mirror of
git://projects.qi-hardware.com/xburst-tools.git
synced 2024-11-22 13:41:32 +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