1
0
Fork 0
forked from len0rd/rockbox

Initial Cowon D2 commit:

* bootloader test program (basic LCD & button drivers, reads touchscreen)
* work-in-progress stubs for main build


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16090 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Rob Purchase 2008-01-14 22:04:48 +00:00
parent b30ca8ca5a
commit 47ea030e2e
42 changed files with 3082 additions and 11 deletions

View file

@ -0,0 +1,76 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 by Dave Chapman
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* 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 "kernel.h"
#include "thread.h"
#include "string.h"
#include "adc.h"
/*
TODO: We probably want to do this on the timer interrupt once we get
interrupts going - see the sh-adc.c implementation for an example which
looks like it should work well with the TCC77x.
Also, this code is practically identical between 77x & 780x targets.
Should probably find a common location to avoid the duplication.
*/
static unsigned short adcdata[8];
static void adc_do_read(void)
{
int i;
uint32_t adc_status;
PCLK_ADC |= PCK_EN; /* Enable ADC clock */
/* Start converting the first 4 channels */
for (i = 0; i < 4; i++)
ADCCON = i;
/* Wait for data to become stable */
while ((ADCDATA & 0x1) == 0);
/* Now read the values back */
for (i=0;i < 4; i++) {
adc_status = ADCSTATUS;
adcdata[(adc_status >> 16) & 0x7] = adc_status & 0x3ff;
}
PCLK_ADC &= ~PCK_EN; /* Disable ADC clock */
}
unsigned short adc_read(int channel)
{
/* Either move this to an interrupt routine, or only perform the read if
the last call was X length of time ago. */
adc_do_read();
return adcdata[channel];
}
void adc_init(void)
{
/* consider configuring PCK_ADC source here */
ADCCON = (1<<4); /* Leave standby mode */
ADCCFG |= 0x00000003; /* Single-mode, auto power-down */
}

View file

@ -0,0 +1,113 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 Dave Chapman
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "ata.h"
#include "ata-target.h"
#include "ata_idle_notify.h"
#include "system.h"
#include <string.h>
#include "thread.h"
#include "led.h"
#include "disk.h"
#include "panic.h"
#include "usb.h"
/* for compatibility */
int ata_spinup_time = 0;
long last_disk_activity = -1;
/** static, private data **/
static bool initialized = false;
static long next_yield = 0;
#define MIN_YIELD_PERIOD 2000
/* API Functions */
void ata_led(bool onoff)
{
led(onoff);
}
int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount,
void* inbuf)
{
#warning function not implemented
(void)start;
(void)incount;
(void)inbuf;
return 0;
}
int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count,
const void* outbuf)
{
#warning function not implemented
(void)start;
(void)count;
(void)outbuf;
return 0;
}
void ata_spindown(int seconds)
{
#warning function not implemented
(void)seconds;
}
bool ata_disk_is_active(void)
{
#warning function not implemented
return 0;
}
void ata_sleep(void)
{
#warning function not implemented
}
void ata_spin(void)
{
#warning function not implemented
}
/* Hardware reset protocol as specified in chapter 9.1, ATA spec draft v5 */
int ata_hard_reset(void)
{
#warning function not implemented
return 0;
}
int ata_soft_reset(void)
{
#warning function not implemented
return 0;
}
void ata_enable(bool on)
{
#warning function not implemented
(void)on;
}
int ata_init(void)
{
#warning function not implemented
return 0;
}

View file

@ -0,0 +1,22 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 Dave Chapman
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef ATA_TARGET_H
#define ATA_TARGET_H
#endif

View file

@ -0,0 +1,26 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 Dave Chapman
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* 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_
#define NUM_ADC_CHANNELS 4
#define ADC_BUTTONS 0
#endif /* _ADC_TARGET_H_ */

View file

@ -0,0 +1,40 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2008 by Rob Purchase
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* 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
#include "tcc780x.h"
#define _backlight_init() true
/* nb: we can set the backlight intensity using PCF50606 register 0x35 */
static inline void _backlight_on(void)
{
/* Enable backlight */
GPIOA_SET = (1<<6);
}
static inline void _backlight_off(void)
{
/* Disable backlight */
GPIOA_CLEAR = (1<<6);
}
#endif

View file

@ -0,0 +1,67 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2008 by Rob Purchase
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* 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 "button.h"
#include "adc.h"
void button_init_device(void)
{
/* Nothing to do */
}
int button_read_device(void)
{
int btn = BUTTON_NONE;
int adc;
if (GPIOB & 0x4)
{
adc = adc_read(ADC_BUTTONS);
/* The following contains some abitrary, but working, guesswork */
if (adc < 0x038) {
btn |= (BUTTON_MINUS | BUTTON_PLUS | BUTTON_MENU);
} else if (adc < 0x048) {
btn |= (BUTTON_MINUS | BUTTON_PLUS);
} else if (adc < 0x058) {
btn |= (BUTTON_PLUS | BUTTON_MENU);
} else if (adc < 0x070) {
btn |= BUTTON_PLUS;
} else if (adc < 0x090) {
btn |= (BUTTON_MINUS | BUTTON_MENU);
} else if (adc < 0x150) {
btn |= BUTTON_MINUS;
} else if (adc < 0x200) {
btn |= BUTTON_MENU;
}
}
/* TODO: Read 'fake' buttons based on touchscreen quadrants.
Question: How can I read from the PCF chip (I2C) in a tick task? */
if (!(GPIOA & 0x8))
btn |= BUTTON_HOLD;
if (!(GPIOA & 0x4))
btn |= BUTTON_POWER;
return btn;
}

View file

@ -0,0 +1,52 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 by Rob Purchase
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* 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 <stdbool.h>
#include "config.h"
void button_init_device(void);
int button_read_device(void);
/* Main unit's buttons */
#define BUTTON_POWER 0x00000001
#define BUTTON_HOLD 0x00000002
#define BUTTON_PLUS 0x00000004
#define BUTTON_MINUS 0x00000008
#define BUTTON_MENU 0x00000010
/* Faked buttons based on touchscreen quadrants (not yet read) */
#define BUTTON_UP 0x00000020
#define BUTTON_DOWN 0x00000040
#define BUTTON_LEFT 0x00000080
#define BUTTON_RIGHT 0x00000100
#define BUTTON_SELECT 0x00000200
#define BUTTON_MAIN 0x3FF
/* No remote */
#define BUTTON_REMOTE 0
/* Software power-off */
#define POWEROFF_BUTTON BUTTON_POWER
#define POWEROFF_COUNT 40
#endif /* _BUTTON_TARGET_H_ */

View file

@ -0,0 +1,37 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2008 by Rob Purchase
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef I2C_TARGET_H
#define I2C_TARGET_H
/* Definitions for the D2 I2C bus */
#define SCL_BIT (1<<0)
#define SDA_BIT (1<<1)
#define SCL (GPIOA & SCL_BIT)
#define SCL_HI GPIOA_SET = SCL_BIT
#define SCL_LO GPIOA_CLEAR = SCL_BIT
#define SDA (GPIOA & SDA_BIT)
#define SDA_HI GPIOA_SET = SDA_BIT
#define SDA_LO GPIOA_CLEAR = SDA_BIT
#define SDA_INPUT GPIOA_DIR &= ~SDA_BIT
#define SDA_OUTPUT GPIOA_DIR |= SDA_BIT
#endif /* I2C_TARGET_H */

View file

@ -0,0 +1,346 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2008 by Rob Purchase
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "hwcompat.h"
#include "kernel.h"
#include "lcd.h"
#include "system.h"
#include "cpu.h"
#include "i2c.h"
/* GPIO A pins for LCD panel SDI interface */
#define LTV250QV_CS (1<<24)
#define LTV250QV_SCL (1<<25)
#define LTV250QV_SDI (1<<26)
/* LCD Controller registers */
#define LCDC_CTRL (*(volatile unsigned long *)0xF0000000)
#define LCDC_CLKDIV (*(volatile unsigned long *)0xF0000008)
#define LCDC_HTIME1 (*(volatile unsigned long *)0xF000000C)
#define LCDC_HTIME2 (*(volatile unsigned long *)0xF0000010)
#define LCDC_VTIME1 (*(volatile unsigned long *)0xF0000014)
#define LCDC_VTIME2 (*(volatile unsigned long *)0xF0000018)
#define LCDC_VTIME3 (*(volatile unsigned long *)0xF000001C)
#define LCDC_VTIME4 (*(volatile unsigned long *)0xF0000020)
#define LCDC_DS (*(volatile unsigned long *)0xF000005C)
#define LCDC_I1CTRL (*(volatile unsigned long *)0xF000008C)
#define LCDC_I1POS (*(volatile unsigned long *)0xF0000090)
#define LCDC_I1SIZE (*(volatile unsigned long *)0xF0000094)
#define LCDC_I1BASE (*(volatile unsigned long *)0xF0000098)
#define LCDC_I1OFF (*(volatile unsigned long *)0xF00000A8)
#define LCDC_I1SCALE (*(volatile unsigned long *)0xF00000AC)
/* Power and display status */
static bool display_on = false; /* Is the display turned on? */
int lcd_default_contrast(void)
{
return 0x1f;
}
void lcd_set_contrast(int val)
{
/* iirc there is an ltv250qv command to do this */
#warning function not implemented
(void)val;
}
/* LTV250QV panel functions */
static void ltv250qv_write(unsigned int command)
{
int i;
GPIOA_CLEAR = LTV250QV_CS;
for (i = 23; i >= 0; i--)
{
GPIOA_CLEAR = LTV250QV_SCL;
if ((command>>i) & 1)
GPIOA_SET = LTV250QV_SDI;
else
GPIOA_CLEAR = LTV250QV_SDI;
GPIOA_SET = LTV250QV_SCL;
}
GPIOA_SET = LTV250QV_CS;
}
static void lcd_write_reg(unsigned char reg, unsigned short val)
{
ltv250qv_write(0x740000 | reg);
ltv250qv_write(0x760000 | val);
}
/* TODO: The existing pcf50606 drivers are target-specific, so the following
lonely function exists until a D2 driver exists. */
void pcf50606_write_reg(unsigned char reg, unsigned char val)
{
unsigned char data[] = { reg, val };
i2c_write(0x10, data, 2);
}
/*
TEMP: Rough millisecond delay routine used by the LCD panel init sequence.
PCK_TCT must first have been initialised to 2Mhz by calling clock_init().
*/
static void sleep_ms(unsigned int ms)
{
/* disable timer */
TCFG1 = 0;
/* set Timer1 reference value based on 125kHz tick */
TREF1 = ms * 125;
/* single count, zero the counter, divider = 16 [2^(3+1)], enable */
TCFG1 = (1<<9) | (1<<8) | (3<<4) | 1;
/* wait until Timer1 ref reached */
while (!(TIREQ & TF1)) {};
}
static void lcd_display_on(void)
{
/* power on sequence as per the D2 firmware */
GPIOA_SET = (1<<16);
sleep_ms(10);
lcd_write_reg(1, 0x1D);
lcd_write_reg(2, 0x0);
lcd_write_reg(3, 0x0);
lcd_write_reg(4, 0x0);
lcd_write_reg(5, 0x40A3);
lcd_write_reg(6, 0x0);
lcd_write_reg(7, 0x0);
lcd_write_reg(8, 0x0);
lcd_write_reg(9, 0x0);
lcd_write_reg(10, 0x0);
lcd_write_reg(16, 0x0);
lcd_write_reg(17, 0x0);
lcd_write_reg(18, 0x0);
lcd_write_reg(19, 0x0);
lcd_write_reg(20, 0x0);
lcd_write_reg(21, 0x0);
lcd_write_reg(22, 0x0);
lcd_write_reg(23, 0x0);
lcd_write_reg(24, 0x0);
lcd_write_reg(25, 0x0);
sleep_ms(10);
lcd_write_reg(9, 0x4055);
lcd_write_reg(10, 0x0);
sleep_ms(40);
lcd_write_reg(10, 0x2000);
sleep_ms(40);
lcd_write_reg(1, 0xC01D);
lcd_write_reg(2, 0x204);
lcd_write_reg(3, 0xE100);
lcd_write_reg(4, 0x1000);
lcd_write_reg(5, 0x5033);
lcd_write_reg(6, 0x4);
lcd_write_reg(7, 0x30);
lcd_write_reg(8, 0x41C);
lcd_write_reg(16, 0x207);
lcd_write_reg(17, 0x702);
lcd_write_reg(18, 0xB05);
lcd_write_reg(19, 0xB05);
lcd_write_reg(20, 0x707);
lcd_write_reg(21, 0x507);
lcd_write_reg(22, 0x103);
lcd_write_reg(23, 0x406);
lcd_write_reg(24, 0x2);
lcd_write_reg(25, 0x0);
sleep_ms(60);
lcd_write_reg(9, 0xA55);
lcd_write_reg(10, 0x111F);
sleep_ms(10);
pcf50606_write_reg(0x35, 0xe9); /* PWMC1 - backlight power (intensity) */
pcf50606_write_reg(0x38, 0x3); /* GPOC1 - ? */
/* tell that we're on now */
display_on = true;
}
static void lcd_display_off(void)
{
/* block drawing operations and changing of first */
display_on = false;
/* LQV shutdown sequence */
lcd_write_reg(9, 0x55);
lcd_write_reg(10, 0x1417);
lcd_write_reg(5, 0x4003);
sleep_ms(10);
lcd_write_reg(9, 0x0);
sleep_ms(10);
/* kill power to LCD panel (unconfirmed) */
GPIOA_CLEAR = (1<<16);
/* also kill the backlight, otherwise LCD fade is visible on screen */
GPIOA_CLEAR = (1<<6);
}
void lcd_enable(bool on)
{
if (on == display_on)
return;
if (on)
{
lcd_display_on(); /* Turn on display */
lcd_update(); /* Resync display */
}
else
{
lcd_display_off(); /* Turn off display */
}
}
bool lcd_enabled(void)
{
return display_on;
}
void lcd_init_device(void)
{
BCLKCTR |= 4; /* enable LCD bus clock */
/* set PCK_LCD to 108Mhz */
PCLK_LCD &= ~PCK_EN;
PCLK_LCD = PCK_EN | (CKSEL_PLL1<<24) | 1; /* source = PLL1, divided by 2 */
/* reset the LCD controller */
SWRESET |= 4;
SWRESET &= ~4;
/* set port configuration */
PORTCFG1 &= ~0xC0000000;
PORTCFG1 &= ~0x3FC0;
PORTCFG2 &= ~0x100;
/* set physical display size */
LCDC_DS = (LCD_HEIGHT<<16) | LCD_WIDTH;
LCDC_HTIME1 = (0x2d<<16) | 0x3bf;
LCDC_HTIME2 = (1<<16) | 1;
LCDC_VTIME1 = LCDC_VTIME3 = (0<<16) | 239;
LCDC_VTIME2 = LCDC_VTIME4 = (1<<16) | 3;
LCDC_I1BASE = (unsigned int)lcd_framebuffer; /* dirty, dirty hack */
LCDC_I1SIZE = (LCD_HEIGHT<<16) | LCD_WIDTH; /* image 1 size */
//LCDC_I1POS = (0<<16) | 0; /* position */
//LCDC_I1OFF = 0; /* address offset */
//LCDC_I1SCALE = 0; /* scaling */
LCDC_I1CTRL = 5; /* 565bpp (7 = 888bpp) */
//LCDC_CTRL &= ~(1<<28);
LCDC_CLKDIV = (LCDC_CLKDIV &~ 0xFF00FF) | (1<<16) | 2; /* and this means? */
/* set and clear various flags - not investigated yet */
//LCDC_CTRL &~ 0x090006AA; /* clear bits 1,3,5,7,9,10,24,27 */
LCDC_CTRL |= 0x02800144; /* set bits 2,6,8,25,23 */
LCDC_CTRL = (LCDC_CTRL &~ 0xF0000) | 0x20000;
//LCDC_CTRL = (LCDC_CTRL &~ 0x700000) | 0x700000;
/* enable LCD controller */
LCDC_CTRL |= 1;
}
/*** Update functions ***/
/* Update the display.
This must be called after all other LCD functions that change the display. */
void lcd_update(void) ICODE_ATTR;
void lcd_update(void)
{
#warning function not implemented
/* currently lcd_framebuffer is accessed directly by the hardware */
}
/* Update a fraction of the display. */
void lcd_update_rect(int, int, int, int) ICODE_ATTR;
void lcd_update_rect(int x, int y, int width, int height)
{
#warning function not implemented
(void)x;
(void)y;
(void)width;
(void)height;
}
void lcd_set_flip(bool yesno)
{
#warning function not implemented
(void)yesno;
}
void lcd_set_invert_display(bool yesno)
{
#warning function not implemented
(void)yesno;
}
void lcd_blit(const fb_data* data, int bx, int y, int bwidth,
int height, int stride)
{
#warning function not implemented
(void)data;
(void)bx;
(void)y;
(void)bwidth;
(void)height;
(void)stride;
}
void lcd_yuv_blit(unsigned char * const src[3],
int src_x, int src_y, int stride,
int x, int y, int width, int height)
{
#warning function not implemented
(void)src;
(void)src_x;
(void)src_y;
(void)stride;
(void)x;
(void)y;
(void)width;
(void)height;
}

View file

@ -0,0 +1,86 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 by Karl Kurbjun
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "system.h"
#include "kernel.h"
#include "logf.h"
#include "audio.h"
#include "sound.h"
#include "file.h"
void pcm_postinit(void)
{
#warning function not implemented
}
const void * pcm_play_dma_get_peak_buffer(int *count)
{
#warning function not implemented
(void) count;
return 0;
}
void pcm_play_dma_init(void)
{
#warning function not implemented
}
void pcm_apply_settings(void)
{
#warning function not implemented
}
void pcm_set_frequency(unsigned int frequency)
{
#warning function not implemented
(void) frequency;
}
void pcm_play_dma_start(const void *addr, size_t size)
{
#warning function not implemented
(void) addr;
(void) size;
}
void pcm_play_dma_stop(void)
{
#warning function not implemented
}
void pcm_play_lock(void)
{
#warning function not implemented
}
void pcm_play_unlock(void)
{
#warning function not implemented
}
void pcm_play_dma_pause(bool pause)
{
#warning function not implemented
(void) pause;
}
size_t pcm_get_bytes_waiting(void)
{
#warning function not implemented
return 0;
}

View file

@ -0,0 +1,71 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 Dave Chapman
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* 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 <stdbool.h>
#include "kernel.h"
#include "system.h"
#include "power.h"
#ifndef SIMULATOR
void power_init(void)
{
#warning function not implemented
}
void ide_power_enable(bool on)
{
#warning function not implemented
(void)on;
}
bool ide_powered(void)
{
#warning function not implemented
return true;
}
void power_off(void)
{
#warning function not implemented
}
#else /* SIMULATOR */
bool charger_inserted(void)
{
return false;
}
void charger_enable(bool on)
{
(void)on;
}
void power_off(void)
{
}
void ide_power_enable(bool on)
{
(void)on;
}
#endif /* SIMULATOR */

View file

@ -0,0 +1,59 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 by Karl Kurbjun
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "adc.h"
#include "powermgmt.h"
#include "kernel.h"
unsigned short current_voltage = 3910;
const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
{
0
};
const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
{
0
};
/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
{
{ 100, 300, 400, 500, 600, 700, 800, 900, 1000, 1200, 1320 },
};
/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
const unsigned short percent_to_volt_charge[11] =
{
100, 300, 400, 500, 600, 700, 800, 900, 1000, 1200, 1320,
};
void read_battery_inputs(void)
{
#warning function not implemented
}
/* Returns battery voltage from ADC [millivolts] */
unsigned int battery_adc_voltage(void)
{
#warning function not implemented
return 0;
}

View file

@ -0,0 +1,49 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2008 by Rob Purchase
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* 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 "kernel.h"
#include "ata.h"
/* USB detect is GPIOC 26 active low */
inline bool usb_detect(void)
{
return (GPIOC & 1<<26)?false:true;
}
void usb_init_device(void)
{
#warning function not implemented
}
void usb_enable(bool on)
{
#warning function not implemented
if (on)
{
}
else
{
}
}

View file

@ -0,0 +1,304 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2002 by Linus Nielsen Feltzing
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
/* Arm bootloader and startup code based on startup.s from the iPodLinux loader
*
* Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
* Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
*
*/
#include "config.h"
#include "cpu.h"
.section .init.text,"ax",%progbits
.global start
/* Telechips firmware files start with a 32-byte header, as part of the code. */
start:
#ifdef TCCBOOT
/* Add -DTCCBOOT to EXTRA_DEFINES in the bootloader Makefile to
enable building the bootloader to be appended to the end of the
original firmware, dual-booting based on a key-press.
NB: On the D2 TCCBOOT currently only works in USB boot mode (via tcctool)
When flashed to the device, the OF will boot as normal - but holding a
key to boot Rockbox results in a blank screen and crashed player.
The following two values are filled in by mktccboot.
*/
.word 0 /* Saved entrypoint of original firmware*/
.word 0 /* Location in RAM of the start of our bootloader */
#else
ldr pc, =start_loc /* jump to the main entry point */
.word 0xffff0601 /* Unknown magic */
.word 0x3a726556 /* "Ver:" */
.word 0x31373030 /* "0071" */
.word 0 /* First CRC32 */
.word 0 /* Unknown - always 0 */
.word 0 /* Second CRC32 */
.word 0 /* length of firmware file */
#ifdef COWON_D2
/* Some original firmwares have 0x40 bytes of zeroes here - we
don't know why, but err on the side of caution and include it
here. */
.space 0x40
#endif
#endif
start_loc:
#ifdef BOOTLOADER
#ifdef TCCBOOT
#ifdef COWON_D2
ldr r0, =0xf005a000
ldr r0, [r0, #0x40] /* Read GPIO B */
tst r0, #0x4
ldreq pc, [pc, #-28] /* Jump to original firmware if keypad not pressed */
#else
#error No bootup key detection implemented for this target
#endif
/* Copy bootloader to safe area - 0x21000000 (DRAM) */
/* TODO: Adjust this for other targets - DRAM + DRAMSIZE - 0x100000 */
ldr r0, [pc, #-28]
mov r1, #0x22000000
sub r1, r1, #0x100000
ldr r2, =_dataend
1:
cmp r2, r1
ldrhi r3, [r0], #4
strhi r3, [r1], #4
bhi 1b
ldr pc, =copied_start /* jump to the relocated start_loc: */
copied_start:
#endif
#else
/* We don't use interrupts in the bootloader */
/* Set up stack for IRQ mode */
mov r0,#0xd2
msr cpsr, r0
ldr sp, =irq_stack
/* Set up stack for FIQ mode */
mov r0,#0xd1
msr cpsr, r0
ldr sp, =fiq_stack
/* Let abort and undefined modes use IRQ stack */
mov r0,#0xd7
msr cpsr, r0
ldr sp, =irq_stack
mov r0,#0xdb
msr cpsr, r0
ldr sp, =irq_stack
#endif
/* Switch to supervisor mode */
mov r0,#0xd3
msr cpsr, r0
ldr sp, =stackend
#if !defined(BOOTLOADER) && !defined(STUB)
/* Copy exception handler code to address 0 */
ldr r2, =_vectorsstart
ldr r3, =_vectorsend
ldr r4, =_vectorscopy
1:
cmp r3, r2
ldrhi r5, [r4], #4
strhi r5, [r2], #4
bhi 1b
/* Zero out IBSS */
ldr r2, =_iedata
ldr r3, =_iend
mov r4, #0
1:
cmp r3, r2
strhi r4, [r2], #4
bhi 1b
/* Copy the ITCM */
ldr r2, =_itcmcopy
ldr r3, =_itcmstart
ldr r4, =_itcmend
1:
cmp r4, r3
ldrhi r5, [r2], #4
strhi r5, [r3], #4
bhi 1b
/* Copy the DTCM */
ldr r2, =_dtcmcopy
ldr r3, =_dtcmstart
ldr r4, =_dtcmend
1:
cmp r4, r3
ldrhi r5, [r2], #4
strhi r5, [r3], #4
bhi 1b
#endif /* !BOOTLOADER,!STUB */
/* Initialise bss section to zero */
ldr r2, =_edata
ldr r3, =_end
mov r4, #0
1:
cmp r3, r2
strhi r4, [r2], #4
bhi 1b
/* Set up some stack and munge it with 0xdeadbeef */
ldr sp, =stackend
mov r3, sp
ldr r2, =stackbegin
ldr r4, =0xdeadbeef
1:
cmp r3, r2
strhi r4, [r2], #4
bhi 1b
/*
Enable cache & TCM regions
TODO: This is just doing what the OF does at present. It needs to be
better understood and moved out to a separate MMU functions package.
*/
ldr r1, =0x1fe0c
mov r0, #0xf7000000
str r1, [r0]
ldr r1, =0x2801ae24
str r1, [r0,#4]
ldr r1, =0x13e44
str r1, [r0,#8]
ldr r1, =0x4001ce60
str r1, [r0,#0xc]
ldr r1, =0x6001be80
str r1, [r0,#0x10]
ldr r1, =0x3801aea4
str r1, [r0,#0x14]
ldr r1, =0x8001eec0
str r1, [r0,#0x18]
ldr r1, =0x1001aee0
str r1, [r0,#0x1c]
add r1, r0, #0x8000 /* r1 now = 0xf7008000 */
ldr r0, =0xa0000011
ldr r2, =0x5507d
mcr p15, 0, r0,c9,c1 /* data tcm region (enabled; 8kb; 0xa0000000) */
mov r0, #0xd
mcr p15, 0, r0,c9,c1, 1 /* inst tcm region (enabled, 4kb, 0x00000000) */
ldr r0, =0x55555555
mcr p15, 0, r1,c2,c0 /* translation table base register = 0xf7008000 */
mcr p15, 0, r0,c3,c0 /* domain access d0-d15 = 'client' */
mov r0, #0
mcr p15, 0, r0,c7,c5 /* invalidate icache */
mcr p15, 0, r2,c1,c0 /* enable mmu, i & d caches */
mcr p15, 0, r0,c7,c6 /* invalidate dcache */
mcr p15, 0, r1,c8,c7 /* invalidate tlb */
bl main
/* main() should never return */
#ifndef BOOTLOADER
/* Exception handlers. Will be copied to address 0 after memory remapping */
.section .vectors,"aw"
ldr pc, [pc, #24]
ldr pc, [pc, #24]
ldr pc, [pc, #24]
ldr pc, [pc, #24]
ldr pc, [pc, #24]
ldr pc, [pc, #24]
ldr pc, [pc, #24]
ldr pc, [pc, #24]
/* Exception vectors */
.global vectors
vectors:
.word start
.word undef_instr_handler
.word software_int_handler
.word prefetch_abort_handler
.word data_abort_handler
.word reserved_handler
.word irq_handler
.word fiq_handler
.text
#if !defined(STUB)
.global irq
.global fiq
.global UIE
#endif
/* All illegal exceptions call into UIE with exception address as first
parameter. This is calculated differently depending on which exception
we're in. Second parameter is exception number, used for a string lookup
in UIE.
*/
undef_instr_handler:
mov r0, lr
mov r1, #0
b UIE
/* We run supervisor mode most of the time, and should never see a software
exception being thrown. Perhaps make it illegal and call UIE?
*/
software_int_handler:
reserved_handler:
movs pc, lr
prefetch_abort_handler:
sub r0, lr, #4
mov r1, #1
b UIE
data_abort_handler:
sub r0, lr, #8
mov r1, #2
b UIE
#if defined(STUB)
UIE:
b UIE
#endif
/* We don't use interrupts in the bootloader */
/* Align stacks to cache line boundary */
.balign 16
/* 256 words of IRQ stack */
.space 256*4
irq_stack:
/* 256 words of FIQ stack */
.space 256*4
fiq_stack:
#endif

View file

@ -0,0 +1,88 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 by Rob Purchase
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* 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 "string.h"
#include <stdbool.h>
#include "button.h"
#include "lcd.h"
#include "sprintf.h"
#include "font.h"
bool __dbg_ports(void);
bool __dbg_ports(void)
{
return false;
}
//extern char r_buffer[5];
//extern int r_button;
bool __dbg_hw_info(void);
bool __dbg_hw_info(void)
{
int line = 0, button, oldline;
int *address=0x0;
bool done=false;
char buf[100];
lcd_setmargins(0, 0);
lcd_setfont(FONT_SYSFIXED);
lcd_clear_display();
/* Put all the static text before the while loop */
lcd_puts(0, line++, "[Hardware info]");
/* TODO: ... */
line++;
oldline=line;
while(!done)
{
line = oldline;
button = button_get(false);
button &= ~BUTTON_REPEAT;
if (button == BUTTON_MENU)
done=true;
if(button==BUTTON_DOWN)
address+=0x01;
else if (button==BUTTON_UP)
address-=0x01;
/*snprintf(buf, sizeof(buf), "Buffer: 0x%02x%02x%02x%02x%02x",
r_buffer[0], r_buffer[1], r_buffer[2], r_buffer[3],r_buffer[4] ); lcd_puts(0, line++, buf);
snprintf(buf, sizeof(buf), "Button: 0x%08x, HWread: 0x%08x",
(unsigned int)button, r_button); lcd_puts(0, line++, buf);*/
snprintf(buf, sizeof(buf), "current tick: %08x Seconds running: %08d",
(unsigned int)current_tick, (unsigned int)current_tick/100); lcd_puts(0, line++, buf);
snprintf(buf, sizeof(buf), "Address: 0x%08x Data: 0x%08x",
(unsigned int)address, *address); lcd_puts(0, line++, buf);
snprintf(buf, sizeof(buf), "Address: 0x%08x Data: 0x%08x",
(unsigned int)(address+1), *(address+1)); lcd_puts(0, line++, buf);
snprintf(buf, sizeof(buf), "Address: 0x%08x Data: 0x%08x",
(unsigned int)(address+2), *(address+2)); lcd_puts(0, line++, buf);
lcd_update();
}
return false;
}

View file

@ -0,0 +1,43 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2008 by Rob Purchase
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* 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"
/* NB: PCK_TCT must previously have been set to 2Mhz by calling clock_init() */
void tick_start(unsigned int interval_in_ms)
{
/* disable Timer0 */
TCFG0 &= ~1;
/* set counter reference value based on 1Mhz tick */
TREF0 = interval_in_ms * 1000;
/* Timer0 = reset to 0, divide=2, IRQ enable, enable (continuous) */
TCFG0 = (1<<8) | (0<<4) | (1<<3) | 1;
/* Unmask timer IRQ */
MIRQ &= ~TIMER_IRQ_MASK;
}
/* NB: Since the 7801 has a single timer IRQ, the tick tasks are dispatched
as part of the central timer IRQ processing in timer-tcc780x.c */

View file

@ -0,0 +1,35 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 by Dave Chapman
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* 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"
#define CPUFREQ_DEFAULT 98784000
#define CPUFREQ_NORMAL 98784000
#define CPUFREQ_MAX 192000000
#define inl(a) (*(volatile unsigned long *) (a))
#define outl(a,b) (*(volatile unsigned long *) (b) = (a))
#define inb(a) (*(volatile unsigned char *) (a))
#define outb(a,b) (*(volatile unsigned char *) (b) = (a))
#define inw(a) (*(volatile unsigned short *) (a))
#define outw(a,b) (*(volatile unsigned short *) (b) = (a))
#endif /* SYSTEM_TARGET_H */

View file

@ -0,0 +1,275 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 by Rob Purchase
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* 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"
#if !defined(BOOTLOADER)
#define default_interrupt(name) \
extern __attribute__((weak,alias("UIRQ"))) void name (void)
void irq_handler(void) __attribute__((interrupt ("IRQ"), naked));
void fiq_handler(void) __attribute__((interrupt ("FIQ"), naked));
default_interrupt(EXT0);
default_interrupt(EXT1);
default_interrupt(EXT2);
default_interrupt(EXT3);
default_interrupt(IRQ4);
default_interrupt(IRQ5);
default_interrupt(TIMER);
default_interrupt(IRQ7);
default_interrupt(IRQ8);
default_interrupt(IRQ9);
default_interrupt(IRQ10);
default_interrupt(IRQ11);
default_interrupt(IRQ12);
default_interrupt(IRQ13);
default_interrupt(DAI_RX);
default_interrupt(DAI_TX);
default_interrupt(IRQ16);
default_interrupt(IRQ17);
default_interrupt(IRQ18);
default_interrupt(IRQ19);
default_interrupt(IRQ20);
default_interrupt(IRQ21);
default_interrupt(IRQ22);
default_interrupt(IRQ23);
default_interrupt(IRQ24);
default_interrupt(IRQ25);
default_interrupt(IRQ26);
default_interrupt(IRQ27);
default_interrupt(IRQ28);
default_interrupt(IRQ29);
default_interrupt(IRQ30);
default_interrupt(IRQ31);
static void (* const irqvector[])(void) =
{
EXT0,EXT1,EXT2,EXT3,IRQ4,IRQ5,TIMER,IRQ7,
IRQ8,IRQ9,IRQ10,IRQ11,IRQ12,IRQ13,DAI_RX,DAI_TX,
IRQ16,IRQ17,IRQ18,IRQ19,IRQ20,IRQ21,IRQ22,IRQ23,
IRQ24,IRQ25,IRQ26,IRQ27,IRQ28,IRQ29,IRQ30,IRQ31
};
static const char * const irqname[] =
{
"EXT0","EXT1","EXT2","EXT3","IRQ4","IRQ5","TIMER","IRQ7",
"IRQ8","IRQ9","IRQ10","IRQ11","IRQ12","IRQ13","DAI_RX","DAI_TX",
"IRQ16","IRQ17","IRQ18","IRQ19","IRQ20","IRQ21","IRQ22","IRQ23",
"IRQ24","IRQ25","IRQ26","IRQ27","IRQ28","IRQ29","IRQ30","IRQ31"
};
static void UIRQ(void)
{
unsigned int offset = VNIRQ;
panicf("Unhandled IRQ %02X: %s", offset, irqname[offset]);
}
void irq_handler(void)
{
/*
* Based on: linux/arch/arm/kernel/entry-armv.S and system-meg-fx.c
*/
asm volatile( "stmfd sp!, {r0-r7, ip, lr} \n" /* Store context */
"sub sp, sp, #8 \n"); /* Reserve stack */
irqvector[VNIRQ]();
asm volatile( "add sp, sp, #8 \n" /* Cleanup stack */
"ldmfd sp!, {r0-r7, ip, lr} \n" /* Restore context */
"subs pc, lr, #4 \n"); /* Return from FIQ */
}
void fiq_handler(void)
{
asm volatile (
"sub lr, lr, #4 \r\n"
"movs lr,pc \r\n"
);
}
#endif /* !defined(BOOTLOADER) */
/* TODO:
a) this is not the place for this function
b) it currently ignores the supplied frequency and uses default values
c) if the PLL being set drives any PCKs, an appropriate new clock divider
will have to be re-calculated for those PCKs (the OF maintains a list of
PCK frequencies for this purpose).
*/
void set_pll_frequency(unsigned int pll_number, unsigned int frequency)
{
int i = 0;
if (pll_number > 1) return;
/* The frequency parameter is currently ignored and temporary values are
used (PLL0=192Mhz, PLL1=216Mhz). The D2 firmware uses a lookup table
to derive the values of PLLxCFG from a the supplied frequency.
Presumably we will need to do something similar. */
if (pll_number == 0)
{
/* drive CPU off Xin while switching */
CLKCTRL = 0xB00FF014; /* Xin enable, Fsys driven by Xin, Fbus = Fsys,
MCPU=Fbus, SCPU=Fbus */
asm volatile (
"nop \n\t"
"nop \n\t"
);
PLL0CFG |= (1<<31); /* power down */
CLKDIVC = CLKDIVC &~ (0xff << 24); /* disable PLL0 divider */
PLL0CFG = 0x80019808; /* set for 192Mhz (with power down) */
PLL0CFG = PLL0CFG &~ (1<<31); /* power up */
CLKCTRL = (CLKCTRL & ~0x1f) | 0x800FF010;
asm volatile (
"nop \n\t"
"nop \n\t"
);
}
else if (pll_number == 1)
{
PLL1CFG |= (1<<31); /* power down */
CLKDIVC = CLKDIVC &~ (0xff << 16); /* disable PLL1 divider */
PLL1CFG = 0x80002503; /* set for 216Mhz (with power down)*/
PLL1CFG = PLL1CFG &~ (1<<31); /* power up */
}
i = 0x1000;
while (--i) {};
}
/* TODO - these should live in the target-specific directories and
once we understand what all the GPIO pins do, move the init to the
specific driver for that hardware. For now, we just perform the
same GPIO init as the original firmware - this makes it easier to
investigate what the GPIO pins do.
*/
#ifdef COWON_D2
static void gpio_init(void)
{
/* Do what the original firmware does */
GPIOA = 0x07000C83;
GPIOA_DIR = 0x0F010CE3;
GPIOB = 0;
GPIOB_DIR = 0x00080000;
GPIOC = 0x39000000;
GPIOC_DIR = 0xB9000000;
GPIOD = 0;
GPIOD_DIR = 0;
GPIOD = 0;
GPIOD_DIR = 0x00480000;
PORTCFG0 = 0x00034540;
PORTCFG1 = 0x0566A000;
PORTCFG2 = 0x000004C0;
PORTCFG3 = 0x0AA40455;
}
#endif
/* Second function called in the original firmware's startup code - we just
set up the clocks in the same way as the original firmware for now. */
#ifdef COWON_D2
static void clock_init(void)
{
int i;
CSCFG3 = (CSCFG3 &~ 0x3fff) | 0x841;
CLKCTRL = (CLKCTRL & ~0xff) | 0x14;
PCLK_RFREQ = 0x1401002d; /* RAM refresh source = Xin (4) / 0x2d = 266kHz */
MCFG |= 1;
SDCFG = (SDCFG &~ 0x7000) | 0x2000;
MCFG1 |= 1;
SDCFG1 = (SDCFG &~ 0x7000) | 0x2000;
PLL0CFG |= 0x80000000; /* power down */
PLL0CFG = 0x14010000; /* power up, source = Xin (4) undivided = 12Mhz */
i = 0x8000;
while (--i) {};
CLKCTRL = (CLKCTRL &~ 0x1f) | 0x800FF010; /* CPU and COP driven by PLL0 */
asm volatile (
"nop \n\t"
"nop \n\t"
);
/* configure PCK_TCT to 2Mhz (clock source 4 (Xin) divided by 6) */
PCLK_TCT = PCK_EN | (CKSEL_XIN<<24) | 5;
}
#endif
#ifdef COWON_D2
void system_init(void)
{
MBCFG = 0x19;
if (TCC780_VER == 0)
ECFG0 = 0x309;
else
ECFG0 = 0x30d;
/* mask all interrupts */
MIRQ = -1;
gpio_init();
clock_init();
/* TODO: these almost certainly shouldn't be here */
set_pll_frequency(0, 192000000); /* drives CPU */
set_pll_frequency(1, 216000000); /* drives LCD PXCLK - divided by 2 */
}
#endif
void system_reboot(void)
{
#warning function not implemented
}
int system_memory_guard(int newmode)
{
#warning function not implemented
(void)newmode;
return 0;
}
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
void set_cpu_frequency(long frequency)
{
#warning function not implemented
(void)frequency;
}
#endif

View file

@ -0,0 +1,39 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 by Karl Kurbjun
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef TIMER_TARGET_H
#define TIMER_TARGET_H
/* timers are based on XIN (12Mhz) */
#define TIMER_FREQ (12000000)
bool __timer_set(long cycles, bool set);
bool __timer_register(void);
void __timer_unregister(void);
#define __TIMER_SET(cycles, set) \
__timer_set(cycles, set)
#define __TIMER_REGISTER(reg_prio, unregister_callback, cycles, \
int_prio, timer_callback) \
__timer_register()
#define __TIMER_UNREGISTER(...) \
__timer_unregister()
#endif /* TIMER_TARGET_H */

View file

@ -0,0 +1,82 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2008 by Rob Purchase
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* 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 "timer.h"
#include "logf.h"
/* Use the TC32 counter [sourced by Xin:12Mhz] for this timer, as it's the
only one that allows a 32-bit counter (Timer0-5 are 16/20 bit only). */
bool __timer_set(long cycles, bool start)
{
#warning function not implemented
(void)cycles;
(void)start;
return false;
}
bool __timer_register(void)
{
#warning function not implemented
return false;
}
void __timer_unregister(void)
{
#warning function not implemented
}
/* Timer interrupt processing - all timers (inc. tick) have a single IRQ */
extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
void TIMER(void)
{
if (TIREQ & TF0) /* Timer0 reached ref value */
{
int i;
/* Run through the list of tick tasks */
for(i = 0; i < MAX_NUM_TICK_TASKS; i++)
{
if(tick_funcs[i])
{
tick_funcs[i]();
}
}
current_tick++;
/* reset Timer 0 IRQ & ref flags */
TIREQ |= TI0 | TF0;
}
if (TC32IRQ & (1<<3)) /* end of TC32 prescale */
{
/* dispatch timer */
}
CREQ |= TIMER_IRQ_MASK; /* clear IRQ */
}