1
0
mirror of git://projects.qi-hardware.com/xburst-tools.git synced 2024-11-01 08:29:41 +02:00

remove useless projects: qiboot, nandboot, nandprog

we can create the project for them in future

Signed-off-by: Xiangfu Liu <xiangfu@sharism.cc>
This commit is contained in:
Xiangfu Liu 2010-07-22 13:26:14 +08:00
parent 19bc94325c
commit 433a3eebdb
120 changed files with 0 additions and 42213 deletions

View File

@ -1,22 +0,0 @@
This is the source code of the NAND Secondary Program Loader (SPL).
The NAND SPL itself will be first loaded by the IPL (Initial Program Loader)
inside the CPU, then it loads the kernel image from NAND into RAM and
starts the kernel from RAM.
To build the NAND SPL, follow next steps:
$ cd src/
$ make
And you will get a binary file called n-boot.bin.
Before building the SPL, you should open config.h and check the
configuration is correct for your system.
For JZ4730, the n-boot.bin must be less than 4KB.
For JZ4740, the n-boot.bin must be less than 8KB.
The platform definitions were declared in include/jz47xx_board.h.
Please check and modify it according to your system.

View File

@ -1,14 +0,0 @@
/*
* config.h
*
*/
#ifndef __CONFIG_H__
#define __CONFIG_H__
/*
* Select one of the following definitions
*/
//#define CONFIG_JZ4730 1
#define CONFIG_JZ4740 1
#endif /* __CONFIG_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -1,52 +0,0 @@
/*
* jz4730_board.h
*
* JZ4730 board definitions.
*
* Copyright (c) 2005-2008 Ingenic Semiconductor Inc.
*
*/
#ifndef __JZ4730_BOARD_H__
#define __JZ4730_BOARD_H__
/*-------------------------------------------------------------------
* Frequency of the external OSC in Hz.
*/
#define CFG_EXTAL 12000000
/*-------------------------------------------------------------------
* CPU speed.
*/
#define CFG_CPU_SPEED 336000000
/*-------------------------------------------------------------------
* Serial console.
*/
#define CFG_UART_BASE UART3_BASE
#define CONFIG_BAUDRATE 9600
/*-------------------------------------------------------------------
* SDRAM info.
*/
// SDRAM paramters
#define CFG_SDRAM_BW16 0 /* Data bus width: 0-32bit, 1-16bit */
#define CFG_SDRAM_BANK4 1 /* Banks each chip: 0-2bank, 1-4bank */
#define CFG_SDRAM_ROW 13 /* Row address: 11 to 13 */
#define CFG_SDRAM_COL 9 /* Column address: 8 to 12 */
#define CFG_SDRAM_CASL 2 /* CAS latency: 2 or 3 */
// SDRAM Timings, unit: ns
#define CFG_SDRAM_TRAS 45 /* RAS# Active Time */
#define CFG_SDRAM_RCD 20 /* RAS# to CAS# Delay */
#define CFG_SDRAM_TPC 20 /* RAS# Precharge Time */
#define CFG_SDRAM_TRWL 7 /* Write Latency Time */
#define CFG_SDRAM_TREF 7812 /* Refresh period: 8192 refresh cycles/64ms */
/*-------------------------------------------------------------------
* Linux kernel command line.
*/
#define CFG_CMDLINE "mem=32M console=ttyS0,57600n8 ip=off rootfstype=yaffs2 root=/dev/mtdblock2 rw init=/etc/inittab"
#endif /* __JZ4730_BOARD_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -1,57 +0,0 @@
/*
* jz4740_board.h
*
* JZ4740 board definitions.
*
* Copyright (c) 2005-2008 Ingenic Semiconductor Inc.
*
*/
#ifndef __JZ4740_BOARD_H__
#define __JZ4740_BOARD_H__
/*-------------------------------------------------------------------
* NAND Boot config code
*/
#define JZ4740_NANDBOOT_CFG JZ4740_NANDBOOT_B8R3 /* NAND Boot config code */
/*-------------------------------------------------------------------
* Frequency of the external OSC in Hz.
*/
#define CFG_EXTAL 12000000
/*-------------------------------------------------------------------
* CPU speed.
*/
#define CFG_CPU_SPEED 336000000
/*-------------------------------------------------------------------
* Serial console.
*/
#define CFG_UART_BASE UART0_BASE
#define CONFIG_BAUDRATE 57600
/*-------------------------------------------------------------------
* SDRAM info.
*/
// SDRAM paramters
#define CFG_SDRAM_BW16 0 /* Data bus width: 0-32bit, 1-16bit */
#define CFG_SDRAM_BANK4 1 /* Banks each chip: 0-2bank, 1-4bank */
#define CFG_SDRAM_ROW 13 /* Row address: 11 to 13 */
#define CFG_SDRAM_COL 9 /* Column address: 8 to 12 */
#define CFG_SDRAM_CASL 2 /* CAS latency: 2 or 3 */
// SDRAM Timings, unit: ns
#define CFG_SDRAM_TRAS 45 /* RAS# Active Time */
#define CFG_SDRAM_RCD 20 /* RAS# to CAS# Delay */
#define CFG_SDRAM_TPC 20 /* RAS# Precharge Time */
#define CFG_SDRAM_TRWL 7 /* Write Latency Time */
#define CFG_SDRAM_TREF 7812 /* Refresh period: 8192 refresh cycles/64ms */
/*-------------------------------------------------------------------
* Linux kernel command line.
*/
#define CFG_CMDLINE "mem=32M console=ttyS0,57600n8 ip=off rootfstype=yaffs2 root=/dev/mtdblock2 rw init=/etc/inittab"
#endif /* __JZ4740_BOARD_H__ */

View File

@ -1,70 +0,0 @@
/*
* nand.h
*
* Standard NAND Flash definitions.
*/
#ifndef __NAND_H__
#define __NAND_H__
/*
* Standard NAND flash commands
*/
#define NAND_CMD_READ0 0
#define NAND_CMD_READ1 1
#define NAND_CMD_RNDOUT 5
#define NAND_CMD_PAGEPROG 0x10
#define NAND_CMD_READOOB 0x50
#define NAND_CMD_ERASE1 0x60
#define NAND_CMD_STATUS 0x70
#define NAND_CMD_STATUS_MULTI 0x71
#define NAND_CMD_SEQIN 0x80
#define NAND_CMD_RNDIN 0x85
#define NAND_CMD_READID 0x90
#define NAND_CMD_ERASE2 0xd0
#define NAND_CMD_RESET 0xff
/* Extended commands for large page devices */
#define NAND_CMD_READSTART 0x30
#define NAND_CMD_RNDOUTSTART 0xE0
#define NAND_CMD_CACHEDPROG 0x15
/* Status bits */
#define NAND_STATUS_FAIL 0x01
#define NAND_STATUS_FAIL_N1 0x02
#define NAND_STATUS_TRUE_READY 0x20
#define NAND_STATUS_READY 0x40
#define NAND_STATUS_WP 0x80
/*
* NAND Flash Manufacturer ID Codes
*/
#define NAND_MFR_TOSHIBA 0x98
#define NAND_MFR_SAMSUNG 0xec
#define NAND_MFR_FUJITSU 0x04
#define NAND_MFR_NATIONAL 0x8f
#define NAND_MFR_RENESAS 0x07
#define NAND_MFR_STMICRO 0x20
#define NAND_MFR_HYNIX 0xad
#define NAND_MFR_MICRON 0x2c
/*
* NAND parameter struct
*/
struct nand_param {
unsigned int bus_width; /* data bus width: 8-bit/16-bit */
unsigned int row_cycle; /* row address cycles: 2/3 */
unsigned int page_size; /* page size in bytes: 512/2048 */
unsigned int oob_size; /* oob size in bytes: 16/64 */
unsigned int page_per_block; /* pages per block: 32/64/128 */
unsigned int bad_block_pos; /* bad block pos in oob: 0/5 */
};
/*
* NAND routines
*/
extern void nand_enable(void);
extern void nand_disable(void);
extern int block_is_bad(struct nand_param *nandp, int block);
extern int nand_read_page(struct nand_param *nandp, int block, int page, unsigned char *dst);
#endif /* __NAND_H__ */

View File

@ -1,8 +0,0 @@
#ifndef __TYPES_H__
#define __TYPES_H__
#define u32 unsigned int
#define u16 unsigned short
#define u8 unsigned char
#endif /* __TYPES_H__ */

View File

@ -1,36 +0,0 @@
#
# Makefile of the n-boot
#
# Copyright (c) 2005-2008 Ingenic Semiconductor Inc.
#
# 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.
#
OBJS := head.o nand_boot.o cpu.o jz_serial.o \
jz4730.o jz4730_nand.o jz4730_board.o \
jz4740.o jz4740_nand.o jz4740_board.o
CROSS := mipsel-openwrt-linux-
CFLAGS := -O2 -G 0 -mno-abicalls -fno-pic -mips32 -I../include -I../
AFLAGS = -D__ASSEMBLY__ $(CFLAGS)
LDFLAGS := -T ld.script -nostdlib -EL
.c.o:
$(CROSS)gcc $(CFLAGS) -c $< -o $@
.S.o:
$(CROSS)gcc $(AFLAGS) -c $< -o $@
n-boot.bin: n-boot
$(CROSS)objdump -D n-boot $< > n-boot.dump
$(CROSS)objcopy -O binary $< $@
n-boot: $(OBJS)
$(CROSS)ld $(LDFLAGS) $^ -o $@
clean:
rm -fr *.o n-boot n-boot.bin n-boot.dump

View File

@ -1,106 +0,0 @@
/*
* cpu.c
*
* CPU common routines
*
* Copyright (c) 2005-2008 Ingenic Semiconductor Inc.
* Author: Peter Wei <jlwei@ingenic.cn>
*
* 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.
*/
#include <types.h>
/*
* Cache Operations
*/
#define Index_Invalidate_I 0x00
#define Index_Writeback_Inv_D 0x01
#define Index_Invalidate_SI 0x02
#define Index_Writeback_Inv_SD 0x03
#define Index_Load_Tag_I 0x04
#define Index_Load_Tag_D 0x05
#define Index_Load_Tag_SI 0x06
#define Index_Load_Tag_SD 0x07
#define Index_Store_Tag_I 0x08
#define Index_Store_Tag_D 0x09
#define Index_Store_Tag_SI 0x0A
#define Index_Store_Tag_SD 0x0B
#define Create_Dirty_Excl_D 0x0d
#define Create_Dirty_Excl_SD 0x0f
#define Hit_Invalidate_I 0x10
#define Hit_Invalidate_D 0x11
#define Hit_Invalidate_SI 0x12
#define Hit_Invalidate_SD 0x13
#define Fill 0x14
#define Hit_Writeback_Inv_D 0x15
/* 0x16 is unused */
#define Hit_Writeback_Inv_SD 0x17
#define Hit_Writeback_I 0x18
#define Hit_Writeback_D 0x19
/* 0x1a is unused */
#define Hit_Writeback_SD 0x1b
/* 0x1c is unused */
/* 0x1e is unused */
#define Hit_Set_Virtual_SI 0x1e
#define Hit_Set_Virtual_SD 0x1f
#define CFG_DCACHE_SIZE 16384
#define CFG_ICACHE_SIZE 16384
#define CFG_CACHELINE_SIZE 32
#define K0BASE 0x80000000
void flush_icache_all(void)
{
unsigned int addr, t = 0;
asm volatile ("mtc0 $0, $28"); /* Clear Taglo */
asm volatile ("mtc0 $0, $29"); /* Clear TagHi */
for (addr = K0BASE; addr < K0BASE + CFG_ICACHE_SIZE;
addr += CFG_CACHELINE_SIZE) {
asm volatile (
".set mips3\n\t"
" cache %0, 0(%1)\n\t"
".set mips2\n\t"
:
: "I" (Index_Store_Tag_I), "r"(addr));
}
/* invalicate btb */
asm volatile (
".set mips32\n\t"
"mfc0 %0, $16, 7\n\t"
"nop\n\t"
"ori %0,2\n\t"
"mtc0 %0, $16, 7\n\t"
".set mips2\n\t"
:
: "r" (t));
}
void flush_dcache_all(void)
{
unsigned int addr;
for (addr = K0BASE; addr < K0BASE + CFG_DCACHE_SIZE;
addr += CFG_CACHELINE_SIZE) {
asm volatile (
".set mips3\n\t"
" cache %0, 0(%1)\n\t"
".set mips2\n\t"
:
: "I" (Index_Writeback_Inv_D), "r"(addr));
}
asm volatile ("sync");
}
void flush_cache_all(void)
{
flush_dcache_all();
flush_icache_all();
}

View File

@ -1,50 +0,0 @@
/*
* head.S
*
* Entry of n-boot
*
* Copyright (c) 2005-2008 Ingenic Semiconductor Inc.
* Author: <jlwei@ingenic.cn>
*
* 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.
*/
#include <config.h>
#ifdef CONFIG_JZ4740
#include <jz4740.h>
#include <jz4740_board.h>
#endif
.text
.set noreorder
.global startup
startup:
#ifdef CONFIG_JZ4740
.word JZ4740_NANDBOOT_CFG /* fetched by CPU during NAND Boot */
#endif
/*
* Disable all interrupts
*/
la $8, 0xB0001004 /* INTC_IMR */
li $9, 0xffffffff
sw $9, 0($8)
/*
* CU0=UM=EXL=IE=0, BEV=ERL=1, IP2~7=1
*/
li $26, 0x0040FC04
mtc0 $26, $12 /* CP0_STATUS */
/* IV=1, use the specical interrupt vector (0x200) */
li $26, 0x00800000
mtc0 $26, $13 /* CP0_CAUSE */
/* Setup stack pointer */
la $29, 0x80004000
/* Jump to the nand boot routine */
j nand_boot
nop
.set reorder

View File

@ -1,161 +0,0 @@
/*
* jz4730.c
*
* JZ4730 common routines
*
* Copyright (c) 2005-2007 Ingenic Semiconductor Inc.
* Author: <jlwei@ingenic.cn>
*
* 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.
*/
#include <config.h>
#ifdef CONFIG_JZ4730
#include <jz4730.h>
#include <jz4730_board.h>
void pll_init(void)
{
unsigned int nf, plcr1;
nf = CFG_CPU_SPEED * 2 / CFG_EXTAL;
plcr1 = ((nf-2) << CPM_PLCR1_PLL1FD_BIT) |
(0 << CPM_PLCR1_PLL1RD_BIT) | /* RD=0, NR=2, 1.8432 = 3.6864/2 */
(0 << CPM_PLCR1_PLL1OD_BIT) | /* OD=0, NO=1 */
(0x20 << CPM_PLCR1_PLL1ST_BIT) | /* PLL stable time */
CPM_PLCR1_PLL1EN; /* enable PLL */
/* Clock divisors.
*
* CFCR values: when CPM_CFCR_UCS(bit 28) is set, select external USB clock.
*
* 0x00411110 -> 1:2:2:2:2
* 0x00422220 -> 1:3:3:3:3
* 0x00433330 -> 1:4:4:4:4
* 0x00444440 -> 1:6:6:6:6
* 0x00455550 -> 1:8:8:8:8
* 0x00466660 -> 1:12:12:12:12
*/
REG_CPM_CFCR = 0x00422220 | (((CFG_CPU_SPEED/48000000) - 1) << 25);
/* PLL out frequency */
REG_CPM_PLCR1 = plcr1;
}
#define MEM_CLK (CFG_CPU_SPEED / 3)
/*
* Init SDRAM memory.
*/
void sdram_init(void)
{
register unsigned int dmcr0, dmcr, sdmode, tmp, ns;
unsigned int cas_latency_sdmr[2] = {
EMC_SDMR_CAS_2,
EMC_SDMR_CAS_3,
};
unsigned int cas_latency_dmcr[2] = {
1 << EMC_DMCR_TCL_BIT, /* CAS latency is 2 */
2 << EMC_DMCR_TCL_BIT /* CAS latency is 3 */
};
REG_EMC_BCR = 0; /* Disable bus release */
REG_EMC_RTCSR = 0; /* Disable clock for counting */
/* Fault DMCR value for mode register setting*/
#define SDRAM_ROW0 11
#define SDRAM_COL0 8
#define SDRAM_BANK40 0
dmcr0 = ((SDRAM_ROW0-11)<<EMC_DMCR_RA_BIT) |
((SDRAM_COL0-8)<<EMC_DMCR_CA_BIT) |
(SDRAM_BANK40<<EMC_DMCR_BA_BIT) |
(CFG_SDRAM_BW16<<EMC_DMCR_BW_BIT) |
EMC_DMCR_EPIN |
cas_latency_dmcr[((CFG_SDRAM_CASL == 3) ? 1 : 0)];
/* Basic DMCR value */
dmcr = ((CFG_SDRAM_ROW-11)<<EMC_DMCR_RA_BIT) |
((CFG_SDRAM_COL-8)<<EMC_DMCR_CA_BIT) |
(CFG_SDRAM_BANK4<<EMC_DMCR_BA_BIT) |
(CFG_SDRAM_BW16<<EMC_DMCR_BW_BIT) |
EMC_DMCR_EPIN |
cas_latency_dmcr[((CFG_SDRAM_CASL == 3) ? 1 : 0)];
/* SDRAM timing */
ns = 1000000000 / MEM_CLK;
tmp = CFG_SDRAM_TRAS/ns;
if (tmp < 4)
tmp = 4;
if (tmp > 11)
tmp = 11;
dmcr |= ((tmp-4) << EMC_DMCR_TRAS_BIT);
tmp = CFG_SDRAM_RCD/ns;
if (tmp > 3)
tmp = 3;
dmcr |= (tmp << EMC_DMCR_RCD_BIT);
tmp = CFG_SDRAM_TPC/ns;
if (tmp > 7)
tmp = 7;
dmcr |= (tmp << EMC_DMCR_TPC_BIT);
tmp = CFG_SDRAM_TRWL/ns;
if (tmp > 3)
tmp = 3;
dmcr |= (tmp << EMC_DMCR_TRWL_BIT);
tmp = (CFG_SDRAM_TRAS + CFG_SDRAM_TPC)/ns;
if (tmp > 14)
tmp = 14;
dmcr |= (((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT);
/* SDRAM mode value */
sdmode = EMC_SDMR_BT_SEQ |
EMC_SDMR_OM_NORMAL |
EMC_SDMR_BL_4 |
cas_latency_sdmr[((CFG_SDRAM_CASL == 3) ? 1 : 0)];
if (CFG_SDRAM_BW16)
sdmode <<= 1;
else
sdmode <<= 2;
/* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */
REG_EMC_DMCR = dmcr;
REG8(EMC_SDMR0|sdmode) = 0;
REG8(EMC_SDMR1|sdmode) = 0;
/* Wait for precharge, > 200us */
tmp = (CFG_CPU_SPEED / 1000000) * 1000;
while (tmp--);
/* Stage 2. Enable auto-refresh */
REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH;
tmp = CFG_SDRAM_TREF/ns;
tmp = tmp/64 + 1;
if (tmp > 0xff) tmp = 0xff;
REG_EMC_RTCOR = tmp;
REG_EMC_RTCNT = 0;
REG_EMC_RTCSR = EMC_RTCSR_CKS_64; /* Divisor is 64, CKO/64 */
/* Wait for number of auto-refresh cycles */
tmp = (CFG_CPU_SPEED / 1000000) * 1000;
while (tmp--);
/* Stage 3. Mode Register Set */
REG_EMC_DMCR = dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
REG8(EMC_SDMR0|sdmode) = 0;
REG8(EMC_SDMR1|sdmode) = 0;
/* Set back to the ture basic DMCR value */
REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
/* everything is ok now */
}
#endif /* CONFIG_JZ4730 */

View File

@ -1,29 +0,0 @@
/*
* board-pmp.c
*
* JZ4730-based PMP board routines.
*
* Copyright (c) 2005-2008 Ingenic Semiconductor Inc.
* Author: <jlwei@ingenic.cn>
*
* 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.
*/
#include <config.h>
#include <jz4730.h>
#include <jz4730_board.h>
#ifdef CONFIG_JZ4730
void gpio_init(void)
{
__harb_usb0_uhc();
__gpio_as_emc();
__gpio_as_uart0();
__gpio_as_uart3();
}
#endif /* CONFIG_JZ4730 */

View File

@ -1,254 +0,0 @@
/*
* jz4730_nand.c
*
* NAND read routine for JZ4730
*
* Copyright (c) 2005-2008 Ingenic Semiconductor Inc.
*
* 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.
*/
#include <config.h>
#ifdef CONFIG_JZ4730
#include <nand.h>
#include <jz4730.h>
/* NAND command/address/data port */
#define NAND_DATAPORT 0xB4000000 /* read-write area */
#define NAND_CMDPORT 0xB4040000 /* write only area */
#define NAND_ADDRPORT 0xB4080000 /* write only area */
#define ECC_BLOCK 256 /* 3-bytes HW ECC per 256-bytes data */
#define ECC_POS 4 /* ECC offset to spare area */
#define __nand_enable() (REG_EMC_NFCSR |= EMC_NFCSR_NFE | EMC_NFCSR_FCE)
#define __nand_disable() (REG_EMC_NFCSR &= ~(EMC_NFCSR_NFE | EMC_NFCSR_FCE))
#define __nand_ecc_enable() (REG_EMC_NFCSR |= EMC_NFCSR_ECCE | EMC_NFCSR_ERST)
#define __nand_ecc_disable() (REG_EMC_NFCSR &= ~EMC_NFCSR_ECCE)
#define __nand_ready() (REG_EMC_NFCSR & EMC_NFCSR_RB)
#define __nand_sync() while (!__nand_ready())
#define __nand_ecc() (REG_EMC_NFECC & 0x00ffffff)
#define __nand_cmd(n) (REG8(NAND_CMDPORT) = (n))
#define __nand_addr(n) (REG8(NAND_ADDRPORT) = (n))
#define __nand_data8() REG8(NAND_DATAPORT)
#define __nand_data16() REG16(NAND_DATAPORT)
/*--------------------------------------------------------------*/
static inline void nand_wait_ready(void)
{
__nand_sync();
}
static inline void nand_read_buf16(void *buf, int count)
{
int i;
u16 *p = (u16 *)buf;
for (i = 0; i < count; i += 2)
*p++ = __nand_data16();
}
static inline void nand_read_buf8(void *buf, int count)
{
int i;
u8 *p = (u8 *)buf;
for (i = 0; i < count; i++)
*p++ = __nand_data8();
}
static inline void nand_read_buf(void *buf, int count, int bw)
{
if (bw == 8)
nand_read_buf8(buf, count);
else
nand_read_buf16(buf, count);
}
/*
* Read oob
*/
static int nand_read_oob(struct nand_param *nandp, int page_addr, u8 *buf, int size)
{
int page_size, row_cycle, bus_width;
int col_addr;
page_size = nandp->page_size;
row_cycle = nandp->row_cycle;
bus_width = nandp->bus_width;
if (page_size == 2048)
col_addr = 2048;
else
col_addr = 0;
if (page_size == 2048)
/* Send READ0 command */
__nand_cmd(NAND_CMD_READ0);
else
/* Send READOOB command */
__nand_cmd(NAND_CMD_READOOB);
/* Send column address */
__nand_addr(col_addr & 0xff);
if (page_size == 2048)
__nand_addr((col_addr >> 8) & 0xff);
/* Send page address */
__nand_addr(page_addr & 0xff);
__nand_addr((page_addr >> 8) & 0xff);
if (row_cycle == 3)
__nand_addr((page_addr >> 16) & 0xff);
/* Send READSTART command for 2048 ps NAND */
if (page_size == 2048)
__nand_cmd(NAND_CMD_READSTART);
/* Wait for device ready */
nand_wait_ready();
/* Read oob data */
nand_read_buf(buf, size, bus_width);
return 0;
}
/*
* nand_read_page()
*
* Input:
*
* nandp - pointer to nand info
* block - block number: 0, 1, 2, ...
* page - page number within a block: 0, 1, 2, ...
* dst - pointer to target buffer
*/
int nand_read_page(struct nand_param *nandp, int block, int page, u8 *dst)
{
int page_size, oob_size, page_per_block;
int row_cycle, bus_width, ecc_count;
int page_addr, i, j;
u8 *databuf;
u8 oob_buf[64];
u32 calc_ecc[8];
page_size = nandp->page_size;
oob_size = nandp->oob_size;
page_per_block = nandp->page_per_block;
row_cycle = nandp->row_cycle;
bus_width = nandp->bus_width;
page_addr = page + block * page_per_block;
/*
* Read page data
*/
/* Send READ0 command */
__nand_cmd(NAND_CMD_READ0);
/* Send column address */
__nand_addr(0);
if (page_size == 2048)
__nand_addr(0);
/* Send page address */
__nand_addr(page_addr & 0xff);
__nand_addr((page_addr >> 8) & 0xff);
if (row_cycle == 3)
__nand_addr((page_addr >> 16) & 0xff);
/* Send READSTART command for 2048 ps NAND */
if (page_size == 2048)
__nand_cmd(NAND_CMD_READSTART);
/* Wait for device ready */
nand_wait_ready();
/* Read page data */
databuf = dst;
ecc_count = page_size / ECC_BLOCK;
for (i = 0; i < ecc_count; i++) {
/* Enable HW ECC */
__nand_ecc_enable();
/* Read data */
nand_read_buf((void *)databuf, ECC_BLOCK, bus_width);
/* Disable HW ECC */
__nand_ecc_disable();
/* Record the ECC */
calc_ecc[i] = __nand_ecc();
databuf += ECC_BLOCK;
}
/*
* Read oob data
*/
nand_read_oob(nandp, page_addr, oob_buf, oob_size);
/*
* ECC correction
*
* Note: the ECC correction algorithm should be conformed to
* the encoding algorithm. It depends on what encoding algorithm
* is used? SW ECC? HW ECC?
*/
return 0;
}
/*
* Check bad block
*
* Note: the bad block flag may be store in either the first or the last
* page of the block.
*/
int block_is_bad(struct nand_param *nandp, int block)
{
int page_addr;
u8 oob_buf[64];
page_addr = block * nandp->page_per_block;
nand_read_oob(nandp, page_addr, oob_buf, nandp->oob_size);
if (oob_buf[nandp->bad_block_pos] != 0xff)
return 1;
page_addr = (block + 1) * nandp->page_per_block - 1;
nand_read_oob(nandp, page_addr, oob_buf, nandp->oob_size);
if (oob_buf[nandp->bad_block_pos] != 0xff)
return 1;
return 0;
}
/*
* Enable NAND controller
*/
void nand_enable(void)
{
__nand_enable();
REG_EMC_SMCR3 = 0x04444400;
}
/*
* Disable NAND controller
*/
void nand_disable(void)
{
__nand_disable();
}
#endif /* CONFIG_JZ4730 */

View File

@ -1,165 +0,0 @@
/*
* jz4740.c
*
* JZ4740 common routines
*
* Copyright (c) 2005-2008 Ingenic Semiconductor Inc.
* Author: Peter Wei <jlwei@ingenic.cn>
*
* 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.
*/
#include <config.h>
#ifdef CONFIG_JZ4740
#include <jz4740.h>
#include <jz4740_board.h>
/* PLL output clock = EXTAL * NF / (NR * NO)
*
* NF = FD + 2, NR = RD + 2
* NO = 1 (if OD = 0), NO = 2 (if OD = 1 or 2), NO = 4 (if OD = 3)
*/
void pll_init(void)
{
register unsigned int cfcr, plcr1;
int n2FR[33] = {
0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0,
7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
9
};
int div[5] = {1, 3, 3, 3, 3}; /* divisors of I:S:P:M:L */
int nf, pllout2;
cfcr = CPM_CPCCR_CLKOEN |
CPM_CPCCR_PCS |
(n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) |
(n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) |
(n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) |
(n2FR[div[3]] << CPM_CPCCR_MDIV_BIT) |
(n2FR[div[4]] << CPM_CPCCR_LDIV_BIT);
pllout2 = (cfcr & CPM_CPCCR_PCS) ? CFG_CPU_SPEED : (CFG_CPU_SPEED / 2);
/* Init USB Host clock, pllout2 must be n*48MHz */
REG_CPM_UHCCDR = pllout2 / 48000000 - 1;
nf = CFG_CPU_SPEED * 2 / CFG_EXTAL;
plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */
(0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */
(0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */
(0x20 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */
CPM_CPPCR_PLLEN; /* enable PLL */
/* init PLL */
REG_CPM_CPCCR = cfcr;
REG_CPM_CPPCR = plcr1;
}
/*
* Init SDRAM memory.
*/
void sdram_init(void)
{
register unsigned int dmcr0, dmcr, sdmode, tmp, cpu_clk, mem_clk, ns;
unsigned int cas_latency_sdmr[2] = {
EMC_SDMR_CAS_2,
EMC_SDMR_CAS_3,
};
unsigned int cas_latency_dmcr[2] = {
1 << EMC_DMCR_TCL_BIT, /* CAS latency is 2 */
2 << EMC_DMCR_TCL_BIT /* CAS latency is 3 */
};
int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
cpu_clk = CFG_CPU_SPEED;
mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()];
REG_EMC_BCR = 0; /* Disable bus release */
REG_EMC_RTCSR = 0; /* Disable clock for counting */
/* Fault DMCR value for mode register setting*/
#define SDRAM_ROW0 11
#define SDRAM_COL0 8
#define SDRAM_BANK40 0
dmcr0 = ((SDRAM_ROW0-11)<<EMC_DMCR_RA_BIT) |
((SDRAM_COL0-8)<<EMC_DMCR_CA_BIT) |
(SDRAM_BANK40<<EMC_DMCR_BA_BIT) |
(CFG_SDRAM_BW16<<EMC_DMCR_BW_BIT) |
EMC_DMCR_EPIN |
cas_latency_dmcr[((CFG_SDRAM_CASL == 3) ? 1 : 0)];
/* Basic DMCR value */
dmcr = ((CFG_SDRAM_ROW-11)<<EMC_DMCR_RA_BIT) |
((CFG_SDRAM_COL-8)<<EMC_DMCR_CA_BIT) |
(CFG_SDRAM_BANK4<<EMC_DMCR_BA_BIT) |
(CFG_SDRAM_BW16<<EMC_DMCR_BW_BIT) |
EMC_DMCR_EPIN |
cas_latency_dmcr[((CFG_SDRAM_CASL == 3) ? 1 : 0)];
/* SDRAM timimg */
ns = 1000000000 / mem_clk;
tmp = CFG_SDRAM_TRAS/ns;
if (tmp < 4) tmp = 4;
if (tmp > 11) tmp = 11;
dmcr |= ((tmp-4) << EMC_DMCR_TRAS_BIT);
tmp = CFG_SDRAM_RCD/ns;
if (tmp > 3) tmp = 3;
dmcr |= (tmp << EMC_DMCR_RCD_BIT);
tmp = CFG_SDRAM_TPC/ns;
if (tmp > 7) tmp = 7;
dmcr |= (tmp << EMC_DMCR_TPC_BIT);
tmp = CFG_SDRAM_TRWL/ns;
if (tmp > 3) tmp = 3;
dmcr |= (tmp << EMC_DMCR_TRWL_BIT);
tmp = (CFG_SDRAM_TRAS + CFG_SDRAM_TPC)/ns;
if (tmp > 14) tmp = 14;
dmcr |= (((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT);
/* SDRAM mode value */
sdmode = EMC_SDMR_BT_SEQ |
EMC_SDMR_OM_NORMAL |
EMC_SDMR_BL_4 |
cas_latency_sdmr[((CFG_SDRAM_CASL == 3) ? 1 : 0)];
/* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */
REG_EMC_DMCR = dmcr;
REG8(EMC_SDMR0|sdmode) = 0;
/* Wait for precharge, > 200us */
tmp = (cpu_clk / 1000000) * 1000;
while (tmp--);
/* Stage 2. Enable auto-refresh */
REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH;
tmp = CFG_SDRAM_TREF/ns;
tmp = tmp/64 + 1;
if (tmp > 0xff) tmp = 0xff;
REG_EMC_RTCOR = tmp;
REG_EMC_RTCNT = 0;
REG_EMC_RTCSR = EMC_RTCSR_CKS_64; /* Divisor is 64, CKO/64 */
/* Wait for number of auto-refresh cycles */
tmp = (cpu_clk / 1000000) * 1000;
while (tmp--);
/* Stage 3. Mode Register Set */
REG_EMC_DMCR = dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
REG8(EMC_SDMR0|sdmode) = 0;
/* Set back to basic DMCR value */
REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
/* everything is ok now */
}
#endif /* CONFIG_JZ4740 */

View File

@ -1,28 +0,0 @@
/*
* board-pmp.c
*
* JZ4730-based PMP board routines.
*
* Copyright (c) 2005-2008 Ingenic Semiconductor Inc.
* Author: <jlwei@ingenic.cn>
*
* 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.
*/
#include <config.h>
#ifdef CONFIG_JZ4740
#include <jz4740.h>
#include <jz4740_board.h>
void gpio_init(void)
{
__gpio_as_uart0();
__gpio_as_sdram_32bit();
}
#endif /* CONFIG_JZ4740 */

View File

@ -1,329 +0,0 @@
/*
* jz4740_nand.c
*
* NAND read routine for JZ4740
*
* Copyright (c) 2005-2008 Ingenic Semiconductor Inc.
*
* 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.
*/
#include <config.h>
#ifdef CONFIG_JZ4740
#include <nand.h>
#include <jz4740.h>
#define NAND_DATAPORT 0xb8000000
#define NAND_ADDRPORT 0xb8010000
#define NAND_COMMPORT 0xb8008000
#define ECC_BLOCK 512
#define ECC_POS 6
#define PAR_SIZE 9
#define __nand_cmd(n) (REG8(NAND_COMMPORT) = (n))
#define __nand_addr(n) (REG8(NAND_ADDRPORT) = (n))
#define __nand_data8() REG8(NAND_DATAPORT)
#define __nand_data16() REG16(NAND_DATAPORT)
#define __nand_enable() (REG_EMC_NFCSR |= EMC_NFCSR_NFE1 | EMC_NFCSR_NFCE1)
#define __nand_disable() (REG_EMC_NFCSR &= ~(EMC_NFCSR_NFCE1))
#define __nand_ecc_rs_encoding() \
(REG_EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_ERST | EMC_NFECR_RS | EMC_NFECR_RS_ENCODING)
#define __nand_ecc_rs_decoding() \
(REG_EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_ERST | EMC_NFECR_RS | EMC_NFECR_RS_DECODING)
#define __nand_ecc_disable() (REG_EMC_NFECR &= ~EMC_NFECR_ECCE)
#define __nand_ecc_encode_sync() while (!(REG_EMC_NFINTS & EMC_NFINTS_ENCF))
#define __nand_ecc_decode_sync() while (!(REG_EMC_NFINTS & EMC_NFINTS_DECF))
/*--------------------------------------------------------------*/
static inline void nand_wait_ready(void)
{
unsigned int timeout = 1000;
while ((REG_GPIO_PXPIN(2) & 0x40000000) && timeout--);
while (!(REG_GPIO_PXPIN(2) & 0x40000000));
}
static inline void nand_read_buf16(void *buf, int count)
{
int i;
u16 *p = (u16 *)buf;
for (i = 0; i < count; i += 2)
*p++ = __nand_data16();
}
static inline void nand_read_buf8(void *buf, int count)
{
int i;
u8 *p = (u8 *)buf;
for (i = 0; i < count; i++)
*p++ = __nand_data8();
}
static inline void nand_read_buf(void *buf, int count, int bw)
{
if (bw == 8)
nand_read_buf8(buf, count);
else
nand_read_buf16(buf, count);
}
/*
* Correct 1~9-bit errors in 512-bytes data
*/
static void rs_correct(unsigned char *dat, int idx, int mask)
{
int i, j;
unsigned short d, d1, dm;
i = (idx * 9) >> 3;
j = (idx * 9) & 0x7;
i = (j == 0) ? (i - 1) : i;
j = (j == 0) ? 7 : (j - 1);
if (i > 512) return;
if (i == 512)
d = dat[i - 1];
else
d = (dat[i] << 8) | dat[i - 1];
d1 = (d >> j) & 0x1ff;
d1 ^= mask;
dm = ~(0x1ff << j);
d = (d & dm) | (d1 << j);
dat[i - 1] = d & 0xff;
if (i < 512)
dat[i] = (d >> 8) & 0xff;
}
/*
* Read oob
*/
static int nand_read_oob(struct nand_param *nandp, int page_addr, u8 *buf, int size)
{
int page_size, row_cycle, bus_width;
int col_addr;
page_size = nandp->page_size;
row_cycle = nandp->row_cycle;
bus_width = nandp->bus_width;
if (page_size == 2048)
col_addr = 2048;
else
col_addr = 0;
if (page_size == 2048)
/* Send READ0 command */
__nand_cmd(NAND_CMD_READ0);
else
/* Send READOOB command */
__nand_cmd(NAND_CMD_READOOB);
/* Send column address */
__nand_addr(col_addr & 0xff);
if (page_size == 2048)
__nand_addr((col_addr >> 8) & 0xff);
/* Send page address */
__nand_addr(page_addr & 0xff);
__nand_addr((page_addr >> 8) & 0xff);
if (row_cycle == 3)
__nand_addr((page_addr >> 16) & 0xff);
/* Send READSTART command for 2048 ps NAND */
if (page_size == 2048)
__nand_cmd(NAND_CMD_READSTART);
/* Wait for device ready */
nand_wait_ready();
/* Read oob data */
nand_read_buf(buf, size, bus_width);
return 0;
}
/*
* nand_read_page()
*
* Input:
*
* nandp - pointer to nand info
* block - block number: 0, 1, 2, ...
* page - page number within a block: 0, 1, 2, ...
* dst - pointer to target buffer
*/
int nand_read_page(struct nand_param *nandp, int block, int page, u8 *dst)
{
int page_size, oob_size, page_per_block;
int row_cycle, bus_width, ecc_count;
int page_addr, i, j;
u8 *data_buf;
u8 oob_buf[64];
page_size = nandp->page_size;
oob_size = nandp->oob_size;
page_per_block = nandp->page_per_block;
row_cycle = nandp->row_cycle;
bus_width = nandp->bus_width;
page_addr = page + block * page_per_block;
/*
* Read oob data
*/
nand_read_oob(nandp, page_addr, oob_buf, oob_size);
/*
* Read page data
*/
/* Send READ0 command */
__nand_cmd(NAND_CMD_READ0);
/* Send column address */
__nand_addr(0);
if (page_size == 2048)
__nand_addr(0);
/* Send page address */
__nand_addr(page_addr & 0xff);
__nand_addr((page_addr >> 8) & 0xff);
if (row_cycle == 3)
__nand_addr((page_addr >> 16) & 0xff);
/* Send READSTART command for 2048 ps NAND */
if (page_size == 2048)
__nand_cmd(NAND_CMD_READSTART);
/* Wait for device ready */
nand_wait_ready();
/* Read page data */
data_buf = dst;
ecc_count = page_size / ECC_BLOCK;
for (i = 0; i < ecc_count; i++) {
volatile u8 *paraddr = (volatile u8 *)EMC_NFPAR0;
unsigned int stat;
/* Enable RS decoding */
REG_EMC_NFINTS = 0x0;
__nand_ecc_rs_decoding();
/* Read data */
nand_read_buf((void *)data_buf, ECC_BLOCK, bus_width);
/* Set PAR values */
for (j = 0; j < PAR_SIZE; j++) {
*paraddr++ = oob_buf[ECC_POS + i*PAR_SIZE + j];
}
/* Set PRDY */
REG_EMC_NFECR |= EMC_NFECR_PRDY;
/* Wait for completion */
__nand_ecc_decode_sync();
/* Disable decoding */
__nand_ecc_disable();
/* Check result of decoding */
stat = REG_EMC_NFINTS;
if (stat & EMC_NFINTS_ERR) {
/* Error occurred */
if (stat & EMC_NFINTS_UNCOR) {
/* Uncorrectable error occurred */
}
else {
unsigned int errcnt, index, mask;
errcnt = (stat & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT;
switch (errcnt) {
case 4:
index = (REG_EMC_NFERR3 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT;
mask = (REG_EMC_NFERR3 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT;
rs_correct(data_buf, index, mask);
case 3:
index = (REG_EMC_NFERR2 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT;
mask = (REG_EMC_NFERR2 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT;
rs_correct(data_buf, index, mask);
case 2:
index = (REG_EMC_NFERR1 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT;
mask = (REG_EMC_NFERR1 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT;
rs_correct(data_buf, index, mask);
case 1:
index = (REG_EMC_NFERR0 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT;
mask = (REG_EMC_NFERR0 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT;
rs_correct(data_buf, index, mask);
break;
default:
break;
}
}
}
data_buf += ECC_BLOCK;
}
return 0;
}
/*
* Check bad block
*
* Note: the bad block flag may be store in either the first or the last
* page of the block.
*/
int block_is_bad(struct nand_param *nandp, int block)
{
int page_addr;
u8 oob_buf[64];
page_addr = block * nandp->page_per_block;
nand_read_oob(nandp, page_addr, oob_buf, nandp->oob_size);
if (oob_buf[nandp->bad_block_pos] != 0xff)
return 1;
page_addr = (block + 1) * nandp->page_per_block - 1;
nand_read_oob(nandp, page_addr, oob_buf, nandp->oob_size);
if (oob_buf[nandp->bad_block_pos] != 0xff)
return 1;
return 0;
}
/*
* Enable NAND controller
*/
void nand_enable(void)
{
__nand_enable();
REG_EMC_SMCR1 = 0x04444400;
}
/*
* Disable NAND controller
*/
void nand_disable(void)
{
__nand_disable();
}
#endif /* CONFIG_JZ4740 */

View File

@ -1,119 +0,0 @@
/*
* Jz47xx UART support
*
* Options hardcoded to 8N1
*
* Copyright (c) 2005 - 2008, Ingenic Semiconductor Inc.
* Ingenic Semiconductor, <jlwei@ingenic.cn>
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <config.h>
#ifdef CONFIG_JZ4730
#include <jz4730.h>
#include <jz4730_board.h>
#endif
#ifdef CONFIG_JZ4740
#include <jz4740.h>
#include <jz4740_board.h>
#endif
#undef UART_BASE
#ifndef CFG_UART_BASE
#define UART_BASE UART0_BASE
#else
#define UART_BASE CFG_UART_BASE
#endif
/******************************************************************************
*
* serial_init - initialize a channel
*
* This routine initializes the number of data bits, parity
* and set the selected baud rate. Interrupts are disabled.
* Set the modem control signals if the option is selected.
*
* RETURNS: N/A
*/
static void serial_setbrg (void)
{
volatile u8 *uart_lcr = (volatile u8 *)(UART_BASE + OFF_LCR);
volatile u8 *uart_dlhr = (volatile u8 *)(UART_BASE + OFF_DLHR);
volatile u8 *uart_dllr = (volatile u8 *)(UART_BASE + OFF_DLLR);
u32 baud_div, tmp;
baud_div = CFG_EXTAL / 16 / CONFIG_BAUDRATE;
tmp = *uart_lcr;
tmp |= UART_LCR_DLAB;
*uart_lcr = tmp;
*uart_dlhr = (baud_div >> 8) & 0xff;
*uart_dllr = baud_div & 0xff;
tmp &= ~UART_LCR_DLAB;
*uart_lcr = tmp;
}
int serial_init (void)
{
volatile u8 *uart_fcr = (volatile u8 *)(UART_BASE + OFF_FCR);
volatile u8 *uart_lcr = (volatile u8 *)(UART_BASE + OFF_LCR);
volatile u8 *uart_ier = (volatile u8 *)(UART_BASE + OFF_IER);
volatile u8 *uart_sircr = (volatile u8 *)(UART_BASE + OFF_SIRCR);
/* Disable port interrupts while changing hardware */
*uart_ier = 0;
/* Disable UART unit function */
*uart_fcr = ~UART_FCR_UUE;
/* Set both receiver and transmitter in UART mode (not SIR) */
*uart_sircr = ~(SIRCR_RSIRE | SIRCR_TSIRE);
/* Set databits, stopbits and parity. (8-bit data, 1 stopbit, no parity) */
*uart_lcr = UART_LCR_WLEN_8 | UART_LCR_STOP_1;
/* Set baud rate */
serial_setbrg();
/* Enable UART unit, enable and clear FIFO */
*uart_fcr = UART_FCR_UUE | UART_FCR_FE | UART_FCR_TFLS | UART_FCR_RFLS;
return 0;
}
void serial_putc (const char c)
{
volatile u8 *uart_lsr = (volatile u8 *)(UART_BASE + OFF_LSR);
volatile u8 *uart_tdr = (volatile u8 *)(UART_BASE + OFF_TDR);
if (c == '\n') serial_putc ('\r');
/* Wait for fifo to shift out some bytes */
while ( !((*uart_lsr & (UART_LSR_TDRQ | UART_LSR_TEMT)) == 0x60) );
*uart_tdr = (u8)c;
}
void serial_puts (const char *s)
{
while (*s) {
serial_putc (*s++);
}
}

View File

@ -1,29 +0,0 @@
OUTPUT_ARCH(mips)
ENTRY(startup)
MEMORY
{
ram : ORIGIN = 0x80000000 , LENGTH = 0x100000
}
SECTIONS
{
. = ALIGN(4);
.text : { *(.text*) } > ram
. = ALIGN(4);
.rodata : { *(.rodata*) } > ram
. = ALIGN(4);
.sdata : { *(.sdata*) } > ram
. = ALIGN(4);
.data : { *(.data*) *(.scommon*) *(.reginfo*) } > ram
_gp = ALIGN(16);
.got : { *(.got*) } > ram
. = ALIGN(4);
.sbss : { *(.sbss*) } > ram
.bss : { *(.bss*) } > ram
. = ALIGN (4);
}

View File

@ -1,207 +0,0 @@
/*
* nand_boot.c
*
* NAND boot routine.
*
* Then nand boot loader can load the zImage type to execute.
* To get the zImage, build the kernel by 'make zImage'.
*
* Copyright (c) 2005-2008 Ingenic Semiconductor Inc.
* Author: <jlwei@ingenic.cn>
*
* 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.
*/
#include <config.h>
#include <nand.h>
#ifdef CONFIG_JZ4730
#include <jz4730.h>
#include <jz4730_board.h>
#endif
#ifdef CONFIG_JZ4740
#include <jz4740.h>
#include <jz4740_board.h>
#endif
/*
* NAND Flash parameters (must be conformed to the NAND being used)
*/
static struct nand_param nand_p = {
.bus_width = 8, /* data bus width: 8-bit/16-bit */
.row_cycle = 3, /* row address cycles: 2/3 */
.page_size = 2048, /* page size in bytes: 512/2048 */
.oob_size = 64, /* oob size in bytes: 16/64 */
.page_per_block = 128, /* pages per block: 32/64/128 */
.bad_block_pos = 0 /* bad block pos in oob: 0/5 */
};
#define SIZE_KB (1 * 1024)
#define SIZE_MB (1 * 1024 * 1024)
/*
* Kernel image
*/
#define CFG_KERNEL_OFFS (256 * SIZE_KB) /* NAND offset of kernel image being loaded, has to be aligned to a block address! */
#define CFG_KERNEL_SIZE (2 * SIZE_MB) /* Size of kernel image, has to be integer multiply of a block size! */
#define CFG_KERNEL_DST 0x80600000 /* Load kernel to this addr */
#define CFG_KERNEL_START 0x80600000 /* Start kernel from this addr */
/*
* Kernel parameters
*/
#define PARAM_BASE 0x80004000
/*
* Local variables
*/
static u32 *param_addr = 0;
static u8 *tmpbuf = 0;
static u8 cmdline[256] = CFG_CMDLINE;
extern void gpio_init(void);
extern int serial_init (void);
extern void pll_init(void);
extern void sdram_init(void);
/*
* Load kernel image from NAND into RAM
*/
static int nand_load(struct nand_param *nandp, int offs, int kernel_size, u8 *dst)
{
int page_size, page_per_block;
int block;
int block_size;
int blockcopy_count;
int page;
page_size = nandp->page_size;
page_per_block = nandp->page_per_block;
/*
* Enable NANDFlash controller
*/
nand_enable();
/*
* offs has to be aligned to a block address!
*/
block_size = page_size * page_per_block;
block = offs / block_size;
blockcopy_count = 0;
while (blockcopy_count < (kernel_size / block_size)) {
for (page = 0; page < page_per_block; page++) {
if (page == 0) {
/*
* New block
*/
if (block_is_bad(nandp, block)) {
block++;
/*
* Skip bad block
*/
continue;
}
}
nand_read_page(nandp, block, page, dst);
dst += page_size;
}
block++;
blockcopy_count++;
}
/*
* Disable NANDFlash controller
*/
nand_disable();
return 0;
}
/*
* NAND Boot routine
*/
void nand_boot(void)
{
unsigned int boot_sel, i;
void (*kernel)(int, char **, char *);
/*
* Init gpio, serial, pll and sdram
*/
gpio_init();
serial_init();
serial_puts("\n\nNAND Secondary Program Loader\n\n");
pll_init();
sdram_init();
#ifdef CONFIG_JZ4740
/*
* JZ4740 can detect some NAND parameters from the boot select
*/
boot_sel = REG_EMC_BCR >> 30;
if (boot_sel == 0x2)
nand_p.page_size = 512;
else
nand_p.page_size = 2048;
#endif
#ifdef CONFIG_JZ4730
/*
* JZ4730 can detect some NAND parameters from the boot select
*/
boot_sel = (REG_EMC_NFCSR & 0x70) >> 4;
nand_p.bus_width = (boot_sel & 0x1) ? 16 : 8;
nand_p.page_size = (boot_sel & 0x2) ? 2048 : 512;
nand_p.row_cycle = (boot_sel & 0x4) ? 3 : 2;
#endif
/*
* Load kernel image from NAND into RAM
*/
nand_load(&nand_p, CFG_KERNEL_OFFS, CFG_KERNEL_SIZE, (u8 *)CFG_KERNEL_DST);
serial_puts("Starting kernel ...\n\n");
/*
* Prepare kernel parameters and environment
*/
param_addr = (u32 *)PARAM_BASE;
param_addr[0] = 0; /* might be address of ascii-z string: "memsize" */
param_addr[1] = 0; /* might be address of ascii-z string: "0x01000000" */
param_addr[2] = 0;
param_addr[3] = 0;
param_addr[4] = 0;
param_addr[5] = PARAM_BASE + 32;
param_addr[6] = CFG_KERNEL_START;
tmpbuf = (u8 *)(PARAM_BASE + 32);
for (i = 0; i < 256; i++)
tmpbuf[i] = cmdline[i]; /* linux command line */
kernel = (void (*)(int, char **, char *))CFG_KERNEL_START;
/*
* Flush caches
*/
flush_cache_all();
/*
* Jump to kernel image
*/
(*kernel)(2, (char **)(PARAM_BASE + 16), (char *)PARAM_BASE);
}

View File

@ -1,37 +0,0 @@
#
# Makefile
#
CROSS = mipsel-linux-
CC = $(CROSS)gcc
LD = $(CROSS)ld
ROOTFIR = .
JZ4730DIR = $(ROOTFIR)/jz4730
JZ4740DIR = $(ROOTFIR)/jz4740
INCDIR = $(ROOTFIR)/include
COMDIR = $(ROOTFIR)/common
SOURCES += $(wildcard $(JZ4730DIR)/*.c)
SOURCES += $(wildcard $(JZ4740DIR)/*.c)
SOURCES += $(wildcard $(COMDIR)/*.c)
HEADS :=$(wildcard $(INCDIR)/*.h)
OBJS := $(addsuffix .o , $(basename $(notdir $(SOURCES))))
CFLAGS := -I$(INCDIR) -O2 -Wall
VPATH := $(JZ4730DIR) $(COMDIR) $(JZ4740DIR)
TARGETS = nandprog
all: $(TARGETS)
$(TARGETS) : $(OBJS) $(HEADS)
$(CC) $(CFLAGS) -o $(TARGETS) $(OBJS)
.c.o:
$(CC) $(CFLAGS) -o $@ -c $<
install:
clean:
rm -f *.o $(TARGETS)

View File

@ -1,30 +0,0 @@
This package contains source of the NAND flash programmer. It is an user
application program running on the Linux kernel.
To build the software, you need to have a Linux PC and install the
mipsel-linux-gcc compiler first, and then type 'make' under the
Linux command shell:
$ make
The dir tree as following:
|-- Makefile
|-- common
| |-- cmdline.c
| |-- loadcfg.c
| `-- main.c
|-- include
| |-- configs.h
| |-- include.h
| |-- jz4730.h
| |-- jz4740.h
| `-- nand_ecc.h
|-- jz4730
| `-- nandflash_4730.c
`-- jz4740
`-- nandflash_4740.c
To get more information, please read <NandProgrammer_Manual.pdf>.
Any questions, contact with me <yliu@ingenic.cn>.

View File

@ -1,605 +0,0 @@
/*
* Command line handling.
*
* This software is free.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "include.h"
#include "configs.h"
#include "nand_ecc.h"
#define printf_log(fp,fmt,args...) fprintf(fp,fmt,## args)
static u8 nand_buf[(2048+64)*128]; //Max 128 pages!
static u8 check_buf[(2048+64)*128];
static u32 spage, epage, chip_num;
static u8 *filename,ops_t,idx,cs_index,args_num;
static np_data *npdata;
static FILE *log_fp;
#define USE_VALID_CHECK
int nand_check_cmp(u8 *buf1,u8 *buf2,u32 len)
{
u32 i;
for (i = 0; i < len; i++)
{
if (buf1[i] != buf2[i])
{
printf("Check error! %x\n",i);
return -1;
}
}
return 0;
}
void dump_npdata(np_data *np)
{
int i;
printf("Process type:%d \n",np->pt);
printf("NAND interface ps:%d bw:%d rc:%d ppb:%d os:%d bbp:%d bba:%d\n",
np->ps,np->bw,np->rc,np->ppb,np->os,np->bbp,np->bba);
printf("ECC configration type:%d index:%d\n",np->et,np->ep);
printf("ECC position:");
for (i = 0;i < oob_64[np->ep].eccbytes;i++)
{
if (i % 9 == 0) printf("\n");
printf("%d ",oob_64[np->ep].eccpos[i]);
}
}
//a check sample for WINCE
//Modify this function according to your system
int check_invalid_block(u8 *buf,np_data *np)
{
int i,j;
u8 *p = buf + np->ps ,* q ;
q = buf + (( np->ps + np->os ) * np->ppb - 1) - 10;
if ( (*q) != 0xff )
{
// printf("A mark erase block! \n");
return 0;
}
for ( i = 0; i < np->ppb; i ++ )
{
for (j = 0; j < np->os; j ++ )
{
if ( p[j] != 0xff )
{
return 1;
}
}
p += np->ps;
}
// printf("A never use block! \n");
return 0;
}
int do_read_flash(np_data *np)
{
FILE *fp;
u32 sp;
int i,j,k;
if ((fp = fopen((const char *)np->fname, "w+")) == NULL )
{
printf("Can not open source or object file!\n");
return -1;
}
i = np->epage - np->spage;
j = i / MAX_BUF_PAGE;
k = i % MAX_BUF_PAGE;
sp = np->spage;
for (i=0;i<j;i++)
{
if (np->nand_check_block(sp/np->ppb))
{
printf_log(log_fp,"Skip a old block at %x!\n",sp/np->ppb);
sp += MAX_BUF_PAGE;
printf("Skip a old block!\n");
continue;
}
np->nand_read(nand_buf, sp, MAX_BUF_PAGE);
#ifdef USE_VALID_CHECK
if ( check_invalid_block(nand_buf,np) )
{
#endif
fwrite(nand_buf,1,MAX_BUF_SIZE,fp);
printf("Read block %d finish\n",sp/np->ppb);
#ifdef USE_VALID_CHECK
}
else printf("Skip a invalid block! %d \n",sp/np->ppb);
#endif
sp += MAX_BUF_PAGE;
}
if (k)
{
if (np->nand_check_block(sp/np->ppb))
{
printf_log(log_fp,"Skip a old block at %x!\n",sp/np->ppb);
printf("Skip a old block!\n");
}
else
{
np->nand_read(nand_buf, sp, k);
#ifdef USE_VALID_CHECK
if ( check_invalid_block(nand_buf,np) )
{
#endif
fwrite(nand_buf, 1, k*OOBPAGE_SIZE, fp);
#ifdef USE_VALID_CHECK
}
else printf("Skip a invalid block! %d \n",sp/np->ppb);
#endif
}
}
printf("Read nand flash finish!\n");
fclose(fp);
return 0;
}
int do_write_flash(np_data *np)
{
FILE *fp;
u32 sp,flen,offset;
int i,j,k,r,error_flag=0;
if ((fp = fopen((const char *)np->fname,"r")) == NULL )
{
printf("Can not open source or object file!\n");
return -1;
}
fseek(fp,0,SEEK_END);
flen = ftell(fp);
i = flen / OOBPAGE_SIZE;
if (flen % OOBPAGE_SIZE !=0)
{
printf("Source file length is not fit!\n");
return -1;
}
sp = np->spage;
if (sp % np->ppb !=0)
{
printf("Start page number not blockaligned!\n");
return -1;
}
//Erase object block first
j = sp / np->ppb;
k = flen/OOBPAGE_SIZE;
if (k % np->ppb == 0) k = k / np->ppb;
else k = k / np->ppb +1;
np->nand_erase(k,j,0);
j = i / MAX_BUF_PAGE;
k = i % MAX_BUF_PAGE;
offset = 0;
// printf("j k %d %d %d %d\n",j,k,i,flen);
for (i=0;i<j;i++)
{
fseek(fp,offset,SEEK_SET);
fread(nand_buf,1,MAX_BUF_SIZE,fp);
BLOCK_BROKEN:
for (r=0;r<MAX_RETRY;r++)
{
for (;sp <=np->epage - np->ppb;sp += np->ppb)
{ //old bad block
if (!np->nand_check_block(sp/np->ppb))
break;
printf("Skip a old bad blocks!\n");
printf_log(log_fp,"Skip a old block at %x!\n",sp/np->ppb);
}
if (sp/np->ppb > np->epage /np->ppb)
{
printf("Program end but not finish,due to bad block!\n");
printf_log(log_fp,"Program end but not finish,due to bad block!\n");
return -1;
}
if (np->nand_program(nand_buf,sp,np->ppb))
{
error_flag = 1;
printf("Program error!\n");
printf_log(log_fp,"Program error! %x\n",sp/np->ppb);
break;
}
memset(check_buf,0,MAX_BUF_SIZE);
np->nand_read(check_buf,sp,np->ppb);
if (np->nand_check(nand_buf,check_buf,
MAX_BUF_SIZE) )
{ //check error!
error_flag = 1;
printf("Error retry!\n");
printf_log(log_fp,"Error retry!\n");
continue;
}
else
{
error_flag = 0;
break;
}
}
if (error_flag)
{ //block has broken!
printf("Found a new bad block: %x!\n",sp/np->ppb);
printf_log(log_fp,"Found a new bad block at %x!\n",sp/np->ppb);
np->nand_erase(1,sp/np->ppb,0); //erase before mark bad block!
np->nand_block_markbad(sp /np->ppb);
sp += np->ppb;
goto BLOCK_BROKEN;
}
else
{
printf("Write block %d finish\n",sp/np->ppb);
sp += np->ppb;
offset += MAX_BUF_SIZE;
}
}
if (k)
{
fseek(fp,offset,SEEK_SET);
fread(nand_buf,1,k * OOBPAGE_SIZE ,fp);
BLOCK_BROKEN1:
for (r=0;r<MAX_RETRY;r++)
{
for (;sp <=np->epage - np->ppb;sp += np->ppb)
{ //old bad block
if (!np->nand_check_block(sp/np->ppb))
break;
printf("Skip a old bad blocks!\n");
printf_log(log_fp,"Skip a old block at %x!\n",sp/np->ppb);
}
if (sp/np->ppb > np->epage/np->ppb)
{
printf("Program end but not finish,due to bad block!\n");
printf_log(log_fp,"Program end but not finish,due to bad block!\n");
return 0;
}
if (np->nand_program(nand_buf,sp,k))
{
error_flag = 1;
printf("Program error!\n");
printf_log(log_fp,"Program error! %x\n",sp/np->ppb);
break;
}
memset(check_buf,0,MAX_BUF_SIZE);
np->nand_read(check_buf,sp,k);
if (np->nand_check(nand_buf,check_buf,
k * OOBPAGE_SIZE) )
{ //check error!
error_flag = 1;
printf("Error retry!\n");
printf_log(log_fp,"Error retry!\n");
continue;
}
else
{
error_flag = 0;
break;
}
}
if (error_flag)
{ //block has broken!
printf("Found a new bad block : %x!\n",sp/np->ppb);
printf_log(log_fp,"Found a new bad block at %x!\n",sp/np->ppb);
np->nand_erase(1,sp/np->ppb,0); //erase before mark bad block!
np->nand_block_markbad(sp /np->ppb);
sp += np->ppb;
goto BLOCK_BROKEN1;
}
}
printf("Nand flash write finish!\n");
return 0;
}
void show_usage()
{
printf("Nand flash programmer.Version v1.0\n");
printf("Usage: nandprog spage epage opration_type obj_file chip_index [config_index]\n\n");
printf(" spage operation start page number\n");
printf(" epage operation end page number\n");
printf(" opration_type operation type read or write\n");
printf(" obj_file source or object filename\n");
printf(" chip_index chip select index\n");
printf(" config_index optional,when chosen,\n");
printf(" will use one of these default configrations instead of load from CFG\n");
}
int cmdline(int argc, char *argv[], np_data *np)
{
if (argc<6 || argc>7)
{
show_usage();
return -1;
}
if (strlen(argv[1])>8)
{
printf("Start address page error!\n");
return -1;
}
spage = atoi(argv[1]);
if (spage > MAX_PAGE)
{
printf("Start address page error!\n");
return -1;
}
if (strlen(argv[2])>8)
{
printf("End address page error!\n");
return -1;
}
epage = atoi(argv[2]);
if (epage > MAX_PAGE)
{
printf("End address page error!\n");
return -1;
}
if (strlen(argv[3])>1)
{
printf("Operation type error!\n");
return -1;
}
if (argv[3][0] == 'r')
ops_t = READ_FLASH;
else if (argv[3][0] == 'w')
ops_t = WRITE_FLASH;
else
{
printf("Operation type error!\n");
return -1;
}
if (strlen(argv[4])>20)
{
printf("Source or object file name error!\n");
return -1;
}
filename = (unsigned char *)argv[4];
if (strlen(argv[5])>2)
{
printf("Chip select number error!\n");
return -1;
}
cs_index = atoi(argv[5]);
if (epage <= spage)
{
printf("End page number must larger than start page number!\n");
return -1;
}
if (argc == 7)
{
args_num = 7;
if (strlen(argv[6])>3)
{
printf("Processor type error!\n");
return -1;
}
idx = atoi(argv[6]);
if (idx > 20)
{
printf("Processor type error!\n");
return -1;
}
}
else args_num = 6;
printf("Deal command line: spage%d epage%d ops%d file:%s cs%d\n",
spage,epage,ops_t,filename,cs_index);
return 0;
}
void init_funs(np_data *np)
{
switch (np->pt)
{
case JZ4740:
np->ebase = 0x13010000;
np->dport = 0x18000000;
np->gport = 0x10010000;
np->bm_ms = 0x100;
np->pm_ms = 0x20000;
np->gm_ms = 0x500;
np->ap_offset = 0x10000;
np->cp_offset = 0x8000;
np->nand_init = nand_init_4740;
np->nand_erase = nand_erase_4740;
np->nand_program = nand_program_4740;
np->nand_read = nand_read_4740_rs;
np->nand_read_raw = nand_read_raw_4740;
np->nand_read_oob = nand_read_oob_4740;
np->nand_block_markbad = nand_block_markbad_4740;
np->nand_check = nand_check_cmp;
np->nand_check_block = nand_check_block_4740;
if (np->et == HARDRS)
np->nand_read = nand_read_4740_rs;
else
np->nand_read = nand_read_4740_hm;
break;
case JZ4730:
np->ebase = 0x13010000;
np->dport = 0x14000000;
np->gport = 0x0;
np->bm_ms = 0x100;
np->pm_ms = 0xb0000;
np->gm_ms = 0x0;
np->ap_offset = 0x80000;
np->cp_offset = 0x40000;
np->nand_init = nand_init_4730;
np->nand_erase = nand_erase_4730;
np->nand_program = nand_program_4730;
np->nand_read = nand_read_4730;
np->nand_read_oob = nand_read_oob_4730;
np->nand_block_markbad = nand_block_markbad;
np->nand_check = nand_check_cmp;
np->nand_check_block = nand_check_block;
np->nand_select = chip_select_4730;
break;
case JZ4760:
break;
}
// dump_npdata(np);
}
np_data * cmdinit()
{
int fd;
if (args_num>6)
{
npdata = &config_list[idx];
if (npdata)
printf("Load configration index success!\n");
else
{
printf("Load configration index fail!\n");
return 0;
}
}
else
{
npdata = load_cfg();
if (npdata)
printf("Load configration file success!\n");
else
{
printf("Load configration file fail!\n");
return 0;
}
}
if (!npdata) return 0;
init_funs(npdata);
npdata->spage = spage;
npdata->epage = epage;
npdata->fname = filename;
npdata->ops = ops_t;
npdata->cs = cs_index;
if((fd=open("/dev/mem",O_RDWR|O_SYNC))==-1)
{
printf("Can not open memory file!\n");
return 0;
}
npdata->base_map = mmap(NULL,npdata->bm_ms,PROT_READ | PROT_WRITE,MAP_SHARED,fd,npdata->ebase);
if(npdata->base_map == MAP_FAILED)
{
printf("Can not map EMC_BASE ioport!\n");
return 0;
}
else printf("Map EMC_BASE success :%x\n",(u32)npdata->base_map);
npdata->port_map=mmap(NULL,npdata->pm_ms ,PROT_READ | PROT_WRITE,MAP_SHARED,fd,npdata->dport);
if(npdata->port_map== MAP_FAILED)
{
printf("Can not map NAND_PORT ioport!\n");
return 0;
}
else printf("Map NAND_PORT success :%x\n",(u32)npdata->port_map);
if (npdata->pt == JZ4740)
{
npdata->gpio_map=mmap(NULL,npdata->gm_ms ,PROT_READ | PROT_WRITE,MAP_SHARED,fd,npdata->gport);
if(npdata->gpio_map== MAP_FAILED)
{
printf("Can not map GPIO ioport!\n");
return 0;
}
else printf("Map GPIO_PORT success :%x\n",(u32)npdata->gpio_map);
}
close(fd);
printf("Memory map all success!\n");
npdata->nand_init(npdata);
return npdata;
}
int cmdexcute(np_data *np)
{
int ret;
if ((log_fp=fopen(NUM_FILENAME,"a+"))==NULL )
{
printf("Can not open number file!\n");
return -1;
}
fscanf(log_fp,"%d",&chip_num);
fclose(log_fp);
chip_num++;
if ((log_fp=fopen(NUM_FILENAME,"w"))==NULL )
{
printf("Can not open number file!\n");
return -1;
}
printf_log(log_fp,"%d",chip_num);
fclose(log_fp);
if ((log_fp=fopen(LOG_FILENAME,"a+"))==NULL )
{
printf("Can not open log file!\n");
return -1;
}
printf_log(log_fp,"\nNo.%d :\n",chip_num);
if (np->ops == READ_FLASH)
{
printf_log(log_fp,"Read nand flash!\n");
printf_log(log_fp,"Args:index=%d spage=%d epage=%d file=%s cs=%d\n",
idx,spage,epage,filename,cs_index);
ret= do_read_flash(np);
}
else
{
printf_log(log_fp,"Write nand flash!\n");
printf_log(log_fp,"Args:index=%d spage=%d epage=%d file=%s cs=%d\n",
idx,spage,epage,filename,cs_index);
ret= do_write_flash(np);
}
if (!ret)
printf_log(log_fp,"Operation success!\n");
else
printf_log(log_fp,"Operation fail!\n");
fclose(log_fp);
return 0;
}
int cmdexit(np_data *np)
{
munmap(np->base_map,np->bm_ms);
munmap(np->port_map,np->pm_ms);
if (np->pt == JZ4740)
munmap(np->gpio_map,np->gm_ms);
return 0;
}

View File

@ -1,214 +0,0 @@
/*
* Configfile parsing.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "include.h"
#define CFG_FIELD_NUM 10
static np_data np;
extern struct nand_oobinfo oob_64[];
const char CFG_FIELD[][30]=
{
"CPUTYPE",
"BUSWIDTH",
"ROWCYCLES",
"PAGESIZE",
"PAGEPERBLOCK",
"OOBSIZE",
"BADBLOCKPOS",
"BADBLOCKPAGE",
"ECCTYPE",
"[END]",
};
np_data * load_cfg(void)
{
FILE *fp;
char line[100];
unsigned short i,j;
unsigned int d;
if ((fp = fopen("nandprog.cfg", "r"))==NULL)
{
printf("Can not open configration file!\n");
return 0;
}
while(!strstr(line, "[NANDPROG]")) //find the nandprog section!
{
if (feof(fp))
{
printf("nand programmer configration file illege!\n");
return 0;
}
fscanf(fp,"%s",line);
}
while(1)
{
if (feof(fp))
{
printf("nand programmer configration file illege!\n");
return 0;
}
fscanf(fp,"%s",line);
if (line[0]==';')
{
line[0]='\0';
continue;
}
for (i=0;i<CFG_FIELD_NUM;i++)
if (strstr(line,CFG_FIELD[i])) break;
switch (i)
{
case 0: //CPUTYPE
while (!feof(fp))
{
fscanf(fp,"%s",line);
if (strstr(line,"JZ4730"))
{
np.pt = JZ4730;
break;
}
else if (strstr(line,"JZ4740"))
{
np.pt = JZ4740;
break;
}
else continue;
}
break;
case 1: //BUSWIDTH
while (!feof(fp))
{
fscanf(fp,"%d",&d);
if (d!=8 && d!=16) continue;
np.bw = d;
break;
}
break;
case 2: //ROWCYCLES
while (!feof(fp))
{
fscanf(fp,"%d",&d);
if (d!=3 && d!=2) continue;
np.rc = d;
break;
}
break;
case 3: //PAGESIZE
while (!feof(fp))
{
fscanf(fp,"%d",&d);
if (d!=2048 && d!=512) continue;
np.ps = d;
break;
}
break;
case 4: //PAGEPERBLOCK
while (!feof(fp))
{
fscanf(fp,"%d",&d);
if (d!=128 && d!=64) continue;
np.ppb = d;
break;
}
break;
case 5: //OOBSIZE
while (!feof(fp))
{
fscanf(fp,"%d",&d);
if (d!=16 && d!=64) continue;
np.os = d;
break;
}
break;
case 6: //BADBLOCKPOS
while (!feof(fp))
{
fscanf(fp,"%d",&d);
if (d>2048) continue;
np.bbp = d;
break;
}
break;
case 7: //BADBLOCKPAGE
while (!feof(fp))
{
fscanf(fp,"%d",&d);
if (d>np.ppb) continue;
np.bba = d;
break;
}
break;
case 8: //ECCTYPE
while (!feof(fp))
{
fscanf(fp,"%s",line);
if (strstr(line,"RS"))
{
np.et = HARDRS;
d = 36; //36 bytes ecc
oob_64[4].eccbytes = 36;
np.ep = 4;
break;
}
else if (strstr(line,"HM"))
{
np.et = HARDHM;
d = 24; //24 bytes ecc
oob_64[4].eccbytes = 24;
np.ep = 4;
break;
}
else continue;
}
while (!feof(fp))
{
fscanf(fp,"%s",line);
if (strstr(line,"{")) break;
}
for (j = 0;j < d;j++)
{
if (feof(fp))
{
printf("nand programmer configration file illege!\n");
return 0;
}
fscanf(fp,"%d",&d);
if (d > np.os)
{
printf("nand programmer configration file illege!\n");
return 0;
}
oob_64[4].eccpos[j] = d;
}
while (!feof(fp))
{
fscanf(fp,"%s",line);
if (strstr(line,"}")) break;
}
break;
case 9:
return &np;
default:
;
}
}
}

View File

@ -1,23 +0,0 @@
/*
* Main entry of the program.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include "include.h"
static np_data *npdata;
int main(int argc, char *argv[])
{
if (cmdline(argc, argv, npdata)) return 0;
npdata=cmdinit();
if (!npdata) return 0;
if (cmdexcute(npdata)) return 0;
if (cmdexit(npdata)) return 0;
return 0;
}

View File

@ -1,406 +0,0 @@
#ifndef __CONFIGS_H__
#define __CONFIGS_H__
#include "include.h"
np_data config_list[]=
{
{
//No 0
//The config for jz4730 uboot
.pt = JZ4730,
.et = HARDHM, //HW HM ECC
.ep = 0, //ecc position index 0
.bw = 8,
.ps = 2048,
.os = 64,
.ppb = 64,
.rc = 3,
.bbp = 0,
.bba = 0,
.ebase = 0x13010000,
.dport = 0x14000000,
.gport = 0,
.bm_ms = 0x100,
.pm_ms = 0xb0000,
.gm_ms = 0,
.ap_offset = 0x80000,
.cp_offset = 0x40000,
.nand_init = nand_init_4730,
.nand_erase = nand_erase_4730,
.nand_program = nand_program_4730,
.nand_read = nand_read_4730,
.nand_read_oob = nand_read_oob_4730,
.nand_block_markbad = nand_block_markbad,
.nand_check = nand_check_cmp,
.nand_check_block = nand_check_block,
.nand_select = chip_select_4730,
},
{
//No 1
//The config for jz4730 linux fs
.pt = JZ4730,
.et = HARDHM, //HW HM ECC
.ep = 1, //ecc position index 1
.bw = 8,
.ps = 2048,
.os = 64,
.ppb = 64,
.rc = 3,
.bbp = 0,
.bba = 0,
.ebase = 0x13010000,
.dport = 0x14000000,
.gport = 0,
.bm_ms = 0x100,
.pm_ms = 0xb0000,
.gm_ms = 0,
.ap_offset = 0x80000,
.cp_offset = 0x40000,
.nand_init = nand_init_4730,
.nand_erase = nand_erase_4730,
.nand_program = nand_program_4730,
.nand_read = nand_read_4730,
.nand_read_oob = nand_read_oob_4730,
.nand_block_markbad = nand_block_markbad,
.nand_check = nand_check_cmp,
.nand_check_block = nand_check_block,
.nand_select = chip_select_4730,
},
{
//No 2
//The config for jz4730 ucos
.pt = JZ4730,
.et = HARDHM, //HW HM ECC
.ep = 1, //need modify
.bw = 8,
.ps = 2048,
.os = 64,
.ppb = 64,
.rc = 3,
.bbp = 0, //need modify
.bba = 0, //need modify
//do not need modify
.ebase = 0x13010000,
.dport = 0x14000000,
.gport = 0,
.bm_ms = 0x100,
.pm_ms = 0xb0000,
.gm_ms = 0,
.ap_offset = 0x80000,
.cp_offset = 0x40000,
.nand_init = nand_init_4730,
.nand_erase = nand_erase_4730,
.nand_program = nand_program_4730,
.nand_read = nand_read_4730,
.nand_read_oob = nand_read_oob_4730,
.nand_block_markbad = nand_block_markbad,
.nand_check = nand_check_cmp,
.nand_check_block = nand_check_block,
.nand_select = chip_select_4730,
},
{
//No 3
//The config for jz4730 wince
.pt = JZ4730,
.et = HARDHM, //HW HM ECC
.ep = 1, //need modify
.bw = 8,
.ps = 2048,
.os = 64,
.ppb = 64,
.rc = 3,
.bbp = 0, //need modify
.bba = 0, //need modify
//do not need modify
.ebase = 0x13010000,
.dport = 0x14000000,
.gport = 0,
.bm_ms = 0x100,
.pm_ms = 0xb0000,
.gm_ms = 0,
.ap_offset = 0x80000,
.cp_offset = 0x40000,
.nand_init = nand_init_4730,
.nand_erase = nand_erase_4730,
.nand_program = nand_program_4730,
.nand_read = nand_read_4730,
.nand_read_oob = nand_read_oob_4730,
.nand_block_markbad = nand_block_markbad,
.nand_check = nand_check_cmp,
.nand_check_block = nand_check_block,
.nand_select = chip_select_4730,
},
{
//No 4
//The config for jz4740 uboot use HW RS
.pt = JZ4740,
.et = HARDRS, //HW HM ECC
.ep = 2, //need modify
.bw = 8,
.ps = 2048,
.os = 64,
.ppb = 128,
.rc = 3,
.bbp = 0, //need modify
.bba = 0, //need modify
//do not need modify
.ebase = 0x13010000,
.dport = 0x18000000,
.gport = 0x10010000,
.bm_ms = 0x100,
.pm_ms = 0x20000,
.gm_ms = 0x500,
.ap_offset = 0x10000,
.cp_offset = 0x8000,
.nand_init = nand_init_4740,
.nand_erase = nand_erase_4740,
.nand_program = nand_program_4740,
.nand_read = nand_read_4740_rs,
.nand_read_oob = nand_read_oob_4740,
.nand_block_markbad = nand_block_markbad_4740,
.nand_check = nand_check_cmp,
.nand_check_block = nand_check_block_4740,
.nand_select = chip_select_4740,
},
{
//No 5
//The config for jz4740 linux use HW RS
.pt = JZ4740,
.et = HARDRS, //HW HM ECC
.ep = 3, //need modify
.bw = 8,
.ps = 2048,
.os = 64,
.ppb = 128,
.rc = 3,
.bbp = 1, //need modify
.bba = 0, //need modify
//do not need modify
.ebase = 0x13010000,
.dport = 0x18000000,
.gport = 0x10010000,
.bm_ms = 0x100,
.pm_ms = 0x20000,
.gm_ms = 0x500,
.ap_offset = 0x10000,
.cp_offset = 0x8000,
.nand_init = nand_init_4740,
.nand_fini = nand_fini_4740,
.nand_erase = nand_erase_4740,
.nand_program = nand_program_4740,
.nand_read = nand_read_4740_rs,
.nand_read_oob = nand_read_oob_4740,
.nand_block_markbad = nand_block_markbad_4740,
.nand_check = nand_check_cmp,
.nand_check_block = nand_check_block_4740,
.nand_select = chip_select_4740,
},
{
//No 6
//The config for jz4740 linux use HW HM
.pt = JZ4740,
.et = HARDHM, //HW HM ECC
.ep = 1, //need modify
.bw = 8,
.ps = 2048,
.os = 64,
.ppb = 128,
.rc = 3,
.bbp = 0, //need modify
.bba = 0, //need modify
//do not need modify
.ebase = 0x13010000,
.dport = 0x18000000,
.gport = 0x10010000,
.bm_ms = 0x100,
.pm_ms = 0x20000,
.gm_ms = 0x500,
.ap_offset = 0x10000,
.cp_offset = 0x8000,
.nand_init = nand_init_4740,
.nand_erase = nand_erase_4740,
.nand_program = nand_program_4740,
.nand_read = nand_read_4740_hm,
.nand_read_oob = nand_read_oob_4740,
.nand_block_markbad = nand_block_markbad_4740,
.nand_check = nand_check_cmp,
.nand_check_block = nand_check_block_4740,
.nand_select = chip_select_4740,
},
{
//No 7
//The config for jz4740 ucos use HW RS
.pt = JZ4740,
.et = HARDRS, //HW HM ECC
// .ep = 3, //need modify
.bw = 8,
.ps = 2048,
.os = 64,
.ppb = 128,
.rc = 3,
// .bbp = 0, //need modify
// .bba = 0, //need modify
//do not need modify
.ebase = 0x13010000,
.dport = 0x18000000,
.gport = 0x10010000,
.bm_ms = 0x100,
.pm_ms = 0x20000,
.gm_ms = 0x500,
.ap_offset = 0x10000,
.cp_offset = 0x8000,
.nand_init = nand_init_4740,
.nand_erase = nand_erase_4740,
.nand_program = nand_program_4740,
.nand_read = nand_read_4740_rs,
.nand_read_oob = nand_read_oob_4740,
.nand_block_markbad = nand_block_markbad_4740,
.nand_check = nand_check_cmp,
.nand_check_block = nand_check_block_4740,
.nand_select = chip_select_4740,
},
{
//No 8
//The config for jz4740 ucos use HW HM
.pt = JZ4740,
.et = HARDHM, //HW HM ECC
// .ep = 3, //need modify
.bw = 8,
.ps = 2048,
.os = 64,
.ppb = 128,
.rc = 3,
// .bbp = 0, //need modify
// .bba = 0, //need modify
//do not need modify
.ebase = 0x13010000,
.dport = 0x18000000,
.gport = 0x10010000,
.bm_ms = 0x100,
.pm_ms = 0x20000,
.gm_ms = 0x500,
.ap_offset = 0x10000,
.cp_offset = 0x8000,
.nand_init = nand_init_4740,
.nand_erase = nand_erase_4740,
.nand_program = nand_program_4740,
.nand_read = nand_read_4740_hm,
.nand_read_oob = nand_read_oob_4740,
.nand_block_markbad = nand_block_markbad_4740,
.nand_check = nand_check_cmp,
.nand_check_block = nand_check_block_4740,
.nand_select = chip_select_4740,
},
{
//No 9
//The config for jz4740 wince use HW RS
.pt = JZ4740,
.et = HARDRS, //HW HM ECC
// .ep = 3, //need modify
.bw = 8,
.ps = 2048,
.os = 64,
.ppb = 128,
.rc = 3,
// .bbp = 0, //need modify
// .bba = 0, //need modify
//do not need modify
.ebase = 0x13010000,
.dport = 0x18000000,
.gport = 0x10010000,
.bm_ms = 0x100,
.pm_ms = 0x20000,
.gm_ms = 0x500,
.ap_offset = 0x10000,
.cp_offset = 0x8000,
.nand_init = nand_init_4740,
.nand_erase = nand_erase_4740,
.nand_program = nand_program_4740,
.nand_read = nand_read_4740_rs,
.nand_read_oob = nand_read_oob_4740,
.nand_block_markbad = nand_block_markbad_4740,
.nand_check = nand_check_cmp,
.nand_check_block = nand_check_block_4740,
.nand_select = chip_select_4740,
},
{
//No 10
//The config for jz4740 wince use HW RS
.pt = JZ4740,
.et = HARDHM, //HW HM ECC
// .ep = 3, //need modify
.bw = 8,
.ps = 2048,
.os = 64,
.ppb = 128,
.rc = 3,
// .bbp = 0, //need modify
// .bba = 0, //need modify
//do not need modify
.ebase = 0x13010000,
.dport = 0x18000000,
.gport = 0x10010000,
.bm_ms = 0x100,
.pm_ms = 0x20000,
.gm_ms = 0x500,
.ap_offset = 0x10000,
.cp_offset = 0x8000,
.nand_init = nand_init_4740,
.nand_erase = nand_erase_4740,
.nand_program = nand_program_4740,
.nand_read = nand_read_4740_hm,
.nand_read_oob = nand_read_oob_4740,
.nand_block_markbad = nand_block_markbad_4740,
.nand_check = nand_check_cmp,
.nand_check_block = nand_check_block_4740,
.nand_select = chip_select_4740,
},
};
#endif

View File

@ -1,140 +0,0 @@
#ifndef __INCLUDE_H__
#define __INCLUDE_H__
//#include "nand_ecc.h"
#define u32 unsigned int
#define u16 unsigned short
#define u8 unsigned char
#define MAX_PAGE 0xffffffff
#define PAGE_SIZE np->ps
#define OOB_SIZE np->os
#define OOBPAGE_SIZE (PAGE_SIZE + OOB_SIZE)
#define MAX_BUF_PAGE np->ppb
#define MAX_BUF_SIZE OOBPAGE_SIZE*MAX_BUF_PAGE
#define MAX_RETRY 3
#define LAST_PAGE 65536
#define LOG_FILENAME "nprog.log"
#define NUM_FILENAME "number.log"
enum
{
JZ4730CPU,
LINUXHM,
JZ4740CPU,
LINUXRS,
USERSPEC,
};
struct nand_oobinfo
{
int eccname;
unsigned int eccbytes;
unsigned int eccpos[64];
};
enum
{
SOFTHM,
SOFTRS,
HARDHM,
HARDRS
};
enum
{
JZ4730,
JZ4740,
JZ4760
};
enum
{
READ_FLASH,
WRITE_FLASH
};
typedef struct _NP_DATA
{
u8 pt; //processor type jz4730/jz4740/jz4760....
u8 et; //ECC type software HM/RS or hardware HM/RS
u8 ep; //ECC position index
u8 ops; //opration type read/write
u8 cs; //chip select index number
u8 *fname; //Source or object file name
u32 spage; //opration start page number of nand flash
u32 epage; //opration end page number of nand flash
u32 bw; //nand flash bus width
u32 ps; //nand flash page size
u32 os; //nand flash oob size
u32 ppb; //nand flash page per block
u32 rc; //nand flash row syscle
u32 bbp; //nand flash bad block ID position
u32 bba; //nand flash bad block ID page position
u32 ebase; //EMC base PHY address
void *base_map; //EMC base mapped address
u32 bm_ms; // EMC base mapped size
u32 dport; //Nand flash port base PHY address
void *port_map; //nand port mapped address
u32 pm_ms; // EMC base mapped size
u32 gport; //GPIO base PHY address
void *gpio_map; //GPIO mapped address
u32 gm_ms; // EMC base mapped size
u32 ap_offset; //addrport offset
u32 cp_offset; //cmdportoffset
int (*nand_init)(struct _NP_DATA *);
int (*nand_fini)(void);
u32 (*nand_query)(void);
int (*nand_erase)(int, int, int);
int (*nand_program)(u8 *, int, int );
int (*nand_read)(u8 *, u32, u32);
int (*nand_read_raw)(u8 *, u32, u32);
int (*nand_read_oob)(u8 *, u32, u32);
int (*nand_check_block) (u32);
int (*nand_check) (u8 *,u8 *,u32 );
void (*nand_block_markbad) (u32);
int (*nand_select) (u8);
}np_data;
//jz4730 functions
extern int nand_init_4730(np_data *);
extern int nand_fini_4730(void);
extern unsigned int nand_query_4730(void);
extern int nand_erase_4730(int blk_num, int sblk, int force);
extern int nand_program_4730(u8 *buf, int startpage, int pagenum);
extern int nand_read_4730(u8 *buf, u32 startpage, u32 pagenum);
extern int nand_read_raw_4730(u8 *buf, u32 startpage, u32 pagenum);
extern int nand_read_oob_4730(u8 *buf, u32 startpage, u32 pagenum);
extern int nand_check_block(u32);
extern void nand_block_markbad(u32);
extern int chip_select_4730(u8 cs);
//jz4740 functions
extern int nand_init_4740(np_data *);
extern int nand_fini_4740(void);
extern unsigned int nand_query_4740(void);
extern int nand_erase_4740(int blk_num, int sblk, int force);
extern int nand_program_4740(u8 *buf, int startpage, int pagenum);
extern int nand_read_4740_hm(u8 *buf, u32 startpage, u32 pagenum);
extern int nand_read_4740_rs(u8 *buf, u32 startpage, u32 pagenum);
extern int nand_read_raw_4740(u8 *buf, u32 startpage, u32 pagenum);
extern int nand_read_oob_4740(u8 *buf, u32 startpage, u32 pagenum);
extern int nand_check_block_4740(u32);
extern void nand_block_markbad_4740(u32);
extern int chip_select_4740(u8 cs);
//common functions
extern int cmdline(int,char **,np_data *);
extern np_data * cmdinit();
extern int cmdexcute(np_data *);
extern int cmdexit(np_data *);
extern int nand_check_cmp(u8 *buf1,u8 *buf2,u32 len);
extern np_data * load_cfg();
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,89 +0,0 @@
#ifndef __NAND_ECC_H__
#define __NAND_ECC_H__
#include "include.h"
// This head file define these ecc position and ecc types
struct nand_oobinfo oob_64[] =
{
{
.eccname = JZ4730CPU,
.eccbytes = 24,
.eccpos =
{
4, 5, 6,
8, 9, 10,
12,13,14,
16,17,18,
20,21,22,
24,25,26,
28,29,30,
32,33,34,
},
},
{
.eccname = LINUXHM,
.eccbytes = 24,
.eccpos =
{
41, 40, 42,
44, 43, 45,
47, 46, 48,
50, 49, 51,
53, 52, 54,
56, 55, 57,
59, 58, 60,
62, 61, 63
/* old need change position
40, 41, 42,
43, 44, 45,
46, 47, 48,
49, 50, 51,
52, 53, 54,
55, 56, 57,
58, 59, 60,
61, 62, 63
*/
},
},
{
.eccname = JZ4740CPU,
.eccbytes = 36,
.eccpos =
{
6, 7, 8, 9, 10,11,12,13,14,
15,16,17,18,19,20,21,22,23,
24,25,26,27,28,29,30,31,32,
33,34,35,36,37,38,39,40,41
},
},
{
.eccname = LINUXRS,
.eccbytes = 36,
.eccpos =
{
28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63
},
},
{ //this one must update by config file
.eccname = USERSPEC,
.eccbytes = 64,
.eccpos =
{
0, 0, 0, 0,
},
},
};
#endif

View File

@ -1,606 +0,0 @@
/*
* Common NAND Flash operations for JZ4730.
*
* This software is free.
*/
#include "jz4730.h"
#include "include.h"
unsigned int EMC_BASE;
extern struct nand_oobinfo oob_64[];
/*
* Standard NAND commands.
*/
#define CMD_READA 0x00
#define CMD_READB 0x01
#define CMD_READC 0x50
#define CMD_ERASE_SETUP 0x60
#define CMD_ERASE 0xD0
#define CMD_READ_STATUS 0x70
#define CMD_CONFIRM 0x30
#define CMD_SEQIN 0x80
#define CMD_PGPROG 0x10
#define CMD_READID 0x90
#define CMD_RESET 0xff
#define ECC_BLOCK 256 /* 3-bytes HW ECC per 256-bytes data */
#define ECC_OFFSET 4 /* ECC store location offset to the spare area */
/*
* NAND routines.
*/
#define nand_enable() (REG_EMC_NFCSR |= EMC_NFCSR_NFE | EMC_NFCSR_FCE)
#define nand_disable() (REG_EMC_NFCSR &= ~(EMC_NFCSR_NFE | EMC_NFCSR_FCE))
#define nand_ecc_enable() (REG_EMC_NFCSR |= EMC_NFCSR_ECCE | EMC_NFCSR_ERST)
#define nand_ecc_disable() (REG_EMC_NFCSR &= ~EMC_NFCSR_ECCE)
#define nand_ready() (REG_EMC_NFCSR & EMC_NFCSR_RB)
#define nand_ecc() (REG_EMC_NFECC & 0x00ffffff)
#define nand_cmd(n) (REG8(cmdport+csn) = (n))
#define nand_addr(n) (REG8(addrport+csn) = (n))
#define nand_data8() REG8(dataport+csn)
#define nand_data16() REG16(dataport+csn)
static inline void nand_wait_ready(void)
{
u32 to = 1000;
while (nand_ready() && to--);
while (!nand_ready());
}
static volatile unsigned char *emcbase = 0;
static volatile unsigned char *addrport = 0;
static volatile unsigned char *dataport = 0;
static volatile unsigned char *cmdport = 0;
static u32 bus = 8, row = 2, pagesize = 512, oobsize = 16, ppb = 32;
static u32 bad_block_pos = 0 , bad_block_page =0, csn =0;
static struct nand_oobinfo *oob_pos;
static np_data *np;
/*
* notify(int param)
*
* param value:
* 0 : Ok
* -1: page op fail
* -2: hit bad block, skip it.
*/
static int (*write_proc)(unsigned char *, int) = 0;
static int (*read_proc)(unsigned char *, int) = 0;
static u8 badbuf[2048 + 64] = {0};
static u8 oobbuf[64] = {0};
/*
* I/O read/write interface.
*/
static inline int nand_data_write8(unsigned char *buf, int count)
{
int i;
u8 *p = (u8 *)buf;
for (i = 0; i < count; i++)
nand_data8() = *p++;
return 0;
}
static inline int nand_data_write16(unsigned char *buf, int count)
{
int i;
u16 *p = (u16 *)buf;
for (i = 0; i < count/2; i++)
nand_data16() = *p++;
return 0;
}
static inline int nand_data_read8(unsigned char *buf, int count)
{
int i;
u8 *p = (u8 *)buf;
for (i = 0; i < count; i++)
*p++ = nand_data8();
return 0;
}
static inline int nand_data_read16(unsigned char *buf, int count)
{
int i;
u16 *p = (u16 *)buf;
for (i = 0; i < count/2; i++)
*p++ = nand_data16();
return 0;
}
int chip_select_4730(u8 cs)
{
csn = (u32)cs << 15; //modify this number for your board
return 0;
}
/*
* Init nand parameters and enable nand controller.
*/
int nand_init_4730(np_data *npp)
{
bus = npp->bw;
row = npp->rc;
pagesize = npp->ps;
oobsize = npp->os;
ppb = npp->ppb;
bad_block_pos = npp->bbp;
bad_block_page = npp->bba;
if (bus == 8) {
write_proc = nand_data_write8;
read_proc = nand_data_read8;
} else {
write_proc = nand_data_write16;
read_proc = nand_data_read16;
}
emcbase = (u8 *)npp->base_map;
dataport = (u8 *)npp->port_map;
addrport = (u8 *)((u32)dataport + npp->ap_offset);
cmdport = (u8 *)((u32)dataport + npp->cp_offset);
EMC_BASE = (u32)emcbase;
oob_pos = &oob_64[npp->ep];
np = npp;
nand_enable();
chip_select_4730(npp->cs);
return 0;
}
/*
* Disable nand operation.
*/
int nand_fini_4730(void)
{
nand_disable();
return 0;
}
/*
* Read ID.
*/
unsigned int nand_query_4730(void)
{
u16 vid, did;
nand_cmd(CMD_READID);
nand_addr(0);
vid = nand_data8();
did = nand_data8();
return (vid << 16) | did;
}
/*
* Read oob data for 512B pagesize.
*/
static void read_oob_512(void *buf, u32 oobsize, u32 pg)
{
int i;
u32 rowaddr;
rowaddr = pg;
nand_cmd(0x50);
nand_addr(0);
for (i = 0; i < row; i++) {
nand_addr(rowaddr & 0xff);
rowaddr >>= 8;
}
nand_wait_ready();
read_proc(buf, oobsize);
}
/*
* Read oob data for 2KB pagesize.
*/
static void read_oob_2048(u8 *buf, u32 oobsize, u32 pg)
{
u32 i, coladdr, rowaddr;
coladdr = 2048;
rowaddr = pg;
nand_cmd(CMD_READA);
nand_addr(coladdr & 0xff);
nand_addr(coladdr >> 8);
for (i = 0; i < row; i++) {
nand_addr(rowaddr & 0xff);
rowaddr >>= 8;
}
nand_cmd(CMD_CONFIRM);
nand_wait_ready();
read_proc(buf, oobsize);
}
/*
* Read oob data.
*/
static void read_oob(u8 *buf, int oobsize, int pg)
{
if (pagesize == 2048)
read_oob_2048(buf, oobsize, pg);
else
read_oob_512(buf, oobsize, pg);
}
/*
* Return 1 if the block is bad block, else return 0.
*/
int nand_check_block(u32 block)
{
u32 pg;
// pg = block * ppb;
pg = block * ppb + bad_block_page;
//bad block ID locate No.bad_block_page
read_oob(oobbuf, oobsize, pg);
if (oobbuf[bad_block_pos] != 0xff)
return -1;
read_oob(oobbuf, oobsize, pg + 1);
if (oobbuf[bad_block_pos] != 0xff)
return -1;
return 0;
}
/*
* Mark a block bad.
*/
void nand_block_markbad(u32 block)
{
u32 i, rowaddr;
for (i = 0; i < pagesize + oobsize; i++)
badbuf[i] = 0xff;
badbuf[pagesize + bad_block_pos] = 0; /* bad block flag */
rowaddr = block * ppb + bad_block_page;
//bad block ID locate No.bad_block_page
nand_cmd(CMD_READA);
nand_cmd(CMD_SEQIN);
nand_addr(0);
if (pagesize == 2048)
nand_addr(0);
for (i = 0; i < row; i++) {
nand_addr(rowaddr & 0xff);
rowaddr >>= 8;
}
write_proc((unsigned char *)badbuf, pagesize + oobsize);
nand_cmd(CMD_PGPROG);
nand_wait_ready();
}
/*
* Erase <blk_num> blocks from block <sblk>.
*/
int nand_erase_4730(int blk_num, int sblk, int force)
{
int i, cnt;
u32 cur_blk, rowaddr;
force = 0;
/* Send reset command to nand */
nand_cmd(CMD_RESET);
nand_wait_ready();
cur_blk = sblk;
cnt = 0;
while (cnt < blk_num) {
/*
* if force flag was not set, check for bad block.
* if force flag was set, erase anything.
*/
#if 1
//we do force erase for ever??
if (!force) {
if (nand_check_block(cur_blk)) {
cur_blk ++; /* Bad block, set to next block */
continue;
}
}
#endif
nand_cmd(CMD_ERASE_SETUP);
rowaddr = cur_blk * ppb;
for (i = 0; i < row; i++) {
nand_addr(rowaddr & 0xff);
rowaddr >>= 8;
}
nand_cmd(CMD_ERASE);
nand_wait_ready();
nand_cmd(CMD_READ_STATUS);
nand_wait_ready();
if (nand_data8() & 0x01) {
/* Erase Error, mark it as bad block */
nand_block_markbad(cur_blk);
} else {
/* Erase OK */
cnt++;
}
cur_blk++;
}
return 0;
}
/*
* Do nand hw ecc correction.
*/
int nand_hw_ecc_correct(u8 *buf, u8 *stored_ecc, u8 *calc_ecc, int eccblock)
{
u32 i, j, ecc_bit,a,b,c,tmp;
int res = 0;
for (i = 0; i < eccblock; i++) {
a=stored_ecc[oob_pos->eccpos[i*3+0]] ^ calc_ecc[i*4+0];
b=stored_ecc[oob_pos->eccpos[i*3+1]] ^ calc_ecc[i*4+1];
c=stored_ecc[oob_pos->eccpos[i*3+2]] ^ calc_ecc[i*4+2];
tmp = (c<<16) + (b<<8) +a;
#if 0
printf("AAAAAAAA %x %x %x : %x %x %x %x\n",
stored_ecc[oob_pos->eccpos[i*3+0]],
stored_ecc[oob_pos->eccpos[i*3+1]],
stored_ecc[oob_pos->eccpos[i*3+2]],
calc_ecc[i*4+0],
calc_ecc[i*4+1],
calc_ecc[i*4+2],
tmp);
#endif
if (tmp) { /* ECC error */
ecc_bit = 0;
for (j = 0; j < 24; j++)
if ((tmp >> j) & 0x01)
ecc_bit ++;
if (ecc_bit == 11) { /* Correctable error */
u8 idx;
ecc_bit = 0;
for (j = 12; j >= 1; j--) {
ecc_bit <<= 1;
ecc_bit |= ((tmp >> (j*2-1)) & 0x01);
}
idx = ecc_bit & 0x07;
buf[i * ECC_BLOCK + (ecc_bit >> 3)] ^= (1 << idx);
}
else { /* Fatal error */
//if ecc all ff means this page no data!
if (stored_ecc[oob_pos->eccpos[i*3+0]]==0xff
&&stored_ecc[oob_pos->eccpos[i*3+1]]==0xff
&&stored_ecc[oob_pos->eccpos[i*3+2]]==0xff )
return res;
// printf("Uncorrectable ecc error!\n");
res = -1;
}
}
}
return res;
}
/*
* Read data <pagenum> pages from <startpage> page.
* Skip bad block if detected.
* HW ECC is used.
*/
int nand_read_4730(u8 *buf, u32 startpage, u32 pagenum)
{
u32 cnt, i;
u32 cur_page, rowaddr, eccblock;
u32 calc_ecc[8];
u8 *tmpbuf,*stored_ecc;
eccblock = pagesize / ECC_BLOCK;
cur_page = startpage;
cnt = 0;
while (cnt < pagenum) {
//we do not check bad block here!
#if 0
if ((cur_page % ppb) == 0) {
cur_blk = cur_page / ppb;
if (nand_check_block(cur_blk)) {
cur_page += ppb; /* Bad block, set to next block */
continue;
}
}
#endif
nand_cmd(CMD_READA);
nand_addr(0);
if (pagesize == 2048)
nand_addr(0);
rowaddr = cur_page;
for (i = 0; i < row; i++) {
nand_addr(rowaddr & 0xff);
rowaddr >>= 8;
}
if (pagesize == 2048)
nand_cmd(CMD_CONFIRM);
nand_wait_ready();
tmpbuf = (u8 *)((u32)buf + cnt * (pagesize + oobsize));
for (i = 0; i < eccblock; i++) {
nand_ecc_enable();
read_proc(tmpbuf, ECC_BLOCK);
nand_ecc_disable();
calc_ecc[i] = nand_ecc();
if (oob_pos->eccname == LINUXHM)
calc_ecc[i] = ~(calc_ecc[i]) | 0x00030000;
tmpbuf += ECC_BLOCK;
}
read_proc((u8 *)tmpbuf, oobsize);
tmpbuf = (u8 *)((u32)buf + cnt * (pagesize + oobsize));
//read ecc from oob
stored_ecc = (u8 *)(((u32)tmpbuf) + pagesize );
/* Check ECC */
nand_hw_ecc_correct(tmpbuf, stored_ecc, (u8 *)calc_ecc, eccblock);
cur_page++;
cnt++;
}
return 0;
}
/*
* Read data <pagenum> pages from <startpage> page.
* Don't skip bad block.
* Don't use HW ECC.
*/
int nand_read_raw_4730(u8 *buf, u32 startpage, u32 pagenum)
{
u32 cnt, i;
u32 cur_page, rowaddr;
u8 *tmpbuf;
tmpbuf = (u8 *)buf;
cur_page = startpage;
cnt = 0;
while (cnt < pagenum) {
nand_cmd(CMD_READA);
nand_addr(0);
if (pagesize == 2048)
nand_addr(0);
rowaddr = cur_page;
for (i = 0; i < row; i++) {
nand_addr(rowaddr & 0xff);
rowaddr >>= 8;
}
if (pagesize == 2048)
nand_cmd(CMD_CONFIRM);
nand_wait_ready();
read_proc(tmpbuf, pagesize);
tmpbuf += pagesize;
cur_page++;
cnt++;
}
return 0;
}
/*
* Read oob <pagenum> pages from <startpage> page.
* Don't skip bad block.
* Don't use HW ECC.
*/
int nand_read_oob_4730(u8 *buf, u32 startpage, u32 pagenum)
{
u32 cnt, cur_page;
u8 *tmpbuf;
tmpbuf = (u8 *)buf;
cur_page = startpage;
cnt = 0;
while (cnt < pagenum) {
read_oob((void *)tmpbuf, oobsize, cur_page);
tmpbuf += oobsize;
cur_page++;
cnt++;
}
return 0;
}
/*
* Write <pagenum> pages from <startpage> page.
* Skip bad block if detected.
*/
int nand_program_4730(u8 *buf, int startpage, int pagenum)
{
u32 cnt, i,j;
u32 cur_page, rowaddr, eccblock;
u8 *tmpbuf;
tmpbuf = (u8 *)buf;
eccblock = pagesize / ECC_BLOCK;
cur_page = startpage;
cnt = 0;
while (cnt < pagenum) {
//do not check bad block here! check uplayer!
for (j=0;j<np->os;j++)
{
if (tmpbuf[j+np->ps]!=0xff)
break;
}
if (j==np->os)
{
tmpbuf += np->ps+np->os;
cur_page ++;
cnt ++;
continue;
}
// nand_wait_ready();
nand_cmd(CMD_READA);
nand_cmd(CMD_SEQIN);
nand_addr(0);
if (pagesize == 2048)
nand_addr(0);
rowaddr = cur_page;
for (i = 0; i < row; i++) {
nand_addr(rowaddr & 0xff);
rowaddr >>= 8;
}
/* Write out data and oob*/
// we don't need work out ecc
//because it already exist in image file
write_proc(tmpbuf, np->ps+np->os);
tmpbuf += np->ps+np->os;
nand_cmd(CMD_PGPROG);
nand_wait_ready();
nand_cmd(CMD_READ_STATUS);
// nand_wait_ready();
if (nand_data8() & 0x01) {
/* Page program error.
* Note: we should mark this block bad, and copy data of this
* block to a new block.
*/
;
} else {
;
}
cur_page ++;
cnt ++;
}
return cnt;
}

View File

@ -1,734 +0,0 @@
/*
* Common NAND Flash operations for JZ4740.
*
* This software is free.
*/
#include "jz4740.h"
#include "include.h"
extern struct nand_oobinfo oob_64[];
#define __nand_enable() (REG_EMC_NFCSR |= EMC_NFCSR_NFE1 | EMC_NFCSR_NFCE1)
#define __nand_disable() (REG_EMC_NFCSR &= ~(EMC_NFCSR_NFCE1|EMC_NFCSR_NFE1 ))
#define __nand_ecc_rs_encoding() (REG_EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_ERST | EMC_NFECR_RS | EMC_NFECR_RS_ENCODING)
#define __nand_ecc_rs_decoding() (REG_EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_ERST | EMC_NFECR_RS | EMC_NFECR_RS_DECODING)
#define __nand_ecc_disable() (REG_EMC_NFECR &= ~EMC_NFECR_ECCE)
#define __nand_ecc_encode_sync() while (!(REG_EMC_NFINTS & EMC_NFINTS_ENCF))
#define __nand_ecc_decode_sync() while (!(REG_EMC_NFINTS & EMC_NFINTS_DECF))
#define __nand_ecc_enable() (REG_EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_ERST )
#define __nand_ecc_disable() (REG_EMC_NFECR &= ~EMC_NFECR_ECCE)
#define __nand_select_hm_ecc() (REG_EMC_NFECR &= ~EMC_NFECR_RS )
#define __nand_select_rs_ecc() (REG_EMC_NFECR |= EMC_NFECR_RS)
#define __nand_read_hm_ecc() (REG_EMC_NFECC & 0x00ffffff)
#define __nand_ecc() (REG_EMC_NFECC & 0x00ffffff)
#define __nand_cmd(n) (REG8(cmdport+csn) = (n))
#define __nand_addr(n) (REG8(addrport+csn) = (n))
#define __nand_data8() REG8(dataport+csn)
#define __nand_data16() REG16(dataport+csn)
#define CMD_READA 0x00
#define CMD_READB 0x01
#define CMD_READC 0x50
#define CMD_ERASE_SETUP 0x60
#define CMD_ERASE 0xD0
#define CMD_READ_STATUS 0x70
#define CMD_CONFIRM 0x30
#define CMD_SEQIN 0x80
#define CMD_PGPROG 0x10
#define CMD_READID 0x90
#define OOB_BAD_OFF 0x00
#define OOB_ECC_OFF 0x04
#define OP_ERASE 0
#define OP_WRITE 1
#define OP_READ 2
#define ECC_BLOCK 512
#define ECC_POS 6
#define PAR_SIZE 9
static volatile unsigned char *gpio_base;
static volatile unsigned char *emc_base;
static volatile unsigned char *addrport;
static volatile unsigned char *dataport;
static volatile unsigned char *cmdport;
unsigned int EMC_BASE;
unsigned int GPIO_BASE;
static int bus = 8, row = 2, pagesize = 512, oobsize = 16, ppb = 32;
static u32 bad_block_pos = 0,bad_block_page=0, csn = 0;
static u8 badbuf[2048 + 64] = {0};
static u8 data_buf[2048] = {0};
static u8 oob_buf[128] = {0};
static struct nand_oobinfo *oob_pos;
static np_data *np;
static inline void __nand_sync(void)
{
unsigned int timeout = 1000;
while ((REG_GPIO_PXPIN(2) & 0x40000000) && timeout--);
while (!(REG_GPIO_PXPIN(2) & 0x40000000));
}
static int read_oob(u8 *buf, u32 size, u32 pg);
static int nand_data_write8(unsigned char *buf, int count);
static int nand_data_write16(unsigned char *buf, int count);
static int nand_data_read8(unsigned char *buf, int count);
static int nand_data_read16(unsigned char *buf, int count);
static int (*write_proc)(unsigned char *, int) = 0;
static int (*read_proc)(unsigned char *, int) = 0;
extern void dumpbuf(u8 *p, int count);
unsigned int nand_query_4740(void)
{
u16 vid, did;
__nand_sync();
__nand_cmd(CMD_READID);
__nand_addr(0);
vid = __nand_data8();
did = __nand_data8();
return (vid << 16) | did;
}
int chip_select_4740(u8 cs)
{
csn = (u32)cs << 15; // modify this number for your board
return 0;
}
int nand_init_4740(np_data *npp)
{
bus = npp->bw;
row = npp->rc;
pagesize = npp->ps;
oobsize = npp->os;
ppb = npp->ppb;
bad_block_pos = npp->bbp;
bad_block_page = npp->bba;
gpio_base = (u8 *)npp->gpio_map;
emc_base = (u8 *)npp->base_map;
dataport = (u8 *)npp->port_map;
addrport = (u8 *)((u32)dataport + npp->ap_offset);
cmdport = (u8 *)((u32)dataport + npp->cp_offset);
EMC_BASE = (u32)emc_base;
GPIO_BASE = (u32)gpio_base;
/* Initialize NAND Flash Pins */
// __gpio_as_nand();
// __nand_enable();
chip_select_4740(npp->cs);
if (bus == 8) {
write_proc = nand_data_write8;
read_proc = nand_data_read8;
} else {
write_proc = nand_data_write16;
read_proc = nand_data_read16;
}
oob_pos = &oob_64[npp->ep];
// REG_EMC_SMCR1 = 0x0fff7700;
np = npp;
return 0;
}
int nand_fini_4740(void)
{
__nand_disable();
return 0;
}
/*
* Read oob <pagenum> pages from <startpage> page.
* Don't skip bad block.
* Don't use HW ECC.
*/
int nand_read_oob_4740(u8 *buf, u32 startpage, u32 pagenum)
{
u32 cnt, cur_page;
u8 *tmpbuf;
tmpbuf = (u8 *)buf;
cur_page = startpage;
cnt = 0;
while (cnt < pagenum) {
read_oob((void *)tmpbuf, oobsize, cur_page);
tmpbuf += oobsize;
cur_page++;
cnt++;
}
return 0;
}
int nand_check_block_4740(u32 block)
{
u32 pg;
pg = block * ppb + bad_block_page;
read_oob(oob_buf, oobsize, pg);
if (oob_buf[bad_block_pos] != 0xff)
return -1;
read_oob(oob_buf, oobsize, pg + 1);
if (oob_buf[bad_block_pos] != 0xff)
return -1;
return 0;
}
/*
* Mark a block bad.
*/
void nand_block_markbad_4740(u32 block)
{
u32 i, rowaddr;
for (i = 0; i < pagesize + oobsize; i++)
badbuf[i] = 0x00;
badbuf[pagesize + bad_block_pos] = 0; /* bad block flag */
rowaddr = block * ppb + bad_block_page;
//bad block ID locate No.bad_block_page page
__nand_cmd(CMD_READA);
__nand_cmd(CMD_SEQIN);
__nand_addr(0);
if (pagesize == 2048)
__nand_addr(0);
for (i = 0; i < row; i++) {
__nand_addr(rowaddr & 0xff);
rowaddr >>= 8;
}
write_proc((unsigned char *)badbuf, pagesize + oobsize);
__nand_cmd(CMD_PGPROG);
__nand_sync();
}
/*
* Read data <pagenum> pages from <startpage> page.
* Don't skip bad block.
* Don't use HW ECC.
*/
int nand_read_raw_4740(u8 *buf, u32 startpage, u32 pagenum)
{
u32 cnt, j;
u32 cur_page, rowaddr;
u8 *tmpbuf;
tmpbuf = (u8 *)buf;
cur_page = startpage;
cnt = 0;
while (cnt < pagenum) {
__nand_sync();
__nand_cmd(CMD_READA);
__nand_addr(0);
if (pagesize == 2048)
__nand_addr(0);
rowaddr = cur_page;
for (j = 0; j < row; j++) {
__nand_addr(rowaddr & 0xff);
rowaddr >>= 8;
}
if (pagesize == 2048)
__nand_cmd(CMD_CONFIRM);
__nand_sync();
read_proc(tmpbuf, pagesize);
tmpbuf += pagesize;
cur_page++;
cnt++;
}
return 0;
}
int nand_erase_4740(int blk_num, int sblk, int force)
{
int i, j;
u32 cur, rowaddr;
cur = sblk * ppb;
for (i = 0; i < blk_num; i++) {
rowaddr = cur;
if (!force) { /* if set, erase anything */
/* test Badflag. */
__nand_sync();
__nand_cmd(CMD_READA);
__nand_addr(0);
if (pagesize == 2048)
__nand_addr(0);
for (j=0;j<row;j++) {
__nand_addr(rowaddr & 0xff);
rowaddr >>= 8;
}
if (pagesize == 2048)
__nand_cmd(CMD_CONFIRM);
__nand_sync();
read_proc((u8 *)data_buf, pagesize);
read_proc((u8 *)oob_buf, oobsize);
if (oob_buf[0] != 0xff) { /* Bad block, skip */
cur += ppb;
continue;
}
rowaddr = cur;
}
__nand_cmd(CMD_ERASE_SETUP);
for (j = 0; j < row; j++) {
__nand_addr(rowaddr & 0xff);
rowaddr >>= 8;
}
__nand_cmd(CMD_ERASE);
__nand_sync();
__nand_cmd(CMD_READ_STATUS);
if (__nand_data8() & 0x01)
{
/* Erase Error, mark it as bad block */
nand_block_markbad(cur);
} else ;
cur += ppb;
}
return 0;
}
static int read_oob(u8 *buf, u32 size, u32 pg)
{
u32 i, coladdr, rowaddr;
if (pagesize == 512)
coladdr = 0;
else
coladdr = pagesize;
if (pagesize == 512)
/* Send READOOB command */
__nand_cmd(CMD_READC);
else
/* Send READ0 command */
__nand_cmd(CMD_READA);
/* Send column address */
__nand_addr(coladdr & 0xff);
if (pagesize != 512)
__nand_addr(coladdr >> 8);
/* Send page address */
rowaddr = pg;
for (i = 0; i < row; i++) {
__nand_addr(rowaddr & 0xff);
rowaddr >>= 8;
}
/* Send READSTART command for 2048 ps NAND */
if (pagesize != 512)
__nand_cmd(CMD_CONFIRM);
/* Wait for device ready */
__nand_sync();
/* Read oob data */
read_proc(buf, size);
return 0;
}
/* Correct 1~9-bit errors in 512-bytes data */
static void rs_correct(unsigned char *dat, int idx, int mask)
{
int i;
idx--;
i = idx + (idx >> 3);
if (i >= 512)
return;
mask <<= (idx & 0x7);
dat[i] ^= mask & 0xff;
if (i < 511)
dat[i+1] ^= (mask >> 8) & 0xff;
}
static int nand_hm_correct_data(u8 *dat, u8 *oob_s, u8 *calc_ecc,u8 p)
{
u8 a, b, c, d1, d2, d3, add, bit, i;
u8 *e1,*e2,*e3;
e1 = &oob_s[oob_pos->eccpos[p+0]];
e2 = &oob_s[oob_pos->eccpos[p+1]];
e3 = &oob_s[oob_pos->eccpos[p+2]];
// printf("read ecc :%x %x %x %d %d\n",*e1,*e2,*e3,
// oob_pos->eccpos[p+0],oob_pos->eccpos[p+1]);
d1 = calc_ecc[0] ^ *e1;
d2 = calc_ecc[1] ^ *e2;
d3 = calc_ecc[2] ^ *e3;
if ((d1 | d2 | d3) == 0) {
/* No errors */
return 0;
}
else {
a = (d1 ^ (d1 >> 1)) & 0x55;
b = (d2 ^ (d2 >> 1)) & 0x55;
c = (d3 ^ (d3 >> 1)) & 0x54;
/* Found and will correct single bit error in the data */
if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
c = 0x80;
add = 0;
a = 0x80;
for (i=0; i<4; i++) {
if (d1 & c)
add |= a;
c >>= 2;
a >>= 1;
}
c = 0x80;
for (i=0; i<4; i++) {
if (d2 & c)
add |= a;
c >>= 2;
a >>= 1;
}
bit = 0;
b = 0x04;
c = 0x80;
for (i=0; i<3; i++) {
if (d3 & c)
bit |= b;
c >>= 2;
b >>= 1;
}
b = 0x01;
a = dat[add];
a ^= (b << bit);
dat[add] = a;
return 0;
}
else {
i = 0;
while (d1) {
if (d1 & 0x01)
++i;
d1 >>= 1;
}
while (d2) {
if (d2 & 0x01)
++i;
d2 >>= 1;
}
while (d3) {
if (d3 & 0x01)
++i;
d3 >>= 1;
}
if (i == 1) {
/* ECC Code Error Correction */
*e1 = calc_ecc[0];
*e2 = calc_ecc[1];
*e3 = calc_ecc[2];
return 0;
}
else {
/* Uncorrectable Error */
// printf("uncorrectable ECC error\n");
return -1;
}
}
}
/* Should never happen */
return -1;
}
/*
* Read data <pagenum> pages from <startpage> page.
* HW ECC is used.
*/
int nand_read_4740_hm(u8 *buf, u32 startpage, u32 pagenum)
{
u32 j, calc_ecc;
u32 cur_page, cnt, rowaddr, ecccnt;
u8 *tmpbuf;
ecccnt = pagesize / 256;
cur_page = startpage;
cnt = 0;
while (cnt < pagenum) {
/* read oob first */
read_oob(oob_buf, oobsize, cur_page);
__nand_sync();
__nand_cmd(CMD_READA);
__nand_addr(0);
if (pagesize == 2048)
__nand_addr(0);
rowaddr = cur_page;
for (j = 0; j < row; j++) {
__nand_addr(rowaddr & 0xff);
rowaddr >>= 8;
}
if (pagesize == 2048)
__nand_cmd(CMD_CONFIRM);
__nand_sync();
tmpbuf = (u8 *)((u32)buf + cnt * ( pagesize+oobsize));
for (j = 0; j < ecccnt ; j++)
{
__nand_ecc_enable();
__nand_select_hm_ecc();
read_proc(tmpbuf, 256);
__nand_ecc_disable();
calc_ecc = __nand_read_hm_ecc();
if (oob_pos->eccname == LINUXHM)
calc_ecc = ~calc_ecc | 0x00030000;
nand_hm_correct_data(tmpbuf,oob_buf,(u8*)&calc_ecc,j*3);
tmpbuf += 256;
}
for (j = 0; j < oobsize; j++)
tmpbuf[j] = oob_buf[j];
cur_page++;
cnt++;
}
return 0;
}
/*
* Read data <pagenum> pages from <startpage> page.
* HW ECC is used.
*/
int nand_read_4740_rs(u8 *buf, u32 startpage, u32 pagenum)
{
u32 j, k;
u32 cur_page, cnt, rowaddr, ecccnt;
u8 *tmpbuf;
ecccnt = pagesize / ECC_BLOCK;
cur_page = startpage;
cnt = 0;
while (cnt < pagenum) {
/* read oob first */
read_oob(oob_buf, oobsize, cur_page);
__nand_sync();
__nand_cmd(CMD_READA);
__nand_addr(0);
if (pagesize == 2048)
__nand_addr(0);
rowaddr = cur_page;
for (j = 0; j < row; j++) {
__nand_addr(rowaddr & 0xff);
rowaddr >>= 8;
}
if (pagesize == 2048)
__nand_cmd(CMD_CONFIRM);
__nand_sync();
tmpbuf = (u8 *)((u32)buf + cnt * ( pagesize+oobsize));
for (j = 0; j < ecccnt ; j++) {
volatile u8 *paraddr = (volatile u8 *)EMC_NFPAR0;
u32 stat;
/* Read data */
REG_EMC_NFINTS = 0x0;
__nand_ecc_rs_decoding();
read_proc(tmpbuf, ECC_BLOCK);
/* Set PAR values */
for (k = 0; k < PAR_SIZE; k++) {
*paraddr++ = oob_buf[oob_pos->eccpos[j*PAR_SIZE + k]];
}
/* Set PRDY */
REG_EMC_NFECR |= EMC_NFECR_PRDY;
/* Wait for completion */
__nand_ecc_decode_sync();
__nand_ecc_disable();
/* Check decoding */
stat = REG_EMC_NFINTS;
if (stat & EMC_NFINTS_ERR) {
// printf("Error occured!\n");
if (stat & EMC_NFINTS_UNCOR) {
int t;
for (t = 0; t < oob_pos->eccbytes; t++)
if (oob_buf[oob_pos->eccpos[t]] != 0xff) break;
if (t < oob_pos->eccbytes-1) {
// printf("Uncorrectable error occurred\n");
}
}
else {
u32 errcnt = (stat & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT;
switch (errcnt) {
case 4:
rs_correct(tmpbuf, (REG_EMC_NFERR3 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT, (REG_EMC_NFERR3 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT);
case 3:
rs_correct(tmpbuf, (REG_EMC_NFERR2 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT, (REG_EMC_NFERR2 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT);
case 2:
rs_correct(tmpbuf, (REG_EMC_NFERR1 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT, (REG_EMC_NFERR1 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT);
case 1:
rs_correct(tmpbuf, (REG_EMC_NFERR0 & EMC_NFERR_INDEX_MASK) >> EMC_NFERR_INDEX_BIT, (REG_EMC_NFERR0 & EMC_NFERR_MASK_MASK) >> EMC_NFERR_MASK_BIT);
break;
default:
break;
}
}
}
/* increment pointer */
tmpbuf += ECC_BLOCK ;
}
for (j = 0; j < oobsize; j++)
tmpbuf[j] = oob_buf[j];
cur_page++;
cnt++;
}
return 0;
}
int nand_program_4740(u8 *context, int spage, int pages)
{
u32 i, j, cur, rowaddr;
u8 *tmpbuf;
tmpbuf = (u8 *)context;
i = 0;
cur = spage;
while (i < pages) {
for (j=0;j<np->os;j++)
{
if (tmpbuf[j+np->ps]!=0xff)
break;
}
if (j==np->os)
{
tmpbuf += np->ps+np->os;
i ++;
cur ++;
continue;
}
if (pagesize != 2048)
__nand_cmd(CMD_READA);
__nand_cmd(CMD_SEQIN);
__nand_addr(0);
if (pagesize == 2048)
__nand_addr(0);
rowaddr = cur;
for (j = 0; j < row; j++) {
__nand_addr(rowaddr & 0xff);
rowaddr >>= 8;
}
write_proc(tmpbuf, np->ps+np->os);
tmpbuf += np->ps+np->os;
/* send program confirm command */
__nand_cmd(CMD_PGPROG);
__nand_sync();
__nand_cmd(CMD_READ_STATUS);
// __nand_sync();
if (__nand_data8() & 0x01) { /* page program error */
return -1;
} else ;
i ++;
cur ++;
}
return 0;
}
static int nand_data_write8(unsigned char *buf, int count)
{
int i;
u8 *p = (u8 *)buf;
for (i=0;i<count;i++)
__nand_data8() = *p++;
return 0;
}
static int nand_data_write16(unsigned char *buf, int count)
{
int i;
u16 *p = (u16 *)buf;
for (i=0;i<count/2;i++)
__nand_data16() = *p++;
return 0;
}
static int nand_data_read8(unsigned char *buf, int count)
{
int i;
u8 *p = (u8 *)buf;
for (i=0;i<count;i++)
*p++ = __nand_data8();
return 0;
}
static int nand_data_read16(unsigned char *buf, int count)
{
int i;
u16 *p = (u16 *)buf;
for (i=0;i<count/2;i++)
*p++ = __nand_data16();
return 0;
}

View File

@ -1,283 +0,0 @@
#!/bin/sh
# 6410 SD Boot formatter
# (C) 2008 Openmoko, Inc
# Author: Andy Green <andy@openmoko.com>
# LAYOUT (if partition parameter is not specified)
# Partition table, then
# VFAT takes up remaining space here
# then...
#
EXT3_ROOTFS_SECTORS=$(( 256 * 1024 * 2 ))
EXT3_BACKUP_FS_SECTORS=$(( 8 * 1024 * 2 ))
QI_ALLOCATION=$(( 256 * 2 ))
#
# lastly fixed stuff: 8KByte initial boot, sig, padding
#
# ----------------------
echo "s3c6410 bootable SD partitioning utility"
echo "(C) Openmoko, Inc Andy Green <andy@openmoko.com>"
echo
# these are fixed in iROM
QI_INITIAL=$(( 8 * 2 ))
SIG=1
# display usage message and exit
# any arguments are displayed as an error message
USAGE()
{
echo
[ -z "$1" ] || echo ERROR: $*
echo
echo 'This formats a SD card for usage on SD Card boot'
echo ' on 6410 based systems'
echo
echo Usage: $(basename "$0") '<device> <card> <bootloader> <partition>'
echo ' device = disk device name for SD Card, e.g. sde /dev/sdf'
echo ' card = sd | sdhc'
echo ' bootloader = /path/to/qi-binary'
echo ' partition = vfat | NN | NN,NN | NN,NN,NN | NN,NN,NN,NN | no'
echo ' * vfat -> main-vfat[rest] + rootfs[256M] + backupfs[8M]'
echo ' NN -> rootfs1[NN%] + .. + rootfs4[NN%]'
echo ' NN=0 -> will skip the partition'
echo ' no -> leave partitions alone'
echo
echo 'Note: * => default action if no parameter specified'
echo ' sum(NN) must be in [1..100]'
echo
echo 'e.g. '$(basename "$0")' sdb sdhc images/qi 0,30,0,45'
echo ' will format an SDHC with partition 2 receiving 20% and partition 4'
echo ' receiving 45% of the disk capacity and the remaining 35% will be'
echo ' unused.'
echo ' Capacity is calculated after subtracting the space reserved for Qi.'
echo ' Partitions 1 and 3 will not be used.'
exit 1
}
[ -z "$1" -o -z "$2" -o -z "$3" ] && USAGE 'Missing arguments'
dev="$1"
card="$2"
qi="$3"
partition="$4"
case "${card}" in
[sS][dD][hH][cC])
PADDING=1025
;;
[sS][dD])
PADDING=1
;;
*)
USAGE "${card} is an unknown card type"
esac
# the amount of space that must remain unused at the end of the disk
REAR_SECTORS=$(( $QI_ALLOCATION + $QI_INITIAL + $SIG + $PADDING ))
# validate parameters
[ -b "${dev}" ] || dev="/dev/${dev}"
[ -b "${dev}" ] || USAGE "${dev} is not a valid block device"
[ X"${dev}" = X"${dev%%[0-9]}" ] || USAGE "${dev} is a partition, please use device: perhaps ${dev%%[0-9]}"
echo "Checking for mounted partitions..."
grep "${dev}" /proc/mounts && USAGE "partitions on ${dev} are mounted, please unmount them"
[ -e "${qi}" ] || USAGE "bootloader file: ${qi} does not exist"
# get size of device
bytes=$(echo p | fdisk "${dev}" 2>&1 | sed '/^Disk.*, \([0-9]*\) bytes/s//\1/p;d')
SECTORS=$(($bytes / 512))
[ -z "$SECTORS" ] && USAGE "could not find size for ${dev}"
[ "$SECTORS" -le 0 ] && USAGE "invalid size: '${SECTORS}' for ${dev}"
echo "${dev} is $SECTORS 512-byte blocks"
# Partition and format a disk (or SD card)
# Parameters to format function are:
#
# device -> device to partition e.g. /dev/sdX
#
# Partition 1 parameters:
#
# label -> file system volume label e.g. rootfs
# sizeMB -> size of the partition in MB e.g. 256
# fstype -> filesystem type e.g. ext2, ext3, vfat (look at /sbin/mkfs.* for others)
#
# Notes: 1. Repeat "label, sizeMB, fstype" for partitions 2..4
# 2. Partitions 2..4 are optional
# 3. Do not repeat device parameter
# 4. To skip a partition use: 'null 0 none' for that partition
FORMAT()
{
local device label sizeMB fstype p partition flag skip
device="$1"; shift
(
p=0
flag=0
echo o
while [ $# -gt 0 ]
do
label="$1"; shift
sizeMB="$1"; shift
fstype="$1"; shift
p=$((${p} + 1))
skip=NO
[ ${sizeMB} -le 0 ] && skip=YES
case "${label}" in
[nN][uU][lL][lL])
skip=YES
;;
*)
;;
esac
case "${skip}" in
[yY][eE][sS]|[yY])
;;
*)
echo n
echo p
echo ${p}
echo
echo +${sizeMB}M
case "${fstype}" in
[vV][fF][aA][tT]|[mM][sS][dD][oO][sS])
echo t
# fdisk is "helpful" & will auto select partition if there is only one
# so do not output partition number if this is the first partition
[ "${flag}" -eq 1 ] && echo ${p}
echo 0b
;;
*)
;;
esac
flag=1
;;
esac
done
echo p
echo w
echo q
) | fdisk "${device}"
p=0
while [ $# -gt 0 ]
do
label="$1"; shift
sizeMB="$1"; shift
fstype="$1"; shift
p=$((${p} + 1))
partition="${dev}${p}"
skip=NO
[ ${sizeMB} -eq 0 ] && skip=YES
case "${label}" in
[nN][uU][lL][lL])
skip=YES
;;
esac
case "${skip}" in
[yY][eE][sS]|[yY])
echo "Skipping: ${partition}"
;;
*)
echo "Formatting: ${partition} -> ${fstype}[${sizeMB}MB]"
case "${fstype}" in
[vV][fF][aA][tT]|[mM][sS][dD][oO][sS])
mkfs.${fstype} -n "${label}" "${partition}"
;;
*)
mkfs.${fstype} -L "${label}" "${partition}"
;;
esac
;;
esac
done
}
# format the disk
case "${partition}" in
# this case also hadles the default case (i.e. empty string: "")
[vV][fF][aA][tT]|"")
EXT3_TOTAL_SECTORS=$(( $EXT3_ROOTFS_SECTORS + $EXT3_BACKUP_FS_SECTORS ))
FAT_SECTORS=$(( $SECTORS - $EXT3_TOTAL_SECTORS - $REAR_SECTORS ))
FAT_MB=$(( $FAT_SECTORS / 2048 ))
EXT3_ROOTFS_MB=$(( ${EXT3_ROOTFS_SECTORS} / 2048 ))
EXT3_BACKUP_FS_MB=$(( ${EXT3_BACKUP_FS_SECTORS} / 2048 ))
echo Creating VFAT partition of ${FAT_MB} MB
echo Creating Linux partition of ${EXT3_ROOTFS_MB} MB
echo Creating backup Linux partition of ${EXT3_BACKUP_FS_MB} MB
FORMAT "${dev}" \
main-vfat "${FAT_MB}" vfat \
rootfs "${EXT3_ROOTFS_MB}" ext3 \
backupfs "${EXT3_BACKUP_FS_MB}" ext3
;;
# decode partition or partition list
*,*|100|[1-9][0-9]|[1-9])
arg="${partition},"
for v in 1 2 3 4
do
eval n${v}="\${arg%%,*}"
eval n${v}="\${n${v}:-0}"
arg="${arg#*,},"
done
total=$(( ${n1} + ${n2} + ${n3} + ${n4} ))
echo Percentage of disk partitioned = ${total}%
[ ${total} -gt 100 -o ${total} -lt 1 ] && USAGE partition: "'${partition}' => ${total}% outside [1..100]"
EXT3_TOTAL_SECTORS=$(( $SECTORS - $REAR_SECTORS ))
EXT3_ROOTFS1_SECTORS=$(( $EXT3_TOTAL_SECTORS * $n1 / 100 ))
EXT3_ROOTFS2_SECTORS=$(( $EXT3_TOTAL_SECTORS * $n2 / 100 ))
EXT3_ROOTFS3_SECTORS=$(( $EXT3_TOTAL_SECTORS * $n3 / 100 ))
EXT3_ROOTFS4_SECTORS=$(( $EXT3_TOTAL_SECTORS * $n4 / 100 ))
EXT3_ROOTFS1_MB=$(( ${EXT3_ROOTFS1_SECTORS} / 2048 ))
EXT3_ROOTFS2_MB=$(( ${EXT3_ROOTFS2_SECTORS} / 2048 ))
EXT3_ROOTFS3_MB=$(( ${EXT3_ROOTFS3_SECTORS} / 2048 ))
EXT3_ROOTFS4_MB=$(( ${EXT3_ROOTFS4_SECTORS} / 2048 ))
echo Creating Linux partition 1 of ${EXT3_ROOTFS1_MB} MB
echo Creating Linux partition 2 of ${EXT3_ROOTFS2_MB} MB
echo Creating Linux partition 3 of ${EXT3_ROOTFS3_MB} MB
echo Creating Linux partition 4 of ${EXT3_ROOTFS4_MB} MB
FORMAT "${dev}" \
rootfs1 "${EXT3_ROOTFS1_MB}" ext3 \
rootfs2 "${EXT3_ROOTFS2_MB}" ext3 \
rootfs3 "${EXT3_ROOTFS3_MB}" ext3 \
rootfs4 "${EXT3_ROOTFS4_MB}" ext3
;;
[Nn]*)
# do not format
;;
*)
USAGE "'${partition}' is an unknown partition config"
;;
esac
# copy the full bootloader image to the right place after the
# partitioned area
echo
echo Installing Qi bootloader from: ${qi}
dd if="${qi}" of="${dev}" bs=512 count=512 \
seek=$(( $SECTORS - $REAR_SECTORS ))
dd if="${qi}" of="${dev}" bs=512 \
seek=$(( $SECTORS - $REAR_SECTORS + $QI_ALLOCATION )) \
count=$QI_INITIAL
dd if=/dev/zero of="${dev}" bs=512 \
seek=$(( $SECTORS - $REAR_SECTORS + $QI_ALLOCATION + $QI_INITIAL )) \
count=$(( $SIG + $PADDING ))
# done
echo
echo "**** completed"

View File

@ -1,92 +0,0 @@
# 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 program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
include config.mk
BUILD_DATE := $(shell date)
BUILD_HOST := $(shell hostname)
BUILD_BRANCH := $(shell git branch | grep ^\* | cut -d' ' -f2)
BUILD_HEAD := $(shell git show --pretty=oneline | head -n1 | cut -d' ' -f1 | cut -b1-16)
BUILD_VERSION := ${BUILD_BRANCH}_${BUILD_HEAD}
LDS = src/cpu/$(CPU)/qi.lds
INCLUDE = include
IMAGE_DIR = image
TOOLS = tools
CFLAGS = -Wall -Werror -I $(INCLUDE) -g -c -Os -fno-strict-aliasing -mlong-calls \
-fno-common -ffixed-r8 -msoft-float -fno-builtin -ffreestanding \
-march=armv4t -mno-thumb-interwork -Wstrict-prototypes \
-DBUILD_HOST="${BUILD_HOST}" -DBUILD_VERSION="${BUILD_VERSION}" \
-DBUILD_DATE="${BUILD_DATE}" -DQI_CPU="${CPU}"
LDFLAGS =
S_SRCS = $(wildcard src/cpu/$(CPU)/*.S)
S_OBJS = $(patsubst %.S,%.o, $(S_SRCS))
C_SRCS = $(wildcard src/*.c) \
$(wildcard src/drivers/*.c) $(wildcard src/fs/*.c) \
$(wildcard src/cpu/$(CPU)/*.c)
C_OBJS = $(patsubst %.c,%.o, $(C_SRCS))
SRCS = ${S_SRCS} ${C_SRCS}
OBJS = ${S_OBJS} ${C_OBJS}
LIBS = -L${COMPILER_LIB_PATH} -lgcc
ifeq ($(CPU),s3c2410)
# GTA01 U-Boot IDs
UDFU_VID = 0x1457
UDFU_PID = 0x5119
UDFU_REV = 0x0240
else
# GTA02 A5 and A6 U-Boot will eat these for DFU action
UDFU_VID = 0x1d50
UDFU_PID = 0x5119
UDFU_REV = 0x350
endif
TARGET = $(IMAGE_DIR)/start_qi_all-$(CPU)
IMAGE = $(IMAGE_DIR)/qi-$(CPU)-$(BUILD_VERSION)
UDFU_IMAGE = $(IMAGE_DIR)/qi-$(CPU)-$(BUILD_VERSION).udfu
MKUDFU = $(TOOLS)/mkudfu
%.o: %.S
@$(CC) $(CFLAGS) -o $@ $<
%.o: %.c
@$(CC) $(CFLAGS) -o $@ $<
all:${UDFU_IMAGE}
${OBJS}:${SRCS} ${INCLUDE}/*.h
${MKUDFU}:
make -C $(TOOLS)
${UDFU_IMAGE}:${OBJS} ${MKUDFU}
mkdir -p image
@$(LD) ${LDFLAGS} -T$(LDS) -g $(OBJS) -o ${TARGET} ${LIBS}
@$(OBJCOPY) -O binary -S ${TARGET} ${IMAGE}
@$(MKUDFU) -v ${UDFU_VID} -p ${UDFU_PID} -r ${UDFU_REV} \
-d ${IMAGE} ${UDFU_IMAGE}
@$(OBJDUMP) -d ${TARGET} >${IMAGE}.dis
clean:
@rm -f *~ src/*.o src/*~
@rm -f src/cpu/*/*.o src/cpu/*/*~
@rm -f src/drivers/*.o src/drivers/*~
@rm -f src/fs/*.o src/fs/*~
@rm -f include/*~ ${IMAGE_DIR}/*
@make clean -C $(TOOLS)

View File

@ -1,149 +0,0 @@
Qi
==
Qi (named by Alan Cox on Openmoko kernel list) is a minimal bootloader that
"breathes life" into Linux. Its goal is to stay close to the minimum needed
to "load" and then "boot" Linux -- no boot menus, additional peripheral init
or private states.
What's wrong with U-Boot, they keep telling people to not reinvent the wheel?
=============================================================================
U-Boot is gradually becoming a simplified knockoff of Linux. After using it a
while, it became clear we were cutting and pasting drivers into U-Boot from
Linux, cutting them down and not having a plan to maintain the U-Boot versions
as the Linux ones were changed.
We decided that we would use full Linux for things that Linux is good at and
only have the bootloader do the device init that is absolutely required before
Linux can be pulled into memory and started. In practice since we had a working
U-Boot implementation it meant cutting that right down to the bone (start.S
mainly for s3c2442) and then building it up from scratch optimized to just do
load and boot.
Samsung - specific boot sequence
================================
Right now Qi supports Samsung "steppingstone" scheme devices, but in fact it's
the same in processors like iMX31 that there is a small area of SRAM that is
prepped with NAND content via ROM on the device. There's nothing that stops Qi
use on processors without steppingstone, although the ATAG stuff assumes we deal
with ARM based processor.
Per-CPU Qi
==========
Qi has a concept of a single bootloader binary created per CPU type. The
different devices that use that CPU are all supported in the same binary. At
runtime after the common init is done, Qi asks each supported device code in
turn if it recognizes the device as being handled by it, the first one to reply
that it knows the device gets to control the rest of the process.
Consequently, there is NO build-time configuration file as found on U-Boot
except a make env var that sets the CPU type being built, eg:
make CPU=s3c6410
Booting Heuristics
==================
Qi has one or more ways to fetch a kernel depending on the device it finds it is
running on, for example on GTA02 it can use NAND and SD card devices. It goes
through these device-specific storage devices in order and tries to boot the
first viable kernel it finds, usually /boot/<uImage-device>.bin for example
/boot/uImage-GTA02.bin.
The default order for GTA02 is: 1st SD primary partition, 2nd primary
partition, 3rd primary partition, NAND kernel partition.
You can disable a rootfs for consideration for boot if you add a file
/boot/noboot-<device>, eg, /boot/noboot-GTA02. This differs from renaming or
deleting the kernel image because updating the kernel package would give you a
working kernel again and allow boot, whereas the noboot indication will remain
until you remove it.
The kernel commandline used is associated with the storage device and partition,
this allows the correct root= line to be arrived at without any work.
If no kernel image can be found, Qi falls back to doing a memory test.
Appending to commandline
========================
You can append to the Qi commandline by creating a file /boot/append-<device>,
eg, /boot/append-GTA02 containing the additional kernel commandline you want.
This means you can affect the boot per-rootfs, but that if you reimage the
rootfs you at the same time define what is appeneded. Because these files are
looked for with the <device> name in them, options can be selected depending on
the device the rootfs is run on.
Initrd support
==============
Initrd or initramfs in separate file is supported to be loaded at given
memory address in addition to kernel image. The ATAGs are issued accordingly.
Interactive UI
==============
Being minimalistic by its nature, Qi has very limited abilities to
interact with a user. On GTA02 the red LED and the vibrator are used
(if the battery is in good condition) to notify user of the following
actions:
The LED is turned on either on:
- Successful partition mount
- Successful kernel pull
- Successful initramfs pull
The LED is turned off and vibrator runs briefly either on:
- Fail of kernel pull
- Fail of initramfs pull
- Fail of mount partition
- Skipping of current boot possibility
The LED is turned off either on:
- Start of the kernel
- Start of the mem test
- Start of the kernel pull
- Start of the initramfs pull
If a user presses the AUX button after successful partition mount and
before start of the kernel pull (that is, while the red LED is on),
this boot possibility is skipped (and GTA02 owners can feel
vibration). If a user holds the POWER button just before start of the
kernel, debugging parameters are added to the kernel command line
and a lot of information is output to the screen.
Functional Differences from U-Boot on GTA02
===========================================
- Backlight and USB is not enabled until Linux starts after a few seconds
- No startup splash screen
- by default there is no boot spew on the LCM
- On GTAxx boots from first uSD ext2 / 3 partition containing
/boot/uImage-<devicename>.bin present, eg, /boot/uImage-GTA02.bin, it checks
first three partitions in turn
- On GTA01 and 02 if nothing is workable on the SD Card, or it is not present,
Qi will try to boot from NAND
- You can disable a partition for boot by creating /boot/noboot-<devicename>,
eg, /boot/noboot-GTA02, it will skip it and check the next partition
- Way faster
- There is no concept of "staying in the bootloader". The bootloader exits to
Linux as fast as possible, that's all it does.

View File

@ -1,12 +0,0 @@
#!/bin/sh
make clean && \
make CPU=s3c6410 && \
make CPU=s3c2442 && \
make CPU=s3c2410
# as root then...
#
# ./6410-partition-sd.sh sde sdhc image/qi-s3c6410-andy_???????????????? x
# mount /dev/sde2 /mnt ; cp ../kernel/linux-2.6/uImage.bin /mnt/boot ; umount /dev/sde2

View File

@ -1,22 +0,0 @@
#
# Include the make variables (CC, etc...)
#
CROSS_PATH=/usr/local/openmoko/arm
CROSS_COMPILE=${CROSS_PATH}/bin/arm-angstrom-linux-gnueabi-
####
COMPILER_LIB_PATH_PRE=${CROSS_PATH}/lib/gcc/arm-angstrom-linux-gnueabi
COMPILER_LIB_PATH=${COMPILER_LIB_PATH_PRE}/`ls ${COMPILER_LIB_PATH_PRE}`
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
HOSTCC = gcc
# we need the mkudfu tool from U-Boot build
#MKUDFU = ../uboot/u-boot/tools/mkudfu
export CROSS_COMPILE AD LD CC OBJCOPY OBJDUMP MKUDFU

View File

@ -1,7 +0,0 @@
#!/bin/bash
../dfu-util/src/dfu-util -a 1 -d 0x1d50:0x5119 -D image/qi-s3c2442*.udfu
if [ $? -eq 1 ] ; then
../dfu-util/src/dfu-util -a 1 -d 0x1d50:0x5120 -D image/qi-s3c2442*.udfu
../dfu-util/src/dfu-util -a 1 -d 0x1d50:0x5119 -D image/qi-s3c2442*.udfu
fi

View File

@ -1,34 +0,0 @@
# gta02 Qi script
# Andy Green <andy@openmoko.com>
reset halt
wait_halt
sleep 2000
# bring the steppingstone part of qi image into steppingstone
#
load_binary /projects/openmoko/bootloader/image/qi 0x0
#
# mark ourselves as JTAG load
#
mww 0x4 0xffffffff
#
# we have to run that so SDRAM exists in a usable way
# fixed jumpthrough at 0x8 is executed after steppingstone
# init (including RAM) has completed
#
bp 0x8 4 hw
resume 0x0
wait_halt
rbp 0x8
#
# now prep the SDRAM
#
load_binary /projects/openmoko/bootloader/image/qi 0x33000000
#
# and continue...
resume 0x8
#

View File

@ -1,80 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
*
* (C) Copyright 2003 Sysgo Real-Time Solutions, AG <www.elinos.com>
* Pavel Bartusek <pba@sysgo.de>
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* An implementation for the Ext2FS filesystem ported from GRUB.
* Some parts of this code (mainly the structures and defines) are
* from the original ext2 fs code, as found in the linux kernel.
*/
#define SECTOR_SIZE 0x200
#define SECTOR_BITS 9
/* Error codes */
typedef enum
{
ERR_NONE = 0,
ERR_BAD_FILENAME,
ERR_BAD_FILETYPE,
ERR_BAD_GZIP_DATA,
ERR_BAD_GZIP_HEADER,
ERR_BAD_PART_TABLE,
ERR_BAD_VERSION,
ERR_BELOW_1MB,
ERR_BOOT_COMMAND,
ERR_BOOT_FAILURE,
ERR_BOOT_FEATURES,
ERR_DEV_FORMAT,
ERR_DEV_VALUES,
ERR_EXEC_FORMAT,
ERR_FILELENGTH,
ERR_FILE_NOT_FOUND,
ERR_FSYS_CORRUPT,
ERR_FSYS_MOUNT,
ERR_GEOM,
ERR_NEED_LX_KERNEL,
ERR_NEED_MB_KERNEL,
ERR_NO_DISK,
ERR_NO_PART,
ERR_NUMBER_PARSING,
ERR_OUTSIDE_PART,
ERR_READ,
ERR_SYMLINK_LOOP,
ERR_UNRECOGNIZED,
ERR_WONT_FIT,
ERR_WRITE,
ERR_BAD_ARGUMENT,
ERR_UNALIGNED,
ERR_PRIVILEGED,
ERR_DEV_NEED_INIT,
ERR_NO_DISK_SPACE,
ERR_NUMBER_OVERFLOW,
MAX_ERR_NUM
} ext2fs_error_t;
extern int ext2fs_ls(char *dirname);
extern int ext2fs_open(const char *filename);
extern int ext2fs_read(char *buf, unsigned len);
extern int ext2fs_mount(void);
extern int ext2fs_close(void);

View File

@ -1,220 +0,0 @@
/*
* R/O (V)FAT 12/16/32 filesystem implementation by Marcus Sundberg
*
* 2002-07-28 - rjones@nexus-tech.net - ported to ppcboot v1.1.6
* 2003-03-10 - kharris@nexus-tech.net - ported to u-boot
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
#ifndef _FAT_H_
#define _FAT_H_
#include <asm/byteorder.h>
#define CONFIG_SUPPORT_VFAT
#define SECTOR_SIZE FS_BLOCK_SIZE
#define FS_BLOCK_SIZE 512
#if FS_BLOCK_SIZE != SECTOR_SIZE
#error FS_BLOCK_SIZE != SECTOR_SIZE - This code needs to be fixed!
#endif
#define MAX_CLUSTSIZE 65536
#define DIRENTSPERBLOCK (FS_BLOCK_SIZE/sizeof(dir_entry))
#define DIRENTSPERCLUST ((mydata->clust_size*SECTOR_SIZE)/sizeof(dir_entry))
#define FATBUFBLOCKS 6
#define FATBUFSIZE (FS_BLOCK_SIZE*FATBUFBLOCKS)
#define FAT12BUFSIZE ((FATBUFSIZE*2)/3)
#define FAT16BUFSIZE (FATBUFSIZE/2)
#define FAT32BUFSIZE (FATBUFSIZE/4)
/* Filesystem identifiers */
#define FAT12_SIGN "FAT12 "
#define FAT16_SIGN "FAT16 "
#define FAT32_SIGN "FAT32 "
#define SIGNLEN 8
/* File attributes */
#define ATTR_RO 1
#define ATTR_HIDDEN 2
#define ATTR_SYS 4
#define ATTR_VOLUME 8
#define ATTR_DIR 16
#define ATTR_ARCH 32
#define ATTR_VFAT (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME)
#define DELETED_FLAG ((char)0xe5) /* Marks deleted files when in name[0] */
#define aRING 0x05 /* Used to represent 'å' in name[0] */
/* Indicates that the entry is the last long entry in a set of long
* dir entries
*/
#define LAST_LONG_ENTRY_MASK 0x40
/* Flags telling whether we should read a file or list a directory */
#define LS_NO 0
#define LS_YES 1
#define LS_DIR 1
#define LS_ROOT 2
#ifdef DEBUG
#define FAT_DPRINT(args...) printf(args)
#else
#define FAT_DPRINT(args...)
#endif
#define FAT_ERROR(arg) printf(arg)
#define ISDIRDELIM(c) ((c) == '/' || (c) == '\\')
#define FSTYPE_NONE (-1)
#if defined(__linux__) && defined(__KERNEL__)
#define FAT2CPU16 le16_to_cpu
#define FAT2CPU32 le32_to_cpu
#else
#if __LITTLE_ENDIAN
#define FAT2CPU16(x) (x)
#define FAT2CPU32(x) (x)
#else
#define FAT2CPU16(x) ((((x) & 0x00ff) << 8) | (((x) & 0xff00) >> 8))
#define FAT2CPU32(x) ((((x) & 0x000000ff) << 24) | \
(((x) & 0x0000ff00) << 8) | \
(((x) & 0x00ff0000) >> 8) | \
(((x) & 0xff000000) >> 24))
#endif
#endif
#define TOLOWER(c) if((c) >= 'A' && (c) <= 'Z'){(c)+=('a' - 'A');}
#define START(dent) (FAT2CPU16((dent)->start) \
+ (mydata->fatsize != 32 ? 0 : \
(FAT2CPU16((dent)->starthi) << 16)))
#define CHECK_CLUST(x, fatsize) ((x) <= 1 || \
(x) >= ((fatsize) != 32 ? 0xfff0 : 0xffffff0))
typedef struct boot_sector {
__u8 ignored[3]; /* Bootstrap code */
char system_id[8]; /* Name of fs */
__u8 sector_size[2]; /* Bytes/sector */
__u8 cluster_size; /* Sectors/cluster */
__u16 reserved; /* Number of reserved sectors */
__u8 fats; /* Number of FATs */
__u8 dir_entries[2]; /* Number of root directory entries */
__u8 sectors[2]; /* Number of sectors */
__u8 media; /* Media code */
__u16 fat_length; /* Sectors/FAT */
__u16 secs_track; /* Sectors/track */
__u16 heads; /* Number of heads */
__u32 hidden; /* Number of hidden sectors */
__u32 total_sect; /* Number of sectors (if sectors == 0) */
/* FAT32 only */
__u32 fat32_length; /* Sectors/FAT */
__u16 flags; /* Bit 8: fat mirroring, low 4: active fat */
__u8 version[2]; /* Filesystem version */
__u32 root_cluster; /* First cluster in root directory */
__u16 info_sector; /* Filesystem info sector */
__u16 backup_boot; /* Backup boot sector */
__u16 reserved2[6]; /* Unused */
} boot_sector;
typedef struct volume_info
{
__u8 drive_number; /* BIOS drive number */
__u8 reserved; /* Unused */
__u8 ext_boot_sign; /* 0x29 if fields below exist (DOS 3.3+) */
__u8 volume_id[4]; /* Volume ID number */
char volume_label[11]; /* Volume label */
char fs_type[8]; /* Typically FAT12, FAT16, or FAT32 */
/* Boot code comes next, all but 2 bytes to fill up sector */
/* Boot sign comes last, 2 bytes */
} volume_info;
typedef struct dir_entry {
char name[8],ext[3]; /* Name and extension */
__u8 attr; /* Attribute bits */
__u8 lcase; /* Case for base and extension */
__u8 ctime_ms; /* Creation time, milliseconds */
__u16 ctime; /* Creation time */
__u16 cdate; /* Creation date */
__u16 adate; /* Last access date */
__u16 starthi; /* High 16 bits of cluster in FAT32 */
__u16 time,date,start;/* Time, date and first cluster */
__u32 size; /* File size in bytes */
} dir_entry;
typedef struct dir_slot {
__u8 id; /* Sequence number for slot */
__u8 name0_4[10]; /* First 5 characters in name */
__u8 attr; /* Attribute byte */
__u8 reserved; /* Unused */
__u8 alias_checksum;/* Checksum for 8.3 alias */
__u8 name5_10[12]; /* 6 more characters in name */
__u16 start; /* Unused */
__u8 name11_12[4]; /* Last 2 characters in name */
} dir_slot;
/* Private filesystem parameters
*
* Note: FAT buffer has to be 32 bit aligned
* (see FAT32 accesses)
*/
typedef struct {
__u8 fatbuf[FATBUFSIZE]; /* Current FAT buffer */
int fatsize; /* Size of FAT in bits */
__u16 fatlength; /* Length of FAT in sectors */
__u16 fat_sect; /* Starting sector of the FAT */
__u16 rootdir_sect; /* Start sector of root directory */
__u16 clust_size; /* Size of clusters in sectors */
short data_begin; /* The sector of the first cluster, can be negative */
int fatbufnum; /* Used by get_fatent, init to -1 */
} fsdata;
typedef int (file_detectfs_func)(void);
typedef int (file_ls_func)(const char *dir);
typedef long (file_read_func)(const char *filename, void *buffer,
unsigned long maxsize);
struct filesystem {
file_detectfs_func *detect;
file_ls_func *ls;
file_read_func *read;
const char name[12];
};
/* FAT tables */
file_detectfs_func file_fat_detectfs;
file_ls_func file_fat_ls;
file_read_func file_fat_read;
/* Currently this doesn't check if the dir exists or is valid... */
int file_cd(const char *path);
int file_fat_detectfs(void);
int file_fat_ls(const char *dir);
long file_fat_read(const char *filename, void *buffer, unsigned long maxsize);
const char *file_getfsname(int idx);
int fat_register_device(block_dev_desc_t *dev_desc, int part_no);
#endif /* _FAT_H_ */

View File

@ -1 +0,0 @@
extern void glamo_core_init(void);

View File

@ -1,149 +0,0 @@
#ifndef __GLAMO_MMC_H__
#define __GLAMO_MMC_H__
/* Standard MMC commands (4.1) type argument response */
/* class 1 */
#define MMC_GO_IDLE_STATE 0 /* bc */
#define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */
#define MMC_ALL_SEND_CID 2 /* bcr R2 */
#define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */
#define MMC_SET_DSR 4 /* bc [31:16] RCA */
#define MMC_SWITCH 6 /* ac [31:0] See below R1b */
#define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */
#define MMC_SEND_EXT_CSD 8 /* adtc R1 */
#define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */
#define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */
#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
#define MMC_STOP_TRANSMISSION 12 /* ac R1b */
#define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */
#define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */
#define MMC_SPI_READ_OCR 58 /* spi spi_R3 */
#define MMC_SPI_CRC_ON_OFF 59 /* spi [0:0] flag spi_R1 */
#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */
#define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */
/* class 2 */
#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */
#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
/* class 3 */
#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
/* class 4 */
#define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */
#define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */
#define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */
#define MMC_PROGRAM_CID 26 /* adtc R1 */
#define MMC_PROGRAM_CSD 27 /* adtc R1 */
/* class 6 */
#define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */
#define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */
#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
/* class 5 */
#define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */
#define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */
#define MMC_ERASE 38 /* ac R1b */
/* class 9 */
#define MMC_FAST_IO 39 /* ac <Complex> R4 */
#define MMC_GO_IRQ_STATE 40 /* bcr R5 */
/* class 7 */
#define MMC_LOCK_UNLOCK 42 /* adtc R1b */
/* class 8 */
#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */
#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */
#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
#define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */
#define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */
#define SD_APP_SEND_SCR 51 /* adtc R1 */
#define MMC_RSP_PRESENT (1 << 0)
#define MMC_RSP_136 (1 << 1) /* 136 bit response */
#define MMC_RSP_CRC (1 << 2) /* expect valid crc */
#define MMC_RSP_BUSY (1 << 3) /* card may send busy */
#define MMC_RSP_OPCODE (1 << 4) /* response contains opcode */
#define MMC_CMD_MASK (3 << 5) /* non-SPI command type */
#define MMC_CMD_AC (0 << 5)
#define MMC_CMD_ADTC (1 << 5)
#define MMC_CMD_BC (2 << 5)
#define MMC_CMD_BCR (3 << 5)
#define MMC_RSP_SPI_S1 (1 << 7) /* one status byte */
#define MMC_RSP_SPI_S2 (1 << 8) /* second byte */
#define MMC_RSP_SPI_B4 (1 << 9) /* four data bytes */
#define MMC_RSP_SPI_BUSY (1 << 10) /* card may send busy */
/*
* These are the native response types, and correspond to valid bit
* patterns of the above flags. One additional valid pattern
* is all zeros, which means we don't expect a response.
*/
#define MMC_RSP_NONE (0)
#define MMC_RSP_R1 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R1B (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)
#define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
#define MMC_RSP_R3 (MMC_RSP_PRESENT)
#define MMC_RSP_R4 (MMC_RSP_PRESENT)
#define MMC_RSP_R5 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R7 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define mmc_resp_type(f) ((f) & (MMC_RSP_PRESENT | MMC_RSP_136 | MMC_RSP_CRC |\
MMC_RSP_BUSY | MMC_RSP_OPCODE))
#define mmc_cmd_type(f) ((f) & MMC_CMD_MASK)
/*
* These are the SPI response types for MMC, SD, and SDIO cards.
* Commands return R1, with maybe more info. Zero is an error type;
* callers must always provide the appropriate MMC_RSP_SPI_Rx flags.
*/
#define MMC_RSP_SPI_R1 (MMC_RSP_SPI_S1)
#define MMC_RSP_SPI_R1B (MMC_RSP_SPI_S1|MMC_RSP_SPI_BUSY)
#define MMC_RSP_SPI_R2 (MMC_RSP_SPI_S1|MMC_RSP_SPI_S2)
#define MMC_RSP_SPI_R3 (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)
#define MMC_RSP_SPI_R4 (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)
#define MMC_RSP_SPI_R5 (MMC_RSP_SPI_S1|MMC_RSP_SPI_S2)
#define MMC_RSP_SPI_R7 (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)
#define MMC_DATA_WRITE (1 << 8)
#define MMC_DATA_READ (1 << 9)
#define MMC_DATA_STREAM (1 << 10)
struct sd_cid {
char pnm_0; /* product name */
char oid_1; /* OEM/application ID */
char oid_0;
u8 mid; /* manufacturer ID */
char pnm_4;
char pnm_3;
char pnm_2;
char pnm_1;
u8 psn_2; /* product serial number */
u8 psn_1;
u8 psn_0; /* MSB */
u8 prv; /* product revision */
u8 crc; /* CRC7 checksum, b0 is unused and set to 1 */
u8 mdt_1; /* manufacturing date, LSB, RRRRyyyy yyyymmmm */
u8 mdt_0; /* MSB */
u8 psn_3; /* LSB */
};
enum card_type {
CARDTYPE_NONE = 0,
CARDTYPE_MMC,
CARDTYPE_SD,
CARDTYPE_SD20,
CARDTYPE_SDHC
};
#endif /* __GLAMO_MMC_H__ */

View File

@ -1,628 +0,0 @@
#ifndef _GLAMO_REGS_H
#define _GLAMO_REGS_H
/* Smedia Glamo 336x/337x driver
*
* (C) 2007 by OpenMoko, Inc.
* Author: Harald Welte <laforge@openmoko.org>
* All rights reserved.
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
enum glamo_regster_offsets {
GLAMO_REGOFS_GENERIC = 0x0000,
GLAMO_REGOFS_HOSTBUS = 0x0200,
GLAMO_REGOFS_MEMORY = 0x0300,
GLAMO_REGOFS_VIDCAP = 0x0400,
GLAMO_REGOFS_ISP = 0x0500,
GLAMO_REGOFS_JPEG = 0x0800,
GLAMO_REGOFS_MPEG = 0x0c00,
GLAMO_REGOFS_LCD = 0x1100,
GLAMO_REGOFS_MMC = 0x1400,
GLAMO_REGOFS_MPROC0 = 0x1500,
GLAMO_REGOFS_MPROC1 = 0x1580,
GLAMO_REGOFS_CMDQUEUE = 0x1600,
GLAMO_REGOFS_RISC = 0x1680,
GLAMO_REGOFS_2D = 0x1700,
GLAMO_REGOFS_3D = 0x1b00,
GLAMO_REGOFS_END = 0x2400,
};
enum glamo_register_generic {
GLAMO_REG_GCONF1 = 0x0000,
GLAMO_REG_GCONF2 = 0x0002,
#define GLAMO_REG_DEVICE_ID GLAMO_REG_GCONF2
GLAMO_REG_GCONF3 = 0x0004,
#define GLAMO_REG_REVISION_ID GLAMO_REG_GCONF3
GLAMO_REG_IRQ_GEN1 = 0x0006,
#define GLAMO_REG_IRQ_ENABLE GLAMO_REG_IRQ_GEN1
GLAMO_REG_IRQ_GEN2 = 0x0008,
#define GLAMO_REG_IRQ_SET GLAMO_REG_IRQ_GEN2
GLAMO_REG_IRQ_GEN3 = 0x000a,
#define GLAMO_REG_IRQ_CLEAR GLAMO_REG_IRQ_GEN3
GLAMO_REG_IRQ_GEN4 = 0x000c,
#define GLAMO_REG_IRQ_STATUS GLAMO_REG_IRQ_GEN4
GLAMO_REG_CLOCK_HOST = 0x0010,
GLAMO_REG_CLOCK_MEMORY = 0x0012,
GLAMO_REG_CLOCK_LCD = 0x0014,
GLAMO_REG_CLOCK_MMC = 0x0016,
GLAMO_REG_CLOCK_ISP = 0x0018,
GLAMO_REG_CLOCK_JPEG = 0x001a,
GLAMO_REG_CLOCK_3D = 0x001c,
GLAMO_REG_CLOCK_2D = 0x001e,
GLAMO_REG_CLOCK_RISC1 = 0x0020, /* 3365 only? */
GLAMO_REG_CLOCK_RISC2 = 0x0022, /* 3365 only? */
GLAMO_REG_CLOCK_MPEG = 0x0024,
GLAMO_REG_CLOCK_MPROC = 0x0026,
GLAMO_REG_CLOCK_GEN5_1 = 0x0030,
GLAMO_REG_CLOCK_GEN5_2 = 0x0032,
GLAMO_REG_CLOCK_GEN6 = 0x0034,
GLAMO_REG_CLOCK_GEN7 = 0x0036,
GLAMO_REG_CLOCK_GEN8 = 0x0038,
GLAMO_REG_CLOCK_GEN9 = 0x003a,
GLAMO_REG_CLOCK_GEN10 = 0x003c,
GLAMO_REG_CLOCK_GEN11 = 0x003e,
GLAMO_REG_PLL_GEN1 = 0x0040,
GLAMO_REG_PLL_GEN2 = 0x0042,
GLAMO_REG_PLL_GEN3 = 0x0044,
GLAMO_REG_PLL_GEN4 = 0x0046,
GLAMO_REG_PLL_GEN5 = 0x0048,
GLAMO_REG_GPIO_GEN1 = 0x0050,
GLAMO_REG_GPIO_GEN2 = 0x0052,
GLAMO_REG_GPIO_GEN3 = 0x0054,
GLAMO_REG_GPIO_GEN4 = 0x0056,
GLAMO_REG_GPIO_GEN5 = 0x0058,
GLAMO_REG_GPIO_GEN6 = 0x005a,
GLAMO_REG_GPIO_GEN7 = 0x005c,
GLAMO_REG_GPIO_GEN8 = 0x005e,
GLAMO_REG_GPIO_GEN9 = 0x0060,
GLAMO_REG_GPIO_GEN10 = 0x0062,
GLAMO_REG_DFT_GEN1 = 0x0070,
GLAMO_REG_DFT_GEN2 = 0x0072,
GLAMO_REG_DFT_GEN3 = 0x0074,
GLAMO_REG_DFT_GEN4 = 0x0076,
GLAMO_REG_PLL_GEN6 = 0x01e0,
GLAMO_REG_PLL_GEN7 = 0x01f0,
};
#define GLAMO_REG_HOSTBUS(x) (GLAMO_REGOFS_HOSTBUS-2+(x*2))
#define REG_MEM(x) (GLAMO_REGOFS_MEMORY+(x))
#define GLAMO_REG_MEM_TIMING(x) (GLAMO_REG_MEM_TIMING1-2+(x*2))
enum glamo_register_mem {
GLAMO_REG_MEM_TYPE = REG_MEM(0x00),
GLAMO_REG_MEM_GEN = REG_MEM(0x02),
GLAMO_REG_MEM_TIMING1 = REG_MEM(0x04),
GLAMO_REG_MEM_TIMING2 = REG_MEM(0x06),
GLAMO_REG_MEM_TIMING3 = REG_MEM(0x08),
GLAMO_REG_MEM_TIMING4 = REG_MEM(0x0a),
GLAMO_REG_MEM_TIMING5 = REG_MEM(0x0c),
GLAMO_REG_MEM_TIMING6 = REG_MEM(0x0e),
GLAMO_REG_MEM_TIMING7 = REG_MEM(0x10),
GLAMO_REG_MEM_TIMING8 = REG_MEM(0x12),
GLAMO_REG_MEM_TIMING9 = REG_MEM(0x14),
GLAMO_REG_MEM_TIMING10 = REG_MEM(0x16),
GLAMO_REG_MEM_TIMING11 = REG_MEM(0x18),
GLAMO_REG_MEM_POWER1 = REG_MEM(0x1a),
GLAMO_REG_MEM_POWER2 = REG_MEM(0x1c),
GLAMO_REG_MEM_LCD_BUF1 = REG_MEM(0x1e),
GLAMO_REG_MEM_LCD_BUF2 = REG_MEM(0x20),
GLAMO_REG_MEM_LCD_BUF3 = REG_MEM(0x22),
GLAMO_REG_MEM_LCD_BUF4 = REG_MEM(0x24),
GLAMO_REG_MEM_BIST1 = REG_MEM(0x26),
GLAMO_REG_MEM_BIST2 = REG_MEM(0x28),
GLAMO_REG_MEM_BIST3 = REG_MEM(0x2a),
GLAMO_REG_MEM_BIST4 = REG_MEM(0x2c),
GLAMO_REG_MEM_BIST5 = REG_MEM(0x2e),
GLAMO_REG_MEM_MAH1 = REG_MEM(0x30),
GLAMO_REG_MEM_MAH2 = REG_MEM(0x32),
GLAMO_REG_MEM_DRAM1 = REG_MEM(0x34),
GLAMO_REG_MEM_DRAM2 = REG_MEM(0x36),
GLAMO_REG_MEM_CRC = REG_MEM(0x38),
};
#define GLAMO_MEM_TYPE_MASK 0x03
enum glamo_reg_mem_dram1 {
GLAMO_MEM_DRAM1_EN_SDRAM_CLK = (1 << 11),
GLAMO_MEM_DRAM1_SELF_REFRESH = (1 << 12),
};
enum glamo_reg_mem_dram2 {
GLAMO_MEM_DRAM2_DEEP_PWRDOWN = (1 << 12),
};
enum glamo_irq_index {
GLAMO_IRQIDX_HOSTBUS = 0,
GLAMO_IRQIDX_JPEG = 1,
GLAMO_IRQIDX_MPEG = 2,
GLAMO_IRQIDX_MPROC1 = 3,
GLAMO_IRQIDX_MPROC0 = 4,
GLAMO_IRQIDX_CMDQUEUE = 5,
GLAMO_IRQIDX_2D = 6,
GLAMO_IRQIDX_MMC = 7,
GLAMO_IRQIDX_RISC = 8,
};
enum glamo_irq {
GLAMO_IRQ_HOSTBUS = (1 << GLAMO_IRQIDX_HOSTBUS),
GLAMO_IRQ_JPEG = (1 << GLAMO_IRQIDX_JPEG),
GLAMO_IRQ_MPEG = (1 << GLAMO_IRQIDX_MPEG),
GLAMO_IRQ_MPROC1 = (1 << GLAMO_IRQIDX_MPROC1),
GLAMO_IRQ_MPROC0 = (1 << GLAMO_IRQIDX_MPROC0),
GLAMO_IRQ_CMDQUEUE = (1 << GLAMO_IRQIDX_CMDQUEUE),
GLAMO_IRQ_2D = (1 << GLAMO_IRQIDX_2D),
GLAMO_IRQ_MMC = (1 << GLAMO_IRQIDX_MMC),
GLAMO_IRQ_RISC = (1 << GLAMO_IRQIDX_RISC),
};
enum glamo_reg_clock_host {
GLAMO_CLOCK_HOST_DG_BCLK = 0x0001,
GLAMO_CLOCK_HOST_DG_M0CLK = 0x0004,
GLAMO_CLOCK_HOST_RESET = 0x1000,
};
enum glamo_reg_clock_mem {
GLAMO_CLOCK_MEM_DG_M1CLK = 0x0001,
GLAMO_CLOCK_MEM_EN_M1CLK = 0x0002,
GLAMO_CLOCK_MEM_DG_MOCACLK = 0x0004,
GLAMO_CLOCK_MEM_EN_MOCACLK = 0x0008,
GLAMO_CLOCK_MEM_RESET = 0x1000,
GLAMO_CLOCK_MOCA_RESET = 0x2000,
};
enum glamo_reg_clock_lcd {
GLAMO_CLOCK_LCD_DG_DCLK = 0x0001,
GLAMO_CLOCK_LCD_EN_DCLK = 0x0002,
GLAMO_CLOCK_LCD_DG_DMCLK = 0x0004,
GLAMO_CLOCK_LCD_EN_DMCLK = 0x0008,
//
GLAMO_CLOCK_LCD_EN_DHCLK = 0x0020,
GLAMO_CLOCK_LCD_DG_M5CLK = 0x0040,
GLAMO_CLOCK_LCD_EN_M5CLK = 0x0080,
GLAMO_CLOCK_LCD_RESET = 0x1000,
};
enum glamo_reg_clock_mmc {
GLAMO_CLOCK_MMC_DG_TCLK = 0x0001,
GLAMO_CLOCK_MMC_EN_TCLK = 0x0002,
GLAMO_CLOCK_MMC_DG_M9CLK = 0x0004,
GLAMO_CLOCK_MMC_EN_M9CLK = 0x0008,
GLAMO_CLOCK_MMC_RESET = 0x1000,
};
enum glamo_reg_basic_mmc {
/* set to disable CRC error rejection */
GLAMO_BASIC_MMC_DISABLE_CRC = 0x0001,
/* enable completion interrupt */
GLAMO_BASIC_MMC_EN_COMPL_INT = 0x0002,
/* stop MMC clock while enforced idle waiting for data from card */
GLAMO_BASIC_MMC_NO_CLK_RD_WAIT = 0x0004,
/* 0 = 1-bit bus to card, 1 = use 4-bit bus (has to be negotiated) */
GLAMO_BASIC_MMC_EN_4BIT_DATA = 0x0008,
/* enable 75K pullups on D3..D0 */
GLAMO_BASIC_MMC_EN_DATA_PUPS = 0x0010,
/* enable 75K pullup on CMD */
GLAMO_BASIC_MMC_EN_CMD_PUP = 0x0020,
/* IO drive strength 00=weak -> 11=strongest */
GLAMO_BASIC_MMC_EN_DR_STR0 = 0x0040,
GLAMO_BASIC_MMC_EN_DR_STR1 = 0x0080,
/* TCLK delay stage A, 0000 = 500ps --> 1111 = 8ns */
GLAMO_BASIC_MMC_EN_TCLK_DLYA0 = 0x0100,
GLAMO_BASIC_MMC_EN_TCLK_DLYA1 = 0x0200,
GLAMO_BASIC_MMC_EN_TCLK_DLYA2 = 0x0400,
GLAMO_BASIC_MMC_EN_TCLK_DLYA3 = 0x0800,
/* TCLK delay stage B (cumulative), 0000 = 500ps --> 1111 = 8ns */
GLAMO_BASIC_MMC_EN_TCLK_DLYB0 = 0x1000,
GLAMO_BASIC_MMC_EN_TCLK_DLYB1 = 0x2000,
GLAMO_BASIC_MMC_EN_TCLK_DLYB2 = 0x4000,
GLAMO_BASIC_MMC_EN_TCLK_DLYB3 = 0x8000,
};
enum glamo_reg_stat1_mmc {
/* command "counter" (really: toggle) */
GLAMO_STAT1_MMC_CMD_CTR = 0x8000,
/* engine is idle */
GLAMO_STAT1_MMC_IDLE = 0x4000,
/* readback response is ready */
GLAMO_STAT1_MMC_RB_RRDY = 0x0200,
/* readback data is ready */
GLAMO_STAT1_MMC_RB_DRDY = 0x0100,
/* no response timeout */
GLAMO_STAT1_MMC_RTOUT = 0x0020,
/* no data timeout */
GLAMO_STAT1_MMC_DTOUT = 0x0010,
/* CRC error on block write */
GLAMO_STAT1_MMC_BWERR = 0x0004,
/* CRC error on block read */
GLAMO_STAT1_MMC_BRERR = 0x0002
};
enum glamo_reg_fire_mmc {
/* command "counter" (really: toggle)
* the STAT1 register reflects this so you can ensure you don't look
* at status for previous command
*/
GLAMO_FIRE_MMC_CMD_CTR = 0x8000,
/* sets kind of response expected */
GLAMO_FIRE_MMC_RES_MASK = 0x0700,
/* sets command type */
GLAMO_FIRE_MMC_TYP_MASK = 0x00C0,
/* sets command class */
GLAMO_FIRE_MMC_CLS_MASK = 0x000F,
};
enum glamo_fire_mmc_response_types {
GLAMO_FIRE_MMC_RSPT_R1 = 0x0000,
GLAMO_FIRE_MMC_RSPT_R1b = 0x0100,
GLAMO_FIRE_MMC_RSPT_R2 = 0x0200,
GLAMO_FIRE_MMC_RSPT_R3 = 0x0300,
GLAMO_FIRE_MMC_RSPT_R4 = 0x0400,
GLAMO_FIRE_MMC_RSPT_R5 = 0x0500,
};
enum glamo_fire_mmc_command_types {
/* broadcast, no response */
GLAMO_FIRE_MMC_CMDT_BNR = 0x0000,
/* broadcast, with response */
GLAMO_FIRE_MMC_CMDT_BR = 0x0040,
/* addressed, no data */
GLAMO_FIRE_MMC_CMDT_AND = 0x0080,
/* addressed, with data */
GLAMO_FIRE_MMC_CMDT_AD = 0x00C0,
};
enum glamo_fire_mmc_command_class {
/* "Stream Read" */
GLAMO_FIRE_MMC_CC_STRR = 0x0000,
/* Single Block Read */
GLAMO_FIRE_MMC_CC_SBR = 0x0001,
/* Multiple Block Read With Stop */
GLAMO_FIRE_MMC_CC_MBRS = 0x0002,
/* Multiple Block Read No Stop */
GLAMO_FIRE_MMC_CC_MBRNS = 0x0003,
/* RESERVED for "Stream Write" */
GLAMO_FIRE_MMC_CC_STRW = 0x0004,
/* "Stream Write" */
GLAMO_FIRE_MMC_CC_SBW = 0x0005,
/* RESERVED for Multiple Block Write With Stop */
GLAMO_FIRE_MMC_CC_MBWS = 0x0006,
/* Multiple Block Write No Stop */
GLAMO_FIRE_MMC_CC_MBWNS = 0x0007,
/* STOP command */
GLAMO_FIRE_MMC_CC_STOP = 0x0008,
/* Cancel on Running Command */
GLAMO_FIRE_MMC_CC_CANCL = 0x0009,
/* "Basic Command" */
GLAMO_FIRE_MMC_CC_BASIC = 0x000a,
};
/* these are offsets from the start of the MMC register region */
enum glamo_register_mmc {
/* MMC command, b15..8 = cmd arg b7..0; b7..1 = CRC; b0 = end bit */
GLAMO_REG_MMC_CMD_REG1 = 0x00,
/* MMC command, b15..0 = cmd arg b23 .. 8 */
GLAMO_REG_MMC_CMD_REG2 = 0x02,
/* MMC command, b15=start, b14=transmission,
* b13..8=cmd idx, b7..0=cmd arg b31..24
*/
GLAMO_REG_MMC_CMD_REG3 = 0x04,
GLAMO_REG_MMC_CMD_FIRE = 0x06,
GLAMO_REG_MMC_CMD_RSP1 = 0x10,
GLAMO_REG_MMC_CMD_RSP2 = 0x12,
GLAMO_REG_MMC_CMD_RSP3 = 0x14,
GLAMO_REG_MMC_CMD_RSP4 = 0x16,
GLAMO_REG_MMC_CMD_RSP5 = 0x18,
GLAMO_REG_MMC_CMD_RSP6 = 0x1a,
GLAMO_REG_MMC_CMD_RSP7 = 0x1c,
GLAMO_REG_MMC_CMD_RSP8 = 0x1e,
GLAMO_REG_MMC_RB_STAT1 = 0x20,
GLAMO_REG_MMC_RB_BLKCNT = 0x22,
GLAMO_REG_MMC_RB_BLKLEN = 0x24,
GLAMO_REG_MMC_BASIC = 0x30,
GLAMO_REG_MMC_RDATADS1 = 0x34,
GLAMO_REG_MMC_RDATADS2 = 0x36,
GLAMO_REG_MMC_WDATADS1 = 0x38,
GLAMO_REG_MMC_WDATADS2 = 0x3a,
GLAMO_REG_MMC_DATBLKCNT = 0x3c,
GLAMO_REG_MMC_DATBLKLEN = 0x3e,
GLAMO_REG_MMC_TIMEOUT = 0x40,
};
enum glamo_reg_clock_isp {
GLAMO_CLOCK_ISP_DG_I1CLK = 0x0001,
GLAMO_CLOCK_ISP_EN_I1CLK = 0x0002,
GLAMO_CLOCK_ISP_DG_CCLK = 0x0004,
GLAMO_CLOCK_ISP_EN_CCLK = 0x0008,
//
GLAMO_CLOCK_ISP_EN_SCLK = 0x0020,
GLAMO_CLOCK_ISP_DG_M2CLK = 0x0040,
GLAMO_CLOCK_ISP_EN_M2CLK = 0x0080,
GLAMO_CLOCK_ISP_DG_M15CLK = 0x0100,
GLAMO_CLOCK_ISP_EN_M15CLK = 0x0200,
GLAMO_CLOCK_ISP1_RESET = 0x1000,
GLAMO_CLOCK_ISP2_RESET = 0x2000,
};
enum glamo_reg_clock_jpeg {
GLAMO_CLOCK_JPEG_DG_JCLK = 0x0001,
GLAMO_CLOCK_JPEG_EN_JCLK = 0x0002,
GLAMO_CLOCK_JPEG_DG_M3CLK = 0x0004,
GLAMO_CLOCK_JPEG_EN_M3CLK = 0x0008,
GLAMO_CLOCK_JPEG_RESET = 0x1000,
};
enum glamo_reg_clock_2d {
GLAMO_CLOCK_2D_DG_GCLK = 0x0001,
GLAMO_CLOCK_2D_EN_GCLK = 0x0002,
GLAMO_CLOCK_2D_DG_M7CLK = 0x0004,
GLAMO_CLOCK_2D_EN_M7CLK = 0x0008,
GLAMO_CLOCK_2D_DG_M6CLK = 0x0010,
GLAMO_CLOCK_2D_EN_M6CLK = 0x0020,
GLAMO_CLOCK_2D_RESET = 0x1000,
GLAMO_CLOCK_2D_CQ_RESET = 0x2000,
};
enum glamo_reg_clock_3d {
GLAMO_CLOCK_3D_DG_ECLK = 0x0001,
GLAMO_CLOCK_3D_EN_ECLK = 0x0002,
GLAMO_CLOCK_3D_DG_RCLK = 0x0004,
GLAMO_CLOCK_3D_EN_RCLK = 0x0008,
GLAMO_CLOCK_3D_DG_M8CLK = 0x0010,
GLAMO_CLOCK_3D_EN_M8CLK = 0x0020,
GLAMO_CLOCK_3D_BACK_RESET = 0x1000,
GLAMO_CLOCK_3D_FRONT_RESET = 0x2000,
};
enum glamo_reg_clock_mpeg {
GLAMO_CLOCK_MPEG_DG_X0CLK = 0x0001,
GLAMO_CLOCK_MPEG_EN_X0CLK = 0x0002,
GLAMO_CLOCK_MPEG_DG_X1CLK = 0x0004,
GLAMO_CLOCK_MPEG_EN_X1CLK = 0x0008,
GLAMO_CLOCK_MPEG_DG_X2CLK = 0x0010,
GLAMO_CLOCK_MPEG_EN_X2CLK = 0x0020,
GLAMO_CLOCK_MPEG_DG_X3CLK = 0x0040,
GLAMO_CLOCK_MPEG_EN_X3CLK = 0x0080,
GLAMO_CLOCK_MPEG_DG_X4CLK = 0x0100,
GLAMO_CLOCK_MPEG_EN_X4CLK = 0x0200,
GLAMO_CLOCK_MPEG_DG_X6CLK = 0x0400,
GLAMO_CLOCK_MPEG_EN_X6CLK = 0x0800,
GLAMO_CLOCK_MPEG_ENC_RESET = 0x1000,
GLAMO_CLOCK_MPEG_DEC_RESET = 0x2000,
};
enum glamo_reg_clock51 {
GLAMO_CLOCK_GEN51_EN_DIV_MCLK = 0x0001,
GLAMO_CLOCK_GEN51_EN_DIV_SCLK = 0x0002,
GLAMO_CLOCK_GEN51_EN_DIV_JCLK = 0x0004,
GLAMO_CLOCK_GEN51_EN_DIV_DCLK = 0x0008,
GLAMO_CLOCK_GEN51_EN_DIV_DMCLK = 0x0010,
GLAMO_CLOCK_GEN51_EN_DIV_DHCLK = 0x0020,
GLAMO_CLOCK_GEN51_EN_DIV_GCLK = 0x0040,
GLAMO_CLOCK_GEN51_EN_DIV_TCLK = 0x0080,
/* FIXME: higher bits */
};
enum glamo_reg_hostbus2 {
GLAMO_HOSTBUS2_MMIO_EN_ISP = 0x0001,
GLAMO_HOSTBUS2_MMIO_EN_JPEG = 0x0002,
GLAMO_HOSTBUS2_MMIO_EN_MPEG = 0x0004,
GLAMO_HOSTBUS2_MMIO_EN_LCD = 0x0008,
GLAMO_HOSTBUS2_MMIO_EN_MMC = 0x0010,
GLAMO_HOSTBUS2_MMIO_EN_MICROP0 = 0x0020,
GLAMO_HOSTBUS2_MMIO_EN_MICROP1 = 0x0040,
GLAMO_HOSTBUS2_MMIO_EN_CQ = 0x0080,
GLAMO_HOSTBUS2_MMIO_EN_RISC = 0x0100,
GLAMO_HOSTBUS2_MMIO_EN_2D = 0x0200,
GLAMO_HOSTBUS2_MMIO_EN_3D = 0x0400,
};
/* LCD Controller */
#define REG_LCD(x) (x)
enum glamo_reg_lcd {
GLAMO_REG_LCD_MODE1 = REG_LCD(0x00),
GLAMO_REG_LCD_MODE2 = REG_LCD(0x02),
GLAMO_REG_LCD_MODE3 = REG_LCD(0x04),
GLAMO_REG_LCD_WIDTH = REG_LCD(0x06),
GLAMO_REG_LCD_HEIGHT = REG_LCD(0x08),
GLAMO_REG_LCD_POLARITY = REG_LCD(0x0a),
GLAMO_REG_LCD_A_BASE1 = REG_LCD(0x0c),
GLAMO_REG_LCD_A_BASE2 = REG_LCD(0x0e),
GLAMO_REG_LCD_B_BASE1 = REG_LCD(0x10),
GLAMO_REG_LCD_B_BASE2 = REG_LCD(0x12),
GLAMO_REG_LCD_C_BASE1 = REG_LCD(0x14),
GLAMO_REG_LCD_C_BASE2 = REG_LCD(0x16),
GLAMO_REG_LCD_PITCH = REG_LCD(0x18),
/* RES */
GLAMO_REG_LCD_HORIZ_TOTAL = REG_LCD(0x1c),
/* RES */
GLAMO_REG_LCD_HORIZ_RETR_START = REG_LCD(0x20),
/* RES */
GLAMO_REG_LCD_HORIZ_RETR_END = REG_LCD(0x24),
/* RES */
GLAMO_REG_LCD_HORIZ_DISP_START = REG_LCD(0x28),
/* RES */
GLAMO_REG_LCD_HORIZ_DISP_END = REG_LCD(0x2c),
/* RES */
GLAMO_REG_LCD_VERT_TOTAL = REG_LCD(0x30),
/* RES */
GLAMO_REG_LCD_VERT_RETR_START = REG_LCD(0x34),
/* RES */
GLAMO_REG_LCD_VERT_RETR_END = REG_LCD(0x38),
/* RES */
GLAMO_REG_LCD_VERT_DISP_START = REG_LCD(0x3c),
/* RES */
GLAMO_REG_LCD_VERT_DISP_END = REG_LCD(0x40),
/* RES */
GLAMO_REG_LCD_POL = REG_LCD(0x44),
GLAMO_REG_LCD_DATA_START = REG_LCD(0x46),
GLAMO_REG_LCD_FRATE_CONTRO = REG_LCD(0x48),
GLAMO_REG_LCD_DATA_CMD_HDR = REG_LCD(0x4a),
GLAMO_REG_LCD_SP_START = REG_LCD(0x4c),
GLAMO_REG_LCD_SP_END = REG_LCD(0x4e),
GLAMO_REG_LCD_CURSOR_BASE1 = REG_LCD(0x50),
GLAMO_REG_LCD_CURSOR_BASE2 = REG_LCD(0x52),
GLAMO_REG_LCD_CURSOR_PITCH = REG_LCD(0x54),
GLAMO_REG_LCD_CURSOR_X_SIZE = REG_LCD(0x56),
GLAMO_REG_LCD_CURSOR_Y_SIZE = REG_LCD(0x58),
GLAMO_REG_LCD_CURSOR_X_POS = REG_LCD(0x5a),
GLAMO_REG_LCD_CURSOR_Y_POS = REG_LCD(0x5c),
GLAMO_REG_LCD_CURSOR_PRESET = REG_LCD(0x5e),
GLAMO_REG_LCD_CURSOR_FG_COLOR = REG_LCD(0x60),
/* RES */
GLAMO_REG_LCD_CURSOR_BG_COLOR = REG_LCD(0x64),
/* RES */
GLAMO_REG_LCD_CURSOR_DST_COLOR = REG_LCD(0x68),
/* RES */
GLAMO_REG_LCD_STATUS1 = REG_LCD(0x80),
GLAMO_REG_LCD_STATUS2 = REG_LCD(0x82),
GLAMO_REG_LCD_STATUS3 = REG_LCD(0x84),
GLAMO_REG_LCD_STATUS4 = REG_LCD(0x86),
/* RES */
GLAMO_REG_LCD_COMMAND1 = REG_LCD(0xa0),
GLAMO_REG_LCD_COMMAND2 = REG_LCD(0xa2),
/* RES */
GLAMO_REG_LCD_WFORM_DELAY1 = REG_LCD(0xb0),
GLAMO_REG_LCD_WFORM_DELAY2 = REG_LCD(0xb2),
/* RES */
GLAMO_REG_LCD_GAMMA_CORR = REG_LCD(0x100),
/* RES */
GLAMO_REG_LCD_GAMMA_R_ENTRY01 = REG_LCD(0x110),
GLAMO_REG_LCD_GAMMA_R_ENTRY23 = REG_LCD(0x112),
GLAMO_REG_LCD_GAMMA_R_ENTRY45 = REG_LCD(0x114),
GLAMO_REG_LCD_GAMMA_R_ENTRY67 = REG_LCD(0x116),
GLAMO_REG_LCD_GAMMA_R_ENTRY8 = REG_LCD(0x118),
/* RES */
GLAMO_REG_LCD_GAMMA_G_ENTRY01 = REG_LCD(0x130),
GLAMO_REG_LCD_GAMMA_G_ENTRY23 = REG_LCD(0x132),
GLAMO_REG_LCD_GAMMA_G_ENTRY45 = REG_LCD(0x134),
GLAMO_REG_LCD_GAMMA_G_ENTRY67 = REG_LCD(0x136),
GLAMO_REG_LCD_GAMMA_G_ENTRY8 = REG_LCD(0x138),
/* RES */
GLAMO_REG_LCD_GAMMA_B_ENTRY01 = REG_LCD(0x150),
GLAMO_REG_LCD_GAMMA_B_ENTRY23 = REG_LCD(0x152),
GLAMO_REG_LCD_GAMMA_B_ENTRY45 = REG_LCD(0x154),
GLAMO_REG_LCD_GAMMA_B_ENTRY67 = REG_LCD(0x156),
GLAMO_REG_LCD_GAMMA_B_ENTRY8 = REG_LCD(0x158),
/* RES */
GLAMO_REG_LCD_SRAM_DRIVING1 = REG_LCD(0x160),
GLAMO_REG_LCD_SRAM_DRIVING2 = REG_LCD(0x162),
GLAMO_REG_LCD_SRAM_DRIVING3 = REG_LCD(0x164),
};
enum glamo_reg_lcd_mode1 {
GLAMO_LCD_MODE1_PWRSAVE = 0x0001,
GLAMO_LCD_MODE1_PARTIAL_PRT = 0x0002,
GLAMO_LCD_MODE1_HWFLIP = 0x0004,
GLAMO_LCD_MODE1_LCD2 = 0x0008,
/* RES */
GLAMO_LCD_MODE1_PARTIAL_MODE = 0x0020,
GLAMO_LCD_MODE1_CURSOR_DSTCOLOR = 0x0040,
GLAMO_LCD_MODE1_PARTIAL_ENABLE = 0x0080,
GLAMO_LCD_MODE1_TVCLK_IN_ENABLE = 0x0100,
GLAMO_LCD_MODE1_HSYNC_HIGH_ACT = 0x0200,
GLAMO_LCD_MODE1_VSYNC_HIGH_ACT = 0x0400,
GLAMO_LCD_MODE1_HSYNC_FLIP = 0x0800,
GLAMO_LCD_MODE1_GAMMA_COR_EN = 0x1000,
GLAMO_LCD_MODE1_DITHER_EN = 0x2000,
GLAMO_LCD_MODE1_CURSOR_EN = 0x4000,
GLAMO_LCD_MODE1_ROTATE_EN = 0x8000,
};
enum glamo_reg_lcd_mode2 {
GLAMO_LCD_MODE2_CRC_CHECK_EN = 0x0001,
GLAMO_LCD_MODE2_DCMD_PER_LINE = 0x0002,
GLAMO_LCD_MODE2_NOUSE_BDEF = 0x0004,
GLAMO_LCD_MODE2_OUT_POS_MODE = 0x0008,
GLAMO_LCD_MODE2_FRATE_CTRL_EN = 0x0010,
GLAMO_LCD_MODE2_SINGLE_BUFFER = 0x0020,
GLAMO_LCD_MODE2_SER_LSB_TO_MSB = 0x0040,
/* FIXME */
};
enum glamo_reg_lcd_mode3 {
/* LCD color source data format */
GLAMO_LCD_SRC_RGB565 = 0x0000,
GLAMO_LCD_SRC_ARGB1555 = 0x4000,
GLAMO_LCD_SRC_ARGB4444 = 0x8000,
/* interface type */
GLAMO_LCD_MODE3_LCD = 0x1000,
GLAMO_LCD_MODE3_RGB = 0x0800,
GLAMO_LCD_MODE3_CPU = 0x0000,
/* mode */
GLAMO_LCD_MODE3_RGB332 = 0x0000,
GLAMO_LCD_MODE3_RGB444 = 0x0100,
GLAMO_LCD_MODE3_RGB565 = 0x0200,
GLAMO_LCD_MODE3_RGB666 = 0x0300,
/* depth */
GLAMO_LCD_MODE3_6BITS = 0x0000,
GLAMO_LCD_MODE3_8BITS = 0x0010,
GLAMO_LCD_MODE3_9BITS = 0x0020,
GLAMO_LCD_MODE3_16BITS = 0x0030,
GLAMO_LCD_MODE3_18BITS = 0x0040,
};
enum glamo_lcd_rot_mode {
GLAMO_LCD_ROT_MODE_0 = 0x0000,
GLAMO_LCD_ROT_MODE_180 = 0x2000,
GLAMO_LCD_ROT_MODE_MIRROR = 0x4000,
GLAMO_LCD_ROT_MODE_FLIP = 0x6000,
GLAMO_LCD_ROT_MODE_90 = 0x8000,
GLAMO_LCD_ROT_MODE_270 = 0xa000,
};
#define GLAMO_LCD_ROT_MODE_MASK 0xe000
enum glamo_lcd_cmd_type {
GLAMO_LCD_CMD_TYPE_DISP = 0x0000,
GLAMO_LCD_CMD_TYPE_PARALLEL = 0x4000,
GLAMO_LCD_CMD_TYPE_SERIAL = 0x8000,
GLAMO_LCD_CMD_TYPE_SERIAL_DIRECT= 0xc000,
};
#define GLAMO_LCD_CMD_TYPE_MASK 0xc000
enum glamo_lcd_cmds {
GLAMO_LCD_CMD_DATA_DISP_FIRE = 0x00,
GLAMO_LCD_CMD_DATA_DISP_SYNC = 0x01, /* RGB only */
/* switch to command mode, no display */
GLAMO_LCD_CMD_DATA_FIRE_NO_DISP = 0x02,
/* display until VSYNC, switch to command */
GLAMO_LCD_CMD_DATA_FIRE_VSYNC = 0x11,
/* display until HSYNC, switch to command */
GLAMO_LCD_CMD_DATA_FIRE_HSYNC = 0x12,
/* display until VSYNC, 1 black frame, VSYNC, switch to command */
GLAMO_LCD_CMD_DATA_FIRE_VSYNC_B = 0x13,
/* don't care about display and switch to command */
GLAMO_LCD_CMD_DATA_FIRE_FREE = 0x14, /* RGB only */
/* don't care about display, keep data display but disable data,
* and switch to command */
GLAMO_LCD_CMD_DATA_FIRE_FREE_D = 0x15, /* RGB only */
};
enum glamo_core_revisions {
GLAMO_CORE_REV_A0 = 0x0000,
GLAMO_CORE_REV_A1 = 0x0001,
GLAMO_CORE_REV_A2 = 0x0002,
GLAMO_CORE_REV_A3 = 0x0003,
};
#endif /* _GLAMO_REGS_H */

View File

@ -1,3 +0,0 @@
#include <i2c-bitbang.h>
extern struct i2c_bitbang bb_s3c24xx;

View File

@ -1,3 +0,0 @@
#include <i2c-bitbang.h>
extern struct i2c_bitbang bb_s3c6410;

View File

@ -1,102 +0,0 @@
/*
* (C) Copyright 2007 OpenMoko, Inc.
* Author: Andy Green <andy@openmoko.com>
*
* Generic i2c bitbang state machine
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
/* controls symbol sequencing on i2c */
enum i2c_bitbang_control {
IBCONTROL_DO_START = -1,
IBCONTROL_DO_STOP = -2,
IBCONTROL_DO_READ = -3,
IBCONTROL_COMPLETE = -4
};
/* control intra-bit and byte states */
enum i2c_bitbang_states {
IBS_INIT,
IBS_START1,
IBS_START2,
IBS_ADS_TX_S,
IBS_ADS_TX_H,
IBS_ADS_TX_L,
IBS_ADS_TX_ACK_H,
IBS_ADS_TX_ACK_L,
IBS_DATA_RX_S,
IBS_DATA_RX_H,
IBS_DATA_RX_L,
IBS_DATA_RX_ACK_H,
IBS_DATA_RX_ACK_L,
IBS_STOP1,
IBS_STOP2,
IBS_STOP3,
IBS_STOP4
};
/* context for bitbang GPIO pins and transaction */
struct i2c_bitbang {
enum i2c_bitbang_states state;
int count;
unsigned int data[8]; /* read result found here */
int index;
int index_read;
char (*read_sda)(void);
/* data = 0 = op low, 1 == inp */
void (*set)(char clock, char data);
/* delay > 1 half-bit time, used by i2c_complete_synchronously() */
void (*spin)(void);
void (*close)(void);
};
/* synchronous read and write functions spin until completed or failed
* i2c_read_sync returns -1 for fail or byte result from device
*/
extern int i2c_read_sync(struct i2c_bitbang * bb, unsigned char ads7,
unsigned char reg);
extern void i2c_write_sync(struct i2c_bitbang * bb, unsigned char ads7,
unsigned char reg, unsigned char data);
/*
* set up an asynchronous read or write transaction
*/
extern void i2c_read(struct i2c_bitbang * bb, unsigned char ads7,
unsigned char reg);
extern void i2c_write(struct i2c_bitbang * bb, unsigned char ads7,
unsigned char reg, unsigned char data);
/*
* after setting up a read or write transaction above, you loop calling this
* with >= 1.25us (400kHz) or >= 5us (100kHz) delay between calls. You don't
* have to spin but can do something useful if you know it will take more than
* an i2c bit-time, hiding the time for the i2c transaction completely.
*/
extern int i2c_next_state(struct i2c_bitbang * bb); /* return !=0 = completed */

View File

@ -1,570 +0,0 @@
/*
* (C) Copyright 2008 Semihalf
*
* (C) Copyright 2000-2005
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
********************************************************************
* NOTE: This header file defines an interface to U-Boot. Including
* this (unmodified) header file in another file is considered normal
* use of U-Boot, and does *not* fall under the heading of "derived
* work".
********************************************************************
*/
#ifndef __IMAGE_H__
#define __IMAGE_H__
/*
* Operating System Codes
*/
#define IH_OS_INVALID 0 /* Invalid OS */
#define IH_OS_OPENBSD 1 /* OpenBSD */
#define IH_OS_NETBSD 2 /* NetBSD */
#define IH_OS_FREEBSD 3 /* FreeBSD */
#define IH_OS_4_4BSD 4 /* 4.4BSD */
#define IH_OS_LINUX 5 /* Linux */
#define IH_OS_SVR4 6 /* SVR4 */
#define IH_OS_ESIX 7 /* Esix */
#define IH_OS_SOLARIS 8 /* Solaris */
#define IH_OS_IRIX 9 /* Irix */
#define IH_OS_SCO 10 /* SCO */
#define IH_OS_DELL 11 /* Dell */
#define IH_OS_NCR 12 /* NCR */
#define IH_OS_LYNXOS 13 /* LynxOS */
#define IH_OS_VXWORKS 14 /* VxWorks */
#define IH_OS_PSOS 15 /* pSOS */
#define IH_OS_QNX 16 /* QNX */
#define IH_OS_U_BOOT 17 /* Firmware */
#define IH_OS_RTEMS 18 /* RTEMS */
#define IH_OS_ARTOS 19 /* ARTOS */
#define IH_OS_UNITY 20 /* Unity OS */
/*
* CPU Architecture Codes (supported by Linux)
*/
#define IH_ARCH_INVALID 0 /* Invalid CPU */
#define IH_ARCH_ALPHA 1 /* Alpha */
#define IH_ARCH_ARM 2 /* ARM */
#define IH_ARCH_I386 3 /* Intel x86 */
#define IH_ARCH_IA64 4 /* IA64 */
#define IH_ARCH_MIPS 5 /* MIPS */
#define IH_ARCH_MIPS64 6 /* MIPS 64 Bit */
#define IH_ARCH_PPC 7 /* PowerPC */
#define IH_ARCH_S390 8 /* IBM S390 */
#define IH_ARCH_SH 9 /* SuperH */
#define IH_ARCH_SPARC 10 /* Sparc */
#define IH_ARCH_SPARC64 11 /* Sparc 64 Bit */
#define IH_ARCH_M68K 12 /* M68K */
#define IH_ARCH_NIOS 13 /* Nios-32 */
#define IH_ARCH_MICROBLAZE 14 /* MicroBlaze */
#define IH_ARCH_NIOS2 15 /* Nios-II */
#define IH_ARCH_BLACKFIN 16 /* Blackfin */
#define IH_ARCH_AVR32 17 /* AVR32 */
#define IH_ARCH_ST200 18 /* STMicroelectronics ST200 */
/*
* Image Types
*
* "Standalone Programs" are directly runnable in the environment
* provided by U-Boot; it is expected that (if they behave
* well) you can continue to work in U-Boot after return from
* the Standalone Program.
* "OS Kernel Images" are usually images of some Embedded OS which
* will take over control completely. Usually these programs
* will install their own set of exception handlers, device
* drivers, set up the MMU, etc. - this means, that you cannot
* expect to re-enter U-Boot except by resetting the CPU.
* "RAMDisk Images" are more or less just data blocks, and their
* parameters (address, size) are passed to an OS kernel that is
* being started.
* "Multi-File Images" contain several images, typically an OS
* (Linux) kernel image and one or more data images like
* RAMDisks. This construct is useful for instance when you want
* to boot over the network using BOOTP etc., where the boot
* server provides just a single image file, but you want to get
* for instance an OS kernel and a RAMDisk image.
*
* "Multi-File Images" start with a list of image sizes, each
* image size (in bytes) specified by an "uint32_t" in network
* byte order. This list is terminated by an "(uint32_t)0".
* Immediately after the terminating 0 follow the images, one by
* one, all aligned on "uint32_t" boundaries (size rounded up to
* a multiple of 4 bytes - except for the last file).
*
* "Firmware Images" are binary images containing firmware (like
* U-Boot or FPGA images) which usually will be programmed to
* flash memory.
*
* "Script files" are command sequences that will be executed by
* U-Boot's command interpreter; this feature is especially
* useful when you configure U-Boot to use a real shell (hush)
* as command interpreter (=> Shell Scripts).
*/
#define IH_TYPE_INVALID 0 /* Invalid Image */
#define IH_TYPE_STANDALONE 1 /* Standalone Program */
#define IH_TYPE_KERNEL 2 /* OS Kernel Image */
#define IH_TYPE_RAMDISK 3 /* RAMDisk Image */
#define IH_TYPE_MULTI 4 /* Multi-File Image */
#define IH_TYPE_FIRMWARE 5 /* Firmware Image */
#define IH_TYPE_SCRIPT 6 /* Script file */
#define IH_TYPE_FILESYSTEM 7 /* Filesystem Image (any type) */
#define IH_TYPE_FLATDT 8 /* Binary Flat Device Tree Blob */
/*
* Compression Types
*/
#define IH_COMP_NONE 0 /* No Compression Used */
#define IH_COMP_GZIP 1 /* gzip Compression Used */
#define IH_COMP_BZIP2 2 /* bzip2 Compression Used */
#define IH_MAGIC 0x27051956 /* Image Magic Number */
#define IH_NMLEN 32 /* Image Name Length */
/*
* Legacy format image header,
* all data in network byte order (aka natural aka bigendian).
*/
typedef struct image_header {
uint32_t ih_magic; /* Image Header Magic Number */
uint32_t ih_hcrc; /* Image Header CRC Checksum */
uint32_t ih_time; /* Image Creation Timestamp */
uint32_t ih_size; /* Image Data Size */
uint32_t ih_load; /* Data Load Address */
uint32_t ih_ep; /* Entry Point Address */
uint32_t ih_dcrc; /* Image Data CRC Checksum */
uint8_t ih_os; /* Operating System */
uint8_t ih_arch; /* CPU architecture */
uint8_t ih_type; /* Image Type */
uint8_t ih_comp; /* Compression Type */
uint8_t ih_name[IH_NMLEN]; /* Image Name */
} image_header_t;
/*
* Legacy and FIT format headers used by do_bootm() and do_bootm_<os>()
* routines.
*/
typedef struct bootm_headers {
/*
* Legacy os image header, if it is a multi component image
* then boot_get_ramdisk() and get_fdt() will attempt to get
* data from second and third component accordingly.
*/
image_header_t *legacy_hdr_os;
ulong legacy_hdr_valid;
#if defined(CONFIG_FIT)
const char *fit_uname_cfg; /* configuration node unit name */
void *fit_hdr_os; /* os FIT image header */
const char *fit_uname_os; /* os subimage node unit name */
int fit_noffset_os; /* os subimage node offset */
void *fit_hdr_rd; /* init ramdisk FIT image header */
const char *fit_uname_rd; /* init ramdisk subimage node unit name */
int fit_noffset_rd; /* init ramdisk subimage node offset */
#if defined(CONFIG_PPC)
void *fit_hdr_fdt; /* FDT blob FIT image header */
const char *fit_uname_fdt; /* FDT blob subimage node unit name */
int fit_noffset_fdt;/* FDT blob subimage node offset */
#endif
#endif
int verify; /* getenv("verify")[0] != 'n' */
int autostart; /* getenv("autostart")[0] != 'n' */
struct lmb *lmb; /* for memory mgmt */
} bootm_headers_t;
/*
* Some systems (for example LWMON) have very short watchdog periods;
* we must make sure to split long operations like memmove() or
* crc32() into reasonable chunks.
*/
#define CHUNKSZ (64 * 1024)
#define uimage_to_cpu(x) __be32_to_cpu(x)
#define cpu_to_uimage(x) __cpu_to_be32(x)
const char *genimg_get_os_name (uint8_t os);
const char *genimg_get_arch_name (uint8_t arch);
const char *genimg_get_type_name (uint8_t type);
const char *genimg_get_comp_name (uint8_t comp);
int genimg_get_os_id (const char *name);
int genimg_get_arch_id (const char *name);
int genimg_get_type_id (const char *name);
int genimg_get_comp_id (const char *name);
#ifndef USE_HOSTCC
/* Image format types, returned by _get_format() routine */
#define IMAGE_FORMAT_INVALID 0x00
#define IMAGE_FORMAT_LEGACY 0x01 /* legacy image_header based format */
#define IMAGE_FORMAT_FIT 0x02 /* new, libfdt based format */
int genimg_get_format (void *img_addr);
int genimg_has_config (bootm_headers_t *images);
ulong genimg_get_image (ulong img_addr);
int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images,
uint8_t arch, ulong *rd_start, ulong *rd_end);
#if defined(CONFIG_PPC) || defined(CONFIG_M68K)
int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len,
ulong *initrd_start, ulong *initrd_end);
int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end,
ulong bootmap_base);
int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base);
#endif /* CONFIG_PPC || CONFIG_M68K */
#endif /* !USE_HOSTCC */
/*******************************************************************/
/* Legacy format specific code (prefixed with image_) */
/*******************************************************************/
static inline uint32_t image_get_header_size (void)
{
return (sizeof (image_header_t));
}
#define image_get_hdr_l(f) \
static inline uint32_t image_get_##f(image_header_t *hdr) \
{ \
return uimage_to_cpu (hdr->ih_##f); \
}
image_get_hdr_l (magic);
image_get_hdr_l (hcrc);
image_get_hdr_l (time);
image_get_hdr_l (size);
image_get_hdr_l (load);
image_get_hdr_l (ep);
image_get_hdr_l (dcrc);
#define image_get_hdr_b(f) \
static inline uint8_t image_get_##f(image_header_t *hdr) \
{ \
return hdr->ih_##f; \
}
image_get_hdr_b (os);
image_get_hdr_b (arch);
image_get_hdr_b (type);
image_get_hdr_b (comp);
static inline char *image_get_name (image_header_t *hdr)
{
return (char *)hdr->ih_name;
}
static inline uint32_t image_get_data_size (image_header_t *hdr)
{
return image_get_size (hdr);
}
/**
* image_get_data - get image payload start address
* @hdr: image header
*
* image_get_data() returns address of the image payload. For single
* component images it is image data start. For multi component
* images it points to the null terminated table of sub-images sizes.
*
* returns:
* image payload data start address
*/
static inline ulong image_get_data (image_header_t *hdr)
{
return ((ulong)hdr + image_get_header_size ());
}
static inline uint32_t image_get_image_size (image_header_t *hdr)
{
return (image_get_size (hdr) + image_get_header_size ());
}
static inline ulong image_get_image_end (image_header_t *hdr)
{
return ((ulong)hdr + image_get_image_size (hdr));
}
#define image_set_hdr_l(f) \
static inline void image_set_##f(image_header_t *hdr, uint32_t val) \
{ \
hdr->ih_##f = cpu_to_uimage (val); \
}
image_set_hdr_l (magic);
image_set_hdr_l (hcrc);
image_set_hdr_l (time);
image_set_hdr_l (size);
image_set_hdr_l (load);
image_set_hdr_l (ep);
image_set_hdr_l (dcrc);
#define image_set_hdr_b(f) \
static inline void image_set_##f(image_header_t *hdr, uint8_t val) \
{ \
hdr->ih_##f = val; \
}
image_set_hdr_b (os);
image_set_hdr_b (arch);
image_set_hdr_b (type);
image_set_hdr_b (comp);
static inline void image_set_name (image_header_t *hdr, const char *name)
{
strncpy (image_get_name (hdr), name, IH_NMLEN);
}
int image_check_hcrc (image_header_t *hdr);
int image_check_dcrc (image_header_t *hdr);
#ifndef USE_HOSTCC
int image_check_dcrc_wd (image_header_t *hdr, ulong chunksize);
int getenv_verify (void);
int getenv_autostart (void);
ulong getenv_bootm_low(void);
ulong getenv_bootm_size(void);
void memmove_wd (void *to, void *from, size_t len, ulong chunksz);
#endif
static inline int image_check_magic (image_header_t *hdr)
{
return (image_get_magic (hdr) == IH_MAGIC);
}
static inline int image_check_type (image_header_t *hdr, uint8_t type)
{
return (image_get_type (hdr) == type);
}
static inline int image_check_arch (image_header_t *hdr, uint8_t arch)
{
return (image_get_arch (hdr) == arch);
}
static inline int image_check_os (image_header_t *hdr, uint8_t os)
{
return (image_get_os (hdr) == os);
}
ulong image_multi_count (image_header_t *hdr);
void image_multi_getimg (image_header_t *hdr, ulong idx,
ulong *data, ulong *len);
inline void image_print_contents (image_header_t *hdr);
inline void image_print_contents_noindent (image_header_t *hdr);
#ifndef USE_HOSTCC
static inline int image_check_target_arch (image_header_t *hdr)
{
#if defined(__ARM__)
if (!image_check_arch (hdr, IH_ARCH_ARM))
#elif defined(__avr32__)
if (!image_check_arch (hdr, IH_ARCH_AVR32))
#elif defined(__bfin__)
if (!image_check_arch (hdr, IH_ARCH_BLACKFIN))
#elif defined(__I386__)
if (!image_check_arch (hdr, IH_ARCH_I386))
#elif defined(__M68K__)
if (!image_check_arch (hdr, IH_ARCH_M68K))
#elif defined(__microblaze__)
if (!image_check_arch (hdr, IH_ARCH_MICROBLAZE))
#elif defined(__mips__)
if (!image_check_arch (hdr, IH_ARCH_MIPS))
#elif defined(__nios__)
if (!image_check_arch (hdr, IH_ARCH_NIOS))
#elif defined(__nios2__)
if (!image_check_arch (hdr, IH_ARCH_NIOS2))
#elif defined(__PPC__)
if (!image_check_arch (hdr, IH_ARCH_PPC))
#elif defined(__sh__)
if (!image_check_arch (hdr, IH_ARCH_SH))
#else
# error Unknown CPU type
#endif
return 0;
return 1;
}
#endif /* USE_HOSTCC */
/*******************************************************************/
/* New uImage format specific code (prefixed with fit_) */
/*******************************************************************/
#if defined(CONFIG_FIT)
#define FIT_IMAGES_PATH "/images"
#define FIT_CONFS_PATH "/configurations"
/* hash node */
#define FIT_HASH_NODENAME "hash"
#define FIT_ALGO_PROP "algo"
#define FIT_VALUE_PROP "value"
/* image node */
#define FIT_DATA_PROP "data"
#define FIT_TIMESTAMP_PROP "timestamp"
#define FIT_DESC_PROP "description"
#define FIT_ARCH_PROP "arch"
#define FIT_TYPE_PROP "type"
#define FIT_OS_PROP "os"
#define FIT_COMP_PROP "compression"
#define FIT_ENTRY_PROP "entry"
#define FIT_LOAD_PROP "load"
/* configuration node */
#define FIT_KERNEL_PROP "kernel"
#define FIT_RAMDISK_PROP "ramdisk"
#define FIT_FDT_PROP "fdt"
#define FIT_DEFAULT_PROP "default"
#define FIT_MAX_HASH_LEN 20 /* max(crc32_len(4), sha1_len(20)) */
/* cmdline argument format parsing */
inline int fit_parse_conf (const char *spec, ulong addr_curr,
ulong *addr, const char **conf_name);
inline int fit_parse_subimage (const char *spec, ulong addr_curr,
ulong *addr, const char **image_name);
inline void fit_print_contents (const void *fit);
inline void fit_print_contents_noindent (const void *fit);
void fit_image_print (const void *fit, int noffset, const char *p);
void fit_image_print_hash (const void *fit, int noffset, const char *p);
/**
* fit_get_end - get FIT image size
* @fit: pointer to the FIT format image header
*
* returns:
* size of the FIT image (blob) in memory
*/
static inline ulong fit_get_size (const void *fit)
{
return fdt_totalsize (fit);
}
/**
* fit_get_end - get FIT image end
* @fit: pointer to the FIT format image header
*
* returns:
* end address of the FIT image (blob) in memory
*/
static inline ulong fit_get_end (const void *fit)
{
return (ulong)fit + fdt_totalsize (fit);
}
/**
* fit_get_name - get FIT node name
* @fit: pointer to the FIT format image header
*
* returns:
* NULL, on error
* pointer to node name, on success
*/
static inline const char *fit_get_name (const void *fit_hdr,
int noffset, int *len)
{
return fdt_get_name (fit_hdr, noffset, len);
}
int fit_get_desc (const void *fit, int noffset, char **desc);
int fit_get_timestamp (const void *fit, int noffset, time_t *timestamp);
int fit_image_get_node (const void *fit, const char *image_uname);
int fit_image_get_os (const void *fit, int noffset, uint8_t *os);
int fit_image_get_arch (const void *fit, int noffset, uint8_t *arch);
int fit_image_get_type (const void *fit, int noffset, uint8_t *type);
int fit_image_get_comp (const void *fit, int noffset, uint8_t *comp);
int fit_image_get_load (const void *fit, int noffset, ulong *load);
int fit_image_get_entry (const void *fit, int noffset, ulong *entry);
int fit_image_get_data (const void *fit, int noffset,
const void **data, size_t *size);
int fit_image_hash_get_algo (const void *fit, int noffset, char **algo);
int fit_image_hash_get_value (const void *fit, int noffset, uint8_t **value,
int *value_len);
int fit_set_timestamp (void *fit, int noffset, time_t timestamp);
int fit_set_hashes (void *fit);
int fit_image_set_hashes (void *fit, int image_noffset);
int fit_image_hash_set_value (void *fit, int noffset, uint8_t *value,
int value_len);
int fit_image_check_hashes (const void *fit, int noffset);
int fit_image_check_os (const void *fit, int noffset, uint8_t os);
int fit_image_check_arch (const void *fit, int noffset, uint8_t arch);
int fit_image_check_type (const void *fit, int noffset, uint8_t type);
int fit_image_check_comp (const void *fit, int noffset, uint8_t comp);
int fit_check_format (const void *fit);
int fit_conf_get_node (const void *fit, const char *conf_uname);
int fit_conf_get_kernel_node (const void *fit, int noffset);
int fit_conf_get_ramdisk_node (const void *fit, int noffset);
int fit_conf_get_fdt_node (const void *fit, int noffset);
void fit_conf_print (const void *fit, int noffset, const char *p);
#ifndef USE_HOSTCC
static inline int fit_image_check_target_arch (const void *fdt, int node)
{
#if defined(__ARM__)
if (!fit_image_check_arch (fdt, node, IH_ARCH_ARM))
#elif defined(__avr32__)
if (!fit_image_check_arch (fdt, node, IH_ARCH_AVR32))
#elif defined(__bfin__)
if (!fit_image_check_arch (fdt, node, IH_ARCH_BLACKFIN))
#elif defined(__I386__)
if (!fit_image_check_arch (fdt, node, IH_ARCH_I386))
#elif defined(__M68K__)
if (!fit_image_check_arch (fdt, node, IH_ARCH_M68K))
#elif defined(__microblaze__)
if (!fit_image_check_arch (fdt, node, IH_ARCH_MICROBLAZE))
#elif defined(__mips__)
if (!fit_image_check_arch (fdt, node, IH_ARCH_MIPS))
#elif defined(__nios__)
if (!fit_image_check_arch (fdt, node, IH_ARCH_NIOS))
#elif defined(__nios2__)
if (!fit_image_check_arch (fdt, node, IH_ARCH_NIOS2))
#elif defined(__PPC__)
if (!fit_image_check_arch (fdt, node, IH_ARCH_PPC))
#elif defined(__sh__)
if (!fit_image_check_arch (fdt, node, IH_ARCH_SH))
#else
# error Unknown CPU type
#endif
return 0;
return 1;
}
#endif /* USE_HOSTCC */
#ifdef CONFIG_FIT_VERBOSE
#define fit_unsupported(msg) printf ("! %s:%d " \
"FIT images not supported for '%s'\n", \
__FILE__, __LINE__, (msg))
#define fit_unsupported_reset(msg) printf ("! %s:%d " \
"FIT images not supported for '%s' " \
"- must reset board to recover!\n", \
__FILE__, __LINE__, (msg))
#else
#define fit_unsupported(msg)
#define fit_unsupported_reset(msg)
#endif /* CONFIG_FIT_VERBOSE */
#endif /* CONFIG_FIT */
#endif /* __IMAGE_H__ */

View File

@ -1,382 +0,0 @@
/*
* Header for MultiMediaCard (MMC)
*
* Copyright 2002 Hewlett-Packard Company
*
* Use consistent with the GNU GPL is permitted,
* provided that this copyright notice is
* preserved in its entirety in all copies and derived works.
*
* HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
* FITNESS FOR ANY PARTICULAR PURPOSE.
*
* Many thanks to Alessandro Rubini and Jonathan Corbet!
*
* Based strongly on code by:
*
* Author: Yong-iL Joh <tolkien@mizi.com>
* Date : $Date: 2006/12/06 02:50:52 $
*
* Author: Andrew Christian
* 15 May 2002
*/
#ifndef MMC_MMC_PROTOCOL_H
#define MMC_MMC_PROTOCOL_H
#ifdef CONFIG_SUPPORT_MMC_PLUS
/* Standard MMC commands (4.2) type argument response */
#else
/* Standard MMC commands (3.1) type argument response */
#endif
/* class 1 */
#define MMC_GO_IDLE_STATE 0 /* bc */
#define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */
#define MMC_ALL_SEND_CID 2 /* bcr R2 */
#define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */
#define MMC_SET_DSR 4 /* bc [31:16] RCA */
#define MMC_SWITCH 6 /* ac R1b */
#define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */
#define MMC_SEND_EXT_CSD 8 /* adtc R1 */
#define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */
#define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */
#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
#define MMC_STOP_TRANSMISSION 12 /* ac R1b */
#define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */
#define MMC_BUSTEST_R 14 /* adtc R1 */
#define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */
#define MMC_BUSTEST_W 19 /* adtc R1 */
/* class 2 */
#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */
#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
/* class 3 */
#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
/* class 4 */
#define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */
#define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */
#define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */
#define MMC_PROGRAM_CID 26 /* adtc R1 */
#define MMC_PROGRAM_CSD 27 /* adtc R1 */
/* class 6 */
#define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */
#define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */
#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
/* class 5 */
#define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */
#define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */
#define MMC_ERASE 38 /* ac R1b */
/* class 9 */
#define MMC_FAST_IO 39 /* ac <Complex> R4 */
#define MMC_GO_IRQ_STATE 40 /* bcr R5 */
/* class 7 */
#define MMC_LOCK_UNLOCK 42 /* adtc R1b */
/* class 8 */
#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */
#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */
/* SD commands type argument response */
/* class 8 */
/* This is basically the same command as for MMC with some quirks. */
#define SD_SEND_RELATIVE_ADDR 3 /* ac R6 */
/* Application commands */
#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
#define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */
#define SD_APP_SEND_SCR 51 /* adtc R1 */
/*
MMC status in R1
Type
e : error bit
s : status bit
r : detected and set for the actual command response
x : detected and set during command execution. the host must poll
the card by sending status command in order to read these bits.
Clear condition
a : according to the card state
b : always related to the previous command. Reception of
a valid command will clear it (with a delay of one command)
c : clear by read
*/
#define R1_OUT_OF_RANGE (1 << 31) /* er, c */
#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */
#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */
#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */
#define R1_ERASE_PARAM (1 << 27) /* ex, c */
#define R1_WP_VIOLATION (1 << 26) /* erx, c */
#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */
#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */
#define R1_COM_CRC_ERROR (1 << 23) /* er, b */
#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */
#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */
#define R1_CC_ERROR (1 << 20) /* erx, c */
#define R1_ERROR (1 << 19) /* erx, c */
#define R1_UNDERRUN (1 << 18) /* ex, c */
#define R1_OVERRUN (1 << 17) /* ex, c */
#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */
#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
#define R1_ERASE_RESET (1 << 13) /* sr, c */
#define R1_STATUS(x) (x & 0xFFFFE000)
#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */
#define R1_READY_FOR_DATA (1 << 8) /* sx, a */
#define R1_APP_CMD (1 << 5) /* sr, c */
/*
MMC CURRENT_STATE in R1 [12:9]
*/
#define STATE_IDLE (0x0 << 9) /* 0 */
#define STATE_READY (0x1 << 9) /* 1 */
#define STATE_IDENT (0x2 << 9) /* 2 */
#define STATE_STBY (0x3 << 9) /* 3 */
#define STATE_TRAN (0x4 << 9) /* 4 */
#define STATE_DATA (0x5 << 9) /* 5 */
#define STATE_RCV (0x6 << 9) /* 6 */
#define STATE_PRG (0x7 << 9) /* 7 */
#define STATE_DIS (0x8 << 9) /* 8 */
#define STATE_BTST (0x9 << 9) /* 9 */
/* These are unpacked versions of the actual responses */
struct _mmc_csd {
u8 csd_structure;
u8 spec_vers;
u8 taac;
u8 nsac;
u8 tran_speed;
u16 ccc;
u8 read_bl_len;
u8 read_bl_partial;
u8 write_blk_misalign;
u8 read_blk_misalign;
u8 dsr_imp;
u16 c_size;
u8 vdd_r_curr_min;
u8 vdd_r_curr_max;
u8 vdd_w_curr_min;
u8 vdd_w_curr_max;
u8 c_size_mult;
union {
struct { /* MMC system specification version 3.1 */
u8 erase_grp_size;
u8 erase_grp_mult;
} v31;
struct { /* MMC system specification version 2.2 */
u8 sector_size;
u8 erase_grp_size;
} v22;
} erase;
u8 wp_grp_size;
u8 wp_grp_enable;
u8 default_ecc;
u8 r2w_factor;
u8 write_bl_len;
u8 write_bl_partial;
u8 file_format_grp;
u8 copy;
u8 perm_write_protect;
u8 tmp_write_protect;
u8 file_format;
u8 ecc;
};
struct _mmc_ext_csd {
u8 s_cmd_set;
u32 sec_count;
u8 MIN_PERF_W_8_52;
u8 MIN_PERF_R_8_52;
u8 MIN_PERF_W_8_26_4_52;
u8 MIN_PERF_R_8_26_4_52;
u8 MIN_PERF_W_4_26;
u8 MIN_PERF_R_4_26;
u8 PWR_CL_26_360;
u8 PWR_CL_52_360;
u8 PWR_CL_26_195;
u8 PWR_CL_52_195;
u8 card_type;
u8 csd_structure;
u8 ext_csd_rev;
u8 cmd_set;
u8 cmd_set_rev;
u8 power_class;
u8 hs_timing;
u8 bus_width;
};
#define MMC_VDD_145_150 0x00000001 /* VDD voltage 1.45 - 1.50 */
#define MMC_VDD_150_155 0x00000002 /* VDD voltage 1.50 - 1.55 */
#define MMC_VDD_155_160 0x00000004 /* VDD voltage 1.55 - 1.60 */
#define MMC_VDD_160_165 0x00000008 /* VDD voltage 1.60 - 1.65 */
#define MMC_VDD_165_170 0x00000010 /* VDD voltage 1.65 - 1.70 */
#define MMC_VDD_17_18 0x00000020 /* VDD voltage 1.7 - 1.8 */
#define MMC_VDD_18_19 0x00000040 /* VDD voltage 1.8 - 1.9 */
#define MMC_VDD_19_20 0x00000080 /* VDD voltage 1.9 - 2.0 */
#define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */
#define MMC_VDD_21_22 0x00000200 /* VDD voltage 2.1 ~ 2.2 */
#define MMC_VDD_22_23 0x00000400 /* VDD voltage 2.2 ~ 2.3 */
#define MMC_VDD_23_24 0x00000800 /* VDD voltage 2.3 ~ 2.4 */
#define MMC_VDD_24_25 0x00001000 /* VDD voltage 2.4 ~ 2.5 */
#define MMC_VDD_25_26 0x00002000 /* VDD voltage 2.5 ~ 2.6 */
#define MMC_VDD_26_27 0x00004000 /* VDD voltage 2.6 ~ 2.7 */
#define MMC_VDD_27_28 0x00008000 /* VDD voltage 2.7 ~ 2.8 */
#define MMC_VDD_28_29 0x00010000 /* VDD voltage 2.8 ~ 2.9 */
#define MMC_VDD_29_30 0x00020000 /* VDD voltage 2.9 ~ 3.0 */
#define MMC_VDD_30_31 0x00040000 /* VDD voltage 3.0 ~ 3.1 */
#define MMC_VDD_31_32 0x00080000 /* VDD voltage 3.1 ~ 3.2 */
#define MMC_VDD_32_33 0x00100000 /* VDD voltage 3.2 ~ 3.3 */
#define MMC_VDD_33_34 0x00200000 /* VDD voltage 3.3 ~ 3.4 */
#define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */
#define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */
#define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */
/*
* Card Command Classes (CCC)
*/
#define CCC_BASIC (1<<0) /* (0) Basic protocol functions */
/* (CMD0,1,2,3,4,7,9,10,12,13,15) */
#define CCC_STREAM_READ (1<<1) /* (1) Stream read commands */
/* (CMD11) */
#define CCC_BLOCK_READ (1<<2) /* (2) Block read commands */
/* (CMD16,17,18) */
#define CCC_STREAM_WRITE (1<<3) /* (3) Stream write commands */
/* (CMD20) */
#define CCC_BLOCK_WRITE (1<<4) /* (4) Block write commands */
/* (CMD16,24,25,26,27) */
#define CCC_ERASE (1<<5) /* (5) Ability to erase blocks */
/* (CMD32,33,34,35,36,37,38,39) */
#define CCC_WRITE_PROT (1<<6) /* (6) Able to write protect blocks */
/* (CMD28,29,30) */
#define CCC_LOCK_CARD (1<<7) /* (7) Able to lock down card */
/* (CMD16,CMD42) */
#define CCC_APP_SPEC (1<<8) /* (8) Application specific */
/* (CMD55,56,57,ACMD*) */
#define CCC_IO_MODE (1<<9) /* (9) I/O mode */
/* (CMD5,39,40,52,53) */
#define CCC_SWITCH (1<<10) /* (10) High speed switch */
/* (CMD6,34,35,36,37,50) */
/* (11) Reserved */
/* (CMD?) */
/*
* CSD field definitions
*/
#define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */
#define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */
#define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 */
#define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */
#define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */
#define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */
#define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 */
#define CSD_SPEC_VER_4 4 /* Implements system specification 4.0 ~ 4.2 */
/*
* SD bus widths
*/
#define SD_BUS_WIDTH_1 0
#define SD_BUS_WIDTH_4 2
/*
* EXT_CSD field definitions
*/
/*
* S_CMD_SET
*/
#define STANDARD_MMC 0 /* Standard MMC */
#define SECURE_MMC 1 /* Secure MMC */
#define CPS_MMC 2 /* Content Protection Secure MMC */
#define SECURE_MMC_2 3 /* Secure MMC 2.0 */
#define ATA_MMC 4 /* ATA on MMC */
/*
* MIN_PERF_a_b_ff
*/
#define NO_CLASS 0x0 /* For cards not reaching the 2.4MB/s minimum value */
#define CLASS_A 0x08 /* Class A */
#define CLASS_B 0x0A /* Class B */
#define CLASS_C 0x0F /* Class C */
#define CLASS_D 0x14 /* Class D */
#define CLASS_E 0x1E /* Class E */
#define CLASS_F 0x28 /* Class F */
#define CLASS_G 0x32 /* Class G */
#define CLASS_H 0x3c /* Class H */
#define CLASS_J 0x46 /* Class J */
#define CLASS_K 0x50 /* Class E */
#define CLASS_M 0x64 /* Class M */
#define CLASS_O 0x78 /* Class O */
#define CLASS_R 0x8c /* Class R */
#define CLASS_T 0xa0 /* Class T */
/*
* CARD_TYPE
*/
#define MMCPLUS_26MHZ (1<<0)
#define MMCPLUS_52MHZ (1<<1)
/*
* EXT_CSD_REV
*/
#define EXT_CSD_REV_1_0 0
#define EXT_CSD_REV_1_1 1
#define EXT_CSD_REV_1_2 2
/*
* HS_TIMING
*/
#define HS_TIMING_LOW 0
#define HS_TIMING_HIGH 1
/*
* BUS_WIDTH
*/
#define MMCPLUS_BUS_WIDTH_1 0
#define MMCPLUS_BUS_WIDTH_4 1
#define MMCPLUS_BUS_WIDTH_8 2
/*
* ERASED_MEM_CONT
*/
#define ERASED_MEM_CONT_0 0
#define ERASED_MEM_CONT_1 1
/*
* Argument for CMD6
*/
/*
* EXT_CSD Access Modes
*/
#define EXT_CSD_COMMAND_SET 0
#define EXT_CSD_SET_BITS 1
#define EXT_CSD_CLEAR_BITS 2
#define EXT_CSD_WRITE_BYTE 3
/*
* EXT_CSD Argument Byte
*/
#define EXT_CSD_POWER_CLASS 187
#define EXT_CSD_BUS_WIDTH 183
#define EXT_CSD_HS_TIMING 185
#endif /* MMC_MMC_PROTOCOL_H */

View File

@ -1,120 +0,0 @@
/*
* linux/include/linux/mmc/mmc.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef MMC_H
#define MMC_H
/* removed by scsuh */
#if 0
#include <linux/list.h>
#include <linux/interrupt.h>
#include <linux/device.h>
struct request;
struct mmc_data;
struct mmc_request;
#endif
#define MMC_RSP_PRESENT (1 << 0)
#define MMC_RSP_136 (1 << 1) /* 136 bit response */
#define MMC_RSP_CRC (1 << 2) /* expect valid crc */
#define MMC_RSP_BUSY (1 << 3) /* card may send busy */
#define MMC_RSP_OPCODE (1 << 4) /* response contains opcode */
#define MMC_CMD_MASK (3 << 5) /* command type */
#define MMC_CMD_AC (0 << 5)
#define MMC_CMD_ADTC (1 << 5)
#define MMC_CMD_BC (2 << 5)
#define MMC_CMD_BCR (3 << 5)
/*
* These are the response types, and correspond to valid bit
* patterns of the above flags. One additional valid pattern
* is all zeros, which means we don't expect a response.
*/
#define MMC_RSP_NONE (0)
#define MMC_RSP_R1 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R1B (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)
#define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
#define MMC_RSP_R3 (MMC_RSP_PRESENT)
#define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC)
#define mmc_resp_type(cmd) ((cmd)->flags & (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE))
/*
* These are the command types.
*/
#define mmc_cmd_type(cmd) ((cmd)->flags & MMC_CMD_MASK)
#define MMC_ERR_NONE 0
#define MMC_ERR_TIMEOUT 1
#define MMC_ERR_BADCRC 2
#define MMC_ERR_FIFO 3
#define MMC_ERR_FAILED 4
#define MMC_ERR_INVALID 5
struct mmc_command {
u32 opcode;
u32 arg;
u32 resp[4];
unsigned int flags; /* expected response type */
struct mmc_data *data; /* data segment associated with cmd */
struct mmc_request *mrq; /* associated request */
unsigned int retries; /* max number of retries */
unsigned int error; /* command error */
};
struct mmc_data {
unsigned int timeout_ns; /* data timeout (in ns, max 80ms) */
unsigned int timeout_clks; /* data timeout (in clocks) */
unsigned int blksz_bits; /* data block size */
unsigned int blksz; /* data block size */
unsigned int blocks; /* number of blocks */
unsigned int error; /* data error */
unsigned int flags;
#define MMC_DATA_WRITE (1 << 8)
#define MMC_DATA_READ (1 << 9)
#define MMC_DATA_STREAM (1 << 10)
#define MMC_DATA_MULTI (1 << 11)
unsigned int bytes_xfered;
struct mmc_command *stop; /* stop command */
struct mmc_request *mrq; /* associated request */
unsigned int sg_len; /* size of scatter list */
struct scatterlist *sg; /* I/O scatter list */
};
struct mmc_request {
struct mmc_command *cmd;
struct mmc_data *data;
struct mmc_command *stop;
void *done_data; /* completion data */
void (*done)(struct mmc_request *);/* completion function */
};
struct mmc_host;
struct mmc_card;
extern int mmc_wait_for_req(struct mmc_host *, struct mmc_request *);
extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int);
extern int mmc_wait_for_app_cmd(struct mmc_host *, unsigned int,
struct mmc_command *, int);
extern int __mmc_claim_host(struct mmc_host *host, struct mmc_card *card);
static inline void mmc_claim_host(struct mmc_host *host)
{
__mmc_claim_host(host, (struct mmc_card *)-1);
}
extern void mmc_release_host(struct mmc_host *host);
#endif

View File

@ -1,110 +0,0 @@
/*
* linux/drivers/mmc/mmc_pxa.h
*
* Author: Vladimir Shebordaev, Igor Oblakov
* Copyright: MontaVista Software Inc.
*
* $Id: mmc_pxa.h,v 0.3.1.6 2002/09/25 19:25:48 ted Exp ted $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __MMC_PXA_P_H__
#define __MMC_PXA_P_H__
#define MMC_DEFAULT_RCA (1<<16)
#define MMC_BLOCK_SIZE 512
#define MMC_CMD_RESET 0
#define MMC_CMD_SEND_OP_COND 1
#define MMC_CMD_ALL_SEND_CID 2
#define MMC_CMD_SET_RCA 3
#define MMC_CMD_SELECT_CARD 7
#define MMC_CMD_SEND_CSD 9
#define MMC_CMD_SEND_CID 10
#define MMC_CMD_SEND_STATUS 13
#define MMC_CMD_SET_BLOCKLEN 16
#define MMC_CMD_READ_BLOCK 17
#define MMC_CMD_RD_BLK_MULTI 18
#define MMC_CMD_WRITE_BLOCK 24
#define MMC_MAX_BLOCK_SIZE 512
#define MMC_R1_IDLE_STATE 0x01
#define MMC_R1_ERASE_STATE 0x02
#define MMC_R1_ILLEGAL_CMD 0x04
#define MMC_R1_COM_CRC_ERR 0x08
#define MMC_R1_ERASE_SEQ_ERR 0x01
#define MMC_R1_ADDR_ERR 0x02
#define MMC_R1_PARAM_ERR 0x04
#define MMC_R1B_WP_ERASE_SKIP 0x0002
#define MMC_R1B_ERR 0x0004
#define MMC_R1B_CC_ERR 0x0008
#define MMC_R1B_CARD_ECC_ERR 0x0010
#define MMC_R1B_WP_VIOLATION 0x0020
#define MMC_R1B_ERASE_PARAM 0x0040
#define MMC_R1B_OOR 0x0080
#define MMC_R1B_IDLE_STATE 0x0100
#define MMC_R1B_ERASE_RESET 0x0200
#define MMC_R1B_ILLEGAL_CMD 0x0400
#define MMC_R1B_COM_CRC_ERR 0x0800
#define MMC_R1B_ERASE_SEQ_ERR 0x1000
#define MMC_R1B_ADDR_ERR 0x2000
#define MMC_R1B_PARAM_ERR 0x4000
typedef struct mmc_cid
{
/* FIXME: BYTE_ORDER */
u8 year:4,
month:4;
u8 sn[3];
u8 fwrev:4,
hwrev:4;
u8 name[6];
u8 id[3];
} mmc_cid_t;
typedef struct mmc_csd
{
u8 ecc:2,
file_format:2,
tmp_write_protect:1,
perm_write_protect:1,
copy:1,
file_format_grp:1;
unsigned long long content_prot_app:1,
rsvd3:4,
write_bl_partial:1,
write_bl_len:4,
r2w_factor:3,
default_ecc:2,
wp_grp_enable:1,
wp_grp_size:5,
erase_grp_mult:5,
erase_grp_size:5,
c_size_mult1:3,
vdd_w_curr_max:3,
vdd_w_curr_min:3,
vdd_r_curr_max:3,
vdd_r_curr_min:3,
c_size:12,
rsvd2:2,
dsr_imp:1,
read_blk_misalign:1,
write_blk_misalign:1,
read_bl_partial:1;
u16 read_bl_len:4,
ccc:12;
u8 tran_speed;
u8 nsac;
u8 taac;
u8 rsvd1:2,
spec_vers:4,
csd_structure:2;
} mmc_csd_t;
#endif /* __MMC_PXA_P_H__ */

View File

@ -1,30 +0,0 @@
/*
* (C) Copyright 2007 OpenMoko, Inc.
* Author: xiangfu liu <xiangfu@openmoko.org>
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef __CONFIG_H
#define __CONFIG_H
#ifndef __ASM_MODE__
#include <qi.h>
extern const struct board_api board_api_gta01;
#endif
#define TEXT_BASE 0x33000000
#endif /* __CONFIG_H */

View File

@ -1,32 +0,0 @@
/*
* (C) Copyright 2007 OpenMoko, Inc.
* Author: xiangfu liu <xiangfu@openmoko.org>
*
* Configuation settings for the FIC Neo GTA02 Linux GSM phone
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef __CONFIG_H
#define __CONFIG_H
#ifndef __ASM_MODE__
#include <qi.h>
extern const struct board_api board_api_gta02;
#endif
#define TEXT_BASE 0x33000000
#endif /* __CONFIG_H */

View File

@ -1,28 +0,0 @@
/*
* (C) Copyright 2007 OpenMoko, Inc.
* Author: xiangfu liu <xiangfu@openmoko.org>
*
* Configuation settings for the FIC Neo GTA02 Linux GSM phone
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef __ASM_MODE__
#include <qi.h>
extern const struct board_api board_api_om_3d7k;
#endif
#define TEXT_BASE_OM_3D7K 0x53000000

View File

@ -1,6 +0,0 @@
#ifndef __ASM_MODE__
#include <qi.h>
extern const struct board_api board_api_smdk6410;
#endif
#define TEXT_BASE_SMDK6410 0x53000000

View File

@ -1,260 +0,0 @@
#ifndef _PCF50606_H
#define _PCF50606_H
/* Philips PCF50606 Power Managemnt Unit (PMU) driver
* (C) 2006-2007 by OpenMoko, Inc.
* Author: Harald Welte <laforge@openmoko.org>
*
*/
enum pfc50606_regs {
PCF50606_REG_ID = 0x00,
PCF50606_REG_OOCS = 0x01,
PCF50606_REG_INT1 = 0x02, /* Interrupt Status */
PCF50606_REG_INT2 = 0x03, /* Interrupt Status */
PCF50606_REG_INT3 = 0x04, /* Interrupt Status */
PCF50606_REG_INT1M = 0x05, /* Interrupt Mask */
PCF50606_REG_INT2M = 0x06, /* Interrupt Mask */
PCF50606_REG_INT3M = 0x07, /* Interrupt Mask */
PCF50606_REG_OOCC1 = 0x08,
PCF50606_REG_OOCC2 = 0x09,
PCF50606_REG_RTCSC = 0x0a, /* Second */
PCF50606_REG_RTCMN = 0x0b, /* Minute */
PCF50606_REG_RTCHR = 0x0c, /* Hour */
PCF50606_REG_RTCWD = 0x0d, /* Weekday */
PCF50606_REG_RTCDT = 0x0e, /* Day */
PCF50606_REG_RTCMT = 0x0f, /* Month */
PCF50606_REG_RTCYR = 0x10, /* Year */
PCF50606_REG_RTCSCA = 0x11, /* Alarm Second */
PCF50606_REG_RTCMNA = 0x12, /* Alarm Minute */
PCF50606_REG_RTCHRA = 0x13, /* Alarm Hour */
PCF50606_REG_RTCWDA = 0x14, /* Alarm Weekday */
PCF50606_REG_RTCDTA = 0x15, /* Alarm Day */
PCF50606_REG_RTCMTA = 0x16, /* Alarm Month */
PCF50606_REG_RTCYRA = 0x17, /* Alarm Year */
PCF50606_REG_PSSC = 0x18, /* Power sequencing */
PCF50606_REG_PWROKM = 0x19, /* PWROK mask */
PCF50606_REG_PWROKS = 0x1a, /* PWROK status */
PCF50606_REG_DCDC1 = 0x1b,
PCF50606_REG_DCDC2 = 0x1c,
PCF50606_REG_DCDC3 = 0x1d,
PCF50606_REG_DCDC4 = 0x1e,
PCF50606_REG_DCDEC1 = 0x1f,
PCF50606_REG_DCDEC2 = 0x20,
PCF50606_REG_DCUDC1 = 0x21,
PCF50606_REG_DCUDC2 = 0x22,
PCF50606_REG_IOREGC = 0x23,
PCF50606_REG_D1REGC1 = 0x24,
PCF50606_REG_D2REGC1 = 0x25,
PCF50606_REG_D3REGC1 = 0x26,
PCF50606_REG_LPREGC1 = 0x27,
PCF50606_REG_LPREGC2 = 0x28,
PCF50606_REG_MBCC1 = 0x29,
PCF50606_REG_MBCC2 = 0x2a,
PCF50606_REG_MBCC3 = 0x2b,
PCF50606_REG_MBCS1 = 0x2c,
PCF50606_REG_BBCC = 0x2d,
PCF50606_REG_ADCC1 = 0x2e,
PCF50606_REG_ADCC2 = 0x2f,
PCF50606_REG_ADCS1 = 0x30,
PCF50606_REG_ADCS2 = 0x31,
PCF50606_REG_ADCS3 = 0x32,
PCF50606_REG_ACDC1 = 0x33,
PCF50606_REG_BVMC = 0x34,
PCF50606_REG_PWMC1 = 0x35,
PCF50606_REG_LEDC1 = 0x36,
PCF50606_REG_LEDC2 = 0x37,
PCF50606_REG_GPOC1 = 0x38,
PCF50606_REG_GPOC2 = 0x39,
PCF50606_REG_GPOC3 = 0x3a,
PCF50606_REG_GPOC4 = 0x3b,
PCF50606_REG_GPOC5 = 0x3c,
__NUM_PCF50606_REGS
};
enum pcf50606_reg_oocs {
PFC50606_OOCS_ONKEY = 0x01,
PCF50606_OOCS_EXTON = 0x02,
PCF50606_OOCS_PWROKRST = 0x04,
PCF50606_OOCS_BATOK = 0x08,
PCF50606_OOCS_BACKOK = 0x10,
PCF50606_OOCS_CHGOK = 0x20,
PCF50606_OOCS_TEMPOK = 0x40,
PCF50606_OOCS_WDTEXP = 0x80,
};
enum pcf50606_reg_oocc1 {
PCF50606_OOCC1_GOSTDBY = 0x01,
PCF50606_OOCC1_TOTRST = 0x02,
PCF50606_OOCC1_CLK32ON = 0x04,
PCF50606_OOCC1_WDTRST = 0x08,
PCF50606_OOCC1_RTCWAK = 0x10,
PCF50606_OOCC1_CHGWAK = 0x20,
PCF50606_OOCC1_EXTONWAK_HIGH = 0x40,
PCF50606_OOCC1_EXTONWAK_LOW = 0x80,
PCF50606_OOCC1_EXTONWAK_NO_WAKEUP = 0x3f,
};
enum pcf50606_reg_oocc2 {
PCF50606_OOCC2_ONKEYDB_NONE = 0x00,
PCF50606_OOCC2_ONKEYDB_14ms = 0x01,
PCF50606_OOCC2_ONKEYDB_62ms = 0x02,
PCF50606_OOCC2_ONKEYDB_500ms = 0x03,
PCF50606_OOCC2_EXTONDB_NONE = 0x00,
PCF50606_OOCC2_EXTONDB_14ms = 0x04,
PCF50606_OOCC2_EXTONDB_62ms = 0x08,
PCF50606_OOCC2_EXTONDB_500ms = 0x0c,
};
enum pcf50606_reg_int1 {
PCF50606_INT1_ONKEYR = 0x01, /* ONKEY rising edge */
PCF50606_INT1_ONKEYF = 0x02, /* ONKEY falling edge */
PCF50606_INT1_ONKEY1S = 0x04, /* OMKEY at least 1sec low */
PCF50606_INT1_EXTONR = 0x08, /* EXTON rising edge */
PCF50606_INT1_EXTONF = 0x10, /* EXTON falling edge */
PCF50606_INT1_SECOND = 0x40, /* RTC periodic second interrupt */
PCF50606_INT1_ALARM = 0x80, /* RTC alarm time is reached */
};
enum pcf50606_reg_int2 {
PCF50606_INT2_CHGINS = 0x01, /* Charger inserted */
PCF50606_INT2_CHGRM = 0x02, /* Charger removed */
PCF50606_INT2_CHGFOK = 0x04, /* Fast charging OK */
PCF50606_INT2_CHGERR = 0x08, /* Error in charging mode */
PCF50606_INT2_CHGFRDY = 0x10, /* Fast charge completed */
PCF50606_INT2_CHGPROT = 0x20, /* Charging protection interrupt */
PCF50606_INT2_CHGWD10S = 0x40, /* Charger watchdig expires in 10s */
PCF50606_INT2_CHGWDEXP = 0x80, /* Charger watchdog expires */
};
enum pcf50606_reg_int3 {
PCF50606_INT3_ADCRDY = 0x01, /* ADC conversion finished */
PCF50606_INT3_ACDINS = 0x02, /* Accessory inserted */
PCF50606_INT3_ACDREM = 0x04, /* Accessory removed */
PCF50606_INT3_TSCPRES = 0x08, /* Touch screen pressed */
PCF50606_INT3_LOWBAT = 0x40, /* Low battery voltage */
PCF50606_INT3_HIGHTMP = 0x80, /* High temperature */
};
/* used by PSSC, PWROKM, PWROKS, */
enum pcf50606_regu {
PCF50606_REGU_DCD = 0x01, /* DCD in phase 2 */
PCF50606_REGU_DCDE = 0x02, /* DCDE in phase 2 */
PCF50606_REGU_DCUD = 0x04, /* DCDU in phase 2 */
PCF50606_REGU_IO = 0x08, /* IO in phase 2 */
PCF50606_REGU_D1 = 0x10, /* D1 in phase 2 */
PCF50606_REGU_D2 = 0x20, /* D2 in phase 2 */
PCF50606_REGU_D3 = 0x40, /* D3 in phase 2 */
PCF50606_REGU_LP = 0x80, /* LP in phase 2 */
};
enum pcf50606_reg_dcdc4 {
PCF50606_DCDC4_MODE_AUTO = 0x00,
PCF50606_DCDC4_MODE_PWM = 0x01,
PCF50606_DCDC4_MODE_PCF = 0x02,
PCF50606_DCDC4_OFF_FLOAT = 0x00,
PCF50606_DCDC4_OFF_BYPASS = 0x04,
PCF50606_DCDC4_OFF_PULLDOWN = 0x08,
PCF50606_DCDC4_CURLIM_500mA = 0x00,
PCF50606_DCDC4_CURLIM_750mA = 0x10,
PCF50606_DCDC4_CURLIM_1000mA = 0x20,
PCF50606_DCDC4_CURLIM_1250mA = 0x30,
PCF50606_DCDC4_TOGGLE = 0x40,
PCF50606_DCDC4_REGSEL_DCDC2 = 0x80,
};
enum pcf50606_reg_dcdec2 {
PCF50606_DCDEC2_MODE_AUTO = 0x00,
PCF50606_DCDEC2_MODE_PWM = 0x01,
PCF50606_DCDEC2_MODE_PCF = 0x02,
PCF50606_DCDEC2_OFF_FLOAT = 0x00,
PCF50606_DCDEC2_OFF_BYPASS = 0x04,
};
enum pcf50606_reg_dcudc2 {
PCF50606_DCUDC2_MODE_AUTO = 0x00,
PCF50606_DCUDC2_MODE_PWM = 0x01,
PCF50606_DCUDC2_MODE_PCF = 0x02,
PCF50606_DCUDC2_OFF_FLOAT = 0x00,
PCF50606_DCUDC2_OFF_BYPASS = 0x04,
};
enum pcf50606_reg_adcc1 {
PCF50606_ADCC1_TSCMODACT = 0x01,
PCF50606_ADCC1_TSCMODSTB = 0x02,
PCF50606_ADCC1_TRATSET = 0x04,
PCF50606_ADCC1_NTCSWAPE = 0x08,
PCF50606_ADCC1_NTCSWAOFF = 0x10,
PCF50606_ADCC1_EXTSYNCBREAK = 0x20,
/* reserved */
PCF50606_ADCC1_TSCINT = 0x80,
};
enum pcf50606_reg_adcc2 {
PCF50606_ADCC2_ADCSTART = 0x01,
/* see enum pcf50606_adcc2_adcmux */
PCF50606_ADCC2_SYNC_NONE = 0x00,
PCF50606_ADCC2_SYNC_TXON = 0x20,
PCF50606_ADCC2_SYNC_PWREN1 = 0x40,
PCF50606_ADCC2_SYNC_PWREN2 = 0x60,
PCF50606_ADCC2_RES_10BIT = 0x00,
PCF50606_ADCC2_RES_8BIT = 0x80,
};
#define PCF50606_ADCC2_ADCMUX_MASK (0xf << 1)
#define ADCMUX_SHIFT 1
enum pcf50606_adcc2_adcmux {
PCF50606_ADCMUX_BATVOLT_RES = 0x0 << ADCMUX_SHIFT,
PCF50606_ADCMUX_BATVOLT_SUBTR = 0x1 << ADCMUX_SHIFT,
PCF50606_ADCMUX_ADCIN1_RES = 0x2 << ADCMUX_SHIFT,
PCF50606_ADCMUX_ADCIN1_SUBTR = 0x3 << ADCMUX_SHIFT,
PCF50606_ADCMUX_BATTEMP = 0x4 << ADCMUX_SHIFT,
PCF50606_ADCMUX_ADCIN2 = 0x5 << ADCMUX_SHIFT,
PCF50606_ADCMUX_ADCIN3 = 0x6 << ADCMUX_SHIFT,
PCF50606_ADCMUX_ADCIN3_RATIO = 0x7 << ADCMUX_SHIFT,
PCF50606_ADCMUX_XPOS = 0x8 << ADCMUX_SHIFT,
PCF50606_ADCMUX_YPOS = 0x9 << ADCMUX_SHIFT,
PCF50606_ADCMUX_P1 = 0xa << ADCMUX_SHIFT,
PCF50606_ADCMUX_P2 = 0xb << ADCMUX_SHIFT,
PCF50606_ADCMUX_BATVOLT_ADCIN1 = 0xc << ADCMUX_SHIFT,
PCF50606_ADCMUX_XY_SEQUENCE = 0xe << ADCMUX_SHIFT,
PCF50606_P1_P2_RESISTANCE = 0xf << ADCMUX_SHIFT,
};
enum pcf50606_adcs2 {
PCF50606_ADCS2_ADCRDY = 0x80,
};
enum pcf50606_reg_mbcc1 {
PCF50606_MBCC1_CHGAPE = 0x01,
PCF50606_MBCC1_AUTOFST = 0x02,
#define PCF50606_MBCC1_CHGMOD_MASK 0x1c
#define PCF50606_MBCC1_CHGMOD_SHIFT 2
PCF50606_MBCC1_CHGMOD_QUAL = 0x00,
PCF50606_MBCC1_CHGMOD_PRE = 0x04,
PCF50606_MBCC1_CHGMOD_TRICKLE = 0x08,
PCF50606_MBCC1_CHGMOD_FAST_CCCV = 0x0c,
PCF50606_MBCC1_CHGMOD_FAST_NOCC = 0x10,
PCF50606_MBCC1_CHGMOD_FAST_NOCV = 0x14,
PCF50606_MBCC1_CHGMOD_FAST_SW = 0x18,
PCF50606_MBCC1_CHGMOD_IDLE = 0x1c,
PCF50606_MBCC1_DETMOD_LOWCHG = 0x20,
PCF50606_MBCC1_DETMOD_WDRST = 0x40,
};
enum pcf50606_reg_bvmc {
PCF50606_BVMC_LOWBAT = 0x01,
PCF50606_BVMC_THRSHLD_NULL = 0x00,
PCF50606_BVMC_THRSHLD_2V8 = 0x02,
PCF50606_BVMC_THRSHLD_2V9 = 0x04,
PCF50606_BVMC_THRSHLD_3V = 0x08,
PCF50606_BVMC_THRSHLD_3V1 = 0x08,
PCF50606_BVMC_THRSHLD_3V2 = 0x0a,
PCF50606_BVMC_THRSHLD_3V3 = 0x0c,
PCF50606_BVMC_THRSHLD_3V4 = 0x0e,
PCF50606_BVMC_DISDB = 0x10,
};
#endif /* _PCF50606_H */

View File

@ -1,392 +0,0 @@
#ifndef _PCF50633_H
#define _PCF50633_H
/* Philips PCF50633 Power Managemnt Unit (PMU) driver
* (C) 2006-2007 by OpenMoko, Inc.
* Author: Harald Welte <laforge@openmoko.org>
*
*/
enum pfc50633_regs {
PCF50633_REG_VERSION = 0x00,
PCF50633_REG_VARIANT = 0x01,
PCF50633_REG_INT1 = 0x02, /* Interrupt Status */
PCF50633_REG_INT2 = 0x03, /* Interrupt Status */
PCF50633_REG_INT3 = 0x04, /* Interrupt Status */
PCF50633_REG_INT4 = 0x05, /* Interrupt Status */
PCF50633_REG_INT5 = 0x06, /* Interrupt Status */
PCF50633_REG_INT1M = 0x07, /* Interrupt Mask */
PCF50633_REG_INT2M = 0x08, /* Interrupt Mask */
PCF50633_REG_INT3M = 0x09, /* Interrupt Mask */
PCF50633_REG_INT4M = 0x0a, /* Interrupt Mask */
PCF50633_REG_INT5M = 0x0b, /* Interrupt Mask */
PCF50633_REG_OOCSHDWN = 0x0c,
PCF50633_REG_OOCWAKE = 0x0d,
PCF50633_REG_OOCTIM1 = 0x0e,
PCF50633_REG_OOCTIM2 = 0x0f,
PCF50633_REG_OOCMODE = 0x10,
PCF50633_REG_OOCCTL = 0x11,
PCF50633_REG_OOCSTAT = 0x12,
PCF50633_REG_GPIOCTL = 0x13,
PCF50633_REG_GPIO1CFG = 0x14,
PCF50633_REG_GPIO2CFG = 0x15,
PCF50633_REG_GPIO3CFG = 0x16,
PCF50633_REG_GPOCFG = 0x17,
PCF50633_REG_BVMCTL = 0x18,
PCF50633_REG_SVMCTL = 0x19,
PCF50633_REG_AUTOOUT = 0x1a,
PCF50633_REG_AUTOENA = 0x1b,
PCF50633_REG_AUTOCTL = 0x1c,
PCF50633_REG_AUTOMXC = 0x1d,
PCF50633_REG_DOWN1OUT = 0x1e,
PCF50633_REG_DOWN1ENA = 0x1f,
PCF50633_REG_DOWN1CTL = 0x20,
PCF50633_REG_DOWN1MXC = 0x21,
PCF50633_REG_DOWN2OUT = 0x22,
PCF50633_REG_DOWN2ENA = 0x23,
PCF50633_REG_DOWN2CTL = 0x24,
PCF50633_REG_DOWN2MXC = 0x25,
PCF50633_REG_MEMLDOOUT = 0x26,
PCF50633_REG_MEMLDOENA = 0x27,
PCF50633_REG_LEDOUT = 0x28,
PCF50633_REG_LEDENA = 0x29,
PCF50633_REG_LEDCTL = 0x2a,
PCF50633_REG_LEDDIM = 0x2b,
/* reserved */
PCF50633_REG_LDO1OUT = 0x2d,
PCF50633_REG_LDO1ENA = 0x2e,
PCF50633_REG_LDO2OUT = 0x2f,
PCF50633_REG_LDO2ENA = 0x30,
PCF50633_REG_LDO3OUT = 0x31,
PCF50633_REG_LDO3ENA = 0x32,
PCF50633_REG_LDO4OUT = 0x33,
PCF50633_REG_LDO4ENA = 0x34,
PCF50633_REG_LDO5OUT = 0x35,
PCF50633_REG_LDO5ENA = 0x36,
PCF50633_REG_LDO6OUT = 0x37,
PCF50633_REG_LDO6ENA = 0x38,
PCF50633_REG_HCLDOOUT = 0x39,
PCF50633_REG_HCLDOENA = 0x3a,
PCF50633_REG_STBYCTL1 = 0x3b,
PCF50633_REG_STBYCTL2 = 0x3c,
PCF50633_REG_DEBPF1 = 0x3d,
PCF50633_REG_DEBPF2 = 0x3e,
PCF50633_REG_DEBPF3 = 0x3f,
PCF50633_REG_HCLDOOVL = 0x40,
PCF50633_REG_DCDCSTAT = 0x41,
PCF50633_REG_LDOSTAT = 0x42,
PCF50633_REG_MBCC1 = 0x43,
PCF50633_REG_MBCC2 = 0x44,
PCF50633_REG_MBCC3 = 0x45,
PCF50633_REG_MBCC4 = 0x46,
PCF50633_REG_MBCC5 = 0x47,
PCF50633_REG_MBCC6 = 0x48,
PCF50633_REG_MBCC7 = 0x49,
PCF50633_REG_MBCC8 = 0x4a,
PCF50633_REG_MBCS1 = 0x4b,
PCF50633_REG_MBCS2 = 0x4c,
PCF50633_REG_MBCS3 = 0x4d,
PCF50633_REG_BBCCTL = 0x4e,
PCF50633_REG_ALMGAIN = 0x4f,
PCF50633_REG_ALMDATA = 0x50,
/* reserved */
PCF50633_REG_ADCC3 = 0x52,
PCF50633_REG_ADCC2 = 0x53,
PCF50633_REG_ADCC1 = 0x54,
PCF50633_REG_ADCS1 = 0x55,
PCF50633_REG_ADCS2 = 0x56,
PCF50633_REG_ADCS3 = 0x57,
/* reserved */
PCF50633_REG_RTCSC = 0x59, /* Second */
PCF50633_REG_RTCMN = 0x5a, /* Minute */
PCF50633_REG_RTCHR = 0x5b, /* Hour */
PCF50633_REG_RTCWD = 0x5c, /* Weekday */
PCF50633_REG_RTCDT = 0x5d, /* Day */
PCF50633_REG_RTCMT = 0x5e, /* Month */
PCF50633_REG_RTCYR = 0x5f, /* Year */
PCF50633_REG_RTCSCA = 0x60, /* Alarm Second */
PCF50633_REG_RTCMNA = 0x61, /* Alarm Minute */
PCF50633_REG_RTCHRA = 0x62, /* Alarm Hour */
PCF50633_REG_RTCWDA = 0x63, /* Alarm Weekday */
PCF50633_REG_RTCDTA = 0x64, /* Alarm Day */
PCF50633_REG_RTCMTA = 0x65, /* Alarm Month */
PCF50633_REG_RTCYRA = 0x66, /* Alarm Year */
PCF50633_REG_MEMBYTE0 = 0x67,
PCF50633_REG_MEMBYTE1 = 0x68,
PCF50633_REG_MEMBYTE2 = 0x69,
PCF50633_REG_MEMBYTE3 = 0x6a,
PCF50633_REG_MEMBYTE4 = 0x6b,
PCF50633_REG_MEMBYTE5 = 0x6c,
PCF50633_REG_MEMBYTE6 = 0x6d,
PCF50633_REG_MEMBYTE7 = 0x6e,
/* reserved */
PCF50633_REG_DCDCPFM = 0x84,
__NUM_PCF50633_REGS
};
enum pcf50633_reg_int1 {
PCF50633_INT1_ADPINS = 0x01, /* Adapter inserted */
PCF50633_INT1_ADPREM = 0x02, /* Adapter removed */
PCF50633_INT1_USBINS = 0x04, /* USB inserted */
PCF50633_INT1_USBREM = 0x08, /* USB removed */
/* reserved */
PCF50633_INT1_ALARM = 0x40, /* RTC alarm time is reached */
PCF50633_INT1_SECOND = 0x80, /* RTC periodic second interrupt */
};
enum pcf50633_reg_int2 {
PCF50633_INT2_ONKEYR = 0x01, /* ONKEY rising edge */
PCF50633_INT2_ONKEYF = 0x02, /* ONKEY falling edge */
PCF50633_INT2_EXTON1R = 0x04, /* EXTON1 rising edge */
PCF50633_INT2_EXTON1F = 0x08, /* EXTON1 falling edge */
PCF50633_INT2_EXTON2R = 0x10, /* EXTON2 rising edge */
PCF50633_INT2_EXTON2F = 0x20, /* EXTON2 falling edge */
PCF50633_INT2_EXTON3R = 0x40, /* EXTON3 rising edge */
PCF50633_INT2_EXTON3F = 0x80, /* EXTON3 falling edge */
};
enum pcf50633_reg_int3 {
PCF50633_INT3_BATFULL = 0x01, /* Battery full */
PCF50633_INT3_CHGHALT = 0x02, /* Charger halt */
PCF50633_INT3_THLIMON = 0x04,
PCF50633_INT3_THLIMOFF = 0x08,
PCF50633_INT3_USBLIMON = 0x10,
PCF50633_INT3_USBLIMOFF = 0x20,
PCF50633_INT3_ADCRDY = 0x40, /* ADC conversion finished */
PCF50633_INT3_ONKEY1S = 0x80, /* ONKEY pressed 1 second */
};
enum pcf50633_reg_int4 {
PCF50633_INT4_LOWSYS = 0x01,
PCF50633_INT4_LOWBAT = 0x02,
PCF50633_INT4_HIGHTMP = 0x04,
PCF50633_INT4_AUTOPWRFAIL = 0x08,
PCF50633_INT4_DWN1PWRFAIL = 0x10,
PCF50633_INT4_DWN2PWRFAIL = 0x20,
PCF50633_INT4_LEDPWRFAIL = 0x40,
PCF50633_INT4_LEDOVP = 0x80,
};
enum pcf50633_reg_int5 {
PCF50633_INT4_LDO1PWRFAIL = 0x01,
PCF50633_INT4_LDO2PWRFAIL = 0x02,
PCF50633_INT4_LDO3PWRFAIL = 0x04,
PCF50633_INT4_LDO4PWRFAIL = 0x08,
PCF50633_INT4_LDO5PWRFAIL = 0x10,
PCF50633_INT4_LDO6PWRFAIL = 0x20,
PCF50633_INT4_HCLDOPWRFAIL = 0x40,
PCF50633_INT4_HCLDOOVL = 0x80,
};
enum pcf50633_reg_oocwake {
PCF50633_OOCWAKE_ONKEY = 0x01,
PCF50633_OOCWAKE_EXTON1 = 0x02,
PCF50633_OOCWAKE_EXTON2 = 0x04,
PCF50633_OOCWAKE_EXTON3 = 0x08,
PCF50633_OOCWAKE_RTC = 0x10,
/* reserved */
PCF50633_OOCWAKE_USB = 0x40,
PCF50633_OOCWAKE_ADP = 0x80,
};
enum pcf50633_reg_mbcc1 {
PCF50633_MBCC1_CHGENA = 0x01, /* Charger enable */
PCF50633_MBCC1_AUTOSTOP = 0x02,
PCF50633_MBCC1_AUTORES = 0x04, /* automatic resume */
PCF50633_MBCC1_RESUME = 0x08, /* explicit resume cmd */
PCF50633_MBCC1_RESTART = 0x10, /* restart charging */
PCF50633_MBCC1_PREWDTIME_60M = 0x20, /* max. precharging time */
PCF50633_MBCC1_WDTIME_1H = 0x00,
PCF50633_MBCC1_WDTIME_2H = 0x40,
PCF50633_MBCC1_WDTIME_4H = 0x80,
PCF50633_MBCC1_WDTIME_6H = 0xc0,
};
#define PCF50633_MBCC1_WDTIME_MASK 0xc0
enum pcf50633_reg_mbcc2 {
PCF50633_MBCC2_VBATCOND_2V7 = 0x00,
PCF50633_MBCC2_VBATCOND_2V85 = 0x01,
PCF50633_MBCC2_VBATCOND_3V = 0x02,
PCF50633_MBCC2_VBATCOND_3V15 = 0x03,
PCF50633_MBCC2_VMAX_4V = 0x00,
PCF50633_MBCC2_VMAX_4V20 = 0x28,
PCF50633_MBCC2_VRESDEBTIME_64S = 0x80, /* debounce time (32/64sec) */
};
#define PCF50633_MBCC2_VBATCOND_MASK 0x03
#define PCF50633_MBCC2_VMAX_MASK 0x3c
#define PCF50633_OOCSTAT_ONKEY 0x01
enum pcf50633_reg_adcc1 {
PCF50633_ADCC1_ADCSTART = 0x01,
PCF50633_ADCC1_RES_10BIT = 0x02,
PCF50633_ADCC1_AVERAGE_NO = 0x00,
PCF50633_ADCC1_AVERAGE_4 = 0x04,
PCF50633_ADCC1_AVERAGE_8 = 0x08,
PCF50633_ADCC1_AVERAGE_16 = 0x0c,
PCF50633_ADCC1_MUX_BATSNS_RES = 0x00,
PCF50633_ADCC1_MUX_BATSNS_SUBTR = 0x10,
PCF50633_ADCC1_MUX_ADCIN2_RES = 0x20,
PCF50633_ADCC1_MUX_ADCIN2_SUBTR = 0x30,
PCF50633_ADCC1_MUX_BATTEMP = 0x60,
PCF50633_ADCC1_MUX_ADCIN1 = 0x70,
};
#define PCF50633_ADCC1_AVERAGE_MASK 0x0c
#define PCF50633_ADCC1_ADCMUX_MASK 0xf0
enum pcf50633_reg_adcc2 {
PCF50633_ADCC2_RATIO_NONE = 0x00,
PCF50633_ADCC2_RATIO_BATTEMP = 0x01,
PCF50633_ADCC2_RATIO_ADCIN1 = 0x02,
PCF50633_ADCC2_RATIO_BOTH = 0x03,
PCF50633_ADCC2_RATIOSETTL_100US = 0x04,
};
#define PCF50633_ADCC2_RATIO_MASK 0x03
enum pcf50633_reg_adcc3 {
PCF50633_ADCC3_ACCSW_EN = 0x01,
PCF50633_ADCC3_NTCSW_EN = 0x04,
PCF50633_ADCC3_RES_DIV_TWO = 0x10,
PCF50633_ADCC3_RES_DIV_THREE = 0x00,
};
enum pcf50633_reg_adcs3 {
PCF50633_ADCS3_REF_NTCSW = 0x00,
PCF50633_ADCS3_REF_ACCSW = 0x10,
PCF50633_ADCS3_REF_2V0 = 0x20,
PCF50633_ADCS3_REF_VISA = 0x30,
PCF50633_ADCS3_REF_2V0_2 = 0x70,
PCF50633_ADCS3_ADCRDY = 0x80,
};
#define PCF50633_ADCS3_ADCDAT1L_MASK 0x03
#define PCF50633_ADCS3_ADCDAT2L_MASK 0x0c
#define PCF50633_ADCS3_ADCDAT2L_SHIFT 2
#define PCF50633_ASCS3_REF_MASK 0x70
enum pcf50633_regulator_enable {
PCF50633_REGULATOR_ON = 0x01,
PCF50633_REGULATOR_ON_GPIO1 = 0x02,
PCF50633_REGULATOR_ON_GPIO2 = 0x04,
PCF50633_REGULATOR_ON_GPIO3 = 0x08,
};
#define PCF50633_REGULATOR_ON_MASK 0x0f
enum pcf50633_regulator_phase {
PCF50633_REGULATOR_ACTPH1 = 0x00,
PCF50633_REGULATOR_ACTPH2 = 0x10,
PCF50633_REGULATOR_ACTPH3 = 0x20,
PCF50633_REGULATOR_ACTPH4 = 0x30,
};
#define PCF50633_REGULATOR_ACTPH_MASK 0x30
enum pcf50633_reg_gpocfg {
PCF50633_GPOCFG_GPOSEL_0 = 0x00,
PCF50633_GPOCFG_GPOSEL_LED_NFET = 0x01,
PCF50633_GPOCFG_GPOSEL_SYSxOK = 0x02,
PCF50633_GPOCFG_GPOSEL_CLK32K = 0x03,
PCF50633_GPOCFG_GPOSEL_ADAPUSB = 0x04,
PCF50633_GPOCFG_GPOSEL_USBxOK = 0x05,
PCF50633_GPOCFG_GPOSEL_ACTPH4 = 0x06,
PCF50633_GPOCFG_GPOSEL_1 = 0x07,
PCF50633_GPOCFG_GPOSEL_INVERSE = 0x08,
};
#define PCF50633_GPOCFG_GPOSEL_MASK 0x07
#if 0
enum pcf50633_reg_mbcc1 {
PCF50633_MBCC1_CHGENA = 0x01,
PCF50633_MBCC1_AUTOSTOP = 0x02,
PCF50633_MBCC1_AUTORES = 0x04,
PCF50633_MBCC1_RESUME = 0x08,
PCF50633_MBCC1_RESTART = 0x10,
PCF50633_MBCC1_PREWDTIME_30MIN = 0x00,
PCF50633_MBCC1_PREWDTIME_60MIN = 0x20,
PCF50633_MBCC1_WDTIME_2HRS = 0x40,
PCF50633_MBCC1_WDTIME_4HRS = 0x80,
PCF50633_MBCC1_WDTIME_6HRS = 0xc0,
};
enum pcf50633_reg_mbcc2 {
PCF50633_MBCC2_VBATCOND_2V7 = 0x00,
PCF50633_MBCC2_VBATCOND_2V85 = 0x01,
PCF50633_MBCC2_VBATCOND_3V0 = 0x02,
PCF50633_MBCC2_VBATCOND_3V15 = 0x03,
PCF50633_MBCC2_VRESDEBTIME_64S = 0x80,
};
#define PCF50633_MBCC2_VMAX_MASK 0x3c
#endif
enum pcf50633_reg_mbcc7 {
PCF50633_MBCC7_USB_100mA = 0x00,
PCF50633_MBCC7_USB_500mA = 0x01,
PCF50633_MBCC7_USB_1000mA = 0x02,
PCF50633_MBCC7_USB_SUSPEND = 0x03,
PCF50633_MBCC7_BATTEMP_EN = 0x04,
PCF50633_MBCC7_BATSYSIMAX_1A6 = 0x00,
PCF50633_MBCC7_BATSYSIMAX_1A8 = 0x40,
PCF50633_MBCC7_BATSYSIMAX_2A0 = 0x80,
PCF50633_MBCC7_BATSYSIMAX_2A2 = 0xc0,
};
#define PCF56033_MBCC7_USB_MASK 0x03
enum pcf50633_reg_mbcc8 {
PCF50633_MBCC8_USBENASUS = 0x10,
};
enum pcf50633_reg_mbcs1 {
PCF50633_MBCS1_USBPRES = 0x01,
PCF50633_MBCS1_USBOK = 0x02,
PCF50633_MBCS1_ADAPTPRES = 0x04,
PCF50633_MBCS1_ADAPTOK = 0x08,
PCF50633_MBCS1_TBAT_OK = 0x00,
PCF50633_MBCS1_TBAT_ABOVE = 0x10,
PCF50633_MBCS1_TBAT_BELOW = 0x20,
PCF50633_MBCS1_TBAT_UNDEF = 0x30,
PCF50633_MBCS1_PREWDTEXP = 0x40,
PCF50633_MBCS1_WDTEXP = 0x80,
};
enum pcf50633_reg_mbcs2_mbcmod {
PCF50633_MBCS2_MBC_PLAY = 0x00,
PCF50633_MBCS2_MBC_USB_PRE = 0x01,
PCF50633_MBCS2_MBC_USB_PRE_WAIT = 0x02,
PCF50633_MBCS2_MBC_USB_FAST = 0x03,
PCF50633_MBCS2_MBC_USB_FAST_WAIT= 0x04,
PCF50633_MBCS2_MBC_USB_SUSPEND = 0x05,
PCF50633_MBCS2_MBC_ADP_PRE = 0x06,
PCF50633_MBCS2_MBC_ADP_PRE_WAIT = 0x07,
PCF50633_MBCS2_MBC_ADP_FAST = 0x08,
PCF50633_MBCS2_MBC_ADP_FAST_WAIT= 0x09,
PCF50633_MBCS2_MBC_BAT_FULL = 0x0a,
PCF50633_MBCS2_MBC_HALT = 0x0b,
};
#define PCF50633_MBCS2_MBC_MASK 0x0f
enum pcf50633_reg_mbcs2_chgstat {
PCF50633_MBCS2_CHGS_NONE = 0x00,
PCF50633_MBCS2_CHGS_ADAPTER = 0x10,
PCF50633_MBCS2_CHGS_USB = 0x20,
PCF50633_MBCS2_CHGS_BOTH = 0x30,
};
#define PCF50633_MBCS2_RESSTAT_AUTO 0x40
enum pcf50633_reg_mbcs3 {
PCF50633_MBCS3_USBLIM_PLAY = 0x01,
PCF50633_MBCS3_USBLIM_CGH = 0x02,
PCF50633_MBCS3_TLIM_PLAY = 0x04,
PCF50633_MBCS3_TLIM_CHG = 0x08,
PCF50633_MBCS3_ILIM = 0x10, /* 1: Ibat > Icutoff */
PCF50633_MBCS3_VLIM = 0x20, /* 1: Vbat == Vmax */
PCF50633_MBCS3_VBATSTAT = 0x40, /* 1: Vbat > Vbatcond */
PCF50633_MBCS3_VRES = 0x80, /* 1: Vbat > Vth(RES) */
};
struct pcf50633_init {
u8 index;
u8 value;
};
#endif /* _PCF50633_H */

View File

@ -1,41 +0,0 @@
#ifndef __PORTS_S3C24XX_H__
#define __PORTS_S3C24XX_H__
// I/O PORT
#define rGPACON (*(volatile unsigned *)0x56000000)
#define rGPADAT (*(volatile unsigned *)0x56000004)
#define rGPBCON (*(volatile unsigned *)0x56000010)
#define rGPBDAT (*(volatile unsigned *)0x56000014)
#define rGPBUP (*(volatile unsigned *)0x56000018)
#define rGPCCON (*(volatile unsigned *)0x56000020)
#define rGPCDAT (*(volatile unsigned *)0x56000024)
#define rGPCUP (*(volatile unsigned *)0x56000028)
#define rGPDCON (*(volatile unsigned *)0x56000030)
#define rGPDDAT (*(volatile unsigned *)0x56000034)
#define rGPDUP (*(volatile unsigned *)0x56000038)
#define rGPECON (*(volatile unsigned *)0x56000040)
#define rGPEDAT (*(volatile unsigned *)0x56000044)
#define rGPEUP (*(volatile unsigned *)0x56000048)
#define rGPFCON (*(volatile unsigned *)0x56000050)
#define rGPFDAT (*(volatile unsigned *)0x56000054)
#define rGPFUP (*(volatile unsigned *)0x56000058)
#define rGPGCON (*(volatile unsigned *)0x56000060)
#define rGPGDAT (*(volatile unsigned *)0x56000064)
#define rGPGUP (*(volatile unsigned *)0x56000068)
#define rGPHCON (*(volatile unsigned *)0x56000070)
#define rGPHDAT (*(volatile unsigned *)0x56000074)
#define rGPHUP (*(volatile unsigned *)0x56000078)
#define rGPJCON (*(volatile unsigned *)0x560000d0) //Port J control
#define rGPJDAT (*(volatile unsigned *)0x560000d4) //Port J data
#define rGPJUP (*(volatile unsigned *)0x560000d8) //Port J data
#endif

View File

@ -1,45 +0,0 @@
#define _U 0x01 /* upper */
#define _L 0x02 /* lower */
#define _D 0x04 /* digit */
#define _C 0x08 /* cntrl */
#define _P 0x10 /* punct */
#define _S 0x20 /* white space (space/lf/tab) */
#define _X 0x40 /* hex digit */
#define _SP 0x80 /* hard space (0x20) */
extern unsigned char _ctype[];
#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
#define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0)
#define isalpha(c) ((__ismask(c)&(_U|_L)) != 0)
#define iscntrl(c) ((__ismask(c)&(_C)) != 0)
#define isdigit(c) ((__ismask(c)&(_D)) != 0)
#define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0)
#define islower(c) ((__ismask(c)&(_L)) != 0)
#define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)
#define ispunct(c) ((__ismask(c)&(_P)) != 0)
#define isspace(c) ((__ismask(c)&(_S)) != 0)
#define isupper(c) ((__ismask(c)&(_U)) != 0)
#define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0)
#define isascii(c) (((unsigned char)(c))<=0x7f)
#define toascii(c) (((unsigned char)(c))&0x7f)
static inline unsigned char __tolower(unsigned char c)
{
if (isupper(c))
c -= 'A'-'a';
return c;
}
static inline unsigned char __toupper(unsigned char c)
{
if (islower(c))
c -= 'a'-'A';
return c;
}
#define tolower(c) __tolower(c)
#define toupper(c) __toupper(c)

View File

@ -1,144 +0,0 @@
/*
* (C) Copyright 2008 Openmoko, Inc.
* Author: Andy Green <andy@openmoko.org>
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef __QI_H__
#define __QI_H__
#include <stdarg.h>
#include <qi-ctype.h>
#include <asm/byteorder.h>
#define MALLOC_POOL_EXTENT (100 * 1024)
#define u32 unsigned int
#define u16 unsigned short
#define u8 unsigned char
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
enum filesystem {
FS_RAW,
FS_FAT,
FS_EXT2
};
enum ui_actions {
UI_ACTION_ADD_DEBUG = (1 << 0),
UI_ACTION_SKIPKERNEL = (1 << 1),
};
enum ui_indication {
UI_IND_UPDATE_ONLY,
UI_IND_MOUNT_PART,
UI_IND_MOUNT_FAIL,
UI_IND_SKIPPING,
UI_IND_KERNEL_PULL,
UI_IND_KERNEL_PULL_OK,
UI_IND_KERNEL_PULL_FAIL,
UI_IND_INITRAMFS_PULL,
UI_IND_INITRAMFS_PULL_OK,
UI_IND_INITRAMFS_PULL_FAIL,
UI_IND_KERNEL_START,
UI_IND_MEM_TEST
};
/* describes a source for getting kernel image */
struct kernel_source {
const char *name; /* NULL name means invalid */
const char *filepath;
const char *initramfs_filepath;
int (*block_init)(void);
int (*block_read)(unsigned char * buf, unsigned long start512,
int blocks512);
int partition_index; /* -1 means no partition table */
int offset_blocks512_if_no_partition; /* used if partition_index is -1 */
enum filesystem filesystem;
const char * commandline_append;
};
/* describes a board variant, eg, PCB revision */
struct board_variant {
const char * name;
int machine_revision; /* passed in revision tag to linux */
};
/* describes a "board", ie, a device like GTA02 including revisions */
struct board_api {
const char * name;
int linux_machine_id;
unsigned long linux_mem_start;
unsigned long linux_mem_size;
unsigned long linux_tag_placement;
const char *commandline_board;
const char *commandline_board_debug;
const char *noboot;
const char *append;
const struct board_variant const * (*get_board_variant)(void);
int (*is_this_board)(void);
void (*early_port_init)(void);
void (*port_init)(void);
void (*post_serial_init)(void); /* print device-specific things */
char * (*append_device_specific_cmdline)(char *);
void (*putc)(char);
void (*close)(void);
u8 (*get_ui_keys)(void);
u8 (*get_ui_debug)(void);
void (*set_ui_indication)(enum ui_indication);
struct kernel_source kernel_source[8];
};
/* this is the board we are running on */
extern struct board_api const * this_board;
extern struct kernel_source const * this_kernel;
int printk(const char *fmt, ...);
int vsprintf(char *buf, const char *fmt, va_list args);
int puts(const char *string);
void printhex(unsigned char v);
void print8(unsigned char u);
void print32(unsigned int u);
void printdec(int n);
void hexdump(unsigned char *start, int len);
void udelay(int n);
/* phase2 only */
void setnybble(char *p, unsigned char n);
void set8(char *p, unsigned char n);
void set32(char *p, unsigned int u);
unsigned long crc32(unsigned long crc, const unsigned char *buf,
unsigned int len);
int nand_read_ll(unsigned char *buf, unsigned long start512, int blocks512);
extern void memory_test(void * start, unsigned int length);
void set_putc_func(void (*p)(char));
#endif

View File

@ -1,33 +0,0 @@
/*
* (C) Copyright 2000-2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef _S3C24XX_MMC_H_
#define _S3C24XX_MMC_H_
#include <mmc.h>
int s3c24xx_mmc_init(int verbose);
u32 s3c24xx_mmc_bread(int dev_num, u32 blknr, u32 blkcnt, void *dst);
int s3c24xx_mmc_read(u32 src, u8 *dst, int size);
int s3c24xx_mmc_write(u8 *src, u32 dst, int size);
#endif /* _MMC_H_ */

View File

@ -1,110 +0,0 @@
/* linux/include/asm/arch-s3c2410/regs-sdi.h
*
* Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
* http://www.simtec.co.uk/products/SWLINUX/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* S3C2410 MMC/SDIO register definitions
*
* Changelog:
* 18-Aug-2004 Ben Dooks Created initial file
* 29-Nov-2004 Koen Martens Added some missing defines, fixed duplicates
* 29-Nov-2004 Ben Dooks Updated Koen's patch
*/
#ifndef __ASM_ARM_REGS_SDI
#define __ASM_ARM_REGS_SDI "regs-sdi.h"
#define S3C2440_SDICON_SDRESET (1<<8)
#define S3C2440_SDICON_MMCCLOCK (1<<5)
#define S3C2410_SDICON_BYTEORDER (1<<4)
#define S3C2410_SDICON_SDIOIRQ (1<<3)
#define S3C2410_SDICON_RWAITEN (1<<2)
#define S3C2410_SDICON_FIFORESET (1<<1)
#define S3C2410_SDICON_CLOCKTYPE (1<<0)
#define S3C2410_SDICMDCON_ABORT (1<<12)
#define S3C2410_SDICMDCON_WITHDATA (1<<11)
#define S3C2410_SDICMDCON_LONGRSP (1<<10)
#define S3C2410_SDICMDCON_WAITRSP (1<<9)
#define S3C2410_SDICMDCON_CMDSTART (1<<8)
#define S3C2410_SDICMDCON_SENDERHOST (1<<6)
#define S3C2410_SDICMDCON_INDEX (0x3f)
#define S3C2410_SDICMDSTAT_CRCFAIL (1<<12)
#define S3C2410_SDICMDSTAT_CMDSENT (1<<11)
#define S3C2410_SDICMDSTAT_CMDTIMEOUT (1<<10)
#define S3C2410_SDICMDSTAT_RSPFIN (1<<9)
#define S3C2410_SDICMDSTAT_XFERING (1<<8)
#define S3C2410_SDICMDSTAT_INDEX (0xff)
#define S3C2440_SDIDCON_DS_BYTE (0<<22)
#define S3C2440_SDIDCON_DS_HALFWORD (1<<22)
#define S3C2440_SDIDCON_DS_WORD (2<<22)
#define S3C2410_SDIDCON_IRQPERIOD (1<<21)
#define S3C2410_SDIDCON_TXAFTERRESP (1<<20)
#define S3C2410_SDIDCON_RXAFTERCMD (1<<19)
#define S3C2410_SDIDCON_BUSYAFTERCMD (1<<18)
#define S3C2410_SDIDCON_BLOCKMODE (1<<17)
#define S3C2410_SDIDCON_WIDEBUS (1<<16)
#define S3C2410_SDIDCON_DMAEN (1<<15)
#define S3C2410_SDIDCON_STOP (1<<14)
#define S3C2440_SDIDCON_DATSTART (1<<14)
#define S3C2410_SDIDCON_DATMODE (3<<12)
#define S3C2410_SDIDCON_BLKNUM (0x7ff)
/* constants for S3C2410_SDIDCON_DATMODE */
#define S3C2410_SDIDCON_XFER_READY (0<<12)
#define S3C2410_SDIDCON_XFER_CHKSTART (1<<12)
#define S3C2410_SDIDCON_XFER_RXSTART (2<<12)
#define S3C2410_SDIDCON_XFER_TXSTART (3<<12)
#define S3C2410_SDIDCNT_BLKNUM_MASK (0xFFF)
#define S3C2410_SDIDCNT_BLKNUM_SHIFT (12)
#define S3C2410_SDIDSTA_RDYWAITREQ (1<<10)
#define S3C2410_SDIDSTA_SDIOIRQDETECT (1<<9)
#define S3C2410_SDIDSTA_FIFOFAIL (1<<8) /* reserved on 2440 */
#define S3C2410_SDIDSTA_CRCFAIL (1<<7)
#define S3C2410_SDIDSTA_RXCRCFAIL (1<<6)
#define S3C2410_SDIDSTA_DATATIMEOUT (1<<5)
#define S3C2410_SDIDSTA_XFERFINISH (1<<4)
#define S3C2410_SDIDSTA_BUSYFINISH (1<<3)
#define S3C2410_SDIDSTA_SBITERR (1<<2) /* reserved on 2410a/2440 */
#define S3C2410_SDIDSTA_TXDATAON (1<<1)
#define S3C2410_SDIDSTA_RXDATAON (1<<0)
#define S3C2440_SDIFSTA_FIFORESET (1<<16)
#define S3C2440_SDIFSTA_FIFOFAIL (3<<14) /* 3 is correct (2 bits) */
#define S3C2410_SDIFSTA_TFDET (1<<13)
#define S3C2410_SDIFSTA_RFDET (1<<12)
#define S3C2410_SDIFSTA_TFHALF (1<<11)
#define S3C2410_SDIFSTA_TFEMPTY (1<<10)
#define S3C2410_SDIFSTA_RFLAST (1<<9)
#define S3C2410_SDIFSTA_RFFULL (1<<8)
#define S3C2410_SDIFSTA_RFHALF (1<<7)
#define S3C2410_SDIFSTA_COUNTMASK (0x7f)
#define S3C2410_SDIIMSK_RESPONSECRC (1<<17)
#define S3C2410_SDIIMSK_CMDSENT (1<<16)
#define S3C2410_SDIIMSK_CMDTIMEOUT (1<<15)
#define S3C2410_SDIIMSK_RESPONSEND (1<<14)
#define S3C2410_SDIIMSK_READWAIT (1<<13)
#define S3C2410_SDIIMSK_SDIOIRQ (1<<12)
#define S3C2410_SDIIMSK_FIFOFAIL (1<<11)
#define S3C2410_SDIIMSK_CRCSTATUS (1<<10)
#define S3C2410_SDIIMSK_DATACRC (1<<9)
#define S3C2410_SDIIMSK_DATATIMEOUT (1<<8)
#define S3C2410_SDIIMSK_DATAFINISH (1<<7)
#define S3C2410_SDIIMSK_BUSYFINISH (1<<6)
#define S3C2410_SDIIMSK_SBITERR (1<<5) /* reserved 2440/2410a */
#define S3C2410_SDIIMSK_TXFIFOHALF (1<<4)
#define S3C2410_SDIIMSK_TXFIFOEMPTY (1<<3)
#define S3C2410_SDIIMSK_RXFIFOLAST (1<<2)
#define S3C2410_SDIIMSK_RXFIFOFULL (1<<1)
#define S3C2410_SDIIMSK_RXFIFOHALF (1<<0)
#endif /* __ASM_ARM_REGS_SDI */

File diff suppressed because it is too large Load Diff

View File

@ -1,72 +0,0 @@
/*
* (C) Copyright 2007 OpenMoko, Inc.
* Author: xiangfu liu <xiangfu@openmoko.org>
*
* Configuation settings for the FIC Neo GTA02 Linux GSM phone
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef __SERIAL_S3C24XX_H__
#define __SERIAL_S3C24XX_H__
#define UART0 0
#define UART1 1
#define UART2 2
#define rGPHCON (*(volatile unsigned *)0x56000070) /*UART 0 Line control*/
#define rULCON0 (*(volatile unsigned *)0x50000000) /*UART 0 Line control*/
#define rUCON0 (*(volatile unsigned *)0x50000004) /*UART 0 Control*/
#define rUFCON0 (*(volatile unsigned *)0x50000008) /*UART 0 FIFO control*/
#define rUMCON0 (*(volatile unsigned *)0x5000000c) /*UART 0 Modem control*/
#define rUTRSTAT0 (*(volatile unsigned *)0x50000010) /*UART 0 Tx/Rx status*/
#define rUERSTAT0 (*(volatile unsigned *)0x50000014) /*UART 0 Rx error status*/
#define rUFSTAT0 (*(volatile unsigned *)0x50000018) /*UART 0 FIFO status*/
#define rUMSTAT0 (*(volatile unsigned *)0x5000001c) /*UART 0 Modem status*/
#define rUBRDIV0 (*(volatile unsigned *)0x50000028) /*UART 0 Baud rate divisor*/
#define rULCON1 (*(volatile unsigned *)0x50004000) /*UART 1 Line control*/
#define rUCON1 (*(volatile unsigned *)0x50004004) /*UART 1 Control*/
#define rUFCON1 (*(volatile unsigned *)0x50004008) /*UART 1 FIFO control*/
#define rUMCON1 (*(volatile unsigned *)0x5000400c) /*UART 1 Modem control*/
#define rUTRSTAT1 (*(volatile unsigned *)0x50004010) /*UART 1 Tx/Rx status*/
#define rUERSTAT1 (*(volatile unsigned *)0x50004014) /*UART 1 Rx error status*/
#define rUFSTAT1 (*(volatile unsigned *)0x50004018) /*UART 1 FIFO status*/
#define rUMSTAT1 (*(volatile unsigned *)0x5000401c) /*UART 1 Modem status*/
#define rUBRDIV1 (*(volatile unsigned *)0x50004028) /*UART 1 Baud rate divisor*/
#define rULCON2 (*(volatile unsigned *)0x50008000) /*UART 2 Line control*/
#define rUCON2 (*(volatile unsigned *)0x50008004) /*UART 2 Control*/
#define rUFCON2 (*(volatile unsigned *)0x50008008) /*UART 2 FIFO control*/
#define rUTRSTAT2 (*(volatile unsigned *)0x50008010) /*UART 2 Tx/Rx status*/
#define rUERSTAT2 (*(volatile unsigned *)0x50008014) /*UART 2 Rx error status*/
#define rUFSTAT2 (*(volatile unsigned *)0x50008018) /*UART 2 FIFO status*/
#define rUBRDIV2 (*(volatile unsigned *)0x50008028) /*UART 2 Baud rate divisor*/
#define WrUTXH0(ch) (*(volatile unsigned char *)0x50000020)=(unsigned char)(ch)
#define RdURXH0() (*(volatile unsigned char *)0x50000024)
#define WrUTXH1(ch) (*(volatile unsigned char *)0x50004020)=(unsigned char)(ch)
#define RdURXH1() (*(volatile unsigned char *)0x50004024)
#define WrUTXH2(ch) (*(volatile unsigned char *)0x50008020)=(unsigned char)(ch)
#define RdURXH2() (*(volatile unsigned char *)0x50008024)
extern void serial_init_115200_s3c24xx(const int uart, const int pclk_MHz);
extern void serial_putc_s3c24xx(const int uart, const char c);
extern int puts(const char *string);
#endif

View File

@ -1,72 +0,0 @@
/*
* (C) Copyright 2007 OpenMoko, Inc.
* Author: xiangfu liu <xiangfu@openmoko.org>
*
* Configuation settings for the FIC Neo GTA02 Linux GSM phone
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef __SERIAL_S3C64XX_H__
#define __SERIAL_S3C64XX_H__
#define UART0 0
#define UART1 1
#define UART2 2
#define rGPHCON (*(volatile unsigned *)0x56000070) /*UART 0 Line control*/
#define rULCON0 (*(volatile unsigned *)0x50000000) /*UART 0 Line control*/
#define rUCON0 (*(volatile unsigned *)0x50000004) /*UART 0 Control*/
#define rUFCON0 (*(volatile unsigned *)0x50000008) /*UART 0 FIFO control*/
#define rUMCON0 (*(volatile unsigned *)0x5000000c) /*UART 0 Modem control*/
#define rUTRSTAT0 (*(volatile unsigned *)0x50000010) /*UART 0 Tx/Rx status*/
#define rUERSTAT0 (*(volatile unsigned *)0x50000014) /*UART 0 Rx error status*/
#define rUFSTAT0 (*(volatile unsigned *)0x50000018) /*UART 0 FIFO status*/
#define rUMSTAT0 (*(volatile unsigned *)0x5000001c) /*UART 0 Modem status*/
#define rUBRDIV0 (*(volatile unsigned *)0x50000028) /*UART 0 Baud rate divisor*/
#define rULCON1 (*(volatile unsigned *)0x50004000) /*UART 1 Line control*/
#define rUCON1 (*(volatile unsigned *)0x50004004) /*UART 1 Control*/
#define rUFCON1 (*(volatile unsigned *)0x50004008) /*UART 1 FIFO control*/
#define rUMCON1 (*(volatile unsigned *)0x5000400c) /*UART 1 Modem control*/
#define rUTRSTAT1 (*(volatile unsigned *)0x50004010) /*UART 1 Tx/Rx status*/
#define rUERSTAT1 (*(volatile unsigned *)0x50004014) /*UART 1 Rx error status*/
#define rUFSTAT1 (*(volatile unsigned *)0x50004018) /*UART 1 FIFO status*/
#define rUMSTAT1 (*(volatile unsigned *)0x5000401c) /*UART 1 Modem status*/
#define rUBRDIV1 (*(volatile unsigned *)0x50004028) /*UART 1 Baud rate divisor*/
#define rULCON2 (*(volatile unsigned *)0x50008000) /*UART 2 Line control*/
#define rUCON2 (*(volatile unsigned *)0x50008004) /*UART 2 Control*/
#define rUFCON2 (*(volatile unsigned *)0x50008008) /*UART 2 FIFO control*/
#define rUTRSTAT2 (*(volatile unsigned *)0x50008010) /*UART 2 Tx/Rx status*/
#define rUERSTAT2 (*(volatile unsigned *)0x50008014) /*UART 2 Rx error status*/
#define rUFSTAT2 (*(volatile unsigned *)0x50008018) /*UART 2 FIFO status*/
#define rUBRDIV2 (*(volatile unsigned *)0x50008028) /*UART 2 Baud rate divisor*/
#define WrUTXH0(ch) (*(volatile unsigned char *)0x50000020)=(unsigned char)(ch)
#define RdURXH0() (*(volatile unsigned char *)0x50000024)
#define WrUTXH1(ch) (*(volatile unsigned char *)0x50004020)=(unsigned char)(ch)
#define RdURXH1() (*(volatile unsigned char *)0x50004024)
#define WrUTXH2(ch) (*(volatile unsigned char *)0x50008020)=(unsigned char)(ch)
#define RdURXH2() (*(volatile unsigned char *)0x50008024)
extern void serial_init_115200_s3c64xx(const int uart, const int pclk_MHz);
extern void serial_putc_s3c64xx(const int uart, const char c);
extern int puts(const char *string);
#endif

View File

@ -1,269 +0,0 @@
/*
* linux/include/asm/setup.h
*
* Copyright (C) 1997-1999 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Structure passed to kernel to tell it about the
* hardware it's running on. See linux/Documentation/arm/Setup
* for more info.
*
* NOTE:
* This file contains two ways to pass information from the boot
* loader to the kernel. The old struct param_struct is deprecated,
* but it will be kept in the kernel for 5 years from now
* (2001). This will allow boot loaders to convert to the new struct
* tag way.
*/
#ifndef __ASMARM_SETUP_H
#define __ASMARM_SETUP_H
/*
* Usage:
* - do not go blindly adding fields, add them at the end
* - when adding fields, don't rely on the address until
* a patch from me has been released
* - unused fields should be zero (for future expansion)
* - this structure is relatively short-lived - only
* guaranteed to contain useful data in setup_arch()
*/
#define COMMAND_LINE_SIZE 1024
/* This is the old deprecated way to pass parameters to the kernel */
struct param_struct {
union {
struct {
unsigned long page_size; /* 0 */
unsigned long nr_pages; /* 4 */
unsigned long ramdisk_size; /* 8 */
unsigned long flags; /* 12 */
#define FLAG_READONLY 1
#define FLAG_RDLOAD 4
#define FLAG_RDPROMPT 8
unsigned long rootdev; /* 16 */
unsigned long video_num_cols; /* 20 */
unsigned long video_num_rows; /* 24 */
unsigned long video_x; /* 28 */
unsigned long video_y; /* 32 */
unsigned long memc_control_reg; /* 36 */
unsigned char sounddefault; /* 40 */
unsigned char adfsdrives; /* 41 */
unsigned char bytes_per_char_h; /* 42 */
unsigned char bytes_per_char_v; /* 43 */
unsigned long pages_in_bank[4]; /* 44 */
unsigned long pages_in_vram; /* 60 */
unsigned long initrd_start; /* 64 */
unsigned long initrd_size; /* 68 */
unsigned long rd_start; /* 72 */
unsigned long system_rev; /* 76 */
unsigned long system_serial_low; /* 80 */
unsigned long system_serial_high; /* 84 */
unsigned long mem_fclk_21285; /* 88 */
} s;
char unused[256];
} u1;
union {
char paths[8][128];
struct {
unsigned long magic;
char n[1024 - sizeof(unsigned long)];
} s;
} u2;
char commandline[COMMAND_LINE_SIZE];
};
/*
* The new way of passing information: a list of tagged entries
*/
/* The list ends with an ATAG_NONE node. */
#define ATAG_NONE 0x00000000
struct tag_header {
u32 size;
u32 tag;
};
/* The list must start with an ATAG_CORE node */
#define ATAG_CORE 0x54410001
struct tag_core {
u32 flags; /* bit 0 = read-only */
u32 pagesize;
u32 rootdev;
};
/* it is allowed to have multiple ATAG_MEM nodes */
#define ATAG_MEM 0x54410002
struct tag_mem32 {
u32 size;
u32 start; /* physical start address */
};
/* VGA text type displays */
#define ATAG_VIDEOTEXT 0x54410003
struct tag_videotext {
u8 x;
u8 y;
u16 video_page;
u8 video_mode;
u8 video_cols;
u16 video_ega_bx;
u8 video_lines;
u8 video_isvga;
u16 video_points;
};
/* describes how the ramdisk will be used in kernel */
#define ATAG_RAMDISK 0x54410004
struct tag_ramdisk {
u32 flags; /* bit 0 = load, bit 1 = prompt */
u32 size; /* decompressed ramdisk size in _kilo_ bytes */
u32 start; /* starting block of floppy-based RAM disk image */
};
/* describes where the compressed ramdisk image lives (virtual address) */
/*
* this one accidentally used virtual addresses - as such,
* its depreciated.
*/
#define ATAG_INITRD 0x54410005
/* describes where the compressed ramdisk image lives (physical address) */
#define ATAG_INITRD2 0x54420005
struct tag_initrd {
u32 start; /* physical start address */
u32 size; /* size of compressed ramdisk image in bytes */
};
/* board serial number. "64 bits should be enough for everybody" */
#define ATAG_SERIAL 0x54410006
struct tag_serialnr {
u32 low;
u32 high;
};
/* board revision */
#define ATAG_REVISION 0x54410007
struct tag_revision {
u32 rev;
};
/* initial values for vesafb-type framebuffers. see struct screen_info
* in include/linux/tty.h
*/
#define ATAG_VIDEOLFB 0x54410008
struct tag_videolfb {
u16 lfb_width;
u16 lfb_height;
u16 lfb_depth;
u16 lfb_linelength;
u32 lfb_base;
u32 lfb_size;
u8 red_size;
u8 red_pos;
u8 green_size;
u8 green_pos;
u8 blue_size;
u8 blue_pos;
u8 rsvd_size;
u8 rsvd_pos;
};
/* command line: \0 terminated string */
#define ATAG_CMDLINE 0x54410009
struct tag_cmdline {
char cmdline[1]; /* this is the minimum size */
};
/* acorn RiscPC specific information */
#define ATAG_ACORN 0x41000101
struct tag_acorn {
u32 memc_control_reg;
u32 vram_pages;
u8 sounddefault;
u8 adfsdrives;
};
/* footbridge memory clock, see arch/arm/mach-footbridge/arch.c */
#define ATAG_MEMCLK 0x41000402
struct tag_memclk {
u32 fmemclk;
};
struct tag {
struct tag_header hdr;
union {
struct tag_core core;
struct tag_mem32 mem;
struct tag_videotext videotext;
struct tag_ramdisk ramdisk;
struct tag_initrd initrd;
struct tag_serialnr serialnr;
struct tag_revision revision;
struct tag_videolfb videolfb;
struct tag_cmdline cmdline;
/*
* Acorn specific
*/
struct tag_acorn acorn;
/*
* DC21285 specific
*/
struct tag_memclk memclk;
} u;
};
struct tagtable {
u32 tag;
int (*parse)(const struct tag *);
};
#define __tag __attribute__((unused, __section__(".taglist")))
#define __tagtable(tag, fn) \
static struct tagtable __tagtable_##fn __tag = { tag, fn }
#define tag_member_present(tag,member) \
((unsigned long)(&((struct tag *)0L)->member + 1) \
<= (tag)->hdr.size * 4)
#define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size))
#define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
#define for_each_tag(t,base) \
for (t = base; t->hdr.size; t = tag_next(t))
/*
* Memory map description
*/
#define NR_BANKS 8
struct meminfo {
int nr_banks;
unsigned long end;
struct {
unsigned long start;
unsigned long size;
int node;
} bank[NR_BANKS];
};
extern struct meminfo meminfo;
#endif

View File

@ -1,6 +0,0 @@
#ifndef __ASM_MODE__
#include <qi.h>
extern const struct board_api board_api_smdk6410;
#endif
#define TEXT_BASE_SMDK6410 0x53000000

View File

@ -1,16 +0,0 @@
# ARM1176 / s3c6410 OpenOCD config suitable for Openmoko Debug board usage
telnet_port 4444
gdb_port 3333
interface ft2232
jtag_speed 18
ft2232_layout oocdlink
#Info: 446 309386 jtag.c:1410 jtag_examine_chain(): JTAG device found: 0x2b900f0f (Manufacturer: 0x787, Part: 0xb900, Version: 0x2)
#Info: 447 309386 jtag.c:1410 jtag_examine_chain(): JTAG device found: 0x07b76f0f (Manufacturer: 0x787, Part: 0x7b76, Version: 0x0)
jtag_device 4 0x1 0xF 0xE
jtag_device 5 0x1 0x1F 0x1E
reset_config trst_and_srst
target create target0 arm11 -endian little -chain-position 1 -variant arm11

View File

@ -1,90 +0,0 @@
/*
* (C) Copyright 2007 OpenMoko, Inc.
* Author: xiangfu liu <xiangfu@openmoko.org>
*
* Configuation settings for the FIC Neo GTA02 Linux GSM phone
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include "blink_led.h"
int delay(int time)
{
int i=0;
for(i=0;i<time;i++);
return 0;
}
int set_GPB(void)
{
GPBCON = 0x5;
GPBDW = 0xffff;
return 0;
}
int orange_on(int times)
{
int count=0;
set_GPB();
for(count=0;count<times;count++)
{
ORANGE_ON();
delay(0xfffff);
ORANGE_OFF() ;
delay(0xfffff);
}
return 0;
}
int blue_on(int times)
{
int count=0;
set_GPB();
for(count=0;count<times;count++)
{
BLUE_ON();
delay(0xfffff);
BLUE_OFF();
delay(0xfffff);
}
return 0;
}
int blink_led(void)
{
set_GPB();
while(1)
{
ORANGE_ON();
delay(0xfffff);
ORANGE_OFF() ;
delay(0xfffff);
BLUE_ON();
delay(0xfffff);
BLUE_OFF();
delay(0xfffff);
}
return 0;
}

View File

@ -1,39 +0,0 @@
/*
* (C) Copyright 2007 OpenMoko, Inc.
* Author: xiangfu liu <xiangfu@openmoko.org>
*
* Configuation settings for the FIC Neo GTA02 Linux GSM phone
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef __BLINK_LED_H
#define __BLINK_LED_H
#define GPBCON (*(volatile unsigned *)0x56000010)
#define GPBDAT (*(volatile unsigned *)0x56000014)
#define GPBDW (*(volatile unsigned *)0x56000018)
#define ORANGE_OFF() (GPBDAT &= ~(0x1))
#define BLUE_OFF() (GPBDAT &= ~(0x2))
#define ORANGE_ON() (GPBDAT |= (0x1))
#define BLUE_ON() (GPBDAT |= (0x2))
int orange_on(int times);
int blue_on(int times);
int blink_led(void);
int delay(int time);
#endif /* __BLINK_LED_H */

View File

@ -1,681 +0,0 @@
/*
* (C) Copyright 2000-2007
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef __COMMON_H_
#define __COMMON_H_ 1
#undef _LINUX_CONFIG_H
#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
typedef unsigned char uchar;
typedef volatile unsigned long vu_long;
typedef volatile unsigned short vu_short;
typedef volatile unsigned char vu_char;
#include <config.h>
#include <linux/bitops.h>
#include <linux/types.h>
#include <linux/string.h>
#include <asm/ptrace.h>
#include <stdarg.h>
#if defined(CONFIG_PCI) && (defined(CONFIG_4xx) && !defined(CONFIG_AP1000))
#include <pci.h>
#endif
#if defined(CONFIG_8xx)
#include <asm/8xx_immap.h>
#if defined(CONFIG_MPC852) || defined(CONFIG_MPC852T) || \
defined(CONFIG_MPC859) || defined(CONFIG_MPC859T) || \
defined(CONFIG_MPC859DSL) || \
defined(CONFIG_MPC866) || defined(CONFIG_MPC866T) || \
defined(CONFIG_MPC866P)
# define CONFIG_MPC866_FAMILY 1
#elif defined(CONFIG_MPC870) \
|| defined(CONFIG_MPC875) \
|| defined(CONFIG_MPC880) \
|| defined(CONFIG_MPC885)
# define CONFIG_MPC885_FAMILY 1
#endif
#if defined(CONFIG_MPC860) \
|| defined(CONFIG_MPC860T) \
|| defined(CONFIG_MPC866_FAMILY) \
|| defined(CONFIG_MPC885_FAMILY)
# define CONFIG_MPC86x 1
#endif
#elif defined(CONFIG_5xx)
#include <asm/5xx_immap.h>
#elif defined(CONFIG_MPC5xxx)
#include <mpc5xxx.h>
#elif defined(CONFIG_MPC512X)
#include <mpc512x.h>
#include <asm/immap_512x.h>
#elif defined(CONFIG_MPC8220)
#include <asm/immap_8220.h>
#elif defined(CONFIG_8260)
#if defined(CONFIG_MPC8247) \
|| defined(CONFIG_MPC8248) \
|| defined(CONFIG_MPC8271) \
|| defined(CONFIG_MPC8272)
#define CONFIG_MPC8272_FAMILY 1
#endif
#if defined(CONFIG_MPC8272_FAMILY)
#define CONFIG_MPC8260 1
#endif
#include <asm/immap_8260.h>
#endif
#ifdef CONFIG_MPC86xx
#include <mpc86xx.h>
#include <asm/immap_86xx.h>
#endif
#ifdef CONFIG_MPC85xx
#include <mpc85xx.h>
#include <asm/immap_85xx.h>
#endif
#ifdef CONFIG_MPC83XX
#include <mpc83xx.h>
#include <asm/immap_83xx.h>
#endif
#ifdef CONFIG_4xx
#include <ppc4xx.h>
#endif
#ifdef CONFIG_HYMOD
#include <board/hymod/hymod.h>
#endif
#ifdef CONFIG_ARM
#define asmlinkage /* nothing */
#endif
#ifdef CONFIG_BLACKFIN
#include <asm/blackfin.h>
#endif
#include <part.h>
#include <flash.h>
#include <image.h>
#ifdef DEBUG
#define debug(fmt,args...) printf (fmt ,##args)
#define debugX(level,fmt,args...) if (DEBUG>=level) printf(fmt,##args);
#else
#define debug(fmt,args...)
#define debugX(level,fmt,args...)
#endif /* DEBUG */
#define BUG() do { \
printf("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \
panic("BUG!"); \
} while (0)
#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0)
typedef void (interrupt_handler_t)(void *);
#include <asm/u-boot.h> /* boot information for Linux kernel */
#include <asm/global_data.h> /* global data used for startup functions */
/*
* enable common handling for all TQM8xxL/M boards:
* - CONFIG_TQM8xxM will be defined for all TQM8xxM boards
* - CONFIG_TQM8xxL will be defined for all TQM8xxL _and_ TQM8xxM boards
* and for the TQM885D board
*/
#if defined(CONFIG_TQM823M) || defined(CONFIG_TQM850M) || \
defined(CONFIG_TQM855M) || defined(CONFIG_TQM860M) || \
defined(CONFIG_TQM862M) || defined(CONFIG_TQM866M)
# ifndef CONFIG_TQM8xxM
# define CONFIG_TQM8xxM
# endif
#endif
#if defined(CONFIG_TQM823L) || defined(CONFIG_TQM850L) || \
defined(CONFIG_TQM855L) || defined(CONFIG_TQM860L) || \
defined(CONFIG_TQM862L) || defined(CONFIG_TQM8xxM) || \
defined(CONFIG_TQM885D)
# ifndef CONFIG_TQM8xxL
# define CONFIG_TQM8xxL
# endif
#endif
#ifndef CONFIG_SERIAL_MULTI
#if defined(CONFIG_8xx_CONS_SMC1) || defined(CONFIG_8xx_CONS_SMC2) \
|| defined(CONFIG_8xx_CONS_SCC1) || defined(CONFIG_8xx_CONS_SCC2) \
|| defined(CONFIG_8xx_CONS_SCC3) || defined(CONFIG_8xx_CONS_SCC4)
#define CONFIG_SERIAL_MULTI 1
#endif
#endif /* CONFIG_SERIAL_MULTI */
/*
* General Purpose Utilities
*/
#define min(X, Y) \
({ typeof (X) __x = (X), __y = (Y); \
(__x < __y) ? __x : __y; })
#define max(X, Y) \
({ typeof (X) __x = (X), __y = (Y); \
(__x > __y) ? __x : __y; })
/*
* Function Prototypes
*/
#ifdef CONFIG_SERIAL_SOFTWARE_FIFO
void serial_buffered_init (void);
void serial_buffered_putc (const char);
void serial_buffered_puts (const char *);
int serial_buffered_getc (void);
int serial_buffered_tstc (void);
#endif /* CONFIG_SERIAL_SOFTWARE_FIFO */
void hang (void) __attribute__ ((noreturn));
/* */
long int initdram (int);
int display_options (void);
void print_size (ulong, const char *);
int print_buffer (ulong addr, void* data, uint width, uint count, uint linelen);
/* common/main.c */
void main_loop (void);
int run_command (const char *cmd, int flag);
int readline (const char *const prompt);
int readline_into_buffer (const char *const prompt, char * buffer);
int parse_line (char *, char *[]);
void init_cmd_timeout(void);
void reset_cmd_timeout(void);
/* lib_$(ARCH)/board.c */
void board_init_f (ulong) __attribute__ ((noreturn));
void board_init_r (gd_t *, ulong) __attribute__ ((noreturn));
int checkboard (void);
int checkflash (void);
int checkdram (void);
char * strmhz(char *buf, long hz);
int last_stage_init(void);
extern ulong monitor_flash_len;
#ifdef CFG_ID_EEPROM
int mac_read_from_eeprom(void);
#endif
/* common/flash.c */
void flash_perror (int);
/* common/cmd_autoscript.c */
int autoscript (ulong addr, const char *fit_uname);
extern ulong load_addr; /* Default Load Address */
/* common/cmd_nvedit.c */
int env_init (void);
void env_relocate (void);
int envmatch (uchar *, int);
char *getenv (char *);
int getenv_r (char *name, char *buf, unsigned len);
int saveenv (void);
#ifdef CONFIG_PPC /* ARM version to be fixed! */
void inline setenv (char *, char *);
#else
void setenv (char *, char *);
#ifdef CONFIG_HAS_UID
void forceenv (char *, char *);
#endif
#endif /* CONFIG_PPC */
#ifdef CONFIG_ARM
# include <asm/mach-types.h>
# include <asm/setup.h>
# include <asm/u-boot-arm.h> /* ARM version to be fixed! */
#endif /* CONFIG_ARM */
#ifdef CONFIG_I386 /* x86 version to be fixed! */
# include <asm/u-boot-i386.h>
#endif /* CONFIG_I386 */
#ifdef CONFIG_AUTO_COMPLETE
int env_complete(char *var, int maxv, char *cmdv[], int maxsz, char *buf);
#endif
void pci_init (void);
void pci_init_board(void);
void pciinfo (int, int);
#if defined(CONFIG_PCI) && (defined(CONFIG_4xx) && !defined(CONFIG_AP1000))
int pci_pre_init (struct pci_controller * );
#endif
#if defined(CONFIG_PCI) && (defined(CONFIG_440) || defined(CONFIG_405EX))
# if defined(CFG_PCI_TARGET_INIT)
void pci_target_init (struct pci_controller *);
# endif
# if defined(CFG_PCI_MASTER_INIT)
void pci_master_init (struct pci_controller *);
# endif
int is_pci_host (struct pci_controller *);
#if defined(CONFIG_440SPE) || \
defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
defined(CONFIG_405EX)
void pcie_setup_hoses(int busno);
#endif
#endif
int misc_init_f (void);
int misc_init_r (void);
/* common/exports.c */
void jumptable_init(void);
/* api/api.c */
void api_init (void);
/* common/memsize.c */
long get_ram_size (volatile long *, long);
/* $(BOARD)/$(BOARD).c */
void reset_phy (void);
void fdc_hw_init (void);
/* $(BOARD)/eeprom.c */
void eeprom_init (void);
#ifndef CONFIG_SPI
int eeprom_probe (unsigned dev_addr, unsigned offset);
#endif
int eeprom_read (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt);
int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt);
#ifdef CONFIG_LWMON
extern uchar pic_read (uchar reg);
extern void pic_write (uchar reg, uchar val);
#endif
/*
* Set this up regardless of board
* type, to prevent errors.
*/
#if defined(CONFIG_SPI) || !defined(CFG_I2C_EEPROM_ADDR)
# define CFG_DEF_EEPROM_ADDR 0
#else
# define CFG_DEF_EEPROM_ADDR CFG_I2C_EEPROM_ADDR
#endif /* CONFIG_SPI || !defined(CFG_I2C_EEPROM_ADDR) */
#if defined(CONFIG_SPI)
extern void spi_init_f (void);
extern void spi_init_r (void);
extern ssize_t spi_read (uchar *, int, uchar *, int);
extern ssize_t spi_write (uchar *, int, uchar *, int);
#endif
#ifdef CONFIG_RPXCLASSIC
void rpxclassic_init (void);
#endif
void rpxlite_init (void);
#ifdef CONFIG_MBX
/* $(BOARD)/mbx8xx.c */
void mbx_init (void);
void board_serial_init (void);
void board_ether_init (void);
#endif
#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_MBX) || \
defined(CONFIG_IAD210) || defined(CONFIG_XPEDITE1K) || \
defined(CONFIG_METROBOX) || defined(CONFIG_KAREF) || \
defined(CONFIG_V38B)
void board_get_enetaddr (uchar *addr);
#endif
#ifdef CONFIG_HERMES
/* $(BOARD)/hermes.c */
void hermes_start_lxt980 (int speed);
#endif
#ifdef CONFIG_EVB64260
void evb64260_init(void);
void debug_led(int, int);
void display_mem_map(void);
void perform_soft_reset(void);
#endif
void load_sernum_ethaddr (void);
/* $(BOARD)/$(BOARD).c */
int board_early_init_f (void);
int board_late_init (void);
int board_postclk_init (void); /* after clocks/timebase, before env/serial */
int board_early_init_r (void);
void board_poweroff (void);
#if defined(CFG_DRAM_TEST)
int testdram(void);
#endif /* CFG_DRAM_TEST */
/* $(CPU)/start.S */
#if defined(CONFIG_5xx) || \
defined(CONFIG_8xx)
uint get_immr (uint);
#endif
uint get_pir (void);
#if defined(CONFIG_MPC5xxx)
uint get_svr (void);
#endif
uint get_pvr (void);
uint get_svr (void);
uint rd_ic_cst (void);
void wr_ic_cst (uint);
void wr_ic_adr (uint);
uint rd_dc_cst (void);
void wr_dc_cst (uint);
void wr_dc_adr (uint);
int icache_status (void);
void icache_enable (void);
void icache_disable(void);
int dcache_status (void);
void dcache_enable (void);
void dcache_disable(void);
void relocate_code (ulong, gd_t *, ulong) __attribute__ ((noreturn));
ulong get_endaddr (void);
void trap_init (ulong);
#if defined (CONFIG_4xx) || \
defined (CONFIG_MPC5xxx) || \
defined (CONFIG_74xx_7xx) || \
defined (CONFIG_74x) || \
defined (CONFIG_75x) || \
defined (CONFIG_74xx) || \
defined (CONFIG_MPC8220) || \
defined (CONFIG_MPC85xx) || \
defined (CONFIG_MPC86xx) || \
defined (CONFIG_MPC83XX)
unsigned char in8(unsigned int);
void out8(unsigned int, unsigned char);
unsigned short in16(unsigned int);
unsigned short in16r(unsigned int);
void out16(unsigned int, unsigned short value);
void out16r(unsigned int, unsigned short value);
unsigned long in32(unsigned int);
unsigned long in32r(unsigned int);
void out32(unsigned int, unsigned long value);
void out32r(unsigned int, unsigned long value);
void ppcDcbf(unsigned long value);
void ppcDcbi(unsigned long value);
void ppcSync(void);
void ppcDcbz(unsigned long value);
#endif
#if defined (CONFIG_MICROBLAZE)
unsigned short in16(unsigned int);
void out16(unsigned int, unsigned short value);
#endif
#if defined (CONFIG_MPC83XX)
void ppcDWload(unsigned int *addr, unsigned int *ret);
void ppcDWstore(unsigned int *addr, unsigned int *value);
#endif
/* $(CPU)/cpu.c */
int checkcpu (void);
int checkicache (void);
int checkdcache (void);
void upmconfig (unsigned int, unsigned int *, unsigned int);
ulong get_tbclk (void);
void reset_cpu (ulong addr);
#if defined (CONFIG_OF_LIBFDT) && defined (CONFIG_OF_BOARD_SETUP)
void ft_cpu_setup(void *blob, bd_t *bd);
#ifdef CONFIG_PCI
void ft_pci_setup(void *blob, bd_t *bd);
#endif
#endif
/* $(CPU)/serial.c */
int serial_init (void);
void serial_addr (unsigned int);
void serial_setbrg (void);
void serial_putc (const char);
void serial_putc_raw(const char);
void serial_puts (const char *);
int serial_getc (void);
int serial_tstc (void);
void _serial_setbrg (const int);
void _serial_putc (const char, const int);
void _serial_putc_raw(const char, const int);
void _serial_puts (const char *, const int);
int _serial_getc (const int);
int _serial_tstc (const int);
/* $(CPU)/speed.c */
int get_clocks (void);
int get_clocks_866 (void);
int sdram_adjust_866 (void);
int adjust_sdram_tbs_8xx (void);
#if defined(CONFIG_8260)
int prt_8260_clks (void);
#elif defined(CONFIG_MPC5xxx)
int prt_mpc5xxx_clks (void);
#endif
#if defined(CONFIG_MPC512X)
int prt_mpc512xxx_clks (void);
#endif
#if defined(CONFIG_MPC8220)
int prt_mpc8220_clks (void);
#endif
#ifdef CONFIG_4xx
ulong get_OPB_freq (void);
ulong get_PCI_freq (void);
#endif
#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || \
defined(CONFIG_S3C2440) || defined(CONFIG_S3C2442) || \
defined(CONFIG_LH7A40X)
void s3c2410_irq(void);
#define ARM920_IRQ_CALLBACK s3c2410_irq
ulong get_FCLK (void);
ulong get_HCLK (void);
ulong get_PCLK (void);
ulong get_UCLK (void);
#endif
#if defined(CONFIG_LH7A40X)
ulong get_PLLCLK (void);
#endif
#if defined CONFIG_INCA_IP
uint incaip_get_cpuclk (void);
#endif
#if defined(CONFIG_IMX)
ulong get_systemPLLCLK(void);
ulong get_FCLK(void);
ulong get_HCLK(void);
ulong get_BCLK(void);
ulong get_PERCLK1(void);
ulong get_PERCLK2(void);
ulong get_PERCLK3(void);
#endif
ulong get_bus_freq (ulong);
#if defined(CONFIG_MPC85xx)
typedef MPC85xx_SYS_INFO sys_info_t;
void get_sys_info ( sys_info_t * );
ulong get_ddr_freq (ulong);
#endif
#if defined(CONFIG_MPC86xx)
typedef MPC86xx_SYS_INFO sys_info_t;
void get_sys_info ( sys_info_t * );
#endif
#if defined(CONFIG_4xx) || defined(CONFIG_IOP480)
# if defined(CONFIG_440)
# if defined(CONFIG_440SPE)
unsigned long determine_sysper(void);
unsigned long determine_pci_clock_per(void);
# endif
# endif
typedef PPC4xx_SYS_INFO sys_info_t;
int ppc440spe_revB(void);
void get_sys_info ( sys_info_t * );
#endif
/* $(CPU)/cpu_init.c */
#if defined(CONFIG_8xx) || defined(CONFIG_8260)
void cpu_init_f (volatile immap_t *immr);
#endif
#if defined(CONFIG_4xx) || defined(CONFIG_MPC85xx) || defined(CONFIG_MCF52x2) ||defined(CONFIG_MPC86xx)
void cpu_init_f (void);
#endif
int cpu_init_r (void);
#if defined(CONFIG_8260)
int prt_8260_rsr (void);
#elif defined(CONFIG_MPC83XX)
int prt_83xx_rsr (void);
#endif
/* $(CPU)/interrupts.c */
int interrupt_init (void);
void timer_interrupt (struct pt_regs *);
void external_interrupt (struct pt_regs *);
void irq_install_handler(int, interrupt_handler_t *, void *);
void irq_free_handler (int);
void reset_timer (void);
ulong get_timer (ulong base);
void set_timer (ulong t);
void enable_interrupts (void);
int disable_interrupts (void);
/* $(CPU)/.../commproc.c */
int dpram_init (void);
uint dpram_base(void);
uint dpram_base_align(uint align);
uint dpram_alloc(uint size);
uint dpram_alloc_align(uint size,uint align);
void post_word_store (ulong);
ulong post_word_load (void);
void bootcount_store (ulong);
ulong bootcount_load (void);
#define BOOTCOUNT_MAGIC 0xB001C041
/* $(CPU)/.../<eth> */
void mii_init (void);
/* $(CPU)/.../lcd.c */
ulong lcd_setmem (ulong);
/* $(CPU)/.../vfd.c */
ulong vfd_setmem (ulong);
/* $(CPU)/.../video.c */
ulong video_setmem (ulong);
/* lib_$(ARCH)/cache.c */
void flush_cache (unsigned long, unsigned long);
/* lib_$(ARCH)/ticks.S */
unsigned long long get_ticks(void);
void wait_ticks (unsigned long);
/* lib_$(ARCH)/time.c */
void udelay (unsigned long);
ulong usec2ticks (unsigned long usec);
ulong ticks2usec (unsigned long ticks);
int init_timebase (void);
/* lib_generic/vsprintf.c */
ulong simple_strtoul(const char *cp,char **endp,unsigned int base);
#ifdef CFG_64BIT_VSPRINTF
unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base);
#endif
long simple_strtol(const char *cp,char **endp,unsigned int base);
void panic(const char *fmt, ...);
int sprintf(char * buf, const char *fmt, ...);
int vsprintf(char *buf, const char *fmt, va_list args);
/* lib_generic/crc32.c */
ulong crc32 (ulong, const unsigned char *, uint);
ulong crc32_no_comp (ulong, const unsigned char *, uint);
/* common/console.c */
int console_init_f(void); /* Before relocation; uses the serial stuff */
int console_init_r(void); /* After relocation; uses the console stuff */
int console_assign (int file, char *devname); /* Assign the console */
int ctrlc (void);
int had_ctrlc (void); /* have we had a Control-C since last clear? */
void clear_ctrlc (void); /* clear the Control-C condition */
int disable_ctrlc (int); /* 1 to disable, 0 to enable Control-C detect */
/*
* STDIO based functions (can always be used)
*/
/* serial stuff */
void serial_printf (const char *fmt, ...);
/* stdin */
int getc(void);
int tstc(void);
/* stdout */
void putc(const char c);
void puts(const char *s);
void printf(const char *fmt, ...);
void vprintf(const char *fmt, va_list args);
/* stderr */
#define eputc(c) fputc(stderr, c)
#define eputs(s) fputs(stderr, s)
#define eprintf(fmt,args...) fprintf(stderr,fmt ,##args)
/*
* FILE based functions (can only be used AFTER relocation!)
*/
#define stdin 0
#define stdout 1
#define stderr 2
#define MAX_FILES 3
void fprintf(int file, const char *fmt, ...);
void fputs(int file, const char *s);
void fputc(int file, const char c);
int ftstc(int file);
int fgetc(int file);
int pcmcia_init (void);
#ifdef CONFIG_STATUS_LED
# include <status_led.h>
#endif
/*
* Board-specific Platform code can reimplement show_boot_progress () if needed
*/
void inline show_boot_progress (int val);
#ifdef CONFIG_INIT_CRITICAL
#error CONFIG_INIT_CRITICAL is deprecated!
#error Read section CONFIG_SKIP_LOWLEVEL_INIT in README.
#endif
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
/* Multicore arch functions */
#ifdef CONFIG_MP
int cpu_status(int nr);
int cpu_reset(int nr);
int cpu_release(int nr, int argc, char *argv[]);
#endif
#endif /* __COMMON_H_ */

View File

@ -1,312 +0,0 @@
/*
* (C) Copyright 2007 OpenMoko, Inc.
* Author: Andy Green <andy@openmoko.com>
*
* Configuation settings for the OPENMOKO Neo GTA02 Linux GSM phone
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
#include <qi.h>
#include <neo_gta01.h>
#include <serial-s3c24xx.h>
#include <ports-s3c24xx.h>
#include <s3c24xx-mci.h>
#include <i2c-bitbang-s3c24xx.h>
#include <pcf50606.h>
#define GTA01_DEBUG_UART 0
#define PCF50606_I2C_ADS 0x08
struct pcf50606_init {
u8 index;
u8 value;
};
/* initial register set for PCF50606 in Neo1973 devices */
const struct pcf50606_init pcf50606_initial_regs[] = {
{ PCF50606_REG_OOCS, 0x00 },
{ PCF50606_REG_INT1M, 0x00 },
{ PCF50606_REG_INT2M, 0x00 },
{ PCF50606_REG_INT3M, PCF50606_INT3_TSCPRES },
{ PCF50606_REG_OOCC1, PCF50606_OOCC1_RTCWAK | PCF50606_OOCC1_CHGWAK |
PCF50606_OOCC1_EXTONWAK_HIGH },
{ PCF50606_REG_OOCC2, PCF50606_OOCC2_ONKEYDB_14ms | PCF50606_OOCC2_EXTONDB_14ms },
{ PCF50606_REG_PSSC, 0x00 },
{ PCF50606_REG_PWROKM, 0x00 },
{ PCF50606_REG_DCDC1, 0x18 }, /* GL_1V5: off */
{ PCF50606_REG_DCDC2, 0x00 },
{ PCF50606_REG_DCDC3, 0x00 },
{ PCF50606_REG_DCDC4, 0x30 }, /* 1.25A */
{ PCF50606_REG_DCDEC1, 0xe8 }, /* IO_3V3: on */
{ PCF50606_REG_DCDEC2, 0x00 },
{ PCF50606_REG_DCUDC1, 0xc4 }, /* CORE_1V8: 2.1V if PWREN2 = HIGH */
{ PCF50606_REG_DCUDC2, 0x30 }, /* 1.25A current limit */
{ PCF50606_REG_IOREGC, 0xf8 }, /* CODEC_3V3: on */
{ PCF50606_REG_D1REGC1, 0x16 }, /* BT_3V15: off */
{ PCF50606_REG_D2REGC1, 0x10 }, /* GL_2V5: off */
{ PCF50606_REG_D3REGC1, 0xec }, /* STBY_1V8: 2.1V */
{ PCF50606_REG_LPREGC1, 0xf8 }, /* LCM_3V3: on */
{ PCF50606_REG_LPREGC2, 0x00 },
{ PCF50606_REG_MBCC1, 0x01 }, /* CHGAPE */
{ PCF50606_REG_MBCC2, 0x00 }, /* unlimited charging */
{ PCF50606_REG_MBCC3, 0x1a }, /* 0.2*Ifast, 4.20V */
{ PCF50606_REG_BBCC, 0x1f }, /* 400uA */
{ PCF50606_REG_ADCC1, 0x00 },
{ PCF50606_REG_ADCC2, 0x00 },
{ PCF50606_REG_ACDC1, 0x86 }, /* ACD thresh 1.6V, enabled */
{ PCF50606_REG_BVMC, PCF50606_BVMC_THRSHLD_3V3 },
{ PCF50606_REG_PWMC1, 0x00 },
{ PCF50606_REG_LEDC1, 0x00 },
{ PCF50606_REG_LEDC2, 0x00 },
{ PCF50606_REG_GPOC1, 0x00 },
{ PCF50606_REG_GPOC2, 0x00 },
{ PCF50606_REG_GPOC3, 0x00 },
{ PCF50606_REG_GPOC4, 0x00 },
{ PCF50606_REG_GPOC5, 0x00 },
};
static const struct board_variant board_variants[] = {
[0] = {
.name = "Bv4",
.machine_revision = 0x240,
}
};
void port_init_gta01(void)
{
int n;
unsigned int * MPLLCON = (unsigned int *)0x4c000004;
rGPACON = 0x005E0FFF;
rGPADAT = 0x00010000; /* nNAND_WP set high */
rGPBCON = 0x00045455;
rGPBUP = 0x000007FF;
rGPBDAT = 0x00000004; /* SD-card pwr off */
rGPCCON = 0xAAAA12A9;
rGPCUP = 0x0000FFFF;
rGPDCON = 0xAAAAAAAA;
rGPDUP = 0x0000FFFF;
rGPECON = 0xAAAAAAAA;
rGPEUP = 0x0000FFFF;
rGPFCON = 0x0000aa99;
rGPFUP = 0x000000FF;
rGPFDAT = 0x00000004;
rGPGCON = 0xFF14F0F8;
rGPGUP = 0x0000AFEF;
rGPHCON = 0x0000FAAA;
rGPHUP = 0x000007FF;
/* Load PMU with safe values */
for (n = 0; n < ARRAY_SIZE(pcf50606_initial_regs); n++)
i2c_write_sync(&bb_s3c24xx, PCF50606_I2C_ADS,
pcf50606_initial_regs[n].index,
pcf50606_initial_regs[n].value);
/* Give a short vibrate notification */
rGPBDAT |= (1 << 3);
udelay(1000000);
rGPBDAT &= ~(1 << 3);
/* change CPU to 266MHz 1:2:4 */
*MPLLCON = ((0x7d << 12) + (0x1 << 4) + 0x1);
/* Delay after update of PLL: Page 7-19, seven nops */
asm __volatile__ (
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
);
/* set debug UART working at 115kbps */
serial_init_115200_s3c24xx(GTA01_DEBUG_UART, 66 /* 66.5MHz PCLK */);
}
int sd_card_init_gta01(void)
{
int retval = -1;
/* Check if AUX is held. Then skip SD-card kernels!
* FIXME: This would be nicer to do with an API.
*/
if (!(rGPFDAT & (1 << 6))) {
return -1;
}
/* if SD card inserted, power it up and initialize*/
if (!(rGPFDAT & (1 << 5)))
{
rGPBDAT &= ~(1 << 2);
retval = s3c24xx_mmc_init(1);
}
return retval;
}
int sd_card_block_read_gta01(unsigned char * buf, unsigned long start512,
int blocks512)
{
return s3c24xx_mmc_bread(0, start512, blocks512, buf);
}
int is_this_board_gta01(void)
{
/* FIXME: How to check for GTA01 ? */
return 1;
}
const struct board_variant const * get_board_variant_gta01(void)
{
return &board_variants[0];
}
static __attribute__ (( section (".steppingstone") )) void putc_gta01(char c)
{
serial_putc_s3c24xx(GTA01_DEBUG_UART, c);
}
static void close_gta01(void)
{
/* set I2C GPIO back to peripheral unit */
(bb_s3c24xx.close)();
}
/* Here we will care only about AUX button as polling for PWR button
* through i2c slows down the boot */
static u8 get_ui_keys_gta01(void)
{
u8 keys;
u8 ret = 0;
static u8 old_keys = 0; /* previous state for debounce */
static u8 older_keys = 0; /* previous debounced output for edge detect */
/* GPF6 is AUX on GTA01, map to UI_ACTION_SKIPKERNEL, down = 0 */
keys = ! (rGPFDAT & (1 << 6));
/* edge action */
if ((old_keys & 1) && !(older_keys & 1))
ret |= UI_ACTION_SKIPKERNEL;
older_keys = old_keys;
old_keys = keys;
return ret;
}
static u8 get_ui_debug_gta01(void)
{
/* PWR button state can be seen in OOCS b0, down = 0, map to UI_ACTION_ADD_DEBUG */
return !(i2c_read_sync(&bb_s3c24xx, PCF50606_I2C_ADS, PCF50606_REG_OOCS) & 1);
}
/*
* API for bootloader on this machine
*/
const struct board_api board_api_gta01 = {
.name = "Neo1973 GTA01",
.linux_machine_id = 1182,
.linux_mem_start = 0x30000000,
.linux_mem_size = (128 * 1024 * 1024),
.linux_tag_placement = 0x30000000 + 0x100,
.get_board_variant = get_board_variant_gta01,
.is_this_board = is_this_board_gta01,
.port_init = port_init_gta01,
.putc = putc_gta01,
.close = close_gta01,
.get_ui_keys = get_ui_keys_gta01,
.get_ui_debug = get_ui_debug_gta01,
.commandline_board = "mtdparts="
"neo1973-nand:"
"0x00040000(qi),"
"0x00004000(u-boot_env),"
"0x00200000(kernel),"
"0x000a0000(splash),"
"0x03d1c000(rootfs) "
"loglevel=4 "
"console=tty0 "
"console=ttySAC0,115200 "
"init=/sbin/init "
"ro ",
.commandline_board_debug = " loglevel=8 ",
.noboot = "boot/noboot-GTA01",
.append = "boot/append-GTA01",
/* these are the ways we could boot GTA01 in order to try */
.kernel_source = {
[0] = {
.name = "SD Card EXT2 Kernel p1",
.block_init = sd_card_init_gta01,
.block_read = sd_card_block_read_gta01,
.partition_index = 1,
.filesystem = FS_EXT2,
.filepath = "boot/uImage-GTA01.bin",
.commandline_append = "root=/dev/mmcblk0p1 rootdelay=1 ",
},
[1] = {
.name = "SD Card EXT2 Kernel p2",
.block_init = sd_card_init_gta01,
.block_read = sd_card_block_read_gta01,
.partition_index = 2,
.filesystem = FS_EXT2,
.filepath = "boot/uImage-GTA01.bin",
.commandline_append = "root=/dev/mmcblk0p2 rootdelay=1 ",
},
[2] = {
.name = "SD Card EXT2 Kernel p3",
.block_init = sd_card_init_gta01,
.block_read = sd_card_block_read_gta01,
.partition_index = 3,
.filesystem = FS_EXT2,
.filepath = "boot/uImage-GTA01.bin",
.commandline_append = "root=/dev/mmcblk0p3 rootdelay=1 ",
},
[3] = {
.name = "NAND Kernel",
.block_read = nand_read_ll,
.offset_blocks512_if_no_partition = 0x44000 / 512,
.filesystem = FS_RAW,
.commandline_append = "rootfstype=jffs2 "
"root=/dev/mtdblock4 ",
},
},
};

View File

@ -1,68 +0,0 @@
/*
* (C) Copyright 2007 OpenMoko, Inc.
* Author: Andy Green <andy@openmoko.com>
*
* s3c24xx-specific i2c shared by, eg, GTA02 and GTA03
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
#include <qi.h>
#include <i2c-bitbang.h>
#include <ports-s3c24xx.h>
static char i2c_read_sda_s3c24xx(void)
{
return (rGPEDAT & 0x8000) != 0;
}
static void i2c_set_s3c24xx(char clock, char data)
{
if (clock) /* SCL <- input */
rGPECON = (rGPECON & ~0x30000000);
else { /* SCL <- output 0 */
rGPEDAT = (rGPEDAT & ~0x4000);
rGPECON = (rGPECON & ~0x30000000) | 0x10000000;
}
if (data) /* SDA <- input */
rGPECON = (rGPECON & ~0xc0000000);
else { /* SDA <- output 0 */
rGPEDAT = (rGPEDAT & ~0x8000);
rGPECON = (rGPECON & ~0xc0000000) | 0x40000000;
}
}
static void i2c_close_s3c24xx(void)
{
/* set back to hardware I2C ready for Linux */
rGPECON = (rGPECON & ~0xf0000000) | 0xa0000000;
}
static void i2c_spin_s3c24xx(void)
{
int n;
for (n = 0; n < 1000; n++)
rGPJDAT |= (1 << 5);
}
struct i2c_bitbang bb_s3c24xx = {
.read_sda = i2c_read_sda_s3c24xx,
.set = i2c_set_s3c24xx,
.spin = i2c_spin_s3c24xx,
.close = i2c_close_s3c24xx,
};

View File

@ -1,162 +0,0 @@
/*
* Memory Setup stuff - taken from blob memsetup.S
*
* Modified for the FIC Neo1973 GTA01 by Harald Welte <laforge@openmoko.org>
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/* NOTE this stuff runs in steppingstone context! */
/*
* #include <config.h>
* #include <version.h>
*/
#define __ASM_MODE__
#include <neo_gta01.h>
/*
*
* Taken from linux/arch/arm/boot/compressed/head-s3c2410.S
*
* Copyright (C) 2002 Samsung Electronics SW.LEE <hitchcar@sec.samsung.com>
*
*/
#define BWSCON 0x48000000
/* BWSCON */
#define DW8 (0x0)
#define DW16 (0x1)
#define DW32 (0x2)
#define WAIT (0x1<<2)
#define UBLB (0x1<<3)
#define B1_BWSCON (DW16 + WAIT + UBLB)
#define B2_BWSCON (DW16)
#define B3_BWSCON (DW16 + WAIT + UBLB)
#define B4_BWSCON (DW16)
#define B5_BWSCON (DW16)
#define B6_BWSCON (DW32)
#define B7_BWSCON (DW32)
/* BANK0CON */
#define B0_Tacs 0x0 /* 0clk */
#define B0_Tcos 0x0 /* 0clk */
#define B0_Tacc 0x7 /* 14clk */
#define B0_Tcoh 0x0 /* 0clk */
#define B0_Tah 0x0 /* 0clk */
#define B0_Tacp 0x0
#define B0_PMC 0x0 /* normal */
/* BANK1CON: Smedia Glamo 3362 (on GTA02) */
#define B1_Tacs 0x0 /* 0clk */
#define B1_Tcos 0x3 /* 4clk */
#define B1_Tacc 0x3 /* 4clk */
#define B1_Tcoh 0x3 /* 4clk */
#define B1_Tah 0x0 /* 0clk */
#define B1_Tacp 0x0
#define B1_PMC 0x0
#define B2_Tacs 0x0
#define B2_Tcos 0x0
#define B2_Tacc 0x7
#define B2_Tcoh 0x0
#define B2_Tah 0x0
#define B2_Tacp 0x0
#define B2_PMC 0x0
#define B3_Tacs 0x0 /* 0clk */
#define B3_Tcos 0x3 /* 4clk */
#define B3_Tacc 0x7 /* 14clk */
#define B3_Tcoh 0x1 /* 1clk */
#define B3_Tah 0x0 /* 0clk */
#define B3_Tacp 0x3 /* 6clk */
#define B3_PMC 0x0 /* normal */
#define B4_Tacs 0x0 /* 0clk */
#define B4_Tcos 0x0 /* 0clk */
#define B4_Tacc 0x7 /* 14clk */
#define B4_Tcoh 0x0 /* 0clk */
#define B4_Tah 0x0 /* 0clk */
#define B4_Tacp 0x0
#define B4_PMC 0x0 /* normal */
#define B5_Tacs 0x0 /* 0clk */
#define B5_Tcos 0x0 /* 0clk */
#define B5_Tacc 0x7 /* 14clk */
#define B5_Tcoh 0x0 /* 0clk */
#define B5_Tah 0x0 /* 0clk */
#define B5_Tacp 0x0
#define B5_PMC 0x0 /* normal */
#define B6_MT 0x3 /* SDRAM */
#define B6_Trcd 0x1 /* 3clk */
#define B6_SCAN 0x2 /* 10bit */
#define B7_SCAN 0x2 /* 10bit */
#define B7_MT 0x3 /* SDRAM */
#define B7_Trcd 0x1 /* 3clk */
/* REFRESH parameter */
#define REFEN 0x1 /* Refresh enable */
#define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh */
#define Trp 0x1 /* 3clk */
#define Trc 0x3 /* 7clk */
#define Tchr 0x2 /* 3clk */
//#define REFCNT 1113 /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */
#define REFCNT 997 /* period=17.5us, HCLK=60Mhz, (2048+1-15.6*60) */
/**************************************/
.globl lowlevel_init
lowlevel_init:
ldr r0, =SMRDATA
ldr r1, =BWSCON /* Bus Width Status Controller */
add r2, r0, #13*4
0:
ldr r3, [r0], #4
str r3, [r1], #4
cmp r2, r0
bne 0b
/* setup asynchronous bus mode */
mrc p15, 0, r1 ,c1 ,c0, 0
orr r1, r1, #0xc0000000
mcr p15, 0, r1, c1, c0, 0
/* everything is fine now */
mov pc, lr
.ltorg
/* the literal pools origin */
SMRDATA:
.word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
.word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
.word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
.word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
.word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
.word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
.word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
.word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
.word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
.word 0xb2
.word 0x30
.word 0x30

View File

@ -1,136 +0,0 @@
/*
* nand_read.c: Simple NAND read functions for booting from NAND
*
* This is used by cpu/arm920/start.S assembler code,
* and the board-specific linker script must make sure this
* file is linked within the first 4kB of NAND flash.
*
* Taken from GPLv2 licensed vivi bootloader,
* Copyright (C) 2002 MIZI Research, Inc.
*
* Author: Hwang, Chideok <hwang@mizi.com>
* Date : $Date: 2004/02/04 10:37:37 $
*
* u-boot integration and bad-block skipping (C) 2006 by OpenMoko, Inc.
* Author: Harald Welte <laforge@openmoko.org>
*/
/* NOTE this stuff runs in steppingstone context! */
/* the API refers to 512-byte blocks */
#include <qi.h>
#include "nand_read.h"
#define NAND_CMD_READ0 0
#define NAND_CMD_READOOB 0x50
#define __REGb(x) (*(volatile unsigned char *)(x))
#define __REGw(x) (*(volatile unsigned short *)(x))
#define __REGi(x) (*(volatile unsigned int *)(x))
#define NF_BASE 0x4e000000
#define NFCONF __REGi(NF_BASE + 0x0)
#define NFCMD __REGb(NF_BASE + 0x4)
#define NFADDR __REGb(NF_BASE + 0x8)
#define NFDATA __REGb(NF_BASE + 0xc)
#define NFSTAT __REGb(NF_BASE + 0x10)
#define NFSTAT_BUSY 1
#define nand_select() (NFCONF &= ~0x800)
#define nand_deselect() (NFCONF |= 0x800)
#define nand_clear_RnB() do {} while (0)
static inline void nand_wait(void)
{
int i;
while (!(NFSTAT & NFSTAT_BUSY))
for (i=0; i<10; i++);
}
/* configuration for 2410 with 512byte sized flash */
#define NAND_PAGE_SIZE 512
#define BAD_BLOCK_OFFSET 5
#define NAND_BLOCK_MASK (NAND_PAGE_SIZE - 1)
#define NAND_BLOCK_SIZE 0x4000
static int is_bad_block(unsigned long block_index)
{
unsigned char data;
nand_clear_RnB();
NFCMD = NAND_CMD_READOOB; /* 0x50 */
NFADDR = BAD_BLOCK_OFFSET & 0xf;
NFADDR = (block_index ) & 0xff;
NFADDR = (block_index >> 8 ) & 0xff;
NFADDR = (block_index >> 16) & 0xff;
nand_wait();
data = (NFDATA & 0xff);
if (data != 0xff)
return 1;
return 0;
}
static int nand_read_page_ll(unsigned char *buf, unsigned long block512)
{
unsigned int i;
nand_clear_RnB();
NFCMD = NAND_CMD_READ0;
/* Write Address */
NFADDR = 0;
NFADDR = (block512 ) & 0xff;
NFADDR = (block512 >> 8 ) & 0xff;
NFADDR = (block512 >> 16) & 0xff;
nand_wait();
for (i = 0; i < NAND_PAGE_SIZE; i++) {
*buf = (NFDATA & 0xff);
buf++;
}
return 1;
}
/* low level nand read function */
int nand_read_ll(unsigned char *buf, unsigned long start_block512, int blocks512)
{
int i, j;
int bad_count = 0;
/* chip Enable */
nand_select();
nand_clear_RnB();
for (i = 0; i < 10; i++)
;
while (blocks512 > 0) {
if (is_bad_block(start_block512) ||
is_bad_block(start_block512 + 1)) {
start_block512 += 1;
blocks512 += 1;
if (bad_count++ == 4)
return -1;
continue;
}
j = nand_read_page_ll(buf, start_block512);
start_block512 += j;
buf += j << 9;
blocks512 -= j;
}
/* chip Disable */
nand_deselect();
return 0;
}

View File

@ -1,22 +0,0 @@
/*
* nand_read.c: Simple NAND read functions for booting from NAND
*
* This is used by cpu/arm920/start.S assembler code,
* and the board-specific linker script must make sure this
* file is linked within the first 4kB of NAND flash.
*
* Taken from GPLv2 licensed vivi bootloader,
* Copyright (C) 2002 MIZI Research, Inc.
*
* Author: Hwang, Chideok <hwang@mizi.com>
* Date : $Date: 2004/02/04 10:37:37 $
*
* u-boot integration and bad-block skipping (C) 2006 by OpenMoko, Inc.
* Author: Harald Welte <laforge@openmoko.org>
*/
#ifndef __NAND_READ_H
#define __NAND_READ_H
int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size);
#endif /* __NAND_READ_H */

View File

@ -1,63 +0,0 @@
/*
* (C) Copyright 2002
* Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
/* this is intended to take the first 4KBytes of stuff initially.
* We have to make sure we have .rodata* in there for everything
* because we do not compile PIC.
*/
. = ALIGN(4);
.text :
{
src/cpu/s3c2410/start.o (.text .rodata* .data .bss)
src/cpu/s3c2410/lowlevel_init.o (.text .rodata* .data .bss)
src/cpu/s3c2410/start_qi.o (.text .rodata* .data .bss)
src/cpu/s3c2410/nand_read.o (.text .rodata* .data .bss)
src/cpu/s3c2410/serial-s3c24xx.o (.text .rodata* .data .bss)
src/memory-test.o (.text .rodata* .data .bss)
src/utils.o (.text .rodata* .data .bss)
src/ctype.o (.text .rodata* .data .bss)
* (.steppingstone)
}
. = ALIGN(4);
.everything_else ADDR (.text) + SIZEOF (.text) + 0x33000000 :
AT ( ADDR (.text) + SIZEOF (.text) ) { *(.text .rodata* .data) }
. = 0x33800000 ;
__bss_start = .;
.bss (NOLOAD) :
{
*(.bss)
}
_end = .;
}

View File

@ -1,579 +0,0 @@
/*
* qi s3c24xx SD card driver
* Author: Andy Green <andy@openmoko.com>
* based on ---->
*
* u-boot S3C2410 MMC/SD card driver
* (C) Copyright 2006 by OpenMoko, Inc.
* Author: Harald Welte <laforge@openmoko.org>
*
* based on u-boot pxa MMC driver and linux/drivers/mmc/s3c2410mci.c
* (C) 2005-2005 Thomas Kleffel
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <qi.h>
#include <mmc.h>
#include <s3c24xx-regs-sdi.h>
#include <string.h>
#define SDICON (*(u32 *)0x5a000000)
#define SDIPRE (*(u32 *)0x5a000004)
#define SDICARG (*(u32 *)0x5a000008)
#define SDICCON (*(u32 *)0x5a00000c)
#define SDICSTA (*(u32 *)0x5a000010)
#define SDIRSP0 (*(u32 *)0x5a000014)
#define SDIRSP1 (*(u32 *)0x5a000018)
#define SDIRSP2 (*(u32 *)0x5a00001c)
#define SDIRSP3 (*(u32 *)0x5a000020)
#define SDIDTIMER (*(u32 *)0x5a000024)
#define SDIBSIZE (*(u32 *)0x5a000028)
#define SDIDCON (*(u32 *)0x5a00002c)
#define SDIDCNT (*(u32 *)0x5a000030)
#define SDIDSTA (*(u32 *)0x5a000034)
#define SDIFSTA (*(u32 *)0x5a000038)
/* s3c2410 in GTA01 has these two last ones the other way around!!! */
#define SDIIMSK (*(u32 *)0x5a00003c)
#define SDIDAT (*(u32 *)0x5a000040)
#define SDIDAT2410 (*(u32 *)0x5a00003c)
#define SDIIMSK2410 (*(u32 *)0x5a000040)
#define CFG_MMC_BASE 0xff000000
int am_i_s3c2410(void)
{
return 1;
}
#define CONFIG_MMC_WIDE
#define MMC_BLOCK_SIZE 512
/*
* FIXME needs to read cid and csd info to determine block size
* and other parameters
*/
static u8 mmc_buf[MMC_BLOCK_SIZE];
static mmc_csd_t mmc_csd;
static int mmc_ready = 0;
static int wide = 0;
static int is_sdhc = 0;
#define CMD_F_RESP 0x01
#define CMD_F_RESP_LONG 0x02
static u32 *mmc_cmd(u16 cmd, u32 arg, u16 flags)
{
static u32 resp[5];
u32 ccon, csta;
u32 csta_rdy_bit = S3C2410_SDICMDSTAT_CMDSENT;
memset(resp, 0, sizeof(resp));
// debug("mmc_cmd CMD%d arg=0x%08x flags=%x\n", cmd, arg, flags);
SDICSTA = 0xffffffff;
SDIDSTA = 0xffffffff;
SDIFSTA = 0xffffffff;
SDICARG = arg;
ccon = cmd & S3C2410_SDICMDCON_INDEX;
ccon |= S3C2410_SDICMDCON_SENDERHOST|S3C2410_SDICMDCON_CMDSTART;
if (flags & CMD_F_RESP) {
ccon |= S3C2410_SDICMDCON_WAITRSP;
csta_rdy_bit = S3C2410_SDICMDSTAT_RSPFIN; /* 1 << 9 */
}
if (flags & CMD_F_RESP_LONG)
ccon |= S3C2410_SDICMDCON_LONGRSP;
SDICCON = ccon;
while (1) {
csta = SDICSTA;
if (csta & csta_rdy_bit)
break;
if (csta & S3C2410_SDICMDSTAT_CMDTIMEOUT) {
puts("===============> MMC CMD Timeout\n");
SDICSTA |= S3C2410_SDICMDSTAT_CMDTIMEOUT;
break;
}
}
// debug("final MMC CMD status 0x%x\n", csta);
SDICSTA |= csta_rdy_bit;
if (flags & CMD_F_RESP) {
resp[0] = SDIRSP0;
resp[1] = SDIRSP1;
resp[2] = SDIRSP2;
resp[3] = SDIRSP3;
}
return resp;
}
#define FIFO_FILL() ((SDIFSTA & S3C2410_SDIFSTA_COUNTMASK) >> 2)
static int mmc_block_read(u8 *dst, u32 src, u32 len)
{
u32 dcon, fifo;
u32 *dst_u32 = (u32 *)dst;
u32 *resp;
if (len == 0)
return 0;
// debug("mmc_block_rd dst %lx src %lx len %d\n", (u32)dst, src, len);
/* set block len */
resp = mmc_cmd(MMC_CMD_SET_BLOCKLEN, len, CMD_F_RESP);
SDIBSIZE = len;
//SDIPRE = 0xff;
/* setup data */
dcon = (len >> 9) & S3C2410_SDIDCON_BLKNUM;
dcon |= S3C2410_SDIDCON_BLOCKMODE;
dcon |= S3C2410_SDIDCON_RXAFTERCMD|S3C2410_SDIDCON_XFER_RXSTART;
if (wide)
dcon |= S3C2410_SDIDCON_WIDEBUS;
if (!am_i_s3c2410())
dcon |= S3C2440_SDIDCON_DS_WORD | S3C2440_SDIDCON_DATSTART;
SDIDCON = dcon;
/* send read command */
if (!is_sdhc)
resp = mmc_cmd(MMC_CMD_READ_BLOCK, src, CMD_F_RESP);
else
resp = mmc_cmd(MMC_CMD_READ_BLOCK, src / MMC_BLOCK_SIZE, CMD_F_RESP);
while (len > 0) {
u32 sdidsta = SDIDSTA;
fifo = FIFO_FILL();
if (sdidsta & (S3C2410_SDIDSTA_FIFOFAIL|
S3C2410_SDIDSTA_CRCFAIL|
S3C2410_SDIDSTA_RXCRCFAIL|
S3C2410_SDIDSTA_DATATIMEOUT)) {
puts("mmc_block_read: err SDIDSTA=0x");
print32(sdidsta);
puts("\n");
return -1;
}
if (am_i_s3c2410()) {
while (fifo--) {
//debug("dst_u32 = 0x%08x\n", dst_u32);
*(dst_u32++) = SDIDAT2410;
if (len >= 4)
len -= 4;
else {
len = 0;
break;
}
}
} else {
while (fifo--) {
//debug("dst_u32 = 0x%08x\n", dst_u32);
*(dst_u32++) = SDIDAT;
if (len >= 4)
len -= 4;
else {
len = 0;
break;
}
}
}
}
// debug("waiting for SDIDSTA (currently 0x%08x\n", SDIDSTA);
while (!(SDIDSTA & (1 << 4))) {}
// debug("done waiting for SDIDSTA (currently 0x%08x\n", SDIDSTA);
SDIDCON = 0;
if (!(SDIDSTA & S3C2410_SDIDSTA_XFERFINISH))
puts("mmc_block_read; transfer not finished!\n");
return 0;
}
static int mmc_block_write(u32 dst, u8 *src, int len)
{
puts("MMC block write not yet supported on S3C2410!\n");
return -1;
}
int s3c24xx_mmc_read(u32 src, u8 *dst, int size)
{
u32 end, part_start, part_end, part_len, aligned_start, aligned_end;
u32 mmc_block_size, mmc_block_address;
if (size == 0)
return 0;
if (!mmc_ready) {
puts("Please initialize the MMC first\n");
return -1;
}
mmc_block_size = MMC_BLOCK_SIZE;
mmc_block_address = ~(mmc_block_size - 1);
src -= CFG_MMC_BASE;
end = src + size;
part_start = ~mmc_block_address & src;
part_end = ~mmc_block_address & end;
aligned_start = mmc_block_address & src;
aligned_end = mmc_block_address & end;
/* all block aligned accesses */
// debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// src, (u32)dst, end, part_start, part_end, aligned_start, aligned_end);
if (part_start) {
part_len = mmc_block_size - part_start;
// debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// src, (u32)dst, end, part_start, part_end, aligned_start, aligned_end);
if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0)
return -1;
memcpy(dst, mmc_buf+part_start, part_len);
dst += part_len;
src += part_len;
}
// debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// src, (u32)dst, end, part_start, part_end, aligned_start, aligned_end);
for (; src < aligned_end; src += mmc_block_size, dst += mmc_block_size) {
// debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// src, (u32)dst, end, part_start, part_end, aligned_start, aligned_end);
if ((mmc_block_read((u8 *)(dst), src, mmc_block_size)) < 0)
return -1;
}
// debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// src, (u32)dst, end, part_start, part_end, aligned_start, aligned_end);
if (part_end && src < end) {
// debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// src, (u32)dst, end, part_start, part_end, aligned_start, aligned_end);
if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0)
return -1;
memcpy(dst, mmc_buf, part_end);
}
return 0;
}
int s3c24xx_mmc_write(u8 *src, u32 dst, int size)
{
u32 end, part_start, part_end, part_len, aligned_start, aligned_end;
u32 mmc_block_size, mmc_block_address;
if (size == 0)
return 0;
if (!mmc_ready) {
puts("Please initialize the MMC first\n");
return -1;
}
mmc_block_size = MMC_BLOCK_SIZE;
mmc_block_address = ~(mmc_block_size - 1);
dst -= CFG_MMC_BASE;
end = dst + size;
part_start = ~mmc_block_address & dst;
part_end = ~mmc_block_address & end;
aligned_start = mmc_block_address & dst;
aligned_end = mmc_block_address & end;
/* all block aligned accesses */
// debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// src, (u32)dst, end, part_start, part_end, aligned_start, aligned_end);
if (part_start) {
part_len = mmc_block_size - part_start;
// debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// (u32)src, dst, end, part_start, part_end, aligned_start, aligned_end);
if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0)
return -1;
memcpy(mmc_buf+part_start, src, part_len);
if ((mmc_block_write(aligned_start, mmc_buf, mmc_block_size)) < 0)
return -1;
dst += part_len;
src += part_len;
}
// debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// src, (u32)dst, end, part_start, part_end, aligned_start, aligned_end);
for (; dst < aligned_end; src += mmc_block_size, dst += mmc_block_size) {
// debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// src, (u32)dst, end, part_start, part_end, aligned_start, aligned_end);
if ((mmc_block_write(dst, (u8 *)src, mmc_block_size)) < 0)
return -1;
}
// debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// src, (u32)dst, end, part_start, part_end, aligned_start, aligned_end);
if (part_end && dst < end) {
// debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// src, (u32)dst, end, part_start, part_end, aligned_start, aligned_end);
if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0)
return -1;
memcpy(mmc_buf, src, part_end);
if ((mmc_block_write(aligned_end, mmc_buf, mmc_block_size)) < 0)
return -1;
}
return 0;
}
u32 s3c24xx_mmc_bread(int dev_num, u32 blknr, u32 blkcnt, void *dst)
{
int mmc_block_size = MMC_BLOCK_SIZE;
u32 src = blknr * mmc_block_size + CFG_MMC_BASE;
s3c24xx_mmc_read(src, dst, blkcnt*mmc_block_size);
return blkcnt;
}
/* MMC_DEFAULT_RCA should probably be just 1, but this may break other code
that expects it to be shifted. */
static u_int16_t rca = MMC_DEFAULT_RCA >> 16;
#if 0
static u32 mmc_size(const struct mmc_csd *csd)
{
u32 block_len, mult, blocknr;
block_len = csd->read_bl_len << 12;
mult = csd->c_size_mult1 << 8;
blocknr = (csd->c_size+1) * mult;
return blocknr * block_len;
}
#endif
struct sd_cid {
char pnm_0; /* product name */
char oid_1; /* OEM/application ID */
char oid_0;
uint8_t mid; /* manufacturer ID */
char pnm_4;
char pnm_3;
char pnm_2;
char pnm_1;
uint8_t psn_2; /* product serial number */
uint8_t psn_1;
uint8_t psn_0; /* MSB */
uint8_t prv; /* product revision */
uint8_t crc; /* CRC7 checksum, b0 is unused and set to 1 */
uint8_t mdt_1; /* manufacturing date, LSB, RRRRyyyy yyyymmmm */
uint8_t mdt_0; /* MSB */
uint8_t psn_3; /* LSB */
};
static void print_mmc_cid(mmc_cid_t *cid)
{
puts("MMC found. Card desciption is:\n");
puts("Manufacturer ID = ");
print8(cid->id[0]);
print8(cid->id[1]);
print8(cid->id[2]);
puts("\nHW/FW Revision = ");
print8(cid->hwrev);
print8(cid->fwrev);
cid->hwrev = cid->fwrev = 0; /* null terminate string */
puts("Product Name = ");
puts((char *)cid->name);
puts("\nSerial Number = ");
print8(cid->sn[0]);
print8(cid->sn[1]);
print8(cid->sn[2]);
puts("\nMonth = ");
printdec(cid->month);
puts("\nYear = ");
printdec(1997 + cid->year);
puts("\n");
}
static void print_sd_cid(const struct sd_cid *cid)
{
puts("Manufacturer: 0x");
print8(cid->mid);
puts("OEM \"");
this_board->putc(cid->oid_0);
this_board->putc(cid->oid_1);
puts("\"\nProduct name: \"");
this_board->putc(cid->pnm_0);
this_board->putc(cid->pnm_1);
this_board->putc(cid->pnm_2);
this_board->putc(cid->pnm_3);
this_board->putc(cid->pnm_4);
puts("\", revision ");
printdec(cid->prv >> 4);
puts(".");
printdec(cid->prv & 15);
puts("\nSerial number: ");
printdec(cid->psn_0 << 24 | cid->psn_1 << 16 | cid->psn_2 << 8 |
cid->psn_3);
puts("\nManufacturing date: ");
printdec(cid->mdt_1 & 15);
puts("/");
printdec(2000+((cid->mdt_0 & 15) << 4)+((cid->mdt_1 & 0xf0) >> 4));
puts("\nCRC: 0x");
print8(cid->crc >> 1);
puts(" b0 = ");
print8(cid->crc & 1);
puts("\n");
}
int s3c24xx_mmc_init(int verbose)
{
int retries, rc = -2;
int is_sd = 0;
u32 *resp;
u32 hcs = 0;
SDICON = S3C2410_SDICON_FIFORESET | S3C2410_SDICON_CLOCKTYPE;
SDIBSIZE = 512;
if (am_i_s3c2410()) {
/* S3C2410 has some bug that prevents reliable operation at higher speed */
//SDIPRE = 0x3e; /* SDCLK = PCLK/2 / (SDIPRE+1) = 396kHz */
SDIPRE = 0x02; /* 2410: SDCLK = PCLK/2 / (SDIPRE+1) = 11MHz */
SDIDTIMER = 0xffff;
SDIIMSK2410 = 0x0;
} else {
SDIPRE = 0x05; /* 2410: SDCLK = PCLK / (SDIPRE+1) = 11MHz */
SDIDTIMER = 0x7fffff;
SDIIMSK = 0x0;
}
udelay(1250000); /* FIXME: 74 SDCLK cycles */
mmc_csd.c_size = 0;
puts("Sending reset...\n");
/* reset */
retries = 10;
resp = mmc_cmd(MMC_CMD_RESET, 0, 0);
resp = mmc_cmd(8, 0x000001aa, CMD_F_RESP);
if ((resp[0] & 0xff) == 0xaa) {
puts("The card is either SD2.0 or SDHC\n");
hcs = 0x40000000;
}
puts("trying to detect SD Card...\n");
while (retries--) {
udelay(1000000);
resp = mmc_cmd(55, 0x00000000, CMD_F_RESP);
resp = mmc_cmd(41, hcs | 0x00300000, CMD_F_RESP);
if (resp[0] & (1 << 30))
is_sdhc = 1;
if (resp[0] & (1 << 31)) {
is_sd = 1;
break;
}
}
if (retries < 0 && !is_sd)
return -3;
/* try to get card id */
resp = mmc_cmd(MMC_CMD_ALL_SEND_CID, hcs, CMD_F_RESP|CMD_F_RESP_LONG);
if (resp) {
if (!is_sd) {
/* TODO configure mmc driver depending on card
attributes */
mmc_cid_t *cid = (mmc_cid_t *)resp;
if (verbose)
print_mmc_cid(cid);
#if 0
sprintf((char *) mmc_dev.vendor,
"Man %02x%02x%02x Snr %02x%02x%02x",
cid->id[0], cid->id[1], cid->id[2],
cid->sn[0], cid->sn[1], cid->sn[2]);
sprintf((char *) mmc_dev.product,"%s",cid->name);
sprintf((char *) mmc_dev.revision,"%x %x",
cid->hwrev, cid->fwrev);
#endif
}
else {
struct sd_cid *cid = (struct sd_cid *) resp;
if (verbose)
print_sd_cid(cid);
#if 0
sprintf((char *) mmc_dev.vendor,
"Man %02 OEM %c%c \"%c%c%c%c%c\"",
cid->mid, cid->oid_0, cid->oid_1,
cid->pnm_0, cid->pnm_1, cid->pnm_2, cid->pnm_3,
cid->pnm_4);
sprintf((char *) mmc_dev.product, "%d",
cid->psn_0 << 24 | cid->psn_1 << 16 |
cid->psn_2 << 8 | cid->psn_3);
sprintf((char *) mmc_dev.revision, "%d.%d",
cid->prv >> 4, cid->prv & 15);
#endif
}
/* MMC exists, get CSD too */
resp = mmc_cmd(MMC_CMD_SET_RCA, MMC_DEFAULT_RCA, CMD_F_RESP);
if (is_sd)
rca = resp[0] >> 16;
resp = mmc_cmd(MMC_CMD_SEND_CSD, rca<<16, CMD_F_RESP|CMD_F_RESP_LONG);
if (resp) {
mmc_csd_t *csd = (mmc_csd_t *)resp;
memcpy(&mmc_csd, csd, sizeof(csd));
rc = 0;
mmc_ready = 1;
#if 0
/* FIXME add verbose printout for csd */
printf("READ_BL_LEN=%u, C_SIZE_MULT=%u, C_SIZE=%u\n",
csd->read_bl_len, csd->c_size_mult1, csd->c_size);
printf("size = %u\n", mmc_size(csd));
#endif
}
}
resp = mmc_cmd(MMC_CMD_SELECT_CARD, rca<<16, CMD_F_RESP);
#ifdef CONFIG_MMC_WIDE
if (is_sd) {
resp = mmc_cmd(55, rca<<16, CMD_F_RESP);
resp = mmc_cmd(6, 0x02, CMD_F_RESP);
wide = 1;
}
#endif
return rc;
}

View File

@ -1,77 +0,0 @@
/*
* (C) Copyright 2007 OpenMoko, Inc.
* Author: xiangfu liu <xiangfu@openmoko.org>
*
* Configuation settings for the FIC Neo GTA02 Linux GSM phone
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <qi.h>
#include <serial-s3c24xx.h>
void serial_init_115200_s3c24xx(const int uart, const int pclk_MHz)
{
int div = (((54 * pclk_MHz) + 26) / 100) -1;
switch(uart)
{
case UART0:
rULCON0 = 0x3;
rUCON0 = 0x245;
rUFCON0 = 0x0;
rUMCON0 = 0x0;
rUBRDIV0 = div;
break;
case UART1:
rULCON1 = 0x3;
rUCON1 = 0x245;
rUFCON1 = 0x0;
rUMCON1 = 0x0;
rUBRDIV1 = div;
break;
case UART2:
rULCON2 = 0x3;
rUCON2 = 0x245;
rUFCON2 = 0x1;
rUBRDIV2 = div;
break;
default:
break;
}
}
/*
* Output a single byte to the serial port.
*/
void serial_putc_s3c24xx(const int uart, const char c)
{
switch(uart)
{
case UART0:
while ( !( rUTRSTAT0 & 0x2 ) );
WrUTXH0(c);
break;
case UART1:
while ( !( rUTRSTAT1 & 0x2 ) );
WrUTXH1(c);
break;
case UART2:
while ( !( rUTRSTAT2 & 0x2 ) );
WrUTXH2(c);
break;
default:
break;
}
}

View File

@ -1,304 +0,0 @@
/*
* (C) Copyright 2007 OpenMoko, Inc.
*
* Configuation settings for the OPENMOKO Neo GTA02 Linux GSM phone
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#define __ASM_MODE__
#define __ASSEMBLY__
#include <neo_gta01.h>
#define S3C2410_MISCCR_nEN_SCLK0 (1 << 17)
#define S3C2410_MISCCR_nEN_SCLK1 (1 << 18)
#define S3C2410_MISCCR_nEN_SCLKE (1 << 19)
.globl _start, processor_id, is_jtag
_start: b start_code
/* if we are injected by JTAG, the script sets _istag content to nonzero */
is_jtag:
.word 0
/* it's at a fixed address (+0x8) so we can breakpoint it in the JTAG script
* we need to go through this hassle because before this moment, SDRAM is not
* working so we can't prep it from JTAG
*/
_steppingstone_done:
ldr pc, _start_armboot
_start_armboot:
.word start_qi
_TEXT_BASE:
.word TEXT_BASE
/*
* These are defined in the board-specific linker script.
*/
.globl _bss_start
_bss_start:
.word __bss_start
.globl _bss_end
_bss_end:
.word _end
/*
* we have a stack in steppingstone because we can want to run full memory
* memory tests
*/
.fill 128
.globl _ss_stack
_ss_stack:
start_code:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0xd3
msr cpsr,r0
# define pWTCON 0x53000000
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]
/*
* mask all IRQs by setting all bits in the INTMR - default
*/
# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */
# define INTSUBMSK 0x4A00001C
# define INTSUBMSK_val 0x000007ff
mov r1, #0xffffffff
ldr r0, =INTMSK
str r1, [r0]
ldr r1, =INTSUBMSK_val
ldr r0, =INTSUBMSK
str r1, [r0]
/* Clock asynchronous mode */
mrc p15, 0, r1, c1, c0, 0
orr r1, r1, #0xc0000000
mcr p15, 0, r1, c1, c0, 0
#define LOCKTIME 0x4c000000
ldr r0, =LOCKTIME
mov r1, #0xffffff
str r1, [r0]
# define UPLLCON 0x4c000008
# define MPLLCON_val ((0x90 << 12) + (0x7 << 4) + 0x0) /* 202 MHz */
# define UPLLCON_val ((0x78 << 12) + (0x2 << 4) + 0x3)
ldr r0, =UPLLCON
ldr r1, =UPLLCON_val
str r1, [r0]
/* Page 7-19, seven nops between UPLL and MPLL */
nop
nop
nop
nop
nop
nop
nop
ldr r1, =MPLLCON_val
str r1, [r0, #-4] /* MPLLCON */
# define CLKDIVN 0x4C000014 /* clock divisor register */
# define CLKDIVN_val 3 /* FCLK:HCLK:PCLK = 1:2:4 */
/* FCLK:HCLK:PCLK = 1:3:6 */
ldr r0, =CLKDIVN
mov r1, #CLKDIVN_val
str r1, [r0]
/* enable only CPU peripheral block clocks we actually use */
ldr r0, =0x4c00000c /* clkcon */
ldr r1, =0x3f10 /* uart, pwm, gpio, nand, sdi clocks on */
str r1, [r0]
/* gpio UART0 init */
ldr r0, =0x56000070
ldr r1, =0x000000AA
str r1, [r0]
/* init uart0 */
ldr r0, =0x50000000
mov r1, #0x03
str r1, [r0]
ldr r1, =0x245
str r1, [r0, #0x04]
mov r1, #0x01
str r1, [r0, #0x08]
mov r1, #0x00
str r1, [r0, #0x0c]
mov r1, #0x1a
str r1, [r0, #0x28]
/* reset nand controller, or it is dead to us */
#define oNFCONF 0x00
#define oNFCMD 0x04
#define oNFSTAT 0x10
mov r1, #0x4E000000
ldr r2, =0xf842 @ initial value enable tacls=3,rph0=6,rph1=0
str r2, [r1, #oNFCONF]
ldr r2, [r1, #oNFCONF]
bic r2, r2, #0x800 @ enable chip
str r2, [r1, #oNFCONF]
mov r2, #0xff @ RESET command
strb r2, [r1, #oNFCMD]
mov r3, #0 @ wait
1: add r3, r3, #0x1
cmp r3, #0xa
blt 1b
2: ldr r2, [r1, #oNFSTAT] @ wait ready
tst r2, #0x1
beq 2b
ldr r2, [r1, #oNFCONF]
orr r2, r2, #0x800 @ disable chip
str r2, [r1, #oNFCONF]
/* take sdram out of power down */
ldr r0, =0x56000080 /* misccr */
ldr r1, [ r0 ]
bic r1, r1, #(S3C2410_MISCCR_nEN_SCLK0 | S3C2410_MISCCR_nEN_SCLK1 | S3C2410_MISCCR_nEN_SCLKE)
str r1, [ r0 ]
/* ensure signals stabalise */
mov r1, #128
3: subs r1, r1, #1
bpl 3b
bl cpu_init_crit
/* ensure some refresh has happened */
ldr r1, =0xfffff
4: subs r1, r1, #1
bpl 4b
/* capture full EINT situation into gstatus 4 */
ldr r0, =0x4A000000 /* SRCPND */
ldr r1, [ r0 ]
and r1, r1, #0xf
ldr r0, =0x560000BC /* gstatus4 */
str r1, [ r0 ]
ldr r0, =0x560000A8 /* EINTPEND */
ldr r1, [ r0 ]
ldr r0, =0xfff0
and r1, r1, r0
ldr r0, =0x560000BC /* gstatus4 */
ldr r0, [ r0 ]
orr r1, r1, r0
ldr r0, =0x560000BC /* gstatus4 */
str r1, [ r0 ]
/* test for resume */
ldr r1, =0x560000B4 /* gstatus2 */
ldr r0, [ r1 ]
tst r0, #0x02 /* is this resume from power down */
/* well, if it was, we are going to jump to
* whatever address we stashed in gstatus3,
* and gstatus4 will hold the wake interrupt
* source for the OS to look at
*/
ldrne pc, [r1, #4]
/* >> CFG_VIDEO_LOGO_MAX_SIZE */
#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
stack_setup:
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
sub sp, r0, #12 /* leave 3 words for abort-stack */
clear_bss:
ldr r0, _bss_start /* find start of bss segment */
ldr r1, _bss_end /* stop here */
mov r2, #0x00000000 /* clear */
clbss_l:
str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
ble clbss_l
/* we are going to jump into the C part of the init now */
spin:
b _steppingstone_done
/*
*************************************************************************
*
* CPU_init_critical registers
*
* setup important registers
* setup memory timing
*
*************************************************************************
*/
cpu_init_crit:
/*
* flush v4 I/D caches
*/
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
/*
* disable MMU stuff and caches
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
orr r0, r0, #0x00000002 @ set bit 2 (A) Align
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
mcr p15, 0, r0, c1, c0, 0
/*
* before relocating, we have to setup RAM timing
* because memory timing is board-dependend, you will
* find a lowlevel_init.S in your board directory.
*/
mov ip, lr
bl lowlevel_init
mov lr, ip
mov pc, lr

View File

@ -1,131 +0,0 @@
/*
* (C) Copyright 2007 OpenMoko, Inc.
* Author: xiangfu liu <xiangfu@openmoko.org>
* Andy Green <andy@openmoko.com>
*
* Configuation settings for the OPENMOKO Neo GTA02 Linux GSM phone
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/* NOTE this stuff runs in steppingstone context! */
#include <qi.h>
#include "nand_read.h"
#include <neo_gta01.h>
#define stringify2(s) stringify1(s)
#define stringify1(s) #s
extern void bootloader_second_phase(void);
const struct board_api *boards[] = {
&board_api_gta01,
NULL /* always last */
};
struct board_api const * this_board;
extern int is_jtag;
void start_qi(void)
{
int flag = 0;
int board = 0;
/*
* well, we can be running on this CPU two different ways.
*
* 1) We were copied into steppingstone and TEXT_BASE already
* by JTAG. We don't have to do anything else. JTAG script
* then sets data at address 0x4 to 0xffffffff as a signal we
* are running by JTAG.
*
* 2) We only got our first 4K into steppingstone, we need to copy
* the rest of ourselves into TEXT_BASE.
*
* So we do the copy out of NAND only if we see we did not come up
* under control of JTAG.
*/
if (!is_jtag)
/*
* We got the first 4KBytes of the bootloader pulled into the
* steppingstone SRAM for free. Now we pull the whole bootloader
* image into SDRAM.
*
* This code and the .S files are arranged by the linker script
* to expect to run from 0x0. But the linker script has told
* everything else to expect to run from 0x33000000+. That's
* why we are going to be able to copy this code and not have it
* crash when we run it from there.
*/
/* We randomly pull 32KBytes of bootloader */
if (nand_read_ll((u8 *)TEXT_BASE, 0, 32 * 1024 / 512) < 0)
goto unhappy;
/* ask all the boards we support in turn if they recognize this
* hardware we are running on, accept the first positive answer
*/
this_board = boards[board];
while (!flag && this_board) {
/* check if it is the right board... */
if (this_board->is_this_board()) {
flag = 1;
continue;
}
this_board = boards[board++];
}
/* No valid board found */
if (!this_board)
goto unhappy;
this_board->port_init();
set_putc_func(this_board->putc);
/* stick some hello messages on debug console */
puts("\n\n\nQi Bootloader "stringify2(QI_CPU)" "
stringify2(BUILD_HOST)" "
stringify2(BUILD_VERSION)" "
"\n");
puts(stringify2(BUILD_DATE) " Copyright (C) 2008 Openmoko, Inc.\n");
puts("\n Detected: ");
puts(this_board->name);
puts(", ");
puts((this_board->get_board_variant)()->name);
puts("\n");
/*
* jump to bootloader_second_phase() running from DRAM copy
*/
bootloader_second_phase();
unhappy:
while(1)
;
}

View File

@ -1,740 +0,0 @@
/*
* (C) Copyright 2007 OpenMoko, Inc.
* Author: Andy Green <andy@openmoko.com>
*
* (port_init_gta02 came out of Openmoko U-Boot)
*
* Configuation settings for the OPENMOKO Neo GTA02 Linux GSM phone
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
#include <qi.h>
#include <neo_gta02.h>
#include <serial-s3c24xx.h>
#include <ports-s3c24xx.h>
#include <i2c-bitbang-s3c24xx.h>
#include <pcf50633.h>
#include <glamo-init.h>
#include <string.h>
#include <ext2.h>
#define GTA02_DEBUG_UART 2
#define PCF50633_I2C_ADS 0x73
#define BOOST_TO_400MHZ 1
static int battery_condition_reasonable = 0;
extern unsigned long partition_offset_blocks;
extern unsigned long partition_length_blocks;
const struct board_api board_api_gta02;
struct nand_dynparts {
const char *name; /* name of this partition for Linux */
u32 good_length; /* bytes needed from good sectors in this partition */
u32 true_offset;
};
/*
* These are the NAND partitions U-Boot leaves in GTA02 NAND.
* The "dynparts" business means that in the case of bad blocks, all the
* following partitions move up accordingly to have the right amount of
* good blocks. To allow for this, the length of the last, largest
* partition is computed according to the bad blocks that went before.
*/
static struct nand_dynparts nand_dynparts[] = {
{ "qi", 0x40000 },
{ "depr-ub-env", 0x40000 },
{ "kernel", 0x800000 },
{ "depr", 0xa0000 },
{ "identity-ext2", 0x40000 },
{ "rootfs", 0 },
};
static u32 nand_extent_block512 = 256 * 1024 * 1024 / 512;
const struct pcf50633_init pcf50633_init[] = {
{ PCF50633_REG_OOCWAKE, 0xd3 }, /* wake from ONKEY,EXTON!,RTC,USB,ADP */
{ PCF50633_REG_OOCTIM1, 0xaa }, /* debounce 14ms everything */
{ PCF50633_REG_OOCTIM2, 0x4a },
{ PCF50633_REG_OOCMODE, 0x55 },
{ PCF50633_REG_OOCCTL, 0x47 },
{ PCF50633_REG_GPIO2CFG, 0x00 }, /* GSM_ON = 0 */
{ PCF50633_REG_GPIOCTL, 0x01 }, /* only GPIO1 is input */
{ PCF50633_REG_SVMCTL, 0x08 }, /* 3.10V SYS vth, 62ms filter */
{ PCF50633_REG_BVMCTL, 0x02 }, /* 2.80V BAT vth, 62ms filter */
{ PCF50633_REG_AUTOENA, 0x01 }, /* always on */
{ PCF50633_REG_DOWN1OUT, 0x1b }, /* 1.3V (0x1b * .025V + 0.625V) */
{ PCF50633_REG_DOWN1ENA, 0x02 }, /* enabled if GPIO1 = HIGH */
{ PCF50633_REG_HCLDOOUT, 21 }, /* 3.0V (21 * 0.1V + 0.9V) */
{ PCF50633_REG_HCLDOENA, 0x01 }, /* ON by default*/
{ PCF50633_REG_DOWN1OUT, 0x1b }, /* 1.3V (0x1b * .025V + 0.625V) */
{ PCF50633_REG_DOWN1ENA, 0x02 }, /* enabled if GPIO1 = HIGH */
{ PCF50633_REG_INT1M, 0x00 },
{ PCF50633_REG_INT2M, 0x00 },
{ PCF50633_REG_INT3M, 0x00 },
{ PCF50633_REG_INT4M, 0x00 },
{ PCF50633_REG_INT5M, 0x00 },
{ PCF50633_REG_MBCC2, 0x28 }, /* Vbatconid=2.7V, Vmax=4.20V */
{ PCF50633_REG_MBCC3, 0x19 }, /* 25/255 == 98mA pre-charge */
{ PCF50633_REG_MBCC4, 0xff }, /* 255/255 == 1A adapter fast */
{ PCF50633_REG_MBCC5, 0xff }, /* 255/255 == 1A usb fast */
{ PCF50633_REG_MBCC6, 0x01 }, /* cutoff current 2/32 * Ichg */
{ PCF50633_REG_MBCC7, 0x00 }, /* 1.6A max bat curr, USB 100mA */
{ PCF50633_REG_MBCC8, 0x00 },
{ PCF50633_REG_MBCC1, 0xff }, /* chgena */
{ PCF50633_REG_LDO1ENA, 2 }, /* accel enabled if GPIO1 = H */
{ PCF50633_REG_LDO2ENA, 2 }, /* codec enabled if GPIO1 = H */
{ PCF50633_REG_LDO4ENA, 0 }, /* bt off */
{ PCF50633_REG_LDO5ENA, 0 }, /* gps off */
{ PCF50633_REG_LDO6ENA, 2 }, /* lcm enabled if GPIO1 = H */
{ PCF50633_REG_BBCCTL, 0x19 }, /* 3V, 200uA, on */
{ PCF50633_REG_OOCSHDWN, 0x04 }, /* defeat 8s death from lowsys on A5 */
};
static const struct board_variant board_variants[] = {
[0] = {
.name = "A5 PCB",
.machine_revision = 0x350,
},
[1] = {
.name = "A6 PCB",
.machine_revision = 0x360,
},
[9] = { /* 01001 */
.name = "A7 PCB",
.machine_revision = 0x360, /* report as A6 */
},
};
void port_init_gta02(void)
{
unsigned int * MPLLCON = (unsigned int *)0x4c000004;
unsigned int * UPLLCON = (unsigned int *)0x4c000008;
unsigned int * CLKDIVN = (unsigned int *)0x4c000014;
int n;
u32 block512 = 0;
u32 start_block512 = 0;
const u32 GTA02_NAND_READBLOCK_SIZE = 2048;
extern int s3c2442_nand_is_bad_block(unsigned long block_index_512);
//CAUTION:Follow the configuration order for setting the ports.
// 1) setting value(GPnDAT)
// 2) setting control register (GPnCON)
// 3) configure pull-down resistor(GPnUP)
/* 32bit data bus configuration */
/*
* === PORT A GROUP
* Ports : GPA22 GPA21 GPA20 GPA19 GPA18 GPA17 GPA16 GPA15 GPA14 GPA13 GPA12
* Signal : nFCE nRSTOUT nFRE nFWE ALE CLE nGCS5 nGCS4 nGCS3 nGCS2 nGCS1
* Binary : 1 1 1 , 1 1 1 1 , 1 1 1 1
* Ports : GPA11 GPA10 GPA9 GPA8 GPA7 GPA6 GPA5 GPA4 GPA3 GPA2 GPA1 GPA0
* Signal : ADDR26 ADDR25 ADDR24 ADDR23 ADDR22 ADDR21 ADDR20 ADDR19 ADDR18 ADDR17 ADDR16 ADDR0
* Binary : 1 1 1 1 , 1 1 1 1 , 1 1 1 1
*/
rGPACON = 0x007E5FFF;
rGPADAT = 0x00000000;
/*
* ===* PORT B GROUP
* Ports : GPB10 GPB9 GPB8 GPB7 GPB6 GPB5 GPB4 GPB3 GPB2 GPB1 GPB0
* Signal : nXDREQ0 nXDACK0 nXDREQ1 nXDACK1 nSS_KBD nDIS_OFF L3CLOCK L3DATA L3MODE nIrDATXDEN Keyboard
* Setting: INPUT OUTPUT INPUT OUTPUT INPUT OUTPUT OUTPUT OUTPUT OUTPUT OUTPUT OUTPUT
* Binary : 00 , 01 00 , 01 00 , 01 01 , 01 01 , 01 01
*/
rGPBCON = 0x00155555;
rGPBUP = 0x000007FF;
rGPBDAT = 0x00000000;
/*
* === PORT C GROUP
* Ports : GPC15 GPC14 GPC13 GPC12 GPC11 GPC10 GPC9 GPC8 GPC7 GPC6 GPC5 GPC4 GPC3 GPC2 GPC1 GPC0
* Signal : VD7 VD6 VD5 VD4 VD3 VD2 VD1 VD0 LCDVF2 LCDVF1 LCDVF0 VM VFRAME VLINE VCLK LEND
* Binary : 10 10 , 10 10 , 10 10 , 10 10 , 10 10 , 10 10 , 10 10 , 10 10
*/
rGPCCON = 0x55555155;
rGPCUP = 0x0000FFFF & ~(1 << 5);
rGPCDAT = (1 << 13) | (1 << 15); /* index detect -> hi */
/*
* === PORT D GROUP
* Ports : GPD15 GPD14 GPD13 GPD12 GPD11 GPD10 GPD9 GPD8 GPD7 GPD6 GPD5 GPD4 GPD3 GPD2 GPD1 GPD0
* Signal : VD23 VD22 VD21 VD20 VD19 VD18 VD17 VD16 VD15 VD14 VD13 VD12 VD11 VD10 VD9 VD8
* Binary : 10 10 , 10 10 , 10 10 , 10 10 , 10 10 , 10 10 , 10 10 ,10 10
*/
rGPDCON = 0x55555555;
rGPDUP = 0x0000FFFF;
rGPDDAT = (1 << 0) | (1 << 3) | (1 << 4); /* index detect -> hi */
/*
* === PORT E GROUP
* Ports : GPE15 GPE14 GPE13 GPE12 GPE11 GPE10 GPE9 GPE8 GPE7 GPE6 GPE5 GPE4
* Signal : IICSDA IICSCL SPICLK SPIMOSI SPIMISO SDDATA3 SDDATA2 SDDATA1 SDDATA0 SDCMD SDCLK I2SSDO
* Binary : 10 10 , 10 10 , 10 10 , 10 10 , 10 10 , 10 10 ,
* -------------------------------------------------------------------------------------------------------
* Ports : GPE3 GPE2 GPE1 GPE0
* Signal : I2SSDI CDCLK I2SSCLK I2SLRCK
* Binary : 10 10 , 10 10
*/
rGPECON = 0xAAAAAAAA;
rGPEUP = 0x0000FFFF & ~(1 << 11);
rGPEDAT = 0x00000000;
/*
* === PORT F GROUP
* Ports : GPF7 GPF6 GPF5 GPF4 GPF3 GPF2 GPF1 GPF0
* Signal : nLED_8 nLED_4 nLED_2 nLED_1 nIRQ_PCMCIA EINT2 KBDINT EINT0
* Setting: Output Output Output Output EINT3 EINT2 EINT1 EINT0
* Binary : 01 01 , 01 01 , 10 10 , 10 10
*/
/* pulldown on GPF03: TP-4705+debug - debug conn will float */
rGPFCON = 0x00008AAA;
rGPFUP = 0x000000FF & ~(1 << 3);
rGPFDAT = 0x00000000;
/*
* === PORT G GROUP
* Ports : GPG15 GPG14 GPG13 GPG12 GPG11 GPG10 GPG9 GPG8 GPG7 GPG6
* Signal : nYPON YMON nXPON XMON EINT19 DMAMODE1 DMAMODE0 DMASTART KBDSPICLK KBDSPIMOSI
* Setting: nYPON YMON nXPON XMON EINT19 Output Output Output SPICLK1 SPIMOSI1
* Binary : 11 11 , 11 11 , 10 01 , 01 01 , 11 11
* -----------------------------------------------------------------------------------------
* Ports : GPG5 GPG4 GPG3 GPG2 GPG1 GPG0
* Signal : KBDSPIMISO LCD_PWREN EINT11 nSS_SPI IRQ_LAN IRQ_PCMCIA
* Setting: SPIMISO1 LCD_PWRDN EINT11 nSS0 EINT9 EINT8
* Binary : 11 11 , 10 11 , 10 10
*/
rGPGCON = 0x01AAFE79;
rGPGUP = 0x0000FFFF;
rGPGDAT = 0x00000000;
/*
* === PORT H GROUP
* Ports : GPH10 GPH9 GPH8 GPH7 GPH6 GPH5 GPH4 GPH3 GPH2 GPH1 GPH0
* Signal : CLKOUT1 CLKOUT0 UCLK RXD2 TXD2 RXD1 TXD1 RXD0 TXD0 nRTS0 nCTS0
* Binary : 10 , 10 10 , 11 11 , 10 10 , 10 10 , 10 10
*/
/*
* FIXME the following should be removed eventually and only the first stanza
* kept unconditionally. As it stands it allows TX and RTS to drive high into
* a powered-down GSM unit, which draws considerable fault current.
*
* However kernels earlier than andy-tracking from end Feb 2009 do not enforce
* the mode of these GPIOs, so Qi doing the correct thing here "breaks GSM"
* apparently for those users.
*
* Upgrading to current kernel will solve this, so after most distros are on
* 2.6.29-rc3 and later, we should return here and again disable driving out
* into unpowered GSM.
*/
#if 0
rGPHCON = 0x001AAA82; /* H1 and H2 are INPUTs to start with, not UART */
#else
rGPHCON = 0x001AAAAA; /* Wrong but compatible: H1 and H2 = UART */
#endif
/* pulldown on GPH08: UEXTCLK, just floats!
* pulldown GPH1 -- nCTS0 / RTS_MODEM -- floats when GSM off
* pulldown GPH3 -- RXD[0] / RX_MODEM -- floats when GSM off
*/
rGPHUP = 0x000007FF & ~(1 << 8) & ~(1 << 1) & ~(1 << 3);
rGPHDAT = 0x00000000;
/* pulldown on GPJ00: input, just floats! */
/* pulldown on GPJ07: WLAN module WLAN_GPIO0, no ext pull */
rGPJCON = 0x1551544;
rGPJUP = 0x1ffff & ~(1 << 0) & ~(1 << 7);
rGPJDAT = 0x00000100;
rGPJDAT |= (1 << 4) | (1 << 6);
/* Set GPJ4 to high (nGSM_EN) */
/* Set GPJ6 to high (nDL_GSM) */
rGPJDAT &= ~(1 << 5); /* Set GPJ5 to low 3D RST */
/* leaving Glamo forced to Reset# active here killed
* U-Boot when you touched the memory region
*/
rGPJDAT |= (1 << 5); /* Set GPJ5 to high 3D RST */
/*
* We have to talk to the PMU a little bit
*/
for (n = 0; n < ARRAY_SIZE(pcf50633_init); n++)
i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS,
pcf50633_init[n].index, pcf50633_init[n].value);
/* what does the battery monitoring unit say about the battery? */
battery_condition_reasonable = !(i2c_read_sync(&bb_s3c24xx,
PCF50633_I2C_ADS, PCF50633_REG_BVMCTL) & 1);
if (battery_condition_reasonable) {
/* change CPU clocking to 400MHz 1:4:8 */
/* clock divide 1:4:8 - do it first */
*CLKDIVN = 5;
/* configure UPLL */
*UPLLCON = ((88 << 12) + (4 << 4) + 2);
/* Magic delay: Page 7-19, seven nops between UPLL and MPLL */
asm __volatile__ (
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
);
/* configure MPLL */
*MPLLCON = ((42 << 12) + (1 << 4) + 0);
/* get debug UART working at 115kbps */
serial_init_115200_s3c24xx(GTA02_DEBUG_UART, 50 /* 50MHz */);
} else {
serial_init_115200_s3c24xx(GTA02_DEBUG_UART, 33 /* 33MHz */);
}
/* we're going to use Glamo for SD Card access, so we need to init the
* evil beast
*/
glamo_core_init();
/*
* dynparts computation
*/
n = 0;
while (n < ARRAY_SIZE(nand_dynparts)) {
if (nand_dynparts[n].good_length)
while (nand_dynparts[n].good_length) {
if (!s3c2442_nand_is_bad_block(block512))
nand_dynparts[n].good_length -=
GTA02_NAND_READBLOCK_SIZE;
block512 += GTA02_NAND_READBLOCK_SIZE / 512;
}
else
/*
* cannot afford to compute real size of last block
* set it to extent - end of last block
*/
block512 = nand_extent_block512;
/* stash a copy of real offset for each partition */
nand_dynparts[n].true_offset = start_block512;
/* and the accurate length */
nand_dynparts[n].good_length = block512 - start_block512;
start_block512 = block512;
n++;
}
/* fix up the true start of kernel partition */
((struct board_api *)&board_api_gta02)->kernel_source[3].
offset_blocks512_if_no_partition = nand_dynparts[2].true_offset;
}
/**
* returns PCB revision information in b9,b8 and b2,b1,b0
* Pre-GTA02 A6 returns 0x000
* GTA02 A6 returns 0x001
*/
int gta02_get_pcb_revision(void)
{
int n;
u32 u;
/* make C13 and C15 pulled-down inputs */
rGPCCON &= ~0xcc000000;
rGPCUP &= ~((1 << 13) | (1 << 15));
/* D0, D3 and D4 pulled-down inputs */
rGPDCON &= ~0x000003c3;
rGPDUP &= ~((1 << 0) | (1 << 3) | (1 << 4));
/* delay after changing pulldowns */
u = rGPCDAT;
u = rGPDDAT;
/* read the version info */
u = rGPCDAT;
n = (u >> (13 - 0)) & 0x001;
n |= (u >> (15 - 1)) & 0x002;
u = rGPDDAT;
n |= (u << (0 + 2)) & 0x004;
n |= (u << (3 - 3)) & 0x008;
n |= (u << (4 - 4)) & 0x010;
/*
* when not being interrogated, all of the revision GPIO
* are set to output HIGH without pulldown so no current flows
* if they are NC or pulled up.
*/
/* make C13 and C15 high ouputs with no pulldowns */
rGPCCON |= 0x44000000;
rGPCUP |= (1 << 13) | (1 << 15);
rGPCDAT |= (1 << 13) | (1 << 15);
/* D0, D3 and D4 high ouputs with no pulldowns */
rGPDCON |= 0x00000141;
rGPDUP |= (1 << 0) | (1 << 3) | (1 << 4);
rGPDDAT |= (1 << 0) | (1 << 3) | (1 << 4);
n &= 1;
return n;
}
int sd_card_init_gta02(void)
{
extern int mmc_init(int verbose);
return mmc_init(1);
}
int sd_card_block_read_gta02(unsigned char * buf, unsigned long start512,
int blocks512)
{
unsigned long mmc_bread(int dev_num, unsigned long blknr, unsigned long blkcnt,
void *dst);
return mmc_bread(0, start512, blocks512, buf);
}
/* return nonzero if we believe we run on GTA02 */
int is_this_board_gta02(void)
{
/* look for GTA02 NOR */
*(volatile unsigned short *)(0x18000000) = 0x98;
return !!(*(volatile unsigned short *)(0x18000000) == 0x0020);
}
const struct board_variant const * get_board_variant_gta02(void)
{
int rev = gta02_get_pcb_revision() & 0x1f;
if (!board_variants[rev].name)
return &board_variants[1]; /* A6 */
return &board_variants[rev];
}
static __attribute__ (( section (".steppingstone") )) void putc_gta02(char c)
{
serial_putc_s3c24xx(GTA02_DEBUG_UART, c);
}
static void close_gta02(void)
{
/* explicitly clear any pending 8s timeout */
i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_OOCSHDWN, 0x04);
/* clear any pending timeouts by reading interrupts */
i2c_read_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_INT1);
i2c_read_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_INT2);
i2c_read_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_INT3);
i2c_read_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_INT4);
i2c_read_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_INT5);
/* set I2C GPIO back to peripheral unit */
(bb_s3c24xx.close)();
/* aux back to being EINT */
rGPFCON = 0x0000AAAA;
}
/* Here we will care only about AUX button as polling for PWR button
* through i2c slows down the boot */
static u8 get_ui_keys_gta02(void)
{
u8 keys;
u8 ret = 0;
static u8 old_keys = 0; /* previous state for debounce */
static u8 older_keys = 0; /* previous debounced output for edge detect */
/* GPF6 is AUX on GTA02, map to UI_ACTION_SKIPKERNEL, down = 1 */
keys = !!(rGPFDAT & (1 << 6));
/* edge action */
if ((old_keys & 1) && !(older_keys & 1))
ret |= UI_ACTION_SKIPKERNEL;
older_keys = old_keys;
old_keys = keys;
return ret;
}
static u8 get_ui_debug_gta02(void)
{
/* PWR button state can be seen in OOCSTAT b0, down = 0, map to UI_ACTION_ADD_DEBUG */
return !(i2c_read_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_OOCSTAT) & 1);
}
static void set_ui_indication_gta02(enum ui_indication ui_indication)
{
switch (ui_indication) {
case UI_IND_UPDATE_ONLY:
break;
case UI_IND_MOUNT_PART:
case UI_IND_KERNEL_PULL_OK:
case UI_IND_INITRAMFS_PULL_OK:
if (battery_condition_reasonable)
rGPBDAT |= 4;
break;
case UI_IND_KERNEL_PULL_FAIL:
case UI_IND_SKIPPING:
case UI_IND_INITRAMFS_PULL_FAIL:
case UI_IND_MOUNT_FAIL:
rGPBDAT &= ~4;
if (battery_condition_reasonable) {
rGPBDAT |= 8;
udelay(2000000);
rGPBDAT &= ~8;
udelay(200000);
}
break;
case UI_IND_KERNEL_START:
case UI_IND_MEM_TEST:
case UI_IND_KERNEL_PULL:
case UI_IND_INITRAMFS_PULL:
rGPBDAT &= ~4;
break;
}
}
void post_serial_init_gta02(void)
{
if (battery_condition_reasonable)
puts("Battery condition reasonable\n");
else
puts("BATTERY CONDITION LOW\n");
}
/*
* Increment a hexadecimal digit represented by a char and
* return 1 if an overflow occured.
*/
static char inc_hexchar(char * p)
{
if (*p == '9')
*p = 'A';
else if (*p != 'F')
(*p)++;
else {
*p = '0';
return 1;
}
return 0;
}
/*
* create and append device-specific Linux kernel commandline
*
* This takes care of legacy dyanmic partition sizing and USB Ethernet
* MAC address identity information.
*/
char * append_device_specific_cmdline_gta02(char * cmdline)
{
int n = 0;
int i;
int len;
static char mac[64];
struct kernel_source const * real_kernel = this_kernel;
/*
* dynparts computation
*/
cmdline += strlen(strcpy(cmdline,
" mtdparts=physmap-flash:-(nor);neo1973-nand:"));
while (n < ARRAY_SIZE(nand_dynparts)) {
*cmdline++ = '0';
*cmdline++ = 'x';
set32(cmdline, nand_dynparts[n].good_length * 512);
cmdline += 8;
*cmdline++ = '(';
cmdline += strlen(strcpy(cmdline, nand_dynparts[n].name));
*cmdline++ = ')';
if (++n == ARRAY_SIZE(nand_dynparts))
*cmdline++ = ' ';
else
*cmdline++ = ',';
}
*cmdline = '\0';
/*
* Identity
*/
/* position ourselves at true start of GTA02 identity partition */
partition_offset_blocks = nand_dynparts[4].true_offset;
partition_length_blocks = 0x40000 / 512;
/*
* lie that we are in NAND context... GTA02 specific
* all filesystem access is completed before we are called
*/
this_kernel = &board_api_gta02.kernel_source[3];
if (!ext2fs_mount()) {
puts("Unable to mount ext2 filesystem\n");
goto bail;
}
len = ext2fs_open("usb");
if (len < 0) {
puts(" Open failed\n");
goto bail;
}
n = ext2fs_read(mac, sizeof(mac));
if (n < 0) {
puts(" Read failed\n");
goto bail;
}
mac[len] = '\0';
cmdline += strlen(strcpy(cmdline, " g_ether.dev_addr="));
cmdline += strlen(strcpy(cmdline, &mac[2]));
for (i = 0; i != 10; i++) {
if ((i % 3) == 2)
continue;
if (!inc_hexchar(mac + 18 - i))
break; /* Carry not needed. */
}
cmdline += strlen(strcpy(cmdline, " g_ether.host_addr="));
cmdline += strlen(strcpy(cmdline, &mac[2]));
*cmdline++ = ' ' ;
bail:
this_kernel = real_kernel;
*cmdline = '\0';
return cmdline;
}
/*
* our API for bootloader on this machine
*/
const struct board_api board_api_gta02 = {
.name = "Freerunner / GTA02",
.linux_machine_id = 1304,
.linux_mem_start = 0x30000000,
.linux_mem_size = (128 * 1024 * 1024),
.linux_tag_placement = 0x30000000 + 0x100,
.get_board_variant = get_board_variant_gta02,
.is_this_board = is_this_board_gta02,
.port_init = port_init_gta02,
.post_serial_init = post_serial_init_gta02,
.append_device_specific_cmdline = append_device_specific_cmdline_gta02,
.putc = putc_gta02,
.close = close_gta02,
.get_ui_keys = get_ui_keys_gta02,
.get_ui_debug = get_ui_debug_gta02,
.set_ui_indication = set_ui_indication_gta02,
.commandline_board = "loglevel=4 "
"console=tty0 "
"console=ttySAC2,115200 "
"init=/sbin/init "
"ro ",
.commandline_board_debug = " loglevel=8",
.noboot = "boot/noboot-GTA02",
.append = "boot/append-GTA02",
/* these are the ways we could boot GTA02 in the order to try */
.kernel_source = {
[0] = {
.name = "SD Card EXT2 P1 Kernel",
.block_init = sd_card_init_gta02,
.block_read = sd_card_block_read_gta02,
.partition_index = 1,
.filesystem = FS_EXT2,
.filepath = "boot/uImage-GTA02.bin",
.commandline_append = " root=/dev/mmcblk0p1 rootdelay=1 ",
},
[1] = {
.name = "SD Card EXT2 P2 Kernel",
.block_init = sd_card_init_gta02,
.block_read = sd_card_block_read_gta02,
.partition_index = 2,
.filesystem = FS_EXT2,
.filepath = "boot/uImage-GTA02.bin",
.commandline_append = " root=/dev/mmcblk0p2 rootdelay=1 ",
},
[2] = {
.name = "SD Card EXT2 P3 Kernel",
.block_init = sd_card_init_gta02,
.block_read = sd_card_block_read_gta02,
.partition_index = 3,
.filesystem = FS_EXT2,
.filepath = "boot/uImage-GTA02.bin",
.commandline_append = " root=/dev/mmcblk0p3 rootdelay=1 ",
},
[3] = {
.name = "NAND Kernel",
.block_read = nand_read_ll,
/* NOTE offset below is replaced at runtime */
.offset_blocks512_if_no_partition = 0x80000 / 512,
.filesystem = FS_RAW,
.commandline_append = " rootfstype=jffs2 "
"root=/dev/mtdblock6 ",
},
},
};

View File

@ -1,68 +0,0 @@
/*
* (C) Copyright 2007 OpenMoko, Inc.
* Author: Andy Green <andy@openmoko.com>
*
* s3c24xx-specific i2c used by, eg, GTA02
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
#include <qi.h>
#include <i2c-bitbang.h>
#include <ports-s3c24xx.h>
static char i2c_read_sda_s3c24xx(void)
{
return (rGPEDAT & 0x8000) != 0;
}
static void i2c_set_s3c24xx(char clock, char data)
{
if (clock) /* SCL <- input */
rGPECON = (rGPECON & ~0x30000000);
else { /* SCL <- output 0 */
rGPEDAT = (rGPEDAT & ~0x4000);
rGPECON = (rGPECON & ~0x30000000) | 0x10000000;
}
if (data) /* SDA <- input */
rGPECON = (rGPECON & ~0xc0000000);
else { /* SDA <- output 0 */
rGPEDAT = (rGPEDAT & ~0x8000);
rGPECON = (rGPECON & ~0xc0000000) | 0x40000000;
}
}
static void i2c_close_s3c24xx(void)
{
/* set back to hardware I2C ready for Linux */
rGPECON = (rGPECON & ~0xf0000000) | 0xa0000000;
}
static void i2c_spin_s3c24xx(void)
{
int n;
for (n = 0; n < 1000; n++)
rGPJDAT |= (1 << 5);
}
struct i2c_bitbang bb_s3c24xx = {
.read_sda = i2c_read_sda_s3c24xx,
.set = i2c_set_s3c24xx,
.spin = i2c_spin_s3c24xx,
.close = i2c_close_s3c24xx,
};

View File

@ -1,162 +0,0 @@
/*
* Memory Setup stuff - taken from blob memsetup.S
*
* Modified for the FIC Neo1973 GTA01 by Harald Welte <laforge@openmoko.org>
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/* NOTE this stuff runs in steppingstone context! */
/*
* #include <config.h>
* #include <version.h>
*/
#define __ASM_MODE__
#include <neo_gta02.h>
/*
*
* Taken from linux/arch/arm/boot/compressed/head-s3c2410.S
*
* Copyright (C) 2002 Samsung Electronics SW.LEE <hitchcar@sec.samsung.com>
*
*/
#define BWSCON 0x48000000
/* BWSCON */
#define DW8 (0x0)
#define DW16 (0x1)
#define DW32 (0x2)
#define WAIT (0x1<<2)
#define UBLB (0x1<<3)
#define B1_BWSCON (DW16 + WAIT + UBLB)
#define B2_BWSCON (DW16)
#define B3_BWSCON (DW16 + WAIT + UBLB)
#define B4_BWSCON (DW16)
#define B5_BWSCON (DW16)
#define B6_BWSCON (DW32)
#define B7_BWSCON (DW32)
/* BANK0CON */
#define B0_Tacs 0x0 /* 0clk */
#define B0_Tcos 0x0 /* 0clk */
#define B0_Tacc 0x7 /* 14clk */
#define B0_Tcoh 0x0 /* 0clk */
#define B0_Tah 0x0 /* 0clk */
#define B0_Tacp 0x0
#define B0_PMC 0x0 /* normal */
/* BANK1CON: Smedia Glamo 3362 (on GTA02) */
#define B1_Tacs 0x0 /* 0clk */
#define B1_Tcos 0x3 /* 4clk */
#define B1_Tacc 0x3 /* 4clk */
#define B1_Tcoh 0x3 /* 4clk */
#define B1_Tah 0x0 /* 0clk */
#define B1_Tacp 0x0
#define B1_PMC 0x0
#define B2_Tacs 0x0
#define B2_Tcos 0x0
#define B2_Tacc 0x7
#define B2_Tcoh 0x0
#define B2_Tah 0x0
#define B2_Tacp 0x0
#define B2_PMC 0x0
#define B3_Tacs 0x0 /* 0clk */
#define B3_Tcos 0x3 /* 4clk */
#define B3_Tacc 0x7 /* 14clk */
#define B3_Tcoh 0x1 /* 1clk */
#define B3_Tah 0x0 /* 0clk */
#define B3_Tacp 0x3 /* 6clk */
#define B3_PMC 0x0 /* normal */
#define B4_Tacs 0x0 /* 0clk */
#define B4_Tcos 0x0 /* 0clk */
#define B4_Tacc 0x7 /* 14clk */
#define B4_Tcoh 0x0 /* 0clk */
#define B4_Tah 0x0 /* 0clk */
#define B4_Tacp 0x0
#define B4_PMC 0x0 /* normal */
#define B5_Tacs 0x0 /* 0clk */
#define B5_Tcos 0x0 /* 0clk */
#define B5_Tacc 0x7 /* 14clk */
#define B5_Tcoh 0x0 /* 0clk */
#define B5_Tah 0x0 /* 0clk */
#define B5_Tacp 0x0
#define B5_PMC 0x0 /* normal */
#define B6_MT 0x3 /* SDRAM */
#define B6_Trcd 0x1 /* 3clk */
#define B6_SCAN 0x1 /* 9bit */
#define B7_SCAN 0x1 /* 9bit */
#define B7_MT 0x3 /* SDRAM */
#define B7_Trcd 0x1 /* 3clk */
/* REFRESH parameter */
#define REFEN 0x1 /* Refresh enable */
#define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh */
#define Trp 0x1 /* 3clk */
#define Trc 0x3 /* 7clk */
#define Tchr 0x2 /* 3clk */
//#define REFCNT 1113 /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */
#define REFCNT 997 /* period=17.5us, HCLK=60Mhz, (2048+1-15.6*60) */
/**************************************/
.globl lowlevel_init
lowlevel_init:
ldr r0, =SMRDATA
ldr r1, =BWSCON /* Bus Width Status Controller */
add r2, r0, #13*4
0:
ldr r3, [r0], #4
str r3, [r1], #4
cmp r2, r0
bne 0b
/* setup asynchronous bus mode */
mrc p15, 0, r1 ,c1 ,c0, 0
orr r1, r1, #0xc0000000
mcr p15, 0, r1, c1, c0, 0
/* everything is fine now */
mov pc, lr
.ltorg
/* the literal pools origin */
SMRDATA:
.word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
.word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
.word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
.word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
.word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
.word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
.word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
.word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
.word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
.word 0xb1
.word 0x30
.word 0x30

View File

@ -1,156 +0,0 @@
/*
* nand_read.c: Simple NAND read functions for booting from NAND
*
* This is used by cpu/arm920/start.S assembler code,
* and the board-specific linker script must make sure this
* file is linked within the first 4kB of NAND flash.
*
* Taken from GPLv2 licensed vivi bootloader,
* Copyright (C) 2002 MIZI Research, Inc.
*
* Author: Hwang, Chideok <hwang@mizi.com>
* Date : $Date: 2004/02/04 10:37:37 $
*
* u-boot integration and bad-block skipping (C) 2006 by OpenMoko, Inc.
* Author: Harald Welte <laforge@openmoko.org>
*/
/* NOTE this stuff runs in steppingstone context! */
/* the API refers to 512-byte blocks */
#include <qi.h>
#include "nand_read.h"
#define NAND_CMD_READ0 0
#define NAND_CMD_READSTART 0x30
#define __REGb(x) (*(volatile unsigned char *)(x))
#define __REGw(x) (*(volatile unsigned short *)(x))
#define __REGi(x) (*(volatile unsigned int *)(x))
#define NF_BASE 0x4e000000
#define NFCONF __REGi(NF_BASE + 0x0)
#define NFCONT __REGi(NF_BASE + 0x4)
#define NFCMD __REGb(NF_BASE + 0x8)
#define NFADDR __REGb(NF_BASE + 0xc)
#define NFDATA __REGb(NF_BASE + 0x10)
#define NFDATA16 __REGw(NF_BASE + 0x10)
#define NFSTAT __REGb(NF_BASE + 0x20)
#define NFSTAT_BUSY 1
#define nand_select() (NFCONT &= ~(1 << 1))
#define nand_deselect() (NFCONT |= (1 << 1))
#define nand_clear_RnB() (NFSTAT |= (1 << 2))
static inline void nand_wait(void)
{
int i;
while (!(NFSTAT & NFSTAT_BUSY))
for (i=0; i<10; i++);
}
/* configuration for 2440 with 2048byte sized flash */
#define NAND_5_ADDR_CYCLE
#define NAND_PAGE_SIZE 2048
#define BAD_BLOCK_OFFSET NAND_PAGE_SIZE
#define NAND_BLOCK_MASK (NAND_PAGE_SIZE - 1)
#define NAND_BLOCK_SIZE (NAND_PAGE_SIZE * 64)
int s3c2442_nand_is_bad_block(unsigned long block_index)
{
unsigned char data;
unsigned long page_num;
nand_select();
nand_clear_RnB();
page_num = block_index >> 2; /* addr / 2048 */
NFCMD = NAND_CMD_READ0;
NFADDR = BAD_BLOCK_OFFSET & 0xff;
NFADDR = (BAD_BLOCK_OFFSET >> 8) & 0xff;
NFADDR = page_num & 0xff;
NFADDR = (page_num >> 8) & 0xff;
NFADDR = (page_num >> 16) & 0xff;
NFCMD = NAND_CMD_READSTART;
nand_wait();
data = (NFDATA & 0xff);
if (data != 0xff)
return 1;
return 0;
}
static int nand_read_page_ll(unsigned char *buf, unsigned long block512, int blocks512)
{
unsigned short *ptr16 = (unsigned short *)buf;
unsigned int i, page_num;
unsigned int block_amount;
int blocks_possible = (3 - (block512 & 3)) + 1;
if (blocks512 > blocks_possible)
blocks512 = blocks_possible;
block_amount = (NAND_PAGE_SIZE / 4 / 2) * blocks512;
nand_clear_RnB();
NFCMD = NAND_CMD_READ0;
page_num = block512 >> 2; /* 512 block -> 2048 block */
/* Write Address */
NFADDR = 0;
NFADDR = (block512 & 3) << 1; /* which 512 block in 2048 */
NFADDR = page_num & 0xff;
NFADDR = (page_num >> 8) & 0xff;
NFADDR = (page_num >> 16) & 0xff;
NFCMD = NAND_CMD_READSTART;
nand_wait();
for (i = 0; i < block_amount; i++)
*ptr16++ = NFDATA16;
return blocks512;
}
/* low level nand read function */
int nand_read_ll(unsigned char *buf, unsigned long start_block512,
int blocks512)
{
int i, j;
/* chip Enable */
nand_select();
nand_clear_RnB();
for (i = 0; i < 10; i++)
;
while (blocks512 > 0) {
if (s3c2442_nand_is_bad_block(start_block512)) {
start_block512 += 4;
if (start_block512 >> 2 > BAD_BLOCK_OFFSET)
/* end of NAND */
return -1;
continue;
}
j = nand_read_page_ll(buf, start_block512, blocks512);
start_block512 += j;
buf += j << 9;
blocks512 -= j;
if (this_board->get_ui_keys)
if ((this_board->get_ui_keys)() & UI_ACTION_SKIPKERNEL) {
puts(" ** skipping \n");
return -3;
}
}
/* chip Disable */
nand_deselect();
return 0;
}

View File

@ -1,22 +0,0 @@
/*
* nand_read.c: Simple NAND read functions for booting from NAND
*
* This is used by cpu/arm920/start.S assembler code,
* and the board-specific linker script must make sure this
* file is linked within the first 4kB of NAND flash.
*
* Taken from GPLv2 licensed vivi bootloader,
* Copyright (C) 2002 MIZI Research, Inc.
*
* Author: Hwang, Chideok <hwang@mizi.com>
* Date : $Date: 2004/02/04 10:37:37 $
*
* u-boot integration and bad-block skipping (C) 2006 by OpenMoko, Inc.
* Author: Harald Welte <laforge@openmoko.org>
*/
#ifndef __NAND_READ_H
#define __NAND_READ_H
int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size);
#endif /* __NAND_READ_H */

View File

@ -1,65 +0,0 @@
/*
* (C) Copyright 2002
* Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
__steppingstone_always = 0x40000000;
__qi_sdram_copy = 0x33000000;
. = __steppingstone_always;
/* this is intended to take the first 4KBytes of stuff initially.
* We have to make sure we have .rodata* in there for everything
* because we do not compile PIC.
*/
.text __steppingstone_always : AT (0x0)
{
src/cpu/s3c2442/start.o (.text .rodata* .data .bss)
src/cpu/s3c2442/lowlevel_init.o (.text .rodata* .data .bss)
src/cpu/s3c2442/start_qi.o (.text .rodata* .data .bss)
src/cpu/s3c2442/nand_read.o (.text .rodata* .data .bss)
src/cpu/s3c2442/serial-s3c24xx.o (.text .rodata* .data .bss)
src/memory-test.o (.text .rodata* .data .bss)
src/utils.o (.text .rodata* .data .bss)
src/ctype.o (.text .rodata* .data .bss)
* (.steppingstone)
}
. = ALIGN(4);
.everything_else ADDR (.text) - __steppingstone_always + SIZEOF (.text) + __qi_sdram_copy :
AT ( ADDR (.text) - __steppingstone_always + SIZEOF (.text) ) { *(.text .rodata* .data) }
. = __qi_sdram_copy + 0x800000 ;
__bss_start = .;
.bss (NOLOAD) :
{
*(.bss)
}
_end = .;
}

View File

@ -1,569 +0,0 @@
/*
* qi s3c24xx SD card driver
* Author: Andy Green <andy@openmoko.com>
* based on ---->
*
* u-boot S3C2410 MMC/SD card driver
* (C) Copyright 2006 by OpenMoko, Inc.
* Author: Harald Welte <laforge@openmoko.org>
*
* based on u-boot pxa MMC driver and linux/drivers/mmc/s3c2410mci.c
* (C) 2005-2005 Thomas Kleffel
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <qi.h>
#include <mmc.h>
#include <s3c24xx-regs-sdi.h>
#include <string.h>
#define SDICON (*(u32 *)0x5a000000)
#define SDIPRE (*(u32 *)0x5a000004)
#define SDICARG (*(u32 *)0x5a000008)
#define SDICCON (*(u32 *)0x5a00000c)
#define SDICSTA (*(u32 *)0x5a000010)
#define SDIRSP0 (*(u32 *)0x5a000014)
#define SDIRSP1 (*(u32 *)0x5a000018)
#define SDIRSP2 (*(u32 *)0x5a00001c)
#define SDIRSP3 (*(u32 *)0x5a000020)
#define SDIDTIMER (*(u32 *)0x5a000024)
#define SDIBSIZE (*(u32 *)0x5a000028)
#define SDIDCON (*(u32 *)0x5a00002c)
#define SDIDCNT (*(u32 *)0x5a000030)
#define SDIDSTA (*(u32 *)0x5a000034)
#define SDIFSTA (*(u32 *)0x5a000038)
/* s3c2410 in GTA01 has these two last ones the other way around!!! */
#define SDIIMSK (*(u32 *)0x5a00003c)
#define SDIDAT (*(u32 *)0x5a000040)
#define SDIDAT2410 (*(u32 *)0x5a00003c)
#define SDIIMSK2410 (*(u32 *)0x5a000040)
#define CFG_MMC_BASE 0xff000000
/* FIXME: anyone who wants to use this on GTA01 / s3c2410 need to
* have this return 1 on that CPU
*/
int am_i_s3c2410(void)
{
return 0;
}
#define CONFIG_MMC_WIDE
#define MMC_BLOCK_SIZE 512
/*
* FIXME needs to read cid and csd info to determine block size
* and other parameters
*/
static u8 mmc_buf[MMC_BLOCK_SIZE];
static mmc_csd_t mmc_csd;
static int mmc_ready = 0;
static int wide = 0;
#define CMD_F_RESP 0x01
#define CMD_F_RESP_LONG 0x02
static u32 *mmc_cmd(u16 cmd, u32 arg, u16 flags)
{
static u32 resp[5];
u32 ccon, csta;
u32 csta_rdy_bit = S3C2410_SDICMDSTAT_CMDSENT;
memset(resp, 0, sizeof(resp));
// debug("mmc_cmd CMD%d arg=0x%08x flags=%x\n", cmd, arg, flags);
SDICSTA = 0xffffffff;
SDIDSTA = 0xffffffff;
SDIFSTA = 0xffffffff;
SDICARG = arg;
ccon = cmd & S3C2410_SDICMDCON_INDEX;
ccon |= S3C2410_SDICMDCON_SENDERHOST|S3C2410_SDICMDCON_CMDSTART;
if (flags & CMD_F_RESP) {
ccon |= S3C2410_SDICMDCON_WAITRSP;
csta_rdy_bit = S3C2410_SDICMDSTAT_RSPFIN; /* 1 << 9 */
}
if (flags & CMD_F_RESP_LONG)
ccon |= S3C2410_SDICMDCON_LONGRSP;
SDICCON = ccon;
while (1) {
csta = SDICSTA;
if (csta & csta_rdy_bit)
break;
if (csta & S3C2410_SDICMDSTAT_CMDTIMEOUT) {
puts("===============> MMC CMD Timeout\n");
SDICSTA |= S3C2410_SDICMDSTAT_CMDTIMEOUT;
break;
}
}
// debug("final MMC CMD status 0x%x\n", csta);
SDICSTA |= csta_rdy_bit;
if (flags & CMD_F_RESP) {
resp[0] = SDIRSP0;
resp[1] = SDIRSP1;
resp[2] = SDIRSP2;
resp[3] = SDIRSP3;
}
return resp;
}
#define FIFO_FILL() ((SDIFSTA & S3C2410_SDIFSTA_COUNTMASK) >> 2)
static int mmc_block_read(u8 *dst, u32 src, u32 len)
{
u32 dcon, fifo;
u32 *dst_u32 = (u32 *)dst;
u32 *resp;
if (len == 0)
return 0;
// debug("mmc_block_rd dst %lx src %lx len %d\n", (u32)dst, src, len);
/* set block len */
resp = mmc_cmd(MMC_CMD_SET_BLOCKLEN, len, CMD_F_RESP);
SDIBSIZE = len;
//SDIPRE = 0xff;
/* setup data */
dcon = (len >> 9) & S3C2410_SDIDCON_BLKNUM;
dcon |= S3C2410_SDIDCON_BLOCKMODE;
dcon |= S3C2410_SDIDCON_RXAFTERCMD|S3C2410_SDIDCON_XFER_RXSTART;
if (wide)
dcon |= S3C2410_SDIDCON_WIDEBUS;
if (!am_i_s3c2410())
dcon |= S3C2440_SDIDCON_DS_WORD | S3C2440_SDIDCON_DATSTART;
SDIDCON = dcon;
/* send read command */
resp = mmc_cmd(MMC_CMD_READ_BLOCK, src, CMD_F_RESP);
while (len > 0) {
u32 sdidsta = SDIDSTA;
fifo = FIFO_FILL();
if (sdidsta & (S3C2410_SDIDSTA_FIFOFAIL|
S3C2410_SDIDSTA_CRCFAIL|
S3C2410_SDIDSTA_RXCRCFAIL|
S3C2410_SDIDSTA_DATATIMEOUT)) {
puts("mmc_block_read: err SDIDSTA=0x");
print32(sdidsta);
puts("\n");
return -1;
}
if (am_i_s3c2410()) {
while (fifo--) {
//debug("dst_u32 = 0x%08x\n", dst_u32);
*(dst_u32++) = SDIDAT2410;
if (len >= 4)
len -= 4;
else {
len = 0;
break;
}
}
} else {
while (fifo--) {
//debug("dst_u32 = 0x%08x\n", dst_u32);
*(dst_u32++) = SDIDAT;
if (len >= 4)
len -= 4;
else {
len = 0;
break;
}
}
}
}
// debug("waiting for SDIDSTA (currently 0x%08x\n", SDIDSTA);
while (!(SDIDSTA & (1 << 4))) {}
// debug("done waiting for SDIDSTA (currently 0x%08x\n", SDIDSTA);
SDIDCON = 0;
if (!(SDIDSTA & S3C2410_SDIDSTA_XFERFINISH))
puts("mmc_block_read; transfer not finished!\n");
return 0;
}
static int mmc_block_write(u32 dst, u8 *src, int len)
{
puts("MMC block write not yet supported on S3C2410!\n");
return -1;
}
int s3c24xx_mmc_read(u32 src, u8 *dst, int size)
{
u32 end, part_start, part_end, part_len, aligned_start, aligned_end;
u32 mmc_block_size, mmc_block_address;
if (size == 0)
return 0;
if (!mmc_ready) {
puts("Please initialize the MMC first\n");
return -1;
}
mmc_block_size = MMC_BLOCK_SIZE;
mmc_block_address = ~(mmc_block_size - 1);
src -= CFG_MMC_BASE;
end = src + size;
part_start = ~mmc_block_address & src;
part_end = ~mmc_block_address & end;
aligned_start = mmc_block_address & src;
aligned_end = mmc_block_address & end;
/* all block aligned accesses */
// debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// src, (u32)dst, end, part_start, part_end, aligned_start, aligned_end);
if (part_start) {
part_len = mmc_block_size - part_start;
// debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// src, (u32)dst, end, part_start, part_end, aligned_start, aligned_end);
if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0)
return -1;
memcpy(dst, mmc_buf+part_start, part_len);
dst += part_len;
src += part_len;
}
// debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// src, (u32)dst, end, part_start, part_end, aligned_start, aligned_end);
for (; src < aligned_end; src += mmc_block_size, dst += mmc_block_size) {
// debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// src, (u32)dst, end, part_start, part_end, aligned_start, aligned_end);
if ((mmc_block_read((u8 *)(dst), src, mmc_block_size)) < 0)
return -1;
}
// debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// src, (u32)dst, end, part_start, part_end, aligned_start, aligned_end);
if (part_end && src < end) {
// debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// src, (u32)dst, end, part_start, part_end, aligned_start, aligned_end);
if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0)
return -1;
memcpy(dst, mmc_buf, part_end);
}
return 0;
}
int s3c24xx_mmc_write(u8 *src, u32 dst, int size)
{
u32 end, part_start, part_end, part_len, aligned_start, aligned_end;
u32 mmc_block_size, mmc_block_address;
if (size == 0)
return 0;
if (!mmc_ready) {
puts("Please initialize the MMC first\n");
return -1;
}
mmc_block_size = MMC_BLOCK_SIZE;
mmc_block_address = ~(mmc_block_size - 1);
dst -= CFG_MMC_BASE;
end = dst + size;
part_start = ~mmc_block_address & dst;
part_end = ~mmc_block_address & end;
aligned_start = mmc_block_address & dst;
aligned_end = mmc_block_address & end;
/* all block aligned accesses */
// debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// src, (u32)dst, end, part_start, part_end, aligned_start, aligned_end);
if (part_start) {
part_len = mmc_block_size - part_start;
// debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// (u32)src, dst, end, part_start, part_end, aligned_start, aligned_end);
if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0)
return -1;
memcpy(mmc_buf+part_start, src, part_len);
if ((mmc_block_write(aligned_start, mmc_buf, mmc_block_size)) < 0)
return -1;
dst += part_len;
src += part_len;
}
// debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// src, (u32)dst, end, part_start, part_end, aligned_start, aligned_end);
for (; dst < aligned_end; src += mmc_block_size, dst += mmc_block_size) {
// debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// src, (u32)dst, end, part_start, part_end, aligned_start, aligned_end);
if ((mmc_block_write(dst, (u8 *)src, mmc_block_size)) < 0)
return -1;
}
// debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// src, (u32)dst, end, part_start, part_end, aligned_start, aligned_end);
if (part_end && dst < end) {
// debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
// src, (u32)dst, end, part_start, part_end, aligned_start, aligned_end);
if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0)
return -1;
memcpy(mmc_buf, src, part_end);
if ((mmc_block_write(aligned_end, mmc_buf, mmc_block_size)) < 0)
return -1;
}
return 0;
}
u32 s3c24xx_mmc_bread(int dev_num, u32 blknr, u32 blkcnt, void *dst)
{
int mmc_block_size = MMC_BLOCK_SIZE;
u32 src = blknr * mmc_block_size + CFG_MMC_BASE;
s3c24xx_mmc_read(src, dst, blkcnt*mmc_block_size);
return blkcnt;
}
/* MMC_DEFAULT_RCA should probably be just 1, but this may break other code
that expects it to be shifted. */
static u_int16_t rca = MMC_DEFAULT_RCA >> 16;
#if 0
static u32 mmc_size(const struct mmc_csd *csd)
{
u32 block_len, mult, blocknr;
block_len = csd->read_bl_len << 12;
mult = csd->c_size_mult1 << 8;
blocknr = (csd->c_size+1) * mult;
return blocknr * block_len;
}
#endif
struct sd_cid {
char pnm_0; /* product name */
char oid_1; /* OEM/application ID */
char oid_0;
uint8_t mid; /* manufacturer ID */
char pnm_4;
char pnm_3;
char pnm_2;
char pnm_1;
uint8_t psn_2; /* product serial number */
uint8_t psn_1;
uint8_t psn_0; /* MSB */
uint8_t prv; /* product revision */
uint8_t crc; /* CRC7 checksum, b0 is unused and set to 1 */
uint8_t mdt_1; /* manufacturing date, LSB, RRRRyyyy yyyymmmm */
uint8_t mdt_0; /* MSB */
uint8_t psn_3; /* LSB */
};
static void print_mmc_cid(mmc_cid_t *cid)
{
puts("MMC found. Card desciption is:\n");
puts("Manufacturer ID = ");
print8(cid->id[0]);
print8(cid->id[1]);
print8(cid->id[2]);
puts("\nHW/FW Revision = ");
print8(cid->hwrev);
print8(cid->fwrev);
cid->hwrev = cid->fwrev = 0; /* null terminate string */
puts("Product Name = ");
puts((char *)cid->name);
puts("\nSerial Number = ");
print8(cid->sn[0]);
print8(cid->sn[1]);
print8(cid->sn[2]);
puts("\nMonth = ");
printdec(cid->month);
puts("\nYear = ");
printdec(1997 + cid->year);
puts("\n");
}
static void print_sd_cid(const struct sd_cid *cid)
{
puts("Manufacturer: 0x");
print8(cid->mid);
puts("OEM \"");
this_board->putc(cid->oid_0);
this_board->putc(cid->oid_1);
puts("\"\nProduct name: \"");
this_board->putc(cid->pnm_0);
this_board->putc(cid->pnm_1);
this_board->putc(cid->pnm_2);
this_board->putc(cid->pnm_3);
this_board->putc(cid->pnm_4);
puts("\", revision ");
printdec(cid->prv >> 4);
puts(".");
printdec(cid->prv & 15);
puts("\nSerial number: ");
printdec(cid->psn_0 << 24 | cid->psn_1 << 16 | cid->psn_2 << 8 |
cid->psn_3);
puts("\nManufacturing date: ");
printdec(cid->mdt_1 & 15);
puts("/");
printdec(2000+((cid->mdt_0 & 15) << 4)+((cid->mdt_1 & 0xf0) >> 4));
puts("\nCRC: 0x");
print8(cid->crc >> 1);
puts(" b0 = ");
print8(cid->crc & 1);
puts("\n");
}
int s3c24xx_mmc_init(int verbose)
{
int retries, rc = -2;
int is_sd = 0;
u32 *resp;
SDICON = S3C2410_SDICON_FIFORESET | S3C2410_SDICON_CLOCKTYPE;
SDIBSIZE = 512;
if (am_i_s3c2410()) {
/* S3C2410 has some bug that prevents reliable operation at higher speed */
//SDIPRE = 0x3e; /* SDCLK = PCLK/2 / (SDIPRE+1) = 396kHz */
SDIPRE = 0x02; /* 2410: SDCLK = PCLK/2 / (SDIPRE+1) = 11MHz */
SDIDTIMER = 0xffff;
SDIIMSK2410 = 0x0;
} else {
SDIPRE = 0x05; /* 2410: SDCLK = PCLK / (SDIPRE+1) = 11MHz */
SDIDTIMER = 0x7fffff;
SDIIMSK = 0x0;
}
udelay(1250000); /* FIXME: 74 SDCLK cycles */
mmc_csd.c_size = 0;
puts("Sending reset...\n");
/* reset */
retries = 10;
resp = mmc_cmd(MMC_CMD_RESET, 0, 0);
puts("trying to detect SD Card...\n");
while (retries--) {
udelay(1000000);
resp = mmc_cmd(55, 0x00000000, CMD_F_RESP);
resp = mmc_cmd(41, 0x00300000, CMD_F_RESP);
if (resp[0] & (1 << 31)) {
is_sd = 1;
break;
}
}
if (retries < 0 && !is_sd)
return -3;
/* try to get card id */
resp = mmc_cmd(MMC_CMD_ALL_SEND_CID, 0, CMD_F_RESP|CMD_F_RESP_LONG);
if (resp) {
if (!is_sd) {
/* TODO configure mmc driver depending on card
attributes */
mmc_cid_t *cid = (mmc_cid_t *)resp;
if (verbose)
print_mmc_cid(cid);
#if 0
sprintf((char *) mmc_dev.vendor,
"Man %02x%02x%02x Snr %02x%02x%02x",
cid->id[0], cid->id[1], cid->id[2],
cid->sn[0], cid->sn[1], cid->sn[2]);
sprintf((char *) mmc_dev.product,"%s",cid->name);
sprintf((char *) mmc_dev.revision,"%x %x",
cid->hwrev, cid->fwrev);
#endif
}
else {
struct sd_cid *cid = (struct sd_cid *) resp;
if (verbose)
print_sd_cid(cid);
#if 0
sprintf((char *) mmc_dev.vendor,
"Man %02 OEM %c%c \"%c%c%c%c%c\"",
cid->mid, cid->oid_0, cid->oid_1,
cid->pnm_0, cid->pnm_1, cid->pnm_2, cid->pnm_3,
cid->pnm_4);
sprintf((char *) mmc_dev.product, "%d",
cid->psn_0 << 24 | cid->psn_1 << 16 |
cid->psn_2 << 8 | cid->psn_3);
sprintf((char *) mmc_dev.revision, "%d.%d",
cid->prv >> 4, cid->prv & 15);
#endif
}
/* MMC exists, get CSD too */
resp = mmc_cmd(MMC_CMD_SET_RCA, MMC_DEFAULT_RCA, CMD_F_RESP);
if (is_sd)
rca = resp[0] >> 16;
resp = mmc_cmd(MMC_CMD_SEND_CSD, rca<<16, CMD_F_RESP|CMD_F_RESP_LONG);
if (resp) {
mmc_csd_t *csd = (mmc_csd_t *)resp;
memcpy(&mmc_csd, csd, sizeof(csd));
rc = 0;
mmc_ready = 1;
#if 0
/* FIXME add verbose printout for csd */
printf("READ_BL_LEN=%u, C_SIZE_MULT=%u, C_SIZE=%u\n",
csd->read_bl_len, csd->c_size_mult1, csd->c_size);
printf("size = %u\n", mmc_size(csd));
#endif
}
}
resp = mmc_cmd(MMC_CMD_SELECT_CARD, rca<<16, CMD_F_RESP);
#ifdef CONFIG_MMC_WIDE
if (is_sd) {
resp = mmc_cmd(55, rca<<16, CMD_F_RESP);
resp = mmc_cmd(6, 0x02, CMD_F_RESP);
wide = 1;
}
#endif
return rc;
}

View File

@ -1,77 +0,0 @@
/*
* (C) Copyright 2007 OpenMoko, Inc.
* Author: xiangfu liu <xiangfu@openmoko.org>
*
* Configuation settings for the FIC Neo GTA02 Linux GSM phone
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <qi.h>
#include <serial-s3c24xx.h>
void serial_init_115200_s3c24xx(const int uart, const int pclk_MHz)
{
int div = (((54 * pclk_MHz) + 26) / 100) -1;
switch(uart)
{
case UART0:
rULCON0 = 0x3;
rUCON0 = 0x245;
rUFCON0 = 0x0;
rUMCON0 = 0x0;
rUBRDIV0 = div;
break;
case UART1:
rULCON1 = 0x3;
rUCON1 = 0x245;
rUFCON1 = 0x0;
rUMCON1 = 0x0;
rUBRDIV1 = div;
break;
case UART2:
rULCON2 = 0x3;
rUCON2 = 0x245;
rUFCON2 = 0x1;
rUBRDIV2 = div;
break;
default:
break;
}
}
/*
* Output a single byte to the serial port.
*/
void serial_putc_s3c24xx(const int uart, const char c)
{
switch(uart)
{
case UART0:
while ( !( rUTRSTAT0 & 0x2 ) );
WrUTXH0(c);
break;
case UART1:
while ( !( rUTRSTAT1 & 0x2 ) );
WrUTXH1(c);
break;
case UART2:
while ( !( rUTRSTAT2 & 0x2 ) );
WrUTXH2(c);
break;
default:
break;
}
}

View File

@ -1,315 +0,0 @@
/*
* (C) Copyright 2007 OpenMoko, Inc.
*
* Configuation settings for the OPENMOKO Neo GTA02 Linux GSM phone
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#define __ASM_MODE__
#define __ASSEMBLY__
#include <neo_gta02.h>
#define S3C2410_MISCCR_nEN_SCLK0 (1 << 17)
#define S3C2410_MISCCR_nEN_SCLK1 (1 << 18)
#define S3C2410_MISCCR_nEN_SCLKE (1 << 19)
.globl _start, processor_id, is_jtag
_start: b start_code
/* if we are injected by JTAG, the script sets _istag content to nonzero */
is_jtag:
.word 0
/* it's at a fixed address (+0x8) so we can breakpoint it in the JTAG script
* we need to go through this hassle because before this moment, SDRAM is not
* working so we can't prep it from JTAG
*/
_steppingstone_done:
ldr pc, _start_armboot
_start_armboot:
.word start_qi
_TEXT_BASE:
.word TEXT_BASE
/*
* These are defined in the board-specific linker script.
*/
.globl _bss_start
_bss_start:
.word __bss_start
.globl _bss_end
_bss_end:
.word _end
/*
* we have a stack in steppingstone because we can want to run full memory
* memory tests
*/
.fill 128
.globl _ss_stack
_ss_stack:
start_code:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0xd3
msr cpsr,r0
# define pWTCON 0x53000000
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]
/*
* mask all IRQs by setting all bits in the INTMR - default
*/
# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */
# define INTSUBMSK 0x4A00001C
# define INTSUBMSK_val 0x0000ffff
mov r1, #0xffffffff
ldr r0, =INTMSK
str r1, [r0]
ldr r1, =INTSUBMSK_val
ldr r0, =INTSUBMSK
str r1, [r0]
/* Make sure we get FCLK:HCLK:PCLK = 1:3:6 */
# define CAMDIVN 0x4C000018
ldr r0, =CAMDIVN
mov r1, #0
str r1, [r0]
/* Clock asynchronous mode */
mrc p15, 0, r1, c1, c0, 0
orr r1, r1, #0xc0000000
mcr p15, 0, r1, c1, c0, 0
#define LOCKTIME 0x4c000000
ldr r0, =LOCKTIME
mov r1, #0xffffff
str r1, [r0]
# define UPLLCON 0x4c000008
# define MPLLCON_val ((142 << 12) + (7 << 4) + 1)
# define UPLLCON_val (( 88 << 12) + (8 << 4) + 2)
ldr r0, =UPLLCON
ldr r1, =UPLLCON_val
str r1, [r0]
/* Page 7-19, seven nops between UPLL and MPLL */
nop
nop
nop
nop
nop
nop
nop
ldr r1, =MPLLCON_val
str r1, [r0, #-4] /* MPLLCON */
# define CLKDIVN 0x4C000014 /* clock divisor register */
# define CLKDIVN_val 7 /* FCLK:HCLK:PCLK = 1:3:6 */
/* FCLK:HCLK:PCLK = 1:3:6 */
ldr r0, =CLKDIVN
mov r1, #CLKDIVN_val
str r1, [r0]
/* enable only CPU peripheral block clocks we actually use */
ldr r0, =0x4c00000c /* clkcon */
ldr r1, =0x3f10 /* uart, pwm, gpio, nand, sdi clocks on */
str r1, [r0]
/* gpio UART2 init, H port */
ldr r0, =0x56000070
ldr r1, =0x001AAAAA
str r1, [r0]
/* enable KEEPACT(GPJ8) to make sure PMU keeps us alive */
ldr r0, =0x56000000 /* GPJ base */
ldr r1, [r0, #0xd0] /* GPJCON */
orr r1, r1, #(1 << 16)
str r1, [r0, #0xd0]
ldr r1, [r0, #0xd4] /* GPJDAT */
orr r1, r1, #(1 << 8)
str r1, [r0, #0xd4]
/* init uart2 */
ldr r0, =0x50008000
mov r1, #0x03
str r1, [r0]
ldr r1, =0x245
str r1, [r0, #0x04]
mov r1, #0x00
str r1, [r0, #0x08]
mov r1, #0x00
str r1, [r0, #0x0c]
mov r1, #0x11
str r1, [r0, #0x28]
ldr r0, =0x50008000
ldr r1, =0x54
str r1, [r0, #0x20]
/* reset nand controller, or it is dead to us */
mov r1, #0x4E000000
ldr r2, =0xfff0 @ initial value tacls=3,rph0=7,rph1=7
ldr r3, [r1, #0]
orr r3, r3, r2
str r3, [r1, #0]
ldr r3, [r1, #4]
orr r3, r3, #1 @ enable nand controller
str r3, [r1, #4]
/* take sdram out of power down */
ldr r0, =0x56000080 /* misccr */
ldr r1, [ r0 ]
bic r1, r1, #(S3C2410_MISCCR_nEN_SCLK0 | S3C2410_MISCCR_nEN_SCLK1 | S3C2410_MISCCR_nEN_SCLKE)
str r1, [ r0 ]
/* ensure signals stabalise */
mov r1, #128
1: subs r1, r1, #1
bpl 1b
bl cpu_init_crit
/* ensure some refresh has happened */
ldr r1, =0xfffff
1: subs r1, r1, #1
bpl 1b
/* capture full EINT situation into gstatus 4 */
ldr r0, =0x4A000000 /* SRCPND */
ldr r1, [ r0 ]
and r1, r1, #0xf
ldr r0, =0x560000BC /* gstatus4 */
str r1, [ r0 ]
ldr r0, =0x560000A8 /* EINTPEND */
ldr r1, [ r0 ]
ldr r0, =0xfff0
and r1, r1, r0
ldr r0, =0x560000BC /* gstatus4 */
ldr r0, [ r0 ]
orr r1, r1, r0
ldr r0, =0x560000BC /* gstatus4 */
str r1, [ r0 ]
/* test for resume */
ldr r1, =0x560000B4 /* gstatus2 */
ldr r0, [ r1 ]
tst r0, #0x02 /* is this resume from power down */
/* well, if it was, we are going to jump to
* whatever address we stashed in gstatus3,
* and gstatus4 will hold the wake interrupt
* source for the OS to look at
*/
ldrne pc, [r1, #4]
/* >> CFG_VIDEO_LOGO_MAX_SIZE */
#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
stack_setup:
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
sub sp, r0, #12 /* leave 3 words for abort-stack */
clear_bss:
ldr r0, _bss_start /* find start of bss segment */
ldr r1, _bss_end /* stop here */
mov r2, #0x00000000 /* clear */
clbss_l:
str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
ble clbss_l
/* we are going to jump into the C part of the init now */
spin:
b _steppingstone_done
/*
*************************************************************************
*
* CPU_init_critical registers
*
* setup important registers
* setup memory timing
*
*************************************************************************
*/
cpu_init_crit:
/*
* flush v4 I/D caches
*/
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
/*
* disable MMU stuff and caches
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
orr r0, r0, #0x00000002 @ set bit 2 (A) Align
orr r0, r0, #0x00005000 @ set bits 14, 12 D and I-Cache
mcr p15, 0, r0, c1, c0, 0
/*
* before relocating, we have to setup RAM timing
* because memory timing is board-dependend, you will
* find a lowlevel_init.S in your board directory.
*/
mov ip, lr
bl lowlevel_init
mov lr, ip
mov pc, lr

View File

@ -1,126 +0,0 @@
/*
* (C) Copyright 2007 OpenMoko, Inc.
* Author: xiangfu liu <xiangfu@openmoko.org>
* Andy Green <andy@openmoko.com>
*
* Configuation settings for the OPENMOKO Neo GTA02 Linux GSM phone
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/* NOTE this stuff runs in steppingstone context! */
#include <qi.h>
#include "nand_read.h"
#include <neo_gta02.h>
#define stringify2(s) stringify1(s)
#define stringify1(s) #s
extern void bootloader_second_phase(void);
const struct board_api *boards[] = {
&board_api_gta02,
NULL /* always last */
};
struct board_api const * this_board;
extern int is_jtag;
void start_qi(void)
{
int flag = 0;
int board = 0;
/*
* well, we can be running on this CPU two different ways.
*
* 1) We were copied into steppingstone and TEXT_BASE already
* by JTAG. We don't have to do anything else. JTAG script
* then sets data at address 0x4 to 0xffffffff as a signal we
* are running by JTAG.
*
* 2) We only got our first 4K into steppingstone, we need to copy
* the rest of ourselves into TEXT_BASE.
*
* So we do the copy out of NAND only if we see we did not come up
* under control of JTAG.
*/
if (!is_jtag)
/*
* We got the first 4KBytes of the bootloader pulled into the
* steppingstone SRAM for free. Now we pull the whole bootloader
* image into SDRAM.
*
* This code and the .S files are arranged by the linker script
* to expect to run from 0x0. But the linker script has told
* everything else to expect to run from 0x33000000+. That's
* why we are going to be able to copy this code and not have it
* crash when we run it from there.
*/
/* We randomly pull 32KBytes of bootloader */
if (nand_read_ll((u8 *)TEXT_BASE, 0, 32 * 1024 / 512) < 0)
goto unhappy;
/* ask all the boards we support in turn if they recognize this
* hardware we are running on, accept the first positive answer
*/
this_board = boards[board];
while (!flag && this_board) {
/* check if it is the right board... */
if (this_board->is_this_board()) {
flag = 1;
continue;
}
this_board = boards[board++];
}
this_board->port_init();
set_putc_func(this_board->putc);
/* stick some hello messages on debug console */
puts("\n\n\nQi Bootloader "stringify2(QI_CPU)" "
stringify2(BUILD_HOST)" "
stringify2(BUILD_VERSION)" "
"\n");
puts(stringify2(BUILD_DATE) " Copyright (C) 2008 Openmoko, Inc.\n");
puts("\n Detected: ");
puts(this_board->name);
puts(", ");
puts((this_board->get_board_variant)()->name);
puts("\n");
/*
* jump to bootloader_second_phase() running from DRAM copy
*/
bootloader_second_phase();
unhappy:
while(1)
;
}

View File

@ -1,650 +0,0 @@
#include <qi.h>
#include "hs_mmc.h"
#include <string.h>
#include <glamo-mmc.h>
#define HCLK_OPERATION
#undef DEBUG_HSMMC
#ifdef DEBUG_HSMMC
#define dbg(x...) printf(x)
#else
#define dbg(x...) do { } while (0)
#endif
//#include <linux-mmc.h>
#include <linux-mmc-protocol.h>
#include <s3c6410.h>
//#include <linux/mmc/protocol.h>
//#include <asm/io.h>
//#include <movi.h>
#include "hs_mmc.h"
#include <mmc.h>
#define SDI_Tx_buffer_HSMMC (0x51000000)
#define SDI_Rx_buffer_HSMMC (0x51000000+(0x300000))
#define SDI_Compare_buffer_HSMMC (0x51000000+(0x600000))
#define Card_OneBlockSize_ver1 512
#define MMC_DEFAULT_RCA (1<<16)
/* Global variables */
static u32 HS_DMA_END = 0;
static u32 rca = 0;
static ulong HCLK;
int movi_hc = 1; /* sdhc style block indexing */
enum card_type card_type;
/* extern functions */
extern ulong get_HCLK(void);
#define s3c_hsmmc_readl(x) *((unsigned int *)(((ELFIN_HSMMC_BASE + (HSMMC_CHANNEL * 0x100000)) + (x))))
#define s3c_hsmmc_readw(x) *((unsigned short *)(((ELFIN_HSMMC_BASE + (HSMMC_CHANNEL * 0x100000)) + (x))))
#define s3c_hsmmc_readb(x) *((unsigned char *)(((ELFIN_HSMMC_BASE + (HSMMC_CHANNEL * 0x100000)) + (x))))
#define s3c_hsmmc_writel(v,x) *((unsigned int *) (((ELFIN_HSMMC_BASE + (HSMMC_CHANNEL * 0x100000)) + (x)))) = v
#define s3c_hsmmc_writew(v,x) *((unsigned short *)(((ELFIN_HSMMC_BASE + (HSMMC_CHANNEL * 0x100000)) + (x)))) = v
#define s3c_hsmmc_writeb(v,x) *((unsigned char *)(((ELFIN_HSMMC_BASE + (HSMMC_CHANNEL * 0x100000)) + (x)))) = v
#define readl(x) *((unsigned int *)(x))
#define writel(v, x) *((unsigned int *)(x)) = v
#define UNSTUFF_BITS(resp,start,size) \
({ \
const int __size = size; \
const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \
const int __off = 3 - ((start) / 32); \
const int __shft = (start) & 31; \
u32 __res; \
\
__res = resp[__off] >> __shft; \
if (__size + __shft > 32) \
__res |= resp[__off-1] << ((32 - __shft) & 31); \
__res & __mask; \
})
static int wait_for_cmd_done (void)
{
u32 i;
ushort n_int, e_int;
dbg("wait_for_cmd_done\n");
for (i = 0; i < 0x20000000; i++) {
n_int = s3c_hsmmc_readw(HM_NORINTSTS);
dbg(" HM_NORINTSTS: %04x\n", n_int);
if (n_int & 0x8000)
/* any error */
break;
if (n_int & 0x0001)
/* command complete */
return 0;
}
e_int = s3c_hsmmc_readw(HM_ERRINTSTS);
s3c_hsmmc_writew(e_int, HM_ERRINTSTS);
s3c_hsmmc_writew(n_int, HM_NORINTSTS);
puts("cmd error1: 0x");
print32(e_int);
puts(", HM_NORINTSTS: 0x");
print32(n_int);
puts("\n");
return -1;
}
static void ClearCommandCompleteStatus(void)
{
s3c_hsmmc_writew(1 << 0, HM_NORINTSTS);
while (s3c_hsmmc_readw(HM_NORINTSTS) & 0x1) {
s3c_hsmmc_writew(1 << 0, HM_NORINTSTS);
}
}
static void card_irq_enable(ushort temp)
{
s3c_hsmmc_writew((s3c_hsmmc_readw(HM_NORINTSTSEN) & 0xFEFF) | (temp << 8), HM_NORINTSTSEN);
}
void hsmmc_reset (void)
{
s3c_hsmmc_writeb(0x3, HM_SWRST);
}
void hsmmc_set_gpio (void)
{
u32 reg;
reg = readl(GPGCON) & 0xf0000000;
writel(reg | 0x02222222, GPGCON);
reg = readl(GPGPUD) & 0xfffff000;
writel(reg, GPGPUD);
}
static void set_transfer_mode_register (u32 MultiBlk, u32 DataDirection, u32 AutoCmd12En, u32 BlockCntEn, u32 DmaEn)
{
s3c_hsmmc_writew((s3c_hsmmc_readw(HM_TRNMOD) & ~(0xffff)) | (MultiBlk << 5)
| (DataDirection << 4) | (AutoCmd12En << 2)
| (BlockCntEn << 1) | (DmaEn << 0), HM_TRNMOD);
// dbg("\nHM_TRNMOD = 0x%04x\n", HM_TRNMOD);
}
static void set_arg_register (u32 arg)
{
s3c_hsmmc_writel(arg, HM_ARGUMENT);
}
static void set_blkcnt_register(ushort uBlkCnt)
{
s3c_hsmmc_writew(uBlkCnt, HM_BLKCNT);
}
static void SetSystemAddressReg(u32 SysAddr)
{
s3c_hsmmc_writel(SysAddr, HM_SYSAD);
}
static void set_blksize_register(ushort uDmaBufBoundary, ushort uBlkSize)
{
s3c_hsmmc_writew((uDmaBufBoundary << 12) | (uBlkSize), HM_BLKSIZE);
}
static void ClearErrInterruptStatus(void)
{
while (s3c_hsmmc_readw(HM_NORINTSTS) & (0x1 << 15)) {
s3c_hsmmc_writew(s3c_hsmmc_readw(HM_NORINTSTS), HM_NORINTSTS);
s3c_hsmmc_writew(s3c_hsmmc_readw(HM_ERRINTSTS), HM_ERRINTSTS);
}
}
static void InterruptEnable(ushort NormalIntEn, ushort ErrorIntEn)
{
ClearErrInterruptStatus();
s3c_hsmmc_writew(NormalIntEn, HM_NORINTSTSEN);
s3c_hsmmc_writew(ErrorIntEn, HM_ERRINTSTSEN);
}
static void hsmmc_clock_onoff (int on)
{
u16 reg16;
if (on == 0) {
reg16 = s3c_hsmmc_readw(HM_CLKCON) & ~(0x1<<2);
s3c_hsmmc_writew(reg16, HM_CLKCON);
} else {
reg16 = s3c_hsmmc_readw(HM_CLKCON);
s3c_hsmmc_writew(reg16 | (0x1<<2), HM_CLKCON);
while (1) {
reg16 = s3c_hsmmc_readw(HM_CLKCON);
if (reg16 & (0x1<<3)) /* SD_CLKSRC is Stable */
break;
}
}
}
static void set_clock (u32 clksrc, u32 div)
{
u16 reg16;
u32 i;
s3c_hsmmc_writel(0xC0004100 | (clksrc << 4), HM_CONTROL2); // rx feedback control
s3c_hsmmc_writel(0x00008080, HM_CONTROL3); // Low clock: 00008080
s3c_hsmmc_writel(0x3 << 16, HM_CONTROL4);
s3c_hsmmc_writew(s3c_hsmmc_readw(HM_CLKCON) & ~(0xff << 8), HM_CLKCON);
/* SDCLK Value Setting + Internal Clock Enable */
s3c_hsmmc_writew(((div<<8) | 0x1), HM_CLKCON);
/* CheckInternalClockStable */
for (i = 0; i < 0x10000; i++) {
reg16 = s3c_hsmmc_readw(HM_CLKCON);
if (reg16 & 0x2)
break;
}
if (i == 0x10000)
puts("internal clock stabilization failed\n");
hsmmc_clock_onoff(1);
}
static void set_cmd_register (ushort cmd, u32 data, u32 flags)
{
ushort val = (cmd << 8);
if (cmd == 12)
val |= (3 << 6);
if (flags & MMC_RSP_136) /* Long RSP */
val |= 0x01;
else if (flags & MMC_RSP_BUSY) /* R1B */
val |= 0x03;
else if (flags & MMC_RSP_PRESENT) /* Normal RSP */
val |= 0x02;
if (flags & MMC_RSP_OPCODE)
val |= (1<<4);
if (flags & MMC_RSP_CRC)
val |= (1<<3);
if (data)
val |= (1<<5);
// puts("cmdreg = 0x");
// print32(val);
// puts("\n");
s3c_hsmmc_writew(val, HM_CMDREG);
}
static int issue_command (ushort cmd, u32 arg, u32 data, u32 flags)
{
int i;
/* puts("### issue_command: ");
printdec(cmd);
puts(" 0x");
print32(arg);
puts(" ");
printdec(data);
puts(" 0x");
print32(flags);
puts("\n");
*/
/* Check CommandInhibit_CMD */
for (i = 0; i < 0x1000000; i++) {
if (!(s3c_hsmmc_readl(HM_PRNSTS) & 0x1))
break;
}
if (i == 0x1000000) {
puts("@@@@@@1 rHM_PRNSTS: ");
printdec(s3c_hsmmc_readl(HM_PRNSTS));
puts("\n");
}
/* Check CommandInhibit_DAT */
if (flags & MMC_RSP_BUSY) {
for (i = 0; i < 0x1000000; i++) {
if (!(s3c_hsmmc_readl(HM_PRNSTS) & 0x2))
break;
}
if (i == 0x1000000) {
puts("@@@@@@2 rHM_PRNSTS: ");
print32(s3c_hsmmc_readl(HM_PRNSTS));
puts("\n");
}
}
s3c_hsmmc_writel(arg, HM_ARGUMENT);
set_cmd_register(cmd, data, flags);
if (wait_for_cmd_done())
return 0;
ClearCommandCompleteStatus();
if (!(s3c_hsmmc_readw(HM_NORINTSTS) & 0x8000))
return 1;
puts("Command = ");
printdec((s3c_hsmmc_readw(HM_CMDREG) >> 8));
puts(", Error Stat = 0x");
print32(s3c_hsmmc_readw(HM_ERRINTSTS));
return 0;
}
static int check_card_status(void)
{
if (!issue_command(MMC_SEND_STATUS, rca<<16, 0, MMC_RSP_R1))
return 0;
if (((s3c_hsmmc_readl(HM_RSPREG0) >> 9) & 0xf) == 4) {
// puts("Card is transfer status\n");
return 1;
}
return 1;
}
static void set_hostctl_speed (u8 mode)
{
u8 reg8;
reg8 = s3c_hsmmc_readb(HM_HOSTCTL) & ~(0x1<<2);
s3c_hsmmc_writeb(reg8 | (mode<<2), HM_HOSTCTL);
}
/* return 0: OK
* return -1: error
*/
static int set_bus_width (u32 width)
{
u8 reg = s3c_hsmmc_readb(HM_HOSTCTL);
u8 bitmode = 0;
card_irq_enable(0); // Disable sd card interrupt
if (!issue_command(MMC_APP_CMD, rca<<16, 0, MMC_RSP_R1))
return -1;
else {
if (width == 1) { // 1-bits
bitmode = 0;
if (!issue_command(MMC_SWITCH, 0, 0, MMC_RSP_R1B))
return -1;
} else { // 4-bits
bitmode = 1;
if (!issue_command(MMC_SWITCH, 2, 0, MMC_RSP_R1B))
return -1;
}
}
if (bitmode == 2)
reg |= 1 << 5;
else
reg |= bitmode << 1;
s3c_hsmmc_writeb(reg, HM_HOSTCTL);
card_irq_enable(1);
// puts(" transfer rHM_HOSTCTL(0x28) = 0x");
// print32(s3c_hsmmc_readb(HM_HOSTCTL));
return 0;
}
static void clock_config (u32 Divisior)
{
if (100000000 / (Divisior * 2) > 25000000) // Higher than 25MHz, it is necessary to enable high speed mode of the host controller.
set_hostctl_speed(HIGH);
else
set_hostctl_speed(NORMAL);
hsmmc_clock_onoff(0); // when change the sd clock frequency, need to stop sd clock.
set_clock(SD_EPLL, Divisior);
}
static void check_dma_int (void)
{
u32 i;
for (i = 0; i < 0x10000000; i++) {
if (s3c_hsmmc_readw(HM_NORINTSTS) & 0x0002) {
HS_DMA_END = 1;
s3c_hsmmc_writew(s3c_hsmmc_readw(HM_NORINTSTS) | 0x0002, HM_NORINTSTS);
return;
}
if (s3c_hsmmc_readw(HM_NORINTSTS) & 0x8000) {
puts("error found: ");
print32(s3c_hsmmc_readw(HM_ERRINTSTS));
return;
}
}
puts("check_dma_int: timeout\n");
}
static void print_sd_cid(const struct sd_cid *cid)
{
puts(" Card Type: ");
switch (card_type) {
case CARDTYPE_NONE:
puts("(None) / ");
break;
case CARDTYPE_MMC:
puts("MMC / ");
break;
case CARDTYPE_SD:
puts("SD / ");
break;
case CARDTYPE_SD20:
puts("SD 2.0 / ");
break;
case CARDTYPE_SDHC:
puts("SD 2.0 SDHC / ");
break;
}
puts("Mfr: 0x");
print8(cid->mid);
puts(", OEM \"");
this_board->putc(cid->oid_0);
this_board->putc(cid->oid_1);
puts("\" / ");
this_board->putc(cid->pnm_0);
this_board->putc(cid->pnm_1);
this_board->putc(cid->pnm_2);
this_board->putc(cid->pnm_3);
this_board->putc(cid->pnm_4);
puts("\", rev ");
printdec(cid->prv >> 4);
puts(".");
printdec(cid->prv & 15);
puts(" / s/n: ");
print32(cid->psn_0 << 24 | cid->psn_1 << 16 | cid->psn_2 << 8 |
cid->psn_3);
puts(" / date: ");
printdec(cid->mdt_1 & 15);
puts("/");
printdec(2000 + ((cid->mdt_0 & 15) << 4)+((cid->mdt_1 & 0xf0) >> 4));
puts("\n");
}
unsigned int s3c6410_mmc_init (int verbose)
{
u32 reg;
u32 width;
int resp;
int hcs;
int retries = 50;
u8 response[16];
unsigned int r1[4];
struct sd_cid *sd_cid = (struct sd_cid *)response;
struct mmc_csd *csd = (struct mmc_csd *)response;
u8 *p8 = (u8 *)&r1[0];
unsigned int sd_sectors = 0;
/* we need to shift result by 8 bits spread over 4 x 32-bit regs */
u8 mangle[] = { 7, 0, 1, 2, 11, 4, 5, 6, 15, 8, 9, 10, 0, 12, 13, 14 };
int n;
hsmmc_set_gpio();
hsmmc_reset();
width = 4;
HCLK = 33000000; /* FIXME */
hsmmc_clock_onoff(0);
reg = readl(SCLK_GATE);
writel(reg | (1<<27), SCLK_GATE);
set_clock(SD_EPLL, 0x80);
s3c_hsmmc_writeb(0xe, HM_TIMEOUTCON);
set_hostctl_speed(NORMAL);
InterruptEnable(0xff, 0xff);
// dbg("HM_NORINTSTS = %x\n", s3c_hsmmc_readw(HM_NORINTSTS));
/* MMC_GO_IDLE_STATE */
issue_command(MMC_GO_IDLE_STATE, 0x00, 0, 0);
udelay(100000);
udelay(100000);
udelay(100000);
udelay(100000);
/* SDHC card? */
resp = issue_command(SD_SEND_IF_COND, 0x000001aa,
0, MMC_CMD_BCR | MMC_RSP_R7);
if (resp && ((s3c_hsmmc_readl(HM_RSPREG0) & 0xff) == 0xaa)) {
card_type = CARDTYPE_SD20; /* 2.0 SD, may not be SDHC */
hcs = 0x40000000;
}
/* Well, either way let's say hello in SD card protocol */
while (retries--) {
udelay(100000);
udelay(100000);
udelay(100000);
resp = issue_command(MMC_APP_CMD, 0x00000000, 0,
MMC_RSP_R1);
if (!resp)
continue;
resp = issue_command(SD_APP_OP_COND, hcs | 0x00300000, 0,
MMC_RSP_R3);
if (!resp)
continue;
if ((s3c_hsmmc_readl(HM_RSPREG0) >> 24) & (1 << 6)) { /* asserts block addressing */
retries = -2;
card_type = CARDTYPE_SDHC;
}
if ((s3c_hsmmc_readl(HM_RSPREG0) >> 24) & (1 << 7)) { /* not busy */
retries = -2;
if (card_type == CARDTYPE_NONE)
card_type = CARDTYPE_SD;
break;
}
}
if (retries == -1) {
puts("no response\n");
return -2;
}
if (!issue_command(MMC_ALL_SEND_CID, 0, 0, MMC_RSP_R2)) {
puts("CID broken\n");
return -3;
}
r1[0] = s3c_hsmmc_readl(HM_RSPREG3);
r1[1] = s3c_hsmmc_readl(HM_RSPREG2);
r1[2] = s3c_hsmmc_readl(HM_RSPREG1);
r1[3] = s3c_hsmmc_readl(HM_RSPREG0);
for (n = 0; n < 16; n++)
response[n] = p8[mangle[n]];
switch (card_type) {
case CARDTYPE_SD:
case CARDTYPE_SD20:
case CARDTYPE_SDHC:
if (verbose)
print_sd_cid(sd_cid);
resp = issue_command(SD_SEND_RELATIVE_ADDR, MMC_DEFAULT_RCA,
0, MMC_RSP_R6);
rca = s3c_hsmmc_readl(HM_RSPREG0) >> 16;
break;
default:
return 1;
}
/* grab the CSD */
resp = issue_command(MMC_SEND_CSD, rca << 16, 0, MMC_RSP_R2);
if (resp) {
r1[0] = s3c_hsmmc_readl(HM_RSPREG3);
r1[1] = s3c_hsmmc_readl(HM_RSPREG2);
r1[2] = s3c_hsmmc_readl(HM_RSPREG1);
r1[3] = s3c_hsmmc_readl(HM_RSPREG0);
for (n = 0; n < 16; n++)
response[n] = p8[mangle[n]];
switch (card_type) {
case CARDTYPE_SDHC:
puts(" SDHC size: ");
sd_sectors = (UNSTUFF_BITS(((u32 *)&response[0]), 48, 22)
+ 1) << 10;
break;
default:
puts(" MMC/SD size: ");
sd_sectors = ((((unsigned long)1 << csd->c_size_mult1) *
(unsigned long)(csd->c_size)) >> 9);
}
printdec(sd_sectors / 2048);
puts(" MiB\n");
} else
puts("CSD grab broken\n");
resp = issue_command(MMC_SELECT_CARD, rca<<16, 0, MMC_RSP_R1);
if (!resp)
return 1;
/* Operating Clock setting */
clock_config(2); // Divisor 1 = Base clk /2 ,Divisor 2 = Base clk /4, Divisor 4 = Base clk /8 ...
while (set_bus_width(width));
while (!check_card_status());
/* MMC_SET_BLOCKLEN */
while (!issue_command(MMC_SET_BLOCKLEN, 512, 0, MMC_RSP_R1));
s3c_hsmmc_writew(0xffff, HM_NORINTSTS);
return sd_sectors;
}
unsigned long s3c6410_mmc_bread(int dev_num, unsigned long start_blk, unsigned long blknum,
void *dst)
{
u32 blksize; //j, , Addr_temp = start_blk;
u32 dma = 0, cmd, multi; //, TotalReadByte, read_blk_cnt = 0;
HS_DMA_END = 0;
blksize = Card_OneBlockSize_ver1;
while (!check_card_status());
s3c_hsmmc_writew(s3c_hsmmc_readw(HM_NORINTSTSEN) & ~(DMA_STS_INT_EN | BLOCKGAP_EVENT_STS_INT_EN), HM_NORINTSTSEN);
s3c_hsmmc_writew((HM_NORINTSIGEN & ~(0xffff)) | TRANSFERCOMPLETE_SIG_INT_EN, HM_NORINTSIGEN);
SetSystemAddressReg((unsigned long)dst); // AHB System Address For Write
dma = 1;
set_blksize_register(7, 512); // Maximum DMA Buffer Size, Block Size
set_blkcnt_register(blknum); // Block Numbers to Write
if (movi_hc)
set_arg_register(start_blk); // Card Start Block Address to Write
else
set_arg_register(start_blk * 512); // Card Start Block Address to Write
cmd = (blknum > 1) ? 18 : 17;
multi = (blknum > 1);
set_transfer_mode_register(multi, 1, multi, 1, dma);
set_cmd_register(cmd, 1, MMC_RSP_R1);
if (wait_for_cmd_done()) {
puts("Command NOT Complete\n");
return -1;
} else
ClearCommandCompleteStatus();
check_dma_int();
while (!HS_DMA_END);
HS_DMA_END = 0;
return blknum;
}

View File

@ -1,40 +0,0 @@
#ifndef __HS_MMC_H__
#define __HS_MMC_H__
/////////////////////////////////////////////////////////////////////////////////////////////////
//#define SDHC_MONITOR (*(volatile unsigned *)0x4800004c)
//#define SDHC_SLOT_INT_STAT (*(volatile unsigned *)0x480000fc)
/////////////////////////////////////////////////////////////////////////////////////////////////
#define SD_HCLK 1
#define SD_EPLL 2
#define SD_EXTCLK 3
#define NORMAL 0
#define HIGH 1
//Normal Interrupt Signal Enable
#define READWAIT_SIG_INT_EN (1<<10)
#define CARD_SIG_INT_EN (1<<8)
#define CARD_REMOVAL_SIG_INT_EN (1<<7)
#define CARD_INSERT_SIG_INT_EN (1<<6)
#define BUFFER_READREADY_SIG_INT_EN (1<<5)
#define BUFFER_WRITEREADY_SIG_INT_EN (1<<4)
#define DMA_SIG_INT_EN (1<<3)
#define BLOCKGAP_EVENT_SIG_INT_EN (1<<2)
#define TRANSFERCOMPLETE_SIG_INT_EN (1<<1)
#define COMMANDCOMPLETE_SIG_INT_EN (1<<0)
//Normal Interrupt Status Enable
#define READWAIT_STS_INT_EN (1<<10)
#define CARD_STS_INT_EN (1<<8)
#define CARD_REMOVAL_STS_INT_EN (1<<7)
#define CARD_INSERT_STS_INT_EN (1<<6)
#define BUFFER_READREADY_STS_INT_EN (1<<5)
#define BUFFER_WRITEREADY_STS_INT_EN (1<<4)
#define DMA_STS_INT_EN (1<<3)
#define BLOCKGAP_EVENT_STS_INT_EN (1<<2)
#define TRANSFERCOMPLETE_STS_INT_EN (1<<1)
#define COMMANDCOMPLETE_STS_INT_EN (1<<0)
#endif /*__HS_MMC_H__*/

View File

@ -1,69 +0,0 @@
/*
* (C) Copyright 2007 OpenMoko, Inc.
* Author: Andy Green <andy@openmoko.com>
*
* s3c6410-specific i2c
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
#include <qi.h>
#include <i2c-bitbang.h>
#include <s3c6410.h>
static char i2c_read_sda_s3c6410(void)
{
return !!(__REG(GPBDAT) & (1 << 6));
}
static void i2c_set_s3c6410(char clock, char data)
{
if (clock) /* SCL <- input */
__REG(GPBCON) = (__REG(GPBCON) & ~(3 << (5 * 4)));
else { /* SCL <- output 0 */
__REG(GPBDAT) = (__REG(GPBDAT) & ~(1 << 5));
__REG(GPBCON) = (__REG(GPBCON) & ~(3 << (5 * 4))) | (1 << (5 * 4));
}
if (data) /* SDA <- input */
__REG(GPBCON) = (__REG(GPBCON) & ~(3 << (6 * 4)));
else { /* SDA <- output 0 */
__REG(GPBDAT) = (__REG(GPBDAT) & ~(1 << 6));
__REG(GPBCON) = (__REG(GPBCON) & ~(3 << (6 * 4))) | (1 << (6 * 4));
}
}
static void i2c_close_s3c6410(void)
{
/* set back to hardware I2C ready for Linux */
__REG(GPBCON) = (__REG(GPBCON) & ~(3 << (5 * 4))) | (2 << (5 * 4));
__REG(GPBCON) = (__REG(GPBCON) & ~(3 << (6 * 4))) | (2 << (6 * 4));
}
static void i2c_spin_s3c6410(void)
{
int n;
for (n = 0; n < 1000; n++)
__REG(GPBDAT) = __REG(GPBDAT);
}
struct i2c_bitbang bb_s3c6410 = {
.read_sda = i2c_read_sda_s3c6410,
.set = i2c_set_s3c6410,
.spin = i2c_spin_s3c6410,
.close = i2c_close_s3c6410,
};

View File

@ -1,114 +0,0 @@
#include <qi.h>
#include <neo_om_3d7k.h>
#include <s3c6410.h>
#include <serial-s3c64xx.h>
#define OM_3D7K_DEBUG_UART 3
/* out of steppingstone */
extern const struct board_variant const * get_board_variant_om_3d7k(void);
extern void port_init_om_3d7k(void);
int is_this_board_om_3d7k(void)
{
/* FIXME: find something om_3d7k specific */
return 1;
}
static void putc_om_3d7k(char c)
{
serial_putc_s3c64xx(OM_3D7K_DEBUG_UART, c);
}
int sd_card_init_om_3d7k(void)
{
extern int s3c6410_mmc_init(int verbose);
return s3c6410_mmc_init(1);
}
int sd_card_block_read_om_3d7k(unsigned char * buf, unsigned long start512,
int blocks512)
{
unsigned long s3c6410_mmc_bread(int dev_num, unsigned long blknr, unsigned long blkcnt,
void *dst);
return s3c6410_mmc_bread(0, start512, blocks512, buf);
}
/*
* our API for bootloader on this machine
*/
/* for initrd:
* .initramfs_filepath = "boot/initramfs.gz",
* and
* "root=/dev/ram ramdisk_size=6000000"
*/
static u8 get_ui_keys_om_3d7k(void)
{
u8 keys;
u8 ret;
static u8 old_keys = 0; /* previous state for debounce */
static u8 old_ret = 0; /* previous debounced output for edge detect */
/* GPN1 is MINUS on OM_3D7K, map to UI_ACTION_ADD_DEBUG, down = 1 */
keys = !!(__REG(GPMDAT) & (1 << 1));
if (keys == old_keys)
ret = keys;
else
ret = old_keys;
/* edge action */
if ((ret & 1) && !(old_ret & 1))
ret |= UI_ACTION_SKIPKERNEL;
old_keys = keys;
old_ret = ret;
return ret;
}
const struct board_api board_api_om_3d7k = {
.name = "OM_3D7K",
.linux_machine_id = 2120,
.linux_mem_start = 0x50000000,
.linux_mem_size = (128 * 1024 * 1024),
.linux_tag_placement = 0x50000000 + 0x100,
.get_board_variant = get_board_variant_om_3d7k,
.is_this_board = is_this_board_om_3d7k,
.port_init = port_init_om_3d7k,
.putc = putc_om_3d7k,
.noboot = "boot/noboot-OM_3D7K",
.append = "boot/append-OM_3D7K",
.get_ui_keys = get_ui_keys_om_3d7k,
.commandline_board = "console=tty0 "
"console=ttySAC3,115200 "
"init=/sbin/init "
"loglevel=8 "
"rootdelay=1 no_console_suspend "
"ro ",
.commandline_board_debug = " loglevel=8",
.kernel_source = {
[0] = {
.name = "SD Card rootfs",
.block_read = sd_card_block_read_om_3d7k,
.filesystem = FS_EXT2,
.partition_index = 2,
.filepath = "boot/uImage-OM_3D7K.bin",
.commandline_append = "root=/dev/mmcblk0p2 ",
},
[1] = {
.name = "SD Card backup rootfs",
.block_read = sd_card_block_read_om_3d7k,
.filesystem = FS_EXT2,
.partition_index = 3,
.filepath = "boot/uImage-OM_3D7K.bin",
.commandline_append = "root=/dev/mmcblk0p3 ",
},
},
};

View File

@ -1,935 +0,0 @@
#include <qi.h>
#include <neo_om_3d7k.h>
#include <s3c6410.h>
#include <serial-s3c64xx.h>
#include <i2c-bitbang-s3c6410.h>
#include <pcf50633.h>
#define PCF50633_I2C_ADS 0x73
const struct pcf50633_init om_3d7k_pcf50633_init[] = {
{ PCF50633_REG_OOCWAKE, 0xd3 }, /* wake from ONKEY,EXTON!,RTC,USB,ADP */
{ PCF50633_REG_OOCTIM1, 0xaa }, /* debounce 14ms everything */
{ PCF50633_REG_OOCTIM2, 0x4a },
{ PCF50633_REG_OOCMODE, 0x55 },
{ PCF50633_REG_OOCCTL, 0x47 },
{ PCF50633_REG_SVMCTL, 0x08 }, /* 3.10V SYS voltage thresh. */
{ PCF50633_REG_BVMCTL, 0x02 }, /* 2.80V BAT voltage thresh. */
{ PCF50633_REG_AUTOENA, 0x01 }, /* always on */
{ PCF50633_REG_DOWN1OUT, 0x17 }, /* 1.2V (0x17 * .025V + 0.625V) */
/* all of these are down in 3d7k suspend except MEMLDO */
{ PCF50633_REG_DOWN1ENA, 0x02 }, /* enabled if GPIO1 = HIGH */
{ PCF50633_REG_DOWN2ENA, 0x02 }, /* enabled if GPIO1 = HIGH */
{ PCF50633_REG_HCLDOENA, 0x00 }, /* Camera 2.8V power off */
{ PCF50633_REG_MEMLDOENA, 0x01 }, /* Memory LDO always ON */
{ PCF50633_REG_LDO1ENA, 0x00 }, /* Gsensor power off */
{ PCF50633_REG_LDO2ENA, 0x00 }, /* Camera 1.5V power off */
{ PCF50633_REG_LDO3ENA, 0x02 }, /* Codec power ON */
{ PCF50633_REG_LDO4ENA, 0x02 }, /* SD power ON */
{ PCF50633_REG_LDO5ENA, 0x00 }, /* BT power off */
{ PCF50633_REG_LDO6ENA, 0x00 }, /* LCM power off */
{ PCF50633_REG_INT1M, 0x00 },
{ PCF50633_REG_INT2M, 0x00 },
{ PCF50633_REG_INT3M, 0x00 },
{ PCF50633_REG_INT4M, 0x00 },
{ PCF50633_REG_INT5M, 0x00 },
{ PCF50633_REG_MBCC2, 0x28 }, /* Vbatconid=2.7V, Vmax=4.20V */
{ PCF50633_REG_MBCC3, 0x19 }, /* 25/255 == 98mA pre-charge */
{ PCF50633_REG_MBCC4, 0xff }, /* 255/255 == 1A adapter fast */
{ PCF50633_REG_MBCC5, 0xff }, /* 255/255 == 1A USB fast */
{ PCF50633_REG_MBCC6, 0x00 }, /* cutoff current 1/32 * Ichg */
/* current prototype is pulling > 100mA at startup */
{ PCF50633_REG_MBCC7, 0xc1 }, /* 2.2A max bat curr, USB 500mA */
{ PCF50633_REG_MBCC8, 0x00 },
{ PCF50633_REG_MBCC1, 0xff }, /* chgena */
{ PCF50633_REG_BBCCTL, 0x19 }, /* 3V, 200uA, on */
{ PCF50633_REG_OOCSHDWN, 0x04 }, /* defeat 8s death from lowsys on A5 */
};
static const struct board_variant board_variants[] = {
[0] = {
.name = "OM 3D7K unknown",
.machine_revision = 0
},
[1] = {
.name = "OM 3D7K A1",
.machine_revision = 1
},
[2] = {
.name = "OM 3D7K A2",
.machine_revision = 2
},
[3] = {
.name = "OM 3D7K A3",
.machine_revision = 3
},
[4] = {
.name = "OM 3D7K A4",
.machine_revision = 4
},
[5] = {
.name = "OM 3D7K A5",
.machine_revision = 5
},
[6] = {
.name = "OM 3D7K A6",
.machine_revision = 6
},
[7] = {
.name = "OM 3D7K A7",
.machine_revision = 7
}
};
#define S0 0
#define S1 1
#define SIN 2
#define SHOLD 3
#define SNP 0
#define SPD 1
#define SPU 2
void port_init_om_3d7k(void)
{
int n;
/*
* We leave iROM up for clock and power otherwise resume fails
*/
__REG(EINT_MASK) =
(0 << 4) /* PMU interrupt */
;
__REG(PWR_CFG) =
(1 << 17) | /* kill OSCotg clock pad */
(0 << 0) /* 27MHz osc off */
;
__REG(STOP_MEM_CFG) =
(0 << 6) | /* modem */
(0 << 5) | /* host IF */
(1 << 4) | /* OTG */
(1 << 3) | /* HSMMC */
(1 << 2) | /* iROM */
(0 << 1) | /* IRDA */
(1 << 0) /* NFCON / steppingstone */
;
__REG(NOR_CFG) =
(1 << 31) | /* reserved */
(1 << 30) | /* iROM */
(0x1fff << 17) | /* reserved */
(1 << 16) | /* ETM domain */
(1 << 15) | /* S domain */
(1 << 14) | /* F domain / LCD */
(0 << 13) | /* P domain / 2D, scaler, TV encoder */
(0 << 12) | /* I domain / JPEG / Camera */
(1 << 11) | /* reserved */
(0 << 10) | /* G domain / 3D */
(0 << 9) | /* V domain / MFC */
(1 << 8) | /* reserved */
(0x00 << 0) /* reserved */
;
__REG(HCLK_GATE) =
(0 << 31) | /* 3D unit */
(1 << 30) | /* reserved */
(0 << 29) | /* USB host */
(0 << 28) | /* "security subsystem" */
(0 << 27) | /* SDMA1 */
(0 << 26) | /* SDMA0 */
(1 << 25) | /* iROM */
(1 << 24) | /* DDR 1 */
(1 << 23) | /* reserved */
(1 << 22) | /* DMC1 */
(1 << 21) | /* SROM / NAND controller / NAND */
(0 << 20) | /* USB OTG */
(0 << 19) | /* HSMMC 2 */
(0 << 18) | /* HSMMC 1 */
(1 << 17) | /* HSMMC 0 */
(0 << 16) | /* MDP */
(0 << 15) | /* direct host */
(0 << 14) | /* indirect host */
(1 << 13) | /* DMA1 */
(1 << 12) | /* DMA0 */
(0 << 11) | /* JPEG */
(0 << 10) | /* camera */
(0 << 9) | /* scaler */
(0 << 8) | /* 2D */
(0 << 7) | /* TV */
(1 << 6) | /* reserved */
(1 << 5) | /* POST0 */
(1 << 4) | /* rotator */
(1 << 3) | /* LCD controller */
(1 << 2) | /* TZICs */
(1 << 1) | /* VICs */
(0 << 0) /* MFC */
;
__REG(PCLK_GATE) =
(0x1f << 28) | /* reserved */
(0 << 27) | /* I2C1 */
(0 << 26) | /* IIS2 */
(1 << 25) | /* reserved */
(0 << 24) | /* security key */
(1 << 23) | /* chip ID */
(0 << 22) | /* SPI1 */
(0 << 21) | /* SPI0 */
(0 << 20) | /* HSI RX */
(0 << 19) | /* HSI TX */
(1 << 18) | /* GPIO */
(1 << 17) | /* I2C 0 */
(1 << 16) | /* IIS1 */
(1 << 15) | /* IIS0 */
(0 << 14) | /* AC97 */
(0 << 13) | /* TZPC */
(0 << 12) | /* TS ADC */
(0 << 11) | /* keypad */
(0 << 10) | /* IRDA */
(0 << 9) | /* PCM1 */
(0 << 8) | /* PCM0 */
(1 << 7) | /* PWM */
(0 << 6) | /* RTC */
(1 << 5) | /* WDC */
(1 << 4) | /* UART3 */
(1 << 3) | /* UART2 */
(1 << 2) | /* UART1 */
(1 << 1) | /* UART0 */
(0 << 0) /* MFC */
;
__REG(SCLK_GATE) =
(1 << 31) |
(0 << 30) | /* USB Host */
(0 << 29) | /* HSMMC2 48MHz */
(0 << 28) | /* HSMMC1 48MHz */
(0 << 27) | /* HSMMC0 48MHz */
(0 << 26) | /* HSMMC2 */
(0 << 25) | /* HSMMC1 */
(1 << 24) | /* HSMMC0 */
(0 << 23) | /* SPI1 - 48MHz */
(0 << 22) | /* SPI0 - 48MHz */
(0 << 21) | /* SPI1 */
(0 << 20) | /* SPI0 */
(0 << 19) | /* TV DAC */
(0 << 18) | /* TV encoder */
(0 << 17) | /* scaler 27 */
(0 << 16) | /* scaler */
(1 << 15) | /* LCD 27MHz */
(1 << 14) | /* LCD */
(1 << 13) | /* camera and LCD */
(1 << 12) | /* POST0 */
(1 << 11) | /* AUDIO2 */
(1 << 10) | /* POST0 again */
(1 << 9) | /* IIS1 */
(1 << 8) | /* IIS0 */
(0 << 7) | /* security */
(0 << 6) | /* IRDA */
(1 << 5) | /* UART */
(1 << 4) | /* reserved */
(0 << 3) | /* MFC */
(0 << 2) | /* Cam */
(0 << 1) | /* JPEG */
(1 << 0) /* reserved */
;
/* ---------------------------- Port A ---------------------------- */
__REG(GPACON) =
(2 << 0) | /* GPA0 - UART_RXD0 */
(2 << 4) | /* GPA1 - UART_TXD0 */
(2 << 8) | /* GPA2 - UART_CTS0 */
(2 << 12) | /* GPA3 - UART_RTS0 */
(2 << 16) | /* GPA4 - UART_RXD1 */
(2 << 20) | /* GPA5 - UART_TXD1 */
(2 << 24) | /* GPA6 - UART_CTS1 */
(2 << 28) /* GPA7 - UART_RTS1 */
;
__REG(GPAPUD) = /* pullup inputs */
0x2222
;
__REG(GPADAT) = 0; /* just for determinism */
__REG(GPACONSLP) =
(SIN << 0) | /* GPA0 bluetooth down in suspend*/
(S0 << 2) | /* GPA1 */
(SIN << 4) | /* GPA2 */
(S0 << 6) | /* GPA3 */
(SIN << 8) | /* GPA4 gsm */
(SHOLD << 10) | /* GPA5 */
(SIN << 12) | /* GPA6 */
(SHOLD << 14) /* GPA7 */
;
__REG(GPAPUDSLP) =
(SPD << 0) | /* GPA0 */
(SNP << 2) | /* GPA1 */
(SPD << 4) | /* GPA2 */
(SNP << 6) | /* GPA3 */
(SPU << 8) | /* GPA4 */
(SNP << 10) | /* GPA5 */
(SPU << 12) | /* GPA6 */
(SNP << 14) /* GPA7 */
;
/* ---------------------------- Port B ---------------------------- */
__REG(GPBCON) =
(1 << 0) | /* GPB0 - (NC) output low */
(1 << 4) | /* GPB1 - (NC) output low */
(2 << 8) | /* GPB2 - UART_RXD3 */
(2 << 12) | /* GPB3 - UART_TXD3 */
(1 << 16) | /* GPB4 - (NC) output low */
(1 << 20) | /* GPB5 - (I2C BB SCL) OUTPUT */
(1 << 24) /* GPB6 - (I2C BB SDA) OUTPUT */
;
__REG(GPBPUD) = /* all pullup and pulldown disabled */
(SPU << (2 * 2)) /* pullup console rx */
;
__REG(GPBDAT) = 0; /* just for determinism */
__REG(GPBCONSLP) =
(SHOLD << 0) | /* GPB0 */
(SHOLD << 2) | /* GPB1 */
(SIN << 4) | /* GPB2 */
(SHOLD << 6) | /* GPB3 */
(SHOLD << 8) | /* GPB4 */
(SIN << 10) | /* GPB5 ext pullup */
(SIN << 12) /* GPB6 ext pullup */
;
__REG(GPBPUDSLP) =
(SNP << 0) | /* GPB0 */
(SNP << 2) | /* GPB1 */
(SPU << 4) | /* GPB2 */
(SNP << 6) | /* GPB3 */
(SNP << 8) | /* GPB4 */
(SNP << 10) | /* GPB5 */
(SNP << 12) /* GPB6 */
;
/* ---------------------------- Port C ---------------------------- */
__REG(GPCCON) =
(0 << 0) | /* GPC0 - SPI_MISO0 INPUT motion sensor spi */
(1 << 4) | /* GPC1 - SPI_CLK0 OUTPUT */
(1 << 8) | /* GPC2 - SPI_MOSI0 OUTPUT */
(1 << 12) | /* GPC3 - SPI_CS0 OUTPUT */
(1 << 16) | /* GPC4 - (NC) OUTPUT lcm spi*/
(1 << 20) | /* GPC5 - SPI_CLK1 OUTPUT */
(1 << 24) | /* GPC6 - SPI_MOSI1 OUTPUT */
(1 << 28) /* GPC7 - SPI_CS1 OUTPUT */
;
__REG(GPCPUD) =
(SPD << 0)
;
__REG(GPCDAT) = 0; /* just for determinism */
__REG(GPCCONSLP) = /* both peripherals down in suspend */
(SIN << 0) | /* GPC0 */
(S0 << 2) | /* GPC1 */
(S0 << 4) | /* GPC2 */
(S0 << 6) | /* GPC3 */
(SIN << 8) | /* GPC4 */
(S0 << 10) | /* GPC5 */
(S0 << 12) | /* GPC6 */
(S0 << 14) /* GPC7 */
;
__REG(GPCPUDSLP) =
(SPD << 0) | /* GPC0 */
(SNP << 2) | /* GPC1 */
(SNP << 4) | /* GPC2 */
(SNP << 6) | /* GPC3 */
(SPD << 8) | /* GPC4 */
(SNP << 10) | /* GPC5 */
(SNP << 12) | /* GPC6 */
(SNP << 14) /* GPC7 */
;
/* ---------------------------- Port D ---------------------------- */
__REG(GPDCON) =
(3 << 0) | /* GPD0 - I2S_CLK0 */
(3 << 4) | /* GPD1 - I2S_CDCLK0 */
(3 << 8) | /* GPD2 - I2S_LRCLK0 */
(3 << 12) | /* GPD3 - I2S_DI */
(3 << 16) /* GPD4 - I2S_DO */
;
__REG(GPDPUD) = 0; /* all pullup and pulldown disabled */
__REG(GPDDAT) = 0; /* just for determinism */
__REG(GPDCONSLP) =
(S0 << 0) | /* GPD0 */
(S0 << 2) | /* GPD1 */
(S0 << 4) | /* GPD2 */
(SIN << 6) | /* GPD3 */
(S0 << 8) /* GPD4 */
;
__REG(GPDPUDSLP) =
(SNP << 0) | /* GPD0 */
(SNP << 2) | /* GPD1 */
(SNP << 4) | /* GPD2 */
(SPD << 6) | /* GPD3 */
(SNP << 8) /* GPD4 */
;
/* ---------------------------- Port E ---------------------------- */
__REG(GPECON) =
(3 << 0) | /* GPE0 - PCM_SCLK1 */
(3 << 4) | /* GPE1 - PCM_EXTCLK1 */
(3 << 8) | /* GPE2 - PCM_FSYNC1 */
(3 << 12) | /* GPE3 - PCM_SIN */
(3 << 16) /* GPE4 - PCM_SOUT */
;
__REG(GPEPUD) = 0; /* all pullup and pulldown disabled */
__REG(GPEDAT) = 0; /* just for determinism */
__REG(GPECONSLP) =
(S0 << 0) | /* GPE0 */
(S0 << 2) | /* GPE1 */
(S0 << 4) | /* GPE2 */
(SIN << 6) | /* GPE3 */
(S0 << 8) /* GPE4 */
;
__REG(GPEPUDSLP) =
(SNP << 0) | /* GPE0 */
(SNP << 2) | /* GPE1 */
(SNP << 4) | /* GPE2 */
(SPD << 6) | /* GPE3 */
(SNP << 8) /* GPE4 */
;
/* ---------------------------- Port F ---------------------------- */
__REG(GPFCON) =
(2 << 0) | /* GPF0 - CAMIF_CLK */
(2 << 2) | /* GPF1 - CAMIF_HREF */
(2 << 4) | /* GPF2 - CAMIF_PCLK */
(2 << 6) | /* GPF3 - CAMIF_RSTn */
(2 << 8) | /* GPF4 - CAMIF_VSYNC */
(2 << 10) | /* GPF5 - CAMIF_YDATA0 */
(2 << 12) | /* GPF6 - CAMIF_YDATA1 */
(2 << 14) | /* GPF7 - CAMIF_YDATA2 */
(2 << 16) | /* GPF8 - CAMIF_YDATA3 */
(2 << 18) | /* GPF9 - CAMIF_YDATA4 */
(2 << 20) | /* GPF10 - CAMIF_YDATA5 */
(2 << 22) | /* GPF11 - CAMIF_YDATA6 */
(2 << 24) | /* GPF12 - CAMIF_YDATA7 */
(1 << 26) | /* GPF13 - OUTPUT Vibrator */
(1 << 28) | /* GPF14 - output not CLKOUT0 */
(1 << 30) /* GPF15 - OUTPUT CAM_PWRDN */
;
__REG(GPFPUD) =
(SPD << (2 * 12)) |
(SPD << (2 * 11)) |
(SPD << (2 * 10)) |
(SPD << (2 * 9)) |
(SPD << (2 * 8)) |
(SPD << (2 * 7)) |
(SPD << (2 * 6)) |
(SPD << (2 * 5)); /* all cam data pulldown */
__REG(GPFDAT) = (1 << 15); /* assert CAM_PWRDN */
__REG(GPFCONSLP) =
(S0 << 0) | /* GPF0 */
(S0 << 2) | /* GPF1 */
(SIN << 4) | /* GPF2 */
(S0 << 6) | /* GPF3 */
(S0 << 8) | /* GPF4 */
(SIN << 10) | /* GPF5 */
(SIN << 12) | /* GPF6 */
(SIN << 14) | /* GPF7 */
(SIN << 16) | /* GPF8 */
(SIN << 18) | /* GPF9 */
(SIN << 20) | /* GPF10 */
(SIN << 22) | /* GPF11 */
(SIN << 24) | /* GPF12 */
(S0 << 26) | /* GPF13 */
(S0 << 28) | /* GPF14 */
(S0 << 30) /* GPF15 */
;
__REG(GPFPUDSLP) =
(SPD << 4) | /* GPF2 - pull down */
(SPD << 10) | /* GPF5 - pull down */
(SPD << 12) | /* GPF6 - pull down */
(SPD << 14) | /* GPF7 - pull down */
(SPD << 16) | /* GPF8 - pull down */
(SPD << 18) | /* GPF9 - pull down */
(SPD << 20) | /* GPF10 - pull down */
(SPD << 22) | /* GPF11 - pull down */
(SPD << 24) /* GPF12 - pull down */
;
/* ---------------------------- Port G ---------------------------- */
__REG(GPGCON) =
(2 << 0) | /* GPG0 - MMC_CLK0 */
(2 << 4) | /* GPG1 - MMC_CMD0 */
(2 << 8) | /* GPG2 - MMC_DATA00 */
(2 << 12) | /* GPG3 - MMC_DATA10 */
(2 << 16) | /* GPG4 - MMC_DATA20 */
(2 << 20) | /* GPG5 - MMC_DATA30 */
(2 << 24) /* GPG6 - (NC) MMC CARD DETECT */
;
__REG(GPGPUD) = (1 << (6 * 2)); /* pull down card detect */
__REG(GPGDAT) = 0; /* just for determinism */
__REG(GPGCONSLP) =
(SIN << 0) | /* GPG0 - it's not powered*/
(SIN << 2) | /* GPG1 */
(SIN << 4) | /* GPG2 */
(SIN << 6) | /* GPG3 */
(SIN << 8) | /* GPG4 */
(SIN << 10) | /* GPG5 */
(SIN << 12) /* GPG6 */
;
__REG(GPGPUDSLP) =
(SPD << 0) | /* GPG0 - it's not powered*/
(SPD << 2) | /* GPG1 */
(SPD << 4) | /* GPG2 */
(SPD << 6) | /* GPG3 */
(SPD << 8) | /* GPG4 */
(SPD << 10) | /* GPG5 */
(SPD << 12) /* GPG6 */
;
/* ---------------------------- Port H ---------------------------- */
__REG(GPHCON0) =
(1 << 0) | /* GPH0 - NC OUT 0 */
(1 << 4) | /* GPH1 - NC OUT 0 */
(1 << 8) | /* GPH2 - NC OUT 0 */
(1 << 12) | /* GPH3 - NC OUT 0 */
(1 << 16) | /* GPH4 - NC OUT 0 */
(1 << 20) | /* GPH5 - NC OUT 0 */
(1 << 24) | /* GPH6 - OUTPUT nBT_RESET */
(0 << 28) /* GPH7 - INPUT HDQ */
;
__REG(GPHCON1) =
(1 << 0) | /* GPH8 - OUTPUT BT PIO5 */
(0 << 4) /* GPH9 - INPUT LED INT */
;
__REG(GPHPUD) = (SPU << (9 * 2)) | (SPU << (7 * 2));
__REG(GPHDAT) = 0;
__REG(GPHCONSLP) =
(S0 << 0) | /* GPH0 */
(S0 << 2) | /* GPH1 */
(S0 << 4) | /* GPH2 */
(S0 << 6) | /* GPH3 */
(S0 << 8) | /* GPH4 */
(S0 << 10) | /* GPH5 */
(S0 << 12) | /* GPH6 */
(SIN << 14) | /* GPH7 - INPUT (HDQ) */
(S0 << 16) | /* GPH8 */
(SIN << 18) /* GPH9 */
;
__REG(GPHPUDSLP) = (SPU << (7 * 2)) | (SPU << (9 * 2));
/* ---------------------------- Port I ---------------------------- */
__REG(GPICON) =
(0 << 0) | /* GPI0 - INPUT version b0 */
(0 << 2) | /* GPI1 - INPUT version b1 */
(2 << 4) | /* GPI2 - LCD_VD2 */
(2 << 6) | /* GPI3 - LCD_VD3 */
(2 << 8) | /* GPI4 - LCD_VD4 */
(2 << 10) | /* GPI5 - LCD_VD5 */
(2 << 12) | /* GPI6 - LCD_VD6 */
(2 << 14) | /* GPI7 - LCD_VD7 */
(0 << 16) | /* GPI8 - INPUT version b2 */
(2 << 18) | /* GPI9 - LCD_VD9 */
(2 << 20) | /* GPI10 - LCD_VD10 */
(2 << 22) | /* GPI11 - LCD_VD11 */
(2 << 24) | /* GPI12 - LCD_VD12 */
(2 << 26) | /* GPI13 - LCD_VD13 */
(2 << 28) | /* GPI14 - LCD_VD14 */
(2 << 30) /* GPI15 - LCD_VD15 */
;
__REG(GPIPUD) = 0; /* all pullup and pulldown disabled */
__REG(GPIDAT) = 0; /* just for determinism */
__REG(GPICONSLP) =
(SIN << 0) | /* GPI0 - input */
(SIN << 2) | /* GPI1 - input */
(S0 << 4) | /* GPI2 - input */
(S0 << 6) | /* GPI3 - input */
(S0 << 8) | /* GPI4 - input */
(S0 << 10) | /* GPI5 - input */
(S0 << 12) | /* GPI6 - input */
(S0 << 14) | /* GPI7 - input */
(SIN << 16) | /* GPI8 - input */
(S0 << 18) | /* GPI9 - input */
(S0 << 20) | /* GPI10 - input */
(S0 << 22) | /* GPI11 - input */
(S0 << 24) | /* GPI12 - input */
(S0 << 26) | /* GPI13 - input */
(S0 << 28) | /* GPI14 - input */
(S0 << 30) /* GPI15 - input */
;
__REG(GPIPUDSLP) =
(1 << 0) | /* GPI0 - pull down */
(1 << 2) | /* GPI1 - pull down */
(1 << 16) /* GPI8 - pull down */
;
/* ---------------------------- Port J ---------------------------- */
__REG(GPJCON) =
(2 << 0) | /* GPJ0 - LCD_VD16 */
(2 << 2) | /* GPJ1 - LCD_VD17 */
(2 << 4) | /* GPJ2 - LCD_VD18 */
(2 << 6) | /* GPJ3 - LCD_VD19 */
(2 << 8) | /* GPJ4 - LCD_VD20 */
(2 << 10) | /* GPJ5 - LCD_VD21 */
(2 << 12) | /* GPJ6 - LCD_VD22 */
(2 << 14) | /* GPJ7 - LCD_VD23 */
(2 << 16) | /* GPJ8 - LCD_HSYNC */
(2 << 18) | /* GPJ9 - LCD_VSYNC */
(2 << 20) | /* GPJ10 - LCD_VDEN */
(2 << 22) /* GPJ11 - LCD_VCLK */
;
__REG(GPJPUD) = 0; /* all pullup and pulldown disabled */
__REG(GPJDAT) = 0; /* just for determinism */
__REG(GPJCONSLP) =
(S0 << 0) | /* GPJ0 */
(S0 << 2) | /* GPJ1 */
(S0 << 4) | /* GPJ2 */
(S0 << 6) | /* GPJ3 */
(S0 << 8) | /* GPJ4 */
(S0 << 10) | /* GPJ5 */
(S0 << 12) | /* GPJ6 */
(S0 << 14) | /* GPJ7 */
(S0 << 16) | /* GPJ8 */
(S0 << 18) | /* GPJ9 */
(S0 << 20) | /* GPJ10 */
(S0 << 22) /* GPJ11 */
;
__REG(GPJPUDSLP) =
0
;
/* ---------------------------- Port K ---------------------------- */
__REG(GPKCON0) =
(1 << 0) | /* GPK0 - OUTPUT NC */
(1 << 4) | /* GPK1 - OUTPUT NC */
(1 << 8) | /* GPK2 - OUTPUT (nMODEM_ON) */
(1 << 12) | /* GPK3 - OUTPUT (LED_TRIG) */
(1 << 16) | /* GPK4 - OUTPUT (LED_EN) */
(0 << 20) | /* GPK5 - OUTPUT NC */
(1 << 24) | /* GPK6 - OUTPUT (LCD_RESET) */
(0 << 28) /* GPK7 - OUTPUT NC */
;
__REG(GPKCON1) =
(1 << 0) | /* GPK8 - OUTPUT NC */
(1 << 4) | /* GPK9 - OUTPUT NC */
(1 << 8) | /* GPK10 - OUTPUT NC */
(1 << 12) | /* GPK11 - OUTPUT NC */
(1 << 16) | /* GPK12 - OUTPUT NC */
(1 << 20) | /* GPK13 - OUTPUT NC */
(1 << 24) | /* GPK14 - OUTPUT NC */
(1 << 28) /* GPK15 - OUTPUT NC */
;
__REG(GPKPUD) = 0;
__REG(GPKDAT) = /* rest output 0 */
(SHOLD << (2 * 2)) | /* nMODEM_ON */
(SHOLD << (2 * 3)) | /* LED_TRIG */
(SHOLD << (2 * 4)) | /* LED_EN */
(S0 << (2 * 6)) /* LCD_RESET */
;
/* ---------------------------- Port L ---------------------------- */
__REG(GPLCON0) =
(1 << 0) | /* GPL0 - OUTPUT (NC) */
(1 << 4) | /* GPL1 - OUTPUT (NC) */
(1 << 8) | /* GPL2 - OUTPUT (NC) */
(1 << 12) | /* GPL3 - OUTPUT (NC) */
(1 << 16) | /* GPL4 - OUTPUT (NC) */
(1 << 20) | /* GPL5 - OUTPUT (NC) */
(1 << 24) | /* GPL6 - OUTPUT (NC) */
(1 << 28) /* GPL7 - OUTPUT (NC) */
;
__REG(GPLCON1) =
(1 << 0) | /* GPL8 - OUTPUT (NC) */
(1 << 4) | /* GPL9 - OUTPUT (NC) */
(1 << 8) | /* GPL10 - OUTPUT (NC) */
(1 << 12) | /* GPL11 - OUTPUT (NC) */
(1 << 16) | /* GPL12 - OUTPUT (NC) */
(1 << 20) | /* GPL13 - OUTPUT (NC) */
(1 << 24) /* GPL14 - OUTPUT (NC) */
;
__REG(GPLPUD) = 0; /* all pullup and pulldown disabled */
__REG(GPLDAT) = 0;
/* ---------------------------- Port M ---------------------------- */
__REG(GPMCON) =
(1 << 0) | /* GPM0 - OUTPUT (TP_RESET) */
(1 << 4) | /* GPM1 - OUTPUT (NC) */
(1 << 8) | /* GPM2 - OUTPUT (NC) */
(1 << 12) | /* GPM3 - OUTPUT (NC) */
(0 << 16) | /* GPM4 - INPUT (nUSB_FLT) */
(0 << 20) /* GPM5 - INPUT (nUSB_OC) */
;
__REG(GPMPUD) = (2 << (4 * 2)) | (2 << (5 * 2)); /* Pup on inputs */
__REG(GPMDAT) = 0;
/* ---------------------------- Port N ---------------------------- */
__REG(GPNCON) =
(2 << 0) | /* GPN0 - EXINT0 nG1INT1 */
(2 << 2) | /* GPN1 - EXINT1 KEY_MINUS */
(2 << 4) | /* GPN2 - EXINT2 KEY_PLUS */
(2 << 6) | /* GPN3 - EXINT3 PWR_IND */
(2 << 8) | /* GPN4 - EXINT4 PWR_IRQ */
(2 << 10) | /* GPN5 - EXINT5 nTOUCH */
(2 << 12) | /* GPN6 - EXINT6 nJACK_INSERT */
(1 << 14) | /* GPN7 - EXINT7 NC OUTPUT */
(2 << 16) | /* GPN8 - EXINT8 nHOLD */
(2 << 18) | /* GPN9 - EXINT9 WLAN_WAKEUP */
(2 << 20) | /* GPN10 - EXINT10 nG1INT2 */
(2 << 22) | /* GPN11 - EXINT11 nIO1 */
(2 << 24) | /* GPN12 - EXINT12 nONKEYWAKE */
(0 << 26) | /* GPN13 - INPUT (iROM CFG0) */
(0 << 28) | /* GPN14 - INPUT (iROM CFG1) */
(0 << 30) /* GPN15 - INPUT (iROM CFG2) */
;
__REG(GPNPUD) =
(SPD << 0) | /* GPN0 - EXINT0 nG1INT1 */
(SPU << 2) | /* GPN1 - EXINT1 KEY_MINUS */
(SPU << 4) | /* GPN2 - EXINT2 KEY_PLUS */
(SPU << 6) | /* GPN3 - EXINT3 PWR_IND */
(SNP << 8) | /* GPN4 - EXINT4 PWR_IRQ */
(SPU << 10) | /* GPN5 - EXINT5 nTOUCH */
(SNP << 12) | /* GPN6 - EXINT6 nJACK_INSERT */
(SNP << 14) | /* GPN7 - EXINT7 NC OP */
(SPU << 16) | /* GPN8 - EXINT8 nHOLD */
(SPU << 18) | /* GPN9 - EXINT9 BT_WAKEUP */
(SPD << 20) | /* GPN10 - EXINT10 nG1INT2 */
(SPD << 22) | /* GPN11 - EXINT11 nIO1 */
(SPU << 24) | /* GPN12 - EXINT12 nONKEYWAKE */
(SPD << 26) | /* GPN13 - INPUT (iROM CFG0) */
(SPD << 28) | /* GPN14 - INPUT (iROM CFG1) */
(SPD << 30) /* GPN15 - INPUT (iROM CFG2) */
;
__REG(GPNDAT) = 0;
/* ---------------------------- Port O ---------------------------- */
__REG(GPOCON) =
(2 << 0) | /* GPO0 - XM0CS2 (nNANDCS0) */
(1 << 2) | /* GPO1 - OUTPUT (nMODEM_RESET) */
(1 << 4) | /* GPO2 - OUTPUT (NC) */
(1 << 6) | /* GPO3 - OUTPUT (NC) */
(1 << 8) | /* GPO4 - OUTPUT (NC) */
(1 << 10) | /* GPO5 - OUTPUT (NC) */
(1 << 12) | /* GPO6 - OUTPUT (NC) */
(1 << 14) | /* GPO7 - OUTPUT (NC) */
(1 << 16) | /* GPO8 - OUTPUT (NC) */
(1 << 18) | /* GPO9 - OUTPUT (NC) */
(1 << 20) | /* GPO10 - OUTPUT (NC) */
(1 << 22) | /* GPO11 - OUTPUT (NC) */
(1 << 24) | /* GPO12 - OUTPUT (NC) */
(1 << 26) | /* GPO13 - OUTPUT (NC) */
(1 << 28) | /* GPO14 - OUTPUT (NC) */
(1 << 30) /* GPO15 - OUTPUT (NC) */
;
__REG(GPOPUD) = 0; /* no pulling */
__REG(GPODAT) = (1 << 15); /* assert CAM_PWRDN */
__REG(GPOCONSLP) =
(SHOLD << 0) | /* GPO0 - hold state */
(SHOLD << 2) | /* GPO1 - OUTPUT 1 (do not reset modem) */
(S0 << 4) | /* GPO2 - OUTPUT 0 */
(S0 << 6) | /* GPO3 - OUTPUT 0 */
(S0 << 8) | /* GPO4 - OUTPUT 0 */
(S0 << 10) | /* GPO5 - OUTPUT 0 */
(S0 << 12) | /* GPO6 - OUTPUT 0 */
(S0 << 14) | /* GPO7 - OUTPUT 0 */
(S0 << 16) | /* GPO8 - OUTPUT 0 */
(S0 << 18) | /* GPO9 - OUTPUT 0 */
(S0 << 20) | /* GPO10 - OUTPUT 0 */
(S0 << 22) | /* GPO11 - OUTPUT 0 */
(S0 << 24) | /* GPO12 - OUTPUT 0 */
(S0 << 26) | /* GPO13 - OUTPUT 0 */
(S0 << 28) | /* GPO14 - OUTPUT 0 */
(S0 << 30) /* GPO15 - OUTPUT 0 */
;
__REG(GPOPUDSLP) =
0
;
/* ---------------------------- Port P ---------------------------- */
__REG(GPPCON) =
(1 << 0) | /* GPP0 - input (NC) */
(1 << 2) | /* GPP1 - input (NC) */
(1 << 4) | /* GPP2 - input (NC) */
(1 << 6) | /* GPP3 - input (NC) */
(1 << 8) | /* GPP4 - input (NC) */
(1 << 10) | /* GPP5 - input (NC) */
(1 << 12) | /* GPP6 - input (NC) */
(1 << 14) | /* GPP7 - input (NC) */
(1 << 16) | /* GPP8 - input (NC) */
(1 << 18) | /* GPP9 - input (NC) */
(1 << 20) | /* GPP10 - input (NC) */
(1 << 22) | /* GPP11 - input (NC) */
(1 << 24) | /* GPP12 - input (NC) */
(1 << 26) | /* GPP13 - input (NC) */
(1 << 28) /* GPP14 - input (NC) */
;
__REG(GPPPUD) = 0; /* no pull */
__REG(GPPDAT) = 0;
__REG(GPPCONSLP) =
(S0 << 0) | /* GPP0 - OUTPUT 0 */
(S0 << 2) | /* GPP1 - OUTPUT 0 */
(S0 << 4) | /* GPP2 - OUTPUT 0 */
(S0 << 6) | /* GPP3 - OUTPUT 0 */
(S0 << 8) | /* GPP4 - OUTPUT 0 */
(S0 << 10) | /* GPP5 - OUTPUT 0 */
(S0 << 12) | /* GPP6 - OUTPUT 0 */
(S0 << 14) | /* GPP7 - OUTPUT 0 */
(S0 << 16) | /* GPP8 - OUTPUT 0 */
(S0 << 18) | /* GPP9 - OUTPUT 0 */
(S0 << 20) | /* GPP10 - OUTPUT 0 */
(S0 << 22) | /* GPP11 - OUTPUT 0 */
(S0 << 24) | /* GPP12 - OUTPUT 0 */
(S0 << 26) | /* GPP13 - OUTPUT 0 */
(S0 << 28) /* GPP14 - OUTPUT 0 */
;
__REG(GPPPUDSLP) = 0;
/* ---------------------------- Port Q ---------------------------- */
__REG(GPQCON) =
(1 << 0) | /* GPQ0 - OUTPUT (NC) */
(1 << 2) | /* GPQ1 - OUTPUT (NC) */
(1 << 4) | /* GPQ2 - OUTPUT (NC) */
(1 << 6) | /* GPQ3 - OUTPUT (NC) */
(1 << 8) | /* GPQ4 - OUTPUT (NC) */
(1 << 10) | /* GPQ5 - OUTPUT (NC) */
(1 << 12) | /* GPQ6 - OUTPUT (NC) */
(1 << 14) | /* GPQ7 - OUTPUT (NC) */
(1 << 16) /* GPQ8 - OUTPUT (NC) */
;
__REG(GPQPUD) = 0; /* no pull */
__REG(GPQDAT) = 0;
__REG(GPQCONSLP) =
(S0 << 0) | /* GPQ0 - OUTPUT 0 */
(S0 << 2) | /* GPQ1 - OUTPUT 0 */
(S0 << 4) | /* GPQ2 - OUTPUT 0 */
(S0 << 6) | /* GPQ3 - OUTPUT 0 */
(S0 << 8) | /* GPQ4 - OUTPUT 0 */
(S0 << 10) | /* GPQ5 - OUTPUT 0 */
(S0 << 12) | /* GPQ6 - OUTPUT 0 */
(S0 << 14) | /* GPQ7 - OUTPUT 0 */
(S0 << 16) /* GPQ8 - OUTPUT 0 */
;
__REG(GPQPUDSLP) = 0;
/* LCD Controller enable */
__REG(0x7410800c) = 0;
__REG(0x7f0081a0) = 0xbfc115c1;
/*
* We have to talk to the PMU a little bit
*/
for (n = 0; n < ARRAY_SIZE(om_3d7k_pcf50633_init); n++)
i2c_write_sync(&bb_s3c6410, PCF50633_I2C_ADS,
om_3d7k_pcf50633_init[n].index,
om_3d7k_pcf50633_init[n].value);
}
int om_3d7k_get_pcb_revision(void)
{
u32 v = __REG(GPIDAT);
/*
* PCB rev is 3 bit code (info from Dkay)
* (b2, b1, b0) = (0,0,1) => pcb rev A1
* maximum rev = A7
* bit0 = GPI8
* bit1 = GPI1
* bit2 = GPI0
*/
return (
((v & (1 << 8)) ? 1 : 0) |
((v & (1 << 1)) ? 2 : 0) |
((v & (1 << 0)) ? 4 : 0)
);
}
const struct board_variant const * get_board_variant_om_3d7k(void)
{
return &board_variants[om_3d7k_get_pcb_revision()];
}

View File

@ -1,75 +0,0 @@
/*
* (C) Copyright 2002
* Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
__system_ram_start = 0x50000000;
__steppingstone = 0x0c000000;
/* this text section is magically pulled from the SD Card
* and stored by the iRom at 0x0c000000, then it is jumped into
* by the iRom. So we arrange our early parts needed at 0 in the
* output file, but set to run at 0x0c000000+
*/
.text
__steppingstone :
AT (0)
{
src/cpu/s3c6410/start.o (.text .rodata* .data .bss)
src/cpu/s3c6410/start_qi.o (.text .rodata* .data .bss)
src/cpu/s3c6410/serial-s3c64xx.o (.text .rodata* .data .bss)
src/cpu/s3c6410/om_3d7k-steppingstone.o (.text .rodata* .data .bss)
src/cpu/s3c6410/smdk6410-steppingstone.o (.text .rodata* .data .bss)
src/cpu/s3c6410/hs_mmc.o (.text .rodata* .data .bss)
src/utils.o (.text .rodata* .data .bss)
src/memory-test.o (.text .rodata* .data .bss)
/* src/ctype.o (.text .rodata* .data .bss) */
* (.steppingstone)
}
. = ALIGN(4);
.everything_else
__system_ram_start + 0x3000000 + SIZEOF(.text) :
AT (SIZEOF(.text))
{
*(.text .rodata* .data)
}
__bss_start = __system_ram_start + 0x03800000;
.bss_6410
__bss_start (NOLOAD) :
AT (SIZEOF(.text) + SIZEOF(.everything_else))
{
* (.bss)
}
_end = .;
}

View File

@ -1,38 +0,0 @@
/*
* (C) Copyright 2007 OpenMoko, Inc.
* Author: Andy Green <andy@openmoko.com>
*
* Configuation settings for the FIC Neo GTA02 Linux GSM phone
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <qi.h>
#include <s3c6410.h>
/*
* Output a single byte to the serial port.
*/
void serial_putc_s3c64xx(const int uart, const char c)
{
if (uart >= 4)
return;
while (!(__REG(0x7F005000 + UTRSTAT_OFFSET + (uart << 10)) & 0x2))
;
__REG(0x7F005000 + UTXH_OFFSET + (uart << 10)) = c;
}

View File

@ -1,73 +0,0 @@
#include <qi.h>
#include <neo_smdk6410.h>
#include <serial-s3c64xx.h>
#define SMDK6410_DEBUG_UART 0
extern const struct board_variant const * get_board_variant_smdk6410(void);
int is_this_board_smdk6410(void)
{
/* FIXME: find something smdk6410 specific */
return 1;
}
static void putc_smdk6410(char c)
{
serial_putc_s3c64xx(SMDK6410_DEBUG_UART, c);
}
int sd_card_init_smdk6410(void)
{
extern int s3c6410_mmc_init(int verbose);
return s3c6410_mmc_init(1);
}
int sd_card_block_read_smdk6410(unsigned char * buf, unsigned long start512,
int blocks512)
{
unsigned long s3c6410_mmc_bread(int dev_num, unsigned long blknr,
unsigned long blkcnt, void *dst);
return s3c6410_mmc_bread(0, start512, blocks512, buf);
}
/*
* our API for bootloader on this machine
*/
const struct board_api board_api_smdk6410 = {
.name = "SMDK6410",
.linux_machine_id = 1866 /* 1626 */,
.linux_mem_start = 0x50000000,
.linux_mem_size = (128 * 1024 * 1024),
.linux_tag_placement = 0x50000000 + 0x100,
.get_board_variant = get_board_variant_smdk6410,
.is_this_board = is_this_board_smdk6410,
.putc = putc_smdk6410,
.commandline_board = "console=ttySAC0,115200 "
"loglevel=3 "
"init=/bin/sh ",
.commandline_board_debug = " loglevel=8",
.noboot = "boot/noboot-SDMK6410",
.append = "boot/append-SMDK6410",
.kernel_source = {
[0] = {
.name = "SD Card rootfs",
.block_read = sd_card_block_read_smdk6410,
.filesystem = FS_EXT2,
.partition_index = 2,
.filepath = "boot/uImage-SMDK6410.bin",
.commandline_append = "root=/dev/mmcblk0p2 "
},
[1] = {
.name = "SD Card backup rootfs",
.block_read = sd_card_block_read_smdk6410,
.filesystem = FS_EXT2,
.partition_index = 3,
.filepath = "boot/uImage-SMDK6410.bin",
.commandline_append = "root=/dev/mmcblk0p3 "
},
},
};

View File

@ -1,27 +0,0 @@
#include <qi.h>
#include <neo_smdk6410.h>
#include <serial-s3c64xx.h>
static const struct board_variant board_variants[] = {
[0] = {
.name = "SMDK",
.machine_revision = 0,
},
};
/**
* returns PCB revision information in b0, d8, d9
* SMDK6410 EVB returns 0x000
* SMDK6410 returns 0x001
*/
int smdk6410_get_pcb_revision(void)
{
return 0;
}
const struct board_variant const * get_board_variant_smdk6410(void)
{
return &board_variants[smdk6410_get_pcb_revision()];
}

Some files were not shown because too many files have changed in this diff Show More