From 41c497025f40615373817498606fabd0fcd41dd6 Mon Sep 17 00:00:00 2001 From: Dominik Wenger Date: Mon, 19 Oct 2009 18:14:27 +0000 Subject: Initial mini2440 port. Flyspray: FS#10627 Author: Bob Cousins git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23265 a1c6a512-1295-4272-9138-f99709370657 --- bootloader/SOURCES | 3 + bootloader/mini2440.c | 145 +++++ docs/CREDITS | 1 + firmware/SOURCES | 35 +- firmware/export/config-mini2440.h | 150 ++++++ firmware/export/config.h | 10 +- firmware/export/s3c2440.h | 57 +- firmware/target/arm/s3c2440/crt0.S | 291 ++++++---- firmware/target/arm/s3c2440/debug-target.h | 5 + .../target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c | 79 --- .../target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c | 558 ------------------- .../target/arm/s3c2440/gigabeat-fx/lcd-target.h | 22 + .../target/arm/s3c2440/gigabeat-fx/system-meg-fx.c | 243 --------- .../target/arm/s3c2440/gigabeat-fx/system-target.h | 44 -- firmware/target/arm/s3c2440/kernel-s3c2440.c | 79 +++ firmware/target/arm/s3c2440/lcd-s3c2440.c | 592 +++++++++++++++++++++ firmware/target/arm/s3c2440/mini2440/adc-target.h | 42 ++ .../arm/s3c2440/mini2440/backlight-mini2440.c | 151 ++++++ .../target/arm/s3c2440/mini2440/backlight-target.h | 31 ++ .../target/arm/s3c2440/mini2440/button-mini2440.c | 80 +++ .../target/arm/s3c2440/mini2440/button-target.h | 70 +++ firmware/target/arm/s3c2440/mini2440/lcd-target.h | 43 ++ .../target/arm/s3c2440/mini2440/led-mini2440.c | 66 +++ .../target/arm/s3c2440/mini2440/led-mini2440.h | 46 ++ .../target/arm/s3c2440/mini2440/power-mini2440.c | 55 ++ firmware/target/arm/s3c2440/system-s3c2440.c | 249 +++++++++ firmware/target/arm/s3c2440/system-target.h | 70 +++ tools/configure | 24 +- 28 files changed, 2205 insertions(+), 1036 deletions(-) create mode 100644 bootloader/mini2440.c create mode 100644 firmware/export/config-mini2440.h delete mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c delete mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c delete mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c delete mode 100644 firmware/target/arm/s3c2440/gigabeat-fx/system-target.h create mode 100644 firmware/target/arm/s3c2440/kernel-s3c2440.c create mode 100644 firmware/target/arm/s3c2440/lcd-s3c2440.c create mode 100644 firmware/target/arm/s3c2440/mini2440/adc-target.h create mode 100644 firmware/target/arm/s3c2440/mini2440/backlight-mini2440.c create mode 100644 firmware/target/arm/s3c2440/mini2440/backlight-target.h create mode 100644 firmware/target/arm/s3c2440/mini2440/button-mini2440.c create mode 100644 firmware/target/arm/s3c2440/mini2440/button-target.h create mode 100644 firmware/target/arm/s3c2440/mini2440/lcd-target.h create mode 100644 firmware/target/arm/s3c2440/mini2440/led-mini2440.c create mode 100644 firmware/target/arm/s3c2440/mini2440/led-mini2440.h create mode 100644 firmware/target/arm/s3c2440/mini2440/power-mini2440.c create mode 100644 firmware/target/arm/s3c2440/system-s3c2440.c create mode 100644 firmware/target/arm/s3c2440/system-target.h diff --git a/bootloader/SOURCES b/bootloader/SOURCES index a512064ffd..de902e2a4b 100644 --- a/bootloader/SOURCES +++ b/bootloader/SOURCES @@ -57,4 +57,7 @@ show_logo.c #elif defined(LYRE_PROTO1) lyre_proto1.c show_logo.c +#elif defined(MINI2440) +mini2440.c +show_logo.c #endif diff --git a/bootloader/mini2440.c b/bootloader/mini2440.c new file mode 100644 index 0000000000..c17f386b5b --- /dev/null +++ b/bootloader/mini2440.c @@ -0,0 +1,145 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * + * Copyright (C) 2009 by Bob Cousins, Lyre Project + * + * 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 Standard files */ +#include +#include +#include "inttypes.h" +#include "string.h" +#include "cpu.h" +#include "system.h" +#include "lcd.h" +#include "kernel.h" +#include "thread.h" +#include "storage.h" +#include "fat.h" +#include "disk.h" +#include "font.h" +#include "backlight.h" +#include "button.h" +#include "panic.h" +#include "power.h" +#include "file.h" +#include "common.h" +#include "sd.h" +#include "backlight-target.h" +#include "lcd-target.h" +#include "debug-target.h" +#if 0 +#include "dma-target.h" +#include "uart-s3c2440.h" +#endif +#include "led-mini2440.h" + +/* Show the Rockbox logo - in show_logo.c */ +extern int show_logo(void); + + +int main(void) +{ +#if 0 + /* required later */ + unsigned char* loadbuffer; + int buffer_size; + int rc; + int(*kernel_entry)(void); +#endif + int start, elapsed; + + led_init(); + clear_leds(LED_ALL); + /* NB: something in system_init() prevents H-JTAG from downloading */ +/* system_init(); */ + kernel_init(); +/* enable_interrupt(IRQ_FIQ_STATUS); */ + backlight_init(); + lcd_init(); + lcd_setfont(FONT_SYSFIXED); + button_init(); +#if 0 + dma_init(); + uart_init_device(UART_DEBUG); +#endif +/* mini2440_test(); */ + +#if 1 + show_logo(); + /* pause here for now */ + led_flash(LED1|LED4, LED2|LED3); +#endif + + +#if 0 + /* TODO */ + + /* Show debug messages if button is pressed */ + if(button_read_device() & BUTTON_MENU) + verbose = true; + + printf("Rockbox boot loader"); + printf("Version %s", APPSVERSION); + + rc = storage_init(); + if(rc) + { + reset_screen(); + error(EATA, rc); + } + + disk_init(IF_MD(0)); + rc = disk_mount_all(); + if (rc<=0) + { + error(EDISK,rc); + } + + printf("Loading firmware"); + + /* Flush out anything pending first */ + cpucache_invalidate(); + + loadbuffer = (unsigned char*) 0x31000000; + buffer_size = (unsigned char*)0x31400000 - loadbuffer; + + rc = load_firmware(loadbuffer, BOOTFILE, buffer_size); + if(rc < 0) + error(EBOOTFILE, rc); + + printf("Loaded firmware %d\n", rc); + +/* storage_close(); */ + system_prepare_fw_start(); + + if (rc == EOK) + { + uart_printf ("entering kernel\n"); + cpucache_invalidate(); + kernel_entry = (void*) loadbuffer; + rc = kernel_entry(); + } + + uart_printf ("stopping %d\n", rc); +#endif + + /* end stop - should not get here */ + led_flash(LED_ALL, LED_NONE); + while (1); /* avoid warning */ +} diff --git a/docs/CREDITS b/docs/CREDITS index 093ee194eb..4555877bc2 100644 --- a/docs/CREDITS +++ b/docs/CREDITS @@ -499,6 +499,7 @@ Michael Sparmann Seth Opgenorth Jonas Aaberg Junio C Hamano +Bob Cousins The libmad team The wavpack team diff --git a/firmware/SOURCES b/firmware/SOURCES index e31231c9ec..b91d49b7f7 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -274,6 +274,8 @@ drivers/audio/tlv320.c drivers/audio/mas35xx.c #elif defined(HAVE_AK4537) drivers/audio/ak4537.c +#elif defined(HAVE_UDA1341) +drivers/audio/uda1341.c #endif /* defined(HAVE_*) */ #endif /* !defined(SIMULATOR) && !defined(BOOTLOADER) */ @@ -808,15 +810,15 @@ target/arm/usb-fw-pp502x.c target/arm/lcd-as-memframe.S target/arm/mmu-arm.S target/arm/s3c2440/debug-s3c2440.c +target/arm/s3c2440/kernel-s3c2440.c +target/arm/s3c2440/lcd-s3c2440.c +target/arm/s3c2440/system-s3c2440.c target/arm/s3c2440/gigabeat-fx/adc-meg-fx.c target/arm/s3c2440/gigabeat-fx/ata-meg-fx.c target/arm/s3c2440/gigabeat-fx/backlight-meg-fx.c target/arm/s3c2440/gigabeat-fx/button-meg-fx.c -target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c -target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c target/arm/s3c2440/gigabeat-fx/power-meg-fx.c target/arm/s3c2440/gigabeat-fx/sc606-meg-fx.c -target/arm/s3c2440/gigabeat-fx/system-meg-fx.c target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c #ifndef BOOTLOADER target/arm/s3c2440/gigabeat-fx/i2c-meg-fx.c @@ -1392,6 +1394,33 @@ target/arm/at91sam/lyre_proto1/timer-lyre_proto1.c #endif #endif /* SIMULATOR */ +#if defined(MINI2440) +#ifndef SIMULATOR +target/arm/lcd-as-memframe.S +target/arm/mmu-arm.S +target/arm/s3c2440/debug-s3c2440.c +target/arm/s3c2440/kernel-s3c2440.c +target/arm/s3c2440/lcd-s3c2440.c +target/arm/s3c2440/system-s3c2440.c +target/arm/s3c2440/mini2440/backlight-mini2440.c +target/arm/s3c2440/mini2440/button-mini2440.c +target/arm/s3c2440/mini2440/led-mini2440.c +target/arm/s3c2440/mini2440/power-mini2440.c +#ifdef BOOTLOADER +/*target/arm/s3c2440/mini2440/mini2440_test.c*/ +#endif +#ifndef BOOTLOADER +target/arm/s3c2440/mini2440/adc-mini2440.c +target/arm/s3c2440/mini2440/i2c-mini2440.c +target/arm/s3c2440/mini2440/pcm-mini2440.c +target/arm/s3c2440/mini2440/powermgmt-mini2440.c +target/arm/s3c2440/mini2440/power-mini2440.c +target/arm/s3c2440/mini2440/timer-mini2440.c +target/arm/s3c2440/mini2440/usb-mini2440.c +#endif +#endif /* SIMULATOR */ +#endif /* MINI2440 */ + #ifdef SAMSUNG_YH820 #ifndef SIMULATOR target/arm/ata-as-arm.S diff --git a/firmware/export/config-mini2440.h b/firmware/export/config-mini2440.h new file mode 100644 index 0000000000..0db027c7a0 --- /dev/null +++ b/firmware/export/config-mini2440.h @@ -0,0 +1,150 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2009 by Bob Cousins, Lyre Project + * Copyright (C) 2009 by Jorge Pinto, Lyre Project + * + * 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. + * + ****************************************************************************/ + +/* + * This config file is for the Mini2440 + */ +#define TARGET_TREE /* this target is using the target tree system */ + +/* For Rolo and boot loader */ +#define MODEL_NUMBER 131 +#define MODEL_NAME "Mini2440" + +/***************************************************************************/ +/* Hardware Config */ + +/* TODO: ??? */ +#define CONFIG_SDRAM_START 0x30000000 + +/* Flash storage */ +#define HAVE_FLASH_STORAGE +/* define the storage type */ +#define CONFIG_STORAGE STORAGE_SD + +#define HAVE_MULTIDRIVE +#define NUM_DRIVES 2 +#define HAVE_HOTSWAP + +/* Disk storage */ +/* define this if you have a disk storage, i.e. something + that needs spinups and can cause skips when shaked */ +/* #define HAVE_DISK_STORAGE */ + +/* Display */ +/* define this if you have a bitmap LCD display */ +#define HAVE_LCD_BITMAP +/* define this if you have a colour LCD */ +#define HAVE_LCD_COLOR +/* The LCD is assumed to be 3.5" TFT touch screen, others are possible */ +#define CONFIG_LCD LCD_MINI2440 +/* LCD dimensions */ +#define LCD_WIDTH 240 +#define LCD_HEIGHT 320 +/* The LCD is configured for RGB565 */ +#define LCD_DEPTH 16 /* 65536 colours */ +#define LCD_PIXELFORMAT RGB565 /* rgb565 */ +/* Define this for LCD backlight available */ +/* The Mini2440 supports backight brightness depending on LCD type */ +/* But the 3.5" LCD touch screen does not support brightness*/ +#define HAVE_BACKLIGHT +#define HAVE_BACKLIGHT_BRIGHTNESS + +/* Keypad */ +#define CONFIG_KEYPAD MINI2440_PAD + +/* I2C */ +/* Do not use I2C */ +#define CONFIG_I2C I2C_NONE + +/* Define DAC/Codec */ +/*#define HAVE_UDA1341*/ +#define HAVE_TLV320 +/* ... tone controls, use the software ones */ +#define HAVE_SW_TONE_CONTROLS + +/* Battery */ +#define BATTERY_CAPACITY_DEFAULT 1100 /* 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 */ + +/* USB */ +/* TODO:#define HAVE_USBSTACK */ + +/***************************************************************************/ +/* Application Config */ + +#define HAVE_ALBUMART +/* define this to enable bitmap scaling */ +#define HAVE_BMP_SCALING +/* define this to enable JPEG decoding */ +#define HAVE_JPEG +/* RMC TODO: what is this for?? */ +/* define this if you have access to the pitchscreen */ +#define HAVE_PITCHSCREEN + +/* Define this if you do software codec */ +#define CONFIG_CODEC SWCODEC + +/* The number of bytes reserved for loadable codecs */ +#define CODEC_SIZE 0x100000 + +/* The number of bytes reserved for loadable plugins */ +#define PLUGIN_BUFFER_SIZE 0x100000 + + +/***************************************************************************/ +#ifndef SIMULATOR + +#define CONFIG_CPU S3C2440 + +/* Define this to the CPU frequency */ +#define CPU_FREQ 405000000 +#define MCK_FREQ (CPU_FREQ/4) +#define SLOW_CLOCK 32768 + +/* Main LCD backlight brightness range and defaults */ +#define MIN_BRIGHTNESS_SETTING 1 /* 0.5 mA */ +#define MAX_BRIGHTNESS_SETTING 12 /* 32 mA */ +#define DEFAULT_BRIGHTNESS_SETTING 10 /* 16 mA */ +/* Define this if your LCD can set contrast */ +#define HAVE_LCD_CONTRAST +#define MIN_CONTRAST_SETTING 0 +#define MAX_CONTRAST_SETTING 63 +#define DEFAULT_CONTRAST_SETTING 47 /* Match boot contrast */ + +/* Hardware controlled charging with monitoring */ +#define CONFIG_CHARGING CHARGING_MONITOR +/*#define POWER_INPUT_BATTERY 0*/ + +/* Offset ( in the firmware file's header ) to the file CRC */ +#define FIRMWARE_OFFSET_FILE_CRC 0 + +/* Offset ( in the firmware file's header ) to the real data */ +#define FIRMWARE_OFFSET_FILE_DATA 8 + +#define BOOTFILE_EXT "mini2440" +#define BOOTFILE "rockbox." BOOTFILE_EXT +#define BOOTDIR "/.rockbox" + +#endif +/***************************************************************************/ diff --git a/firmware/export/config.h b/firmware/export/config.h index 70e2c792d0..8a1adeaac8 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -112,6 +112,7 @@ #define SAMSUNG_YH_PAD 38 #define ONDAVX777_PAD 39 #define SAMSUNG_YPS3_PAD 40 +#define MINI2440_PAD 41 /* CONFIG_REMOTE_KEYPAD */ #define H100_REMOTE 1 @@ -192,10 +193,11 @@ #define LCD_ONDAVX767 30 /* as used by the Onda VX767 */ #define LCD_SSD1303 31 /* as used by the Sansa Clip */ #define LCD_FUZE 32 /* as used by the Sansa Fuze */ -#define LCD_LYRE_PROTO1 33 /* as used by the Lyre */ +#define LCD_LYRE_PROTO1 33 /* as used by the Lyre prototype 1 */ #define LCD_YH925 34 /* as used by Samsung YH-925 (similar to the H10 20GB) */ -#define LCD_VIEW 35 /* as used by the Sansa View */ +#define LCD_VIEW 35 /* as used by the Sansa View */ #define LCD_NANO2G 36 /* as used by the iPod Nano 2nd Generation */ +#define LCD_MINI2440 37 /* as used by the Mini2440 */ /* LCD_PIXELFORMAT */ #define HORIZONTAL_PACKING 1 @@ -216,7 +218,7 @@ /* CONFIG_I2C */ #define I2C_NONE 0 /* For targets that do not use I2C - as the -Lyre prototype 1*/ +Lyre prototype 1 */ #define I2C_PLAYREC 1 /* Archos Player/Recorder style */ #define I2C_ONDIO 2 /* Ondio style */ #define I2C_COLDFIRE 3 /* Coldfire style */ @@ -386,6 +388,8 @@ Lyre prototype 1*/ #include "config-view.h" #elif defined(LYRE_PROTO1) #include "config-lyre_proto1.h" +#elif defined(MINI2440) +#include "config-mini2440.h" #elif defined(SAMSUNG_YH820) #include "config-yh820.h" #elif defined(SAMSUNG_YH920) diff --git a/firmware/export/s3c2440.h b/firmware/export/s3c2440.h index 0589f3b6b0..5f595214a1 100644 --- a/firmware/export/s3c2440.h +++ b/firmware/export/s3c2440.h @@ -178,6 +178,41 @@ #define DCDST3 (*(volatile unsigned long *)0x4B0000DC) /* DMA 3 current destination */ #define DMASKTRIG3 (*(volatile unsigned long *)0x4B0000E0) /* DMA 3 mask trigger */ +#define DISRCC_LOC_AHB (0 << 1) +#define DISRCC_LOC_APB (1 << 1) +#define DISRCC_INC_AUTO (0 << 0) +#define DISRCC_INC_FIXED (1 << 0) + +#define DIDSTC_CHK_INT_TC_ZERO (0 << 2) +#define DIDSTC_CHK_INT_AFTER_RELOAD (1 << 2) +#define DIDSTC_LOC_AHB (0 << 1) +#define DIDSTC_LOC_APB (1 << 1) +#define DIDSTC_INC_AUTO (0 << 0) +#define DIDSTC_INC_FIXED (1 << 0) + +#define DCON_DMD_HS (1 << 31) +#define DCON_SYNC_APB (0 << 30) +#define DCON_SYNC_AHB (1 << 30) +#define DCON_INT (1 << 29) +#define DCON_TSZ (1 << 28) +#define DCON_SERVMODE_WHOLE (1 << 27) +#define DCON_HWSRCSEL (1 << 24) +#define DCON_HW_SEL (1 << 23) +#define DCON_NO_RELOAD (1 << 22) +#define DCON_DSZ_MASK (3 << 20) +#define DCON_DSZ_BYTE (0 << 20) +#define DCON_DSZ_HALF_WORD (1 << 20) +#define DCON_DSZ_WORD (2 << 20) +#define DCON_TC (1 << 0) + +#define DSTAT_STAT_BUSY (1 << 20) +#define DSTAT_CURR_TC (1 << 0) + +#define DMASKTRIG_STOP (1 << 2) +#define DMASKTRIG_ON (1 << 1) +#define DMASKTRIG_SW_TRIG (1 << 0) + + /* Clock & Power Management */ #define LOCKTIME (*(volatile unsigned long *)0x4C000000) /* PLL lock time counter */ @@ -499,7 +534,14 @@ #define SDIDSTA (*(volatile unsigned long *)0x5A000034) /* SDI data status */ #define SDIFSTA (*(volatile unsigned long *)0x5A000038) /* SDI FIFO status */ #define SDIIMSK (*(volatile unsigned long *)0x5A00003C) /* SDI interrupt mask */ -#define SDIDAT (*(volatile unsigned char *)0x5A000040) /* SDI data */ + +/* SDI data - LE = Little Endian, BE = Big Endian */ +#define SDIDAT_LLE (*(volatile unsigned long *)0x5A000040) /* 32 bit */ +#define SDIDAT_HLE (*(volatile unsigned short *)0x5A000044) /* 16 */ +#define SDIDAT_BLE (*(volatile unsigned char *)0x5A000048) /* 8 */ +#define SDIDAT_LBE (*(volatile unsigned long *)0x5A00004C) /* 32 */ +#define SDIDAT_HBE (*(volatile unsigned short *)0x5A000041) /* 16 */ +#define SDIDAT_BBE (*(volatile unsigned char *)0x5A000043) /* 8 */ /* AC97 Audio-CODEC Interface */ @@ -530,5 +572,18 @@ #define TIMER_FREQ (49156800/2) #define TIMER234_PRESCALE 21 +/* I/O Port macros */ + +#define GPIO_INPUT 0 +#define GPIO_OUTPUT 1 +#define GPIO_FUNCTION 2 +#define GPIO_ALT_FUNCTION 3 + +#define GPIO_PULLUP_DISABLE 1 +#define GPIO_PULLUP_ENABLE 0 + +#define S3C2440_GPIO_CONFIG(port,pin,function) port = ( (port & ~(3<<(pin*2)) ) | (function<<(pin*2)) ) +#define S3C2440_GPIO_PULLUP(port,pin,state) port = ( (port & ~(1< ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Copyright (C) 2007 by Michael Sevakis -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version 2 -* of the License, or (at your option) any later version. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ -#include "config.h" -#include "system.h" -#include "kernel.h" -#include "timer.h" -#include "thread.h" - -void tick_start(unsigned int interval_in_ms) -{ - /* - * Based on default PCLK of 49.1568MHz - scaling chosen to give - * remainder-free result for tick interval of 10ms (100Hz) - * Timer input clock frequency = - * fPCLK / {prescaler value+1} / {divider value} - * TIMER_FREQ = 49156800 / 2 - * 146300 = TIMER_FREQ / 21 / 8 - * 49156800 = 19*11*(7)*7*5*5*(3)*2*2*2*2*2*2 - * 21 = 7*3 - */ - - /* stop timer 4 */ - TCON &= ~(1 << 20); - /* Set the count for timer 4 */ - TCNTB4 = (TIMER_FREQ / TIMER234_PRESCALE / 8) * interval_in_ms / 1000; - /* Set the the prescaler value for timers 2,3, and 4 */ - TCFG0 = (TCFG0 & ~0xff00) | ((TIMER234_PRESCALE-1) << 8); - /* DMA mode off, MUX4 = 1/16 */ - TCFG1 = (TCFG1 & ~0xff0000) | 0x030000; - /* set manual bit */ - TCON |= 1 << 21; - /* reset manual bit */ - TCON &= ~(1 << 21); - - /* interval mode */ - TCON |= 1 << 22; - /* start timer 4 */ - TCON |= (1 << 20); - - /* timer 4 unmask interrupts */ - INTMSK &= ~TIMER4_MASK; -} - -#ifdef BOOTLOADER -void tick_stop(void) -{ - s3c_regset32(&INTMSK, TIMER4_MASK); - TCON &= ~(1 << 20); - SRCPND = TIMER4_MASK; - INTPND = TIMER4_MASK; -} -#endif - -void TIMER4(void) -{ - /* Run through the list of tick tasks */ - call_tick_tasks(); - - SRCPND = TIMER4_MASK; - INTPND = TIMER4_MASK; -} diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c deleted file mode 100644 index 661ae8e6a9..0000000000 --- a/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c +++ /dev/null @@ -1,558 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Copyright (C) 2007 by Greg White -* -* 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 - -#include "config.h" -#include "system.h" -#include "cpu.h" -#include "string.h" -#include "lcd.h" -#include "kernel.h" -#include "lcd-target.h" - -#define LCDADDR(x, y) (&lcd_framebuffer[(y)][(x)]) - -static bool lcd_on = true; -#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) -static bool lcd_powered = true; -#endif -static unsigned lcd_yuv_options = 0; -/* -** This is imported from lcd-16bit.c -*/ -extern struct viewport* current_vp; - -/* Copies a rectangle from one framebuffer to another. Can be used in - single transfer mode with width = num pixels, and height = 1 which - allows a full-width rectangle to be copied more efficiently. */ -extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src, - int width, int height); - -#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) -bool lcd_active(void) -{ - return lcd_on; -} -#endif - -static unsigned int LCDBANK(unsigned int address) -{ - return ((address >> 22) & 0xff); -} - -static unsigned int LCDBASEU(unsigned int address) -{ - return (address & ((1 << 22)-1)) >> 1; -} - -static unsigned int LCDBASEL(unsigned int address) -{ - address += 320*240*2; - return (address & ((1 << 22)-1)) >> 1; -} - -static inline void delay_cycles(volatile int delay) -{ - while(delay>0) delay--; -} - -static void LCD_CTRL_setup(void) -{ - /* ENVID = 0, BPPMODE = 16 bpp, PNRMODE = TFT, MMODE = Each Frame, CLKVAL = 8 */ - LCDCON1 = 0x878; - - /* VCPW = 1, VFPD = 5, LINEVAL = 319, VBPD = 7 */ - LCDCON2 = 0x74FC141; - - /* HFPD = 9, HOZVAL = 239, HBPD = 7 */ - LCDCON3 = 0x38EF09; - - /* HSPW = 7 */ - LCDCON4 = 7; - - /* HWSWP = 1, INVVFRAM = 1, INVVLINE = 1, FRM565 = 1, All others = 0 */ - LCDCON5 = 0xB01; - - LCDSADDR1 = (LCDBANK((unsigned)FRAME) << 21) | (LCDBASEU((unsigned)FRAME)); - LCDSADDR2 = LCDBASEL((unsigned)FRAME); - LCDSADDR3 = 0x000000F0; -} - -static void LCD_CTRL_clock(bool onoff) -{ - if(onoff) - { - GPCCON &= ~0xFFF000FC; - GPDCON &= ~0xFFF0FFF0; - - GPCCON |= 0xAAA000A8; - GPCUP |= 0xFC0E; - - GPDCON |= 0xAAA0AAA0; - GPDUP |= 0xFCFC; - - s3c_regset32(&CLKCON, 0x20); /* enable LCD clock */ - LCDCON1 |=0x01; - } - else - { - GPCCON &= ~0xFFF000FC; - GPCUP &= ~0xFC0E; - - GPDCON &= ~0xFFF0FFF0; - GPDUP &= ~0xFCFC; - - LCDCON1 &= ~1; /* Must diable first or bus may freeze */ - s3c_regclr32(&CLKCON, 0x20); /* disable LCD clock */ - } -} - -static void reset_LCD(bool reset) -{ - GPBCON&=~0xC000; - GPBCON|=0x4000; - if(reset) - GPBDAT|=0x80; - else - GPBDAT&=~0x80; -} - -static void LCD_SPI_send(const unsigned char *array, int count) -{ - while (count--) - { - while ((SPSTA0&0x01)==0){}; - SPTDAT0=*array++; - } -} - -static void LCD_SPI_setreg(unsigned char reg, unsigned char value) -{ - unsigned char regval[] = - { - 0x00,reg,0x01,value - }; - LCD_SPI_send(regval, sizeof(regval)); -} - -static void LCD_SPI_SS(bool select) -{ - delay_cycles(0x4FFF); - - GPBCON&=~0x30000; - GPBCON|=0x10000; - - if(select) - GPBDAT|=0x100; - else - GPBDAT&=~0x100; -} - -static void LCD_SPI_start(void) -{ - s3c_regset32(&CLKCON, 0x40000); /* enable SPI clock */ - LCD_SPI_SS(false); - SPCON0=0x3E; - SPPRE0=24; - - reset_LCD(true); - LCD_SPI_SS(true); -} - -static void LCD_SPI_stop(void) -{ - LCD_SPI_SS(false); - - SPCON0 &= ~0x10; - s3c_regclr32(&CLKCON, 0x40000); /* disable SPI clock */ -} - -static void LCD_SPI_init(void) -{ - /* - * SPI setup - Some of these registers are known; they are documented in - * the wiki. Many thanks to Alex Gerchanovsky for discovering this - * sequence. - */ - - LCD_CTRL_clock(true); - - LCD_SPI_start(); - LCD_SPI_setreg(0x0F, 0x01); - LCD_SPI_setreg(0x09, 0x06); - LCD_SPI_setreg(0x16, 0xA6); - LCD_SPI_setreg(0x1E, 0x49); - LCD_SPI_setreg(0x1F, 0x26); - LCD_SPI_setreg(0x0B, 0x2F); - LCD_SPI_setreg(0x0C, 0x2B); - LCD_SPI_setreg(0x19, 0x5E); - LCD_SPI_setreg(0x1A, 0x15); - LCD_SPI_setreg(0x1B, 0x15); - LCD_SPI_setreg(0x1D, 0x01); - LCD_SPI_setreg(0x00, 0x03); - LCD_SPI_setreg(0x01, 0x10); - LCD_SPI_setreg(0x02, 0x0A); - LCD_SPI_setreg(0x06, 0x04); /* Set the orientation */ - LCD_SPI_setreg(0x08, 0x2E); - LCD_SPI_setreg(0x24, 0x12); - LCD_SPI_setreg(0x25, 0x3F); - LCD_SPI_setreg(0x26, 0x0B); - LCD_SPI_setreg(0x27, 0x00); - LCD_SPI_setreg(0x28, 0x00); - LCD_SPI_setreg(0x29, 0xF6); - LCD_SPI_setreg(0x2A, 0x03); - LCD_SPI_setreg(0x2B, 0x0A); - LCD_SPI_setreg(0x04, 0x01); /* Turn the display on */ - LCD_SPI_stop(); -} - -/* LCD init */ -void lcd_init_device(void) -{ -#ifdef BOOTLOADER - int i; - /* When the Rockbox bootloader starts the framebuffer address is changed - * but the LCD display should stay the same til an lcd_update() occurs. - * This copies the data from the old framebuffer to the new one to make the - * change non-visable to the user. - */ - unsigned short *buf = (unsigned short*)(FRAME); - unsigned short *oldbuf = (unsigned short*)(LCDSADDR1<<1); - - /* The Rockbox bootloader is transitioning from RGB555I to RGB565 mode - so convert the frambuffer data accordingly */ - for(i=0; i< 320*240; i++) - { - *(buf++) = ((*oldbuf>>1) & 0x1F) | (*oldbuf & 0xffc0); - oldbuf++; - } -#endif - - /* Set pins up */ - - GPHUP &= 0x600; - - GPECON |= 0x0A800000; - GPEUP |= 0x3800; - - GPBUP |= 0x181; - - s3c_regset32(&CLKCON, 0x20); /* enable LCD clock */ - - LCD_CTRL_setup(); - LCD_SPI_init(); -} - -#if defined(HAVE_LCD_SLEEP) -static void LCD_SPI_powerdown(void) -{ - lcd_powered = false; - - LCD_SPI_start(); - LCD_SPI_setreg(0x04, 0x00); - LCD_SPI_stop(); - - reset_LCD(false); /* This makes a big difference on power */ - LCD_CTRL_clock(false); -} - -void lcd_sleep(void) -{ - if (lcd_powered) - { - /* "not powered" implies "disabled" */ - if (lcd_on) - lcd_enable(false); - - LCD_SPI_powerdown(); - } -} -#endif - -#if defined(HAVE_LCD_ENABLE) -static void LCD_SPI_powerup(void) -{ - LCD_CTRL_clock(true); - - LCD_SPI_start(); - LCD_SPI_setreg(0x04, 0x01); - LCD_SPI_stop(); - - lcd_powered = true; -} - -void lcd_enable(bool state) -{ - if (state == lcd_on) - return; - - if(state) - { - /* "enabled" implies "powered" */ - if (!lcd_powered) - { - LCD_SPI_powerup(); - /* Wait long enough for a frame to be written - yes, it - * takes awhile. */ - sleep(HZ/5); - } - - lcd_on = true; - lcd_update(); - lcd_activation_call_hook(); - } - else - { - lcd_on = false; - } -} -#endif - -void lcd_set_flip(bool yesno) { - if (!lcd_on) - return; - - LCD_SPI_start(); - if(yesno) - { - LCD_SPI_setreg(0x06, 0x02); - } - else - { - LCD_SPI_setreg(0x06, 0x04); - } - LCD_SPI_stop(); -} - -int lcd_default_contrast(void) -{ - return DEFAULT_CONTRAST_SETTING; -} - -void lcd_set_contrast(int val) { - if (!lcd_on) - return; - - LCD_SPI_start(); - LCD_SPI_setreg(0x0B, (unsigned char) val); - LCD_SPI_stop(); -} - -void lcd_set_invert_display(bool yesno) { - if (!lcd_on) - return; - - LCD_SPI_start(); - if(yesno) - { - LCD_SPI_setreg(0x27, 0x10); - } - else - { - LCD_SPI_setreg(0x27, 0x00); - } - LCD_SPI_stop(); -} - -/* Update a fraction of the display. */ -void lcd_update_rect(int x, int y, int width, int height) -{ - fb_data *dst, *src; - - if (!lcd_on) - return; - - if (x + width > LCD_WIDTH) - width = LCD_WIDTH - x; /* Clip right */ - if (x < 0) - width += x, x = 0; /* Clip left */ - if (width <= 0) - return; /* nothing left to do */ - - if (y + height > LCD_HEIGHT) - height = LCD_HEIGHT - y; /* Clip bottom */ - if (y < 0) - height += y, y = 0; /* Clip top */ - if (height <= 0) - return; /* nothing left to do */ - - /* TODO: It may be faster to swap the addresses of lcd_driver_framebuffer - * and lcd_framebuffer */ - dst = (fb_data *)FRAME + LCD_WIDTH*y + x; - src = &lcd_framebuffer[y][x]; - - /* Copy part of the Rockbox framebuffer to the second framebuffer */ - if (width < LCD_WIDTH) - { - /* Not full width - do line-by-line */ - lcd_copy_buffer_rect(dst, src, width, height); - } - else - { - /* Full width - copy as one line */ - lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1); - } -} - -/* Update the display. - This must be called after all other LCD functions that change the display. */ -void lcd_update(void) -{ - if (!lcd_on) - return; - - lcd_copy_buffer_rect((fb_data *)FRAME, &lcd_framebuffer[0][0], - LCD_WIDTH*LCD_HEIGHT, 1); -} - -void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y, - int stride, int x, int y, int width, - int height) -{ - int w, px; - fb_data *dst; - - if (x + width > current_vp->width) - width = current_vp->width - x; /* Clip right */ - - if (x < 0) /* Clip left */ - { - width += x; - src_x -= x; - x = 0; - } - - if (width <= 0) - return; /* nothing left to do */ - - if (y + height > current_vp->height) - height = current_vp->height - y; /* Clip bottom */ - - if (y < 0) /* Clip top */ - { - height += y; - src_y -= y; - y = 0; - } - - if (height <= 0) - return; /* nothing left to do */ - - src += stride * src_y + src_x; /* move starting point */ - dst = &lcd_framebuffer[current_vp->y+y][current_vp->x+x]; - - asm volatile ( - ".rowstart: \r\n" - "mov %[w], %[width] \r\n" /* Load width for inner loop */ - ".nextpixel: \r\n" - "ldrh %[px], [%[s]], #2 \r\n" /* Load src pixel */ - "add %[d], %[d], #2 \r\n" /* Uncoditionally increment dst */ - "cmp %[px], %[fgcolor] \r\n" /* Compare to foreground color */ - "streqh %[fgpat], [%[d], #-2] \r\n" /* Store foregroud if match */ - "cmpne %[px], %[transcolor] \r\n" /* Compare to transparent color */ - "strneh %[px], [%[d], #-2] \r\n" /* Store dst if not transparent */ - "subs %[w], %[w], #1 \r\n" /* Width counter has run down? */ - "bgt .nextpixel \r\n" /* More in this row? */ - "add %[s], %[s], %[sstp], lsl #1 \r\n" /* Skip over to start of next line */ - "add %[d], %[d], %[dstp], lsl #1 \r\n" - "subs %[h], %[h], #1 \r\n" /* Height counter has run down? */ - "bgt .rowstart \r\n" /* More rows? */ - : [w]"=&r"(w), [h]"+&r"(height), [px]"=&r"(px), - [s]"+&r"(src), [d]"+&r"(dst) - : [width]"r"(width), - [sstp]"r"(stride - width), - [dstp]"r"(LCD_WIDTH - width), - [transcolor]"r"(TRANSPARENT_COLOR), - [fgcolor]"r"(REPLACEWITHFG_COLOR), - [fgpat]"r"(current_vp->fg_pattern) - ); -} - -void lcd_yuv_set_options(unsigned options) -{ - lcd_yuv_options = options; -} - -/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ -extern void lcd_write_yuv420_lines(fb_data *dst, - unsigned char const * const src[3], - int width, - int stride); -extern void lcd_write_yuv420_lines_odither(fb_data *dst, - unsigned char const * const src[3], - int width, - int stride, - int x_screen, /* To align dither pattern */ - int y_screen); -/* Performance function to blit a YUV bitmap directly to the LCD */ -/* For the Gigabeat - show it rotated */ -/* So the LCD_WIDTH is now the 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) -{ - /* Caches for chroma data so it only need be recaculated every other - line */ - unsigned char const * yuv_src[3]; - off_t z; - - if (!lcd_on) - return; - - /* Sorry, but width and height must be >= 2 or else */ - width &= ~1; - height >>= 1; - - y = LCD_WIDTH - 1 - y; - fb_data *dst = (fb_data*)FRAME + x * LCD_WIDTH + y; - - z = stride*src_y; - yuv_src[0] = src[0] + z + src_x; - yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); - yuv_src[2] = src[2] + (yuv_src[1] - src[1]); - - if (lcd_yuv_options & LCD_YUV_DITHER) - { - do - { - lcd_write_yuv420_lines_odither(dst, yuv_src, width, stride, y, x); - yuv_src[0] += stride << 1; /* Skip down two luma lines */ - yuv_src[1] += stride >> 1; /* Skip down one chroma line */ - yuv_src[2] += stride >> 1; - dst -= 2; - y -= 2; - } - while (--height > 0); - } - else - { - do - { - lcd_write_yuv420_lines(dst, yuv_src, width, stride); - yuv_src[0] += stride << 1; /* Skip down two luma lines */ - yuv_src[1] += stride >> 1; /* Skip down one chroma line */ - yuv_src[2] += stride >> 1; - dst -= 2; - } - while (--height > 0); - } -} - diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/lcd-target.h b/firmware/target/arm/s3c2440/gigabeat-fx/lcd-target.h index cb82a8076f..c136a2052d 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/lcd-target.h +++ b/firmware/target/arm/s3c2440/gigabeat-fx/lcd-target.h @@ -21,3 +21,25 @@ extern void lcd_enable(bool state); +/* Config values for LCDCON1 */ +/* ENVID = 0, BPPMODE = 16 bpp, PNRMODE = TFT, MMODE = Each Frame, CLKVAL = 8 */ +#define LCD_CLKVAL 8 +#define LCD_MMODE 0 +#define LCD_PNRMODE 3 +#define LCD_BPPMODE 12 +#define LCD_ENVID 1 + +/* Config values for LCDCON2 */ +/* VCPW = 1, VFPD = 5, VBPD = 7 */ +#define LCD_UPPER_MARGIN 7 +#define LCD_LOWER_MARGIN 5 +#define LCD_VSYNC_LEN 1 + +/* Config values for LCDCON3 */ +/* HFPD = 9, HBPD = 7 */ +#define LCD_LEFT_MARGIN 7 +#define LCD_RIGHT_MARGIN 9 + +/* Config values for LCDCON4 */ +/* HSPW = 7 */ +#define LCD_HSYNC_LEN 7 diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c deleted file mode 100644 index 79d592091e..0000000000 --- a/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c +++ /dev/null @@ -1,243 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Copyright (C) 2007 by Michael Sevakis -* -* 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 "kernel.h" -#include "system.h" -#include "panic.h" -#include "mmu-arm.h" -#include "cpu.h" - -#define default_interrupt(name) \ - extern __attribute__((weak,alias("UIRQ"))) void name (void) - -default_interrupt(EINT0); -default_interrupt(EINT1); -default_interrupt(EINT2); -default_interrupt(EINT3); -default_interrupt(EINT4_7); -default_interrupt(EINT8_23); -default_interrupt(CAM); -default_interrupt(nBATT_FLT); -default_interrupt(TICK); -default_interrupt(WDT_AC97); -default_interrupt(TIMER0); -default_interrupt(TIMER1); -default_interrupt(TIMER2); -default_interrupt(TIMER3); -default_interrupt(TIMER4); -default_interrupt(UART2); -default_interrupt(LCD); -default_interrupt(DMA0); -default_interrupt(DMA1); -default_interrupt(DMA2); -default_interrupt(DMA3); -default_interrupt(SDI); -default_interrupt(SPI0); -default_interrupt(UART1); -default_interrupt(NFCON); -default_interrupt(USBD); -default_interrupt(USBH); -default_interrupt(IIC); -default_interrupt(UART0); -default_interrupt(SPI1); -default_interrupt(RTC); -default_interrupt(ADC); - -static void (* const irqvector[32])(void) __attribute__((__used__)) = -{ - EINT0, EINT1, EINT2, EINT3, - EINT4_7, EINT8_23, CAM, nBATT_FLT, TICK, WDT_AC97, - TIMER0, TIMER1, TIMER2, TIMER3, TIMER4, UART2, - LCD, DMA0, DMA1, DMA2, DMA3, SDI, - SPI0, UART1, NFCON, USBD, USBH, IIC, - UART0, SPI1, RTC, ADC, -}; - -static const char * const irqname[32] = -{ - "EINT0", "EINT1", "EINT2", "EINT3", - "EINT4_7", "EINT8_23", "CAM", "nBATT_FLT", "TICK", "WDT_AC97", - "TIMER0", "TIMER1", "TIMER2", "TIMER3", "TIMER4", "UART2", - "LCD", "DMA0", "DMA1", "DMA2", "DMA3", "SDI", - "SPI0", "UART1", "NFCON", "USBD", "USBH", "IIC", - "UART0", "SPI1", "RTC", "ADC" -}; - -static void UIRQ(void) -{ - unsigned int offset = INTOFFSET; - panicf("Unhandled IRQ %02X: %s", offset, irqname[offset]); -} - -void irq_handler(void) __attribute__((interrupt ("IRQ"), naked)); -void irq_handler(void) -{ - asm volatile ( - "sub lr, lr, #4 \r\n" - "stmfd sp!, {r0-r3, ip, lr} \r\n" - "mov r0, #0x4a000000 \r\n" /* INTOFFSET = 0x4a000014 */ - "ldr r0, [r0, #0x14] \r\n" - "ldr r1, =irqvector \r\n" - "ldr r1, [r1, r0, lsl #2] \r\n" - "mov lr, pc \r\n" - "bx r1 \r\n" - "ldmfd sp!, {r0-r3, ip, pc}^ \r\n" - ); -} - -void system_reboot(void) -{ - WTCON = 0; - WTCNT = WTDAT = 1 ; - WTCON = 0x21; - for(;;) - ; -} - -void system_exception_wait(void) -{ - INTMSK = 0xFFFFFFFF; - while ((GPGDAT & (1 << 0)) == 0); /* Wait for power button */ -} - -static void set_page_tables(void) -{ - /* map every memory region to itself */ - map_section(0, 0, 0x1000, CACHE_NONE); - - /* map RAM to 0 and enable caching for it */ - map_section(0x30000000, 0, 32, CACHE_ALL); - - /* enable buffered writing for the framebuffer */ - map_section((int)FRAME, (int)FRAME, 1, BUFFERED); -} - -void memory_init(void) -{ - ttb_init(); - set_page_tables(); - enable_mmu(); -} - -void s3c_regmod32(volatile unsigned long *reg, unsigned long bits, - unsigned long mask) -{ - int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS); - *reg = (*reg & ~mask) | (bits & mask); - restore_interrupt(oldstatus); -} - -void s3c_regset32(volatile unsigned long *reg, unsigned long bits) -{ - s3c_regmod32(reg, bits, bits); -} - -void s3c_regclr32(volatile unsigned long *reg, unsigned long bits) -{ - s3c_regmod32(reg, 0, bits); -} - -#ifdef BOOTLOADER -void system_prepare_fw_start(void) -{ - tick_stop(); - disable_interrupt(IRQ_FIQ_STATUS); - INTMSK = 0xFFFFFFFF; -} -#endif - -void system_init(void) -{ - INTMSK = 0xFFFFFFFF; - INTMOD = 0; - SRCPND = 0xFFFFFFFF; - INTPND = 0xFFFFFFFF; - INTSUBMSK = 0xFFFFFFFF; - SUBSRCPND = 0xFFFFFFFF; - - GPBCON |= 0x85; - GPBDAT |= 0x07; - GPBUP |= 0x20F; - - /* Take care of flash related pins */ - GPCCON |= 0x1000; - GPCDAT &= ~0x40; - GPCUP |= 0x51; - - GPDCON |= 0x05; - GPDUP |= 0x03; - GPDDAT &= ~0x03; - - GPFCON |= 0x00000AAA; - GPFUP |= 0xFF; - - GPGCON |= 0x01001000; - GPGUP |= 0x70; - - GPHCON |= 0x4005; - GPHDAT |= 0x03; - - /* TODO: do something with PRIORITY */ - - /* Turn off currently-not or never-needed devices. - * Be careful here, it is possible to freeze the device by disabling - * clocks at the wrong time. - * - * Turn off AC97, Camera, SPI, IIS, I2C, UARTS, MMC/SD/SDIO Controller - * USB device, USB host, NAND flash controller. - * - * IDLE, Sleep, LCDC, PWM timer, GPIO, RTC, and ADC are untouched (on) - */ - CLKCON &= ~0xFF1ED0; - - CLKSLOW |= 0x80; -} - -int system_memory_guard(int newmode) -{ - (void)newmode; - return 0; -} - -#ifdef HAVE_ADJUSTABLE_CPU_FREQ - -void set_cpu_frequency(long frequency) -{ - if (frequency == CPUFREQ_MAX) - { - asm volatile("mov r0, #0\n" - "mrc p15, 0, r0, c1, c0, 0\n" - "orr r0, r0, #3<<30\n" /* set to Asynchronous mode*/ - "mcr p15, 0, r0, c1, c0, 0" : : : "r0"); - - FREQ = CPUFREQ_MAX; - } - else - { - asm volatile("mov r0, #0\n" - "mrc p15, 0, r0, c1, c0, 0\n" - "bic r0, r0, #3<<30\n" /* set to FastBus mode*/ - "mcr p15, 0, r0, c1, c0, 0" : : : "r0"); - - FREQ = CPUFREQ_NORMAL; - } -} - -#endif diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/system-target.h b/firmware/target/arm/s3c2440/gigabeat-fx/system-target.h deleted file mode 100644 index f310b9ac26..0000000000 --- a/firmware/target/arm/s3c2440/gigabeat-fx/system-target.h +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2007 by Greg White - * - * 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. - * - ****************************************************************************/ -#ifndef SYSTEM_TARGET_H -#define SYSTEM_TARGET_H - -#include "system-arm.h" -#include "mmu-arm.h" - -#define CPUFREQ_DEFAULT 98784000 -#define CPUFREQ_NORMAL 98784000 -#define CPUFREQ_MAX 296352000 - -void system_prepare_fw_start(void); -void tick_stop(void); - -/* Functions to set and clear regiser bits atomically */ - -/* Set and clear register bits */ -void s3c_regmod32(volatile unsigned long *reg, unsigned long bits, - unsigned long mask); -/* Set register bits */ -void s3c_regset32(volatile unsigned long *reg, unsigned long bits); -/* Clear register bits */ -void s3c_regclr32(volatile unsigned long *reg, unsigned long bits); - -#endif /* SYSTEM_TARGET_H */ diff --git a/firmware/target/arm/s3c2440/kernel-s3c2440.c b/firmware/target/arm/s3c2440/kernel-s3c2440.c new file mode 100644 index 0000000000..6cabc8dc81 --- /dev/null +++ b/firmware/target/arm/s3c2440/kernel-s3c2440.c @@ -0,0 +1,79 @@ +/*************************************************************************** +* __________ __ ___. +* Open \______ \ ____ ____ | | _\_ |__ _______ ___ +* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +* \/ \/ \/ \/ \/ +* $Id$ +* +* Copyright (C) 2007 by Michael Sevakis +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +* KIND, either express or implied. +* +****************************************************************************/ +#include "config.h" +#include "system.h" +#include "kernel.h" +#include "timer.h" +#include "thread.h" + +void tick_start(unsigned int interval_in_ms) +{ + /* + * Based on default PCLK of 49.1568MHz - scaling chosen to give + * remainder-free result for tick interval of 10ms (100Hz) + * Timer input clock frequency = + * fPCLK / {prescaler value+1} / {divider value} + * TIMER_FREQ = 49156800 / 2 + * 146300 = TIMER_FREQ / 21 / 8 + * 49156800 = 19*11*(7)*7*5*5*(3)*2*2*2*2*2*2 + * 21 = 7*3 + */ + + /* stop timer 4 */ + TCON &= ~(1 << 20); + /* Set the count for timer 4 */ + TCNTB4 = (TIMER_FREQ / TIMER234_PRESCALE / 8) * interval_in_ms / 1000; + /* Set the the prescaler value for timers 2,3, and 4 */ + TCFG0 = (TCFG0 & ~0xff00) | ((TIMER234_PRESCALE-1) << 8); + /* DMA mode off, MUX4 = 1/16 */ + TCFG1 = (TCFG1 & ~0xff0000) | 0x030000; + /* set manual bit */ + TCON |= 1 << 21; + /* reset manual bit */ + TCON &= ~(1 << 21); + + /* interval mode */ + TCON |= 1 << 22; + /* start timer 4 */ + TCON |= (1 << 20); + + /* timer 4 unmask interrupts */ + INTMSK &= ~TIMER4_MASK; +} + +#ifdef BOOTLOADER +void tick_stop(void) +{ + s3c_regset32(&INTMSK, TIMER4_MASK); + TCON &= ~(1 << 20); + SRCPND = TIMER4_MASK; + INTPND = TIMER4_MASK; +} +#endif + +void TIMER4(void) +{ + /* Run through the list of tick tasks */ + call_tick_tasks(); + + SRCPND = TIMER4_MASK; + INTPND = TIMER4_MASK; +} diff --git a/firmware/target/arm/s3c2440/lcd-s3c2440.c b/firmware/target/arm/s3c2440/lcd-s3c2440.c new file mode 100644 index 0000000000..b9f76b7400 --- /dev/null +++ b/firmware/target/arm/s3c2440/lcd-s3c2440.c @@ -0,0 +1,592 @@ +/*************************************************************************** +* __________ __ ___. +* Open \______ \ ____ ____ | | _\_ |__ _______ ___ +* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +* \/ \/ \/ \/ \/ +* $Id$ +* +* Copyright (C) 2007 by Greg White +* Copyright (C) 2009 by Bob Cousins +* +* 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 + +#include "config.h" +#include "system.h" +#include "cpu.h" +#include "string.h" +#include "lcd.h" +#include "kernel.h" +#include "lcd-target.h" + +#define LCDADDR(x, y) (&lcd_framebuffer[(y)][(x)]) + +static bool lcd_on = true; +#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) +static bool lcd_powered = true; +#endif +static unsigned lcd_yuv_options = 0; +/* +** This is imported from lcd-16bit.c +*/ +extern struct viewport* current_vp; + +/* Copies a rectangle from one framebuffer to another. Can be used in + single transfer mode with width = num pixels, and height = 1 which + allows a full-width rectangle to be copied more efficiently. */ +extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src, + int width, int height); + +#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) +bool lcd_active(void) +{ + return lcd_on; +} +#endif + +static unsigned int LCDBANK(unsigned int address) +{ + return ((address >> 22) & 0xff); +} + +static unsigned int LCDBASEU(unsigned int address) +{ + return (address & ((1 << 22)-1)) >> 1; +} + +static unsigned int LCDBASEL(unsigned int address) +{ + address += 320*240*2; + return (address & ((1 << 22)-1)) >> 1; +} + +static inline void delay_cycles(volatile int delay) +{ + while(delay>0) delay--; +} + +static void LCD_CTRL_setup(void) +{ + LCDCON1 = (LCD_CLKVAL << 8) | (LCD_MMODE << 7) | (LCD_PNRMODE << 5) | + (LCD_BPPMODE << 1); + LCDCON2 = (LCD_UPPER_MARGIN << 24) | ((LCD_HEIGHT - 1) << 14) | + (LCD_LOWER_MARGIN << 6) | (LCD_VSYNC_LEN << 0); + LCDCON3 = (LCD_LEFT_MARGIN << 19) | ((LCD_WIDTH - 1) << 8) | + (LCD_RIGHT_MARGIN << 0); + LCDCON4 = (LCD_HSYNC_LEN << 0); + + /* HWSWP = 1, INVVFRAM = 1, INVVLINE = 1, FRM565 = 1, All others = 0 */ + LCDCON5 = 0xB01; + + LCDSADDR1 = (LCDBANK((unsigned)FRAME) << 21) | (LCDBASEU((unsigned)FRAME)); + LCDSADDR2 = LCDBASEL((unsigned)FRAME); + LCDSADDR3 = 0x000000F0; +} + +static void LCD_CTRL_clock(bool onoff) +{ + if(onoff) + { + GPCCON &=~0xFFF000FC; + GPCCON |= 0xAAA000A8; + GPCUP |= 0xFC0E; + + GPDCON &=~0xFFF0FFF0; + GPDCON |= 0xAAA0AAA0; + GPDUP |= 0xFCFC; + + s3c_regset32(&CLKCON, 0x20); /* enable LCD clock */ + LCDCON1 |= LCD_ENVID; + } + else + { + GPCCON &= ~0xFFF000FC; + GPCUP &= ~0xFC0E; + + GPDCON &= ~0xFFF0FFF0; + GPDUP &= ~0xFCFC; + + LCDCON1 &= ~LCD_ENVID; /* Must disable first or bus may freeze */ + s3c_regclr32(&CLKCON, 0x20); /* disable LCD clock */ + } +} + +#ifdef GIGABEAT_F +static void reset_LCD(bool reset) +{ + GPBCON&=~0xC000; + GPBCON|=0x4000; + if(reset) + GPBDAT|=0x80; + else + GPBDAT&=~0x80; +} +#endif + + +/****************************************************************************/ +#ifdef GIGABEAT_F +static void LCD_SPI_send(const unsigned char *array, int count) +{ + while (count--) + { + while ((SPSTA0&0x01)==0){}; + SPTDAT0=*array++; + } +} + +static void LCD_SPI_setreg(unsigned char reg, unsigned char value) +{ + unsigned char regval[] = + { + 0x00,reg,0x01,value + }; + LCD_SPI_send(regval, sizeof(regval)); +} + +static void LCD_SPI_SS(bool select) +{ + delay_cycles(0x4FFF); + + GPBCON&=~0x30000; + GPBCON|=0x10000; + + if(select) + GPBDAT|=0x100; + else + GPBDAT&=~0x100; +} + +static void LCD_SPI_start(void) +{ + s3c_regset32(&CLKCON, 0x40000); /* enable SPI clock */ + LCD_SPI_SS(false); + SPCON0=0x3E; + SPPRE0=24; + + reset_LCD(true); + LCD_SPI_SS(true); +} + +static void LCD_SPI_stop(void) +{ + LCD_SPI_SS(false); + + SPCON0 &= ~0x10; + s3c_regclr32(&CLKCON, 0x40000); /* disable SPI clock */ +} + +static void LCD_SPI_init(void) +{ + /* + * SPI setup - Some of these registers are known; they are documented in + * the wiki. Many thanks to Alex Gerchanovsky for discovering this + * sequence. + */ + + LCD_CTRL_clock(true); + + LCD_SPI_start(); + LCD_SPI_setreg(0x0F, 0x01); + LCD_SPI_setreg(0x09, 0x06); + LCD_SPI_setreg(0x16, 0xA6); + LCD_SPI_setreg(0x1E, 0x49); + LCD_SPI_setreg(0x1F, 0x26); + LCD_SPI_setreg(0x0B, 0x2F); + LCD_SPI_setreg(0x0C, 0x2B); + LCD_SPI_setreg(0x19, 0x5E); + LCD_SPI_setreg(0x1A, 0x15); + LCD_SPI_setreg(0x1B, 0x15); + LCD_SPI_setreg(0x1D, 0x01); + LCD_SPI_setreg(0x00, 0x03); + LCD_SPI_setreg(0x01, 0x10); + LCD_SPI_setreg(0x02, 0x0A); + LCD_SPI_setreg(0x06, 0x04); /* Set the orientation */ + LCD_SPI_setreg(0x08, 0x2E); + LCD_SPI_setreg(0x24, 0x12); + LCD_SPI_setreg(0x25, 0x3F); + LCD_SPI_setreg(0x26, 0x0B); + LCD_SPI_setreg(0x27, 0x00); + LCD_SPI_setreg(0x28, 0x00); + LCD_SPI_setreg(0x29, 0xF6); + LCD_SPI_setreg(0x2A, 0x03); + LCD_SPI_setreg(0x2B, 0x0A); + LCD_SPI_setreg(0x04, 0x01); /* Turn the display on */ + LCD_SPI_stop(); +} +#endif +/****************************************************************************/ + +/* LCD init */ +void lcd_init_device(void) +{ +#ifdef BOOTLOADER + int i; + /* When the Rockbox bootloader starts the framebuffer address is changed + * but the LCD display should stay the same til an lcd_update() occurs. + * This copies the data from the old framebuffer to the new one to make the + * change non-visable to the user. + */ + unsigned short *buf = (unsigned short*)(FRAME); + unsigned short *oldbuf = (unsigned short*)(LCDSADDR1<<1); + + /* The Rockbox bootloader is transitioning from RGB555I to RGB565 mode + so convert the frambuffer data accordingly */ + for(i=0; i< 320*240; i++) + { + *(buf++) = ((*oldbuf>>1) & 0x1F) | (*oldbuf & 0xffc0); + oldbuf++; + } +#endif + + /* Set pins up */ + GPHUP &= 0x600; + GPECON |= 0x0A800000; + GPEUP |= 0x3800; +#ifdef GIGABEAT_F + GPBUP |= 0x181; +#endif + + s3c_regset32(&CLKCON, 0x20); /* enable LCD clock */ + + LCD_CTRL_setup(); +#ifdef GIGABEAT_F + LCD_SPI_init(); +#else + LCD_CTRL_clock(true); +#endif +} + +#if defined(HAVE_LCD_SLEEP) +static void LCD_SPI_powerdown(void) +{ + lcd_powered = false; + + LCD_SPI_start(); + LCD_SPI_setreg(0x04, 0x00); + LCD_SPI_stop(); + + reset_LCD(false); /* This makes a big difference on power */ + LCD_CTRL_clock(false); +} + +void lcd_sleep(void) +{ + if (lcd_powered) + { + /* "not powered" implies "disabled" */ + if (lcd_on) + lcd_enable(false); + + LCD_SPI_powerdown(); + } +} +#endif + +#if defined(HAVE_LCD_ENABLE) +static void LCD_SPI_powerup(void) +{ + LCD_CTRL_clock(true); + + LCD_SPI_start(); + LCD_SPI_setreg(0x04, 0x01); + LCD_SPI_stop(); + + lcd_powered = true; +} + +void lcd_enable(bool state) +{ + if (state == lcd_on) + return; + + if(state) + { + /* "enabled" implies "powered" */ + if (!lcd_powered) + { + LCD_SPI_powerup(); + /* Wait long enough for a frame to be written - yes, it + * takes awhile. */ + sleep(HZ/5); + } + + lcd_on = true; + lcd_update(); + lcd_activation_call_hook(); + } + else + { + lcd_on = false; + } +} +#endif + +#ifdef GIGABEAT_F +void lcd_set_flip(bool yesno) { + if (!lcd_on) + return; + + LCD_SPI_start(); + if(yesno) + { + LCD_SPI_setreg(0x06, 0x02); + } + else + { + LCD_SPI_setreg(0x06, 0x04); + } + LCD_SPI_stop(); +} + +int lcd_default_contrast(void) +{ + return DEFAULT_CONTRAST_SETTING; +} + +void lcd_set_contrast(int val) { + if (!lcd_on) + return; + + LCD_SPI_start(); + LCD_SPI_setreg(0x0B, (unsigned char) val); + LCD_SPI_stop(); +} + +void lcd_set_invert_display(bool yesno) { + if (!lcd_on) + return; + + LCD_SPI_start(); + if(yesno) + { + LCD_SPI_setreg(0x27, 0x10); + } + else + { + LCD_SPI_setreg(0x27, 0x00); + } + LCD_SPI_stop(); +} +#else +void lcd_set_flip(bool yesno) +{ + (void)yesno; + /* Not implemented */ +} + +int lcd_default_contrast(void) +{ + return DEFAULT_CONTRAST_SETTING; +} + +void lcd_set_contrast(int val) +{ + (void)val; + /* Not implemented */ +} + +void lcd_set_invert_display(bool yesno) +{ + (void)yesno; + /* Not implemented */ +} + +#endif + +/* Update a fraction of the display. */ +void lcd_update_rect(int x, int y, int width, int height) +{ + fb_data *dst, *src; + + if (!lcd_on) + return; + + if (x + width > LCD_WIDTH) + width = LCD_WIDTH - x; /* Clip right */ + if (x < 0) + width += x, x = 0; /* Clip left */ + if (width <= 0) + return; /* nothing left to do */ + + if (y + height > LCD_HEIGHT) + height = LCD_HEIGHT - y; /* Clip bottom */ + if (y < 0) + height += y, y = 0; /* Clip top */ + if (height <= 0) + return; /* nothing left to do */ + + /* TODO: It may be faster to swap the addresses of lcd_driver_framebuffer + * and lcd_framebuffer */ + dst = (fb_data *)FRAME + LCD_WIDTH*y + x; + src = &lcd_framebuffer[y][x]; + + /* Copy part of the Rockbox framebuffer to the second framebuffer */ + if (width < LCD_WIDTH) + { + /* Not full width - do line-by-line */ + lcd_copy_buffer_rect(dst, src, width, height); + } + else + { + /* Full width - copy as one line */ + lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1); + } +} + +/* Update the display. + This must be called after all other LCD functions that change the display. */ +void lcd_update(void) +{ + if (!lcd_on) + return; + + lcd_copy_buffer_rect((fb_data *)FRAME, &lcd_framebuffer[0][0], + LCD_WIDTH*LCD_HEIGHT, 1); +} + +#if defined(TOSHIBA_GIGABEAT_F) || defined(TOSHIBA_GIGABEAT_S) +void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y, + int stride, int x, int y, int width, + int height) +{ + int w, px; + fb_data *dst; + + if (x + width > current_vp->width) + width = current_vp->width - x; /* Clip right */ + + if (x < 0) /* Clip left */ + { + width += x; + src_x -= x; + x = 0; + } + + if (width <= 0) + return; /* nothing left to do */ + + if (y + height > current_vp->height) + height = current_vp->height - y; /* Clip bottom */ + + if (y < 0) /* Clip top */ + { + height += y; + src_y -= y; + y = 0; + } + + if (height <= 0) + return; /* nothing left to do */ + + src += stride * src_y + src_x; /* move starting point */ + dst = &lcd_framebuffer[current_vp->y+y][current_vp->x+x]; + + asm volatile ( + ".rowstart: \r\n" + "mov %[w], %[width] \r\n" /* Load width for inner loop */ + ".nextpixel: \r\n" + "ldrh %[px], [%[s]], #2 \r\n" /* Load src pixel */ + "add %[d], %[d], #2 \r\n" /* Uncoditionally increment dst */ + "cmp %[px], %[fgcolor] \r\n" /* Compare to foreground color */ + "streqh %[fgpat], [%[d], #-2] \r\n" /* Store foregroud if match */ + "cmpne %[px], %[transcolor] \r\n" /* Compare to transparent color */ + "strneh %[px], [%[d], #-2] \r\n" /* Store dst if not transparent */ + "subs %[w], %[w], #1 \r\n" /* Width counter has run down? */ + "bgt .nextpixel \r\n" /* More in this row? */ + "add %[s], %[s], %[sstp], lsl #1 \r\n" /* Skip over to start of next line */ + "add %[d], %[d], %[dstp], lsl #1 \r\n" + "subs %[h], %[h], #1 \r\n" /* Height counter has run down? */ + "bgt .rowstart \r\n" /* More rows? */ + : [w]"=&r"(w), [h]"+&r"(height), [px]"=&r"(px), + [s]"+&r"(src), [d]"+&r"(dst) + : [width]"r"(width), + [sstp]"r"(stride - width), + [dstp]"r"(LCD_WIDTH - width), + [transcolor]"r"(TRANSPARENT_COLOR), + [fgcolor]"r"(REPLACEWITHFG_COLOR), + [fgpat]"r"(current_vp->fg_pattern) + ); +} +#endif + +void lcd_yuv_set_options(unsigned options) +{ + lcd_yuv_options = options; +} + +/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ +extern void lcd_write_yuv420_lines(fb_data *dst, + unsigned char const * const src[3], + int width, + int stride); +extern void lcd_write_yuv420_lines_odither(fb_data *dst, + unsigned char const * const src[3], + int width, + int stride, + int x_screen, /* To align dither pattern */ + int y_screen); +/* Performance function to blit a YUV bitmap directly to the LCD */ +/* For the Gigabeat - show it rotated */ +/* So the LCD_WIDTH is now the 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) +{ + /* Caches for chroma data so it only need be recaculated every other + line */ + unsigned char const * yuv_src[3]; + off_t z; + + if (!lcd_on) + return; + + /* Sorry, but width and height must be >= 2 or else */ + width &= ~1; + height >>= 1; + + y = LCD_WIDTH - 1 - y; + fb_data *dst = (fb_data*)FRAME + x * LCD_WIDTH + y; + + z = stride*src_y; + yuv_src[0] = src[0] + z + src_x; + yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); + yuv_src[2] = src[2] + (yuv_src[1] - src[1]); + + if (lcd_yuv_options & LCD_YUV_DITHER) + { + do + { + lcd_write_yuv420_lines_odither(dst, yuv_src, width, stride, y, x); + yuv_src[0] += stride << 1; /* Skip down two luma lines */ + yuv_src[1] += stride >> 1; /* Skip down one chroma line */ + yuv_src[2] += stride >> 1; + dst -= 2; + y -= 2; + } + while (--height > 0); + } + else + { + do + { + lcd_write_yuv420_lines(dst, yuv_src, width, stride); + yuv_src[0] += stride << 1; /* Skip down two luma lines */ + yuv_src[1] += stride >> 1; /* Skip down one chroma line */ + yuv_src[2] += stride >> 1; + dst -= 2; + } + while (--height > 0); + } +} + diff --git a/firmware/target/arm/s3c2440/mini2440/adc-target.h b/firmware/target/arm/s3c2440/mini2440/adc-target.h new file mode 100644 index 0000000000..24e878e735 --- /dev/null +++ b/firmware/target/arm/s3c2440/mini2440/adc-target.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 by Bob Cousins + * + * 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. + * + ****************************************************************************/ +#ifndef _ADC_TARGET_H_ +#define _ADC_TARGET_H_ + +/* Channel 0 is connected to an on board pot for testing + Channels 0-3 are available via expansion connector CON4 + Channels 4-7 are routed to LCD connector for touchscreen operation if + supported by display panel. +*/ +#define NUM_ADC_CHANNELS 8 + +#define ADC_ONBOARD 0 +#define ADC_SPARE_1 1 +#define ADC_SPARE_2 2 +#define ADC_SPARE_3 3 +#define ADC_TSYM 4 +#define ADC_TSYP 5 +#define ADC_TSXM 6 +#define ADC_TSXP 7 + +#define ADC_READ_ERROR 0xFFFF + +#endif diff --git a/firmware/target/arm/s3c2440/mini2440/backlight-mini2440.c b/firmware/target/arm/s3c2440/mini2440/backlight-mini2440.c new file mode 100644 index 0000000000..88c0b5ce2c --- /dev/null +++ b/firmware/target/arm/s3c2440/mini2440/backlight-mini2440.c @@ -0,0 +1,151 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 by Bob Cousins + * + * 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 "cpu.h" +#include "system.h" +#include "backlight-target.h" +#include "backlight.h" +#include "lcd.h" +#include "power.h" + + +/* Dummy value at index 0, 1-12 used. */ +static const unsigned char log_brightness[13] = + {0,0,1,2,3,5,7,10,15,22,31,44,63}; + + +static enum backlight_states +{ + BACKLIGHT_CONTROL_IDLE, + BACKLIGHT_CONTROL_OFF, + BACKLIGHT_CONTROL_ON, + BACKLIGHT_CONTROL_SET, + BACKLIGHT_CONTROL_FADE +} backlight_control; + +static unsigned char _backlight_brightness; +static unsigned char backlight_target; + + +/* Assumes that the backlight has been initialized */ +void _backlight_set_brightness(int brightness) +{ + /* stop the interrupt from messing us up */ + backlight_control = BACKLIGHT_CONTROL_IDLE; + _backlight_brightness = log_brightness[brightness]; + backlight_control = BACKLIGHT_CONTROL_SET; +} + +void _backlight_set_state (unsigned int level) +{ + if (level == 0) + GPGDAT &= ~GPIO_LCD_PWR; + else + GPGDAT |= GPIO_LCD_PWR; +} + +/* led_control_service runs in interrupt context - be brief! + * This service is called once per interrupt timer tick - 100 times a second. + * + * There should be at most only one i2c operation per call - if more are need + * the calls should be spread across calls. + * + * Putting all led servicing in one thread means that we wont step on any + * i2c operations - they are all serialized here in the ISR tick. It also + * insures that we get called at equal timing for good visual effect. + */ +#ifndef BOOTLOADER +static void led_control_service(void) +{ + switch (backlight_control) + { + case BACKLIGHT_CONTROL_IDLE: + backlight_control = BACKLIGHT_CONTROL_IDLE; + break; + case BACKLIGHT_CONTROL_OFF: + _backlight_set_brightness(0); + backlight_control = BACKLIGHT_CONTROL_IDLE; + break; + case BACKLIGHT_CONTROL_ON: + _backlight_set_brightness(255); + backlight_control = BACKLIGHT_CONTROL_IDLE; + break; + case BACKLIGHT_CONTROL_SET: + _backlight_set_brightness(255); + backlight_control = BACKLIGHT_CONTROL_IDLE; + break; + case BACKLIGHT_CONTROL_FADE: + _backlight_set_brightness(0); + backlight_control = BACKLIGHT_CONTROL_IDLE; + break; + default: + backlight_control = BACKLIGHT_CONTROL_IDLE; + break; + } +} +#endif /* BOOTLOADER */ + +static void __backlight_dim(bool dim_now) +{ + /* dont let the interrupt tick happen */ + backlight_control = BACKLIGHT_CONTROL_IDLE; + backlight_target = dim_now ? 0 : _backlight_brightness; + if(backlight_target==0 && _backlight_brightness==0) + { + if(dim_now == false) + backlight_control = BACKLIGHT_CONTROL_ON; + else + backlight_control = BACKLIGHT_CONTROL_OFF; + } + else + backlight_control = BACKLIGHT_CONTROL_FADE; +} + +void _backlight_on(void) +{ +#ifdef HAVE_LCD_ENABLE + lcd_enable(true); /* power on lcd + visible display */ +#endif + __backlight_dim(false); +} + +void _backlight_off(void) +{ + __backlight_dim(true); +} + + +bool _backlight_init(void) +{ + unsigned char brightness = log_brightness[DEFAULT_BRIGHTNESS_SETTING]; + _backlight_brightness = brightness; + + backlight_control = BACKLIGHT_CONTROL_ON; + + _backlight_set_state (1); + S3C2440_GPIO_CONFIG (GPGCON, 4, GPIO_OUTPUT); + +#ifndef BOOTLOADER + /* put the led control on the tick list */ + tick_add_task(led_control_service); +#endif + return true; +} diff --git a/firmware/target/arm/s3c2440/mini2440/backlight-target.h b/firmware/target/arm/s3c2440/mini2440/backlight-target.h new file mode 100644 index 0000000000..c804f16bcc --- /dev/null +++ b/firmware/target/arm/s3c2440/mini2440/backlight-target.h @@ -0,0 +1,31 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 by Linus Nielsen Feltzing + * + * 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. + * + ****************************************************************************/ +#ifndef BACKLIGHT_TARGET_H +#define BACKLIGHT_TARGET_H + +#define GPIO_LCD_PWR (1 << 4) /* GPIO.G4 */ + +bool _backlight_init(void); +void _backlight_on(void); +void _backlight_off(void); +void _backlight_set_brightness(int brightness); + +#endif diff --git a/firmware/target/arm/s3c2440/mini2440/button-mini2440.c b/firmware/target/arm/s3c2440/mini2440/button-mini2440.c new file mode 100644 index 0000000000..787c04d1ef --- /dev/null +++ b/firmware/target/arm/s3c2440/mini2440/button-mini2440.c @@ -0,0 +1,80 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 by Bob Cousins + * + * 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 "cpu.h" +#include "system.h" +#include "button.h" +#include "kernel.h" + +void button_init_device(void) +{ + /* Configure port directions and enable internal pullups on button inputs */ + + /* These are the standard 6 buttons on the Mini2440 */ + S3C2440_GPIO_CONFIG (GPGCON, 0, GPIO_INPUT); + S3C2440_GPIO_CONFIG (GPGCON, 3, GPIO_INPUT); + S3C2440_GPIO_CONFIG (GPGCON, 5, GPIO_INPUT); + S3C2440_GPIO_CONFIG (GPGCON, 6, GPIO_INPUT); + S3C2440_GPIO_CONFIG (GPGCON, 7, GPIO_INPUT); + S3C2440_GPIO_CONFIG (GPGCON, 11, GPIO_INPUT); + + S3C2440_GPIO_PULLUP (GPGUP, 0, GPIO_PULLUP_ENABLE); + S3C2440_GPIO_PULLUP (GPGUP, 3, GPIO_PULLUP_ENABLE); + S3C2440_GPIO_PULLUP (GPGUP, 5, GPIO_PULLUP_ENABLE); + S3C2440_GPIO_PULLUP (GPGUP, 6, GPIO_PULLUP_ENABLE); + S3C2440_GPIO_PULLUP (GPGUP, 7, GPIO_PULLUP_ENABLE); + S3C2440_GPIO_PULLUP (GPGUP, 11, GPIO_PULLUP_ENABLE); + + /* These are additional buttons on my add on keypad */ + S3C2440_GPIO_CONFIG (GPGCON, 9, GPIO_INPUT); + S3C2440_GPIO_CONFIG (GPGCON, 10, GPIO_INPUT); + S3C2440_GPIO_PULLUP (GPGUP, 9, GPIO_PULLUP_ENABLE); + S3C2440_GPIO_PULLUP (GPGUP, 10, GPIO_PULLUP_ENABLE); + +} + +inline bool button_hold(void) +{ + return 0; +} + +int button_read_device(void) +{ + int btn = BUTTON_NONE; + + /* Read the buttons - active low */ + btn = (GPGDAT & BUTTON_MAIN) ^ BUTTON_MAIN; + + return btn; +} + +void touchpad_set_sensitivity(int level) +{ + (void)level; + /* No touchpad */ +} + +bool headphones_inserted(void) +{ + /* No detect */ + return false; +} diff --git a/firmware/target/arm/s3c2440/mini2440/button-target.h b/firmware/target/arm/s3c2440/mini2440/button-target.h new file mode 100644 index 0000000000..4a84014462 --- /dev/null +++ b/firmware/target/arm/s3c2440/mini2440/button-target.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 by Bob Cousins + * + * 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. + * + ****************************************************************************/ +#ifndef _BUTTON_TARGET_H_ +#define _BUTTON_TARGET_H_ + +#include +#include "config.h" + + +bool button_hold(void); +void button_init_device(void); +int button_read_device(void); +void touchpad_set_sensitivity(int level); + +/* Mini2440 specific button codes */ + +#define BUTTON_ONE 0x0001 +#define BUTTON_TWO 0x0008 +#define BUTTON_THREE 0x0020 +#define BUTTON_FOUR 0x0040 +#define BUTTON_FIVE 0x0080 +#define BUTTON_SIX 0x0800 + +/* Add on buttons */ +#define BUTTON_SEVEN 0x0200 +#define BUTTON_EIGHT 0x0400 + +#define BUTTON_MENU BUTTON_ONE +#define BUTTON_UP BUTTON_TWO +#define BUTTON_SELECT BUTTON_THREE +#define BUTTON_DOWN BUTTON_FOUR +#define BUTTON_LEFT BUTTON_FIVE +#define BUTTON_RIGHT BUTTON_SIX + +/* Add on buttons */ +#define BUTTON_A BUTTON_SEVEN +#define BUTTON_POWER BUTTON_EIGHT + +/* TODO: bodge to keep keymap-mini2440 happy */ +#define BUTTON_VOL_DOWN 0x4000 +#define BUTTON_VOL_UP 0x8000 + +#define BUTTON_MAIN (BUTTON_MENU|BUTTON_LEFT|BUTTON_RIGHT | \ + BUTTON_UP |BUTTON_DOWN|BUTTON_SELECT | \ + BUTTON_A |BUTTON_POWER ) + +#define BUTTON_REMOTE 0 + +#define POWEROFF_BUTTON BUTTON_MENU +#define POWEROFF_COUNT 10 + +#endif /* _BUTTON_TARGET_H_ */ diff --git a/firmware/target/arm/s3c2440/mini2440/lcd-target.h b/firmware/target/arm/s3c2440/mini2440/lcd-target.h new file mode 100644 index 0000000000..b2882e2390 --- /dev/null +++ b/firmware/target/arm/s3c2440/mini2440/lcd-target.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 by Bob Cousins, Lyre Project + * + * 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. + * + ****************************************************************************/ + +extern void lcd_enable(bool state); + +/* Setup for Mini2440, 3.5" TFT LCD Touchscreen */ + +/* Config values for LCDCON1 */ +#define LCD_CLKVAL 4 +#define LCD_MMODE 0 +#define LCD_PNRMODE 3 +#define LCD_BPPMODE 12 +#define LCD_ENVID 1 + +/* Config values for LCDCON2 */ +#define LCD_UPPER_MARGIN 1 +#define LCD_LOWER_MARGIN 4 +#define LCD_VSYNC_LEN 1 + +/* Config values for LCDCON3 */ +#define LCD_RIGHT_MARGIN 0 +#define LCD_LEFT_MARGIN 25 + +/* Config values for LCDCON4 */ +#define LCD_HSYNC_LEN 4 diff --git a/firmware/target/arm/s3c2440/mini2440/led-mini2440.c b/firmware/target/arm/s3c2440/mini2440/led-mini2440.c new file mode 100644 index 0000000000..f541d75273 --- /dev/null +++ b/firmware/target/arm/s3c2440/mini2440/led-mini2440.c @@ -0,0 +1,66 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 by Bob Cousins + * + * 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 "cpu.h" +#include "kernel.h" + +/* LED functions for debug */ + +void led_init (void) +{ + S3C2440_GPIO_CONFIG (GPBCON, 5, GPIO_OUTPUT); + S3C2440_GPIO_CONFIG (GPBCON, 6, GPIO_OUTPUT); + S3C2440_GPIO_CONFIG (GPBCON, 7, GPIO_OUTPUT); + S3C2440_GPIO_CONFIG (GPBCON, 8, GPIO_OUTPUT); + + S3C2440_GPIO_PULLUP (GPBUP, 5, GPIO_PULLUP_DISABLE); + S3C2440_GPIO_PULLUP (GPBUP, 6, GPIO_PULLUP_DISABLE); + S3C2440_GPIO_PULLUP (GPBUP, 7, GPIO_PULLUP_DISABLE); + S3C2440_GPIO_PULLUP (GPBUP, 8, GPIO_PULLUP_DISABLE); +} + +/* Turn on one or more LEDS */ +void set_leds (int led_mask) +{ + GPBDAT &= ~led_mask; +} + +/* Turn off one or more LEDS */ +void clear_leds (int led_mask) +{ + GPBDAT |= led_mask; +} + +/* Alternate flash pattern1 and pattern2 */ +/* Never returns */ +void led_flash (int led_pattern1, int led_pattern2) +{ + while (1) + { + set_leds (led_pattern1); + sleep(HZ/2); + clear_leds (led_pattern1); + + set_leds(led_pattern2); + sleep(HZ/2); + clear_leds (led_pattern2); + } +} diff --git a/firmware/target/arm/s3c2440/mini2440/led-mini2440.h b/firmware/target/arm/s3c2440/mini2440/led-mini2440.h new file mode 100644 index 0000000000..0aaad1c9a4 --- /dev/null +++ b/firmware/target/arm/s3c2440/mini2440/led-mini2440.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 by Bob Cousins + * + * 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. + * + ****************************************************************************/ + +#ifndef _LED_MINI2440_H_ +#define _LED_MINI2440_H_ + +/* LED functions for debug etc */ + +#define LED1 0x0020 /* GPB5 */ +#define LED2 0x0040 /* GPB6 */ +#define LED3 0x0080 /* GPB7 */ +#define LED4 0x0100 /* GPB8 */ + +#define LED_NONE 0x0000 +#define LED_ALL (LED1|LED2|LED3|LED4) + +void led_init (void); + +/* Turn on one or more LEDS */ +void set_leds (int led_mask); + +/* Turn off one or more LEDS */ +void clear_leds (int led_mask); + +/* Alternate flash of pattern1 and pattern2 - never returns */ +void led_flash (int led_pattern1, int led_pattern2); + +#endif /* _LED_MINI2440_H_ */ diff --git a/firmware/target/arm/s3c2440/mini2440/power-mini2440.c b/firmware/target/arm/s3c2440/mini2440/power-mini2440.c new file mode 100644 index 0000000000..d4b00751e0 --- /dev/null +++ b/firmware/target/arm/s3c2440/mini2440/power-mini2440.c @@ -0,0 +1,55 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 by Bob Cousins + * + * 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 "cpu.h" +#include +#include +#include "kernel.h" +#include "system.h" +#include "power.h" +#include "led-mini2440.h" + +void power_init(void) +{ + /* Nothing to do */ +} + +unsigned int power_input_status(void) +{ + unsigned int status = 0; + + /* Always on*/ + status = POWER_INPUT_MAIN; + return status; +} + +/* Returns true if the unit is charging the batteries. */ +bool charging_state(void) +{ + return false; +} + +void power_off(void) +{ + /* we don't have any power control, user must do it */ + led_flash (LED_NONE, LED_ALL); + while (1); +} diff --git a/firmware/target/arm/s3c2440/system-s3c2440.c b/firmware/target/arm/s3c2440/system-s3c2440.c new file mode 100644 index 0000000000..6b7609b88b --- /dev/null +++ b/firmware/target/arm/s3c2440/system-s3c2440.c @@ -0,0 +1,249 @@ +/*************************************************************************** +* __________ __ ___. +* Open \______ \ ____ ____ | | _\_ |__ _______ ___ +* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +* \/ \/ \/ \/ \/ +* $Id$ +* +* Copyright (C) 2007 by Michael Sevakis +* +* 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 "kernel.h" +#include "system.h" +#include "panic.h" +#include "mmu-arm.h" +#include "cpu.h" + +#define default_interrupt(name) \ + extern __attribute__((weak,alias("UIRQ"))) void name (void) + +default_interrupt(EINT0); +default_interrupt(EINT1); +default_interrupt(EINT2); +default_interrupt(EINT3); +default_interrupt(EINT4_7); +default_interrupt(EINT8_23); +default_interrupt(CAM); +default_interrupt(nBATT_FLT); +default_interrupt(TICK); +default_interrupt(WDT_AC97); +default_interrupt(TIMER0); +default_interrupt(TIMER1); +default_interrupt(TIMER2); +default_interrupt(TIMER3); +default_interrupt(TIMER4); +default_interrupt(UART2); +default_interrupt(LCD); +default_interrupt(DMA0); +default_interrupt(DMA1); +default_interrupt(DMA2); +default_interrupt(DMA3); +default_interrupt(SDI); +default_interrupt(SPI0); +default_interrupt(UART1); +default_interrupt(NFCON); +default_interrupt(USBD); +default_interrupt(USBH); +default_interrupt(IIC); +default_interrupt(UART0); +default_interrupt(SPI1); +default_interrupt(RTC); +default_interrupt(ADC); + +static void (* const irqvector[32])(void) __attribute__((__used__)) = +{ + EINT0, EINT1, EINT2, EINT3, + EINT4_7, EINT8_23, CAM, nBATT_FLT, TICK, WDT_AC97, + TIMER0, TIMER1, TIMER2, TIMER3, TIMER4, UART2, + LCD, DMA0, DMA1, DMA2, DMA3, SDI, + SPI0, UART1, NFCON, USBD, USBH, IIC, + UART0, SPI1, RTC, ADC, +}; + +static const char * const irqname[32] = +{ + "EINT0", "EINT1", "EINT2", "EINT3", + "EINT4_7", "EINT8_23", "CAM", "nBATT_FLT", "TICK", "WDT_AC97", + "TIMER0", "TIMER1", "TIMER2", "TIMER3", "TIMER4", "UART2", + "LCD", "DMA0", "DMA1", "DMA2", "DMA3", "SDI", + "SPI0", "UART1", "NFCON", "USBD", "USBH", "IIC", + "UART0", "SPI1", "RTC", "ADC" +}; + +static void UIRQ(void) +{ + unsigned int offset = INTOFFSET; + panicf("Unhandled IRQ %02X: %s", offset, irqname[offset]); +} + +void irq_handler(void) __attribute__((interrupt ("IRQ"), naked)); +void irq_handler(void) +{ + asm volatile ( + "sub lr, lr, #4 \r\n" + "stmfd sp!, {r0-r3, ip, lr} \r\n" + "mov r0, #0x4a000000 \r\n" /* INTOFFSET = 0x4a000014 */ + "ldr r0, [r0, #0x14] \r\n" + "ldr r1, =irqvector \r\n" + "ldr r1, [r1, r0, lsl #2] \r\n" + "mov lr, pc \r\n" + "bx r1 \r\n" + "ldmfd sp!, {r0-r3, ip, pc}^ \r\n" + ); +} + +void system_reboot(void) +{ + WTCON = 0; + WTCNT = WTDAT = 1 ; + WTCON = 0x21; + for(;;) + ; +} + +void system_exception_wait(void) +{ + INTMSK = 0xFFFFFFFF; + while ((GPGDAT & (1 << 0)) == 0); /* Wait for power button */ +} + +static void set_page_tables(void) +{ + /* map every memory region to itself */ + map_section(0, 0, 0x1000, CACHE_NONE); + + /* map RAM to 0 and enable caching for it */ + map_section(0x30000000, 0, 32, CACHE_ALL); + + /* enable buffered writing for the framebuffer */ + map_section((int)FRAME, (int)FRAME, 1, BUFFERED); +} + +void memory_init(void) +{ + ttb_init(); + set_page_tables(); + enable_mmu(); +} + +void s3c_regmod32(volatile unsigned long *reg, unsigned long bits, + unsigned long mask) +{ + int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS); + *reg = (*reg & ~mask) | (bits & mask); + restore_interrupt(oldstatus); +} + +void s3c_regset32(volatile unsigned long *reg, unsigned long bits) +{ + s3c_regmod32(reg, bits, bits); +} + +void s3c_regclr32(volatile unsigned long *reg, unsigned long bits) +{ + s3c_regmod32(reg, 0, bits); +} + +#ifdef BOOTLOADER +void system_prepare_fw_start(void) +{ + tick_stop(); + disable_interrupt(IRQ_FIQ_STATUS); + INTMSK = 0xFFFFFFFF; +} +#endif + +void system_init(void) +{ +#ifdef GIGABEAT_F + INTMSK = 0xFFFFFFFF; + INTMOD = 0; + SRCPND = 0xFFFFFFFF; + INTPND = 0xFFFFFFFF; + INTSUBMSK = 0xFFFFFFFF; + SUBSRCPND = 0xFFFFFFFF; + + GPBCON |= 0x85; + GPBDAT |= 0x07; + GPBUP |= 0x20F; + + /* Take care of flash related pins */ + GPCCON |= 0x1000; + GPCDAT &= ~0x40; + GPCUP |= 0x51; + + GPDCON |= 0x05; + GPDUP |= 0x03; + GPDDAT &= ~0x03; + + GPFCON |= 0x00000AAA; + GPFUP |= 0xFF; + + GPGCON |= 0x01001000; + GPGUP |= 0x70; + + GPHCON |= 0x4005; + GPHDAT |= 0x03; + + /* TODO: do something with PRIORITY */ + + /* Turn off currently-not or never-needed devices. + * Be careful here, it is possible to freeze the device by disabling + * clocks at the wrong time. + * + * Turn off AC97, Camera, SPI, IIS, I2C, UARTS, MMC/SD/SDIO Controller + * USB device, USB host, NAND flash controller. + * + * IDLE, Sleep, LCDC, PWM timer, GPIO, RTC, and ADC are untouched (on) + */ + CLKCON &= ~0xFF1ED0; + + CLKSLOW |= 0x80; +#elif defined(MINI2440) + /* TODO: anything? */ +#else +#error Unknown target +#endif +} + +int system_memory_guard(int newmode) +{ + (void)newmode; + return 0; +} + +#ifdef HAVE_ADJUSTABLE_CPU_FREQ + +void set_cpu_frequency(long frequency) +{ + if (frequency == CPUFREQ_MAX) + { + asm volatile("mov r0, #0\n" + "mrc p15, 0, r0, c1, c0, 0\n" + "orr r0, r0, #3<<30\n" /* set to Asynchronous mode*/ + "mcr p15, 0, r0, c1, c0, 0" : : : "r0"); + + FREQ = CPUFREQ_MAX; + } + else + { + asm volatile("mov r0, #0\n" + "mrc p15, 0, r0, c1, c0, 0\n" + "bic r0, r0, #3<<30\n" /* set to FastBus mode*/ + "mcr p15, 0, r0, c1, c0, 0" : : : "r0"); + + FREQ = CPUFREQ_NORMAL; + } +} + +#endif diff --git a/firmware/target/arm/s3c2440/system-target.h b/firmware/target/arm/s3c2440/system-target.h new file mode 100644 index 0000000000..9808d31255 --- /dev/null +++ b/firmware/target/arm/s3c2440/system-target.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 by Greg White + * + * 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. + * + ****************************************************************************/ +#ifndef SYSTEM_TARGET_H +#define SYSTEM_TARGET_H + +#include "system-arm.h" +#include "mmu-arm.h" + +/* TODO: Needs checking/porting */ + +#ifdef GIGABEAT_F +#define CPUFREQ_DEFAULT 98784000 +#define CPUFREQ_NORMAL 98784000 +#define CPUFREQ_MAX 296352000 + +#ifdef BOOTLOADER +/* All addresses within rockbox are in IRAM in the bootloader so + are therefore uncached */ +#define UNCACHED_ADDR(a) (a) +#else /* !BOOTLOADER */ +#define UNCACHED_BASE_ADDR 0x30000000 +#define UNCACHED_ADDR(a) ((typeof(a))((unsigned int)(a) | UNCACHED_BASE_ADDR )) +#endif /* BOOTLOADER */ + +#elif defined(MINI2440) + +#define CPUFREQ_DEFAULT 101250000 +#define CPUFREQ_NORMAL 101250000 +#define CPUFREQ_MAX 405000000 + +#define UNCACHED_BASE_ADDR 0x30000000 +#define UNCACHED_ADDR(a) ((typeof(a))((unsigned int)(a) | UNCACHED_BASE_ADDR )) + +#else +#error Unknown target +#endif + + +void system_prepare_fw_start(void); +void tick_stop(void); + +/* Functions to set and clear register bits atomically */ + +/* Set and clear register bits */ +void s3c_regmod32(volatile unsigned long *reg, unsigned long bits, + unsigned long mask); +/* Set register bits */ +void s3c_regset32(volatile unsigned long *reg, unsigned long bits); +/* Clear register bits */ +void s3c_regclr32(volatile unsigned long *reg, unsigned long bits); + +#endif /* SYSTEM_TARGET_H */ diff --git a/tools/configure b/tools/configure index 3e54f818e5..6246c428a6 100755 --- a/tools/configure +++ b/tools/configure @@ -893,7 +893,7 @@ cat <