Rockchip rk27xx port initial commit. This is still work in progress.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29935 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
8a5a2b82fd
commit
976a1699da
|
@ -69,4 +69,7 @@ main-pp.c
|
|||
show_logo.c
|
||||
#elif defined(MPIO_HD200) || defined(MPIO_HD300)
|
||||
mpio_hd200_hd300.c
|
||||
#elif defined(RK27_GENERIC)
|
||||
rk27xx.c
|
||||
show_logo.c
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
#include "config.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "inttypes.h"
|
||||
#include "string.h"
|
||||
#include "cpu.h"
|
||||
#include "system.h"
|
||||
#include "lcd.h"
|
||||
#include "kernel.h"
|
||||
#include "thread.h"
|
||||
#include "backlight.h"
|
||||
#include "backlight-target.h"
|
||||
#include "font.h"
|
||||
#include "common.h"
|
||||
#include "version.h"
|
||||
|
||||
extern int show_logo( void );
|
||||
void main(void)
|
||||
{
|
||||
|
||||
_backlight_init();
|
||||
|
||||
system_init();
|
||||
kernel_init();
|
||||
enable_irq();
|
||||
|
||||
lcd_init_device();
|
||||
_backlight_on();
|
||||
font_init();
|
||||
lcd_setfont(FONT_SYSFIXED);
|
||||
|
||||
show_logo();
|
||||
sleep(HZ*2);
|
||||
|
||||
while(1)
|
||||
{
|
||||
reset_screen();
|
||||
printf("GPIOA: 0x%0x", GPIO_PADR);
|
||||
printf("GPIOB: 0x%0x", GPIO_PBDR);
|
||||
printf("GPIOC: 0x%0x", GPIO_PCDR);
|
||||
printf("GPIOD: 0x%0x", GPIO_PDDR);
|
||||
sleep(HZ/10);
|
||||
}
|
||||
}
|
|
@ -210,6 +210,9 @@ target/arm/ata-nand-telechips.c
|
|||
#if (CONFIG_STORAGE & STORAGE_NAND) && (CONFIG_NAND == NAND_SAMSUNG)
|
||||
target/arm/s5l8700/ata-nand-s5l8700.c
|
||||
#endif
|
||||
#if (CONFIG_STORAGE & STORAGE_NAND) && (CONFIG_NAND == NAND_RK27XX)
|
||||
target/arm/rk27xx/ata-nand-rk27xx.c
|
||||
#endif
|
||||
#if (CONFIG_STORAGE & STORAGE_ATA) && !defined(IPOD_6G)
|
||||
drivers/ata.c
|
||||
#endif
|
||||
|
@ -473,6 +476,8 @@ target/arm/i2c-telechips.c
|
|||
target/arm/s5l8700/i2c-s5l8700.c
|
||||
#elif CONFIG_I2C == I2C_S5L8702
|
||||
target/arm/s5l8702/i2c-s5l8702.c
|
||||
#elif CONFIG_I2C == I2C_RK27XX
|
||||
target/arm/rk27xx/i2c-rk27xx.c
|
||||
#endif
|
||||
|
||||
#if CONFIG_CPU == PNX0101
|
||||
|
@ -562,6 +567,8 @@ target/arm/s5l8700/crt0.S
|
|||
target/arm/s5l8702/crt0.S
|
||||
#elif CONFIG_CPU==IMX233
|
||||
target/arm/imx233/crt0.S
|
||||
#elif CONFIG_CPU==RK27XX
|
||||
target/arm/rk27xx/crt0.S
|
||||
#elif defined(CPU_ARM)
|
||||
target/arm/crt0.S
|
||||
#endif /* defined(CPU_*) */
|
||||
|
@ -1604,6 +1611,23 @@ target/arm/s5l8702/ipod6g/adc-ipod6g.c
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SIMULATOR
|
||||
#if CONFIG_CPU == RK27XX
|
||||
target/arm/rk27xx/kernel-rk27xx.c
|
||||
target/arm/rk27xx/system-rk27xx.c
|
||||
target/arm/rk27xx/timer-rk27xx.c
|
||||
target/arm/rk27xx/backlight-rk27xx.c
|
||||
target/arm/rk27xx/lcd-rk27xx.c
|
||||
target/arm/rk27xx/adc-rk27xx.c
|
||||
target/arm/rk27xx/sd-rk27xx.c
|
||||
target/arm/rk27xx/ftl-rk27xx.c
|
||||
#endif
|
||||
|
||||
#if defined(RK27_GENERIC)
|
||||
target/arm/rk27xx/rk27generic/button-rk27generic.c
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SIMULATOR
|
||||
#if CONFIG_CPU == JZ4732
|
||||
target/mips/ingenic_jz47xx/ata-nand-jz4740.c
|
||||
|
|
|
@ -75,6 +75,7 @@
|
|||
#define AT91SAM9260 9260
|
||||
#define AS3525v2 35252
|
||||
#define IMX233 233
|
||||
#define RK27XX 2700
|
||||
|
||||
/* platforms
|
||||
* bit fields to allow PLATFORM_HOSTED to be OR'ed e.g. with a
|
||||
|
@ -222,6 +223,7 @@
|
|||
#define LCD_VIBE500 39 /* as used by the Packard Bell Vibe 500 */
|
||||
#define LCD_IPOD6G 40 /* as used by the iPod Nano 2nd Generation */
|
||||
#define LCD_FUZEPLUS 41
|
||||
#define LCD_SPFD5420A 42 /* rk27xx */
|
||||
|
||||
/* LCD_PIXELFORMAT */
|
||||
#define HORIZONTAL_PACKING 1
|
||||
|
@ -260,6 +262,7 @@ Lyre prototype 1 */
|
|||
#define I2C_AS3525 15
|
||||
#define I2C_S5L8702 16 /* Same as S5L8700, but with two channels */
|
||||
#define I2C_IMX233 17
|
||||
#define I2C_RK27XX 18
|
||||
|
||||
/* CONFIG_LED */
|
||||
#define LED_REAL 1 /* SW controlled LED (Archos recorders, player) */
|
||||
|
@ -271,6 +274,7 @@ Lyre prototype 1 */
|
|||
#define NAND_TCC 2
|
||||
#define NAND_SAMSUNG 3
|
||||
#define NAND_CC 4 /* ChinaChip */
|
||||
#define NAND_RK27XX 5
|
||||
|
||||
/* CONFIG_RTC */
|
||||
#define RTC_M41ST84W 1 /* Archos Recorder */
|
||||
|
@ -448,6 +452,8 @@ Lyre prototype 1 */
|
|||
#include "config/mpiohd200.h"
|
||||
#elif defined(MPIO_HD300)
|
||||
#include "config/mpiohd300.h"
|
||||
#elif defined(RK27_GENERIC)
|
||||
#include "config/rk27generic.h"
|
||||
#elif defined(SDLAPP)
|
||||
#include "config/sdlapp.h"
|
||||
#elif defined(ANDROID)
|
||||
|
@ -533,8 +539,8 @@ Lyre prototype 1 */
|
|||
|
||||
#elif defined(CPU_TCC77X) || defined(CPU_TCC780X) || (CONFIG_CPU == DM320) \
|
||||
|| (CONFIG_CPU == AT91SAM9260) || (CONFIG_CPU == AS3525v2) \
|
||||
|| (CONFIG_CPU == S5L8702) || (CONFIG_PLATFORM & PLATFORM_ANDROID) \
|
||||
|| (CONFIG_CPU == IMX233)
|
||||
|| (CONFIG_CPU == S5L8702) || (CONFIG_CPU == IMX233) \
|
||||
|| (CONFIG_CPU == RK27XX) ||(CONFIG_PLATFORM & PLATFORM_ANDROID)
|
||||
#define CPU_ARM
|
||||
#define ARM_ARCH 5 /* ARMv5 */
|
||||
|
||||
|
@ -774,7 +780,8 @@ Lyre prototype 1 */
|
|||
#if defined(HAVE_USBSTACK) || (CONFIG_CPU == JZ4732) \
|
||||
|| (CONFIG_CPU == AS3525) || (CONFIG_CPU == AS3525v2) \
|
||||
|| defined(CPU_S5L870X) || (CONFIG_CPU == S3C2440) \
|
||||
|| defined(APPLICATION) || (CONFIG_CPU == PP5002)
|
||||
|| defined(APPLICATION) || (CONFIG_CPU == PP5002) \
|
||||
|| (CONFIG_CPU == RK27XX)
|
||||
#define HAVE_SEMAPHORE_OBJECTS
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* This config file is for Rockchip rk27xx reference design
|
||||
*/
|
||||
#define TARGET_TREE /* this target is using the target tree system */
|
||||
|
||||
/* For Rolo and boot loader */
|
||||
#define MODEL_NUMBER 78
|
||||
|
||||
#define MODEL_NAME "Rockchip 27xx generic"
|
||||
|
||||
/* define this if you have recording possibility */
|
||||
/* #define HAVE_RECORDING */
|
||||
|
||||
/* Define bitmask of input sources - recordable bitmask can be defined
|
||||
explicitly if different */
|
||||
#define INPUT_SRC_CAPS (SRC_CAP_LINEIN)
|
||||
|
||||
/* define the bitmask of hardware sample rates */
|
||||
#define HW_SAMPR_CAPS (SAMPR_CAP_44 | SAMPR_CAP_22 | SAMPR_CAP_11 \
|
||||
| SAMPR_CAP_48 | SAMPR_CAP_24 | SAMPR_CAP_12 \
|
||||
| SAMPR_CAP_32 | SAMPR_CAP_16 | SAMPR_CAP_8)
|
||||
|
||||
/* define the bitmask of recording sample rates */
|
||||
#define REC_SAMPR_CAPS (SAMPR_CAP_44 | SAMPR_CAP_22 | SAMPR_CAP_11 \
|
||||
| SAMPR_CAP_48 | SAMPR_CAP_24 | SAMPR_CAP_12 \
|
||||
| SAMPR_CAP_32 | SAMPR_CAP_16 | SAMPR_CAP_8)
|
||||
|
||||
/* define this if you have a bitmap LCD display */
|
||||
#define HAVE_LCD_BITMAP
|
||||
|
||||
/* define this if you can flip your LCD */
|
||||
/* #define HAVE_LCD_FLIP */
|
||||
|
||||
/* define this if you have a colour LCD */
|
||||
#define HAVE_LCD_COLOR
|
||||
|
||||
/* define this if you want album art for this target */
|
||||
#define HAVE_ALBUMART
|
||||
|
||||
/* define this to enable bitmap scaling */
|
||||
#define HAVE_BMP_SCALING
|
||||
|
||||
/* define this to enable JPEG decoding */
|
||||
#define HAVE_JPEG
|
||||
|
||||
/* define this if you can invert the colours on your LCD */
|
||||
/* #define HAVE_LCD_INVERT */
|
||||
|
||||
/* define this if you have access to the quickscreen */
|
||||
#define HAVE_QUICKSCREEN
|
||||
|
||||
/* define this if you have access to the pitchscreen */
|
||||
#define HAVE_PITCHSCREEN
|
||||
|
||||
/* define this if you would like tagcache to build on this target */
|
||||
#define HAVE_TAGCACHE
|
||||
|
||||
/* define this if you have a flash memory storage */
|
||||
#define HAVE_FLASH_STORAGE
|
||||
|
||||
#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND)
|
||||
|
||||
#define CONFIG_NAND NAND_RK27XX
|
||||
|
||||
/* commented for now */
|
||||
/* #define HAVE_HOTSWAP */
|
||||
|
||||
#define NUM_DRIVES 2
|
||||
#define SECTOR_SIZE 512
|
||||
|
||||
/* for small(ish) SD cards */
|
||||
#define HAVE_FAT16SUPPORT
|
||||
|
||||
/* LCD dimensions */
|
||||
#define LCD_WIDTH 400
|
||||
#define LCD_HEIGHT 240
|
||||
#define LCD_DEPTH 16 /* pseudo 262.144 colors */
|
||||
#define LCD_PIXELFORMAT RGB565 /* rgb565 */
|
||||
|
||||
/* Define this if the LCD can shut down */
|
||||
/* #define HAVE_LCD_SHUTDOWN */
|
||||
|
||||
/* Define this if your LCD can be enabled/disabled */
|
||||
/* #define HAVE_LCD_ENABLE */
|
||||
|
||||
/* Define this if your LCD can be put to sleep. HAVE_LCD_ENABLE
|
||||
should be defined as well. */
|
||||
#ifndef BOOTLOADER
|
||||
/* TODO: #define HAVE_LCD_SLEEP */
|
||||
/* TODO: #define HAVE_LCD_SLEEP_SETTING */
|
||||
#endif
|
||||
|
||||
#define CONFIG_KEYPAD IPOD_4G_PAD
|
||||
|
||||
/* Define this to enable morse code input */
|
||||
#define HAVE_MORSE_INPUT
|
||||
|
||||
/* Define this if you do software codec */
|
||||
#define CONFIG_CODEC SWCODEC
|
||||
|
||||
/* define this if you have a real-time clock */
|
||||
/* #define CONFIG_RTC RTC_NANO2G */
|
||||
|
||||
/* Define if the device can wake from an RTC alarm */
|
||||
/* #define HAVE_RTC_ALARM */
|
||||
|
||||
#define CONFIG_LCD LCD_SPFD5420A
|
||||
|
||||
/* Define the type of audio codec */
|
||||
/* #define HAVE_RK27XX_CODEC */
|
||||
|
||||
/* #define HAVE_PCM_DMA_ADDRESS */
|
||||
|
||||
/* Define this for LCD backlight available */
|
||||
#define HAVE_BACKLIGHT
|
||||
|
||||
/* Doesn't work so comment it out for now */
|
||||
/* #define HAVE_BACKLIGHT_BRIGHTNESS */
|
||||
|
||||
/* Define this if you have a software controlled poweroff */
|
||||
#define HAVE_SW_POWEROFF
|
||||
|
||||
/* The number of bytes reserved for loadable codecs */
|
||||
#define CODEC_SIZE 0x100000
|
||||
|
||||
/* The number of bytes reserved for loadable plugins */
|
||||
#define PLUGIN_BUFFER_SIZE 0x80000
|
||||
|
||||
/* TODO: Figure out real values */
|
||||
#define BATTERY_CAPACITY_DEFAULT 400 /* default battery capacity */
|
||||
#define BATTERY_CAPACITY_MIN 300 /* min. capacity selectable */
|
||||
#define BATTERY_CAPACITY_MAX 500 /* max. capacity selectable */
|
||||
#define BATTERY_CAPACITY_INC 10 /* capacity increment */
|
||||
#define BATTERY_TYPES_COUNT 1 /* only one type */
|
||||
|
||||
/* Hardware controlled charging with monitoring */
|
||||
#define CONFIG_CHARGING CHARGING_MONITOR
|
||||
|
||||
/* define current usage levels */
|
||||
/* TODO: #define CURRENT_NORMAL
|
||||
* TODO: #define CURRENT_BACKLIGHT 23
|
||||
*/
|
||||
|
||||
/* define this if the unit can be powered or charged via USB */
|
||||
#define HAVE_USB_POWER
|
||||
|
||||
/* Define this if your LCD can set contrast */
|
||||
/* #define HAVE_LCD_CONTRAST */
|
||||
|
||||
/* The exact type of CPU */
|
||||
#define CONFIG_CPU RK27XX
|
||||
|
||||
/* I2C interface */
|
||||
#define CONFIG_I2C I2C_RK27XX
|
||||
|
||||
/* Define this to the CPU frequency */
|
||||
#define CPU_FREQ 200000000
|
||||
|
||||
/* define this if the hardware can be powered off while charging */
|
||||
#define HAVE_POWEROFF_WHILE_CHARGING
|
||||
|
||||
/* 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 STORAGE_NEEDS_ALIGN
|
||||
|
||||
/* Define this if you have adjustable CPU frequency */
|
||||
/* #define HAVE_ADJUSTABLE_CPU_FREQ */
|
||||
|
||||
#define BOOTFILE_EXT "rk27"
|
||||
#define BOOTFILE "rockbox." BOOTFILE_EXT
|
||||
#define BOOTDIR "/.rockbox"
|
|
@ -77,3 +77,6 @@
|
|||
#if CONFIG_CPU == IMX233
|
||||
#include "imx233.h"
|
||||
#endif
|
||||
#if CONFIG_CPU == RK27XX
|
||||
#include "rk27xx.h"
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2009 by Bertrik Sikken
|
||||
*
|
||||
* 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 _I2C_RK27XX_H
|
||||
#define _I2C_RK27XX_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
void i2c_init(void);
|
||||
int i2c_write(unsigned char slave, int address, int len, const unsigned char *data);
|
||||
int i2c_read(unsigned char slave, int address, int len, unsigned char *data);
|
||||
|
||||
#endif /* _I2C_RK27XX_H */
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,47 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2011 Marcin Bukat
|
||||
*
|
||||
* 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 "kernel.h"
|
||||
#include "thread.h"
|
||||
#include "adc.h"
|
||||
|
||||
unsigned int adc_scan(int channel)
|
||||
{
|
||||
ADC_CTRL = (1<<4) | (1<<3) | (channel & (NUM_ADC_CHANNELS - 1));
|
||||
|
||||
/* wait for conversion ready ~10us */
|
||||
while (ADC_STAT & 0x01);
|
||||
|
||||
/* 10bits result */
|
||||
return (ADC_DATA & 0x3ff);
|
||||
}
|
||||
|
||||
void adc_init(void)
|
||||
{
|
||||
/* ADC clock divider to reach max 1MHz */
|
||||
SCU_DIVCON1 = (SCU_DIVCON1 & ~(0xff<<10)) | (49<<10);
|
||||
|
||||
/* enable clocks for ADC */
|
||||
SCU_CLKCFG |= 3<<23;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2011 by Marcin Bukat
|
||||
*
|
||||
* 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_
|
||||
|
||||
#define NUM_ADC_CHANNELS 4
|
||||
|
||||
#define ADC_BATTERY 0
|
||||
#define ADC_UNKNOWN_1 1
|
||||
#define ADC_UNKNOWN_2 2
|
||||
#define ADC_VREF 3 /* that is what datasheet says */
|
||||
|
||||
#define ADC_UNREG_POWER ADC_BATTERY /* For compatibility */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,118 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007 Dave Chapman
|
||||
*
|
||||
* 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 <string.h>
|
||||
#include "thread.h"
|
||||
#include "disk.h"
|
||||
#include "storage.h"
|
||||
#include "panic.h"
|
||||
#include "usb.h"
|
||||
#include "ftl-target.h"
|
||||
#include "nand-target.h"
|
||||
|
||||
/* This file provides only STUBS for now */
|
||||
|
||||
/** static, private data **/
|
||||
static bool initialized = false;
|
||||
|
||||
/* API Functions */
|
||||
int nand_read_sectors(IF_MD2(int drive,) unsigned long start, int incount,
|
||||
void* inbuf)
|
||||
{
|
||||
(void)drive;
|
||||
return ftl_read(start, incount, inbuf);
|
||||
}
|
||||
|
||||
int nand_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
|
||||
const void* outbuf)
|
||||
{
|
||||
(void)drive;
|
||||
return ftl_write(start, count, outbuf);
|
||||
}
|
||||
|
||||
void nand_spindown(int seconds)
|
||||
{
|
||||
(void)seconds;
|
||||
}
|
||||
|
||||
void nand_sleep(void)
|
||||
{
|
||||
nand_power_down();
|
||||
}
|
||||
|
||||
void nand_sleepnow(void)
|
||||
{
|
||||
nand_power_down();
|
||||
}
|
||||
|
||||
void nand_spin(void)
|
||||
{
|
||||
nand_set_active();
|
||||
}
|
||||
|
||||
void nand_enable(bool on)
|
||||
{
|
||||
(void)on;
|
||||
}
|
||||
|
||||
void nand_get_info(IF_MD2(int drive,) struct storage_info *info)
|
||||
{
|
||||
(void)drive;
|
||||
uint32_t ppb = ftl_banks * (*ftl_nand_type).pagesperblock;
|
||||
(*info).sector_size = SECTOR_SIZE;
|
||||
(*info).num_sectors = (*ftl_nand_type).userblocks * ppb;
|
||||
(*info).vendor = "Apple";
|
||||
(*info).product = "iPod Nano 2G";
|
||||
(*info).revision = "1.0";
|
||||
}
|
||||
|
||||
long nand_last_disk_activity(void)
|
||||
{
|
||||
return nand_last_activity();
|
||||
}
|
||||
|
||||
#ifdef HAVE_STORAGE_FLUSH
|
||||
int nand_flush(void)
|
||||
{
|
||||
int rc = ftl_sync();
|
||||
if (rc != 0) panicf("Failed to unmount flash: %X", rc);
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
int nand_init(void)
|
||||
{
|
||||
if (ftl_init()) return 1;
|
||||
|
||||
initialized = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_STORAGE_MULTI
|
||||
int nand_num_drives(int first_drive)
|
||||
{
|
||||
/* We don't care which logical drive number(s) we have been assigned */
|
||||
(void)first_drive;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,86 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2011 by Marcin Bukat
|
||||
*
|
||||
* 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 <stdbool.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "backlight.h"
|
||||
#include "backlight-target.h"
|
||||
#include "system.h"
|
||||
|
||||
bool _backlight_init(void)
|
||||
{
|
||||
/* configure PD4 as output */
|
||||
GPIO_PDCON |= (1<<4);
|
||||
|
||||
/* set PD4 low (backlight off) */
|
||||
GPIO_PDDR &= ~(1<<4);
|
||||
|
||||
/* IOMUXB - set PWM0 pin as GPIO */
|
||||
SCU_IOMUXB_CON &= ~(1 << 11); /* type<<11<<channel */
|
||||
|
||||
/* setup pwm */
|
||||
PWMT0_CTRL = (0<<9) | (1<<7);
|
||||
|
||||
/* set pwm frequency ~10kHz */
|
||||
/* (apb_freq/pwm_freq)/pwm_div = (50 000 000/10 000)/2 */
|
||||
PWMT0_LRC = 2500;
|
||||
PWMT0_HRC = 1;
|
||||
|
||||
PWMT0_CNTR = 0x00;
|
||||
PWMT0_CTRL = (0<<9) | (1<<3) | (1<<0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void _backlight_on(void)
|
||||
{
|
||||
/* enable PWM clock */
|
||||
SCU_CLKCFG &= ~(1<<29);
|
||||
|
||||
/* set output pin as PWM pin */
|
||||
SCU_IOMUXB_CON |= (1<<11); /* type<<11<<channel */
|
||||
|
||||
/* 100% duty cycle. Other settings doesn't work for
|
||||
* unknown reason
|
||||
*/
|
||||
PWMT0_HRC = PWMT0_LRC;
|
||||
|
||||
/* pwm enable */
|
||||
PWMT0_CTRL |= (1<<3) | (1<<0);
|
||||
}
|
||||
|
||||
void _backlight_off(void)
|
||||
{
|
||||
/* setup PWM0 pin as GPIO which is pulled low */
|
||||
SCU_IOMUXB_CON &= ~(1<<11);
|
||||
|
||||
/* stop pwm timer */
|
||||
PWMT0_CTRL &= ~(1<<3) | (1<<0);
|
||||
|
||||
/* disable PWM clock */
|
||||
SCU_CLKCFG |= (1<<29);
|
||||
}
|
||||
|
||||
void _backlight_set_brightness(int brightness)
|
||||
{
|
||||
(void)brightness;
|
||||
/* doesn't work for unknown reason */
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2008 by Marcoen Hirschberg
|
||||
*
|
||||
* 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
|
||||
|
||||
bool _backlight_init(void);
|
||||
void _backlight_on(void);
|
||||
void _backlight_off(void);
|
||||
void _backlight_set_brightness(int brightness);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,81 @@
|
|||
#include "config.h"
|
||||
|
||||
ENTRY(start)
|
||||
#ifdef ROCKBOX_LITTLE_ENDIAN
|
||||
OUTPUT_FORMAT(elf32-littlearm)
|
||||
#else
|
||||
OUTPUT_FORMAT(elf32-bigarm)
|
||||
#endif
|
||||
OUTPUT_ARCH(arm)
|
||||
STARTUP(target/arm/rk27xx/crt0.o)
|
||||
|
||||
#define DRAMORIG 0x60000000
|
||||
#define DRAMSIZE (MEMORYSIZE * 0x100000)
|
||||
|
||||
#define IRAMORIG 0x00000000
|
||||
#define IRAMSIZE 4K
|
||||
|
||||
MEMORY
|
||||
{
|
||||
DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
|
||||
IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.intvect : {
|
||||
_intvectstart = . ;
|
||||
*(.intvect)
|
||||
_intvectend = _newstart ;
|
||||
} > IRAM AT > DRAM
|
||||
_intvectcopy = LOADADDR(.intvect) ;
|
||||
|
||||
.text : {
|
||||
*(.init.text)
|
||||
*(.text*)
|
||||
*(.glue_7*)
|
||||
} > DRAM
|
||||
|
||||
.data : {
|
||||
*(.rodata*)
|
||||
*(.data*)
|
||||
*(.ncdata*);
|
||||
. = ALIGN(0x4);
|
||||
} > DRAM
|
||||
|
||||
.idata : {
|
||||
_datastart = . ;
|
||||
*(.irodata)
|
||||
*(.icode)
|
||||
*(.idata)
|
||||
. = ALIGN(0x4);
|
||||
_dataend = . ;
|
||||
} > DRAM
|
||||
_datacopy = LOADADDR(.idata) ;
|
||||
|
||||
.stack (NOLOAD) :
|
||||
{
|
||||
*(.stack)
|
||||
_stackbegin = .;
|
||||
stackbegin = .;
|
||||
. += 0x2000;
|
||||
_stackend = .;
|
||||
stackend = .;
|
||||
_irqstackbegin = .;
|
||||
. += 0x400;
|
||||
_irqstackend = .;
|
||||
_fiqstackbegin = .;
|
||||
. += 0x400;
|
||||
_fiqstackend = .;
|
||||
} > DRAM
|
||||
|
||||
.bss (NOLOAD) : {
|
||||
_edata = .;
|
||||
*(.bss*);
|
||||
*(.ibss);
|
||||
*(.ncbss*);
|
||||
*(COMMON);
|
||||
. = ALIGN(0x4);
|
||||
_end = .;
|
||||
} > DRAM
|
||||
}
|
|
@ -0,0 +1,209 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: crt0.S 18776 2008-10-11 18:32:17Z gevaerts $
|
||||
*
|
||||
* Copyright (C) 2008 by Marcoen Hirschberg
|
||||
* Copyright (C) 2008 by Denes Balatoni
|
||||
* Copyright (C) 2010 by Marcin Bukat
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
#define ASM
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
|
||||
.section .intvect,"ax",%progbits
|
||||
.global start
|
||||
.global _newstart
|
||||
/* Exception vectors */
|
||||
start:
|
||||
b _newstart
|
||||
ldr pc, =undef_instr_handler
|
||||
ldr pc, =software_int_handler
|
||||
ldr pc, =prefetch_abort_handler
|
||||
ldr pc, =data_abort_handler
|
||||
ldr pc, =reserved_handler
|
||||
ldr pc, =irq_handler
|
||||
ldr pc, =fiq_handler
|
||||
.ltorg
|
||||
_newstart:
|
||||
ldr pc, =newstart2
|
||||
.section .init.text,"ax",%progbits
|
||||
newstart2:
|
||||
msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
|
||||
|
||||
mov r0, #0x18000000
|
||||
add r0, r0, #0x1c000
|
||||
|
||||
/* setup ARM core freq = 200MHz */
|
||||
/* AHB bus freq (HCLK) = 100MHz */
|
||||
/* APB bus freq (PCLK) = 50MHz */
|
||||
ldr r1, [r0,#0x14] /* SCU_DIVCON1 */
|
||||
orr r1, #9 /* ARM slow mode, HCLK:PCLK = 2:1 */
|
||||
str r1, [r0,#0x14]
|
||||
|
||||
ldr r1,=0x01970c70 /* (1<<24) | (1<<23) | (23<<16) | (199<<4) */
|
||||
str r1, [r0,#0x08]
|
||||
|
||||
ldr r2,=0x40000
|
||||
1:
|
||||
ldr r1, [r0,#0x2c] /* SCU_STATUS */
|
||||
tst r1, #1 /* ARM pll lock */
|
||||
bne 1f
|
||||
subs r2, #1
|
||||
bne 1b
|
||||
1:
|
||||
ldr r1, [r0,#0x14] /* SCU_DIVCON1 */
|
||||
bic r1, #5 /* leave ARM slow mode, ARMclk:HCLK = 2:1 */
|
||||
str r1, [r0,#0x14]
|
||||
|
||||
#if defined(BOOTLOADER)
|
||||
/* remap iram to 0x00000000 */
|
||||
ldr r1,=0xdeadbeef
|
||||
str r1, [r0, #4]
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* setup caches */
|
||||
ldr r0, =0xefff0000 /* cache controler base address */
|
||||
ldrh r1, [r0]
|
||||
strh r1, [r0] /* global cache disable */
|
||||
|
||||
/* setup uncached regions */
|
||||
mov r1, #0x18000000
|
||||
orr r1, r1, #0xfe
|
||||
str r1, [r0,#0x10] /* MemMapA BUS0IP, 32MB */
|
||||
str r1, [r0,#0x14] /* MemMapB BUS0IP, 32MB */
|
||||
mov r1, #0x30000000
|
||||
orr r1, r1, #0xfe
|
||||
str r1, [r0,#0x18] /* MemMapC DSPMEM, 32MB */
|
||||
mov r1, #0xee000000 /* 0xefff0000 & 0xfe000000 */
|
||||
orr r1, r1, #0xfe
|
||||
str r1, [r0,#0x1c] /* MemMapD cache controller, 32MB */
|
||||
|
||||
mov r1, #2 /* invalidate way opcode */
|
||||
str r1, [r0,#4] /* invalidate way0 */
|
||||
1:
|
||||
ldr r2, [r0,#4]
|
||||
tst r2, #3
|
||||
bne 1b /* wait for invalidate to complete */
|
||||
|
||||
orr r1, r1, #0x80000000
|
||||
str r1, [r0,#4] /* invalidate way1 */
|
||||
1:
|
||||
ldr r2, [r0,#4]
|
||||
tst r2, #3
|
||||
bne 1b /* wait for invalidate to complete */
|
||||
|
||||
ldr r1, [r0]
|
||||
orr r1, r1, #0x80000000
|
||||
str r1, [r0] /* global cache enable */
|
||||
#endif
|
||||
|
||||
/* Copy interrupt vectors to iram */
|
||||
ldr r2, =_intvectstart
|
||||
ldr r3, =_intvectend
|
||||
ldr r4, =_intvectcopy
|
||||
1:
|
||||
cmp r3, r2
|
||||
ldrhi r1, [r4], #4
|
||||
strhi r1, [r2], #4
|
||||
bhi 1b
|
||||
|
||||
/* Initialise bss section to zero */
|
||||
ldr r2, =_edata
|
||||
ldr r3, =_end
|
||||
mov r4, #0
|
||||
1:
|
||||
cmp r3, r2
|
||||
strhi r4, [r2], #4
|
||||
bhi 1b
|
||||
|
||||
#ifndef BOOTLOADER
|
||||
/* Copy icode and data to ram */
|
||||
ldr r2, =_iramstart
|
||||
ldr r3, =_iramend
|
||||
ldr r4, =_iramcopy
|
||||
1:
|
||||
cmp r3, r2
|
||||
ldrhi r1, [r4], #4
|
||||
strhi r1, [r2], #4
|
||||
bhi 1b
|
||||
|
||||
/* Initialise ibss section to zero */
|
||||
ldr r2, =_iedata
|
||||
ldr r3, =_iend
|
||||
mov r4, #0
|
||||
1:
|
||||
cmp r3, r2
|
||||
strhi r4, [r2], #4
|
||||
bhi 1b
|
||||
#endif
|
||||
|
||||
/* Set up some stack and munge it with 0xdeadbeef */
|
||||
ldr sp, =stackend
|
||||
ldr r2, =stackbegin
|
||||
ldr r3, =0xdeadbeef
|
||||
1:
|
||||
cmp sp, r2
|
||||
strhi r3, [r2], #4
|
||||
bhi 1b
|
||||
|
||||
/* Set up stack for IRQ mode */
|
||||
msr cpsr_c, #0xd2
|
||||
ldr sp, =_irqstackend
|
||||
|
||||
/* Set up stack for FIQ mode */
|
||||
msr cpsr_c, #0xd1
|
||||
ldr sp, =_fiqstackend
|
||||
|
||||
/* Let abort and undefined modes use IRQ stack */
|
||||
msr cpsr_c, #0xd7
|
||||
ldr sp, =_irqstackend
|
||||
msr cpsr_c, #0xdb
|
||||
ldr sp, =_irqstackend
|
||||
|
||||
/* Switch back to supervisor mode */
|
||||
msr cpsr_c, #0xd3
|
||||
|
||||
bl main
|
||||
|
||||
.text
|
||||
/* .global UIE*/
|
||||
|
||||
/* 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:
|
||||
sub r0, lr, #4
|
||||
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
|
|
@ -0,0 +1,56 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2010 by Bertrik Sikken
|
||||
*
|
||||
* 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 "ftl-target.h"
|
||||
|
||||
/* this file provides empty STUBS for now */
|
||||
|
||||
uint32_t ftl_init(void)
|
||||
{
|
||||
/* TODO implement */
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t ftl_read(uint32_t sector, uint32_t count, void* buffer)
|
||||
{
|
||||
/* TODO implement */
|
||||
(void)sector;
|
||||
(void)count;
|
||||
(void)buffer;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t ftl_write(uint32_t sector, uint32_t count, const void* buffer)
|
||||
{
|
||||
/* TODO implement */
|
||||
(void)sector;
|
||||
(void)count;
|
||||
(void)buffer;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t ftl_sync(void)
|
||||
{
|
||||
/* TODO implement */
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2009 by Michael Sparmann
|
||||
*
|
||||
* 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 __FTL_TARGET_H__
|
||||
#define __FTL_TARGET_H__
|
||||
|
||||
#include "config.h"
|
||||
#include "inttypes.h"
|
||||
|
||||
#ifdef BOOTLOADER
|
||||
/* Bootloaders don't need write access */
|
||||
#define FTL_READONLY
|
||||
#endif
|
||||
|
||||
/* Pointer to an info structure regarding the flash type used */
|
||||
const struct nand_device_info_type* ftl_nand_type;
|
||||
|
||||
/* Number of banks we detected a chip on */
|
||||
uint32_t ftl_banks;
|
||||
|
||||
uint32_t ftl_init(void);
|
||||
uint32_t ftl_read(uint32_t sector, uint32_t count, void* buffer);
|
||||
uint32_t ftl_write(uint32_t sector, uint32_t count, const void* buffer);
|
||||
uint32_t ftl_sync(void);
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,242 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2011 by Marcin Bukat
|
||||
*
|
||||
* 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 "i2c-rk27xx.h"
|
||||
|
||||
/* NOT TESTED YET */
|
||||
|
||||
/* Driver for the rockchip rk27xx built-in I2C controller in master mode
|
||||
|
||||
Both the i2c_read and i2c_write function take the following arguments:
|
||||
* slave, the address of the i2c slave device to read from / write to
|
||||
* address, optional sub-address in the i2c slave (unused if -1)
|
||||
* len, number of bytes to be transfered
|
||||
* data, pointer to data to be transfered
|
||||
A return value other than 0 indicates an error.
|
||||
*/
|
||||
|
||||
static struct mutex i2c_mtx;
|
||||
|
||||
static bool i2c_write_byte(uint8_t data, bool start)
|
||||
{
|
||||
long timeout = current_tick + HZ / 50;
|
||||
|
||||
/* START */
|
||||
I2C_CONR |= (1<<3) | (1<<2); /* master port enable, transmit bit */
|
||||
I2C_MTXR = data;
|
||||
|
||||
if (start)
|
||||
I2C_LCMR = (1<<2) | (1<<0); /* resume op, start bit */
|
||||
else
|
||||
I2C_LCMR = (1<<2); /* resume op */
|
||||
|
||||
I2C_CONR &= ~(1<<4); /* ACK enable */
|
||||
|
||||
/* wait for ACK from slave */
|
||||
while ( !(I2C_ISR & (1<<0)) || (I2C_LSR & (1<<0)) )
|
||||
if (TIME_AFTER(current_tick, timeout))
|
||||
return false;
|
||||
|
||||
/* clear status bit */
|
||||
I2C_ISR &= ~(1<<0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool i2c_read_byte(unsigned char *data)
|
||||
{
|
||||
long timeout = current_tick + HZ / 50;
|
||||
|
||||
I2C_LCMR = (1<<2); /* resume op */
|
||||
|
||||
while (I2C_ISR & (1<<1))
|
||||
if (TIME_AFTER(current_tick, timeout))
|
||||
return false;
|
||||
|
||||
*data = I2C_MRXR;
|
||||
|
||||
/* clear status bit */
|
||||
I2C_ISR &= ~(1<<1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool i2c_stop(void)
|
||||
{
|
||||
long timeout = current_tick + HZ / 50;
|
||||
|
||||
I2C_CONR &= ~(1<<4);
|
||||
I2C_LCMR |= (1<<2) | (1<<1); /* resume op, stop */
|
||||
|
||||
while (I2C_LCMR & (1<<1))
|
||||
if (TIME_AFTER(current_tick, timeout))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* route i2c bus to internal codec or external bus
|
||||
* internal codec has 0x27 i2c slave address so
|
||||
* access to this address is routed to internal bus.
|
||||
* All other addresses are routed to external pads
|
||||
*/
|
||||
static void i2c_iomux(unsigned char slave)
|
||||
{
|
||||
unsigned long muxa = SCU_IOMUXA_CON & ~(0x1f<<14);
|
||||
|
||||
if (slave == (0x27<<1))
|
||||
{
|
||||
/* internal codec */
|
||||
SCU_IOMUXA_CON = muxa | (1<<16) | (1<<14);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* external I2C bus */
|
||||
SCU_IOMUXA_CON = muxa | (1<<18);
|
||||
}
|
||||
}
|
||||
|
||||
void i2c_init(void)
|
||||
{
|
||||
mutex_init(&i2c_mtx);
|
||||
|
||||
SCU_CLKCFG &= ~(1<< 20);
|
||||
|
||||
I2C_OPR |= (1<<7); /* reset state machine */
|
||||
sleep(HZ/100);
|
||||
I2C_OPR &= ~((1<<7) | (1<<6)); /* clear ENABLE bit, deasert reset */
|
||||
|
||||
/* set I2C divider to stay within allowed SCL freq limit
|
||||
* APBfreq = 50Mhz
|
||||
* SCLfreq = (APBfreq/5*(I2CCDVR[5:3] + 1) * 2^((I2CCDVR[2:0] + 1))
|
||||
*/
|
||||
I2C_OPR = (I2C_OPR & ~(0x3F)) | (6<<3) | 1<<0;
|
||||
|
||||
I2C_IER = 0x00;
|
||||
|
||||
I2C_OPR |= (1<<6); /* enable i2c core */
|
||||
}
|
||||
|
||||
int i2c_write(unsigned char slave, int address, int len,
|
||||
const unsigned char *data)
|
||||
{
|
||||
mutex_lock(&i2c_mtx);
|
||||
|
||||
i2c_iomux(slave);
|
||||
|
||||
/* START */
|
||||
if (! i2c_write_byte(slave & ~1, true))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (address >= 0)
|
||||
{
|
||||
if (! i2c_write_byte(address, false))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* write data */
|
||||
while (len--)
|
||||
{
|
||||
if (! i2c_write_byte(*data++, false))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
/* STOP */
|
||||
if (! i2c_stop())
|
||||
{
|
||||
mutex_unlock(&i2c_mtx);
|
||||
return 5;
|
||||
}
|
||||
|
||||
mutex_unlock(&i2c_mtx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_read(unsigned char slave, int address, int len, unsigned char *data)
|
||||
{
|
||||
mutex_lock(&i2c_mtx);
|
||||
|
||||
i2c_iomux(slave);
|
||||
|
||||
if (address >= 0)
|
||||
{
|
||||
/* START */
|
||||
if (! i2c_write_byte(slave & ~1, true))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* write address */
|
||||
if (! i2c_write_byte(address, false))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* (repeated) START */
|
||||
if (! i2c_write_byte(slave | 1, true))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx);
|
||||
return 3;
|
||||
}
|
||||
|
||||
I2C_CONR &= ~(1<<3); /* clear transmit bit (switch to receive mode) */
|
||||
|
||||
while (len)
|
||||
{
|
||||
if (! i2c_read_byte(data++))
|
||||
{
|
||||
mutex_unlock(&i2c_mtx);
|
||||
return 4;
|
||||
}
|
||||
|
||||
if (len == 1)
|
||||
I2C_CONR |= (1<<4); /* NACK */
|
||||
else
|
||||
I2C_CONR &= ~(1<<4); /* ACK */
|
||||
|
||||
len--;
|
||||
}
|
||||
|
||||
/* STOP */
|
||||
if (! i2c_stop())
|
||||
{
|
||||
mutex_unlock(&i2c_mtx);
|
||||
return 5;
|
||||
}
|
||||
|
||||
mutex_unlock(&i2c_mtx);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2011 by Marcin Bukat
|
||||
*
|
||||
* 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"
|
||||
|
||||
/* rockchip rk27xx driver for the kernel timer */
|
||||
|
||||
/* sys timer ISR */
|
||||
void INT_TIMER0(void)
|
||||
{
|
||||
/* clear interrupt */
|
||||
TMR0CON &= ~0x04;
|
||||
|
||||
call_tick_tasks(); /* Run through the list of tick tasks */
|
||||
}
|
||||
|
||||
/* this assumes 50MHz APB bus frequency */
|
||||
void tick_start(unsigned int interval_in_ms)
|
||||
{
|
||||
unsigned int cycles = 50000 * interval_in_ms;
|
||||
|
||||
/* enable timer clock */
|
||||
SCU_CLKCFG &= (1<<28);
|
||||
|
||||
/* configure timer0 */
|
||||
TMR0LR = cycles;
|
||||
TMR0CON = (1<<8) | (1<<7) | (1<<1); /* periodic, 1/1, interrupt enable */
|
||||
|
||||
/* unmask timer0 interrupt */
|
||||
INTC_IMR |= 0x04;
|
||||
|
||||
/* enable timer0 interrupt */
|
||||
INTC_IECR |= 0x04;
|
||||
}
|
||||
|
|
@ -0,0 +1,304 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2011 Marcin Bukat
|
||||
*
|
||||
* 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 "kernel.h"
|
||||
#include "lcd.h"
|
||||
#include "system.h"
|
||||
#include "cpu.h"
|
||||
#include "spfd5420a.h"
|
||||
|
||||
static inline void delay_nop(int cycles)
|
||||
{
|
||||
asm volatile ("1: subs %[n], %[n], #1 \n\t"
|
||||
" bne 1b"
|
||||
:
|
||||
: [n] "r" (cycles));
|
||||
}
|
||||
|
||||
static unsigned int lcd_data_transform(unsigned int data)
|
||||
{
|
||||
/* 18 bit interface */
|
||||
unsigned int r, g, b;
|
||||
r = (data & 0x0000fc00)<<8;
|
||||
/* g = ((data & 0x00000300) >> 2) | ((data & 0x000000e0) >> 3); */
|
||||
g = ((data & 0x00000300) << 6) | ((data & 0x000000e0) << 5);
|
||||
b = (data & 0x00000001f) << 3;
|
||||
|
||||
return (r | g | b);
|
||||
}
|
||||
|
||||
/* converts RGB565 pixel into internal lcd bus format */
|
||||
static unsigned int lcd_pixel_transform(unsigned short rgb565)
|
||||
{
|
||||
unsigned int r, g, b;
|
||||
b = rgb565 & 0x1f;
|
||||
g = (rgb565 >> 5) & 0x3f;
|
||||
r = (rgb565 >> 11) & 0x1f;
|
||||
|
||||
return r<<19 | g<<10 | b<<3;
|
||||
}
|
||||
|
||||
static void lcd_cmd(unsigned int cmd)
|
||||
{
|
||||
LCD_COMMAND = lcd_data_transform(cmd);
|
||||
}
|
||||
|
||||
static void lcd_data(unsigned int data)
|
||||
{
|
||||
LCD_DATA = lcd_data_transform(data);
|
||||
}
|
||||
|
||||
static void lcd_write_reg(unsigned int reg, unsigned int val)
|
||||
{
|
||||
lcd_cmd(reg);
|
||||
lcd_data(val);
|
||||
}
|
||||
|
||||
static void lcdctrl_bypass(unsigned int on_off)
|
||||
{
|
||||
while (!(LCDC_STA & LCDC_MCU_IDLE));
|
||||
|
||||
if (on_off)
|
||||
MCU_CTRL |= MCU_CTRL_BYPASS;
|
||||
else
|
||||
MCU_CTRL &= ~MCU_CTRL_BYPASS;
|
||||
}
|
||||
|
||||
/* This part is unclear. I am unable to use buffered/FIFO based writes
|
||||
* to lcd. Depending on settings of IF I get various patterns on display
|
||||
* but not what I want to display apparently.
|
||||
*/
|
||||
static void lcdctrl_init(void)
|
||||
{
|
||||
/* alpha b111
|
||||
* stop at current frame complete
|
||||
* MCU mode
|
||||
* 24b RGB
|
||||
*/
|
||||
LCDC_CTRL = ALPHA(7) | LCDC_STOP | LCDC_MCU | RGB24B;
|
||||
MCU_CTRL = ALPHA_BASE(0x3f) | MCU_CTRL_BYPASS;
|
||||
|
||||
HOR_ACT = 400 + 3; /* define horizonatal active region */
|
||||
VERT_ACT = 240; /* define vertical active region */
|
||||
VERT_PERIOD = 0xfff; /* CSn/WEn/RDn signal timings */
|
||||
|
||||
LINE0_YADDR = LINE_ALPHA_EN | 0x7fe;
|
||||
LINE1_YADDR = LINE_ALPHA_EN | ((1 * 400) - 2);
|
||||
LINE2_YADDR = LINE_ALPHA_EN | ((2 * 400) - 2);
|
||||
LINE3_YADDR = LINE_ALPHA_EN | ((3 * 400) - 2);
|
||||
|
||||
LINE0_UVADDR = 0x7fe + 1;
|
||||
LINE1_UVADDR = ((1 * 400) - 2 + 1);
|
||||
LINE2_UVADDR = ((2 * 400) - 2 + 1);
|
||||
LINE3_UVADDR = ((3 * 400) - 2 + 1);
|
||||
|
||||
#if 0
|
||||
LINE0_YADDR = 0;
|
||||
LINE1_YADDR = (1 * 400);
|
||||
LINE2_YADDR = (2 * 400);
|
||||
LINE3_YADDR = (3 * 400);
|
||||
|
||||
LINE0_UVADDR = 1;
|
||||
LINE1_UVADDR = (1 * 400) + 1;
|
||||
LINE2_UVADDR = (2 * 400) + 1;
|
||||
LINE3_UVADDR = (3 * 400) + 1;
|
||||
|
||||
START_X = 0;
|
||||
START_Y = 0;
|
||||
DELTA_X = 0x200; /* no scaling */
|
||||
DELTA_Y = 0x200; /* no scaling */
|
||||
#endif
|
||||
LCDC_INTR_MASK = INTR_MASK_LINE; /* INTR_MASK_EVENLINE; */
|
||||
}
|
||||
|
||||
/* configure pins to drive lcd in 18bit mode */
|
||||
static void iomux_lcd(void)
|
||||
{
|
||||
unsigned long muxa;
|
||||
|
||||
muxa = SCU_IOMUXA_CON & ~(IOMUX_LCD_VSYNC|IOMUX_LCD_DEN|0xff);
|
||||
muxa |= IOMUX_LCD_D18|IOMUX_LCD_D20|IOMUX_LCD_D22|IOMUX_LCD_D17|IOMUX_LCD_D16;
|
||||
|
||||
SCU_IOMUXA_CON = muxa;
|
||||
SCU_IOMUXB_CON |= IOMUX_LCD_D815;
|
||||
}
|
||||
|
||||
/* not tested */
|
||||
static void lcd_sleep(unsigned int sleep)
|
||||
{
|
||||
if (sleep)
|
||||
{
|
||||
/* enter sleep mode */
|
||||
lcd_write_reg(DISPLAY_CTRL1, 0x0170);
|
||||
delay_nop(50);
|
||||
lcd_write_reg(DISPLAY_CTRL1, 0x0000);
|
||||
delay_nop(50);
|
||||
lcd_write_reg(PWR_CTRL1, 0x14B4);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* return to normal operation */
|
||||
lcd_write_reg(PWR_CTRL1, 0x14B0);
|
||||
delay_nop(50);
|
||||
lcd_write_reg(DISPLAY_CTRL1, 0x0173);
|
||||
}
|
||||
|
||||
lcd_cmd(GRAM_WRITE);
|
||||
}
|
||||
|
||||
void lcd_init_device()
|
||||
{
|
||||
unsigned int x, y;
|
||||
|
||||
iomux_lcd(); /* setup pins for 18bit lcd interface */
|
||||
lcdctrl_init(); /* basic lcdc module configuration */
|
||||
|
||||
lcdctrl_bypass(1); /* run in bypass mode - all writes goes directly to lcd controller */
|
||||
|
||||
lcd_write_reg(RESET, 0x0001);
|
||||
delay_nop(10000);
|
||||
lcd_write_reg(RESET, 0x0000);
|
||||
delay_nop(10000);
|
||||
lcd_write_reg(IF_ENDIAN, 0x0000); /* order of receiving data */
|
||||
lcd_write_reg(DRIVER_OUT_CTRL, 0x0000);
|
||||
lcd_write_reg(ENTRY_MODE, 0x1038);
|
||||
lcd_write_reg(WAVEFORM_CTRL, 0x0100);
|
||||
lcd_write_reg(SHAPENING_CTRL, 0x0000);
|
||||
lcd_write_reg(DISPLAY_CTRL2, 0x0808);
|
||||
lcd_write_reg(LOW_PWR_CTRL1, 0x0001);
|
||||
lcd_write_reg(LOW_PWR_CTRL2, 0x0010);
|
||||
lcd_write_reg(EXT_DISP_CTRL1, 0x0000);
|
||||
lcd_write_reg(EXT_DISP_CTRL2, 0x0000);
|
||||
lcd_write_reg(BASE_IMG_SIZE, 0x3100);
|
||||
lcd_write_reg(BASE_IMG_CTRL, 0x0001);
|
||||
lcd_write_reg(VSCROLL_CTRL, 0x0000);
|
||||
lcd_write_reg(PART1_POS, 0x0000);
|
||||
lcd_write_reg(PART1_START, 0x0000);
|
||||
lcd_write_reg(PART1_END, 0x018F);
|
||||
lcd_write_reg(PART2_POS, 0x0000);
|
||||
lcd_write_reg(PART2_START, 0x0000);
|
||||
lcd_write_reg(PART2_END, 0x0000);
|
||||
|
||||
lcd_write_reg(PANEL_IF_CTRL1, 0x0011);
|
||||
delay_nop(10000);
|
||||
lcd_write_reg(PANEL_IF_CTRL2, 0x0202);
|
||||
lcd_write_reg(PANEL_IF_CTRL3, 0x0300);
|
||||
delay_nop(10000);
|
||||
lcd_write_reg(PANEL_IF_CTRL4, 0x021E);
|
||||
lcd_write_reg(PANEL_IF_CTRL5, 0x0202);
|
||||
lcd_write_reg(PANEL_IF_CTRL6, 0x0100);
|
||||
lcd_write_reg(FRAME_MKR_CTRL, 0x0000);
|
||||
lcd_write_reg(MDDI_CTRL, 0x0000);
|
||||
|
||||
lcd_write_reg(GAMMA_CTRL1, 0x0101);
|
||||
lcd_write_reg(GAMMA_CTRL2, 0x0000);
|
||||
lcd_write_reg(GAMMA_CTRL3, 0x0016);
|
||||
lcd_write_reg(GAMMA_CTRL4, 0x2913);
|
||||
lcd_write_reg(GAMMA_CTRL5, 0x260B);
|
||||
lcd_write_reg(GAMMA_CTRL6, 0x0101);
|
||||
lcd_write_reg(GAMMA_CTRL7, 0x1204);
|
||||
lcd_write_reg(GAMMA_CTRL8, 0x0415);
|
||||
lcd_write_reg(GAMMA_CTRL9, 0x0205);
|
||||
lcd_write_reg(GAMMA_CTRL10, 0x0303);
|
||||
lcd_write_reg(GAMMA_CTRL11, 0x0E05);
|
||||
lcd_write_reg(GAMMA_CTRL12, 0x0D01);
|
||||
lcd_write_reg(GAMMA_CTRL13, 0x010D);
|
||||
lcd_write_reg(GAMMA_CTRL14, 0x050E);
|
||||
lcd_write_reg(GAMMA_CTRL15, 0x0303);
|
||||
lcd_write_reg(GAMMA_CTRL16, 0x0502);
|
||||
|
||||
/* power on */
|
||||
lcd_write_reg(DISPLAY_CTRL1, 0x0001);
|
||||
lcd_write_reg(PWR_CTRL6, 0x0001);
|
||||
lcd_write_reg(PWR_CTRL7, 0x0060);
|
||||
delay_nop(50000);
|
||||
lcd_write_reg(PWR_CTRL1, 0x16B0);
|
||||
delay_nop(10000);
|
||||
lcd_write_reg(PWR_CTRL2, 0x0147);
|
||||
delay_nop(10000);
|
||||
lcd_write_reg(PWR_CTRL3, 0x0117);
|
||||
delay_nop(10000);
|
||||
lcd_write_reg(PWR_CTRL4, 0x2F00);
|
||||
delay_nop(50000);
|
||||
lcd_write_reg(VCOM_HV2, 0x0000); /* src 0x0090 */
|
||||
delay_nop(10000);
|
||||
lcd_write_reg(VCOM_HV1, 0x0008); /* src 0x000A */
|
||||
lcd_write_reg(PWR_CTRL3, 0x01BE);
|
||||
delay_nop(10000);
|
||||
|
||||
/* addresses setup */
|
||||
lcd_write_reg(WINDOW_H_START, 0x0000);
|
||||
lcd_write_reg(WINDOW_H_END, 0x00EF); /* 239 */
|
||||
lcd_write_reg(WINDOW_V_START, 0x0000);
|
||||
lcd_write_reg(WINDOW_V_END, 0x018F); /* 399 */
|
||||
lcd_write_reg(GRAM_H_ADDR, 0x0000);
|
||||
lcd_write_reg(GRAM_V_ADDR, 0x0000);
|
||||
|
||||
/* display on */
|
||||
lcd_write_reg(DISPLAY_CTRL1, 0x0021);
|
||||
delay_nop(40000);
|
||||
lcd_write_reg(DISPLAY_CTRL1, 0x0061);
|
||||
delay_nop(100000);
|
||||
lcd_write_reg(DISPLAY_CTRL1, 0x0173);
|
||||
delay_nop(300000);
|
||||
|
||||
|
||||
/* clear screen */
|
||||
lcd_cmd(GRAM_WRITE);
|
||||
|
||||
for (x=0; x<400; x++)
|
||||
for(y=0; y<240; y++)
|
||||
lcd_data(0x000000);
|
||||
|
||||
lcd_sleep(0);
|
||||
}
|
||||
|
||||
/* This is ugly hack. We drive lcd in bypass mode
|
||||
* where all writes goes directly to lcd controller.
|
||||
* This is suboptimal at best. IF module povides
|
||||
* FIFO, internal sram buffer, hardware scaller,
|
||||
* DMA signals, hardware alpha blending and more.
|
||||
* BUT the fact is that I have no idea how to use
|
||||
* this modes. Datasheet floating around is very
|
||||
* unclean in this regard and OF uses ackward
|
||||
* lcd update routines which are hard to understand.
|
||||
* Moreover OF sets some bits in IF module registers
|
||||
* which are referred as reseved in datasheet.
|
||||
*/
|
||||
void lcd_update()
|
||||
{
|
||||
unsigned int x,y;
|
||||
|
||||
for (y=0; y<240; y++)
|
||||
for (x=0; x<400; x++)
|
||||
LCD_DATA = lcd_pixel_transform(lcd_framebuffer[y][x]);
|
||||
}
|
||||
|
||||
/* not implemented yet */
|
||||
void lcd_update_rect(int x, int y, int width, int height)
|
||||
{
|
||||
(void)x;
|
||||
(void)y;
|
||||
(void)width;
|
||||
(void)height;
|
||||
lcd_update();
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2009 by Michael Sparmann
|
||||
*
|
||||
* 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 __NAND_TARGET_H__
|
||||
#define __NAND_TARGET_H__
|
||||
|
||||
#include "config.h"
|
||||
#include "inttypes.h"
|
||||
|
||||
|
||||
struct nand_device_info_type
|
||||
{
|
||||
uint32_t id;
|
||||
uint16_t blocks;
|
||||
uint16_t userblocks;
|
||||
uint16_t pagesperblock;
|
||||
uint8_t blocksizeexponent;
|
||||
uint8_t tunk1;
|
||||
uint8_t twp;
|
||||
uint8_t tunk2;
|
||||
uint8_t tunk3;
|
||||
} __attribute__((packed));
|
||||
|
||||
uint32_t nand_read_page(uint32_t bank, uint32_t page, void* databuffer,
|
||||
void* sparebuffer, uint32_t doecc,
|
||||
uint32_t checkempty);
|
||||
uint32_t nand_write_page(uint32_t bank, uint32_t page, void* databuffer,
|
||||
void* sparebuffer, uint32_t doecc);
|
||||
uint32_t nand_block_erase(uint32_t bank, uint32_t page);
|
||||
|
||||
const struct nand_device_info_type* nand_get_device_type(uint32_t bank);
|
||||
uint32_t nand_reset(uint32_t bank);
|
||||
uint32_t nand_device_init(void);
|
||||
void nand_set_active(void);
|
||||
long nand_last_activity(void);
|
||||
void nand_power_up(void);
|
||||
void nand_power_down(void);
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,39 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2011 Marcin Bukat
|
||||
*
|
||||
* 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"
|
||||
|
||||
void button_init_device(void)
|
||||
{
|
||||
/* setup button gpios as input */
|
||||
GPIO_PCCON &= ~(BUTTON_MAIN);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get button pressed from hardware
|
||||
*/
|
||||
int button_read_device(void)
|
||||
{
|
||||
return (GPIO_PCDR & BUTTON_MAIN);
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2011 Marcin Bukat
|
||||
*
|
||||
* 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 <stdbool.h>
|
||||
#include "config.h"
|
||||
|
||||
void button_init_device(void);
|
||||
int button_read_device(void);
|
||||
|
||||
/* Main unit's buttons */
|
||||
/* values assigned corespond to GPIOs numbers */
|
||||
#define BUTTON_PLAY 0x00000002
|
||||
|
||||
#define BUTTON_REW 0x00000008
|
||||
#define BUTTON_FF 0x00000004
|
||||
#define BUTTON_VOL 0x00000040
|
||||
#define BUTTON_M 0x00000010
|
||||
|
||||
#define BUTTON_LEFT BUTTON_REW
|
||||
#define BUTTON_RIGHT BUTTON_FF
|
||||
#define BUTTON_ON BUTTON_PLAY
|
||||
|
||||
#define BUTTON_REMOTE 0
|
||||
|
||||
#define BUTTON_MAIN (BUTTON_PLAY|BUTTON_REW|BUTTON_FF|\
|
||||
BUTTON_VOL|BUTTON_M)
|
||||
|
||||
#define POWEROFF_BUTTON BUTTON_PLAY
|
||||
#define POWEROFF_COUNT 30
|
||||
|
||||
#endif /* _BUTTON_TARGET_H_ */
|
|
@ -0,0 +1,719 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2006 Daniel Ankers
|
||||
* Copyright © 2008-2009 Rafaël Carré
|
||||
* Copyright (C) 2011 Marcin Bukat
|
||||
*
|
||||
* 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" /* for HAVE_MULTIVOLUME */
|
||||
#include "fat.h"
|
||||
#include "thread.h"
|
||||
#include "gcc_extensions.h"
|
||||
#include "led.h"
|
||||
#include "sdmmc.h"
|
||||
#include "system.h"
|
||||
#include "kernel.h"
|
||||
#include "cpu.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "panic.h"
|
||||
#include "stdbool.h"
|
||||
#include "ata_idle_notify.h"
|
||||
#include "sd.h"
|
||||
#include "usb.h"
|
||||
|
||||
#ifdef HAVE_HOTSWAP
|
||||
#include "disk.h"
|
||||
#endif
|
||||
|
||||
#include "lcd.h"
|
||||
#include <stdarg.h>
|
||||
#include "sysfont.h"
|
||||
|
||||
#define RES_NO (-1)
|
||||
|
||||
static tCardInfo card_info;
|
||||
|
||||
/* for compatibility */
|
||||
static long last_disk_activity = -1;
|
||||
|
||||
static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)];
|
||||
static const char sd_thread_name[] = "ata/sd";
|
||||
static struct mutex sd_mtx SHAREDBSS_ATTR;
|
||||
static struct event_queue sd_queue;
|
||||
#ifndef BOOTLOADER
|
||||
bool sd_enabled = false;
|
||||
#endif
|
||||
|
||||
static struct semaphore transfer_completion_signal;
|
||||
static struct semaphore command_completion_signal;
|
||||
static volatile bool retry;
|
||||
static volatile int cmd_error;
|
||||
|
||||
/* interrupt handler for SD */
|
||||
void INT_SD(void)
|
||||
{
|
||||
const int status = SD_INT;
|
||||
|
||||
SD_INT = 0; /* disable sd interrupts, clear pending interrupts */
|
||||
|
||||
/* cmd and response status pending */
|
||||
if(status & CMD_RES_STAT)
|
||||
{
|
||||
/* get the status */
|
||||
cmd_error = SD_CMDRES;
|
||||
semaphore_release(&command_completion_signal);
|
||||
}
|
||||
|
||||
/* data transfer status pending */
|
||||
if(status & DATA_XFER_STAT)
|
||||
{
|
||||
cmd_error = SD_DATAT;
|
||||
if (cmd_error & DATA_XFER_ERR)
|
||||
retry = true;
|
||||
|
||||
semaphore_release(&transfer_completion_signal);
|
||||
}
|
||||
|
||||
SD_INT = CMD_RES_INT_EN | DATA_XFER_INT_EN;
|
||||
}
|
||||
|
||||
/* Exchange buffers - the one where SD module puts into/reads from
|
||||
* data and the one controlled by MCU. This allows some overlap
|
||||
* in transfer operations and should increase throuput.
|
||||
*/
|
||||
static void mmu_switch_buff(void)
|
||||
{
|
||||
static unsigned int i = 0;
|
||||
|
||||
if (i++ & 0x01)
|
||||
{
|
||||
MMU_CTRL = MMU_MMU0_BUFII | MMU_CPU_BUFI | MMU_BUFII_RESET |
|
||||
MMU_BUFII_BYTE | MMU_BUFI_RESET | MMU_BUFI_WORD;
|
||||
}
|
||||
else
|
||||
{
|
||||
MMU_CTRL = MMU_MMU0_BUFI | MMU_CPU_BUFII | MMU_BUFII_RESET |
|
||||
MMU_BUFII_WORD | MMU_BUFI_RESET | MMU_BUFI_BYTE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset internal pointers of the MMU submodule */
|
||||
static void mmu_buff_reset(void)
|
||||
{
|
||||
MMU_CTRL |= MMU_BUFII_RESET | MMU_BUFI_RESET;
|
||||
}
|
||||
|
||||
/* My generic device uses PC7 pin, active low */
|
||||
static inline bool card_detect_target(void)
|
||||
{
|
||||
return !(GPIO_PCDR & 0x80);
|
||||
}
|
||||
|
||||
/* Send command to the SD card. Command finish is signaled in ISR */
|
||||
static bool send_cmd(const int cmd, const int arg, const int res,
|
||||
unsigned long *response)
|
||||
{
|
||||
SD_CMD = arg;
|
||||
|
||||
if (res > 0)
|
||||
SD_CMDREST = CMD_XFER_START | RES_XFER_START | res | cmd;
|
||||
else
|
||||
SD_CMDREST = CMD_XFER_START | RES_XFER_END | RES_R1 | cmd;
|
||||
|
||||
semaphore_wait(&command_completion_signal, TIMEOUT_BLOCK);
|
||||
|
||||
/* Handle command responses & errors */
|
||||
if(res != RES_NO)
|
||||
{
|
||||
if(cmd_error & STAT_CMD_RES_ERR)
|
||||
return false;
|
||||
|
||||
if(res == RES_R2)
|
||||
{
|
||||
response[0] = SD_RES3;
|
||||
response[1] = SD_RES2;
|
||||
response[2] = SD_RES1;
|
||||
response[3] = SD_RES0;
|
||||
}
|
||||
else
|
||||
response[0] = SD_RES3;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* for some misterious reason the card does not report itself as being in TRAN
|
||||
* but transfers are successful. Rockchip OF does not check the card state
|
||||
* after SELECT. I checked two different cards.
|
||||
*/
|
||||
static void print_card_status(void)
|
||||
{
|
||||
unsigned long response;
|
||||
send_cmd(SD_SEND_STATUS, card_info.rca, RES_R1,
|
||||
&response);
|
||||
|
||||
printf("card status: 0x%0x, state: 0x%0x", response, (response>>9)&0xf);
|
||||
}
|
||||
|
||||
static int sd_wait_for_tran_state(void)
|
||||
{
|
||||
unsigned long response;
|
||||
unsigned int timeout = current_tick + 5*HZ;
|
||||
int cmd_retry = 10;
|
||||
|
||||
while (1)
|
||||
{
|
||||
while (!send_cmd(SD_SEND_STATUS, card_info.rca, RES_R1,
|
||||
&response) && cmd_retry > 0)
|
||||
{
|
||||
cmd_retry--;
|
||||
}
|
||||
|
||||
if (cmd_retry <= 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (((response >> 9) & 0xf) == SD_TRAN)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(TIME_AFTER(current_tick, timeout))
|
||||
{
|
||||
return -10 * ((response >> 9) & 0xf);
|
||||
}
|
||||
|
||||
last_disk_activity = current_tick;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool sd_wait_card_busy(void)
|
||||
{
|
||||
unsigned int timeout = current_tick + 5*HZ;
|
||||
|
||||
while (!(SD_CARD & SD_CARD_BSY))
|
||||
{
|
||||
if(TIME_AFTER(current_tick, timeout))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int sd_init_card(void)
|
||||
{
|
||||
unsigned long response;
|
||||
long init_timeout;
|
||||
bool sd_v2 = false;
|
||||
|
||||
card_info.rca = 0;
|
||||
|
||||
/* assume 50 MHz APB freq / 125 = 400 kHz */
|
||||
SD_CTRL = (SD_CTRL & ~(0x7FF)) | 0x7D;
|
||||
|
||||
/* 100 - 400kHz clock required for Identification Mode */
|
||||
/* Start of Card Identification Mode ************************************/
|
||||
|
||||
/* CMD0 Go Idle */
|
||||
if(!send_cmd(SD_GO_IDLE_STATE, 0, RES_NO, NULL))
|
||||
return -1;
|
||||
|
||||
sleep(1);
|
||||
|
||||
/* CMD8 Check for v2 sd card. Must be sent before using ACMD41
|
||||
Non v2 cards will not respond to this command*/
|
||||
if(send_cmd(SD_SEND_IF_COND, 0x1AA, RES_R6, &response))
|
||||
if((response & 0xFFF) == 0x1AA)
|
||||
sd_v2 = true;
|
||||
|
||||
/* timeout for initialization is 1sec, from SD Specification 2.00 */
|
||||
init_timeout = current_tick + HZ;
|
||||
|
||||
do {
|
||||
/* this timeout is the only valid error for this loop*/
|
||||
if(TIME_AFTER(current_tick, init_timeout))
|
||||
return -2;
|
||||
|
||||
if(!send_cmd(SD_APP_CMD, card_info.rca, RES_R1, &response))
|
||||
return -3;
|
||||
|
||||
sleep(1); /* bus conflict otherwise */
|
||||
|
||||
/* ACMD41 For v2 cards set HCS bit[30] & send host voltage range to all */
|
||||
if(!send_cmd(SD_APP_OP_COND, (0x00FF8000 | (sd_v2 ? 1<<30 : 0)),
|
||||
RES_R3, &card_info.ocr))
|
||||
return -4;
|
||||
} while(!(card_info.ocr & (1<<31)) );
|
||||
|
||||
/* CMD2 send CID */
|
||||
if(!send_cmd(SD_ALL_SEND_CID, 0, RES_R2, card_info.cid))
|
||||
return -5;
|
||||
|
||||
/* CMD3 send RCA */
|
||||
if(!send_cmd(SD_SEND_RELATIVE_ADDR, 0, RES_R6, &card_info.rca))
|
||||
return -6;
|
||||
|
||||
/* End of Card Identification Mode ************************************/
|
||||
|
||||
/* Card back to full speed 25MHz*/
|
||||
SD_CTRL = (SD_CTRL & ~0x7FF) | 1; /* FIXME check this divider - OF uses 0 here*/
|
||||
|
||||
/* CMD9 send CSD */
|
||||
if(!send_cmd(SD_SEND_CSD, card_info.rca, RES_R2, card_info.csd))
|
||||
return -11;
|
||||
|
||||
sd_parse_csd(&card_info);
|
||||
|
||||
if(!send_cmd(SD_SELECT_CARD, card_info.rca, RES_R1b, &response))
|
||||
return -20;
|
||||
|
||||
if (!sd_wait_card_busy())
|
||||
return -21;
|
||||
|
||||
card_info.initialized = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sd_thread(void) NORETURN_ATTR;
|
||||
static void sd_thread(void)
|
||||
{
|
||||
struct queue_event ev;
|
||||
bool idle_notified = false;
|
||||
|
||||
while (1)
|
||||
{
|
||||
queue_wait_w_tmo(&sd_queue, &ev, HZ);
|
||||
|
||||
switch ( ev.id )
|
||||
{
|
||||
#ifdef HAVE_HOTSWAP
|
||||
case SYS_HOTSWAP_INSERTED:
|
||||
case SYS_HOTSWAP_EXTRACTED:
|
||||
{
|
||||
int microsd_init = 1;
|
||||
fat_lock(); /* lock-out FAT activity first -
|
||||
prevent deadlocking via disk_mount that
|
||||
would cause a reverse-order attempt with
|
||||
another thread */
|
||||
mutex_lock(&sd_mtx); /* lock-out card activity - direct calls
|
||||
into driver that bypass the fat cache */
|
||||
|
||||
/* We now have exclusive control of fat cache and ata */
|
||||
|
||||
disk_unmount(sd_first_drive); /* release "by force", ensure file
|
||||
descriptors aren't leaked and any busy
|
||||
ones are invalid if mounting */
|
||||
/* Force card init for new card, re-init for re-inserted one or
|
||||
* clear if the last attempt to init failed with an error. */
|
||||
card_info.initialized = 0;
|
||||
|
||||
if (ev.id == SYS_HOTSWAP_INSERTED)
|
||||
{
|
||||
sd_enable(true);
|
||||
microsd_init = sd_init_card(sd_first_drive);
|
||||
if (microsd_init < 0) /* initialisation failed */
|
||||
panicf("microSD init failed : %d", microsd_init);
|
||||
|
||||
microsd_init = disk_mount(sd_first_drive); /* 0 if fail */
|
||||
}
|
||||
|
||||
/*
|
||||
* Mount succeeded, or this was an EXTRACTED event,
|
||||
* in both cases notify the system about the changed filesystems
|
||||
*/
|
||||
if (microsd_init)
|
||||
queue_broadcast(SYS_FS_CHANGED, 0);
|
||||
|
||||
sd_enable(false);
|
||||
|
||||
/* Access is now safe */
|
||||
mutex_unlock(&sd_mtx);
|
||||
fat_unlock();
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case SYS_TIMEOUT:
|
||||
if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
|
||||
{
|
||||
idle_notified = false;
|
||||
}
|
||||
else if (!idle_notified)
|
||||
{
|
||||
call_storage_idle_notifys(false);
|
||||
idle_notified = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case SYS_USB_CONNECTED:
|
||||
usb_acknowledge(SYS_USB_CONNECTED_ACK);
|
||||
/* Wait until the USB cable is extracted again */
|
||||
usb_wait_for_disconnect(&sd_queue);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void init_controller(void)
|
||||
{
|
||||
/* reset SD module */
|
||||
SCU_RSTCFG |= (1<<9);
|
||||
sleep(1);
|
||||
SCU_RSTCFG &= ~(1<<9);
|
||||
|
||||
/* set pins functions as SD signals */
|
||||
SCU_IOMUXA_CON |= IOMUX_SD;
|
||||
|
||||
/* enable and unmask SD interrupts in interrupt controller */
|
||||
INTC_IMR |= (1<<10);
|
||||
INTC_IECR |= (1<<10);
|
||||
|
||||
SD_CTRL = SD_PWR_CPU | SD_DETECT_MECH | SD_CLOCK_EN | 0x7D;
|
||||
SD_INT = CMD_RES_INT_EN | DATA_XFER_INT_EN;
|
||||
SD_CARD = SD_CARD_SELECT | SD_CARD_PWR_EN;
|
||||
|
||||
/* setup mmu buffers */
|
||||
MMU_PNRI = 0x1ff;
|
||||
MMU_PNRII = 0x1ff;
|
||||
MMU_CTRL = MMU_MMU0_BUFII | MMU_CPU_BUFI | MMU_BUFII_RESET |
|
||||
MMU_BUFII_BYTE | MMU_BUFI_RESET | MMU_BUFI_WORD;
|
||||
|
||||
}
|
||||
|
||||
int sd_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
semaphore_init(&transfer_completion_signal, 1, 0);
|
||||
semaphore_init(&command_completion_signal, 1, 0);
|
||||
|
||||
init_controller();
|
||||
|
||||
ret = sd_init_card();
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
|
||||
/* init mutex */
|
||||
mutex_init(&sd_mtx);
|
||||
|
||||
queue_init(&sd_queue, true);
|
||||
create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,
|
||||
sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count,
|
||||
void* buf)
|
||||
{
|
||||
#ifdef HAVE_MULTIDRIVE
|
||||
(void)drive;
|
||||
#endif
|
||||
unsigned long response;
|
||||
unsigned int retry_cnt = 0;
|
||||
int cnt, ret = 0;
|
||||
unsigned char *dst;
|
||||
|
||||
mutex_lock(&sd_mtx);
|
||||
sd_enable(true);
|
||||
|
||||
if (count <= 0 || start + count > card_info.numblocks)
|
||||
return -1;
|
||||
|
||||
if(!(card_info.ocr & (1<<30)))
|
||||
start <<= 9; /* not SDHC */
|
||||
|
||||
/* setup A2A DMA CH0 */
|
||||
A2A_ISRC0 = (unsigned long)(&MMU_DATA);
|
||||
A2A_ICNT0 = 512;
|
||||
A2A_LCNT0 = 1;
|
||||
A2A_DOMAIN = 0;
|
||||
|
||||
while (retry_cnt++ < 20)
|
||||
{
|
||||
cnt = count;
|
||||
dst = (unsigned char *)buf;
|
||||
|
||||
ret = 0;
|
||||
retry = false; /* reset retry flag */
|
||||
mmu_buff_reset(); /* reset recive buff state */
|
||||
|
||||
/* issue read command to the card */
|
||||
if (!send_cmd(SD_READ_MULTIPLE_BLOCK, start, RES_R1, &response))
|
||||
{
|
||||
ret = -4;
|
||||
continue;
|
||||
}
|
||||
|
||||
while (cnt > 0)
|
||||
{
|
||||
if (cnt == 1)
|
||||
{
|
||||
/* last block to tranfer */
|
||||
SD_DATAT = DATA_XFER_START | DATA_XFER_READ |
|
||||
DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
|
||||
DATA_XFER_SINGLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* more than one block to transfer */
|
||||
SD_DATAT = DATA_XFER_START | DATA_XFER_READ |
|
||||
DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
|
||||
DATA_XFER_MULTI;
|
||||
}
|
||||
|
||||
/* wait for transfer completion */
|
||||
semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
|
||||
|
||||
if (retry)
|
||||
{
|
||||
/* data transfer error */
|
||||
ret = -5;
|
||||
break;
|
||||
}
|
||||
|
||||
/* exchange buffers */
|
||||
mmu_switch_buff();
|
||||
|
||||
last_disk_activity = current_tick;
|
||||
|
||||
/* transfer data from receive buffer to the dest
|
||||
* for (i=0; i<(512/4); i++)
|
||||
* *dst++ = MMU_DATA;
|
||||
*
|
||||
* below is DMA version in software mode.
|
||||
* SD module provides DMAreq signals and all this
|
||||
* can be done in hardware in theory but I can't
|
||||
* figure this out. OF doesn't use DMA at all.
|
||||
*/
|
||||
A2A_IDST0 = (unsigned long)dst;
|
||||
A2A_CON0 = (3<<9) | (1<<6) | (1<<3) | (2<<1) | (1<<0);
|
||||
|
||||
/* wait for DMA engine to finish transfer */
|
||||
while (A2A_DMA_STS & 1);
|
||||
|
||||
dst += 512;
|
||||
cnt--;
|
||||
} /* while (cnt > 0) */
|
||||
|
||||
if (!send_cmd(SD_STOP_TRANSMISSION, 0, RES_R1b, &response))
|
||||
ret = -6;
|
||||
|
||||
/* transfer successfull - leave retry loop */
|
||||
if (ret == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
sd_enable(false);
|
||||
mutex_unlock(&sd_mtx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Not tested */
|
||||
int sd_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
|
||||
const void* buf)
|
||||
{
|
||||
#ifdef HAVE_MULTIDRIVE
|
||||
(void) drive;
|
||||
#endif
|
||||
#if defined(BOOTLOADER) /* we don't need write support in bootloader */
|
||||
(void) start;
|
||||
(void) count;
|
||||
(void) buf;
|
||||
return -1;
|
||||
#else
|
||||
unsigned long response;
|
||||
unsigned int retry_cnt = 0;
|
||||
int cnt, ret = 0;
|
||||
unsigned char *src;
|
||||
bool card_selected = false;
|
||||
|
||||
mutex_lock(&sd_mtx);
|
||||
sd_enable(true);
|
||||
|
||||
if (count <= 0 || start + count > card_info.numblocks)
|
||||
return -1;
|
||||
|
||||
if(!(card_info.ocr & (1<<30)))
|
||||
start <<= 9; /* not SDHC */
|
||||
|
||||
/* setup A2A DMA CH0 */
|
||||
A2A_IDST0 = (unsigned long)(&MMU_DATA);
|
||||
A2A_ICNT0 = 512;
|
||||
A2A_LCNT0 = 1;
|
||||
A2A_DOMAIN = 0;
|
||||
|
||||
while (retry_cnt++ < 20)
|
||||
{
|
||||
cnt = count;
|
||||
src = (unsigned char *)buf;
|
||||
|
||||
ret = 0;
|
||||
retry = false; /* reset retry flag */
|
||||
mmu_buff_reset(); /* reset recive buff state */
|
||||
|
||||
if (!send_cmd(SD_WRITE_MULTIPLE_BLOCK, start, RES_R1, &response))
|
||||
{
|
||||
ret = -3;
|
||||
continue;
|
||||
}
|
||||
|
||||
while (cnt > 0)
|
||||
{
|
||||
/* transfer data from receive buffer to the dest
|
||||
* for (i=0; i<(512/4); i++)
|
||||
* MMU_DATA = *src++;
|
||||
*
|
||||
* Below is DMA version in software mode.
|
||||
*/
|
||||
|
||||
A2A_ISRC0 = (unsigned long)src;
|
||||
A2A_CON0 = (3<<9) | (1<<5) | (1<<3) | (2<<1) | (1<<0);
|
||||
|
||||
while (A2A_DMA_STS & 1);
|
||||
|
||||
src += 512;
|
||||
|
||||
/* exchange buffers */
|
||||
mmu_switch_buff();
|
||||
|
||||
if (cnt == 1)
|
||||
{
|
||||
/* last block to tranfer */
|
||||
SD_DATAT = DATA_XFER_START | DATA_XFER_WRITE |
|
||||
DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
|
||||
DATA_XFER_SINGLE;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* more than one block to transfer */
|
||||
SD_DATAT = DATA_XFER_START | DATA_XFER_WRITE |
|
||||
DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
|
||||
DATA_XFER_MULTI;
|
||||
|
||||
}
|
||||
|
||||
/* wait for transfer completion */
|
||||
semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
|
||||
|
||||
if (retry)
|
||||
{
|
||||
/* data transfer error */
|
||||
ret = -3;
|
||||
break;
|
||||
}
|
||||
|
||||
cnt--;
|
||||
} /* while (cnt > 0) */
|
||||
|
||||
if (!send_cmd(SD_STOP_TRANSMISSION, 0, RES_R1b, &response))
|
||||
ret = -4;
|
||||
|
||||
if (!sd_wait_card_busy())
|
||||
ret = -5;
|
||||
|
||||
/* transfer successfull - leave retry loop */
|
||||
if (ret == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
sd_enable(false);
|
||||
mutex_unlock(&sd_mtx);
|
||||
|
||||
return ret;
|
||||
|
||||
#endif /* defined(BOOTLOADER) */
|
||||
}
|
||||
|
||||
void sd_enable(bool on)
|
||||
{
|
||||
/* enable or disable clock signal for SD module */
|
||||
if (on)
|
||||
{
|
||||
SCU_CLKCFG &= ~(1<<22);
|
||||
}
|
||||
else
|
||||
{
|
||||
SCU_CLKCFG |= (1<<22);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BOOTLOADER
|
||||
long sd_last_disk_activity(void)
|
||||
{
|
||||
return last_disk_activity;
|
||||
}
|
||||
|
||||
tCardInfo *card_get_info_target(int card_no)
|
||||
{
|
||||
(void)card_no;
|
||||
return &card_info;
|
||||
}
|
||||
#endif /* BOOTLOADER */
|
||||
|
||||
#ifdef HAVE_HOTSWAP
|
||||
/* Not complete and disabled in config */
|
||||
bool sd_removable(IF_MD_NONVOID(int drive))
|
||||
{
|
||||
(void)drive;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sd_present(IF_MD_NONVOID(int drive))
|
||||
{
|
||||
(void)drive;
|
||||
return card_detect_target();
|
||||
}
|
||||
|
||||
static int sd_oneshot_callback(struct timeout *tmo)
|
||||
{
|
||||
(void)tmo;
|
||||
|
||||
/* This is called only if the state was stable for 300ms - check state
|
||||
* and post appropriate event. */
|
||||
if (card_detect_target())
|
||||
{
|
||||
queue_broadcast(SYS_HOTSWAP_INSERTED, 0);
|
||||
}
|
||||
else
|
||||
queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* interrupt handler for SD detect */
|
||||
|
||||
#endif /* HAVE_HOTSWAP */
|
||||
|
||||
#ifdef CONFIG_STORAGE_MULTI
|
||||
int sd_num_drives(int first_drive)
|
||||
{
|
||||
(void)first_drive;
|
||||
|
||||
/* we have only one SD drive */
|
||||
return 1;
|
||||
}
|
||||
#endif /* CONFIG_STORAGE_MULTI */
|
|
@ -0,0 +1,107 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2011 Marcin Bukat
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define ID_READ 0x000
|
||||
#define DRIVER_OUT_CTRL 0x001
|
||||
#define WAVEFORM_CTRL 0x002
|
||||
#define ENTRY_MODE 0x003
|
||||
/* 0x004 - 0x005 reserved */
|
||||
#define SHAPENING_CTRL 0x006 /* not present in datasheet */
|
||||
#define DISPLAY_CTRL1 0x007
|
||||
#define DISPLAY_CTRL2 0x008
|
||||
#define LOW_PWR_CTRL1 0x009
|
||||
/* 0x00A reserved */
|
||||
#define LOW_PWR_CTRL2 0x00B
|
||||
#define EXT_DISP_CTRL1 0x00C
|
||||
/* 0x00D - 0x00E reserved */
|
||||
#define EXT_DISP_CTRL2 0x00F
|
||||
#define PANEL_IF_CTRL1 0x010
|
||||
#define PANEL_IF_CTRL2 0x011
|
||||
#define PANEL_IF_CTRL3 0x012
|
||||
/* 0x013 - 0x01F reserved */
|
||||
#define PANEL_IF_CTRL4 0x020
|
||||
#define PANEL_IF_CTRL5 0x021
|
||||
#define PANEL_IF_CTRL6 0x022
|
||||
/* 0x023 - 0x08F reserved */
|
||||
#define FRAME_MKR_CTRL 0x090
|
||||
/* 0x091 reserved */
|
||||
#define MDDI_CTRL 0x092 /* not present in datasheet */
|
||||
/* 0x093 - 0x0FF reserved */
|
||||
#define PWR_CTRL1 0x100
|
||||
#define PWR_CTRL2 0x101
|
||||
#define PWR_CTRL3 0x102
|
||||
#define PWR_CTRL4 0x103 /* amplitude to VCOM */
|
||||
/* 0x104 - 0x106 reserved */
|
||||
#define PWR_CTRL5 0x107
|
||||
/* 0x108 - 0x10F reserved */
|
||||
#define PWR_CTRL6 0x110
|
||||
#define PWR_CTRL7 0x112 /* not present in datasheet */
|
||||
/* 0x113 - 0x1FF reserved */
|
||||
#define GRAM_H_ADDR 0x200
|
||||
#define GRAM_V_ADDR 0x201
|
||||
#define GRAM_READ 0x202
|
||||
#define GRAM_WRITE 0x202
|
||||
/* 0x203 - 0x20F reserved */
|
||||
#define WINDOW_H_START 0x210
|
||||
#define WINDOW_H_END 0x211
|
||||
#define WINDOW_V_START 0x212
|
||||
#define WINDOW_V_END 0x213
|
||||
/* 0x214 - 0x27F reserved */
|
||||
#define NVM_READ 0x280
|
||||
#define NVM_WRITE 0x280
|
||||
#define VCOM_HV1 0x281
|
||||
#define VCOM_HV2 0x282
|
||||
/* 0x283 - 0x2FF reserved */
|
||||
#define GAMMA_CTRL1 0x300
|
||||
#define GAMMA_CTRL2 0x301
|
||||
#define GAMMA_CTRL3 0x302
|
||||
#define GAMMA_CTRL4 0x303
|
||||
#define GAMMA_CTRL5 0x304
|
||||
#define GAMMA_CTRL6 0x305
|
||||
#define GAMMA_CTRL7 0x306
|
||||
#define GAMMA_CTRL8 0x307
|
||||
#define GAMMA_CTRL9 0x308
|
||||
#define GAMMA_CTRL10 0x309
|
||||
#define GAMMA_CTRL11 0x30A
|
||||
#define GAMMA_CTRL12 0x30B
|
||||
#define GAMMA_CTRL13 0x30C
|
||||
#define GAMMA_CTRL14 0x30D
|
||||
#define GAMMA_CTRL15 0x30E
|
||||
#define GAMMA_CTRL16 0x30F
|
||||
/* 0x310 - 0x3FF reserved */
|
||||
#define BASE_IMG_SIZE 0x400
|
||||
#define BASE_IMG_CTRL 0x401
|
||||
/* 0x402 - 0x403 reserved */
|
||||
#define VSCROLL_CTRL 0x404
|
||||
/* 0x405 - 0x4FF reserved */
|
||||
#define PART1_POS 0x500
|
||||
#define PART1_START 0x501
|
||||
#define PART1_END 0x502
|
||||
#define PART2_POS 0x503
|
||||
#define PART2_START 0x504
|
||||
#define PART2_END 0x505
|
||||
/* 0x506 - 0x5FF reserved */
|
||||
#define RESET 0x600 /* not present in datasheet */
|
||||
/* 0x601 - 0x605 */
|
||||
#define IF_ENDIAN 0x606
|
||||
/* 0x607 - 0x6EF reserved */
|
||||
#define NVM_CTRL 0x6F0
|
||||
/* 0x6F1 - 0xFFF reserved */
|
|
@ -0,0 +1,164 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2011 by Marcin Bukat
|
||||
*
|
||||
* 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 "system-target.h"
|
||||
|
||||
#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, \
|
||||
weak, alias("fiq_dummy")));
|
||||
|
||||
default_interrupt(INT_UART0);
|
||||
default_interrupt(INT_UART1);
|
||||
default_interrupt(INT_TIMER0);
|
||||
default_interrupt(INT_TIMER1);
|
||||
default_interrupt(INT_TIMER2);
|
||||
default_interrupt(INT_GPIO0);
|
||||
default_interrupt(INT_SW_INT0);
|
||||
default_interrupt(INT_AHB0_MAILBOX);
|
||||
default_interrupt(INT_RTC);
|
||||
default_interrupt(INT_SCU);
|
||||
default_interrupt(INT_SD);
|
||||
default_interrupt(INT_SPI);
|
||||
default_interrupt(INT_HDMA);
|
||||
default_interrupt(INT_A2A_BRIDGE);
|
||||
default_interrupt(INT_I2C);
|
||||
default_interrupt(INT_I2S);
|
||||
default_interrupt(INT_UDC);
|
||||
default_interrupt(INT_UHC);
|
||||
default_interrupt(INT_PWM0);
|
||||
default_interrupt(INT_PWM1);
|
||||
default_interrupt(INT_PWM2);
|
||||
default_interrupt(INT_ADC);
|
||||
default_interrupt(INT_GPIO1);
|
||||
default_interrupt(INT_VIP);
|
||||
default_interrupt(INT_DWDMA);
|
||||
default_interrupt(INT_NANDC);
|
||||
default_interrupt(INT_LCDC);
|
||||
default_interrupt(INT_DSP);
|
||||
default_interrupt(INT_SW_INT1);
|
||||
default_interrupt(INT_SW_INT2);
|
||||
default_interrupt(INT_SW_INT3);
|
||||
|
||||
static void (* const irqvector[])(void) =
|
||||
{
|
||||
INT_UART0,INT_UART1,INT_TIMER0,INT_TIMER1,INT_TIMER2,INT_GPIO0,INT_SW_INT0,INT_AHB0_MAILBOX,
|
||||
INT_RTC,INT_SCU,INT_SD,INT_SPI,INT_HDMA,INT_A2A_BRIDGE,INT_I2C,
|
||||
INT_I2S,INT_UDC,INT_UHC,INT_PWM0,INT_PWM1,INT_PWM2,INT_ADC,INT_GPIO1,
|
||||
INT_VIP,INT_DWDMA,INT_NANDC,INT_LCDC,INT_DSP,INT_SW_INT1,INT_SW_INT2,INT_SW_INT3
|
||||
};
|
||||
|
||||
static const char * const irqname[] =
|
||||
{
|
||||
"INT_UART0","INT_UART1","INT_TIMER0","INT_TIMER1","INT_TIMER2","INT_GPIO0","INT_SW_INT0","INT_AHB0_MAILBOX",
|
||||
"INT_RTC","INT_SCU","INT_SD","INT_SPI","INT_HDMA","INT_A2A_BRIDGE","INT_I2C",
|
||||
"INT_I2S","INT_UDC","INT_UHC","INT_PWM0","INT_PWM1","INT_PWM2","INT_ADC","INT_GPIO1",
|
||||
"INT_VIP","INT_DWDMA","INT_NANDC","INT_LCDC","INT_DSP","INT_SW_INT1","INT_SW_INT2","INT_SW_INT3"
|
||||
};
|
||||
|
||||
static void UIRQ(void)
|
||||
{
|
||||
unsigned int offset = INTC_ISR & 0x1f;
|
||||
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 */
|
||||
|
||||
int irq_no = INTC_ISR & 0x1f;
|
||||
|
||||
irqvector[irq_no]();
|
||||
|
||||
/* clear interrupt */
|
||||
INTC_ICCR = (1 << irq_no);
|
||||
|
||||
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 IRQ */
|
||||
}
|
||||
|
||||
void fiq_dummy(void)
|
||||
{
|
||||
asm volatile (
|
||||
"subs pc, lr, #4 \r\n"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void system_init(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* not tested */
|
||||
void system_reboot(void)
|
||||
{
|
||||
/* use Watchdog to reset */
|
||||
WDTLR = 1;
|
||||
WDTCON = (1<<4) | (1<<3);
|
||||
|
||||
/* Wait for reboot to kick in */
|
||||
while(1);
|
||||
}
|
||||
|
||||
void system_exception_wait(void)
|
||||
{
|
||||
while(1);
|
||||
}
|
||||
|
||||
int system_memory_guard(int newmode)
|
||||
{
|
||||
(void)newmode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* usecs may be at most 2^32/200 (~21 seconds) for 200MHz max cpu freq */
|
||||
void udelay(unsigned usecs)
|
||||
{
|
||||
unsigned cycles_per_usec;
|
||||
unsigned delay;
|
||||
|
||||
if (cpu_frequency == CPUFREQ_MAX) {
|
||||
cycles_per_usec = (CPUFREQ_MAX + 999999) / 1000000;
|
||||
} else {
|
||||
cycles_per_usec = (CPUFREQ_NORMAL + 999999) / 1000000;
|
||||
}
|
||||
|
||||
delay = (usecs * cycles_per_usec + 3) / 4;
|
||||
|
||||
asm volatile(
|
||||
"1: subs %0, %0, #1 \n" /* 1 cycle */
|
||||
" bne 1b \n" /* 3 cycles */
|
||||
: : "r"(delay)
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2008 Rafaël Carré
|
||||
* Copyright (C) 2011 Marcin Bukat
|
||||
*
|
||||
* 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 "panic.h"
|
||||
|
||||
void udelay(unsigned usecs);
|
||||
static inline void mdelay(unsigned msecs)
|
||||
{
|
||||
udelay(1000 * msecs);
|
||||
}
|
||||
|
||||
/* this needs more testing */
|
||||
static inline void core_sleep(void)
|
||||
{
|
||||
enable_irq();
|
||||
SCU_CPUPD = 0xdeedbabe;
|
||||
}
|
||||
|
||||
#define CPUFREQ_NORMAL 200000000
|
||||
#define CPUFREQ_MAX 200000000
|
||||
|
||||
#endif /* SYSTEM_TARGET_H */
|
|
@ -0,0 +1,74 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2011 by Marcin Bukat
|
||||
*
|
||||
* 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 "inttypes.h"
|
||||
#include "system.h"
|
||||
#include "timer.h"
|
||||
|
||||
void INT_TIMER1(void)
|
||||
{
|
||||
/* clear interrupt */
|
||||
TMR1CON &= ~(1<<2);
|
||||
|
||||
if (pfn_timer != NULL)
|
||||
{
|
||||
pfn_timer();
|
||||
}
|
||||
}
|
||||
|
||||
bool timer_set(long cycles, bool start)
|
||||
{
|
||||
/* optionally unregister any previously registered timer user */
|
||||
if (start)
|
||||
{
|
||||
if (pfn_unregister != NULL)
|
||||
{
|
||||
pfn_unregister();
|
||||
pfn_unregister = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
TMR1LR = cycles;
|
||||
TMR1CON = (1<<7) | (1<<1); /* periodic, 1/1 */
|
||||
|
||||
/* unmask timer1 interrupt */
|
||||
INTC_IMR |= (1<<3);
|
||||
|
||||
/* enable timer1 interrupt */
|
||||
INTC_IECR |= (1<<3);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool timer_start(void)
|
||||
{
|
||||
TMR1CON |= (1 << 8); /* timer1 enable */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void timer_stop(void)
|
||||
{
|
||||
TMR1CON &= ~(1 << 8); /* timer1 disable */
|
||||
}
|
||||
|
|
@ -109,7 +109,7 @@ static inline void core_sleep(void)
|
|||
}
|
||||
#else
|
||||
/* Skip this if special code is required and implemented */
|
||||
#ifndef CPU_PP
|
||||
#if !(defined(CPU_PP)) && CONFIG_CPU != RK27XX
|
||||
static inline void core_sleep(void)
|
||||
{
|
||||
#warning core_sleep not implemented, battery life will be decreased
|
||||
|
|
|
@ -500,6 +500,13 @@ arm1176jzscc () {
|
|||
endian="little"
|
||||
}
|
||||
|
||||
arm7ejscc () {
|
||||
findarmgcc
|
||||
GCCOPTS="$CCOPTS -march=armv5te"
|
||||
GCCOPTIMIZE="-fomit-frame-pointer"
|
||||
endian="little"
|
||||
}
|
||||
|
||||
mipselcc () {
|
||||
prefixtools mipsel-elf-
|
||||
# mips is predefined, but we want it for paths. use __mips instead
|
||||
|
@ -1271,8 +1278,8 @@ cat <<EOF
|
|||
200) SDL 170) HD200 131) Mini2440
|
||||
201) Android 171) HD300
|
||||
202) Nokia N8xx
|
||||
203) Nokia N900
|
||||
204) Pandora
|
||||
203) Nokia N900 ==ROCKCHIP==
|
||||
204) Pandora 180) rk27xx generic
|
||||
|
||||
EOF
|
||||
|
||||
|
@ -2969,6 +2976,29 @@ fi
|
|||
t_model="hd300"
|
||||
;;
|
||||
|
||||
180|rk27generic)
|
||||
target_id=78
|
||||
modelname="rk27generic"
|
||||
target="-DRK27_GENERIC"
|
||||
memory=16 # always
|
||||
arm7ejscc
|
||||
tool="$rootdir/tools/scramble -add=rk27"
|
||||
bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
|
||||
bmp2rb_native="$rootdir/tools/bmp2rb -f 4"
|
||||
output="rockbox.rk27"
|
||||
bootoutput="bootloader.rk27"
|
||||
appextra="recorder:gui:radio"
|
||||
plugins="yes"
|
||||
swcodec="yes"
|
||||
# toolset is the tools within the tools directory that we build for
|
||||
# this particular target.
|
||||
toolset="$genericbitmaptools"
|
||||
# architecture, manufacturer and model for the target-tree build
|
||||
t_cpu="arm"
|
||||
t_manufacturer="rk27xx"
|
||||
t_model="rk27generic"
|
||||
;;
|
||||
|
||||
200|sdlapp)
|
||||
application="yes"
|
||||
target_id=73
|
||||
|
|
|
@ -126,7 +126,7 @@ void usage(void)
|
|||
printf("\t 9200, 1630, 6330, ldax, m200, c100, clip, e2v2,\n"
|
||||
"\t m2v4, fuze, c2v2, clv2, y820, y920, y925, x747,\n"
|
||||
"\t 747p, x777, nn2g, m244, cli+, fuz2, hd20, hd30,\n"
|
||||
"\t ip6g)\n");
|
||||
"\t ip6g, rk27)\n");
|
||||
printf("\nNo option results in Archos standard player/recorder format.\n");
|
||||
|
||||
exit(1);
|
||||
|
@ -337,6 +337,8 @@ int main (int argc, char** argv)
|
|||
modelnum = 71;
|
||||
else if (!strcmp(&argv[1][5], "fuz+")) /* Sansa Fuze+ */
|
||||
modelnum = 72;
|
||||
else if (!strcmp(&argv[1][5], "rk27")) /* rockchip 27xx generic */
|
||||
modelnum = 73;
|
||||
else {
|
||||
fprintf(stderr, "unsupported model: %s\n", &argv[1][5]);
|
||||
return 2;
|
||||
|
|
Loading…
Reference in New Issue