aboutsummaryrefslogtreecommitdiffstats
path: root/package/boot/uboot-xburst
diff options
context:
space:
mode:
Diffstat (limited to 'package/boot/uboot-xburst')
-rw-r--r--package/boot/uboot-xburst/Makefile88
-rw-r--r--package/boot/uboot-xburst/patches/0001-qi_lb60-add-nand-spl-support.patch894
-rw-r--r--package/boot/uboot-xburst/patches/0002-qi_lb60-add-software-usbboot-support.patch916
-rw-r--r--package/boot/uboot-xburst/patches/0003-add-mmc-support.patch1664
-rw-r--r--package/boot/uboot-xburst/patches/0004-add-more-boot-options-F1-F2-F3-F4-M-S.patch200
-rw-r--r--package/boot/uboot-xburst/patches/0005-add-nanonote-lcd-support.patch847
-rw-r--r--package/boot/uboot-xburst/patches/0006-enable-silent-console.patch60
7 files changed, 0 insertions, 4669 deletions
diff --git a/package/boot/uboot-xburst/Makefile b/package/boot/uboot-xburst/Makefile
deleted file mode 100644
index 413289a7f9..0000000000
--- a/package/boot/uboot-xburst/Makefile
+++ /dev/null
@@ -1,88 +0,0 @@
-#
-# Copyright (C) 2010 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-include $(INCLUDE_DIR)/kernel.mk
-
-PKG_NAME:=u-boot
-PKG_VERSION:=2012.10-rc2
-PKG_RELEASE:=1
-
-PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
-PKG_SOURCE_URL:= \
- http://mirror2.openwrt.org/sources \
- ftp://ftp.denx.de/pub/u-boot
-PKG_HASH:=6d094cafa7ecea8b671fbdcd21130b6a4f5744fc47dd263e101ed5d3629dffd4
-PKG_TARGETS:=bin
-
-PKG_LICENSE:=GPL-2.0 GPL-2.0+
-PKG_LICENSE_FILES:=Licenses/README
-
-include $(INCLUDE_DIR)/package.mk
-
-define uboot/Default
- TITLE:=
- CONFIG:=
- IMAGE:=
-endef
-
-define uboot/qi_lb60
- TITLE:=U-boot for the qi_lb60 board
-endef
-
-UBOOTS:=qi_lb60
-
-define Package/uboot/template
-define Package/uboot-xburst-$(1)
- SECTION:=boot
- CATEGORY:=Boot Loaders
- DEPENDS:=@TARGET_xburst
- TITLE:=$(2)
- URL:=http://www.denx.de/wiki/UBoot/WebHome
- VARIANT:=$(1)
-endef
-endef
-
-define BuildUbootPackage
- $(eval $(uboot/Default))
- $(eval $(uboot/$(1)))
- $(call Package/uboot/template,$(1),$(TITLE))
-endef
-
-
-ifdef BUILD_VARIANT
-$(eval $(call uboot/$(BUILD_VARIANT)))
-UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT))
-UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin)
-endif
-
-define Build/Configure
- $(MAKE) -C $(PKG_BUILD_DIR) \
- $(UBOOT_CONFIG)_config
-endef
-
-define Build/Compile
- $(MAKE) -C $(PKG_BUILD_DIR) \
- CROSS_COMPILE=$(TARGET_CROSS)
-endef
-
-define Package/uboot/install/template
-define Package/uboot-xburst-$(1)/install
- $(CP) $(PKG_BUILD_DIR)/u-boot-xburst.bin $(BIN_DIR)/$(2)
- rmdir $$(1)
-endef
-endef
-
-$(foreach u,$(UBOOTS), \
- $(eval $(call Package/uboot/install/template,$(u),openwrt-$(BOARD)-$(u)-u-boot.bin)) \
-)
-
-$(foreach u,$(UBOOTS), \
- $(eval $(call BuildUbootPackage,$(u))) \
- $(eval $(call BuildPackage,uboot-xburst-$(u))) \
-)
diff --git a/package/boot/uboot-xburst/patches/0001-qi_lb60-add-nand-spl-support.patch b/package/boot/uboot-xburst/patches/0001-qi_lb60-add-nand-spl-support.patch
deleted file mode 100644
index e770243528..0000000000
--- a/package/boot/uboot-xburst/patches/0001-qi_lb60-add-nand-spl-support.patch
+++ /dev/null
@@ -1,894 +0,0 @@
-From 0329cf7965956a5a7044827e0ce88ae8d5150e54 Mon Sep 17 00:00:00 2001
-From: Xiangfu <xiangfu@openmobilefree.net>
-Date: Fri, 12 Oct 2012 09:46:58 +0800
-Subject: [PATCH 1/6] qi_lb60: add nand spl support
-
- The JZ4740 CPU can load 8KB from two different addresses:
- 1. the normal area up to 8KB starting from NAND flash address 0x00000000
- 2. the backup area up to 8KB starting from NAND flash address 0x00002000
-
-Signed-off-by: Xiangfu <xiangfu@openmobilefree.net>
----
- Makefile | 12 +++
- arch/mips/cpu/xburst/Makefile | 7 +-
- arch/mips/cpu/xburst/cpu.c | 4 +
- arch/mips/cpu/xburst/jz4740.c | 82 +++++++----------
- arch/mips/cpu/xburst/spl/Makefile | 47 ++++++++++
- arch/mips/cpu/xburst/spl/start.S | 63 +++++++++++++
- board/qi/qi_lb60/Makefile | 4 +
- board/qi/qi_lb60/qi_lb60-spl.c | 30 +++++++
- board/qi/qi_lb60/qi_lb60.c | 8 +-
- board/qi/qi_lb60/u-boot-spl.lds | 61 +++++++++++++
- drivers/mtd/nand/jz4740_nand.c | 39 ++++++++-
- include/configs/qi_lb60.h | 175 ++++++++++++++++++-------------------
- 12 files changed, 386 insertions(+), 146 deletions(-)
- create mode 100644 arch/mips/cpu/xburst/spl/Makefile
- create mode 100644 arch/mips/cpu/xburst/spl/start.S
- create mode 100644 board/qi/qi_lb60/qi_lb60-spl.c
- create mode 100644 board/qi/qi_lb60/u-boot-spl.lds
-
-diff --git a/Makefile b/Makefile
-index 34d9075..a22778e 100644
---- a/Makefile
-+++ b/Makefile
-@@ -393,6 +393,10 @@ ALL-y += $(obj)u-boot-nodtb-tegra.bin
- endif
- endif
-
-+ifeq ($(CPU),xburst)
-+ALL-y += $(obj)u-boot-xburst.bin
-+endif
-+
- all: $(ALL-y) $(SUBDIR_EXAMPLES)
-
- $(obj)u-boot.dtb: $(obj)u-boot
-@@ -506,6 +510,14 @@ $(obj)u-boot-nodtb-tegra.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin
- endif
- endif
-
-+ifeq ($(CPU),xburst)
-+$(obj)u-boot-xburst.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin
-+ dd if=$(obj)spl/u-boot-spl.bin of=$(obj)spl/u-boot-pad.bin conv=sync bs=8192 count=1
-+ dd if=$(obj)spl/u-boot-spl.bin of=$(obj)spl/u-boot-pad.bin conv=sync,notrunc oflag=append bs=8192 count=1
-+ tr '\0' '\377' < /dev/zero | dd of=$(obj)spl/u-boot-pad.bin conv=sync,notrunc oflag=append bs=16384 count=1
-+ cat $(obj)spl/u-boot-pad.bin u-boot.bin > $@
-+endif
-+
- ifeq ($(CONFIG_SANDBOX),y)
- GEN_UBOOT = \
- cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \
-diff --git a/arch/mips/cpu/xburst/Makefile b/arch/mips/cpu/xburst/Makefile
-index b1f2ae4..ec35e55 100644
---- a/arch/mips/cpu/xburst/Makefile
-+++ b/arch/mips/cpu/xburst/Makefile
-@@ -24,9 +24,12 @@ include $(TOPDIR)/config.mk
-
- LIB = $(obj)lib$(CPU).o
-
-+COBJS-y = cpu.o jz_serial.o
-+
-+ifneq ($(CONFIG_SPL_BUILD),y)
- START = start.o
--SOBJS-y =
--COBJS-y = cpu.o timer.o jz_serial.o
-+COBJS-y += timer.o
-+endif
-
- COBJS-$(CONFIG_JZ4740) += jz4740.o
-
-diff --git a/arch/mips/cpu/xburst/cpu.c b/arch/mips/cpu/xburst/cpu.c
-index ddcbfaa..1432838 100644
---- a/arch/mips/cpu/xburst/cpu.c
-+++ b/arch/mips/cpu/xburst/cpu.c
-@@ -42,6 +42,8 @@
- : \
- : "i" (op), "R" (*(unsigned char *)(addr)))
-
-+#ifndef CONFIG_SPL_BUILD
-+
- void __attribute__((weak)) _machine_restart(void)
- {
- struct jz4740_wdt *wdt = (struct jz4740_wdt *)JZ4740_WDT_BASE;
-@@ -109,6 +111,8 @@ void invalidate_dcache_range(ulong start_addr, ulong stop)
- cache_op(Hit_Invalidate_D, addr);
- }
-
-+#endif
-+
- void flush_icache_all(void)
- {
- u32 addr, t = 0;
-diff --git a/arch/mips/cpu/xburst/jz4740.c b/arch/mips/cpu/xburst/jz4740.c
-index c0b9817..8816aa3 100644
---- a/arch/mips/cpu/xburst/jz4740.c
-+++ b/arch/mips/cpu/xburst/jz4740.c
-@@ -32,31 +32,19 @@ int disable_interrupts(void)
- return 0;
- }
-
--/*
-- * PLL output clock = EXTAL * NF / (NR * NO)
-- * NF = FD + 2, NR = RD + 2
-- * NO = 1 (if OD = 0), NO = 2 (if OD = 1 or 2), NO = 4 (if OD = 3)
-- */
- void pll_init(void)
- {
- struct jz4740_cpm *cpm = (struct jz4740_cpm *)JZ4740_CPM_BASE;
-
-- register unsigned int cfcr, plcr1;
-- int n2FR[33] = {
-- 0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0,
-- 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
-- 9
-- };
-- int div[5] = {1, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */
-- int nf, pllout2;
-+ register unsigned int cfcr, plcr;
-+ unsigned int nf, pllout2;
-
- cfcr = CPM_CPCCR_CLKOEN |
-- CPM_CPCCR_PCS |
-- (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) |
-- (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) |
-- (n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) |
-- (n2FR[div[3]] << CPM_CPCCR_MDIV_BIT) |
-- (n2FR[div[4]] << CPM_CPCCR_LDIV_BIT);
-+ (0 << CPM_CPCCR_CDIV_BIT) |
-+ (2 << CPM_CPCCR_HDIV_BIT) |
-+ (2 << CPM_CPCCR_PDIV_BIT) |
-+ (2 << CPM_CPCCR_MDIV_BIT) |
-+ (2 << CPM_CPCCR_LDIV_BIT);
-
- pllout2 = (cfcr & CPM_CPCCR_PCS) ?
- CONFIG_SYS_CPU_SPEED : (CONFIG_SYS_CPU_SPEED / 2);
-@@ -65,15 +53,18 @@ void pll_init(void)
- writel(pllout2 / 48000000 - 1, &cpm->uhccdr);
-
- nf = CONFIG_SYS_CPU_SPEED * 2 / CONFIG_SYS_EXTAL;
-- plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */
-+ plcr = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */
- (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */
- (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */
-- (0x20 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */
-+ (0x32 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */
- CPM_CPPCR_PLLEN; /* enable PLL */
-
- /* init PLL */
- writel(cfcr, &cpm->cpccr);
-- writel(plcr1, &cpm->cppcr);
-+ writel(plcr, &cpm->cppcr);
-+
-+ while (!(readl(&cpm->cppcr) & CPM_CPPCR_PLLS))
-+ ;
- }
-
- void sdram_init(void)
-@@ -92,26 +83,12 @@ void sdram_init(void)
- 2 << EMC_DMCR_TCL_BIT /* CAS latency is 3 */
- };
-
-- int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
--
- cpu_clk = CONFIG_SYS_CPU_SPEED;
-- mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()];
-+ mem_clk = 84000000;
-
- writel(0, &emc->bcr); /* Disable bus release */
- writew(0, &emc->rtcsr); /* Disable clock for counting */
-
-- /* Fault DMCR value for mode register setting*/
--#define SDRAM_ROW0 11
--#define SDRAM_COL0 8
--#define SDRAM_BANK40 0
--
-- dmcr0 = ((SDRAM_ROW0 - 11) << EMC_DMCR_RA_BIT) |
-- ((SDRAM_COL0 - 8) << EMC_DMCR_CA_BIT) |
-- (SDRAM_BANK40 << EMC_DMCR_BA_BIT) |
-- (SDRAM_BW16 << EMC_DMCR_BW_BIT) |
-- EMC_DMCR_EPIN |
-- cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
--
- /* Basic DMCR value */
- dmcr = ((SDRAM_ROW - 11) << EMC_DMCR_RA_BIT) |
- ((SDRAM_COL - 8) << EMC_DMCR_CA_BIT) |
-@@ -128,31 +105,31 @@ void sdram_init(void)
- if (tmp > 11)
- tmp = 11;
- dmcr |= (tmp - 4) << EMC_DMCR_TRAS_BIT;
-- tmp = SDRAM_RCD / ns;
-
-+ tmp = SDRAM_RCD / ns;
- if (tmp > 3)
- tmp = 3;
- dmcr |= tmp << EMC_DMCR_RCD_BIT;
-- tmp = SDRAM_TPC / ns;
-
-+ tmp = SDRAM_TPC / ns;
- if (tmp > 7)
- tmp = 7;
- dmcr |= tmp << EMC_DMCR_TPC_BIT;
-- tmp = SDRAM_TRWL / ns;
-
-+ tmp = SDRAM_TRWL / ns;
- if (tmp > 3)
- tmp = 3;
- dmcr |= tmp << EMC_DMCR_TRWL_BIT;
-- tmp = (SDRAM_TRAS + SDRAM_TPC) / ns;
-
-+ tmp = (SDRAM_TRAS + SDRAM_TPC) / ns;
- if (tmp > 14)
- tmp = 14;
- dmcr |= ((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT;
-
- /* SDRAM mode value */
-- sdmode = EMC_SDMR_BT_SEQ |
-- EMC_SDMR_OM_NORMAL |
-- EMC_SDMR_BL_4 |
-+ sdmode = EMC_SDMR_BT_SEQ |
-+ EMC_SDMR_OM_NORMAL |
-+ EMC_SDMR_BL_4 |
- cas_latency_sdmr[((SDRAM_CASL == 3) ? 1 : 0)];
-
- /* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */
-@@ -172,8 +149,8 @@ void sdram_init(void)
- if (tmp > 0xff)
- tmp = 0xff;
- writew(tmp, &emc->rtcor);
-+
- writew(0, &emc->rtcnt);
-- /* Divisor is 64, CKO/64 */
- writew(EMC_RTCSR_CKS_64, &emc->rtcsr);
-
- /* Wait for number of auto-refresh cycles */
-@@ -182,13 +159,17 @@ void sdram_init(void)
- ;
-
- /* Stage 3. Mode Register Set */
-+ dmcr0 = (11 << EMC_DMCR_RA_BIT) |
-+ (8 << EMC_DMCR_CA_BIT) |
-+ (0 << EMC_DMCR_BA_BIT) |
-+ EMC_DMCR_EPIN |
-+ (SDRAM_BW16 << EMC_DMCR_BW_BIT) |
-+ cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
- writel(dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET, &emc->dmcr);
- writeb(0, JZ4740_EMC_SDMR0 | sdmode);
-
- /* Set back to basic DMCR value */
- writel(dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET, &emc->dmcr);
--
-- /* everything is ok now */
- }
-
- DECLARE_GLOBAL_DATA_PTR;
-@@ -232,9 +213,10 @@ void rtc_init(void)
- phys_size_t initdram(int board_type)
- {
- struct jz4740_emc *emc = (struct jz4740_emc *)JZ4740_EMC_BASE;
-- u32 dmcr;
-- u32 rows, cols, dw, banks;
-- ulong size;
-+
-+ unsigned int dmcr;
-+ unsigned int rows, cols, dw, banks;
-+ unsigned long size;
-
- dmcr = readl(&emc->dmcr);
- rows = 11 + ((dmcr & EMC_DMCR_RA_MASK) >> EMC_DMCR_RA_BIT);
-diff --git a/arch/mips/cpu/xburst/spl/Makefile b/arch/mips/cpu/xburst/spl/Makefile
-new file mode 100644
-index 0000000..f45e8c8
---- /dev/null
-+++ b/arch/mips/cpu/xburst/spl/Makefile
-@@ -0,0 +1,47 @@
-+#
-+# Copyright (C) 2011 Xiangfu Liu <xiangfu@openmobilefree.net>
-+#
-+# 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 $(TOPDIR)/config.mk
-+
-+LIB = $(obj)lib$(CPU).o
-+
-+START = start.o
-+SOBJS-y =
-+COBJS-y =
-+
-+SRCS := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
-+OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
-+START := $(addprefix $(obj),$(START))
-+
-+all: $(obj).depend $(START) $(LIB)
-+
-+$(LIB): $(OBJS)
-+ $(call cmd_link_o_target, $(OBJS))
-+
-+#########################################################################
-+
-+# defines $(obj).depend target
-+include $(SRCTREE)/rules.mk
-+
-+sinclude $(obj).depend
-+
-+#########################################################################
-diff --git a/arch/mips/cpu/xburst/spl/start.S b/arch/mips/cpu/xburst/spl/start.S
-new file mode 100644
-index 0000000..e31c4c8
---- /dev/null
-+++ b/arch/mips/cpu/xburst/spl/start.S
-@@ -0,0 +1,63 @@
-+/*
-+ * Copyright (c) 2010 Xiangfu Liu <xiangfu@openmobilefree.net>
-+ *
-+ * 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 3 of
-+ * the License, or (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-+ * MA 02111-1307 USA
-+ */
-+
-+#include <config.h>
-+#include <version.h>
-+#include <asm/regdef.h>
-+#include <asm/mipsregs.h>
-+#include <asm/addrspace.h>
-+#include <asm/cacheops.h>
-+
-+#include <asm/jz4740.h>
-+
-+ .set noreorder
-+
-+ .globl _start
-+ .text
-+_start:
-+ .word JZ4740_NANDBOOT_CFG /* fetched during NAND Boot */
-+reset:
-+ /*
-+ * STATUS register
-+ * CU0=UM=EXL=IE=0, BEV=ERL=1, IP2~7=1
-+ */
-+ li t0, 0x0040FC04
-+ mtc0 t0, CP0_STATUS
-+ /*
-+ * CAUSE register
-+ * IV=1, use the specical interrupt vector (0x200)
-+ */
-+ li t1, 0x00800000
-+ mtc0 t1, CP0_CAUSE
-+
-+ bal 1f
-+ nop
-+ .word _GLOBAL_OFFSET_TABLE_
-+1:
-+ move gp, ra
-+ lw t1, 0(ra)
-+ move gp, t1
-+
-+ la sp, 0x80004000
-+ la t9, nand_spl_boot
-+ j t9
-+ nop
-diff --git a/board/qi/qi_lb60/Makefile b/board/qi/qi_lb60/Makefile
-index 5dae11b..e399246 100644
---- a/board/qi/qi_lb60/Makefile
-+++ b/board/qi/qi_lb60/Makefile
-@@ -22,7 +22,11 @@ include $(TOPDIR)/config.mk
-
- LIB = $(obj)lib$(BOARD).o
-
-+ifeq ($(CONFIG_SPL_BUILD),y)
-+COBJS := $(BOARD)-spl.o
-+else
- COBJS := $(BOARD).o
-+endif
-
- SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
- OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
-diff --git a/board/qi/qi_lb60/qi_lb60-spl.c b/board/qi/qi_lb60/qi_lb60-spl.c
-new file mode 100644
-index 0000000..3fe3fa3
---- /dev/null
-+++ b/board/qi/qi_lb60/qi_lb60-spl.c
-@@ -0,0 +1,30 @@
-+/*
-+ * Authors: Xiangfu Liu <xiangfu@openmobilefree.cc>
-+ *
-+ * 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
-+ * 3 of the License, or (at your option) any later version.
-+ */
-+
-+#include <common.h>
-+#include <nand.h>
-+#include <asm/io.h>
-+#include <asm/jz4740.h>
-+
-+void nand_spl_boot(void)
-+{
-+ __gpio_as_sdram_16bit_4720();
-+ __gpio_as_uart0();
-+ __gpio_jtag_to_uart0();
-+
-+ serial_init();
-+
-+ pll_init();
-+ sdram_init();
-+
-+ nand_init();
-+
-+ puts("\nQi LB60 SPL: Starting U-Boot ...\n");
-+ nand_boot();
-+}
-diff --git a/board/qi/qi_lb60/qi_lb60.c b/board/qi/qi_lb60/qi_lb60.c
-index d975209..3bd4e2f 100644
---- a/board/qi/qi_lb60/qi_lb60.c
-+++ b/board/qi/qi_lb60/qi_lb60.c
-@@ -1,5 +1,5 @@
- /*
-- * Authors: Xiangfu Liu <xiangfu@sharism.cc>
-+ * Authors: Xiangfu Liu <xiangfu@openmobilefree.net>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
-@@ -97,8 +97,10 @@ int board_early_init_f(void)
- /* U-Boot common routines */
- int checkboard(void)
- {
-- printf("Board: Qi LB60 (Ingenic XBurst Jz4740 SoC, Speed %ld MHz)\n",
-- gd->cpu_clk / 1000000);
-+ printf("Board: Qi LB60 (Ingenic XBurst Jz4740 SoC)\n");
-+ printf(" CPU: %ld\n", gd->cpu_clk);
-+ printf(" MEM: %ld\n", gd->mem_clk);
-+ printf(" DEV: %ld\n", gd->dev_clk);
-
- return 0;
- }
-diff --git a/board/qi/qi_lb60/u-boot-spl.lds b/board/qi/qi_lb60/u-boot-spl.lds
-new file mode 100644
-index 0000000..930537f
---- /dev/null
-+++ b/board/qi/qi_lb60/u-boot-spl.lds
-@@ -0,0 +1,61 @@
-+/*
-+ * (C) Copyright 2012 Xiangfu Liu <xiangfu@openmobilefree.net>
-+ *
-+ * 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-tradlittlemips", "elf32-tradlittlemips", "elf32-tradlittlemips")
-+
-+OUTPUT_ARCH(mips)
-+ENTRY(_start)
-+SECTIONS
-+{
-+ . = 0x80000000;
-+ . = ALIGN(4);
-+ .text :
-+ {
-+ *(.text)
-+ }
-+
-+ . = ALIGN(4);
-+ .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
-+
-+ . = ALIGN(4);
-+ .data : { *(.data) }
-+
-+ . = ALIGN(4);
-+ .sdata : { *(.sdata) }
-+
-+ _gp = ALIGN(16);
-+
-+ __got_start = .;
-+ .got : { *(.got) }
-+ __got_end = .;
-+
-+ . = .;
-+ __u_boot_cmd_start = .;
-+ .u_boot_cmd : { *(.u_boot_cmd) }
-+ __u_boot_cmd_end = .;
-+
-+ uboot_end_data = .;
-+ num_got_entries = (__got_end - __got_start) >> 2;
-+
-+ . = ALIGN(4);
-+ .sbss : { *(.sbss) }
-+ .bss : { *(.bss) }
-+ uboot_end = .;
-+}
-+ASSERT(uboot_end <= 0x80002000, "NAND bootstrap too big");
-diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c
-index 3ec34f3..24a4921 100644
---- a/drivers/mtd/nand/jz4740_nand.c
-+++ b/drivers/mtd/nand/jz4740_nand.c
-@@ -15,6 +15,9 @@
- #include <asm/io.h>
- #include <asm/jz4740.h>
-
-+#ifdef CONFIG_SPL_BUILD
-+#define printf(s) puts(s)
-+#endif
- #define JZ_NAND_DATA_ADDR ((void __iomem *)0xB8000000)
- #define JZ_NAND_CMD_ADDR (JZ_NAND_DATA_ADDR + 0x8000)
- #define JZ_NAND_ADDR_ADDR (JZ_NAND_DATA_ADDR + 0x10000)
-@@ -176,7 +179,7 @@ static int jz_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat,
- for (k = 0; k < 9; k++)
- writeb(read_ecc[k], &emc->nfpar[k]);
- }
-- /* Set PRDY */
-+
- writel(readl(&emc->nfecr) | EMC_NFECR_PRDY, &emc->nfecr);
-
- /* Wait for completion */
-@@ -184,7 +187,7 @@ static int jz_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat,
- status = readl(&emc->nfints);
- } while (!(status & EMC_NFINTS_DECF));
-
-- /* disable ecc */
-+ /* Disable ECC */
- writel(readl(&emc->nfecr) & ~EMC_NFECR_ECCE, &emc->nfecr);
-
- /* Check decoding */
-@@ -192,7 +195,7 @@ static int jz_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat,
- return 0;
-
- if (status & EMC_NFINTS_UNCOR) {
-- printf("uncorrectable ecc\n");
-+ printf("JZ4740 uncorrectable ECC\n");
- return -1;
- }
-
-@@ -230,6 +233,32 @@ static int jz_nand_rs_correct_data(struct mtd_info *mtd, u_char *dat,
- return errcnt;
- }
-
-+#ifdef CONFIG_SPL_BUILD
-+static void jz_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
-+{
-+ int i;
-+ struct nand_chip *this = mtd->priv;
-+
-+#if (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B16R3) || \
-+ (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B16R2)
-+ for (i = 0; i < len; i += 2)
-+ buf[i] = readw(this->IO_ADDR_R);
-+#elif (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B8R3) || \
-+ (JZ4740_NANDBOOT_CFG == JZ4740_NANDBOOT_B8R2)
-+ for (i = 0; i < len; i++)
-+ buf[i] = readb(this->IO_ADDR_R);
-+#else
-+ #error JZ4740_NANDBOOT_CFG not defined or wrong
-+#endif
-+}
-+
-+static uint8_t jz_nand_read_byte(struct mtd_info *mtd)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ return readb(this->IO_ADDR_R);
-+}
-+#endif
-+
- /*
- * Main initialization routine
- */
-@@ -254,6 +283,10 @@ int board_nand_init(struct nand_chip *nand)
- nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
- nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
- nand->ecc.layout = &qi_lb60_ecclayout_2gb;
-+#ifdef CONFIG_SPL_BUILD
-+ nand->read_byte = jz_nand_read_byte;
-+ nand->read_buf = jz_nand_read_buf;
-+#endif
- nand->chip_delay = 50;
- nand->options = NAND_USE_FLASH_BBT;
-
-diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h
-index 4bb5bbc..7bff444 100644
---- a/include/configs/qi_lb60.h
-+++ b/include/configs/qi_lb60.h
-@@ -1,5 +1,5 @@
- /*
-- * Authors: Xiangfu Liu <xiangfu.z@gmail.com>
-+ * Authors: Xiangfu Liu <xiangfu@openmobilefree.net>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
-@@ -14,7 +14,6 @@
- #define CONFIG_SYS_LITTLE_ENDIAN
- #define CONFIG_JZSOC /* Jz SoC */
- #define CONFIG_JZ4740 /* Jz4740 SoC */
--#define CONFIG_NAND_JZ4740
-
- #define CONFIG_SYS_CPU_SPEED 336000000 /* CPU clock: 336 MHz */
- #define CONFIG_SYS_EXTAL 12000000 /* EXTAL freq: 12 MHz */
-@@ -24,24 +23,43 @@
- #define CONFIG_SYS_UART_BASE JZ4740_UART0_BASE /* Base of the UART channel */
- #define CONFIG_BAUDRATE 57600
-
-+#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAUL)
-+#define CONFIG_BOOTDELAY 0
-+#define CONFIG_BOOTARGS "mem=32M console=tty0 console=ttyS0,57600n8 ubi.mtd=2 rootfstype=ubifs root=ubi0:rootfs rw rootwait"
-+#define CONFIG_BOOTCOMMAND "nand read 0x80600000 0x400000 0x280000;bootm"
-+
-+/*
-+ * Miscellaneous configurable options
-+ */
-+#define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */
-+#define CONFIG_SYS_INIT_SP_OFFSET 0x400000
-+#define CONFIG_SYS_LOAD_ADDR 0x80600000
-+#define CONFIG_SYS_MEMTEST_START 0x80100000
-+#define CONFIG_SYS_MEMTEST_END 0x80A00000
-+#define CONFIG_SYS_TEXT_BASE 0x80100000
-+#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
-+
-+#define CONFIG_SYS_MALLOC_LEN (4 * 1024 * 1024)
-+#define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024)
-+
-+#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
-+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
-+
-+#define CONFIG_SYS_LONGHELP
-+#define CONFIG_SYS_MAXARGS 16
-+#define CONFIG_SYS_PROMPT "NanoNote# "
-+
- #define CONFIG_SKIP_LOWLEVEL_INIT
- #define CONFIG_BOARD_EARLY_INIT_F
- #define CONFIG_SYS_NO_FLASH
- #define CONFIG_SYS_FLASH_BASE 0 /* init flash_base as 0 */
--#define CONFIG_ENV_OVERWRITE
--
--#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAUL)
--#define CONFIG_BOOTDELAY 0
--#define CONFIG_BOOTARGS "mem=32M console=tty0 console=ttyS0,57600n8 ubi.mtd=2 rootfstype=ubifs root=ubi0:rootfs rw rootwait"
--#define CONFIG_BOOTCOMMAND "nand read 0x80600000 0x400000 0x200000;bootm"
-
- /*
-- * Command line configuration.
-+ * Command line configuration
- */
- #define CONFIG_CMD_BOOTD /* bootd */
- #define CONFIG_CMD_CONSOLE /* coninfo */
- #define CONFIG_CMD_ECHO /* echo arguments */
--
- #define CONFIG_CMD_LOADB /* loadb */
- #define CONFIG_CMD_LOADS /* loads */
- #define CONFIG_CMD_MEMORY /* md mm nm mw cp cmp crc base loop mtest */
-@@ -58,45 +76,16 @@
- #define CONFIG_LOADS_ECHO 1 /* echo on for serial download */
-
- /*
-- * Miscellaneous configurable options
-- */
--#define CONFIG_SYS_MAXARGS 16
--#define CONFIG_SYS_LONGHELP
--#define CONFIG_SYS_PROMPT "NanoNote# "
--#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
--#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
--
--#define CONFIG_SYS_MALLOC_LEN (4 * 1024 * 1024)
--#define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024)
--
--#define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */
--#define CONFIG_SYS_INIT_SP_OFFSET 0x400000
--#define CONFIG_SYS_LOAD_ADDR 0x80600000
--#define CONFIG_SYS_MEMTEST_START 0x80100000
--#define CONFIG_SYS_MEMTEST_END 0x80800000
--
--/*
-- * Environment
-+ * NAND driver configuration
- */
--#define CONFIG_ENV_IS_IN_NAND /* use NAND for environment vars */
--
--#define CONFIG_SYS_NAND_5_ADDR_CYCLE
--/*
-- * if board nand flash is 1GB, set to 1
-- * if board nand flash is 2GB, set to 2
-- * for change the PAGE_SIZE and BLOCK_SIZE
-- * will delete when there is no 1GB flash
-- */
--#define NANONOTE_NAND_SIZE 2
--
--#define CONFIG_SYS_NAND_PAGE_SIZE (2048 * NANONOTE_NAND_SIZE)
--#define CONFIG_SYS_NAND_BLOCK_SIZE (256 * NANONOTE_NAND_SIZE << 10)
--/* nand bad block was marked at this page in a block, start from 0 */
-+#define CONFIG_NAND_JZ4740
-+#define CONFIG_SYS_NAND_PAGE_SIZE 4096
-+#define CONFIG_SYS_NAND_BLOCK_SIZE (512 << 10)
-+/* NAND bad block was marked at this page in a block, start from 0 */
- #define CONFIG_SYS_NAND_BADBLOCK_PAGE 127
- #define CONFIG_SYS_NAND_PAGE_COUNT 128
- #define CONFIG_SYS_NAND_BAD_BLOCK_POS 0
--/* ECC offset position in oob area, default value is 6 if it isn't defined */
--#define CONFIG_SYS_NAND_ECC_POS (6 * NANONOTE_NAND_SIZE)
-+#define CONFIG_SYS_NAND_ECC_POS 12
- #define CONFIG_SYS_NAND_ECCSIZE 512
- #define CONFIG_SYS_NAND_ECCBYTES 9
- #define CONFIG_SYS_NAND_ECCPOS \
-@@ -115,10 +104,9 @@
- #define CONFIG_SYS_ONENAND_BASE CONFIG_SYS_NAND_BASE
- #define CONFIG_SYS_MAX_NAND_DEVICE 1
- #define CONFIG_SYS_NAND_SELECT_DEVICE 1 /* nand driver supports mutipl.*/
--#define CONFIG_NAND_SPL_TEXT_BASE 0x80000000
-
- /*
-- * IPL (Initial Program Loader, integrated inside CPU)
-+ * IPL (Initial Program Loader, integrated inside Ingenic Xburst JZ4740 CPU)
- * Will load first 8k from NAND (SPL) into cache and execute it from there.
- *
- * SPL (Secondary Program Loader)
-@@ -130,77 +118,88 @@
- * NUB (NAND U-Boot)
- * This NAND U-Boot (NUB) is a special U-Boot version which can be started
- * from RAM. Therefore it mustn't (re-)configure the SDRAM controller.
-- *
- */
-+
-+/*
-+ * NAND SPL configuration
-+ */
-+#define CONFIG_SPL
-+#define CONFIG_SPL_LIBGENERIC_SUPPORT
-+#define CONFIG_SPL_LIBCOMMON_SUPPORT
-+#define CONFIG_SPL_NAND_LOAD
-+#define CONFIG_SPL_NAND_SIMPLE
-+#define CONFIG_SPL_NAND_SUPPORT
-+#define CONFIG_SPL_TEXT_BASE 0x80000000
-+#define CONFIG_SPL_START_S_PATH "arch/mips/cpu/xburst/spl"
-+
-+#define CONFIG_SYS_NAND_5_ADDR_CYCLE
-+#define CONFIG_SYS_NAND_HW_ECC_OOBFIRST
-+#define JZ4740_NANDBOOT_CFG JZ4740_NANDBOOT_B8R3
-+
- #define CONFIG_SYS_NAND_U_BOOT_DST 0x80100000 /* Load NUB to this addr */
- #define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_NAND_U_BOOT_DST
--/* Start NUB from this addr*/
-+ /* Start NUB from this addr */
-+#define CONFIG_SYS_NAND_U_BOOT_OFFS (32 << 10) /* Offset of NUB */
-+#define CONFIG_SYS_NAND_U_BOOT_SIZE (256 << 10) /* Size of NUB */
-
- /*
-- * Define the partitioning of the NAND chip (only RAM U-Boot is needed here)
-+ * Environment configuration
- */
--#define CONFIG_SYS_NAND_U_BOOT_OFFS (256 << 10) /* Offset to RAM U-Boot image */
--#define CONFIG_SYS_NAND_U_BOOT_SIZE (512 << 10) /* Size of RAM U-Boot image */
--
-+#define CONFIG_ENV_OVERWRITE
-+#define CONFIG_ENV_IS_IN_NAND
- #define CONFIG_ENV_SIZE (4 << 10)
- #define CONFIG_ENV_OFFSET \
- (CONFIG_SYS_NAND_BLOCK_SIZE + CONFIG_SYS_NAND_U_BOOT_SIZE)
- #define CONFIG_ENV_OFFSET_REDUND \
- (CONFIG_ENV_OFFSET + CONFIG_SYS_NAND_BLOCK_SIZE)
-
--#define CONFIG_SYS_TEXT_BASE 0x80100000
--#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
--
- /*
-- * SDRAM Info.
-+ * CPU cache configuration
- */
--#define CONFIG_NR_DRAM_BANKS 1
-+#define CONFIG_SYS_DCACHE_SIZE 16384
-+#define CONFIG_SYS_ICACHE_SIZE 16384
-+#define CONFIG_SYS_CACHELINE_SIZE 32
-
- /*
-- * Cache Configuration
-+ * SDRAM configuration
- */
--#define CONFIG_SYS_DCACHE_SIZE 16384
--#define CONFIG_SYS_ICACHE_SIZE 16384
--#define CONFIG_SYS_CACHELINE_SIZE 32
-+#define CONFIG_NR_DRAM_BANKS 1
-+
-+#define SDRAM_BW16 1 /* Data bus width: 0-32bit, 1-16bit */
-+#define SDRAM_BANK4 1 /* Banks each chip: 0-2bank, 1-4bank */
-+#define SDRAM_ROW 13 /* Row address: 11 to 13 */
-+#define SDRAM_COL 9 /* Column address: 8 to 12 */
-+#define SDRAM_CASL 2 /* CAS latency: 2 or 3 */
-+#define SDRAM_TRAS 45 /* RAS# Active Time */
-+#define SDRAM_RCD 20 /* RAS# to CAS# Delay */
-+#define SDRAM_TPC 20 /* RAS# Precharge Time */
-+#define SDRAM_TRWL 7 /* Write Latency Time */
-+#define SDRAM_TREF 15625 /* Refresh period: 8192 cycles/64ms */
-
- /*
-- * GPIO definition
-+ * GPIO configuration
- */
--#define GPIO_LCD_CS (2 * 32 + 21)
--#define GPIO_AMP_EN (3 * 32 + 4)
-+#define GPIO_LCD_CS (2 * 32 + 21)
-+#define GPIO_AMP_EN (3 * 32 + 4)
-
--#define GPIO_SDPW_EN (3 * 32 + 2)
--#define GPIO_SD_DETECT (3 * 32 + 0)
-+#define GPIO_SDPW_EN (3 * 32 + 2)
-+#define GPIO_SD_DETECT (3 * 32 + 0)
-
--#define GPIO_BUZZ_PWM (3 * 32 + 27)
--#define GPIO_USB_DETECT (3 * 32 + 28)
-+#define GPIO_BUZZ_PWM (3 * 32 + 27)
-+#define GPIO_USB_DETECT (3 * 32 + 28)
-
--#define GPIO_AUDIO_POP (1 * 32 + 29)
--#define GPIO_COB_TEST (1 * 32 + 30)
-+#define GPIO_AUDIO_POP (1 * 32 + 29)
-+#define GPIO_COB_TEST (1 * 32 + 30)
-
- #define GPIO_KEYOUT_BASE (2 * 32 + 10)
--#define GPIO_KEYIN_BASE (3 * 32 + 18)
--#define GPIO_KEYIN_8 (3 * 32 + 26)
-+#define GPIO_KEYIN_BASE (3 * 32 + 18)
-+#define GPIO_KEYIN_8 (3 * 32 + 26)
-
--#define GPIO_SD_CD_N GPIO_SD_DETECT /* SD Card insert detect */
-+#define GPIO_SD_CD_N GPIO_SD_DETECT /* SD Card insert detect */
- #define GPIO_SD_VCC_EN_N GPIO_SDPW_EN /* SD Card Power Enable */
-
- #define SPEN GPIO_LCD_CS /* LCDCS :Serial command enable */
- #define SPDA (2 * 32 + 22) /* LCDSCL:Serial command clock input */
- #define SPCK (2 * 32 + 23) /* LCDSDA:Serial command data input */
-
--/* SDRAM paramters */
--#define SDRAM_BW16 1 /* Data bus width: 0-32bit, 1-16bit */
--#define SDRAM_BANK4 1 /* Banks each chip: 0-2bank, 1-4bank */
--#define SDRAM_ROW 13 /* Row address: 11 to 13 */
--#define SDRAM_COL 9 /* Column address: 8 to 12 */
--#define SDRAM_CASL 2 /* CAS latency: 2 or 3 */
--
--/* SDRAM Timings, unit: ns */
--#define SDRAM_TRAS 45 /* RAS# Active Time */
--#define SDRAM_RCD 20 /* RAS# to CAS# Delay */
--#define SDRAM_TPC 20 /* RAS# Precharge Time */
--#define SDRAM_TRWL 7 /* Write Latency Time */
--#define SDRAM_TREF 15625 /* Refresh period: 8192 cycles/64ms */
--
- #endif
---
-1.7.9.5
-
diff --git a/package/boot/uboot-xburst/patches/0002-qi_lb60-add-software-usbboot-support.patch b/package/boot/uboot-xburst/patches/0002-qi_lb60-add-software-usbboot-support.patch
deleted file mode 100644
index feaf297b7c..0000000000
--- a/package/boot/uboot-xburst/patches/0002-qi_lb60-add-software-usbboot-support.patch
+++ /dev/null
@@ -1,916 +0,0 @@
-From fa51192b912d296b8eec10f7d44c6c17eb1dd368 Mon Sep 17 00:00:00 2001
-From: Xiangfu <xiangfu@openmobilefree.net>
-Date: Fri, 12 Oct 2012 09:47:39 +0800
-Subject: [PATCH 2/6] qi_lb60: add software usbboot support
-
- JZ4740 CPU have a internal ROM have such kind of code, that make
- JZ4740 can boot from USB
-
- usbboot.S can downloads user program from the USB port to internal
- SRAM and branches to the internal SRAM to execute the program
-
-Signed-off-by: Xiangfu <xiangfu@openmobilefree.net>
----
- board/qi/qi_lb60/Makefile | 1 +
- board/qi/qi_lb60/qi_lb60-spl.c | 20 +
- board/qi/qi_lb60/usbboot.S | 838 ++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 859 insertions(+)
- create mode 100644 board/qi/qi_lb60/usbboot.S
-
-diff --git a/board/qi/qi_lb60/Makefile b/board/qi/qi_lb60/Makefile
-index e399246..6dd8c6f 100644
---- a/board/qi/qi_lb60/Makefile
-+++ b/board/qi/qi_lb60/Makefile
-@@ -23,6 +23,7 @@ include $(TOPDIR)/config.mk
- LIB = $(obj)lib$(BOARD).o
-
- ifeq ($(CONFIG_SPL_BUILD),y)
-+SOBJS := usbboot.o
- COBJS := $(BOARD)-spl.o
- else
- COBJS := $(BOARD).o
-diff --git a/board/qi/qi_lb60/qi_lb60-spl.c b/board/qi/qi_lb60/qi_lb60-spl.c
-index 3fe3fa3..aea459c 100644
---- a/board/qi/qi_lb60/qi_lb60-spl.c
-+++ b/board/qi/qi_lb60/qi_lb60-spl.c
-@@ -12,6 +12,24 @@
- #include <asm/io.h>
- #include <asm/jz4740.h>
-
-+#define KEY_U_OUT (32 * 2 + 16)
-+#define KEY_U_IN (32 * 3 + 19)
-+
-+extern void usb_boot(void);
-+
-+static void check_usb_boot(void)
-+{
-+ __gpio_as_input(KEY_U_IN);
-+ __gpio_enable_pull(KEY_U_IN);
-+ __gpio_as_output(KEY_U_OUT);
-+ __gpio_clear_pin(KEY_U_OUT);
-+
-+ if (!__gpio_get_pin(KEY_U_IN)) {
-+ puts("[U] pressed, goto USBBOOT mode\n");
-+ usb_boot();
-+ }
-+}
-+
- void nand_spl_boot(void)
- {
- __gpio_as_sdram_16bit_4720();
-@@ -23,6 +41,8 @@ void nand_spl_boot(void)
- pll_init();
- sdram_init();
-
-+ check_usb_boot();
-+
- nand_init();
-
- puts("\nQi LB60 SPL: Starting U-Boot ...\n");
-diff --git a/board/qi/qi_lb60/usbboot.S b/board/qi/qi_lb60/usbboot.S
-new file mode 100644
-index 0000000..c872266
---- /dev/null
-+++ b/board/qi/qi_lb60/usbboot.S
-@@ -0,0 +1,838 @@
-+/*
-+ * for jz4740 usb boot
-+ *
-+ * Copyright (c) 2009 Author: <jlwei@ingenic.cn>
-+ *
-+ * 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
-+ */
-+ .set noreorder
-+ .globl usb_boot
-+ .text
-+
-+/*
-+ * Both NAND and USB boot load data to D-Cache first, then transfer
-+ * data from D-Cache to I-Cache, and jump to execute the code in I-Cache.
-+ * So init caches first and then dispatch to a proper boot routine.
-+ */
-+
-+.macro load_addr reg addr
-+ li \reg, 0x80000000
-+ addiu \reg, \reg, \addr
-+ la $2, usbboot_begin
-+ subu \reg, \reg, $2
-+.endm
-+
-+usb_boot:
-+ /* Initialize PLL: set ICLK to 84MHz and HCLK to 42MHz. */
-+ la $9, 0xB0000000 /* CPCCR: Clock Control Register */
-+ la $8, 0x42041110 /* I:S:M:P=1:2:2:2 */
-+ sw $8, 0($9)
-+
-+ la $9, 0xB0000010 /* CPPCR: PLL Control Register */
-+ la $8, 0x06000120 /* M=12 N=0 D=0 CLK=12*(M+2)/(N+2) */
-+ sw $8, 0($9)
-+
-+ mtc0 $0, $26 /* CP0_ERRCTL, restore WST reset state */
-+ nop
-+
-+ mtc0 $0, $16 /* CP0_CONFIG */
-+ nop
-+
-+ /* Relocate code to beginning of the ram */
-+
-+ la $2, usbboot_begin
-+ la $3, usbboot_end
-+ li $4, 0x80000000
-+
-+1:
-+ lw $5, 0($2)
-+ sw $5, 0($4)
-+ addiu $2, $2, 4
-+ bne $2, $3, 1b
-+ addiu $4, $4, 4
-+
-+ li $2, 0x80000000
-+ ori $3, $2, 0
-+ addiu $3, $3, usbboot_end
-+ la $4, usbboot_begin
-+ subu $3, $3, $4
-+
-+
-+2:
-+ cache 0x0, 0($2) /* Index_Invalidate_I */
-+ cache 0x1, 0($2) /* Index_Writeback_Inv_D */
-+ addiu $2, $2, 32
-+ subu $4, $3, $2
-+ bgtz $4, 2b
-+ nop
-+
-+ load_addr $3, usb_boot_return
-+
-+ jr $3
-+
-+usbboot_begin:
-+
-+init_caches:
-+ li $2, 3 /* cacheable for kseg0 access */
-+ mtc0 $2, $16 /* CP0_CONFIG */
-+ nop
-+
-+ li $2, 0x20000000 /* enable idx-store-data cache insn */
-+ mtc0 $2, $26 /* CP0_ERRCTL */
-+
-+ ori $2, $28, 0 /* start address */
-+ ori $3, $2, 0x3fe0 /* end address, total 16KB */
-+ mtc0 $0, $28, 0 /* CP0_TAGLO */
-+ mtc0 $0, $28, 1 /* CP0_DATALO */
-+cache_clear_a_line:
-+ cache 0x8, 0($2) /* Index_Store_Tag_I */
-+ cache 0x9, 0($2) /* Index_Store_Tag_D */
-+ bne $2, $3, cache_clear_a_line
-+ addiu $2, $2, 32 /* increment CACHE_LINE_SIZE */
-+
-+ ori $2, $28, 0 /* start address */
-+ ori $3, $2, 0x3fe0 /* end address, total 16KB */
-+ la $4, 0x1ffff000 /* physical address and 4KB page mask */
-+cache_alloc_a_line:
-+ and $5, $2, $4
-+ ori $5, $5, 1 /* V bit of the physical tag */
-+ mtc0 $5, $28, 0 /* CP0_TAGLO */
-+ cache 0x8, 0($2) /* Index_Store_Tag_I */
-+ cache 0x9, 0($2) /* Index_Store_Tag_D */
-+ bne $2, $3, cache_alloc_a_line
-+ addiu $2, $2, 32 /* increment CACHE_LINE_SIZE */
-+
-+ nop
-+ nop
-+ nop
-+ /*
-+ * Transfer data from dcache to icache, then jump to icache.
-+ * Input parameters:
-+ * $19: data length in bytes
-+ * $20: jump target address
-+ */
-+xfer_d2i:
-+
-+ ori $8, $20, 0
-+ addu $9, $8, $19 /* total 16KB */
-+
-+1:
-+ cache 0x0, 0($8) /* Index_Invalidate_I */
-+ cache 0x1, 0($8) /* Index_Writeback_Inv_D */
-+ bne $8, $9, 1b
-+ addiu $8, $8, 32
-+
-+ /* flush write-buffer */
-+ sync
-+
-+ /* Invalidate BTB */
-+ mfc0 $8, $16, 7 /* CP0_CONFIG */
-+ nop
-+ ori $8, 2
-+ mtc0 $8, $16, 7
-+ nop
-+
-+ /* Overwrite config to disable ram initalisation */
-+ li $2, 0xff
-+ sb $2, 20($20)
-+
-+ jalr $20
-+ nop
-+
-+icache_return:
-+ /* User code can return to here after executing itself in
-+ icache, by jumping to $31. */
-+ b usb_boot_return
-+ nop
-+
-+
-+usb_boot_return:
-+ /* Enable the USB PHY */
-+ la $9, 0xB0000024 /* CPM_SCR */
-+ lw $8, 0($9)
-+ ori $8, 0x40 /* USBPHY_ENABLE */
-+ sw $8, 0($9)
-+
-+ /* Initialize USB registers */
-+ la $27, 0xb3040000 /* USB registers base address */
-+
-+ sb $0, 0x0b($27) /* INTRUSBE: disable common USB interrupts */
-+ sh $0, 0x06($27) /* INTRINE: disable EPIN interrutps */
-+ sh $0, 0x08($27) /* INTROUTE: disable EPOUT interrutps */
-+
-+ li $9, 0x61
-+ sb $9, 0x01($27) /* POWER: HSENAB | SUSPENDM | SOFTCONN */
-+
-+ /* Initialize USB states */
-+ li $22, 0 /* set EP0 to IDLE state */
-+ li $23, 1 /* no data stage */
-+
-+ /* Main loop of polling the usb commands */
-+usb_command_loop:
-+ lbu $9, 0x0a($27) /* read INTRUSB */
-+ andi $9, 0x04 /* check USB_INTR_RESET */
-+ beqz $9, check_intr_ep0in
-+ nop
-+
-+ /* 1. Handle USB reset interrupt */
-+handle_reset_intr:
-+ lbu $9, 0x01($27) /* read POWER */
-+ andi $9, 0x10 /* test HS_MODE */
-+ bnez $9, _usb_set_maxpktsize
-+ li $9, 512 /* max packet size of HS mode */
-+ li $9, 64 /* max packet size of FS mode */
-+
-+_usb_set_maxpktsize:
-+ li $8, 1
-+ sb $8, 0x0e($27) /* set INDEX 1 */
-+
-+ sh $9, 0x10($27) /* INMAXP */
-+ sb $0, 0x13($27) /* INCSRH */
-+ sh $9, 0x14($27) /* OUTMAXP */
-+ sb $0, 0x17($27) /* OUTCSRH */
-+
-+_usb_flush_fifo:
-+ li $8, 0x48 /* INCSR_CDT && INCSR_FF */
-+ sb $8, 0x12($27) /* INCSR */
-+ li $8, 0x90 /* OUTCSR_CDT && OUTCSR_FF */
-+ sb $8, 0x16($27) /* OUTCSR */
-+
-+ li $22, 0 /* set EP0 to IDLE state */
-+ li $23, 1 /* no data stage */
-+
-+ /* 2. Check and handle EP0 interrupt */
-+check_intr_ep0in:
-+ lhu $10, 0x02($27) /* read INTRIN */
-+ andi $9, $10, 0x1 /* check EP0 interrupt */
-+ beqz $9, check_intr_ep1in
-+ nop
-+
-+handle_ep0_intr:
-+ sb $0, 0x0e($27) /* set INDEX 0 */
-+ lbu $11, 0x12($27) /* read CSR0 */
-+
-+ andi $9, $11, 0x04 /* check SENTSTALL */
-+ beqz $9, _ep0_setupend
-+ nop
-+
-+_ep0_sentstall:
-+ andi $9, $11, 0xdb
-+ sb $9, 0x12($27) /* clear SENDSTALL and SENTSTALL */
-+ li $22, 0 /* set EP0 to IDLE state */
-+
-+_ep0_setupend:
-+ andi $9, $11, 0x10 /* check SETUPEND */
-+ beqz $9, ep0_idle_state
-+ nop
-+
-+ ori $9, $11, 0x80
-+ sb $9, 0x12($27) /* set SVDSETUPEND */
-+ li $22, 0 /* set EP0 to IDLE state */
-+
-+ep0_idle_state:
-+ bnez $22, ep0_tx_state
-+ nop
-+
-+ /* 2.1 Handle EP0 IDLE state interrupt */
-+ andi $9, $11, 0x01 /* check OUTPKTRDY */
-+ beqz $9, check_intr_ep1in
-+ nop
-+
-+ /* Read 8-bytes setup packet from the FIFO */
-+ lw $25, 0x20($27) /* first word of setup packet */
-+ lw $26, 0x20($27) /* second word of setup packet */
-+
-+ andi $9, $25, 0x60 /* bRequestType & USB_TYPE_MASK */
-+ beqz $9, _ep0_std_req
-+ nop
-+
-+ /* 2.1.1 Vendor-specific setup request */
-+_ep0_vend_req:
-+ li $22, 0 /* set EP0 to IDLE state */
-+ li $23, 1 /* NoData = 1 */
-+
-+ andi $9, $25, 0xff00 /* check bRequest */
-+ srl $9, $9, 8
-+ beqz $9, __ep0_get_cpu_info
-+ sub $8, $9, 0x1
-+ beqz $8, __ep0_set_data_address
-+ sub $8, $9, 0x2
-+ beqz $8, __ep0_set_data_length
-+ sub $8, $9, 0x3
-+ beqz $8, __ep0_flush_caches
-+ sub $8, $9, 0x4
-+ beqz $8, __ep0_prog_start1
-+ sub $8, $9, 0x5
-+ beqz $8, __ep0_prog_start2
-+ nop
-+ b _ep0_idle_state_fini /* invalid request */
-+ nop
-+
-+__ep0_get_cpu_info:
-+ load_addr $20, cpu_info_data /* data pointer to transfer */
-+ li $21, 8 /* bytes left to transfer */
-+ li $22, 1 /* set EP0 to TX state */
-+ li $23, 0 /* NoData = 0 */
-+
-+ b _ep0_idle_state_fini
-+ nop
-+
-+__ep0_set_data_address:
-+ li $9, 0xffff0000
-+ and $9, $25, $9
-+ andi $8, $26, 0xffff
-+ or $20, $9, $8 /* data address of next transfer */
-+
-+ b _ep0_idle_state_fini
-+ nop
-+
-+__ep0_set_data_length:
-+ li $9, 0xffff0000
-+ and $9, $25, $9
-+ andi $8, $26, 0xffff
-+ or $21, $9, $8 /* data length of next transfer */
-+
-+ li $9, 0x48 /* SVDOUTPKTRDY and DATAEND */
-+ sb $9, 0x12($27) /* CSR0 */
-+
-+ /* We must write packet to FIFO before EP1-IN interrupt here. */
-+ b handle_epin1_intr
-+ nop
-+
-+__ep0_flush_caches:
-+ /* Flush dcache and invalidate icache. */
-+ li $8, 0x80000000
-+ addi $9, $8, 0x3fe0 /* total 16KB */
-+
-+1:
-+ cache 0x0, 0($8) /* Index_Invalidate_I */
-+ cache 0x1, 0($8) /* Index_Writeback_Inv_D */
-+ bne $8, $9, 1b
-+ addiu $8, $8, 32
-+
-+ /* flush write-buffer */
-+ sync
-+
-+ /* Invalidate BTB */
-+ mfc0 $8, $16, 7 /* CP0_CONFIG */
-+ nop
-+ ori $8, 2
-+ mtc0 $8, $16, 7
-+ nop
-+
-+ b _ep0_idle_state_fini
-+ nop
-+
-+__ep0_prog_start1:
-+ li $9, 0x48 /* SVDOUTPKTRDY and DATAEND */
-+ sb $9, 0x12($27) /* CSR0 */
-+
-+ li $9, 0xffff0000
-+ and $9, $25, $9
-+ andi $8, $26, 0xffff
-+ or $20, $9, $8 /* target address */
-+
-+ b xfer_d2i
-+ li $19, 0x2000 /* 16KB data length */
-+
-+__ep0_prog_start2:
-+ li $9, 0x48 /* SVDOUTPKTRDY and DATAEND */
-+ sb $9, 0x12($27) /* CSR0 */
-+
-+ li $9, 0xffff0000
-+ and $9, $25, $9
-+ andi $8, $26, 0xffff
-+ or $20, $9, $8 /* target address */
-+
-+ jalr $20 /* jump, and place the return address in $31 */
-+ nop
-+
-+__ep0_prog_start2_return:
-+/* User code can return to here after executing itself, by jumping to $31 */
-+ b usb_boot_return
-+ nop
-+
-+ /* 2.1.2 Standard setup request */
-+_ep0_std_req:
-+ andi $12, $25, 0xff00 /* check bRequest */
-+ srl $12, $12, 8
-+ sub $9, $12, 0x05 /* check USB_REQ_SET_ADDRESS */
-+ bnez $9, __ep0_req_set_config
-+ nop
-+
-+ /* Handle USB_REQ_SET_ADDRESS */
-+__ep0_req_set_addr:
-+ srl $9, $25, 16 /* get wValue */
-+ sb $9, 0x0($27) /* set FADDR */
-+ li $23, 1 /* NoData = 1 */
-+ b _ep0_idle_state_fini
-+ nop
-+
-+__ep0_req_set_config:
-+ sub $9, $12, 0x09 /* check USB_REQ_SET_CONFIGURATION */
-+ bnez $9, __ep0_req_get_desc
-+ nop
-+
-+ /* Handle USB_REQ_SET_CONFIGURATION */
-+ li $23, 1 /* NoData = 1 */
-+ b _ep0_idle_state_fini
-+ nop
-+
-+__ep0_req_get_desc:
-+ sub $9, $12, 0x06 /* check USB_REQ_GET_DESCRIPTOR */
-+ bnez $9, _ep0_idle_state_fini
-+ li $23, 1 /* NoData = 1 */
-+
-+ /* Handle USB_REQ_GET_DESCRIPTOR */
-+ li $23, 0 /* NoData = 0 */
-+
-+ srl $9, $25, 24 /* wValue >> 8 */
-+ sub $8, $9, 0x01 /* check USB_DT_DEVICE */
-+ beqz $8, ___ep0_get_dev_desc
-+ srl $21, $26, 16 /* get wLength */
-+ sub $8, $9, 0x02 /* check USB_DT_CONFIG */
-+ beqz $8, ___ep0_get_conf_desc
-+ sub $8, $9, 0x03 /* check USB_DT_STRING */
-+ beqz $8, ___ep0_get_string_desc
-+ sub $8, $9, 0x06 /* check USB_DT_DEVICE_QUALIFIER */
-+ beqz $8, ___ep0_get_dev_qualifier
-+ nop
-+ b _ep0_idle_state_fini
-+ nop
-+
-+___ep0_get_dev_desc:
-+ load_addr $20, device_desc /* data pointer */
-+ li $22, 1 /* set EP0 to TX state */
-+ sub $8, $21, 18
-+ blez $8, _ep0_idle_state_fini /* wLength <= 18 */
-+ nop
-+ li $21, 18 /* max length of device_desc */
-+ b _ep0_idle_state_fini
-+ nop
-+
-+___ep0_get_dev_qualifier:
-+ load_addr $20, dev_qualifier /* data pointer */
-+ li $22, 1 /* set EP0 to TX state */
-+ sub $8, $21, 10
-+ blez $8, _ep0_idle_state_fini /* wLength <= 10 */
-+ nop
-+ li $21, 10 /* max length of dev_qualifier */
-+ b _ep0_idle_state_fini
-+ nop
-+
-+___ep0_get_conf_desc:
-+ load_addr $20, config_desc_fs /* data pointer of FS mode */
-+ lbu $8, 0x01($27) /* read POWER */
-+ andi $8, 0x10 /* test HS_MODE */
-+ beqz $8, ___ep0_get_conf_desc2
-+ nop
-+ load_addr $20, config_desc_hs /* data pointer of HS mode */
-+
-+___ep0_get_conf_desc2:
-+ li $22, 1 /* set EP0 to TX state */
-+ sub $8, $21, 32
-+ blez $8, _ep0_idle_state_fini /* wLength <= 32 */
-+ nop
-+ li $21, 32 /* max length of config_desc */
-+ b _ep0_idle_state_fini
-+ nop
-+
-+___ep0_get_string_desc:
-+ li $22, 1 /* set EP0 to TX state */
-+
-+ srl $9, $25, 16 /* wValue & 0xff */
-+ andi $9, 0xff
-+
-+ sub $8, $9, 1
-+ beqz $8, ___ep0_get_string_manufacture
-+ sub $8, $9, 2
-+ beqz $8, ___ep0_get_string_product
-+ nop
-+
-+___ep0_get_string_lang_ids:
-+ load_addr $20, string_lang_ids /* data pointer */
-+ b _ep0_idle_state_fini
-+ li $21, 4 /* data length */
-+
-+___ep0_get_string_manufacture:
-+ load_addr $20, string_manufacture /* data pointer */
-+ b _ep0_idle_state_fini
-+ li $21, 16 /* data length */
-+
-+___ep0_get_string_product:
-+ load_addr $20, string_product /* data pointer */
-+ b _ep0_idle_state_fini
-+ li $21, 46 /* data length */
-+
-+_ep0_idle_state_fini:
-+ li $9, 0x40 /* SVDOUTPKTRDY */
-+ beqz $23, _ep0_idle_state_fini2
-+ nop
-+ ori $9, $9, 0x08 /* DATAEND */
-+_ep0_idle_state_fini2:
-+ sb $9, 0x12($27) /* CSR0 */
-+ beqz $22, check_intr_ep1in
-+ nop
-+
-+ /* 2.2 Handle EP0 TX state interrupt */
-+ep0_tx_state:
-+ sub $9, $22, 1
-+ bnez $9, check_intr_ep1in
-+ nop
-+
-+ sub $9, $21, 64 /* max packetsize */
-+ blez $9, _ep0_tx_state2 /* data count <= 64 */
-+ ori $19, $21, 0
-+ li $19, 64
-+
-+_ep0_tx_state2:
-+ beqz $19, _ep0_tx_state3 /* send ZLP */
-+ ori $18, $19, 0 /* record bytes to be transferred */
-+ sub $21, $21, $19 /* decrement data count */
-+
-+_ep0_fifo_write_loop:
-+ lbu $9, 0($20) /* read data */
-+ sb $9, 0x20($27) /* load FIFO */
-+ sub $19, $19, 1 /* decrement counter */
-+ bnez $19, _ep0_fifo_write_loop
-+ addi $20, $20, 1 /* increment data pointer */
-+
-+ sub $9, $18, 64 /* max packetsize */
-+ beqz $9, _ep0_tx_state4
-+ nop
-+
-+_ep0_tx_state3:
-+ /* transferred bytes < max packetsize */
-+ li $9, 0x0a /* set INPKTRDY and DATAEND */
-+ sb $9, 0x12($27) /* CSR0 */
-+ li $22, 0 /* set EP0 to IDLE state */
-+ b check_intr_ep1in
-+ nop
-+
-+_ep0_tx_state4:
-+ /* transferred bytes == max packetsize */
-+ li $9, 0x02 /* set INPKTRDY */
-+ sb $9, 0x12($27) /* CSR0 */
-+ b check_intr_ep1in
-+ nop
-+
-+ /* 3. Check and handle EP1 BULK-IN interrupt */
-+check_intr_ep1in:
-+ andi $9, $10, 0x2 /* check EP1 IN interrupt */
-+ beqz $9, check_intr_ep1out
-+ nop
-+
-+handle_epin1_intr:
-+ li $9, 1
-+ sb $9, 0x0e($27) /* set INDEX 1 */
-+ lbu $9, 0x12($27) /* read INCSR */
-+
-+ andi $8, $9, 0x2 /* check INCSR_FFNOTEMPT */
-+ bnez $8, _epin1_tx_state4
-+ nop
-+
-+_epin1_write_fifo:
-+ lhu $9, 0x10($27) /* get INMAXP */
-+ sub $8, $21, $9
-+ blez $8, _epin1_tx_state1 /* bytes left <= INMAXP */
-+ ori $19, $21, 0
-+ ori $19, $9, 0
-+
-+_epin1_tx_state1:
-+ beqz $19, _epin1_tx_state4 /* No data */
-+ nop
-+
-+ sub $21, $21, $19 /* decrement data count */
-+
-+ srl $5, $19, 2 /* # of word */
-+ andi $6, $19, 0x3 /* # of byte */
-+ beqz $5, _epin1_tx_state2
-+ nop
-+
-+_epin1_fifo_write_word:
-+ lw $9, 0($20) /* read data from source address */
-+ sw $9, 0x24($27) /* write FIFO */
-+ sub $5, $5, 1 /* decrement counter */
-+ bnez $5, _epin1_fifo_write_word
-+ addiu $20, $20, 4 /* increment dest address */
-+
-+_epin1_tx_state2:
-+ beqz $6, _epin1_tx_state3
-+ nop
-+
-+_epin1_fifo_write_byte:
-+ lbu $9, 0($20) /* read data from source address */
-+ sb $9, 0x24($27) /* write FIFO */
-+ sub $6, $6, 1 /* decrement counter */
-+ bnez $6, _epin1_fifo_write_byte
-+ addiu $20, $20, 1 /* increment dest address */
-+
-+_epin1_tx_state3:
-+ li $9, 0x1
-+ sb $9, 0x12($27) /* INCSR, set INPKTRDY */
-+
-+_epin1_tx_state4:
-+ /* 4. Check and handle EP1 BULK-OUT interrupt */
-+check_intr_ep1out:
-+ lhu $9, 0x04($27) /* read INTROUT */
-+ andi $9, 0x2
-+ beqz $9, check_status_next
-+ nop
-+
-+handle_epout1_intr:
-+ li $9, 1
-+ sb $9, 0x0e($27) /* set INDEX 1 */
-+
-+ lbu $9, 0x16($27) /* read OUTCSR */
-+ andi $9, 0x1 /* check OUTPKTRDY */
-+ beqz $9, check_status_next
-+ nop
-+
-+_epout1_read_fifo:
-+ lhu $19, 0x18($27) /* read OUTCOUNT */
-+ srl $5, $19, 2 /* # of word */
-+ andi $6, $19, 0x3 /* # of byte */
-+ beqz $5, _epout1_rx_state1
-+ nop
-+
-+_epout1_fifo_read_word:
-+ lw $9, 0x24($27) /* read FIFO */
-+ sw $9, 0($20) /* store to dest address */
-+ sub $5, $5, 1 /* decrement counter */
-+ bnez $5, _epout1_fifo_read_word
-+ addiu $20, $20, 4 /* increment dest address */
-+
-+_epout1_rx_state1:
-+ beqz $6, _epout1_rx_state2
-+ nop
-+
-+_epout1_fifo_read_byte:
-+ lbu $9, 0x24($27) /* read FIFO */
-+ sb $9, 0($20) /* store to dest address */
-+ sub $6, $6, 1 /* decrement counter */
-+ bnez $6, _epout1_fifo_read_byte
-+ addiu $20, $20, 1 /* increment dest address */
-+
-+_epout1_rx_state2:
-+ sb $0, 0x16($27) /* clear OUTPKTRDY */
-+
-+check_status_next:
-+ b usb_command_loop
-+ nop
-+
-+/* Device/Configuration/Interface/Endpoint/String Descriptors */
-+
-+ .align 2
-+device_desc:
-+ .byte 0x12 /* bLength */
-+ .byte 0x01 /* bDescriptorType */
-+ .byte 0x00 /* bcdUSB */
-+ .byte 0x02 /* bcdUSB */
-+ .byte 0x00 /* bDeviceClass */
-+ .byte 0x00 /* bDeviceSubClass */
-+ .byte 0x00 /* bDeviceProtocol */
-+ .byte 0x40 /* bMaxPacketSize0 */
-+ .byte 0x1a /* idVendor */
-+ .byte 0x60 /* idVendor */
-+ .byte 0x40 /* idProduct */
-+ .byte 0x47 /* idProduct */
-+ .byte 0x00 /* bcdDevice */
-+ .byte 0x01 /* bcdDevice */
-+ .byte 0x01 /* iManufacturer */
-+ .byte 0x02 /* iProduct */
-+ .byte 0x00 /* iSerialNumber */
-+ .byte 0x01 /* bNumConfigurations */
-+
-+ .align 2
-+dev_qualifier:
-+ .byte 0x0a /* bLength */
-+ .byte 0x06 /* bDescriptorType */
-+ .byte 0x00 /* bcdUSB */
-+ .byte 0x02 /* bcdUSB */
-+ .byte 0x00 /* bDeviceClass */
-+ .byte 0x00 /* bDeviceSubClass */
-+ .byte 0x00 /* bDeviceProtocol */
-+ .byte 0x40 /* bMaxPacketSize0 */
-+ .byte 0x01 /* bNumConfigurations */
-+ .byte 0x00 /* bRESERVED */
-+
-+ .align 2
-+config_desc_hs:
-+ .byte 0x09 /* bLength */
-+ .byte 0x02 /* bDescriptorType */
-+ .byte 0x20 /* wTotalLength */
-+ .byte 0x00 /* wTotalLength */
-+ .byte 0x01 /* bNumInterfaces */
-+ .byte 0x01 /* bConfigurationValue */
-+ .byte 0x00 /* iConfiguration */
-+ .byte 0xc0 /* bmAttributes */
-+ .byte 0x01 /* MaxPower */
-+intf_desc_hs:
-+ .byte 0x09 /* bLength */
-+ .byte 0x04 /* bDescriptorType */
-+ .byte 0x00 /* bInterfaceNumber */
-+ .byte 0x00 /* bAlternateSetting */
-+ .byte 0x02 /* bNumEndpoints */
-+ .byte 0xff /* bInterfaceClass */
-+ .byte 0x00 /* bInterfaceSubClass */
-+ .byte 0x50 /* bInterfaceProtocol */
-+ .byte 0x00 /* iInterface */
-+ep1_desc_hs:
-+ .byte 0x07 /* bLength */
-+ .byte 0x05 /* bDescriptorType */
-+ .byte 0x01 /* bEndpointAddress */
-+ .byte 0x02 /* bmAttributes */
-+ .byte 0x00 /* wMaxPacketSize */
-+ .byte 0x02 /* wMaxPacketSize */
-+ .byte 0x00 /* bInterval */
-+ep2_desc_hs:
-+ .byte 0x07 /* bLength */
-+ .byte 0x05 /* bDescriptorType */
-+ .byte 0x81 /* bEndpointAddress */
-+ .byte 0x02 /* bmAttributes */
-+ .byte 0x00 /* wMaxPacketSize */
-+ .byte 0x02 /* wMaxPacketSize */
-+ .byte 0x00 /* bInterval */
-+
-+ .align 2
-+config_desc_fs:
-+ .byte 0x09 /* bLength */
-+ .byte 0x02 /* bDescriptorType */
-+ .byte 0x20 /* wTotalLength */
-+ .byte 0x00 /* wTotalLength */
-+ .byte 0x01 /* bNumInterfaces */
-+ .byte 0x01 /* bConfigurationValue */
-+ .byte 0x00 /* iConfiguration */
-+ .byte 0xc0 /* bmAttributes */
-+ .byte 0x01 /* MaxPower */
-+intf_desc_fs:
-+ .byte 0x09 /* bLength */
-+ .byte 0x04 /* bDescriptorType */
-+ .byte 0x00 /* bInterfaceNumber */
-+ .byte 0x00 /* bAlternateSetting */
-+ .byte 0x02 /* bNumEndpoints */
-+ .byte 0xff /* bInterfaceClass */
-+ .byte 0x00 /* bInterfaceSubClass */
-+ .byte 0x50 /* bInterfaceProtocol */
-+ .byte 0x00 /* iInterface */
-+ep1_desc_fs:
-+ .byte 0x07 /* bLength */
-+ .byte 0x05 /* bDescriptorType */
-+ .byte 0x01 /* bEndpointAddress */
-+ .byte 0x02 /* bmAttributes */
-+ .byte 0x40 /* wMaxPacketSize */
-+ .byte 0x00 /* wMaxPacketSize */
-+ .byte 0x00 /* bInterval */
-+ep2_desc_fs:
-+ .byte 0x07 /* bLength */
-+ .byte 0x05 /* bDescriptorType */
-+ .byte 0x81 /* bEndpointAddress */
-+ .byte 0x02 /* bmAttributes */
-+ .byte 0x40 /* wMaxPacketSize */
-+ .byte 0x00 /* wMaxPacketSize */
-+ .byte 0x00 /* bInterval */
-+
-+ .align 2
-+string_lang_ids:
-+ .byte 0x04
-+ .byte 0x03
-+ .byte 0x09
-+ .byte 0x04
-+
-+ .align 2
-+string_manufacture:
-+ .byte 0x10
-+ .byte 0x03
-+ .byte 0x49
-+ .byte 0x00
-+ .byte 0x6e
-+ .byte 0x00
-+ .byte 0x67
-+ .byte 0x00
-+ .byte 0x65
-+ .byte 0x00
-+ .byte 0x6e
-+ .byte 0x00
-+ .byte 0x69
-+ .byte 0x00
-+ .byte 0x63
-+ .byte 0x00
-+
-+ .align 2
-+string_product:
-+ .byte 0x2e
-+ .byte 0x03
-+ .byte 0x4a
-+ .byte 0x00
-+ .byte 0x5a
-+ .byte 0x00
-+ .byte 0x34
-+ .byte 0x00
-+ .byte 0x37
-+ .byte 0x00
-+ .byte 0x34
-+ .byte 0x00
-+ .byte 0x30
-+ .byte 0x00
-+ .byte 0x20
-+ .byte 0x00
-+ .byte 0x55
-+ .byte 0x00
-+ .byte 0x53
-+ .byte 0x00
-+ .byte 0x42
-+ .byte 0x00
-+ .byte 0x20
-+ .byte 0x00
-+ .byte 0x42
-+ .byte 0x00
-+ .byte 0x6f
-+ .byte 0x00
-+ .byte 0x6f
-+ .byte 0x00
-+ .byte 0x74
-+ .byte 0x00
-+ .byte 0x20
-+ .byte 0x00
-+ .byte 0x44
-+ .byte 0x00
-+ .byte 0x65
-+ .byte 0x00
-+ .byte 0x76
-+ .byte 0x00
-+ .byte 0x69
-+ .byte 0x00
-+ .byte 0x63
-+ .byte 0x00
-+ .byte 0x65
-+ .byte 0x00
-+
-+ .align 2
-+cpu_info_data:
-+ .byte 0x4a
-+ .byte 0x5a
-+ .byte 0x34
-+ .byte 0x37
-+ .byte 0x34
-+ .byte 0x30
-+ .byte 0x56
-+ .byte 0x31
-+usbboot_end:
-+
-+ .set reorder
---
-1.7.9.5
-
diff --git a/package/boot/uboot-xburst/patches/0003-add-mmc-support.patch b/package/boot/uboot-xburst/patches/0003-add-mmc-support.patch
deleted file mode 100644
index e9baa7c373..0000000000
--- a/package/boot/uboot-xburst/patches/0003-add-mmc-support.patch
+++ /dev/null
@@ -1,1664 +0,0 @@
-From bd36739e77669e8df45c38f6acfe2cea511534d9 Mon Sep 17 00:00:00 2001
-From: Xiangfu <xiangfu@openmobilefree.net>
-Date: Wed, 10 Oct 2012 18:19:41 +0800
-Subject: [PATCH 3/6] add mmc support
-
----
- arch/mips/include/asm/jz4740.h | 166 ++++++
- board/qi/qi_lb60/qi_lb60.c | 9 +-
- drivers/mmc/Makefile | 1 +
- drivers/mmc/jz_mmc.c | 1179 ++++++++++++++++++++++++++++++++++++++++
- drivers/mmc/jz_mmc.h | 176 ++++++
- include/configs/qi_lb60.h | 9 +
- include/mmc.h | 40 ++
- 7 files changed, 1578 insertions(+), 2 deletions(-)
- create mode 100644 drivers/mmc/jz_mmc.c
- create mode 100644 drivers/mmc/jz_mmc.h
-
-diff --git a/arch/mips/include/asm/jz4740.h b/arch/mips/include/asm/jz4740.h
-index 7a7cfff..68287fb 100644
---- a/arch/mips/include/asm/jz4740.h
-+++ b/arch/mips/include/asm/jz4740.h
-@@ -1146,5 +1146,171 @@ extern void sdram_init(void);
- extern void calc_clocks(void);
- extern void rtc_init(void);
-
-+/*************************************************************************
-+ * MSC
-+ *************************************************************************/
-+#define REG8(addr) *((volatile u8 *)(addr))
-+#define REG16(addr) *((volatile u16 *)(addr))
-+#define REG32(addr) *((volatile u32 *)(addr))
-+
-+#define CPM_BASE 0xB0000000
-+#define CPM_CPCCR (CPM_BASE+0x00)
-+#define CPM_MSCCDR (CPM_BASE+0x68)
-+#define REG_CPM_MSCCDR REG32(CPM_MSCCDR)
-+#define REG_CPM_CPCCR REG32(CPM_CPCCR)
-+
-+#define MSC_BASE 0xB0021000
-+
-+#define MSC_STRPCL (MSC_BASE + 0x000)
-+#define MSC_STAT (MSC_BASE + 0x004)
-+#define MSC_CLKRT (MSC_BASE + 0x008)
-+#define MSC_CMDAT (MSC_BASE + 0x00C)
-+#define MSC_RESTO (MSC_BASE + 0x010)
-+#define MSC_RDTO (MSC_BASE + 0x014)
-+#define MSC_BLKLEN (MSC_BASE + 0x018)
-+#define MSC_NOB (MSC_BASE + 0x01C)
-+#define MSC_SNOB (MSC_BASE + 0x020)
-+#define MSC_IMASK (MSC_BASE + 0x024)
-+#define MSC_IREG (MSC_BASE + 0x028)
-+#define MSC_CMD (MSC_BASE + 0x02C)
-+#define MSC_ARG (MSC_BASE + 0x030)
-+#define MSC_RES (MSC_BASE + 0x034)
-+#define MSC_RXFIFO (MSC_BASE + 0x038)
-+#define MSC_TXFIFO (MSC_BASE + 0x03C)
-+
-+#define REG_MSC_STRPCL REG16(MSC_STRPCL)
-+#define REG_MSC_STAT REG32(MSC_STAT)
-+#define REG_MSC_CLKRT REG16(MSC_CLKRT)
-+#define REG_MSC_CMDAT REG32(MSC_CMDAT)
-+#define REG_MSC_RESTO REG16(MSC_RESTO)
-+#define REG_MSC_RDTO REG16(MSC_RDTO)
-+#define REG_MSC_BLKLEN REG16(MSC_BLKLEN)
-+#define REG_MSC_NOB REG16(MSC_NOB)
-+#define REG_MSC_SNOB REG16(MSC_SNOB)
-+#define REG_MSC_IMASK REG16(MSC_IMASK)
-+#define REG_MSC_IREG REG16(MSC_IREG)
-+#define REG_MSC_CMD REG8(MSC_CMD)
-+#define REG_MSC_ARG REG32(MSC_ARG)
-+#define REG_MSC_RES REG16(MSC_RES)
-+#define REG_MSC_RXFIFO REG32(MSC_RXFIFO)
-+#define REG_MSC_TXFIFO REG32(MSC_TXFIFO)
-+
-+/* MSC Clock and Control Register (MSC_STRPCL) */
-+
-+#define MSC_STRPCL_EXIT_MULTIPLE (1 << 7)
-+#define MSC_STRPCL_EXIT_TRANSFER (1 << 6)
-+#define MSC_STRPCL_START_READWAIT (1 << 5)
-+#define MSC_STRPCL_STOP_READWAIT (1 << 4)
-+#define MSC_STRPCL_RESET (1 << 3)
-+#define MSC_STRPCL_START_OP (1 << 2)
-+#define MSC_STRPCL_CLOCK_CONTROL_BIT 0
-+#define MSC_STRPCL_CLOCK_CONTROL_MASK (0x3 << MSC_STRPCL_CLOCK_CONTROL_BIT)
-+ #define MSC_STRPCL_CLOCK_CONTROL_STOP (0x1 << MSC_STRPCL_CLOCK_CONTROL_BIT) /* Stop MMC/SD clock */
-+ #define MSC_STRPCL_CLOCK_CONTROL_START (0x2 << MSC_STRPCL_CLOCK_CONTROL_BIT) /* Start MMC/SD clock */
-+
-+/* MSC Status Register (MSC_STAT) */
-+
-+#define MSC_STAT_IS_RESETTING (1 << 15)
-+#define MSC_STAT_SDIO_INT_ACTIVE (1 << 14)
-+#define MSC_STAT_PRG_DONE (1 << 13)
-+#define MSC_STAT_DATA_TRAN_DONE (1 << 12)
-+#define MSC_STAT_END_CMD_RES (1 << 11)
-+#define MSC_STAT_DATA_FIFO_AFULL (1 << 10)
-+#define MSC_STAT_IS_READWAIT (1 << 9)
-+#define MSC_STAT_CLK_EN (1 << 8)
-+#define MSC_STAT_DATA_FIFO_FULL (1 << 7)
-+#define MSC_STAT_DATA_FIFO_EMPTY (1 << 6)
-+#define MSC_STAT_CRC_RES_ERR (1 << 5)
-+#define MSC_STAT_CRC_READ_ERROR (1 << 4)
-+#define MSC_STAT_CRC_WRITE_ERROR_BIT 2
-+#define MSC_STAT_CRC_WRITE_ERROR_MASK (0x3 << MSC_STAT_CRC_WRITE_ERROR_BIT)
-+ #define MSC_STAT_CRC_WRITE_ERROR_NO (0 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* No error on transmission of data */
-+ #define MSC_STAT_CRC_WRITE_ERROR (1 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* Card observed erroneous transmission of data */
-+ #define MSC_STAT_CRC_WRITE_ERROR_NOSTS (2 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* No CRC status is sent back */
-+#define MSC_STAT_TIME_OUT_RES (1 << 1)
-+#define MSC_STAT_TIME_OUT_READ (1 << 0)
-+
-+/* MSC Bus Clock Control Register (MSC_CLKRT) */
-+
-+#define MSC_CLKRT_CLK_RATE_BIT 0
-+#define MSC_CLKRT_CLK_RATE_MASK (0x7 << MSC_CLKRT_CLK_RATE_BIT)
-+ #define MSC_CLKRT_CLK_RATE_DIV_1 (0x0 << MSC_CLKRT_CLK_RATE_BIT) /* CLK_SRC */
-+ #define MSC_CLKRT_CLK_RATE_DIV_2 (0x1 << MSC_CLKRT_CLK_RATE_BIT) /* 1/2 of CLK_SRC */
-+ #define MSC_CLKRT_CLK_RATE_DIV_4 (0x2 << MSC_CLKRT_CLK_RATE_BIT) /* 1/4 of CLK_SRC */
-+ #define MSC_CLKRT_CLK_RATE_DIV_8 (0x3 << MSC_CLKRT_CLK_RATE_BIT) /* 1/8 of CLK_SRC */
-+ #define MSC_CLKRT_CLK_RATE_DIV_16 (0x4 << MSC_CLKRT_CLK_RATE_BIT) /* 1/16 of CLK_SRC */
-+ #define MSC_CLKRT_CLK_RATE_DIV_32 (0x5 << MSC_CLKRT_CLK_RATE_BIT) /* 1/32 of CLK_SRC */
-+ #define MSC_CLKRT_CLK_RATE_DIV_64 (0x6 << MSC_CLKRT_CLK_RATE_BIT) /* 1/64 of CLK_SRC */
-+ #define MSC_CLKRT_CLK_RATE_DIV_128 (0x7 << MSC_CLKRT_CLK_RATE_BIT) /* 1/128 of CLK_SRC */
-+
-+/* MSC Command Sequence Control Register (MSC_CMDAT) */
-+
-+#define MSC_CMDAT_IO_ABORT (1 << 11)
-+#define MSC_CMDAT_BUS_WIDTH_BIT 9
-+#define MSC_CMDAT_BUS_WIDTH_MASK (0x3 << MSC_CMDAT_BUS_WIDTH_BIT)
-+#define MSC_CMDAT_BUS_WIDTH_1BIT (0x0 << MSC_CMDAT_BUS_WIDTH_BIT)
-+#define MSC_CMDAT_BUS_WIDTH_4BIT (0x2 << MSC_CMDAT_BUS_WIDTH_BIT)
-+#define MSC_CMDAT_DMA_EN (1 << 8)
-+#define MSC_CMDAT_INIT (1 << 7)
-+#define MSC_CMDAT_BUSY (1 << 6)
-+#define MSC_CMDAT_STREAM_BLOCK (1 << 5)
-+#define MSC_CMDAT_WRITE (1 << 4)
-+#define MSC_CMDAT_READ (0 << 4)
-+#define MSC_CMDAT_DATA_EN (1 << 3)
-+#define MSC_CMDAT_RESPONSE_BIT 0
-+#define MSC_CMDAT_RESPONSE_MASK (0x7 << MSC_CMDAT_RESPONSE_BIT)
-+#define MSC_CMDAT_RESPONSE_NONE (0x0 << MSC_CMDAT_RESPONSE_BIT)
-+#define MSC_CMDAT_RESPONSE_R1 (0x1 << MSC_CMDAT_RESPONSE_BIT)
-+#define MSC_CMDAT_RESPONSE_R2 (0x2 << MSC_CMDAT_RESPONSE_BIT)
-+#define MSC_CMDAT_RESPONSE_R3 (0x3 << MSC_CMDAT_RESPONSE_BIT)
-+#define MSC_CMDAT_RESPONSE_R4 (0x4 << MSC_CMDAT_RESPONSE_BIT)
-+#define MSC_CMDAT_RESPONSE_R5 (0x5 << MSC_CMDAT_RESPONSE_BIT)
-+#define MSC_CMDAT_RESPONSE_R6 (0x6 << MSC_CMDAT_RESPONSE_BIT)
-+
-+/* MSC Interrupts Mask Register (MSC_IMASK) */
-+#define MSC_IMASK_SDIO (1 << 7)
-+#define MSC_IMASK_TXFIFO_WR_REQ (1 << 6)
-+#define MSC_IMASK_RXFIFO_RD_REQ (1 << 5)
-+#define MSC_IMASK_END_CMD_RES (1 << 2)
-+#define MSC_IMASK_PRG_DONE (1 << 1)
-+#define MSC_IMASK_DATA_TRAN_DONE (1 << 0)
-+
-+
-+/* MSC Interrupts Status Register (MSC_IREG) */
-+#define MSC_IREG_SDIO (1 << 7)
-+#define MSC_IREG_TXFIFO_WR_REQ (1 << 6)
-+#define MSC_IREG_RXFIFO_RD_REQ (1 << 5)
-+#define MSC_IREG_END_CMD_RES (1 << 2)
-+#define MSC_IREG_PRG_DONE (1 << 1)
-+#define MSC_IREG_DATA_TRAN_DONE (1 << 0)
-+
-+static __inline__ unsigned int __cpm_get_pllout2(void)
-+{
-+ if (REG_CPM_CPCCR & CPM_CPCCR_PCS)
-+ return __cpm_get_pllout();
-+ else
-+ return __cpm_get_pllout()/2;
-+}
-+
-+static inline void __cpm_select_msc_clk(int sd)
-+{
-+ unsigned int pllout2 = __cpm_get_pllout2();
-+ unsigned int div = 0;
-+
-+ if (sd) {
-+ div = pllout2 / 24000000;
-+ }
-+ else {
-+ div = pllout2 / 16000000;
-+ }
-+
-+ REG_CPM_MSCCDR = div - 1;
-+}
-+#define __msc_reset() \
-+do { \
-+ REG_MSC_STRPCL = MSC_STRPCL_RESET; \
-+ while (REG_MSC_STAT & MSC_STAT_IS_RESETTING); \
-+} while (0)
-+
- #endif /* !__ASSEMBLY__ */
- #endif /* __JZ4740_H__ */
-diff --git a/board/qi/qi_lb60/qi_lb60.c b/board/qi/qi_lb60/qi_lb60.c
-index 3bd4e2f..a2ba648 100644
---- a/board/qi/qi_lb60/qi_lb60.c
-+++ b/board/qi/qi_lb60/qi_lb60.c
-@@ -40,8 +40,13 @@ static void gpio_init(void)
- __gpio_clear_pin(GPIO_KEYOUT_BASE + i);
- }
-
-- __gpio_as_input(GPIO_KEYIN_8);
-- __gpio_enable_pull(GPIO_KEYIN_8);
-+ if (__gpio_get_pin(GPIO_KEYIN_BASE + 2) == 0){
-+ printf("[S] pressed, enable UART0\n");
-+ __gpio_as_uart0();
-+ } else {
-+ __gpio_as_input(GPIO_KEYIN_8);
-+ __gpio_enable_pull(GPIO_KEYIN_8);
-+ }
-
- /* enable the TP4, TP5 as UART0 */
- __gpio_jtag_to_uart0();
-diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
-index 565ba6a..3c717b1 100644
---- a/drivers/mmc/Makefile
-+++ b/drivers/mmc/Makefile
-@@ -47,6 +47,7 @@ COBJS-$(CONFIG_SDHCI) += sdhci.o
- COBJS-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o
- COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o
- COBJS-$(CONFIG_TEGRA_MMC) += tegra_mmc.o
-+COBJS-$(CONFIG_JZ4740_MMC) += jz_mmc.o
-
- COBJS := $(COBJS-y)
- SRCS := $(COBJS:.o=.c)
-diff --git a/drivers/mmc/jz_mmc.c b/drivers/mmc/jz_mmc.c
-new file mode 100644
-index 0000000..642cecc
---- /dev/null
-+++ b/drivers/mmc/jz_mmc.c
-@@ -0,0 +1,1179 @@
-+/*
-+ * (C) Copyright 2003
-+ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
-+ *
-+ * 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 <config.h>
-+#include <common.h>
-+#include <part.h>
-+#include <mmc.h>
-+
-+#include <asm/io.h>
-+#include <asm/jz4740.h>
-+#include "jz_mmc.h"
-+
-+static int sd2_0 = 0;
-+static int mmc_ready = 0;
-+static int use_4bit; /* Use 4-bit data bus */
-+/*
-+ * MMC Events
-+ */
-+#define MMC_EVENT_NONE 0x00 /* No events */
-+#define MMC_EVENT_RX_DATA_DONE 0x01 /* Rx data done */
-+#define MMC_EVENT_TX_DATA_DONE 0x02 /* Tx data done */
-+#define MMC_EVENT_PROG_DONE 0x04 /* Programming is done */
-+
-+
-+#define MMC_IRQ_MASK() \
-+do { \
-+ REG_MSC_IMASK = 0xffff; \
-+ REG_MSC_IREG = 0xffff; \
-+} while (0)
-+
-+/*
-+ * GPIO definition
-+ */
-+#if defined(CONFIG_SAKC)
-+
-+#define __msc_init_io() \
-+do { \
-+ __gpio_as_input(GPIO_SD_CD_N); \
-+} while (0)
-+
-+#else
-+#define __msc_init_io() \
-+do { \
-+ __gpio_as_output(GPIO_SD_VCC_EN_N); \
-+ __gpio_as_input(GPIO_SD_CD_N); \
-+} while (0)
-+
-+#define __msc_enable_power() \
-+do { \
-+ __gpio_clear_pin(GPIO_SD_VCC_EN_N); \
-+} while (0)
-+
-+#define __msc_disable_power() \
-+do { \
-+ __gpio_set_pin(GPIO_SD_VCC_EN_N); \
-+} while (0)
-+
-+#endif /* CONFIG_SAKE */
-+
-+#define __msc_card_detected() \
-+({ \
-+ int detected = 1; \
-+ __gpio_as_input(GPIO_SD_CD_N); \
-+ __gpio_disable_pull(GPIO_SD_CD_N); \
-+ if (!__gpio_get_pin(GPIO_SD_CD_N)) \
-+ detected = 0; \
-+ detected; \
-+})
-+
-+/*
-+ * Local functions
-+ */
-+
-+extern int
-+fat_register_device(block_dev_desc_t *dev_desc, int part_no);
-+
-+static block_dev_desc_t mmc_dev;
-+
-+block_dev_desc_t * mmc_get_dev(int dev)
-+{
-+ return ((block_dev_desc_t *)&mmc_dev);
-+}
-+
-+/* Stop the MMC clock and wait while it happens */
-+static inline int jz_mmc_stop_clock(void)
-+{
-+ int timeout = 1000;
-+
-+ REG_MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_STOP;
-+
-+ while (timeout && (REG_MSC_STAT & MSC_STAT_CLK_EN)) {
-+ timeout--;
-+ if (timeout == 0)
-+ return MMC_ERROR_TIMEOUT;
-+ udelay(1);
-+ }
-+ return MMC_NO_ERROR;
-+}
-+
-+/* Start the MMC clock and operation */
-+static inline int jz_mmc_start_clock(void)
-+{
-+ REG_MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_START | MSC_STRPCL_START_OP;
-+ return MMC_NO_ERROR;
-+}
-+
-+static inline u32 jz_mmc_calc_clkrt(int is_sd, u32 rate)
-+{
-+ u32 clkrt = 0;
-+ u32 clk_src = is_sd ? 24000000 : 16000000;
-+
-+ while (rate < clk_src) {
-+ clkrt ++;
-+ clk_src >>= 1;
-+ }
-+
-+ return clkrt;
-+}
-+
-+/* Set the MMC clock frequency */
-+void jz_mmc_set_clock(int sd, u32 rate)
-+{
-+ jz_mmc_stop_clock();
-+
-+ /* Select clock source of MSC */
-+ __cpm_select_msc_clk(sd);
-+
-+ /* Set clock dividor of MSC */
-+ REG_MSC_CLKRT = jz_mmc_calc_clkrt(sd, rate);
-+}
-+
-+static int jz_mmc_check_status(struct mmc_request *request)
-+{
-+ u32 status = REG_MSC_STAT;
-+
-+ /* Checking for response or data timeout */
-+ if (status & (MSC_STAT_TIME_OUT_RES | MSC_STAT_TIME_OUT_READ)) {
-+ printf("MMC/SD timeout, MMC_STAT 0x%x CMD %d\n", status, request->cmd);
-+ return MMC_ERROR_TIMEOUT;
-+ }
-+
-+ /* Checking for CRC error */
-+ if (status & (MSC_STAT_CRC_READ_ERROR | MSC_STAT_CRC_WRITE_ERROR | MSC_STAT_CRC_RES_ERR)) {
-+ printf("MMC/CD CRC error, MMC_STAT 0x%x\n", status);
-+ return MMC_ERROR_CRC;
-+ }
-+
-+ return MMC_NO_ERROR;
-+}
-+
-+/* Obtain response to the command and store it to response buffer */
-+static void jz_mmc_get_response(struct mmc_request *request)
-+{
-+ int i;
-+ u8 *buf;
-+ u32 data;
-+
-+ debug("fetch response for request %d, cmd %d\n",
-+ request->rtype, request->cmd);
-+
-+ buf = request->response;
-+ request->result = MMC_NO_ERROR;
-+
-+ switch (request->rtype) {
-+ case RESPONSE_R1: case RESPONSE_R1B: case RESPONSE_R6:
-+ case RESPONSE_R3: case RESPONSE_R4: case RESPONSE_R5:
-+ {
-+ data = REG_MSC_RES;
-+ buf[0] = (data >> 8) & 0xff;
-+ buf[1] = data & 0xff;
-+ data = REG_MSC_RES;
-+ buf[2] = (data >> 8) & 0xff;
-+ buf[3] = data & 0xff;
-+ data = REG_MSC_RES;
-+ buf[4] = data & 0xff;
-+
-+ debug("request %d, response [%02x %02x %02x %02x %02x]\n",
-+ request->rtype, buf[0], buf[1], buf[2], buf[3], buf[4]);
-+ break;
-+ }
-+ case RESPONSE_R2_CID: case RESPONSE_R2_CSD:
-+ {
-+ for (i = 0; i < 16; i += 2) {
-+ data = REG_MSC_RES;
-+ buf[i] = (data >> 8) & 0xff;
-+ buf[i+1] = data & 0xff;
-+ }
-+ debug("request %d, response [", request->rtype);
-+#if CONFIG_MMC_DEBUG_VERBOSE > 2
-+ if (g_mmc_debug >= 3) {
-+ int n;
-+ for (n = 0; n < 17; n++)
-+ printk("%02x ", buf[n]);
-+ printk("]\n");
-+ }
-+#endif
-+ break;
-+ }
-+ case RESPONSE_NONE:
-+ debug("No response\n");
-+ break;
-+
-+ default:
-+ debug("unhandled response type for request %d\n", request->rtype);
-+ break;
-+ }
-+}
-+
-+static int jz_mmc_receive_data(struct mmc_request *req)
-+{
-+ u32 stat, timeout, data, cnt;
-+ u8 *buf = req->buffer;
-+ u32 wblocklen = (u32)(req->block_len + 3) >> 2; /* length in word */
-+
-+ timeout = 0x3ffffff;
-+
-+ while (timeout) {
-+ timeout--;
-+ stat = REG_MSC_STAT;
-+
-+ if (stat & MSC_STAT_TIME_OUT_READ)
-+ return MMC_ERROR_TIMEOUT;
-+ else if (stat & MSC_STAT_CRC_READ_ERROR)
-+ return MMC_ERROR_CRC;
-+ else if (!(stat & MSC_STAT_DATA_FIFO_EMPTY)
-+ || (stat & MSC_STAT_DATA_FIFO_AFULL)) {
-+ /* Ready to read data */
-+ break;
-+ }
-+ udelay(1);
-+ }
-+ if (!timeout)
-+ return MMC_ERROR_TIMEOUT;
-+
-+ /* Read data from RXFIFO. It could be FULL or PARTIAL FULL */
-+ cnt = wblocklen;
-+ while (cnt) {
-+ data = REG_MSC_RXFIFO;
-+ {
-+ *buf++ = (u8)(data >> 0);
-+ *buf++ = (u8)(data >> 8);
-+ *buf++ = (u8)(data >> 16);
-+ *buf++ = (u8)(data >> 24);
-+ }
-+ cnt --;
-+ while (cnt && (REG_MSC_STAT & MSC_STAT_DATA_FIFO_EMPTY))
-+ ;
-+ }
-+ return MMC_NO_ERROR;
-+}
-+
-+static int jz_mmc_transmit_data(struct mmc_request *req)
-+{
-+#if 0
-+ u32 nob = req->nob;
-+ u32 wblocklen = (u32)(req->block_len + 3) >> 2; /* length in word */
-+ u8 *buf = req->buffer;
-+ u32 *wbuf = (u32 *)buf;
-+ u32 waligned = (((u32)buf & 0x3) == 0); /* word aligned ? */
-+ u32 stat, timeout, data, cnt;
-+
-+ for (nob; nob >= 1; nob--) {
-+ timeout = 0x3FFFFFF;
-+
-+ while (timeout) {
-+ timeout--;
-+ stat = REG_MSC_STAT;
-+
-+ if (stat & (MSC_STAT_CRC_WRITE_ERROR | MSC_STAT_CRC_WRITE_ERROR_NOSTS))
-+ return MMC_ERROR_CRC;
-+ else if (!(stat & MSC_STAT_DATA_FIFO_FULL)) {
-+ /* Ready to write data */
-+ break;
-+ }
-+
-+ udelay(1);
-+ }
-+
-+ if (!timeout)
-+ return MMC_ERROR_TIMEOUT;
-+
-+ /* Write data to TXFIFO */
-+ cnt = wblocklen;
-+ while (cnt) {
-+ while (REG_MSC_STAT & MSC_STAT_DATA_FIFO_FULL)
-+ ;
-+
-+ if (waligned) {
-+ REG_MSC_TXFIFO = *wbuf++;
-+ }
-+ else {
-+ data = *buf++ | (*buf++ << 8) | (*buf++ << 16) | (*buf++ << 24);
-+ REG_MSC_TXFIFO = data;
-+ }
-+
-+ cnt--;
-+ }
-+ }
-+#endif
-+ return MMC_NO_ERROR;
-+}
-+
-+
-+/*
-+ * Name: int jz_mmc_exec_cmd()
-+ * Function: send command to the card, and get a response
-+ * Input: struct mmc_request *req : MMC/SD request
-+ * Output: 0: right >0: error code
-+ */
-+int jz_mmc_exec_cmd(struct mmc_request *request)
-+{
-+ u32 cmdat = 0, events = 0;
-+ int retval, timeout = 0x3fffff;
-+
-+ /* Indicate we have no result yet */
-+ request->result = MMC_NO_RESPONSE;
-+ if (request->cmd == MMC_CIM_RESET) {
-+ /* On reset, 1-bit bus width */
-+ use_4bit = 0;
-+
-+ /* Reset MMC/SD controller */
-+ __msc_reset();
-+
-+ /* On reset, drop MMC clock down */
-+ jz_mmc_set_clock(0, MMC_CLOCK_SLOW);
-+
-+ /* On reset, stop MMC clock */
-+ jz_mmc_stop_clock();
-+ }
-+ if (request->cmd == MMC_CMD_SEND_OP_COND) {
-+ debug("Have an MMC card\n");
-+ /* always use 1bit for MMC */
-+ use_4bit = 0;
-+ }
-+ if (request->cmd == SET_BUS_WIDTH) {
-+ if (request->arg == 0x2) {
-+ printf("Use 4-bit bus width\n");
-+ use_4bit = 1;
-+ } else {
-+ printf("Use 1-bit bus width\n");
-+ use_4bit = 0;
-+ }
-+ }
-+
-+ /* stop clock */
-+ jz_mmc_stop_clock();
-+
-+ /* mask all interrupts */
-+ REG_MSC_IMASK = 0xffff;
-+
-+ /* clear status */
-+ REG_MSC_IREG = 0xffff;
-+
-+ /* use 4-bit bus width when possible */
-+ if (use_4bit)
-+ cmdat |= MSC_CMDAT_BUS_WIDTH_4BIT;
-+
-+ /* Set command type and events */
-+ switch (request->cmd) {
-+ /* MMC core extra command */
-+ case MMC_CIM_RESET:
-+ cmdat |= MSC_CMDAT_INIT; /* Initialization sequence sent prior to command */
-+ break;
-+
-+ /* bc - broadcast - no response */
-+ case MMC_CMD_GO_IDLE_STATE:
-+ case MMC_CMD_SET_DSR:
-+ break;
-+
-+ /* bcr - broadcast with response */
-+ case MMC_CMD_SEND_OP_COND:
-+ case MMC_CMD_ALL_SEND_CID:
-+ case MMC_GO_IRQ_STATE:
-+ break;
-+
-+ /* adtc - addressed with data transfer */
-+ case MMC_READ_DAT_UNTIL_STOP:
-+ case MMC_CMD_READ_SINGLE_BLOCK:
-+ case MMC_CMD_READ_MULTIPLE_BLOCK:
-+ case SD_CMD_APP_SEND_SCR:
-+ cmdat |= MSC_CMDAT_DATA_EN | MSC_CMDAT_READ;
-+ events = MMC_EVENT_RX_DATA_DONE;
-+ break;
-+
-+ case MMC_WRITE_DAT_UNTIL_STOP:
-+ case MMC_CMD_WRITE_SINGLE_BLOCK:
-+ case MMC_CMD_WRITE_MULTIPLE_BLOCK:
-+ case MMC_PROGRAM_CID:
-+ case MMC_PROGRAM_CSD:
-+ case MMC_SEND_WRITE_PROT:
-+ case MMC_GEN_CMD:
-+ case MMC_LOCK_UNLOCK:
-+ cmdat |= MSC_CMDAT_DATA_EN | MSC_CMDAT_WRITE;
-+ events = MMC_EVENT_TX_DATA_DONE | MMC_EVENT_PROG_DONE;
-+
-+ break;
-+
-+ case MMC_CMD_STOP_TRANSMISSION:
-+ events = MMC_EVENT_PROG_DONE;
-+ break;
-+
-+ /* ac - no data transfer */
-+ default:
-+ break;
-+ }
-+
-+ /* Set response type */
-+ switch (request->rtype) {
-+ case RESPONSE_NONE:
-+ break;
-+
-+ case RESPONSE_R1B:
-+ cmdat |= MSC_CMDAT_BUSY;
-+ /*FALLTHRU*/
-+ case RESPONSE_R1:
-+ cmdat |= MSC_CMDAT_RESPONSE_R1;
-+ break;
-+ case RESPONSE_R2_CID:
-+ case RESPONSE_R2_CSD:
-+ cmdat |= MSC_CMDAT_RESPONSE_R2;
-+ break;
-+ case RESPONSE_R3:
-+ cmdat |= MSC_CMDAT_RESPONSE_R3;
-+ break;
-+ case RESPONSE_R4:
-+ cmdat |= MSC_CMDAT_RESPONSE_R4;
-+ break;
-+ case RESPONSE_R5:
-+ cmdat |= MSC_CMDAT_RESPONSE_R5;
-+ break;
-+ case RESPONSE_R6:
-+ cmdat |= MSC_CMDAT_RESPONSE_R6;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ /* Set command index */
-+ if (request->cmd == MMC_CIM_RESET) {
-+ REG_MSC_CMD = MMC_CMD_GO_IDLE_STATE;
-+ } else {
-+ REG_MSC_CMD = request->cmd;
-+ }
-+
-+ /* Set argument */
-+ REG_MSC_ARG = request->arg;
-+
-+ /* Set block length and nob */
-+ if (request->cmd == SD_CMD_APP_SEND_SCR) { /* get SCR from DataFIFO */
-+ REG_MSC_BLKLEN = 8;
-+ REG_MSC_NOB = 1;
-+ } else {
-+ REG_MSC_BLKLEN = request->block_len;
-+ REG_MSC_NOB = request->nob;
-+ }
-+
-+ /* Set command */
-+ REG_MSC_CMDAT = cmdat;
-+
-+ debug("Send cmd %d cmdat: %x arg: %x resp %d\n", request->cmd,
-+ cmdat, request->arg, request->rtype);
-+
-+ /* Start MMC/SD clock and send command to card */
-+ jz_mmc_start_clock();
-+
-+ /* Wait for command completion */
-+ while (timeout-- && !(REG_MSC_STAT & MSC_STAT_END_CMD_RES))
-+ ;
-+
-+ if (timeout == 0)
-+ return MMC_ERROR_TIMEOUT;
-+
-+ REG_MSC_IREG = MSC_IREG_END_CMD_RES; /* clear flag */
-+
-+ /* Check for status */
-+ retval = jz_mmc_check_status(request);
-+ if (retval) {
-+ return retval;
-+ }
-+
-+ /* Complete command with no response */
-+ if (request->rtype == RESPONSE_NONE) {
-+ return MMC_NO_ERROR;
-+ }
-+
-+ /* Get response */
-+ jz_mmc_get_response(request);
-+
-+ /* Start data operation */
-+ if (events & (MMC_EVENT_RX_DATA_DONE | MMC_EVENT_TX_DATA_DONE)) {
-+ if (events & MMC_EVENT_RX_DATA_DONE) {
-+ if (request->cmd == SD_CMD_APP_SEND_SCR) {
-+ /* SD card returns SCR register as data.
-+ MMC core expect it in the response buffer,
-+ after normal response. */
-+ request->buffer = (u8 *)((u32)request->response + 5);
-+ }
-+ jz_mmc_receive_data(request);
-+ }
-+
-+ if (events & MMC_EVENT_TX_DATA_DONE) {
-+ jz_mmc_transmit_data(request);
-+ }
-+
-+ /* Wait for Data Done */
-+ while (!(REG_MSC_IREG & MSC_IREG_DATA_TRAN_DONE))
-+ ;
-+ REG_MSC_IREG = MSC_IREG_DATA_TRAN_DONE; /* clear status */
-+ }
-+
-+ /* Wait for Prog Done event */
-+ if (events & MMC_EVENT_PROG_DONE) {
-+ while (!(REG_MSC_IREG & MSC_IREG_PRG_DONE))
-+ ;
-+ REG_MSC_IREG = MSC_IREG_PRG_DONE; /* clear status */
-+ }
-+
-+ /* Command completed */
-+
-+ return MMC_NO_ERROR; /* return successfully */
-+}
-+
-+int mmc_block_read(u8 *dst, ulong src, ulong len)
-+{
-+
-+ struct mmc_request request;
-+ struct mmc_response_r1 r1;
-+ int retval = 0;
-+
-+ if (len == 0)
-+ goto exit;
-+
-+ mmc_simple_cmd(&request, MMC_CMD_SEND_STATUS, mmcinfo.rca, RESPONSE_R1);
-+ retval = mmc_unpack_r1(&request, &r1, 0);
-+ if (retval && (retval != MMC_ERROR_STATE_MISMATCH))
-+ goto exit;
-+
-+ mmc_simple_cmd(&request, MMC_CMD_SET_BLOCKLEN, len, RESPONSE_R1);
-+ if (retval = mmc_unpack_r1(&request, &r1, 0))
-+ goto exit;
-+
-+ if (!sd2_0)
-+ src *= mmcinfo.block_len;
-+
-+ mmc_send_cmd(&request, MMC_CMD_READ_SINGLE_BLOCK, src, 1, len, RESPONSE_R1, dst);
-+ if (retval = mmc_unpack_r1(&request, &r1, 0))
-+ goto exit;
-+
-+exit:
-+ return retval;
-+}
-+
-+ulong mmc_bread(int dev_num, ulong blkstart, ulong blkcnt, ulong *dst)
-+{
-+ if (!mmc_ready) {
-+ printf("Please initial the MMC first\n");
-+ return -1;
-+ }
-+
-+ int i = 0;
-+ ulong dst_tmp = dst;
-+
-+ for (i = 0; i < blkcnt; i++) {
-+ if ((mmc_block_read((uchar *)(dst_tmp), blkstart, mmcinfo.block_len)) < 0)
-+ return -1;
-+
-+ dst_tmp += mmcinfo.block_len;
-+ blkstart++;
-+ }
-+
-+ return i;
-+}
-+
-+int mmc_select_card(void)
-+{
-+ struct mmc_request request;
-+ struct mmc_response_r1 r1;
-+ int retval;
-+
-+ mmc_simple_cmd(&request, MMC_CMD_SELECT_CARD, mmcinfo.rca, RESPONSE_R1B);
-+ retval = mmc_unpack_r1(&request, &r1, 0);
-+ if (retval) {
-+ return retval;
-+ }
-+
-+ if (mmcinfo.sd) {
-+ mmc_simple_cmd(&request, MMC_CMD_APP_CMD, mmcinfo.rca, RESPONSE_R1);
-+ retval = mmc_unpack_r1(&request,&r1,0);
-+ if (retval) {
-+ return retval;
-+ }
-+#if defined(MMC_BUS_WIDTH_1BIT)
-+ mmc_simple_cmd(&request, SET_BUS_WIDTH, 1, RESPONSE_R1);
-+#else
-+ mmc_simple_cmd(&request, SET_BUS_WIDTH, 2, RESPONSE_R1);
-+#endif
-+ retval = mmc_unpack_r1(&request,&r1,0);
-+ if (retval) {
-+ return retval;
-+ }
-+ }
-+ return 0;
-+}
-+
-+/*
-+ * Configure card
-+ */
-+static void mmc_configure_card(void)
-+{
-+ u32 rate;
-+
-+ /* Get card info */
-+ if (sd2_0)
-+ mmcinfo.block_num = (mmcinfo.csd.c_size + 1) << 10;
-+ else
-+ mmcinfo.block_num = (mmcinfo.csd.c_size + 1) * (1 << (mmcinfo.csd.c_size_mult + 2));
-+
-+ mmcinfo.block_len = 1 << mmcinfo.csd.read_bl_len;
-+
-+ mmc_dev.if_type = IF_TYPE_SD;
-+ mmc_dev.part_type = PART_TYPE_DOS;
-+ mmc_dev.dev = 0;
-+ mmc_dev.lun = 0;
-+ mmc_dev.type = 0;
-+ mmc_dev.blksz = mmcinfo.block_len;
-+ mmc_dev.lba = mmcinfo.block_num;
-+ mmc_dev.removable = 0;
-+
-+ printf("%s Detected: %lu blocks of %lu bytes\n",
-+ sd2_0 == 1 ? "SDHC" : "SD",
-+ mmc_dev.lba,
-+ mmc_dev.blksz);
-+
-+ /* Fix the clock rate */
-+ rate = mmc_tran_speed(mmcinfo.csd.tran_speed);
-+ if (rate < MMC_CLOCK_SLOW)
-+ rate = MMC_CLOCK_SLOW;
-+ if ((mmcinfo.sd == 0) && (rate > MMC_CLOCK_FAST))
-+ rate = MMC_CLOCK_FAST;
-+ if ((mmcinfo.sd) && (rate > SD_CLOCK_FAST))
-+ rate = SD_CLOCK_FAST;
-+
-+ debug("%s: block_len=%d block_num=%d rate=%d\n",
-+ __func__, mmcinfo.block_len, mmcinfo.block_num, rate);
-+
-+ jz_mmc_set_clock(mmcinfo.sd, rate);
-+}
-+
-+/*
-+ * State machine routines to initialize card(s)
-+ */
-+
-+/*
-+ CIM_SINGLE_CARD_ACQ (frequency at 400 kHz)
-+ --- Must enter from GO_IDLE_STATE ---
-+ 1. SD_SEND_OP_COND (SD Card) [CMD55] + [CMD41]
-+ 2. SEND_OP_COND (Full Range) [CMD1] {optional}
-+ 3. SEND_OP_COND (Set Range ) [CMD1]
-+ If busy, delay and repeat step 2
-+ 4. ALL_SEND_CID [CMD2]
-+ If timeout, set an error (no cards found)
-+ 5. SET_RELATIVE_ADDR [CMD3]
-+ 6. SEND_CSD [CMD9]
-+ 7. SET_DSR [CMD4] Only call this if (csd.dsr_imp).
-+ 8. Set clock frequency (check available in csd.tran_speed)
-+ */
-+
-+#define MMC_INIT_DOING 0
-+#define MMC_INIT_PASSED 1
-+#define MMC_INIT_FAILED 2
-+
-+static int mmc_init_card_state(struct mmc_request *request)
-+{
-+ struct mmc_response_r1 r1;
-+ struct mmc_response_r3 r3;
-+ int retval;
-+ int ocr = 0x40300000;
-+ int limit_41 = 0;
-+
-+ switch (request->cmd) {
-+ case MMC_CMD_GO_IDLE_STATE: /* No response to parse */
-+ if (mmcinfo.sd)
-+ mmc_simple_cmd(request, 8, 0x1aa, RESPONSE_R1);
-+ else
-+ mmc_simple_cmd(request, MMC_CMD_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3);
-+ break;
-+
-+ case 8:
-+ retval = mmc_unpack_r1(request,&r1,mmcinfo.state);
-+ mmc_simple_cmd(request, MMC_CMD_APP_CMD, 0, RESPONSE_R1);
-+ break;
-+
-+ case MMC_CMD_APP_CMD:
-+ retval = mmc_unpack_r1(request,&r1,mmcinfo.state);
-+ if (retval & (limit_41 < 100)) {
-+ debug("%s: unable to MMC_APP_CMD error=%d (%s)\n",
-+ __func__, retval, mmc_result_to_string(retval));
-+ limit_41++;
-+ mmc_simple_cmd(request, SD_CMD_APP_SEND_OP_COND, ocr, RESPONSE_R3);
-+ } else if (limit_41 < 100) {
-+ limit_41++;
-+ mmc_simple_cmd(request, SD_CMD_APP_SEND_OP_COND, ocr, RESPONSE_R3);
-+ } else{
-+ /* reset the card to idle*/
-+ mmc_simple_cmd(request, MMC_CMD_GO_IDLE_STATE, 0, RESPONSE_NONE);
-+ mmcinfo.sd = 0;
-+ }
-+ break;
-+
-+ case SD_CMD_APP_SEND_OP_COND:
-+ retval = mmc_unpack_r3(request, &r3);
-+ if (retval) {
-+ debug("%s: try MMC card\n", __func__);
-+ mmc_simple_cmd(request, SD_CMD_APP_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3);
-+ break;
-+ }
-+
-+ debug("%s: read ocr value = 0x%08x\n", __func__, r3.ocr);
-+
-+ if(!(r3.ocr & MMC_CARD_BUSY || ocr == 0)){
-+ udelay(50000);
-+ mmc_simple_cmd(request, MMC_CMD_APP_CMD, 0, RESPONSE_R1);
-+ } else {
-+ mmcinfo.sd = 1; /* SD Card ready */
-+ mmcinfo.state = CARD_STATE_READY;
-+ mmc_simple_cmd(request, MMC_CMD_ALL_SEND_CID, 0, RESPONSE_R2_CID);
-+ }
-+ break;
-+
-+ case MMC_CMD_SEND_OP_COND:
-+ retval = mmc_unpack_r3(request, &r3);
-+ if (retval) {
-+ debug("%s: failed SEND_OP_COND error=%d (%s)\n",
-+ __func__, retval, mmc_result_to_string(retval));
-+ return MMC_INIT_FAILED;
-+ }
-+
-+ debug("%s: read ocr value = 0x%08x\n", __func__, r3.ocr);
-+ if (!(r3.ocr & MMC_CARD_BUSY)) {
-+ mmc_simple_cmd(request, MMC_CMD_SEND_OP_COND, MMC_OCR_ARG, RESPONSE_R3);
-+ } else {
-+ mmcinfo.sd = 0; /* MMC Card ready */
-+ mmcinfo.state = CARD_STATE_READY;
-+ mmc_simple_cmd(request, MMC_CMD_ALL_SEND_CID, 0, RESPONSE_R2_CID);
-+ }
-+ break;
-+
-+ case MMC_CMD_ALL_SEND_CID:
-+ retval = mmc_unpack_cid( request, &mmcinfo.cid );
-+ /*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */
-+ if ( retval && (retval != MMC_ERROR_CRC)) {
-+ debug("mmc_init_card_state: unable to ALL_SEND_CID error=%d (%s)\n",
-+ retval, mmc_result_to_string(retval));
-+ return MMC_INIT_FAILED;
-+ }
-+ mmcinfo.state = CARD_STATE_IDENT;
-+ if(mmcinfo.sd)
-+ mmc_simple_cmd(request, MMC_CMD_SET_RELATIVE_ADDR, 0, RESPONSE_R6);
-+ else
-+ mmc_simple_cmd(request, MMC_CMD_SET_RELATIVE_ADDR, ID_TO_RCA(mmcinfo.id) << 16, RESPONSE_R1);
-+ break;
-+
-+ case MMC_CMD_SET_RELATIVE_ADDR:
-+ if (mmcinfo.sd) {
-+ retval = mmc_unpack_r6(request, &r1, mmcinfo.state, &mmcinfo.rca);
-+ mmcinfo.rca = mmcinfo.rca << 16;
-+ debug("%s: Get RCA from SD: 0x%04x Status: %x\n",
-+ __func__, mmcinfo.rca, r1.status);
-+ } else {
-+ retval = mmc_unpack_r1(request,&r1,mmcinfo.state);
-+ mmcinfo.rca = ID_TO_RCA(mmcinfo.id) << 16;
-+ }
-+ if (retval) {
-+ debug("%s: unable to SET_RELATIVE_ADDR error=%d (%s)\n",
-+ __func__, retval, mmc_result_to_string(retval));
-+ return MMC_INIT_FAILED;
-+ }
-+
-+ mmcinfo.state = CARD_STATE_STBY;
-+ mmc_simple_cmd(request, MMC_CMD_SEND_CSD, mmcinfo.rca, RESPONSE_R2_CSD);
-+
-+ break;
-+
-+ case MMC_CMD_SEND_CSD:
-+ retval = mmc_unpack_csd(request, &mmcinfo.csd);
-+ mmc_ready = 1;
-+ /*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */
-+ if (retval && (retval != MMC_ERROR_CRC)) {
-+ debug("%s: unable to SEND_CSD error=%d (%s)\n",
-+ __func__, retval, mmc_result_to_string(retval));
-+ return MMC_INIT_FAILED;
-+ }
-+ if (mmcinfo.csd.dsr_imp) {
-+ debug("%s: driver doesn't support setting DSR\n", __func__);
-+ }
-+ mmc_configure_card();
-+ return MMC_INIT_PASSED;
-+
-+ default:
-+ debug("%s: error! Illegal last cmd %d\n", __func__, request->cmd);
-+ return MMC_INIT_FAILED;
-+ }
-+
-+ return MMC_INIT_DOING;
-+}
-+
-+int mmc_init_card(void)
-+{
-+ struct mmc_request request;
-+ int retval;
-+
-+ mmc_simple_cmd(&request, MMC_CIM_RESET, 0, RESPONSE_NONE); /* reset card */
-+ mmc_simple_cmd(&request, MMC_CMD_GO_IDLE_STATE, 0, RESPONSE_NONE);
-+ mmcinfo.sd = 1; /* assuming a SD card */
-+
-+ while ((retval = mmc_init_card_state(&request)) == MMC_INIT_DOING)
-+ ;
-+
-+ if (retval == MMC_INIT_PASSED)
-+ return MMC_NO_ERROR;
-+ else
-+ return MMC_NO_RESPONSE;
-+}
-+
-+int mmc_legacy_init(int verbose)
-+{
-+ if (!__msc_card_detected())
-+ return 1;
-+
-+ /* Step-1: init GPIO */
-+ __gpio_as_msc();
-+ __msc_init_io();
-+
-+ /* Step-2: turn on power of card */
-+#if !defined(CONFIG_SAKC)
-+ __msc_enable_power();
-+#endif
-+
-+ /* Step-3: Reset MSC Controller. */
-+ __msc_reset();
-+
-+ /* Step-3: mask all IRQs. */
-+ MMC_IRQ_MASK();
-+
-+ /* Step-4: stop MMC/SD clock */
-+ jz_mmc_stop_clock();
-+ mmc_init_card();
-+ mmc_select_card();
-+
-+ mmc_dev.block_read = mmc_bread;
-+ fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */
-+
-+ return 0;
-+}
-+
-+/*
-+ * Debugging functions
-+ */
-+static char * mmc_result_strings[] = {
-+ "NO_RESPONSE",
-+ "NO_ERROR",
-+ "ERROR_OUT_OF_RANGE",
-+ "ERROR_ADDRESS",
-+ "ERROR_BLOCK_LEN",
-+ "ERROR_ERASE_SEQ",
-+ "ERROR_ERASE_PARAM",
-+ "ERROR_WP_VIOLATION",
-+ "ERROR_CARD_IS_LOCKED",
-+ "ERROR_LOCK_UNLOCK_FAILED",
-+ "ERROR_COM_CRC",
-+ "ERROR_ILLEGAL_COMMAND",
-+ "ERROR_CARD_ECC_FAILED",
-+ "ERROR_CC",
-+ "ERROR_GENERAL",
-+ "ERROR_UNDERRUN",
-+ "ERROR_OVERRUN",
-+ "ERROR_CID_CSD_OVERWRITE",
-+ "ERROR_STATE_MISMATCH",
-+ "ERROR_HEADER_MISMATCH",
-+ "ERROR_TIMEOUT",
-+ "ERROR_CRC",
-+ "ERROR_DRIVER_FAILURE",
-+};
-+
-+char * mmc_result_to_string(int i)
-+{
-+ return mmc_result_strings[i+1];
-+}
-+
-+static char * card_state_strings[] = {
-+ "empty",
-+ "idle",
-+ "ready",
-+ "ident",
-+ "stby",
-+ "tran",
-+ "data",
-+ "rcv",
-+ "prg",
-+ "dis",
-+};
-+
-+static inline char * card_state_to_string(int i)
-+{
-+ return card_state_strings[i+1];
-+}
-+
-+/*
-+ * Utility functions
-+ */
-+
-+#define PARSE_U32(_buf,_index) \
-+ (((u32)_buf[_index]) << 24) | (((u32)_buf[_index+1]) << 16) | \
-+ (((u32)_buf[_index+2]) << 8) | ((u32)_buf[_index+3]);
-+
-+#define PARSE_U16(_buf,_index) \
-+ (((u16)_buf[_index]) << 8) | ((u16)_buf[_index+1]);
-+
-+int mmc_unpack_csd(struct mmc_request *request, struct mmc_csd *csd)
-+{
-+ u8 *buf = request->response;
-+ int num = 0;
-+
-+ if (request->result)
-+ return request->result;
-+
-+ if (buf[0] != 0x3f)
-+ return MMC_ERROR_HEADER_MISMATCH;
-+
-+ csd->csd_structure = (buf[1] & 0xc0) >> 6;
-+ if (csd->csd_structure)
-+ sd2_0 = 1;
-+ else
-+ sd2_0 = 0;
-+
-+ switch (csd->csd_structure) {
-+ case 0 :/* Version 1.01-1.10
-+ * Version 2.00/Standard Capacity */
-+ csd->taac = buf[2];
-+ csd->nsac = buf[3];
-+ csd->tran_speed = buf[4];
-+ csd->ccc = (((u16)buf[5]) << 4) | ((buf[6] & 0xf0) >> 4);
-+ csd->read_bl_len = buf[6] & 0x0f;
-+ /* for support 2GB card*/
-+ if (csd->read_bl_len >= 10)
-+ {
-+ num = csd->read_bl_len - 9;
-+ csd->read_bl_len = 9;
-+ }
-+
-+ csd->read_bl_partial = (buf[7] & 0x80) ? 1 : 0;
-+ csd->write_blk_misalign = (buf[7] & 0x40) ? 1 : 0;
-+ csd->read_blk_misalign = (buf[7] & 0x20) ? 1 : 0;
-+ csd->dsr_imp = (buf[7] & 0x10) ? 1 : 0;
-+ csd->c_size = ((((u16)buf[7]) & 0x03) << 10) | (((u16)buf[8]) << 2) | (((u16)buf[9]) & 0xc0) >> 6;
-+
-+ if (num)
-+ csd->c_size = csd->c_size << num;
-+
-+
-+ csd->vdd_r_curr_min = (buf[9] & 0x38) >> 3;
-+ csd->vdd_r_curr_max = buf[9] & 0x07;
-+ csd->vdd_w_curr_min = (buf[10] & 0xe0) >> 5;
-+ csd->vdd_w_curr_max = (buf[10] & 0x1c) >> 2;
-+ csd->c_size_mult = ((buf[10] & 0x03) << 1) | ((buf[11] & 0x80) >> 7);
-+ csd->sector_size = (buf[11] & 0x7c) >> 2;
-+ csd->erase_grp_size = ((buf[11] & 0x03) << 3) | ((buf[12] & 0xe0) >> 5);
-+ csd->wp_grp_size = buf[12] & 0x1f;
-+ csd->wp_grp_enable = (buf[13] & 0x80) ? 1 : 0;
-+ csd->default_ecc = (buf[13] & 0x60) >> 5;
-+ csd->r2w_factor = (buf[13] & 0x1c) >> 2;
-+ csd->write_bl_len = ((buf[13] & 0x03) << 2) | ((buf[14] & 0xc0) >> 6);
-+ if (csd->write_bl_len >= 10)
-+ csd->write_bl_len = 9;
-+
-+ csd->write_bl_partial = (buf[14] & 0x20) ? 1 : 0;
-+ csd->file_format_grp = (buf[15] & 0x80) ? 1 : 0;
-+ csd->copy = (buf[15] & 0x40) ? 1 : 0;
-+ csd->perm_write_protect = (buf[15] & 0x20) ? 1 : 0;
-+ csd->tmp_write_protect = (buf[15] & 0x10) ? 1 : 0;
-+ csd->file_format = (buf[15] & 0x0c) >> 2;
-+ csd->ecc = buf[15] & 0x03;
-+ break;
-+ case 1 : /* Version 2.00/High Capacity */
-+ csd->taac = 0;
-+ csd->nsac = 0;
-+ csd->tran_speed = buf[4];
-+ csd->ccc = (((u16)buf[5]) << 4) | ((buf[6] & 0xf0) >> 4);
-+
-+ csd->read_bl_len = 9;
-+ csd->read_bl_partial = 0;
-+ csd->write_blk_misalign = 0;
-+ csd->read_blk_misalign = 0;
-+ csd->dsr_imp = (buf[7] & 0x10) ? 1 : 0;
-+ csd->c_size = ((((u16)buf[8]) & 0x3f) << 16) | (((u16)buf[9]) << 8) | ((u16)buf[10]) ;
-+ csd->sector_size = 0x7f;
-+ csd->erase_grp_size = 0;
-+ csd->wp_grp_size = 0;
-+ csd->wp_grp_enable = 0;
-+ csd->default_ecc = (buf[13] & 0x60) >> 5;
-+ csd->r2w_factor = 4;/* Unused */
-+ csd->write_bl_len = 9;
-+
-+ csd->write_bl_partial = 0;
-+ csd->file_format_grp = 0;
-+ csd->copy = (buf[15] & 0x40) ? 1 : 0;
-+ csd->perm_write_protect = (buf[15] & 0x20) ? 1 : 0;
-+ csd->tmp_write_protect = (buf[15] & 0x10) ? 1 : 0;
-+ csd->file_format = 0;
-+ csd->ecc = buf[15] & 0x03;
-+ }
-+
-+ return 0;
-+}
-+
-+int mmc_unpack_r1(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state)
-+{
-+ u8 *buf = request->response;
-+
-+ if (request->result)
-+ return request->result;
-+
-+ r1->cmd = buf[0];
-+ r1->status = PARSE_U32(buf,1);
-+
-+ debug("mmc_unpack_r1: cmd=%d status=%08x\n", r1->cmd, r1->status);
-+
-+ if (R1_STATUS(r1->status)) {
-+ if (r1->status & R1_OUT_OF_RANGE) return MMC_ERROR_OUT_OF_RANGE;
-+ if (r1->status & R1_ADDRESS_ERROR) return MMC_ERROR_ADDRESS;
-+ if (r1->status & R1_BLOCK_LEN_ERROR) return MMC_ERROR_BLOCK_LEN;
-+ if (r1->status & R1_ERASE_SEQ_ERROR) return MMC_ERROR_ERASE_SEQ;
-+ if (r1->status & R1_ERASE_PARAM) return MMC_ERROR_ERASE_PARAM;
-+ if (r1->status & R1_WP_VIOLATION) return MMC_ERROR_WP_VIOLATION;
-+ /*if (r1->status & R1_CARD_IS_LOCKED) return MMC_ERROR_CARD_IS_LOCKED; */
-+ if (r1->status & R1_LOCK_UNLOCK_FAILED) return MMC_ERROR_LOCK_UNLOCK_FAILED;
-+ if (r1->status & R1_COM_CRC_ERROR) return MMC_ERROR_COM_CRC;
-+ if (r1->status & R1_ILLEGAL_COMMAND) return MMC_ERROR_ILLEGAL_COMMAND;
-+ if (r1->status & R1_CARD_ECC_FAILED) return MMC_ERROR_CARD_ECC_FAILED;
-+ if (r1->status & R1_CC_ERROR) return MMC_ERROR_CC;
-+ if (r1->status & R1_ERROR) return MMC_ERROR_GENERAL;
-+ if (r1->status & R1_UNDERRUN) return MMC_ERROR_UNDERRUN;
-+ if (r1->status & R1_OVERRUN) return MMC_ERROR_OVERRUN;
-+ if (r1->status & R1_CID_CSD_OVERWRITE) return MMC_ERROR_CID_CSD_OVERWRITE;
-+ }
-+
-+ if (buf[0] != request->cmd)
-+ return MMC_ERROR_HEADER_MISMATCH;
-+
-+ /* This should be last - it's the least dangerous error */
-+
-+ return 0;
-+}
-+
-+int mmc_unpack_scr(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, u32 *scr)
-+{
-+ u8 *buf = request->response;
-+ if (request->result)
-+ return request->result;
-+
-+ *scr = PARSE_U32(buf, 5); /* Save SCR returned by the SD Card */
-+ return mmc_unpack_r1(request, r1, state);
-+
-+}
-+
-+int mmc_unpack_r6(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, int *rca)
-+{
-+ u8 *buf = request->response;
-+
-+ if (request->result)
-+ return request->result;
-+
-+ *rca = PARSE_U16(buf,1); /* Save RCA returned by the SD Card */
-+
-+ *(buf+1) = 0;
-+ *(buf+2) = 0;
-+
-+ return mmc_unpack_r1(request, r1, state);
-+}
-+
-+int mmc_unpack_cid(struct mmc_request *request, struct mmc_cid *cid)
-+{
-+ int i;
-+ u8 *buf = request->response;
-+
-+ if (request->result)
-+ return request->result;
-+
-+ cid->mid = buf[1];
-+ cid->oid = PARSE_U16(buf,2);
-+ for (i = 0 ; i < 5 ; i++)
-+ cid->pnm[i] = buf[4+i];
-+ cid->pnm[6] = 0;
-+ cid->prv = buf[10];
-+ cid->psn = PARSE_U32(buf,10);
-+ cid->mdt = buf[15];
-+
-+ printf("Man %02x OEM 0x%04x \"%s\" %d.%d 0x%08x "
-+ "Date %02u/%04u\n",
-+ cid->mid,
-+ cid->oid,
-+ cid->pnm,
-+ cid->prv >> 4,
-+ cid->prv & 0xf,
-+ cid->psn,
-+ cid->mdt & 0xf,
-+ (cid->mdt >> 4) + 2000);
-+
-+ if (buf[0] != 0x3f)
-+ return MMC_ERROR_HEADER_MISMATCH;
-+ return 0;
-+}
-+
-+int mmc_unpack_r3(struct mmc_request *request, struct mmc_response_r3 *r3)
-+{
-+ u8 *buf = request->response;
-+
-+ if (request->result)
-+ return request->result;
-+
-+ r3->ocr = PARSE_U32(buf,1);
-+ debug("mmc_unpack_r3: ocr=%08x\n", r3->ocr);
-+
-+ if (buf[0] != 0x3f) return MMC_ERROR_HEADER_MISMATCH;
-+ return 0;
-+}
-+
-+#define KBPS 1
-+#define MBPS 1000
-+
-+static u32 ts_exp[] = { 100*KBPS, 1*MBPS, 10*MBPS, 100*MBPS, 0, 0, 0, 0 };
-+static u32 ts_mul[] = { 0, 1000, 1200, 1300, 1500, 2000, 2500, 3000,
-+ 3500, 4000, 4500, 5000, 5500, 6000, 7000, 8000 };
-+
-+u32 mmc_tran_speed(u8 ts)
-+{
-+ u32 rate = ts_exp[(ts & 0x7)] * ts_mul[(ts & 0x78) >> 3];
-+
-+ if (rate <= 0) {
-+ debug("%s: error - unrecognized speed 0x%02x\n", __func__, ts);
-+ return 1;
-+ }
-+
-+ return rate;
-+}
-+
-+void mmc_send_cmd(struct mmc_request *request, int cmd, u32 arg,
-+ u16 nob, u16 block_len, enum mmc_rsp_t rtype, u8 *buffer)
-+{
-+ request->cmd = cmd;
-+ request->arg = arg;
-+ request->rtype = rtype;
-+ request->nob = nob;
-+ request->block_len = block_len;
-+ request->buffer = buffer;
-+ request->cnt = nob * block_len;
-+
-+ jz_mmc_exec_cmd(request);
-+}
-diff --git a/drivers/mmc/jz_mmc.h b/drivers/mmc/jz_mmc.h
-new file mode 100644
-index 0000000..936c514
---- /dev/null
-+++ b/drivers/mmc/jz_mmc.h
-@@ -0,0 +1,176 @@
-+/*
-+ * linux/drivers/mmc/jz_mmc.h
-+ *
-+ * Author: Vladimir Shebordaev, Igor Oblakov
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * $Id: jz_mmc.h,v 1.3 2007-06-15 08:04:20 jlwei Exp $
-+ *
-+ * 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_JZMMC_H__
-+#define __MMC_JZMMC_H__
-+
-+#define ID_TO_RCA(x) ((x)+1)
-+#define MMC_OCR_ARG 0x00ff8000 /* Argument of OCR */
-+
-+/* Standard MMC/SD clock speeds */
-+#define MMC_CLOCK_SLOW 400000 /* 400 kHz for initial setup */
-+#define MMC_CLOCK_FAST 20000000 /* 20 MHz for maximum for normal operation */
-+#define SD_CLOCK_FAST 24000000 /* 24 MHz for SD Cards */
-+
-+/* Use negative numbers to disambiguate */
-+#define MMC_CIM_RESET -1
-+#define SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
-+
-+#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 MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */
-+
-+#define MMC_PROGRAM_CID 26 /* adtc R1 */
-+#define MMC_PROGRAM_CSD 27 /* adtc R1 */
-+
-+#define MMC_GO_IRQ_STATE 40 /* bcr R5 */
-+#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1b */
-+#define MMC_LOCK_UNLOCK 42 /* adtc R1b */
-+#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
-+#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
-+#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
-+
-+
-+enum mmc_result_t {
-+ MMC_NO_RESPONSE = -1,
-+ MMC_NO_ERROR = 0,
-+ MMC_ERROR_OUT_OF_RANGE,
-+ MMC_ERROR_ADDRESS,
-+ MMC_ERROR_BLOCK_LEN,
-+ MMC_ERROR_ERASE_SEQ,
-+ MMC_ERROR_ERASE_PARAM,
-+ MMC_ERROR_WP_VIOLATION,
-+ MMC_ERROR_CARD_IS_LOCKED,
-+ MMC_ERROR_LOCK_UNLOCK_FAILED,
-+ MMC_ERROR_COM_CRC,
-+ MMC_ERROR_ILLEGAL_COMMAND,
-+ MMC_ERROR_CARD_ECC_FAILED,
-+ MMC_ERROR_CC,
-+ MMC_ERROR_GENERAL,
-+ MMC_ERROR_UNDERRUN,
-+ MMC_ERROR_OVERRUN,
-+ MMC_ERROR_CID_CSD_OVERWRITE,
-+ MMC_ERROR_STATE_MISMATCH,
-+ MMC_ERROR_HEADER_MISMATCH,
-+ MMC_ERROR_TIMEOUT,
-+ MMC_ERROR_CRC,
-+ MMC_ERROR_DRIVER_FAILURE,
-+};
-+
-+enum card_state {
-+ CARD_STATE_EMPTY = -1,
-+ CARD_STATE_IDLE = 0,
-+ CARD_STATE_READY = 1,
-+ CARD_STATE_IDENT = 2,
-+ CARD_STATE_STBY = 3,
-+ CARD_STATE_TRAN = 4,
-+ CARD_STATE_DATA = 5,
-+ CARD_STATE_RCV = 6,
-+ CARD_STATE_PRG = 7,
-+ CARD_STATE_DIS = 8,
-+};
-+
-+enum mmc_rsp_t {
-+ RESPONSE_NONE = 0,
-+ RESPONSE_R1 = 1,
-+ RESPONSE_R1B = 2,
-+ RESPONSE_R2_CID = 3,
-+ RESPONSE_R2_CSD = 4,
-+ RESPONSE_R3 = 5,
-+ RESPONSE_R4 = 6,
-+ RESPONSE_R5 = 7,
-+ RESPONSE_R6 = 8,
-+};
-+
-+struct mmc_response_r1 {
-+ u8 cmd;
-+ u32 status;
-+};
-+
-+struct mmc_response_r3 {
-+ u32 ocr;
-+};
-+
-+/* the information structure of MMC/SD Card */
-+struct mmc_info {
-+ int id; /* Card index */
-+ int sd; /* MMC or SD card */
-+ int rca; /* RCA */
-+ u32 scr; /* SCR 63:32*/
-+ int flags; /* Ejected, inserted */
-+ enum card_state state; /* empty, ident, ready, whatever */
-+
-+ /* Card specific information */
-+ struct mmc_cid cid;
-+ struct mmc_csd csd;
-+ u32 block_num;
-+ u32 block_len;
-+ u32 erase_unit;
-+};
-+
-+struct mmc_info mmcinfo;
-+
-+struct mmc_request {
-+ int index; /* Slot index - used for CS lines */
-+ int cmd; /* Command to send */
-+ u32 arg; /* Argument to send */
-+ enum mmc_rsp_t rtype; /* Response type expected */
-+
-+ /* Data transfer (these may be modified at the low level) */
-+ u16 nob; /* Number of blocks to transfer*/
-+ u16 block_len; /* Block length */
-+ u8 *buffer; /* Data buffer */
-+ u32 cnt; /* Data length, for PIO */
-+
-+ /* Results */
-+ u8 response[18]; /* Buffer to store response - CRC is optional */
-+ enum mmc_result_t result;
-+};
-+
-+char * mmc_result_to_string(int);
-+int mmc_unpack_csd(struct mmc_request *request, struct mmc_csd *csd);
-+int mmc_unpack_r1(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state);
-+int mmc_unpack_r6(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, int *rca);
-+int mmc_unpack_scr(struct mmc_request *request, struct mmc_response_r1 *r1, enum card_state state, u32 *scr);
-+int mmc_unpack_cid(struct mmc_request *request, struct mmc_cid *cid);
-+int mmc_unpack_r3(struct mmc_request *request, struct mmc_response_r3 *r3);
-+
-+void mmc_send_cmd(struct mmc_request *request, int cmd, u32 arg,
-+ u16 nob, u16 block_len, enum mmc_rsp_t rtype, u8 *buffer);
-+u32 mmc_tran_speed(u8 ts);
-+void jz_mmc_set_clock(int sd, u32 rate);
-+
-+static inline void mmc_simple_cmd(struct mmc_request *request, int cmd, u32 arg, enum mmc_rsp_t rtype)
-+{
-+ mmc_send_cmd( request, cmd, arg, 0, 0, rtype, 0);
-+}
-+
-+#endif /* __MMC_JZMMC_H__ */
-diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h
-index 7bff444..7b33be0 100644
---- a/include/configs/qi_lb60.h
-+++ b/include/configs/qi_lb60.h
-@@ -31,6 +31,15 @@
- /*
- * Miscellaneous configurable options
- */
-+#define CONFIG_JZ4740_MMC
-+#define CONFIG_MMC 1
-+#define CONFIG_FAT 1
-+#define CONFIG_DOS_PARTITION 1
-+#define CONFIG_CMD_MMC
-+#define CONFIG_CMD_FAT
-+#define CONFIG_CMD_EXT2
-+
-+
- #define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */
- #define CONFIG_SYS_INIT_SP_OFFSET 0x400000
- #define CONFIG_SYS_LOAD_ADDR 0x80600000
-diff --git a/include/mmc.h b/include/mmc.h
-index a13e2bd..3c4761c 100644
---- a/include/mmc.h
-+++ b/include/mmc.h
-@@ -283,4 +283,44 @@ struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode);
- int mmc_legacy_init(int verbose);
- #endif
-
-+struct mmc_csd
-+{
-+ u8 csd_structure:2,
-+ spec_vers:4,
-+ rsvd1:2;
-+ u8 taac;
-+ u8 nsac;
-+ u8 tran_speed;
-+ u16 ccc:12,
-+ read_bl_len:4;
-+ u32 c_size:22;
-+ u64 read_bl_partial:1,
-+ write_blk_misalign:1,
-+ read_blk_misalign:1,
-+ dsr_imp:1,
-+ rsvd2:2,
-+ vdd_r_curr_min:3,
-+ vdd_r_curr_max:3,
-+ vdd_w_curr_min:3,
-+ vdd_w_curr_max:3,
-+ c_size_mult:3,
-+ sector_size:5,
-+ erase_grp_size:5,
-+ wp_grp_size:5,
-+ wp_grp_enable:1,
-+ default_ecc:2,
-+ r2w_factor:3,
-+ write_bl_len:4,
-+ write_bl_partial:1,
-+ rsvd3:5;
-+ u8 file_format_grp:1,
-+ copy:1,
-+ perm_write_protect:1,
-+ tmp_write_protect:1,
-+ file_format:2,
-+ ecc:2;
-+ u8 crc:7;
-+ u8 one:1;
-+};
-+
- #endif /* _MMC_H_ */
---
-1.7.9.5
-
diff --git a/package/boot/uboot-xburst/patches/0004-add-more-boot-options-F1-F2-F3-F4-M-S.patch b/package/boot/uboot-xburst/patches/0004-add-more-boot-options-F1-F2-F3-F4-M-S.patch
deleted file mode 100644
index 73e03243c3..0000000000
--- a/package/boot/uboot-xburst/patches/0004-add-more-boot-options-F1-F2-F3-F4-M-S.patch
+++ /dev/null
@@ -1,200 +0,0 @@
-From c52b6168979d03fc31205444c3278c537787472a Mon Sep 17 00:00:00 2001
-From: Xiangfu <xiangfu@openmobilefree.net>
-Date: Wed, 10 Oct 2012 18:39:55 +0800
-Subject: [PATCH 4/6] add more boot options(F1/F2/F3/F4/M/S)
-
----
- arch/mips/include/asm/global_data.h | 3 +++
- arch/mips/lib/bootm.c | 17 ++++++++++++++++-
- board/qi/qi_lb60/qi_lb60.c | 26 +++++++++++++++++++++++---
- common/main.c | 21 +++++++++++++++++++--
- include/configs/qi_lb60.h | 32 ++++++++++++++++++++++++++++++++
- 5 files changed, 93 insertions(+), 6 deletions(-)
-
-diff --git a/arch/mips/include/asm/global_data.h b/arch/mips/include/asm/global_data.h
-index 6e2cdc7..cd03d7e 100644
---- a/arch/mips/include/asm/global_data.h
-+++ b/arch/mips/include/asm/global_data.h
-@@ -59,6 +59,9 @@ typedef struct global_data {
- unsigned long env_valid; /* Checksum of Environment valid? */
- void **jt; /* jump table */
- char env_buf[32]; /* buffer for getenv() before reloc. */
-+#if defined(CONFIG_NANONOTE)
-+ unsigned long boot_option;
-+#endif
- } gd_t;
-
- #include <asm-generic/global_data_flags.h>
-diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c
-index 608c1a7..e00416b 100644
---- a/arch/mips/lib/bootm.c
-+++ b/arch/mips/lib/bootm.c
-@@ -47,10 +47,25 @@ int do_bootm_linux(int flag, int argc, char * const argv[],
- bootm_headers_t *images)
- {
- void (*theKernel) (int, char **, char **, int *);
-- char *commandline = getenv("bootargs");
-+ char *commandline;
- char env_buf[12];
- char *cp;
-
-+#if defined(CONFIG_NANONOTE)
-+ if (gd->boot_option & BOOT_FROM_MEMCARD)
-+ commandline = getenv ("bootargsfromsd");
-+ else if (gd->boot_option & BOOT_WITH_F1)
-+ commandline = getenv ("bootargsf1");
-+ else if (gd->boot_option & BOOT_WITH_F2)
-+ commandline = getenv ("bootargsf2");
-+ else if (gd->boot_option & BOOT_WITH_F3)
-+ commandline = getenv ("bootargsf3");
-+ else if (gd->boot_option & BOOT_WITH_F4)
-+ commandline = getenv ("bootargsf4");
-+ else
-+#endif
-+ commandline = getenv ("bootargs");
-+
- if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
- return 1;
-
-diff --git a/board/qi/qi_lb60/qi_lb60.c b/board/qi/qi_lb60/qi_lb60.c
-index a2ba648..d622219 100644
---- a/board/qi/qi_lb60/qi_lb60.c
-+++ b/board/qi/qi_lb60/qi_lb60.c
-@@ -15,7 +15,7 @@ DECLARE_GLOBAL_DATA_PTR;
-
- static void gpio_init(void)
- {
-- unsigned int i;
-+ unsigned int i, j;
-
- /* Initialize NAND Flash Pins */
- __gpio_as_nand();
-@@ -42,14 +42,34 @@ static void gpio_init(void)
-
- if (__gpio_get_pin(GPIO_KEYIN_BASE + 2) == 0){
- printf("[S] pressed, enable UART0\n");
-+ gd->boot_option |= BOOT_WITH_ENABLE_UART;
- __gpio_as_uart0();
- } else {
- __gpio_as_input(GPIO_KEYIN_8);
- __gpio_enable_pull(GPIO_KEYIN_8);
- }
-
-- /* enable the TP4, TP5 as UART0 */
-- __gpio_jtag_to_uart0();
-+ if (__gpio_get_pin(GPIO_KEYIN_BASE + 3) == 0) {
-+ printf("[M] pressed, boot from memory card\n");
-+ gd->boot_option |= BOOT_FROM_MEMCARD;
-+ __gpio_jtag_to_uart0();
-+ }
-+
-+ for (j = 0; j < 4; j++) {
-+ for (i = 0; i < 4; i++)
-+ __gpio_set_pin(GPIO_KEYOUT_BASE + i);
-+
-+ __gpio_clear_pin(GPIO_KEYOUT_BASE + j);
-+
-+ if (__gpio_get_pin(GPIO_KEYIN_BASE) == 0) {
-+ printf("[F%d] pressed", (j + 1));
-+ gd->boot_option |= (1 << (j + 2));
-+ /* BOOT_WITH_F1 (1 << 2) */
-+ /* BOOT_WITH_F2 (1 << 3) */
-+ /* BOOT_WITH_F3 (1 << 4) */
-+ /* BOOT_WITH_F4 (1 << 5) */
-+ }
-+ }
-
- __gpio_as_output(GPIO_AUDIO_POP);
- __gpio_set_pin(GPIO_AUDIO_POP);
-diff --git a/common/main.c b/common/main.c
-index 9507cec..dbfb7ca 100644
---- a/common/main.c
-+++ b/common/main.c
-@@ -355,7 +355,11 @@ void main_loop (void)
- #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
- s = getenv ("bootdelay");
- bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
--
-+#if defined(CONFIG_NANONOTE)
-+ DECLARE_GLOBAL_DATA_PTR;
-+ if (gd->boot_option & BOOT_WITH_ENABLE_UART)
-+ bootdelay = 3;
-+# endif
- debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);
-
- #if defined(CONFIG_MENU_SHOW)
-@@ -379,7 +383,20 @@ void main_loop (void)
- }
- else
- #endif /* CONFIG_BOOTCOUNT_LIMIT */
-- s = getenv ("bootcmd");
-+#if defined(CONFIG_NANONOTE)
-+ if (gd->boot_option & BOOT_FROM_MEMCARD)
-+ s = getenv ("bootcmdfromsd");
-+ else if (gd->boot_option & BOOT_WITH_F1)
-+ s = getenv ("bootcmdf1");
-+ else if (gd->boot_option & BOOT_WITH_F2)
-+ s = getenv ("bootcmdf2");
-+ else if (gd->boot_option & BOOT_WITH_F3)
-+ s = getenv ("bootcmdf3");
-+ else if (gd->boot_option & BOOT_WITH_F4)
-+ s = getenv ("bootcmdf4");
-+ else
-+#endif
-+ s = getenv ("bootcmd");
-
- debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");
-
-diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h
-index 7b33be0..52b370c 100644
---- a/include/configs/qi_lb60.h
-+++ b/include/configs/qi_lb60.h
-@@ -31,6 +31,7 @@
- /*
- * Miscellaneous configurable options
- */
-+#define CONFIG_NANONOTE
- #define CONFIG_JZ4740_MMC
- #define CONFIG_MMC 1
- #define CONFIG_FAT 1
-@@ -39,6 +40,37 @@
- #define CONFIG_CMD_FAT
- #define CONFIG_CMD_EXT2
-
-+#define CONFIG_CMD_UBIFS
-+#define CONFIG_CMD_UBI
-+#define CONFIG_MTD_PARTITIONS
-+#define CONFIG_MTD_DEVICE
-+#define CONFIG_CMD_MTDPARTS
-+#define CONFIG_CMD_UBI
-+#define CONFIG_CMD_UBIFS
-+#define CONFIG_LZO
-+#define CONFIG_RBTREE
-+
-+#define MTDIDS_DEFAULT "nand0=jz4740-nand"
-+#define MTDPARTS_DEFAULT "mtdparts=jz4740-nand:4M@0(uboot)ro,4M@4M(kernel)ro,512M@8M(rootfs)ro,-(data)ro"
-+
-+#define BOOT_FROM_MEMCARD 1
-+#define BOOT_WITH_ENABLE_UART (1 << 1) /* Vaule for global_data.h gd->boot_option */
-+#define BOOT_WITH_F1 (1 << 2)
-+#define BOOT_WITH_F2 (1 << 3)
-+#define BOOT_WITH_F3 (1 << 4)
-+#define BOOT_WITH_F4 (1 << 5)
-+
-+#define CONFIG_EXTRA_ENV_SETTINGS \
-+ "bootcmdfromsd=mmc init; ext2load mmc 0 0x80600000 /boot/uImage; bootm;\0" \
-+ "bootargsfromsd=mem=32M console=tty0 console=ttyS0,57600n8 rootfstype=ext2 root=/dev/mmcblk0p1 rw rootwait\0" \
-+ "bootcmdf1=mmc init; ext2load mmc 0:1 0x80600000 /boot/uImage; bootm;\0" \
-+ "bootargsf1=mem=32M console=tty0 console=ttyS0,57600n8 rootfstype=ext2 root=/dev/mmcblk0p1 rw rootwait\0" \
-+ "bootcmdf2=mmc init; ext2load mmc 0:2 0x80600000 /boot/uImage; bootm;\0" \
-+ "bootargsf2=mem=32M console=tty0 console=ttyS0,57600n8 rootfstype=ext2 root=/dev/mmcblk0p2 rw rootwait\0" \
-+ "bootcmdf3=mmc init; ext2load mmc 0:3 0x80600000 /boot/uImage; bootm;\0" \
-+ "bootargsf3=mem=32M console=tty0 console=ttyS0,57600n8 rootfstype=ext2 root=/dev/mmcblk0p3 rw rootwait\0" \
-+ "bootcmdf4=mtdparts default;ubi part rootfs;ubifsmount rootfs;ubifsload 0x80600000 /boot/uImage; bootm;\0" \
-+ "bootargsf4=mem=32M console=tty0 console=ttyS0,57600n8 ubi.mtd=2 rootfstype=ubifs root=ubi0:rootfs rw rootwait"
-
- #define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */
- #define CONFIG_SYS_INIT_SP_OFFSET 0x400000
---
-1.7.9.5
-
diff --git a/package/boot/uboot-xburst/patches/0005-add-nanonote-lcd-support.patch b/package/boot/uboot-xburst/patches/0005-add-nanonote-lcd-support.patch
deleted file mode 100644
index 2c550f7205..0000000000
--- a/package/boot/uboot-xburst/patches/0005-add-nanonote-lcd-support.patch
+++ /dev/null
@@ -1,847 +0,0 @@
-From ca8c5216cfd3ad3fda9867ed2d157ae5a209834b Mon Sep 17 00:00:00 2001
-From: Xiangfu <xiangfu@openmobilefree.net>
-Date: Wed, 10 Oct 2012 22:05:27 +0800
-Subject: [PATCH 5/6] add nanonote lcd support
-
----
- arch/mips/include/asm/global_data.h | 1 +
- arch/mips/include/asm/jz4740.h | 90 ++++++++
- arch/mips/lib/board.c | 6 +
- common/lcd.c | 9 +-
- drivers/video/Makefile | 1 +
- drivers/video/nanonote_gpm940b0.c | 400 +++++++++++++++++++++++++++++++++++
- drivers/video/nanonote_gpm940b0.h | 135 ++++++++++++
- include/configs/qi_lb60.h | 7 +
- include/lcd.h | 52 ++++-
- 9 files changed, 697 insertions(+), 4 deletions(-)
- create mode 100644 drivers/video/nanonote_gpm940b0.c
- create mode 100644 drivers/video/nanonote_gpm940b0.h
-
-diff --git a/arch/mips/include/asm/global_data.h b/arch/mips/include/asm/global_data.h
-index cd03d7e..7cec2de 100644
---- a/arch/mips/include/asm/global_data.h
-+++ b/arch/mips/include/asm/global_data.h
-@@ -44,6 +44,7 @@ typedef struct global_data {
- unsigned long per_clk; /* Peripheral bus clock */
- unsigned long mem_clk; /* Memory bus clock */
- unsigned long dev_clk; /* Device clock */
-+ unsigned long fb_base; /* base address of framebuffer */
- /* "static data" needed by most of timer.c */
- unsigned long tbl;
- unsigned long lastinc;
-diff --git a/arch/mips/include/asm/jz4740.h b/arch/mips/include/asm/jz4740.h
-index 68287fb..13724a2 100644
---- a/arch/mips/include/asm/jz4740.h
-+++ b/arch/mips/include/asm/jz4740.h
-@@ -1312,5 +1312,95 @@ do { \
- while (REG_MSC_STAT & MSC_STAT_IS_RESETTING); \
- } while (0)
-
-+/*************************************************************************
-+ * LCD (LCD Controller)
-+ *************************************************************************/
-+#define REG32(addr) *((volatile u32 *)(addr))
-+
-+#define CPM_BASE 0xB0000000
-+#define CPM_CPCCR (CPM_BASE+0x00)
-+#define REG_CPM_CPCCR REG32(CPM_CPCCR)
-+
-+#define LCD_BASE 0xB3050000
-+#define LCD_CFG (LCD_BASE + 0x00) /* LCD Configure Register */
-+#define LCD_VSYNC (LCD_BASE + 0x04) /* Vertical Synchronize Register */
-+#define LCD_HSYNC (LCD_BASE + 0x08) /* Horizontal Synchronize Register */
-+#define LCD_VAT (LCD_BASE + 0x0c) /* Virtual Area Setting Register */
-+#define LCD_DAH (LCD_BASE + 0x10) /* Display Area Horizontal Start/End Point */
-+#define LCD_DAV (LCD_BASE + 0x14) /* Display Area Vertical Start/End Point */
-+#define LCD_PS (LCD_BASE + 0x18) /* PS Signal Setting */
-+#define LCD_CLS (LCD_BASE + 0x1c) /* CLS Signal Setting */
-+#define LCD_SPL (LCD_BASE + 0x20) /* SPL Signal Setting */
-+#define LCD_REV (LCD_BASE + 0x24) /* REV Signal Setting */
-+#define LCD_CTRL (LCD_BASE + 0x30) /* LCD Control Register */
-+#define LCD_STATE (LCD_BASE + 0x34) /* LCD Status Register */
-+#define LCD_IID (LCD_BASE + 0x38) /* Interrupt ID Register */
-+#define LCD_DA0 (LCD_BASE + 0x40) /* Descriptor Address Register 0 */
-+#define LCD_SA0 (LCD_BASE + 0x44) /* Source Address Register 0 */
-+#define LCD_FID0 (LCD_BASE + 0x48) /* Frame ID Register 0 */
-+#define LCD_CMD0 (LCD_BASE + 0x4c) /* DMA Command Register 0 */
-+#define LCD_DA1 (LCD_BASE + 0x50) /* Descriptor Address Register 1 */
-+#define LCD_SA1 (LCD_BASE + 0x54) /* Source Address Register 1 */
-+#define LCD_FID1 (LCD_BASE + 0x58) /* Frame ID Register 1 */
-+#define LCD_CMD1 (LCD_BASE + 0x5c) /* DMA Command Register 1 */
-+
-+#define REG_LCD_CFG REG32(LCD_CFG)
-+#define REG_LCD_VSYNC REG32(LCD_VSYNC)
-+#define REG_LCD_HSYNC REG32(LCD_HSYNC)
-+#define REG_LCD_VAT REG32(LCD_VAT)
-+#define REG_LCD_DAH REG32(LCD_DAH)
-+#define REG_LCD_DAV REG32(LCD_DAV)
-+#define REG_LCD_PS REG32(LCD_PS)
-+#define REG_LCD_CLS REG32(LCD_CLS)
-+#define REG_LCD_SPL REG32(LCD_SPL)
-+#define REG_LCD_REV REG32(LCD_REV)
-+#define REG_LCD_CTRL REG32(LCD_CTRL)
-+#define REG_LCD_STATE REG32(LCD_STATE)
-+#define REG_LCD_IID REG32(LCD_IID)
-+#define REG_LCD_DA0 REG32(LCD_DA0)
-+#define REG_LCD_SA0 REG32(LCD_SA0)
-+#define REG_LCD_FID0 REG32(LCD_FID0)
-+#define REG_LCD_CMD0 REG32(LCD_CMD0)
-+#define REG_LCD_DA1 REG32(LCD_DA1)
-+#define REG_LCD_SA1 REG32(LCD_SA1)
-+#define REG_LCD_FID1 REG32(LCD_FID1)
-+#define REG_LCD_CMD1 REG32(LCD_CMD1)
-+
-+#define LCD_CTRL_BPP_BIT 0 /* Bits Per Pixel */
-+#define LCD_CTRL_BPP_MASK (0x07 << LCD_CTRL_BPP_BIT)
-+ #define LCD_CTRL_BPP_1 (0 << LCD_CTRL_BPP_BIT) /* 1 bpp */
-+ #define LCD_CTRL_BPP_2 (1 << LCD_CTRL_BPP_BIT) /* 2 bpp */
-+ #define LCD_CTRL_BPP_4 (2 << LCD_CTRL_BPP_BIT) /* 4 bpp */
-+ #define LCD_CTRL_BPP_8 (3 << LCD_CTRL_BPP_BIT) /* 8 bpp */
-+ #define LCD_CTRL_BPP_16 (4 << LCD_CTRL_BPP_BIT) /* 15/16 bpp */
-+ #define LCD_CTRL_BPP_18_24 (5 << LCD_CTRL_BPP_BIT) /* 18/24/32 bpp */
-+
-+#define LCD_CTRL_BST_BIT 28 /* Burst Length Selection */
-+#define LCD_CTRL_BST_MASK (0x03 << LCD_CTRL_BST_BIT)
-+ #define LCD_CTRL_BST_4 (0 << LCD_CTRL_BST_BIT) /* 4-word */
-+ #define LCD_CTRL_BST_8 (1 << LCD_CTRL_BST_BIT) /* 8-word */
-+ #define LCD_CTRL_BST_16 (2 << LCD_CTRL_BST_BIT) /* 16-word */
-+#define LCD_CTRL_RGB565 (0 << 27) /* RGB565 mode */
-+#define LCD_CTRL_RGB555 (1 << 27) /* RGB555 mode */
-+#define LCD_CTRL_OFUP (1 << 26) /* Output FIFO underrun protection enable */
-+#define LCD_CTRL_FRC_BIT 24 /* STN FRC Algorithm Selection */
-+#define LCD_CTRL_FRC_MASK (0x03 << LCD_CTRL_FRC_BIT)
-+ #define LCD_CTRL_FRC_16 (0 << LCD_CTRL_FRC_BIT) /* 16 grayscale */
-+ #define LCD_CTRL_FRC_4 (1 << LCD_CTRL_FRC_BIT) /* 4 grayscale */
-+ #define LCD_CTRL_FRC_2 (2 << LCD_CTRL_FRC_BIT) /* 2 grayscale */
-+
-+#define CPM_LPCDR (CPM_BASE+0x64)
-+#define CPM_CLKGR (CPM_BASE+0x20)
-+#define REG_CPM_LPCDR REG32(CPM_LPCDR)
-+#define REG_CPM_CLKGR REG32(CPM_CLKGR)
-+
-+#define __cpm_start_tcu() (REG_CPM_CLKGR &= ~CPM_CLKGR_TCU)
-+#define __cpm_stop_lcd() (REG_CPM_CLKGR |= CPM_CLKGR_LCD)
-+#define __cpm_set_pixdiv(v) \
-+ (REG_CPM_LPCDR = (REG_CPM_LPCDR & ~CPM_LPCDR_PIXDIV_MASK) | ((v) << (CPM_LPCDR_PIXDIV_BIT)))
-+#define __cpm_set_ldiv(v) \
-+ (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_LDIV_MASK) | ((v) << (CPM_CPCCR_LDIV_BIT)))
-+#define __cpm_start_lcd() (REG_CPM_CLKGR &= ~CPM_CLKGR_LCD)
-+
- #endif /* !__ASSEMBLY__ */
- #endif /* __JZ4740_H__ */
-diff --git a/arch/mips/lib/board.c b/arch/mips/lib/board.c
-index b14b33e..c2e64d9 100644
---- a/arch/mips/lib/board.c
-+++ b/arch/mips/lib/board.c
-@@ -172,6 +172,12 @@ void board_init_f(ulong bootflag)
- addr &= ~(4096 - 1);
- debug("Top of RAM usable for U-Boot at: %08lx\n", addr);
-
-+#ifdef CONFIG_LCD
-+ /* reserve memory for LCD display (always full pages) */
-+ addr = lcd_setmem (addr);
-+ gd->fb_base = addr;
-+#endif /* CONFIG_LCD */
-+
- /* Reserve memory for U-Boot code, data & bss
- * round down to next 16 kB limit
- */
-diff --git a/common/lcd.c b/common/lcd.c
-index b6be800..af1281a 100644
---- a/common/lcd.c
-+++ b/common/lcd.c
-@@ -263,6 +263,13 @@ static void lcd_drawchars(ushort x, ushort y, uchar *str, int count)
- lcd_color_fg : lcd_color_bg;
- bits <<= 1;
- }
-+#elif LCD_BPP == LCD_COLOR32
-+ uint *m = (uint *)d;
-+ for (c=0; c<32; ++c) {
-+ *m++ = (bits & 0x80) ?
-+ lcd_color_fg : lcd_color_bg;
-+ bits <<= 1;
-+ }
- #endif
- }
- #if LCD_BPP == LCD_MONOCHROME
-@@ -509,7 +516,7 @@ static inline ushort *configuration_get_cmap(void)
- return (ushort *)&(cp->lcd_cmap[255 * sizeof(ushort)]);
- #elif defined(CONFIG_ATMEL_LCD)
- return (ushort *)(panel_info.mmio + ATMEL_LCDC_LUT(0));
--#elif !defined(CONFIG_ATMEL_HLCD) && !defined(CONFIG_EXYNOS_FB)
-+#elif !defined(CONFIG_ATMEL_HLCD) && !defined(CONFIG_EXYNOS_FB) && !defined(CONFIG_VIDEO_GPM940B0)
- return panel_info.cmap;
- #else
- #if defined(CONFIG_LCD_LOGO)
-diff --git a/drivers/video/Makefile b/drivers/video/Makefile
-index ebb6da8..03625bc 100644
---- a/drivers/video/Makefile
-+++ b/drivers/video/Makefile
-@@ -50,6 +50,7 @@ COBJS-$(CONFIG_VIDEO_SED13806) += sed13806.o
- COBJS-$(CONFIG_VIDEO_SM501) += sm501.o
- COBJS-$(CONFIG_VIDEO_SMI_LYNXEM) += smiLynxEM.o videomodes.o
- COBJS-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o
-+COBJS-$(CONFIG_VIDEO_GPM940B0) += nanonote_gpm940b0.o
-
- COBJS := $(sort $(COBJS-y))
- SRCS := $(COBJS:.o=.c)
-diff --git a/drivers/video/nanonote_gpm940b0.c b/drivers/video/nanonote_gpm940b0.c
-new file mode 100644
-index 0000000..11efb72
---- /dev/null
-+++ b/drivers/video/nanonote_gpm940b0.c
-@@ -0,0 +1,400 @@
-+/*
-+ * JzRISC lcd controller
-+ *
-+ * Xiangfu Liu <xiangfu@sharism.cc>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation; either version 2 of
-+ * the License, or (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-+ * MA 02111-1307 USA
-+ */
-+
-+#include <config.h>
-+#include <common.h>
-+#include <lcd.h>
-+
-+#include <asm/io.h> /* virt_to_phys() */
-+#include <asm/jz4740.h>
-+
-+#include "nanonote_gpm940b0.h"
-+
-+#define align2(n) (n)=((((n)+1)>>1)<<1)
-+#define align4(n) (n)=((((n)+3)>>2)<<2)
-+#define align8(n) (n)=((((n)+7)>>3)<<3)
-+
-+struct jzfb_info {
-+ unsigned int cfg; /* panel mode and pin usage etc. */
-+ unsigned int w;
-+ unsigned int h;
-+ unsigned int bpp; /* bit per pixel */
-+ unsigned int fclk; /* frame clk */
-+ unsigned int hsw; /* hsync width, in pclk */
-+ unsigned int vsw; /* vsync width, in line count */
-+ unsigned int elw; /* end of line, in pclk */
-+ unsigned int blw; /* begin of line, in pclk */
-+ unsigned int efw; /* end of frame, in line count */
-+ unsigned int bfw; /* begin of frame, in line count */
-+};
-+
-+static struct jzfb_info jzfb = {
-+ MODE_8BIT_SERIAL_TFT | PCLK_N | HSYNC_N | VSYNC_N,
-+ 320, 240, 32, 70, 1, 1, 273, 140, 1, 20
-+};
-+
-+vidinfo_t panel_info = {
-+ 320, 240, LCD_BPP,
-+};
-+
-+void *lcd_base;
-+void *lcd_console_address;
-+int lcd_line_length;
-+int lcd_color_fg;
-+int lcd_color_bg;
-+short console_col;
-+short console_row;
-+
-+static int jz_lcd_init_mem(void *lcdbase, vidinfo_t *vid)
-+{
-+ u_long palette_mem_size;
-+ struct jz_fb_info *fbi = &vid->jz_fb;
-+ int fb_size = vid->vl_row * (vid->vl_col * NBITS (vid->vl_bpix)) / 8;
-+
-+ fbi->screen = (u_long)lcdbase;
-+ fbi->palette_size = 256;
-+ palette_mem_size = fbi->palette_size * sizeof(u16);
-+
-+ debug("jz_lcd.c palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size);
-+ /* locate palette and descs at end of page following fb */
-+ fbi->palette = (u_long)lcdbase + fb_size + PAGE_SIZE - palette_mem_size;
-+
-+ return 0;
-+}
-+
-+static void jz_lcd_desc_init(vidinfo_t *vid)
-+{
-+ struct jz_fb_info * fbi;
-+ fbi = &vid->jz_fb;
-+ fbi->dmadesc_fblow = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 3*16);
-+ fbi->dmadesc_fbhigh = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 2*16);
-+ fbi->dmadesc_palette = (struct jz_fb_dma_descriptor *)((unsigned int)fbi->palette - 1*16);
-+
-+ #define BYTES_PER_PANEL (vid->vl_col * vid->vl_row * NBITS(vid->vl_bpix) / 8)
-+
-+ /* populate descriptors */
-+ fbi->dmadesc_fblow->fdadr = virt_to_phys(fbi->dmadesc_fblow);
-+ fbi->dmadesc_fblow->fsadr = virt_to_phys((void *)(fbi->screen + BYTES_PER_PANEL));
-+ fbi->dmadesc_fblow->fidr = 0;
-+ fbi->dmadesc_fblow->ldcmd = BYTES_PER_PANEL / 4 ;
-+
-+ fbi->fdadr1 = virt_to_phys(fbi->dmadesc_fblow); /* only used in dual-panel mode */
-+
-+ fbi->dmadesc_fbhigh->fsadr = virt_to_phys((void *)fbi->screen);
-+ fbi->dmadesc_fbhigh->fidr = 0;
-+ fbi->dmadesc_fbhigh->ldcmd = BYTES_PER_PANEL / 4; /* length in word */
-+
-+ fbi->dmadesc_palette->fsadr = virt_to_phys((void *)fbi->palette);
-+ fbi->dmadesc_palette->fidr = 0;
-+ fbi->dmadesc_palette->ldcmd = (fbi->palette_size * 2)/4 | (1<<28);
-+
-+ if(NBITS(vid->vl_bpix) < 12) {
-+ /* assume any mode with <12 bpp is palette driven */
-+ fbi->dmadesc_palette->fdadr = virt_to_phys(fbi->dmadesc_fbhigh);
-+ fbi->dmadesc_fbhigh->fdadr = virt_to_phys(fbi->dmadesc_palette);
-+ /* flips back and forth between pal and fbhigh */
-+ fbi->fdadr0 = virt_to_phys(fbi->dmadesc_palette);
-+ } else {
-+ /* palette shouldn't be loaded in true-color mode */
-+ fbi->dmadesc_fbhigh->fdadr = virt_to_phys((void *)fbi->dmadesc_fbhigh);
-+ fbi->fdadr0 = virt_to_phys(fbi->dmadesc_fbhigh); /* no pal just fbhigh */
-+ }
-+}
-+
-+static int jz_lcd_hw_init(vidinfo_t *vid)
-+{
-+ struct jz_fb_info *fbi = &vid->jz_fb;
-+ unsigned int val = 0;
-+ unsigned int pclk;
-+ unsigned int stnH;
-+ int pll_div;
-+
-+ /* Setting Control register */
-+ switch (jzfb.bpp) {
-+ case 1:
-+ val |= LCD_CTRL_BPP_1;
-+ break;
-+ case 2:
-+ val |= LCD_CTRL_BPP_2;
-+ break;
-+ case 4:
-+ val |= LCD_CTRL_BPP_4;
-+ break;
-+ case 8:
-+ val |= LCD_CTRL_BPP_8;
-+ break;
-+ case 15:
-+ val |= LCD_CTRL_RGB555;
-+ case 16:
-+ val |= LCD_CTRL_BPP_16;
-+ break;
-+ case 17 ... 32:
-+ val |= LCD_CTRL_BPP_18_24; /* target is 4bytes/pixel */
-+ break;
-+
-+ default:
-+ printf("jz_lcd.c The BPP %d is not supported\n", jzfb.bpp);
-+ val |= LCD_CTRL_BPP_16;
-+ break;
-+ }
-+
-+ switch (jzfb.cfg & MODE_MASK) {
-+ case MODE_STN_MONO_DUAL:
-+ case MODE_STN_COLOR_DUAL:
-+ case MODE_STN_MONO_SINGLE:
-+ case MODE_STN_COLOR_SINGLE:
-+ switch (jzfb.bpp) {
-+ case 1:
-+ /* val |= LCD_CTRL_PEDN; */
-+ case 2:
-+ val |= LCD_CTRL_FRC_2;
-+ break;
-+ case 4:
-+ val |= LCD_CTRL_FRC_4;
-+ break;
-+ case 8:
-+ default:
-+ val |= LCD_CTRL_FRC_16;
-+ break;
-+ }
-+ break;
-+ }
-+
-+ val |= LCD_CTRL_BST_16; /* Burst Length is 16WORD=64Byte */
-+ val |= LCD_CTRL_OFUP; /* OutFIFO underrun protect */
-+
-+ switch (jzfb.cfg & MODE_MASK) {
-+ case MODE_STN_MONO_DUAL:
-+ case MODE_STN_COLOR_DUAL:
-+ case MODE_STN_MONO_SINGLE:
-+ case MODE_STN_COLOR_SINGLE:
-+ switch (jzfb.cfg & STN_DAT_PINMASK) {
-+ case STN_DAT_PIN1:
-+ /* Do not adjust the hori-param value. */
-+ break;
-+ case STN_DAT_PIN2:
-+ align2(jzfb.hsw);
-+ align2(jzfb.elw);
-+ align2(jzfb.blw);
-+ break;
-+ case STN_DAT_PIN4:
-+ align4(jzfb.hsw);
-+ align4(jzfb.elw);
-+ align4(jzfb.blw);
-+ break;
-+ case STN_DAT_PIN8:
-+ align8(jzfb.hsw);
-+ align8(jzfb.elw);
-+ align8(jzfb.blw);
-+ break;
-+ }
-+ break;
-+ }
-+
-+ REG_LCD_CTRL = val;
-+
-+ switch (jzfb.cfg & MODE_MASK) {
-+ case MODE_STN_MONO_DUAL:
-+ case MODE_STN_COLOR_DUAL:
-+ case MODE_STN_MONO_SINGLE:
-+ case MODE_STN_COLOR_SINGLE:
-+ if (((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL) ||
-+ ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL))
-+ stnH = jzfb.h >> 1;
-+ else
-+ stnH = jzfb.h;
-+
-+ REG_LCD_VSYNC = (0 << 16) | jzfb.vsw;
-+ REG_LCD_HSYNC = ((jzfb.blw+jzfb.w) << 16) | (jzfb.blw+jzfb.w+jzfb.hsw);
-+
-+ /* Screen setting */
-+ REG_LCD_VAT = ((jzfb.blw + jzfb.w + jzfb.hsw + jzfb.elw) << 16) | (stnH + jzfb.vsw + jzfb.bfw + jzfb.efw);
-+ REG_LCD_DAH = (jzfb.blw << 16) | (jzfb.blw + jzfb.w);
-+ REG_LCD_DAV = (0 << 16) | (stnH);
-+
-+ /* AC BIAs signal */
-+ REG_LCD_PS = (0 << 16) | (stnH+jzfb.vsw+jzfb.efw+jzfb.bfw);
-+
-+ break;
-+
-+ case MODE_TFT_GEN:
-+ case MODE_TFT_SHARP:
-+ case MODE_TFT_CASIO:
-+ case MODE_TFT_SAMSUNG:
-+ case MODE_8BIT_SERIAL_TFT:
-+ case MODE_TFT_18BIT:
-+ REG_LCD_VSYNC = (0 << 16) | jzfb.vsw;
-+ REG_LCD_HSYNC = (0 << 16) | jzfb.hsw;
-+ REG_LCD_DAV =((jzfb.vsw+jzfb.bfw) << 16) | (jzfb.vsw +jzfb.bfw+jzfb.h);
-+ REG_LCD_DAH = ((jzfb.hsw + jzfb.blw) << 16) | (jzfb.hsw + jzfb.blw + jzfb.w );
-+ REG_LCD_VAT = (((jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw)) << 16) \
-+ | (jzfb.vsw + jzfb.bfw + jzfb.h + jzfb.efw);
-+ break;
-+ }
-+
-+ switch (jzfb.cfg & MODE_MASK) {
-+ case MODE_TFT_SAMSUNG:
-+ {
-+ unsigned int total, tp_s, tp_e, ckv_s, ckv_e;
-+ unsigned int rev_s, rev_e, inv_s, inv_e;
-+
-+ pclk = val * (jzfb.w + jzfb.hsw + jzfb.elw + jzfb.blw) *
-+ (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */
-+
-+ total = jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw;
-+ tp_s = jzfb.blw + jzfb.w + 1;
-+ tp_e = tp_s + 1;
-+ ckv_s = tp_s - pclk/(1000000000/4100);
-+ ckv_e = tp_s + total;
-+ rev_s = tp_s - 11; /* -11.5 clk */
-+ rev_e = rev_s + total;
-+ inv_s = tp_s;
-+ inv_e = inv_s + total;
-+ REG_LCD_CLS = (tp_s << 16) | tp_e;
-+ REG_LCD_PS = (ckv_s << 16) | ckv_e;
-+ REG_LCD_SPL = (rev_s << 16) | rev_e;
-+ REG_LCD_REV = (inv_s << 16) | inv_e;
-+ jzfb.cfg |= STFT_REVHI | STFT_SPLHI;
-+ break;
-+ }
-+ case MODE_TFT_SHARP:
-+ {
-+ unsigned int total, cls_s, cls_e, ps_s, ps_e;
-+ unsigned int spl_s, spl_e, rev_s, rev_e;
-+ total = jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw;
-+ spl_s = 1;
-+ spl_e = spl_s + 1;
-+ cls_s = 0;
-+ cls_e = total - 60; /* > 4us (pclk = 80ns) */
-+ ps_s = cls_s;
-+ ps_e = cls_e;
-+ rev_s = total - 40; /* > 3us (pclk = 80ns) */
-+ rev_e = rev_s + total;
-+ jzfb.cfg |= STFT_PSHI;
-+ REG_LCD_SPL = (spl_s << 16) | spl_e;
-+ REG_LCD_CLS = (cls_s << 16) | cls_e;
-+ REG_LCD_PS = (ps_s << 16) | ps_e;
-+ REG_LCD_REV = (rev_s << 16) | rev_e;
-+ break;
-+ }
-+ case MODE_TFT_CASIO:
-+ break;
-+ }
-+
-+ /* Configure the LCD panel */
-+ REG_LCD_CFG = jzfb.cfg;
-+
-+ /* Timing setting */
-+ __cpm_stop_lcd();
-+
-+ val = jzfb.fclk; /* frame clk */
-+ if ( (jzfb.cfg & MODE_MASK) != MODE_8BIT_SERIAL_TFT) {
-+ pclk = val * (jzfb.w + jzfb.hsw + jzfb.elw + jzfb.blw) *
-+ (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */
-+ } else {
-+ /* serial mode: Hsync period = 3*Width_Pixel */
-+ pclk = val * (jzfb.w*3 + jzfb.hsw + jzfb.elw + jzfb.blw) *
-+ (jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */
-+ }
-+
-+ if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_SINGLE) ||
-+ ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL))
-+ pclk = (pclk * 3);
-+
-+ if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_SINGLE) ||
-+ ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||
-+ ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_SINGLE) ||
-+ ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))
-+ pclk = pclk >> ((jzfb.cfg & STN_DAT_PINMASK) >> 4);
-+
-+ if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||
-+ ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))
-+ pclk >>= 1;
-+
-+ pll_div = (REG_CPM_CPCCR & CPM_CPCCR_PCS); /* clock source,0:pllout/2 1: pllout */
-+ pll_div = pll_div ? 1 : 2;
-+ val = (__cpm_get_pllout() / pll_div) / pclk;
-+ val--;
-+ if (val > 0x1ff) {
-+ printf("CPM_LPCDR too large, set it to 0x1ff\n");
-+ val = 0x1ff;
-+ }
-+ __cpm_set_pixdiv(val);
-+
-+ val = pclk * 3 ; /* LCDClock > 2.5*Pixclock */
-+ if (val > 150000000) {
-+ printf("Warning: LCDClock=%d\n, LCDClock must less or equal to 150MHz.\n", val);
-+ printf("Change LCDClock to 150MHz\n");
-+ val = 150000000;
-+ }
-+ val = (__cpm_get_pllout() / pll_div) / val;
-+ val--;
-+ if (val > 0x1f) {
-+ printf("CPM_CPCCR.LDIV too large, set it to 0x1f\n");
-+ val = 0x1f;
-+ }
-+ __cpm_set_ldiv( val );
-+ REG_CPM_CPCCR |= CPM_CPCCR_CE ; /* update divide */
-+
-+ __cpm_start_lcd();
-+ udelay(1000);
-+
-+ REG_LCD_DA0 = fbi->fdadr0; /* frame descripter*/
-+
-+ if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||
-+ ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))
-+ REG_LCD_DA1 = fbi->fdadr1; /* frame descripter*/
-+
-+ return 0;
-+}
-+
-+void lcd_ctrl_init (void *lcdbase)
-+{
-+ __lcd_display_pin_init();
-+ __lcd_display_on() ;
-+
-+ jz_lcd_init_mem(lcdbase, &panel_info);
-+ jz_lcd_desc_init(&panel_info);
-+ jz_lcd_hw_init(&panel_info);
-+
-+}
-+
-+/*
-+ * Before enabled lcd controller, lcd registers should be configured correctly.
-+ */
-+void lcd_enable (void)
-+{
-+ REG_LCD_CTRL &= ~(1<<4); /* LCDCTRL.DIS */
-+ REG_LCD_CTRL |= 1<<3; /* LCDCTRL.ENA*/
-+}
-+
-+void lcd_disable (void)
-+{
-+ REG_LCD_CTRL |= (1<<4);
-+}
-+
-+void lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue)
-+{
-+}
-+
-+void lcd_initcolregs (void)
-+{
-+}
-diff --git a/drivers/video/nanonote_gpm940b0.h b/drivers/video/nanonote_gpm940b0.h
-new file mode 100644
-index 0000000..efe491e
---- /dev/null
-+++ b/drivers/video/nanonote_gpm940b0.h
-@@ -0,0 +1,135 @@
-+/*
-+ * JzRISC lcd controller
-+ *
-+ * Xiangfu Liu <xiangfu@sharism.cc>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation; either version 2 of
-+ * the License, or (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-+ * MA 02111-1307 USA
-+ */
-+
-+#ifndef __QI_LB60_GPM940B0_H__
-+#define __QI_LB60_GPM940B0_H__
-+
-+struct lcd_desc{
-+ unsigned int next_desc; /* LCDDAx */
-+ unsigned int databuf; /* LCDSAx */
-+ unsigned int frame_id; /* LCDFIDx */
-+ unsigned int cmd; /* LCDCMDx */
-+};
-+
-+#define MODE_MASK 0x0f
-+#define MODE_TFT_GEN 0x00
-+#define MODE_TFT_SHARP 0x01
-+#define MODE_TFT_CASIO 0x02
-+#define MODE_TFT_SAMSUNG 0x03
-+#define MODE_CCIR656_NONINT 0x04
-+#define MODE_CCIR656_INT 0x05
-+#define MODE_STN_COLOR_SINGLE 0x08
-+#define MODE_STN_MONO_SINGLE 0x09
-+#define MODE_STN_COLOR_DUAL 0x0a
-+#define MODE_STN_MONO_DUAL 0x0b
-+#define MODE_8BIT_SERIAL_TFT 0x0c
-+
-+#define MODE_TFT_18BIT (1<<7)
-+
-+#define STN_DAT_PIN1 (0x00 << 4)
-+#define STN_DAT_PIN2 (0x01 << 4)
-+#define STN_DAT_PIN4 (0x02 << 4)
-+#define STN_DAT_PIN8 (0x03 << 4)
-+#define STN_DAT_PINMASK STN_DAT_PIN8
-+
-+#define STFT_PSHI (1 << 15)
-+#define STFT_CLSHI (1 << 14)
-+#define STFT_SPLHI (1 << 13)
-+#define STFT_REVHI (1 << 12)
-+
-+#define SYNC_MASTER (0 << 16)
-+#define SYNC_SLAVE (1 << 16)
-+
-+#define DE_P (0 << 9)
-+#define DE_N (1 << 9)
-+
-+#define PCLK_P (0 << 10)
-+#define PCLK_N (1 << 10)
-+
-+#define HSYNC_P (0 << 11)
-+#define HSYNC_N (1 << 11)
-+
-+#define VSYNC_P (0 << 8)
-+#define VSYNC_N (1 << 8)
-+
-+#define DATA_NORMAL (0 << 17)
-+#define DATA_INVERSE (1 << 17)
-+
-+
-+/* Jz LCDFB supported I/O controls. */
-+#define FBIOSETBACKLIGHT 0x4688
-+#define FBIODISPON 0x4689
-+#define FBIODISPOFF 0x468a
-+#define FBIORESET 0x468b
-+#define FBIOPRINT_REG 0x468c
-+
-+/*
-+ * LCD panel specific definition
-+ */
-+#define MODE (0xc9) /* 8bit serial RGB */
-+
-+#define __spi_write_reg1(reg, val) \
-+do { \
-+ unsigned char no; \
-+ unsigned short value; \
-+ unsigned char a=reg; \
-+ unsigned char b=val; \
-+ __gpio_set_pin(SPEN); \
-+ __gpio_set_pin(SPCK); \
-+ __gpio_clear_pin(SPDA); \
-+ __gpio_clear_pin(SPEN); \
-+ value=((a<<8)|(b&0xFF)); \
-+ for(no=0;no<16;no++) \
-+ { \
-+ __gpio_clear_pin(SPCK); \
-+ if((value&0x8000)==0x8000) \
-+ __gpio_set_pin(SPDA); \
-+ else \
-+ __gpio_clear_pin(SPDA); \
-+ __gpio_set_pin(SPCK); \
-+ value=(value<<1); \
-+ } \
-+ __gpio_set_pin(SPEN); \
-+} while (0)
-+
-+#define __lcd_display_pin_init() \
-+do { \
-+ __cpm_start_tcu(); \
-+ __gpio_as_output(SPEN); /* use SPDA */ \
-+ __gpio_as_output(SPCK); /* use SPCK */ \
-+ __gpio_as_output(SPDA); /* use SPDA */ \
-+} while (0)
-+
-+#define __lcd_display_on() \
-+do { \
-+ __spi_write_reg1(0x05, 0x1e); \
-+ __spi_write_reg1(0x05, 0x5e); \
-+ __spi_write_reg1(0x07, 0x8d); \
-+ __spi_write_reg1(0x13, 0x01); \
-+ __spi_write_reg1(0x05, 0x5f); \
-+} while (0)
-+
-+#define __lcd_display_off() \
-+do { \
-+ __spi_write_reg1(0x05, 0x5e); \
-+} while (0)
-+
-+#endif /* __QI_LB60_GPM940B0_H__ */
-diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h
-index 52b370c..d3e78ad 100644
---- a/include/configs/qi_lb60.h
-+++ b/include/configs/qi_lb60.h
-@@ -32,6 +32,13 @@
- * Miscellaneous configurable options
- */
- #define CONFIG_NANONOTE
-+
-+#define CONFIG_LCD
-+#define CONFIG_SYS_WHITE_ON_BLACK
-+#define LCD_BPP LCD_COLOR32
-+#define CONFIG_VIDEO_GPM940B0
-+
-+
- #define CONFIG_JZ4740_MMC
- #define CONFIG_MMC 1
- #define CONFIG_FAT 1
-diff --git a/include/lcd.h b/include/lcd.h
-index 42070d7..6de5482 100644
---- a/include/lcd.h
-+++ b/include/lcd.h
-@@ -263,8 +263,44 @@ typedef struct vidinfo {
-
- void init_panel_info(vidinfo_t *vid);
-
--#else
-+#elif defined(CONFIG_JZSOC)
-+/*
-+ * LCD controller stucture for JZSOC: JZ4740
-+ */
-+struct jz_fb_dma_descriptor {
-+ u_long fdadr; /* Frame descriptor address register */
-+ u_long fsadr; /* Frame source address register */
-+ u_long fidr; /* Frame ID register */
-+ u_long ldcmd; /* Command register */
-+};
-+
-+/*
-+ * Jz LCD info
-+ */
-+struct jz_fb_info {
-+
-+ u_long fdadr0; /* physical address of frame/palette descriptor */
-+ u_long fdadr1; /* physical address of frame descriptor */
-+
-+ /* DMA descriptors */
-+ struct jz_fb_dma_descriptor * dmadesc_fblow;
-+ struct jz_fb_dma_descriptor * dmadesc_fbhigh;
-+ struct jz_fb_dma_descriptor * dmadesc_palette;
-+ u_long screen; /* address of frame buffer */
-+ u_long palette; /* address of palette memory */
-+ u_int palette_size;
-+};
-+typedef struct vidinfo {
-+ ushort vl_col; /* Number of columns (i.e. 640) */
-+ ushort vl_row; /* Number of rows (i.e. 480) */
-+ u_char vl_bpix; /* Bits per pixel, 0 = 1, 1 = 2, 2 = 4, 3 = 8 */
-+
-+ struct jz_fb_info jz_fb;
-+} vidinfo_t;
-+
-+extern vidinfo_t panel_info;
-
-+#else
- typedef struct vidinfo {
- ushort vl_col; /* Number of columns (i.e. 160) */
- ushort vl_row; /* Number of rows (i.e. 100) */
-@@ -318,6 +354,7 @@ void lcd_show_board_info(void);
- #define LCD_COLOR4 2
- #define LCD_COLOR8 3
- #define LCD_COLOR16 4
-+#define LCD_COLOR32 5
-
- /*----------------------------------------------------------------------*/
- #if defined(CONFIG_LCD_INFO_BELOW_LOGO)
-@@ -369,7 +406,7 @@ void lcd_show_board_info(void);
- # define CONSOLE_COLOR_GREY 14
- # define CONSOLE_COLOR_WHITE 15 /* Must remain last / highest */
-
--#else
-+#elif LCD_BPP == LCD_COLOR16
-
- /*
- * 16bpp color definitions
-@@ -377,6 +414,15 @@ void lcd_show_board_info(void);
- # define CONSOLE_COLOR_BLACK 0x0000
- # define CONSOLE_COLOR_WHITE 0xffff /* Must remain last / highest */
-
-+#elif LCD_BPP == LCD_COLOR32
-+/*
-+ * 18,24,32 bpp color definitions
-+ */
-+# define CONSOLE_COLOR_BLACK 0x00000000
-+# define CONSOLE_COLOR_WHITE 0xffffffff /* Must remain last / highest */
-+
-+#else
-+
- #endif /* color definitions */
-
- /************************************************************************/
-@@ -406,7 +452,7 @@ void lcd_show_board_info(void);
- #if LCD_BPP == LCD_MONOCHROME
- # define COLOR_MASK(c) ((c) | (c) << 1 | (c) << 2 | (c) << 3 | \
- (c) << 4 | (c) << 5 | (c) << 6 | (c) << 7)
--#elif (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16)
-+#elif (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16) || (LCD_BPP == LCD_COLOR32)
- # define COLOR_MASK(c) (c)
- #else
- # error Unsupported LCD BPP.
---
-1.7.9.5
-
diff --git a/package/boot/uboot-xburst/patches/0006-enable-silent-console.patch b/package/boot/uboot-xburst/patches/0006-enable-silent-console.patch
deleted file mode 100644
index ebd6a6a7bf..0000000000
--- a/package/boot/uboot-xburst/patches/0006-enable-silent-console.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From 5eb4d4c598f2806bd1b3d1140e917bfead7851ad Mon Sep 17 00:00:00 2001
-From: Xiangfu <xiangfu@openmobilefree.net>
-Date: Wed, 10 Oct 2012 23:51:26 +0800
-Subject: [PATCH 6/6] enable silent console
-
----
- common/console.c | 16 ++++++++++++++++
- include/configs/qi_lb60.h | 2 ++
- 2 files changed, 18 insertions(+)
-
-diff --git a/common/console.c b/common/console.c
-index 1177f7d..e8a2078 100644
---- a/common/console.c
-+++ b/common/console.c
-@@ -685,6 +685,14 @@ done:
-
- gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
-
-+#ifdef CONFIG_SILENT_CONSOLE
-+ /* Check one more time the contents of the silent environment
-+ * variable, because if the environment is loaded from NAND it was
-+ * not available when console_init_f() was called */
-+ if (getenv("silent") != NULL)
-+ gd->flags |= GD_FLG_SILENT;
-+#endif
-+
- stdio_print_current_devices();
-
- #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE
-@@ -760,6 +768,14 @@ int console_init_r(void)
-
- gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */
-
-+#ifdef CONFIG_SILENT_CONSOLE
-+ /* Check one more time the contents of the silent environment
-+ * variable, because if the environment is loaded from NAND it was
-+ * not available when console_init_f() was called */
-+ if (getenv("silent") != NULL)
-+ gd->flags |= GD_FLG_SILENT;
-+#endif
-+
- stdio_print_current_devices();
-
- /* Setting environment variables */
-diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h
-index d3e78ad..a3534ff 100644
---- a/include/configs/qi_lb60.h
-+++ b/include/configs/qi_lb60.h
-@@ -102,6 +102,8 @@
- #define CONFIG_SYS_NO_FLASH
- #define CONFIG_SYS_FLASH_BASE 0 /* init flash_base as 0 */
-
-+#define CONFIG_SILENT_CONSOLE 1 /* Enable silent console */
-+
- /*
- * Command line configuration
- */
---
-1.7.9.5
-