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:
parent
19bc94325c
commit
433a3eebdb
@ -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.
|
@ -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
@ -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
@ -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__ */
|
@ -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__ */
|
@ -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__ */
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
@ -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
|
@ -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 */
|
@ -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 */
|
@ -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 */
|
@ -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 */
|
@ -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 */
|
@ -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 */
|
@ -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++);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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)
|
||||
|
@ -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>.
|
@ -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;
|
||||
}
|
@ -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:
|
||||
;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -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
|
@ -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
@ -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
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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"
|
@ -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)
|
149
qiboot/README
149
qiboot/README
@ -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.
|
||||
|
12
qiboot/build
12
qiboot/build
@ -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
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
#
|
||||
|
@ -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);
|
@ -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_ */
|
@ -1 +0,0 @@
|
||||
extern void glamo_core_init(void);
|
@ -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__ */
|
@ -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 */
|
@ -1,3 +0,0 @@
|
||||
#include <i2c-bitbang.h>
|
||||
|
||||
extern struct i2c_bitbang bb_s3c24xx;
|
@ -1,3 +0,0 @@
|
||||
#include <i2c-bitbang.h>
|
||||
|
||||
extern struct i2c_bitbang bb_s3c6410;
|
@ -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 */
|
@ -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__ */
|
@ -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 */
|
||||
|
@ -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
|
@ -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__ */
|
@ -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 */
|
@ -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 */
|
@ -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
|
@ -1,6 +0,0 @@
|
||||
#ifndef __ASM_MODE__
|
||||
#include <qi.h>
|
||||
extern const struct board_api board_api_smdk6410;
|
||||
#endif
|
||||
|
||||
#define TEXT_BASE_SMDK6410 0x53000000
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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_ */
|
@ -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
@ -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
|
@ -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
|
@ -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
|
@ -1,6 +0,0 @@
|
||||
#ifndef __ASM_MODE__
|
||||
#include <qi.h>
|
||||
extern const struct board_api board_api_smdk6410;
|
||||
#endif
|
||||
|
||||
#define TEXT_BASE_SMDK6410 0x53000000
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
@ -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_ */
|
@ -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 ",
|
||||
},
|
||||
},
|
||||
};
|
@ -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,
|
||||
};
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
@ -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 = .;
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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)
|
||||
;
|
||||
|
||||
}
|
@ -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 ",
|
||||
},
|
||||
},
|
||||
};
|
@ -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,
|
||||
};
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
@ -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 = .;
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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)
|
||||
;
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
@ -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__*/
|
@ -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,
|
||||
};
|
@ -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 ",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -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()];
|
||||
}
|
||||
|
@ -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 = .;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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 "
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user