From 39d58838d968b6a79bbae61380836dfbbd292b6e Mon Sep 17 00:00:00 2001 From: xiangfu Date: Thu, 12 Jun 2008 18:22:49 -0400 Subject: [PATCH 001/248] blink led --- qiboot/Makefile | 25 +++++++++++++++++++++++++ qiboot/README | 0 qiboot/config.mk | 11 +++++++++++ qiboot/src/Makefile | 35 +++++++++++++++++++++++++++++++++++ qiboot/src/led.S | 12 ++++++++++++ qiboot/src/led.c | 29 +++++++++++++++++++++++++++++ 6 files changed, 112 insertions(+) create mode 100644 qiboot/Makefile create mode 100644 qiboot/README create mode 100644 qiboot/config.mk create mode 100644 qiboot/src/Makefile create mode 100644 qiboot/src/led.S create mode 100644 qiboot/src/led.c diff --git a/qiboot/Makefile b/qiboot/Makefile new file mode 100644 index 0000000..b49ee49 --- /dev/null +++ b/qiboot/Makefile @@ -0,0 +1,25 @@ +# 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 + +all : + cd src ; make all + +clean: + cd src ; make clean + + diff --git a/qiboot/README b/qiboot/README new file mode 100644 index 0000000..e69de29 diff --git a/qiboot/config.mk b/qiboot/config.mk new file mode 100644 index 0000000..c475739 --- /dev/null +++ b/qiboot/config.mk @@ -0,0 +1,11 @@ +# +# Include the make variables (CC, etc...) +# +CROSS_COMPILE=arm-angstrom-linux-gnueabi- + +AS = $(CROSS_COMPILE)as +LD = $(CROSS_COMPILE)ld +CC = $(CROSS_COMPILE)gcc +OBJCOPY = $(CROSS_COMPILE)objcopy + +export CROSS_COMPILE AD LD CC OBJCOPY diff --git a/qiboot/src/Makefile b/qiboot/src/Makefile new file mode 100644 index 0000000..39d2d0d --- /dev/null +++ b/qiboot/src/Makefile @@ -0,0 +1,35 @@ +# 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 +# + + + +TEXT_BASE =0x0000000 + +INCLUDE =../include +IMAGE =../image +CFLAGS =-I $(INCLUDE) -g -c -o + +all:led.S led.c + $(CC) $(CFLAGS) led_S.o led.S + $(CC) $(CFLAGS) led_C.o led.c + $(LD) -Ttext $(TEXT_BASE) -g led_S.o led_C.o -o led.o + $(OBJCOPY) -O binary -S led.o $(IMAGE)/led_on + +clean: + rm -f *.o + rm -f led_on + rm -f $(IMAGE)/* + diff --git a/qiboot/src/led.S b/qiboot/src/led.S new file mode 100644 index 0000000..8e539df --- /dev/null +++ b/qiboot/src/led.S @@ -0,0 +1,12 @@ +.global _start +_start: + ldr sp,=1024*4 + +.extern main + bl main +.global delay +delay: + subs r0,r0,#0x1 + bne delay + mov pc,lr + diff --git a/qiboot/src/led.c b/qiboot/src/led.c new file mode 100644 index 0000000..5e8447b --- /dev/null +++ b/qiboot/src/led.c @@ -0,0 +1,29 @@ +#define GPBCON (*(volatile unsigned *)0x56000010) +#define GPBDAT (*(volatile unsigned *)0x56000014) +#define GPBDW (*(volatile unsigned *)0x56000018) +#define LED3_ON() (GPBDAT &= ~(0x1)) +#define LED4_ON() (GPBDAT &= ~(0x2)) +#define LED3_OFF() (GPBDAT |= (0x1)) +#define LED4_OFF() (GPBDAT |= (0x2)) + +extern void delay(int time); + +int main() +{ + GPBCON = 0x5; + GPBDW = 0xffff; + while(1) + { + LED3_ON(); + delay(0xffff); + LED3_OFF() ; + delay(0xffff); + + LED4_ON(); + delay(0xffff); + LED4_OFF(); + delay(0xffff); + } + return 1; +} + From 98fb0b6654a84cfe846a27a32690556a68e74a0b Mon Sep 17 00:00:00 2001 From: xiangfu Date: Fri, 13 Jun 2008 14:53:04 -0400 Subject: [PATCH 002/248] the led_on does not random abort --- qiboot/README | 6 ++++++ qiboot/src/led.S | 18 +++++++++++++----- qiboot/src/led.c | 2 +- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/qiboot/README b/qiboot/README index e69de29..ab9cad4 100644 --- a/qiboot/README +++ b/qiboot/README @@ -0,0 +1,6 @@ +use follow command to run this program +start OpenOCD,then do this + + > reset halt + > load_image /path/to/led_on 0 + > resume diff --git a/qiboot/src/led.S b/qiboot/src/led.S index 8e539df..04a98ee 100644 --- a/qiboot/src/led.S +++ b/qiboot/src/led.S @@ -1,9 +1,17 @@ -.global _start -_start: +.globl _start +_start: b start_code + +start_code: ldr sp,=1024*4 - -.extern main - bl main + + /* turn off the watchdog */ +# define pWTCON 0x53000000 + ldr r0, =pWTCON + mov r1, #0x0 + str r1, [r0] + +.extern blink_led + bl blink_led .global delay delay: subs r0,r0,#0x1 diff --git a/qiboot/src/led.c b/qiboot/src/led.c index 5e8447b..29a32a2 100644 --- a/qiboot/src/led.c +++ b/qiboot/src/led.c @@ -8,7 +8,7 @@ extern void delay(int time); -int main() +int blink_led() { GPBCON = 0x5; GPBDW = 0xffff; From 280f8ffb134ea27c8eb4af9f2391ad0456afd30b Mon Sep 17 00:00:00 2001 From: xiangfu Date: Fri, 13 Jun 2008 16:17:04 -0400 Subject: [PATCH 003/248] add some initial cpu code in led.S --- qiboot/src/led.S | 62 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/qiboot/src/led.S b/qiboot/src/led.S index 04a98ee..1d5ccc1 100644 --- a/qiboot/src/led.S +++ b/qiboot/src/led.S @@ -2,16 +2,74 @@ _start: b start_code start_code: - ldr sp,=1024*4 + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + /* turn off the watchdog */ -# define pWTCON 0x53000000 +# define pWTCON 0x53000000 +# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */ +# define INTSUBMSK 0x4A00001C +# define INTSUBMSK_val 0xffff +# define CAMDIVN 0x4C000018 + ldr r0, =pWTCON mov r1, #0x0 str r1, [r0] + /* + * mask all IRQs by setting all bits in the INTMR - default + */ + 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 */ + 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 + + /* enable uart */ + ldr r0, =0x4c00000c /* clkcon */ + ldr r1, =0x7fff0 /* all clocks on */ + str r1, [r0] + + /* gpio UART0 init */ + ldr r0, =0x56000070 + mov r1, #0xaa + str r1, [r0] + + /* init uart */ + 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] + + /* blink led */ + ldr sp,=1024*4 .extern blink_led bl blink_led + .global delay delay: subs r0,r0,#0x1 From d076efdbe73cf3bc3b4af676c6b0010fa3c86187 Mon Sep 17 00:00:00 2001 From: xiangfu Date: Tue, 17 Jun 2008 10:40:22 -0400 Subject: [PATCH 004/248] add neo_gta02.h lowlevel_init.S and kboot-stage1.lds --- qiboot/include/neo_gta02.h | 306 +++++++++++++++++++++++++++++++++++++ qiboot/src/kboot.lds | 53 +++++++ qiboot/src/lowlevel_init.S | 209 +++++++++++++++++++++++++ 3 files changed, 568 insertions(+) create mode 100644 qiboot/include/neo_gta02.h create mode 100644 qiboot/src/kboot.lds create mode 100644 qiboot/src/lowlevel_init.S diff --git a/qiboot/include/neo_gta02.h b/qiboot/include/neo_gta02.h new file mode 100644 index 0000000..dc130f8 --- /dev/null +++ b/qiboot/include/neo_gta02.h @@ -0,0 +1,306 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: Harald Welte + * + * Configuation settings for the FIC Neo1973 GTA02 Linux GSM phone + * + * 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 __CONFIG_H +#define __CONFIG_H + +#define TEXT_BASE 0x00000000 /* xiangfu add*/ + +/* we want to be able to start u-boot directly from within NAND flash */ +#define CONFIG_LL_INIT_NAND_ONLY +#define CONFIG_S3C2410_NAND_BOOT 1 +#define CONFIG_S3C2410_NAND_SKIP_BAD 1 + +#define CFG_UBOOT_SIZE 0x40000 /* size of u-boot, for NAND loading */ + +/* + * High Level Configuration Options + * (easy to change) + */ +#define CONFIG_ARM920T 1 /* This is an ARM920T Core */ +#define CONFIG_SMDK2440 1 /* on a SAMSUNG SMDK2410 Board */ + +/* input clock of PLL */ +#define CONFIG_SYS_CLK_FREQ 12000000/* the GTA02 has this input clock */ + + +#define USE_920T_MMU 1 +#define CONFIG_USE_IRQ 1 + +/* + * Size of malloc() pool + */ +#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 400*1024) + /* >> CFG_VIDEO_LOGO_MAX_SIZE */ +#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ + +/* + * Hardware drivers + */ + +/* + * select serial console configuration + */ +#define CONFIG_SERIAL3 1 /* we use SERIAL 1 on GTA01 */ +#define CONFIG_SERIAL_MULTI + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +#define CONFIG_BAUDRATE 115200 + +/*********************************************************** + * Command definition + ***********************************************************/ +#define CONFIG_CMD_BDI +#define CONFIG_CMD_LOADS +#define CONFIG_CMD_LOADB +#define CONFIG_CMD_IMI +#define CONFIG_CMD_CACHE +#define CONFIG_CMD_MEMORY +#define CONFIG_CMD_ENV + /* CFG_CMD_IRQ | */ \ +#define CONFIG_CMD_BOOTD +#define CONFIG_CMD_CONSOLE + /* CFG_CMD_BMP | */ \ +#define CONFIG_CMD_ASKENV +#define CONFIG_CMD_RUN +#define CONFIG_CMD_ECHO +#define CONFIG_CMD_I2C +#define CONFIG_CMD_REGINFO +#define CONFIG_CMD_IMMAP +#define CONFIG_CMD_DATE +#define CONFIG_CMD_AUTOSCRIPT +#define CONFIG_CMD_BSP +#define CONFIG_CMD_ELF +#define CONFIG_CMD_MISC + /* CFG_CMD_USB | */ \ +#define CONFIG_CMD_JFFS2 +#define CONFIG_CMD_DIAG + /* CFG_CMD_HWFLOW | */ \ +#define CONFIG_CMD_SAVES +#define CONFIG_CMD_NAND +#define CONFIG_CMD_FLASH +#define CONFIG_CMD_PORTIO +#define CONFIG_CMD_MMC +#define CONFIG_CMD_FAT +#define CONFIG_CMD_EXT2 +#define CONFIG_CMD_LICENSE +#define CONFIG_CMD_TERMINAL + +#define CONFIG_BOOTDELAY 3 +#define CONFIG_BOOTARGS "" +#define CONFIG_BOOTCOMMAND "setenv bootargs ${bootargs_base} ${mtdparts}; nand read.e 0x32000000 kernel; bootm 0x32000000" + +#define CONFIG_DOS_PARTITION 1 + +#if defined(CONFIG_CMD_KGDB) +#define CONFIG_KGDB_BAUDRATE 115200 /* speed to run kgdb serial port */ +/* what's this ? it's not used anywhere */ +#define CONFIG_KGDB_SER_INDEX 1 /* which serial port to use */ +#endif + +/* + * Miscellaneous configurable options + */ +#define CFG_LONGHELP /* undef to save memory */ + +#define STRINGIFY(s) DO_STRINGIFY(s) /* expand the argument */ +#define DO_STRINGIFY(s) #s /* quote it */ +#define CFG_PROMPT __cfg_prompt + /* Monitor Command Prompt */ +#ifndef __ASSEMBLY__ +/*extern char __cfg_prompt[20];*/ +#endif + +#if defined(CONFIG_ARCH_GTA02_v1) +#define CONFIG_S3C2440 1 /* SAMSUNG S3C2440 SoC */ +#else +#define CONFIG_S3C2442 1 /* SAMSUNG S3C2442 SoC */ +#endif + +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 64 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ + +#define CFG_MEMTEST_START 0x30000000 /* memtest works on */ +#define CFG_MEMTEST_END 0x33F00000 /* 63 MB in DRAM */ + +#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ + +#define CFG_LOAD_ADDR 0x33000000 /* default load address */ + +/* the PWM TImer 4 uses a counter of 15625 for 10 ms, so we need */ +/* it to wrap 100 times (total 1562500) to get 1 sec. */ +#define CFG_HZ 1562500 + +/* valid baudrates */ +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } + +#define CFG_BOOTMENU + +/*----------------------------------------------------------------------- + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE (128*1024) /* regular stack */ +#ifdef CONFIG_USE_IRQ +#define CONFIG_STACKSIZE_IRQ (8*1024) /* IRQ stack */ +#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */ +#endif + +#if 0 +#define CONFIG_USB_OHCI_NEW 1 +#define CFG_USB_OHCI_CPU_INIT 1 +#define CFG_USB_OHCI_REGS_BASE 0x49000000 /* S3C24X0_USB_HOST_BASE */ +#define CFG_USB_OHCI_SLOT_NAME "s3c2440" +#define CFG_USB_OHCI_MAX_ROOT_PORTS 2 +#endif + +#define CONFIG_USB_DEVICE 1 +#define CONFIG_USB_TTY 1 +#define CFG_CONSOLE_IS_IN_ENV 1 +#define CONFIG_USBD_VENDORID 0x1d50 /* OpenMoko, Inc. */ +#define CONFIG_USBD_PRODUCTID_GSERIAL 0x5120 /* gserial */ +#define CONFIG_USBD_PRODUCTID_CDCACM 0x5119 /* CDC ACM */ +#define CONFIG_USBD_MANUFACTURER "OpenMoko, Inc" +#define CONFIG_USBD_PRODUCT_NAME "Neo1973 Bootloader " U_BOOT_VERSION +#define CONFIG_USBD_DFU 1 +#define CONFIG_USBD_DFU_XFER_SIZE 4096 /* 0x4000 */ +#define CONFIG_USBD_DFU_INTERFACE 2 + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "usbtty=cdc_acm\0" \ + "stderr=usbtty\0stdout=usbtty\0stdin=usbtty\0" \ + "bootargs_base=rootfstype=jffs2 root=/dev/mtdblock6 console=ttySAC2,115200 console=tty0 loglevel=8\0" \ + "" +#define CONFIG_CMD_LOADENV +#define CONFIG_CMD_DEFAULTENV + + +/*----------------------------------------------------------------------- + * Physical Memory Map + */ +#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */ +#define PHYS_SDRAM_1 0x30000000 /* SDRAM Bank #1 */ +#define PHYS_SDRAM_1_SIZE 0x08000000 /* 128 MB */ +#define PHYS_SDRAM_RES_SIZE 0x00200000 /* 2 MB for frame buffer */ + +/*----------------------------------------------------------------------- + * FLASH and environment organization + */ + +#define CFG_ENV_IS_IN_NAND 1 +#define CFG_ENV_SIZE 0x40000 /* 128k Total Size of Environment Sector */ +#define CFG_ENV_OFFSET_OOB 1 /* Location of ENV stored in block 0 OOB */ +#define CFG_PREBOOT_OVERRIDE 1 /* allow preboot from memory */ +#define CFG_ENV_OVERRIDE /* allow pre-loading the environment */ + +#define NAND_MAX_CHIPS 1 +#define CFG_NAND_BASE 0x4e000000 +#define CFG_MAX_NAND_DEVICE 1 + +#define CONFIG_MMC 1 +#define CONFIG_MMC_WIDE 1 +#define CONFIG_MMC_GLAMO 1 +#define CFG_MMC_BASE 0xff000000 +#define CONFIG_DEPOWER_MMC_ON_BOOT 1 + +/* EXT2 driver */ +#define CONFIG_EXT2 1 + +#define CONFIG_FAT 1 +#define CONFIG_SUPPORT_VFAT + +#if 1 +/* JFFS2 driver */ +#define CONFIG_JFFS2_CMDLINE 1 +#define CONFIG_JFFS2_NAND 1 +#define CONFIG_JFFS2_NAND_DEV 0 +//#define CONFIG_JFFS2_NAND_OFF 0x634000 +//#define CONFIG_JFFS2_NAND_SIZE 0x39cc000 +#endif + +/* ATAG configuration */ +#define CONFIG_INITRD_TAG 1 +#define CONFIG_SETUP_MEMORY_TAGS 1 +#define CONFIG_CMDLINE_TAG 1 +#define CONFIG_REVISION_TAG 1 +#if 0 +#define CONFIG_SERIAL_TAG 1 +#endif + +#define CONFIG_DRIVER_S3C24X0_I2C 1 +#define CONFIG_HARD_I2C 1 +#define CFG_I2C_SPEED 400000 /* 400kHz according to PCF50633 data sheet */ +#define CFG_I2C_SLAVE 0x7f + +/* we have a board_late_init() function */ +#define BOARD_LATE_INIT 1 + +#if 1 +#define CONFIG_VIDEO +#define CONFIG_VIDEO_GLAMO3362 +#define CONFIG_CFB_CONSOLE +//#define CONFIG_VIDEO_LOGO +//#define CONFIG_SPLASH_SCREEN +#define CFG_VIDEO_LOGO_MAX_SIZE (640*480+1024+100) /* 100 = slack */ +#define CONFIG_VIDEO_BMP_GZIP +#define CONFIG_VGA_AS_SINGLE_DEVICE +#define CONFIG_CMD_UNZIP + +#define VIDEO_FB_16BPP_PIXEL_SWAP + +#define VIDEO_KBD_INIT_FCT 0 +#define VIDEO_TSTC_FCT serial_tstc +#define VIDEO_GETC_FCT serial_getc + +#define CONFIG_GLAMO_BASE 0x08000000 +#endif + +#define CONFIG_S3C2410_NAND_BBT 1 +//#define CONFIG_S3C2410_NAND_HWECC 1 + +#define CONFIG_DRIVER_PCF50633 1 +#define CONFIG_RTC_PCF50633 1 + +#define MTDIDS_DEFAULT "nor0=physmap-flash,nand0=neo1973-nand" +//#define MTPARTS_DEFAULT "neo1973-nand:256k(u-boot),128k(u-boot_env),8M(kernel),640k(splash),256k(factory),-(rootfs)" +#define CFG_MTDPARTS_PREFIX "physmap-flash:-(nor);" +#define CFG_NAND_DYNPART_MTD_KERNEL_NAME "neo1973-nand" +#define CONFIG_NAND_DYNPART + +#define CFG_MAX_FLASH_BANKS 1 +#define CFG_MAX_FLASH_SECT 1 + +#define DFU_NUM_ALTERNATES 7 + +#ifndef __ASSEMBLY__ +/*extern int gta02_revision;*/ /* use this instead of CONFIG_GTA02_REVISION */ +#endif + +#endif /* __CONFIG_H */ diff --git a/qiboot/src/kboot.lds b/qiboot/src/kboot.lds new file mode 100644 index 0000000..3cc3e58 --- /dev/null +++ b/qiboot/src/kboot.lds @@ -0,0 +1,53 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * 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; + + . = ALIGN(4); + .text : + { + led_S.o (.text) + led_C.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = ALIGN(4); + __bss_start = .; + .bss (NOLOAD) : { *(.bss) } + _end = .; +} diff --git a/qiboot/src/lowlevel_init.S b/qiboot/src/lowlevel_init.S new file mode 100644 index 0000000..cca9fac --- /dev/null +++ b/qiboot/src/lowlevel_init.S @@ -0,0 +1,209 @@ +/* + * Memory Setup stuff - taken from blob memsetup.S + * + * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and + * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) + * + * Modified for the FIC Neo1973 GTA01 by Harald Welte + * + * 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 + */ + +/* +* #include +* #include +*/ +#include +/* some parameters for the board */ + +/* + * + * Taken from linux/arch/arm/boot/compressed/head-s3c2410.S + * + * Copyright (C) 2002 Samsung Electronics SW.LEE + * + */ + +#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) */ +/**************************************/ + +_TEXT_BASE: + .word TEXT_BASE + +.globl lowlevel_init +lowlevel_init: + /* memory control configuration */ + /* make r0 relative the current location so that it */ + /* reads SMRDATA out of FLASH rather than memory ! */ + adr 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 + +#if defined(CONFIG_ARCH_GTA01_v4) || defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3) + /* switch on power for NAND */ + ldr r0, =0x56000010 /* GPBCON */ + ldr r1, [r0] + orr r1, r1, #0x10 + str r1, [r0] + + ldr r0, =0x56000014 /* GPBDAT */ + ldr r1, [r0] + orr r1, r1, #(1 <<2) + str r1, [r0] +#endif + +#if defined(CONFIG_ARCH_GTA02_v1) + /* enable KEEPACT(GPJ3) to make sure PMU keeps us alive */ + ldr r0, =0x56000000 /* GPJ base */ + ldr r1, [r0, #0xd0] /* GPJCON */ + orr r1, r1, #(1 << 6) + str r1, [r0, #0xd0] + + ldr r1, [r0, #0xd4] /* GPJDAT */ + orr r1, r1, #(1 << 3) + str r1, [r0, #0xd4] +#elif CONFIG_GTA02_REVISION >= 2 + /* 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] +#endif + /* 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) +#if CONFIG_GTA02_REVISION >= 2 + .word 0xb1 +#else + .word 0xb2 +#endif + .word 0x30 + .word 0x30 From 02fe96ba6f2235e3bfd7f6c76382b88e2d7d660e Mon Sep 17 00:00:00 2001 From: xiangfu Date: Tue, 17 Jun 2008 10:42:35 -0400 Subject: [PATCH 005/248] add neo_gta02.h lowlevel_init.S kboot-stage1.lds --- qiboot/src/Makefile | 12 ++--- qiboot/src/kboot.lds | 53 ------------------- qiboot/src/led.S | 118 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 122 insertions(+), 61 deletions(-) delete mode 100644 qiboot/src/kboot.lds diff --git a/qiboot/src/Makefile b/qiboot/src/Makefile index 39d2d0d..1e052b2 100644 --- a/qiboot/src/Makefile +++ b/qiboot/src/Makefile @@ -14,18 +14,16 @@ # MA 02111-1307 USA # - - -TEXT_BASE =0x0000000 - +LDS =kboot-stage1.lds INCLUDE =../include IMAGE =../image -CFLAGS =-I $(INCLUDE) -g -c -o +CFLAGS =-Wall -I $(INCLUDE) -g -c -o -all:led.S led.c +all:led.S led.c lowlevel_init.S $(CC) $(CFLAGS) led_S.o led.S $(CC) $(CFLAGS) led_C.o led.c - $(LD) -Ttext $(TEXT_BASE) -g led_S.o led_C.o -o led.o + $(CC) $(CFLAGS) lowlevel_init.o lowlevel_init.S + $(LD) -T$(LDS) -g led_S.o led_C.o lowlevel_init.o -o led.o $(OBJCOPY) -O binary -S led.o $(IMAGE)/led_on clean: diff --git a/qiboot/src/kboot.lds b/qiboot/src/kboot.lds deleted file mode 100644 index 3cc3e58..0000000 --- a/qiboot/src/kboot.lds +++ /dev/null @@ -1,53 +0,0 @@ -/* - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * 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; - - . = ALIGN(4); - .text : - { - led_S.o (.text) - led_C.o (.text) - *(.text) - } - - . = ALIGN(4); - .rodata : { *(.rodata) } - - . = ALIGN(4); - .data : { *(.data) } - - . = ALIGN(4); - .got : { *(.got) } - - . = ALIGN(4); - __bss_start = .; - .bss (NOLOAD) : { *(.bss) } - _end = .; -} diff --git a/qiboot/src/led.S b/qiboot/src/led.S index 1d5ccc1..52c4bf5 100644 --- a/qiboot/src/led.S +++ b/qiboot/src/led.S @@ -1,5 +1,57 @@ + +#include .globl _start _start: b start_code +/* ldr pc, _undefined_instruction + ldr pc, _software_interrupt + ldr pc, _prefetch_abort + ldr pc, _data_abort + ldr pc, _not_used + ldr pc, _irq + ldr pc, _fiq + +_undefined_instruction: .word undefined_instruction +_software_interrupt: .word software_interrupt +_prefetch_abort: .word prefetch_abort +_data_abort: .word data_abort +_not_used: .word not_used +_irq: .word irq +_fiq: .word fiq + + .balignl 16,0xdeadbeef +*/ + +_TEXT_BASE: + .word TEXT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +#ifdef CONFIG_USE_IRQ +/* IRQ stack memory (calculated at run-time) */ +.globl IRQ_STACK_START +IRQ_STACK_START: + .word 0x0badc0de + +/* IRQ stack memory (calculated at run-time) */ +.globl FIQ_STACK_START +FIQ_STACK_START: + .word 0x0badc0de +#endif + + start_code: @@ -65,8 +117,28 @@ start_code: mov r1, #0x1a str r1, [r0, #0x28] + bl cpu_init_crit + +stack_setup: + ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ + sub r0, r0, #CFG_MALLOC_LEN /* malloc area */ + sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */ +#ifdef CONFIG_USE_IRQ + sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) +#endif + 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 + /* blink led */ - ldr sp,=1024*4 .extern blink_led bl blink_led @@ -76,3 +148,47 @@ delay: bne delay mov pc,lr + + +/* + ************************************************************************* + * + * 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 + + From 83a402b963ca8f37e75789c460c05de3e8328929 Mon Sep 17 00:00:00 2001 From: xiangfu Date: Tue, 17 Jun 2008 10:48:52 -0400 Subject: [PATCH 006/248] add kboot-stage1.lds --- qiboot/src/kboot-stage1.lds | 53 +++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 qiboot/src/kboot-stage1.lds diff --git a/qiboot/src/kboot-stage1.lds b/qiboot/src/kboot-stage1.lds new file mode 100644 index 0000000..3cc3e58 --- /dev/null +++ b/qiboot/src/kboot-stage1.lds @@ -0,0 +1,53 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * 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; + + . = ALIGN(4); + .text : + { + led_S.o (.text) + led_C.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = ALIGN(4); + __bss_start = .; + .bss (NOLOAD) : { *(.bss) } + _end = .; +} From dbb19d74ce1e1428594fa18874aa4eede8860fee Mon Sep 17 00:00:00 2001 From: xiangfu Date: Tue, 17 Jun 2008 10:53:16 -0400 Subject: [PATCH 007/248] add lowlevel_init funtion to led.S --- qiboot/src/led.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiboot/src/led.S b/qiboot/src/led.S index 52c4bf5..00bb291 100644 --- a/qiboot/src/led.S +++ b/qiboot/src/led.S @@ -186,7 +186,7 @@ cpu_init_crit: */ mov ip, lr -/* bl lowlevel_init*/ + bl lowlevel_init mov lr, ip mov pc, lr From 474787a5011228feab6eed3d2a489adcb35486ef Mon Sep 17 00:00:00 2001 From: xiangfu Date: Tue, 17 Jun 2008 19:18:37 -0400 Subject: [PATCH 008/248] reduce the neo_gta02.h --- qiboot/include/neo_gta02.h | 271 +------------------------------------ 1 file changed, 2 insertions(+), 269 deletions(-) diff --git a/qiboot/include/neo_gta02.h b/qiboot/include/neo_gta02.h index dc130f8..8f632c9 100644 --- a/qiboot/include/neo_gta02.h +++ b/qiboot/include/neo_gta02.h @@ -26,29 +26,9 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define TEXT_BASE 0x00000000 /* xiangfu add*/ - -/* we want to be able to start u-boot directly from within NAND flash */ -#define CONFIG_LL_INIT_NAND_ONLY -#define CONFIG_S3C2410_NAND_BOOT 1 -#define CONFIG_S3C2410_NAND_SKIP_BAD 1 - -#define CFG_UBOOT_SIZE 0x40000 /* size of u-boot, for NAND loading */ - -/* - * High Level Configuration Options - * (easy to change) - */ -#define CONFIG_ARM920T 1 /* This is an ARM920T Core */ -#define CONFIG_SMDK2440 1 /* on a SAMSUNG SMDK2410 Board */ - -/* input clock of PLL */ -#define CONFIG_SYS_CLK_FREQ 12000000/* the GTA02 has this input clock */ - - -#define USE_920T_MMU 1 -#define CONFIG_USE_IRQ 1 +#define TEXT_BASE 0x00000000 /* xiangfu add*/ +#define CFG_ENV_SIZE 0x40000 /* 128k Total Size of Environment Sector */ /* * Size of malloc() pool */ @@ -56,251 +36,4 @@ /* >> CFG_VIDEO_LOGO_MAX_SIZE */ #define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ -/* - * Hardware drivers - */ - -/* - * select serial console configuration - */ -#define CONFIG_SERIAL3 1 /* we use SERIAL 1 on GTA01 */ -#define CONFIG_SERIAL_MULTI - -/* allow to overwrite serial and ethaddr */ -#define CONFIG_ENV_OVERWRITE - -#define CONFIG_BAUDRATE 115200 - -/*********************************************************** - * Command definition - ***********************************************************/ -#define CONFIG_CMD_BDI -#define CONFIG_CMD_LOADS -#define CONFIG_CMD_LOADB -#define CONFIG_CMD_IMI -#define CONFIG_CMD_CACHE -#define CONFIG_CMD_MEMORY -#define CONFIG_CMD_ENV - /* CFG_CMD_IRQ | */ \ -#define CONFIG_CMD_BOOTD -#define CONFIG_CMD_CONSOLE - /* CFG_CMD_BMP | */ \ -#define CONFIG_CMD_ASKENV -#define CONFIG_CMD_RUN -#define CONFIG_CMD_ECHO -#define CONFIG_CMD_I2C -#define CONFIG_CMD_REGINFO -#define CONFIG_CMD_IMMAP -#define CONFIG_CMD_DATE -#define CONFIG_CMD_AUTOSCRIPT -#define CONFIG_CMD_BSP -#define CONFIG_CMD_ELF -#define CONFIG_CMD_MISC - /* CFG_CMD_USB | */ \ -#define CONFIG_CMD_JFFS2 -#define CONFIG_CMD_DIAG - /* CFG_CMD_HWFLOW | */ \ -#define CONFIG_CMD_SAVES -#define CONFIG_CMD_NAND -#define CONFIG_CMD_FLASH -#define CONFIG_CMD_PORTIO -#define CONFIG_CMD_MMC -#define CONFIG_CMD_FAT -#define CONFIG_CMD_EXT2 -#define CONFIG_CMD_LICENSE -#define CONFIG_CMD_TERMINAL - -#define CONFIG_BOOTDELAY 3 -#define CONFIG_BOOTARGS "" -#define CONFIG_BOOTCOMMAND "setenv bootargs ${bootargs_base} ${mtdparts}; nand read.e 0x32000000 kernel; bootm 0x32000000" - -#define CONFIG_DOS_PARTITION 1 - -#if defined(CONFIG_CMD_KGDB) -#define CONFIG_KGDB_BAUDRATE 115200 /* speed to run kgdb serial port */ -/* what's this ? it's not used anywhere */ -#define CONFIG_KGDB_SER_INDEX 1 /* which serial port to use */ -#endif - -/* - * Miscellaneous configurable options - */ -#define CFG_LONGHELP /* undef to save memory */ - -#define STRINGIFY(s) DO_STRINGIFY(s) /* expand the argument */ -#define DO_STRINGIFY(s) #s /* quote it */ -#define CFG_PROMPT __cfg_prompt - /* Monitor Command Prompt */ -#ifndef __ASSEMBLY__ -/*extern char __cfg_prompt[20];*/ -#endif - -#if defined(CONFIG_ARCH_GTA02_v1) -#define CONFIG_S3C2440 1 /* SAMSUNG S3C2440 SoC */ -#else -#define CONFIG_S3C2442 1 /* SAMSUNG S3C2442 SoC */ -#endif - -#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ -#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ -#define CFG_MAXARGS 64 /* max number of command args */ -#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ - -#define CFG_MEMTEST_START 0x30000000 /* memtest works on */ -#define CFG_MEMTEST_END 0x33F00000 /* 63 MB in DRAM */ - -#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ - -#define CFG_LOAD_ADDR 0x33000000 /* default load address */ - -/* the PWM TImer 4 uses a counter of 15625 for 10 ms, so we need */ -/* it to wrap 100 times (total 1562500) to get 1 sec. */ -#define CFG_HZ 1562500 - -/* valid baudrates */ -#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } - -#define CFG_BOOTMENU - -/*----------------------------------------------------------------------- - * Stack sizes - * - * The stack sizes are set up in start.S using the settings below - */ -#define CONFIG_STACKSIZE (128*1024) /* regular stack */ -#ifdef CONFIG_USE_IRQ -#define CONFIG_STACKSIZE_IRQ (8*1024) /* IRQ stack */ -#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */ -#endif - -#if 0 -#define CONFIG_USB_OHCI_NEW 1 -#define CFG_USB_OHCI_CPU_INIT 1 -#define CFG_USB_OHCI_REGS_BASE 0x49000000 /* S3C24X0_USB_HOST_BASE */ -#define CFG_USB_OHCI_SLOT_NAME "s3c2440" -#define CFG_USB_OHCI_MAX_ROOT_PORTS 2 -#endif - -#define CONFIG_USB_DEVICE 1 -#define CONFIG_USB_TTY 1 -#define CFG_CONSOLE_IS_IN_ENV 1 -#define CONFIG_USBD_VENDORID 0x1d50 /* OpenMoko, Inc. */ -#define CONFIG_USBD_PRODUCTID_GSERIAL 0x5120 /* gserial */ -#define CONFIG_USBD_PRODUCTID_CDCACM 0x5119 /* CDC ACM */ -#define CONFIG_USBD_MANUFACTURER "OpenMoko, Inc" -#define CONFIG_USBD_PRODUCT_NAME "Neo1973 Bootloader " U_BOOT_VERSION -#define CONFIG_USBD_DFU 1 -#define CONFIG_USBD_DFU_XFER_SIZE 4096 /* 0x4000 */ -#define CONFIG_USBD_DFU_INTERFACE 2 - -#define CONFIG_EXTRA_ENV_SETTINGS \ - "usbtty=cdc_acm\0" \ - "stderr=usbtty\0stdout=usbtty\0stdin=usbtty\0" \ - "bootargs_base=rootfstype=jffs2 root=/dev/mtdblock6 console=ttySAC2,115200 console=tty0 loglevel=8\0" \ - "" -#define CONFIG_CMD_LOADENV -#define CONFIG_CMD_DEFAULTENV - - -/*----------------------------------------------------------------------- - * Physical Memory Map - */ -#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */ -#define PHYS_SDRAM_1 0x30000000 /* SDRAM Bank #1 */ -#define PHYS_SDRAM_1_SIZE 0x08000000 /* 128 MB */ -#define PHYS_SDRAM_RES_SIZE 0x00200000 /* 2 MB for frame buffer */ - -/*----------------------------------------------------------------------- - * FLASH and environment organization - */ - -#define CFG_ENV_IS_IN_NAND 1 -#define CFG_ENV_SIZE 0x40000 /* 128k Total Size of Environment Sector */ -#define CFG_ENV_OFFSET_OOB 1 /* Location of ENV stored in block 0 OOB */ -#define CFG_PREBOOT_OVERRIDE 1 /* allow preboot from memory */ -#define CFG_ENV_OVERRIDE /* allow pre-loading the environment */ - -#define NAND_MAX_CHIPS 1 -#define CFG_NAND_BASE 0x4e000000 -#define CFG_MAX_NAND_DEVICE 1 - -#define CONFIG_MMC 1 -#define CONFIG_MMC_WIDE 1 -#define CONFIG_MMC_GLAMO 1 -#define CFG_MMC_BASE 0xff000000 -#define CONFIG_DEPOWER_MMC_ON_BOOT 1 - -/* EXT2 driver */ -#define CONFIG_EXT2 1 - -#define CONFIG_FAT 1 -#define CONFIG_SUPPORT_VFAT - -#if 1 -/* JFFS2 driver */ -#define CONFIG_JFFS2_CMDLINE 1 -#define CONFIG_JFFS2_NAND 1 -#define CONFIG_JFFS2_NAND_DEV 0 -//#define CONFIG_JFFS2_NAND_OFF 0x634000 -//#define CONFIG_JFFS2_NAND_SIZE 0x39cc000 -#endif - -/* ATAG configuration */ -#define CONFIG_INITRD_TAG 1 -#define CONFIG_SETUP_MEMORY_TAGS 1 -#define CONFIG_CMDLINE_TAG 1 -#define CONFIG_REVISION_TAG 1 -#if 0 -#define CONFIG_SERIAL_TAG 1 -#endif - -#define CONFIG_DRIVER_S3C24X0_I2C 1 -#define CONFIG_HARD_I2C 1 -#define CFG_I2C_SPEED 400000 /* 400kHz according to PCF50633 data sheet */ -#define CFG_I2C_SLAVE 0x7f - -/* we have a board_late_init() function */ -#define BOARD_LATE_INIT 1 - -#if 1 -#define CONFIG_VIDEO -#define CONFIG_VIDEO_GLAMO3362 -#define CONFIG_CFB_CONSOLE -//#define CONFIG_VIDEO_LOGO -//#define CONFIG_SPLASH_SCREEN -#define CFG_VIDEO_LOGO_MAX_SIZE (640*480+1024+100) /* 100 = slack */ -#define CONFIG_VIDEO_BMP_GZIP -#define CONFIG_VGA_AS_SINGLE_DEVICE -#define CONFIG_CMD_UNZIP - -#define VIDEO_FB_16BPP_PIXEL_SWAP - -#define VIDEO_KBD_INIT_FCT 0 -#define VIDEO_TSTC_FCT serial_tstc -#define VIDEO_GETC_FCT serial_getc - -#define CONFIG_GLAMO_BASE 0x08000000 -#endif - -#define CONFIG_S3C2410_NAND_BBT 1 -//#define CONFIG_S3C2410_NAND_HWECC 1 - -#define CONFIG_DRIVER_PCF50633 1 -#define CONFIG_RTC_PCF50633 1 - -#define MTDIDS_DEFAULT "nor0=physmap-flash,nand0=neo1973-nand" -//#define MTPARTS_DEFAULT "neo1973-nand:256k(u-boot),128k(u-boot_env),8M(kernel),640k(splash),256k(factory),-(rootfs)" -#define CFG_MTDPARTS_PREFIX "physmap-flash:-(nor);" -#define CFG_NAND_DYNPART_MTD_KERNEL_NAME "neo1973-nand" -#define CONFIG_NAND_DYNPART - -#define CFG_MAX_FLASH_BANKS 1 -#define CFG_MAX_FLASH_SECT 1 - -#define DFU_NUM_ALTERNATES 7 - -#ifndef __ASSEMBLY__ -/*extern int gta02_revision;*/ /* use this instead of CONFIG_GTA02_REVISION */ -#endif - #endif /* __CONFIG_H */ From c382c5066c178bf3567981d7351a6fed263151d1 Mon Sep 17 00:00:00 2001 From: xiangfu Date: Fri, 20 Jun 2008 22:24:29 -0400 Subject: [PATCH 009/248] blink led all in c code, start add read nand code --- qiboot/config.mk | 3 +- qiboot/include/neo_gta02.h | 17 +- qiboot/src/Makefile | 8 +- qiboot/src/blink_led.c | 55 +++++ qiboot/src/kboot-stage1.lds | 7 +- qiboot/src/led.S | 194 ----------------- qiboot/src/led.c | 29 --- qiboot/src/lowlevel_init.S | 68 ++---- qiboot/src/start.S | 417 ++++++++++++++++++++++++++++++++++++ 9 files changed, 501 insertions(+), 297 deletions(-) create mode 100644 qiboot/src/blink_led.c delete mode 100644 qiboot/src/led.S delete mode 100644 qiboot/src/led.c create mode 100644 qiboot/src/start.S diff --git a/qiboot/config.mk b/qiboot/config.mk index c475739..b45478e 100644 --- a/qiboot/config.mk +++ b/qiboot/config.mk @@ -7,5 +7,6 @@ AS = $(CROSS_COMPILE)as LD = $(CROSS_COMPILE)ld CC = $(CROSS_COMPILE)gcc OBJCOPY = $(CROSS_COMPILE)objcopy +OBJDUMP = $(CROSS_COMPILE)objdump -export CROSS_COMPILE AD LD CC OBJCOPY +export CROSS_COMPILE AD LD CC OBJCOPY OBJDUMP diff --git a/qiboot/include/neo_gta02.h b/qiboot/include/neo_gta02.h index 8f632c9..506149a 100644 --- a/qiboot/include/neo_gta02.h +++ b/qiboot/include/neo_gta02.h @@ -1,11 +1,8 @@ /* * (C) Copyright 2007 OpenMoko, Inc. - * Author: Harald Welte + * Author: xiangfu liu * - * Configuation settings for the FIC Neo1973 GTA02 Linux GSM phone - * - * See file CREDITS for list of people who contributed to this - * project. + * 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 @@ -26,14 +23,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define TEXT_BASE 0x00000000 /* xiangfu add*/ - -#define CFG_ENV_SIZE 0x40000 /* 128k Total Size of Environment Sector */ -/* - * Size of malloc() pool - */ -#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 400*1024) - /* >> CFG_VIDEO_LOGO_MAX_SIZE */ -#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ +#define TEXT_BASE 0x33F80000 /* xiangfu add*/ #endif /* __CONFIG_H */ diff --git a/qiboot/src/Makefile b/qiboot/src/Makefile index 1e052b2..e092d01 100644 --- a/qiboot/src/Makefile +++ b/qiboot/src/Makefile @@ -19,11 +19,11 @@ INCLUDE =../include IMAGE =../image CFLAGS =-Wall -I $(INCLUDE) -g -c -o -all:led.S led.c lowlevel_init.S - $(CC) $(CFLAGS) led_S.o led.S - $(CC) $(CFLAGS) led_C.o led.c +all:start.S blink_led.c lowlevel_init.S + $(CC) $(CFLAGS) start.o start.S + $(CC) $(CFLAGS) blink_led.o blink_led.c $(CC) $(CFLAGS) lowlevel_init.o lowlevel_init.S - $(LD) -T$(LDS) -g led_S.o led_C.o lowlevel_init.o -o led.o + $(LD) -T$(LDS) -g start.o blink_led.o lowlevel_init.o -o led.o $(OBJCOPY) -O binary -S led.o $(IMAGE)/led_on clean: diff --git a/qiboot/src/blink_led.c b/qiboot/src/blink_led.c new file mode 100644 index 0000000..0a5c4df --- /dev/null +++ b/qiboot/src/blink_led.c @@ -0,0 +1,55 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: xiangfu liu + * + * 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 + */ +#define GPBCON (*(volatile unsigned *)0x56000010) +#define GPBDAT (*(volatile unsigned *)0x56000014) +#define GPBDW (*(volatile unsigned *)0x56000018) +#define LED3_ON() (GPBDAT &= ~(0x1)) +#define LED4_ON() (GPBDAT &= ~(0x2)) +#define LED3_OFF() (GPBDAT |= (0x1)) +#define LED4_OFF() (GPBDAT |= (0x2)) + +int delay(int time) +{ + int i=0; + for(i=0;i -.globl _start -_start: b start_code -/* ldr pc, _undefined_instruction - ldr pc, _software_interrupt - ldr pc, _prefetch_abort - ldr pc, _data_abort - ldr pc, _not_used - ldr pc, _irq - ldr pc, _fiq - -_undefined_instruction: .word undefined_instruction -_software_interrupt: .word software_interrupt -_prefetch_abort: .word prefetch_abort -_data_abort: .word data_abort -_not_used: .word not_used -_irq: .word irq -_fiq: .word fiq - - .balignl 16,0xdeadbeef -*/ - -_TEXT_BASE: - .word TEXT_BASE - -.globl _armboot_start -_armboot_start: - .word _start - -/* - * These are defined in the board-specific linker script. - */ -.globl _bss_start -_bss_start: - .word __bss_start - -.globl _bss_end -_bss_end: - .word _end - -#ifdef CONFIG_USE_IRQ -/* IRQ stack memory (calculated at run-time) */ -.globl IRQ_STACK_START -IRQ_STACK_START: - .word 0x0badc0de - -/* IRQ stack memory (calculated at run-time) */ -.globl FIQ_STACK_START -FIQ_STACK_START: - .word 0x0badc0de -#endif - - - -start_code: - - /* - * set the cpu to SVC32 mode - */ - mrs r0,cpsr - bic r0,r0,#0x1f - orr r0,r0,#0xd3 - msr cpsr,r0 - - /* turn off the watchdog */ -# define pWTCON 0x53000000 -# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */ -# define INTSUBMSK 0x4A00001C -# define INTSUBMSK_val 0xffff -# define CAMDIVN 0x4C000018 - - ldr r0, =pWTCON - mov r1, #0x0 - str r1, [r0] - /* - * mask all IRQs by setting all bits in the INTMR - default - */ - 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 */ - 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 - - /* enable uart */ - ldr r0, =0x4c00000c /* clkcon */ - ldr r1, =0x7fff0 /* all clocks on */ - str r1, [r0] - - /* gpio UART0 init */ - ldr r0, =0x56000070 - mov r1, #0xaa - str r1, [r0] - - /* init uart */ - 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] - - bl cpu_init_crit - -stack_setup: - ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ - sub r0, r0, #CFG_MALLOC_LEN /* malloc area */ - sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */ -#ifdef CONFIG_USE_IRQ - sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) -#endif - 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 - - /* blink led */ -.extern blink_led - bl blink_led - -.global delay -delay: - subs r0,r0,#0x1 - bne delay - mov pc,lr - - - -/* - ************************************************************************* - * - * 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 - - diff --git a/qiboot/src/led.c b/qiboot/src/led.c deleted file mode 100644 index 29a32a2..0000000 --- a/qiboot/src/led.c +++ /dev/null @@ -1,29 +0,0 @@ -#define GPBCON (*(volatile unsigned *)0x56000010) -#define GPBDAT (*(volatile unsigned *)0x56000014) -#define GPBDW (*(volatile unsigned *)0x56000018) -#define LED3_ON() (GPBDAT &= ~(0x1)) -#define LED4_ON() (GPBDAT &= ~(0x2)) -#define LED3_OFF() (GPBDAT |= (0x1)) -#define LED4_OFF() (GPBDAT |= (0x2)) - -extern void delay(int time); - -int blink_led() -{ - GPBCON = 0x5; - GPBDW = 0xffff; - while(1) - { - LED3_ON(); - delay(0xffff); - LED3_OFF() ; - delay(0xffff); - - LED4_ON(); - delay(0xffff); - LED4_OFF(); - delay(0xffff); - } - return 1; -} - diff --git a/qiboot/src/lowlevel_init.S b/qiboot/src/lowlevel_init.S index cca9fac..2ce0133 100644 --- a/qiboot/src/lowlevel_init.S +++ b/qiboot/src/lowlevel_init.S @@ -1,14 +1,8 @@ /* * Memory Setup stuff - taken from blob memsetup.S * - * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and - * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) - * * Modified for the FIC Neo1973 GTA01 by Harald Welte * - * 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 @@ -26,11 +20,10 @@ */ /* -* #include -* #include -*/ + * #include + * #include + */ #include -/* some parameters for the board */ /* * @@ -62,7 +55,7 @@ #define B0_Tcos 0x0 /* 0clk */ #define B0_Tacc 0x7 /* 14clk */ #define B0_Tcoh 0x0 /* 0clk */ -#define B0_Tah 0x0 /* 0clk */ +#define B0_Tah 0x0 /* 0clk */ #define B0_Tacp 0x0 #define B0_PMC 0x0 /* normal */ @@ -71,7 +64,7 @@ #define B1_Tcos 0x3 /* 4clk */ #define B1_Tacc 0x3 /* 4clk */ #define B1_Tcoh 0x3 /* 4clk */ -#define B1_Tah 0x0 /* 0clk */ +#define B1_Tah 0x0 /* 0clk */ #define B1_Tacp 0x0 #define B1_PMC 0x0 @@ -79,7 +72,7 @@ #define B2_Tcos 0x0 #define B2_Tacc 0x7 #define B2_Tcoh 0x0 -#define B2_Tah 0x0 +#define B2_Tah 0x0 #define B2_Tacp 0x0 #define B2_PMC 0x0 @@ -87,15 +80,15 @@ #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_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_Tah 0x0 /* 0clk */ #define B4_Tacp 0x0 #define B4_PMC 0x0 /* normal */ @@ -103,26 +96,26 @@ #define B5_Tcos 0x0 /* 0clk */ #define B5_Tacc 0x7 /* 14clk */ #define B5_Tcoh 0x0 /* 0clk */ -#define B5_Tah 0x0 /* 0clk */ +#define B5_Tah 0x0 /* 0clk */ #define B5_Tacp 0x0 #define B5_PMC 0x0 /* normal */ -#define B6_MT 0x3 /* SDRAM */ +#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_MT 0x3 /* SDRAM */ #define B7_Trcd 0x1 /* 3clk */ /* REFRESH parameter */ -#define REFEN 0x1 /* Refresh enable */ +#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 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) */ /**************************************/ @@ -149,30 +142,6 @@ lowlevel_init: orr r1, r1, #0xc0000000 mcr p15, 0, r1, c1, c0, 0 -#if defined(CONFIG_ARCH_GTA01_v4) || defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3) - /* switch on power for NAND */ - ldr r0, =0x56000010 /* GPBCON */ - ldr r1, [r0] - orr r1, r1, #0x10 - str r1, [r0] - - ldr r0, =0x56000014 /* GPBDAT */ - ldr r1, [r0] - orr r1, r1, #(1 <<2) - str r1, [r0] -#endif - -#if defined(CONFIG_ARCH_GTA02_v1) - /* enable KEEPACT(GPJ3) to make sure PMU keeps us alive */ - ldr r0, =0x56000000 /* GPJ base */ - ldr r1, [r0, #0xd0] /* GPJCON */ - orr r1, r1, #(1 << 6) - str r1, [r0, #0xd0] - - ldr r1, [r0, #0xd4] /* GPJDAT */ - orr r1, r1, #(1 << 3) - str r1, [r0, #0xd4] -#elif CONFIG_GTA02_REVISION >= 2 /* enable KEEPACT(GPJ8) to make sure PMU keeps us alive */ ldr r0, =0x56000000 /* GPJ base */ ldr r1, [r0, #0xd0] /* GPJCON */ @@ -182,7 +151,6 @@ lowlevel_init: ldr r1, [r0, #0xd4] /* GPJDAT */ orr r1, r1, #(1 << 8) str r1, [r0, #0xd4] -#endif /* everything is fine now */ mov pc, lr @@ -200,10 +168,6 @@ SMRDATA: .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) -#if CONFIG_GTA02_REVISION >= 2 .word 0xb1 -#else - .word 0xb2 -#endif .word 0x30 .word 0x30 diff --git a/qiboot/src/start.S b/qiboot/src/start.S new file mode 100644 index 0000000..cdae014 --- /dev/null +++ b/qiboot/src/start.S @@ -0,0 +1,417 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * + * 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 +.globl _start +_start: b start_code + ldr pc, _undefined_instruction + ldr pc, _software_interrupt + ldr pc, _prefetch_abort + ldr pc, _data_abort + ldr pc, _not_used + ldr pc, _irq + ldr pc, _fiq + +_undefined_instruction: .word undefined_instruction +_software_interrupt: .word software_interrupt +_prefetch_abort: .word prefetch_abort +_data_abort: .word data_abort +_not_used: .word not_used +_irq: .word irq +_fiq: .word fiq + + .balignl 16,0xdeadbeef +/* + ************************************************************************* + * + * Startup Code (called from the ARM reset exception vector) + * + * do important init only if we don't start from memory! + * relocate armboot to ram + * setup stack + * + ************************************************************************* + */ + +.globl preboot_override +preboot_override: + .word 0 + +/* Must follow preboot_override , so we get a well-known address ! */ +.globl env_override +env_override: + .word 0 + +/* we want to be able to start kboot directly from within NAND flash */ +.globl booted_from_nand +booted_from_nand: + .word 0 +_booted_from_nand: + .word booted_from_nand + + +_TEXT_BASE: + .word TEXT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +/* IRQ stack memory (calculated at run-time) */ +.globl IRQ_STACK_START +IRQ_STACK_START: + .word 0x0badc0de + +/* IRQ stack memory (calculated at run-time) */ +.globl FIQ_STACK_START +FIQ_STACK_START: + .word 0x0badc0de + + +start_code: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + + /* turn off the watchdog */ +# 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 0xffff + 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 +# define UPLLCON 0x4c000008 +# define UPLLCON_val (( 88 << 12) + (8 << 4) + 2) +# define MPLLCON 0x4c000004 +# define MPLLCON_val ((142 << 12) + (7 << 4) + 1) + + ldr r0, =LOCKTIME + mov r1, #0xffffff + str r1, [r0] + + ldr r0, =UPLLCON + ldr r1, =UPLLCON_val + str r1, [r0] + + /* Page 7-23 in s3c2442B manual, seven nops between UPLL and MPLL */ + nop + nop + nop + nop + nop + nop + nop + + ldr r0, =MPLLCON + ldr r1, =MPLLCON_val + str r1, [r0] /* MPLLCON */ + +# define CLKDIVN 0x4C000014 /* clock divisor register */ +# define CLKDIVN_val 7 /* FCLK:HCLK:PCLK = 1:3:6 */ + ldr r0, =CLKDIVN + mov r1, #CLKDIVN_val + str r1, [r0] + + /* enable uart */ + ldr r0, =0x4c00000c /* clkcon */ + ldr r1, =0x7fff0 /* all clocks on */ + str r1, [r0] + + /* gpio UART0 init */ + ldr r0, =0x56000070 + mov r1, #0xaa + str r1, [r0] + + /* init uart */ + 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] + + bl cpu_init_crit +/* + * Size of malloc() pool + */ +#define CFG_ENV_SIZE 0x40000 /* 128k Total Size of Environment Sector */ +#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 400*1024) + /* >> CFG_VIDEO_LOGO_MAX_SIZE */ +#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ +#define CONFIG_STACKSIZE (128*1024) /* regular stack */ +#define CONFIG_STACKSIZE_IRQ (8*1024) /* IRQ stack */ +#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */ +stack_setup: + ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ + sub r0, r0, #CFG_MALLOC_LEN /* malloc area */ + sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */ + sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) + 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 + + /* blink led */ + ldr pc, _start_armboot + +_start_armboot: + .word blink_led + +/* + ************************************************************************* + * + * 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 + +/* + ************************************************************************* + * + * Interrupt handling + * + ************************************************************************* + */ + +@ +@ IRQ stack frame. +@ +#define S_FRAME_SIZE 72 + +#define S_OLD_R0 68 +#define S_PSR 64 +#define S_PC 60 +#define S_LR 56 +#define S_SP 52 + +#define S_IP 48 +#define S_FP 44 +#define S_R10 40 +#define S_R9 36 +#define S_R8 32 +#define S_R7 28 +#define S_R6 24 +#define S_R5 20 +#define S_R4 16 +#define S_R3 12 +#define S_R2 8 +#define S_R1 4 +#define S_R0 0 + +#define MODE_SVC 0x13 +#define I_BIT 0x80 + +/* + * use bad_save_user_regs for abort/prefetch/undef/swi ... + * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling + */ + + .macro bad_save_user_regs + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0-r12 + ldr r2, _armboot_start + sub r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN) + sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack + ldmia r2, {r2 - r3} @ get pc, cpsr + add r0, sp, #S_FRAME_SIZE @ restore sp_SVC + + add r5, sp, #S_SP + mov r1, lr + stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr + mov r0, sp + .endm + + .macro irq_save_user_regs + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0-r12 + add r7, sp, #S_PC + stmdb r7, {sp, lr}^ @ Calling SP, LR + str lr, [r7, #0] @ Save calling PC + mrs r6, spsr + str r6, [r7, #4] @ Save CPSR + str r0, [r7, #8] @ Save OLD_R0 + mov r0, sp + .endm + + .macro irq_restore_user_regs + ldmia sp, {r0 - lr}^ @ Calling r0 - lr + mov r0, r0 + ldr lr, [sp, #S_PC] @ Get PC + add sp, sp, #S_FRAME_SIZE + subs pc, lr, #4 @ return & move spsr_svc into cpsr + .endm + + .macro get_bad_stack + ldr r13, _armboot_start @ setup our mode stack + sub r13, r13, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN) + sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack + + str lr, [r13] @ save caller lr / spsr + mrs lr, spsr + str lr, [r13, #4] + + mov r13, #MODE_SVC @ prepare SVC-Mode + @ msr spsr_c, r13 + msr spsr, r13 + mov lr, pc + movs pc, lr + .endm + + .macro get_irq_stack @ setup IRQ stack + ldr sp, IRQ_STACK_START + .endm + + .macro get_fiq_stack @ setup FIQ stack + ldr sp, FIQ_STACK_START + .endm + +/* + * exception handlers + */ + .align 5 +undefined_instruction: + get_bad_stack + bad_save_user_regs + //bl do_undefined_instruction + + .align 5 +software_interrupt: + get_bad_stack + bad_save_user_regs + //bl do_software_interrupt + + .align 5 +prefetch_abort: + get_bad_stack + bad_save_user_regs + //bl do_prefetch_abort + + .align 5 +data_abort: + get_bad_stack + bad_save_user_regs + //bl do_data_abort + + .align 5 +not_used: + get_bad_stack + bad_save_user_regs + //bl do_not_used + +/* CONFIG_USE_IRQ*/ + .align 5 +irq: + get_irq_stack + irq_save_user_regs + //bl do_irq + irq_restore_user_regs + + .align 5 +fiq: + get_fiq_stack + /* someone ought to write a more effiction fiq_save_user_regs */ + irq_save_user_regs + //bl do_fiq + irq_restore_user_regs From eab58ff419f6206c9c40f85765caaf3e3fc9cf3c Mon Sep 17 00:00:00 2001 From: xiangfu Date: Sat, 28 Jun 2008 19:47:57 -0400 Subject: [PATCH 010/248] delete something we don't need --- qiboot/src/blink_led.c | 5 + qiboot/src/start.S | 213 +---------------------------------------- 2 files changed, 7 insertions(+), 211 deletions(-) diff --git a/qiboot/src/blink_led.c b/qiboot/src/blink_led.c index 0a5c4df..f5abb74 100644 --- a/qiboot/src/blink_led.c +++ b/qiboot/src/blink_led.c @@ -53,3 +53,8 @@ int blink_led() return 0; } +int start_armboot() +{ + blink_led(); + return 0; +} diff --git a/qiboot/src/start.S b/qiboot/src/start.S index cdae014..bf1a7f5 100644 --- a/qiboot/src/start.S +++ b/qiboot/src/start.S @@ -19,53 +19,9 @@ * MA 02111-1307 USA */ #include + .globl _start _start: b start_code - ldr pc, _undefined_instruction - ldr pc, _software_interrupt - ldr pc, _prefetch_abort - ldr pc, _data_abort - ldr pc, _not_used - ldr pc, _irq - ldr pc, _fiq - -_undefined_instruction: .word undefined_instruction -_software_interrupt: .word software_interrupt -_prefetch_abort: .word prefetch_abort -_data_abort: .word data_abort -_not_used: .word not_used -_irq: .word irq -_fiq: .word fiq - - .balignl 16,0xdeadbeef -/* - ************************************************************************* - * - * Startup Code (called from the ARM reset exception vector) - * - * do important init only if we don't start from memory! - * relocate armboot to ram - * setup stack - * - ************************************************************************* - */ - -.globl preboot_override -preboot_override: - .word 0 - -/* Must follow preboot_override , so we get a well-known address ! */ -.globl env_override -env_override: - .word 0 - -/* we want to be able to start kboot directly from within NAND flash */ -.globl booted_from_nand -booted_from_nand: - .word 0 -_booted_from_nand: - .word booted_from_nand - _TEXT_BASE: .word TEXT_BASE @@ -85,17 +41,6 @@ _bss_start: _bss_end: .word _end -/* IRQ stack memory (calculated at run-time) */ -.globl IRQ_STACK_START -IRQ_STACK_START: - .word 0x0badc0de - -/* IRQ stack memory (calculated at run-time) */ -.globl FIQ_STACK_START -FIQ_STACK_START: - .word 0x0badc0de - - start_code: /* * set the cpu to SVC32 mode @@ -192,11 +137,6 @@ start_code: str r1, [r0, #0x28] bl cpu_init_crit -/* - * Size of malloc() pool - */ -#define CFG_ENV_SIZE 0x40000 /* 128k Total Size of Environment Sector */ -#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 400*1024) /* >> CFG_VIDEO_LOGO_MAX_SIZE */ #define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ #define CONFIG_STACKSIZE (128*1024) /* regular stack */ @@ -204,7 +144,6 @@ start_code: #define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */ stack_setup: ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ - sub r0, r0, #CFG_MALLOC_LEN /* malloc area */ sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */ sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) sub sp, r0, #12 /* leave 3 words for abort-stack */ @@ -224,7 +163,7 @@ clbss_l: ldr pc, _start_armboot _start_armboot: - .word blink_led + .word start_armboot /* ************************************************************************* @@ -267,151 +206,3 @@ cpu_init_crit: mov lr, ip mov pc, lr -/* - ************************************************************************* - * - * Interrupt handling - * - ************************************************************************* - */ - -@ -@ IRQ stack frame. -@ -#define S_FRAME_SIZE 72 - -#define S_OLD_R0 68 -#define S_PSR 64 -#define S_PC 60 -#define S_LR 56 -#define S_SP 52 - -#define S_IP 48 -#define S_FP 44 -#define S_R10 40 -#define S_R9 36 -#define S_R8 32 -#define S_R7 28 -#define S_R6 24 -#define S_R5 20 -#define S_R4 16 -#define S_R3 12 -#define S_R2 8 -#define S_R1 4 -#define S_R0 0 - -#define MODE_SVC 0x13 -#define I_BIT 0x80 - -/* - * use bad_save_user_regs for abort/prefetch/undef/swi ... - * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling - */ - - .macro bad_save_user_regs - sub sp, sp, #S_FRAME_SIZE - stmia sp, {r0 - r12} @ Calling r0-r12 - ldr r2, _armboot_start - sub r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN) - sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack - ldmia r2, {r2 - r3} @ get pc, cpsr - add r0, sp, #S_FRAME_SIZE @ restore sp_SVC - - add r5, sp, #S_SP - mov r1, lr - stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr - mov r0, sp - .endm - - .macro irq_save_user_regs - sub sp, sp, #S_FRAME_SIZE - stmia sp, {r0 - r12} @ Calling r0-r12 - add r7, sp, #S_PC - stmdb r7, {sp, lr}^ @ Calling SP, LR - str lr, [r7, #0] @ Save calling PC - mrs r6, spsr - str r6, [r7, #4] @ Save CPSR - str r0, [r7, #8] @ Save OLD_R0 - mov r0, sp - .endm - - .macro irq_restore_user_regs - ldmia sp, {r0 - lr}^ @ Calling r0 - lr - mov r0, r0 - ldr lr, [sp, #S_PC] @ Get PC - add sp, sp, #S_FRAME_SIZE - subs pc, lr, #4 @ return & move spsr_svc into cpsr - .endm - - .macro get_bad_stack - ldr r13, _armboot_start @ setup our mode stack - sub r13, r13, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN) - sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack - - str lr, [r13] @ save caller lr / spsr - mrs lr, spsr - str lr, [r13, #4] - - mov r13, #MODE_SVC @ prepare SVC-Mode - @ msr spsr_c, r13 - msr spsr, r13 - mov lr, pc - movs pc, lr - .endm - - .macro get_irq_stack @ setup IRQ stack - ldr sp, IRQ_STACK_START - .endm - - .macro get_fiq_stack @ setup FIQ stack - ldr sp, FIQ_STACK_START - .endm - -/* - * exception handlers - */ - .align 5 -undefined_instruction: - get_bad_stack - bad_save_user_regs - //bl do_undefined_instruction - - .align 5 -software_interrupt: - get_bad_stack - bad_save_user_regs - //bl do_software_interrupt - - .align 5 -prefetch_abort: - get_bad_stack - bad_save_user_regs - //bl do_prefetch_abort - - .align 5 -data_abort: - get_bad_stack - bad_save_user_regs - //bl do_data_abort - - .align 5 -not_used: - get_bad_stack - bad_save_user_regs - //bl do_not_used - -/* CONFIG_USE_IRQ*/ - .align 5 -irq: - get_irq_stack - irq_save_user_regs - //bl do_irq - irq_restore_user_regs - - .align 5 -fiq: - get_fiq_stack - /* someone ought to write a more effiction fiq_save_user_regs */ - irq_save_user_regs - //bl do_fiq - irq_restore_user_regs From fa9c4976fad672c16c6771411c1c9ab8fd48f88e Mon Sep 17 00:00:00 2001 From: xiangfu Date: Tue, 8 Jul 2008 18:48:48 -0400 Subject: [PATCH 011/248] blink led in other way ,but not read from NAND --- qiboot/Makefile | 2 - qiboot/README | 6 -- qiboot/src/Makefile | 30 ++++++--- qiboot/src/blink_led.c | 6 -- qiboot/src/kboot-stage1.lds | 2 +- qiboot/src/led_on.S | 37 +++++++++++ qiboot/src/nand_read.c | 124 ++++++++++++++++++++++++++++++++++++ qiboot/src/start.S | 9 +-- qiboot/src/start_kboot.c | 48 ++++++++++++++ 9 files changed, 233 insertions(+), 31 deletions(-) create mode 100644 qiboot/src/led_on.S create mode 100644 qiboot/src/nand_read.c create mode 100644 qiboot/src/start_kboot.c diff --git a/qiboot/Makefile b/qiboot/Makefile index b49ee49..4d7bb46 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -14,8 +14,6 @@ # MA 02111-1307 USA # -include ./config.mk - all : cd src ; make all diff --git a/qiboot/README b/qiboot/README index ab9cad4..e69de29 100644 --- a/qiboot/README +++ b/qiboot/README @@ -1,6 +0,0 @@ -use follow command to run this program -start OpenOCD,then do this - - > reset halt - > load_image /path/to/led_on 0 - > resume diff --git a/qiboot/src/Makefile b/qiboot/src/Makefile index e092d01..27d4458 100644 --- a/qiboot/src/Makefile +++ b/qiboot/src/Makefile @@ -14,20 +14,32 @@ # MA 02111-1307 USA # -LDS =kboot-stage1.lds -INCLUDE =../include -IMAGE =../image -CFLAGS =-Wall -I $(INCLUDE) -g -c -o +include ../config.mk -all:start.S blink_led.c lowlevel_init.S +LDS = kboot-stage1.lds +INCLUDE = ../include +IMAGE = ../image +CFLAGS = -Wall -I $(INCLUDE) -g -c -o + +START = start.o lowlevel_init.o +COBJS = start_kboot.o nand_read.o + +SRCS := $(START: .o=.S) $(COBJS: .o=.c) + +all:start.S lowlevel_init.S nand_read.c start_kboot.c $(CC) $(CFLAGS) start.o start.S - $(CC) $(CFLAGS) blink_led.o blink_led.c $(CC) $(CFLAGS) lowlevel_init.o lowlevel_init.S - $(LD) -T$(LDS) -g start.o blink_led.o lowlevel_init.o -o led.o - $(OBJCOPY) -O binary -S led.o $(IMAGE)/led_on + $(CC) $(CFLAGS) nand_read.o nand_read.c + $(CC) $(CFLAGS) start_kboot.o start_kboot.c + $(LD) -T$(LDS) -g $(START) $(COBJS) -o start_kboot_all.o + $(OBJCOPY) -O binary -S start_kboot_all.o $(IMAGE)/start + +blink_led:led_on.S + $(CC) $(CFLAGS) led_on.o led_on.S + $(LD) -g led_on.o -o led_on_temp.o + $(OBJCOPY) -O binary -S led_on_temp.o $(IMAGE)/led_on clean: rm -f *.o - rm -f led_on rm -f $(IMAGE)/* diff --git a/qiboot/src/blink_led.c b/qiboot/src/blink_led.c index f5abb74..92c8211 100644 --- a/qiboot/src/blink_led.c +++ b/qiboot/src/blink_led.c @@ -52,9 +52,3 @@ int blink_led() } return 0; } - -int start_armboot() -{ - blink_led(); - return 0; -} diff --git a/qiboot/src/kboot-stage1.lds b/qiboot/src/kboot-stage1.lds index a1c9529..6393fdb 100644 --- a/qiboot/src/kboot-stage1.lds +++ b/qiboot/src/kboot-stage1.lds @@ -34,7 +34,7 @@ SECTIONS { start.o (.text) lowlevel_init.o(.text) - blink_led.o (.text) + start_kboot.o (.text) *(.text) } diff --git a/qiboot/src/led_on.S b/qiboot/src/led_on.S new file mode 100644 index 0000000..1ebcaa9 --- /dev/null +++ b/qiboot/src/led_on.S @@ -0,0 +1,37 @@ +_start: + mov ip, sp + stmfd sp!, {fp, ip, lr, pc} + sub fp, ip, #4 + ldr r2, .L4 + mov r3, #5 + str r3, [r2, #0] + ldr r2, .L4+4 + ldr r3, .L4+8 + str r3, [r2, #0] +.L2: + ldr r2, .L4+12 + ldr r3, .L4+12 + ldr r3, [r3, #0] + bic r3, r3, #1 + str r3, [r2, #0] + ldr r0, .L4+8 + bl delay + ldr r2, .L4+12 + ldr r3, .L4+12 + ldr r3, [r3, #0] + orr r3, r3, #1 + str r3, [r2, #0] + ldr r0, .L4+8 + bl delay + b .L2 +.L5: + .align 2 +.L4: + .word 1442840592 + .word 1442840600 + .word 65535 + .word 1442840596 + delay: + subs r0,r0,#0x1 + bne delay + mov pc,lr diff --git a/qiboot/src/nand_read.c b/qiboot/src/nand_read.c new file mode 100644 index 0000000..2ae0cbe --- /dev/null +++ b/qiboot/src/nand_read.c @@ -0,0 +1,124 @@ +/* + * 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 + * Date : $Date: 2004/02/04 10:37:37 $ + * + * u-boot integration and bad-block skipping (C) 2006 by OpenMoko, Inc. + * Author: Harald Welte + */ + + +#define NAND_CMD_READ0 0 +#define NAND_CMD_READ1 1 +/* Extended commands for large page devices */ +#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=0; + 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)#endif + +static int is_bad_block(unsigned long i) +{ + unsigned char data; + unsigned long page_num; + + nand_clear_RnB(); + page_num = i >> 11; /* 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 addr) +{ + unsigned short *ptr16 = (unsigned short *)buf; + unsigned int i, page_num; + + nand_clear_RnB(); + + NFCMD = NAND_CMD_READ0; + page_num = addr >> 11; /* addr / 2048 */ + /* Write Address */ + NFADDR = 0; + NFADDR = 0; + NFADDR = page_num & 0xff; + NFADDR = (page_num >> 8) & 0xff; + NFADDR = (page_num >> 16) & 0xff; + NFCMD = NAND_CMD_READSTART; + nand_wait(); + + for (i = 0; i < NAND_PAGE_SIZE/2; i++) { + *ptr16 = NFDATA16; + ptr16++; + } + return NAND_PAGE_SIZE; +} + +/* low level nand read function */ + int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size) +{ + int i, j; + + if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) + return -1; /* invalid alignment */ + + /* chip Enable */ + nand_select(); + nand_clear_RnB(); + for (i=0; i<10; i++); + + for (i=start_addr; i < (start_addr + size);) { + j = nand_read_page_ll(buf, i); + i += j; + buf += j; + } + + /* chip Disable */ + nand_deselect(); + + return 0; +} diff --git a/qiboot/src/start.S b/qiboot/src/start.S index bf1a7f5..c98a55b 100644 --- a/qiboot/src/start.S +++ b/qiboot/src/start.S @@ -1,7 +1,7 @@ /* * (C) Copyright 2007 OpenMoko, Inc. * - * Configuation settings for the FIC Neo GTA02 Linux GSM phone + * 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 @@ -26,10 +26,6 @@ _start: b start_code _TEXT_BASE: .word TEXT_BASE -.globl _armboot_start -_armboot_start: - .word _start - /* * These are defined in the board-specific linker script. */ @@ -159,11 +155,10 @@ clbss_l: cmp r0, r1 ble clbss_l - /* blink led */ ldr pc, _start_armboot _start_armboot: - .word start_armboot + .word start_kboot /* ************************************************************************* diff --git a/qiboot/src/start_kboot.c b/qiboot/src/start_kboot.c new file mode 100644 index 0000000..581cb6e --- /dev/null +++ b/qiboot/src/start_kboot.c @@ -0,0 +1,48 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: xiangfu liu + * + * 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 + */ + +unsigned char buf[]={ +0x0d,0xc0,0xa0,0xe1,0x00,0xd8,0x2d,0xe9,0x04,0xb0,0x4c,0xe2,0x4c,0x20,0x9f,0xe5, +0x05,0x30,0xa0,0xe3,0x00,0x30,0x82,0xe5,0x44,0x20,0x9f,0xe5,0x44,0x30,0x9f,0xe5, +0x00,0x30,0x82,0xe5,0x40,0x20,0x9f,0xe5,0x3c,0x30,0x9f,0xe5,0x00,0x30,0x93,0xe5, +0x01,0x30,0xc3,0xe3,0x00,0x30,0x82,0xe5,0x28,0x00,0x9f,0xe5,0x0b,0x00,0x00,0xeb, +0x24,0x20,0x9f,0xe5,0x20,0x30,0x9f,0xe5,0x00,0x30,0x93,0xe5,0x01,0x30,0x83,0xe3, +0x00,0x30,0x82,0xe5,0x0c,0x00,0x9f,0xe5,0x04,0x00,0x00,0xeb,0xf0,0xff,0xff,0xea, +0x10,0x00,0x00,0x56,0x18,0x00,0x00,0x56,0xff,0xff,0x00,0x00,0x14,0x00,0x00,0x56, +0x01,0x00,0x50,0xe2,0xfd,0xff,0xff,0x1a,0x0e,0xf0,0xa0,0xe1,0x0a}; + +#define ADDR ((volatile unsigned *)&buf) + +int start_kboot() +{ + /* nand_read_ll(buf, 0, sizeof(buf));*/ + /* + void (*fp)(void)=(void (*)(void))&buf; + (fp)(); + */ + asm volatile("mov pc, %0\n" + : /* output */ + :"r"(ADDR) /* input */ + ); + return 0; +} + From 50aa233b9a449d7f67068906ea57e4bd469ec516 Mon Sep 17 00:00:00 2001 From: xiangfu Date: Sat, 12 Jul 2008 22:57:57 -0400 Subject: [PATCH 012/248] file a way to debug the nand_read.c if it's work the one led will be always on if something wrong blink two led under Power Button --- qiboot/src/Makefile | 3 ++- qiboot/src/blink_led.c | 1 + qiboot/src/blink_led.h | 23 +++++++++++++++++++++++ qiboot/src/nand_read.c | 39 ++++++++++++++++++++++++++++----------- qiboot/src/nand_read.h | 18 ++++++++++++++++++ qiboot/src/start_kboot.c | 12 ++++++++++-- 6 files changed, 82 insertions(+), 14 deletions(-) create mode 100644 qiboot/src/blink_led.h create mode 100644 qiboot/src/nand_read.h diff --git a/qiboot/src/Makefile b/qiboot/src/Makefile index 27d4458..fb3f4a8 100644 --- a/qiboot/src/Makefile +++ b/qiboot/src/Makefile @@ -22,7 +22,7 @@ IMAGE = ../image CFLAGS = -Wall -I $(INCLUDE) -g -c -o START = start.o lowlevel_init.o -COBJS = start_kboot.o nand_read.o +COBJS = start_kboot.o nand_read.o blink_led.o SRCS := $(START: .o=.S) $(COBJS: .o=.c) @@ -30,6 +30,7 @@ all:start.S lowlevel_init.S nand_read.c start_kboot.c $(CC) $(CFLAGS) start.o start.S $(CC) $(CFLAGS) lowlevel_init.o lowlevel_init.S $(CC) $(CFLAGS) nand_read.o nand_read.c + $(CC) $(CFLAGS) blink_led.o blink_led.c $(CC) $(CFLAGS) start_kboot.o start_kboot.c $(LD) -T$(LDS) -g $(START) $(COBJS) -o start_kboot_all.o $(OBJCOPY) -O binary -S start_kboot_all.o $(IMAGE)/start diff --git a/qiboot/src/blink_led.c b/qiboot/src/blink_led.c index 92c8211..bd43a52 100644 --- a/qiboot/src/blink_led.c +++ b/qiboot/src/blink_led.c @@ -19,6 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ +#include "blink_led.h" #define GPBCON (*(volatile unsigned *)0x56000010) #define GPBDAT (*(volatile unsigned *)0x56000014) #define GPBDW (*(volatile unsigned *)0x56000018) diff --git a/qiboot/src/blink_led.h b/qiboot/src/blink_led.h new file mode 100644 index 0000000..051df59 --- /dev/null +++ b/qiboot/src/blink_led.h @@ -0,0 +1,23 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: xiangfu liu + * + * 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 + */ + +int blink_led(); diff --git a/qiboot/src/nand_read.c b/qiboot/src/nand_read.c index 2ae0cbe..0108a14 100644 --- a/qiboot/src/nand_read.c +++ b/qiboot/src/nand_read.c @@ -15,22 +15,24 @@ * Author: Harald Welte */ +/*#include +#include +*/ +#include "nand_read.h" -#define NAND_CMD_READ0 0 -#define NAND_CMD_READ1 1 -/* Extended commands for large page devices */ -#define NAND_CMD_READSTART 0x30 +#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 __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 NFDATA16 __REGw(NF_BASE + 0x10) #define NFSTAT __REGb(NF_BASE + 0x20) #define NFSTAT_BUSY 1 #define nand_select() (NFCONT &= ~(1 << 1)) @@ -39,7 +41,8 @@ static inline void nand_wait(void) { - int i=0; + int i; + while (!(NFSTAT & NFSTAT_BUSY)) for (i=0; i<10; i++); } @@ -49,7 +52,7 @@ static inline void nand_wait(void) #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)#endif +#define NAND_BLOCK_SIZE (NAND_PAGE_SIZE * 64) static int is_bad_block(unsigned long i) { @@ -81,6 +84,7 @@ static int nand_read_page_ll(unsigned char *buf, unsigned long addr) nand_clear_RnB(); NFCMD = NAND_CMD_READ0; + page_num = addr >> 11; /* addr / 2048 */ /* Write Address */ NFADDR = 0; @@ -95,11 +99,12 @@ static int nand_read_page_ll(unsigned char *buf, unsigned long addr) *ptr16 = NFDATA16; ptr16++; } + return NAND_PAGE_SIZE; } /* low level nand read function */ - int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size) +int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size) { int i, j; @@ -112,6 +117,17 @@ static int nand_read_page_ll(unsigned char *buf, unsigned long addr) for (i=0; i<10; i++); for (i=start_addr; i < (start_addr + size);) { + + if (i % NAND_BLOCK_SIZE == 0) { + if (is_bad_block(i) || + is_bad_block(i + NAND_PAGE_SIZE)) { + /* Bad block */ + i += NAND_BLOCK_SIZE; + size += NAND_BLOCK_SIZE; + continue; + } + } + j = nand_read_page_ll(buf, i); i += j; buf += j; @@ -122,3 +138,4 @@ static int nand_read_page_ll(unsigned char *buf, unsigned long addr) return 0; } + diff --git a/qiboot/src/nand_read.h b/qiboot/src/nand_read.h new file mode 100644 index 0000000..fa5d938 --- /dev/null +++ b/qiboot/src/nand_read.h @@ -0,0 +1,18 @@ +/* + * 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 + * Date : $Date: 2004/02/04 10:37:37 $ + * + * u-boot integration and bad-block skipping (C) 2006 by OpenMoko, Inc. + * Author: Harald Welte + */ + +int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size); diff --git a/qiboot/src/start_kboot.c b/qiboot/src/start_kboot.c index 581cb6e..2ae0449 100644 --- a/qiboot/src/start_kboot.c +++ b/qiboot/src/start_kboot.c @@ -19,7 +19,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ - +#include "blink_led.h" +#include "nand_read.h" +/* unsigned char buf[]={ 0x0d,0xc0,0xa0,0xe1,0x00,0xd8,0x2d,0xe9,0x04,0xb0,0x4c,0xe2,0x4c,0x20,0x9f,0xe5, 0x05,0x30,0xa0,0xe3,0x00,0x30,0x82,0xe5,0x44,0x20,0x9f,0xe5,0x44,0x30,0x9f,0xe5, @@ -29,16 +31,22 @@ unsigned char buf[]={ 0x00,0x30,0x82,0xe5,0x0c,0x00,0x9f,0xe5,0x04,0x00,0x00,0xeb,0xf0,0xff,0xff,0xea, 0x10,0x00,0x00,0x56,0x18,0x00,0x00,0x56,0xff,0xff,0x00,0x00,0x14,0x00,0x00,0x56, 0x01,0x00,0x50,0xe2,0xfd,0xff,0xff,0x1a,0x0e,0xf0,0xa0,0xe1,0x0a}; +*/ +unsigned char buf[124]; #define ADDR ((volatile unsigned *)&buf) int start_kboot() { - /* nand_read_ll(buf, 0, sizeof(buf));*/ + if(nand_read_ll(buf, 0, sizeof(buf))==-1) { + blink_led(); + } + /* void (*fp)(void)=(void (*)(void))&buf; (fp)(); */ + asm volatile("mov pc, %0\n" : /* output */ :"r"(ADDR) /* input */ From 3840e0b9d0008ab983c3fc33f4c3351c16631342 Mon Sep 17 00:00:00 2001 From: xiangfu Date: Sun, 13 Jul 2008 10:53:56 -0400 Subject: [PATCH 013/248] modified *.h add define --- qiboot/src/Makefile | 2 +- qiboot/src/blink_led.h | 5 +++++ qiboot/src/nand_read.h | 4 ++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/qiboot/src/Makefile b/qiboot/src/Makefile index fb3f4a8..df07141 100644 --- a/qiboot/src/Makefile +++ b/qiboot/src/Makefile @@ -43,4 +43,4 @@ blink_led:led_on.S clean: rm -f *.o rm -f $(IMAGE)/* - + rm -f *~ diff --git a/qiboot/src/blink_led.h b/qiboot/src/blink_led.h index 051df59..b00d260 100644 --- a/qiboot/src/blink_led.h +++ b/qiboot/src/blink_led.h @@ -20,4 +20,9 @@ * MA 02111-1307 USA */ +#ifndef __BLINK_LED_H +#define __BLINK_LED_H + int blink_led(); + +#define /* __BLINK_LED_H */ diff --git a/qiboot/src/nand_read.h b/qiboot/src/nand_read.h index fa5d938..71aeda5 100644 --- a/qiboot/src/nand_read.h +++ b/qiboot/src/nand_read.h @@ -14,5 +14,9 @@ * u-boot integration and bad-block skipping (C) 2006 by OpenMoko, Inc. * Author: Harald Welte */ +#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 */ From 05afbb65a7a81b642bc51b4ee06384ec49ef1ed7 Mon Sep 17 00:00:00 2001 From: xiangfu Date: Sun, 13 Jul 2008 11:05:36 -0400 Subject: [PATCH 014/248] corrent the blink_led.h file --- qiboot/src/blink_led.h | 2 +- qiboot/src/start_kboot.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/qiboot/src/blink_led.h b/qiboot/src/blink_led.h index b00d260..bc40f39 100644 --- a/qiboot/src/blink_led.h +++ b/qiboot/src/blink_led.h @@ -25,4 +25,4 @@ int blink_led(); -#define /* __BLINK_LED_H */ +#endif /* __BLINK_LED_H */ diff --git a/qiboot/src/start_kboot.c b/qiboot/src/start_kboot.c index 2ae0449..70b262d 100644 --- a/qiboot/src/start_kboot.c +++ b/qiboot/src/start_kboot.c @@ -32,13 +32,13 @@ unsigned char buf[]={ 0x10,0x00,0x00,0x56,0x18,0x00,0x00,0x56,0xff,0xff,0x00,0x00,0x14,0x00,0x00,0x56, 0x01,0x00,0x50,0xe2,0xfd,0xff,0xff,0x1a,0x0e,0xf0,0xa0,0xe1,0x0a}; */ -unsigned char buf[124]; +unsigned char buf[2048]; #define ADDR ((volatile unsigned *)&buf) int start_kboot() { - if(nand_read_ll(buf, 0, sizeof(buf))==-1) { + if(nand_read_ll(buf, 0x32000000, sizeof(buf))==-1) { blink_led(); } From 12ba156cfbeef221771540561ca8c194fd1f61d8 Mon Sep 17 00:00:00 2001 From: xiangfu Date: Sun, 13 Jul 2008 13:20:35 -0400 Subject: [PATCH 015/248] try to debug the nand_read --- qiboot/src/blink_led.c | 80 ++++++++++++++++++++++++++++------------ qiboot/src/blink_led.h | 13 +++++++ qiboot/src/nand_read.c | 54 +++++++++++++-------------- qiboot/src/start_kboot.c | 12 ++---- 4 files changed, 101 insertions(+), 58 deletions(-) diff --git a/qiboot/src/blink_led.c b/qiboot/src/blink_led.c index bd43a52..ed906aa 100644 --- a/qiboot/src/blink_led.c +++ b/qiboot/src/blink_led.c @@ -20,36 +20,70 @@ * MA 02111-1307 USA */ #include "blink_led.h" -#define GPBCON (*(volatile unsigned *)0x56000010) -#define GPBDAT (*(volatile unsigned *)0x56000014) -#define GPBDW (*(volatile unsigned *)0x56000018) -#define LED3_ON() (GPBDAT &= ~(0x1)) -#define LED4_ON() (GPBDAT &= ~(0x2)) -#define LED3_OFF() (GPBDAT |= (0x1)) -#define LED4_OFF() (GPBDAT |= (0x2)) int delay(int time) { - int i=0; - for(i=0;i */ #include "nand_read.h" +#include "blink_led.h" #define NAND_CMD_READ0 0 #define NAND_CMD_READSTART 0x30 @@ -106,36 +107,35 @@ static int nand_read_page_ll(unsigned char *buf, unsigned long addr) /* low level nand read function */ int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size) { - int i, j; + int i, j; - if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) - return -1; /* invalid alignment */ + if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) + return -1; /* invalid alignment */ - /* chip Enable */ - nand_select(); - nand_clear_RnB(); - for (i=0; i<10; i++); + /* chip Enable */ + nand_select(); + nand_clear_RnB(); + for (i=0; i<10; i++); - for (i=start_addr; i < (start_addr + size);) { + for (i=start_addr; i < (start_addr + size);) { + if (i % NAND_BLOCK_SIZE == 0) { + if (is_bad_block(i) || + is_bad_block(i + NAND_PAGE_SIZE)) { + orange_on(1); + i += NAND_BLOCK_SIZE; + size += NAND_BLOCK_SIZE; + continue; + } + } + blue_on(1); + j = nand_read_page_ll(buf, i); + i += j; + /* buf += j;*/ + } - if (i % NAND_BLOCK_SIZE == 0) { - if (is_bad_block(i) || - is_bad_block(i + NAND_PAGE_SIZE)) { - /* Bad block */ - i += NAND_BLOCK_SIZE; - size += NAND_BLOCK_SIZE; - continue; - } - } - - j = nand_read_page_ll(buf, i); - i += j; - buf += j; - } - - /* chip Disable */ - nand_deselect(); - - return 0; + /* chip Disable */ + nand_deselect(); + + return 0; } diff --git a/qiboot/src/start_kboot.c b/qiboot/src/start_kboot.c index 70b262d..f1f8bec 100644 --- a/qiboot/src/start_kboot.c +++ b/qiboot/src/start_kboot.c @@ -38,19 +38,15 @@ unsigned char buf[2048]; int start_kboot() { - if(nand_read_ll(buf, 0x32000000, sizeof(buf))==-1) { - blink_led(); + if(nand_read_ll(buf, 0x32000000, sizeof(buf))==-1) + { + while(1){blink_led(1);} } - /* - void (*fp)(void)=(void (*)(void))&buf; - (fp)(); - */ - asm volatile("mov pc, %0\n" : /* output */ :"r"(ADDR) /* input */ ); + return 0; } - From b92d8222aa948a56a3d4b3f5c03eb6cd4cdef8a9 Mon Sep 17 00:00:00 2001 From: xiangfu Date: Thu, 24 Jul 2008 22:27:23 -0400 Subject: [PATCH 016/248] add serial output function, Thanks Dennis , his patch make me clear. Thank for Andy Green help. --- qiboot/Makefile | 46 +++++++++++++++++++++++++++++++++---- qiboot/config.mk | 1 + qiboot/include/blink_led.h | 41 +++++++++++++++++++++++++++++++++ qiboot/include/nand_read.h | 22 ++++++++++++++++++ qiboot/include/serial.h | 32 ++++++++++++++++++++++++++ qiboot/src/blink_led.c | 2 +- qiboot/src/kboot-stage1.lds | 26 +++++++++++++++------ qiboot/src/serial.c | 33 ++++++++++++++++++++++++++ qiboot/src/start_kboot.c | 16 +++++++++---- 9 files changed, 201 insertions(+), 18 deletions(-) create mode 100644 qiboot/include/blink_led.h create mode 100644 qiboot/include/nand_read.h create mode 100644 qiboot/include/serial.h create mode 100644 qiboot/src/serial.c diff --git a/qiboot/Makefile b/qiboot/Makefile index 4d7bb46..bfd6245 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -14,10 +14,46 @@ # MA 02111-1307 USA # -all : - cd src ; make all +include config.mk + +LDS = src/kboot-stage1.lds +INCLUDE = include +IMAGE_DIR = image +#CFLAGS = -Wall -I $(INCLUDE) -msoft-float -g -c +CFLAGS = -Wall -I $(INCLUDE) -g -c +LDFLAGS = +#START = start.o lowlevel_init.o +S_SRCS = src/start.S src/lowlevel_init.S +S_OBJS = $(patsubst %.S,%.o, $(S_SRCS)) +C_SRCS = $(wildcard src/*.c) +C_OBJS = $(patsubst %.c,%.o, $(C_SRCS)) + +#SRCS := $(START: .o=.S) $(COBJS: .o=.c) +SRCS = ${S_SRCS} ${C_SRCS} +OBJS = ${S_OBJS} ${C_OBJS} + +TARGET = src/start_kboot_all +IMAGE = $(IMAGE_DIR)/start + +%.o: %.S + @$(CC) $(CFLAGS) -o $@ $< + +%.o: %.c + @$(CC) $(CFLAGS) -o $@ $< + +all:${TARGET} + +${OBJS}:${SRCS} + +${TARGET}:${OBJS} + $(LD) ${LDFLAGS} -T$(LDS) -g $(OBJS) -o ${TARGET} + $(OBJCOPY) -O binary -S ${TARGET} ${IMAGE} + $(OBJDUMP) -D ${TARGET} >${IMAGE}.dis + +blink_led:src/led_on.S + $(CC) $(CFLAGS) led_on.o led_on.S + $(LD) -g led_on.o -o led_on_temp.o + $(OBJCOPY) -O binary -S led_on_temp.o $(IMAGE)/led_on clean: - cd src ; make clean - - + rm -f src/*.o src/*~ ${IMAGE}* ${TARGET} diff --git a/qiboot/config.mk b/qiboot/config.mk index b45478e..52c0148 100644 --- a/qiboot/config.mk +++ b/qiboot/config.mk @@ -1,6 +1,7 @@ # # Include the make variables (CC, etc...) # +#CROSS_COMPILE=arm-softfloat-linux-gnu- CROSS_COMPILE=arm-angstrom-linux-gnueabi- AS = $(CROSS_COMPILE)as diff --git a/qiboot/include/blink_led.h b/qiboot/include/blink_led.h new file mode 100644 index 0000000..8485404 --- /dev/null +++ b/qiboot/include/blink_led.h @@ -0,0 +1,41 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: xiangfu liu + * + * 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)) + +#define ORANGE 1; +#define BLUE 0; + +int orange_on(int times); +int blue_on(int times); +int blink_led(void); + +#endif /* __BLINK_LED_H */ diff --git a/qiboot/include/nand_read.h b/qiboot/include/nand_read.h new file mode 100644 index 0000000..71aeda5 --- /dev/null +++ b/qiboot/include/nand_read.h @@ -0,0 +1,22 @@ +/* + * 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 + * Date : $Date: 2004/02/04 10:37:37 $ + * + * u-boot integration and bad-block skipping (C) 2006 by OpenMoko, Inc. + * Author: Harald Welte + */ +#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 */ diff --git a/qiboot/include/serial.h b/qiboot/include/serial.h new file mode 100644 index 0000000..053c712 --- /dev/null +++ b/qiboot/include/serial.h @@ -0,0 +1,32 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: xiangfu liu + * + * 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 + */ + +#define rUTXH0 (*(volatile unsigned char *)0x50000023) +#define UTRSTAT (*(volatile unsigned char *)0x50000010) + +/* +#define PUT_CHAR() (rUTXH0 +#define ORANGE_OFF() (GPBDAT &= ~(0x1)) +*/ + +void serial_puti (const int i); + diff --git a/qiboot/src/blink_led.c b/qiboot/src/blink_led.c index ed906aa..fa4482e 100644 --- a/qiboot/src/blink_led.c +++ b/qiboot/src/blink_led.c @@ -66,7 +66,7 @@ int blue_on(int times) return 0; } -int blink_led() +int blink_led(void) { set_GPB(); diff --git a/qiboot/src/kboot-stage1.lds b/qiboot/src/kboot-stage1.lds index 6393fdb..8cc49f6 100644 --- a/qiboot/src/kboot-stage1.lds +++ b/qiboot/src/kboot-stage1.lds @@ -32,23 +32,35 @@ SECTIONS . = ALIGN(4); .text : { - start.o (.text) - lowlevel_init.o(.text) - start_kboot.o (.text) + src/start.o (.text) + src/lowlevel_init.o(.text) + src/start_kboot.o (.text) *(.text) } . = ALIGN(4); - .rodata : { *(.rodata) } + .rodata : + { + *(.rodata) + } . = ALIGN(4); - .data : { *(.data) } + .data : + { + *(.data) + } . = ALIGN(4); - .got : { *(.got) } + .got : + { + *(.got) + } . = ALIGN(4); __bss_start = .; - .bss : { *(.bss) } + .bss : + { + *(.bss) + } _end = .; } diff --git a/qiboot/src/serial.c b/qiboot/src/serial.c new file mode 100644 index 0000000..66fe066 --- /dev/null +++ b/qiboot/src/serial.c @@ -0,0 +1,33 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: xiangfu liu + * + * 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 + +/* + * Output a single byte to the serial port. + */ +void serial_puti (const int i) +{ + while (!(UTRSTAT & 0x2)); + + rUTXH0 |= i; +} diff --git a/qiboot/src/start_kboot.c b/qiboot/src/start_kboot.c index f1f8bec..935be30 100644 --- a/qiboot/src/start_kboot.c +++ b/qiboot/src/start_kboot.c @@ -21,6 +21,7 @@ */ #include "blink_led.h" #include "nand_read.h" +#include "serial.h" /* unsigned char buf[]={ 0x0d,0xc0,0xa0,0xe1,0x00,0xd8,0x2d,0xe9,0x04,0xb0,0x4c,0xe2,0x4c,0x20,0x9f,0xe5, @@ -36,14 +37,19 @@ unsigned char buf[2048]; #define ADDR ((volatile unsigned *)&buf) -int start_kboot() +int start_kboot(void) { - if(nand_read_ll(buf, 0x32000000, sizeof(buf))==-1) - { - while(1){blink_led(1);} + /*1 say hello to uart */ + serial_puti (123); + blue_on(1); + /*2. test nand flash */ + if(nand_read_ll(buf, 0x40000, sizeof(buf))==-1) { + while(1) { + blink_led(); + } } - asm volatile("mov pc, %0\n" + asm volatile("mov pc, %0\n" : /* output */ :"r"(ADDR) /* input */ ); From 07ac5def3b1c83a21472e3615e295c47bc7690d2 Mon Sep 17 00:00:00 2001 From: xiangfu Date: Thu, 24 Jul 2008 23:12:37 -0400 Subject: [PATCH 017/248] change serial_puti to serial_putc --- qiboot/include/serial.h | 6 +----- qiboot/src/serial.c | 4 ++-- qiboot/src/start_kboot.c | 2 +- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/qiboot/include/serial.h b/qiboot/include/serial.h index 053c712..9ec35f5 100644 --- a/qiboot/include/serial.h +++ b/qiboot/include/serial.h @@ -23,10 +23,6 @@ #define rUTXH0 (*(volatile unsigned char *)0x50000023) #define UTRSTAT (*(volatile unsigned char *)0x50000010) -/* -#define PUT_CHAR() (rUTXH0 -#define ORANGE_OFF() (GPBDAT &= ~(0x1)) -*/ +void serial_putc (const char c); -void serial_puti (const int i); diff --git a/qiboot/src/serial.c b/qiboot/src/serial.c index 66fe066..83322e5 100644 --- a/qiboot/src/serial.c +++ b/qiboot/src/serial.c @@ -25,9 +25,9 @@ /* * Output a single byte to the serial port. */ -void serial_puti (const int i) +void serial_putc (const char c) { while (!(UTRSTAT & 0x2)); - rUTXH0 |= i; + rUTXH0 = c; } diff --git a/qiboot/src/start_kboot.c b/qiboot/src/start_kboot.c index 935be30..caf98b8 100644 --- a/qiboot/src/start_kboot.c +++ b/qiboot/src/start_kboot.c @@ -40,7 +40,7 @@ unsigned char buf[2048]; int start_kboot(void) { /*1 say hello to uart */ - serial_puti (123); + serial_putc ('a'); blue_on(1); /*2. test nand flash */ if(nand_read_ll(buf, 0x40000, sizeof(buf))==-1) { From dded3f8cbf0c4d03e8d48d7c24d2470711c8598d Mon Sep 17 00:00:00 2001 From: xiangfu Date: Mon, 28 Jul 2008 10:47:53 -0400 Subject: [PATCH 018/248] add init serial console in serial.c --- qiboot/include/blink_led.h | 1 + qiboot/include/serial.h | 41 ++++++++++++++++++++++++++-- qiboot/src/nand_read.c | 11 ++++---- qiboot/src/serial.c | 56 ++++++++++++++++++++++++++++++++++---- qiboot/src/start.S | 51 +++++++++++++++++----------------- qiboot/src/start_kboot.c | 29 +++++++++++--------- 6 files changed, 137 insertions(+), 52 deletions(-) diff --git a/qiboot/include/blink_led.h b/qiboot/include/blink_led.h index 8485404..a32f395 100644 --- a/qiboot/include/blink_led.h +++ b/qiboot/include/blink_led.h @@ -37,5 +37,6 @@ int orange_on(int times); int blue_on(int times); int blink_led(void); +int delay(int time); #endif /* __BLINK_LED_H */ diff --git a/qiboot/include/serial.h b/qiboot/include/serial.h index 9ec35f5..fb740ef 100644 --- a/qiboot/include/serial.h +++ b/qiboot/include/serial.h @@ -20,9 +20,44 @@ * MA 02111-1307 USA */ -#define rUTXH0 (*(volatile unsigned char *)0x50000023) -#define UTRSTAT (*(volatile unsigned char *)0x50000010) +#define UART0 0 +#define UART1 1 +#define UART2 2 -void serial_putc (const char c); +#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) + +void serial_init (const int ubrdiv_val,const int uart); +void serial_putc (const int uart,const char c); diff --git a/qiboot/src/nand_read.c b/qiboot/src/nand_read.c index 20b2694..8a5778a 100644 --- a/qiboot/src/nand_read.c +++ b/qiboot/src/nand_read.c @@ -15,11 +15,7 @@ * Author: Harald Welte */ -/*#include -#include -*/ #include "nand_read.h" -#include "blink_led.h" #define NAND_CMD_READ0 0 #define NAND_CMD_READSTART 0x30 @@ -108,6 +104,7 @@ static int nand_read_page_ll(unsigned char *buf, unsigned long addr) int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size) { int i, j; + int bad_count = 0; if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) return -1; /* invalid alignment */ @@ -121,13 +118,15 @@ int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size) if (i % NAND_BLOCK_SIZE == 0) { if (is_bad_block(i) || is_bad_block(i + NAND_PAGE_SIZE)) { - orange_on(1); i += NAND_BLOCK_SIZE; size += NAND_BLOCK_SIZE; + if(bad_count++ == 4) { + return -1; + } continue; } } - blue_on(1); + j = nand_read_page_ll(buf, i); i += j; /* buf += j;*/ diff --git a/qiboot/src/serial.c b/qiboot/src/serial.c index 83322e5..840a9d8 100644 --- a/qiboot/src/serial.c +++ b/qiboot/src/serial.c @@ -20,14 +20,60 @@ * MA 02111-1307 USA */ -# include +#include "serial.h" +#include "blink_led.h" +void serial_init (const int ubrdiv_val,const int uart) +{ + switch(uart) + { + case UART0: + rULCON0 = 0x3; + rUCON0 = 0x245; + rUFCON0 = 0x0; + rUMCON0 = 0x0; + rUBRDIV0 = ubrdiv_val; + break; + case UART1: + rULCON1 = 0x3; + rUCON1 = 0x245; + rUFCON1 = 0x0; + rUMCON1 = 0x0; + rUBRDIV1 = ubrdiv_val; + break; + case UART2: + rULCON2 = 0x3; + rUCON2 = 0x245; + rUFCON2 = 0x0; + rUBRDIV2 = ubrdiv_val; + break; + default: + break; + } +} /* * Output a single byte to the serial port. */ -void serial_putc (const char c) +void serial_putc (const int uart,const char c) { - while (!(UTRSTAT & 0x2)); - - rUTXH0 = c; + switch(uart) + { + case UART0: + while ( !( rUTRSTAT0 & 0x2 ) ); + delay(10); + WrUTXH0(c); + break; + case UART1: + while ( !( rUTRSTAT1 & 0x2 ) ); + delay(10); + WrUTXH1(c); + break; + case UART2: + while ( !( rUTRSTAT2 & 0x2 ) ); + WrUTXH2(c); + break; + default: + break; + } } + diff --git a/qiboot/src/start.S b/qiboot/src/start.S index c98a55b..b7934ea 100644 --- a/qiboot/src/start.S +++ b/qiboot/src/start.S @@ -46,17 +46,19 @@ start_code: orr r0,r0,#0xd3 msr cpsr,r0 - /* turn off the watchdog */ # 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 0xffff +# define INTSUBMSK_val 0x0000ffff + mov r1, #0xffffffff ldr r0, =INTMSK str r1, [r0] @@ -65,8 +67,10 @@ start_code: ldr r0, =INTSUBMSK str r1, [r0] + /* Make sure we get FCLK:HCLK:PCLK = 1:3:6 */ -# define CAMDIVN 0x4C000018 +# define CAMDIVN 0x4C000018 + ldr r0, =CAMDIVN mov r1, #0 str r1, [r0] @@ -76,21 +80,21 @@ start_code: orr r1, r1, #0xc0000000 mcr p15, 0, r1, c1, c0, 0 -# define LOCKTIME 0x4c000000 -# define UPLLCON 0x4c000008 -# define UPLLCON_val (( 88 << 12) + (8 << 4) + 2) -# define MPLLCON 0x4c000004 -# define MPLLCON_val ((142 << 12) + (7 << 4) + 1) +#define LOCKTIME 0x4c000000 ldr r0, =LOCKTIME mov r1, #0xffffff str r1, [r0] +# define MPLLCON_val ((142 << 12) + (7 << 4) + 1) +# define UPLLCON 0x4c000008 +# define UPLLCON_val (( 88 << 12) + (8 << 4) + 2) + ldr r0, =UPLLCON ldr r1, =UPLLCON_val str r1, [r0] - /* Page 7-23 in s3c2442B manual, seven nops between UPLL and MPLL */ + /* Page 7-19, seven nops between UPLL and MPLL */ nop nop nop @@ -99,49 +103,46 @@ start_code: nop nop - ldr r0, =MPLLCON ldr r1, =MPLLCON_val - str r1, [r0] /* MPLLCON */ + str r1, [r0, #-4] /* MPLLCON */ # define CLKDIVN 0x4C000014 /* clock divisor register */ -# define CLKDIVN_val 7 /* FCLK:HCLK:PCLK = 1:3:6 */ +# 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 uart */ - ldr r0, =0x4c00000c /* clkcon */ - ldr r1, =0x7fff0 /* all clocks on */ + ldr r0, =0x4c00000c /* clkcon */ + ldr r1, =0xffff0 /* all clocks on */ str r1, [r0] /* gpio UART0 init */ ldr r0, =0x56000070 - mov r1, #0xaa + ldr r1, =0x2afaaa str r1, [r0] - /* init uart */ - ldr r0, =0x50000000 + /* init uart0 */ +/* ldr r0, =0x50000000 mov r1, #0x03 str r1, [r0] ldr r1, =0x245 str r1, [r0, #0x04] - mov r1, #0x01 + mov r1, #0x00 str r1, [r0, #0x08] mov r1, #0x00 - str r1, [r0, #0x0c] - mov r1, #0x1a - str r1, [r0, #0x28] + str r1, [r0, #0x0c] + mov r1, #0x11 + str r1, [r0, #0x28] */ bl cpu_init_crit /* >> CFG_VIDEO_LOGO_MAX_SIZE */ #define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ -#define CONFIG_STACKSIZE (128*1024) /* regular stack */ -#define CONFIG_STACKSIZE_IRQ (8*1024) /* IRQ stack */ -#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */ stack_setup: ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */ - sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) sub sp, r0, #12 /* leave 3 words for abort-stack */ clear_bss: diff --git a/qiboot/src/start_kboot.c b/qiboot/src/start_kboot.c index caf98b8..ab5e115 100644 --- a/qiboot/src/start_kboot.c +++ b/qiboot/src/start_kboot.c @@ -33,26 +33,29 @@ unsigned char buf[]={ 0x10,0x00,0x00,0x56,0x18,0x00,0x00,0x56,0xff,0xff,0x00,0x00,0x14,0x00,0x00,0x56, 0x01,0x00,0x50,0xe2,0xfd,0xff,0xff,0x1a,0x0e,0xf0,0xa0,0xe1,0x0a}; */ -unsigned char buf[2048]; +unsigned char buf[2*1024]; #define ADDR ((volatile unsigned *)&buf) int start_kboot(void) { - /*1 say hello to uart */ - serial_putc ('a'); + serial_init(0x11,UART0); + while(1){ + serial_putc (UART0,'0'); blue_on(1); - /*2. test nand flash */ - if(nand_read_ll(buf, 0x40000, sizeof(buf))==-1) { - while(1) { - blink_led(); - } - } + } - asm volatile("mov pc, %0\n" - : /* output */ - :"r"(ADDR) /* input */ - ); + /*2. test nand flash */ + if(nand_read_ll(buf, 0x000, sizeof(buf))==-1) { + while(1) { + blink_led(); + } + } + + asm volatile("mov pc, %0\n" + : /* output */ + :"r"(ADDR) /* input */ + ); return 0; } From f410b994a908c53f3e0b3a0136d4f0956c3a2000 Mon Sep 17 00:00:00 2001 From: xiangfu Date: Wed, 30 Jul 2008 08:32:03 -0400 Subject: [PATCH 019/248] the serial console begin output something --- qiboot/Makefile | 2 +- qiboot/include/serial.h | 41 +++++++++++++ qiboot/src/serial.c | 129 ++++++++++++++++++++++++++++++++++++++- qiboot/src/start.S | 12 ++-- qiboot/src/start_kboot.c | 3 +- 5 files changed, 178 insertions(+), 9 deletions(-) diff --git a/qiboot/Makefile b/qiboot/Makefile index bfd6245..515553b 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -56,4 +56,4 @@ blink_led:src/led_on.S $(OBJCOPY) -O binary -S led_on_temp.o $(IMAGE)/led_on clean: - rm -f src/*.o src/*~ ${IMAGE}* ${TARGET} + rm -f src/*.o src/*~ include/*~ ${IMAGE}* ${TARGET} diff --git a/qiboot/include/serial.h b/qiboot/include/serial.h index fb740ef..1a773eb 100644 --- a/qiboot/include/serial.h +++ b/qiboot/include/serial.h @@ -24,6 +24,8 @@ #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*/ @@ -59,5 +61,44 @@ #define WrUTXH2(ch) (*(volatile unsigned char *)0x50008020)=(unsigned char)(ch) #define RdURXH2() (*(volatile unsigned char *)0x50008024) + + +// 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 + +void port_init(void); void serial_init (const int ubrdiv_val,const int uart); void serial_putc (const int uart,const char c); diff --git a/qiboot/src/serial.c b/qiboot/src/serial.c index 840a9d8..23d6747 100644 --- a/qiboot/src/serial.c +++ b/qiboot/src/serial.c @@ -30,6 +30,9 @@ void serial_init (const int ubrdiv_val,const int uart) case UART0: rULCON0 = 0x3; rUCON0 = 0x245; + rGPHCON = rGPHCON & ~(3 << 16); + delay(1); + rGPHCON = rGPHCON & ~(3 << 16)|(1 << 17); rUFCON0 = 0x0; rUMCON0 = 0x0; rUBRDIV0 = ubrdiv_val; @@ -44,6 +47,9 @@ void serial_init (const int ubrdiv_val,const int uart) case UART2: rULCON2 = 0x3; rUCON2 = 0x245; + rGPHCON = rGPHCON & ~(3 << 16); + delay(1); + rGPHCON = rGPHCON & ~(3 << 16)|(1 << 17); rUFCON2 = 0x0; rUBRDIV2 = ubrdiv_val; break; @@ -60,16 +66,17 @@ void serial_putc (const int uart,const char c) { case UART0: while ( !( rUTRSTAT0 & 0x2 ) ); - delay(10); + delay(1); WrUTXH0(c); break; case UART1: while ( !( rUTRSTAT1 & 0x2 ) ); - delay(10); + delay(1); WrUTXH1(c); break; case UART2: while ( !( rUTRSTAT2 & 0x2 ) ); + delay(1); WrUTXH2(c); break; default: @@ -77,3 +84,121 @@ void serial_putc (const int uart,const char c) } } + +/* + * ===================================================================== + * PORTS Librarues + * ===================================================================== + */ +void port_init(void) +{ + //CAUTION:Follow the configuration order for setting the ports. + // 1) setting value(GPnDAT) + // 2) setting control register (GPnCON) + // 3) configure pull-up 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 |= (1 << 16); /* Set GPA16 to high (nNAND_WP) */ + /* + * ===* 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; + /* + * === 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); + /* + * === 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 = 0x0000AAAA; + rGPFUP = 0x000000FF & ~(1 << 3); + + + /* + * === 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; + /* + * === PORT H GROUP + * Ports : GPH10 GPH9 GPH8 GPH7 GPH6 GPH5 GPH4 GPH3 GPH2 GPH1 GPH0 + * Signal : CLKOUT1 CLKOUT0 UCLK nCTS1 nRTS1 RXD1 TXD1 RXD0 TXD0 nRTS0 nCTS0 + * Binary : 10 , 10 10 , 11 11 , 10 10 , 10 10 , 10 10 + */ + /* pulldown on GPH08: UEXTCLK, just floats! + * pulldown GPH0 -- nCTS0 / RTS_MODEM -- floats when GSM off + * pulldown GPH3 -- RXD[0] / TX_MODEM -- floats when GSM off + */ + rGPHCON = 0x001AAAAA; + rGPHUP = 0x000007FF & ~(1 << 8) & ~(1 << 0) & ~(1 << 3); + + /* 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 |= (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 */ +} diff --git a/qiboot/src/start.S b/qiboot/src/start.S index b7934ea..b92ccc7 100644 --- a/qiboot/src/start.S +++ b/qiboot/src/start.S @@ -85,11 +85,13 @@ start_code: ldr r0, =LOCKTIME mov r1, #0xffffff str r1, [r0] - -# define MPLLCON_val ((142 << 12) + (7 << 4) + 1) + # define UPLLCON 0x4c000008 +# define MPLLCON_val ((142 << 12) + (7 << 4) + 1) # define UPLLCON_val (( 88 << 12) + (8 << 4) + 2) - +/*# define MPLLCON_val ((0x7d << 12) + (0x2 << 4) + 0x1) +# define UPLLCON_val ((0x38 << 12) + (0x2 << 4) + 0x2)*/ + ldr r0, =UPLLCON ldr r1, =UPLLCON_val str r1, [r0] @@ -116,7 +118,7 @@ start_code: /* enable uart */ ldr r0, =0x4c00000c /* clkcon */ - ldr r1, =0xffff0 /* all clocks on */ + ldr r1, =0x7fff0 /* all clocks on */ str r1, [r0] /* gpio UART0 init */ @@ -134,7 +136,7 @@ start_code: str r1, [r0, #0x08] mov r1, #0x00 str r1, [r0, #0x0c] - mov r1, #0x11 + mov r1, #0x7 str r1, [r0, #0x28] */ bl cpu_init_crit diff --git a/qiboot/src/start_kboot.c b/qiboot/src/start_kboot.c index ab5e115..7d41e9f 100644 --- a/qiboot/src/start_kboot.c +++ b/qiboot/src/start_kboot.c @@ -39,7 +39,8 @@ unsigned char buf[2*1024]; int start_kboot(void) { - serial_init(0x11,UART0); + port_init(); + serial_init(0x7,UART0); while(1){ serial_putc (UART0,'0'); blue_on(1); From 67335c833f0cb562e2f42d4b49992b2fe7c96b80 Mon Sep 17 00:00:00 2001 From: xiangfu Date: Wed, 30 Jul 2008 13:33:24 -0400 Subject: [PATCH 020/248] when set rUBRDIV=0x11 can output correct. --- qiboot/src/serial.c | 8 +------- qiboot/src/start.S | 4 ++-- qiboot/src/start_kboot.c | 4 ++-- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/qiboot/src/serial.c b/qiboot/src/serial.c index 23d6747..c617a73 100644 --- a/qiboot/src/serial.c +++ b/qiboot/src/serial.c @@ -30,9 +30,6 @@ void serial_init (const int ubrdiv_val,const int uart) case UART0: rULCON0 = 0x3; rUCON0 = 0x245; - rGPHCON = rGPHCON & ~(3 << 16); - delay(1); - rGPHCON = rGPHCON & ~(3 << 16)|(1 << 17); rUFCON0 = 0x0; rUMCON0 = 0x0; rUBRDIV0 = ubrdiv_val; @@ -47,10 +44,7 @@ void serial_init (const int ubrdiv_val,const int uart) case UART2: rULCON2 = 0x3; rUCON2 = 0x245; - rGPHCON = rGPHCON & ~(3 << 16); - delay(1); - rGPHCON = rGPHCON & ~(3 << 16)|(1 << 17); - rUFCON2 = 0x0; + rUFCON2 = 0x1; rUBRDIV2 = ubrdiv_val; break; default: diff --git a/qiboot/src/start.S b/qiboot/src/start.S index b92ccc7..b2b0596 100644 --- a/qiboot/src/start.S +++ b/qiboot/src/start.S @@ -89,8 +89,8 @@ start_code: # define UPLLCON 0x4c000008 # define MPLLCON_val ((142 << 12) + (7 << 4) + 1) # define UPLLCON_val (( 88 << 12) + (8 << 4) + 2) -/*# define MPLLCON_val ((0x7d << 12) + (0x2 << 4) + 0x1) -# define UPLLCON_val ((0x38 << 12) + (0x2 << 4) + 0x2)*/ +/* # define MPLLCON_val ((0x7d << 12) + (0x2 << 4) + 0x1) +# define UPLLCON_val ((0x38 << 12) + (0x2 << 4) + 0x2) */ ldr r0, =UPLLCON ldr r1, =UPLLCON_val diff --git a/qiboot/src/start_kboot.c b/qiboot/src/start_kboot.c index 7d41e9f..70ece03 100644 --- a/qiboot/src/start_kboot.c +++ b/qiboot/src/start_kboot.c @@ -40,9 +40,9 @@ unsigned char buf[2*1024]; int start_kboot(void) { port_init(); - serial_init(0x7,UART0); + serial_init(0x11,UART2); while(1){ - serial_putc (UART0,'0'); + serial_putc (UART2,'2'); blue_on(1); } From a2dfa2c956ba6826f176812d4df8e9d2b6298795 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Tue, 12 Aug 2008 14:03:13 +0100 Subject: [PATCH 021/248] build-warn-all-error-all.patch Signed-off-by: Andy Green --- qiboot/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qiboot/Makefile b/qiboot/Makefile index 515553b..563d932 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -19,8 +19,7 @@ include config.mk LDS = src/kboot-stage1.lds INCLUDE = include IMAGE_DIR = image -#CFLAGS = -Wall -I $(INCLUDE) -msoft-float -g -c -CFLAGS = -Wall -I $(INCLUDE) -g -c +CFLAGS = -Wall -Werror -I $(INCLUDE) -g -c LDFLAGS = #START = start.o lowlevel_init.o S_SRCS = src/start.S src/lowlevel_init.S From 8783cd9896624f55387d243ddd08accdce146d38 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Wed, 13 Aug 2008 00:34:06 +0100 Subject: [PATCH 022/248] add-dfu-image-generation.patch Integrate udfu image generation to ease testing with GTA02 NOR Signed-off-by: Andy Green --- qiboot/Makefile | 16 ++++++++++++---- qiboot/config.mk | 7 +++++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/qiboot/Makefile b/qiboot/Makefile index 563d932..43511ec 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -31,8 +31,14 @@ C_OBJS = $(patsubst %.c,%.o, $(C_SRCS)) SRCS = ${S_SRCS} ${C_SRCS} OBJS = ${S_OBJS} ${C_OBJS} +# GTA02 A5 and A6 U-Boot will eat these for DFU action +UDFU_VID = 0x1d50 +UDFU_PID = 0x5119 +UDFU_REV = 0x350 + TARGET = src/start_kboot_all -IMAGE = $(IMAGE_DIR)/start +IMAGE = $(IMAGE_DIR)/kboot +UDFU_IMAGE = $(IMAGE_DIR)/kboot.udfu %.o: %.S @$(CC) $(CFLAGS) -o $@ $< @@ -40,13 +46,15 @@ IMAGE = $(IMAGE_DIR)/start %.o: %.c @$(CC) $(CFLAGS) -o $@ $< -all:${TARGET} +all:${UDFU_IMAGE} ${OBJS}:${SRCS} -${TARGET}:${OBJS} +${UDFU_IMAGE}:${OBJS} $(LD) ${LDFLAGS} -T$(LDS) -g $(OBJS) -o ${TARGET} $(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 blink_led:src/led_on.S @@ -55,4 +63,4 @@ blink_led:src/led_on.S $(OBJCOPY) -O binary -S led_on_temp.o $(IMAGE)/led_on clean: - rm -f src/*.o src/*~ include/*~ ${IMAGE}* ${TARGET} + rm -f src/*.o src/*~ include/*~ ${IMAGE}* ${TARGET} ${UDFU_IMAGE} diff --git a/qiboot/config.mk b/qiboot/config.mk index 52c0148..5d01952 100644 --- a/qiboot/config.mk +++ b/qiboot/config.mk @@ -2,7 +2,7 @@ # Include the make variables (CC, etc...) # #CROSS_COMPILE=arm-softfloat-linux-gnu- -CROSS_COMPILE=arm-angstrom-linux-gnueabi- +CROSS_COMPILE=/usr/local/openmoko/arm/bin/arm-angstrom-linux-gnueabi- AS = $(CROSS_COMPILE)as LD = $(CROSS_COMPILE)ld @@ -10,4 +10,7 @@ CC = $(CROSS_COMPILE)gcc OBJCOPY = $(CROSS_COMPILE)objcopy OBJDUMP = $(CROSS_COMPILE)objdump -export CROSS_COMPILE AD LD CC OBJCOPY OBJDUMP +# we need the mkudfu tool from U-Boot build +MKUDFU = ../uboot/u-boot/tools/mkudfu + +export CROSS_COMPILE AD LD CC OBJCOPY OBJDUMP MKUDFU From 0d888f897e1e874c30cb20d43908f6b0b10697b2 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Wed, 13 Aug 2008 00:34:40 +0100 Subject: [PATCH 023/248] add-dfu-script.patch Little helper script to do the DFU action without getting confused by changing VID / PID Signed-off-by: Andy Green --- qiboot/dfu-kboot | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100755 qiboot/dfu-kboot diff --git a/qiboot/dfu-kboot b/qiboot/dfu-kboot new file mode 100755 index 0000000..eb54a75 --- /dev/null +++ b/qiboot/dfu-kboot @@ -0,0 +1,7 @@ +#!/bin/bash +../dfu-util/src/dfu-util -a 1 -d 0x1d50:0x5119 -D image/kboot.udfu +if [ $? -eq 1 ] ; then +../dfu-util/src/dfu-util -a 1 -d 0x1d50:0x5120 -D image/kboot.udfu +../dfu-util/src/dfu-util -a 1 -d 0x1d50:0x5119 -D image/kboot.udfu +fi + From 372145cd292a0ea7a5f5f4ada810d8d55faa54e0 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Wed, 13 Aug 2008 00:35:09 +0100 Subject: [PATCH 024/248] build-link-with-libgcc.patch libgcc has divide and things we would like to use Signed-off-by: Andy Green --- qiboot/Makefile | 3 ++- qiboot/config.mk | 9 +++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/qiboot/Makefile b/qiboot/Makefile index 43511ec..0cf54e3 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -30,6 +30,7 @@ C_OBJS = $(patsubst %.c,%.o, $(C_SRCS)) #SRCS := $(START: .o=.S) $(COBJS: .o=.c) SRCS = ${S_SRCS} ${C_SRCS} OBJS = ${S_OBJS} ${C_OBJS} +LIBS = -L${COMPILER_LIB_PATH} -lgcc # GTA02 A5 and A6 U-Boot will eat these for DFU action UDFU_VID = 0x1d50 @@ -51,7 +52,7 @@ all:${UDFU_IMAGE} ${OBJS}:${SRCS} ${UDFU_IMAGE}:${OBJS} - $(LD) ${LDFLAGS} -T$(LDS) -g $(OBJS) -o ${TARGET} + $(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} diff --git a/qiboot/config.mk b/qiboot/config.mk index 5d01952..b8cb833 100644 --- a/qiboot/config.mk +++ b/qiboot/config.mk @@ -1,8 +1,13 @@ # # Include the make variables (CC, etc...) # -#CROSS_COMPILE=arm-softfloat-linux-gnu- -CROSS_COMPILE=/usr/local/openmoko/arm/bin/arm-angstrom-linux-gnueabi- + +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 From ae53877e7f525b4001ec5c7ea8cabc2693248fdb Mon Sep 17 00:00:00 2001 From: Andy Green Date: Wed, 13 Aug 2008 00:36:14 +0100 Subject: [PATCH 025/248] add-serial-strings.patch Add various debugging code for serial, this got changed around a lot in subsequent patches and printk() / vsprintf() was taken out in the end. Signed-off-by: Andy Green --- qiboot/include/serial.h | 12 +- qiboot/src/ctype.c | 27 ++++ qiboot/src/ctype.h | 45 ++++++ qiboot/src/serial.c | 30 +++- qiboot/src/sprintf.c | 342 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 452 insertions(+), 4 deletions(-) create mode 100644 qiboot/src/ctype.c create mode 100644 qiboot/src/ctype.h create mode 100644 qiboot/src/sprintf.c diff --git a/qiboot/include/serial.h b/qiboot/include/serial.h index 1a773eb..4e0f0b4 100644 --- a/qiboot/include/serial.h +++ b/qiboot/include/serial.h @@ -20,6 +20,11 @@ * MA 02111-1307 USA */ +#include + +#ifndef __SERIAL_H__ +#define __SERIAL_H__ + #define UART0 0 #define UART1 1 #define UART2 2 @@ -95,10 +100,15 @@ #define rGPHDAT (*(volatile unsigned *)0x56000074) #define rGPHUP (*(volatile unsigned *)0x56000078) -#define rGPJCON (*(volatile unsigned *)0x560000d0) //Port J control +#define rGPJCON (*(volatile unsigned *)0x560000d0) //Port J control #define rGPJDAT (*(volatile unsigned *)0x560000d4) //Port J data #define rGPJUP (*(volatile unsigned *)0x560000d8) //Port J data void port_init(void); void serial_init (const int ubrdiv_val,const int uart); void serial_putc (const int uart,const char c); +int printk(const char *fmt, ...); +int vsprintf(char *buf, const char *fmt, va_list args); +int puts(const char *string); + +#endif diff --git a/qiboot/src/ctype.c b/qiboot/src/ctype.c new file mode 100644 index 0000000..ce1d315 --- /dev/null +++ b/qiboot/src/ctype.c @@ -0,0 +1,27 @@ +#include "ctype.h" + +unsigned char _ctype[] = { +_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ +_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ +_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ +_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ +_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ +_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ +_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ +_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ +_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ +_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ +_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ +_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ +_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ +_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ +_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ +_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ +_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */ +_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */ +_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */ +_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */ +_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */ +_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */ diff --git a/qiboot/src/ctype.h b/qiboot/src/ctype.h new file mode 100644 index 0000000..ed65522 --- /dev/null +++ b/qiboot/src/ctype.h @@ -0,0 +1,45 @@ +#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) + diff --git a/qiboot/src/serial.c b/qiboot/src/serial.c index c617a73..09bb177 100644 --- a/qiboot/src/serial.c +++ b/qiboot/src/serial.c @@ -23,6 +23,8 @@ #include "serial.h" #include "blink_led.h" +#define DEBUG_CONSOLE_UART 2 + void serial_init (const int ubrdiv_val,const int uart) { switch(uart) @@ -60,17 +62,14 @@ void serial_putc (const int uart,const char c) { case UART0: while ( !( rUTRSTAT0 & 0x2 ) ); - delay(1); WrUTXH0(c); break; case UART1: while ( !( rUTRSTAT1 & 0x2 ) ); - delay(1); WrUTXH1(c); break; case UART2: while ( !( rUTRSTAT2 & 0x2 ) ); - delay(1); WrUTXH2(c); break; default: @@ -78,6 +77,31 @@ void serial_putc (const int uart,const char c) } } +int puts(const char *string) +{ + while (*string) + serial_putc(DEBUG_CONSOLE_UART, *string++); + serial_putc(DEBUG_CONSOLE_UART, '\n'); + + return 1; +} + +int printk(const char *fmt, ...) +{ + va_list args; + int r; + static char buf[512]; + char *p = buf; + + va_start(args, fmt); + r = vsprintf(buf, fmt, args); + va_end(args); + + while (*p) + serial_putc(DEBUG_CONSOLE_UART, *p++); + + return r; +} /* * ===================================================================== diff --git a/qiboot/src/sprintf.c b/qiboot/src/sprintf.c new file mode 100644 index 0000000..21253a1 --- /dev/null +++ b/qiboot/src/sprintf.c @@ -0,0 +1,342 @@ +/* + * linux/lib/vsprintf.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ +/* + * Wirzenius wrote this portably, Torvalds fucked it up :-) + */ + +#include +#include "ctype.h" + + + +int strnlen(const char * s, int count) +{ + const char *sc; + + for (sc = s; count-- && *sc != '\0'; ++sc) + /* nothing */; + return sc - s; +} + + +unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base) +{ + unsigned long result = 0,value; + + if (!base) { + base = 10; + if (*cp == '0') { + base = 8; + cp++; + if ((toupper(*cp) == 'X') && isxdigit(cp[1])) { + cp++; + base = 16; + } + } + } else if (base == 16) { + if (cp[0] == '0' && toupper(cp[1]) == 'X') + cp += 2; + } + while (isxdigit(*cp) && + (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) { + result = result*base + value; + cp++; + } + if (endp) + *endp = (char *)cp; + return result; +} + +long simple_strtol(const char *cp,char **endp,unsigned int base) +{ + if(*cp=='-') + return -simple_strtoul(cp+1,endp,base); + return simple_strtoul(cp,endp,base); +} + +/* we use this so that we can do without the ctype library */ +#define is_digit(c) ((c) >= '0' && (c) <= '9') + +static int skip_atoi(const char **s) +{ + int i=0; + + while (is_digit(**s)) + i = i*10 + *((*s)++) - '0'; + return i; +} + +#define ZEROPAD 1 /* pad with zero */ +#define SIGN 2 /* unsigned/signed long */ +#define PLUS 4 /* show plus */ +#define SPACE 8 /* space if plus */ +#define LEFT 16 /* left justified */ +#define SPECIAL 32 /* 0x */ +#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ + + +int raise(int n) +{ + return 0; +} + +#define do_div(n,base) ({ \ + int __res; \ + __res = (n) - (((n) / (base)) * (base)); \ + n = ((unsigned long) n) / base; \ + __res; \ +}) + +static char * number(char * str, long num, unsigned int base, int size, int precision ,int type) +{ + char c,sign,tmp[66]; + const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; + int i; + + if (type & LARGE) + digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if (type & LEFT) + type &= ~ZEROPAD; + if (base < 2 || base > 36) + return 0; + c = (type & ZEROPAD) ? '0' : ' '; + sign = 0; + if (type & SIGN) { + if (num < 0) { + sign = '-'; + num = -num; + size--; + } else if (type & PLUS) { + sign = '+'; + size--; + } else if (type & SPACE) { + sign = ' '; + size--; + } + } + if (type & SPECIAL) { + if (base == 16) + size -= 2; + else if (base == 8) + size--; + } + i = 0; + if (num == 0) + tmp[i++]='0'; + else while (num != 0) + tmp[i++] = digits[do_div(num,base)]; + if (i > precision) + precision = i; + size -= precision; + if (!(type&(ZEROPAD+LEFT))) + while(size-->0) + *str++ = ' '; + if (sign) + *str++ = sign; + if (type & SPECIAL) { + if (base==8) + *str++ = '0'; + else if (base==16) { + *str++ = '0'; + *str++ = digits[33]; + } + } + if (!(type & LEFT)) + while (size-- > 0) + *str++ = c; + while (i < precision--) + *str++ = '0'; + while (i-- > 0) + *str++ = tmp[i]; + while (size-- > 0) + *str++ = ' '; + return str; +} + +/* Forward decl. needed for IP address printing stuff... */ +int sprintf(char * buf, const char *fmt, ...); + +int vsprintf(char *buf, const char *fmt, va_list args) +{ + int len; + unsigned long num; + int i, base; + char * str; + const char *s; + + int flags; /* flags to number() */ + + int field_width; /* width of output field */ + int precision; /* min. # of digits for integers; max + number of chars for from string */ + int qualifier; /* 'h', 'l', or 'q' for integer fields */ + + for (str=buf ; *fmt ; ++fmt) { + if (*fmt != '%') { + *str++ = *fmt; + continue; + } + + /* process flags */ + flags = 0; + repeat: + ++fmt; /* this also skips first '%' */ + switch (*fmt) { + case '-': flags |= LEFT; goto repeat; + case '+': flags |= PLUS; goto repeat; + case ' ': flags |= SPACE; goto repeat; + case '#': flags |= SPECIAL; goto repeat; + case '0': flags |= ZEROPAD; goto repeat; + } + + /* get field width */ + field_width = -1; + if (is_digit(*fmt)) + field_width = skip_atoi(&fmt); + else if (*fmt == '*') { + ++fmt; + /* it's the next argument */ + field_width = va_arg(args, int); + if (field_width < 0) { + field_width = -field_width; + flags |= LEFT; + } + } + + /* get the precision */ + precision = -1; + if (*fmt == '.') { + ++fmt; + if (is_digit(*fmt)) + precision = skip_atoi(&fmt); + else if (*fmt == '*') { + ++fmt; + /* it's the next argument */ + precision = va_arg(args, int); + } + if (precision < 0) + precision = 0; + } + + /* get the conversion qualifier */ + qualifier = -1; + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'q') { + qualifier = *fmt; + if (qualifier == 'l' && *(fmt+1) == 'l') { + qualifier = 'q'; + ++fmt; + } + ++fmt; + } + + /* default base */ + base = 10; + + switch (*fmt) { + case 'c': + if (!(flags & LEFT)) + while (--field_width > 0) + *str++ = ' '; + *str++ = (unsigned char) va_arg(args, int); + while (--field_width > 0) + *str++ = ' '; + continue; + + case 's': + s = va_arg(args, char *); + if (!s) + s = ""; + + len = strnlen(s, precision); + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = *s++; + while (len < field_width--) + *str++ = ' '; + continue; + + case 'p': + if (field_width == -1) { + field_width = 2*sizeof(void *); + flags |= ZEROPAD; + } + str = number(str, + (unsigned long) va_arg(args, void *), 16, + field_width, precision, flags); + continue; + + + case 'n': + if (qualifier == 'l') { + long * ip = va_arg(args, long *); + *ip = (str - buf); + } else { + int * ip = va_arg(args, int *); + *ip = (str - buf); + } + continue; + + case '%': + *str++ = '%'; + continue; + + /* integer number formats - set up the flags and "break" */ + case 'o': + base = 8; + break; + + case 'X': + flags |= LARGE; + case 'x': + base = 16; + break; + + case 'd': + case 'i': + flags |= SIGN; + case 'u': + break; + + default: + *str++ = '%'; + if (*fmt) + *str++ = *fmt; + else + --fmt; + continue; + } + if (qualifier == 'l') + num = va_arg(args, unsigned long); + else if (qualifier == 'h') { + num = (unsigned short) va_arg(args, int); + if (flags & SIGN) + num = (short) num; + } else if (flags & SIGN) + num = va_arg(args, int); + else + num = va_arg(args, unsigned int); + str = number(str, num, base, field_width, precision, flags); + } + *str = '\0'; + return str-buf; +} + +int sprintf(char * buf, const char *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + i=vsprintf(buf,fmt,args); + va_end(args); + return i; +} + From 072c9da01049454673d5b4fcf7af0635526ec7bd Mon Sep 17 00:00:00 2001 From: Andy Green Date: Wed, 13 Aug 2008 00:36:46 +0100 Subject: [PATCH 026/248] add-kboot-h.patch kboot.h includes the common things and some externs Signed-off-by: Andy Green --- qiboot/include/serial.h | 1 - qiboot/src/kboot.h | 14 ++++++++++++++ qiboot/src/serial.c | 2 +- qiboot/src/start_kboot.c | 2 +- 4 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 qiboot/src/kboot.h diff --git a/qiboot/include/serial.h b/qiboot/include/serial.h index 4e0f0b4..12e2ae9 100644 --- a/qiboot/include/serial.h +++ b/qiboot/include/serial.h @@ -20,7 +20,6 @@ * MA 02111-1307 USA */ -#include #ifndef __SERIAL_H__ #define __SERIAL_H__ diff --git a/qiboot/src/kboot.h b/qiboot/src/kboot.h new file mode 100644 index 0000000..037a5d0 --- /dev/null +++ b/qiboot/src/kboot.h @@ -0,0 +1,14 @@ + +#ifndef __KBOOT_H__ +#define __KBOOT_H__ + +#include +#include "serial.h" +#include "ctype.h" + +int printk(const char *fmt, ...); +int vsprintf(char *buf, const char *fmt, va_list args); +void puts(const char *string); + +#endif + diff --git a/qiboot/src/serial.c b/qiboot/src/serial.c index 09bb177..9c7e7f9 100644 --- a/qiboot/src/serial.c +++ b/qiboot/src/serial.c @@ -20,8 +20,8 @@ * MA 02111-1307 USA */ -#include "serial.h" #include "blink_led.h" +#include "kboot.h" #define DEBUG_CONSOLE_UART 2 diff --git a/qiboot/src/start_kboot.c b/qiboot/src/start_kboot.c index 70ece03..76a1c34 100644 --- a/qiboot/src/start_kboot.c +++ b/qiboot/src/start_kboot.c @@ -21,7 +21,7 @@ */ #include "blink_led.h" #include "nand_read.h" -#include "serial.h" +#include "kboot.h" /* unsigned char buf[]={ 0x0d,0xc0,0xa0,0xe1,0x00,0xd8,0x2d,0xe9,0x04,0xb0,0x4c,0xe2,0x4c,0x20,0x9f,0xe5, From 7143408081108ac07dab9bd239cbe01a2b50137d Mon Sep 17 00:00:00 2001 From: Andy Green Date: Wed, 13 Aug 2008 00:37:17 +0100 Subject: [PATCH 027/248] add-build-stamps.patch Add git-based versioning Signed-off-by: Andy Green --- qiboot/Makefile | 8 +++++++- qiboot/src/serial.c | 2 +- qiboot/src/start_kboot.c | 37 ++++++++++++++++++++----------------- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/qiboot/Makefile b/qiboot/Makefile index 0cf54e3..1f2936b 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -16,10 +16,16 @@ 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/kboot-stage1.lds INCLUDE = include IMAGE_DIR = image -CFLAGS = -Wall -Werror -I $(INCLUDE) -g -c +CFLAGS = -Wall -Werror -I $(INCLUDE) -g -c -DBUILD_HOST="${BUILD_HOST}" -DBUILD_VERSION="${BUILD_VERSION}" -DBUILD_DATE="${BUILD_DATE}" LDFLAGS = #START = start.o lowlevel_init.o S_SRCS = src/start.S src/lowlevel_init.S diff --git a/qiboot/src/serial.c b/qiboot/src/serial.c index 9c7e7f9..38053f8 100644 --- a/qiboot/src/serial.c +++ b/qiboot/src/serial.c @@ -23,7 +23,7 @@ #include "blink_led.h" #include "kboot.h" -#define DEBUG_CONSOLE_UART 2 +#define DEBUG_CONSOLE_UART UART2 void serial_init (const int ubrdiv_val,const int uart) { diff --git a/qiboot/src/start_kboot.c b/qiboot/src/start_kboot.c index 76a1c34..b9777ec 100644 --- a/qiboot/src/start_kboot.c +++ b/qiboot/src/start_kboot.c @@ -36,27 +36,30 @@ unsigned char buf[]={ unsigned char buf[2*1024]; #define ADDR ((volatile unsigned *)&buf) +#define stringify(x) #x int start_kboot(void) { - port_init(); - serial_init(0x11,UART2); - while(1){ - serial_putc (UART2,'2'); - blue_on(1); - } + port_init(); + serial_init(0x11, UART2); - /*2. test nand flash */ - if(nand_read_ll(buf, 0x000, sizeof(buf))==-1) { - while(1) { - blink_led(); - } - } + while(1) { + serial_putc(2, 'x'); + serial_putc(2, 'x'); + serial_putc(2, 'x'); + printk("Openmoko KBOOT "stringify(BUILD_HOST)" "stringify(BUILD_VERSION)" "stringify(BUILD_DATE)"\n"); + blue_on(1); + } - asm volatile("mov pc, %0\n" - : /* output */ - :"r"(ADDR) /* input */ - ); + /*2. test nand flash */ + if(nand_read_ll(buf, 0x000, sizeof(buf))==-1) + while(1) + blink_led(); - return 0; + asm volatile("mov pc, %0\n" + : /* output */ + :"r"(ADDR) /* input */ + ); + + return 0; } From 0b4bd34f15eb935bea6ba04711d22e8f3bbc4451 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Wed, 13 Aug 2008 00:40:01 +0100 Subject: [PATCH 028/248] change-text-base-and-meddle.patch change the TEXT_BASE and meddle around Signed-off-by: Andy Green --- qiboot/include/neo_gta02.h | 2 +- qiboot/src/kboot.h | 4 +++- qiboot/src/lowlevel_init.S | 3 --- qiboot/src/serial.c | 27 +++++++++++++++++++++++++-- qiboot/src/start.S | 2 ++ qiboot/src/start_kboot.c | 10 +++++++--- 6 files changed, 38 insertions(+), 10 deletions(-) diff --git a/qiboot/include/neo_gta02.h b/qiboot/include/neo_gta02.h index 506149a..c126adb 100644 --- a/qiboot/include/neo_gta02.h +++ b/qiboot/include/neo_gta02.h @@ -23,6 +23,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define TEXT_BASE 0x33F80000 /* xiangfu add*/ +#define TEXT_BASE 0x33000000 #endif /* __CONFIG_H */ diff --git a/qiboot/src/kboot.h b/qiboot/src/kboot.h index 037a5d0..7143aae 100644 --- a/qiboot/src/kboot.h +++ b/qiboot/src/kboot.h @@ -8,7 +8,9 @@ int printk(const char *fmt, ...); int vsprintf(char *buf, const char *fmt, va_list args); -void puts(const char *string); +int puts(const char *string); +void printhex(unsigned char v); +void print32(unsigned int u); #endif diff --git a/qiboot/src/lowlevel_init.S b/qiboot/src/lowlevel_init.S index 2ce0133..dcb3adf 100644 --- a/qiboot/src/lowlevel_init.S +++ b/qiboot/src/lowlevel_init.S @@ -120,9 +120,6 @@ #define REFCNT 997 /* period=17.5us, HCLK=60Mhz, (2048+1-15.6*60) */ /**************************************/ -_TEXT_BASE: - .word TEXT_BASE - .globl lowlevel_init lowlevel_init: /* memory control configuration */ diff --git a/qiboot/src/serial.c b/qiboot/src/serial.c index 38053f8..8c8c2a5 100644 --- a/qiboot/src/serial.c +++ b/qiboot/src/serial.c @@ -86,17 +86,40 @@ int puts(const char *string) return 1; } +/* done like this to avoid needing statics in steppingstone */ +void printnybble(unsigned char n) +{ + if (n < 10) + serial_putc(DEBUG_CONSOLE_UART, '0' + n); + else + serial_putc(DEBUG_CONSOLE_UART, 'a' + n - 10); +} + +void printhex(unsigned char n) +{ + printnybble((n >> 4) & 15); + printnybble(n & 15); +} + +void print32(unsigned int u) +{ + printhex(u >> 24); + printhex(u >> 16); + printhex(u >> 8); + printhex(u); +} + int printk(const char *fmt, ...) { va_list args; int r; static char buf[512]; - char *p = buf; + const char *p = buf; va_start(args, fmt); r = vsprintf(buf, fmt, args); va_end(args); - + p = fmt; while (*p) serial_putc(DEBUG_CONSOLE_UART, *p++); diff --git a/qiboot/src/start.S b/qiboot/src/start.S index b2b0596..5f956ed 100644 --- a/qiboot/src/start.S +++ b/qiboot/src/start.S @@ -158,6 +158,8 @@ clbss_l: cmp r0, r1 ble clbss_l +/* we are going to jump into the C part of the init now */ + ldr pc, _start_armboot _start_armboot: diff --git a/qiboot/src/start_kboot.c b/qiboot/src/start_kboot.c index b9777ec..86e2483 100644 --- a/qiboot/src/start_kboot.c +++ b/qiboot/src/start_kboot.c @@ -40,15 +40,19 @@ unsigned char buf[2*1024]; int start_kboot(void) { + static int n = 0; + port_init(); serial_init(0x11, UART2); while(1) { + serial_putc(2, '0'); serial_putc(2, 'x'); - serial_putc(2, 'x'); - serial_putc(2, 'x'); - printk("Openmoko KBOOT "stringify(BUILD_HOST)" "stringify(BUILD_VERSION)" "stringify(BUILD_DATE)"\n"); + print32((unsigned int)&n); + serial_putc(2, '\n'); +// printk("Openmoko KBOOT "stringify(BUILD_HOST)" "stringify(BUILD_VERSION)" "stringify(BUILD_DATE)"\n"); blue_on(1); + n++; } /*2. test nand flash */ From fdb05a1e8b53f585879523932f4b155292904fe4 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Wed, 13 Aug 2008 00:41:21 +0100 Subject: [PATCH 029/248] fix-do-relocation Start meddling with linkser script, more changes came later that actually got it working by pushing all .rodata into first 4K so the linked addresses matched reality even when ran from the SDRAM copy. Signed-off-by: Andy Green --- qiboot/src/kboot-stage1.lds | 9 ++------- qiboot/src/start_kboot.c | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/qiboot/src/kboot-stage1.lds b/qiboot/src/kboot-stage1.lds index 8cc49f6..1998807 100644 --- a/qiboot/src/kboot-stage1.lds +++ b/qiboot/src/kboot-stage1.lds @@ -36,14 +36,9 @@ SECTIONS src/lowlevel_init.o(.text) src/start_kboot.o (.text) *(.text) + *(.rodata) } - . = ALIGN(4); - .rodata : - { - *(.rodata) - } - . = ALIGN(4); .data : { @@ -58,7 +53,7 @@ SECTIONS . = ALIGN(4); __bss_start = .; - .bss : + .bss (NOLOAD) : { *(.bss) } diff --git a/qiboot/src/start_kboot.c b/qiboot/src/start_kboot.c index 86e2483..8b46919 100644 --- a/qiboot/src/start_kboot.c +++ b/qiboot/src/start_kboot.c @@ -38,9 +38,12 @@ unsigned char buf[2*1024]; #define ADDR ((volatile unsigned *)&buf) #define stringify(x) #x +static char * hello = "hello"; + int start_kboot(void) { static int n = 0; + void (*p)(unsigned int) = print32; port_init(); serial_init(0x11, UART2); @@ -49,7 +52,18 @@ int start_kboot(void) serial_putc(2, '0'); serial_putc(2, 'x'); print32((unsigned int)&n); + serial_putc(2, ' '); + serial_putc(2, '0'); + serial_putc(2, 'x'); + print32((unsigned int)p); + serial_putc(2, ' '); + serial_putc(2, '0'); + serial_putc(2, 'x'); + print32((unsigned int)hello); + serial_putc(2, '\n'); + + // printk("Openmoko KBOOT "stringify(BUILD_HOST)" "stringify(BUILD_VERSION)" "stringify(BUILD_DATE)"\n"); blue_on(1); n++; From f26f60b0ac1dd815cfd167bfff557a9c28368492 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Wed, 13 Aug 2008 00:42:35 +0100 Subject: [PATCH 030/248] fix-nand.patch NAND stuff wasn't going to do anything until the controller in the CPU was reset. NAND code was cleaned and other minor meddlings Signed-off-by: Andy Green --- qiboot/src/kboot-stage1.lds | 1 + qiboot/src/lowlevel_init.S | 3 + qiboot/src/nand_read.c | 93 +++++++++++++++------- qiboot/src/phase2.c | 154 ++++++++++++++++++++++++++++++++++++ qiboot/src/start.S | 13 +++ qiboot/src/start_kboot.c | 42 ++++++---- 6 files changed, 263 insertions(+), 43 deletions(-) create mode 100644 qiboot/src/phase2.c diff --git a/qiboot/src/kboot-stage1.lds b/qiboot/src/kboot-stage1.lds index 1998807..551d354 100644 --- a/qiboot/src/kboot-stage1.lds +++ b/qiboot/src/kboot-stage1.lds @@ -35,6 +35,7 @@ SECTIONS src/start.o (.text) src/lowlevel_init.o(.text) src/start_kboot.o (.text) + src/start_kboot.o (.rodata) *(.text) *(.rodata) } diff --git a/qiboot/src/lowlevel_init.S b/qiboot/src/lowlevel_init.S index dcb3adf..4f20d5e 100644 --- a/qiboot/src/lowlevel_init.S +++ b/qiboot/src/lowlevel_init.S @@ -19,6 +19,9 @@ * MA 02111-1307 USA */ +/* NOTE this stuff runs in steppingstone context! */ + + /* * #include * #include diff --git a/qiboot/src/nand_read.c b/qiboot/src/nand_read.c index 8a5778a..8deadb7 100644 --- a/qiboot/src/nand_read.c +++ b/qiboot/src/nand_read.c @@ -15,7 +15,11 @@ * Author: Harald Welte */ +/* NOTE this stuff runs in steppingstone context! */ + + #include "nand_read.h" +#include "kboot.h" #define NAND_CMD_READ0 0 #define NAND_CMD_READSTART 0x30 @@ -67,6 +71,14 @@ static int is_bad_block(unsigned long i) NFCMD = NAND_CMD_READSTART; nand_wait(); data = (NFDATA & 0xff); +#ifdef DEBUG + serial_putc(2, '$'); + serial_putc(2, '0'); + serial_putc(2, 'x'); + print32((unsigned int)data); + serial_putc(2, ' '); +#endif + if (data != 0xff) return 1; @@ -103,38 +115,65 @@ static int nand_read_page_ll(unsigned char *buf, unsigned long addr) /* low level nand read function */ int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size) { - int i, j; - int bad_count = 0; + int i, j; + int bad_count = 0; - if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) - return -1; /* invalid alignment */ + if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) + return -1; /* invalid alignment */ - /* chip Enable */ - nand_select(); - nand_clear_RnB(); - for (i=0; i<10; i++); + /* chip Enable */ + nand_select(); + nand_clear_RnB(); - for (i=start_addr; i < (start_addr + size);) { - if (i % NAND_BLOCK_SIZE == 0) { - if (is_bad_block(i) || - is_bad_block(i + NAND_PAGE_SIZE)) { - i += NAND_BLOCK_SIZE; - size += NAND_BLOCK_SIZE; - if(bad_count++ == 4) { - return -1; + for (i = 0; i < 10; i++) + ; + + for (i = start_addr; i < (start_addr + size);) { +#ifdef DEBUG + serial_putc(2, 'i'); + serial_putc(2, '0'); + serial_putc(2, 'x'); + print32((unsigned int)i); + serial_putc(2, ' '); +#endif + if (i % NAND_BLOCK_SIZE == 0) { + if (is_bad_block(i) || + is_bad_block(i + NAND_PAGE_SIZE)) { +#ifdef DEBUG + serial_putc(2, '?'); +#endif + i += NAND_BLOCK_SIZE; + size += NAND_BLOCK_SIZE; + if (bad_count++ == 4) { +#ifdef DEBUG + serial_putc(2, '+'); + serial_putc(2, '\n'); +#endif + return -1; + } + serial_putc(2, '\n'); + continue; + } + } + + j = nand_read_page_ll(buf, i); +#ifdef DEBUG + serial_putc(2, 'j'); + serial_putc(2, '0'); + serial_putc(2, 'x'); + print32((unsigned int)j); + serial_putc(2, ' '); +#endif + i += j; + buf += j; +#if DEBUG + serial_putc(2, '\n'); +#endif } - continue; - } - } - j = nand_read_page_ll(buf, i); - i += j; - /* buf += j;*/ - } + /* chip Disable */ + nand_deselect(); - /* chip Disable */ - nand_deselect(); - - return 0; + return 0; } diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c new file mode 100644 index 0000000..75ae2fd --- /dev/null +++ b/qiboot/src/phase2.c @@ -0,0 +1,154 @@ +#include "kboot.h" +#include +#include "blink_led.h" +#include +#define __ARM__ +#include +#define u32 unsigned int +#define u16 unsigned short +#define u8 unsigned char +typedef unsigned int uint32_t; + +#include +#include "nand_read.h" + +/* See also ARM920T Technical reference Manual */ +#define C1_MMU (1<<0) /* mmu off/on */ +#define C1_ALIGN (1<<1) /* alignment faults off/on */ +#define C1_DC (1<<2) /* dcache off/on */ + +#define C1_BIG_ENDIAN (1<<7) /* big endian off/on */ +#define C1_SYS_PROT (1<<8) /* system protection */ +#define C1_ROM_PROT (1<<9) /* ROM protection */ +#define C1_IC (1<<12) /* icache off/on */ +#define C1_HIGH_VECTORS (1<<13) /* location of vectors: low/high addresses */ + +size_t strlen(const char *s) +{ + size_t n = 0; + + while (*s++) + n++; + + return n; +} + +char *strcpy(char *dest, const char *src) +{ + char * dest_orig = dest; + + while (*src) + *dest++ = *src++; + + return dest_orig; +} + +unsigned int _ntohl(unsigned int n) { + return ((n & 0xff) << 24) | ((n & 0xff00) << 8) | + ((n & 0xff0000) >> 8) | ((n & 0xff000000) >> 24); +} + +void bootloader_second_phase(void) +{ + image_header_t *hdr; + unsigned long i = 0; + int machid = 1304; /* GTA02 */ + void (*theKernel)(int zero, int arch, uint params); + struct tag * params_base = (struct tag *)0x30000100; /* atags need to live here */ + struct tag *params = params_base; + const char * cmdline = "rootfstype=ext2 root=/dev/mmcblk0p1 console=ttySAC2,115200 loglevel=8 init=/sbin/init ro"; + const char *p = cmdline; + void * kernel_nand = (void *)(TEXT_BASE - 4 * 1024 * 1024); + + puts("Checking kernel... "); + + if (nand_read_ll(kernel_nand, 0x80000, 4096) < 0) { + puts ("Kernel header read failed\n"); + goto unhappy; + } + + hdr = (image_header_t *)kernel_nand; + + if (_ntohl(hdr->ih_magic) != IH_MAGIC) { + puts("Unknown image magic "); + print32(hdr->ih_magic); + goto unhappy; + } + + puts((const char *)hdr->ih_name); + + puts("Fetching kernel..."); + + if (nand_read_ll(kernel_nand, 0x80000, ((32 * 1024) + + (_ntohl(hdr->ih_size) + + sizeof(hdr) + 2048)) & + ~(2048 - 1)) < 0) { + puts ("Kernel body read failed\n"); + goto unhappy; + } + + puts(" Done"); + + theKernel = (void (*)(int, int, uint)) + (((char *)hdr) + sizeof(image_header_t)); + + /* first tag */ + params->hdr.tag = ATAG_CORE; + params->hdr.size = tag_size (tag_core); + params->u.core.flags = 0; + params->u.core.pagesize = 0; + params->u.core.rootdev = 0; + params = tag_next (params); + + /* revision tag */ + params->hdr.tag = ATAG_REVISION; + params->hdr.size = tag_size (tag_revision); + params->u.revision.rev = 0x350; + params = tag_next (params); + + /* memory tags */ + params->hdr.tag = ATAG_MEM; + params->hdr.size = tag_size (tag_mem32); + params->u.mem.start = 0x30000000; + params->u.mem.size = 128 * 1024 * 1024; + params = tag_next (params); + + /* kernel commandline */ + /* eat leading white space */ + for (p = cmdline; *p == ' '; p++); + + if (*p) { + params->hdr.tag = ATAG_CMDLINE; + params->hdr.size = + (sizeof (struct tag_header) + strlen (p) + 1 + 4) >> 2; + strcpy (params->u.cmdline.cmdline, p); + params = tag_next (params); + } + + /* needs to always be the last tag */ + params->hdr.tag = ATAG_NONE; + params->hdr.size = 0; + + puts ("Running Linux...\n\n"); + + /* trash the cache */ + + /* turn off I/D-cache */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + i &= ~(C1_DC | C1_IC); + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); + + /* flush I/D-cache */ + i = 0; + asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); + + /* ooh that's it, we're gonna try boot this image! */ + + theKernel(0, machid, (unsigned int)params_base); + + /* that didn't quite pan out */ + +unhappy: + while (1) + blue_on(1); +} diff --git a/qiboot/src/start.S b/qiboot/src/start.S index 5f956ed..c16a2a0 100644 --- a/qiboot/src/start.S +++ b/qiboot/src/start.S @@ -140,6 +140,19 @@ start_code: str r1, [r0, #0x28] */ bl cpu_init_crit + +/* 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] + /* >> CFG_VIDEO_LOGO_MAX_SIZE */ #define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ stack_setup: diff --git a/qiboot/src/start_kboot.c b/qiboot/src/start_kboot.c index 8b46919..b4256d2 100644 --- a/qiboot/src/start_kboot.c +++ b/qiboot/src/start_kboot.c @@ -19,9 +19,15 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ + +/* NOTE this stuff runs in steppingstone context! */ + + #include "blink_led.h" #include "nand_read.h" #include "kboot.h" +#include + /* unsigned char buf[]={ 0x0d,0xc0,0xa0,0xe1,0x00,0xd8,0x2d,0xe9,0x04,0xb0,0x4c,0xe2,0x4c,0x20,0x9f,0xe5, @@ -33,21 +39,20 @@ unsigned char buf[]={ 0x10,0x00,0x00,0x56,0x18,0x00,0x00,0x56,0xff,0xff,0x00,0x00,0x14,0x00,0x00,0x56, 0x01,0x00,0x50,0xe2,0xfd,0xff,0xff,0x1a,0x0e,0xf0,0xa0,0xe1,0x0a}; */ -unsigned char buf[2*1024]; - -#define ADDR ((volatile unsigned *)&buf) #define stringify(x) #x -static char * hello = "hello"; +extern void bootloader_second_phase(void); -int start_kboot(void) +void start_kboot(void) { - static int n = 0; - void (*p)(unsigned int) = print32; + void (*phase2)(void) = bootloader_second_phase + TEXT_BASE; port_init(); serial_init(0x11, UART2); + puts("Openmoko KBOOT BUILD_HOST BUILD_VERSION BUILD_DATE\n"); + +#if 0 while(1) { serial_putc(2, '0'); serial_putc(2, 'x'); @@ -63,21 +68,26 @@ int start_kboot(void) serial_putc(2, '\n'); - -// printk("Openmoko KBOOT "stringify(BUILD_HOST)" "stringify(BUILD_VERSION)" "stringify(BUILD_DATE)"\n"); blue_on(1); n++; } - /*2. test nand flash */ - if(nand_read_ll(buf, 0x000, sizeof(buf))==-1) +#endif + + /* + * pull the whole U-Boot image into SDRAM + */ + + if (nand_read_ll((unsigned char *)TEXT_BASE, 0, 256 * 1024) < 0) while(1) blink_led(); - asm volatile("mov pc, %0\n" - : /* output */ - :"r"(ADDR) /* input */ - ); + serial_putc(2, '0'); + serial_putc(2, 'x'); + print32((unsigned int)bootloader_second_phase); + serial_putc(2, ' '); + serial_putc(2, '\n'); - return 0; + + (phase2)(); } From b44cb06c6b04f23918b5b8348880590e99bbe376 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Wed, 13 Aug 2008 00:43:27 +0100 Subject: [PATCH 031/248] tidy-second-phase-stub.patch Clean up the jump into the full SDRAM copy of bootloader that is made now. Adjust the compiler options. Signed-off-by: Andy Green --- qiboot/Makefile | 5 +++- qiboot/src/kboot-stage1.lds | 6 ++--- qiboot/src/start_kboot.c | 49 ++++++------------------------------- 3 files changed, 14 insertions(+), 46 deletions(-) diff --git a/qiboot/Makefile b/qiboot/Makefile index 1f2936b..b279e25 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -25,7 +25,10 @@ BUILD_VERSION := ${BUILD_BRANCH}_${BUILD_HEAD} LDS = src/kboot-stage1.lds INCLUDE = include IMAGE_DIR = image -CFLAGS = -Wall -Werror -I $(INCLUDE) -g -c -DBUILD_HOST="${BUILD_HOST}" -DBUILD_VERSION="${BUILD_VERSION}" -DBUILD_DATE="${BUILD_DATE}" +CFLAGS = -Wall -Werror -fno-builtin -ffreestanding -fno-strict-aliasing \ + -fno-common -ffixed-r8 -I $(INCLUDE) -g -c \ + -DBUILD_HOST="${BUILD_HOST}" -DBUILD_VERSION="${BUILD_VERSION}" \ + -DBUILD_DATE="${BUILD_DATE}" LDFLAGS = #START = start.o lowlevel_init.o S_SRCS = src/start.S src/lowlevel_init.S diff --git a/qiboot/src/kboot-stage1.lds b/qiboot/src/kboot-stage1.lds index 551d354..4b93b52 100644 --- a/qiboot/src/kboot-stage1.lds +++ b/qiboot/src/kboot-stage1.lds @@ -34,10 +34,8 @@ SECTIONS { src/start.o (.text) src/lowlevel_init.o(.text) - src/start_kboot.o (.text) - src/start_kboot.o (.rodata) - *(.text) - *(.rodata) + src/start_kboot.o (.text .rodata) + *(.text .rodata) } . = ALIGN(4); diff --git a/qiboot/src/start_kboot.c b/qiboot/src/start_kboot.c index b4256d2..10badfa 100644 --- a/qiboot/src/start_kboot.c +++ b/qiboot/src/start_kboot.c @@ -28,18 +28,8 @@ #include "kboot.h" #include -/* -unsigned char buf[]={ -0x0d,0xc0,0xa0,0xe1,0x00,0xd8,0x2d,0xe9,0x04,0xb0,0x4c,0xe2,0x4c,0x20,0x9f,0xe5, -0x05,0x30,0xa0,0xe3,0x00,0x30,0x82,0xe5,0x44,0x20,0x9f,0xe5,0x44,0x30,0x9f,0xe5, -0x00,0x30,0x82,0xe5,0x40,0x20,0x9f,0xe5,0x3c,0x30,0x9f,0xe5,0x00,0x30,0x93,0xe5, -0x01,0x30,0xc3,0xe3,0x00,0x30,0x82,0xe5,0x28,0x00,0x9f,0xe5,0x0b,0x00,0x00,0xeb, -0x24,0x20,0x9f,0xe5,0x20,0x30,0x9f,0xe5,0x00,0x30,0x93,0xe5,0x01,0x30,0x83,0xe3, -0x00,0x30,0x82,0xe5,0x0c,0x00,0x9f,0xe5,0x04,0x00,0x00,0xeb,0xf0,0xff,0xff,0xea, -0x10,0x00,0x00,0x56,0x18,0x00,0x00,0x56,0xff,0xff,0x00,0x00,0x14,0x00,0x00,0x56, -0x01,0x00,0x50,0xe2,0xfd,0xff,0xff,0x1a,0x0e,0xf0,0xa0,0xe1,0x0a}; -*/ -#define stringify(x) #x +#define stringify2(s) stringify1(s) +#define stringify1(s) #s extern void bootloader_second_phase(void); @@ -50,29 +40,9 @@ void start_kboot(void) port_init(); serial_init(0x11, UART2); - puts("Openmoko KBOOT BUILD_HOST BUILD_VERSION BUILD_DATE\n"); - -#if 0 - while(1) { - serial_putc(2, '0'); - serial_putc(2, 'x'); - print32((unsigned int)&n); - serial_putc(2, ' '); - serial_putc(2, '0'); - serial_putc(2, 'x'); - print32((unsigned int)p); - serial_putc(2, ' '); - serial_putc(2, '0'); - serial_putc(2, 'x'); - print32((unsigned int)hello); - - serial_putc(2, '\n'); - - blue_on(1); - n++; - } - -#endif + puts("Openmoko KBOOT "stringify2(BUILD_HOST)" " + stringify2(BUILD_VERSION)" " + stringify2(BUILD_DATE)"\n"); /* * pull the whole U-Boot image into SDRAM @@ -82,12 +52,9 @@ void start_kboot(void) while(1) blink_led(); - serial_putc(2, '0'); - serial_putc(2, 'x'); - print32((unsigned int)bootloader_second_phase); - serial_putc(2, ' '); - serial_putc(2, '\n'); - + /* + * jump to bootloader_second_phase() running from DRAM copy + */ (phase2)(); } From 5a494607f07379cdb6ad5c1d03001b1eeda4b482 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Wed, 13 Aug 2008 00:44:29 +0100 Subject: [PATCH 032/248] add-kernel-init.patch Huge patch boils down massive kernel image parsing and boot action to a modest sequence of code that actually boots the kernel. Signed-off-by: Andy Green --- qiboot/Makefile | 5 +- qiboot/include/image.h | 572 ++++++++++++++++++++++++++++++++++++ qiboot/include/serial.h | 1 - qiboot/include/setup.h | 269 +++++++++++++++++ qiboot/src/blink_led.c | 2 +- qiboot/src/blink_led.h | 2 +- qiboot/src/kboot-stage1.lds | 17 +- qiboot/src/kboot.h | 1 + qiboot/src/nand_read.c | 40 +-- qiboot/src/serial.c | 17 ++ qiboot/src/start_kboot.c | 10 +- 11 files changed, 890 insertions(+), 46 deletions(-) create mode 100644 qiboot/include/image.h create mode 100644 qiboot/include/setup.h diff --git a/qiboot/Makefile b/qiboot/Makefile index b279e25..1a73ddb 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -25,8 +25,9 @@ BUILD_VERSION := ${BUILD_BRANCH}_${BUILD_HEAD} LDS = src/kboot-stage1.lds INCLUDE = include IMAGE_DIR = image -CFLAGS = -Wall -Werror -fno-builtin -ffreestanding -fno-strict-aliasing \ - -fno-common -ffixed-r8 -I $(INCLUDE) -g -c \ +CFLAGS = -Wall -Werror -I $(INCLUDE) -g -c -O2 -fno-strict-aliasing \ + -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}" LDFLAGS = diff --git a/qiboot/include/image.h b/qiboot/include/image.h new file mode 100644 index 0000000..2e3c6ef --- /dev/null +++ b/qiboot/include/image.h @@ -0,0 +1,572 @@ +/* + * (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__ + +#include + +/* + * 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_() + * 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) ntohl(x) +#define cpu_to_uimage(x) htonl(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__ */ diff --git a/qiboot/include/serial.h b/qiboot/include/serial.h index 12e2ae9..732fe67 100644 --- a/qiboot/include/serial.h +++ b/qiboot/include/serial.h @@ -107,7 +107,6 @@ void port_init(void); void serial_init (const int ubrdiv_val,const int uart); void serial_putc (const int uart,const char c); int printk(const char *fmt, ...); -int vsprintf(char *buf, const char *fmt, va_list args); int puts(const char *string); #endif diff --git a/qiboot/include/setup.h b/qiboot/include/setup.h new file mode 100644 index 0000000..89df4dc --- /dev/null +++ b/qiboot/include/setup.h @@ -0,0 +1,269 @@ +/* + * 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 diff --git a/qiboot/src/blink_led.c b/qiboot/src/blink_led.c index fa4482e..e1e7a94 100644 --- a/qiboot/src/blink_led.c +++ b/qiboot/src/blink_led.c @@ -27,7 +27,7 @@ int delay(int time) for(i=0;i 0) { + print32((int)start); + serial_putc(DEBUG_CONSOLE_UART, ':'); + serial_putc(DEBUG_CONSOLE_UART, ' '); + for (n = 0; n < 16; n++) { + printhex(*start++); + serial_putc(DEBUG_CONSOLE_UART, ' '); + } + serial_putc(DEBUG_CONSOLE_UART, '\n'); + len -= 16; + } +} + int printk(const char *fmt, ...) { va_list args; diff --git a/qiboot/src/start_kboot.c b/qiboot/src/start_kboot.c index 10badfa..2e2c605 100644 --- a/qiboot/src/start_kboot.c +++ b/qiboot/src/start_kboot.c @@ -35,7 +35,8 @@ extern void bootloader_second_phase(void); void start_kboot(void) { - void (*phase2)(void) = bootloader_second_phase + TEXT_BASE; + void (*phase2)(void) = (void (*)(void))((int)bootloader_second_phase + + TEXT_BASE); port_init(); serial_init(0x11, UART2); @@ -43,18 +44,15 @@ void start_kboot(void) puts("Openmoko KBOOT "stringify2(BUILD_HOST)" " stringify2(BUILD_VERSION)" " stringify2(BUILD_DATE)"\n"); - /* - * pull the whole U-Boot image into SDRAM + * pull the whole bootloader image into SDRAM */ - if (nand_read_ll((unsigned char *)TEXT_BASE, 0, 256 * 1024) < 0) + if (nand_read_ll((unsigned char *)TEXT_BASE, 0, 24 * 1024) < 0) while(1) blink_led(); - /* * jump to bootloader_second_phase() running from DRAM copy */ - (phase2)(); } From a9c7c4718992947021cc3553807d822165aa080b Mon Sep 17 00:00:00 2001 From: Andy Green Date: Wed, 13 Aug 2008 00:44:56 +0100 Subject: [PATCH 033/248] tidy-strings.patch Move things around to tidy them up Signed-off-by: Andy Green --- qiboot/src/kboot.h | 1 + qiboot/src/phase2.c | 25 ---------- qiboot/src/serial.c | 67 ------------------------- qiboot/src/utils.c | 117 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+), 92 deletions(-) create mode 100644 qiboot/src/utils.c diff --git a/qiboot/src/kboot.h b/qiboot/src/kboot.h index 1c70dda..6ad28de 100644 --- a/qiboot/src/kboot.h +++ b/qiboot/src/kboot.h @@ -12,6 +12,7 @@ int puts(const char *string); void printhex(unsigned char v); void print32(unsigned int u); void hexdump(unsigned char *start, int len); +unsigned int _ntohl(unsigned int n); #endif diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 75ae2fd..4c4fedf 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -23,31 +23,6 @@ typedef unsigned int uint32_t; #define C1_IC (1<<12) /* icache off/on */ #define C1_HIGH_VECTORS (1<<13) /* location of vectors: low/high addresses */ -size_t strlen(const char *s) -{ - size_t n = 0; - - while (*s++) - n++; - - return n; -} - -char *strcpy(char *dest, const char *src) -{ - char * dest_orig = dest; - - while (*src) - *dest++ = *src++; - - return dest_orig; -} - -unsigned int _ntohl(unsigned int n) { - return ((n & 0xff) << 24) | ((n & 0xff00) << 8) | - ((n & 0xff0000) >> 8) | ((n & 0xff000000) >> 24); -} - void bootloader_second_phase(void) { image_header_t *hdr; diff --git a/qiboot/src/serial.c b/qiboot/src/serial.c index 5fb8b04..7b56fe6 100644 --- a/qiboot/src/serial.c +++ b/qiboot/src/serial.c @@ -23,8 +23,6 @@ #include "blink_led.h" #include "kboot.h" -#define DEBUG_CONSOLE_UART UART2 - void serial_init (const int ubrdiv_val,const int uart) { switch(uart) @@ -77,71 +75,6 @@ void serial_putc (const int uart,const char c) } } -int puts(const char *string) -{ - while (*string) - serial_putc(DEBUG_CONSOLE_UART, *string++); - serial_putc(DEBUG_CONSOLE_UART, '\n'); - - return 1; -} - -/* done like this to avoid needing statics in steppingstone */ -void printnybble(unsigned char n) -{ - if (n < 10) - serial_putc(DEBUG_CONSOLE_UART, '0' + n); - else - serial_putc(DEBUG_CONSOLE_UART, 'a' + n - 10); -} - -void printhex(unsigned char n) -{ - printnybble((n >> 4) & 15); - printnybble(n & 15); -} - -void print32(unsigned int u) -{ - printhex(u >> 24); - printhex(u >> 16); - printhex(u >> 8); - printhex(u); -} - -void hexdump(unsigned char *start, int len) -{ - int n; - - while (len > 0) { - print32((int)start); - serial_putc(DEBUG_CONSOLE_UART, ':'); - serial_putc(DEBUG_CONSOLE_UART, ' '); - for (n = 0; n < 16; n++) { - printhex(*start++); - serial_putc(DEBUG_CONSOLE_UART, ' '); - } - serial_putc(DEBUG_CONSOLE_UART, '\n'); - len -= 16; - } -} - -int printk(const char *fmt, ...) -{ - va_list args; - int r; - static char buf[512]; - const char *p = buf; - - va_start(args, fmt); - r = vsprintf(buf, fmt, args); - va_end(args); - p = fmt; - while (*p) - serial_putc(DEBUG_CONSOLE_UART, *p++); - - return r; -} /* * ===================================================================== diff --git a/qiboot/src/utils.c b/qiboot/src/utils.c new file mode 100644 index 0000000..cb444d7 --- /dev/null +++ b/qiboot/src/utils.c @@ -0,0 +1,117 @@ +/* + * (C) Copyright 2008 Openmoko, Inc. + * Author: Andy Green + * + * Little utils for print and strings + * + * 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 "kboot.h" +#include + +#define DEBUG_CONSOLE_UART UART2 + +size_t strlen(const char *s) +{ + size_t n = 0; + + while (*s++) + n++; + + return n; +} + +char *strcpy(char *dest, const char *src) +{ + char * dest_orig = dest; + + while (*src) + *dest++ = *src++; + + return dest_orig; +} + +unsigned int _ntohl(unsigned int n) { + return ((n & 0xff) << 24) | ((n & 0xff00) << 8) | + ((n & 0xff0000) >> 8) | ((n & 0xff000000) >> 24); +} + +int puts(const char *string) +{ + while (*string) + serial_putc(DEBUG_CONSOLE_UART, *string++); + serial_putc(DEBUG_CONSOLE_UART, '\n'); + + return 1; +} + +/* done like this to avoid needing statics in steppingstone */ +void printnybble(unsigned char n) +{ + if (n < 10) + serial_putc(DEBUG_CONSOLE_UART, '0' + n); + else + serial_putc(DEBUG_CONSOLE_UART, 'a' + n - 10); +} + +void printhex(unsigned char n) +{ + printnybble((n >> 4) & 15); + printnybble(n & 15); +} + +void print32(unsigned int u) +{ + printhex(u >> 24); + printhex(u >> 16); + printhex(u >> 8); + printhex(u); +} + +void hexdump(unsigned char *start, int len) +{ + int n; + + while (len > 0) { + print32((int)start); + serial_putc(DEBUG_CONSOLE_UART, ':'); + serial_putc(DEBUG_CONSOLE_UART, ' '); + for (n = 0; n < 16; n++) { + printhex(*start++); + serial_putc(DEBUG_CONSOLE_UART, ' '); + } + serial_putc(DEBUG_CONSOLE_UART, '\n'); + len -= 16; + } +} + +int printk(const char *fmt, ...) +{ + va_list args; + int r; + static char buf[512]; + const char *p = buf; + + va_start(args, fmt); + r = vsprintf(buf, fmt, args); + va_end(args); + p = fmt; + while (*p) + serial_putc(DEBUG_CONSOLE_UART, *p++); + + return r; +} From 4391a5281995f2613e9108f4b395cc26792b1310 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Wed, 13 Aug 2008 00:45:21 +0100 Subject: [PATCH 034/248] remove-prink.patch didn't need it and it doubled the size of the bootloader :-O Signed-off-by: Andy Green --- qiboot/src/sprintf.c | 342 ------------------------------------------- qiboot/src/utils.c | 16 -- 2 files changed, 358 deletions(-) delete mode 100644 qiboot/src/sprintf.c diff --git a/qiboot/src/sprintf.c b/qiboot/src/sprintf.c deleted file mode 100644 index 21253a1..0000000 --- a/qiboot/src/sprintf.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * linux/lib/vsprintf.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - */ - -/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ -/* - * Wirzenius wrote this portably, Torvalds fucked it up :-) - */ - -#include -#include "ctype.h" - - - -int strnlen(const char * s, int count) -{ - const char *sc; - - for (sc = s; count-- && *sc != '\0'; ++sc) - /* nothing */; - return sc - s; -} - - -unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base) -{ - unsigned long result = 0,value; - - if (!base) { - base = 10; - if (*cp == '0') { - base = 8; - cp++; - if ((toupper(*cp) == 'X') && isxdigit(cp[1])) { - cp++; - base = 16; - } - } - } else if (base == 16) { - if (cp[0] == '0' && toupper(cp[1]) == 'X') - cp += 2; - } - while (isxdigit(*cp) && - (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) { - result = result*base + value; - cp++; - } - if (endp) - *endp = (char *)cp; - return result; -} - -long simple_strtol(const char *cp,char **endp,unsigned int base) -{ - if(*cp=='-') - return -simple_strtoul(cp+1,endp,base); - return simple_strtoul(cp,endp,base); -} - -/* we use this so that we can do without the ctype library */ -#define is_digit(c) ((c) >= '0' && (c) <= '9') - -static int skip_atoi(const char **s) -{ - int i=0; - - while (is_digit(**s)) - i = i*10 + *((*s)++) - '0'; - return i; -} - -#define ZEROPAD 1 /* pad with zero */ -#define SIGN 2 /* unsigned/signed long */ -#define PLUS 4 /* show plus */ -#define SPACE 8 /* space if plus */ -#define LEFT 16 /* left justified */ -#define SPECIAL 32 /* 0x */ -#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ - - -int raise(int n) -{ - return 0; -} - -#define do_div(n,base) ({ \ - int __res; \ - __res = (n) - (((n) / (base)) * (base)); \ - n = ((unsigned long) n) / base; \ - __res; \ -}) - -static char * number(char * str, long num, unsigned int base, int size, int precision ,int type) -{ - char c,sign,tmp[66]; - const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; - int i; - - if (type & LARGE) - digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - if (type & LEFT) - type &= ~ZEROPAD; - if (base < 2 || base > 36) - return 0; - c = (type & ZEROPAD) ? '0' : ' '; - sign = 0; - if (type & SIGN) { - if (num < 0) { - sign = '-'; - num = -num; - size--; - } else if (type & PLUS) { - sign = '+'; - size--; - } else if (type & SPACE) { - sign = ' '; - size--; - } - } - if (type & SPECIAL) { - if (base == 16) - size -= 2; - else if (base == 8) - size--; - } - i = 0; - if (num == 0) - tmp[i++]='0'; - else while (num != 0) - tmp[i++] = digits[do_div(num,base)]; - if (i > precision) - precision = i; - size -= precision; - if (!(type&(ZEROPAD+LEFT))) - while(size-->0) - *str++ = ' '; - if (sign) - *str++ = sign; - if (type & SPECIAL) { - if (base==8) - *str++ = '0'; - else if (base==16) { - *str++ = '0'; - *str++ = digits[33]; - } - } - if (!(type & LEFT)) - while (size-- > 0) - *str++ = c; - while (i < precision--) - *str++ = '0'; - while (i-- > 0) - *str++ = tmp[i]; - while (size-- > 0) - *str++ = ' '; - return str; -} - -/* Forward decl. needed for IP address printing stuff... */ -int sprintf(char * buf, const char *fmt, ...); - -int vsprintf(char *buf, const char *fmt, va_list args) -{ - int len; - unsigned long num; - int i, base; - char * str; - const char *s; - - int flags; /* flags to number() */ - - int field_width; /* width of output field */ - int precision; /* min. # of digits for integers; max - number of chars for from string */ - int qualifier; /* 'h', 'l', or 'q' for integer fields */ - - for (str=buf ; *fmt ; ++fmt) { - if (*fmt != '%') { - *str++ = *fmt; - continue; - } - - /* process flags */ - flags = 0; - repeat: - ++fmt; /* this also skips first '%' */ - switch (*fmt) { - case '-': flags |= LEFT; goto repeat; - case '+': flags |= PLUS; goto repeat; - case ' ': flags |= SPACE; goto repeat; - case '#': flags |= SPECIAL; goto repeat; - case '0': flags |= ZEROPAD; goto repeat; - } - - /* get field width */ - field_width = -1; - if (is_digit(*fmt)) - field_width = skip_atoi(&fmt); - else if (*fmt == '*') { - ++fmt; - /* it's the next argument */ - field_width = va_arg(args, int); - if (field_width < 0) { - field_width = -field_width; - flags |= LEFT; - } - } - - /* get the precision */ - precision = -1; - if (*fmt == '.') { - ++fmt; - if (is_digit(*fmt)) - precision = skip_atoi(&fmt); - else if (*fmt == '*') { - ++fmt; - /* it's the next argument */ - precision = va_arg(args, int); - } - if (precision < 0) - precision = 0; - } - - /* get the conversion qualifier */ - qualifier = -1; - if (*fmt == 'h' || *fmt == 'l' || *fmt == 'q') { - qualifier = *fmt; - if (qualifier == 'l' && *(fmt+1) == 'l') { - qualifier = 'q'; - ++fmt; - } - ++fmt; - } - - /* default base */ - base = 10; - - switch (*fmt) { - case 'c': - if (!(flags & LEFT)) - while (--field_width > 0) - *str++ = ' '; - *str++ = (unsigned char) va_arg(args, int); - while (--field_width > 0) - *str++ = ' '; - continue; - - case 's': - s = va_arg(args, char *); - if (!s) - s = ""; - - len = strnlen(s, precision); - - if (!(flags & LEFT)) - while (len < field_width--) - *str++ = ' '; - for (i = 0; i < len; ++i) - *str++ = *s++; - while (len < field_width--) - *str++ = ' '; - continue; - - case 'p': - if (field_width == -1) { - field_width = 2*sizeof(void *); - flags |= ZEROPAD; - } - str = number(str, - (unsigned long) va_arg(args, void *), 16, - field_width, precision, flags); - continue; - - - case 'n': - if (qualifier == 'l') { - long * ip = va_arg(args, long *); - *ip = (str - buf); - } else { - int * ip = va_arg(args, int *); - *ip = (str - buf); - } - continue; - - case '%': - *str++ = '%'; - continue; - - /* integer number formats - set up the flags and "break" */ - case 'o': - base = 8; - break; - - case 'X': - flags |= LARGE; - case 'x': - base = 16; - break; - - case 'd': - case 'i': - flags |= SIGN; - case 'u': - break; - - default: - *str++ = '%'; - if (*fmt) - *str++ = *fmt; - else - --fmt; - continue; - } - if (qualifier == 'l') - num = va_arg(args, unsigned long); - else if (qualifier == 'h') { - num = (unsigned short) va_arg(args, int); - if (flags & SIGN) - num = (short) num; - } else if (flags & SIGN) - num = va_arg(args, int); - else - num = va_arg(args, unsigned int); - str = number(str, num, base, field_width, precision, flags); - } - *str = '\0'; - return str-buf; -} - -int sprintf(char * buf, const char *fmt, ...) -{ - va_list args; - int i; - - va_start(args, fmt); - i=vsprintf(buf,fmt,args); - va_end(args); - return i; -} - diff --git a/qiboot/src/utils.c b/qiboot/src/utils.c index cb444d7..c9506c2 100644 --- a/qiboot/src/utils.c +++ b/qiboot/src/utils.c @@ -99,19 +99,3 @@ void hexdump(unsigned char *start, int len) } } -int printk(const char *fmt, ...) -{ - va_list args; - int r; - static char buf[512]; - const char *p = buf; - - va_start(args, fmt); - r = vsprintf(buf, fmt, args); - va_end(args); - p = fmt; - while (*p) - serial_putc(DEBUG_CONSOLE_UART, *p++); - - return r; -} From b8407950d8c1afb8bb2edcce17cb31ac6e93bf88 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Wed, 13 Aug 2008 00:45:55 +0100 Subject: [PATCH 035/248] add-comments-and-tidy.patch Push the config options into a config .h, tidy things, add attribution Signed-off-by: Andy Green --- qiboot/include/device_configuration.h | 15 ++++ qiboot/src/kboot-stage1.lds | 5 ++ qiboot/src/kboot.h | 19 ++++ qiboot/src/phase2.c | 66 ++++++++------ qiboot/src/serial.c | 119 ------------------------ qiboot/src/start_kboot.c | 125 +++++++++++++++++++++++++- 6 files changed, 204 insertions(+), 145 deletions(-) create mode 100644 qiboot/include/device_configuration.h diff --git a/qiboot/include/device_configuration.h b/qiboot/include/device_configuration.h new file mode 100644 index 0000000..69e247c --- /dev/null +++ b/qiboot/include/device_configuration.h @@ -0,0 +1,15 @@ +/* define the easily changed settings for the device here */ + +#define CFG_NAND_OFFSET_FOR_KERNEL_PARTITION 0x80000 +#define CFG_LINUX_MACHINE_ID 1304 +#define CFG_LINUX_ATAG_ADDRESS 0x30000100 +#define CFG_LINUX_CMDLINE "rootfstype=ext2 " \ + "root=/dev/mmcblk0p1 " \ + "console=ttySAC2,115200 " \ + "loglevel=8 " \ + "init=/sbin/init ro" +#define CFG_LINUX_BIGGEST_KERNEL (4 * 1024 * 1024) +#define CFG_MACHINE_REVISION 0x350 +#define CFG_MEMORY_REGION_START 0x30000000 +#define CFG_MEMORY_REGION_SIZE (128 * 1024 * 1024) + diff --git a/qiboot/src/kboot-stage1.lds b/qiboot/src/kboot-stage1.lds index 7987801..5c8d50c 100644 --- a/qiboot/src/kboot-stage1.lds +++ b/qiboot/src/kboot-stage1.lds @@ -29,6 +29,11 @@ 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 : { diff --git a/qiboot/src/kboot.h b/qiboot/src/kboot.h index 6ad28de..af47a12 100644 --- a/qiboot/src/kboot.h +++ b/qiboot/src/kboot.h @@ -1,3 +1,22 @@ +/* + * (C) Copyright 2008 Openmoko, Inc. + * Author: Andy Green + * + * 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 __KBOOT_H__ #define __KBOOT_H__ diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 4c4fedf..ac43822 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -1,3 +1,26 @@ +/* + * (C) Copyright 2008 Openmoko, Inc. + * Author: Andy Green + * + * Parse the U-Boot header and Boot Linux + * based on various code from U-Boot + * + * 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 "kboot.h" #include #include "blink_led.h" @@ -12,32 +35,26 @@ typedef unsigned int uint32_t; #include #include "nand_read.h" -/* See also ARM920T Technical reference Manual */ -#define C1_MMU (1<<0) /* mmu off/on */ -#define C1_ALIGN (1<<1) /* alignment faults off/on */ -#define C1_DC (1<<2) /* dcache off/on */ +#include -#define C1_BIG_ENDIAN (1<<7) /* big endian off/on */ -#define C1_SYS_PROT (1<<8) /* system protection */ -#define C1_ROM_PROT (1<<9) /* ROM protection */ +#define C1_DC (1<<2) /* dcache off/on */ #define C1_IC (1<<12) /* icache off/on */ -#define C1_HIGH_VECTORS (1<<13) /* location of vectors: low/high addresses */ void bootloader_second_phase(void) { image_header_t *hdr; unsigned long i = 0; - int machid = 1304; /* GTA02 */ - void (*theKernel)(int zero, int arch, uint params); - struct tag * params_base = (struct tag *)0x30000100; /* atags need to live here */ + void (*the_kernel)(int zero, int arch, uint params); + struct tag * params_base = (struct tag *)CFG_LINUX_ATAG_ADDRESS; struct tag *params = params_base; - const char * cmdline = "rootfstype=ext2 root=/dev/mmcblk0p1 console=ttySAC2,115200 loglevel=8 init=/sbin/init ro"; + const char * cmdline = CFG_LINUX_CMDLINE; const char *p = cmdline; - void * kernel_nand = (void *)(TEXT_BASE - 4 * 1024 * 1024); + void * kernel_nand = (void *)(TEXT_BASE - CFG_LINUX_BIGGEST_KERNEL); puts("Checking kernel... "); - if (nand_read_ll(kernel_nand, 0x80000, 4096) < 0) { + if (nand_read_ll(kernel_nand, CFG_NAND_OFFSET_FOR_KERNEL_PARTITION, + 4096) < 0) { puts ("Kernel header read failed\n"); goto unhappy; } @@ -54,18 +71,17 @@ void bootloader_second_phase(void) puts("Fetching kernel..."); - if (nand_read_ll(kernel_nand, 0x80000, ((32 * 1024) + - (_ntohl(hdr->ih_size) + - sizeof(hdr) + 2048)) & - ~(2048 - 1)) < 0) { + if (nand_read_ll(kernel_nand, CFG_NAND_OFFSET_FOR_KERNEL_PARTITION, + ((32 * 1024) + (_ntohl(hdr->ih_size) + sizeof(hdr) + 2048)) & + ~(2048 - 1)) < 0) { puts ("Kernel body read failed\n"); goto unhappy; } puts(" Done"); - theKernel = (void (*)(int, int, uint)) - (((char *)hdr) + sizeof(image_header_t)); + the_kernel = (void (*)(int, int, uint)) + (((char *)hdr) + sizeof(image_header_t)); /* first tag */ params->hdr.tag = ATAG_CORE; @@ -78,14 +94,14 @@ void bootloader_second_phase(void) /* revision tag */ params->hdr.tag = ATAG_REVISION; params->hdr.size = tag_size (tag_revision); - params->u.revision.rev = 0x350; + params->u.revision.rev = CFG_MACHINE_REVISION; params = tag_next (params); /* memory tags */ params->hdr.tag = ATAG_MEM; params->hdr.size = tag_size (tag_mem32); - params->u.mem.start = 0x30000000; - params->u.mem.size = 128 * 1024 * 1024; + params->u.mem.start = CFG_MEMORY_REGION_START; + params->u.mem.size = CFG_MEMORY_REGION_SIZE; params = tag_next (params); /* kernel commandline */ @@ -104,7 +120,7 @@ void bootloader_second_phase(void) params->hdr.tag = ATAG_NONE; params->hdr.size = 0; - puts ("Running Linux...\n\n"); + puts ("Running Linux --->\n\n"); /* trash the cache */ @@ -119,7 +135,7 @@ void bootloader_second_phase(void) /* ooh that's it, we're gonna try boot this image! */ - theKernel(0, machid, (unsigned int)params_base); + the_kernel(0, CFG_LINUX_MACHINE_ID, (unsigned int)params_base); /* that didn't quite pan out */ diff --git a/qiboot/src/serial.c b/qiboot/src/serial.c index 7b56fe6..e5b1952 100644 --- a/qiboot/src/serial.c +++ b/qiboot/src/serial.c @@ -74,122 +74,3 @@ void serial_putc (const int uart,const char c) break; } } - - -/* - * ===================================================================== - * PORTS Librarues - * ===================================================================== - */ -void port_init(void) -{ - //CAUTION:Follow the configuration order for setting the ports. - // 1) setting value(GPnDAT) - // 2) setting control register (GPnCON) - // 3) configure pull-up 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 |= (1 << 16); /* Set GPA16 to high (nNAND_WP) */ - /* - * ===* 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; - /* - * === 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); - /* - * === 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 = 0x0000AAAA; - rGPFUP = 0x000000FF & ~(1 << 3); - - - /* - * === 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; - /* - * === PORT H GROUP - * Ports : GPH10 GPH9 GPH8 GPH7 GPH6 GPH5 GPH4 GPH3 GPH2 GPH1 GPH0 - * Signal : CLKOUT1 CLKOUT0 UCLK nCTS1 nRTS1 RXD1 TXD1 RXD0 TXD0 nRTS0 nCTS0 - * Binary : 10 , 10 10 , 11 11 , 10 10 , 10 10 , 10 10 - */ - /* pulldown on GPH08: UEXTCLK, just floats! - * pulldown GPH0 -- nCTS0 / RTS_MODEM -- floats when GSM off - * pulldown GPH3 -- RXD[0] / TX_MODEM -- floats when GSM off - */ - rGPHCON = 0x001AAAAA; - rGPHUP = 0x000007FF & ~(1 << 8) & ~(1 << 0) & ~(1 << 3); - - /* 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 |= (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 */ -} diff --git a/qiboot/src/start_kboot.c b/qiboot/src/start_kboot.c index 2e2c605..51625ca 100644 --- a/qiboot/src/start_kboot.c +++ b/qiboot/src/start_kboot.c @@ -1,6 +1,7 @@ /* * (C) Copyright 2007 OpenMoko, Inc. * Author: xiangfu liu + * Andy Green * * Configuation settings for the OPENMOKO Neo GTA02 Linux GSM phone * @@ -33,6 +34,121 @@ extern void bootloader_second_phase(void); +void port_init(void) +{ + //CAUTION:Follow the configuration order for setting the ports. + // 1) setting value(GPnDAT) + // 2) setting control register (GPnCON) + // 3) configure pull-up 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 |= (1 << 16); /* Set GPA16 to high (nNAND_WP) */ + /* + * ===* 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; + /* + * === 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); + /* + * === 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 = 0x0000AAAA; + rGPFUP = 0x000000FF & ~(1 << 3); + + + /* + * === 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; + /* + * === PORT H GROUP + * Ports : GPH10 GPH9 GPH8 GPH7 GPH6 GPH5 GPH4 GPH3 GPH2 GPH1 GPH0 + * Signal : CLKOUT1 CLKOUT0 UCLK nCTS1 nRTS1 RXD1 TXD1 RXD0 TXD0 nRTS0 nCTS0 + * Binary : 10 , 10 10 , 11 11 , 10 10 , 10 10 , 10 10 + */ + /* pulldown on GPH08: UEXTCLK, just floats! + * pulldown GPH0 -- nCTS0 / RTS_MODEM -- floats when GSM off + * pulldown GPH3 -- RXD[0] / TX_MODEM -- floats when GSM off + */ + rGPHCON = 0x001AAAAA; + rGPHUP = 0x000007FF & ~(1 << 8) & ~(1 << 0) & ~(1 << 3); + + /* 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 |= (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 */ +} + + + void start_kboot(void) { void (*phase2)(void) = (void (*)(void))((int)bootloader_second_phase + @@ -45,9 +161,16 @@ void start_kboot(void) stringify2(BUILD_VERSION)" " stringify2(BUILD_DATE)"\n"); /* - * pull the whole bootloader image into SDRAM + * We got the first 4KBytes of the bootloader pulled into the + * steppingstone SRAM for free. Now we pull the whole bootloader + * image into SDRAM. + * + * So this doesn't trash position-dependent code, we took care in the + * linker script to arrange all rodata* segment content to be in the + * first 4K region. */ + /* We randomly pull 24KBytes of bootloader */ if (nand_read_ll((unsigned char *)TEXT_BASE, 0, 24 * 1024) < 0) while(1) blink_led(); From 7c0e35e1a226968114ff54b7ba7cd9150b7ffa12 Mon Sep 17 00:00:00 2001 From: xiangfu Date: Sat, 16 Aug 2008 09:51:37 -0400 Subject: [PATCH 036/248] delete some commend and change ubrdiv_var inner serial_init funtion --- qiboot/include/serial.h | 2 +- qiboot/src/serial.c | 3 ++- qiboot/src/start.S | 19 ++----------------- qiboot/src/start_kboot.c | 2 +- 4 files changed, 6 insertions(+), 20 deletions(-) diff --git a/qiboot/include/serial.h b/qiboot/include/serial.h index 732fe67..c10a386 100644 --- a/qiboot/include/serial.h +++ b/qiboot/include/serial.h @@ -104,7 +104,7 @@ #define rGPJUP (*(volatile unsigned *)0x560000d8) //Port J data void port_init(void); -void serial_init (const int ubrdiv_val,const int uart); +void serial_init (const int uart); void serial_putc (const int uart,const char c); int printk(const char *fmt, ...); int puts(const char *string); diff --git a/qiboot/src/serial.c b/qiboot/src/serial.c index e5b1952..5432056 100644 --- a/qiboot/src/serial.c +++ b/qiboot/src/serial.c @@ -23,8 +23,9 @@ #include "blink_led.h" #include "kboot.h" -void serial_init (const int ubrdiv_val,const int uart) +void serial_init (const int uart) { + int ubrdiv_val = 0x11; switch(uart) { case UART0: diff --git a/qiboot/src/start.S b/qiboot/src/start.S index c16a2a0..1d2ee92 100644 --- a/qiboot/src/start.S +++ b/qiboot/src/start.S @@ -89,8 +89,6 @@ start_code: # define UPLLCON 0x4c000008 # define MPLLCON_val ((142 << 12) + (7 << 4) + 1) # define UPLLCON_val (( 88 << 12) + (8 << 4) + 2) -/* # define MPLLCON_val ((0x7d << 12) + (0x2 << 4) + 0x1) -# define UPLLCON_val ((0x38 << 12) + (0x2 << 4) + 0x2) */ ldr r0, =UPLLCON ldr r1, =UPLLCON_val @@ -108,7 +106,7 @@ start_code: ldr r1, =MPLLCON_val str r1, [r0, #-4] /* MPLLCON */ -# define CLKDIVN 0x4C000014 /* clock divisor register */ +# define CLKDIVN 0x4C000014 /* clock divisor register */ # define CLKDIVN_val 7 /* FCLK:HCLK:PCLK = 1:3:6 */ /* FCLK:HCLK:PCLK = 1:3:6 */ @@ -126,19 +124,6 @@ start_code: ldr r1, =0x2afaaa str r1, [r0] - /* init uart0 */ -/* ldr r0, =0x50000000 - 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, #0x7 - str r1, [r0, #0x28] */ - bl cpu_init_crit /* reset nand controller, or it is dead to us */ @@ -153,7 +138,7 @@ start_code: orr r3, r3, #1 @ enable nand controller str r3, [r1, #4] - /* >> CFG_VIDEO_LOGO_MAX_SIZE */ + /* >> 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 */ diff --git a/qiboot/src/start_kboot.c b/qiboot/src/start_kboot.c index 51625ca..12806ce 100644 --- a/qiboot/src/start_kboot.c +++ b/qiboot/src/start_kboot.c @@ -155,7 +155,7 @@ void start_kboot(void) TEXT_BASE); port_init(); - serial_init(0x11, UART2); + serial_init(UART2); puts("Openmoko KBOOT "stringify2(BUILD_HOST)" " stringify2(BUILD_VERSION)" " From 4adc376ba22148215c845596331d6d13efa622a0 Mon Sep 17 00:00:00 2001 From: xiangfu Date: Sat, 16 Aug 2008 10:24:29 -0400 Subject: [PATCH 037/248] mv some .h file to src/ there are same files. --- qiboot/Makefile | 2 +- qiboot/include/blink_led.h | 42 -------------- qiboot/include/nand_read.h | 22 -------- qiboot/include/serial.h | 112 ------------------------------------- qiboot/src/blink_led.h | 1 + 5 files changed, 2 insertions(+), 177 deletions(-) delete mode 100644 qiboot/include/blink_led.h delete mode 100644 qiboot/include/nand_read.h delete mode 100644 qiboot/include/serial.h diff --git a/qiboot/Makefile b/qiboot/Makefile index 1a73ddb..22851f2 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -64,9 +64,9 @@ ${OBJS}:${SRCS} ${UDFU_IMAGE}:${OBJS} $(LD) ${LDFLAGS} -T$(LDS) -g $(OBJS) -o ${TARGET} ${LIBS} $(OBJCOPY) -O binary -S ${TARGET} ${IMAGE} + $(OBJDUMP) -D ${TARGET} >${IMAGE}.dis $(MKUDFU) -v ${UDFU_VID} -p ${UDFU_PID} -r ${UDFU_REV} \ -d ${IMAGE} ${UDFU_IMAGE} - $(OBJDUMP) -D ${TARGET} >${IMAGE}.dis blink_led:src/led_on.S $(CC) $(CFLAGS) led_on.o led_on.S diff --git a/qiboot/include/blink_led.h b/qiboot/include/blink_led.h deleted file mode 100644 index a32f395..0000000 --- a/qiboot/include/blink_led.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * (C) Copyright 2007 OpenMoko, Inc. - * Author: xiangfu liu - * - * 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)) - -#define ORANGE 1; -#define BLUE 0; - -int orange_on(int times); -int blue_on(int times); -int blink_led(void); -int delay(int time); - -#endif /* __BLINK_LED_H */ diff --git a/qiboot/include/nand_read.h b/qiboot/include/nand_read.h deleted file mode 100644 index 71aeda5..0000000 --- a/qiboot/include/nand_read.h +++ /dev/null @@ -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 - * Date : $Date: 2004/02/04 10:37:37 $ - * - * u-boot integration and bad-block skipping (C) 2006 by OpenMoko, Inc. - * Author: Harald Welte - */ -#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 */ diff --git a/qiboot/include/serial.h b/qiboot/include/serial.h deleted file mode 100644 index c10a386..0000000 --- a/qiboot/include/serial.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * (C) Copyright 2007 OpenMoko, Inc. - * Author: xiangfu liu - * - * 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_H__ -#define __SERIAL_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) - - - -// 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 - -void port_init(void); -void serial_init (const int uart); -void serial_putc (const int uart,const char c); -int printk(const char *fmt, ...); -int puts(const char *string); - -#endif diff --git a/qiboot/src/blink_led.h b/qiboot/src/blink_led.h index 8485404..a32f395 100644 --- a/qiboot/src/blink_led.h +++ b/qiboot/src/blink_led.h @@ -37,5 +37,6 @@ int orange_on(int times); int blue_on(int times); int blink_led(void); +int delay(int time); #endif /* __BLINK_LED_H */ From 09407415de21c19843866ec4d964df621d8277f3 Mon Sep 17 00:00:00 2001 From: xiangfu Date: Sat, 16 Aug 2008 10:25:25 -0400 Subject: [PATCH 038/248] mv some .h file to src/ there are same files. --- qiboot/src/serial.h | 112 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 qiboot/src/serial.h diff --git a/qiboot/src/serial.h b/qiboot/src/serial.h new file mode 100644 index 0000000..c10a386 --- /dev/null +++ b/qiboot/src/serial.h @@ -0,0 +1,112 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: xiangfu liu + * + * 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_H__ +#define __SERIAL_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) + + + +// 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 + +void port_init(void); +void serial_init (const int uart); +void serial_putc (const int uart,const char c); +int printk(const char *fmt, ...); +int puts(const char *string); + +#endif From 5b5a581ffa52c09cdcba93e6f0a6b419a0d501ee Mon Sep 17 00:00:00 2001 From: xiangfu Date: Sat, 16 Aug 2008 22:34:17 -0400 Subject: [PATCH 039/248] remove src/Makefile --- qiboot/README | 1 + qiboot/src/Makefile | 46 --------------------------------------------- 2 files changed, 1 insertion(+), 46 deletions(-) delete mode 100644 qiboot/src/Makefile diff --git a/qiboot/README b/qiboot/README index e69de29..8b13789 100644 --- a/qiboot/README +++ b/qiboot/README @@ -0,0 +1 @@ + diff --git a/qiboot/src/Makefile b/qiboot/src/Makefile deleted file mode 100644 index df07141..0000000 --- a/qiboot/src/Makefile +++ /dev/null @@ -1,46 +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 - -LDS = kboot-stage1.lds -INCLUDE = ../include -IMAGE = ../image -CFLAGS = -Wall -I $(INCLUDE) -g -c -o - -START = start.o lowlevel_init.o -COBJS = start_kboot.o nand_read.o blink_led.o - -SRCS := $(START: .o=.S) $(COBJS: .o=.c) - -all:start.S lowlevel_init.S nand_read.c start_kboot.c - $(CC) $(CFLAGS) start.o start.S - $(CC) $(CFLAGS) lowlevel_init.o lowlevel_init.S - $(CC) $(CFLAGS) nand_read.o nand_read.c - $(CC) $(CFLAGS) blink_led.o blink_led.c - $(CC) $(CFLAGS) start_kboot.o start_kboot.c - $(LD) -T$(LDS) -g $(START) $(COBJS) -o start_kboot_all.o - $(OBJCOPY) -O binary -S start_kboot_all.o $(IMAGE)/start - -blink_led:led_on.S - $(CC) $(CFLAGS) led_on.o led_on.S - $(LD) -g led_on.o -o led_on_temp.o - $(OBJCOPY) -O binary -S led_on_temp.o $(IMAGE)/led_on - -clean: - rm -f *.o - rm -f $(IMAGE)/* - rm -f *~ From a0265478626a730271b16810ae21944ff6e70c8f Mon Sep 17 00:00:00 2001 From: xiangfu Date: Sun, 17 Aug 2008 00:28:39 -0400 Subject: [PATCH 040/248] add-mmc.c-and-other-file-but-can-not-boot-from-sd --- qiboot/src/calc_pclk.c | 78 +++++ qiboot/src/common.h | 681 +++++++++++++++++++++++++++++++++++++++++ qiboot/src/fat.h | 220 +++++++++++++ qiboot/src/io.h | 337 ++++++++++++++++++++ qiboot/src/mmc.c | 538 ++++++++++++++++++++++++++++++++ qiboot/src/mmc.h | 33 ++ qiboot/src/part.h | 138 +++++++++ 7 files changed, 2025 insertions(+) create mode 100644 qiboot/src/calc_pclk.c create mode 100644 qiboot/src/common.h create mode 100644 qiboot/src/fat.h create mode 100644 qiboot/src/io.h create mode 100644 qiboot/src/mmc.c create mode 100644 qiboot/src/mmc.h create mode 100644 qiboot/src/part.h diff --git a/qiboot/src/calc_pclk.c b/qiboot/src/calc_pclk.c new file mode 100644 index 0000000..777ad03 --- /dev/null +++ b/qiboot/src/calc_pclk.c @@ -0,0 +1,78 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: xiangfu liu + * + * + * 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 code is not good, some define is + * is already show in other files + */ + +# define CLKDIVN_val (7) +# define CAMDIVN_val (0) +# define CONFIG_SYS_CLK_FREQ (12000000)/* the GTA02 has this input clock */ + +# define MPLL ((142 << 12) + (7 << 4) + 1) +# define BAUDRATE (115200) + +typedef unsigned long ulong; + +static ulong get_PLLCLK(int pllreg) +{ + ulong r, m, p, s; + + if (pllreg == MPLL){ + r = MPLL; + } + + m = ((r & 0xFF000) >> 12) + 8; + p = ((r & 0x003F0) >> 4) + 2; + s = r & 0x3; + /* To avoid integer overflow, changed the calc order */ + if (pllreg == MPLL) + return ( 2 * m * (CONFIG_SYS_CLK_FREQ / (p << s )) ); + else + return ( m * (CONFIG_SYS_CLK_FREQ / (p << s )) ); +} + +ulong get_FCLK(void) +{ + return(get_PLLCLK(MPLL)); +} + + +ulong get_HCLK(void) +{ + switch (CLKDIVN_val & 0x6) { + case 0x0: + return get_FCLK(); + case 0x2: + return get_FCLK()/2; + case 0x4: + return (CAMDIVN_val & 0x200) ? get_FCLK()/8 : get_FCLK()/4; + case 0x6: + return (CAMDIVN_val & 0x100) ? get_FCLK()/6 : get_FCLK()/3; + } + return 0; +} + +ulong get_PCLK(void) +{ + return((CLKDIVN_val & 0x1) ? get_HCLK()/2 : get_HCLK()); +} + diff --git a/qiboot/src/common.h b/qiboot/src/common.h new file mode 100644 index 0000000..055dec2 --- /dev/null +++ b/qiboot/src/common.h @@ -0,0 +1,681 @@ +/* + * (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 +#include +#include +#include +#include +#include +#if defined(CONFIG_PCI) && (defined(CONFIG_4xx) && !defined(CONFIG_AP1000)) +#include +#endif +#if defined(CONFIG_8xx) +#include +#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 +#elif defined(CONFIG_MPC5xxx) +#include +#elif defined(CONFIG_MPC512X) +#include +#include +#elif defined(CONFIG_MPC8220) +#include +#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 +#endif +#ifdef CONFIG_MPC86xx +#include +#include +#endif +#ifdef CONFIG_MPC85xx +#include +#include +#endif +#ifdef CONFIG_MPC83XX +#include +#include +#endif +#ifdef CONFIG_4xx +#include +#endif +#ifdef CONFIG_HYMOD +#include +#endif +#ifdef CONFIG_ARM +#define asmlinkage /* nothing */ +#endif +#ifdef CONFIG_BLACKFIN +#include +#endif + +#include +#include +#include + +#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 /* boot information for Linux kernel */ +#include /* 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 +# include +# include /* ARM version to be fixed! */ +#endif /* CONFIG_ARM */ +#ifdef CONFIG_I386 /* x86 version to be fixed! */ +# include +#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)/.../ */ +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 +#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_ */ diff --git a/qiboot/src/fat.h b/qiboot/src/fat.h new file mode 100644 index 0000000..f993cca --- /dev/null +++ b/qiboot/src/fat.h @@ -0,0 +1,220 @@ +/* + * 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 + +#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_ */ diff --git a/qiboot/src/io.h b/qiboot/src/io.h new file mode 100644 index 0000000..029b7f9 --- /dev/null +++ b/qiboot/src/io.h @@ -0,0 +1,337 @@ +/* + * linux/include/asm-arm/io.h + * + * Copyright (C) 1996-2000 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. + * + * Modifications: + * 16-Sep-1996 RMK Inlined the inx/outx functions & optimised for both + * constant addresses and variable addresses. + * 04-Dec-1997 RMK Moved a lot of this stuff to the new architecture + * specific IO header files. + * 27-Mar-1999 PJB Second parameter of memcpy_toio is const.. + * 04-Apr-1999 PJB Added check_signature. + * 12-Dec-1999 RMK More cleanups + * 18-Jun-2000 RMK Removed virt_to_* and friends definitions + */ +#ifndef __ASM_ARM_IO_H +#define __ASM_ARM_IO_H + +#ifdef __KERNEL__ + +#include +#include +#include +#if 0 /* XXX###XXX */ +#include +#endif /* XXX###XXX */ + +static inline void sync(void) +{ +} + +/* + * Given a physical address and a length, return a virtual address + * that can be used to access the memory range with the caching + * properties specified by "flags". + */ +typedef unsigned long phys_addr_t; + +#define MAP_NOCACHE (0) +#define MAP_WRCOMBINE (0) +#define MAP_WRBACK (0) +#define MAP_WRTHROUGH (0) + +static inline void * +map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) +{ + return (void *)paddr; +} + +/* + * Take down a mapping set up by map_physmem(). + */ +static inline void unmap_physmem(void *vaddr, unsigned long flags) +{ + +} + +/* + * Generic virtual read/write. Note that we don't support half-word + * read/writes. We define __arch_*[bl] here, and leave __arch_*w + * to the architecture specific code. + */ +#define __arch_getb(a) (*(volatile unsigned char *)(a)) +#define __arch_getw(a) (*(volatile unsigned short *)(a)) +#define __arch_getl(a) (*(volatile unsigned int *)(a)) + +#define __arch_putb(v,a) (*(volatile unsigned char *)(a) = (v)) +#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v)) +#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v)) + +extern void __raw_writesb(unsigned int addr, const void *data, int bytelen); +extern void __raw_writesw(unsigned int addr, const void *data, int wordlen); +extern void __raw_writesl(unsigned int addr, const void *data, int longlen); + +extern void __raw_readsb(unsigned int addr, void *data, int bytelen); +extern void __raw_readsw(unsigned int addr, void *data, int wordlen); +extern void __raw_readsl(unsigned int addr, void *data, int longlen); + +#define __raw_writeb(v,a) __arch_putb(v,a) +#define __raw_writew(v,a) __arch_putw(v,a) +#define __raw_writel(v,a) __arch_putl(v,a) + +#define __raw_readb(a) __arch_getb(a) +#define __raw_readw(a) __arch_getw(a) +#define __raw_readl(a) __arch_getl(a) + +#define writeb(v,a) __arch_putb(v,a) +#define writew(v,a) __arch_putw(v,a) +#define writel(v,a) __arch_putl(v,a) + +#define readb(a) __arch_getb(a) +#define readw(a) __arch_getw(a) +#define readl(a) __arch_getl(a) + +/* + * The compiler seems to be incapable of optimising constants + * properly. Spell it out to the compiler in some cases. + * These are only valid for small values of "off" (< 1<<12) + */ +#define __raw_base_writeb(val,base,off) __arch_base_putb(val,base,off) +#define __raw_base_writew(val,base,off) __arch_base_putw(val,base,off) +#define __raw_base_writel(val,base,off) __arch_base_putl(val,base,off) + +#define __raw_base_readb(base,off) __arch_base_getb(base,off) +#define __raw_base_readw(base,off) __arch_base_getw(base,off) +#define __raw_base_readl(base,off) __arch_base_getl(base,off) + +/* + * Now, pick up the machine-defined IO definitions + */ +#if 0 /* XXX###XXX */ +#include +#endif /* XXX###XXX */ + +/* + * IO port access primitives + * ------------------------- + * + * The ARM doesn't have special IO access instructions; all IO is memory + * mapped. Note that these are defined to perform little endian accesses + * only. Their primary purpose is to access PCI and ISA peripherals. + * + * Note that for a big endian machine, this implies that the following + * big endian mode connectivity is in place, as described by numerious + * ARM documents: + * + * PCI: D0-D7 D8-D15 D16-D23 D24-D31 + * ARM: D24-D31 D16-D23 D8-D15 D0-D7 + * + * The machine specific io.h include defines __io to translate an "IO" + * address to a memory address. + * + * Note that we prevent GCC re-ordering or caching values in expressions + * by introducing sequence points into the in*() definitions. Note that + * __raw_* do not guarantee this behaviour. + * + * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space. + */ +#ifdef __io +#define outb(v,p) __raw_writeb(v,__io(p)) +#define outw(v,p) __raw_writew(cpu_to_le16(v),__io(p)) +#define outl(v,p) __raw_writel(cpu_to_le32(v),__io(p)) + +#define inb(p) ({ unsigned int __v = __raw_readb(__io(p)); __v; }) +#define inw(p) ({ unsigned int __v = le16_to_cpu(__raw_readw(__io(p))); __v; }) +#define inl(p) ({ unsigned int __v = le32_to_cpu(__raw_readl(__io(p))); __v; }) + +#define outsb(p,d,l) __raw_writesb(__io(p),d,l) +#define outsw(p,d,l) __raw_writesw(__io(p),d,l) +#define outsl(p,d,l) __raw_writesl(__io(p),d,l) + +#define insb(p,d,l) __raw_readsb(__io(p),d,l) +#define insw(p,d,l) __raw_readsw(__io(p),d,l) +#define insl(p,d,l) __raw_readsl(__io(p),d,l) +#endif + +#define outb_p(val,port) outb((val),(port)) +#define outw_p(val,port) outw((val),(port)) +#define outl_p(val,port) outl((val),(port)) +#define inb_p(port) inb((port)) +#define inw_p(port) inw((port)) +#define inl_p(port) inl((port)) + +#define outsb_p(port,from,len) outsb(port,from,len) +#define outsw_p(port,from,len) outsw(port,from,len) +#define outsl_p(port,from,len) outsl(port,from,len) +#define insb_p(port,to,len) insb(port,to,len) +#define insw_p(port,to,len) insw(port,to,len) +#define insl_p(port,to,len) insl(port,to,len) + +/* + * ioremap and friends. + * + * ioremap takes a PCI memory address, as specified in + * linux/Documentation/IO-mapping.txt. If you want a + * physical address, use __ioremap instead. + */ +extern void * __ioremap(unsigned long offset, size_t size, unsigned long flags); +extern void __iounmap(void *addr); + +/* + * Generic ioremap support. + * + * Define: + * iomem_valid_addr(off,size) + * iomem_to_phys(off) + */ +#ifdef iomem_valid_addr +#define __arch_ioremap(off,sz,nocache) \ + ({ \ + unsigned long _off = (off), _size = (sz); \ + void *_ret = (void *)0; \ + if (iomem_valid_addr(_off, _size)) \ + _ret = __ioremap(iomem_to_phys(_off),_size,0); \ + _ret; \ + }) + +#define __arch_iounmap __iounmap +#endif + +#define ioremap(off,sz) __arch_ioremap((off),(sz),0) +#define ioremap_nocache(off,sz) __arch_ioremap((off),(sz),1) +#define iounmap(_addr) __arch_iounmap(_addr) + +/* + * DMA-consistent mapping functions. These allocate/free a region of + * uncached, unwrite-buffered mapped memory space for use with DMA + * devices. This is the "generic" version. The PCI specific version + * is in pci.h + */ +extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle); +extern void consistent_free(void *vaddr, size_t size, dma_addr_t handle); +extern void consistent_sync(void *vaddr, size_t size, int rw); + +/* + * String version of IO memory access ops: + */ +extern void _memcpy_fromio(void *, unsigned long, size_t); +extern void _memcpy_toio(unsigned long, const void *, size_t); +extern void _memset_io(unsigned long, int, size_t); + +extern void __readwrite_bug(const char *fn); + +/* + * If this architecture has PCI memory IO, then define the read/write + * macros. These should only be used with the cookie passed from + * ioremap. + */ +#ifdef __mem_pci + +#define readb(c) ({ unsigned int __v = __raw_readb(__mem_pci(c)); __v; }) +#define readw(c) ({ unsigned int __v = le16_to_cpu(__raw_readw(__mem_pci(c))); __v; }) +#define readl(c) ({ unsigned int __v = le32_to_cpu(__raw_readl(__mem_pci(c))); __v; }) + +#define writeb(v,c) __raw_writeb(v,__mem_pci(c)) +#define writew(v,c) __raw_writew(cpu_to_le16(v),__mem_pci(c)) +#define writel(v,c) __raw_writel(cpu_to_le32(v),__mem_pci(c)) + +#define memset_io(c,v,l) _memset_io(__mem_pci(c),(v),(l)) +#define memcpy_fromio(a,c,l) _memcpy_fromio((a),__mem_pci(c),(l)) +#define memcpy_toio(c,a,l) _memcpy_toio(__mem_pci(c),(a),(l)) + +#define eth_io_copy_and_sum(s,c,l,b) \ + eth_copy_and_sum((s),__mem_pci(c),(l),(b)) + +static inline int +check_signature(unsigned long io_addr, const unsigned char *signature, + int length) +{ + int retval = 0; + do { + if (readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} + +#elif !defined(readb) + +#define readb(addr) (__readwrite_bug("readb"),0) +#define readw(addr) (__readwrite_bug("readw"),0) +#define readl(addr) (__readwrite_bug("readl"),0) +#define writeb(v,addr) __readwrite_bug("writeb") +#define writew(v,addr) __readwrite_bug("writew") +#define writel(v,addr) __readwrite_bug("writel") + +#define eth_io_copy_and_sum(a,b,c,d) __readwrite_bug("eth_io_copy_and_sum") + +#define check_signature(io,sig,len) (0) + +#endif /* __mem_pci */ + +/* + * If this architecture has ISA IO, then define the isa_read/isa_write + * macros. + */ +#ifdef __mem_isa + +#define isa_readb(addr) __raw_readb(__mem_isa(addr)) +#define isa_readw(addr) __raw_readw(__mem_isa(addr)) +#define isa_readl(addr) __raw_readl(__mem_isa(addr)) +#define isa_writeb(val,addr) __raw_writeb(val,__mem_isa(addr)) +#define isa_writew(val,addr) __raw_writew(val,__mem_isa(addr)) +#define isa_writel(val,addr) __raw_writel(val,__mem_isa(addr)) +#define isa_memset_io(a,b,c) _memset_io(__mem_isa(a),(b),(c)) +#define isa_memcpy_fromio(a,b,c) _memcpy_fromio((a),__mem_isa(b),(c)) +#define isa_memcpy_toio(a,b,c) _memcpy_toio(__mem_isa((a)),(b),(c)) + +#define isa_eth_io_copy_and_sum(a,b,c,d) \ + eth_copy_and_sum((a),__mem_isa(b),(c),(d)) + +static inline int +isa_check_signature(unsigned long io_addr, const unsigned char *signature, + int length) +{ + int retval = 0; + do { + if (isa_readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} + +#else /* __mem_isa */ + +#define isa_readb(addr) (__readwrite_bug("isa_readb"),0) +#define isa_readw(addr) (__readwrite_bug("isa_readw"),0) +#define isa_readl(addr) (__readwrite_bug("isa_readl"),0) +#define isa_writeb(val,addr) __readwrite_bug("isa_writeb") +#define isa_writew(val,addr) __readwrite_bug("isa_writew") +#define isa_writel(val,addr) __readwrite_bug("isa_writel") +#define isa_memset_io(a,b,c) __readwrite_bug("isa_memset_io") +#define isa_memcpy_fromio(a,b,c) __readwrite_bug("isa_memcpy_fromio") +#define isa_memcpy_toio(a,b,c) __readwrite_bug("isa_memcpy_toio") + +#define isa_eth_io_copy_and_sum(a,b,c,d) \ + __readwrite_bug("isa_eth_io_copy_and_sum") + +#define isa_check_signature(io,sig,len) (0) + +#endif /* __mem_isa */ +#endif /* __KERNEL__ */ +#endif /* __ASM_ARM_IO_H */ diff --git a/qiboot/src/mmc.c b/qiboot/src/mmc.c new file mode 100644 index 0000000..39f1720 --- /dev/null +++ b/qiboot/src/mmc.c @@ -0,0 +1,538 @@ +/* + * u-boot S3C2410 MMC/SD card driver + * (C) Copyright 2006 by OpenMoko, Inc. + * Author: Harald Welte + * + * 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 +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_MMC) && defined(CONFIG_MMC_S3C) + +#define CONFIG_MMC_WIDE + +static S3C2410_SDI *sdi; + +static block_dev_desc_t mmc_dev; + +block_dev_desc_t * mmc_get_dev(int dev) +{ + return ((block_dev_desc_t *)&mmc_dev); +} + +/* + * FIXME needs to read cid and csd info to determine block size + * and other parameters + */ +static uchar 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 u_int32_t *mmc_cmd(ushort cmd, ulong arg, ushort flags) +{ + static u_int32_t resp[5]; + + u_int32_t ccon, csta; + u_int32_t 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); + + sdi->SDICSTA = 0xffffffff; + sdi->SDIDSTA = 0xffffffff; + sdi->SDIFSTA = 0xffffffff; + + sdi->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; + + sdi->SDICCON = ccon; + + while (1) { + csta = sdi->SDICSTA; + if (csta & csta_rdy_bit) + break; + if (csta & S3C2410_SDICMDSTAT_CMDTIMEOUT) { + printf("===============> MMC CMD Timeout\n"); + sdi->SDICSTA |= S3C2410_SDICMDSTAT_CMDTIMEOUT; + break; + } + } + + debug("final MMC CMD status 0x%x\n", csta); + + sdi->SDICSTA |= csta_rdy_bit; + + if (flags & CMD_F_RESP) { + resp[0] = sdi->SDIRSP0; + resp[1] = sdi->SDIRSP1; + resp[2] = sdi->SDIRSP2; + resp[3] = sdi->SDIRSP3; + } + + return resp; +} + +#define FIFO_FILL(host) ((host->SDIFSTA & S3C2410_SDIFSTA_COUNTMASK) >> 2) + +static int mmc_block_read(uchar *dst, ulong src, ulong len) +{ + u_int32_t dcon, fifo; + u_int32_t *dst_u32 = (u_int32_t *)dst; + u_int32_t *resp; + + if (len == 0) + return 0; + + debug("mmc_block_rd dst %lx src %lx len %d\n", (ulong)dst, src, len); + + /* set block len */ + resp = mmc_cmd(MMC_CMD_SET_BLOCKLEN, len, CMD_F_RESP); + sdi->SDIBSIZE = len; + + //sdi->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 defined(CONFIG_S3C2440) || defined(CONFIG_S3C2442) + dcon |= S3C2440_SDIDCON_DS_WORD | S3C2440_SDIDCON_DATSTART; +#endif + sdi->SDIDCON = dcon; + + /* send read command */ + resp = mmc_cmd(MMC_CMD_READ_BLOCK, src, CMD_F_RESP); + + while (len > 0) { + u_int32_t sdidsta = sdi->SDIDSTA; + fifo = FIFO_FILL(sdi); + if (sdidsta & (S3C2410_SDIDSTA_FIFOFAIL| + S3C2410_SDIDSTA_CRCFAIL| + S3C2410_SDIDSTA_RXCRCFAIL| + S3C2410_SDIDSTA_DATATIMEOUT)) { + printf("mmc_block_read: err SDIDSTA=0x%08x\n", sdidsta); + return -EIO; + } + + while (fifo--) { + //debug("dst_u32 = 0x%08x\n", dst_u32); + *(dst_u32++) = sdi->SDIDAT; + if (len >= 4) + len -= 4; + else { + len = 0; + break; + } + } + } + + debug("waiting for SDIDSTA (currently 0x%08x\n", sdi->SDIDSTA); + while (!(sdi->SDIDSTA & (1 << 4))) {} + debug("done waiting for SDIDSTA (currently 0x%08x\n", sdi->SDIDSTA); + + sdi->SDIDCON = 0; + + if (!(sdi->SDIDSTA & S3C2410_SDIDSTA_XFERFINISH)) + debug("mmc_block_read; transfer not finished!\n"); + + return 0; +} + +static int mmc_block_write(ulong dst, uchar *src, int len) +{ + printf("MMC block write not yet supported on S3C2410!\n"); + return -1; +} + + +int mmc_read(ulong src, uchar *dst, int size) +{ + ulong end, part_start, part_end, part_len, aligned_start, aligned_end; + ulong mmc_block_size, mmc_block_address; + + if (size == 0) + return 0; + + if (!mmc_ready) { + printf("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, (ulong)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, (ulong)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, (ulong)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, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end); + if ((mmc_block_read((uchar *)(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, (ulong)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, (ulong)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 mmc_write(uchar *src, ulong dst, int size) +{ + ulong end, part_start, part_end, part_len, aligned_start, aligned_end; + ulong mmc_block_size, mmc_block_address; + + if (size == 0) + return 0; + + if (!mmc_ready) { + printf("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, (ulong)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", + (ulong)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, (ulong)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, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end); + if ((mmc_block_write(dst, (uchar *)src, mmc_block_size)) < 0) + return -1; + + } + debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n", + src, (ulong)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, (ulong)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; +} + +ulong mmc_bread(int dev_num, ulong blknr, ulong blkcnt, void *dst) +{ + int mmc_block_size = MMC_BLOCK_SIZE; + ulong src = blknr * mmc_block_size + CFG_MMC_BASE; + + 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; + +static u_int32_t mmc_size(const struct mmc_csd *csd) +{ + u_int32_t 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; +} + +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) +{ + printf("MMC found. Card desciption is:\n"); + printf("Manufacturer ID = %02x%02x%02x\n", + cid->id[0], cid->id[1], cid->id[2]); + printf("HW/FW Revision = %x %x\n",cid->hwrev, cid->fwrev); + cid->hwrev = cid->fwrev = 0; /* null terminate string */ + printf("Product Name = %s\n",cid->name); + printf("Serial Number = %02x%02x%02x\n", + cid->sn[0], cid->sn[1], cid->sn[2]); + printf("Month = %d\n",cid->month); + printf("Year = %d\n",1997 + cid->year); +} + +static void print_sd_cid(const struct sd_cid *cid) +{ + printf("Manufacturer: 0x%02x, OEM \"%c%c\"\n", + cid->mid, cid->oid_0, cid->oid_1); + printf("Product name: \"%c%c%c%c%c\", revision %d.%d\n", + cid->pnm_0, cid->pnm_1, cid->pnm_2, cid->pnm_3, cid->pnm_4, + cid->prv >> 4, cid->prv & 15); + printf("Serial number: %u\n", + cid->psn_0 << 24 | cid->psn_1 << 16 | cid->psn_2 << 8 | + cid->psn_3); + printf("Manufacturing date: %d/%d\n", + cid->mdt_1 & 15, + 2000+((cid->mdt_0 & 15) << 4)+((cid->mdt_1 & 0xf0) >> 4)); + printf("CRC: 0x%02x, b0 = %d\n", + cid->crc >> 1, cid->crc & 1); +} + +int mmc_init(int verbose) +{ + int retries, rc = -ENODEV; + int is_sd = 0; + u_int32_t *resp; + S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER(); + + sdi = S3C2410_GetBase_SDI(); + + debug("mmc_init(PCLK=%u)\n", get_PCLK()); + + clk_power->CLKCON |= (1 << 9); + + sdi->SDIBSIZE = 512; +#if defined(CONFIG_S3C2410) + /* S3C2410 has some bug that prevents reliable operation at higher speed */ + //sdi->SDIPRE = 0x3e; /* SDCLK = PCLK/2 / (SDIPRE+1) = 396kHz */ + sdi->SDIPRE = 0x02; /* 2410: SDCLK = PCLK/2 / (SDIPRE+1) = 11MHz */ + sdi->SDIDTIMER = 0xffff; +#elif defined(CONFIG_S3C2440) || defined(CONFIG_S3C2442) + sdi->SDIPRE = 0x05; /* 2410: SDCLK = PCLK / (SDIPRE+1) = 11MHz */ + sdi->SDIDTIMER = 0x7fffff; +#endif + sdi->SDIIMSK = 0x0; + sdi->SDICON = S3C2410_SDICON_FIFORESET|S3C2410_SDICON_CLOCKTYPE; + udelay(125000); /* FIXME: 74 SDCLK cycles */ + + mmc_csd.c_size = 0; + + /* reset */ + retries = 10; + resp = mmc_cmd(MMC_CMD_RESET, 0, 0); + + printf("trying to detect SD Card...\n"); + while (retries--) { + udelay(100000); + 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) { + retries = 10; + printf("failed to detect SD Card, trying MMC\n"); + resp = mmc_cmd(MMC_CMD_SEND_OP_COND, 0x00ffc000, CMD_F_RESP); + while (retries-- && resp && !(resp[4] & 0x80)) { + debug("resp %x %x\n", resp[0], resp[1]); + udelay(50); + resp = mmc_cmd(1, 0x00ffff00, CMD_F_RESP); + } + } + + /* 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); + 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); + } + else { + struct sd_cid *cid = (struct sd_cid *) resp; + + if (verbose) + print_sd_cid(cid); + 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); + } + + /* fill in device description */ + mmc_dev.if_type = IF_TYPE_MMC; + mmc_dev.part_type = PART_TYPE_DOS; + mmc_dev.dev = 0; + mmc_dev.lun = 0; + mmc_dev.type = 0; + /* FIXME fill in the correct size (is set to 32MByte) */ + mmc_dev.blksz = 512; + mmc_dev.lba = 0x10000; + mmc_dev.removable = 0; + mmc_dev.block_read = mmc_bread; + + /* 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; + /* 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)); + } + } + + 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 + + fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */ + + return rc; +} + +int +mmc_ident(block_dev_desc_t *dev) +{ + return 0; +} + +int +mmc2info(ulong addr) +{ + /* FIXME hard codes to 32 MB device */ + if (addr >= CFG_MMC_BASE && addr < CFG_MMC_BASE + 0x02000000) + return 1; + + return 0; +} + +#endif /* defined(CONFIG_MMC) && defined(CONFIG_MMC_S3C) */ diff --git a/qiboot/src/mmc.h b/qiboot/src/mmc.h new file mode 100644 index 0000000..a271695 --- /dev/null +++ b/qiboot/src/mmc.h @@ -0,0 +1,33 @@ +/* + * (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 _MMC_H_ +#define _MMC_H_ +#include + +int mmc_init(int verbose); +int mmc_read(ulong src, uchar *dst, int size); +int mmc_write(uchar *src, ulong dst, int size); +int mmc2info(ulong addr); + +#endif /* _MMC_H_ */ diff --git a/qiboot/src/part.h b/qiboot/src/part.h new file mode 100644 index 0000000..b22a637 --- /dev/null +++ b/qiboot/src/part.h @@ -0,0 +1,138 @@ +/* + * (C) Copyright 2000-2004 + * 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 _PART_H +#define _PART_H + +#include + +typedef struct block_dev_desc { + int if_type; /* type of the interface */ + int dev; /* device number */ + unsigned char part_type; /* partition type */ + unsigned char target; /* target SCSI ID */ + unsigned char lun; /* target LUN */ + unsigned char type; /* device type */ + unsigned char removable; /* removable device */ +#ifdef CONFIG_LBA48 + unsigned char lba48; /* device can use 48bit addr (ATA/ATAPI v7) */ +#endif + lbaint_t lba; /* number of blocks */ + unsigned long blksz; /* block size */ + char vendor [40+1]; /* IDE model, SCSI Vendor */ + char product[20+1]; /* IDE Serial no, SCSI product */ + char revision[8+1]; /* firmware revision */ + unsigned long (*block_read)(int dev, + unsigned long start, + lbaint_t blkcnt, + void *buffer); + unsigned long (*block_write)(int dev, + unsigned long start, + lbaint_t blkcnt, + const void *buffer); + void *priv; /* driver private struct pointer */ +}block_dev_desc_t; + +/* Interface types: */ +#define IF_TYPE_UNKNOWN 0 +#define IF_TYPE_IDE 1 +#define IF_TYPE_SCSI 2 +#define IF_TYPE_ATAPI 3 +#define IF_TYPE_USB 4 +#define IF_TYPE_DOC 5 +#define IF_TYPE_MMC 6 +#define IF_TYPE_SD 7 +#define IF_TYPE_SATA 8 + +/* Part types */ +#define PART_TYPE_UNKNOWN 0x00 +#define PART_TYPE_MAC 0x01 +#define PART_TYPE_DOS 0x02 +#define PART_TYPE_ISO 0x03 +#define PART_TYPE_AMIGA 0x04 + +/* + * Type string for U-Boot bootable partitions + */ +#define BOOT_PART_TYPE "U-Boot" /* primary boot partition type */ +#define BOOT_PART_COMP "PPCBoot" /* PPCBoot compatibility type */ + +/* device types */ +#define DEV_TYPE_UNKNOWN 0xff /* not connected */ +#define DEV_TYPE_HARDDISK 0x00 /* harddisk */ +#define DEV_TYPE_TAPE 0x01 /* Tape */ +#define DEV_TYPE_CDROM 0x05 /* CD-ROM */ +#define DEV_TYPE_OPDISK 0x07 /* optical disk */ + +typedef struct disk_partition { + ulong start; /* # of first block in partition */ + ulong size; /* number of blocks in partition */ + ulong blksz; /* block size in bytes */ + uchar name[32]; /* partition name */ + uchar type[32]; /* string type description */ +} disk_partition_t; + +/* Misc _get_dev functions */ +block_dev_desc_t* get_dev(char* ifname, int dev); +block_dev_desc_t* ide_get_dev(int dev); +block_dev_desc_t* sata_get_dev(int dev); +block_dev_desc_t* scsi_get_dev(int dev); +block_dev_desc_t* usb_stor_get_dev(int dev); +block_dev_desc_t* mmc_get_dev(int dev); +block_dev_desc_t* systemace_get_dev(int dev); + +/* disk/part.c */ +int get_partition_info (block_dev_desc_t * dev_desc, int part, disk_partition_t *info); +void print_part (block_dev_desc_t *dev_desc); +void init_part (block_dev_desc_t *dev_desc); +void dev_print(block_dev_desc_t *dev_desc); + + +#ifdef CONFIG_MAC_PARTITION +/* disk/part_mac.c */ +int get_partition_info_mac (block_dev_desc_t * dev_desc, int part, disk_partition_t *info); +void print_part_mac (block_dev_desc_t *dev_desc); +int test_part_mac (block_dev_desc_t *dev_desc); +#endif + +#ifdef CONFIG_DOS_PARTITION +/* disk/part_dos.c */ +int get_partition_info_dos (block_dev_desc_t * dev_desc, int part, disk_partition_t *info); +void print_part_dos (block_dev_desc_t *dev_desc); +int test_part_dos (block_dev_desc_t *dev_desc); +#endif + +#ifdef CONFIG_ISO_PARTITION +/* disk/part_iso.c */ +int get_partition_info_iso (block_dev_desc_t * dev_desc, int part, disk_partition_t *info); +void print_part_iso (block_dev_desc_t *dev_desc); +int test_part_iso (block_dev_desc_t *dev_desc); +#endif + +#ifdef CONFIG_AMIGA_PARTITION +/* disk/part_amiga.c */ +int get_partition_info_amiga (block_dev_desc_t * dev_desc, int part, disk_partition_t *info); +void print_part_amiga (block_dev_desc_t *dev_desc); +int test_part_amiga (block_dev_desc_t *dev_desc); +#endif + +#endif /* _PART_H */ From 957929aeafae9962c7625b521f2670c3578d10db Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:35 +0000 Subject: [PATCH 041/248] add-nand-fixed-partition-layout.patch Signed-off-by: Andy Green --- qiboot/include/device_configuration.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/qiboot/include/device_configuration.h b/qiboot/include/device_configuration.h index 69e247c..deb7072 100644 --- a/qiboot/include/device_configuration.h +++ b/qiboot/include/device_configuration.h @@ -1,8 +1,25 @@ /* define the easily changed settings for the device here */ -#define CFG_NAND_OFFSET_FOR_KERNEL_PARTITION 0x80000 #define CFG_LINUX_MACHINE_ID 1304 #define CFG_LINUX_ATAG_ADDRESS 0x30000100 +#define CFG_NAND_OFFSET_FOR_KERNEL_PARTITION 0x80000 +/* + * we follow GTA02 layout actually to make life easier allowing NOR DFU during + * our initial development on GTA02 + */ +#define CFG_LINUX_CMDLINE_BACKUP "mtdparts=neo1973-nand:" \ + "0x00040000(kboot)," \ + "0x00040000(cmdline)," \ + "0x00800000(backupkernel)," \ + "0x000a0000(extra)," \ + "0x00040000(identity)," \ + "0x0f6a0000(backuprootfs) " \ + "rootfstype=jffs2 " \ + "root=/dev/mtdblock5 " \ + "console=ttySAC2,115200 " \ + "loglevel=4 " \ + "init=/sbin/init ro" + #define CFG_LINUX_CMDLINE "rootfstype=ext2 " \ "root=/dev/mmcblk0p1 " \ "console=ttySAC2,115200 " \ From 32cb2fa93c6c6c3f70ee974896f414b85f7f4dac Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:35 +0000 Subject: [PATCH 042/248] change-name.patch Signed-off-by: Andy Green --- qiboot/src/start_kboot.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/qiboot/src/start_kboot.c b/qiboot/src/start_kboot.c index 12806ce..683b2f7 100644 --- a/qiboot/src/start_kboot.c +++ b/qiboot/src/start_kboot.c @@ -157,9 +157,14 @@ void start_kboot(void) port_init(); serial_init(UART2); - puts("Openmoko KBOOT "stringify2(BUILD_HOST)" " + puts("Qi Bootloader "stringify2(BUILD_HOST)" " stringify2(BUILD_VERSION)" " - stringify2(BUILD_DATE)"\n"); + stringify2(BUILD_DATE)); + puts("Copyright (C) 2008 Openmoko, Inc."); + puts("This is free software; see the source for copying conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or\n" + "FITNESS FOR A PARTICULAR PURPOSE.\n"); + /* * We got the first 4KBytes of the bootloader pulled into the * steppingstone SRAM for free. Now we pull the whole bootloader From 8cff2ca83661fb84c58bfbd3d9847331b9f76ebb Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:35 +0000 Subject: [PATCH 043/248] move-kboot.h-to-include.patch Signed-off-by: Andy Green --- qiboot/{src/ctype.h => include/qi-ctype.h} | 0 qiboot/include/qi-serial.h | 112 +++++++++++++++++++++ qiboot/{src/kboot.h => include/qi.h} | 13 ++- qiboot/src/ctype.c | 2 +- qiboot/src/nand_read.c | 2 +- qiboot/src/phase2.c | 6 +- qiboot/src/serial.c | 2 +- qiboot/src/start_kboot.c | 2 +- qiboot/src/utils.c | 2 +- 9 files changed, 127 insertions(+), 14 deletions(-) rename qiboot/{src/ctype.h => include/qi-ctype.h} (100%) create mode 100644 qiboot/include/qi-serial.h rename qiboot/{src/kboot.h => include/qi.h} (85%) diff --git a/qiboot/src/ctype.h b/qiboot/include/qi-ctype.h similarity index 100% rename from qiboot/src/ctype.h rename to qiboot/include/qi-ctype.h diff --git a/qiboot/include/qi-serial.h b/qiboot/include/qi-serial.h new file mode 100644 index 0000000..732fe67 --- /dev/null +++ b/qiboot/include/qi-serial.h @@ -0,0 +1,112 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: xiangfu liu + * + * 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_H__ +#define __SERIAL_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) + + + +// 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 + +void port_init(void); +void serial_init (const int ubrdiv_val,const int uart); +void serial_putc (const int uart,const char c); +int printk(const char *fmt, ...); +int puts(const char *string); + +#endif diff --git a/qiboot/src/kboot.h b/qiboot/include/qi.h similarity index 85% rename from qiboot/src/kboot.h rename to qiboot/include/qi.h index af47a12..92d92ca 100644 --- a/qiboot/src/kboot.h +++ b/qiboot/include/qi.h @@ -18,12 +18,17 @@ * MA 02111-1307 USA */ -#ifndef __KBOOT_H__ -#define __KBOOT_H__ +#ifndef __QI_H__ +#define __QI_H__ #include -#include "serial.h" -#include "ctype.h" +#include +#include + +#define u32 unsigned int +#define u16 unsigned short +#define u8 unsigned char +typedef unsigned int uint32_t; int printk(const char *fmt, ...); int vsprintf(char *buf, const char *fmt, va_list args); diff --git a/qiboot/src/ctype.c b/qiboot/src/ctype.c index ce1d315..cf5a5a6 100644 --- a/qiboot/src/ctype.c +++ b/qiboot/src/ctype.c @@ -1,4 +1,4 @@ -#include "ctype.h" +#include unsigned char _ctype[] = { _C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ diff --git a/qiboot/src/nand_read.c b/qiboot/src/nand_read.c index 16310bb..bdd1b6a 100644 --- a/qiboot/src/nand_read.c +++ b/qiboot/src/nand_read.c @@ -18,8 +18,8 @@ /* NOTE this stuff runs in steppingstone context! */ +#include #include "nand_read.h" -#include "kboot.h" #define NAND_CMD_READ0 0 #define NAND_CMD_READSTART 0x30 diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index ac43822..59a18f0 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -21,16 +21,12 @@ * MA 02111-1307 USA */ -#include "kboot.h" +#include #include #include "blink_led.h" #include #define __ARM__ #include -#define u32 unsigned int -#define u16 unsigned short -#define u8 unsigned char -typedef unsigned int uint32_t; #include #include "nand_read.h" diff --git a/qiboot/src/serial.c b/qiboot/src/serial.c index 5432056..19fb850 100644 --- a/qiboot/src/serial.c +++ b/qiboot/src/serial.c @@ -20,8 +20,8 @@ * MA 02111-1307 USA */ +#include #include "blink_led.h" -#include "kboot.h" void serial_init (const int uart) { diff --git a/qiboot/src/start_kboot.c b/qiboot/src/start_kboot.c index 683b2f7..8b5078c 100644 --- a/qiboot/src/start_kboot.c +++ b/qiboot/src/start_kboot.c @@ -24,9 +24,9 @@ /* NOTE this stuff runs in steppingstone context! */ +#include #include "blink_led.h" #include "nand_read.h" -#include "kboot.h" #include #define stringify2(s) stringify1(s) diff --git a/qiboot/src/utils.c b/qiboot/src/utils.c index c9506c2..55fc3f1 100644 --- a/qiboot/src/utils.c +++ b/qiboot/src/utils.c @@ -20,7 +20,7 @@ * MA 02111-1307 USA */ -#include "kboot.h" +#include #include #define DEBUG_CONSOLE_UART UART2 From 4a8bada67103938110d4e4ab49175c02e36bb71f Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:36 +0000 Subject: [PATCH 044/248] add-per-board-init-change-qi.patch Giant patch: - renames everything from kboot to qi - changes filenames accordingly in several places - fixes the linker script so stuff that does not execute from steppingstone context has real linked addresses in the relocated region, it means all code and pointers work now outside first 4KBytes - adds src/gta02/gta02.c to contain board-specific init and other functions - adds sophisticated structs to define most features in the board-specific files, including board type detection, board revision detection, and multiple kernel source definition (NAND, SD FAT, SD ext2, etc), including auto sequencing of trying the kernel sources in order (filesystems and partition support not done yet) - GTA02 detects itself by NOR presence and reports A5 / A6 - commandlines for kernel also come from board-specific kernel source definitions so correct kernel commandlines are provided depending on boot device -- on GTA02 now boots NAND kernel into NAND jffs2 filesystem - CRC32 is checked on loaded kernel image to make sure we know about corruption in bootloader Signed-off-by: Andy Green --- qiboot/Makefile | 22 +- qiboot/dfu-kboot | 7 - qiboot/dfu-qi | 7 + qiboot/include/device_configuration.h | 32 --- qiboot/include/neo_gta02.h | 4 + qiboot/include/qi-serial.h | 5 +- qiboot/include/qi.h | 47 ++++ qiboot/src/{start_kboot.c => gta02/gta02.c} | 174 +++++++++------ qiboot/src/lowlevel_init.S | 17 +- qiboot/src/mmc.c | 2 + qiboot/src/nand_read.c | 6 +- qiboot/src/phase2.c | 225 ++++++++++++-------- qiboot/src/{kboot-stage1.lds => qi.lds} | 21 +- qiboot/src/serial.c | 89 ++++---- qiboot/src/start.S | 43 +++- qiboot/src/start_qi.c | 108 ++++++++++ qiboot/src/utils.c | 104 ++++++++- 17 files changed, 619 insertions(+), 294 deletions(-) delete mode 100755 qiboot/dfu-kboot create mode 100755 qiboot/dfu-qi delete mode 100644 qiboot/include/device_configuration.h rename qiboot/src/{start_kboot.c => gta02/gta02.c} (64%) rename qiboot/src/{kboot-stage1.lds => qi.lds} (79%) create mode 100644 qiboot/src/start_qi.c diff --git a/qiboot/Makefile b/qiboot/Makefile index 22851f2..794748c 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -22,10 +22,10 @@ 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/kboot-stage1.lds +LDS = src/qi.lds INCLUDE = include IMAGE_DIR = image -CFLAGS = -Wall -Werror -I $(INCLUDE) -g -c -O2 -fno-strict-aliasing \ +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}" \ @@ -34,7 +34,7 @@ LDFLAGS = #START = start.o lowlevel_init.o S_SRCS = src/start.S src/lowlevel_init.S S_OBJS = $(patsubst %.S,%.o, $(S_SRCS)) -C_SRCS = $(wildcard src/*.c) +C_SRCS = $(wildcard src/*.c) $(wildcard src/gt*/*.c) C_OBJS = $(patsubst %.c,%.o, $(C_SRCS)) #SRCS := $(START: .o=.S) $(COBJS: .o=.c) @@ -47,9 +47,9 @@ UDFU_VID = 0x1d50 UDFU_PID = 0x5119 UDFU_REV = 0x350 -TARGET = src/start_kboot_all -IMAGE = $(IMAGE_DIR)/kboot -UDFU_IMAGE = $(IMAGE_DIR)/kboot.udfu +TARGET = image/start_qi_all +IMAGE = $(IMAGE_DIR)/qi +UDFU_IMAGE = $(IMAGE_DIR)/qi.udfu %.o: %.S @$(CC) $(CFLAGS) -o $@ $< @@ -62,11 +62,11 @@ all:${UDFU_IMAGE} ${OBJS}:${SRCS} ${UDFU_IMAGE}:${OBJS} - $(LD) ${LDFLAGS} -T$(LDS) -g $(OBJS) -o ${TARGET} ${LIBS} - $(OBJCOPY) -O binary -S ${TARGET} ${IMAGE} - $(OBJDUMP) -D ${TARGET} >${IMAGE}.dis - $(MKUDFU) -v ${UDFU_VID} -p ${UDFU_PID} -r ${UDFU_REV} \ + @$(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 blink_led:src/led_on.S $(CC) $(CFLAGS) led_on.o led_on.S @@ -74,4 +74,4 @@ blink_led:src/led_on.S $(OBJCOPY) -O binary -S led_on_temp.o $(IMAGE)/led_on clean: - rm -f src/*.o src/*~ include/*~ ${IMAGE}* ${TARGET} ${UDFU_IMAGE} + @rm -f src/*.o src/*~ include/*~ ${IMAGE}* ${TARGET} ${UDFU_IMAGE} diff --git a/qiboot/dfu-kboot b/qiboot/dfu-kboot deleted file mode 100755 index eb54a75..0000000 --- a/qiboot/dfu-kboot +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -../dfu-util/src/dfu-util -a 1 -d 0x1d50:0x5119 -D image/kboot.udfu -if [ $? -eq 1 ] ; then -../dfu-util/src/dfu-util -a 1 -d 0x1d50:0x5120 -D image/kboot.udfu -../dfu-util/src/dfu-util -a 1 -d 0x1d50:0x5119 -D image/kboot.udfu -fi - diff --git a/qiboot/dfu-qi b/qiboot/dfu-qi new file mode 100755 index 0000000..1a4e497 --- /dev/null +++ b/qiboot/dfu-qi @@ -0,0 +1,7 @@ +#!/bin/bash +../dfu-util/src/dfu-util -a 1 -d 0x1d50:0x5119 -D image/qi.udfu +if [ $? -eq 1 ] ; then +../dfu-util/src/dfu-util -a 1 -d 0x1d50:0x5120 -D image/qi.udfu +../dfu-util/src/dfu-util -a 1 -d 0x1d50:0x5119 -D image/qi.udfu +fi + diff --git a/qiboot/include/device_configuration.h b/qiboot/include/device_configuration.h deleted file mode 100644 index deb7072..0000000 --- a/qiboot/include/device_configuration.h +++ /dev/null @@ -1,32 +0,0 @@ -/* define the easily changed settings for the device here */ - -#define CFG_LINUX_MACHINE_ID 1304 -#define CFG_LINUX_ATAG_ADDRESS 0x30000100 -#define CFG_NAND_OFFSET_FOR_KERNEL_PARTITION 0x80000 -/* - * we follow GTA02 layout actually to make life easier allowing NOR DFU during - * our initial development on GTA02 - */ -#define CFG_LINUX_CMDLINE_BACKUP "mtdparts=neo1973-nand:" \ - "0x00040000(kboot)," \ - "0x00040000(cmdline)," \ - "0x00800000(backupkernel)," \ - "0x000a0000(extra)," \ - "0x00040000(identity)," \ - "0x0f6a0000(backuprootfs) " \ - "rootfstype=jffs2 " \ - "root=/dev/mtdblock5 " \ - "console=ttySAC2,115200 " \ - "loglevel=4 " \ - "init=/sbin/init ro" - -#define CFG_LINUX_CMDLINE "rootfstype=ext2 " \ - "root=/dev/mmcblk0p1 " \ - "console=ttySAC2,115200 " \ - "loglevel=8 " \ - "init=/sbin/init ro" -#define CFG_LINUX_BIGGEST_KERNEL (4 * 1024 * 1024) -#define CFG_MACHINE_REVISION 0x350 -#define CFG_MEMORY_REGION_START 0x30000000 -#define CFG_MEMORY_REGION_SIZE (128 * 1024 * 1024) - diff --git a/qiboot/include/neo_gta02.h b/qiboot/include/neo_gta02.h index c126adb..7492630 100644 --- a/qiboot/include/neo_gta02.h +++ b/qiboot/include/neo_gta02.h @@ -22,6 +22,10 @@ #ifndef __CONFIG_H #define __CONFIG_H +#ifndef __ASM_MODE__ +#include +extern const struct board_api board_api_gta02; +#endif #define TEXT_BASE 0x33000000 diff --git a/qiboot/include/qi-serial.h b/qiboot/include/qi-serial.h index 732fe67..d674178 100644 --- a/qiboot/include/qi-serial.h +++ b/qiboot/include/qi-serial.h @@ -103,9 +103,8 @@ #define rGPJDAT (*(volatile unsigned *)0x560000d4) //Port J data #define rGPJUP (*(volatile unsigned *)0x560000d8) //Port J data -void port_init(void); -void serial_init (const int ubrdiv_val,const int uart); -void serial_putc (const int uart,const char c); +void serial_init(const int uart, const int ubrdiv_val); +void serial_putc(const int uart, const char c); int printk(const char *fmt, ...); int puts(const char *string); diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index 92d92ca..cc27c0c 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -30,6 +30,51 @@ #define u8 unsigned char typedef unsigned int uint32_t; +enum filesystem { + FS_RAW, + FS_FAT, + FS_EXT2 +}; + +/* describes a source for getting kernel image */ + +struct kernel_source { + const char *name; /* NULL name means invalid */ + int (*block_init)(void); + int (*block_read)(unsigned char * buf, unsigned long byte_start, + int count_bytes); + int partition_index; /* -1 means no partition table */ + int offset_if_no_partition; /* used if partition_index is -1 */ + enum filesystem filesystem; + const char * commandline; +}; + +/* 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 debug_serial_port; + int linux_machine_id; + unsigned long linux_mem_start; + unsigned long linux_mem_size; + unsigned long linux_tag_placement; + const struct board_variant const * (*get_board_variant)(void); + int (*is_this_board)(void); + void (*port_init)(void); + struct kernel_source kernel_source[8]; +}; + +/* this is the board we are running on */ + +extern struct board_api const * this_board; + int printk(const char *fmt, ...); int vsprintf(char *buf, const char *fmt, va_list args); int puts(const char *string); @@ -37,6 +82,8 @@ void printhex(unsigned char v); void print32(unsigned int u); void hexdump(unsigned char *start, int len); unsigned int _ntohl(unsigned int n); +unsigned long crc32(unsigned long crc, const unsigned char *buf, + unsigned int len); #endif diff --git a/qiboot/src/start_kboot.c b/qiboot/src/gta02/gta02.c similarity index 64% rename from qiboot/src/start_kboot.c rename to qiboot/src/gta02/gta02.c index 8b5078c..066ed23 100644 --- a/qiboot/src/start_kboot.c +++ b/qiboot/src/gta02/gta02.c @@ -1,40 +1,19 @@ -/* - * (C) Copyright 2007 OpenMoko, Inc. - * Author: xiangfu liu - * Andy Green - * - * 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 -#include "blink_led.h" -#include "nand_read.h" #include +#include "nand_read.h" -#define stringify2(s) stringify1(s) -#define stringify1(s) #s +static const struct board_variant board_variants[] = { + [0] = { + .name = "A5 PCB", + .machine_revision = 0x350, + }, + [1] = { + .name = "A6 PCB", + .machine_revision = 0x360, + } +}; -extern void bootloader_second_phase(void); - -void port_init(void) +void port_init_gta02(void) { //CAUTION:Follow the configuration order for setting the ports. // 1) setting value(GPnDAT) @@ -121,7 +100,7 @@ void port_init(void) /* * === PORT H GROUP * Ports : GPH10 GPH9 GPH8 GPH7 GPH6 GPH5 GPH4 GPH3 GPH2 GPH1 GPH0 - * Signal : CLKOUT1 CLKOUT0 UCLK nCTS1 nRTS1 RXD1 TXD1 RXD0 TXD0 nRTS0 nCTS0 + * Signal : CLKOUT1 CLKOUT0 UCLK RXD2 TXD2 RXD1 TXD1 RXD0 TXD0 nRTS0 nCTS0 * Binary : 10 , 10 10 , 11 11 , 10 10 , 10 10 , 10 10 */ /* pulldown on GPH08: UEXTCLK, just floats! @@ -145,42 +124,113 @@ void port_init(void) */ rGPJDAT |= (1 << 5); /* Set GPJ5 to high 3D RST */ + + serial_init(UART2, 0x11); } +/** + * returns PCB revision information in b9,b8 and b2,b1,b0 + * Pre-GTA02 A6 returns 0x000 + * GTA02 A6 returns 0x001 + */ - -void start_kboot(void) +int gta02_get_pcb_revision(void) { - void (*phase2)(void) = (void (*)(void))((int)bootloader_second_phase + - TEXT_BASE); + int n; + u32 u; - port_init(); - serial_init(UART2); + /* 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)); - puts("Qi Bootloader "stringify2(BUILD_HOST)" " - stringify2(BUILD_VERSION)" " - stringify2(BUILD_DATE)); - puts("Copyright (C) 2008 Openmoko, Inc."); - puts("This is free software; see the source for copying conditions.\n" - "There is NO warranty; not even for MERCHANTABILITY or\n" - "FITNESS FOR A PARTICULAR PURPOSE.\n"); + /* 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 << (8 - 3)) & 0x100; + n |= (u << (9 - 4)) & 0x200; /* - * We got the first 4KBytes of the bootloader pulled into the - * steppingstone SRAM for free. Now we pull the whole bootloader - * image into SDRAM. - * - * So this doesn't trash position-dependent code, we took care in the - * linker script to arrange all rodata* segment content to be in the - * first 4K region. + * 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); - /* We randomly pull 24KBytes of bootloader */ - if (nand_read_ll((unsigned char *)TEXT_BASE, 0, 24 * 1024) < 0) - while(1) - blink_led(); - /* - * jump to bootloader_second_phase() running from DRAM copy - */ - (phase2)(); + return n; } + + + +/* 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) +{ + return &board_variants[gta02_get_pcb_revision()]; +} + +/* + * our API for bootloader on this machine + */ + +const struct board_api board_api_gta02 = { + .name = "Freerunner / GTA02", + .debug_serial_port = 2, + .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, + /* these are the ways we could boot GTA02 in order to try */ + .kernel_source = { + [0] = { + .name = "NAND Kernel", + .block_read = nand_read_ll, + .partition_index = -1, + .offset_if_no_partition = 0x80000, + .filesystem = FS_RAW, + .commandline = "mtdparts=physmap-flash:-(nor);" \ + "neo1973-nand:" \ + "0x00040000(qi)," \ + "0x00040000(cmdline)," \ + "0x00800000(backupkernel)," \ + "0x000a0000(extra)," \ + "0x00040000(identity)," \ + "0x0f6a0000(backuprootfs) " \ + "rootfstype=jffs2 " \ + "root=/dev/mtdblock6 " \ + "console=ttySAC2,115200 " \ + "loglevel=4 " \ + "init=/sbin/init "\ + "ro" + }, + }, +}; diff --git a/qiboot/src/lowlevel_init.S b/qiboot/src/lowlevel_init.S index 4f20d5e..2a1654c 100644 --- a/qiboot/src/lowlevel_init.S +++ b/qiboot/src/lowlevel_init.S @@ -26,6 +26,7 @@ * #include * #include */ +#define __ASM_MODE__ #include /* @@ -125,10 +126,8 @@ .globl lowlevel_init lowlevel_init: - /* memory control configuration */ - /* make r0 relative the current location so that it */ - /* reads SMRDATA out of FLASH rather than memory ! */ - adr r0, SMRDATA + + ldr r0, =SMRDATA ldr r1, =BWSCON /* Bus Width Status Controller */ add r2, r0, #13*4 0: @@ -142,21 +141,11 @@ lowlevel_init: orr r1, r1, #0xc0000000 mcr p15, 0, r1, c1, c0, 0 - /* 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] /* 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)) diff --git a/qiboot/src/mmc.c b/qiboot/src/mmc.c index 39f1720..b982657 100644 --- a/qiboot/src/mmc.c +++ b/qiboot/src/mmc.c @@ -1,3 +1,4 @@ +#if 0 /* * u-boot S3C2410 MMC/SD card driver * (C) Copyright 2006 by OpenMoko, Inc. @@ -536,3 +537,4 @@ mmc2info(ulong addr) } #endif /* defined(CONFIG_MMC) && defined(CONFIG_MMC_S3C) */ +#endif diff --git a/qiboot/src/nand_read.c b/qiboot/src/nand_read.c index bdd1b6a..6351173 100644 --- a/qiboot/src/nand_read.c +++ b/qiboot/src/nand_read.c @@ -89,8 +89,10 @@ static int nand_read_page_ll(unsigned char *buf, unsigned long addr) { unsigned short *ptr16 = (unsigned short *)buf; unsigned int i, page_num; +#if 0 unsigned char ecc[64]; unsigned short *p16 = (unsigned short *)ecc; +#endif nand_clear_RnB(); @@ -108,11 +110,11 @@ static int nand_read_page_ll(unsigned char *buf, unsigned long addr) for (i = 0; i < NAND_PAGE_SIZE/2; i++) *ptr16++ = NFDATA16; - +#if 0 for (i = 0; i < 64 / 2; i++) { *p16++ = NFDATA16; } - +#endif return NAND_PAGE_SIZE; } diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 59a18f0..826e90e 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -31,111 +31,156 @@ #include #include "nand_read.h" -#include - -#define C1_DC (1<<2) /* dcache off/on */ -#define C1_IC (1<<12) /* icache off/on */ void bootloader_second_phase(void) { - image_header_t *hdr; - unsigned long i = 0; void (*the_kernel)(int zero, int arch, uint params); - struct tag * params_base = (struct tag *)CFG_LINUX_ATAG_ADDRESS; - struct tag *params = params_base; - const char * cmdline = CFG_LINUX_CMDLINE; - const char *p = cmdline; - void * kernel_nand = (void *)(TEXT_BASE - CFG_LINUX_BIGGEST_KERNEL); + int kernel = 0; + const struct board_variant * board_variant = + (this_board->get_board_variant)(); - puts("Checking kernel... "); + /* we try the possible kernels for this board in order */ - if (nand_read_ll(kernel_nand, CFG_NAND_OFFSET_FOR_KERNEL_PARTITION, - 4096) < 0) { - puts ("Kernel header read failed\n"); - goto unhappy; - } + while (this_board->kernel_source[kernel].name) { + const char * cmdline = this_board->kernel_source[kernel].commandline; + const char *p = cmdline; + struct tag *params = (struct tag *)this_board->linux_tag_placement; + void * kernel_dram = (void *)(TEXT_BASE - (8 * 1024 * 1024)); + unsigned long crc; + image_header_t *hdr; - hdr = (image_header_t *)kernel_nand; + /* eat leading white space */ + for (p = cmdline; *p == ' '; p++); - if (_ntohl(hdr->ih_magic) != IH_MAGIC) { - puts("Unknown image magic "); - print32(hdr->ih_magic); - goto unhappy; - } + puts("\nTrying kernel: "); + puts(this_board->kernel_source[kernel].name); + puts("\n"); - puts((const char *)hdr->ih_name); + /* if this device needs initializing, try to init it */ + if (this_board->kernel_source[kernel].block_init) + if ((this_board->kernel_source[kernel].block_init)()) { + puts("block device init failed\n"); + kernel++; + continue; + } - puts("Fetching kernel..."); + /* if there's a partition table implied, parse it, otherwise + * just use a fixed offset + */ + if (this_board->kernel_source[kernel].partition_index != -1) { - if (nand_read_ll(kernel_nand, CFG_NAND_OFFSET_FOR_KERNEL_PARTITION, - ((32 * 1024) + (_ntohl(hdr->ih_size) + sizeof(hdr) + 2048)) & + puts("partitions not supported yet\n"); + kernel++; + continue; + + } else { + if (this_board->kernel_source[kernel].block_read( + kernel_dram, this_board->kernel_source[kernel]. + offset_if_no_partition, 4096) < 0) { + puts ("Bad kernel header\n"); + kernel++; + continue; + } + + hdr = (image_header_t *)kernel_dram; + + if (_ntohl(hdr->ih_magic) != IH_MAGIC) { + puts("bad magic "); + print32(hdr->ih_magic); + kernel++; + continue; + } + + puts(" Found: "); + puts((const char *)hdr->ih_name); + puts("\n Size: 0x"); + print32(_ntohl(hdr->ih_size)); + + if (nand_read_ll(kernel_dram, + this_board->kernel_source[kernel]. + offset_if_no_partition, (_ntohl(hdr->ih_size) + + sizeof(image_header_t) + 2048) & ~(2048 - 1)) < 0) { - puts ("Kernel body read failed\n"); - goto unhappy; + puts ("Bad kernel read\n"); + kernel++; + continue; + } + } + + puts("\n Cmdline: "); + puts(p); + puts("\n"); + + /* + * It's good for now to know that our kernel is intact from + * the storage before we jump into it and maybe crash silently + * even though it costs us some time + */ + crc = crc32(0, kernel_dram + sizeof(image_header_t), + _ntohl(hdr->ih_size)); + if (crc != _ntohl(hdr->ih_dcrc)) { + puts("\nKernel CRC ERROR: read 0x"); + print32(crc); + puts(" vs hdr CRC 0x"); + print32(_ntohl(hdr->ih_dcrc)); + puts("\n"); + kernel++; + continue; + } + + the_kernel = (void (*)(int, int, uint)) + (((char *)hdr) + sizeof(image_header_t)); + + /* first tag */ + params->hdr.tag = ATAG_CORE; + params->hdr.size = tag_size (tag_core); + params->u.core.flags = 0; + params->u.core.pagesize = 0; + params->u.core.rootdev = 0; + params = tag_next(params); + + /* revision tag */ + params->hdr.tag = ATAG_REVISION; + params->hdr.size = tag_size (tag_revision); + params->u.revision.rev = board_variant->machine_revision; + params = tag_next(params); + + /* memory tags */ + params->hdr.tag = ATAG_MEM; + params->hdr.size = tag_size (tag_mem32); + params->u.mem.start = this_board->linux_mem_start; + params->u.mem.size = this_board->linux_mem_size; + params = tag_next(params); + + /* kernel commandline */ + + if (*p) { + params->hdr.tag = ATAG_CMDLINE; + params->hdr.size = (sizeof (struct tag_header) + + strlen (p) + 1 + 4) >> 2; + strcpy (params->u.cmdline.cmdline, p); + params = tag_next (params); + } + + /* needs to always be the last tag */ + params->hdr.tag = ATAG_NONE; + params->hdr.size = 0; + + puts ("Starting --->\n\n"); + + /* + * ooh that's it, we're gonna try boot this image! + * never mind the cache, Linux will take care of it + */ + the_kernel(0, this_board->linux_machine_id, + this_board->linux_tag_placement); + + /* we won't come back here no matter what */ } - puts(" Done"); + /* none of the kernels worked out */ - the_kernel = (void (*)(int, int, uint)) - (((char *)hdr) + sizeof(image_header_t)); - - /* first tag */ - params->hdr.tag = ATAG_CORE; - params->hdr.size = tag_size (tag_core); - params->u.core.flags = 0; - params->u.core.pagesize = 0; - params->u.core.rootdev = 0; - params = tag_next (params); - - /* revision tag */ - params->hdr.tag = ATAG_REVISION; - params->hdr.size = tag_size (tag_revision); - params->u.revision.rev = CFG_MACHINE_REVISION; - params = tag_next (params); - - /* memory tags */ - params->hdr.tag = ATAG_MEM; - params->hdr.size = tag_size (tag_mem32); - params->u.mem.start = CFG_MEMORY_REGION_START; - params->u.mem.size = CFG_MEMORY_REGION_SIZE; - params = tag_next (params); - - /* kernel commandline */ - /* eat leading white space */ - for (p = cmdline; *p == ' '; p++); - - if (*p) { - params->hdr.tag = ATAG_CMDLINE; - params->hdr.size = - (sizeof (struct tag_header) + strlen (p) + 1 + 4) >> 2; - strcpy (params->u.cmdline.cmdline, p); - params = tag_next (params); - } - - /* needs to always be the last tag */ - params->hdr.tag = ATAG_NONE; - params->hdr.size = 0; - - puts ("Running Linux --->\n\n"); - - /* trash the cache */ - - /* turn off I/D-cache */ - asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - i &= ~(C1_DC | C1_IC); - asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); - - /* flush I/D-cache */ - i = 0; - asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); - - /* ooh that's it, we're gonna try boot this image! */ - - the_kernel(0, CFG_LINUX_MACHINE_ID, (unsigned int)params_base); - - /* that didn't quite pan out */ - -unhappy: + puts("No usable kernel image found, we've had it :-(\n"); while (1) blue_on(1); } diff --git a/qiboot/src/kboot-stage1.lds b/qiboot/src/qi.lds similarity index 79% rename from qiboot/src/kboot-stage1.lds rename to qiboot/src/qi.lds index 5c8d50c..29ec63f 100644 --- a/qiboot/src/kboot-stage1.lds +++ b/qiboot/src/qi.lds @@ -37,24 +37,19 @@ SECTIONS . = ALIGN(4); .text : { - src/start.o (.text .rodata* .data) - src/lowlevel_init.o(.text .rodata* .data) - src/start_kboot.o (.text .rodata* .data) - src/serial.o (.text .rodata* .data) + src/start.o (.text .rodata* .data) + src/lowlevel_init.o (.text .rodata* .data) + src/start_qi.o (.text .rodata* .data) src/blink_led.o (.text .rodata* .data) - * (.rodata* .data) + src/nand_read.o (.text .rodata* .data) + src/serial.o (.text .rodata* .data) } . = ALIGN(4); - .everything_else : { *(.text) } + .everything_else ADDR (.text) + SIZEOF (.text) + 0x33000000 : + AT ( ADDR (.text) + SIZEOF (.text) ) { *(.text .rodata* .data) } - . = ALIGN(4); - .got : - { - *(.got) - } - - . = 0x32000000 ; + . = 0x33800000 ; __bss_start = .; .bss (NOLOAD) : { diff --git a/qiboot/src/serial.c b/qiboot/src/serial.c index 19fb850..61b4762 100644 --- a/qiboot/src/serial.c +++ b/qiboot/src/serial.c @@ -23,55 +23,54 @@ #include #include "blink_led.h" -void serial_init (const int uart) +void serial_init (const int uart, const int ubrdiv_val) { - int ubrdiv_val = 0x11; - switch(uart) - { - case UART0: - rULCON0 = 0x3; - rUCON0 = 0x245; - rUFCON0 = 0x0; - rUMCON0 = 0x0; - rUBRDIV0 = ubrdiv_val; - break; - case UART1: - rULCON1 = 0x3; - rUCON1 = 0x245; - rUFCON1 = 0x0; - rUMCON1 = 0x0; - rUBRDIV1 = ubrdiv_val; - break; - case UART2: - rULCON2 = 0x3; - rUCON2 = 0x245; - rUFCON2 = 0x1; - rUBRDIV2 = ubrdiv_val; - break; - default: - break; - } + switch(uart) + { + case UART0: + rULCON0 = 0x3; + rUCON0 = 0x245; + rUFCON0 = 0x0; + rUMCON0 = 0x0; + rUBRDIV0 = ubrdiv_val; + break; + case UART1: + rULCON1 = 0x3; + rUCON1 = 0x245; + rUFCON1 = 0x0; + rUMCON1 = 0x0; + rUBRDIV1 = ubrdiv_val; + break; + case UART2: + rULCON2 = 0x3; + rUCON2 = 0x245; + rUFCON2 = 0x1; + rUBRDIV2 = ubrdiv_val; + break; + default: + break; + } } /* * Output a single byte to the serial port. */ -void serial_putc (const int uart,const char c) +void serial_putc (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; - } + 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; + } } diff --git a/qiboot/src/start.S b/qiboot/src/start.S index 1d2ee92..3a98bef 100644 --- a/qiboot/src/start.S +++ b/qiboot/src/start.S @@ -18,6 +18,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ + +#define __ASM_MODE__ #include .globl _start @@ -119,11 +121,39 @@ start_code: ldr r1, =0x7fff0 /* all clocks on */ str r1, [r0] - /* gpio UART0 init */ + /* gpio UART2 init, H port */ ldr r0, =0x56000070 - ldr r1, =0x2afaaa + 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] + bl cpu_init_crit /* reset nand controller, or it is dead to us */ @@ -140,11 +170,12 @@ start_code: /* >> 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 */ - +#if 0 clear_bss: ldr r0, _bss_start /* find start of bss segment */ ldr r1, _bss_end /* stop here */ @@ -155,13 +186,14 @@ clbss_l: add r0, r0, #4 cmp r0, r1 ble clbss_l +#endif /* we are going to jump into the C part of the init now */ - +spin: ldr pc, _start_armboot _start_armboot: - .word start_kboot + .word start_qi /* ************************************************************************* @@ -175,6 +207,7 @@ _start_armboot: */ cpu_init_crit: + /* * flush v4 I/D caches */ diff --git a/qiboot/src/start_qi.c b/qiboot/src/start_qi.c new file mode 100644 index 0000000..f0cdeaf --- /dev/null +++ b/qiboot/src/start_qi.c @@ -0,0 +1,108 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: xiangfu liu + * Andy Green + * + * 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 +#include "blink_led.h" +#include "nand_read.h" +#include + +#define stringify2(s) stringify1(s) +#define stringify1(s) #s + +extern void bootloader_second_phase(void); + +const struct board_api * boards[] = { + &board_api_gta02 +}; + +struct board_api const * this_board; + +void start_qi(void) +{ + int n = 0; + int board = 0; + const struct board_variant * board_variant; + /* + * We got the first 4KBytes of the bootloader pulled into the + * steppingstone SRAM for free. Now we pull the whole bootloader + * image into SDRAM. + * + * So this doesn't trash position-dependent code, we took care in the + * linker script to arrange all rodata* segment content to be in the + * first 4K region. + */ + + /* We randomly pull 24KBytes of bootloader */ + if (nand_read_ll((unsigned char *)TEXT_BASE, 0, 24 * 1024) < 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 (!n) { + if (board >= (sizeof(boards) / sizeof(boards[0]))) + /* can't put diagnostic on serial... too early */ + goto unhappy; + + if (this_board->is_this_board()) + n = 1; + else + this_board = boards[board++]; + } + + /* okay, do the critical port and serial init for our board */ + + this_board->port_init(); + + /* stick some hello messages on debug console */ + + puts("\n\n\nQi Bootloader "stringify2(BUILD_HOST)" " + stringify2(BUILD_VERSION)" " + stringify2(BUILD_DATE)"\n"); + + puts("Copyright (C) 2008 Openmoko, Inc.\n"); + puts("This is free software; see the source for copying conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or " + "FITNESS FOR A PARTICULAR PURPOSE.\n\n Detected: "); + + puts(this_board->name); + puts(", "); + board_variant = (this_board->get_board_variant)(); + puts(board_variant->name); + puts("\n"); + + /* + * jump to bootloader_second_phase() running from DRAM copy + */ + bootloader_second_phase(); + +unhappy: + while(1) + blink_led(); + +} diff --git a/qiboot/src/utils.c b/qiboot/src/utils.c index 55fc3f1..45605af 100644 --- a/qiboot/src/utils.c +++ b/qiboot/src/utils.c @@ -23,8 +23,6 @@ #include #include -#define DEBUG_CONSOLE_UART UART2 - size_t strlen(const char *s) { size_t n = 0; @@ -41,6 +39,7 @@ char *strcpy(char *dest, const char *src) while (*src) *dest++ = *src++; + *dest = '\0'; return dest_orig; } @@ -53,8 +52,7 @@ unsigned int _ntohl(unsigned int n) { int puts(const char *string) { while (*string) - serial_putc(DEBUG_CONSOLE_UART, *string++); - serial_putc(DEBUG_CONSOLE_UART, '\n'); + serial_putc(this_board->debug_serial_port, *string++); return 1; } @@ -63,9 +61,9 @@ int puts(const char *string) void printnybble(unsigned char n) { if (n < 10) - serial_putc(DEBUG_CONSOLE_UART, '0' + n); + serial_putc(this_board->debug_serial_port, '0' + n); else - serial_putc(DEBUG_CONSOLE_UART, 'a' + n - 10); + serial_putc(this_board->debug_serial_port, 'a' + n - 10); } void printhex(unsigned char n) @@ -88,14 +86,100 @@ void hexdump(unsigned char *start, int len) while (len > 0) { print32((int)start); - serial_putc(DEBUG_CONSOLE_UART, ':'); - serial_putc(DEBUG_CONSOLE_UART, ' '); + serial_putc(this_board->debug_serial_port, ':'); + serial_putc(this_board->debug_serial_port, ' '); for (n = 0; n < 16; n++) { printhex(*start++); - serial_putc(DEBUG_CONSOLE_UART, ' '); + serial_putc(this_board->debug_serial_port, ' '); } - serial_putc(DEBUG_CONSOLE_UART, '\n'); + serial_putc(this_board->debug_serial_port, '\n'); len -= 16; } } +/* original copyright notice for this crc code (it is from U-Boot) --> */ +/* + * This file is derived from crc32.c from the zlib-1.1.3 distribution + * by Jean-loup Gailly and Mark Adler. + */ + +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +const unsigned long crc_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; + +#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); + +unsigned long crc32(unsigned long crc, const unsigned char *buf, + unsigned int len) +{ + crc = crc ^ 0xffffffffL; + while (len >= 8) { + DO8(buf); + len -= 8; + } + if (len) + do { + DO1(buf); + } while (--len); + + return crc ^ 0xffffffffL; +} From a8baab94b4bbb38a8d6dd5a09903caa660d75428 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:36 +0000 Subject: [PATCH 045/248] add-nand-read-prototype.patch Signed-off-by: Andy Green --- qiboot/include/qi.h | 1 + qiboot/src/gta02/gta02.c | 1 - qiboot/src/utils.c | 5 +++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index cc27c0c..16227a4 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -84,6 +84,7 @@ void hexdump(unsigned char *start, int len); unsigned int _ntohl(unsigned int n); unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned int len); +int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size); #endif diff --git a/qiboot/src/gta02/gta02.c b/qiboot/src/gta02/gta02.c index 066ed23..7566a9c 100644 --- a/qiboot/src/gta02/gta02.c +++ b/qiboot/src/gta02/gta02.c @@ -1,6 +1,5 @@ #include #include -#include "nand_read.h" static const struct board_variant board_variants[] = { [0] = { diff --git a/qiboot/src/utils.c b/qiboot/src/utils.c index 45605af..ccc14b4 100644 --- a/qiboot/src/utils.c +++ b/qiboot/src/utils.c @@ -23,6 +23,11 @@ #include #include +int raise(int n) +{ + return 0; +} + size_t strlen(const char *s) { size_t n = 0; From 2547be573888a8a334a9dac37abc5cae137d3c6c Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:36 +0000 Subject: [PATCH 046/248] change-drivers-dir.patch Create ./src/drivers and move s3c24xx mmc thing in there with more specific name. Move fat.h into ./include Signed-off-by: Andy Green --- qiboot/Makefile | 2 +- qiboot/{src => include}/fat.h | 0 qiboot/src/{mmc.c => drivers/s3c24xx-mci.c} | 0 qiboot/src/{mmc.h => drivers/s3c24xx-mci.h} | 0 4 files changed, 1 insertion(+), 1 deletion(-) rename qiboot/{src => include}/fat.h (100%) rename qiboot/src/{mmc.c => drivers/s3c24xx-mci.c} (100%) rename qiboot/src/{mmc.h => drivers/s3c24xx-mci.h} (100%) diff --git a/qiboot/Makefile b/qiboot/Makefile index 794748c..1a620f9 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -34,7 +34,7 @@ LDFLAGS = #START = start.o lowlevel_init.o S_SRCS = src/start.S src/lowlevel_init.S S_OBJS = $(patsubst %.S,%.o, $(S_SRCS)) -C_SRCS = $(wildcard src/*.c) $(wildcard src/gt*/*.c) +C_SRCS = $(wildcard src/*.c) $(wildcard src/gt*/*.c) $(wildcard src/drivers/*.c) C_OBJS = $(patsubst %.c,%.o, $(C_SRCS)) #SRCS := $(START: .o=.S) $(COBJS: .o=.c) diff --git a/qiboot/src/fat.h b/qiboot/include/fat.h similarity index 100% rename from qiboot/src/fat.h rename to qiboot/include/fat.h diff --git a/qiboot/src/mmc.c b/qiboot/src/drivers/s3c24xx-mci.c similarity index 100% rename from qiboot/src/mmc.c rename to qiboot/src/drivers/s3c24xx-mci.c diff --git a/qiboot/src/mmc.h b/qiboot/src/drivers/s3c24xx-mci.h similarity index 100% rename from qiboot/src/mmc.h rename to qiboot/src/drivers/s3c24xx-mci.h From 20144f6c956e7299f4dd6cc88b0911e65c9fa627 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:36 +0000 Subject: [PATCH 047/248] add-glamo-mmc-files.patch Signed-off-by: Andy Green --- qiboot/src/drivers/glamo-mmc.c | 828 ++++++++++++++++++++++++++++++++ qiboot/src/drivers/glamo-mmc.h | 149 ++++++ qiboot/src/drivers/glamo-regs.h | 628 ++++++++++++++++++++++++ 3 files changed, 1605 insertions(+) create mode 100644 qiboot/src/drivers/glamo-mmc.c create mode 100644 qiboot/src/drivers/glamo-mmc.h create mode 100644 qiboot/src/drivers/glamo-regs.h diff --git a/qiboot/src/drivers/glamo-mmc.c b/qiboot/src/drivers/glamo-mmc.c new file mode 100644 index 0000000..b010235 --- /dev/null +++ b/qiboot/src/drivers/glamo-mmc.c @@ -0,0 +1,828 @@ +/* + * linux/drivers/mmc/host/glamo-mmc.c - Glamo MMC driver + * + * Copyright (C) 2007 OpenMoko, Inc, Andy Green + * Based on the Glamo MCI driver that was --> + * + * Copyright (C) 2007 OpenMoko, Inc, Andy Green + * Based on S3C MMC driver that was: + * Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel + * + * and + * + * Based on S3C MMC driver that was (original copyright notice ---->) + * + * (C) Copyright 2006 by OpenMoko, Inc. + * Author: Harald Welte + * + * based on u-boot pxa MMC driver and linux/drivers/mmc/s3c2410mci.c + * (C) 2005-2005 Thomas Kleffel + * + * Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel + * + * 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. + */ + +#if 0 + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "glamo-regs.h" +#include "glamo-mmc.h" + +#define MMC_BLOCK_SIZE_BITS 9 +#define MMC_BLOCK_SIZE (1 << MMC_BLOCK_SIZE_BITS) + +#define GLAMO_REG(x) (*(volatile u16 *)(CONFIG_GLAMO_BASE + x)) +#define GLAMO_INTRAM_OFFSET (8 * 1024 * 1024) +#define GLAMO_FB_SIZE ((8 * 1024 * 1024) - 0x10000) +#define GLAMO_START_OF_MMC_INTMEM ((volatile u16 *)(CONFIG_GLAMO_BASE + \ + GLAMO_INTRAM_OFFSET + GLAMO_FB_SIZE)) + +static int ccnt; +static block_dev_desc_t mmc_dev; +static mmc_csd_t mmc_csd; +static int mmc_ready = 0; +static int wide = 0; +static enum card_type card_type = CARDTYPE_NONE; + +block_dev_desc_t * mmc_get_dev(int dev) +{ + return (block_dev_desc_t *)&mmc_dev; +} + +static void +glamo_reg_write(u_int16_t val, u_int16_t reg) +{ + GLAMO_REG(reg) = val; +} + +static u_int16_t +glamo_reg_read(u_int16_t reg) +{ + return GLAMO_REG(reg); +} + +unsigned char CRC7(u8 * pu8, int cnt) +{ + u8 crc = 0; + + while (cnt--) { + int n; + u8 d = *pu8++; + for (n = 0; n < 8; n++) { + crc <<= 1; + if ((d & 0x80) ^ (crc & 0x80)) + crc ^= 0x09; + d <<= 1; + } + } + return (crc << 1) | 1; +} + +ulong mmc_bread(int dev_num, ulong blknr, ulong blkcnt, void *dst) +{ + ulong src = blknr * MMC_BLOCK_SIZE; + + if (!blkcnt) + return 0; + +/* printf("mmc_bread(%d, %ld, %ld, %p)\n", dev_num, blknr, blkcnt, dst); */ + 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; + +static void do_pio_read(u16 *buf, int count_words) +{ + volatile u16 *from_ptr = GLAMO_START_OF_MMC_INTMEM; + + while (count_words--) + *buf++ = *from_ptr++; +} + +static void do_pio_write(u16 *buf, int count_words) +{ + volatile u16 *to_ptr = GLAMO_START_OF_MMC_INTMEM; + + while (count_words--) + *to_ptr++ = *buf++; +} + + +static int mmc_cmd(int opcode, int arg, int flags, + int data_size, int data_blocks, + int will_stop, u16 *resp) +{ + u16 * pu16 = (u16 *)&resp[0]; + u16 * reg_resp = (u16 *)(CONFIG_GLAMO_BASE + GLAMO_REGOFS_MMC + + GLAMO_REG_MMC_CMD_RSP1); + u16 status; + int n; + u8 u8a[6]; + u16 fire = 0; + int cmd_is_stop = 0; + int error = 0; + +#if 0 + printf("mmc_cmd(opcode=%d, arg=0x%08X, flags=0x%x, " + "data_size=%d, data_blocks=%d, will_stop=%d, resp=%p)\n", + opcode, arg, flags, data_size, data_blocks, will_stop, resp); +#endif + switch (opcode) { + case MMC_STOP_TRANSMISSION: + cmd_is_stop = 1; + break; + default: + break; + } + + ccnt++; + + /* this guy has data to read/write? */ + if ((!cmd_is_stop) && (flags & (MMC_DATA_WRITE | MMC_DATA_READ))) { + /* + * the S-Media-internal RAM offset for our MMC buffer + */ + glamo_reg_write((u16)GLAMO_FB_SIZE, + GLAMO_REGOFS_MMC + GLAMO_REG_MMC_WDATADS1); + glamo_reg_write((u16)(GLAMO_FB_SIZE >> 16), + GLAMO_REGOFS_MMC + GLAMO_REG_MMC_WDATADS2); + glamo_reg_write((u16)GLAMO_FB_SIZE, + GLAMO_REGOFS_MMC + GLAMO_REG_MMC_RDATADS1); + glamo_reg_write((u16)(GLAMO_FB_SIZE >> 16), + GLAMO_REGOFS_MMC + GLAMO_REG_MMC_RDATADS2); + + /* set up the block info */ + glamo_reg_write(data_size, GLAMO_REGOFS_MMC + + GLAMO_REG_MMC_DATBLKLEN); + glamo_reg_write(data_blocks, GLAMO_REGOFS_MMC + + GLAMO_REG_MMC_DATBLKCNT); + } + + /* if we can't do it, reject as busy */ + if (!glamo_reg_read(GLAMO_REGOFS_MMC + GLAMO_REG_MMC_RB_STAT1) & + GLAMO_STAT1_MMC_IDLE) + return -1; + + /* create an array in wire order for CRC computation */ + u8a[0] = 0x40 | (opcode & 0x3f); + u8a[1] = (arg >> 24); + u8a[2] = (arg >> 16); + u8a[3] = (arg >> 8); + u8a[4] = arg; + u8a[5] = CRC7(&u8a[0], 5); /* CRC7 on first 5 bytes of packet */ + + /* issue the wire-order array including CRC in register order */ + glamo_reg_write((u8a[4] << 8) | u8a[5], + GLAMO_REGOFS_MMC + GLAMO_REG_MMC_CMD_REG1); + glamo_reg_write((u8a[2] << 8) | u8a[3], + GLAMO_REGOFS_MMC + GLAMO_REG_MMC_CMD_REG2); + glamo_reg_write((u8a[0] << 8) | u8a[1], + GLAMO_REGOFS_MMC + GLAMO_REG_MMC_CMD_REG3); + + /* command index toggle */ + fire |= (ccnt & 1) << 12; + + /* set type of command */ + switch (mmc_cmd_type(flags)) { + case MMC_CMD_BC: + fire |= GLAMO_FIRE_MMC_CMDT_BNR; + break; + case MMC_CMD_BCR: + fire |= GLAMO_FIRE_MMC_CMDT_BR; + break; + case MMC_CMD_AC: + fire |= GLAMO_FIRE_MMC_CMDT_AND; + break; + case MMC_CMD_ADTC: + fire |= GLAMO_FIRE_MMC_CMDT_AD; + break; + } + /* + * if it expects a response, set the type expected + * + * R1, Length : 48bit, Normal response + * R1b, Length : 48bit, same R1, but added card busy status + * R2, Length : 136bit (really 128 bits with CRC snipped) + * R3, Length : 48bit (OCR register value) + * R4, Length : 48bit, SDIO_OP_CONDITION, Reverse SDIO Card + * R5, Length : 48bit, IO_RW_DIRECTION, Reverse SDIO Card + * R6, Length : 48bit (RCA register) + * R7, Length : 48bit (interface condition, VHS(voltage supplied), + * check pattern, CRC7) + */ + switch (mmc_resp_type(flags)) { + case MMC_RSP_R6: /* same index as R7 and R1 */ + fire |= GLAMO_FIRE_MMC_RSPT_R1; + break; + case MMC_RSP_R1B: + fire |= GLAMO_FIRE_MMC_RSPT_R1b; + break; + case MMC_RSP_R2: + fire |= GLAMO_FIRE_MMC_RSPT_R2; + break; + case MMC_RSP_R3: + fire |= GLAMO_FIRE_MMC_RSPT_R3; + break; + /* R4 and R5 supported by chip not defined in linux/mmc/core.h (sdio) */ + } + /* + * From the command index, set up the command class in the host ctrllr + * + * missing guys present on chip but couldn't figure out how to use yet: + * 0x0 "stream read" + * 0x9 "cancel running command" + */ + switch (opcode) { + case MMC_READ_SINGLE_BLOCK: + fire |= GLAMO_FIRE_MMC_CC_SBR; /* single block read */ + break; + case MMC_SWITCH: /* 64 byte payload */ + case 0x33: /* observed issued by MCI */ + case MMC_READ_MULTIPLE_BLOCK: + /* we will get an interrupt off this */ + if (!will_stop) + /* multiblock no stop */ + fire |= GLAMO_FIRE_MMC_CC_MBRNS; + else + /* multiblock with stop */ + fire |= GLAMO_FIRE_MMC_CC_MBRS; + break; + case MMC_WRITE_BLOCK: + fire |= GLAMO_FIRE_MMC_CC_SBW; /* single block write */ + break; + case MMC_WRITE_MULTIPLE_BLOCK: + if (will_stop) + /* multiblock with stop */ + fire |= GLAMO_FIRE_MMC_CC_MBWS; + else + /* multiblock NO stop-- 'RESERVED'? */ + fire |= GLAMO_FIRE_MMC_CC_MBWNS; + break; + case MMC_STOP_TRANSMISSION: + fire |= GLAMO_FIRE_MMC_CC_STOP; /* STOP */ + break; + default: + fire |= GLAMO_FIRE_MMC_CC_BASIC; /* "basic command" */ + break; + } + /* enforce timeout */ + glamo_reg_write(0xfff, GLAMO_REGOFS_MMC + GLAMO_REG_MMC_TIMEOUT); + + /* Generate interrupt on txfer; drive strength max */ + glamo_reg_write((glamo_reg_read(GLAMO_REGOFS_MMC + + GLAMO_REG_MMC_BASIC) & 0xfe) | + 0x0800 | GLAMO_BASIC_MMC_NO_CLK_RD_WAIT | + GLAMO_BASIC_MMC_EN_COMPL_INT | + GLAMO_BASIC_MMC_EN_DR_STR0 | + GLAMO_BASIC_MMC_EN_DR_STR1, + GLAMO_REGOFS_MMC + GLAMO_REG_MMC_BASIC); + + /* send the command out on the wire */ + /* dev_info(&host->pdev->dev, "Using FIRE %04X\n", fire); */ + glamo_reg_write(fire, GLAMO_REGOFS_MMC + GLAMO_REG_MMC_CMD_FIRE); + + /* + * we must spin until response is ready or timed out + * -- we don't get interrupts unless there is a bulk rx + */ + do + status = glamo_reg_read(GLAMO_REGOFS_MMC + + GLAMO_REG_MMC_RB_STAT1); + while ((((status >> 15) & 1) != (ccnt & 1)) || + (!(status & (GLAMO_STAT1_MMC_RB_RRDY | + GLAMO_STAT1_MMC_RTOUT | + GLAMO_STAT1_MMC_DTOUT | + GLAMO_STAT1_MMC_BWERR | + GLAMO_STAT1_MMC_BRERR)))); + + if (status & (GLAMO_STAT1_MMC_RTOUT | GLAMO_STAT1_MMC_DTOUT)) + error = -4; + if (status & (GLAMO_STAT1_MMC_BWERR | GLAMO_STAT1_MMC_BRERR)) + error = -5; + + if (cmd_is_stop) + return 0; + + if (error) { + printf("cmd 0x%x, arg 0x%x flags 0x%x\n", opcode, arg, flags); + printf("Error after cmd: 0x%x\n", error); + goto done; + } + /* + * mangle the response registers in two different exciting + * undocumented ways discovered by trial and error + */ + if (mmc_resp_type(flags) == MMC_RSP_R2) + /* grab the response */ + for (n = 0; n < 8; n++) /* super mangle power 1 */ + pu16[n ^ 6] = reg_resp[n]; + else + for (n = 0; n < 3; n++) /* super mangle power 2 */ + pu16[n] = (reg_resp[n] >> 8) | + (reg_resp[n + 1] << 8); + /* + * if we don't have bulk data to take care of, we're done + */ + if (!(flags & (MMC_DATA_READ | MMC_DATA_WRITE))) + goto done; + + /* enforce timeout */ + glamo_reg_write(0xfff, GLAMO_REGOFS_MMC + GLAMO_REG_MMC_TIMEOUT); + /* + * spin + */ + while (!(glamo_reg_read(GLAMO_REG_IRQ_STATUS) & GLAMO_IRQ_MMC)) + ; + /* ack this interrupt source */ + glamo_reg_write(GLAMO_IRQ_MMC, GLAMO_REG_IRQ_CLEAR); + + if (status & GLAMO_STAT1_MMC_DTOUT) + error = -1; + if (status & (GLAMO_STAT1_MMC_BWERR | GLAMO_STAT1_MMC_BRERR)) + error = -2; + if (status & GLAMO_STAT1_MMC_RTOUT) + error = -5; + if (error) { + printf("cmd 0x%x, arg 0x%x flags 0x%x\n", opcode, arg, flags); + printf("Error after resp: 0x%x\n", status); + goto done; + } +#if 0 + if (flags & MMC_DATA_READ) { + volatile u8 * pu8 = (volatile u8 *)GLAMO_START_OF_MMC_INTMEM; + for (n = 0; n < 512; n += 16) { + int n1; + for (n1 = 0; n1 < 16; n1++) { + printf("%02X ", pu8[n + n1]); + } + printf("\n"); + } + } +#endif + return 0; + +done: + return error; +} + +static void glamo_mci_reset(void) +{ + /* reset MMC controller */ + glamo_reg_write(GLAMO_CLOCK_MMC_RESET | GLAMO_CLOCK_MMC_DG_TCLK | + GLAMO_CLOCK_MMC_EN_TCLK | GLAMO_CLOCK_MMC_DG_M9CLK | + GLAMO_CLOCK_MMC_EN_M9CLK, + GLAMO_REG_CLOCK_MMC); + udelay(100000); + /* and disable reset */ + glamo_reg_write(GLAMO_CLOCK_MMC_DG_TCLK | + GLAMO_CLOCK_MMC_EN_TCLK | GLAMO_CLOCK_MMC_DG_M9CLK | + GLAMO_CLOCK_MMC_EN_M9CLK, + GLAMO_REG_CLOCK_MMC); +} + + +static u_int8_t ldo_voltage(unsigned int millivolts) +{ + if (millivolts < 900) + return 0; + else if (millivolts > 3600) + return 0x1f; + + millivolts -= 900; + return millivolts / 100; +} + +int mmc_read(ulong src, uchar *dst, int size) +{ + int resp; + u8 response[16]; + int size_original = size; + + if ((!size) || (size & (MMC_BLOCK_SIZE - 1))) { + printf("Bad size %d\n", size); + return 0; + } + + if (((int)dst) & 1) { + printf("Bad align on dst\n"); + return 0; + } + + resp = mmc_cmd(MMC_SET_BLOCKLEN, MMC_BLOCK_SIZE, + MMC_CMD_AC | MMC_RSP_R1, 0, 0, 0, + (u16 *)&response[0]); + + while (size) { + switch (card_type) { + case CARDTYPE_SDHC: /* block addressing */ + resp = mmc_cmd(MMC_READ_SINGLE_BLOCK, + src >> MMC_BLOCK_SIZE_BITS, + MMC_CMD_ADTC | MMC_RSP_R1 | + MMC_DATA_READ, MMC_BLOCK_SIZE, 1, 0, + (u16 *)&response[0]); + break; + default: /* byte addressing */ + resp = mmc_cmd(MMC_READ_SINGLE_BLOCK, src, + MMC_CMD_ADTC | MMC_RSP_R1 | MMC_DATA_READ, + MMC_BLOCK_SIZE, 1, 0, + (u16 *)&response[0]); + break; + } + do_pio_read((u16 *)dst, MMC_BLOCK_SIZE >> 1); + + if (size >= MMC_BLOCK_SIZE) + size -= MMC_BLOCK_SIZE; + else + size = 0; + dst += MMC_BLOCK_SIZE; + src += MMC_BLOCK_SIZE; + } + return size_original; +} + +int mmc_write(uchar *src, ulong dst, int size) +{ + int resp; + u8 response[16]; + int size_original = size; + + if ((!size) || (size & (MMC_BLOCK_SIZE - 1))) { + printf("Bad size %d\n", size); + return 0; + } + + if (((int)dst) & 1) { + printf("Bad align on dst\n"); + return 0; + } + + resp = mmc_cmd(MMC_SET_BLOCKLEN, MMC_BLOCK_SIZE, + MMC_CMD_AC | MMC_RSP_R1, 0, 0, 0, + (u16 *)&response[0]); + + while (size) { + do_pio_write((u16 *)src, MMC_BLOCK_SIZE >> 1); + switch (card_type) { + case CARDTYPE_SDHC: /* block addressing */ + resp = mmc_cmd(MMC_WRITE_BLOCK, + dst >> MMC_BLOCK_SIZE_BITS, + MMC_CMD_ADTC | MMC_RSP_R1 | + MMC_DATA_WRITE, + MMC_BLOCK_SIZE, 1, 0, + (u16 *)&response[0]); + break; + default: /* byte addressing */ + resp = mmc_cmd(MMC_WRITE_BLOCK, dst, + MMC_CMD_ADTC | MMC_RSP_R1 | + MMC_DATA_WRITE, + MMC_BLOCK_SIZE, 1, 0, + (u16 *)&response[0]); + break; + } + if (size >= MMC_BLOCK_SIZE) + size -= MMC_BLOCK_SIZE; + else + size = 0; + dst += MMC_BLOCK_SIZE; + src += MMC_BLOCK_SIZE; + } + return size_original; +} + +static void print_mmc_cid(mmc_cid_t *cid) +{ + printf("MMC found. Card desciption is:\n"); + printf("Manufacturer ID = %02x%02x%02x\n", + cid->id[0], cid->id[1], cid->id[2]); + printf("HW/FW Revision = %x %x\n",cid->hwrev, cid->fwrev); + cid->hwrev = cid->fwrev = 0; /* null terminate string */ + printf("Product Name = %s\n",cid->name); + printf("Serial Number = %02x%02x%02x\n", + cid->sn[0], cid->sn[1], cid->sn[2]); + printf("Month = %d\n",cid->month); + printf("Year = %d\n",1997 + cid->year); +} + +static void print_sd_cid(const struct sd_cid *cid) +{ + printf("Card Type: "); + switch (card_type) { + case CARDTYPE_NONE: + printf("(None)\n"); + break; + case CARDTYPE_MMC: + printf("MMC\n"); + break; + case CARDTYPE_SD: + printf("SD\n"); + break; + case CARDTYPE_SD20: + printf("SD 2.0\n"); + break; + case CARDTYPE_SDHC: + printf("SD 2.0 SDHC\n"); + break; + } + printf("Manufacturer: 0x%02x, OEM \"%c%c\"\n", + cid->mid, cid->oid_0, cid->oid_1); + printf("Product name: \"%c%c%c%c%c\", revision %d.%d\n", + cid->pnm_0, cid->pnm_1, cid->pnm_2, cid->pnm_3, cid->pnm_4, + cid->prv >> 4, cid->prv & 15); + printf("Serial number: %u\n", + cid->psn_0 << 24 | cid->psn_1 << 16 | cid->psn_2 << 8 | + cid->psn_3); + printf("Manufacturing date: %d/%d\n", + cid->mdt_1 & 15, + 2000+((cid->mdt_0 & 15) << 4)+((cid->mdt_1 & 0xf0) >> 4)); +/* printf("CRC: 0x%02x, b0 = %d\n", + cid->crc >> 1, cid->crc & 1); */ +} + + +int mmc_init(int verbose) +{ + int retries = 14, rc = -ENODEV; + int resp; + u8 response[16]; + mmc_cid_t *mmc_cid = (mmc_cid_t *)response; + struct sd_cid *sd_cid = (struct sd_cid *)response; + u32 hcs = 0; + + card_type = CARDTYPE_NONE; + + /* enable engine */ + + glamo_reg_write(GLAMO_CLOCK_MMC_EN_M9CLK | + GLAMO_CLOCK_MMC_EN_TCLK | + GLAMO_CLOCK_MMC_DG_M9CLK | + GLAMO_CLOCK_MMC_DG_TCLK, GLAMO_REG_CLOCK_MMC); + glamo_reg_write(glamo_reg_read(GLAMO_REG_HOSTBUS(2)) | + GLAMO_HOSTBUS2_MMIO_EN_MMC, GLAMO_REG_HOSTBUS(2)); + + /* controller reset */ + + glamo_mci_reset(); + + /* power the sdcard slot */ + + pcf50633_reg_write(PCF50633_REG_HCLDOOUT, ldo_voltage(3300)); + udelay(10000); + pcf50633_reg_write(PCF50633_REG_HCLDOOUT + 1, + pcf50633_reg_read(PCF50633_REG_HCLDOOUT + 1) | 1); /* on */ + udelay(10000); + + /* start the clock -- slowly (50MHz / 250 == 195kHz */ + + glamo_reg_write((glamo_reg_read(GLAMO_REG_CLOCK_GEN8) & 0xff00) | 250, + GLAMO_REG_CLOCK_GEN8); + + /* enable clock to divider input */ + + glamo_reg_write(glamo_reg_read( + GLAMO_REG_CLOCK_GEN5_1) | GLAMO_CLOCK_GEN51_EN_DIV_TCLK, + GLAMO_REG_CLOCK_GEN5_1); + + udelay(100000); + + /* set bus width to 1 */ + + glamo_reg_write((glamo_reg_read(GLAMO_REGOFS_MMC + + GLAMO_REG_MMC_BASIC) & + (~GLAMO_BASIC_MMC_EN_4BIT_DATA)), + GLAMO_REGOFS_MMC + GLAMO_REG_MMC_BASIC); + + /* reset */ + + resp = mmc_cmd(MMC_GO_IDLE_STATE, 0, MMC_CMD_BCR, 0, 0, 0, + (u16 *)&response[0]); + + udelay(100000); + udelay(100000); + udelay(100000); + + /* SDHC card? */ + + resp = mmc_cmd(SD_SEND_IF_COND, 0x000001aa, + MMC_CMD_BCR | MMC_RSP_R7, 0, 0, 0, + (u16 *)&response[0]); + if (!resp && (response[0] == 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); + + resp = mmc_cmd(MMC_APP_CMD, 0x00000000, + MMC_CMD_AC | MMC_RSP_R1, 0, 0, 0, + (u16 *)&response[0]); + if (resp) + continue; + resp = mmc_cmd(SD_APP_OP_COND, hcs | 0x00300000, + MMC_CMD_BCR | MMC_RSP_R3, 0, 0, 0, + (u16 *)&response[0]); + if (resp) + continue; + + if (response[3] & (1 << 6)) /* asserts block addressing */ + card_type = CARDTYPE_SDHC; + + if (response[3] & (1 << 7)) { /* not busy */ + if (card_type == CARDTYPE_NONE) + card_type = CARDTYPE_SD; + break; + } + } + if (retries < 0) + return 1; + + if (card_type == CARDTYPE_NONE) { + retries = 10; + printf("failed to detect SD Card, trying MMC\n"); + do { + resp = mmc_cmd(MMC_SEND_OP_COND, 0x00ffc000, + MMC_CMD_BCR | MMC_RSP_R3, 0, 0, 0, + (u16 *)&response[0]); + debug("resp %x %x\n", response[0], response[1]); + udelay(50); + } while (retries-- && !(response[3] & 0x80)); + if (retries >= 0) + card_type = CARDTYPE_MMC; + else + return 1; + } + + /* fill in device description */ + mmc_dev.if_type = IF_TYPE_MMC; + mmc_dev.part_type = PART_TYPE_DOS; + mmc_dev.dev = 0; + mmc_dev.lun = 0; + mmc_dev.type = 0; + mmc_dev.removable = 0; + mmc_dev.block_read = mmc_bread; + mmc_dev.blksz = 512; + mmc_dev.lba = 1 << 16; /* 64K x 512 blocks = 32MB default */ + + /* try to get card id */ + resp = mmc_cmd(MMC_ALL_SEND_CID, hcs, + MMC_CMD_BCR | MMC_RSP_R2, 0, 0, 0, + (u16 *)&response[0]); + if (resp) + return 1; + + switch (card_type) { + case CARDTYPE_MMC: + /* TODO configure mmc driver depending on card + attributes */ + + if (verbose) + print_mmc_cid(mmc_cid); + sprintf((char *) mmc_dev.vendor, + "Man %02x%02x%02x Snr %02x%02x%02x", + mmc_cid->id[0], mmc_cid->id[1], mmc_cid->id[2], + mmc_cid->sn[0], mmc_cid->sn[1], mmc_cid->sn[2]); + sprintf((char *) mmc_dev.product, "%s", mmc_cid->name); + sprintf((char *) mmc_dev.revision, "%x %x", + mmc_cid->hwrev, mmc_cid->fwrev); + + /* MMC exists, get CSD too */ + resp = mmc_cmd(MMC_SET_RELATIVE_ADDR, MMC_DEFAULT_RCA, + MMC_CMD_AC | MMC_RSP_R1, 0, 0, 0, + (u16 *)&response[0]); + break; + + case CARDTYPE_SD: + case CARDTYPE_SD20: + case CARDTYPE_SDHC: + if (verbose) + print_sd_cid(sd_cid); + sprintf((char *) mmc_dev.vendor, + "Man %02 OEM %c%c \"%c%c%c%c%c\"", + sd_cid->mid, sd_cid->oid_0, sd_cid->oid_1, + sd_cid->pnm_0, sd_cid->pnm_1, sd_cid->pnm_2, + sd_cid->pnm_3, sd_cid->pnm_4); + sprintf((char *) mmc_dev.product, "%d", + sd_cid->psn_0 << 24 | sd_cid->psn_1 << 16 | + sd_cid->psn_2 << 8 | sd_cid->psn_3); + sprintf((char *) mmc_dev.revision, "%d.%d", + sd_cid->prv >> 4, sd_cid->prv & 15); + + resp = mmc_cmd(SD_SEND_RELATIVE_ADDR, MMC_DEFAULT_RCA, + MMC_CMD_BCR | MMC_RSP_R6, 0, 0, 0, + (u16 *)&response[0]); + rca = response[2] | (response[3] << 8); + break; + + default: + return 1; + } + + /* grab the CSD */ + + resp = mmc_cmd(MMC_SEND_CSD, rca << 16, + MMC_CMD_AC | MMC_RSP_R2, 0, 0, 0, + (u16 *)&response[0]); + if (!resp) { + mmc_csd_t *csd = (mmc_csd_t *)response; + + memcpy(&mmc_csd, csd, sizeof(csd)); + rc = 0; + mmc_ready = 1; + /* 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); */ + mmc_dev.blksz = 512; + mmc_dev.lba = (((unsigned long)1 << csd->c_size_mult1) * + (unsigned long)csd->c_size) >> 9; + printf("MMC/SD size: %dMiB\n", mmc_dev.lba >> 1); + } + + resp = mmc_cmd(MMC_SELECT_CARD, rca<<16, MMC_CMD_AC | MMC_RSP_R1, + 0, 0, 0, (u16 *)&response[0]); + if (resp) + return 1; + +#ifdef CONFIG_MMC_WIDE + /* yay 4-bit! */ + if (card_type == CARDTYPE_SD || card_type == CARDTYPE_SDHC) { + resp = mmc_cmd(MMC_APP_CMD, rca<<16, MMC_CMD_AC | MMC_RSP_R1, + 0, 0, 0, (u16 *)&response[0]); + resp = mmc_cmd(MMC_SWITCH, 0x02, MMC_CMD_AC | MMC_RSP_R1B, + 0, 0, 0, (u16 *)&response[0]); + wide = 1; + glamo_reg_write(glamo_reg_read(GLAMO_REGOFS_MMC + + GLAMO_REG_MMC_BASIC) | GLAMO_BASIC_MMC_EN_4BIT_DATA, + GLAMO_REGOFS_MMC + GLAMO_REG_MMC_BASIC); + } +#endif + + /* crank the clock to the final speed, 16MHz */ + + glamo_reg_write((glamo_reg_read(GLAMO_REG_CLOCK_GEN8) & 0xff00) | 2, + GLAMO_REG_CLOCK_GEN8); + + fat_register_device(&mmc_dev, 1); /* partitions start counting with 1 */ + + return rc; +} + +void mmc_depower(void) +{ + u8 response[16]; + + /* reset */ + mmc_cmd(MMC_GO_IDLE_STATE, 0, MMC_CMD_BCR, 0, 0, 0, + (u16 *)&response[0]); + + /* hold engine reset, remove clocks */ + + glamo_reg_write(GLAMO_CLOCK_MMC_RESET, GLAMO_REG_CLOCK_MMC); + + /* disable engine */ + + glamo_reg_write(0, GLAMO_REG_CLOCK_MMC); + glamo_reg_write(glamo_reg_read(GLAMO_REG_HOSTBUS(2)) & + (~GLAMO_HOSTBUS2_MMIO_EN_MMC), GLAMO_REG_HOSTBUS(2)); + + /* remove power */ + + pcf50633_reg_write(PCF50633_REG_HCLDOOUT + 1, + pcf50633_reg_read(PCF50633_REG_HCLDOOUT + 1) & ~1); /* off */ +} + +int +mmc_ident(block_dev_desc_t *dev) +{ + return 0; +} + +int +mmc2info(ulong addr) +{ + /* FIXME hard codes to 32 MB device */ + if (addr >= CFG_MMC_BASE && addr < CFG_MMC_BASE + 0x02000000) + return 1; + + return 0; +} + +#endif + diff --git a/qiboot/src/drivers/glamo-mmc.h b/qiboot/src/drivers/glamo-mmc.h new file mode 100644 index 0000000..3f2294c --- /dev/null +++ b/qiboot/src/drivers/glamo-mmc.h @@ -0,0 +1,149 @@ +#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 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; + 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 */ +}; + +enum card_type { + CARDTYPE_NONE = 0, + CARDTYPE_MMC, + CARDTYPE_SD, + CARDTYPE_SD20, + CARDTYPE_SDHC +}; + + +#endif /* __GLAMO_MMC_H__ */ diff --git a/qiboot/src/drivers/glamo-regs.h b/qiboot/src/drivers/glamo-regs.h new file mode 100644 index 0000000..8f6c45c --- /dev/null +++ b/qiboot/src/drivers/glamo-regs.h @@ -0,0 +1,628 @@ +#ifndef _GLAMO_REGS_H +#define _GLAMO_REGS_H + +/* Smedia Glamo 336x/337x driver + * + * (C) 2007 by OpenMoko, Inc. + * Author: Harald Welte + * 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_DFT_GEN5 = 0x01e0, + GLAMO_REG_DFT_GEN6 = 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 */ From 58c0b5743992211af1d8d8eec438042d4f6b4468 Mon Sep 17 00:00:00 2001 From: Matt Hsu Date: Fri, 28 Nov 2008 10:16:36 +0000 Subject: [PATCH 048/248] add gta03 board specific support --- qiboot/include/neo_gta03.h | 32 ++++++ qiboot/src/gta03/gta03.c | 200 +++++++++++++++++++++++++++++++++++++ qiboot/src/start_qi.c | 4 +- 3 files changed, 235 insertions(+), 1 deletion(-) create mode 100644 qiboot/include/neo_gta03.h create mode 100644 qiboot/src/gta03/gta03.c diff --git a/qiboot/include/neo_gta03.h b/qiboot/include/neo_gta03.h new file mode 100644 index 0000000..a01972e --- /dev/null +++ b/qiboot/include/neo_gta03.h @@ -0,0 +1,32 @@ +/* + * (C) Copyright 2008 OpenMoko, Inc. + * Author: Matt Hsu + * + * Configuation settings for the Openmoko GTA03 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_GTA03_H +#define __CONFIG_GTA03_H +#ifndef __ASM_MODE__ +#include +extern const struct board_api board_api_gta03; +#endif + +#define TEXT_BASE 0x33000000 + +#endif /* __CONFIG_GTA03_H */ diff --git a/qiboot/src/gta03/gta03.c b/qiboot/src/gta03/gta03.c new file mode 100644 index 0000000..1a2c00b --- /dev/null +++ b/qiboot/src/gta03/gta03.c @@ -0,0 +1,200 @@ +#include +#include + +static const struct board_variant board_variants[] = { + [0] = { + .name = "EVB PCB", + .machine_revision = 0x010, + }, +}; + +void port_init_gta03(void) +{ + //CAUTION:Follow the configuration order for setting the ports. + // 1) setting value(GPnDAT) + // 2) setting control register (GPnCON) + // 3) configure pull-up 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 = 0x007F8FFF; + /* + * ===* 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 = 0x00145554; + rGPBDAT |= (1 <<9 ); /* USB_PULLUP */ + rGPBUP = 0x000007FF; + /* + * === 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 = 0xAAA776E9; + rGPCUP = 0x0000FFFF; + rGPCDAT |= (1 << 9); /* WLAN_nRESET pull high */ + /* + * === 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 = 0xAAA0AAA5; + rGPDUP = 0x0000FFFF; + /* + * === 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; + /* + * === 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 + */ + rGPFCON = 0x0000AAAA; + rGPFUP = 0x000000FF; + + /* + * === 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 = 0x02A9FE5A; + rGPGUP = 0x0000FFFF; + + /* + * === 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 + */ + /* pulldown on GPH08: UEXTCLK, just floats! + * pulldown GPH0 -- nCTS0 / RTS_MODEM -- floats when GSM off + * pulldown GPH3 -- RXD[0] / TX_MODEM -- floats when GSM off + */ + rGPHCON = 0x0019A0AA; + rGPHUP = 0x000007FF; + + /* pulldown on GPJ00: input, just floats! */ + /* pulldown on GPJ07: WLAN module WLAN_GPIO0, no ext pull */ + rGPJCON = 0x02AAAAAA; + rGPJUP = 0x1FFFF; + + serial_init(UART2, 0x11); +} + +/** + * returns PCB revision information in b0, d8, d9 + * GTA03 EVB returns 0x000 + * GTA03 returns 0x001 + */ + +int gta03_get_pcb_revision(void) +{ + int n; + u32 u; + + /* make B0 inputs */ + rGPBCON &= ~0x00000003; + /* D8 and D9 inputs */ + rGPDCON &= ~0x000f0000; + + /* delay after changing pulldowns */ + u = rGPBDAT; + u = rGPDDAT; + + /* read the version info */ + u = rGPBDAT; + n = (u >> (0 - 0))& 0x001; + u = rGPDDAT; + n |= (u >> (8 -1)) & 0x002; + n |= (u >> (9 - 2)) & 0x004; + + /* + * when not being interrogated, all of the revision GPIO + * are set to output + */ + /* make B0 high ouput */ + rGPBCON |= 0x00000001; + /* D8 and D9 high ouputs */ + rGPDCON |= 0x00050000; + + return n; + +} + +const struct board_variant const * get_board_variant_gta03(void) +{ + return &board_variants[gta03_get_pcb_revision()]; +} + +int is_this_board_gta03(void) +{ + /* FIXME: find something gta03 specific */ + return 1; +} +/* + * our API for bootloader on this machine + */ +const struct board_api board_api_gta03 = { + .name = "GTA03", + .debug_serial_port = 2, + .linux_machine_id = 1808, + .linux_mem_start = 0x30000000, + .linux_mem_size = (128 * 1024 * 1024), + .linux_tag_placement = 0x30000000 + 0x100, + .get_board_variant = get_board_variant_gta03, + .is_this_board = is_this_board_gta03, + .port_init = port_init_gta03, + /* these are the ways we could boot GTA03 in order to try */ + .kernel_source = { + [0] = { + .name = "NAND Kernel", + .block_read = nand_read_ll, + .partition_index = -1, + .offset_if_no_partition = 0x80000, + .filesystem = FS_RAW, + .commandline = "neo1973-nand:" \ + "0x00040000(qi)," \ + "0x00040000(cmdline)," \ + "0x00800000(backupkernel)," \ + "0x000a0000(extra)," \ + "0x00040000(identity)," \ + "0x0f6a0000(backuprootfs) " \ + "rootfstype=jffs2 " \ + "root=/dev/mtdblock6 " \ + "console=ttySAC2,115200 " \ + "loglevel=4 " \ + "init=/sbin/init "\ + "ro" + }, + }, +}; diff --git a/qiboot/src/start_qi.c b/qiboot/src/start_qi.c index f0cdeaf..de5abd4 100644 --- a/qiboot/src/start_qi.c +++ b/qiboot/src/start_qi.c @@ -28,6 +28,7 @@ #include "blink_led.h" #include "nand_read.h" #include +#include #define stringify2(s) stringify1(s) #define stringify1(s) #s @@ -35,7 +36,8 @@ extern void bootloader_second_phase(void); const struct board_api * boards[] = { - &board_api_gta02 + &board_api_gta02, + &board_api_gta03, }; struct board_api const * this_board; From d10aee81b0b7643146b4c22c9e5862c68faf63b3 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:36 +0000 Subject: [PATCH 049/248] add-copyright-notices.patch Little notice cleanup + add ARRAY_SIZE Signed-off-by: Andy Green --- qiboot/include/qi.h | 2 ++ qiboot/src/gta02/gta02.c | 25 +++++++++++++++++++++++++ qiboot/src/start_qi.c | 2 +- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index 16227a4..c4094d0 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -30,6 +30,8 @@ #define u8 unsigned char typedef unsigned int uint32_t; +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) + enum filesystem { FS_RAW, FS_FAT, diff --git a/qiboot/src/gta02/gta02.c b/qiboot/src/gta02/gta02.c index 7566a9c..b74b727 100644 --- a/qiboot/src/gta02/gta02.c +++ b/qiboot/src/gta02/gta02.c @@ -1,3 +1,28 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: Andy Green + * + * (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 #include diff --git a/qiboot/src/start_qi.c b/qiboot/src/start_qi.c index de5abd4..1fe7df2 100644 --- a/qiboot/src/start_qi.c +++ b/qiboot/src/start_qi.c @@ -67,7 +67,7 @@ void start_qi(void) this_board = boards[board]; while (!n) { - if (board >= (sizeof(boards) / sizeof(boards[0]))) + if (board >= ARRAY_SIZE(boards)) /* can't put diagnostic on serial... too early */ goto unhappy; From 126fef5514b2086ece34326423236b0c43e96bcd Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:36 +0000 Subject: [PATCH 050/248] reenable-bss-cleardown.patch Left BSS zeroing disabled from previous debugging, re-enable it Signed-off-by: Andy Green --- qiboot/src/start.S | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qiboot/src/start.S b/qiboot/src/start.S index 3a98bef..ef7ff2d 100644 --- a/qiboot/src/start.S +++ b/qiboot/src/start.S @@ -175,7 +175,7 @@ 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 */ -#if 0 + clear_bss: ldr r0, _bss_start /* find start of bss segment */ ldr r1, _bss_end /* stop here */ @@ -186,7 +186,6 @@ clbss_l: add r0, r0, #4 cmp r0, r1 ble clbss_l -#endif /* we are going to jump into the C part of the init now */ spin: From aa04cc7e5d7ab03d0d60fd28df1533638386c961 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:36 +0000 Subject: [PATCH 051/248] update-comment-linker-script.patch Update the comment for linker script system in use now Signed-off-by: Andy Green --- qiboot/src/start_qi.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/qiboot/src/start_qi.c b/qiboot/src/start_qi.c index 1fe7df2..f5c0223 100644 --- a/qiboot/src/start_qi.c +++ b/qiboot/src/start_qi.c @@ -52,9 +52,11 @@ void start_qi(void) * steppingstone SRAM for free. Now we pull the whole bootloader * image into SDRAM. * - * So this doesn't trash position-dependent code, we took care in the - * linker script to arrange all rodata* segment content to be in the - * first 4K region. + * 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 24KBytes of bootloader */ From 65087a264e0212da1033b14bfdf41c0deff0484f Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:36 +0000 Subject: [PATCH 052/248] introduce-i2c.patch Introduce generic bitbang I2C system, and a s3c24xx-specific implementation of it that knows which GPIO pins and how to control them. The generic bitbang stuff exposes synchronous (ie, it will return when it is done) and asynchronous read and write APIs, allowing the delay between bits to be hidden in other slow, looping code if necessary. Signed-off-by: Andy Green --- qiboot/include/i2c-bitbang-s3c24xx.h | 3 + qiboot/include/i2c-bitbang.h | 101 ++++++++++ qiboot/src/drivers/i2c-bitbang-s3c24xx.c | 67 +++++++ qiboot/src/drivers/i2c-bitbang.c | 230 +++++++++++++++++++++++ qiboot/src/gta02/gta02.c | 2 + 5 files changed, 403 insertions(+) create mode 100644 qiboot/include/i2c-bitbang-s3c24xx.h create mode 100644 qiboot/include/i2c-bitbang.h create mode 100644 qiboot/src/drivers/i2c-bitbang-s3c24xx.c create mode 100644 qiboot/src/drivers/i2c-bitbang.c diff --git a/qiboot/include/i2c-bitbang-s3c24xx.h b/qiboot/include/i2c-bitbang-s3c24xx.h new file mode 100644 index 0000000..6be18b9 --- /dev/null +++ b/qiboot/include/i2c-bitbang-s3c24xx.h @@ -0,0 +1,3 @@ +#include + +extern struct i2c_bitbang bb_s3c24xx; diff --git a/qiboot/include/i2c-bitbang.h b/qiboot/include/i2c-bitbang.h new file mode 100644 index 0000000..0873b3b --- /dev/null +++ b/qiboot/include/i2c-bitbang.h @@ -0,0 +1,101 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: Andy Green + * + * 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 +}; + +/* 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 */ diff --git a/qiboot/src/drivers/i2c-bitbang-s3c24xx.c b/qiboot/src/drivers/i2c-bitbang-s3c24xx.c new file mode 100644 index 0000000..353dedc --- /dev/null +++ b/qiboot/src/drivers/i2c-bitbang-s3c24xx.c @@ -0,0 +1,67 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: Andy Green + * + * 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 +#include + +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 < 700; 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, +}; diff --git a/qiboot/src/drivers/i2c-bitbang.c b/qiboot/src/drivers/i2c-bitbang.c new file mode 100644 index 0000000..9762415 --- /dev/null +++ b/qiboot/src/drivers/i2c-bitbang.c @@ -0,0 +1,230 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: Andy Green + * + * 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 + * + */ + +#include +#include + +void i2c_read(struct i2c_bitbang * bb, unsigned char ads7, unsigned char reg) +{ + bb->data[0] = (ads7 << 1); /* write the register address */ + bb->data[1] = reg; + bb->data[2] = IBCONTROL_DO_START; + bb->data[3] = (ads7 << 1) | 1; /* then issue read cycle to device */ + bb->data[4] = IBCONTROL_DO_READ; + bb->data[5] = IBCONTROL_DO_STOP; + bb->data[6] = IBCONTROL_COMPLETE; + bb->state = IBS_INIT; +} + +void i2c_write(struct i2c_bitbang * bb, unsigned char ads7, unsigned char reg, + unsigned char b) +{ + bb->data[0] = (ads7 << 1); + bb->data[1] = reg; + bb->data[2] = b; + bb->data[3] = IBCONTROL_DO_STOP; + bb->data[4] = IBCONTROL_COMPLETE; + bb->state = IBS_INIT; +} + +int i2c_next_state(struct i2c_bitbang * bb) +{ + switch (bb->state) { + case IBS_INIT: + bb->index = 0; + bb->index_read = 0; + /* fall thru */ + case IBS_START1: + (bb->set)(1, 0); + (bb->set)(0, 0); /* start */ + bb->state = IBS_START2; + break; + + case IBS_START2: + bb->count = 8; + bb->state = IBS_ADS_TX_S; + break; + + /* transmit address or data */ + case IBS_ADS_TX_S: + (bb->set)(0, !!(bb->data[bb->index] & 0x80)); + bb->state = IBS_ADS_TX_H; + break; + case IBS_ADS_TX_H: + (bb->set)(1, !!(bb->data[bb->index] & 0x80)); + bb->state = IBS_ADS_TX_L; + break; + case IBS_ADS_TX_L: + (bb->set)(0, !!(bb->data[bb->index] & 0x80)); + bb->data[bb->index] <<= 1; + bb->count--; + if (bb->count) { + bb->state = IBS_ADS_TX_S; + break; + } + + (bb->set)(0, 1); + bb->state = IBS_ADS_TX_ACK_H; + break; + + case IBS_ADS_TX_ACK_H: + /* we finished... we expect an ack now */ + if ((bb->read_sda)()) + return -1; + + (bb->set)(1, 1); + bb->state = IBS_ADS_TX_ACK_L; + break; + + case IBS_ADS_TX_ACK_L: + (bb->set)(0, 1); + + bb->count = 8; + bb->index++; + switch (bb->data[bb->index]) { + case IBCONTROL_DO_START: + bb->state = IBS_START1; + bb->index++; + break; + case IBCONTROL_DO_STOP: + bb->state = IBS_STOP1; + bb->index++; + break; + case IBCONTROL_DO_READ: + bb->data[bb->index_read] = 0; + bb->state = IBS_DATA_RX_S; + break; + case IBCONTROL_COMPLETE: + return 1; + default: + bb->state = IBS_ADS_TX_S; /* write it out */ + break; + } + break; + + + /* receive data */ + case IBS_DATA_RX_S: + (bb->set)(0, 1); + bb->state = IBS_DATA_RX_H; + break; + + case IBS_DATA_RX_H: + (bb->set)(1, 1); + bb->state = IBS_DATA_RX_L; + break; + + case IBS_DATA_RX_L: + bb->data[bb->index_read] <<= 1; + bb->data[bb->index_read] |= !!(bb->read_sda)(); + (bb->set)(0, 1); + bb->count--; + if (bb->count) { + bb->state = IBS_DATA_RX_S; + break; + } + + /* slave has released SDA now, bang down ACK */ + (bb->set)(0, 0); + bb->state = IBS_DATA_RX_ACK_H; + break; + + case IBS_DATA_RX_ACK_H: + (bb->set)(1, 0); + bb->state = IBS_DATA_RX_ACK_L; + break; + + case IBS_DATA_RX_ACK_L: + (bb->set)(0, 1); + bb->index_read++; + bb->index++; + switch (bb->data[bb->index]) { + case IBCONTROL_DO_START: + bb->state = IBS_START1; + bb->index++; + break; + case IBCONTROL_DO_STOP: + bb->state = IBS_STOP1; + bb->index++; + break; + case IBCONTROL_DO_READ: + bb->state = IBS_DATA_RX_S; + bb->data[bb->index_read] = 0; + break; + case IBCONTROL_COMPLETE: + return 1; + default: + bb->state = IBS_ADS_TX_S; /* write it out */ + break; + } + break; + + break; + + + case IBS_STOP1: + (bb->set)(0, 0); + bb->state = IBS_STOP2; + break; + + case IBS_STOP2: + (bb->set)(1, 0); + bb->state = IBS_STOP3; + break; + + case IBS_STOP3: + (bb->set)(1, 1); + return 1; /* done */ + } + + return 0; /* keep going */ +} + +static int i2c_complete_synchronously(struct i2c_bitbang * bb) +{ + int ret = 0; + + while (!ret) { + ret = i2c_next_state(bb); + (bb->spin)(); + } + + return ret; +} + +int i2c_read_sync(struct i2c_bitbang * bb, unsigned char ads7, + unsigned char reg) +{ + i2c_read(bb, ads7, reg); + if (i2c_complete_synchronously(bb) < 0) + return -1; + + return bb->data[0]; +} + +void i2c_write_sync(struct i2c_bitbang * bb, unsigned char ads7, + unsigned char reg, unsigned char b) +{ + i2c_write(bb, ads7, reg, b); + i2c_complete_synchronously(bb); +} diff --git a/qiboot/src/gta02/gta02.c b/qiboot/src/gta02/gta02.c index b74b727..8bdcaa9 100644 --- a/qiboot/src/gta02/gta02.c +++ b/qiboot/src/gta02/gta02.c @@ -37,8 +37,10 @@ static const struct board_variant board_variants[] = { } }; + void port_init_gta02(void) { + //CAUTION:Follow the configuration order for setting the ports. // 1) setting value(GPnDAT) // 2) setting control register (GPnCON) From 666089cd0a21265dc94c60a07907ff6e90dc0e3d Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:36 +0000 Subject: [PATCH 053/248] add-gta02-400MHz.patch Add the i2c stuff to set GTA02 PMU to 1.3V core voltage, and push the cpu into 400MHz. Signed-off-by: Andy Green --- qiboot/src/gta02/gta02.c | 47 ++++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/qiboot/src/gta02/gta02.c b/qiboot/src/gta02/gta02.c index 8bdcaa9..17c7338 100644 --- a/qiboot/src/gta02/gta02.c +++ b/qiboot/src/gta02/gta02.c @@ -25,6 +25,9 @@ #include #include +#include + +#define PCF50633_I2C_ADS 0x73 static const struct board_variant board_variants[] = { [0] = { @@ -40,13 +43,16 @@ static const struct board_variant board_variants[] = { void port_init_gta02(void) { + unsigned int * MPLLCON = (unsigned int *)0x4c000004; + unsigned int * UPLLCON = (unsigned int *)0x4c000008; + unsigned int * CLKDIVN = (unsigned int *)0x4c000014; - //CAUTION:Follow the configuration order for setting the ports. - // 1) setting value(GPnDAT) - // 2) setting control register (GPnCON) - // 3) configure pull-up resistor(GPnUP) + //CAUTION:Follow the configuration order for setting the ports. + // 1) setting value(GPnDAT) + // 2) setting control register (GPnCON) + // 3) configure pull-up resistor(GPnUP) - /* 32bit data bus configuration */ + /* 32bit data bus configuration */ /* * === PORT A GROUP * Ports : GPA22 GPA21 GPA20 GPA19 GPA18 GPA17 GPA16 GPA15 GPA14 GPA13 GPA12 @@ -151,7 +157,34 @@ void port_init_gta02(void) rGPJDAT |= (1 << 5); /* Set GPJ5 to high 3D RST */ - serial_init(UART2, 0x11); + + /* + * We have to talk to the PMU a little bit + */ + + /* push DOWN1 (CPU Core rail) to 1.3V, allowing 400MHz */ + i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, 0x1e, 0x1b); + + /* 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); + + serial_init(UART2, (((54 * 50) + 50) / 100) -1); } /** @@ -254,7 +287,7 @@ const struct board_api board_api_gta02 = { "rootfstype=jffs2 " \ "root=/dev/mtdblock6 " \ "console=ttySAC2,115200 " \ - "loglevel=4 " \ + "loglevel=8 " \ "init=/sbin/init "\ "ro" }, From 9eba09a86f1f7c1703f5c77f715be1f8ee4787b7 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:36 +0000 Subject: [PATCH 054/248] clean-serial-c-into-drivers.patch Move serial.c into drivers/serial-s3c24xx.c and qi-serial.h into include/serial-s3c24xx.h making things a bit cleaner for being s3c24xx-specific. This needed a lot of meddling additionally, ending up with a new puts() callback that belongs in the board structure and removal of the debug uart member, since the puts() action was the only user. Also change serial init API name and function to only fix to 115kbps and adapt to PCLK. Signed-off-by: Andy Green --- qiboot/include/ports-s3c24xx.h | 41 ++++++++++++++++ qiboot/include/qi.h | 3 +- .../include/{qi-serial.h => serial-s3c24xx.h} | 49 ++----------------- qiboot/src/drivers/i2c-bitbang-s3c24xx.c | 1 + .../{serial.c => drivers/serial-s3c24xx.c} | 13 ++--- qiboot/src/gta02/gta02.c | 15 ++++-- qiboot/src/gta03/gta03.c | 19 ++++++- qiboot/src/nand_read.c | 20 +------- qiboot/src/qi.lds | 12 ++--- qiboot/src/utils.c | 14 +++--- 10 files changed, 99 insertions(+), 88 deletions(-) create mode 100644 qiboot/include/ports-s3c24xx.h rename qiboot/include/{qi-serial.h => serial-s3c24xx.h} (67%) rename qiboot/src/{serial.c => drivers/serial-s3c24xx.c} (85%) diff --git a/qiboot/include/ports-s3c24xx.h b/qiboot/include/ports-s3c24xx.h new file mode 100644 index 0000000..e784d85 --- /dev/null +++ b/qiboot/include/ports-s3c24xx.h @@ -0,0 +1,41 @@ +#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 diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index c4094d0..b168ae7 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -22,7 +22,6 @@ #define __QI_H__ #include -#include #include #define u32 unsigned int @@ -62,7 +61,6 @@ struct board_variant { struct board_api { const char * name; - int debug_serial_port; int linux_machine_id; unsigned long linux_mem_start; unsigned long linux_mem_size; @@ -70,6 +68,7 @@ struct board_api { const struct board_variant const * (*get_board_variant)(void); int (*is_this_board)(void); void (*port_init)(void); + void (*putc)(char); struct kernel_source kernel_source[8]; }; diff --git a/qiboot/include/qi-serial.h b/qiboot/include/serial-s3c24xx.h similarity index 67% rename from qiboot/include/qi-serial.h rename to qiboot/include/serial-s3c24xx.h index d674178..6209401 100644 --- a/qiboot/include/qi-serial.h +++ b/qiboot/include/serial-s3c24xx.h @@ -21,8 +21,8 @@ */ -#ifndef __SERIAL_H__ -#define __SERIAL_H__ +#ifndef __SERIAL_S3C24XX_H__ +#define __SERIAL_S3C24XX_H__ #define UART0 0 #define UART1 1 @@ -65,47 +65,8 @@ #define WrUTXH2(ch) (*(volatile unsigned char *)0x50008020)=(unsigned char)(ch) #define RdURXH2() (*(volatile unsigned char *)0x50008024) - - -// 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 - -void serial_init(const int uart, const int ubrdiv_val); -void serial_putc(const int uart, const char c); -int printk(const char *fmt, ...); -int puts(const char *string); +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 diff --git a/qiboot/src/drivers/i2c-bitbang-s3c24xx.c b/qiboot/src/drivers/i2c-bitbang-s3c24xx.c index 353dedc..f71dfc4 100644 --- a/qiboot/src/drivers/i2c-bitbang-s3c24xx.c +++ b/qiboot/src/drivers/i2c-bitbang-s3c24xx.c @@ -23,6 +23,7 @@ #include #include +#include static char i2c_read_sda_s3c24xx(void) { diff --git a/qiboot/src/serial.c b/qiboot/src/drivers/serial-s3c24xx.c similarity index 85% rename from qiboot/src/serial.c rename to qiboot/src/drivers/serial-s3c24xx.c index 61b4762..206f0a1 100644 --- a/qiboot/src/serial.c +++ b/qiboot/src/drivers/serial-s3c24xx.c @@ -21,10 +21,11 @@ */ #include -#include "blink_led.h" +#include -void serial_init (const int uart, const int ubrdiv_val) +void serial_init_115200_s3c24xx(const int uart, const int pclk_MHz) { + int div = (((54 * pclk_MHz) + (pclk_MHz / 2)) / 100) -1; switch(uart) { case UART0: @@ -32,20 +33,20 @@ void serial_init (const int uart, const int ubrdiv_val) rUCON0 = 0x245; rUFCON0 = 0x0; rUMCON0 = 0x0; - rUBRDIV0 = ubrdiv_val; + rUBRDIV0 = div; break; case UART1: rULCON1 = 0x3; rUCON1 = 0x245; rUFCON1 = 0x0; rUMCON1 = 0x0; - rUBRDIV1 = ubrdiv_val; + rUBRDIV1 = div; break; case UART2: rULCON2 = 0x3; rUCON2 = 0x245; rUFCON2 = 0x1; - rUBRDIV2 = ubrdiv_val; + rUBRDIV2 = div; break; default: break; @@ -54,7 +55,7 @@ void serial_init (const int uart, const int ubrdiv_val) /* * Output a single byte to the serial port. */ -void serial_putc (const int uart, const char c) +void serial_putc_s3c24xx(const int uart, const char c) { switch(uart) { diff --git a/qiboot/src/gta02/gta02.c b/qiboot/src/gta02/gta02.c index 17c7338..6a2516d 100644 --- a/qiboot/src/gta02/gta02.c +++ b/qiboot/src/gta02/gta02.c @@ -25,8 +25,12 @@ #include #include +#include +#include #include +#define GTA02_DEBUG_UART 2 + #define PCF50633_I2C_ADS 0x73 static const struct board_variant board_variants[] = { @@ -180,11 +184,11 @@ void port_init_gta02(void) "nop\n"\ "nop\n"\ "nop\n"\ - ); + ); /* configure MPLL */ *MPLLCON = ((42 << 12) + (1 << 4) + 0); - serial_init(UART2, (((54 * 50) + 50) / 100) -1); + serial_init_115200_s3c24xx(GTA02_DEBUG_UART, 50 /* 50MHz PCLK */); } /** @@ -254,13 +258,17 @@ const struct board_variant const * get_board_variant_gta02(void) return &board_variants[gta02_get_pcb_revision()]; } +static void putc_gta02(char c) +{ + serial_putc_s3c24xx(GTA02_DEBUG_UART, c); +} + /* * our API for bootloader on this machine */ const struct board_api board_api_gta02 = { .name = "Freerunner / GTA02", - .debug_serial_port = 2, .linux_machine_id = 1304, .linux_mem_start = 0x30000000, .linux_mem_size = (128 * 1024 * 1024), @@ -268,6 +276,7 @@ const struct board_api board_api_gta02 = { .get_board_variant = get_board_variant_gta02, .is_this_board = is_this_board_gta02, .port_init = port_init_gta02, + .putc = putc_gta02, /* these are the ways we could boot GTA02 in order to try */ .kernel_source = { [0] = { diff --git a/qiboot/src/gta03/gta03.c b/qiboot/src/gta03/gta03.c index 1a2c00b..1738856 100644 --- a/qiboot/src/gta03/gta03.c +++ b/qiboot/src/gta03/gta03.c @@ -1,5 +1,13 @@ #include #include +#include +#include +#include + +#define GTA03_DEBUG_UART 2 + +#define PCF50633_I2C_ADS 0x73 + static const struct board_variant board_variants[] = { [0] = { @@ -108,7 +116,7 @@ void port_init_gta03(void) rGPJCON = 0x02AAAAAA; rGPJUP = 0x1FFFF; - serial_init(UART2, 0x11); + serial_init_115200_s3c24xx(GTA03_DEBUG_UART, 33 /*MHz PCLK */); } /** @@ -161,12 +169,18 @@ int is_this_board_gta03(void) /* FIXME: find something gta03 specific */ return 1; } + +static void putc_gta03(char c) +{ + serial_putc_s3c24xx(GTA03_DEBUG_UART, c); +} + + /* * our API for bootloader on this machine */ const struct board_api board_api_gta03 = { .name = "GTA03", - .debug_serial_port = 2, .linux_machine_id = 1808, .linux_mem_start = 0x30000000, .linux_mem_size = (128 * 1024 * 1024), @@ -174,6 +188,7 @@ const struct board_api board_api_gta03 = { .get_board_variant = get_board_variant_gta03, .is_this_board = is_this_board_gta03, .port_init = port_init_gta03, + .putc = putc_gta03, /* these are the ways we could boot GTA03 in order to try */ .kernel_source = { [0] = { diff --git a/qiboot/src/nand_read.c b/qiboot/src/nand_read.c index 6351173..94bf839 100644 --- a/qiboot/src/nand_read.c +++ b/qiboot/src/nand_read.c @@ -71,13 +71,6 @@ static int is_bad_block(unsigned long i) NFCMD = NAND_CMD_READSTART; nand_wait(); data = (NFDATA & 0xff); -#ifdef DEBUG - serial_putc(2, '$'); - serial_putc(2, '0'); - serial_putc(2, 'x'); - print32((unsigned int)data); - serial_putc(2, ' '); -#endif if (data != 0xff) return 1; @@ -138,20 +131,11 @@ int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size) if ((i & (NAND_BLOCK_SIZE - 1)) == 0) { if (is_bad_block(i) || is_bad_block(i + NAND_PAGE_SIZE)) { - serial_putc(2, '!'); - serial_putc(2, '0'); - serial_putc(2, 'x'); - print32((unsigned int)i); - serial_putc(2, ' '); - i += NAND_BLOCK_SIZE; size += NAND_BLOCK_SIZE; - if (bad_count++ == 4) { - serial_putc(2, '+'); - serial_putc(2, '\n'); + if (bad_count++ == 4) return -1; - } - serial_putc(2, '\n'); + continue; } } diff --git a/qiboot/src/qi.lds b/qiboot/src/qi.lds index 29ec63f..bdc1d2c 100644 --- a/qiboot/src/qi.lds +++ b/qiboot/src/qi.lds @@ -37,12 +37,12 @@ SECTIONS . = ALIGN(4); .text : { - src/start.o (.text .rodata* .data) - src/lowlevel_init.o (.text .rodata* .data) - src/start_qi.o (.text .rodata* .data) - src/blink_led.o (.text .rodata* .data) - src/nand_read.o (.text .rodata* .data) - src/serial.o (.text .rodata* .data) + src/start.o (.text .rodata* .data) + src/lowlevel_init.o (.text .rodata* .data) + src/start_qi.o (.text .rodata* .data) + src/blink_led.o (.text .rodata* .data) + src/nand_read.o (.text .rodata* .data) + src/drivers/serial-s3c24xx.o (.text .rodata* .data) } . = ALIGN(4); diff --git a/qiboot/src/utils.c b/qiboot/src/utils.c index ccc14b4..5c945a8 100644 --- a/qiboot/src/utils.c +++ b/qiboot/src/utils.c @@ -57,7 +57,7 @@ unsigned int _ntohl(unsigned int n) { int puts(const char *string) { while (*string) - serial_putc(this_board->debug_serial_port, *string++); + this_board->putc(*string++); return 1; } @@ -66,9 +66,9 @@ int puts(const char *string) void printnybble(unsigned char n) { if (n < 10) - serial_putc(this_board->debug_serial_port, '0' + n); + this_board->putc('0' + n); else - serial_putc(this_board->debug_serial_port, 'a' + n - 10); + this_board->putc('a' + n - 10); } void printhex(unsigned char n) @@ -91,13 +91,13 @@ void hexdump(unsigned char *start, int len) while (len > 0) { print32((int)start); - serial_putc(this_board->debug_serial_port, ':'); - serial_putc(this_board->debug_serial_port, ' '); + this_board->putc(':'); + this_board->putc(' '); for (n = 0; n < 16; n++) { printhex(*start++); - serial_putc(this_board->debug_serial_port, ' '); + this_board->putc(' '); } - serial_putc(this_board->debug_serial_port, '\n'); + this_board->putc('\n'); len -= 16; } } From d593873938cfaca988f53681295e7605b6507d60 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:36 +0000 Subject: [PATCH 055/248] add-gta02-bring-sd-card-power-up.patch Power up the SD Card rail getting ready to start talking to that Signed-off-by: Andy Green --- qiboot/src/gta02/gta02.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/qiboot/src/gta02/gta02.c b/qiboot/src/gta02/gta02.c index 6a2516d..0185349 100644 --- a/qiboot/src/gta02/gta02.c +++ b/qiboot/src/gta02/gta02.c @@ -166,6 +166,12 @@ void port_init_gta02(void) * We have to talk to the PMU a little bit */ + /* We need SD Card rail (HCLDO) at 3.0V */ + i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, 0x39, 21); + + /* switch HCLDO on */ + i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, 0x3a, 1); + /* push DOWN1 (CPU Core rail) to 1.3V, allowing 400MHz */ i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, 0x1e, 0x1b); @@ -189,6 +195,7 @@ void port_init_gta02(void) *MPLLCON = ((42 << 12) + (1 << 4) + 0); serial_init_115200_s3c24xx(GTA02_DEBUG_UART, 50 /* 50MHz PCLK */); + } /** From 33ee0f3ae43b10d7e24577ee9d94ce81b7f1adb3 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:36 +0000 Subject: [PATCH 056/248] add-gta03-pmu-533MHz-init.patch Get GTA03 into 533MHz / 133MHz memory bus goodness Signed-off-by: Andy Green --- qiboot/src/gta03/gta03.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/qiboot/src/gta03/gta03.c b/qiboot/src/gta03/gta03.c index 1738856..cd00731 100644 --- a/qiboot/src/gta03/gta03.c +++ b/qiboot/src/gta03/gta03.c @@ -18,6 +18,10 @@ static const struct board_variant board_variants[] = { void port_init_gta03(void) { + unsigned int * MPLLCON = (unsigned int *)0x4c000004; + unsigned int * UPLLCON = (unsigned int *)0x4c000008; + unsigned int * CLKDIVN = (unsigned int *)0x4c000014; + //CAUTION:Follow the configuration order for setting the ports. // 1) setting value(GPnDAT) // 2) setting control register (GPnCON) @@ -116,7 +120,34 @@ void port_init_gta03(void) rGPJCON = 0x02AAAAAA; rGPJUP = 0x1FFFF; - serial_init_115200_s3c24xx(GTA03_DEBUG_UART, 33 /*MHz PCLK */); + /* + * We have to talk to the PMU a little bit + */ + + /* push DOWN1 (CPU Core rail) to 1.7V, allowing 533MHz */ + i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, 0x1e, 0x2b); + + /* change CPU clocking to 533MHz 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 = ((169 << 12) + (2 << 4) + 1); + + + serial_init_115200_s3c24xx(GTA03_DEBUG_UART, 50 /*MHz PCLK */); } /** From 674a6a836ab35d06d87e6d6a46d8929e68eda0c3 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:36 +0000 Subject: [PATCH 057/248] add-gta03-bring-sd-card-power-up.patch Signed-off-by: Andy Green --- qiboot/src/gta03/gta03.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/qiboot/src/gta03/gta03.c b/qiboot/src/gta03/gta03.c index cd00731..7f88ba8 100644 --- a/qiboot/src/gta03/gta03.c +++ b/qiboot/src/gta03/gta03.c @@ -124,6 +124,12 @@ void port_init_gta03(void) * We have to talk to the PMU a little bit */ + /* We need SD Card rail (HCLDO) at 3.0V */ + i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, 0x39, 21); + + /* switch HCLDO on */ + i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, 0x3a, 1); + /* push DOWN1 (CPU Core rail) to 1.7V, allowing 533MHz */ i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, 0x1e, 0x2b); From ee7de6d4abfea6d62d1c026e78482f1cf523059e Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:36 +0000 Subject: [PATCH 058/248] add-pcf50633-include.patch Bring over pcf50633.h register definitions from U-Boot and use them Signed-off-by: Andy Green --- qiboot/include/pcf50633.h | 387 ++++++++++++++++++++++++++++++++++++++ qiboot/src/gta02/gta02.c | 9 +- qiboot/src/gta03/gta03.c | 9 +- 3 files changed, 399 insertions(+), 6 deletions(-) create mode 100644 qiboot/include/pcf50633.h diff --git a/qiboot/include/pcf50633.h b/qiboot/include/pcf50633.h new file mode 100644 index 0000000..73e233a --- /dev/null +++ b/qiboot/include/pcf50633.h @@ -0,0 +1,387 @@ +#ifndef _PCF50633_H +#define _PCF50633_H + +/* Philips PCF50633 Power Managemnt Unit (PMU) driver + * (C) 2006-2007 by OpenMoko, Inc. + * Author: Harald Welte + * + */ + +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) */ +}; + +#endif /* _PCF50633_H */ + diff --git a/qiboot/src/gta02/gta02.c b/qiboot/src/gta02/gta02.c index 0185349..ce08fe5 100644 --- a/qiboot/src/gta02/gta02.c +++ b/qiboot/src/gta02/gta02.c @@ -28,6 +28,7 @@ #include #include #include +#include #define GTA02_DEBUG_UART 2 @@ -167,13 +168,15 @@ void port_init_gta02(void) */ /* We need SD Card rail (HCLDO) at 3.0V */ - i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, 0x39, 21); + i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_HCLDOOUT, + 21); /* switch HCLDO on */ - i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, 0x3a, 1); + i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_HCLDOENA, 1); /* push DOWN1 (CPU Core rail) to 1.3V, allowing 400MHz */ - i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, 0x1e, 0x1b); + i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_DOWN1OUT, + 0x1b); /* change CPU clocking to 400MHz 1:4:8 */ diff --git a/qiboot/src/gta03/gta03.c b/qiboot/src/gta03/gta03.c index 7f88ba8..f99ecae 100644 --- a/qiboot/src/gta03/gta03.c +++ b/qiboot/src/gta03/gta03.c @@ -3,6 +3,7 @@ #include #include #include +#include #define GTA03_DEBUG_UART 2 @@ -125,13 +126,15 @@ void port_init_gta03(void) */ /* We need SD Card rail (HCLDO) at 3.0V */ - i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, 0x39, 21); + i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_HCLDOOUT, + 21); /* switch HCLDO on */ - i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, 0x3a, 1); + i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_HCLDOENA, 1); /* push DOWN1 (CPU Core rail) to 1.7V, allowing 533MHz */ - i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, 0x1e, 0x2b); + i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_DOWN1OUT, + 0x2b); /* change CPU clocking to 533MHz 1:4:8 */ From 9759d4e910608a2e6af8c4be96c0da82e866f4d7 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:36 +0000 Subject: [PATCH 059/248] add-glamo-init.patch We have to init PLLs and memory and other assets in Glamo before we can use SD Card stuff. Signed-off-by: Andy Green --- qiboot/include/glamo-init.h | 1 + qiboot/include/glamo_regs.h | 459 ++++++++++++++++++++++++++++++++ qiboot/src/drivers/glamo-init.c | 103 +++++++ qiboot/src/gta02/gta02.c | 7 + 4 files changed, 570 insertions(+) create mode 100644 qiboot/include/glamo-init.h create mode 100644 qiboot/include/glamo_regs.h create mode 100644 qiboot/src/drivers/glamo-init.c diff --git a/qiboot/include/glamo-init.h b/qiboot/include/glamo-init.h new file mode 100644 index 0000000..ca43d8a --- /dev/null +++ b/qiboot/include/glamo-init.h @@ -0,0 +1 @@ +extern void glamo_core_init(void); diff --git a/qiboot/include/glamo_regs.h b/qiboot/include/glamo_regs.h new file mode 100644 index 0000000..b85a051 --- /dev/null +++ b/qiboot/include/glamo_regs.h @@ -0,0 +1,459 @@ +#ifndef _GLAMO_REGS_H +#define _GLAMO_REGS_H + +/* Smedia Glamo 336x/337x driver + * + * (C) 2007 by OpenMoko, Inc. + * Author: Harald Welte + * 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, +}; + + +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, +}; + +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_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, +}; + + +#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), +}; + +enum glamo_irq { + GLAMO_IRQ_HOSTBUS = 0x0001, + GLAMO_IRQ_JPEG = 0x0002, + GLAMO_IRQ_MPEG = 0x0004, + GLAMO_IRQ_MPROC1 = 0x0008, + GLAMO_IRQ_MPROC0 = 0x0010, + GLAMO_IRQ_CMDQUEUE = 0x0020, + GLAMO_IRQ_2D = 0x0040, + GLAMO_IRQ_MMC = 0x0080, + GLAMO_IRQ_RISC = 0x0100, +}; + +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_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_3d { + GLAMO_CLOCK_3D_DG_GCLK = 0x0001, + GLAMO_CLOCK_3D_EN_GCLK = 0x0002, + GLAMO_CLOCK_3D_DG_M7CLK = 0x0004, + GLAMO_CLOCK_3D_EN_M7CLK = 0x0008, + GLAMO_CLOCK_3D_DG_M6CLK = 0x0010, + GLAMO_CLOCK_3D_EN_M6CLK = 0x0020, + GLAMO_CLOCK_3D_2D_RESET = 0x1000, + GLAMO_CLOCK_3D_CQ_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, +}; + +/* 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_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_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, +}; + +#endif /* _GLAMO_REGS_H */ diff --git a/qiboot/src/drivers/glamo-init.c b/qiboot/src/drivers/glamo-init.c new file mode 100644 index 0000000..c9c0c8c --- /dev/null +++ b/qiboot/src/drivers/glamo-init.c @@ -0,0 +1,103 @@ +/* + * (C) Copyright 2007 by OpenMoko, Inc. + * Author: Harald Welte + * Andy Green + * + * 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 +#include + +#define GLAMO_REG(x) (*(volatile unsigned short *)(0x08000000 + x)) + +static void glamo_reg_write(u16 reg, u16 val) +{ + GLAMO_REG(reg) = val; +} + +static u16 glamo_reg_read(u16 reg) +{ + return GLAMO_REG(reg); +} + + +static u16 u16a_gen_init_0x0000[] = { + 0x2020, 0x3650, 0x0002, 0x01FF, 0x0000, 0x0000, 0x0000, 0x0000, + 0x000D, 0x000B, 0x00EE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1839, 0x0000, 0x2000, 0x0001, 0x0100, 0x0000, 0x0000, 0x0000, + 0x05DB, 0x5231, 0x09C3, 0x8261, 0x0003, 0x0000, 0x0000, 0x0000, + 0x000F, 0x101E, 0xC0C3, 0x101E, 0x000F, 0x0001, 0x030F, 0x020F, + 0x080F, 0x0F0F +}; + +static u16 u16a_gen_init_0x0200[] = { + 0x0EF0, 0x07FF, 0x0000, 0x0080, 0x0344, 0x0600, 0x0000, 0x0000, + 0x0000, 0x0000, 0x4000, 0xF00E, 0x00C0, 0x00C0, 0x00C0, 0x00C0, + 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, + 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, + 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, + 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, + 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, + 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, + 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, + 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, + 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, + 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, + 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, + 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, + 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, + 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, + 0x0873, 0xAFAF, 0x0108, 0x0010, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x1002, 0x6006, 0x00FF, 0x0001, 0x0020, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x3210, 0x5432, 0xE100, 0x01D6 +}; + + +void glamo_core_init(void) +{ + int bp; + + /* power up PLL1 and PLL2 */ + glamo_reg_write(GLAMO_REG_PLL_GEN7, 0x0000); + glamo_reg_write(GLAMO_REG_PLL_GEN3, 0x0400); + + /* enable memory clock and get it out of deep pwrdown */ + glamo_reg_write(GLAMO_REG_CLOCK_MEMORY, + glamo_reg_read(GLAMO_REG_CLOCK_MEMORY) | 8); + glamo_reg_write(GLAMO_REG_MEM_DRAM2, + glamo_reg_read(GLAMO_REG_MEM_DRAM2) & (~(1 << 12))); + glamo_reg_write(GLAMO_REG_MEM_DRAM1, + glamo_reg_read(GLAMO_REG_MEM_DRAM1) & (~(1 << 12))); + /* + * we just fill up the general hostbus and LCD register sets + * with magic values taken from the Linux framebuffer init action + */ + for (bp = 0; bp < ARRAY_SIZE(u16a_gen_init_0x0000); bp++) + glamo_reg_write(0x0 | (bp << 1), + u16a_gen_init_0x0000[bp]); + + for (bp = 0; bp < ARRAY_SIZE(u16a_gen_init_0x0200); bp++) + glamo_reg_write(0x200 | (bp << 1), + u16a_gen_init_0x0200[bp]); + + /* spin until PLL1 lock */ + while (!(glamo_reg_read(GLAMO_REG_PLL_GEN5) & 1)) + ; +} + diff --git a/qiboot/src/gta02/gta02.c b/qiboot/src/gta02/gta02.c index ce08fe5..00175a4 100644 --- a/qiboot/src/gta02/gta02.c +++ b/qiboot/src/gta02/gta02.c @@ -29,6 +29,7 @@ #include #include #include +#include #define GTA02_DEBUG_UART 2 @@ -197,6 +198,12 @@ void port_init_gta02(void) /* configure MPLL */ *MPLLCON = ((42 << 12) + (1 << 4) + 0); + /* we're going to use Glamo for SD Card access, so we need to init the + * evil beast + */ + glamo_core_init(); + + /* get debug UART working at 115kbps */ serial_init_115200_s3c24xx(GTA02_DEBUG_UART, 50 /* 50MHz PCLK */); } From fdd6c5544b76968e8fcfb679ad78d0560069b3f9 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:37 +0000 Subject: [PATCH 060/248] add-glmo-mmc.patch Moves various .h into include from drivers Gets glamo-mmc.h working so we can detect card ID / Size if the card is plugged in. Adds FAT / MMC kernel source entry for GTA02 that is first before the NAND one. When it works it will favour to boot off SD Card if a kernel is found there, but right now we don't have a working filesystem parser and partition handling hooked up. Signed-off-by: Andy Green --- qiboot/{src/drivers => include}/glamo-mmc.h | 18 +- qiboot/{src/drivers => include}/glamo-regs.h | 4 +- qiboot/include/glamo_regs.h | 459 ------------------- qiboot/include/mmc.h | 110 +++++ qiboot/include/qi.h | 1 + qiboot/src/drivers/glamo-mmc.c | 208 ++++----- qiboot/src/gta02/gta02.c | 33 +- qiboot/src/utils.c | 12 +- 8 files changed, 242 insertions(+), 603 deletions(-) rename qiboot/{src/drivers => include}/glamo-mmc.h (94%) rename qiboot/{src/drivers => include}/glamo-regs.h (99%) delete mode 100644 qiboot/include/glamo_regs.h create mode 100644 qiboot/include/mmc.h diff --git a/qiboot/src/drivers/glamo-mmc.h b/qiboot/include/glamo-mmc.h similarity index 94% rename from qiboot/src/drivers/glamo-mmc.h rename to qiboot/include/glamo-mmc.h index 3f2294c..48e8161 100644 --- a/qiboot/src/drivers/glamo-mmc.h +++ b/qiboot/include/glamo-mmc.h @@ -122,19 +122,19 @@ struct sd_cid { char pnm_0; /* product name */ char oid_1; /* OEM/application ID */ char oid_0; - uint8_t mid; /* manufacturer ID */ + u8 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 */ + 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 { diff --git a/qiboot/src/drivers/glamo-regs.h b/qiboot/include/glamo-regs.h similarity index 99% rename from qiboot/src/drivers/glamo-regs.h rename to qiboot/include/glamo-regs.h index 8f6c45c..bfc3919 100644 --- a/qiboot/src/drivers/glamo-regs.h +++ b/qiboot/include/glamo-regs.h @@ -98,8 +98,8 @@ enum glamo_register_generic { GLAMO_REG_DFT_GEN3 = 0x0074, GLAMO_REG_DFT_GEN4 = 0x0076, - GLAMO_REG_DFT_GEN5 = 0x01e0, - GLAMO_REG_DFT_GEN6 = 0x01f0, + GLAMO_REG_PLL_GEN6 = 0x01e0, + GLAMO_REG_PLL_GEN7 = 0x01f0, }; #define GLAMO_REG_HOSTBUS(x) (GLAMO_REGOFS_HOSTBUS-2+(x*2)) diff --git a/qiboot/include/glamo_regs.h b/qiboot/include/glamo_regs.h deleted file mode 100644 index b85a051..0000000 --- a/qiboot/include/glamo_regs.h +++ /dev/null @@ -1,459 +0,0 @@ -#ifndef _GLAMO_REGS_H -#define _GLAMO_REGS_H - -/* Smedia Glamo 336x/337x driver - * - * (C) 2007 by OpenMoko, Inc. - * Author: Harald Welte - * 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, -}; - - -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, -}; - -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_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, -}; - - -#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), -}; - -enum glamo_irq { - GLAMO_IRQ_HOSTBUS = 0x0001, - GLAMO_IRQ_JPEG = 0x0002, - GLAMO_IRQ_MPEG = 0x0004, - GLAMO_IRQ_MPROC1 = 0x0008, - GLAMO_IRQ_MPROC0 = 0x0010, - GLAMO_IRQ_CMDQUEUE = 0x0020, - GLAMO_IRQ_2D = 0x0040, - GLAMO_IRQ_MMC = 0x0080, - GLAMO_IRQ_RISC = 0x0100, -}; - -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_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_3d { - GLAMO_CLOCK_3D_DG_GCLK = 0x0001, - GLAMO_CLOCK_3D_EN_GCLK = 0x0002, - GLAMO_CLOCK_3D_DG_M7CLK = 0x0004, - GLAMO_CLOCK_3D_EN_M7CLK = 0x0008, - GLAMO_CLOCK_3D_DG_M6CLK = 0x0010, - GLAMO_CLOCK_3D_EN_M6CLK = 0x0020, - GLAMO_CLOCK_3D_2D_RESET = 0x1000, - GLAMO_CLOCK_3D_CQ_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, -}; - -/* 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_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_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, -}; - -#endif /* _GLAMO_REGS_H */ diff --git a/qiboot/include/mmc.h b/qiboot/include/mmc.h new file mode 100644 index 0000000..1a81f2a --- /dev/null +++ b/qiboot/include/mmc.h @@ -0,0 +1,110 @@ +/* + * 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__ */ diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index b168ae7..17fafe7 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -80,6 +80,7 @@ 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 hexdump(unsigned char *start, int len); unsigned int _ntohl(unsigned int n); diff --git a/qiboot/src/drivers/glamo-mmc.c b/qiboot/src/drivers/glamo-mmc.c index b010235..c8d43bd 100644 --- a/qiboot/src/drivers/glamo-mmc.c +++ b/qiboot/src/drivers/glamo-mmc.c @@ -25,22 +25,15 @@ * published by the Free Software Foundation. */ -#if 0 - -#include -#include +#include #include -#include -#include -#include -#include -#include -#include "glamo-regs.h" -#include "glamo-mmc.h" +#include +#include + +#define CONFIG_GLAMO_BASE 0x08000000 #define MMC_BLOCK_SIZE_BITS 9 -#define MMC_BLOCK_SIZE (1 << MMC_BLOCK_SIZE_BITS) #define GLAMO_REG(x) (*(volatile u16 *)(CONFIG_GLAMO_BASE + x)) #define GLAMO_INTRAM_OFFSET (8 * 1024 * 1024) @@ -49,25 +42,29 @@ GLAMO_INTRAM_OFFSET + GLAMO_FB_SIZE)) static int ccnt; -static block_dev_desc_t mmc_dev; -static mmc_csd_t mmc_csd; +//static mmc_csd_t mmc_csd; static int mmc_ready = 0; -static int wide = 0; +//static int wide = 0; static enum card_type card_type = CARDTYPE_NONE; -block_dev_desc_t * mmc_get_dev(int dev) +int mmc_read(unsigned long src, u8 *dst, int size); + +int q; + +void udelay(int n) { - return (block_dev_desc_t *)&mmc_dev; + while (n--) + q+=n * q; } static void -glamo_reg_write(u_int16_t val, u_int16_t reg) +glamo_reg_write(u16 val, u16 reg) { GLAMO_REG(reg) = val; } -static u_int16_t -glamo_reg_read(u_int16_t reg) +static u16 +glamo_reg_read(u16 reg) { return GLAMO_REG(reg); } @@ -89,9 +86,10 @@ unsigned char CRC7(u8 * pu8, int cnt) return (crc << 1) | 1; } -ulong mmc_bread(int dev_num, ulong blknr, ulong blkcnt, void *dst) +unsigned long mmc_bread(int dev_num, unsigned long blknr, unsigned long blkcnt, + void *dst) { - ulong src = blknr * MMC_BLOCK_SIZE; + unsigned long src = blknr * MMC_BLOCK_SIZE; if (!blkcnt) return 0; @@ -103,7 +101,7 @@ ulong mmc_bread(int dev_num, ulong blknr, ulong blkcnt, void *dst) /* 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; +static u16 rca = MMC_DEFAULT_RCA >> 16; static void do_pio_read(u16 *buf, int count_words) { @@ -160,7 +158,7 @@ static int mmc_cmd(int opcode, int arg, int flags, GLAMO_REGOFS_MMC + GLAMO_REG_MMC_WDATADS1); glamo_reg_write((u16)(GLAMO_FB_SIZE >> 16), GLAMO_REGOFS_MMC + GLAMO_REG_MMC_WDATADS2); - glamo_reg_write((u16)GLAMO_FB_SIZE, + glamo_reg_write((u16)GLAMO_FB_/*SIZE*/, GLAMO_REGOFS_MMC + GLAMO_REG_MMC_RDATADS1); glamo_reg_write((u16)(GLAMO_FB_SIZE >> 16), GLAMO_REGOFS_MMC + GLAMO_REG_MMC_RDATADS2); @@ -318,8 +316,12 @@ static int mmc_cmd(int opcode, int arg, int flags, return 0; if (error) { - printf("cmd 0x%x, arg 0x%x flags 0x%x\n", opcode, arg, flags); - printf("Error after cmd: 0x%x\n", error); +// printf("cmd 0x%x, arg 0x%x flags 0x%x\n", opcode, arg, flags); +#if 0 + puts("Error after cmd: 0x"); + print32(error); + puts("\n"); +#endif goto done; } /* @@ -357,8 +359,12 @@ static int mmc_cmd(int opcode, int arg, int flags, if (status & GLAMO_STAT1_MMC_RTOUT) error = -5; if (error) { - printf("cmd 0x%x, arg 0x%x flags 0x%x\n", opcode, arg, flags); - printf("Error after resp: 0x%x\n", status); +// printf("cmd 0x%x, arg 0x%x flags 0x%x\n", opcode, arg, flags); +#if 0 + puts("Error after resp: 0x"); + print32(status); + puts("\n"); +#endif goto done; } #if 0 @@ -386,7 +392,6 @@ static void glamo_mci_reset(void) GLAMO_CLOCK_MMC_EN_TCLK | GLAMO_CLOCK_MMC_DG_M9CLK | GLAMO_CLOCK_MMC_EN_M9CLK, GLAMO_REG_CLOCK_MMC); - udelay(100000); /* and disable reset */ glamo_reg_write(GLAMO_CLOCK_MMC_DG_TCLK | GLAMO_CLOCK_MMC_EN_TCLK | GLAMO_CLOCK_MMC_DG_M9CLK | @@ -395,30 +400,21 @@ static void glamo_mci_reset(void) } -static u_int8_t ldo_voltage(unsigned int millivolts) -{ - if (millivolts < 900) - return 0; - else if (millivolts > 3600) - return 0x1f; - millivolts -= 900; - return millivolts / 100; -} - -int mmc_read(ulong src, uchar *dst, int size) +int mmc_read(unsigned long src, u8 *dst, int size) { int resp; u8 response[16]; int size_original = size; if ((!size) || (size & (MMC_BLOCK_SIZE - 1))) { - printf("Bad size %d\n", size); + puts("Bad size 0x"); + print32(size); return 0; } if (((int)dst) & 1) { - printf("Bad align on dst\n"); + puts("Bad align on dst\n"); return 0; } @@ -454,19 +450,20 @@ int mmc_read(ulong src, uchar *dst, int size) return size_original; } -int mmc_write(uchar *src, ulong dst, int size) +int mmc_write(u8 *src, unsigned long dst, int size) { int resp; u8 response[16]; int size_original = size; if ((!size) || (size & (MMC_BLOCK_SIZE - 1))) { - printf("Bad size %d\n", size); + puts("Bad size 0x"); + print32(size); return 0; } if (((int)dst) & 1) { - printf("Bad align on dst\n"); + puts("Bad align on dst\n"); return 0; } @@ -503,40 +500,46 @@ int mmc_write(uchar *src, ulong dst, int size) return size_original; } +#if 0 static void print_mmc_cid(mmc_cid_t *cid) { - printf("MMC found. Card desciption is:\n"); - printf("Manufacturer ID = %02x%02x%02x\n", - cid->id[0], cid->id[1], cid->id[2]); - printf("HW/FW Revision = %x %x\n",cid->hwrev, cid->fwrev); - cid->hwrev = cid->fwrev = 0; /* null terminate string */ - printf("Product Name = %s\n",cid->name); + puts("MMC found. Card desciption is:\n"); + puts("Manufacturer ID = "); + print8(cid->id[0]); + print8(cid->id[1]); + print8(cid->id[2]); +/* + puts("HW/FW Revision = %x %x\n",cid->hwrev, cid->fwrev); + cid->hwrev = cid->fwrev = 0; + puts("Product Name = %s\n",cid->name); printf("Serial Number = %02x%02x%02x\n", cid->sn[0], cid->sn[1], cid->sn[2]); printf("Month = %d\n",cid->month); printf("Year = %d\n",1997 + cid->year); +*/ } - +#endif static void print_sd_cid(const struct sd_cid *cid) { - printf("Card Type: "); + puts("Card Type: "); switch (card_type) { case CARDTYPE_NONE: - printf("(None)\n"); + puts("(None)\n"); break; case CARDTYPE_MMC: - printf("MMC\n"); + puts("MMC\n"); break; case CARDTYPE_SD: - printf("SD\n"); + puts("SD\n"); break; case CARDTYPE_SD20: - printf("SD 2.0\n"); + puts("SD 2.0\n"); break; case CARDTYPE_SDHC: - printf("SD 2.0 SDHC\n"); + puts("SD 2.0 SDHC\n"); break; } +#if 0 printf("Manufacturer: 0x%02x, OEM \"%c%c\"\n", cid->mid, cid->oid_0, cid->oid_1); printf("Product name: \"%c%c%c%c%c\", revision %d.%d\n", @@ -548,6 +551,7 @@ static void print_sd_cid(const struct sd_cid *cid) printf("Manufacturing date: %d/%d\n", cid->mdt_1 & 15, 2000+((cid->mdt_0 & 15) << 4)+((cid->mdt_1 & 0xf0) >> 4)); +#endif /* printf("CRC: 0x%02x, b0 = %d\n", cid->crc >> 1, cid->crc & 1); */ } @@ -555,11 +559,11 @@ static void print_sd_cid(const struct sd_cid *cid) int mmc_init(int verbose) { - int retries = 14, rc = -ENODEV; + int retries = 14, rc = -1; int resp; u8 response[16]; - mmc_cid_t *mmc_cid = (mmc_cid_t *)response; - struct sd_cid *sd_cid = (struct sd_cid *)response; +// mmc_cid_t *mmc_cid = (mmc_cid_t *)response; +// struct sd_cid *sd_cid = (struct sd_cid *)response; u32 hcs = 0; card_type = CARDTYPE_NONE; @@ -577,14 +581,6 @@ int mmc_init(int verbose) glamo_mci_reset(); - /* power the sdcard slot */ - - pcf50633_reg_write(PCF50633_REG_HCLDOOUT, ldo_voltage(3300)); - udelay(10000); - pcf50633_reg_write(PCF50633_REG_HCLDOOUT + 1, - pcf50633_reg_read(PCF50633_REG_HCLDOOUT + 1) | 1); /* on */ - udelay(10000); - /* start the clock -- slowly (50MHz / 250 == 195kHz */ glamo_reg_write((glamo_reg_read(GLAMO_REG_CLOCK_GEN8) & 0xff00) | 250, @@ -613,6 +609,7 @@ int mmc_init(int verbose) udelay(100000); udelay(100000); udelay(100000); + udelay(100000); /* SDHC card? */ @@ -629,6 +626,7 @@ int mmc_init(int verbose) while (retries--) { udelay(100000); + udelay(100000); resp = mmc_cmd(MMC_APP_CMD, 0x00000000, MMC_CMD_AC | MMC_RSP_R1, 0, 0, 0, @@ -650,17 +648,18 @@ int mmc_init(int verbose) break; } } - if (retries < 0) + if (retries < 0) { + puts("no response\n"); return 1; + } if (card_type == CARDTYPE_NONE) { retries = 10; - printf("failed to detect SD Card, trying MMC\n"); + puts("failed to detect SD Card, trying MMC\n"); do { resp = mmc_cmd(MMC_SEND_OP_COND, 0x00ffc000, MMC_CMD_BCR | MMC_RSP_R3, 0, 0, 0, (u16 *)&response[0]); - debug("resp %x %x\n", response[0], response[1]); udelay(50); } while (retries-- && !(response[3] & 0x80)); if (retries >= 0) @@ -670,6 +669,7 @@ int mmc_init(int verbose) } /* fill in device description */ +#if 0 mmc_dev.if_type = IF_TYPE_MMC; mmc_dev.part_type = PART_TYPE_DOS; mmc_dev.dev = 0; @@ -679,7 +679,7 @@ int mmc_init(int verbose) mmc_dev.block_read = mmc_bread; mmc_dev.blksz = 512; mmc_dev.lba = 1 << 16; /* 64K x 512 blocks = 32MB default */ - +#endif /* try to get card id */ resp = mmc_cmd(MMC_ALL_SEND_CID, hcs, MMC_CMD_BCR | MMC_RSP_R2, 0, 0, 0, @@ -691,7 +691,7 @@ int mmc_init(int verbose) case CARDTYPE_MMC: /* TODO configure mmc driver depending on card attributes */ - +#if 0 if (verbose) print_mmc_cid(mmc_cid); sprintf((char *) mmc_dev.vendor, @@ -701,7 +701,7 @@ int mmc_init(int verbose) sprintf((char *) mmc_dev.product, "%s", mmc_cid->name); sprintf((char *) mmc_dev.revision, "%x %x", mmc_cid->hwrev, mmc_cid->fwrev); - +#endif /* MMC exists, get CSD too */ resp = mmc_cmd(MMC_SET_RELATIVE_ADDR, MMC_DEFAULT_RCA, MMC_CMD_AC | MMC_RSP_R1, 0, 0, 0, @@ -713,6 +713,7 @@ int mmc_init(int verbose) case CARDTYPE_SDHC: if (verbose) print_sd_cid(sd_cid); +#if 0 sprintf((char *) mmc_dev.vendor, "Man %02 OEM %c%c \"%c%c%c%c%c\"", sd_cid->mid, sd_cid->oid_0, sd_cid->oid_1, @@ -723,7 +724,7 @@ int mmc_init(int verbose) sd_cid->psn_2 << 8 | sd_cid->psn_3); sprintf((char *) mmc_dev.revision, "%d.%d", sd_cid->prv >> 4, sd_cid->prv & 15); - +#endif resp = mmc_cmd(SD_SEND_RELATIVE_ADDR, MMC_DEFAULT_RCA, MMC_CMD_BCR | MMC_RSP_R6, 0, 0, 0, (u16 *)&response[0]); @@ -742,17 +743,20 @@ int mmc_init(int verbose) if (!resp) { mmc_csd_t *csd = (mmc_csd_t *)response; - memcpy(&mmc_csd, csd, sizeof(csd)); +// memcpy(&mmc_csd, csd, sizeof(csd)); rc = 0; mmc_ready = 1; /* 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); */ - mmc_dev.blksz = 512; - mmc_dev.lba = (((unsigned long)1 << csd->c_size_mult1) * - (unsigned long)csd->c_size) >> 9; - printf("MMC/SD size: %dMiB\n", mmc_dev.lba >> 1); +// mmc_dev.blksz = 512; +// mmc_dev.lba = (((unsigned long)1 << csd->c_size_mult1) * +// (unsigned long)csd->c_size) >> 9; + puts(" MMC/SD size: "); + print32((((unsigned long)1 << csd->c_size_mult1) * + (unsigned long)csd->c_size) >> 10); + puts(" MiB\n"); } resp = mmc_cmd(MMC_SELECT_CARD, rca<<16, MMC_CMD_AC | MMC_RSP_R1, @@ -779,50 +783,8 @@ int mmc_init(int verbose) glamo_reg_write((glamo_reg_read(GLAMO_REG_CLOCK_GEN8) & 0xff00) | 2, GLAMO_REG_CLOCK_GEN8); - fat_register_device(&mmc_dev, 1); /* partitions start counting with 1 */ - return rc; } -void mmc_depower(void) -{ - u8 response[16]; - /* reset */ - mmc_cmd(MMC_GO_IDLE_STATE, 0, MMC_CMD_BCR, 0, 0, 0, - (u16 *)&response[0]); - - /* hold engine reset, remove clocks */ - - glamo_reg_write(GLAMO_CLOCK_MMC_RESET, GLAMO_REG_CLOCK_MMC); - - /* disable engine */ - - glamo_reg_write(0, GLAMO_REG_CLOCK_MMC); - glamo_reg_write(glamo_reg_read(GLAMO_REG_HOSTBUS(2)) & - (~GLAMO_HOSTBUS2_MMIO_EN_MMC), GLAMO_REG_HOSTBUS(2)); - - /* remove power */ - - pcf50633_reg_write(PCF50633_REG_HCLDOOUT + 1, - pcf50633_reg_read(PCF50633_REG_HCLDOOUT + 1) & ~1); /* off */ -} - -int -mmc_ident(block_dev_desc_t *dev) -{ - return 0; -} - -int -mmc2info(ulong addr) -{ - /* FIXME hard codes to 32 MB device */ - if (addr >= CFG_MMC_BASE && addr < CFG_MMC_BASE + 0x02000000) - return 1; - - return 0; -} - -#endif diff --git a/qiboot/src/gta02/gta02.c b/qiboot/src/gta02/gta02.c index 00175a4..5023180 100644 --- a/qiboot/src/gta02/gta02.c +++ b/qiboot/src/gta02/gta02.c @@ -198,14 +198,13 @@ void port_init_gta02(void) /* configure MPLL */ *MPLLCON = ((42 << 12) + (1 << 4) + 0); + /* get debug UART working at 115kbps */ + serial_init_115200_s3c24xx(GTA02_DEBUG_UART, 50 /* 50MHz PCLK */); + /* we're going to use Glamo for SD Card access, so we need to init the * evil beast */ glamo_core_init(); - - /* get debug UART working at 115kbps */ - serial_init_115200_s3c24xx(GTA02_DEBUG_UART, 50 /* 50MHz PCLK */); - } /** @@ -257,7 +256,12 @@ int gta02_get_pcb_revision(void) return n; } +int sd_card_init_gta02(void) +{ + extern int mmc_init(int verbose); + return mmc_init(1); +} /* return nonzero if we believe we run on GTA02 */ @@ -297,6 +301,27 @@ const struct board_api board_api_gta02 = { /* these are the ways we could boot GTA02 in order to try */ .kernel_source = { [0] = { + .name = "SD Card FAT Kernel", + .block_init = sd_card_init_gta02, + .block_read = nand_read_ll, + .partition_index = 0, + .filesystem = FS_FAT, + .commandline = "mtdparts=physmap-flash:-(nor);" \ + "neo1973-nand:" \ + "0x00040000(qi)," \ + "0x00040000(cmdline)," \ + "0x00800000(backupkernel)," \ + "0x000a0000(extra)," \ + "0x00040000(identity)," \ + "0x0f6a0000(backuprootfs) " \ + "rootfstype=jffs2 " \ + "root=/dev/mtdblock6 " \ + "console=ttySAC2,115200 " \ + "loglevel=8 " \ + "init=/sbin/init "\ + "ro" + }, + [1] = { .name = "NAND Kernel", .block_read = nand_read_ll, .partition_index = -1, diff --git a/qiboot/src/utils.c b/qiboot/src/utils.c index 5c945a8..5f183bc 100644 --- a/qiboot/src/utils.c +++ b/qiboot/src/utils.c @@ -71,7 +71,7 @@ void printnybble(unsigned char n) this_board->putc('a' + n - 10); } -void printhex(unsigned char n) +void print8(unsigned char n) { printnybble((n >> 4) & 15); printnybble(n & 15); @@ -79,10 +79,10 @@ void printhex(unsigned char n) void print32(unsigned int u) { - printhex(u >> 24); - printhex(u >> 16); - printhex(u >> 8); - printhex(u); + print8(u >> 24); + print8(u >> 16); + print8(u >> 8); + print8(u); } void hexdump(unsigned char *start, int len) @@ -94,7 +94,7 @@ void hexdump(unsigned char *start, int len) this_board->putc(':'); this_board->putc(' '); for (n = 0; n < 16; n++) { - printhex(*start++); + print8(*start++); this_board->putc(' '); } this_board->putc('\n'); From b4134e84cff26c6ae4b1cb419349151aaca34e98 Mon Sep 17 00:00:00 2001 From: xiangfu Date: Fri, 28 Nov 2008 10:16:37 +0000 Subject: [PATCH 061/248] Subject: we-don't-nend-led_on.S-any-more X-Git-Url: http://git.openmoko.org/?p=qi.git;a=commitdiff_plain;h=ebbad42a5c0013c68407167c65d9c7e56a725a93 we-don't-nend-led_on.S-any-more --- qiboot/Makefile | 5 ----- qiboot/src/led_on.S | 37 ------------------------------------- 2 files changed, 42 deletions(-) delete mode 100644 qiboot/src/led_on.S diff --git a/qiboot/Makefile b/qiboot/Makefile index 1a620f9..5276ea3 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -68,10 +68,5 @@ ${UDFU_IMAGE}:${OBJS} -d ${IMAGE} ${UDFU_IMAGE} @$(OBJDUMP) -d ${TARGET} >${IMAGE}.dis -blink_led:src/led_on.S - $(CC) $(CFLAGS) led_on.o led_on.S - $(LD) -g led_on.o -o led_on_temp.o - $(OBJCOPY) -O binary -S led_on_temp.o $(IMAGE)/led_on - clean: @rm -f src/*.o src/*~ include/*~ ${IMAGE}* ${TARGET} ${UDFU_IMAGE} diff --git a/qiboot/src/led_on.S b/qiboot/src/led_on.S deleted file mode 100644 index 1ebcaa9..0000000 --- a/qiboot/src/led_on.S +++ /dev/null @@ -1,37 +0,0 @@ -_start: - mov ip, sp - stmfd sp!, {fp, ip, lr, pc} - sub fp, ip, #4 - ldr r2, .L4 - mov r3, #5 - str r3, [r2, #0] - ldr r2, .L4+4 - ldr r3, .L4+8 - str r3, [r2, #0] -.L2: - ldr r2, .L4+12 - ldr r3, .L4+12 - ldr r3, [r3, #0] - bic r3, r3, #1 - str r3, [r2, #0] - ldr r0, .L4+8 - bl delay - ldr r2, .L4+12 - ldr r3, .L4+12 - ldr r3, [r3, #0] - orr r3, r3, #1 - str r3, [r2, #0] - ldr r0, .L4+8 - bl delay - b .L2 -.L5: - .align 2 -.L4: - .word 1442840592 - .word 1442840600 - .word 65535 - .word 1442840596 - delay: - subs r0,r0,#0x1 - bne delay - mov pc,lr From c7a4e4dc0dc4184d2472793c285d552be83e958c Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:37 +0000 Subject: [PATCH 062/248] fix-kill-clocks-unused.patch We leave a lot of funny clocks up in things like camera unit. This pares it down to just what we use in Qi. Signed-off-by: Andy Green --- qiboot/src/start.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qiboot/src/start.S b/qiboot/src/start.S index ef7ff2d..7e02ecf 100644 --- a/qiboot/src/start.S +++ b/qiboot/src/start.S @@ -116,9 +116,9 @@ start_code: mov r1, #CLKDIVN_val str r1, [r0] - /* enable uart */ + /* enable only CPU peripheral block clocks we actually use */ ldr r0, =0x4c00000c /* clkcon */ - ldr r1, =0x7fff0 /* all clocks on */ + ldr r1, =0x3d10 /* uart, pwm, gpio, nand clocks on */ str r1, [r0] /* gpio UART2 init, H port */ From 1b043e0fe5768687f5277f38e174c3097e066300 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:37 +0000 Subject: [PATCH 063/248] add-print-decimal.patch Signed-off-by: Andy Green --- qiboot/include/qi.h | 1 + qiboot/src/phase2.c | 7 ++++--- qiboot/src/utils.c | 21 +++++++++++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index 17fafe7..ea0382b 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -82,6 +82,7 @@ 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); unsigned int _ntohl(unsigned int n); unsigned long crc32(unsigned long crc, const unsigned char *buf, diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 826e90e..b2ad6a9 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -93,8 +93,9 @@ void bootloader_second_phase(void) puts(" Found: "); puts((const char *)hdr->ih_name); - puts("\n Size: 0x"); - print32(_ntohl(hdr->ih_size)); + puts("\n Size: "); + printdec(_ntohl(hdr->ih_size) >> 10); + puts(" KiB\n"); if (nand_read_ll(kernel_dram, this_board->kernel_source[kernel]. @@ -107,7 +108,7 @@ void bootloader_second_phase(void) } } - puts("\n Cmdline: "); + puts(" Cmdline: "); puts(p); puts("\n"); diff --git a/qiboot/src/utils.c b/qiboot/src/utils.c index 5f183bc..11b1675 100644 --- a/qiboot/src/utils.c +++ b/qiboot/src/utils.c @@ -102,6 +102,27 @@ void hexdump(unsigned char *start, int len) } } +void printdec(int n) +{ + int d = 1 * 1000 * 1000 * 1000; + int flag = 0; + + if (n < 0) { + this_board->putc('-'); + n = -n; + } + + while (d) { + int r = n / d; + if (r || flag || (d == 1)) { + this_board->putc('0' + r); + flag = 1; + } + n -= r * d; + d = d / 10; + } +} + /* original copyright notice for this crc code (it is from U-Boot) --> */ /* * This file is derived from crc32.c from the zlib-1.1.3 distribution From b6dd949b0e96ebb99f4c3679467ecc3f89497cf3 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:37 +0000 Subject: [PATCH 064/248] fix-wild-comment-GLAMO_FB_.patch Some crud leaked in last commits. Plus more nice printing. Signed-off-by: Andy Green --- qiboot/src/drivers/glamo-mmc.c | 47 ++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/qiboot/src/drivers/glamo-mmc.c b/qiboot/src/drivers/glamo-mmc.c index c8d43bd..035bc07 100644 --- a/qiboot/src/drivers/glamo-mmc.c +++ b/qiboot/src/drivers/glamo-mmc.c @@ -158,7 +158,7 @@ static int mmc_cmd(int opcode, int arg, int flags, GLAMO_REGOFS_MMC + GLAMO_REG_MMC_WDATADS1); glamo_reg_write((u16)(GLAMO_FB_SIZE >> 16), GLAMO_REGOFS_MMC + GLAMO_REG_MMC_WDATADS2); - glamo_reg_write((u16)GLAMO_FB_/*SIZE*/, + glamo_reg_write((u16)GLAMO_FB_SIZE, GLAMO_REGOFS_MMC + GLAMO_REG_MMC_RDATADS1); glamo_reg_write((u16)(GLAMO_FB_SIZE >> 16), GLAMO_REGOFS_MMC + GLAMO_REG_MMC_RDATADS2); @@ -521,7 +521,7 @@ static void print_mmc_cid(mmc_cid_t *cid) #endif static void print_sd_cid(const struct sd_cid *cid) { - puts("Card Type: "); + puts(" Card Type: "); switch (card_type) { case CARDTYPE_NONE: puts("(None)\n"); @@ -539,19 +539,33 @@ static void print_sd_cid(const struct sd_cid *cid) puts("SD 2.0 SDHC\n"); break; } -#if 0 - printf("Manufacturer: 0x%02x, OEM \"%c%c\"\n", - cid->mid, cid->oid_0, cid->oid_1); - printf("Product name: \"%c%c%c%c%c\", revision %d.%d\n", - cid->pnm_0, cid->pnm_1, cid->pnm_2, cid->pnm_3, cid->pnm_4, - cid->prv >> 4, cid->prv & 15); - printf("Serial number: %u\n", - cid->psn_0 << 24 | cid->psn_1 << 16 | cid->psn_2 << 8 | + + puts(" Manufacturer: 0x"); + print8(cid->mid); + puts(", OEM \""); + this_board->putc(cid->oid_0); + this_board->putc(cid->oid_1); + puts("\"\n"); + + puts(" Product 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); - printf("Manufacturing date: %d/%d\n", - cid->mdt_1 & 15, - 2000+((cid->mdt_0 & 15) << 4)+((cid->mdt_1 & 0xf0) >> 4)); -#endif + puts("\n Manf. date: "); + printdec(cid->mdt_1 & 15); + puts("/"); + printdec(2000 + ((cid->mdt_0 & 15) << 4)+((cid->mdt_1 & 0xf0) >> 4)); + puts("\n"); + /* printf("CRC: 0x%02x, b0 = %d\n", cid->crc >> 1, cid->crc & 1); */ } @@ -563,7 +577,7 @@ int mmc_init(int verbose) int resp; u8 response[16]; // mmc_cid_t *mmc_cid = (mmc_cid_t *)response; -// struct sd_cid *sd_cid = (struct sd_cid *)response; + struct sd_cid *sd_cid = (struct sd_cid *)response; u32 hcs = 0; card_type = CARDTYPE_NONE; @@ -711,6 +725,7 @@ int mmc_init(int verbose) case CARDTYPE_SD: case CARDTYPE_SD20: case CARDTYPE_SDHC: + if (verbose) print_sd_cid(sd_cid); #if 0 @@ -754,7 +769,7 @@ int mmc_init(int verbose) // mmc_dev.lba = (((unsigned long)1 << csd->c_size_mult1) * // (unsigned long)csd->c_size) >> 9; puts(" MMC/SD size: "); - print32((((unsigned long)1 << csd->c_size_mult1) * + printdec((((unsigned long)1 << csd->c_size_mult1) * (unsigned long)csd->c_size) >> 10); puts(" MiB\n"); } From 935ef0e12dba85e10c21be9ffc24d8122b12ce1e Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:37 +0000 Subject: [PATCH 065/248] add-partition-support.patch We have to minimally support DOS partition scheme. Partitions are counted from 1+ now, and 0 means no partition table instead of -1. Signed-off-by: Andy Green --- qiboot/include/qi.h | 7 +- qiboot/src/drivers/glamo-mmc.c | 15 ++-- qiboot/src/drivers/i2c-bitbang-s3c24xx.c | 2 +- qiboot/src/gta02/gta02.c | 24 ++++--- qiboot/src/gta03/gta03.c | 3 +- qiboot/src/nand_read.c | 44 ++++++------ qiboot/src/phase2.c | 88 +++++++++++++++--------- qiboot/src/start_qi.c | 2 +- qiboot/src/utils.c | 5 ++ 9 files changed, 117 insertions(+), 73 deletions(-) diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index ea0382b..01cf2fa 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -42,8 +42,8 @@ enum filesystem { struct kernel_source { const char *name; /* NULL name means invalid */ int (*block_init)(void); - int (*block_read)(unsigned char * buf, unsigned long byte_start, - int count_bytes); + int (*block_read)(unsigned char * buf, unsigned long start512, + int blocks512); int partition_index; /* -1 means no partition table */ int offset_if_no_partition; /* used if partition_index is -1 */ enum filesystem filesystem; @@ -85,9 +85,10 @@ void print32(unsigned int u); void printdec(int n); void hexdump(unsigned char *start, int len); unsigned int _ntohl(unsigned int n); +unsigned int _letocpu(unsigned int n); unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned int len); -int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size); +int nand_read_ll(unsigned char *buf, unsigned long start512, int blocks512); #endif diff --git a/qiboot/src/drivers/glamo-mmc.c b/qiboot/src/drivers/glamo-mmc.c index 035bc07..4f383dd 100644 --- a/qiboot/src/drivers/glamo-mmc.c +++ b/qiboot/src/drivers/glamo-mmc.c @@ -316,8 +316,14 @@ static int mmc_cmd(int opcode, int arg, int flags, return 0; if (error) { -// printf("cmd 0x%x, arg 0x%x flags 0x%x\n", opcode, arg, flags); -#if 0 + puts("cmd 0x"); + print8(opcode); + puts(", arg 0x"); + print8(arg); + puts(", flags 0x"); + print32(flags); + puts("\n"); +#if 1 puts("Error after cmd: 0x"); print32(error); puts("\n"); @@ -360,7 +366,7 @@ static int mmc_cmd(int opcode, int arg, int flags, error = -5; if (error) { // printf("cmd 0x%x, arg 0x%x flags 0x%x\n", opcode, arg, flags); -#if 0 +#if 1 puts("Error after resp: 0x"); print32(status); puts("\n"); @@ -573,7 +579,7 @@ static void print_sd_cid(const struct sd_cid *cid) int mmc_init(int verbose) { - int retries = 14, rc = -1; + int retries = 16, rc = -1; int resp; u8 response[16]; // mmc_cid_t *mmc_cid = (mmc_cid_t *)response; @@ -641,6 +647,7 @@ int mmc_init(int verbose) udelay(100000); udelay(100000); + udelay(100000); resp = mmc_cmd(MMC_APP_CMD, 0x00000000, MMC_CMD_AC | MMC_RSP_R1, 0, 0, 0, diff --git a/qiboot/src/drivers/i2c-bitbang-s3c24xx.c b/qiboot/src/drivers/i2c-bitbang-s3c24xx.c index f71dfc4..c2d46ed 100644 --- a/qiboot/src/drivers/i2c-bitbang-s3c24xx.c +++ b/qiboot/src/drivers/i2c-bitbang-s3c24xx.c @@ -56,7 +56,7 @@ static void i2c_spin_s3c24xx(void) { int n; - for (n = 0; n < 700; n++) + for (n = 0; n < 1000; n++) rGPJDAT |= (1 << 5); } diff --git a/qiboot/src/gta02/gta02.c b/qiboot/src/gta02/gta02.c index 5023180..cda7a2b 100644 --- a/qiboot/src/gta02/gta02.c +++ b/qiboot/src/gta02/gta02.c @@ -263,6 +263,15 @@ int sd_card_init_gta02(void) 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) @@ -303,9 +312,9 @@ const struct board_api board_api_gta02 = { [0] = { .name = "SD Card FAT Kernel", .block_init = sd_card_init_gta02, - .block_read = nand_read_ll, - .partition_index = 0, - .filesystem = FS_FAT, + .block_read = sd_card_block_read_gta02, + .partition_index = 1, + .filesystem = FS_EXT2, .commandline = "mtdparts=physmap-flash:-(nor);" \ "neo1973-nand:" \ "0x00040000(qi)," \ @@ -314,18 +323,17 @@ const struct board_api board_api_gta02 = { "0x000a0000(extra)," \ "0x00040000(identity)," \ "0x0f6a0000(backuprootfs) " \ - "rootfstype=jffs2 " \ - "root=/dev/mtdblock6 " \ + "rootfstype=ext2 " \ + "root=/dev/mmcblk0p1 " \ "console=ttySAC2,115200 " \ - "loglevel=8 " \ + "loglevel=4 " \ "init=/sbin/init "\ "ro" }, [1] = { .name = "NAND Kernel", .block_read = nand_read_ll, - .partition_index = -1, - .offset_if_no_partition = 0x80000, + .offset_if_no_partition = 0x80000 / 512, .filesystem = FS_RAW, .commandline = "mtdparts=physmap-flash:-(nor);" \ "neo1973-nand:" \ diff --git a/qiboot/src/gta03/gta03.c b/qiboot/src/gta03/gta03.c index f99ecae..90f5908 100644 --- a/qiboot/src/gta03/gta03.c +++ b/qiboot/src/gta03/gta03.c @@ -234,8 +234,7 @@ const struct board_api board_api_gta03 = { [0] = { .name = "NAND Kernel", .block_read = nand_read_ll, - .partition_index = -1, - .offset_if_no_partition = 0x80000, + .offset_if_no_partition = 0x80000 / 512, .filesystem = FS_RAW, .commandline = "neo1973-nand:" \ "0x00040000(qi)," \ diff --git a/qiboot/src/nand_read.c b/qiboot/src/nand_read.c index 94bf839..cb2a2de 100644 --- a/qiboot/src/nand_read.c +++ b/qiboot/src/nand_read.c @@ -17,6 +17,7 @@ /* NOTE this stuff runs in steppingstone context! */ +/* the API refers to 512-byte blocks */ #include #include "nand_read.h" @@ -55,13 +56,13 @@ static inline void nand_wait(void) #define NAND_BLOCK_MASK (NAND_PAGE_SIZE - 1) #define NAND_BLOCK_SIZE (NAND_PAGE_SIZE * 64) -static int is_bad_block(unsigned long i) +static int is_bad_block(unsigned long block_index) { unsigned char data; unsigned long page_num; nand_clear_RnB(); - page_num = i >> 11; /* addr / 2048 */ + page_num = block_index >> 2; /* addr / 2048 */ NFCMD = NAND_CMD_READ0; NFADDR = BAD_BLOCK_OFFSET & 0xff; NFADDR = (BAD_BLOCK_OFFSET >> 8) & 0xff; @@ -78,7 +79,7 @@ static int is_bad_block(unsigned long i) return 0; } -static int nand_read_page_ll(unsigned char *buf, unsigned long addr) +static int nand_read_page_ll(unsigned char *buf, unsigned long block512) { unsigned short *ptr16 = (unsigned short *)buf; unsigned int i, page_num; @@ -91,7 +92,7 @@ static int nand_read_page_ll(unsigned char *buf, unsigned long addr) NFCMD = NAND_CMD_READ0; - page_num = addr >> 11; /* addr / 2048 */ + page_num = block512 >> 2; /* 512 block -> 2048 block */ /* Write Address */ NFADDR = 0; NFADDR = 0; @@ -108,17 +109,18 @@ static int nand_read_page_ll(unsigned char *buf, unsigned long addr) *p16++ = NFDATA16; } #endif - return NAND_PAGE_SIZE; + return 4; } /* low level nand read function */ -int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size) +int nand_read_ll(unsigned char *buf, unsigned long start_block512, + int blocks512) { int i, j; int bad_count = 0; - if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) - return -1; /* invalid alignment */ + if (start_block512 & 3) /* inside 2048-byte block */ + return -1; /* chip Enable */ nand_select(); @@ -127,22 +129,20 @@ int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size) for (i = 0; i < 10; i++) ; - for (i = start_addr; i < (start_addr + size);) { - if ((i & (NAND_BLOCK_SIZE - 1)) == 0) { - if (is_bad_block(i) || - is_bad_block(i + NAND_PAGE_SIZE)) { - i += NAND_BLOCK_SIZE; - size += NAND_BLOCK_SIZE; - if (bad_count++ == 4) - return -1; - - continue; - } + while (blocks512 > 0) { + if (is_bad_block(start_block512) || + is_bad_block(start_block512 + 4)) { + start_block512 += 4; + blocks512 += 4; + if (bad_count++ == 4) + return -1; + continue; } - j = nand_read_page_ll(buf, i); - i += j; - buf += j; + j = nand_read_page_ll(buf, start_block512); + start_block512 += j; + buf += j << 9; + blocks512 -= j; } /* chip Disable */ diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index b2ad6a9..7543e49 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -48,6 +48,8 @@ void bootloader_second_phase(void) void * kernel_dram = (void *)(TEXT_BASE - (8 * 1024 * 1024)); unsigned long crc; image_header_t *hdr; + unsigned long partition_offset_blocks = 0; + unsigned long partition_length_blocks = 0; /* eat leading white space */ for (p = cmdline; *p == ' '; p++); @@ -67,45 +69,67 @@ void bootloader_second_phase(void) /* if there's a partition table implied, parse it, otherwise * just use a fixed offset */ - if (this_board->kernel_source[kernel].partition_index != -1) { + if (this_board->kernel_source[kernel].partition_index) { + unsigned char *p = kernel_dram; - puts("partitions not supported yet\n"); + if (this_board->kernel_source[kernel].block_read( + kernel_dram, 0, 4) < 0) { + puts("Bad partition read\n"); + kernel++; + continue; + } + + if ((p[0x1fe] != 0x55) || (p[0x1ff] != 0xaa)) { + puts("partition signature missing\n"); + kernel++; + continue; + } + + p += 0x1be + 8 + (0x10 * (this_board-> + kernel_source[kernel].partition_index - 1)); + + partition_offset_blocks = (((u32)p[3]) << 24) | + (((u32)p[2]) << 16) | + (((u32)p[1]) << 8) | + p[0]; + partition_length_blocks = (((u32)p[7]) << 24) | + (((u32)p[6]) << 16) | + (((u32)p[5]) << 8) | + p[4]; + + } else + partition_offset_blocks = this_board-> + kernel_source[kernel].offset_if_no_partition; + + if (this_board->kernel_source[kernel].block_read( + kernel_dram, partition_offset_blocks, 8) < 0) { + puts ("Bad kernel header\n"); kernel++; continue; + } - } else { - if (this_board->kernel_source[kernel].block_read( - kernel_dram, this_board->kernel_source[kernel]. - offset_if_no_partition, 4096) < 0) { - puts ("Bad kernel header\n"); - kernel++; - continue; - } + hdr = (image_header_t *)kernel_dram; - hdr = (image_header_t *)kernel_dram; + if (_ntohl(hdr->ih_magic) != IH_MAGIC) { + puts("bad magic "); + print32(hdr->ih_magic); + kernel++; + continue; + } - if (_ntohl(hdr->ih_magic) != IH_MAGIC) { - puts("bad magic "); - print32(hdr->ih_magic); - kernel++; - continue; - } + puts(" Found: "); + puts((const char *)hdr->ih_name); + puts("\n Size: "); + printdec(_ntohl(hdr->ih_size) >> 10); + puts(" KiB\n"); - puts(" Found: "); - puts((const char *)hdr->ih_name); - puts("\n Size: "); - printdec(_ntohl(hdr->ih_size) >> 10); - puts(" KiB\n"); - - if (nand_read_ll(kernel_dram, - this_board->kernel_source[kernel]. - offset_if_no_partition, (_ntohl(hdr->ih_size) + - sizeof(image_header_t) + 2048) & - ~(2048 - 1)) < 0) { - puts ("Bad kernel read\n"); - kernel++; - continue; - } + if ((this_board->kernel_source[kernel].block_read)( + kernel_dram, partition_offset_blocks, + ((_ntohl(hdr->ih_size) + sizeof(image_header_t) + + 2048) & ~(2048 - 1)) >> 9) < 0) { + puts ("Bad kernel read\n"); + kernel++; + continue; } puts(" Cmdline: "); diff --git a/qiboot/src/start_qi.c b/qiboot/src/start_qi.c index f5c0223..3d993fd 100644 --- a/qiboot/src/start_qi.c +++ b/qiboot/src/start_qi.c @@ -60,7 +60,7 @@ void start_qi(void) */ /* We randomly pull 24KBytes of bootloader */ - if (nand_read_ll((unsigned char *)TEXT_BASE, 0, 24 * 1024) < 0) + if (nand_read_ll((unsigned char *)TEXT_BASE, 0, 24 * 1024 / 512) < 0) goto unhappy; /* ask all the boards we support in turn if they recognize this diff --git a/qiboot/src/utils.c b/qiboot/src/utils.c index 11b1675..62f7c17 100644 --- a/qiboot/src/utils.c +++ b/qiboot/src/utils.c @@ -54,6 +54,11 @@ unsigned int _ntohl(unsigned int n) { ((n & 0xff0000) >> 8) | ((n & 0xff000000) >> 24); } +unsigned int _letocpu(unsigned int n) { + return n; +} + + int puts(const char *string) { while (*string) From ec8ea0c2815fc0ee62597a6e37cdd7397a289136 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:37 +0000 Subject: [PATCH 066/248] add-ext2-fs.patch This adds ext2 support from U-Boot and stitches it into the partition stuff. It also upgrades the board definitions so they can define the path to look for in the ext2 filesystem being mounted. I used /boot/uImage.bin because this is already in use by the packaged kernel. We now mount, open and pull the kernel from ext2 in phase2.c if the kernel source defines it. Signed-off-by: Andy Green --- qiboot/Makefile | 3 +- qiboot/include/ext2.h | 80 +++ qiboot/include/image.h | 6 +- qiboot/include/qi.h | 11 +- qiboot/src/drivers/glamo-mmc.c | 25 +- qiboot/src/fs/dev.c | 115 +++++ qiboot/src/fs/ext2.c | 867 +++++++++++++++++++++++++++++++++ qiboot/src/gta02/gta02.c | 5 +- qiboot/src/gta03/gta03.c | 2 +- qiboot/src/phase2.c | 146 ++++-- qiboot/src/start_qi.c | 1 - qiboot/src/utils.c | 81 ++- 12 files changed, 1269 insertions(+), 73 deletions(-) create mode 100644 qiboot/include/ext2.h create mode 100644 qiboot/src/fs/dev.c create mode 100644 qiboot/src/fs/ext2.c diff --git a/qiboot/Makefile b/qiboot/Makefile index 5276ea3..cdb075e 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -34,7 +34,8 @@ LDFLAGS = #START = start.o lowlevel_init.o S_SRCS = src/start.S src/lowlevel_init.S S_OBJS = $(patsubst %.S,%.o, $(S_SRCS)) -C_SRCS = $(wildcard src/*.c) $(wildcard src/gt*/*.c) $(wildcard src/drivers/*.c) +C_SRCS = $(wildcard src/*.c) $(wildcard src/gt*/*.c) \ + $(wildcard src/drivers/*.c) $(wildcard src/fs/*.c) C_OBJS = $(patsubst %.c,%.o, $(C_SRCS)) #SRCS := $(START: .o=.S) $(COBJS: .o=.c) diff --git a/qiboot/include/ext2.h b/qiboot/include/ext2.h new file mode 100644 index 0000000..85b0860 --- /dev/null +++ b/qiboot/include/ext2.h @@ -0,0 +1,80 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2000, 2001 Free Software Foundation, Inc. + * + * (C) Copyright 2003 Sysgo Real-Time Solutions, AG + * Pavel Bartusek + * + * 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); diff --git a/qiboot/include/image.h b/qiboot/include/image.h index 2e3c6ef..af9ecda 100644 --- a/qiboot/include/image.h +++ b/qiboot/include/image.h @@ -33,8 +33,6 @@ #ifndef __IMAGE_H__ #define __IMAGE_H__ -#include - /* * Operating System Codes */ @@ -204,8 +202,8 @@ typedef struct bootm_headers { */ #define CHUNKSZ (64 * 1024) -#define uimage_to_cpu(x) ntohl(x) -#define cpu_to_uimage(x) htonl(x) +#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); diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index 01cf2fa..3429e9b 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -23,11 +23,15 @@ #include #include +#include + #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])) @@ -41,11 +45,12 @@ enum filesystem { struct kernel_source { const char *name; /* NULL name means invalid */ + const char *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_if_no_partition; /* used if partition_index is -1 */ + int offset_blocks512_if_no_partition; /* used if partition_index is -1 */ enum filesystem filesystem; const char * commandline; }; @@ -75,6 +80,7 @@ struct board_api { /* 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); @@ -84,8 +90,7 @@ void print8(unsigned char u); void print32(unsigned int u); void printdec(int n); void hexdump(unsigned char *start, int len); -unsigned int _ntohl(unsigned int n); -unsigned int _letocpu(unsigned int n); + 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); diff --git a/qiboot/src/drivers/glamo-mmc.c b/qiboot/src/drivers/glamo-mmc.c index 4f383dd..051c810 100644 --- a/qiboot/src/drivers/glamo-mmc.c +++ b/qiboot/src/drivers/glamo-mmc.c @@ -316,6 +316,7 @@ static int mmc_cmd(int opcode, int arg, int flags, return 0; if (error) { +#if 0 puts("cmd 0x"); print8(opcode); puts(", arg 0x"); @@ -323,7 +324,6 @@ static int mmc_cmd(int opcode, int arg, int flags, puts(", flags 0x"); print32(flags); puts("\n"); -#if 1 puts("Error after cmd: 0x"); print32(error); puts("\n"); @@ -366,7 +366,7 @@ static int mmc_cmd(int opcode, int arg, int flags, error = -5; if (error) { // printf("cmd 0x%x, arg 0x%x flags 0x%x\n", opcode, arg, flags); -#if 1 +#if 0 puts("Error after resp: 0x"); print32(status); puts("\n"); @@ -530,43 +530,42 @@ static void print_sd_cid(const struct sd_cid *cid) puts(" Card Type: "); switch (card_type) { case CARDTYPE_NONE: - puts("(None)\n"); + puts("(None) / "); break; case CARDTYPE_MMC: - puts("MMC\n"); + puts("MMC / "); break; case CARDTYPE_SD: - puts("SD\n"); + puts("SD / "); break; case CARDTYPE_SD20: - puts("SD 2.0\n"); + puts("SD 2.0 / "); break; case CARDTYPE_SDHC: - puts("SD 2.0 SDHC\n"); + puts("SD 2.0 SDHC / "); break; } - puts(" Manufacturer: 0x"); + puts("Mfr: 0x"); print8(cid->mid); puts(", OEM \""); this_board->putc(cid->oid_0); this_board->putc(cid->oid_1); - puts("\"\n"); + puts("\" / "); - puts(" Product 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 "); + puts("\", rev "); printdec(cid->prv >> 4); puts("."); printdec(cid->prv & 15); - puts("\nSerial number: "); + puts(" / s/n: "); printdec(cid->psn_0 << 24 | cid->psn_1 << 16 | cid->psn_2 << 8 | cid->psn_3); - puts("\n Manf. date: "); + puts(" / date: "); printdec(cid->mdt_1 & 15); puts("/"); printdec(2000 + ((cid->mdt_0 & 15) << 4)+((cid->mdt_1 & 0xf0) >> 4)); diff --git a/qiboot/src/fs/dev.c b/qiboot/src/fs/dev.c new file mode 100644 index 0000000..ebe8d6e --- /dev/null +++ b/qiboot/src/fs/dev.c @@ -0,0 +1,115 @@ +/* + * (C) Copyright 2004 + * esd gmbh + * Reinhard Arlt + * + * based on code of fs/reiserfs/dev.c by + * + * (C) Copyright 2003 - 2004 + * Sysgo AG, , Pavel Bartusek + * + * 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. + */ + + +#include +#include +#include + +extern unsigned long partition_offset_blocks; +extern unsigned long partition_length_blocks; + + +int ext2fs_devread(int sector, int byte_offset, int byte_len, u8 *buf) +{ + unsigned char sec_buf[SECTOR_SIZE]; + unsigned block_len; + +/* + * Check partition boundaries + */ + if ((sector < 0) + || ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) >= + partition_length_blocks)) { + /* errnum = ERR_OUTSIDE_PART; */ + puts(" ** ext2fs_devread() read outside partition sector "); + printdec(sector); + puts("\n"); + return 0; + } + +/* + * Get the read to the beginning of a partition. + */ + sector += byte_offset >> SECTOR_BITS; + byte_offset &= SECTOR_SIZE - 1; + + if (byte_offset) { + int minimum = SECTOR_SIZE - byte_offset; + + if (byte_len < minimum) + minimum = byte_len; + + /* read first part which isn't aligned with start of sector */ + if ((this_kernel->block_read)(sec_buf, + partition_offset_blocks + sector, 1) < 0) { + puts(" ** ext2fs_devread() read error **\n"); + return 0; + } + memcpy(buf, sec_buf + byte_offset, + minimum); + buf += minimum; + byte_len -= minimum; + sector++; + } + + if (!byte_len) + return 1; + + /* read sector aligned part */ + block_len = byte_len & ~(SECTOR_SIZE - 1); + + if (block_len == 0) { + u8 p[SECTOR_SIZE]; + + block_len = SECTOR_SIZE; + this_kernel->block_read(p, + partition_offset_blocks + sector, 1); + memcpy(buf, p, byte_len); + return 1; + } + + if (this_kernel->block_read(buf, partition_offset_blocks + sector, + block_len / SECTOR_SIZE) < 0) { + puts(" ** ext2fs_devread() read error - block\n"); + return 0; + } + block_len = byte_len & ~(SECTOR_SIZE - 1); + buf += block_len; + byte_len -= block_len; + sector += block_len / SECTOR_SIZE; + + if (byte_len) { + /* read rest of data which are not in whole sector */ + if (this_kernel->block_read(sec_buf, + partition_offset_blocks + sector, 1) != 1) { + puts(" ** ext2fs_devread() read error - last part\n"); + return 0; + } + memcpy (buf, sec_buf, byte_len); + } + return 1; +} + diff --git a/qiboot/src/fs/ext2.c b/qiboot/src/fs/ext2.c new file mode 100644 index 0000000..25616e5 --- /dev/null +++ b/qiboot/src/fs/ext2.c @@ -0,0 +1,867 @@ +/* + *(C) Copyright 2004 + * esd gmbh + * Reinhard Arlt + * + * based on code from grub2 fs/ext2.c and fs/fshelp.c by + * + * GRUB -- GRand Unified Bootloader + * Copyright(C) 2003, 2004 Free Software Foundation, 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. + * + * 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. + */ + +#include + +#include +#include +#include + +extern int ext2fs_devread(int sector, int byte_offset, int byte_len, + char *buf); + +/* Magic value used to identify an ext2 filesystem. */ +#define EXT2_MAGIC 0xEF53 +/* Amount of indirect blocks in an inode. */ +#define INDIRECT_BLOCKS 12 +/* Maximum lenght of a pathname. */ +#define EXT2_PATH_MAX 4096 +/* Maximum nesting of symlinks, used to prevent a loop. */ +#define EXT2_MAX_SYMLINKCNT 8 + +/* Filetype used in directory entry. */ +#define FILETYPE_UNKNOWN 0 +#define FILETYPE_REG 1 +#define FILETYPE_DIRECTORY 2 +#define FILETYPE_SYMLINK 7 + +/* Filetype information as used in inodes. */ +#define FILETYPE_INO_MASK 0170000 +#define FILETYPE_INO_REG 0100000 +#define FILETYPE_INO_DIRECTORY 0040000 +#define FILETYPE_INO_SYMLINK 0120000 + +/* Bits used as offset in sector */ +#define DISK_SECTOR_BITS 9 + +/* Log2 size of ext2 block in 512 blocks. */ +#define LOG2_EXT2_BLOCK_SIZE(data)(__le32_to_cpu(data->sblock.log2_block_size) + 1) + +/* Log2 size of ext2 block in bytes. */ +#define LOG2_BLOCK_SIZE(data) (__le32_to_cpu(data->sblock.log2_block_size) + 10) + +/* The size of an ext2 block in bytes. */ +#define EXT2_BLOCK_SIZE(data) (1 << LOG2_BLOCK_SIZE(data)) + +/* The ext2 superblock. */ +struct ext2_sblock { + uint32_t total_inodes; + uint32_t total_blocks; + uint32_t reserved_blocks; + uint32_t free_blocks; + uint32_t free_inodes; + uint32_t first_data_block; + uint32_t log2_block_size; + uint32_t log2_fragment_size; + uint32_t blocks_per_group; + uint32_t fragments_per_group; + uint32_t inodes_per_group; + uint32_t mtime; + uint32_t utime; + uint16_t mnt_count; + uint16_t max_mnt_count; + uint16_t magic; + uint16_t fs_state; + uint16_t error_handling; + uint16_t minor_revision_level; + uint32_t lastcheck; + uint32_t checkinterval; + uint32_t creator_os; + uint32_t revision_level; + uint16_t uid_reserved; + uint16_t gid_reserved; + uint32_t first_inode; + uint16_t inode_size; + uint16_t block_group_number; + uint32_t feature_compatibility; + uint32_t feature_incompat; + uint32_t feature_ro_compat; + uint32_t unique_id[4]; + char volume_name[16]; + char last_mounted_on[64]; + uint32_t compression_info; +}; + +/* The ext2 blockgroup. */ +struct ext2_block_group { + uint32_t block_id; + uint32_t inode_id; + uint32_t inode_table_id; + uint16_t free_blocks; + uint16_t free_inodes; + uint16_t pad; + uint32_t reserved[3]; +}; + +/* The ext2 inode. */ +struct ext2_inode { + uint16_t mode; + uint16_t uid; + uint32_t size; + uint32_t atime; + uint32_t ctime; + uint32_t mtime; + uint32_t dtime; + uint16_t gid; + uint16_t nlinks; + uint32_t blockcnt; /* Blocks of 512 bytes!! */ + uint32_t flags; + uint32_t osd1; + union { + struct datablocks { + uint32_t dir_blocks[INDIRECT_BLOCKS]; + uint32_t indir_block; + uint32_t double_indir_block; + uint32_t tripple_indir_block; + } blocks; + char symlink[60]; + } b; + uint32_t version; + uint32_t acl; + uint32_t dir_acl; + uint32_t fragment_addr; + uint32_t osd2[3]; +}; + +/* The header of an ext2 directory entry. */ +struct ext2_dirent { + uint32_t inode; + uint16_t direntlen; + uint8_t namelen; + uint8_t filetype; +}; + +struct ext2fs_node { + struct ext2_data *data; + struct ext2_inode inode; + int ino; + int inode_read; +}; + +/* Information about a "mounted" ext2 filesystem. */ +struct ext2_data { + struct ext2_sblock sblock; + struct ext2_inode *inode; + struct ext2fs_node diropen; +}; + + +typedef struct ext2fs_node *ext2fs_node_t; + +struct ext2_data *ext2fs_root = NULL; +ext2fs_node_t ext2fs_file = NULL; +int symlinknest = 0; +uint32_t *indir1_block = NULL; +int indir1_size = 0; +int indir1_blkno = -1; +uint32_t *indir2_block = NULL; +int indir2_size = 0; +int indir2_blkno = -1; + + +static int ext2fs_blockgroup + (struct ext2_data *data, int group, struct ext2_block_group *blkgrp) { +#ifdef DEBUG + puts("ext2fs read blockgroup\n"); +#endif + return ext2fs_devread + (((__le32_to_cpu(data->sblock.first_data_block) + + 1) << LOG2_EXT2_BLOCK_SIZE(data)), + group * sizeof(struct ext2_block_group), + sizeof(struct ext2_block_group),(char *) blkgrp); +} + + +static int ext2fs_read_inode + (struct ext2_data *data, int ino, struct ext2_inode *inode) { + struct ext2_block_group blkgrp; + struct ext2_sblock *sblock = &data->sblock; + int inodes_per_block; + int status; + + unsigned int blkno; + unsigned int blkoff; + + /* It is easier to calculate if the first inode is 0. */ + ino--; +#ifdef DEBUG + puts("ext2fs read inode %d\n", ino); +#endif + status = ext2fs_blockgroup(data, + ino / + __le32_to_cpu(sblock->inodes_per_group), + &blkgrp); + if (status == 0) + return 0; + + inodes_per_block = EXT2_BLOCK_SIZE(data) / 128; + blkno =(ino % __le32_to_cpu(sblock->inodes_per_group)) / + inodes_per_block; + blkoff =(ino % __le32_to_cpu(sblock->inodes_per_group)) % + inodes_per_block; +#ifdef DEBUG + puts("ext2fs read inode blkno %d blkoff %d\n", blkno, blkoff); +#endif + /* Read the inode. */ + status = ext2fs_devread(((__le32_to_cpu(blkgrp.inode_table_id) + + blkno) << LOG2_EXT2_BLOCK_SIZE(data)), + sizeof(struct ext2_inode) * blkoff, + sizeof(struct ext2_inode),(char *) inode); + + return !!status; +} + + +void ext2fs_free_node(ext2fs_node_t node, ext2fs_node_t currroot) { + if ((node != &ext2fs_root->diropen) &&(node != currroot)) { + free(node); + } +} + + +static int ext2fs_read_block(ext2fs_node_t node, int fileblock) { + struct ext2_data *data = node->data; + struct ext2_inode *inode = &node->inode; + int blknr; + int blksz = EXT2_BLOCK_SIZE(data); + int log2_blksz = LOG2_EXT2_BLOCK_SIZE(data); + int status; + + /* Direct blocks. */ + if (fileblock < INDIRECT_BLOCKS) { + blknr = __le32_to_cpu(inode->b.blocks.dir_blocks[fileblock]); + } + /* Indirect. */ + else if (fileblock <(INDIRECT_BLOCKS +(blksz / 4))) { + if (indir1_block == NULL) { + indir1_block =(uint32_t *) malloc(blksz); + if (indir1_block == NULL) { + puts("** ext2fs read block(indir 1) malloc failed. **\n"); + return -1; + } + indir1_size = blksz; + indir1_blkno = -1; + } + if (blksz != indir1_size) { + free(indir1_block); + indir1_block = NULL; + indir1_size = 0; + indir1_blkno = -1; + indir1_block =(uint32_t *) malloc(blksz); + if (indir1_block == NULL) { + puts("** ext2fs read block(indir 1) malloc failed. **\n"); + return -1; + } + indir1_size = blksz; + } + if ((__le32_to_cpu(inode->b.blocks.indir_block) << + log2_blksz) != indir1_blkno) { + status = ext2fs_devread(__le32_to_cpu(inode->b.blocks.indir_block) << log2_blksz, + 0, blksz, + (char *) indir1_block); + if (status == 0) { + puts("** ext2fs read block(indir 1) failed. **\n"); + return 0; + } + indir1_blkno = + __le32_to_cpu(inode->b.blocks. + indir_block) << log2_blksz; + } + blknr = __le32_to_cpu(indir1_block + [fileblock - INDIRECT_BLOCKS]); + } + /* Double indirect. */ + else if (fileblock < + (INDIRECT_BLOCKS +(blksz / 4 *(blksz / 4 + 1)))) { + unsigned int perblock = blksz / 4; + unsigned int rblock = fileblock -(INDIRECT_BLOCKS + + blksz / 4); + + if (indir1_block == NULL) { + indir1_block =(uint32_t *) malloc(blksz); + if (indir1_block == NULL) { + puts("** ext2fs read block(indir 2 1) malloc failed. **\n"); + return -1; + } + indir1_size = blksz; + indir1_blkno = -1; + } + if (blksz != indir1_size) { + free(indir1_block); + indir1_block = NULL; + indir1_size = 0; + indir1_blkno = -1; + indir1_block =(uint32_t *) malloc(blksz); + if (indir1_block == NULL) { + puts("** ext2fs read block(indir 2 1) malloc failed. **\n"); + return -1; + } + indir1_size = blksz; + } + if ((__le32_to_cpu(inode->b.blocks.double_indir_block) << + log2_blksz) != indir1_blkno) { + status = ext2fs_devread(__le32_to_cpu(inode->b.blocks.double_indir_block) << log2_blksz, + 0, blksz, + (char *) indir1_block); + if (status == 0) { + puts("** ext2fs read block(indir 2 1) failed. **\n"); + return -1; + } + indir1_blkno = + __le32_to_cpu(inode->b.blocks.double_indir_block) << log2_blksz; + } + + if (indir2_block == NULL) { + indir2_block =(uint32_t *) malloc(blksz); + if (indir2_block == NULL) { + puts("** ext2fs read block(indir 2 2) malloc failed. **\n"); + return -1; + } + indir2_size = blksz; + indir2_blkno = -1; + } + if (blksz != indir2_size) { + free(indir2_block); + indir2_block = NULL; + indir2_size = 0; + indir2_blkno = -1; + indir2_block =(uint32_t *) malloc(blksz); + if (indir2_block == NULL) { + puts("** ext2fs read block(indir 2 2) malloc failed. **\n"); + return -1; + } + indir2_size = blksz; + } + if ((__le32_to_cpu(indir1_block[rblock / perblock]) << + log2_blksz) != indir1_blkno) { + status = ext2fs_devread(__le32_to_cpu(indir1_block[rblock / perblock]) << log2_blksz, + 0, blksz, + (char *) indir2_block); + if (status == 0) { + puts("** ext2fs read block(indir 2 2) failed. **\n"); + return -1; + } + indir2_blkno = + __le32_to_cpu(indir1_block[rblock / perblock]) << log2_blksz; + } + blknr = __le32_to_cpu(indir2_block[rblock % perblock]); + } + /* Tripple indirect. */ + else { + puts("** ext2fs doesn't support tripple indirect blocks. **\n"); + return -1; + } +#ifdef DEBUG + printf("ext2fs_read_block %08x\n", blknr); +#endif + return blknr; +} + + +int ext2fs_read_file + (ext2fs_node_t node, int pos, unsigned int len, char *buf) { + int i; + int blockcnt; + int log2blocksize = LOG2_EXT2_BLOCK_SIZE(node->data); + int blocksize = 1 <<(log2blocksize + DISK_SECTOR_BITS); + unsigned int filesize = __le32_to_cpu(node->inode.size); + + /* Adjust len so it we can't read past the end of the file. */ + if (len > filesize) { + len = filesize; + } + blockcnt = ((len + pos) + blocksize - 1) / blocksize; + + for(i = pos / blocksize; i < blockcnt; i++) { + int blknr; + int blockoff = pos % blocksize; + int blockend = blocksize; + + int skipfirst = 0; + + blknr = ext2fs_read_block(node, i); + if (blknr < 0) + return -1; + + blknr = blknr << log2blocksize; + + /* Last block. */ + if (i == blockcnt - 1) { + blockend =(len + pos) % blocksize; + + /* The last portion is exactly blocksize. */ + if (!blockend) { + blockend = blocksize; + } + } + + /* First block. */ + if (i == pos / blocksize) { + skipfirst = blockoff; + blockend -= skipfirst; + } + + /* If the block number is 0 this block is not stored on disk but + is zero filled instead. */ + if (blknr) { + int status; + + status = ext2fs_devread(blknr, skipfirst, blockend, buf); + if (status == 0) + return -1; + } else + memset(buf, 0, blocksize - skipfirst); + + buf += blocksize - skipfirst; + } + return(len); +} + + +static int ext2fs_iterate_dir(ext2fs_node_t dir, char *name, ext2fs_node_t * fnode, int *ftype) +{ + unsigned int fpos = 0; + int status; + struct ext2fs_node *diro =(struct ext2fs_node *) dir; + +#ifdef DEBUG + if (name != NULL) + printf("Iterate dir %s\n", name); +#endif /* of DEBUG */ + if (!diro->inode_read) { + status = ext2fs_read_inode(diro->data, diro->ino, + &diro->inode); + if (status == 0) + return(0); + } + /* Search the file. */ + while (fpos < __le32_to_cpu(diro->inode.size)) { + struct ext2_dirent dirent; + + status = ext2fs_read_file(diro, fpos, + sizeof(struct ext2_dirent), + (char *) &dirent); + if (status < 1) + return 0; + + if (dirent.namelen != 0) { + char filename[256]; + ext2fs_node_t fdiro; + int type = FILETYPE_UNKNOWN; + + status = ext2fs_read_file(diro, + fpos + sizeof(struct ext2_dirent), + dirent.namelen, filename); + if (status < 1) + return(0); + + fdiro = malloc(sizeof(struct ext2fs_node)); + if (!fdiro) + return(0); + + + fdiro->data = diro->data; + fdiro->ino = __le32_to_cpu(dirent.inode); + + filename[dirent.namelen] = '\0'; + + if (dirent.filetype != FILETYPE_UNKNOWN) { + fdiro->inode_read = 0; + + if (dirent.filetype == FILETYPE_DIRECTORY) { + type = FILETYPE_DIRECTORY; + } else if (dirent.filetype == + FILETYPE_SYMLINK) { + type = FILETYPE_SYMLINK; + } else if (dirent.filetype == FILETYPE_REG) { + type = FILETYPE_REG; + } + } else { + /* The filetype can not be read from the dirent, get it from inode */ + + status = ext2fs_read_inode(diro->data, + __le32_to_cpu(dirent.inode), + &fdiro->inode); + if (status == 0) { + free(fdiro); + return(0); + } + fdiro->inode_read = 1; + + if ((__le16_to_cpu(fdiro->inode.mode) & + FILETYPE_INO_MASK) == + FILETYPE_INO_DIRECTORY) { + type = FILETYPE_DIRECTORY; + } else if ((__le16_to_cpu(fdiro->inode.mode) + & FILETYPE_INO_MASK) == + FILETYPE_INO_SYMLINK) { + type = FILETYPE_SYMLINK; + } else if ((__le16_to_cpu(fdiro->inode.mode) + & FILETYPE_INO_MASK) == + FILETYPE_INO_REG) { + type = FILETYPE_REG; + } + } +#ifdef DEBUG + printf("iterate >%s<\n", filename); +#endif /* of DEBUG */ + if ((name != NULL) &&(fnode != NULL) + &&(ftype != NULL)) { + if (strcmp(filename, name) == 0) { + *ftype = type; + *fnode = fdiro; + return 1; + } + } else { + if (fdiro->inode_read == 0) { + status = ext2fs_read_inode(diro->data, + __le32_to_cpu(dirent.inode), + &fdiro->inode); + if (status == 0) { + free(fdiro); + return(0); + } + fdiro->inode_read = 1; + } + switch(type) { + case FILETYPE_DIRECTORY: + puts(" "); + break; + case FILETYPE_SYMLINK: + puts(" "); + break; + case FILETYPE_REG: + puts(" "); + break; + default: + puts("< ? > "); + break; + } + printdec(__le32_to_cpu(fdiro->inode.size)); + puts(" "); + puts(filename); + puts("\n"); + } + free(fdiro); + } + fpos += __le16_to_cpu(dirent.direntlen); + } + return 0; +} + + +static char *ext2fs_read_symlink(ext2fs_node_t node) { + char *symlink; + struct ext2fs_node *diro = node; + int status; + + if (!diro->inode_read) { + status = ext2fs_read_inode(diro->data, diro->ino, + &diro->inode); + if (status == 0) { + return(0); + } + } + symlink = malloc(__le32_to_cpu(diro->inode.size) + 1); + if (!symlink) + return(0); + + /* If the filesize of the symlink is bigger than + 60 the symlink is stored in a separate block, + otherwise it is stored in the inode. */ + if (__le32_to_cpu(diro->inode.size) <= 60) { + strncpy(symlink, diro->inode.b.symlink, + __le32_to_cpu(diro->inode.size)); + } else { + status = ext2fs_read_file(diro, 0, + __le32_to_cpu(diro->inode.size), + symlink); + if (status == 0) { + free(symlink); + return(0); + } + } + symlink[__le32_to_cpu(diro->inode.size)] = '\0'; + return(symlink); +} + + +int ext2fs_find_file1 + (const char *currpath, + ext2fs_node_t currroot, ext2fs_node_t * currfound, int *foundtype) { + char fpath[strlen(currpath) + 1]; + char *name = fpath; + char *next; + int status; + int type = FILETYPE_DIRECTORY; + ext2fs_node_t currnode = currroot; + ext2fs_node_t oldnode = currroot; + + strncpy(fpath, currpath, strlen(currpath) + 1); + + /* Remove all leading slashes. */ + while (*name == '/') + name++; + + if (!*name) { + *currfound = currnode; + return 1; + } + + for(;;) { + int found; + + /* Extract the actual part from the pathname. */ + next = strchr(name, '/'); + if (next) { + /* Remove all leading slashes. */ + while (*next == '/') { + *(next++) = '\0'; + } + } + + /* At this point it is expected that the current node is a directory, check if this is true. */ + if (type != FILETYPE_DIRECTORY) { + ext2fs_free_node(currnode, currroot); + return(0); + } + + oldnode = currnode; + + /* Iterate over the directory. */ + found = ext2fs_iterate_dir(currnode, name, &currnode, &type); + if (found == 0) + return(0); + + if (found == -1) + break; + + /* Read in the symlink and follow it. */ + if (type == FILETYPE_SYMLINK) { + char *symlink; + + /* Test if the symlink does not loop. */ + if (++symlinknest == 8) { + ext2fs_free_node(currnode, currroot); + ext2fs_free_node(oldnode, currroot); + return(0); + } + + symlink = ext2fs_read_symlink(currnode); + ext2fs_free_node(currnode, currroot); + + if (!symlink) { + ext2fs_free_node(oldnode, currroot); + return(0); + } +#ifdef DEBUG + printf("Got symlink >%s<\n", symlink); +#endif /* of DEBUG */ + /* The symlink is an absolute path, go back to the root inode. */ + if (symlink[0] == '/') { + ext2fs_free_node(oldnode, currroot); + oldnode = &ext2fs_root->diropen; + } + + /* Lookup the node the symlink points to. */ + status = ext2fs_find_file1(symlink, oldnode, + &currnode, &type); + + free(symlink); + + if (status == 0) { + ext2fs_free_node(oldnode, currroot); + return(0); + } + } + + ext2fs_free_node(oldnode, currroot); + + /* Found the node! */ + if (!next || *next == '\0') { + *currfound = currnode; + *foundtype = type; + return(1); + } + name = next; + } + return -1; +} + + +int ext2fs_find_file + (const char *path, + ext2fs_node_t rootnode, ext2fs_node_t * foundnode, int expecttype) { + int status; + int foundtype = FILETYPE_DIRECTORY; + + + symlinknest = 0; + if (!path) + return(0); + + status = ext2fs_find_file1(path, rootnode, foundnode, &foundtype); + if (status == 0) + return 0; + + /* Check if the node that was found was of the expected type. */ + if ((expecttype == FILETYPE_REG) &&(foundtype != expecttype)) { + return 0; + } else if ((expecttype == FILETYPE_DIRECTORY) + &&(foundtype != expecttype)) { + return 0; + } + return 1; +} + + +int ext2fs_ls(char *dirname) { + ext2fs_node_t dirnode; + int status; + + if (ext2fs_root == NULL) + return 0; + + status = ext2fs_find_file(dirname, &ext2fs_root->diropen, &dirnode, + FILETYPE_DIRECTORY); + if (status != 1) { + puts("** Can not find directory. **\n"); + return 1; + } + ext2fs_iterate_dir(dirnode, NULL, NULL, NULL); + ext2fs_free_node(dirnode, &ext2fs_root->diropen); + return 0; +} + + +int ext2fs_open(const char *filename) { + ext2fs_node_t fdiro = NULL; + int status; + int len; + + if (ext2fs_root == NULL) + return -1; + + ext2fs_file = NULL; + status = ext2fs_find_file(filename, &ext2fs_root->diropen, &fdiro, + FILETYPE_REG); + if (status == 0) + goto fail; + + if (!fdiro->inode_read) { + status = ext2fs_read_inode(fdiro->data, fdiro->ino, + &fdiro->inode); + if (status == 0) + goto fail; + } + len = __le32_to_cpu(fdiro->inode.size); + ext2fs_file = fdiro; + return(len); + +fail: + ext2fs_free_node(fdiro, &ext2fs_root->diropen); + return -1; +} + + +int ext2fs_close(void + ) { + if ((ext2fs_file != NULL) &&(ext2fs_root != NULL)) { + ext2fs_free_node(ext2fs_file, &ext2fs_root->diropen); + ext2fs_file = NULL; + } + if (ext2fs_root != NULL) { + free(ext2fs_root); + ext2fs_root = NULL; + } + if (indir1_block != NULL) { + free(indir1_block); + indir1_block = NULL; + indir1_size = 0; + indir1_blkno = -1; + } + if (indir2_block != NULL) { + free(indir2_block); + indir2_block = NULL; + indir2_size = 0; + indir2_blkno = -1; + } + return(0); +} + + +int ext2fs_read(char *buf, unsigned len) { + int status; + + if (ext2fs_root == NULL) + return 0; + + if (ext2fs_file == NULL) + return 0; + + status = ext2fs_read_file(ext2fs_file, 0, len, buf); + return status; +} + + +int ext2fs_mount(void) { + struct ext2_data *data; + int status; + + data = malloc(sizeof(struct ext2_data)); + if (!data) + return 0; + + /* Read the superblock. */ + status = ext2fs_devread(1 * 2, 0, sizeof(struct ext2_sblock), + (char *) &data->sblock); + if (!status) + goto fail; + + /* Make sure this is an ext2 filesystem. */ + if (__le16_to_cpu(data->sblock.magic) != EXT2_MAGIC) + goto fail; + + data->diropen.data = data; + data->diropen.ino = 2; + data->diropen.inode_read = 1; + data->inode = &data->diropen.inode; + + status = ext2fs_read_inode(data, 2, data->inode); + if (status == 0) + goto fail; + + ext2fs_root = data; + + return 1; + +fail: + puts("Failed to mount ext2 filesystem...\n"); + free(data); + ext2fs_root = NULL; + + return 0; +} + diff --git a/qiboot/src/gta02/gta02.c b/qiboot/src/gta02/gta02.c index cda7a2b..fd84329 100644 --- a/qiboot/src/gta02/gta02.c +++ b/qiboot/src/gta02/gta02.c @@ -310,11 +310,12 @@ const struct board_api board_api_gta02 = { /* these are the ways we could boot GTA02 in order to try */ .kernel_source = { [0] = { - .name = "SD Card FAT Kernel", + .name = "SD Card EXT2 Kernel", .block_init = sd_card_init_gta02, .block_read = sd_card_block_read_gta02, .partition_index = 1, .filesystem = FS_EXT2, + .filepath = "boot/uImage.bin", .commandline = "mtdparts=physmap-flash:-(nor);" \ "neo1973-nand:" \ "0x00040000(qi)," \ @@ -333,7 +334,7 @@ const struct board_api board_api_gta02 = { [1] = { .name = "NAND Kernel", .block_read = nand_read_ll, - .offset_if_no_partition = 0x80000 / 512, + .offset_blocks512_if_no_partition = 0x80000 / 512, .filesystem = FS_RAW, .commandline = "mtdparts=physmap-flash:-(nor);" \ "neo1973-nand:" \ diff --git a/qiboot/src/gta03/gta03.c b/qiboot/src/gta03/gta03.c index 90f5908..778fda5 100644 --- a/qiboot/src/gta03/gta03.c +++ b/qiboot/src/gta03/gta03.c @@ -234,7 +234,7 @@ const struct board_api board_api_gta03 = { [0] = { .name = "NAND Kernel", .block_read = nand_read_ll, - .offset_if_no_partition = 0x80000 / 512, + .offset_blocks512_if_no_partition = 0x80000 / 512, .filesystem = FS_RAW, .commandline = "neo1973-nand:" \ "0x00040000(qi)," \ diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 7543e49..fe8b0ec 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -27,9 +27,14 @@ #include #define __ARM__ #include - #include #include "nand_read.h" +#include + +unsigned long partition_offset_blocks = 0; +unsigned long partition_length_blocks = 0; + +struct kernel_source const * this_kernel = 0; void bootloader_second_phase(void) @@ -41,52 +46,57 @@ void bootloader_second_phase(void) /* we try the possible kernels for this board in order */ - while (this_board->kernel_source[kernel].name) { - const char * cmdline = this_board->kernel_source[kernel].commandline; - const char *p = cmdline; + this_kernel = &this_board->kernel_source[kernel++]; + + while (this_kernel->name) { + const char *p; struct tag *params = (struct tag *)this_board->linux_tag_placement; void * kernel_dram = (void *)(TEXT_BASE - (8 * 1024 * 1024)); unsigned long crc; image_header_t *hdr; - unsigned long partition_offset_blocks = 0; - unsigned long partition_length_blocks = 0; + u32 kernel_size; + + partition_offset_blocks = 0; + partition_length_blocks = 0; /* eat leading white space */ - for (p = cmdline; *p == ' '; p++); + for (p = this_kernel->commandline; *p == ' '; p++); - puts("\nTrying kernel: "); - puts(this_board->kernel_source[kernel].name); + puts("\n\nTrying kernel: "); + puts(this_kernel->name); puts("\n"); /* if this device needs initializing, try to init it */ - if (this_board->kernel_source[kernel].block_init) - if ((this_board->kernel_source[kernel].block_init)()) { + if (this_kernel->block_init) + if ((this_kernel->block_init)()) { puts("block device init failed\n"); - kernel++; + this_kernel = &this_board-> + kernel_source[kernel++]; continue; } /* if there's a partition table implied, parse it, otherwise * just use a fixed offset */ - if (this_board->kernel_source[kernel].partition_index) { + if (this_kernel->partition_index) { unsigned char *p = kernel_dram; - if (this_board->kernel_source[kernel].block_read( - kernel_dram, 0, 4) < 0) { + if (this_kernel->block_read(kernel_dram, 0, 4) < 0) { puts("Bad partition read\n"); - kernel++; + this_kernel = &this_board-> + kernel_source[kernel++]; continue; } if ((p[0x1fe] != 0x55) || (p[0x1ff] != 0xaa)) { puts("partition signature missing\n"); - kernel++; + this_kernel = &this_board-> + kernel_source[kernel++]; continue; } - p += 0x1be + 8 + (0x10 * (this_board-> - kernel_source[kernel].partition_index - 1)); + p += 0x1be + 8 + (0x10 * + (this_kernel->partition_index - 1)); partition_offset_blocks = (((u32)p[3]) << 24) | (((u32)p[2]) << 16) | @@ -97,39 +107,89 @@ void bootloader_second_phase(void) (((u32)p[5]) << 8) | p[4]; - } else - partition_offset_blocks = this_board-> - kernel_source[kernel].offset_if_no_partition; + puts(" Partition: "); + printdec(this_kernel->partition_index); + puts(" start +"); + printdec(partition_offset_blocks); + puts(" 512-byte blocks, size "); + printdec(partition_length_blocks / 2048); + puts(" MiB\n"); - if (this_board->kernel_source[kernel].block_read( - kernel_dram, partition_offset_blocks, 8) < 0) { - puts ("Bad kernel header\n"); - kernel++; - continue; + } else + partition_offset_blocks = + this_kernel->offset_blocks512_if_no_partition; + + switch (this_kernel->filesystem) { + case FS_EXT2: + if (!ext2fs_mount()) { + puts("Unable to mount ext2 filesystem\n"); + this_kernel = &this_board-> + kernel_source[kernel++]; + continue; + } + puts(" EXT2 open: "); + puts(this_kernel->filepath); + puts("\n"); + if (ext2fs_open(this_kernel->filepath) < 0) { + puts("Open failed\n"); + this_kernel = &this_board-> + kernel_source[kernel++]; + continue; + } + ext2fs_read(kernel_dram, 4096); + break; + case FS_FAT: + /* FIXME */ + case FS_RAW: + puts(" RAW open: +"); + printdec(partition_offset_blocks); + puts(" 512-byte blocks\n"); + if (this_kernel->block_read(kernel_dram, + partition_offset_blocks, 8) < 0) { + puts ("Bad kernel header\n"); + this_kernel = &this_board-> + kernel_source[kernel++]; + continue; + } + break; } hdr = (image_header_t *)kernel_dram; - if (_ntohl(hdr->ih_magic) != IH_MAGIC) { + if (__be32_to_cpu(hdr->ih_magic) != IH_MAGIC) { puts("bad magic "); print32(hdr->ih_magic); - kernel++; + puts("\n"); + this_kernel = &this_board->kernel_source[kernel++]; continue; } - puts(" Found: "); + puts(" Found: \""); puts((const char *)hdr->ih_name); - puts("\n Size: "); - printdec(_ntohl(hdr->ih_size) >> 10); + puts("\"\n Size: "); + printdec(__be32_to_cpu(hdr->ih_size) >> 10); puts(" KiB\n"); - if ((this_board->kernel_source[kernel].block_read)( - kernel_dram, partition_offset_blocks, - ((_ntohl(hdr->ih_size) + sizeof(image_header_t) + - 2048) & ~(2048 - 1)) >> 9) < 0) { - puts ("Bad kernel read\n"); - kernel++; - continue; + kernel_size = ((__be32_to_cpu(hdr->ih_size) + + sizeof(image_header_t) + 2048) & ~(2048 - 1)); + + switch (this_kernel->filesystem) { + case FS_EXT2: + /* This read API always restarts from beginning */ + ext2fs_read(kernel_dram, kernel_size); + break; + case FS_FAT: + /* FIXME */ + case FS_RAW: + if ((this_kernel->block_read)( + kernel_dram, partition_offset_blocks, + kernel_size >> 9) < 0) { + puts ("Bad kernel read\n"); + this_kernel = &this_board-> + kernel_source[kernel++]; + continue; + } + break; } puts(" Cmdline: "); @@ -142,14 +202,14 @@ void bootloader_second_phase(void) * even though it costs us some time */ crc = crc32(0, kernel_dram + sizeof(image_header_t), - _ntohl(hdr->ih_size)); - if (crc != _ntohl(hdr->ih_dcrc)) { + __be32_to_cpu(hdr->ih_size)); + if (crc != __be32_to_cpu(hdr->ih_dcrc)) { puts("\nKernel CRC ERROR: read 0x"); print32(crc); puts(" vs hdr CRC 0x"); - print32(_ntohl(hdr->ih_dcrc)); + print32(__be32_to_cpu(hdr->ih_dcrc)); puts("\n"); - kernel++; + this_kernel = &this_board->kernel_source[kernel++]; continue; } diff --git a/qiboot/src/start_qi.c b/qiboot/src/start_qi.c index 3d993fd..d4f4905 100644 --- a/qiboot/src/start_qi.c +++ b/qiboot/src/start_qi.c @@ -98,7 +98,6 @@ void start_qi(void) puts(", "); board_variant = (this_board->get_board_variant)(); puts(board_variant->name); - puts("\n"); /* * jump to bootloader_second_phase() running from DRAM copy diff --git a/qiboot/src/utils.c b/qiboot/src/utils.c index 62f7c17..3d72ec2 100644 --- a/qiboot/src/utils.c +++ b/qiboot/src/utils.c @@ -23,6 +23,9 @@ #include #include +static u8 malloc_pool[100 * 1024]; +void * malloc_pointer = &malloc_pool[0]; + int raise(int n) { return 0; @@ -49,15 +52,39 @@ char *strcpy(char *dest, const char *src) return dest_orig; } -unsigned int _ntohl(unsigned int n) { - return ((n & 0xff) << 24) | ((n & 0xff00) << 8) | - ((n & 0xff0000) >> 8) | ((n & 0xff000000) >> 24); +char *strncpy(char *dest, const char *src, size_t n) +{ + char * dest_orig = dest; + + while (*src && n--) + *dest++ = *src++; + + return dest_orig; } -unsigned int _letocpu(unsigned int n) { - return n; + +int strcmp(const char *s1, const char *s2) +{ + while (1) { + if (*s1 != *s2) + return *s1 - *s2; + if (!*s1) + return 0; + s1++; + s2++; + } } +char *strchr(const char *s, int c) +{ + while ((*s) && (*s != c)) + s++; + + if (*s == c) + return (char *)s; + + return NULL; +} int puts(const char *string) { @@ -214,3 +241,47 @@ unsigned long crc32(unsigned long crc, const unsigned char *buf, return crc ^ 0xffffffffL; } + +void *memcpy(void *dest, const void *src, size_t n) +{ + u8 const * ps = src; + u8 * pd = dest; + + while (n--) + *pd++ = *ps++; + + return dest; +} + +void *memset(void *s, int c, size_t n) +{ + u8 * p = s; + + while (n--) + *p++ = c; + + return s; +} + +/* improbably simple malloc and free for small and non-intense allocation + * just moves the allocation ptr forward each time and ignores free + */ + +void *malloc(size_t size) +{ + void *p = malloc_pointer; + + malloc_pointer += size; + + if (((u8 *)malloc_pointer - &malloc_pool[0]) > sizeof(malloc_pool)) { + puts("Ran out of malloc pool\n"); + while (1) + ; + } + + return p; +} + +void free(void *ptr) +{ +} From a560858377c770706617166aa13a6004ae24e66a Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:37 +0000 Subject: [PATCH 067/248] add-jtag-detection.patch This adds capability to use single qi image for JTAG load action as well as execution from NAND. It requires JTAG script to load the image at 0x0 and 0x33000000 addresses, then set data at 0x04 address to 0xffffffff. This eliminates the lowlevel_foo stuff from U-Boot world. Signed-off-by: Andy Green --- qiboot/src/start.S | 3 +++ qiboot/src/start_qi.c | 42 ++++++++++++++++++++++++++++++------------ 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/qiboot/src/start.S b/qiboot/src/start.S index 7e02ecf..43cfffd 100644 --- a/qiboot/src/start.S +++ b/qiboot/src/start.S @@ -24,6 +24,9 @@ .globl _start _start: b start_code +/* if we are injected by JTAG, the script sets _istag content to nonzero */ +_is_jtag: + .word 0 _TEXT_BASE: .word TEXT_BASE diff --git a/qiboot/src/start_qi.c b/qiboot/src/start_qi.c index d4f4905..ac7d42e 100644 --- a/qiboot/src/start_qi.c +++ b/qiboot/src/start_qi.c @@ -47,21 +47,39 @@ void start_qi(void) int n = 0; int board = 0; const struct board_variant * board_variant; + const u32 * p_is_jtag = (const u32 *)4; + /* - * We got the first 4KBytes of the bootloader pulled into the - * steppingstone SRAM for free. Now we pull the whole bootloader - * image into SDRAM. + * well, we can be running on this CPU two different ways. * - * 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. + * 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. */ - /* We randomly pull 24KBytes of bootloader */ - if (nand_read_ll((unsigned char *)TEXT_BASE, 0, 24 * 1024 / 512) < 0) - goto unhappy; + if (!*p_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 @@ -69,7 +87,7 @@ void start_qi(void) this_board = boards[board]; while (!n) { - if (board >= ARRAY_SIZE(boards)) + if (board > ARRAY_SIZE(boards)) /* can't put diagnostic on serial... too early */ goto unhappy; From 4542548a35ea432ebcc40f6981623ae47a5717e3 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:37 +0000 Subject: [PATCH 068/248] fix-gta03-pclk.patch GTA03 PCLK runs at 66MHz, we need to set that right to get 1150kbps serial OK. Signed-off-by: Andy Green --- qiboot/src/gta03/gta03.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiboot/src/gta03/gta03.c b/qiboot/src/gta03/gta03.c index 778fda5..27e3022 100644 --- a/qiboot/src/gta03/gta03.c +++ b/qiboot/src/gta03/gta03.c @@ -156,7 +156,7 @@ void port_init_gta03(void) *MPLLCON = ((169 << 12) + (2 << 4) + 1); - serial_init_115200_s3c24xx(GTA03_DEBUG_UART, 50 /*MHz PCLK */); + serial_init_115200_s3c24xx(GTA03_DEBUG_UART, 66 /*MHz PCLK */); } /** From d06a3c2c3a1471e9d1301fef48a3bba14fcd4a68 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:37 +0000 Subject: [PATCH 069/248] add-openocd-script.patch This is the script for gta03 load by openocd. We use the single qi image for all purposes now so U-Boot lowlevel_foo style crap is dead. We have to run the first part of init before copying qi image to TEXT_BASE (0x33000000) because DRAM is not functional until then. Fixed branchthrough at 0x8 is used as a place to hang the breakpoint. Signed-off-by: Andy Green --- qiboot/gta03-qi.ocd | 33 +++++++++++++++++++++++++++++++++ qiboot/src/start.S | 16 ++++++++++++---- 2 files changed, 45 insertions(+), 4 deletions(-) create mode 100755 qiboot/gta03-qi.ocd diff --git a/qiboot/gta03-qi.ocd b/qiboot/gta03-qi.ocd new file mode 100755 index 0000000..16cf0bd --- /dev/null +++ b/qiboot/gta03-qi.ocd @@ -0,0 +1,33 @@ +# gta03 Qi script +# Andy Green + +reset halt +wait_halt + +# 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 +# + diff --git a/qiboot/src/start.S b/qiboot/src/start.S index 43cfffd..1514e0f 100644 --- a/qiboot/src/start.S +++ b/qiboot/src/start.S @@ -28,6 +28,17 @@ _start: b start_code _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 @@ -192,10 +203,7 @@ clbss_l: /* we are going to jump into the C part of the init now */ spin: - ldr pc, _start_armboot - -_start_armboot: - .word start_qi + b _steppingstone_done /* ************************************************************************* From ba82ccbff1028004c76fc7a0145e19b5505add98 Mon Sep 17 00:00:00 2001 From: xiangfu Date: Fri, 28 Nov 2008 10:16:37 +0000 Subject: [PATCH 070/248] Subject: add-mkudfu-to-qi X-Git-Url: http://git.openmoko.org/?p=qi.git;a=commitdiff_plain;h=bdc874553c41b5c540188798928433ad9ef89a76 add-mkudfu-to-qi --- qiboot/Makefile | 14 +- qiboot/config.mk | 3 +- qiboot/tools/Makefile | 39 ++++ qiboot/tools/mkudfu.c | 314 +++++++++++++++++++++++++++++++++ qiboot/tools/usb_dfu_trailer.h | 31 ++++ 5 files changed, 396 insertions(+), 5 deletions(-) create mode 100644 qiboot/tools/Makefile create mode 100644 qiboot/tools/mkudfu.c create mode 100644 qiboot/tools/usb_dfu_trailer.h diff --git a/qiboot/Makefile b/qiboot/Makefile index cdb075e..c1f9468 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -25,20 +25,20 @@ BUILD_VERSION := ${BUILD_BRANCH}_${BUILD_HEAD} LDS = src/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}" LDFLAGS = -#START = start.o lowlevel_init.o + S_SRCS = src/start.S src/lowlevel_init.S S_OBJS = $(patsubst %.S,%.o, $(S_SRCS)) C_SRCS = $(wildcard src/*.c) $(wildcard src/gt*/*.c) \ $(wildcard src/drivers/*.c) $(wildcard src/fs/*.c) C_OBJS = $(patsubst %.c,%.o, $(C_SRCS)) -#SRCS := $(START: .o=.S) $(COBJS: .o=.c) SRCS = ${S_SRCS} ${C_SRCS} OBJS = ${S_OBJS} ${C_OBJS} LIBS = -L${COMPILER_LIB_PATH} -lgcc @@ -52,6 +52,8 @@ TARGET = image/start_qi_all IMAGE = $(IMAGE_DIR)/qi UDFU_IMAGE = $(IMAGE_DIR)/qi.udfu +MKUDFU = $(TOOLS)/mkudfu + %.o: %.S @$(CC) $(CFLAGS) -o $@ $< @@ -60,9 +62,12 @@ UDFU_IMAGE = $(IMAGE_DIR)/qi.udfu all:${UDFU_IMAGE} -${OBJS}:${SRCS} +${OBJS}:${SRCS} ${INCLUDE}/*.h -${UDFU_IMAGE}:${OBJS} +${MKUDFU}: + make -C $(TOOLS) + +${UDFU_IMAGE}:${OBJS} ${MKUDFU} @$(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} \ @@ -71,3 +76,4 @@ ${UDFU_IMAGE}:${OBJS} clean: @rm -f src/*.o src/*~ include/*~ ${IMAGE}* ${TARGET} ${UDFU_IMAGE} + @make clean -C $(TOOLS) \ No newline at end of file diff --git a/qiboot/config.mk b/qiboot/config.mk index b8cb833..1fee1a3 100644 --- a/qiboot/config.mk +++ b/qiboot/config.mk @@ -14,8 +14,9 @@ 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 +#MKUDFU = ../uboot/u-boot/tools/mkudfu export CROSS_COMPILE AD LD CC OBJCOPY OBJDUMP MKUDFU diff --git a/qiboot/tools/Makefile b/qiboot/tools/Makefile new file mode 100644 index 0000000..e2a5409 --- /dev/null +++ b/qiboot/tools/Makefile @@ -0,0 +1,39 @@ +#(C) Copyright 2007 OpenMoko, Inc. +# Author: xiangfu liu +# +# 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 ../config.mk + +CC = ${HOSTCC} +CFLAGS = -Wall +C_SRCS = $(wildcard *.c) +C_OBJS = $(patsubst %.c,%.o, $(C_SRCS)) +SRCS = ${C_SRCS} +OBJS = ${C_OBJS} +TARGET = mkudfu + +%.o: %.c + CC $(CFLAGS) -o $@ $< + +all:${TARGET} + +${TARGET}:${SRCS} + +clean: + @rm -f *.o *~ ${TARGET} diff --git a/qiboot/tools/mkudfu.c b/qiboot/tools/mkudfu.c new file mode 100644 index 0000000..57ac294 --- /dev/null +++ b/qiboot/tools/mkudfu.c @@ -0,0 +1,314 @@ +/* + * USB DFU file trailer tool + * (C) Copyright by OpenMoko, Inc. + * Author: Harald Welte + * + * based on mkimage.c, copyright information as follows: + * + * (C) Copyright 2000-2004 + * DENX Software Engineering + * Wolfgang Denk, wd@denx.de + * 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 + */ + +#include +#include +#include +#include +#include +#ifndef __WIN32__ +#include /* for host / network byte order conversions */ +#endif +#include +#include +#include +#include + +#if defined(__BEOS__) || defined(__NetBSD__) || defined(__APPLE__) +#include +#endif + +#ifdef __WIN32__ +typedef unsigned int __u32; + +#define SWAP_LONG(x) \ + ((__u32)( \ + (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \ + (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \ + (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \ + (((__u32)(x) & (__u32)0xff000000UL) >> 24) )) +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; + +#define ntohl(a) SWAP_LONG(a) +#define htonl(a) SWAP_LONG(a) +#endif /* __WIN32__ */ + +#ifndef O_BINARY /* should be define'd on __WIN32__ */ +#define O_BINARY 0 +#endif + +#include "usb_dfu_trailer.h" + +extern int errno; + +#ifndef MAP_FAILED +#define MAP_FAILED (-1) +#endif + +static char *cmdname; + +static char *datafile; +static char *imagefile; + + +static void usage() +{ + fprintf (stderr, "%s - create / display u-boot DFU trailer\n", cmdname); + fprintf (stderr, "Usage: %s -l image\n" + " -l ==> list image header information\n" + " %s -v VID -p PID -r REV -d data_file image\n", + cmdname, cmdname); + fprintf (stderr, " -v ==> set vendor ID to 'VID'\n" + " -p ==> set product ID system to 'PID'\n" + " -r ==> set hardware revision to 'REV'\n" + " -d ==> use 'data_file' as input file\n" + ); + exit (EXIT_FAILURE); +} + +static void print_trailer(struct uboot_dfu_trailer *trailer) +{ + printf("===> DFU Trailer information:\n"); + printf("Trailer Vers.: %d\n", trailer->version); + printf("Trailer Length: %d\n", trailer->length); + printf("VendorID: 0x%04x\n", trailer->vendor); + printf("ProductID: 0x%04x\n", trailer->product); + printf("HW Revision: 0x%04x\n", trailer->revision); +} + +static void copy_file (int ifd, const char *datafile, int pad) +{ + int dfd; + struct stat sbuf; + unsigned char *ptr; + int tail; + int zero = 0; + int offset = 0; + int size; + + if ((dfd = open(datafile, O_RDONLY|O_BINARY)) < 0) { + fprintf (stderr, "%s: Can't open %s: %s\n", + cmdname, datafile, strerror(errno)); + exit (EXIT_FAILURE); + } + + if (fstat(dfd, &sbuf) < 0) { + fprintf (stderr, "%s: Can't stat %s: %s\n", + cmdname, datafile, strerror(errno)); + exit (EXIT_FAILURE); + } + + ptr = (unsigned char *)mmap(0, sbuf.st_size, + PROT_READ, MAP_SHARED, dfd, 0); + if (ptr == (unsigned char *)MAP_FAILED) { + fprintf (stderr, "%s: Can't read %s: %s\n", + cmdname, datafile, strerror(errno)); + exit (EXIT_FAILURE); + } + + size = sbuf.st_size - offset; + if (write(ifd, ptr + offset, size) != size) { + fprintf (stderr, "%s: Write error on %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + if (pad && ((tail = size % 4) != 0)) { + + if (write(ifd, (char *)&zero, 4-tail) != 4-tail) { + fprintf (stderr, "%s: Write error on %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + } + + (void) munmap((void *)ptr, sbuf.st_size); + (void) close (dfd); +} + + +int main(int argc, char **argv) +{ + int ifd; + int lflag = 0; + struct stat sbuf; + u_int16_t opt_vendor, opt_product, opt_revision; + struct uboot_dfu_trailer _hdr, _mirror, *hdr = &_hdr; + + opt_vendor = opt_product = opt_revision = 0; + + cmdname = *argv; + + while (--argc > 0 && **++argv == '-') { + while (*++*argv) { + switch (**argv) { + case 'l': + lflag = 1; + break; + case 'v': + if (--argc <= 0) + usage (); + opt_vendor = strtoul(*++argv, NULL, 16); + goto NXTARG; + case 'p': + if (--argc <= 0) + usage (); + opt_product = strtoul(*++argv, NULL, 16); + goto NXTARG; + case 'r': + if (--argc <= 0) + usage (); + opt_revision = strtoul(*++argv, NULL, 16); + goto NXTARG; + case 'd': + if (--argc <= 0) + usage (); + datafile = *++argv; + goto NXTARG; + case 'h': + usage(); + break; + default: + usage(); + } + } +NXTARG: ; + } + + if (argc != 1) + usage(); + + imagefile = *argv; + + if (lflag) + ifd = open(imagefile, O_RDONLY|O_BINARY); + else + ifd = open(imagefile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666); + + if (ifd < 0) { + fprintf (stderr, "%s: Can't open %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + if (lflag) { + unsigned char *ptr; + /* list header information of existing image */ + if (fstat(ifd, &sbuf) < 0) { + fprintf (stderr, "%s: Can't stat %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + if ((unsigned)sbuf.st_size < sizeof(struct uboot_dfu_trailer)) { + fprintf (stderr, + "%s: Bad size: \"%s\" is no valid image\n", + cmdname, imagefile); + exit (EXIT_FAILURE); + } + + ptr = (unsigned char *)mmap(0, sbuf.st_size, + PROT_READ, MAP_SHARED, ifd, 0); + if ((caddr_t)ptr == (caddr_t)-1) { + fprintf (stderr, "%s: Can't read %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + dfu_trailer_mirror(hdr, ptr+sbuf.st_size); + + if (hdr->magic != UBOOT_DFU_TRAILER_MAGIC) { + fprintf (stderr, + "%s: Bad Magic Number: \"%s\" is no valid image\n", + cmdname, imagefile); + exit (EXIT_FAILURE); + } + + /* for multi-file images we need the data part, too */ + print_trailer(hdr); + + (void) munmap((void *)ptr, sbuf.st_size); + (void) close (ifd); + + exit (EXIT_SUCCESS); + } + + /* if we're not listing: */ + + copy_file (ifd, datafile, 0); + + memset (hdr, 0, sizeof(struct uboot_dfu_trailer)); + + /* Build new header */ + hdr->version = UBOOT_DFU_TRAILER_V1; + hdr->magic = UBOOT_DFU_TRAILER_MAGIC; + hdr->length = sizeof(struct uboot_dfu_trailer); + hdr->vendor = opt_vendor; + hdr->product = opt_product; + hdr->revision = opt_revision; + + print_trailer(hdr); + dfu_trailer_mirror(&_mirror, (unsigned char *)hdr+sizeof(*hdr)); + + if (write(ifd, &_mirror, sizeof(struct uboot_dfu_trailer)) + != sizeof(struct uboot_dfu_trailer)) { + fprintf (stderr, "%s: Write error on %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + /* We're a bit of paranoid */ +#if defined(_POSIX_SYNCHRONIZED_IO) && !defined(__sun__) && !defined(__FreeBSD__) + (void) fdatasync (ifd); +#else + (void) fsync (ifd); +#endif + + if (fstat(ifd, &sbuf) < 0) { + fprintf (stderr, "%s: Can't stat %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + /* We're a bit of paranoid */ +#if defined(_POSIX_SYNCHRONIZED_IO) && !defined(__sun__) && !defined(__FreeBSD__) + (void) fdatasync (ifd); +#else + (void) fsync (ifd); +#endif + + if (close(ifd)) { + fprintf (stderr, "%s: Write error on %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + exit (EXIT_SUCCESS); +} diff --git a/qiboot/tools/usb_dfu_trailer.h b/qiboot/tools/usb_dfu_trailer.h new file mode 100644 index 0000000..3903b85 --- /dev/null +++ b/qiboot/tools/usb_dfu_trailer.h @@ -0,0 +1,31 @@ +#ifndef _USB_DFU_TRAILER_H +#define _USB_DFU_TRAILER_H + +/* trailer handling for DFU files */ + +#define UBOOT_DFU_TRAILER_V1 1 +#define UBOOT_DFU_TRAILER_MAGIC 0x19731978 +struct uboot_dfu_trailer { + u_int32_t magic; + u_int16_t version; + u_int16_t length; + u_int16_t vendor; + u_int16_t product; + u_int32_t revision; +} __attribute__((packed)); + +/* we mirror the trailer because we want it to be longer in later versions + * while keeping backwards compatibility */ +static inline void dfu_trailer_mirror(struct uboot_dfu_trailer *trailer, + unsigned char *eof) +{ + int i; + int len = sizeof(struct uboot_dfu_trailer); + unsigned char *src = eof - len; + unsigned char *dst = (unsigned char *) trailer; + + for (i = 0; i < len; i++) + dst[len-1-i] = src[i]; +} + +#endif /* _USB_DFU_TRAILER_H */ From dca4815a1ebdfecc482f1e3e4fbd405afbaddd1a Mon Sep 17 00:00:00 2001 From: Matt Hsu Date: Fri, 28 Nov 2008 10:16:37 +0000 Subject: [PATCH 071/248] From b25a27989d72a43f2064dcbb85ad2ea0f2bea4b7 Mon Sep 17 00:00:00 2001 Subject: [PATCH] - correct machine id of gta03 - add mtdparts prefix in the kernel command line Signed-off-by: Matt Hsu --- qiboot/src/gta03/gta03.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qiboot/src/gta03/gta03.c b/qiboot/src/gta03/gta03.c index 27e3022..2ee037c 100644 --- a/qiboot/src/gta03/gta03.c +++ b/qiboot/src/gta03/gta03.c @@ -221,7 +221,7 @@ static void putc_gta03(char c) */ const struct board_api board_api_gta03 = { .name = "GTA03", - .linux_machine_id = 1808, + .linux_machine_id = 1866, .linux_mem_start = 0x30000000, .linux_mem_size = (128 * 1024 * 1024), .linux_tag_placement = 0x30000000 + 0x100, @@ -236,7 +236,7 @@ const struct board_api board_api_gta03 = { .block_read = nand_read_ll, .offset_blocks512_if_no_partition = 0x80000 / 512, .filesystem = FS_RAW, - .commandline = "neo1973-nand:" \ + .commandline = "mtdparts=neo1973-nand:" \ "0x00040000(qi)," \ "0x00040000(cmdline)," \ "0x00800000(backupkernel)," \ From 49f96ef705014376c7ff4618c7efb8155e062f1f Mon Sep 17 00:00:00 2001 From: xiangfu Date: Fri, 28 Nov 2008 10:16:37 +0000 Subject: [PATCH 072/248] Subject: we don't need calc_pclk.c we don't need calc_pclk.c --- qiboot/src/blink_led.c | 1 + qiboot/src/blink_led.h | 3 -- qiboot/src/calc_pclk.c | 78 ------------------------------------------ 3 files changed, 1 insertion(+), 81 deletions(-) delete mode 100644 qiboot/src/calc_pclk.c diff --git a/qiboot/src/blink_led.c b/qiboot/src/blink_led.c index e1e7a94..6bac9e7 100644 --- a/qiboot/src/blink_led.c +++ b/qiboot/src/blink_led.c @@ -19,6 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ + #include "blink_led.h" int delay(int time) diff --git a/qiboot/src/blink_led.h b/qiboot/src/blink_led.h index a32f395..a42333a 100644 --- a/qiboot/src/blink_led.h +++ b/qiboot/src/blink_led.h @@ -31,9 +31,6 @@ #define ORANGE_ON() (GPBDAT |= (0x1)) #define BLUE_ON() (GPBDAT |= (0x2)) -#define ORANGE 1; -#define BLUE 0; - int orange_on(int times); int blue_on(int times); int blink_led(void); diff --git a/qiboot/src/calc_pclk.c b/qiboot/src/calc_pclk.c deleted file mode 100644 index 777ad03..0000000 --- a/qiboot/src/calc_pclk.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * (C) Copyright 2007 OpenMoko, Inc. - * Author: xiangfu liu - * - * - * 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 code is not good, some define is - * is already show in other files - */ - -# define CLKDIVN_val (7) -# define CAMDIVN_val (0) -# define CONFIG_SYS_CLK_FREQ (12000000)/* the GTA02 has this input clock */ - -# define MPLL ((142 << 12) + (7 << 4) + 1) -# define BAUDRATE (115200) - -typedef unsigned long ulong; - -static ulong get_PLLCLK(int pllreg) -{ - ulong r, m, p, s; - - if (pllreg == MPLL){ - r = MPLL; - } - - m = ((r & 0xFF000) >> 12) + 8; - p = ((r & 0x003F0) >> 4) + 2; - s = r & 0x3; - /* To avoid integer overflow, changed the calc order */ - if (pllreg == MPLL) - return ( 2 * m * (CONFIG_SYS_CLK_FREQ / (p << s )) ); - else - return ( m * (CONFIG_SYS_CLK_FREQ / (p << s )) ); -} - -ulong get_FCLK(void) -{ - return(get_PLLCLK(MPLL)); -} - - -ulong get_HCLK(void) -{ - switch (CLKDIVN_val & 0x6) { - case 0x0: - return get_FCLK(); - case 0x2: - return get_FCLK()/2; - case 0x4: - return (CAMDIVN_val & 0x200) ? get_FCLK()/8 : get_FCLK()/4; - case 0x6: - return (CAMDIVN_val & 0x100) ? get_FCLK()/6 : get_FCLK()/3; - } - return 0; -} - -ulong get_PCLK(void) -{ - return((CLKDIVN_val & 0x1) ? get_HCLK()/2 : get_HCLK()); -} - From 9f3614edd089d538de81657d06b6f75059adaf6c Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:37 +0000 Subject: [PATCH 073/248] qi-change-gta02-ext3-sd.patch Signed-off-by: Andy Green --- qiboot/src/gta02/gta02.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiboot/src/gta02/gta02.c b/qiboot/src/gta02/gta02.c index fd84329..ff2149d 100644 --- a/qiboot/src/gta02/gta02.c +++ b/qiboot/src/gta02/gta02.c @@ -324,7 +324,7 @@ const struct board_api board_api_gta02 = { "0x000a0000(extra)," \ "0x00040000(identity)," \ "0x0f6a0000(backuprootfs) " \ - "rootfstype=ext2 " \ + "rootfstype=ext3 " \ "root=/dev/mmcblk0p1 " \ "console=ttySAC2,115200 " \ "loglevel=4 " \ From 4bdb43cc93d9210ce50b01acdfdca772b33fb6a8 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:37 +0000 Subject: [PATCH 074/248] qi-fix-large-sdhc-timeout.patch This patch increases the timeout for card initializaton so it works with 8GB Sandisk uSDHC, and adds the size computation for SDHC as well. Signed-off-by: Andy Green --- qiboot/src/drivers/glamo-mmc.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/qiboot/src/drivers/glamo-mmc.c b/qiboot/src/drivers/glamo-mmc.c index 051c810..16ca21a 100644 --- a/qiboot/src/drivers/glamo-mmc.c +++ b/qiboot/src/drivers/glamo-mmc.c @@ -49,6 +49,22 @@ static enum card_type card_type = CARDTYPE_NONE; int mmc_read(unsigned long src, u8 *dst, int size); +#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; \ + }) + + + int q; void udelay(int n) @@ -578,7 +594,7 @@ static void print_sd_cid(const struct sd_cid *cid) int mmc_init(int verbose) { - int retries = 16, rc = -1; + int retries = 50, rc = -1; int resp; u8 response[16]; // mmc_cid_t *mmc_cid = (mmc_cid_t *)response; @@ -774,9 +790,18 @@ int mmc_init(int verbose) // mmc_dev.blksz = 512; // mmc_dev.lba = (((unsigned long)1 << csd->c_size_mult1) * // (unsigned long)csd->c_size) >> 9; - puts(" MMC/SD size: "); - printdec((((unsigned long)1 << csd->c_size_mult1) * - (unsigned long)csd->c_size) >> 10); + + switch (card_type) { + case CARDTYPE_SDHC: + puts(" SDHC size: "); + printdec((UNSTUFF_BITS(((u32 *)&response[0]), 48, 22) + + 1) / 2); + break; + default: + puts(" MMC/SD size: "); + printdec((((unsigned long)1 << csd->c_size_mult1) * + (unsigned long)(csd->c_size)) >> 10); + } puts(" MiB\n"); } From b2995f8b399617d2aa31fac7e194c3ae598f60e9 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:38 +0000 Subject: [PATCH 075/248] qi-fix-malloc-alignment.patch Noticed malloc() could become unaligned Signed-off-by: Andy Green --- qiboot/src/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiboot/src/utils.c b/qiboot/src/utils.c index 3d72ec2..7e92288 100644 --- a/qiboot/src/utils.c +++ b/qiboot/src/utils.c @@ -271,7 +271,7 @@ void *malloc(size_t size) { void *p = malloc_pointer; - malloc_pointer += size; + malloc_pointer += (size & ~3) + 4; if (((u8 *)malloc_pointer - &malloc_pool[0]) > sizeof(malloc_pool)) { puts("Ran out of malloc pool\n"); From 2e2480ff21d4f3d298a4050b4c03af77a4d070de Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:38 +0000 Subject: [PATCH 076/248] qi-fix-slow-first-bulk.patch This patch performs the equivalent init actions to the SDHC slow unitl first bulk patch in kernel, it allows us to work with large SDHC cards which exceed Glamo timeout capability at 16MHz for first access. Signed-off-by: Andy Green --- qiboot/src/drivers/glamo-mmc.c | 21 ++++++++++++++--- qiboot/src/fs/ext2.c | 41 ++++++++++++++++++++++++++-------- qiboot/src/phase2.c | 3 ++- 3 files changed, 52 insertions(+), 13 deletions(-) diff --git a/qiboot/src/drivers/glamo-mmc.c b/qiboot/src/drivers/glamo-mmc.c index 16ca21a..39d4199 100644 --- a/qiboot/src/drivers/glamo-mmc.c +++ b/qiboot/src/drivers/glamo-mmc.c @@ -106,12 +106,16 @@ unsigned long mmc_bread(int dev_num, unsigned long blknr, unsigned long blkcnt, void *dst) { unsigned long src = blknr * MMC_BLOCK_SIZE; + int ret; if (!blkcnt) return 0; /* printf("mmc_bread(%d, %ld, %ld, %p)\n", dev_num, blknr, blkcnt, dst); */ - mmc_read(src, dst, blkcnt * MMC_BLOCK_SIZE); + ret = mmc_read(src, dst, blkcnt * MMC_BLOCK_SIZE); + if (ret) + return ret; + return blkcnt; } @@ -443,6 +447,8 @@ int mmc_read(unsigned long src, u8 *dst, int size) resp = mmc_cmd(MMC_SET_BLOCKLEN, MMC_BLOCK_SIZE, MMC_CMD_AC | MMC_RSP_R1, 0, 0, 0, (u16 *)&response[0]); + if (resp) + return resp; while (size) { switch (card_type) { @@ -460,6 +466,15 @@ int mmc_read(unsigned long src, u8 *dst, int size) (u16 *)&response[0]); break; } + + if (resp) + return resp; + + /* final speed 16MHz */ + glamo_reg_write((glamo_reg_read(GLAMO_REG_CLOCK_GEN8) & + 0xff00) | 2, GLAMO_REG_CLOCK_GEN8); + + do_pio_read((u16 *)dst, MMC_BLOCK_SIZE >> 1); if (size >= MMC_BLOCK_SIZE) @@ -824,9 +839,9 @@ int mmc_init(int verbose) } #endif - /* crank the clock to the final speed, 16MHz */ + /* set the clock to slow until first bulk completes (for slow SDHC) */ - glamo_reg_write((glamo_reg_read(GLAMO_REG_CLOCK_GEN8) & 0xff00) | 2, + glamo_reg_write((glamo_reg_read(GLAMO_REG_CLOCK_GEN8) & 0xff00) | 32, GLAMO_REG_CLOCK_GEN8); return rc; diff --git a/qiboot/src/fs/ext2.c b/qiboot/src/fs/ext2.c index 25616e5..ffbffa0 100644 --- a/qiboot/src/fs/ext2.c +++ b/qiboot/src/fs/ext2.c @@ -453,9 +453,18 @@ static int ext2fs_iterate_dir(ext2fs_node_t dir, char *name, ext2fs_node_t * fno if (!diro->inode_read) { status = ext2fs_read_inode(diro->data, diro->ino, &diro->inode); - if (status == 0) + if (status == 0) { + printdec(diro->ino); + puts("failed to read inode\n"); return(0); + } + } else { + puts("fail\n"); } + printdec(fpos); + puts(" "); + printdec(diro->inode.size); + puts("\n"); /* Search the file. */ while (fpos < __le32_to_cpu(diro->inode.size)) { struct ext2_dirent dirent; @@ -463,8 +472,10 @@ static int ext2fs_iterate_dir(ext2fs_node_t dir, char *name, ext2fs_node_t * fno status = ext2fs_read_file(diro, fpos, sizeof(struct ext2_dirent), (char *) &dirent); - if (status < 1) + if (status < 1) { + puts("ext2fs_read_file ret < 1\n"); return 0; + } if (dirent.namelen != 0) { char filename[256]; @@ -474,12 +485,16 @@ static int ext2fs_iterate_dir(ext2fs_node_t dir, char *name, ext2fs_node_t * fno status = ext2fs_read_file(diro, fpos + sizeof(struct ext2_dirent), dirent.namelen, filename); - if (status < 1) + if (status < 1) { + puts("ext2fs_read_file fail 2\n"); return(0); + } fdiro = malloc(sizeof(struct ext2fs_node)); - if (!fdiro) + if (!fdiro) { + puts("malloc fail\n"); return(0); + } fdiro->data = diro->data; @@ -505,6 +520,7 @@ static int ext2fs_iterate_dir(ext2fs_node_t dir, char *name, ext2fs_node_t * fno __le32_to_cpu(dirent.inode), &fdiro->inode); if (status == 0) { + puts("inner ext2fs_read_inode fail\n"); free(fdiro); return(0); } @@ -540,6 +556,7 @@ static int ext2fs_iterate_dir(ext2fs_node_t dir, char *name, ext2fs_node_t * fno __le32_to_cpu(dirent.inode), &fdiro->inode); if (status == 0) { + puts("ext2fs_read_inode 3 fail\n"); free(fdiro); return(0); } @@ -720,7 +737,7 @@ int ext2fs_find_file symlinknest = 0; if (!path) - return(0); + return 0; status = ext2fs_find_file1(path, rootnode, foundnode, &foundtype); if (status == 0) @@ -760,29 +777,35 @@ int ext2fs_open(const char *filename) { ext2fs_node_t fdiro = NULL; int status; int len; + int ret = -1; if (ext2fs_root == NULL) - return -1; + goto fail; ext2fs_file = NULL; status = ext2fs_find_file(filename, &ext2fs_root->diropen, &fdiro, FILETYPE_REG); - if (status == 0) + if (status == 0) { + ret = -2; goto fail; + } if (!fdiro->inode_read) { status = ext2fs_read_inode(fdiro->data, fdiro->ino, &fdiro->inode); - if (status == 0) + if (status == 0) { + ret = -3; goto fail; + } } len = __le32_to_cpu(fdiro->inode.size); ext2fs_file = fdiro; + return(len); fail: ext2fs_free_node(fdiro, &ext2fs_root->diropen); - return -1; + return ret; } diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index fe8b0ec..c3f4e44 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -81,7 +81,8 @@ void bootloader_second_phase(void) if (this_kernel->partition_index) { unsigned char *p = kernel_dram; - if (this_kernel->block_read(kernel_dram, 0, 4) < 0) { + if ((int)this_kernel->block_read(kernel_dram, 0, 4) + < 0) { puts("Bad partition read\n"); this_kernel = &this_board-> kernel_source[kernel++]; From 5dbdcda9b252a5d72ca54846b97cb196682e8755 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:38 +0000 Subject: [PATCH 077/248] qi-fix-strncpy.patch Mini strncpy patch was buggy. Signed-off-by: Andy Green --- qiboot/src/utils.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/qiboot/src/utils.c b/qiboot/src/utils.c index 7e92288..dce53a3 100644 --- a/qiboot/src/utils.c +++ b/qiboot/src/utils.c @@ -59,6 +59,9 @@ char *strncpy(char *dest, const char *src, size_t n) while (*src && n--) *dest++ = *src++; + if (n) + *dest = '\0'; + return dest_orig; } From bcdb9491827b25844e03617e6b8ddb6ed3c65798 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:38 +0000 Subject: [PATCH 078/248] qi-block-sd-indexing-throughout.patch Now cards larger than 4GB are normal, we can't use the byte addressing internally any more for SDHC type card. This changes us to use block (512 byte) addressing internally always. Signed-off-by: Andy Green --- qiboot/src/drivers/glamo-mmc.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/qiboot/src/drivers/glamo-mmc.c b/qiboot/src/drivers/glamo-mmc.c index 39d4199..4f2f530 100644 --- a/qiboot/src/drivers/glamo-mmc.c +++ b/qiboot/src/drivers/glamo-mmc.c @@ -105,14 +105,13 @@ unsigned char CRC7(u8 * pu8, int cnt) unsigned long mmc_bread(int dev_num, unsigned long blknr, unsigned long blkcnt, void *dst) { - unsigned long src = blknr * MMC_BLOCK_SIZE; int ret; if (!blkcnt) return 0; /* printf("mmc_bread(%d, %ld, %ld, %p)\n", dev_num, blknr, blkcnt, dst); */ - ret = mmc_read(src, dst, blkcnt * MMC_BLOCK_SIZE); + ret = mmc_read(blknr, dst, blkcnt); if (ret) return ret; @@ -433,12 +432,6 @@ int mmc_read(unsigned long src, u8 *dst, int size) u8 response[16]; int size_original = size; - if ((!size) || (size & (MMC_BLOCK_SIZE - 1))) { - puts("Bad size 0x"); - print32(size); - return 0; - } - if (((int)dst) & 1) { puts("Bad align on dst\n"); return 0; @@ -454,13 +447,13 @@ int mmc_read(unsigned long src, u8 *dst, int size) switch (card_type) { case CARDTYPE_SDHC: /* block addressing */ resp = mmc_cmd(MMC_READ_SINGLE_BLOCK, - src >> MMC_BLOCK_SIZE_BITS, + src, MMC_CMD_ADTC | MMC_RSP_R1 | MMC_DATA_READ, MMC_BLOCK_SIZE, 1, 0, (u16 *)&response[0]); break; default: /* byte addressing */ - resp = mmc_cmd(MMC_READ_SINGLE_BLOCK, src, + resp = mmc_cmd(MMC_READ_SINGLE_BLOCK, src * MMC_BLOCK_SIZE, MMC_CMD_ADTC | MMC_RSP_R1 | MMC_DATA_READ, MMC_BLOCK_SIZE, 1, 0, (u16 *)&response[0]); @@ -477,12 +470,11 @@ int mmc_read(unsigned long src, u8 *dst, int size) do_pio_read((u16 *)dst, MMC_BLOCK_SIZE >> 1); - if (size >= MMC_BLOCK_SIZE) - size -= MMC_BLOCK_SIZE; - else - size = 0; + if (size) + size--; + dst += MMC_BLOCK_SIZE; - src += MMC_BLOCK_SIZE; + src++; } return size_original; } From c4e54f889fd19097155d209d0bf8c01e57f72870 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:38 +0000 Subject: [PATCH 079/248] qi-fix-ryan-chen-dynamic-inode-size.patch With large SDHC cards, the ext2/3 filesystem put on large partitions by mkfs.ext2/3 is not how it used to be, it has a dynamic multiplier for its block addressing. Without these changes, based on a patch by Ryan Chen http://lists.denx.de/pipermail/u-boot/2008-July/037786.html we cannot parse large ext3 filesystem. Signed-off-by: Andy Green --- qiboot/src/fs/ext2.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/qiboot/src/fs/ext2.c b/qiboot/src/fs/ext2.c index ffbffa0..bd35b51 100644 --- a/qiboot/src/fs/ext2.c +++ b/qiboot/src/fs/ext2.c @@ -65,6 +65,12 @@ extern int ext2fs_devread(int sector, int byte_offset, int byte_len, /* The size of an ext2 block in bytes. */ #define EXT2_BLOCK_SIZE(data) (1 << LOG2_BLOCK_SIZE(data)) +#define EXT2_GOOD_OLD_REV 0 /* The good old (original) format */ +#define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */ + +#define EXT2_GOOD_OLD_INODE_SIZE 128 +uint32_t ext2_inode_size = EXT2_GOOD_OLD_INODE_SIZE; + /* The ext2 superblock. */ struct ext2_sblock { uint32_t total_inodes; @@ -216,7 +222,7 @@ static int ext2fs_read_inode if (status == 0) return 0; - inodes_per_block = EXT2_BLOCK_SIZE(data) / 128; + inodes_per_block = EXT2_BLOCK_SIZE(data) / ext2_inode_size; blkno =(ino % __le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block; blkoff =(ino % __le32_to_cpu(sblock->inodes_per_group)) % @@ -225,9 +231,9 @@ static int ext2fs_read_inode puts("ext2fs read inode blkno %d blkoff %d\n", blkno, blkoff); #endif /* Read the inode. */ - status = ext2fs_devread(((__le32_to_cpu(blkgrp.inode_table_id) + - blkno) << LOG2_EXT2_BLOCK_SIZE(data)), - sizeof(struct ext2_inode) * blkoff, + status = ext2fs_devread((__le32_to_cpu(blkgrp.inode_table_id) + + blkno) << LOG2_EXT2_BLOCK_SIZE(data), + ext2_inode_size * blkoff, sizeof(struct ext2_inode),(char *) inode); return !!status; @@ -867,6 +873,11 @@ int ext2fs_mount(void) { if (__le16_to_cpu(data->sblock.magic) != EXT2_MAGIC) goto fail; + if (__le32_to_cpu(data->sblock.revision_level) == EXT2_GOOD_OLD_REV) + ext2_inode_size = EXT2_GOOD_OLD_INODE_SIZE; + else + ext2_inode_size = __le16_to_cpu (data->sblock.inode_size); + data->diropen.data = data; data->diropen.ino = 2; data->diropen.inode_read = 1; From 50fe6feeac9f1942c83b58994073029b8702149a Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:38 +0000 Subject: [PATCH 080/248] qi-fix-ext2-sdhc.patch This adjusts ext2fs_devread to use block addressing itself with dynamic multiplier support separately. Signed-off-by: Andy Green --- qiboot/src/fs/dev.c | 4 +++- qiboot/src/fs/ext2.c | 25 +++++++++++++------------ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/qiboot/src/fs/dev.c b/qiboot/src/fs/dev.c index ebe8d6e..ecb2a3a 100644 --- a/qiboot/src/fs/dev.c +++ b/qiboot/src/fs/dev.c @@ -32,11 +32,13 @@ extern unsigned long partition_offset_blocks; extern unsigned long partition_length_blocks; -int ext2fs_devread(int sector, int byte_offset, int byte_len, u8 *buf) +int ext2fs_devread(int sector, int filesystem_block_log2, int byte_offset, int byte_len, u8 *buf) { unsigned char sec_buf[SECTOR_SIZE]; unsigned block_len; + sector = sector << filesystem_block_log2; + /* * Check partition boundaries */ diff --git a/qiboot/src/fs/ext2.c b/qiboot/src/fs/ext2.c index bd35b51..7290268 100644 --- a/qiboot/src/fs/ext2.c +++ b/qiboot/src/fs/ext2.c @@ -29,7 +29,7 @@ #include #include -extern int ext2fs_devread(int sector, int byte_offset, int byte_len, +extern int ext2fs_devread(int sector, int log2blksize, int byte_offset, int byte_len, char *buf); /* Magic value used to identify an ext2 filesystem. */ @@ -193,8 +193,8 @@ static int ext2fs_blockgroup puts("ext2fs read blockgroup\n"); #endif return ext2fs_devread - (((__le32_to_cpu(data->sblock.first_data_block) + - 1) << LOG2_EXT2_BLOCK_SIZE(data)), + ((__le32_to_cpu(data->sblock.first_data_block) + + 1), LOG2_EXT2_BLOCK_SIZE(data), group * sizeof(struct ext2_block_group), sizeof(struct ext2_block_group),(char *) blkgrp); } @@ -231,10 +231,11 @@ static int ext2fs_read_inode puts("ext2fs read inode blkno %d blkoff %d\n", blkno, blkoff); #endif /* Read the inode. */ - status = ext2fs_devread((__le32_to_cpu(blkgrp.inode_table_id) + - blkno) << LOG2_EXT2_BLOCK_SIZE(data), - ext2_inode_size * blkoff, - sizeof(struct ext2_inode),(char *) inode); + + status = ext2fs_devread(__le32_to_cpu(blkgrp.inode_table_id) + blkno, + LOG2_EXT2_BLOCK_SIZE(data), + ext2_inode_size * blkoff, + sizeof(struct ext2_inode), (char *)inode); return !!status; } @@ -284,7 +285,7 @@ static int ext2fs_read_block(ext2fs_node_t node, int fileblock) { } if ((__le32_to_cpu(inode->b.blocks.indir_block) << log2_blksz) != indir1_blkno) { - status = ext2fs_devread(__le32_to_cpu(inode->b.blocks.indir_block) << log2_blksz, + status = ext2fs_devread(__le32_to_cpu(inode->b.blocks.indir_block), log2_blksz, 0, blksz, (char *) indir1_block); if (status == 0) { @@ -328,7 +329,7 @@ static int ext2fs_read_block(ext2fs_node_t node, int fileblock) { } if ((__le32_to_cpu(inode->b.blocks.double_indir_block) << log2_blksz) != indir1_blkno) { - status = ext2fs_devread(__le32_to_cpu(inode->b.blocks.double_indir_block) << log2_blksz, + status = ext2fs_devread(__le32_to_cpu(inode->b.blocks.double_indir_block), log2_blksz, 0, blksz, (char *) indir1_block); if (status == 0) { @@ -362,7 +363,7 @@ static int ext2fs_read_block(ext2fs_node_t node, int fileblock) { } if ((__le32_to_cpu(indir1_block[rblock / perblock]) << log2_blksz) != indir1_blkno) { - status = ext2fs_devread(__le32_to_cpu(indir1_block[rblock / perblock]) << log2_blksz, + status = ext2fs_devread(__le32_to_cpu(indir1_block[rblock / perblock]), log2_blksz, 0, blksz, (char *) indir2_block); if (status == 0) { @@ -434,7 +435,7 @@ int ext2fs_read_file if (blknr) { int status; - status = ext2fs_devread(blknr, skipfirst, blockend, buf); + status = ext2fs_devread(blknr, 0 /* already accounted */, skipfirst, blockend, buf); if (status == 0) return -1; } else @@ -864,7 +865,7 @@ int ext2fs_mount(void) { return 0; /* Read the superblock. */ - status = ext2fs_devread(1 * 2, 0, sizeof(struct ext2_sblock), + status = ext2fs_devread(1 * 2, 0, 0, sizeof(struct ext2_sblock), (char *) &data->sblock); if (!status) goto fail; From 53ce7d80f0388f3c07bb6ac8d9c05226778f9ec7 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:39 +0000 Subject: [PATCH 081/248] qi-clean-debugging-messages.patch Signed-off-by: Andy Green --- qiboot/src/fs/ext2.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/qiboot/src/fs/ext2.c b/qiboot/src/fs/ext2.c index 7290268..e09ca4a 100644 --- a/qiboot/src/fs/ext2.c +++ b/qiboot/src/fs/ext2.c @@ -465,13 +465,8 @@ static int ext2fs_iterate_dir(ext2fs_node_t dir, char *name, ext2fs_node_t * fno puts("failed to read inode\n"); return(0); } - } else { - puts("fail\n"); } - printdec(fpos); - puts(" "); - printdec(diro->inode.size); - puts("\n"); + /* Search the file. */ while (fpos < __le32_to_cpu(diro->inode.size)) { struct ext2_dirent dirent; From 4414f130bdc5ef1ca09d73976dcfa0fd9b677ac3 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:39 +0000 Subject: [PATCH 082/248] qi-add-more-pcf50633-init.patch We need to set a few more things up in pcf50633 to get suspend and resume to work -- without them suspend actually goes OFF. Take the opportunity to optimize this init significantly. Signed-off-by: Andy Green --- qiboot/src/gta02/gta02.c | 51 ++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/qiboot/src/gta02/gta02.c b/qiboot/src/gta02/gta02.c index ff2149d..dd586d1 100644 --- a/qiboot/src/gta02/gta02.c +++ b/qiboot/src/gta02/gta02.c @@ -35,6 +35,42 @@ #define PCF50633_I2C_ADS 0x73 +struct pcf50633_init { + u8 index; + u8 value; +}; + +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_OOCSHDWN, 0x04 }, /* defeat 8s death from lowsys on A5 */ + { 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, 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_MBCC1, 0xe6 }, + { 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, 0x19 }, /* 25/255 == 98mA soft-start usb fast */ + { PCF50633_REG_MBCC6, 0x00 }, /* cutoff current 1/32 * Ichg */ + { PCF50633_REG_MBCC7, 0x00 }, /* 1.6A max bat curr, USB 100mA */ + { PCF50633_REG_MBCC8, 0x00 }, + + { PCF50633_REG_BBCCTL, 0x19 }, /* 3V, 200uA, on */ + +}; + static const struct board_variant board_variants[] = { [0] = { .name = "A5 PCB", @@ -52,6 +88,7 @@ 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; //CAUTION:Follow the configuration order for setting the ports. // 1) setting value(GPnDAT) @@ -168,16 +205,10 @@ void port_init_gta02(void) * We have to talk to the PMU a little bit */ - /* We need SD Card rail (HCLDO) at 3.0V */ - i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_HCLDOOUT, - 21); + 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); - /* switch HCLDO on */ - i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_HCLDOENA, 1); - - /* push DOWN1 (CPU Core rail) to 1.3V, allowing 400MHz */ - i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_DOWN1OUT, - 0x1b); /* change CPU clocking to 400MHz 1:4:8 */ @@ -327,7 +358,7 @@ const struct board_api board_api_gta02 = { "rootfstype=ext3 " \ "root=/dev/mmcblk0p1 " \ "console=ttySAC2,115200 " \ - "loglevel=4 " \ + "loglevel=8 " \ "init=/sbin/init "\ "ro" }, From 6e84650e2ffca4c76918e20d372bb8af1e0db7bf Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:39 +0000 Subject: [PATCH 083/248] qi-delay-after-stop.patch Bitbang I2C could do with delay after last stop before next back-back transaction Signed-off-by: Andy Green --- qiboot/include/i2c-bitbang.h | 3 ++- qiboot/src/drivers/i2c-bitbang.c | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/qiboot/include/i2c-bitbang.h b/qiboot/include/i2c-bitbang.h index 0873b3b..f5b86ef 100644 --- a/qiboot/include/i2c-bitbang.h +++ b/qiboot/include/i2c-bitbang.h @@ -53,7 +53,8 @@ enum i2c_bitbang_states { IBS_STOP1, IBS_STOP2, - IBS_STOP3 + IBS_STOP3, + IBS_STOP4 }; /* context for bitbang GPIO pins and transaction */ diff --git a/qiboot/src/drivers/i2c-bitbang.c b/qiboot/src/drivers/i2c-bitbang.c index 9762415..eef28a6 100644 --- a/qiboot/src/drivers/i2c-bitbang.c +++ b/qiboot/src/drivers/i2c-bitbang.c @@ -193,6 +193,11 @@ int i2c_next_state(struct i2c_bitbang * bb) break; case IBS_STOP3: + (bb->set)(1, 1); + bb->state = IBS_STOP4; + break; + + case IBS_STOP4: (bb->set)(1, 1); return 1; /* done */ } From 0a72b19c3fec92ec6aeaeb943811b52760c927f1 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:39 +0000 Subject: [PATCH 084/248] qi-return-i2c-to-peripheral.patch Return IO to peripheral mode for i2c at end of init Signed-off-by: Andy Green --- qiboot/include/qi.h | 1 + qiboot/src/gta02/gta02.c | 16 ++++++++++++++++ qiboot/src/phase2.c | 6 ++++++ 3 files changed, 23 insertions(+) diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index 3429e9b..1db3248 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -74,6 +74,7 @@ struct board_api { int (*is_this_board)(void); void (*port_init)(void); void (*putc)(char); + void (*close)(void); struct kernel_source kernel_source[8]; }; diff --git a/qiboot/src/gta02/gta02.c b/qiboot/src/gta02/gta02.c index dd586d1..5b569fe 100644 --- a/qiboot/src/gta02/gta02.c +++ b/qiboot/src/gta02/gta02.c @@ -324,6 +324,21 @@ static void putc_gta02(char c) serial_putc_s3c24xx(GTA02_DEBUG_UART, c); } +static void close_gta02(void) +{ + /* 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)(); +} + /* * our API for bootloader on this machine */ @@ -338,6 +353,7 @@ const struct board_api board_api_gta02 = { .is_this_board = is_this_board_gta02, .port_init = port_init_gta02, .putc = putc_gta02, + .close = close_gta02, /* these are the ways we could boot GTA02 in order to try */ .kernel_source = { [0] = { diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index c3f4e44..8284541 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -252,6 +252,12 @@ void bootloader_second_phase(void) params->hdr.tag = ATAG_NONE; params->hdr.size = 0; + /* give board implementation a chance to shut down + * anything it may have going on, leave GPIO set for Linux + */ + if (this_board->close) + (this_board->close)(); + puts ("Starting --->\n\n"); /* From 977852eb5777dfb63aaed94206e7364ac96e80f2 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:39 +0000 Subject: [PATCH 085/248] qi-constrain-gta02-board-variants.patch Constrain board variants to legal numbers Signed-off-by: Andy Green --- qiboot/src/gta02/gta02.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qiboot/src/gta02/gta02.c b/qiboot/src/gta02/gta02.c index 5b569fe..c0d75d9 100644 --- a/qiboot/src/gta02/gta02.c +++ b/qiboot/src/gta02/gta02.c @@ -284,6 +284,8 @@ int gta02_get_pcb_revision(void) rGPDUP |= (1 << 0) | (1 << 3) | (1 << 4); rGPDDAT |= (1 << 0) | (1 << 3) | (1 << 4); + n &= 1; + return n; } @@ -316,7 +318,7 @@ int is_this_board_gta02(void) const struct board_variant const * get_board_variant_gta02(void) { - return &board_variants[gta02_get_pcb_revision()]; + return &board_variants[gta02_get_pcb_revision() & 1]; } static void putc_gta02(char c) From ac360fcdf6b5e27263d9963b7a9c1972265314e0 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:39 +0000 Subject: [PATCH 086/248] qi-enable-charger-and-unmask-interrupts.patch Unmask interrupts, enable charger Signed-off-by: Andy Green --- qiboot/src/gta02/gta02.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/qiboot/src/gta02/gta02.c b/qiboot/src/gta02/gta02.c index c0d75d9..762ba9b 100644 --- a/qiboot/src/gta02/gta02.c +++ b/qiboot/src/gta02/gta02.c @@ -46,7 +46,7 @@ const struct pcf50633_init pcf50633_init[] = { { PCF50633_REG_OOCTIM1, 0xaa }, /* debounce 14ms everything */ { PCF50633_REG_OOCTIM2, 0x4a }, { PCF50633_REG_OOCMODE, 0x55 }, - { PCF50633_REG_OOCSHDWN, 0x04 }, /* defeat 8s death from lowsys on A5 */ + { PCF50633_REG_OOCSHDWN, 0x04 }, /* defeat 8s death from lowsys on A5 */ { PCF50633_REG_OOCCTL, 0x47 }, { PCF50633_REG_SVMCTL, 0x08 }, /* 3.10V SYS voltage thresh. */ @@ -58,7 +58,13 @@ const struct pcf50633_init pcf50633_init[] = { { 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_MBCC1, 0xe6 }, + + { 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 */ @@ -66,6 +72,7 @@ const struct pcf50633_init pcf50633_init[] = { { PCF50633_REG_MBCC6, 0x00 }, /* cutoff current 1/32 * Ichg */ { PCF50633_REG_MBCC7, 0x00 }, /* 1.6A max bat curr, USB 100mA */ { PCF50633_REG_MBCC8, 0x00 }, + { PCF50633_REG_MBCC1, 0xe7 }, /* chgena */ { PCF50633_REG_BBCCTL, 0x19 }, /* 3V, 200uA, on */ From 64f0faee5431b93b325e78efaf51bfe4b6b57b6e Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:39 +0000 Subject: [PATCH 087/248] qi-fix-resume.patch Add resume processing so we can resume and not just start up Signed-off-by: Andy Green --- qiboot/src/start.S | 58 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/qiboot/src/start.S b/qiboot/src/start.S index 1514e0f..cf15645 100644 --- a/qiboot/src/start.S +++ b/qiboot/src/start.S @@ -22,6 +22,11 @@ #define __ASM_MODE__ #include +#define S3C2410_MISCCR_nEN_SCLK0 (1 << 17) +#define S3C2410_MISCCR_nEN_SCLK1 (1 << 18) +#define S3C2410_MISCCR_nEN_SCLKE (1 << 19) + + .globl _start _start: b start_code /* if we are injected by JTAG, the script sets _istag content to nonzero */ @@ -168,8 +173,6 @@ start_code: ldr r1, =0x54 str r1, [r0, #0x20] - bl cpu_init_crit - /* reset nand controller, or it is dead to us */ mov r1, #0x4E000000 @@ -182,6 +185,57 @@ start_code: 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 */ From e55b148f55cb0ee37c718fc68b49b0f51739a68e Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:39 +0000 Subject: [PATCH 088/248] qi-fix-i2c-multiread-nack-nak.patch On the last read, master must NAK, on intermediate reads it must ACK. If you get this wrong, communication with device is screwed even in Linux. Signed-off-by: Andy Green --- qiboot/src/drivers/i2c-bitbang.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/qiboot/src/drivers/i2c-bitbang.c b/qiboot/src/drivers/i2c-bitbang.c index eef28a6..436003e 100644 --- a/qiboot/src/drivers/i2c-bitbang.c +++ b/qiboot/src/drivers/i2c-bitbang.c @@ -53,14 +53,17 @@ int i2c_next_state(struct i2c_bitbang * bb) case IBS_INIT: bb->index = 0; bb->index_read = 0; - /* fall thru */ + (bb->set)(1, 1); + bb->state = IBS_START1; + break; + case IBS_START1: (bb->set)(1, 0); - (bb->set)(0, 0); /* start */ bb->state = IBS_START2; break; case IBS_START2: + (bb->set)(0, 0); /* start */ bb->count = 8; bb->state = IBS_ADS_TX_S; break; @@ -137,25 +140,34 @@ int i2c_next_state(struct i2c_bitbang * bb) case IBS_DATA_RX_L: bb->data[bb->index_read] <<= 1; bb->data[bb->index_read] |= !!(bb->read_sda)(); - (bb->set)(0, 1); bb->count--; if (bb->count) { + (bb->set)(0, 1); bb->state = IBS_DATA_RX_S; break; } /* slave has released SDA now, bang down ACK */ - (bb->set)(0, 0); + if (bb->data[bb->index + 1] != IBCONTROL_DO_READ) + (bb->set)(0, 1); + else + (bb->set)(0, 0); bb->state = IBS_DATA_RX_ACK_H; break; case IBS_DATA_RX_ACK_H: - (bb->set)(1, 0); + if (bb->data[bb->index + 1] != IBCONTROL_DO_READ) + (bb->set)(1, 1); /* NAK */ + else + (bb->set)(1, 0); /* ACK */ bb->state = IBS_DATA_RX_ACK_L; break; case IBS_DATA_RX_ACK_L: - (bb->set)(0, 1); + if (bb->data[bb->index + 1] != IBCONTROL_DO_READ) + (bb->set)(0, 1); /* NAK */ + else + (bb->set)(0, 0); /* ACK */ bb->index_read++; bb->index++; switch (bb->data[bb->index]) { @@ -214,6 +226,11 @@ static int i2c_complete_synchronously(struct i2c_bitbang * bb) (bb->spin)(); } + if (ret < 0) { + puts("i2c transaction failed "); + printdec(ret); + puts("\n"); + } return ret; } From 14e63e56b6dbf48ffd862e816c595c258b211df0 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:39 +0000 Subject: [PATCH 089/248] qi-add-build-stamps.patch Signed-off-by: Andy Green --- qiboot/Makefile | 8 ++++---- qiboot/src/gta02/gta02.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/qiboot/Makefile b/qiboot/Makefile index c1f9468..1adfaab 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -49,8 +49,8 @@ UDFU_PID = 0x5119 UDFU_REV = 0x350 TARGET = image/start_qi_all -IMAGE = $(IMAGE_DIR)/qi -UDFU_IMAGE = $(IMAGE_DIR)/qi.udfu +IMAGE = $(IMAGE_DIR)/qi-$(BUILD_VERSION) +UDFU_IMAGE = $(IMAGE_DIR)/qi-$(BUILD_VERSION).udfu MKUDFU = $(TOOLS)/mkudfu @@ -75,5 +75,5 @@ ${UDFU_IMAGE}:${OBJS} ${MKUDFU} @$(OBJDUMP) -d ${TARGET} >${IMAGE}.dis clean: - @rm -f src/*.o src/*~ include/*~ ${IMAGE}* ${TARGET} ${UDFU_IMAGE} - @make clean -C $(TOOLS) \ No newline at end of file + @rm -f src/*.o src/*~ include/*~ ${IMAGE_DIR}/* ${TARGET} ${UDFU_IMAGE} + @make clean -C $(TOOLS) diff --git a/qiboot/src/gta02/gta02.c b/qiboot/src/gta02/gta02.c index 762ba9b..9b2726f 100644 --- a/qiboot/src/gta02/gta02.c +++ b/qiboot/src/gta02/gta02.c @@ -46,7 +46,6 @@ const struct pcf50633_init pcf50633_init[] = { { PCF50633_REG_OOCTIM1, 0xaa }, /* debounce 14ms everything */ { PCF50633_REG_OOCTIM2, 0x4a }, { PCF50633_REG_OOCMODE, 0x55 }, - { PCF50633_REG_OOCSHDWN, 0x04 }, /* defeat 8s death from lowsys on A5 */ { PCF50633_REG_OOCCTL, 0x47 }, { PCF50633_REG_SVMCTL, 0x08 }, /* 3.10V SYS voltage thresh. */ @@ -72,9 +71,10 @@ const struct pcf50633_init pcf50633_init[] = { { PCF50633_REG_MBCC6, 0x00 }, /* cutoff current 1/32 * Ichg */ { PCF50633_REG_MBCC7, 0x00 }, /* 1.6A max bat curr, USB 100mA */ { PCF50633_REG_MBCC8, 0x00 }, - { PCF50633_REG_MBCC1, 0xe7 }, /* chgena */ + { PCF50633_REG_MBCC1, 0xff }, /* chgena */ { PCF50633_REG_BBCCTL, 0x19 }, /* 3V, 200uA, on */ + { PCF50633_REG_OOCSHDWN, 0x04 }, /* defeat 8s death from lowsys on A5 */ }; From c91dcc3b7699627aa420f22de8cd5d041f1bb8b2 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:39 +0000 Subject: [PATCH 090/248] qi-fix-dfu-stamped-image.patch Now we generate stamped images, need to dfu them up Signed-off-by: Andy Green --- qiboot/dfu-qi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qiboot/dfu-qi b/qiboot/dfu-qi index 1a4e497..7bd103d 100755 --- a/qiboot/dfu-qi +++ b/qiboot/dfu-qi @@ -1,7 +1,7 @@ #!/bin/bash -../dfu-util/src/dfu-util -a 1 -d 0x1d50:0x5119 -D image/qi.udfu +../dfu-util/src/dfu-util -a 1 -d 0x1d50:0x5119 -D image/qi-*.udfu if [ $? -eq 1 ] ; then -../dfu-util/src/dfu-util -a 1 -d 0x1d50:0x5120 -D image/qi.udfu -../dfu-util/src/dfu-util -a 1 -d 0x1d50:0x5119 -D image/qi.udfu +../dfu-util/src/dfu-util -a 1 -d 0x1d50:0x5120 -D image/qi-*.udfu +../dfu-util/src/dfu-util -a 1 -d 0x1d50:0x5119 -D image/qi-*.udfu fi From c8d5147d6fb092d4a46ac5fc4da123f64078929f Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:39 +0000 Subject: [PATCH 091/248] qi-reduce-power-glamo-video-off.patch No need to burn power generating video in Glamo during Qi Signed-off-by: Andy Green --- qiboot/src/drivers/glamo-init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiboot/src/drivers/glamo-init.c b/qiboot/src/drivers/glamo-init.c index c9c0c8c..cf96794 100644 --- a/qiboot/src/drivers/glamo-init.c +++ b/qiboot/src/drivers/glamo-init.c @@ -39,7 +39,7 @@ static u16 u16a_gen_init_0x0000[] = { 0x2020, 0x3650, 0x0002, 0x01FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x000D, 0x000B, 0x00EE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x1839, 0x0000, 0x2000, 0x0001, 0x0100, 0x0000, 0x0000, 0x0000, + 0x1801 /*0x1839*/, 0x0000, 0x2000, 0x0001, 0x0100, 0x0000, 0x0000, 0x0000, 0x05DB, 0x5231, 0x09C3, 0x8261, 0x0003, 0x0000, 0x0000, 0x0000, 0x000F, 0x101E, 0xC0C3, 0x101E, 0x000F, 0x0001, 0x030F, 0x020F, 0x080F, 0x0F0F From 2c16e47344b92eaa786d08a9b5412c0bc3afb124 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:39 +0000 Subject: [PATCH 092/248] qi-fix-baud-for-200MHz-1-3-6.patch Baud rate for 115200 at 33MHz PCLK wasn't calculated right Signed-off-by: Andy Green --- qiboot/src/drivers/serial-s3c24xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiboot/src/drivers/serial-s3c24xx.c b/qiboot/src/drivers/serial-s3c24xx.c index 206f0a1..0f4ba22 100644 --- a/qiboot/src/drivers/serial-s3c24xx.c +++ b/qiboot/src/drivers/serial-s3c24xx.c @@ -25,7 +25,7 @@ void serial_init_115200_s3c24xx(const int uart, const int pclk_MHz) { - int div = (((54 * pclk_MHz) + (pclk_MHz / 2)) / 100) -1; + int div = (((54 * pclk_MHz) + 26) / 100) -1; switch(uart) { case UART0: From f6bb301f5f6e6729d7403efd8e364cebb41ecb74 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:39 +0000 Subject: [PATCH 093/248] qi-fix-define-all-gpio-data.patch Nothing defined most GPIO output data on start until now Signed-off-by: Andy Green --- qiboot/src/gta02/gta02.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/qiboot/src/gta02/gta02.c b/qiboot/src/gta02/gta02.c index 9b2726f..cc33ea1 100644 --- a/qiboot/src/gta02/gta02.c +++ b/qiboot/src/gta02/gta02.c @@ -113,7 +113,7 @@ void port_init_gta02(void) * Binary : 1 1 1 1 , 1 1 1 1 , 1 1 1 1 */ rGPACON = 0x007E5FFF; - rGPADAT |= (1 << 16); /* Set GPA16 to high (nNAND_WP) */ + rGPADAT = 0x00000000; /* * ===* PORT B GROUP * Ports : GPB10 GPB9 GPB8 GPB7 GPB6 GPB5 GPB4 GPB3 GPB2 GPB1 GPB0 @@ -123,6 +123,7 @@ void port_init_gta02(void) */ 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 @@ -131,7 +132,7 @@ void port_init_gta02(void) */ rGPCCON = 0x55555155; rGPCUP = 0x0000FFFF & ~(1 << 5); - rGPCDAT |= (1 << 13) | (1 << 15); /* index detect -> hi */ + 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 @@ -140,7 +141,7 @@ void port_init_gta02(void) */ rGPDCON = 0x55555555; rGPDUP = 0x0000FFFF; - rGPDDAT |= (1 << 0) | (1 << 3) | (1 << 4); /* index detect -> hi */ + 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 @@ -153,6 +154,7 @@ void port_init_gta02(void) */ rGPECON = 0xAAAAAAAA; rGPEUP = 0x0000FFFF & ~(1 << 11); + rGPEDAT = 0x00000000; /* * === PORT F GROUP * Ports : GPF7 GPF6 GPF5 GPF4 GPF3 GPF2 GPF1 GPF0 @@ -163,6 +165,7 @@ void port_init_gta02(void) /* pulldown on GPF03: TP-4705+debug - debug conn will float */ rGPFCON = 0x0000AAAA; rGPFUP = 0x000000FF & ~(1 << 3); + rGPFDAT = 0x00000000; /* @@ -179,6 +182,8 @@ void port_init_gta02(void) */ rGPGCON = 0x01AAFE79; rGPGUP = 0x0000FFFF; + rGPGDAT = 0x00000000; + /* * === PORT H GROUP * Ports : GPH10 GPH9 GPH8 GPH7 GPH6 GPH5 GPH4 GPH3 GPH2 GPH1 GPH0 @@ -191,11 +196,14 @@ void port_init_gta02(void) */ rGPHCON = 0x001AAAAA; rGPHUP = 0x000007FF & ~(1 << 8) & ~(1 << 0) & ~(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) */ From cea4b83d5324c7539d425dc6adcb36eef3a496b0 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:39 +0000 Subject: [PATCH 094/248] qi-change-boot-speed-200MHz.patch Part of the effort to save power during booting so we can do it inside the 500mW budget from un-enumerated USB connection. Signed-off-by: Andy Green --- qiboot/src/gta02/gta02.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/qiboot/src/gta02/gta02.c b/qiboot/src/gta02/gta02.c index cc33ea1..df4fe48 100644 --- a/qiboot/src/gta02/gta02.c +++ b/qiboot/src/gta02/gta02.c @@ -92,9 +92,11 @@ static const struct board_variant board_variants[] = { void port_init_gta02(void) { +#if 0 unsigned int * MPLLCON = (unsigned int *)0x4c000004; unsigned int * UPLLCON = (unsigned int *)0x4c000008; unsigned int * CLKDIVN = (unsigned int *)0x4c000014; +#endif int n; //CAUTION:Follow the configuration order for setting the ports. @@ -224,7 +226,7 @@ void port_init_gta02(void) i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, pcf50633_init[n].index, pcf50633_init[n].value); - +#if 0 /* change CPU clocking to 400MHz 1:4:8 */ /* clock divide 1:4:8 - do it first */ @@ -246,6 +248,9 @@ void port_init_gta02(void) /* get debug UART working at 115kbps */ serial_init_115200_s3c24xx(GTA02_DEBUG_UART, 50 /* 50MHz PCLK */); +#else + serial_init_115200_s3c24xx(GTA02_DEBUG_UART, 33 /* 33MHz PCLK */); +#endif /* we're going to use Glamo for SD Card access, so we need to init the * evil beast From 3554f337df59fc960d2dd2e8ee517037959752e9 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:39 +0000 Subject: [PATCH 095/248] qi-add-totrst-clear-before-linux.patch Before leaving for Linux, gratuitously clear down the totrst / timeout counter to help stop us dying partway through boot on effective power-off. In the case we have no battery or battery < ~3V, we still somehow need to do more in kernel because it can switch itself off more than 8 seconds after this point. Signed-off-by: Andy Green --- qiboot/src/gta02/gta02.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/qiboot/src/gta02/gta02.c b/qiboot/src/gta02/gta02.c index df4fe48..f6710b4 100644 --- a/qiboot/src/gta02/gta02.c +++ b/qiboot/src/gta02/gta02.c @@ -348,6 +348,10 @@ static void putc_gta02(char 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); From 064a13861c7760b1402e83b94fff01f75a2d9e79 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:40 +0000 Subject: [PATCH 096/248] qi-refactor-for-multi-cpu-add-s3c6410-base.patch This patch makes qi source structure cpu-centric, and allows multiple CPUs to be handled with the board definitions inside the CPU dirs. You have to make a particular CPU version of Qi now, which you can do by a shell command like this: make clean ; make CPU=s3c2442 && make CPU=s3c6410 which gets you $ ls -l image/ total 744 -rwxrwxr-x 1 agreen agreen 25372 2008-10-17 18:25 qi-s3c2442-andy_77c1fcdddc3e2cbf -rw-rw-r-- 1 agreen agreen 237100 2008-10-17 18:25 qi-s3c2442-andy_77c1fcdddc3e2cbf.dis -rw-rw-r-- 1 agreen agreen 25388 2008-10-17 18:25 qi-s3c2442-andy_77c1fcdddc3e2cbf.udfu -rwxrwxr-x 1 agreen agreen 22736 2008-10-17 18:25 qi-s3c6410-andy_77c1fcdddc3e2cbf -rw-rw-r-- 1 agreen agreen 216294 2008-10-17 18:25 qi-s3c6410-andy_77c1fcdddc3e2cbf.dis -rw-rw-r-- 1 agreen agreen 22752 2008-10-17 18:25 qi-s3c6410-andy_77c1fcdddc3e2cbf.udfu The 6410 support in there is enough to send a character "U" on the 6410 SMDK Because the product naming is not defined, currently the device targeted for 6410 is called "TLA01" Signed-off-by: Andy Green --- qiboot/Makefile | 15 ++-- qiboot/include/qi.h | 7 ++ qiboot/src/gta03/gta03.c | 2 +- qiboot/src/nand_read.c | 153 --------------------------------------- qiboot/src/nand_read.h | 22 ------ qiboot/src/phase2.c | 25 ++++++- qiboot/src/qi.lds | 59 --------------- qiboot/src/start.S | 35 ++++++++- qiboot/src/start_qi.c | 129 --------------------------------- 9 files changed, 72 insertions(+), 375 deletions(-) delete mode 100644 qiboot/src/nand_read.c delete mode 100644 qiboot/src/nand_read.h delete mode 100644 qiboot/src/qi.lds delete mode 100644 qiboot/src/start_qi.c diff --git a/qiboot/Makefile b/qiboot/Makefile index 1adfaab..b43e958 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -22,7 +22,7 @@ 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/qi.lds +LDS = src/cpu/$(CPU)/qi.lds INCLUDE = include IMAGE_DIR = image TOOLS = tools @@ -33,10 +33,11 @@ CFLAGS = -Wall -Werror -I $(INCLUDE) -g -c -Os -fno-strict-aliasing -mlong-calls -DBUILD_DATE="${BUILD_DATE}" LDFLAGS = -S_SRCS = src/start.S src/lowlevel_init.S +S_SRCS = src/cpu/$(CPU)/start.S src/lowlevel_init.S S_OBJS = $(patsubst %.S,%.o, $(S_SRCS)) -C_SRCS = $(wildcard src/*.c) $(wildcard src/gt*/*.c) \ - $(wildcard src/drivers/*.c) $(wildcard src/fs/*.c) +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} @@ -48,9 +49,9 @@ UDFU_VID = 0x1d50 UDFU_PID = 0x5119 UDFU_REV = 0x350 -TARGET = image/start_qi_all -IMAGE = $(IMAGE_DIR)/qi-$(BUILD_VERSION) -UDFU_IMAGE = $(IMAGE_DIR)/qi-$(BUILD_VERSION).udfu +TARGET = image/start_qi_all-$(CPU) +IMAGE = $(IMAGE_DIR)/qi-$(CPU)-$(BUILD_VERSION) +UDFU_IMAGE = $(IMAGE_DIR)/qi-$(CPU)-$(BUILD_VERSION).udfu MKUDFU = $(TOOLS)/mkudfu diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index 1db3248..652bb23 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -78,6 +78,13 @@ struct board_api { struct kernel_source kernel_source[8]; }; +/* these are the boards we support for a given CPU */ + +struct cpu_supported_boards { + const u32 cpu_id; + const struct board_api **boards; +}; + /* this is the board we are running on */ extern struct board_api const * this_board; diff --git a/qiboot/src/gta03/gta03.c b/qiboot/src/gta03/gta03.c index 2ee037c..4c58ee3 100644 --- a/qiboot/src/gta03/gta03.c +++ b/qiboot/src/gta03/gta03.c @@ -220,7 +220,7 @@ static void putc_gta03(char c) * our API for bootloader on this machine */ const struct board_api board_api_gta03 = { - .name = "GTA03", + .name = "GTA03-2442", .linux_machine_id = 1866, .linux_mem_start = 0x30000000, .linux_mem_size = (128 * 1024 * 1024), diff --git a/qiboot/src/nand_read.c b/qiboot/src/nand_read.c deleted file mode 100644 index cb2a2de..0000000 --- a/qiboot/src/nand_read.c +++ /dev/null @@ -1,153 +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 - * Date : $Date: 2004/02/04 10:37:37 $ - * - * u-boot integration and bad-block skipping (C) 2006 by OpenMoko, Inc. - * Author: Harald Welte - */ - -/* NOTE this stuff runs in steppingstone context! */ - -/* the API refers to 512-byte blocks */ - -#include -#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) - -static int is_bad_block(unsigned long block_index) -{ - unsigned char data; - unsigned long page_num; - - 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) -{ - unsigned short *ptr16 = (unsigned short *)buf; - unsigned int i, page_num; -#if 0 - unsigned char ecc[64]; - unsigned short *p16 = (unsigned short *)ecc; -#endif - - nand_clear_RnB(); - - NFCMD = NAND_CMD_READ0; - - page_num = block512 >> 2; /* 512 block -> 2048 block */ - /* Write Address */ - NFADDR = 0; - NFADDR = 0; - NFADDR = page_num & 0xff; - NFADDR = (page_num >> 8) & 0xff; - NFADDR = (page_num >> 16) & 0xff; - NFCMD = NAND_CMD_READSTART; - nand_wait(); - - for (i = 0; i < NAND_PAGE_SIZE/2; i++) - *ptr16++ = NFDATA16; -#if 0 - for (i = 0; i < 64 / 2; i++) { - *p16++ = NFDATA16; - } -#endif - return 4; -} - -/* 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; - - if (start_block512 & 3) /* inside 2048-byte block */ - return -1; - - /* 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 + 4)) { - start_block512 += 4; - blocks512 += 4; - 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; -} - diff --git a/qiboot/src/nand_read.h b/qiboot/src/nand_read.h deleted file mode 100644 index 71aeda5..0000000 --- a/qiboot/src/nand_read.h +++ /dev/null @@ -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 - * Date : $Date: 2004/02/04 10:37:37 $ - * - * u-boot integration and bad-block skipping (C) 2006 by OpenMoko, Inc. - * Author: Harald Welte - */ -#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 */ diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 8284541..40053ff 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -28,9 +28,12 @@ #define __ARM__ #include #include -#include "nand_read.h" #include +#define stringify2(s) stringify1(s) +#define stringify1(s) #s + + unsigned long partition_offset_blocks = 0; unsigned long partition_length_blocks = 0; @@ -44,6 +47,26 @@ void bootloader_second_phase(void) const struct board_variant * board_variant = (this_board->get_board_variant)(); + /* okay, do the critical port and serial init for our board */ + + this_board->port_init(); + + /* stick some hello messages on debug console */ + + puts("\n\n\nQi Bootloader "stringify2(BUILD_HOST)" " + stringify2(BUILD_VERSION)" " + stringify2(BUILD_DATE)"\n"); + + puts("Copyright (C) 2008 Openmoko, Inc.\n"); + puts("This is free software; see the source for copying conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or " + "FITNESS FOR A PARTICULAR PURPOSE.\n\n Detected: "); + + puts(this_board->name); + puts(", "); + board_variant = (this_board->get_board_variant)(); + puts(board_variant->name); + /* we try the possible kernels for this board in order */ this_kernel = &this_board->kernel_source[kernel++]; diff --git a/qiboot/src/qi.lds b/qiboot/src/qi.lds deleted file mode 100644 index bdc1d2c..0000000 --- a/qiboot/src/qi.lds +++ /dev/null @@ -1,59 +0,0 @@ -/* - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * 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/start.o (.text .rodata* .data) - src/lowlevel_init.o (.text .rodata* .data) - src/start_qi.o (.text .rodata* .data) - src/blink_led.o (.text .rodata* .data) - src/nand_read.o (.text .rodata* .data) - src/drivers/serial-s3c24xx.o (.text .rodata* .data) - } - - . = ALIGN(4); - .everything_else ADDR (.text) + SIZEOF (.text) + 0x33000000 : - AT ( ADDR (.text) + SIZEOF (.text) ) { *(.text .rodata* .data) } - - . = 0x33800000 ; - __bss_start = .; - .bss (NOLOAD) : - { - *(.bss) - } - _end = .; -} diff --git a/qiboot/src/start.S b/qiboot/src/start.S index cf15645..a16e9a5 100644 --- a/qiboot/src/start.S +++ b/qiboot/src/start.S @@ -27,10 +27,12 @@ #define S3C2410_MISCCR_nEN_SCLKE (1 << 19) -.globl _start + +.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: +is_jtag: .word 0 /* it's at a fixed address (+0x8) so we can breakpoint it in the JTAG script @@ -47,6 +49,11 @@ _start_armboot: _TEXT_BASE: .word TEXT_BASE +processor_id: + .word 0 + .word 0x41129200 /* s3c2442 ID */ + .word 0x410fb760 /* s3c6410 ID */ + /* * These are defined in the board-specific linker script. */ @@ -66,7 +73,29 @@ start_code: bic r0,r0,#0x1f orr r0,r0,#0xd3 msr cpsr,r0 - + + /* + * detect processor we are running on + * s3c2442: 0x4112920x + * s3c6410: 0x410fb76x + */ + MRC p15, 0 ,r0, c0, c0, 0 + ldr r1, =processor_id + str r0, [r1] + ldr r2, [r1, #4] + + and r0, #0xfffffff0 + cmp r0, r2 + beq startup_2442 + + /* 6410 startup */ +startup_6410: + + mov r0, #0 + str r0, [r1] + + /* 2442 startup */ +startup_2442: # define pWTCON 0x53000000 ldr r0, =pWTCON diff --git a/qiboot/src/start_qi.c b/qiboot/src/start_qi.c deleted file mode 100644 index ac7d42e..0000000 --- a/qiboot/src/start_qi.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * (C) Copyright 2007 OpenMoko, Inc. - * Author: xiangfu liu - * Andy Green - * - * 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 -#include "blink_led.h" -#include "nand_read.h" -#include -#include - -#define stringify2(s) stringify1(s) -#define stringify1(s) #s - -extern void bootloader_second_phase(void); - -const struct board_api * boards[] = { - &board_api_gta02, - &board_api_gta03, -}; - -struct board_api const * this_board; - -void start_qi(void) -{ - int n = 0; - int board = 0; - const struct board_variant * board_variant; - const u32 * p_is_jtag = (const u32 *)4; - - /* - * 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 (!*p_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 (!n) { - if (board > ARRAY_SIZE(boards)) - /* can't put diagnostic on serial... too early */ - goto unhappy; - - if (this_board->is_this_board()) - n = 1; - else - this_board = boards[board++]; - } - - /* okay, do the critical port and serial init for our board */ - - this_board->port_init(); - - /* stick some hello messages on debug console */ - - puts("\n\n\nQi Bootloader "stringify2(BUILD_HOST)" " - stringify2(BUILD_VERSION)" " - stringify2(BUILD_DATE)"\n"); - - puts("Copyright (C) 2008 Openmoko, Inc.\n"); - puts("This is free software; see the source for copying conditions.\n" - "There is NO warranty; not even for MERCHANTABILITY or " - "FITNESS FOR A PARTICULAR PURPOSE.\n\n Detected: "); - - puts(this_board->name); - puts(", "); - board_variant = (this_board->get_board_variant)(); - puts(board_variant->name); - - /* - * jump to bootloader_second_phase() running from DRAM copy - */ - bootloader_second_phase(); - -unhappy: - while(1) - blink_led(); - -} From cd9d23c6ec1027aa53290fcb1a8e5494e0497a7c Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:40 +0000 Subject: [PATCH 097/248] qi-fix-s3c24xx-mci.patch Some work on s3c24xx MCI (which might be useful for GTA01 port eventually too) Signed-off-by: Andy Green --- qiboot/gta03-qi.ocd | 1 + qiboot/include/qi.h | 2 + qiboot/{src/drivers => include}/s3c24xx-mci.h | 14 +- qiboot/include/s3c24xx-regs-sdi.h | 110 +++++ qiboot/src/drivers/s3c24xx-mci.c | 415 ++++++++++-------- qiboot/src/gta03/gta03.c | 35 ++ qiboot/src/start.S | 2 +- 7 files changed, 378 insertions(+), 201 deletions(-) rename qiboot/{src/drivers => include}/s3c24xx-mci.h (77%) create mode 100644 qiboot/include/s3c24xx-regs-sdi.h diff --git a/qiboot/gta03-qi.ocd b/qiboot/gta03-qi.ocd index 16cf0bd..7513767 100755 --- a/qiboot/gta03-qi.ocd +++ b/qiboot/gta03-qi.ocd @@ -3,6 +3,7 @@ reset halt wait_halt +sleep 2000 # bring the steppingstone part of qi image into steppingstone # diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index 652bb23..7b03687 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -98,6 +98,8 @@ 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); + unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned int len); diff --git a/qiboot/src/drivers/s3c24xx-mci.h b/qiboot/include/s3c24xx-mci.h similarity index 77% rename from qiboot/src/drivers/s3c24xx-mci.h rename to qiboot/include/s3c24xx-mci.h index a271695..7abeb1f 100644 --- a/qiboot/src/drivers/s3c24xx-mci.h +++ b/qiboot/include/s3c24xx-mci.h @@ -21,13 +21,13 @@ * MA 02111-1307 USA */ -#ifndef _MMC_H_ -#define _MMC_H_ -#include +#ifndef _S3C24XX_MMC_H_ +#define _S3C24XX_MMC_H_ +#include -int mmc_init(int verbose); -int mmc_read(ulong src, uchar *dst, int size); -int mmc_write(uchar *src, ulong dst, int size); -int mmc2info(ulong addr); +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_ */ diff --git a/qiboot/include/s3c24xx-regs-sdi.h b/qiboot/include/s3c24xx-regs-sdi.h new file mode 100644 index 0000000..9597542 --- /dev/null +++ b/qiboot/include/s3c24xx-regs-sdi.h @@ -0,0 +1,110 @@ +/* linux/include/asm/arch-s3c2410/regs-sdi.h + * + * Copyright (c) 2004 Simtec Electronics + * 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 */ diff --git a/qiboot/src/drivers/s3c24xx-mci.c b/qiboot/src/drivers/s3c24xx-mci.c index b982657..42eecb9 100644 --- a/qiboot/src/drivers/s3c24xx-mci.c +++ b/qiboot/src/drivers/s3c24xx-mci.c @@ -1,5 +1,8 @@ -#if 0 /* + * qi s3c24xx SD card driver + * Author: Andy Green + * based on ----> + * * u-boot S3C2410 MMC/SD card driver * (C) Copyright 2006 by OpenMoko, Inc. * Author: Harald Welte @@ -23,32 +26,51 @@ * MA 02111-1307 USA */ -#include -#include +#include #include -#include -#include -#include -#include +#include +#include -#if defined(CONFIG_MMC) && defined(CONFIG_MMC_S3C) +#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 - -static S3C2410_SDI *sdi; - -static block_dev_desc_t mmc_dev; - -block_dev_desc_t * mmc_get_dev(int dev) -{ - return ((block_dev_desc_t *)&mmc_dev); -} +#define MMC_BLOCK_SIZE 512 /* * FIXME needs to read cid and csd info to determine block size * and other parameters */ -static uchar mmc_buf[MMC_BLOCK_SIZE]; +static u8 mmc_buf[MMC_BLOCK_SIZE]; static mmc_csd_t mmc_csd; static int mmc_ready = 0; static int wide = 0; @@ -57,22 +79,22 @@ static int wide = 0; #define CMD_F_RESP 0x01 #define CMD_F_RESP_LONG 0x02 -static u_int32_t *mmc_cmd(ushort cmd, ulong arg, ushort flags) +static u32 *mmc_cmd(u16 cmd, u32 arg, u16 flags) { - static u_int32_t resp[5]; + static u32 resp[5]; - u_int32_t ccon, csta; - u_int32_t csta_rdy_bit = S3C2410_SDICMDSTAT_CMDSENT; + 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); +// debug("mmc_cmd CMD%d arg=0x%08x flags=%x\n", cmd, arg, flags); - sdi->SDICSTA = 0xffffffff; - sdi->SDIDSTA = 0xffffffff; - sdi->SDIFSTA = 0xffffffff; + SDICSTA = 0xffffffff; + SDIDSTA = 0xffffffff; + SDIFSTA = 0xffffffff; - sdi->SDICARG = arg; + SDICARG = arg; ccon = cmd & S3C2410_SDICMDCON_INDEX; ccon |= S3C2410_SDICMDCON_SENDERHOST|S3C2410_SDICMDCON_CMDSTART; @@ -85,51 +107,51 @@ static u_int32_t *mmc_cmd(ushort cmd, ulong arg, ushort flags) if (flags & CMD_F_RESP_LONG) ccon |= S3C2410_SDICMDCON_LONGRSP; - sdi->SDICCON = ccon; + SDICCON = ccon; while (1) { - csta = sdi->SDICSTA; + csta = SDICSTA; if (csta & csta_rdy_bit) break; if (csta & S3C2410_SDICMDSTAT_CMDTIMEOUT) { - printf("===============> MMC CMD Timeout\n"); - sdi->SDICSTA |= S3C2410_SDICMDSTAT_CMDTIMEOUT; + puts("===============> MMC CMD Timeout\n"); + SDICSTA |= S3C2410_SDICMDSTAT_CMDTIMEOUT; break; } } - debug("final MMC CMD status 0x%x\n", csta); +// debug("final MMC CMD status 0x%x\n", csta); - sdi->SDICSTA |= csta_rdy_bit; + SDICSTA |= csta_rdy_bit; if (flags & CMD_F_RESP) { - resp[0] = sdi->SDIRSP0; - resp[1] = sdi->SDIRSP1; - resp[2] = sdi->SDIRSP2; - resp[3] = sdi->SDIRSP3; + resp[0] = SDIRSP0; + resp[1] = SDIRSP1; + resp[2] = SDIRSP2; + resp[3] = SDIRSP3; } return resp; } -#define FIFO_FILL(host) ((host->SDIFSTA & S3C2410_SDIFSTA_COUNTMASK) >> 2) +#define FIFO_FILL() ((SDIFSTA & S3C2410_SDIFSTA_COUNTMASK) >> 2) -static int mmc_block_read(uchar *dst, ulong src, ulong len) +static int mmc_block_read(u8 *dst, u32 src, u32 len) { - u_int32_t dcon, fifo; - u_int32_t *dst_u32 = (u_int32_t *)dst; - u_int32_t *resp; + 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", (ulong)dst, src, len); +// 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); - sdi->SDIBSIZE = len; + SDIBSIZE = len; - //sdi->SDIPRE = 0xff; + //SDIPRE = 0xff; /* setup data */ dcon = (len >> 9) & S3C2410_SDIDCON_BLKNUM; @@ -137,66 +159,82 @@ static int mmc_block_read(uchar *dst, ulong src, ulong len) dcon |= S3C2410_SDIDCON_RXAFTERCMD|S3C2410_SDIDCON_XFER_RXSTART; if (wide) dcon |= S3C2410_SDIDCON_WIDEBUS; -#if defined(CONFIG_S3C2440) || defined(CONFIG_S3C2442) - dcon |= S3C2440_SDIDCON_DS_WORD | S3C2440_SDIDCON_DATSTART; -#endif - sdi->SDIDCON = dcon; + + 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) { - u_int32_t sdidsta = sdi->SDIDSTA; - fifo = FIFO_FILL(sdi); + u32 sdidsta = SDIDSTA; + fifo = FIFO_FILL(); if (sdidsta & (S3C2410_SDIDSTA_FIFOFAIL| S3C2410_SDIDSTA_CRCFAIL| S3C2410_SDIDSTA_RXCRCFAIL| S3C2410_SDIDSTA_DATATIMEOUT)) { - printf("mmc_block_read: err SDIDSTA=0x%08x\n", sdidsta); - return -EIO; + puts("mmc_block_read: err SDIDSTA=0x"); + print32(sdidsta); + puts("\n"); + return -1; } - while (fifo--) { - //debug("dst_u32 = 0x%08x\n", dst_u32); - *(dst_u32++) = sdi->SDIDAT; - if (len >= 4) - len -= 4; - else { - len = 0; - break; + 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", sdi->SDIDSTA); - while (!(sdi->SDIDSTA & (1 << 4))) {} - debug("done waiting for SDIDSTA (currently 0x%08x\n", sdi->SDIDSTA); +// debug("waiting for SDIDSTA (currently 0x%08x\n", SDIDSTA); + while (!(SDIDSTA & (1 << 4))) {} +// debug("done waiting for SDIDSTA (currently 0x%08x\n", SDIDSTA); - sdi->SDIDCON = 0; + SDIDCON = 0; - if (!(sdi->SDIDSTA & S3C2410_SDIDSTA_XFERFINISH)) - debug("mmc_block_read; transfer not finished!\n"); + if (!(SDIDSTA & S3C2410_SDIDSTA_XFERFINISH)) + puts("mmc_block_read; transfer not finished!\n"); return 0; } -static int mmc_block_write(ulong dst, uchar *src, int len) +static int mmc_block_write(u32 dst, u8 *src, int len) { - printf("MMC block write not yet supported on S3C2410!\n"); + puts("MMC block write not yet supported on S3C2410!\n"); return -1; } -int mmc_read(ulong src, uchar *dst, int size) +int s3c24xx_mmc_read(u32 src, u8 *dst, int size) { - ulong end, part_start, part_end, part_len, aligned_start, aligned_end; - ulong mmc_block_size, mmc_block_address; + 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) { - printf("Please initialize the MMC first\n"); + puts("Please initialize the MMC first\n"); return -1; } @@ -211,12 +249,12 @@ int mmc_read(ulong src, uchar *dst, int size) 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, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end); +// 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, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end); +// 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; @@ -224,19 +262,19 @@ int mmc_read(ulong src, uchar *dst, int size) dst += part_len; src += part_len; } - debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n", - src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end); +// 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, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end); - if ((mmc_block_read((uchar *)(dst), src, mmc_block_size)) < 0) +// 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, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end); +// 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, (ulong)dst, end, part_start, part_end, aligned_start, aligned_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; @@ -245,16 +283,16 @@ int mmc_read(ulong src, uchar *dst, int size) return 0; } -int mmc_write(uchar *src, ulong dst, int size) +int s3c24xx_mmc_write(u8 *src, u32 dst, int size) { - ulong end, part_start, part_end, part_len, aligned_start, aligned_end; - ulong mmc_block_size, mmc_block_address; + 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) { - printf("Please initialize the MMC first\n"); + puts("Please initialize the MMC first\n"); return -1; } @@ -269,12 +307,12 @@ int mmc_write(uchar *src, ulong dst, int size) 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, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end); +// 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", - (ulong)src, dst, end, part_start, part_end, aligned_start, aligned_end); +// 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; @@ -285,20 +323,20 @@ int mmc_write(uchar *src, ulong dst, int size) dst += part_len; src += part_len; } - debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n", - src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end); +// 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, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end); - if ((mmc_block_write(dst, (uchar *)src, mmc_block_size)) < 0) +// 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, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end); +// 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, (ulong)dst, end, part_start, part_end, aligned_start, aligned_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; @@ -310,12 +348,12 @@ int mmc_write(uchar *src, ulong dst, int size) return 0; } -ulong mmc_bread(int dev_num, ulong blknr, ulong blkcnt, void *dst) +u32 s3c24xx_mmc_bread(int dev_num, u32 blknr, u32 blkcnt, void *dst) { int mmc_block_size = MMC_BLOCK_SIZE; - ulong src = blknr * mmc_block_size + CFG_MMC_BASE; + u32 src = blknr * mmc_block_size + CFG_MMC_BASE; - mmc_read(src, dst, blkcnt*mmc_block_size); + s3c24xx_mmc_read(src, dst, blkcnt*mmc_block_size); return blkcnt; } @@ -323,9 +361,10 @@ ulong mmc_bread(int dev_num, ulong blknr, ulong blkcnt, void *dst) that expects it to be shifted. */ static u_int16_t rca = MMC_DEFAULT_RCA >> 16; -static u_int32_t mmc_size(const struct mmc_csd *csd) +#if 0 +static u32 mmc_size(const struct mmc_csd *csd) { - u_int32_t block_len, mult, blocknr; + u32 block_len, mult, blocknr; block_len = csd->read_bl_len << 12; mult = csd->c_size_mult1 << 8; @@ -333,6 +372,7 @@ static u_int32_t mmc_size(const struct mmc_csd *csd) return blocknr * block_len; } +#endif struct sd_cid { char pnm_0; /* product name */ @@ -355,71 +395,92 @@ struct sd_cid { static void print_mmc_cid(mmc_cid_t *cid) { - printf("MMC found. Card desciption is:\n"); - printf("Manufacturer ID = %02x%02x%02x\n", - cid->id[0], cid->id[1], cid->id[2]); - printf("HW/FW Revision = %x %x\n",cid->hwrev, cid->fwrev); + 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 */ - printf("Product Name = %s\n",cid->name); - printf("Serial Number = %02x%02x%02x\n", - cid->sn[0], cid->sn[1], cid->sn[2]); - printf("Month = %d\n",cid->month); - printf("Year = %d\n",1997 + cid->year); + 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) { - printf("Manufacturer: 0x%02x, OEM \"%c%c\"\n", - cid->mid, cid->oid_0, cid->oid_1); - printf("Product name: \"%c%c%c%c%c\", revision %d.%d\n", - cid->pnm_0, cid->pnm_1, cid->pnm_2, cid->pnm_3, cid->pnm_4, - cid->prv >> 4, cid->prv & 15); - printf("Serial number: %u\n", - cid->psn_0 << 24 | cid->psn_1 << 16 | cid->psn_2 << 8 | + 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); - printf("Manufacturing date: %d/%d\n", - cid->mdt_1 & 15, - 2000+((cid->mdt_0 & 15) << 4)+((cid->mdt_1 & 0xf0) >> 4)); - printf("CRC: 0x%02x, b0 = %d\n", - cid->crc >> 1, cid->crc & 1); + 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 mmc_init(int verbose) +int s3c24xx_mmc_init(int verbose) { - int retries, rc = -ENODEV; + int retries, rc = -2; int is_sd = 0; - u_int32_t *resp; - S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER(); + u32 *resp; - sdi = S3C2410_GetBase_SDI(); + 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; + } - debug("mmc_init(PCLK=%u)\n", get_PCLK()); - - clk_power->CLKCON |= (1 << 9); - - sdi->SDIBSIZE = 512; -#if defined(CONFIG_S3C2410) - /* S3C2410 has some bug that prevents reliable operation at higher speed */ - //sdi->SDIPRE = 0x3e; /* SDCLK = PCLK/2 / (SDIPRE+1) = 396kHz */ - sdi->SDIPRE = 0x02; /* 2410: SDCLK = PCLK/2 / (SDIPRE+1) = 11MHz */ - sdi->SDIDTIMER = 0xffff; -#elif defined(CONFIG_S3C2440) || defined(CONFIG_S3C2442) - sdi->SDIPRE = 0x05; /* 2410: SDCLK = PCLK / (SDIPRE+1) = 11MHz */ - sdi->SDIDTIMER = 0x7fffff; -#endif - sdi->SDIIMSK = 0x0; - sdi->SDICON = S3C2410_SDICON_FIFORESET|S3C2410_SDICON_CLOCKTYPE; - udelay(125000); /* FIXME: 74 SDCLK cycles */ + 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); - printf("trying to detect SD Card...\n"); + puts("trying to detect SD Card...\n"); while (retries--) { - udelay(100000); + udelay(1000000); resp = mmc_cmd(55, 0x00000000, CMD_F_RESP); resp = mmc_cmd(41, 0x00300000, CMD_F_RESP); @@ -429,16 +490,8 @@ int mmc_init(int verbose) } } - if (retries == 0 && !is_sd) { - retries = 10; - printf("failed to detect SD Card, trying MMC\n"); - resp = mmc_cmd(MMC_CMD_SEND_OP_COND, 0x00ffc000, CMD_F_RESP); - while (retries-- && resp && !(resp[4] & 0x80)) { - debug("resp %x %x\n", resp[0], resp[1]); - udelay(50); - resp = mmc_cmd(1, 0x00ffff00, CMD_F_RESP); - } - } + 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); @@ -450,6 +503,7 @@ int mmc_init(int verbose) 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], @@ -457,12 +511,14 @@ int mmc_init(int verbose) 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, @@ -473,19 +529,9 @@ int mmc_init(int verbose) cid->psn_2 << 8 | cid->psn_3); sprintf((char *) mmc_dev.revision, "%d.%d", cid->prv >> 4, cid->prv & 15); +#endif } - /* fill in device description */ - mmc_dev.if_type = IF_TYPE_MMC; - mmc_dev.part_type = PART_TYPE_DOS; - mmc_dev.dev = 0; - mmc_dev.lun = 0; - mmc_dev.type = 0; - /* FIXME fill in the correct size (is set to 32MByte) */ - mmc_dev.blksz = 512; - mmc_dev.lba = 0x10000; - mmc_dev.removable = 0; - mmc_dev.block_read = mmc_bread; /* MMC exists, get CSD too */ resp = mmc_cmd(MMC_CMD_SET_RCA, MMC_DEFAULT_RCA, CMD_F_RESP); @@ -498,10 +544,12 @@ int mmc_init(int verbose) 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 } } @@ -515,26 +563,7 @@ int mmc_init(int verbose) } #endif - fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */ - return rc; } -int -mmc_ident(block_dev_desc_t *dev) -{ - return 0; -} -int -mmc2info(ulong addr) -{ - /* FIXME hard codes to 32 MB device */ - if (addr >= CFG_MMC_BASE && addr < CFG_MMC_BASE + 0x02000000) - return 1; - - return 0; -} - -#endif /* defined(CONFIG_MMC) && defined(CONFIG_MMC_S3C) */ -#endif diff --git a/qiboot/src/gta03/gta03.c b/qiboot/src/gta03/gta03.c index 4c58ee3..73fa268 100644 --- a/qiboot/src/gta03/gta03.c +++ b/qiboot/src/gta03/gta03.c @@ -4,6 +4,7 @@ #include #include #include +#include #define GTA03_DEBUG_UART 2 @@ -215,6 +216,18 @@ static void putc_gta03(char c) serial_putc_s3c24xx(GTA03_DEBUG_UART, c); } +int sd_card_init_gta03(void) +{ + return s3c24xx_mmc_init(1); +} + +int sd_card_block_read_gta03(unsigned char * buf, unsigned long start512, + int blocks512) +{ + return s3c24xx_mmc_bread(0, start512, blocks512, buf); +} + + /* * our API for bootloader on this machine @@ -232,6 +245,28 @@ const struct board_api board_api_gta03 = { /* these are the ways we could boot GTA03 in order to try */ .kernel_source = { [0] = { + .name = "SD Card EXT2 Kernel", + .block_init = sd_card_init_gta03, + .block_read = sd_card_block_read_gta03, + .partition_index = 1, + .filesystem = FS_EXT2, + .filepath = "boot/uImage.bin", + .commandline = "mtdparts=physmap-flash:-(nor);" \ + "neo1973-nand:" \ + "0x00040000(qi)," \ + "0x00040000(cmdline)," \ + "0x00800000(backupkernel)," \ + "0x000a0000(extra)," \ + "0x00040000(identity)," \ + "0x0f6a0000(backuprootfs) " \ + "rootfstype=ext2 " \ + "root=/dev/mmcblk0p1 " \ + "console=ttySAC2,115200 " \ + "loglevel=4 " \ + "init=/sbin/init "\ + "ro" + }, + [1] = { .name = "NAND Kernel", .block_read = nand_read_ll, .offset_blocks512_if_no_partition = 0x80000 / 512, diff --git a/qiboot/src/start.S b/qiboot/src/start.S index a16e9a5..bbc8186 100644 --- a/qiboot/src/start.S +++ b/qiboot/src/start.S @@ -166,7 +166,7 @@ startup_2442: /* enable only CPU peripheral block clocks we actually use */ ldr r0, =0x4c00000c /* clkcon */ - ldr r1, =0x3d10 /* uart, pwm, gpio, nand clocks on */ + ldr r1, =0x3f10 /* uart, pwm, gpio, nand, sdi clocks on */ str r1, [r0] /* gpio UART2 init, H port */ From f82d4861e68d0622fc10137daaf30d0a59ecc916 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:40 +0000 Subject: [PATCH 098/248] qi-add-6410-bootable-sdcard-generator.patch This patch adds a small script that knows how to partition, format and prepare with a bootloader image an SD Card for usage with SD Card boot on 6410. You use it like this: ./6410-partition-sd.sh sde sdhc ./image/qi-s3c6410-andy_495294c60f2f1432 This will prepare your card with three partitions and put the bootloader images at the end as required by 6410 iROM. If you put anything on the fourth parameter, it skips the fdisk and the formatting stages and just updates the bootloader. Signed-off-by: Andy Green --- qiboot/6410-partition-sd.sh | 125 ++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100755 qiboot/6410-partition-sd.sh diff --git a/qiboot/6410-partition-sd.sh b/qiboot/6410-partition-sd.sh new file mode 100755 index 0000000..a3399a7 --- /dev/null +++ b/qiboot/6410-partition-sd.sh @@ -0,0 +1,125 @@ +#!/bin/sh +# 6410 SD Boot formatter +# (C) 2008 Openmoko, Inc +# Author: Andy Green + +# LAYOUT +# Partition table, then +# VFAT takes up remaining space here +# then... +# +EXT3_ROOTFS_SECTORS=$(( 64 * 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 " +echo + +# these are fixed in iROM +QI_INITIAL=$(( 8 * 2 )) +SIG=1 + +FDISK_SCRIPT=/tmp/_fds + +if [ -z $1 -o -z $2 -o -z $3 ] ; then + echo "This formats a SD card for usage on SD Card boot" + echo " on 6410 based systems" + echo + echo "Usage:" + echo + echo "$0 " + exit 1 +fi + +if [ $2 = "sdhc" ] ; then +PADDING=1025 +else +PADDING=1 +fi + +EXT3_TOTAL_SECTORS=$(( $EXT3_ROOTFS_SECTORS + $EXT3_BACKUP_FS_SECTORS )) +REARSECTORS=$(( $QI_ALLOCATION + $QI_INITIAL + $SIG + $PADDING )) + +if [ ! -z "`grep $1 /proc/mounts`" ] ; then + echo "ERROR $1 seems to be mounted, that ain't right" + exit 2 +fi + +SECTORS=`dmesg | grep $1 | grep "512-byte hardware" | tail -n 1 | cut -d' ' -f4` + +if [ $SECTORS -le 0 ] ; then + echo "problem finding size for /dev/$1" + exit 3 +fi + +if [ -z "$4" ] ; then + + echo "$1 is $SECTORS 512-byte blocks" + + FATSECTORS=$(( $SECTORS - $EXT3_TOTAL_SECTORS + $REARSECTORS )) + FATMB=$(( $FATSECTORS / 2048 - 16 )) + + echo "Creating VFAT section $FATMB MB" + + # create the script for fdisk + # clear the existing partition table + echo "o" >$FDISK_SCRIPT + + # add main VFAT storage partition + echo "n" >>$FDISK_SCRIPT + echo "p" >>$FDISK_SCRIPT + echo "1" >>$FDISK_SCRIPT + # first partition == 1 + echo "1" >>$FDISK_SCRIPT + echo "+$FATMB"M >>$FDISK_SCRIPT + + # add the normal EXT3 rootfs + echo "n" >>$FDISK_SCRIPT + echo "p" >>$FDISK_SCRIPT + echo "2" >>$FDISK_SCRIPT + # continue after last + echo "" >>$FDISK_SCRIPT + echo "+$(( $EXT3_ROOTFS_SECTORS / 2048 ))"M >>$FDISK_SCRIPT + + # add the backup EXT3 rootfs + echo "n" >>$FDISK_SCRIPT + echo "p" >>$FDISK_SCRIPT + echo "3" >>$FDISK_SCRIPT + # continue after last + echo "" >>$FDISK_SCRIPT + echo "+$(( $EXT3_BACKUP_FS_SECTORS / 2048 ))"M >>$FDISK_SCRIPT + + # commit it and exit + echo "w" >>$FDISK_SCRIPT + echo "q" >>$FDISK_SCRIPT + + # do the partitioning action + fdisk /dev/$1 <$FDISK_SCRIPT + + # prep the filesystems + + mkfs.vfat "/dev/$1"1 -n main-vfat + mkfs.ext3 "/dev/$1"2 -L rootfs + mkfs.ext3 "/dev/$1"3 -L backupfs + +fi # if -z $4 + +# copy the full bootloader image to the right place after the +# partitioned area +dd if=$3 of=/dev/$1 bs=512 count=512 \ + seek=$(( $SECTORS - $REARSECTORS )) +dd if=$3 of=/dev/$1 bs=512 \ + seek=$(( $SECTORS - $REARSECTORS + $QI_ALLOCATION )) \ + count=$QI_INITIAL +dd if=/dev/zero of=/dev/$1 bs=512 \ + seek=$(( $SECTORS - $REARSECTORS + $QI_ALLOCATION + $QI_INITIAL )) \ + count=$(( $SIG + $PADDING )) + +# done +echo +echo "**** completed" From c3f69eb333463295ab28e1952f081e9aea59b4bd Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:40 +0000 Subject: [PATCH 099/248] qi-add-missed-files-for-scm.patch Moved several files and they didn't get added to git Signed-off-by: Andy Green --- qiboot/include/neo_tla01.h | 28 + qiboot/include/s3c6410.h | 1430 ++++++++++++++++++++++++++++ qiboot/src/cpu/s3c2442/gta02.c | 428 +++++++++ qiboot/src/cpu/s3c2442/gta03.c | 289 ++++++ qiboot/src/cpu/s3c2442/nand_read.c | 153 +++ qiboot/src/cpu/s3c2442/nand_read.h | 22 + qiboot/src/cpu/s3c2442/qi.lds | 60 ++ qiboot/src/cpu/s3c2442/start.S | 311 ++++++ qiboot/src/cpu/s3c2442/start_qi.c | 106 +++ qiboot/src/cpu/s3c6410/qi.lds | 57 ++ qiboot/src/cpu/s3c6410/start.S | 548 +++++++++++ qiboot/src/cpu/s3c6410/start_qi.c | 105 ++ qiboot/src/cpu/s3c6410/tla01.c | 246 +++++ 13 files changed, 3783 insertions(+) create mode 100644 qiboot/include/neo_tla01.h create mode 100644 qiboot/include/s3c6410.h create mode 100644 qiboot/src/cpu/s3c2442/gta02.c create mode 100644 qiboot/src/cpu/s3c2442/gta03.c create mode 100644 qiboot/src/cpu/s3c2442/nand_read.c create mode 100644 qiboot/src/cpu/s3c2442/nand_read.h create mode 100644 qiboot/src/cpu/s3c2442/qi.lds create mode 100644 qiboot/src/cpu/s3c2442/start.S create mode 100644 qiboot/src/cpu/s3c2442/start_qi.c create mode 100644 qiboot/src/cpu/s3c6410/qi.lds create mode 100644 qiboot/src/cpu/s3c6410/start.S create mode 100644 qiboot/src/cpu/s3c6410/start_qi.c create mode 100644 qiboot/src/cpu/s3c6410/tla01.c diff --git a/qiboot/include/neo_tla01.h b/qiboot/include/neo_tla01.h new file mode 100644 index 0000000..6d9ca72 --- /dev/null +++ b/qiboot/include/neo_tla01.h @@ -0,0 +1,28 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: xiangfu liu + * + * 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 +extern const struct board_api board_api_tla01; +#endif + +#define TEXT_BASE_TLA01 0x53000000 diff --git a/qiboot/include/s3c6410.h b/qiboot/include/s3c6410.h new file mode 100644 index 0000000..d0b9dd6 --- /dev/null +++ b/qiboot/include/s3c6410.h @@ -0,0 +1,1430 @@ +/* + * (C) Copyright 2007 + * Byungjae Lee, Samsung Erectronics, bjlee@samsung.com. + * - only support for S3C6400 + * $Id: s3c6410.h,v 1.6 2008/07/02 11:01:48 jsgood Exp $ + * + * 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 + */ + +/************************************************ + * NAME : s3c6400.h + * + * Based on S3C6400 User's manual Rev 0.0 + ************************************************/ + +#ifndef __S3C6410_H__ +#define __S3C6410_H__ + +#ifndef CONFIG_S3C6410 +#define CONFIG_S3C6410 1 +#endif + +#define S3C64XX_UART_CHANNELS 3 +#define S3C64XX_SPI_CHANNELS 2 + +//#include + +#ifndef __ASSEMBLY__ +typedef enum { + S3C64XX_UART0, + S3C64XX_UART1, + S3C64XX_UART2, +} S3C64XX_UARTS_NR; + +//#include +#endif + +#define BIT0 0x00000001 +#define BIT1 0x00000002 +#define BIT2 0x00000004 +#define BIT3 0x00000008 +#define BIT4 0x00000010 +#define BIT5 0x00000020 +#define BIT6 0x00000040 +#define BIT7 0x00000080 +#define BIT8 0x00000100 +#define BIT9 0x00000200 +#define BIT10 0x00000400 +#define BIT11 0x00000800 +#define BIT12 0x00001000 +#define BIT13 0x00002000 +#define BIT14 0x00004000 +#define BIT15 0x00008000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 + +#define ROM_BASE0 0x00000000 /* base address of rom bank 0 */ +#define ROM_BASE1 0x04000000 /* base address of rom bank 1 */ +#define DRAM_BASE0 0x40000000 /* base address of dram bank 0 */ +#define DRAM_BASE1 0x50000000 /* base address of dram bank 1 */ + + +/* S3C6400 device base addresses */ +#define ELFIN_DMA_BASE 0x75000000 +#define ELFIN_LCD_BASE 0x77100000 +#define ELFIN_USB_HOST_BASE 0x74300000 +#define ELFIN_I2C_BASE 0x7f004000 +#define ELFIN_I2S_BASE 0x7f002000 +#define ELFIN_ADC_BASE 0x7e00b000 +#define ELFIN_SPI_BASE 0x7f00b000 +#define ELFIN_HSMMC_0_BASE 0x7c200000 +#define ELFIN_HSMMC_1_BASE 0x7c300000 +#define ELFIN_HSMMC_2_BASE 0x7c400000 + +#define ELFIN_CLOCK_POWER_BASE 0x7e00f000 + +/* Clock & Power Controller for mDirac3*/ +#define APLL_LOCK_OFFSET 0x00 +#define MPLL_LOCK_OFFSET 0x04 +#define EPLL_LOCK_OFFSET 0x08 +#define APLL_CON_OFFSET 0x0C +#define MPLL_CON_OFFSET 0x10 +#define EPLL_CON0_OFFSET 0x14 +#define EPLL_CON1_OFFSET 0x18 +#define CLK_SRC_OFFSET 0x1C +#define CLK_DIV0_OFFSET 0x20 +#define CLK_DIV1_OFFSET 0x24 +#define CLK_DIV2_OFFSET 0x28 +#define CLK_OUT_OFFSET 0x2C +#define HCLK_GATE_OFFSET 0x30 +#define PCLK_GATE_OFFSET 0x34 +#define SCLK_GATE_OFFSET 0x38 +#define AHB_CON0_OFFSET 0x100 +#define AHB_CON1_OFFSET 0x104 +#define AHB_CON2_OFFSET 0x108 +#define SELECT_DMA_OFFSET 0x110 +#define SW_RST_OFFSET 0x114 +#define SYS_ID_OFFSET 0x118 +#define MEM_SYS_CFG_OFFSET 0x120 +#define QOS_OVERRIDE0_OFFSET 0x124 +#define QOS_OVERRIDE1_OFFSET 0x128 +#define MEM_CFG_STAT_OFFSET 0x12C +#define PWR_CFG_OFFSET 0x804 +#define EINT_MASK_OFFSET 0x808 +#define NOR_CFG_OFFSET 0x810 +#define STOP_CFG_OFFSET 0x814 +#define SLEEP_CFG_OFFSET 0x818 +#define OSC_FREQ_OFFSET 0x820 +#define OSC_STABLE_OFFSET 0x824 +#define PWR_STABLE_OFFSET 0x828 +#define FPC_STABLE_OFFSET 0x82C +#define MTC_STABLE_OFFSET 0x830 +#define OTHERS_OFFSET 0x900 +#define RST_STAT_OFFSET 0x904 +#define WAKEUP_STAT_OFFSET 0x908 +#define BLK_PWR_STAT_OFFSET 0x90C +#define INF_REG0_OFFSET 0xA00 +#define INF_REG1_OFFSET 0xA04 +#define INF_REG2_OFFSET 0xA08 +#define INF_REG3_OFFSET 0xA0C +#define INF_REG4_OFFSET 0xA10 +#define INF_REG5_OFFSET 0xA14 +#define INF_REG6_OFFSET 0xA18 +#define INF_REG7_OFFSET 0xA1C + +#define OSC_CNT_VAL_OFFSET 0x824 +#define PWR_CNT_VAL_OFFSET 0x828 +#define FPC_CNT_VAL_OFFSET 0x82C +#define MTC_CNT_VAL_OFFSET 0x830 + + +#define APLL_LOCK_REG __REG(ELFIN_CLOCK_POWER_BASE+APLL_LOCK_OFFSET) +#define MPLL_LOCK_REG __REG(ELFIN_CLOCK_POWER_BASE+MPLL_LOCK_OFFSET) +#define EPLL_LOCK_REG __REG(ELFIN_CLOCK_POWER_BASE+EPLL_LOCK_OFFSET) +#define APLL_CON_REG __REG(ELFIN_CLOCK_POWER_BASE+APLL_CON_OFFSET) +#define MPLL_CON_REG __REG(ELFIN_CLOCK_POWER_BASE+MPLL_CON_OFFSET) +#define EPLL_CON0_REG __REG(ELFIN_CLOCK_POWER_BASE+EPLL_CON0_OFFSET) +#define EPLL_CON1_REG __REG(ELFIN_CLOCK_POWER_BASE+EPLL_CON1_OFFSET) +#define CLK_SRC_REG __REG(ELFIN_CLOCK_POWER_BASE+CLK_SRC_OFFSET) +#define CLK_DIV0_REG __REG(ELFIN_CLOCK_POWER_BASE+CLK_DIV0_OFFSET) +#define CLK_DIV1_REG __REG(ELFIN_CLOCK_POWER_BASE+CLK_DIV1_OFFSET) +#define CLK_DIV2_REG __REG(ELFIN_CLOCK_POWER_BASE+CLK_DIV2_OFFSET) +#define CLK_OUT_REG __REG(ELFIN_CLOCK_POWER_BASE+CLK_OUT_OFFSET) +#define HCLK_GATE_REG __REG(ELFIN_CLOCK_POWER_BASE+HCLK_GATE_OFFSET) +#define PCLK_GATE_REG __REG(ELFIN_CLOCK_POWER_BASE+PCLK_GATE_OFFSET) +#define SCLK_GATE_REG __REG(ELFIN_CLOCK_POWER_BASE+SCLK_GATE_OFFSET) +#define AHB_CON0_REG __REG(ELFIN_CLOCK_POWER_BASE+AHB_CON0_OFFSET) +#define AHB_CON1_REG __REG(ELFIN_CLOCK_POWER_BASE+AHB_CON1_OFFSET) +#define AHB_CON2_REG __REG(ELFIN_CLOCK_POWER_BASE+AHB_CON2_OFFSET) +#define SELECT_DMA_REG __REG(ELFIN_CLOCK_POWER_BASE+SELECT_DMA_OFFSET) +#define SW_RST_REG __REG(ELFIN_CLOCK_POWER_BASE+SW_RST_OFFSET) +#define SYS_ID_REG __REG(ELFIN_CLOCK_POWER_BASE+SYS_ID_OFFSET) +#define MEM_SYS_CFG_REG __REG(ELFIN_CLOCK_POWER_BASE+MEM_SYS_CFG_OFFSET) +#define QOS_OVERRIDE0_REG __REG(ELFIN_CLOCK_POWER_BASE+QOS_OVERRIDE0_OFFSET) +#define QOS_OVERRIDE1_REG __REG(ELFIN_CLOCK_POWER_BASE+QOS_OVERRIDE1_OFFSET) +#define MEM_CFG_STAT_REG __REG(ELFIN_CLOCK_POWER_BASE+MEM_CFG_STAT_OFFSET) +#define PWR_CFG_REG __REG(ELFIN_CLOCK_POWER_BASE+PWR_CFG_OFFSET) +#define EINT_MASK_REG __REG(ELFIN_CLOCK_POWER_BASE+EINT_MASK_OFFSET) +#define NOR_CFG_REG __REG(ELFIN_CLOCK_POWER_BASE+NOR_CFG_OFFSET) +#define STOP_CFG_REG __REG(ELFIN_CLOCK_POWER_BASE+STOP_CFG_OFFSET) +#define SLEEP_CFG_REG __REG(ELFIN_CLOCK_POWER_BASE+SLEEP_CFG_OFFSET) +#define OSC_FREQ_REG __REG(ELFIN_CLOCK_POWER_BASE+OSC_FREQ_OFFSET) +#define OSC_CNT_VAL_REG __REG(ELFIN_CLOCK_POWER_BASE+OSC_CNT_VAL_OFFSET) +#define PWR_CNT_VAL_REG __REG(ELFIN_CLOCK_POWER_BASE+PWR_CNT_VAL_OFFSET) +#define FPC_CNT_VAL_REG __REG(ELFIN_CLOCK_POWER_BASE+FPC_CNT_VAL_OFFSET) +#define MTC_CNT_VAL_REG __REG(ELFIN_CLOCK_POWER_BASE+MTC_CNT_VAL_OFFSET) +#define OTHERS_REG __REG(ELFIN_CLOCK_POWER_BASE+OTHERS_OFFSET) +#define RST_STAT_REG __REG(ELFIN_CLOCK_POWER_BASE+RST_STAT_OFFSET) +#define WAKEUP_STAT_REG __REG(ELFIN_CLOCK_POWER_BASE+WAKEUP_STAT_OFFSET) +#define BLK_PWR_STAT_REG __REG(ELFIN_CLOCK_POWER_BASE+BLK_PWR_STAT_OFFSET) +#define INF_REG0_REG __REG(ELFIN_CLOCK_POWER_BASE+INF_REG0_OFFSET) +#define INF_REG1_REG __REG(ELFIN_CLOCK_POWER_BASE+INF_REG1_OFFSET) +#define INF_REG2_REG __REG(ELFIN_CLOCK_POWER_BASE+INF_REG2_OFFSET) +#define INF_REG3_REG __REG(ELFIN_CLOCK_POWER_BASE+INF_REG3_OFFSET) +#define INF_REG4_REG __REG(ELFIN_CLOCK_POWER_BASE+INF_REG4_OFFSET) +#define INF_REG5_REG __REG(ELFIN_CLOCK_POWER_BASE+INF_REG5_OFFSET) +#define INF_REG6_REG __REG(ELFIN_CLOCK_POWER_BASE+INF_REG6_OFFSET) +#define INF_REG7_REG __REG(ELFIN_CLOCK_POWER_BASE+INF_REG7_OFFSET) + +#define APLL_LOCK (ELFIN_CLOCK_POWER_BASE+APLL_LOCK_OFFSET) +#define MPLL_LOCK (ELFIN_CLOCK_POWER_BASE+MPLL_LOCK_OFFSET) +#define EPLL_LOCK (ELFIN_CLOCK_POWER_BASE+EPLL_LOCK_OFFSET) +#define APLL_CON (ELFIN_CLOCK_POWER_BASE+APLL_CON_OFFSET) +#define MPLL_CON (ELFIN_CLOCK_POWER_BASE+MPLL_CON_OFFSET) +#define EPLL_CON0 (ELFIN_CLOCK_POWER_BASE+EPLL_CON0_OFFSET) +#define EPLL_CON1 (ELFIN_CLOCK_POWER_BASE+EPLL_CON1_OFFSET) +#define CLK_SRC (ELFIN_CLOCK_POWER_BASE+CLK_SRC_OFFSET) +#define CLK_DIV0 (ELFIN_CLOCK_POWER_BASE+CLK_DIV0_OFFSET) +#define CLK_DIV1 (ELFIN_CLOCK_POWER_BASE+CLK_DIV1_OFFSET) +#define CLK_DIV2 (ELFIN_CLOCK_POWER_BASE+CLK_DIV2_OFFSET) +#define CLK_OUT (ELFIN_CLOCK_POWER_BASE+CLK_OUT_OFFSET) +#define HCLK_GATE (ELFIN_CLOCK_POWER_BASE+HCLK_GATE_OFFSET) +#define PCLK_GATE (ELFIN_CLOCK_POWER_BASE+PCLK_GATE_OFFSET) +#define SCLK_GATE (ELFIN_CLOCK_POWER_BASE+SCLK_GATE_OFFSET) +#define AHB_CON0 (ELFIN_CLOCK_POWER_BASE+AHB_CON0_OFFSET) +#define AHB_CON1 (ELFIN_CLOCK_POWER_BASE+AHB_CON1_OFFSET) +#define AHB_CON2 (ELFIN_CLOCK_POWER_BASE+AHB_CON2_OFFSET) +#define SELECT_DMA (ELFIN_CLOCK_POWER_BASE+SELECT_DMA_OFFSET) +#define SW_RST (ELFIN_CLOCK_POWER_BASE+SW_RST_OFFSET) +#define SYS_ID (ELFIN_CLOCK_POWER_BASE+SYS_ID_OFFSET) +#define MEM_SYS_CFG (ELFIN_CLOCK_POWER_BASE+MEM_SYS_CFG_OFFSET) +#define QOS_OVERRIDE0 (ELFIN_CLOCK_POWER_BASE+QOS_OVERRIDE0_OFFSET) +#define QOS_OVERRIDE1 (ELFIN_CLOCK_POWER_BASE+QOS_OVERRIDE1_OFFSET) +#define MEM_CFG_STAT (ELFIN_CLOCK_POWER_BASE+MEM_CFG_STAT_OFFSET) +#define PWR_CFG (ELFIN_CLOCK_POWER_BASE+PWR_CFG_OFFSET) +#define EINT_MASK (ELFIN_CLOCK_POWER_BASE+EINT_MASK_OFFSET) +#define NOR_CFG (ELFIN_CLOCK_POWER_BASE+NOR_CFG_OFFSET) +#define STOP_CFG (ELFIN_CLOCK_POWER_BASE+STOP_CFG_OFFSET) +#define SLEEP_CFG (ELFIN_CLOCK_POWER_BASE+SLEEP_CFG_OFFSET) +#define OSC_FREQ (ELFIN_CLOCK_POWER_BASE+OSC_FREQ_OFFSET) +#define OSC_CNT_VAL (ELFIN_CLOCK_POWER_BASE+OSC_CNT_VAL_OFFSET) +#define PWR_CNT_VAL (ELFIN_CLOCK_POWER_BASE+PWR_CNT_VAL_OFFSET) +#define FPC_CNT_VAL (ELFIN_CLOCK_POWER_BASE+FPC_CNT_VAL_OFFSET) +#define MTC_CNT_VAL (ELFIN_CLOCK_POWER_BASE+MTC_CNT_VAL_OFFSET) +#define OTHERS (ELFIN_CLOCK_POWER_BASE+OTHERS_OFFSET) +#define RST_STAT (ELFIN_CLOCK_POWER_BASE+RST_STAT_OFFSET) +#define WAKEUP_STAT (ELFIN_CLOCK_POWER_BASE+WAKEUP_STAT_OFFSET) +#define BLK_PWR_STAT (ELFIN_CLOCK_POWER_BASE+BLK_PWR_STAT_OFFSET) +#define INF_REG0 (ELFIN_CLOCK_POWER_BASE+INF_REG0_OFFSET) +#define INF_REG1 (ELFIN_CLOCK_POWER_BASE+INF_REG1_OFFSET) +#define INF_REG2 (ELFIN_CLOCK_POWER_BASE+INF_REG2_OFFSET) +#define INF_REG3 (ELFIN_CLOCK_POWER_BASE+INF_REG3_OFFSET) +#define INF_REG4 (ELFIN_CLOCK_POWER_BASE+INF_REG4_OFFSET) +#define INF_REG5 (ELFIN_CLOCK_POWER_BASE+INF_REG5_OFFSET) +#define INF_REG6 (ELFIN_CLOCK_POWER_BASE+INF_REG6_OFFSET) +#define INF_REG7 (ELFIN_CLOCK_POWER_BASE+INF_REG7_OFFSET) + + +/* + * GPIO + */ +#define ELFIN_GPIO_BASE 0x7f008000 + +#define GPACON_OFFSET 0x00 +#define GPADAT_OFFSET 0x04 +#define GPAPUD_OFFSET 0x08 +#define GPACONSLP_OFFSET 0x0C +#define GPAPUDSLP_OFFSET 0x10 +#define GPBCON_OFFSET 0x20 +#define GPBDAT_OFFSET 0x04 +#define GPBPUD_OFFSET 0x08 +#define GPBCONSLP_OFFSET 0x0C +#define GPBPUDSLP_OFFSET 0x30 +#define GPCCON_OFFSET 0x40 +#define GPCDAT_OFFSET 0x44 +#define GPCPUD_OFFSET 0x48 +#define GPCCONSLP_OFFSET 0x4C +#define GPCPUDSLP_OFFSET 0x50 +#define GPDCON_OFFSET 0x60 +#define GPDDAT_OFFSET 0x64 +#define GPDPUD_OFFSET 0x68 +#define GPDCONSLP_OFFSET 0x6C +#define GPDPUDSLP_OFFSET 0x70 +#define GPECON_OFFSET 0x80 +#define GPEDAT_OFFSET 0x84 +#define GPEPUD_OFFSET 0x88 +#define GPECONSLP_OFFSET 0x8C +#define GPEPUDSLP_OFFSET 0x90 +#define GPFCON_OFFSET 0xA0 +#define GPFDAT_OFFSET 0xA4 +#define GPFPUD_OFFSET 0xA8 +#define GPFCONSLP_OFFSET 0xAC +#define GPFPUDSLP_OFFSET 0xB0 +#define GPGCON_OFFSET 0xC0 +#define GPGDAT_OFFSET 0xC4 +#define GPGPUD_OFFSET 0xC8 +#define GPGCONSLP_OFFSET 0xCC +#define GPGPUDSLP_OFFSET 0xD0 +#define GPHCON0_OFFSET 0xE0 +#define GPHCON1_OFFSET 0xE4 +#define GPHDAT_OFFSET 0xE8 +#define GPHPUD_OFFSET 0xEC +#define GPHCONSLP_OFFSET 0xF0 +#define GPHPUDSLP_OFFSET 0xF4 +#define GPICON_OFFSET 0x100 +#define GPIDAT_OFFSET 0x104 +#define GPIPUD_OFFSET 0x108 +#define GPICONSLP_OFFSET 0x10C +#define GPIPUDSLP_OFFSET 0x110 +#define GPJCON_OFFSET 0x120 +#define GPJDAT_OFFSET 0x124 +#define GPJPUD_OFFSET 0x128 +#define GPJCONSLP_OFFSET 0x12C +#define GPJPUDSLP_OFFSET 0x130 +#define SPCON_OFFSET 0x1A0 +#define MEM0DRVCON_OFFSET 0x1D0 +#define MEM1DRVCON_OFFSET 0x1D4 +#define GPKCON0_OFFSET 0x800 +#define GPKCON1_OFFSET 0x804 +#define GPKDAT_OFFSET 0x808 +#define GPKPUD_OFFSET 0x80C +#define GPLCON0_OFFSET 0x810 +#define GPLCON1_OFFSET 0x814 +#define GPLDAT_OFFSET 0x818 +#define GPLPUD_OFFSET 0x81C +#define GPMCON_OFFSET 0x820 +#define GPMDAT_OFFSET 0x824 +#define GPMPUD_OFFSET 0x828 +#define GPNCON_OFFSET 0x830 +#define GPNDAT_OFFSET 0x834 +#define GPNPUD_OFFSET 0x838 +#define GPOCON_OFFSET 0x140 +#define GPODAT_OFFSET 0x144 +#define GPOPUD_OFFSET 0x148 +#define GPOCONSLP_OFFSET 0x14C +#define GPOPUDSLP_OFFSET 0x150 +#define GPPCON_OFFSET 0x160 +#define GPPDAT_OFFSET 0x164 +#define GPPPUD_OFFSET 0x168 +#define GPPCONSLP_OFFSET 0x16C +#define GPPPUDSLP_OFFSET 0x170 +#define GPQCON_OFFSET 0x180 +#define GPQDAT_OFFSET 0x184 +#define GPQPUD_OFFSET 0x188 +#define GPQCONSLP_OFFSET 0x18C +#define GPQPUDSLP_OFFSET 0x190 + +#define EINTPEND_OFFSET 0x924 + +#define GPACON_REG __REG(ELFIN_GPIO_BASE+GPACON_OFFSET) +#define GPADAT_REG __REG(ELFIN_GPIO_BASE+GPADAT_OFFSET) +#define GPAPUD_REG __REG(ELFIN_GPIO_BASE+GPAPUD_OFFSET) +#define GPACONSLP_REG __REG(ELFIN_GPIO_BASE+GPACONSLP_OFFSET) +#define GPAPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPAPUDSLP_OFFSET) +#define GPBCON_REG __REG(ELFIN_GPIO_BASE+GPBCON_OFFSET) +#define GPBDAT_REG __REG(ELFIN_GPIO_BASE+GPBDAT_OFFSET) +#define GPBPUD_REG __REG(ELFIN_GPIO_BASE+GPBPUD_OFFSET) +#define GPBCONSLP_REG __REG(ELFIN_GPIO_BASE+GPBCONSLP_OFFSET) +#define GPBPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPBPUDSLP_OFFSET) +#define GPCCON_REG __REG(ELFIN_GPIO_BASE+GPCCON_OFFSET) +#define GPCDAT_REG __REG(ELFIN_GPIO_BASE+GPCDAT_OFFSET) +#define GPCPUD_REG __REG(ELFIN_GPIO_BASE+GPCPUD_OFFSET) +#define GPCCONSLP_REG __REG(ELFIN_GPIO_BASE+GPCCONSLP_OFFSET) +#define GPCPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPCPUDSLP_OFFSET) +#define GPDCON_REG __REG(ELFIN_GPIO_BASE+GPDCON_OFFSET) +#define GPDDAT_REG __REG(ELFIN_GPIO_BASE+GPDDAT_OFFSET) +#define GPDPUD_REG __REG(ELFIN_GPIO_BASE+GPDPUD_OFFSET) +#define GPDCONSLP_REG __REG(ELFIN_GPIO_BASE+GPDCONSLP_OFFSET) +#define GPDPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPDPUDSLP_OFFSET) +#define GPECON_REG __REG(ELFIN_GPIO_BASE+GPECON_OFFSET) +#define GPEDAT_REG __REG(ELFIN_GPIO_BASE+GPEDAT_OFFSET) +#define GPEPUD_REG __REG(ELFIN_GPIO_BASE+GPEPUD_OFFSET) +#define GPECONSLP_REG __REG(ELFIN_GPIO_BASE+GPECONSLP_OFFSET) +#define GPEPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPEPUDSLP_OFFSET) +#define GPFCON_REG __REG(ELFIN_GPIO_BASE+GPFCON_OFFSET) +#define GPFDAT_REG __REG(ELFIN_GPIO_BASE+GPFDAT_OFFSET) +#define GPFPUD_REG __REG(ELFIN_GPIO_BASE+GPFPUD_OFFSET) +#define GPFCONSLP_REG __REG(ELFIN_GPIO_BASE+GPFCONSLP_OFFSET) +#define GPFPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPFPUDSLP_OFFSET) +#define GPGCON_REG __REG(ELFIN_GPIO_BASE+GPGCON_OFFSET) +#define GPGDAT_REG __REG(ELFIN_GPIO_BASE+GPGDAT_OFFSET) +#define GPGPUD_REG __REG(ELFIN_GPIO_BASE+GPGPUD_OFFSET) +#define GPGCONSLP_REG __REG(ELFIN_GPIO_BASE+GPGCONSLP_OFFSET) +#define GPGPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPGPUDSLP_OFFSET) +#define GPHCON0_REG __REG(ELFIN_GPIO_BASE+GPHCON0_OFFSET) +#define GPHCON1_REG __REG(ELFIN_GPIO_BASE+GPHCON1_OFFSET) +#define GPHDAT_REG __REG(ELFIN_GPIO_BASE+GPHDAT_OFFSET) +#define GPHPUD_REG __REG(ELFIN_GPIO_BASE+GPHPUD_OFFSET) +#define GPHCONSLP_REG __REG(ELFIN_GPIO_BASE+GPHCONSLP_OFFSET) +#define GPHPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPHPUDSLP_OFFSET) +#define GPICON_REG __REG(ELFIN_GPIO_BASE+GPICON_OFFSET) +#define GPIDAT_REG __REG(ELFIN_GPIO_BASE+GPIDAT_OFFSET) +#define GPIPUD_REG __REG(ELFIN_GPIO_BASE+GPIPUD_OFFSET) +#define GPICONSLP_REG __REG(ELFIN_GPIO_BASE+GPICONSLP_OFFSET) +#define GPIPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPIPUDSLP_OFFSET) +#define GPJCON_REG __REG(ELFIN_GPIO_BASE+GPJCON_OFFSET) +#define GPJDAT_REG __REG(ELFIN_GPIO_BASE+GPJDAT_OFFSET) +#define GPJPUD_REG __REG(ELFIN_GPIO_BASE+GPJPUD_OFFSET) +#define GPJCONSLP_REG __REG(ELFIN_GPIO_BASE+GPJCONSLP_OFFSET) +#define GPJPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPJPUDSLP_OFFSET) +#define GPKCON0_REG __REG(ELFIN_GPIO_BASE+GPKCON0_OFFSET) +#define GPKCON1_REG __REG(ELFIN_GPIO_BASE+GPKCON1_OFFSET) +#define GPKDAT_REG __REG(ELFIN_GPIO_BASE+GPKDAT_OFFSET) +#define GPKPUD_REG __REG(ELFIN_GPIO_BASE+GPKPUD_OFFSET) +#define GPLCON0_REG __REG(ELFIN_GPIO_BASE+GPLCON0_OFFSET) +#define GPLCON1_REG __REG(ELFIN_GPIO_BASE+GPLCON1_OFFSET) +#define GPLDAT_REG __REG(ELFIN_GPIO_BASE+GPLDAT_OFFSET) +#define GPLPUD_REG __REG(ELFIN_GPIO_BASE+GPLPUD_OFFSET) +#define GPMCON_REG __REG(ELFIN_GPIO_BASE+GPMCON_OFFSET) +#define GPMDAT_REG __REG(ELFIN_GPIO_BASE+GPMDAT_OFFSET) +#define GPMPUD_REG __REG(ELFIN_GPIO_BASE+GPMPUD_OFFSET) +#define GPNCON_REG __REG(ELFIN_GPIO_BASE+GPNCON_OFFSET) +#define GPNDAT_REG __REG(ELFIN_GPIO_BASE+GPNDAT_OFFSET) +#define GPNPUD_REG __REG(ELFIN_GPIO_BASE+GPNPUD_OFFSET) +#define GPOCON_REG __REG(ELFIN_GPIO_BASE+GPOCON_OFFSET) +#define GPODAT_REG __REG(ELFIN_GPIO_BASE+GPODAT_OFFSET) +#define GPOPUD_REG __REG(ELFIN_GPIO_BASE+GPOPUD_OFFSET) +#define GPOCONSLP_REG __REG(ELFIN_GPIO_BASE+GPOCONSLP_OFFSET) +#define GPOPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPOPUDSLP_OFFSET) +#define GPPCON_REG __REG(ELFIN_GPIO_BASE+GPPCON_OFFSET) +#define GPPDAT_REG __REG(ELFIN_GPIO_BASE+GPPDAT_OFFSET) +#define GPPPUD_REG __REG(ELFIN_GPIO_BASE+GPPPUD_OFFSET) +#define GPPCONSLP_REG __REG(ELFIN_GPIO_BASE+GPPCONSLP_OFFSET) +#define GPPPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPPPUDSLP_OFFSET) +#define GPQCON_REG __REG(ELFIN_GPIO_BASE+GPQCON_OFFSET) +#define GPQDAT_REG __REG(ELFIN_GPIO_BASE+GPQDAT_OFFSET) +#define GPQPUD_REG __REG(ELFIN_GPIO_BASE+GPQPUD_OFFSET) +#define GPQCONSLP_REG __REG(ELFIN_GPIO_BASE+GPQCONSLP_OFFSET) +#define GPQPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPQPUDSLP_OFFSET) + +#define GPACON (ELFIN_GPIO_BASE+GPACON_OFFSET) +#define GPADAT (ELFIN_GPIO_BASE+GPADAT_OFFSET) +#define GPAPUD (ELFIN_GPIO_BASE+GPAPUD_OFFSET) +#define GPACONSLP (ELFIN_GPIO_BASE+GPACONSLP_OFFSET) +#define GPAPUDSLP (ELFIN_GPIO_BASE+GPAPUDSLP_OFFSET) +#define GPBCON (ELFIN_GPIO_BASE+GPBCON_OFFSET) +#define GPBDAT (ELFIN_GPIO_BASE+GPBDAT_OFFSET) +#define GPBPUD (ELFIN_GPIO_BASE+GPBPUD_OFFSET) +#define GPBCONSLP (ELFIN_GPIO_BASE+GPBCONSLP_OFFSET) +#define GPBPUDSLP (ELFIN_GPIO_BASE+GPBPUDSLP_OFFSET) +#define GPCCON (ELFIN_GPIO_BASE+GPCCON_OFFSET) +#define GPCDAT (ELFIN_GPIO_BASE+GPCDAT_OFFSET) +#define GPCPUD (ELFIN_GPIO_BASE+GPCPUD_OFFSET) +#define GPCCONSLP (ELFIN_GPIO_BASE+GPCCONSLP_OFFSET) +#define GPCPUDSLP (ELFIN_GPIO_BASE+GPCPUDSLP_OFFSET) +#define GPDCON (ELFIN_GPIO_BASE+GPDCON_OFFSET) +#define GPDDAT (ELFIN_GPIO_BASE+GPDDAT_OFFSET) +#define GPDPUD (ELFIN_GPIO_BASE+GPDPUD_OFFSET) +#define GPDCONSLP (ELFIN_GPIO_BASE+GPDCONSLP_OFFSET) +#define GPDPUDSLP (ELFIN_GPIO_BASE+GPDPUDSLP_OFFSET) +#define GPECON (ELFIN_GPIO_BASE+GPECON_OFFSET) +#define GPEDAT (ELFIN_GPIO_BASE+GPEDAT_OFFSET) +#define GPEPUD (ELFIN_GPIO_BASE+GPEPUD_OFFSET) +#define GPECONSLP (ELFIN_GPIO_BASE+GPECONSLP_OFFSET) +#define GPEPUDSLP (ELFIN_GPIO_BASE+GPEPUDSLP_OFFSET) +#define GPFCON (ELFIN_GPIO_BASE+GPFCON_OFFSET) +#define GPFDAT (ELFIN_GPIO_BASE+GPFDAT_OFFSET) +#define GPFPUD (ELFIN_GPIO_BASE+GPFPUD_OFFSET) +#define GPFCONSLP (ELFIN_GPIO_BASE+GPFCONSLP_OFFSET) +#define GPFPUDSLP (ELFIN_GPIO_BASE+GPFPUDSLP_OFFSET) +#define GPGCON (ELFIN_GPIO_BASE+GPGCON_OFFSET) +#define GPGDAT (ELFIN_GPIO_BASE+GPGDAT_OFFSET) +#define GPGPUD (ELFIN_GPIO_BASE+GPGPUD_OFFSET) +#define GPGCONSLP (ELFIN_GPIO_BASE+GPGCONSLP_OFFSET) +#define GPGPUDSLP (ELFIN_GPIO_BASE+GPGPUDSLP_OFFSET) +#define GPHCON0 (ELFIN_GPIO_BASE+GPHCON0_OFFSET) +#define GPHCON1 (ELFIN_GPIO_BASE+GPHCON1_OFFSET) +#define GPHDAT (ELFIN_GPIO_BASE+GPHDAT_OFFSET) +#define GPHPUD (ELFIN_GPIO_BASE+GPHPUD_OFFSET) +#define GPHCONSLP (ELFIN_GPIO_BASE+GPHCONSLP_OFFSET) +#define GPHPUDSLP (ELFIN_GPIO_BASE+GPHPUDSLP_OFFSET) +#define GPICON (ELFIN_GPIO_BASE+GPICON_OFFSET) +#define GPIDAT (ELFIN_GPIO_BASE+GPIDAT_OFFSET) +#define GPIPUD (ELFIN_GPIO_BASE+GPIPUD_OFFSET) +#define GPICONSLP (ELFIN_GPIO_BASE+GPICONSLP_OFFSET) +#define GPIPUDSLP (ELFIN_GPIO_BASE+GPIPUDSLP_OFFSET) +#define GPJCON (ELFIN_GPIO_BASE+GPJCON_OFFSET) +#define GPJDAT (ELFIN_GPIO_BASE+GPJDAT_OFFSET) +#define GPJPUD (ELFIN_GPIO_BASE+GPJPUD_OFFSET) +#define GPJCONSLP (ELFIN_GPIO_BASE+GPJCONSLP_OFFSET) +#define GPJPUDSLP (ELFIN_GPIO_BASE+GPJPUDSLP_OFFSET) +#define GPKCON0 (ELFIN_GPIO_BASE+GPKCON0_OFFSET) +#define GPKCON1 (ELFIN_GPIO_BASE+GPKCON1_OFFSET) +#define GPKDAT (ELFIN_GPIO_BASE+GPKDAT_OFFSET) +#define GPKPUD (ELFIN_GPIO_BASE+GPKPUD_OFFSET) +#define GPLCON0 (ELFIN_GPIO_BASE+GPLCON0_OFFSET) +#define GPLCON1 (ELFIN_GPIO_BASE+GPLCON1_OFFSET) +#define GPLDAT (ELFIN_GPIO_BASE+GPLDAT_OFFSET) +#define GPLPUD (ELFIN_GPIO_BASE+GPLPUD_OFFSET) +#define GPMCON (ELFIN_GPIO_BASE+GPMCON_OFFSET) +#define GPMDAT (ELFIN_GPIO_BASE+GPMDAT_OFFSET) +#define GPMPUD (ELFIN_GPIO_BASE+GPMPUD_OFFSET) +#define GPNCON (ELFIN_GPIO_BASE+GPNCON_OFFSET) +#define GPNDAT (ELFIN_GPIO_BASE+GPNDAT_OFFSET) +#define GPNPUD (ELFIN_GPIO_BASE+GPNPUD_OFFSET) +#define GPOCON (ELFIN_GPIO_BASE+GPOCON_OFFSET) +#define GPODAT (ELFIN_GPIO_BASE+GPODAT_OFFSET) +#define GPOPUD (ELFIN_GPIO_BASE+GPOPUD_OFFSET) +#define GPOCONSLP (ELFIN_GPIO_BASE+GPOCONSLP_OFFSET) +#define GPOPUDSLP (ELFIN_GPIO_BASE+GPOPUDSLP_OFFSET) +#define GPPCON (ELFIN_GPIO_BASE+GPPCON_OFFSET) +#define GPPDAT (ELFIN_GPIO_BASE+GPPDAT_OFFSET) +#define GPPPUD (ELFIN_GPIO_BASE+GPPPUD_OFFSET) +#define GPPCONSLP (ELFIN_GPIO_BASE+GPPCONSLP_OFFSET) +#define GPPPUDSLP (ELFIN_GPIO_BASE+GPPPUDSLP_OFFSET) +#define GPQCON (ELFIN_GPIO_BASE+GPQCON_OFFSET) +#define GPQDAT (ELFIN_GPIO_BASE+GPQDAT_OFFSET) +#define GPQPUD (ELFIN_GPIO_BASE+GPQPUD_OFFSET) +#define GPQCONSLP (ELFIN_GPIO_BASE+GPQCONSLP_OFFSET) +#define GPQPUDSLP (ELFIN_GPIO_BASE+GPQPUDSLP_OFFSET) + +/* + * Bus Matrix + */ +#define ELFIN_MEM_SYS_CFG 0x7e00f120 + + + +/* + * Memory controller + */ +#define ELFIN_SROM_BASE 0x70000000 + +#define SROM_BW_REG __REG(ELFIN_SROM_BASE+0x0) +#define SROM_BC0_REG __REG(ELFIN_SROM_BASE+0x4) +#define SROM_BC1_REG __REG(ELFIN_SROM_BASE+0x8) +#define SROM_BC2_REG __REG(ELFIN_SROM_BASE+0xC) +#define SROM_BC3_REG __REG(ELFIN_SROM_BASE+0x10) +#define SROM_BC4_REG __REG(ELFIN_SROM_BASE+0x14) +#define SROM_BC5_REG __REG(ELFIN_SROM_BASE+0x18) + + + +/* + * SDRAM Controller + */ +#define ELFIN_DMC0_BASE 0x7e000000 +#define ELFIN_DMC1_BASE 0x7e001000 + +#define INDEX_DMC_MEMC_STATUS (0x00) +#define INDEX_DMC_MEMC_CMD (0x04) +#define INDEX_DMC_DIRECT_CMD (0x08) +#define INDEX_DMC_MEMORY_CFG (0x0C) +#define INDEX_DMC_REFRESH_PRD (0x10) +#define INDEX_DMC_CAS_LATENCY (0x14) +#define INDEX_DMC_T_DQSS (0x18) +#define INDEX_DMC_T_MRD (0x1C) +#define INDEX_DMC_T_RAS (0x20) +#define INDEX_DMC_T_RC (0x24) +#define INDEX_DMC_T_RCD (0x28) +#define INDEX_DMC_T_RFC (0x2C) +#define INDEX_DMC_T_RP (0x30) +#define INDEX_DMC_T_RRD (0x34) +#define INDEX_DMC_T_WR (0x38) +#define INDEX_DMC_T_WTR (0x3C) +#define INDEX_DMC_T_XP (0x40) +#define INDEX_DMC_T_XSR (0x44) +#define INDEX_DMC_T_ESR (0x48) +#define INDEX_DMC_MEMORY_CFG2 (0x4C) +#define INDEX_DMC_CHIP_0_CFG (0x200) +#define INDEX_DMC_CHIP_1_CFG (0x204) +#define INDEX_DMC_CHIP_2_CFG (0x208) +#define INDEX_DMC_CHIP_3_CFG (0x20C) +#define INDEX_DMC_USER_STATUS (0x300) +#define INDEX_DMC_USER_CONFIG (0x304) + +/* +* Memory Chip direct command +*/ +#define DMC_NOP0 0x0c0000 +#define DMC_NOP1 0x1c0000 +#define DMC_PA0 0x000000 //Precharge all +#define DMC_PA1 0x100000 +#define DMC_AR0 0x040000 //Autorefresh +#define DMC_AR1 0x140000 +#define DMC_SDR_MR0 0x080032 //MRS, CAS 3, Burst Length 4 +#define DMC_SDR_MR1 0x180032 +#define DMC_DDR_MR0 0x080162 +#define DMC_DDR_MR1 0x180162 +#define DMC_mDDR_MR0 0x080032 //CAS 3, Burst Length 4 +#define DMC_mDDR_MR1 0x180032 +#define DMC_mSDR_EMR0 0x0a0000 //EMRS, DS:Full, PASR:Full Array +#define DMC_mSDR_EMR1 0x1a0000 +#define DMC_DDR_EMR0 0x090000 +#define DMC_DDR_EMR1 0x190000 +#define DMC_mDDR_EMR0 0x0a0000 // DS:Full, PASR:Full Array +#define DMC_mDDR_EMR1 0x1a0000 + + +/**************************************************************** + Definitions for memory configuration + Set memory configuration + active_chips = 1'b0 (1 chip) + qos_master_chip = 3'b000(ARID[3:0]) + memory burst = 3'b010(burst 4) + stop_mem_clock = 1'b0(disable dynamical stop) + auto_power_down = 1'b0(disable auto power-down mode) + power_down_prd = 6'b00_0000(0 cycle for auto power-down) + ap_bit = 1'b0 (bit position of auto-precharge is 10) + row_bits = 3'b010(# row address 13) + column_bits = 3'b010(# column address 10 ) + + Set user configuration + 2'b10=SDRAM/mSDRAM, 2'b11=DDR, 2'b01=mDDR + + Set chip select for chip [n] + row bank control, bank address 0x3000_0000 ~ 0x37ff_ffff + CHIP_[n]_CFG=0x30F8, 30: ADDR[31:24], F8: Mask[31:24] +******************************************************************/ + +/* + * HS MMC Interface + */ +#define ELFIN_HSMMC_BASE 0x7C200000 + +#define HM_SYSAD (0x00) +#define HM_BLKSIZE (0x04) +#define HM_BLKCNT (0x06) +#define HM_ARGUMENT (0x08) +#define HM_TRNMOD (0x0c) +#define HM_CMDREG (0x0e) +#define HM_RSPREG0 (0x10) +#define HM_RSPREG1 (0x14) +#define HM_RSPREG2 (0x18) +#define HM_RSPREG3 (0x1c) +#define HM_BDATA (0x20) +#define HM_PRNSTS (0x24) +#define HM_HOSTCTL (0x28) +#define HM_PWRCON (0x29) +#define HM_BLKGAP (0x2a) +#define HM_WAKCON (0x2b) +#define HM_CLKCON (0x2c) +#define HM_TIMEOUTCON (0x2e) +#define HM_SWRST (0x2f) +#define HM_NORINTSTS (0x30) +#define HM_ERRINTSTS (0x32) +#define HM_NORINTSTSEN (0x34) +#define HM_ERRINTSTSEN (0x36) +#define HM_NORINTSIGEN (0x38) +#define HM_ERRINTSIGEN (0x3a) +#define HM_ACMD12ERRSTS (0x3c) +#define HM_CAPAREG (0x40) +#define HM_MAXCURR (0x48) +#define HM_CONTROL2 (0x80) +#define HM_CONTROL3 (0x84) +#define HM_CONTROL4 (0x8c) +#define HM_HCVER (0xfe) + +/* + * Nand flash controller + */ +#define ELFIN_NAND_BASE 0x70200000 + +#define NFCONF_OFFSET 0x00 +#define NFCONT_OFFSET 0x04 +#define NFCMMD_OFFSET 0x08 +#define NFADDR_OFFSET 0x0c +#define NFDATA_OFFSET 0x10 +#define NFMECCDATA0_OFFSET 0x14 +#define NFMECCDATA1_OFFSET 0x18 +#define NFSECCDATA0_OFFSET 0x1c +#define NFSBLK_OFFSET 0x20 +#define NFEBLK_OFFSET 0x24 +#define NFSTAT_OFFSET 0x28 +#define NFESTAT0_OFFSET 0x2c +#define NFESTAT1_OFFSET 0x30 +#define NFMECC0_OFFSET 0x34 +#define NFMECC1_OFFSET 0x38 +#define NFSECC_OFFSET 0x3c +#define NFMLCBITPT_OFFSET 0x40 +#define NF8ECCERR0_OFFSET 0x44 +#define NF8ECCERR1_OFFSET 0x48 +#define NF8ECCERR2_OFFSET 0x4c +#define NFM8ECC0_OFFSET 0x50 +#define NFM8ECC1_OFFSET 0x54 +#define NFM8ECC2_OFFSET 0x58 +#define NFM8ECC3_OFFSET 0x5c +#define NFMLC8BITPT0_OFFSET 0x60 +#define NFMLC8BITPT1_OFFSET 0x64 + +#define NFCONF (ELFIN_NAND_BASE+NFCONF_OFFSET) +#define NFCONT (ELFIN_NAND_BASE+NFCONT_OFFSET) +#define NFCMMD (ELFIN_NAND_BASE+NFCMMD_OFFSET) +#define NFADDR (ELFIN_NAND_BASE+NFADDR_OFFSET) +#define NFDATA (ELFIN_NAND_BASE+NFDATA_OFFSET) +#define NFMECCDATA0 (ELFIN_NAND_BASE+NFMECCDATA0_OFFSET) +#define NFMECCDATA1 (ELFIN_NAND_BASE+NFMECCDATA1_OFFSET) +#define NFSECCDATA0 (ELFIN_NAND_BASE+NFSECCDATA0_OFFSET) +#define NFSBLK (ELFIN_NAND_BASE+NFSBLK_OFFSET) +#define NFEBLK (ELFIN_NAND_BASE+NFEBLK_OFFSET) +#define NFSTAT (ELFIN_NAND_BASE+NFSTAT_OFFSET) +#define NFESTAT0 (ELFIN_NAND_BASE+NFESTAT0_OFFSET) +#define NFESTAT1 (ELFIN_NAND_BASE+NFESTAT1_OFFSET) +#define NFMECC0 (ELFIN_NAND_BASE+NFMECC0_OFFSET) +#define NFMECC1 (ELFIN_NAND_BASE+NFMECC1_OFFSET) +#define NFSECC (ELFIN_NAND_BASE+NFSECC_OFFSET) +#define NFMLCBITPT (ELFIN_NAND_BASE+NFMLCBITPT_OFFSET) +#define NF8ECCERR0 (ELFIN_NAND_BASE+NF8ECCERR0_OFFSET) +#define NF8ECCERR1 (ELFIN_NAND_BASE+NF8ECCERR1_OFFSET) +#define NF8ECCERR2 (ELFIN_NAND_BASE+NF8ECCERR2_OFFSET) +#define NFM8ECC0 (ELFIN_NAND_BASE+NFM8ECC0_OFFSET) +#define NFM8ECC1 (ELFIN_NAND_BASE+NFM8ECC1_OFFSET) +#define NFM8ECC2 (ELFIN_NAND_BASE+NFM8ECC2_OFFSET) +#define NFM8ECC3 (ELFIN_NAND_BASE+NFM8ECC3_OFFSET) +#define NFMLC8BITPT0 (ELFIN_NAND_BASE+NFMLC8BITPT0_OFFSET) +#define NFMLC8BITPT1 (ELFIN_NAND_BASE+NFMLC8BITPT1_OFFSET) + +#define NFCONF_REG __REG(ELFIN_NAND_BASE+NFCONF_OFFSET) +#define NFCONT_REG __REG(ELFIN_NAND_BASE+NFCONT_OFFSET) +#define NFCMD_REG __REG(ELFIN_NAND_BASE+NFCMMD_OFFSET) +#define NFADDR_REG __REG(ELFIN_NAND_BASE+NFADDR_OFFSET) +#define NFDATA_REG __REG(ELFIN_NAND_BASE+NFDATA_OFFSET) +#define NFDATA8_REG __REGb(ELFIN_NAND_BASE+NFDATA_OFFSET) +#define NFMECCDATA0_REG __REG(ELFIN_NAND_BASE+NFMECCDATA0_OFFSET) +#define NFMECCDATA1_REG __REG(ELFIN_NAND_BASE+NFMECCDATA1_OFFSET) +#define NFSECCDATA0_REG __REG(ELFIN_NAND_BASE+NFSECCDATA0_OFFSET) +#define NFSBLK_REG __REG(ELFIN_NAND_BASE+NFSBLK_OFFSET) +#define NFEBLK_REG __REG(ELFIN_NAND_BASE+NFEBLK_OFFSET) +#define NFSTAT_REG __REG(ELFIN_NAND_BASE+NFSTAT_OFFSET) +#define NFESTAT0_REG __REG(ELFIN_NAND_BASE+NFESTAT0_OFFSET) +#define NFESTAT1_REG __REG(ELFIN_NAND_BASE+NFESTAT1_OFFSET) +#define NFMECC0_REG __REG(ELFIN_NAND_BASE+NFMECC0_OFFSET) +#define NFMECC1_REG __REG(ELFIN_NAND_BASE+NFMECC1_OFFSET) +#define NFSECC_REG __REG(ELFIN_NAND_BASE+NFSECC_OFFSET) +#define NFMLCBITPT_REG __REG(ELFIN_NAND_BASE+NFMLCBITPT_OFFSET) + +#define NFCONF_ECC_MLC (1<<24) +#define NFCONT_ECC_ENC (1<<18) +#define NFCONT_WP (1<<16) +#define NFCONT_MECCLOCK (1<<7) +#define NFCONT_SECCLOCK (1<<6) +#define NFCONT_INITMECC (1<<5) +#define NFCONT_INITSECC (1<<4) +#define NFCONT_INITECC (NFCONT_INITMECC | NFCONT_INITSECC) +#define NFCONT_CS_ALT (1<<1) +#define NFCONT_CS (1<<1) +#define NFSTAT_ECCENCDONE (1<<7) +#define NFSTAT_ECCDECDONE (1<<6) +#define NFSTAT_RnB (1<<0) +#define NFESTAT0_ECCBUSY (1<<31) + + + +/************************************************************* + * OneNAND Controller + *************************************************************/ + +/* + * S3C6400 SFRs + */ +#define ONENAND_REG_MEM_CFG (0x000) +#define ONENAND_REG_BURST_LEN (0x010) +#define ONENAND_REG_MEM_RESET (0x020) +#define ONENAND_REG_INT_ERR_STAT (0x030) +#define ONENAND_REG_INT_ERR_MASK (0x040) +#define ONENAND_REG_INT_ERR_ACK (0x050) +#define ONENAND_REG_ECC_ERR_STAT (0x060) +#define ONENAND_REG_MANUFACT_ID (0x070) +#define ONENAND_REG_DEVICE_ID (0x080) +#define ONENAND_REG_DATA_BUF_SIZE (0x090) +#define ONENAND_REG_BOOT_BUF_SIZE (0x0A0) +#define ONENAND_REG_BUF_AMOUNT (0x0B0) +#define ONENAND_REG_TECH (0x0C0) +#define ONENAND_REG_FBA_WIDTH (0x0D0) +#define ONENAND_REG_FPA_WIDTH (0x0E0) +#define ONENAND_REG_FSA_WIDTH (0x0F0) +#define ONENAND_REG_REVISION (0x100) +#define ONENAND_REG_DATARAM0 (0x110) +#define ONENAND_REG_DATARAM1 (0x120) +#define ONENAND_REG_SYNC_MODE (0x130) +#define ONENAND_REG_TRANS_SPARE (0x140) +#define ONENAND_REG_LOCK_BIT (0x150) +#define ONENAND_REG_DBS_DFS_WIDTH (0x160) +#define ONENAND_REG_PAGE_CNT (0x170) +#define ONENAND_REG_ERR_PAGE_ADDR (0x180) +#define ONENAND_REG_BURST_RD_LAT (0x190) +#define ONENAND_REG_INT_PIN_ENABLE (0x1A0) +#define ONENAND_REG_INT_MON_CYC (0x1B0) +#define ONENAND_REG_ACC_CLOCK (0x1C0) +#define ONENAND_REG_SLOW_RD_PATH (0x1D0) +#define ONENAND_REG_ERR_BLK_ADDR (0x1E0) +#define ONENAND_REG_FLASH_VER_ID (0x1F0) +#define ONENAND_REG_FLASH_AUX_CNTRL (0x300) + +/* + * S3C6400 SFR values + */ +#define ONENAND_MEM_CFG_SYNC_READ (1 << 15) +#define ONENAND_MEM_CFG_BRL_7 (7 << 12) +#define ONENAND_MEM_CFG_BRL_6 (6 << 12) +#define ONENAND_MEM_CFG_BRL_5 (5 << 12) +#define ONENAND_MEM_CFG_BRL_4 (4 << 12) +#define ONENAND_MEM_CFG_BRL_3 (3 << 12) +#define ONENAND_MEM_CFG_BRL_10 (2 << 12) +#define ONENAND_MEM_CFG_BRL_9 (1 << 12) +#define ONENAND_MEM_CFG_BRL_8 (0 << 12) +#define ONENAND_MEM_CFG_BRL_SHIFT (12) +#define ONENAND_MEM_CFG_BL_1K (5 << 9) +#define ONENAND_MEM_CFG_BL_32 (4 << 9) +#define ONENAND_MEM_CFG_BL_16 (3 << 9) +#define ONENAND_MEM_CFG_BL_8 (2 << 9) +#define ONENAND_MEM_CFG_BL_4 (1 << 9) +#define ONENAND_MEM_CFG_BL_CONT (0 << 9) +#define ONENAND_MEM_CFG_BL_SHIFT (9) +#define ONENAND_MEM_CFG_NO_ECC (1 << 8) +#define ONENAND_MEM_CFG_RDY_HIGH (1 << 7) +#define ONENAND_MEM_CFG_INT_HIGH (1 << 6) +#define ONENAND_MEM_CFG_IOBE (1 << 5) +#define ONENAND_MEM_CFG_RDY_CONF (1 << 4) +#define ONENAND_MEM_CFG_HF (1 << 2) +#define ONENAND_MEM_CFG_WM_SYNC (1 << 1) +#define ONENAND_MEM_CFG_BWPS_UNLOCK (1 << 0) + +#define ONENAND_BURST_LEN_CONT (0) +#define ONENAND_BURST_LEN_4 (4) +#define ONENAND_BURST_LEN_8 (8) +#define ONENAND_BURST_LEN_16 (16) + +#define ONENAND_MEM_RESET_WARM (0x1) +#define ONENAND_MEM_RESET_COLD (0x2) +#define ONENAND_MEM_RESET_HOT (0x3) + +#define ONENAND_INT_ERR_CACHE_OP_ERR (1 << 13) +#define ONENAND_INT_ERR_RST_CMP (1 << 12) +#define ONENAND_INT_ERR_RDY_ACT (1 << 11) +#define ONENAND_INT_ERR_INT_ACT (1 << 10) +#define ONENAND_INT_ERR_UNSUP_CMD (1 << 9) +#define ONENAND_INT_ERR_LOCKED_BLK (1 << 8) +#define ONENAND_INT_ERR_BLK_RW_CMP (1 << 7) +#define ONENAND_INT_ERR_ERS_CMP (1 << 6) +#define ONENAND_INT_ERR_PGM_CMP (1 << 5) +#define ONENAND_INT_ERR_LOAD_CMP (1 << 4) +#define ONENAND_INT_ERR_ERS_FAIL (1 << 3) +#define ONENAND_INT_ERR_PGM_FAIL (1 << 2) +#define ONENAND_INT_ERR_INT_TO (1 << 1) +#define ONENAND_INT_ERR_LD_FAIL_ECC_ERR (1 << 0) + +#define ONENAND_DEVICE_DENSITY_SHIFT (4) +#define ONENAND_DEVICE_IS_DDP (1 << 3) +#define ONENAND_DEVICE_IS_DEMUX (1 << 2) +#define ONENAND_DEVICE_VCC_MASK (0x3) +#define ONENAND_DEVICE_DENSITY_128Mb (0x000) +#define ONENAND_DEVICE_DENSITY_256Mb (0x001) +#define ONENAND_DEVICE_DENSITY_512Mb (0x002) +#define ONENAND_DEVICE_DENSITY_1Gb (0x003) +#define ONENAND_DEVICE_DENSITY_2Gb (0x004) +#define ONENAND_DEVICE_DENSITY_4Gb (0x005) + +#define ONENAND_SYNC_MODE_RM_SYNC (1 << 1) +#define ONENAND_SYNC_MODE_WM_SYNC (1 << 0) + +#define ONENAND_TRANS_SPARE_TSRF_INC (1 << 0) + +#define ONENAND_INT_PIN_ENABLE (1 << 0) + +#define ONENAND_ACC_CLOCK_266_133 (0x5) +#define ONENAND_ACC_CLOCK_166_83 (0x3) +#define ONENAND_ACC_CLOCK_134_67 (0x3) +#define ONENAND_ACC_CLOCK_100_50 (0x2) +#define ONENAND_ACC_CLOCK_60_30 (0x2) + +#define ONENAND_FLASH_AUX_WD_DISABLE (1 << 0) + +/* + * Datain values for mapped commands + */ +#define ONENAND_DATAIN_ERASE_STATUS (0x00) +#define ONENAND_DATAIN_ERASE_MULTI (0x01) +#define ONENAND_DATAIN_ERASE_SINGLE (0x03) +#define ONENAND_DATAIN_ERASE_VERIFY (0x15) +#define ONENAND_DATAIN_UNLOCK_START (0x08) +#define ONENAND_DATAIN_UNLOCK_END (0x09) +#define ONENAND_DATAIN_LOCK_START (0x0A) +#define ONENAND_DATAIN_LOCK_END (0x0B) +#define ONENAND_DATAIN_LOCKTIGHT_START (0x0C) +#define ONENAND_DATAIN_LOCKTIGHT_END (0x0D) +#define ONENAND_DATAIN_UNLOCK_ALL (0x0E) +#define ONENAND_DATAIN_COPYBACK_SRC (0x1000) +#define ONENAND_DATAIN_COPYBACK_DST (0x2000) +#define ONENAND_DATAIN_ACCESS_OTP (0x12) +#define ONENAND_DATAIN_ACCESS_MAIN (0x14) +#define ONENAND_DATAIN_PIPELINE_READ (0x4000) +#define ONENAND_DATAIN_PIPELINE_WRITE (0x4100) +#define ONENAND_DATAIN_RMW_LOAD (0x10) +#define ONENAND_DATAIN_RMW_MODIFY (0x11) + +/* + * Device ID Register F001h (R) + */ +#define ONENAND_DEVICE_DENSITY_SHIFT (4) +#define ONENAND_DEVICE_IS_DDP (1 << 3) +#define ONENAND_DEVICE_IS_DEMUX (1 << 2) +#define ONENAND_DEVICE_VCC_MASK (0x3) + +/* + * Version ID Register F002h (R) + */ +#define ONENAND_VERSION_PROCESS_SHIFT (8) + +/* + * Start Address 1 F100h (R/W) + */ +#define ONENAND_DDP_SHIFT (15) +#define ONENAND_DDP_CHIP0 (0) +#define ONENAND_DDP_CHIP1 (1 << ONENAND_DDP_SHIFT) + +/* + * Start Buffer Register F200h (R/W) + */ +#define ONENAND_BSA_MASK (0x03) +#define ONENAND_BSA_SHIFT (8) +#define ONENAND_BSA_BOOTRAM (0 << 2) +#define ONENAND_BSA_DATARAM0 (2 << 2) +#define ONENAND_BSA_DATARAM1 (3 << 2) +#define ONENAND_BSC_MASK (0x03) + +/* + * Command Register F220h (R/W) + */ +#define ONENAND_CMD_READ (0x00) +#define ONENAND_CMD_READOOB (0x13) +#define ONENAND_CMD_PROG (0x80) +#define ONENAND_CMD_PROGOOB (0x1A) +#define ONENAND_CMD_UNLOCK (0x23) +#define ONENAND_CMD_LOCK (0x2A) +#define ONENAND_CMD_LOCK_TIGHT (0x2C) +#define ONENAND_CMD_UNLOCK_ALL (0x27) +#define ONENAND_CMD_ERASE (0x94) +#define ONENAND_CMD_RESET (0xF0) +#define ONENAND_CMD_OTP_ACCESS (0x65) +#define ONENAND_CMD_READID (0x90) +#define ONENAND_CMD_STARTADDR1 (0xE0) +#define ONENAND_CMD_WP_STATUS (0xE1) +#define ONENAND_CMD_PIPELINE_READ (0x01) +#define ONENAND_CMD_PIPELINE_WRITE (0x81) + +/* + * Command Mapping for S3C6400 OneNAND Controller + */ +#define ONENAND_AHB_ADDR (0x20000000) +#define ONENAND_DUMMY_ADDR (0x20400000) +#define ONENAND_CMD_SHIFT (24) +#define ONENAND_CMD_MAP_00 (0x0) +#define ONENAND_CMD_MAP_01 (0x1) +#define ONENAND_CMD_MAP_10 (0x2) +#define ONENAND_CMD_MAP_11 (0x3) +#define ONENAND_CMD_MAP_FF (0xF) + +/* + * Mask for Mapping table + */ +#define ONENAND_MEM_ADDR_MASK (0xffffff) +#define ONENAND_DDP_SHIFT_1Gb (21) +#define ONENAND_DDP_SHIFT_2Gb (22) +#define ONENAND_DDP_SHIFT_4Gb (23) +#define ONENAND_FBA_SHIFT (12) +#define ONENAND_FPA_SHIFT (6) +#define ONENAND_FSA_SHIFT (4) +#define ONENAND_FBA_MASK_128Mb (0xff) +#define ONENAND_FBA_MASK_256Mb (0x1ff) +#define ONENAND_FBA_MASK_512Mb (0x1ff) +#define ONENAND_FBA_MASK_1Gb_DDP (0x1ff) +#define ONENAND_FBA_MASK_1Gb (0x3ff) +#define ONENAND_FBA_MASK_2Gb_DDP (0x3ff) +#define ONENAND_FBA_MASK_2Gb (0x7ff) +#define ONENAND_FBA_MASK_4Gb_DDP (0x7ff) +#define ONENAND_FBA_MASK_4Gb (0xfff) +#define ONENAND_FPA_MASK (0x3f) +#define ONENAND_FSA_MASK (0x3) + +/* + * System Configuration 1 Register F221h (R, R/W) + */ +#define ONENAND_SYS_CFG1_SYNC_READ (1 << 15) +#define ONENAND_SYS_CFG1_BRL_7 (7 << 12) +#define ONENAND_SYS_CFG1_BRL_6 (6 << 12) +#define ONENAND_SYS_CFG1_BRL_5 (5 << 12) +#define ONENAND_SYS_CFG1_BRL_4 (4 << 12) +#define ONENAND_SYS_CFG1_BRL_3 (3 << 12) +#define ONENAND_SYS_CFG1_BRL_10 (2 << 12) +#define ONENAND_SYS_CFG1_BRL_9 (1 << 12) +#define ONENAND_SYS_CFG1_BRL_8 (0 << 12) +#define ONENAND_SYS_CFG1_BRL_SHIFT (12) +#define ONENAND_SYS_CFG1_BL_32 (4 << 9) +#define ONENAND_SYS_CFG1_BL_16 (3 << 9) +#define ONENAND_SYS_CFG1_BL_8 (2 << 9) +#define ONENAND_SYS_CFG1_BL_4 (1 << 9) +#define ONENAND_SYS_CFG1_BL_CONT (0 << 9) +#define ONENAND_SYS_CFG1_BL_SHIFT (9) +#define ONENAND_SYS_CFG1_NO_ECC (1 << 8) +#define ONENAND_SYS_CFG1_RDY (1 << 7) +#define ONENAND_SYS_CFG1_INT (1 << 6) +#define ONENAND_SYS_CFG1_IOBE (1 << 5) +#define ONENAND_SYS_CFG1_RDY_CONF (1 << 4) + +/* + * Controller Status Register F240h (R) + */ +#define ONENAND_CTRL_ONGO (1 << 15) +#define ONENAND_CTRL_LOCK (1 << 14) +#define ONENAND_CTRL_LOAD (1 << 13) +#define ONENAND_CTRL_PROGRAM (1 << 12) +#define ONENAND_CTRL_ERASE (1 << 11) +#define ONENAND_CTRL_ERROR (1 << 10) +#define ONENAND_CTRL_RSTB (1 << 7) +#define ONENAND_CTRL_OTP_L (1 << 6) +#define ONENAND_CTRL_OTP_BL (1 << 5) + +/* + * Interrupt Status Register F241h (R) + */ +#define ONENAND_INT_MASTER (1 << 15) +#define ONENAND_INT_READ (1 << 7) +#define ONENAND_INT_WRITE (1 << 6) +#define ONENAND_INT_ERASE (1 << 5) +#define ONENAND_INT_RESET (1 << 4) +#define ONENAND_INT_CLEAR (0 << 0) + +/* + * NAND Flash Write Protection Status Register F24Eh (R) + */ +#define ONENAND_WP_US (1 << 2) +#define ONENAND_WP_LS (1 << 1) +#define ONENAND_WP_LTS (1 << 0) + +/* + * ECC Status Register FF00h (R) + */ +#define ONENAND_ECC_1BIT (1 << 0) +#define ONENAND_ECC_1BIT_ALL (0x5555) +#define ONENAND_ECC_2BIT (1 << 1) +#define ONENAND_ECC_2BIT_ALL (0xAAAA) + +/* + * One-Time Programmable (OTP) + */ +#define ONENAND_OTP_LOCK_OFFSET (14) + +/************************************************************* + * End of OneNAND Controller + *************************************************************/ + + +/* + * Interrupt + */ +#define ELFIN_VIC0_BASE_ADDR (0x71200000) +#define ELFIN_VIC1_BASE_ADDR (0x71300000) +#define oINTMOD (0x0C) // VIC INT SELECT (IRQ or FIQ) +#define oINTUNMSK (0x10) // VIC INT EN (Unmask by writing 1) +#define oINTMSK (0x14) // VIC INT EN CLEAR (Mask by writing 1) +#define oINTSUBMSK (0x1C) // VIC SOFT INT CLEAR +#define oVECTADDR (0xF00) // VIC ADDRESS + + + +/* + * Watchdog timer + */ +#define ELFIN_WATCHDOG_BASE 0x7E004000 + +#define WTCON_REG __REG(0x7E004004) +#define WTDAT_REG __REG(0x7E004008) +#define WTCNT_REG __REG(0x7E00400C) + + + +/* + * UART + */ +#define ELFIN_UART_BASE 0x7F005000 + +#define ELFIN_UART0_OFFSET 0x0000 +#define ELFIN_UART1_OFFSET 0x0400 +#define ELFIN_UART2_OFFSET 0x0800 + +#ifdef CONFIG_SERIAL1 +#define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART0_OFFSET) +#elif defined(CONFIG_SERIAL2) +#define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART1_OFFSET) +#else +#define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART0_OFFSET) +#endif + +#define ULCON_OFFSET 0x00 +#define UCON_OFFSET 0x04 +#define UFCON_OFFSET 0x08 +#define UMCON_OFFSET 0x0C +#define UTRSTAT_OFFSET 0x10 +#define UERSTAT_OFFSET 0x14 +#define UFSTAT_OFFSET 0x18 +#define UMSTAT_OFFSET 0x1C +#define UTXH_OFFSET 0x20 +#define URXH_OFFSET 0x24 +#define UBRDIV_OFFSET 0x28 +#define UDIVSLOT_OFFSET 0x2C +#define UINTP_OFFSET 0x30 +#define UINTSP_OFFSET 0x34 +#define UINTM_OFFSET 0x38 + +#define ULCON0_REG __REG(0x7F005000) +#define UCON0_REG __REG(0x7F005004) +#define UFCON0_REG __REG(0x7F005008) +#define UMCON0_REG __REG(0x7F00500C) +#define UTRSTAT0_REG __REG(0x7F005010) +#define UERSTAT0_REG __REG(0x7F005014) +#define UFSTAT0_REG __REG(0x7F005018) +#define UMSTAT0_REG __REG(0x7F00501c) +#define UTXH0_REG __REG(0x7F005020) +#define URXH0_REG __REG(0x7F005024) +#define UBRDIV0_REG __REG(0x7F005028) +#define UDIVSLOT0_REG __REG(0x7F00502c) +#define UINTP0_REG __REG(0x7F005030) +#define UINTSP0_REG __REG(0x7F005034) +#define UINTM0_REG __REG(0x7F005038) + +#define ULCON1_REG __REG(0x7F005400) +#define UCON1_REG __REG(0x7F005404) +#define UFCON1_REG __REG(0x7F005408) +#define UMCON1_REG __REG(0x7F00540C) +#define UTRSTAT1_REG __REG(0x7F005410) +#define UERSTAT1_REG __REG(0x7F005414) +#define UFSTAT1_REG __REG(0x7F005418) +#define UMSTAT1_REG __REG(0x7F00541c) +#define UTXH1_REG __REG(0x7F005420) +#define URXH1_REG __REG(0x7F005424) +#define UBRDIV1_REG __REG(0x7F005428) +#define UDIVSLOT1_REG __REG(0x7F00542c) +#define UINTP1_REG __REG(0x7F005430) +#define UINTSP1_REG __REG(0x7F005434) +#define UINTM1_REG __REG(0x7F005438) + +#define UTRSTAT_TX_EMPTY BIT2 +#define UTRSTAT_RX_READY BIT0 +#define UART_ERR_MASK 0xF + + +/* + * PWM timer + */ +#define ELFIN_TIMER_BASE 0x7F006000 + +#define TCFG0_REG __REG(0x7F006000) +#define TCFG1_REG __REG(0x7F006004) +#define TCON_REG __REG(0x7F006008) +#define TCNTB0_REG __REG(0x7F00600c) +#define TCMPB0_REG __REG(0x7F006010) +#define TCNTO0_REG __REG(0x7F006014) +#define TCNTB1_REG __REG(0x7F006018) +#define TCMPB1_REG __REG(0x7F00601c) +#define TCNTO1_REG __REG(0x7F006020) +#define TCNTB2_REG __REG(0x7F006024) +#define TCMPB2_REG __REG(0x7F006028) +#define TCNTO2_REG __REG(0x7F00602c) +#define TCNTB3_REG __REG(0x7F006030) +#define TCMPB3_REG __REG(0x7F006034) +#define TCNTO3_REG __REG(0x7F006038) +#define TCNTB4_REG __REG(0x7F00603c) +#define TCNTO4_REG __REG(0x7F006040) + +/* Fields */ +#define fTCFG0_DZONE Fld(8,16) /* the dead zone length (= timer 0) */ +#define fTCFG0_PRE1 Fld(8,8) /* prescaler value for time 2,3,4 */ +#define fTCFG0_PRE0 Fld(8,0) /* prescaler value for time 0,1 */ +#define fTCFG1_MUX4 Fld(4,16) +/* bits */ +#define TCFG0_DZONE(x) FInsrt((x), fTCFG0_DZONE) +#define TCFG0_PRE1(x) FInsrt((x), fTCFG0_PRE1) +#define TCFG0_PRE0(x) FInsrt((x), fTCFG0_PRE0) +#define TCON_4_AUTO (1 << 22) /* auto reload on/off for Timer 4 */ +#define TCON_4_UPDATE (1 << 21) /* manual Update TCNTB4 */ +#define TCON_4_ONOFF (1 << 20) /* 0: Stop, 1: start Timer 4 */ +#define COUNT_4_ON (TCON_4_ONOFF*1) +#define COUNT_4_OFF (TCON_4_ONOFF*0) +#define TCON_3_AUTO (1 << 19) /* auto reload on/off for Timer 3 */ +#define TIMER3_ATLOAD_ON (TCON_3_AUTO*1) +#define TIMER3_ATLAOD_OFF FClrBit(TCON, TCON_3_AUTO) +#define TCON_3_INVERT (1 << 18) /* 1: Inverter on for TOUT3 */ +#define TIMER3_IVT_ON (TCON_3_INVERT*1) +#define TIMER3_IVT_OFF (FClrBit(TCON, TCON_3_INVERT)) +#define TCON_3_MAN (1 << 17) /* manual Update TCNTB3,TCMPB3 */ +#define TIMER3_MANUP (TCON_3_MAN*1) +#define TIMER3_NOP (FClrBit(TCON, TCON_3_MAN)) +#define TCON_3_ONOFF (1 << 16) /* 0: Stop, 1: start Timer 3 */ +#define TIMER3_ON (TCON_3_ONOFF*1) +#define TIMER3_OFF (FClrBit(TCON, TCON_3_ONOFF)) +/* macros */ +#define GET_PRESCALE_TIMER4(x) FExtr((x), fTCFG0_PRE1) +#define GET_DIVIDER_TIMER4(x) FExtr((x), fTCFG1_MUX4) + +/* + * RTC Controller + */ +#define ELFIN_RTC_BASE 0x7e005000 + +#define RTCCON_REG __REG(0x7e005040) +#define TICNT_REG __REG(0x7e005044) +#define RTCALM_REG __REG(0x7e005050) +#define ALMSEC_REG __REG(0x7e005054) +#define ALMMIN_REG __REG(0x7e005058) +#define ALMHOUR_REG __REG(0x7e00505c) +#define ALMDATE_REG __REG(0x7e005060) +#define ALMMON_REG __REG(0x7e005064) +#define ALMYEAR_REG __REG(0x7e005068) +#define BCDSEC_REG __REG(0x7e005070) +#define BCDMIN_REG __REG(0x7e005074) +#define BCDHOUR_REG __REG(0x7e005078) +#define BCDDATE_REG __REG(0x7e00507c) +#define BCDDAY_REG __REG(0x7e005080) +#define BCDMON_REG __REG(0x7e005084) +#define BCDYEAR_REG __REG(0x7e005088) + +/* + * USB2.0 HS OTG (Chapter 26) + */ +#define USBOTG_LINK_BASE (0x7C000000) +#define USBOTG_PHY_BASE (0x7C100000) + +/* Core Global Registers */ +#define S3C_OTG_GOTGCTL (USBOTG_LINK_BASE + 0x000) /* OTG Control & Status */ +#define S3C_OTG_GOTGINT (USBOTG_LINK_BASE + 0x004) /* OTG Interrupt */ +#define S3C_OTG_GAHBCFG (USBOTG_LINK_BASE + 0x008) /* Core AHB Configuration */ +#define S3C_OTG_GUSBCFG (USBOTG_LINK_BASE + 0x00C) /* Core USB Configuration */ +#define S3C_OTG_GRSTCTL (USBOTG_LINK_BASE + 0x010) /* Core Reset */ +#define S3C_OTG_GINTSTS (USBOTG_LINK_BASE + 0x014) /* Core Interrupt */ +#define S3C_OTG_GINTMSK (USBOTG_LINK_BASE + 0x018) /* Core Interrupt Mask */ +#define S3C_OTG_GRXSTSR (USBOTG_LINK_BASE + 0x01C) /* Receive Status Debug Read/Status Read */ +#define S3C_OTG_GRXSTSP (USBOTG_LINK_BASE + 0x020) /* Receive Status Debug Pop/Status Pop */ +#define S3C_OTG_GRXFSIZ (USBOTG_LINK_BASE + 0x024) /* Receive FIFO Size */ +#define S3C_OTG_GNPTXFSIZ (USBOTG_LINK_BASE + 0x028) /* Non-Periodic Transmit FIFO Size */ +#define S3C_OTG_GNPTXSTS (USBOTG_LINK_BASE + 0x02C) /* Non-Periodic Transmit FIFO/Queue Status */ + +#define S3C_OTG_HPTXFSIZ (USBOTG_LINK_BASE + 0x100) /* Host Periodic Transmit FIFO Size */ +#define S3C_OTG_DPTXFSIZ1 (USBOTG_LINK_BASE + 0x104) /* Device Periodic Transmit FIFO-1 Size */ +#define S3C_OTG_DPTXFSIZ2 (USBOTG_LINK_BASE + 0x108) /* Device Periodic Transmit FIFO-2 Size */ +#define S3C_OTG_DPTXFSIZ3 (USBOTG_LINK_BASE + 0x10C) /* Device Periodic Transmit FIFO-3 Size */ +#define S3C_OTG_DPTXFSIZ4 (USBOTG_LINK_BASE + 0x110) /* Device Periodic Transmit FIFO-4 Size */ +#define S3C_OTG_DPTXFSIZ5 (USBOTG_LINK_BASE + 0x114) /* Device Periodic Transmit FIFO-5 Size */ +#define S3C_OTG_DPTXFSIZ6 (USBOTG_LINK_BASE + 0x118) /* Device Periodic Transmit FIFO-6 Size */ +#define S3C_OTG_DPTXFSIZ7 (USBOTG_LINK_BASE + 0x11C) /* Device Periodic Transmit FIFO-7 Size */ +#define S3C_OTG_DPTXFSIZ8 (USBOTG_LINK_BASE + 0x120) /* Device Periodic Transmit FIFO-8 Size */ +#define S3C_OTG_DPTXFSIZ9 (USBOTG_LINK_BASE + 0x124) /* Device Periodic Transmit FIFO-9 Size */ +#define S3C_OTG_DPTXFSIZ10 (USBOTG_LINK_BASE + 0x128) /* Device Periodic Transmit FIFO-10 Size */ +#define S3C_OTG_DPTXFSIZ11 (USBOTG_LINK_BASE + 0x12C) /* Device Periodic Transmit FIFO-11 Size */ +#define S3C_OTG_DPTXFSIZ12 (USBOTG_LINK_BASE + 0x130) /* Device Periodic Transmit FIFO-12 Size */ +#define S3C_OTG_DPTXFSIZ13 (USBOTG_LINK_BASE + 0x134) /* Device Periodic Transmit FIFO-13 Size */ +#define S3C_OTG_DPTXFSIZ14 (USBOTG_LINK_BASE + 0x138) /* Device Periodic Transmit FIFO-14 Size */ +#define S3C_OTG_DPTXFSIZ15 (USBOTG_LINK_BASE + 0x13C) /* Device Periodic Transmit FIFO-15 Size */ + +/* Host Global Registers */ +#define S3C_OTG_HCFG (USBOTG_LINK_BASE + 0x400) /* Host Configuration */ +#define S3C_OTG_HFIR (USBOTG_LINK_BASE + 0x404) /* Host Frame Interval */ +#define S3C_OTG_HFNUM (USBOTG_LINK_BASE + 0x408) /* Host Frame Number/Frame Time Remaining */ +#define S3C_OTG_HPTXSTS (USBOTG_LINK_BASE + 0x410) /* Host Periodic Transmit FIFO/Queue Status */ +#define S3C_OTG_HAINT (USBOTG_LINK_BASE + 0x414) /* Host All Channels Interrupt */ +#define S3C_OTG_HAINTMSK (USBOTG_LINK_BASE + 0x418) /* Host All Channels Interrupt Mask */ + +/* Host Port Control & Status Registers */ +#define S3C_OTG_HPRT (USBOTG_LINK_BASE + 0x440) /* Host Port Control & Status */ + +/* Host Channel-Specific Registers */ +#define S3C_OTG_HCCHAR0 (USBOTG_LINK_BASE + 0x500) /* Host Channel-0 Characteristics */ +#define S3C_OTG_HCSPLT0 (USBOTG_LINK_BASE + 0x504) /* Host Channel-0 Split Control */ +#define S3C_OTG_HCINT0 (USBOTG_LINK_BASE + 0x508) /* Host Channel-0 Interrupt */ +#define S3C_OTG_HCINTMSK0 (USBOTG_LINK_BASE + 0x50C) /* Host Channel-0 Interrupt Mask */ +#define S3C_OTG_HCTSIZ0 (USBOTG_LINK_BASE + 0x510) /* Host Channel-0 Transfer Size */ +#define S3C_OTG_HCDMA0 (USBOTG_LINK_BASE + 0x514) /* Host Channel-0 DMA Address */ + + +/* Device Global Registers */ +#define S3C_OTG_DCFG (USBOTG_LINK_BASE + 0x800) /* Device Configuration */ +#define S3C_OTG_DCTL (USBOTG_LINK_BASE + 0x804) /* Device Control */ +#define S3C_OTG_DSTS (USBOTG_LINK_BASE + 0x808) /* Device Status */ +#define S3C_OTG_DIEPMSK (USBOTG_LINK_BASE + 0x810) /* Device IN Endpoint Common Interrupt Mask */ +#define S3C_OTG_DOEPMSK (USBOTG_LINK_BASE + 0x814) /* Device OUT Endpoint Common Interrupt Mask */ +#define S3C_OTG_DAINT (USBOTG_LINK_BASE + 0x818) /* Device All Endpoints Interrupt */ +#define S3C_OTG_DAINTMSK (USBOTG_LINK_BASE + 0x81C) /* Device All Endpoints Interrupt Mask */ +#define S3C_OTG_DTKNQR1 (USBOTG_LINK_BASE + 0x820) /* Device IN Token Sequence Learning Queue Read 1 */ +#define S3C_OTG_DTKNQR2 (USBOTG_LINK_BASE + 0x824) /* Device IN Token Sequence Learning Queue Read 2 */ +#define S3C_OTG_DVBUSDIS (USBOTG_LINK_BASE + 0x828) /* Device VBUS Discharge Time */ +#define S3C_OTG_DVBUSPULSE (USBOTG_LINK_BASE + 0x82C) /* Device VBUS Pulsing Time */ +#define S3C_OTG_DTKNQR3 (USBOTG_LINK_BASE + 0x830) /* Device IN Token Sequence Learning Queue Read 3 */ +#define S3C_OTG_DTKNQR4 (USBOTG_LINK_BASE + 0x834) /* Device IN Token Sequence Learning Queue Read 4 */ + +/* Device Logical IN Endpoint-Specific Registers */ +#define S3C_OTG_DIEPCTL0 (USBOTG_LINK_BASE + 0x900) /* Device IN Endpoint 0 Control */ +#define S3C_OTG_DIEPINT0 (USBOTG_LINK_BASE + 0x908) /* Device IN Endpoint 0 Interrupt */ +#define S3C_OTG_DIEPTSIZ0 (USBOTG_LINK_BASE + 0x910) /* Device IN Endpoint 0 Transfer Size */ +#define S3C_OTG_DIEPDMA0 (USBOTG_LINK_BASE + 0x914) /* Device IN Endpoint 0 DMA Address */ + +/* Device Logical OUT Endpoint-Specific Registers */ +#define S3C_OTG_DOEPCTL0 (USBOTG_LINK_BASE + 0xB00) /* Device OUT Endpoint 0 Control */ +#define S3C_OTG_DOEPINT0 (USBOTG_LINK_BASE + 0xB08) /* Device OUT Endpoint 0 Interrupt */ +#define S3C_OTG_DOEPTSIZ0 (USBOTG_LINK_BASE + 0xB10) /* Device OUT Endpoint 0 Transfer Size */ +#define S3C_OTG_DOEPDMA0 (USBOTG_LINK_BASE + 0xB14) /* Device OUT Endpoint 0 DMA Address */ + +/* Power & clock gating registers */ +#define S3C_OTG_PCGCCTRL (USBOTG_LINK_BASE + 0xE00) + +/* Endpoint FIFO address */ +#define S3C_OTG_EP0_FIFO (USBOTG_LINK_BASE + 0x1000) + + + +/* OTG PHY CORE REGISTERS */ +#define S3C_OTG_PHYPWR (USBOTG_PHY_BASE+0x00) +#define S3C_OTG_PHYCTRL (USBOTG_PHY_BASE+0x04) +#define S3C_OTG_RSTCON (USBOTG_PHY_BASE+0x08) + +/* include common stuff */ +#ifndef __ASSEMBLY__ +static inline S3C64XX_MEMCTL * S3C64XX_GetBase_MEMCTL(void) +{ + return (S3C64XX_MEMCTL *)(ELFIN_DMC0_BASE); +} +static inline S3C64XX_USB_HOST * S3C64XX_GetBase_USB_HOST(void) +{ + return (S3C64XX_USB_HOST *)ELFIN_USB_HOST_BASE; +} +static inline S3C64XX_INTERRUPT * S3C64XX_GetBase_INTERRUPT(void) +{ + return (S3C64XX_INTERRUPT *)ELFIN_VIC0_BASE_ADDR; +} +static inline S3C64XX_DMAS * S3C64XX_GetBase_DMAS(void) +{ + return (S3C64XX_DMAS *)ELFIN_DMA_BASE; +} +static inline S3C64XX_CLOCK_POWER * S3C64XX_GetBase_CLOCK_POWER(void) +{ + return (S3C64XX_CLOCK_POWER *)ELFIN_CLOCK_POWER_BASE; +} +static inline S3C64XX_LCD * S3C64XX_GetBase_LCD(void) +{ + return (S3C64XX_LCD *)ELFIN_LCD_BASE; +} +/* +static inline S3C2410_NAND * S3C2410_GetBase_NAND(void) +{ + return (S3C2410_NAND *)ELFIN_NAND_BASE; +} +*/ +static inline S3C64XX_UART * S3C64XX_GetBase_UART(S3C64XX_UARTS_NR nr) +{ +// return (S3C64XX_UART *)(ELFIN_UART_BASE + (nr * 0x4000)); + return (S3C64XX_UART *)(ELFIN_UART_BASE + (nr*0x400)); +} +static inline S3C64XX_TIMERS * S3C64XX_GetBase_TIMERS(void) +{ + return (S3C64XX_TIMERS *)ELFIN_TIMER_BASE; +} +/* +static inline S3C64XX_USB_DEVICE * S3C64XX_GetBase_USB_DEVICE(void) +{ + return (S3C64XX_USB_DEVICE *)ELFIN_USB_DEVICE_BASE; +} +*/ +static inline S3C64XX_WATCHDOG * S3C64XX_GetBase_WATCHDOG(void) +{ + return (S3C64XX_WATCHDOG *)ELFIN_WATCHDOG_BASE; +} +static inline S3C64XX_I2C * S3C64XX_GetBase_I2C(void) +{ + return (S3C64XX_I2C *)ELFIN_I2C_BASE; +} +static inline S3C64XX_I2S * S3C64XX_GetBase_I2S(void) +{ + return (S3C64XX_I2S *)ELFIN_I2S_BASE; +} +static inline S3C64XX_GPIO * S3C64XX_GetBase_GPIO(void) +{ + return (S3C64XX_GPIO *)ELFIN_GPIO_BASE; +} +static inline S3C64XX_RTC * S3C64XX_GetBase_RTC(void) +{ + return (S3C64XX_RTC *)ELFIN_RTC_BASE; +} +static inline S3C2410_ADC * S3C2410_GetBase_ADC(void) +{ + return (S3C2410_ADC *)ELFIN_ADC_BASE; +} +static inline S3C64XX_SPI * S3C64XX_GetBase_SPI(void) +{ + return (S3C64XX_SPI *)ELFIN_SPI_BASE; +} +#if 0 +static inline S3C2410_SDI * S3C2410_GetBase_SDI(void) +{ + return (S3C2410_SDI *)ELFIN_SDI_BASE; +} +#endif +#else /* #ifndef __ASSEMBLY__ */ + +/* watchdog */ +#define WTCON_OFFSET 0x00 + +/* LCD controller */ +#define LCDBGCON_OFFSET 0x5c + +#endif /* #ifndef __ASSEMBLY__ */ + +/* PENDING BIT */ +#define BIT_EINT0 (0x1) +#define BIT_EINT1 (0x1<<1) +#define BIT_EINT2 (0x1<<2) +#define BIT_EINT3 (0x1<<3) +#define BIT_EINT4_7 (0x1<<4) +#define BIT_EINT8_23 (0x1<<5) +#define BIT_BAT_FLT (0x1<<7) +#define BIT_TICK (0x1<<8) +#define BIT_WDT (0x1<<9) +#define BIT_TIMER0 (0x1<<10) +#define BIT_TIMER1 (0x1<<11) +#define BIT_TIMER2 (0x1<<12) +#define BIT_TIMER3 (0x1<<13) +#define BIT_TIMER4 (0x1<<14) +#define BIT_UART2 (0x1<<15) +#define BIT_LCD (0x1<<16) +#define BIT_DMA0 (0x1<<17) +#define BIT_DMA1 (0x1<<18) +#define BIT_DMA2 (0x1<<19) +#define BIT_DMA3 (0x1<<20) +#define BIT_SDI (0x1<<21) +#define BIT_SPI0 (0x1<<22) +#define BIT_UART1 (0x1<<23) +#define BIT_USBH (0x1<<26) +#define BIT_IIC (0x1<<27) +#define BIT_UART0 (0x1<<28) +#define BIT_SPI1 (0x1<<29) +#define BIT_RTC (0x1<<30) +#define BIT_ADC (0x1<<31) +#define BIT_ALLMSK (0xFFFFFFFF) + +#endif /*__S3C6410_H__*/ diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c new file mode 100644 index 0000000..1bda6bf --- /dev/null +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -0,0 +1,428 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: Andy Green + * + * (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 +#include +#include +#include +#include +#include +#include + +#define GTA02_DEBUG_UART 2 + +#define PCF50633_I2C_ADS 0x73 + +struct pcf50633_init { + u8 index; + u8 value; +}; + +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_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, 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_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, 0x19 }, /* 25/255 == 98mA soft-start usb fast */ + { PCF50633_REG_MBCC6, 0x00 }, /* cutoff current 1/32 * Ichg */ + { PCF50633_REG_MBCC7, 0x00 }, /* 1.6A max bat curr, USB 100mA */ + { 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 = "A5 PCB", + .machine_revision = 0x350, + }, + [1] = { + .name = "A6 PCB", + .machine_revision = 0x360, + } +}; + + +void port_init_gta02(void) +{ +#if 0 + unsigned int * MPLLCON = (unsigned int *)0x4c000004; + unsigned int * UPLLCON = (unsigned int *)0x4c000008; + unsigned int * CLKDIVN = (unsigned int *)0x4c000014; +#endif + int n; + + //CAUTION:Follow the configuration order for setting the ports. + // 1) setting value(GPnDAT) + // 2) setting control register (GPnCON) + // 3) configure pull-up 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 = 0x0000AAAA; + 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 + */ + /* pulldown on GPH08: UEXTCLK, just floats! + * pulldown GPH0 -- nCTS0 / RTS_MODEM -- floats when GSM off + * pulldown GPH3 -- RXD[0] / TX_MODEM -- floats when GSM off + */ + rGPHCON = 0x001AAAAA; + rGPHUP = 0x000007FF & ~(1 << 8) & ~(1 << 0) & ~(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); + +#if 0 + /* 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 PCLK */); +#else + serial_init_115200_s3c24xx(GTA02_DEBUG_UART, 33 /* 33MHz PCLK */); +#endif + + /* we're going to use Glamo for SD Card access, so we need to init the + * evil beast + */ + glamo_core_init(); +} + +/** + * 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 << (8 - 3)) & 0x100; + n |= (u << (9 - 4)) & 0x200; + + /* + * 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) +{ + return &board_variants[gta02_get_pcb_revision() & 1]; +} + +static 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)(); +} + +/* + * 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, + .putc = putc_gta02, + .close = close_gta02, + /* these are the ways we could boot GTA02 in order to try */ + .kernel_source = { + [0] = { + .name = "SD Card EXT2 Kernel", + .block_init = sd_card_init_gta02, + .block_read = sd_card_block_read_gta02, + .partition_index = 1, + .filesystem = FS_EXT2, + .filepath = "boot/uImage.bin", + .commandline = "mtdparts=physmap-flash:-(nor);" \ + "neo1973-nand:" \ + "0x00040000(qi)," \ + "0x00040000(cmdline)," \ + "0x00800000(backupkernel)," \ + "0x000a0000(extra)," \ + "0x00040000(identity)," \ + "0x0f6a0000(backuprootfs) " \ + "rootfstype=ext3 " \ + "root=/dev/mmcblk0p1 " \ + "console=ttySAC2,115200 " \ + "loglevel=8 " \ + "init=/sbin/init "\ + "ro" + }, + [1] = { + .name = "NAND Kernel", + .block_read = nand_read_ll, + .offset_blocks512_if_no_partition = 0x80000 / 512, + .filesystem = FS_RAW, + .commandline = "mtdparts=physmap-flash:-(nor);" \ + "neo1973-nand:" \ + "0x00040000(qi)," \ + "0x00040000(cmdline)," \ + "0x00800000(backupkernel)," \ + "0x000a0000(extra)," \ + "0x00040000(identity)," \ + "0x0f6a0000(backuprootfs) " \ + "rootfstype=jffs2 " \ + "root=/dev/mtdblock6 " \ + "console=ttySAC2,115200 " \ + "loglevel=3 " \ + "init=/sbin/init "\ + "ro" + }, + }, +}; diff --git a/qiboot/src/cpu/s3c2442/gta03.c b/qiboot/src/cpu/s3c2442/gta03.c new file mode 100644 index 0000000..73fa268 --- /dev/null +++ b/qiboot/src/cpu/s3c2442/gta03.c @@ -0,0 +1,289 @@ +#include +#include +#include +#include +#include +#include +#include + +#define GTA03_DEBUG_UART 2 + +#define PCF50633_I2C_ADS 0x73 + + +static const struct board_variant board_variants[] = { + [0] = { + .name = "EVB PCB", + .machine_revision = 0x010, + }, +}; + +void port_init_gta03(void) +{ + unsigned int * MPLLCON = (unsigned int *)0x4c000004; + unsigned int * UPLLCON = (unsigned int *)0x4c000008; + unsigned int * CLKDIVN = (unsigned int *)0x4c000014; + + //CAUTION:Follow the configuration order for setting the ports. + // 1) setting value(GPnDAT) + // 2) setting control register (GPnCON) + // 3) configure pull-up 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 = 0x007F8FFF; + /* + * ===* 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 = 0x00145554; + rGPBDAT |= (1 <<9 ); /* USB_PULLUP */ + rGPBUP = 0x000007FF; + /* + * === 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 = 0xAAA776E9; + rGPCUP = 0x0000FFFF; + rGPCDAT |= (1 << 9); /* WLAN_nRESET pull high */ + /* + * === 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 = 0xAAA0AAA5; + rGPDUP = 0x0000FFFF; + /* + * === 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; + /* + * === 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 + */ + rGPFCON = 0x0000AAAA; + rGPFUP = 0x000000FF; + + /* + * === 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 = 0x02A9FE5A; + rGPGUP = 0x0000FFFF; + + /* + * === 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 + */ + /* pulldown on GPH08: UEXTCLK, just floats! + * pulldown GPH0 -- nCTS0 / RTS_MODEM -- floats when GSM off + * pulldown GPH3 -- RXD[0] / TX_MODEM -- floats when GSM off + */ + rGPHCON = 0x0019A0AA; + rGPHUP = 0x000007FF; + + /* pulldown on GPJ00: input, just floats! */ + /* pulldown on GPJ07: WLAN module WLAN_GPIO0, no ext pull */ + rGPJCON = 0x02AAAAAA; + rGPJUP = 0x1FFFF; + + /* + * We have to talk to the PMU a little bit + */ + + /* We need SD Card rail (HCLDO) at 3.0V */ + i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_HCLDOOUT, + 21); + + /* switch HCLDO on */ + i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_HCLDOENA, 1); + + /* push DOWN1 (CPU Core rail) to 1.7V, allowing 533MHz */ + i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_DOWN1OUT, + 0x2b); + + /* change CPU clocking to 533MHz 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 = ((169 << 12) + (2 << 4) + 1); + + + serial_init_115200_s3c24xx(GTA03_DEBUG_UART, 66 /*MHz PCLK */); +} + +/** + * returns PCB revision information in b0, d8, d9 + * GTA03 EVB returns 0x000 + * GTA03 returns 0x001 + */ + +int gta03_get_pcb_revision(void) +{ + int n; + u32 u; + + /* make B0 inputs */ + rGPBCON &= ~0x00000003; + /* D8 and D9 inputs */ + rGPDCON &= ~0x000f0000; + + /* delay after changing pulldowns */ + u = rGPBDAT; + u = rGPDDAT; + + /* read the version info */ + u = rGPBDAT; + n = (u >> (0 - 0))& 0x001; + u = rGPDDAT; + n |= (u >> (8 -1)) & 0x002; + n |= (u >> (9 - 2)) & 0x004; + + /* + * when not being interrogated, all of the revision GPIO + * are set to output + */ + /* make B0 high ouput */ + rGPBCON |= 0x00000001; + /* D8 and D9 high ouputs */ + rGPDCON |= 0x00050000; + + return n; + +} + +const struct board_variant const * get_board_variant_gta03(void) +{ + return &board_variants[gta03_get_pcb_revision()]; +} + +int is_this_board_gta03(void) +{ + /* FIXME: find something gta03 specific */ + return 1; +} + +static void putc_gta03(char c) +{ + serial_putc_s3c24xx(GTA03_DEBUG_UART, c); +} + +int sd_card_init_gta03(void) +{ + return s3c24xx_mmc_init(1); +} + +int sd_card_block_read_gta03(unsigned char * buf, unsigned long start512, + int blocks512) +{ + return s3c24xx_mmc_bread(0, start512, blocks512, buf); +} + + + +/* + * our API for bootloader on this machine + */ +const struct board_api board_api_gta03 = { + .name = "GTA03-2442", + .linux_machine_id = 1866, + .linux_mem_start = 0x30000000, + .linux_mem_size = (128 * 1024 * 1024), + .linux_tag_placement = 0x30000000 + 0x100, + .get_board_variant = get_board_variant_gta03, + .is_this_board = is_this_board_gta03, + .port_init = port_init_gta03, + .putc = putc_gta03, + /* these are the ways we could boot GTA03 in order to try */ + .kernel_source = { + [0] = { + .name = "SD Card EXT2 Kernel", + .block_init = sd_card_init_gta03, + .block_read = sd_card_block_read_gta03, + .partition_index = 1, + .filesystem = FS_EXT2, + .filepath = "boot/uImage.bin", + .commandline = "mtdparts=physmap-flash:-(nor);" \ + "neo1973-nand:" \ + "0x00040000(qi)," \ + "0x00040000(cmdline)," \ + "0x00800000(backupkernel)," \ + "0x000a0000(extra)," \ + "0x00040000(identity)," \ + "0x0f6a0000(backuprootfs) " \ + "rootfstype=ext2 " \ + "root=/dev/mmcblk0p1 " \ + "console=ttySAC2,115200 " \ + "loglevel=4 " \ + "init=/sbin/init "\ + "ro" + }, + [1] = { + .name = "NAND Kernel", + .block_read = nand_read_ll, + .offset_blocks512_if_no_partition = 0x80000 / 512, + .filesystem = FS_RAW, + .commandline = "mtdparts=neo1973-nand:" \ + "0x00040000(qi)," \ + "0x00040000(cmdline)," \ + "0x00800000(backupkernel)," \ + "0x000a0000(extra)," \ + "0x00040000(identity)," \ + "0x0f6a0000(backuprootfs) " \ + "rootfstype=jffs2 " \ + "root=/dev/mtdblock6 " \ + "console=ttySAC2,115200 " \ + "loglevel=4 " \ + "init=/sbin/init "\ + "ro" + }, + }, +}; diff --git a/qiboot/src/cpu/s3c2442/nand_read.c b/qiboot/src/cpu/s3c2442/nand_read.c new file mode 100644 index 0000000..cb2a2de --- /dev/null +++ b/qiboot/src/cpu/s3c2442/nand_read.c @@ -0,0 +1,153 @@ +/* + * 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 + * Date : $Date: 2004/02/04 10:37:37 $ + * + * u-boot integration and bad-block skipping (C) 2006 by OpenMoko, Inc. + * Author: Harald Welte + */ + +/* NOTE this stuff runs in steppingstone context! */ + +/* the API refers to 512-byte blocks */ + +#include +#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) + +static int is_bad_block(unsigned long block_index) +{ + unsigned char data; + unsigned long page_num; + + 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) +{ + unsigned short *ptr16 = (unsigned short *)buf; + unsigned int i, page_num; +#if 0 + unsigned char ecc[64]; + unsigned short *p16 = (unsigned short *)ecc; +#endif + + nand_clear_RnB(); + + NFCMD = NAND_CMD_READ0; + + page_num = block512 >> 2; /* 512 block -> 2048 block */ + /* Write Address */ + NFADDR = 0; + NFADDR = 0; + NFADDR = page_num & 0xff; + NFADDR = (page_num >> 8) & 0xff; + NFADDR = (page_num >> 16) & 0xff; + NFCMD = NAND_CMD_READSTART; + nand_wait(); + + for (i = 0; i < NAND_PAGE_SIZE/2; i++) + *ptr16++ = NFDATA16; +#if 0 + for (i = 0; i < 64 / 2; i++) { + *p16++ = NFDATA16; + } +#endif + return 4; +} + +/* 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; + + if (start_block512 & 3) /* inside 2048-byte block */ + return -1; + + /* 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 + 4)) { + start_block512 += 4; + blocks512 += 4; + 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; +} + diff --git a/qiboot/src/cpu/s3c2442/nand_read.h b/qiboot/src/cpu/s3c2442/nand_read.h new file mode 100644 index 0000000..71aeda5 --- /dev/null +++ b/qiboot/src/cpu/s3c2442/nand_read.h @@ -0,0 +1,22 @@ +/* + * 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 + * Date : $Date: 2004/02/04 10:37:37 $ + * + * u-boot integration and bad-block skipping (C) 2006 by OpenMoko, Inc. + * Author: Harald Welte + */ +#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 */ diff --git a/qiboot/src/cpu/s3c2442/qi.lds b/qiboot/src/cpu/s3c2442/qi.lds new file mode 100644 index 0000000..504b130 --- /dev/null +++ b/qiboot/src/cpu/s3c2442/qi.lds @@ -0,0 +1,60 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * 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/s3c2442/start.o (.text .rodata* .data) + src/lowlevel_init.o (.text .rodata* .data) + src/cpu/s3c2442/start_qi.o (.text .rodata* .data) + src/blink_led.o (.text .rodata* .data) + src/cpu/s3c2442/nand_read.o (.text .rodata* .data) + src/drivers/serial-s3c24xx.o (.text .rodata* .data) + } + + . = ALIGN(4); + .everything_else ADDR (.text) + SIZEOF (.text) + 0x33000000 : + AT ( ADDR (.text) + SIZEOF (.text) ) { *(.text .rodata* .data) } + + . = 0x33800000 ; + __bss_start = .; + .bss (NOLOAD) : + { + *(.bss) + } + + _end = .; +} diff --git a/qiboot/src/cpu/s3c2442/start.S b/qiboot/src/cpu/s3c2442/start.S new file mode 100644 index 0000000..9961d8f --- /dev/null +++ b/qiboot/src/cpu/s3c2442/start.S @@ -0,0 +1,311 @@ +/* + * (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 + +#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 + +processor_id: + .word 0 + .word 0x41129200 /* s3c2442 ID */ + .word 0x410fb760 /* s3c6410 ID */ + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +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, #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 + diff --git a/qiboot/src/cpu/s3c2442/start_qi.c b/qiboot/src/cpu/s3c2442/start_qi.c new file mode 100644 index 0000000..ff479b6 --- /dev/null +++ b/qiboot/src/cpu/s3c2442/start_qi.c @@ -0,0 +1,106 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: xiangfu liu + * Andy Green + * + * 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 +#include "nand_read.h" +#include +#include + +extern void bootloader_second_phase(void); + +const struct board_api *boards[] = { + &board_api_gta02, + &board_api_gta03, + 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++]; + } + + /* + * jump to bootloader_second_phase() running from DRAM copy + */ + bootloader_second_phase(); + +unhappy: + while(1) + ; + +} diff --git a/qiboot/src/cpu/s3c6410/qi.lds b/qiboot/src/cpu/s3c6410/qi.lds new file mode 100644 index 0000000..14051a4 --- /dev/null +++ b/qiboot/src/cpu/s3c6410/qi.lds @@ -0,0 +1,57 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * 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/s3c6410/start.o (.text .rodata* .data) + src/lowlevel_init.o (.text .rodata* .data) + src/cpu/s3c6410/start_qi.o (.text .rodata* .data) + src/blink_led.o (.text .rodata* .data) + } + + . = ALIGN(4); + .everything_else ADDR (.text) + SIZEOF (.text) + 0x53000000 : + AT ( ADDR (.text) + SIZEOF (.text) ) { *(.text .rodata* .data) } + + . = 0x53800000 ; + __bss_start = .; + .bss_6410 (NOLOAD) : + { + * (.bss) + } + _end = .; +} diff --git a/qiboot/src/cpu/s3c6410/start.S b/qiboot/src/cpu/s3c6410/start.S new file mode 100644 index 0000000..7cb429e --- /dev/null +++ b/qiboot/src/cpu/s3c6410/start.S @@ -0,0 +1,548 @@ +/* + * (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 + +#define TEXT_BASE 0x53000000 + + +#define S3C6410_POP_A 0 + +#define set_pll(mdiv, pdiv, sdiv) (1<<31 | mdiv<<16 | pdiv<<8 | sdiv) + +/* fixed MPLL 533MHz */ +#define MPLL_MDIV 266 +#define MPLL_PDIV 3 +#define MPLL_SDIV 1 + +#define Startup_APLLdiv 0 +#define APLL_MDIV 266 +#define APLL_PDIV 3 +#define APLL_SDIV 1 +#define Startup_PCLKdiv 3 +#define Startup_HCLKdiv 1 +#define Startup_MPLLdiv 1 +#define Startup_HCLKx2div 1 +#define Startup_APLL (12000000/(APLL_PDIV< EXT_UCLK1*/ + + str r1, [r0, #UCON_OFFSET] + + ldr r1, =0x22 + str r1, [r0, #UBRDIV_OFFSET] + + ldr r1, =0x1FFF + str r1, [r0, #UDIVSLOT_OFFSET] + + ldr r1, =0x4f4f4f4f + str r1, [r0, #UTXH_OFFSET] @'O' + + /* send out a char to say hello */ + ldr r1, =0x55 + str r1, [r0, #UTXH_OFFSET] + + +#if 0 +/* Below code is for ARM926EJS and ARM1026EJS */ + .globl cleanDCache +cleanDCache: + mrc p15, 0, pc, c7, c10, 3 /* test/clean D-Cache */ + bne cleanDCache + mov pc, lr + + .globl cleanFlushDCache +cleanFlushDCache: + mrc p15, 0, pc, c7, c14, 3 /* test/cleanflush D-Cache */ + bne cleanFlushDCache + mov pc, lr + + .globl cleanFlushCache +cleanFlushCache: + mrc p15, 0, pc, c7, c14, 3 /* test/cleanflush D-Cache */ + bne cleanFlushCache + mcr p15, 0, r0, c7, c5, 0 /* flush I-Cache */ + mov pc, lr + + .ltorg +#endif + +#if 0 + + /* 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] + + + + /* 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] + +#endif + + /* >> 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 diff --git a/qiboot/src/cpu/s3c6410/start_qi.c b/qiboot/src/cpu/s3c6410/start_qi.c new file mode 100644 index 0000000..ca419ee --- /dev/null +++ b/qiboot/src/cpu/s3c6410/start_qi.c @@ -0,0 +1,105 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: xiangfu liu + * Andy Green + * + * 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 +#include + +extern void bootloader_second_phase(void); + +const struct board_api *boards[] = { + &board_api_tla01, + 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 */ + /* FIXME this ain't right for s3c6410 */ +#if 0 + if (nand_read_ll((u8 *)TEXT_BASE, 0, 32 * 1024 / 512) < 0) + goto unhappy; +#endif + + /* 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++]; + } + + /* + * jump to bootloader_second_phase() running from DRAM copy + */ + bootloader_second_phase(); +#if 0 +unhappy: + while(1) + ; +#endif +} diff --git a/qiboot/src/cpu/s3c6410/tla01.c b/qiboot/src/cpu/s3c6410/tla01.c new file mode 100644 index 0000000..2269d09 --- /dev/null +++ b/qiboot/src/cpu/s3c6410/tla01.c @@ -0,0 +1,246 @@ +#include +#include +#include +#include +#include +#include + +#define GTA03_DEBUG_UART 2 + +#define PCF50633_I2C_ADS 0x73 + + +static const struct board_variant board_variants[] = { + [0] = { + .name = "TLA01", + .machine_revision = 0x010, + }, +}; + +void port_init_tla01(void) +{ + unsigned int * MPLLCON = (unsigned int *)0x4c000004; + unsigned int * UPLLCON = (unsigned int *)0x4c000008; + unsigned int * CLKDIVN = (unsigned int *)0x4c000014; + + //CAUTION:Follow the configuration order for setting the ports. + // 1) setting value(GPnDAT) + // 2) setting control register (GPnCON) + // 3) configure pull-up 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 = 0x007F8FFF; + /* + * ===* 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 = 0x00145554; + rGPBDAT |= (1 <<9 ); /* USB_PULLUP */ + rGPBUP = 0x000007FF; + /* + * === 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 = 0xAAA776E9; + rGPCUP = 0x0000FFFF; + rGPCDAT |= (1 << 9); /* WLAN_nRESET pull high */ + /* + * === 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 = 0xAAA0AAA5; + rGPDUP = 0x0000FFFF; + /* + * === 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; + /* + * === 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 + */ + rGPFCON = 0x0000AAAA; + rGPFUP = 0x000000FF; + + /* + * === 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 = 0x02A9FE5A; + rGPGUP = 0x0000FFFF; + + /* + * === 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 + */ + /* pulldown on GPH08: UEXTCLK, just floats! + * pulldown GPH0 -- nCTS0 / RTS_MODEM -- floats when GSM off + * pulldown GPH3 -- RXD[0] / TX_MODEM -- floats when GSM off + */ + rGPHCON = 0x0019A0AA; + rGPHUP = 0x000007FF; + + /* pulldown on GPJ00: input, just floats! */ + /* pulldown on GPJ07: WLAN module WLAN_GPIO0, no ext pull */ + rGPJCON = 0x02AAAAAA; + rGPJUP = 0x1FFFF; + + /* + * We have to talk to the PMU a little bit + */ + + /* We need SD Card rail (HCLDO) at 3.0V */ + i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_HCLDOOUT, + 21); + + /* switch HCLDO on */ + i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_HCLDOENA, 1); + + /* push DOWN1 (CPU Core rail) to 1.7V, allowing 533MHz */ + i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_DOWN1OUT, + 0x2b); + + /* change CPU clocking to 533MHz 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 = ((169 << 12) + (2 << 4) + 1); + + + serial_init_115200_s3c24xx(GTA03_DEBUG_UART, 66 /*MHz PCLK */); +} + +/** + * returns PCB revision information in b0, d8, d9 + * GTA03 EVB returns 0x000 + * GTA03 returns 0x001 + */ + +int tla01_get_pcb_revision(void) +{ + int n; + u32 u; + + /* make B0 inputs */ + rGPBCON &= ~0x00000003; + /* D8 and D9 inputs */ + rGPDCON &= ~0x000f0000; + + /* delay after changing pulldowns */ + u = rGPBDAT; + u = rGPDDAT; + + /* read the version info */ + u = rGPBDAT; + n = (u >> (0 - 0))& 0x001; + u = rGPDDAT; + n |= (u >> (8 -1)) & 0x002; + n |= (u >> (9 - 2)) & 0x004; + + /* + * when not being interrogated, all of the revision GPIO + * are set to output + */ + /* make B0 high ouput */ + rGPBCON |= 0x00000001; + /* D8 and D9 high ouputs */ + rGPDCON |= 0x00050000; + + return n; + +} + +const struct board_variant const * get_board_variant_tla01(void) +{ + return &board_variants[tla01_get_pcb_revision()]; +} + +int is_this_board_tla01(void) +{ + /* FIXME: find something tla01 specific */ + return 1; +} + +static void putc_tla01(char c) +{ + serial_putc_s3c24xx(GTA03_DEBUG_UART, c); +} + + +/* + * our API for bootloader on this machine + */ +const struct board_api board_api_tla01 = { + .name = "TLA01", + .linux_machine_id = 1866, + .linux_mem_start = 0x30000000, + .linux_mem_size = (128 * 1024 * 1024), + .linux_tag_placement = 0x30000000 + 0x100, + .get_board_variant = get_board_variant_tla01, + .is_this_board = is_this_board_tla01, + .port_init = port_init_tla01, + .putc = putc_tla01, + .kernel_source = { + [0] = { + .name = "SD Card", + .block_read = NULL, /* FIXME It's s3c6400 sd card*/ + .offset_blocks512_if_no_partition = 0x80000 / 512, + .filesystem = FS_RAW, + .commandline = "rootfstype=ext3 " \ + "root=/dev/mmcblk0p1 " \ + "console=ttySAC2,115200 " \ + "loglevel=4 " \ + "init=/sbin/init "\ + "ro" + }, + }, +}; From 007a6b20a78c4f3b188a6bbc6f57c6df47f3b23a Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:40 +0000 Subject: [PATCH 100/248] qi-build-create-image-dir.patch Signed-off-by: Andy Green --- qiboot/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/qiboot/Makefile b/qiboot/Makefile index b43e958..ad99a3f 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -69,6 +69,7 @@ ${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} \ From 24a263998c83229a51a42a7a407e62fd6c29e3bf Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:40 +0000 Subject: [PATCH 101/248] qi-move-cpu-specific-drivers-into-cpu-dir.patch Signed-off-by: Andy Green --- qiboot/6410-partition-sd.sh | 2 +- qiboot/Makefile | 8 +- qiboot/include/s3c6410.h | 75 +-- qiboot/include/serial-s3c64xx.h | 72 +++ .../s3c2442}/i2c-bitbang-s3c24xx.c | 0 qiboot/src/{ => cpu/s3c2442}/lowlevel_init.S | 0 qiboot/src/cpu/s3c2442/qi.lds | 12 +- .../{drivers => cpu/s3c2442}/s3c24xx-mci.c | 0 .../{drivers => cpu/s3c2442}/serial-s3c24xx.c | 0 qiboot/src/cpu/s3c6410/qi.lds | 26 +- qiboot/src/cpu/s3c6410/serial-s3c64xx.c | 47 ++ qiboot/src/cpu/s3c6410/start.S | 138 +----- qiboot/src/cpu/s3c6410/start_qi.c | 7 +- qiboot/src/cpu/s3c6410/tla01.c | 71 +-- qiboot/src/gta02/gta02.c | 428 ------------------ qiboot/src/gta03/gta03.c | 289 ------------ qiboot/src/phase2.c | 21 +- qiboot/src/utils.c | 32 +- 18 files changed, 218 insertions(+), 1010 deletions(-) create mode 100644 qiboot/include/serial-s3c64xx.h rename qiboot/src/{drivers => cpu/s3c2442}/i2c-bitbang-s3c24xx.c (100%) rename qiboot/src/{ => cpu/s3c2442}/lowlevel_init.S (100%) rename qiboot/src/{drivers => cpu/s3c2442}/s3c24xx-mci.c (100%) rename qiboot/src/{drivers => cpu/s3c2442}/serial-s3c24xx.c (100%) create mode 100644 qiboot/src/cpu/s3c6410/serial-s3c64xx.c delete mode 100644 qiboot/src/gta02/gta02.c delete mode 100644 qiboot/src/gta03/gta03.c diff --git a/qiboot/6410-partition-sd.sh b/qiboot/6410-partition-sd.sh index a3399a7..a2b38ef 100755 --- a/qiboot/6410-partition-sd.sh +++ b/qiboot/6410-partition-sd.sh @@ -26,7 +26,7 @@ SIG=1 FDISK_SCRIPT=/tmp/_fds -if [ -z $1 -o -z $2 -o -z $3 ] ; then +if [ -z "$1" -o -z "$2" -o -z "$3" ] ; then echo "This formats a SD card for usage on SD Card boot" echo " on 6410 based systems" echo diff --git a/qiboot/Makefile b/qiboot/Makefile index ad99a3f..cd4f3e3 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -30,10 +30,10 @@ 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}" + -DBUILD_DATE="${BUILD_DATE}" -DQI_CPU="${CPU}" LDFLAGS = -S_SRCS = src/cpu/$(CPU)/start.S src/lowlevel_init.S +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) \ @@ -44,6 +44,8 @@ SRCS = ${S_SRCS} ${C_SRCS} OBJS = ${S_OBJS} ${C_OBJS} LIBS = -L${COMPILER_LIB_PATH} -lgcc +OBJS = src/cpu/s3c6410/start.o src/cpu/s3c6410/start_qi.o src/cpu/s3c6410/serial-s3c64xx.o src/ctype.o src/utils.o src/cpu/s3c6410/tla01.o src/phase2.o + # GTA02 A5 and A6 U-Boot will eat these for DFU action UDFU_VID = 0x1d50 UDFU_PID = 0x5119 @@ -77,5 +79,5 @@ ${UDFU_IMAGE}:${OBJS} ${MKUDFU} @$(OBJDUMP) -d ${TARGET} >${IMAGE}.dis clean: - @rm -f src/*.o src/*~ include/*~ ${IMAGE_DIR}/* ${TARGET} ${UDFU_IMAGE} + @rm -f src/*.o cpu/*/*.o cpu/*/*~ src/*~ src/drivers/*.o src/drivers/*~ include/*~ ${IMAGE_DIR}/* ${TARGET} ${UDFU_IMAGE} @make clean -C $(TOOLS) diff --git a/qiboot/include/s3c6410.h b/qiboot/include/s3c6410.h index d0b9dd6..926c38d 100644 --- a/qiboot/include/s3c6410.h +++ b/qiboot/include/s3c6410.h @@ -45,6 +45,8 @@ typedef enum { S3C64XX_UART2, } S3C64XX_UARTS_NR; +#define __REG(x) (*((unsigned int *)(x))) + //#include #endif @@ -1306,79 +1308,6 @@ typedef enum { /* include common stuff */ #ifndef __ASSEMBLY__ -static inline S3C64XX_MEMCTL * S3C64XX_GetBase_MEMCTL(void) -{ - return (S3C64XX_MEMCTL *)(ELFIN_DMC0_BASE); -} -static inline S3C64XX_USB_HOST * S3C64XX_GetBase_USB_HOST(void) -{ - return (S3C64XX_USB_HOST *)ELFIN_USB_HOST_BASE; -} -static inline S3C64XX_INTERRUPT * S3C64XX_GetBase_INTERRUPT(void) -{ - return (S3C64XX_INTERRUPT *)ELFIN_VIC0_BASE_ADDR; -} -static inline S3C64XX_DMAS * S3C64XX_GetBase_DMAS(void) -{ - return (S3C64XX_DMAS *)ELFIN_DMA_BASE; -} -static inline S3C64XX_CLOCK_POWER * S3C64XX_GetBase_CLOCK_POWER(void) -{ - return (S3C64XX_CLOCK_POWER *)ELFIN_CLOCK_POWER_BASE; -} -static inline S3C64XX_LCD * S3C64XX_GetBase_LCD(void) -{ - return (S3C64XX_LCD *)ELFIN_LCD_BASE; -} -/* -static inline S3C2410_NAND * S3C2410_GetBase_NAND(void) -{ - return (S3C2410_NAND *)ELFIN_NAND_BASE; -} -*/ -static inline S3C64XX_UART * S3C64XX_GetBase_UART(S3C64XX_UARTS_NR nr) -{ -// return (S3C64XX_UART *)(ELFIN_UART_BASE + (nr * 0x4000)); - return (S3C64XX_UART *)(ELFIN_UART_BASE + (nr*0x400)); -} -static inline S3C64XX_TIMERS * S3C64XX_GetBase_TIMERS(void) -{ - return (S3C64XX_TIMERS *)ELFIN_TIMER_BASE; -} -/* -static inline S3C64XX_USB_DEVICE * S3C64XX_GetBase_USB_DEVICE(void) -{ - return (S3C64XX_USB_DEVICE *)ELFIN_USB_DEVICE_BASE; -} -*/ -static inline S3C64XX_WATCHDOG * S3C64XX_GetBase_WATCHDOG(void) -{ - return (S3C64XX_WATCHDOG *)ELFIN_WATCHDOG_BASE; -} -static inline S3C64XX_I2C * S3C64XX_GetBase_I2C(void) -{ - return (S3C64XX_I2C *)ELFIN_I2C_BASE; -} -static inline S3C64XX_I2S * S3C64XX_GetBase_I2S(void) -{ - return (S3C64XX_I2S *)ELFIN_I2S_BASE; -} -static inline S3C64XX_GPIO * S3C64XX_GetBase_GPIO(void) -{ - return (S3C64XX_GPIO *)ELFIN_GPIO_BASE; -} -static inline S3C64XX_RTC * S3C64XX_GetBase_RTC(void) -{ - return (S3C64XX_RTC *)ELFIN_RTC_BASE; -} -static inline S3C2410_ADC * S3C2410_GetBase_ADC(void) -{ - return (S3C2410_ADC *)ELFIN_ADC_BASE; -} -static inline S3C64XX_SPI * S3C64XX_GetBase_SPI(void) -{ - return (S3C64XX_SPI *)ELFIN_SPI_BASE; -} #if 0 static inline S3C2410_SDI * S3C2410_GetBase_SDI(void) { diff --git a/qiboot/include/serial-s3c64xx.h b/qiboot/include/serial-s3c64xx.h new file mode 100644 index 0000000..bab0872 --- /dev/null +++ b/qiboot/include/serial-s3c64xx.h @@ -0,0 +1,72 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: xiangfu liu + * + * 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 diff --git a/qiboot/src/drivers/i2c-bitbang-s3c24xx.c b/qiboot/src/cpu/s3c2442/i2c-bitbang-s3c24xx.c similarity index 100% rename from qiboot/src/drivers/i2c-bitbang-s3c24xx.c rename to qiboot/src/cpu/s3c2442/i2c-bitbang-s3c24xx.c diff --git a/qiboot/src/lowlevel_init.S b/qiboot/src/cpu/s3c2442/lowlevel_init.S similarity index 100% rename from qiboot/src/lowlevel_init.S rename to qiboot/src/cpu/s3c2442/lowlevel_init.S diff --git a/qiboot/src/cpu/s3c2442/qi.lds b/qiboot/src/cpu/s3c2442/qi.lds index 504b130..78df9d3 100644 --- a/qiboot/src/cpu/s3c2442/qi.lds +++ b/qiboot/src/cpu/s3c2442/qi.lds @@ -37,12 +37,12 @@ SECTIONS . = ALIGN(4); .text : { - src/cpu/s3c2442/start.o (.text .rodata* .data) - src/lowlevel_init.o (.text .rodata* .data) - src/cpu/s3c2442/start_qi.o (.text .rodata* .data) - src/blink_led.o (.text .rodata* .data) - src/cpu/s3c2442/nand_read.o (.text .rodata* .data) - src/drivers/serial-s3c24xx.o (.text .rodata* .data) + src/cpu/s3c2442/start.o (.text .rodata* .data) + src/lowlevel_init.o (.text .rodata* .data) + src/cpu/s3c2442/start_qi.o (.text .rodata* .data) + src/blink_led.o (.text .rodata* .data) + src/cpu/s3c2442/nand_read.o (.text .rodata* .data) + src/cpu/s3c2442/serial-s3c24xx.o (.text .rodata* .data) } . = ALIGN(4); diff --git a/qiboot/src/drivers/s3c24xx-mci.c b/qiboot/src/cpu/s3c2442/s3c24xx-mci.c similarity index 100% rename from qiboot/src/drivers/s3c24xx-mci.c rename to qiboot/src/cpu/s3c2442/s3c24xx-mci.c diff --git a/qiboot/src/drivers/serial-s3c24xx.c b/qiboot/src/cpu/s3c2442/serial-s3c24xx.c similarity index 100% rename from qiboot/src/drivers/serial-s3c24xx.c rename to qiboot/src/cpu/s3c2442/serial-s3c24xx.c diff --git a/qiboot/src/cpu/s3c6410/qi.lds b/qiboot/src/cpu/s3c6410/qi.lds index 14051a4..888972a 100644 --- a/qiboot/src/cpu/s3c6410/qi.lds +++ b/qiboot/src/cpu/s3c6410/qi.lds @@ -29,29 +29,35 @@ 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. + /* 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+ */ - . = ALIGN(4); - .text : + .text 0x0c000000 : AT ( 0 ) { - src/cpu/s3c6410/start.o (.text .rodata* .data) - src/lowlevel_init.o (.text .rodata* .data) - src/cpu/s3c6410/start_qi.o (.text .rodata* .data) - src/blink_led.o (.text .rodata* .data) + src/cpu/s3c6410/start.o (.text .rodata* .data) + src/cpu/s3c6410/start_qi.o (.text .rodata* .data) + src/cpu/s3c6410/serial-s3c64xx.o (.text .rodata* .data) + src/cpu/s3c6410/tla01.o (.text .rodata* .data) + src/ctype.o (.text .rodata* .data) + src/phase2.o (.text .rodata* .data) + src/utils.o (.text .rodata* .data) } - . = ALIGN(4); +/* . = ALIGN(4); .everything_else ADDR (.text) + SIZEOF (.text) + 0x53000000 : AT ( ADDR (.text) + SIZEOF (.text) ) { *(.text .rodata* .data) } +*/ . = 0x53800000 ; +/* . = 0x0c001900 ; */ __bss_start = .; .bss_6410 (NOLOAD) : { * (.bss) } + _end = .; } diff --git a/qiboot/src/cpu/s3c6410/serial-s3c64xx.c b/qiboot/src/cpu/s3c6410/serial-s3c64xx.c new file mode 100644 index 0000000..7e5a2b3 --- /dev/null +++ b/qiboot/src/cpu/s3c6410/serial-s3c64xx.c @@ -0,0 +1,47 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: xiangfu liu + * + * 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 +#include + +/* + * Output a single byte to the serial port. + */ +void serial_putc_s3c64xx(const int uart, const char c) +{ + switch(uart) + { + case 0: + while (!( UTRSTAT0_REG & 0x2 )) + ; + UTXH0_REG = c; + break; + case 1: + while (!( UTRSTAT1_REG & 0x2)) + ; + UTXH1_REG = c; + break; + + default: + break; + } +} diff --git a/qiboot/src/cpu/s3c6410/start.S b/qiboot/src/cpu/s3c6410/start.S index 7cb429e..29a5713 100644 --- a/qiboot/src/cpu/s3c6410/start.S +++ b/qiboot/src/cpu/s3c6410/start.S @@ -141,11 +141,6 @@ _start_armboot: _TEXT_BASE: .word TEXT_BASE -processor_id: - .word 0 - .word 0x41129200 /* s3c2442 ID */ - .word 0x410fb760 /* s3c6410 ID */ - /* * These are defined in the board-specific linker script. */ @@ -311,12 +306,12 @@ start_code: mov r1, #0x0 str r1, [r0, #INDEX_DMC_MEMC_CMD] -check_dmc1_ready: +1: ldr r1, [r0, #INDEX_DMC_MEMC_STATUS] mov r2, #0x3 and r1, r1, r2 cmp r1, #0x1 - bne check_dmc1_ready + bne 1b nop ldr r0, =ELFIN_CLOCK_POWER_BASE @0x7e00f000 @@ -336,12 +331,12 @@ check_dmc1_ready: orr r1, r1, r2 str r1, [r0, #OTHERS_OFFSET] -check_syncack: +2: ldr r1, [r0, #OTHERS_OFFSET] ldr r2, =0xf00 and r1, r1, r2 cmp r1, #0xf00 - bne check_syncack + bne 2b mov r1, #0xff00 orr r1, r1, #0xff @@ -385,8 +380,8 @@ check_syncack: /* wait at least 200us to stablize all clock */ mov r1, #0x10000 -1: subs r1, r1, #1 - bne 1b +3: subs r1, r1, #1 + bne 3b ldr r1, [r0, #OTHERS_OFFSET] orr r1, r1, #0x20 @@ -417,121 +412,14 @@ check_syncack: ldr r1, =0x1FFF str r1, [r0, #UDIVSLOT_OFFSET] - ldr r1, =0x4f4f4f4f - str r1, [r0, #UTXH_OFFSET] @'O' - - /* send out a char to say hello */ - ldr r1, =0x55 - str r1, [r0, #UTXH_OFFSET] - - -#if 0 -/* Below code is for ARM926EJS and ARM1026EJS */ - .globl cleanDCache -cleanDCache: - mrc p15, 0, pc, c7, c10, 3 /* test/clean D-Cache */ - bne cleanDCache - mov pc, lr - - .globl cleanFlushDCache -cleanFlushDCache: - mrc p15, 0, pc, c7, c14, 3 /* test/cleanflush D-Cache */ - bne cleanFlushDCache - mov pc, lr - - .globl cleanFlushCache -cleanFlushCache: - mrc p15, 0, pc, c7, c14, 3 /* test/cleanflush D-Cache */ - bne cleanFlushCache - mcr p15, 0, r0, c7, c5, 0 /* flush I-Cache */ - mov pc, lr - - .ltorg -#endif - -#if 0 - - /* 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] - - - - /* 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] - -#endif /* >> 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 */ @@ -543,6 +431,14 @@ clbss_l: cmp r0, r1 ble clbss_l -/* we are going to jump into the C part of the init now */ -spin: +#if 0 + ldr r0, =ELFIN_UART_CONSOLE_BASE + ldr r1, =0x55 + push {r1} + pop {r1} + str r1, [r0, #UTXH_OFFSET] @'U' +#endif b _steppingstone_done + +4: + b 4b diff --git a/qiboot/src/cpu/s3c6410/start_qi.c b/qiboot/src/cpu/s3c6410/start_qi.c index ca419ee..a39abc5 100644 --- a/qiboot/src/cpu/s3c6410/start_qi.c +++ b/qiboot/src/cpu/s3c6410/start_qi.c @@ -37,6 +37,8 @@ const struct board_api *boards[] = { struct board_api const * this_board; extern int is_jtag; +#include + void start_qi(void) { int flag = 0; @@ -97,9 +99,8 @@ void start_qi(void) * jump to bootloader_second_phase() running from DRAM copy */ bootloader_second_phase(); -#if 0 -unhappy: + while(1) ; -#endif + } diff --git a/qiboot/src/cpu/s3c6410/tla01.c b/qiboot/src/cpu/s3c6410/tla01.c index 2269d09..f4b9714 100644 --- a/qiboot/src/cpu/s3c6410/tla01.c +++ b/qiboot/src/cpu/s3c6410/tla01.c @@ -1,24 +1,25 @@ #include #include -#include -#include -#include +#include +//#include +//#include #include -#define GTA03_DEBUG_UART 2 +#define GTA03_DEBUG_UART 0 #define PCF50633_I2C_ADS 0x73 static const struct board_variant board_variants[] = { [0] = { - .name = "TLA01", + .name = "SMDK", .machine_revision = 0x010, }, }; void port_init_tla01(void) { +#if 0 unsigned int * MPLLCON = (unsigned int *)0x4c000004; unsigned int * UPLLCON = (unsigned int *)0x4c000008; unsigned int * CLKDIVN = (unsigned int *)0x4c000014; @@ -135,28 +136,7 @@ void port_init_tla01(void) /* push DOWN1 (CPU Core rail) to 1.7V, allowing 533MHz */ i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_DOWN1OUT, 0x2b); - - /* change CPU clocking to 533MHz 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 = ((169 << 12) + (2 << 4) + 1); - - - serial_init_115200_s3c24xx(GTA03_DEBUG_UART, 66 /*MHz PCLK */); +#endif } /** @@ -167,36 +147,7 @@ void port_init_tla01(void) int tla01_get_pcb_revision(void) { - int n; - u32 u; - - /* make B0 inputs */ - rGPBCON &= ~0x00000003; - /* D8 and D9 inputs */ - rGPDCON &= ~0x000f0000; - - /* delay after changing pulldowns */ - u = rGPBDAT; - u = rGPDDAT; - - /* read the version info */ - u = rGPBDAT; - n = (u >> (0 - 0))& 0x001; - u = rGPDDAT; - n |= (u >> (8 -1)) & 0x002; - n |= (u >> (9 - 2)) & 0x004; - - /* - * when not being interrogated, all of the revision GPIO - * are set to output - */ - /* make B0 high ouput */ - rGPBCON |= 0x00000001; - /* D8 and D9 high ouputs */ - rGPDCON |= 0x00050000; - - return n; - + return 0; } const struct board_variant const * get_board_variant_tla01(void) @@ -212,7 +163,7 @@ int is_this_board_tla01(void) static void putc_tla01(char c) { - serial_putc_s3c24xx(GTA03_DEBUG_UART, c); + serial_putc_s3c64xx(GTA03_DEBUG_UART, c); } @@ -222,9 +173,9 @@ static void putc_tla01(char c) const struct board_api board_api_tla01 = { .name = "TLA01", .linux_machine_id = 1866, - .linux_mem_start = 0x30000000, + .linux_mem_start = 0x50000000, .linux_mem_size = (128 * 1024 * 1024), - .linux_tag_placement = 0x30000000 + 0x100, + .linux_tag_placement = 0x50000000 + 0x100, .get_board_variant = get_board_variant_tla01, .is_this_board = is_this_board_tla01, .port_init = port_init_tla01, diff --git a/qiboot/src/gta02/gta02.c b/qiboot/src/gta02/gta02.c deleted file mode 100644 index f6710b4..0000000 --- a/qiboot/src/gta02/gta02.c +++ /dev/null @@ -1,428 +0,0 @@ -/* - * (C) Copyright 2007 OpenMoko, Inc. - * Author: Andy Green - * - * (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 -#include -#include -#include -#include -#include -#include - -#define GTA02_DEBUG_UART 2 - -#define PCF50633_I2C_ADS 0x73 - -struct pcf50633_init { - u8 index; - u8 value; -}; - -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_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, 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_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, 0x19 }, /* 25/255 == 98mA soft-start usb fast */ - { PCF50633_REG_MBCC6, 0x00 }, /* cutoff current 1/32 * Ichg */ - { PCF50633_REG_MBCC7, 0x00 }, /* 1.6A max bat curr, USB 100mA */ - { 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 = "A5 PCB", - .machine_revision = 0x350, - }, - [1] = { - .name = "A6 PCB", - .machine_revision = 0x360, - } -}; - - -void port_init_gta02(void) -{ -#if 0 - unsigned int * MPLLCON = (unsigned int *)0x4c000004; - unsigned int * UPLLCON = (unsigned int *)0x4c000008; - unsigned int * CLKDIVN = (unsigned int *)0x4c000014; -#endif - int n; - - //CAUTION:Follow the configuration order for setting the ports. - // 1) setting value(GPnDAT) - // 2) setting control register (GPnCON) - // 3) configure pull-up 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 = 0x0000AAAA; - 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 - */ - /* pulldown on GPH08: UEXTCLK, just floats! - * pulldown GPH0 -- nCTS0 / RTS_MODEM -- floats when GSM off - * pulldown GPH3 -- RXD[0] / TX_MODEM -- floats when GSM off - */ - rGPHCON = 0x001AAAAA; - rGPHUP = 0x000007FF & ~(1 << 8) & ~(1 << 0) & ~(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); - -#if 0 - /* 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 PCLK */); -#else - serial_init_115200_s3c24xx(GTA02_DEBUG_UART, 33 /* 33MHz PCLK */); -#endif - - /* we're going to use Glamo for SD Card access, so we need to init the - * evil beast - */ - glamo_core_init(); -} - -/** - * 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 << (8 - 3)) & 0x100; - n |= (u << (9 - 4)) & 0x200; - - /* - * 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) -{ - return &board_variants[gta02_get_pcb_revision() & 1]; -} - -static 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)(); -} - -/* - * 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, - .putc = putc_gta02, - .close = close_gta02, - /* these are the ways we could boot GTA02 in order to try */ - .kernel_source = { - [0] = { - .name = "SD Card EXT2 Kernel", - .block_init = sd_card_init_gta02, - .block_read = sd_card_block_read_gta02, - .partition_index = 1, - .filesystem = FS_EXT2, - .filepath = "boot/uImage.bin", - .commandline = "mtdparts=physmap-flash:-(nor);" \ - "neo1973-nand:" \ - "0x00040000(qi)," \ - "0x00040000(cmdline)," \ - "0x00800000(backupkernel)," \ - "0x000a0000(extra)," \ - "0x00040000(identity)," \ - "0x0f6a0000(backuprootfs) " \ - "rootfstype=ext3 " \ - "root=/dev/mmcblk0p1 " \ - "console=ttySAC2,115200 " \ - "loglevel=8 " \ - "init=/sbin/init "\ - "ro" - }, - [1] = { - .name = "NAND Kernel", - .block_read = nand_read_ll, - .offset_blocks512_if_no_partition = 0x80000 / 512, - .filesystem = FS_RAW, - .commandline = "mtdparts=physmap-flash:-(nor);" \ - "neo1973-nand:" \ - "0x00040000(qi)," \ - "0x00040000(cmdline)," \ - "0x00800000(backupkernel)," \ - "0x000a0000(extra)," \ - "0x00040000(identity)," \ - "0x0f6a0000(backuprootfs) " \ - "rootfstype=jffs2 " \ - "root=/dev/mtdblock6 " \ - "console=ttySAC2,115200 " \ - "loglevel=8 " \ - "init=/sbin/init "\ - "ro" - }, - }, -}; diff --git a/qiboot/src/gta03/gta03.c b/qiboot/src/gta03/gta03.c deleted file mode 100644 index 73fa268..0000000 --- a/qiboot/src/gta03/gta03.c +++ /dev/null @@ -1,289 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#define GTA03_DEBUG_UART 2 - -#define PCF50633_I2C_ADS 0x73 - - -static const struct board_variant board_variants[] = { - [0] = { - .name = "EVB PCB", - .machine_revision = 0x010, - }, -}; - -void port_init_gta03(void) -{ - unsigned int * MPLLCON = (unsigned int *)0x4c000004; - unsigned int * UPLLCON = (unsigned int *)0x4c000008; - unsigned int * CLKDIVN = (unsigned int *)0x4c000014; - - //CAUTION:Follow the configuration order for setting the ports. - // 1) setting value(GPnDAT) - // 2) setting control register (GPnCON) - // 3) configure pull-up 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 = 0x007F8FFF; - /* - * ===* 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 = 0x00145554; - rGPBDAT |= (1 <<9 ); /* USB_PULLUP */ - rGPBUP = 0x000007FF; - /* - * === 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 = 0xAAA776E9; - rGPCUP = 0x0000FFFF; - rGPCDAT |= (1 << 9); /* WLAN_nRESET pull high */ - /* - * === 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 = 0xAAA0AAA5; - rGPDUP = 0x0000FFFF; - /* - * === 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; - /* - * === 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 - */ - rGPFCON = 0x0000AAAA; - rGPFUP = 0x000000FF; - - /* - * === 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 = 0x02A9FE5A; - rGPGUP = 0x0000FFFF; - - /* - * === 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 - */ - /* pulldown on GPH08: UEXTCLK, just floats! - * pulldown GPH0 -- nCTS0 / RTS_MODEM -- floats when GSM off - * pulldown GPH3 -- RXD[0] / TX_MODEM -- floats when GSM off - */ - rGPHCON = 0x0019A0AA; - rGPHUP = 0x000007FF; - - /* pulldown on GPJ00: input, just floats! */ - /* pulldown on GPJ07: WLAN module WLAN_GPIO0, no ext pull */ - rGPJCON = 0x02AAAAAA; - rGPJUP = 0x1FFFF; - - /* - * We have to talk to the PMU a little bit - */ - - /* We need SD Card rail (HCLDO) at 3.0V */ - i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_HCLDOOUT, - 21); - - /* switch HCLDO on */ - i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_HCLDOENA, 1); - - /* push DOWN1 (CPU Core rail) to 1.7V, allowing 533MHz */ - i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_DOWN1OUT, - 0x2b); - - /* change CPU clocking to 533MHz 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 = ((169 << 12) + (2 << 4) + 1); - - - serial_init_115200_s3c24xx(GTA03_DEBUG_UART, 66 /*MHz PCLK */); -} - -/** - * returns PCB revision information in b0, d8, d9 - * GTA03 EVB returns 0x000 - * GTA03 returns 0x001 - */ - -int gta03_get_pcb_revision(void) -{ - int n; - u32 u; - - /* make B0 inputs */ - rGPBCON &= ~0x00000003; - /* D8 and D9 inputs */ - rGPDCON &= ~0x000f0000; - - /* delay after changing pulldowns */ - u = rGPBDAT; - u = rGPDDAT; - - /* read the version info */ - u = rGPBDAT; - n = (u >> (0 - 0))& 0x001; - u = rGPDDAT; - n |= (u >> (8 -1)) & 0x002; - n |= (u >> (9 - 2)) & 0x004; - - /* - * when not being interrogated, all of the revision GPIO - * are set to output - */ - /* make B0 high ouput */ - rGPBCON |= 0x00000001; - /* D8 and D9 high ouputs */ - rGPDCON |= 0x00050000; - - return n; - -} - -const struct board_variant const * get_board_variant_gta03(void) -{ - return &board_variants[gta03_get_pcb_revision()]; -} - -int is_this_board_gta03(void) -{ - /* FIXME: find something gta03 specific */ - return 1; -} - -static void putc_gta03(char c) -{ - serial_putc_s3c24xx(GTA03_DEBUG_UART, c); -} - -int sd_card_init_gta03(void) -{ - return s3c24xx_mmc_init(1); -} - -int sd_card_block_read_gta03(unsigned char * buf, unsigned long start512, - int blocks512) -{ - return s3c24xx_mmc_bread(0, start512, blocks512, buf); -} - - - -/* - * our API for bootloader on this machine - */ -const struct board_api board_api_gta03 = { - .name = "GTA03-2442", - .linux_machine_id = 1866, - .linux_mem_start = 0x30000000, - .linux_mem_size = (128 * 1024 * 1024), - .linux_tag_placement = 0x30000000 + 0x100, - .get_board_variant = get_board_variant_gta03, - .is_this_board = is_this_board_gta03, - .port_init = port_init_gta03, - .putc = putc_gta03, - /* these are the ways we could boot GTA03 in order to try */ - .kernel_source = { - [0] = { - .name = "SD Card EXT2 Kernel", - .block_init = sd_card_init_gta03, - .block_read = sd_card_block_read_gta03, - .partition_index = 1, - .filesystem = FS_EXT2, - .filepath = "boot/uImage.bin", - .commandline = "mtdparts=physmap-flash:-(nor);" \ - "neo1973-nand:" \ - "0x00040000(qi)," \ - "0x00040000(cmdline)," \ - "0x00800000(backupkernel)," \ - "0x000a0000(extra)," \ - "0x00040000(identity)," \ - "0x0f6a0000(backuprootfs) " \ - "rootfstype=ext2 " \ - "root=/dev/mmcblk0p1 " \ - "console=ttySAC2,115200 " \ - "loglevel=4 " \ - "init=/sbin/init "\ - "ro" - }, - [1] = { - .name = "NAND Kernel", - .block_read = nand_read_ll, - .offset_blocks512_if_no_partition = 0x80000 / 512, - .filesystem = FS_RAW, - .commandline = "mtdparts=neo1973-nand:" \ - "0x00040000(qi)," \ - "0x00040000(cmdline)," \ - "0x00800000(backupkernel)," \ - "0x000a0000(extra)," \ - "0x00040000(identity)," \ - "0x0f6a0000(backuprootfs) " \ - "rootfstype=jffs2 " \ - "root=/dev/mtdblock6 " \ - "console=ttySAC2,115200 " \ - "loglevel=4 " \ - "init=/sbin/init "\ - "ro" - }, - }, -}; diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 40053ff..679f206 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -39,13 +39,17 @@ unsigned long partition_length_blocks = 0; struct kernel_source const * this_kernel = 0; +int raise(int n) +{ + return 0; +} + void bootloader_second_phase(void) { void (*the_kernel)(int zero, int arch, uint params); int kernel = 0; - const struct board_variant * board_variant = - (this_board->get_board_variant)(); + const struct board_variant * board_variant; /* okay, do the critical port and serial init for our board */ @@ -53,9 +57,10 @@ void bootloader_second_phase(void) /* stick some hello messages on debug console */ - puts("\n\n\nQi Bootloader "stringify2(BUILD_HOST)" " - stringify2(BUILD_VERSION)" " - stringify2(BUILD_DATE)"\n"); + puts("\n\n\nQi Bootloader "stringify2(QI_CPU)" " + stringify2(BUILD_HOST)" " + stringify2(BUILD_VERSION)" " + stringify2(BUILD_DATE)"\n"); puts("Copyright (C) 2008 Openmoko, Inc.\n"); puts("This is free software; see the source for copying conditions.\n" @@ -145,6 +150,7 @@ void bootloader_second_phase(void) switch (this_kernel->filesystem) { case FS_EXT2: +#if 0 if (!ext2fs_mount()) { puts("Unable to mount ext2 filesystem\n"); this_kernel = &this_board-> @@ -162,6 +168,7 @@ void bootloader_second_phase(void) } ext2fs_read(kernel_dram, 4096); break; +#endif case FS_FAT: /* FIXME */ case FS_RAW: @@ -199,9 +206,11 @@ void bootloader_second_phase(void) switch (this_kernel->filesystem) { case FS_EXT2: +#if 0 /* This read API always restarts from beginning */ ext2fs_read(kernel_dram, kernel_size); break; +#endif case FS_FAT: /* FIXME */ case FS_RAW: @@ -297,5 +306,5 @@ void bootloader_second_phase(void) puts("No usable kernel image found, we've had it :-(\n"); while (1) - blue_on(1); + ; } diff --git a/qiboot/src/utils.c b/qiboot/src/utils.c index dce53a3..4ec61dd 100644 --- a/qiboot/src/utils.c +++ b/qiboot/src/utils.c @@ -26,10 +26,6 @@ static u8 malloc_pool[100 * 1024]; void * malloc_pointer = &malloc_pool[0]; -int raise(int n) -{ - return 0; -} size_t strlen(const char *s) { @@ -139,22 +135,38 @@ void hexdump(unsigned char *start, int len) void printdec(int n) { - int d = 1 * 1000 * 1000 * 1000; + int d[] = { + 1 * 1000 * 1000 * 1000, + 100 * 1000 * 1000, + 10 * 1000 * 1000, + 1 * 1000 * 1000, + 100 * 1000, + 10 * 1000, + 1 * 1000, + 100, + 10, + 1, + 0 + }; int flag = 0; + int div = 0; if (n < 0) { this_board->putc('-'); n = -n; } - while (d) { - int r = n / d; - if (r || flag || (d == 1)) { + while (d[div]) { + int r = 0; + while (n >= d[div]) { + r++; + n -= d[div]; + } + if (r || flag || (d[div] == 1)) { this_board->putc('0' + r); flag = 1; } - n -= r * d; - d = d / 10; + div++; } } From 4a07126420d8a30da48ba2e92dbb2bdfa4dbbbd2 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:40 +0000 Subject: [PATCH 102/248] qi-moved-lowlevel-init-2442.patch lowlevel-init.S is specific to cpu and is moved there now, update s3c2442 linker script Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/qi.lds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiboot/src/cpu/s3c2442/qi.lds b/qiboot/src/cpu/s3c2442/qi.lds index 78df9d3..09da8bb 100644 --- a/qiboot/src/cpu/s3c2442/qi.lds +++ b/qiboot/src/cpu/s3c2442/qi.lds @@ -38,7 +38,7 @@ SECTIONS .text : { src/cpu/s3c2442/start.o (.text .rodata* .data) - src/lowlevel_init.o (.text .rodata* .data) + src/cpu/s3c2442/lowlevel_init.o (.text .rodata* .data) src/cpu/s3c2442/start_qi.o (.text .rodata* .data) src/blink_led.o (.text .rodata* .data) src/cpu/s3c2442/nand_read.o (.text .rodata* .data) From 999c78e7f80f92719bd127038d3e11d0bc4d3caf Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:40 +0000 Subject: [PATCH 103/248] qi-break-crc32-out-of-utils.patch We want utils stuffs in steppingstone part, it's too expensive to have CRC32 in there. Bust it out into its own file that appears only in everything_else section in second bootloader stage. Signed-off-by: Andy Green --- qiboot/src/crc32.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++ qiboot/src/utils.c | 87 -------------------------------------------- 2 files changed, 90 insertions(+), 87 deletions(-) create mode 100644 qiboot/src/crc32.c diff --git a/qiboot/src/crc32.c b/qiboot/src/crc32.c new file mode 100644 index 0000000..81f1792 --- /dev/null +++ b/qiboot/src/crc32.c @@ -0,0 +1,90 @@ +#include +#include + + +/* original copyright notice for this crc code (it is from U-Boot) --> */ +/* + * This file is derived from crc32.c from the zlib-1.1.3 distribution + * by Jean-loup Gailly and Mark Adler. + */ + +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +const unsigned long crc_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; + +#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); + +unsigned long crc32(unsigned long crc, const unsigned char *buf, + unsigned int len) +{ + crc = crc ^ 0xffffffffL; + while (len >= 8) { + DO8(buf); + len -= 8; + } + if (len) + do { + DO1(buf); + } while (--len); + + return crc ^ 0xffffffffL; +} diff --git a/qiboot/src/utils.c b/qiboot/src/utils.c index 4ec61dd..ffc1368 100644 --- a/qiboot/src/utils.c +++ b/qiboot/src/utils.c @@ -170,93 +170,6 @@ void printdec(int n) } } -/* original copyright notice for this crc code (it is from U-Boot) --> */ -/* - * This file is derived from crc32.c from the zlib-1.1.3 distribution - * by Jean-loup Gailly and Mark Adler. - */ - -/* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -const unsigned long crc_table[256] = { - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, - 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, - 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, - 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, - 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, - 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, - 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, - 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, - 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, - 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, - 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, - 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, - 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, - 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, - 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, - 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, - 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, - 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, - 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, - 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, - 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, - 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, - 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, - 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, - 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, - 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, - 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, - 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, - 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, - 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, - 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, - 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, - 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, - 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, - 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, - 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, - 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, - 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, - 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, - 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, - 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, - 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, - 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, - 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, - 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, - 0x2d02ef8dL -}; - -#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); -#define DO2(buf) DO1(buf); DO1(buf); -#define DO4(buf) DO2(buf); DO2(buf); -#define DO8(buf) DO4(buf); DO4(buf); - -unsigned long crc32(unsigned long crc, const unsigned char *buf, - unsigned int len) -{ - crc = crc ^ 0xffffffffL; - while (len >= 8) { - DO8(buf); - len -= 8; - } - if (len) - do { - DO1(buf); - } while (--len); - - return crc ^ 0xffffffffL; -} - void *memcpy(void *dest, const void *src, size_t n) { u8 const * ps = src; From 75e1f8d156e408cbb5a6a5a4146ec16d8a219fdd Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:40 +0000 Subject: [PATCH 104/248] qi-move-udelay-out-of-glamo-mmc-to-utils.patch udelay() is more generally wanted, move it to utils.c Signed-off-by: Andy Green --- qiboot/src/drivers/glamo-mmc.c | 9 --------- qiboot/src/utils.c | 8 ++++++++ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/qiboot/src/drivers/glamo-mmc.c b/qiboot/src/drivers/glamo-mmc.c index 4f2f530..a031d0b 100644 --- a/qiboot/src/drivers/glamo-mmc.c +++ b/qiboot/src/drivers/glamo-mmc.c @@ -64,15 +64,6 @@ int mmc_read(unsigned long src, u8 *dst, int size); }) - -int q; - -void udelay(int n) -{ - while (n--) - q+=n * q; -} - static void glamo_reg_write(u16 val, u16 reg) { diff --git a/qiboot/src/utils.c b/qiboot/src/utils.c index ffc1368..ffca1f5 100644 --- a/qiboot/src/utils.c +++ b/qiboot/src/utils.c @@ -213,3 +213,11 @@ void *malloc(size_t size) void free(void *ptr) { } + +int q; + +void udelay(int n) +{ + while (n--) + q+=n * q; +} From 4e326e29faf173d0e05e59e37d53d3dd03f9ce68 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:40 +0000 Subject: [PATCH 105/248] qi-fix-always-slow-glamo-mmc-init.patch Little bugfix that we never exit the mmc init wait loop before the timeout expires. Signed-off-by: Andy Green --- qiboot/src/drivers/glamo-mmc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/qiboot/src/drivers/glamo-mmc.c b/qiboot/src/drivers/glamo-mmc.c index a031d0b..4df2ec6 100644 --- a/qiboot/src/drivers/glamo-mmc.c +++ b/qiboot/src/drivers/glamo-mmc.c @@ -673,16 +673,18 @@ int mmc_init(int verbose) if (resp) continue; - if (response[3] & (1 << 6)) /* asserts block addressing */ + if (response[3] & (1 << 6)) { /* asserts block addressing */ + retries = -2; card_type = CARDTYPE_SDHC; - + } if (response[3] & (1 << 7)) { /* not busy */ if (card_type == CARDTYPE_NONE) card_type = CARDTYPE_SD; + retries = -2; break; } } - if (retries < 0) { + if (retries == -1) { puts("no response\n"); return 1; } From 82d2e255c33ec8bfcf5aa2aa6eb56edd58c7324b Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:40 +0000 Subject: [PATCH 106/248] qi-add-sc36410-mci.patch This heavily adapts the Samsung U-Boot hs_mmc code and combines it with the SD / SDHC startup code written for glamo-mci stuff that is known to work OK with common SD and SDHC. tla01 is changed to use the implementation. Signed-off-by: Andy Green --- qiboot/Makefile | 2 - qiboot/include/linux-mmc-protocol.h | 382 ++++++++++++++++ qiboot/include/linux-mmc.h | 120 +++++ qiboot/include/s3c6410.h | 64 ++- qiboot/src/cpu/s3c2442/start_qi.c | 20 + qiboot/src/cpu/s3c6410/hs_mmc.c | 683 ++++++++++++++++++++++++++++ qiboot/src/cpu/s3c6410/hs_mmc.h | 40 ++ qiboot/src/cpu/s3c6410/qi.lds | 37 +- qiboot/src/cpu/s3c6410/start_qi.c | 70 ++- qiboot/src/cpu/s3c6410/tla01.c | 41 +- qiboot/src/phase2.c | 36 +- 11 files changed, 1416 insertions(+), 79 deletions(-) create mode 100644 qiboot/include/linux-mmc-protocol.h create mode 100644 qiboot/include/linux-mmc.h create mode 100644 qiboot/src/cpu/s3c6410/hs_mmc.c create mode 100644 qiboot/src/cpu/s3c6410/hs_mmc.h diff --git a/qiboot/Makefile b/qiboot/Makefile index cd4f3e3..374d83e 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -44,8 +44,6 @@ SRCS = ${S_SRCS} ${C_SRCS} OBJS = ${S_OBJS} ${C_OBJS} LIBS = -L${COMPILER_LIB_PATH} -lgcc -OBJS = src/cpu/s3c6410/start.o src/cpu/s3c6410/start_qi.o src/cpu/s3c6410/serial-s3c64xx.o src/ctype.o src/utils.o src/cpu/s3c6410/tla01.o src/phase2.o - # GTA02 A5 and A6 U-Boot will eat these for DFU action UDFU_VID = 0x1d50 UDFU_PID = 0x5119 diff --git a/qiboot/include/linux-mmc-protocol.h b/qiboot/include/linux-mmc-protocol.h new file mode 100644 index 0000000..2d90273 --- /dev/null +++ b/qiboot/include/linux-mmc-protocol.h @@ -0,0 +1,382 @@ +/* + * 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 + * 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 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 */ + diff --git a/qiboot/include/linux-mmc.h b/qiboot/include/linux-mmc.h new file mode 100644 index 0000000..2750a51 --- /dev/null +++ b/qiboot/include/linux-mmc.h @@ -0,0 +1,120 @@ +/* + * 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 +#include +#include + +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 diff --git a/qiboot/include/s3c6410.h b/qiboot/include/s3c6410.h index 926c38d..960c493 100644 --- a/qiboot/include/s3c6410.h +++ b/qiboot/include/s3c6410.h @@ -36,9 +36,71 @@ #define S3C64XX_UART_CHANNELS 3 #define S3C64XX_SPI_CHANNELS 2 +#define HSMMC_CHANNEL 0 +#define MOVI_INIT_REQUIRED 0 +#define TCM_BASE 0x0C004000 +#define BL2_BASE 0x57E00000 +#define CopyMovitoMem(a,b,c,d,e) (((int(*)(int, uint, ushort, uint *, int))(*((uint *)(TCM_BASE + 0x8))))(a,b,c,d,e)) +#define SS_SIZE (8 * 1024) +#define eFUSE_SIZE (1 * 1024) // 0.5k eFuse, 0.5k reserved` +#define PART_UBOOT_OFFSET 0x0 +#define PART_ZIMAGE_OFFSET 0x40000 +#define PART_ROOTFS_OFFSET 0x200000 +#define PART_EXTRA_OFFSET 0x3200000 + +/* movinand definitions */ +#define MOVI_BLKSIZE 512 + +#define MOVI_TOTAL_BLKCNT 7864320 // 7864320 // 3995648 // 1003520 /* static movinand total block count: for writing to movinand when nand boot */ +#define MOVI_HIGH_CAPACITY 0 + +#define MOVI_LAST_BLKPOS (MOVI_TOTAL_BLKCNT - (eFUSE_SIZE / MOVI_BLKSIZE)) +#define MOVI_BL1_BLKCNT (SS_SIZE / MOVI_BLKSIZE) +#define MOVI_ENV_BLKCNT (CFG_ENV_SIZE / MOVI_BLKSIZE) +#define MOVI_BL2_BLKCNT (((PART_ZIMAGE_OFFSET - PART_UBOOT_OFFSET) / MOVI_BLKSIZE) - MOVI_ENV_BLKCNT) +#define MOVI_ZIMAGE_BLKCNT ((PART_ROOTFS_OFFSET - PART_ZIMAGE_OFFSET) / MOVI_BLKSIZE) +#define MOVI_BL2_POS (MOVI_LAST_BLKPOS - MOVI_BL1_BLKCNT - MOVI_BL2_BLKCNT - MOVI_ENV_BLKCNT) +#ifndef __ASSEMBLY__ + +struct movi_offset_t { + uint last; + uint bl1; + uint env; + uint bl2; + uint zimage; +}; + +/* external functions */ +extern void hsmmc_set_gpio(void); +extern void hsmmc_reset (void); +extern int hsmmc_init (void); +extern int movi_init(void); +extern void movi_set_capacity(void); +extern int movi_set_ofs(uint last); +extern void movi_write (uint addr, uint start_blk, uint blknum); +extern void movi_read (uint addr, uint start_blk, uint blknum); +extern void movi_write_env(ulong addr); +extern void movi_read_env(ulong addr); + +#if defined(CONFIG_S3C2450) +extern ulong virt_to_phy_smdk2450(ulong addr); +#elif defined(CONFIG_S3C6400) +extern ulong virt_to_phy_smdk6400(ulong addr); +#elif defined(CONFIG_S3C6410) +extern ulong virt_to_phy_smdk6410(ulong addr); +#elif defined(CONFIG_S3C6430) +extern ulong virt_to_phy_smdk6430(ulong addr); +#elif defined(CONFIG_S3C2416) +extern ulong virt_to_phy_smdk2416(ulong addr); +#endif + +extern void test_hsmmc (uint width, uint test, uint start_blk, uint blknum); + +/* external variables */ +extern struct movi_offset_t ofsinfo; + //#include -#ifndef __ASSEMBLY__ typedef enum { S3C64XX_UART0, S3C64XX_UART1, diff --git a/qiboot/src/cpu/s3c2442/start_qi.c b/qiboot/src/cpu/s3c2442/start_qi.c index ff479b6..cfb5c61 100644 --- a/qiboot/src/cpu/s3c2442/start_qi.c +++ b/qiboot/src/cpu/s3c2442/start_qi.c @@ -29,6 +29,10 @@ #include #include +#define stringify2(s) stringify1(s) +#define stringify1(s) #s + + extern void bootloader_second_phase(void); const struct board_api *boards[] = { @@ -94,6 +98,22 @@ void start_qi(void) this_board = boards[board++]; } + this_board->port_init(); + + /* 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); + /* * jump to bootloader_second_phase() running from DRAM copy */ diff --git a/qiboot/src/cpu/s3c6410/hs_mmc.c b/qiboot/src/cpu/s3c6410/hs_mmc.c new file mode 100644 index 0000000..def5046 --- /dev/null +++ b/qiboot/src/cpu/s3c6410/hs_mmc.c @@ -0,0 +1,683 @@ +#include +#include "hs_mmc.h" +#include +#include + +#define HCLK_OPERATION +#undef DEBUG_HSMMC +#ifdef DEBUG_HSMMC +#define dbg(x...) printf(x) +#else +#define dbg(x...) do { } while (0) +#endif + +//#include +#include +#include +//#include +//#include +//#include + +#include "hs_mmc.h" +#include + +#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 rd_cnt_HSMMC; +//static u32 wt_cnt_HSMMC; +static u32 BlockNum_HSMMC = 0; + +//static u32 WriteBlockCnt_INT = 0; +static u32 ReadBlockCnt_INT = 0; +//static u32 WRITEINT_DONE = 0; +//static u32 READINT_DONE = 0; +//static u32 COMPARE_INT_DONE = 0; +//static u32 CompareCnt_INT = 0; +//static u32 BufferBoundary_INT_Cnt = 0; + +static u32 HS_DMA_END = 0; +//static u32 HS_CARD_DETECT = 0; + +//static u32 ocr_check = 0; +//static u32 mmc_card = 0; +static u32 rca = 0; + +static ulong HCLK; +//static u32 card_mid = 0; + +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 < 0x1000000; i++) { + if (s3c_hsmmc_readw(HM_NORINTSTS) & 0x0002) { + HS_DMA_END = 1; + s3c_hsmmc_writew(s3c_hsmmc_readw(HM_NORINTSTS) | 0x0002, HM_NORINTSTS); + break; + } + if (s3c_hsmmc_readw(HM_NORINTSTS) & 0x8000) { + puts("error found: "); + print32(s3c_hsmmc_readw(HM_ERRINTSTS)); + break; + } + } +} + + +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)) { + puts("SD 2.0\n"); + 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; + + rd_cnt_HSMMC = 0; + HS_DMA_END = 0; + BlockNum_HSMMC = 0; + rd_cnt_HSMMC = 0; + ReadBlockCnt_INT = 0; + +// printf("\nHS-MMC block Read test: %d, 0x%x 0x%x\n", test, start_blk, blknum); + + BlockNum_HSMMC = blknum; + + blksize = Card_OneBlockSize_ver1; + +#if 0 + Rx_buffer_HSMMC = (u32 *) SDI_Rx_buffer_HSMMC; + for (i = 0; i < (blksize * BlockNum_HSMMC) / 4; i++) + *(Rx_buffer_HSMMC + i) = 0x0; +#endif + 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(BlockNum_HSMMC); // 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); +// puts("\nDMA Read End\n"); + + HS_DMA_END = 0; + BlockNum_HSMMC = 0; + rd_cnt_HSMMC = 0; + ReadBlockCnt_INT = 0; + + return 0; +} diff --git a/qiboot/src/cpu/s3c6410/hs_mmc.h b/qiboot/src/cpu/s3c6410/hs_mmc.h new file mode 100644 index 0000000..f1218ce --- /dev/null +++ b/qiboot/src/cpu/s3c6410/hs_mmc.h @@ -0,0 +1,40 @@ +#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__*/ diff --git a/qiboot/src/cpu/s3c6410/qi.lds b/qiboot/src/cpu/s3c6410/qi.lds index 888972a..dbc9aa8 100644 --- a/qiboot/src/cpu/s3c6410/qi.lds +++ b/qiboot/src/cpu/s3c6410/qi.lds @@ -29,35 +29,44 @@ 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 0x0c000000 : AT ( 0 ) + .text + __steppingstone : + AT (0) { src/cpu/s3c6410/start.o (.text .rodata* .data) src/cpu/s3c6410/start_qi.o (.text .rodata* .data) src/cpu/s3c6410/serial-s3c64xx.o (.text .rodata* .data) src/cpu/s3c6410/tla01.o (.text .rodata* .data) - src/ctype.o (.text .rodata* .data) - src/phase2.o (.text .rodata* .data) + src/cpu/s3c6410/hs_mmc.o (.text .rodata* .data) src/utils.o (.text .rodata* .data) + src/ctype.o (.text .rodata* .data) } -/* . = ALIGN(4); - .everything_else ADDR (.text) + SIZEOF (.text) + 0x53000000 : - AT ( ADDR (.text) + SIZEOF (.text) ) { *(.text .rodata* .data) } + . = ALIGN(4); + .everything_else + __system_ram_start + 0x3000000 + SIZEOF(.text) : + AT (SIZEOF(.text)) + { + *(.text .rodata* .data) + } -*/ - . = 0x53800000 ; -/* . = 0x0c001900 ; */ - __bss_start = .; - .bss_6410 (NOLOAD) : - { - * (.bss) - } + + __bss_start = __system_ram_start + 0x03800000; + .bss_6410 + __bss_start (NOLOAD) : + AT (SIZEOF(.text) + SIZEOF(.everything_else)) + { + * (.bss) + } _end = .; } diff --git a/qiboot/src/cpu/s3c6410/start_qi.c b/qiboot/src/cpu/s3c6410/start_qi.c index a39abc5..f29d994 100644 --- a/qiboot/src/cpu/s3c6410/start_qi.c +++ b/qiboot/src/cpu/s3c6410/start_qi.c @@ -27,6 +27,9 @@ #include #include +#define stringify2(s) stringify1(s) +#define stringify1(s) #s + extern void bootloader_second_phase(void); const struct board_api *boards[] = { @@ -43,6 +46,7 @@ void start_qi(void) { int flag = 0; int board = 0; + unsigned int sd_sectors = 0; /* * well, we can be running on this CPU two different ways. @@ -59,7 +63,38 @@ void start_qi(void) * under control of JTAG. */ - if (!is_jtag) + + /* 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; + else + this_board = boards[board++]; + + /* okay, do the critical port and serial init for our board */ + + this_board->port_init(); + + /* 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); + + if (!is_jtag) { /* * We got the first 4KBytes of the bootloader pulled into the * steppingstone SRAM for free. Now we pull the whole bootloader @@ -67,40 +102,25 @@ void start_qi(void) * * 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 + * everything else to expect to run from 0x53000000+. 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 */ - /* FIXME this ain't right for s3c6410 */ -#if 0 - if (nand_read_ll((u8 *)TEXT_BASE, 0, 32 * 1024 / 512) < 0) - goto unhappy; -#endif - /* 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++]; + extern unsigned int s3c6410_mmc_init(int verbose); + unsigned long s3c6410_mmc_bread(int dev_num, + unsigned long start_blk, unsigned long blknum, + void *dst); + sd_sectors = s3c6410_mmc_init(1); + s3c6410_mmc_bread(0, sd_sectors - 1026 - 16 - (256 * 2), + 256 * 2, (u8 *)0x53000000); } + /* * jump to bootloader_second_phase() running from DRAM copy */ bootloader_second_phase(); - - while(1) - ; - } diff --git a/qiboot/src/cpu/s3c6410/tla01.c b/qiboot/src/cpu/s3c6410/tla01.c index f4b9714..09422dc 100644 --- a/qiboot/src/cpu/s3c6410/tla01.c +++ b/qiboot/src/cpu/s3c6410/tla01.c @@ -137,6 +137,7 @@ void port_init_tla01(void) i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_DOWN1OUT, 0x2b); #endif + } /** @@ -166,13 +167,28 @@ static void putc_tla01(char c) serial_putc_s3c64xx(GTA03_DEBUG_UART, c); } +int sd_card_init_tla01(void) +{ + extern int s3c6410_mmc_init(int verbose); + + return s3c6410_mmc_init(1); +} + +int sd_card_block_read_tla01(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_tla01 = { .name = "TLA01", - .linux_machine_id = 1866, + .linux_machine_id = 1304 /*1866*/, .linux_mem_start = 0x50000000, .linux_mem_size = (128 * 1024 * 1024), .linux_tag_placement = 0x50000000 + 0x100, @@ -182,10 +198,11 @@ const struct board_api board_api_tla01 = { .putc = putc_tla01, .kernel_source = { [0] = { - .name = "SD Card", - .block_read = NULL, /* FIXME It's s3c6400 sd card*/ - .offset_blocks512_if_no_partition = 0x80000 / 512, - .filesystem = FS_RAW, + .name = "SD Card rootfs", + .block_read = sd_card_block_read_tla01, + .filesystem = FS_EXT2, + .partition_index = 2, + .filepath = "boot/uImage.bin", .commandline = "rootfstype=ext3 " \ "root=/dev/mmcblk0p1 " \ "console=ttySAC2,115200 " \ @@ -193,5 +210,17 @@ const struct board_api board_api_tla01 = { "init=/sbin/init "\ "ro" }, - }, + [1] = { + .name = "SD Card backup rootfs", + .block_read = sd_card_block_read_tla01, + .filesystem = FS_EXT2, + .partition_index = 3, + .filepath = "boot/uImage.bin", + .commandline = "rootfstype=ext3 " \ + "root=/dev/mmcblk0p1 " \ + "console=ttySAC2,115200 " \ + "loglevel=4 " \ + "init=/sbin/init "\ + "ro" + }, }, }; diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 679f206..29137a5 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -30,10 +30,6 @@ #include #include -#define stringify2(s) stringify1(s) -#define stringify1(s) #s - - unsigned long partition_offset_blocks = 0; unsigned long partition_length_blocks = 0; @@ -49,28 +45,8 @@ void bootloader_second_phase(void) { void (*the_kernel)(int zero, int arch, uint params); int kernel = 0; - const struct board_variant * board_variant; - - /* okay, do the critical port and serial init for our board */ - - this_board->port_init(); - - /* stick some hello messages on debug console */ - - puts("\n\n\nQi Bootloader "stringify2(QI_CPU)" " - stringify2(BUILD_HOST)" " - stringify2(BUILD_VERSION)" " - stringify2(BUILD_DATE)"\n"); - - puts("Copyright (C) 2008 Openmoko, Inc.\n"); - puts("This is free software; see the source for copying conditions.\n" - "There is NO warranty; not even for MERCHANTABILITY or " - "FITNESS FOR A PARTICULAR PURPOSE.\n\n Detected: "); - - puts(this_board->name); - puts(", "); - board_variant = (this_board->get_board_variant)(); - puts(board_variant->name); + const struct board_variant * board_variant = + (this_board->get_board_variant)(); /* we try the possible kernels for this board in order */ @@ -79,7 +55,7 @@ void bootloader_second_phase(void) while (this_kernel->name) { const char *p; struct tag *params = (struct tag *)this_board->linux_tag_placement; - void * kernel_dram = (void *)(TEXT_BASE - (8 * 1024 * 1024)); + void * kernel_dram = (void *)this_board->linux_mem_start + 0x8000; unsigned long crc; image_header_t *hdr; u32 kernel_size; @@ -150,7 +126,6 @@ void bootloader_second_phase(void) switch (this_kernel->filesystem) { case FS_EXT2: -#if 0 if (!ext2fs_mount()) { puts("Unable to mount ext2 filesystem\n"); this_kernel = &this_board-> @@ -168,7 +143,7 @@ void bootloader_second_phase(void) } ext2fs_read(kernel_dram, 4096); break; -#endif + case FS_FAT: /* FIXME */ case FS_RAW: @@ -206,11 +181,10 @@ void bootloader_second_phase(void) switch (this_kernel->filesystem) { case FS_EXT2: -#if 0 /* This read API always restarts from beginning */ ext2fs_read(kernel_dram, kernel_size); break; -#endif + case FS_FAT: /* FIXME */ case FS_RAW: From 7d1786f9a3229aad0785fd073872ea7962dee122 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:40 +0000 Subject: [PATCH 107/248] qi-change-machine-number-to-smdk.patch Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/tla01.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiboot/src/cpu/s3c6410/tla01.c b/qiboot/src/cpu/s3c6410/tla01.c index 09422dc..6c30e80 100644 --- a/qiboot/src/cpu/s3c6410/tla01.c +++ b/qiboot/src/cpu/s3c6410/tla01.c @@ -188,7 +188,7 @@ unsigned long s3c6410_mmc_bread(int dev_num, unsigned long blknr, unsigned long */ const struct board_api board_api_tla01 = { .name = "TLA01", - .linux_machine_id = 1304 /*1866*/, + .linux_machine_id = 1626 /*1866*/, .linux_mem_start = 0x50000000, .linux_mem_size = (128 * 1024 * 1024), .linux_tag_placement = 0x50000000 + 0x100, From aaa0586a8f5d698878ea2bb2a57611038a5ccfe5 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:40 +0000 Subject: [PATCH 108/248] qi-add-report-sector-for-ext2-errors.patch Signed-off-by: Andy Green --- qiboot/src/fs/dev.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/qiboot/src/fs/dev.c b/qiboot/src/fs/dev.c index ecb2a3a..694c8b1 100644 --- a/qiboot/src/fs/dev.c +++ b/qiboot/src/fs/dev.c @@ -96,6 +96,11 @@ int ext2fs_devread(int sector, int filesystem_block_log2, int byte_offset, int b if (this_kernel->block_read(buf, partition_offset_blocks + sector, block_len / SECTOR_SIZE) < 0) { puts(" ** ext2fs_devread() read error - block\n"); + printdec(partition_offset_blocks + sector); + puts(" "); + print32(block_len); + puts(" "); + print32(sector); return 0; } block_len = byte_len & ~(SECTOR_SIZE - 1); @@ -108,6 +113,11 @@ int ext2fs_devread(int sector, int filesystem_block_log2, int byte_offset, int b if (this_kernel->block_read(sec_buf, partition_offset_blocks + sector, 1) != 1) { puts(" ** ext2fs_devread() read error - last part\n"); + printdec(partition_offset_blocks + sector); + puts(" "); + print32(block_len); + puts(" "); + print32(sector); return 0; } memcpy (buf, sec_buf, byte_len); From fbd0c13ecde3bba7ce77b1471e28c5b385b78db5 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:40 +0000 Subject: [PATCH 109/248] qi-clean-remove-debug-line.patch Cosmetic console output cleaning Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/hs_mmc.c | 1 - qiboot/src/cpu/s3c6410/start_qi.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/qiboot/src/cpu/s3c6410/hs_mmc.c b/qiboot/src/cpu/s3c6410/hs_mmc.c index def5046..1ecbc50 100644 --- a/qiboot/src/cpu/s3c6410/hs_mmc.c +++ b/qiboot/src/cpu/s3c6410/hs_mmc.c @@ -504,7 +504,6 @@ unsigned int s3c6410_mmc_init (int verbose) resp = issue_command(SD_SEND_IF_COND, 0x000001aa, 0, MMC_CMD_BCR | MMC_RSP_R7); if (resp && ((s3c_hsmmc_readl(HM_RSPREG0) & 0xff) == 0xaa)) { - puts("SD 2.0\n"); card_type = CARDTYPE_SD20; /* 2.0 SD, may not be SDHC */ hcs = 0x40000000; } diff --git a/qiboot/src/cpu/s3c6410/start_qi.c b/qiboot/src/cpu/s3c6410/start_qi.c index f29d994..664b378 100644 --- a/qiboot/src/cpu/s3c6410/start_qi.c +++ b/qiboot/src/cpu/s3c6410/start_qi.c @@ -93,6 +93,7 @@ void start_qi(void) puts(this_board->name); puts(", "); puts((this_board->get_board_variant)()->name); + puts("\n"); if (!is_jtag) { /* From d83ef548d3d080b624adc8b3b747490d9ea5df5e Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:41 +0000 Subject: [PATCH 110/248] qi-add-build-script.patch Signed-off-by: Andy Green --- qiboot/build | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100755 qiboot/build diff --git a/qiboot/build b/qiboot/build new file mode 100755 index 0000000..64160ab --- /dev/null +++ b/qiboot/build @@ -0,0 +1,6 @@ +#!/bin/sh + +make clean && \ +make CPU=s3c6410 && \ +make CPU=s3c2442 + From 38ccc5078352f9efbd3788a73b6d852f10683c09 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Wed, 22 Oct 2008 01:41:59 +0100 Subject: [PATCH 111/248] qi-clean-s3c6410-hs_mmc.patch Signed-off-by: Andy Green --- qiboot/build | 5 ++++ qiboot/src/cpu/s3c2442/start_qi.c | 1 + qiboot/src/cpu/s3c6410/hs_mmc.c | 39 +++---------------------------- qiboot/src/phase2.c | 2 +- 4 files changed, 10 insertions(+), 37 deletions(-) diff --git a/qiboot/build b/qiboot/build index 64160ab..c9c7788 100755 --- a/qiboot/build +++ b/qiboot/build @@ -4,3 +4,8 @@ make clean && \ make CPU=s3c6410 && \ make CPU=s3c2442 +# 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 + diff --git a/qiboot/src/cpu/s3c2442/start_qi.c b/qiboot/src/cpu/s3c2442/start_qi.c index cfb5c61..6c19394 100644 --- a/qiboot/src/cpu/s3c2442/start_qi.c +++ b/qiboot/src/cpu/s3c2442/start_qi.c @@ -113,6 +113,7 @@ void start_qi(void) puts(this_board->name); puts(", "); puts((this_board->get_board_variant)()->name); + puts("\n"); /* * jump to bootloader_second_phase() running from DRAM copy diff --git a/qiboot/src/cpu/s3c6410/hs_mmc.c b/qiboot/src/cpu/s3c6410/hs_mmc.c index 1ecbc50..2224a38 100644 --- a/qiboot/src/cpu/s3c6410/hs_mmc.c +++ b/qiboot/src/cpu/s3c6410/hs_mmc.c @@ -31,27 +31,10 @@ /* Global variables */ -static u32 rd_cnt_HSMMC; -//static u32 wt_cnt_HSMMC; -static u32 BlockNum_HSMMC = 0; - -//static u32 WriteBlockCnt_INT = 0; -static u32 ReadBlockCnt_INT = 0; -//static u32 WRITEINT_DONE = 0; -//static u32 READINT_DONE = 0; -//static u32 COMPARE_INT_DONE = 0; -//static u32 CompareCnt_INT = 0; -//static u32 BufferBoundary_INT_Cnt = 0; - static u32 HS_DMA_END = 0; -//static u32 HS_CARD_DETECT = 0; - -//static u32 ocr_check = 0; -//static u32 mmc_card = 0; static u32 rca = 0; static ulong HCLK; -//static u32 card_mid = 0; int movi_hc = 1; /* sdhc style block indexing */ enum card_type card_type; @@ -392,7 +375,7 @@ static void check_dma_int (void) { u32 i; - for (i = 0; i < 0x1000000; 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); @@ -404,6 +387,7 @@ static void check_dma_int (void) break; } } + puts("check_dma_int: timeout\n"); } @@ -623,23 +607,10 @@ unsigned long s3c6410_mmc_bread(int dev_num, unsigned long start_blk, unsigned l u32 blksize; //j, , Addr_temp = start_blk; u32 dma = 0, cmd, multi; //, TotalReadByte, read_blk_cnt = 0; - rd_cnt_HSMMC = 0; HS_DMA_END = 0; - BlockNum_HSMMC = 0; - rd_cnt_HSMMC = 0; - ReadBlockCnt_INT = 0; - -// printf("\nHS-MMC block Read test: %d, 0x%x 0x%x\n", test, start_blk, blknum); - - BlockNum_HSMMC = blknum; blksize = Card_OneBlockSize_ver1; -#if 0 - Rx_buffer_HSMMC = (u32 *) SDI_Rx_buffer_HSMMC; - for (i = 0; i < (blksize * BlockNum_HSMMC) / 4; i++) - *(Rx_buffer_HSMMC + i) = 0x0; -#endif while (!check_card_status()); s3c_hsmmc_writew(s3c_hsmmc_readw(HM_NORINTSTSEN) & ~(DMA_STS_INT_EN | BLOCKGAP_EVENT_STS_INT_EN), HM_NORINTSTSEN); @@ -649,7 +620,7 @@ unsigned long s3c6410_mmc_bread(int dev_num, unsigned long start_blk, unsigned l dma = 1; set_blksize_register(7, 512); // Maximum DMA Buffer Size, Block Size - set_blkcnt_register(BlockNum_HSMMC); // Block Numbers to Write + set_blkcnt_register(blknum); // Block Numbers to Write if (movi_hc) set_arg_register(start_blk); // Card Start Block Address to Write @@ -671,12 +642,8 @@ unsigned long s3c6410_mmc_bread(int dev_num, unsigned long start_blk, unsigned l check_dma_int(); while (!HS_DMA_END); -// puts("\nDMA Read End\n"); HS_DMA_END = 0; - BlockNum_HSMMC = 0; - rd_cnt_HSMMC = 0; - ReadBlockCnt_INT = 0; return 0; } diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 29137a5..efca157 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -66,7 +66,7 @@ void bootloader_second_phase(void) /* eat leading white space */ for (p = this_kernel->commandline; *p == ' '; p++); - puts("\n\nTrying kernel: "); + puts("\nTrying kernel: "); puts(this_kernel->name); puts("\n"); From 4e7afacaef74677cff86b1654b899cc37f58dd89 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:41 +0000 Subject: [PATCH 112/248] qi-add-warn-on-timeouts.patch Just let us know if we ever have a timeout situation Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/hs_mmc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qiboot/src/cpu/s3c6410/hs_mmc.c b/qiboot/src/cpu/s3c6410/hs_mmc.c index 2224a38..c87a1f7 100644 --- a/qiboot/src/cpu/s3c6410/hs_mmc.c +++ b/qiboot/src/cpu/s3c6410/hs_mmc.c @@ -379,14 +379,15 @@ static void check_dma_int (void) if (s3c_hsmmc_readw(HM_NORINTSTS) & 0x0002) { HS_DMA_END = 1; s3c_hsmmc_writew(s3c_hsmmc_readw(HM_NORINTSTS) | 0x0002, HM_NORINTSTS); - break; + return; } if (s3c_hsmmc_readw(HM_NORINTSTS) & 0x8000) { puts("error found: "); print32(s3c_hsmmc_readw(HM_ERRINTSTS)); - break; + return; } } + puts("check_dma_int: timeout\n"); } From c44ce29cb4f0ce16d168bd4ff0dfbbfcea3d23ef Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:41 +0000 Subject: [PATCH 113/248] qi-high-loglevel-tla01.patch Currently interested in dmesg stuff on console Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/tla01.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qiboot/src/cpu/s3c6410/tla01.c b/qiboot/src/cpu/s3c6410/tla01.c index 6c30e80..b40f977 100644 --- a/qiboot/src/cpu/s3c6410/tla01.c +++ b/qiboot/src/cpu/s3c6410/tla01.c @@ -206,7 +206,7 @@ const struct board_api board_api_tla01 = { .commandline = "rootfstype=ext3 " \ "root=/dev/mmcblk0p1 " \ "console=ttySAC2,115200 " \ - "loglevel=4 " \ + "loglevel=8 " \ "init=/sbin/init "\ "ro" }, @@ -219,7 +219,7 @@ const struct board_api board_api_tla01 = { .commandline = "rootfstype=ext3 " \ "root=/dev/mmcblk0p1 " \ "console=ttySAC2,115200 " \ - "loglevel=4 " \ + "loglevel=8 " \ "init=/sbin/init "\ "ro" }, }, From 9b5a1a65db4573a48e03dff5f67a256ec9440bb2 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:41 +0000 Subject: [PATCH 114/248] qi-fix-return-ext2-dev-last-sector.patch There was a bug about dealing with last ext2 sector of file because we failed to return the number of sectors pulled Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/hs_mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiboot/src/cpu/s3c6410/hs_mmc.c b/qiboot/src/cpu/s3c6410/hs_mmc.c index c87a1f7..485d2a7 100644 --- a/qiboot/src/cpu/s3c6410/hs_mmc.c +++ b/qiboot/src/cpu/s3c6410/hs_mmc.c @@ -646,5 +646,5 @@ unsigned long s3c6410_mmc_bread(int dev_num, unsigned long start_blk, unsigned l HS_DMA_END = 0; - return 0; + return blknum; } From fe884c6d1024309149fe47573b98099cbe586ac3 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:41 +0000 Subject: [PATCH 115/248] qi-add-initrd-support.patch Signed-off-by: Andy Green --- qiboot/include/qi.h | 1 + qiboot/src/phase2.c | 115 ++++++++++++++++++++++++++------------------ 2 files changed, 68 insertions(+), 48 deletions(-) diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index 7b03687..a6c5b59 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -46,6 +46,7 @@ enum filesystem { 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); diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index efca157..3056aa6 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -35,11 +35,50 @@ unsigned long partition_length_blocks = 0; struct kernel_source const * this_kernel = 0; +const int INITRD_OFFSET = (8 * 1024 * 1024); + int raise(int n) { return 0; } +int read_file(const char * filepath, u8 * destination, int size) +{ + unsigned int len = size; + + switch (this_kernel->filesystem) { + case FS_EXT2: + if (!ext2fs_mount()) { + puts("Unable to mount ext2 filesystem\n"); + return -1; + } + puts(" EXT2 open: "); + puts(filepath); + puts("\n"); + len = ext2fs_open(filepath); + if (len < 0) { + puts("Open failed\n"); + return -1; + } + ext2fs_read((char *)destination, size); + break; + + case FS_FAT: + /* FIXME */ + case FS_RAW: + puts(" RAW open: +"); + printdec(partition_offset_blocks); + puts(" 512-byte blocks\n"); + if (this_kernel->block_read(destination, + partition_offset_blocks, size >> 9) < 0) { + puts ("Bad kernel header\n"); + return -1; + } + break; + } + + return len; +} void bootloader_second_phase(void) { @@ -47,6 +86,7 @@ void bootloader_second_phase(void) int kernel = 0; const struct board_variant * board_variant = (this_board->get_board_variant)(); + unsigned int initramfs_len = 0; /* we try the possible kernels for this board in order */ @@ -124,40 +164,11 @@ void bootloader_second_phase(void) partition_offset_blocks = this_kernel->offset_blocks512_if_no_partition; - switch (this_kernel->filesystem) { - case FS_EXT2: - if (!ext2fs_mount()) { - puts("Unable to mount ext2 filesystem\n"); - this_kernel = &this_board-> - kernel_source[kernel++]; - continue; - } - puts(" EXT2 open: "); - puts(this_kernel->filepath); - puts("\n"); - if (ext2fs_open(this_kernel->filepath) < 0) { - puts("Open failed\n"); - this_kernel = &this_board-> - kernel_source[kernel++]; - continue; - } - ext2fs_read(kernel_dram, 4096); - break; + /* pull the kernel image */ - case FS_FAT: - /* FIXME */ - case FS_RAW: - puts(" RAW open: +"); - printdec(partition_offset_blocks); - puts(" 512-byte blocks\n"); - if (this_kernel->block_read(kernel_dram, - partition_offset_blocks, 8) < 0) { - puts ("Bad kernel header\n"); - this_kernel = &this_board-> - kernel_source[kernel++]; - continue; - } - break; + if (read_file(this_kernel->filepath, kernel_dram, 4096) < 0) { + this_kernel = &this_board->kernel_source[kernel++]; + continue; } hdr = (image_header_t *)kernel_dram; @@ -179,24 +190,22 @@ void bootloader_second_phase(void) kernel_size = ((__be32_to_cpu(hdr->ih_size) + sizeof(image_header_t) + 2048) & ~(2048 - 1)); - switch (this_kernel->filesystem) { - case FS_EXT2: - /* This read API always restarts from beginning */ - ext2fs_read(kernel_dram, kernel_size); - break; + if (read_file(this_kernel->filepath, kernel_dram, + kernel_size) < 0) { + this_kernel = &this_board->kernel_source[kernel++]; + continue; + } - case FS_FAT: - /* FIXME */ - case FS_RAW: - if ((this_kernel->block_read)( - kernel_dram, partition_offset_blocks, - kernel_size >> 9) < 0) { - puts ("Bad kernel read\n"); - this_kernel = &this_board-> - kernel_source[kernel++]; + /* initramfs if needed */ + + if (this_kernel->initramfs_filepath) { + initramfs_len = read_file(this_kernel->initramfs_filepath, + (u8 *)this_board->linux_mem_start + INITRD_OFFSET, 16 * 1024 * 1024); + if (initramfs_len < 0) { + puts("initramfs load failed\n"); + this_kernel = &this_board->kernel_source[kernel++]; continue; } - break; } puts(" Cmdline: "); @@ -244,6 +253,16 @@ void bootloader_second_phase(void) params->u.mem.size = this_board->linux_mem_size; params = tag_next(params); + if (this_kernel->initramfs_filepath) { + /* INITRD2 tag */ + params->hdr.tag = ATAG_INITRD2; + params->hdr.size = tag_size (tag_initrd); + params->u.initrd.start = this_board->linux_mem_start + + INITRD_OFFSET; + params->u.initrd.size = initramfs_len; + params = tag_next(params); + } + /* kernel commandline */ if (*p) { From 2c83dc66366beebefaaa9af4c3a679fa0d1a21f2 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:41 +0000 Subject: [PATCH 116/248] qi-add-initrd-tla01.patch Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/tla01.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/qiboot/src/cpu/s3c6410/tla01.c b/qiboot/src/cpu/s3c6410/tla01.c index b40f977..e53e6bd 100644 --- a/qiboot/src/cpu/s3c6410/tla01.c +++ b/qiboot/src/cpu/s3c6410/tla01.c @@ -203,12 +203,9 @@ const struct board_api board_api_tla01 = { .filesystem = FS_EXT2, .partition_index = 2, .filepath = "boot/uImage.bin", - .commandline = "rootfstype=ext3 " \ - "root=/dev/mmcblk0p1 " \ - "console=ttySAC2,115200 " \ - "loglevel=8 " \ - "init=/sbin/init "\ - "ro" + .initramfs_filepath = "boot/initramfs.gz", + .commandline = "console=ttySAC0,115200 " \ + "loglevel=8 init=/bin/sh root=/dev/ram ramdisk_size=6000000" }, [1] = { .name = "SD Card backup rootfs", @@ -216,11 +213,8 @@ const struct board_api board_api_tla01 = { .filesystem = FS_EXT2, .partition_index = 3, .filepath = "boot/uImage.bin", - .commandline = "rootfstype=ext3 " \ - "root=/dev/mmcblk0p1 " \ - "console=ttySAC2,115200 " \ - "loglevel=8 " \ - "init=/sbin/init "\ - "ro" + .initramfs_filepath = "boot/initramfs.gz", + .commandline = "console=ttySAC0,115200 " \ + "loglevel=8 init=/bin/sh " }, }, }; From b0d8b1535e5c9d968675dedc11854097faeeffa5 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:41 +0000 Subject: [PATCH 117/248] qi-rename-tla01-gta03.patch TLA01 is officially GTA03 now :-) Signed-off-by: Andy Green --- qiboot/{gta03-qi.ocd => gta02-qi.ocd} | 2 +- qiboot/include/neo_gta03.h | 12 +- qiboot/include/neo_tla01.h | 28 -- qiboot/src/cpu/s3c2442/gta03.c | 289 -------------------- qiboot/src/cpu/s3c2442/start_qi.c | 1 - qiboot/src/cpu/s3c6410/{tla01.c => gta03.c} | 45 +-- qiboot/src/cpu/s3c6410/qi.lds | 2 +- qiboot/src/cpu/s3c6410/start_qi.c | 4 +- 8 files changed, 33 insertions(+), 350 deletions(-) rename qiboot/{gta03-qi.ocd => gta02-qi.ocd} (96%) delete mode 100644 qiboot/include/neo_tla01.h delete mode 100644 qiboot/src/cpu/s3c2442/gta03.c rename qiboot/src/cpu/s3c6410/{tla01.c => gta03.c} (89%) diff --git a/qiboot/gta03-qi.ocd b/qiboot/gta02-qi.ocd similarity index 96% rename from qiboot/gta03-qi.ocd rename to qiboot/gta02-qi.ocd index 7513767..9d2cf1f 100755 --- a/qiboot/gta03-qi.ocd +++ b/qiboot/gta02-qi.ocd @@ -1,4 +1,4 @@ -# gta03 Qi script +# gta02 Qi script # Andy Green reset halt diff --git a/qiboot/include/neo_gta03.h b/qiboot/include/neo_gta03.h index a01972e..110b795 100644 --- a/qiboot/include/neo_gta03.h +++ b/qiboot/include/neo_gta03.h @@ -1,8 +1,8 @@ /* - * (C) Copyright 2008 OpenMoko, Inc. - * Author: Matt Hsu + * (C) Copyright 2007 OpenMoko, Inc. + * Author: xiangfu liu * - * Configuation settings for the Openmoko GTA03 Linux GSM phone + * 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 @@ -20,13 +20,9 @@ * MA 02111-1307 USA */ -#ifndef __CONFIG_GTA03_H -#define __CONFIG_GTA03_H #ifndef __ASM_MODE__ #include extern const struct board_api board_api_gta03; #endif -#define TEXT_BASE 0x33000000 - -#endif /* __CONFIG_GTA03_H */ +#define TEXT_BASE_GTA03 0x53000000 diff --git a/qiboot/include/neo_tla01.h b/qiboot/include/neo_tla01.h deleted file mode 100644 index 6d9ca72..0000000 --- a/qiboot/include/neo_tla01.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * (C) Copyright 2007 OpenMoko, Inc. - * Author: xiangfu liu - * - * 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 -extern const struct board_api board_api_tla01; -#endif - -#define TEXT_BASE_TLA01 0x53000000 diff --git a/qiboot/src/cpu/s3c2442/gta03.c b/qiboot/src/cpu/s3c2442/gta03.c deleted file mode 100644 index 73fa268..0000000 --- a/qiboot/src/cpu/s3c2442/gta03.c +++ /dev/null @@ -1,289 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#define GTA03_DEBUG_UART 2 - -#define PCF50633_I2C_ADS 0x73 - - -static const struct board_variant board_variants[] = { - [0] = { - .name = "EVB PCB", - .machine_revision = 0x010, - }, -}; - -void port_init_gta03(void) -{ - unsigned int * MPLLCON = (unsigned int *)0x4c000004; - unsigned int * UPLLCON = (unsigned int *)0x4c000008; - unsigned int * CLKDIVN = (unsigned int *)0x4c000014; - - //CAUTION:Follow the configuration order for setting the ports. - // 1) setting value(GPnDAT) - // 2) setting control register (GPnCON) - // 3) configure pull-up 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 = 0x007F8FFF; - /* - * ===* 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 = 0x00145554; - rGPBDAT |= (1 <<9 ); /* USB_PULLUP */ - rGPBUP = 0x000007FF; - /* - * === 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 = 0xAAA776E9; - rGPCUP = 0x0000FFFF; - rGPCDAT |= (1 << 9); /* WLAN_nRESET pull high */ - /* - * === 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 = 0xAAA0AAA5; - rGPDUP = 0x0000FFFF; - /* - * === 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; - /* - * === 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 - */ - rGPFCON = 0x0000AAAA; - rGPFUP = 0x000000FF; - - /* - * === 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 = 0x02A9FE5A; - rGPGUP = 0x0000FFFF; - - /* - * === 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 - */ - /* pulldown on GPH08: UEXTCLK, just floats! - * pulldown GPH0 -- nCTS0 / RTS_MODEM -- floats when GSM off - * pulldown GPH3 -- RXD[0] / TX_MODEM -- floats when GSM off - */ - rGPHCON = 0x0019A0AA; - rGPHUP = 0x000007FF; - - /* pulldown on GPJ00: input, just floats! */ - /* pulldown on GPJ07: WLAN module WLAN_GPIO0, no ext pull */ - rGPJCON = 0x02AAAAAA; - rGPJUP = 0x1FFFF; - - /* - * We have to talk to the PMU a little bit - */ - - /* We need SD Card rail (HCLDO) at 3.0V */ - i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_HCLDOOUT, - 21); - - /* switch HCLDO on */ - i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_HCLDOENA, 1); - - /* push DOWN1 (CPU Core rail) to 1.7V, allowing 533MHz */ - i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_DOWN1OUT, - 0x2b); - - /* change CPU clocking to 533MHz 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 = ((169 << 12) + (2 << 4) + 1); - - - serial_init_115200_s3c24xx(GTA03_DEBUG_UART, 66 /*MHz PCLK */); -} - -/** - * returns PCB revision information in b0, d8, d9 - * GTA03 EVB returns 0x000 - * GTA03 returns 0x001 - */ - -int gta03_get_pcb_revision(void) -{ - int n; - u32 u; - - /* make B0 inputs */ - rGPBCON &= ~0x00000003; - /* D8 and D9 inputs */ - rGPDCON &= ~0x000f0000; - - /* delay after changing pulldowns */ - u = rGPBDAT; - u = rGPDDAT; - - /* read the version info */ - u = rGPBDAT; - n = (u >> (0 - 0))& 0x001; - u = rGPDDAT; - n |= (u >> (8 -1)) & 0x002; - n |= (u >> (9 - 2)) & 0x004; - - /* - * when not being interrogated, all of the revision GPIO - * are set to output - */ - /* make B0 high ouput */ - rGPBCON |= 0x00000001; - /* D8 and D9 high ouputs */ - rGPDCON |= 0x00050000; - - return n; - -} - -const struct board_variant const * get_board_variant_gta03(void) -{ - return &board_variants[gta03_get_pcb_revision()]; -} - -int is_this_board_gta03(void) -{ - /* FIXME: find something gta03 specific */ - return 1; -} - -static void putc_gta03(char c) -{ - serial_putc_s3c24xx(GTA03_DEBUG_UART, c); -} - -int sd_card_init_gta03(void) -{ - return s3c24xx_mmc_init(1); -} - -int sd_card_block_read_gta03(unsigned char * buf, unsigned long start512, - int blocks512) -{ - return s3c24xx_mmc_bread(0, start512, blocks512, buf); -} - - - -/* - * our API for bootloader on this machine - */ -const struct board_api board_api_gta03 = { - .name = "GTA03-2442", - .linux_machine_id = 1866, - .linux_mem_start = 0x30000000, - .linux_mem_size = (128 * 1024 * 1024), - .linux_tag_placement = 0x30000000 + 0x100, - .get_board_variant = get_board_variant_gta03, - .is_this_board = is_this_board_gta03, - .port_init = port_init_gta03, - .putc = putc_gta03, - /* these are the ways we could boot GTA03 in order to try */ - .kernel_source = { - [0] = { - .name = "SD Card EXT2 Kernel", - .block_init = sd_card_init_gta03, - .block_read = sd_card_block_read_gta03, - .partition_index = 1, - .filesystem = FS_EXT2, - .filepath = "boot/uImage.bin", - .commandline = "mtdparts=physmap-flash:-(nor);" \ - "neo1973-nand:" \ - "0x00040000(qi)," \ - "0x00040000(cmdline)," \ - "0x00800000(backupkernel)," \ - "0x000a0000(extra)," \ - "0x00040000(identity)," \ - "0x0f6a0000(backuprootfs) " \ - "rootfstype=ext2 " \ - "root=/dev/mmcblk0p1 " \ - "console=ttySAC2,115200 " \ - "loglevel=4 " \ - "init=/sbin/init "\ - "ro" - }, - [1] = { - .name = "NAND Kernel", - .block_read = nand_read_ll, - .offset_blocks512_if_no_partition = 0x80000 / 512, - .filesystem = FS_RAW, - .commandline = "mtdparts=neo1973-nand:" \ - "0x00040000(qi)," \ - "0x00040000(cmdline)," \ - "0x00800000(backupkernel)," \ - "0x000a0000(extra)," \ - "0x00040000(identity)," \ - "0x0f6a0000(backuprootfs) " \ - "rootfstype=jffs2 " \ - "root=/dev/mtdblock6 " \ - "console=ttySAC2,115200 " \ - "loglevel=4 " \ - "init=/sbin/init "\ - "ro" - }, - }, -}; diff --git a/qiboot/src/cpu/s3c2442/start_qi.c b/qiboot/src/cpu/s3c2442/start_qi.c index 6c19394..38a95ba 100644 --- a/qiboot/src/cpu/s3c2442/start_qi.c +++ b/qiboot/src/cpu/s3c2442/start_qi.c @@ -37,7 +37,6 @@ extern void bootloader_second_phase(void); const struct board_api *boards[] = { &board_api_gta02, - &board_api_gta03, NULL /* always last */ }; diff --git a/qiboot/src/cpu/s3c6410/tla01.c b/qiboot/src/cpu/s3c6410/gta03.c similarity index 89% rename from qiboot/src/cpu/s3c6410/tla01.c rename to qiboot/src/cpu/s3c6410/gta03.c index e53e6bd..a6766d8 100644 --- a/qiboot/src/cpu/s3c6410/tla01.c +++ b/qiboot/src/cpu/s3c6410/gta03.c @@ -1,5 +1,5 @@ #include -#include +#include #include //#include //#include @@ -13,11 +13,15 @@ static const struct board_variant board_variants[] = { [0] = { .name = "SMDK", - .machine_revision = 0x010, + .machine_revision = 0, }, + [1] = { + .name = "GTA03 EVT1", + .machine_revision = 1 + } }; -void port_init_tla01(void) +void port_init_gta03(void) { #if 0 unsigned int * MPLLCON = (unsigned int *)0x4c000004; @@ -146,35 +150,35 @@ void port_init_tla01(void) * GTA03 returns 0x001 */ -int tla01_get_pcb_revision(void) +int gta03_get_pcb_revision(void) { - return 0; + return 0; /* always SMDK right now */ } -const struct board_variant const * get_board_variant_tla01(void) +const struct board_variant const * get_board_variant_gta03(void) { - return &board_variants[tla01_get_pcb_revision()]; + return &board_variants[gta03_get_pcb_revision()]; } -int is_this_board_tla01(void) +int is_this_board_gta03(void) { - /* FIXME: find something tla01 specific */ + /* FIXME: find something gta03 specific */ return 1; } -static void putc_tla01(char c) +static void putc_gta03(char c) { serial_putc_s3c64xx(GTA03_DEBUG_UART, c); } -int sd_card_init_tla01(void) +int sd_card_init_gta03(void) { extern int s3c6410_mmc_init(int verbose); return s3c6410_mmc_init(1); } -int sd_card_block_read_tla01(unsigned char * buf, unsigned long start512, +int sd_card_block_read_gta03(unsigned char * buf, unsigned long start512, int blocks512) { unsigned long s3c6410_mmc_bread(int dev_num, unsigned long blknr, unsigned long blkcnt, @@ -186,20 +190,20 @@ unsigned long s3c6410_mmc_bread(int dev_num, unsigned long blknr, unsigned long /* * our API for bootloader on this machine */ -const struct board_api board_api_tla01 = { - .name = "TLA01", +const struct board_api board_api_gta03 = { + .name = "GTA03", .linux_machine_id = 1626 /*1866*/, .linux_mem_start = 0x50000000, .linux_mem_size = (128 * 1024 * 1024), .linux_tag_placement = 0x50000000 + 0x100, - .get_board_variant = get_board_variant_tla01, - .is_this_board = is_this_board_tla01, - .port_init = port_init_tla01, - .putc = putc_tla01, + .get_board_variant = get_board_variant_gta03, + .is_this_board = is_this_board_gta03, + .port_init = port_init_gta03, + .putc = putc_gta03, .kernel_source = { [0] = { .name = "SD Card rootfs", - .block_read = sd_card_block_read_tla01, + .block_read = sd_card_block_read_gta03, .filesystem = FS_EXT2, .partition_index = 2, .filepath = "boot/uImage.bin", @@ -209,7 +213,7 @@ const struct board_api board_api_tla01 = { }, [1] = { .name = "SD Card backup rootfs", - .block_read = sd_card_block_read_tla01, + .block_read = sd_card_block_read_gta03, .filesystem = FS_EXT2, .partition_index = 3, .filepath = "boot/uImage.bin", @@ -218,3 +222,4 @@ const struct board_api board_api_tla01 = { "loglevel=8 init=/bin/sh " }, }, }; + diff --git a/qiboot/src/cpu/s3c6410/qi.lds b/qiboot/src/cpu/s3c6410/qi.lds index dbc9aa8..d148c86 100644 --- a/qiboot/src/cpu/s3c6410/qi.lds +++ b/qiboot/src/cpu/s3c6410/qi.lds @@ -45,7 +45,7 @@ SECTIONS src/cpu/s3c6410/start.o (.text .rodata* .data) src/cpu/s3c6410/start_qi.o (.text .rodata* .data) src/cpu/s3c6410/serial-s3c64xx.o (.text .rodata* .data) - src/cpu/s3c6410/tla01.o (.text .rodata* .data) + src/cpu/s3c6410/gta03.o (.text .rodata* .data) src/cpu/s3c6410/hs_mmc.o (.text .rodata* .data) src/utils.o (.text .rodata* .data) src/ctype.o (.text .rodata* .data) diff --git a/qiboot/src/cpu/s3c6410/start_qi.c b/qiboot/src/cpu/s3c6410/start_qi.c index 664b378..a12a512 100644 --- a/qiboot/src/cpu/s3c6410/start_qi.c +++ b/qiboot/src/cpu/s3c6410/start_qi.c @@ -25,7 +25,7 @@ #include -#include +#include #define stringify2(s) stringify1(s) #define stringify1(s) #s @@ -33,7 +33,7 @@ extern void bootloader_second_phase(void); const struct board_api *boards[] = { - &board_api_tla01, + &board_api_gta03, NULL /* always last */ }; From ade0e093da3472e9d21332fd567aac6b1d45af02 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:41 +0000 Subject: [PATCH 118/248] qi-return-to-400MHz-boot-for-now.patch Not ready for 200MHz boot yet -- but will be soon, cpufreq is coming to upstream 2442 kernel it seems. Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/gta02.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 1bda6bf..38fc5cf 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -32,8 +32,8 @@ #include #define GTA02_DEBUG_UART 2 - #define PCF50633_I2C_ADS 0x73 +#define BOOST_TO_400MHZ 1 struct pcf50633_init { u8 index; @@ -92,7 +92,7 @@ static const struct board_variant board_variants[] = { void port_init_gta02(void) { -#if 0 +#if BOOST_TO_400MHZ unsigned int * MPLLCON = (unsigned int *)0x4c000004; unsigned int * UPLLCON = (unsigned int *)0x4c000008; unsigned int * CLKDIVN = (unsigned int *)0x4c000014; @@ -226,7 +226,7 @@ void port_init_gta02(void) i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, pcf50633_init[n].index, pcf50633_init[n].value); -#if 0 +#if BOOST_TO_400MHZ /* change CPU clocking to 400MHz 1:4:8 */ /* clock divide 1:4:8 - do it first */ From 39fc2afbf4250e7bfa0ea16e3dc684f43c24d197 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:41 +0000 Subject: [PATCH 119/248] qi-fix-ext2-inefficiency-bug.patch Naughty bug bug U-Boot ext2 implementation -- cut and paste of stanza above for indir1 check used for indir2 but not all the check was not updated. This removes hundreds of repeated reads of same sector during kernel load. Signed-off-by: Andy Green --- qiboot/src/fs/ext2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiboot/src/fs/ext2.c b/qiboot/src/fs/ext2.c index e09ca4a..acb979f 100644 --- a/qiboot/src/fs/ext2.c +++ b/qiboot/src/fs/ext2.c @@ -362,7 +362,7 @@ static int ext2fs_read_block(ext2fs_node_t node, int fileblock) { indir2_size = blksz; } if ((__le32_to_cpu(indir1_block[rblock / perblock]) << - log2_blksz) != indir1_blkno) { + log2_blksz) != indir2_blkno) { status = ext2fs_devread(__le32_to_cpu(indir1_block[rblock / perblock]), log2_blksz, 0, blksz, (char *) indir2_block); From f46dc9e4ab0f2bf5bf5aeeb36d764c67d034caca Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:41 +0000 Subject: [PATCH 120/248] qi-optimize-ext2.patch Little cleanup and new code that collects and defers contiguous sector reads into one potentially more efficient larger sequential read action. This matters for example on SD Card protocol. Signed-off-by: Andy Green --- qiboot/src/fs/ext2.c | 73 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 15 deletions(-) diff --git a/qiboot/src/fs/ext2.c b/qiboot/src/fs/ext2.c index acb979f..21165a3 100644 --- a/qiboot/src/fs/ext2.c +++ b/qiboot/src/fs/ext2.c @@ -189,9 +189,6 @@ int indir2_blkno = -1; static int ext2fs_blockgroup (struct ext2_data *data, int group, struct ext2_block_group *blkgrp) { -#ifdef DEBUG - puts("ext2fs read blockgroup\n"); -#endif return ext2fs_devread ((__le32_to_cpu(data->sblock.first_data_block) + 1), LOG2_EXT2_BLOCK_SIZE(data), @@ -212,9 +209,6 @@ static int ext2fs_read_inode /* It is easier to calculate if the first inode is 0. */ ino--; -#ifdef DEBUG - puts("ext2fs read inode %d\n", ino); -#endif status = ext2fs_blockgroup(data, ino / __le32_to_cpu(sblock->inodes_per_group), @@ -375,9 +369,9 @@ static int ext2fs_read_block(ext2fs_node_t node, int fileblock) { } blknr = __le32_to_cpu(indir2_block[rblock % perblock]); } - /* Tripple indirect. */ + /* Triple indirect. */ else { - puts("** ext2fs doesn't support tripple indirect blocks. **\n"); + puts("** ext2fs doesn't support triple indirect blocks. **\n"); return -1; } #ifdef DEBUG @@ -387,13 +381,19 @@ static int ext2fs_read_block(ext2fs_node_t node, int fileblock) { } -int ext2fs_read_file - (ext2fs_node_t node, int pos, unsigned int len, char *buf) { +int ext2fs_read_file(ext2fs_node_t node, int pos, unsigned int len, char *buf) { int i; int blockcnt; int log2blocksize = LOG2_EXT2_BLOCK_SIZE(node->data); int blocksize = 1 <<(log2blocksize + DISK_SECTOR_BITS); unsigned int filesize = __le32_to_cpu(node->inode.size); + int previous_block_number = -1; + int delayed_start = 0; + int delayed_extent = 0; + int delayed_skipfirst = 0; + int delayed_next = 0; + char * delayed_buf = NULL; + int status; /* Adjust len so it we can't read past the end of the file. */ if (len > filesize) { @@ -435,14 +435,57 @@ int ext2fs_read_file if (blknr) { int status; - status = ext2fs_devread(blknr, 0 /* already accounted */, skipfirst, blockend, buf); - if (status == 0) - return -1; - } else - memset(buf, 0, blocksize - skipfirst); + if (previous_block_number != -1) { + if (delayed_next == blknr) { + delayed_extent += blockend; + delayed_next += blockend >> SECTOR_BITS; + } else { /* spill */ + status = ext2fs_devread(delayed_start, + 0, delayed_skipfirst, + delayed_extent, delayed_buf); + if (status == 0) + return -1; + previous_block_number = blknr; + delayed_start = blknr; + delayed_extent = blockend; + delayed_skipfirst = skipfirst; + delayed_buf = buf; + delayed_next = blknr + (blockend >> SECTOR_BITS); + } + } else { + previous_block_number = blknr; + delayed_start = blknr; + delayed_extent = blockend; + delayed_skipfirst = skipfirst; + delayed_buf = buf; + delayed_next = blknr + (blockend >> SECTOR_BITS); + } + } else { + if (previous_block_number != -1) { + /* spill */ + status = ext2fs_devread(delayed_start, + 0, delayed_skipfirst, + delayed_extent, delayed_buf); + if (status == 0) + return -1; + previous_block_number = -1; + } + memset(buf, 0, blocksize - skipfirst); + } buf += blocksize - skipfirst; } + + if (previous_block_number != -1) { + /* spill */ + status = ext2fs_devread(delayed_start, + 0, delayed_skipfirst, + delayed_extent, delayed_buf); + if (status == 0) + return -1; + previous_block_number = -1; + } + return(len); } From cff19a41ce03deca617b705ac69d33376e95eea1 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:41 +0000 Subject: [PATCH 121/248] qi-glamo-mmc-multiblock-read.patch Improve glamo-mmc so that it uses MMC_READ_MULTIPLE_BLOCK and copes with 64 blocks in one command (and STOP sent after each set), instead of sending a new command per-block Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/gta02.c | 4 ++-- qiboot/src/drivers/glamo-mmc.c | 33 +++++++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 38fc5cf..3f33957 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -400,7 +400,7 @@ const struct board_api board_api_gta02 = { "rootfstype=ext3 " \ "root=/dev/mmcblk0p1 " \ "console=ttySAC2,115200 " \ - "loglevel=8 " \ + "loglevel=4 " \ "init=/sbin/init "\ "ro" }, @@ -420,7 +420,7 @@ const struct board_api board_api_gta02 = { "rootfstype=jffs2 " \ "root=/dev/mtdblock6 " \ "console=ttySAC2,115200 " \ - "loglevel=3 " \ + "loglevel=8 " \ "init=/sbin/init "\ "ro" }, diff --git a/qiboot/src/drivers/glamo-mmc.c b/qiboot/src/drivers/glamo-mmc.c index 4df2ec6..be6b6e2 100644 --- a/qiboot/src/drivers/glamo-mmc.c +++ b/qiboot/src/drivers/glamo-mmc.c @@ -47,6 +47,9 @@ static int mmc_ready = 0; //static int wide = 0; static enum card_type card_type = CARDTYPE_NONE; + +#define MULTI_READ_BLOCKS_PER_COMMAND 64 + int mmc_read(unsigned long src, u8 *dst, int size); #define UNSTUFF_BITS(resp,start,size) \ @@ -422,6 +425,7 @@ int mmc_read(unsigned long src, u8 *dst, int size) int resp; u8 response[16]; int size_original = size; + int lump; if (((int)dst) & 1) { puts("Bad align on dst\n"); @@ -435,18 +439,23 @@ int mmc_read(unsigned long src, u8 *dst, int size) return resp; while (size) { + /* glamo mmc times out as this increases too much */ + lump = MULTI_READ_BLOCKS_PER_COMMAND; + if (lump > size) + lump = size; + switch (card_type) { case CARDTYPE_SDHC: /* block addressing */ - resp = mmc_cmd(MMC_READ_SINGLE_BLOCK, + resp = mmc_cmd(MMC_READ_MULTIPLE_BLOCK, src, MMC_CMD_ADTC | MMC_RSP_R1 | - MMC_DATA_READ, MMC_BLOCK_SIZE, 1, 0, + MMC_DATA_READ, MMC_BLOCK_SIZE, lump, 1, (u16 *)&response[0]); break; default: /* byte addressing */ - resp = mmc_cmd(MMC_READ_SINGLE_BLOCK, src * MMC_BLOCK_SIZE, + resp = mmc_cmd(MMC_READ_MULTIPLE_BLOCK, src * MMC_BLOCK_SIZE, MMC_CMD_ADTC | MMC_RSP_R1 | MMC_DATA_READ, - MMC_BLOCK_SIZE, 1, 0, + MMC_BLOCK_SIZE, lump, 1, (u16 *)&response[0]); break; } @@ -459,14 +468,22 @@ int mmc_read(unsigned long src, u8 *dst, int size) 0xff00) | 2, GLAMO_REG_CLOCK_GEN8); - do_pio_read((u16 *)dst, MMC_BLOCK_SIZE >> 1); + do_pio_read((u16 *)dst, lump * MMC_BLOCK_SIZE >> 1); if (size) - size--; + size -= lump; + + dst += lump * MMC_BLOCK_SIZE; + src += lump; + + resp = mmc_cmd(MMC_STOP_TRANSMISSION, 0, + MMC_CMD_AC | MMC_RSP_R1B, 0, 0, 0, + (u16 *)&response[0]); + if (resp) + return resp; - dst += MMC_BLOCK_SIZE; - src++; } + return size_original; } From 2e982c433da4d463a6a4f2ee95c42d90a21245cf Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:41 +0000 Subject: [PATCH 122/248] qi-add-memory-testing-routines.patch This adds the memory testing code to Qi. It tests the range of memory with several constants and then a 32-bit walking 1 pattern, and repeats forever. The entire main SDRAM can be tested due to the fact this runs out of steppingstone only and does not need to store anything outside of it. It introduces a steppingstone-based stack for use entirely in steppingstone. Signed-off-by: Andy Green --- qiboot/include/qi.h | 2 + qiboot/src/cpu/s3c2442/start.S | 14 ++-- qiboot/src/cpu/s3c6410/start.S | 9 ++ qiboot/src/memory-test.c | 145 +++++++++++++++++++++++++++++++++ 4 files changed, 165 insertions(+), 5 deletions(-) create mode 100644 qiboot/src/memory-test.c diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index a6c5b59..b9970a4 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -106,5 +106,7 @@ 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); + #endif diff --git a/qiboot/src/cpu/s3c2442/start.S b/qiboot/src/cpu/s3c2442/start.S index 9961d8f..eaab799 100644 --- a/qiboot/src/cpu/s3c2442/start.S +++ b/qiboot/src/cpu/s3c2442/start.S @@ -50,11 +50,6 @@ _start_armboot: _TEXT_BASE: .word TEXT_BASE -processor_id: - .word 0 - .word 0x41129200 /* s3c2442 ID */ - .word 0x410fb760 /* s3c6410 ID */ - /* * These are defined in the board-specific linker script. */ @@ -65,6 +60,15 @@ _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: /* diff --git a/qiboot/src/cpu/s3c6410/start.S b/qiboot/src/cpu/s3c6410/start.S index 29a5713..3d63fc7 100644 --- a/qiboot/src/cpu/s3c6410/start.S +++ b/qiboot/src/cpu/s3c6410/start.S @@ -152,6 +152,15 @@ _bss_start: _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 diff --git a/qiboot/src/memory-test.c b/qiboot/src/memory-test.c new file mode 100644 index 0000000..4cdc8cc --- /dev/null +++ b/qiboot/src/memory-test.c @@ -0,0 +1,145 @@ +#include +#include + +int memory_test_const32(void * start, unsigned int length, u32 value) +{ + int errors = 0; + u32 * p = (u32 *)start; + u32 * pend = (u32 *)(start + length); + int count = length >> 2; + + puts("."); + + while (p < pend) + *p++ = value; + + p = (u32 *)start; + count = length >> 2; + + while (count--) + if (*p++ != value) { + puts("*** Error "); + print32((long)p - 4); + errors++; + } + + return errors; +} + +int memory_test_ads(void * start, unsigned int length, u32 mask) +{ + int errors = 0; + u32 * p = (u32 *)start; + u32 * pend = (u32 *)(start + length); + + puts("."); + + while (p < pend) + if ((u32)p & mask) + *p++ = 0xffffffff; + else + *p++ = 0; + + p = (u32 *)start; + + while (p < pend) { + if ((u32)p & mask) { + if (*p++ != 0xffffffff) { + puts("*** Error "); + print32((long)p - 4); + errors++; + } + } else { + if (*p++) { + puts("*** Error "); + print32((long)p - 4); + errors++; + } + } + } + return errors; +} + +int memory_test_walking1(void * start, unsigned int length) +{ + int errors = 0; + u32 value = 1; + + while (value) { + errors += memory_test_const32(start, length, value); + value <<= 1; + } + + return errors; +} + +/* negative runs == run forever */ + +void __memory_test(void * start, unsigned int length) +{ + int errors = 0; + int series = 0; + int mask; + + puts("\nMemory Testing 0x"); + print32((u32)start); + puts(" length "); + printdec(length >> 20); + puts(" MB\n"); + + while (1) { + puts(" Test series "); + printdec(series + 1); + puts(" "); + + /* these are looking at data issues, they flood the whole + * array with the same data + */ + + errors += memory_test_const32(start, length, 0x55555555); + errors += memory_test_const32(start, length, 0xaaaaaaaa); + errors += memory_test_const32(start, length, 0x55aa55aa); + errors += memory_test_const32(start, length, 0xaa55aa55); + errors += memory_test_const32(start, length, 0x00ff00ff); + errors += memory_test_const32(start, length, 0xff00ff00); + errors += memory_test_walking1(start, length); + + /* this is looking at addressing issues, it floods only + * addresses meeting a walking mask with 0xffffffff (the rest + * is zeroed), and makes sure all the bits are only seen where + * they were placed + */ + + mask = 1; + while (! (length & mask)) { + errors += memory_test_ads(start, length, mask); + mask = mask << 1; + } + + puts(" Total errors: "); + printdec(errors); + puts("\n"); + + series++; + } +} + + +void memory_test(void * start, unsigned int length) +{ + /* it's a small steppingstone stack from start.S */ + extern int _ss_stack; + + /* + * we won't be coming back from this, so just force our local stack to + * steppingstone out of the way of main memory test action + * + * then jump into the actual test + */ + asm volatile ( + "mov sp, %0\n" + : : "r" (&_ss_stack) + ); + + __memory_test(start, length); +} From 8d0a6cbd9fa821834ec314e323381ab9b1acbb98 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:41 +0000 Subject: [PATCH 123/248] qi-add-steppingstone-section-for-putc.patch We need putc even when we are operating entirely from steppingstone. Arrange that the board-specific putc code is in a section that goes into steppingstone, and adapt the utils.c putc() so that it no longer needs to indirect through the board_api struct that is in main memory. Signed-off-by: Andy Green --- qiboot/include/qi.h | 2 ++ qiboot/src/cpu/s3c2442/gta02.c | 2 +- qiboot/src/cpu/s3c2442/qi.lds | 16 ++++++++++------ qiboot/src/cpu/s3c2442/start_qi.c | 1 + qiboot/src/cpu/s3c6410/gta03.c | 2 +- qiboot/src/cpu/s3c6410/qi.lds | 16 +++++++++------- qiboot/src/cpu/s3c6410/start_qi.c | 3 ++- qiboot/src/utils.c | 26 +++++++++++++++----------- 8 files changed, 41 insertions(+), 27 deletions(-) diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index b9970a4..90d16cf 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -108,5 +108,7 @@ 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 diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 3f33957..23acefa 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -341,7 +341,7 @@ const struct board_variant const * get_board_variant_gta02(void) return &board_variants[gta02_get_pcb_revision() & 1]; } -static void putc_gta02(char c) +static __attribute__ (( section (".steppingstone") )) void putc_gta02(char c) { serial_putc_s3c24xx(GTA02_DEBUG_UART, c); } diff --git a/qiboot/src/cpu/s3c2442/qi.lds b/qiboot/src/cpu/s3c2442/qi.lds index 09da8bb..c23b447 100644 --- a/qiboot/src/cpu/s3c2442/qi.lds +++ b/qiboot/src/cpu/s3c2442/qi.lds @@ -37,12 +37,16 @@ SECTIONS . = ALIGN(4); .text : { - src/cpu/s3c2442/start.o (.text .rodata* .data) - src/cpu/s3c2442/lowlevel_init.o (.text .rodata* .data) - src/cpu/s3c2442/start_qi.o (.text .rodata* .data) - src/blink_led.o (.text .rodata* .data) - src/cpu/s3c2442/nand_read.o (.text .rodata* .data) - src/cpu/s3c2442/serial-s3c24xx.o (.text .rodata* .data) + 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/blink_led.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); diff --git a/qiboot/src/cpu/s3c2442/start_qi.c b/qiboot/src/cpu/s3c2442/start_qi.c index 38a95ba..8364a2d 100644 --- a/qiboot/src/cpu/s3c2442/start_qi.c +++ b/qiboot/src/cpu/s3c2442/start_qi.c @@ -98,6 +98,7 @@ void start_qi(void) } this_board->port_init(); + set_putc_func(this_board->putc); /* stick some hello messages on debug console */ diff --git a/qiboot/src/cpu/s3c6410/gta03.c b/qiboot/src/cpu/s3c6410/gta03.c index a6766d8..e925740 100644 --- a/qiboot/src/cpu/s3c6410/gta03.c +++ b/qiboot/src/cpu/s3c6410/gta03.c @@ -166,7 +166,7 @@ int is_this_board_gta03(void) return 1; } -static void putc_gta03(char c) +static __attribute__ (( section (".steppingstone") )) void putc_gta03(char c) { serial_putc_s3c64xx(GTA03_DEBUG_UART, c); } diff --git a/qiboot/src/cpu/s3c6410/qi.lds b/qiboot/src/cpu/s3c6410/qi.lds index d148c86..7a89334 100644 --- a/qiboot/src/cpu/s3c6410/qi.lds +++ b/qiboot/src/cpu/s3c6410/qi.lds @@ -42,13 +42,15 @@ SECTIONS __steppingstone : AT (0) { - src/cpu/s3c6410/start.o (.text .rodata* .data) - src/cpu/s3c6410/start_qi.o (.text .rodata* .data) - src/cpu/s3c6410/serial-s3c64xx.o (.text .rodata* .data) - src/cpu/s3c6410/gta03.o (.text .rodata* .data) - src/cpu/s3c6410/hs_mmc.o (.text .rodata* .data) - src/utils.o (.text .rodata* .data) - src/ctype.o (.text .rodata* .data) + 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/gta03.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); diff --git a/qiboot/src/cpu/s3c6410/start_qi.c b/qiboot/src/cpu/s3c6410/start_qi.c index a12a512..ac94b66 100644 --- a/qiboot/src/cpu/s3c6410/start_qi.c +++ b/qiboot/src/cpu/s3c6410/start_qi.c @@ -79,6 +79,7 @@ void start_qi(void) /* okay, do the critical port and serial init for our board */ this_board->port_init(); + set_putc_func(this_board->putc); /* stick some hello messages on debug console */ @@ -97,7 +98,7 @@ void start_qi(void) if (!is_jtag) { /* - * We got the first 4KBytes of the bootloader pulled into the + * We got the first 8KBytes of the bootloader pulled into the * steppingstone SRAM for free. Now we pull the whole bootloader * image into SDRAM. * diff --git a/qiboot/src/utils.c b/qiboot/src/utils.c index ffca1f5..fc1e668 100644 --- a/qiboot/src/utils.c +++ b/qiboot/src/utils.c @@ -23,10 +23,14 @@ #include #include -static u8 malloc_pool[100 * 1024]; -void * malloc_pointer = &malloc_pool[0]; +static void (*putc_func)(char) = NULL; +void set_putc_func(void (*p)(char)) +{ + putc_func = p; +} + size_t strlen(const char *s) { size_t n = 0; @@ -88,7 +92,7 @@ char *strchr(const char *s, int c) int puts(const char *string) { while (*string) - this_board->putc(*string++); + (putc_func)(*string++); return 1; } @@ -97,9 +101,9 @@ int puts(const char *string) void printnybble(unsigned char n) { if (n < 10) - this_board->putc('0' + n); + (putc_func)('0' + n); else - this_board->putc('a' + n - 10); + (putc_func)('a' + n - 10); } void print8(unsigned char n) @@ -122,13 +126,13 @@ void hexdump(unsigned char *start, int len) while (len > 0) { print32((int)start); - this_board->putc(':'); - this_board->putc(' '); + (putc_func)(':'); + (putc_func)(' '); for (n = 0; n < 16; n++) { print8(*start++); - this_board->putc(' '); + (putc_func)(' '); } - this_board->putc('\n'); + (putc_func)('\n'); len -= 16; } } @@ -152,7 +156,7 @@ void printdec(int n) int div = 0; if (n < 0) { - this_board->putc('-'); + (putc_func)('-'); n = -n; } @@ -163,7 +167,7 @@ void printdec(int n) n -= d[div]; } if (r || flag || (d[div] == 1)) { - this_board->putc('0' + r); + (putc_func)('0' + r); flag = 1; } div++; From c5d0a6379f81aa296a5159110815cce0042ff64b Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:42 +0000 Subject: [PATCH 124/248] qi-clean-split-utils.c-by-phase.patch Some of utils.c isn't used until the full Qi image has been loaded into memory, to save space in 4K steppingstone case on 2442, we split utils.c now so only the interesting routines for steppingstone time take up space there. Signed-off-by: Andy Green --- qiboot/include/qi.h | 1 + qiboot/src/utils-phase2.c | 111 ++++++++++++++++++++++++++++++++++++++ qiboot/src/utils.c | 79 +-------------------------- 3 files changed, 113 insertions(+), 78 deletions(-) create mode 100644 qiboot/src/utils-phase2.c diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index 90d16cf..1ddf9cb 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -25,6 +25,7 @@ #include #include +#define MALLOC_POOL_EXTENT (100 * 1024) #define u32 unsigned int #define u16 unsigned short diff --git a/qiboot/src/utils-phase2.c b/qiboot/src/utils-phase2.c new file mode 100644 index 0000000..f02d5b1 --- /dev/null +++ b/qiboot/src/utils-phase2.c @@ -0,0 +1,111 @@ +/* + * (C) Copyright 2008 Openmoko, Inc. + * Author: Andy Green + * + * Little utils for print and strings + * + * 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 +#include + +extern void (*putc_func)(char); + +/* + * malloc pool needs to be in phase 2 bss section, we have phase 1 bss in + * steppingstone to allow full memory range testing in C + */ +u8 malloc_pool[MALLOC_POOL_EXTENT]; +void * malloc_pointer = &malloc_pool[0]; + + +/* improbably simple malloc and free for small and non-intense allocation + * just moves the allocation ptr forward each time and ignores free + */ + +void *malloc(size_t size) +{ + void *p = malloc_pointer; + + malloc_pointer += (size & ~3) + 4; + + if (((u8 *)malloc_pointer - &malloc_pool[0]) > sizeof(malloc_pool)) { + puts("Ran out of malloc pool\n"); + while (1) + ; + } + + return p; +} + +void free(void *ptr) +{ +} + +char *strncpy(char *dest, const char *src, size_t n) +{ + char * dest_orig = dest; + + while (*src && n--) + *dest++ = *src++; + + if (n) + *dest = '\0'; + + return dest_orig; +} + + +int strcmp(const char *s1, const char *s2) +{ + while (1) { + if (*s1 != *s2) + return *s1 - *s2; + if (!*s1) + return 0; + s1++; + s2++; + } +} + +char *strchr(const char *s, int c) +{ + while ((*s) && (*s != c)) + s++; + + if (*s == c) + return (char *)s; + + return NULL; +} + +void hexdump(unsigned char *start, int len) +{ + int n; + + while (len > 0) { + print32((int)start); + (putc_func)(':'); + (putc_func)(' '); + for (n = 0; n < 16; n++) { + print8(*start++); + (putc_func)(' '); + } + (putc_func)('\n'); + len -= 16; + } +} diff --git a/qiboot/src/utils.c b/qiboot/src/utils.c index fc1e668..82f3e4a 100644 --- a/qiboot/src/utils.c +++ b/qiboot/src/utils.c @@ -23,7 +23,7 @@ #include #include -static void (*putc_func)(char) = NULL; +void (*putc_func)(char) = NULL; void set_putc_func(void (*p)(char)) @@ -52,43 +52,6 @@ char *strcpy(char *dest, const char *src) return dest_orig; } -char *strncpy(char *dest, const char *src, size_t n) -{ - char * dest_orig = dest; - - while (*src && n--) - *dest++ = *src++; - - if (n) - *dest = '\0'; - - return dest_orig; -} - - -int strcmp(const char *s1, const char *s2) -{ - while (1) { - if (*s1 != *s2) - return *s1 - *s2; - if (!*s1) - return 0; - s1++; - s2++; - } -} - -char *strchr(const char *s, int c) -{ - while ((*s) && (*s != c)) - s++; - - if (*s == c) - return (char *)s; - - return NULL; -} - int puts(const char *string) { while (*string) @@ -120,23 +83,6 @@ void print32(unsigned int u) print8(u); } -void hexdump(unsigned char *start, int len) -{ - int n; - - while (len > 0) { - print32((int)start); - (putc_func)(':'); - (putc_func)(' '); - for (n = 0; n < 16; n++) { - print8(*start++); - (putc_func)(' '); - } - (putc_func)('\n'); - len -= 16; - } -} - void printdec(int n) { int d[] = { @@ -195,29 +141,6 @@ void *memset(void *s, int c, size_t n) return s; } -/* improbably simple malloc and free for small and non-intense allocation - * just moves the allocation ptr forward each time and ignores free - */ - -void *malloc(size_t size) -{ - void *p = malloc_pointer; - - malloc_pointer += (size & ~3) + 4; - - if (((u8 *)malloc_pointer - &malloc_pool[0]) > sizeof(malloc_pool)) { - puts("Ran out of malloc pool\n"); - while (1) - ; - } - - return p; -} - -void free(void *ptr) -{ -} - int q; void udelay(int n) From 69de926cf409c508b4e5010820608c5f35104476 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:42 +0000 Subject: [PATCH 125/248] qi-memory-test-when-no-kernels.patch This makes a new behaviour for Qi, when there are no valid kernels then it performs the memory test. It means you can either move kernels out of the way to get the memory test, or make an SD Card just with normal Qi on it and no kernels to get a memory test. Signed-off-by: Andy Green --- qiboot/src/phase2.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 3056aa6..847dfc8 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -297,7 +297,20 @@ void bootloader_second_phase(void) /* none of the kernels worked out */ - puts("No usable kernel image found, we've had it :-(\n"); - while (1) - ; + puts("\nNo usable kernel image found\n"); + + /* + * sit there doing a memory test in this case. + * + * This phase 2 code will get destroyed but it's OK, we won't be + * coming back and the whole memory test and dependency functions are + * in phase 1 / steppingstone, so we can test entire memory range. + * + * It means we just boot with SD Card with kernel(s) renamed or removed + * to provoke memory test. + */ + + memory_test((void *)this_board->linux_mem_start, + this_board->linux_mem_size); + } From 736355ab4f9879fc7e20a25d0f5e597496d15413 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:42 +0000 Subject: [PATCH 126/248] qi-gta02-also-try-boot-sdcard-partition-2.patch This gives compatability with SD Cards using the old U-Boot scheme of an initial VFAT part for kernel and then ext2. If you put the kernel you actually want to use in /boot/uImage.bin in the ext2 partition, it can boot these cards then. Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/gta02.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 23acefa..3e5b02e 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -405,6 +405,28 @@ const struct board_api board_api_gta02 = { "ro" }, [1] = { + .name = "SD Card EXT2 Kernel", + .block_init = sd_card_init_gta02, + .block_read = sd_card_block_read_gta02, + .partition_index = 2, + .filesystem = FS_EXT2, + .filepath = "boot/uImage.bin", + .commandline = "mtdparts=physmap-flash:-(nor);" \ + "neo1973-nand:" \ + "0x00040000(qi)," \ + "0x00040000(cmdline)," \ + "0x00800000(backupkernel)," \ + "0x000a0000(extra)," \ + "0x00040000(identity)," \ + "0x0f6a0000(backuprootfs) " \ + "rootfstype=ext3 " \ + "root=/dev/mmcblk0p2 " \ + "console=ttySAC2,115200 " \ + "loglevel=4 " \ + "init=/sbin/init "\ + "ro" + }, + [2] = { .name = "NAND Kernel", .block_read = nand_read_ll, .offset_blocks512_if_no_partition = 0x80000 / 512, From fe71796cc1e82d58e47d12f5df4f5cb265053576 Mon Sep 17 00:00:00 2001 From: Xiangfu Date: Fri, 28 Nov 2008 10:16:42 +0000 Subject: [PATCH 127/248] qi-clean-and-add-readme-content.patch Signed-off-by: Xiangfu --- qiboot/Makefile | 5 +++-- qiboot/README | 6 +++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/qiboot/Makefile b/qiboot/Makefile index 374d83e..7c53ecb 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -49,7 +49,7 @@ UDFU_VID = 0x1d50 UDFU_PID = 0x5119 UDFU_REV = 0x350 -TARGET = image/start_qi_all-$(CPU) +TARGET = $(IMAGE_DIR)/start_qi_all-$(CPU) IMAGE = $(IMAGE_DIR)/qi-$(CPU)-$(BUILD_VERSION) UDFU_IMAGE = $(IMAGE_DIR)/qi-$(CPU)-$(BUILD_VERSION).udfu @@ -77,5 +77,6 @@ ${UDFU_IMAGE}:${OBJS} ${MKUDFU} @$(OBJDUMP) -d ${TARGET} >${IMAGE}.dis clean: - @rm -f src/*.o cpu/*/*.o cpu/*/*~ src/*~ src/drivers/*.o src/drivers/*~ include/*~ ${IMAGE_DIR}/* ${TARGET} ${UDFU_IMAGE} + @rm -f src/*.o cpu/*/*.o cpu/*/*~ src/*~ src/drivers/*.o src/drivers/*~ \ + include/*~ ${IMAGE_DIR}/* ${TARGET} ${UDFU_IMAGE} @make clean -C $(TOOLS) diff --git a/qiboot/README b/qiboot/README index 8b13789..e489299 100644 --- a/qiboot/README +++ b/qiboot/README @@ -1 +1,5 @@ - +Backlight turns on right away, but screen remains blank until kernel load, +and kernel does NOT output gobs of text to the screen. +Will ALWAYS boot from uSD if first partition is ext2 and contains +/boot/uImage.bin, otherwise boots from NAND. +No splash screen. From 72f081daa8b241edf2b78203645337cdbcae1780 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:42 +0000 Subject: [PATCH 128/248] qi-split-boards-smdk6410-gta03.patch Signed-off-by: Andy Green --- qiboot/include/neo_smdk6410.h | 6 ++ qiboot/include/smdk6410.h | 6 ++ qiboot/src/cpu/s3c6410/gta03.c | 15 ++-- qiboot/src/cpu/s3c6410/qi.lds | 1 + qiboot/src/cpu/s3c6410/serial-s3c64xx.c | 23 ++---- qiboot/src/cpu/s3c6410/smdk6410.c | 99 +++++++++++++++++++++++++ qiboot/src/cpu/s3c6410/start_qi.c | 2 + 7 files changed, 127 insertions(+), 25 deletions(-) create mode 100644 qiboot/include/neo_smdk6410.h create mode 100644 qiboot/include/smdk6410.h create mode 100644 qiboot/src/cpu/s3c6410/smdk6410.c diff --git a/qiboot/include/neo_smdk6410.h b/qiboot/include/neo_smdk6410.h new file mode 100644 index 0000000..a438170 --- /dev/null +++ b/qiboot/include/neo_smdk6410.h @@ -0,0 +1,6 @@ +#ifndef __ASM_MODE__ +#include +extern const struct board_api board_api_smdk6410; +#endif + +#define TEXT_BASE_SMDK6410 0x53000000 diff --git a/qiboot/include/smdk6410.h b/qiboot/include/smdk6410.h new file mode 100644 index 0000000..a438170 --- /dev/null +++ b/qiboot/include/smdk6410.h @@ -0,0 +1,6 @@ +#ifndef __ASM_MODE__ +#include +extern const struct board_api board_api_smdk6410; +#endif + +#define TEXT_BASE_SMDK6410 0x53000000 diff --git a/qiboot/src/cpu/s3c6410/gta03.c b/qiboot/src/cpu/s3c6410/gta03.c index e925740..6c63ca0 100644 --- a/qiboot/src/cpu/s3c6410/gta03.c +++ b/qiboot/src/cpu/s3c6410/gta03.c @@ -5,17 +5,13 @@ //#include #include -#define GTA03_DEBUG_UART 0 +#define GTA03_DEBUG_UART 3 #define PCF50633_I2C_ADS 0x73 static const struct board_variant board_variants[] = { [0] = { - .name = "SMDK", - .machine_revision = 0, - }, - [1] = { .name = "GTA03 EVT1", .machine_revision = 1 } @@ -192,7 +188,7 @@ unsigned long s3c6410_mmc_bread(int dev_num, unsigned long blknr, unsigned long */ const struct board_api board_api_gta03 = { .name = "GTA03", - .linux_machine_id = 1626 /*1866*/, + .linux_machine_id = 1866, .linux_mem_start = 0x50000000, .linux_mem_size = (128 * 1024 * 1024), .linux_tag_placement = 0x50000000 + 0x100, @@ -208,8 +204,9 @@ const struct board_api board_api_gta03 = { .partition_index = 2, .filepath = "boot/uImage.bin", .initramfs_filepath = "boot/initramfs.gz", - .commandline = "console=ttySAC0,115200 " \ - "loglevel=8 init=/bin/sh root=/dev/ram ramdisk_size=6000000" + .commandline = "console=ttySAC3,115200 " \ + "loglevel=8 init=/bin/sh " \ + "root=/dev/ram ramdisk_size=6000000" }, [1] = { .name = "SD Card backup rootfs", @@ -218,7 +215,7 @@ const struct board_api board_api_gta03 = { .partition_index = 3, .filepath = "boot/uImage.bin", .initramfs_filepath = "boot/initramfs.gz", - .commandline = "console=ttySAC0,115200 " \ + .commandline = "console=ttySAC3,115200 " \ "loglevel=8 init=/bin/sh " }, }, }; diff --git a/qiboot/src/cpu/s3c6410/qi.lds b/qiboot/src/cpu/s3c6410/qi.lds index 7a89334..4bdddb8 100644 --- a/qiboot/src/cpu/s3c6410/qi.lds +++ b/qiboot/src/cpu/s3c6410/qi.lds @@ -46,6 +46,7 @@ SECTIONS src/cpu/s3c6410/start_qi.o (.text .rodata* .data .bss) src/cpu/s3c6410/serial-s3c64xx.o (.text .rodata* .data .bss) src/cpu/s3c6410/gta03.o (.text .rodata* .data .bss) + src/cpu/s3c6410/smdk6410.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) diff --git a/qiboot/src/cpu/s3c6410/serial-s3c64xx.c b/qiboot/src/cpu/s3c6410/serial-s3c64xx.c index 7e5a2b3..256419b 100644 --- a/qiboot/src/cpu/s3c6410/serial-s3c64xx.c +++ b/qiboot/src/cpu/s3c6410/serial-s3c64xx.c @@ -1,6 +1,6 @@ /* * (C) Copyright 2007 OpenMoko, Inc. - * Author: xiangfu liu + * Author: Andy Green * * Configuation settings for the FIC Neo GTA02 Linux GSM phone * @@ -28,20 +28,11 @@ */ void serial_putc_s3c64xx(const int uart, const char c) { - switch(uart) - { - case 0: - while (!( UTRSTAT0_REG & 0x2 )) - ; - UTXH0_REG = c; - break; - case 1: - while (!( UTRSTAT1_REG & 0x2)) - ; - UTXH1_REG = c; - break; + if (uart >= 4) + return; - default: - break; - } + while (!(__REG(0x7F005000 + UTRSTAT_OFFSET + (uart << 10)) & 0x2)) + ; + + __REG(0x7F005000 + UTXH_OFFSET + (uart << 10)) = c; } diff --git a/qiboot/src/cpu/s3c6410/smdk6410.c b/qiboot/src/cpu/s3c6410/smdk6410.c new file mode 100644 index 0000000..5085fd4 --- /dev/null +++ b/qiboot/src/cpu/s3c6410/smdk6410.c @@ -0,0 +1,99 @@ +#include +#include +#include + +#define SMDK6410_DEBUG_UART 0 + + +static const struct board_variant board_variants[] = { + [0] = { + .name = "SMDK", + .machine_revision = 0, + }, +}; + +void port_init_smdk6410(void) +{ + +} + +/** + * 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()]; +} + +int is_this_board_smdk6410(void) +{ + /* FIXME: find something smdk6410 specific */ + return 1; +} + +static __attribute__ (( section (".steppingstone") )) 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 = 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, + .port_init = port_init_smdk6410, + .putc = putc_smdk6410, + .kernel_source = { + [0] = { + .name = "SD Card rootfs", + .block_read = sd_card_block_read_smdk6410, + .filesystem = FS_EXT2, + .partition_index = 2, + .filepath = "boot/uImage.bin", + .initramfs_filepath = "boot/initramfs.gz", + .commandline = "console=ttySAC0,115200 " \ + "loglevel=8 init=/bin/sh " \ + " root=/dev/ram ramdisk_size=6000000" + }, + [1] = { + .name = "SD Card backup rootfs", + .block_read = sd_card_block_read_smdk6410, + .filesystem = FS_EXT2, + .partition_index = 3, + .filepath = "boot/uImage.bin", + .initramfs_filepath = "boot/initramfs.gz", + .commandline = "console=ttySAC0,115200 " \ + "loglevel=8 init=/bin/sh " + }, }, +}; + diff --git a/qiboot/src/cpu/s3c6410/start_qi.c b/qiboot/src/cpu/s3c6410/start_qi.c index ac94b66..28d70ee 100644 --- a/qiboot/src/cpu/s3c6410/start_qi.c +++ b/qiboot/src/cpu/s3c6410/start_qi.c @@ -26,6 +26,7 @@ #include #include +#include #define stringify2(s) stringify1(s) #define stringify1(s) #s @@ -33,6 +34,7 @@ extern void bootloader_second_phase(void); const struct board_api *boards[] = { + &board_api_smdk6410, &board_api_gta03, NULL /* always last */ }; From acaa3b450729fb8eb14409191a2fb40e8529b17f Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:42 +0000 Subject: [PATCH 129/248] qi-gta03-gpio-init.patch Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/gta03.c | 815 ++++++++++++++++++++++++++++----- 1 file changed, 713 insertions(+), 102 deletions(-) diff --git a/qiboot/src/cpu/s3c6410/gta03.c b/qiboot/src/cpu/s3c6410/gta03.c index 6c63ca0..0214e6e 100644 --- a/qiboot/src/cpu/s3c6410/gta03.c +++ b/qiboot/src/cpu/s3c6410/gta03.c @@ -1,5 +1,6 @@ #include #include +#include #include //#include //#include @@ -19,109 +20,719 @@ static const struct board_variant board_variants[] = { void port_init_gta03(void) { + + /* ---------------------------- 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) = 0; /* all pullup and pulldown disabled */ + + __REG(GPADAT) = 0; /* just for determinism */ + + __REG(GPACONSLP) = + (3 << 0) | /* GPA0 - keep */ + (3 << 2) | /* GPA1 - keep */ + (3 << 4) | /* GPA2 - keep */ + (3 << 6) | /* GPA3 - keep */ + (3 << 8) | /* GPA4 - keep */ + (3 << 10) | /* GPA5 - keep */ + (3 << 12) | /* GPA6 - keep */ + (3 << 14) /* GPA7 - keep */ + ; + + /* ---------------------------- Port B ---------------------------- */ + + __REG(GPBCON) = + (2 << 0) | /* GPB0 - UART_RXD2 */ + (2 << 4) | /* GPB1 - UART_TXD2 */ + (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) = 0; /* all pullup and pulldown disabled */ + + __REG(GPBDAT) = 0; /* just for determinism */ + + __REG(GPBCONSLP) = + (3 << 0) | /* GPB0 - keep */ + (3 << 2) | /* GPB1 - keep */ + (3 << 4) | /* GPB2 - keep */ + (3 << 6) | /* GPB3 - keep */ + (3 << 8) | /* GPB4 - keep */ + (3 << 10) | /* GPB5 - keep */ + (3 << 12) | /* GPB6 - keep */ + (3 << 14) /* GPB7 - keep */ + ; + + __REG(GPBPUDSLP) = + (0 << 0) | /* GPB0 - no pull up or down */ + (0 << 2) | /* GPB1 - no pull up or down */ + (0 << 4) | /* GPB2 - no pull up or down */ + (0 << 6) | /* GPB3 - no pull up or down */ + (0 << 8) | /* GPB4 - no pull up or down */ + (0 << 10) | /* GPB5 - no pull up or down */ + (0 << 12) | /* GPB6 - no pull up or down */ + (0 << 14) /* GPB7 - no pull up or down */ + ; + + /* ---------------------------- Port C ---------------------------- */ + + __REG(GPCCON) = + (0 << 0) | /* GPC0 - SPI_MISO0 INPUT */ + (1 << 4) | /* GPC1 - SPI_CLK0 OUTPUT */ + (1 << 8) | /* GPC2 - SPI_MOSI0 OUTPUT */ + (1 << 12) | /* GPC3 - SPI_CS0 OUTPUT */ + (1 << 16) | /* GPC4 - (NC) OUTPUT */ + (1 << 20) | /* GPC5 - SPI_CLK1 OUTPUT */ + (1 << 24) | /* GPC6 - SPI_MOSI1 OUTPUT */ + (1 << 28) /* GPC7 - SPI_CS1 OUTPUT */ + ; + + __REG(GPCPUD) = 0; /* all pullup and pulldown disabled */ + + __REG(GPCDAT) = 0; /* just for determinism */ + + __REG(GPCCONSLP) = + (3 << 0) | /* GPC0 - keep */ + (3 << 2) | /* GPC1 - keep */ + (3 << 4) | /* GPC2 - keep */ + (3 << 6) | /* GPC3 - keep */ + (3 << 8) | /* GPC4 - keep */ + (3 << 10) | /* GPC5 - keep */ + (3 << 12) | /* GPC6 - keep */ + (3 << 14) /* GPC7 - keep */ + ; + + __REG(GPCPUDSLP) = + (0 << 0) | /* GPC0 - no pull up or down */ + (0 << 2) | /* GPC1 - no pull up or down */ + (0 << 4) | /* GPC2 - no pull up or down */ + (0 << 6) | /* GPC3 - no pull up or down */ + (0 << 8) | /* GPC4 - no pull up or down */ + (0 << 10) | /* GPC5 - no pull up or down */ + (0 << 12) | /* GPC6 - no pull up or down */ + (0 << 14) /* GPC7 - no pull up or down */ + ; + + /* ---------------------------- 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) = + (3 << 0) | /* GPD0 - keep */ + (3 << 2) | /* GPD1 - keep */ + (3 << 4) | /* GPD2 - keep */ + (3 << 6) | /* GPD3 - keep */ + (3 << 8) /* GPD4 - keep */ + ; + + __REG(GPDPUDSLP) = + (0 << 0) | /* GPD0 - no pull up or down */ + (0 << 2) | /* GPD1 - no pull up or down */ + (0 << 4) | /* GPD2 - no pull up or down */ + (0 << 6) | /* GPD3 - no pull up or down */ + (0 << 8) /* GPD4 - no pull up or down */ + ; + + /* ---------------------------- 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) = + (3 << 0) | /* GPE0 - keep */ + (3 << 2) | /* GPE1 - keep */ + (3 << 4) | /* GPE2 - keep */ + (3 << 6) | /* GPE3 - keep */ + (3 << 8) /* GPE4 - keep */ + ; + + __REG(GPEPUDSLP) = + (1 << 0) | /* GPE0 - pull down */ + (1 << 2) | /* GPE1 - pull down */ + (1 << 4) | /* GPE2 - pull down */ + (1 << 6) | /* GPE3 - pull down */ + (1 << 8) /* GPE4 - pull down */ + ; + + /* ---------------------------- 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 */ + (3 << 28) | /* GPF14 - CLKOUT0 */ + (1 << 30) /* GPF15 - OUTPUT CAM_PWRDN */ + ; + + __REG(GPFPUD) = 0; /* all pullup and pulldown disabled */ + + __REG(GPFDAT) = (1 << 15); /* assert CAM_PWRDN */ + + __REG(GPFCONSLP) = + (0 << 0) | /* GPF0 - OUTPUT 0 */ + (0 << 2) | /* GPF1 - OUTPUT 0 */ + (0 << 4) | /* GPF2 - OUTPUT 0 */ + (0 << 6) | /* GPF3 - OUTPUT 0 */ + (0 << 8) | /* GPF4 - OUTPUT 0 */ + (0 << 10) | /* GPF5 - OUTPUT 0 */ + (0 << 12) | /* GPF6 - OUTPUT 0 */ + (0 << 14) | /* GPF7 - OUTPUT 0 */ + (0 << 16) | /* GPF8 - OUTPUT 0 */ + (0 << 18) | /* GPF9 - OUTPUT 0 */ + (0 << 20) | /* GPF10 - OUTPUT 0 */ + (0 << 22) | /* GPF11 - OUTPUT 0 */ + (0 << 24) | /* GPF12 - OUTPUT 0 */ + (0 << 26) | /* GPF13 - OUTPUT 0 */ + (0 << 28) | /* GPF14 - OUTPUT 0 */ + (0 << 30) /* GPF15 - OUTPUT 0 */ + ; + + __REG(GPFPUDSLP) = + (0 << 0) | /* GPF0 - no pull up or down */ + (0 << 2) | /* GPF1 - no pull up or down */ + (0 << 4) | /* GPF2 - no pull up or down */ + (0 << 6) | /* GPF3 - no pull up or down */ + (0 << 8) | /* GPF4 - no pull up or down */ + (0 << 10) | /* GPF5 - no pull up or down */ + (0 << 12) | /* GPF6 - no pull up or down */ + (0 << 14) | /* GPF7 - no pull up or down */ + (0 << 16) | /* GPF8 - no pull up or down */ + (0 << 18) | /* GPF9 - no pull up or down */ + (0 << 20) | /* GPF10 - no pull up or down */ + (0 << 22) | /* GPF11 - no pull up or down */ + (0 << 24) | /* GPF12 - no pull up or down */ + (0 << 26) | /* GPF13 - no pull up or down */ + (0 << 28) | /* GPF14 - no pull up or down */ + (0 << 30) /* GPF15 - no pull up or 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 */ + (1 << 24) /* GPG6 - (NC) OUTPUT 0 */ + ; + + __REG(GPGPUD) = 0; /* all pullup and pulldown disabled */ + + __REG(GPGDAT) = 0; /* just for determinism */ + + __REG(GPGCONSLP) = + (0 << 0) | /* GPG0 - OUTPUT 0 */ + (0 << 2) | /* GPG1 - OUTPUT 0 */ + (0 << 4) | /* GPG2 - OUTPUT 0 */ + (0 << 6) | /* GPG3 - OUTPUT 0 */ + (0 << 8) | /* GPG4 - OUTPUT 0 */ + (0 << 10) | /* GPG5 - OUTPUT 0 */ + (0 << 12) /* GPG6 - OUTPUT 0 */ + ; + + __REG(GPGPUDSLP) = + (0 << 0) | /* GPG0 - no pull up or down */ + (0 << 2) | /* GPG1 - no pull up or down */ + (0 << 4) | /* GPG2 - no pull up or down */ + (0 << 6) | /* GPG3 - no pull up or down */ + (0 << 8) | /* GPG4 - no pull up or down */ + (0 << 10) | /* GPG5 - no pull up or down */ + (0 << 12) /* GPG6 - no pull up or down */ + ; + + /* ---------------------------- Port H ---------------------------- */ + + __REG(GPHCON0) = + (2 << 0) | /* GPH0 - MMC_CLK1 */ + (2 << 4) | /* GPH1 - MMC_CMD1 */ + (2 << 8) | /* GPH2 - MMC_DATA01 */ + (2 << 12) | /* GPH3 - MMC_DATA11 */ + (2 << 16) | /* GPH4 - MMC_DATA21 */ + (2 << 20) | /* GPH5 - MMC_DATA31 */ + (1 << 24) | /* GPH6 - OUTPUT nWLAN_RESET */ + (1 << 28) /* GPH7 - OUTPUT HDQ */ + ; + __REG(GPHCON1) = + (1 << 0) | /* GPH8 - OUTPUT nWLAN_PD */ + (1 << 4) /* GPH9 - OUTPUT (NC) */ + ; + + __REG(GPHPUD) = 0; /* all pullup and pulldown disabled */ + + __REG(GPHDAT) = 0; + + __REG(GPHCONSLP) = + (0 << 0) | /* GPH0 - OUTPUT 0 */ + (0 << 2) | /* GPH1 - OUTPUT 0 */ + (0 << 4) | /* GPH2 - OUTPUT 0 */ + (0 << 6) | /* GPH3 - OUTPUT 0 */ + (0 << 8) | /* GPH4 - OUTPUT 0 */ + (0 << 10) | /* GPH5 - OUTPUT 0 */ + (0 << 12) | /* GPH6 - OUTPUT 0 */ + (2 << 14) | /* GPH7 - INPUT (HDQ) */ + (0 << 16) | /* GPH8 - OUTPUT 0 */ + (0 << 18) /* GPH9 - OUTPUT 0 */ + ; + + __REG(GPHPUDSLP) = + (0 << 0) | /* GPH0 - no pull up or down */ + (0 << 2) | /* GPH1 - no pull up or down */ + (0 << 4) | /* GPH2 - no pull up or down */ + (0 << 6) | /* GPH3 - no pull up or down */ + (0 << 8) | /* GPH4 - no pull up or down */ + (0 << 10) | /* GPH5 - no pull up or down */ + (2 << 12) | /* GPH6 - PULLUP (HDQ) */ + (0 << 14) | /* GPH7 - no pull up or down */ + (0 << 16) | /* GPH8 - no pull up or down */ + (0 << 18) /* GPH9 - no pull up or down */ + ; + + /* ---------------------------- Port I ---------------------------- */ + + __REG(GPICON) = + (2 << 0) | /* GPI0 - LCD_VD0 */ + (2 << 2) | /* GPI1 - LCD_VD1 */ + (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 */ + (2 << 16) | /* GPI8 - LCD_VD8 */ + (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) = + (0 << 0) | /* GPI0 - OUTPUT 0 */ + (0 << 2) | /* GPI1 - OUTPUT 0 */ + (0 << 4) | /* GPI2 - OUTPUT 0 */ + (0 << 6) | /* GPI3 - OUTPUT 0 */ + (0 << 8) | /* GPI4 - OUTPUT 0 */ + (0 << 10) | /* GPI5 - OUTPUT 0 */ + (0 << 12) | /* GPI6 - OUTPUT 0 */ + (0 << 14) | /* GPI7 - OUTPUT 0 */ + (0 << 16) | /* GPI8 - OUTPUT 0 */ + (0 << 18) | /* GPI9 - OUTPUT 0 */ + (0 << 20) | /* GPI10 - OUTPUT 0 */ + (0 << 22) | /* GPI11 - OUTPUT 0 */ + (0 << 24) | /* GPI12 - OUTPUT 0 */ + (0 << 26) | /* GPI13 - OUTPUT 0 */ + (0 << 28) | /* GPI14 - OUTPUT 0 */ + (0 << 30) /* GPI15 - OUTPUT 0 */ + ; + + __REG(GPIPUDSLP) = + (0 << 0) | /* GPI0 - no pull up or down */ + (0 << 2) | /* GPI1 - no pull up or down */ + (0 << 4) | /* GPI2 - no pull up or down */ + (0 << 6) | /* GPI3 - no pull up or down */ + (0 << 8) | /* GPI4 - no pull up or down */ + (0 << 10) | /* GPI5 - no pull up or down */ + (0 << 12) | /* GPI6 - no pull up or down */ + (0 << 14) | /* GPI7 - no pull up or down */ + (0 << 16) | /* GPI8 - no pull up or down */ + (0 << 18) | /* GPI9 - no pull up or down */ + (0 << 20) | /* GPI10 - no pull up or down */ + (0 << 22) | /* GPI11 - no pull up or down */ + (0 << 24) | /* GPI12 - no pull up or down */ + (0 << 26) | /* GPI13 - no pull up or down */ + (0 << 28) | /* GPI14 - no pull up or down */ + (0 << 30) /* GPI15 - no pull up or 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) = + (0 << 0) | /* GPJ0 - OUTPUT 0 */ + (0 << 2) | /* GPJ1 - OUTPUT 0 */ + (0 << 4) | /* GPJ2 - OUTPUT 0 */ + (0 << 6) | /* GPJ3 - OUTPUT 0 */ + (0 << 8) | /* GPJ4 - OUTPUT 0 */ + (0 << 10) | /* GPJ5 - OUTPUT 0 */ + (0 << 12) | /* GPJ6 - OUTPUT 0 */ + (0 << 14) | /* GPJ7 - OUTPUT 0 */ + (0 << 16) | /* GPJ8 - OUTPUT 0 */ + (0 << 18) | /* GPJ9 - OUTPUT 0 */ + (0 << 20) | /* GPJ10 - OUTPUT 0 */ + (0 << 22) /* GPJ11 - OUTPUT 0 */ + ; + + __REG(GPJPUDSLP) = + (0 << 0) | /* GPJ0 - no pull up or down */ + (0 << 2) | /* GPJ1 - no pull up or down */ + (0 << 4) | /* GPJ2 - no pull up or down */ + (0 << 6) | /* GPJ3 - no pull up or down */ + (0 << 8) | /* GPJ4 - no pull up or down */ + (0 << 10) | /* GPJ5 - no pull up or down */ + (0 << 12) | /* GPJ6 - no pull up or down */ + (0 << 14) | /* GPJ7 - no pull up or down */ + (0 << 16) | /* GPJ8 - no pull up or down */ + (0 << 18) | /* GPJ9 - no pull up or down */ + (0 << 20) | /* GPJ10 - no pull up or down */ + (0 << 22) /* GPJ11 - no pull up or down */ + ; + + /* ---------------------------- Port K ---------------------------- */ + + __REG(GPKCON0) = + (1 << 0) | /* GPK0 - OUTPUT nWLAN_POWERON */ + (1 << 4) | /* GPK1 - OUTPUT (NC) */ + (1 << 8) | /* GPK2 - OUTPUT (nMODEM_ON) */ + (1 << 12) | /* GPK3 - OUTPUT (NC) */ + (1 << 16) | /* GPK4 - OUTPUT (NC) */ + (1 << 20) | /* GPK5 - OUTPUT (NC) */ + (1 << 24) | /* GPK6 - OUTPUT (NC) */ + (1 << 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; /* all pullup and pulldown disabled */ + + __REG(GPKDAT) = + (1 << 2) /* deassert nMODEM_ON */ + ; + + /* ---------------------------- 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 (GPS_LNA_EN) */ + (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 */ + (2 << 14) | /* GPN7 - EXINT7 GPS_INT */ + (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) = 0; /* all pullup and pulldown disabled */ + + __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; /* all pullup and pulldown disabled */ + + __REG(GPODAT) = (1 << 15); /* assert CAM_PWRDN */ + + __REG(GPOCONSLP) = + (3 << 0) | /* GPO0 - hold state */ + (1 << 2) | /* GPO1 - OUTPUT 1 (do not reset modem) */ + (0 << 4) | /* GPO2 - OUTPUT 0 */ + (0 << 6) | /* GPO3 - OUTPUT 0 */ + (0 << 8) | /* GPO4 - OUTPUT 0 */ + (0 << 10) | /* GPO5 - OUTPUT 0 */ + (0 << 12) | /* GPO6 - OUTPUT 0 */ + (0 << 14) | /* GPO7 - OUTPUT 0 */ + (0 << 16) | /* GPO8 - OUTPUT 0 */ + (0 << 18) | /* GPO9 - OUTPUT 0 */ + (0 << 20) | /* GPO10 - OUTPUT 0 */ + (0 << 22) | /* GPO11 - OUTPUT 0 */ + (0 << 24) | /* GPO12 - OUTPUT 0 */ + (0 << 26) | /* GPO13 - OUTPUT 0 */ + (0 << 28) | /* GPO14 - OUTPUT 0 */ + (0 << 30) /* GPO15 - OUTPUT 0 */ + ; + + __REG(GPOPUDSLP) = + (0 << 0) | /* GPO0 - no pull up or down */ + (0 << 2) | /* GPO1 - no pull up or down */ + (0 << 4) | /* GPO2 - no pull up or down */ + (0 << 6) | /* GPO3 - no pull up or down */ + (0 << 8) | /* GPO4 - no pull up or down */ + (0 << 10) | /* GPO5 - no pull up or down */ + (0 << 12) | /* GPO6 - no pull up or down */ + (0 << 14) | /* GPO7 - no pull up or down */ + (0 << 16) | /* GPO8 - no pull up or down */ + (0 << 18) | /* GPO9 - no pull up or down */ + (0 << 20) | /* GPO10 - no pull up or down */ + (0 << 22) | /* GPO11 - no pull up or down */ + (0 << 24) | /* GPO12 - no pull up or down */ + (0 << 26) | /* GPO13 - no pull up or down */ + (0 << 28) | /* GPO14 - no pull up or down */ + (0 << 30) /* GPO15 - no pull up or down */ + ; + + /* ---------------------------- Port P ---------------------------- */ + + __REG(GPPCON) = + (1 << 0) | /* GPP0 - OUTPUT (NC) */ + (1 << 2) | /* GPP1 - OUTPUT (NC) */ + (1 << 4) | /* GPP2 - OUTPUT (NC) */ + (1 << 6) | /* GPP3 - OUTPUT (NC) */ + (1 << 8) | /* GPP4 - OUTPUT (NC) */ + (1 << 10) | /* GPP5 - OUTPUT (NC) */ + (1 << 12) | /* GPP6 - OUTPUT (NC) */ + (1 << 14) | /* GPP7 - OUTPUT (NC) */ + (1 << 16) | /* GPP8 - OUTPUT (NC) */ + (1 << 18) | /* GPP9 - OUTPUT (NC) */ + (1 << 20) | /* GPP10 - OUTPUT (NC) */ + (1 << 22) | /* GPP11 - OUTPUT (NC) */ + (1 << 24) | /* GPP12 - OUTPUT (NC) */ + (1 << 26) | /* GPP13 - OUTPUT (NC) */ + (1 << 28) | /* GPP14 - OUTPUT (NC) */ + (1 << 30) /* GPP15 - OUTPUT (NC) */ + ; + + __REG(GPPPUD) = 0; /* all pullup and pulldown disabled */ + + __REG(GPPDAT) = 0; /* assert CAM_PWRDN */ + + __REG(GPPCONSLP) = + (0 << 0) | /* GPP0 - OUTPUT 0 */ + (0 << 2) | /* GPP1 - OUTPUT 0 */ + (0 << 4) | /* GPP2 - OUTPUT 0 */ + (0 << 6) | /* GPP3 - OUTPUT 0 */ + (0 << 8) | /* GPP4 - OUTPUT 0 */ + (0 << 10) | /* GPP5 - OUTPUT 0 */ + (0 << 12) | /* GPP6 - OUTPUT 0 */ + (0 << 14) | /* GPP7 - OUTPUT 0 */ + (0 << 16) | /* GPP8 - OUTPUT 0 */ + (0 << 18) | /* GPP9 - OUTPUT 0 */ + (0 << 20) | /* GPP10 - OUTPUT 0 */ + (0 << 22) | /* GPP11 - OUTPUT 0 */ + (0 << 24) | /* GPP12 - OUTPUT 0 */ + (0 << 26) | /* GPP13 - OUTPUT 0 */ + (0 << 28) | /* GPP14 - OUTPUT 0 */ + (0 << 30) /* GPP15 - OUTPUT 0 */ + ; + + __REG(GPPPUDSLP) = + (0 << 0) | /* GPP0 - no pull up or down */ + (0 << 2) | /* GPP1 - no pull up or down */ + (0 << 4) | /* GPP2 - no pull up or down */ + (0 << 6) | /* GPP3 - no pull up or down */ + (0 << 8) | /* GPP4 - no pull up or down */ + (0 << 10) | /* GPP5 - no pull up or down */ + (0 << 12) | /* GPP6 - no pull up or down */ + (0 << 14) | /* GPP7 - no pull up or down */ + (0 << 16) | /* GPP8 - no pull up or down */ + (0 << 18) | /* GPP9 - no pull up or down */ + (0 << 20) | /* GPP10 - no pull up or down */ + (0 << 22) | /* GPP11 - no pull up or down */ + (0 << 24) | /* GPP12 - no pull up or down */ + (0 << 26) | /* GPP13 - no pull up or down */ + (0 << 28) | /* GPP14 - no pull up or down */ + (0 << 30) /* GPP15 - no pull up or down */ + ; + + /* ---------------------------- 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) */ + (1 << 18) | /* GPQ9 - OUTPUT (NC) */ + (1 << 20) | /* GPQ10 - OUTPUT (NC) */ + (1 << 22) | /* GPQ11 - OUTPUT (NC) */ + (1 << 24) | /* GPQ12 - OUTPUT (NC) */ + (1 << 26) | /* GPQ13 - OUTPUT (NC) */ + (1 << 28) | /* GPQ14 - OUTPUT (NC) */ + (1 << 30) /* GPQ15 - OUTPUT (NC) */ + ; + + __REG(GPQPUD) = 0; /* all pullup and pulldown disabled */ + + __REG(GPQDAT) = 0; /* assert CAM_PWRDN */ + + __REG(GPQCONSLP) = + (0 << 0) | /* GPQ0 - OUTPUT 0 */ + (0 << 2) | /* GPQ1 - OUTPUT 0 */ + (0 << 4) | /* GPQ2 - OUTPUT 0 */ + (0 << 6) | /* GPQ3 - OUTPUT 0 */ + (0 << 8) | /* GPQ4 - OUTPUT 0 */ + (0 << 10) | /* GPQ5 - OUTPUT 0 */ + (0 << 12) | /* GPQ6 - OUTPUT 0 */ + (0 << 14) | /* GPQ7 - OUTPUT 0 */ + (0 << 16) | /* GPQ8 - OUTPUT 0 */ + (0 << 18) | /* GPQ9 - OUTPUT 0 */ + (0 << 20) | /* GPQ10 - OUTPUT 0 */ + (0 << 22) | /* GPQ11 - OUTPUT 0 */ + (0 << 24) | /* GPQ12 - OUTPUT 0 */ + (0 << 26) | /* GPQ13 - OUTPUT 0 */ + (0 << 28) | /* GPQ14 - OUTPUT 0 */ + (0 << 30) /* GPQ15 - OUTPUT 0 */ + ; + + __REG(GPQPUDSLP) = + (0 << 0) | /* GPQ0 - no pull up or down */ + (0 << 2) | /* GPQ1 - no pull up or down */ + (0 << 4) | /* GPQ2 - no pull up or down */ + (0 << 6) | /* GPQ3 - no pull up or down */ + (0 << 8) | /* GPQ4 - no pull up or down */ + (0 << 10) | /* GPQ5 - no pull up or down */ + (0 << 12) | /* GPQ6 - no pull up or down */ + (0 << 14) | /* GPQ7 - no pull up or down */ + (0 << 16) | /* GPQ8 - no pull up or down */ + (0 << 18) | /* GPQ9 - no pull up or down */ + (0 << 20) | /* GPQ10 - no pull up or down */ + (0 << 22) | /* GPQ11 - no pull up or down */ + (0 << 24) | /* GPQ12 - no pull up or down */ + (0 << 26) | /* GPQ13 - no pull up or down */ + (0 << 28) | /* GPQ14 - no pull up or down */ + (0 << 30) /* GPQ15 - no pull up or down */ + ; + #if 0 - unsigned int * MPLLCON = (unsigned int *)0x4c000004; - unsigned int * UPLLCON = (unsigned int *)0x4c000008; - unsigned int * CLKDIVN = (unsigned int *)0x4c000014; - - //CAUTION:Follow the configuration order for setting the ports. - // 1) setting value(GPnDAT) - // 2) setting control register (GPnCON) - // 3) configure pull-up 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 = 0x007F8FFF; - /* - * ===* 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 = 0x00145554; - rGPBDAT |= (1 <<9 ); /* USB_PULLUP */ - rGPBUP = 0x000007FF; - /* - * === 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 = 0xAAA776E9; - rGPCUP = 0x0000FFFF; - rGPCDAT |= (1 << 9); /* WLAN_nRESET pull high */ - /* - * === 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 = 0xAAA0AAA5; - rGPDUP = 0x0000FFFF; - /* - * === 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; - /* - * === 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 - */ - rGPFCON = 0x0000AAAA; - rGPFUP = 0x000000FF; - - /* - * === 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 = 0x02A9FE5A; - rGPGUP = 0x0000FFFF; - - /* - * === 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 - */ - /* pulldown on GPH08: UEXTCLK, just floats! - * pulldown GPH0 -- nCTS0 / RTS_MODEM -- floats when GSM off - * pulldown GPH3 -- RXD[0] / TX_MODEM -- floats when GSM off - */ - rGPHCON = 0x0019A0AA; - rGPHUP = 0x000007FF; - - /* pulldown on GPJ00: input, just floats! */ - /* pulldown on GPJ07: WLAN module WLAN_GPIO0, no ext pull */ - rGPJCON = 0x02AAAAAA; - rGPJUP = 0x1FFFF; - /* * We have to talk to the PMU a little bit */ From 31f03046d54330a00eafaf8e58ebb2c2e38b7582 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:42 +0000 Subject: [PATCH 130/248] qi-6410-i2c-bitbang.patch Signed-off-by: Andy Green --- qiboot/include/i2c-bitbang-s3c6410.h | 3 + qiboot/src/cpu/s3c2442/i2c-bitbang-s3c24xx.c | 2 +- qiboot/src/cpu/s3c6410/i2c-bitbang-s3c6410.c | 69 ++++++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 qiboot/include/i2c-bitbang-s3c6410.h create mode 100644 qiboot/src/cpu/s3c6410/i2c-bitbang-s3c6410.c diff --git a/qiboot/include/i2c-bitbang-s3c6410.h b/qiboot/include/i2c-bitbang-s3c6410.h new file mode 100644 index 0000000..b1c3ed5 --- /dev/null +++ b/qiboot/include/i2c-bitbang-s3c6410.h @@ -0,0 +1,3 @@ +#include + +extern struct i2c_bitbang bb_s3c6410; diff --git a/qiboot/src/cpu/s3c2442/i2c-bitbang-s3c24xx.c b/qiboot/src/cpu/s3c2442/i2c-bitbang-s3c24xx.c index c2d46ed..e68b9b9 100644 --- a/qiboot/src/cpu/s3c2442/i2c-bitbang-s3c24xx.c +++ b/qiboot/src/cpu/s3c2442/i2c-bitbang-s3c24xx.c @@ -2,7 +2,7 @@ * (C) Copyright 2007 OpenMoko, Inc. * Author: Andy Green * - * s3c24xx-specific i2c shared by, eg, GTA02 and GTA03 + * 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 diff --git a/qiboot/src/cpu/s3c6410/i2c-bitbang-s3c6410.c b/qiboot/src/cpu/s3c6410/i2c-bitbang-s3c6410.c new file mode 100644 index 0000000..0d1236d --- /dev/null +++ b/qiboot/src/cpu/s3c6410/i2c-bitbang-s3c6410.c @@ -0,0 +1,69 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: Andy Green + * + * 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 +#include +#include + +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, +}; From 56841f9f5d3146e56f8b0ab38bfe37ae675b1d10 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:42 +0000 Subject: [PATCH 131/248] qi-gta03-add-pmu-init.patch Signed-off-by: Andy Green --- qiboot/include/pcf50633.h | 5 +++ qiboot/src/cpu/s3c2442/gta02.c | 5 --- qiboot/src/cpu/s3c6410/gta03.c | 56 +++++++++++++++++++++++++--------- 3 files changed, 47 insertions(+), 19 deletions(-) diff --git a/qiboot/include/pcf50633.h b/qiboot/include/pcf50633.h index 73e233a..51da119 100644 --- a/qiboot/include/pcf50633.h +++ b/qiboot/include/pcf50633.h @@ -383,5 +383,10 @@ enum pcf50633_reg_mbcs3 { PCF50633_MBCS3_VRES = 0x80, /* 1: Vbat > Vth(RES) */ }; +struct pcf50633_init { + u8 index; + u8 value; +}; + #endif /* _PCF50633_H */ diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 3e5b02e..06d270f 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -35,11 +35,6 @@ #define PCF50633_I2C_ADS 0x73 #define BOOST_TO_400MHZ 1 -struct pcf50633_init { - u8 index; - u8 value; -}; - const struct pcf50633_init pcf50633_init[] = { { PCF50633_REG_OOCWAKE, 0xd3 }, /* wake from ONKEY,EXTON!,RTC,USB,ADP */ diff --git a/qiboot/src/cpu/s3c6410/gta03.c b/qiboot/src/cpu/s3c6410/gta03.c index 0214e6e..d2141ca 100644 --- a/qiboot/src/cpu/s3c6410/gta03.c +++ b/qiboot/src/cpu/s3c6410/gta03.c @@ -2,14 +2,49 @@ #include #include #include -//#include -//#include +#include #include #define GTA03_DEBUG_UART 3 #define PCF50633_I2C_ADS 0x73 +const struct pcf50633_init gta03_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) */ + { PCF50633_REG_DOWN1ENA, 0x02 }, /* enabled if GPIO1 = HIGH */ + { PCF50633_REG_LDO6ENA, 0x01 }, /* 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, 0x19 }, /* 25/255 == 98mA soft-start usb fast */ + { PCF50633_REG_MBCC6, 0x00 }, /* cutoff current 1/32 * Ichg */ + { PCF50633_REG_MBCC7, 0x00 }, /* 1.6A max bat curr, USB 100mA */ + { 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] = { @@ -20,6 +55,7 @@ static const struct board_variant board_variants[] = { void port_init_gta03(void) { + int n; /* ---------------------------- Port A ---------------------------- */ @@ -732,22 +768,14 @@ void port_init_gta03(void) (0 << 30) /* GPQ15 - no pull up or down */ ; -#if 0 /* * We have to talk to the PMU a little bit */ - /* We need SD Card rail (HCLDO) at 3.0V */ - i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_HCLDOOUT, - 21); - - /* switch HCLDO on */ - i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_HCLDOENA, 1); - - /* push DOWN1 (CPU Core rail) to 1.7V, allowing 533MHz */ - i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, PCF50633_REG_DOWN1OUT, - 0x2b); -#endif + for (n = 0; n < ARRAY_SIZE(gta03_pcf50633_init); n++) + i2c_write_sync(&bb_s3c6410, PCF50633_I2C_ADS, + gta03_pcf50633_init[n].index, + gta03_pcf50633_init[n].value); } From b4ac8b9dc96828511cb2a74edebf365880386554 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:42 +0000 Subject: [PATCH 132/248] qi-split-board-specific-in-steppingstone.patch Signed-off-by: Andy Green --- qiboot/include/qi.h | 1 + qiboot/include/s3c6410.h | 4 +- qiboot/src/cpu/s3c6410/gta03-steppingstone.c | 76 +++++++++++++++++++ qiboot/src/cpu/s3c6410/gta03.c | 66 ---------------- qiboot/src/cpu/s3c6410/qi.lds | 6 +- .../src/cpu/s3c6410/smdk6410-steppingstone.c | 71 +++++++++++++++++ qiboot/src/cpu/s3c6410/smdk6410.c | 72 ------------------ qiboot/src/cpu/s3c6410/start.S | 2 + qiboot/src/cpu/s3c6410/start_qi.c | 22 ++++-- 9 files changed, 168 insertions(+), 152 deletions(-) create mode 100644 qiboot/src/cpu/s3c6410/gta03-steppingstone.c create mode 100644 qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index 1ddf9cb..1ecf31f 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -74,6 +74,7 @@ struct board_api { unsigned long linux_tag_placement; const struct board_variant const * (*get_board_variant)(void); int (*is_this_board)(void); + void (*early_port_init)(void); void (*port_init)(void); void (*putc)(char); void (*close)(void); diff --git a/qiboot/include/s3c6410.h b/qiboot/include/s3c6410.h index 960c493..7314fc2 100644 --- a/qiboot/include/s3c6410.h +++ b/qiboot/include/s3c6410.h @@ -96,8 +96,6 @@ extern ulong virt_to_phy_smdk2416(ulong addr); extern void test_hsmmc (uint width, uint test, uint start_blk, uint blknum); -/* external variables */ -extern struct movi_offset_t ofsinfo; //#include @@ -107,7 +105,7 @@ typedef enum { S3C64XX_UART2, } S3C64XX_UARTS_NR; -#define __REG(x) (*((unsigned int *)(x))) +#define __REG(x) (*((volatile unsigned int *)(x))) //#include #endif diff --git a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c new file mode 100644 index 0000000..be5d37b --- /dev/null +++ b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c @@ -0,0 +1,76 @@ +#include +#include +#include +#include + +#define GTA03_DEBUG_UART 3 + +/* out of steppingstone */ +extern const struct board_variant const * get_board_variant_gta03(void); +extern void port_init_gta03(void); + + +int is_this_board_gta03(void) +{ + /* FIXME: find something gta03 specific */ + return 1; +} + +static void putc_gta03(char c) +{ + serial_putc_s3c64xx(GTA03_DEBUG_UART, c); +} + +int sd_card_init_gta03(void) +{ + extern int s3c6410_mmc_init(int verbose); + + return s3c6410_mmc_init(1); +} + +int sd_card_block_read_gta03(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_gta03 = { + .name = "GTA03", + .linux_machine_id = 1866, + .linux_mem_start = 0x50000000, + .linux_mem_size = (128 * 1024 * 1024), + .linux_tag_placement = 0x50000000 + 0x100, + .get_board_variant = get_board_variant_gta03, + .is_this_board = is_this_board_gta03, + .port_init = port_init_gta03, + .putc = putc_gta03, + .kernel_source = { + [0] = { + .name = "SD Card rootfs", + .block_read = sd_card_block_read_gta03, + .filesystem = FS_EXT2, + .partition_index = 2, + .filepath = "boot/uImage.bin", + .initramfs_filepath = "boot/initramfs.gz", + .commandline = "console=ttySAC3,115200 " \ + "loglevel=8 init=/bin/sh " \ + "root=/dev/ram ramdisk_size=6000000" + }, + [1] = { + .name = "SD Card backup rootfs", + .block_read = sd_card_block_read_gta03, + .filesystem = FS_EXT2, + .partition_index = 3, + .filepath = "boot/uImage.bin", + .initramfs_filepath = "boot/initramfs.gz", + .commandline = "console=ttySAC3,115200 " \ + "loglevel=8 init=/bin/sh " + }, }, +}; + diff --git a/qiboot/src/cpu/s3c6410/gta03.c b/qiboot/src/cpu/s3c6410/gta03.c index d2141ca..167746f 100644 --- a/qiboot/src/cpu/s3c6410/gta03.c +++ b/qiboot/src/cpu/s3c6410/gta03.c @@ -5,8 +5,6 @@ #include #include -#define GTA03_DEBUG_UART 3 - #define PCF50633_I2C_ADS 0x73 const struct pcf50633_init gta03_pcf50633_init[] = { @@ -795,67 +793,3 @@ const struct board_variant const * get_board_variant_gta03(void) return &board_variants[gta03_get_pcb_revision()]; } -int is_this_board_gta03(void) -{ - /* FIXME: find something gta03 specific */ - return 1; -} - -static __attribute__ (( section (".steppingstone") )) void putc_gta03(char c) -{ - serial_putc_s3c64xx(GTA03_DEBUG_UART, c); -} - -int sd_card_init_gta03(void) -{ - extern int s3c6410_mmc_init(int verbose); - - return s3c6410_mmc_init(1); -} - -int sd_card_block_read_gta03(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_gta03 = { - .name = "GTA03", - .linux_machine_id = 1866, - .linux_mem_start = 0x50000000, - .linux_mem_size = (128 * 1024 * 1024), - .linux_tag_placement = 0x50000000 + 0x100, - .get_board_variant = get_board_variant_gta03, - .is_this_board = is_this_board_gta03, - .port_init = port_init_gta03, - .putc = putc_gta03, - .kernel_source = { - [0] = { - .name = "SD Card rootfs", - .block_read = sd_card_block_read_gta03, - .filesystem = FS_EXT2, - .partition_index = 2, - .filepath = "boot/uImage.bin", - .initramfs_filepath = "boot/initramfs.gz", - .commandline = "console=ttySAC3,115200 " \ - "loglevel=8 init=/bin/sh " \ - "root=/dev/ram ramdisk_size=6000000" - }, - [1] = { - .name = "SD Card backup rootfs", - .block_read = sd_card_block_read_gta03, - .filesystem = FS_EXT2, - .partition_index = 3, - .filepath = "boot/uImage.bin", - .initramfs_filepath = "boot/initramfs.gz", - .commandline = "console=ttySAC3,115200 " \ - "loglevel=8 init=/bin/sh " - }, }, -}; - diff --git a/qiboot/src/cpu/s3c6410/qi.lds b/qiboot/src/cpu/s3c6410/qi.lds index 4bdddb8..41defed 100644 --- a/qiboot/src/cpu/s3c6410/qi.lds +++ b/qiboot/src/cpu/s3c6410/qi.lds @@ -45,12 +45,12 @@ SECTIONS 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/gta03.o (.text .rodata* .data .bss) - src/cpu/s3c6410/smdk6410.o (.text .rodata* .data .bss) + src/cpu/s3c6410/gta03-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) +/* src/ctype.o (.text .rodata* .data .bss) */ * (.steppingstone) } diff --git a/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c b/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c new file mode 100644 index 0000000..02b22e6 --- /dev/null +++ b/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c @@ -0,0 +1,71 @@ +#include +#include +#include + +#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, + .kernel_source = { + [0] = { + .name = "SD Card rootfs", + .block_read = sd_card_block_read_smdk6410, + .filesystem = FS_EXT2, + .partition_index = 2, + .filepath = "boot/uImage.bin", + .initramfs_filepath = "boot/initramfs.gz", + .commandline = "console=ttySAC0,115200 " \ + "loglevel=8 init=/bin/sh " \ + " root=/dev/ram ramdisk_size=6000000" + }, + [1] = { + .name = "SD Card backup rootfs", + .block_read = sd_card_block_read_smdk6410, + .filesystem = FS_EXT2, + .partition_index = 3, + .filepath = "boot/uImage.bin", + .initramfs_filepath = "boot/initramfs.gz", + .commandline = "console=ttySAC0,115200 " \ + "loglevel=8 init=/bin/sh " + }, }, +}; + diff --git a/qiboot/src/cpu/s3c6410/smdk6410.c b/qiboot/src/cpu/s3c6410/smdk6410.c index 5085fd4..63dc3b6 100644 --- a/qiboot/src/cpu/s3c6410/smdk6410.c +++ b/qiboot/src/cpu/s3c6410/smdk6410.c @@ -2,9 +2,6 @@ #include #include -#define SMDK6410_DEBUG_UART 0 - - static const struct board_variant board_variants[] = { [0] = { .name = "SMDK", @@ -12,11 +9,6 @@ static const struct board_variant board_variants[] = { }, }; -void port_init_smdk6410(void) -{ - -} - /** * returns PCB revision information in b0, d8, d9 * SMDK6410 EVB returns 0x000 @@ -33,67 +25,3 @@ const struct board_variant const * get_board_variant_smdk6410(void) return &board_variants[smdk6410_get_pcb_revision()]; } -int is_this_board_smdk6410(void) -{ - /* FIXME: find something smdk6410 specific */ - return 1; -} - -static __attribute__ (( section (".steppingstone") )) 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 = 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, - .port_init = port_init_smdk6410, - .putc = putc_smdk6410, - .kernel_source = { - [0] = { - .name = "SD Card rootfs", - .block_read = sd_card_block_read_smdk6410, - .filesystem = FS_EXT2, - .partition_index = 2, - .filepath = "boot/uImage.bin", - .initramfs_filepath = "boot/initramfs.gz", - .commandline = "console=ttySAC0,115200 " \ - "loglevel=8 init=/bin/sh " \ - " root=/dev/ram ramdisk_size=6000000" - }, - [1] = { - .name = "SD Card backup rootfs", - .block_read = sd_card_block_read_smdk6410, - .filesystem = FS_EXT2, - .partition_index = 3, - .filepath = "boot/uImage.bin", - .initramfs_filepath = "boot/initramfs.gz", - .commandline = "console=ttySAC0,115200 " \ - "loglevel=8 init=/bin/sh " - }, }, -}; - diff --git a/qiboot/src/cpu/s3c6410/start.S b/qiboot/src/cpu/s3c6410/start.S index 3d63fc7..ad2ef6c 100644 --- a/qiboot/src/cpu/s3c6410/start.S +++ b/qiboot/src/cpu/s3c6410/start.S @@ -421,6 +421,8 @@ start_code: ldr r1, =0x1FFF str r1, [r0, #UDIVSLOT_OFFSET] + ldr r1, =0x55 + str r1, [r0, #UTXH_OFFSET] @'U' /* >> CFG_VIDEO_LOGO_MAX_SIZE */ #define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ diff --git a/qiboot/src/cpu/s3c6410/start_qi.c b/qiboot/src/cpu/s3c6410/start_qi.c index 28d70ee..b5b7cb9 100644 --- a/qiboot/src/cpu/s3c6410/start_qi.c +++ b/qiboot/src/cpu/s3c6410/start_qi.c @@ -80,7 +80,9 @@ void start_qi(void) /* okay, do the critical port and serial init for our board */ - this_board->port_init(); + if (this_board->early_port_init) + this_board->early_port_init(); + set_putc_func(this_board->putc); /* stick some hello messages on debug console */ @@ -90,13 +92,7 @@ void start_qi(void) 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"); + puts(stringify2(BUILD_DATE) " Copyright (C) 2008 Openmoko, Inc.\n\n"); if (!is_jtag) { /* @@ -122,6 +118,16 @@ void start_qi(void) 256 * 2, (u8 *)0x53000000); } + /* all of Qi is in memory now, stuff outside steppingstone too */ + + if (this_board->port_init) + this_board->port_init(); + + 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 From decf58f0430193f8d82c7ccfc7c84687fe63b64c Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:42 +0000 Subject: [PATCH 133/248] qi-gta03-get-dynamic-board-rev.patch Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/gta03.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/qiboot/src/cpu/s3c6410/gta03.c b/qiboot/src/cpu/s3c6410/gta03.c index 167746f..b8beb83 100644 --- a/qiboot/src/cpu/s3c6410/gta03.c +++ b/qiboot/src/cpu/s3c6410/gta03.c @@ -369,15 +369,15 @@ void port_init_gta03(void) /* ---------------------------- Port I ---------------------------- */ __REG(GPICON) = - (2 << 0) | /* GPI0 - LCD_VD0 */ - (2 << 2) | /* GPI1 - LCD_VD1 */ + (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 */ - (2 << 16) | /* GPI8 - LCD_VD8 */ + (0 << 16) | /* GPI8 - INPUT version b2 */ (2 << 18) | /* GPI9 - LCD_VD9 */ (2 << 20) | /* GPI10 - LCD_VD10 */ (2 << 22) | /* GPI11 - LCD_VD11 */ @@ -777,15 +777,14 @@ void port_init_gta03(void) } -/** - * returns PCB revision information in b0, d8, d9 - * GTA03 EVB returns 0x000 - * GTA03 returns 0x001 - */ - int gta03_get_pcb_revision(void) { - return 0; /* always SMDK right now */ + u32 v = __REG(GPIDAT); + + return (v & (1 << 8)) >> (8 - 2) | + (v & (1 << 1)) >> 0 | + (v & (1 << 0)) >> 0 + ; } const struct board_variant const * get_board_variant_gta03(void) From 776fdbd42c8f9a23156b7c4ebee0129804bfffea Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:42 +0000 Subject: [PATCH 134/248] qi-gta03-smdk6410-sdcard-rootfs.patch Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/gta03-steppingstone.c | 17 ++++++++++++----- qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c | 7 +++---- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c index be5d37b..731604d 100644 --- a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c @@ -40,6 +40,13 @@ unsigned long s3c6410_mmc_bread(int dev_num, unsigned long blknr, unsigned long /* * our API for bootloader on this machine */ + +/* for initrd: + * .initramfs_filepath = "boot/initramfs.gz", + * and + * "root=/dev/ram ramdisk_size=6000000" + */ + const struct board_api board_api_gta03 = { .name = "GTA03", .linux_machine_id = 1866, @@ -57,10 +64,9 @@ const struct board_api board_api_gta03 = { .filesystem = FS_EXT2, .partition_index = 2, .filepath = "boot/uImage.bin", - .initramfs_filepath = "boot/initramfs.gz", .commandline = "console=ttySAC3,115200 " \ "loglevel=8 init=/bin/sh " \ - "root=/dev/ram ramdisk_size=6000000" + "root=/dev/mmcblk0p2 rootfstype=ext3" }, [1] = { .name = "SD Card backup rootfs", @@ -68,9 +74,10 @@ const struct board_api board_api_gta03 = { .filesystem = FS_EXT2, .partition_index = 3, .filepath = "boot/uImage.bin", - .initramfs_filepath = "boot/initramfs.gz", .commandline = "console=ttySAC3,115200 " \ - "loglevel=8 init=/bin/sh " - }, }, + "loglevel=8 init=/bin/sh " \ + "root=/dev/mmcblk0p3 rootfstype=ext3" + }, + }, }; diff --git a/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c b/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c index 02b22e6..e7caab8 100644 --- a/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c @@ -52,10 +52,9 @@ const struct board_api board_api_smdk6410 = { .filesystem = FS_EXT2, .partition_index = 2, .filepath = "boot/uImage.bin", - .initramfs_filepath = "boot/initramfs.gz", .commandline = "console=ttySAC0,115200 " \ "loglevel=8 init=/bin/sh " \ - " root=/dev/ram ramdisk_size=6000000" + "root=/dev/mmcblk0p2 rootfstype=ext3" }, [1] = { .name = "SD Card backup rootfs", @@ -63,9 +62,9 @@ const struct board_api board_api_smdk6410 = { .filesystem = FS_EXT2, .partition_index = 3, .filepath = "boot/uImage.bin", - .initramfs_filepath = "boot/initramfs.gz", .commandline = "console=ttySAC0,115200 " \ - "loglevel=8 init=/bin/sh " + "loglevel=8 init=/bin/sh " \ + "root=/dev/mmcblk0p3 rootfstype=ext3" }, }, }; From c384afb378acd6b70cbfcccc646a9c857be941fe Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:42 +0000 Subject: [PATCH 135/248] qi-gta03-priority.patch Prefer GTA03, enable dual mDDR init (killing SMDK compatability for now) fix bugs in GPIO register offsets, set loglevel=8 for GTA03 Signed-off-by: Andy Green --- qiboot/include/s3c6410.h | 15 ++++----------- qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c | 2 +- qiboot/src/cpu/s3c6410/start.S | 2 +- qiboot/src/cpu/s3c6410/start_qi.c | 2 +- 4 files changed, 7 insertions(+), 14 deletions(-) diff --git a/qiboot/include/s3c6410.h b/qiboot/include/s3c6410.h index 7314fc2..baad9f5 100644 --- a/qiboot/include/s3c6410.h +++ b/qiboot/include/s3c6410.h @@ -33,7 +33,7 @@ #define CONFIG_S3C6410 1 #endif -#define S3C64XX_UART_CHANNELS 3 +#define S3C64XX_UART_CHANNELS 4 #define S3C64XX_SPI_CHANNELS 2 #define HSMMC_CHANNEL 0 @@ -326,9 +326,9 @@ typedef enum { #define GPACONSLP_OFFSET 0x0C #define GPAPUDSLP_OFFSET 0x10 #define GPBCON_OFFSET 0x20 -#define GPBDAT_OFFSET 0x04 -#define GPBPUD_OFFSET 0x08 -#define GPBCONSLP_OFFSET 0x0C +#define GPBDAT_OFFSET 0x24 +#define GPBPUD_OFFSET 0x28 +#define GPBCONSLP_OFFSET 0x2C #define GPBPUDSLP_OFFSET 0x30 #define GPCCON_OFFSET 0x40 #define GPCDAT_OFFSET 0x44 @@ -1133,13 +1133,6 @@ typedef enum { #define ELFIN_UART1_OFFSET 0x0400 #define ELFIN_UART2_OFFSET 0x0800 -#ifdef CONFIG_SERIAL1 -#define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART0_OFFSET) -#elif defined(CONFIG_SERIAL2) -#define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART1_OFFSET) -#else -#define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART0_OFFSET) -#endif #define ULCON_OFFSET 0x00 #define UCON_OFFSET 0x04 diff --git a/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c b/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c index e7caab8..b8c3237 100644 --- a/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c @@ -53,7 +53,7 @@ const struct board_api board_api_smdk6410 = { .partition_index = 2, .filepath = "boot/uImage.bin", .commandline = "console=ttySAC0,115200 " \ - "loglevel=8 init=/bin/sh " \ + "loglevel=3 init=/bin/sh " \ "root=/dev/mmcblk0p2 rootfstype=ext3" }, [1] = { diff --git a/qiboot/src/cpu/s3c6410/start.S b/qiboot/src/cpu/s3c6410/start.S index ad2ef6c..a7da554 100644 --- a/qiboot/src/cpu/s3c6410/start.S +++ b/qiboot/src/cpu/s3c6410/start.S @@ -27,7 +27,7 @@ #define TEXT_BASE 0x53000000 -#define S3C6410_POP_A 0 +#define S3C6410_POP_A 1 #define set_pll(mdiv, pdiv, sdiv) (1<<31 | mdiv<<16 | pdiv<<8 | sdiv) diff --git a/qiboot/src/cpu/s3c6410/start_qi.c b/qiboot/src/cpu/s3c6410/start_qi.c index b5b7cb9..622131c 100644 --- a/qiboot/src/cpu/s3c6410/start_qi.c +++ b/qiboot/src/cpu/s3c6410/start_qi.c @@ -34,8 +34,8 @@ extern void bootloader_second_phase(void); const struct board_api *boards[] = { - &board_api_smdk6410, &board_api_gta03, + &board_api_smdk6410, NULL /* always last */ }; From 37cf1238a9a5bef34fb087a2883f7b26021d1b55 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:43 +0000 Subject: [PATCH 136/248] qi-gta03-add-openocd-config.patch Signed-off-by: Andy Green --- qiboot/openocd-openmoko-debug-6410.cfg | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 qiboot/openocd-openmoko-debug-6410.cfg diff --git a/qiboot/openocd-openmoko-debug-6410.cfg b/qiboot/openocd-openmoko-debug-6410.cfg new file mode 100644 index 0000000..a8ac051 --- /dev/null +++ b/qiboot/openocd-openmoko-debug-6410.cfg @@ -0,0 +1,16 @@ +# 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 + From a607f194fb196e32630ca7ece3f0693b807f8b89 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:43 +0000 Subject: [PATCH 137/248] qi-gta03-pulldown-card-detect-mmc0.patch We don't have card detect connected. Try to fake it better by enabling the peripheral fuction to the ball and forcing pulldown (card detect is active-low). Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/gta03.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qiboot/src/cpu/s3c6410/gta03.c b/qiboot/src/cpu/s3c6410/gta03.c index b8beb83..c96bdd6 100644 --- a/qiboot/src/cpu/s3c6410/gta03.c +++ b/qiboot/src/cpu/s3c6410/gta03.c @@ -292,10 +292,10 @@ void port_init_gta03(void) (2 << 12) | /* GPG3 - MMC_DATA10 */ (2 << 16) | /* GPG4 - MMC_DATA20 */ (2 << 20) | /* GPG5 - MMC_DATA30 */ - (1 << 24) /* GPG6 - (NC) OUTPUT 0 */ + (2 << 24) /* GPG6 - (NC) MMC CARD DETECT */ ; - __REG(GPGPUD) = 0; /* all pullup and pulldown disabled */ + __REG(GPGPUD) = (1 << (6 * 2)); /* pull down card detect */ __REG(GPGDAT) = 0; /* just for determinism */ From f18c42310fe5b1a05bdaac2a64430db6bf4a75bd Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:44 +0000 Subject: [PATCH 138/248] qi-clean-s3c6410.h-add-uart3.patch Signed-off-by: Andy Green --- qiboot/include/s3c6410.h | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/qiboot/include/s3c6410.h b/qiboot/include/s3c6410.h index baad9f5..a11fbec 100644 --- a/qiboot/include/s3c6410.h +++ b/qiboot/include/s3c6410.h @@ -74,35 +74,15 @@ struct movi_offset_t { extern void hsmmc_set_gpio(void); extern void hsmmc_reset (void); extern int hsmmc_init (void); -extern int movi_init(void); -extern void movi_set_capacity(void); -extern int movi_set_ofs(uint last); -extern void movi_write (uint addr, uint start_blk, uint blknum); -extern void movi_read (uint addr, uint start_blk, uint blknum); -extern void movi_write_env(ulong addr); -extern void movi_read_env(ulong addr); - -#if defined(CONFIG_S3C2450) -extern ulong virt_to_phy_smdk2450(ulong addr); -#elif defined(CONFIG_S3C6400) -extern ulong virt_to_phy_smdk6400(ulong addr); -#elif defined(CONFIG_S3C6410) -extern ulong virt_to_phy_smdk6410(ulong addr); -#elif defined(CONFIG_S3C6430) -extern ulong virt_to_phy_smdk6430(ulong addr); -#elif defined(CONFIG_S3C2416) -extern ulong virt_to_phy_smdk2416(ulong addr); -#endif extern void test_hsmmc (uint width, uint test, uint start_blk, uint blknum); -//#include - typedef enum { S3C64XX_UART0, S3C64XX_UART1, S3C64XX_UART2, + S3C64XX_UART3, } S3C64XX_UARTS_NR; #define __REG(x) (*((volatile unsigned int *)(x))) @@ -1132,7 +1112,7 @@ typedef enum { #define ELFIN_UART0_OFFSET 0x0000 #define ELFIN_UART1_OFFSET 0x0400 #define ELFIN_UART2_OFFSET 0x0800 - +#define ELFIN_UART3_OFFSET 0x0c00 #define ULCON_OFFSET 0x00 #define UCON_OFFSET 0x04 From b3714a932b60e7e774609ea2eb5c08e8a3b4be04 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:44 +0000 Subject: [PATCH 139/248] qi-gta03-populate-variant-list.patch The first revision for GTA03 A1 is "1", but we only populated the info for revision 0. Reported-by: Christopher Hall Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/gta03.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/qiboot/src/cpu/s3c6410/gta03.c b/qiboot/src/cpu/s3c6410/gta03.c index c96bdd6..ff9c641 100644 --- a/qiboot/src/cpu/s3c6410/gta03.c +++ b/qiboot/src/cpu/s3c6410/gta03.c @@ -46,8 +46,36 @@ const struct pcf50633_init gta03_pcf50633_init[] = { static const struct board_variant board_variants[] = { [0] = { - .name = "GTA03 EVT1", + .name = "GTA03 unknown", + .machine_revision = 0 + }, + [1] = { + .name = "GTA03 A1", .machine_revision = 1 + }, + [2] = { + .name = "GTA03 A2", + .machine_revision = 2 + }, + [3] = { + .name = "GTA03 A3", + .machine_revision = 3 + }, + [4] = { + .name = "GTA03 A4", + .machine_revision = 4 + }, + [5] = { + .name = "GTA03 A5", + .machine_revision = 5 + }, + [6] = { + .name = "GTA03 A6", + .machine_revision = 6 + }, + [7] = { + .name = "GTA03 A7", + .machine_revision = 7 } }; From 8ce5b645e6c6eaf51e3ad2a3e0a728fd1de6fed0 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:44 +0000 Subject: [PATCH 140/248] qi-fix-gta03-boot-uart3.patch Set GPIO and UART init for UART3 suitable for GTA03 (breaks SMDK UART right now) Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/start.S | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/qiboot/src/cpu/s3c6410/start.S b/qiboot/src/cpu/s3c6410/start.S index a7da554..dbb9883 100644 --- a/qiboot/src/cpu/s3c6410/start.S +++ b/qiboot/src/cpu/s3c6410/start.S @@ -400,10 +400,10 @@ start_code: /* set GPIO to enable UART */ @ GPIO setting for UART ldr r0, =ELFIN_GPIO_BASE - ldr r1, =0x220022 - str r1, [r0, #GPACON_OFFSET] + ldr r1, =0x2222 + str r1, [r0, #GPBCON_OFFSET] - ldr r0, =ELFIN_UART_CONSOLE_BASE @0x7F005000 + ldr r0, =ELFIN_UART_BASE + ELFIN_UART3_OFFSET @0x7F005c00 uart 3 mov r1, #0x0 str r1, [r0, #UFCON_OFFSET] str r1, [r0, #UMCON_OFFSET] @@ -442,13 +442,6 @@ clbss_l: cmp r0, r1 ble clbss_l -#if 0 - ldr r0, =ELFIN_UART_CONSOLE_BASE - ldr r1, =0x55 - push {r1} - pop {r1} - str r1, [r0, #UTXH_OFFSET] @'U' -#endif b _steppingstone_done 4: From e856eed04a3148b639f428167d48a84a3e6ef87f Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:44 +0000 Subject: [PATCH 141/248] qi-doc-README-update.patch Signed-off-by: Andy Green --- qiboot/README | 102 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 97 insertions(+), 5 deletions(-) diff --git a/qiboot/README b/qiboot/README index e489299..abff09f 100644 --- a/qiboot/README +++ b/qiboot/README @@ -1,5 +1,97 @@ -Backlight turns on right away, but screen remains blank until kernel load, -and kernel does NOT output gobs of text to the screen. -Will ALWAYS boot from uSD if first partition is ext2 and contains -/boot/uImage.bin, otherwise boots from NAND. -No splash screen. +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.bin. + +The kernel commandline used is associated with the storage device, this allows +the correct root= line to be arrived at without any work. The inability to set +the Qi kernel commandline externally is deliberate, two otherwise identical +devices differing by the kernel commandline or other "environment" is not good. +A whole class of bugs and support issues around private bootloader state are +therefore avoided. + +If no kernel image can be found, Qi falls back to doing a memory test. + + +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. + + +Functional Differences from U-Boot on GTA02 +=========================================== + + - Backlight is not enabled until Linux starts after a few seconds + + - kernel loglevel is set to NOT output gobs of text to the screen + + - On GTA02 will ALWAYS boot from uSD if first partition is ext2 and contains + /boot/uImage.bin, otherwise boots from NAND + + - On GTA03 will ALWAYS boot from uSD second partition if /boot/uImage.bin is + present otherwise try the third / backup partition + + - No startup splash screen + + - 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. + + - USB is not started until Linux starts around 5 seconds after boot, there is + no DFU. From 938a79d90dbcbf9e6905b6e293e17623984abd3c Mon Sep 17 00:00:00 2001 From: Micael Henriksson Date: Fri, 28 Nov 2008 10:16:44 +0000 Subject: [PATCH 142/248] qi-add-s3c2410-cpu.patch This patch add support for s3c2410 in Qi. Signed-off-by: Micael Henriksson --- qiboot/include/neo_gta01.h | 30 + qiboot/include/pcf50606.h | 260 +++++++++ qiboot/src/cpu/s3c2410/gta01.c | 291 ++++++++++ qiboot/src/cpu/s3c2410/i2c-bitbang-s3c24xx.c | 68 +++ qiboot/src/cpu/s3c2410/lowlevel_init.S | 162 ++++++ qiboot/src/cpu/s3c2410/nand_read.c | 136 +++++ qiboot/src/cpu/s3c2410/nand_read.h | 22 + qiboot/src/cpu/s3c2410/qi.lds | 63 +++ qiboot/src/cpu/s3c2410/s3c24xx-mci.c | 565 +++++++++++++++++++ qiboot/src/cpu/s3c2410/serial-s3c24xx.c | 77 +++ qiboot/src/cpu/s3c2410/start.S | 304 ++++++++++ qiboot/src/cpu/s3c2410/start_qi.c | 131 +++++ 12 files changed, 2109 insertions(+) create mode 100644 qiboot/include/neo_gta01.h create mode 100644 qiboot/include/pcf50606.h create mode 100644 qiboot/src/cpu/s3c2410/gta01.c create mode 100644 qiboot/src/cpu/s3c2410/i2c-bitbang-s3c24xx.c create mode 100644 qiboot/src/cpu/s3c2410/lowlevel_init.S create mode 100644 qiboot/src/cpu/s3c2410/nand_read.c create mode 100644 qiboot/src/cpu/s3c2410/nand_read.h create mode 100644 qiboot/src/cpu/s3c2410/qi.lds create mode 100644 qiboot/src/cpu/s3c2410/s3c24xx-mci.c create mode 100644 qiboot/src/cpu/s3c2410/serial-s3c24xx.c create mode 100644 qiboot/src/cpu/s3c2410/start.S create mode 100644 qiboot/src/cpu/s3c2410/start_qi.c diff --git a/qiboot/include/neo_gta01.h b/qiboot/include/neo_gta01.h new file mode 100644 index 0000000..6b4b174 --- /dev/null +++ b/qiboot/include/neo_gta01.h @@ -0,0 +1,30 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: xiangfu liu + * + * 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 +extern const struct board_api board_api_gta01; +#endif + +#define TEXT_BASE 0x33000000 + +#endif /* __CONFIG_H */ diff --git a/qiboot/include/pcf50606.h b/qiboot/include/pcf50606.h new file mode 100644 index 0000000..b0a1807 --- /dev/null +++ b/qiboot/include/pcf50606.h @@ -0,0 +1,260 @@ +#ifndef _PCF50606_H +#define _PCF50606_H + +/* Philips PCF50606 Power Managemnt Unit (PMU) driver + * (C) 2006-2007 by OpenMoko, Inc. + * Author: Harald Welte + * + */ + +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 */ + diff --git a/qiboot/src/cpu/s3c2410/gta01.c b/qiboot/src/cpu/s3c2410/gta01.c new file mode 100644 index 0000000..5d97daa --- /dev/null +++ b/qiboot/src/cpu/s3c2410/gta01.c @@ -0,0 +1,291 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: Andy Green + * + * 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 +#include +#include +#include +#include +#include +#include + +#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)(); +} + +/* + * 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, + /* 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", + .commandline = "mtdparts=" \ + "neo1973-nand:" \ + "0x00040000(qi)," \ + "0x00004000(u-boot_env)," \ + "0x00200000(kernel)," \ + "0x000a0000(splash)," \ + "0x03d1c000(rootfs) " \ + "rootfstype=ext3 " \ + "root=/dev/mmcblk0p2 " \ + "console=ttySAC0,115200 " \ + "loglevel=4 " \ + "init=/sbin/init "\ + "ro" + }, + [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", + .commandline = "mtdparts=" \ + "neo1973-nand:" \ + "0x00040000(qi)," \ + "0x00004000(u-boot_env)," \ + "0x00200000(kernel)," \ + "0x000a0000(splash)," \ + "0x03d1c000(rootfs) " \ + "rootfstype=ext3 " \ + "root=/dev/mmcblk0p2 " \ + "console=ttySAC0,115200 " \ + "loglevel=4 " \ + "init=/sbin/init "\ + "ro" + }, + [2] = { + .name = "NAND Kernel", + .block_read = nand_read_ll, + .offset_blocks512_if_no_partition = 0x44000 / 512, + .filesystem = FS_RAW, + .commandline = "mtdparts=" \ + "neo1973-nand:" \ + "0x00040000(qi)," \ + "0x00004000(u-boot_env)," \ + "0x00200000(kernel)," \ + "0x000a0000(splash)," \ + "0x03d1c000(rootfs) " \ + "rootfstype=jffs2 " \ + "root=/dev/mtdblock4 " \ + "console=ttySAC0,115200 " \ + "loglevel=4 " \ + "init=/sbin/init "\ + "ro" + }, + }, +}; diff --git a/qiboot/src/cpu/s3c2410/i2c-bitbang-s3c24xx.c b/qiboot/src/cpu/s3c2410/i2c-bitbang-s3c24xx.c new file mode 100644 index 0000000..c2d46ed --- /dev/null +++ b/qiboot/src/cpu/s3c2410/i2c-bitbang-s3c24xx.c @@ -0,0 +1,68 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: Andy Green + * + * 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 +#include +#include + +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, +}; diff --git a/qiboot/src/cpu/s3c2410/lowlevel_init.S b/qiboot/src/cpu/s3c2410/lowlevel_init.S new file mode 100644 index 0000000..2b14373 --- /dev/null +++ b/qiboot/src/cpu/s3c2410/lowlevel_init.S @@ -0,0 +1,162 @@ +/* + * Memory Setup stuff - taken from blob memsetup.S + * + * Modified for the FIC Neo1973 GTA01 by Harald Welte + * + * 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 + * #include + */ +#define __ASM_MODE__ +#include + +/* + * + * Taken from linux/arch/arm/boot/compressed/head-s3c2410.S + * + * Copyright (C) 2002 Samsung Electronics SW.LEE + * + */ + +#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 diff --git a/qiboot/src/cpu/s3c2410/nand_read.c b/qiboot/src/cpu/s3c2410/nand_read.c new file mode 100644 index 0000000..83b1651 --- /dev/null +++ b/qiboot/src/cpu/s3c2410/nand_read.c @@ -0,0 +1,136 @@ +/* + * 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 + * Date : $Date: 2004/02/04 10:37:37 $ + * + * u-boot integration and bad-block skipping (C) 2006 by OpenMoko, Inc. + * Author: Harald Welte + */ + +/* NOTE this stuff runs in steppingstone context! */ + +/* the API refers to 512-byte blocks */ + +#include +#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; +} + diff --git a/qiboot/src/cpu/s3c2410/nand_read.h b/qiboot/src/cpu/s3c2410/nand_read.h new file mode 100644 index 0000000..71aeda5 --- /dev/null +++ b/qiboot/src/cpu/s3c2410/nand_read.h @@ -0,0 +1,22 @@ +/* + * 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 + * Date : $Date: 2004/02/04 10:37:37 $ + * + * u-boot integration and bad-block skipping (C) 2006 by OpenMoko, Inc. + * Author: Harald Welte + */ +#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 */ diff --git a/qiboot/src/cpu/s3c2410/qi.lds b/qiboot/src/cpu/s3c2410/qi.lds new file mode 100644 index 0000000..27ba2f0 --- /dev/null +++ b/qiboot/src/cpu/s3c2410/qi.lds @@ -0,0 +1,63 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * 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 = .; +} diff --git a/qiboot/src/cpu/s3c2410/s3c24xx-mci.c b/qiboot/src/cpu/s3c2410/s3c24xx-mci.c new file mode 100644 index 0000000..7d53b42 --- /dev/null +++ b/qiboot/src/cpu/s3c2410/s3c24xx-mci.c @@ -0,0 +1,565 @@ +/* + * qi s3c24xx SD card driver + * Author: Andy Green + * based on ----> + * + * u-boot S3C2410 MMC/SD card driver + * (C) Copyright 2006 by OpenMoko, Inc. + * Author: Harald Welte + * + * 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 +#include +#include +#include + +#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; + + +#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; +} + + diff --git a/qiboot/src/cpu/s3c2410/serial-s3c24xx.c b/qiboot/src/cpu/s3c2410/serial-s3c24xx.c new file mode 100644 index 0000000..0f4ba22 --- /dev/null +++ b/qiboot/src/cpu/s3c2410/serial-s3c24xx.c @@ -0,0 +1,77 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: xiangfu liu + * + * 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 +#include + +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; + } +} diff --git a/qiboot/src/cpu/s3c2410/start.S b/qiboot/src/cpu/s3c2410/start.S new file mode 100644 index 0000000..5c9d3db --- /dev/null +++ b/qiboot/src/cpu/s3c2410/start.S @@ -0,0 +1,304 @@ +/* + * (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 + +#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 + diff --git a/qiboot/src/cpu/s3c2410/start_qi.c b/qiboot/src/cpu/s3c2410/start_qi.c new file mode 100644 index 0000000..4d9b7ae --- /dev/null +++ b/qiboot/src/cpu/s3c2410/start_qi.c @@ -0,0 +1,131 @@ +/* + * (C) Copyright 2007 OpenMoko, Inc. + * Author: xiangfu liu + * Andy Green + * + * 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 +#include "nand_read.h" +#include + +#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) + ; + +} From aeb2133dc8ab289acebe25cf25005f1c70d8d165 Mon Sep 17 00:00:00 2001 From: Micael Henriksson Date: Fri, 28 Nov 2008 10:16:44 +0000 Subject: [PATCH 143/248] qi-update-makefile.patch Update target "clean" to clean build directorys Update IDs for mkudfu Signed-off-by: Micael Henriksson --- qiboot/Makefile | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/qiboot/Makefile b/qiboot/Makefile index 7c53ecb..9c242a3 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -44,10 +44,17 @@ SRCS = ${S_SRCS} ${C_SRCS} OBJS = ${S_OBJS} ${C_OBJS} LIBS = -L${COMPILER_LIB_PATH} -lgcc -# GTA02 A5 and A6 U-Boot will eat these for DFU action -UDFU_VID = 0x1d50 -UDFU_PID = 0x5119 -UDFU_REV = 0x350 +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) @@ -77,6 +84,6 @@ ${UDFU_IMAGE}:${OBJS} ${MKUDFU} @$(OBJDUMP) -d ${TARGET} >${IMAGE}.dis clean: - @rm -f src/*.o cpu/*/*.o cpu/*/*~ src/*~ src/drivers/*.o src/drivers/*~ \ - include/*~ ${IMAGE_DIR}/* ${TARGET} ${UDFU_IMAGE} + @rm -f src/*.o src/*~ src/cpu/*/*.o src/cpu/*/*~ src/drivers/*.o \ + src/drivers/*~ src/fs/*.o src/fs/*~ include/*~ ${IMAGE_DIR}/* @make clean -C $(TOOLS) From aa813c24d5266a6edbb433af48dc24bae2f405c6 Mon Sep 17 00:00:00 2001 From: Christopher Hall Date: Fri, 28 Nov 2008 10:16:44 +0000 Subject: [PATCH 145/248] qi-fix-gta03-format-script-less-fragile-for-host-kernel.patch The hack to find the number of sectors turns out to be sensitive to the host kernel. This is a workaround until we find something in /proc or /sys that has the same info in a more accessible way. Signed-off-by: Christopher Hall --- qiboot/6410-partition-sd.sh | 28 ++++++++++++++++++++++++++-- qiboot/build | 3 ++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/qiboot/6410-partition-sd.sh b/qiboot/6410-partition-sd.sh index a2b38ef..cb1cac0 100755 --- a/qiboot/6410-partition-sd.sh +++ b/qiboot/6410-partition-sd.sh @@ -50,16 +50,40 @@ if [ ! -z "`grep $1 /proc/mounts`" ] ; then exit 2 fi -SECTORS=`dmesg | grep $1 | grep "512-byte hardware" | tail -n 1 | cut -d' ' -f4` +# set CUT_COLUMN for each OS +case "$(lsb_release --short --description)" in + Ubuntu\ 7*) + CUT_COLUMN=5 + ;; + Ubuntu\ 8.04*) + CUT_COLUMN=5 + ;; + *) + CUT_COLUMN=4 + ;; +esac + +DMESG_LINE=$(dmesg | grep "$1" | grep "512-byte hardware" | tail -n 1) +SECTORS=$(echo "${DMESG_LINE}" | cut -d' ' -f"${CUT_COLUMN}") + +if ! echo "${SECTORS}" | grep '^[[:digit:]]\+$' +then + echo "problem finding size for /dev/$1 check CUT_COLUMN value for your os" + echo "CUT_COLUMN=${CUT_COLUMN} --> ${SECTORS}" + echo "dmesg line was:" + echo "${DMESG_LINE}" + exit 3 +fi if [ $SECTORS -le 0 ] ; then echo "problem finding size for /dev/$1" exit 3 fi +echo "$1 is $SECTORS 512-byte blocks" + if [ -z "$4" ] ; then - echo "$1 is $SECTORS 512-byte blocks" FATSECTORS=$(( $SECTORS - $EXT3_TOTAL_SECTORS + $REARSECTORS )) FATMB=$(( $FATSECTORS / 2048 - 16 )) diff --git a/qiboot/build b/qiboot/build index c9c7788..87684bb 100755 --- a/qiboot/build +++ b/qiboot/build @@ -2,7 +2,8 @@ make clean && \ make CPU=s3c6410 && \ -make CPU=s3c2442 +make CPU=s3c2442 && \ +make CPU=s3c2410 # as root then... # From d80dd5b880c14698d9a0dfb39ecb4e8ff809975c Mon Sep 17 00:00:00 2001 From: Christopher Hall Date: Fri, 28 Nov 2008 10:16:44 +0000 Subject: [PATCH 146/248] qi-clean-makefile-clean.patch Just tidy up the clean rm-s Signed-off-by: Christopher Hall --- qiboot/Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/qiboot/Makefile b/qiboot/Makefile index 9c242a3..2ac0e2c 100644 --- a/qiboot/Makefile +++ b/qiboot/Makefile @@ -84,6 +84,10 @@ ${UDFU_IMAGE}:${OBJS} ${MKUDFU} @$(OBJDUMP) -d ${TARGET} >${IMAGE}.dis clean: - @rm -f src/*.o src/*~ src/cpu/*/*.o src/cpu/*/*~ src/drivers/*.o \ - src/drivers/*~ src/fs/*.o src/fs/*~ include/*~ ${IMAGE_DIR}/* + @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) + From 31fe321be553efacde58bddaf31c537c1ae90ce6 Mon Sep 17 00:00:00 2001 From: Christopher Hall Date: Fri, 28 Nov 2008 10:16:44 +0000 Subject: [PATCH 147/248] qi-fix-compute-GTA03-pcb-rev-backwards.patch Hm the revision bit ordering is backwards... oh well Signed-off-by: Christopher Hall --- qiboot/src/cpu/s3c6410/gta03.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/qiboot/src/cpu/s3c6410/gta03.c b/qiboot/src/cpu/s3c6410/gta03.c index ff9c641..15f41ae 100644 --- a/qiboot/src/cpu/s3c6410/gta03.c +++ b/qiboot/src/cpu/s3c6410/gta03.c @@ -808,11 +808,20 @@ void port_init_gta03(void) int gta03_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)) >> (8 - 2) | - (v & (1 << 1)) >> 0 | - (v & (1 << 0)) >> 0 - ; + return ( + ((v & (1 << 8)) ? 1 : 0) | + ((v & (1 << 1)) ? 2 : 0) | + ((v & (1 << 0)) ? 4 : 0) + ); } const struct board_variant const * get_board_variant_gta03(void) From c6531168f6d8aa89dff39d35aa425e13c9516e58 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:44 +0000 Subject: [PATCH 148/248] qi-introduce-device-named-kernels.patch This patch changes Qi to insist to fetch device-specific kernels from filesystems that have named kernels. The kernels looked for are now called GTA01: /boot/uImage-GTA01.bin GTA02: /boot/uImage-GTA02.bin GTA03: /boot/uImage-GTA03.bin This is part of the support for single rootfs that can be run on multiple devices with correct kernel and module handling by the bootloader. Signed-off-by: Andy Green --- qiboot/dfu-qi | 6 +++--- qiboot/src/cpu/s3c2410/gta01.c | 4 ++-- qiboot/src/cpu/s3c2442/gta02.c | 4 ++-- qiboot/src/cpu/s3c6410/gta03-steppingstone.c | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/qiboot/dfu-qi b/qiboot/dfu-qi index 7bd103d..f5e6e1e 100755 --- a/qiboot/dfu-qi +++ b/qiboot/dfu-qi @@ -1,7 +1,7 @@ #!/bin/bash -../dfu-util/src/dfu-util -a 1 -d 0x1d50:0x5119 -D image/qi-*.udfu +../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-*.udfu -../dfu-util/src/dfu-util -a 1 -d 0x1d50:0x5119 -D image/qi-*.udfu +../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 diff --git a/qiboot/src/cpu/s3c2410/gta01.c b/qiboot/src/cpu/s3c2410/gta01.c index 5d97daa..b6d6db8 100644 --- a/qiboot/src/cpu/s3c2410/gta01.c +++ b/qiboot/src/cpu/s3c2410/gta01.c @@ -232,7 +232,7 @@ const struct board_api board_api_gta01 = { .block_read = sd_card_block_read_gta01, .partition_index = 1, .filesystem = FS_EXT2, - .filepath = "boot/uImage", + .filepath = "boot/uImage-GTA01.bin", .commandline = "mtdparts=" \ "neo1973-nand:" \ "0x00040000(qi)," \ @@ -253,7 +253,7 @@ const struct board_api board_api_gta01 = { .block_read = sd_card_block_read_gta01, .partition_index = 2, .filesystem = FS_EXT2, - .filepath = "boot/uImage", + .filepath = "boot/uImage-GTA01.bin", .commandline = "mtdparts=" \ "neo1973-nand:" \ "0x00040000(qi)," \ diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 06d270f..662f1e8 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -383,7 +383,7 @@ const struct board_api board_api_gta02 = { .block_read = sd_card_block_read_gta02, .partition_index = 1, .filesystem = FS_EXT2, - .filepath = "boot/uImage.bin", + .filepath = "boot/uImage-GTA02.bin", .commandline = "mtdparts=physmap-flash:-(nor);" \ "neo1973-nand:" \ "0x00040000(qi)," \ @@ -405,7 +405,7 @@ const struct board_api board_api_gta02 = { .block_read = sd_card_block_read_gta02, .partition_index = 2, .filesystem = FS_EXT2, - .filepath = "boot/uImage.bin", + .filepath = "boot/uImage-GTA02.bin", .commandline = "mtdparts=physmap-flash:-(nor);" \ "neo1973-nand:" \ "0x00040000(qi)," \ diff --git a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c index 731604d..ec9d63e 100644 --- a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c @@ -63,7 +63,7 @@ const struct board_api board_api_gta03 = { .block_read = sd_card_block_read_gta03, .filesystem = FS_EXT2, .partition_index = 2, - .filepath = "boot/uImage.bin", + .filepath = "boot/uImage-GTA03.bin", .commandline = "console=ttySAC3,115200 " \ "loglevel=8 init=/bin/sh " \ "root=/dev/mmcblk0p2 rootfstype=ext3" @@ -73,7 +73,7 @@ const struct board_api board_api_gta03 = { .block_read = sd_card_block_read_gta03, .filesystem = FS_EXT2, .partition_index = 3, - .filepath = "boot/uImage.bin", + .filepath = "boot/uImage-GTA03.bin", .commandline = "console=ttySAC3,115200 " \ "loglevel=8 init=/bin/sh " \ "root=/dev/mmcblk0p3 rootfstype=ext3" From a2a5e782f44f531ad6f2859678f177ea01548d46 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:44 +0000 Subject: [PATCH 149/248] qi-gta03-kill-100mA-usb-limit-temporary.patch We need > 100mA to boot GTA03 A1 right now Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/gta03.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/qiboot/src/cpu/s3c6410/gta03.c b/qiboot/src/cpu/s3c6410/gta03.c index 15f41ae..1d9bbb9 100644 --- a/qiboot/src/cpu/s3c6410/gta03.c +++ b/qiboot/src/cpu/s3c6410/gta03.c @@ -34,8 +34,12 @@ const struct pcf50633_init gta03_pcf50633_init[] = { { PCF50633_REG_MBCC3, 0x19 }, /* 25/255 == 98mA pre-charge */ { PCF50633_REG_MBCC4, 0xff }, /* 255/255 == 1A adapter fast */ { PCF50633_REG_MBCC5, 0x19 }, /* 25/255 == 98mA soft-start usb fast */ + { PCF50633_REG_MBCC6, 0x00 }, /* cutoff current 1/32 * Ichg */ +#if 0 + /* current prototype is pulling > 100mA at startup */ { PCF50633_REG_MBCC7, 0x00 }, /* 1.6A max bat curr, USB 100mA */ +#endif { PCF50633_REG_MBCC8, 0x00 }, { PCF50633_REG_MBCC1, 0xff }, /* chgena */ @@ -797,7 +801,6 @@ void port_init_gta03(void) /* * We have to talk to the PMU a little bit */ - for (n = 0; n < ARRAY_SIZE(gta03_pcf50633_init); n++) i2c_write_sync(&bb_s3c6410, PCF50633_I2C_ADS, gta03_pcf50633_init[n].index, From 98591fc54bda8a9fc21e949fba50611e59e8f130 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:44 +0000 Subject: [PATCH 150/248] qi-reduce-stage2-extent-32KB.patch We dedicate 256MB for bootloader in GTA03 SD image, but actually they're around 25KB currently. Reduce the stage2 pull to 32KByte. Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/start_qi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiboot/src/cpu/s3c6410/start_qi.c b/qiboot/src/cpu/s3c6410/start_qi.c index 622131c..abe34cf 100644 --- a/qiboot/src/cpu/s3c6410/start_qi.c +++ b/qiboot/src/cpu/s3c6410/start_qi.c @@ -115,7 +115,7 @@ void start_qi(void) void *dst); sd_sectors = s3c6410_mmc_init(1); s3c6410_mmc_bread(0, sd_sectors - 1026 - 16 - (256 * 2), - 256 * 2, (u8 *)0x53000000); + 32 * 2, (u8 *)0x53000000); } /* all of Qi is in memory now, stuff outside steppingstone too */ From 61ff9453dd26bad57556027f1de67ea45be1fbf0 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:44 +0000 Subject: [PATCH 151/248] qi-gta02-add-partition3-boot.patch It's worth looking on partition3, for GTA03 SD Card this will be backup / recovery rootfs Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/gta02.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 662f1e8..885debd 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -378,7 +378,7 @@ const struct board_api board_api_gta02 = { /* these are the ways we could boot GTA02 in order to try */ .kernel_source = { [0] = { - .name = "SD Card EXT2 Kernel", + .name = "SD Card EXT2 P1 Kernel", .block_init = sd_card_init_gta02, .block_read = sd_card_block_read_gta02, .partition_index = 1, @@ -400,7 +400,7 @@ const struct board_api board_api_gta02 = { "ro" }, [1] = { - .name = "SD Card EXT2 Kernel", + .name = "SD Card EXT2 P2 Kernel", .block_init = sd_card_init_gta02, .block_read = sd_card_block_read_gta02, .partition_index = 2, @@ -422,6 +422,28 @@ const struct board_api board_api_gta02 = { "ro" }, [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 = "mtdparts=physmap-flash:-(nor);" \ + "neo1973-nand:" \ + "0x00040000(qi)," \ + "0x00040000(cmdline)," \ + "0x00800000(backupkernel)," \ + "0x000a0000(extra)," \ + "0x00040000(identity)," \ + "0x0f6a0000(backuprootfs) " \ + "rootfstype=ext3 " \ + "root=/dev/mmcblk0p3 " \ + "console=ttySAC2,115200 " \ + "loglevel=4 " \ + "init=/sbin/init "\ + "ro" + }, + [3] = { .name = "NAND Kernel", .block_read = nand_read_ll, .offset_blocks512_if_no_partition = 0x80000 / 512, From 1b810a4dc6b7ad52eb8cf34438cf75b29be83407 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:44 +0000 Subject: [PATCH 152/248] qi-gta02-additional-regs-init.patch This should fix the reported problems with audio when the kernel is started with Qi on GTA02 Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/gta02.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 885debd..dbeb852 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -53,6 +53,9 @@ const struct pcf50633_init pcf50633_init[] = { { 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 }, @@ -62,12 +65,17 @@ const struct pcf50633_init pcf50633_init[] = { { 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, 0x19 }, /* 25/255 == 98mA soft-start usb fast */ + { PCF50633_REG_MBCC5, 0xff }, /* 255/255 == 1A usb fast */ { PCF50633_REG_MBCC6, 0x00 }, /* cutoff current 1/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 }, /* enabled if GPIO1 = H */ + { PCF50633_REG_LDO2ENA, 2 }, /* enabled if GPIO1 = H */ + { PCF50633_REG_LDO5ENA, 1 }, + { PCF50633_REG_LDO6ENA, 1 }, + { PCF50633_REG_BBCCTL, 0x19 }, /* 3V, 200uA, on */ { PCF50633_REG_OOCSHDWN, 0x04 }, /* defeat 8s death from lowsys on A5 */ From f6ee0972f94dd000dca60fb885d3a7a0d031ae26 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:44 +0000 Subject: [PATCH 153/248] qi-commandline-remove-all-sd-rootfstype.patch Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2410/gta01.c | 22 +++++++++++++++++-- qiboot/src/cpu/s3c2442/gta02.c | 11 ++++------ qiboot/src/cpu/s3c6410/gta03-steppingstone.c | 4 ++-- .../src/cpu/s3c6410/smdk6410-steppingstone.c | 4 ++-- 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/qiboot/src/cpu/s3c2410/gta01.c b/qiboot/src/cpu/s3c2410/gta01.c index b6d6db8..4b34112 100644 --- a/qiboot/src/cpu/s3c2410/gta01.c +++ b/qiboot/src/cpu/s3c2410/gta01.c @@ -240,7 +240,6 @@ const struct board_api board_api_gta01 = { "0x00200000(kernel)," \ "0x000a0000(splash)," \ "0x03d1c000(rootfs) " \ - "rootfstype=ext3 " \ "root=/dev/mmcblk0p2 " \ "console=ttySAC0,115200 " \ "loglevel=4 " \ @@ -261,7 +260,6 @@ const struct board_api board_api_gta01 = { "0x00200000(kernel)," \ "0x000a0000(splash)," \ "0x03d1c000(rootfs) " \ - "rootfstype=ext3 " \ "root=/dev/mmcblk0p2 " \ "console=ttySAC0,115200 " \ "loglevel=4 " \ @@ -269,6 +267,26 @@ const struct board_api board_api_gta01 = { "ro" }, [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 = "mtdparts=" \ + "neo1973-nand:" \ + "0x00040000(qi)," \ + "0x00004000(u-boot_env)," \ + "0x00200000(kernel)," \ + "0x000a0000(splash)," \ + "0x03d1c000(rootfs) " \ + "root=/dev/mmcblk0p2 " \ + "console=ttySAC0,115200 " \ + "loglevel=4 " \ + "init=/sbin/init "\ + "ro" + }, + [3] = { .name = "NAND Kernel", .block_read = nand_read_ll, .offset_blocks512_if_no_partition = 0x44000 / 512, diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index dbeb852..a9078fe 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -400,10 +400,9 @@ const struct board_api board_api_gta02 = { "0x000a0000(extra)," \ "0x00040000(identity)," \ "0x0f6a0000(backuprootfs) " \ - "rootfstype=ext3 " \ "root=/dev/mmcblk0p1 " \ "console=ttySAC2,115200 " \ - "loglevel=4 " \ + "loglevel=8 console=tty0 " \ "init=/sbin/init "\ "ro" }, @@ -422,10 +421,9 @@ const struct board_api board_api_gta02 = { "0x000a0000(extra)," \ "0x00040000(identity)," \ "0x0f6a0000(backuprootfs) " \ - "rootfstype=ext3 " \ "root=/dev/mmcblk0p2 " \ "console=ttySAC2,115200 " \ - "loglevel=4 " \ + "loglevel=8 console=tty0 " \ "init=/sbin/init "\ "ro" }, @@ -444,10 +442,9 @@ const struct board_api board_api_gta02 = { "0x000a0000(extra)," \ "0x00040000(identity)," \ "0x0f6a0000(backuprootfs) " \ - "rootfstype=ext3 " \ "root=/dev/mmcblk0p3 " \ "console=ttySAC2,115200 " \ - "loglevel=4 " \ + "loglevel=8 console=tty0 " \ "init=/sbin/init "\ "ro" }, @@ -467,7 +464,7 @@ const struct board_api board_api_gta02 = { "rootfstype=jffs2 " \ "root=/dev/mtdblock6 " \ "console=ttySAC2,115200 " \ - "loglevel=8 " \ + "loglevel=8 console=tty0 " \ "init=/sbin/init "\ "ro" }, diff --git a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c index ec9d63e..eb10622 100644 --- a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c @@ -66,7 +66,7 @@ const struct board_api board_api_gta03 = { .filepath = "boot/uImage-GTA03.bin", .commandline = "console=ttySAC3,115200 " \ "loglevel=8 init=/bin/sh " \ - "root=/dev/mmcblk0p2 rootfstype=ext3" + "root=/dev/mmcblk0p2" }, [1] = { .name = "SD Card backup rootfs", @@ -76,7 +76,7 @@ const struct board_api board_api_gta03 = { .filepath = "boot/uImage-GTA03.bin", .commandline = "console=ttySAC3,115200 " \ "loglevel=8 init=/bin/sh " \ - "root=/dev/mmcblk0p3 rootfstype=ext3" + "root=/dev/mmcblk0p3" }, }, }; diff --git a/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c b/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c index b8c3237..f41d904 100644 --- a/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c @@ -54,7 +54,7 @@ const struct board_api board_api_smdk6410 = { .filepath = "boot/uImage.bin", .commandline = "console=ttySAC0,115200 " \ "loglevel=3 init=/bin/sh " \ - "root=/dev/mmcblk0p2 rootfstype=ext3" + "root=/dev/mmcblk0p2" }, [1] = { .name = "SD Card backup rootfs", @@ -64,7 +64,7 @@ const struct board_api board_api_smdk6410 = { .filepath = "boot/uImage.bin", .commandline = "console=ttySAC0,115200 " \ "loglevel=8 init=/bin/sh " \ - "root=/dev/mmcblk0p3 rootfstype=ext3" + "root=/dev/mmcblk0p3" }, }, }; From 46fd1c005bcdad9d3a4965d29e2c2fb7441c8e92 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:45 +0000 Subject: [PATCH 154/248] qi-commandline-split.patch Signed-off-by: Andy Green --- qiboot/include/qi.h | 4 +- qiboot/src/cpu/s3c2410/gta01.c | 65 ++++------------- qiboot/src/cpu/s3c2442/gta02.c | 73 +++++-------------- qiboot/src/cpu/s3c6410/gta03-steppingstone.c | 11 ++- .../src/cpu/s3c6410/smdk6410-steppingstone.c | 14 ++-- qiboot/src/phase2.c | 21 ++++-- 6 files changed, 64 insertions(+), 124 deletions(-) diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index 1ecf31f..6cf4cf5 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -54,7 +54,7 @@ struct kernel_source { 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; + const char * commandline_append; }; /* describes a board variant, eg, PCB revision */ @@ -72,6 +72,8 @@ struct board_api { 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 struct board_variant const * (*get_board_variant)(void); int (*is_this_board)(void); void (*early_port_init)(void); diff --git a/qiboot/src/cpu/s3c2410/gta01.c b/qiboot/src/cpu/s3c2410/gta01.c index 4b34112..5ad84ca 100644 --- a/qiboot/src/cpu/s3c2410/gta01.c +++ b/qiboot/src/cpu/s3c2410/gta01.c @@ -224,6 +224,17 @@ const struct board_api board_api_gta01 = { .port_init = port_init_gta01, .putc = putc_gta01, .close = close_gta01, + .commandline_board = "mtdparts=" \ + "neo1973-nand:" \ + "0x00040000(qi)," \ + "0x00004000(u-boot_env)," \ + "0x00200000(kernel)," \ + "0x000a0000(splash)," \ + "0x03d1c000(rootfs) " \ + "console=ttySAC0,115200 " \ + "init=/sbin/init "\ + "ro", + .commandline_board_debug = " loglevel=8 console=tty0", /* these are the ways we could boot GTA01 in order to try */ .kernel_source = { [0] = { @@ -233,18 +244,7 @@ const struct board_api board_api_gta01 = { .partition_index = 1, .filesystem = FS_EXT2, .filepath = "boot/uImage-GTA01.bin", - .commandline = "mtdparts=" \ - "neo1973-nand:" \ - "0x00040000(qi)," \ - "0x00004000(u-boot_env)," \ - "0x00200000(kernel)," \ - "0x000a0000(splash)," \ - "0x03d1c000(rootfs) " \ - "root=/dev/mmcblk0p2 " \ - "console=ttySAC0,115200 " \ - "loglevel=4 " \ - "init=/sbin/init "\ - "ro" + .commandline_append = " root=/dev/mmcblk0p1", }, [1] = { .name = "SD Card EXT2 Kernel p2", @@ -253,18 +253,7 @@ const struct board_api board_api_gta01 = { .partition_index = 2, .filesystem = FS_EXT2, .filepath = "boot/uImage-GTA01.bin", - .commandline = "mtdparts=" \ - "neo1973-nand:" \ - "0x00040000(qi)," \ - "0x00004000(u-boot_env)," \ - "0x00200000(kernel)," \ - "0x000a0000(splash)," \ - "0x03d1c000(rootfs) " \ - "root=/dev/mmcblk0p2 " \ - "console=ttySAC0,115200 " \ - "loglevel=4 " \ - "init=/sbin/init "\ - "ro" + .commandline_append = " root=/dev/mmcblk0p2", }, [2] = { .name = "SD Card EXT2 Kernel p3", @@ -273,37 +262,15 @@ const struct board_api board_api_gta01 = { .partition_index = 3, .filesystem = FS_EXT2, .filepath = "boot/uImage-GTA01.bin", - .commandline = "mtdparts=" \ - "neo1973-nand:" \ - "0x00040000(qi)," \ - "0x00004000(u-boot_env)," \ - "0x00200000(kernel)," \ - "0x000a0000(splash)," \ - "0x03d1c000(rootfs) " \ - "root=/dev/mmcblk0p2 " \ - "console=ttySAC0,115200 " \ - "loglevel=4 " \ - "init=/sbin/init "\ - "ro" + .commandline_append = " root=/dev/mmcblk0p3", }, [3] = { .name = "NAND Kernel", .block_read = nand_read_ll, .offset_blocks512_if_no_partition = 0x44000 / 512, .filesystem = FS_RAW, - .commandline = "mtdparts=" \ - "neo1973-nand:" \ - "0x00040000(qi)," \ - "0x00004000(u-boot_env)," \ - "0x00200000(kernel)," \ - "0x000a0000(splash)," \ - "0x03d1c000(rootfs) " \ - "rootfstype=jffs2 " \ - "root=/dev/mtdblock4 " \ - "console=ttySAC0,115200 " \ - "loglevel=4 " \ - "init=/sbin/init "\ - "ro" + .commandline_append = " rootfstype=jffs2 " \ + "root=/dev/mtdblock4 ", }, }, }; diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index a9078fe..f434ba9 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -383,7 +383,20 @@ const struct board_api board_api_gta02 = { .port_init = port_init_gta02, .putc = putc_gta02, .close = close_gta02, - /* these are the ways we could boot GTA02 in order to try */ + .commandline_board = "mtdparts=physmap-flash:-(nor);" \ + "neo1973-nand:" \ + "0x00040000(qi)," \ + "0x00040000(cmdline)," \ + "0x00800000(backupkernel)," \ + "0x000a0000(extra)," \ + "0x00040000(identity)," \ + "0x0f6a0000(backuprootfs) " \ + "console=ttySAC2,115200 " \ + "init=/sbin/init " \ + "ro", + .commandline_board_debug = " console=tty0 " \ + "loglevel=8", + /* these are the ways we could boot GTA02 in the order to try */ .kernel_source = { [0] = { .name = "SD Card EXT2 P1 Kernel", @@ -392,19 +405,7 @@ const struct board_api board_api_gta02 = { .partition_index = 1, .filesystem = FS_EXT2, .filepath = "boot/uImage-GTA02.bin", - .commandline = "mtdparts=physmap-flash:-(nor);" \ - "neo1973-nand:" \ - "0x00040000(qi)," \ - "0x00040000(cmdline)," \ - "0x00800000(backupkernel)," \ - "0x000a0000(extra)," \ - "0x00040000(identity)," \ - "0x0f6a0000(backuprootfs) " \ - "root=/dev/mmcblk0p1 " \ - "console=ttySAC2,115200 " \ - "loglevel=8 console=tty0 " \ - "init=/sbin/init "\ - "ro" + .commandline_append = " root=/dev/mmcblk0p1", }, [1] = { .name = "SD Card EXT2 P2 Kernel", @@ -413,19 +414,7 @@ const struct board_api board_api_gta02 = { .partition_index = 2, .filesystem = FS_EXT2, .filepath = "boot/uImage-GTA02.bin", - .commandline = "mtdparts=physmap-flash:-(nor);" \ - "neo1973-nand:" \ - "0x00040000(qi)," \ - "0x00040000(cmdline)," \ - "0x00800000(backupkernel)," \ - "0x000a0000(extra)," \ - "0x00040000(identity)," \ - "0x0f6a0000(backuprootfs) " \ - "root=/dev/mmcblk0p2 " \ - "console=ttySAC2,115200 " \ - "loglevel=8 console=tty0 " \ - "init=/sbin/init "\ - "ro" + .commandline_append = " root=/dev/mmcblk0p2", }, [2] = { .name = "SD Card EXT2 P3 Kernel", @@ -434,39 +423,15 @@ const struct board_api board_api_gta02 = { .partition_index = 3, .filesystem = FS_EXT2, .filepath = "boot/uImage-GTA02.bin", - .commandline = "mtdparts=physmap-flash:-(nor);" \ - "neo1973-nand:" \ - "0x00040000(qi)," \ - "0x00040000(cmdline)," \ - "0x00800000(backupkernel)," \ - "0x000a0000(extra)," \ - "0x00040000(identity)," \ - "0x0f6a0000(backuprootfs) " \ - "root=/dev/mmcblk0p3 " \ - "console=ttySAC2,115200 " \ - "loglevel=8 console=tty0 " \ - "init=/sbin/init "\ - "ro" + .commandline_append = " root=/dev/mmcblk0p3", }, [3] = { .name = "NAND Kernel", .block_read = nand_read_ll, .offset_blocks512_if_no_partition = 0x80000 / 512, .filesystem = FS_RAW, - .commandline = "mtdparts=physmap-flash:-(nor);" \ - "neo1973-nand:" \ - "0x00040000(qi)," \ - "0x00040000(cmdline)," \ - "0x00800000(backupkernel)," \ - "0x000a0000(extra)," \ - "0x00040000(identity)," \ - "0x0f6a0000(backuprootfs) " \ - "rootfstype=jffs2 " \ - "root=/dev/mtdblock6 " \ - "console=ttySAC2,115200 " \ - "loglevel=8 console=tty0 " \ - "init=/sbin/init "\ - "ro" + .commandline_append = " rootfstype=jffs2 " \ + "root=/dev/mtdblock6", }, }, }; diff --git a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c index eb10622..ac147c2 100644 --- a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c @@ -57,6 +57,9 @@ const struct board_api board_api_gta03 = { .is_this_board = is_this_board_gta03, .port_init = port_init_gta03, .putc = putc_gta03, + .commandline_board = "console=ttySAC3,115200 " \ + "init=/bin/sh " \ + "loglevel=8 ", .kernel_source = { [0] = { .name = "SD Card rootfs", @@ -64,9 +67,7 @@ const struct board_api board_api_gta03 = { .filesystem = FS_EXT2, .partition_index = 2, .filepath = "boot/uImage-GTA03.bin", - .commandline = "console=ttySAC3,115200 " \ - "loglevel=8 init=/bin/sh " \ - "root=/dev/mmcblk0p2" + .commandline_append = "root=/dev/mmcblk0p2", }, [1] = { .name = "SD Card backup rootfs", @@ -74,9 +75,7 @@ const struct board_api board_api_gta03 = { .filesystem = FS_EXT2, .partition_index = 3, .filepath = "boot/uImage-GTA03.bin", - .commandline = "console=ttySAC3,115200 " \ - "loglevel=8 init=/bin/sh " \ - "root=/dev/mmcblk0p3" + .commandline_append = "root=/dev/mmcblk0p3", }, }, }; diff --git a/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c b/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c index f41d904..8a62b6c 100644 --- a/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c @@ -45,6 +45,9 @@ const struct board_api board_api_smdk6410 = { .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", .kernel_source = { [0] = { .name = "SD Card rootfs", @@ -52,9 +55,7 @@ const struct board_api board_api_smdk6410 = { .filesystem = FS_EXT2, .partition_index = 2, .filepath = "boot/uImage.bin", - .commandline = "console=ttySAC0,115200 " \ - "loglevel=3 init=/bin/sh " \ - "root=/dev/mmcblk0p2" + .commandline_append = " root=/dev/mmcblk0p2" }, [1] = { .name = "SD Card backup rootfs", @@ -62,9 +63,8 @@ const struct board_api board_api_smdk6410 = { .filesystem = FS_EXT2, .partition_index = 3, .filepath = "boot/uImage.bin", - .commandline = "console=ttySAC0,115200 " \ - "loglevel=8 init=/bin/sh " \ - "root=/dev/mmcblk0p3" - }, }, + .commandline_append = " root=/dev/mmcblk0p3" + }, + }, }; diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 847dfc8..60bace3 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -94,6 +94,7 @@ void bootloader_second_phase(void) while (this_kernel->name) { const char *p; + char * cmdline; struct tag *params = (struct tag *)this_board->linux_tag_placement; void * kernel_dram = (void *)this_board->linux_mem_start + 0x8000; unsigned long crc; @@ -104,7 +105,7 @@ void bootloader_second_phase(void) partition_length_blocks = 0; /* eat leading white space */ - for (p = this_kernel->commandline; *p == ' '; p++); + for (p = this_board->commandline_board; *p == ' '; p++); puts("\nTrying kernel: "); puts(this_kernel->name); @@ -208,10 +209,6 @@ void bootloader_second_phase(void) } } - puts(" Cmdline: "); - puts(p); - puts("\n"); - /* * It's good for now to know that our kernel is intact from * the storage before we jump into it and maybe crash silently @@ -266,10 +263,20 @@ void bootloader_second_phase(void) /* kernel commandline */ if (*p) { + cmdline = params->u.cmdline.cmdline; + cmdline += strlen(strcpy(cmdline, p)); + if (this_kernel->commandline_append) + cmdline += strlen(strcpy(cmdline, + this_kernel->commandline_append)); + params->hdr.tag = ATAG_CMDLINE; params->hdr.size = (sizeof (struct tag_header) + - strlen (p) + 1 + 4) >> 2; - strcpy (params->u.cmdline.cmdline, p); + strlen(params->u.cmdline.cmdline) + 1 + 4) >> 2; + + puts(" Cmdline: "); + puts(params->u.cmdline.cmdline); + puts("\n"); + params = tag_next (params); } From 729a4040557d1d7da18c4ff72a156c93e4a2e6f1 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:45 +0000 Subject: [PATCH 155/248] qi-gta03-framebuffer-enable.patch Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/start.S | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/qiboot/src/cpu/s3c6410/start.S b/qiboot/src/cpu/s3c6410/start.S index dbb9883..9d17c58 100644 --- a/qiboot/src/cpu/s3c6410/start.S +++ b/qiboot/src/cpu/s3c6410/start.S @@ -184,7 +184,7 @@ start_code: 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 + orr r0, r0, #0x00005000 @ Enable I and D-Cache mcr p15, 0, r0, c1, c0, 0 /* Peri port setup */ @@ -192,6 +192,18 @@ start_code: orr r0, r0, #0x13 mcr p15,0,r0,c15,c2,4 @ 256M(0x70000000-0x7fffffff) + /* LCD Controller enable */ + + ldr r0, =0x7410800c @ MIFPCON[3] = 0 + mov r1, #0 + str r1, [r0] + + ldr r0, =0x7f0081a0 @ SPCON[1:0] = 01 + mov r1, =0xbfc11501 + str r1, [r0] + + /* SDRAM */ + ldr r0, =ELFIN_MEM_SYS_CFG @Memory sussystem address 0x7e00f120 mov r1, #0xd @ Xm0CSn2 = NFCON CS0, Xm0CSn3 = NFCON CS1 str r1, [r0] From 12828f98f260b7ffb64d694659205ae102269219 Mon Sep 17 00:00:00 2001 From: Matt Hsu Date: Fri, 28 Nov 2008 10:16:45 +0000 Subject: [PATCH 156/248] fix a compiling error Signed-off-by: Matt Hsu --- qiboot/src/cpu/s3c6410/start.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiboot/src/cpu/s3c6410/start.S b/qiboot/src/cpu/s3c6410/start.S index 9d17c58..445e905 100644 --- a/qiboot/src/cpu/s3c6410/start.S +++ b/qiboot/src/cpu/s3c6410/start.S @@ -199,7 +199,7 @@ start_code: str r1, [r0] ldr r0, =0x7f0081a0 @ SPCON[1:0] = 01 - mov r1, =0xbfc11501 + ldr r1, =0xbfc11501 str r1, [r0] /* SDRAM */ From 4a503bbc81f4f5ac3837c2894dc5cfe98c43fe95 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:45 +0000 Subject: [PATCH 157/248] qi-update-README.patch Signed-off-by: Andy Green --- qiboot/README | 50 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/qiboot/README b/qiboot/README index abff09f..f892773 100644 --- a/qiboot/README +++ b/qiboot/README @@ -54,18 +54,30 @@ 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.bin. +first viable kernel it finds, usually /boot/uImage-device>.bin for example +/boot/uImage-GTA02.bin. -The kernel commandline used is associated with the storage device, this allows -the correct root= line to be arrived at without any work. The inability to set -the Qi kernel commandline externally is deliberate, two otherwise identical -devices differing by the kernel commandline or other "environment" is not good. -A whole class of bugs and support issues around private bootloader state are -therefore avoided. +You can disable a rootfs for consideration for boot if you add a file +/boot/noboot-, eg, /boot/noboot-GTA02. + +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-, +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 name in them, options can be selected depending on +the device the rootfs is run on. + + Initrd support ============== @@ -76,22 +88,24 @@ memory address in addition to kernel image. The ATAGs are issued accordingly. Functional Differences from U-Boot on GTA02 =========================================== - - Backlight is not enabled until Linux starts after a few seconds - - - kernel loglevel is set to NOT output gobs of text to the screen - - - On GTA02 will ALWAYS boot from uSD if first partition is ext2 and contains - /boot/uImage.bin, otherwise boots from NAND - - - On GTA03 will ALWAYS boot from uSD second partition if /boot/uImage.bin is - present otherwise try the third / backup partition + - 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-.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-, + 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. - - USB is not started until Linux starts around 5 seconds after boot, there is - no DFU. From 3565397f1c2fd80b648d01439a1963f638b73e57 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:45 +0000 Subject: [PATCH 158/248] qi-gta03-framebuffer-init-to-c.patch Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/gta03.c | 5 +++++ qiboot/src/cpu/s3c6410/start.S | 10 ---------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/qiboot/src/cpu/s3c6410/gta03.c b/qiboot/src/cpu/s3c6410/gta03.c index 1d9bbb9..10ac90e 100644 --- a/qiboot/src/cpu/s3c6410/gta03.c +++ b/qiboot/src/cpu/s3c6410/gta03.c @@ -798,6 +798,11 @@ void port_init_gta03(void) (0 << 30) /* GPQ15 - no pull up or down */ ; + /* LCD Controller enable */ + + __REG(0x7410800c) = 0; + __REG(0x7f0081a0) = 0xbfc11501; + /* * We have to talk to the PMU a little bit */ diff --git a/qiboot/src/cpu/s3c6410/start.S b/qiboot/src/cpu/s3c6410/start.S index 445e905..f9e5079 100644 --- a/qiboot/src/cpu/s3c6410/start.S +++ b/qiboot/src/cpu/s3c6410/start.S @@ -192,16 +192,6 @@ start_code: orr r0, r0, #0x13 mcr p15,0,r0,c15,c2,4 @ 256M(0x70000000-0x7fffffff) - /* LCD Controller enable */ - - ldr r0, =0x7410800c @ MIFPCON[3] = 0 - mov r1, #0 - str r1, [r0] - - ldr r0, =0x7f0081a0 @ SPCON[1:0] = 01 - ldr r1, =0xbfc11501 - str r1, [r0] - /* SDRAM */ ldr r0, =ELFIN_MEM_SYS_CFG @Memory sussystem address 0x7e00f120 From 1b06d98bc7587459ad2bc9930c8f640f8e5029a7 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:45 +0000 Subject: [PATCH 159/248] qi-add-noboot-and-append-check.patch This adds two features that can be set in the rootfs that Qi is checking. - if it finds /boot/noboot-, eg /boot/noboot-GTA02 then it will skip the rootfs for booting and try the next one if any - if it finds /boot/append-, eg, /boot/append-GTA02 then it will append the contents of this file to the kernel commandline. Signed-off-by: Andy Green --- qiboot/include/qi.h | 2 ++ qiboot/src/cpu/s3c2410/gta01.c | 8 +++--- qiboot/src/cpu/s3c2442/gta02.c | 10 +++++--- qiboot/src/cpu/s3c6410/gta03-steppingstone.c | 6 +++-- .../src/cpu/s3c6410/smdk6410-steppingstone.c | 12 +++++---- qiboot/src/phase2.c | 25 ++++++++++++++++--- 6 files changed, 46 insertions(+), 17 deletions(-) diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index 6cf4cf5..e11489a 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -74,6 +74,8 @@ struct board_api { 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); diff --git a/qiboot/src/cpu/s3c2410/gta01.c b/qiboot/src/cpu/s3c2410/gta01.c index 5ad84ca..cb20a72 100644 --- a/qiboot/src/cpu/s3c2410/gta01.c +++ b/qiboot/src/cpu/s3c2410/gta01.c @@ -235,6 +235,8 @@ const struct board_api board_api_gta01 = { "init=/sbin/init "\ "ro", .commandline_board_debug = " loglevel=8 console=tty0", + .noboot = "boot/noboot-GTA01", + .append = "boot/append-GTA01", /* these are the ways we could boot GTA01 in order to try */ .kernel_source = { [0] = { @@ -244,7 +246,7 @@ const struct board_api board_api_gta01 = { .partition_index = 1, .filesystem = FS_EXT2, .filepath = "boot/uImage-GTA01.bin", - .commandline_append = " root=/dev/mmcblk0p1", + .commandline_append = " root=/dev/mmcblk0p1 ", }, [1] = { .name = "SD Card EXT2 Kernel p2", @@ -253,7 +255,7 @@ const struct board_api board_api_gta01 = { .partition_index = 2, .filesystem = FS_EXT2, .filepath = "boot/uImage-GTA01.bin", - .commandline_append = " root=/dev/mmcblk0p2", + .commandline_append = " root=/dev/mmcblk0p2 ", }, [2] = { .name = "SD Card EXT2 Kernel p3", @@ -262,7 +264,7 @@ const struct board_api board_api_gta01 = { .partition_index = 3, .filesystem = FS_EXT2, .filepath = "boot/uImage-GTA01.bin", - .commandline_append = " root=/dev/mmcblk0p3", + .commandline_append = " root=/dev/mmcblk0p3 ", }, [3] = { .name = "NAND Kernel", diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index f434ba9..f7405e6 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -396,6 +396,8 @@ const struct board_api board_api_gta02 = { "ro", .commandline_board_debug = " console=tty0 " \ "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] = { @@ -405,7 +407,7 @@ const struct board_api board_api_gta02 = { .partition_index = 1, .filesystem = FS_EXT2, .filepath = "boot/uImage-GTA02.bin", - .commandline_append = " root=/dev/mmcblk0p1", + .commandline_append = " root=/dev/mmcblk0p1 ", }, [1] = { .name = "SD Card EXT2 P2 Kernel", @@ -414,7 +416,7 @@ const struct board_api board_api_gta02 = { .partition_index = 2, .filesystem = FS_EXT2, .filepath = "boot/uImage-GTA02.bin", - .commandline_append = " root=/dev/mmcblk0p2", + .commandline_append = " root=/dev/mmcblk0p2 ", }, [2] = { .name = "SD Card EXT2 P3 Kernel", @@ -423,7 +425,7 @@ const struct board_api board_api_gta02 = { .partition_index = 3, .filesystem = FS_EXT2, .filepath = "boot/uImage-GTA02.bin", - .commandline_append = " root=/dev/mmcblk0p3", + .commandline_append = " root=/dev/mmcblk0p3 ", }, [3] = { .name = "NAND Kernel", @@ -431,7 +433,7 @@ const struct board_api board_api_gta02 = { .offset_blocks512_if_no_partition = 0x80000 / 512, .filesystem = FS_RAW, .commandline_append = " rootfstype=jffs2 " \ - "root=/dev/mtdblock6", + "root=/dev/mtdblock6 ", }, }, }; diff --git a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c index ac147c2..fe4381b 100644 --- a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c @@ -57,6 +57,8 @@ const struct board_api board_api_gta03 = { .is_this_board = is_this_board_gta03, .port_init = port_init_gta03, .putc = putc_gta03, + .noboot = "boot/noboot-GTA03", + .append = "boot/append-GTA03", .commandline_board = "console=ttySAC3,115200 " \ "init=/bin/sh " \ "loglevel=8 ", @@ -67,7 +69,7 @@ const struct board_api board_api_gta03 = { .filesystem = FS_EXT2, .partition_index = 2, .filepath = "boot/uImage-GTA03.bin", - .commandline_append = "root=/dev/mmcblk0p2", + .commandline_append = "root=/dev/mmcblk0p2 ", }, [1] = { .name = "SD Card backup rootfs", @@ -75,7 +77,7 @@ const struct board_api board_api_gta03 = { .filesystem = FS_EXT2, .partition_index = 3, .filepath = "boot/uImage-GTA03.bin", - .commandline_append = "root=/dev/mmcblk0p3", + .commandline_append = "root=/dev/mmcblk0p3 ", }, }, }; diff --git a/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c b/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c index 8a62b6c..f2c8a5a 100644 --- a/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c @@ -47,23 +47,25 @@ const struct board_api board_api_smdk6410 = { .putc = putc_smdk6410, .commandline_board = "console=ttySAC0,115200 " \ "loglevel=3 " \ - "init=/bin/sh", + "init=/bin/sh ", + .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.bin", - .commandline_append = " root=/dev/mmcblk0p2" + .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.bin", - .commandline_append = " root=/dev/mmcblk0p3" + .filepath = "boot/uImage-SMDK6410.bin", + .commandline_append = "root=/dev/mmcblk0p3 " }, }, }; diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 60bace3..5a0367b 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -44,7 +44,7 @@ int raise(int n) int read_file(const char * filepath, u8 * destination, int size) { - unsigned int len = size; + int len = size; switch (this_kernel->filesystem) { case FS_EXT2: @@ -54,12 +54,12 @@ int read_file(const char * filepath, u8 * destination, int size) } puts(" EXT2 open: "); puts(filepath); - puts("\n"); len = ext2fs_open(filepath); if (len < 0) { - puts("Open failed\n"); + puts(" Open failed\n"); return -1; } + puts(" OK\n"); ext2fs_read((char *)destination, size); break; @@ -87,6 +87,7 @@ void bootloader_second_phase(void) const struct board_variant * board_variant = (this_board->get_board_variant)(); unsigned int initramfs_len = 0; + static char commandline_rootfs_append[512] = ""; /* we try the possible kernels for this board in order */ @@ -165,6 +166,21 @@ void bootloader_second_phase(void) partition_offset_blocks = this_kernel->offset_blocks512_if_no_partition; + /* does he want us to skip this? */ + + if (read_file(this_board->noboot, kernel_dram, 512) >= 0) { + puts(" (Skipping on finding "); + puts(this_board->noboot); + puts(")\n"); + this_kernel = &this_board->kernel_source[kernel++]; + continue; + } + + /* is there a commandline append file? */ + + read_file(this_board->append, (u8 *)commandline_rootfs_append, + 512); + /* pull the kernel image */ if (read_file(this_kernel->filepath, kernel_dram, 4096) < 0) { @@ -268,6 +284,9 @@ void bootloader_second_phase(void) if (this_kernel->commandline_append) cmdline += strlen(strcpy(cmdline, this_kernel->commandline_append)); + if (commandline_rootfs_append[0]) + cmdline += strlen(strcpy(cmdline, + commandline_rootfs_append)); params->hdr.tag = ATAG_CMDLINE; params->hdr.size = (sizeof (struct tag_header) + From 02fb6167212935bdd7b0a243485bb4dc3bac6fff Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:45 +0000 Subject: [PATCH 160/248] qi-fixes-append.patch Signed-off-by: Andy Green --- qiboot/README | 7 +++++-- qiboot/src/phase2.c | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/qiboot/README b/qiboot/README index f892773..198507c 100644 --- a/qiboot/README +++ b/qiboot/README @@ -54,11 +54,14 @@ 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 +first viable kernel it finds, usually /boot/.bin for example /boot/uImage-GTA02.bin. You can disable a rootfs for consideration for boot if you add a file -/boot/noboot-, eg, /boot/noboot-GTA02. +/boot/noboot-, 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. diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 5a0367b..66d9150 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -178,6 +178,7 @@ void bootloader_second_phase(void) /* is there a commandline append file? */ + commandline_rootfs_append[0] = '\0'; read_file(this_board->append, (u8 *)commandline_rootfs_append, 512); From 4285b49897dc430f958b75f4b8d62a91ab055b13 Mon Sep 17 00:00:00 2001 From: Christopher Hall Date: Fri, 28 Nov 2008 10:16:45 +0000 Subject: [PATCH 161/248] qi-move-to-sbin-init.patch Signed-off-by: Christopher Hall --- qiboot/src/cpu/s3c6410/gta03-steppingstone.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c index fe4381b..27094f3 100644 --- a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c @@ -60,7 +60,7 @@ const struct board_api board_api_gta03 = { .noboot = "boot/noboot-GTA03", .append = "boot/append-GTA03", .commandline_board = "console=ttySAC3,115200 " \ - "init=/bin/sh " \ + "init=/sbin/init " \ "loglevel=8 ", .kernel_source = { [0] = { From d0c9237ee148c309be7d302a0adf99aa46ae8a66 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 28 Nov 2008 10:16:45 +0000 Subject: [PATCH 162/248] qi-fix-nand-noboot-append-disable.patch Recent addition of append and noboot file checks broke NAND Reported-by: Micael Henriksson Signed-off-by: Andy Green --- qiboot/src/phase2.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 66d9150..30c9b15 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -66,6 +66,9 @@ int read_file(const char * filepath, u8 * destination, int size) case FS_FAT: /* FIXME */ case FS_RAW: + /* any filename-related request in raw filesystem will fail */ + if (filepath) + return -1; puts(" RAW open: +"); printdec(partition_offset_blocks); puts(" 512-byte blocks\n"); From 263f4335adf99a83ea3a3d27677364ff8623070c Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 1 Dec 2008 01:26:03 +0000 Subject: [PATCH 163/248] qi-add-ui-api.patch Introduce the ability for boards to have UI inputs for purposes decided by Qi Signed-off-by: Andy Green --- qiboot/include/qi.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index e11489a..c8971e6 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -42,6 +42,11 @@ enum filesystem { FS_EXT2 }; +enum ui_actions { + UI_ACTION_ADD_DEBUG = (1 << 0), + UI_ACTION_SKIPKERNEL = (1 << 1), +}; + /* describes a source for getting kernel image */ struct kernel_source { @@ -76,22 +81,18 @@ struct board_api { 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 (*putc)(char); void (*close)(void); + u8 (*get_ui_keys)(void); + struct kernel_source kernel_source[8]; }; -/* these are the boards we support for a given CPU */ - -struct cpu_supported_boards { - const u32 cpu_id; - const struct board_api **boards; -}; - /* this is the board we are running on */ extern struct board_api const * this_board; From d87c26ee38cc2cf1d242d0a772648be7ee4e6d4e Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 1 Dec 2008 01:26:04 +0000 Subject: [PATCH 164/248] qi-gta02-add-ui-debounce.patch Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/gta02.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index f7405e6..2ea520a 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -368,6 +368,30 @@ static void close_gta02(void) (bb_s3c24xx.close)(); } +static u8 get_ui_keys_gta02(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 */ + + /* GPF6 is AUX on GTA02, map to UI_ACTION_ADD_DEBUG, down = 1 */ + keys = !!(rGPFDAT & (1 << 6)); + + 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; +} /* * our API for bootloader on this machine */ @@ -383,6 +407,7 @@ const struct board_api board_api_gta02 = { .port_init = port_init_gta02, .putc = putc_gta02, .close = close_gta02, + .get_ui_keys = get_ui_keys_gta02, .commandline_board = "mtdparts=physmap-flash:-(nor);" \ "neo1973-nand:" \ "0x00040000(qi)," \ From bede2a1359fda33957da9afd334459408a4e5348 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 1 Dec 2008 01:26:04 +0000 Subject: [PATCH 165/248] qi-gta03-add-ui-debounce.patch Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/gta03-steppingstone.c | 26 ++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c index 27094f3..723b390 100644 --- a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c @@ -47,6 +47,31 @@ unsigned long s3c6410_mmc_bread(int dev_num, unsigned long blknr, unsigned long * "root=/dev/ram ramdisk_size=6000000" */ +static u8 get_ui_keys_gta03(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 GTA03, 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_gta03 = { .name = "GTA03", .linux_machine_id = 1866, @@ -59,6 +84,7 @@ const struct board_api board_api_gta03 = { .putc = putc_gta03, .noboot = "boot/noboot-GTA03", .append = "boot/append-GTA03", + .get_ui_keys = get_ui_keys_gta03, .commandline_board = "console=ttySAC3,115200 " \ "init=/sbin/init " \ "loglevel=8 ", From f23a39d80d2e87c16171728533c4d80a061cbb58 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 1 Dec 2008 01:26:04 +0000 Subject: [PATCH 166/248] qi-gta01-add-ui-debounce.patch Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2410/gta01.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/qiboot/src/cpu/s3c2410/gta01.c b/qiboot/src/cpu/s3c2410/gta01.c index cb20a72..1b572d2 100644 --- a/qiboot/src/cpu/s3c2410/gta01.c +++ b/qiboot/src/cpu/s3c2410/gta01.c @@ -209,6 +209,32 @@ static void close_gta01(void) (bb_s3c24xx.close)(); } +static u8 get_ui_keys_gta02(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 */ + + /* GPF6 is AUX on GTA01, map to UI_ACTION_ADD_DEBUG, down = 1 */ + keys = ! (rGPFDAT & (1 << 6)); + + 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; +} + + /* * API for bootloader on this machine */ @@ -224,6 +250,8 @@ const struct board_api board_api_gta01 = { .port_init = port_init_gta01, .putc = putc_gta01, .close = close_gta01, + .get_ui_keys = get_ui_keys_gta02, + .commandline_board = "mtdparts=" \ "neo1973-nand:" \ "0x00040000(qi)," \ From 842a4ad19b6bf5b2376a578478e109453f5bdd89 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 1 Dec 2008 01:26:05 +0000 Subject: [PATCH 167/248] qi-kernel-source-skip-if-ui-key-down.patch Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/nand_read.c | 6 ++++++ qiboot/src/fs/dev.c | 6 ++++++ qiboot/src/phase2.c | 31 ++++++++++++++++-------------- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/qiboot/src/cpu/s3c2442/nand_read.c b/qiboot/src/cpu/s3c2442/nand_read.c index cb2a2de..bec2e8b 100644 --- a/qiboot/src/cpu/s3c2442/nand_read.c +++ b/qiboot/src/cpu/s3c2442/nand_read.c @@ -143,6 +143,12 @@ int nand_read_ll(unsigned char *buf, unsigned long start_block512, 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 */ diff --git a/qiboot/src/fs/dev.c b/qiboot/src/fs/dev.c index 694c8b1..8ffcf2d 100644 --- a/qiboot/src/fs/dev.c +++ b/qiboot/src/fs/dev.c @@ -52,6 +52,12 @@ int ext2fs_devread(int sector, int filesystem_block_log2, int byte_offset, int b return 0; } + if (this_board->get_ui_keys) + if ((this_board->get_ui_keys)() & UI_ACTION_SKIPKERNEL) { + puts(" ** skipping \n"); + return 0; + } + /* * Get the read to the beginning of a partition. */ diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 30c9b15..2ce7829 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -45,6 +45,7 @@ int raise(int n) int read_file(const char * filepath, u8 * destination, int size) { int len = size; + int ret; switch (this_kernel->filesystem) { case FS_EXT2: @@ -60,7 +61,11 @@ int read_file(const char * filepath, u8 * destination, int size) return -1; } puts(" OK\n"); - ext2fs_read((char *)destination, size); + ret = ext2fs_read((char *)destination, size); + if (ret < 0) { + puts(" Read failed\n"); + return -1; + } break; case FS_FAT: @@ -282,26 +287,24 @@ void bootloader_second_phase(void) /* kernel commandline */ - if (*p) { - cmdline = params->u.cmdline.cmdline; - cmdline += strlen(strcpy(cmdline, p)); - if (this_kernel->commandline_append) - cmdline += strlen(strcpy(cmdline, + cmdline = params->u.cmdline.cmdline; + cmdline += strlen(strcpy(cmdline, p)); + if (this_kernel->commandline_append) + cmdline += strlen(strcpy(cmdline, this_kernel->commandline_append)); if (commandline_rootfs_append[0]) cmdline += strlen(strcpy(cmdline, commandline_rootfs_append)); - params->hdr.tag = ATAG_CMDLINE; - params->hdr.size = (sizeof (struct tag_header) + - strlen(params->u.cmdline.cmdline) + 1 + 4) >> 2; + params->hdr.tag = ATAG_CMDLINE; + params->hdr.size = (sizeof (struct tag_header) + + strlen(params->u.cmdline.cmdline) + 1 + 4) >> 2; - puts(" Cmdline: "); - puts(params->u.cmdline.cmdline); - puts("\n"); + puts(" Cmdline: "); + puts(params->u.cmdline.cmdline); + puts("\n"); - params = tag_next (params); - } + params = tag_next (params); /* needs to always be the last tag */ params->hdr.tag = ATAG_NONE; From 5c9a2104f95b1ffbf7dce77765f10793b266eef8 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 1 Dec 2008 01:26:05 +0000 Subject: [PATCH 168/248] qi-commandline-debug-added-if-ui-key-down.patch Signed-off-by: Andy Green --- qiboot/src/phase2.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 2ce7829..2100d74 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -296,6 +296,18 @@ void bootloader_second_phase(void) cmdline += strlen(strcpy(cmdline, commandline_rootfs_append)); + /* + * if he's still holding down the UI_ACTION_SKIPKERNEL key + * now we finished loading the kernel, take it to mean he wants + * to have the debugging options added to the commandline + */ + + if (this_board->commandline_board_debug && + this_board->get_ui_keys) + if ((this_board->get_ui_keys)() & UI_ACTION_SKIPKERNEL) + cmdline += strlen(strcpy(cmdline, this_board-> + commandline_board_debug)); + params->hdr.tag = ATAG_CMDLINE; params->hdr.size = (sizeof (struct tag_header) + strlen(params->u.cmdline.cmdline) + 1 + 4) >> 2; From 9a6d9de901e9611926a1fc8bf68d63240bc86442 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 1 Dec 2008 01:26:06 +0000 Subject: [PATCH 169/248] qi-s3c2442-enable-d-cache.patch Seems we have no D-Cache enabled before? Also defeat AUX as EINT Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/gta02.c | 6 +++++- qiboot/src/cpu/s3c2442/start.S | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 2ea520a..7b78b81 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -168,7 +168,7 @@ void port_init_gta02(void) * Binary : 01 01 , 01 01 , 10 10 , 10 10 */ /* pulldown on GPF03: TP-4705+debug - debug conn will float */ - rGPFCON = 0x0000AAAA; + rGPFCON = 0x00008AAA; rGPFUP = 0x000000FF & ~(1 << 3); rGPFDAT = 0x00000000; @@ -366,6 +366,10 @@ static void close_gta02(void) /* set I2C GPIO back to peripheral unit */ (bb_s3c24xx.close)(); + + /* aux back to being EINT */ + rGPFCON = 0x0000AAAA; + } static u8 get_ui_keys_gta02(void) diff --git a/qiboot/src/cpu/s3c2442/start.S b/qiboot/src/cpu/s3c2442/start.S index eaab799..6ff9194 100644 --- a/qiboot/src/cpu/s3c2442/start.S +++ b/qiboot/src/cpu/s3c2442/start.S @@ -298,7 +298,7 @@ cpu_init_crit: 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 + orr r0, r0, #0x00005000 @ set bits 14, 12 D and I-Cache mcr p15, 0, r0, c1, c0, 0 /* From 40edd785a74fc442bc5baef47695ab9741d4e52c Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 1 Dec 2008 01:26:06 +0000 Subject: [PATCH 170/248] qi-gta02-remap-steppingstone.patch Despite what the docs say, steppingstone is always resident at 0x40000000 on s3c2442, this patch changes our linker script to stick all steppingstone code there. The mapping of steppingstone at 0x0 is broken by OM[] bus change dynamically caused for example by GTA02 AUX button actuation. Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/qi.lds | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/qiboot/src/cpu/s3c2442/qi.lds b/qiboot/src/cpu/s3c2442/qi.lds index c23b447..600f950 100644 --- a/qiboot/src/cpu/s3c2442/qi.lds +++ b/qiboot/src/cpu/s3c2442/qi.lds @@ -27,20 +27,21 @@ OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS { - . = 0x00000000; + __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. */ - . = ALIGN(4); - .text : + .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/blink_led.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) @@ -50,10 +51,10 @@ SECTIONS } . = ALIGN(4); - .everything_else ADDR (.text) + SIZEOF (.text) + 0x33000000 : - AT ( ADDR (.text) + SIZEOF (.text) ) { *(.text .rodata* .data) } + .everything_else ADDR (.text) - __steppingstone_always + SIZEOF (.text) + __qi_sdram_copy : + AT ( ADDR (.text) - __steppingstone_always + SIZEOF (.text) ) { *(.text .rodata* .data) } - . = 0x33800000 ; + . = __qi_sdram_copy + 0x800000 ; __bss_start = .; .bss (NOLOAD) : { From 710f2dbb6e01cb8b497239da71fed00721aa819e Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 1 Dec 2008 01:26:06 +0000 Subject: [PATCH 171/248] qi-introduce-ui-indicators.patch Allow a board to "indicate" events if it likes on whatever it has On GTA02 we light AUX during boot and run the vibrator briefly when we skip a partition or device. Signed-off-by: Andy Green --- qiboot/include/qi.h | 16 ++++++++++++++++ qiboot/src/cpu/s3c2442/gta02.c | 35 ++++++++++++++++++++++++++++++++++ qiboot/src/phase2.c | 28 ++++++++++++++++++++++++++- 3 files changed, 78 insertions(+), 1 deletion(-) diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index c8971e6..2592cd4 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -47,6 +47,21 @@ enum ui_actions { 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 { @@ -89,6 +104,7 @@ struct board_api { void (*putc)(char); void (*close)(void); u8 (*get_ui_keys)(void); + void (*set_ui_indication)(enum ui_indication); struct kernel_source kernel_source[8]; }; diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 7b78b81..708e8a8 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -396,6 +396,40 @@ static u8 get_ui_keys_gta02(void) return ret; } + +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: + 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; + 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; + } +} + + /* * our API for bootloader on this machine */ @@ -412,6 +446,7 @@ const struct board_api board_api_gta02 = { .putc = putc_gta02, .close = close_gta02, .get_ui_keys = get_ui_keys_gta02, + .set_ui_indication = set_ui_indication_gta02, .commandline_board = "mtdparts=physmap-flash:-(nor);" \ "neo1973-nand:" \ "0x00040000(qi)," \ diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 2100d74..eeb81a1 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -37,11 +37,18 @@ struct kernel_source const * this_kernel = 0; const int INITRD_OFFSET = (8 * 1024 * 1024); + int raise(int n) { return 0; } +void indicate(enum ui_indication ui_indication) +{ + if (this_board->set_ui_indication) + (this_board->set_ui_indication)(ui_indication); +} + int read_file(const char * filepath, u8 * destination, int size) { int len = size; @@ -51,6 +58,7 @@ int read_file(const char * filepath, u8 * destination, int size) case FS_EXT2: if (!ext2fs_mount()) { puts("Unable to mount ext2 filesystem\n"); + indicate(UI_IND_MOUNT_FAIL); return -1; } puts(" EXT2 open: "); @@ -120,12 +128,15 @@ void bootloader_second_phase(void) puts(this_kernel->name); puts("\n"); + indicate(UI_IND_MOUNT_PART); + /* if this device needs initializing, try to init it */ if (this_kernel->block_init) if ((this_kernel->block_init)()) { puts("block device init failed\n"); this_kernel = &this_board-> kernel_source[kernel++]; + indicate(UI_IND_MOUNT_FAIL); continue; } @@ -140,6 +151,7 @@ void bootloader_second_phase(void) puts("Bad partition read\n"); this_kernel = &this_board-> kernel_source[kernel++]; + indicate(UI_IND_MOUNT_FAIL); continue; } @@ -147,6 +159,7 @@ void bootloader_second_phase(void) puts("partition signature missing\n"); this_kernel = &this_board-> kernel_source[kernel++]; + indicate(UI_IND_MOUNT_FAIL); continue; } @@ -181,6 +194,7 @@ void bootloader_second_phase(void) puts(this_board->noboot); puts(")\n"); this_kernel = &this_board->kernel_source[kernel++]; + indicate(UI_IND_SKIPPING); continue; } @@ -190,6 +204,8 @@ void bootloader_second_phase(void) read_file(this_board->append, (u8 *)commandline_rootfs_append, 512); + indicate(UI_IND_KERNEL_PULL); + /* pull the kernel image */ if (read_file(this_kernel->filepath, kernel_dram, 4096) < 0) { @@ -219,19 +235,26 @@ void bootloader_second_phase(void) if (read_file(this_kernel->filepath, kernel_dram, kernel_size) < 0) { this_kernel = &this_board->kernel_source[kernel++]; + indicate(UI_IND_KERNEL_PULL_FAIL); continue; } + indicate(UI_IND_KERNEL_PULL_OK); + /* initramfs if needed */ if (this_kernel->initramfs_filepath) { + indicate(UI_IND_INITRAMFS_PULL); initramfs_len = read_file(this_kernel->initramfs_filepath, - (u8 *)this_board->linux_mem_start + INITRD_OFFSET, 16 * 1024 * 1024); + (u8 *)this_board->linux_mem_start + INITRD_OFFSET, + 16 * 1024 * 1024); if (initramfs_len < 0) { puts("initramfs load failed\n"); this_kernel = &this_board->kernel_source[kernel++]; + indicate(UI_IND_INITRAMFS_PULL_FAIL); continue; } + indicate(UI_IND_INITRAMFS_PULL_OK); } /* @@ -329,6 +352,7 @@ void bootloader_second_phase(void) (this_board->close)(); puts ("Starting --->\n\n"); + indicate(UI_IND_KERNEL_START); /* * ooh that's it, we're gonna try boot this image! @@ -355,6 +379,8 @@ void bootloader_second_phase(void) * to provoke memory test. */ + indicate(UI_IND_MEM_TEST); + memory_test((void *)this_board->linux_mem_start, this_board->linux_mem_size); From 513fb7d0fc12a30871eb6f288c70e2173fb75084 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 1 Dec 2008 01:26:06 +0000 Subject: [PATCH 172/248] qi-clean-fail-partition-on-mount-fail.patch Failure to mount the filesystem makes us give up on the whole partition the moment it happens Signed-off-by: Andy Green --- qiboot/src/phase2.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index eeb81a1..1d7e3c7 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -59,7 +59,7 @@ int read_file(const char * filepath, u8 * destination, int size) if (!ext2fs_mount()) { puts("Unable to mount ext2 filesystem\n"); indicate(UI_IND_MOUNT_FAIL); - return -1; + return -2; /* death */ } puts(" EXT2 open: "); puts(filepath); @@ -104,6 +104,7 @@ void bootloader_second_phase(void) (this_board->get_board_variant)(); unsigned int initramfs_len = 0; static char commandline_rootfs_append[512] = ""; + int ret; /* we try the possible kernels for this board in order */ @@ -189,12 +190,16 @@ void bootloader_second_phase(void) /* does he want us to skip this? */ - if (read_file(this_board->noboot, kernel_dram, 512) >= 0) { - puts(" (Skipping on finding "); - puts(this_board->noboot); - puts(")\n"); + ret = read_file(this_board->noboot, kernel_dram, 512); + if (ret != -1) { + /* -2 (mount fail) should make us give up too */ + if (ret >= 0) { + puts(" (Skipping on finding "); + puts(this_board->noboot); + puts(")\n"); + indicate(UI_IND_SKIPPING); + } this_kernel = &this_board->kernel_source[kernel++]; - indicate(UI_IND_SKIPPING); continue; } From b4d381380c62530874b7b1a353ac725e863f7760 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 1 Dec 2008 01:26:07 +0000 Subject: [PATCH 173/248] qi-fix-only-init-same-block-device-once.patch If we're accessing the same device, we don't need to keep init-ing it Signed-off-by: Andy Green --- qiboot/src/phase2.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 1d7e3c7..162c434 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -105,6 +105,8 @@ void bootloader_second_phase(void) unsigned int initramfs_len = 0; static char commandline_rootfs_append[512] = ""; int ret; + void * last_block_init = NULL; + int last_block_init_result = 0; /* we try the possible kernels for this board in order */ @@ -132,14 +134,26 @@ void bootloader_second_phase(void) indicate(UI_IND_MOUNT_PART); /* if this device needs initializing, try to init it */ - if (this_kernel->block_init) - if ((this_kernel->block_init)()) { + if (this_kernel->block_init) { + /* + * cache result to limit attempts for same + * block device to one time + */ + if (this_kernel->block_init != last_block_init) + last_block_init_result = + (this_kernel->block_init)(); + + if (last_block_init_result) { puts("block device init failed\n"); + if (this_kernel->block_init != last_block_init) + indicate(UI_IND_MOUNT_FAIL); this_kernel = &this_board-> kernel_source[kernel++]; - indicate(UI_IND_MOUNT_FAIL); + last_block_init = this_kernel->block_init; continue; } + last_block_init = this_kernel->block_init; + } /* if there's a partition table implied, parse it, otherwise * just use a fixed offset From 3867e3d4cef25394cb0782c0e19e3adfca329d6f Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 1 Dec 2008 01:26:07 +0000 Subject: [PATCH 174/248] qi-gta01-02-03-always-tty0-console.patch tty0 is the LCM... this patch changes the defaults so that the kernel always treats tty0 as a console, but it also sets the loglevel so that only KERN_ERR or worse will be printed there. With matching changes to the kernel, most of the noise at KERN_ERR is reduced to KERN_INFO, so it gets the behviour the LCM by default is not cluttered with messages unless they are important during boot. Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2410/gta01.c | 14 ++++++++------ qiboot/src/cpu/s3c2442/gta02.c | 7 ++++--- qiboot/src/cpu/s3c6410/gta03-steppingstone.c | 6 ++++-- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/qiboot/src/cpu/s3c2410/gta01.c b/qiboot/src/cpu/s3c2410/gta01.c index 1b572d2..db7d653 100644 --- a/qiboot/src/cpu/s3c2410/gta01.c +++ b/qiboot/src/cpu/s3c2410/gta01.c @@ -259,10 +259,12 @@ const struct board_api board_api_gta01 = { "0x00200000(kernel)," \ "0x000a0000(splash)," \ "0x03d1c000(rootfs) " \ + "loglevel=4 " \ + "console=tty0 "\ "console=ttySAC0,115200 " \ "init=/sbin/init "\ - "ro", - .commandline_board_debug = " loglevel=8 console=tty0", + "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 */ @@ -274,7 +276,7 @@ const struct board_api board_api_gta01 = { .partition_index = 1, .filesystem = FS_EXT2, .filepath = "boot/uImage-GTA01.bin", - .commandline_append = " root=/dev/mmcblk0p1 ", + .commandline_append = "root=/dev/mmcblk0p1 ", }, [1] = { .name = "SD Card EXT2 Kernel p2", @@ -283,7 +285,7 @@ const struct board_api board_api_gta01 = { .partition_index = 2, .filesystem = FS_EXT2, .filepath = "boot/uImage-GTA01.bin", - .commandline_append = " root=/dev/mmcblk0p2 ", + .commandline_append = "root=/dev/mmcblk0p2 ", }, [2] = { .name = "SD Card EXT2 Kernel p3", @@ -292,14 +294,14 @@ const struct board_api board_api_gta01 = { .partition_index = 3, .filesystem = FS_EXT2, .filepath = "boot/uImage-GTA01.bin", - .commandline_append = " root=/dev/mmcblk0p3 ", + .commandline_append = "root=/dev/mmcblk0p3 ", }, [3] = { .name = "NAND Kernel", .block_read = nand_read_ll, .offset_blocks512_if_no_partition = 0x44000 / 512, .filesystem = FS_RAW, - .commandline_append = " rootfstype=jffs2 " \ + .commandline_append = "rootfstype=jffs2 " \ "root=/dev/mtdblock4 ", }, }, diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 708e8a8..583f22e 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -455,11 +455,12 @@ const struct board_api board_api_gta02 = { "0x000a0000(extra)," \ "0x00040000(identity)," \ "0x0f6a0000(backuprootfs) " \ + "loglevel=4 " \ + "console=tty0 " \ "console=ttySAC2,115200 " \ "init=/sbin/init " \ - "ro", - .commandline_board_debug = " console=tty0 " \ - "loglevel=8", + "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 */ diff --git a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c index 723b390..7e1bac6 100644 --- a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c @@ -85,9 +85,11 @@ const struct board_api board_api_gta03 = { .noboot = "boot/noboot-GTA03", .append = "boot/append-GTA03", .get_ui_keys = get_ui_keys_gta03, - .commandline_board = "console=ttySAC3,115200 " \ + .commandline_board = "console=tty0 " \ + "console=ttySAC3,115200 " \ "init=/sbin/init " \ - "loglevel=8 ", + "loglevel=8 " \ + "ro ", .kernel_source = { [0] = { .name = "SD Card rootfs", From 14acfb40af7dc00839f262336d2ce94bed8a88cb Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 1 Dec 2008 01:26:07 +0000 Subject: [PATCH 175/248] qi-gta02-no-inidcators-if-battery-low.patch This patch turns on the SYS and BAT monitoring filters, and checks if the battery meets the BAT OK threshold. If it doesn't, which is the case if the battery is not present, it disables the "indicator" (eg, LED, vibrator) stuff and holds the CPU at 200MHz during the boot into Linux. This allows the GTA02 A6 here to boot with no battery up to the point it is going to bring up backlight, and this with 100mA limit on USB at PMU. Enabling the threshold filters for battery and SYS seems to have been critical in getting any stability with this. Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/gta02.c | 73 +++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 583f22e..4ef9d55 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -35,6 +35,8 @@ #define PCF50633_I2C_ADS 0x73 #define BOOST_TO_400MHZ 1 +static int battery_condition_reasonable = 0; + const struct pcf50633_init pcf50633_init[] = { { PCF50633_REG_OOCWAKE, 0xd3 }, /* wake from ONKEY,EXTON!,RTC,USB,ADP */ @@ -43,8 +45,8 @@ const struct pcf50633_init pcf50633_init[] = { { 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_SVMCTL, 0x18 }, /* 3.10V SYS vth, 62ms filter */ + { PCF50633_REG_BVMCTL, 0x12 }, /* 2.80V BAT vth, 62ms filter */ { PCF50633_REG_AUTOENA, 0x01 }, /* always on */ @@ -95,11 +97,9 @@ static const struct board_variant board_variants[] = { void port_init_gta02(void) { -#if BOOST_TO_400MHZ unsigned int * MPLLCON = (unsigned int *)0x4c000004; unsigned int * UPLLCON = (unsigned int *)0x4c000008; unsigned int * CLKDIVN = (unsigned int *)0x4c000014; -#endif int n; //CAUTION:Follow the configuration order for setting the ports. @@ -229,31 +229,36 @@ void port_init_gta02(void) i2c_write_sync(&bb_s3c24xx, PCF50633_I2C_ADS, pcf50633_init[n].index, pcf50633_init[n].value); -#if BOOST_TO_400MHZ - /* change CPU clocking to 400MHz 1:4:8 */ + /* what does the battery monitoring unit say about the battery? */ - /* 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); + battery_condition_reasonable = !(i2c_read_sync(&bb_s3c24xx, + PCF50633_I2C_ADS, PCF50633_REG_BVMCTL) & 1); - /* get debug UART working at 115kbps */ - serial_init_115200_s3c24xx(GTA02_DEBUG_UART, 50 /* 50MHz PCLK */); -#else - serial_init_115200_s3c24xx(GTA02_DEBUG_UART, 33 /* 33MHz PCLK */); -#endif + 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 @@ -399,6 +404,7 @@ static u8 get_ui_keys_gta02(void) static void set_ui_indication_gta02(enum ui_indication ui_indication) { + switch (ui_indication) { case UI_IND_UPDATE_ONLY: break; @@ -406,7 +412,8 @@ static void set_ui_indication_gta02(enum ui_indication ui_indication) case UI_IND_MOUNT_PART: case UI_IND_KERNEL_PULL_OK: case UI_IND_INITRAMFS_PULL_OK: - rGPBDAT |= 4; + if (battery_condition_reasonable) + rGPBDAT |= 4; break; case UI_IND_KERNEL_PULL_FAIL: @@ -414,10 +421,12 @@ static void set_ui_indication_gta02(enum ui_indication ui_indication) case UI_IND_INITRAMFS_PULL_FAIL: case UI_IND_MOUNT_FAIL: rGPBDAT &= ~4; - rGPBDAT |= 8; - udelay(2000000); - rGPBDAT &= ~8; - udelay(200000); + if (battery_condition_reasonable) { + rGPBDAT |= 8; + udelay(2000000); + rGPBDAT &= ~8; + udelay(200000); + } break; case UI_IND_KERNEL_START: From af49f931b62579cb520194ebdd1d77d6bdf06b6c Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 1 Dec 2008 11:16:17 +0000 Subject: [PATCH 176/248] qi-gta03-rootdelay.patch Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/gta03-steppingstone.c | 1 + 1 file changed, 1 insertion(+) diff --git a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c index 7e1bac6..7f97d17 100644 --- a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c @@ -89,6 +89,7 @@ const struct board_api board_api_gta03 = { "console=ttySAC3,115200 " \ "init=/sbin/init " \ "loglevel=8 " \ + "rootdelay=1 " \ "ro ", .kernel_source = { [0] = { From 1f150a592ec53b49e19a072e135725500b93d0aa Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 5 Dec 2008 23:15:47 +0000 Subject: [PATCH 177/248] qi-s3c6410-add-resume-path-processing.patch First go at resume processing for 6410, can't test it until Ben Dooks confirms operation of Linux side on SMDK Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/start.S | 39 +++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/qiboot/src/cpu/s3c6410/start.S b/qiboot/src/cpu/s3c6410/start.S index f9e5079..be90d57 100644 --- a/qiboot/src/cpu/s3c6410/start.S +++ b/qiboot/src/cpu/s3c6410/start.S @@ -423,9 +423,19 @@ start_code: ldr r1, =0x1FFF str r1, [r0, #UDIVSLOT_OFFSET] + /* resuming? */ + + ldr r0, =(ELFIN_CLOCK_POWER_BASE+RST_STAT_OFFSET) + ldr r1, [r0] + bic r1, r1, #0xfffffff7 + cmp r1, #0x8 + beq wakeup_reset + + /* no, cold boot */ + + ldr r0, =ELFIN_UART_BASE + ELFIN_UART3_OFFSET ldr r1, =0x55 str r1, [r0, #UTXH_OFFSET] @'U' - /* >> CFG_VIDEO_LOGO_MAX_SIZE */ #define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ @@ -446,5 +456,32 @@ clbss_l: b _steppingstone_done + /* resume */ + +wakeup_reset: + + ldr r0, =ELFIN_UART_BASE + ELFIN_UART3_OFFSET + ldr r1, =0x4b4b4b4b + str r1, [r0, #UTXH_OFFSET] + + /*Clear wakeup status register*/ + ldr r0, =(ELFIN_CLOCK_POWER_BASE+WAKEUP_STAT_OFFSET) + ldr r1, [r0] + str r1, [r0] + +#if 0 + /*LED test*/ + ldr r0, =ELFIN_GPIO_BASE + ldr r1, =0x3000 + str r1, [r0, #GPNDAT_OFFSET] +#endif + + /*Load return address and jump to kernel*/ + ldr r0, =(ELFIN_CLOCK_POWER_BASE+INF_REG0_OFFSET) + ldr r1, [r0] /* r1 = physical address of s3c6400_cpu_resume function*/ + mov pc, r1 /*Jump to kernel (sleep-s3c6400.S)*/ + nop + nop + 4: b 4b From 6dae9d7009bc95aacd13e47f546336d88b64b2fa Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 5 Dec 2008 23:15:47 +0000 Subject: [PATCH 178/248] qi-gta02-improve-default-reg-states.patch Need to let PWREN take care of more regulators really Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/gta02.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 4ef9d55..d9c6b8a 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -73,10 +73,11 @@ const struct pcf50633_init pcf50633_init[] = { { PCF50633_REG_MBCC8, 0x00 }, { PCF50633_REG_MBCC1, 0xff }, /* chgena */ - { PCF50633_REG_LDO1ENA, 2 }, /* enabled if GPIO1 = H */ - { PCF50633_REG_LDO2ENA, 2 }, /* enabled if GPIO1 = H */ - { PCF50633_REG_LDO5ENA, 1 }, - { PCF50633_REG_LDO6ENA, 1 }, + { 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 */ From f9b0afbdb6d83ebcf6da52c82415011e8a3eb06d Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 5 Dec 2008 23:15:47 +0000 Subject: [PATCH 179/248] qi-gta03-fix-charging.patch These two changes get charging working on GTA03 with new battery. Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/gta03.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qiboot/src/cpu/s3c6410/gta03.c b/qiboot/src/cpu/s3c6410/gta03.c index 10ac90e..acffb0b 100644 --- a/qiboot/src/cpu/s3c6410/gta03.c +++ b/qiboot/src/cpu/s3c6410/gta03.c @@ -33,13 +33,13 @@ const struct pcf50633_init gta03_pcf50633_init[] = { { 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, 0x19 }, /* 25/255 == 98mA soft-start usb fast */ + { PCF50633_REG_MBCC5, 0xff }, /* 255/255 == 1A USB fast */ { PCF50633_REG_MBCC6, 0x00 }, /* cutoff current 1/32 * Ichg */ -#if 0 + /* current prototype is pulling > 100mA at startup */ - { PCF50633_REG_MBCC7, 0x00 }, /* 1.6A max bat curr, USB 100mA */ -#endif + { PCF50633_REG_MBCC7, 0xc1 }, /* 2.2A max bat curr, USB 500mA */ + { PCF50633_REG_MBCC8, 0x00 }, { PCF50633_REG_MBCC1, 0xff }, /* chgena */ From 74dc2cc01ac37469dea7a2f2ca23265aa9f19f41 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 5 Dec 2008 23:15:48 +0000 Subject: [PATCH 180/248] qi-fix-gta03-default-wlan-power.patch Make sure WLAN module power is off by default - this controls a P-Channel MOSFET that gates all the power there Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/gta03.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qiboot/src/cpu/s3c6410/gta03.c b/qiboot/src/cpu/s3c6410/gta03.c index acffb0b..3bb9fb8 100644 --- a/qiboot/src/cpu/s3c6410/gta03.c +++ b/qiboot/src/cpu/s3c6410/gta03.c @@ -538,7 +538,8 @@ void port_init_gta03(void) __REG(GPKPUD) = 0; /* all pullup and pulldown disabled */ __REG(GPKDAT) = - (1 << 2) /* deassert nMODEM_ON */ + (1 << 2) | /* deassert nMODEM_ON */ + (1 << 0) /* deassert nWLAN_POWERON */ ; /* ---------------------------- Port L ---------------------------- */ From b5c87ae317363c1b5de8f6fbdb87fd4893b9c888 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 5 Dec 2008 23:15:48 +0000 Subject: [PATCH 181/248] qi-gta03-revert-to-bin-sh.patch Rootfs is not quite ready for /sbin/init Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/gta03-steppingstone.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c index 7f97d17..d0027c6 100644 --- a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c @@ -87,7 +87,7 @@ const struct board_api board_api_gta03 = { .get_ui_keys = get_ui_keys_gta03, .commandline_board = "console=tty0 " \ "console=ttySAC3,115200 " \ - "init=/sbin/init " \ + "init=/bin/sh " \ "loglevel=8 " \ "rootdelay=1 " \ "ro ", From 51ce8bac68b8b10ef4835fb704b512ad08d7ae51 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Tue, 9 Dec 2008 11:04:57 +0000 Subject: [PATCH 182/248] qi-gta03-suspend-gpio.patch Change to input / pulldown on most GPIO. With no battery and just USB power, this gets us into suspend with 9.5mA at 5V consumption... but Ben Dooks told that we don't put the mDDR into deep sleep yet in the platform pm code, so this should come right down when we have that. The suspend is otherwise real though, PWREN to the PMU goes down, and when we wake the device Qi is able to see it is a resume wake and jumps back into Linux, where we currently die due to issues on s3c6410 platform code getting worked on. Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/gta03.c | 374 +++++++++++++++++---------------- 1 file changed, 194 insertions(+), 180 deletions(-) diff --git a/qiboot/src/cpu/s3c6410/gta03.c b/qiboot/src/cpu/s3c6410/gta03.c index 3bb9fb8..d2f25aa 100644 --- a/qiboot/src/cpu/s3c6410/gta03.c +++ b/qiboot/src/cpu/s3c6410/gta03.c @@ -100,19 +100,30 @@ void port_init_gta03(void) (2 << 28) /* GPA7 - UART_RTS1 */ ; - __REG(GPAPUD) = 0; /* all pullup and pulldown disabled */ - + __REG(GPAPUD) = /* all pullup and pulldown disabled */ + 0 + ; __REG(GPADAT) = 0; /* just for determinism */ __REG(GPACONSLP) = - (3 << 0) | /* GPA0 - keep */ - (3 << 2) | /* GPA1 - keep */ - (3 << 4) | /* GPA2 - keep */ - (3 << 6) | /* GPA3 - keep */ - (3 << 8) | /* GPA4 - keep */ - (3 << 10) | /* GPA5 - keep */ - (3 << 12) | /* GPA6 - keep */ - (3 << 14) /* GPA7 - keep */ + (2 << 0) | /* GPA0 - input */ + (2 << 2) | /* GPA1 - input */ + (2 << 4) | /* GPA2 - input */ + (2 << 6) | /* GPA3 - input */ + (2 << 8) | /* GPA4 - input */ + (2 << 10) | /* GPA5 - input */ + (2 << 12) | /* GPA6 - input */ + (2 << 14) /* GPA7 - input */ + ; + __REG(GPAPUDSLP) = + (1 << 0) | /* GPA0 - pulldown */ + (1 << 2) | /* GPA1 - pulldown */ + (1 << 4) | /* GPA2 - pulldown */ + (1 << 6) | /* GPA3 - pulldown */ + (1 << 8) | /* GPA4 - pulldown */ + (1 << 10) | /* GPA5 - pulldown */ + (1 << 12) | /* GPA6 - pulldown */ + (1 << 14) /* GPA7 - pulldown */ ; /* ---------------------------- Port B ---------------------------- */ @@ -127,30 +138,32 @@ void port_init_gta03(void) (1 << 24) /* GPB6 - (I2C BB SDA) OUTPUT */ ; - __REG(GPBPUD) = 0; /* all pullup and pulldown disabled */ + __REG(GPBPUD) = /* all pullup and pulldown disabled */ + 0 + ; __REG(GPBDAT) = 0; /* just for determinism */ __REG(GPBCONSLP) = - (3 << 0) | /* GPB0 - keep */ - (3 << 2) | /* GPB1 - keep */ - (3 << 4) | /* GPB2 - keep */ - (3 << 6) | /* GPB3 - keep */ - (3 << 8) | /* GPB4 - keep */ - (3 << 10) | /* GPB5 - keep */ - (3 << 12) | /* GPB6 - keep */ - (3 << 14) /* GPB7 - keep */ + (2 << 0) | /* GPB0 - input */ + (2 << 2) | /* GPB1 - input */ + (2 << 4) | /* GPB2 - input */ + (2 << 6) | /* GPB3 - input */ + (2 << 8) | /* GPB4 - input */ + (2 << 10) | /* GPB5 - input */ + (2 << 12) | /* GPB6 - input */ + (2 << 14) /* GPB7 - input */ ; __REG(GPBPUDSLP) = - (0 << 0) | /* GPB0 - no pull up or down */ - (0 << 2) | /* GPB1 - no pull up or down */ - (0 << 4) | /* GPB2 - no pull up or down */ - (0 << 6) | /* GPB3 - no pull up or down */ - (0 << 8) | /* GPB4 - no pull up or down */ - (0 << 10) | /* GPB5 - no pull up or down */ - (0 << 12) | /* GPB6 - no pull up or down */ - (0 << 14) /* GPB7 - no pull up or down */ + (1 << 0) | /* GPB0 - pull down */ + (1 << 2) | /* GPB1 - pull down */ + (1 << 4) | /* GPB2 - pull down */ + (1 << 6) | /* GPB3 - pull down */ + (1 << 8) | /* GPB4 - pull down */ + (1 << 10) | /* GPB5 - pull down */ + (1 << 12) | /* GPB6 - pull down */ + (1 << 14) /* GPB7 - pull down */ ; /* ---------------------------- Port C ---------------------------- */ @@ -166,30 +179,31 @@ void port_init_gta03(void) (1 << 28) /* GPC7 - SPI_CS1 OUTPUT */ ; - __REG(GPCPUD) = 0; /* all pullup and pulldown disabled */ - + __REG(GPCPUD) = /* all pullup and pulldown disabled */ + 0 + ; __REG(GPCDAT) = 0; /* just for determinism */ __REG(GPCCONSLP) = - (3 << 0) | /* GPC0 - keep */ - (3 << 2) | /* GPC1 - keep */ - (3 << 4) | /* GPC2 - keep */ - (3 << 6) | /* GPC3 - keep */ - (3 << 8) | /* GPC4 - keep */ - (3 << 10) | /* GPC5 - keep */ - (3 << 12) | /* GPC6 - keep */ - (3 << 14) /* GPC7 - keep */ + (2 << 0) | /* GPC0 - input */ + (2 << 2) | /* GPC1 - input */ + (2 << 4) | /* GPC2 - input */ + (2 << 6) | /* GPC3 - input */ + (2 << 8) | /* GPC4 - input */ + (2 << 10) | /* GPC5 - input */ + (2 << 12) | /* GPC6 - input */ + (2 << 14) /* GPC7 - input */ ; __REG(GPCPUDSLP) = - (0 << 0) | /* GPC0 - no pull up or down */ - (0 << 2) | /* GPC1 - no pull up or down */ - (0 << 4) | /* GPC2 - no pull up or down */ - (0 << 6) | /* GPC3 - no pull up or down */ - (0 << 8) | /* GPC4 - no pull up or down */ - (0 << 10) | /* GPC5 - no pull up or down */ - (0 << 12) | /* GPC6 - no pull up or down */ - (0 << 14) /* GPC7 - no pull up or down */ + (1 << 0) | /* GPC0 - pull down */ + (1 << 2) | /* GPC1 - pull down */ + (1 << 4) | /* GPC2 - pull down */ + (1 << 6) | /* GPC3 - pull down */ + (1 << 8) | /* GPC4 - pull down */ + (1 << 10) | /* GPC5 - pull down */ + (1 << 12) | /* GPC6 - pull down */ + (1 << 14) /* GPC7 - pull down */ ; /* ---------------------------- Port D ---------------------------- */ @@ -207,19 +221,19 @@ void port_init_gta03(void) __REG(GPDDAT) = 0; /* just for determinism */ __REG(GPDCONSLP) = - (3 << 0) | /* GPD0 - keep */ - (3 << 2) | /* GPD1 - keep */ - (3 << 4) | /* GPD2 - keep */ - (3 << 6) | /* GPD3 - keep */ - (3 << 8) /* GPD4 - keep */ + (2 << 0) | /* GPD0 - input */ + (2 << 2) | /* GPD1 - input */ + (2 << 4) | /* GPD2 - input */ + (2 << 6) | /* GPD3 - input */ + (2 << 8) /* GPD4 - input */ ; __REG(GPDPUDSLP) = - (0 << 0) | /* GPD0 - no pull up or down */ - (0 << 2) | /* GPD1 - no pull up or down */ - (0 << 4) | /* GPD2 - no pull up or down */ - (0 << 6) | /* GPD3 - no pull up or down */ - (0 << 8) /* GPD4 - no pull up or down */ + (1 << 0) | /* GPD0 - pull down */ + (1 << 2) | /* GPD1 - pull down */ + (1 << 4) | /* GPD2 - pull down */ + (1 << 6) | /* GPD3 - pull down */ + (1 << 8) /* GPD4 - pull down */ ; /* ---------------------------- Port E ---------------------------- */ @@ -237,11 +251,11 @@ void port_init_gta03(void) __REG(GPEDAT) = 0; /* just for determinism */ __REG(GPECONSLP) = - (3 << 0) | /* GPE0 - keep */ - (3 << 2) | /* GPE1 - keep */ - (3 << 4) | /* GPE2 - keep */ - (3 << 6) | /* GPE3 - keep */ - (3 << 8) /* GPE4 - keep */ + (2 << 0) | /* GPE0 - input */ + (2 << 2) | /* GPE1 - input */ + (2 << 4) | /* GPE2 - input */ + (2 << 6) | /* GPE3 - input */ + (2 << 8) /* GPE4 - input */ ; __REG(GPEPUDSLP) = @@ -278,41 +292,41 @@ void port_init_gta03(void) __REG(GPFDAT) = (1 << 15); /* assert CAM_PWRDN */ __REG(GPFCONSLP) = - (0 << 0) | /* GPF0 - OUTPUT 0 */ - (0 << 2) | /* GPF1 - OUTPUT 0 */ - (0 << 4) | /* GPF2 - OUTPUT 0 */ - (0 << 6) | /* GPF3 - OUTPUT 0 */ - (0 << 8) | /* GPF4 - OUTPUT 0 */ - (0 << 10) | /* GPF5 - OUTPUT 0 */ - (0 << 12) | /* GPF6 - OUTPUT 0 */ - (0 << 14) | /* GPF7 - OUTPUT 0 */ - (0 << 16) | /* GPF8 - OUTPUT 0 */ - (0 << 18) | /* GPF9 - OUTPUT 0 */ - (0 << 20) | /* GPF10 - OUTPUT 0 */ - (0 << 22) | /* GPF11 - OUTPUT 0 */ - (0 << 24) | /* GPF12 - OUTPUT 0 */ - (0 << 26) | /* GPF13 - OUTPUT 0 */ - (0 << 28) | /* GPF14 - OUTPUT 0 */ - (0 << 30) /* GPF15 - OUTPUT 0 */ + (2 << 0) | /* GPF0 - input */ + (2 << 2) | /* GPF1 - input */ + (2 << 4) | /* GPF2 - input */ + (2 << 6) | /* GPF3 - input */ + (2 << 8) | /* GPF4 - input */ + (2 << 10) | /* GPF5 - input */ + (2 << 12) | /* GPF6 - input */ + (2 << 14) | /* GPF7 - input */ + (2 << 16) | /* GPF8 - input */ + (2 << 18) | /* GPF9 - input */ + (2 << 20) | /* GPF10 - input */ + (2 << 22) | /* GPF11 - input */ + (2 << 24) | /* GPF12 - input */ + (2 << 26) | /* GPF13 - input */ + (2 << 28) | /* GPF14 - input */ + (2 << 30) /* GPF15 - input */ ; __REG(GPFPUDSLP) = - (0 << 0) | /* GPF0 - no pull up or down */ - (0 << 2) | /* GPF1 - no pull up or down */ - (0 << 4) | /* GPF2 - no pull up or down */ - (0 << 6) | /* GPF3 - no pull up or down */ - (0 << 8) | /* GPF4 - no pull up or down */ - (0 << 10) | /* GPF5 - no pull up or down */ - (0 << 12) | /* GPF6 - no pull up or down */ - (0 << 14) | /* GPF7 - no pull up or down */ - (0 << 16) | /* GPF8 - no pull up or down */ - (0 << 18) | /* GPF9 - no pull up or down */ - (0 << 20) | /* GPF10 - no pull up or down */ - (0 << 22) | /* GPF11 - no pull up or down */ - (0 << 24) | /* GPF12 - no pull up or down */ - (0 << 26) | /* GPF13 - no pull up or down */ - (0 << 28) | /* GPF14 - no pull up or down */ - (0 << 30) /* GPF15 - no pull up or down */ + (1 << 0) | /* GPF0 - pull down */ + (1 << 2) | /* GPF1 - pull down */ + (1 << 4) | /* GPF2 - pull down */ + (1 << 6) | /* GPF3 - pull down */ + (1 << 8) | /* GPF4 - pull down */ + (1 << 10) | /* GPF5 - pull down */ + (1 << 12) | /* GPF6 - pull down */ + (1 << 14) | /* GPF7 - pull down */ + (1 << 16) | /* GPF8 - pull down */ + (1 << 18) | /* GPF9 - pull down */ + (1 << 20) | /* GPF10 - pull down */ + (1 << 22) | /* GPF11 - pull down */ + (1 << 24) | /* GPF12 - pull down */ + (1 << 26) | /* GPF13 - pull down */ + (1 << 28) | /* GPF14 - pull down */ + (1 << 30) /* GPF15 - pull down */ ; /* ---------------------------- Port G ---------------------------- */ @@ -332,23 +346,23 @@ void port_init_gta03(void) __REG(GPGDAT) = 0; /* just for determinism */ __REG(GPGCONSLP) = - (0 << 0) | /* GPG0 - OUTPUT 0 */ - (0 << 2) | /* GPG1 - OUTPUT 0 */ - (0 << 4) | /* GPG2 - OUTPUT 0 */ - (0 << 6) | /* GPG3 - OUTPUT 0 */ - (0 << 8) | /* GPG4 - OUTPUT 0 */ - (0 << 10) | /* GPG5 - OUTPUT 0 */ - (0 << 12) /* GPG6 - OUTPUT 0 */ + (2 << 0) | /* GPG0 - input */ + (2 << 2) | /* GPG1 - input */ + (2 << 4) | /* GPG2 - input */ + (2 << 6) | /* GPG3 - input */ + (2 << 8) | /* GPG4 - input */ + (2 << 10) | /* GPG5 - input */ + (2 << 12) /* GPG6 - input */ ; __REG(GPGPUDSLP) = - (0 << 0) | /* GPG0 - no pull up or down */ - (0 << 2) | /* GPG1 - no pull up or down */ - (0 << 4) | /* GPG2 - no pull up or down */ - (0 << 6) | /* GPG3 - no pull up or down */ - (0 << 8) | /* GPG4 - no pull up or down */ - (0 << 10) | /* GPG5 - no pull up or down */ - (0 << 12) /* GPG6 - no pull up or down */ + (1 << 0) | /* GPG0 - pull down */ + (1 << 2) | /* GPG1 - pull down */ + (1 << 4) | /* GPG2 - pull down */ + (1 << 6) | /* GPG3 - pull down */ + (1 << 8) | /* GPG4 - pull down */ + (1 << 10) | /* GPG5 - pull down */ + (1 << 12) /* GPG6 - pull down */ ; /* ---------------------------- Port H ---------------------------- */ @@ -373,29 +387,29 @@ void port_init_gta03(void) __REG(GPHDAT) = 0; __REG(GPHCONSLP) = - (0 << 0) | /* GPH0 - OUTPUT 0 */ - (0 << 2) | /* GPH1 - OUTPUT 0 */ - (0 << 4) | /* GPH2 - OUTPUT 0 */ - (0 << 6) | /* GPH3 - OUTPUT 0 */ - (0 << 8) | /* GPH4 - OUTPUT 0 */ - (0 << 10) | /* GPH5 - OUTPUT 0 */ - (0 << 12) | /* GPH6 - OUTPUT 0 */ + (2 << 0) | /* GPH0 - input */ + (2 << 2) | /* GPH1 - input */ + (2 << 4) | /* GPH2 - input */ + (2 << 6) | /* GPH3 - input */ + (2 << 8) | /* GPH4 - input */ + (2 << 10) | /* GPH5 - input */ + (2 << 12) | /* GPH6 - input */ (2 << 14) | /* GPH7 - INPUT (HDQ) */ - (0 << 16) | /* GPH8 - OUTPUT 0 */ - (0 << 18) /* GPH9 - OUTPUT 0 */ + (2 << 16) | /* GPH8 - input */ + (2 << 18) /* GPH9 - input */ ; __REG(GPHPUDSLP) = - (0 << 0) | /* GPH0 - no pull up or down */ - (0 << 2) | /* GPH1 - no pull up or down */ - (0 << 4) | /* GPH2 - no pull up or down */ - (0 << 6) | /* GPH3 - no pull up or down */ - (0 << 8) | /* GPH4 - no pull up or down */ - (0 << 10) | /* GPH5 - no pull up or down */ + (1 << 0) | /* GPH0 - pull down */ + (1 << 2) | /* GPH1 - pull down */ + (1 << 4) | /* GPH2 - pull down */ + (1 << 6) | /* GPH3 - pull down */ + (1 << 8) | /* GPH4 - pull down */ + (1 << 10) | /* GPH5 - pull down */ (2 << 12) | /* GPH6 - PULLUP (HDQ) */ - (0 << 14) | /* GPH7 - no pull up or down */ - (0 << 16) | /* GPH8 - no pull up or down */ - (0 << 18) /* GPH9 - no pull up or down */ + (1 << 14) | /* GPH7 - pull down */ + (1 << 16) | /* GPH8 - pull down */ + (1 << 18) /* GPH9 - pull down */ ; /* ---------------------------- Port I ---------------------------- */ @@ -424,41 +438,41 @@ void port_init_gta03(void) __REG(GPIDAT) = 0; /* just for determinism */ __REG(GPICONSLP) = - (0 << 0) | /* GPI0 - OUTPUT 0 */ - (0 << 2) | /* GPI1 - OUTPUT 0 */ - (0 << 4) | /* GPI2 - OUTPUT 0 */ - (0 << 6) | /* GPI3 - OUTPUT 0 */ - (0 << 8) | /* GPI4 - OUTPUT 0 */ - (0 << 10) | /* GPI5 - OUTPUT 0 */ - (0 << 12) | /* GPI6 - OUTPUT 0 */ - (0 << 14) | /* GPI7 - OUTPUT 0 */ - (0 << 16) | /* GPI8 - OUTPUT 0 */ - (0 << 18) | /* GPI9 - OUTPUT 0 */ - (0 << 20) | /* GPI10 - OUTPUT 0 */ - (0 << 22) | /* GPI11 - OUTPUT 0 */ - (0 << 24) | /* GPI12 - OUTPUT 0 */ - (0 << 26) | /* GPI13 - OUTPUT 0 */ - (0 << 28) | /* GPI14 - OUTPUT 0 */ - (0 << 30) /* GPI15 - OUTPUT 0 */ + (2 << 0) | /* GPI0 - input */ + (2 << 2) | /* GPI1 - input */ + (2 << 4) | /* GPI2 - input */ + (2 << 6) | /* GPI3 - input */ + (2 << 8) | /* GPI4 - input */ + (2 << 10) | /* GPI5 - input */ + (2 << 12) | /* GPI6 - input */ + (2 << 14) | /* GPI7 - input */ + (2 << 16) | /* GPI8 - input */ + (2 << 18) | /* GPI9 - input */ + (2 << 20) | /* GPI10 - input */ + (2 << 22) | /* GPI11 - input */ + (2 << 24) | /* GPI12 - input */ + (2 << 26) | /* GPI13 - input */ + (2 << 28) | /* GPI14 - input */ + (2 << 30) /* GPI15 - input */ ; __REG(GPIPUDSLP) = - (0 << 0) | /* GPI0 - no pull up or down */ - (0 << 2) | /* GPI1 - no pull up or down */ - (0 << 4) | /* GPI2 - no pull up or down */ - (0 << 6) | /* GPI3 - no pull up or down */ - (0 << 8) | /* GPI4 - no pull up or down */ - (0 << 10) | /* GPI5 - no pull up or down */ - (0 << 12) | /* GPI6 - no pull up or down */ - (0 << 14) | /* GPI7 - no pull up or down */ - (0 << 16) | /* GPI8 - no pull up or down */ - (0 << 18) | /* GPI9 - no pull up or down */ - (0 << 20) | /* GPI10 - no pull up or down */ - (0 << 22) | /* GPI11 - no pull up or down */ - (0 << 24) | /* GPI12 - no pull up or down */ - (0 << 26) | /* GPI13 - no pull up or down */ - (0 << 28) | /* GPI14 - no pull up or down */ - (0 << 30) /* GPI15 - no pull up or down */ + (1 << 0) | /* GPI0 - pull down */ + (1 << 2) | /* GPI1 - pull down */ + (1 << 4) | /* GPI2 - pull down */ + (1 << 6) | /* GPI3 - pull down */ + (1 << 8) | /* GPI4 - pull down */ + (1 << 10) | /* GPI5 - pull down */ + (1 << 12) | /* GPI6 - pull down */ + (1 << 14) | /* GPI7 - pull down */ + (1 << 16) | /* GPI8 - pull down */ + (1 << 18) | /* GPI9 - pull down */ + (1 << 20) | /* GPI10 - pull down */ + (1 << 22) | /* GPI11 - pull down */ + (1 << 24) | /* GPI12 - pull down */ + (1 << 26) | /* GPI13 - pull down */ + (1 << 28) | /* GPI14 - pull down */ + (1 << 30) /* GPI15 - pull down */ ; /* ---------------------------- Port J ---------------------------- */ @@ -483,33 +497,33 @@ void port_init_gta03(void) __REG(GPJDAT) = 0; /* just for determinism */ __REG(GPJCONSLP) = - (0 << 0) | /* GPJ0 - OUTPUT 0 */ - (0 << 2) | /* GPJ1 - OUTPUT 0 */ - (0 << 4) | /* GPJ2 - OUTPUT 0 */ - (0 << 6) | /* GPJ3 - OUTPUT 0 */ - (0 << 8) | /* GPJ4 - OUTPUT 0 */ - (0 << 10) | /* GPJ5 - OUTPUT 0 */ - (0 << 12) | /* GPJ6 - OUTPUT 0 */ - (0 << 14) | /* GPJ7 - OUTPUT 0 */ - (0 << 16) | /* GPJ8 - OUTPUT 0 */ - (0 << 18) | /* GPJ9 - OUTPUT 0 */ - (0 << 20) | /* GPJ10 - OUTPUT 0 */ - (0 << 22) /* GPJ11 - OUTPUT 0 */ + (2 << 0) | /* GPJ0 - input */ + (2 << 2) | /* GPJ1 - input */ + (2 << 4) | /* GPJ2 - input */ + (2 << 6) | /* GPJ3 - input */ + (2 << 8) | /* GPJ4 - input */ + (2 << 10) | /* GPJ5 - input */ + (2 << 12) | /* GPJ6 - input */ + (2 << 14) | /* GPJ7 - input */ + (2 << 16) | /* GPJ8 - input */ + (2 << 18) | /* GPJ9 - input */ + (2 << 20) | /* GPJ10 - input */ + (2 << 22) /* GPJ11 - input */ ; __REG(GPJPUDSLP) = - (0 << 0) | /* GPJ0 - no pull up or down */ - (0 << 2) | /* GPJ1 - no pull up or down */ - (0 << 4) | /* GPJ2 - no pull up or down */ - (0 << 6) | /* GPJ3 - no pull up or down */ - (0 << 8) | /* GPJ4 - no pull up or down */ - (0 << 10) | /* GPJ5 - no pull up or down */ - (0 << 12) | /* GPJ6 - no pull up or down */ - (0 << 14) | /* GPJ7 - no pull up or down */ - (0 << 16) | /* GPJ8 - no pull up or down */ - (0 << 18) | /* GPJ9 - no pull up or down */ - (0 << 20) | /* GPJ10 - no pull up or down */ - (0 << 22) /* GPJ11 - no pull up or down */ + (1 << 0) | /* GPJ0 - pull down */ + (1 << 2) | /* GPJ1 - pull down */ + (1 << 4) | /* GPJ2 - pull down */ + (1 << 6) | /* GPJ3 - pull down */ + (1 << 8) | /* GPJ4 - pull down */ + (1 << 10) | /* GPJ5 - pull down */ + (1 << 12) | /* GPJ6 - pull down */ + (1 << 14) | /* GPJ7 - pull down */ + (1 << 16) | /* GPJ8 - pull down */ + (1 << 18) | /* GPJ9 - pull down */ + (1 << 20) | /* GPJ10 - pull down */ + (1 << 22) /* GPJ11 - pull down */ ; /* ---------------------------- Port K ---------------------------- */ From 177921a4e6148e85f4a8fdebacafaea66802cef9 Mon Sep 17 00:00:00 2001 From: Paul Fertser Date: Sat, 13 Dec 2008 20:34:46 +0000 Subject: [PATCH 183/248] [PATCH] Some SD cards require more retries in mmc_init This patch effectively doubles maximum time allowed for retries performed by mmc_init. Also, the delay was shortened to lower the average time needed to init a card. Without it, i was unable to boot from Transcend TS8GUSDHC4 (appending rootdelay=1 was necessary as well). --- qiboot/src/drivers/glamo-mmc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/qiboot/src/drivers/glamo-mmc.c b/qiboot/src/drivers/glamo-mmc.c index be6b6e2..8f649d1 100644 --- a/qiboot/src/drivers/glamo-mmc.c +++ b/qiboot/src/drivers/glamo-mmc.c @@ -609,7 +609,7 @@ static void print_sd_cid(const struct sd_cid *cid) int mmc_init(int verbose) { - int retries = 50, rc = -1; + int retries = 3000, rc = -1; int resp; u8 response[16]; // mmc_cid_t *mmc_cid = (mmc_cid_t *)response; @@ -675,9 +675,7 @@ int mmc_init(int verbose) while (retries--) { - udelay(100000); - udelay(100000); - udelay(100000); + udelay(10000); resp = mmc_cmd(MMC_APP_CMD, 0x00000000, MMC_CMD_AC | MMC_RSP_R1, 0, 0, 0, From 6e190bc68cf1517221d5d91c92afe6162e6ad222 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Thu, 18 Dec 2008 13:49:33 +0000 Subject: [PATCH 184/248] qi-gta02-rootdelay.patch There's not enough time between Glamo init (now after pcf50633 init) and the completion of machine init before we try to use the boot device in the case of GTA02 and SD boot. So we add rootdelay=1 to the SD card boot cases Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/gta02.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index d9c6b8a..08674f6 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -482,7 +482,7 @@ const struct board_api board_api_gta02 = { .partition_index = 1, .filesystem = FS_EXT2, .filepath = "boot/uImage-GTA02.bin", - .commandline_append = " root=/dev/mmcblk0p1 ", + .commandline_append = " root=/dev/mmcblk0p1 rootdelay=1 ", }, [1] = { .name = "SD Card EXT2 P2 Kernel", @@ -491,7 +491,7 @@ const struct board_api board_api_gta02 = { .partition_index = 2, .filesystem = FS_EXT2, .filepath = "boot/uImage-GTA02.bin", - .commandline_append = " root=/dev/mmcblk0p2 ", + .commandline_append = " root=/dev/mmcblk0p2 rootdelay=1 ", }, [2] = { .name = "SD Card EXT2 P3 Kernel", @@ -500,7 +500,7 @@ const struct board_api board_api_gta02 = { .partition_index = 3, .filesystem = FS_EXT2, .filepath = "boot/uImage-GTA02.bin", - .commandline_append = " root=/dev/mmcblk0p3 ", + .commandline_append = " root=/dev/mmcblk0p3 rootdelay=1 ", }, [3] = { .name = "NAND Kernel", From e08b5189906335b27c3d14d5b6ddda5b883fb108 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Thu, 18 Dec 2008 13:49:44 +0000 Subject: [PATCH 185/248] qi-gta02-correct-filter-polarity.patch Filter is enabled by b4 being 0 in each case, not 1 Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/gta02.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 08674f6..d0dafd0 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -45,8 +45,8 @@ const struct pcf50633_init pcf50633_init[] = { { PCF50633_REG_OOCMODE, 0x55 }, { PCF50633_REG_OOCCTL, 0x47 }, - { PCF50633_REG_SVMCTL, 0x18 }, /* 3.10V SYS vth, 62ms filter */ - { PCF50633_REG_BVMCTL, 0x12 }, /* 2.80V BAT vth, 62ms filter */ + { 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 */ From b98b8f5ea1ea1b4abd735af6376f9ad9f016949a Mon Sep 17 00:00:00 2001 From: Christopher Hall Date: Wed, 7 Jan 2009 10:07:46 +0000 Subject: [PATCH 186/248] Fix dmesg line filtering if uptime is too low On Ubuntu 8.04.1 there can be spaces inside the initial bracketed uptime number after a reboot. These spaces disappear once the uptime is large enough. Therefore, use sed to filter out these spaces so that the cut command that extracts SD card size will always work. Signed-off-by: Christopher Hall --- qiboot/6410-partition-sd.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/qiboot/6410-partition-sd.sh b/qiboot/6410-partition-sd.sh index cb1cac0..f6a564e 100755 --- a/qiboot/6410-partition-sd.sh +++ b/qiboot/6410-partition-sd.sh @@ -51,19 +51,23 @@ if [ ! -z "`grep $1 /proc/mounts`" ] ; then fi # set CUT_COLUMN for each OS +# set USE_SED=some editing command +# default: use cat as a no-op +USE_SED='cat' case "$(lsb_release --short --description)" in Ubuntu\ 7*) CUT_COLUMN=5 ;; Ubuntu\ 8.04*) CUT_COLUMN=5 + USE_SED='sed s/^\[[[:space:]]*/[/' ;; *) CUT_COLUMN=4 ;; esac -DMESG_LINE=$(dmesg | grep "$1" | grep "512-byte hardware" | tail -n 1) +DMESG_LINE=$(dmesg | ${USE_SED} | grep "$1" | grep "512-byte hardware" | tail -n 1) SECTORS=$(echo "${DMESG_LINE}" | cut -d' ' -f"${CUT_COLUMN}") if ! echo "${SECTORS}" | grep '^[[:digit:]]\+$' From 32f76a7afeeaa0fbd57a60f0248e795ccb0874cf Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Fri, 9 Jan 2009 04:32:46 +0000 Subject: [PATCH 187/248] phase2: simplify the bootloader_second_phase mega-loop This puts the loop body in a new function called try_this_kernel. As an added benefit, we can drop one level of indentation. This change is hard to read as a patch. It gets better if one just applies it and then looks at it with "git diff -w" or similar. Signed-off-by: Werner Almesberger --- qiboot/src/phase2.c | 534 +++++++++++++++++++++----------------------- 1 file changed, 258 insertions(+), 276 deletions(-) diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 162c434..7da39f6 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -96,292 +96,274 @@ int read_file(const char * filepath, u8 * destination, int size) return len; } -void bootloader_second_phase(void) +static void try_this_kernel(void) { void (*the_kernel)(int zero, int arch, uint params); - int kernel = 0; const struct board_variant * board_variant = (this_board->get_board_variant)(); unsigned int initramfs_len = 0; static char commandline_rootfs_append[512] = ""; + static void * last_block_init = NULL; + static int last_block_init_result = 0; int ret; - void * last_block_init = NULL; - int last_block_init_result = 0; + const char *p; + char * cmdline; + struct tag *params = (struct tag *)this_board->linux_tag_placement; + void * kernel_dram = (void *)this_board->linux_mem_start + 0x8000; + unsigned long crc; + image_header_t *hdr; + u32 kernel_size; + partition_offset_blocks = 0; + partition_length_blocks = 0; + + /* eat leading white space */ + for (p = this_board->commandline_board; *p == ' '; p++); + + puts("\nTrying kernel: "); + puts(this_kernel->name); + puts("\n"); + + indicate(UI_IND_MOUNT_PART); + + /* if this device needs initializing, try to init it */ + if (this_kernel->block_init) { + /* + * cache result to limit attempts for same + * block device to one time + */ + if (this_kernel->block_init != last_block_init) + last_block_init_result = (this_kernel->block_init)(); + + if (last_block_init_result) { + puts("block device init failed\n"); + if (this_kernel->block_init != last_block_init) + indicate(UI_IND_MOUNT_FAIL); + last_block_init = this_kernel[1].block_init; + return; + } + last_block_init = this_kernel->block_init; + } + + /* if there's a partition table implied, parse it, otherwise + * just use a fixed offset + */ + if (this_kernel->partition_index) { + unsigned char *p = kernel_dram; + + if ((int)this_kernel->block_read(kernel_dram, 0, 4) < 0) { + puts("Bad partition read\n"); + indicate(UI_IND_MOUNT_FAIL); + return; + } + + if ((p[0x1fe] != 0x55) || (p[0x1ff] != 0xaa)) { + puts("partition signature missing\n"); + indicate(UI_IND_MOUNT_FAIL); + return; + } + + p += 0x1be + 8 + (0x10 * (this_kernel->partition_index - 1)); + + partition_offset_blocks = (((u32)p[3]) << 24) | + (((u32)p[2]) << 16) | + (((u32)p[1]) << 8) | + p[0]; + partition_length_blocks = (((u32)p[7]) << 24) | + (((u32)p[6]) << 16) | + (((u32)p[5]) << 8) | + p[4]; + + puts(" Partition: "); + printdec(this_kernel->partition_index); + puts(" start +"); + printdec(partition_offset_blocks); + puts(" 512-byte blocks, size "); + printdec(partition_length_blocks / 2048); + puts(" MiB\n"); + + } else + partition_offset_blocks = + this_kernel->offset_blocks512_if_no_partition; + + /* does he want us to skip this? */ + + ret = read_file(this_board->noboot, kernel_dram, 512); + if (ret != -1) { + /* -2 (mount fail) should make us give up too */ + if (ret >= 0) { + puts(" (Skipping on finding "); + puts(this_board->noboot); + puts(")\n"); + indicate(UI_IND_SKIPPING); + } + return; + } + + /* is there a commandline append file? */ + + commandline_rootfs_append[0] = '\0'; + read_file(this_board->append, (u8 *)commandline_rootfs_append, 512); + + indicate(UI_IND_KERNEL_PULL); + + /* pull the kernel image */ + + if (read_file(this_kernel->filepath, kernel_dram, 4096) < 0) + return; + + hdr = (image_header_t *)kernel_dram; + + if (__be32_to_cpu(hdr->ih_magic) != IH_MAGIC) { + puts("bad magic "); + print32(hdr->ih_magic); + puts("\n"); + return; + } + + puts(" Found: \""); + puts((const char *)hdr->ih_name); + puts("\"\n Size: "); + printdec(__be32_to_cpu(hdr->ih_size) >> 10); + puts(" KiB\n"); + + kernel_size = ((__be32_to_cpu(hdr->ih_size) + + sizeof(image_header_t) + 2048) & ~(2048 - 1)); + + if (read_file(this_kernel->filepath, kernel_dram, kernel_size) < 0) { + indicate(UI_IND_KERNEL_PULL_FAIL); + return; + } + + indicate(UI_IND_KERNEL_PULL_OK); + + /* initramfs if needed */ + + if (this_kernel->initramfs_filepath) { + indicate(UI_IND_INITRAMFS_PULL); + initramfs_len = read_file(this_kernel->initramfs_filepath, + (u8 *)this_board->linux_mem_start + INITRD_OFFSET, + 16 * 1024 * 1024); + if (initramfs_len < 0) { + puts("initramfs load failed\n"); + indicate(UI_IND_INITRAMFS_PULL_FAIL); + return; + } + indicate(UI_IND_INITRAMFS_PULL_OK); + } + + /* + * It's good for now to know that our kernel is intact from + * the storage before we jump into it and maybe crash silently + * even though it costs us some time + */ + crc = crc32(0, kernel_dram + sizeof(image_header_t), + __be32_to_cpu(hdr->ih_size)); + if (crc != __be32_to_cpu(hdr->ih_dcrc)) { + puts("\nKernel CRC ERROR: read 0x"); + print32(crc); + puts(" vs hdr CRC 0x"); + print32(__be32_to_cpu(hdr->ih_dcrc)); + puts("\n"); + return; + } + + the_kernel = (void (*)(int, int, uint)) + (((char *)hdr) + sizeof(image_header_t)); + + /* first tag */ + params->hdr.tag = ATAG_CORE; + params->hdr.size = tag_size (tag_core); + params->u.core.flags = 0; + params->u.core.pagesize = 0; + params->u.core.rootdev = 0; + params = tag_next(params); + + /* revision tag */ + params->hdr.tag = ATAG_REVISION; + params->hdr.size = tag_size (tag_revision); + params->u.revision.rev = board_variant->machine_revision; + params = tag_next(params); + + /* memory tags */ + params->hdr.tag = ATAG_MEM; + params->hdr.size = tag_size (tag_mem32); + params->u.mem.start = this_board->linux_mem_start; + params->u.mem.size = this_board->linux_mem_size; + params = tag_next(params); + + if (this_kernel->initramfs_filepath) { + /* INITRD2 tag */ + params->hdr.tag = ATAG_INITRD2; + params->hdr.size = tag_size (tag_initrd); + params->u.initrd.start = this_board->linux_mem_start + + INITRD_OFFSET; + params->u.initrd.size = initramfs_len; + params = tag_next(params); + } + + /* kernel commandline */ + + cmdline = params->u.cmdline.cmdline; + cmdline += strlen(strcpy(cmdline, p)); + if (this_kernel->commandline_append) + cmdline += strlen(strcpy(cmdline, + this_kernel->commandline_append)); + if (commandline_rootfs_append[0]) + cmdline += strlen(strcpy(cmdline, + commandline_rootfs_append)); + + /* + * if he's still holding down the UI_ACTION_SKIPKERNEL key + * now we finished loading the kernel, take it to mean he wants + * to have the debugging options added to the commandline + */ + + if (this_board->commandline_board_debug && this_board->get_ui_keys) + if ((this_board->get_ui_keys)() & UI_ACTION_SKIPKERNEL) + cmdline += strlen(strcpy(cmdline, this_board-> + commandline_board_debug)); + + params->hdr.tag = ATAG_CMDLINE; + params->hdr.size = (sizeof (struct tag_header) + + strlen(params->u.cmdline.cmdline) + 1 + 4) >> 2; + + puts(" Cmdline: "); + puts(params->u.cmdline.cmdline); + puts("\n"); + + params = tag_next (params); + + /* needs to always be the last tag */ + params->hdr.tag = ATAG_NONE; + params->hdr.size = 0; + + /* give board implementation a chance to shut down + * anything it may have going on, leave GPIO set for Linux + */ + if (this_board->close) + (this_board->close)(); + + puts ("Starting --->\n\n"); + indicate(UI_IND_KERNEL_START); + + /* + * ooh that's it, we're gonna try boot this image! + * never mind the cache, Linux will take care of it + */ + the_kernel(0, this_board->linux_machine_id, + this_board->linux_tag_placement); + + /* we won't come back here no matter what */ +} + +void bootloader_second_phase(void) +{ /* we try the possible kernels for this board in order */ - this_kernel = &this_board->kernel_source[kernel++]; - - while (this_kernel->name) { - const char *p; - char * cmdline; - struct tag *params = (struct tag *)this_board->linux_tag_placement; - void * kernel_dram = (void *)this_board->linux_mem_start + 0x8000; - unsigned long crc; - image_header_t *hdr; - u32 kernel_size; - - partition_offset_blocks = 0; - partition_length_blocks = 0; - - /* eat leading white space */ - for (p = this_board->commandline_board; *p == ' '; p++); - - puts("\nTrying kernel: "); - puts(this_kernel->name); - puts("\n"); - - indicate(UI_IND_MOUNT_PART); - - /* if this device needs initializing, try to init it */ - if (this_kernel->block_init) { - /* - * cache result to limit attempts for same - * block device to one time - */ - if (this_kernel->block_init != last_block_init) - last_block_init_result = - (this_kernel->block_init)(); - - if (last_block_init_result) { - puts("block device init failed\n"); - if (this_kernel->block_init != last_block_init) - indicate(UI_IND_MOUNT_FAIL); - this_kernel = &this_board-> - kernel_source[kernel++]; - last_block_init = this_kernel->block_init; - continue; - } - last_block_init = this_kernel->block_init; - } - - /* if there's a partition table implied, parse it, otherwise - * just use a fixed offset - */ - if (this_kernel->partition_index) { - unsigned char *p = kernel_dram; - - if ((int)this_kernel->block_read(kernel_dram, 0, 4) - < 0) { - puts("Bad partition read\n"); - this_kernel = &this_board-> - kernel_source[kernel++]; - indicate(UI_IND_MOUNT_FAIL); - continue; - } - - if ((p[0x1fe] != 0x55) || (p[0x1ff] != 0xaa)) { - puts("partition signature missing\n"); - this_kernel = &this_board-> - kernel_source[kernel++]; - indicate(UI_IND_MOUNT_FAIL); - continue; - } - - p += 0x1be + 8 + (0x10 * - (this_kernel->partition_index - 1)); - - partition_offset_blocks = (((u32)p[3]) << 24) | - (((u32)p[2]) << 16) | - (((u32)p[1]) << 8) | - p[0]; - partition_length_blocks = (((u32)p[7]) << 24) | - (((u32)p[6]) << 16) | - (((u32)p[5]) << 8) | - p[4]; - - puts(" Partition: "); - printdec(this_kernel->partition_index); - puts(" start +"); - printdec(partition_offset_blocks); - puts(" 512-byte blocks, size "); - printdec(partition_length_blocks / 2048); - puts(" MiB\n"); - - } else - partition_offset_blocks = - this_kernel->offset_blocks512_if_no_partition; - - /* does he want us to skip this? */ - - ret = read_file(this_board->noboot, kernel_dram, 512); - if (ret != -1) { - /* -2 (mount fail) should make us give up too */ - if (ret >= 0) { - puts(" (Skipping on finding "); - puts(this_board->noboot); - puts(")\n"); - indicate(UI_IND_SKIPPING); - } - this_kernel = &this_board->kernel_source[kernel++]; - continue; - } - - /* is there a commandline append file? */ - - commandline_rootfs_append[0] = '\0'; - read_file(this_board->append, (u8 *)commandline_rootfs_append, - 512); - - indicate(UI_IND_KERNEL_PULL); - - /* pull the kernel image */ - - if (read_file(this_kernel->filepath, kernel_dram, 4096) < 0) { - this_kernel = &this_board->kernel_source[kernel++]; - continue; - } - - hdr = (image_header_t *)kernel_dram; - - if (__be32_to_cpu(hdr->ih_magic) != IH_MAGIC) { - puts("bad magic "); - print32(hdr->ih_magic); - puts("\n"); - this_kernel = &this_board->kernel_source[kernel++]; - continue; - } - - puts(" Found: \""); - puts((const char *)hdr->ih_name); - puts("\"\n Size: "); - printdec(__be32_to_cpu(hdr->ih_size) >> 10); - puts(" KiB\n"); - - kernel_size = ((__be32_to_cpu(hdr->ih_size) + - sizeof(image_header_t) + 2048) & ~(2048 - 1)); - - if (read_file(this_kernel->filepath, kernel_dram, - kernel_size) < 0) { - this_kernel = &this_board->kernel_source[kernel++]; - indicate(UI_IND_KERNEL_PULL_FAIL); - continue; - } - - indicate(UI_IND_KERNEL_PULL_OK); - - /* initramfs if needed */ - - if (this_kernel->initramfs_filepath) { - indicate(UI_IND_INITRAMFS_PULL); - initramfs_len = read_file(this_kernel->initramfs_filepath, - (u8 *)this_board->linux_mem_start + INITRD_OFFSET, - 16 * 1024 * 1024); - if (initramfs_len < 0) { - puts("initramfs load failed\n"); - this_kernel = &this_board->kernel_source[kernel++]; - indicate(UI_IND_INITRAMFS_PULL_FAIL); - continue; - } - indicate(UI_IND_INITRAMFS_PULL_OK); - } - - /* - * It's good for now to know that our kernel is intact from - * the storage before we jump into it and maybe crash silently - * even though it costs us some time - */ - crc = crc32(0, kernel_dram + sizeof(image_header_t), - __be32_to_cpu(hdr->ih_size)); - if (crc != __be32_to_cpu(hdr->ih_dcrc)) { - puts("\nKernel CRC ERROR: read 0x"); - print32(crc); - puts(" vs hdr CRC 0x"); - print32(__be32_to_cpu(hdr->ih_dcrc)); - puts("\n"); - this_kernel = &this_board->kernel_source[kernel++]; - continue; - } - - the_kernel = (void (*)(int, int, uint)) - (((char *)hdr) + sizeof(image_header_t)); - - /* first tag */ - params->hdr.tag = ATAG_CORE; - params->hdr.size = tag_size (tag_core); - params->u.core.flags = 0; - params->u.core.pagesize = 0; - params->u.core.rootdev = 0; - params = tag_next(params); - - /* revision tag */ - params->hdr.tag = ATAG_REVISION; - params->hdr.size = tag_size (tag_revision); - params->u.revision.rev = board_variant->machine_revision; - params = tag_next(params); - - /* memory tags */ - params->hdr.tag = ATAG_MEM; - params->hdr.size = tag_size (tag_mem32); - params->u.mem.start = this_board->linux_mem_start; - params->u.mem.size = this_board->linux_mem_size; - params = tag_next(params); - - if (this_kernel->initramfs_filepath) { - /* INITRD2 tag */ - params->hdr.tag = ATAG_INITRD2; - params->hdr.size = tag_size (tag_initrd); - params->u.initrd.start = this_board->linux_mem_start + - INITRD_OFFSET; - params->u.initrd.size = initramfs_len; - params = tag_next(params); - } - - /* kernel commandline */ - - cmdline = params->u.cmdline.cmdline; - cmdline += strlen(strcpy(cmdline, p)); - if (this_kernel->commandline_append) - cmdline += strlen(strcpy(cmdline, - this_kernel->commandline_append)); - if (commandline_rootfs_append[0]) - cmdline += strlen(strcpy(cmdline, - commandline_rootfs_append)); - - /* - * if he's still holding down the UI_ACTION_SKIPKERNEL key - * now we finished loading the kernel, take it to mean he wants - * to have the debugging options added to the commandline - */ - - if (this_board->commandline_board_debug && - this_board->get_ui_keys) - if ((this_board->get_ui_keys)() & UI_ACTION_SKIPKERNEL) - cmdline += strlen(strcpy(cmdline, this_board-> - commandline_board_debug)); - - params->hdr.tag = ATAG_CMDLINE; - params->hdr.size = (sizeof (struct tag_header) + - strlen(params->u.cmdline.cmdline) + 1 + 4) >> 2; - - puts(" Cmdline: "); - puts(params->u.cmdline.cmdline); - puts("\n"); - - params = tag_next (params); - - /* needs to always be the last tag */ - params->hdr.tag = ATAG_NONE; - params->hdr.size = 0; - - /* give board implementation a chance to shut down - * anything it may have going on, leave GPIO set for Linux - */ - if (this_board->close) - (this_board->close)(); - - puts ("Starting --->\n\n"); - indicate(UI_IND_KERNEL_START); - - /* - * ooh that's it, we're gonna try boot this image! - * never mind the cache, Linux will take care of it - */ - the_kernel(0, this_board->linux_machine_id, - this_board->linux_tag_placement); - - /* we won't come back here no matter what */ - } + for (this_kernel = this_board->kernel_source; this_kernel->name; + this_kernel++) + try_this_kernel(); /* none of the kernels worked out */ From 5c75acae122cf8bc27cb70f8e320f08f7bb6384e Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Fri, 9 Jan 2009 04:32:46 +0000 Subject: [PATCH 188/248] phase2: no space after function Putting a space between a function name and the parenthesis following it ain't the One True K&R Way. Signed-off-by: Werner Almesberger --- qiboot/src/phase2.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 7da39f6..4b38b39 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -87,7 +87,7 @@ int read_file(const char * filepath, u8 * destination, int size) puts(" 512-byte blocks\n"); if (this_kernel->block_read(destination, partition_offset_blocks, size >> 9) < 0) { - puts ("Bad kernel header\n"); + puts("Bad kernel header\n"); return -1; } break; @@ -273,7 +273,7 @@ static void try_this_kernel(void) /* first tag */ params->hdr.tag = ATAG_CORE; - params->hdr.size = tag_size (tag_core); + params->hdr.size = tag_size(tag_core); params->u.core.flags = 0; params->u.core.pagesize = 0; params->u.core.rootdev = 0; @@ -281,13 +281,13 @@ static void try_this_kernel(void) /* revision tag */ params->hdr.tag = ATAG_REVISION; - params->hdr.size = tag_size (tag_revision); + params->hdr.size = tag_size(tag_revision); params->u.revision.rev = board_variant->machine_revision; params = tag_next(params); /* memory tags */ params->hdr.tag = ATAG_MEM; - params->hdr.size = tag_size (tag_mem32); + params->hdr.size = tag_size(tag_mem32); params->u.mem.start = this_board->linux_mem_start; params->u.mem.size = this_board->linux_mem_size; params = tag_next(params); @@ -295,7 +295,7 @@ static void try_this_kernel(void) if (this_kernel->initramfs_filepath) { /* INITRD2 tag */ params->hdr.tag = ATAG_INITRD2; - params->hdr.size = tag_size (tag_initrd); + params->hdr.size = tag_size(tag_initrd); params->u.initrd.start = this_board->linux_mem_start + INITRD_OFFSET; params->u.initrd.size = initramfs_len; @@ -325,14 +325,14 @@ static void try_this_kernel(void) commandline_board_debug)); params->hdr.tag = ATAG_CMDLINE; - params->hdr.size = (sizeof (struct tag_header) + + params->hdr.size = (sizeof(struct tag_header) + strlen(params->u.cmdline.cmdline) + 1 + 4) >> 2; puts(" Cmdline: "); puts(params->u.cmdline.cmdline); puts("\n"); - params = tag_next (params); + params = tag_next(params); /* needs to always be the last tag */ params->hdr.tag = ATAG_NONE; @@ -344,7 +344,7 @@ static void try_this_kernel(void) if (this_board->close) (this_board->close)(); - puts ("Starting --->\n\n"); + puts("Starting --->\n\n"); indicate(UI_IND_KERNEL_START); /* From 545f0662ef7ddca1b108010364ee0633830a7719 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Fri, 9 Jan 2009 04:32:47 +0000 Subject: [PATCH 189/248] phase2: separate parameter setup from try_this_kernel It's still huge, but less painful to read. Signed-off-by: Werner Almesberger --- qiboot/src/phase2.c | 155 +++++++++++++++++++++++--------------------- 1 file changed, 81 insertions(+), 74 deletions(-) diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 4b38b39..e416be0 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -96,19 +96,94 @@ int read_file(const char * filepath, u8 * destination, int size) return len; } +static void do_params(unsigned initramfs_len, + const char *commandline_rootfs_append) +{ + const struct board_variant * board_variant = + (this_board->get_board_variant)(); + const char *p; + char * cmdline; + struct tag *params = (struct tag *)this_board->linux_tag_placement; + + /* eat leading white space */ + for (p = this_board->commandline_board; *p == ' '; p++); + + /* first tag */ + params->hdr.tag = ATAG_CORE; + params->hdr.size = tag_size(tag_core); + params->u.core.flags = 0; + params->u.core.pagesize = 0; + params->u.core.rootdev = 0; + params = tag_next(params); + + /* revision tag */ + params->hdr.tag = ATAG_REVISION; + params->hdr.size = tag_size(tag_revision); + params->u.revision.rev = board_variant->machine_revision; + params = tag_next(params); + + /* memory tags */ + params->hdr.tag = ATAG_MEM; + params->hdr.size = tag_size(tag_mem32); + params->u.mem.start = this_board->linux_mem_start; + params->u.mem.size = this_board->linux_mem_size; + params = tag_next(params); + + if (this_kernel->initramfs_filepath) { + /* INITRD2 tag */ + params->hdr.tag = ATAG_INITRD2; + params->hdr.size = tag_size(tag_initrd); + params->u.initrd.start = this_board->linux_mem_start + + INITRD_OFFSET; + params->u.initrd.size = initramfs_len; + params = tag_next(params); + } + + /* kernel commandline */ + + cmdline = params->u.cmdline.cmdline; + cmdline += strlen(strcpy(cmdline, p)); + if (this_kernel->commandline_append) + cmdline += strlen(strcpy(cmdline, + this_kernel->commandline_append)); + if (commandline_rootfs_append[0]) + cmdline += strlen(strcpy(cmdline, + commandline_rootfs_append)); + + /* + * if he's still holding down the UI_ACTION_SKIPKERNEL key + * now we finished loading the kernel, take it to mean he wants + * to have the debugging options added to the commandline + */ + + if (this_board->commandline_board_debug && this_board->get_ui_keys) + if ((this_board->get_ui_keys)() & UI_ACTION_SKIPKERNEL) + cmdline += strlen(strcpy(cmdline, this_board-> + commandline_board_debug)); + + params->hdr.tag = ATAG_CMDLINE; + params->hdr.size = (sizeof(struct tag_header) + + strlen(params->u.cmdline.cmdline) + 1 + 4) >> 2; + + puts(" Cmdline: "); + puts(params->u.cmdline.cmdline); + puts("\n"); + + params = tag_next(params); + + /* needs to always be the last tag */ + params->hdr.tag = ATAG_NONE; + params->hdr.size = 0; +} + static void try_this_kernel(void) { void (*the_kernel)(int zero, int arch, uint params); - const struct board_variant * board_variant = - (this_board->get_board_variant)(); unsigned int initramfs_len = 0; static char commandline_rootfs_append[512] = ""; static void * last_block_init = NULL; static int last_block_init_result = 0; int ret; - const char *p; - char * cmdline; - struct tag *params = (struct tag *)this_board->linux_tag_placement; void * kernel_dram = (void *)this_board->linux_mem_start + 0x8000; unsigned long crc; image_header_t *hdr; @@ -117,9 +192,6 @@ static void try_this_kernel(void) partition_offset_blocks = 0; partition_length_blocks = 0; - /* eat leading white space */ - for (p = this_board->commandline_board; *p == ' '; p++); - puts("\nTrying kernel: "); puts(this_kernel->name); puts("\n"); @@ -271,72 +343,7 @@ static void try_this_kernel(void) the_kernel = (void (*)(int, int, uint)) (((char *)hdr) + sizeof(image_header_t)); - /* first tag */ - params->hdr.tag = ATAG_CORE; - params->hdr.size = tag_size(tag_core); - params->u.core.flags = 0; - params->u.core.pagesize = 0; - params->u.core.rootdev = 0; - params = tag_next(params); - - /* revision tag */ - params->hdr.tag = ATAG_REVISION; - params->hdr.size = tag_size(tag_revision); - params->u.revision.rev = board_variant->machine_revision; - params = tag_next(params); - - /* memory tags */ - params->hdr.tag = ATAG_MEM; - params->hdr.size = tag_size(tag_mem32); - params->u.mem.start = this_board->linux_mem_start; - params->u.mem.size = this_board->linux_mem_size; - params = tag_next(params); - - if (this_kernel->initramfs_filepath) { - /* INITRD2 tag */ - params->hdr.tag = ATAG_INITRD2; - params->hdr.size = tag_size(tag_initrd); - params->u.initrd.start = this_board->linux_mem_start + - INITRD_OFFSET; - params->u.initrd.size = initramfs_len; - params = tag_next(params); - } - - /* kernel commandline */ - - cmdline = params->u.cmdline.cmdline; - cmdline += strlen(strcpy(cmdline, p)); - if (this_kernel->commandline_append) - cmdline += strlen(strcpy(cmdline, - this_kernel->commandline_append)); - if (commandline_rootfs_append[0]) - cmdline += strlen(strcpy(cmdline, - commandline_rootfs_append)); - - /* - * if he's still holding down the UI_ACTION_SKIPKERNEL key - * now we finished loading the kernel, take it to mean he wants - * to have the debugging options added to the commandline - */ - - if (this_board->commandline_board_debug && this_board->get_ui_keys) - if ((this_board->get_ui_keys)() & UI_ACTION_SKIPKERNEL) - cmdline += strlen(strcpy(cmdline, this_board-> - commandline_board_debug)); - - params->hdr.tag = ATAG_CMDLINE; - params->hdr.size = (sizeof(struct tag_header) + - strlen(params->u.cmdline.cmdline) + 1 + 4) >> 2; - - puts(" Cmdline: "); - puts(params->u.cmdline.cmdline); - puts("\n"); - - params = tag_next(params); - - /* needs to always be the last tag */ - params->hdr.tag = ATAG_NONE; - params->hdr.size = 0; + do_params(initramfs_len, commandline_rootfs_append); /* give board implementation a chance to shut down * anything it may have going on, leave GPIO set for Linux From 668e3f5ed96d2c04b63d07f464428e79c07c1aef Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Fri, 9 Jan 2009 04:32:48 +0000 Subject: [PATCH 190/248] phase2: separate partition scan from try_this_kernel As an added benefit, we can drop one level of indentation. Signed-off-by: Werner Almesberger --- qiboot/src/phase2.c | 89 +++++++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index e416be0..3ee349b 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -96,6 +96,53 @@ int read_file(const char * filepath, u8 * destination, int size) return len; } +static int do_partitions(void *kernel_dram) +{ + unsigned char *p = kernel_dram; + + /* if there's a partition table implied, parse it, otherwise + * just use a fixed offset + */ + if (!this_kernel->partition_index) { + partition_offset_blocks = + this_kernel->offset_blocks512_if_no_partition; + return 1; + } + + if ((int)this_kernel->block_read(kernel_dram, 0, 4) < 0) { + puts("Bad partition read\n"); + indicate(UI_IND_MOUNT_FAIL); + return 0; + } + + if ((p[0x1fe] != 0x55) || (p[0x1ff] != 0xaa)) { + puts("partition signature missing\n"); + indicate(UI_IND_MOUNT_FAIL); + return 0; + } + + p += 0x1be + 8 + (0x10 * (this_kernel->partition_index - 1)); + + partition_offset_blocks = (((u32)p[3]) << 24) | + (((u32)p[2]) << 16) | + (((u32)p[1]) << 8) | + p[0]; + partition_length_blocks = (((u32)p[7]) << 24) | + (((u32)p[6]) << 16) | + (((u32)p[5]) << 8) | + p[4]; + + puts(" Partition: "); + printdec(this_kernel->partition_index); + puts(" start +"); + printdec(partition_offset_blocks); + puts(" 512-byte blocks, size "); + printdec(partition_length_blocks / 2048); + puts(" MiB\n"); + + return 1; +} + static void do_params(unsigned initramfs_len, const char *commandline_rootfs_append) { @@ -217,46 +264,8 @@ static void try_this_kernel(void) last_block_init = this_kernel->block_init; } - /* if there's a partition table implied, parse it, otherwise - * just use a fixed offset - */ - if (this_kernel->partition_index) { - unsigned char *p = kernel_dram; - - if ((int)this_kernel->block_read(kernel_dram, 0, 4) < 0) { - puts("Bad partition read\n"); - indicate(UI_IND_MOUNT_FAIL); - return; - } - - if ((p[0x1fe] != 0x55) || (p[0x1ff] != 0xaa)) { - puts("partition signature missing\n"); - indicate(UI_IND_MOUNT_FAIL); - return; - } - - p += 0x1be + 8 + (0x10 * (this_kernel->partition_index - 1)); - - partition_offset_blocks = (((u32)p[3]) << 24) | - (((u32)p[2]) << 16) | - (((u32)p[1]) << 8) | - p[0]; - partition_length_blocks = (((u32)p[7]) << 24) | - (((u32)p[6]) << 16) | - (((u32)p[5]) << 8) | - p[4]; - - puts(" Partition: "); - printdec(this_kernel->partition_index); - puts(" start +"); - printdec(partition_offset_blocks); - puts(" 512-byte blocks, size "); - printdec(partition_length_blocks / 2048); - puts(" MiB\n"); - - } else - partition_offset_blocks = - this_kernel->offset_blocks512_if_no_partition; + if (!do_partitions(kernel_dram)) + return; /* does he want us to skip this? */ From d3ee803b58e0de3f89cd3ac96c694e5208aad2ac Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Fri, 9 Jan 2009 04:32:49 +0000 Subject: [PATCH 191/248] phase2: separate CRC from try_this_kernel As an added benefit, we can drop one level of indentation. Signed-off-by: Werner Almesberger --- qiboot/src/phase2.c | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 3ee349b..4b639c9 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -223,6 +223,29 @@ static void do_params(unsigned initramfs_len, params->hdr.size = 0; } +static int do_crc(const image_header_t *hdr, const void *kernel_dram) +{ + unsigned long crc; + + /* + * It's good for now to know that our kernel is intact from + * the storage before we jump into it and maybe crash silently + * even though it costs us some time + */ + crc = crc32(0, kernel_dram + sizeof(image_header_t), + __be32_to_cpu(hdr->ih_size)); + if (crc == __be32_to_cpu(hdr->ih_dcrc)) + return 1; + + puts("\nKernel CRC ERROR: read 0x"); + print32(crc); + puts(" vs hdr CRC 0x"); + print32(__be32_to_cpu(hdr->ih_dcrc)); + puts("\n"); + + return 0; +} + static void try_this_kernel(void) { void (*the_kernel)(int zero, int arch, uint params); @@ -232,7 +255,6 @@ static void try_this_kernel(void) static int last_block_init_result = 0; int ret; void * kernel_dram = (void *)this_board->linux_mem_start + 0x8000; - unsigned long crc; image_header_t *hdr; u32 kernel_size; @@ -333,21 +355,8 @@ static void try_this_kernel(void) indicate(UI_IND_INITRAMFS_PULL_OK); } - /* - * It's good for now to know that our kernel is intact from - * the storage before we jump into it and maybe crash silently - * even though it costs us some time - */ - crc = crc32(0, kernel_dram + sizeof(image_header_t), - __be32_to_cpu(hdr->ih_size)); - if (crc != __be32_to_cpu(hdr->ih_dcrc)) { - puts("\nKernel CRC ERROR: read 0x"); - print32(crc); - puts(" vs hdr CRC 0x"); - print32(__be32_to_cpu(hdr->ih_dcrc)); - puts("\n"); + if (!do_crc(hdr, kernel_dram)) return; - } the_kernel = (void (*)(int, int, uint)) (((char *)hdr) + sizeof(image_header_t)); From f5798e63594d5999edcd2bf5a1567b6b1d425cce Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Fri, 9 Jan 2009 04:32:49 +0000 Subject: [PATCH 192/248] phase2: separate block init from try_this_kernel As an added benefit, we can drop one level of indentation. Signed-off-by: Werner Almesberger --- qiboot/src/phase2.c | 50 +++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 4b639c9..34ed4d8 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -96,6 +96,34 @@ int read_file(const char * filepath, u8 * destination, int size) return len; } +static int do_block_init(void) +{ + static void * last_block_init = NULL; + static int last_block_init_result = 0; + + /* if this device needs initializing, try to init it */ + if (!this_kernel->block_init) + return 1; + + /* + * cache result to limit attempts for same + * block device to one time + */ + if (this_kernel->block_init != last_block_init) + last_block_init_result = (this_kernel->block_init)(); + + if (last_block_init_result) { + puts("block device init failed\n"); + if (this_kernel->block_init != last_block_init) + indicate(UI_IND_MOUNT_FAIL); + last_block_init = this_kernel[1].block_init; + return 0; + } + last_block_init = this_kernel->block_init; + + return 1; +} + static int do_partitions(void *kernel_dram) { unsigned char *p = kernel_dram; @@ -251,8 +279,6 @@ static void try_this_kernel(void) void (*the_kernel)(int zero, int arch, uint params); unsigned int initramfs_len = 0; static char commandline_rootfs_append[512] = ""; - static void * last_block_init = NULL; - static int last_block_init_result = 0; int ret; void * kernel_dram = (void *)this_board->linux_mem_start + 0x8000; image_header_t *hdr; @@ -267,24 +293,8 @@ static void try_this_kernel(void) indicate(UI_IND_MOUNT_PART); - /* if this device needs initializing, try to init it */ - if (this_kernel->block_init) { - /* - * cache result to limit attempts for same - * block device to one time - */ - if (this_kernel->block_init != last_block_init) - last_block_init_result = (this_kernel->block_init)(); - - if (last_block_init_result) { - puts("block device init failed\n"); - if (this_kernel->block_init != last_block_init) - indicate(UI_IND_MOUNT_FAIL); - last_block_init = this_kernel[1].block_init; - return; - } - last_block_init = this_kernel->block_init; - } + if (!do_block_init()) + return; if (!do_partitions(kernel_dram)) return; From 9411e40603f995f28321103c6a38a40c858812a2 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Fri, 9 Jan 2009 04:32:50 +0000 Subject: [PATCH 193/248] phase2: block init buggy x Is it really correct to set last_block_init to the next entry ? It would seem that the current (i.e., bogus) values are then just used without further ado. Untested. Not-Yet-Signed-off-by: Werner Almesberger --- qiboot/src/phase2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 34ed4d8..6628bf0 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -116,7 +116,7 @@ static int do_block_init(void) puts("block device init failed\n"); if (this_kernel->block_init != last_block_init) indicate(UI_IND_MOUNT_FAIL); - last_block_init = this_kernel[1].block_init; + last_block_init = NULL; return 0; } last_block_init = this_kernel->block_init; From 73b8441e3bb84f13de9dde5a68e208845a245232 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Fri, 9 Jan 2009 04:32:51 +0000 Subject: [PATCH 194/248] phase2: use "static" wherever possible Makes it easier to determine what can be safely changed. Signed-off-by: Werner Almesberger --- qiboot/src/phase2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 6628bf0..9e3626e 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -35,7 +35,7 @@ unsigned long partition_length_blocks = 0; struct kernel_source const * this_kernel = 0; -const int INITRD_OFFSET = (8 * 1024 * 1024); +static const int INITRD_OFFSET = (8 * 1024 * 1024); int raise(int n) @@ -43,13 +43,13 @@ int raise(int n) return 0; } -void indicate(enum ui_indication ui_indication) +static void indicate(enum ui_indication ui_indication) { if (this_board->set_ui_indication) (this_board->set_ui_indication)(ui_indication); } -int read_file(const char * filepath, u8 * destination, int size) +static int read_file(const char * filepath, u8 * destination, int size) { int len = size; int ret; From 31448578d1259031c7c9cf9d5d455964fc8665eb Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Fri, 9 Jan 2009 04:32:51 +0000 Subject: [PATCH 195/248] phase2: use a typedefed type for the kernel function This makes things a little easier to read, particularly when we return this pointer from a function, which we'll do in the next patch. Signed-off-by: Werner Almesberger --- qiboot/src/phase2.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 9e3626e..20d2ce9 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -30,6 +30,9 @@ #include #include + +typedef void (*the_kernel_fn)(int zero, int arch, uint params); + unsigned long partition_offset_blocks = 0; unsigned long partition_length_blocks = 0; @@ -276,7 +279,7 @@ static int do_crc(const image_header_t *hdr, const void *kernel_dram) static void try_this_kernel(void) { - void (*the_kernel)(int zero, int arch, uint params); + the_kernel_fn the_kernel; unsigned int initramfs_len = 0; static char commandline_rootfs_append[512] = ""; int ret; @@ -368,8 +371,7 @@ static void try_this_kernel(void) if (!do_crc(hdr, kernel_dram)) return; - the_kernel = (void (*)(int, int, uint)) - (((char *)hdr) + sizeof(image_header_t)); + the_kernel = (the_kernel_fn) (((char *)hdr) + sizeof(image_header_t)); do_params(initramfs_len, commandline_rootfs_append); From 188fff8fc3030a179bc5ebabf1975de88b4709d5 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Fri, 9 Jan 2009 04:32:52 +0000 Subject: [PATCH 196/248] zimage: separate uImage loader from try_this_kernel Finally all the restructuring pays off: we can cleanly separate the uImage loader from all the rest, which will make it easy to add loaders for other kernel image formats. Signed-off-by: Werner Almesberger --- qiboot/src/phase2.c | 68 +++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 20d2ce9..cf31e8b 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -277,6 +277,42 @@ static int do_crc(const image_header_t *hdr, const void *kernel_dram) return 0; } +static the_kernel_fn load_uimage(void *kernel_dram) +{ + image_header_t *hdr; + u32 kernel_size; + + hdr = (image_header_t *)kernel_dram; + + if (__be32_to_cpu(hdr->ih_magic) != IH_MAGIC) { + puts("bad magic "); + print32(hdr->ih_magic); + puts("\n"); + return NULL; + } + + puts(" Found: \""); + puts((const char *)hdr->ih_name); + puts("\"\n Size: "); + printdec(__be32_to_cpu(hdr->ih_size) >> 10); + puts(" KiB\n"); + + kernel_size = ((__be32_to_cpu(hdr->ih_size) + + sizeof(image_header_t) + 2048) & ~(2048 - 1)); + + if (read_file(this_kernel->filepath, kernel_dram, kernel_size) < 0) { + indicate(UI_IND_KERNEL_PULL_FAIL); + return NULL; + } + + indicate(UI_IND_KERNEL_PULL_OK); + + if (!do_crc(hdr, kernel_dram)) + return NULL; + + return (the_kernel_fn) (((char *)hdr) + sizeof(image_header_t)); +} + static void try_this_kernel(void) { the_kernel_fn the_kernel; @@ -284,8 +320,6 @@ static void try_this_kernel(void) static char commandline_rootfs_append[512] = ""; int ret; void * kernel_dram = (void *)this_board->linux_mem_start + 0x8000; - image_header_t *hdr; - u32 kernel_size; partition_offset_blocks = 0; partition_length_blocks = 0; @@ -328,30 +362,9 @@ static void try_this_kernel(void) if (read_file(this_kernel->filepath, kernel_dram, 4096) < 0) return; - hdr = (image_header_t *)kernel_dram; - - if (__be32_to_cpu(hdr->ih_magic) != IH_MAGIC) { - puts("bad magic "); - print32(hdr->ih_magic); - puts("\n"); + the_kernel = load_uimage(kernel_dram); + if (!the_kernel) return; - } - - puts(" Found: \""); - puts((const char *)hdr->ih_name); - puts("\"\n Size: "); - printdec(__be32_to_cpu(hdr->ih_size) >> 10); - puts(" KiB\n"); - - kernel_size = ((__be32_to_cpu(hdr->ih_size) + - sizeof(image_header_t) + 2048) & ~(2048 - 1)); - - if (read_file(this_kernel->filepath, kernel_dram, kernel_size) < 0) { - indicate(UI_IND_KERNEL_PULL_FAIL); - return; - } - - indicate(UI_IND_KERNEL_PULL_OK); /* initramfs if needed */ @@ -368,11 +381,6 @@ static void try_this_kernel(void) indicate(UI_IND_INITRAMFS_PULL_OK); } - if (!do_crc(hdr, kernel_dram)) - return; - - the_kernel = (the_kernel_fn) (((char *)hdr) + sizeof(image_header_t)); - do_params(initramfs_len, commandline_rootfs_append); /* give board implementation a chance to shut down From 9ec680a757d481ff7a4120bc8a0da6d9381b9d54 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Fri, 9 Jan 2009 04:32:53 +0000 Subject: [PATCH 197/248] zimage: add support for the zImage format If the kernel we found isn't an uImage, try to use it as a zImage. Signed-off-by: Werner Almesberger --- qiboot/src/phase2.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index cf31e8b..ab9802d 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -313,6 +313,39 @@ static the_kernel_fn load_uimage(void *kernel_dram) return (the_kernel_fn) (((char *)hdr) + sizeof(image_header_t)); } +static the_kernel_fn load_zimage(void *kernel_dram) +{ + u32 magic = *(u32 *) (kernel_dram + 0x24); + u32 size = *(u32 *) (kernel_dram + 0x2c); + int got; + + if (magic != 0x016f2818) { + puts("bad magic "); + print32(magic); + puts("\n"); + return NULL; + } + + puts(" Size: "); + printdec(size >> 10); + puts(" KiB\n"); + + got = read_file(this_kernel->filepath, kernel_dram, size); + if (got < 0) { + indicate(UI_IND_KERNEL_PULL_FAIL); + return NULL; + } + + if (got != size) { + puts("short kernel\n"); + return NULL; + } + + indicate(UI_IND_KERNEL_PULL_OK); + + return (the_kernel_fn) kernel_dram; +} + static void try_this_kernel(void) { the_kernel_fn the_kernel; @@ -363,6 +396,8 @@ static void try_this_kernel(void) return; the_kernel = load_uimage(kernel_dram); + if (!the_kernel) + the_kernel = load_zimage(kernel_dram); if (!the_kernel) return; From f055e1e9a1f60b785a4c7cffd42a4cbbe513a8c8 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 19 Jan 2009 01:37:08 +0000 Subject: [PATCH 198/248] qi-change-partitioning.patch Signed-off-by: Andy Green --- qiboot/6410-partition-sd.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qiboot/6410-partition-sd.sh b/qiboot/6410-partition-sd.sh index f6a564e..20ad9d0 100755 --- a/qiboot/6410-partition-sd.sh +++ b/qiboot/6410-partition-sd.sh @@ -8,7 +8,7 @@ # VFAT takes up remaining space here # then... # -EXT3_ROOTFS_SECTORS=$(( 64 * 1024 * 2 )) +EXT3_ROOTFS_SECTORS=$(( 256 * 1024 * 2 )) EXT3_BACKUP_FS_SECTORS=$(( 8 * 1024 * 2 )) QI_ALLOCATION=$(( 256 * 2 )) # @@ -103,7 +103,7 @@ if [ -z "$4" ] ; then echo "p" >>$FDISK_SCRIPT echo "1" >>$FDISK_SCRIPT # first partition == 1 - echo "1" >>$FDISK_SCRIPT + echo "64" >>$FDISK_SCRIPT echo "+$FATMB"M >>$FDISK_SCRIPT # add the normal EXT3 rootfs From 6940235ae655dcbf816b3974672f7f55efb0ad12 Mon Sep 17 00:00:00 2001 From: Paul Fertser Date: Mon, 19 Jan 2009 01:37:09 +0000 Subject: [PATCH 199/248] Add a dedicated function to query debug action to board_api On the devices where we have only 2 physical buttons, one of those buttons (i.e. POWER) is connected directly to PMU. The other button (AUX) is connected directly to S3C pin and we can get its state immediately, it is currently used to skip a boot possibility. To allow user to debug boot problems we can use the POWER button, but we cannot poll for it too many times as it slows down the boot considerably, therefore a dedicated function is needed. --- qiboot/include/qi.h | 1 + qiboot/src/phase2.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index 2592cd4..be25626 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -104,6 +104,7 @@ struct board_api { 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]; diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index ab9802d..b733444 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -234,8 +234,8 @@ static void do_params(unsigned initramfs_len, * to have the debugging options added to the commandline */ - if (this_board->commandline_board_debug && this_board->get_ui_keys) - if ((this_board->get_ui_keys)() & UI_ACTION_SKIPKERNEL) + if (this_board->commandline_board_debug && this_board->get_ui_debug) + if ((this_board->get_ui_debug)()) cmdline += strlen(strcpy(cmdline, this_board-> commandline_board_debug)); From 7c8892dfa1a2fd7a78f1742572c4ce2b92a25711 Mon Sep 17 00:00:00 2001 From: Paul Fertser Date: Mon, 19 Jan 2009 01:37:09 +0000 Subject: [PATCH 200/248] GTA02: use POWER button to append debug parameters to the kernel command line --- qiboot/src/cpu/s3c2442/gta02.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index d0dafd0..ac18338 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -378,31 +378,35 @@ static void close_gta02(void) } +/* 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; + u8 ret = 0; static u8 old_keys = 0; /* previous state for debounce */ - static u8 old_ret = 0; /* previous debounced output for edge detect */ + static u8 older_keys = 0; /* previous debounced output for edge detect */ - /* GPF6 is AUX on GTA02, map to UI_ACTION_ADD_DEBUG, down = 1 */ + /* GPF6 is AUX on GTA02, map to UI_ACTION_SKIPKERNEL, down = 1 */ keys = !!(rGPFDAT & (1 << 6)); - if (keys == old_keys) - ret = keys; - else - ret = old_keys; - /* edge action */ - if ((ret & 1) && !(old_ret & 1)) + if ((old_keys & 1) && !(older_keys & 1)) ret |= UI_ACTION_SKIPKERNEL; + older_keys = old_keys; old_keys = keys; - old_ret = ret; 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) { @@ -456,6 +460,7 @@ const struct board_api board_api_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 = "mtdparts=physmap-flash:-(nor);" \ "neo1973-nand:" \ From bdaef4fd508bb4a9f98c9a456e2788657614902b Mon Sep 17 00:00:00 2001 From: Paul Fertser Date: Mon, 19 Jan 2009 01:37:09 +0000 Subject: [PATCH 201/248] GTA01: use POWER button to append debug parameters to the kernel command line This patch is based on the one tested on GTA02, it compiles but i could not verify if it works. --- qiboot/src/cpu/s3c2410/gta01.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/qiboot/src/cpu/s3c2410/gta01.c b/qiboot/src/cpu/s3c2410/gta01.c index db7d653..c8ff25e 100644 --- a/qiboot/src/cpu/s3c2410/gta01.c +++ b/qiboot/src/cpu/s3c2410/gta01.c @@ -209,31 +209,34 @@ static void close_gta01(void) (bb_s3c24xx.close)(); } -static u8 get_ui_keys_gta02(void) +/* 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; + u8 ret = 0; static u8 old_keys = 0; /* previous state for debounce */ - static u8 old_ret = 0; /* previous debounced output for edge detect */ + static u8 older_keys = 0; /* previous debounced output for edge detect */ - /* GPF6 is AUX on GTA01, map to UI_ACTION_ADD_DEBUG, down = 1 */ + /* GPF6 is AUX on GTA01, map to UI_ACTION_SKIPKERNEL, down = 0 */ keys = ! (rGPFDAT & (1 << 6)); - if (keys == old_keys) - ret = keys; - else - ret = old_keys; - /* edge action */ - if ((ret & 1) && !(old_ret & 1)) + if ((old_keys & 1) && !(older_keys & 1)) ret |= UI_ACTION_SKIPKERNEL; + older_keys = old_keys; old_keys = keys; - old_ret = ret; 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 @@ -250,7 +253,8 @@ const struct board_api board_api_gta01 = { .port_init = port_init_gta01, .putc = putc_gta01, .close = close_gta01, - .get_ui_keys = get_ui_keys_gta02, + .get_ui_keys = get_ui_keys_gta01, + .get_ui_debug = get_ui_debug_gta01, .commandline_board = "mtdparts=" \ "neo1973-nand:" \ From 5ffd09774dfd1093e82196ee6355c59acdc2e7c5 Mon Sep 17 00:00:00 2001 From: Paul Fertser Date: Fri, 23 Jan 2009 11:26:44 +0000 Subject: [PATCH 202/248] Describe interactive UI in README --- qiboot/README | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/qiboot/README b/qiboot/README index 198507c..0ab7a3f 100644 --- a/qiboot/README +++ b/qiboot/README @@ -57,6 +57,9 @@ through these device-specific storage devices in order and tries to boot the first viable kernel it finds, usually /boot/.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-, eg, /boot/noboot-GTA02. This differs from renaming or deleting the kernel image because updating the kernel package would give you a @@ -88,6 +91,38 @@ 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 =========================================== From fbc7e8b244779d19386d616335398c5906b86294 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Sat, 31 Jan 2009 17:23:29 +0000 Subject: [PATCH 203/248] qi-strip-trailing-newlines-in-append-file.patch Signed-off-by: Andy Green --- qiboot/src/phase2.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index b733444..dd15055 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -181,6 +181,7 @@ static void do_params(unsigned initramfs_len, (this_board->get_board_variant)(); const char *p; char * cmdline; + char * p1; struct tag *params = (struct tag *)this_board->linux_tag_placement; /* eat leading white space */ @@ -228,6 +229,12 @@ static void do_params(unsigned initramfs_len, cmdline += strlen(strcpy(cmdline, commandline_rootfs_append)); + /* deal with any trailing newlines that hitched a ride */ + + p1 = cmdline + strlen(cmdline) - 1; + while (*p1 == '\n') + *p1-- = '\0'; + /* * if he's still holding down the UI_ACTION_SKIPKERNEL key * now we finished loading the kernel, take it to mean he wants From 4a8cabd5a9689fa12a6b0d58b17c78ea445cead9 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Sat, 31 Jan 2009 17:23:30 +0000 Subject: [PATCH 204/248] None The PMU initializes all GPIOs to inputs in NoPower, including GPIO2, which drives GSM_ON and has an external pull-up. Furthermore, we may have entered PMU.Standby with the modem up. Unlike u-boot, qi didn't initialize the GPIOs. With this patch is does. Reported-by: Paul Ferster Signed-off-by: Werner Almesberger --- qiboot/src/cpu/s3c2442/gta02.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index ac18338..5ad5316 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -45,6 +45,9 @@ const struct pcf50633_init pcf50633_init[] = { { 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 */ From 7132195b320b4d5cd2713eb840045f8e2e525554 Mon Sep 17 00:00:00 2001 From: Paul Fertser Date: Sat, 31 Jan 2009 17:23:30 +0000 Subject: [PATCH 205/248] Fix handling of 60 bytes long symlinks On ext2 the symlink can be stored in inode itself if it's not larger than 60 bytes. If the symlink path is exactly 60 bytes, then one more byte is needed to store terminating NULL, therefore the path is placed in a separate block. --- qiboot/src/fs/ext2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiboot/src/fs/ext2.c b/qiboot/src/fs/ext2.c index 21165a3..2709806 100644 --- a/qiboot/src/fs/ext2.c +++ b/qiboot/src/fs/ext2.c @@ -653,7 +653,7 @@ static char *ext2fs_read_symlink(ext2fs_node_t node) { /* If the filesize of the symlink is bigger than 60 the symlink is stored in a separate block, otherwise it is stored in the inode. */ - if (__le32_to_cpu(diro->inode.size) <= 60) { + if (__le32_to_cpu(diro->inode.size) < 60) { strncpy(symlink, diro->inode.b.symlink, __le32_to_cpu(diro->inode.size)); } else { From f3c740f11ce7a27f04ecddbd6dd6edf9d26e9351 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Sun, 1 Feb 2009 19:28:18 +0000 Subject: [PATCH 206/248] qi-reduce-glamo-mmc-wait-delay.patch 3000 retries is a very long time for an SD card to wake up, far longer than should be necessary. This patch reduces it to 1000. Signed-off-by: Andy Green --- qiboot/src/drivers/glamo-mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiboot/src/drivers/glamo-mmc.c b/qiboot/src/drivers/glamo-mmc.c index 8f649d1..c3b92c3 100644 --- a/qiboot/src/drivers/glamo-mmc.c +++ b/qiboot/src/drivers/glamo-mmc.c @@ -609,7 +609,7 @@ static void print_sd_cid(const struct sd_cid *cid) int mmc_init(int verbose) { - int retries = 3000, rc = -1; + int retries = 1000, rc = -1; int resp; u8 response[16]; // mmc_cid_t *mmc_cid = (mmc_cid_t *)response; From a1af68434bde6d65fe30a3befda89a1fb56e3e01 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Sun, 1 Feb 2009 19:28:18 +0000 Subject: [PATCH 207/248] qi-fix-block-init-cache-logic.patch Changes in the last couple of weeks aimed at cleaning this code broke the block device init cache logic. This patch restores the logic and reduces the card init failures when there is no SD Card present to 1 regardless of the number of partitions probed on the card. Together with the reduction in Glamo card wait on init this reduces the delay before trying NAND to 1/9th of before the patches. Signed-off-by: Andy Green --- qiboot/src/phase2.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index dd15055..de20cd3 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -103,28 +103,32 @@ static int do_block_init(void) { static void * last_block_init = NULL; static int last_block_init_result = 0; + int fresh = 0; /* if this device needs initializing, try to init it */ if (!this_kernel->block_init) - return 1; + return 1; /* happy */ /* * cache result to limit attempts for same * block device to one time */ - if (this_kernel->block_init != last_block_init) + if (this_kernel->block_init != last_block_init) { + last_block_init = this_kernel->block_init; last_block_init_result = (this_kernel->block_init)(); + fresh = 1; + } if (last_block_init_result) { puts("block device init failed\n"); - if (this_kernel->block_init != last_block_init) + if (fresh) indicate(UI_IND_MOUNT_FAIL); - last_block_init = NULL; - return 0; + + return 0; /* failed */ } last_block_init = this_kernel->block_init; - return 1; + return 1; /* happy */ } static int do_partitions(void *kernel_dram) From 53279b5983d99c91d91555d888b6a789d7b7d6de Mon Sep 17 00:00:00 2001 From: Andy Green Date: Tue, 3 Feb 2009 18:06:36 +0000 Subject: [PATCH 208/248] qi-export-s3c2442-nand-bad-block-check.patch At least GTA02 specific code is now interested in bad blocks. Rename the function and export it. Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/nand_read.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/qiboot/src/cpu/s3c2442/nand_read.c b/qiboot/src/cpu/s3c2442/nand_read.c index bec2e8b..8d05380 100644 --- a/qiboot/src/cpu/s3c2442/nand_read.c +++ b/qiboot/src/cpu/s3c2442/nand_read.c @@ -56,11 +56,12 @@ static inline void nand_wait(void) #define NAND_BLOCK_MASK (NAND_PAGE_SIZE - 1) #define NAND_BLOCK_SIZE (NAND_PAGE_SIZE * 64) -static int is_bad_block(unsigned long block_index) +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; @@ -130,8 +131,8 @@ int nand_read_ll(unsigned char *buf, unsigned long start_block512, ; while (blocks512 > 0) { - if (is_bad_block(start_block512) || - is_bad_block(start_block512 + 4)) { + if (s3c2442_nand_is_bad_block(start_block512) || + s3c2442_nand_is_bad_block(start_block512 + 4)) { start_block512 += 4; blocks512 += 4; if (bad_count++ == 4) From dd2344a9c7707ebf24cd640060f0fb098d2ff062 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Tue, 3 Feb 2009 18:06:36 +0000 Subject: [PATCH 209/248] qi-add-post-serial-init-api.patch It can be useful to have a device API that can print device-specific things after serial is initialized. Signed-off-by: Andy Green --- qiboot/include/qi.h | 1 + qiboot/src/cpu/s3c2442/gta02.c | 10 ++++++++++ qiboot/src/phase2.c | 5 +++++ 3 files changed, 16 insertions(+) diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index be25626..8d46ac0 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -101,6 +101,7 @@ struct board_api { int (*is_this_board)(void); void (*early_port_init)(void); void (*port_init)(void); + void (*post_serial_init)(void); /* print device-specific things */ void (*putc)(char); void (*close)(void); u8 (*get_ui_keys)(void); diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 5ad5316..3fd93e0 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -447,6 +447,15 @@ static void set_ui_indication_gta02(enum ui_indication ui_indication) } +void post_serial_init_gta02(void) +{ + if (battery_condition_reasonable) + puts("Battery condition reasonable\n"); + else + puts("BATTERY CONDITION LOW\n"); +} + + /* * our API for bootloader on this machine */ @@ -460,6 +469,7 @@ const struct board_api board_api_gta02 = { .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, .putc = putc_gta02, .close = close_gta02, .get_ui_keys = get_ui_keys_gta02, diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index de20cd3..1fe96b8 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -450,6 +450,11 @@ static void try_this_kernel(void) void bootloader_second_phase(void) { + /* give device a chance to print device-specific things */ + + if (this_board->post_serial_init) + (this_board->post_serial_init)(); + /* we try the possible kernels for this board in order */ for (this_kernel = this_board->kernel_source; this_kernel->name; From 72ecb60392d4fd43bac0be3e9f8cab6bbf6c49a7 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Tue, 3 Feb 2009 18:06:37 +0000 Subject: [PATCH 210/248] qi-add-hex-sprintf-type-functions.patch We need to print hex into string buffers now, only in phase 2 Signed-off-by: Andy Green --- qiboot/include/qi.h | 4 ++++ qiboot/src/utils-phase2.c | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index 8d46ac0..84fdc50 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -126,6 +126,10 @@ 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); diff --git a/qiboot/src/utils-phase2.c b/qiboot/src/utils-phase2.c index f02d5b1..bbbd672 100644 --- a/qiboot/src/utils-phase2.c +++ b/qiboot/src/utils-phase2.c @@ -109,3 +109,26 @@ void hexdump(unsigned char *start, int len) len -= 16; } } + +void setnybble(char *p, unsigned char n) +{ + if (n < 10) + *p = '0' + n; + else + *p = 'a' + n - 10; +} + +void set8(char *p, unsigned char n) +{ + setnybble(p, (n >> 4) & 15); + setnybble(p + 1, n & 15); +} + +void set32(char *p, unsigned int u) +{ + set8(p, u >> 24); + set8(p + 2, u >> 16); + set8(p + 4, u >> 8); + set8(p + 6, u); +} + From a5f8c6f2f87d1909d7da76a033f29f105b3714c3 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Tue, 3 Feb 2009 18:06:38 +0000 Subject: [PATCH 211/248] qi-add-append_device_specific_cmdline-API.patch Add a board API callback that allows a device-specific commandline area to be created at the time the kernel commandline is being composed. Signed-off-by: Andy Green --- qiboot/include/qi.h | 1 + qiboot/src/phase2.c | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index 84fdc50..b99695d 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -102,6 +102,7 @@ struct board_api { 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); diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 1fe96b8..4a7ff18 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -185,7 +185,6 @@ static void do_params(unsigned initramfs_len, (this_board->get_board_variant)(); const char *p; char * cmdline; - char * p1; struct tag *params = (struct tag *)this_board->linux_tag_placement; /* eat leading white space */ @@ -225,7 +224,18 @@ static void do_params(unsigned initramfs_len, /* kernel commandline */ cmdline = params->u.cmdline.cmdline; + + /* start with the fixed device part of the commandline */ + cmdline += strlen(strcpy(cmdline, p)); + + /* if the board itself needs a computed commandline, add it now */ + + if (this_board->append_device_specific_cmdline) + cmdline = (this_board->append_device_specific_cmdline)(cmdline); + + /* If he is giving an append commandline for this rootfs, apply that */ + if (this_kernel->commandline_append) cmdline += strlen(strcpy(cmdline, this_kernel->commandline_append)); @@ -235,9 +245,10 @@ static void do_params(unsigned initramfs_len, /* deal with any trailing newlines that hitched a ride */ - p1 = cmdline + strlen(cmdline) - 1; - while (*p1 == '\n') - *p1-- = '\0'; + while (*(cmdline - 1) == '\n') + cmdline--; + + *cmdline = '\0'; /* * if he's still holding down the UI_ACTION_SKIPKERNEL key From 25b5a9ba6259420fe8f1b7bc9a6eb5bf3cbfc1fd Mon Sep 17 00:00:00 2001 From: Andy Green Date: Tue, 3 Feb 2009 18:06:38 +0000 Subject: [PATCH 212/248] qi-gta02-compute-and-append-dynparts.patch This adds dynamic partition computation support for Qi on GTA02. It's for compatability with existing GTA02 using U-Boot partition scheme where a bad block in the previous partition moves on the start of the next partition by one block. It's important that Qi has no private state, so we need to compute the NAND arrangement each boot. It turns out this is extremely fast using Qi's bad block code originally from Xinagfu. Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/gta02.c | 93 ++++++++++++++++++++++++++++++---- 1 file changed, 83 insertions(+), 10 deletions(-) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 3fd93e0..522ec03 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -30,6 +30,7 @@ #include #include #include +#include #define GTA02_DEBUG_UART 2 #define PCF50633_I2C_ADS 0x73 @@ -37,6 +38,30 @@ static int battery_condition_reasonable = 0; +struct nand_dynparts { + const char *name; /* name of this partition for Linux */ + u32 good_length; /* bytes needed from good sectors in this partition */ +}; + +/* + * 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 */ @@ -400,7 +425,7 @@ static u8 get_ui_keys_gta02(void) older_keys = old_keys; old_keys = keys; - + return ret; } @@ -455,6 +480,61 @@ void post_serial_init_gta02(void) puts("BATTERY CONDITION LOW\n"); } +/* + * create and append dynparts Linux kernel commandline + */ + +char * append_device_specific_cmdline_gta02(char * cmdline) +{ + int n = 0; + u32 block512 = 0; + u32 start_block512 = 0; + char term = ','; + const u32 GTA02_NAND_READBLOCK_SIZE = 2048; + extern int s3c2442_nand_is_bad_block(unsigned long block_index_512); + + cmdline += strlen(strcpy(cmdline, + " mtdparts=physmap-flash:-(nor);neo1973-nand:")); + + 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; + term = ' '; + } + + *cmdline++ = '0'; + *cmdline++ = 'x'; + set32(cmdline, (block512 - start_block512) * 512); + cmdline += 8; + *cmdline++ = '('; + cmdline += strlen(strcpy(cmdline, nand_dynparts[n].name)); + *cmdline++ = ')'; + *cmdline++ = term; + + /* stash a copy of real offset for each partition */ + nand_dynparts[n].good_length = start_block512; + + start_block512 = block512; + + n++; + } + + *cmdline = '\0'; + + return cmdline; +} /* * our API for bootloader on this machine @@ -470,20 +550,13 @@ const struct board_api board_api_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 = "mtdparts=physmap-flash:-(nor);" \ - "neo1973-nand:" \ - "0x00040000(qi)," \ - "0x00040000(cmdline)," \ - "0x00800000(backupkernel)," \ - "0x000a0000(extra)," \ - "0x00040000(identity)," \ - "0x0f6a0000(backuprootfs) " \ - "loglevel=4 " \ + .commandline_board = "loglevel=4 " \ "console=tty0 " \ "console=ttySAC2,115200 " \ "init=/sbin/init " \ From bb67ea1a843981b249e04ba353d2de411939bb5b Mon Sep 17 00:00:00 2001 From: Andy Green Date: Tue, 3 Feb 2009 18:06:39 +0000 Subject: [PATCH 213/248] qi-improve-nand-read-512-granularity.patch Previously we insisted on NAND block granularity read addressing and buffer length, even though we normalized the block indexing to 512 bytes to be compatible with ext2 and SD. This patch improves the read functions so they are completely 512- block friendly, any number of 512 byte blocks can be fetched from any 512 byte boundary now. Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/nand_read.c | 32 ++++++++++++++---------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/qiboot/src/cpu/s3c2442/nand_read.c b/qiboot/src/cpu/s3c2442/nand_read.c index 8d05380..06ec24d 100644 --- a/qiboot/src/cpu/s3c2442/nand_read.c +++ b/qiboot/src/cpu/s3c2442/nand_read.c @@ -80,14 +80,18 @@ int s3c2442_nand_is_bad_block(unsigned long block_index) return 0; } -static int nand_read_page_ll(unsigned char *buf, unsigned long block512) +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; -#if 0 - unsigned char ecc[64]; - unsigned short *p16 = (unsigned short *)ecc; -#endif + 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(); @@ -96,23 +100,20 @@ static int nand_read_page_ll(unsigned char *buf, unsigned long block512) page_num = block512 >> 2; /* 512 block -> 2048 block */ /* Write Address */ NFADDR = 0; - 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 < NAND_PAGE_SIZE/2; i++) + for (i = 0; i < block_amount; i++) *ptr16++ = NFDATA16; -#if 0 - for (i = 0; i < 64 / 2; i++) { - *p16++ = NFDATA16; - } -#endif - return 4; + + return blocks512; } + /* low level nand read function */ int nand_read_ll(unsigned char *buf, unsigned long start_block512, int blocks512) @@ -120,9 +121,6 @@ int nand_read_ll(unsigned char *buf, unsigned long start_block512, int i, j; int bad_count = 0; - if (start_block512 & 3) /* inside 2048-byte block */ - return -1; - /* chip Enable */ nand_select(); nand_clear_RnB(); @@ -140,7 +138,7 @@ int nand_read_ll(unsigned char *buf, unsigned long start_block512, continue; } - j = nand_read_page_ll(buf, start_block512); + j = nand_read_page_ll(buf, start_block512, blocks512); start_block512 += j; buf += j << 9; blocks512 -= j; From dd0c85f42706fa95d27f40af57f1f0db53eae7b3 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Tue, 3 Feb 2009 18:06:39 +0000 Subject: [PATCH 214/248] qi-add-gta02-indentity-part-parsing.patch Now everything else is in place, we are able to mount the GTA02 "identity" partition and extract the USB Ethernet MAC Address from it, and add it to the kernel commandline. This causes the Ethernet gadget to use the same MAC address each boot, simplifying DHCP server situation. The MAC address in the identity partition is globally unique from the factory. Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/gta02.c | 59 +++++++++++++++++++++++++++++++++- qiboot/src/fs/dev.c | 4 +-- 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 522ec03..e520fbb 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -31,6 +31,7 @@ #include #include #include +#include #define GTA02_DEBUG_UART 2 #define PCF50633_I2C_ADS 0x73 @@ -38,6 +39,9 @@ static int battery_condition_reasonable = 0; +extern unsigned long partition_offset_blocks; +extern unsigned long partition_length_blocks; + struct nand_dynparts { const char *name; /* name of this partition for Linux */ u32 good_length; /* bytes needed from good sectors in this partition */ @@ -480,18 +484,30 @@ void post_serial_init_gta02(void) puts("BATTERY CONDITION LOW\n"); } +const struct board_api board_api_gta02; + /* - * create and append dynparts Linux kernel commandline + * 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 len; u32 block512 = 0; u32 start_block512 = 0; char term = ','; const u32 GTA02_NAND_READBLOCK_SIZE = 2048; extern int s3c2442_nand_is_bad_block(unsigned long block_index_512); + static char mac[64]; + struct kernel_source const * real_kernel = this_kernel; + + /* + * dynparts computation + */ cmdline += strlen(strcpy(cmdline, " mtdparts=physmap-flash:-(nor);neo1973-nand:")); @@ -533,6 +549,47 @@ char * append_device_specific_cmdline_gta02(char * cmdline) *cmdline = '\0'; + /* + * Identity + */ + + /* position ourselves at true start of GTA02 identity partition */ + partition_offset_blocks = nand_dynparts[4].good_length; + 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.host_addr=")); + cmdline += strlen(strcpy(cmdline, &mac[2])); + *cmdline += ' ' ; +bail: + this_kernel = real_kernel; + + *cmdline = '\0'; + return cmdline; } diff --git a/qiboot/src/fs/dev.c b/qiboot/src/fs/dev.c index 8ffcf2d..9d4fba3 100644 --- a/qiboot/src/fs/dev.c +++ b/qiboot/src/fs/dev.c @@ -39,6 +39,7 @@ int ext2fs_devread(int sector, int filesystem_block_log2, int byte_offset, int b sector = sector << filesystem_block_log2; + /* * Check partition boundaries */ @@ -93,8 +94,7 @@ int ext2fs_devread(int sector, int filesystem_block_log2, int byte_offset, int b u8 p[SECTOR_SIZE]; block_len = SECTOR_SIZE; - this_kernel->block_read(p, - partition_offset_blocks + sector, 1); + this_kernel->block_read(p,partition_offset_blocks + sector, 1); memcpy(buf, p, byte_len); return 1; } From 08362c95c77cf68506a12ecf489b1d137ba8e724 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Tue, 3 Feb 2009 18:06:40 +0000 Subject: [PATCH 215/248] qi-gta02-compute-nand-kernel-partition-offset.patch There's one more thing that wants dynpart computed block offset - the kernel offset used for NAND boot. This patch moves the business end of the dynparts computation into the port_init_gta02() so it's done earlier, and writes the block index into the board_api struct NAND option's partition block start field. It also adds a field to the nand_dynparts struct so we can hold both the true length and true block offset for each partition for later use by the original code in append_device_specific_cmdline_gta02. Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/gta02.c | 82 +++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 30 deletions(-) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index e520fbb..3fd9e42 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -42,9 +42,12 @@ 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; }; /* @@ -134,6 +137,10 @@ void port_init_gta02(void) 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) @@ -297,6 +304,44 @@ void port_init_gta02(void) * 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; + } /** @@ -484,7 +529,6 @@ void post_serial_init_gta02(void) puts("BATTERY CONDITION LOW\n"); } -const struct board_api board_api_gta02; /* * create and append device-specific Linux kernel commandline @@ -497,11 +541,6 @@ char * append_device_specific_cmdline_gta02(char * cmdline) { int n = 0; int len; - u32 block512 = 0; - u32 start_block512 = 0; - char term = ','; - const u32 GTA02_NAND_READBLOCK_SIZE = 2048; - extern int s3c2442_nand_is_bad_block(unsigned long block_index_512); static char mac[64]; struct kernel_source const * real_kernel = this_kernel; @@ -514,37 +553,19 @@ char * append_device_specific_cmdline_gta02(char * cmdline) 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; - term = ' '; - } - *cmdline++ = '0'; *cmdline++ = 'x'; - set32(cmdline, (block512 - start_block512) * 512); + set32(cmdline, nand_dynparts[n].good_length * 512); cmdline += 8; *cmdline++ = '('; cmdline += strlen(strcpy(cmdline, nand_dynparts[n].name)); *cmdline++ = ')'; - *cmdline++ = term; - /* stash a copy of real offset for each partition */ - nand_dynparts[n].good_length = start_block512; + if (++n == ARRAY_SIZE(nand_dynparts)) + *cmdline++ = ' '; + else + *cmdline++ = ','; - start_block512 = block512; - - n++; } *cmdline = '\0'; @@ -554,7 +575,7 @@ char * append_device_specific_cmdline_gta02(char * cmdline) */ /* position ourselves at true start of GTA02 identity partition */ - partition_offset_blocks = nand_dynparts[4].good_length; + partition_offset_blocks = nand_dynparts[4].true_offset; partition_length_blocks = 0x40000 / 512; /* @@ -653,6 +674,7 @@ const struct board_api board_api_gta02 = { [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 " \ From c9033e2d91f35e40f43500a7c7241ab2376a5441 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Thu, 19 Feb 2009 03:30:56 +0000 Subject: [PATCH 216/248] fix-6410-partition-initial-offset.patch Signed-off-by: Andy Green --- qiboot/6410-partition-sd.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiboot/6410-partition-sd.sh b/qiboot/6410-partition-sd.sh index 20ad9d0..4f5502d 100755 --- a/qiboot/6410-partition-sd.sh +++ b/qiboot/6410-partition-sd.sh @@ -103,7 +103,7 @@ if [ -z "$4" ] ; then echo "p" >>$FDISK_SCRIPT echo "1" >>$FDISK_SCRIPT # first partition == 1 - echo "64" >>$FDISK_SCRIPT + echo "" >>$FDISK_SCRIPT echo "+$FATMB"M >>$FDISK_SCRIPT # add the normal EXT3 rootfs From 0395c03c9d748090591125ffd53cf0114eabc595 Mon Sep 17 00:00:00 2001 From: Robert Piasek Date: Fri, 20 Feb 2009 02:34:36 +0000 Subject: [PATCH 217/248] Re: [PATCH 7/8] qi-add-gta02-indentity-part-parsing.patch Andy, On Tuesday 03 February 2009 18:12:50 Andy Green wrote: > Now everything else is in place, we are able to mount > the GTA02 "identity" partition and extract the USB Ethernet > MAC Address from it, and add it to the kernel commandline. > > This causes the Ethernet gadget to use the same MAC address > each boot, simplifying DHCP server situation. The MAC > address in the identity partition is globally unique from > the factory. Because of this patch I can no longer load g_ether module with host_addr= and dev_addr= parameters. The module is always loaded using factory mac for HOST and random mac for DEV. That messes up my setup a bit, as I use NetworkManager 0.7 on FreeRunner itself (and it expects DEV mac to be the same each time). Would it be a problem to also include g_ether.dev_addr? Attached patch solves my problem. Rob --- qiboot/src/cpu/s3c2442/gta02.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 3fd9e42..ce8b5a0 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -606,6 +606,10 @@ char * append_device_specific_cmdline_gta02(char * cmdline) cmdline += strlen(strcpy(cmdline, " g_ether.host_addr=")); cmdline += strlen(strcpy(cmdline, &mac[2])); *cmdline += ' ' ; + + cmdline += strlen(strcpy(cmdline, " g_ether.dev_addr=")); + cmdline += strlen(strcpy(cmdline, &mac[2])); + *cmdline += ' ' ; bail: this_kernel = real_kernel; From 97b9bc018e48ada9deeabb54215593afe160f4d9 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 20 Feb 2009 04:57:47 +0000 Subject: [PATCH 218/248] fix-trailing-space-ethernet-mac.patch There's no trailing space after the last mac address addition, it was broken before the recent patch adding the second mac address. Also, we don't need to add the first space by hand if it's unconditionally added in the string afterwards. Reported-by: Werner Almesberger Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/gta02.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index ce8b5a0..61ca75c 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -605,11 +605,10 @@ char * append_device_specific_cmdline_gta02(char * cmdline) cmdline += strlen(strcpy(cmdline, " g_ether.host_addr=")); cmdline += strlen(strcpy(cmdline, &mac[2])); - *cmdline += ' ' ; cmdline += strlen(strcpy(cmdline, " g_ether.dev_addr=")); cmdline += strlen(strcpy(cmdline, &mac[2])); - *cmdline += ' ' ; + *cmdline++ += ' ' ; bail: this_kernel = real_kernel; From 05027f9b8af1cffc807272653524fa9b5e7bab86 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 20 Feb 2009 05:10:44 +0000 Subject: [PATCH 219/248] qi-fix-adding-space-to-char-not-to-string.patch Reported-by: Sean McNeil Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/gta02.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 61ca75c..650ea25 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -608,7 +608,7 @@ char * append_device_specific_cmdline_gta02(char * cmdline) cmdline += strlen(strcpy(cmdline, " g_ether.dev_addr=")); cmdline += strlen(strcpy(cmdline, &mac[2])); - *cmdline++ += ' ' ; + *cmdline++ = ' ' ; bail: this_kernel = real_kernel; From dd81d5fb05ca283d1bb1c9fb0c44fb93e4ab3e14 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 23 Feb 2009 02:15:26 +0000 Subject: [PATCH 220/248] qi-gta02-fix-gph-uart0-pin.patch Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/gta02.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 650ea25..47198ff 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -145,7 +145,7 @@ void port_init_gta02(void) //CAUTION:Follow the configuration order for setting the ports. // 1) setting value(GPnDAT) // 2) setting control register (GPnCON) - // 3) configure pull-up resistor(GPnUP) + // 3) configure pull-down resistor(GPnUP) /* 32bit data bus configuration */ /* @@ -236,11 +236,11 @@ void port_init_gta02(void) * Binary : 10 , 10 10 , 11 11 , 10 10 , 10 10 , 10 10 */ /* pulldown on GPH08: UEXTCLK, just floats! - * pulldown GPH0 -- nCTS0 / RTS_MODEM -- floats when GSM off - * pulldown GPH3 -- RXD[0] / TX_MODEM -- floats when GSM off + * pulldown GPH1 -- nCTS0 / RTS_MODEM -- floats when GSM off + * pulldown GPH2 -- RXD[0] / TX_MODEM -- floats when GSM off */ - rGPHCON = 0x001AAAAA; - rGPHUP = 0x000007FF & ~(1 << 8) & ~(1 << 0) & ~(1 << 3); + rGPHCON = 0x001AAA82; /* H1 and H2 are INPUTs to start with, not UART */ + rGPHUP = 0x000007FF & ~(1 << 8) & ~(1 << 1) & ~(1 << 3); rGPHDAT = 0x00000000; /* pulldown on GPJ00: input, just floats! */ From 6ace49aa533f7021fe5cfe4b47d53165bb92e6ea Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 23 Feb 2009 02:15:26 +0000 Subject: [PATCH 221/248] qi-gta02-a7-as-a6.patch Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/gta02.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 47198ff..1591ccb 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -127,7 +127,11 @@ static const struct board_variant board_variants[] = { [1] = { .name = "A6 PCB", .machine_revision = 0x360, - } + }, + [9] = { /* 01001 */ + .name = "A7 PCB", + .machine_revision = 0x360, /* report as A6 */ + }, }; @@ -373,8 +377,8 @@ int gta02_get_pcb_revision(void) u = rGPDDAT; n |= (u << (0 + 2)) & 0x004; - n |= (u << (8 - 3)) & 0x100; - n |= (u << (9 - 4)) & 0x200; + n |= (u << (3 - 3)) & 0x008; + n |= (u << (4 - 4)) & 0x010; /* * when not being interrogated, all of the revision GPIO @@ -424,7 +428,12 @@ int is_this_board_gta02(void) const struct board_variant const * get_board_variant_gta02(void) { - return &board_variants[gta02_get_pcb_revision() & 1]; + 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) From b4ed735c58392bb8af6e3d1a75488daacde43693 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 23 Feb 2009 02:15:27 +0000 Subject: [PATCH 222/248] qi-fix-prepend-debug-space.patch Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2410/gta01.c | 2 +- qiboot/src/cpu/s3c2442/gta02.c | 2 +- qiboot/src/cpu/s3c6410/gta03-steppingstone.c | 1 + qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/qiboot/src/cpu/s3c2410/gta01.c b/qiboot/src/cpu/s3c2410/gta01.c index c8ff25e..15fc315 100644 --- a/qiboot/src/cpu/s3c2410/gta01.c +++ b/qiboot/src/cpu/s3c2410/gta01.c @@ -268,7 +268,7 @@ const struct board_api board_api_gta01 = { "console=ttySAC0,115200 " \ "init=/sbin/init "\ "ro ", - .commandline_board_debug = "loglevel=8 ", + .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 */ diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 1591ccb..e836f9b 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -651,7 +651,7 @@ const struct board_api board_api_gta02 = { "console=ttySAC2,115200 " \ "init=/sbin/init " \ "ro ", - .commandline_board_debug = "loglevel=8", + .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 */ diff --git a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c index d0027c6..521f521 100644 --- a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/gta03-steppingstone.c @@ -91,6 +91,7 @@ const struct board_api board_api_gta03 = { "loglevel=8 " \ "rootdelay=1 " \ "ro ", + .commandline_board_debug = " loglevel=8", .kernel_source = { [0] = { .name = "SD Card rootfs", diff --git a/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c b/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c index f2c8a5a..5bc05f0 100644 --- a/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c @@ -48,6 +48,7 @@ const struct board_api board_api_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 = { From 0363beaa021c133b40b125d8628e2162568e6cb1 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Wed, 25 Feb 2009 15:09:43 +0000 Subject: [PATCH 223/248] [QI] make GTA03 boot-SD on Debian 6410-partition-sd.sh didn't handle Debian, which is just like Ubuntu 7. (Tested on "lenny". YMMV.) Signed-off-by: Werner Almesberger --- qiboot/6410-partition-sd.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiboot/6410-partition-sd.sh b/qiboot/6410-partition-sd.sh index 4f5502d..3615de5 100755 --- a/qiboot/6410-partition-sd.sh +++ b/qiboot/6410-partition-sd.sh @@ -55,7 +55,7 @@ fi # default: use cat as a no-op USE_SED='cat' case "$(lsb_release --short --description)" in - Ubuntu\ 7*) + Ubuntu\ 7*|Debian\ *) CUT_COLUMN=5 ;; Ubuntu\ 8.04*) From 1cb7b0b53cc643ca5827bbd6bd4bde803a18e2f8 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Sat, 28 Feb 2009 11:04:47 +0000 Subject: [PATCH 224/248] simplify QI GTA03 boot-SD size discovery This patch uses fdisk instead of dmesg to determine the size of the uSD card. This should be less fragile and is much simpler than the previous solution. Signed-off-by: Werner Almesberger --- qiboot/6410-partition-sd.sh | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/qiboot/6410-partition-sd.sh b/qiboot/6410-partition-sd.sh index 3615de5..7952667 100755 --- a/qiboot/6410-partition-sd.sh +++ b/qiboot/6410-partition-sd.sh @@ -50,34 +50,8 @@ if [ ! -z "`grep $1 /proc/mounts`" ] ; then exit 2 fi -# set CUT_COLUMN for each OS -# set USE_SED=some editing command -# default: use cat as a no-op -USE_SED='cat' -case "$(lsb_release --short --description)" in - Ubuntu\ 7*|Debian\ *) - CUT_COLUMN=5 - ;; - Ubuntu\ 8.04*) - CUT_COLUMN=5 - USE_SED='sed s/^\[[[:space:]]*/[/' - ;; - *) - CUT_COLUMN=4 - ;; -esac - -DMESG_LINE=$(dmesg | ${USE_SED} | grep "$1" | grep "512-byte hardware" | tail -n 1) -SECTORS=$(echo "${DMESG_LINE}" | cut -d' ' -f"${CUT_COLUMN}") - -if ! echo "${SECTORS}" | grep '^[[:digit:]]\+$' -then - echo "problem finding size for /dev/$1 check CUT_COLUMN value for your os" - echo "CUT_COLUMN=${CUT_COLUMN} --> ${SECTORS}" - echo "dmesg line was:" - echo "${DMESG_LINE}" - exit 3 -fi +bytes=`echo p | fdisk /dev/$1 2>&1 | sed '/^Disk.*, \([0-9]*\) bytes/s//\1/p;d'` +SECTORS=`expr $bytes / 512` if [ $SECTORS -le 0 ] ; then echo "problem finding size for /dev/$1" From 67d668d7818fe7e5cda347774bdf0e60f2501f18 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 2 Mar 2009 12:21:38 +0000 Subject: [PATCH 225/248] qi-gta02-revert-unpowered-gsm-UART-safe-at-boot.patch Signed-off-by: Andy Green --- qiboot/src/cpu/s3c2442/gta02.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index e836f9b..b2671b3 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -239,11 +239,31 @@ void port_init_gta02(void) * 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 GPH2 -- RXD[0] / TX_MODEM -- floats when GSM off + * pulldown GPH3 -- RXD[0] / RX_MODEM -- floats when GSM off */ - rGPHCON = 0x001AAA82; /* H1 and H2 are INPUTs to start with, not UART */ rGPHUP = 0x000007FF & ~(1 << 8) & ~(1 << 1) & ~(1 << 3); rGPHDAT = 0x00000000; From c53df5fb28fa54229dc0b1698cc8843f2321f9cb Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 2 Mar 2009 18:51:08 +0000 Subject: [PATCH 226/248] qi-rename-gta03-3d7k.patch Signed-off-by: Andy Green --- qiboot/include/{neo_gta03.h => neo_om_3d7k.h} | 4 +- qiboot/src/cpu/s3c2442/start_qi.c | 1 - ...teppingstone.c => om_3d7k-steppingstone.c} | 52 +++++++++---------- qiboot/src/cpu/s3c6410/{gta03.c => om_3d7k.c} | 34 ++++++------ qiboot/src/cpu/s3c6410/qi.lds | 2 +- qiboot/src/cpu/s3c6410/start_qi.c | 4 +- 6 files changed, 48 insertions(+), 49 deletions(-) rename qiboot/include/{neo_gta03.h => neo_om_3d7k.h} (91%) rename qiboot/src/cpu/s3c6410/{gta03-steppingstone.c => om_3d7k-steppingstone.c} (60%) rename qiboot/src/cpu/s3c6410/{gta03.c => om_3d7k.c} (97%) diff --git a/qiboot/include/neo_gta03.h b/qiboot/include/neo_om_3d7k.h similarity index 91% rename from qiboot/include/neo_gta03.h rename to qiboot/include/neo_om_3d7k.h index 110b795..141b390 100644 --- a/qiboot/include/neo_gta03.h +++ b/qiboot/include/neo_om_3d7k.h @@ -22,7 +22,7 @@ #ifndef __ASM_MODE__ #include -extern const struct board_api board_api_gta03; +extern const struct board_api board_api_om_3d7k; #endif -#define TEXT_BASE_GTA03 0x53000000 +#define TEXT_BASE_OM_3D7K 0x53000000 diff --git a/qiboot/src/cpu/s3c2442/start_qi.c b/qiboot/src/cpu/s3c2442/start_qi.c index 8364a2d..d7136fd 100644 --- a/qiboot/src/cpu/s3c2442/start_qi.c +++ b/qiboot/src/cpu/s3c2442/start_qi.c @@ -27,7 +27,6 @@ #include #include "nand_read.h" #include -#include #define stringify2(s) stringify1(s) #define stringify1(s) #s diff --git a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c b/qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c similarity index 60% rename from qiboot/src/cpu/s3c6410/gta03-steppingstone.c rename to qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c index 521f521..9723276 100644 --- a/qiboot/src/cpu/s3c6410/gta03-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c @@ -1,34 +1,34 @@ #include -#include +#include #include #include -#define GTA03_DEBUG_UART 3 +#define OM_3D7K_DEBUG_UART 3 /* out of steppingstone */ -extern const struct board_variant const * get_board_variant_gta03(void); -extern void port_init_gta03(void); +extern const struct board_variant const * get_board_variant_om_3d7k(void); +extern void port_init_om_3d7k(void); -int is_this_board_gta03(void) +int is_this_board_om_3d7k(void) { - /* FIXME: find something gta03 specific */ + /* FIXME: find something om_3d7k specific */ return 1; } -static void putc_gta03(char c) +static void putc_om_3d7k(char c) { - serial_putc_s3c64xx(GTA03_DEBUG_UART, c); + serial_putc_s3c64xx(OM_3D7K_DEBUG_UART, c); } -int sd_card_init_gta03(void) +int sd_card_init_om_3d7k(void) { extern int s3c6410_mmc_init(int verbose); return s3c6410_mmc_init(1); } -int sd_card_block_read_gta03(unsigned char * buf, unsigned long start512, +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, @@ -47,14 +47,14 @@ unsigned long s3c6410_mmc_bread(int dev_num, unsigned long blknr, unsigned long * "root=/dev/ram ramdisk_size=6000000" */ -static u8 get_ui_keys_gta03(void) +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 GTA03, map to UI_ACTION_ADD_DEBUG, down = 1 */ + /* GPN1 is MINUS on OM_3D7K, map to UI_ACTION_ADD_DEBUG, down = 1 */ keys = !!(__REG(GPMDAT) & (1 << 1)); if (keys == old_keys) @@ -72,19 +72,19 @@ static u8 get_ui_keys_gta03(void) return ret; } -const struct board_api board_api_gta03 = { - .name = "GTA03", - .linux_machine_id = 1866, +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_gta03, - .is_this_board = is_this_board_gta03, - .port_init = port_init_gta03, - .putc = putc_gta03, - .noboot = "boot/noboot-GTA03", - .append = "boot/append-GTA03", - .get_ui_keys = get_ui_keys_gta03, + .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=/bin/sh " \ @@ -95,18 +95,18 @@ const struct board_api board_api_gta03 = { .kernel_source = { [0] = { .name = "SD Card rootfs", - .block_read = sd_card_block_read_gta03, + .block_read = sd_card_block_read_om_3d7k, .filesystem = FS_EXT2, .partition_index = 2, - .filepath = "boot/uImage-GTA03.bin", + .filepath = "boot/uImage-OM_3D7K.bin", .commandline_append = "root=/dev/mmcblk0p2 ", }, [1] = { .name = "SD Card backup rootfs", - .block_read = sd_card_block_read_gta03, + .block_read = sd_card_block_read_om_3d7k, .filesystem = FS_EXT2, .partition_index = 3, - .filepath = "boot/uImage-GTA03.bin", + .filepath = "boot/uImage-OM_3D7K.bin", .commandline_append = "root=/dev/mmcblk0p3 ", }, }, diff --git a/qiboot/src/cpu/s3c6410/gta03.c b/qiboot/src/cpu/s3c6410/om_3d7k.c similarity index 97% rename from qiboot/src/cpu/s3c6410/gta03.c rename to qiboot/src/cpu/s3c6410/om_3d7k.c index d2f25aa..b24d247 100644 --- a/qiboot/src/cpu/s3c6410/gta03.c +++ b/qiboot/src/cpu/s3c6410/om_3d7k.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include @@ -7,7 +7,7 @@ #define PCF50633_I2C_ADS 0x73 -const struct pcf50633_init gta03_pcf50633_init[] = { +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 */ @@ -50,40 +50,40 @@ const struct pcf50633_init gta03_pcf50633_init[] = { static const struct board_variant board_variants[] = { [0] = { - .name = "GTA03 unknown", + .name = "OM 3D7K unknown", .machine_revision = 0 }, [1] = { - .name = "GTA03 A1", + .name = "OM 3D7K A1", .machine_revision = 1 }, [2] = { - .name = "GTA03 A2", + .name = "OM 3D7K A2", .machine_revision = 2 }, [3] = { - .name = "GTA03 A3", + .name = "OM 3D7K A3", .machine_revision = 3 }, [4] = { - .name = "GTA03 A4", + .name = "OM 3D7K A4", .machine_revision = 4 }, [5] = { - .name = "GTA03 A5", + .name = "OM 3D7K A5", .machine_revision = 5 }, [6] = { - .name = "GTA03 A6", + .name = "OM 3D7K A6", .machine_revision = 6 }, [7] = { - .name = "GTA03 A7", + .name = "OM 3D7K A7", .machine_revision = 7 } }; -void port_init_gta03(void) +void port_init_om_3d7k(void) { int n; @@ -821,14 +821,14 @@ void port_init_gta03(void) /* * We have to talk to the PMU a little bit */ - for (n = 0; n < ARRAY_SIZE(gta03_pcf50633_init); n++) + for (n = 0; n < ARRAY_SIZE(om_3d7k_pcf50633_init); n++) i2c_write_sync(&bb_s3c6410, PCF50633_I2C_ADS, - gta03_pcf50633_init[n].index, - gta03_pcf50633_init[n].value); + om_3d7k_pcf50633_init[n].index, + om_3d7k_pcf50633_init[n].value); } -int gta03_get_pcb_revision(void) +int om_3d7k_get_pcb_revision(void) { u32 v = __REG(GPIDAT); /* @@ -847,8 +847,8 @@ int gta03_get_pcb_revision(void) ); } -const struct board_variant const * get_board_variant_gta03(void) +const struct board_variant const * get_board_variant_om_3d7k(void) { - return &board_variants[gta03_get_pcb_revision()]; + return &board_variants[om_3d7k_get_pcb_revision()]; } diff --git a/qiboot/src/cpu/s3c6410/qi.lds b/qiboot/src/cpu/s3c6410/qi.lds index 41defed..22d8546 100644 --- a/qiboot/src/cpu/s3c6410/qi.lds +++ b/qiboot/src/cpu/s3c6410/qi.lds @@ -45,7 +45,7 @@ SECTIONS 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/gta03-steppingstone.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) diff --git a/qiboot/src/cpu/s3c6410/start_qi.c b/qiboot/src/cpu/s3c6410/start_qi.c index abe34cf..e85d63b 100644 --- a/qiboot/src/cpu/s3c6410/start_qi.c +++ b/qiboot/src/cpu/s3c6410/start_qi.c @@ -25,7 +25,7 @@ #include -#include +#include #include #define stringify2(s) stringify1(s) @@ -34,7 +34,7 @@ extern void bootloader_second_phase(void); const struct board_api *boards[] = { - &board_api_gta03, + &board_api_om_3d7k, &board_api_smdk6410, NULL /* always last */ }; From e73e47ab936e0bbf88431f5947f0b1ad1966c661 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Sat, 7 Mar 2009 07:35:25 +0000 Subject: [PATCH 227/248] qi-3d7k-audit-gpio.patch Signed-off-by: Andy Green --- qiboot/6410-partition-sd.sh | 9 +- .../src/cpu/s3c6410/om_3d7k-steppingstone.c | 2 +- qiboot/src/cpu/s3c6410/om_3d7k.c | 178 +++++++++--------- 3 files changed, 98 insertions(+), 91 deletions(-) diff --git a/qiboot/6410-partition-sd.sh b/qiboot/6410-partition-sd.sh index 7952667..d692ed1 100755 --- a/qiboot/6410-partition-sd.sh +++ b/qiboot/6410-partition-sd.sh @@ -51,9 +51,16 @@ if [ ! -z "`grep $1 /proc/mounts`" ] ; then fi bytes=`echo p | fdisk /dev/$1 2>&1 | sed '/^Disk.*, \([0-9]*\) bytes/s//\1/p;d'` +echo bytes = $bytes + SECTORS=`expr $bytes / 512` -if [ $SECTORS -le 0 ] ; then +if [ -z "$SECTORS" ] ; then + echo "problem finding size for /dev/$1" + exit 4 +fi + +if [ "$SECTORS" -le 0 ] ; then echo "problem finding size for /dev/$1" exit 3 fi diff --git a/qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c b/qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c index 9723276..a6bdce1 100644 --- a/qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c @@ -89,7 +89,7 @@ const struct board_api board_api_om_3d7k = { "console=ttySAC3,115200 " \ "init=/bin/sh " \ "loglevel=8 " \ - "rootdelay=1 " \ + "rootdelay=1 no_console_suspend " \ "ro ", .commandline_board_debug = " loglevel=8", .kernel_source = { diff --git a/qiboot/src/cpu/s3c6410/om_3d7k.c b/qiboot/src/cpu/s3c6410/om_3d7k.c index b24d247..72750bb 100644 --- a/qiboot/src/cpu/s3c6410/om_3d7k.c +++ b/qiboot/src/cpu/s3c6410/om_3d7k.c @@ -22,7 +22,12 @@ const struct pcf50633_init om_3d7k_pcf50633_init[] = { { PCF50633_REG_DOWN1OUT, 0x17 }, /* 1.2V (0x17 * .025V + 0.625V) */ { PCF50633_REG_DOWN1ENA, 0x02 }, /* enabled if GPIO1 = HIGH */ - { PCF50633_REG_LDO6ENA, 0x01 }, /* LCM power off */ + { PCF50633_REG_LDO1ENA, 0x00 }, /* LCM power on */ + { PCF50633_REG_LDO2ENA, 0x00 }, /* LCM power on */ + { PCF50633_REG_LDO3ENA, 0x01 }, /* Codec power on */ + { PCF50633_REG_LDO4ENA, 0x01 }, /* SD power on */ + { PCF50633_REG_LDO5ENA, 0x00 }, /* LCM power on */ + { PCF50633_REG_LDO6ENA, 0x00 }, /* LCM power on */ { PCF50633_REG_INT1M, 0x00 }, { PCF50633_REG_INT2M, 0x00 }, @@ -100,8 +105,8 @@ void port_init_om_3d7k(void) (2 << 28) /* GPA7 - UART_RTS1 */ ; - __REG(GPAPUD) = /* all pullup and pulldown disabled */ - 0 + __REG(GPAPUD) = /* pullup inputs */ + 0x2222 ; __REG(GPADAT) = 0; /* just for determinism */ @@ -129,8 +134,8 @@ void port_init_om_3d7k(void) /* ---------------------------- Port B ---------------------------- */ __REG(GPBCON) = - (2 << 0) | /* GPB0 - UART_RXD2 */ - (2 << 4) | /* GPB1 - UART_TXD2 */ + (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 */ @@ -180,7 +185,7 @@ void port_init_om_3d7k(void) ; __REG(GPCPUD) = /* all pullup and pulldown disabled */ - 0 + (1 << 0) ; __REG(GPCDAT) = 0; /* just for determinism */ @@ -283,11 +288,13 @@ void port_init_om_3d7k(void) (2 << 22) | /* GPF11 - CAMIF_YDATA6 */ (2 << 24) | /* GPF12 - CAMIF_YDATA7 */ (1 << 26) | /* GPF13 - OUTPUT Vibrator */ - (3 << 28) | /* GPF14 - CLKOUT0 */ + (1 << 28) | /* GPF14 - output not CLKOUT0 */ (1 << 30) /* GPF15 - OUTPUT CAM_PWRDN */ ; - __REG(GPFPUD) = 0; /* all pullup and pulldown disabled */ + __REG(GPFPUD) = (1 << (2 * 12)) | (1 << (2 * 11)) | (1 << (2 * 10)) | + (1 << (2 * 9)) | (1 << (2 * 8)) | (1 << (2 * 7)) | + (1 << (2 * 6)) | (1 << (2 * 5)); /* all cam data pulldown */ __REG(GPFDAT) = (1 << 15); /* assert CAM_PWRDN */ @@ -368,21 +375,21 @@ void port_init_om_3d7k(void) /* ---------------------------- Port H ---------------------------- */ __REG(GPHCON0) = - (2 << 0) | /* GPH0 - MMC_CLK1 */ - (2 << 4) | /* GPH1 - MMC_CMD1 */ - (2 << 8) | /* GPH2 - MMC_DATA01 */ - (2 << 12) | /* GPH3 - MMC_DATA11 */ - (2 << 16) | /* GPH4 - MMC_DATA21 */ - (2 << 20) | /* GPH5 - MMC_DATA31 */ + (0 << 0) | /* GPH0 - NC OUT 0 */ + (0 << 4) | /* GPH1 - NC OUT 0 */ + (0 << 8) | /* GPH2 - NC OUT 0 */ + (0 << 12) | /* GPH3 - NC OUT 0 */ + (0 << 16) | /* GPH4 - NC OUT 0 */ + (0 << 20) | /* GPH5 - NC OUT 0 */ (1 << 24) | /* GPH6 - OUTPUT nWLAN_RESET */ (1 << 28) /* GPH7 - OUTPUT HDQ */ ; __REG(GPHCON1) = (1 << 0) | /* GPH8 - OUTPUT nWLAN_PD */ - (1 << 4) /* GPH9 - OUTPUT (NC) */ + (0 << 4) /* GPH9 - OUTPUT (NC) */ ; - __REG(GPHPUD) = 0; /* all pullup and pulldown disabled */ + __REG(GPHPUD) = 0x40555; /* all NC pulldown */ __REG(GPHDAT) = 0; @@ -530,26 +537,26 @@ void port_init_om_3d7k(void) __REG(GPKCON0) = (1 << 0) | /* GPK0 - OUTPUT nWLAN_POWERON */ - (1 << 4) | /* GPK1 - OUTPUT (NC) */ + (0 << 4) | /* GPK1 - input (NC) */ (1 << 8) | /* GPK2 - OUTPUT (nMODEM_ON) */ - (1 << 12) | /* GPK3 - OUTPUT (NC) */ - (1 << 16) | /* GPK4 - OUTPUT (NC) */ - (1 << 20) | /* GPK5 - OUTPUT (NC) */ - (1 << 24) | /* GPK6 - OUTPUT (NC) */ - (1 << 28) /* GPK7 - OUTPUT (NC) */ + (0 << 12) | /* GPK3 - input (NC) */ + (0 << 16) | /* GPK4 - input (NC) */ + (0 << 20) | /* GPK5 - input (NC) */ + (0 << 24) | /* GPK6 - input (NC) */ + (0 << 28) /* GPK7 - input (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) */ + (0 << 0) | /* GPK8 - input (NC) */ + (0 << 4) | /* GPK9 - input (NC) */ + (0 << 8) | /* GPK10 - input (NC) */ + (0 << 12) | /* GPK11 - input (NC) */ + (0 << 16) | /* GPK12 - input (NC) */ + (0 << 20) | /* GPK13 - input (NC) */ + (0 << 24) | /* GPK14 - input (NC) */ + (0 << 28) /* GPK15 - input (NC) */ ; - __REG(GPKPUD) = 0; /* all pullup and pulldown disabled */ + __REG(GPKPUD) = 0x55555544; /* all input pulldown */ __REG(GPKDAT) = (1 << 2) | /* deassert nMODEM_ON */ @@ -559,14 +566,14 @@ void port_init_om_3d7k(void) /* ---------------------------- 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) */ + (0 << 0) | /* GPL0 - OUTPUT (NC) */ + (0 << 4) | /* GPL1 - OUTPUT (NC) */ + (0 << 8) | /* GPL2 - OUTPUT (NC) */ + (0 << 12) | /* GPL3 - OUTPUT (NC) */ + (0 << 16) | /* GPL4 - OUTPUT (NC) */ + (0 << 20) | /* GPL5 - OUTPUT (NC) */ + (0 << 24) | /* GPL6 - OUTPUT (NC) */ + (0 << 28) /* GPL7 - OUTPUT (NC) */ ; __REG(GPLCON1) = (1 << 0) | /* GPL8 - OUTPUT (NC) */ @@ -578,7 +585,7 @@ void port_init_om_3d7k(void) (1 << 24) /* GPL14 - OUTPUT (NC) */ ; - __REG(GPLPUD) = 0; /* all pullup and pulldown disabled */ + __REG(GPLPUD) = 0x5555; /* all pullup and pulldown disabled */ __REG(GPLDAT) = 0; @@ -629,23 +636,23 @@ void port_init_om_3d7k(void) __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) */ + (0 << 4) | /* GPO2 - input (NC) */ + (0 << 6) | /* GPO3 - input (NC) */ + (0 << 8) | /* GPO4 - input (NC) */ + (0 << 10) | /* GPO5 - input (NC) */ + (0 << 12) | /* GPO6 - input (NC) */ + (0 << 14) | /* GPO7 - input (NC) */ + (0 << 16) | /* GPO8 - input (NC) */ + (0 << 18) | /* GPO9 - input (NC) */ + (0 << 20) | /* GPO10 - input (NC) */ + (0 << 22) | /* GPO11 - input (NC) */ + (0 << 24) | /* GPO12 - input (NC) */ + (0 << 26) | /* GPO13 - input (NC) */ + (0 << 28) | /* GPO14 - input (NC) */ + (0 << 30) /* GPO15 - input (NC) */ ; - __REG(GPOPUD) = 0; /* all pullup and pulldown disabled */ + __REG(GPOPUD) = 0x55555550; /* all NC pulldown */ __REG(GPODAT) = (1 << 15); /* assert CAM_PWRDN */ @@ -690,25 +697,25 @@ void port_init_om_3d7k(void) /* ---------------------------- Port P ---------------------------- */ __REG(GPPCON) = - (1 << 0) | /* GPP0 - OUTPUT (NC) */ - (1 << 2) | /* GPP1 - OUTPUT (NC) */ - (1 << 4) | /* GPP2 - OUTPUT (NC) */ - (1 << 6) | /* GPP3 - OUTPUT (NC) */ - (1 << 8) | /* GPP4 - OUTPUT (NC) */ - (1 << 10) | /* GPP5 - OUTPUT (NC) */ - (1 << 12) | /* GPP6 - OUTPUT (NC) */ - (1 << 14) | /* GPP7 - OUTPUT (NC) */ - (1 << 16) | /* GPP8 - OUTPUT (NC) */ - (1 << 18) | /* GPP9 - OUTPUT (NC) */ - (1 << 20) | /* GPP10 - OUTPUT (NC) */ - (1 << 22) | /* GPP11 - OUTPUT (NC) */ - (1 << 24) | /* GPP12 - OUTPUT (NC) */ - (1 << 26) | /* GPP13 - OUTPUT (NC) */ - (1 << 28) | /* GPP14 - OUTPUT (NC) */ - (1 << 30) /* GPP15 - OUTPUT (NC) */ + (0 << 0) | /* GPP0 - input (NC) */ + (0 << 2) | /* GPP1 - input (NC) */ + (0 << 4) | /* GPP2 - input (NC) */ + (0 << 6) | /* GPP3 - input (NC) */ + (0 << 8) | /* GPP4 - input (NC) */ + (0 << 10) | /* GPP5 - input (NC) */ + (0 << 12) | /* GPP6 - input (NC) */ + (0 << 14) | /* GPP7 - input (NC) */ + (0 << 16) | /* GPP8 - input (NC) */ + (0 << 18) | /* GPP9 - input (NC) */ + (0 << 20) | /* GPP10 - input (NC) */ + (0 << 22) | /* GPP11 - input (NC) */ + (0 << 24) | /* GPP12 - input (NC) */ + (0 << 26) | /* GPP13 - input (NC) */ + (0 << 28) | /* GPP14 - input (NC) */ + (0 << 30) /* GPP15 - input (NC) */ ; - __REG(GPPPUD) = 0; /* all pullup and pulldown disabled */ + __REG(GPPPUD) = 0x15555555; /* all pulldown */ __REG(GPPDAT) = 0; /* assert CAM_PWRDN */ @@ -753,25 +760,18 @@ void port_init_om_3d7k(void) /* ---------------------------- 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) */ - (1 << 18) | /* GPQ9 - OUTPUT (NC) */ - (1 << 20) | /* GPQ10 - OUTPUT (NC) */ - (1 << 22) | /* GPQ11 - OUTPUT (NC) */ - (1 << 24) | /* GPQ12 - OUTPUT (NC) */ - (1 << 26) | /* GPQ13 - OUTPUT (NC) */ - (1 << 28) | /* GPQ14 - OUTPUT (NC) */ - (1 << 30) /* GPQ15 - OUTPUT (NC) */ + (0 << 0) | /* GPQ0 - input (NC) */ + (0 << 2) | /* GPQ1 - input (NC) */ + (0 << 4) | /* GPQ2 - input (NC) */ + (0 << 6) | /* GPQ3 - input (NC) */ + (0 << 8) | /* GPQ4 - input (NC) */ + (0 << 10) | /* GPQ5 - input (NC) */ + (0 << 12) | /* GPQ6 - input (NC) */ + (0 << 14) | /* GPQ7 - input (NC) */ + (0 << 16) /* GPQ8 - input (NC) */ ; - __REG(GPQPUD) = 0; /* all pullup and pulldown disabled */ + __REG(GPQPUD) = 0x15555; /* all pulldown */ __REG(GPQDAT) = 0; /* assert CAM_PWRDN */ From 8858f9a2fc94817ffa03f5e62f7b57c1cc6a2da2 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Sat, 7 Mar 2009 07:35:25 +0000 Subject: [PATCH 228/248] qi-3d7k-regulator-suspend-tune.patch Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c | 2 +- qiboot/src/cpu/s3c6410/om_3d7k.c | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c b/qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c index a6bdce1..e181441 100644 --- a/qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c @@ -87,7 +87,7 @@ const struct board_api board_api_om_3d7k = { .get_ui_keys = get_ui_keys_om_3d7k, .commandline_board = "console=tty0 " \ "console=ttySAC3,115200 " \ - "init=/bin/sh " \ + "init=/sbin/init " \ "loglevel=8 " \ "rootdelay=1 no_console_suspend " \ "ro ", diff --git a/qiboot/src/cpu/s3c6410/om_3d7k.c b/qiboot/src/cpu/s3c6410/om_3d7k.c index 72750bb..ba1d2a8 100644 --- a/qiboot/src/cpu/s3c6410/om_3d7k.c +++ b/qiboot/src/cpu/s3c6410/om_3d7k.c @@ -21,13 +21,17 @@ const struct pcf50633_init om_3d7k_pcf50633_init[] = { { PCF50633_REG_AUTOENA, 0x01 }, /* always on */ { PCF50633_REG_DOWN1OUT, 0x17 }, /* 1.2V (0x17 * .025V + 0.625V) */ + + /* all of these are down in 3d7k suspend */ + { PCF50633_REG_DOWN1ENA, 0x02 }, /* enabled if GPIO1 = HIGH */ - { PCF50633_REG_LDO1ENA, 0x00 }, /* LCM power on */ - { PCF50633_REG_LDO2ENA, 0x00 }, /* LCM power on */ - { PCF50633_REG_LDO3ENA, 0x01 }, /* Codec power on */ - { PCF50633_REG_LDO4ENA, 0x01 }, /* SD power on */ - { PCF50633_REG_LDO5ENA, 0x00 }, /* LCM power on */ - { PCF50633_REG_LDO6ENA, 0x00 }, /* LCM power on */ + { PCF50633_REG_HCLDOENA, 0x02 }, /* Camera 2.8V power off */ + { PCF50633_REG_LDO1ENA, 0x02 }, /* Gsensor power off */ + { PCF50633_REG_LDO2ENA, 0x02 }, /* Camera 1.5V power off */ + { PCF50633_REG_LDO3ENA, 0x03 }, /* Codec power ON */ + { PCF50633_REG_LDO4ENA, 0x03 }, /* SD power ON */ + { PCF50633_REG_LDO5ENA, 0x02 }, /* BT power off */ + { PCF50633_REG_LDO6ENA, 0x02 }, /* LCM power off */ { PCF50633_REG_INT1M, 0x00 }, { PCF50633_REG_INT2M, 0x00 }, From 45187521a2705269320fc290061e9244b4df0c05 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Sat, 7 Mar 2009 07:35:26 +0000 Subject: [PATCH 229/248] Return-Path: Received: from mail.openmoko.org ([unix socket]) by mail.openmoko.org (Cyrus v2.1.18-IPv6-Debian-2.1.18-5.1) with LMTP; Sat, 07 Mar 2009 06:46:20 +0000 X-Sieve: CMU Sieve 2.2 Return-path: Received: from sita.openmoko.org ([88.198.124.203]) by mail.openmoko.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.63) (envelope-from ) id 1LfqIe-000690-LR for andy@imap.openmoko.org; Sat, 07 Mar 2009 06:46:20 +0000 Received: from localhost ([127.0.0.1] helo=sita.openmoko.org) by sita.openmoko.org with esmtp (Exim 4.63) (envelope-from ) id 1LfqIA-0005iO-2x; Sat, 07 Mar 2009 07:45:50 +0100 Received: from imap.tw.openmoko.org ([59.124.115.149] helo=aakash.openmoko.org) by sita.openmoko.org with esmtp (Exim 4.63) (envelope-from ) id 1LfqI0-0005cg-Rz for openmoko-kernel@lists.openmoko.org; Sat, 07 Mar 2009 07:45:44 +0100 Received: from [172.16.22.173] (helo=abacus-om.tw.openmoko.com ident=Debian-exim) by aakash.openmoko.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.63) (envelope-from ) id 1LfqHA-0007Xa-Eu for openmoko-kernel@lists.openmoko.org; Sat, 07 Mar 2009 14:45:09 +0800 Received: from matt by abacus-om.tw.openmoko.com with local (Exim 4.69) (envelope-from ) id 1Lfqto-0006XS-9X for openmoko-kernel@lists.openmoko.org; Sat, 07 Mar 2009 15:24:44 +0800 From: Matt Hsu To: openmoko-kernel@lists.openmoko.org Date: Sat, 7 Mar 2009 15:24:42 +0800 Message-Id: <1236410684-20364-2-git-send-email-matt_hsu@openmoko.org> X-Mailer: git-send-email 1.5.6.5 In-Reply-To: <1236410684-20364-1-git-send-email-matt_hsu@openmoko.org> References: <1236410684-20364-1-git-send-email-matt_hsu@openmoko.org> X-Spam-Checker-Version: SpamAssassin 3.2.3 (2007-08-08) on sita.openmoko.org X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.2.3 Subject: [PATCH 1/3] qi/om_3d7k: deassert LCM_RESET pin before getting kernel. X-BeenThere: openmoko-kernel@lists.openmoko.org X-Mailman-Version: 2.1.9 Precedence: list List-Id: Discussion regarding the OpenMoko Linux Kernel and boot loader List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: openmoko-kernel-bounces@lists.openmoko.org Errors-To: openmoko-kernel-bounces@lists.openmoko.org Since the reset callback function of probing jbt6k74 is eliminated for some reasons in kernel. In order to support both of LCM driver device, l1k002 and jbt6k74, just issue this reset in qi stage. Signed-off-by: Matt Hsu --- qiboot/src/cpu/s3c6410/om_3d7k.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qiboot/src/cpu/s3c6410/om_3d7k.c b/qiboot/src/cpu/s3c6410/om_3d7k.c index ba1d2a8..18be867 100644 --- a/qiboot/src/cpu/s3c6410/om_3d7k.c +++ b/qiboot/src/cpu/s3c6410/om_3d7k.c @@ -564,7 +564,8 @@ void port_init_om_3d7k(void) __REG(GPKDAT) = (1 << 2) | /* deassert nMODEM_ON */ - (1 << 0) /* deassert nWLAN_POWERON */ + (1 << 0) | /* deassert nWLAN_POWERON */ + (1 << 6) /* deassert LCM_RESET */ ; /* ---------------------------- Port L ---------------------------- */ From 7d85f72dbc663affc50b4533687a187dc14fb24d Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Mon, 9 Mar 2009 08:51:05 +0000 Subject: [PATCH 230/248] clean-backslash-strings.patch We can get rid of quite a few backslashes since in modern C, consecutive strings are concatenated at compile time. Signed-off-by: Werner Almesberger --- qiboot/src/cpu/s3c2410/gta01.c | 38 +++++++++---------- qiboot/src/cpu/s3c2442/gta02.c | 24 ++++++------ .../src/cpu/s3c6410/om_3d7k-steppingstone.c | 10 ++--- .../src/cpu/s3c6410/smdk6410-steppingstone.c | 4 +- 4 files changed, 38 insertions(+), 38 deletions(-) diff --git a/qiboot/src/cpu/s3c2410/gta01.c b/qiboot/src/cpu/s3c2410/gta01.c index 15fc315..0371505 100644 --- a/qiboot/src/cpu/s3c2410/gta01.c +++ b/qiboot/src/cpu/s3c2410/gta01.c @@ -146,13 +146,13 @@ void port_init_gta01(void) *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"\ + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" ); @@ -256,17 +256,17 @@ const struct board_api board_api_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 "\ + .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", @@ -305,7 +305,7 @@ const struct board_api board_api_gta01 = { .block_read = nand_read_ll, .offset_blocks512_if_no_partition = 0x44000 / 512, .filesystem = FS_RAW, - .commandline_append = "rootfstype=jffs2 " \ + .commandline_append = "rootfstype=jffs2 " "root=/dev/mtdblock4 ", }, }, diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index b2671b3..e9bc0a3 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -307,13 +307,13 @@ void port_init_gta02(void) *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"\ + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" ); /* configure MPLL */ *MPLLCON = ((42 << 12) + (1 << 4) + 0); @@ -666,10 +666,10 @@ const struct board_api board_api_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 " \ + .commandline_board = "loglevel=4 " + "console=tty0 " + "console=ttySAC2,115200 " + "init=/sbin/init " "ro ", .commandline_board_debug = " loglevel=8", .noboot = "boot/noboot-GTA02", @@ -709,7 +709,7 @@ const struct board_api board_api_gta02 = { /* NOTE offset below is replaced at runtime */ .offset_blocks512_if_no_partition = 0x80000 / 512, .filesystem = FS_RAW, - .commandline_append = " rootfstype=jffs2 " \ + .commandline_append = " rootfstype=jffs2 " "root=/dev/mtdblock6 ", }, }, diff --git a/qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c b/qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c index e181441..71c57f9 100644 --- a/qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c @@ -85,11 +85,11 @@ const struct board_api board_api_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 " \ + .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 = { diff --git a/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c b/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c index 5bc05f0..c1d991f 100644 --- a/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/smdk6410-steppingstone.c @@ -45,8 +45,8 @@ const struct board_api board_api_smdk6410 = { .get_board_variant = get_board_variant_smdk6410, .is_this_board = is_this_board_smdk6410, .putc = putc_smdk6410, - .commandline_board = "console=ttySAC0,115200 " \ - "loglevel=3 " \ + .commandline_board = "console=ttySAC0,115200 " + "loglevel=3 " "init=/bin/sh ", .commandline_board_debug = " loglevel=8", .noboot = "boot/noboot-SDMK6410", From 9416da3dc7f3ac04ac09d59907fdf3bcaaa27d00 Mon Sep 17 00:00:00 2001 From: Matt Hsu Date: Mon, 9 Mar 2009 08:51:06 +0000 Subject: [PATCH 231/248] qi-3d7k-GPK6-should-be-set-as-output.patch Hi Andy, Sorry, previous patch to enable reset function of LCM is not working stably somehow. :( Since it's pin configuration is input. Attached patch is to set LCM reset pin as output. Cheers, Matt --- qiboot/src/cpu/s3c6410/om_3d7k.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiboot/src/cpu/s3c6410/om_3d7k.c b/qiboot/src/cpu/s3c6410/om_3d7k.c index 18be867..814d4d8 100644 --- a/qiboot/src/cpu/s3c6410/om_3d7k.c +++ b/qiboot/src/cpu/s3c6410/om_3d7k.c @@ -546,7 +546,7 @@ void port_init_om_3d7k(void) (0 << 12) | /* GPK3 - input (NC) */ (0 << 16) | /* GPK4 - input (NC) */ (0 << 20) | /* GPK5 - input (NC) */ - (0 << 24) | /* GPK6 - input (NC) */ + (1 << 24) | /* GPK6 - output */ (0 << 28) /* GPK7 - input (NC) */ ; __REG(GPKCON1) = From 3b3f2857a9c89ba4bfe44cbb11f1f66ec97c7084 Mon Sep 17 00:00:00 2001 From: Christopher Hall Date: Mon, 9 Mar 2009 12:00:57 +0000 Subject: [PATCH 232/248] Possible mistake in qi/6410-partition.sh Hello Andy, I am in the process of making a modified 6410-partition.sh and I wonder if there is a mistake in the VFAT partition size: Shouldn't the "+ $REARSECTORS" in the FATSECTORS calculation be a subtraction, otherwise the backupfs will overlap the space reserved for Qi at the end of the SD Card. Please look at this dif to see what I mean: --- qiboot/6410-partition-sd.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qiboot/6410-partition-sd.sh b/qiboot/6410-partition-sd.sh index d692ed1..81db829 100755 --- a/qiboot/6410-partition-sd.sh +++ b/qiboot/6410-partition-sd.sh @@ -70,8 +70,8 @@ echo "$1 is $SECTORS 512-byte blocks" if [ -z "$4" ] ; then - FATSECTORS=$(( $SECTORS - $EXT3_TOTAL_SECTORS + $REARSECTORS )) - FATMB=$(( $FATSECTORS / 2048 - 16 )) + FATSECTORS=$(( $SECTORS - $EXT3_TOTAL_SECTORS - $REARSECTORS )) + FATMB=$(( $FATSECTORS / 2048 )) echo "Creating VFAT section $FATMB MB" From d823b1732a33fee9a7010c539b3eb1e10a83fee3 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Tue, 10 Mar 2009 09:14:05 +0000 Subject: [PATCH 233/248] qi-3d7k-gate-all-unused-clocks.patch s3c6410 defaults to all clocks up, this leads to 120mA idle current at 5V. Gating all the unused clocks off gets us down to 76mA idle current at 533Mhz CPU clock down to 133MHz only helps by a further ~1.5mA. During these tests camera unit was active with no camera attached, no EDGE. Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/om_3d7k.c | 101 +++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/qiboot/src/cpu/s3c6410/om_3d7k.c b/qiboot/src/cpu/s3c6410/om_3d7k.c index 814d4d8..fc97705 100644 --- a/qiboot/src/cpu/s3c6410/om_3d7k.c +++ b/qiboot/src/cpu/s3c6410/om_3d7k.c @@ -96,6 +96,107 @@ void port_init_om_3d7k(void) { int n; + __REG(HCLK_GATE) = + (0 << 31) | /* 3D unit */ + (1 << 30) | /* reserved */ + (0 << 29) | /* USB host */ + (0 << 28) | /* "security subsystem" */ + (1 << 27) | /* SDMA1 */ + (1 << 26) | /* SDMA0 */ + (0 << 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 */ + (0 << 5) | /* POST0 */ + (0 << 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 */ + (0 << 15) | /* LCD 27MHz */ + (1 << 14) | /* LCD */ + (1 << 13) | /* camera and LCD */ + (0 << 12) | /* POST0 */ + (0 << 11) | /* AUDIO2 */ + (0 << 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) = From e8899ba1e130caf644a34ca6f1004c917b277850 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Wed, 11 Mar 2009 07:32:14 +0000 Subject: [PATCH 234/248] qi-3d7k-suspend-gpio-tune.patch Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/om_3d7k.c | 703 ++++++++++++++----------------- 1 file changed, 315 insertions(+), 388 deletions(-) diff --git a/qiboot/src/cpu/s3c6410/om_3d7k.c b/qiboot/src/cpu/s3c6410/om_3d7k.c index fc97705..f6babed 100644 --- a/qiboot/src/cpu/s3c6410/om_3d7k.c +++ b/qiboot/src/cpu/s3c6410/om_3d7k.c @@ -22,16 +22,18 @@ const struct pcf50633_init om_3d7k_pcf50633_init[] = { { PCF50633_REG_DOWN1OUT, 0x17 }, /* 1.2V (0x17 * .025V + 0.625V) */ - /* all of these are down in 3d7k suspend */ + /* all of these are down in 3d7k suspend except MEMLDO */ { PCF50633_REG_DOWN1ENA, 0x02 }, /* enabled if GPIO1 = HIGH */ - { PCF50633_REG_HCLDOENA, 0x02 }, /* Camera 2.8V power off */ - { PCF50633_REG_LDO1ENA, 0x02 }, /* Gsensor power off */ - { PCF50633_REG_LDO2ENA, 0x02 }, /* Camera 1.5V power off */ - { PCF50633_REG_LDO3ENA, 0x03 }, /* Codec power ON */ - { PCF50633_REG_LDO4ENA, 0x03 }, /* SD power ON */ - { PCF50633_REG_LDO5ENA, 0x02 }, /* BT power off */ - { PCF50633_REG_LDO6ENA, 0x02 }, /* LCM power off */ + { 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 }, @@ -92,6 +94,15 @@ static const struct board_variant board_variants[] = { } }; +#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; @@ -216,24 +227,24 @@ void port_init_om_3d7k(void) __REG(GPADAT) = 0; /* just for determinism */ __REG(GPACONSLP) = - (2 << 0) | /* GPA0 - input */ - (2 << 2) | /* GPA1 - input */ - (2 << 4) | /* GPA2 - input */ - (2 << 6) | /* GPA3 - input */ - (2 << 8) | /* GPA4 - input */ - (2 << 10) | /* GPA5 - input */ - (2 << 12) | /* GPA6 - input */ - (2 << 14) /* GPA7 - input */ + (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) = - (1 << 0) | /* GPA0 - pulldown */ - (1 << 2) | /* GPA1 - pulldown */ - (1 << 4) | /* GPA2 - pulldown */ - (1 << 6) | /* GPA3 - pulldown */ - (1 << 8) | /* GPA4 - pulldown */ - (1 << 10) | /* GPA5 - pulldown */ - (1 << 12) | /* GPA6 - pulldown */ - (1 << 14) /* GPA7 - pulldown */ + (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 ---------------------------- */ @@ -249,71 +260,69 @@ void port_init_om_3d7k(void) ; __REG(GPBPUD) = /* all pullup and pulldown disabled */ - 0 + (SPU << (2 * 2)) /* pullup console rx */ ; __REG(GPBDAT) = 0; /* just for determinism */ __REG(GPBCONSLP) = - (2 << 0) | /* GPB0 - input */ - (2 << 2) | /* GPB1 - input */ - (2 << 4) | /* GPB2 - input */ - (2 << 6) | /* GPB3 - input */ - (2 << 8) | /* GPB4 - input */ - (2 << 10) | /* GPB5 - input */ - (2 << 12) | /* GPB6 - input */ - (2 << 14) /* GPB7 - input */ + (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) = - (1 << 0) | /* GPB0 - pull down */ - (1 << 2) | /* GPB1 - pull down */ - (1 << 4) | /* GPB2 - pull down */ - (1 << 6) | /* GPB3 - pull down */ - (1 << 8) | /* GPB4 - pull down */ - (1 << 10) | /* GPB5 - pull down */ - (1 << 12) | /* GPB6 - pull down */ - (1 << 14) /* GPB7 - pull down */ + (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 */ + (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 */ + (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) = /* all pullup and pulldown disabled */ - (1 << 0) + __REG(GPCPUD) = + (SPD << 0) ; __REG(GPCDAT) = 0; /* just for determinism */ - __REG(GPCCONSLP) = - (2 << 0) | /* GPC0 - input */ - (2 << 2) | /* GPC1 - input */ - (2 << 4) | /* GPC2 - input */ - (2 << 6) | /* GPC3 - input */ - (2 << 8) | /* GPC4 - input */ - (2 << 10) | /* GPC5 - input */ - (2 << 12) | /* GPC6 - input */ - (2 << 14) /* GPC7 - input */ + __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) = - (1 << 0) | /* GPC0 - pull down */ - (1 << 2) | /* GPC1 - pull down */ - (1 << 4) | /* GPC2 - pull down */ - (1 << 6) | /* GPC3 - pull down */ - (1 << 8) | /* GPC4 - pull down */ - (1 << 10) | /* GPC5 - pull down */ - (1 << 12) | /* GPC6 - pull down */ - (1 << 14) /* GPC7 - pull down */ + (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 ---------------------------- */ @@ -331,19 +340,19 @@ void port_init_om_3d7k(void) __REG(GPDDAT) = 0; /* just for determinism */ __REG(GPDCONSLP) = - (2 << 0) | /* GPD0 - input */ - (2 << 2) | /* GPD1 - input */ - (2 << 4) | /* GPD2 - input */ - (2 << 6) | /* GPD3 - input */ - (2 << 8) /* GPD4 - input */ + (S0 << 0) | /* GPD0 */ + (S0 << 2) | /* GPD1 */ + (S0 << 4) | /* GPD2 */ + (S0 << 6) | /* GPD3 */ + (S0 << 8) /* GPD4 */ ; __REG(GPDPUDSLP) = - (1 << 0) | /* GPD0 - pull down */ - (1 << 2) | /* GPD1 - pull down */ - (1 << 4) | /* GPD2 - pull down */ - (1 << 6) | /* GPD3 - pull down */ - (1 << 8) /* GPD4 - pull down */ + (SNP << 0) | /* GPD0 */ + (SNP << 2) | /* GPD1 */ + (SNP << 4) | /* GPD2 */ + (SNP << 6) | /* GPD3 */ + (SNP << 8) /* GPD4 */ ; /* ---------------------------- Port E ---------------------------- */ @@ -361,19 +370,19 @@ void port_init_om_3d7k(void) __REG(GPEDAT) = 0; /* just for determinism */ __REG(GPECONSLP) = - (2 << 0) | /* GPE0 - input */ - (2 << 2) | /* GPE1 - input */ - (2 << 4) | /* GPE2 - input */ - (2 << 6) | /* GPE3 - input */ - (2 << 8) /* GPE4 - input */ + (S0 << 0) | /* GPE0 */ + (S0 << 2) | /* GPE1 */ + (S0 << 4) | /* GPE2 */ + (S0 << 6) | /* GPE3 */ + (S0 << 8) /* GPE4 */ ; __REG(GPEPUDSLP) = - (1 << 0) | /* GPE0 - pull down */ - (1 << 2) | /* GPE1 - pull down */ - (1 << 4) | /* GPE2 - pull down */ - (1 << 6) | /* GPE3 - pull down */ - (1 << 8) /* GPE4 - pull down */ + (SNP << 0) | /* GPE0 */ + (SNP << 2) | /* GPE1 */ + (SNP << 4) | /* GPE2 */ + (SNP << 6) | /* GPE3 */ + (SNP << 8) /* GPE4 */ ; /* ---------------------------- Port F ---------------------------- */ @@ -397,37 +406,38 @@ void port_init_om_3d7k(void) (1 << 30) /* GPF15 - OUTPUT CAM_PWRDN */ ; - __REG(GPFPUD) = (1 << (2 * 12)) | (1 << (2 * 11)) | (1 << (2 * 10)) | - (1 << (2 * 9)) | (1 << (2 * 8)) | (1 << (2 * 7)) | - (1 << (2 * 6)) | (1 << (2 * 5)); /* all cam data pulldown */ + __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) = - (2 << 0) | /* GPF0 - input */ - (2 << 2) | /* GPF1 - input */ - (2 << 4) | /* GPF2 - input */ - (2 << 6) | /* GPF3 - input */ - (2 << 8) | /* GPF4 - input */ - (2 << 10) | /* GPF5 - input */ - (2 << 12) | /* GPF6 - input */ - (2 << 14) | /* GPF7 - input */ - (2 << 16) | /* GPF8 - input */ - (2 << 18) | /* GPF9 - input */ - (2 << 20) | /* GPF10 - input */ - (2 << 22) | /* GPF11 - input */ - (2 << 24) | /* GPF12 - input */ - (2 << 26) | /* GPF13 - input */ - (2 << 28) | /* GPF14 - input */ - (2 << 30) /* GPF15 - input */ + (S0 << 0) | /* GPF0 */ + (S0 << 2) | /* GPF1 */ + (S0 << 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) = - (1 << 0) | /* GPF0 - pull down */ - (1 << 2) | /* GPF1 - pull down */ - (1 << 4) | /* GPF2 - pull down */ - (1 << 6) | /* GPF3 - pull down */ - (1 << 8) | /* GPF4 - pull down */ (1 << 10) | /* GPF5 - pull down */ (1 << 12) | /* GPF6 - pull down */ (1 << 14) | /* GPF7 - pull down */ @@ -435,10 +445,7 @@ void port_init_om_3d7k(void) (1 << 18) | /* GPF9 - pull down */ (1 << 20) | /* GPF10 - pull down */ (1 << 22) | /* GPF11 - pull down */ - (1 << 24) | /* GPF12 - pull down */ - (1 << 26) | /* GPF13 - pull down */ - (1 << 28) | /* GPF14 - pull down */ - (1 << 30) /* GPF15 - pull down */ + (1 << 24) /* GPF12 - pull down */ ; /* ---------------------------- Port G ---------------------------- */ @@ -458,71 +465,52 @@ void port_init_om_3d7k(void) __REG(GPGDAT) = 0; /* just for determinism */ __REG(GPGCONSLP) = - (2 << 0) | /* GPG0 - input */ - (2 << 2) | /* GPG1 - input */ - (2 << 4) | /* GPG2 - input */ - (2 << 6) | /* GPG3 - input */ - (2 << 8) | /* GPG4 - input */ - (2 << 10) | /* GPG5 - input */ - (2 << 12) /* GPG6 - input */ + (S0 << 0) | /* GPG0 - it's not powered*/ + (S0 << 2) | /* GPG1 */ + (S0 << 4) | /* GPG2 */ + (S0 << 6) | /* GPG3 */ + (S0 << 8) | /* GPG4 */ + (S0 << 10) | /* GPG5 */ + (S0 << 12) /* GPG6 */ ; - __REG(GPGPUDSLP) = - (1 << 0) | /* GPG0 - pull down */ - (1 << 2) | /* GPG1 - pull down */ - (1 << 4) | /* GPG2 - pull down */ - (1 << 6) | /* GPG3 - pull down */ - (1 << 8) | /* GPG4 - pull down */ - (1 << 10) | /* GPG5 - pull down */ - (1 << 12) /* GPG6 - pull down */ - ; + __REG(GPGPUDSLP) = 0; /* ---------------------------- Port H ---------------------------- */ __REG(GPHCON0) = - (0 << 0) | /* GPH0 - NC OUT 0 */ - (0 << 4) | /* GPH1 - NC OUT 0 */ - (0 << 8) | /* GPH2 - NC OUT 0 */ - (0 << 12) | /* GPH3 - NC OUT 0 */ - (0 << 16) | /* GPH4 - NC OUT 0 */ - (0 << 20) | /* GPH5 - NC OUT 0 */ - (1 << 24) | /* GPH6 - OUTPUT nWLAN_RESET */ - (1 << 28) /* GPH7 - OUTPUT HDQ */ + (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 nWLAN_PD */ - (0 << 4) /* GPH9 - OUTPUT (NC) */ + (1 << 0) | /* GPH8 - OUTPUT BT PIO5 */ + (0 << 4) /* GPH9 - INPUT LED INT */ ; - __REG(GPHPUD) = 0x40555; /* all NC pulldown */ + __REG(GPHPUD) = (SPU << (9 * 2)) | (SPU << (7 * 2)); __REG(GPHDAT) = 0; __REG(GPHCONSLP) = - (2 << 0) | /* GPH0 - input */ - (2 << 2) | /* GPH1 - input */ - (2 << 4) | /* GPH2 - input */ - (2 << 6) | /* GPH3 - input */ - (2 << 8) | /* GPH4 - input */ - (2 << 10) | /* GPH5 - input */ - (2 << 12) | /* GPH6 - input */ - (2 << 14) | /* GPH7 - INPUT (HDQ) */ - (2 << 16) | /* GPH8 - input */ - (2 << 18) /* GPH9 - input */ + (S0 << 0) | /* GPH0 */ + (S0 << 2) | /* GPH1 */ + (S0 << 4) | /* GPH2 */ + (S0 << 6) | /* GPH3 */ + (S0 << 8) | /* GPH4 */ + (S0 << 10) | /* GPH5 */ + (S0 << 12) | /* GPH6 */ + (SHOLD << 14) | /* GPH7 - INPUT (HDQ) */ + (S0 << 16) | /* GPH8 */ + (SIN << 18) /* GPH9 */ ; - __REG(GPHPUDSLP) = - (1 << 0) | /* GPH0 - pull down */ - (1 << 2) | /* GPH1 - pull down */ - (1 << 4) | /* GPH2 - pull down */ - (1 << 6) | /* GPH3 - pull down */ - (1 << 8) | /* GPH4 - pull down */ - (1 << 10) | /* GPH5 - pull down */ - (2 << 12) | /* GPH6 - PULLUP (HDQ) */ - (1 << 14) | /* GPH7 - pull down */ - (1 << 16) | /* GPH8 - pull down */ - (1 << 18) /* GPH9 - pull down */ - ; + __REG(GPHPUDSLP) = (SPU << (9 * 2)); /* ---------------------------- Port I ---------------------------- */ @@ -550,41 +538,28 @@ void port_init_om_3d7k(void) __REG(GPIDAT) = 0; /* just for determinism */ __REG(GPICONSLP) = - (2 << 0) | /* GPI0 - input */ - (2 << 2) | /* GPI1 - input */ - (2 << 4) | /* GPI2 - input */ - (2 << 6) | /* GPI3 - input */ - (2 << 8) | /* GPI4 - input */ - (2 << 10) | /* GPI5 - input */ - (2 << 12) | /* GPI6 - input */ - (2 << 14) | /* GPI7 - input */ - (2 << 16) | /* GPI8 - input */ - (2 << 18) | /* GPI9 - input */ - (2 << 20) | /* GPI10 - input */ - (2 << 22) | /* GPI11 - input */ - (2 << 24) | /* GPI12 - input */ - (2 << 26) | /* GPI13 - input */ - (2 << 28) | /* GPI14 - input */ - (2 << 30) /* GPI15 - input */ + (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 << 4) | /* GPI2 - pull down */ - (1 << 6) | /* GPI3 - pull down */ - (1 << 8) | /* GPI4 - pull down */ - (1 << 10) | /* GPI5 - pull down */ - (1 << 12) | /* GPI6 - pull down */ - (1 << 14) | /* GPI7 - pull down */ - (1 << 16) | /* GPI8 - pull down */ - (1 << 18) | /* GPI9 - pull down */ - (1 << 20) | /* GPI10 - pull down */ - (1 << 22) | /* GPI11 - pull down */ - (1 << 24) | /* GPI12 - pull down */ - (1 << 26) | /* GPI13 - pull down */ - (1 << 28) | /* GPI14 - pull down */ - (1 << 30) /* GPI15 - pull down */ + (1 << 16) /* GPI8 - pull down */ ; /* ---------------------------- Port J ---------------------------- */ @@ -609,77 +584,68 @@ void port_init_om_3d7k(void) __REG(GPJDAT) = 0; /* just for determinism */ __REG(GPJCONSLP) = - (2 << 0) | /* GPJ0 - input */ - (2 << 2) | /* GPJ1 - input */ - (2 << 4) | /* GPJ2 - input */ - (2 << 6) | /* GPJ3 - input */ - (2 << 8) | /* GPJ4 - input */ - (2 << 10) | /* GPJ5 - input */ - (2 << 12) | /* GPJ6 - input */ - (2 << 14) | /* GPJ7 - input */ - (2 << 16) | /* GPJ8 - input */ - (2 << 18) | /* GPJ9 - input */ - (2 << 20) | /* GPJ10 - input */ - (2 << 22) /* GPJ11 - input */ + (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) = - (1 << 0) | /* GPJ0 - pull down */ - (1 << 2) | /* GPJ1 - pull down */ - (1 << 4) | /* GPJ2 - pull down */ - (1 << 6) | /* GPJ3 - pull down */ - (1 << 8) | /* GPJ4 - pull down */ - (1 << 10) | /* GPJ5 - pull down */ - (1 << 12) | /* GPJ6 - pull down */ - (1 << 14) | /* GPJ7 - pull down */ - (1 << 16) | /* GPJ8 - pull down */ - (1 << 18) | /* GPJ9 - pull down */ - (1 << 20) | /* GPJ10 - pull down */ - (1 << 22) /* GPJ11 - pull down */ + 0 ; /* ---------------------------- Port K ---------------------------- */ __REG(GPKCON0) = - (1 << 0) | /* GPK0 - OUTPUT nWLAN_POWERON */ - (0 << 4) | /* GPK1 - input (NC) */ + (1 << 0) | /* GPK0 - OUTPUT NC */ + (1 << 4) | /* GPK1 - OUTPUT NC */ (1 << 8) | /* GPK2 - OUTPUT (nMODEM_ON) */ - (0 << 12) | /* GPK3 - input (NC) */ - (0 << 16) | /* GPK4 - input (NC) */ - (0 << 20) | /* GPK5 - input (NC) */ - (1 << 24) | /* GPK6 - output */ - (0 << 28) /* GPK7 - input (NC) */ + + (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) = - (0 << 0) | /* GPK8 - input (NC) */ - (0 << 4) | /* GPK9 - input (NC) */ - (0 << 8) | /* GPK10 - input (NC) */ - (0 << 12) | /* GPK11 - input (NC) */ - (0 << 16) | /* GPK12 - input (NC) */ - (0 << 20) | /* GPK13 - input (NC) */ - (0 << 24) | /* GPK14 - input (NC) */ - (0 << 28) /* GPK15 - input (NC) */ + (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) = 0x55555544; /* all input pulldown */ + __REG(GPKPUD) = 0; - __REG(GPKDAT) = - (1 << 2) | /* deassert nMODEM_ON */ - (1 << 0) | /* deassert nWLAN_POWERON */ - (1 << 6) /* deassert LCM_RESET */ + __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) = - (0 << 0) | /* GPL0 - OUTPUT (NC) */ - (0 << 4) | /* GPL1 - OUTPUT (NC) */ - (0 << 8) | /* GPL2 - OUTPUT (NC) */ - (0 << 12) | /* GPL3 - OUTPUT (NC) */ - (0 << 16) | /* GPL4 - OUTPUT (NC) */ - (0 << 20) | /* GPL5 - OUTPUT (NC) */ - (0 << 24) | /* GPL6 - OUTPUT (NC) */ - (0 << 28) /* GPL7 - OUTPUT (NC) */ + (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) */ @@ -691,7 +657,7 @@ void port_init_om_3d7k(void) (1 << 24) /* GPL14 - OUTPUT (NC) */ ; - __REG(GPLPUD) = 0x5555; /* all pullup and pulldown disabled */ + __REG(GPLPUD) = 0; /* all pullup and pulldown disabled */ __REG(GPLDAT) = 0; @@ -701,7 +667,7 @@ void port_init_om_3d7k(void) __REG(GPMCON) = (1 << 0) | /* GPM0 - OUTPUT (TP_RESET) */ (1 << 4) | /* GPM1 - OUTPUT (NC) */ - (1 << 8) | /* GPM2 - OUTPUT (GPS_LNA_EN) */ + (1 << 8) | /* GPM2 - OUTPUT (NC) */ (1 << 12) | /* GPM3 - OUTPUT (NC) */ (0 << 16) | /* GPM4 - INPUT (nUSB_FLT) */ (0 << 20) /* GPM5 - INPUT (nUSB_OC) */ @@ -721,7 +687,7 @@ void port_init_om_3d7k(void) (2 << 8) | /* GPN4 - EXINT4 PWR_IRQ */ (2 << 10) | /* GPN5 - EXINT5 nTOUCH */ (2 << 12) | /* GPN6 - EXINT6 nJACK_INSERT */ - (2 << 14) | /* GPN7 - EXINT7 GPS_INT */ + (1 << 14) | /* GPN7 - EXINT7 NC OUTPUT */ (2 << 16) | /* GPN8 - EXINT8 nHOLD */ (2 << 18) | /* GPN9 - EXINT9 WLAN_WAKEUP */ (2 << 20) | /* GPN10 - EXINT10 nG1INT2 */ @@ -732,7 +698,24 @@ void port_init_om_3d7k(void) (0 << 30) /* GPN15 - INPUT (iROM CFG2) */ ; - __REG(GPNPUD) = 0; /* all pullup and pulldown disabled */ + __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; @@ -742,182 +725,126 @@ void port_init_om_3d7k(void) __REG(GPOCON) = (2 << 0) | /* GPO0 - XM0CS2 (nNANDCS0) */ (1 << 2) | /* GPO1 - OUTPUT (nMODEM_RESET) */ - (0 << 4) | /* GPO2 - input (NC) */ - (0 << 6) | /* GPO3 - input (NC) */ - (0 << 8) | /* GPO4 - input (NC) */ - (0 << 10) | /* GPO5 - input (NC) */ - (0 << 12) | /* GPO6 - input (NC) */ - (0 << 14) | /* GPO7 - input (NC) */ - (0 << 16) | /* GPO8 - input (NC) */ - (0 << 18) | /* GPO9 - input (NC) */ - (0 << 20) | /* GPO10 - input (NC) */ - (0 << 22) | /* GPO11 - input (NC) */ - (0 << 24) | /* GPO12 - input (NC) */ - (0 << 26) | /* GPO13 - input (NC) */ - (0 << 28) | /* GPO14 - input (NC) */ - (0 << 30) /* GPO15 - input (NC) */ + (1 << 4) | /* GPO2 - input (NC) */ + (1 << 6) | /* GPO3 - input (NC) */ + (1 << 8) | /* GPO4 - input (NC) */ + (1 << 10) | /* GPO5 - input (NC) */ + (1 << 12) | /* GPO6 - input (NC) */ + (1 << 14) | /* GPO7 - input (NC) */ + (1 << 16) | /* GPO8 - input (NC) */ + (1 << 18) | /* GPO9 - input (NC) */ + (1 << 20) | /* GPO10 - input (NC) */ + (1 << 22) | /* GPO11 - input (NC) */ + (1 << 24) | /* GPO12 - input (NC) */ + (1 << 26) | /* GPO13 - input (NC) */ + (1 << 28) | /* GPO14 - input (NC) */ + (1 << 30) /* GPO15 - input (NC) */ ; - __REG(GPOPUD) = 0x55555550; /* all NC pulldown */ + __REG(GPOPUD) = 0; /* no pulling */ __REG(GPODAT) = (1 << 15); /* assert CAM_PWRDN */ __REG(GPOCONSLP) = - (3 << 0) | /* GPO0 - hold state */ - (1 << 2) | /* GPO1 - OUTPUT 1 (do not reset modem) */ - (0 << 4) | /* GPO2 - OUTPUT 0 */ - (0 << 6) | /* GPO3 - OUTPUT 0 */ - (0 << 8) | /* GPO4 - OUTPUT 0 */ - (0 << 10) | /* GPO5 - OUTPUT 0 */ - (0 << 12) | /* GPO6 - OUTPUT 0 */ - (0 << 14) | /* GPO7 - OUTPUT 0 */ - (0 << 16) | /* GPO8 - OUTPUT 0 */ - (0 << 18) | /* GPO9 - OUTPUT 0 */ - (0 << 20) | /* GPO10 - OUTPUT 0 */ - (0 << 22) | /* GPO11 - OUTPUT 0 */ - (0 << 24) | /* GPO12 - OUTPUT 0 */ - (0 << 26) | /* GPO13 - OUTPUT 0 */ - (0 << 28) | /* GPO14 - OUTPUT 0 */ - (0 << 30) /* GPO15 - OUTPUT 0 */ + (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 << 0) | /* GPO0 - no pull up or down */ - (0 << 2) | /* GPO1 - no pull up or down */ - (0 << 4) | /* GPO2 - no pull up or down */ - (0 << 6) | /* GPO3 - no pull up or down */ - (0 << 8) | /* GPO4 - no pull up or down */ - (0 << 10) | /* GPO5 - no pull up or down */ - (0 << 12) | /* GPO6 - no pull up or down */ - (0 << 14) | /* GPO7 - no pull up or down */ - (0 << 16) | /* GPO8 - no pull up or down */ - (0 << 18) | /* GPO9 - no pull up or down */ - (0 << 20) | /* GPO10 - no pull up or down */ - (0 << 22) | /* GPO11 - no pull up or down */ - (0 << 24) | /* GPO12 - no pull up or down */ - (0 << 26) | /* GPO13 - no pull up or down */ - (0 << 28) | /* GPO14 - no pull up or down */ - (0 << 30) /* GPO15 - no pull up or down */ + 0 ; /* ---------------------------- Port P ---------------------------- */ __REG(GPPCON) = - (0 << 0) | /* GPP0 - input (NC) */ - (0 << 2) | /* GPP1 - input (NC) */ - (0 << 4) | /* GPP2 - input (NC) */ - (0 << 6) | /* GPP3 - input (NC) */ - (0 << 8) | /* GPP4 - input (NC) */ - (0 << 10) | /* GPP5 - input (NC) */ - (0 << 12) | /* GPP6 - input (NC) */ - (0 << 14) | /* GPP7 - input (NC) */ - (0 << 16) | /* GPP8 - input (NC) */ - (0 << 18) | /* GPP9 - input (NC) */ - (0 << 20) | /* GPP10 - input (NC) */ - (0 << 22) | /* GPP11 - input (NC) */ - (0 << 24) | /* GPP12 - input (NC) */ - (0 << 26) | /* GPP13 - input (NC) */ - (0 << 28) | /* GPP14 - input (NC) */ - (0 << 30) /* GPP15 - input (NC) */ + (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) */ + (1 << 30) /* GPP15 - input (NC) */ ; - __REG(GPPPUD) = 0x15555555; /* all pulldown */ + __REG(GPPPUD) = 0; /* no pull */ - __REG(GPPDAT) = 0; /* assert CAM_PWRDN */ + __REG(GPPDAT) = 0; __REG(GPPCONSLP) = - (0 << 0) | /* GPP0 - OUTPUT 0 */ - (0 << 2) | /* GPP1 - OUTPUT 0 */ - (0 << 4) | /* GPP2 - OUTPUT 0 */ - (0 << 6) | /* GPP3 - OUTPUT 0 */ - (0 << 8) | /* GPP4 - OUTPUT 0 */ - (0 << 10) | /* GPP5 - OUTPUT 0 */ - (0 << 12) | /* GPP6 - OUTPUT 0 */ - (0 << 14) | /* GPP7 - OUTPUT 0 */ - (0 << 16) | /* GPP8 - OUTPUT 0 */ - (0 << 18) | /* GPP9 - OUTPUT 0 */ - (0 << 20) | /* GPP10 - OUTPUT 0 */ - (0 << 22) | /* GPP11 - OUTPUT 0 */ - (0 << 24) | /* GPP12 - OUTPUT 0 */ - (0 << 26) | /* GPP13 - OUTPUT 0 */ - (0 << 28) | /* GPP14 - OUTPUT 0 */ - (0 << 30) /* GPP15 - OUTPUT 0 */ + (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 */ + (S0 << 30) /* GPP15 - OUTPUT 0 */ ; - __REG(GPPPUDSLP) = - (0 << 0) | /* GPP0 - no pull up or down */ - (0 << 2) | /* GPP1 - no pull up or down */ - (0 << 4) | /* GPP2 - no pull up or down */ - (0 << 6) | /* GPP3 - no pull up or down */ - (0 << 8) | /* GPP4 - no pull up or down */ - (0 << 10) | /* GPP5 - no pull up or down */ - (0 << 12) | /* GPP6 - no pull up or down */ - (0 << 14) | /* GPP7 - no pull up or down */ - (0 << 16) | /* GPP8 - no pull up or down */ - (0 << 18) | /* GPP9 - no pull up or down */ - (0 << 20) | /* GPP10 - no pull up or down */ - (0 << 22) | /* GPP11 - no pull up or down */ - (0 << 24) | /* GPP12 - no pull up or down */ - (0 << 26) | /* GPP13 - no pull up or down */ - (0 << 28) | /* GPP14 - no pull up or down */ - (0 << 30) /* GPP15 - no pull up or down */ - ; + __REG(GPPPUDSLP) = 0; /* ---------------------------- Port Q ---------------------------- */ __REG(GPQCON) = - (0 << 0) | /* GPQ0 - input (NC) */ - (0 << 2) | /* GPQ1 - input (NC) */ - (0 << 4) | /* GPQ2 - input (NC) */ - (0 << 6) | /* GPQ3 - input (NC) */ - (0 << 8) | /* GPQ4 - input (NC) */ - (0 << 10) | /* GPQ5 - input (NC) */ - (0 << 12) | /* GPQ6 - input (NC) */ - (0 << 14) | /* GPQ7 - input (NC) */ - (0 << 16) /* GPQ8 - input (NC) */ + (1 << 0) | /* GPQ0 - input (NC) */ + (1 << 2) | /* GPQ1 - input (NC) */ + (1 << 4) | /* GPQ2 - input (NC) */ + (1 << 6) | /* GPQ3 - input (NC) */ + (1 << 8) | /* GPQ4 - input (NC) */ + (1 << 10) | /* GPQ5 - input (NC) */ + (1 << 12) | /* GPQ6 - input (NC) */ + (1 << 14) | /* GPQ7 - input (NC) */ + (1 << 16) /* GPQ8 - input (NC) */ ; - __REG(GPQPUD) = 0x15555; /* all pulldown */ + __REG(GPQPUD) = 0; /* all pulldown */ __REG(GPQDAT) = 0; /* assert CAM_PWRDN */ __REG(GPQCONSLP) = - (0 << 0) | /* GPQ0 - OUTPUT 0 */ - (0 << 2) | /* GPQ1 - OUTPUT 0 */ - (0 << 4) | /* GPQ2 - OUTPUT 0 */ - (0 << 6) | /* GPQ3 - OUTPUT 0 */ - (0 << 8) | /* GPQ4 - OUTPUT 0 */ - (0 << 10) | /* GPQ5 - OUTPUT 0 */ - (0 << 12) | /* GPQ6 - OUTPUT 0 */ - (0 << 14) | /* GPQ7 - OUTPUT 0 */ - (0 << 16) | /* GPQ8 - OUTPUT 0 */ - (0 << 18) | /* GPQ9 - OUTPUT 0 */ - (0 << 20) | /* GPQ10 - OUTPUT 0 */ - (0 << 22) | /* GPQ11 - OUTPUT 0 */ - (0 << 24) | /* GPQ12 - OUTPUT 0 */ - (0 << 26) | /* GPQ13 - OUTPUT 0 */ - (0 << 28) | /* GPQ14 - OUTPUT 0 */ - (0 << 30) /* GPQ15 - OUTPUT 0 */ + (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 << 0) | /* GPQ0 - no pull up or down */ - (0 << 2) | /* GPQ1 - no pull up or down */ - (0 << 4) | /* GPQ2 - no pull up or down */ - (0 << 6) | /* GPQ3 - no pull up or down */ - (0 << 8) | /* GPQ4 - no pull up or down */ - (0 << 10) | /* GPQ5 - no pull up or down */ - (0 << 12) | /* GPQ6 - no pull up or down */ - (0 << 14) | /* GPQ7 - no pull up or down */ - (0 << 16) | /* GPQ8 - no pull up or down */ - (0 << 18) | /* GPQ9 - no pull up or down */ - (0 << 20) | /* GPQ10 - no pull up or down */ - (0 << 22) | /* GPQ11 - no pull up or down */ - (0 << 24) | /* GPQ12 - no pull up or down */ - (0 << 26) | /* GPQ13 - no pull up or down */ - (0 << 28) | /* GPQ14 - no pull up or down */ - (0 << 30) /* GPQ15 - no pull up or down */ - ; + __REG(GPQPUDSLP) = 0; /* LCD Controller enable */ From 8b75ed7105c3745060190cf30f49607fb3fd31e4 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Wed, 11 Mar 2009 07:32:15 +0000 Subject: [PATCH 235/248] qi-3d7k-additional-power-reg-config.patch Signed-off-by: Andy Green --- qiboot/include/s3c6410.h | 4 +++- qiboot/src/cpu/s3c6410/om_3d7k.c | 34 ++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/qiboot/include/s3c6410.h b/qiboot/include/s3c6410.h index a11fbec..6689bfa 100644 --- a/qiboot/include/s3c6410.h +++ b/qiboot/include/s3c6410.h @@ -174,6 +174,7 @@ typedef enum { #define NOR_CFG_OFFSET 0x810 #define STOP_CFG_OFFSET 0x814 #define SLEEP_CFG_OFFSET 0x818 +#define STOP_MEM_CFG_OFFSET 0x81c #define OSC_FREQ_OFFSET 0x820 #define OSC_STABLE_OFFSET 0x824 #define PWR_STABLE_OFFSET 0x828 @@ -226,7 +227,7 @@ typedef enum { #define PWR_CFG_REG __REG(ELFIN_CLOCK_POWER_BASE+PWR_CFG_OFFSET) #define EINT_MASK_REG __REG(ELFIN_CLOCK_POWER_BASE+EINT_MASK_OFFSET) #define NOR_CFG_REG __REG(ELFIN_CLOCK_POWER_BASE+NOR_CFG_OFFSET) -#define STOP_CFG_REG __REG(ELFIN_CLOCK_POWER_BASE+STOP_CFG_OFFSET) +#define STOP_MEM_CFG_REG __REG(ELFIN_CLOCK_POWER_BASE+STOP_MEM_CFG_OFFSET) #define SLEEP_CFG_REG __REG(ELFIN_CLOCK_POWER_BASE+SLEEP_CFG_OFFSET) #define OSC_FREQ_REG __REG(ELFIN_CLOCK_POWER_BASE+OSC_FREQ_OFFSET) #define OSC_CNT_VAL_REG __REG(ELFIN_CLOCK_POWER_BASE+OSC_CNT_VAL_OFFSET) @@ -276,6 +277,7 @@ typedef enum { #define NOR_CFG (ELFIN_CLOCK_POWER_BASE+NOR_CFG_OFFSET) #define STOP_CFG (ELFIN_CLOCK_POWER_BASE+STOP_CFG_OFFSET) #define SLEEP_CFG (ELFIN_CLOCK_POWER_BASE+SLEEP_CFG_OFFSET) +#define STOP_MEM_CFG (ELFIN_CLOCK_POWER_BASE+STOP_MEM_CFG_OFFSET) #define OSC_FREQ (ELFIN_CLOCK_POWER_BASE+OSC_FREQ_OFFSET) #define OSC_CNT_VAL (ELFIN_CLOCK_POWER_BASE+OSC_CNT_VAL_OFFSET) #define PWR_CNT_VAL (ELFIN_CLOCK_POWER_BASE+PWR_CNT_VAL_OFFSET) diff --git a/qiboot/src/cpu/s3c6410/om_3d7k.c b/qiboot/src/cpu/s3c6410/om_3d7k.c index f6babed..ce9db6b 100644 --- a/qiboot/src/cpu/s3c6410/om_3d7k.c +++ b/qiboot/src/cpu/s3c6410/om_3d7k.c @@ -107,6 +107,39 @@ void port_init_om_3d7k(void) { int n; + __REG(PWR_CFG) = + (0 << 17) | /* kill OSCotg clock pad */ + (1 << 10) | /* RTC alarm wakeup source */ + (0 << 0) /* 27MHz osc off */ + ; + + __REG(STOP_MEM_CFG) = + (0 << 6) | /* modem */ + (0 << 5) | /* host IF */ + (1 << 4) | /* OTG */ + (1 << 3) | /* HSMMC */ + (0 << 2) | /* iROM */ + (0 << 1) | /* IRDA */ + (1 << 0) /* NFCON / steppingstone */ + ; + + __REG(NOR_CFG) = + (1 << 31) | /* reserved */ + (0 << 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 */ @@ -208,6 +241,7 @@ void port_init_om_3d7k(void) (1 << 0) /* reserved */ ; + /* ---------------------------- Port A ---------------------------- */ __REG(GPACON) = From 683fc5a92ae9a591fd1c25fd3cb65e461c970462 Mon Sep 17 00:00:00 2001 From: Christopher Hall Date: Wed, 11 Mar 2009 07:32:15 +0000 Subject: [PATCH 236/248] My revised version of the partition tool The fdisk and mkfs was factored out into a shell function so that it is easier to create dirfferent partition layouts. The default case was left the same as the original script The partitions can be specified as percentages of the available space (after Qi reserved space has been taken out) by providing a comma separated list of values: e.g. 25,0,50 Which would create partitions 1 and 3 with 25% and 50% of the usable capacity. Partitions 2 and 4 would not be assigned. Signed-off-by: Christopher Hall --- qiboot/6410-partition-sd.sh | 301 +++++++++++++++++++++++++++--------- 1 file changed, 225 insertions(+), 76 deletions(-) diff --git a/qiboot/6410-partition-sd.sh b/qiboot/6410-partition-sd.sh index 81db829..8dd5f30 100755 --- a/qiboot/6410-partition-sd.sh +++ b/qiboot/6410-partition-sd.sh @@ -3,7 +3,7 @@ # (C) 2008 Openmoko, Inc # Author: Andy Green -# LAYOUT +# LAYOUT (if partition parameter is not specified) # Partition table, then # VFAT takes up remaining space here # then... @@ -13,7 +13,7 @@ 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" @@ -24,109 +24,258 @@ echo QI_INITIAL=$(( 8 * 2 )) SIG=1 -FDISK_SCRIPT=/tmp/_fds -if [ -z "$1" -o -z "$2" -o -z "$3" ] ; then - echo "This formats a SD card for usage on SD Card boot" - echo " on 6410 based systems" +# display usage message and exit +# any arguments are displayed as an error message +USAGE() +{ echo - echo "Usage:" + [ -z "$1" ] || echo ERROR: $* echo - echo "$0 " + echo 'This formats a SD card for usage on SD Card boot' + echo ' on 6410 based systems' + echo + echo Usage: $(basename "$0") ' ' + 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 -fi +} -if [ $2 = "sdhc" ] ; then -PADDING=1025 -else -PADDING=1 -fi +[ -z "$1" -o -z "$2" -o -z "$3" ] && USAGE 'Missing arguments' -EXT3_TOTAL_SECTORS=$(( $EXT3_ROOTFS_SECTORS + $EXT3_BACKUP_FS_SECTORS )) -REARSECTORS=$(( $QI_ALLOCATION + $QI_INITIAL + $SIG + $PADDING )) +dev="$1" +card="$2" +qi="$3" +partition="$4" -if [ ! -z "`grep $1 /proc/mounts`" ] ; then - echo "ERROR $1 seems to be mounted, that ain't right" - exit 2 -fi +case "${card}" in + [sS][dD][hH][cC]) + PADDING=1025 + ;; + [sS][dD]) + PADDING=1 + ;; + *) + USAGE "${card} is an unknown card type" +esac -bytes=`echo p | fdisk /dev/$1 2>&1 | sed '/^Disk.*, \([0-9]*\) bytes/s//\1/p;d'` -echo bytes = $bytes +# the amount of space that must remain unused at the end of the disk +REAR_SECTORS=$(( $QI_ALLOCATION + $QI_INITIAL + $SIG + $PADDING )) -SECTORS=`expr $bytes / 512` +# 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]}" -if [ -z "$SECTORS" ] ; then - echo "problem finding size for /dev/$1" - exit 4 -fi +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" -if [ "$SECTORS" -le 0 ] ; then - echo "problem finding size for /dev/$1" - exit 3 -fi +# get size of device +bytes=$(echo p | fdisk "${dev}" 2>&1 | sed '/^Disk.*, \([0-9]*\) bytes/s//\1/p;d') +SECTORS=$(($bytes / 512)) -echo "$1 is $SECTORS 512-byte blocks" +[ -z "$SECTORS" ] && USAGE "could not find size for ${dev}" +[ "$SECTORS" -le 0 ] && USAGE "invalid size: '${SECTORS}' for ${dev}" -if [ -z "$4" ] ; then +echo "${dev} is $SECTORS 512-byte blocks" - FATSECTORS=$(( $SECTORS - $EXT3_TOTAL_SECTORS - $REARSECTORS )) - FATMB=$(( $FATSECTORS / 2048 )) +# 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 - echo "Creating VFAT section $FATMB MB" +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 - # create the script for fdisk - # clear the existing partition table - echo "o" >$FDISK_SCRIPT + 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 +} - # add main VFAT storage partition - echo "n" >>$FDISK_SCRIPT - echo "p" >>$FDISK_SCRIPT - echo "1" >>$FDISK_SCRIPT - # first partition == 1 - echo "" >>$FDISK_SCRIPT - echo "+$FATMB"M >>$FDISK_SCRIPT +# format the disk +case "${partition}" in - # add the normal EXT3 rootfs - echo "n" >>$FDISK_SCRIPT - echo "p" >>$FDISK_SCRIPT - echo "2" >>$FDISK_SCRIPT - # continue after last - echo "" >>$FDISK_SCRIPT - echo "+$(( $EXT3_ROOTFS_SECTORS / 2048 ))"M >>$FDISK_SCRIPT + # 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 )) - # add the backup EXT3 rootfs - echo "n" >>$FDISK_SCRIPT - echo "p" >>$FDISK_SCRIPT - echo "3" >>$FDISK_SCRIPT - # continue after last - echo "" >>$FDISK_SCRIPT - echo "+$(( $EXT3_BACKUP_FS_SECTORS / 2048 ))"M >>$FDISK_SCRIPT + 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 + ;; - # commit it and exit - echo "w" >>$FDISK_SCRIPT - echo "q" >>$FDISK_SCRIPT + # 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]" - # do the partitioning action - fdisk /dev/$1 <$FDISK_SCRIPT + 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 )) - # prep the filesystems + 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 - mkfs.vfat "/dev/$1"1 -n main-vfat - mkfs.ext3 "/dev/$1"2 -L rootfs - mkfs.ext3 "/dev/$1"3 -L backupfs + 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 -fi # if -z $4 # copy the full bootloader image to the right place after the # partitioned area -dd if=$3 of=/dev/$1 bs=512 count=512 \ - seek=$(( $SECTORS - $REARSECTORS )) -dd if=$3 of=/dev/$1 bs=512 \ - seek=$(( $SECTORS - $REARSECTORS + $QI_ALLOCATION )) \ +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/$1 bs=512 \ - seek=$(( $SECTORS - $REARSECTORS + $QI_ALLOCATION + $QI_INITIAL )) \ +dd if=/dev/zero of="${dev}" bs=512 \ + seek=$(( $SECTORS - $REAR_SECTORS + $QI_ALLOCATION + $QI_INITIAL )) \ count=$(( $SIG + $PADDING )) # done From 796fea906ee017179030193ef82c91978caed49d Mon Sep 17 00:00:00 2001 From: Andy Green Date: Thu, 12 Mar 2009 09:05:12 +0000 Subject: [PATCH 237/248] qi-3d7k-more-suspend-gpio-meddle.patch Signed-off-by: Andy Green --- qiboot/src/cpu/s3c6410/om_3d7k.c | 146 +++++++++++++++++-------------- 1 file changed, 80 insertions(+), 66 deletions(-) diff --git a/qiboot/src/cpu/s3c6410/om_3d7k.c b/qiboot/src/cpu/s3c6410/om_3d7k.c index ce9db6b..badc595 100644 --- a/qiboot/src/cpu/s3c6410/om_3d7k.c +++ b/qiboot/src/cpu/s3c6410/om_3d7k.c @@ -107,9 +107,16 @@ 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) = - (0 << 17) | /* kill OSCotg clock pad */ - (1 << 10) | /* RTC alarm wakeup source */ + (1 << 17) | /* kill OSCotg clock pad */ (0 << 0) /* 27MHz osc off */ ; @@ -118,14 +125,14 @@ void port_init_om_3d7k(void) (0 << 5) | /* host IF */ (1 << 4) | /* OTG */ (1 << 3) | /* HSMMC */ - (0 << 2) | /* iROM */ + (1 << 2) | /* iROM */ (0 << 1) | /* IRDA */ (1 << 0) /* NFCON / steppingstone */ ; __REG(NOR_CFG) = (1 << 31) | /* reserved */ - (0 << 30) | /* iROM */ + (1 << 30) | /* iROM */ (0x1fff << 17) | /* reserved */ (1 << 16) | /* ETM domain */ (1 << 15) | /* S domain */ @@ -145,9 +152,9 @@ void port_init_om_3d7k(void) (1 << 30) | /* reserved */ (0 << 29) | /* USB host */ (0 << 28) | /* "security subsystem" */ - (1 << 27) | /* SDMA1 */ - (1 << 26) | /* SDMA0 */ - (0 << 25) | /* iROM */ + (0 << 27) | /* SDMA1 */ + (0 << 26) | /* SDMA0 */ + (1 << 25) | /* iROM */ (1 << 24) | /* DDR 1 */ (1 << 23) | /* reserved */ (1 << 22) | /* DMC1 */ @@ -167,8 +174,8 @@ void port_init_om_3d7k(void) (0 << 8) | /* 2D */ (0 << 7) | /* TV */ (1 << 6) | /* reserved */ - (0 << 5) | /* POST0 */ - (0 << 4) | /* rotator */ + (1 << 5) | /* POST0 */ + (1 << 4) | /* rotator */ (1 << 3) | /* LCD controller */ (1 << 2) | /* TZICs */ (1 << 1) | /* VICs */ @@ -223,12 +230,12 @@ void port_init_om_3d7k(void) (0 << 18) | /* TV encoder */ (0 << 17) | /* scaler 27 */ (0 << 16) | /* scaler */ - (0 << 15) | /* LCD 27MHz */ + (1 << 15) | /* LCD 27MHz */ (1 << 14) | /* LCD */ (1 << 13) | /* camera and LCD */ - (0 << 12) | /* POST0 */ - (0 << 11) | /* AUDIO2 */ - (0 << 10) | /* POST0 again */ + (1 << 12) | /* POST0 */ + (1 << 11) | /* AUDIO2 */ + (1 << 10) | /* POST0 again */ (1 << 9) | /* IIS1 */ (1 << 8) | /* IIS0 */ (0 << 7) | /* security */ @@ -377,7 +384,7 @@ void port_init_om_3d7k(void) (S0 << 0) | /* GPD0 */ (S0 << 2) | /* GPD1 */ (S0 << 4) | /* GPD2 */ - (S0 << 6) | /* GPD3 */ + (SIN << 6) | /* GPD3 */ (S0 << 8) /* GPD4 */ ; @@ -385,7 +392,7 @@ void port_init_om_3d7k(void) (SNP << 0) | /* GPD0 */ (SNP << 2) | /* GPD1 */ (SNP << 4) | /* GPD2 */ - (SNP << 6) | /* GPD3 */ + (SPD << 6) | /* GPD3 */ (SNP << 8) /* GPD4 */ ; @@ -407,7 +414,7 @@ void port_init_om_3d7k(void) (S0 << 0) | /* GPE0 */ (S0 << 2) | /* GPE1 */ (S0 << 4) | /* GPE2 */ - (S0 << 6) | /* GPE3 */ + (SIN << 6) | /* GPE3 */ (S0 << 8) /* GPE4 */ ; @@ -415,7 +422,7 @@ void port_init_om_3d7k(void) (SNP << 0) | /* GPE0 */ (SNP << 2) | /* GPE1 */ (SNP << 4) | /* GPE2 */ - (SNP << 6) | /* GPE3 */ + (SPD << 6) | /* GPE3 */ (SNP << 8) /* GPE4 */ ; @@ -455,7 +462,7 @@ void port_init_om_3d7k(void) __REG(GPFCONSLP) = (S0 << 0) | /* GPF0 */ (S0 << 2) | /* GPF1 */ - (S0 << 4) | /* GPF2 */ + (SIN << 4) | /* GPF2 */ (S0 << 6) | /* GPF3 */ (S0 << 8) | /* GPF4 */ (SIN << 10) | /* GPF5 */ @@ -472,14 +479,15 @@ void port_init_om_3d7k(void) ; __REG(GPFPUDSLP) = - (1 << 10) | /* GPF5 - pull down */ - (1 << 12) | /* GPF6 - pull down */ - (1 << 14) | /* GPF7 - pull down */ - (1 << 16) | /* GPF8 - pull down */ - (1 << 18) | /* GPF9 - pull down */ - (1 << 20) | /* GPF10 - pull down */ - (1 << 22) | /* GPF11 - pull down */ - (1 << 24) /* GPF12 - pull down */ + (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 ---------------------------- */ @@ -499,16 +507,24 @@ void port_init_om_3d7k(void) __REG(GPGDAT) = 0; /* just for determinism */ __REG(GPGCONSLP) = - (S0 << 0) | /* GPG0 - it's not powered*/ - (S0 << 2) | /* GPG1 */ - (S0 << 4) | /* GPG2 */ - (S0 << 6) | /* GPG3 */ - (S0 << 8) | /* GPG4 */ - (S0 << 10) | /* GPG5 */ - (S0 << 12) /* GPG6 */ + (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) = 0; + __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 ---------------------------- */ @@ -539,12 +555,12 @@ void port_init_om_3d7k(void) (S0 << 8) | /* GPH4 */ (S0 << 10) | /* GPH5 */ (S0 << 12) | /* GPH6 */ - (SHOLD << 14) | /* GPH7 - INPUT (HDQ) */ + (SIN << 14) | /* GPH7 - INPUT (HDQ) */ (S0 << 16) | /* GPH8 */ (SIN << 18) /* GPH9 */ ; - __REG(GPHPUDSLP) = (SPU << (9 * 2)); + __REG(GPHPUDSLP) = (SPU << (7 * 2)) | (SPU << (9 * 2)); /* ---------------------------- Port I ---------------------------- */ @@ -759,20 +775,20 @@ void port_init_om_3d7k(void) __REG(GPOCON) = (2 << 0) | /* GPO0 - XM0CS2 (nNANDCS0) */ (1 << 2) | /* GPO1 - OUTPUT (nMODEM_RESET) */ - (1 << 4) | /* GPO2 - input (NC) */ - (1 << 6) | /* GPO3 - input (NC) */ - (1 << 8) | /* GPO4 - input (NC) */ - (1 << 10) | /* GPO5 - input (NC) */ - (1 << 12) | /* GPO6 - input (NC) */ - (1 << 14) | /* GPO7 - input (NC) */ - (1 << 16) | /* GPO8 - input (NC) */ - (1 << 18) | /* GPO9 - input (NC) */ - (1 << 20) | /* GPO10 - input (NC) */ - (1 << 22) | /* GPO11 - input (NC) */ - (1 << 24) | /* GPO12 - input (NC) */ - (1 << 26) | /* GPO13 - input (NC) */ - (1 << 28) | /* GPO14 - input (NC) */ - (1 << 30) /* GPO15 - input (NC) */ + (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 */ @@ -819,8 +835,7 @@ void port_init_om_3d7k(void) (1 << 22) | /* GPP11 - input (NC) */ (1 << 24) | /* GPP12 - input (NC) */ (1 << 26) | /* GPP13 - input (NC) */ - (1 << 28) | /* GPP14 - input (NC) */ - (1 << 30) /* GPP15 - input (NC) */ + (1 << 28) /* GPP14 - input (NC) */ ; __REG(GPPPUD) = 0; /* no pull */ @@ -842,8 +857,7 @@ void port_init_om_3d7k(void) (S0 << 22) | /* GPP11 - OUTPUT 0 */ (S0 << 24) | /* GPP12 - OUTPUT 0 */ (S0 << 26) | /* GPP13 - OUTPUT 0 */ - (S0 << 28) | /* GPP14 - OUTPUT 0 */ - (S0 << 30) /* GPP15 - OUTPUT 0 */ + (S0 << 28) /* GPP14 - OUTPUT 0 */ ; __REG(GPPPUDSLP) = 0; @@ -851,20 +865,20 @@ void port_init_om_3d7k(void) /* ---------------------------- Port Q ---------------------------- */ __REG(GPQCON) = - (1 << 0) | /* GPQ0 - input (NC) */ - (1 << 2) | /* GPQ1 - input (NC) */ - (1 << 4) | /* GPQ2 - input (NC) */ - (1 << 6) | /* GPQ3 - input (NC) */ - (1 << 8) | /* GPQ4 - input (NC) */ - (1 << 10) | /* GPQ5 - input (NC) */ - (1 << 12) | /* GPQ6 - input (NC) */ - (1 << 14) | /* GPQ7 - input (NC) */ - (1 << 16) /* GPQ8 - input (NC) */ + (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; /* all pulldown */ + __REG(GPQPUD) = 0; /* no pull */ - __REG(GPQDAT) = 0; /* assert CAM_PWRDN */ + __REG(GPQDAT) = 0; __REG(GPQCONSLP) = (S0 << 0) | /* GPQ0 - OUTPUT 0 */ @@ -883,7 +897,7 @@ void port_init_om_3d7k(void) /* LCD Controller enable */ __REG(0x7410800c) = 0; - __REG(0x7f0081a0) = 0xbfc11501; + __REG(0x7f0081a0) = 0xbfc115c1; /* * We have to talk to the PMU a little bit From 0ca1d894123c0a4086a046b5c5456a2e7a20e5a1 Mon Sep 17 00:00:00 2001 From: Dmitry Kurochkin Date: Fri, 10 Apr 2009 00:14:49 +0400 Subject: [PATCH 238/248] Bad magic when booting from NAND Qi fails to boot from NAND. Qi booting from SD goes fine. Booting NAND from NOR works as well. I have found the problem. The error was because we check if the current block is bad or the next one is bad. And skip the current block even if only the next one is bad. This way we skip good block before a bad one. This patch fixes the bug. Signed-off-by: Dmitry Kurochkin --- qiboot/src/cpu/s3c2442/nand_read.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/qiboot/src/cpu/s3c2442/nand_read.c b/qiboot/src/cpu/s3c2442/nand_read.c index 06ec24d..8206717 100644 --- a/qiboot/src/cpu/s3c2442/nand_read.c +++ b/qiboot/src/cpu/s3c2442/nand_read.c @@ -119,7 +119,6 @@ int nand_read_ll(unsigned char *buf, unsigned long start_block512, int blocks512) { int i, j; - int bad_count = 0; /* chip Enable */ nand_select(); @@ -129,11 +128,10 @@ int nand_read_ll(unsigned char *buf, unsigned long start_block512, ; while (blocks512 > 0) { - if (s3c2442_nand_is_bad_block(start_block512) || - s3c2442_nand_is_bad_block(start_block512 + 4)) { + if (s3c2442_nand_is_bad_block(start_block512)) { start_block512 += 4; - blocks512 += 4; - if (bad_count++ == 4) + if (start_block512 >> 2 > BAD_BLOCK_OFFSET) + /* end of NAND */ return -1; continue; } From 8089e8de8bdd21cc115692c3b23ddbca8ec6a43f Mon Sep 17 00:00:00 2001 From: Paul Fertser Date: Sun, 24 May 2009 01:16:35 +0400 Subject: [PATCH 239/248] Added SDHC support Implemented and tested on Josch's GTA01Bv4 Signed-off-by: Paul Fertser --- qiboot/src/cpu/s3c2410/gta01.c | 6 +++--- qiboot/src/cpu/s3c2410/s3c24xx-mci.c | 20 +++++++++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/qiboot/src/cpu/s3c2410/gta01.c b/qiboot/src/cpu/s3c2410/gta01.c index 0371505..4686fa2 100644 --- a/qiboot/src/cpu/s3c2410/gta01.c +++ b/qiboot/src/cpu/s3c2410/gta01.c @@ -280,7 +280,7 @@ const struct board_api board_api_gta01 = { .partition_index = 1, .filesystem = FS_EXT2, .filepath = "boot/uImage-GTA01.bin", - .commandline_append = "root=/dev/mmcblk0p1 ", + .commandline_append = "root=/dev/mmcblk0p1 rootdelay=1 ", }, [1] = { .name = "SD Card EXT2 Kernel p2", @@ -289,7 +289,7 @@ const struct board_api board_api_gta01 = { .partition_index = 2, .filesystem = FS_EXT2, .filepath = "boot/uImage-GTA01.bin", - .commandline_append = "root=/dev/mmcblk0p2 ", + .commandline_append = "root=/dev/mmcblk0p2 rootdelay=1 ", }, [2] = { .name = "SD Card EXT2 Kernel p3", @@ -298,7 +298,7 @@ const struct board_api board_api_gta01 = { .partition_index = 3, .filesystem = FS_EXT2, .filepath = "boot/uImage-GTA01.bin", - .commandline_append = "root=/dev/mmcblk0p3 ", + .commandline_append = "root=/dev/mmcblk0p3 rootdelay=1 ", }, [3] = { .name = "NAND Kernel", diff --git a/qiboot/src/cpu/s3c2410/s3c24xx-mci.c b/qiboot/src/cpu/s3c2410/s3c24xx-mci.c index 7d53b42..dbef90d 100644 --- a/qiboot/src/cpu/s3c2410/s3c24xx-mci.c +++ b/qiboot/src/cpu/s3c2410/s3c24xx-mci.c @@ -70,6 +70,7 @@ 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 @@ -162,7 +163,10 @@ static int mmc_block_read(u8 *dst, u32 src, u32 len) SDIDCON = dcon; /* send read command */ - resp = mmc_cmd(MMC_CMD_READ_BLOCK, src, CMD_F_RESP); + 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; @@ -449,6 +453,7 @@ 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; @@ -474,11 +479,20 @@ int s3c24xx_mmc_init(int verbose) 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, 0x00300000, 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; @@ -490,7 +504,7 @@ int s3c24xx_mmc_init(int verbose) return -3; /* try to get card id */ - resp = mmc_cmd(MMC_CMD_ALL_SEND_CID, 0, CMD_F_RESP|CMD_F_RESP_LONG); + 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 From 141b2bedfc9bdbd40d15c306f104174a9da2b47b Mon Sep 17 00:00:00 2001 From: Paul Fertser Date: Thu, 28 May 2009 20:01:20 -0300 Subject: [PATCH 240/248] Use different MACs for the host and for the device ends of usb link This makes Qi consistent with current SHR boot script. It assigns the MAC specified on the identity partition to the device and the next address to the host, ie: from "g_ether.dev_addr=00:1F:11:01:58:67" generate "g_ether.host_addr=00:1F:11:01:58:68". Signed-off-by: Paul Fertser --- qiboot/src/cpu/s3c2442/gta02.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index e9bc0a3..1a31274 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -558,6 +558,22 @@ void post_serial_init_gta02(void) 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 @@ -569,6 +585,7 @@ void post_serial_init_gta02(void) 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; @@ -632,10 +649,17 @@ char * append_device_specific_cmdline_gta02(char * cmdline) mac[len] = '\0'; - cmdline += strlen(strcpy(cmdline, " g_ether.host_addr=")); + cmdline += strlen(strcpy(cmdline, " g_ether.dev_addr=")); cmdline += strlen(strcpy(cmdline, &mac[2])); - cmdline += strlen(strcpy(cmdline, " g_ether.dev_addr=")); + 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: From fd3fac5a54d681e3cb91d3a4bd5d49393ac95bf0 Mon Sep 17 00:00:00 2001 From: Paul Fertser Date: Tue, 2 Jun 2009 04:21:26 +0400 Subject: [PATCH 241/248] GTA02: set battery full charging current threshold to 2/32*Ichg In most conditions the charger is unable to detect battery full status because gsm modem continiously draws current directly from the battery. This makes it less sensitive and therefore will cutoff charging properly. Signed-off-by: Paul Fertser --- qiboot/src/cpu/s3c2442/gta02.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 1a31274..13be2ac 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -103,7 +103,7 @@ const struct pcf50633_init pcf50633_init[] = { { 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 */ + { 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 */ From 2b6f1b3c048c103edef25db723f7134d3b7205ea Mon Sep 17 00:00:00 2001 From: Sebastian Krzyszkowiak Date: Sat, 6 Jun 2009 22:18:28 +0200 Subject: [PATCH 242/248] Remove loglevel from default kernel boot arguments Remove loglevel from default kernel boot arguments to let kernel use its default configuration. Signed-off-by: Sebastian Krzyszkowiak --- qiboot/src/cpu/s3c2410/gta01.c | 1 - qiboot/src/cpu/s3c2442/gta02.c | 3 +-- qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/qiboot/src/cpu/s3c2410/gta01.c b/qiboot/src/cpu/s3c2410/gta01.c index 4686fa2..639c072 100644 --- a/qiboot/src/cpu/s3c2410/gta01.c +++ b/qiboot/src/cpu/s3c2410/gta01.c @@ -263,7 +263,6 @@ const struct board_api board_api_gta01 = { "0x00200000(kernel)," "0x000a0000(splash)," "0x03d1c000(rootfs) " - "loglevel=4 " "console=tty0 " "console=ttySAC0,115200 " "init=/sbin/init " diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 13be2ac..143f831 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -690,8 +690,7 @@ const struct board_api board_api_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 " + .commandline_board = "console=tty0 " "console=ttySAC2,115200 " "init=/sbin/init " "ro ", diff --git a/qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c b/qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c index 71c57f9..9e63b5d 100644 --- a/qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c @@ -88,7 +88,6 @@ const struct board_api board_api_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", From bdc81cae2db96411682a2f809180c52537836f4e Mon Sep 17 00:00:00 2001 From: Nelson Castillo Date: Wed, 10 Jun 2009 10:40:53 -0300 Subject: [PATCH 243/248] Revert "Remove loglevel from default kernel boot arguments" This reverts commit 01e049d704cfba97192efeed6afabd71cf7ca130. It seems default loglevel cannot be set in kernel .config. --- qiboot/src/cpu/s3c2410/gta01.c | 1 + qiboot/src/cpu/s3c2442/gta02.c | 3 ++- qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/qiboot/src/cpu/s3c2410/gta01.c b/qiboot/src/cpu/s3c2410/gta01.c index 639c072..4686fa2 100644 --- a/qiboot/src/cpu/s3c2410/gta01.c +++ b/qiboot/src/cpu/s3c2410/gta01.c @@ -263,6 +263,7 @@ const struct board_api board_api_gta01 = { "0x00200000(kernel)," "0x000a0000(splash)," "0x03d1c000(rootfs) " + "loglevel=4 " "console=tty0 " "console=ttySAC0,115200 " "init=/sbin/init " diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 143f831..13be2ac 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -690,7 +690,8 @@ const struct board_api board_api_gta02 = { .get_ui_keys = get_ui_keys_gta02, .get_ui_debug = get_ui_debug_gta02, .set_ui_indication = set_ui_indication_gta02, - .commandline_board = "console=tty0 " + .commandline_board = "loglevel=4 " + "console=tty0 " "console=ttySAC2,115200 " "init=/sbin/init " "ro ", diff --git a/qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c b/qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c index 9e63b5d..71c57f9 100644 --- a/qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c +++ b/qiboot/src/cpu/s3c6410/om_3d7k-steppingstone.c @@ -88,6 +88,7 @@ const struct board_api board_api_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", From ba682deebb9207f0122f21574a2fb8f73aeee894 Mon Sep 17 00:00:00 2001 From: Xiangfu Liu Date: Sun, 28 Jun 2009 17:42:34 +0800 Subject: [PATCH 244/248] fix the version, use date for the inflash version Signed-off-by: Xiangfu Liu --- inflash/src/Makefile.am | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/inflash/src/Makefile.am b/inflash/src/Makefile.am index 81f5960..acea824 100644 --- a/inflash/src/Makefile.am +++ b/inflash/src/Makefile.am @@ -1,8 +1,12 @@ AM_CFLAGS = -pedantic -Wall -W -O1 -g3 -std=gnu99 -lusb -lconfuse +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} + inflash_version.h: echo -e '#ifndef INFLASH_VERSION' \ - '\n#define INFLASH_VERSION "'`svnversion`'"' \ + '\n#define INFLASH_VERSION "20090628-1"' \ '\n#endif' > inflash_version.h BUILT_SOURCES = inflash_version.h From 7e7567ef7eac434f64fc1dd6a2e4299f499c2754 Mon Sep 17 00:00:00 2001 From: Xiangfu Liu Date: Mon, 29 Jun 2009 09:10:51 +0800 Subject: [PATCH 245/248] Signed-off-by: Xiangfu Liu --- inflash/src/command_line.c | 53 +++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/inflash/src/command_line.c b/inflash/src/command_line.c index d3f32f8..9225e4c 100644 --- a/inflash/src/command_line.c +++ b/inflash/src/command_line.c @@ -60,27 +60,38 @@ static const char COMMAND[][COMMAND_NUM]= static int handle_help(void) { printf(" command support in current version:\n" - " help print this help;\n" - " boot boot device and make it in stage2;\n" - " list show current device number can connect;\n" - " fconfig set USB Boot config file;\n" - " nquery query NAND flash info;\n" - " nread read NAND flash data with checking bad block and ECC;\n" - " nreadraw read NAND flash data without checking bad block and ECC;\n" - " nreadoob read NAND flash oob without checking bad block and ECC;\n" - " nerase erase NAND flash;\n" - " nprog program NAND flash with data and ECC;\n" - " nmark mark a bad block in NAND flash;\n" - " go execute program in SDRAM;\n" - " version show current USB Boot software version;\n" - " exit quit from telnet session;\n" - " readnand read data from nand flash and store to SDRAM;\n" - " load load file data to SDRAM;\n" - " run run command script in file;\n" - " memtest do SDRAM test;\n" - " gpios let one GPIO to high level;\n" - " gpioc let one GPIO to low level;\n"); - /* printf(" nmake read all data from nand flash and store to file(experimental);\n"); */ + /* " query" */ + /* " querya" */ + /* " erase" */ + /* " read" */ + /* " prog" */ + " nquery \tquery NAND flash info;\n" + " nerase \terase NAND flash;\n" + " nread \tread NAND flash data with checking bad block and ECC;\n" + " nreadraw \tread NAND flash data without checking bad block and ECC;\n" + " nreadoob \tread NAND flash oob without checking bad block and ECC;\n" /* index 10 */ + " nprog \tprogram NAND flash with data and ECC;\n" + " help \tprint this help;\n" + " version \tshow current USB Boot software version;\n" + " go \texecute program in SDRAM;\n" + " fconfig \tset USB Boot config file;(not implement)\n" + " exit \tquit from telnet session;\n" + " readnand \tread data from nand flash and store to SDRAM;\n" + " gpios \tset one GPIO to high level;\n" + " gpioc \tlet one GPIO to low level;\n"); + " boot \tboot device and make it in stage2;\n" /* index 20 */ + " list \tshow current device number can connect;(not implement)\n" + /* " select" */ + /* " unselect" */ + /* " chip" */ + /* " unchip" */ + " nmark \tmark a bad block in NAND flash;\n" + " nmake \tread all data from nand flash and store to file(experimental);(not implement)\n" + " load \tload file data to SDRAM;\n" + " memtest \tdo SDRAM test;\n" + " run\tun command script in file;\n" + " sdprog \tprogram SD card;(not implement)" + " sdread \tread data from SD card;(not implement)"); return 1; } From 2dc8b232e3f88786919c9906d70f4f5de83ec116 Mon Sep 17 00:00:00 2001 From: Xiangfu Liu Date: Mon, 29 Jun 2009 09:25:19 +0800 Subject: [PATCH 246/248] cleanup the help command Signed-off-by: Xiangfu Liu --- inflash/src/command_line.c | 46 +++++++++++++++++++------------------- inflash/src/main.c | 2 +- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/inflash/src/command_line.c b/inflash/src/command_line.c index 9225e4c..312a97a 100644 --- a/inflash/src/command_line.c +++ b/inflash/src/command_line.c @@ -65,33 +65,33 @@ static int handle_help(void) /* " erase" */ /* " read" */ /* " prog" */ - " nquery \tquery NAND flash info;\n" - " nerase \terase NAND flash;\n" - " nread \tread NAND flash data with checking bad block and ECC;\n" - " nreadraw \tread NAND flash data without checking bad block and ECC;\n" - " nreadoob \tread NAND flash oob without checking bad block and ECC;\n" /* index 10 */ - " nprog \tprogram NAND flash with data and ECC;\n" - " help \tprint this help;\n" - " version \tshow current USB Boot software version;\n" - " go \texecute program in SDRAM;\n" - " fconfig \tset USB Boot config file;(not implement)\n" - " exit \tquit from telnet session;\n" - " readnand \tread data from nand flash and store to SDRAM;\n" - " gpios \tset one GPIO to high level;\n" - " gpioc \tlet one GPIO to low level;\n"); - " boot \tboot device and make it in stage2;\n" /* index 20 */ - " list \tshow current device number can connect;(not implement)\n" + " nquery query NAND flash info\n" + " nerase erase NAND flash\n" + " nread read NAND flash data with checking bad block and ECC\n" + " nreadraw read NAND flash data without checking bad block and ECC\n" + " nreadoo read NAND flash oob without checking bad block and ECC\n" /* index 10 */ + " nprog program NAND flash with data and ECC\n" + " help print this help\n" + " version show current USB Boot software version\n" + " go execute program in SDRAM\n" + " fconfig set USB Boot config file(not implement)\n" + " exit quit from telnet session\n" + " readnand read data from nand flash and store to SDRAM\n" + " gpios set one GPIO to high level\n" + " gpioc set one GPIO to low level\n" + " boot boot device and make it in stage2\n" /* index 20 */ + " list show current device number can connect(not implement)\n" /* " select" */ /* " unselect" */ /* " chip" */ /* " unchip" */ - " nmark \tmark a bad block in NAND flash;\n" - " nmake \tread all data from nand flash and store to file(experimental);(not implement)\n" - " load \tload file data to SDRAM;\n" - " memtest \tdo SDRAM test;\n" - " run\tun command script in file;\n" - " sdprog \tprogram SD card;(not implement)" - " sdread \tread data from SD card;(not implement)"); + " nmark mark a bad block in NAND flash\n" + " nmake read all data from nand flash and store to file(not implement)\n" + " load load file data to SDRAM\n" + " memtest do SDRAM test\n" + " run run command script in file(implement by -c args)\n" + " sdprog program SD card(not implement)\n" + " sdread read data from SD card(not implement)\n"); return 1; } diff --git a/inflash/src/main.c b/inflash/src/main.c index 17c388c..ddb5ce3 100644 --- a/inflash/src/main.c +++ b/inflash/src/main.c @@ -25,7 +25,7 @@ static void help(void) printf("Usage: inflash [options] ...(must run as root)\n" " -h --help\t\t\tPrint this help message\n" " -v --version\t\t\tPrint the version number\n" - " -c --command\t\t\tDirect run the command\n\n" + " -c --command\t\t\tDirect run the commands, split by ';'\n" " \n\n" "Report bugs to .\n" ); From 476093fe0e0cfb42133e017805c1590f2e411b7a Mon Sep 17 00:00:00 2001 From: Xiangfu Liu Date: Mon, 29 Jun 2009 16:26:24 +0800 Subject: [PATCH 247/248] -change the verison to 20090630(YYYYMMDD) -correct the description Signed-off-by: Xiangfu Liu --- inflash/debian/changelog | 4 ++-- inflash/debian/control | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/inflash/debian/changelog b/inflash/debian/changelog index 2c70435..c39f5e7 100644 --- a/inflash/debian/changelog +++ b/inflash/debian/changelog @@ -1,5 +1,5 @@ -inflash (1.0.0-1) unstable; urgency=low +inflash (20090630-1) unstable; urgency=low * Initial release (Closes: #nnnn) - -- xiangfu Mon, 22 Jun 2009 22:48:14 +0800 + -- xiangfu Mon, 29 Jun 2009 16:24:32 +0800 diff --git a/inflash/debian/control b/inflash/debian/control index bcf8a25..3ed5bc8 100644 --- a/inflash/debian/control +++ b/inflash/debian/control @@ -9,7 +9,7 @@ Homepage: http://code.google.com/p/pi-project Package: inflash Architecture: any Depends: ${shlibs:Depends}, libusb, libconfuse -Description: inflash - host tool for Ingenic XBurst CPU USB boot and NAND flash access. +Description: host tool for Ingenic XBurst CPU USB boot and NAND flash access. inflash is a host tool for Ingenic XBurst CPU device usb boot. it's can flash bootloader, kernel, rootfs to Ingenic XBurst CPU device nand. also have some test function for Ingenic XBurst CPU From d5a74247a24f90a0038e2f7448fb18ecb1395a89 Mon Sep 17 00:00:00 2001 From: Xiangfu Liu Date: Mon, 29 Jun 2009 23:17:29 +0800 Subject: [PATCH 248/248] rename inflash to xburst-tools Signed-off-by: Xiangfu Liu --- inflash/debian/changelog | 5 ----- inflash/debian/dirs | 3 --- {inflash => xburst-tools}/COPYING | 0 {inflash => xburst-tools}/ChangeLog | 2 +- {inflash => xburst-tools}/Makefile.am | 0 {inflash => xburst-tools}/README | 20 +++++++++---------- {inflash => xburst-tools}/autogen.sh | 0 {inflash => xburst-tools}/configure.ac | 2 +- xburst-tools/debian/changelog | 5 +++++ {inflash => xburst-tools}/debian/compat | 0 {inflash => xburst-tools}/debian/control | 6 +++--- {inflash => xburst-tools}/debian/copyright | 0 xburst-tools/debian/dirs | 3 +++ {inflash => xburst-tools}/debian/docs | 0 {inflash => xburst-tools}/debian/rules | 6 +++--- {inflash => xburst-tools}/src/Makefile.am | 18 ++++++++--------- {inflash => xburst-tools}/src/cmd.c | 0 {inflash => xburst-tools}/src/cmd.h | 0 {inflash => xburst-tools}/src/command_line.c | 6 +++--- {inflash => xburst-tools}/src/command_line.h | 0 {inflash => xburst-tools}/src/ingenic_cfg.c | 0 {inflash => xburst-tools}/src/ingenic_cfg.h | 2 +- {inflash => xburst-tools}/src/ingenic_usb.c | 0 {inflash => xburst-tools}/src/ingenic_usb.h | 4 ++-- {inflash => xburst-tools}/src/main.c | 12 +++++------ .../src/usb_boot_defines.h | 0 .../src/xburst_tools.cfg | 2 +- .../xburst_include/archdefs.h | 0 .../xburst_include/configs.h | 0 .../xburst_include/error.h | 0 .../xburst_include/jz4740.h | 0 .../xburst_include/jz4750.h | 0 .../xburst_include/mips.h | 0 .../xburst_include/mipsregs.h | 0 .../xburst_include/nandflash.h | 0 .../xburst_include/sysdefs.h | 0 .../xburst_include/udc.h | 0 .../xburst_include/usb.h | 0 .../xburst_include/usb_boot.h | 0 .../xburst_include/xburst_types.h | 0 .../xburst_stage1/Makefile | 0 .../xburst_stage1/board_4740.c | 0 .../xburst_stage1/board_4750.c | 0 .../xburst_stage1/common.c | 0 .../xburst_stage1/debug.c | 0 .../xburst_stage1/head.S | 0 .../xburst_stage1/main.c | 0 .../xburst_stage1/target.ld | 0 .../xburst_stage2/Makefile | 0 .../xburst_stage2/boothandler.c | 0 .../xburst_stage2/cache.c | 0 .../xburst_stage2/head.S | 0 .../xburst_stage2/main.c | 0 .../xburst_stage2/nandflash_4740.c | 0 .../xburst_stage2/nandflash_4750.c | 0 .../xburst_stage2/serial.c | 0 .../xburst_stage2/target.ld | 0 {inflash => xburst-tools}/xburst_stage2/udc.c | 0 58 files changed, 48 insertions(+), 48 deletions(-) delete mode 100644 inflash/debian/changelog delete mode 100644 inflash/debian/dirs rename {inflash => xburst-tools}/COPYING (100%) rename {inflash => xburst-tools}/ChangeLog (73%) rename {inflash => xburst-tools}/Makefile.am (100%) rename {inflash => xburst-tools}/README (57%) rename {inflash => xburst-tools}/autogen.sh (100%) rename {inflash => xburst-tools}/configure.ac (96%) create mode 100644 xburst-tools/debian/changelog rename {inflash => xburst-tools}/debian/compat (100%) rename {inflash => xburst-tools}/debian/control (81%) rename {inflash => xburst-tools}/debian/copyright (100%) create mode 100644 xburst-tools/debian/dirs rename {inflash => xburst-tools}/debian/docs (100%) rename {inflash => xburst-tools}/debian/rules (92%) rename {inflash => xburst-tools}/src/Makefile.am (62%) rename {inflash => xburst-tools}/src/cmd.c (100%) rename {inflash => xburst-tools}/src/cmd.h (100%) rename {inflash => xburst-tools}/src/command_line.c (97%) rename {inflash => xburst-tools}/src/command_line.h (100%) rename {inflash => xburst-tools}/src/ingenic_cfg.c (100%) rename {inflash => xburst-tools}/src/ingenic_cfg.h (89%) rename {inflash => xburst-tools}/src/ingenic_usb.c (100%) rename {inflash => xburst-tools}/src/ingenic_usb.h (93%) rename {inflash => xburst-tools}/src/main.c (88%) rename {inflash => xburst-tools}/src/usb_boot_defines.h (100%) rename inflash/src/inflash.cfg => xburst-tools/src/xburst_tools.cfg (98%) rename {inflash => xburst-tools}/xburst_include/archdefs.h (100%) rename {inflash => xburst-tools}/xburst_include/configs.h (100%) rename {inflash => xburst-tools}/xburst_include/error.h (100%) rename {inflash => xburst-tools}/xburst_include/jz4740.h (100%) rename {inflash => xburst-tools}/xburst_include/jz4750.h (100%) rename {inflash => xburst-tools}/xburst_include/mips.h (100%) rename {inflash => xburst-tools}/xburst_include/mipsregs.h (100%) rename {inflash => xburst-tools}/xburst_include/nandflash.h (100%) rename {inflash => xburst-tools}/xburst_include/sysdefs.h (100%) rename {inflash => xburst-tools}/xburst_include/udc.h (100%) rename {inflash => xburst-tools}/xburst_include/usb.h (100%) rename {inflash => xburst-tools}/xburst_include/usb_boot.h (100%) rename {inflash => xburst-tools}/xburst_include/xburst_types.h (100%) rename {inflash => xburst-tools}/xburst_stage1/Makefile (100%) rename {inflash => xburst-tools}/xburst_stage1/board_4740.c (100%) rename {inflash => xburst-tools}/xburst_stage1/board_4750.c (100%) rename {inflash => xburst-tools}/xburst_stage1/common.c (100%) rename {inflash => xburst-tools}/xburst_stage1/debug.c (100%) rename {inflash => xburst-tools}/xburst_stage1/head.S (100%) rename {inflash => xburst-tools}/xburst_stage1/main.c (100%) rename {inflash => xburst-tools}/xburst_stage1/target.ld (100%) rename {inflash => xburst-tools}/xburst_stage2/Makefile (100%) rename {inflash => xburst-tools}/xburst_stage2/boothandler.c (100%) rename {inflash => xburst-tools}/xburst_stage2/cache.c (100%) rename {inflash => xburst-tools}/xburst_stage2/head.S (100%) rename {inflash => xburst-tools}/xburst_stage2/main.c (100%) rename {inflash => xburst-tools}/xburst_stage2/nandflash_4740.c (100%) rename {inflash => xburst-tools}/xburst_stage2/nandflash_4750.c (100%) rename {inflash => xburst-tools}/xburst_stage2/serial.c (100%) rename {inflash => xburst-tools}/xburst_stage2/target.ld (100%) rename {inflash => xburst-tools}/xburst_stage2/udc.c (100%) diff --git a/inflash/debian/changelog b/inflash/debian/changelog deleted file mode 100644 index c39f5e7..0000000 --- a/inflash/debian/changelog +++ /dev/null @@ -1,5 +0,0 @@ -inflash (20090630-1) unstable; urgency=low - - * Initial release (Closes: #nnnn) - - -- xiangfu Mon, 29 Jun 2009 16:24:32 +0800 diff --git a/inflash/debian/dirs b/inflash/debian/dirs deleted file mode 100644 index 9fe37db..0000000 --- a/inflash/debian/dirs +++ /dev/null @@ -1,3 +0,0 @@ -usr/bin -usr/share/inflash -usr/man/man1 diff --git a/inflash/COPYING b/xburst-tools/COPYING similarity index 100% rename from inflash/COPYING rename to xburst-tools/COPYING diff --git a/inflash/ChangeLog b/xburst-tools/ChangeLog similarity index 73% rename from inflash/ChangeLog rename to xburst-tools/ChangeLog index d6b9394..f9d5afa 100644 --- a/inflash/ChangeLog +++ b/xburst-tools/ChangeLog @@ -1,4 +1,4 @@ - * inflash ChangeLog + * xburst-tools ChangeLog 25Jun2009 [WS] some cleanup in directory structure and build system diff --git a/inflash/Makefile.am b/xburst-tools/Makefile.am similarity index 100% rename from inflash/Makefile.am rename to xburst-tools/Makefile.am diff --git a/inflash/README b/xburst-tools/README similarity index 57% rename from inflash/README rename to xburst-tools/README index 68579d6..55b1696 100644 --- a/inflash/README +++ b/xburst-tools/README @@ -1,5 +1,5 @@ * -* inflash +* xburst-tools * * Utility to respond to Ingenic XBurst USB boot protocol, provide * initial boot stages and ability to access NAND on device. @@ -14,7 +14,7 @@ modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. -inflash is the Linux version of a Windows utility from Ingenic called 'usbboot'. +xburst-tools is the Linux version of a Windows utility from Ingenic called 'usbboot'. Homepage: http://www.ingenic.cn/eng/productServ/kfyd/compiler/pffaqContents.aspx#questionAnchor8 Manual: ftp://ftp.ingenic.cn/3sw/00tools/usb_boot/manual/USB_Boot_Tool_Manual_1.4_EN.pdf @@ -25,14 +25,14 @@ Build and Installation: ./configure make make install - *) make install will install the 'inflash' binary to /usr/bin/inflash - and the stage 1 and 2 bootloaders as well as inflash.cfg configuration - file into /usr/share/inflash + *) make install will install the 'xburst-tools' binary to /usr/bin/xburst-tools + and the stage 1 and 2 bootloaders as well as xburst-tools.cfg configuration + file into /usr/share/xburst-tools -Configuration file: /usr/share/inflash/inflash.cfg +Configuration file: /usr/share/xburst-tools/xburst-tools.cfg Examples: - sudo inflash (invoking inflash without options will let you enter commands at the inflash prompt) - sudo inflash -c "boot" - sudo inflash -c "nprog 0 u-boot-nand.bin 0 0 -n" - sudo inflash -c "nprog 2048 uImage 0 0 -n" + sudo xburst-tools (invoking xburst-tools without options will let you enter commands at the xburst-tools prompt) + sudo xburst-tools -c "boot" + sudo xburst-tools -c "nprog 0 u-boot-nand.bin 0 0 -n" + sudo xburst-tools -c "nprog 2048 uImage 0 0 -n" diff --git a/inflash/autogen.sh b/xburst-tools/autogen.sh similarity index 100% rename from inflash/autogen.sh rename to xburst-tools/autogen.sh diff --git a/inflash/configure.ac b/xburst-tools/configure.ac similarity index 96% rename from inflash/configure.ac rename to xburst-tools/configure.ac index 469e8d2..97e171e 100644 --- a/inflash/configure.ac +++ b/xburst-tools/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.63) -AC_INIT([inflash], [0.1]) +AC_INIT([xburst-tools], [0.1]) AC_CONFIG_AUX_DIR(m4) AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION) AM_CONFIG_HEADER([config.h]) diff --git a/xburst-tools/debian/changelog b/xburst-tools/debian/changelog new file mode 100644 index 0000000..2ff76c0 --- /dev/null +++ b/xburst-tools/debian/changelog @@ -0,0 +1,5 @@ +xburst-tools (20090630-1) unstable; urgency=low + + * Initial release (Closes: #nnnn) + + -- xiangfu Mon, 29 Jun 2009 16:27:20 +0800 diff --git a/inflash/debian/compat b/xburst-tools/debian/compat similarity index 100% rename from inflash/debian/compat rename to xburst-tools/debian/compat diff --git a/inflash/debian/control b/xburst-tools/debian/control similarity index 81% rename from inflash/debian/control rename to xburst-tools/debian/control index 3ed5bc8..5aa3563 100644 --- a/inflash/debian/control +++ b/xburst-tools/debian/control @@ -1,4 +1,4 @@ -Source: inflash +Source: xburst-tools Section: misc Priority: extra Maintainer: xiangfu liu @@ -6,11 +6,11 @@ Build-Depends: debhelper (>= 7), libusb-dev, libconfuse-dev Standards-Version: 3.8.0 Homepage: http://code.google.com/p/pi-project -Package: inflash +Package: xburst-tools Architecture: any Depends: ${shlibs:Depends}, libusb, libconfuse Description: host tool for Ingenic XBurst CPU USB boot and NAND flash access. - inflash is a host tool for Ingenic XBurst CPU device usb boot. + xburst-tools is a host tool for Ingenic XBurst CPU device usb boot. it's can flash bootloader, kernel, rootfs to Ingenic XBurst CPU device nand. also have some test function for Ingenic XBurst CPU device. diff --git a/inflash/debian/copyright b/xburst-tools/debian/copyright similarity index 100% rename from inflash/debian/copyright rename to xburst-tools/debian/copyright diff --git a/xburst-tools/debian/dirs b/xburst-tools/debian/dirs new file mode 100644 index 0000000..141fd23 --- /dev/null +++ b/xburst-tools/debian/dirs @@ -0,0 +1,3 @@ +usr/bin +usr/share/xburst-tools +usr/man/man1 diff --git a/inflash/debian/docs b/xburst-tools/debian/docs similarity index 100% rename from inflash/debian/docs rename to xburst-tools/debian/docs diff --git a/inflash/debian/rules b/xburst-tools/debian/rules similarity index 92% rename from inflash/debian/rules rename to xburst-tools/debian/rules index 3fc5e34..ad47651 100755 --- a/inflash/debian/rules +++ b/xburst-tools/debian/rules @@ -41,7 +41,7 @@ build-stamp: config.status # Add here commands to compile the package. $(MAKE) - #docbook-to-man debian/inflash.sgml > inflash.1 + #docbook-to-man debian/xburst-tools.sgml > xburst-tools.1 touch $@ @@ -62,8 +62,8 @@ install: build dh_prep dh_installdirs - # Add here commands to install the package into debian/inflash. - $(MAKE) DESTDIR=$(CURDIR)/debian/inflash install + # Add here commands to install the package into debian/xburst-tools. + $(MAKE) DESTDIR=$(CURDIR)/debian/xburst-tools install # Build architecture-independent files here. diff --git a/inflash/src/Makefile.am b/xburst-tools/src/Makefile.am similarity index 62% rename from inflash/src/Makefile.am rename to xburst-tools/src/Makefile.am index acea824..a381632 100644 --- a/inflash/src/Makefile.am +++ b/xburst-tools/src/Makefile.am @@ -4,21 +4,21 @@ 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} -inflash_version.h: - echo -e '#ifndef INFLASH_VERSION' \ - '\n#define INFLASH_VERSION "20090628-1"' \ - '\n#endif' > inflash_version.h -BUILT_SOURCES = inflash_version.h +xburst_tools_version.h: + echo -e '#ifndef XBURST_TOOLS_VERSION' \ + '\n#define XBURST_TOOLS_VERSION "20090630-1"' \ + '\n#endif' > xburst_tools_version.h +BUILT_SOURCES = xburst_tools_version.h -bin_PROGRAMS = inflash -inflash_SOURCES = cmd.c command_line.c ingenic_cfg.c \ +bin_PROGRAMS = xburst_tools +xburst_tools_SOURCES = cmd.c command_line.c ingenic_cfg.c \ ingenic_usb.c main.c prefix = /usr -datadir = /usr/share/inflash +datadir = /usr/share/xburst_tools data_DATA = ../xburst_stage1/xburst_stage1.bin \ ../xburst_stage2/xburst_stage2.bin \ - inflash.cfg + xburst_tools.cfg EXTRA_DIST = $(datadir) ../xburst_stage1/xburst_stage1.bin: diff --git a/inflash/src/cmd.c b/xburst-tools/src/cmd.c similarity index 100% rename from inflash/src/cmd.c rename to xburst-tools/src/cmd.c diff --git a/inflash/src/cmd.h b/xburst-tools/src/cmd.h similarity index 100% rename from inflash/src/cmd.h rename to xburst-tools/src/cmd.h diff --git a/inflash/src/command_line.c b/xburst-tools/src/command_line.c similarity index 97% rename from inflash/src/command_line.c rename to xburst-tools/src/command_line.c index 312a97a..c2226ed 100644 --- a/inflash/src/command_line.c +++ b/xburst-tools/src/command_line.c @@ -13,7 +13,7 @@ #include "usb_boot_defines.h" #include "ingenic_usb.h" #include "cmd.h" -#include "inflash_version.h" +#include "xburst_tools_version.h" extern struct nand_in nand_in; extern struct sdram_in sdram_in; @@ -97,7 +97,7 @@ static int handle_help(void) static int handle_version(void) { - printf(" USB Boot Software current version: %s\n", INFLASH_VERSION); + printf(" USB Boot Software current version: %s\n", XBURST_TOOLS_VERSION); return 1; } @@ -284,7 +284,7 @@ int command_handle(char *buf) debug_go(); break; case 16: /* exit */ - printf(" exiting inflash software\n"); + printf(" exiting xburst-tools software\n"); return -1; /* return -1 to break the main.c while * then run usb_ingenic_cleanup*/ /*case 17: diff --git a/inflash/src/command_line.h b/xburst-tools/src/command_line.h similarity index 100% rename from inflash/src/command_line.h rename to xburst-tools/src/command_line.h diff --git a/inflash/src/ingenic_cfg.c b/xburst-tools/src/ingenic_cfg.c similarity index 100% rename from inflash/src/ingenic_cfg.c rename to xburst-tools/src/ingenic_cfg.c diff --git a/inflash/src/ingenic_cfg.h b/xburst-tools/src/ingenic_cfg.h similarity index 89% rename from inflash/src/ingenic_cfg.h rename to xburst-tools/src/ingenic_cfg.h index 3ea5b01..d6cc671 100644 --- a/inflash/src/ingenic_cfg.h +++ b/xburst-tools/src/ingenic_cfg.h @@ -12,7 +12,7 @@ #include "usb_boot_defines.h" -#define CONFIG_FILE_PATH "/usr/share/inflash/inflash.cfg" +#define CONFIG_FILE_PATH "/usr/share/xburst_tools/xburst_tools.cfg" int hand_init_def(struct hand *hand); int check_dump_cfg(struct hand *hand); diff --git a/inflash/src/ingenic_usb.c b/xburst-tools/src/ingenic_usb.c similarity index 100% rename from inflash/src/ingenic_usb.c rename to xburst-tools/src/ingenic_usb.c diff --git a/inflash/src/ingenic_usb.h b/xburst-tools/src/ingenic_usb.h similarity index 93% rename from inflash/src/ingenic_usb.h rename to xburst-tools/src/ingenic_usb.h index 5ade2b0..8983a5b 100644 --- a/inflash/src/ingenic_usb.h +++ b/xburst-tools/src/ingenic_usb.h @@ -37,8 +37,8 @@ #define VENDOR_ID 0x601a #define PRODUCT_ID 0x4740 -#define STAGE1_FILE_PATH "/usr/share/inflash/xburst_stage1.bin" -#define STAGE2_FILE_PATH "/usr/share/inflash/xburst_stage2.bin" +#define STAGE1_FILE_PATH "/usr/share/xburst_tools/xburst_stage1.bin" +#define STAGE2_FILE_PATH "/usr/share/xburst_tools/xburst_stage2.bin" #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) diff --git a/inflash/src/main.c b/xburst-tools/src/main.c similarity index 88% rename from inflash/src/main.c rename to xburst-tools/src/main.c index ddb5ce3..0c60bae 100644 --- a/inflash/src/main.c +++ b/xburst-tools/src/main.c @@ -12,7 +12,7 @@ #include #include #include -#include "inflash_version.h" +#include "xburst_tools_version.h" #include "command_line.h" #include "ingenic_usb.h" #include "ingenic_cfg.h" @@ -22,18 +22,18 @@ extern struct hand hand; static void help(void) { - printf("Usage: inflash [options] ...(must run as root)\n" + printf("Usage: xburst-tools [options] ...(must run as root)\n" " -h --help\t\t\tPrint this help message\n" " -v --version\t\t\tPrint the version number\n" " -c --command\t\t\tDirect run the commands, split by ';'\n" - " \n\n" + " \n\n" "Report bugs to .\n" ); } static void print_version(void) { - printf("inflash version: %s\n", INFLASH_VERSION); + printf("xburst-tools version: %s\n", XBURST_TOOLS_VERSION); } static struct option opts[] = { @@ -50,7 +50,7 @@ int main(int argc, char **argv) char com_buf[256] = {0}; char *cmdpt; - printf("inflash - Ingenic XBurst USB Boot Utility\n" + printf("xburst-tools - Ingenic XBurst USB Boot Utility\n" "(c) 2009 Ingenic Semiconductor Inc., Qi Hardware Inc., Xiangfu Liu, Marek Lindner\n" "This program is Free Software and comes with ABSOLUTELY NO WARRANTY.\n\n"); @@ -106,7 +106,7 @@ int main(int argc, char **argv) } while (1) { - printf("inflash :> "); + printf("xburst-tools :> "); cptr = fgets(com_buf, 256, stdin); if (cptr == NULL) continue; diff --git a/inflash/src/usb_boot_defines.h b/xburst-tools/src/usb_boot_defines.h similarity index 100% rename from inflash/src/usb_boot_defines.h rename to xburst-tools/src/usb_boot_defines.h diff --git a/inflash/src/inflash.cfg b/xburst-tools/src/xburst_tools.cfg similarity index 98% rename from inflash/src/inflash.cfg rename to xburst-tools/src/xburst_tools.cfg index 2b16cc1..f6595c1 100644 --- a/inflash/src/inflash.cfg +++ b/xburst-tools/src/xburst_tools.cfg @@ -1,5 +1,5 @@ # -# inflash configuration file +# xburst-tools configuration file # # Utility to respond to Ingenic XBurst USB boot protocol, provide # initial boot stages and ability to access NAND on device. diff --git a/inflash/xburst_include/archdefs.h b/xburst-tools/xburst_include/archdefs.h similarity index 100% rename from inflash/xburst_include/archdefs.h rename to xburst-tools/xburst_include/archdefs.h diff --git a/inflash/xburst_include/configs.h b/xburst-tools/xburst_include/configs.h similarity index 100% rename from inflash/xburst_include/configs.h rename to xburst-tools/xburst_include/configs.h diff --git a/inflash/xburst_include/error.h b/xburst-tools/xburst_include/error.h similarity index 100% rename from inflash/xburst_include/error.h rename to xburst-tools/xburst_include/error.h diff --git a/inflash/xburst_include/jz4740.h b/xburst-tools/xburst_include/jz4740.h similarity index 100% rename from inflash/xburst_include/jz4740.h rename to xburst-tools/xburst_include/jz4740.h diff --git a/inflash/xburst_include/jz4750.h b/xburst-tools/xburst_include/jz4750.h similarity index 100% rename from inflash/xburst_include/jz4750.h rename to xburst-tools/xburst_include/jz4750.h diff --git a/inflash/xburst_include/mips.h b/xburst-tools/xburst_include/mips.h similarity index 100% rename from inflash/xburst_include/mips.h rename to xburst-tools/xburst_include/mips.h diff --git a/inflash/xburst_include/mipsregs.h b/xburst-tools/xburst_include/mipsregs.h similarity index 100% rename from inflash/xburst_include/mipsregs.h rename to xburst-tools/xburst_include/mipsregs.h diff --git a/inflash/xburst_include/nandflash.h b/xburst-tools/xburst_include/nandflash.h similarity index 100% rename from inflash/xburst_include/nandflash.h rename to xburst-tools/xburst_include/nandflash.h diff --git a/inflash/xburst_include/sysdefs.h b/xburst-tools/xburst_include/sysdefs.h similarity index 100% rename from inflash/xburst_include/sysdefs.h rename to xburst-tools/xburst_include/sysdefs.h diff --git a/inflash/xburst_include/udc.h b/xburst-tools/xburst_include/udc.h similarity index 100% rename from inflash/xburst_include/udc.h rename to xburst-tools/xburst_include/udc.h diff --git a/inflash/xburst_include/usb.h b/xburst-tools/xburst_include/usb.h similarity index 100% rename from inflash/xburst_include/usb.h rename to xburst-tools/xburst_include/usb.h diff --git a/inflash/xburst_include/usb_boot.h b/xburst-tools/xburst_include/usb_boot.h similarity index 100% rename from inflash/xburst_include/usb_boot.h rename to xburst-tools/xburst_include/usb_boot.h diff --git a/inflash/xburst_include/xburst_types.h b/xburst-tools/xburst_include/xburst_types.h similarity index 100% rename from inflash/xburst_include/xburst_types.h rename to xburst-tools/xburst_include/xburst_types.h diff --git a/inflash/xburst_stage1/Makefile b/xburst-tools/xburst_stage1/Makefile similarity index 100% rename from inflash/xburst_stage1/Makefile rename to xburst-tools/xburst_stage1/Makefile diff --git a/inflash/xburst_stage1/board_4740.c b/xburst-tools/xburst_stage1/board_4740.c similarity index 100% rename from inflash/xburst_stage1/board_4740.c rename to xburst-tools/xburst_stage1/board_4740.c diff --git a/inflash/xburst_stage1/board_4750.c b/xburst-tools/xburst_stage1/board_4750.c similarity index 100% rename from inflash/xburst_stage1/board_4750.c rename to xburst-tools/xburst_stage1/board_4750.c diff --git a/inflash/xburst_stage1/common.c b/xburst-tools/xburst_stage1/common.c similarity index 100% rename from inflash/xburst_stage1/common.c rename to xburst-tools/xburst_stage1/common.c diff --git a/inflash/xburst_stage1/debug.c b/xburst-tools/xburst_stage1/debug.c similarity index 100% rename from inflash/xburst_stage1/debug.c rename to xburst-tools/xburst_stage1/debug.c diff --git a/inflash/xburst_stage1/head.S b/xburst-tools/xburst_stage1/head.S similarity index 100% rename from inflash/xburst_stage1/head.S rename to xburst-tools/xburst_stage1/head.S diff --git a/inflash/xburst_stage1/main.c b/xburst-tools/xburst_stage1/main.c similarity index 100% rename from inflash/xburst_stage1/main.c rename to xburst-tools/xburst_stage1/main.c diff --git a/inflash/xburst_stage1/target.ld b/xburst-tools/xburst_stage1/target.ld similarity index 100% rename from inflash/xburst_stage1/target.ld rename to xburst-tools/xburst_stage1/target.ld diff --git a/inflash/xburst_stage2/Makefile b/xburst-tools/xburst_stage2/Makefile similarity index 100% rename from inflash/xburst_stage2/Makefile rename to xburst-tools/xburst_stage2/Makefile diff --git a/inflash/xburst_stage2/boothandler.c b/xburst-tools/xburst_stage2/boothandler.c similarity index 100% rename from inflash/xburst_stage2/boothandler.c rename to xburst-tools/xburst_stage2/boothandler.c diff --git a/inflash/xburst_stage2/cache.c b/xburst-tools/xburst_stage2/cache.c similarity index 100% rename from inflash/xburst_stage2/cache.c rename to xburst-tools/xburst_stage2/cache.c diff --git a/inflash/xburst_stage2/head.S b/xburst-tools/xburst_stage2/head.S similarity index 100% rename from inflash/xburst_stage2/head.S rename to xburst-tools/xburst_stage2/head.S diff --git a/inflash/xburst_stage2/main.c b/xburst-tools/xburst_stage2/main.c similarity index 100% rename from inflash/xburst_stage2/main.c rename to xburst-tools/xburst_stage2/main.c diff --git a/inflash/xburst_stage2/nandflash_4740.c b/xburst-tools/xburst_stage2/nandflash_4740.c similarity index 100% rename from inflash/xburst_stage2/nandflash_4740.c rename to xburst-tools/xburst_stage2/nandflash_4740.c diff --git a/inflash/xburst_stage2/nandflash_4750.c b/xburst-tools/xburst_stage2/nandflash_4750.c similarity index 100% rename from inflash/xburst_stage2/nandflash_4750.c rename to xburst-tools/xburst_stage2/nandflash_4750.c diff --git a/inflash/xburst_stage2/serial.c b/xburst-tools/xburst_stage2/serial.c similarity index 100% rename from inflash/xburst_stage2/serial.c rename to xburst-tools/xburst_stage2/serial.c diff --git a/inflash/xburst_stage2/target.ld b/xburst-tools/xburst_stage2/target.ld similarity index 100% rename from inflash/xburst_stage2/target.ld rename to xburst-tools/xburst_stage2/target.ld diff --git a/inflash/xburst_stage2/udc.c b/xburst-tools/xburst_stage2/udc.c similarity index 100% rename from inflash/xburst_stage2/udc.c rename to xburst-tools/xburst_stage2/udc.c