+++ /dev/null
-#
-# 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))) \
-)
+++ /dev/null
-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
-
+++ /dev/null
-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
-
+++ /dev/null
-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
-
+++ /dev/null
-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
-
+++ /dev/null
-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
-
+++ /dev/null
-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
-
+++ /dev/null
-#
-# Copyright (C) 2009-2011 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-include $(TOPDIR)/rules.mk
-
-ARCH:=mipsel
-BOARD:=xburst
-BOARDNAME:=Ingenic XBurst
-FEATURES:=targz nand ubifs audio source-only
-SUBTARGETS:=qi_lb60
-
-KERNEL_PATCHVER:=3.18
-
-DEVICE_TYPE:=other
-
-define Target/Description
- Build firmware images for XBurst JZ47x0 based boards.
-endef
-
-include $(INCLUDE_DIR)/target.mk
-
-$(eval $(call BuildTarget))
+++ /dev/null
-#!/bin/sh
-
-. /lib/functions/uci-defaults.sh
-
-board_config_update
-
-ucidef_set_hostname "BenNanoNote"
-ucidef_set_ntpserver
-
-board_config_flush
-
-exit 0
+++ /dev/null
-config mount
- option target /card
- option device /dev/mmcblk0p1
- option fstype auto
- option options rw,sync
- option enabled 1
+++ /dev/null
-# Copyright (C) 2006 OpenWrt.org
-
-config interface loopback
- option ifname lo
- option proto static
- option ipaddr 127.0.0.1
- option netmask 255.0.0.0
-
-config interface lan
- option ifname usb0
- option proto static
- option ipaddr 192.168.1.1
- option netmask 255.255.255.0
+++ /dev/null
-CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
-CONFIG_ARCH_DISCARD_MEMBLOCK=y
-CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
-# CONFIG_ARCH_HAS_SG_CHAIN is not set
-CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
-CONFIG_ARCH_REQUIRE_GPIOLIB=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
-# CONFIG_BACKLIGHT_ADP8860 is not set
-# CONFIG_BACKLIGHT_ADP8870 is not set
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_BACKLIGHT_GENERIC is not set
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-# CONFIG_BACKLIGHT_PWM is not set
-CONFIG_BATTERY_JZ4740=y
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_CHARGER_GPIO=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CONFIGFS_FS=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_CPU_GENERIC_DUMP_TLB=y
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_MIPS32=y
-CONFIG_CPU_MIPS32_R1=y
-CONFIG_CPU_MIPSR1=y
-CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
-CONFIG_CPU_R4K_CACHE_TLB=y
-CONFIG_CPU_R4K_FPU=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_HASH2=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_WORKQUEUE=y
-CONFIG_DMADEVICES=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_JZ4740=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_VIRTUAL_CHANNELS=y
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_DW_DMAC_CORE is not set
-CONFIG_EARLY_PRINTK=y
-CONFIG_ENABLE_MUST_CHECK=y
-CONFIG_EXT4_FS=y
-CONFIG_FAT_FS=y
-CONFIG_FB=y
-CONFIG_FB_CMDLINE=y
-CONFIG_FB_JZ4740=y
-CONFIG_FB_SYS_COPYAREA=y
-CONFIG_FB_SYS_FILLRECT=y
-CONFIG_FB_SYS_IMAGEBLIT=y
-CONFIG_FONTS=y
-# CONFIG_FONT_10x18 is not set
-# CONFIG_FONT_6x10 is not set
-CONFIG_FONT_6x11=y
-# CONFIG_FONT_7x14 is not set
-# CONFIG_FONT_8x16 is not set
-# CONFIG_FONT_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-# CONFIG_FONT_MINI_4x6 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_SUN12x22 is not set
-# CONFIG_FONT_SUN8x16 is not set
-CONFIG_FONT_SUPPORT=y
-CONFIG_FORCE_MAX_ZONEORDER=12
-CONFIG_FRAMEBUFFER_CONSOLE=y
-# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
-# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
-CONFIG_FREEZER=y
-CONFIG_FS_MBCACHE=y
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_GENERIC_IO=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_DEVRES=y
-CONFIG_HARDWARE_WATCHPOINTS=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
-CONFIG_HAVE_ARCH_JUMP_LABEL=y
-CONFIG_HAVE_ARCH_KGDB=y
-CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
-CONFIG_HAVE_ARCH_TRACEHOOK=y
-# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
-CONFIG_HAVE_BPF_JIT=y
-CONFIG_HAVE_CC_STACKPROTECTOR=y
-CONFIG_HAVE_CLK=y
-CONFIG_HAVE_CONTEXT_TRACKING=y
-CONFIG_HAVE_C_RECORDMCOUNT=y
-CONFIG_HAVE_DEBUG_KMEMLEAK=y
-CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
-CONFIG_HAVE_DMA_API_DEBUG=y
-CONFIG_HAVE_DMA_ATTRS=y
-CONFIG_HAVE_DMA_CONTIGUOUS=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_GENERIC_DMA_COHERENT=y
-CONFIG_HAVE_IDE=y
-CONFIG_HAVE_KERNEL_BZIP2=y
-CONFIG_HAVE_KERNEL_GZIP=y
-CONFIG_HAVE_KERNEL_LZ4=y
-CONFIG_HAVE_KERNEL_LZMA=y
-CONFIG_HAVE_KERNEL_LZO=y
-CONFIG_HAVE_KERNEL_XZ=y
-CONFIG_HAVE_MEMBLOCK=y
-CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
-CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
-CONFIG_HAVE_NET_DSA=y
-CONFIG_HAVE_OPROFILE=y
-CONFIG_HAVE_PERF_EVENTS=y
-CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
-CONFIG_HW_CONSOLE=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_INPUT=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_INPUT_MATRIXKMAP=y
-CONFIG_INPUT_MOUSE=y
-CONFIG_INPUT_MOUSEDEV=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-CONFIG_INPUT_PWM_BEEPER=y
-CONFIG_INPUT_UINPUT=y
-CONFIG_IRQ_CPU=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_JBD2=y
-CONFIG_JZ4740_QI_LB60=y
-CONFIG_KALLSYMS=y
-CONFIG_KEXEC=y
-CONFIG_KEYBOARD_GPIO=y
-CONFIG_KEYBOARD_MATRIX=y
-# CONFIG_LCD_AMS369FG06 is not set
-CONFIG_LCD_CLASS_DEVICE=y
-CONFIG_LCD_ILI8960=y
-# CONFIG_LCD_L4F00242T03 is not set
-# CONFIG_LCD_LD9040 is not set
-# CONFIG_LCD_LMS283GF05 is not set
-# CONFIG_LCD_LTV350QV is not set
-# CONFIG_LCD_PLATFORM is not set
-# CONFIG_LCD_S6E63M0 is not set
-# CONFIG_LCD_TDO24M is not set
-# CONFIG_LCD_VGG2432A4 is not set
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=2
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MACH_JZ4740=y
-CONFIG_MFD_CORE=y
-CONFIG_MFD_JZ4740_ADC=y
-CONFIG_MIPS=y
-# CONFIG_MIPS_HUGE_TLB_SUPPORT is not set
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_MIPS_MACHINE is not set
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-# CONFIG_MMC_BLOCK_BOUNCE is not set
-CONFIG_MMC_JZ4740=y
-CONFIG_MODULES_USE_ELF_REL=y
-# CONFIG_MOUSE_BCM5974 is not set
-# CONFIG_MOUSE_CYAPA is not set
-# CONFIG_MOUSE_PS2 is not set
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_MTD_CFI is not set
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_JZ4740=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-# CONFIG_MTD_UBI_BLOCK is not set
-# CONFIG_MTD_UBI_FASTMAP is not set
-# CONFIG_MTD_UBI_GLUEBI is not set
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_MUSB_PIO_ONLY=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_NLS=y
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_CODEPAGE_1250=y
-CONFIG_NLS_CODEPAGE_1251=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_737=y
-CONFIG_NLS_CODEPAGE_775=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_CODEPAGE_852=y
-CONFIG_NLS_CODEPAGE_855=y
-CONFIG_NLS_CODEPAGE_857=y
-CONFIG_NLS_CODEPAGE_860=y
-CONFIG_NLS_CODEPAGE_861=y
-CONFIG_NLS_CODEPAGE_862=y
-CONFIG_NLS_CODEPAGE_863=y
-CONFIG_NLS_CODEPAGE_864=y
-CONFIG_NLS_CODEPAGE_865=y
-CONFIG_NLS_CODEPAGE_866=y
-CONFIG_NLS_CODEPAGE_869=y
-CONFIG_NLS_CODEPAGE_874=y
-CONFIG_NLS_CODEPAGE_932=y
-CONFIG_NLS_CODEPAGE_936=y
-CONFIG_NLS_CODEPAGE_949=y
-CONFIG_NLS_CODEPAGE_950=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_13=y
-CONFIG_NLS_ISO8859_14=y
-CONFIG_NLS_ISO8859_15=y
-CONFIG_NLS_ISO8859_2=y
-CONFIG_NLS_ISO8859_3=y
-CONFIG_NLS_ISO8859_4=y
-CONFIG_NLS_ISO8859_5=y
-CONFIG_NLS_ISO8859_6=y
-CONFIG_NLS_ISO8859_7=y
-CONFIG_NLS_ISO8859_8=y
-CONFIG_NLS_ISO8859_9=y
-CONFIG_NLS_KOI8_R=y
-CONFIG_NLS_KOI8_U=y
-CONFIG_NLS_UTF8=y
-CONFIG_NOP_USB_XCEIV=y
-# CONFIG_NO_IOPORT_MAP is not set
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PM=y
-CONFIG_PM_CLK=y
-# CONFIG_PM_DEBUG is not set
-CONFIG_PM_SLEEP=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_PREEMPT=y
-CONFIG_PREEMPT_COUNT=y
-# CONFIG_PREEMPT_NONE is not set
-CONFIG_PREEMPT_RCU=y
-CONFIG_PRINTK_TIME=y
-CONFIG_PWM=y
-CONFIG_PWM_JZ4740=y
-CONFIG_PWM_SYSFS=y
-# CONFIG_RCU_BOOST is not set
-CONFIG_RCU_CPU_STALL_VERBOSE=y
-CONFIG_RCU_STALL_COMMON=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGMAP_SPI=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_DRV_CMOS is not set
-CONFIG_RTC_DRV_JZ4740=y
-# CONFIG_SCSI_DMA is not set
-CONFIG_SERIO=y
-CONFIG_SERIO_LIBPS2=y
-CONFIG_SND=y
-CONFIG_SND_COMPRESS_OFFLOAD=y
-CONFIG_SND_DMAENGINE_PCM=y
-# CONFIG_SND_EMU10K1_SEQ is not set
-CONFIG_SND_JACK=y
-CONFIG_SND_JZ4740_SOC=y
-CONFIG_SND_JZ4740_SOC_I2S=y
-CONFIG_SND_JZ4740_SOC_QI_LB60=y
-# CONFIG_SND_OPL3_LIB_SEQ is not set
-# CONFIG_SND_OPL4_LIB_SEQ is not set
-CONFIG_SND_PCM=y
-# CONFIG_SND_RAWMIDI_SEQ is not set
-# CONFIG_SND_SBAWE_SEQ is not set
-CONFIG_SND_SOC=y
-# CONFIG_SND_SOC_FSL_SSI is not set
-CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
-CONFIG_SND_SOC_I2C_AND_SPI=y
-# CONFIG_SND_SOC_IMX_AUDMUX is not set
-CONFIG_SND_SOC_JZ4740_CODEC=y
-CONFIG_SND_TIMER=y
-CONFIG_SOUND=y
-# CONFIG_SOUND_OSS_CORE is not set
-CONFIG_SPI=y
-CONFIG_SPI_BITBANG=y
-CONFIG_SPI_GPIO=y
-CONFIG_SPI_MASTER=y
-# CONFIG_SQUASHFS is not set
-# CONFIG_STAGING is not set
-CONFIG_SUSPEND=y
-CONFIG_SUSPEND_FREEZER=y
-# CONFIG_SYN_COOKIES is not set
-CONFIG_SYS_HAS_CPU_MIPS32_R1=y
-CONFIG_SYS_HAS_EARLY_PRINTK=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_ZBOOT=y
-CONFIG_SYS_SUPPORTS_ZBOOT_UART16550=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TREE_PREEMPT_RCU=y
-CONFIG_UBIFS_FS=y
-CONFIG_UBIFS_FS_ADVANCED_COMPR=y
-CONFIG_UBIFS_FS_LZO=y
-CONFIG_UBIFS_FS_ZLIB=y
-CONFIG_UNINLINE_SPIN_UNLOCK=y
-CONFIG_USB=y
-# CONFIG_USB_AUDIO is not set
-CONFIG_USB_COMMON=y
-# CONFIG_USB_EHCI_HCD is not set
-CONFIG_USB_ETH=y
-# CONFIG_USB_ETH_EEM is not set
-# CONFIG_USB_ETH_RNDIS is not set
-CONFIG_USB_F_ECM=y
-CONFIG_USB_F_SUBSET=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_LIBCOMPOSITE=y
-# CONFIG_USB_MUSB_DUAL_ROLE is not set
-CONFIG_USB_MUSB_GADGET=y
-CONFIG_USB_MUSB_HDRC=y
-# CONFIG_USB_MUSB_HOST is not set
-CONFIG_USB_MUSB_JZ4740=y
-# CONFIG_USB_MUSB_TUSB6010 is not set
-# CONFIG_USB_MUSB_UX500 is not set
-CONFIG_USB_OTG_BLACKLIST_HUB=y
-CONFIG_USB_PHY=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_U_ETHER=y
-CONFIG_VFAT_FS=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_VT_CONSOLE_SLEEP=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
-# CONFIG_WATCHDOG is not set
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZONE_DMA_FLAG=0
+++ /dev/null
-#
-# Copyright (C) 2009-2010 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-JFFS2_BLOCKSIZE=256k 512k
-
-include $(TOPDIR)/rules.mk
-include $(INCLUDE_DIR)/image.mk
-
-ifneq ($(CONFIG_TARGET_xburst_qi_lb60),)
-UBI_OPTS = -m 4096 -p 512KiB
-UBIFS_OPTS = -m 4096 -e 516096 -c 4095
-else
-UBI_OPTS = -m 2048 -p 128KiB -s 512
-UBIFS_OPTS = -m 2048 -e 126KiB -c 4096
-endif
-
-UIMAGE:=$(BIN_DIR)/$(IMG_PREFIX)-uImage.bin
-
-define MkImageGzip
- gzip -9n -c $(1) > $(1).gz
- mkimage -A mips -O linux -T kernel -a 0x80010000 -C gzip \
- -e 0x80010000 -n 'MIPS OpenWrt Linux-$(LINUX_VERSION)' \
- -d $(1).gz $(2)
-endef
-
-define Image/Prepare
- $(call MkImageGzip,$(KDIR)/vmlinux,$(KDIR)/uimage)
-endef
-
-define Image/BuildKernel
- cp $(KDIR)/uimage $(UIMAGE)
-endef
-
-define Image/Build/squashfs
- $(call prepare_generic_squashfs,$(KDIR)/root.squashfs)
-endef
-
-define Image/Build
- dd if=$(KDIR)/root.$(1) of=$(BIN_DIR)/$(IMG_PREFIX)-root.$(1) bs=128k conv=sync
-endef
-
-$(eval $(call BuildImage))
+++ /dev/null
-[rootfs]
-# Volume mode (other option is static)
-mode=ubi
-# Source image
-image=root.ubifs
-# Volume ID in UBI image
-vol_id=0
-# Allow for dynamic resize
-vol_type=dynamic
-# Volume name
-vol_name=rootfs
-# Autoresize volume at first mount
-vol_flags=autoresize
-
+++ /dev/null
-
-
-SOUND_MENU:=Sound Support
-
-define KernelPackage/sound-soc-jz4740
- SUBMENU:=$(SOUND_MENU)
- DEPENDS:=kmod-sound-soc-core @TARGET_xburst @BROKEN
- TITLE:=JZ4740 SoC sound support
- KCONFIG:=CONFIG_SND_JZ4740_SOC CONFIG_SND_JZ4740_SOC_I2S
- FILES:= \
- $(LINUX_DIR)/sound/soc/jz4740/snd-soc-jz4740.ko \
- $(LINUX_DIR)/sound/soc/jz4740/snd-soc-jz4740-i2s.ko
- AUTOLOAD:=$(call AutoLoad,60,snd-soc-jz4740 snd-soc-jz4740-i2s)
-endef
-
-define KernelPackage/sound-soc-jz4740-codec
- SUBMENU:=$(SOUND_MENU)
- DEPENDS:=kmod-sound-soc-core @TARGET_xburst @BROKEN
- TITLE:=JZ4740 SoC internal codec support
- KCONFIG:=CONFIG_SND_SOC_JZ4740_CODEC
- FILES:=$(LINUX_DIR)/sound/soc/codecs/snd-soc-jz4740-codec.ko
- AUTOLOAD:=$(call AutoLoad,60,snd-soc-jz4740-codec)
-endef
-
-define KernelPackage/sound-soc-xburst/default
- SUBMENU:=$(SOUND_MENU)
- DEPENDS:=kmod-sound-soc-jz4740 kmod-sound-soc-jz4740-codec @TARGET_xburst_$(if $(4),$(4),$(3)) @BROKEN
- TITLE:=$(1) sound support
- KCONFIG:=CONFIG_SND_JZ4740_SOC_$(2)
- FILES:=$(LINUX_DIR)/sound/soc/jz4740/snd-soc-$(3).ko
- AUTOLOAD:=$(call AutoLoad,65,snd-soc-$(3))
-endef
-
-define KernelPackage/sound-soc-qilb60
-$(call KernelPackage/sound-soc-xburst/default,QI NanoNote,QI_LB60,qi-lb60,qi_lb60)
-endef
-
-$(eval $(call KernelPackage,sound-soc-jz4740))
-$(eval $(call KernelPackage,sound-soc-jz4740-codec))
-$(eval $(call KernelPackage,sound-soc-qilb60))
+++ /dev/null
-From b0eb5175e0de3e5134a36a7da382d8811562af12 Mon Sep 17 00:00:00 2001
-From: Lars-Peter Clausen <lars@metafoo.de>
-Date: Tue, 15 Mar 2011 12:49:15 +0100
-Subject: [PATCH 1/7] ubi: Read only the vid header instead of the whole page
-
----
- drivers/mtd/ubi/io.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/mtd/ubi/io.c
-+++ b/drivers/mtd/ubi/io.c
-@@ -1014,7 +1014,7 @@ int ubi_io_read_vid_hdr(struct ubi_devic
-
- p = (char *)vid_hdr - ubi->vid_hdr_shift;
- read_err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset,
-- ubi->vid_hdr_alsize);
-+ UBI_VID_HDR_SIZE + ubi->vid_hdr_shift);
- if (read_err && read_err != UBI_IO_BITFLIPS && !mtd_is_eccerr(read_err))
- return read_err;
-
+++ /dev/null
-From 98d33db1c87e2447b9b203399d2f995e05ecdb52 Mon Sep 17 00:00:00 2001
-From: Lars-Peter Clausen <lars@metafoo.de>
-Date: Sat, 26 Feb 2011 15:30:07 +0100
-Subject: [PATCH 2/7] NAND: Optimize NAND_ECC_HW_OOB_FIRST read
-
-Avoid sending unnecessary READ commands to the chip.
----
- drivers/mtd/nand/nand_base.c | 17 +++++++++++++----
- 1 file changed, 13 insertions(+), 4 deletions(-)
-
---- a/drivers/mtd/nand/nand_base.c
-+++ b/drivers/mtd/nand/nand_base.c
-@@ -1365,9 +1365,16 @@ static int nand_read_page_hwecc_oob_firs
- unsigned int max_bitflips = 0;
-
- /* Read the OOB area first */
-- chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
-- chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
-- chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
-+ /* Read the OOB area first */
-+ if (mtd->writesize > 512) {
-+ chip->cmdfunc(mtd, NAND_CMD_READ0, mtd->writesize, page);
-+ chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
-+ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, 0, -1);
-+ } else {
-+ chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
-+ chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
-+ chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
-+ }
-
- for (i = 0; i < chip->ecc.total; i++)
- ecc_code[i] = chip->oob_poi[eccpos[i]];
-@@ -1580,7 +1587,9 @@ static int nand_do_read_ops(struct mtd_i
- __func__, buf);
-
- read_retry:
-- chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
-+ if (chip->ecc.mode != NAND_ECC_HW_OOB_FIRST) {
-+ chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
-+ }
-
- /*
- * Now read the page into the buffer. Absent an error,
+++ /dev/null
-From 6031a240816d1c9a10f596d0648e586f6b878809 Mon Sep 17 00:00:00 2001
-From: Lars-Peter Clausen <lars@metafoo.de>
-Date: Tue, 15 Mar 2011 12:33:41 +0100
-Subject: [PATCH 3/7] NAND: Add support for subpage reads for
- NAND_ECC_HW_OOB_FIRST
-
----
- drivers/mtd/nand/nand_base.c | 77 +++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 76 insertions(+), 1 deletion(-)
-
---- a/drivers/mtd/nand/nand_base.c
-+++ b/drivers/mtd/nand/nand_base.c
-@@ -1398,6 +1398,75 @@ static int nand_read_page_hwecc_oob_firs
- }
-
- /**
-+ * nand_read_subpage_hwecc_oob_first - [REPLACABLE] hw ecc based sub-page read function
-+ * @mtd: mtd info structure
-+ * @chip: nand chip info structure
-+ * @data_offs: offset of requested data within the page
-+ * @readlen: data length
-+ * @bufpoi: buffer to store read data
-+ * @page: page number to read
-+ *
-+ * Hardware ECC for large page chips, require OOB to be read first.
-+ * For this ECC mode, the write_page method is re-used from ECC_HW.
-+ * These methods read/write ECC from the OOB area, unlike the
-+ * ECC_HW_SYNDROME support with multiple ECC steps, follows the
-+ * "infix ECC" scheme and reads/writes ECC from the data area, by
-+ * overwriting the NAND manufacturer bad block markings.
-+ */
-+static int nand_read_subpage_hwecc_oob_first(struct mtd_info *mtd, struct nand_chip *chip,
-+ uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi, int page)
-+{
-+ int start_step, end_step, num_steps;
-+ uint32_t *eccpos = chip->ecc.layout->eccpos;
-+ uint8_t *p;
-+ int data_col_addr;
-+ int eccsize = chip->ecc.size;
-+ int eccbytes = chip->ecc.bytes;
-+ uint8_t *ecc_code = chip->buffers->ecccode;
-+ uint8_t *ecc_calc = chip->buffers->ecccalc;
-+ int i;
-+
-+ /* Column address wihin the page aligned to ECC size */
-+ start_step = data_offs / chip->ecc.size;
-+ end_step = (data_offs + readlen - 1) / chip->ecc.size;
-+ num_steps = end_step - start_step + 1;
-+
-+ data_col_addr = start_step * chip->ecc.size;
-+
-+ /* Read the OOB area first */
-+ if (mtd->writesize > 512) {
-+ chip->cmdfunc(mtd, NAND_CMD_READ0, mtd->writesize, page);
-+ chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
-+ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_col_addr, -1);
-+ } else {
-+ chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
-+ chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
-+ chip->cmdfunc(mtd, NAND_CMD_READ0, data_col_addr, page);
-+ }
-+
-+ for (i = 0; i < chip->ecc.total; i++)
-+ ecc_code[i] = chip->oob_poi[eccpos[i]];
-+
-+ p = bufpoi + data_col_addr;
-+
-+ for (i = eccbytes * start_step; num_steps; num_steps--, i += eccbytes, p += eccsize) {
-+ int stat;
-+
-+ chip->ecc.hwctl(mtd, NAND_ECC_READ);
-+ chip->read_buf(mtd, p, eccsize);
-+ chip->ecc.calculate(mtd, p, &ecc_calc[i]);
-+
-+ stat = chip->ecc.correct(mtd, p, &ecc_code[i], NULL);
-+ if (stat < 0)
-+ mtd->ecc_stats.failed++;
-+ else
-+ mtd->ecc_stats.corrected += stat;
-+ }
-+
-+ return 0;
-+}
-+
-+/**
- * nand_read_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page read
- * @mtd: mtd info structure
- * @chip: nand chip info structure
-@@ -3961,8 +4030,14 @@ int nand_scan_tail(struct mtd_info *mtd)
- pr_warn("No ECC functions supplied; hardware ECC not possible\n");
- BUG();
- }
-- if (!ecc->read_page)
-+
-+ if (!ecc->read_page) {
- ecc->read_page = nand_read_page_hwecc_oob_first;
-+ if (!ecc->read_subpage) {
-+ ecc->read_subpage = nand_read_subpage_hwecc_oob_first;
-+ chip->options |= NAND_SUBPAGE_READ;
-+ }
-+ }
-
- case NAND_ECC_HW:
- /* Use standard hwecc read page function? */
+++ /dev/null
-From 1a1095927d224403af8ad57c354cc64521bf3081 Mon Sep 17 00:00:00 2001
-From: Paul Cercueil <paul@crapouillou.net>
-Date: Sat, 16 Jun 2012 19:36:31 +0200
-Subject: [PATCH 4/7] ASoC: JZ4740: delay activation of the DAC to work around
- a sound bug.
-
-A proper fix of that bug would require a big rewrite of the driver,
-which (I hope) will be done eventually.
----
- sound/soc/codecs/jz4740.c | 9 ++++++---
- 1 file changed, 6 insertions(+), 3 deletions(-)
-
---- a/sound/soc/codecs/jz4740.c
-+++ b/sound/soc/codecs/jz4740.c
-@@ -249,12 +249,15 @@ static int jz4740_codec_set_bias_level(s
- case SND_SOC_BIAS_ON:
- break;
- case SND_SOC_BIAS_PREPARE:
-- mask = JZ4740_CODEC_1_VREF_DISABLE |
-- JZ4740_CODEC_1_VREF_AMP_DISABLE |
-- JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M;
-+ mask = JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M;
- value = 0;
-
- regmap_update_bits(regmap, JZ4740_REG_CODEC_1, mask, value);
-+
-+ msleep(500);
-+ mask = JZ4740_CODEC_1_VREF_DISABLE |
-+ JZ4740_CODEC_1_VREF_AMP_DISABLE;
-+ regmap_update_bits(regmap, JZ4740_REG_CODEC_1, mask, 0);
- break;
- case SND_SOC_BIAS_STANDBY:
- /* The only way to clear the suspend flag is to reset the codec */
+++ /dev/null
-From f05b1ecd7e4fde7e69320a4b7be461636e982991 Mon Sep 17 00:00:00 2001
-From: Paul Cercueil <paul@crapouillou.net>
-Date: Thu, 13 Sep 2012 00:09:20 +0200
-Subject: [PATCH 5/7] RTC: JZ4740: Init the "regulator" register on startup.
-
-This register controls the accuracy of the RTC. uC/OS-II use
-the RTC as a 100Hz clock, and writes a completely wrong value
-on that register, that we have to overwrite if we want a working
-real-time clock.
-
-Signed-off-by: Paul Cercueil <paul@crapouillou.net>
----
- drivers/rtc/rtc-jz4740.c | 17 +++++++++++++++++
- 1 file changed, 17 insertions(+)
-
---- a/drivers/rtc/rtc-jz4740.c
-+++ b/drivers/rtc/rtc-jz4740.c
-@@ -15,6 +15,7 @@
- */
-
- #include <linux/io.h>
-+#include <linux/clk.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/platform_device.h>
-@@ -216,6 +217,7 @@ static int jz4740_rtc_probe(struct platf
- struct jz4740_rtc *rtc;
- uint32_t scratchpad;
- struct resource *mem;
-+ struct clk *rtc_clk;
-
- rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
- if (!rtc)
-@@ -263,6 +265,21 @@ static int jz4740_rtc_probe(struct platf
- }
- }
-
-+ rtc_clk = clk_get(&pdev->dev, "rtc");
-+ if (IS_ERR(rtc_clk)) {
-+ dev_err(&pdev->dev, "Failed to get RTC clock\n");
-+ return PTR_ERR(rtc_clk);
-+ }
-+
-+ /* TODO: initialize the ADJC bits (25:16) to fine-tune
-+ * the accuracy of the RTC */
-+ ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_REGULATOR,
-+ (clk_get_rate(rtc_clk) - 1) & 0xffff);
-+ clk_put(rtc_clk);
-+
-+ if (ret)
-+ dev_warn(&pdev->dev, "Could not update RTC regulator register\n");
-+
- return 0;
- }
-
+++ /dev/null
-From 8741ead92bc93e66740237e51b88b8690ebcbba3 Mon Sep 17 00:00:00 2001
-From: Lars-Peter Clausen <lars@metafoo.de>
-Date: Sun, 1 Aug 2010 21:19:40 +0200
-Subject: [PATCH 6/7] Add ili8960 lcd driver
-
-Includes the following changes from the jz-3.5 branch:
-- Use module_spi_driver
-- Use devm_kzalloc
-- Use kstrtoul
-
-Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
----
- drivers/video/backlight/Kconfig | 7 +
- drivers/video/backlight/Makefile | 1 +
- drivers/video/backlight/ili8960.c | 262 +++++++++++++++++++++++++++++++++++++
- 3 files changed, 270 insertions(+)
- create mode 100644 drivers/video/backlight/ili8960.c
-
---- a/drivers/video/backlight/Kconfig
-+++ b/drivers/video/backlight/Kconfig
-@@ -59,6 +59,13 @@ config LCD_LTV350QV
-
- The LTV350QV panel is present on all ATSTK1000 boards.
-
-+config LCD_ILI8960
-+ tristate "Ilitek ili8960 LCD driver"
-+ depends on LCD_CLASS_DEVICE && SPI
-+ default n
-+ help
-+ Driver for the Ilitek ili8960 LCD controller chip.
-+
- config LCD_ILI922X
- tristate "ILI Technology ILI9221/ILI9222 support"
- depends on SPI
---- a/drivers/video/backlight/Makefile
-+++ b/drivers/video/backlight/Makefile
-@@ -5,6 +5,7 @@ obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o
- obj-$(CONFIG_LCD_CORGI) += corgi_lcd.o
- obj-$(CONFIG_LCD_HP700) += jornada720_lcd.o
- obj-$(CONFIG_LCD_HX8357) += hx8357.o
-+obj-$(CONFIG_LCD_ILI8960) += ili8960.o
- obj-$(CONFIG_LCD_ILI922X) += ili922x.o
- obj-$(CONFIG_LCD_ILI9320) += ili9320.o
- obj-$(CONFIG_LCD_L4F00242T03) += l4f00242t03.o
---- /dev/null
-+++ b/drivers/video/backlight/ili8960.c
-@@ -0,0 +1,262 @@
-+/*
-+ * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
-+ * Driver for Ilitek ili8960 LCD
-+ *
-+ * 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.
-+ *
-+ * You should have received a copy of the GNU General Public License along
-+ * with this program; if not, write to the Free Software Foundation, Inc.,
-+ * 675 Mass Ave, Cambridge, MA 02139, USA.
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/spi/spi.h>
-+#include <linux/lcd.h>
-+#include <linux/delay.h>
-+
-+struct ili8960 {
-+ struct spi_device *spi;
-+ struct lcd_device *lcd;
-+ bool enabled;
-+ unsigned int brightness;
-+};
-+
-+#define ILI8960_REG_BRIGHTNESS 0x03
-+#define ILI8960_REG_POWER 0x05
-+#define ILI8960_REG_CONTRAST 0x0d
-+
-+static int ili8960_write_reg(struct spi_device *spi, uint8_t reg,
-+ uint8_t data)
-+{
-+ uint8_t buf[2];
-+ buf[0] = ((reg & 0x40) << 1) | (reg & 0x3f);
-+ buf[1] = data;
-+
-+ return spi_write(spi, buf, sizeof(buf));
-+}
-+
-+static int ili8960_programm_power(struct spi_device *spi, bool enabled)
-+{
-+ int ret;
-+
-+ if (enabled)
-+ mdelay(20);
-+
-+ ret = ili8960_write_reg(spi, ILI8960_REG_POWER, enabled ? 0xc7 : 0xc6);
-+
-+ if (!enabled)
-+ mdelay(20);
-+
-+ return ret;
-+}
-+
-+static int ili8960_set_power(struct lcd_device *lcd, int power)
-+{
-+ struct ili8960 *ili8960 = lcd_get_data(lcd);
-+
-+ switch (power) {
-+ case FB_BLANK_UNBLANK:
-+ ili8960->enabled = true;
-+ break;
-+ default:
-+ return 0;
-+ }
-+
-+ return ili8960_programm_power(ili8960->spi, ili8960->enabled);
-+}
-+
-+static int ili8960_early_set_power(struct lcd_device *lcd, int power)
-+{
-+ struct ili8960 *ili8960 = lcd_get_data(lcd);
-+
-+ switch (power) {
-+ case FB_BLANK_UNBLANK:
-+ return 0;
-+ default:
-+ ili8960->enabled = false;
-+ break;
-+ }
-+
-+ return ili8960_programm_power(ili8960->spi, ili8960->enabled);
-+}
-+
-+static int ili8960_get_power(struct lcd_device *lcd)
-+{
-+ struct ili8960 *ili8960 = lcd_get_data(lcd);
-+ return ili8960->enabled ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
-+}
-+
-+static int ili8960_set_contrast(struct lcd_device *lcd, int contrast)
-+{
-+ struct ili8960 *ili8960 = lcd_get_data(lcd);
-+
-+ return ili8960_write_reg(ili8960->spi, ILI8960_REG_CONTRAST, contrast);
-+}
-+
-+static int ili8960_set_mode(struct lcd_device *lcd, struct fb_videomode *mode)
-+{
-+ if (mode->xres != 320 && mode->yres != 240)
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+static int ili8960_set_brightness(struct ili8960 *ili8960, int brightness)
-+{
-+ int ret;
-+
-+ ret = ili8960_write_reg(ili8960->spi, ILI8960_REG_BRIGHTNESS, brightness);
-+
-+ if (ret == 0)
-+ ili8960->brightness = brightness;
-+
-+ return ret;
-+}
-+
-+static ssize_t ili8960_show_brightness(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct lcd_device *ld = to_lcd_device(dev);
-+ struct ili8960 *ili8960 = lcd_get_data(ld);
-+
-+ return sprintf(buf, "%u\n", ili8960->brightness);
-+}
-+
-+static ssize_t ili8960_store_brightness(struct device *dev,
-+ struct device_attribute *attr, const char *buf, size_t count)
-+{
-+ struct lcd_device *ld = to_lcd_device(dev);
-+ struct ili8960 *ili8960 = lcd_get_data(ld);
-+ unsigned long brightness;
-+ int ret;
-+
-+ ret = kstrtoul(buf, 0, &brightness);
-+ if (ret)
-+ return ret;
-+
-+ if (brightness > 255)
-+ return -EINVAL;
-+
-+ ili8960_set_brightness(ili8960, brightness);
-+
-+ return count;
-+}
-+
-+
-+static DEVICE_ATTR(brightness, 0644, ili8960_show_brightness,
-+ ili8960_store_brightness);
-+
-+static struct lcd_ops ili8960_lcd_ops = {
-+ .set_power = ili8960_set_power,
-+ .early_set_power = ili8960_early_set_power,
-+ .get_power = ili8960_get_power,
-+ .set_contrast = ili8960_set_contrast,
-+ .set_mode = ili8960_set_mode,
-+};
-+
-+static int ili8960_probe(struct spi_device *spi)
-+{
-+ int ret;
-+ struct ili8960 *ili8960;
-+
-+ ili8960 = devm_kzalloc(&spi->dev, sizeof(*ili8960), GFP_KERNEL);
-+ if (!ili8960)
-+ return -ENOMEM;
-+
-+ spi->bits_per_word = 8;
-+ spi->mode = SPI_MODE_3;
-+
-+ ret = spi_setup(spi);
-+ if (ret) {
-+ dev_err(&spi->dev, "Failed to setup spi\n");
-+ return ret;
-+ }
-+
-+ ili8960->spi = spi;
-+
-+ ili8960->lcd = lcd_device_register("ili8960-lcd", &spi->dev, ili8960,
-+ &ili8960_lcd_ops);
-+
-+ if (IS_ERR(ili8960->lcd)) {
-+ ret = PTR_ERR(ili8960->lcd);
-+ dev_err(&spi->dev, "Failed to register lcd device: %d\n", ret);
-+ return ret;
-+ }
-+
-+ ili8960->lcd->props.max_contrast = 255;
-+
-+ ret = device_create_file(&ili8960->lcd->dev, &dev_attr_brightness);
-+ if (ret)
-+ goto err_unregister_lcd;
-+
-+ ili8960_programm_power(ili8960->spi, true);
-+ ili8960->enabled = true;
-+
-+ spi_set_drvdata(spi, ili8960);
-+
-+ ili8960_write_reg(spi, 0x13, 0x01);
-+
-+ return 0;
-+err_unregister_lcd:
-+ lcd_device_unregister(ili8960->lcd);
-+ return ret;
-+}
-+
-+static int ili8960_remove(struct spi_device *spi)
-+{
-+ struct ili8960 *ili8960 = spi_get_drvdata(spi);
-+
-+ device_remove_file(&ili8960->lcd->dev, &dev_attr_brightness);
-+ lcd_device_unregister(ili8960->lcd);
-+
-+ spi_set_drvdata(spi, NULL);
-+ return 0;
-+}
-+
-+#ifdef CONFIG_PM
-+
-+static int ili8960_suspend(struct spi_device *spi, pm_message_t state)
-+{
-+ struct ili8960 *ili8960 = spi_get_drvdata(spi);
-+
-+ if (ili8960->enabled)
-+ ili8960_programm_power(ili8960->spi, false);
-+
-+ return 0;
-+}
-+
-+static int ili8960_resume(struct spi_device *spi)
-+{
-+ struct ili8960 *ili8960 = spi_get_drvdata(spi);
-+
-+ if (ili8960->enabled)
-+ ili8960_programm_power(ili8960->spi, true);
-+
-+ return 0;
-+}
-+
-+#else
-+#define ili8960_suspend NULL
-+#define ili8960_resume NULL
-+#endif
-+
-+static struct spi_driver ili8960_driver = {
-+ .driver = {
-+ .name = "ili8960",
-+ .owner = THIS_MODULE,
-+ },
-+ .probe = ili8960_probe,
-+ .remove = ili8960_remove,
-+ .suspend = ili8960_suspend,
-+ .resume = ili8960_resume,
-+};
-+module_spi_driver(ili8960_driver);
-+
-+MODULE_AUTHOR("Lars-Peter Clausen");
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("LCD driver for Ilitek ili8960");
-+MODULE_ALIAS("spi:ili8960");
+++ /dev/null
-From 4371d60ae342c76708c4317e06fb7dcf0159c2f1 Mon Sep 17 00:00:00 2001
-From: Lars-Peter Clausen <lars@metafoo.de>
-Date: Wed, 13 Oct 2010 01:17:24 +0200
-Subject: [PATCH 7/7] qi_lb60: Don't use 3-wire spi mode for the display for
- now
-
-The spi_gpio driver does not support 3-wire mode.
----
- arch/mips/jz4740/board-qi_lb60.c | 1 -
- 1 file changed, 1 deletion(-)
-
---- a/arch/mips/jz4740/board-qi_lb60.c
-+++ b/arch/mips/jz4740/board-qi_lb60.c
-@@ -313,7 +313,6 @@ static struct spi_board_info qi_lb60_spi
- .chip_select = 0,
- .bus_num = 1,
- .max_speed_hz = 30 * 1000,
-- .mode = SPI_3WIRE,
- },
- };
-
+++ /dev/null
-# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_INPUT_MATRIXKMAP=y
-CONFIG_KEYBOARD_GPIO=y
-CONFIG_KEYBOARD_MATRIX=y
-CONFIG_LCD_CLASS_DEVICE=y
-CONFIG_LCD_ILI8960=y
-# CONFIG_LCD_L4F00242T03 is not set
-# CONFIG_LCD_LMS283GF05 is not set
-# CONFIG_LCD_LTV350QV is not set
-# CONFIG_LCD_PLATFORM is not set
-# CONFIG_LCD_TDO24M is not set
-# CONFIG_LCD_VGG2432A4 is not set
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_CLUT224 is not set
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_REGMAP_SPI=y
-CONFIG_SND_HWDEP=y
-CONFIG_SND_MIXER_OSS=y
-CONFIG_SND_PCM_OSS=y
-CONFIG_SND_SEQUENCER=y
-# CONFIG_SND_SEQUENCER_OSS is not set
-CONFIG_SND_SEQ_DUMMY=y
-# CONFIG_SND_VIRMIDI is not set
-CONFIG_SOUND_OSS_CORE=y
-CONFIG_SOUND_OSS_CORE_PRECLAIM=y
-CONFIG_SPI=y
-CONFIG_SPI_BITBANG=y
-CONFIG_SPI_GPIO=y
-CONFIG_SPI_MASTER=y
-# CONFIG_USB_FUSB300 is not set
-CONFIG_USB_JZ4740=y
+++ /dev/null
-BOARDNAME:=QI Ben Nanonote (qi_lb60)