summaryrefslogtreecommitdiffstats
path: root/meta-aspeed
diff options
context:
space:
mode:
Diffstat (limited to 'meta-aspeed')
-rw-r--r--meta-aspeed/classes/aspeed_uboot_image.bbclass63
-rw-r--r--meta-aspeed/conf/layer.conf10
-rw-r--r--meta-aspeed/conf/machine/include/ast1250.inc28
-rw-r--r--meta-aspeed/conf/machine/include/ast2400.inc7
-rw-r--r--meta-aspeed/recipes-bsp/u-boot/files/fw_env.config22
-rw-r--r--meta-aspeed/recipes-bsp/u-boot/files/patch-2013.07/0000-u-boot-aspeed-064.patch44658
-rw-r--r--meta-aspeed/recipes-bsp/u-boot/files/patch-2013.07/0001-u-boot-openbmc.patch1580
-rw-r--r--meta-aspeed/recipes-bsp/u-boot/u-boot-fw-utils_2013.07%.bbappend5
-rw-r--r--meta-aspeed/recipes-bsp/u-boot/u-boot_2013.07%.bbappend12
-rw-r--r--meta-aspeed/recipes-core/images/aspeed-dev.inc5
-rw-r--r--meta-aspeed/recipes-core/images/files/aspeed_device_table41
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0000-linux-aspeed-064.patch50917
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0000-linux-openbmc.patch13400
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0001-MTD-fix-m25p80-64-bit-divisions.patch129
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0001-bzip2-lzma-library-support-for-gzip-bzip2-and-lzma-d.patch1876
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0002-bzip2-lzma-config-and-initramfs-support-for-bzip2-lz.patch585
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0005-mtd-Bug-in-m25p80.c-during-whole-chip-erase.patch53
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0006-mtd-fix-timeout-in-M25P80-driver.patch63
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0009-mtd-m25p80-timeout-too-short-for-worst-case-m25p16-d.patch31
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0010-mtd-m25p80-fix-null-pointer-dereference-bug.patch56
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0012-mtd-m25p80-add-support-for-AAI-programming-with-SST-.patch179
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0020-mtd-m25p80-make-command-buffer-DMA-safe.patch56
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0021-mtd-m25p80-Add-support-for-CAT25xxx-serial-EEPROMs.patch327
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0022-mtd-m25p80-Add-support-for-Macronix-MX25L25635E.patch99
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0023-mtd-m25p80-Add-support-for-Macronix-MX25L25655E.patch72
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0024-mtd-m25p80-add-support-for-Micron-N25Q256A.patch35
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0025-mtd-m25p80-add-support-for-Micron-N25Q128.patch28
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0026-mtd-m25p80-modify-info-for-Micron-N25Q128.patch39
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0027-mtd-m25p80-n25q064-is-Micron-not-Intel-Numonyx.patch29
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0028-ipv6-Plug-sk_buff-leak-in-ipv6_rcv-net-ipv6-ip6_inpu.patch52
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/README1
-rw-r--r--meta-aspeed/recipes-kernel/linux/linux-aspeed.inc31
-rw-r--r--meta-aspeed/recipes-kernel/linux/linux-aspeed_2.6.28.9.bb39
33 files changed, 114528 insertions, 0 deletions
diff --git a/meta-aspeed/classes/aspeed_uboot_image.bbclass b/meta-aspeed/classes/aspeed_uboot_image.bbclass
new file mode 100644
index 0000000..b22b0b8
--- /dev/null
+++ b/meta-aspeed/classes/aspeed_uboot_image.bbclass
@@ -0,0 +1,63 @@
+inherit image_types_uboot
+
+# oe_mkimage() was defined in image_types_uboot. Howver, it does not consider
+# the image load address and entry point. Override it here.
+
+oe_mkimage () {
+ mkimage -A ${UBOOT_ARCH} -O linux -T ramdisk -C $2 -n ${IMAGE_NAME} \
+ -a ${UBOOT_IMAGE_LOADADDRESS} -e ${UBOOT_IMAGE_ENTRYPOINT} \
+ -d ${DEPLOY_DIR_IMAGE}/$1 ${DEPLOY_DIR_IMAGE}/$1.u-boot
+}
+
+UBOOT_IMAGE_ENTRYPOINT ?= "0x42000000"
+UBOOT_IMAGE_LOADADDRESS ?= "${UBOOT_IMAGE_ENTRYPOINT}"
+
+# 24M
+IMAGE_ROOTFS_SIZE = "24576"
+# and don't put overhead behind my back
+IMAGE_OVERHEAD_FACTOR = "1"
+
+IMAGE_PREPROCESS_COMMAND += " generate_data_mount_dir ; "
+IMAGE_POSTPROCESS_COMMAND += " flash_image_generate ; "
+
+FLASH_IMAGE_NAME ?= "flash-${MACHINE}-${DATETIME}"
+FLASH_IMAGE_LINK ?= "flash-${MACHINE}"
+# 16M
+FLASH_SIZE ?= "16384"
+FLASH_UBOOT_OFFSET ?= "0"
+# 512k
+FLASH_KERNEL_OFFSET ?= "512"
+# 3M
+FLASH_ROOTFS_OFFSET ?= "3072"
+
+flash_image_generate() {
+ kernelfile="${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}"
+ ubootfile="${DEPLOY_DIR_IMAGE}/u-boot.${UBOOT_SUFFIX}"
+ # rootfs has to match the type defined in IMAGE_FSTYPES"
+ rootfs="${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}.cpio.lzma.u-boot"
+ if [ ! -f $kernelfile ]; then
+ echo "Kernel file ${kernelfile} does not exist"
+ return 1
+ fi
+ if [ ! -f $ubootfile ]; then
+ echo "U-boot file ${ubootfile} does not exist"
+ return 1
+ fi
+ if [ ! -f $rootfs ]; then
+ echo "Rootfs file ${rootfs} does not exist"
+ return 1
+ fi
+ dst="${DEPLOY_DIR_IMAGE}/${FLASH_IMAGE_NAME}"
+ rm -rf $dst
+ dd if=/dev/zero of=${dst} bs=1k count=${FLASH_SIZE}
+ dd if=${ubootfile} of=${dst} bs=1k seek=${FLASH_UBOOT_OFFSET}
+ dd if=${kernelfile} of=${dst} bs=1k seek=${FLASH_KERNEL_OFFSET}
+ dd if=${rootfs} of=${dst} bs=1k seek=${FLASH_ROOTFS_OFFSET}
+ dstlink="${DEPLOY_DIR_IMAGE}/${FLASH_IMAGE_LINK}"
+ rm -rf $dstlink
+ ln -sf ${FLASH_IMAGE_NAME} $dstlink
+}
+
+generate_data_mount_dir() {
+ mkdir -p "${IMAGE_ROOTFS}/mnt/data"
+}
diff --git a/meta-aspeed/conf/layer.conf b/meta-aspeed/conf/layer.conf
new file mode 100644
index 0000000..2418d8e
--- /dev/null
+++ b/meta-aspeed/conf/layer.conf
@@ -0,0 +1,10 @@
+# We have a conf and classes directory, add to BBPATH
+BBPATH .= ":${LAYERDIR}"
+
+# We have recipes-* directories, add to BBFILES
+BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
+ ${LAYERDIR}/recipes-*/*/*.bbappend"
+
+BBFILE_COLLECTIONS += "aspeed"
+BBFILE_PATTERN_aspeed = "^${LAYERDIR}/"
+BBFILE_PRIORITY_aspeed = "7"
diff --git a/meta-aspeed/conf/machine/include/ast1250.inc b/meta-aspeed/conf/machine/include/ast1250.inc
new file mode 100644
index 0000000..099fdb0
--- /dev/null
+++ b/meta-aspeed/conf/machine/include/ast1250.inc
@@ -0,0 +1,28 @@
+#@TYPE: Machine
+#@NAME: aspeed ast1250
+#@DESCRIPTION: Machine configuration for aspeed ast1250 SoC
+
+# Ship all kernel modules by default
+MACHINE_EXTRA_RRECOMMENDS = "kernel-modules"
+
+# Allow for MMC booting (required by the NAND-less Beagleboard XM)
+EXTRA_IMAGEDEPENDS += "u-boot"
+
+# Uncomment the following line to enable the hard floating point abi. Note that
+# this breaks some binary libraries and 3D (neither of which ship with
+# meta-yocto). For maximum compatibility, leave this disabled.
+DEFAULTTUNE ?= "arm926ejs"
+require conf/machine/include/tune-arm926ejs.inc
+
+PREFERRED_PROVIDER_virtual/kernel ?= "linux-aspeed"
+PREFERRED_VERSION_linux-aspeed ?= "2.6.28%"
+
+KERNEL_IMAGETYPE ?= "uImage"
+KERNEL_EXTRA_ARGS ?= "UIMAGE_LOADADDR=0x40008000"
+
+UBOOT_SUFFIX ?= "bin"
+UBOOT_ENTRYPOINT ?= "0x40008000"
+UBOOT_LOADADDRESS ?= "0x40008000"
+UBOOT_MACHINE ?= "ast1250_config"
+
+MACHINE_FEATURES = "usbgadget usbhost vfat ext2 serial"
diff --git a/meta-aspeed/conf/machine/include/ast2400.inc b/meta-aspeed/conf/machine/include/ast2400.inc
new file mode 100644
index 0000000..4ea982b
--- /dev/null
+++ b/meta-aspeed/conf/machine/include/ast2400.inc
@@ -0,0 +1,7 @@
+#@TYPE: Machine
+#@NAME: aspeed ast2400
+#@DESCRIPTION: Machine configuration for aspeed ast2400 SoC
+
+UBOOT_MACHINE ?= "ast2400_config"
+
+require conf/machine/include/ast1250.inc \ No newline at end of file
diff --git a/meta-aspeed/recipes-bsp/u-boot/files/fw_env.config b/meta-aspeed/recipes-bsp/u-boot/files/fw_env.config
new file mode 100644
index 0000000..9cb3ad2
--- /dev/null
+++ b/meta-aspeed/recipes-bsp/u-boot/files/fw_env.config
@@ -0,0 +1,22 @@
+# Configuration file for fw_(printenv/setenv) utility.
+# Up to two entries are valid, in this case the redundant
+# environment sector is assumed present.
+# Notice, that the "Number of sectors" is ignored on NOR and SPI-dataflash.
+# Futhermore, if the Flash sector size is ommitted, this value is assumed to
+# be the same as the Environment size, which is valid for NOR and SPI-dataflash
+
+# NOR example
+# MTD device name Device offset Env. size Flash sector size Number of sectors
+/dev/mtd1 0x0000 0x20000 0x20000
+#/dev/mtd2 0x0000 0x4000 0x4000
+
+# MTD SPI-dataflash example
+# MTD device name Device offset Env. size Flash sector size Number of sectors
+#/dev/mtd5 0x4200 0x4200
+#/dev/mtd6 0x4200 0x4200
+
+# NAND example
+#/dev/mtd0 0x4000 0x4000 0x20000 2
+
+# Block device example
+#/dev/mmcblk0 0xc0000 0x20000
diff --git a/meta-aspeed/recipes-bsp/u-boot/files/patch-2013.07/0000-u-boot-aspeed-064.patch b/meta-aspeed/recipes-bsp/u-boot/files/patch-2013.07/0000-u-boot-aspeed-064.patch
new file mode 100644
index 0000000..8ebfb96
--- /dev/null
+++ b/meta-aspeed/recipes-bsp/u-boot/files/patch-2013.07/0000-u-boot-aspeed-064.patch
@@ -0,0 +1,44658 @@
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/COMMINF.H b/arch/arm/cpu/arm926ejs/aspeed/COMMINF.H
+new file mode 100644
+index 0000000..44b7540
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/COMMINF.H
+@@ -0,0 +1,641 @@
++/*
++ * 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 COMMINF_H
++#define COMMINF_H
++
++#include "SWFUNC.H"
++
++#if defined(LinuxAP)
++#endif
++#ifdef SLT_UBOOT
++#endif
++#ifdef SLT_DOS
++ #include <stdio.h>
++ #include <time.h>
++ #include <dos.h> // For delay()
++#endif
++
++#include "TYPEDEF.H"
++#include "LIB.H"
++
++//---------------------------------------------------------
++// Print Message
++//---------------------------------------------------------
++// for function
++#define FP_LOG 0
++#define FP_IO 1
++#define STD_OUT 2
++
++#ifdef SLT_UBOOT
++ #define PRINT printf
++ #define OUT_OBJ
++ #define FILE_VAR
++
++ #define GET_OBJ( i ) \
++ do { \
++ if ( i != STD_OUT ) \
++ return; \
++ } while ( 0 );
++
++#else
++ #define PRINT fprintf
++ #define OUT_OBJ fp,
++ #define FILE_VAR FILE *fp;
++
++ #define GET_OBJ( i ) \
++ switch( i ) { \
++ case FP_LOG: \
++ fp = fp_log; \
++ break; \
++ case FP_IO: \
++ fp = fp_io; \
++ break; \
++ case STD_OUT: \
++ fp = stdout; \
++ break; \
++ default : break; \
++ }
++#endif
++
++//---------------------------------------------------------
++// Function
++//---------------------------------------------------------
++#ifdef SLT_UBOOT
++ #define DELAY( x ) udelay( x * 1000 ) // For Uboot, the unit of udelay() is us.
++ #define GET_CAHR getc
++#endif
++#ifdef SLT_DOS
++ #define DELAY( x ) delay( x ) // For DOS, the unit of delay() is ms.
++ #define GET_CAHR getchar
++#endif
++
++//---------------------------------------------------------
++// Default argument
++//---------------------------------------------------------
++#define DEF_USER_DEF_PACKET_VAL 0x66666666 //0xff00ff00, 0xf0f0f0f0, 0xcccccccc, 0x55aa55aa, 0x5a5a5a5a, 0x66666666
++#define DEF_IOTIMINGBUND 5 //0/1/3/5/7
++#define DEF_PHY_ADR 0
++#define DEF_TESTMODE 0 //[0]0: no burst mode, 1: 0xff, 2: 0x55, 3: random, 4: ARP, 5: ARP, 6: IO timing, 7: IO timing+IO Strength
++#define DEF_LOOP_MAX 1
++#define DEF_MAC_LOOP_BACK 0 //GCtrl bit6
++#define DEF_SKIP_CHECK_PHY 0 //GCtrl bit4
++#define DEF_INIT_PHY 1 //GCtrl bit3
++
++#define SET_1GBPS 0 // 1G bps
++#define SET_100MBPS 1 // 100M bps
++#define SET_10MBPS 2 // 10M bps
++#define SET_1G_100M_10MBPS 3 // 1G and 100M and 10M bps
++#define DEF_SPEED SET_1G_100M_10MBPS
++#define DEF_ARPNUMCNT 0
++
++//---------------------------------------------------------
++// MAC information
++//---------------------------------------------------------
++#if ( AST1010_IOMAP == 1 )
++ // AST1010 only has a MAC
++ #define MAC_BASE1 AST_MAC1_BASE
++ #define MAC_BASE2 AST_MAC1_BASE
++ #define MAC_BASE3 AST_MAC1_BASE
++ #define MAC_BASE4 AST_MAC1_BASE
++#endif
++
++#if ( AST1010_IOMAP == 2 )
++ // AST1010 only has a MAC
++ #define MAC_BASE1 0x0830000
++ #define MAC_BASE2 0x0830000
++ #define MAC_BASE3 0x0830000
++ #define MAC_BASE4 0x0830000
++#endif
++
++#ifndef AST1010_IOMAP
++ #define MAC_BASE1 0x1e660000
++ #define MAC_BASE2 0x1e680000
++ #define MAC_BASE3 0x1e670000
++ #define MAC_BASE4 0x1e690000
++#endif
++
++#define MDC_Thres 0x3f
++#define MAC_PHYWr 0x08000000
++#define MAC_PHYRd 0x04000000
++
++#define MAC_PHYWr_New 0x00009400
++#define MAC_PHYRd_New 0x00009800
++#define MAC_PHYBusy_New 0x00008000
++
++//#define MAC_30h 0x00001010
++//#define MAC_34h 0x00000000
++//#define MAC_38h 0x00d22f00 //default 0x22f00
++//#define MAC_38h 0x00022f00 //default 0x22f00
++
++#define MAC_40h 0x40000000
++
++#ifdef Enable_BufMerge
++ #define MAC_48h 0x007702F1 //default 0xf1
++#else
++ #ifdef AST1010_IOMAP
++ #define MAC_48h 0x000002F1 //default 0xf1
++ #else
++ #define MAC_48h 0x000001F1 //default 0xf1
++ #endif
++#endif
++
++//---------------------------------------------------------
++// Data information
++//---------------------------------------------------------
++#ifdef SelectSimpleBoundary
++ #define ZeroCopy_OFFSET 0
++#else
++ #define ZeroCopy_OFFSET ( (BurstEnable) ? 0 : 2 )
++#endif
++
++// --------------------------------- DRAM_MapAdr = TDES_BASE1
++// | TX descriptor ring #1 |
++// ------------------------- DRAM_MapAdr + 0x040000 = RDES_BASE1
++// | RX descriptor ring #1 |
++// ------------------------- DRAM_MapAdr + 0x080000 = TDES_BASE2
++// | TX descriptor ring #2 |
++// ------------------------- DRAM_MapAdr + 0x0C0000 = RDES_BASE2
++// | RX descriptor ring #2 |
++// --------------------------------- DRAM_MapAdr + 0x100000 = DMA_BASE -------------------------
++// | #1 | \ | #1 Tx |
++// DMA buffer | | DMA_BufSize | LOOP = 0 |
++// ( Tx/Rx ) ------------------------- / --------------------------------------------------
++// | #2 | | #2 Rx | #2 Tx |
++// | | | LOOP = 0 | LOOP = 1 |
++// ------------------------- --------------------------------------------------
++// | #3 | | #3 Rx |
++// | | | LOOP = 1 |
++// ------------------------- -------------------------
++// | #4 | ..........
++// | |
++// -------------------------
++// | #5 |
++// | |
++// -------------------------
++// | #6 |
++// | |
++// -------------------------
++// .
++// .
++// -------------------------
++// | #n, n = DMA_BufNum |
++// | |
++// ---------------------------------
++
++#if ( AST1010_IOMAP == 1 )
++ #define DRAM_MapAdr ( CONFIG_DRAM_SWAP_BASE + 0x00200000 ) // We use 0xA00000 to 0xEFFFFF
++ #define CPU_BUS_ADDR_SDRAM_OFFSET 0x01000000 // In ReMapping function, MAC engine need Bus address
++ // But Coldfire need CPU address, so need to do offset
++#endif
++
++#if ( AST1010_IOMAP == 2 )
++ #define DRAM_MapAdr 0x0A00000 // We use 0xA00000 to 0xEFFFFF
++ #define CPU_BUS_ADDR_SDRAM_OFFSET 0
++#endif
++
++#ifndef AST1010_IOMAP
++ #ifdef AST3200_IOMAP
++ #define DRAM_MapAdr 0x80000000
++ #else
++ #define DRAM_MapAdr 0x44000000
++ #endif
++
++ #define CPU_BUS_ADDR_SDRAM_OFFSET 0
++#endif
++
++ #define TDES_BASE1 ( 0x00000000 + DRAM_MapAdr )
++ #define RDES_BASE1 ( 0x00040000 + DRAM_MapAdr )
++ #define TDES_BASE2 ( 0x00080000 + DRAM_MapAdr )
++ #define RDES_BASE2 ( 0x000C0000 + DRAM_MapAdr )
++
++ #define TDES_IniVal ( 0xb0000000 + FRAME_LEN_Cur )
++ #define RDES_IniVal ( 0x00000fff )
++ #define EOR_IniVal ( 0x40008000 )
++ #define HWOwnTx(dat) ( (dat) & 0x80000000 )
++ #define HWOwnRx(dat) ( !((dat) & 0x80000000) )
++ #define HWEOR(dat) ( dat & 0x40000000 )
++
++//---------------------------------------------------------
++// Error Flag Bits
++//---------------------------------------------------------
++#define Err_MACMode ( 1 << 0 ) // MAC interface mode mismatch
++#define Err_PHY_Type ( 1 << 1 ) // Unidentifiable PHY
++#define Err_MALLOC_FrmSize ( 1 << 2 ) // Malloc fail at frame size buffer
++#define Err_MALLOC_LastWP ( 1 << 3 ) // Malloc fail at last WP buffer
++#define Err_Check_Buf_Data ( 1 << 4 ) // Received data mismatch
++#define Err_Check_Des ( 1 << 5 ) // Descriptor error
++#define Err_NCSI_LinkFail ( 1 << 6 ) // NCSI packet retry number over flows
++#define Err_NCSI_Check_TxOwnTimeOut ( 1 << 7 ) // Time out of checking Tx owner bit in NCSI packet
++#define Err_NCSI_Check_RxOwnTimeOut ( 1 << 8 ) // Time out of checking Rx owner bit in NCSI packet
++#define Err_NCSI_Check_ARPOwnTimeOut ( 1 << 9 ) // Time out of checking ARP owner bit in NCSI packet
++#define Err_NCSI_No_PHY ( 1 << 10 ) // Can not find NCSI PHY
++#define Err_NCSI_Channel_Num ( 1 << 11 ) // NCSI Channel Number Mismatch
++#define Err_NCSI_Package_Num ( 1 << 12 ) // NCSI Package Number Mismatch
++#define Err_PHY_TimeOut ( 1 << 13 ) // Time out of read/write/reset PHY register
++#define Err_RXBUF_UNAVA ( 1 << 14 ) // MAC00h[2]:Receiving buffer unavailable
++#define Err_RPKT_LOST ( 1 << 15 ) // MAC00h[3]:Received packet lost due to RX FIFO full
++#define Err_NPTXBUF_UNAVA ( 1 << 16 ) // MAC00h[6]:Normal priority transmit buffer unavailable
++#define Err_TPKT_LOST ( 1 << 17 ) // MAC00h[7]:Packets transmitted to Ethernet lost
++#define Err_DMABufNum ( 1 << 18 ) // DMA Buffer is not enough
++#define Err_IOMargin ( 1 << 19 ) // IO timing margin is not enough
++#define Err_IOMarginOUF ( 1 << 20 ) // IO timing testing out of boundary
++#define Err_MHCLK_Ratio ( 1 << 21 ) // Error setting of MAC AHB bus clock (SCU08[18:16])
++
++#define Check_Des_TxOwnTimeOut ( 1 << 0 ) // Time out of checking Tx owner bit
++#define Check_Des_RxOwnTimeOut ( 1 << 1 ) // Time out of checking Rx owner bit
++#define Check_Des_RxErr ( 1 << 2 ) // Input signal RxErr
++#define Check_Des_OddNibble ( 1 << 3 ) // Nibble bit happen
++#define Check_Des_CRC ( 1 << 4 ) // CRC error of frame
++#define Check_Des_RxFIFOFull ( 1 << 5 ) // Rx FIFO full
++#define Check_Des_FrameLen ( 1 << 6 ) // Frame length mismatch
++
++#define NCSI_LinkFail_Get_Version_ID ( 1 << 0 ) // Time out when Get Version ID
++#define NCSI_LinkFail_Get_Capabilities ( 1 << 1 ) // Time out when Get Capabilities
++#define NCSI_LinkFail_Select_Active_Package ( 1 << 2 ) // Time out when Select Active Package
++#define NCSI_LinkFail_Enable_Set_MAC_Address ( 1 << 3 ) // Time out when Enable Set MAC Address
++#define NCSI_LinkFail_Enable_Broadcast_Filter ( 1 << 4 ) // Time out when Enable Broadcast Filter
++#define NCSI_LinkFail_Enable_Network_TX ( 1 << 5 ) // Time out when Enable Network TX
++#define NCSI_LinkFail_Enable_Channel ( 1 << 6 ) // Time out when Enable Channel
++#define NCSI_LinkFail_Disable_Network_TX ( 1 << 7 ) // Time out when Disable Network TX
++#define NCSI_LinkFail_Disable_Channel ( 1 << 8 ) // Time out when Disable Channel
++
++//---------------------------------------------------------
++// SCU information
++//---------------------------------------------------------
++#if ( AST1010_IOMAP == 1 )
++ #define SCU_BASE AST_SCU_BASE
++#endif
++#if ( AST1010_IOMAP == 2 )
++ #define SCU_BASE 0x0841000
++#endif
++
++#ifndef AST1010_IOMAP
++ #define SCU_BASE 0x1e6e2000
++#endif
++
++#define SCU_48h_AST1010 0x00000200
++#define SCU_48h_AST2300 0x00222255
++
++//#ifdef SLT_DOS
++// #define SCU_80h 0x00000000
++// #define SCU_88h 0x00000000
++// #define SCU_90h 0x00000000
++// #define SCU_74h 0x00000000
++//#else
++// #define SCU_80h 0x0000000f //AST2300[3:0]MAC1~4 PHYLINK
++// #define SCU_88h 0xc0000000 //AST2300[31]MAC1 MDIO, [30]MAC1 MDC
++// #define SCU_90h 0x00000004 //AST2300[2 ]MAC2 MDC/MDIO
++// #define SCU_74h 0x06300000 //AST3000[20]MAC2 MDC/MDIO, [21]MAC2 MII, [25]MAC1 PHYLINK, [26]MAC2 PHYLINK
++//#endif
++
++//---------------------------------------------------------
++// DMA Buffer information
++//---------------------------------------------------------
++#ifdef FPGA
++ #define DRAM_KByteSize ( 56 * 1024 )
++#else
++ #ifdef AST1010_IOMAP
++ #define DRAM_KByteSize ( 3 * 1024 ) // DATA buffer only use 0xB00000 to 0xE00000
++ #else
++ #define DRAM_KByteSize ( 18 * 1024 )
++ #endif
++#endif
++
++#define DMA_BASE ( 0x00100000 + DRAM_MapAdr )
++
++#ifdef Enable_Jumbo
++ #define DMA_PakSize ( 10 * 1024 )
++#else
++ #define DMA_PakSize ( 2 * 1024 ) // The size of one LAN packet
++#endif
++
++#ifdef SelectSimpleBoundary
++ #define DMA_BufSize ( ( ( ( ( DES_NUMBER + 15 ) * DMA_PakSize ) >> 2 ) << 2 ) ) //vary by DES_NUMBER
++#else
++ #define DMA_BufSize (4 + ( ( ( ( DES_NUMBER + 15 ) * DMA_PakSize ) >> 2 ) << 2 ) ) //vary by DES_NUMBER
++#endif
++
++#define DMA_BufNum ( ( DRAM_KByteSize * 1024 ) / ( DMA_BufSize ) ) //vary by DES_NUMBER
++#define GET_DMA_BASE_SETUP ( DMA_BASE )
++#define GET_DMA_BASE(x) ( DMA_BASE + ( ( ( ( x ) % DMA_BufNum ) + 1 ) * DMA_BufSize ) )//vary by DES_NUMBER
++
++#define SEED_START 8
++#define DATA_SEED(seed) ( ( seed ) | (( seed + 1 ) << 16 ) )
++#define DATA_IncVal 0x00020001
++//#define DATA_IncVal 0x01000001 //fail
++//#define DATA_IncVal 0x10000001 //fail
++//#define DATA_IncVal 0x10000000 //fail
++//#define DATA_IncVal 0x80000000 //fail
++//#define DATA_IncVal 0x00000001 //ok
++//#define DATA_IncVal 0x01000100 //ok
++//#define DATA_IncVal 0x01010000 //ok
++//#define DATA_IncVal 0x01010101 //ok
++//#define DATA_IncVal 0x00000101 //ok
++//#define DATA_IncVal 0x00001111 //fail
++//#define DATA_IncVal 0x00000011 //fail
++//#define DATA_IncVal 0x10100101 //fail
++//#define DATA_IncVal 0xfeff0201
++//#define DATA_IncVal 0x00010001
++#define PktByteSize ( ( ( ( ZeroCopy_OFFSET + FRAME_LEN_Cur - 1 ) >> 2 ) + 1) << 2 )
++
++//---------------------------------------------------------
++// Delay (ms)
++//---------------------------------------------------------
++//#define Delay_DesGap 1000 //off
++//#define Delay_DesGap 700 //off
++
++//#define Delay_ChkRxOwn 10
++//#define Delay_ChkTxOwn 10
++#define Delay_CntMax 100000000
++//#define Delay_CntMax 1000
++//#define Delay_CntMax 8465
++//#define Delay_CntMaxIncVal 50000
++#define Delay_CntMaxIncVal 47500
++
++#define Delay_PHYRst 100
++#define Delay_PHYRd 5
++
++#define Delay_SCU 11
++#define Delay_MACRst 1
++#define Delay_MACDump 100
++
++//#define Delay_DES 1
++
++//---------------------------------------------------------
++// Time Out
++//---------------------------------------------------------
++#define TIME_OUT_Des 10000
++#define TIME_OUT_PHY_RW 10000
++#define TIME_OUT_PHY_Rst 10000
++
++//#define TIME_OUT_NCSI 300000
++#define TIME_OUT_NCSI 30000
++
++
++
++//---------------------------------------------------------
++// Chip memory MAP
++//---------------------------------------------------------
++#define LITTLE_ENDIAN_ADDRESS 0
++#define BIG_ENDIAN_ADDRESS 1
++
++typedef struct {
++ ULONG StartAddr;
++ ULONG EndAddr;
++} LittleEndian_Area;
++
++#if ( AST1010_IOMAP == 1 )
++ static const LittleEndian_Area LittleEndianArea[] = {
++ { AST_IO_BASE, (AST_IO_BASE + 0x000FFFFF) },
++ { 0xFFFFFFFF, 0xFFFFFFFF } // End
++ };
++#else
++ static const LittleEndian_Area LittleEndianArea[] = {
++ { 0xFFFFFFFF, 0xFFFFFFFF } // End
++ };
++#endif
++
++// ========================================================
++// For ncsi.c
++
++#define DEF_PACKAGE2NUM 1 // Default value
++#define DEF_CHANNEL2NUM 2 // Default value
++
++typedef struct {
++ unsigned char Package_ID;
++ unsigned char Channel_ID;
++ unsigned long Capabilities_Flags;
++ unsigned long Broadcast_Packet_Filter_Capabilities;
++ unsigned long Multicast_Packet_Filter_Capabilities;
++ unsigned long Buffering_Capabilities;
++ unsigned long AEN_Control_Support;
++ unsigned long PCI_DID_VID;
++ unsigned long ManufacturerID;
++} NCSI_Capability;
++
++#undef GLOBAL
++#ifdef NCSI_C
++#define GLOBAL
++#else
++#define GLOBAL extern
++#endif
++
++GLOBAL NCSI_Capability NCSI_Cap_SLT;
++GLOBAL BYTE number_chl;
++
++GLOBAL char phy_ncsi (void);
++
++// ========================================================
++// For mactest
++
++#undef GLOBAL
++#ifdef MACTEST_C
++#define GLOBAL
++#else
++#define GLOBAL extern
++#endif
++
++GLOBAL ULONG NCSI_DiSChannel;
++
++//
++#ifdef SLT_UBOOT
++#else
++// SLT_DOS
++GLOBAL FILE *fp_log;
++GLOBAL FILE *fp_io;
++#endif
++
++GLOBAL CHAR dlymap[16][16];
++GLOBAL CHAR PrintNCSIEn;
++GLOBAL ULONG ARPNumCnt;
++GLOBAL CHAR FileNameMain[256];
++GLOBAL CHAR FileName[256];
++GLOBAL CHAR ASTChipName[256];
++GLOBAL CHAR LOOP_Str[256];
++GLOBAL BYTE IOTimingBund;
++GLOBAL BYTE ChannelTolNum;
++GLOBAL BYTE PackageTolNum;
++GLOBAL ULONG IOdly_out_reg;
++GLOBAL BYTE IOdly_out_reg_idx;
++GLOBAL ULONG Dat_ULONG;
++GLOBAL ULONG IOdly_incval;
++GLOBAL ULONG IOdly_in_reg;
++GLOBAL BYTE IOdly_in_reg_idx;
++GLOBAL ULONG *wp_lst;
++GLOBAL ULONG *FRAME_LEN;
++GLOBAL ULONG DES_NUMBER;
++GLOBAL ULONG DES_NUMBER_Org;
++GLOBAL int LOOP_MAX;
++GLOBAL ULONG LOOP_CheckNum;
++GLOBAL int Loop;
++GLOBAL ULONG CheckBuf_MBSize;
++GLOBAL ULONG Err_Flag;
++GLOBAL ULONG SCU_f0h_old;
++#ifdef AST1010_IOMAP
++ GLOBAL ULONG SCU_11Ch_old;
++#endif
++GLOBAL ULONG SCU_04h;
++GLOBAL ULONG SCU_90h_old;
++GLOBAL ULONG SCU_7ch_old;
++GLOBAL ULONG MAC_50h;
++GLOBAL ULONG SCU_ach_old;
++GLOBAL ULONG SCU_70h_old;
++GLOBAL ULONG MAC_50h_Speed;
++GLOBAL ULONG SCU_48h_old;
++GLOBAL ULONG SCU_48h_mix;
++GLOBAL ULONG MAC_08h_old;
++GLOBAL ULONG MAC_0ch_old;
++GLOBAL ULONG MAC_40h_old;
++GLOBAL ULONG SCU_08h_old;
++GLOBAL ULONG MAC_PHYBASE;
++GLOBAL ULONG LOOP_MAX_arg;
++GLOBAL BYTE GRun_Mode;
++GLOBAL ULONG GSpeed_idx;
++GLOBAL CHAR GSpeed_sel[3];
++GLOBAL CHAR PHY_ADR;
++GLOBAL CHAR PHY_ADR_arg;
++GLOBAL CHAR PHYName[256];
++GLOBAL ULONG PHY_ID3;
++GLOBAL ULONG PHY_ID2;
++GLOBAL BYTE number_pak;
++GLOBAL BYTE TestMode;
++GLOBAL ULONG IOStr_i;
++GLOBAL BYTE IOTimingBund_arg;
++GLOBAL BYTE GSpeed;
++GLOBAL BYTE GCtrl;
++GLOBAL ULONG UserDVal;
++GLOBAL ULONG H_MAC_BASE;
++GLOBAL ULONG H_TDES_BASE;
++GLOBAL ULONG H_RDES_BASE;
++GLOBAL CHAR Loop_rl[3];
++GLOBAL CHAR IOTiming;
++GLOBAL CHAR LOOP_INFINI;
++GLOBAL CHAR SelectMAC;
++GLOBAL CHAR Enable_SkipChkPHY;
++GLOBAL CHAR Enable_MAC34;
++GLOBAL CHAR IOStrength;
++GLOBAL CHAR DataDelay;
++GLOBAL CHAR SA[6];
++GLOBAL CHAR RxDataEnable;
++GLOBAL CHAR IEEETesting;
++GLOBAL CHAR BurstEnable;
++GLOBAL CHAR MAC_Mode;
++GLOBAL CHAR Enable_MACLoopback;
++GLOBAL CHAR Enable_InitPHY;
++GLOBAL CHAR MAC1_1GEn;
++GLOBAL CHAR MAC2_RMII;
++GLOBAL CHAR Enable_RMII;
++GLOBAL CHAR MAC2_1GEn;
++GLOBAL CHAR TxDataEnable;
++GLOBAL CHAR AST2300_NewMDIO;
++GLOBAL CHAR ASTChipType;
++GLOBAL CHAR Err_Flag_PrintEn;
++GLOBAL CHAR AST2400;
++GLOBAL CHAR AST2300;
++GLOBAL CHAR AST1100;//Different in phy & dram initiation & dram size & RMII
++GLOBAL CHAR AST3200;
++GLOBAL CHAR AST1010;
++GLOBAL SCHAR IOdly_i_min;
++GLOBAL SCHAR IOdly_j_min;
++GLOBAL SCHAR IOdly_i_max;
++GLOBAL SCHAR IOdly_j_max;
++GLOBAL BYTE IOdly_i;
++GLOBAL BYTE IOdly_j;
++GLOBAL BYTE IOdly_in;
++GLOBAL BYTE IOdly_out;
++GLOBAL SCHAR IOdly_in_str;
++GLOBAL BYTE IOdly_in_end;
++GLOBAL BYTE IOdly_out_end;
++GLOBAL BYTE IOdly_out_shf;
++GLOBAL BYTE IOdly_in_shf;
++GLOBAL SCHAR IOdly_out_str;
++GLOBAL BYTE valary[16];
++
++#define MODE_DEDICATED 0x01
++#define MODE_NSCI 0x02
++GLOBAL CHAR ModeSwitch;
++
++#ifdef SLT_UBOOT
++#else
++ GLOBAL time_t timestart;
++#endif
++
++#ifdef SPI_BUS
++ GLOBAL ULONG mmiobase;
++#else
++ // ( USE_P2A | USE_LPC )
++ GLOBAL UCHAR *mmiobase;
++ GLOBAL ULONG ulPCIBaseAddress;
++ GLOBAL ULONG ulMMIOBaseAddress;
++#endif
++
++
++// ========================================================
++// For mac.c
++#undef GLOBAL
++#ifdef MAC_C
++#define GLOBAL
++#else
++#define GLOBAL extern
++#endif
++
++GLOBAL ULONG ARP_data[16];
++GLOBAL ULONG NCSI_LinkFail_Val;
++static const char version_name[] = VER_NAME;
++
++GLOBAL void Debug_delay (void);
++GLOBAL void read_scu (void);
++GLOBAL void Setting_scu (void);
++GLOBAL void PrintMode (void);
++GLOBAL void PrintPakNUm (void);
++GLOBAL void PrintChlNUm (void);
++GLOBAL void PrintTest (void);
++GLOBAL void PrintIOTimingBund (void);
++GLOBAL void PrintSpeed (void);
++GLOBAL void PrintCtrl (void);
++GLOBAL void PrintLoop (void);
++GLOBAL void PrintPHYAdr (void);
++GLOBAL void Finish_Close (void);
++GLOBAL void Calculate_LOOP_CheckNum (void);
++GLOBAL char Finish_Check (int value);
++GLOBAL void init_scu1 (void);
++GLOBAL void init_scu_macrst (void);
++GLOBAL void setup_arp (void);
++GLOBAL void TestingSetup (void);
++GLOBAL void init_scu2 (void);
++GLOBAL void init_scu3 (void);
++GLOBAL void init_mac (ULONG base, ULONG tdexbase, ULONG rdexbase);
++GLOBAL char TestingLoop (ULONG loop_checknum);
++GLOBAL void PrintIO_Line_LOG (void);
++GLOBAL void init_phy (int loop_phy);
++GLOBAL void recov_phy (int loop_phy);
++GLOBAL int FindErr (int value);
++GLOBAL int FindErr_Des (int value);
++GLOBAL void PrintIO_Header (BYTE option);
++GLOBAL void Print_Header (BYTE option);
++GLOBAL void PrintIO_LineS (BYTE option);
++GLOBAL void PrintIO_Line (BYTE option);
++GLOBAL void FPri_ErrFlag (BYTE option);
++
++#ifdef SUPPORT_PHY_LAN9303
++// ========================================================
++// For LAN9303.c
++#undef GLOBAL
++#ifdef LAN9303_C
++#define GLOBAL
++#else
++#define GLOBAL extern
++#endif
++
++GLOBAL void LAN9303(int num, int phy_adr, int speed, int int_loopback);
++#endif // SUPPORT_PHY_LAN9303
++#endif // End COMMINF_H
++
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/DEF_SPI.H b/arch/arm/cpu/arm926ejs/aspeed/DEF_SPI.H
+new file mode 100644
+index 0000000..02353e7
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/DEF_SPI.H
+@@ -0,0 +1,35 @@
++/*
++ * 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 DEF_SPI_H
++#define DEF_SPI_H
++
++#include "TYPEDEF.H"
++#include "SWFUNC.H"
++
++typedef struct _DEVICE_PCI_INFO
++{
++ USHORT usVendorID;
++ USHORT usDeviceID;
++ ULONG ulPCIConfigurationBaseAddress;
++ ULONG ulPhysicalBaseAddress;
++ ULONG ulMMIOBaseAddress;
++ USHORT usRelocateIO;
++} DEVICE_PCI_INFO;
++
++//VIDEO Engine Info
++typedef struct _VIDEO_ENGINE_INFO {
++ USHORT iEngVersion;
++ DEVICE_PCI_INFO VGAPCIInfo;
++} VIDEO_ENGINE_INFO;
++
++BOOLEAN GetDevicePCIInfo (VIDEO_ENGINE_INFO *VideoEngineInfo);
++
++#endif // DEF_SPI_H
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/DRAM_SPI.c b/arch/arm/cpu/arm926ejs/aspeed/DRAM_SPI.c
+new file mode 100644
+index 0000000..fe2b5cf
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/DRAM_SPI.c
+@@ -0,0 +1,78 @@
++/*
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#define DRAM_SPI_C
++static const char ThisFile[] = "DRAM_SPI.c";
++
++#include "SWFUNC.H"
++
++#ifdef SPI_BUS
++#include <stdio.h>
++#include "DEF_SPI.H"
++#include "LIB_SPI.H"
++
++VOID Set_MMIO_Base(ULONG PCI_BASE, ULONG addr)
++{
++ static ULONG MMIO_BASE = -1;
++
++ if(MMIO_BASE != (addr & 0xffff0000)){
++ if(MMIO_BASE == -1){
++ *(ULONG *)(PCI_BASE + 0xF000) = 1;
++ }
++ *(ULONG *)(PCI_BASE + 0xF004) = addr;
++ MMIO_BASE = addr & 0xffff0000;
++ }
++}
++
++VOID MOutbm(ULONG PCI_BASE, ULONG Offset, BYTE Data)
++{
++ Set_MMIO_Base(PCI_BASE, Offset);
++ *(BYTE *)(PCI_BASE + 0x10000 + (Offset & 0xffff)) = Data;
++}
++
++VOID MOutwm(ULONG PCI_BASE, ULONG Offset, USHORT Data)
++{
++ Set_MMIO_Base(PCI_BASE, Offset);
++ *(USHORT *)(PCI_BASE + 0x10000 + (Offset & 0xffff)) = Data;
++}
++
++VOID MOutdwm(ULONG PCI_BASE, ULONG Offset, ULONG Data)
++{
++ Set_MMIO_Base(PCI_BASE, Offset);
++ *(ULONG *)(PCI_BASE + 0x10000 + (Offset & 0xffff)) = Data;
++}
++
++BYTE MInbm(ULONG PCI_BASE, ULONG Offset)
++{
++ BYTE jData;
++
++ Set_MMIO_Base(PCI_BASE, Offset);
++ jData = *(BYTE *)(PCI_BASE + 0x10000 + (Offset & 0xffff));
++ return(jData);
++}
++
++USHORT MInwm(ULONG PCI_BASE, ULONG Offset)
++{
++ USHORT usData;
++
++ Set_MMIO_Base(PCI_BASE, Offset);
++ usData = *(USHORT *)(PCI_BASE + 0x10000 + (Offset & 0xffff));
++ return(usData);
++}
++
++ULONG MIndwm(ULONG PCI_BASE, ULONG Offset)
++{
++ ULONG ulData;
++
++ Set_MMIO_Base(PCI_BASE, Offset);
++ ulData = *(ULONG *)(PCI_BASE + 0x10000 + (Offset & 0xffff));
++ return(ulData);
++}
++#endif // End SPI_BUS
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/IO.H b/arch/arm/cpu/arm926ejs/aspeed/IO.H
+new file mode 100644
+index 0000000..5fe03f0
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/IO.H
+@@ -0,0 +1,36 @@
++/*
++ * 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 IO_H
++#define IO_H
++
++#include "SWFUNC.H"
++
++//
++// Macro
++//
++#if defined(LinuxAP)
++ #define delay(val) usleep(val*1000)
++ #define ob(p,d) outb(d,p)
++ #define ib(p) inb(p)
++#else
++ #define ob(p,d) outp(p,d)
++ #define ib(p) inp(p)
++#endif
++
++#ifdef USE_LPC
++void open_aspeed_sio_password(void);
++void enable_aspeed_LDU(BYTE jldu_number);
++int findlpcport(BYTE jldu_number);
++#endif
++
++void WriteSOC_DD(ULONG addr, ULONG data);
++ULONG ReadSOC_DD(ULONG addr);
++#endif
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/IO.c b/arch/arm/cpu/arm926ejs/aspeed/IO.c
+new file mode 100644
+index 0000000..86e9918
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/IO.c
+@@ -0,0 +1,356 @@
++/*
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#define IO_C
++static const char ThisFile[] = "IO.c";
++
++#include "SWFUNC.H"
++
++#if defined(LinuxAP)
++ #include <stdio.h>
++ #include <string.h>
++ #include <stdlib.h>
++ #include <stdarg.h>
++ #include <unistd.h>
++ #include <string.h>
++ #include <fcntl.h>
++ #include <pthread.h>
++ #include <sys/mman.h>
++ #include <sys/io.h>
++#endif
++#ifdef SLT_UBOOT
++ #include <common.h>
++ #include <command.h>
++ #include <post.h>
++ #include <malloc.h>
++ #include <net.h>
++ #include <COMMINF.H>
++#endif
++#ifdef SLT_DOS
++ #include <stdlib.h>
++ #include <stdio.h>
++ #include <time.h>
++ #include <conio.h>
++ #include <dos.h>
++ #include <mem.h>
++ #include "TYPEDEF.H"
++ #include "LIB.H"
++ #include "COMMINF.H"
++#endif
++
++#include "TYPEDEF.H"
++#include "IO.H"
++#include "LIB_SPI.H"
++
++#ifdef SPI_BUS
++#endif
++#ifdef USE_LPC
++ USHORT usLPCPort;
++#endif
++#ifdef USE_P2A
++#endif
++
++#ifdef USE_LPC
++//------------------------------------------------------------
++// LPC access
++//------------------------------------------------------------
++void open_aspeed_sio_password(void)
++{
++ ob (usLPCPort, 0xaa);
++
++ ob (usLPCPort, 0xa5);
++ ob (usLPCPort, 0xa5);
++}
++
++//------------------------------------------------------------
++void close_aspeed_sio_password(void)
++{
++ ob (usLPCPort, 0xaa);
++}
++
++//------------------------------------------------------------
++void enable_aspeed_LDU(BYTE jldu_number)
++{
++ ob (usLPCPort, 0x07);
++ ob ((usLPCPort + 1), jldu_number);
++ ob (usLPCPort, 0x30);
++ ob ((usLPCPort + 1), 0x01);
++}
++
++//------------------------------------------------------------
++void disable_aspeed_LDU(BYTE jldu_number)
++{
++ ob (usLPCPort, 0x07);
++ ob ((usLPCPort + 1), jldu_number);
++ ob (usLPCPort, 0x30);
++ ob ((usLPCPort + 1), 0x00);
++}
++
++//------------------------------------------------------------
++/*
++ulAddress = AHB address
++jmode = 0: byte mode
++ 1: word mode
++ 2: dword mode
++*/
++static ULONG lpc_read (ULONG ulAddress, BYTE jmode)
++{
++ ULONG uldata = 0;
++ ULONG ultemp = 0;
++ BYTE jtemp;
++
++ //Write Address
++ ob ( usLPCPort, 0xf0);
++ ob ( (usLPCPort + 1 ), ((ulAddress & 0xff000000) >> 24));
++ ob ( usLPCPort, 0xf1);
++ ob ( (usLPCPort + 1) , ((ulAddress & 0x00ff0000) >> 16));
++ ob ( usLPCPort, 0xf2);
++ ob ( (usLPCPort + 1), ((ulAddress & 0x0000ff00) >> 8));
++ ob ( usLPCPort, 0xf3);
++ ob ( (usLPCPort + 1), ulAddress & 0xff);
++
++ //Write Mode
++ ob (usLPCPort, 0xf8);
++ jtemp = ib ((usLPCPort + 1));
++ ob ((usLPCPort + 1), ((jtemp & 0xfc) | jmode));
++
++ //Fire
++ ob (usLPCPort, 0xfe);
++ jtemp = ib ((usLPCPort + 1));
++
++ //Get Data
++ switch ( jmode )
++ {
++ case 0:
++ ob (usLPCPort, 0xf7);
++ ultemp = ib ((usLPCPort + 1));
++ uldata |= (ultemp);
++ break;
++
++ case 1:
++ ob (usLPCPort, 0xf6);
++ ultemp = ib ((usLPCPort + 1));
++ uldata |= (ultemp << 8);
++ ob (usLPCPort, 0xf7);
++ ultemp = ib ((usLPCPort + 1));
++ uldata |= (ultemp << 0);
++ break;
++
++ case 2:
++ ob (usLPCPort, 0xf4);
++ ultemp = ib ((usLPCPort + 1));
++ uldata |= (ultemp << 24);
++ ob (usLPCPort, 0xf5);
++ ultemp = ib ((usLPCPort + 1));
++ uldata |= (ultemp << 16);
++ ob (usLPCPort, 0xf6);
++ ultemp = ib ((usLPCPort + 1));
++ uldata |= (ultemp << 8);
++ ob (usLPCPort, 0xf7);
++ ultemp = ib ((usLPCPort + 1));
++ uldata |= ultemp;
++ break;
++ } // End switch ( jmode )
++
++ return uldata;
++} // End static ULONG lpc_read (ULONG ulAddress, BYTE jmode)
++
++//------------------------------------------------------------
++static void lpc_write (ULONG ulAddress, ULONG uldata, BYTE jmode)
++{
++ BYTE jtemp;
++
++ //Write Address
++ ob ( usLPCPort, 0xf0);
++ ob ((usLPCPort + 1), ((ulAddress & 0xff000000) >> 24));
++ ob ( usLPCPort, 0xf1);
++ ob ((usLPCPort + 1), ((ulAddress & 0x00ff0000) >> 16));
++ ob ( usLPCPort, 0xf2);
++ ob ((usLPCPort + 1), ((ulAddress & 0x0000ff00) >> 8));
++ ob ( usLPCPort, 0xf3);
++ ob ((usLPCPort + 1), ulAddress & 0xff);
++
++ //Write Data
++ switch ( jmode )
++ {
++ case 0:
++ ob ( usLPCPort, 0xf7);
++ ob ((usLPCPort + 1), (uldata & 0xff));
++ break;
++ case 1:
++ ob ( usLPCPort, 0xf6);
++ ob ((usLPCPort + 1), ((uldata & 0xff00) >> 8));
++ ob ( usLPCPort, 0xf7);
++ ob ((usLPCPort + 1), (uldata & 0x00ff));
++ break;
++ case 2:
++ ob ( usLPCPort, 0xf4);
++ ob ((usLPCPort + 1), ((uldata & 0xff000000) >> 24));
++ ob ( usLPCPort, 0xf5);
++ ob ((usLPCPort + 1), ((uldata & 0x00ff0000) >> 16));
++ ob ( usLPCPort, 0xf6);
++ ob ((usLPCPort + 1), ((uldata & 0x0000ff00) >> 8));
++ ob ( usLPCPort, 0xf7);
++ ob ((usLPCPort + 1), uldata & 0xff);
++ break;
++ } // End switch ( jmode )
++
++ //Write Mode
++ ob (usLPCPort, 0xf8);
++ jtemp = ib ((usLPCPort + 1));
++ ob ((usLPCPort + 1), ((jtemp & 0xfc) | jmode));
++
++ //Fire
++ ob (usLPCPort, 0xfe);
++ ob ((usLPCPort + 1), 0xcf);
++
++} // End static void lpc_write (ULONG ulAddress, ULONG uldata, BYTE jmode)
++
++//------------------------------------------------------------
++static USHORT usLPCPortList[] = {0x2e, 0x4e, 0xff};
++int findlpcport(BYTE jldu_number)
++{
++ USHORT *jLPCPortPtr;
++ ULONG ulData;
++
++ jLPCPortPtr = usLPCPortList;
++ while (*(USHORT *)(jLPCPortPtr) != 0xff )
++ {
++ usLPCPort = *(USHORT *)(jLPCPortPtr++);
++
++ open_aspeed_sio_password();
++ enable_aspeed_LDU(0x0d);
++
++ ulData = lpc_read(0x1e6e207c, 2);
++
++ if ( (ulData != 0x00000000) &&
++ (ulData != 0xFFFFFFFF) )
++ {
++ printf("Find LPC IO port at 0x%2x \n", usLPCPort);
++ return 1;
++ }
++
++ disable_aspeed_LDU(0x0d);
++ close_aspeed_sio_password();
++ }
++
++ //printf("[Error] Fail to find proper LPC IO Port \n");
++ return 0;
++}
++#endif // End ifdef USE_LPC
++
++#ifdef USE_P2A
++//------------------------------------------------------------
++// A2P Access
++//------------------------------------------------------------
++void mm_write (ULONG addr, ULONG data, BYTE jmode)
++{
++ *(ULONG *) (mmiobase + 0xF004) = (ULONG) ((addr) & 0xFFFF0000);
++ *(ULONG *) (mmiobase + 0xF000) = (ULONG) 0x00000001;
++
++ switch ( jmode )
++ {
++ case 0:
++ *(BYTE *) (mmiobase + 0x10000 + ((addr) & 0x0000FFFF)) = (BYTE) data;
++ break;
++ case 1:
++ *(USHORT *) (mmiobase + 0x10000 + ((addr) & 0x0000FFFF)) = (USHORT) data;
++ break;
++ case 2:
++ default:
++ *(ULONG *) (mmiobase + 0x10000 + ((addr) & 0x0000FFFF)) = data;
++ break;
++ } //switch
++}
++
++//------------------------------------------------------------
++ULONG mm_read (ULONG addr, BYTE jmode)
++{
++ *(ULONG *) (mmiobase + 0xF004) = (ULONG) ((addr) & 0xFFFF0000);
++ *(ULONG *) (mmiobase + 0xF000) = (ULONG) 0x00000001;
++ switch (jmode)
++ {
++ case 0:
++ return ( *(BYTE *) (mmiobase + 0x10000 + ((addr) & 0x0000FFFF)) );
++ break;
++ case 1:
++ return ( *(USHORT *) (mmiobase + 0x10000 + ((addr) & 0x0000FFFF)) );
++ break;
++ default:
++ case 2:
++ return ( *(ULONG *) (mmiobase + 0x10000 + ((addr) & 0x0000FFFF)) );
++ break;
++ } //switch
++
++ return 0;
++}
++#endif // End ifdef USE_P2A
++
++//------------------------------------------------------------
++// General Access API
++//------------------------------------------------------------
++#ifdef SLT_UBOOT
++BYTE Check_BEorLN ( ULONG chkaddr )
++{
++ BYTE ret = BIG_ENDIAN_ADDRESS;
++ BYTE i = 0;
++
++ do {
++ if ( LittleEndianArea[i].StartAddr == LittleEndianArea[i].EndAddr )
++ break;
++
++ if ( ( LittleEndianArea[i].StartAddr <= chkaddr ) &&
++ ( LittleEndianArea[i].EndAddr >= chkaddr ) ) {
++ ret = LITTLE_ENDIAN_ADDRESS;
++ break;
++ }
++ i++;
++ } while ( 1 );
++
++ return ret;
++}
++#endif
++
++void WriteSOC_DD(ULONG addr, ULONG data)
++{
++#ifdef SLT_UBOOT
++ if ( Check_BEorLN( addr ) == BIG_ENDIAN_ADDRESS )
++ *(volatile unsigned long *)(addr) = cpu_to_le32(data);
++ else
++ *(volatile unsigned long *)(addr) = data;
++#else
++ #ifdef USE_LPC
++ lpc_write(addr, data, 2);
++ #endif
++ #ifdef USE_P2A
++ mm_write(addr, data, 2);
++ #endif
++#endif
++}
++
++//------------------------------------------------------------
++ULONG ReadSOC_DD(ULONG addr)
++{
++#ifdef SLT_UBOOT
++ if ( Check_BEorLN( addr ) == BIG_ENDIAN_ADDRESS )
++ return le32_to_cpu(*(volatile unsigned long *) (addr));
++ else
++ return (*(volatile unsigned long *) (addr));
++#else
++ #ifdef USE_LPC
++ return (lpc_read(addr, 2));
++ #endif
++ #ifdef USE_P2A
++ return (mm_read(addr, 2));
++ #endif
++#endif
++ return 0;
++}
++
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/LAN9303.c b/arch/arm/cpu/arm926ejs/aspeed/LAN9303.c
+new file mode 100644
+index 0000000..498d4fd
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/LAN9303.c
+@@ -0,0 +1,525 @@
++/*
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#define LAN9303_C
++static const char ThisFile[] = "LAN9303.c";
++
++#include "SWFUNC.H"
++#ifdef SLT_UBOOT
++ #include <COMMINF.H>
++ #include <MAC.H>
++ #include <IO.H>
++#endif
++
++#ifdef SLT_DOS
++ #include "COMMINF.H"
++ #include <stdlib.h>
++ #include "IO.H"
++#endif
++
++#ifdef SUPPORT_PHY_LAN9303
++//#define LAN9303M
++#define I2C_Debug 0
++#define Print_DWRW 0
++#define Print_PHYRW 0
++#define I2C_TIMEOUT 10000000
++
++ULONG devbase;
++ULONG busnum;
++ULONG byte;
++ULONG data_rd;
++
++//------------------------------------------------------------
++// Basic
++//------------------------------------------------------------
++void actime(ULONG ac1, ULONG ac2, ULONG *fact, ULONG *ckh, ULONG *ckl)
++{
++ static int divcnt;
++
++ ac1 = ac1 * 50 + 1;
++ ac2 = ac2 * 50 + 1;
++
++ divcnt = 0;
++ while (ac1 > 8 || ac2 > 8) {
++ divcnt++;
++ ac1 >>= 1;
++ ac2 >>= 1;
++ }
++
++ if (ac1 < 2 ) ac1 = 2;
++ if (ac2 < 2 ) ac2 = 2;
++ if (ac1 > ac2) ac2 = 1;
++ else ac1 += 1;
++
++#ifdef PRINT_MSG
++ printf("Divcnt = %d, ckdiv = %d, ckh = %d, ckl = %d\n",(1<<divcnt)*(ac1+ac2),divcnt,ac1-1,ac2-1);
++ printf("CKH = %d us, CKL = %d us\n",(1<<divcnt)*ac1/50,(1<<divcnt)*ac2/50);
++#endif
++
++ *fact = divcnt;
++ *ckh = ac1 - 1;
++ *ckl = ac2 - 1;
++}
++
++//------------------------------------------------------------
++ULONG PollStatus()
++{
++ static ULONG status;
++ static ULONG cnt = 0;
++
++ do {
++ status = ReadSOC_DD( devbase + 0x14 ) & 0xff;
++
++ if ( ++cnt > I2C_TIMEOUT ) {
++ printf("\nWait1 Timeout at bus %d!\n", busnum);
++ printf("Status 14 = %08x\n", ReadSOC_DD(devbase + 0x14));
++ exit(0);
++ }
++ } while (status != 0);
++
++ cnt = 0;
++ do {
++ status = ReadSOC_DD( devbase + 0x10 );
++ if ( ++cnt > I2C_TIMEOUT ) {
++ printf("\nWait2 Timeout at bus %d!\n", busnum);
++ printf("Status 14 = %08x\n", ReadSOC_DD(devbase + 0x14));
++ exit(0);
++ }
++ } while (status == 0);
++
++ WriteSOC_DD( devbase + 0x10, status );
++
++ return(status);
++}
++
++
++//------------------------------------------------------------
++ULONG writeb(ULONG start, ULONG data, ULONG stop)
++{
++ WriteSOC_DD( devbase + 0x20, data);
++ WriteSOC_DD( devbase + 0x14, 0x02 | start | (stop << 5) );
++ return(PollStatus());
++}
++
++//------------------------------------------------------------
++ULONG readb(ULONG last, ULONG stop)
++{
++ static ULONG data;
++
++ WriteSOC_DD( devbase + 0x14, 0x08 | (last << 4) | (stop << 5) );
++ data = PollStatus();
++
++ if (data & 0x4) {
++ data = ReadSOC_DD( devbase + 0x20 );
++ return(data >> 8);
++ }
++ else {
++ return(-1);
++ }
++}
++
++//------------------------------------------------------------
++void Initial(ULONG base, ULONG ckh, ULONG ckl)
++{
++ static ULONG ackh;
++ static ULONG ackl;
++ static ULONG divx;
++
++ actime(ckh, ckl, &divx, &ackh, &ackl);
++ WriteSOC_DD(base + 0x00, 0x1);
++ if (ReadSOC_DD(base + 0x00) != 0x1) {
++ printf("Controller initial fail : %x\n",base);
++ exit(0);
++ }
++ WriteSOC_DD(base + 0x04, 0x77700360 | (ackh << 16) | (ackl << 12) | divx);
++ WriteSOC_DD(base + 0x08, 0x0);
++ WriteSOC_DD(base + 0x0c, 0x0);
++ WriteSOC_DD(base + 0x10, 0xffffffff);
++ WriteSOC_DD(base + 0x14, 0x00);
++ WriteSOC_DD(base + 0x1C, 0xff0000);
++ WriteSOC_DD(base + 0x20, 0x00);
++}
++
++//------------------------------------------------------------
++void print_status(ULONG status)
++{
++ if ( status & 0x02 ) printf( "Device NAK\n" );
++ if ( status & 0x08 ) printf( "Arbitration Loss\n" );
++ if ( status & 0x10 ) printf( "STOP\n" );
++ if ( status & 0x20 ) printf( "Abnormal STOP\n" );
++ if ( status & 0x40 ) printf( "SCL Low timeout\n" );
++}
++
++//------------------------------------------------------------
++void readme()
++{
++ printf("\nVersion:%s\n", version_name);
++#ifdef LAN9303M
++ printf("LAN9303M [bus] [vir_PHY_adr] [speed] [func]\n");
++#else
++ printf("LAN9303 [bus] [vir_PHY_adr] [speed] [func]\n" );
++#endif
++ printf("[bus] | 1~14: I2C bus number\n" );
++ printf("[vir_PHY_adr] | 0~1: virtual PHY address\n" );
++ printf("[speed] | 1: 100M\n" );
++ printf(" | 2: 10 M\n" );
++ printf("[func] | 0: external loopback\n" );
++ printf(" | 1: internal loopback\n" );
++}
++
++//------------------------------------------------------------
++void quit()
++{
++ WriteSOC_DD( devbase + 0x14, 0x20 );
++ PollStatus();
++ readme();
++}
++
++//------------------------------------------------------------
++// Double-Word Read/Write
++//------------------------------------------------------------
++ULONG I2C_DWRead(ULONG adr)
++{
++ static ULONG status;
++ int i;
++
++ Initial(devbase, 10, 10);
++
++ if ( Print_DWRW )
++ printf("RAdr %02x: ", adr);
++
++ status = writeb( 1, LAN9303_I2C_ADR, 0 );
++ if ( I2C_Debug )
++ printf("R1W[%02x]%02x ", status, LAN9303_I2C_ADR);
++
++ if ( status != 0x1 ) {
++ print_status(status);
++ quit();
++ exit(0);
++ }
++
++ status = writeb(0, adr, 0);
++ if ( I2C_Debug )
++ printf("R2W[%02x]%02x ", status, adr);
++ if ( !(status & 0x1) ) {
++ print_status(status);
++ quit();
++ exit(0);
++ }
++
++ status = writeb(1, LAN9303_I2C_ADR | 0x1, 0);
++ if ( I2C_Debug )
++ printf("R3W[%02x]%02x ", status, LAN9303_I2C_ADR | 0x1);
++ if ( status != 0x1 ) {
++ print_status(status);
++ quit();
++ exit(0);
++ }
++
++ if ( I2C_Debug )
++ printf("R4");
++
++ data_rd = 0;
++ for (i = 24; i >= 0; i-=8) {
++ if (i == 0) byte = readb(1, 1);
++ else byte = readb(0, 0);
++
++ if ( I2C_Debug )
++ printf("%02x ", byte);
++ data_rd = data_rd | (byte << i);
++ }
++
++ if ( Print_DWRW )
++ printf("%08x\n", data_rd);
++
++ return (data_rd);
++} // End ULONG I2C_DWRead(ULONG adr)
++
++//------------------------------------------------------------
++void I2C_DWWrite(ULONG adr, ULONG dwdata)
++{
++ static ULONG status;
++ int i;
++ ULONG endx;
++
++ Initial(devbase, 10, 10);
++ if (Print_DWRW)
++ printf("WAdr %02x: ", adr);
++
++ status = writeb(1, LAN9303_I2C_ADR, 0);
++ if ( I2C_Debug )
++ printf("W1[%02x]%02x ", status, LAN9303_I2C_ADR);
++ if ( status != 0x1 ) {
++ print_status(status);
++ quit();
++ exit(0);
++ }
++ status = writeb(0, adr, 0);
++ if ( I2C_Debug )
++ printf("W2[%02x]%02x ", status, adr);
++ if ( !(status & 0x1) ) {
++ print_status(status);
++ quit();
++ exit(0);
++ }
++
++ if (I2C_Debug)
++ printf("W3");
++ endx = 0;
++ for (i = 24; i >= 0; i-=8) {
++ if (i == 0)
++ endx = 1;
++ byte = (dwdata >> i) & 0xff;
++ status = writeb(0, byte, endx);
++
++ if (I2C_Debug)
++ printf("[%02x]%02x ", status, byte);
++ if (!(status & 0x1)) {
++ print_status(status);
++ quit();
++ exit(0);
++ }
++ }
++
++ if (Print_DWRW) printf("%08x\n", dwdata);
++} // End void I2C_DWWrite(ULONG adr, ULONG dwdata)
++
++//------------------------------------------------------------
++// PHY Read/Write
++//------------------------------------------------------------
++ULONG LAN9303_PHY_Read(ULONG phy_adr, ULONG reg_adr)
++{
++ static ULONG data_rd;
++
++ I2C_DWWrite(0x2a, ((phy_adr & 0x1f) << 11) | ((reg_adr & 0x1f) << 6));//[0A8h]PMI_ACCESS
++ do {
++ data_rd = I2C_DWRead (0x2a);
++ } while(data_rd & 0x00000001);//[0A8h]PMI_ACCESS
++
++ data_rd = I2C_DWRead (0x29);//[0A4h]PMI_DATA
++ if (Print_PHYRW)
++ printf("PHY:%2d, Reg:%2d, Data:%08x\n", phy_adr, reg_adr, data_rd);
++
++ return(data_rd);
++}
++
++//------------------------------------------------------------
++void LAN9303_PHY_Write(ULONG phy_adr, ULONG reg_adr, ULONG data_wr)
++{
++ static ULONG data_rd;
++
++ I2C_DWWrite(0x29, data_wr);//[0A4h]PMI_DATA
++
++ I2C_DWWrite(0x2a, ((phy_adr & 0x1f) << 11) | ((reg_adr & 0x1f) << 6) | 0x2);//[0A8h]PMI_ACCESS
++ do {
++ data_rd = I2C_DWRead (0x2a);
++ } while(data_rd & 0x00000001);//[0A8h]PMI_ACCESS
++}
++
++//------------------------------------------------------------
++ULONG LAN9303_PHY_Read_WD(ULONG data_ctl)
++{
++ static ULONG data_rd;
++
++ I2C_DWWrite(0x2a, data_ctl);//[0A8h]PMI_ACCESS
++ do {
++ data_rd = I2C_DWRead (0x2a);
++ } while(data_rd & 0x00000001);//[0A8h]PMI_ACCESS
++
++ data_rd = I2C_DWRead (0x29);//[0A4h]PMI_DATA
++ if (Print_PHYRW)
++ printf("WD Data:%08x\n", data_ctl);
++
++ return(data_rd);
++}
++
++//------------------------------------------------------------
++void LAN9303_PHY_Write_WD(ULONG data_ctl, ULONG data_wr)
++{
++ static ULONG data_rd;
++
++ I2C_DWWrite( 0x29, data_wr ); //[0A4h]PMI_DATA
++ I2C_DWWrite( 0x2a, data_ctl ); //[0A8h]PMI_ACCESS
++ do {
++ data_rd = I2C_DWRead (0x2a);
++ } while(data_rd & 0x00000001); //[0A8h]PMI_ACCESS
++}
++
++//------------------------------------------------------------
++// Virtual PHY Read/Write
++//------------------------------------------------------------
++ULONG LAN9303_VirPHY_Read(ULONG reg_adr)
++{
++ static ULONG data_rd;
++
++ data_rd = I2C_DWRead (0x70+reg_adr);//[1C0h]
++ if ( Print_PHYRW )
++ printf("VirPHY Reg:%2d, Data:%08x\n", reg_adr, data_rd);
++
++ return(data_rd);
++}
++
++//------------------------------------------------------------
++void LAN9303_VirPHY_Write(ULONG reg_adr, ULONG data_wr)
++{
++ I2C_DWWrite(0x70+reg_adr, data_wr);//[1C0h]
++}
++
++//------------------------------------------------------------
++void LAN9303_VirPHY_RW(ULONG reg_adr, ULONG data_clr, ULONG data_set)
++{
++ I2C_DWWrite(0x70+reg_adr, (LAN9303_VirPHY_Read(reg_adr) & (~data_clr)) | data_set);//[1C0h]
++}
++
++//------------------------------------------------------------
++// PHY Read/Write
++//------------------------------------------------------------
++ULONG LAN9303_Read(ULONG adr)
++{
++ static ULONG data_rd;
++
++ I2C_DWWrite(0x6c, 0xc00f0000 | adr & 0xffff);//[1B0h]SWITCH_CSR_CMD
++ do {
++ data_rd = I2C_DWRead (0x6c);
++ } while(data_rd & 0x80000000);//[1B0h]SWITCH_CSR_CMD
++
++ return(I2C_DWRead (0x6b));//[1ACh]SWITCH_CSR_DATA
++}
++
++//------------------------------------------------------------
++void LAN9303_Write(ULONG adr, ULONG data)
++{
++ static ULONG data_rd;
++
++ I2C_DWWrite(0x6b, data);//[1ACh]SWITCH_CSR_DATA
++ I2C_DWWrite(0x6c, 0x800f0000 | adr & 0xffff);//[1B0h]SWITCH_CSR_CMD
++
++ do {
++ data_rd = I2C_DWRead (0x6c);
++ } while(data_rd & 0x80000000);//[1B0h]SWITCH_CSR_CMD
++}
++
++//------------------------------------------------------------
++void LAN9303(int num, int phy_adr, int speed, int int_loopback)
++{
++ static ULONG data_rd;
++
++ //------------------------------------------------------------
++ // I2C Initial
++ //------------------------------------------------------------
++ busnum = num;
++ if (busnum <= 7) devbase = 0x1E78A000 + ( busnum * 0x40);
++ else devbase = 0x1E78A300 + ((busnum-8) * 0x40);
++ Initial(devbase, 10, 10);
++
++ //------------------------------------------------------------
++ // LAN9303 Register Setting
++ //------------------------------------------------------------
++ printf("----> Start\n");
++ if (int_loopback == 0) {
++ //Force Speed & external loopback
++ if (speed == 1) { //100M
++ LAN9303_VirPHY_RW( 0, 0xffff, 0x2300 ); //adr clr set //VPHY_BASIC_CTRL
++ LAN9303_VirPHY_RW( 11, 0xffff, 0x2300 ); //adr clr set //P1_MII_BASIC_CONTROL
++ LAN9303_PHY_Write( phy_adr + 1, 0, 0x2300 );
++ LAN9303_PHY_Write( phy_adr + 2, 0, 0x2300 );
++ }
++ else {
++ LAN9303_VirPHY_RW( 0, 0xffff, 0x0100 ); //adr clr set //VPHY_BASIC_CTRL
++ LAN9303_VirPHY_RW( 11, 0xffff, 0x0100 ); //adr clr set //P1_MII_BASIC_CONTROL
++ LAN9303_PHY_Write( phy_adr + 1, 0, 0x0100);
++ LAN9303_PHY_Write( phy_adr + 2, 0, 0x0100);
++ }
++
++ LAN9303_Write( 0x180c, 0x00000001 ); // SWE_VLAN_WR_DATA
++ LAN9303_Write( 0x180b, 0x00000010 ); // SWE_VLAN_CMD
++ do {data_rd = LAN9303_Read (0x1810);} while(data_rd & 0x1);
++
++ LAN9303_Write( 0x180c, 0x00000002 ); // SWE_VLAN_WR_DATA
++ LAN9303_Write( 0x180b, 0x00000011 ); // SWE_VLAN_CMD
++ do {data_rd = LAN9303_Read (0x1810);} while(data_rd & 0x1);
++
++ LAN9303_Write( 0x180c, 0x00000003 ); // SWE_VLAN_WR_DATA
++ LAN9303_Write( 0x180b, 0x00000012 ); // SWE_VLAN_CMD
++ do {data_rd = LAN9303_Read (0x1810);} while(data_rd & 0x1);
++
++#ifdef LAN9303M
++ LAN9303_Write( 0x180c, 0x00022001 ); // SWE_VLAN_WR_DATA
++ LAN9303_Write( 0x180b, 0x00000000 ); // SWE_VLAN_CMD
++ do {data_rd = LAN9303_Read (0x1810);} while(data_rd & 0x1);
++
++ LAN9303_Write( 0x180c, 0x00024002 ); // SWE_VLAN_WR_DATA
++ LAN9303_Write( 0x180b, 0x00000001 ); // SWE_VLAN_CMD
++ do {data_rd = LAN9303_Read (0x1810);} while(data_rd & 0x1);
++
++ LAN9303_Write( 0x180c, 0x0002a003 ); // SWE_VLAN_WR_DATA
++ LAN9303_Write( 0x180b, 0x00000002 ); // SWE_VLAN_CMD
++ do {data_rd = LAN9303_Read (0x1810);} while(data_rd & 0x1);
++#else
++ LAN9303_Write( 0x180c, 0x0002a001 ); // SWE_VLAN_WR_DATA
++ LAN9303_Write( 0x180b, 0x00000000 ); // SWE_VLAN_CMD
++ do {data_rd = LAN9303_Read (0x1810);} while(data_rd & 0x1);
++
++ LAN9303_Write( 0x180c, 0x0000a002 ); // SWE_VLAN_WR_DATA
++ LAN9303_Write( 0x180b, 0x00000001 ); // SWE_VLAN_CMD
++ do {data_rd = LAN9303_Read (0x1810);} while(data_rd & 0x1);
++
++ LAN9303_Write( 0x180c, 0x00022003 ); // SWE_VLAN_WR_DATA
++ LAN9303_Write( 0x180b, 0x00000002 ); // SWE_VLAN_CMD
++ do {data_rd = LAN9303_Read (0x1810);} while(data_rd & 0x1);
++#endif
++ LAN9303_Write( 0x1840, 0x00000007);
++ }
++ else if ( int_loopback == 1 ) {
++ //Force Speed & internal loopback
++ if ( speed == 1 ) {
++ //100M
++ LAN9303_VirPHY_RW( 0, 0xffff, 0x6300 ); // adr clr set //VPHY_BASIC_CTRL
++ LAN9303_VirPHY_RW( 11, 0xffff, 0x6300 ); // adr clr set //P1_MII_BASIC_CONTROL
++ LAN9303_PHY_Write( phy_adr + 1, 0, 0x6300 );
++ LAN9303_PHY_Write( phy_adr + 2, 0, 0x6300 );
++ }
++ else {
++ LAN9303_VirPHY_RW( 0, 0xffff, 0x4100 ); // adr clr set //VPHY_BASIC_CTRL
++ LAN9303_VirPHY_RW( 11, 0xffff, 0x4100 ); // adr clr set //P1_MII_BASIC_CONTROL
++ LAN9303_PHY_Write( phy_adr + 1, 0, 0x4100 );
++ LAN9303_PHY_Write( phy_adr + 2, 0, 0x4100 );
++ }
++ }
++ else {
++ //Force Speed
++ if (speed == 1) {
++ //100M
++ LAN9303_VirPHY_RW( 0, 0xffff, 0x2300 ); // adr clr set //VPHY_BASIC_CTRL
++ LAN9303_VirPHY_RW( 11, 0xffff, 0x2300 ); // adr clr set //P1_MII_BASIC_CONTROL
++ LAN9303_PHY_Write( phy_adr + 1, 0, 0x2300 );
++ LAN9303_PHY_Write( phy_adr + 2, 0, 0x2300 );
++ }
++ else {
++ LAN9303_VirPHY_RW( 0, 0xffff, 0x0100 ); // adr clr set //VPHY_BASIC_CTRL
++ LAN9303_VirPHY_RW( 11, 0xffff, 0x0100 ); // adr clr set //P1_MII_BASIC_CONTROL
++ LAN9303_PHY_Write( phy_adr + 1, 0, 0x0100 );
++ LAN9303_PHY_Write( phy_adr + 2, 0, 0x0100 );
++ }
++#ifdef LAN9303M
++#else
++ if (int_loopback == 3) {
++ //[LAN9303]IEEE measurement
++ data_rd = LAN9303_PHY_Read(phy_adr+1, 27);//PHY_SPECIAL_CONTROL_STAT_IND_x
++ LAN9303_PHY_Write(phy_adr+1, 27, (data_rd & 0x9fff) | 0x8000);//PHY_SPECIAL_CONTROL_STAT_IND_x
++
++ data_rd = LAN9303_PHY_Read(phy_adr+2, 27);//PHY_SPECIAL_CONTROL_STAT_IND_x
++ LAN9303_PHY_Write(phy_adr+2, 27, (data_rd & 0x9fff) | 0x8000);//PHY_SPECIAL_CONTROL_STAT_IND_x
++ }
++#endif
++ } // End if (int_loopback == 0)
++} // End void LAN9303(int num, int phy_adr, int speed, int int_loopback)
++#endif // SUPPORT_PHY_LAN9303
++
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/LIB.H b/arch/arm/cpu/arm926ejs/aspeed/LIB.H
+new file mode 100644
+index 0000000..a7c61dd
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/LIB.H
+@@ -0,0 +1,37 @@
++/*
++ * 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 LIB_H
++#define LIB_H
++
++#include "TYPEDEF.H"
++
++//
++// Macro
++//
++#define INTFUNC int386
++
++#define OUTDWPORT outpd
++#define INDWPORT inpd
++#define OUTPUT outp
++#define INPUT inp
++
++//
++// PCI
++//
++ULONG ReadPCIReg (ULONG ulPCIConfigAddress, BYTE jOffest, ULONG ulMask);
++ULONG FindPCIDevice (USHORT usVendorID, USHORT usDeviceID, USHORT usBusType);
++VOID WritePCIReg (ULONG ulPCIConfigAddress, BYTE jOffest, ULONG ulMask, ULONG ulData);
++
++//
++// Map Resource
++//
++ULONG MapPhysicalToLinear (ULONG ulBaseAddress, ULONG ulSize);
++#endif
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/LIB.c b/arch/arm/cpu/arm926ejs/aspeed/LIB.c
+new file mode 100644
+index 0000000..f2a0c54
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/LIB.c
+@@ -0,0 +1,184 @@
++/*
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#define LIB_C
++static const char ThisFile[] = "LIB.c";
++
++#include "SWFUNC.H"
++
++#ifdef SLT_UBOOT
++ #include <common.h>
++ #include <command.h>
++#endif
++#ifdef SLT_DOS
++#include <stdlib.h>
++#include <stdio.h>
++#include <time.h>
++#include <conio.h>
++#include <dos.h>
++#include <mem.h>
++#endif
++
++#include "LIB.H"
++#include "TYPEDEF.H"
++
++#ifdef USE_P2A
++//------------------------------------------------------------
++// PCI
++//------------------------------------------------------------
++ULONG ReadPCIReg (ULONG ulPCIConfigAddress, BYTE jOffest, ULONG ulMask)
++{
++#ifndef Windows
++ OUTDWPORT(0xcf8, ulPCIConfigAddress + jOffest);
++
++ return (((ULONG)INDWPORT(0xcfc)) & ulMask);
++#else
++ WRITE_PORT_ULONG((PULONG)0xcf8, ulPCIConfigAddress + jOffest);
++
++ return (READ_PORT_ULONG((PULONG)0xcfc) & ulMask);
++#endif
++}
++
++//------------------------------------------------------------
++VOID WritePCIReg (ULONG ulPCIConfigAddress, BYTE jOffest, ULONG ulMask, ULONG ulData)
++{
++#ifndef Windows
++ OUTDWPORT(0xcf8, ulPCIConfigAddress + jOffest);
++ OUTDWPORT(0xcfc, (INDWPORT(0xcfc) & ulMask | ulData));
++#else
++ WRITE_PORT_ULONG((PULONG)0xcf8, ulPCIConfigAddress + jOffest);
++ WRITE_PORT_ULONG((PULONG)0xcfc, (READ_PORT_ULONG((PULONG)0xcfc) & ulMask | ulData));
++#endif
++}
++
++//------------------------------------------------------------
++ULONG FindPCIDevice (USHORT usVendorID, USHORT usDeviceID, USHORT usBusType)
++{
++//Return: ulPCIConfigAddress
++//usBusType: ACTIVE/PCI/AGP/PCI-E
++
++ ULONG Base[256];
++ ULONG ebx;
++ USHORT i;
++ USHORT j;
++
++ for (i = 0; i < 256; i++) {
++ Base[i] = 0x80000000 + 0x10000 * i;
++ }
++
++ if (usBusType == PCI)
++ {
++ ebx = 0x80000000;
++ }
++ else if (usBusType == PCIE)
++ {
++ ebx = 0x80020000;
++ }
++ else // AGP and ACTIVE
++ {
++ ebx = 0x80010000;
++ }
++
++ if ( usBusType != ACTIVE ) //AGP, PCI, PCIE
++ {
++ for (i = 0; i < 32; i++)
++ {
++ ebx = ebx + (0x800);
++ if (((USHORT)ReadPCIReg(ebx, 0, 0xffff) == usVendorID) && ((USHORT)(ReadPCIReg(ebx, 0, 0xffff0000) >> 16) == usDeviceID))
++ {
++ return ebx;
++ }
++ }
++ return 0;
++ }
++ else //ACTIVE
++ {
++ for (j = 0; j < 256; j++)
++ {
++ ebx = Base[j];
++ for (i = 0; i < 32; i++)
++ {
++ ebx = ebx + (0x800);
++ if (((USHORT)ReadPCIReg(ebx, 0, 0xffff) == usVendorID) && ((USHORT)(ReadPCIReg(ebx, 0, 0xffff0000) >> 16) == usDeviceID))
++ {
++ return ebx;
++ }
++ }
++ }
++ return 0;
++ }
++} // End ULONG FindPCIDevice (USHORT usVendorID, USHORT usDeviceID, USHORT usBusType)
++#endif
++//------------------------------------------------------------
++// Allocate Resource
++//------------------------------------------------------------
++#ifdef SLT_DOS
++ULONG InitDOS32()
++{
++ union REGS regs ;
++
++ regs.w.ax = 0xee00;
++ INTFUNC(0x31, &regs, &regs) ;
++
++ if(regs.w.ax >= 0x301) // DOS32 version >= 3.01 ?
++ return 1;
++ else
++ return 0;
++}
++
++//------------------------------------------------------------
++USHORT CheckDOS()
++{
++ union REGS regs;
++
++ regs.w.ax = 0xeeff;
++ int386(0x31, &regs, &regs);
++ if (regs.x.eax == 0x504d4457)
++ {
++ return 0;
++ } else {
++ printf("PMODEW Init. fail\n");
++ return 1;
++ }
++}
++
++//------------------------------------------------------------
++ULONG MapPhysicalToLinear (ULONG ulBaseAddress, ULONG ulSize)
++{
++ union REGS regs;
++
++ regs.w.ax = 0x0800; // map physcial memory
++ regs.w.bx = ulBaseAddress >> 16; // bx:cx = physical address
++ regs.w.cx = ulBaseAddress;
++ regs.w.si = ulSize >> 16; // si:di = mapped memory block size
++ regs.w.di = ulSize;
++ INTFUNC(0x31, &regs, &regs); // int386(0x31, &regs, &regs);
++ if (regs.w.cflag == 0)
++ return (ULONG) (regs.w.bx << 16 + regs.w.cx); // Linear Addr = bx:cx
++ else
++ return 0;
++}
++
++//------------------------------------------------------------
++USHORT FreePhysicalMapping(ULONG udwLinAddress)
++{
++ union REGS regs;
++
++ regs.w.ax = 0x0801;
++ regs.w.bx = udwLinAddress >> 16;
++ regs.w.cx = udwLinAddress & 0xFFFF;
++ int386(0x31, &regs, &regs);
++
++ if (regs.x.cflag)
++ return ((USHORT) 0);
++ else return ((USHORT) 1);
++}
++#endif
++
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/LIB_SPI.H b/arch/arm/cpu/arm926ejs/aspeed/LIB_SPI.H
+new file mode 100644
+index 0000000..78c8f1e
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/LIB_SPI.H
+@@ -0,0 +1,23 @@
++/*
++ * 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 LIB_SPI_H
++#define LIB_SPI_H
++
++#ifdef SPI_BUS
++ // MMIO Functions
++ VOID MOutwm (ULONG, ULONG, USHORT);
++ VOID MOutdwm (ULONG, ULONG, ULONG);
++ ULONG MIndwm (ULONG, ULONG);
++
++ void spim_init(int cs);
++#endif
++
++#endif // LIB_SPI_H
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/MAC.H b/arch/arm/cpu/arm926ejs/aspeed/MAC.H
+new file mode 100644
+index 0000000..6732117
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/MAC.H
+@@ -0,0 +1,157 @@
++/*
++ * 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 MAC_H
++#define MAC_H
++
++#ifdef SPI_BUS
++ #include <stdio.h>
++ #include <stdlib.h>
++ #include <time.h>
++ #define SPI_CS 1
++#endif
++// ( USE_P2A | USE_LPC )
++
++#if defined(LinuxAP)
++ #include <stdio.h>
++ #include <stdlib.h>
++ #include <string.h>
++ #include <stdarg.h>
++ #include <unistd.h>
++ #include <string.h>
++ #include <fcntl.h>
++ #include <pthread.h>
++ #include <sys/mman.h>
++ #include <sys/io.h>
++#endif
++#ifdef SLT_UBOOT
++ #include <common.h>
++ #include <command.h>
++#endif
++#ifdef SLT_DOS
++ #include <stdio.h>
++ #include <stdlib.h>
++ #include <time.h>
++ #include <conio.h>
++ #include <dos.h>
++ #include <mem.h>
++#endif
++
++#include "NCSI.H"
++#include "IO.H"
++
++// --------------------------------------------------------------
++// Define
++// --------------------------------------------------------------
++
++//#define Force_Enable_MAC34 //[ON][SLT:off] (Force enable mac34)
++//#define Force_Enable_NewMDIO //[off][SLT:off] (Force enable new MDC/MDIO)
++//#define Enable_Fast_SCU //[off]
++//#define Enable_Old_Style //[off]
++#define ENABLE_DASA //[ON]
++//#define Enable_AST2300_Int125MHz //[off]
++//#define ENABLE_ARP_2_WOL //[off]
++//#define Enable_MAC_SWRst //[off]
++
++#define Enable_Runt
++//#define Enable_Jumbo
++//#define Enable_BufMerge
++//#define Disable_VGA
++
++//#define SelectSimpleBoundary //[off] Using in debug
++//#define SelectSimpleData //[off] Using in debug
++//#define SelectSimpleLength 1512 //[off] 60(0x3c) ~ 1514(0x5ea); 1512(0x5e8)
++//#define SelectDesNumber 8 //[off] 1 ~
++//#define SelectSimpleDA //[off] Using in debug
++//#define SelectSimpleDes //[off]
++//#define SelectLengthInc //[off] Using in debug
++
++#define SimpleData_Fix //[ON] Using in debug
++#define SimpleData_FixNum 12
++#define SimpleData_FixVal00 0x00000000 //[0]no SelectSimpleDA: (60: 0412 8908)(1512: e20d e9da)
++#define SimpleData_FixVal01 0xffffffff //[0]no SelectSimpleDA: (60: f48c f14d)(1512: af05 260c)
++#define SimpleData_FixVal02 0x55555555 //[0]no SelectSimpleDA: (60: 5467 5ecb)(1512: d90a 5368)
++#define SimpleData_FixVal03 0xaaaaaaaa //[0]no SelectSimpleDA: (60: a4f9 268e)(1512: 9402 9cbe)
++#define SimpleData_FixVal04 0x5a5a5a5a //[1]no SelectSimpleDA: (60: 7f01 e22d)(1512: 4fd3 8012)
++#define SimpleData_FixVal05 0xc3c3c3c3 //[1]no SelectSimpleDA: (60: 5916 02d5)(1512: 99f1 6127)
++#define SimpleData_FixVal06 0x96969696 //[1]no SelectSimpleDA: (60: 0963 d516)(1512: a2f6 db95)
++#define SimpleData_FixVal07 0xf0f0f0f0 //[1]no SelectSimpleDA: (60: dfea 4dab)(1512: 39dc f576)
++#define SimpleData_FixVal08 0x5555aaaa //[2]no SelectSimpleDA: (60: b61b 5777)(1512: 4652 ddb0)
++#define SimpleData_FixVal09 0xffff0000 //[2]no SelectSimpleDA: (60: 16f0 f8f1)(1512: 305d a8d4)
++#define SimpleData_FixVal10 0x5a5aa5a5 //[2]no SelectSimpleDA: (60: 9d7d eb91)(1512: d08b 0eca)
++#define SimpleData_FixVal11 0xc3c33c3c //[2]no SelectSimpleDA: (60: bb6a 0b69)(1512: 06a9 efff)
++
++#define SelectSimpleDA_Dat0 0x67052301
++#define SelectSimpleDA_Dat1 0xe0cda089
++#define SelectSimpleDA_Dat2 0x98badcfe
++
++#define SelectWOLDA_DatH 0x206a
++#define SelectWOLDA_DatL 0x8a374d9b
++
++#define MOVE_DATA_MB_SEC 800 // MByte per second to move data
++
++//---------------------------------------------------------
++// Frame size
++//---------------------------------------------------------
++#define ENABLE_RAND_SIZE 0
++#define Rand_Sed 0xffccd
++#define FRAME_Rand_Simple 0
++#define MIN_FRAME_RAND_SIZE 60
++#define MAX_FRAME_RAND_SIZE 1514
++
++#define FRAME_SELH_PERD 7
++#ifdef Enable_Jumbo
++// #define FRAME_LENH 9212 //max:9212
++// #define FRAME_LENL 9211 //max:9212
++ #define FRAME_LENH 9212 //max:9212
++ #define FRAME_LENL 9212 //max:9212
++// #define FRAME_LENH 8120
++// #define FRAME_LENL 8119
++// #define FRAME_LENH 7000
++// #define FRAME_LENL 6999
++// #define FRAME_LENH 4095
++// #define FRAME_LENL 4094
++// #define FRAME_LENH 2040
++// #define FRAME_LENL 2039
++#else
++ #ifdef SelectSimpleLength
++// #define FRAME_LENH ( SelectSimpleLength + 1 )
++// #define FRAME_LENL ( SelectSimpleLength )
++ #define FRAME_LENH SelectSimpleLength
++ #define FRAME_LENL SelectSimpleLength
++ #else
++// #define FRAME_LENH 1514 //max:1514
++// #define FRAME_LENL 1513 //max:1514
++ #define FRAME_LENH 1514 //max:1514
++ #define FRAME_LENL 1514 //max:1514
++ #endif
++#endif
++
++const ULONG ARP_org_data[16] = {
++ 0xffffffff,
++ 0x0000ffff, // SA:00 00
++ 0x12345678, // SA:12 34 56 78
++ 0x01000608, // ARP(0x0806)
++ 0x04060008,
++ 0x00000100, // sender MAC Address: 00 00
++ 0x12345678, // sender MAC Address: 12 34 56 78
++ 0xeb00a8c0, // sender IP Address: 192.168.0.235
++ 0x00000000, // target MAC Address: 00 00 00 00
++ 0xa8c00000, // target MAC Address: 00 00, sender IP Address:192.168
++ 0x00000100, // sender IP Address: 0.1
++// 0x0000de00, // sender IP Address: 0.222
++ 0x00000000,
++ 0x00000000,
++ 0x00000000,
++ 0x00000000,
++ 0xc68e2bd5
++};
++
++#endif // MAC_H
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/MAC.c b/arch/arm/cpu/arm926ejs/aspeed/MAC.c
+new file mode 100644
+index 0000000..829da92
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/MAC.c
+@@ -0,0 +1,2085 @@
++/*
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#define MAC_C
++static const char ThisFile[] = "MAC.c";
++
++#include "SWFUNC.H"
++
++#ifdef SLT_UBOOT
++ #include <common.h>
++ #include <command.h>
++ #include <COMMINF.H>
++ #include "STDUBOOT.H"
++#endif
++#ifdef SLT_DOS
++ #include <stdio.h>
++ #include <stdlib.h>
++ #include <conio.h>
++ #include <string.h>
++ #include "COMMINF.H"
++#endif
++
++#include "MAC.H"
++
++double Avg_frame_len;
++ULONG Check_Des_Val;
++ULONG wp_fir;
++ULONG wp;
++ULONG FRAME_LEN_Cur;
++ULONG gdata;
++ULONG CheckDesFail_DesNum;
++ULONG VGAMode;
++ULONG SCU_1ch_old;
++ULONG SCU_0ch_old;
++ULONG SCU_48h_default;
++ULONG SCU_2ch_old;
++ULONG SCU_80h_old;
++ULONG SCU_74h_old;
++ULONG SCU_a4h_old;
++ULONG SCU_88h_old;
++ULONG WDT_0ch_old;
++ULONG SCU_04h_mix;
++ULONG SCU_04h_old;
++ULONG WDT_2ch_old;
++char SCU_oldvld = 0;
++
++#ifdef SLT_UBOOT
++#else
++ static double timeused;
++#endif
++// -------------------------------------------------------------
++
++void Debug_delay (void) {
++ #ifdef DbgPrn_Enable_Debug_delay
++ GET_CAHR();
++ #endif
++}
++
++
++
++
++void dump_mac_ROreg (void) {
++ DELAY(Delay_MACDump);
++ printf("\n");
++ printf("[MAC-H] ROReg A0h~ACh: %08lx %08lx %08lx %08lx\n", ReadSOC_DD(H_MAC_BASE+0xA0), ReadSOC_DD(H_MAC_BASE+0xA4), ReadSOC_DD(H_MAC_BASE+0xA8), ReadSOC_DD(H_MAC_BASE+0xAC));
++ printf("[MAC-H] ROReg B0h~BCh: %08lx %08lx %08lx %08lx\n", ReadSOC_DD(H_MAC_BASE+0xB0), ReadSOC_DD(H_MAC_BASE+0xB4), ReadSOC_DD(H_MAC_BASE+0xB8), ReadSOC_DD(H_MAC_BASE+0xBC));
++ printf("[MAC-H] ROReg C0h~C8h: %08lx %08lx %08lx \n", ReadSOC_DD(H_MAC_BASE+0xC0), ReadSOC_DD(H_MAC_BASE+0xC4), ReadSOC_DD(H_MAC_BASE+0xC8));
++}
++
++//------------------------------------------------------------
++// SCU
++//------------------------------------------------------------
++void recov_scu (void) {
++ #ifdef DbgPrn_FuncHeader
++ printf ("recov_scu\n");
++ Debug_delay();
++ #endif
++
++ //MAC
++ WriteSOC_DD( H_MAC_BASE + 0x08, MAC_08h_old );
++ WriteSOC_DD( H_MAC_BASE + 0x0c, MAC_0ch_old );
++ WriteSOC_DD( H_MAC_BASE + 0x40, MAC_40h_old );
++
++ //SCU
++ WriteSOC_DD( SCU_BASE + 0x04, SCU_04h_old );
++ WriteSOC_DD( SCU_BASE + 0x08, SCU_08h_old );
++ WriteSOC_DD( SCU_BASE + 0x0c, SCU_0ch_old );
++ WriteSOC_DD( SCU_BASE + 0x1c, SCU_1ch_old );
++ WriteSOC_DD( SCU_BASE + 0x2c, SCU_2ch_old );
++ WriteSOC_DD( SCU_BASE + 0x48, SCU_48h_old );
++// WriteSOC_DD( SCU_BASE + 0x70, SCU_70h_old );
++ WriteSOC_DD( SCU_BASE + 0x74, SCU_74h_old );
++ WriteSOC_DD( SCU_BASE + 0x7c, SCU_7ch_old );
++ WriteSOC_DD( SCU_BASE + 0x80, SCU_80h_old );
++ WriteSOC_DD( SCU_BASE + 0x88, SCU_88h_old );
++ WriteSOC_DD( SCU_BASE + 0x90, SCU_90h_old );
++ WriteSOC_DD( SCU_BASE + 0xa4, SCU_a4h_old );
++ WriteSOC_DD( SCU_BASE + 0xac, SCU_ach_old );
++ #ifdef AST1010_IOMAP
++ WriteSOC_DD( SCU_BASE + 0x11C, SCU_11Ch_old );
++ #endif
++
++ //WDT
++ #ifdef AST1010_IOMAP
++ #else
++ // WriteSOC_DD(0x1e78500c, WDT_0ch_old);
++ // WriteSOC_DD(0x1e78502c, WDT_2ch_old);
++ #endif
++
++ if ( ASTChipType == 3 ) {
++ if ( SCU_f0h_old & 0x01 ) WriteSOC_DD( SCU_BASE + 0xf0, 0xAEED0001 ); //Enable MAC34
++ if ( SCU_f0h_old & 0x02 ) WriteSOC_DD( SCU_BASE + 0xf0, 0x2000DEEA ); //Enable Decode
++ if ( SCU_f0h_old & 0x04 ) WriteSOC_DD( SCU_BASE + 0xf0, 0xA0E0E0D3 ); //Enable I2S
++ if ( SCU_f0h_old & 0x08 ) WriteSOC_DD( SCU_BASE + 0xf0, 0x4D0E0E0A ); //Enable PCI Host
++ if ( SCU_f0h_old & 0x10 ) WriteSOC_DD( SCU_BASE + 0xf0, 0x10ADDEED ); //Enable IR
++ if ( SCU_f0h_old & 0x20 ) WriteSOC_DD( SCU_BASE + 0xf0, 0x66559959 ); //Enabel Buffer Merge
++ if ( SCU_f0h_old & 0x40 ) WriteSOC_DD( SCU_BASE + 0xf0, 0x68961A33 ); //Enable PS2 IO
++ if ( SCU_f0h_old & 0x80 ) WriteSOC_DD( SCU_BASE + 0xf0, 0x68971A33 ); //Enable PS2 IO
++ }
++} // End void recov_scu (void)
++
++void read_scu (void) {
++ #ifdef DbgPrn_FuncHeader
++ printf ("read_scu\n");
++ Debug_delay();
++ #endif
++
++ if (!SCU_oldvld) {
++ //SCU
++ SCU_04h_old = ReadSOC_DD( SCU_BASE + 0x04 );
++ SCU_08h_old = ReadSOC_DD( SCU_BASE + 0x08 );
++ SCU_0ch_old = ReadSOC_DD( SCU_BASE + 0x0c );
++ SCU_1ch_old = ReadSOC_DD( SCU_BASE + 0x1c );
++ SCU_2ch_old = ReadSOC_DD( SCU_BASE + 0x2c );
++ SCU_48h_old = ReadSOC_DD( SCU_BASE + 0x48 );
++ SCU_70h_old = ReadSOC_DD( SCU_BASE + 0x70 );
++ SCU_74h_old = ReadSOC_DD( SCU_BASE + 0x74 );
++ SCU_7ch_old = ReadSOC_DD( SCU_BASE + 0x7c );
++ SCU_80h_old = ReadSOC_DD( SCU_BASE + 0x80 );
++ SCU_88h_old = ReadSOC_DD( SCU_BASE + 0x88 );
++ SCU_90h_old = ReadSOC_DD( SCU_BASE + 0x90 );
++ SCU_a4h_old = ReadSOC_DD( SCU_BASE + 0xa4 );
++ SCU_ach_old = ReadSOC_DD( SCU_BASE + 0xac );
++ SCU_f0h_old = ReadSOC_DD( SCU_BASE + 0xf0 );
++ #ifdef AST1010_IOMAP
++ SCU_11Ch_old = ReadSOC_DD( SCU_BASE + 0x11C );
++ #endif
++
++ //WDT
++ #ifdef AST1010_IOMAP
++ #else
++ WDT_0ch_old = ReadSOC_DD( 0x1e78500c );
++ WDT_2ch_old = ReadSOC_DD( 0x1e78502c );
++ #endif
++
++ SCU_oldvld = 1;
++ } // End if (!SCU_oldvld)
++} // End read_scu()
++
++void Setting_scu (void)
++{
++ //SCU
++ if (AST1010) {
++ do {
++ WriteSOC_DD( SCU_BASE + 0x00 , 0x1688a8a8);
++ #ifndef SLT_UBOOT
++ WriteSOC_DD( SCU_BASE + 0x70 , SCU_70h_old & 0xfffffffe); // Disable CPU
++ #endif
++ } while ( ReadSOC_DD( SCU_BASE + 0x00 ) != 0x1 );
++
++ #if( AST1010_IOMAP == 1)
++ WriteSOC_DD( SCU_BASE + 0x11C, 0x00000000); // Disable Cache functionn
++ #endif
++ }
++ else {
++ do {
++ WriteSOC_DD( SCU_BASE + 0x00, 0x1688a8a8);
++ #ifndef SLT_UBOOT
++ WriteSOC_DD( SCU_BASE + 0x70, SCU_70h_old | 0x3 ); // Disable CPU
++ #endif
++ } while ( ReadSOC_DD( SCU_BASE + 0x00 ) != 0x1 );
++ } // End if (AST1010)
++
++ //WDT
++ #ifdef AST1010_IOMAP
++ #else
++ WriteSOC_DD( 0x1e78500c, WDT_0ch_old & 0xfffffffc );
++ WriteSOC_DD( 0x1e78502c, WDT_2ch_old & 0xfffffffc );
++ #endif
++}
++
++//------------------------------------------------------------
++void init_scu1 (void) {
++ #ifdef DbgPrn_FuncHeader
++ printf ("init_scu1\n");
++ Debug_delay();
++ #endif
++
++ if (AST3200) {
++ WriteSOC_DD( SCU_BASE + 0x0c, (SCU_0ch_old & 0xffefffff) );//Clock Stop Control
++ }
++ else if (AST1010) {
++ WriteSOC_DD( SCU_BASE + 0x0c, ( SCU_0ch_old & 0xffffffbf ) );//Clock Stop Control
++ WriteSOC_DD( SCU_BASE + 0x88, ((SCU_88h_old & 0x003fffff ) | 0xffc00000) );//Multi-function Pin Control
++ }
++ else if (AST2300) {
++#ifdef Enable_BufMerge
++ WriteSOC_DD( SCU_BASE + 0xf0, 0x66559959 );//MAC buffer merge
++#endif
++
++#ifdef Enable_AST2300_Int125MHz
++ SCU_48h_mix = (SCU_48h_old & 0xf0000000) | 0x80000000;
++// WriteSOC_DD( SCU_BASE + 0xf0, 0xa0e0e0d3 );//Enable I2S
++// WriteSOC_DD( SCU_BASE + 0x04, SCU_04h_old & 0xfffdffff );//Rst(Enable I2S)
++//
++//// WriteSOC_DD( 0x1e6e5020, ReadSOC_DD(0x1e6e5020) | 0x00010000 );//P_I2SPLLAdjEnable
++// WriteSOC_DD( 0x1e6e5020, ReadSOC_DD(0x1e6e5020) | 0x00000000 );//P_I2SPLLAdjEnable
++// WriteSOC_DD( 0x1e6e5024, 0x00000175 );//P_I2SPLLAdjCnt
++
++// WriteSOC_DD( SCU_BASE + 0x1c, 0x0000a51a );//124800000(24MHz)
++// WriteSOC_DD( SCU_BASE + 0x1c, 0x0000a92f );//125333333(24MHz)
++// WriteSOC_DD( SCU_BASE + 0x1c, 0x0000587d );//125000000(24MHz)
++ WriteSOC_DD( SCU_BASE + 0x1c, 0x00006c7d );//125000000(24MHz)
++ WriteSOC_DD( SCU_BASE + 0x2c, 0x00300000 | (SCU_2ch_old & 0xffcfffef) );//D-PLL assigned to VGA, D2-PLL assigned to I2S.
++ WriteSOC_DD( SCU_BASE + 0x48, 0x80000000 | SCU_48h_old );//125MHz come from I2SPLL
++#else
++ SCU_48h_mix = (SCU_48h_old & 0xf0000000);
++#endif
++ switch (SelectMAC) {
++ case 0 :
++ WriteSOC_DD( SCU_BASE + 0x88, (SCU_88h_old & 0x3fffffff) | 0xc0000000 );//[31]MAC1 MDIO, [30]MAC1 MDC
++ break;
++ case 1 :
++ WriteSOC_DD( SCU_BASE + 0x90, (SCU_90h_old & 0xfffffffb) | 0x00000004 );//[2 ]MAC2 MDC/MDIO
++ break;
++ case 2 :
++ case 3 :
++ default : break;
++ }
++
++ WriteSOC_DD(SCU_BASE+0x0c, (SCU_0ch_old & 0xff0fffff) );//Clock Stop Control
++// WriteSOC_DD(SCU_BASE+0x80, (SCU_80h_old & 0xfffffff0) | 0x0000000f);//MAC1LINK/MAC2LINK
++ }
++ else {
++ switch (SelectMAC) {
++ case 0 :
++// WriteSOC_DD(SCU_BASE+0x74, (SCU_74h_old & 0xfdffffff) | 0x02000000);//[25]MAC1 PHYLINK
++ break;
++ case 1 :
++ if (MAC2_RMII) {
++// WriteSOC_DD(SCU_BASE+0x74, (SCU_74h_old & 0xfbefffff) | 0x04100000);//[26]MAC2 PHYLINK, [21]MAC2 MII, [20]MAC2 MDC/MDIO
++ WriteSOC_DD(SCU_BASE+0x74, (SCU_74h_old & 0xffefffff) | 0x00100000);//[26]MAC2 PHYLINK, [21]MAC2 MII, [20]MAC2 MDC/MDIO
++ } else {
++// WriteSOC_DD(SCU_BASE+0x74, (SCU_74h_old & 0xfbcfffff) | 0x04300000);//[26]MAC2 PHYLINK, [21]MAC2 MII, [20]MAC2 MDC/MDIO
++ WriteSOC_DD(SCU_BASE+0x74, (SCU_74h_old & 0xffcfffff) | 0x00300000);//[26]MAC2 PHYLINK, [21]MAC2 MII, [20]MAC2 MDC/MDIO
++ }
++ break;
++ default : break;
++ } // End switch (SelectMAC)
++ } // End if (AST3200)
++} // End void init_scu1 (void)
++
++//------------------------------------------------------------
++void init_scu_macrst (void) {
++
++#ifdef Enable_AST2300_Int125MHz
++ if (ASTChipType == 3) {
++ SCU_04h_mix = SCU_04h_old & 0xfffdffff;
++ } else {
++ SCU_04h_mix = SCU_04h_old;
++ }
++#else
++ SCU_04h_mix = SCU_04h_old;
++#endif
++
++ WriteSOC_DD ( SCU_BASE + 0x04, (SCU_04h_mix & ~SCU_04h) | SCU_04h);//Rst
++ DELAY(Delay_SCU);
++ WriteSOC_DD ( SCU_BASE + 0x04, (SCU_04h_mix & ~SCU_04h) );//Enable Engine
++// DELAY(Delay_SCU);
++} // End void init_scu_macrst (void)
++
++//------------------------------------------------------------
++void init_scu2 (void) {
++
++#ifdef SCU_74h
++ #ifdef DbgPrn_FuncHeader
++ printf ("init_scu2\n");
++ Debug_delay();
++ #endif
++
++ WriteSOC_DD( SCU_BASE + 0x74, SCU_74h_old | SCU_74h );//PinMux
++ delay(Delay_SCU);
++#endif
++
++} // End void init_scu2 (void)
++
++//------------------------------------------------------------
++void init_scu3 (void) {
++
++#ifdef SCU_74h
++ #ifdef DbgPrn_FuncHeader
++ printf ("init_scu3\n");
++ Debug_delay();
++ #endif
++
++ WriteSOC_DD( SCU_BASE + 0x74, SCU_74h_old | (SCU_74h & 0xffefffff) );//PinMux
++ delay(Delay_SCU);
++#endif
++
++} // End void init_scu3 (void)
++
++//------------------------------------------------------------
++// MAC
++//------------------------------------------------------------
++void init_mac (ULONG base, ULONG tdexbase, ULONG rdexbase) {
++ #ifdef DbgPrn_FuncHeader
++ printf ("init_mac\n");
++ Debug_delay();
++ #endif
++
++#ifdef Enable_MAC_SWRst
++ WriteSOC_DD( base + 0x50, 0x80000000 | MAC_50h | MAC_50h_Speed);
++// WriteSOC_DD( base + 0x50, 0x80000000);
++
++ while (0x80000000 & ReadSOC_DD(base+0x50)) {
++//printf(".");
++ DELAY(Delay_MACRst);
++ }
++ DELAY(Delay_MACRst);
++#endif
++
++ WriteSOC_DD( base + 0x20, (tdexbase + CPU_BUS_ADDR_SDRAM_OFFSET) ); // 20130730
++ WriteSOC_DD( base + 0x24, (rdexbase + CPU_BUS_ADDR_SDRAM_OFFSET) ); // 20130730
++
++#ifdef MAC_30h
++ WriteSOC_DD( base + 0x30, MAC_30h);//Int Thr/Cnt
++#endif
++
++#ifdef MAC_34h
++ WriteSOC_DD( base + 0x34, MAC_34h);//Poll Cnt
++#endif
++
++#ifdef MAC_38h
++ WriteSOC_DD( base + 0x38, MAC_38h);
++#endif
++
++#ifdef MAC_40h
++ if (Enable_MACLoopback) {
++ if (AST2300_NewMDIO) WriteSOC_DD( base + 0x40, MAC_40h | 0x80000000);
++ else WriteSOC_DD( base + 0x40, MAC_40h);
++ }
++#endif
++
++#ifdef MAC_48h
++ WriteSOC_DD( base + 0x48, MAC_48h);
++#endif
++
++ if ( ModeSwitch == MODE_NSCI )
++ WriteSOC_DD( base + 0x4c, NCSI_RxDMA_PakSize);
++ else
++ WriteSOC_DD( base + 0x4c, DMA_PakSize);
++
++ WriteSOC_DD( base + 0x50, MAC_50h | MAC_50h_Speed | 0xf);
++ DELAY(Delay_MACRst);
++} // End void init_mac (ULONG base, ULONG tdexbase, ULONG rdexbase)
++
++//------------------------------------------------------------
++// Basic
++//------------------------------------------------------------
++void FPri_RegValue (BYTE option) {
++
++#ifdef SLT_UBOOT
++#else
++ time_t timecur;
++#endif
++
++ FILE_VAR
++
++ GET_OBJ( option )
++
++ PRINT(OUT_OBJ "[SCU] 04:%08lx 08:%08lx 0c:%08lx 48:%08lx\n", SCU_04h_old, SCU_08h_old, SCU_0ch_old, SCU_48h_old);
++ PRINT(OUT_OBJ "[SCU] 70:%08lx 74:%08lx 7c:%08lx\n", SCU_70h_old, SCU_74h_old, SCU_7ch_old);
++ PRINT(OUT_OBJ "[SCU] 80:%08lx 88:%08lx 90:%08lx f0:%08lx\n", SCU_80h_old, SCU_88h_old, SCU_90h_old, SCU_f0h_old);
++ PRINT(OUT_OBJ "[SCU] a4:%08lx ac:%08lx\n", SCU_a4h_old, SCU_ach_old);
++ PRINT(OUT_OBJ "[WDT] 0c:%08lx 2c:%08lx\n", WDT_0ch_old, WDT_2ch_old);
++ PRINT(OUT_OBJ "[MAC] 08:%08lx 0c:%08lx\n", MAC_08h_old, MAC_0ch_old);
++ PRINT(OUT_OBJ "[MAC] A0|%08lx %08lx %08lx %08lx\n", ReadSOC_DD( MAC_PHYBASE + 0xa0), ReadSOC_DD( MAC_PHYBASE + 0xa4 ), ReadSOC_DD( MAC_PHYBASE + 0xa8 ), ReadSOC_DD(MAC_PHYBASE + 0xac ) );
++ PRINT(OUT_OBJ "[MAC] B0|%08lx %08lx %08lx %08lx\n", ReadSOC_DD( MAC_PHYBASE + 0xb0), ReadSOC_DD( MAC_PHYBASE + 0xb4 ), ReadSOC_DD( MAC_PHYBASE + 0xb8 ), ReadSOC_DD(MAC_PHYBASE + 0xbc ) );
++ PRINT(OUT_OBJ "[MAC] C0|%08lx %08lx %08lx\n", ReadSOC_DD( MAC_PHYBASE + 0xc0), ReadSOC_DD( MAC_PHYBASE + 0xc4 ), ReadSOC_DD( MAC_PHYBASE + 0xc8 ));
++
++#ifdef SLT_UBOOT
++#else
++ fprintf(fp, "Time: %s", ctime(&timestart));
++ time(&timecur);
++ fprintf(fp, "----> %s", ctime(&timecur));
++#endif
++} // End void FPri_RegValue (BYTE *fp)
++
++//------------------------------------------------------------
++void FPri_End (BYTE option) {
++
++ FILE_VAR
++
++ GET_OBJ( option )
++
++ if ( !RxDataEnable ) {
++ }
++ else if ( Err_Flag ) {
++ PRINT(OUT_OBJ " \n----> fail !!!\n");
++ } else {
++ PRINT(OUT_OBJ " \n----> All Pass !!!\n");
++ }
++
++ if ( ModeSwitch == MODE_DEDICATED ) {
++ if (PHY_ADR_arg != PHY_ADR)
++ PRINT(OUT_OBJ "\n[Warning] PHY Address change from %d to %d !!!\n", PHY_ADR_arg, PHY_ADR);
++ }
++
++ if ( AST1010 ) {
++ Dat_ULONG = (SCU_ach_old >> 12) & 0xf;
++ if (Dat_ULONG) {
++ PRINT(OUT_OBJ "\n[Warning] SCUAC[15:12] == 0x%02lx is not the suggestion value 0.\n", Dat_ULONG);
++ PRINT(OUT_OBJ " This change at this platform must been proven again by the ASPEED.\n");
++ }
++
++ SCU_48h_default = SCU_48h_AST1010 & 0x01000f00;
++ if ((SCU_48h_old != SCU_48h_default)) {
++ PRINT(OUT_OBJ "\n[Warning] SCU48 == 0x%08lx is not the suggestion value 0x%08lx.\n", SCU_48h_old, SCU_48h_default);
++ PRINT(OUT_OBJ " This change at this platform must been proven again by the ASPEED.\n");
++ }
++ }
++ else if ( AST2300 ) {
++ if ( AST2400 ) {
++ Dat_ULONG = (SCU_90h_old >> 8) & 0xf;
++ if (Dat_ULONG) {
++ PRINT(OUT_OBJ "\n[Warning] SCU90[11: 8] == 0x%02lx is not the suggestion value 0.\n", Dat_ULONG);
++ PRINT(OUT_OBJ " This change at this platform must been proven again by the ASPEED.\n");
++ }
++ }
++ else {
++ Dat_ULONG = (SCU_90h_old >> 8) & 0xff;
++ if (Dat_ULONG) {
++ PRINT(OUT_OBJ "\n[Warning] SCU90[15: 8] == 0x%02lx is not the suggestion value 0.\n", Dat_ULONG);
++ PRINT(OUT_OBJ " This change at this platform must been proven again by the ASPEED.\n");
++ }
++ }
++
++ if (Enable_MAC34) SCU_48h_default = SCU_48h_AST2300;
++ else SCU_48h_default = SCU_48h_AST2300 & 0x0300ffff;
++
++ if ((SCU_48h_old != SCU_48h_default)) {
++ PRINT(OUT_OBJ "\n[Warning] SCU48 == 0x%08lx is not the suggestion value 0x%08lx.\n", SCU_48h_old, SCU_48h_default);
++ PRINT(OUT_OBJ " This change at this platform must been proven again by the ASPEED.\n");
++ }
++ } // End if ( AST1010 )
++
++ if ( ModeSwitch == MODE_NSCI ) {
++ PRINT(OUT_OBJ "\n[Arg] %d %d %d %d %d %ld (%s)\n", GRun_Mode, PackageTolNum, ChannelTolNum, TestMode, IOTimingBund, (ARPNumCnt| (ULONG)PrintNCSIEn), ASTChipName);
++
++ switch (NCSI_Cap_SLT.PCI_DID_VID) {
++ case PCI_DID_VID_Intel_82574L : PRINT( OUT_OBJ "[NC]%08lx %08lx: Intel 82574L \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ case PCI_DID_VID_Intel_82575_10d6 : PRINT( OUT_OBJ "[NC]%08lx %08lx: Intel 82575 \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ case PCI_DID_VID_Intel_82575_10a7 : PRINT( OUT_OBJ "[NC]%08lx %08lx: Intel 82575 \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ case PCI_DID_VID_Intel_82575_10a9 : PRINT( OUT_OBJ "[NC]%08lx %08lx: Intel 82575 \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ case PCI_DID_VID_Intel_82576_10c9 : PRINT( OUT_OBJ "[NC]%08lx %08lx: Intel 82576 \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ case PCI_DID_VID_Intel_82576_10e6 : PRINT( OUT_OBJ "[NC]%08lx %08lx: Intel 82576 \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ case PCI_DID_VID_Intel_82576_10e7 : PRINT( OUT_OBJ "[NC]%08lx %08lx: Intel 82576 \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ case PCI_DID_VID_Intel_82576_10e8 : PRINT( OUT_OBJ "[NC]%08lx %08lx: Intel 82576 \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ case PCI_DID_VID_Intel_82576_1518 : PRINT( OUT_OBJ "[NC]%08lx %08lx: Intel 82576 \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ case PCI_DID_VID_Intel_82576_1526 : PRINT( OUT_OBJ "[NC]%08lx %08lx: Intel 82576 \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ case PCI_DID_VID_Intel_82576_150a : PRINT( OUT_OBJ "[NC]%08lx %08lx: Intel 82576 \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ case PCI_DID_VID_Intel_82576_150d : PRINT( OUT_OBJ "[NC]%08lx %08lx: Intel 82576 \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ case PCI_DID_VID_Intel_82599_10fb : PRINT( OUT_OBJ "[NC]%08lx %08lx: Intel 82599 \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ case PCI_DID_VID_Intel_82599_1557 : PRINT( OUT_OBJ "[NC]%08lx %08lx: Intel 82599 \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ case PCI_DID_VID_Intel_I350_1521 : PRINT( OUT_OBJ "[NC]%08lx %08lx: Intel I350 \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ case PCI_DID_VID_Intel_I350_1523 : PRINT( OUT_OBJ "[NC]%08lx %08lx: Intel I350 \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ case PCI_DID_VID_Intel_I210 : PRINT( OUT_OBJ "[NC]%08lx %08lx: Intel I210 \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ case PCI_DID_VID_Intel_X540 : PRINT( OUT_OBJ "[NC]%08lx %08lx: Intel X540 \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ case PCI_DID_VID_Broadcom_BCM5718 : PRINT( OUT_OBJ "[NC]%08lx %08lx: Broadcom BCM5718 \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ case PCI_DID_VID_Broadcom_BCM5720 : PRINT( OUT_OBJ "[NC]%08lx %08lx: Broadcom BCM5720 \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ case PCI_DID_VID_Broadcom_BCM5725 : PRINT( OUT_OBJ "[NC]%08lx %08lx: Broadcom BCM5725 \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++// case PCI_DID_VID_Broadcom_BCM57810 : PRINT( OUT_OBJ "[NC]%08x %08x: Broadcom BCM57810 \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ case PCI_DID_VID_Mellanox_ConnectX_3 : PRINT( OUT_OBJ "[NC]%08lx %08lx: Mellanox ConnectX-3\n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ default :
++ switch (NCSI_Cap_SLT.ManufacturerID) {
++ case ManufacturerID_Intel : PRINT( OUT_OBJ "[NC]%08lx %08lx: Intel \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ case ManufacturerID_Broadcom : PRINT( OUT_OBJ "[NC]%08lx %08lx: Broadcom\n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ case ManufacturerID_Mellanox : PRINT( OUT_OBJ "[NC]%08lx %08lx: Mellanox\n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID ); break;
++ default : PRINT(OUT_OBJ "[NC]%08lx %08lx \n", NCSI_Cap_SLT.ManufacturerID, NCSI_Cap_SLT.PCI_DID_VID); break;
++ } // End switch (NCSI_Cap_SLT.ManufacturerID)
++ } // End switch (NCSI_Cap_SLT.PCI_DID_VID)
++ }
++ else {
++ if (LOOP_INFINI) PRINT(OUT_OBJ "\n[Arg] %d %d %d # %d %d %d %lx (%s)[%d %d %d]\n" , GRun_Mode, GSpeed, GCtrl, TestMode, PHY_ADR_arg, IOTimingBund, UserDVal, ASTChipName, Loop_rl[0], Loop_rl[1], Loop_rl[2]);
++ else PRINT(OUT_OBJ "\n[Arg] %d %d %d %ld %d %d %d %lx (%s)[%d %d %d]\n", GRun_Mode, GSpeed, GCtrl, LOOP_MAX_arg, TestMode, PHY_ADR_arg, IOTimingBund, UserDVal, ASTChipName, Loop_rl[0], Loop_rl[1], Loop_rl[2]);
++
++ PRINT(OUT_OBJ "[PHY] Adr:%d ID2:%04lx ID3:%04lx (%s)\n", PHY_ADR, PHY_ID2, PHY_ID3, PHYName);
++ } // End if ( ModeSwitch == MODE_NSCI )
++
++#ifdef SUPPORT_PHY_LAN9303
++ PRINT(OUT_OBJ "[Ver II] %s (for LAN9303 with I2C%d)\n", version_name, LAN9303_I2C_BUSNUM);
++#else
++ PRINT(OUT_OBJ "[Ver II] %s\n", version_name);
++#endif
++} // End void FPri_End (BYTE option)
++
++//------------------------------------------------------------
++void FPri_ErrFlag (BYTE option) {
++
++ FILE_VAR
++
++ GET_OBJ( option )
++
++ if (Err_Flag && Err_Flag_PrintEn) {
++ PRINT(OUT_OBJ "\n\n");
++//fprintf(fp, "Err_Flag: %x\n\n", Err_Flag);
++
++ if ( Err_Flag & Err_PHY_Type ) PRINT( OUT_OBJ "[Err] Unidentifiable PHY \n" );
++ if ( Err_Flag & Err_MALLOC_FrmSize ) PRINT( OUT_OBJ "[Err] Malloc fail at frame size buffer \n" );
++ if ( Err_Flag & Err_MALLOC_LastWP ) PRINT( OUT_OBJ "[Err] Malloc fail at last WP buffer \n" );
++ if ( Err_Flag & Err_Check_Buf_Data ) PRINT( OUT_OBJ "[Err] Received data mismatch \n" );
++ if ( Err_Flag & Err_NCSI_Check_TxOwnTimeOut ) PRINT( OUT_OBJ "[Err] Time out of checking Tx owner bit in NCSI packet \n" );
++ if ( Err_Flag & Err_NCSI_Check_RxOwnTimeOut ) PRINT( OUT_OBJ "[Err] Time out of checking Rx owner bit in NCSI packet \n" );
++ if ( Err_Flag & Err_NCSI_Check_ARPOwnTimeOut) PRINT( OUT_OBJ "[Err] Time out of checking ARP owner bit in NCSI packet \n" );
++ if ( Err_Flag & Err_NCSI_No_PHY ) PRINT( OUT_OBJ "[Err] Can not find NCSI PHY \n" );
++ if ( Err_Flag & Err_NCSI_Channel_Num ) PRINT( OUT_OBJ "[Err] NCSI Channel Number Mismatch \n" );
++ if ( Err_Flag & Err_NCSI_Package_Num ) PRINT( OUT_OBJ "[Err] NCSI Package Number Mismatch \n" );
++ if ( Err_Flag & Err_PHY_TimeOut ) PRINT( OUT_OBJ "[Err] Time out of read/write/reset PHY register \n" );
++ if ( Err_Flag & Err_RXBUF_UNAVA ) PRINT( OUT_OBJ "[Err] MAC00h[2]:Receiving buffer unavailable \n" );
++ if ( Err_Flag & Err_RPKT_LOST ) PRINT( OUT_OBJ "[Err] MAC00h[3]:Received packet lost due to RX FIFO full \n" );
++ if ( Err_Flag & Err_NPTXBUF_UNAVA ) PRINT( OUT_OBJ "[Err] MAC00h[6]:Normal priority transmit buffer unavailable \n" );
++ if ( Err_Flag & Err_TPKT_LOST ) PRINT( OUT_OBJ "[Err] MAC00h[7]:Packets transmitted to Ethernet lost \n" );
++ if ( Err_Flag & Err_DMABufNum ) PRINT( OUT_OBJ "[Err] DMA Buffer is not enough \n" );
++ if ( Err_Flag & Err_IOMargin ) PRINT( OUT_OBJ "[Err] IO timing margin is not enough \n" );
++
++ if ( Err_Flag & Err_MHCLK_Ratio ) {
++ if ( AST1010 ) {
++ PRINT(OUT_OBJ "[Err] Error setting of MAC AHB bus clock (SCU08[13:12]) \n");
++ Dat_ULONG = (SCU_08h_old >> 12) & 0x3;
++ PRINT(OUT_OBJ " SCU08[13:12] == 0x%01lx is not the suggestion value 0.\n", Dat_ULONG);
++ }
++ else {
++ PRINT(OUT_OBJ "[Err] Error setting of MAC AHB bus clock (SCU08[18:16]) \n");
++ Dat_ULONG = (SCU_08h_old >> 16) & 0x7;
++
++ if (MAC1_1GEn | MAC2_1GEn) {
++ PRINT(OUT_OBJ " SCU08[18:16] == 0x%01lx is not the suggestion value 2.\n", Dat_ULONG);
++ }
++ else {
++ PRINT(OUT_OBJ " SCU08[18:16] == 0x%01lx is not the suggestion value 4.\n", Dat_ULONG);
++ }
++ } // end if ( AST1010 )
++ } // End if ( Err_Flag & Err_MHCLK_Ratio )
++
++ if (Err_Flag & Err_IOMarginOUF ) {
++ PRINT(OUT_OBJ "[Err] IO timing testing range out of boundary\n");
++ if (Enable_RMII) {
++#ifdef Enable_Old_Style
++ PRINT(OUT_OBJ " (%d,%d): 1x%d [%d]x[%d:%d]\n", IOdly_out_reg_idx, IOdly_in_reg_idx, IOTimingBund, IOdly_out_reg_idx, IOdly_in_reg_idx - (IOTimingBund>>1), IOdly_in_reg_idx + (IOTimingBund>>1));
++#else
++ PRINT(OUT_OBJ " (%d,%d): %dx1 [%d:%d]x[%d]\n", IOdly_in_reg_idx, IOdly_out_reg_idx, IOTimingBund, IOdly_in_reg_idx - (IOTimingBund>>1), IOdly_in_reg_idx + (IOTimingBund>>1), IOdly_out_reg_idx);
++#endif
++ } else {
++#ifdef Enable_Old_Style
++ PRINT(OUT_OBJ " (%d,%d): %dx%d [%d:%d]x[%d:%d]\n", IOdly_out_reg_idx, IOdly_in_reg_idx, IOTimingBund, IOTimingBund, IOdly_out_reg_idx - (IOTimingBund>>1), IOdly_out_reg_idx + (IOTimingBund>>1), IOdly_in_reg_idx - (IOTimingBund>>1), IOdly_in_reg_idx + (IOTimingBund>>1));
++#else
++ PRINT(OUT_OBJ " (%d,%d): %dx%d [%d:%d]x[%d:%d]\n", IOdly_in_reg_idx, IOdly_out_reg_idx, IOTimingBund, IOTimingBund, IOdly_in_reg_idx - (IOTimingBund>>1), IOdly_in_reg_idx + (IOTimingBund>>1), IOdly_out_reg_idx - (IOTimingBund>>1), IOdly_out_reg_idx + (IOTimingBund>>1));
++#endif
++ }
++ } // End if (Err_Flag & Err_IOMarginOUF )
++
++ if (Err_Flag & Err_Check_Des ) {
++ PRINT(OUT_OBJ "[Err] Descriptor error\n");
++ if ( Check_Des_Val & Check_Des_TxOwnTimeOut ) PRINT( OUT_OBJ "[Des] Time out of checking Tx owner bit\n" );
++ if ( Check_Des_Val & Check_Des_RxOwnTimeOut ) PRINT( OUT_OBJ "[Des] Time out of checking Rx owner bit\n" );
++ if ( Check_Des_Val & Check_Des_RxErr ) PRINT( OUT_OBJ "[Des] Input signal RxErr \n" );
++ if ( Check_Des_Val & Check_Des_OddNibble ) PRINT( OUT_OBJ "[Des] Nibble bit happen \n" );
++ if ( Check_Des_Val & Check_Des_CRC ) PRINT( OUT_OBJ "[Des] CRC error of frame \n" );
++ if ( Check_Des_Val & Check_Des_RxFIFOFull ) PRINT( OUT_OBJ "[Des] Rx FIFO full \n" );
++ if ( Check_Des_Val & Check_Des_FrameLen ) PRINT( OUT_OBJ "[Des] Frame length mismatch \n" );
++ } // End if (Err_Flag & Err_Check_Des )
++
++ if (Err_Flag & Err_MACMode ) {
++ PRINT(OUT_OBJ "[Err] MAC interface mode mismatch\n");
++ if ( AST1010 ) {
++ }
++ else if (AST2300) {
++ switch (MAC_Mode) {
++ case 0 : PRINT( OUT_OBJ " SCU70h[7:6] == 0: [MAC#1] RMII [MAC#2] RMII \n" ); break;
++ case 1 : PRINT( OUT_OBJ " SCU70h[7:6] == 1: [MAC#1] RGMII [MAC#2] RMII \n" ); break;
++ case 2 : PRINT( OUT_OBJ " SCU70h[7:6] == 2: [MAC#1] RMII [MAC#2] RGMII\n" ); break;
++ case 3 : PRINT( OUT_OBJ " SCU70h[7:6] == 3: [MAC#1] RGMII [MAC#2] RGMII\n" ); break;
++ }
++ }
++ else {
++ switch (MAC_Mode) {
++ case 0 : PRINT( OUT_OBJ " SCU70h[8:6] == 000: [MAC#1] GMII \n" ); break;
++ case 1 : PRINT( OUT_OBJ " SCU70h[8:6] == 001: [MAC#1] MII [MAC#2] MII \n" ); break;
++ case 2 : PRINT( OUT_OBJ " SCU70h[8:6] == 010: [MAC#1] RMII [MAC#2] MII \n" ); break;
++ case 3 : PRINT( OUT_OBJ " SCU70h[8:6] == 011: [MAC#1] MII \n" ); break;
++ case 4 : PRINT( OUT_OBJ " SCU70h[8:6] == 100: [MAC#1] RMII \n" ); break;
++ case 5 : PRINT( OUT_OBJ " SCU70h[8:6] == 101: Reserved \n" ); break;
++ case 6 : PRINT( OUT_OBJ " SCU70h[8:6] == 110: [MAC#1] RMII [MAC#2] RMII\n" ); break;
++ case 7 : PRINT( OUT_OBJ " SCU70h[8:6] == 111: Disable MAC \n" ); break;
++ }
++ } // End if ( AST1010 )
++ } // End if (Err_Flag & Err_MACMode )
++
++ if ( ModeSwitch == MODE_NSCI ) {
++ if (Err_Flag & Err_NCSI_LinkFail ) {
++ PRINT(OUT_OBJ "[Err] NCSI packet retry number over flows when find channel\n");
++
++ if (NCSI_LinkFail_Val & NCSI_LinkFail_Get_Version_ID ) PRINT(OUT_OBJ "[NCSI] Time out when Get Version ID \n");
++ if (NCSI_LinkFail_Val & NCSI_LinkFail_Get_Capabilities ) PRINT(OUT_OBJ "[NCSI] Time out when Get Capabilities \n");
++ if (NCSI_LinkFail_Val & NCSI_LinkFail_Select_Active_Package ) PRINT(OUT_OBJ "[NCSI] Time out when Select Active Package \n");
++ if (NCSI_LinkFail_Val & NCSI_LinkFail_Enable_Set_MAC_Address ) PRINT(OUT_OBJ "[NCSI] Time out when Enable Set MAC Address \n");
++ if (NCSI_LinkFail_Val & NCSI_LinkFail_Enable_Broadcast_Filter) PRINT(OUT_OBJ "[NCSI] Time out when Enable Broadcast Filter\n");
++ if (NCSI_LinkFail_Val & NCSI_LinkFail_Enable_Network_TX ) PRINT(OUT_OBJ "[NCSI] Time out when Enable Network TX \n");
++ if (NCSI_LinkFail_Val & NCSI_LinkFail_Enable_Channel ) PRINT(OUT_OBJ "[NCSI] Time out when Enable Channel \n");
++ if (NCSI_LinkFail_Val & NCSI_LinkFail_Disable_Network_TX ) PRINT(OUT_OBJ "[NCSI] Time out when Disable Network TX \n");
++ if (NCSI_LinkFail_Val & NCSI_LinkFail_Disable_Channel ) PRINT(OUT_OBJ "[NCSI] Time out when Disable Channel \n");
++ }
++
++ if (Err_Flag & Err_NCSI_Channel_Num ) PRINT(OUT_OBJ "[NCSI] Channel number expected: %d, real: %d\n", ChannelTolNum, number_chl);
++ if (Err_Flag & Err_NCSI_Package_Num ) PRINT(OUT_OBJ "[NCSI] Peckage number expected: %d, real: %d\n", PackageTolNum, number_pak);
++ } // End if ( ModeSwitch == MODE_NSCI )
++ } // End if (Err_Flag && Err_Flag_PrintEn)
++} // End void FPri_ErrFlag (BYTE option)
++
++//------------------------------------------------------------
++void Finish_Close (void) {
++
++ if (SCU_oldvld)
++ recov_scu();
++
++#ifdef SLT_DOS
++ if (fp_io && IOTiming)
++ fclose(fp_io);
++
++ if (fp_log)
++ fclose(fp_log);
++#endif
++} // End void Finish_Close (void)
++
++//------------------------------------------------------------
++char Finish_Check (int value) {
++ ULONG temp;
++ CHAR i = 0;
++
++#ifdef Disable_VGA
++ if (VGAModeVld) {
++ outp(0x3d4, 0x17);
++ outp(0x3d5, VGAMode);
++ }
++#endif
++ #ifdef DbgPrn_FuncHeader
++ printf ("Finish_Check\n");
++ Debug_delay();
++ #endif
++
++ if ( FRAME_LEN )
++ free(FRAME_LEN);
++
++ if ( wp_lst )
++ free(wp_lst );
++
++ Err_Flag = Err_Flag | value;
++
++ if ( DbgPrn_ErrFlg )
++ printf ("\nErr_Flag: [%08lx]\n", Err_Flag);
++
++ if ( !BurstEnable )
++ FPri_ErrFlag( FP_LOG );
++
++ if ( IOTiming )
++ FPri_ErrFlag( FP_IO );
++
++ FPri_ErrFlag( STD_OUT );
++
++ if ( !BurstEnable )
++ FPri_End( FP_LOG );
++
++ if ( IOTiming )
++ FPri_End( FP_IO );
++
++ FPri_End( STD_OUT );
++
++
++ if ( !BurstEnable ) FPri_RegValue( FP_LOG );
++ if ( IOTiming ) FPri_RegValue( FP_IO );
++
++ Finish_Close();
++
++ // 20140325
++ temp = ReadSOC_DD( 0x1e6e2040 );
++ if ( ModeSwitch == MODE_NSCI )
++ {
++ if ( SelectMAC == 0 )
++ i = 17;
++ else
++ i = 16;
++ }
++ else
++ {
++ if ( SelectMAC == 0 )
++ i = 19;
++ else
++ i = 18;
++ }
++ WriteSOC_DD( 0x1e6e2040, (temp | (1 << i)) );
++
++
++ if ( Err_Flag )
++ {
++ // Fail
++ return( 1 );
++ }
++ else
++ {
++ // Pass
++ return( 0 );
++ }
++} // End char Finish_Check (int value)
++
++//------------------------------------------------------------
++int FindErr (int value) {
++ Err_Flag = Err_Flag | value;
++
++ if ( DbgPrn_ErrFlg )
++ printf ("\nErr_Flag: [%08lx]\n", Err_Flag);
++
++ return(1);
++}
++
++//------------------------------------------------------------
++int FindErr_Des (int value) {
++ Check_Des_Val = Check_Des_Val | value;
++ Err_Flag = Err_Flag | Err_Check_Des;
++ if ( DbgPrn_ErrFlg )
++ printf ("\nErr_Flag: [%08lx] Check_Des_Val: [%08lx]\n", Err_Flag, Check_Des_Val);
++
++ return(1);
++}
++
++//------------------------------------------------------------
++// Get and Check status of Interrupt
++//------------------------------------------------------------
++int check_int ( char *type ) {
++ #ifdef DbgPrn_FuncHeader
++ printf ("check_int : %d\n", Loop);
++ Debug_delay();
++ #endif
++
++ Dat_ULONG = ReadSOC_DD( H_MAC_BASE + 0x00 );//Interrupt Status
++#ifdef SLT_DOS
++#ifdef CheckRxbufUNAVA
++ if ( Dat_ULONG & 0x00000004 ) {
++ fprintf(fp_log, "[%sIntStatus] Receiving buffer unavailable : %08lx [loop:%d]\n", type, Dat_ULONG, Loop);
++ FindErr( Err_RXBUF_UNAVA );
++ }
++#endif
++
++#ifdef CheckRPktLost
++ if ( Dat_ULONG & 0x00000008 ) {
++ fprintf(fp_log, "[%sIntStatus] Received packet lost due to RX FIFO full : %08lx [loop:%d]\n", type, Dat_ULONG, Loop);
++ FindErr( Err_RPKT_LOST );
++ }
++#endif
++
++#ifdef CheckNPTxbufUNAVA
++ if ( Dat_ULONG & 0x00000040 ) {
++ fprintf(fp_log, "[%sIntStatus] Normal priority transmit buffer unavailable: %08lx [loop:%d]\n", type, Dat_ULONG, Loop);
++ FindErr( Err_NPTXBUF_UNAVA );
++ }
++#endif
++
++#ifdef CheckTPktLost
++ if ( Dat_ULONG & 0x00000080 ) {
++ fprintf(fp_log, "[%sIntStatus] Packets transmitted to Ethernet lost : %08lx [loop:%d]\n", type, Dat_ULONG, Loop);
++ FindErr( Err_TPKT_LOST );
++ }
++#endif
++#endif
++ if (Err_Flag)
++ return(1);
++ else
++ return(0);
++} // End int check_int (char *type)
++
++
++//------------------------------------------------------------
++// Buffer
++//------------------------------------------------------------
++void setup_framesize (void) {
++ int i;
++
++ #ifdef DbgPrn_FuncHeader
++ printf ("setup_framesize\n");
++ Debug_delay();
++ #endif
++
++ //------------------------------------------------------------
++ // Fill Frame Size out descriptor area
++ //------------------------------------------------------------
++ #ifdef SLT_UBOOT
++ if (0)
++ #else
++ if ( ENABLE_RAND_SIZE )
++ #endif
++ {
++ for (i = 0; i < DES_NUMBER; i++) {
++ if ( FRAME_Rand_Simple ) {
++ switch(rand() % 5) {
++ case 0 : FRAME_LEN[i] = 0x4e ; break;
++ case 1 : FRAME_LEN[i] = 0x4ba; break;
++ default: FRAME_LEN[i] = 0x5ea; break;
++ }
++ }
++ else {
++ FRAME_LEN_Cur = rand() % (MAX_FRAME_RAND_SIZE + 1);
++
++ if (FRAME_LEN_Cur < MIN_FRAME_RAND_SIZE)
++ FRAME_LEN_Cur = MIN_FRAME_RAND_SIZE;
++
++ FRAME_LEN[i] = FRAME_LEN_Cur;
++ }
++#ifdef SLT_DOS
++ if (DbgPrn_FRAME_LEN)
++ fprintf(fp_log, "[setup_framesize] FRAME_LEN_Cur:%08lx[Des:%d][loop:%d]\n", FRAME_LEN[i], i, Loop);
++#endif
++ }
++ }
++ else {
++ for (i = 0; i < DES_NUMBER; i++) {
++ #ifdef SelectSimpleLength
++ if (i % FRAME_SELH_PERD)
++ FRAME_LEN[i] = FRAME_LENH;
++ else
++ FRAME_LEN[i] = FRAME_LENL;
++ #else
++ if ( BurstEnable ) {
++ if (IEEETesting) {
++ FRAME_LEN[i] = 1514;
++ }
++ else {
++ #ifdef ENABLE_ARP_2_WOL
++ FRAME_LEN[i] = 164;
++ #else
++ FRAME_LEN[i] = 60;
++ #endif
++ }
++ }
++ else {
++ #ifdef SelectLengthInc
++// FRAME_LEN[i] = (i%1455)+60;
++ FRAME_LEN[i] = 1514-( i % 1455 );
++ #else
++ if (i % FRAME_SELH_PERD)
++ FRAME_LEN[i] = FRAME_LENH;
++ else
++ FRAME_LEN[i] = FRAME_LENL;
++ #endif
++ } // End if (BurstEnable)
++ #endif
++/*
++ switch(i % 20) {
++ case 0 : FRAME_LEN[i] = FRAME_LENH; break;
++ case 1 : FRAME_LEN[i] = FRAME_LENH; break;
++ case 2 : FRAME_LEN[i] = FRAME_LENH; break;
++ default: FRAME_LEN[i] = FRAME_LENL; break;
++ }
++*/
++#ifdef SLT_DOS
++ if (DbgPrn_FRAME_LEN)
++ fprintf(fp_log, "[setup_framesize] FRAME_LEN_Cur:%08lx[Des:%d][loop:%d]\n", FRAME_LEN[i], i, Loop);
++#endif
++ } // End for (i = 0; i < DES_NUMBER; i++)
++ } // End if ( ENABLE_RAND_SIZE )
++
++ // Calculate average of frame size
++ Avg_frame_len = 0;
++
++ for ( i = 0; i < DES_NUMBER; i++ ) {
++ Avg_frame_len += FRAME_LEN[i];
++ }
++
++ Avg_frame_len = Avg_frame_len / (double)DES_NUMBER;
++
++ //------------------------------------------------------------
++ // Write Plane
++ //------------------------------------------------------------
++ switch( ZeroCopy_OFFSET & 0x3 ) {
++ case 0: wp_fir = 0xffffffff; break;
++ case 1: wp_fir = 0xffffff00; break;
++ case 2: wp_fir = 0xffff0000; break;
++ case 3: wp_fir = 0xff000000; break;
++ }
++
++ for ( i = 0; i < DES_NUMBER; i++ ) {
++ switch( ( ZeroCopy_OFFSET + FRAME_LEN[i] - 1 ) & 0x3 ) {
++ case 0: wp_lst[i] = 0x000000ff; break;
++ case 1: wp_lst[i] = 0x0000ffff; break;
++ case 2: wp_lst[i] = 0x00ffffff; break;
++ case 3: wp_lst[i] = 0xffffffff; break;
++ }
++ } // End for ( i = 0; i < DES_NUMBER; i++ )
++} // End void setup_framesize (void)
++
++//------------------------------------------------------------
++void setup_arp (void) {
++ int i;
++ for (i = 0; i < 16; i++ )
++ ARP_data[i] = ARP_org_data[i];
++
++ ARP_data[1] = 0x0000ffff | ( SA[0] << 16 )
++ | ( SA[1] << 24 );
++
++ ARP_data[2] = ( SA[2] )
++ | ( SA[3] << 8 )
++ | ( SA[4] << 16 )
++ | ( SA[5] << 24 );
++
++ ARP_data[5] = 0x00000100 | ( SA[0] << 16 )
++ | ( SA[1] << 24 );
++
++ ARP_data[6] = ( SA[2] )
++ | ( SA[3] << 8 )
++ | ( SA[4] << 16 )
++ | ( SA[5] << 24 );
++} // End void setup_arp (void)
++
++//------------------------------------------------------------
++void setup_buf (void) {
++ int i;
++ int j;
++ ULONG adr;
++ ULONG adr_srt;
++ ULONG adr_end;
++ ULONG len;
++ #ifdef SelectSimpleDA
++ int cnt;
++ ULONG Current_framelen;
++ #endif
++
++ #ifdef ENABLE_ARP_2_WOL
++ int DA[3];
++
++ DA[0] = ( ( SelectWOLDA_DatH >> 8 ) & 0x00ff ) |
++ ( ( SelectWOLDA_DatH << 8 ) & 0xff00 );
++
++ DA[1] = ( ( SelectWOLDA_DatL >> 24 ) & 0x00ff ) |
++ ( ( SelectWOLDA_DatL >> 8 ) & 0xff00 );
++
++ DA[2] = ( ( SelectWOLDA_DatL >> 8 ) & 0x00ff ) |
++ ( ( SelectWOLDA_DatL << 8 ) & 0xff00 );
++ #endif
++
++ #ifdef DbgPrn_FuncHeader
++ printf ("setup_buf : %d\n", Loop);
++ Debug_delay();
++ #endif
++
++ // It need be multiple of 4
++ adr_srt = GET_DMA_BASE_SETUP & 0xfffffffc;
++
++ for (j = 0; j < DES_NUMBER; j++) {
++ if ( DbgPrn_BufAdr )
++ printf("[loop:%4d][des:%4d][setup_buf ] %08lx\n", Loop, j, adr_srt);
++
++ if ( BurstEnable ) {
++ if ( IEEETesting ) {
++ #ifdef ENABLE_DASA
++ WriteSOC_DD( adr_srt , 0xffffffff );
++ WriteSOC_DD( adr_srt + 4, ARP_data[1] );
++ WriteSOC_DD( adr_srt + 8, ARP_data[2] );
++
++ for (adr = (adr_srt + 12); adr < (adr_srt + DMA_PakSize); adr += 4 )
++ #else
++ for (adr = adr_srt; adr < (adr_srt + DMA_PakSize); adr += 4 )
++ #endif
++ {
++ switch( TestMode ) {
++ case 1: gdata = 0xffffffff; break;
++ case 2: gdata = 0x55555555; break;
++ case 3: gdata = rand() | (rand() << 16); break;
++ case 5: gdata = UserDVal; break;
++ }
++ WriteSOC_DD(adr, gdata);
++ } // End for()
++ }
++ else {
++ for (i = 0; i < 16; i++) {
++ WriteSOC_DD( adr_srt + ( i << 2 ), ARP_data[i] );
++ }
++
++ #ifdef ENABLE_ARP_2_WOL
++ for (i = 16; i < 40; i += 3) {
++ WriteSOC_DD( adr_srt + ( i << 2 ), ( DA[1] << 16 ) | DA[0] );
++ WriteSOC_DD( adr_srt + ( i << 2 ) + 4, ( DA[0] << 16 ) | DA[2] );
++ WriteSOC_DD( adr_srt + ( i << 2 ) + 8, ( DA[2] << 16 ) | DA[1] );
++ }
++ #endif
++ } // End if ( IEEETesting )
++ }
++ else {
++ // --------------------------------------------
++ #ifdef SelectSimpleData
++ #ifdef SimpleData_Fix
++ switch( j % SimpleData_FixNum ) {
++ case 0 : gdata = SimpleData_FixVal00; break;
++ case 1 : gdata = SimpleData_FixVal01; break;
++ case 2 : gdata = SimpleData_FixVal02; break;
++ case 3 : gdata = SimpleData_FixVal03; break;
++ case 4 : gdata = SimpleData_FixVal04; break;
++ case 5 : gdata = SimpleData_FixVal05; break;
++ case 6 : gdata = SimpleData_FixVal06; break;
++ case 7 : gdata = SimpleData_FixVal07; break;
++ case 8 : gdata = SimpleData_FixVal08; break;
++ case 9 : gdata = SimpleData_FixVal09; break;
++ case 10 : gdata = SimpleData_FixVal10; break;
++ default : gdata = SimpleData_FixVal11; break;
++ }
++ #else
++ gdata = 0x11111111 * ((j + SEED_START) % 256);
++ #endif
++
++ adr_end = adr_srt + DMA_PakSize;
++ for ( adr = adr_srt; adr < adr_end; adr += 4 ) {
++ WriteSOC_DD( adr, gdata );
++ }
++ // --------------------------------------------
++ #elif SelectSimpleDA
++
++ gdata = DATA_SEED(j + SEED_START);
++ Current_framelen = FRAME_LEN[j];
++
++ if ( DbgPrn_FRAME_LEN )
++ fprintf(fp_log, "[setup_buf ] Current_framelen:%08lx[Des:%d][loop:%d]\n", Current_framelen, j, Loop);
++
++ cnt = 0;
++ len = ( ( ( Current_framelen - 14 ) & 0xff ) << 8) |
++ ( ( Current_framelen - 14 ) >> 8 );
++
++ adr_end = adr_srt + DMA_PakSize;
++ for ( adr = adr_srt; adr < adr_end; adr += 4 ) {
++ cnt++;
++ if (cnt == 1 ) WriteSOC_DD( adr, SelectSimpleDA_Dat0 );
++ else if (cnt == 2 ) WriteSOC_DD( adr, SelectSimpleDA_Dat1 );
++ else if (cnt == 3 ) WriteSOC_DD( adr, SelectSimpleDA_Dat2 );
++ else if (cnt == 4 ) WriteSOC_DD( adr, len | (len << 16) );
++ else
++ WriteSOC_DD( adr, gdata );
++
++ gdata += DATA_IncVal;
++ }
++ // --------------------------------------------
++ #else
++
++ gdata = DATA_SEED(j + SEED_START);
++ adr_end = adr_srt + DMA_PakSize;
++ for ( adr = adr_srt; adr < adr_end; adr += 4 ) {
++ WriteSOC_DD( adr, gdata );
++
++ gdata += DATA_IncVal;
++ }
++
++ #endif
++
++ } // End if ( BurstEnable )
++
++ adr_srt += DMA_PakSize;
++ } // End for (j = 0; j < DES_NUMBER; j++)
++} // End void setup_buf (void)
++
++//------------------------------------------------------------
++// Check data of one packet
++//------------------------------------------------------------
++char check_Data (ULONG desadr, LONG number) {
++ int index;
++ int cnt;
++ ULONG rdata;
++ ULONG wp_lst_cur;
++ ULONG adr_las;
++ ULONG adr;
++ ULONG adr_srt;
++ ULONG adr_end;
++ ULONG len;
++ #ifdef SelectSimpleDA
++ ULONG gdata_bak;
++ #endif
++
++ #ifdef DbgPrn_FuncHeader
++ printf ("check_Data : %d\n", Loop);
++ Debug_delay();
++ #endif
++ //printf("[Des:%d][loop:%d]Desadr:%08x\n", number, Loop, desadr);
++
++ wp_lst_cur = wp_lst[number];
++ FRAME_LEN_Cur = FRAME_LEN[number];
++#ifdef SLT_DOS
++ if ( DbgPrn_FRAME_LEN )
++ fprintf(fp_log, "[check_Data ] FRAME_LEN_Cur:%08lx[Des:%d][loop:%d]\n", FRAME_LEN_Cur, number, Loop);
++#endif
++ adr_srt = ReadSOC_DD(desadr) & 0xfffffffc;
++ adr_end = adr_srt + PktByteSize;
++
++ #ifdef SelectSimpleData
++ #ifdef SimpleData_Fix
++ switch( number % SimpleData_FixNum ) {
++ case 0 : gdata = SimpleData_FixVal00; break;
++ case 1 : gdata = SimpleData_FixVal01; break;
++ case 2 : gdata = SimpleData_FixVal02; break;
++ case 3 : gdata = SimpleData_FixVal03; break;
++ case 4 : gdata = SimpleData_FixVal04; break;
++ case 5 : gdata = SimpleData_FixVal05; break;
++ case 6 : gdata = SimpleData_FixVal06; break;
++ case 7 : gdata = SimpleData_FixVal07; break;
++ case 8 : gdata = SimpleData_FixVal08; break;
++ case 9 : gdata = SimpleData_FixVal09; break;
++ case 10 : gdata = SimpleData_FixVal10; break;
++ default : gdata = SimpleData_FixVal11; break;
++ }
++ #else
++ gdata = 0x11111111 * ((number + SEED_START) % 256);
++ #endif
++ #else
++ gdata = DATA_SEED(number + SEED_START);
++ #endif
++
++ wp = wp_fir;
++ adr_las = adr_end - 4;
++
++ cnt = 0;
++ len = (((FRAME_LEN_Cur-14) & 0xff) << 8) | ((FRAME_LEN_Cur-14) >> 8);
++#ifdef SLT_DOS
++ if (DbgPrn_Bufdat)
++ fprintf(fp_log, " Inf:%08lx ~ %08lx(%08lx) %08lx [Des:%d][loop:%d]\n", adr_srt, adr_end, adr_las, gdata, number, Loop);
++#endif
++ for (adr = adr_srt; adr < adr_end; adr+=4) {
++
++ #ifdef SelectSimpleDA
++ cnt++;
++ if ( cnt == 1 ) { gdata_bak = gdata; gdata = SelectSimpleDA_Dat0; }
++ else if ( cnt == 2 ) { gdata_bak = gdata; gdata = SelectSimpleDA_Dat1; }
++ else if ( cnt == 3 ) { gdata_bak = gdata; gdata = SelectSimpleDA_Dat2; }
++ else if ( cnt == 4 ) { gdata_bak = gdata; gdata = len | (len << 16); }
++ #endif
++ rdata = ReadSOC_DD(adr);
++ if (adr == adr_las)
++ wp = wp & wp_lst_cur;
++
++ if ( (rdata & wp) != (gdata & wp) ) {
++#ifdef SLT_DOS
++ fprintf(fp_log, "\nError: Adr:%08lx[%3d] (%08lx) (%08lx:%08lx) [Des:%d][loop:%d]\n", adr, (adr - adr_srt) / 4, rdata, gdata, wp, number, Loop);
++#endif
++ for (index = 0; index < 6; index++) {
++ rdata = ReadSOC_DD(adr);
++#ifdef SLT_DOS
++ fprintf(fp_log, "Rep : Adr:%08lx (%08lx) (%08lx:%08lx) [Des:%d][loop:%d]\n", adr, rdata, gdata, wp, number, Loop);
++#endif
++ }
++
++ if ( DbgPrn_DumpMACCnt )
++ dump_mac_ROreg();
++
++ return( FindErr( Err_Check_Buf_Data ) );
++ } // End if ( (rdata & wp) != (gdata & wp) )
++#ifdef SLT_DOS
++ if ( DbgPrn_BufdatDetail )
++ fprintf(fp_log, " Adr:%08lx[%3d] (%08lx) (%08lx:%08lx) [Des:%d][loop:%d]\n", adr, (adr - adr_srt) / 4, rdata, gdata, wp, number, Loop);
++#endif
++ #ifdef SelectSimpleDA
++ if ( cnt <= 4 )
++ gdata = gdata_bak;
++ #endif
++
++ #ifdef SelectSimpleData
++ #else
++ gdata += DATA_IncVal;
++ #endif
++
++ wp = 0xffffffff;
++ }
++ return(0);
++} // End char check_Data (ULONG desadr, LONG number)
++
++//------------------------------------------------------------
++char check_buf (int loopcnt) {
++ int count;
++ ULONG desadr;
++
++ #ifdef DbgPrn_FuncHeader
++ printf ("check_buf : %d\n", Loop);
++ Debug_delay();
++ #endif
++
++ for ( count = DES_NUMBER - 1; count >= 0; count-- ) {
++ desadr = H_RDES_BASE + ( 16 * count ) + 12;
++ //printf("%d:%08x\n", count, desadr);
++ if (check_Data(desadr, count)) {
++ check_int ("");
++
++ return(1);
++ }
++ }
++ if ( check_int ("") )
++ return(1);
++
++ return(0);
++} // End char check_buf (int loopcnt)
++
++//------------------------------------------------------------
++// Descriptor
++//------------------------------------------------------------
++void setup_txdes (ULONG desadr, ULONG bufbase) {
++ ULONG bufadr;
++ ULONG desval;
++ int count;
++
++ #ifdef DbgPrn_FuncHeader
++ printf ("setup_txdes: %d\n", Loop);
++ Debug_delay();
++ #endif
++
++ bufadr = bufbase + ZeroCopy_OFFSET;
++
++ if (TxDataEnable) {
++ for (count = 0; count < DES_NUMBER; count++) {
++ FRAME_LEN_Cur = FRAME_LEN[count];
++ desval = TDES_IniVal;
++ #ifdef SLT_DOS
++ if (DbgPrn_FRAME_LEN)
++ fprintf(fp_log, "[setup_txdes ] FRAME_LEN_Cur:%08lx[Des:%d][loop:%d]\n", FRAME_LEN_Cur, count, Loop);
++ #endif
++ if (DbgPrn_BufAdr)
++ printf("[loop:%4d][des:%4d][setup_txdes] %08lx\n", Loop, count, bufadr);
++
++ WriteSOC_DD( desadr + 0x04, 0 );
++ WriteSOC_DD( desadr + 0x08, 0 );
++ WriteSOC_DD( desadr + 0x0C, (bufadr + CPU_BUS_ADDR_SDRAM_OFFSET) ); // 20130730
++ if ( count == ( DES_NUMBER - 1 ) )
++ WriteSOC_DD( desadr , desval | EOR_IniVal);
++ else
++ WriteSOC_DD( desadr , desval );
++
++ bufadr += DMA_PakSize;
++ desadr += 16;
++ }
++ }
++ else {
++ WriteSOC_DD( desadr , 0);
++ }
++} // End void setup_txdes (ULONG desadr, ULONG bufbase)
++
++//------------------------------------------------------------
++void setup_rxdes (ULONG desadr, ULONG bufbase) {
++ ULONG bufadr;
++ ULONG desval;
++ int count;
++
++ #ifdef DbgPrn_FuncHeader
++ printf ("setup_rxdes: %d\n", Loop);
++ Debug_delay();
++ #endif
++
++ bufadr = bufbase+ZeroCopy_OFFSET;
++ desval = RDES_IniVal;
++
++ if ( RxDataEnable ) {
++ for (count = 0; count < DES_NUMBER; count++) {
++ if (DbgPrn_BufAdr)
++ printf("[loop:%4d][des:%4d][setup_rxdes] %08lx\n", Loop, count, bufadr);
++ WriteSOC_DD( desadr + 0x04, 0 );
++ WriteSOC_DD( desadr + 0x08, 0 );
++ WriteSOC_DD( desadr + 0x0C, ( bufadr + CPU_BUS_ADDR_SDRAM_OFFSET) ); // 20130730
++ if ( count == ( DES_NUMBER - 1 ) )
++ WriteSOC_DD( desadr , desval | EOR_IniVal );
++ else
++ WriteSOC_DD( desadr , desval );
++
++ desadr += 16;
++ bufadr += DMA_PakSize;
++ }
++ }
++ else {
++ WriteSOC_DD( desadr , 0x80000000 );
++ } // End if ( RxDataEnable )
++} // End void setup_rxdes (ULONG desadr, ULONG bufbase)
++
++//------------------------------------------------------------
++// First setting TX and RX information
++//------------------------------------------------------------
++void setup_des (ULONG bufnum) {
++
++ if ( DbgPrn_BufAdr ) {
++ printf ("setup_rxdes: %ld\n", bufnum);
++ Debug_delay();
++ }
++
++ setup_txdes( H_TDES_BASE, GET_DMA_BASE_SETUP );
++ setup_rxdes( H_RDES_BASE, GET_DMA_BASE(0) );
++
++} // End void setup_des (ULONG bufnum)
++
++//------------------------------------------------------------
++// Move buffer point of TX and RX descriptor to next DMA buffer
++//------------------------------------------------------------
++void setup_des_loop (ULONG bufnum) {
++ int count;
++ ULONG H_rx_desadr;
++ ULONG H_tx_desadr;
++ ULONG H_tx_bufadr;
++ ULONG H_rx_bufadr;
++
++ if ( DbgPrn_BufAdr ) {
++ printf ("setup_rxdes_loop: %ld\n", bufnum);
++ Debug_delay();
++ }
++
++ if (RxDataEnable) {
++ H_rx_bufadr = GET_DMA_BASE( bufnum + 1 ) + ZeroCopy_OFFSET;
++ H_rx_desadr = H_RDES_BASE;
++//printf (" =====>setup_rxdes_loop: %ld [%lX]\n", bufnum, H_rx_bufadr);
++ for (count = 0; count < DES_NUMBER; count++) {
++ WriteSOC_DD(H_rx_desadr + 0x0C, (H_rx_bufadr + CPU_BUS_ADDR_SDRAM_OFFSET) ); // 20130730
++
++ if (count == (DES_NUMBER - 1)) {
++ WriteSOC_DD( H_rx_desadr, RDES_IniVal | EOR_IniVal );
++ }
++ else {
++ WriteSOC_DD( H_rx_desadr, RDES_IniVal );
++ }
++ H_rx_bufadr += DMA_PakSize;
++ H_rx_desadr += 16;
++ }
++ }
++
++ if (TxDataEnable) {
++ if (RxDataEnable) {
++ H_tx_bufadr = GET_DMA_BASE( bufnum ) + ZeroCopy_OFFSET;
++ }
++ else {
++ H_tx_bufadr = GET_DMA_BASE( 0 ) + ZeroCopy_OFFSET;
++ }
++ H_tx_desadr = H_TDES_BASE;
++//printf (" =====>setup_Txdes_loop: %ld [%lX]\n", bufnum, H_tx_bufadr);
++ for (count = 0; count < DES_NUMBER; count++) {
++ FRAME_LEN_Cur = FRAME_LEN[count];
++ WriteSOC_DD( H_tx_desadr + 0x0C, ( H_tx_bufadr + CPU_BUS_ADDR_SDRAM_OFFSET) ); // 20130730
++ if (count == (DES_NUMBER - 1)) {
++ WriteSOC_DD( H_tx_desadr, TDES_IniVal | EOR_IniVal );
++ }
++ else {
++ WriteSOC_DD( H_tx_desadr, TDES_IniVal );
++ }
++ H_tx_bufadr += DMA_PakSize;
++ H_tx_desadr += 16;
++ }
++ }
++
++ WriteSOC_DD( H_MAC_BASE + 0x18, 0x00000000 ); // Tx Poll
++ WriteSOC_DD( H_MAC_BASE + 0x1c, 0x00000000 ); // Rx Poll
++} // End void setup_des_loop (ULONG bufnum)
++
++//------------------------------------------------------------
++char check_des_header_Tx (char *type, ULONG adr, LONG desnum) {
++ int timeout = 0;
++ ULONG dat;
++
++ dat = ReadSOC_DD(adr);
++
++ while ( HWOwnTx(dat) ) {
++ // we will run again, if transfer has not been completed.
++ if ( RxDataEnable && (++timeout > TIME_OUT_Des) ) {
++ #ifdef SLT_DOS
++ fprintf(fp_log, "[%sTxDesOwn] Address %08lx = %08lx [Des:%d][loop:%d]\n", type, adr, dat, desnum, Loop);
++ #endif
++ return(FindErr_Des(Check_Des_TxOwnTimeOut));
++ }
++ WriteSOC_DD(H_MAC_BASE + 0x18, 0x00000000);//Tx Poll
++ WriteSOC_DD(H_MAC_BASE + 0x1c, 0x00000000);//Rx Poll
++
++ #ifdef Delay_ChkTxOwn
++ delay(Delay_ChkTxOwn);
++ #endif
++ dat = ReadSOC_DD(adr);
++ }
++
++ return(0);
++} // End char check_des_header_Tx (char *type, ULONG adr, LONG desnum)
++
++//------------------------------------------------------------
++char check_des_header_Rx (char *type, ULONG adr, LONG desnum) {
++ #ifdef CheckRxOwn
++ int timeout = 0;
++ ULONG dat;
++
++ dat = ReadSOC_DD(adr);
++
++ while ( HWOwnRx( dat ) ) {
++ // we will run again, if transfer has not been completed.
++ if (TxDataEnable && (++timeout > TIME_OUT_Des)) {
++ #ifdef SLT_DOS
++ fprintf(fp_log, "[%sRxDesOwn] Address %08lx = %08lx [Des:%d][loop:%d]\n", type, adr, dat, desnum, Loop);
++ #endif
++ return(FindErr_Des(Check_Des_RxOwnTimeOut));
++ }
++
++ WriteSOC_DD(H_MAC_BASE + 0x18, 0x00000000);//Tx Poll
++ WriteSOC_DD(H_MAC_BASE + 0x1c, 0x00000000);//Rx Poll
++
++ #ifdef Delay_ChkRxOwn
++ delay(Delay_ChkRxOwn);
++ #endif
++ dat = ReadSOC_DD(adr);
++ };
++
++ Dat_ULONG = ReadSOC_DD( adr + 12 );
++
++ #ifdef CheckRxLen
++ #ifdef SLT_DOS
++ if ( DbgPrn_FRAME_LEN )
++ fprintf(fp_log, "[%sRxDes ] FRAME_LEN_Cur:%08lx[Des:%d][loop:%d]\n", type, (FRAME_LEN_Cur + 4), desnum, Loop);
++ #endif
++
++ if ((dat & 0x3fff) != (FRAME_LEN_Cur + 4)) {
++ #ifdef SLT_DOS
++ fprintf(fp_log, "[%sRxDes] Error Frame Length %08lx:%08lx %08lx(%4d/%4d) [Des:%d][loop:%d]\n", type, adr, dat, Dat_ULONG, (dat & 0x3fff), (FRAME_LEN_Cur + 4), desnum, Loop);
++ #endif
++ FindErr_Des(Check_Des_FrameLen);
++ }
++ #endif // End CheckRxLen
++
++ #ifdef CheckRxErr
++ if (dat & 0x00040000) {
++ #ifdef SLT_DOS
++ fprintf(fp_log, "[%sRxDes] Error RxErr %08lx:%08lx %08lx [Des:%d][loop:%d]\n", type, adr, dat, Dat_ULONG, desnum, Loop);
++ #endif
++ FindErr_Des(Check_Des_RxErr);
++ }
++ #endif // End CheckRxErr
++
++ #ifdef CheckOddNibble
++ if (dat & 0x00400000) {
++ #ifdef SLT_DOS
++ fprintf(fp_log, "[%sRxDes] Odd Nibble %08lx:%08lx %08lx [Des:%d][loop:%d]\n", type, adr, dat, Dat_ULONG, desnum, Loop);
++ #endif
++ FindErr_Des(Check_Des_OddNibble);
++ }
++ #endif // End CheckOddNibble
++
++ #ifdef CheckCRC
++ if (dat & 0x00080000) {
++ #ifdef SLT_DOS
++ fprintf(fp_log, "[%sRxDes] Error CRC %08lx:%08lx %08lx [Des:%d][loop:%d]\n", type, adr, dat, Dat_ULONG, desnum, Loop);
++ #endif
++ FindErr_Des(Check_Des_CRC);
++ }
++ #endif // End CheckCRC
++
++ #ifdef CheckRxFIFOFull
++ if (dat & 0x00800000) {
++ #ifdef SLT_DOS
++ fprintf(fp_log, "[%sRxDes] Error Rx FIFO Full %08lx:%08lx %08lx [Des:%d][loop:%d]\n", type, adr, dat, Dat_ULONG, desnum, Loop);
++ #endif
++ FindErr_Des(Check_Des_RxFIFOFull);
++ }
++ #endif // End CheckRxFIFOFull
++
++ // if (check_int ("")) {return(1);}
++ #endif // End CheckRxOwn
++
++ if (Err_Flag)
++ return(1);
++ else
++ return(0);
++} // End char check_des_header_Rx (char *type, ULONG adr, LONG desnum)
++
++//------------------------------------------------------------
++char check_des (ULONG bufnum, int checkpoint) {
++ int desnum;
++ ULONG H_rx_desadr;
++ ULONG H_tx_desadr;
++ ULONG H_tx_bufadr;
++ ULONG H_rx_bufadr;
++
++ #ifdef Delay_DesGap
++ ULONG dly_cnt = 0;
++ ULONG dly_max = Delay_CntMaxIncVal;
++ #endif
++
++ #ifdef DbgPrn_FuncHeader
++ printf ("check_des : %d(%d)\n", Loop, checkpoint);
++ Debug_delay();
++ #endif
++
++ // Fire the engine to send and recvice
++ WriteSOC_DD( H_MAC_BASE + 0x18, 0x00000000 );//Tx Poll
++ WriteSOC_DD( H_MAC_BASE + 0x1c, 0x00000000 );//Rx Poll
++
++ #ifdef SelectSimpleDes
++ #else
++ if ( IEEETesting == 1 ) {
++ // IEEE test mode, there is the same data in every lan packet
++ H_tx_bufadr = GET_DMA_BASE_SETUP;
++ H_rx_bufadr = GET_DMA_BASE(0);
++ }
++ else {
++ H_rx_bufadr = GET_DMA_BASE( bufnum + 1 ) + ZeroCopy_OFFSET;
++
++ if (RxDataEnable) {
++ H_tx_bufadr = GET_DMA_BASE(bufnum ) + ZeroCopy_OFFSET;
++ }
++ else {
++ H_tx_bufadr = GET_DMA_BASE( 0 ) + ZeroCopy_OFFSET;
++ }
++ }
++ #endif
++
++ H_rx_desadr = H_RDES_BASE;
++ H_tx_desadr = H_TDES_BASE;
++
++ #ifdef Delay_DES
++ delay(Delay_DES);
++ #endif
++
++ for (desnum = 0; desnum < DES_NUMBER; desnum++) {
++ if ( DbgPrn_BufAdr )
++ printf( "[loop:%4d][des:%4d][check_des ] %08lx %08lx [%08lx] [%08lx]\n", Loop, desnum, ( H_tx_desadr ), ( H_rx_desadr ), ReadSOC_DD( H_tx_desadr + 12 ), ReadSOC_DD( H_rx_desadr + 12 ) );
++
++ //[Delay]--------------------
++ #ifdef Delay_DesGap
++ if ( dly_cnt++ > 3 ) {
++ switch ( rand() % 12 ) {
++ case 1 : dly_max = 00000; break;
++ case 3 : dly_max = 20000; break;
++ case 5 : dly_max = 40000; break;
++ case 7 : dly_max = 60000; break;
++ defaule: dly_max = 70000; break;
++ }
++
++ dly_max += ( rand() % 4 ) * 14321;
++
++ while (dly_cnt < dly_max) {
++ dly_cnt++;
++ }
++
++ dly_cnt = 0;
++ }
++ else {
++// timeout = 0;
++// while (timeout < 50000) {timeout++;};
++ }
++ #endif // End Delay_DesGap
++
++ //[Check Owner Bit]--------------------
++ FRAME_LEN_Cur = FRAME_LEN[desnum];
++#ifdef SLT_DOS
++ if ( DbgPrn_FRAME_LEN )
++ fprintf(fp_log, "[check_des ] FRAME_LEN_Cur:%08lx[Des:%d][loop:%d]%d\n", FRAME_LEN_Cur, desnum, Loop, checkpoint);
++#endif
++// if (BurstEnable) {
++// if (check_des_header_Tx("", H_tx_desadr, desnum)) {CheckDesFail_DesNum = desnum; return(1);}
++// } else {
++// if (check_des_header_Rx("", H_rx_desadr, desnum)) {CheckDesFail_DesNum = desnum; return(1);}
++// if (check_des_header_Tx("", H_tx_desadr, desnum)) {CheckDesFail_DesNum = desnum; return(1);}
++// }
++
++ // Check the description of Tx and Rx
++ if ( RxDataEnable && check_des_header_Rx("", H_rx_desadr, desnum) ) {
++ CheckDesFail_DesNum = desnum;
++
++ return(1);
++ }
++ if ( TxDataEnable && check_des_header_Tx("", H_tx_desadr, desnum) ) {
++ CheckDesFail_DesNum = desnum;
++
++ return(1);
++ }
++// else {
++// printf(" %d \r", desnum);
++// }
++
++ #ifdef SelectSimpleDes
++ #else
++ if ( !checkpoint ) {
++ // Setting buffer address to description of Tx and Rx on next stage
++
++// if (!BurstEnable) {
++// WriteSOC_DD( H_rx_desadr + 0x0C, (H_rx_bufadr + CPU_BUS_ADDR_SDRAM_OFFSET) );
++// WriteSOC_DD( H_tx_desadr + 0x0C, (H_tx_bufadr + CPU_BUS_ADDR_SDRAM_OFFSET) );
++// }
++//
++// if ( desnum == (DES_NUMBER - 1) ) {
++// WriteSOC_DD( H_rx_desadr, RDES_IniVal | EOR_IniVal );
++// WriteSOC_DD( H_tx_desadr, TDES_IniVal | EOR_IniVal );
++// }
++// else {
++// WriteSOC_DD( H_rx_desadr, RDES_IniVal );
++// WriteSOC_DD( H_tx_desadr, TDES_IniVal );
++// }
++// WriteSOC_DD( H_MAC_BASE+0x18, 0x00000000 ); //Tx Poll
++// WriteSOC_DD( H_MAC_BASE+0x1c, 0x00000000 ); //Rx Poll
++
++ if ( RxDataEnable ) {
++ WriteSOC_DD( H_rx_desadr + 0x0C, (H_rx_bufadr + CPU_BUS_ADDR_SDRAM_OFFSET) ); // 20130730
++
++ if ( desnum == (DES_NUMBER - 1) ) {
++ WriteSOC_DD( H_rx_desadr, RDES_IniVal | EOR_IniVal );
++ } else {
++ WriteSOC_DD( H_rx_desadr, RDES_IniVal );
++ }
++ }
++ if ( TxDataEnable ) {
++ WriteSOC_DD( H_tx_desadr + 0x0C, (H_tx_bufadr + CPU_BUS_ADDR_SDRAM_OFFSET) ); // 20130730
++ if ( desnum == (DES_NUMBER - 1) ) {
++ WriteSOC_DD( H_tx_desadr, TDES_IniVal | EOR_IniVal );
++ }
++ else {
++ WriteSOC_DD( H_tx_desadr, TDES_IniVal );
++ }
++ }
++ WriteSOC_DD( H_MAC_BASE + 0x18, 0x00000000 ); //Tx Poll
++ WriteSOC_DD( H_MAC_BASE + 0x1c, 0x00000000 ); //Rx Poll
++ }
++ H_rx_bufadr += DMA_PakSize;
++ H_tx_bufadr += DMA_PakSize;
++ #endif // End SelectSimpleDes
++
++ H_rx_desadr += 16;
++ H_tx_desadr += 16;
++ } // End for (desnum = 0; desnum < DES_NUMBER; desnum++)
++
++ return(0);
++} // End char check_des (ULONG bufnum, int checkpoint)
++//#endif
++
++//------------------------------------------------------------
++// Print
++//------------------------------------------------------------
++void PrintMode (void) {
++ if (Enable_MAC34) printf ("run_mode[dec] | 0->MAC1 1->MAC2 2->MAC3 3->MAC4\n");
++ else printf ("run_mode[dec] | 0->MAC1 1->MAC2\n");
++}
++
++//------------------------------------------------------------
++void PrintSpeed (void) {
++ printf ("speed[dec] | 0->1G 1->100M 2->10M 3->all speed (default:%3d)\n", DEF_SPEED);
++}
++
++//------------------------------------------------------------
++void PrintCtrl (void) {
++ printf ("ctrl[dec] | bit0~2: Reserved\n");
++ printf ("(default:%3d) | bit3 : 1->Enable PHY init 0->Disable PHY init\n", GCtrl);
++ printf (" | bit4 : 1->Enable PHY int-loop 0->Disable PHY int-loop\n");
++ printf (" | bit5 : 1->Ignore PHY ID 0->Check PHY ID\n");
++ if (AST2400) {
++ printf (" | bit6 : 1->Enable MAC int-loop 0->Disable MAC int-loop\n");
++ }
++}
++
++//------------------------------------------------------------
++void PrintLoop (void) {
++ printf ("loop_max[dec] | 1G : 20 will run 1 sec (default:%3d)\n", DEF_LOOP_MAX * 20);
++ printf (" | 100M: 2 will run 1 sec (default:%3d)\n", DEF_LOOP_MAX * 2);
++ printf (" | 10M : 1 will run 1 sec (default:%3d)\n", DEF_LOOP_MAX);
++}
++
++//------------------------------------------------------------
++void PrintTest (void) {
++ if ( ModeSwitch == MODE_NSCI ) {
++ printf ("test_mode[dec] | 0: NCSI configuration with Disable_Channel request\n");
++ printf ("(default:%3d) | 1: NCSI configuration without Disable_Channel request\n", DEF_TESTMODE);
++ }
++ else {
++ printf ("test_mode[dec] | 0: Tx/Rx frame checking\n");
++ printf ("(default:%3d) | 1: Tx output 0xff frame\n", DEF_TESTMODE);
++ printf (" | 2: Tx output 0x55 frame\n");
++ printf (" | 3: Tx output random frame\n");
++ printf (" | 4: Tx output ARP frame\n");
++ printf (" | 5: Tx output user defined value frame (default:0x%8x)\n", DEF_USER_DEF_PACKET_VAL);
++ } // End if ( ModeSwitch == MODE_NSCI )
++
++ if (AST2300) {
++ printf (" | 6: IO timing testing\n");
++ printf (" | 7: IO timing/strength testing\n");
++ }
++}
++
++//------------------------------------------------------------
++void PrintPHYAdr (void) {
++ printf ("phy_adr[dec] | 0~31: PHY Address (default:%d)\n", DEF_PHY_ADR);
++}
++
++//------------------------------------------------------------
++void PrintIOTimingBund (void) {
++ printf ("IO margin[dec] | 0/1/3/5 (default:%d)\n", DEF_IOTIMINGBUND);
++}
++
++//------------------------------------------------------------
++void PrintPakNUm (void) {
++ printf ("package_num[dec] | 1~ 8: Total Number of NCSI Package (default:%d)\n", DEF_PACKAGE2NUM);
++}
++
++//------------------------------------------------------------
++void PrintChlNUm (void) {
++ printf ("channel_num[dec] | 1~32: Total Number of NCSI Channel (default:%d)\n", DEF_CHANNEL2NUM);
++}
++
++//------------------------------------------------------------
++
++void Print_Header (BYTE option) {
++
++ FILE_VAR
++
++ GET_OBJ( option )
++
++ if (GSpeed_sel[0]) PRINT(OUT_OBJ " 1G ");
++ else if (GSpeed_sel[1]) PRINT(OUT_OBJ " 100M ");
++ else PRINT(OUT_OBJ " 10M ");
++
++ switch (TestMode) {
++ case 0 : PRINT(OUT_OBJ "Tx/Rx frame checking \n" ); break;
++ case 1 : PRINT(OUT_OBJ "Tx output 0xff frame \n" ); break;
++ case 2 : PRINT(OUT_OBJ "Tx output 0x55 frame \n" ); break;
++ case 3 : PRINT(OUT_OBJ "Tx output random frame \n" ); break;
++ case 4 : PRINT(OUT_OBJ "Tx output ARP frame \n" ); break;
++ case 5 : PRINT(OUT_OBJ "Tx output 0x%08lx frame \n", UserDVal); break;
++ case 6 : PRINT(OUT_OBJ "IO delay testing \n" ); break;
++ case 7 : PRINT(OUT_OBJ "IO delay testing(Strength) \n" ); break;
++ case 8 : PRINT(OUT_OBJ "Tx frame \n" ); break;
++ case 9 : PRINT(OUT_OBJ "Rx frame checking \n" ); break;
++ }
++}
++
++//------------------------------------------------------------
++void PrintIO_Header (BYTE option) {
++
++ FILE_VAR
++
++ GET_OBJ( option )
++
++ if ( IOStrength ) {
++ if (GSpeed_sel[0]) PRINT(OUT_OBJ "[Strength %ld][1G ]========================================\n", IOStr_i);
++ else if (GSpeed_sel[1]) PRINT(OUT_OBJ "[Strength %ld][100M]========================================\n", IOStr_i);
++ else PRINT(OUT_OBJ "[Strength %ld][10M ]========================================\n", IOStr_i);
++ } else {
++ if (GSpeed_sel[0]) PRINT(OUT_OBJ "[1G ]========================================\n");
++ else if (GSpeed_sel[1]) PRINT(OUT_OBJ "[100M]========================================\n");
++ else PRINT(OUT_OBJ "[10M ]========================================\n");
++ }
++
++#ifdef Enable_Old_Style
++ if (Enable_RMII) PRINT(OUT_OBJ "Tx:SCU48[ %2d]= ", IOdly_out_shf);
++ else PRINT(OUT_OBJ "Tx:SCU48[%2d:%2d]= ", IOdly_out_shf+3, IOdly_out_shf);
++
++ for (IOdly_j = IOdly_out_str; IOdly_j <= IOdly_out_end; IOdly_j+=IOdly_incval) {
++ IOdly_out = valary[IOdly_j];
++ PRINT(OUT_OBJ "%2x", IOdly_out);
++ }
++
++ PRINT(OUT_OBJ "\n ");
++ for (IOdly_j = IOdly_out_str; IOdly_j <= IOdly_out_end; IOdly_j+=IOdly_incval) {
++ if (IOdly_out_reg_idx == IOdly_j) PRINT(OUT_OBJ " |");
++ else PRINT(OUT_OBJ " ");
++ }
++#else
++ PRINT(OUT_OBJ "Rx:SCU48[%2d:%2d]= ", IOdly_in_shf+3, IOdly_in_shf);
++
++ for (IOdly_i = IOdly_in_str; IOdly_i <= IOdly_in_end; IOdly_i+=IOdly_incval) {
++ IOdly_in = valary[IOdly_i];
++ PRINT(OUT_OBJ "%2x", IOdly_in);
++ }
++
++ PRINT(OUT_OBJ "\n ");
++ for (IOdly_i = IOdly_in_str; IOdly_i <= IOdly_in_end; IOdly_i+=IOdly_incval) {
++ if (IOdly_in_reg_idx == IOdly_i) PRINT(OUT_OBJ " |");
++ else PRINT(OUT_OBJ " ");
++ }
++#endif
++
++ PRINT(OUT_OBJ "\n");
++} // End void PrintIO_Header (BYTE option)
++
++//------------------------------------------------------------
++void PrintIO_LineS (BYTE option) {
++
++ FILE_VAR
++
++ GET_OBJ( option )
++
++
++#ifdef Enable_Old_Style
++ if (IOdly_in_reg == IOdly_in) {
++ PRINT(OUT_OBJ "Rx:SCU48[%2d:%2d]=%01x:-", IOdly_in_shf+3, IOdly_in_shf, IOdly_in);
++ }
++ else {
++ PRINT(OUT_OBJ "Rx:SCU48[%2d:%2d]=%01x: ", IOdly_in_shf+3, IOdly_in_shf, IOdly_in);
++ }
++#else
++ if (Enable_RMII) {
++ if (IOdly_out_reg == IOdly_out) {
++ PRINT(OUT_OBJ "Tx:SCU48[ %2d]=%01x:-", IOdly_out_shf, IOdly_out);
++ }
++ else {
++ PRINT(OUT_OBJ "Tx:SCU48[ %2d]=%01x: ", IOdly_out_shf, IOdly_out);
++ }
++ } else {
++ if (IOdly_out_reg == IOdly_out) {
++ PRINT(OUT_OBJ "Tx:SCU48[%2d:%2d]=%01x:-", IOdly_out_shf+3, IOdly_out_shf, IOdly_out);
++ }
++ else {
++ PRINT(OUT_OBJ "Tx:SCU48[%2d:%2d]=%01x: ", IOdly_out_shf+3, IOdly_out_shf, IOdly_out);
++ }
++ }
++#endif
++} // void PrintIO_LineS (BYTE option)
++
++//------------------------------------------------------------
++void PrintIO_Line (BYTE option) {
++
++ FILE_VAR
++
++ GET_OBJ( option )
++
++ if ( ( IOdly_in_reg == IOdly_in ) && ( IOdly_out_reg == IOdly_out ) ) {
++ if (dlymap[IOdly_i][IOdly_j]) PRINT(OUT_OBJ " X");
++ else PRINT(OUT_OBJ " O");
++ }
++ else {
++ if (dlymap[IOdly_i][IOdly_j]) PRINT(OUT_OBJ " x");
++ else PRINT(OUT_OBJ " o");
++ }
++} // End void PrintIO_Line (BYTE option)
++
++//------------------------------------------------------------
++void PrintIO_Line_LOG (void) {
++#ifndef SLT_UBOOT
++#ifdef Enable_Old_Style
++ if (Enable_RMII) fprintf(fp_log, "\nTx:SCU48[ %2d]=%2x, ", IOdly_out_shf, IOdly_out);
++ else fprintf(fp_log, "\nTx:SCU48[%2d:%2d]=%2x, ", IOdly_out_shf+3, IOdly_out_shf, IOdly_out);
++
++ fprintf(fp_log, "Rx:SCU48[%2d:%2d]=%01x: ", IOdly_in_shf+3, IOdly_in_shf, IOdly_in);
++
++ if (dlymap[IOdly_i][IOdly_j]) fprintf(fp_log, " X\n");
++ else fprintf(fp_log, " O\n");
++#else
++ fprintf(fp_log, "\nRx:SCU48[%2d:%2d]=%2x, ", IOdly_in_shf+3, IOdly_in_shf, IOdly_in);
++
++ if (Enable_RMII) fprintf(fp_log, "Tx:SCU48[ %2d]=%01x: ", IOdly_out_shf, IOdly_out);
++ else fprintf(fp_log, "Tx:SCU48[%2d:%2d]=%01x: ", IOdly_out_shf+3, IOdly_out_shf, IOdly_out);
++
++ if (dlymap[IOdly_i][IOdly_j]) fprintf(fp_log, " X\n");
++ else fprintf(fp_log, " O\n");
++#endif
++#endif
++}
++
++//------------------------------------------------------------
++// main
++//------------------------------------------------------------
++void Calculate_LOOP_CheckNum (void) {
++
++#define ONE_MBYTE 1048576
++
++ #ifdef CheckDataEveryTime
++ LOOP_CheckNum = 1;
++ #else
++ if (IOTiming || IOTimingBund || (GSpeed == SET_1G_100M_10MBPS)) {
++ LOOP_CheckNum = LOOP_MAX;
++ }
++ else {
++ switch ( GSpeed ) {
++ case SET_1GBPS : CheckBuf_MBSize = MOVE_DATA_MB_SEC ; break; // 1G
++ case SET_100MBPS : CheckBuf_MBSize = (MOVE_DATA_MB_SEC >> 3); break; // 100M ~ 1G / 8
++ case SET_10MBPS : CheckBuf_MBSize = (MOVE_DATA_MB_SEC >> 6); break; // 10M ~ 1G / 64
++ }
++ LOOP_CheckNum = ( CheckBuf_MBSize / ( ((DES_NUMBER * DMA_PakSize) / ONE_MBYTE ) + 1) );
++ }
++ #endif
++}
++
++//------------------------------------------------------------
++void TestingSetup (void) {
++ #ifdef DbgPrn_FuncHeader
++ printf ("TestingSetup\n");
++ Debug_delay();
++ #endif
++
++ #ifdef SLT_UBOOT
++ #else
++ #ifdef Rand_Sed
++ srand((unsigned) Rand_Sed);
++ #else
++ srand((unsigned) timestart);
++ #endif
++ #endif
++
++ //[Disable VGA]--------------------
++ #ifdef Disable_VGA
++ if ( LOOP_INFINI & ~(BurstEnable || IOTiming) ) {
++ VGAModeVld = 1;
++ outp(0x3d4, 0x17);
++ VGAMode = inp(0x3d5);
++ outp(0x3d4, 0x17);
++ outp(0x3d5, 0);
++ }
++ #endif
++
++ //[Setup]--------------------
++ setup_framesize();
++ setup_buf();
++}
++
++//------------------------------------------------------------
++// Return 1 ==> fail
++// Return 0 ==> PASS
++//------------------------------------------------------------
++char TestingLoop (ULONG loop_checknum) {
++ char checkprd;
++ char looplast;
++ char checken;
++
++ #ifdef SLT_UBOOT
++ #else
++ clock_t timeold;
++ #endif
++
++ #ifdef DbgPrn_FuncHeader
++ printf ("TestingLoop: %d\n", Loop);
++ Debug_delay();
++ #endif
++
++ if ( DbgPrn_DumpMACCnt )
++ dump_mac_ROreg();
++
++ //[Setup]--------------------
++ Loop = 0;
++ checkprd = 0;
++ checken = 0;
++ looplast = 0;
++
++ setup_des( 0 );
++
++ #ifdef SLT_UBOOT
++ #else
++ timeold = clock();
++ #endif
++
++ while ( (Loop < LOOP_MAX) || LOOP_INFINI ) {
++ looplast = !LOOP_INFINI && (Loop == LOOP_MAX - 1);
++
++ #ifdef CheckRxBuf
++ if (!BurstEnable) {
++ checkprd = ((Loop % loop_checknum) == (loop_checknum - 1));
++ }
++ checken = looplast | checkprd;
++ #endif
++
++ if ( DataDelay & ( Loop == 0 ) ) {
++ printf ("Press any key to start...\n");
++ GET_CAHR();
++ }
++
++#ifdef DbgPrn_FuncHeader
++ if ( DbgPrn_BufAdr ) {
++ printf ("for start ======> %d/%d(%d) looplast:%d checkprd:%d checken:%d\n", Loop, LOOP_MAX, LOOP_INFINI, looplast, checkprd, checken);
++ Debug_delay();
++ }
++#endif
++
++ //[Check DES]--------------------
++ if ( check_des(Loop, checken) ) {
++ //descriptor error
++ #ifdef CheckRxBuf
++ DES_NUMBER = CheckDesFail_DesNum + 1;
++ if ( checkprd ) {
++ check_buf(loop_checknum);
++ }
++ else {
++ check_buf((LOOP_MAX % loop_checknum));
++ }
++ DES_NUMBER = DES_NUMBER_Org;
++ #endif
++
++ if (DbgPrn_DumpMACCnt)
++ dump_mac_ROreg();
++
++ return(1);
++ }
++
++ //[Check Buf]--------------------
++ if ( RxDataEnable && checken ) {
++ #ifdef SLT_UBOOT
++ #else
++ timeused = (clock() - timeold) / (double) CLK_TCK;
++ #endif
++
++ if ( checkprd ) {
++ #ifdef SLT_DOS
++ #else
++ #ifdef SLT_UBOOT
++ #else
++ printf("[run loop:%3d] BandWidth: %7.2f Mbps, %6.2f sec\n", loop_checknum, ((double)loop_checknum * (double)DES_NUMBER * Avg_frame_len * 8.0) / ((double)timeused * 1000000.0), timeused);
++ fprintf(fp_log, "[run loop:%3d] BandWidth: %7.2f Mbps, %6.2f sec\n", loop_checknum, ((double)loop_checknum * (double)DES_NUMBER * Avg_frame_len * 8.0) / ((double)timeused * 1000000.0), timeused);
++ #endif
++ #endif
++
++ #ifdef CheckRxBuf
++ if ( check_buf( loop_checknum ) )
++ return(1);
++ #endif
++ }
++ else {
++ #ifdef SLT_DOS
++ #else
++ #ifdef SLT_UBOOT
++ #else
++ printf("[run loop:%3d] BandWidth: %7.2f Mbps, %6.2f sec\n", (LOOP_MAX % loop_checknum), ((double)(LOOP_MAX % loop_checknum) * (double)DES_NUMBER * Avg_frame_len * 8.0) / ((double)timeused * 1000000.0), timeused);
++ fprintf(fp_log, "[run loop:%3d] BandWidth: %7.2f Mbps, %6.2f sec\n", (LOOP_MAX % loop_checknum), ((double)(LOOP_MAX % loop_checknum) * (double)DES_NUMBER * Avg_frame_len * 8.0) / ((double)timeused * 1000000.0), timeused);
++ #endif
++ #endif
++
++ #ifdef CheckRxBuf
++ if ( check_buf( ( LOOP_MAX % loop_checknum ) ) )
++ return(1);
++ #endif
++ } // End if ( checkprd )
++
++ #ifdef SelectSimpleDes
++ #else
++ if ( !looplast )
++ setup_des_loop( Loop );
++ #endif
++
++ #ifdef SLT_DOS
++ #else
++ #ifdef SLT_UBOOT
++ #else
++ timeold = clock();
++ #endif
++ #endif
++
++ } // End if ( RxDataEnable && checken )
++
++ #ifdef SelectSimpleDes
++ if ( !looplast )
++ setup_des_loop( Loop );
++ #endif
++
++ if ( LOOP_INFINI ) {
++ printf("===============> Loop: %d \r", Loop);
++ }
++ else if (TestMode == 0) {
++ if (!(DbgPrn_BufAdr || IOTimingBund))
++ printf(" %d \r", Loop);
++// switch (Loop % 4) {
++// case 0x00: printf("| %d \r", Loop); break;
++// case 0x01: printf("/ %d \r", Loop); break;
++// case 0x02: printf("- %d \r", Loop); break;
++// default : printf("\ %d \r", Loop); break;
++// }
++ }
++
++ if ( DbgPrn_BufAdr ) {
++ printf ("for end ======> %d/%d(%d)\n", Loop, LOOP_MAX, LOOP_INFINI);
++ Debug_delay();
++ }
++
++ Loop++;
++ } // End while ((Loop < LOOP_MAX) || LOOP_INFINI)
++
++ Loop_rl[GSpeed_idx] = Loop;
++
++ return(0);
++} // End char TestingLoop (ULONG loop_checknum)
++
++
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/Makefile b/arch/arm/cpu/arm926ejs/aspeed/Makefile
+new file mode 100644
+index 0000000..378745e
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/Makefile
+@@ -0,0 +1,53 @@
++# 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$(SOC).a
++
++COBJS = timer.o
++COBJS += reset.o
++COBJS += mactest.o
++COBJS += DRAM_SPI.o
++COBJS += IO.o
++COBJS += LIB.o
++COBJS += MAC.o
++COBJS += NCSI.o
++COBJS += PCI_SPI.o
++COBJS += PHY.o
++COBJS += SPIM.o
++COBJS += STDUBOOT.o
++COBJS += PLLTESTU.o
++COBJS += TRAPTEST.o
++COBJS += STRESS.o
++
++SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
++START := $(addprefix $(obj),$(START))
++
++all: $(obj).depend $(LIB)
++
++$(LIB): $(OBJS)
++ $(AR) $(ARFLAGS) $@ $(OBJS)
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/NCSI.H b/arch/arm/cpu/arm926ejs/aspeed/NCSI.H
+new file mode 100644
+index 0000000..a0e448b
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/NCSI.H
+@@ -0,0 +1,189 @@
++/*
++ * 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 NCSI_H
++#define NCSI_H
++
++#include "TYPEDEF.H"
++
++//---------------------------------------------------------
++// Define
++//---------------------------------------------------------
++#define MAX_PACKAGE_NUM 8 // 1 ~ 8
++#define MAX_CHANNEL_NUM 4 // 1 ~ 32
++//#define Enable_NCSI_LOOP_INFINI //[off]
++
++//---------------------------------------------------------
++// Function
++//---------------------------------------------------------
++#define SENT_RETRY_COUNT 1
++#define NCSI_RxDESNum 50
++
++//#define NCSI_Skip_Phase1_DeSelectPackage
++//#define NCSI_Skip_DeSelectPackage
++//#define NCSI_Skip_DiSChannel
++//#define NCSI_EnableDelay_DeSelectPackage
++//#define NCSI_EnableDelay_GetLinkStatus
++//#define NCSI_EnableDelay_EachPackage
++//#define Print_Version_ID
++//#define Print_PackageName
++
++//---------------------------------------------------------
++// PCI DID/VID & Manufacturer ID
++//---------------------------------------------------------
++#define ManufacturerID_Intel 0x00000157 //343
++#define ManufacturerID_Broadcom 0x0000113d //4413
++#define ManufacturerID_Mellanox 0x000002c9 //713
++
++//PCI VID: [163c]intel
++//PCI VID: [8086]Intel Corporation
++//PCI VID: [8087]Intel
++//PCI VID: [14e4]Broadcom Corporation
++//PCI VID: [15b3]Mellanox
++#define PCI_DID_VID_Intel_82574L 0x10d38086 // IntelR 82574L Gigabit Ethernet Controller
++#define PCI_DID_VID_Intel_82575_10d6 0x10d68086 // 82566 DM-2-gigabyte
++#define PCI_DID_VID_Intel_82575_10a7 0x10a78086 // 82575EB Gigabit Network Connection
++#define PCI_DID_VID_Intel_82575_10a9 0x10a98086 // 82575EB Gigabit Network Connection
++#define PCI_DID_VID_Intel_82576_10c9 0x10c98086 //*82576 Gigabit ET Dual Port Server Adapter
++#define PCI_DID_VID_Intel_82576_10e6 0x10e68086 // 82576 Gigabit Network Connection
++#define PCI_DID_VID_Intel_82576_10e7 0x10e78086 // 82576 Gigabit Network Connection
++#define PCI_DID_VID_Intel_82576_10e8 0x10e88086 // E64750-xxx Intel Gigabit ET Quad Port Server Adapter
++#define PCI_DID_VID_Intel_82576_1518 0x15188086 // 82576NS SerDes Gigabit Network Connectio
++#define PCI_DID_VID_Intel_82576_1526 0x15268086 // Intel Gigabit ET2 Quad Port Server Adapter
++#define PCI_DID_VID_Intel_82576_150a 0x150a8086 // 82576NS Gigabit Ethernet Controller
++#define PCI_DID_VID_Intel_82576_150d 0x150d8086 // 82576 Gigabit Backplane Connection
++#define PCI_DID_VID_Intel_82599_10fb 0x10fb8086 // 10 Gb Ethernet controller
++#define PCI_DID_VID_Intel_82599_1557 0x15578086 //
++#define PCI_DID_VID_Intel_I350_1521 0x15218086 //
++#define PCI_DID_VID_Intel_I350_1523 0x15238086 //
++#define PCI_DID_VID_Intel_I210 0x15338086 //
++#define PCI_DID_VID_Intel_X540 0x15288086 //
++#define PCI_DID_VID_Broadcom_BCM5718 0x165614e4 //
++#define PCI_DID_VID_Broadcom_BCM5720 0x165f14e4 //
++#define PCI_DID_VID_Broadcom_BCM5725 0x164314e4 //
++#define PCI_DID_VID_Mellanox_ConnectX_3 0x100315b3 //*
++
++//---------------------------------------------------------
++// Delay (ms)
++//---------------------------------------------------------
++#define Delay_EachPackage 1000
++#define Delay_DeSelectPackage 50
++#define Delay_GetLinkStatus 50
++
++//---------------------------------------------------------
++// NCSI Parameter
++//---------------------------------------------------------
++//Command and Response Type
++#define CLEAR_INITIAL_STATE 0x00 //M
++#define SELECT_PACKAGE 0x01 //M
++#define DESELECT_PACKAGE 0x02 //M
++#define ENABLE_CHANNEL 0x03 //M
++#define DISABLE_CHANNEL 0x04 //M
++#define RESET_CHANNEL 0x05 //M
++#define ENABLE_CHANNEL_NETWORK_TX 0x06 //M
++#define DISABLE_CHANNEL_NETWORK_TX 0x07 //M
++#define AEN_ENABLE 0x08
++#define SET_LINK 0x09 //M
++#define GET_LINK_STATUS 0x0A //M
++#define SET_VLAN_FILTER 0x0B //M
++#define ENABLE_VLAN 0x0C //M
++#define DISABLE_VLAN 0x0D //M
++#define SET_MAC_ADDRESS 0x0E //M
++#define ENABLE_BROADCAST_FILTERING 0x10 //M
++#define DISABLE_BROADCAST_FILTERING 0x11 //M
++#define ENABLE_GLOBAL_MULTICAST_FILTERING 0x12
++#define DISABLE_GLOBAL_MULTICAST_FILTERING 0x13
++#define SET_NCSI_FLOW_CONTROL 0x14
++#define GET_VERSION_ID 0x15 //M
++#define GET_CAPABILITIES 0x16 //M
++#define GET_PARAMETERS 0x17 //M
++#define GET_CONTROLLER_PACKET_STATISTICS 0x18
++#define GET_NCSI_STATISTICS 0x19
++#define GET_NCSI_PASS_THROUGH_STATISTICS 0x1A
++
++//Standard Response Code
++#define COMMAND_COMPLETED 0x00
++#define COMMAND_FAILED 0x01
++#define COMMAND_UNAVAILABLE 0x02
++#define COMMAND_UNSUPPORTED 0x03
++
++//Standard Reason Code
++#define NO_ERROR 0x0000
++#define INTERFACE_INITIALIZATION_REQUIRED 0x0001
++#define PARAMETER_IS_INVALID 0x0002
++#define CHANNEL_NOT_READY 0x0003
++#define PACKAGE_NOT_READY 0x0004
++#define INVALID_PAYLOAD_LENGTH 0x0005
++#define UNKNOWN_COMMAND_TYPE 0x7FFF
++
++//SET_MAC_ADDRESS
++#define UNICAST ( 0x00 << 5 )
++#define MULTICAST ( 0x01 << 5 )
++#define DISABLE_MAC_ADDRESS_FILTER 0x00
++#define ENABLE_MAC_ADDRESS_FILTER 0x01
++
++//GET_LINK_STATUS
++#define LINK_DOWN 0
++#define LINK_UP 1
++
++#define NCSI_RxDMA_PakSize 2048
++#define NCSI_RxDMA_BASE (DMA_BASE+0x00100000)
++
++//---------------------------------------------------------
++// Variable
++//---------------------------------------------------------
++//NC-SI Command Packet
++typedef struct {
++//Ethernet Header
++ unsigned char DA[6]; // Destination Address
++ unsigned char SA[6]; // Source Address
++ unsigned short EtherType; // DMTF NC-SI, it should be 0x88F8
++//NC-SI Control Packet
++ unsigned char MC_ID; // Management Controller should set this field to 0x00
++ unsigned char Header_Revision; // For NC-SI 1.0 spec, this field has to set 0x01
++ unsigned char Reserved_1; // Reserved has to set to 0x00
++ unsigned char IID; // Instance ID
++ unsigned char Command;
++ unsigned char Channel_ID;
++ unsigned short Payload_Length; // Payload Length = 12 bits, 4 bits are reserved
++ unsigned long Reserved_2;
++ unsigned long Reserved_3;
++
++ unsigned short Reserved_4;
++ unsigned short Reserved_5;
++ unsigned short Response_Code;
++ unsigned short Reason_Code;
++ unsigned char Payload_Data[64];
++} NCSI_Command_Packet;
++
++//NC-SI Response Packet
++typedef struct {
++ unsigned char DA[6];
++ unsigned char SA[6];
++ unsigned short EtherType; //DMTF NC-SI
++//NC-SI Control Packet
++ unsigned char MC_ID; //Management Controller should set this field to 0x00
++ unsigned char Header_Revision; //For NC-SI 1.0 spec, this field has to set 0x01
++ unsigned char Reserved_1; //Reserved has to set to 0x00
++ unsigned char IID; //Instance ID
++ unsigned char Command;
++ unsigned char Channel_ID;
++ unsigned short Payload_Length; //Payload Length = 12 bits, 4 bits are reserved
++ unsigned short Reserved_2;
++ unsigned short Reserved_3;
++ unsigned short Reserved_4;
++ unsigned short Reserved_5;
++
++ unsigned short Response_Code;
++ unsigned short Reason_Code;
++ unsigned char Payload_Data[64];
++} NCSI_Response_Packet;
++
++#endif // NCSI_H
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/NCSI.c b/arch/arm/cpu/arm926ejs/aspeed/NCSI.c
+new file mode 100644
+index 0000000..7de06c3
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/NCSI.c
+@@ -0,0 +1,934 @@
++/*
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#define NCSI_C
++static const char ThisFile[] = "NCSI.c";
++
++#include "SWFUNC.H"
++
++#ifdef SLT_UBOOT
++ #include <common.h>
++ #include <command.h>
++ #include <COMMINF.H>
++ #include <NCSI.H>
++ #include <IO.H>
++#endif
++#ifdef SLT_DOS
++ #include <stdio.h>
++ #include <stdlib.h>
++ #include <conio.h>
++ #include <string.h>
++ #include "COMMINF.H"
++ #include "NCSI.H"
++ #include "IO.H"
++#endif
++
++NCSI_Command_Packet NCSI_Request_SLT;
++NCSI_Response_Packet NCSI_Respond_SLT;
++int InstanceID;
++int NCSI_RxTimeOutScale;
++ULONG NCSI_RxDesBase;
++ULONG NCSI_TxDWBUF[512];
++ULONG NCSI_RxDWBUF[512];
++char NCSI_CommandStr[512];
++unsigned char *NCSI_TxByteBUF;
++unsigned char *NCSI_RxByteBUF;
++unsigned char NCSI_Payload_Data[16];
++unsigned long Payload_Checksum_NCSI = 0x00000000;
++ULONG select_flag[MAX_PACKAGE_NUM];
++
++ULONG DWSwap_SLT (ULONG in) {
++ return( ((in & 0xff000000) >> 24)
++ | ((in & 0x00ff0000) >> 8)
++ | ((in & 0x0000ff00) << 8)
++ | ((in & 0x000000ff) << 24)
++ );
++}
++USHORT WDSwap_SLT (USHORT in) {
++ return( ((in & 0xff00) >> 8)
++ | ((in & 0x00ff) << 8)
++ );
++}
++
++//------------------------------------------------------------
++int FindErr_NCSI (int value) {
++ NCSI_LinkFail_Val = NCSI_LinkFail_Val | value;
++ Err_Flag = Err_Flag | Err_NCSI_LinkFail;
++ if ( DbgPrn_ErrFlg )
++ printf ("\nErr_Flag: [%08lx] NCSI_LinkFail_Val: [%08lx]\n", Err_Flag, NCSI_LinkFail_Val);
++
++ return(1);
++}
++
++//------------------------------------------------------------
++// PHY IC(NC-SI)
++//------------------------------------------------------------
++void ncsi_respdump ( NCSI_Response_Packet *in ) {
++ printf ("DA : %02x %02x %02x %02x %02x %02x\n", in->DA[5], in->DA[4], in->DA[3], in->DA[2], in->DA[1], in->DA[0]);
++ printf ("SA : %02x %02x %02x %02x %02x %02x\n", in->SA[5], in->SA[4], in->SA[3], in->SA[2], in->SA[1], in->SA[0]);
++ printf ("EtherType : %04x\n", in->EtherType );//DMTF NC-SI
++ printf ("MC_ID : %02x\n", in->MC_ID );//Management Controller should set this field to 0x00
++ printf ("Header_Revision: %02x\n", in->Header_Revision );//For NC-SI 1.0 spec, this field has to set 0x01
++// printf ("Reserved_1 : %02x\n", in->Reserved_1 ); //Reserved has to set to 0x00
++ printf ("IID : %02x\n", in->IID );//Instance ID
++ printf ("Command : %02x\n", in->Command );
++ printf ("Channel_ID : %02x\n", in->Channel_ID );
++ printf ("Payload_Length : %04x\n", in->Payload_Length );//Payload Length = 12 bits, 4 bits are reserved
++// printf ("Reserved_2 : %04x\n", in->Reserved_2 );
++// printf ("Reserved_3 : %04x\n", in->Reserved_3 );
++// printf ("Reserved_4 : %04x\n", in->Reserved_4 );
++// printf ("Reserved_5 : %04x\n", in->Reserved_5 );
++ printf ("Response_Code : %04x\n", in->Response_Code );
++ printf ("Reason_Code : %04x\n", in->Reason_Code );
++ printf ("Payload_Data : %02x%02x%02x%02x\n", in->Payload_Data[ 3], in->Payload_Data[ 2], in->Payload_Data[ 1], in->Payload_Data[ 0]);
++// printf ("Payload_Data : %02x%02x%02x%02x\n", in->Payload_Data[ 7], in->Payload_Data[ 6], in->Payload_Data[ 5], in->Payload_Data[ 4]);
++// printf ("Payload_Data : %02x%02x%02x%02x\n", in->Payload_Data[11], in->Payload_Data[10], in->Payload_Data[ 9], in->Payload_Data[ 8]);
++// printf ("Payload_Data : %02x%02x%02x%02x\n", in->Payload_Data[15], in->Payload_Data[14], in->Payload_Data[13], in->Payload_Data[12]);
++// printf ("Payload_Data : %02x%02x%02x%02x\n", in->Payload_Data[19], in->Payload_Data[18], in->Payload_Data[17], in->Payload_Data[16]);
++// printf ("Payload_Data : %02x%02x%02x%02x\n", in->Payload_Data[23], in->Payload_Data[22], in->Payload_Data[21], in->Payload_Data[20]);
++}
++
++//------------------------------------------------------------
++void NCSI_Struct_Initialize_SLT (void) {
++ int i;
++
++ ULONG NCSI_RxDatBase;
++
++ InstanceID = 0;
++ NCSI_RxTimeOutScale = 1;
++
++ for (i = 0; i < 6; i++) {
++ NCSI_Request_SLT.DA[i] = 0xFF;
++ }
++
++ for (i = 0; i < 6; i++) {
++// NCSI_Request.SA[i] = i<<2;
++ NCSI_Request_SLT.SA[i] = SA[i];
++ }
++
++ NCSI_Request_SLT.EtherType = WDSwap_SLT(0x88F8); // EtherType = 0x88F8 (DMTF NC-SI) page 50, table 8, NC-SI spec. version 1.0.0
++ NCSI_Request_SLT.MC_ID = 0;
++ NCSI_Request_SLT.Header_Revision = 0x01;
++ NCSI_Request_SLT.Reserved_1 = 0;
++ NCSI_Request_SLT.Reserved_2 = 0;
++ NCSI_Request_SLT.Reserved_3 = 0;
++
++ NCSI_TxByteBUF = (unsigned char *) &NCSI_TxDWBUF[0];
++ NCSI_RxByteBUF = (unsigned char *) &NCSI_RxDWBUF[0];
++
++ NCSI_RxDesBase = H_RDES_BASE;
++ NCSI_RxDatBase = NCSI_RxDMA_BASE;
++
++ for (i = 0; i < NCSI_RxDESNum - 1; i++) {
++ WriteSOC_DD( ( NCSI_RxDesBase + 0 ), 0x00000000 );
++ WriteSOC_DD( ( NCSI_RxDesBase + 4 ), 0x00000000 );
++ WriteSOC_DD( ( NCSI_RxDesBase + 8 ), 0x00000000 );
++ WriteSOC_DD( ( NCSI_RxDesBase + 0x0C ), (NCSI_RxDatBase + CPU_BUS_ADDR_SDRAM_OFFSET) ); // 20130730
++ NCSI_RxDesBase += 16;
++ NCSI_RxDatBase += NCSI_RxDMA_PakSize;
++ }
++ WriteSOC_DD( ( NCSI_RxDesBase + 0 ), EOR_IniVal );
++ WriteSOC_DD( ( NCSI_RxDesBase + 4 ), 0x00000000 );
++ WriteSOC_DD( ( NCSI_RxDesBase + 8 ), 0x00000000 );
++ WriteSOC_DD( ( NCSI_RxDesBase + 0x0C ), (NCSI_RxDatBase + CPU_BUS_ADDR_SDRAM_OFFSET) ); // 20130730
++
++ NCSI_RxDesBase = H_RDES_BASE;
++}
++
++//------------------------------------------------------------
++void Calculate_Checksum_NCSI (unsigned char *buffer_base, int Length) {
++ ULONG CheckSum = 0;
++ ULONG Data;
++ ULONG Data1;
++ int i;
++
++ // Calculate checksum is from byte 14 of ethernet Haeder and Control packet header
++ // Page 50, NC-SI spec. ver. 1.0.0 form DMTF
++ for (i = 14; i < Length; i += 2 ) {
++ Data = buffer_base[i];
++ Data1 = buffer_base[i + 1];
++ CheckSum += ((Data << 8) + Data1);
++ }
++ Payload_Checksum_NCSI = DWSwap_SLT(~(CheckSum) + 1); //2's complement
++}
++
++//------------------------------------------------------------
++// return 0: it is PASS
++// return 1: it is FAIL
++//------------------------------------------------------------
++char NCSI_Rx_SLT (unsigned char command) {
++
++#define NCSI_RX_RETRY_TIME 2
++ int timeout = 0;
++ int bytesize;
++ int dwsize;
++ int i;
++ int retry = 0;
++ char ret = 1;
++
++ ULONG NCSI_RxDatBase;
++ ULONG NCSI_RxDesDat;
++ ULONG NCSI_RxData;
++
++
++ do {
++ WriteSOC_DD( ( H_MAC_BASE + 0x1C ), 0x00000000 );//Rx Poll
++
++ do {
++ NCSI_RxDesDat = ReadSOC_DD(NCSI_RxDesBase);
++ if ( ++timeout > TIME_OUT_NCSI * NCSI_RxTimeOutScale ) {
++ #ifdef SLT_DOS
++ fprintf(fp_log, "[Cmd:%02X][NCSI-RxDesOwn] %08lX \n", command, NCSI_RxDesDat );
++ #endif
++ return( FindErr(Err_NCSI_Check_RxOwnTimeOut) );
++ }
++ } while( HWOwnRx(NCSI_RxDesDat) );
++
++ #ifdef CheckRxErr
++ if (NCSI_RxDesDat & 0x00040000) {
++ #ifdef SLT_DOS
++ fprintf(fp_log, "[RxDes] Error RxErr %08lx\n", NCSI_RxDesDat);
++ #endif
++ FindErr_Des(Check_Des_RxErr);
++ }
++ #endif
++
++ #ifdef CheckOddNibble
++ if (NCSI_RxDesDat & 0x00400000) {
++ #ifdef SLT_DOS
++ fprintf(fp_log, "[RxDes] Odd Nibble %08lx\n", NCSI_RxDesDat);
++ #endif
++ FindErr_Des(Check_Des_OddNibble);
++ }
++ #endif
++
++ #ifdef CheckCRC
++ if (NCSI_RxDesDat & 0x00080000) {
++ #ifdef SLT_DOS
++ fprintf(fp_log, "[RxDes] Error CRC %08lx\n", NCSI_RxDesDat);
++ #endif
++ FindErr_Des(Check_Des_CRC);
++ }
++ #endif
++
++ #ifdef CheckRxFIFOFull
++ if (NCSI_RxDesDat & 0x00800000) {
++ #ifdef SLT_DOS
++ fprintf(fp_log, "[RxDes] Error Rx FIFO Full %08lx\n", NCSI_RxDesDat);
++ #endif
++ FindErr_Des(Check_Des_RxFIFOFull);
++ }
++ #endif
++
++ // Get point of RX DMA buffer
++ NCSI_RxDatBase = ReadSOC_DD( NCSI_RxDesBase + 0x0C );
++ NCSI_RxData = ReadSOC_DD( NCSI_RxDatBase + 0x0C );
++
++ if ( HWEOR( NCSI_RxDesDat ) ) {
++ // it is last the descriptor in the receive Ring
++ WriteSOC_DD( NCSI_RxDesBase , EOR_IniVal );
++ NCSI_RxDesBase = H_RDES_BASE;
++ }
++ else {
++ WriteSOC_DD( NCSI_RxDesBase , 0x00000000 );
++ NCSI_RxDesBase += 16;
++ }
++
++ // Get RX valid data in offset 00h of RXDS#0
++ bytesize = (NCSI_RxDesDat & 0x3fff);
++
++ // Fill up to multiple of 4
++ if ( ( bytesize % 4 ) != 0 )
++ dwsize = ( bytesize >> 2 ) + 1;
++ else
++ dwsize = bytesize >> 2;
++
++ #ifdef SLT_DOS
++ if ( PrintNCSIEn )
++ fprintf(fp_log ,"[Rx] %d bytes(%xh)\n", bytesize, bytesize);
++ #endif
++
++ for (i = 0; i < dwsize; i++) {
++ NCSI_RxDWBUF[i] = ReadSOC_DD(NCSI_RxDatBase + ( i << 2 ));
++ if ( PrintNCSIEn ) {
++ if ( i == ( dwsize - 1 ) ) {
++ switch (bytesize % 4) {
++ case 0 : NCSI_RxDWBUF[i] = NCSI_RxDWBUF[i] & 0xffffffff; break;
++ case 3 : NCSI_RxDWBUF[i] = NCSI_RxDWBUF[i] & 0xffffff ; break;
++ case 2 : NCSI_RxDWBUF[i] = NCSI_RxDWBUF[i] & 0xffff ; break;
++ case 1 : NCSI_RxDWBUF[i] = NCSI_RxDWBUF[i] & 0xff ; break;
++ }
++ #ifdef SLT_DOS
++ switch (bytesize % 4) {
++ case 0 : fprintf(fp_log ,"[Rx%02d]%08lx %08lx\n", i, NCSI_RxDWBUF[i], DWSwap_SLT(NCSI_RxDWBUF[i]) ); break;
++ case 3 : fprintf(fp_log ,"[Rx%02d]--%06lx %06lx--\n", i, NCSI_RxDWBUF[i], DWSwap_SLT(NCSI_RxDWBUF[i]) >> 8 ); break;
++ case 2 : fprintf(fp_log ,"[Rx%02d]----%04lx %04lx----\n", i, NCSI_RxDWBUF[i], DWSwap_SLT(NCSI_RxDWBUF[i]) >> 16 ); break;
++ case 1 : fprintf(fp_log ,"[Rx%02d]------%02lx %02lx------\n", i, NCSI_RxDWBUF[i], DWSwap_SLT(NCSI_RxDWBUF[i]) >> 24 ); break;
++ default : fprintf(fp_log ,"[Rx%02d]error", i); break;
++ }
++ #endif
++ }
++ else {
++ #ifdef SLT_DOS
++ fprintf(fp_log ,"[Rx%02d]%08lx %08lx\n", i, NCSI_RxDWBUF[i], DWSwap_SLT(NCSI_RxDWBUF[i]));
++ #endif
++ }
++ }
++ } // End for (i = 0; i < dwsize; i++)
++
++ // EtherType field of the response packet should be 0x88F8
++ if ((NCSI_RxData & 0xffff) == 0xf888) {
++ memcpy (&NCSI_Respond_SLT, NCSI_RxByteBUF, bytesize);
++
++ #ifdef SLT_DOS
++ if ( PrintNCSIEn )
++ fprintf(fp_log ,"[Rx IID:%2d]\n", NCSI_Respond_SLT.IID);
++ #endif
++
++ NCSI_Respond_SLT.EtherType = WDSwap_SLT( NCSI_Respond_SLT.EtherType );
++ NCSI_Respond_SLT.Payload_Length = WDSwap_SLT( NCSI_Respond_SLT.Payload_Length );
++ NCSI_Respond_SLT.Response_Code = WDSwap_SLT( NCSI_Respond_SLT.Response_Code );
++ NCSI_Respond_SLT.Reason_Code = WDSwap_SLT( NCSI_Respond_SLT.Reason_Code );
++
++ ret = 0;
++ break;
++ }
++ else {
++ #ifdef SLT_DOS
++ if ( PrintNCSIEn )
++ fprintf(fp_log, "[Skip] Not NCSI Response: %08lx\n", NCSI_RxData);
++ #endif
++
++ retry++;
++ }
++ } while ( retry < NCSI_RX_RETRY_TIME );
++
++ return( ret );
++} // End char NCSI_Rx_SLT (void)
++
++//------------------------------------------------------------
++char NCSI_Tx (void) {
++ int bytesize;
++ int dwsize;
++ int i;
++ int timeout = 0;
++ ULONG NCSI_TxDesDat;
++
++ // Header of NC-SI command format is 34 bytes. page 58, NC-SI spec. ver 1.0.0 from DMTF
++ // The minimum size of a NC-SI package is 64 bytes.
++ bytesize = 34 + WDSwap_SLT(NCSI_Request_SLT.Payload_Length);
++ if ( bytesize < 64 ) {
++ memset (NCSI_TxByteBUF + bytesize, 0, 60 - bytesize);
++ bytesize = 64;
++ }
++
++ // Fill up to multiple of 4
++// dwsize = (bytesize + 3) >> 2;
++ if ( ( bytesize % 4 ) != 0 )
++ dwsize = ( bytesize >> 2 ) + 1;
++ else
++ dwsize = bytesize >> 2;
++
++ #ifdef SLT_DOS
++ if ( PrintNCSIEn )
++ fprintf(fp_log ,"[Tx IID:%2d] %d bytes(%xh)\n", NCSI_Request_SLT.IID, bytesize, bytesize);
++ #endif
++
++ // Copy data to DMA buffer
++ for (i = 0; i < dwsize; i++) {
++ WriteSOC_DD( DMA_BASE + (i << 2), NCSI_TxDWBUF[i] );
++ if ( PrintNCSIEn ) {
++ if (i == (dwsize - 1)) {
++ switch (bytesize % 4) {
++ case 0 : NCSI_TxDWBUF[i] = NCSI_TxDWBUF[i] & 0xffffffff; break;
++ case 3 : NCSI_TxDWBUF[i] = NCSI_TxDWBUF[i] & 0x00ffffff; break;
++ case 2 : NCSI_TxDWBUF[i] = NCSI_TxDWBUF[i] & 0x0000ffff; break;
++ case 1 : NCSI_TxDWBUF[i] = NCSI_TxDWBUF[i] & 0x000000ff; break;
++ }
++ #ifdef SLT_DOS
++ switch (bytesize % 4) {
++ case 0 : fprintf(fp_log ,"[Tx%02d]%08x %08x\n", i, NCSI_TxDWBUF[i], DWSwap_SLT( NCSI_TxDWBUF[i]) ); break;
++ case 3 : fprintf(fp_log ,"[Tx%02d]--%06x %06x--\n", i, NCSI_TxDWBUF[i], DWSwap_SLT( NCSI_TxDWBUF[i]) >> 8 ); break;
++ case 2 : fprintf(fp_log ,"[Tx%02d]----%04x %04x----\n", i, NCSI_TxDWBUF[i], DWSwap_SLT( NCSI_TxDWBUF[i]) >> 16 ); break;
++ case 1 : fprintf(fp_log ,"[Tx%02d]------%02x %02x------\n", i, NCSI_TxDWBUF[i], DWSwap_SLT( NCSI_TxDWBUF[i]) >> 24 ); break;
++ default : fprintf(fp_log ,"[Tx%02d]error", i); break;
++ }
++ #endif
++ }
++ else {
++ #ifdef SLT_DOS
++ fprintf( fp_log , "[Tx%02d]%08x %08x\n", i, NCSI_TxDWBUF[i], DWSwap_SLT(NCSI_TxDWBUF[i]) );
++ #endif
++ }
++ }
++ } // End for (i = 0; i < dwsize; i++)
++
++ // Setting one TX descriptor
++ WriteSOC_DD( H_TDES_BASE + 0x04, 0 );
++ WriteSOC_DD( H_TDES_BASE + 0x08, 0 );
++ WriteSOC_DD( H_TDES_BASE + 0x0C, (DMA_BASE + CPU_BUS_ADDR_SDRAM_OFFSET) ); // 20130730
++ WriteSOC_DD( H_TDES_BASE , 0xf0008000 + bytesize );
++ // Fire
++ WriteSOC_DD( H_MAC_BASE + 0x18, 0x00000000 );//Tx Poll
++
++ do {
++ NCSI_TxDesDat = ReadSOC_DD(H_TDES_BASE);
++ if ( ++timeout > TIME_OUT_NCSI ) {
++ #ifdef SLT_DOS
++ fprintf(fp_log, "[NCSI-TxDesOwn] %08lx\n", NCSI_TxDesDat);
++ #endif
++
++ return(FindErr(Err_NCSI_Check_TxOwnTimeOut));
++ }
++ } while ( HWOwnTx(NCSI_TxDesDat) );
++
++ return(0);
++} // End char NCSI_Tx (void)
++
++//------------------------------------------------------------
++char NCSI_ARP (void) {
++ int i;
++ int timeout = 0;
++ ULONG NCSI_TxDesDat;
++
++ if ( ARPNumCnt ) {
++ #ifdef SLT_DOS
++ if ( PrintNCSIEn )
++ fprintf(fp_log ,"[ARP] 60 bytes x%d\n", ARPNumCnt);
++ #endif
++
++ for (i = 0; i < 15; i++) {
++ #ifdef SLT_DOS
++ if ( PrintNCSIEn )
++ fprintf(fp_log ,"[Tx%02d] %08x %08x\n", i, ARP_data[i], DWSwap_SLT(ARP_data[i]));
++ #endif
++ WriteSOC_DD( DMA_BASE + ( i << 2 ), ARP_data[i] );
++ }
++ WriteSOC_DD( H_TDES_BASE + 0x04, 0 );
++ WriteSOC_DD( H_TDES_BASE + 0x08, 0 );
++ WriteSOC_DD( H_TDES_BASE + 0x0C, (DMA_BASE + CPU_BUS_ADDR_SDRAM_OFFSET) ); // 20130730
++ WriteSOC_DD( H_TDES_BASE , 0xf0008000 + 60 );
++
++ for (i = 0; i < ARPNumCnt; i++) {
++ WriteSOC_DD( H_TDES_BASE , 0xf0008000 + 60);
++
++ WriteSOC_DD( H_MAC_BASE + 0x18, 0x00000000 );//Tx Poll
++
++ timeout = 0;
++ do {
++ NCSI_TxDesDat = ReadSOC_DD(H_TDES_BASE);
++
++ if (++timeout > TIME_OUT_NCSI) {
++ #ifdef SLT_DOS
++ fprintf(fp_log, "[ARP-TxDesOwn] %08lx\n", NCSI_TxDesDat);
++ #endif
++
++ return(FindErr(Err_NCSI_Check_ARPOwnTimeOut));
++ }
++ } while (HWOwnTx(NCSI_TxDesDat));
++ }
++ }
++ return(0);
++} // End char NCSI_ARP (void)
++
++//------------------------------------------------------------
++void WrRequest (unsigned char command, unsigned char id, unsigned short length) {
++
++ NCSI_Request_SLT.IID = InstanceID;
++ NCSI_Request_SLT.Command = command;
++ NCSI_Request_SLT.Channel_ID = id;
++ NCSI_Request_SLT.Payload_Length = WDSwap_SLT(length);
++
++ memcpy ( NCSI_TxByteBUF , &NCSI_Request_SLT , 30 );
++ memcpy ((NCSI_TxByteBUF + 30 ), &NCSI_Payload_Data , length);
++ Calculate_Checksum_NCSI(NCSI_TxByteBUF, 30 + length);
++ memcpy ((NCSI_TxByteBUF + 30 + length), &Payload_Checksum_NCSI, 4 );
++}
++
++//------------------------------------------------------------
++void NCSI_PrintCommandStr (unsigned char command, unsigned iid) {
++ switch (command & 0x80) {
++ case 0x80 : sprintf(NCSI_CommandStr, "IID:%3d [%02x][Respond]", iid, command); break;
++ default : sprintf(NCSI_CommandStr, "IID:%3d [%02x][Request]", iid, command); break;
++ }
++ switch (command & 0x7f) {
++ case 0x00 : sprintf(NCSI_CommandStr, "%s[CLEAR_INITIAL_STATE ]", NCSI_CommandStr); break;
++ case 0x01 : sprintf(NCSI_CommandStr, "%s[SELECT_PACKAGE ]", NCSI_CommandStr); break;
++ case 0x02 : sprintf(NCSI_CommandStr, "%s[DESELECT_PACKAGE ]", NCSI_CommandStr); break;
++ case 0x03 : sprintf(NCSI_CommandStr, "%s[ENABLE_CHANNEL ]", NCSI_CommandStr); break;
++ case 0x04 : sprintf(NCSI_CommandStr, "%s[DISABLE_CHANNEL ]", NCSI_CommandStr); break;
++ case 0x05 : sprintf(NCSI_CommandStr, "%s[RESET_CHANNEL ]", NCSI_CommandStr); break;
++ case 0x06 : sprintf(NCSI_CommandStr, "%s[ENABLE_CHANNEL_NETWORK_TX ]", NCSI_CommandStr); break;
++ case 0x07 : sprintf(NCSI_CommandStr, "%s[DISABLE_CHANNEL_NETWORK_TX ]", NCSI_CommandStr); break;
++ case 0x08 : sprintf(NCSI_CommandStr, "%s[AEN_ENABLE ]", NCSI_CommandStr); break;
++ case 0x09 : sprintf(NCSI_CommandStr, "%s[SET_LINK ]", NCSI_CommandStr); break;
++ case 0x0A : sprintf(NCSI_CommandStr, "%s[GET_LINK_STATUS ]", NCSI_CommandStr); break;
++ case 0x0B : sprintf(NCSI_CommandStr, "%s[SET_VLAN_FILTER ]", NCSI_CommandStr); break;
++ case 0x0C : sprintf(NCSI_CommandStr, "%s[ENABLE_VLAN ]", NCSI_CommandStr); break;
++ case 0x0D : sprintf(NCSI_CommandStr, "%s[DISABLE_VLAN ]", NCSI_CommandStr); break;
++ case 0x0E : sprintf(NCSI_CommandStr, "%s[SET_MAC_ADDRESS ]", NCSI_CommandStr); break;
++ case 0x10 : sprintf(NCSI_CommandStr, "%s[ENABLE_BROADCAST_FILTERING ]", NCSI_CommandStr); break;
++ case 0x11 : sprintf(NCSI_CommandStr, "%s[DISABLE_BROADCAST_FILTERING ]", NCSI_CommandStr); break;
++ case 0x12 : sprintf(NCSI_CommandStr, "%s[ENABLE_GLOBAL_MULTICAST_FILTERING ]", NCSI_CommandStr); break;
++ case 0x13 : sprintf(NCSI_CommandStr, "%s[DISABLE_GLOBAL_MULTICAST_FILTERING ]", NCSI_CommandStr); break;
++ case 0x14 : sprintf(NCSI_CommandStr, "%s[SET_NCSI_FLOW_CONTROL ]", NCSI_CommandStr); break;
++ case 0x15 : sprintf(NCSI_CommandStr, "%s[GET_VERSION_ID ]", NCSI_CommandStr); break;
++ case 0x16 : sprintf(NCSI_CommandStr, "%s[GET_CAPABILITIES ]", NCSI_CommandStr); break;
++ case 0x17 : sprintf(NCSI_CommandStr, "%s[GET_PARAMETERS ]", NCSI_CommandStr); break;
++ case 0x18 : sprintf(NCSI_CommandStr, "%s[GET_CONTROLLER_PACKET_STATISTICS ]", NCSI_CommandStr); break;
++ case 0x19 : sprintf(NCSI_CommandStr, "%s[GET_NCSI_STATISTICS ]", NCSI_CommandStr); break;
++ case 0x1A : sprintf(NCSI_CommandStr, "%s[GET_NCSI_PASS_THROUGH_STATISTICS ]", NCSI_CommandStr); break;
++ case 0x50 : sprintf(NCSI_CommandStr, "%s[OEM_COMMAND ]", NCSI_CommandStr); break;
++ default : sprintf(NCSI_CommandStr, "%s Not Support Command", NCSI_CommandStr); break ;
++ }
++} // End void NCSI_PrintCommandStr (unsigned char command, unsigned iid)
++
++//------------------------------------------------------------
++void NCSI_PrintCommandType (unsigned char command, unsigned iid) {
++ NCSI_PrintCommandStr(command, iid);
++ printf ("%s\n", NCSI_CommandStr);
++}
++
++//------------------------------------------------------------
++void NCSI_PrintCommandType2File (unsigned char command, unsigned iid) {
++ NCSI_PrintCommandStr(command, iid);
++ #ifdef SLT_DOS
++ fprintf(fp_log, "%s\n", NCSI_CommandStr);
++ #endif
++}
++
++//------------------------------------------------------------
++char NCSI_SentWaitPacket (unsigned char command, unsigned char id, unsigned short length) {
++ int Retry = 0;
++ char ret;
++
++ do {
++ InstanceID++;
++ WrRequest(command, id, length);
++
++ ret = NCSI_Tx(); if ( ret != 0 )
++ {
++ // printf("======> NCSI_Tx return code = %X\n", ret );
++ return(1);
++ }
++#ifdef Print_PackageName
++ NCSI_PrintCommandType(command, InstanceID);
++#endif
++
++#ifdef NCSI_EnableDelay_EachPackage
++ delay(Delay_EachPackage);
++#endif
++ if ( NCSI_Rx_SLT( command ) )
++ return(2);
++
++ #ifdef SLT_DOS
++ if ( PrintNCSIEn )
++ fprintf(fp_log, "[Request] ETyp:%04x MC_ID:%02x HeadVer:%02x IID:%02x Comm:%02x ChlID:%02x PayLen:%04x\n", WDSwap_SLT(NCSI_Request_SLT.EtherType),
++ NCSI_Request_SLT.MC_ID,
++ NCSI_Request_SLT.Header_Revision,
++ NCSI_Request_SLT.IID,
++ NCSI_Request_SLT.Command,
++ NCSI_Request_SLT.Channel_ID,
++ WDSwap_SLT(NCSI_Request_SLT.Payload_Length) );
++ if ( PrintNCSIEn )
++ fprintf(fp_log, "[Respond] ETyp:%04x MC_ID:%02x HeadVer:%02x IID:%02x Comm:%02x ChlID:%02x PayLen:%04x ResCd:%02x ReaCd:%02x\n",
++ NCSI_Respond_SLT.EtherType,
++ NCSI_Respond_SLT.MC_ID,
++ NCSI_Respond_SLT.Header_Revision,
++ NCSI_Respond_SLT.IID,
++ NCSI_Respond_SLT.Command,
++ NCSI_Respond_SLT.Channel_ID,
++ NCSI_Respond_SLT.Payload_Length,
++ NCSI_Respond_SLT.Response_Code,
++ NCSI_Respond_SLT.Reason_Code);
++ #endif
++
++ if ( (NCSI_Respond_SLT.IID != InstanceID) ||
++ (NCSI_Respond_SLT.Command != (command | 0x80)) ||
++ (NCSI_Respond_SLT.Response_Code != COMMAND_COMPLETED) ) {
++ #ifdef SLT_DOS
++ if ( PrintNCSIEn )
++ fprintf(fp_log, "Retry: Command = %x, Response_Code = %x\n", NCSI_Request_SLT.Command, NCSI_Respond_SLT.Response_Code);
++
++ #endif
++ Retry++;
++ }
++ else {
++ if ( PrintNCSIEn )
++ NCSI_PrintCommandType2File(command, InstanceID);
++
++ return(0);
++ }
++ } while (Retry <= SENT_RETRY_COUNT);
++
++ return( 3 );
++} // End char NCSI_SentWaitPacket (unsigned char command, unsigned char id, unsigned short length)
++
++//------------------------------------------------------------
++char Clear_Initial_State_SLT (int Channel_ID) {//Command:0x00
++ return(NCSI_SentWaitPacket(CLEAR_INITIAL_STATE, (NCSI_Cap_SLT.Package_ID << 5) + Channel_ID, 0));//Internal Channel ID = 0
++}
++
++//------------------------------------------------------------
++char Select_Package_SLT (int Package_ID) {//Command:0x01
++ memset ((void *)NCSI_Payload_Data, 0, 4);
++ NCSI_Payload_Data[3] = 1; //Arbitration Disable
++
++ return(NCSI_SentWaitPacket(SELECT_PACKAGE, (Package_ID << 5) + 0x1F, 4));//Internal Channel ID = 0x1F, 0x1F means all channel
++}
++
++//------------------------------------------------------------
++void Select_Active_Package_SLT (void) {//Command:0x01
++ memset ((void *)NCSI_Payload_Data, 0, 4);
++ NCSI_Payload_Data[3] = 1; //Arbitration Disable
++
++ if (NCSI_SentWaitPacket(SELECT_PACKAGE, (NCSI_Cap_SLT.Package_ID << 5) + 0x1F, 4)) {//Internal Channel ID = 0x1F
++ FindErr_NCSI(NCSI_LinkFail_Select_Active_Package);
++ }
++}
++
++//------------------------------------------------------------
++void DeSelect_Package_SLT (int Package_ID) {//Command:0x02
++ NCSI_SentWaitPacket(DESELECT_PACKAGE, (Package_ID << 5) + 0x1F, 0);//Internal Channel ID = 0x1F, 0x1F means all channel
++
++#ifdef NCSI_EnableDelay_DeSelectPackage
++ delay(Delay_DeSelectPackage);
++#endif
++}
++
++//------------------------------------------------------------
++void Enable_Channel_SLT (void) {//Command:0x03
++ if ( NCSI_SentWaitPacket(ENABLE_CHANNEL, (NCSI_Cap_SLT.Package_ID << 5) + NCSI_Cap_SLT.Channel_ID, 0) ) {
++ FindErr_NCSI(NCSI_LinkFail_Enable_Channel);
++ }
++}
++
++//------------------------------------------------------------
++void Disable_Channel_SLT (void) {//Command:0x04
++ memset ((void *)NCSI_Payload_Data, 0, 4);
++ NCSI_Payload_Data[3] = 0x1; //ALD
++
++ if (NCSI_SentWaitPacket(DISABLE_CHANNEL, (NCSI_Cap_SLT.Package_ID << 5) + NCSI_Cap_SLT.Channel_ID, 4)) {
++ FindErr_NCSI(NCSI_LinkFail_Disable_Channel);
++ }
++}
++void Enable_Network_TX_SLT (void) {//Command:0x06
++ if ( NCSI_SentWaitPacket(ENABLE_CHANNEL_NETWORK_TX, (NCSI_Cap_SLT.Package_ID << 5) + NCSI_Cap_SLT.Channel_ID, 0) ) {
++ FindErr_NCSI(NCSI_LinkFail_Enable_Network_TX);
++ }
++}
++
++//------------------------------------------------------------
++void Disable_Network_TX_SLT (void) {//Command:0x07
++ if ( NCSI_SentWaitPacket(DISABLE_CHANNEL_NETWORK_TX, (NCSI_Cap_SLT.Package_ID << 5) + NCSI_Cap_SLT.Channel_ID, 0) ) {
++ FindErr_NCSI(NCSI_LinkFail_Disable_Network_TX);
++ }
++}
++
++//------------------------------------------------------------
++void Set_Link_SLT (void) {//Command:0x09
++ memset ((void *)NCSI_Payload_Data, 0, 8);
++ NCSI_Payload_Data[2] = 0x02; //full duplex
++// NCSI_Payload_Data[3] = 0x04; //100M, auto-disable
++ NCSI_Payload_Data[3] = 0x05; //100M, auto-enable
++
++ NCSI_SentWaitPacket(SET_LINK, (NCSI_Cap_SLT.Package_ID << 5) + NCSI_Cap_SLT.Channel_ID, 8);
++}
++
++//------------------------------------------------------------
++char Get_Link_Status_SLT (void) {//Command:0x0a
++
++ if (NCSI_SentWaitPacket(GET_LINK_STATUS, (NCSI_Cap_SLT.Package_ID << 5) + NCSI_Cap_SLT.Channel_ID, 0)) {
++ return(0);
++ }
++ else {
++ if (NCSI_Respond_SLT.Payload_Data[3] & 0x20) {
++ if (NCSI_Respond_SLT.Payload_Data[3] & 0x40) {
++ if (NCSI_Respond_SLT.Payload_Data[3] & 0x01)
++ return(1); //Link Up or Not
++ else
++ return(0);
++ } else
++ return(0); //Auto Negotiate did not finish
++ } else {
++ if (NCSI_Respond_SLT.Payload_Data[3] & 0x01)
++ return(1); //Link Up or Not
++ else
++ return(0);
++ }
++ }
++} // End char Get_Link_Status_SLT (void)
++
++//------------------------------------------------------------
++void Enable_Set_MAC_Address_SLT (void) {//Command:0x0e
++ int i;
++
++ for ( i = 0; i < 6; i++ ) {
++ NCSI_Payload_Data[i] = NCSI_Request_SLT.SA[i];
++ }
++ NCSI_Payload_Data[6] = 1; //MAC Address Num = 1 --> address filter 1, fixed in sample code
++ NCSI_Payload_Data[7] = UNICAST + 0 + ENABLE_MAC_ADDRESS_FILTER; //AT + Reserved + E
++
++ if ( NCSI_SentWaitPacket(SET_MAC_ADDRESS, (NCSI_Cap_SLT.Package_ID << 5) + NCSI_Cap_SLT.Channel_ID, 8) ) {
++ FindErr_NCSI(NCSI_LinkFail_Enable_Set_MAC_Address);
++ }
++}
++
++//------------------------------------------------------------
++void Enable_Broadcast_Filter_SLT (void) {//Command:0x10
++ memset ((void *)NCSI_Payload_Data, 0, 4);
++ NCSI_Payload_Data[3] = 0xF; //ARP, DHCP, NetBIOS
++
++ if (NCSI_SentWaitPacket(ENABLE_BROADCAST_FILTERING, (NCSI_Cap_SLT.Package_ID << 5) + NCSI_Cap_SLT.Channel_ID, 4) ) {
++ FindErr_NCSI(NCSI_LinkFail_Enable_Broadcast_Filter);
++ }
++}
++
++//------------------------------------------------------------
++void Get_Version_ID_SLT (void) {//Command:0x15
++
++ if (NCSI_SentWaitPacket(GET_VERSION_ID, (NCSI_Cap_SLT.Package_ID << 5) + NCSI_Cap_SLT.Channel_ID, 0) ) {
++ FindErr_NCSI(NCSI_LinkFail_Get_Version_ID);
++ }
++ else {
++#ifdef Print_Version_ID
++ printf ("NCSI Version : %02x %02x %02x %02x\n", NCSI_Respond_SLT.Payload_Data[ 0], NCSI_Respond_SLT.Payload_Data[ 1], NCSI_Respond_SLT.Payload_Data[ 2], NCSI_Respond_SLT.Payload_Data[ 3]);
++ printf ("NCSI Version : %02x %02x %02x %02x\n", NCSI_Respond_SLT.Payload_Data[ 4], NCSI_Respond_SLT.Payload_Data[ 5], NCSI_Respond_SLT.Payload_Data[ 6], NCSI_Respond_SLT.Payload_Data[ 7]);
++ printf ("Firmware Name String: %02x %02x %02x %02x\n", NCSI_Respond_SLT.Payload_Data[ 8], NCSI_Respond_SLT.Payload_Data[ 9], NCSI_Respond_SLT.Payload_Data[10], NCSI_Respond_SLT.Payload_Data[11]);
++ printf ("Firmware Name String: %02x %02x %02x %02x\n", NCSI_Respond_SLT.Payload_Data[12], NCSI_Respond_SLT.Payload_Data[13], NCSI_Respond_SLT.Payload_Data[14], NCSI_Respond_SLT.Payload_Data[15]);
++ printf ("Firmware Name String: %02x %02x %02x %02x\n", NCSI_Respond_SLT.Payload_Data[16], NCSI_Respond_SLT.Payload_Data[17], NCSI_Respond_SLT.Payload_Data[18], NCSI_Respond_SLT.Payload_Data[19]);
++ printf ("Firmware Version : %02x %02x %02x %02x\n", NCSI_Respond_SLT.Payload_Data[20], NCSI_Respond_SLT.Payload_Data[21], NCSI_Respond_SLT.Payload_Data[22], NCSI_Respond_SLT.Payload_Data[23]);
++ printf ("PCI DID/VID : %02x %02x/%02x %02x\n", NCSI_Respond_SLT.Payload_Data[24], NCSI_Respond_SLT.Payload_Data[25], NCSI_Respond_SLT.Payload_Data[26], NCSI_Respond_SLT.Payload_Data[27]);
++ printf ("PCI SSID/SVID : %02x %02x/%02x %02x\n", NCSI_Respond_SLT.Payload_Data[28], NCSI_Respond_SLT.Payload_Data[29], NCSI_Respond_SLT.Payload_Data[30], NCSI_Respond_SLT.Payload_Data[31]);
++ printf ("Manufacturer ID : %02x %02x %02x %02x\n", NCSI_Respond_SLT.Payload_Data[32], NCSI_Respond_SLT.Payload_Data[33], NCSI_Respond_SLT.Payload_Data[34], NCSI_Respond_SLT.Payload_Data[35]);
++ printf ("Checksum : %02x %02x %02x %02x\n", NCSI_Respond_SLT.Payload_Data[36], NCSI_Respond_SLT.Payload_Data[37], NCSI_Respond_SLT.Payload_Data[38], NCSI_Respond_SLT.Payload_Data[39]);
++#endif
++ NCSI_Cap_SLT.PCI_DID_VID = (NCSI_Respond_SLT.Payload_Data[24]<<24)
++ | (NCSI_Respond_SLT.Payload_Data[25]<<16)
++ | (NCSI_Respond_SLT.Payload_Data[26]<< 8)
++ | (NCSI_Respond_SLT.Payload_Data[27] );
++ NCSI_Cap_SLT.ManufacturerID = (NCSI_Respond_SLT.Payload_Data[32]<<24)
++ | (NCSI_Respond_SLT.Payload_Data[33]<<16)
++ | (NCSI_Respond_SLT.Payload_Data[34]<< 8)
++ | (NCSI_Respond_SLT.Payload_Data[35] );
++ }
++} // End void Get_Version_ID_SLT (void)
++
++//------------------------------------------------------------
++void Get_Capabilities_SLT (void) {//Command:0x16
++
++ if (NCSI_SentWaitPacket(GET_CAPABILITIES, (NCSI_Cap_SLT.Package_ID << 5) + NCSI_Cap_SLT.Channel_ID, 0)) {
++ FindErr_NCSI(NCSI_LinkFail_Get_Capabilities);
++ }
++ else {
++ NCSI_Cap_SLT.Capabilities_Flags = NCSI_Respond_SLT.Payload_Data[0];
++ NCSI_Cap_SLT.Broadcast_Packet_Filter_Capabilities = NCSI_Respond_SLT.Payload_Data[1];
++ NCSI_Cap_SLT.Multicast_Packet_Filter_Capabilities = NCSI_Respond_SLT.Payload_Data[2];
++ NCSI_Cap_SLT.Buffering_Capabilities = NCSI_Respond_SLT.Payload_Data[3];
++ NCSI_Cap_SLT.AEN_Control_Support = NCSI_Respond_SLT.Payload_Data[4];
++ }
++}
++
++//------------------------------------------------------------
++void Get_Controller_Packet_Statistics (void) {//Command:0x18
++
++ NCSI_SentWaitPacket(GET_CONTROLLER_PACKET_STATISTICS, (NCSI_Cap_SLT.Package_ID << 5) + NCSI_Cap_SLT.Channel_ID, 0);
++}
++
++//------------------------------------------------------------
++char phy_ncsi (void) {
++ ULONG Channel_Found = 0;
++ ULONG Package_Found = 0;
++ ULONG Re_Send;
++ ULONG Err_Flag_bak;
++ ULONG pkg_idx;
++ ULONG chl_idx;
++ ULONG Link_Status;
++ ULONG NCSI_LinkFail_Val_bak;
++
++ number_chl = 0;
++ number_pak = 0;
++
++ NCSI_LinkFail_Val = 0;
++ #ifdef SLT_DOS
++ fprintf(fp_log, "\n\n======> Start:\n" );
++ #endif
++ NCSI_Struct_Initialize_SLT();
++
++ #ifdef NCSI_Skip_Phase1_DeSelectPackage
++ #else
++
++ //NCSI Start
++ //Disable Channel then DeSelect Package
++ for (pkg_idx = 0; pkg_idx < MAX_PACKAGE_NUM; pkg_idx++) {
++ // Ignore error flag in the NCSI command
++ Err_Flag_bak = Err_Flag;
++ NCSI_LinkFail_Val_bak = NCSI_LinkFail_Val;
++ select_flag[pkg_idx] = Select_Package_SLT (pkg_idx); // Command:0x01
++ Err_Flag = Err_Flag_bak;
++ NCSI_LinkFail_Val = NCSI_LinkFail_Val_bak;
++
++ if ( select_flag[pkg_idx] == 0 ) {
++ NCSI_Cap_SLT.Package_ID = pkg_idx;
++
++ for ( chl_idx = 0; chl_idx < MAX_CHANNEL_NUM; chl_idx++ ) {
++ NCSI_Cap_SLT.Channel_ID = chl_idx;
++ // Ignore error flag in the NCSI command
++ Err_Flag_bak = Err_Flag;
++ NCSI_LinkFail_Val_bak = NCSI_LinkFail_Val;
++ Disable_Channel_SLT(); // Command: 0x04
++ Err_Flag = Err_Flag_bak;
++ NCSI_LinkFail_Val = NCSI_LinkFail_Val_bak;
++ }
++ #ifdef NCSI_Skip_DeSelectPackage
++ #else
++ DeSelect_Package_SLT (pkg_idx); // Command:0x02
++ #endif
++ } // End if ( select_flag[pkg_idx] == 0 )
++ } // End for (pkg_idx = 0; pkg_idx < MAX_PACKAGE_NUM; pkg_idx++)
++ #endif
++
++ //Select Package
++ for (pkg_idx = 0; pkg_idx < MAX_PACKAGE_NUM; pkg_idx++) {
++ #ifdef NCSI_Skip_Phase1_DeSelectPackage
++ // Ignore error flag in the NCSI command
++ Err_Flag_bak = Err_Flag;
++ NCSI_LinkFail_Val_bak = NCSI_LinkFail_Val;
++ select_flag[pkg_idx] = Select_Package_SLT (pkg_idx);//Command:0x01
++ Err_Flag = Err_Flag_bak;
++ NCSI_LinkFail_Val = NCSI_LinkFail_Val_bak;
++ #endif
++
++ if (select_flag[pkg_idx] == 0) {
++ //NCSI_RxTimeOutScale = 1000;
++ NCSI_RxTimeOutScale = 10;
++ number_pak++;
++ Package_Found = 1;
++ NCSI_Cap_SLT.Package_ID = pkg_idx;
++
++ if ( !(IOTiming||IOTimingBund) )
++ printf ("====Find Package ID: %d\n", NCSI_Cap_SLT.Package_ID);
++ #ifdef SLT_DOS
++ fprintf(fp_log, "====Find Package ID: %d\n", NCSI_Cap_SLT.Package_ID);
++ #endif
++
++ #ifdef NCSI_Skip_Phase1_DeSelectPackage
++ #else
++ Select_Package_SLT (pkg_idx);//Command:0x01
++ #endif
++
++ // Scan all channel in the package
++ for ( chl_idx = 0; chl_idx < MAX_CHANNEL_NUM; chl_idx++ ) {
++ // backup error flag
++ Err_Flag_bak = Err_Flag;
++ NCSI_LinkFail_Val_bak = NCSI_LinkFail_Val;
++ if (Clear_Initial_State_SLT(chl_idx) == 0) { //Command:0x00
++ number_chl++;
++ Channel_Found = 1;
++ NCSI_Cap_SLT.Channel_ID = chl_idx;
++
++ if ( !(IOTiming || IOTimingBund) )
++ printf ("--------Find Channel ID: %d\n", NCSI_Cap_SLT.Channel_ID);
++
++ #ifdef SLT_DOS
++ fprintf(fp_log, "--------Find Channel ID: %d\n", NCSI_Cap_SLT.Channel_ID);
++ #endif
++ // Get Version and Capabilities
++ Get_Version_ID_SLT(); //Command:0x15
++ Get_Capabilities_SLT(); //Command:0x16
++ Select_Active_Package_SLT(); //Command:0x01
++ Enable_Set_MAC_Address_SLT(); //Command:0x0e
++ Enable_Broadcast_Filter_SLT(); //Command:0x10
++
++ // Enable TX
++ Enable_Network_TX_SLT(); //Command:0x06
++
++ // Enable Channel
++ Enable_Channel_SLT(); //Command:0x03
++
++ // Get Link Status
++ Re_Send = 0;
++ do {
++ #ifdef NCSI_EnableDelay_GetLinkStatus
++ if ( Re_Send >= 2 )
++ delay(Delay_GetLinkStatus);
++ #endif
++
++ Link_Status = Get_Link_Status_SLT();//Command:0x0a
++
++ if ( Link_Status == LINK_UP ) {
++ if (!(IOTiming||IOTimingBund))
++ printf (" This Channel is LINK_UP\n");
++
++ #ifdef SLT_DOS
++ fprintf(fp_log, " This Channel is LINK_UP\n");
++ #endif
++
++ NCSI_ARP ();
++
++ break;
++ }
++ else if ( Link_Status == LINK_DOWN ) {
++ if ( Re_Send >= 2 ) {
++ if ( !(IOTiming || IOTimingBund) )
++ printf (" This Channel is LINK_DOWN\n");
++
++ #ifdef SLT_DOS
++ fprintf(fp_log, " This Channel is LINK_DOWN\n");
++ #endif
++
++ break;
++ }
++ } // End if ( Link_Status == LINK_UP )
++ } while ( Re_Send++ <= 2 );
++
++ #ifdef NCSI_Skip_DiSChannel
++ #else
++ if ( NCSI_DiSChannel ) {
++ // Disable TX
++ Disable_Network_TX_SLT(); //Command:0x07
++ // Disable Channel
++ Disable_Channel_SLT(); //Command:0x04
++ }
++ #endif
++ }
++ else {
++ Err_Flag = Err_Flag_bak;
++ NCSI_LinkFail_Val = NCSI_LinkFail_Val_bak;
++ }
++ } // End for ( chl_idx = 0; chl_idx < MAX_CHANNEL_NUM; chl_idx++ )
++
++ #ifdef NCSI_Skip_DeSelectPackage
++ #else
++ DeSelect_Package_SLT (pkg_idx);//Command:0x02
++ #endif
++ NCSI_RxTimeOutScale = 1;
++ }
++ else {
++ if (!(IOTiming||IOTimingBund)) {
++ printf ("====Absence of Package ID: %ld\n", pkg_idx);
++ #ifdef SLT_DOS
++ fprintf(fp_log, "====Absence of Package ID: %ld\n", pkg_idx);
++ #endif
++ }
++ } // End if (select_flag[pkg_idx] == 0)
++ } // End for (pkg_idx = 0; pkg_idx < MAX_PACKAGE_NUM; pkg_idx++)
++
++ if ( !Package_Found ) FindErr( Err_NCSI_No_PHY );
++ if ( ChannelTolNum != number_chl ) FindErr( Err_NCSI_Channel_Num );
++ if ( PackageTolNum != number_pak ) FindErr( Err_NCSI_Package_Num );
++// if ( !Channel_Found) FindErr();
++
++ if ( Err_Flag )
++ return(1);
++ else
++ return(0);
++}
++
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/PCI_SPI.c b/arch/arm/cpu/arm926ejs/aspeed/PCI_SPI.c
+new file mode 100644
+index 0000000..77aac47
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/PCI_SPI.c
+@@ -0,0 +1,83 @@
++/*
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#define PCI_SPI_C
++static const char ThisFile[] = "PCI_SPI.c";
++
++#include "SWFUNC.H"
++
++#ifdef SLT_UBOOT
++ #include <common.h>
++ #include <command.h>
++#endif
++#ifdef SLT_DOS
++ #include <stdio.h>
++ #include <stdlib.h>
++ #include <conio.h>
++ #include <string.h>
++ #include <dos.h>
++#endif
++
++#include "DEF_SPI.H"
++#include "LIB.H"
++#include "TYPEDEF.H"
++
++#ifdef SPI_BUS
++ULONG GetPCIInfo (DEVICE_PCI_INFO *VGAPCIInfo)
++{
++ ULONG ulPCIBaseAddress, MMIOBaseAddress, LinearAddressBase, busnum, data;
++
++ ulPCIBaseAddress = FindPCIDevice (0x1A03, 0x2000, ACTIVE);
++ busnum = 0;
++ while (ulPCIBaseAddress == 0 && busnum < 256) {
++ ulPCIBaseAddress = FindPCIDevice (0x1A03, 0x2000, busnum);
++ if (ulPCIBaseAddress == 0) {
++ ulPCIBaseAddress = FindPCIDevice (0x1688, 0x2000, busnum);
++ }
++ if (ulPCIBaseAddress == 0) {
++ ulPCIBaseAddress = FindPCIDevice (0x1A03, 0x1160, busnum);
++ }
++ if (ulPCIBaseAddress == 0) {
++ ulPCIBaseAddress = FindPCIDevice (0x1A03, 0x1180, busnum);
++ }
++ busnum++;
++ }
++ printf ("ulPCIBaseAddress = %lx\n", ulPCIBaseAddress);
++ if (ulPCIBaseAddress != 0) {
++ VGAPCIInfo->ulPCIConfigurationBaseAddress = ulPCIBaseAddress;
++ VGAPCIInfo->usVendorID = ReadPCIReg(ulPCIBaseAddress, 0, 0xFFFF);
++ VGAPCIInfo->usDeviceID = ReadPCIReg(ulPCIBaseAddress, 0, 0xFFFF0000) >> 16;
++ LinearAddressBase = ReadPCIReg (ulPCIBaseAddress, 0x10, 0xFFFFFFF0);
++ VGAPCIInfo->ulPhysicalBaseAddress = MapPhysicalToLinear (LinearAddressBase, 64 * 1024 * 1024 + 0x200000);
++ MMIOBaseAddress = ReadPCIReg (ulPCIBaseAddress, 0x14, 0xFFFF0000);
++ VGAPCIInfo->ulMMIOBaseAddress = MapPhysicalToLinear (MMIOBaseAddress, 64 * 1024 * 1024);
++ VGAPCIInfo->usRelocateIO = ReadPCIReg (ulPCIBaseAddress, 0x18, 0x0000FF80);
++ OUTDWPORT(0xcf8, ulPCIBaseAddress + 0x4);
++ data = INDWPORT(0xcfc);
++ OUTDWPORT(0xcfc, data | 0x3);
++ return TRUE;
++ }
++ else {
++ return FALSE;
++ }
++} // End ULONG GetPCIInfo (DEVICE_PCI_INFO *VGAPCIInfo)
++
++BOOLEAN GetDevicePCIInfo (VIDEO_ENGINE_INFO *VideoEngineInfo)
++{
++ if (GetPCIInfo (&VideoEngineInfo->VGAPCIInfo) == TRUE) {
++ return TRUE;
++ }
++ else {
++ printf("Can not find PCI device!\n");
++ exit(0);
++ return FALSE;
++ }
++} // End
++#endif // End ifdef SPI_BUS
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/PHY.H b/arch/arm/cpu/arm926ejs/aspeed/PHY.H
+new file mode 100644
+index 0000000..81d9470
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/PHY.H
+@@ -0,0 +1,56 @@
++/*
++ * 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 PHY_H
++#define PHY_H
++
++//
++// Define
++//
++#define Enable_SearchPHYID //[ON] (Search vlid PHY ID)
++#define Enable_CheckZeroPHYID //[ON] (Check PHY ID with value 0)
++
++#ifdef Enable_CheckZeroPHYID
++ #define PHY_IS_VALID( dat ) ( ( (dat & 0xffff) != 0xffff ) && ( ( dat & 0xffff ) != 0x0 ) )
++#else
++ #define PHY_IS_VALID( dat ) ( ( dat & 0xffff) != 0xffff )
++#endif
++
++// Define PHY basic register
++#define PHY_REG_BMCR 0x00 // Basic Mode Control Register
++#define PHY_REG_BMSR 0x01 // Basic Mode Status Register
++#define PHY_REG_ID_1 0x02
++#define PHY_REG_ID_2 0x03
++#define PHY_ANER 0x06 // Auto-negotiation Expansion Register
++#define PHY_GBCR 0x09 // 1000Base-T Control Register
++#define PHY_SR 0x11 // PHY Specific Status Register
++#define PHY_INER 0x12 // Interrupt Enable Register
++
++#define TIME_OUT_PHY_RW 10000
++#define TIME_OUT_PHY_Rst 10000
++
++#define PHYID3_Mask 0xfc00 //0xffc0
++
++/* --- Note for SettingPHY chip ---
++void phy_xxxx (int loop_phy) {
++
++ if ( BurstEnable ) {
++ // IEEE test
++ }
++ else if (loop_phy) {
++ // Internal loop back
++ }
++ else {
++ // external loop back
++ }
++}
++----------------------------------- */
++
++#endif // PHY_H
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/PHY.c b/arch/arm/cpu/arm926ejs/aspeed/PHY.c
+new file mode 100644
+index 0000000..6afed9d
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/PHY.c
+@@ -0,0 +1,1541 @@
++/*
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#define PHY_C
++static const char ThisFile[] = "PHY.c";
++
++#include "SWFUNC.H"
++
++#ifdef SLT_UBOOT
++ #include <common.h>
++ #include <command.h>
++ #include <COMMINF.H>
++ #include "STDUBOOT.H"
++#endif
++#ifdef SLT_DOS
++ #include <stdio.h>
++ #include <stdlib.h>
++ #include <conio.h>
++ #include <string.h>
++ #include "COMMINF.H"
++#endif
++
++#include "PHY.H"
++#include "TYPEDEF.H"
++#include "IO.H"
++
++ULONG PHY_09h;
++ULONG PHY_18h;
++ULONG PHY_1fh;
++ULONG PHY_06hA[7];
++ULONG PHY_11h;
++ULONG PHY_12h;
++ULONG PHY_15h;
++ULONG PHY_06h;
++char PHYID[256];
++ULONG PHY_00h;
++
++//------------------------------------------------------------
++// PHY R/W basic
++//------------------------------------------------------------
++void phy_write (int adr, ULONG data) {
++ int timeout = 0;
++
++ if (AST2300_NewMDIO) {
++ WriteSOC_DD( MAC_PHYBASE + 0x60, ( data << 16 ) | MAC_PHYWr_New | (PHY_ADR<<5) | (adr & 0x1f));
++
++ while ( ReadSOC_DD( MAC_PHYBASE + 0x60 ) & MAC_PHYBusy_New ) {
++ if ( ++timeout > TIME_OUT_PHY_RW ) {
++ if (!BurstEnable)
++#ifdef SLT_DOS
++ fprintf(fp_log, "[PHY-Write] Time out: %08lx\n", ReadSOC_DD( MAC_PHYBASE + 0x60 ) );
++#endif
++ FindErr( Err_PHY_TimeOut );
++ break;
++ }
++ }
++ }
++ else {
++ WriteSOC_DD( MAC_PHYBASE + 0x64, data );
++
++ WriteSOC_DD( MAC_PHYBASE + 0x60, MDC_Thres | MAC_PHYWr | (PHY_ADR<<16) | ((adr & 0x1f) << 21));
++
++ while ( ReadSOC_DD( MAC_PHYBASE + 0x60 ) & MAC_PHYWr ) {
++ if ( ++timeout > TIME_OUT_PHY_RW ) {
++#ifdef SLT_DOS
++ if (!BurstEnable)
++ fprintf(fp_log, "[PHY-Write] Time out: %08lx\n", ReadSOC_DD( MAC_PHYBASE + 0x60 ) );
++#endif
++ FindErr( Err_PHY_TimeOut );
++ break;
++ }
++ }
++ } // End if (AST2300_NewMDIO)
++
++ if ( DbgPrn_PHYRW )
++ printf ("[Wr ]%02d: %04lx\n", adr, data);
++} // End void phy_write (int adr, ULONG data)
++
++//------------------------------------------------------------
++ULONG phy_read (int adr) {
++ int timeout = 0;
++
++ if ( AST2300_NewMDIO ) {
++ WriteSOC_DD( MAC_PHYBASE + 0x60, MAC_PHYRd_New | (PHY_ADR << 5) | ( adr & 0x1f ) );
++
++ while ( ReadSOC_DD( MAC_PHYBASE + 0x60 ) & MAC_PHYBusy_New ) {
++ if ( ++timeout > TIME_OUT_PHY_RW ) {
++ if ( !BurstEnable )
++#ifdef SLT_DOS
++ fprintf(fp_log, "[PHY-Read] Time out: %08lx\n", ReadSOC_DD( MAC_PHYBASE + 0x60 ));
++#endif
++ FindErr( Err_PHY_TimeOut );
++ break;
++ }
++ }
++
++ DELAY(Delay_PHYRd);
++ Dat_ULONG = ReadSOC_DD( MAC_PHYBASE + 0x64 ) & 0xffff;
++ }
++ else {
++ WriteSOC_DD( MAC_PHYBASE + 0x60, MDC_Thres | MAC_PHYRd | (PHY_ADR << 16) | ((adr & 0x1f) << 21) );
++
++ while ( ReadSOC_DD( MAC_PHYBASE + 0x60 ) & MAC_PHYRd ) {
++ if ( ++timeout > TIME_OUT_PHY_RW ) {
++#ifdef SLT_DOS
++ if ( !BurstEnable )
++ fprintf( fp_log, "[PHY-Read] Time out: %08lx\n", ReadSOC_DD( MAC_PHYBASE + 0x60 ) );
++#endif
++ FindErr( Err_PHY_TimeOut );
++ break;
++ }
++ }
++
++ DELAY( Delay_PHYRd );
++ Dat_ULONG = ReadSOC_DD( MAC_PHYBASE + 0x64 ) >> 16;
++ }
++
++ if ( DbgPrn_PHYRW )
++ printf ("[Rd ]%02d: %04lx\n", adr, Dat_ULONG );
++
++ return( Dat_ULONG );
++} // End ULONG phy_read (int adr)
++
++//------------------------------------------------------------
++void phy_Read_Write (int adr, ULONG clr_mask, ULONG set_mask) {
++ if ( DbgPrn_PHYRW )
++ printf ("[RW ]%02d: clr:%04lx: set:%04lx\n", adr, clr_mask, set_mask);
++ phy_write(adr, ((phy_read(adr) & (~clr_mask)) | set_mask));
++}
++
++//------------------------------------------------------------
++void phy_out ( int adr ) {
++ printf ("%02d: %04lx\n", adr, phy_read(adr));
++}
++
++//------------------------------------------------------------
++//void phy_outchg ( int adr ) {
++// ULONG PHY_valold = 0;
++// ULONG PHY_val;
++//
++// while (1) {
++// PHY_val = phy_read(adr);
++// if (PHY_valold != PHY_val) {
++// printf ("%02d: %04lx\n", adr, PHY_val);
++// PHY_valold = PHY_val;
++// }
++// }
++//}
++
++//------------------------------------------------------------
++void phy_dump (char *name) {
++ int index;
++
++ printf ("[%s][%d]----------------\n", name, PHY_ADR);
++ for (index = 0; index < 32; index++) {
++ printf ("%02d: %04lx ", index, phy_read(index));
++
++ if ((index % 8) == 7)
++ printf ("\n");
++ }
++}
++
++//------------------------------------------------------------
++void phy_id (BYTE option) {
++
++ ULONG reg_adr;
++ CHAR PHY_ADR_org;
++ FILE_VAR
++
++ GET_OBJ( option )
++
++ PHY_ADR_org = PHY_ADR;
++ for (PHY_ADR = 0; PHY_ADR < 32; PHY_ADR++) {
++
++ PRINT(OUT_OBJ "[%02d] ", PHY_ADR);
++
++ for (reg_adr = 2; reg_adr <= 3; reg_adr++)
++ PRINT(OUT_OBJ "%ld:%04lx ", reg_adr, phy_read(reg_adr));
++
++ if ((PHY_ADR % 4) == 3)
++ PRINT(OUT_OBJ "\n");
++ }
++ PHY_ADR = PHY_ADR_org;
++}
++
++
++//------------------------------------------------------------
++void phy_delay (int dt) {
++ DELAY( dt );
++}
++
++//------------------------------------------------------------
++// PHY IC
++//------------------------------------------------------------
++void phy_basic_setting (int loop_phy) {
++ phy_Read_Write(0, 0x7140, PHY_00h); //clr set
++ if ( DbgPrn_PHYRW )
++ printf ("[Set]00: %04lx\n", phy_read( PHY_REG_BMCR ));
++}
++
++//------------------------------------------------------------
++void phy_Wait_Reset_Done (void) {
++ int timeout = 0;
++
++ while ( phy_read( PHY_REG_BMCR ) & 0x8000 ) {
++ if (DbgPrn_PHYRW)
++ printf ("00: %04lx\n", phy_read( PHY_REG_BMCR ));
++
++ if (++timeout > TIME_OUT_PHY_Rst) {
++#ifdef SLT_DOS
++ if (!BurstEnable) fprintf(fp_log, "[PHY-Reset] Time out: %08lx\n", ReadSOC_DD(MAC_PHYBASE+0x60));
++#endif
++ FindErr(Err_PHY_TimeOut);
++ break;
++ }
++ }//wait Rst Done
++
++ if (DbgPrn_PHYRW) printf ("[Clr]00: %04lx\n", phy_read( PHY_REG_BMCR ));
++ DELAY(Delay_PHYRst);
++}
++
++//------------------------------------------------------------
++void phy_Reset (int loop_phy) {
++ phy_basic_setting(loop_phy);
++
++ phy_Read_Write(0, 0x0000, 0x8000 | PHY_00h);//clr set//Rst PHY
++ phy_Wait_Reset_Done();
++
++ phy_basic_setting(loop_phy);
++ DELAY(Delay_PHYRst);
++}
++
++//------------------------------------------------------------
++void recov_phy_marvell (int loop_phy) {//88E1111
++ if ( BurstEnable ) {
++ }
++ else if ( loop_phy ) {
++ }
++ else {
++ if (GSpeed_sel[0]) {
++ phy_write(9, PHY_09h);
++
++ phy_Reset(loop_phy);
++
++ phy_write(29, 0x0007);
++ phy_Read_Write(30, 0x0008, 0x0000);//clr set
++ phy_write(29, 0x0010);
++ phy_Read_Write(30, 0x0002, 0x0000);//clr set
++ phy_write(29, 0x0012);
++ phy_Read_Write(30, 0x0001, 0x0000);//clr set
++
++ phy_write(18, PHY_12h);
++ }
++ }
++}
++
++//------------------------------------------------------------
++void phy_marvell (int loop_phy) {//88E1111
++ int Retry;
++
++ if ( DbgPrn_PHYName )
++ printf ("--->(%04lx %04lx)[Marvell] %s\n", PHY_ID2, PHY_ID3, PHYName);
++
++ if ( BurstEnable ) {
++ phy_Reset(loop_phy);
++ }
++ else if ( loop_phy ) {
++ phy_Reset(loop_phy);
++ }
++ else {
++ if ( GSpeed_sel[0] ) {
++ PHY_09h = phy_read( PHY_GBCR );
++ PHY_12h = phy_read( PHY_INER );
++ phy_write ( 18, 0x0000 );
++ phy_Read_Write( 9, 0x0000, 0x1800 );//clr set
++ }
++
++ phy_Reset(loop_phy);
++
++ if (GSpeed_sel[0]) {
++ phy_write ( 29, 0x0007 );
++ phy_Read_Write( 30, 0x0000, 0x0008 );//clr set
++ phy_write ( 29, 0x0010 );
++ phy_Read_Write( 30, 0x0000, 0x0002 );//clr set
++ phy_write ( 29, 0x0012 );
++ phy_Read_Write( 30, 0x0000, 0x0001 );//clr set
++ }
++ }
++
++ Retry = 0;
++ do {
++ PHY_11h = phy_read( PHY_SR );
++ } while ( !( ( PHY_11h & 0x0400 ) | loop_phy | ( Retry++ > 20 ) ) );
++}
++
++//------------------------------------------------------------
++void recov_phy_marvell0 (int loop_phy) {//88E1310
++ if (BurstEnable) {
++ } else if (loop_phy) {
++ } else {
++ if (GSpeed_sel[0]) {
++ phy_write(22, 0x0006);
++ phy_Read_Write(16, 0x0020, 0x0000);//clr set
++ phy_write(22, 0x0000);
++ }
++ }
++}
++
++//------------------------------------------------------------
++void phy_marvell0 (int loop_phy) {//88E1310
++ int Retry;
++
++ if (DbgPrn_PHYName)
++ printf ("--->(%04lx %04lx)[Marvell] %s\n", PHY_ID2, PHY_ID3, PHYName);
++
++ phy_write( 22, 0x0002 );
++
++ PHY_15h = phy_read(21);
++ if (PHY_15h & 0x0030) {
++ printf ("\n\n[Warning] Page2, Register 21, bit 4~5 must be 0 [Reg15_2:%04lx]\n\n", PHY_15h);
++#ifdef SLT_DOS
++ if ( IOTiming )
++ fprintf (fp_io, "\n\n[Warning] Page2, Register 21, bit 4~5 must be 0 [Reg15_2:%04lx]\n\n", PHY_15h);
++ if ( !BurstEnable)
++ fprintf (fp_log, "\n\n[Warning] Page2, Register 21, bit 4~5 must be 0 [Reg15_2:%04lx]\n\n", PHY_15h);
++#endif
++// phy_Read_Write(21, 0x0030, 0x0000);//clr set//[5]Rx Dly, [4]Tx Dly
++ phy_write(21, PHY_15h & 0xffcf); // Set [5]Rx Dly, [4]Tx Dly to 0
++ }
++ phy_write(22, 0x0000);
++
++ if ( BurstEnable ) {
++ phy_Reset(loop_phy);
++ }
++ else if ( loop_phy ) {
++ phy_write( 22, 0x0002 );
++
++ if ( GSpeed_sel[0] ) {
++ phy_Read_Write( 21, 0x6040, 0x0040 );//clr set
++ }
++ else if ( GSpeed_sel[1] ) {
++ phy_Read_Write( 21, 0x6040, 0x2000 );//clr set
++ }
++ else {
++ phy_Read_Write( 21, 0x6040, 0x0000 );//clr set
++ }
++ phy_write( 22, 0x0000 );
++ phy_Reset( loop_phy );
++ }
++ else {
++ if ( GSpeed_sel[0] ) {
++ phy_write( 22, 0x0006 );
++ phy_Read_Write( 16, 0x0000, 0x0020 );//clr set
++ phy_write( 22, 0x0000 );
++ }
++
++ phy_Reset(loop_phy);
++ }
++
++ Retry = 0;
++ do {
++ PHY_11h = phy_read( PHY_SR );
++ } while (!((PHY_11h & 0x0400) | loop_phy | (Retry++ > 20)));
++}
++
++//------------------------------------------------------------
++void recov_phy_marvell1 (int loop_phy) {//88E6176
++ CHAR PHY_ADR_org;
++
++ PHY_ADR_org = PHY_ADR;
++ for ( PHY_ADR = 16; PHY_ADR <= 22; PHY_ADR++ ) {
++ if ( BurstEnable ) {
++ }
++ else {
++ phy_write(6, PHY_06hA[PHY_ADR-16]);//06h[5]P5 loopback, 06h[6]P6 loopback
++ }
++ }
++ for ( PHY_ADR = 21; PHY_ADR <= 22; PHY_ADR++ ) {
++ phy_write(1, 0x3); //01h[1:0]00 = 10 Mbps, 01 = 100 Mbps, 10 = 1000 Mbps, 11 = Speed is not forced.
++ }
++ PHY_ADR = PHY_ADR_org;
++}
++
++//------------------------------------------------------------
++void phy_marvell1 (int loop_phy) {//88E6176
++// ULONG PHY_01h;
++ CHAR PHY_ADR_org;
++
++ if (DbgPrn_PHYName)
++ printf ("--->(%04lx %04lx)[Marvell] %s\n", PHY_ID2, PHY_ID3, PHYName);
++
++ //The 88E6176 is switch with 7 Port(P0~P6) and the PHYAdr will be fixed at 0x10~0x16, and only P5/P6 can be connected to the MAC.
++ //Therefor, the 88E6176 only can run the internal loopback.
++ PHY_ADR_org = PHY_ADR;
++ for ( PHY_ADR = 16; PHY_ADR <= 20; PHY_ADR++ ) {
++ if ( BurstEnable ) {
++ }
++ else {
++ PHY_06hA[PHY_ADR-16] = phy_read( PHY_ANER );
++ phy_write(6, 0x00);//06h[5]P5 loopback, 06h[6]P6 loopback
++ }
++ }
++
++ for ( PHY_ADR = 21; PHY_ADR <= 22; PHY_ADR++ ) {
++// PHY_01h = phy_read( PHY_REG_BMSR );
++// if (GSpeed_sel[0]) phy_write(1, (PHY_01h & 0xfffc) | 0x2);//[1:0]00 = 10 Mbps, 01 = 100 Mbps, 10 = 1000 Mbps, 11 = Speed is not forced.
++// else if (GSpeed_sel[1]) phy_write(1, (PHY_01h & 0xfffc) | 0x1);//[1:0]00 = 10 Mbps, 01 = 100 Mbps, 10 = 1000 Mbps, 11 = Speed is not forced.
++// else phy_write(1, (PHY_01h & 0xfffc) );//[1:0]00 = 10 Mbps, 01 = 100 Mbps, 10 = 1000 Mbps, 11 = Speed is not forced.
++ if (GSpeed_sel[0]) phy_write(1, 0x2);//01h[1:0]00 = 10 Mbps, 01 = 100 Mbps, 10 = 1000 Mbps, 11 = Speed is not forced.
++ else if (GSpeed_sel[1]) phy_write(1, 0x1);//01h[1:0]00 = 10 Mbps, 01 = 100 Mbps, 10 = 1000 Mbps, 11 = Speed is not forced.
++ else phy_write(1, 0x0);//01h[1:0]00 = 10 Mbps, 01 = 100 Mbps, 10 = 1000 Mbps, 11 = Speed is not forced.
++
++ if (BurstEnable) {
++ }
++ else {
++ PHY_06hA[PHY_ADR-16] = phy_read( PHY_ANER );
++ if (PHY_ADR == 21) phy_write(6, 0x20);//06h[5]P5 loopback, 06h[6]P6 loopback
++ else phy_write(6, 0x40);//06h[5]P5 loopback, 06h[6]P6 loopback
++ }
++ }
++ PHY_ADR = PHY_ADR_org;
++}
++
++//------------------------------------------------------------
++void recov_phy_marvell2 (int loop_phy) {//88E1512
++ if (BurstEnable) {
++ }
++ else if (loop_phy) {
++ }
++ else {
++ if (GSpeed_sel[0]) {
++ phy_write(22, 0x0006);
++ phy_Read_Write(18, 0x0008, 0x0000);//clr set
++ phy_write(22, 0x0000);
++ }
++ }
++}
++
++//------------------------------------------------------------
++void phy_marvell2 (int loop_phy) {//88E1512
++ int Retry = 0;
++ ULONG temp_reg;
++
++ if ( DbgPrn_PHYName )
++ printf ("--->(%04lx %04lx)[Marvell] %s\n", PHY_ID2, PHY_ID3, PHYName);
++
++ phy_write(22, 0x0002);
++ PHY_15h = phy_read(21);
++
++ if ( PHY_15h & 0x0030 ) {
++ printf ("\n\n[Warning] Page2, Register 21, bit 4~5 must be 0 [Reg15h_2:%04lx]\n\n", PHY_15h);
++#ifdef SLT_DOS
++ if (IOTiming ) fprintf (fp_io, "\n\n[Warning] Page2, Register 21, bit 4~5 must be 0 [Reg15h_2:%04lx]\n\n", PHY_15h);
++ if (!BurstEnable) fprintf (fp_log, "\n\n[Warning] Page2, Register 21, bit 4~5 must be 0 [Reg15h_2:%04lx]\n\n", PHY_15h);
++#endif
++ // phy_Read_Write(21, 0x0030, 0x0000);//clr set//[5]Rx Dly, [4]Tx Dly
++// phy_write(21, PHY_15h & 0xffcf);
++ }
++ phy_write(22, 0x0000);
++
++ if ( BurstEnable ) {
++ phy_Reset(loop_phy);
++ }
++ else if (loop_phy) {
++ // Internal loopback funciton only support in copper mode
++ // switch page 18
++ phy_write(22, 0x0012);
++ // Change mode to Copper mode
++ phy_write(20, 0x8210);
++ // do software reset
++ do {
++ temp_reg = phy_read( 20 );
++ } while ( ( (temp_reg & 0x8000) == 0x8000 ) & (Retry++ < 20) );
++
++ // switch page 2
++ phy_write(22, 0x0002);
++ if (GSpeed_sel[0]) {
++ phy_Read_Write(21, 0x2040, 0x0040);//clr set
++ }
++ else if (GSpeed_sel[1]) {
++ phy_Read_Write(21, 0x2040, 0x2000);//clr set
++ }
++ else {
++ phy_Read_Write(21, 0x2040, 0x0000);//clr set
++ }
++ phy_write(22, 0x0000);
++
++ phy_Reset(loop_phy);
++ }
++ else {
++ if (GSpeed_sel[0]) {
++ phy_write(22, 0x0006);
++ phy_Read_Write(18, 0x0000, 0x0008);//clr set
++ phy_write(22, 0x0000);
++ }
++
++ phy_Reset(loop_phy);
++ }
++
++ Retry = 0;
++ do {
++ PHY_11h = phy_read( PHY_SR );
++ } while (!((PHY_11h & 0x0400) | loop_phy | (Retry++ > 20)));
++}
++
++//------------------------------------------------------------
++void phy_broadcom (int loop_phy) {//BCM5221
++ if (DbgPrn_PHYName)
++ printf ("--->(%04lx %04lx)[Broadcom] %s\n", PHY_ID2, PHY_ID3, PHYName);
++
++ phy_Reset(loop_phy);
++
++ if (IEEETesting) {
++ if (IOTimingBund_arg == 0) {
++ phy_write(25, 0x1f01);//Force MDI //Measuring from channel A
++ }
++ else {
++ phy_Read_Write(24, 0x0000, 0x4000);//clr set//Force Link
++// phy_write( 0, PHY_00h);
++// phy_write(30, 0x1000);
++ }
++ }
++}
++
++//------------------------------------------------------------
++void recov_phy_broadcom0 (int loop_phy) {//BCM54612
++
++ // Need to do it for AST2400
++ phy_write(0x1C, 0x8C00); // Disable GTXCLK Clock Delay Enable
++ phy_write(0x18, 0xF0E7); // Disable RGMII RXD to RXC Skew
++
++ if (BurstEnable) {
++ }
++ else if (loop_phy) {
++ phy_write( 0, PHY_00h);
++ }
++ else {
++ phy_write(0x00, PHY_00h);
++ phy_write(0x09, PHY_09h);
++ phy_write(0x18, PHY_18h);
++ }
++}
++
++//------------------------------------------------------------
++void phy_broadcom0 (int loop_phy) {//BCM54612
++ if ( DbgPrn_PHYName )
++ printf ("--->(%04lx %04lx)[Broadcom] %s\n", PHY_ID2, PHY_ID3, PHYName);
++
++ // Need to do it for AST2400
++ phy_write(0x1C, 0x8C00); // Disable GTXCLK Clock Delay Enable
++ phy_write(0x18, 0xF0E7); // Disable RGMII RXD to RXC Skew
++
++ // Backup org value
++ // read reg 18H, Page 103, BCM54612EB1KMLG_Spec.pdf
++ phy_write(0x18, 0x7007);
++ PHY_18h = phy_read(0x18);
++
++ PHY_00h = phy_read( PHY_REG_BMCR );
++ PHY_09h = phy_read( PHY_GBCR );
++
++ if ( BurstEnable ) {
++ phy_basic_setting(loop_phy);
++ }
++ else if (loop_phy) {
++ phy_basic_setting(loop_phy);
++
++ // Enable Internal Loopback mode
++ // Page 58, BCM54612EB1KMLG_Spec.pdf
++ phy_write(0x0, 0x5140);
++ DELAY(Delay_PHYRst);
++ /* Only 1G Test is PASS, 100M and 10M is false @20130619 */
++
++// Waiting for BCM FAE's response
++// if (GSpeed_sel[0]) {
++// // Speed 1G
++// // Enable Internal Loopback mode
++// // Page 58, BCM54612EB1KMLG_Spec.pdf
++// phy_write(0x0, 0x5140);
++// }
++// else if (GSpeed_sel[1]) {
++// // Speed 100M
++// // Enable Internal Loopback mode
++// // Page 58, BCM54612EB1KMLG_Spec.pdf
++// phy_write(0x0, 0x7100);
++// phy_write(0x1E, 0x1000);
++// }
++// else if (GSpeed_sel[2]) {
++// // Speed 10M
++// // Enable Internal Loopback mode
++// // Page 58, BCM54612EB1KMLG_Spec.pdf
++// phy_write(0x0, 0x5100);
++// phy_write(0x1E, 0x1000);
++// }
++//
++// DELAY(Delay_PHYRst);
++ }
++ else {
++
++ if (GSpeed_sel[0]) {
++ // Page 60, BCM54612EB1KMLG_Spec.pdf
++ // need to insert loopback plug
++ phy_write( 9, 0x1800);
++ phy_write( 0, 0x0140);
++ phy_write( 0x18, 0x8400); // Enable Transmit test mode
++ } else if (GSpeed_sel[1]) {
++ // Page 60, BCM54612EB1KMLG_Spec.pdf
++ // need to insert loopback plug
++ phy_write( 0, 0x2100);
++ phy_write( 0x18, 0x8400); // Enable Transmit test mode
++ } else {
++ // Page 60, BCM54612EB1KMLG_Spec.pdf
++ // need to insert loopback plug
++ phy_write( 0, 0x0100);
++ phy_write( 0x18, 0x8400); // Enable Transmit test mode
++ }
++ }
++}
++
++//------------------------------------------------------------
++void phy_realtek (int loop_phy) {//RTL8201N
++ if ( DbgPrn_PHYName )
++ printf ("--->(%04lx %04lx)[Realtek] %s\n", PHY_ID2, PHY_ID3, PHYName);
++
++ phy_Reset(loop_phy);
++}
++
++//------------------------------------------------------------
++//internal loop 100M: Don't support
++//internal loop 10M : no loopback stub
++void phy_realtek0 (int loop_phy) {//RTL8201E
++ if ( DbgPrn_PHYName )
++ printf ("--->(%04lx %04lx)[Realtek] %s\n", PHY_ID2, PHY_ID3, PHYName);
++
++ phy_Reset(loop_phy);
++
++// phy_Read_Write(25, 0x2800, 0x0000);//clr set
++// printf("Enable phy output RMII clock\n");
++ if (IEEETesting) {
++ phy_write(31, 0x0001);
++ if (IOTimingBund_arg == 0) {
++ phy_write(25, 0x1f01);//Force MDI //Measuring from channel A
++ }
++ else {
++ phy_write(25, 0x1f00);//Force MDIX //Measuring from channel B
++ }
++ phy_write(31, 0x0000);
++ }
++}
++
++//------------------------------------------------------------
++void recov_phy_realtek1 (int loop_phy) {//RTL8211D
++ if ( BurstEnable ) {
++ if ( IEEETesting ) {
++ if ( GSpeed_sel[0] ) {
++ if (IOTimingBund_arg == 0) {
++ //Test Mode 1
++ phy_write( 31, 0x0002 );
++ phy_write( 2, 0xc203 );
++ phy_write( 31, 0x0000 );
++ phy_write( 9, 0x0000 );
++ }
++ else {
++ //Test Mode 4
++ phy_write( 31, 0x0000 );
++ phy_write( 9, 0x0000 );
++ }
++
++ phy_write( 31, 0x0000 );
++ }
++ else if ( GSpeed_sel[1] ) {
++ phy_write( 23, 0x2100 );
++ phy_write( 16, 0x016e );
++ }
++ else {
++// phy_write( 31, 0x0006 );
++// phy_write( 0, 0x5a00 );
++// phy_write( 31, 0x0000 );
++ }
++ } // End if ( IEEETesting )
++ }
++ else if (loop_phy) {
++ if ( GSpeed_sel[0] ) {
++ phy_write( 31, 0x0000 ); // new in Rev. 1.6
++ phy_write( 0, 0x1140 ); // new in Rev. 1.6
++ phy_write( 20, 0x8040 ); // new in Rev. 1.6
++ }
++ }
++ else {
++ if ( GSpeed_sel[0] ) {
++ phy_write( 31, 0x0001 );
++ phy_write( 3, 0xdf41 );
++ phy_write( 2, 0xdf20 );
++ phy_write( 1, 0x0140 );
++ phy_write( 0, 0x00bb );
++ phy_write( 4, 0xb800 );
++ phy_write( 4, 0xb000 );
++
++ phy_write( 31, 0x0000 );
++// phy_write( 26, 0x0020 ); // Rev. 1.2
++ phy_write( 26, 0x0040 ); // new in Rev. 1.6
++ phy_write( 0, 0x1140 );
++// phy_write( 21, 0x0006 ); // Rev. 1.2
++ phy_write( 21, 0x1006 ); // new in Rev. 1.6
++ phy_write( 23, 0x2100 );
++// } else if ( GSpeed_sel[1] ) {//option
++// phy_write( 31, 0x0000 );
++// phy_write( 9, 0x0200 );
++// phy_write( 0, 0x1200 );
++// } else if ( GSpeed_sel[2] ) {//option
++// phy_write( 31, 0x0000 );
++// phy_write( 9, 0x0200 );
++// phy_write( 4, 0x05e1 );
++// phy_write( 0, 0x1200 );
++ }
++ } // End if ( BurstEnable )
++} // End void recov_phy_realtek1 (int loop_phy)
++
++//------------------------------------------------------------
++//internal loop 1G : no loopback stub
++//internal loop 100M: no loopback stub
++//internal loop 10M : no loopback stub
++void phy_realtek1 (int loop_phy) {//RTL8211D
++ if ( DbgPrn_PHYName )
++ printf ("--->(%04lx %04lx)[Realtek] %s\n", PHY_ID2, PHY_ID3, PHYName);
++
++ if ( BurstEnable ) {
++ if ( IEEETesting ) {
++ if ( GSpeed_sel[0] ) {
++ if (IOTimingBund_arg == 0) {
++ //Test Mode 1
++ phy_write( 31, 0x0002 );
++ phy_write( 2, 0xc22b );
++ phy_write( 31, 0x0000 );
++ phy_write( 9, 0x2000 );
++ }
++ else {
++ //Test Mode 4
++ phy_write( 31, 0x0000 );
++ phy_write( 9, 0x8000 );
++ }
++ phy_write( 31, 0x0000 );
++ }
++ else if ( GSpeed_sel[1] ) {
++ if ( IOTimingBund_arg == 0 ) {
++ //From Channel A
++ phy_write( 23, 0xa102 );
++ phy_write( 16, 0x01ae );//MDI
++ }
++ else {
++ //From Channel B
++ phy_Read_Write( 17, 0x0008, 0x0000 ); // clr set
++ phy_write( 23, 0xa102 ); // MDI
++ phy_write( 16, 0x010e );
++ }
++ } else {
++// if ( IOTimingBund_arg == 0 ) {//Pseudo-random pattern
++// phy_write( 31, 0x0006 );
++// phy_write( 0, 0x5a21 );
++// phy_write( 31, 0x0000 );
++// }
++// else if ( IOTimingBund_arg == 1 ) {//¡§FF¡¨ pattern
++// phy_write( 31, 0x0006 );
++// phy_write( 2, 0x05ee );
++// phy_write( 0, 0xff21 );
++// phy_write( 31, 0x0000 );
++// } else {//¡§00¡¨ pattern
++// phy_write( 31, 0x0006 );
++// phy_write( 2, 0x05ee );
++// phy_write( 0, 0x0021 );
++// phy_write( 31, 0x0000 );
++// }
++ }
++ }
++ else {
++ phy_Reset(loop_phy);
++ }
++ }
++ else if ( loop_phy ) {
++ phy_Reset(loop_phy);
++
++ if ( GSpeed_sel[0] ) {
++ phy_write(20, 0x0042);//new in Rev. 1.6
++ }
++ }
++ else {
++ if ( GSpeed_sel[0] ) {
++ phy_write( 31, 0x0001 );
++ phy_write( 3, 0xff41 );
++ phy_write( 2, 0xd720 );
++ phy_write( 1, 0x0140 );
++ phy_write( 0, 0x00bb );
++ phy_write( 4, 0xb800 );
++ phy_write( 4, 0xb000 );
++
++ phy_write( 31, 0x0007 );
++ phy_write( 30, 0x0040 );
++ phy_write( 24, 0x0008 );
++
++ phy_write( 31, 0x0000 );
++ phy_write( 9, 0x0300 );
++ phy_write( 26, 0x0020 );
++ phy_write( 0, 0x0140 );
++ phy_write( 23, 0xa101 );
++ phy_write( 21, 0x0200 );
++ phy_write( 23, 0xa121 );
++ phy_write( 23, 0xa161 );
++ phy_write( 0, 0x8000 );
++ phy_Wait_Reset_Done();
++ phy_delay(200); // new in Rev. 1.6
++// }
++// else if ( GSpeed_sel[1] ) {//option
++// phy_write( 31, 0x0000 );
++// phy_write( 9, 0x0000 );
++// phy_write( 4, 0x0061 );
++// phy_write( 0, 0x1200 );
++// phy_delay(5000);
++// }
++// else if (GSpeed_sel[2]) {//option
++// phy_write( 31, 0x0000 );
++// phy_write( 9, 0x0000 );
++// phy_write( 4, 0x05e1 );
++// phy_write( 0, 0x1200 );
++// phy_delay(5000);
++ }
++ else {
++ phy_Reset(loop_phy);
++ }
++ }
++} // End void phy_realtek1 (int loop_phy)
++
++//------------------------------------------------------------
++void recov_phy_realtek2 (int loop_phy) {//RTL8211E
++ if ( BurstEnable ) {
++ if ( IEEETesting ) {
++ phy_write( 31, 0x0005 );
++ phy_write( 5, 0x8b86 );
++ phy_write( 6, 0xe201 );
++ phy_write( 31, 0x0007 );
++ phy_write( 30, 0x0020 );
++ phy_write( 21, 0x1108 );
++ phy_write( 31, 0x0000 );
++
++ if ( GSpeed_sel[0] ) {
++ phy_write( 31, 0x0000 );
++ phy_write( 9, 0x0000 );
++ }
++ else if ( GSpeed_sel[1] ) {
++ phy_write( 31, 0x0007 );
++ phy_write( 30, 0x002f );
++ phy_write( 23, 0xd88f );
++ phy_write( 30, 0x002d );
++ phy_write( 24, 0xf050 );
++ phy_write( 31, 0x0000 );
++ phy_write( 16, 0x006e );
++ }
++ else {
++ }
++ }
++ else {
++ }
++ }
++ else if (loop_phy) {
++ }
++ else {
++ if (GSpeed_sel[0]) {
++ //Rev 1.5 //not stable
++// phy_write( 31, 0x0000 );
++// phy_write( 0, 0x8000 );
++// phy_Wait_Reset_Done();
++// phy_delay(30);
++// phy_write( 23, 0x2160 );
++// phy_write( 31, 0x0007 );
++// phy_write( 30, 0x0040 );
++// phy_write( 24, 0x0004 );
++// phy_write( 24, 0x1a24 );
++// phy_write( 25, 0xfd00 );
++// phy_write( 24, 0x0000 );
++// phy_write( 31, 0x0000 );
++// phy_write( 0, 0x1140 );
++// phy_write( 26, 0x0040 );
++// phy_write( 31, 0x0007 );
++// phy_write( 30, 0x002f );
++// phy_write( 23, 0xd88f );
++// phy_write( 30, 0x0023 );
++// phy_write( 22, 0x0300 );
++// phy_write( 31, 0x0000 );
++// phy_write( 21, 0x1006 );
++// phy_write( 23, 0x2100 );
++/**/
++ //Rev 1.6
++ phy_write( 31, 0x0000 );
++ phy_write( 0, 0x8000 );
++ phy_Wait_Reset_Done();
++ phy_delay(30);
++ phy_write( 31, 0x0007 );
++ phy_write( 30, 0x0042 );
++ phy_write( 21, 0x0500 );
++ phy_write( 31, 0x0000 );
++ phy_write( 0, 0x1140 );
++ phy_write( 26, 0x0040 );
++ phy_write( 31, 0x0007 );
++ phy_write( 30, 0x002f );
++ phy_write( 23, 0xd88f );
++ phy_write( 30, 0x0023 );
++ phy_write( 22, 0x0300 );
++ phy_write( 31, 0x0000 );
++ phy_write( 21, 0x1006 );
++ phy_write( 23, 0x2100 );
++/**/
++// } else if (GSpeed_sel[1]) {//option
++// phy_write( 31, 0x0000 );
++// phy_write( 9, 0x0200 );
++// phy_write( 0, 0x1200 );
++// } else if (GSpeed_sel[2]) {//option
++// phy_write( 31, 0x0000 );
++// phy_write( 9, 0x0200 );
++// phy_write( 4, 0x05e1 );
++// phy_write( 0, 0x1200 );
++ }
++ }
++} // End void recov_phy_realtek2 (int loop_phy)
++
++//------------------------------------------------------------
++//internal loop 1G : no loopback stub
++//internal loop 100M: no loopback stub
++//internal loop 10M : no loopback stub
++void phy_realtek2 (int loop_phy) {//RTL8211E
++
++ if ( DbgPrn_PHYName )
++ printf ("--->(%04lx %04lx)[Realtek] %s\n", PHY_ID2, PHY_ID3, PHYName);
++
++ phy_Read_Write( 0, 0x0000, 0x8000 | PHY_00h ); // clr set // Rst PHY
++ phy_Wait_Reset_Done();
++ phy_delay(30);
++
++ if ( BurstEnable ) {
++ if ( IEEETesting ) {
++ phy_write( 31, 0x0005 );
++ phy_write( 5, 0x8b86 );
++ phy_write( 6, 0xe200 );
++ phy_write( 31, 0x0007 );
++ phy_write( 30, 0x0020 );
++ phy_write( 21, 0x0108 );
++ phy_write( 31, 0x0000 );
++
++ if ( GSpeed_sel[0] ) {
++ phy_write( 31, 0x0000 );
++
++ if ( IOTimingBund_arg == 0 ) {
++ phy_write( 9, 0x2000);//Test Mode 1
++ }
++ else {
++ phy_write( 9, 0x8000);//Test Mode 4
++ }
++ }
++ else if ( GSpeed_sel[1] ) {
++ phy_write( 31, 0x0007 );
++ phy_write( 30, 0x002f );
++ phy_write( 23, 0xd818 );
++ phy_write( 30, 0x002d );
++ phy_write( 24, 0xf060 );
++ phy_write( 31, 0x0000 );
++
++ if ( IOTimingBund_arg == 0 ) {
++ phy_write(16, 0x00ae);//From Channel A
++ }
++ else {
++ phy_write(16, 0x008e);//From Channel B
++ }
++ }
++ else {
++ }
++ }
++ else {
++ phy_basic_setting(loop_phy);
++ phy_delay(30);
++ }
++ }
++ else if (loop_phy) {
++ phy_basic_setting(loop_phy);
++
++ phy_Read_Write(0, 0x0000, 0x8000 | PHY_00h);//clr set//Rst PHY
++ phy_Wait_Reset_Done();
++ phy_delay(30);
++
++ phy_basic_setting(loop_phy);
++ phy_delay(30);
++ }
++ else {
++ if ( GSpeed_sel[0] ) {
++ //Rev 1.5 //not stable
++// phy_write( 23, 0x2160 );
++// phy_write( 31, 0x0007 );
++// phy_write( 30, 0x0040 );
++// phy_write( 24, 0x0004 );
++// phy_write( 24, 0x1a24 );
++// phy_write( 25, 0x7d00 );
++// phy_write( 31, 0x0000 );
++// phy_write( 23, 0x2100 );
++// phy_write( 31, 0x0007 );
++// phy_write( 30, 0x0040 );
++// phy_write( 24, 0x0000 );
++// phy_write( 30, 0x0023 );
++// phy_write( 22, 0x0006 );
++// phy_write( 31, 0x0000 );
++// phy_write( 0, 0x0140 );
++// phy_write( 26, 0x0060 );
++// phy_write( 31, 0x0007 );
++// phy_write( 30, 0x002f );
++// phy_write( 23, 0xd820 );
++// phy_write( 31, 0x0000 );
++// phy_write( 21, 0x0206 );
++// phy_write( 23, 0x2120 );
++// phy_write( 23, 0x2160 );
++/**/
++ //Rev 1.6
++ phy_write( 31, 0x0007 );
++ phy_write( 30, 0x0042 );
++ phy_write( 21, 0x2500 );
++ phy_write( 30, 0x0023 );
++ phy_write( 22, 0x0006 );
++ phy_write( 31, 0x0000 );
++ phy_write( 0, 0x0140 );
++ phy_write( 26, 0x0060 );
++ phy_write( 31, 0x0007 );
++ phy_write( 30, 0x002f );
++ phy_write( 23, 0xd820 );
++ phy_write( 31, 0x0000 );
++ phy_write( 21, 0x0206 );
++ phy_write( 23, 0x2120 );
++ phy_write( 23, 0x2160 );
++ phy_delay(300);
++/**/
++// }
++// else if ( GSpeed_sel[1] ) {//option
++// phy_write( 31, 0x0000 );
++// phy_write( 9, 0x0000 );
++// phy_write( 4, 0x0061 );
++// phy_write( 0, 0x1200 );
++// phy_delay(5000);
++// }
++// else if ( GSpeed_sel[2] ) {//option
++// phy_write( 31, 0x0000 );
++// phy_write( 9, 0x0000 );
++// phy_write( 4, 0x05e1 );
++// phy_write( 0, 0x1200 );
++// phy_delay(5000);
++ }
++ else {
++ phy_basic_setting(loop_phy);
++ phy_delay(150);
++ }
++ }
++} // End void phy_realtek2 (int loop_phy)
++
++//------------------------------------------------------------
++void recov_phy_realtek3 (int loop_phy) {//RTL8211C
++ if ( BurstEnable ) {
++ if ( IEEETesting ) {
++ if ( GSpeed_sel[0] ) {
++ phy_write( 9, 0x0000 );
++ }
++ else if ( GSpeed_sel[1] ) {
++ phy_write( 17, PHY_11h );
++ phy_write( 14, 0x0000 );
++ phy_write( 16, 0x00a0 );
++ }
++ else {
++// phy_write( 31, 0x0006 );
++// phy_write( 0, 0x5a00 );
++// phy_write( 31, 0x0000 );
++ }
++ }
++ else {
++ }
++ }
++ else if (loop_phy) {
++ if ( GSpeed_sel[0] ) {
++ phy_write( 11, 0x0000 );
++ }
++ phy_write( 12, 0x1006 );
++ }
++ else {
++ if ( GSpeed_sel[0] ) {
++ phy_write( 31, 0x0001 );
++ phy_write( 4, 0xb000 );
++ phy_write( 3, 0xff41 );
++ phy_write( 2, 0xdf20 );
++ phy_write( 1, 0x0140 );
++ phy_write( 0, 0x00bb );
++ phy_write( 4, 0xb800 );
++ phy_write( 4, 0xb000 );
++
++ phy_write( 31, 0x0000 );
++ phy_write( 25, 0x8c00 );
++ phy_write( 26, 0x0040 );
++ phy_write( 0, 0x1140 );
++ phy_write( 14, 0x0000 );
++ phy_write( 12, 0x1006 );
++ phy_write( 23, 0x2109 );
++ }
++ }
++}
++
++//------------------------------------------------------------
++void phy_realtek3 (int loop_phy) {//RTL8211C
++ if ( DbgPrn_PHYName )
++ printf ("--->(%04lx %04lx)[Realtek] %s\n", PHY_ID2, PHY_ID3, PHYName);
++
++ if ( BurstEnable ) {
++ if ( IEEETesting ) {
++ if ( GSpeed_sel[0] ) {
++ if ( IOTimingBund_arg == 0 ) { //Test Mode 1
++ phy_write( 9, 0x2000);
++ }
++ else if (IOTimingBund_arg == 1) {//Test Mode 2
++ phy_write( 9, 0x4000);
++ }
++ else if (IOTimingBund_arg == 2) {//Test Mode 3
++ phy_write( 9, 0x6000);
++ }
++ else { //Test Mode 4
++ phy_write( 9, 0x8000);
++ }
++ }
++ else if ( GSpeed_sel[1] ) {
++ PHY_11h = phy_read( PHY_SR );
++ phy_write( 17, PHY_11h & 0xfff7 );
++ phy_write( 14, 0x0660 );
++
++ if ( IOTimingBund_arg == 0 ) {
++ phy_write( 16, 0x00a0 );//MDI //From Channel A
++ }
++ else {
++ phy_write( 16, 0x0080 );//MDIX //From Channel B
++ }
++ }
++ else {
++// if (IOTimingBund_arg == 0) {//Pseudo-random pattern
++// phy_write( 31, 0x0006 );
++// phy_write( 0, 0x5a21 );
++// phy_write( 31, 0x0000 );
++// }
++// else if (IOTimingBund_arg == 1) {//¡§FF¡¨ pattern
++// phy_write( 31, 0x0006 );
++// phy_write( 2, 0x05ee );
++// phy_write( 0, 0xff21 );
++// phy_write( 31, 0x0000 );
++// }
++// else {//¡§00¡¨ pattern
++// phy_write( 31, 0x0006 );
++// phy_write( 2, 0x05ee );
++// phy_write( 0, 0x0021 );
++// phy_write( 31, 0x0000 );
++// }
++ }
++ }
++ else {
++ phy_Reset(loop_phy);
++ }
++ }
++ else if (loop_phy) {
++ phy_write( 0, 0x9200);
++ phy_Wait_Reset_Done();
++ phy_delay(30);
++
++ phy_write( 17, 0x401c );
++ phy_write( 12, 0x0006 );
++
++ if ( GSpeed_sel[0] ) {
++ phy_write(11, 0x0002);
++ }
++ else {
++ phy_basic_setting(loop_phy);
++ }
++ }
++ else {
++ if (GSpeed_sel[0]) {
++ phy_write( 31, 0x0001 );
++ phy_write( 4, 0xb000 );
++ phy_write( 3, 0xff41 );
++ phy_write( 2, 0xd720 );
++ phy_write( 1, 0x0140 );
++ phy_write( 0, 0x00bb );
++ phy_write( 4, 0xb800 );
++ phy_write( 4, 0xb000 );
++
++ phy_write( 31, 0x0000 );
++ phy_write( 25, 0x8400 );
++ phy_write( 26, 0x0020 );
++ phy_write( 0, 0x0140 );
++ phy_write( 14, 0x0210 );
++ phy_write( 12, 0x0200 );
++ phy_write( 23, 0x2109 );
++ phy_write( 23, 0x2139 );
++ }
++ else {
++ phy_Reset(loop_phy);
++ }
++ }
++} // End void phy_realtek3 (int loop_phy)
++
++//------------------------------------------------------------
++void phy_realtek4 (int loop_phy) {//RTL8201F
++ if ( DbgPrn_PHYName )
++ printf ("--->(%04lx %04lx)[Realtek] %s\n", PHY_ID2, PHY_ID3, PHYName);
++
++ if ( BurstEnable ) {
++ if ( IEEETesting ) {
++ phy_write( 31, 0x0004 );
++ phy_write( 16, 0x4077 );
++ phy_write( 21, 0xc5a0 );
++ phy_write( 31, 0x0000 );
++
++ if ( GSpeed_sel[1] ) {
++ phy_write( 0, 0x8000 ); // Reset PHY
++ phy_write( 24, 0x0310 ); // Disable ALDPS
++
++ if ( IOTimingBund_arg == 0 ) {
++ phy_write( 28, 0x40c2 ); //Force MDI //From Channel A (RJ45 pair 1, 2)
++ }
++ else {
++ phy_write( 28, 0x40c0 ); //Force MDIX//From Channel B (RJ45 pair 3, 6)
++ }
++ phy_write( 0, 0x2100); //Force 100M/Full Duplex)
++ }
++ } else {
++ phy_Reset(loop_phy);
++ }
++ }
++ else {
++ phy_Reset(loop_phy);
++ }
++}
++
++//------------------------------------------------------------
++void phy_smsc (int loop_phy) {//LAN8700
++ if ( DbgPrn_PHYName )
++ printf ("--->(%04lx %04lx)[SMSC] %s\n", PHY_ID2, PHY_ID3, PHYName);
++
++ phy_Reset(loop_phy);
++}
++
++//------------------------------------------------------------
++void phy_micrel (int loop_phy) {//KSZ8041
++ if ( DbgPrn_PHYName )
++ printf ("--->(%04lx %04lx)[Micrel] %s\n", PHY_ID2, PHY_ID3, PHYName);
++
++ phy_Reset(loop_phy);
++
++// phy_write(24, 0x0600);
++}
++
++//------------------------------------------------------------
++void phy_micrel0 (int loop_phy) {//KSZ8031/KSZ8051
++ if ( DbgPrn_PHYName ) printf ("--->(%04lx %04lx)[Micrel] %s\n", PHY_ID2, PHY_ID3, PHYName);
++
++ //For KSZ8051RNL only
++ //Reg1Fh[7] = 0(default): 25MHz Mode, XI, XO(pin 9, 8) is 25MHz(crystal/oscilator).
++ //Reg1Fh[7] = 1 : 50MHz Mode, XI(pin 9) is 50MHz(oscilator).
++ PHY_1fh = phy_read(31);
++ if (PHY_1fh & 0x0080) sprintf(PHYName, "%s-50MHz Mode", PHYName);
++ else sprintf(PHYName, "%s-25MHz Mode", PHYName);
++
++ if (IEEETesting) {
++ phy_Read_Write( 0, 0x0000, 0x8000 | PHY_00h );//clr set//Rst PHY
++ phy_Wait_Reset_Done();
++
++ phy_Read_Write( 31, 0x0000, 0x2000 );//clr set//1Fh[13] = 1: Disable auto MDI/MDI-X
++ phy_basic_setting(loop_phy);
++ phy_Read_Write( 31, 0x0000, 0x0800 );//clr set//1Fh[11] = 1: Force link pass
++
++// phy_delay(2500);//2.5 sec
++ }
++ else {
++ phy_Reset(loop_phy);
++
++ //Reg16h[6] = 1 : RMII B-to-B override
++ //Reg16h[1] = 1(default): RMII override
++ phy_Read_Write( 22, 0x0000, 0x0042 );//clr set
++ }
++
++ if ( PHY_1fh & 0x0080 )
++ phy_Read_Write( 31, 0x0000, 0x0080 );//clr set//Reset PHY will clear Reg1Fh[7]
++}
++
++//------------------------------------------------------------
++void recov_phy_vitesse (int loop_phy) {//VSC8601
++ if ( BurstEnable ) {
++// if (IEEETesting) {
++// } else {
++// }
++ }
++ else if ( loop_phy ) {
++ }
++ else {
++ if ( GSpeed_sel[0] ) {
++ phy_write( 24, PHY_18h );
++ phy_write( 18, PHY_12h );
++ }
++ }
++}
++
++//------------------------------------------------------------
++void phy_vitesse (int loop_phy) {//VSC8601
++ if ( DbgPrn_PHYName )
++ printf ("--->(%04lx %04lx)[VITESSE] %s\n", PHY_ID2, PHY_ID3, PHYName);
++
++ if ( BurstEnable ) {
++ if ( IEEETesting ) {
++ phy_Reset(loop_phy);
++ }
++ else {
++ phy_Reset(loop_phy);
++ }
++ }
++ else if ( loop_phy ) {
++ phy_Reset(loop_phy);
++ }
++ else {
++ if ( GSpeed_sel[0] ) {
++ PHY_18h = phy_read( 24 );
++ PHY_12h = phy_read( PHY_INER );
++
++ phy_Reset(loop_phy);
++
++ phy_write( 24, PHY_18h | 0x0001 );
++ phy_write( 18, PHY_12h | 0x0020 );
++ }
++ else {
++ phy_Reset(loop_phy);
++ }
++ }
++}
++
++//------------------------------------------------------------
++void phy_default (int loop_phy) {
++ if ( DbgPrn_PHYName )
++ printf ("--->(%04lx %04lx)%s\n", PHY_ID2, PHY_ID3, PHYName);
++
++ phy_Reset(loop_phy);
++}
++
++//------------------------------------------------------------
++// PHY Init
++//------------------------------------------------------------
++BOOLEAN find_phyadr (void) {
++ ULONG PHY_val;
++ BOOLEAN ret = FALSE;
++
++ #ifdef DbgPrn_FuncHeader
++ printf ("find_phyadr\n");
++ Debug_delay();
++ #endif
++
++ do {
++ // Check current PHY address by user setting
++ PHY_val = phy_read( PHY_REG_ID_1 );
++ if ( PHY_IS_VALID(PHY_val) ) {
++ ret = TRUE;
++ break;
++ }
++
++ if ( Enable_SkipChkPHY ) {
++ PHY_val = phy_read( PHY_REG_BMCR );
++
++ if ((PHY_val & 0x8000) & Enable_InitPHY) {
++ // PHY is reseting and need to inital PHY
++ #ifndef Enable_SearchPHYID
++ break;
++ #endif
++ }
++ else {
++ ret = TRUE;
++ break;
++ }
++ }
++
++ #ifdef Enable_SearchPHYID
++ // Scan PHY address from 0 to 31
++ printf("Search PHY address\n");
++ for ( PHY_ADR = 0; PHY_ADR < 32; PHY_ADR++ ) {
++ PHY_val = phy_read( PHY_REG_ID_1 );
++ if ( PHY_IS_VALID(PHY_val) ) {
++ ret = TRUE;
++ break;
++ }
++ }
++ // Don't find PHY address
++ PHY_ADR = PHY_ADR_arg;
++ #endif
++ } while ( 0 );
++
++ if ( ret == TRUE ) {
++ if ( PHY_ADR_arg != PHY_ADR ) {
++
++ if ( !BurstEnable )
++ phy_id( FP_LOG );
++
++ phy_id( STD_OUT );
++ }
++ }
++ else {
++
++ if ( !BurstEnable )
++ phy_id( FP_LOG );
++
++ phy_id( STD_OUT );
++ FindErr( Err_PHY_Type );
++ }
++
++ return ret;
++} // End BOOLEAN find_phyadr (void)
++
++//------------------------------------------------------------
++char phy_chk (ULONG id2, ULONG id3, ULONG id3_mask) {
++ if ((PHY_ID2 == id2) && ((PHY_ID3 & id3_mask) == (id3 & id3_mask)))
++ return(1);
++ else
++ return(0);
++}
++
++//------------------------------------------------------------
++void phy_set00h (int loop_phy) {
++ #ifdef DbgPrn_FuncHeader
++ printf ("phy_set00h\n");
++ Debug_delay();
++ #endif
++
++ if (BurstEnable) {
++ if (IEEETesting) {
++ if (GSpeed_sel[0]) PHY_00h = 0x0140;
++ else if (GSpeed_sel[1]) PHY_00h = 0x2100;
++ else PHY_00h = 0x0100;
++ }
++ else {
++ if (GSpeed_sel[0]) PHY_00h = 0x1140;
++ else if (GSpeed_sel[1]) PHY_00h = 0x3100;
++ else PHY_00h = 0x1100;
++ }
++ }
++ else if (loop_phy) {
++ if (GSpeed_sel[0]) PHY_00h = 0x4140;
++ else if (GSpeed_sel[1]) PHY_00h = 0x6100;
++ else PHY_00h = 0x4100;
++ }
++ else {
++ if (GSpeed_sel[0]) PHY_00h = 0x0140;
++ else if (GSpeed_sel[1]) PHY_00h = 0x2100;
++ else PHY_00h = 0x0100;
++ }
++}
++
++//------------------------------------------------------------
++void phy_sel (int loop_phy) {
++ #ifdef DbgPrn_FuncHeader
++ printf ("phy_sel\n");
++ Debug_delay();
++ #endif
++
++ PHY_ID2 = phy_read( PHY_REG_ID_1 );
++ PHY_ID3 = phy_read( PHY_REG_ID_2 );
++ phy_set00h(loop_phy);
++
++ if ((PHY_ID2 == 0xffff) && (PHY_ID3 == 0xffff) && !Enable_SkipChkPHY) {
++ sprintf(PHYName, "--");
++ FindErr(Err_PHY_Type);
++ }
++#ifdef Enable_CheckZeroPHYID
++ else if ((PHY_ID2 == 0x0000) && (PHY_ID3 == 0x0000) && !Enable_SkipChkPHY) {
++ sprintf(PHYName, "--"); FindErr(Err_PHY_Type);
++ }
++#endif
++
++ if (phy_chk(0x0362, 0x5e6a, 0xfff0 )) {sprintf(PHYName, "BCM54612" ); if (Enable_InitPHY) phy_broadcom0(loop_phy);}//BCM54612 1G/100/10M RGMII
++ else if (phy_chk(0x0362, 0x5d10, 0xfff0 )) {sprintf(PHYName, "BCM54616S" ); if (Enable_InitPHY) phy_broadcom0(loop_phy);}//BCM54616A 1G/100/10M RGMII
++ else if (phy_chk(0x0040, 0x61e0, PHYID3_Mask)) {sprintf(PHYName, "BCM5221" ); if (Enable_InitPHY) phy_broadcom (loop_phy);}//BCM5221 100/10M MII, RMII
++ else if (phy_chk(0x0141, 0x0dd0, 0xfff0 )) {sprintf(PHYName, "88E1512" ); if (Enable_InitPHY) phy_marvell2 (loop_phy);}//88E1512 1G/100/10M RGMII
++ else if (phy_chk(0xff00, 0x1761, 0xffff )) {sprintf(PHYName, "88E6176(IntLoop)"); if (Enable_InitPHY) phy_marvell1 (loop_phy);}//88E6176 1G/100/10M 2 RGMII Switch
++ else if (phy_chk(0x0141, 0x0e90, 0xfff0 )) {sprintf(PHYName, "88E1310" ); if (Enable_InitPHY) phy_marvell0 (loop_phy);}//88E1310 1G/100/10M RGMII
++ else if (phy_chk(0x0141, 0x0cc0, PHYID3_Mask)) {sprintf(PHYName, "88E1111" ); if (Enable_InitPHY) phy_marvell (loop_phy);}//88E1111 1G/100/10M GMII, MII, RGMII
++ else if (phy_chk(0x001c, 0xc816, 0xffff )) {sprintf(PHYName, "RTL8201F" ); if (Enable_InitPHY) phy_realtek4 (loop_phy);}//RTL8201F 100/10M MII, RMII
++ else if (phy_chk(0x001c, 0xc815, 0xfff0 )) {sprintf(PHYName, "RTL8201E" ); if (Enable_InitPHY) phy_realtek0 (loop_phy);}//RTL8201E 100/10M MII, RMII(RTL8201E(L)-VC only)
++ else if (phy_chk(0x001c, 0xc912, 0xffff )) {sprintf(PHYName, "RTL8211C" ); if (Enable_InitPHY) phy_realtek3 (loop_phy);}//RTL8211C 1G/100/10M RGMII
++ else if (phy_chk(0x001c, 0xc914, 0xffff )) {sprintf(PHYName, "RTL8211D" ); if (Enable_InitPHY) phy_realtek1 (loop_phy);}//RTL8211D 1G/100/10M GMII(RTL8211DN/RTL8211DG only), MII(RTL8211DN/RTL8211DG only), RGMII
++ else if (phy_chk(0x001c, 0xc915, 0xffff )) {sprintf(PHYName, "RTL8211E" ); if (Enable_InitPHY) phy_realtek2 (loop_phy);}//RTL8211E 1G/100/10M GMII(RTL8211EG only), RGMII
++ else if (phy_chk(0x0000, 0x8201, PHYID3_Mask)) {sprintf(PHYName, "RTL8201N" ); if (Enable_InitPHY) phy_realtek (loop_phy);}//RTL8201N 100/10M MII, RMII
++ else if (phy_chk(0x0007, 0xc0c4, PHYID3_Mask)) {sprintf(PHYName, "LAN8700" ); if (Enable_InitPHY) phy_smsc (loop_phy);}//LAN8700 100/10M MII, RMII
++ else if (phy_chk(0x0022, 0x1555, 0xfff0 )) {sprintf(PHYName, "KSZ8031/KSZ8051" ); if (Enable_InitPHY) phy_micrel0 (loop_phy);}//KSZ8051/KSZ8031 100/10M RMII
++ else if (phy_chk(0x0022, 0x1560, 0xfff0 )) {sprintf(PHYName, "KSZ8081" ); if (Enable_InitPHY) phy_micrel0 (loop_phy);}//KSZ8081 100/10M RMII
++ else if (phy_chk(0x0022, 0x1512, 0xfff0 )) {sprintf(PHYName, "KSZ8041" ); if (Enable_InitPHY) phy_micrel (loop_phy);}//KSZ8041 100/10M RMII
++ else if (phy_chk(0x0007, 0x0421, 0xfff0 )) {sprintf(PHYName, "VSC8601" ); if (Enable_InitPHY) phy_vitesse (loop_phy);}//VSC8601 1G/100/10M RGMII
++ else {sprintf(PHYName, "default" ); if (Enable_InitPHY) phy_default (loop_phy);}//
++}
++
++//------------------------------------------------------------
++void recov_phy (int loop_phy) {
++ #ifdef DbgPrn_FuncHeader
++ printf ("recov_phy\n");
++ Debug_delay();
++ #endif
++
++ if (phy_chk(0x0362, 0x5e6a, 0xfff0 )) recov_phy_broadcom0(loop_phy);//BCM54612 1G/100/10M RGMII
++ else if (phy_chk(0x0362, 0x5d10, 0xfff0 )) recov_phy_broadcom0(loop_phy);//BCM54616A 1G/100/10M RGMII
++ else if (phy_chk(0x0141, 0x0dd0, 0xfff0 )) recov_phy_marvell2 (loop_phy);//88E1512 1G/100/10M RGMII
++ else if (phy_chk(0xff00, 0x1761, 0xffff )) recov_phy_marvell1 (loop_phy);//88E6176 1G/100/10M 2 RGMII Switch
++ else if (phy_chk(0x0141, 0x0e90, 0xfff0 )) recov_phy_marvell0 (loop_phy);//88E1310 1G/100/10M RGMII
++ else if (phy_chk(0x0141, 0x0cc0, PHYID3_Mask)) recov_phy_marvell (loop_phy);//88E1111 1G/100/10M GMII, MII, RGMII
++ else if (phy_chk(0x001c, 0xc914, 0xffff )) recov_phy_realtek1 (loop_phy);//RTL8211D 1G/100/10M GMII(RTL8211DN/RTL8211DG only), MII(RTL8211DN/RTL8211DG only), RGMII
++ else if (phy_chk(0x001c, 0xc915, 0xffff )) recov_phy_realtek2 (loop_phy);//RTL8211E 1G/100/10M GMII(RTL8211EG only), RGMII
++ else if (phy_chk(0x001c, 0xc912, 0xffff )) recov_phy_realtek3 (loop_phy);//RTL8211C 1G/100/10M RGMII
++ else if (phy_chk(0x0007, 0x0421, 0xfff0 )) recov_phy_vitesse (loop_phy);//VSC8601 1G/100/10M RGMII
++}
++
++//------------------------------------------------------------
++void init_phy (int loop_phy) {
++ #ifdef DbgPrn_FuncHeader
++ printf ("init_phy\n");
++ Debug_delay();
++ #endif
++
++ sprintf( PHYID, "PHY%d", SelectMAC + 1 );
++
++ if ( DbgPrn_PHYInit )
++ phy_dump( PHYID );
++
++ if ( find_phyadr() == TRUE )
++ phy_sel( loop_phy );
++
++ if ( DbgPrn_PHYInit )
++ phy_dump( PHYID );
++}
++
++
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/PLLTESTU.H b/arch/arm/cpu/arm926ejs/aspeed/PLLTESTU.H
+new file mode 100644
+index 0000000..6fa96e6
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/PLLTESTU.H
+@@ -0,0 +1,50 @@
++/*
++ * 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 PLLTESTU_H
++#define PLLTESTU_H
++
++//PLL Mode Definition
++#define NAND_PLLMODE 0x00
++#define DELAY_PLLMODE 0x04
++#define PCI_PLLMODE 0x08
++#define DPLL_PLLMODE 0x2c
++#define MPLL_PLLMODE 0x10
++#define HPLL_PLLMODE 0x14
++#define LPC_PLLMODE 0x18
++#define VIDEOA_PLLMODE 0x1c
++#define D2PLL_PLLMODE 0x0c
++#define VIDEOB_PLLMODE 0x3c
++
++#define PCI_PLLMODE_AST1160 0x10
++#define MPLL_PLLMODE_AST1160 0x14
++#define HPLL_PLLMODE_AST1160 0x14
++#define DPLL_PLLMODE_AST1160 0x1c
++
++#define PCI_PLLMODE_AST2300 0x2c
++#define MPLL_PLLMODE_AST2300 0x10
++#define HPLL_PLLMODE_AST2300 0x30
++#define DPLL_PLLMODE_AST2300 0x08
++#define DEL0_PLLMODE_AST2300 0x00
++
++#define ERR_FATAL 0x00000001
++
++typedef struct _VGAINFO {
++ USHORT usDeviceID;
++ UCHAR jRevision;
++
++ ULONG ulMCLK;
++ ULONG ulDRAMBusWidth;
++
++ ULONG ulCPUCLK;
++ ULONG ulAHBCLK;
++} _VGAInfo;
++
++#endif // End PLLTESTU_H
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/PLLTESTU.c b/arch/arm/cpu/arm926ejs/aspeed/PLLTESTU.c
+new file mode 100644
+index 0000000..95958b0
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/PLLTESTU.c
+@@ -0,0 +1,411 @@
++/*
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#define PLLTEST_C
++static const char ThisFile[] = "PLLTEST.c";
++
++#include "SWFUNC.H"
++
++#include <COMMINF.H>
++#include <STDUBOOT.H>
++#include <TYPEDEF.H>
++#include <IO.H>
++#include <PLLTESTU.H>
++
++/*
++ * static
++ */
++static UCHAR jVersion[] = "v.0.57.00";
++
++void print_usage( void )
++{
++ printf(" PLLTest [pll mode] [err rate]\n");
++ printf(" [pll mode] h-pll: ARM CPU Clock PLL\n");
++ printf(" m-pll: Memory Clock PLL\n");
++ printf(" [err rate] Error Rate: unit %\n");
++ printf(" default is 1%\n");
++}
++
++BOOL CompareToRing(_VGAInfo *VGAInfo, ULONG ulPLLMode, ULONG ulDCLK, ULONG ulErrRate)
++{
++ ULONG ulCounter, ulLowLimit, ulHighLimit;
++ ULONG ulData, ulValue, ulDiv;
++ ULONG ulSCUBase;
++ double del0;
++ ULONG uldel0;
++
++ if ((VGAInfo->usDeviceID == 0x1160) || (VGAInfo->usDeviceID == 0x1180))
++ ulSCUBase = 0x80fc8200;
++ else
++ ulSCUBase = 0x1e6e2000;
++
++ //Fixed AST2300 H-PLL can't Get Correct Value in VGA only mode, ycchen@081711
++ if ( (VGAInfo->jRevision >= 0x20) && (ulPLLMode == HPLL_PLLMODE_AST2300) )
++ {
++ WriteSOC_DD(ulSCUBase, 0x1688a8a8);
++ ulData = ReadSOC_DD(ulSCUBase + 0x08);
++ WriteSOC_DD(ulSCUBase + 0x08, ulData & 0xFFFFFF00);
++ }
++
++ ulCounter = (ulDCLK/1000) * 512 / 24000 - 1;
++ ulLowLimit = ulCounter * (100 - ulErrRate) / 100;
++ ulHighLimit = ulCounter * (100 + ulErrRate) / 100;
++
++ DELAY(10);
++ WriteSOC_DD(ulSCUBase, 0x1688a8a8);
++ WriteSOC_DD(ulSCUBase + 0x28, (ulHighLimit << 16) | ulLowLimit);
++ WriteSOC_DD(ulSCUBase + 0x10, ulPLLMode);
++ WriteSOC_DD(ulSCUBase + 0x10, ulPLLMode | 0x03);
++ DELAY(1);
++ do {
++ ulData = ReadSOC_DD(ulSCUBase + 0x10);
++ } while (!(ulData & 0x40));
++ ulValue = ReadSOC_DD(ulSCUBase + 0x14);
++
++ //Patch for AST1160/1180 DCLK calculate
++ if ( ((VGAInfo->usDeviceID == 0x1160) || (VGAInfo->usDeviceID == 0x1180)) && (ulPLLMode == DPLL_PLLMODE_AST1160) )
++ {
++ ulData = ReadSOC_DD(0x80fc906c);
++ ulDiv = ulData & 0x000c0000;
++ ulDiv >>= 18;
++ ulDiv++;
++ ulValue /= ulDiv;
++ }
++
++ if ( (VGAInfo->jRevision >= 0x20) && (ulPLLMode == DEL0_PLLMODE_AST2300) )
++ {
++ del0 = (double)(24.0 * (ulValue + 1) / 512.0);
++ del0 = 1000/del0/16/8;
++ uldel0 = (ULONG) (del0 * 1000000);
++ if (uldel0 < ulDCLK)
++ {
++ printf( "[PASS][DEL0] Actual DEL0:%f ns, Max. DEL0:%f ns \n", del0, (double)ulDCLK/1000000);
++ ulData |= 0x80;
++ }
++ else
++ {
++ printf( "[ERROR][DEL0] Actual DEL0:%f ns, Max. DEL0:%f ns \n", del0, (double)ulDCLK/1000000);
++ ulData == 0x00;
++ }
++ }
++ else
++ {
++ printf( "[INFO] PLL Predict Count = %x, Actual Count = %x \n", ulCounter, ulValue);
++ }
++
++ WriteSOC_DD(ulSCUBase + 0x10, 0x2C); //disable ring
++
++ if (ulData & 0x80)
++ return (TRUE);
++ else
++ return(FALSE);
++} /* CompareToRing */
++
++VOID GetDRAMInfo(_VGAInfo *VGAInfo)
++{
++ ULONG ulData, ulData2;
++ ULONG ulRefPLL, ulDeNumerator, ulNumerator, ulDivider, ulOD;
++
++ if (VGAInfo->jRevision >= 0x10)
++ {
++ WriteSOC_DD(0x1e6e2000, 0x1688A8A8);
++
++ //Get DRAM Bus Width
++ ulData = ReadSOC_DD(0x1e6e0004);
++ if (ulData & 0x40)
++ VGAInfo->ulDRAMBusWidth = 16;
++ else
++ VGAInfo->ulDRAMBusWidth = 32;
++
++ ulRefPLL = 24000;
++ if (VGAInfo->jRevision >= 0x30) //AST2400
++ {
++ ulData = ReadSOC_DD(0x1e6e2070);
++ if (ulData & 0x00800000) //D[23] = 1
++ ulRefPLL = 25000;
++ }
++
++ ulData = ReadSOC_DD(0x1e6e2020);
++ ulDeNumerator = ulData & 0x0F;
++ ulNumerator = (ulData & 0x07E0) >> 5;
++ ulOD = (ulData & 0x10) ? 1:2;
++
++ ulData = (ulData & 0x7000) >> 12;
++ switch (ulData)
++ {
++ case 0x07:
++ ulDivider = 16;
++ break;
++ case 0x06:
++ ulDivider = 8;
++ break;
++ case 0x05:
++ ulDivider = 4;
++ break;
++ case 0x04:
++ ulDivider = 2;
++ break;
++ default:
++ ulDivider = 0x01;
++ }
++
++ VGAInfo->ulMCLK = ulRefPLL * ulOD * (ulNumerator + 2) / ((ulDeNumerator + 1) * ulDivider * 1000);
++ }
++} // GetDRAMInfo
++
++VOID GetCLKInfo( _VGAInfo *VGAInfo)
++{
++ ULONG ulData, ulCPUTrap, ulAHBTrap;
++ ULONG ulRefPLL, ulDeNumerator, ulNumerator, ulDivider, ulOD;
++
++ if (VGAInfo->jRevision >= 0x30)
++ {
++ WriteSOC_DD(0x1e6e2000, 0x1688a8a8);
++ ulData = ReadSOC_DD(0x1e6e2024);
++ if (ulData & 0x40000) //from H-PLL
++ {
++ ulRefPLL = 24000;
++ ulData = ReadSOC_DD(0x1e6e2070);
++ if (ulData & 0x00800000) //D[23] = 1
++ ulRefPLL = 25000;
++
++ ulData = ReadSOC_DD(0x1e6e2024);
++
++ ulDeNumerator = ulData & 0x0F;
++ ulNumerator = (ulData & 0x07E0) >> 5;
++ ulOD = (ulData & 0x10) ? 1:2;
++
++ VGAInfo->ulCPUCLK = ulRefPLL * ulOD * (ulNumerator + 2) / ((ulDeNumerator + 1) * 1000);
++
++ }
++ else //from trapping
++ {
++ ulRefPLL = 24;
++ ulData = ReadSOC_DD(0x1e6e2070);
++ if (ulData & 0x00800000) //D[23] = 1
++ ulRefPLL = 25;
++
++ ulCPUTrap = ulData & 0x0300;
++ ulCPUTrap >>= 8;
++
++ switch (ulCPUTrap)
++ {
++ case 0x00:
++ VGAInfo->ulCPUCLK = ulRefPLL * 16;
++ break;
++ case 0x01:
++ VGAInfo->ulCPUCLK = ulRefPLL * 15;
++ break;
++ case 0x02:
++ VGAInfo->ulCPUCLK = ulRefPLL * 14;
++ break;
++ case 0x03:
++ VGAInfo->ulCPUCLK = ulRefPLL * 17;
++ break;
++ }
++
++ }
++
++ ulData = ReadSOC_DD(0x1e6e2070);
++ ulAHBTrap = ulData & 0x0c00;
++ ulAHBTrap >>= 10;
++ switch (ulAHBTrap)
++ {
++ case 0x00:
++ VGAInfo->ulAHBCLK = VGAInfo->ulCPUCLK;
++ break;
++ case 0x01:
++ VGAInfo->ulAHBCLK = VGAInfo->ulCPUCLK / 2;
++ break;
++ case 0x02:
++ VGAInfo->ulAHBCLK = VGAInfo->ulCPUCLK / 4;
++ break;
++ case 0x03:
++ VGAInfo->ulAHBCLK = VGAInfo->ulCPUCLK / 3;
++ break;
++ }
++
++ } //AST2400
++ else if (VGAInfo->jRevision >= 0x20)
++ {
++ WriteSOC_DD(0x1e6e2000, 0x1688a8a8);
++ ulData = ReadSOC_DD(0x1e6e2024);
++ if (ulData & 0x40000) //from H-PLL
++ {
++ ulRefPLL = 24000;
++
++ ulData = ReadSOC_DD(0x1e6e2024);
++
++ ulDeNumerator = ulData & 0x0F;
++ ulNumerator = (ulData & 0x07E0) >> 5;
++ ulOD = (ulData & 0x10) ? 1:2;
++
++ VGAInfo->ulCPUCLK = ulRefPLL * ulOD * (ulNumerator + 2) / ((ulDeNumerator + 1) * 1000);
++
++ }
++ else //from trapping
++ {
++ ulData = ReadSOC_DD(0x1e6e2070);
++ ulCPUTrap = ulData & 0x0300;
++ ulCPUTrap >>= 8;
++
++ switch (ulCPUTrap)
++ {
++ case 0x00:
++ VGAInfo->ulCPUCLK = 384;
++ break;
++ case 0x01:
++ VGAInfo->ulCPUCLK = 360;
++ break;
++ case 0x02:
++ VGAInfo->ulCPUCLK = 336;
++ break;
++ case 0x03:
++ VGAInfo->ulCPUCLK = 408;
++ break;
++ }
++
++ }
++
++ ulData = ReadSOC_DD(0x1e6e2070);
++ ulAHBTrap = ulData & 0x0c00;
++ ulAHBTrap >>= 10;
++ switch (ulAHBTrap)
++ {
++ case 0x00:
++ VGAInfo->ulAHBCLK = VGAInfo->ulCPUCLK;
++ break;
++ case 0x01:
++ VGAInfo->ulAHBCLK = VGAInfo->ulCPUCLK / 2;
++ break;
++ case 0x02:
++ VGAInfo->ulAHBCLK = VGAInfo->ulCPUCLK / 4;
++ break;
++ case 0x03:
++ VGAInfo->ulAHBCLK = VGAInfo->ulCPUCLK / 3;
++ break;
++ }
++
++ } //AST2300
++} // GetCLKInfo
++
++int pll_function(int argc, char *argv[])
++{
++ _VGAInfo *pVGAInfo;
++ ULONG ulErrRate = 1;
++ ULONG PLLMode;
++ ULONG RefClk;
++ CHAR *stop_at;
++ CHAR i;
++
++ printf("**************************************************** \n");
++ printf("*** ASPEED Graphics PLL Test %s Log *** \n", jVersion);
++ printf("*** for u-boot *** \n");
++ printf("**************************************************** \n");
++ printf("\n");
++
++ // Check chip type
++ switch ( ReadSOC_DD( 0x1e6e2000 + 0x7c ) ) {
++ case 0x02010303 :
++ case 0x02000303 :
++ printf("The chip is AST2400\n" );
++ pVGAInfo->usDeviceID = 0x2400;
++ pVGAInfo->jRevision = 0x30;
++ break;
++
++ case 0x02010103 :
++ case 0x02000003 :
++ printf("The chip is AST1400\n" );
++ pVGAInfo->usDeviceID = 0x1400;
++ pVGAInfo->jRevision = 0x30;
++ break;
++
++ case 0x01010303 :
++ case 0x01000003 :
++ printf("The chip is AST2300\n" );
++ pVGAInfo->usDeviceID = 0x2300;
++ pVGAInfo->jRevision = 0x20;
++ break;
++
++ case 0x01010203 :
++ printf("The chip is AST1050\n" );
++ pVGAInfo->usDeviceID = 0x1050;
++ pVGAInfo->jRevision = 0x20;
++ break;
++
++ default :
++ printf ("Error Silicon Revision ID(SCU7C) %08lx!!!\n", ReadSOC_DD( 0x1e6e2000 + 0x7c ) );
++ return(1);
++ }
++
++
++ GetDRAMInfo( pVGAInfo );
++ GetCLKInfo( pVGAInfo );
++
++ if ( ( argc <= 1 ) || ( argc >= 4 ) ){
++ print_usage();
++ return (ERR_FATAL);
++ }
++ else {
++ for ( i = 1; i < argc; i++ ) {
++ switch ( i ) {
++ case 1:
++ if (!strcmp(argv[i], "m-pll"))
++ {
++ if (pVGAInfo->jRevision >= 0x20)
++ PLLMode = MPLL_PLLMODE_AST2300;
++ else
++ PLLMode = MPLL_PLLMODE;
++
++ RefClk = pVGAInfo->ulMCLK * 1000000;
++ if (pVGAInfo->jRevision >= 0x20) //dual-edge
++ RefClk /= 2;
++ }
++ else if (!strcmp(argv[i], "h-pll"))
++ {
++ if (pVGAInfo->jRevision >= 0x20)
++ PLLMode = HPLL_PLLMODE_AST2300;
++ else
++ PLLMode = HPLL_PLLMODE;
++
++ //AST2300 only has HCLK ring test mode, ycchen@040512
++ RefClk = pVGAInfo->ulCPUCLK * 1000000; //Other : H-PLL
++ if (pVGAInfo->jRevision >= 0x20) //AST2300: HCLK
++ RefClk = pVGAInfo->ulAHBCLK * 1000000;
++ }
++ else {
++ print_usage();
++ return (ERR_FATAL);
++ }
++ break;
++ case 2:
++ ulErrRate = (ULONG) strtoul(argv[i], &stop_at, 10);
++
++ break;
++ default:
++ break;
++ } // End switch()
++ } // End for
++ }
++
++ /* Compare ring */
++ if (CompareToRing(pVGAInfo, PLLMode, RefClk, ulErrRate ) == TRUE)
++ {
++ printf("[PASS] %s PLL Check Pass!! \n", argv[1]);
++ return 0;
++ }
++ else
++ {
++ printf("[ERROR] %s PLL Check Failed!! \n", argv[1]);
++ return (ERR_FATAL);
++ }
++}
++
++
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/SPIM.c b/arch/arm/cpu/arm926ejs/aspeed/SPIM.c
+new file mode 100644
+index 0000000..e1bdd07
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/SPIM.c
+@@ -0,0 +1,63 @@
++/*
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#define SPIM_C
++static const char ThisFile[] = "SPIM.c";
++
++#include "SWFUNC.H"
++
++#ifdef SPI_BUS
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <conio.h>
++#include <string.h>
++#include "TYPEDEF.H"
++#include "LIB_SPI.H"
++
++#define SPIM_CMD_WHA 0x01
++#define SPIM_CMD_RD 0x0B
++#define SPIM_CMD_DRD 0xBB
++#define SPIM_CMD_WR 0x02
++#define SPIM_CMD_DWR 0xD2
++#define SPIM_CMD_STA 0x05
++#define SPIM_CMD_ENBYTE 0x06
++#define SPIM_CMD_DISBYTE 0x04
++
++ULONG spim_cs;
++ULONG spim_base;
++ULONG spim_hadr;
++
++void spim_end()
++{
++ ULONG data;
++
++ data = MIndwm((ULONG)mmiobase, 0x1E620010 + (spim_cs << 2));
++ MOutdwm( (ULONG)mmiobase, 0x1E620010 + (spim_cs << 2), data | 0x4);
++ MOutdwm( (ULONG)mmiobase, 0x1E620010 + (spim_cs << 2), data);
++}
++
++//------------------------------------------------------------
++void spim_init(int cs)
++{
++ ULONG data;
++
++ spim_cs = cs;
++ MOutdwm( (ULONG)mmiobase, 0x1E620000, (0x2 << (cs << 1)) | (0x10000 << cs));
++ MOutdwm( (ULONG)mmiobase, 0x1E620010 + (cs << 2), 0x00000007);
++ MOutdwm( (ULONG)mmiobase, 0x1E620010 + (cs << 2), 0x00002003);
++ MOutdwm( (ULONG)mmiobase, 0x1E620004, 0x100 << cs);
++ data = MIndwm((ULONG)mmiobase, 0x1E620030 + (cs << 2));
++ spim_base = 0x20000000 | ((data & 0x007f0000) << 7);
++ MOutwm ( (ULONG)mmiobase, spim_base, SPIM_CMD_WHA);
++ spim_end();
++ spim_hadr = 0;
++}
++#endif // End SPI_BUS
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/STDUBOOT.H b/arch/arm/cpu/arm926ejs/aspeed/STDUBOOT.H
+new file mode 100644
+index 0000000..7fbf590
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/STDUBOOT.H
+@@ -0,0 +1,18 @@
++/*
++ * 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 STDUBOOT_H
++#define STDUBOOT_H
++
++unsigned long int strtoul(char *string, char **endPtr, int base);
++int atoi( char s[] );
++int rand(void);
++
++#endif // End STDUBOOT_H
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/STDUBOOT.c b/arch/arm/cpu/arm926ejs/aspeed/STDUBOOT.c
+new file mode 100644
+index 0000000..90e2997
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/STDUBOOT.c
+@@ -0,0 +1,235 @@
++/*
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#define STDUBOOT_C
++static const char ThisFile[] = "STDUBOOT.c";
++
++#include "SWFUNC.H"
++
++#ifdef SLT_UBOOT
++
++int isspace ( char c )
++{
++ if ( ( c == ' ' ) || ( c == 9 ) || ( c == 13 ) )
++ return 1;
++
++ return 0;
++}
++
++/*
++ * strtoul.c --
++ *
++ * Source code for the "strtoul" library procedure.
++ *
++ * Copyright 1988 Regents of the University of California
++ * Permission to use, copy, modify, and distribute this
++ * software and its documentation for any purpose and without
++ * fee is hereby granted, provided that the above copyright
++ * notice appear in all copies. The University of California
++ * makes no representations about the suitability of this
++ * software for any purpose. It is provided "as is" without
++ * express or implied warranty.
++ */
++
++//#include <ctype.h>
++
++/*
++ * The table below is used to convert from ASCII digits to a
++ * numerical equivalent. It maps from '0' through 'z' to integers
++ * (100 for non-digit characters).
++ */
++
++static char cvtIn[] = {
++ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* '0' - '9' */
++ 100, 100, 100, 100, 100, 100, 100, /* punctuation */
++ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, /* 'A' - 'Z' */
++ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
++ 30, 31, 32, 33, 34, 35,
++ 100, 100, 100, 100, 100, 100, /* punctuation */
++ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, /* 'a' - 'z' */
++ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
++ 30, 31, 32, 33, 34, 35};
++
++/*
++ *----------------------------------------------------------------------
++ *
++ * strtoul --
++ *
++ * Convert an ASCII string into an integer.
++ *
++ * Results:
++ * The return value is the integer equivalent of string. If endPtr
++ * is non-NULL, then *endPtr is filled in with the character
++ * after the last one that was part of the integer. If string
++ * doesn't contain a valid integer value, then zero is returned
++ * and *endPtr is set to string.
++ *
++ * Side effects:
++ * None.
++ *
++ *----------------------------------------------------------------------
++ */
++
++unsigned long int
++strtoul(char *string, char **endPtr, int base)
++ /* string; String of ASCII digits, possibly
++ * preceded by white space. For bases
++ * greater than 10, either lower- or
++ * upper-case digits may be used.
++ */
++ /* **endPtr; Where to store address of terminating
++ * character, or NULL. */
++ /* base; Base for conversion. Must be less
++ * than 37. If 0, then the base is chosen
++ * from the leading characters of string:
++ * "0x" means hex, "0" means octal, anything
++ * else means decimal.
++ */
++{
++ register char *p;
++ register unsigned long int result = 0;
++ register unsigned digit;
++ int anyDigits = 0;
++
++ /*
++ * Skip any leading blanks.
++ */
++
++ p = string;
++ while (isspace(*p)) {
++ p += 1;
++ }
++
++ /*
++ * If no base was provided, pick one from the leading characters
++ * of the string.
++ */
++
++ if (base == 0)
++ {
++ if (*p == '0') {
++ p += 1;
++ if (*p == 'x') {
++ p += 1;
++ base = 16;
++ } else {
++
++ /*
++ * Must set anyDigits here, otherwise "0" produces a
++ * "no digits" error.
++ */
++
++ anyDigits = 1;
++ base = 8;
++ }
++ }
++ else base = 10;
++ } else if (base == 16) {
++
++ /*
++ * Skip a leading "0x" from hex numbers.
++ */
++
++ if ((p[0] == '0') && (p[1] == 'x')) {
++ p += 2;
++ }
++ }
++
++ /*
++ * Sorry this code is so messy, but speed seems important. Do
++ * different things for base 8, 10, 16, and other.
++ */
++
++ if (base == 8) {
++ for ( ; ; p += 1) {
++ digit = *p - '0';
++ if (digit > 7) {
++ break;
++ }
++ result = (result << 3) + digit;
++ anyDigits = 1;
++ }
++ } else if (base == 10) {
++ for ( ; ; p += 1) {
++ digit = *p - '0';
++ if (digit > 9) {
++ break;
++ }
++ result = (10*result) + digit;
++ anyDigits = 1;
++ }
++ } else if (base == 16) {
++ for ( ; ; p += 1) {
++ digit = *p - '0';
++ if (digit > ('z' - '0')) {
++ break;
++ }
++ digit = cvtIn[digit];
++ if (digit > 15) {
++ break;
++ }
++ result = (result << 4) + digit;
++ anyDigits = 1;
++ }
++ } else {
++ for ( ; ; p += 1) {
++ digit = *p - '0';
++ if (digit > ('z' - '0')) {
++ break;
++ }
++ digit = cvtIn[digit];
++ if (digit >= base) {
++ break;
++ }
++ result = result*base + digit;
++ anyDigits = 1;
++ }
++ }
++
++ /*
++ * See if there were any digits at all.
++ */
++
++ if (!anyDigits) {
++ p = string;
++ }
++
++ if (endPtr != 0) {
++ *endPtr = p;
++ }
++
++ return result;
++}
++
++// -----------------------------------------------------------------------------
++int atoi( char s[] )
++{
++
++ int i;
++ int ans = 0;
++
++ for( i = 0; s[i] >= '0' && s[i] <= '9'; ++i )
++ ans = ( 10 * ans ) + ( s[i] - '0' );
++
++ return ans;
++}
++
++// -----------------------------------------------------------------------------
++/* rand:return pseudo-random integer on 0...32767 */
++int rand(void)
++{
++ static unsigned long int next = 1;
++
++ next = next * 1103515245 + 12345;
++
++ return (unsigned int) ( next / 65536 ) % 32768;
++}
++
++#endif // End SLT_UBOOT
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/STRESS.c b/arch/arm/cpu/arm926ejs/aspeed/STRESS.c
+new file mode 100644
+index 0000000..dffd64f
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/STRESS.c
+@@ -0,0 +1,145 @@
++/*
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#define STRESS_C
++static const char ThisFile[] = "STRESS.c";
++
++#include "SWFUNC.H"
++#include <COMMINF.H>
++#include <IO.H>
++
++#define TIMEOUT_DRAM 5000000
++
++/* ------------------------------------------------------------------------- */
++int MMCTestBurst(unsigned int datagen)
++{
++ unsigned int data;
++ unsigned int timeout = 0;
++
++ WriteSOC_DD( 0x1E6E0070, 0x00000000 );
++ WriteSOC_DD( 0x1E6E0070, (0x000000C1 | (datagen << 3)) );
++
++ do {
++ data = ReadSOC_DD( 0x1E6E0070 ) & 0x3000;
++
++ if( data & 0x2000 )
++ return(0);
++
++ if( ++timeout > TIMEOUT_DRAM ) {
++ printf("Timeout!!\n");
++ WriteSOC_DD( 0x1E6E0070, 0x00000000 );
++
++ return(0);
++ }
++ } while( !data );
++ WriteSOC_DD( 0x1E6E0070, 0x00000000 );
++
++ return(1);
++}
++
++/* ------------------------------------------------------------------------- */
++int MMCTestSingle(unsigned int datagen)
++{
++ unsigned int data;
++ unsigned int timeout = 0;
++
++ WriteSOC_DD( 0x1E6E0070, 0x00000000 );
++ WriteSOC_DD( 0x1E6E0070, (0x00000085 | (datagen << 3)) );
++
++ do {
++ data = ReadSOC_DD( 0x1E6E0070 ) & 0x3000;
++
++ if( data & 0x2000 )
++ return(0);
++
++ if( ++timeout > TIMEOUT_DRAM ){
++ printf("Timeout!!\n");
++ WriteSOC_DD( 0x1E6E0070, 0x00000000 );
++
++ return(0);
++ }
++ } while ( !data );
++ WriteSOC_DD( 0x1E6E0070, 0x00000000 );
++
++ return(1);
++}
++
++/* ------------------------------------------------------------------------- */
++int MMCTest()
++{
++ unsigned int pattern;
++
++ pattern = ReadSOC_DD( 0x1E6E2078 );
++ printf("Pattern = %08X : ",pattern);
++
++ WriteSOC_DD(0x1E6E0074, (DRAM_MapAdr | 0x7fffff) );
++ WriteSOC_DD(0x1E6E007C, pattern );
++
++ if(!MMCTestBurst(0)) return(0);
++ if(!MMCTestBurst(1)) return(0);
++ if(!MMCTestBurst(2)) return(0);
++ if(!MMCTestBurst(3)) return(0);
++ if(!MMCTestBurst(4)) return(0);
++ if(!MMCTestBurst(5)) return(0);
++ if(!MMCTestBurst(6)) return(0);
++ if(!MMCTestBurst(7)) return(0);
++ if(!MMCTestSingle(0)) return(0);
++ if(!MMCTestSingle(1)) return(0);
++ if(!MMCTestSingle(2)) return(0);
++ if(!MMCTestSingle(3)) return(0);
++ if(!MMCTestSingle(4)) return(0);
++ if(!MMCTestSingle(5)) return(0);
++ if(!MMCTestSingle(6)) return(0);
++ if(!MMCTestSingle(7)) return(0);
++
++ return(1);
++}
++
++/* ------------------------------------------------------------------------- */
++int dram_stress_function(int argc, char *argv[])
++{
++ unsigned int Pass;
++ unsigned int PassCnt = 0;
++ unsigned int Testcounter = 0;
++ int ret = 1;
++ char *stop_at;
++
++ printf("**************************************************** \n");
++ printf("*** ASPEED Stress DRAM *** \n");
++ printf("*** 20131107 for u-boot *** \n");
++ printf("**************************************************** \n");
++ printf("\n");
++
++ if ( argc != 2 ){
++ ret = 0;
++ return ( ret );
++ }
++ else {
++ Testcounter = (unsigned int) strtoul(argv[1], &stop_at, 10);
++ }
++
++ WriteSOC_DD(0x1E6E0000, 0xFC600309);
++
++ while( ( Testcounter > PassCnt ) || ( Testcounter == 0 ) ){
++ if( !MMCTest() ) {
++ printf("FAIL...%d/%d\n", PassCnt, Testcounter);
++ ret = 0;
++
++ break;
++ }
++ else {
++ PassCnt++;
++ printf("Pass %d/%d\n", PassCnt, Testcounter);
++ }
++ } // End while()
++
++ return( ret );
++}
++
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/SWFUNC.H b/arch/arm/cpu/arm926ejs/aspeed/SWFUNC.H
+new file mode 100644
+index 0000000..0a03654
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/SWFUNC.H
+@@ -0,0 +1,137 @@
++/*
++ * 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 SWFUNC_H
++#define SWFUNC_H
++
++
++//---------------------------------------------------------
++// Program information
++//---------------------------------------------------------
++#define VER_NAME "Ver 0.34 version @2014/03/25 0932"
++
++/* == Step 1: ====== Support OS system =================== */
++// LinuxAP
++// #define Windows
++#define SLT_UBOOT
++//#define SLT_DOS
++
++/* == Step 2:======== Support interface ================== */
++/* Choose One */
++//#define SPI_BUS
++//#define USE_LPC
++//#define USE_P2A // PCI or PCIe bus to AHB bus
++
++/* == Step 3:========== Support Chip ================== */
++//#define AST1010_CHIP
++//#define AST3200_IOMAP
++//#define FPGA
++
++#ifdef AST1010_CHIP
++ #ifdef SLT_UBOOT
++ #define AST1010_IOMAP 1
++ #endif
++ #ifdef SLT_DOS
++ #define AST1010_IOMAP 2
++
++ // AST1010 only has LPC interface
++ #undef USE_P2A
++ #undef SPI_BUS
++ #define USE_LPC
++ #endif
++#endif
++
++/* == Step 4:========== Select PHY ================== */
++//#define SUPPORT_PHY_LAN9303 // Initial PHY via I2C bus
++#define LAN9303_I2C_BUSNUM 6 // 1-based
++#define LAN9303_I2C_ADR 0x14
++
++/* ====================== Program ======================== */
++// The "PHY_NCSI" option is only for DOS compiler
++#if defined (PHY_NCSI)
++ #ifdef SLT_UBOOT
++ #error Wrong setting......
++ #endif
++#endif
++
++#if defined (PHY_NCSI)
++ #ifdef SUPPORT_PHY_LAN9303
++ #error Wrong setting (Can't support LAN9303)......
++ #endif
++#endif
++
++/* ================= Check setting ===================== */
++#ifdef SLT_UBOOT
++ #ifdef SLT_DOS
++ #error Can NOT support two OS
++ #endif
++#endif
++#ifdef SLT_DOS
++ #ifdef SLT_UBOOT
++ #error Can NOT support two OS
++ #endif
++#endif
++
++#ifdef USE_P2A
++ #ifdef SLT_UBOOT
++ #error Can NOT be set PCI bus in Uboot
++ #endif
++#endif
++#ifdef USE_LPC
++ #ifdef SLT_UBOOT
++ #error Can NOT be set LPC bus in Uboot
++ #endif
++#endif
++#ifdef SPI_BUS
++ #ifdef SLT_UBOOT
++ #error Can NOT be set SPI bus in Uboot
++ #endif
++#endif
++
++/* ======================== Program flow control ======================== */
++#define RUN_STEP 5
++// 0: read_scu
++// 1: parameter setup
++// 2: init_scu1,
++// 3: init_scu_macrst
++// 4: Data Initial
++// 5: ALL
++
++/* ====================== Switch print debug message ====================== */
++#define DbgPrn_Enable_Debug_delay 0
++//#define DbgPrn_FuncHeader 0 //1
++#define DbgPrn_ErrFlg 0
++#define DbgPrn_BufAdr 0 //1
++#define DbgPrn_Bufdat 0
++#define DbgPrn_BufdatDetail 0
++#define DbgPrn_PHYRW 0
++#define DbgPrn_PHYInit 0
++#define DbgPrn_PHYName 0
++#define DbgPrn_DumpMACCnt 0
++#define DbgPrn_Info 0 //1
++#define DbgPrn_FRAME_LEN 0
++
++
++/* ============ Enable or Disable Check item of the descriptor ============ */
++#define CheckRxOwn
++#define CheckRxErr
++//#define CheckOddNibble
++#define CheckCRC
++#define CheckRxFIFOFull
++#define CheckRxLen
++//#define CheckDataEveryTime
++
++//#define CheckRxbufUNAVA
++#define CheckRPktLost
++//#define CheckNPTxbufUNAVA
++#define CheckTPktLost
++#define CheckRxBuf
++
++#endif // SWFUNC_H
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/TRAPTEST.c b/arch/arm/cpu/arm926ejs/aspeed/TRAPTEST.c
+new file mode 100644
+index 0000000..72936c0
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/TRAPTEST.c
+@@ -0,0 +1,151 @@
++/*
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#define PLLTEST_C
++static const char ThisFile[] = "PLLTEST.c";
++
++#include "SWFUNC.H"
++
++#include <COMMINF.H>
++#include <TYPEDEF.H>
++#include <IO.H>
++
++#define ASTCHIP_2400 0
++#define ASTCHIP_2300 1
++#define ASTCHIP_1400 2
++#define ASTCHIP_1300 3
++#define ASTCHIP_1050 4
++
++const UCHAR jVersion[] = "v.0.60.06";
++
++typedef struct _TRAPINFO {
++ USHORT CPU_clk;
++ UCHAR CPU_AHB_ratio;
++} _TrapInfo;
++
++const _TrapInfo AST_default_trap_setting[] = {
++ // CPU_clk, CPU_AHB_ratio
++ { 384, 2 }, // AST2400 or AST1250 ( ASTCHIP_2400 )
++ { 384, 2 }, // AST2300 ( ASTCHIP_2300 )
++ { 384, 0xFF }, // AST1400 ( ASTCHIP_1400 )
++ { 384, 0xFF }, // AST1300 ( ASTCHIP_1300 )
++ { 384, 2 } // AST1050 ( ASTCHIP_1050 )
++};
++
++int trap_function(int argc, char *argv[])
++{
++ UCHAR chiptype;
++ ULONG ulData, ulTemp;
++ UCHAR status = TRUE;
++ USHORT val_trap;
++
++ printf("**************************************************** \n");
++ printf("*** ASPEED Trap Test %s Log *** \n", jVersion);
++ printf("*** for u-boot *** \n");
++ printf("**************************************************** \n");
++ printf("\n");
++
++ // Check chip type
++ switch ( ReadSOC_DD( 0x1e6e2000 + 0x7c ) ) {
++ case 0x02010303 :
++ case 0x02000303 :
++ printf("The chip is AST2400 or AST1250\n" );
++ chiptype = ASTCHIP_2400;
++ break;
++
++ case 0x02010103 :
++ case 0x02000003 :
++ printf("The chip is AST1400\n" );
++ chiptype = ASTCHIP_1400;
++ break;
++
++ case 0x01010303 :
++ case 0x01000003 :
++ printf("The chip is AST2300\n" );
++ chiptype = ASTCHIP_2300;
++ break;
++
++ case 0x01010203 :
++ printf("The chip is AST1050\n" );
++ chiptype = ASTCHIP_1050;
++ break;
++
++ case 0x01010003 :
++ printf("The chip is AST1300\n" );
++ chiptype = ASTCHIP_1300;
++ break;
++
++ default :
++ printf ("Error Silicon Revision ID(SCU7C) %08lx!!!\n", ReadSOC_DD( 0x1e6e2000 + 0x7c ) );
++ return(1);
++ }
++
++ WriteSOC_DD(0x1e6e2000, 0x1688A8A8);
++ ulData = ReadSOC_DD(0x1e6e2070);
++
++ // Check CPU clock
++ ulTemp = ulData;
++ ulTemp &= 0x0300;
++ ulTemp >>= 8;
++
++ switch (ulTemp)
++ {
++ case 0x00:
++ val_trap = 384;
++ break;
++ case 0x01:
++ val_trap = 360;
++ break;
++ case 0x02:
++ val_trap = 336;
++ break;
++ case 0x03:
++ val_trap = 408;
++ break;
++ }
++
++ if (AST_default_trap_setting[chiptype].CPU_clk != val_trap)
++ {
++ printf("[ERROR] CPU CLK: Correct is %d; Real is %d \n", AST_default_trap_setting[chiptype].CPU_clk, val_trap);
++ status = FALSE;
++ }
++
++ // Check cpu_ahb_ratio
++ ulTemp = ulData;
++ ulTemp &= 0x0c00;
++ ulTemp >>= 10;
++
++ switch (ulTemp)
++ {
++ case 0x00:
++ val_trap = 1;
++ break;
++ case 0x01:
++ val_trap = 2;
++ break;
++ case 0x02:
++ val_trap = 4;
++ break;
++ case 0x03:
++ val_trap = 3;
++ break;
++ }
++
++ if (AST_default_trap_setting[chiptype].CPU_AHB_ratio != val_trap)
++ {
++ printf("[ERROR] CPU:AHB: Correct is %x:1; Real is %x:1 \n", AST_default_trap_setting[chiptype].CPU_AHB_ratio, val_trap);
++ status = FALSE;
++ }
++
++ if ( status == TRUE )
++ printf("[PASS] hardware trap for CPU clock and CPU\\AHB ratio.\n");
++
++ return status;
++}
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/TYPEDEF.H b/arch/arm/cpu/arm926ejs/aspeed/TYPEDEF.H
+new file mode 100644
+index 0000000..3053ad7
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/TYPEDEF.H
+@@ -0,0 +1,74 @@
++/*
++ * 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 TYPEDEF_H
++#define TYPEDEF_H
++
++#include "SWFUNC.H"
++
++//
++// Define
++//
++#define PCI 1
++#define PCIE 2
++#define AGP 3
++#define ACTIVE 4
++
++#if defined(LinuxAP)
++ #ifndef FLONG
++ #define FLONG unsigned long
++ #endif
++ #ifndef ULONG
++ #define ULONG unsigned long
++ #endif
++ #ifndef LONG
++ #define LONG long
++ #endif
++ #ifndef USHORT
++ #define USHORT unsigned short
++ #endif
++ #ifndef SHORT
++ #define SHORT short
++ #endif
++ #ifndef UCHAR
++ #define UCHAR unsigned char
++ #endif
++ #ifndef CHAR
++ #define CHAR char
++ #endif
++ #ifndef BYTE
++ #define BYTE unsigned char
++ #endif
++ #ifndef VOID
++ #define VOID void
++ #endif
++ #ifndef SCHAR
++ #define SCHAR signed char
++ #endif
++#else
++/* DOS Program */
++ #define VOID void
++ #define FLONG unsigned long
++ #define ULONG unsigned long
++ #define USHORT unsigned short
++ #define UCHAR unsigned char
++ #define LONG long
++ #define SHORT short
++ #define CHAR char
++ #define BYTE UCHAR
++ #define BOOL SHORT
++ #define BOOLEAN unsigned short
++ #define PULONG ULONG *
++ #define SCHAR signed char
++#endif
++ #define TRUE 1
++ #define FALSE 0
++
++#endif // TYPEDEF_H
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/mactest.c b/arch/arm/cpu/arm926ejs/aspeed/mactest.c
+new file mode 100644
+index 0000000..95bd560
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/mactest.c
+@@ -0,0 +1,1215 @@
++/*
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#define MACTEST_C
++static const char ThisFile[] = "MACTEST.c";
++
++#include "SWFUNC.H"
++
++#ifdef SLT_UBOOT
++ #include <common.h>
++ #include <command.h>
++ #include <post.h>
++ #include <malloc.h>
++ #include <net.h>
++ #include <COMMINF.H>
++ #include <STDUBOOT.H>
++ #include <IO.H>
++#else
++ #include <stdlib.h>
++ #include <string.h>
++ #include "LIB.H"
++ #include "COMMINF.H"
++ #include "IO.H"
++#endif
++
++const BYTE Val_Array[16] = {0,1, 2,3, 4,5, 6,7, 8,9, 10,11, 12,13, 14,15}; // AST2300-A1
++const BYTE Val_Array_A0[16] = {8,1, 10,3, 12,5, 14,7, 0,9, 2,11, 4,13, 6,15}; // AST2300-A0
++
++#ifdef SLT_UBOOT
++int main_function(int argc, char *argv[])
++#endif
++#ifdef SLT_DOS
++int main(int argc, char *argv[])
++#endif
++{
++ CHAR MAC2_Valid;
++ CHAR MAC_1GEn;
++ CHAR MAC1_RMII;
++ CHAR Enable_IntLoopPHY;
++ CHAR Disable_RecovPHY;
++ CHAR Force1G;
++ CHAR Force10M;
++ CHAR Force100M;
++ CHAR *stop_at;
++ ULONG IOStr_val;
++ ULONG IOStr_max;
++ ULONG IOStr_shf;
++ ULONG IOdly_val;
++ ULONG Err_Flag_allapeed;
++ int DES_LowNumber;
++ int index;
++ int i;
++ int j;
++ #ifdef Enable_NCSI_LOOP_INFINI
++ BYTE GSpeed_org[3];
++ #endif
++
++#ifdef SPI_BUS
++ VIDEO_ENGINE_INFO VideoEngineInfo;
++#else
++ // ( USE_P2A | USE_LPC )
++ UCHAR *ulMMIOLinearBaseAddress;
++#endif
++
++ #ifdef SLT_UBOOT
++ #else
++ time(&timestart);
++ #endif
++
++ // For DOS system
++ #if defined(PHY_NCSI)
++ // For DOS compiler OPEN WATCOM
++ ModeSwitch = MODE_NSCI;
++ #else
++ #ifdef SLT_DOS
++ ModeSwitch = MODE_DEDICATED;
++ #endif
++ #endif
++
++//------------------------------------------------------------
++// Argument Initial
++//------------------------------------------------------------
++ Err_Flag_allapeed = 0;
++ Err_Flag = 0;
++ Err_Flag_PrintEn = 1;
++ Loop_rl[0] = 0;
++ Loop_rl[1] = 0;
++ Loop_rl[2] = 0;
++
++//------------------------------------------------------------
++// Bus Initial
++//------------------------------------------------------------
++#if defined(LinuxAP)
++#else
++ //DOS system
++ #ifdef SPI_BUS
++ #endif
++ #ifdef USE_LPC
++
++ if ( findlpcport( 0x0d ) == 0) {
++ printf("Failed to find proper LPC port \n");
++
++ return(1);
++ }
++ open_aspeed_sio_password();
++ enable_aspeed_LDU( 0x0d );
++ #endif
++ #ifdef USE_P2A
++ // PCI bus
++ #ifdef DOS_PMODEW
++ if (CheckDOS()) return 1;
++ #endif
++
++ #ifdef DbgPrn_FuncHeader
++ printf ("Initial-MMIO\n");
++ Debug_delay();
++ #endif
++ ulPCIBaseAddress = FindPCIDevice (0x1A03, 0x2000, ACTIVE);
++ if ( ulPCIBaseAddress == 0 )
++ ulPCIBaseAddress = FindPCIDevice (0x1688, 0x2000, ACTIVE);
++ if ( ulPCIBaseAddress == 0 )
++ ulPCIBaseAddress = FindPCIDevice (0x1A03, 0x0200, ACTIVE);
++ if ( ulPCIBaseAddress == 0 )
++ ulPCIBaseAddress = FindPCIDevice (0x1A03, 0x3000, ACTIVE);
++ if ( ulPCIBaseAddress == 0 )
++ ulPCIBaseAddress = FindPCIDevice (0x1A03, 0x2010, ACTIVE);
++ if ( ulPCIBaseAddress == 0 ) {
++ printf ("Can't find device\n");
++
++ return(1);
++ }
++
++ WritePCIReg (ulPCIBaseAddress, 0x04, 0xFFFFFFFc, 0x3);
++ ulMMIOBaseAddress = ReadPCIReg (ulPCIBaseAddress, 0x14, 0xFFFF0000);
++ ulMMIOLinearBaseAddress = (UCHAR *)MapPhysicalToLinear (ulMMIOBaseAddress, 64 * 1024 * 1024);
++ #endif // #ifdef USE_P2A
++#endif // End defined(LinuxAP)
++
++#ifdef SPI_BUS
++ GetDevicePCIInfo (&VideoEngineInfo);
++ mmiobase = VideoEngineInfo.VGAPCIInfo.ulMMIOBaseAddress;
++ spim_init(SPI_CS);
++#else
++ // ( USE_P2A | USE_LPC )
++ mmiobase = ulMMIOLinearBaseAddress;
++#endif
++
++//------------------------------------------------------------
++// Check Chip Feature
++//------------------------------------------------------------
++ read_scu();
++
++ if (RUN_STEP >= 1) {
++ switch (SCU_7ch_old) {
++// case 0x02000003 : sprintf(ASTChipName, "[ ]AST3200-FPGA" ); ASTChipType = 6; AST1100 = 0; break;
++
++ case 0x03020003 : sprintf(ASTChipName, "[ ]AST1010-A2" ); ASTChipType = 5; AST1100 = 0; break;
++ case 0x03010003 : sprintf(ASTChipName, "[ ]AST1010-A1" ); ASTChipType = 5; AST1100 = 0; break;
++ case 0x03000003 : sprintf(ASTChipName, "[*]AST1010-A0" ); ASTChipType = 5; AST1100 = 0; break;
++
++ case 0x02010303 : sprintf(ASTChipName, "[*]AST2400-A1" ); ASTChipType = 4; AST1100 = 0; break;//AST2400-A1
++ case 0x02000303 : sprintf(ASTChipName, "[ ]AST2400-A0" ); ASTChipType = 4; AST1100 = 0; break;//AST2400-A0
++ case 0x02010103 : sprintf(ASTChipName, "[*]AST1400-A1" ); ASTChipType = 4; AST1100 = 0; break;//AST1400-A1
++ case 0x02000003 : sprintf(ASTChipName, "[ ]AST1400-A0" ); ASTChipType = 4; AST1100 = 0; break;//AST1400-A0
++
++ case 0x01010303 : sprintf(ASTChipName, "[*]AST2300-A1" ); ASTChipType = 3; AST1100 = 0; break;//AST2300-A1
++ case 0x01010203 : sprintf(ASTChipName, "[*]AST1050-A1" ); ASTChipType = 3; AST1100 = 0; break;//AST1050-A1
++ case 0x01010003 : sprintf(ASTChipName, "[*]AST1300-A1" ); ASTChipType = 3; AST1100 = 0; break;//AST1300-A1
++ case 0x01000003 : sprintf(ASTChipName, "[ ]AST2300-A0" ); ASTChipType = 3; AST1100 = 0; break;//AST2300-A0
++// case 0x01860003 : sprintf(ASTChipName, "[ ]AST2300-FPGA" ); ASTChipType = 3; AST1100 = 0; break;
++
++ case 0x00000102 : sprintf(ASTChipName, "[*]AST2200-A1" ); ASTChipType = 2; AST1100 = 0; break;//AST2200-A1/A0
++
++ case 0x00000302 : sprintf(ASTChipName, "[*]AST2100-A3" ); ASTChipType = 1; AST1100 = 0; break;//AST2100-A3/A2
++ case 0x00000301 : sprintf(ASTChipName, "[ ]AST2100-A1" ); ASTChipType = 1; AST1100 = 0; break;//AST2100-A1
++ case 0x00000300 : sprintf(ASTChipName, "[ ]AST2100-A0" ); ASTChipType = 1; AST1100 = 0; break;//AST2100-A0
++ case 0x00000202 : sprintf(ASTChipName, "[*]AST2050/AST1100-A3, AST2150-A1"); ASTChipType = 1; AST1100 = 1; break;//AST2050/AST1100-A3/A2 AST2150-A1/A0
++ case 0x00000201 : sprintf(ASTChipName, "[ ]AST2050/AST1100-A1" ); ASTChipType = 1; AST1100 = 1; break;//AST2050/AST1100-A1
++ case 0x00000200 : sprintf(ASTChipName, "[ ]AST2050/AST1100-A0" ); ASTChipType = 1; AST1100 = 1; break;//AST2050/AST1100-A0
++
++ default :
++ printf ("Error Silicon Revision ID(SCU7C) %08lx!!!\n", SCU_7ch_old);
++ return(1);
++ } // End switch (SCU_7ch_old)
++
++ switch (ASTChipType) {
++ case 6 : AST2300 = 1; AST2400 = 1; AST1010 = 0; AST3200 = 1; break;
++ case 5 : AST2300 = 1; AST2400 = 1; AST1010 = 1; AST3200 = 0; break;
++ case 4 : AST2300 = 1; AST2400 = 1; AST1010 = 0; AST3200 = 0; break;
++ case 3 : AST2300 = 1; AST2400 = 0; AST1010 = 0; AST3200 = 0; break;
++ default : AST2300 = 0; AST2400 = 0; AST1010 = 0; AST3200 = 0; break;
++ } // End switch (ASTChipType)
++
++ if (ASTChipType == 3) {
++#ifdef Force_Enable_MAC34
++ WriteSOC_DD( SCU_BASE + 0xf0, 0xAEED0001 ); //enable mac34
++ Enable_MAC34 = 1;
++#else
++ if (SCU_f0h_old & 0x00000001)
++ Enable_MAC34 = 1;
++ else
++ Enable_MAC34 = 0;
++#endif
++ }
++ else {
++ Enable_MAC34 = 0;
++ } // End if (ASTChipType == 3)
++
++ Setting_scu();
++
++//------------------------------------------------------------
++// Argument Input
++//------------------------------------------------------------
++ // Load default value
++ UserDVal = DEF_USER_DEF_PACKET_VAL;
++ IOTimingBund_arg = DEF_IOTIMINGBUND;
++ PHY_ADR_arg = DEF_PHY_ADR;
++ TestMode = DEF_TESTMODE;
++ LOOP_INFINI = 0;
++ LOOP_MAX_arg = 0;
++ GCtrl = ( DEF_MAC_LOOP_BACK << 6 ) | ( DEF_SKIP_CHECK_PHY << 5 ) | ( DEF_INIT_PHY << 3 );
++ GSpeed = DEF_SPEED;
++
++ // Get setting information by user
++ GRun_Mode = (BYTE)atoi(argv[1]);
++
++ if ( ModeSwitch == MODE_NSCI ) {
++ ARPNumCnt = DEF_ARPNUMCNT;
++ ChannelTolNum = DEF_CHANNEL2NUM;
++ PackageTolNum = DEF_PACKAGE2NUM;
++ GSpeed = SET_100MBPS; // In NCSI mode, we set to 100M bps
++ }
++
++ // Setting user's configuration
++ if (argc > 1) {
++ if ( ModeSwitch == MODE_NSCI )
++ switch (argc) {
++ case 7: ARPNumCnt = (ULONG)atoi(argv[6]);
++ case 6: IOTimingBund_arg = (BYTE)atoi(argv[5]);
++ case 5: TestMode = (BYTE)atoi(argv[4]);
++ case 4: ChannelTolNum = (BYTE)atoi(argv[3]);
++ case 3: PackageTolNum = (BYTE)atoi(argv[2]);
++ default: break;
++ }
++ else
++ switch (argc) {
++ case 9: UserDVal = strtoul (argv[8], &stop_at, 16);
++ case 8: IOTimingBund_arg = (BYTE)atoi(argv[7]);
++ case 7: PHY_ADR_arg = (BYTE)atoi(argv[6]);
++ case 6: TestMode = (BYTE)atoi(argv[5]);
++ case 5: strcpy(LOOP_Str, argv[4]);
++ if (!strcmp(LOOP_Str, "#")) LOOP_INFINI = 1;
++ else LOOP_MAX_arg = (ULONG)atoi(LOOP_Str);
++ case 4: GCtrl = (BYTE)atoi(argv[3]);
++ case 3: GSpeed = (BYTE)atoi(argv[2]);
++ default: break;
++ }
++
++ IOTimingBund = IOTimingBund_arg;
++ PHY_ADR = PHY_ADR_arg;
++ }
++ else {
++ // Wrong parameter
++ if ( ModeSwitch == MODE_NSCI ) {
++ if (AST2300)
++ printf ("\nNCSITEST.exe run_mode <package_num> <channel_num> <test_mode> <IO margin>\n\n");
++ else
++ printf ("\nNCSITEST.exe run_mode <package_num> <channel_num> <test_mode>\n\n");
++ PrintMode ();
++ PrintPakNUm();
++ PrintChlNUm();
++ PrintTest ();
++ if (AST2300)
++ PrintIOTimingBund ();
++ }
++ else {
++ if (AST2300)
++ printf ("\nMACTEST.exe run_mode <speed> <ctrl> <loop_max> <test_mode> <phy_adr> <IO margin>\n\n");
++ else
++ printf ("\nMACTEST.exe run_mode <speed> <ctrl> <loop_max> <test_mode> <phy_adr>\n\n");
++ PrintMode ();
++ PrintSpeed ();
++ PrintCtrl ();
++ PrintLoop ();
++ PrintTest ();
++ PrintPHYAdr ();
++ if (AST2300)
++ PrintIOTimingBund ();
++ }
++ Finish_Close();
++
++ return(1);
++ } // End if (argc > 1)
++
++//------------------------------------------------------------
++// Check Argument
++//------------------------------------------------------------
++ switch ( GRun_Mode ) {
++ case 0: printf ("\n[MAC1]\n"); SelectMAC = 0; H_MAC_BASE = MAC_BASE1; break;
++ case 1: printf ("\n[MAC2]\n"); SelectMAC = 1; H_MAC_BASE = MAC_BASE2; break;
++ case 2: if (Enable_MAC34) {printf ("\n[MAC3]\n"); SelectMAC = 2; H_MAC_BASE = MAC_BASE3; break;}
++ else
++ goto Error_MAC_Mode;
++ case 3: if (Enable_MAC34) {printf ("\n[MAC4]\n"); SelectMAC = 3; H_MAC_BASE = MAC_BASE4; break;}
++ else
++ goto Error_MAC_Mode;
++ default:
++Error_MAC_Mode:
++ printf ("Error run_mode!!!\n");
++ PrintMode ();
++
++ return(1);
++ } // End switch ( GRun_Mode )
++
++ H_TDES_BASE = TDES_BASE1;
++ H_RDES_BASE = RDES_BASE1;
++ MAC_PHYBASE = H_MAC_BASE;
++
++ Force1G = 0;
++ Force10M = 0;
++ Force100M = 0;
++ GSpeed_sel[0] = 0;//1G
++ GSpeed_sel[1] = 0;//100M
++ GSpeed_sel[2] = 0;//10M
++
++ switch ( GSpeed ) {
++ case SET_1GBPS : Force1G = 1; GSpeed_sel[0] = 1; break;
++ case SET_100MBPS : Force100M = 1; GSpeed_sel[1] = 1; break;
++ case SET_10MBPS : Force10M = 1; GSpeed_sel[2] = 1; break;
++ case SET_1G_100M_10MBPS : break;
++ default: printf ("Error speed!!!\n");
++ PrintSpeed ();
++ return(1);
++ } // End switch ( GSpeed )
++
++ if ( ModeSwitch == MODE_NSCI ) {
++ Enable_MACLoopback = 0; // For mactest function
++ Enable_SkipChkPHY = 0; // For mactest function
++ Enable_IntLoopPHY = 0; // For mactest function
++ Enable_InitPHY = 0; // For mactest function
++ Disable_RecovPHY = 0; // For mactest function
++ BurstEnable = 0; // For mactest function
++
++ PrintNCSIEn = (ARPNumCnt & 0x1);
++ ARPNumCnt = ARPNumCnt & 0xfffffffe;
++
++ // Check parameter
++ if ((PackageTolNum < 1) || (PackageTolNum > 8)) {
++ PrintPakNUm();
++ return(1);
++ }
++// if ((ChannelTolNum < 0) || (ChannelTolNum > 32)) {
++ if (ChannelTolNum > 32) {
++ PrintChlNUm();
++ return(1);
++ }
++
++ switch (TestMode) {
++ case 0 : NCSI_DiSChannel = 1; IOTiming = 0; IOStrength = 0; TxDataEnable = 1; RxDataEnable = 1; break;
++ case 1 : NCSI_DiSChannel = 0; IOTiming = 0; IOStrength = 0; TxDataEnable = 1; RxDataEnable = 1; break;
++ case 6 : if (AST2300) {NCSI_DiSChannel = 1; IOTiming = 1; IOStrength = 0; TxDataEnable = 1; RxDataEnable = 1; break;}
++ else
++ goto Error_Test_Mode_NCSI;
++ case 7 : if (AST2300) {NCSI_DiSChannel = 1; IOTiming = 1; IOStrength = 1; TxDataEnable = 1; RxDataEnable = 1; break;}
++ else
++ goto Error_Test_Mode_NCSI;
++ default:
++ // Wrong parameter
++Error_Test_Mode_NCSI:
++ printf ("Error test_mode!!!\n");
++ PrintTest ();
++ return(1);
++ } // End switch (TestMode)
++ }
++ else {
++ if ( GCtrl & 0xffffff83 ) {
++ printf ("Error ctrl!!!\n");
++ PrintCtrl ();
++ return(1);
++ }
++ else {
++ Enable_MACLoopback = ( GCtrl >> 6 ) & 0x1; // ??
++ Enable_SkipChkPHY = ( GCtrl >> 5 ) & 0x1; // ??
++ Enable_IntLoopPHY = ( GCtrl >> 4 ) & 0x1;
++ Enable_InitPHY = ( GCtrl >> 3 ) & 0x1;
++ Disable_RecovPHY = ( GCtrl >> 2 ) & 0x1; // ??
++
++ if (!AST2400 && Enable_MACLoopback) {
++ printf ("Error ctrl!!!\n");
++ PrintCtrl ();
++ return(1);
++ }
++ } // End if ( GCtrl & 0xffffff83 )
++
++ if (!LOOP_MAX_arg) {
++ switch (GSpeed) {
++ case SET_1GBPS : LOOP_MAX_arg = DEF_LOOP_MAX * 200; break; // 20140325
++ case SET_100MBPS : LOOP_MAX_arg = DEF_LOOP_MAX * 20 ; break; // 20140325
++ case SET_10MBPS : LOOP_MAX_arg = DEF_LOOP_MAX * 10 ; break; // 20140325
++ case SET_1G_100M_10MBPS: LOOP_MAX_arg = DEF_LOOP_MAX * 10 ; break; // 20140325
++ }
++ } // End if (!LOOP_MAX_arg)
++
++ LOOP_MAX = LOOP_MAX_arg * 10; // 20140325
++ Calculate_LOOP_CheckNum();
++
++ switch (TestMode) {
++ case 0 : BurstEnable = 0; IEEETesting = 0; IOTiming = 0; IOStrength = 0; TxDataEnable = 1; RxDataEnable = 1; DataDelay = 0; break;
++ case 1 : BurstEnable = 1; IEEETesting = 1; IOTiming = 0; IOStrength = 0; TxDataEnable = 1; RxDataEnable = 0; DataDelay = 0; break;
++ case 2 : BurstEnable = 1; IEEETesting = 1; IOTiming = 0; IOStrength = 0; TxDataEnable = 1; RxDataEnable = 0; DataDelay = 0; break;
++ case 3 : BurstEnable = 1; IEEETesting = 1; IOTiming = 0; IOStrength = 0; TxDataEnable = 1; RxDataEnable = 0; DataDelay = 0; break;
++ case 4 : BurstEnable = 1; IEEETesting = 0; IOTiming = 0; IOStrength = 0; TxDataEnable = 1; RxDataEnable = 0; DataDelay = 0; break; // ??
++ case 5 : BurstEnable = 1; IEEETesting = 1; IOTiming = 0; IOStrength = 0; TxDataEnable = 1; RxDataEnable = 0; DataDelay = 0; break; // ??
++ case 6 : if (AST2300) {BurstEnable = 0; IEEETesting = 0; IOTiming = 1; IOStrength = 0; TxDataEnable = 1; RxDataEnable = 1; DataDelay = 0; break;}
++ else
++ goto Error_Test_Mode;
++ case 7 : if (AST2300) {BurstEnable = 0; IEEETesting = 0; IOTiming = 1; IOStrength = 1; TxDataEnable = 1; RxDataEnable = 1; DataDelay = 0; break;}
++ else
++ goto Error_Test_Mode;
++ case 8 : BurstEnable = 0; IEEETesting = 0; IOTiming = 0; IOStrength = 0; TxDataEnable = 1; RxDataEnable = 0; DataDelay = 0; break; // ??
++ case 9 : BurstEnable = 0; IEEETesting = 0; IOTiming = 0; IOStrength = 0; TxDataEnable = 0; RxDataEnable = 1; DataDelay = 0; break; // ??
++ case 10 : BurstEnable = 0; IEEETesting = 0; IOTiming = 0; IOStrength = 0; TxDataEnable = 1; RxDataEnable = 1; DataDelay = 1; break; // ??
++ default:
++Error_Test_Mode:
++ printf ("Error test_mode!!!\n");
++ PrintTest ();
++ return(1);
++ } // End switch (TestMode)
++
++ if ( PHY_ADR > 31 ) {
++ printf ("Error phy_adr!!!\n");
++ PrintPHYAdr ();
++ return(1);
++ } // End if (PHY_ADR > 31)
++ } // End if ( ModeSwitch == MODE_NSCI )
++
++ if ( BurstEnable ) {
++ IOTimingBund = 0;
++ }
++ else {
++ if ( ~DataDelay && AST2300 ) {
++ if ( !( ( (7 >= IOTimingBund) && (IOTimingBund & 0x1) ) ||
++ ( IOTimingBund == 0 ) ) ) {
++ printf ("Error IO margin!!!\n");
++ PrintIOTimingBund ();
++ return(1);
++ }
++ }
++ else {
++ IOTimingBund = 0;
++ } // End if ( ~DataDelay && AST2300 )
++
++ // Define Output file name
++ if ( ModeSwitch == MODE_NSCI )
++ sprintf(FileNameMain, "%d", SelectMAC+1);
++ else {
++ if (Enable_IntLoopPHY)
++ sprintf(FileNameMain, "%dI", SelectMAC+1);
++ else
++ sprintf(FileNameMain, "%dE", SelectMAC+1);
++ }
++
++ #ifndef SLT_UBOOT
++ if ( IOTiming ) {
++ if ( IOStrength )
++ sprintf(FileName, "MIOD%sS.log", FileNameMain);
++ else
++ sprintf(FileName, "MIOD%s.log", FileNameMain);
++
++ fp_log = fopen(FileName,"w");
++
++ if ( IOStrength )
++ sprintf(FileName, "MIO%sS.log", FileNameMain);
++ else
++ sprintf(FileName, "MIO%s.log", FileNameMain);
++
++ fp_io = fopen(FileName,"w");
++ }
++ else {
++ sprintf(FileName, "MAC%s.log", FileNameMain);
++
++ fp_log = fopen(FileName,"w");
++ }
++ #endif
++ } // End if (BurstEnable)
++
++//------------------------------------------------------------
++// Check Definition
++//------------------------------------------------------------
++ for (i = 0; i < 16; i++)
++ valary[i] = Val_Array[i];
++
++ if ( AST3200 ) {
++ MAC_Mode = (SCU_70h_old >> 6) & 0x1;
++ MAC1_1GEn = (MAC_Mode & 0x1) ? 1 : 0;//1:RGMII, 0:RMII
++ MAC2_1GEn = 0;
++
++ MAC1_RMII = !MAC1_1GEn;
++ MAC2_RMII = 0;
++ MAC2_Valid = 0;
++ }
++ else if ( AST1010 ) {
++ MAC_Mode = 0;
++ MAC1_1GEn = 0;
++ MAC2_1GEn = 0;
++
++ MAC1_RMII = 1;
++ MAC2_RMII = 0;
++ MAC2_Valid = 0;
++ }
++ else if ( AST2300 ) {
++ if (SCU_7ch_old == 0x01000003) {
++ //AST2300-A0
++ for (i = 0; i < 16; i++) {
++ valary[i] = Val_Array_A0[i];
++ }
++ }
++
++ MAC_Mode = (SCU_70h_old >> 6) & 0x3;
++ MAC1_1GEn = (MAC_Mode & 0x1) ? 1 : 0;//1:RGMII, 0:RMII
++ MAC2_1GEn = (MAC_Mode & 0x2) ? 1 : 0;//1:RGMII, 0:RMII
++
++ MAC1_RMII = !MAC1_1GEn;
++ MAC2_RMII = !MAC2_1GEn;
++ MAC2_Valid = 1;
++ }
++ else {
++ MAC_Mode = (SCU_70h_old >> 6) & 0x7;
++ MAC1_1GEn = (MAC_Mode == 0x0) ? 1 : 0;
++ MAC2_1GEn = 0;
++
++ switch ( MAC_Mode ) {
++ case 0 : MAC1_RMII = 0; MAC2_RMII = 0; MAC2_Valid = 0; break; //000: Select GMII(MAC#1) only
++ case 1 : MAC1_RMII = 0; MAC2_RMII = 0; MAC2_Valid = 1; break; //001: Select MII (MAC#1) and MII(MAC#2)
++ case 2 : MAC1_RMII = 1; MAC2_RMII = 0; MAC2_Valid = 1; break; //010: Select RMII(MAC#1) and MII(MAC#2)
++ case 3 : MAC1_RMII = 0; MAC2_RMII = 0; MAC2_Valid = 0; break; //011: Select MII (MAC#1) only
++ case 4 : MAC1_RMII = 1; MAC2_RMII = 0; MAC2_Valid = 0; break; //100: Select RMII(MAC#1) only
++// case 5 : MAC1_RMII = 0; MAC2_RMII = 0; MAC2_Valid = 0; break; //101: Reserved
++ case 6 : MAC1_RMII = 1; MAC2_RMII = 1; MAC2_Valid = 1; break; //110: Select RMII(MAC#1) and RMII(MAC#2)
++// case 7 : MAC1_RMII = 0; MAC2_RMII = 0; MAC2_Valid = 0; break; //111: Disable dual MAC
++ default: return(Finish_Check(Err_MACMode));
++ }
++ } // End if ( AST3200 )
++
++ if ( SelectMAC == 0 ) {
++ Enable_RMII = MAC1_RMII;
++ MAC_1GEn = MAC1_1GEn;
++
++ if ( Force1G & !MAC1_1GEn ) {
++ printf ("\nMAC1 don't support 1Gbps !!!\n");
++ return( Finish_Check(Err_MACMode) );
++ }
++ } else if (SelectMAC == 1) {
++ Enable_RMII = MAC2_RMII;
++ MAC_1GEn = MAC2_1GEn;
++
++ if ( Force1G & !MAC2_1GEn ) {
++ printf ("\nMAC2 don't support 1Gbps !!!\n");
++ return(Finish_Check(Err_MACMode));
++ }
++ if ( !MAC2_Valid ) {
++ printf ("\nMAC2 not valid !!!\n");
++ return(Finish_Check(Err_MACMode));
++ }
++ }
++ else {
++ Enable_RMII = 1;
++ MAC_1GEn = 0;
++
++ if (Force1G) {
++ printf ("\nMAC3/MAC4 don't support 1Gbps !!!\n");
++ return(Finish_Check(Err_MACMode));
++ }
++ } // End if ( SelectMAC == 0 )
++
++ if ( ModeSwitch == MODE_NSCI ) {
++ if (!Enable_RMII) {
++ printf ("\nNCSI must be RMII interface !!!\n");
++ return(Finish_Check(Err_MACMode));
++ }
++ }
++
++ if ( GSpeed == SET_1G_100M_10MBPS ) {
++ GSpeed_sel[0] = MAC_1GEn;
++ GSpeed_sel[1] = 1;
++ GSpeed_sel[2] = 1;
++ }
++
++ if ( AST1010 ) {
++ // Check bit 13:12
++ Dat_ULONG = SCU_08h_old & 0x00003000;
++ if (Dat_ULONG != 0x00000000)
++ return(Finish_Check(Err_MHCLK_Ratio));
++ }
++ else if ( AST2300 ) {
++ Dat_ULONG = (SCU_08h_old >> 16) & 0x7;
++ if (MAC1_1GEn | MAC2_1GEn) {
++ if ( (Dat_ULONG == 0) || (Dat_ULONG > 2) )
++ return(Finish_Check(Err_MHCLK_Ratio));
++ }
++ else {
++ if (Dat_ULONG != 4)
++ return(Finish_Check(Err_MHCLK_Ratio));
++ }
++ } // End if (AST1010)
++
++ //MAC
++ MAC_08h_old = ReadSOC_DD( H_MAC_BASE + 0x08 );
++ MAC_0ch_old = ReadSOC_DD( H_MAC_BASE + 0x0c );
++ MAC_40h_old = ReadSOC_DD( H_MAC_BASE + 0x40 );
++
++ if ( ((MAC_08h_old == 0x0000) && (MAC_0ch_old == 0x00000000))
++ || ((MAC_08h_old == 0xffff) && (MAC_0ch_old == 0xffffffff))
++// || (MAC_0ch_old & 0x1)
++// || (MAC_0ch_old & 0x2)
++ )
++ {
++ // Load default for MAC address
++ SA[0] = 0x00;
++ SA[1] = 0x57;
++ SA[2] = 0x89;
++ SA[3] = 0x56;
++ SA[4] = 0x88;
++ SA[5] = 0x38;
++ }
++ else {
++ SA[0] = (MAC_08h_old >> 8) & 0xff;
++ SA[1] = (MAC_08h_old ) & 0xff;
++ SA[2] = (MAC_0ch_old >> 24) & 0xff;
++ SA[3] = (MAC_0ch_old >> 16) & 0xff;
++ SA[4] = (MAC_0ch_old >> 8) & 0xff;
++ SA[5] = (MAC_0ch_old ) & 0xff;
++ }
++ // printf ("%08x %08x: %02x %02x %02x %02x %02x %02x\n", MAC_08h_old, MAC_0ch_old, SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]);
++
++ if ( AST2300 ) {
++#ifdef Force_Enable_NewMDIO
++ AST2300_NewMDIO = 1;
++ WriteSOC_DD(H_MAC_BASE+0x40, MAC_40h_old | 0x80000000)
++#else
++ AST2300_NewMDIO = (MAC_40h_old & 0x80000000) ? 1 : 0;
++#endif
++ }
++ else {
++ AST2300_NewMDIO = 0;
++ } // End if (AST2300)
++
++//------------------------------------------------------------
++// Parameter Initial
++//------------------------------------------------------------
++ if ( AST3200 ) {
++ SCU_04h = 0x0c000800; //Reset Engine
++ }
++ else if (AST1010) {
++ SCU_04h = 0x00000010; //Reset Engine
++ }
++ else if (AST2300) {
++ SCU_04h = 0x0c001800; //Reset Engine
++ }
++ else {
++ SCU_04h = 0x00001800; //Reset Engine
++ } // End if ( AST3200 )
++
++ if ( ModeSwitch == MODE_NSCI )
++ // Set to 100Mbps and Enable RX broabcast packets and CRC_APD and Full duplex
++ MAC_50h = 0x000a0500;
++ else {
++ // RX_ALLADR and CRC_APD and Full duplex
++ MAC_50h = 0x00004500;
++
++ #ifdef Enable_Runt
++ MAC_50h = MAC_50h | 0x00001000;
++ #endif
++
++ #ifdef Enable_Jumbo
++ MAC_50h = MAC_50h | 0x00002000;
++ #endif
++ } // End if ( ModeSwitch == MODE_NSCI )
++
++//------------------------------------------------------------
++// Descriptor Number
++//------------------------------------------------------------
++ if ( ModeSwitch == MODE_DEDICATED ) {
++
++ #ifdef Enable_Jumbo
++ DES_LowNumber = 1;
++ #else
++ DES_LowNumber = IOTiming;
++ #endif
++ if ( Enable_SkipChkPHY && ( TestMode == 0 ) ) {
++ DES_NUMBER = 114;//for SMSC's LAN9303 issue
++ }
++ else {
++ if ( AST1010 | AST3200 ) {
++ DES_NUMBER = (IOTimingBund) ? 100 : 256;
++ }
++ else {
++ switch ( GSpeed ) {
++ case SET_1GBPS : DES_NUMBER = (IOTimingBund) ? 10 : (DES_LowNumber) ? 50 : 400; break; // 20140325
++ case SET_100MBPS : DES_NUMBER = (IOTimingBund) ? 10 : (DES_LowNumber) ? 50 : 400; break; // 20140325
++ case SET_10MBPS : DES_NUMBER = (IOTimingBund) ? 10 : (DES_LowNumber) ? 10 : 80; break; // 20140325
++ case SET_1G_100M_10MBPS : DES_NUMBER = (IOTimingBund) ? 10 : (DES_LowNumber) ? 10 : 80; break; // 20140325
++ }
++ } // End if ( Enable_SkipChkPHY && ( TestMode == 0 ) )
++ }
++
++ #ifdef SelectDesNumber
++ DES_NUMBER = SelectDesNumber;
++ #endif
++
++ #ifdef USE_LPC
++ DES_NUMBER /= 8;
++ #endif
++
++ #ifdef ENABLE_ARP_2_WOL
++ if ( TestMode == 4 ) {
++ DES_NUMBER = 1;
++ }
++ #endif
++
++ DES_NUMBER_Org = DES_NUMBER;
++
++ if ( DbgPrn_Info ) {
++ printf ("CheckBuf_MBSize : %ld\n", CheckBuf_MBSize);
++ printf ("LOOP_CheckNum : %ld\n", LOOP_CheckNum);
++ printf ("DES_NUMBER : %ld\n", DES_NUMBER);
++ printf ("DMA_BufSize : %ld bytes\n", DMA_BufSize);
++ printf ("DMA_BufNum : %d\n", DMA_BufNum);
++ printf ("\n");
++ }
++// if (3 > DMA_BufNum)
++// return( Finish_Check(Err_DMABufNum) );
++
++ if (2 > DMA_BufNum)
++ return( Finish_Check(Err_DMABufNum) );
++ } // End if ( ModeSwitch == MODE_DEDICATED )
++ } // End if (RUN_STEP >= 1)
++
++//------------------------------------------------------------
++// SCU Initial
++//------------------------------------------------------------
++ if ( RUN_STEP >= 2 ) {
++ init_scu1();
++ }
++
++ if ( RUN_STEP >= 3 ) {
++ init_scu_macrst();
++ }
++
++//------------------------------------------------------------
++// Data Initial
++//------------------------------------------------------------
++ if (RUN_STEP >= 4) {
++ setup_arp();
++ if ( ModeSwitch == MODE_DEDICATED ) {
++
++ FRAME_LEN = (ULONG *)malloc(DES_NUMBER * sizeof( ULONG ));
++ wp_lst = (ULONG *)malloc(DES_NUMBER * sizeof( ULONG ));
++
++ if ( !FRAME_LEN )
++ return( Finish_Check( Err_MALLOC_FrmSize ) );
++
++ if ( !wp_lst )
++ return( Finish_Check( Err_MALLOC_LastWP ));
++
++ // Setup data and length
++ TestingSetup();
++ } // End if ( ModeSwitch == MODE_DEDICATED )
++
++ // Get bit (shift) of IO driving strength register
++ if ( IOStrength ) {
++ if (AST1010) {
++ IOStr_max = 1;//0~1
++ }
++ else if (AST2400) {
++ IOStr_max = 1;//0~1
++ switch (SelectMAC) {
++ case 0 : IOStr_shf = 9; break;
++ case 1 : IOStr_shf = 11; break;
++ }
++ }
++ else {
++ IOStr_max = 3;//0~3
++ switch (SelectMAC) {
++ case 0 : IOStr_shf = 8; break;
++ case 1 : IOStr_shf = 10; break;
++ case 2 : IOStr_shf = 12; break;
++ case 3 : IOStr_shf = 14; break;
++ }
++ }
++ }
++ else {
++ IOStr_max = 0;
++ IOStr_shf = 0;
++ } // End if (IOStrength)
++
++ // Get current clock delay value of TX(out) and RX(in) in the SCU48 register
++ // and setting test range
++ if ( Enable_RMII ) {
++ switch (GRun_Mode) {
++ case 0 : IOdly_out_shf = 24; IOdly_in_shf = 8; break;
++ case 1 : IOdly_out_shf = 25; IOdly_in_shf = 12; break;
++ case 2 : IOdly_out_shf = 26; IOdly_in_shf = 16; break;
++ case 3 : IOdly_out_shf = 27; IOdly_in_shf = 20; break;
++ }
++ IOdly_in_reg = (SCU_48h_old >> IOdly_in_shf ) & 0xf;
++ IOdly_out_reg = (SCU_48h_old >> IOdly_out_shf) & 0x1;
++ }
++ else {
++ switch (GRun_Mode) {
++ case 0 : IOdly_out_shf = 0; IOdly_in_shf = 8; break;
++ case 1 : IOdly_out_shf = 4; IOdly_in_shf = 12; break;
++ }
++ IOdly_in_reg = (SCU_48h_old >> IOdly_in_shf ) & 0xf;
++ IOdly_out_reg = (SCU_48h_old >> IOdly_out_shf) & 0xf;
++ } // End if ( Enable_RMII )
++
++ // Find the coordinate in X-Y axis
++ for ( index = 0; index <= 15; index++ )
++ if ( IOdly_in_reg == valary[index] ) {
++ IOdly_in_reg_idx = index;
++ break;
++ }
++ for ( index = 0; index <= 15; index++ )
++ if ( IOdly_out_reg == valary[index] ) {
++ IOdly_out_reg_idx = index;
++ break;
++ }
++
++ // Get the range for testmargin block
++ if ( IOTiming ) {
++ if ( Enable_RMII ) {
++ IOdly_incval = 1;
++ IOdly_in_str = 0;
++ IOdly_in_end = 15;
++ IOdly_out_str = 0;
++ IOdly_out_end = 1;
++ }
++ else {
++ IOdly_incval = 1;
++ IOdly_in_str = 0;
++ IOdly_in_end = 15;
++ IOdly_out_str = 0;
++ IOdly_out_end = 15;
++ }
++ }
++ else if ( IOTimingBund ) {
++ if ( Enable_RMII ) {
++ IOdly_incval = 1;
++ IOdly_in_str = IOdly_in_reg_idx - ( IOTimingBund >> 1 );
++ IOdly_in_end = IOdly_in_reg_idx + ( IOTimingBund >> 1 );
++ IOdly_out_str = IOdly_out_reg_idx;
++ IOdly_out_end = IOdly_out_reg_idx;
++ }
++ else {
++ IOdly_incval = 1;
++ IOdly_in_str = IOdly_in_reg_idx - ( IOTimingBund >> 1 );
++ IOdly_in_end = IOdly_in_reg_idx + ( IOTimingBund >> 1 );
++ IOdly_out_str = IOdly_out_reg_idx - ( IOTimingBund >> 1 );
++ IOdly_out_end = IOdly_out_reg_idx + ( IOTimingBund >> 1 );
++ }
++ if ((IOdly_in_str < 0) || (IOdly_in_end > 15))
++ return( Finish_Check( Err_IOMarginOUF ) );
++
++ if ((IOdly_out_str < 0) || (IOdly_out_end > 15))
++ return( Finish_Check( Err_IOMarginOUF ) );
++
++// if (IOdly_in_str < 0) IOdly_in_str = 0;
++// if (IOdly_in_end > 15) IOdly_in_end = 15;
++// if (IOdly_out_str < 0) IOdly_out_str = 0;
++// if (IOdly_out_end > 15) IOdly_out_end = 15;
++ }
++ else {
++ IOdly_incval = 1;
++ IOdly_in_str = 0;
++ IOdly_in_end = 0;
++ IOdly_out_str = 0;
++ IOdly_out_end = 0;
++ } // End if (IOTiming)
++ } // End if (RUN_STEP >= 4)
++
++//------------------------------------------------------------
++// main
++//------------------------------------------------------------
++ if (RUN_STEP >= 5) {
++ #ifdef DbgPrn_FuncHeader
++ printf ("GSpeed_sel: %d %d %d\n", GSpeed_sel[0], GSpeed_sel[1], GSpeed_sel[2]);
++ Debug_delay();
++ #endif
++
++ if ( ModeSwitch == MODE_NSCI ) {
++ #ifdef Enable_NCSI_LOOP_INFINI
++ for ( GSpeed_idx = 0; GSpeed_idx < 3; GSpeed_idx++ ) {
++ GSpeed_org[GSpeed_idx] = GSpeed_sel[GSpeed_idx];
++ }
++NCSI_LOOP_INFINI:;
++ for ( GSpeed_idx = 0; GSpeed_idx < 3; GSpeed_idx++ ) {
++ GSpeed_sel[GSpeed_idx] = GSpeed_org[GSpeed_idx];
++ }
++ #endif
++ } // End if ( ModeSwitch == MODE_NSCI )
++
++ for (GSpeed_idx = 0; GSpeed_idx < 3; GSpeed_idx++) {
++ Err_Flag_PrintEn = 1;
++ if ( GSpeed_sel[GSpeed_idx] ) {
++ // Setting the LAN speed
++ if ( ModeSwitch == MODE_DEDICATED ) {
++
++
++ // Test three speed of LAN, we will modify loop number
++ if (GSpeed == SET_1G_100M_10MBPS) {
++ if (GSpeed_sel[0]) LOOP_MAX = LOOP_MAX_arg;
++ else if (GSpeed_sel[1]) LOOP_MAX = LOOP_MAX_arg / 10;
++ else LOOP_MAX = LOOP_MAX_arg / 100;
++
++ if ( !LOOP_MAX )
++ LOOP_MAX = 1;
++
++ Calculate_LOOP_CheckNum();
++ }
++
++ // Setting speed of LAN
++ if (GSpeed_sel[0]) MAC_50h_Speed = 0x00000200;
++ else if (GSpeed_sel[1]) MAC_50h_Speed = 0x00080000;
++ else MAC_50h_Speed = 0x00000000;
++
++ //------------------------------------------------------------
++ // PHY Initial
++ //------------------------------------------------------------
++ if ( AST1100 )
++ init_scu2();
++
++ if ( Enable_InitPHY ) {
++#ifdef SUPPORT_PHY_LAN9303
++ LAN9303(LAN9303_I2C_BUSNUM, PHY_ADR_arg, GSpeed_idx, Enable_IntLoopPHY | (BurstEnable<<1) | IEEETesting);
++#else
++ init_phy( Enable_IntLoopPHY );
++#endif
++ DELAY( Delay_PHYRst * 10 );
++ } // End if (Enable_InitPHY)
++
++ if ( AST1100 )
++ init_scu3();
++
++ if ( Err_Flag )
++ return( Finish_Check( 0 ) );
++ } // End if ( ModeSwitch == MODE_DEDICATED )
++
++ //------------------------------------------------------------
++ // Start
++ //------------------------------------------------------------
++
++ // The loop is for different IO strength
++ for ( IOStr_i = 0; IOStr_i <= IOStr_max; IOStr_i++ ) {
++
++ // Print Header of report to monitor and log file
++ if ( IOTiming || IOTimingBund ) {
++ if ( IOStrength ) {
++ if ( AST1010 ) {
++ IOStr_val = (SCU_ach_old & 0xfff0ffff) | ((IOStr_i) ? 0xf0000 : 0x0);
++ }
++ else {
++ IOStr_val = (SCU_90h_old & 0xffff00ff) | (IOStr_i << IOStr_shf);
++ }
++ //printf("\nIOStrength_val= %08x, ", IOStr_val);
++ //printf("SCU90h: %08x ->", ReadSOC_DD(SCU_BASE+0x90));
++ WriteSOC_DD( SCU_BASE + 0x90, IOStr_val );
++ //printf(" %08x\n", ReadSOC_DD(SCU_BASE+0x90));
++
++ #ifndef SLT_UBOOT
++ if (GSpeed_sel[0]) fprintf(fp_log, "[Strength %d][1G ]========================================\n", IOStr_i);
++ else if (GSpeed_sel[1]) fprintf(fp_log, "[Strength %d][100M]========================================\n", IOStr_i);
++ else fprintf(fp_log, "[Strength %d][10M ]========================================\n", IOStr_i);
++ #endif
++ }
++ else {
++ #ifndef SLT_UBOOT
++ if (GSpeed_sel[0]) fprintf(fp_log, "[1G ]========================================\n");
++ else if (GSpeed_sel[1]) fprintf(fp_log, "[100M]========================================\n");
++ else fprintf(fp_log, "[10M ]========================================\n");
++ #endif
++ }
++
++ if ( IOTimingBund )
++ PrintIO_Header(FP_LOG);
++ if ( IOTiming )
++ PrintIO_Header(FP_IO);
++
++ PrintIO_Header(STD_OUT);
++
++ }
++ else {
++ if ( ModeSwitch == MODE_DEDICATED ) {
++
++ if (!BurstEnable)
++ Print_Header(FP_LOG);
++
++ Print_Header(STD_OUT);
++ }
++ } // End if (IOTiming || IOTimingBund)
++
++#ifdef Enable_Old_Style
++ for (IOdly_i = IOdly_in_str; IOdly_i <= IOdly_in_end; IOdly_i+=IOdly_incval) {
++ IOdly_in = valary[IOdly_i];
++#else
++ for (IOdly_j = IOdly_out_str; IOdly_j <= IOdly_out_end; IOdly_j+=IOdly_incval) {
++ IOdly_out = valary[IOdly_j];
++#endif
++
++ if (IOTiming || IOTimingBund) {
++#ifdef Enable_Fast_SCU
++ #ifdef Enable_Old_Style
++ WriteSOC_DD(SCU_BASE + 0x48, SCU_48h_mix | (IOdly_in << IOdly_in_shf));
++ #else
++ WriteSOC_DD(SCU_BASE + 0x48, SCU_48h_mix | (IOdly_out << IOdly_out_shf));
++ #endif
++#endif
++
++ if ( IOTimingBund )
++ PrintIO_LineS(FP_LOG);
++ if ( IOTiming )
++ PrintIO_LineS(FP_IO);
++
++ PrintIO_LineS(STD_OUT);
++ } // End if (IOTiming || IOTimingBund)
++
++ //------------------------------------------------------------
++ // SCU Initial
++ //------------------------------------------------------------
++#ifdef Enable_Fast_SCU
++ init_scu_macrst();
++#endif
++#ifdef Enable_Old_Style
++ for (IOdly_j = IOdly_out_str; IOdly_j <= IOdly_out_end; IOdly_j+=IOdly_incval) {
++ IOdly_out = valary[IOdly_j];
++#else
++ for (IOdly_i = IOdly_in_str; IOdly_i <= IOdly_in_end; IOdly_i+=IOdly_incval) {
++ IOdly_in = valary[IOdly_i];
++#endif
++ if ( IOTiming || IOTimingBund ) {
++ IOdly_val = (IOdly_in << IOdly_in_shf) | (IOdly_out << IOdly_out_shf);
++
++//printf("\nIOdly_val= %08x, ", IOdly_val);
++//printf("SCU48h: %08x ->", ReadSOC_DD( SCU_BASE + 0x48 ) );
++ WriteSOC_DD( SCU_BASE + 0x48, SCU_48h_mix | IOdly_val );
++//printf(" %08x\n", ReadSOC_DD(SCU_BASE+0x48));
++ } // End if (IOTiming || IOTimingBund)
++
++ //------------------------------------------------------------
++ // SCU Initial
++ //------------------------------------------------------------
++#ifdef Enable_Fast_SCU
++#else
++ init_scu_macrst();
++#endif
++
++ //------------------------------------------------------------
++ // MAC Initial
++ //------------------------------------------------------------
++ init_mac(H_MAC_BASE, H_TDES_BASE, H_RDES_BASE);
++ if ( Err_Flag )
++ return( Finish_Check(0) );
++
++ // Testing
++ if ( ModeSwitch == MODE_NSCI )
++ dlymap[IOdly_i][IOdly_j] = phy_ncsi();
++ else
++ dlymap[IOdly_i][IOdly_j] = TestingLoop(LOOP_CheckNum);
++
++
++ // Display to Log file and monitor
++ if ( IOTiming || IOTimingBund ) {
++
++ if ( IOTimingBund )
++ PrintIO_Line(FP_LOG);
++
++ if ( IOTiming )
++ PrintIO_Line(FP_IO);
++
++ PrintIO_Line(STD_OUT);
++
++ // Find the range of current setting
++ if ( ( IOdly_in_reg == IOdly_in ) && ( IOdly_out_reg == IOdly_out ) ) {
++ IOdly_i_min = IOdly_i - ( IOTimingBund >> 1 );
++ IOdly_i_max = IOdly_i + ( IOTimingBund >> 1 );
++
++ if ( Enable_RMII ) {
++ IOdly_j_min = IOdly_j;
++ IOdly_j_max = IOdly_j;
++ }
++ else {
++ IOdly_j_min = IOdly_j - (IOTimingBund >> 1 );
++ IOdly_j_max = IOdly_j + (IOTimingBund >> 1 );
++ }
++ }
++
++ PrintIO_Line_LOG();
++ FPri_ErrFlag(FP_LOG);
++
++// Err_Flag_allapeed = Err_Flag_allapeed | Err_Flag;
++ Err_Flag = 0;
++ }
++ }// End for (IOdly_j = IOdly_out_str; IOdly_j <= IOdly_out_end; IOdly_j+=IOdly_incval)
++#ifndef SLT_UBOOT
++ if ( IOTiming || IOTimingBund ) {
++ if ( IOTimingBund )
++ fprintf(fp_log, "\n");
++ if (IOTiming )
++ fprintf(fp_io, "\n");
++ }
++#endif
++ printf("\n");
++ } // End for (IOdly_j = IOdly_out_str; IOdly_j <= IOdly_out_end; IOdly_j+=IOdly_incval)
++
++ //------------------------------------------------------------
++ // End
++ //------------------------------------------------------------
++
++ if ( IOTiming || IOTimingBund ) {
++ if ( ( IOdly_i_min < 0 ) || ( IOdly_i_max > 15 ) )
++ FindErr(Err_IOMarginOUF);
++ if ( ( IOdly_j_min < 0 ) || ( IOdly_j_max > 15 ) )
++ FindErr(Err_IOMarginOUF);
++
++ if ( IOdly_i_min < 0 ) IOdly_i_min = 0;
++ if ( IOdly_i_max > 15 ) IOdly_i_max = 15;
++ if ( IOdly_j_min < 0 ) IOdly_j_min = 0;
++ if ( IOdly_j_max > 15 ) IOdly_j_max = 15;
++
++#ifdef Enable_Old_Style
++ for (IOdly_i = IOdly_i_min; IOdly_i <= IOdly_i_max; IOdly_i++)
++ for (IOdly_j = IOdly_j_min; IOdly_j <= IOdly_j_max; IOdly_j++)
++#else
++ for (IOdly_j = IOdly_j_min; IOdly_j <= IOdly_j_max; IOdly_j++)
++ for (IOdly_i = IOdly_i_min; IOdly_i <= IOdly_i_max; IOdly_i++)
++#endif
++ {
++ if ( dlymap[IOdly_i][IOdly_j] ) {
++#ifdef SLT_DOS
++ if ( IOTiming ) {
++#ifdef Enable_Old_Style
++ for (i = IOdly_i_min; i <= IOdly_i_max; i++)
++#else
++ for (j = IOdly_j_min; j <= IOdly_j_max; j++)
++#endif
++ {
++#ifdef Enable_Old_Style
++ for (j = IOdly_j_min; j <= IOdly_j_max; j++)
++#else
++ for (i = IOdly_i_min; i <= IOdly_i_max; i++)
++#endif
++ {
++ if (dlymap[i][j]) fprintf(fp_io, "x ");
++ else fprintf(fp_io, "o ");
++ }
++ fprintf(fp_io, "\n");
++ }
++ } // End if ( IOTiming )
++#endif // End SLT_DOS
++ FindErr(Err_IOMargin);
++ goto Find_Err_IOMargin;
++ } // End if ( dlymap[IOdly_i][IOdly_j] )
++ }
++ } // End if ( IOTiming || IOTimingBund )
++
++Find_Err_IOMargin:;
++ if ( !BurstEnable )
++ FPri_ErrFlag(FP_LOG);
++ if ( IOTiming )
++ FPri_ErrFlag(FP_IO);
++
++ FPri_ErrFlag(STD_OUT);
++
++ Err_Flag_allapeed = Err_Flag_allapeed | Err_Flag;
++ Err_Flag = 0;
++ } // End for (IOStr_i = 0; IOStr_i <= IOStr_max; IOStr_i++)
++
++ if ( ModeSwitch == MODE_DEDICATED ) {
++ if ( Enable_InitPHY & !Disable_RecovPHY )
++ recov_phy(Enable_IntLoopPHY);
++ }
++
++ GSpeed_sel[GSpeed_idx] = 0;
++ } // End if (GSpeed_sel[GSpeed_idx])
++
++ Err_Flag_PrintEn = 0;
++ } // End for (GSpeed_idx = 0; GSpeed_idx < 3; GSpeed_idx++)
++
++ Err_Flag = Err_Flag_allapeed;
++
++ if ( ModeSwitch == MODE_NSCI ) {
++ #ifdef Enable_NCSI_LOOP_INFINI
++ if (Err_Flag == 0) {
++ if (fp_log) {
++ fclose(fp_log);
++ fp_log = fopen(FileName,"w");
++ }
++ goto NCSI_LOOP_INFINI;
++ }
++ #endif
++ }
++
++ } // End if (RUN_STEP >= 5)
++
++ return(Finish_Check(0));
++
++}
++
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/reset.c b/arch/arm/cpu/arm926ejs/aspeed/reset.c
+new file mode 100644
+index 0000000..e0a57f9
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/reset.c
+@@ -0,0 +1,24 @@
++/*
++ * 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 <common.h>
++#include <asm/io.h>
++
++#define AST_WDT_BASE 0x1e785000
++void reset_cpu(ulong addr)
++{
++ __raw_writel(0x10 , AST_WDT_BASE+0x04);
++ __raw_writel(0x4755, AST_WDT_BASE+0x08);
++ __raw_writel(0x3, AST_WDT_BASE+0x0c);
++
++ while (1)
++ /*nothing*/;
++}
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/timer.c b/arch/arm/cpu/arm926ejs/aspeed/timer.c
+new file mode 100644
+index 0000000..4bba5c5
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/aspeed/timer.c
+@@ -0,0 +1,153 @@
++/*
++ * 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 <common.h>
++#include <arm926ejs.h>
++
++#define TIMER_LOAD_VAL 0xffffffff
++
++/* macro to read the 32 bit timer */
++#define READ_TIMER (*(volatile ulong *)(CONFIG_SYS_TIMERBASE+0))
++
++static ulong timestamp;
++static ulong lastdec;
++
++int timer_init (void)
++{
++ *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 4) = TIMER_LOAD_VAL;
++ *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 0x30) = 0x3; /* enable timer1 */
++
++ /* init the timestamp and lastdec value */
++ reset_timer_masked();
++
++ return 0;
++}
++
++/*
++ * timer without interrupts
++ */
++
++void reset_timer (void)
++{
++ reset_timer_masked ();
++}
++
++ulong get_timer (ulong base)
++{
++ return get_timer_masked () - base;
++}
++
++void set_timer (ulong t)
++{
++ timestamp = t;
++}
++
++/* delay x useconds AND perserve advance timstamp value */
++void udelay (unsigned long usec)
++{
++ ulong tmo, tmp;
++
++ if(usec >= 1000){ /* if "big" number, spread normalization to seconds */
++ tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
++ tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */
++ tmo /= 1000; /* finish normalize. */
++ }else{ /* else small number, don't kill it prior to HZ multiply */
++ tmo = usec * CONFIG_SYS_HZ;
++ tmo /= (1000*1000);
++ }
++
++ tmp = get_timer (0); /* get current timestamp */
++ if( (tmo + tmp + 1) < tmp ) /* if setting this fordward will roll time stamp */
++ reset_timer_masked (); /* reset "advancing" timestamp to 0, set lastdec value */
++ else
++ tmo += tmp; /* else, set advancing stamp wake up time */
++
++ while (get_timer_masked () < tmo)/* loop till event */
++ /*NOP*/;
++}
++
++void reset_timer_masked (void)
++{
++ /* reset time */
++ lastdec = READ_TIMER; /* capure current decrementer value time */
++ timestamp = 0; /* start "advancing" time stamp from 0 */
++}
++
++ulong get_timer_masked (void)
++{
++ ulong now = READ_TIMER; /* current tick value */
++
++ if (lastdec >= now) { /* normal mode (non roll) */
++ /* normal mode */
++ timestamp += lastdec - now; /* move stamp fordward with absoulte diff ticks */
++ } else { /* we have overflow of the count down timer */
++ /* nts = ts + ld + (TLV - now)
++ * ts=old stamp, ld=time that passed before passing through -1
++ * (TLV-now) amount of time after passing though -1
++ * nts = new "advancing time stamp"...it could also roll and cause problems.
++ */
++ timestamp += lastdec + TIMER_LOAD_VAL - now;
++ }
++ lastdec = now;
++
++ return timestamp;
++}
++
++/* waits specified delay value and resets timestamp */
++void udelay_masked (unsigned long usec)
++{
++ ulong tmo;
++ ulong endtime;
++ signed long diff;
++
++ if (usec >= 1000) { /* if "big" number, spread normalization to seconds */
++ tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
++ tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */
++ tmo /= 1000; /* finish normalize. */
++ } else { /* else small number, don't kill it prior to HZ multiply */
++ tmo = usec * CONFIG_SYS_HZ;
++ tmo /= (1000*1000);
++ }
++
++ endtime = get_timer_masked () + tmo;
++
++ do {
++ ulong now = get_timer_masked ();
++ diff = endtime - now;
++ } while (diff >= 0);
++}
++
++/*
++ * This function is derived from PowerPC code (read timebase as long long).
++ * On ARM it just returns the timer value.
++ */
++unsigned long long get_ticks(void)
++{
++ return get_timer(0);
++}
++
++/*
++ * This function is derived from PowerPC code (timebase clock frequency).
++ * On ARM it returns the number of timer ticks per second.
++ */
++ulong get_tbclk (void)
++{
++ ulong tbclk;
++
++ tbclk = CONFIG_SYS_HZ;
++ return tbclk;
++}
+diff --git a/arch/arm/include/asm/arch-aspeed/aspeed_i2c.h b/arch/arm/include/asm/arch-aspeed/aspeed_i2c.h
+new file mode 100644
+index 0000000..5419fca
+--- /dev/null
++++ b/arch/arm/include/asm/arch-aspeed/aspeed_i2c.h
+@@ -0,0 +1,69 @@
++/*
++ * 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
++ */
++#if defined(CONFIG_AST1300)
++#define SCU_BASE CONFIG_SCUREG_BASE
++#define I2C_BASE CONFIG_I2CREG_BASE
++#define I2C_CHANNEL CONFIG_I2C_CHANNEL
++#else
++#define SCU_BASE 0x1E6E2000
++#define I2C_BASE 0x1E78A000
++/* Cause U-boot i2c command limitation, it can't assign channel number. Our EEPROM is at channel 3 now*/
++/* AST2200's EEPROM is at channel 4 */
++#if defined(CONFIG_AST2200) || defined(CONFIG_AST2300) || defined(CONFIG_AST2400)
++#define I2C_CHANNEL 4
++#else
++#define I2C_CHANNEL 3
++#endif
++#endif
++
++/* Fix timing for EEPROM 100Khz*/
++#define AC_TIMING 0x77743335
++#define ALL_CLEAR 0xFFFFFFFF
++#define MASTER_ENABLE 0x01
++#define SLAVE_ENABLE 0x02
++#define LOOP_COUNT 0x100000
++#define SCU_RESET_CONTROL 0x04
++#define SCU_MULTIFUNCTION_PIN_CTL5_REG 0x90
++
++/* I2C Register */
++#define I2C_FUNCTION_CONTROL_REGISTER (I2C_BASE + I2C_CHANNEL * 0x40 + 0x00)
++#define I2C_AC_TIMING_REGISTER_1 (I2C_BASE + I2C_CHANNEL * 0x40 + 0x04)
++#define I2C_AC_TIMING_REGISTER_2 (I2C_BASE + I2C_CHANNEL * 0x40 + 0x08)
++#define I2C_INTERRUPT_CONTROL_REGISTER (I2C_BASE + I2C_CHANNEL * 0x40 + 0x0c)
++#define I2C_INTERRUPT_STATUS_REGISTER (I2C_BASE + I2C_CHANNEL * 0x40 + 0x10)
++#define I2C_COMMAND_REGISTER (I2C_BASE + I2C_CHANNEL * 0x40 + 0x14)
++#define I2C_DEVICE_ADDRESS_REGISTER (I2C_BASE + I2C_CHANNEL * 0x40 + 0x18)
++#define I2C_BUFFER_CONTROL_REGISTER (I2C_BASE + I2C_CHANNEL * 0x40 + 0x1c)
++#define I2C_BYTE_BUFFER_REGISTER (I2C_BASE + I2C_CHANNEL * 0x40 + 0x20)
++#define I2C_DMA_CONTROL_REGISTER (I2C_BASE + I2C_CHANNEL * 0x40 + 0x24)
++#define I2C_DMA_STATUS_REGISTER (I2C_BASE + I2C_CHANNEL * 0x40 + 0x28)
++
++/* Command Bit */
++#define MASTER_START_COMMAND (1 << 0)
++#define MASTER_TX_COMMAND (1 << 1)
++#define MASTER_RX_COMMAND (1 << 3)
++#define RX_COMMAND_LIST (1 << 4)
++#define MASTER_STOP_COMMAND (1 << 5)
++
++/* Interrupt Status Bit */
++#define TX_ACK (1 << 0)
++#define TX_NACK (1 << 1)
++#define RX_DONE (1 << 2)
++#define STOP_DONE (1 << 4)
++
++/* Macros to access registers */
++#define outb(v,p) *(volatile u8 *) (p) = v
++#define outw(v,p) *(volatile u16 *) (p) = v
++#define outl(v,p) *(volatile u32 *) (p) = v
++
++#define inb(p) *(volatile u8 *) (p)
++#define inw(p) *(volatile u16 *) (p)
++#define inl(p) *(volatile u32 *) (p)
+diff --git a/arch/arm/include/asm/mach-types.h b/arch/arm/include/asm/mach-types.h
+index 440b041..48fcf2b 100644
+--- a/arch/arm/include/asm/mach-types.h
++++ b/arch/arm/include/asm/mach-types.h
+@@ -175,6 +175,16 @@ extern unsigned int __machine_arch_type;
+ #define MACH_TYPE_PALMTX 885
+ #define MACH_TYPE_S3C2413 887
+ #define MACH_TYPE_WG302V2 890
++#define MACH_TYPE_AST1100 903
++#define MACH_TYPE_AST2000 900
++#define MACH_TYPE_AST2100 902
++#define MACH_TYPE_AST2150 907
++#define MACH_TYPE_AST2200 906
++#define MACH_TYPE_AST2300_FPGA_1 901
++#define MACH_TYPE_AST2300_FPGA_2 901
++#define MACH_TYPE_AST2300 901
++#define MACH_TYPE_AST3100 901
++#define MACH_TYPE_ASPEED 8888
+ #define MACH_TYPE_OMAP_2430SDP 900
+ #define MACH_TYPE_DAVINCI_EVM 901
+ #define MACH_TYPE_PALMZ72 904
+@@ -840,7 +850,6 @@ extern unsigned int __machine_arch_type;
+ #define MACH_TYPE_NV1000 3218
+ #define MACH_TYPE_NUC950TS 3219
+ #define MACH_TYPE_NOKIA_RM680 3220
+-#define MACH_TYPE_AST2200 3221
+ #define MACH_TYPE_LEAD 3222
+ #define MACH_TYPE_UNINO1 3223
+ #define MACH_TYPE_GREECO 3224
+@@ -3063,6 +3072,126 @@ extern unsigned int __machine_arch_type;
+ # define machine_is_wg302v2() (0)
+ #endif
+
++#ifdef CONFIG_MACH_AST1100
++# ifdef machine_arch_type
++# undef machine_arch_type
++# define machine_arch_type __machine_arch_type
++# else
++# define machine_arch_type MACH_TYPE_AST1100
++# endif
++# define machine_is_ast1100() (machine_arch_type == MACH_TYPE_AST1100)
++#else
++# define machine_is_ast1100() (0)
++#endif
++
++#ifdef CONFIG_MACH_AST2000
++# ifdef machine_arch_type
++# undef machine_arch_type
++# define machine_arch_type __machine_arch_type
++# else
++# define machine_arch_type MACH_TYPE_AST2000
++# endif
++# define machine_is_ast2000() (machine_arch_type == MACH_TYPE_AST2000)
++#else
++# define machine_is_ast2000() (0)
++#endif
++
++#ifdef CONFIG_MACH_AST2100
++# ifdef machine_arch_type
++# undef machine_arch_type
++# define machine_arch_type __machine_arch_type
++# else
++# define machine_arch_type MACH_TYPE_AST2100
++# endif
++# define machine_is_ast2100() (machine_arch_type == MACH_TYPE_AST2100)
++#else
++# define machine_is_ast2100() (0)
++#endif
++
++#ifdef CONFIG_MACH_AST2150
++# ifdef machine_arch_type
++# undef machine_arch_type
++# define machine_arch_type __machine_arch_type
++# else
++# define machine_arch_type MACH_TYPE_AST2150
++# endif
++# define machine_is_ast2150() (machine_arch_type == MACH_TYPE_AST2150)
++#else
++# define machine_is_ast2150() (0)
++#endif
++
++#ifdef CONFIG_MACH_AST2200
++# ifdef machine_arch_type
++# undef machine_arch_type
++# define machine_arch_type __machine_arch_type
++# else
++# define machine_arch_type MACH_TYPE_AST2200
++# endif
++# define machine_is_ast2200() (machine_arch_type == MACH_TYPE_AST2200)
++#else
++# define machine_is_ast2200() (0)
++#endif
++
++#ifdef CONFIG_MACH_AST2300_FPGA_1
++# ifdef machine_arch_type
++# undef machine_arch_type
++# define machine_arch_type __machine_arch_type
++# else
++# define machine_arch_type MACH_TYPE_AST2300_FPGA_1
++# endif
++# define machine_is_ast2300_fpga_1() (machine_arch_type == MACH_TYPE_AST2300_FPGA_1)
++#else
++# define machine_is_ast2300_fpga_1() (0)
++#endif
++
++#ifdef CONFIG_MACH_AST2300_FPGA_2
++# ifdef machine_arch_type
++# undef machine_arch_type
++# define machine_arch_type __machine_arch_type
++# else
++# define machine_arch_type MACH_TYPE_AST2300_FPGA_2
++# endif
++# define machine_is_ast2300_fpga_2() (machine_arch_type == MACH_TYPE_AST2300_FPGA_2)
++#else
++# define machine_is_ast2300_fpga_2() (0)
++#endif
++
++#ifdef CONFIG_MACH_AST3100
++# ifdef machine_arch_type
++# undef machine_arch_type
++# define machine_arch_type __machine_arch_type
++# else
++# define machine_arch_type MACH_TYPE_AST3100
++# endif
++# define machine_is_ast3100() (machine_arch_type == MACH_TYPE_AST3100)
++#else
++# define machine_is_ast3100() (0)
++#endif
++
++#ifdef CONFIG_MACH_ASPEED
++# ifdef machine_arch_type
++# undef machine_arch_type
++# define machine_arch_type __machine_arch_type
++# else
++# define machine_arch_type MACH_TYPE_ASPEED
++# endif
++# define machine_is_aspeed() (machine_arch_type == MACH_TYPE_ASPEED)
++#else
++# define machine_is_aspeed() (0)
++#endif
++
++#ifdef CONFIG_MACH_AST2300
++# ifdef machine_arch_type
++# undef machine_arch_type
++# define machine_arch_type __machine_arch_type
++# else
++# define machine_arch_type MACH_TYPE_AST2300
++# endif
++# define machine_is_ast2300() (machine_arch_type == MACH_TYPE_AST2300)
++#else
++# define machine_is_ast2300() (0)
++#endif
++
+ #ifdef CONFIG_MACH_OMAP_2430SDP
+ # ifdef machine_arch_type
+ # undef machine_arch_type
+@@ -11043,18 +11172,6 @@ extern unsigned int __machine_arch_type;
+ # define machine_is_nokia_rm680() (0)
+ #endif
+
+-#ifdef CONFIG_MACH_AST2200
+-# ifdef machine_arch_type
+-# undef machine_arch_type
+-# define machine_arch_type __machine_arch_type
+-# else
+-# define machine_arch_type MACH_TYPE_AST2200
+-# endif
+-# define machine_is_ast2200() (machine_arch_type == MACH_TYPE_AST2200)
+-#else
+-# define machine_is_ast2200() (0)
+-#endif
+-
+ #ifdef CONFIG_MACH_LEAD
+ # ifdef machine_arch_type
+ # undef machine_arch_type
+diff --git a/board/aspeed/ast2300/Makefile b/board/aspeed/ast2300/Makefile
+new file mode 100644
+index 0000000..d5300e6
+--- /dev/null
++++ b/board/aspeed/ast2300/Makefile
+@@ -0,0 +1,42 @@
++# 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$(BOARD).a
++
++COBJS = ast2300.o flash.o flash_spi.o pci.o crc32.o slt.o regtest.o vfun.o vhace.o crt.o videotest.o mactest.o hactest.o mictest.o
++
++ifdef CONFIG_FPGA_ASPEED
++SOBJS := platform_fpga.o
++else
++SOBJS := platform.o
++endif
++
++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS))
++SOBJS := $(addprefix $(obj),$(SOBJS))
++
++$(LIB): $(obj).depend $(OBJS) $(SOBJS)
++ $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
++
++clean:
++ rm -f $(SOBJS) $(OBJS)
++
++distclean: clean
++ rm -f $(LIB) core *.bak $(obj).depend
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude .depend
++
++#########################################################################
+diff --git a/board/aspeed/ast2300/aes.c b/board/aspeed/ast2300/aes.c
+new file mode 100755
+index 0000000..f30ab99
+--- /dev/null
++++ b/board/aspeed/ast2300/aes.c
+@@ -0,0 +1,573 @@
++/*
++ * AES implementation
++ * 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
++ */
++
++/* uncomment the following line to run the test suite */
++
++/* #define TEST */
++
++/* uncomment the following line to use pre-computed tables */
++/* otherwise the tables will be generated at the first run */
++
++#define FIXED_TABLES
++
++#ifndef FIXED_TABLES
++
++/* forward S-box & tables */
++
++uint32 FSb[256];
++uint32 FT0[256];
++uint32 FT1[256];
++uint32 FT2[256];
++uint32 FT3[256];
++
++/* reverse S-box & tables */
++
++uint32 RSb[256];
++uint32 RT0[256];
++uint32 RT1[256];
++uint32 RT2[256];
++uint32 RT3[256];
++
++/* round constants */
++
++uint32 RCON[10];
++
++/* tables generation flag */
++
++int do_init = 1;
++
++/* tables generation routine */
++
++#define ROTR8(x) ( ( ( x << 24 ) & 0xFFFFFFFF ) | \
++ ( ( x & 0xFFFFFFFF ) >> 8 ) )
++
++#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) )
++#define MUL(x,y) ( ( x && y ) ? pow[(log[x] + log[y]) % 255] : 0 )
++
++void aes_gen_tables( void )
++{
++ int i;
++ uint8 x, y;
++ uint8 pow[256];
++ uint8 log[256];
++
++ /* compute pow and log tables over GF(2^8) */
++
++ for( i = 0, x = 1; i < 256; i++, x ^= XTIME( x ) )
++ {
++ pow[i] = x;
++ log[x] = i;
++ }
++
++ /* calculate the round constants */
++
++ for( i = 0, x = 1; i < 10; i++, x = XTIME( x ) )
++ {
++ RCON[i] = (uint32) x << 24;
++ }
++
++ /* generate the forward and reverse S-boxes */
++
++ FSb[0x00] = 0x63;
++ RSb[0x63] = 0x00;
++
++ for( i = 1; i < 256; i++ )
++ {
++ x = pow[255 - log[i]];
++
++ y = x; y = ( y << 1 ) | ( y >> 7 );
++ x ^= y; y = ( y << 1 ) | ( y >> 7 );
++ x ^= y; y = ( y << 1 ) | ( y >> 7 );
++ x ^= y; y = ( y << 1 ) | ( y >> 7 );
++ x ^= y ^ 0x63;
++
++ FSb[i] = x;
++ RSb[x] = i;
++ }
++
++ /* generate the forward and reverse tables */
++
++ for( i = 0; i < 256; i++ )
++ {
++ x = (unsigned char) FSb[i]; y = XTIME( x );
++
++ FT0[i] = (uint32) ( x ^ y ) ^
++ ( (uint32) x << 8 ) ^
++ ( (uint32) x << 16 ) ^
++ ( (uint32) y << 24 );
++
++ FT0[i] &= 0xFFFFFFFF;
++
++ FT1[i] = ROTR8( FT0[i] );
++ FT2[i] = ROTR8( FT1[i] );
++ FT3[i] = ROTR8( FT2[i] );
++
++ y = (unsigned char) RSb[i];
++
++ RT0[i] = ( (uint32) MUL( 0x0B, y ) ) ^
++ ( (uint32) MUL( 0x0D, y ) << 8 ) ^
++ ( (uint32) MUL( 0x09, y ) << 16 ) ^
++ ( (uint32) MUL( 0x0E, y ) << 24 );
++
++ RT0[i] &= 0xFFFFFFFF;
++
++ RT1[i] = ROTR8( RT0[i] );
++ RT2[i] = ROTR8( RT1[i] );
++ RT3[i] = ROTR8( RT2[i] );
++ }
++}
++
++#else
++
++/* forward S-box */
++
++static const uint32 FSb[256] =
++{
++ 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
++ 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
++ 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
++ 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
++ 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
++ 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
++ 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
++ 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
++ 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
++ 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
++ 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
++ 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
++ 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
++ 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
++ 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
++ 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
++ 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
++ 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
++ 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
++ 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
++ 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
++ 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
++ 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
++ 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
++ 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
++ 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
++ 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
++ 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
++ 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
++ 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
++ 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
++ 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
++};
++
++/* forward tables */
++
++#define FT \
++\
++ V(C6,63,63,A5), V(F8,7C,7C,84), V(EE,77,77,99), V(F6,7B,7B,8D), \
++ V(FF,F2,F2,0D), V(D6,6B,6B,BD), V(DE,6F,6F,B1), V(91,C5,C5,54), \
++ V(60,30,30,50), V(02,01,01,03), V(CE,67,67,A9), V(56,2B,2B,7D), \
++ V(E7,FE,FE,19), V(B5,D7,D7,62), V(4D,AB,AB,E6), V(EC,76,76,9A), \
++ V(8F,CA,CA,45), V(1F,82,82,9D), V(89,C9,C9,40), V(FA,7D,7D,87), \
++ V(EF,FA,FA,15), V(B2,59,59,EB), V(8E,47,47,C9), V(FB,F0,F0,0B), \
++ V(41,AD,AD,EC), V(B3,D4,D4,67), V(5F,A2,A2,FD), V(45,AF,AF,EA), \
++ V(23,9C,9C,BF), V(53,A4,A4,F7), V(E4,72,72,96), V(9B,C0,C0,5B), \
++ V(75,B7,B7,C2), V(E1,FD,FD,1C), V(3D,93,93,AE), V(4C,26,26,6A), \
++ V(6C,36,36,5A), V(7E,3F,3F,41), V(F5,F7,F7,02), V(83,CC,CC,4F), \
++ V(68,34,34,5C), V(51,A5,A5,F4), V(D1,E5,E5,34), V(F9,F1,F1,08), \
++ V(E2,71,71,93), V(AB,D8,D8,73), V(62,31,31,53), V(2A,15,15,3F), \
++ V(08,04,04,0C), V(95,C7,C7,52), V(46,23,23,65), V(9D,C3,C3,5E), \
++ V(30,18,18,28), V(37,96,96,A1), V(0A,05,05,0F), V(2F,9A,9A,B5), \
++ V(0E,07,07,09), V(24,12,12,36), V(1B,80,80,9B), V(DF,E2,E2,3D), \
++ V(CD,EB,EB,26), V(4E,27,27,69), V(7F,B2,B2,CD), V(EA,75,75,9F), \
++ V(12,09,09,1B), V(1D,83,83,9E), V(58,2C,2C,74), V(34,1A,1A,2E), \
++ V(36,1B,1B,2D), V(DC,6E,6E,B2), V(B4,5A,5A,EE), V(5B,A0,A0,FB), \
++ V(A4,52,52,F6), V(76,3B,3B,4D), V(B7,D6,D6,61), V(7D,B3,B3,CE), \
++ V(52,29,29,7B), V(DD,E3,E3,3E), V(5E,2F,2F,71), V(13,84,84,97), \
++ V(A6,53,53,F5), V(B9,D1,D1,68), V(00,00,00,00), V(C1,ED,ED,2C), \
++ V(40,20,20,60), V(E3,FC,FC,1F), V(79,B1,B1,C8), V(B6,5B,5B,ED), \
++ V(D4,6A,6A,BE), V(8D,CB,CB,46), V(67,BE,BE,D9), V(72,39,39,4B), \
++ V(94,4A,4A,DE), V(98,4C,4C,D4), V(B0,58,58,E8), V(85,CF,CF,4A), \
++ V(BB,D0,D0,6B), V(C5,EF,EF,2A), V(4F,AA,AA,E5), V(ED,FB,FB,16), \
++ V(86,43,43,C5), V(9A,4D,4D,D7), V(66,33,33,55), V(11,85,85,94), \
++ V(8A,45,45,CF), V(E9,F9,F9,10), V(04,02,02,06), V(FE,7F,7F,81), \
++ V(A0,50,50,F0), V(78,3C,3C,44), V(25,9F,9F,BA), V(4B,A8,A8,E3), \
++ V(A2,51,51,F3), V(5D,A3,A3,FE), V(80,40,40,C0), V(05,8F,8F,8A), \
++ V(3F,92,92,AD), V(21,9D,9D,BC), V(70,38,38,48), V(F1,F5,F5,04), \
++ V(63,BC,BC,DF), V(77,B6,B6,C1), V(AF,DA,DA,75), V(42,21,21,63), \
++ V(20,10,10,30), V(E5,FF,FF,1A), V(FD,F3,F3,0E), V(BF,D2,D2,6D), \
++ V(81,CD,CD,4C), V(18,0C,0C,14), V(26,13,13,35), V(C3,EC,EC,2F), \
++ V(BE,5F,5F,E1), V(35,97,97,A2), V(88,44,44,CC), V(2E,17,17,39), \
++ V(93,C4,C4,57), V(55,A7,A7,F2), V(FC,7E,7E,82), V(7A,3D,3D,47), \
++ V(C8,64,64,AC), V(BA,5D,5D,E7), V(32,19,19,2B), V(E6,73,73,95), \
++ V(C0,60,60,A0), V(19,81,81,98), V(9E,4F,4F,D1), V(A3,DC,DC,7F), \
++ V(44,22,22,66), V(54,2A,2A,7E), V(3B,90,90,AB), V(0B,88,88,83), \
++ V(8C,46,46,CA), V(C7,EE,EE,29), V(6B,B8,B8,D3), V(28,14,14,3C), \
++ V(A7,DE,DE,79), V(BC,5E,5E,E2), V(16,0B,0B,1D), V(AD,DB,DB,76), \
++ V(DB,E0,E0,3B), V(64,32,32,56), V(74,3A,3A,4E), V(14,0A,0A,1E), \
++ V(92,49,49,DB), V(0C,06,06,0A), V(48,24,24,6C), V(B8,5C,5C,E4), \
++ V(9F,C2,C2,5D), V(BD,D3,D3,6E), V(43,AC,AC,EF), V(C4,62,62,A6), \
++ V(39,91,91,A8), V(31,95,95,A4), V(D3,E4,E4,37), V(F2,79,79,8B), \
++ V(D5,E7,E7,32), V(8B,C8,C8,43), V(6E,37,37,59), V(DA,6D,6D,B7), \
++ V(01,8D,8D,8C), V(B1,D5,D5,64), V(9C,4E,4E,D2), V(49,A9,A9,E0), \
++ V(D8,6C,6C,B4), V(AC,56,56,FA), V(F3,F4,F4,07), V(CF,EA,EA,25), \
++ V(CA,65,65,AF), V(F4,7A,7A,8E), V(47,AE,AE,E9), V(10,08,08,18), \
++ V(6F,BA,BA,D5), V(F0,78,78,88), V(4A,25,25,6F), V(5C,2E,2E,72), \
++ V(38,1C,1C,24), V(57,A6,A6,F1), V(73,B4,B4,C7), V(97,C6,C6,51), \
++ V(CB,E8,E8,23), V(A1,DD,DD,7C), V(E8,74,74,9C), V(3E,1F,1F,21), \
++ V(96,4B,4B,DD), V(61,BD,BD,DC), V(0D,8B,8B,86), V(0F,8A,8A,85), \
++ V(E0,70,70,90), V(7C,3E,3E,42), V(71,B5,B5,C4), V(CC,66,66,AA), \
++ V(90,48,48,D8), V(06,03,03,05), V(F7,F6,F6,01), V(1C,0E,0E,12), \
++ V(C2,61,61,A3), V(6A,35,35,5F), V(AE,57,57,F9), V(69,B9,B9,D0), \
++ V(17,86,86,91), V(99,C1,C1,58), V(3A,1D,1D,27), V(27,9E,9E,B9), \
++ V(D9,E1,E1,38), V(EB,F8,F8,13), V(2B,98,98,B3), V(22,11,11,33), \
++ V(D2,69,69,BB), V(A9,D9,D9,70), V(07,8E,8E,89), V(33,94,94,A7), \
++ V(2D,9B,9B,B6), V(3C,1E,1E,22), V(15,87,87,92), V(C9,E9,E9,20), \
++ V(87,CE,CE,49), V(AA,55,55,FF), V(50,28,28,78), V(A5,DF,DF,7A), \
++ V(03,8C,8C,8F), V(59,A1,A1,F8), V(09,89,89,80), V(1A,0D,0D,17), \
++ V(65,BF,BF,DA), V(D7,E6,E6,31), V(84,42,42,C6), V(D0,68,68,B8), \
++ V(82,41,41,C3), V(29,99,99,B0), V(5A,2D,2D,77), V(1E,0F,0F,11), \
++ V(7B,B0,B0,CB), V(A8,54,54,FC), V(6D,BB,BB,D6), V(2C,16,16,3A)
++
++#define V(a,b,c,d) 0x##a##b##c##d
++static const uint32 FT0[256] = { FT };
++#undef V
++
++#define V(a,b,c,d) 0x##d##a##b##c
++static const uint32 FT1[256] = { FT };
++#undef V
++
++#define V(a,b,c,d) 0x##c##d##a##b
++static const uint32 FT2[256] = { FT };
++#undef V
++
++#define V(a,b,c,d) 0x##b##c##d##a
++static const uint32 FT3[256] = { FT };
++#undef V
++
++#undef FT
++
++/* reverse S-box */
++
++static const uint32 RSb[256] =
++{
++ 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
++ 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
++ 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
++ 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
++ 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
++ 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
++ 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
++ 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
++ 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
++ 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
++ 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
++ 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
++ 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
++ 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
++ 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
++ 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
++ 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
++ 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
++ 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
++ 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
++ 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
++ 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
++ 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
++ 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
++ 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
++ 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
++ 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
++ 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
++ 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
++ 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
++ 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
++ 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
++};
++
++/* reverse tables */
++
++#define RT \
++\
++ V(51,F4,A7,50), V(7E,41,65,53), V(1A,17,A4,C3), V(3A,27,5E,96), \
++ V(3B,AB,6B,CB), V(1F,9D,45,F1), V(AC,FA,58,AB), V(4B,E3,03,93), \
++ V(20,30,FA,55), V(AD,76,6D,F6), V(88,CC,76,91), V(F5,02,4C,25), \
++ V(4F,E5,D7,FC), V(C5,2A,CB,D7), V(26,35,44,80), V(B5,62,A3,8F), \
++ V(DE,B1,5A,49), V(25,BA,1B,67), V(45,EA,0E,98), V(5D,FE,C0,E1), \
++ V(C3,2F,75,02), V(81,4C,F0,12), V(8D,46,97,A3), V(6B,D3,F9,C6), \
++ V(03,8F,5F,E7), V(15,92,9C,95), V(BF,6D,7A,EB), V(95,52,59,DA), \
++ V(D4,BE,83,2D), V(58,74,21,D3), V(49,E0,69,29), V(8E,C9,C8,44), \
++ V(75,C2,89,6A), V(F4,8E,79,78), V(99,58,3E,6B), V(27,B9,71,DD), \
++ V(BE,E1,4F,B6), V(F0,88,AD,17), V(C9,20,AC,66), V(7D,CE,3A,B4), \
++ V(63,DF,4A,18), V(E5,1A,31,82), V(97,51,33,60), V(62,53,7F,45), \
++ V(B1,64,77,E0), V(BB,6B,AE,84), V(FE,81,A0,1C), V(F9,08,2B,94), \
++ V(70,48,68,58), V(8F,45,FD,19), V(94,DE,6C,87), V(52,7B,F8,B7), \
++ V(AB,73,D3,23), V(72,4B,02,E2), V(E3,1F,8F,57), V(66,55,AB,2A), \
++ V(B2,EB,28,07), V(2F,B5,C2,03), V(86,C5,7B,9A), V(D3,37,08,A5), \
++ V(30,28,87,F2), V(23,BF,A5,B2), V(02,03,6A,BA), V(ED,16,82,5C), \
++ V(8A,CF,1C,2B), V(A7,79,B4,92), V(F3,07,F2,F0), V(4E,69,E2,A1), \
++ V(65,DA,F4,CD), V(06,05,BE,D5), V(D1,34,62,1F), V(C4,A6,FE,8A), \
++ V(34,2E,53,9D), V(A2,F3,55,A0), V(05,8A,E1,32), V(A4,F6,EB,75), \
++ V(0B,83,EC,39), V(40,60,EF,AA), V(5E,71,9F,06), V(BD,6E,10,51), \
++ V(3E,21,8A,F9), V(96,DD,06,3D), V(DD,3E,05,AE), V(4D,E6,BD,46), \
++ V(91,54,8D,B5), V(71,C4,5D,05), V(04,06,D4,6F), V(60,50,15,FF), \
++ V(19,98,FB,24), V(D6,BD,E9,97), V(89,40,43,CC), V(67,D9,9E,77), \
++ V(B0,E8,42,BD), V(07,89,8B,88), V(E7,19,5B,38), V(79,C8,EE,DB), \
++ V(A1,7C,0A,47), V(7C,42,0F,E9), V(F8,84,1E,C9), V(00,00,00,00), \
++ V(09,80,86,83), V(32,2B,ED,48), V(1E,11,70,AC), V(6C,5A,72,4E), \
++ V(FD,0E,FF,FB), V(0F,85,38,56), V(3D,AE,D5,1E), V(36,2D,39,27), \
++ V(0A,0F,D9,64), V(68,5C,A6,21), V(9B,5B,54,D1), V(24,36,2E,3A), \
++ V(0C,0A,67,B1), V(93,57,E7,0F), V(B4,EE,96,D2), V(1B,9B,91,9E), \
++ V(80,C0,C5,4F), V(61,DC,20,A2), V(5A,77,4B,69), V(1C,12,1A,16), \
++ V(E2,93,BA,0A), V(C0,A0,2A,E5), V(3C,22,E0,43), V(12,1B,17,1D), \
++ V(0E,09,0D,0B), V(F2,8B,C7,AD), V(2D,B6,A8,B9), V(14,1E,A9,C8), \
++ V(57,F1,19,85), V(AF,75,07,4C), V(EE,99,DD,BB), V(A3,7F,60,FD), \
++ V(F7,01,26,9F), V(5C,72,F5,BC), V(44,66,3B,C5), V(5B,FB,7E,34), \
++ V(8B,43,29,76), V(CB,23,C6,DC), V(B6,ED,FC,68), V(B8,E4,F1,63), \
++ V(D7,31,DC,CA), V(42,63,85,10), V(13,97,22,40), V(84,C6,11,20), \
++ V(85,4A,24,7D), V(D2,BB,3D,F8), V(AE,F9,32,11), V(C7,29,A1,6D), \
++ V(1D,9E,2F,4B), V(DC,B2,30,F3), V(0D,86,52,EC), V(77,C1,E3,D0), \
++ V(2B,B3,16,6C), V(A9,70,B9,99), V(11,94,48,FA), V(47,E9,64,22), \
++ V(A8,FC,8C,C4), V(A0,F0,3F,1A), V(56,7D,2C,D8), V(22,33,90,EF), \
++ V(87,49,4E,C7), V(D9,38,D1,C1), V(8C,CA,A2,FE), V(98,D4,0B,36), \
++ V(A6,F5,81,CF), V(A5,7A,DE,28), V(DA,B7,8E,26), V(3F,AD,BF,A4), \
++ V(2C,3A,9D,E4), V(50,78,92,0D), V(6A,5F,CC,9B), V(54,7E,46,62), \
++ V(F6,8D,13,C2), V(90,D8,B8,E8), V(2E,39,F7,5E), V(82,C3,AF,F5), \
++ V(9F,5D,80,BE), V(69,D0,93,7C), V(6F,D5,2D,A9), V(CF,25,12,B3), \
++ V(C8,AC,99,3B), V(10,18,7D,A7), V(E8,9C,63,6E), V(DB,3B,BB,7B), \
++ V(CD,26,78,09), V(6E,59,18,F4), V(EC,9A,B7,01), V(83,4F,9A,A8), \
++ V(E6,95,6E,65), V(AA,FF,E6,7E), V(21,BC,CF,08), V(EF,15,E8,E6), \
++ V(BA,E7,9B,D9), V(4A,6F,36,CE), V(EA,9F,09,D4), V(29,B0,7C,D6), \
++ V(31,A4,B2,AF), V(2A,3F,23,31), V(C6,A5,94,30), V(35,A2,66,C0), \
++ V(74,4E,BC,37), V(FC,82,CA,A6), V(E0,90,D0,B0), V(33,A7,D8,15), \
++ V(F1,04,98,4A), V(41,EC,DA,F7), V(7F,CD,50,0E), V(17,91,F6,2F), \
++ V(76,4D,D6,8D), V(43,EF,B0,4D), V(CC,AA,4D,54), V(E4,96,04,DF), \
++ V(9E,D1,B5,E3), V(4C,6A,88,1B), V(C1,2C,1F,B8), V(46,65,51,7F), \
++ V(9D,5E,EA,04), V(01,8C,35,5D), V(FA,87,74,73), V(FB,0B,41,2E), \
++ V(B3,67,1D,5A), V(92,DB,D2,52), V(E9,10,56,33), V(6D,D6,47,13), \
++ V(9A,D7,61,8C), V(37,A1,0C,7A), V(59,F8,14,8E), V(EB,13,3C,89), \
++ V(CE,A9,27,EE), V(B7,61,C9,35), V(E1,1C,E5,ED), V(7A,47,B1,3C), \
++ V(9C,D2,DF,59), V(55,F2,73,3F), V(18,14,CE,79), V(73,C7,37,BF), \
++ V(53,F7,CD,EA), V(5F,FD,AA,5B), V(DF,3D,6F,14), V(78,44,DB,86), \
++ V(CA,AF,F3,81), V(B9,68,C4,3E), V(38,24,34,2C), V(C2,A3,40,5F), \
++ V(16,1D,C3,72), V(BC,E2,25,0C), V(28,3C,49,8B), V(FF,0D,95,41), \
++ V(39,A8,01,71), V(08,0C,B3,DE), V(D8,B4,E4,9C), V(64,56,C1,90), \
++ V(7B,CB,84,61), V(D5,32,B6,70), V(48,6C,5C,74), V(D0,B8,57,42)
++
++#define V(a,b,c,d) 0x##a##b##c##d
++static const uint32 RT0[256] = { RT };
++#undef V
++
++#define V(a,b,c,d) 0x##d##a##b##c
++static const uint32 RT1[256] = { RT };
++#undef V
++
++#define V(a,b,c,d) 0x##c##d##a##b
++static const uint32 RT2[256] = { RT };
++#undef V
++
++#define V(a,b,c,d) 0x##b##c##d##a
++static const uint32 RT3[256] = { RT };
++#undef V
++
++#undef RT
++
++/* round constants */
++
++static const uint32 RCON[10] =
++{
++ 0x01000000, 0x02000000, 0x04000000, 0x08000000,
++ 0x10000000, 0x20000000, 0x40000000, 0x80000000,
++ 0x1B000000, 0x36000000
++};
++
++int do_init = 0;
++
++void aes_gen_tables( void )
++{
++}
++
++#endif
++
++/* platform-independant 32-bit integer manipulation macros */
++
++#define GET_UINT32_aes(n,b,i) \
++{ \
++ (n) = ( (uint32) (b)[(i) ] << 24 ) \
++ | ( (uint32) (b)[(i) + 1] << 16 ) \
++ | ( (uint32) (b)[(i) + 2] << 8 ) \
++ | ( (uint32) (b)[(i) + 3] ); \
++}
++
++#define PUT_UINT32_aes(n,b,i) \
++{ \
++ (b)[(i) ] = (uint8) ( (n) >> 24 ); \
++ (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \
++ (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \
++ (b)[(i) + 3] = (uint8) ( (n) ); \
++}
++
++/* decryption key schedule tables */
++
++int KT_init = 1;
++
++uint32 KT0[256];
++uint32 KT1[256];
++uint32 KT2[256];
++uint32 KT3[256];
++
++/* AES key scheduling routine */
++int aes_set_key( aes_context *ctx, uint8 *key, int nbits )
++{
++ int i;
++ uint32 *RK, *SK;
++
++ if( do_init )
++ {
++ aes_gen_tables();
++
++ do_init = 0;
++ }
++
++ switch( nbits )
++ {
++ case 128: ctx->nr = 10; break;
++ case 192: ctx->nr = 12; break;
++ case 256: ctx->nr = 14; break;
++ default : return( 1 );
++ }
++
++ RK = ctx->erk;
++
++ for( i = 0; i < (nbits >> 5); i++ )
++ {
++ GET_UINT32_aes( RK[i], key, i * 4 );
++ }
++
++ /* setup encryption round keys */
++
++ switch( nbits )
++ {
++ case 128:
++
++ for( i = 0; i < 10; i++, RK += 4 )
++ {
++ RK[4] = RK[0] ^ RCON[i] ^
++ ( FSb[ (uint8) ( RK[3] >> 16 ) ] << 24 ) ^
++ ( FSb[ (uint8) ( RK[3] >> 8 ) ] << 16 ) ^
++ ( FSb[ (uint8) ( RK[3] ) ] << 8 ) ^
++ ( FSb[ (uint8) ( RK[3] >> 24 ) ] );
++
++ RK[5] = RK[1] ^ RK[4];
++ RK[6] = RK[2] ^ RK[5];
++ RK[7] = RK[3] ^ RK[6];
++ }
++ break;
++
++ case 192:
++
++ for( i = 0; i < 8; i++, RK += 6 )
++ {
++ RK[6] = RK[0] ^ RCON[i] ^
++ ( FSb[ (uint8) ( RK[5] >> 16 ) ] << 24 ) ^
++ ( FSb[ (uint8) ( RK[5] >> 8 ) ] << 16 ) ^
++ ( FSb[ (uint8) ( RK[5] ) ] << 8 ) ^
++ ( FSb[ (uint8) ( RK[5] >> 24 ) ] );
++
++ RK[7] = RK[1] ^ RK[6];
++ RK[8] = RK[2] ^ RK[7];
++ RK[9] = RK[3] ^ RK[8];
++ RK[10] = RK[4] ^ RK[9];
++ RK[11] = RK[5] ^ RK[10];
++ }
++ break;
++
++ case 256:
++
++ for( i = 0; i < 7; i++, RK += 8 )
++ {
++ RK[8] = RK[0] ^ RCON[i] ^
++ ( FSb[ (uint8) ( RK[7] >> 16 ) ] << 24 ) ^
++ ( FSb[ (uint8) ( RK[7] >> 8 ) ] << 16 ) ^
++ ( FSb[ (uint8) ( RK[7] ) ] << 8 ) ^
++ ( FSb[ (uint8) ( RK[7] >> 24 ) ] );
++
++ RK[9] = RK[1] ^ RK[8];
++ RK[10] = RK[2] ^ RK[9];
++ RK[11] = RK[3] ^ RK[10];
++
++ RK[12] = RK[4] ^
++ ( FSb[ (uint8) ( RK[11] >> 24 ) ] << 24 ) ^
++ ( FSb[ (uint8) ( RK[11] >> 16 ) ] << 16 ) ^
++ ( FSb[ (uint8) ( RK[11] >> 8 ) ] << 8 ) ^
++ ( FSb[ (uint8) ( RK[11] ) ] );
++
++ RK[13] = RK[5] ^ RK[12];
++ RK[14] = RK[6] ^ RK[13];
++ RK[15] = RK[7] ^ RK[14];
++ }
++ break;
++ }
++
++ /* setup decryption round keys */
++
++ if( KT_init )
++ {
++ for( i = 0; i < 256; i++ )
++ {
++ KT0[i] = RT0[ FSb[i] ];
++ KT1[i] = RT1[ FSb[i] ];
++ KT2[i] = RT2[ FSb[i] ];
++ KT3[i] = RT3[ FSb[i] ];
++ }
++
++ KT_init = 0;
++ }
++
++ SK = ctx->drk;
++
++ *SK++ = *RK++;
++ *SK++ = *RK++;
++ *SK++ = *RK++;
++ *SK++ = *RK++;
++
++ for( i = 1; i < ctx->nr; i++ )
++ {
++ RK -= 8;
++
++ *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
++ KT1[ (uint8) ( *RK >> 16 ) ] ^
++ KT2[ (uint8) ( *RK >> 8 ) ] ^
++ KT3[ (uint8) ( *RK ) ]; RK++;
++
++ *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
++ KT1[ (uint8) ( *RK >> 16 ) ] ^
++ KT2[ (uint8) ( *RK >> 8 ) ] ^
++ KT3[ (uint8) ( *RK ) ]; RK++;
++
++ *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
++ KT1[ (uint8) ( *RK >> 16 ) ] ^
++ KT2[ (uint8) ( *RK >> 8 ) ] ^
++ KT3[ (uint8) ( *RK ) ]; RK++;
++
++ *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
++ KT1[ (uint8) ( *RK >> 16 ) ] ^
++ KT2[ (uint8) ( *RK >> 8 ) ] ^
++ KT3[ (uint8) ( *RK ) ]; RK++;
++ }
++
++ RK -= 8;
++
++ *SK++ = *RK++;
++ *SK++ = *RK++;
++ *SK++ = *RK++;
++ *SK++ = *RK++;
++
++ return( 0 );
++}
+diff --git a/board/aspeed/ast2300/ast2300.c b/board/aspeed/ast2300/ast2300.c
+new file mode 100644
+index 0000000..b317786
+--- /dev/null
++++ b/board/aspeed/ast2300/ast2300.c
+@@ -0,0 +1,171 @@
++/*
++ * 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 <common.h>
++#include <command.h>
++#include <pci.h>
++
++int board_init (void)
++{
++ DECLARE_GLOBAL_DATA_PTR;
++ unsigned char data;
++ unsigned long reg;
++
++ /* AHB Controller */
++ *((volatile ulong*) 0x1E600000) = 0xAEED1A03; /* unlock AHB controller */
++ *((volatile ulong*) 0x1E60008C) |= 0x01; /* map DRAM to 0x00000000 */
++#ifdef CONFIG_PCI
++ *((volatile ulong*) 0x1E60008C) |= 0x30; /* map PCI */
++#endif
++
++ /* Flash Controller */
++#ifdef CONFIG_FLASH_AST2300
++ *((volatile ulong*) 0x1e620000) |= 0x800f0000; /* enable Flash Write */
++#else
++ *((volatile ulong*) 0x16000000) |= 0x00001c00; /* enable Flash Write */
++#endif
++
++ /* SCU */
++ *((volatile ulong*) 0x1e6e2000) = 0x1688A8A8; /* unlock SCU */
++ reg = *((volatile ulong*) 0x1e6e2008);
++ reg &= 0x1c0fffff;
++ reg |= 0x61800000; /* PCLK = HPLL/8 */
++#ifdef CONFIG_AST1070
++ reg |= 0x300000; /* LHCLK = HPLL/8 */
++ reg |= 0x80000; /* LPC Host Clock */
++#endif
++ *((volatile ulong*) 0x1e6e2008) = reg;
++ reg = *((volatile ulong*) 0x1e6e200c); /* enable 2D Clk */
++ *((volatile ulong*) 0x1e6e200c) &= 0xFFFFFFFD;
++/* enable wide screen. If your video driver does not support wide screen, don't
++enable this bit 0x1e6e2040 D[0]*/
++ reg = *((volatile ulong*) 0x1e6e2040);
++ *((volatile ulong*) 0x1e6e2040) |= 0x01;
++#ifdef CONFIG_AST1070
++/*set VPPL1 */
++
++ *((volatile ulong*) 0x1e6e201c) = 0x6420;
++
++// set d2-pll & enable d2-pll D[21:20], D[4]
++ reg = *((volatile ulong*) 0x1e6e202c);
++ reg &= 0xffcfffef;
++ reg |= 0x00200010;
++ *((volatile ulong*) 0x1e6e202c) = reg;
++
++// set OSCCLK = VPLL1
++ *((volatile ulong*) 0x1e6e2010) = 0x8;
++
++// enable OSCCLK
++ reg = *((volatile ulong*) 0x1e6e202c);
++ reg &= 0xfffffffd;
++ reg |= 0x00000002;
++ *((volatile ulong*) 0x1e6e202c) = reg;
++
++// enable AST1050's LPC master
++ reg = *((volatile ulong*) 0x1e7890a0);
++ *((volatile ulong*) 0x1e7890a0) |= 0x11;
++#endif
++ /* arch number */
++ gd->bd->bi_arch_number = MACH_TYPE_ASPEED;
++
++ /* adress of boot parameters */
++ gd->bd->bi_boot_params = 0x40000100;
++
++ return 0;
++}
++
++int dram_init (void)
++{
++ DECLARE_GLOBAL_DATA_PTR;
++
++ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
++ gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
++
++ return 0;
++}
++
++/*
++SCU7C: Silicon Revision ID Register
++D[31:24]: Chip ID
++0: AST2050/AST2100/AST2150/AST2200/AST3000
++1: AST2300
++
++D[23:16] Silicon revision ID for AST2300 generation and later
++0: A0
++1: A1
++2: A2
++.
++.
++.
++FPGA revision starts from 0x80
++
++
++D[11:8] Bounding option
++
++D[7:0] Silicon revision ID for AST2050/AST2100 generation (for software compatible)
++0: A0
++1: A1
++2: A2
++3: A3
++.
++.
++FPGA revision starts from 0x08, 8~10 means A0, 11+ means A1, AST2300 should be assigned to 3
++*/
++int misc_init_r(void)
++{
++ unsigned int reg1, revision, chip_id;
++
++ /* Show H/W Version */
++ reg1 = (unsigned int) (*((ulong*) 0x1e6e207c));
++ chip_id = (reg1 & 0xff000000) >> 24;
++ revision = (reg1 & 0xff0000) >> 16;
++
++ puts ("H/W: ");
++ if (chip_id == 1) {
++ if (revision >= 0x80) {
++ printf("AST2300 series FPGA Rev. %02x \n", revision);
++ }
++ else {
++ printf("AST2300 series chip Rev. %02x \n", revision);
++ }
++ }
++ else if (chip_id == 0) {
++ printf("AST2050/AST2150 series chip\n");
++ }
++
++#ifdef CONFIG_AST1070
++ puts ("C/C: ");
++ revision = (unsigned int) (*((ulong*) 0x60002034));
++ printf("AST1070 ID [%08x] \n", revision);
++#endif
++
++#ifdef CONFIG_PCI
++ pci_init ();
++#endif
++
++ if (getenv ("verify") == NULL) {
++ setenv ("verify", "n");
++ }
++ if (getenv ("eeprom") == NULL) {
++ setenv ("eeprom", "y");
++ }
++}
++
++#ifdef CONFIG_PCI
++static struct pci_controller hose;
++
++extern void aspeed_init_pci (struct pci_controller *hose);
++
++void pci_init_board(void)
++{
++ aspeed_init_pci(&hose);
++}
++#endif
+diff --git a/board/aspeed/ast2300/config.mk b/board/aspeed/ast2300/config.mk
+new file mode 100755
+index 0000000..24ca09b
+--- /dev/null
++++ b/board/aspeed/ast2300/config.mk
+@@ -0,0 +1,18 @@
++# 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
++#
++
++# ROM version
++#TEXT_BASE = 0xBFC00000
++
++# RAM version
++TEXT_BASE = 0x40500000
++#TEXT_BASE = 0x00000000
++#TEXT_BASE = 0x00400000
+diff --git a/board/aspeed/ast2300/crc32.c b/board/aspeed/ast2300/crc32.c
+new file mode 100755
+index 0000000..cc8d2ac
+--- /dev/null
++++ b/board/aspeed/ast2300/crc32.c
+@@ -0,0 +1,127 @@
++/*
++ * 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 <common.h>
++#include <asm/processor.h>
++#include <asm/byteorder.h>
++#include <environment.h>
++
++#ifdef CONFIG_2SPIFLASH
++
++extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
++
++/* ========================================================================
++ * Table of CRC-32's of all single-byte values (made by make_aspeed_crc_table)
++ */
++unsigned long aspeed_crc_table[256] = {
++ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
++ 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
++ 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
++ 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
++ 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
++ 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
++ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
++ 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
++ 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
++ 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
++ 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
++ 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
++ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
++ 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
++ 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
++ 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
++ 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
++ 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
++ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
++ 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
++ 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
++ 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
++ 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
++ 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
++ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
++ 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
++ 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
++ 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
++ 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
++ 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
++ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
++ 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
++ 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
++ 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
++ 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
++ 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
++ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
++ 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
++ 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
++ 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
++ 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
++ 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
++ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
++ 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
++ 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
++ 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
++ 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
++ 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
++ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
++ 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
++ 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
++ 0x2d02ef8dL
++};
++
++/* ========================================================================= */
++#define ASPEED_DO1(buf) crc = aspeed_crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
++#define ASPEED_DO2(buf) ASPEED_DO1(buf); ASPEED_DO1(buf);
++#define ASPEED_DO4(buf) ASPEED_DO2(buf); ASPEED_DO2(buf);
++#define ASPEED_DO8(buf) ASPEED_DO4(buf); ASPEED_DO4(buf);
++
++/* ========================================================================= */
++unsigned long spi2_crc32(crc, buf, len)
++ unsigned long crc;
++ unsigned char *buf;
++ unsigned long len;
++{
++
++ size_t len1, len2;
++ char *s;
++
++ len1 = len2 = 0;
++ if ( (ulong)(buf) <= (flash_info[0].start[0] + flash_info[0].size) )
++ len1 = (flash_info[0].start[0] + flash_info[0].size) - (ulong)(buf);
++
++ len1 = (len < len1) ? len:len1;
++ len2 = (len < len1) ? 0: (len - len1);
++
++ crc = crc ^ 0xffffffffL;
++ while (len1 >= 8)
++ {
++ ASPEED_DO8(buf);
++ len1 -= 8;
++ }
++ if (len1) do {
++ ASPEED_DO1(buf);
++ } while (--len1);
++
++ //s = (char *) flash_info[1].start[0];
++ s= (char *) flash_make_addr (&flash_info[1], 0, 0);
++ while (len2 >= 8)
++ {
++ ASPEED_DO8(s);
++ len2 -= 8;
++ }
++ if (len2) do {
++ ASPEED_DO1(s);
++ } while (--len2);
++
++ return crc ^ 0xffffffffL;
++
++}
++
++#endif /* CONFIG_2SPIFLASH */
++
+diff --git a/board/aspeed/ast2300/crt.c b/board/aspeed/ast2300/crt.c
+new file mode 100755
+index 0000000..b67f669
+--- /dev/null
++++ b/board/aspeed/ast2300/crt.c
+@@ -0,0 +1,322 @@
++/*
++ * 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 <common.h>
++#include <command.h>
++
++#include "type.h"
++#include "vesa.h"
++#include "vdef.h"
++#include "vfun.h"
++#include "vreg.h"
++#include "crt.h"
++
++ULONG AST3000DCLKTableV [] = {
++ 0x00046515, /* 00: VCLK25_175 */
++ 0x00047255, /* 01: VCLK28_322 */
++ 0x0004682a, /* 02: VCLK31_5 */
++ 0x0004672a, /* 03: VCLK36 */
++ 0x00046c50, /* 04: VCLK40 */
++ 0x00046842, /* 05: VCLK49_5 */
++ 0x00006c32, /* 06: VCLK50 */
++ 0x00006a2f, /* 07: VCLK56_25 */
++ 0x00006c41, /* 08: VCLK65 */
++ 0x00006832, /* 09: VCLK75 */
++ 0x0000672e, /* 0A: VCLK78_75 */
++ 0x0000683f, /* 0B: VCLK94_5 */
++ 0x00004824, /* 0C: VCLK108 */
++ 0x00004723, /* 0D: VCLK119 */
++ 0x0000482d, /* 0E: VCLK135 */
++ 0x00004B37, /* 0F: VCLK146_25 */
++ 0x0000472e, /* 10: VCLK157_5 */
++ 0x00004836, /* 11: VCLK162 */
++
++};
++
++BOOL CheckDAC(int nCRTIndex)
++{
++ BYTE btValue;
++ BOOL bValue;
++
++ BYTE btDeviceSelect;
++
++ switch (nCRTIndex)
++ {
++ case CRT_1:
++ btDeviceSelect = DEVICE_ADDRESS_CH7301_CRT1;
++ break;
++ case CRT_2:
++ btDeviceSelect = DEVICE_ADDRESS_CH7301_CRT2;
++ break;
++ default:
++ printf("CRTIndex is not 1 or 2");
++ return FALSE;
++ break;
++ }
++
++ //Enable all DAC's and set register 21h[0] = '0'
++ //DVIP and DVIL disable for DAC
++ SetI2CRegClient(0, DEVICE_SELECT_CH7301, btDeviceSelect, CH7301_PM_REG, 0x00);
++
++ btValue = GetI2CRegClient(0, DEVICE_SELECT_CH7301, btDeviceSelect, CH7301_DC_REG);
++ btValue = btValue & 0xFE;
++ SetI2CRegClient(0, DEVICE_SELECT_CH7301, btDeviceSelect, CH7301_DC_REG, btValue);
++
++ //Set SENSE bit to 1
++ btValue = GetI2CRegClient(0, DEVICE_SELECT_CH7301, btDeviceSelect, CH7301_CD_REG);
++ btValue = btValue | 0x01;
++ SetI2CRegClient(0, DEVICE_SELECT_CH7301, btDeviceSelect, CH7301_CD_REG, btValue);
++
++ //Reset SENSE bit to 0
++ btValue = GetI2CRegClient(0, DEVICE_SELECT_CH7301, btDeviceSelect, CH7301_CD_REG);
++ btValue = btValue & 0xFE;
++ SetI2CRegClient(0, DEVICE_SELECT_CH7301, btDeviceSelect, CH7301_CD_REG, btValue);
++
++ bValue = (GetI2CRegClient(0, DEVICE_SELECT_CH7301, btDeviceSelect, CH7301_CD_REG) & CD_DACT) ? TRUE : FALSE;
++
++ return bValue;
++}
++
++VOID SetCH7301C(ULONG MMIOBase,
++ int nCRTIndex,
++ int inFreqRange,
++ int inOperating)
++{
++ BYTE btDeviceSelect;
++ BYTE btValue;
++
++//#ifdef EVB_CLIENT
++ //output RGB doesn't need to set CH7301
++ //if (1 == inOperating)
++ // return;
++//#endif
++
++ switch (nCRTIndex)
++ {
++ case CRT_1:
++ btDeviceSelect = 0xEA;
++
++ break;
++ case CRT_2:
++ btDeviceSelect = 0xEC;
++
++ break;
++ default:
++ printf("CRTIndex is not 1 or 2");
++ return;
++ break;
++ }
++
++ if (inFreqRange <= VCLK65)
++ {
++ printf("ch7301: low f \n");
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x33, 0x08);
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x34, 0x16);
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x36, 0x60);
++ }
++ else
++ {
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x33, 0x06);
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x34, 0x26);
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x36, 0xA0);
++ }
++
++ switch (inOperating)
++ {
++ case 0:
++ //DVI is normal function
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x49, 0xC0);
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x1D, 0x47);
++ break;
++ case 1:
++ //RGB
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x48, 0x18);
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x49, 0x0);
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x56, 0x0);
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x21, 0x9);
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x1D, 0x48);
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x1C, 0x00);
++ break;
++ default:
++ break;
++ };
++}
++
++void SetASTModeTiming (ULONG MMIOBase, int nCRTIndex, BYTE ModeIndex, BYTE ColorDepth)
++{
++ ULONG temp, RetraceStart, RetraceEnd, DisplayOffset, TerminalCount, bpp;
++
++// Access CRT Engine
++ // SetPolarity
++ WriteMemoryLongWithMASKClient(SCU_BASE, CRT1_CONTROL_REG + nCRTIndex*0x60, ((vModeTable[ModeIndex].HorPolarity << HOR_SYNC_SELECT_BIT) | (vModeTable[ModeIndex].VerPolarity << VER_SYNC_SELECT_BIT)), (HOR_SYNC_SELECT_MASK|VER_SYNC_SELECT_MASK));
++
++#if CONFIG_AST3000
++ WriteMemoryLongClient(SCU_BASE, CRT1_CONTROL2_REG + nCRTIndex*0x60, 0xc0);
++#else
++ //2100 is single edge
++ WriteMemoryLongClient(SCU_BASE, CRT1_CONTROL2_REG + nCRTIndex*0x60, 0x80);
++#endif
++ // Horizontal Timing
++ temp = 0;
++ temp = ((vModeTable[ModeIndex].HorizontalActive - 1) << HOR_ENABLE_END_BIT) | ((vModeTable[ModeIndex].HorizontalTotal - 1) << HOR_TOTAL_BIT);
++ WriteMemoryLongClient(SCU_BASE, CRT1_HOR_TOTAL_END_REG + nCRTIndex*0x60, temp);
++
++ RetraceStart = vModeTable[ModeIndex].HorizontalTotal - vModeTable[ModeIndex].HBackPorch - vModeTable[ModeIndex].HSyncTime - vModeTable[ModeIndex].HLeftBorder - 1;
++ RetraceEnd = (RetraceStart + vModeTable[ModeIndex].HSyncTime);
++ temp = 0;
++ temp = (RetraceEnd << HOR_RETRACE_END_BIT) | (RetraceStart << HOR_RETRACE_START_BIT);
++ WriteMemoryLongClient(SCU_BASE, CRT1_HOR_RETRACE_REG + nCRTIndex*0x60, temp);
++
++ // Vertical Timing
++ temp = 0;
++ temp = ((vModeTable[ModeIndex].VerticalActive - 1) << VER_ENABLE_END_BIT) | ((vModeTable[ModeIndex].VerticalTotal - 1) << VER_TOTAL_BIT);
++ WriteMemoryLongClient(SCU_BASE, CRT1_VER_TOTAL_END_REG + nCRTIndex*0x60, temp);
++
++ temp = 0;
++ RetraceStart = vModeTable[ModeIndex].VerticalTotal - vModeTable[ModeIndex].VBackPorch - vModeTable[ModeIndex].VSyncTime - vModeTable[ModeIndex].VTopBorder - 1;
++ RetraceEnd = (RetraceStart + vModeTable[ModeIndex].VSyncTime);
++ temp = (RetraceEnd << VER_RETRACE_END_BIT) | (RetraceStart << VER_RETRACE_START_BIT);
++ WriteMemoryLongClient(SCU_BASE, CRT1_VER_RETRACE_REG + nCRTIndex*0x60, temp);
++
++ // Set CRT Display Offset and Terminal Count
++ if (ColorDepth == RGB_565) {
++ bpp = 16;
++ }
++ else {
++ bpp = 32;
++ }
++
++ DisplayOffset = vModeTable[ModeIndex].HorizontalActive * bpp / 8;
++ TerminalCount = vModeTable[ModeIndex].HorizontalActive * bpp / 64;
++ if (ColorDepth == YUV_444) {
++ TerminalCount = TerminalCount * 3 / 4;
++ }
++ if (((vModeTable[ModeIndex].HorizontalActive * bpp) % 64) != 0) {
++ TerminalCount++;
++ }
++
++ WriteMemoryLongClient(SCU_BASE, CRT1_DISPLAY_OFFSET + nCRTIndex*0x60, ((TerminalCount << TERMINAL_COUNT_BIT) | DisplayOffset));
++
++ // Set Color Format
++ WriteMemoryLongWithMASKClient(SCU_BASE, CRT1_CONTROL_REG + nCRTIndex*0x60, (ColorDepth << FORMAT_SELECT_BIT), FORMAT_SELECT_MASK);
++
++ // Set Threshold
++ temp = 0;
++ temp = (CRT_HIGH_THRESHOLD_VALUE << THRES_HIGHT_BIT) | (CRT_LOW_THRESHOLD_VALUE << THRES_LOW_BIT);
++ WriteMemoryLongClient(SCU_BASE, CRT1_THRESHOLD_REG + nCRTIndex*0x60, temp);
++
++ WriteMemoryLongClient(SCU_BASE, CRT1_VIDEO_PLL_REG + nCRTIndex*0x60, AST3000DCLKTableV[vModeTable[ModeIndex].PixelClock]);
++}
++
++void SetASTCenter1024ModeTiming (ULONG MMIOBase, int nCRTIndex, BYTE ModeIndex, BYTE ColorDepth)
++{
++ ULONG temp, RetraceStart, RetraceEnd, DisplayOffset, TerminalCount, bpp;
++
++ // Access CRT Engine
++ // SetPolarity
++ WriteMemoryLongWithMASKClient(SCU_BASE, CRT1_CONTROL_REG + nCRTIndex*0x60, (HOR_NEGATIVE << HOR_SYNC_SELECT_BIT) | (VER_NEGATIVE << VER_SYNC_SELECT_BIT), HOR_SYNC_SELECT_MASK|VER_SYNC_SELECT_MASK);
++
++ WriteMemoryLongClient(SCU_BASE, CRT1_CONTROL2_REG + nCRTIndex*0x60, 0xC0);
++
++ // Horizontal Timing
++ temp = 0;
++ temp = ((vModeTable[ModeIndex].HorizontalActive - 1) << HOR_ENABLE_END_BIT) | ((vModeTable[10].HorizontalTotal - 1) << HOR_TOTAL_BIT);
++ WriteMemoryLongClient(SCU_BASE, CRT1_HOR_TOTAL_END_REG + nCRTIndex*0x60, temp);
++
++ RetraceStart = vModeTable[10].HorizontalTotal - vModeTable[10].HBackPorch - vModeTable[10].HSyncTime - vModeTable[10].HLeftBorder - 1;
++ RetraceStart = RetraceStart - (vModeTable[10].HorizontalActive - vModeTable[ModeIndex].HorizontalActive) / 2 - 1;
++ RetraceEnd = (RetraceStart + vModeTable[10].HSyncTime);
++ temp = 0;
++ temp = (RetraceEnd << HOR_RETRACE_END_BIT) | (RetraceStart << HOR_RETRACE_START_BIT);
++ WriteMemoryLongClient(SCU_BASE, CRT1_HOR_RETRACE_REG + nCRTIndex*0x60, temp);
++
++ // Vertical Timing
++ temp = 0;
++ temp = ((vModeTable[ModeIndex].VerticalActive - 1) << VER_ENABLE_END_BIT) | ((vModeTable[10].VerticalTotal - 1) << VER_TOTAL_BIT);
++ WriteMemoryLongClient(SCU_BASE, CRT1_VER_TOTAL_END_REG + nCRTIndex*0x60, temp);
++
++ RetraceStart = vModeTable[10].VerticalTotal - vModeTable[10].VBackPorch - vModeTable[10].VSyncTime - vModeTable[10].VTopBorder - 1;
++ RetraceStart = RetraceStart - (vModeTable[10].VerticalActive - vModeTable[ModeIndex].VerticalActive) / 2 - 1;
++ RetraceEnd = (RetraceStart + vModeTable[10].VSyncTime);
++ temp = (RetraceEnd << VER_RETRACE_END_BIT) | (RetraceStart << VER_RETRACE_START_BIT);
++ WriteMemoryLongClient(SCU_BASE, CRT1_VER_RETRACE_REG + nCRTIndex*0x60, temp);
++
++ // Set CRT Display Offset and Terminal Count
++ if (ColorDepth == RGB_565) {
++ bpp = 16;
++ }
++ else {
++ bpp = 32;
++ }
++ DisplayOffset = vModeTable[ModeIndex].HorizontalActive * bpp / 8;
++ TerminalCount = vModeTable[ModeIndex].HorizontalActive * bpp / 64;
++ if (ColorDepth == YUV_444) {
++ TerminalCount = TerminalCount * 3 / 4;
++ }
++ if (((vModeTable[ModeIndex].HorizontalActive * bpp) % 64) != 0) {
++ TerminalCount++;
++ }
++
++ WriteMemoryLongClient(SCU_BASE, CRT1_DISPLAY_OFFSET + nCRTIndex*0x60, (TerminalCount << TERMINAL_COUNT_BIT) | DisplayOffset);
++
++ // Set Color Format
++ WriteMemoryLongWithMASKClient(SCU_BASE, CRT1_CONTROL_REG + nCRTIndex*0x60, (ColorDepth << FORMAT_SELECT_BIT), FORMAT_SELECT_MASK);
++
++ // Set Threshold
++ temp = 0;
++ temp = (CRT_HIGH_THRESHOLD_VALUE << THRES_HIGHT_BIT) | (CRT_LOW_THRESHOLD_VALUE << THRES_LOW_BIT);
++ WriteMemoryLongClient(SCU_BASE, CRT1_THRESHOLD_REG + nCRTIndex*0x60, temp);
++
++ // Set DCLK
++ WriteMemoryLongClient(SCU_BASE, CRT1_VIDEO_PLL_REG + nCRTIndex*0x60, AST3000DCLKTableV[vModeTable[ModeIndex].PixelClock]);
++
++}
++
++BOOL ASTSetModeV (ULONG MMIOBase, int nCRTIndex, ULONG VGABaseAddr, USHORT Horizontal, USHORT Vertical, BYTE ColorFormat, BYTE CenterMode)
++{
++ BYTE i, ModeIndex;
++ BOOL bDAC;
++ ULONG ulTemp;
++
++ // Access CRT Engine
++ //Enable CRT1 graph
++ WriteMemoryLongWithMASKClient(SCU_BASE, CRT1_CONTROL_REG + 0x60*nCRTIndex, GRAPH_DISPLAY_ON, GRAPH_DISPLAY_MASK);
++
++ // Set CRT Display Start Address
++ WriteMemoryLongWithMASKClient(SCU_BASE, CRT1_DISPLAY_ADDRESS + 0x60*nCRTIndex, VGABaseAddr, DISPLAY_ADDRESS_MASK);
++
++ for (i = 0; i < Mode60HZCount; i++) {
++ if ((vModeTable[i].HorizontalActive == Horizontal) && (vModeTable[i].VerticalActive == Vertical)) {
++
++ ModeIndex = i;
++
++ if (CenterMode != 1) {
++ SetASTModeTiming(MMIOBase, nCRTIndex, i, ColorFormat);
++ }
++ else {
++ SetASTCenter1024ModeTiming (MMIOBase, nCRTIndex, i, ColorFormat);
++ }
++
++ //use internal video out sigal and don't need use 7301
++ /*
++ bDAC = CheckDAC(nCRTIndex);
++
++ SetCH7301C(0,
++ nCRTIndex,
++ vModeTable[ModeIndex].PixelClock,
++ bDAC); //For RGB
++ */
++ return TRUE;
++ }
++ }
++
++ return FALSE;
++}
++
+diff --git a/board/aspeed/ast2300/crt.h b/board/aspeed/ast2300/crt.h
+new file mode 100755
+index 0000000..e7483be
+--- /dev/null
++++ b/board/aspeed/ast2300/crt.h
+@@ -0,0 +1,121 @@
++/*
++ * 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 _CRT_H_
++#define _CRT_H_
++
++#ifdef Watcom
++#define CRT_REMAP_OFFSET 0x10000
++#else
++#define CRT_REMAP_OFFSET 0x0
++#endif
++
++/********************************************************/
++/* CRT register */
++/********************************************************/
++#define CRT_BASE_OFFSET 0x6000+CRT_REMAP_OFFSET
++
++#define CRT1_CONTROL_REG 0x00 + CRT_BASE_OFFSET
++ #define GRAPH_DISPLAY_BIT 0
++ #define GRAPH_DISPLAY_MASK (1<<0)
++ #define GRAPH_DISPLAY_ON 1
++ #define GRAPH_DISPLAY_OFF 0
++ #define FORMAT_SELECT_BIT 8
++ #define FORMAT_SELECT_MASK (3<<8)
++ #define HOR_SYNC_SELECT_BIT 16
++ #define HOR_SYNC_SELECT_MASK (1<<16)
++ #define HOR_NEGATIVE 1
++ #define HOR_POSITIVE 0
++ #define VER_SYNC_SELECT_BIT 17
++ #define VER_SYNC_SELECT_MASK (1<<17)
++ #define VER_NEGATIVE 1
++ #define VER_POSITIVE 0
++
++#define CRT1_CONTROL2_REG 0x04 + CRT_BASE_OFFSET
++
++#define CRT1_VIDEO_PLL_REG 0x0C + CRT_BASE_OFFSET
++ #define POST_DIV_BIT 18
++ #define POST_DIV_MASK 3<<18
++ #define DIV_1_1 0
++ //#define DIV_1_2 1
++ #define DIV_1_2 2
++ #define DIV_1_4 3
++
++#define CRT1_HOR_TOTAL_END_REG 0x10 + CRT_BASE_OFFSET
++ #define HOR_TOTAL_BIT 0
++ #define HOR_ENABLE_END_BIT 16
++
++#define CRT1_HOR_RETRACE_REG 0x14 + CRT_BASE_OFFSET
++ #define HOR_RETRACE_START_BIT 0
++ #define HOR_RETRACE_END_BIT 16
++
++#define CRT1_VER_TOTAL_END_REG 0x18 + CRT_BASE_OFFSET
++ #define VER_TOTAL_BIT 0
++ #define VER_ENABLE_END_BIT 16
++
++#define CRT1_VER_RETRACE_REG 0x1C + CRT_BASE_OFFSET
++ #define VER_RETRACE_START_BIT 0
++ #define VER_RETRACE_END_BIT 16
++
++#define CRT1_DISPLAY_ADDRESS 0x20 + CRT_BASE_OFFSET
++ #define DISPLAY_ADDRESS_MASK 0x0FFFFFFF
++
++#define CRT1_DISPLAY_OFFSET 0x24 + CRT_BASE_OFFSET
++ #define DISPLAY_OFFSET_ALIGN 7 /* 8 byte alignment*/
++ #define TERMINAL_COUNT_BIT 16
++
++#define CRT1_THRESHOLD_REG 0x28 + CRT_BASE_OFFSET
++ #define THRES_LOW_BIT 0
++ #define THRES_HIGHT_BIT 8
++
++#define CURSOR_POSITION 0x30 + OFFSET
++#define CURSOR_OFFSET 0x34 + OFFSET
++#define CURSOR_PATTERN 0x38 + OFFSET
++#define OSD_HORIZONTAL 0x40 + OFFSET
++#define OSD_VERTICAL 0x44 + OFFSET
++#define OSD_PATTERN 0x48 + OFFSET
++#define OSD_OFFSET 0x4C + OFFSET
++#define OSD_THRESHOLD 0x50 + OFFSET
++
++//Ch7301c
++#define DEVICE_ADDRESS_CH7301_CRT1 0xEA
++#define DEVICE_ADDRESS_CH7301_CRT2 0xEC
++
++
++#define DEVICE_SELECT_CH7301 0x3
++
++/* CH7301 Register Definition */
++#define CH7301_CD_REG 0x20
++ #define CD_DACT 0x0E
++ #define CD_DVIT 1 << 5
++#define CH7301_DC_REG 0x21
++#define CH7301_PM_REG 0x49
++
++BOOL CheckHotPlug(int nCRTIndex);
++BOOL CheckDAC(int nCRTIndex);
++
++BOOL ASTSetModeV (ULONG MMIOBase,
++ int nCRTIndex,
++ ULONG VGABaseAddr,
++ USHORT Horizontal,
++ USHORT Vertical,
++ BYTE ColorFormat,
++ BYTE CenterMode);
++
++BOOL SelCRTClock(ULONG MMIOBase,
++ int nCRTIndex,
++ USHORT Horizontal,
++ USHORT Vertical);
++
++void DisableCRT(ULONG MMIOBase, int nCRTIndex);
++void ClearCRTWithBlack(ULONG ulCRTAddr, int iWidth, int iHeight);
++
++#endif /* _CRT_H_ */
++
+diff --git a/board/aspeed/ast2300/flash.c b/board/aspeed/ast2300/flash.c
+new file mode 100755
+index 0000000..d611d0d
+--- /dev/null
++++ b/board/aspeed/ast2300/flash.c
+@@ -0,0 +1,1651 @@
++/*
++ * 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
++ *
++ * History
++ * 01/20/2004 - combined variants of original driver.
++ * 01/22/2004 - Write performance enhancements for parallel chips (Tolunay)
++ * 01/23/2004 - Support for x8/x16 chips (Rune Raknerud)
++ * 01/27/2004 - Little endian support Ed Okerson
++ *
++ * Tested Architectures
++ * Port Width Chip Width # of banks Flash Chip Board
++ * 32 16 1 28F128J3 seranoa/eagle
++ * 64 16 1 28F128J3 seranoa/falcon
++ */
++// (Sun) This CFI driver is written for fixed-width flash chips.
++// It was not designed for flexible 8-bit/16-bit chips, which are the norm.
++// When those chips are connected to a bus in 8-bit mode, the address wires
++// right-shifted by 1.
++//FIXME: Fix the driver to auto-detect "16-bit flash wired in 8-bit mode".
++// Left-shift CFI offsets by 1 bit instead of doubling the #define values.
++
++/* The DEBUG define must be before common to enable debugging */
++// (Sun) Changed to DEBUG_FLASH because flash debug()s are too numerous.
++// #define DEBUG
++
++#include <common.h>
++#include <asm/processor.h>
++#include <asm/byteorder.h>
++#include <environment.h>
++#ifdef CONFIG_SYS_FLASH_CFI
++
++/*
++ * This file implements a Common Flash Interface (CFI) driver for U-Boot.
++ * The width of the port and the width of the chips are determined at initialization.
++ * These widths are used to calculate the address for access CFI data structures.
++ * It has been tested on an Intel Strataflash implementation and AMD 29F016D.
++ *
++ * References
++ * JEDEC Standard JESD68 - Common Flash Interface (CFI)
++ * JEDEC Standard JEP137-A Common Flash Interface (CFI) ID Codes
++ * Intel Application Note 646 Common Flash Interface (CFI) and Command Sets
++ * Intel 290667-008 3 Volt Intel StrataFlash Memory datasheet
++ *
++ * TODO
++ *
++ * Use Primary Extended Query table (PRI) and Alternate Algorithm Query
++ * Table (ALT) to determine if protection is available
++ *
++ * Add support for other command sets Use the PRI and ALT to determine command set
++ * Verify erase and program timeouts.
++ */
++
++#ifndef CONFIG_FLASH_BANKS_LIST
++#define CONFIG_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE }
++#endif
++
++#define FLASH_CMD_CFI 0x98
++#define FLASH_CMD_READ_ID 0x90
++#define FLASH_CMD_RESET 0xff
++#define FLASH_CMD_BLOCK_ERASE 0x20
++#define FLASH_CMD_ERASE_CONFIRM 0xD0
++#define FLASH_CMD_WRITE 0x40
++#define FLASH_CMD_PROTECT 0x60
++#define FLASH_CMD_PROTECT_SET 0x01
++#define FLASH_CMD_PROTECT_CLEAR 0xD0
++#define FLASH_CMD_CLEAR_STATUS 0x50
++#define FLASH_CMD_WRITE_TO_BUFFER 0xE8
++#define FLASH_CMD_WRITE_BUFFER_CONFIRM 0xD0
++
++#define FLASH_STATUS_DONE 0x80
++#define FLASH_STATUS_ESS 0x40
++#define FLASH_STATUS_ECLBS 0x20
++#define FLASH_STATUS_PSLBS 0x10
++#define FLASH_STATUS_VPENS 0x08
++#define FLASH_STATUS_PSS 0x04
++#define FLASH_STATUS_DPS 0x02
++#define FLASH_STATUS_R 0x01
++#define FLASH_STATUS_PROTECT 0x01
++
++#define AMD_CMD_RESET 0xF0
++#define AMD_CMD_WRITE 0xA0
++#define AMD_CMD_ERASE_START 0x80
++#define AMD_CMD_ERASE_SECTOR 0x30
++#define AMD_CMD_UNLOCK_START 0xAA
++#define AMD_CMD_UNLOCK_ACK 0x55
++#define AMD_CMD_WRITE_TO_BUFFER 0x25
++#define AMD_CMD_BUFFER_TO_FLASH 0x29
++
++#define AMD_STATUS_TOGGLE 0x40
++#define AMD_STATUS_ERROR 0x20
++//FIXME: These 3 were also changed for 8-bit/16-bit flash chips.
++#define AMD_ADDR_ERASE_START (0xAAA/info->portwidth)
++#define AMD_ADDR_START (0xAAA/info->portwidth)
++#define AMD_ADDR_ACK (0x555/info->portwidth)
++
++//FIXME: Fix the driver to auto-detect "16-bit flash wired in 8-bit mode".
++// Left-shift CFI offsets by 1 bit instead of doubling the #define values.
++#define FLASH_OFFSET_CFI (0xAA/info->portwidth)
++#define FLASH_OFFSET_CFI_RESP (0x20/info->portwidth)
++#define FLASH_OFFSET_CFI_RESP1 (0x22/info->portwidth)
++#define FLASH_OFFSET_CFI_RESP2 (0x24/info->portwidth)
++#define FLASH_OFFSET_PRIMARY_VENDOR (0x26/info->portwidth)
++#define FLASH_OFFSET_WTOUT (0x3E/info->portwidth)
++#define FLASH_OFFSET_WBTOUT (0x40/info->portwidth)
++#define FLASH_OFFSET_ETOUT (0x42/info->portwidth)
++#define FLASH_OFFSET_CETOUT (0x44/info->portwidth)
++#define FLASH_OFFSET_WMAX_TOUT (0x46/info->portwidth)
++#define FLASH_OFFSET_WBMAX_TOUT (0x48/info->portwidth)
++#define FLASH_OFFSET_EMAX_TOUT (0x4A/info->portwidth)
++#define FLASH_OFFSET_CEMAX_TOUT (0x4C/info->portwidth)
++#define FLASH_OFFSET_SIZE (0x4E/info->portwidth)
++#define FLASH_OFFSET_INTERFACE (0x50/info->portwidth)
++#define FLASH_OFFSET_BUFFER_SIZE (0x54/info->portwidth)
++#define FLASH_OFFSET_NUM_ERASE_REGIONS (0x58/info->portwidth)
++#define FLASH_OFFSET_ERASE_REGIONS (0x5A/info->portwidth)
++#define FLASH_OFFSET_PROTECT (0x02/info->portwidth)
++#define FLASH_OFFSET_USER_PROTECTION (0x85/info->portwidth)
++#define FLASH_OFFSET_INTEL_PROTECTION (0x81/info->portwidth)
++
++#define MAX_NUM_ERASE_REGIONS 4
++
++#define FLASH_MAN_CFI 0x01000000
++
++#define CFI_CMDSET_NONE 0
++#define CFI_CMDSET_INTEL_EXTENDED 1
++#define CFI_CMDSET_AMD_STANDARD 2
++#define CFI_CMDSET_INTEL_STANDARD 3
++#define CFI_CMDSET_AMD_EXTENDED 4
++#define CFI_CMDSET_MITSU_STANDARD 256
++#define CFI_CMDSET_MITSU_EXTENDED 257
++#define CFI_CMDSET_SST 258
++
++
++#ifdef CONFIG_SYS_FLASH_CFI_AMD_RESET /* needed for STM_ID_29W320DB on UC100 */
++# undef FLASH_CMD_RESET
++# define FLASH_CMD_RESET AMD_CMD_RESET /* use AMD-Reset instead */
++#endif
++
++
++typedef union {
++ unsigned char c;
++ unsigned short w;
++ unsigned long l;
++ unsigned long long ll;
++} cfiword_t;
++
++typedef union {
++ volatile unsigned char *cp;
++ volatile unsigned short *wp;
++ volatile unsigned long *lp;
++ volatile unsigned long long *llp;
++} cfiptr_t;
++
++/* use CFG_MAX_FLASH_BANKS_DETECT if defined */
++#ifdef CONFIG_SYS_MAX_FLASH_BANKS_DETECT
++static ulong bank_base[CONFIG_SYS_MAX_FLASH_BANKS_DETECT] = CONFIG_FLASH_BANKS_LIST;
++flash_info_t flash_info[CFG_MAX_FLASH_BANKS_DETECT]; /* FLASH chips info */
++#else
++static ulong bank_base[CONFIG_SYS_MAX_FLASH_BANKS] = CONFIG_FLASH_BANKS_LIST;
++flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* FLASH chips info */
++#endif
++
++
++/*-----------------------------------------------------------------------
++ * Functions
++ */
++static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c);
++static void flash_make_cmd (flash_info_t * info, uchar cmd, void *cmdbuf);
++static void flash_write_cmd (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
++static void flash_write_cmd_nodbg (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
++static void flash_write_cmd_int (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd, int noDebug);
++static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect);
++static int flash_isequal (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
++static int flash_isset (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
++static int flash_toggle (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
++static int flash_detect_cfi (flash_info_t * info);
++ulong flash_get_size (ulong base, int banknum);
++static int flash_write_cfiword (flash_info_t * info, ulong dest, cfiword_t cword);
++static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
++ ulong tout, char *prompt);
++static void write_buffer_abort_reset(flash_info_t * info, flash_sect_t sector);
++#if defined(CFG_ENV_IS_IN_FLASH) || defined(CFG_ENV_ADDR_REDUND) || (CFG_MONITOR_BASE >= CFG_FLASH_BASE)
++static flash_info_t *flash_get_info(ulong base);
++#endif
++#ifdef CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp, int len);
++static int flash_write_cfibuffer_amd (flash_info_t * info, ulong dest, uchar * cp, int len);
++#endif
++
++/*-----------------------------------------------------------------------
++ * create an address based on the offset and the port width
++ */
++inline uchar *flash_make_addr (flash_info_t * info, flash_sect_t sect, uint offset)
++{
++ return ((uchar *) (info->start[sect] + (offset * info->portwidth)));
++}
++
++/*-----------------------------------------------------------------------
++ * Debug support
++ */
++#ifdef DEBUG_FLASH
++static void print_longlong (char *str, unsigned long long data)
++{
++ int i;
++ char *cp;
++
++ cp = (unsigned char *) &data;
++ for (i = 0; i < 8; i++)
++ sprintf (&str[i * 2], "%2.2x", *cp++);
++}
++#endif
++
++#if defined(DEBUG_FLASH)
++static void flash_printqry (flash_info_t * info, flash_sect_t sect)
++{
++ cfiptr_t cptr;
++ int x, y;
++
++ for (x = 0; x < 0x40; x += 16U / info->portwidth) {
++ cptr.cp =
++ flash_make_addr (info, sect,
++ x + FLASH_OFFSET_CFI_RESP);
++ debug ("%p : ", cptr.cp);
++ for (y = 0; y < 16; y++) {
++ debug ("%2.2x ", cptr.cp[y]);
++ }
++ debug (" ");
++ for (y = 0; y < 16; y++) {
++ if (cptr.cp[y] >= 0x20 && cptr.cp[y] <= 0x7e) {
++ debug ("%c", cptr.cp[y]);
++ } else {
++ debug (".");
++ }
++ }
++ debug ("\n");
++ }
++}
++#endif
++
++/*-----------------------------------------------------------------------
++ * read a character at a port width address
++ */
++inline uchar flash_read_uchar (flash_info_t * info, uint offset)
++{
++ uchar *cp;
++
++ cp = flash_make_addr (info, 0, offset);
++#if defined(__LITTLE_ENDIAN)
++ return (cp[0]);
++#else
++ return (cp[info->portwidth - 1]);
++#endif
++}
++
++/*-----------------------------------------------------------------------
++ * read a short word by swapping for ppc format.
++ */
++#if 0
++static ushort flash_read_ushort (flash_info_t * info, flash_sect_t sect, uint offset)
++{
++ uchar *addr;
++ ushort retval;
++
++#ifdef DEBUG_FLASH
++ int x;
++#endif
++ addr = flash_make_addr (info, sect, offset);
++
++#ifdef DEBUG_FLASH
++ debug ("ushort addr is at %p info->portwidth = %d\n", addr,
++ info->portwidth);
++ for (x = 0; x < 2 * info->portwidth; x++) {
++ debug ("addr[%x] = 0x%x\n", x, addr[x]);
++ }
++#endif
++#if defined(__LITTLE_ENDIAN)
++ if (info->interface == FLASH_CFI_X8X16) {
++ retval = (addr[0] | (addr[2] << 8));
++ } else {
++ retval = (addr[0] | (addr[(info->portwidth)] << 8));
++ }
++#else
++ retval = ((addr[(2 * info->portwidth) - 1] << 8) |
++ addr[info->portwidth - 1]);
++#endif
++
++ debug ("retval = 0x%x\n", retval);
++ return retval;
++}
++#endif
++
++/*-----------------------------------------------------------------------
++ * read a long word by picking the least significant byte of each maximum
++ * port size word. Swap for ppc format.
++ */
++static ulong flash_read_long (flash_info_t * info, flash_sect_t sect, uint offset)
++{
++ uchar *addr;
++ ulong retval;
++#ifdef DEBUG_FLASH
++ int x;
++#endif
++#if 0
++ switch (info->interface) {
++ case FLASH_CFI_X8:
++ case FLASH_CFI_X16:
++ break;
++ case FLASH_CFI_X8X16:
++ offset <<= 1;
++ }
++#endif
++ // flash_make_addr() multiplies offset by info->portwidth.
++ addr = flash_make_addr (info, sect, offset);
++
++#ifdef DEBUG_FLASH
++ debug ("long addr is at %p info->portwidth = %d\n", addr,
++ info->portwidth);
++ for (x = 0; x < 4 * info->portwidth; x++) {
++ debug ("addr[%x] = 0x%x\n", x, addr[x]);
++ }
++#endif
++#if defined(__LITTLE_ENDIAN)
++ if (info->interface == FLASH_CFI_X8X16) {
++ retval = (addr[0] | (addr[2] << 8) | (addr[4] << 16) | (addr[6] << 24));
++ } else {
++ retval = (addr[0] | (addr[(info->portwidth)] << 8) |
++ (addr[(2 * info->portwidth)] << 16) |
++ (addr[(3 * info->portwidth)] << 24));
++ }
++#else
++ //FIXME: This undocumented code appears to match broken bus wiring.
++ retval = (addr[(2 * info->portwidth) - 1] << 24) |
++ (addr[(info->portwidth) - 1] << 16) |
++ (addr[(4 * info->portwidth) - 1] << 8) |
++ addr[(3 * info->portwidth) - 1];
++#endif
++ return retval;
++}
++
++/*-----------------------------------------------------------------------
++ */
++unsigned long flash_init (void)
++{
++ unsigned long size = 0;
++ int i;
++
++ /* Init: no FLASHes known */
++ for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
++ flash_info[i].flash_id = FLASH_UNKNOWN;
++ size += flash_info[i].size = flash_get_size (bank_base[i], i);
++ if (flash_info[i].flash_id == FLASH_UNKNOWN) {
++#ifndef CFG_FLASH_QUIET_TEST
++ printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
++ i, flash_info[i].size, flash_info[i].size << 20);
++#endif /* CFG_FLASH_QUIET_TEST */
++ }
++ }
++
++ /* Monitor protection ON by default */
++#if (CONFIG_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
++ flash_protect (FLAG_PROTECT_SET,
++ CONFIG_MONITOR_BASE,
++ CONFIG_MONITOR_BASE + monitor_flash_len - 1,
++ flash_get_info(CONFIG_MONITOR_BASE));
++#endif
++
++ /* Environment protection ON by default */
++#ifdef CONFIG_ENV_IS_IN_FLASH
++ flash_protect (FLAG_PROTECT_SET,
++ CONFIG_ENV_ADDR,
++ CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
++ flash_get_info(CONFIG_ENV_ADDR));
++#endif
++
++ /* Redundant environment protection ON by default */
++#ifdef CONFIG_ENV_ADDR_REDUND
++ flash_protect (FLAG_PROTECT_SET,
++ CONFIG_ENV_ADDR_REDUND,
++ CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SIZE_REDUND - 1,
++ flash_get_info(CONFIG_ENV_ADDR_REDUND));
++#endif
++ return (size);
++}
++
++/*-----------------------------------------------------------------------
++ */
++#if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || (CONFIG_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
++static flash_info_t *flash_get_info(ulong base)
++{
++ int i;
++ flash_info_t * info = 0;
++
++ for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i ++) {
++ info = & flash_info[i];
++ if (info->size && info->start[0] <= base &&
++ base <= info->start[0] + info->size - 1)
++ break;
++ }
++
++ return i == CONFIG_SYS_MAX_FLASH_BANKS ? 0 : info;
++}
++#endif
++
++/*-----------------------------------------------------------------------
++ */
++int flash_erase (flash_info_t * info, int s_first, int s_last)
++{
++ int rcode = 0;
++ int prot;
++ flash_sect_t sect;
++ uchar ch;
++ uchar *addr;
++
++ if (info->flash_id != FLASH_MAN_CFI) {
++ puts ("Can't erase unknown flash type - aborted\n");
++ return 1;
++ }
++ if ((s_first < 0) || (s_first > s_last)) {
++ puts ("- no sectors to erase\n");
++ return 1;
++ }
++
++ prot = 0;
++ for (sect = s_first; sect <= s_last; ++sect) {
++ if (info->protect[sect]) {
++ prot++;
++ }
++ }
++ if (prot) {
++ printf ("- Warning: %d protected sectors will not be erased!\n", prot);
++ } else {
++ putc ('\n');
++ }
++
++
++ for (sect = s_first; sect <= s_last; sect++) {
++ if (info->protect[sect] == 0) { /* not protected */
++ switch (info->vendor) {
++ case CFI_CMDSET_INTEL_STANDARD:
++ case CFI_CMDSET_INTEL_EXTENDED:
++ flash_write_cmd (info, sect, 0, FLASH_CMD_CLEAR_STATUS);
++ flash_write_cmd (info, sect, 0, FLASH_CMD_BLOCK_ERASE);
++ flash_write_cmd (info, sect, 0, FLASH_CMD_ERASE_CONFIRM);
++ break;
++ case CFI_CMDSET_AMD_STANDARD:
++ case CFI_CMDSET_AMD_EXTENDED:
++ flash_unlock_seq (info, sect);
++ flash_write_cmd (info, sect, AMD_ADDR_ERASE_START,
++ AMD_CMD_ERASE_START);
++ flash_unlock_seq (info, sect);
++ flash_write_cmd (info, sect, 0, AMD_CMD_ERASE_SECTOR);
++
++ /* toggle */
++ addr = flash_make_addr (info, sect, 0);
++ do {
++ ch = *(volatile uchar *)(addr);
++ } while ( ((ch & 0x80) == 0) || (ch != 0xFF) );
++ break;
++ default:
++ debug ("Unkown flash vendor %d\n",
++ info->vendor);
++ break;
++ }
++
++ if (flash_full_status_check
++ (info, sect, info->erase_blk_tout, "erase")) {
++ rcode = 1;
++ } else
++ putc ('.');
++ }
++ }
++ puts (" done\n");
++ return rcode;
++}
++
++/*-----------------------------------------------------------------------
++ */
++void flash_print_info (flash_info_t * info)
++{
++ int i;
++
++ if (info->flash_id != FLASH_MAN_CFI) {
++ puts ("missing or unknown FLASH type\n");
++ return;
++ }
++
++ printf ("CFI conformant FLASH (%d x %d)",
++ (info->portwidth << 3), (info->chipwidth << 3));
++ printf (" Size: %ld MB in %d Sectors\n",
++ info->size >> 20, info->sector_count);
++ printf (" Erase timeout %ld ms, write timeout %ld ms, buffer write timeout %ld ms, buffer size %d\n",
++ info->erase_blk_tout,
++ info->write_tout,
++ info->buffer_write_tout,
++ info->buffer_size);
++
++ puts (" Sector Start Addresses:");
++ for (i = 0; i < info->sector_count; ++i) {
++#ifdef CFG_FLASH_EMPTY_INFO
++ int k;
++ int size;
++ int erased;
++ volatile unsigned long *flash;
++
++ /*
++ * Check if whole sector is erased
++ */
++ if (i != (info->sector_count - 1))
++ size = info->start[i + 1] - info->start[i];
++ else
++ size = info->start[0] + info->size - info->start[i];
++ erased = 1;
++ flash = (volatile unsigned long *) info->start[i];
++ size = size >> 2; /* divide by 4 for longword access */
++ for (k = 0; k < size; k++) {
++ if (*flash++ != 0xffffffff) {
++ erased = 0;
++ break;
++ }
++ }
++
++ if ((i % 5) == 0)
++ printf ("\n");
++ /* print empty and read-only info */
++ printf (" %08lX%s%s",
++ info->start[i],
++ erased ? " E" : " ",
++ info->protect[i] ? "RO " : " ");
++#else /* ! CFG_FLASH_EMPTY_INFO */
++ if ((i % 5) == 0)
++ printf ("\n ");
++ printf (" %08lX%s",
++ info->start[i], info->protect[i] ? " (RO)" : " ");
++#endif
++ }
++ putc ('\n');
++ return;
++}
++
++/*-----------------------------------------------------------------------
++ * Copy memory to flash, returns:
++ * 0 - OK
++ * 1 - write timeout
++ * 2 - Flash not erased
++ */
++int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
++{
++ ulong wp;
++ ulong cp;
++ int aln;
++ cfiword_t cword;
++ int i, rc;
++
++#ifdef CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++ unsigned char pat[] = {'|', '-', '/', '\\'};
++ int patcnt = 0;
++ int buffered_size;
++#endif
++ /* get lower aligned address */
++ /* get lower aligned address */
++ wp = (addr & ~(info->portwidth - 1));
++
++ /* handle unaligned start */
++ if ((aln = addr - wp) != 0) {
++ cword.l = 0;
++ cp = wp;
++ for (i = 0; i < aln; ++i, ++cp)
++ flash_add_byte (info, &cword, (*(uchar *) cp));
++
++ for (; (i < info->portwidth) && (cnt > 0); i++) {
++ flash_add_byte (info, &cword, *src++);
++ cnt--;
++ cp++;
++ }
++ for (; (cnt == 0) && (i < info->portwidth); ++i, ++cp)
++ flash_add_byte (info, &cword, (*(uchar *) cp));
++ if ((rc = flash_write_cfiword (info, wp, cword)) != 0)
++ return rc;
++ wp = cp;
++ }
++
++ /* handle the aligned part */
++#ifdef CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++ buffered_size = (info->portwidth / info->chipwidth);
++ buffered_size *= info->buffer_size;
++ while (cnt >= info->portwidth) {
++ /* Show processing */
++ if ((++patcnt % 256) == 0)
++ printf("%c\b", pat[(patcnt / 256) & 0x03]);
++
++ i = buffered_size > cnt ? cnt : buffered_size;
++ if ((rc = flash_write_cfibuffer (info, wp, src, i)) != ERR_OK)
++ return rc;
++ i -= i & (info->portwidth - 1);
++ wp += i;
++ src += i;
++ cnt -= i;
++ }
++#else
++ while (cnt >= info->portwidth) {
++ cword.l = 0;
++ for (i = 0; i < info->portwidth; i++) {
++ flash_add_byte (info, &cword, *src++);
++ }
++ if ((rc = flash_write_cfiword (info, wp, cword)) != 0)
++ return rc;
++ wp += info->portwidth;
++ cnt -= info->portwidth;
++ }
++#endif /* CONFIG_SYS_FLASH_USE_BUFFER_WRITE */
++ if (cnt == 0) {
++ return (0);
++ }
++
++ /*
++ * handle unaligned tail bytes
++ */
++ cword.l = 0;
++ for (i = 0, cp = wp; (i < info->portwidth) && (cnt > 0); ++i, ++cp) {
++ flash_add_byte (info, &cword, *src++);
++ --cnt;
++ }
++ for (; i < info->portwidth; ++i, ++cp) {
++ flash_add_byte (info, &cword, (*(uchar *) cp));
++ }
++
++ return flash_write_cfiword (info, wp, cword);
++}
++
++/*-----------------------------------------------------------------------
++ */
++#ifdef CFG_FLASH_PROTECTION
++
++int flash_real_protect (flash_info_t * info, long sector, int prot)
++{
++ int retcode = 0;
++
++ flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
++ flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT);
++ if (prot)
++ flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT_SET);
++ else
++ flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT_CLEAR);
++
++ if ((retcode =
++ flash_full_status_check (info, sector, info->erase_blk_tout,
++ prot ? "protect" : "unprotect")) == 0) {
++
++ info->protect[sector] = prot;
++ /* Intel's unprotect unprotects all locking */
++ if (prot == 0) {
++ flash_sect_t i;
++
++ for (i = 0; i < info->sector_count; i++) {
++ if (info->protect[i])
++ flash_real_protect (info, i, 1);
++ }
++ }
++ }
++ return retcode;
++}
++
++/*-----------------------------------------------------------------------
++ * flash_read_user_serial - read the OneTimeProgramming cells
++ */
++void flash_read_user_serial (flash_info_t * info, void *buffer, int offset,
++ int len)
++{
++ uchar *src;
++ uchar *dst;
++
++ dst = buffer;
++ src = flash_make_addr (info, 0, FLASH_OFFSET_USER_PROTECTION);
++ flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);
++ memcpy (dst, src + offset, len);
++ flash_write_cmd (info, 0, 0, info->cmd_reset);
++}
++
++/*
++ * flash_read_factory_serial - read the device Id from the protection area
++ */
++void flash_read_factory_serial (flash_info_t * info, void *buffer, int offset,
++ int len)
++{
++ uchar *src;
++
++ src = flash_make_addr (info, 0, FLASH_OFFSET_INTEL_PROTECTION);
++ flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);
++ memcpy (buffer, src + offset, len);
++ flash_write_cmd (info, 0, 0, info->cmd_reset);
++}
++
++#endif /* CFG_FLASH_PROTECTION */
++
++/*
++ * flash_is_busy - check to see if the flash is busy
++ * This routine checks the status of the chip and returns true if the chip is busy
++ */
++static int flash_is_busy (flash_info_t * info, flash_sect_t sect)
++{
++ int retval;
++
++ switch (info->vendor) {
++ case CFI_CMDSET_INTEL_STANDARD:
++ case CFI_CMDSET_INTEL_EXTENDED:
++ retval = !flash_isset (info, sect, 0, FLASH_STATUS_DONE);
++ break;
++ case CFI_CMDSET_AMD_STANDARD:
++ case CFI_CMDSET_AMD_EXTENDED:
++ retval = flash_toggle (info, sect, 0, AMD_STATUS_TOGGLE);
++ break;
++ default:
++ retval = 0;
++ }
++#ifdef DEBUG_FLASH
++ if (retval)
++ debug ("flash_is_busy: %d\n", retval);
++#endif
++ return retval;
++}
++
++/*-----------------------------------------------------------------------
++ * wait for XSR.7 to be set. Time out with an error if it does not.
++ * This routine does not set the flash to read-array mode.
++ */
++static int flash_status_check (flash_info_t * info, flash_sect_t sector,
++ ulong tout, char *prompt)
++{
++ ulong start, now;
++
++ /* Wait for command completion */
++ // (Sun) Fix order of checking time so it works when the CPU is very
++ // slow, e.g., single-stepping or emulation.
++ start = get_timer (0);
++ while (now = get_timer(start),
++ flash_is_busy (info, sector))
++ {
++ if (now > info->erase_blk_tout) {
++ printf ("Flash %s timeout at address %lx data %lx\n",
++ prompt, info->start[sector],
++ flash_read_long (info, sector, 0));
++ flash_write_cmd (info, sector, 0, info->cmd_reset);
++ return ERR_TIMOUT;
++ }
++ }
++ return ERR_OK;
++}
++
++/*-----------------------------------------------------------------------
++ * Wait for XSR.7 to be set, if it times out print an error, otherwise do a full status check.
++ * This routine sets the flash to read-array mode.
++ */
++static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
++ ulong tout, char *prompt)
++{
++ int retcode;
++
++ retcode = flash_status_check (info, sector, tout, prompt);
++ switch (info->vendor) {
++ case CFI_CMDSET_INTEL_EXTENDED:
++ case CFI_CMDSET_INTEL_STANDARD:
++ if ((retcode != ERR_OK)
++ && !flash_isequal (info, sector, 0, FLASH_STATUS_DONE)) {
++ retcode = ERR_INVAL;
++ printf ("Flash %s error at address %lx\n", prompt,
++ info->start[sector]);
++ if (flash_isset (info, sector, 0, FLASH_STATUS_ECLBS | FLASH_STATUS_PSLBS)) {
++ puts ("Command Sequence Error.\n");
++ } else if (flash_isset (info, sector, 0, FLASH_STATUS_ECLBS)) {
++ puts ("Block Erase Error.\n");
++ retcode = ERR_NOT_ERASED;
++ } else if (flash_isset (info, sector, 0, FLASH_STATUS_PSLBS)) {
++ puts ("Locking Error\n");
++ }
++ if (flash_isset (info, sector, 0, FLASH_STATUS_DPS)) {
++ puts ("Block locked.\n");
++ retcode = ERR_PROTECTED;
++ }
++ if (flash_isset (info, sector, 0, FLASH_STATUS_VPENS))
++ puts ("Vpp Low Error.\n");
++ }
++ flash_write_cmd (info, sector, 0, info->cmd_reset);
++ break;
++ default:
++ break;
++ }
++ return retcode;
++}
++
++static void write_buffer_abort_reset(flash_info_t * info, flash_sect_t sector)
++{
++ flash_write_cmd (info, sector, 0xaaa, 0xaa);
++ flash_write_cmd (info, sector, 0x555, 0x55);
++ flash_write_cmd (info, sector, 0xaaa, 0xf0);
++}
++
++/*-----------------------------------------------------------------------
++ */
++static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c)
++{
++#if defined(__LITTLE_ENDIAN)
++ unsigned short w;
++ unsigned int l;
++ unsigned long long ll;
++#endif
++
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ cword->c = c;
++ break;
++ case FLASH_CFI_16BIT:
++#if defined(__LITTLE_ENDIAN)
++ w = c;
++ w <<= 8;
++ cword->w = (cword->w >> 8) | w;
++#else
++ cword->w = (cword->w << 8) | c;
++#endif
++ break;
++ case FLASH_CFI_32BIT:
++#if defined(__LITTLE_ENDIAN)
++ l = c;
++ l <<= 24;
++ cword->l = (cword->l >> 8) | l;
++#else
++ cword->l = (cword->l << 8) | c;
++#endif
++ break;
++ case FLASH_CFI_64BIT:
++#if defined(__LITTLE_ENDIAN)
++ ll = c;
++ ll <<= 56;
++ cword->ll = (cword->ll >> 8) | ll;
++#else
++ cword->ll = (cword->ll << 8) | c;
++#endif
++ break;
++ }
++}
++
++
++/*-----------------------------------------------------------------------
++ * make a proper sized command based on the port and chip widths
++ */
++static void flash_make_cmd (flash_info_t * info, uchar cmd, void *cmdbuf)
++{
++ int i;
++ uchar *cp = (uchar *) cmdbuf;
++
++#if defined(__LITTLE_ENDIAN)
++ for (i = info->portwidth; i > 0; i--)
++#else
++ for (i = 1; i <= info->portwidth; i++)
++#endif
++ *cp++ = (i & (info->chipwidth - 1)) ? '\0' : cmd;
++}
++
++/*
++ * Write a proper sized command to the correct address
++ */
++static void
++flash_write_cmd (flash_info_t * info, flash_sect_t sect, uint offset,
++ uchar cmd)
++{
++#ifdef DEBUG_FLASH
++ const int noDebug = 0;
++#else
++ const int noDebug = 1;
++#endif
++ return flash_write_cmd_int(info, sect, offset, cmd, noDebug);
++}
++static void
++flash_write_cmd_nodbg (flash_info_t * info, flash_sect_t sect, uint offset,
++ uchar cmd)
++{
++ return flash_write_cmd_int(info, sect, offset, cmd, 1);
++}
++
++static void
++flash_write_cmd_int (flash_info_t * info, flash_sect_t sect, uint offset,
++ uchar cmd, int noDebug)
++{
++
++ volatile cfiptr_t addr;
++ cfiword_t cword;
++
++ addr.cp = flash_make_addr (info, sect, offset);
++ flash_make_cmd (info, cmd, &cword);
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ if (noDebug == 0)
++ debug ("fwc addr %p cmd %x %x 8bit x %d bit\n", addr.cp, cmd,
++ cword.c, info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
++ *addr.cp = cword.c;
++ break;
++ case FLASH_CFI_16BIT:
++ if (noDebug == 0)
++ debug ("fwc addr %p cmd %x %4.4x 16bit x %d bit\n", addr.wp,
++ cmd, cword.w,
++ info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
++ *addr.wp = cword.w;
++ break;
++ case FLASH_CFI_32BIT:
++ if (noDebug == 0)
++ debug ("fwc addr %p cmd %x %8.8lx 32bit x %d bit\n", addr.lp,
++ cmd, cword.l,
++ info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
++ *addr.lp = cword.l;
++ break;
++ case FLASH_CFI_64BIT:
++#ifdef DEBUG_FLASH
++ if (noDebug == 0)
++ {
++ char str[20];
++
++ print_longlong (str, cword.ll);
++
++ debug ("fwrite addr %p cmd %x %s 64 bit x %d bit\n",
++ addr.llp, cmd, str,
++ info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
++ }
++#endif
++ *addr.llp = cword.ll;
++ break;
++ }
++}
++
++static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect)
++{
++ flash_write_cmd_nodbg (info, sect, AMD_ADDR_START, AMD_CMD_UNLOCK_START);
++ flash_write_cmd_nodbg (info, sect, AMD_ADDR_ACK, AMD_CMD_UNLOCK_ACK);
++}
++
++/*-----------------------------------------------------------------------
++ */
++static int flash_isequal (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
++{
++ cfiptr_t cptr;
++ cfiword_t cword;
++ int retval;
++#ifdef DEBUG_FLASH
++ const int dbg = 1;
++#else
++ const int dbg = 0;
++#endif
++ cptr.cp = flash_make_addr (info, sect, offset);
++ flash_make_cmd (info, cmd, &cword);
++
++ if (dbg)
++ debug ("is= cmd %x(%c) addr %p ", cmd, cmd, cptr.cp);
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ if (dbg)
++ debug ("is= %x %x\n", cptr.cp[0], cword.c);
++ retval = (cptr.cp[0] == cword.c);
++ break;
++ case FLASH_CFI_16BIT:
++ if (dbg)
++ debug ("is= %4.4x %4.4x\n", cptr.wp[0], cword.w);
++ retval = (cptr.wp[0] == cword.w);
++ break;
++ case FLASH_CFI_32BIT:
++ if (dbg)
++ debug ("is= %8.8lx %8.8lx\n", cptr.lp[0], cword.l);
++ retval = (cptr.lp[0] == cword.l);
++ break;
++ case FLASH_CFI_64BIT:
++#ifdef DEBUG_FLASH
++ {
++ char str1[20];
++ char str2[20];
++
++ print_longlong (str1, cptr.llp[0]);
++ print_longlong (str2, cword.ll);
++ debug ("is= %s %s\n", str1, str2);
++ }
++#endif
++ retval = (cptr.llp[0] == cword.ll);
++ break;
++ default:
++ retval = 0;
++ break;
++ }
++ return retval;
++}
++
++/*-----------------------------------------------------------------------
++ */
++static int flash_isset (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
++{
++ cfiptr_t cptr;
++ cfiword_t cword;
++ int retval;
++
++ cptr.cp = flash_make_addr (info, sect, offset);
++ flash_make_cmd (info, cmd, &cword);
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ retval = ((cptr.cp[0] & cword.c) == cword.c);
++ break;
++ case FLASH_CFI_16BIT:
++ retval = ((cptr.wp[0] & cword.w) == cword.w);
++ break;
++ case FLASH_CFI_32BIT:
++ retval = ((cptr.lp[0] & cword.l) == cword.l);
++ break;
++ case FLASH_CFI_64BIT:
++ retval = ((cptr.llp[0] & cword.ll) == cword.ll);
++ break;
++ default:
++ retval = 0;
++ break;
++ }
++ return retval;
++}
++
++/*-----------------------------------------------------------------------
++ */
++static int flash_toggle (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
++{
++ cfiptr_t cptr;
++ cfiword_t cword;
++ int retval;
++
++ cptr.cp = flash_make_addr (info, sect, offset);
++ flash_make_cmd (info, cmd, &cword);
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ retval = ((cptr.cp[0] & cword.c) != (cptr.cp[0] & cword.c));
++ break;
++ case FLASH_CFI_16BIT:
++ retval = ((cptr.wp[0] & cword.w) != (cptr.wp[0] & cword.w));
++ break;
++ case FLASH_CFI_32BIT:
++ retval = ((cptr.lp[0] & cword.l) != (cptr.lp[0] & cword.l));
++ break;
++ case FLASH_CFI_64BIT:
++ retval = ((cptr.llp[0] & cword.ll) !=
++ (cptr.llp[0] & cword.ll));
++ break;
++ default:
++ retval = 0;
++ break;
++ }
++ return retval;
++}
++
++/*-----------------------------------------------------------------------
++ * detect if flash is compatible with the Common Flash Interface (CFI)
++ * http://www.jedec.org/download/search/jesd68.pdf
++ *
++*/
++static int flash_detect_cfi (flash_info_t * info)
++{
++ ulong data;
++
++ debug ("flash_detect_cfi()... ");
++
++#if defined(CONFIG_FLASH_AST2300)
++ data = *(ulong *)(0x1e6e2070); /* hardware traping */
++ if (data & 0x10) /* D[4]: 0/1 (8/16) */
++ info->portwidth = FLASH_CFI_16BIT;
++ else
++ info->portwidth = FLASH_CFI_8BIT;
++#else
++ info->portwidth = FLASH_CFI_8BIT;
++#endif
++
++ {
++ for (info->chipwidth = FLASH_CFI_BY8;
++ info->chipwidth <= info->portwidth;
++ info->chipwidth <<= 1) {
++ flash_write_cmd (info, 0, 0, FLASH_CMD_RESET);
++ flash_write_cmd (info, 0, FLASH_OFFSET_CFI, FLASH_CMD_CFI);
++ if (flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP, 'Q')
++ //FIXME: Next 3 lines were changed for 8-bit/16-bit flash chips.
++ && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP1, 'R')
++ && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP2, 'Y')) {
++ info->interface = flash_read_uchar (info, FLASH_OFFSET_INTERFACE);
++ debug ("device interface is %d\n",
++ info->interface);
++ debug ("found port %d chip %d ",
++ info->portwidth, info->chipwidth);
++ debug ("port %d bits chip %d bits\n",
++ info->portwidth << CFI_FLASH_SHIFT_WIDTH,
++ info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
++ return 1;
++ }
++ }
++ }
++ debug ("not found\n");
++ return 0;
++}
++
++/*
++ * The following code cannot be run from FLASH!
++ *
++ */
++ulong flash_get_size (ulong base, int banknum)
++{
++ flash_info_t *info = &flash_info[banknum];
++ int i, j;
++ flash_sect_t sect_cnt;
++ unsigned long sector;
++ unsigned long tmp;
++ int size_ratio;
++ uchar num_erase_regions;
++ int erase_region_size;
++ int erase_region_count;
++
++ info->start[0] = base;
++
++ if (flash_detect_cfi (info)) {
++ info->vendor = flash_read_uchar (info, FLASH_OFFSET_PRIMARY_VENDOR);
++#if defined(DEBUG_FLASH)
++ flash_printqry (info, 0);
++#endif
++ switch (info->vendor) {
++ case CFI_CMDSET_INTEL_STANDARD:
++ case CFI_CMDSET_INTEL_EXTENDED:
++ default:
++ info->cmd_reset = FLASH_CMD_RESET;
++ break;
++ case CFI_CMDSET_AMD_STANDARD:
++ case CFI_CMDSET_AMD_EXTENDED:
++ info->cmd_reset = AMD_CMD_RESET;
++ break;
++ }
++
++ debugX(2, "manufacturer is %d\n", info->vendor);
++ size_ratio = info->portwidth / info->chipwidth;
++ /* if the chip is x8/x16 reduce the ratio by half */
++#if 0
++ if ((info->interface == FLASH_CFI_X8X16)
++ && (info->chipwidth == FLASH_CFI_BY8)) {
++ size_ratio >>= 1;
++ }
++#endif
++ num_erase_regions = flash_read_uchar (info, FLASH_OFFSET_NUM_ERASE_REGIONS);
++ debugX(2, "size_ratio %d port %d bits chip %d bits\n",
++ size_ratio, info->portwidth << CFI_FLASH_SHIFT_WIDTH,
++ info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
++ debugX(2, "found %d erase regions\n", num_erase_regions);
++ sect_cnt = 0;
++ sector = base;
++ for (i = 0; i < num_erase_regions; i++) {
++ if (i > MAX_NUM_ERASE_REGIONS) {
++ printf ("%d erase regions found, only %d used\n",
++ num_erase_regions, MAX_NUM_ERASE_REGIONS);
++ break;
++ }
++ // CFI Erase Block Region Information:
++ // Bits[31:16] = sect_size/256, 0 means 128-byte
++ // Bits[15:0] = num_sectors - 1
++ tmp = flash_read_long(info, 0,
++ FLASH_OFFSET_ERASE_REGIONS + i * 4);
++ debug("CFI erase block region info[%d]: 0x%08x, ",
++ i, tmp);
++ erase_region_count = (tmp & 0xffff) + 1;
++ tmp >>= 16;
++ erase_region_size = (tmp ? tmp * 256 : 128);
++ debug ("erase_region_count=%d erase_region_size=%d\n",
++ erase_region_count, erase_region_size);
++#if 0
++ erase_region_size = CFG_FLASH_SECTOR_SIZE; // Commented out
++ erase_region_count = CFG_FLASH_SECTOR_COUNT; // Commented out
++#endif
++ if (sect_cnt + erase_region_count > CONFIG_SYS_MAX_FLASH_SECT) {
++ printf("Warning: Erase region %d adds too many flash sectors"
++ " %d+%d; reducing to fit total limit of %d\n",
++ i, sect_cnt, erase_region_count, CONFIG_SYS_MAX_FLASH_SECT);
++ erase_region_count = CONFIG_SYS_MAX_FLASH_SECT - sect_cnt;
++ }
++ for (j = 0; j < erase_region_count; j++) {
++ info->start[sect_cnt] = sector;
++ sector += (erase_region_size * size_ratio);
++
++ /*
++ * Only read protection status from supported devices (intel...)
++ */
++ switch (info->vendor) {
++ case CFI_CMDSET_INTEL_EXTENDED:
++ case CFI_CMDSET_INTEL_STANDARD:
++ info->protect[sect_cnt] =
++ flash_isset (info, sect_cnt,
++ FLASH_OFFSET_PROTECT,
++ FLASH_STATUS_PROTECT);
++ break;
++ default:
++ info->protect[sect_cnt] = 0; /* default: not protected */
++ }
++
++ sect_cnt++;
++ }
++ }
++
++ info->sector_count = sect_cnt;
++ /* multiply the size by the number of chips */
++ // info->size = (1 << flash_read_uchar (info, FLASH_OFFSET_SIZE)) * size_ratio;
++ // Use only the sectors that fit within the flash_info array size.
++ info->size = sector - base;
++ printf("Flash bank %d at %08x has 0x%x bytes in %d sectors"
++ " (chipSize 1<<%d, size_ratio %d).\n",
++ banknum, base, info->size, info->sector_count,
++ flash_read_uchar(info, FLASH_OFFSET_SIZE), size_ratio);
++
++ info->buffer_size = (1 << flash_read_uchar (info, FLASH_OFFSET_BUFFER_SIZE));
++ /* Limit the buffer size to 32bytes to meet most of AMD-styles flash's minimum requirement */
++ if (info->buffer_size > 32)
++ info->buffer_size = 32;
++ tmp = 1 << flash_read_uchar (info, FLASH_OFFSET_ETOUT);
++ info->erase_blk_tout = (tmp * (1 << flash_read_uchar (info, FLASH_OFFSET_EMAX_TOUT)));
++ tmp = 1 << flash_read_uchar (info, FLASH_OFFSET_WBTOUT);
++ info->buffer_write_tout = (tmp * (1 << flash_read_uchar (info, FLASH_OFFSET_WBMAX_TOUT)));
++ tmp = 1 << flash_read_uchar (info, FLASH_OFFSET_WTOUT);
++ info->write_tout = (tmp * (1 << flash_read_uchar (info, FLASH_OFFSET_WMAX_TOUT))) / 1000;
++ info->flash_id = FLASH_MAN_CFI;
++#if 0
++ if ((info->interface == FLASH_CFI_X8X16) && (info->chipwidth == FLASH_CFI_BY8)) {
++ info->portwidth >>= 1; /* XXX - Need to test on x8/x16 in parallel. */
++ }
++#endif
++ }
++
++ flash_write_cmd (info, 0, 0, info->cmd_reset);
++ return (info->size);
++}
++
++
++/*-----------------------------------------------------------------------
++ */
++static int flash_write_cfiword (flash_info_t * info, ulong dest,
++ cfiword_t cword)
++{
++
++ cfiptr_t ctladdr;
++ cfiptr_t cptr;
++ int flag;
++
++ ctladdr.cp = flash_make_addr (info, 0, 0);
++ cptr.cp = (uchar *) dest;
++
++
++ /* Check if Flash is (sufficiently) erased */
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ flag = ((cptr.cp[0] & cword.c) == cword.c);
++ break;
++ case FLASH_CFI_16BIT:
++ flag = ((cptr.wp[0] & cword.w) == cword.w);
++ break;
++ case FLASH_CFI_32BIT:
++ flag = ((cptr.lp[0] & cword.l) == cword.l);
++ break;
++ case FLASH_CFI_64BIT:
++ flag = ((cptr.llp[0] & cword.ll) == cword.ll);
++ break;
++ default:
++ return 2;
++ }
++ if (!flag)
++ return 2;
++
++ /* Disable interrupts which might cause a timeout here */
++ flag = disable_interrupts ();
++
++ switch (info->vendor) {
++ case CFI_CMDSET_INTEL_EXTENDED:
++ case CFI_CMDSET_INTEL_STANDARD:
++ flash_write_cmd_nodbg (info, 0, 0, FLASH_CMD_CLEAR_STATUS);
++ flash_write_cmd_nodbg (info, 0, 0, FLASH_CMD_WRITE);
++ break;
++ case CFI_CMDSET_AMD_EXTENDED:
++ case CFI_CMDSET_AMD_STANDARD:
++ flash_unlock_seq (info, 0);
++ flash_write_cmd_nodbg (info, 0, AMD_ADDR_START, AMD_CMD_WRITE);
++ break;
++ }
++
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ cptr.cp[0] = cword.c;
++ break;
++ case FLASH_CFI_16BIT:
++ cptr.wp[0] = cword.w;
++ break;
++ case FLASH_CFI_32BIT:
++ cptr.lp[0] = cword.l;
++ break;
++ case FLASH_CFI_64BIT:
++ cptr.llp[0] = cword.ll;
++ break;
++ }
++
++ /* re-enable interrupts if necessary */
++ if (flag)
++ enable_interrupts ();
++
++ return flash_full_status_check (info, 0, info->write_tout, "write");
++}
++
++#ifdef CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++
++/* loop through the sectors from the highest address
++ * when the passed address is greater or equal to the sector address
++ * we have a match
++ */
++static flash_sect_t find_sector (flash_info_t * info, ulong addr)
++{
++ flash_sect_t sector;
++
++ for (sector = info->sector_count - 1; sector >= 0; sector--) {
++ if (addr >= info->start[sector])
++ break;
++ }
++ return sector;
++}
++
++static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
++ int len)
++{
++ flash_sect_t sector;
++ int cnt;
++ int retcode;
++ volatile cfiptr_t src;
++ volatile cfiptr_t dst;
++
++/* Add AMD write buffer mode support, ycchen@102006 */
++#if 0
++ /* buffered writes in the AMD chip set is not supported yet */
++ if((info->vendor == CFI_CMDSET_AMD_STANDARD) ||
++ (info->vendor == CFI_CMDSET_AMD_EXTENDED))
++ return ERR_INVAL;
++#endif
++ if((info->vendor == CFI_CMDSET_AMD_STANDARD) ||
++ (info->vendor == CFI_CMDSET_AMD_EXTENDED))
++ {
++ retcode = flash_write_cfibuffer_amd(info, dest, cp, len);
++ return retcode;
++ }
++
++ src.cp = cp;
++ dst.cp = (uchar *) dest;
++ sector = find_sector (info, dest);
++ flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
++ flash_write_cmd (info, sector, 0, FLASH_CMD_WRITE_TO_BUFFER);
++ if ((retcode =
++ flash_status_check (info, sector, info->buffer_write_tout,
++ "write to buffer")) == ERR_OK) {
++ /* reduce the number of loops by the width of the port */
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ cnt = len;
++ break;
++ case FLASH_CFI_16BIT:
++ cnt = len >> 1;
++ break;
++ case FLASH_CFI_32BIT:
++ cnt = len >> 2;
++ break;
++ case FLASH_CFI_64BIT:
++ cnt = len >> 3;
++ break;
++ default:
++ return ERR_INVAL;
++ break;
++ }
++ flash_write_cmd (info, sector, 0, (uchar) cnt - 1);
++ while (cnt-- > 0) {
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ *dst.cp++ = *src.cp++;
++ break;
++ case FLASH_CFI_16BIT:
++ *dst.wp++ = *src.wp++;
++ break;
++ case FLASH_CFI_32BIT:
++ *dst.lp++ = *src.lp++;
++ break;
++ case FLASH_CFI_64BIT:
++ *dst.llp++ = *src.llp++;
++ break;
++ default:
++ return ERR_INVAL;
++ break;
++ }
++ }
++ flash_write_cmd (info, sector, 0,
++ FLASH_CMD_WRITE_BUFFER_CONFIRM);
++ retcode =
++ flash_full_status_check (info, sector,
++ info->buffer_write_tout,
++ "buffer write");
++ }
++ flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
++ return retcode;
++}
++
++
++static int flash_write_cfibuffer_amd (flash_info_t * info, ulong dest, uchar * cp,
++ int len)
++{
++ flash_sect_t sector;
++ int cnt;
++ int retcode;
++ volatile cfiptr_t src;
++ volatile cfiptr_t dst;
++ volatile cfiword_t tmpsrc, tmpdst;
++
++ src.cp = cp;
++ dst.cp = (uchar *) dest;
++ sector = find_sector (info, dest);
++ flash_unlock_seq (info, 0);
++ if ((retcode =
++ flash_status_check (info, sector, info->buffer_write_tout,
++ "write to buffer")) == ERR_OK) {
++ /* reduce the number of loops by the width of the port */
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ cnt = len;
++ *dst.cp = (uchar) (AMD_CMD_WRITE_TO_BUFFER);
++ *dst.cp = (uchar) (cnt -1);
++ break;
++ case FLASH_CFI_16BIT:
++ cnt = len >> 1;
++ *dst.wp = (unsigned short) (AMD_CMD_WRITE_TO_BUFFER);
++ *dst.wp = (unsigned short) (cnt -1);
++ break;
++ case FLASH_CFI_32BIT:
++ cnt = len >> 2;
++ *dst.lp = (unsigned long) (AMD_CMD_WRITE_TO_BUFFER);
++ *dst.lp = (unsigned long) (cnt -1);
++ break;
++ case FLASH_CFI_64BIT:
++ cnt = len >> 3;
++ *dst.llp = (unsigned long long) (AMD_CMD_WRITE_TO_BUFFER);
++ *dst.llp = (unsigned long long) (cnt -1);
++ break;
++ default:
++ return ERR_INVAL;
++ break;
++ }
++ while (cnt-- > 0) {
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ *dst.cp++ = *src.cp++;
++ break;
++ case FLASH_CFI_16BIT:
++ *dst.wp++ = *src.wp++;
++ break;
++ case FLASH_CFI_32BIT:
++ *dst.lp++ = *src.lp++;
++ break;
++ case FLASH_CFI_64BIT:
++ *dst.llp++ = *src.llp++;
++ break;
++ default:
++ return ERR_INVAL;
++ break;
++ }
++ }
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ src.cp--;
++ dst.cp--;
++ *dst.cp = (unsigned char) (AMD_CMD_BUFFER_TO_FLASH);
++ tmpsrc.c = *src.cp & 0x80;
++
++ do {
++ tmpdst.c = *(volatile uchar *)(dst.cp);
++
++ if (tmpdst.c & 0x20) { /* toggle DQ5 */
++ tmpdst.c = *(volatile uchar *)(dst.cp);
++ if ((tmpdst.c & 0x80) != tmpsrc.c)
++ {
++ printf("program error occurred\n");
++ flash_write_cmd (info, sector, 0, info->cmd_reset);
++ return ERR_PROG_ERROR;
++ }
++ }
++ else if (tmpdst.c & 0x02) { /* toggle DQ1 */
++ tmpdst.c = *(volatile uchar *)(dst.cp);
++ if ((tmpdst.c & 0x80) != tmpsrc.c)
++ {
++ printf("write buffer error occurred \n");
++ write_buffer_abort_reset(info, sector);
++ return ERR_PROG_ERROR;
++ }
++ }
++
++ } while ((tmpdst.c & 0x80) != tmpsrc.c);
++
++ break;
++ case FLASH_CFI_16BIT:
++ src.wp--;
++ dst.wp--;
++ *dst.wp = (unsigned short) (AMD_CMD_BUFFER_TO_FLASH);
++ tmpsrc.w = *src.wp & 0x80;
++
++ do {
++ tmpdst.w = *(volatile short *)(dst.wp);
++
++ if (tmpdst.w & 0x20) { /* toggle DQ5 */
++ tmpdst.w = *(volatile ushort *)(dst.wp);
++ if ((tmpdst.w & 0x80) != tmpsrc.w)
++ {
++ printf("program error occurred\n");
++ flash_write_cmd (info, sector, 0, info->cmd_reset);
++ return ERR_PROG_ERROR;
++ }
++ }
++ else if (tmpdst.w & 0x02) { /* toggle DQ1 */
++ tmpdst.w = *(volatile ushort *)(dst.wp);
++ if ((tmpdst.w & 0x80) != tmpsrc.w)
++ {
++ printf("write buffer error occurred \n");
++ write_buffer_abort_reset(info, sector);
++ return ERR_PROG_ERROR;
++ }
++ }
++
++ } while ((tmpdst.w & 0x80) != tmpsrc.w);
++
++ break;
++ case FLASH_CFI_32BIT:
++ src.lp--;
++ dst.lp--;
++ *dst.lp = (unsigned long) (AMD_CMD_BUFFER_TO_FLASH);
++ tmpsrc.l = *src.lp & 0x80;
++
++ do {
++ tmpdst.l = *(volatile ulong *)(dst.lp);
++
++ if (tmpdst.l & 0x20) { /* toggle DQ5 */
++ tmpdst.l = *(volatile ulong *)(dst.lp);
++ if ((tmpdst.l & 0x80) != tmpsrc.l)
++ {
++ printf("program error occurred\n");
++ flash_write_cmd (info, sector, 0, info->cmd_reset);
++ return ERR_PROG_ERROR;
++ }
++ }
++ else if (tmpdst.l & 0x02) { /* toggle DQ1 */
++ tmpdst.l = *(volatile ulong *)(dst.lp);
++ if ((tmpdst.l & 0x80) != tmpsrc.l)
++ {
++ printf("write buffer error occurred \n");
++ write_buffer_abort_reset(info, sector);
++ return ERR_PROG_ERROR;
++ }
++ }
++
++ } while ((tmpdst.l & 0x80) != tmpsrc.l);
++
++ break;
++ case FLASH_CFI_64BIT:
++ src.llp--;
++ dst.llp--;
++ *dst.llp = (unsigned long long) (AMD_CMD_BUFFER_TO_FLASH);
++ tmpsrc.ll = *src.llp & 0x80;
++
++ do {
++ tmpdst.ll = *(volatile unsigned long long *)(dst.llp);
++
++ if (tmpdst.ll & 0x20) { /* toggle DQ5 */
++ tmpdst.ll = *(volatile unsigned long long *)(dst.llp);
++ if ((tmpdst.ll & 0x80) != tmpsrc.ll)
++ {
++ printf("program error occurred\n");
++ flash_write_cmd (info, sector, 0, info->cmd_reset);
++ return ERR_PROG_ERROR;
++ }
++ }
++ else if (tmpdst.ll & 0x02) { /* toggle DQ1 */
++ tmpdst.ll = *(volatile unsigned long long *)(dst.llp);
++ if ((tmpdst.ll & 0x80) != tmpsrc.ll)
++ {
++ printf("write buffer error occurred \n");
++ write_buffer_abort_reset(info, sector);
++ return ERR_PROG_ERROR;
++ }
++ }
++
++ } while ((tmpdst.ll & 0x80) != tmpsrc.ll);
++
++ break;
++ default:
++ return ERR_INVAL;
++ break;
++ }
++
++ retcode =
++ flash_full_status_check (info, sector,
++ info->buffer_write_tout,
++ "buffer write");
++ }
++
++ return retcode;
++}
++#endif /* CONFIG_SYS_FLASH_USE_BUFFER_WRITE */
++
++#ifdef CONFIG_FLASH_AST2300_DMA
++#define STCBaseAddress 0x1e620000
++
++/* for DMA */
++#define REG_FLASH_INTERRUPT_STATUS 0x08
++#define REG_FLASH_DMA_CONTROL 0x80
++#define REG_FLASH_DMA_FLASH_BASE 0x84
++#define REG_FLASH_DMA_DRAM_BASE 0x88
++#define REG_FLASH_DMA_LENGTH 0x8c
++
++#define FLASH_STATUS_DMA_BUSY 0x0000
++#define FLASH_STATUS_DMA_READY 0x0800
++#define FLASH_STATUS_DMA_CLEAR 0x0800
++
++#define FLASH_DMA_ENABLE 0x01
++
++void * memmove_dma(void * dest,const void *src,size_t count)
++{
++ ulong count_align, poll_time, data;
++
++ count_align = (count + 3) & 0xFFFFFFFC; /* 4-bytes align */
++ poll_time = 100; /* set 100 us as default */
++
++ *(ulong *) (STCBaseAddress + REG_FLASH_DMA_CONTROL) = (ulong) (~FLASH_DMA_ENABLE);
++
++ *(ulong *) (STCBaseAddress + REG_FLASH_DMA_FLASH_BASE) = (ulong *) (src);
++ *(ulong *) (STCBaseAddress + REG_FLASH_DMA_DRAM_BASE) = (ulong *) (dest);
++ *(ulong *) (STCBaseAddress + REG_FLASH_DMA_LENGTH) = (ulong) (count_align);
++ udelay(10);
++ *(ulong *) (STCBaseAddress + REG_FLASH_DMA_CONTROL) = (ulong) (FLASH_DMA_ENABLE);
++
++ /* wait poll */
++ do {
++ udelay(poll_time);
++ data = *(ulong *) (STCBaseAddress + REG_FLASH_INTERRUPT_STATUS);
++ } while (!(data & FLASH_STATUS_DMA_READY));
++
++ /* clear status */
++ *(ulong *) (STCBaseAddress + REG_FLASH_INTERRUPT_STATUS) |= FLASH_STATUS_DMA_CLEAR;
++}
++#endif
++#endif /* CFG_FLASH_CFI */
+diff --git a/board/aspeed/ast2300/flash_spi.c b/board/aspeed/ast2300/flash_spi.c
+new file mode 100755
+index 0000000..6660628
+--- /dev/null
++++ b/board/aspeed/ast2300/flash_spi.c
+@@ -0,0 +1,1639 @@
++/*
++ * 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
++ *
++ * History
++ * 01/20/2004 - combined variants of original driver.
++ * 01/22/2004 - Write performance enhancements for parallel chips (Tolunay)
++ * 01/23/2004 - Support for x8/x16 chips (Rune Raknerud)
++ * 01/27/2004 - Little endian support Ed Okerson
++ *
++ * Tested Architectures
++ * Port Width Chip Width # of banks Flash Chip Board
++ * 32 16 1 28F128J3 seranoa/eagle
++ * 64 16 1 28F128J3 seranoa/falcon
++ *
++ */
++
++/* The DEBUG define must be before common to enable debugging */
++/* #define DEBUG */
++
++#include <common.h>
++#include <asm/processor.h>
++#include <asm/byteorder.h>
++#include <environment.h>
++#ifdef CONFIG_FLASH_SPI
++
++/*
++ * This file implements a Common Flash Interface (CFI) driver for U-Boot.
++ * The width of the port and the width of the chips are determined at initialization.
++ * These widths are used to calculate the address for access CFI data structures.
++ * It has been tested on an Intel Strataflash implementation and AMD 29F016D.
++ *
++ * References
++ * JEDEC Standard JESD68 - Common Flash Interface (CFI)
++ * JEDEC Standard JEP137-A Common Flash Interface (CFI) ID Codes
++ * Intel Application Note 646 Common Flash Interface (CFI) and Command Sets
++ * Intel 290667-008 3 Volt Intel StrataFlash Memory datasheet
++ *
++ * TODO
++ *
++ * Use Primary Extended Query table (PRI) and Alternate Algorithm Query
++ * Table (ALT) to determine if protection is available
++ *
++ * Add support for other command sets Use the PRI and ALT to determine command set
++ * Verify erase and program timeouts.
++ */
++
++#ifndef CONFIG_FLASH_BANKS_LIST
++#define CONFIG_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE }
++#endif
++
++/* use CFG_MAX_FLASH_BANKS_DETECT if defined */
++#ifdef CONFIG_SYS_MAX_FLASH_BANKS_DETECT
++static ulong bank_base[CONFIG_SYS_MAX_FLASH_BANKS_DETECT] = CONFIG_FLASH_BANKS_LIST;
++flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS_DETECT]; /* FLASH chips info */
++#else
++static ulong bank_base[CONFIG_SYS_MAX_FLASH_BANKS] = CONFIG_FLASH_BANKS_LIST;
++flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* FLASH chips info */
++#endif
++
++/* Support Flash ID */
++#define STM25P64 0x172020
++#define STM25P128 0x182020
++#define N25Q256 0x19ba20
++#define N25Q512 0x20ba20
++#define S25FL064A 0x160201
++#define S25FL128P 0x182001
++#define S25FL256S 0x190201
++#define W25X16 0x1530ef
++#define W25X64 0x1730ef
++#define W25Q64BV 0x1740ef
++#define W25Q128BV 0x1840ef
++#define W25Q256FV 0x1940ef
++#define MX25L1605D 0x1520C2
++#define MX25L12805D 0x1820C2
++#define MX25L25635E 0x1920C2
++#define SST25VF016B 0x4125bf
++#define SST25VF064C 0x4b25bf
++#define AT25DF161 0x02461F
++#define AT25DF321 0x01471F
++
++/* SPI Define */
++#if defined(CONFIG_FLASH_AST2300) || defined(CONFIG_AST1300)
++#if defined(CONFIG_AST1300)
++#define STCBaseAddress 0x00620000
++#else
++#define STCBaseAddress 0x1e620000
++#endif
++#define SCU_REVISION_REGISTER 0x1e6e207c
++#define SCU_CACHE_CTRL_REGISTER 0x1e6e2118
++
++#define SPICtrlRegOffset 0x10
++#define SPICtrlRegOffset2 0x14
++
++#define SPIMiscCtrlRegOffset 0x54
++
++/* for DMA */
++#define REG_FLASH_INTERRUPT_STATUS 0x08
++#define REG_FLASH_DMA_CONTROL 0x80
++#define REG_FLASH_DMA_FLASH_BASE 0x84
++#define REG_FLASH_DMA_DRAM_BASE 0x88
++#define REG_FLASH_DMA_LENGTH 0x8c
++
++#define FLASH_STATUS_DMA_BUSY 0x0000
++#define FLASH_STATUS_DMA_READY 0x0800
++#define FLASH_STATUS_DMA_CLEAR 0x0800
++
++#define FLASH_DMA_ENABLE 0x01
++#else
++#define STCBaseAddress 0x16000000
++
++#define SPICtrlRegOffset 0x04
++#define SPICtrlRegOffset2 0x0C
++#endif /* CONFIG_FLASH_AST2300 */
++
++#define CMD_MASK 0xFFFFFFF8
++
++#define NORMALREAD 0x00
++#define FASTREAD 0x01
++#define NORMALWRITE 0x02
++#define USERMODE 0x03
++
++#define CE_LOW 0x00
++#define CE_HIGH 0x04
++
++/* AST2300 only */
++#define IOMODEx1 0x00000000
++#define IOMODEx2 0x20000000
++#define IOMODEx2_dummy 0x30000000
++#define IOMODEx4 0x40000000
++#define IOMODEx4_dummy 0x50000000
++
++#define DUMMY_COMMAND_OUT 0x00008000
++/* ~AST2300 only */
++
++/* specificspi */
++#define SpecificSPI_N25Q512 0x00000001
++
++static ulong AST2300_SPICLK_DIV[16] = {0x0F, 0x07, 0x0E, 0x06, 0x0D, 0x05, 0x0C, 0x04, \
++ 0x0B, 0x03, 0x0A, 0x02, 0x09, 0x01, 0x08, 0x00 };
++
++/*-----------------------------------------------------------------------
++ * Functions
++ */
++static void reset_flash (flash_info_t * info);
++static void enable_write (flash_info_t * info);
++static void write_status_register (flash_info_t * info, uchar data);
++static void enable4b (flash_info_t * info);
++static void enable4b_spansion (flash_info_t * info);
++static void enable4b_numonyx (flash_info_t * info);
++static ulong flash_get_size (ulong base, int banknum);
++static int flash_write_buffer (flash_info_t *info, uchar *src, ulong addr, int len);
++#if defined(CFG_ENV_IS_IN_FLASH) || defined(CFG_ENV_ADDR_REDUND) || (CFG_MONITOR_BASE >= CFG_FLASH_BASE)
++static flash_info_t *flash_get_info(ulong base);
++#endif
++
++
++/*-----------------------------------------------------------------------
++ * create an address based on the offset and the port width
++ */
++inline uchar *flash_make_addr (flash_info_t * info, flash_sect_t sect, uint offset)
++{
++#ifdef CONFIG_2SPIFLASH
++ if (info->start[0] >= PHYS_FLASH_2)
++ return ((uchar *) (info->start[sect] + (offset * 1) - (PHYS_FLASH_2 - PHYS_FLASH_2_BASE) ));
++ else
++ return ((uchar *) (info->start[sect] + (offset * 1)));
++#else
++ return ((uchar *) (info->start[sect] + (offset * 1)));
++#endif
++}
++
++/*-----------------------------------------------------------------------
++ * read a character at a port width address
++ */
++inline uchar flash_read_uchar (flash_info_t * info, uint offset)
++{
++ uchar *cp;
++
++ cp = flash_make_addr (info, 0, offset);
++#if defined(__LITTLE_ENDIAN)
++ return (cp[0]);
++#else
++ return (cp[1 - 1]);
++#endif
++}
++
++/*-----------------------------------------------------------------------
++ * read a short word by swapping for ppc format.
++ */
++ushort flash_read_ushort (flash_info_t * info, flash_sect_t sect, uint offset)
++{
++ uchar *addr;
++ ushort retval;
++
++#ifdef DEBUG
++ int x;
++#endif
++ addr = flash_make_addr (info, sect, offset);
++
++#ifdef DEBUG
++ debug ("ushort addr is at %p 1 = %d\n", addr,
++ 1);
++ for (x = 0; x < 2 * 1; x++) {
++ debug ("addr[%x] = 0x%x\n", x, addr[x]);
++ }
++#endif
++#if defined(__LITTLE_ENDIAN)
++ retval = ((addr[(1)] << 8) | addr[0]);
++#else
++ retval = ((addr[(2 * 1) - 1] << 8) |
++ addr[1 - 1]);
++#endif
++
++ debug ("retval = 0x%x\n", retval);
++ return retval;
++}
++
++/*-----------------------------------------------------------------------
++ * read a long word by picking the least significant byte of each maiximum
++ * port size word. Swap for ppc format.
++ */
++ulong flash_read_long (flash_info_t * info, flash_sect_t sect, uint offset)
++{
++ uchar *addr;
++ ulong retval;
++
++#ifdef DEBUG
++ int x;
++#endif
++ addr = flash_make_addr (info, sect, offset);
++
++#ifdef DEBUG
++ debug ("long addr is at %p 1 = %d\n", addr,
++ 1);
++ for (x = 0; x < 4 * 1; x++) {
++ debug ("addr[%x] = 0x%x\n", x, addr[x]);
++ }
++#endif
++#if defined(__LITTLE_ENDIAN)
++ retval = (addr[0] << 16) | (addr[(1)] << 24) |
++ (addr[(2 * 1)]) | (addr[(3 * 1)] << 8);
++#else
++ retval = (addr[(2 * 1) - 1] << 24) |
++ (addr[(1) - 1] << 16) |
++ (addr[(4 * 1) - 1] << 8) |
++ addr[(3 * 1) - 1];
++#endif
++ return retval;
++}
++
++/*-----------------------------------------------------------------------
++ */
++static void disable_cache(void)
++{
++#if defined(AST1300_CPU_CACHE_ENABLE)
++ ulong uldata;
++
++ uldata = *(volatile ulong *) (SCU_CACHE_CTRL_REGISTER);
++ uldata &= 0xfffffffd;
++ *(ulong *) (SCU_CACHE_CTRL_REGISTER) = uldata;
++#endif
++}
++
++static void enable_cache(void)
++{
++#if defined(AST1300_CPU_CACHE_ENABLE)
++ ulong uldata;
++
++ uldata = *(volatile ulong *) (SCU_CACHE_CTRL_REGISTER);
++ uldata |= 0x00000002;
++ *(ulong *) (SCU_CACHE_CTRL_REGISTER) = uldata;
++#endif
++}
++
++static void reset_flash (flash_info_t * info)
++{
++ ulong ulCtrlData, CtrlOffset, MiscCtrlOffset;
++
++ if (info->CE == 2)
++ {
++ CtrlOffset = SPICtrlRegOffset2;
++ }
++ else
++ {
++ CtrlOffset = SPICtrlRegOffset;
++ }
++
++#if defined(CONFIG_FLASH_AST2300) || defined(CONFIG_AST1300)
++ ulCtrlData = info->iomode | (info->readcmd << 16) | (info->tCK_Read << 8) | (info->dummybyte << 6) | FASTREAD;
++#if 0
++ if (info->quadport)
++ {
++ MiscCtrlOffset = SPIMiscCtrlRegOffset;
++ *(ulong *) (STCBaseAddress + MiscCtrlOffset) = info->dummydata;
++ ulCtrlData |= DUMMY_COMMAND_OUT;
++ }
++#endif
++#else
++ ulCtrlData = (info->readcmd << 16) | (info->tCK_Read << 8) | (info->dummybyte << 6) | FASTREAD;
++ if (info->dualport)
++ ulCtrlData |= 0x08;
++#endif
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++
++ enable_cache();
++}
++
++static void enable_write (flash_info_t * info)
++{
++ ulong base;
++ ulong ulCtrlData, CtrlOffset;
++ uchar jReg;
++
++ if (info->CE == 2)
++ {
++ CtrlOffset = SPICtrlRegOffset2;
++ }
++ else
++ {
++ CtrlOffset = SPICtrlRegOffset;
++ }
++
++ //base = info->start[0];
++ base = flash_make_addr (info, 0, 0);
++
++ ulCtrlData = (info->tCK_Write << 8);
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0x06);
++ udelay(10);
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0x05);
++ udelay(10);
++ do {
++ jReg = *(volatile uchar *) (base);
++ } while (!(jReg & 0x02));
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++}
++
++static void write_status_register (flash_info_t * info, uchar data)
++{
++ ulong base;
++ ulong ulSMMBase, ulCtrlData, CtrlOffset;
++ uchar jReg;
++
++ if (info->CE == 2)
++ {
++ CtrlOffset = SPICtrlRegOffset2;
++ }
++ else
++ {
++ CtrlOffset = SPICtrlRegOffset;
++ }
++
++ //base = info->start[0];
++ base = flash_make_addr (info, 0, 0);
++
++ enable_write (info);
++
++ ulCtrlData = (info->tCK_Write << 8);
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0x01);
++ udelay(10);
++ *(uchar *) (base) = (uchar) (data);
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0x05);
++ udelay(10);
++ do {
++ jReg = *(volatile uchar *) (base);
++ } while (jReg & 0x01);
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++}
++
++static void enable4b (flash_info_t * info)
++{
++ ulong base;
++ ulong ulSMMBase, ulCtrlData, CtrlOffset;
++ uchar jReg;
++
++ if (info->CE == 2)
++ {
++ CtrlOffset = SPICtrlRegOffset2;
++ }
++ else
++ {
++ CtrlOffset = SPICtrlRegOffset;
++ }
++
++ //base = info->start[0];
++ base = flash_make_addr (info, 0, 0);
++
++ ulCtrlData = (info->tCK_Write << 8);
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0xb7);
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++} /* enable4b */
++
++static void enable4b_spansion (flash_info_t * info)
++{
++ ulong base;
++ ulong ulSMMBase, ulCtrlData, CtrlOffset;
++ uchar jReg;
++
++ if (info->CE == 2)
++ {
++ CtrlOffset = SPICtrlRegOffset2;
++ }
++ else
++ {
++ CtrlOffset = SPICtrlRegOffset;
++ }
++
++ //base = info->start[0];
++ base = flash_make_addr (info, 0, 0);
++
++ /* Enable 4B: BAR0 D[7] = 1 */
++ ulCtrlData = (info->tCK_Write << 8);
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0x17);
++ udelay(10);
++ *(uchar *) (base) = (uchar) (0x80);
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0x16);
++ udelay(10);
++ do {
++ jReg = *(volatile uchar *) (base);
++ } while (!(jReg & 0x80));
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++} /* enable4b_spansion */
++
++static void enable4b_numonyx (flash_info_t * info)
++{
++ ulong base;
++ ulong ulSMMBase, ulCtrlData, CtrlOffset;
++ uchar jReg;
++
++ if (info->CE == 2)
++ {
++ CtrlOffset = SPICtrlRegOffset2;
++ }
++ else
++ {
++ CtrlOffset = SPICtrlRegOffset;
++ }
++
++ //base = info->start[0];
++ base = flash_make_addr (info, 0, 0);
++
++ /* Enable Write */
++ enable_write (info);
++
++ /* Enable 4B: CMD:0xB7 */
++ ulCtrlData = (info->tCK_Write << 8);
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0xB7);
++ udelay(10);
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++} /* enable4b_numonyx */
++
++/*
++ *
++ */
++static ulong flash_get_size (ulong base, int banknum)
++{
++ flash_info_t *info = &flash_info[banknum];
++ int j;
++ unsigned long sector;
++ int erase_region_size;
++ ulong ulCtrlData, CtrlOffset;
++ ulong ulID;
++ uchar ch[3];
++ ulong cpuclk, div, reg;
++ ulong WriteClk, EraseClk, ReadClk;
++ ulong vbase;
++ ulong SCURevision;
++
++ ulong ulRefPLL;
++ ulong ulDeNumerator;
++ ulong ulNumerator;
++ ulong ulOD;
++
++ disable_cache();
++
++ info->start[0] = base;
++ vbase = flash_make_addr (info, 0, 0);
++
++#if defined(CONFIG_FLASH_AST2300) || defined(CONFIG_AST1300)
++ CtrlOffset = SPICtrlRegOffset;
++ info->CE = 0;
++#else
++ if (vbase == PHYS_FLASH_1)
++ {
++ CtrlOffset = SPICtrlRegOffset2;
++ info->CE = 2;
++ }
++ else
++ {
++ CtrlOffset = SPICtrlRegOffset;
++ info->CE = 0;
++ }
++#endif
++
++ /* Get Flash ID */
++ ulCtrlData = *(ulong *) (STCBaseAddress + CtrlOffset) & CMD_MASK;
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (vbase) = (uchar) (0x9F);
++ udelay(10);
++ ch[0] = *(volatile uchar *)(vbase);
++ udelay(10);
++ ch[1] = *(volatile uchar *)(vbase);
++ udelay(10);
++ ch[2] = *(volatile uchar *)(vbase);
++ udelay(10);
++ ulCtrlData = *(ulong *) (STCBaseAddress + CtrlOffset) & CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ ulID = ((ulong)ch[0]) | ((ulong)ch[1] << 8) | ((ulong)ch[2] << 16) ;
++ info->flash_id = ulID;
++
++ //printf("SPI Flash ID: %x \n", ulID);
++
++ /* init default */
++ info->iomode = IOMODEx1;
++ info->address32 = 0;
++ info->quadport = 0;
++ info->specificspi = 0;
++
++ switch (info->flash_id)
++ {
++ case STM25P64:
++ info->sector_count = 128;
++ info->size = 0x800000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++ WriteClk = 40;
++ EraseClk = 20;
++ ReadClk = 40;
++ break;
++
++ case STM25P128:
++ info->sector_count = 64;
++ info->size = 0x1000000;
++ erase_region_size = 0x40000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++ WriteClk = 50;
++ EraseClk = 20;
++ ReadClk = 50;
++ break;
++
++ case N25Q256:
++ info->sector_count = 256;
++ info->size = 0x1000000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++ WriteClk = 50;
++ EraseClk = 20;
++ ReadClk = 50;
++#if defined(CONFIG_FLASH_AST2300) || defined(CONFIG_AST1300)
++ info->sector_count = 512;
++ info->size = 0x2000000;
++ info->address32 = 1;
++#endif
++ break;
++
++ case N25Q512:
++ info->sector_count = 256;
++ info->size = 0x1000000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++ info->specificspi = SpecificSPI_N25Q512;
++ WriteClk = 50;
++ EraseClk = 20;
++ ReadClk = 50;
++#if defined(CONFIG_FLASH_AST2300) || defined(CONFIG_AST1300)
++ info->sector_count = 1024;
++ info->size = 0x4000000;
++ info->address32 = 1;
++#endif
++ break;
++
++ case W25X16:
++ info->sector_count = 32;
++ info->size = 0x200000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x3b;
++ info->dualport = 1;
++ info->dummybyte = 1;
++ info->iomode = IOMODEx2;
++ info->buffersize = 256;
++ WriteClk = 50;
++ EraseClk = 25;
++ ReadClk = 50;
++ break;
++
++ case W25X64:
++ info->sector_count = 128;
++ info->size = 0x800000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x3b;
++ info->dualport = 1;
++ info->dummybyte = 1;
++ info->iomode = IOMODEx2;
++ info->buffersize = 256;
++ WriteClk = 50;
++ EraseClk = 25;
++ ReadClk = 50;
++ break;
++
++ case W25Q64BV:
++ info->sector_count = 128;
++ info->size = 0x800000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x3b;
++ info->dualport = 1;
++ info->dummybyte = 1;
++ info->iomode = IOMODEx2;
++ info->buffersize = 256;
++ WriteClk = 80;
++ EraseClk = 40;
++ ReadClk = 80;
++ break;
++
++ case W25Q128BV:
++ info->sector_count = 256;
++ info->size = 0x1000000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x3b;
++ info->dualport = 1;
++ info->dummybyte = 1;
++ info->iomode = IOMODEx2;
++ info->buffersize = 256;
++ WriteClk = 104;
++ EraseClk = 50;
++ ReadClk = 104;
++ break;
++
++ case W25Q256FV:
++ info->sector_count = 256;
++ info->size = 0x1000000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++ WriteClk = 50;
++ EraseClk = 20;
++ ReadClk = 50;
++#if defined(CONFIG_FLASH_AST2300) || defined(CONFIG_AST1300)
++ info->sector_count = 512;
++ info->size = 0x2000000;
++ info->address32 = 1;
++#endif
++ break;
++
++ case S25FL064A:
++ info->sector_count = 128;
++ info->size = 0x800000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++ WriteClk = 50;
++ EraseClk = 25;
++ ReadClk = 50;
++ break;
++
++ case S25FL128P:
++ info->sector_count = 256;
++ info->size = 0x1000000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++ WriteClk = 100;
++ EraseClk = 40;
++ ReadClk = 100;
++ break;
++
++ case S25FL256S:
++ info->sector_count = 256;
++ info->size = 0x1000000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++ WriteClk = 50;
++ EraseClk = 20;
++ ReadClk = 50;
++#if defined(CONFIG_FLASH_AST2300) || defined(CONFIG_AST1300)
++ info->sector_count = 512;
++ info->size = 0x2000000;
++ info->address32 = 1;
++#endif
++ break;
++
++ case MX25L25635E:
++ info->sector_count = 256;
++ info->size = 0x1000000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++ WriteClk = 50;
++ EraseClk = 20;
++ ReadClk = 50;
++#if defined(CONFIG_FLASH_AST2300) || defined(CONFIG_AST1300)
++ info->sector_count = 512;
++ info->size = 0x2000000;
++ info->address32 = 1;
++#if defined(CONFIG_FLASH_SPIx2_Dummy)
++ info->readcmd = 0xbb;
++ info->dummybyte = 1;
++ info->dualport = 1;
++ info->iomode = IOMODEx2_dummy;
++#elif defined(CONFIG_FLASH_SPIx4_Dummy)
++ info->readcmd = 0xeb;
++ info->dummybyte = 3;
++ info->dualport = 0;
++ info->iomode = IOMODEx4_dummy;
++ info->quadport = 1;
++ info->dummydata = 0xaa;
++#endif
++#endif
++ break;
++
++ case MX25L12805D:
++ info->sector_count = 256;
++ info->size = 0x1000000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++/*
++SCU7C: Silicon Revision ID Register
++D[31:24]: Chip ID
++0: AST2050/AST2100/AST2150/AST2200/AST3000
++1: AST2300
++
++D[23:16] Silicon revision ID for AST2300 generation and later
++0: A0
++1: A1
++2: A2
++.
++.
++.
++FPGA revision starts from 0x80
++
++AST2300 A0 SPI can't run faster than 50Mhz
++*/
++ WriteClk = 50;
++ EraseClk = 20;
++ ReadClk = 50;
++
++ SCURevision = *(ulong *) (SCU_REVISION_REGISTER);
++ if (((SCURevision >> 24) & 0xff) == 0x01) { //AST2300
++ if (((SCURevision >> 16) & 0xff) == 0x00) { //A0
++ WriteClk = 25;
++ EraseClk = 20;
++ ReadClk = 25;
++ }
++ }
++#if defined(CONFIG_FLASH_AST2300) || defined(CONFIG_AST1300)
++#if defined(CONFIG_FLASH_SPIx2_Dummy)
++ info->readcmd = 0xbb;
++ info->dummybyte = 1;
++ info->dualport = 1;
++ info->iomode = IOMODEx2_dummy;
++#elif defined(CONFIG_FLASH_SPIx4_Dummy)
++ info->readcmd = 0xeb;
++ info->dummybyte = 3;
++ info->dualport = 0;
++ info->iomode = IOMODEx4_dummy;
++ info->quadport = 1;
++ info->dummydata = 0xaa;
++#endif
++#endif
++ break;
++
++ case MX25L1605D:
++ info->sector_count = 32;
++ info->size = 0x200000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++ WriteClk = 50;
++ EraseClk = 20;
++ ReadClk = 50;
++ break;
++
++ case SST25VF016B:
++ info->sector_count = 32;
++ info->size = 0x200000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 1;
++ WriteClk = 50;
++ EraseClk = 25;
++ ReadClk = 50;
++ break;
++
++ case SST25VF064C:
++ info->sector_count = 128;
++ info->size = 0x800000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 1;
++ WriteClk = 50;
++ EraseClk = 25;
++ ReadClk = 50;
++ break;
++
++ case AT25DF161:
++ info->sector_count = 32;
++ info->size = 0x200000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 1;
++ WriteClk = 50;
++ EraseClk = 25;
++ ReadClk = 50;
++ break;
++
++ case AT25DF321:
++ info->sector_count = 32;
++ info->size = 0x400000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 1;
++ WriteClk = 50;
++ EraseClk = 25;
++ ReadClk = 50;
++ break;
++
++ default: /* use JEDEC ID */
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 1;
++ WriteClk = 50;
++ EraseClk = 25;
++ ReadClk = 50;
++ if ((info->flash_id & 0xFF) == 0x1F) /* Atmel */
++ {
++ switch (info->flash_id & 0x001F00)
++ {
++ case 0x000400:
++ info->sector_count = 8;
++ info->size = 0x80000;
++ break;
++ case 0x000500:
++ info->sector_count = 16;
++ info->size = 0x100000;
++ break;
++ case 0x000600:
++ info->sector_count = 32;
++ info->size = 0x200000;
++ break;
++ case 0x000700:
++ info->sector_count = 64;
++ info->size = 0x400000;
++ break;
++ case 0x000800:
++ info->sector_count = 128;
++ info->size = 0x800000;
++ break;
++ case 0x000900:
++ info->sector_count = 256;
++ info->size = 0x1000000;
++ break;
++ default:
++ printf("Can't support this SPI Flash!! \n");
++ return 0;
++ }
++ } /* Atmel JDEC */
++ else /* JDEC */
++ {
++ switch (info->flash_id & 0xFF0000)
++ {
++ case 0x120000:
++ info->sector_count = 4;
++ info->size = 0x40000;
++ break;
++ case 0x130000:
++ info->sector_count = 8;
++ info->size = 0x80000;
++ break;
++ case 0x140000:
++ info->sector_count =16;
++ info->size = 0x100000;
++ break;
++ case 0x150000:
++ info->sector_count =32;
++ info->size = 0x200000;
++ break;
++ case 0x160000:
++ info->sector_count =64;
++ info->size = 0x400000;
++ break;
++ case 0x170000:
++ info->sector_count =128;
++ info->size = 0x800000;
++ break;
++ case 0x180000:
++ info->sector_count =256;
++ info->size = 0x1000000;
++ break;
++ case 0x190000:
++ info->sector_count =256;
++ info->size = 0x1000000;
++#if defined(CONFIG_FLASH_AST2300) || defined(CONFIG_AST1300)
++ info->sector_count = 512;
++ info->size = 0x2000000;
++ info->address32 = 1;
++#if defined(CONFIG_FLASH_SPIx2_Dummy)
++ info->readcmd = 0xbb;
++ info->dummybyte = 1;
++ info->dualport = 1;
++ info->iomode = IOMODEx2_dummy;
++#elif defined(CONFIG_FLASH_SPIx4_Dummy)
++ info->readcmd = 0xeb;
++ info->dummybyte = 3;
++ info->dualport = 0;
++ info->iomode = IOMODEx4_dummy;
++ info->quadport = 1;
++ info->dummydata = 0xaa;
++#endif
++#endif
++ break;
++
++ case 0x200000:
++ info->sector_count =256;
++ info->size = 0x1000000;
++ if ((info->flash_id & 0xFF) == 0x20) /* numonyx */
++ info->specificspi = SpecificSPI_N25Q512;
++#if defined(CONFIG_FLASH_AST2300) || defined(CONFIG_AST1300)
++ info->sector_count = 1024;
++ info->size = 0x4000000;
++ info->address32 = 1;
++#if defined(CONFIG_FLASH_SPIx2_Dummy)
++ info->readcmd = 0xbb;
++ info->dummybyte = 1;
++ info->dualport = 1;
++ info->iomode = IOMODEx2_dummy;
++#elif defined(CONFIG_FLASH_SPIx4_Dummy)
++ info->readcmd = 0xeb;
++ info->dummybyte = 3;
++ info->dualport = 0;
++ info->iomode = IOMODEx4_dummy;
++ info->quadport = 1;
++ info->dummydata = 0xaa;
++#endif
++#endif
++ break;
++
++ default:
++ printf("Can't support this SPI Flash!! \n");
++ return 0;
++ }
++ } /* JDEC */
++ }
++
++ debug ("erase_region_count = %d erase_region_size = %d\n",
++ erase_region_count, erase_region_size);
++
++ sector = base;
++ for (j = 0; j < info->sector_count; j++) {
++
++ info->start[j] = sector;
++ sector += erase_region_size;
++ info->protect[j] = 0; /* default: not protected */
++ }
++
++ /* set SPI flash extended info */
++#if defined(CONFIG_AST1300)
++ if (info->size > 0x200000) /* limit MAX Flash to 2MB for AST1300 */
++ info->size = 0x200000;
++#endif
++#if defined(CONFIG_AST2400) || defined(CONFIG_AST2300) || defined(CONFIG_AST2300_FPGA_1) || defined(CONFIG_AST2300_FPGA_2) || defined(CONFIG_AST1300)
++ reg = *((volatile ulong*) 0x1e6e2024);
++ if (reg & 0x40000)
++ {
++ reg = *((volatile ulong*) 0x1e6e2070);
++
++ ulRefPLL = 24;
++ ulDeNumerator = reg & 0x0F;
++ ulNumerator = (reg & 0x07E0) >> 5;
++ ulOD = (reg & 0x10) ? 1:2;
++
++ cpuclk = ulRefPLL * ulOD * (ulNumerator + 2) / (ulDeNumerator + 1);
++ }
++ else
++ {
++ reg = *((volatile ulong*) 0x1e6e2070);
++#if defined(CONFIG_AST2400)
++ if (reg & 0x00800000) //ref. clk:25MHz
++ {
++ switch (reg & 0x300)
++ {
++ case 0x000:
++ cpuclk = 400;
++ break;
++ case 0x100:
++ cpuclk = 375;
++ break;
++ case 0x200:
++ cpuclk = 350;
++ break;
++ case 0x300:
++ cpuclk = 325;
++ break;
++ }
++ }
++ else
++ {
++ switch (reg & 0x300) //ref. clk:24MHz
++ {
++ case 0x000:
++ cpuclk = 384;
++ break;
++ case 0x100:
++ cpuclk = 360;
++ break;
++ case 0x200:
++ cpuclk = 336;
++ break;
++ case 0x300:
++ cpuclk = 312;
++ break;
++ }
++ }
++#else
++ switch (reg & 0x300)
++ {
++ case 0x000:
++ cpuclk = 384;
++ break;
++ case 0x100:
++ cpuclk = 360;
++ break;
++ case 0x200:
++ cpuclk = 336;
++ break;
++ case 0x300:
++ cpuclk = 408;
++ break;
++ }
++#endif
++ }
++
++ reg = *((volatile ulong*) 0x1e6e2070);
++ switch (reg & 0xc00)
++ {
++ case 0x000:
++ cpuclk /= 1;
++ break;
++ case 0x400:
++ cpuclk /= 2;
++ break;
++ case 0x800:
++ cpuclk /= 4;
++ break;
++ case 0xC00:
++ cpuclk /= 3;
++ break;
++ }
++#else /* AST2100 */
++ reg = *((volatile ulong*) 0x1e6e2070);
++ switch (reg & 0xe00)
++ {
++ case 0x000:
++ cpuclk = 266;
++ break;
++ case 0x200:
++ cpuclk = 233;
++ break;
++ case 0x400:
++ cpuclk = 200;
++ break;
++ case 0x600:
++ cpuclk = 166;
++ break;
++ case 0x800:
++ cpuclk = 133;
++ break;
++ case 0xA00:
++ cpuclk = 100;
++ break;
++ case 0xC00:
++ cpuclk = 300;
++ break;
++ case 0xE00:
++ cpuclk = 24;
++ break;
++ }
++ switch (reg & 0x3000)
++ {
++ case 0x1000:
++ cpuclk /= 2;
++ break;
++ case 0x2000:
++ cpuclk /= 4;
++ break;
++ case 0x3000:
++ cpuclk /= 3;
++ break;
++ }
++#endif
++
++#if defined(CONFIG_AST2400) || defined(CONFIG_AST2300) || defined(CONFIG_AST2300_FPGA_1) || defined(CONFIG_AST2300_FPGA_2) || defined(CONFIG_AST1300)
++
++#if defined(CONFIG_AST2300) || defined(CONFIG_AST1300)
++ /* limit Max SPI CLK to 50MHz (Datasheet v1.2) */
++ if (WriteClk > 50) WriteClk = 50;
++ if (EraseClk > 50) EraseClk = 50;
++ if (ReadClk > 50) ReadClk = 50;
++#endif
++
++ div = 1;
++ while ( ((cpuclk/div) > WriteClk) && (div < 16) )
++ {
++ div++;
++ }
++ info->tCK_Write = AST2300_SPICLK_DIV[div-1];
++
++ div = 1;
++ while ( ((cpuclk/div) > EraseClk) && (div < 16) )
++ {
++ div++;
++ }
++ info->tCK_Erase = AST2300_SPICLK_DIV[div-1];
++
++ div = 1;
++ while ( ((cpuclk/div) > ReadClk) && (div < 16) )
++ {
++ div++;
++ }
++ info->tCK_Read = AST2300_SPICLK_DIV[div-1];
++#else
++ div = 2;
++ info->tCK_Write = 7;
++ while ( (cpuclk/div) > WriteClk )
++ {
++ info->tCK_Write--;
++ div +=2;
++ }
++ div = 2;
++ info->tCK_Erase = 7;
++ while ( (cpuclk/div) > EraseClk )
++ {
++ info->tCK_Erase--;
++ div +=2;
++ }
++ div = 2;
++ info->tCK_Read = 7;
++ while ( (cpuclk/div) > ReadClk )
++ {
++ info->tCK_Read--;
++ div +=2;
++ }
++#endif
++
++ /* unprotect flash */
++ write_status_register(info, 0);
++
++ if (info->quadport)
++ write_status_register(info, 0x40); /* enable QE */
++
++ if (info->address32)
++ {
++ reg = *((volatile ulong*) 0x1e6e2070); /* set H/W Trappings */
++ reg |= 0x10;
++ *((volatile ulong*) 0x1e6e2070) = reg;
++
++ reg = *((volatile ulong*) 0x1e620004); /* enable 32b control bit*/
++ reg |= (0x01 << info->CE);
++ *((volatile ulong*) 0x1e620004) = reg;
++
++ /* set flash chips to 32bits addressing mode */
++ if ((info->flash_id & 0xFF) == 0x01) /* Spansion */
++ enable4b_spansion(info);
++ else if ((info->flash_id & 0xFF) == 0x20) /* Numonyx */
++ enable4b_numonyx(info);
++ else /* MXIC, Winbond */
++ enable4b(info);
++
++ }
++
++ reset_flash(info);
++
++ return (info->size);
++}
++
++
++/*-----------------------------------------------------------------------
++ */
++static int flash_write_buffer (flash_info_t *info, uchar *src, ulong addr, int len)
++{
++ ulong j, base, offset;
++ ulong ulSMMBase, ulCtrlData, CtrlOffset;
++ uchar jReg;
++
++ if (info->CE == 2)
++ {
++ CtrlOffset = SPICtrlRegOffset2;
++ }
++ else
++ {
++ CtrlOffset = SPICtrlRegOffset;
++ }
++
++ base = info->start[0];
++ offset = addr - base;
++ base = flash_make_addr (info, 0, 0);
++
++ enable_write (info);
++
++ ulCtrlData = (info->tCK_Write << 8);
++
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0x02);
++ udelay(10);
++ if (info->address32)
++ {
++ *(uchar *) (base) = (uchar) ((offset & 0xff000000) >> 24);
++ udelay(10);
++ }
++ *(uchar *) (base) = (uchar) ((offset & 0xff0000) >> 16);
++ udelay(10);
++ *(uchar *) (base) = (uchar) ((offset & 0x00ff00) >> 8);
++ udelay(10);
++ *(uchar *) (base) = (uchar) ((offset & 0x0000ff));
++ udelay(10);
++
++ for (j=0; j<len; j++)
++ {
++ *(uchar *) (base) = *(uchar *) (src++);
++ udelay(10);
++ }
++
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0x05);
++ udelay(10);
++ do {
++ jReg = *(volatile uchar *) (base);
++ } while ((jReg & 0x01));
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++ /* RFSR */
++ if (info->specificspi == SpecificSPI_N25Q512)
++ {
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0x70);
++ udelay(10);
++ do {
++ jReg = *(volatile uchar *) (base);
++ } while (!(jReg & 0x80));
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ }
++}
++
++/*-----------------------------------------------------------------------
++ *
++ * export functions
++ *
++ */
++
++/*-----------------------------------------------------------------------
++ *
++ */
++unsigned long flash_init (void)
++{
++ unsigned long size = 0;
++ int i;
++
++ /* Init: no FLASHes known */
++ for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
++ flash_info[i].flash_id = FLASH_UNKNOWN;
++ size += flash_info[i].size = flash_get_size (bank_base[i], i);
++ if (flash_info[i].flash_id == FLASH_UNKNOWN) {
++#ifndef CFG_FLASH_QUIET_TEST
++ printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
++ i, flash_info[i].size, flash_info[i].size << 20);
++#endif /* CFG_FLASH_QUIET_TEST */
++ }
++ }
++
++ /* Monitor protection ON by default */
++#if (CONFIG_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
++ flash_protect (FLAG_PROTECT_SET,
++ CONFIG_MONITOR_BASE,
++ CONFIG_MONITOR_BASE + monitor_flash_len - 1,
++ flash_get_info(CONFIG_MONITOR_BASE));
++#endif
++
++ /* Environment protection ON by default */
++#ifdef CONFIG_ENV_IS_IN_FLASH
++ flash_protect (FLAG_PROTECT_SET,
++ CONFIG_ENV_ADDR,
++ CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
++ flash_get_info(CONFIG_ENV_ADDR));
++#endif
++
++ /* Redundant environment protection ON by default */
++#ifdef CONFIG_ENV_ADDR_REDUND
++ flash_protect (FLAG_PROTECT_SET,
++ CONFIG_ENV_ADDR_REDUND,
++ CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SIZE_REDUND - 1,
++ flash_get_info(CONFIG_ENV_ADDR_REDUND));
++#endif
++ return (size);
++}
++
++/*-----------------------------------------------------------------------
++ */
++#if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || (CONFIG_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
++static flash_info_t *flash_get_info(ulong base)
++{
++ int i;
++ flash_info_t * info = 0;
++
++ for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i ++) {
++ info = & flash_info[i];
++ if (info->size && info->start[0] <= base &&
++ base <= info->start[0] + info->size - 1)
++ break;
++ }
++
++ return i == CONFIG_SYS_MAX_FLASH_BANKS ? 0 : info;
++}
++#endif
++
++/*-----------------------------------------------------------------------
++ */
++int flash_erase (flash_info_t * info, int s_first, int s_last)
++{
++ int rcode = 0;
++ int prot;
++ flash_sect_t sect;
++
++ ulong base, offset;
++ ulong ulSMMBase, ulCtrlData, CtrlOffset;
++ uchar jReg;
++
++ disable_cache();
++
++ if (info->CE == 2)
++ {
++ CtrlOffset = SPICtrlRegOffset2;
++ }
++ else
++ {
++ CtrlOffset = SPICtrlRegOffset;
++ }
++
++ if ((s_first < 0) || (s_first > s_last)) {
++ puts ("- no sectors to erase\n");
++ return 1;
++ }
++
++ prot = 0;
++ for (sect = s_first; sect <= s_last; ++sect) {
++ if (info->protect[sect]) {
++ prot++;
++ }
++ }
++ if (prot) {
++ printf ("- Warning: %d protected sectors will not be erased!\n", prot);
++ } else {
++ putc ('\n');
++ }
++
++ ulCtrlData = (info->tCK_Erase << 8);
++ for (sect = s_first; sect <= s_last; sect++) {
++ if (info->protect[sect] == 0) { /* not protected */
++ /* start erasing */
++ enable_write(info);
++
++ base = info->start[0];
++ offset = info->start[sect] - base;
++ base = flash_make_addr (info, 0, 0);
++
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0xd8);
++ udelay(10);
++ if (info->address32)
++ {
++ *(uchar *) (base) = (uchar) ((offset & 0xff000000) >> 24);
++ udelay(10);
++ }
++ *(uchar *) (base) = (uchar) ((offset & 0xff0000) >> 16);
++ udelay(10);
++ *(uchar *) (base) = (uchar) ((offset & 0x00ff00) >> 8);
++ udelay(10);
++ *(uchar *) (base) = (uchar) ((offset & 0x0000ff));
++ udelay(10);
++
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0x05);
++ udelay(10);
++ do {
++ jReg = *(volatile uchar *) (base);
++ } while ((jReg & 0x01));
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++ /* RFSR */
++ if (info->specificspi == SpecificSPI_N25Q512)
++ {
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0x70);
++ udelay(10);
++ do {
++ jReg = *(volatile uchar *) (base);
++ } while (!(jReg & 0x80));
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ }
++
++ putc ('.');
++ }
++ }
++ puts (" done\n");
++
++ reset_flash(info);
++
++ return rcode;
++}
++
++/*-----------------------------------------------------------------------
++ */
++void flash_print_info (flash_info_t * info)
++{
++ putc ('\n');
++ return;
++}
++
++/*-----------------------------------------------------------------------
++ * Copy memory to flash, returns:
++ * 0 - OK
++ * 1 - write timeout
++ * 2 - Flash not erased
++ */
++int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
++{
++ int count;
++ unsigned char pat[] = {'|', '-', '/', '\\'};
++ int patcnt;
++
++ disable_cache();
++
++ /* get lower aligned address */
++ if (addr & (info->buffersize - 1))
++ {
++ count = cnt >= info->buffersize ? (info->buffersize - (addr & 0xff)):cnt;
++ flash_write_buffer (info, src, addr, count);
++ addr+= count;
++ src += count;
++ cnt -= count;
++ }
++
++ /* prog */
++ while (cnt > 0) {
++ count = cnt >= info->buffersize ? info->buffersize:cnt;
++ flash_write_buffer (info, src, addr, count);
++ addr+= count;
++ src += count;
++ cnt -= count;
++ printf("%c\b", pat[(patcnt++) & 0x03]);
++ }
++
++ reset_flash(info);
++
++ return (0);
++}
++
++#ifdef CONFIG_FLASH_AST2300_DMA
++void * memmove_dma(void * dest,const void *src,size_t count)
++{
++ ulong count_align, poll_time, data;
++
++ count_align = (count + 3) & 0xFFFFFFFC; /* 4-bytes align */
++ poll_time = 100; /* set 100 us as default */
++
++ /* force end of burst read */
++ *(volatile ulong *) (STCBaseAddress + SPICtrlRegOffset) |= CE_HIGH;
++ *(volatile ulong *) (STCBaseAddress + SPICtrlRegOffset) &= ~CE_HIGH;
++
++ *(ulong *) (STCBaseAddress + REG_FLASH_DMA_CONTROL) = (ulong) (~FLASH_DMA_ENABLE);
++ *(ulong *) (STCBaseAddress + REG_FLASH_DMA_FLASH_BASE) = (ulong *) (src);
++ *(ulong *) (STCBaseAddress + REG_FLASH_DMA_DRAM_BASE) = (ulong *) (dest);
++ *(ulong *) (STCBaseAddress + REG_FLASH_DMA_LENGTH) = (ulong) (count_align);
++ *(ulong *) (STCBaseAddress + REG_FLASH_DMA_CONTROL) = (ulong) (FLASH_DMA_ENABLE);
++
++ /* wait poll */
++ do {
++ udelay(poll_time);
++ data = *(ulong *) (STCBaseAddress + REG_FLASH_INTERRUPT_STATUS);
++ } while (!(data & FLASH_STATUS_DMA_READY));
++
++ /* clear status */
++ *(ulong *) (STCBaseAddress + REG_FLASH_INTERRUPT_STATUS) |= FLASH_STATUS_DMA_CLEAR;
++}
++#endif
++#endif /* CONFIG_FLASH_SPI */
+diff --git a/board/aspeed/ast2300/hactest.c b/board/aspeed/ast2300/hactest.c
+new file mode 100755
+index 0000000..bfa87d5
+--- /dev/null
++++ b/board/aspeed/ast2300/hactest.c
+@@ -0,0 +1,762 @@
++/*
++ * 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
++ */
++
++/*
++ * Diagnostics support
++ */
++#include <common.h>
++#include <command.h>
++#include <post.h>
++#include "slt.h"
++
++#if ((CFG_CMD_SLT & CFG_CMD_HACTEST) && defined(CONFIG_SLT))
++#include "hactest.h"
++
++#include "aes.c"
++#include "rc4.c"
++
++static unsigned char crypto_src[CRYPTO_MAX_SRC], crypto_dst[CRYPTO_MAX_DST], crypto_context[CRYPTO_MAX_CONTEXT];
++static unsigned char hash_src[HASH_MAX_SRC], hash_dst[HASH_MAX_DST], hmac_key[HMAC_MAX_KEY];
++
++/*
++ * table
++ */
++static aes_test aestest[] = {
++ { CRYPTOMODE_ECB, 128,
++ {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, '\0'},
++ {0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34, '\0'},
++ {0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a, 0x0b, 0x32, '\0'} },
++ {0xFF, 0xFF, "", "", ""}, /* End Mark */
++};
++
++static rc4_test rc4test[] = {
++ {{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, '\0'},
++ {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, '\0'}},
++ {{0xff}, {0xff}}, /* End Mark */
++};
++
++static hash_test hashtest[] = {
++ {HASHMODE_SHA1, 20,
++ "abc",
++ {0x53, 0x20, 0xb0, 0x8c, 0xa1, 0xf5, 0x74, 0x62, 0x50, 0x71, 0x89, 0x41, 0xc5, 0x0a, 0xdf, 0x4e, 0xbb, 0x55, 0x76, 0x06, '\0'}},
++ {0xFF, 0xFF, "", ""}, /* End Mark */
++};
++
++static hmac_test hmactest[] = {
++ {HASHMODE_SHA1, 64, 20,
++ {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, '\0' },
++ "Sample #1",
++ {0xbf, 0x39, 0xda, 0xb1, 0x7d, 0xc2, 0xe1, 0x23, 0x0d, 0x28, 0x35, 0x3b, 0x8c, 0xcb, 0x14, 0xb6, 0x22, 0x02, 0x65, 0xb3, '\0'}},
++ {0xFF, 0xFF, 0xFF, "", "", ""}, /* End Mark */
++};
++
++void EnableHMAC(void)
++{
++ unsigned long ulData;
++
++ /* init SCU */
++ *(unsigned long *) (0x1e6e2000) = 0x1688a8a8;
++
++ ulData = *(volatile unsigned long *) (0x1e6e200c);
++ ulData &= 0xfdfff;
++ *(unsigned long *) (0x1e6e200c) = ulData;
++ udelay(100);
++ ulData = *(volatile unsigned long *) (0x1e6e2004);
++ ulData &= 0xfffef;
++ *(unsigned long *) (0x1e6e2004) = ulData;
++
++}
++
++/* AES */
++void aes_enc_ast3000(aes_context *ctx, uint8 *input, uint8 *iv, uint8 *output, uint32 ulMsgLength , uint32 ulAESMode)
++{
++
++ unsigned long i, ulTemp, ulCommand;
++ unsigned char ch;
++ unsigned char *pjsrc, *pjdst, *pjcontext;
++
++ ulCommand = CRYPTO_ENABLE_RW | CRYPTO_ENABLE_CONTEXT_LOAD | CRYPTO_ENABLE_CONTEXT_SAVE | \
++ CRYPTO_AES | CRYPTO_ENCRYPTO | CRYPTO_SYNC_MODE_ASYNC;
++
++ switch (ctx->nr)
++ {
++ case 10:
++ ulCommand |= CRYPTO_AES128;
++ break;
++ case 12:
++ ulCommand |= CRYPTO_AES192;
++ break;
++ case 14:
++ ulCommand |= CRYPTO_AES256;
++ break;
++ }
++
++ switch (ulAESMode)
++ {
++ case CRYPTOMODE_ECB:
++ ulCommand |= CRYPTO_AES_ECB;
++ break;
++ case CRYPTOMODE_CBC:
++ ulCommand |= CRYPTO_AES_CBC;
++ break;
++ case CRYPTOMODE_CFB:
++ ulCommand |= CRYPTO_AES_CFB;
++ break;
++ case CRYPTOMODE_OFB:
++ ulCommand |= CRYPTO_AES_OFB;
++ break;
++ case CRYPTOMODE_CTR:
++ ulCommand |= CRYPTO_AES_CTR;
++ break;
++ }
++
++ pjsrc = (unsigned char *) m16byteAlignment((unsigned long) crypto_src);
++ pjdst = (unsigned char *) m16byteAlignment((unsigned long) crypto_dst);
++ pjcontext = (unsigned char *) m16byteAlignment((unsigned long) crypto_context);
++
++ /* Init HW */
++ *(unsigned long *) (HAC_REG_BASE + REG_CRYPTO_SRC_BASE_OFFSET) = (unsigned long) pjsrc;
++ *(unsigned long *) (HAC_REG_BASE + REG_CRYPTO_DST_BASE_OFFSET) = (unsigned long) pjdst;
++ *(unsigned long *) (HAC_REG_BASE + REG_CRYPTO_CONTEXT_BASE_OFFSET) = (unsigned long) pjcontext;
++ *(unsigned long *) (HAC_REG_BASE + REG_CRYPTO_LEN_OFFSET) = ulMsgLength;
++
++ /* Set source */
++ for (i=0; i< ulMsgLength; i++)
++ {
++ ch = *(uint8 *)(input + i);
++ *(uint8 *) (pjsrc + i) = ch;
++ }
++
++ /* Set Context */
++ /* Set IV */
++ for (i=0; i<16; i++)
++ {
++ ch = *(uint8 *) (iv + i);
++ *(uint8 *) (pjcontext + i) = ch;
++ }
++
++ /* Set Expansion Key */
++ for (i=0; i<(4*(ctx->nr+1)); i++)
++ {
++ ulTemp = ((ctx->erk[i] & 0xFF) << 24) + ((ctx->erk[i] & 0xFF00) << 8) + ((ctx->erk[i] & 0xFF0000) >> 8) + ((ctx->erk[i] & 0xFF000000) >> 24);
++ *(uint32 *) (pjcontext + i*4 + 16) = ulTemp;
++ }
++
++ /* fire cmd */
++ *(unsigned long *) (HAC_REG_BASE + REG_CRYPTO_CMD_BASE_OFFSET) = ulCommand;
++ do {
++ ulTemp = *(volatile unsigned long *) (HAC_REG_BASE + REG_CRYPTO_STATUS_OFFSET);
++ } while (ulTemp & CRYPTO_BUSY);
++
++ /* Output */
++ for (i=0; i<ulMsgLength; i++)
++ {
++ ch = *(uint8 *) (pjdst + i);
++ *(uint8 *) (output + i) = ch;
++ }
++
++} /* aes_enc_ast3000 */
++
++
++void aes_dec_ast3000(aes_context *ctx, uint8 *input, uint8 *iv, uint8 *output, uint32 ulMsgLength , uint32 ulAESMode)
++{
++ unsigned long i, ulTemp, ulCommand;
++ unsigned char ch;
++ unsigned char *pjsrc, *pjdst, *pjcontext;
++
++ ulCommand = CRYPTO_ENABLE_RW | CRYPTO_ENABLE_CONTEXT_LOAD | CRYPTO_ENABLE_CONTEXT_SAVE | \
++ CRYPTO_AES | CRYPTO_DECRYPTO | CRYPTO_SYNC_MODE_ASYNC;
++
++ switch (ctx->nr)
++ {
++ case 10:
++ ulCommand |= CRYPTO_AES128;
++ break;
++ case 12:
++ ulCommand |= CRYPTO_AES192;
++ break;
++ case 14:
++ ulCommand |= CRYPTO_AES256;
++ break;
++ }
++
++ switch (ulAESMode)
++ {
++ case CRYPTOMODE_ECB:
++ ulCommand |= CRYPTO_AES_ECB;
++ break;
++ case CRYPTOMODE_CBC:
++ ulCommand |= CRYPTO_AES_CBC;
++ break;
++ case CRYPTOMODE_CFB:
++ ulCommand |= CRYPTO_AES_CFB;
++ break;
++ case CRYPTOMODE_OFB:
++ ulCommand |= CRYPTO_AES_OFB;
++ break;
++ case CRYPTOMODE_CTR:
++ ulCommand |= CRYPTO_AES_CTR;
++ break;
++ }
++
++ pjsrc = (unsigned char *) m16byteAlignment((unsigned long) crypto_src);
++ pjdst = (unsigned char *) m16byteAlignment((unsigned long) crypto_dst);
++ pjcontext = (unsigned char *) m16byteAlignment((unsigned long) crypto_context);
++
++ /* Init HW */
++ *(unsigned long *) (HAC_REG_BASE + REG_CRYPTO_SRC_BASE_OFFSET) = (unsigned long) pjsrc;
++ *(unsigned long *) (HAC_REG_BASE + REG_CRYPTO_DST_BASE_OFFSET) = (unsigned long) pjdst;
++ *(unsigned long *) (HAC_REG_BASE + REG_CRYPTO_CONTEXT_BASE_OFFSET) = (unsigned long) pjcontext;
++ *(unsigned long *) (HAC_REG_BASE + REG_CRYPTO_LEN_OFFSET) = ulMsgLength;
++
++ /* Set source */
++ for (i=0; i< ulMsgLength; i++)
++ {
++ ch = *(uint8 *)(input + i);
++ *(uint8 *) (pjsrc + i) = ch;
++ }
++
++ /* Set Context */
++ /* Set IV */
++ for (i=0; i<16; i++)
++ {
++ ch = *(uint8 *) (iv + i);
++ *(uint8 *) (pjcontext + i) = ch;
++ }
++
++ /* Set Expansion Key */
++ for (i=0; i<(4*(ctx->nr+1)); i++)
++ {
++ ulTemp = ((ctx->erk[i] & 0xFF) << 24) + ((ctx->erk[i] & 0xFF00) << 8) + ((ctx->erk[i] & 0xFF0000) >> 8) + ((ctx->erk[i] & 0xFF000000) >> 24);
++ *(uint32 *) (pjcontext + i*4 + 16) = ulTemp;
++ }
++
++ /* fire cmd */
++ *(unsigned long *) (HAC_REG_BASE + REG_CRYPTO_CMD_BASE_OFFSET) = ulCommand;
++ do {
++ ulTemp = *(volatile unsigned long *) (HAC_REG_BASE + REG_CRYPTO_STATUS_OFFSET);
++ } while (ulTemp & CRYPTO_BUSY);
++
++ /* Output */
++ for (i=0; i<ulMsgLength; i++)
++ {
++ ch = *(uint8 *) (pjdst + i);
++ *(uint8 *) (output + i) = ch;
++ }
++
++} /* aes_dec_ast3000 */
++
++void rc4_crypt_ast3000(uint8 *data, int ulMsgLength, uint8 *rc4_key, uint32 ulKeyLength)
++{
++ struct rc4_state s;
++ unsigned long i, ulTemp, ulCommand;
++ unsigned char ch;
++ unsigned char *pjsrc, *pjdst, *pjcontext;
++
++ ulCommand = CRYPTO_ENABLE_RW | CRYPTO_ENABLE_CONTEXT_LOAD | CRYPTO_ENABLE_CONTEXT_SAVE | \
++ CRYPTO_RC4 | CRYPTO_SYNC_MODE_ASYNC;
++
++ rc4_setup( &s, rc4_key, ulKeyLength );
++
++ pjsrc = (unsigned char *) m16byteAlignment((unsigned long) crypto_src);
++ pjdst = (unsigned char *) m16byteAlignment((unsigned long) crypto_dst);
++ pjcontext = (unsigned char *) m16byteAlignment((unsigned long) crypto_context);
++
++ /* Init HW */
++ *(uint32 *) (HAC_REG_BASE + REG_CRYPTO_SRC_BASE_OFFSET) = (unsigned long) pjsrc;
++ *(uint32 *) (HAC_REG_BASE + REG_CRYPTO_DST_BASE_OFFSET) = (unsigned long) pjdst;
++ *(uint32 *) (HAC_REG_BASE + REG_CRYPTO_CONTEXT_BASE_OFFSET) = (unsigned long) pjcontext;
++ *(uint32 *) (HAC_REG_BASE + REG_CRYPTO_LEN_OFFSET) = ulMsgLength;
++
++
++ /* Set source */
++ for (i=0; i< ulMsgLength; i++)
++ {
++ ch = *(uint8 *)(data + i);
++ *(uint8 *) (pjsrc + i) = ch;
++ }
++
++ /* Set Context */
++ /* Set i, j */
++ *(uint32 *) (pjcontext + 8) = 0x0001;
++
++ /* Set Expansion Key */
++ for (i=0; i<(256/4); i++)
++ {
++ ulTemp = (s.m[i * 4] & 0xFF) + ((s.m[i * 4 + 1] & 0xFF) << 8) + ((s.m[i * 4 + 2] & 0xFF) << 16) + ((s.m[i * 4+ 3] & 0xFF) << 24);
++ *(uint32 *) (pjcontext + i*4 + 16) = ulTemp;
++ }
++
++ /* fire cmd */
++ *(uint32 *) (HAC_REG_BASE + REG_CRYPTO_CMD_BASE_OFFSET) = ulCommand;
++ do {
++ ulTemp = *(volatile uint32 *) (HAC_REG_BASE + REG_CRYPTO_STATUS_OFFSET);
++ } while (ulTemp & CRYPTO_BUSY);
++
++ /* Output */
++ for (i=0; i<ulMsgLength; i++)
++ {
++ ch = *(volatile uint8 *) (pjdst + i);
++ *(uint8 *) (data + i) = ch;
++ }
++
++} /* rc4_crypt_ast3000 */
++
++/* Hash */
++void hash_ast3000(uint8 *msg, uint32 ulLength, unsigned char *output, uint32 ulHashMode)
++{
++ uint32 i, ulTemp, ulCommand, ulDigestLength, ulMyMsgLength;
++ uint8 ch;
++ unsigned char *pjsrc, *pjdst;
++
++ /* Get Info */
++ switch (ulHashMode)
++ {
++ case HASHMODE_MD5:
++ ulCommand = HASH_ALG_SELECT_MD5;
++ ulDigestLength = 16;
++ break;
++ case HASHMODE_SHA1:
++ ulCommand = HASH_ALG_SELECT_SHA1 | 0x08;
++ ulDigestLength = 20;
++ break;
++ case HASHMODE_SHA256:
++ ulCommand = HASH_ALG_SELECT_SHA256 | 0x08;
++ ulDigestLength = 32;
++ break;
++ case HASHMODE_SHA224:
++ ulCommand = HASH_ALG_SELECT_SHA224 | 0x08;
++ ulDigestLength = 28;
++ break;
++ }
++
++ pjsrc = (unsigned char *) m16byteAlignment((unsigned long) hash_src);
++ pjdst = (unsigned char *) m16byteAlignment((unsigned long) hash_dst);
++
++ /* 16byte alignment */
++ ulMyMsgLength = m16byteAlignment(ulLength);
++
++ /* Init. HW */
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_SRC_BASE_OFFSET) = (unsigned long) pjsrc;
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_DST_BASE_OFFSET) = (unsigned long) pjdst;
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_LEN_OFFSET) = ulMyMsgLength;
++
++ /* write src */
++ for (i=0; i<ulLength; i++)
++ {
++ ch = *(uint8 *)(msg+i);
++ *(uint8 *) (pjsrc + i) = ch;
++ }
++ for (i=ulLength; i<ulMyMsgLength; i++)
++ *(uint8 *) (pjsrc + i) = 0;
++
++ /* fire cmd */
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_CMD_OFFSET) = ulCommand;
++
++ /* get digest */
++ do {
++ ulTemp = *(volatile uint32 *) (HAC_REG_BASE + REG_HASH_STATUS_OFFSET);
++ } while (ulTemp & HASH_BUSY);
++
++ for (i=0; i<ulDigestLength; i++)
++ {
++ ch = *(volatile uint8 *) (pjdst + i);
++ *(uint8 *) (output + i) = ch;
++ }
++
++} /* hash_ast3000 */
++
++/* HMAC */
++void hmackey_ast3000(uint8 *key, uint32 ulKeyLength, uint32 ulHashMode)
++{
++ uint32 i, ulBlkLength, ulDigestLength, ulTemp, ulCommand;
++ uint8 k0[64], sum[32];
++ uint8 ch;
++ unsigned char *pjsrc, *pjdst, *pjkey;
++
++ /* Get Info */
++ switch (ulHashMode)
++ {
++ case HASHMODE_MD5:
++ ulCommand = HASH_ALG_SELECT_MD5;
++ ulDigestLength = 16;
++ break;
++ case HASHMODE_SHA1:
++ ulCommand = HASH_ALG_SELECT_SHA1 | 0x08;
++ ulDigestLength = 20;
++ break;
++ case HASHMODE_SHA256:
++ ulCommand = HASH_ALG_SELECT_SHA256 | 0x08;
++ ulDigestLength = 32;
++ break;
++ case HASHMODE_SHA224:
++ ulCommand = HASH_ALG_SELECT_SHA224 | 0x08;
++ ulDigestLength = 28;
++ break;
++ }
++ ulBlkLength = 64; /* MD5, SHA1/256/224: 64bytes */
++
++ /* Init */
++ memset( (void *) k0, 0, 64); /* reset to zero */
++ memset( (void *) sum, 0, 32); /* reset to zero */
++
++ /* Get k0 */
++ if (ulKeyLength <= ulBlkLength)
++ memcpy( (void *) k0, (void *) key, ulKeyLength );
++ else /* (ulKeyLength > ulBlkLength) */
++ {
++ hash_ast3000(key, ulKeyLength, sum, ulHashMode);
++ memcpy( (void *) k0, (void *) sum, ulDigestLength );
++ }
++
++ pjsrc = (unsigned char *) m16byteAlignment((unsigned long) hash_src);
++ pjdst = (unsigned char *) m16byteAlignment((unsigned long) hash_dst);
++ pjkey = (unsigned char *) m64byteAlignment((unsigned long) hmac_key);
++
++ /* Calculate digest */
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_SRC_BASE_OFFSET) = (unsigned long) pjsrc;
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_DST_BASE_OFFSET) = (unsigned long) pjdst;
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_KEY_BASE_OFFSET) = (unsigned long) pjkey;
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_LEN_OFFSET) = ulBlkLength;
++
++ /* write key to src */
++ for (i=0; i<ulBlkLength; i++)
++ {
++ ch = *(uint8 *)(k0+i);
++ *(uint8 *) (pjsrc + i) = ch;
++ }
++
++ /* fire cmd for calculate */
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_CMD_OFFSET) = ulCommand | HAC_DIGEST_CAL_ENABLE;
++ do {
++ ulTemp = *(volatile uint32 *) (HAC_REG_BASE + REG_HASH_STATUS_OFFSET);
++ } while (ulTemp & HASH_BUSY);
++
++} /* hmackey_ast3000 */
++
++void hmac_ast3000(uint8 *key, uint32 ulKeyLength, uint8 *msg, uint32 ulMsgLength, uint32 ulHashMode, unsigned char *output)
++{
++ uint32 i, ulTemp, ulCommand, ulDigestLength, ulMyMsgLength;;
++ uint8 ch;
++ unsigned char *pjsrc, *pjdst, *pjkey;
++
++ /* Calculate digest */
++ switch (ulHashMode)
++ {
++ case HASHMODE_MD5:
++ ulCommand = HASH_ALG_SELECT_MD5;
++ ulDigestLength = 16;
++ break;
++ case HASHMODE_SHA1:
++ ulCommand = HASH_ALG_SELECT_SHA1 | 0x08;
++ ulDigestLength = 20;
++ break;
++ case HASHMODE_SHA256:
++ ulCommand = HASH_ALG_SELECT_SHA256 | 0x08;
++ ulDigestLength = 32;
++ break;
++ case HASHMODE_SHA224:
++ ulCommand = HASH_ALG_SELECT_SHA224 | 0x08;
++ ulDigestLength = 28;
++ break;
++ }
++
++ pjsrc = (unsigned char *) m16byteAlignment((unsigned long) hash_src);
++ pjdst = (unsigned char *) m16byteAlignment((unsigned long) hash_dst);
++ pjkey = (unsigned char *) m64byteAlignment((unsigned long) hmac_key);
++
++ /* 16byte alignment */
++ ulMyMsgLength = m16byteAlignment(ulMsgLength);
++
++ /* Init. HW */
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_SRC_BASE_OFFSET) = (unsigned long) pjsrc;
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_DST_BASE_OFFSET) = (unsigned long) pjdst;
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_KEY_BASE_OFFSET) = (unsigned long) pjkey;
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_LEN_OFFSET) = ulMyMsgLength;
++
++ /* write Text to src */
++ for (i=0; i<ulMsgLength; i++)
++ {
++ ch = *(uint8 *)(msg+i);
++ *(uint8 *) (pjsrc + i) = ch;
++ }
++ for (i=ulMsgLength; i<ulMyMsgLength; i++)
++ *(uint8 *) (pjsrc + i) = 0;
++
++ /* fire cmd */
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_CMD_OFFSET) = ulCommand | HAC_ENABLE;
++ do {
++ ulTemp = *(volatile uint32 *) (HAC_REG_BASE + REG_HASH_STATUS_OFFSET);
++ } while (ulTemp & HASH_BUSY);
++
++ /* Output Digest */
++ for (i=0; i<ulDigestLength; i++)
++ {
++ ch = *(uint8 *) (pjdst + i);
++ *(uint8 *) (output + i) = ch;
++ }
++
++} /* hmac_ast3000 */
++
++/* main hactest procedure */
++int do_hactest (void)
++{
++ unsigned long i, j, Flags = 0;
++ aes_test *pjaes_test;
++ aes_context aes_ctx;
++ unsigned char AES_Mode[8], aes_output[64];
++ unsigned long ulAESMsgLength;
++
++ rc4_test *pjrc4_test;
++ unsigned char rc4_buf_sw[64], rc4_buf_hw[64];
++ unsigned long ulRC4KeyLength, ulRC4MsgLength;
++
++ hash_test *pjhash_test;
++ unsigned char HASH_Mode[8], hash_out[64];
++
++ hmac_test *pjhmac_test;
++ unsigned char HMAC_Mode[8], hmac_out[64];
++
++ EnableHMAC();
++
++ /* AES Test */
++ pjaes_test = aestest;
++ while (pjaes_test->aes_mode != 0xFF)
++ {
++
++ if (pjaes_test->aes_mode == CRYPTOMODE_CBC)
++ strcpy (AES_Mode, "CBC");
++ else if (pjaes_test->aes_mode == CRYPTOMODE_CFB)
++ strcpy (AES_Mode, "CFB");
++ else if (pjaes_test->aes_mode == CRYPTOMODE_OFB)
++ strcpy (AES_Mode, "OFB");
++ else if (pjaes_test->aes_mode == CRYPTOMODE_CTR)
++ strcpy (AES_Mode, "CTR");
++ else
++ strcpy (AES_Mode, "ECB");
++
++ /* Get Msg. Length */
++ ulAESMsgLength = strlen(pjaes_test->plaintext);
++ j = ( (ulAESMsgLength + 15) >> 4) << 4;
++ for (i=ulAESMsgLength; i<j; i++)
++ pjaes_test->plaintext[i] = 0;
++ ulAESMsgLength = j;
++
++ aes_set_key(&aes_ctx, pjaes_test->key, pjaes_test->key_length);
++
++ /* Encryption Test */
++ aes_enc_ast3000(&aes_ctx, pjaes_test->plaintext, pjaes_test->key, aes_output, ulAESMsgLength, pjaes_test->aes_mode);
++ if (strncmp(aes_output, pjaes_test->ciphertext, ulAESMsgLength))
++ {
++ Flags |= FLAG_AESTEST_FAIL;
++ printf("[INFO] AES%d %s Mode Encryption Failed \n", pjaes_test->key_length, AES_Mode);
++ printf("[DBG] Golden Data Dump .... \n");
++ for (i=0; i< ulAESMsgLength; i++)
++ {
++ printf("%02x ", pjaes_test->ciphertext[i]);
++ if (((i+1) % 8) == 0)
++ printf("\n");
++ }
++ printf("\n [DBG] Error Data Dump .... \n");
++ for (i=0; i< ulAESMsgLength; i++)
++ {
++ printf("%02x ", aes_output[i]);
++ if (((i+1) % 8) == 0)
++ printf("\n");
++ }
++ printf("\n");
++ }
++ else
++ {
++ /*
++ printf("[INFO] AES%d %s Mode Encryption Passed \n", pjaes_test->key_length, AES_Mode);
++ */
++ }
++
++ /* Decryption Test */
++ aes_dec_ast3000(&aes_ctx, pjaes_test->ciphertext, pjaes_test->key, aes_output, ulAESMsgLength, pjaes_test->aes_mode);
++ if (strncmp(aes_output, pjaes_test->plaintext, ulAESMsgLength))
++ {
++ Flags |= FLAG_AESTEST_FAIL;
++ printf("[INFO] AES%d %s Mode Decryption Failed \n", pjaes_test->key_length, AES_Mode);
++ printf("[DBG] Golden Data Dump .... \n");
++ for (i=0; i< ulAESMsgLength; i++)
++ {
++ printf("%02x ", pjaes_test->plaintext[i]);
++ if (((i+1) % 8) == 0)
++ printf("\n");
++ }
++ printf("\n [DBG] Error Data Dump .... \n");
++ for (i=0; i< ulAESMsgLength; i++)
++ {
++ printf("%02x ", aes_output[i]);
++ if (((i+1) % 8) == 0)
++ printf("\n");
++ }
++ printf("\n");
++ }
++ else
++ {
++ /*
++ printf("[INFO] AES%d %s Mode Decryption Passed \n", pjaes_test->key_length, AES_Mode);
++ */
++ }
++
++ pjaes_test++;
++ } /* AES */
++
++ /* RC4 Test */
++ pjrc4_test = rc4test;
++ while ((pjrc4_test->key[0] != 0xff) && (pjrc4_test->data[0] != 0xff))
++ {
++
++ /* Get Info */
++ ulRC4KeyLength = strlen(pjrc4_test->key);
++ ulRC4MsgLength = strlen(pjrc4_test->data);
++ memcpy( (void *) rc4_buf_sw, (void *) pjrc4_test->data, ulRC4MsgLength );
++ memcpy( (void *) rc4_buf_hw, (void *) pjrc4_test->data, ulRC4MsgLength );
++
++ /* Crypto */
++ rc4_crypt_sw(rc4_buf_sw, ulRC4MsgLength, pjrc4_test->key, ulRC4KeyLength);
++ rc4_crypt_ast3000(rc4_buf_hw, ulRC4MsgLength, pjrc4_test->key, ulRC4KeyLength);
++
++ if (strncmp(rc4_buf_hw, rc4_buf_sw, ulRC4MsgLength))
++ {
++ Flags |= FLAG_RC4TEST_FAIL;
++ printf("[INFO] RC4 Encryption Failed \n");
++ printf("[DBG] Golden Data Dump .... \n");
++ for (i=0; i< ulRC4MsgLength; i++)
++ {
++ printf("%02x ", rc4_buf_sw[i]);
++ if (((i+1) % 8) == 0)
++ printf("\n");
++ }
++ printf("\n [DBG] Error Data Dump .... \n");
++ for (i=0; i< ulRC4MsgLength; i++)
++ {
++ printf("%02x ", rc4_buf_hw[i]);
++ if (((i+1) % 8) == 0)
++ printf("\n");
++ }
++ printf("\n");
++ }
++ else
++ {
++ /*
++ printf("[INFO] RC4 Encryption Passed \n");
++ */
++ }
++
++ pjrc4_test++;
++
++ } /* RC4 */
++
++ /* Hash Test */
++ pjhash_test = hashtest;
++ while (pjhash_test->hash_mode != 0xFF)
++ {
++
++ if (pjhash_test->hash_mode == HASHMODE_MD5)
++ strcpy (HASH_Mode, "MD5");
++ else if (pjhash_test->hash_mode == HASHMODE_SHA1)
++ strcpy (HASH_Mode, "SHA1");
++ else if (pjhash_test->hash_mode == HASHMODE_SHA256)
++ strcpy (HASH_Mode, "SHA256");
++ else if (pjhash_test->hash_mode == HASHMODE_SHA224)
++ strcpy (HASH_Mode, "SHA224");
++
++ /* Hash */
++ hash_ast3000(pjhash_test->input, strlen(pjhash_test->input), hash_out, pjhash_test->hash_mode);
++ if (strncmp(hash_out, pjhash_test->digest, pjhash_test->digest_length))
++ {
++ Flags |= FLAG_HASHTEST_FAIL;
++ printf("[INFO] HASH %s Failed \n", HASH_Mode);
++ printf("[DBG] Golden Data Dump .... \n");
++ for (i=0; i< pjhash_test->digest_length; i++)
++ {
++ printf("%02x ",pjhash_test->digest[i]);
++ if (((i+1) % 8) == 0)
++ printf("\n");
++ }
++ printf("\n [DBG] Error Data Dump .... \n");
++ for (i=0; i< pjhash_test->digest_length; i++)
++ {
++ printf("%02x ",hash_out[i]);
++ if (((i+1) % 8) == 0)
++ printf("\n");
++ }
++ printf("\n");
++ }
++ else
++ {
++ /*
++ printf("[INFO] HASH %s Passed \n", HASH_Mode);
++ */
++ }
++
++ pjhash_test++;
++
++ } /* Hash Test */
++
++ /* HMAC Test */
++ pjhmac_test = hmactest;
++ while (pjhmac_test->hash_mode != 0xFF)
++ {
++
++ if (pjhmac_test->hash_mode == HASHMODE_MD5)
++ strcpy (HMAC_Mode, "MD5");
++ else if (pjhmac_test->hash_mode == HASHMODE_SHA1)
++ strcpy (HMAC_Mode, "SHA1");
++ else if (pjhmac_test->hash_mode == HASHMODE_SHA256)
++ strcpy (HMAC_Mode, "SHA256");
++ else if (pjhmac_test->hash_mode == HASHMODE_SHA224)
++ strcpy (HMAC_Mode, "SHA224");
++
++ /* HMAC */
++ hmackey_ast3000(pjhmac_test->key, pjhmac_test->key_length, pjhmac_test->hash_mode);
++ hmac_ast3000(pjhmac_test->key, pjhmac_test->key_length, pjhmac_test->input, strlen(pjhmac_test->input), pjhmac_test->hash_mode, hmac_out);
++ if (strncmp(hmac_out, pjhmac_test->digest, pjhmac_test->digest_length))
++ {
++ Flags |= FLAG_HASHTEST_FAIL;
++ printf("[INFO] HMAC %s Failed \n", HMAC_Mode);
++ printf("[DBG] Golden Data Dump .... \n");
++ for (i=0; i< pjhmac_test->digest_length; i++)
++ {
++ printf("%02x ",pjhmac_test->digest[i]);
++ if (((i+1) % 8) == 0)
++ printf("\n");
++ }
++ printf("\n [DBG] Error Data Dump .... \n");
++ for (i=0; i< pjhmac_test->digest_length; i++)
++ {
++ printf("%02x ",hmac_out[i]);
++ if (((i+1) % 8) == 0)
++ printf("\n");
++ }
++ printf("\n");
++ }
++ else
++ {
++ /*
++ printf("[INFO] HMAC %s Passed \n", HMAC_Mode);
++ */
++ }
++
++ pjhmac_test++;
++
++ } /* HMAC Test */
++
++ return Flags;
++
++}
++
++#endif /* CONFIG_SLT */
+diff --git a/board/aspeed/ast2300/hactest.h b/board/aspeed/ast2300/hactest.h
+new file mode 100755
+index 0000000..fcf2186
+--- /dev/null
++++ b/board/aspeed/ast2300/hactest.h
+@@ -0,0 +1,194 @@
++/*
++ * 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
++ */
++/* Err Flags */
++#define FLAG_AESTEST_FAIL 0x00000001
++#define FLAG_RC4TEST_FAIL 0x00000002
++#define FLAG_HASHTEST_FAIL 0x00000004
++
++/* Specific */
++/*
++#define DRAM_BASE 0x40000000
++#define CRYPTO_SRC_BASE (DRAM_BASE + 0x100000)
++#define CRYPTO_DST_BASE (DRAM_BASE + 0x200000)
++#define CRYPTO_CONTEXT_BASE (DRAM_BASE + 0x300000)
++
++#define HASH_SRC_BASE (DRAM_BASE + 0x400000)
++#define HASH_DST_BASE (DRAM_BASE + 0x500000)
++#define HMAC_KEY_BASE (DRAM_BASE + 0x600000)
++*/
++#define m08byteAlignment(x) ((x + 0x00000007) & 0xFFFFFFF8)
++#define m16byteAlignment(x) ((x + 0x0000000F) & 0xFFFFFFF0)
++#define m64byteAlignment(x) ((x + 0x0000003F) & 0xFFFFFFC0)
++
++#define CRYPTO_ALIGNMENT 16
++#define CRYPTO_MAX_SRC (100+CRYPTO_ALIGNMENT)
++#define CRYPTO_MAX_DST (100+CRYPTO_ALIGNMENT)
++#define CRYPTO_MAX_CONTEXT (100+CRYPTO_ALIGNMENT)
++
++#define HASH_ALIGNMENT 16
++#define HMAC_KEY_ALIGNMENT 64
++#define HASH_MAX_SRC (100+HASH_ALIGNMENT)
++#define HASH_MAX_DST (32+HASH_ALIGNMENT)
++#define HMAC_MAX_KEY (64+HMAC_KEY_ALIGNMENT)
++
++/* General */
++#define HAC_REG_BASE 0x1e6e3000
++
++#define MAX_KEYLENGTH 100
++#define MAX_TEXTLENGTH 100
++#define MAX_AESTEXTLENGTH 256
++#define MAX_RC4TEXTLENGTH 256
++#define MAX_RC4KEYLENGTH 256
++
++#define CRYPTOMODE_ECB 0x00
++#define CRYPTOMODE_CBC 0x01
++#define CRYPTOMODE_CFB 0x02
++#define CRYPTOMODE_OFB 0x03
++#define CRYPTOMODE_CTR 0x04
++
++#define HASHMODE_MD5 0x00
++#define HASHMODE_SHA1 0x01
++#define HASHMODE_SHA256 0x02
++#define HASHMODE_SHA224 0x03
++
++#define MIXMODE_DISABLE 0x00
++#define MIXMODE_CRYPTO 0x02
++#define MIXMODE_HASH 0x03
++
++#define REG_CRYPTO_SRC_BASE_OFFSET 0x00
++#define REG_CRYPTO_DST_BASE_OFFSET 0x04
++#define REG_CRYPTO_CONTEXT_BASE_OFFSET 0x08
++#define REG_CRYPTO_LEN_OFFSET 0x0C
++#define REG_CRYPTO_CMD_BASE_OFFSET 0x10
++//#define REG_CRYPTO_ENABLE_OFFSET 0x14
++#define REG_CRYPTO_STATUS_OFFSET 0x1C
++
++#define REG_HASH_SRC_BASE_OFFSET 0x20
++#define REG_HASH_DST_BASE_OFFSET 0x24
++#define REG_HASH_KEY_BASE_OFFSET 0x28
++#define REG_HASH_LEN_OFFSET 0x2C
++#define REG_HASH_CMD_OFFSET 0x30
++//#define REG_HASH_ENABLE_OFFSET 0x14
++#define REG_HASH_STATUS_OFFSET 0x1C
++
++#define HASH_BUSY 0x01
++#define CRYPTO_BUSY 0x02
++
++//#define ENABLE_HASH 0x01
++//#define DISABLE_HASH 0x00
++//#define ENABLE_CRYPTO 0x02
++//#define DISABLE_CRYPTO 0x00
++
++#define CRYPTO_SYNC_MODE_MASK 0x03
++#define CRYPTO_SYNC_MODE_ASYNC 0x00
++#define CRYPTO_SYNC_MODE_PASSIVE 0x02
++#define CRYPTO_SYNC_MODE_ACTIVE 0x03
++
++#define CRYPTO_AES128 0x00
++#define CRYPTO_AES192 0x04
++#define CRYPTO_AES256 0x08
++
++#define CRYPTO_AES_ECB 0x00
++#define CRYPTO_AES_CBC 0x10
++#define CRYPTO_AES_CFB 0x20
++#define CRYPTO_AES_OFB 0x30
++#define CRYPTO_AES_CTR 0x40
++
++#define CRYPTO_ENCRYPTO 0x80
++#define CRYPTO_DECRYPTO 0x00
++
++#define CRYPTO_AES 0x000
++#define CRYPTO_RC4 0x100
++
++#define CRYPTO_ENABLE_RW 0x000
++#define CRYPTO_ENABLE_CONTEXT_LOAD 0x000
++#define CRYPTO_ENABLE_CONTEXT_SAVE 0x000
++
++#define HASH_SYNC_MODE_MASK 0x03
++#define HASH_SYNC_MODE_ASYNC 0x00
++#define HASH_SYNC_MODE_PASSIVE 0x02
++#define HASH_SYNC_MODE_ACTIVE 0x03
++
++#define HASH_READ_SWAP_ENABLE 0x04
++#define HMAC_SWAP_CONTROL_ENABLE 0x08
++
++#define HASH_ALG_SELECT_MASK 0x70
++#define HASH_ALG_SELECT_MD5 0x00
++#define HASH_ALG_SELECT_SHA1 0x20
++#define HASH_ALG_SELECT_SHA224 0x40
++#define HASH_ALG_SELECT_SHA256 0x50
++
++#define HAC_ENABLE 0x80
++#define HAC_DIGEST_CAL_ENABLE 0x180
++#define HASH_INT_ENABLE 0x200
++
++/* AES */
++#ifndef uint8
++#define uint8 unsigned char
++#endif
++
++#ifndef uint32
++#define uint32 unsigned long int
++#endif
++
++typedef struct
++{
++ uint32 erk[64]; /* encryption round keys */
++ uint32 drk[64]; /* decryption round keys */
++ int nr; /* number of rounds */
++}
++aes_context;
++
++typedef struct
++{
++ int aes_mode;
++ int key_length;
++
++ uint8 key[32]; /* as iv in CTR mode */
++ uint8 plaintext[64];
++ uint8 ciphertext[64];
++
++}
++aes_test;
++
++/* RC4 */
++typedef struct
++{
++ uint8 key[32];
++ uint8 data[64];
++}
++rc4_test;
++
++/* Hash */
++typedef struct
++{
++ int hash_mode;
++ int digest_length;
++
++ uint8 input[64];
++ uint8 digest[64];
++
++}
++hash_test;
++
++/* HMAC */
++typedef struct
++{
++ int hash_mode;
++ int key_length;
++ int digest_length;
++
++ uint8 key[100];
++ uint8 input[64];
++ uint8 digest[64];
++
++}
++hmac_test;
+diff --git a/board/aspeed/ast2300/mactest.c b/board/aspeed/ast2300/mactest.c
+new file mode 100755
+index 0000000..5566b65
+--- /dev/null
++++ b/board/aspeed/ast2300/mactest.c
+@@ -0,0 +1,504 @@
++/*
++ * 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
++ */
++/*
++ * (C) Copyright 2007 ASPEED Software
++ * MAC Manufacture Test in ASPEED's SDK version 0.20.01
++ *
++ * Release History
++ * 1. First Release, river@20071130
++ * 2. Fix the endless loop when PHY is not ready, river@20071204
++ *
++ * Test items:
++ * 1. Support MARVELL PHY only in this version
++ * 2. MDC/MDIO
++ * 3. GMAC/Duplex TX/RX Full_Size, Packet_Length Test
++ * 4. 100M/Duplex TX/RX Full_Size, Packet_Length Test
++ *
++ *
++ *
++*/
++
++
++/*
++* Diagnostics support
++*/
++#include <common.h>
++#include <command.h>
++#include <post.h>
++#include <malloc.h>
++#include <net.h>
++#include "slt.h"
++
++#if ((CFG_CMD_SLT & CFG_CMD_MACTEST) && defined(CONFIG_SLT))
++#include "mactest.h"
++
++static int INL(u_long base, u_long addr)
++{
++ return le32_to_cpu(*(volatile u_long *)(addr + base));
++}
++
++static void OUTL(u_long base, int command, u_long addr)
++{
++ *(volatile u_long *)(addr + base) = cpu_to_le32(command);
++}
++
++
++static void SCU_MAC1_Enable (void)
++{
++ unsigned int SCU_Register;
++
++//MAC1 RESET/PHY_LINK in SCU
++ SCU_Register = INL(SCU_BASE, SCU_RESET_CONTROL_REG);
++ OUTL(SCU_BASE, SCU_Register & ~(0x800), SCU_RESET_CONTROL_REG);
++
++}
++
++/*------------------------------------------------------------
++ . Reads a register from the MII Management serial interface
++ .-------------------------------------------------------------*/
++static u16 phy_read_register (u8 PHY_Register, u8 PHY_Address)
++{
++ u32 Data, Status = 0, Loop_Count = 0, PHY_Ready = 1;
++ u16 Return_Data;
++
++ OUTL(MAC1_IO_BASE, (PHY_Register << 21) + (PHY_Address << 16) + MIIRD + MDC_CYCTHR, PHYCR_REG);
++ do {
++ Status = (INL (MAC1_IO_BASE, PHYCR_REG) & MIIRD);
++ Loop_Count++;
++ if (Loop_Count >= PHY_LOOP) {
++ PHY_Ready = 0;
++ break;
++ }
++ } while (Status == MIIRD);
++
++ if (PHY_Ready == 0) {
++ printf ("PHY NOT REDAY\n");
++ return 0;
++ }
++
++ udelay(5*1000);
++ Data = INL (MAC1_IO_BASE, PHYDATA_REG);
++ Return_Data = (Data >> 16);
++
++ return Return_Data;
++}
++
++static void phy_write_register (u8 PHY_Register, u8 PHY_Address, u16 PHY_Data)
++{
++ u32 Status = 0, Loop_Count = 0, PHY_Ready = 1;
++
++ OUTL(MAC1_IO_BASE, PHY_Data, PHYDATA_REG);
++ OUTL(MAC1_IO_BASE, (PHY_Register << 21) + (PHY_Address << 16) + MIIWR + MDC_CYCTHR, PHYCR_REG);
++ do {
++ Status = (INL (MAC1_IO_BASE, PHYCR_REG) & MIIWR);
++ Loop_Count++;
++ if (Loop_Count >= PHY_LOOP) {
++ PHY_Ready = 0;
++ break;
++ }
++ } while (Status == MIIWR);
++ if (PHY_Ready == 0) {
++ printf ("PHY NOT REDAY\n");
++ }
++}
++
++static int wait_link_resolve (void)
++{
++ int resolved_status, Loop_Count = 0, PHY_Ready = 1;
++
++ do {
++ resolved_status = (phy_read_register (0x11, 0) & (PHY_RESOLVED_bit | PHY_LINK_bit));
++ Loop_Count++;
++ if (Loop_Count >= PHY_LOOP) {
++ PHY_Ready = 0;
++ printf ("PHY NOT READY\n");
++ break;
++ }
++ } while (resolved_status != (PHY_RESOLVED_bit | PHY_LINK_bit));
++
++ return PHY_Ready;
++}
++
++static void set_phy_speed (int chip, int speed, int duplex)
++{
++ unsigned short data, status;
++
++
++ if (chip == PHYID_VENDOR_MARVELL) {
++ if ((speed == PHY_SPEED_1G) && (duplex == DUPLEX_FULL)) {
++//Manual Control
++ phy_write_register (18, 0, 0);
++ data = phy_read_register (9, 0);
++ phy_write_register (9, 0, data | 0x1800);
++//PHY Reset
++ phy_write_register (0, 0, 0x0140 | 0x8000);
++ do {
++ status = (phy_read_register (0, 0) & 0x8000);
++ } while (status != 0);
++
++//Force 1G
++ phy_write_register (29, 0, 0x07);
++ data = phy_read_register (30, 0);
++ phy_write_register (30, 0, data | 0x08);
++ phy_write_register (29, 0, 0x10);
++ data = phy_read_register (30, 0);
++ phy_write_register (30, 0, data | 0x02);
++ phy_write_register (29, 0, 0x12);
++ data = phy_read_register (30, 0);
++ phy_write_register (30, 0, data | 0x01);
++
++ printf ("FORCE MARVELL PHY to 1G/DUPLEX DONE\n");
++ }
++ else if ((speed == PHY_SPEED_100M) && (duplex == DUPLEX_FULL)) {
++//PHY Reset
++ phy_write_register (0, 0, 0x2100 | 0x8000);
++ do {
++ status = (phy_read_register (0, 0) & 0x8000);
++ } while (status != 0);
++
++//Force 100M
++ data = phy_read_register (0, 0);
++ phy_write_register (0, 0, data | 0x4000 | 0x8000);
++ do {
++ status = (phy_read_register (0, 0) & 0x8000);
++ } while (status != 0);
++ data = phy_read_register (0, 0);
++
++ printf ("FORCE MARVELL PHY to 100M/DUPLEX DONE\n");
++ }
++ }
++ else if ( (chip == PHYID_VENDOR_RTL8201E) || (chip == PHYID_VENDOR_BROADCOM) ){
++ /* basic setting */
++ data = phy_read_register (0, 0);
++ data &= 0x7140;
++ data |= 0x4000;
++ if (speed == PHY_SPEED_100M)
++ data |= 0x2000;
++ if (duplex == DUPLEX_FULL)
++ data |= 0x0100;
++ phy_write_register (0, 0, data);
++
++ /* reset */
++ phy_write_register (0, 0, data | 0x8000);
++ do {
++ status = (phy_read_register (0, 0) & 0x8000);
++ } while (status != 0);
++ udelay(100*1000);
++
++ /* basic setting */
++ phy_write_register (0, 0, data);
++
++ if (chip == PHYID_VENDOR_RTL8201E)
++ printf ("FORCE RTL8201E PHY to 100M/DUPLEX DONE\n");
++ else if (chip == PHYID_VENDOR_BROADCOM)
++ printf ("FORCE Broadcom PHY to 100M/DUPLEX DONE\n");
++
++ }
++
++}
++
++static void MAC1_reset (void)
++{
++ OUTL(MAC1_IO_BASE, SW_RST_bit, MACCR_REG);
++ for (; (INL(MAC1_IO_BASE, MACCR_REG ) & SW_RST_bit) != 0; ) {udelay(1000);}
++ OUTL(MAC1_IO_BASE, 0, IER_REG );
++}
++
++static int set_mac1_control_register (int Chip_ID)
++{
++ unsigned long MAC_CR_Register = 0;
++ int PHY_Ready = 1;
++ u16 PHY_Status, PHY_Speed, PHY_Duplex, Advertise, Link_Partner;
++
++ MAC_CR_Register = SPEED_100M_MODE_bit | RX_ALLADR_bit | FULLDUP_bit | RXMAC_EN_bit | RXDMA_EN_bit | TXMAC_EN_bit | TXDMA_EN_bit | CRC_APD_bit;
++
++ if ( (Chip_ID == PHYID_VENDOR_BROADCOM) || (Chip_ID == PHYID_VENDOR_RTL8201E)) {
++ Advertise = phy_read_register (0x04, 0);
++ Link_Partner = phy_read_register (0x05, 0);
++ Advertise = (Advertise & PHY_SPEED_DUPLEX_MASK);
++ Link_Partner = (Link_Partner & PHY_SPEED_DUPLEX_MASK);
++ if ((Advertise & Link_Partner) & PHY_100M_DUPLEX) {
++ MAC_CR_Register |= SPEED_100M_MODE_bit;
++ MAC_CR_Register |= FULLDUP_bit;
++ }
++ else if ((Advertise & Link_Partner) & PHY_100M_HALF) {
++ MAC_CR_Register |= SPEED_100M_MODE_bit;
++ MAC_CR_Register &= ~FULLDUP_bit;
++ }
++ else if ((Advertise & Link_Partner) & PHY_10M_DUPLEX) {
++ MAC_CR_Register &= ~SPEED_100M_MODE_bit;
++ MAC_CR_Register |= FULLDUP_bit;
++ }
++ else if ((Advertise & Link_Partner) & PHY_10M_HALF) {
++ MAC_CR_Register &= ~SPEED_100M_MODE_bit;
++ MAC_CR_Register &= ~FULLDUP_bit;
++ }
++ }
++ else if (Chip_ID == PHYID_VENDOR_MARVELL) {
++
++ PHY_Ready = wait_link_resolve ();
++
++ if (PHY_Ready == 1) {
++ PHY_Status = phy_read_register (0x11, 0);
++ PHY_Speed = (PHY_Status & PHY_SPEED_MASK) >> 14;
++ PHY_Duplex = (PHY_Status & PHY_DUPLEX_MASK) >> 13;
++
++ if (PHY_Speed == SPEED_1000M) {
++ MAC_CR_Register |= GMAC_MODE_bit;
++ }
++ else {
++ MAC_CR_Register &= ~GMAC_MODE_bit;
++ if (PHY_Speed == SPEED_10M) {
++ MAC_CR_Register &= ~SPEED_100M_MODE_bit;
++ }
++ }
++ if (PHY_Duplex == DUPLEX_HALF) {
++ MAC_CR_Register &= ~FULLDUP_bit;
++ }
++ }
++ }
++ OUTL(MAC1_IO_BASE, MAC_CR_Register, MACCR_REG);
++
++ return PHY_Ready;
++}
++
++static void ring_buffer_alloc (void)
++{
++ unsigned int i, j;
++
++//Write data into TX buffer
++ for (i = 0; i < NUM_TX; i++) {
++ for (j = 0; j < TX_BUFF_SZ; j++) {
++ tx_buffer[i][j] = i * 4 + j;
++ }
++ }
++//Initialize RX buffer to 0
++ for (i = 0; i < NUM_RX; i++) {
++ for (j = 0; j < RX_BUFF_SZ; j++) {
++ rx_buffer[i][j] = 0;
++ }
++ }
++//Prepare descriptor
++ for (i = 0; i < NUM_RX; i++) {
++ rx_ring[i].status = cpu_to_le32(RXPKT_RDY + RX_BUFF_SZ);
++ rx_ring[i].buf = ((u32) &rx_buffer[i]);
++ rx_ring[i].reserved = 0;
++ }
++ for (i = 0; i < NUM_TX; i++) {
++ tx_ring[i].status = 0;
++ tx_ring[i].des1 = 0;
++ tx_ring[i].buf = ((u32) &tx_buffer[i]);
++ tx_ring[i].reserved = 0;
++ }
++
++ rx_ring[NUM_RX - 1].status |= cpu_to_le32(EDORR);
++ tx_ring[NUM_TX - 1].status |= cpu_to_le32(EDOTR);
++
++ OUTL(MAC1_IO_BASE, ((u32) &tx_ring), TXR_BADR_REG);
++ OUTL(MAC1_IO_BASE, ((u32) &rx_ring), RXR_BADR_REG);
++
++ tx_new = 0;
++ rx_new = 0;
++}
++
++static int packet_test (void)
++{
++ unsigned int rx_status, length, i, Loop_Count = 0;
++
++ tx_ring[tx_new].status |= cpu_to_le32(LTS | FTS | TX_BUFF_SZ);
++ tx_ring[tx_new].status |= cpu_to_le32(TXDMA_OWN);
++ OUTL(MAC1_IO_BASE, POLL_DEMAND, TXPD_REG);
++
++//Compare result
++ do {
++ rx_status = rx_ring[rx_new].status;
++ Loop_Count++;
++ } while (!(rx_status & RXPKT_STATUS) && (Loop_Count < PHY_LOOP));
++ if (rx_status & (RX_ERR | CRC_ERR | FTL | RUNT | RX_ODD_NB)) {
++ /* There was an error.*/
++ printf("RX error status = 0x%08X\n", rx_status);
++ return PACKET_TEST_FAIL;
++ } else {
++ length = (rx_status & BYTE_COUNT_MASK);
++ for (i = 0; i < RX_BUFF_SZ / 4; i++) {
++ if (rx_buffer[rx_new][i] != tx_buffer[tx_new][i]) {
++ printf ("ERROR at packet %d, address %x\n", rx_new, i);
++ printf ("Gold = %8x, Real = %8x\n", tx_buffer[tx_new][i], rx_buffer[rx_new][i]);
++ return PACKET_TEST_FAIL;
++ }
++ }
++ }
++ tx_new = (tx_new + 1) % NUM_TX;
++ rx_new = (rx_new + 1) % NUM_RX;
++
++ return TEST_PASS;
++}
++
++static int packet_length_test (int packet_length)
++{
++ unsigned int rx_status, length, i, Loop_Count = 0;
++
++ tx_ring[tx_new].status &= (~(BYTE_COUNT_MASK));
++ tx_ring[tx_new].status |= cpu_to_le32(LTS | FTS | packet_length);
++ tx_ring[tx_new].status |= cpu_to_le32(TXDMA_OWN);
++ OUTL(MAC1_IO_BASE, POLL_DEMAND, TXPD_REG);
++
++//Compare result
++ do {
++ rx_status = rx_ring[rx_new].status;
++ Loop_Count++;
++ } while (!(rx_status & RXPKT_STATUS) && (Loop_Count < PHY_LOOP));
++ if (rx_status & (RX_ERR | CRC_ERR | FTL | RUNT | RX_ODD_NB)) {
++ /* There was an error.*/
++ printf("RX error status = 0x%08X\n", rx_status);
++ return PACKET_LENGTH_TEST_FAIL;
++ } else {
++ length = (rx_status & BYTE_COUNT_MASK) - 4;
++ if (length != packet_length) {
++ printf ("Received Length ERROR. Gold = %d, Fail = %d\n",packet_length, length);
++ printf ("rx_new = %d, tx_new = %d\n", rx_new, tx_new);
++ return PACKET_LENGTH_TEST_FAIL;
++ }
++ for (i = 0; i < length; i++) {
++ if (rx_buffer[rx_new][i] != tx_buffer[tx_new][i]) {
++ printf ("ERROR at packet %d, address %x\n", rx_new, i);
++ printf ("Gold = %8x, Real = %8x\n", tx_buffer[tx_new][i], rx_buffer[rx_new][i]);
++ return PACKET_LENGTH_TEST_FAIL;
++ }
++ }
++ }
++ rx_ring[rx_new].status &= (~(RXPKT_STATUS));
++ tx_new = (tx_new + 1) % NUM_TX;
++ rx_new = (rx_new + 1) % NUM_RX;
++
++ return TEST_PASS;
++}
++
++static int MAC1_init (int id)
++{
++ int phy_status = 0;
++
++ MAC1_reset ();
++ phy_status = set_mac1_control_register (id);
++ ring_buffer_alloc ();
++
++ return phy_status;
++}
++
++int do_mactest (void)
++{
++ unsigned int phy_id, i;
++ int test_result = 0, phy_status = 0;
++
++ SCU_MAC1_Enable();
++ phy_id = ((phy_read_register (0x02, 0) << 16) + phy_read_register (0x03, 0)) & PHYID_VENDOR_MASK;
++ if (phy_id == PHYID_VENDOR_MARVELL) {
++ printf ("PHY DETECTED ------> MARVELL\n");
++
++ set_phy_speed (phy_id, PHY_SPEED_1G, DUPLEX_FULL);
++ if ((phy_status = MAC1_init (phy_id)) != 0) {
++ for (i = 0; i < NUM_TX; i++) {
++ test_result |= packet_test ();
++ if (test_result != 0)
++ break;
++ }
++ }
++ else if (phy_status == 0) {
++ printf ("PHY FAIL: Please Check If you are using LOOP BACK Connector\n");
++ test_result = 3;
++ return test_result;
++ }
++ if ((phy_status = MAC1_init (phy_id)) != 0) {
++ for (i = 60; i < TX_BUFF_SZ; i++) {
++ test_result |= packet_length_test (i);
++ if (test_result != 0)
++ break;
++ }
++ }
++ else if (phy_status == 0) {
++ printf ("PHY FAIL: Please Check If you are using LOOP BACK Connector\n");
++ test_result = 3;
++ return test_result;
++ }
++ set_phy_speed (phy_id, PHY_SPEED_100M, DUPLEX_FULL);
++ if ((phy_status = MAC1_init (phy_id)) != 0) {
++ for (i = 0; i < NUM_TX; i++) {
++ test_result |= packet_test ();
++ if (test_result != 0)
++ break;
++ }
++ }
++ else if (phy_status == 0) {
++ printf ("PHY FAIL: Please Check If you are using LOOP BACK Connector\n");
++ test_result = 3;
++ return test_result;
++ }
++
++ if ((phy_status = MAC1_init (phy_id)) != 0) {
++ for (i = 60; i < TX_BUFF_SZ; i++) {
++ test_result |= packet_length_test (i);
++ if (test_result != 0)
++ break;
++ }
++ }
++ else if (phy_status == 0) {
++ printf ("PHY FAIL: Please Check If you are using LOOP BACK Connector\n");
++ test_result = 3;
++ return test_result;
++ }
++ }
++ else if ( (phy_id == PHYID_VENDOR_RTL8201E) || (phy_id == PHYID_VENDOR_BROADCOM) ){
++
++ if (phy_id == PHYID_VENDOR_RTL8201E)
++ printf ("PHY DETECTED ------> RTL 8201E \n");
++ else if (phy_id == PHYID_VENDOR_BROADCOM)
++ printf ("PHY DETECTED ------> Broadcom \n");
++
++ set_phy_speed (phy_id, PHY_SPEED_100M, DUPLEX_FULL);
++ if ((phy_status = MAC1_init (phy_id)) != 0) {
++ for (i = 0; i < NUM_TX; i++) {
++ test_result |= packet_test ();
++ if (test_result != 0)
++ break;
++ }
++ }
++ else if (phy_status == 0) {
++ printf ("PHY FAIL: Please Check If you are using LOOP BACK Connector\n");
++ test_result = 3;
++ return test_result;
++ }
++
++ if ((phy_status = MAC1_init (phy_id)) != 0) {
++ for (i = 60; i < TX_BUFF_SZ; i++) {
++ test_result |= packet_length_test (i);
++ if (test_result != 0)
++ break;
++ }
++ }
++ else if (phy_status == 0) {
++ printf ("PHY FAIL: Please Check If you are using LOOP BACK Connector\n");
++ test_result = 3;
++ return test_result;
++ }
++ }
++
++ if ((phy_status == 0) && (test_result & PACKET_TEST_FAIL)) {
++ printf ("Packet Test FAIL !\n");
++ }
++ else if ((phy_status == 0) && (test_result & PACKET_LENGTH_TEST_FAIL)) {
++ printf ("Packet Length Test FAIL !\n");
++ }
++
++ return test_result;
++
++}
++
++#endif /* CONFIG_SLT */
+diff --git a/board/aspeed/ast2300/mactest.h b/board/aspeed/ast2300/mactest.h
+new file mode 100755
+index 0000000..e75b7bb
+--- /dev/null
++++ b/board/aspeed/ast2300/mactest.h
+@@ -0,0 +1,215 @@
++/*
++ * 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
++ */
++/* MACTest.h */
++
++// --------------------------------------------------------------------
++// General Definition
++// --------------------------------------------------------------------
++#define MAC1_IO_BASE 0x1E660000
++#define PHY_LOOP 100000
++#define NUM_RX 48
++#define NUM_TX 48
++#define RX_BUFF_SZ 1514
++#define TX_BUFF_SZ 1514
++#define TOUT_LOOP 1000000
++#define ETH_ALEN 6
++#define POLL_DEMAND 1
++
++
++// --------------------------------------------------------------------
++// MAC Register Index
++// --------------------------------------------------------------------
++#define ISR_REG 0x00 // interrups status register
++#define IER_REG 0x04 // interrupt maks register
++#define MAC_MADR_REG 0x08 // MAC address (Most significant)
++#define MAC_LADR_REG 0x0c // MAC address (Least significant)
++#define MAHT0_REG 0x10 // Multicast Address Hash Table 0 register
++#define MAHT1_REG 0x14 // Multicast Address Hash Table 1 register
++#define TXPD_REG 0x18 // Transmit Poll Demand register
++#define RXPD_REG 0x1c // Receive Poll Demand register
++#define TXR_BADR_REG 0x20 // Transmit Ring Base Address register
++#define RXR_BADR_REG 0x24 // Receive Ring Base Address register
++#define HPTXPD_REG 0x28
++#define HPTXR_BADR_REG 0x2c
++#define ITC_REG 0x30 // interrupt timer control register
++#define APTC_REG 0x34 // Automatic Polling Timer control register
++#define DBLAC_REG 0x38 // DMA Burst Length and Arbitration control register
++#define DMAFIFOS_REG 0x3c
++#define FEAR_REG 0x44
++#define TPAFCR_REG 0x48
++#define RBSR_REG 0x4c
++#define MACCR_REG 0x50 // MAC control register
++#define MACSR_REG 0x54 // MAC status register
++#define PHYCR_REG 0x60 // PHY control register
++#define PHYDATA_REG 0x64 // PHY Write Data register
++
++// --------------------------------------------------------------------
++// PHYCR_REG
++// --------------------------------------------------------------------
++#define PHY_RE_AUTO_bit (1UL<<9)
++#define PHY_READ_bit (1UL<<26)
++#define PHY_WRITE_bit (1UL<<27)
++// --------------------------------------------------------------------
++// PHYCR_REG
++// --------------------------------------------------------------------
++#define PHY_AUTO_OK_bit (1UL<<5)
++// --------------------------------------------------------------------
++// PHY INT_STAT_REG
++// --------------------------------------------------------------------
++#define PHY_SPEED_CHG_bit (1UL<<14)
++#define PHY_DUPLEX_CHG_bit (1UL<<13)
++#define PHY_LINK_CHG_bit (1UL<<10)
++#define PHY_AUTO_COMP_bit (1UL<<11)
++// --------------------------------------------------------------------
++// PHY SPE_STAT_REG
++// --------------------------------------------------------------------
++#define PHY_RESOLVED_bit (1UL<<11)
++#define PHY_LINK_bit (1UL<<10)
++#define PHY_SPEED_mask 0xC000
++#define PHY_SPEED_10M 0x0
++#define PHY_SPEED_100M 0x1
++#define PHY_SPEED_1G 0x2
++#define PHY_DUPLEX_mask 0x2000
++#define PHY_SPEED_DUPLEX_MASK 0x01E0
++#define PHY_100M_DUPLEX 0x0100
++#define PHY_100M_HALF 0x0080
++#define PHY_10M_DUPLEX 0x0040
++#define PHY_10M_HALF 0x0020
++#define LINK_STATUS 0x04
++#define PHYID_VENDOR_MASK 0xfffffc00
++#define PHYID_VENDOR_MARVELL 0x01410c00
++#define PHYID_VENDOR_BROADCOM 0x00406000
++#define PHYID_VENDOR_RTL8201E 0x001cc800
++#define DUPLEX_FULL 0x01
++#define DUPLEX_HALF 0x00
++
++
++
++// --------------------------------------------------------------------
++// MACCR_REG
++// --------------------------------------------------------------------
++
++#define SW_RST_bit (1UL<<31) // software reset/
++#define DIRPATH_bit (1UL<<21)
++#define RX_IPCS_FAIL_bit (1UL<<20)
++#define SPEED_100M_MODE_bit (1UL<<19)
++#define RX_UDPCS_FAIL_bit (1UL<<18)
++#define RX_BROADPKT_bit (1UL<<17) // Receiving broadcast packet
++#define RX_MULTIPKT_bit (1UL<<16) // receiving multicast packet
++#define RX_HT_EN_bit (1UL<<15)
++#define RX_ALLADR_bit (1UL<<14) // not check incoming packet's destination address
++#define JUMBO_LF_bit (1UL<<13)
++#define RX_RUNT_bit (1UL<<12) // Store incoming packet even its length is les than 64 byte
++#define CRC_CHK_bit (1UL<<11)
++#define CRC_APD_bit (1UL<<10) // append crc to transmit packet
++#define GMAC_MODE_bit (1UL<<9)
++#define FULLDUP_bit (1UL<<8) // full duplex
++#define ENRX_IN_HALFTX_bit (1UL<<7)
++#define LOOP_EN_bit (1UL<<6) // Internal loop-back
++#define HPTXR_EN_bit (1UL<<5)
++#define REMOVE_VLAN_bit (1UL<<4)
++#define RXMAC_EN_bit (1UL<<3) // receiver enable
++#define TXMAC_EN_bit (1UL<<2) // transmitter enable
++#define RXDMA_EN_bit (1UL<<1) // enable DMA receiving channel
++#define TXDMA_EN_bit (1UL<<0) // enable DMA transmitting channel
++
++
++// --------------------------------------------------------------------
++// SCU_REG
++// --------------------------------------------------------------------
++#define SCU_BASE 0x1E6E2000
++#define SCU_PROTECT_KEY_REG 0x0
++#define SCU_PROT_KEY_MAGIC 0x1688a8a8
++#define SCU_RESET_CONTROL_REG 0x04
++#define SCU_RESET_MAC1 (1u << 11)
++#define SCU_RESET_MAC2 (1u << 12)
++#define SCU_HARDWARE_TRAPPING_REG 0x70
++#define SCU_HT_MAC_INTF_LSBIT 6
++#define SCU_HT_MAC_INTERFACE (0x7u << SCU_HT_MAC_INTF_LSBIT)
++#define MAC_INTF_SINGLE_PORT_MODES (1u<<0/*GMII*/ | 1u<<3/*MII_ONLY*/ | 1u<<4/*RMII_ONLY*/)
++#define SCU_HT_MAC_GMII 0x0u
++// MII and MII mode
++#define SCU_HT_MAC_MII_MII 0x1u
++#define SCU_HT_MAC_MII_ONLY 0x3u
++#define SCU_HT_MAC_RMII_ONLY 0x4u
++#define SCU_MULTIFUNCTION_PIN_REG 0x74
++#define SCU_MFP_MAC2_PHYLINK (1u << 26)
++#define SCU_MFP_MAC1_PHYLINK (1u << 25)
++#define SCU_MFP_MAC2_MII_INTF (1u << 21)
++#define SCU_MFP_MAC2_MDC_MDIO (1u << 20)
++#define SCU_SILICON_REVISION_REG 0x7C
++
++//---------------------------------------------------
++// PHY R/W Register Bit
++//---------------------------------------------------
++#define MIIWR (1UL<<27)
++#define MIIRD (1UL<<26)
++#define MDC_CYCTHR 0x34
++#define PHY_SPEED_MASK 0xC000
++#define PHY_DUPLEX_MASK 0x2000
++#define SPEED_1000M 0x02
++#define SPEED_100M 0x01
++#define SPEED_10M 0x00
++#define DUPLEX_FULL 0x01
++#define DUPLEX_HALF 0x00
++#define RESOLVED_BIT 0x800
++
++#define PHY_SPEED_DUPLEX_MASK 0x01E0
++#define PHY_100M_DUPLEX 0x0100
++#define PHY_100M_HALF 0x0080
++#define PHY_10M_DUPLEX 0x0040
++#define PHY_10M_HALF 0x0020
++
++//---------------------------------------------------
++// Descriptor bits.
++//---------------------------------------------------
++#define TXDMA_OWN 0x80000000 /* Own Bit */
++#define RXPKT_RDY 0x00000000
++#define RXPKT_STATUS 0x80000000
++#define EDORR 0x40000000 /* Receive End Of Ring */
++#define LRS 0x10000000 /* Last Descriptor */
++#define RD_ES 0x00008000 /* Error Summary */
++#define EDOTR 0x40000000 /* Transmit End Of Ring */
++#define T_OWN 0x80000000 /* Own Bit */
++#define LTS 0x10000000 /* Last Segment */
++#define FTS 0x20000000 /* First Segment */
++#define CRC_ERR 0x00080000
++#define TD_ES 0x00008000 /* Error Summary */
++#define TD_SET 0x08000000 /* Setup Packet */
++#define RX_ERR 0x00040000
++#define FTL 0x00100000
++#define RUNT 0x00200000
++#define RX_ODD_NB 0x00400000
++#define BYTE_COUNT_MASK 0x00003FFF
++
++//---------------------------------------------------
++// SPEED/DUPLEX Parameters
++//---------------------------------------------------
++
++//---------------------------------------------------
++// Return Status
++//---------------------------------------------------
++#define TEST_PASS 0
++#define PACKET_TEST_FAIL 1
++#define PACKET_LENGTH_TEST_FAIL 2
++
++struct mac_desc {
++ volatile s32 status;
++ u32 des1;
++ u32 reserved;
++ u32 buf;
++};
++static struct mac_desc rx_ring[NUM_RX] __attribute__ ((aligned(32))); /* RX descriptor ring */
++static struct mac_desc tx_ring[NUM_TX] __attribute__ ((aligned(32))); /* TX descriptor ring */
++static int rx_new; /* RX descriptor ring pointer */
++static int tx_new; /* TX descriptor ring pointer */
++static volatile unsigned char rx_buffer[NUM_RX][RX_BUFF_SZ] __attribute__ ((aligned(32))); /* RX buffer */
++static volatile unsigned char tx_buffer[NUM_TX][TX_BUFF_SZ] __attribute__ ((aligned(32))); /* TX buffer */
+diff --git a/board/aspeed/ast2300/mictest.c b/board/aspeed/ast2300/mictest.c
+new file mode 100755
+index 0000000..1b2b342
+--- /dev/null
++++ b/board/aspeed/ast2300/mictest.c
+@@ -0,0 +1,146 @@
++/*
++ * 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
++ */
++
++/*
++ * Diagnostics support
++ */
++#include <common.h>
++#include <command.h>
++#include <post.h>
++#include "slt.h"
++
++#if ((CFG_CMD_SLT & CFG_CMD_MICTEST) && defined(CONFIG_SLT))
++#include "mictest.h"
++
++static unsigned char ctrlbuf[MIC_MAX_CTRL];
++static unsigned char chksumbuf[MIC_MAX_CHKSUM];
++
++void vInitSCU(void)
++{
++ unsigned long ulData;
++
++ *(unsigned long *) (0x1e6e2000) = 0x1688A8A8;
++
++ udelay(100);
++
++ ulData = *(unsigned long *) (0x1e6e2004);
++ ulData &= 0xbffff;
++ *(unsigned long *) (0x1e6e2004) = ulData;
++
++}
++
++void vInitMIC(void)
++{
++ unsigned long i, j, ulPageNumber;
++ unsigned char *pjctrl, *pjsum;
++
++ ulPageNumber = DRAMSIZE >> 12;
++
++ pjctrl = (unsigned char *)(m16byteAlignment((unsigned long) ctrlbuf));
++ pjsum = (unsigned char *)(m16byteAlignment((unsigned long) chksumbuf));
++
++ /* init ctrl buffer (2bits for one page) */
++ for (i=0; i< (ulPageNumber/4); i++)
++ *(unsigned char *) (pjctrl + i) = DEFAULT_CTRL;
++
++ /* init chksum buf (4bytes for one page) */
++ for (i=0; i<ulPageNumber; i++)
++ *(unsigned long *) (pjsum + i*4) = DEFAULT_CHKSUM;
++
++ *(unsigned long *) (MIC_BASE + MIC_CTRLBUFF_REG) = (unsigned long) pjctrl;
++ *(unsigned long *) (MIC_BASE + MIC_CHKSUMBUF_REG) = (unsigned long) pjsum;
++ *(unsigned long *) (MIC_BASE + MIC_RATECTRL_REG) = (unsigned long) DEFAULT_RATE;
++ *(unsigned long *) (MIC_BASE + MIC_ENGINECTRL_REG) = MIC_ENABLE_MIC | (DRAMSIZE - 0x1000);
++
++}
++
++void vDisableMIC(void)
++{
++ *(unsigned long *) (MIC_BASE + MIC_ENGINECTRL_REG) = MIC_RESET_MIC;
++
++}
++
++int do_chksum(void)
++{
++ unsigned long i, j, k, ulPageNumber;
++ int Status = 0;
++ unsigned short tmp;
++ volatile unsigned long sum1, sum2;
++ unsigned long goldensum, chksum;
++ unsigned long len, tlen;
++ unsigned char *pjsum;
++
++ ulPageNumber = DRAMSIZE >> 12;
++ pjsum = (unsigned char *)(m16byteAlignment((unsigned long) chksumbuf));
++
++ /* start test */
++ for (i=0; i<ulPageNumber; i++)
++ {
++
++ sum1 = 0xffff, sum2 = 0xffff;
++ len = 0x0800;
++ j = 0;
++
++ while (len)
++ {
++ tlen = len > 360 ? 360 : len;
++ len -= tlen;
++ do {
++ tmp = *(unsigned short *) (DRAM_BASE + ((i << 12) + j));
++ sum1 += (unsigned long) tmp;
++ sum2 += sum1;
++ j+=2;
++ } while (--tlen);
++ sum1 = (sum1 & 0xffff) + (sum1 >> 16);
++ sum2 = (sum2 & 0xffff) + (sum2 >> 16);
++ }
++
++ sum1 = (sum1 & 0xffff) + (sum1 >> 16);
++ sum2 = (sum2 & 0xffff) + (sum2 >> 16);
++
++ goldensum = (sum2 << 16) | sum1;
++ k= 0;
++ do {
++ chksum = *(unsigned long *) (pjsum + i*4);
++ udelay(100);
++ k++;
++ } while ((chksum == 0) && (k<1000));
++
++ if (chksum != goldensum)
++ {
++ Status = 1;
++ printf("[FAIL] MIC Chksum Failed at Page %x \n", i);
++ }
++
++ } /* end of i loop */
++
++ return (Status);
++
++}
++
++int do_mictest (void)
++{
++ unsigned long Flags = 0;
++
++ vInitSCU();
++ vInitMIC();
++
++ if (do_chksum())
++ Flags = 1;
++
++ vDisableMIC();
++
++ return Flags;
++
++}
++
++#endif /* CONFIG_SLT */
+diff --git a/board/aspeed/ast2300/mictest.h b/board/aspeed/ast2300/mictest.h
+new file mode 100755
+index 0000000..e14bb41
+--- /dev/null
++++ b/board/aspeed/ast2300/mictest.h
+@@ -0,0 +1,55 @@
++/*
++ * 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
++ */
++/* Macro */
++#define m08byteAlignment(x) ((x + 0x00000007) & 0xFFFFFFF8)
++#define m16byteAlignment(x) ((x + 0x0000000F) & 0xFFFFFFF0)
++#define m64byteAlignment(x) ((x + 0x0000003F) & 0xFFFFFFC0)
++
++/* Options */
++#define MIC_TEST_PAGE 32
++#define DRAMSIZE (MIC_TEST_PAGE * 0x1000)
++#define MIC_MAX_CTRL (MIC_TEST_PAGE / 4 + 16)
++#define MIC_MAX_CHKSUM (MIC_TEST_PAGE * 4 + 16)
++
++/* Default Setting */
++#define DEFAULT_RATE 0x00000000
++#define DEFAULT_CTRL 0xFF
++#define DEFAULT_CHKSUM 0x00000000
++#define DEFAULT_WRITEBACK 0x08880000
++
++/* Reg. Definition */
++#define DRAM_BASE 0x40000000
++#define MIC_BASE 0x1e640000
++#define MIC_CTRLBUFF_REG 0x00
++#define MIC_CHKSUMBUF_REG 0x04
++#define MIC_RATECTRL_REG 0x08
++#define MIC_ENGINECTRL_REG 0x0C
++#define MIC_STOPPAGE_REG 0x10
++#define MIC_STATUS_REG 0x14
++#define MIC_STATUS1_REG 0x18
++#define MIC_STATUS2_REG 0x1C
++
++#define MIC_RESET_MIC 0x00000000
++#define MIC_ENABLE_MIC 0x10000000
++#define MIC_MAXPAGE_MASK 0x0FFFF000
++#define MIC_WRITEBACK_MASK 0xFFFF0000
++#define MIC_STOPPAGE_MASK 0x0000FFFF
++#define MIC_PAGEERROR 0x40000000
++#define MIC_PAGE1ERROR 0x10000000
++#define MIC_PAGE2ERROR 0x20000000
++#define MIC_INTMASK 0x00060000
++#define MIC_ERRPAGENO_MASK 0x0000FFFF
++
++#define MIC_CTRL_MASK 0x03
++#define MIC_CTRL_SKIP 0x00
++#define MIC_CTRL_CHK1 0x01
++#define MIC_CTRL_CHK2 0x02
++#define MIC_CTRL_CHK3 0x03
+diff --git a/board/aspeed/ast2300/pci.c b/board/aspeed/ast2300/pci.c
+new file mode 100755
+index 0000000..5b17466
+--- /dev/null
++++ b/board/aspeed/ast2300/pci.c
+@@ -0,0 +1,243 @@
++/*
++ * 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, or (at
++ * your option) any later version.
++ */
++
++#include <common.h>
++#include <pci.h>
++
++#ifdef CONFIG_PCI
++
++#define PCI_CSR_BASE 0x60000000
++#define ASPEED_PCI_IO_BASE 0x00000000
++#define ASPEED_PCI_IO_SIZE 0x00010000
++#define ASPEED_PCI_MEM_BASE 0x68000000
++#define ASPEED_PCI_MEM_SIZE 0x18000000
++
++#define CSR_CRP_CMD_OFFSET 0x00
++#define CSR_CRP_WRITE_OFFSET 0x04
++#define CSR_CRP_READ_OFFSET 0x08
++#define CSR_PCI_ADDR_OFFSET 0x0C
++#define CSR_PCI_CMD_OFFSET 0x10
++#define CSR_PCI_WRITE_OFFSET 0x14
++#define CSR_PCI_READ_OFFSET 0x18
++#define CSR_PCI_STATUS_OFFSET 0x1C
++
++#define CRP_ADDR_REG (volatile ulong*) (PCI_CSR_BASE + CSR_CRP_CMD_OFFSET)
++#define CRP_WRITE_REG (volatile ulong*) (PCI_CSR_BASE + CSR_CRP_WRITE_OFFSET)
++#define CRP_READ_REG (volatile ulong*) (PCI_CSR_BASE + CSR_CRP_READ_OFFSET)
++#define PCI_ADDR_REG (volatile ulong*) (PCI_CSR_BASE + CSR_PCI_ADDR_OFFSET)
++#define PCI_CMD_REG (volatile ulong*) (PCI_CSR_BASE + CSR_PCI_CMD_OFFSET)
++#define PCI_WRITE_REG (volatile ulong*) (PCI_CSR_BASE + CSR_PCI_WRITE_OFFSET)
++#define PCI_READ_REG (volatile ulong*) (PCI_CSR_BASE + CSR_PCI_READ_OFFSET)
++
++#define PCI_CMD_READ 0x0A
++#define PCI_CMD_WRITE 0x0B
++
++#define RESET_PCI_STATUS *(volatile ulong*) (PCI_CSR_BASE + CSR_PCI_STATUS_OFFSET) = 0x01
++#define CHK_PCI_STATUS (*(volatile ulong*) (PCI_CSR_BASE + CSR_PCI_STATUS_OFFSET) & 0x03)
++
++static int pci_config_access (u8 access_type, u32 dev, u32 reg, u32 * data)
++{
++ u32 bus;
++ u32 device;
++ u32 function;
++
++ bus = ((dev & 0xff0000) >> 16);
++ device = ((dev & 0xf800) >> 11);
++ function = (dev & 0x0700);
++
++ if (bus == 0) {
++ // Type 0 Configuration
++ *PCI_ADDR_REG = (u32) (1UL << device | function | (reg & 0xfc));
++ } else {
++ // Type 1 Configuration
++ *PCI_ADDR_REG = (u32) (dev | ((reg / 4) << 2) | 1);
++ }
++
++ RESET_PCI_STATUS;
++
++ if (access_type == PCI_CMD_WRITE) {
++ *PCI_CMD_REG = (ulong) PCI_CMD_WRITE;
++ *PCI_WRITE_REG = *data;
++ } else {
++ *PCI_CMD_REG = (ulong) PCI_CMD_READ;
++ *data = *PCI_READ_REG;
++ }
++
++ return (CHK_PCI_STATUS);
++}
++
++static int aspeed_pci_read_config_byte (u32 hose, u32 dev, u32 reg, u8 * val)
++{
++ u32 data;
++
++ if (pci_config_access (PCI_CMD_READ, dev, reg, &data)) {
++ *val = 0;
++ return -1;
++ }
++
++ *val = (data >> ((reg & 3) << 3)) & 0xff;
++
++ return 0;
++}
++
++
++static int aspeed_pci_read_config_word (u32 hose, u32 dev, u32 reg, u16 * val)
++{
++ u32 data;
++
++ if (reg & 1)
++ return -1;
++
++ if (pci_config_access (PCI_CMD_READ, dev, reg, &data)) {
++ *val = 0;
++ return -1;
++ }
++
++ *val = (data >> ((reg & 3) << 3)) & 0xffff;
++
++ return 0;
++}
++
++
++static int aspeed_pci_read_config_dword (u32 hose, u32 dev, u32 reg,
++ u32 * val)
++{
++ u32 data = 0;
++
++ if (reg & 3)
++ return -1;
++
++ if (pci_config_access (PCI_CMD_READ, dev, reg, &data)) {
++ *val = 0;
++ return -1;
++ }
++
++ *val = data;
++
++ return (0);
++}
++
++static int aspeed_pci_write_config_byte (u32 hose, u32 dev, u32 reg, u8 val)
++{
++ u32 data = 0;
++
++ if (pci_config_access (PCI_CMD_READ, dev, reg, &data))
++ return -1;
++
++ data = (data & ~(0xff << ((reg & 3) << 3))) | (val <<
++ ((reg & 3) << 3));
++
++ if (pci_config_access (PCI_CMD_WRITE, dev, reg, &data))
++ return -1;
++
++ return 0;
++}
++
++
++static int aspeed_pci_write_config_word (u32 hose, u32 dev, u32 reg, u16 val)
++{
++ u32 data = 0;
++
++ if (reg & 1)
++ return -1;
++
++ if (pci_config_access (PCI_CMD_READ, dev, reg, &data))
++ return -1;
++
++ data = (data & ~(0xffff << ((reg & 3) << 3))) | (val <<
++ ((reg & 3) << 3));
++
++ if (pci_config_access (PCI_CMD_WRITE, dev, reg, &data))
++ return -1;
++
++ return 0;
++}
++
++static int aspeed_pci_write_config_dword (u32 hose, u32 dev, u32 reg, u32 val)
++{
++ u32 data;
++
++ if (reg & 3) {
++ return -1;
++ }
++
++ data = val;
++
++ if (pci_config_access (PCI_CMD_WRITE, dev, reg, &data))
++ return -1;
++
++ return (0);
++}
++
++/*
++ * Initialize PCIU
++ */
++aspeed_pciu_init ()
++{
++
++ unsigned long reg;
++
++ /* Reset PCI Host */
++ reg = *((volatile ulong*) 0x1e6e2004);
++ *((volatile ulong*) 0x1e6e2004) = reg | 0x00280000;
++
++ reg = *((volatile ulong*) 0x1e6e2074); /* REQ2 */
++ *((volatile ulong*) 0x1e6e2074) = reg | 0x00000010;
++
++ *((volatile ulong*) 0x1e6e2008) |= 0x00080000;
++ reg = *((volatile ulong*) 0x1e6e200c);
++ *((volatile ulong*) 0x1e6e200c) = reg & 0xfff7ffff;
++ udelay(1);
++ *((volatile ulong*) 0x1e6e2004) &= 0xfff7ffff;
++
++ /* Initial PCI Host */
++ RESET_PCI_STATUS;
++
++ *CRP_ADDR_REG = ((ulong)(PCI_CMD_READ) << 16) | 0x04;
++ reg = *CRP_READ_REG;
++
++ *CRP_ADDR_REG = ((ulong)(PCI_CMD_WRITE) << 16) | 0x04;
++ *CRP_WRITE_REG = reg | 0x07;
++
++}
++
++/*
++ * Initialize Module
++ */
++
++void aspeed_init_pci (struct pci_controller *hose)
++{
++ hose->first_busno = 0;
++ hose->last_busno = 0xff;
++
++ aspeed_pciu_init (); /* Initialize PCIU */
++
++ /* PCI memory space #1 */
++ pci_set_region (hose->regions + 0,
++ ASPEED_PCI_MEM_BASE, ASPEED_PCI_MEM_BASE, ASPEED_PCI_MEM_SIZE, PCI_REGION_MEM);
++
++ /* PCI I/O space */
++ pci_set_region (hose->regions + 1,
++ ASPEED_PCI_IO_BASE, ASPEED_PCI_IO_BASE, ASPEED_PCI_IO_SIZE, PCI_REGION_IO);
++
++ hose->region_count = 2;
++
++ hose->read_byte = aspeed_pci_read_config_byte;
++ hose->read_word = aspeed_pci_read_config_word;
++ hose->read_dword = aspeed_pci_read_config_dword;
++ hose->write_byte = aspeed_pci_write_config_byte;
++ hose->write_word = aspeed_pci_write_config_word;
++ hose->write_dword = aspeed_pci_write_config_dword;
++
++ pci_register_hose (hose);
++
++ hose->last_busno = pci_hose_scan (hose);
++
++ return;
++}
++#endif /* CONFIG_PCI */
++
+diff --git a/board/aspeed/ast2300/platform.S b/board/aspeed/ast2300/platform.S
+new file mode 100644
+index 0000000..27e8f26
+--- /dev/null
++++ b/board/aspeed/ast2300/platform.S
+@@ -0,0 +1,3089 @@
++/*
++ * 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
++ */
++/*
++ * Board specific setup info
++ *
++ ******************************************************************************
++ * ASPEED Technology Inc.
++ * AST2300/AST2400 DDR2/DDR3 SDRAM controller initialization and calibration sequence
++ *
++ * Gary Hsu, <gary_hsu@aspeedtech.com>
++ *
++ * Release date: 2014.12.29 formal release for SDK0.60
++ *
++ * Modified list from v0.23
++ * EC1. Modify DQIDLY and DQSI-MCLK2X calibration algorithm
++ * EC2. Remove pass 2 DQIDLY finetune process
++ * EC3. Modify ECC code
++ * EC4. Add AST2400 supporting
++ * EC5. Add SPI timing calibration for AST2400
++ * EC6. Remove AST2300-A0 PCI-e workaround
++ * EC7. Add CK duty calibration for AST2400
++ * EC8. Remove #define CONFIG_DRAM_UART_OUT, default has message output to UART5
++ * EC9. Add DRAM size auto-detection
++ * EC10. Add GPIO register clear when watchdog reboot (only for AST2400)
++ * EC11. Move the "Solve ASPM" code position of AST2300 to avoid watchdog reset
++ *
++ * Modified list from v0.53
++ * EC1. Add solution of LPC lock issue due to watchdog reset. (AP note A2300-11)
++ *
++ * Modified list from v0.56
++ * EC1. Fix read DQS input mask window too late issue if DRAM's t_DQSCK is earlier too much
++ * (ex. Nanya NT5CB64M16FP)
++ * 1. Change init value of MCR18[4] from '1' to '0'
++ * 2. Add CBR4 code to finetune MCR18[4]
++ *
++ * Modified list from v0.59
++ * EC1. Add DQS input gating window delay tuning (1/2 T) when CBR retry
++ * EC2. Modify DLL1 MAdj = 0x4C
++ *
++ * Optional define variable
++ * 1. DRAM Speed //
++ * CONFIG_DRAM_336 // 336MHz (DDR-667)
++ * CONFIG_DRAM_408 // 408MHz (DDR-800) (default)
++ * 2. ECC Function enable
++ * CONFIG_DRAM_ECC // define to enable ECC function
++ * // when enabled, must define the ECC protected memory size at 0x1e6e0054
++ * 3. UART5 message output //
++ * CONFIG_DRAM_UART_38400 // set the UART baud rate to 38400, default is 115200
++ ******************************************************************************
++ */
++
++#include <config.h>
++#include <version.h>
++/******************************************************************************
++ Calibration Macro Start
++ Usable registers:
++ r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, r11
++ ******************************************************************************/
++/* PATTERN_TABLE,
++ init_delay_timer,
++ check_delay_timer,
++ clear_delay_timer,
++ record_dll2_pass_range,
++ record_dll2_pass_range_h,
++ are for DRAM calibration */
++
++PATTERN_TABLE:
++ .word 0xff00ff00
++ .word 0xcc33cc33
++ .word 0xaa55aa55
++ .word 0x88778877
++ .word 0x92cc4d6e @ 5
++ .word 0x543d3cde
++ .word 0xf1e843c7
++ .word 0x7c61d253
++ .word 0x00000000 @ 8
++
++ .macro init_delay_timer
++ ldr r0, =0x1e782024 @ Set Timer3 Reload
++ str r2, [r0]
++
++ ldr r0, =0x1e6c0038 @ Clear Timer3 ISR
++ ldr r1, =0x00040000
++ str r1, [r0]
++
++ ldr r0, =0x1e782030 @ Enable Timer3
++ ldr r1, [r0]
++ mov r2, #7
++ orr r1, r1, r2, lsl #8
++ str r1, [r0]
++
++ ldr r0, =0x1e6c0090 @ Check ISR for Timer3 timeout
++ .endm
++
++ .macro check_delay_timer
++ ldr r1, [r0]
++ bic r1, r1, #0xFFFBFFFF
++ mov r2, r1, lsr #18
++ cmp r2, #0x01
++ .endm
++
++ .macro clear_delay_timer
++ ldr r0, =0x1e782030 @ Disable Timer3
++ ldr r1, [r0]
++ bic r1, r1, #0x00000F00
++ str r1, [r0]
++
++ ldr r0, =0x1e6c0038 @ Clear Timer3 ISR
++ ldr r1, =0x00040000
++ str r1, [r0]
++ .endm
++
++ .macro record_dll2_pass_range
++ ldr r1, [r0]
++ bic r2, r1, #0xFFFFFF00
++ cmp r2, r3 @ record min
++ bicgt r1, r1, #0x000000FF
++ orrgt r1, r1, r3
++ bic r2, r1, #0xFFFF00FF
++ cmp r3, r2, lsr #8 @ record max
++ bicgt r1, r1, #0x0000FF00
++ orrgt r1, r1, r3, lsl #8
++ str r1, [r0]
++ .endm
++
++ .macro record_dll2_pass_range_h
++ ldr r1, [r0]
++ bic r2, r1, #0xFF00FFFF
++ mov r2, r2, lsr #16
++ cmp r2, r3 @ record min
++ bicgt r1, r1, #0x00FF0000
++ orrgt r1, r1, r3, lsl #16
++ bic r2, r1, #0x00FFFFFF
++ cmp r3, r2, lsr #24 @ record max
++ bicgt r1, r1, #0xFF000000
++ orrgt r1, r1, r3, lsl #24
++ str r1, [r0]
++ .endm
++
++ .macro init_spi_checksum
++ ldr r0, =0x1e620084
++ ldr r1, =0x20010000
++ str r1, [r0]
++ ldr r0, =0x1e62008C
++ ldr r1, =0x20000200
++ str r1, [r0]
++ ldr r0, =0x1e620080
++ ldr r1, =0x0000000D
++ orr r2, r2, r7
++ orr r1, r1, r2, lsl #8
++ and r2, r6, #0xF
++ orr r1, r1, r2, lsl #4
++ str r1, [r0]
++ ldr r0, =0x1e620008
++ ldr r2, =0x00000800
++ .endm
++
++/******************************************************************************
++ Calibration Macro End
++ ******************************************************************************/
++LPC_Patch: @ load to SRAM base 0x1e720400
++ str r1, [r0]
++ str r3, [r2]
++ bic r1, r1, #0xFF
++LPC_Patch_S1:
++ subs r5, r5, #0x01
++ moveq pc, r8
++ ldr r3, [r2]
++ tst r3, #0x01
++ movne pc, r8
++ mov pc, r7
++LPC_Patch_S2: @ load to SRAM base 0x1e720480
++ str r1, [r0]
++ mov pc, r9
++LPC_Patch_E:
++
++.globl lowlevel_init
++lowlevel_init:
++
++init_dram:
++ /* save lr */
++ mov r4, lr
++/* Test - DRAM initial time */
++ ldr r0, =0x1e782044
++ ldr r1, =0xFFFFFFFF
++ str r1, [r0]
++
++ ldr r0, =0x1e782030
++ ldr r1, [r0]
++ bic r1, r1, #0x0000F000
++ str r1, [r0]
++ mov r2, #3
++ orr r1, r1, r2, lsl #12
++ str r1, [r0]
++/* Test - DRAM initial time */
++
++ /*Set Scratch register Bit 7 before initialize*/
++ ldr r0, =0x1e6e2000
++ ldr r1, =0x1688a8a8
++ str r1, [r0]
++
++ ldr r0, =0x1e6e2040
++ ldr r1, [r0]
++ orr r1, r1, #0x80
++ str r1, [r0]
++
++ /* Fix LPC lock issue for AST2300 */
++ ldr r0, =0x1e6e207c @ Check AST2300
++ ldr r1, [r0]
++ mov r1, r1, lsr #24
++ cmp r1, #0x01
++ bne lpc_recover_end @ not match AST2300
++
++ mov r3, #0x0
++lpc_recover_check:
++ ldr r0, =0x1e78900c @ check HICR3[4]=0x1
++ ldr r1, [r0]
++ tst r1, #0x10
++ beq lpc_recover_end
++ ldr r0, =0x1e789004 @ check HICR1[7]=0x1
++ ldr r1, [r0]
++ tst r1, #0x80
++ beq lpc_recover_end
++ ldr r0, =0x1e7890a0 @ check LHCR0[27:24]=0x6
++ ldr r1, [r0]
++ mov r1, r1, lsr #24
++ and r1, r1, #0xF
++ cmp r1, #0x06
++ bne lpc_recover_end
++ add r3, r3, #0x01
++ cmp r3, #0x5 @ repeat 5 times
++ ble lpc_recover_check
++
++ mov r3, #0x0
++lpc_recover_init:
++ ldr r0, =0x1e7890a4 @ set LHCR1[1:0]=0x0
++ ldr r1, =0x00000000
++ str r1, [r0]
++ add r3, r3, #0x01
++ cmp r3, #0x20
++ bge lpc_recover_end
++ ldr r1, [r0]
++ tst r1, #0x01
++ bne lpc_recover_init
++
++ ldr r0, =0x1e7890b0 @ set LHCR4[7:0]=0xFF
++ ldr r1, =0x000000FF
++ str r1, [r0]
++ ldr r0, =0x1e7890b4 @ set LHCR5[31:0]=0xFFFFFFFF
++ ldr r1, =0xFFFFFFFF
++ str r1, [r0]
++ ldr r0, =0x1e7890b8 @ set LHCR6[31:0]=0xFFFFFFFF
++ str r1, [r0]
++
++ adr r6, LPC_Patch
++ adr r7, LPC_Patch_S2
++ ldr r0, =0x1e720400
++copy_lpc_patch_1:
++ ldr r1, [r6]
++ str r1, [r0]
++ add r6, r6, #0x4
++ add r0, r0, #0x4
++ cmp r6, r7
++ bne copy_lpc_patch_1
++
++ adr r6, LPC_Patch_S2
++ adr r7, LPC_Patch_E
++ ldr r0, =0x1e720480
++copy_lpc_patch_2:
++ ldr r1, [r6]
++ str r1, [r0]
++ add r6, r6, #0x4
++ add r0, r0, #0x4
++ cmp r6, r7
++ bne copy_lpc_patch_2
++
++ ldr r0, =0x1e7890a0 @ set LHCR0[31:0]=0xFFFFFF01
++ ldr r1, =0xFFFFFF01
++ add r2, r0, #0x4
++ mov r3, #0x01
++ mov r5, #0x10
++ adr r9, lpc_recover_end
++ adr r6, LPC_Patch
++ adr r7, LPC_Patch_S1
++ sub r6, r7, r6
++ ldr r7, =0x1e720400
++ add r7, r7, r6
++ ldr r8, =0x1e720480
++ ldr pc, =0x1e720400
++
++lpc_recover_end:
++ ldr r0, =0x1e7890a0 @ set LHCR0[31:0]=0xFFFFFF00
++ ldr r1, =0xFFFFFF00
++ str r1, [r0]
++ /* <END> Fix LPC lock issue for AST2300 */
++
++ /* Check Scratch Register Bit 6 */
++ ldr r0, =0x1e6e2040
++ ldr r1, [r0]
++ bic r1, r1, #0xFFFFFFBF
++ mov r2, r1, lsr #6
++ cmp r2, #0x01
++ beq platform_exit
++
++ ldr r2, =0x033103F1 @ load PLL parameter for 24Mhz CLKIN (396:324)
++/* ldr r2, =0x019001F0 @ load PLL parameter for 24Mhz CLKIN (408:336) */
++ ldr r0, =0x1e6e207c @ Check Revision ID
++ ldr r1, [r0]
++ mov r1, r1, lsr #24
++ cmp r1, #0x02
++ bne set_MPLL @ not match AST2400
++
++ ldr r0, =0x1e6e2070 @ Check CLKIN freq
++ ldr r1, [r0]
++ mov r1, r1, lsr #23
++ tst r1, #0x01
++ ldrne r2, =0x017001D0 @ load PLL parameter for 25Mhz CLKIN (400:325)
++
++set_MPLL:
++ ldr r0, =0x1e6e2020 @ M-PLL (DDR SDRAM) Frequency
++ ldr r1, =0xFFFF
++#if defined(CONFIG_DRAM_336)
++ mov r2, r2, lsr #16
++#endif
++ and r1, r2, r1
++ str r1, [r0]
++
++/* Debug - UART console message */
++ ldr r0, =0x1e78400c
++ mov r1, #0x83
++ str r1, [r0]
++
++ ldr r0, =0x1e6e202c
++ ldr r2, [r0]
++ mov r2, r2, lsr #12
++ tst r2, #0x01
++ ldr r0, =0x1e784000
++ moveq r1, #0x0D @ Baudrate 115200
++ movne r1, #0x01 @ Baudrate 115200, div13
++#if defined(CONFIG_DRAM_UART_38400)
++ moveq r1, #0x27 @ Baudrate 38400
++ movne r1, #0x03 @ Baudrate 38400 , div13
++#endif
++ str r1, [r0]
++
++ ldr r0, =0x1e784004
++ mov r1, #0x00
++ str r1, [r0]
++
++ ldr r0, =0x1e78400c
++ mov r1, #0x03
++ str r1, [r0]
++
++ ldr r0, =0x1e784008
++ mov r1, #0x07
++ str r1, [r0]
++
++ ldr r0, =0x1e784000
++ mov r1, #0x0D @ '\r'
++ str r1, [r0]
++ mov r1, #0x0A @ '\n'
++ str r1, [r0]
++ mov r1, #0x44 @ 'D'
++ str r1, [r0]
++ mov r1, #0x52 @ 'R'
++ str r1, [r0]
++ mov r1, #0x41 @ 'A'
++ str r1, [r0]
++ mov r1, #0x4D @ 'M'
++ str r1, [r0]
++ mov r1, #0x20 @ ' '
++ str r1, [r0]
++ mov r1, #0x49 @ 'I'
++ str r1, [r0]
++ mov r1, #0x6E @ 'n'
++ str r1, [r0]
++ mov r1, #0x69 @ 'i'
++ str r1, [r0]
++ mov r1, #0x74 @ 't'
++ str r1, [r0]
++ mov r1, #0x2D @ '-'
++ str r1, [r0]
++ mov r1, #0x44 @ 'D'
++ str r1, [r0]
++ mov r1, #0x44 @ 'D'
++ str r1, [r0]
++ mov r1, #0x52 @ 'R'
++ str r1, [r0]
++/* Debug - UART console message */
++
++ /* Delay about 100us */
++ ldr r0, =0x1e782030 @ Init Timer3 Control
++ ldr r1, [r0]
++ bic r1, r1, #0x00000F00
++ str r1, [r0]
++
++ ldr r2, =0x00000064 @ Set Timer3 Reload = 100 us
++ init_delay_timer
++delay_0:
++ check_delay_timer
++ bne delay_0
++ clear_delay_timer
++ /* end delay 100us */
++
++/******************************************************************************
++ Init DRAM common registers
++ ******************************************************************************/
++ ldr r0, =0x1e6e0000
++ ldr r1, =0xfc600309
++ str r1, [r0]
++
++ /* Reset MMC */
++ ldr r1, =0x00000000
++ ldr r0, =0x1e6e0034
++ str r1, [r0]
++ ldr r0, =0x1e6e0018
++ str r1, [r0]
++ ldr r0, =0x1e6e0024
++ str r1, [r0]
++ ldr r0, =0x1e6e0064 @ REG_MADJ, power down DLL
++ str r1, [r0]
++
++ ldr r1, =0x00034C4C @ REG_MADJ, reset DLL
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0068 @ REG_SADJ
++ ldr r1, =0x00001800
++ str r1, [r0]
++
++ /* Delay about 10us */
++ ldr r2, =0x0000000B @ Set Timer3 Reload = 10 us
++ init_delay_timer
++delay_1:
++ check_delay_timer
++ bne delay_1
++ clear_delay_timer
++ /* end delay 10us */
++
++ ldr r0, =0x1e6e0064 @ REG_MADJ | 0xC0000, enable DLL
++ ldr r1, [r0]
++ ldr r2, =0xC0000
++ orr r1, r1, r2
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0008
++ ldr r1, =0x0090040f /* VGA */
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0018
++ ldr r1, =0x4000A120
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0018
++ ldr r1, =0x00000120
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0038
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0040
++ ldr r1, =0xFF444444
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0044
++ ldr r1, =0x22222222
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0048
++ ldr r1, =0x22222222
++ str r1, [r0]
++
++ ldr r0, =0x1e6e004c
++ ldr r1, =0x22222222
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0050
++ ldr r1, =0x80000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0050
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0054
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0060 @ REG_DRV
++ ldr r1, =0x000000FA @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x000000FA
++#endif
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0070
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0074
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0078
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e007c
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0080
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0084
++ ldr r1, =0x00FFFFFF
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0088 @ REG_DQIDLY
++ ldr r1, =0x00000089 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x00000074
++#endif
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0020 @ REG_DQSIC
++ ldr r1, =0x000000E2 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x000000BA
++#endif
++ str r1, [r0]
++
++ /* Delay about 10us */
++ ldr r2, =0x0000000B @ Set Timer3 Reload = 10 us
++ init_delay_timer
++delay_2:
++ check_delay_timer
++ bne delay_2
++ clear_delay_timer
++ /* end delay 10us */
++
++ /* Check DRAM Type by H/W Trapping */
++ ldr r0, =0x1e6e2070
++ ldr r1, [r0]
++ bic r1, r1, #0xFEFFFFFF @ bit[24]=1 => DDR2
++ mov r2, r1, lsr #24
++ cmp r2, #0x01
++ beq ddr2_init
++ b ddr3_init
++.LTORG
++
++/******************************************************************************
++ DDR3 Init
++
++ tRCD = 15 ns
++ tRAS = 37.5 ns
++ tRRD = max(4 CK,10 ns)
++ tRP = 15 ns
++ tRFC = 110ns/1Gbit, 160ns/2Gbit, 300ns/4Gbit
++ tRTP = max(4 CK,7.5 ns)
++ tWR = 15 ns
++ tXSNR = max(10 CK,200 ns)
++ tWTR = max(4 CK,7.5 ns)
++ tFAW = 50 ns
++ tMRD = max(15 CK,20 ns)
++ ******************************************************************************/
++ddr3_init:
++/* Debug - UART console message */
++ ldr r0, =0x1e784000
++ mov r1, #0x33 @ '3'
++ str r1, [r0]
++ mov r1, #0x0D @ '\r'
++ str r1, [r0]
++ mov r1, #0x0A @ '\n'
++ str r1, [r0]
++/* Debug - UART console message */
++
++ ldr r0, =0x1e6e0004
++ ldr r1, =0x00000531 @ Default set to 1Gbit
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0010 @ REG_AC1
++ ldr r1, =0x33302825 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x22202725
++#endif
++ str r1, [r0]
++
++ /* Check DRAM CL Timing by H/W Trapping */
++ ldr r0, =0x1e6e2070
++ ldr r1, [r0]
++ bic r1, r1, #0xF9FFFFFF
++ mov r2, r1, lsr #9 @ Set CL
++ ldr r1, =0x00020000
++ add r2, r2, r1
++ ldr r1, [r0]
++ bic r1, r1, #0xFBFFFFFF
++ mov r1, r1, lsr #6 @ Set CWL
++ orr r2, r2, r1
++ ldr r1, =0x00300000
++ add r2, r2, r1
++
++ ldr r0, =0x1e6e0014 @ REG_AC2
++ ldr r1, =0xCC00963F @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0xAA007636
++#endif
++ orr r1, r1, r2
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0004 @ check 2400 mode
++ ldr r2, [r0]
++ mov r2, r2, lsr #10
++
++ ldr r0, =0x1e6e006c @ REG_IOZ
++ ldr r1, =0x00002312 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x00002312
++#endif
++ tst r2, #0x01
++ moveq r1, r1, lsr #8
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0120
++ mov r1, #0
++ str r1, [r0]
++ tst r2, #0x01 @ check AST2300
++ beq CBRDLL1_2300_Start
++ ldr r0, =0x1e6e207c @ check AST2400 revision A0
++ ldr r1, [r0]
++ mov r1, r1, lsr #16
++ and r1, r1, #0xFF
++ cmp r1, #0x0
++ beq CBRDLL1_2300_Start
++ b CBRDLL1_2400_Start
++MCLK2X_Phase_CBR_Done_DDR3:
++ ldr r0, =0x1e6e0018
++ ldr r1, [r0]
++ orr r1, r1, #0x40
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0034
++ ldr r1, =0x00000001
++ str r1, [r0]
++
++ ldr r0, =0x1e6e000c
++ ldr r1, =0x00000040
++ str r1, [r0]
++
++ /* Delay about 400us */
++ ldr r2, =0x00000190 @ Set Timer3 Reload = 400 us
++ init_delay_timer
++delay3_4:
++ check_delay_timer
++ bne delay3_4
++ clear_delay_timer
++ /* end delay 400us */
++
++ /* Check DRAM CL Timing by H/W Trapping */
++ ldr r0, =0x1e6e2070
++ ldr r1, [r0]
++ bic r1, r1, #0xF9FFFFFF
++ mov r2, r1, lsr #21 @ Set CL
++ ldr r1, =0x00000010
++ add r2, r2, r1
++ ldr r1, [r0]
++ bic r1, r1, #0xFBFFFFFF
++ mov r1, r1, lsr #7 @ Set CWL
++ orr r2, r2, r1
++
++ ldr r0, =0x1e6e002c @ REG_MRS
++ ldr r1, =0x04001700 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x04001500
++#endif
++ orr r1, r1, r2
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0030 @ REG_EMRS
++ ldr r1, =0x00000000 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x00000000
++#endif
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set EMRS2
++ ldr r1, =0x00000005
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set EMRS3
++ ldr r1, =0x00000007
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set EMRS
++ ldr r1, =0x00000003
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set MRS
++ ldr r1, =0x00000001
++ str r1, [r0]
++
++ ldr r0, =0x1e6e002c @ REG_MRS
++ ldr r1, =0x04001600 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x04001400
++#endif
++ orr r1, r1, r2
++ str r1, [r0]
++
++ ldr r0, =0x1e6e000c @ Refresh 8 times
++ ldr r1, =0x00005C48
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set MRS
++ ldr r1, =0x00000001
++ str r1, [r0]
++
++ ldr r0, =0x1e6e000c @ Set refresh cycle
++ ldr r1, =0x00002001
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0014
++ ldr r1, [r0]
++ bic r1, r1, #0xFFF9FFFF
++ mov r2, r1, lsr #3 @ get CL
++
++ ldr r0, =0x1e6e0034 @ REG_PWC
++ ldr r1, =0x00000303 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x00000303
++#endif
++ orr r1, r1, r2
++ str r1, [r0]
++
++ b Calibration_Start
++.LTORG
++/******************************************************************************
++ End DDR3 Init
++ ******************************************************************************/
++
++/******************************************************************************
++ DDR2 Init
++
++ tRCD = 15 ns
++ tRAS = 45 ns
++ tRRD = 10 ns
++ tRP = 15 ns
++ tRFC = 105ns/512Mbit, 127.5ns/1Gbit, 197.5ns/2Gbit, 327.5ns/4Gbit
++ tRTP = 7.5 ns
++ tWR = 15 ns
++ tXSNR = 200 ns
++ tWTR = 7.5 ns
++ tFAW = 50 ns
++ tMRD = 4 CK
++ ******************************************************************************/
++ddr2_init:
++/* Debug - UART console message */
++ ldr r0, =0x1e784000
++ mov r1, #0x32 @ '2'
++ str r1, [r0]
++ mov r1, #0x0D @ '\r'
++ str r1, [r0]
++ mov r1, #0x0A @ '\n'
++ str r1, [r0]
++/* Debug - UART console message */
++
++ ldr r0, =0x1e6e0004
++ ldr r1, =0x00000510 @ Default set to 512Mbit
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0010 @ REG_AC1
++ ldr r1, =0x33302714 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x22201613
++#endif
++ str r1, [r0]
++
++ /* Check DRAM CL Timing by H/W Trapping */
++ ldr r0, =0x1e6e2070
++ ldr r1, [r0]
++ bic r1, r1, #0xF9FFFFFF
++ mov r2, r1, lsr #5 @ Set CL
++ mov r1, r2, lsr #4 @ Set CWL
++ orr r2, r2, r1
++ ldr r1, =0x00110000
++ add r2, r2, r1
++
++ ldr r0, =0x1e6e0014 @ REG_AC2
++ ldr r1, =0xCC00B03F @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0xAA00903B
++#endif
++ orr r1, r1, r2
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0004 @ check 2400 mode
++ ldr r2, [r0]
++ mov r2, r2, lsr #10
++
++ ldr r0, =0x1e6e006c @ REG_IOZ
++ ldr r1, =0x00002312 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x00002312
++#endif
++ tst r2, #0x01
++ moveq r1, r1, lsr #8
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0120
++ mov r1, #1
++ str r1, [r0]
++ tst r2, #0x01 @ check AST2300
++ beq CBRDLL1_2300_Start
++ ldr r0, =0x1e6e207c @ check AST2400 revision A0
++ ldr r1, [r0]
++ mov r1, r1, lsr #16
++ and r1, r1, #0xFF
++ cmp r1, #0x0
++ beq CBRDLL1_2300_Start
++ b CBRDLL1_2400_Start
++MCLK2X_Phase_CBR_Done_DDR2:
++
++ ldr r0, =0x1e6e0034
++ ldr r1, =0x00000001
++ str r1, [r0]
++
++ ldr r0, =0x1e6e000c
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++ /* Delay about 400us */
++ ldr r2, =0x00000190 @ Set Timer3 Reload = 400 us
++ init_delay_timer
++delay2_4:
++ check_delay_timer
++ bne delay2_4
++ clear_delay_timer
++ /* end delay 400us */
++
++ /* Check DRAM CL Timing by H/W Trapping */
++ ldr r0, =0x1e6e2070
++ ldr r1, [r0]
++ bic r1, r1, #0xF9FFFFFF
++ mov r2, r1, lsr #21 @ Set CL
++ ldr r1, =0x00000040
++ orr r2, r2, r1
++
++ ldr r0, =0x1e6e002c @ REG_MRS
++ ldr r1, =0x00000D03 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x00000B03
++#endif
++ orr r1, r1, r2
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0030 @ REG_EMRS
++ ldr r1, =0x00000040 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x00000040
++#endif
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set EMRS2
++ ldr r1, =0x00000005
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set EMRS3
++ ldr r1, =0x00000007
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set EMRS
++ ldr r1, =0x00000003
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set MRS
++ ldr r1, =0x00000001
++ str r1, [r0]
++
++ ldr r0, =0x1e6e000c @ Refresh 8 times
++ ldr r1, =0x00005C08
++ str r1, [r0]
++
++ ldr r0, =0x1e6e002c @ REG_MRS
++ ldr r1, =0x00000C03 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x00000A03
++#endif
++ orr r1, r1, r2
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set MRS
++ ldr r1, =0x00000001
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0030 @ REG_EMRS
++ ldr r1, =0x000003C0 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x000003C0
++#endif
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set EMRS
++ ldr r1, =0x00000003
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0030 @ REG_EMRS
++ ldr r1, =0x00000040 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x00000040
++#endif
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set EMRS
++ ldr r1, =0x00000003
++ str r1, [r0]
++
++ ldr r0, =0x1e6e000c @ Set refresh cycle
++ ldr r1, =0x00002001
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0014
++ ldr r1, [r0]
++ bic r1, r1, #0xFFF9FFFF
++ mov r2, r1, lsr #3 @ get CL
++
++ ldr r0, =0x1e6e0034 @ REG_PWC
++ ldr r1, =0x00000503 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x00000503
++#endif
++ orr r1, r1, r2
++ str r1, [r0]
++
++ b Calibration_Start
++.LTORG
++/******************************************************************************
++ End DDR2 Init
++ ******************************************************************************/
++/******************************************************************************
++ DDR CK duty finetune program
++ SRAM buffer definition
++ 0x1E720204 : gdll golden DLL1 record
++ 0x1E720208 : gduty golden duty setting record
++ 0x1E72020C : gdutysum golden duty data record
++ 0x1E720210 : duty record of delay 0 invert
++ 0x1E720214 : duty record of delay 1 invert
++ ....
++ 0x1E72024C : duty record of delay 15 invert
++ 0x1E720250 : duty record of delay 0
++ 0x1E720254 : duty record of delay 1
++ ....
++ 0x1E72028C : duty record of delay 15
++
++ Register usage
++ r0 - r3 = free
++ r4 = record the return pc value, do not use
++ r5 = free
++ r6 = free
++ r7 = duty count
++ r8 = gdll
++ r9 = gduty
++ r10 = gdutysum
++ ******************************************************************************/
++CBRDLL1_2400_Start:
++ ldr r0, =0x1e6e0120
++ ldr r1, [r0]
++ orr r1, r1, #0x02
++ str r1, [r0]
++
++ ldr r1, =0x00000000
++ ldr r0, =0x1e720204
++ ldr r2, =0x1e7202a0
++init_sram_start0:
++ str r1, [r0]
++ add r0, r0, #4
++ cmp r0, r2
++ blt init_sram_start0
++
++ ldr r0, =0x1e6e0034
++ mov r1, #0x20
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0060
++ ldr r1, [r0]
++ mov r2, #0x01
++ orr r1, r1, r2, lsl #13
++ str r1, [r0]
++
++ mov r7, #0x0 @ init duty count
++ mov r8, #0x0 @ init gdll
++ mov r9, #0x0 @ init gduty
++ mov r10, #0x0 @ init gdutysum
++cbrdll1_duty_start:
++ cmp r7, #32
++ bge cbrdll1_duty_end
++
++ ldr r0, =0x1e6e0018
++ ldr r1, =0x00008120
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0060
++ ldr r1, [r0]
++ bic r1, r1, #0x00001F00
++ orr r1, r1, r7, lsl #8
++ mov r2, #0x10
++ eor r1, r1, r2, lsl #8
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0000 @ dummy read
++ ldr r1, [r0]
++
++ b CBRDLL1_2300_Start
++CBRDLL1_2400_Call:
++
++ mov r5, #0x01 @ init dqidly count
++ mov r6, #0x00 @ init duty sum
++cbrdll1_duty_cal_start:
++ cmp r5, #0x05
++ bge cbrdll1_duty_cal_end
++
++ ldr r0, =0x1e6e0018
++ ldr r1, =0x00200120
++ orr r1, r1, r5, lsl #16
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0000
++ ldr r1, [r0]
++
++ ldr r0, =0x1e6e0018
++ ldr r1, [r0]
++ mov r2, #0x10
++ orr r1, r1, r2, lsl #24
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0080
++ ldr r1, =0x80000000 @ init duty cal waiting
++cbrdll1_duty_cal_wait:
++ ldr r2, [r0]
++ tst r2, r1
++ beq cbrdll1_duty_cal_wait
++
++ ldr r0, =0x1e6e008c
++ ldr r2, [r0]
++
++ ldr r0, =0x1e720210
++ add r0, r0, r7, lsl #2
++ str r2, [r0]
++
++ ldr r1, =0xFFFF
++ and r3, r1, r2
++ cmp r3, r1
++ moveq r2, r2, lsr #16
++ and r3, r1, r2
++ add r6, r6, r3
++ ldr r1, =0xF000
++ cmp r3, r1
++ blt cbrdll1_duty_cal_end
++ add r5, r5, #0x01
++ b cbrdll1_duty_cal_start
++
++cbrdll1_duty_cal_end:
++ mov r6, r6, lsr #2 @ get dutysum
++ cmp r6, r10 @ check dutysum > gdutysum
++ ble cbrdll1_duty_next
++ ldr r0, =0x1e6e0068
++ ldr r8, [r0]
++ eor r9, r7, #0x10
++ mov r10, r6
++
++cbrdll1_duty_next:
++ add r7, r7, #0x01
++ cmp r7, #16 @ check duty >= 15
++ blt cbrdll1_duty_start
++ ldr r0, =0xFA00 @ check gdutysum > 0xFA00
++ cmp r10, r0
++ blt cbrdll1_duty_start
++
++cbrdll1_duty_end:
++ ldr r0, =0x1e6e0060
++ ldr r1, [r0]
++ bic r1, r1, #0x00001F00
++ orr r1, r1, r9, lsl #8
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0068
++ bic r8, r8, #0xFF000000
++ bic r8, r8, #0x00FF0000
++ str r8, [r0]
++
++ ldr r0, =0x1e720204 @ record result
++ str r8, [r0]
++ add r0, r0, #0x04
++ str r9, [r0]
++ add r0, r0, #0x04
++ str r10, [r0]
++
++ ldr r0, =0x1e6e0018
++ ldr r1, =0x00008120
++ str r1, [r0]
++ ldr r0, =0x1e6e0000 @ dummy read
++ ldr r1, [r0]
++ ldr r0, =0x1e6e0018
++ ldr r1, =0x00000120
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0120
++ ldr r1, [r0]
++ cmp r1, #0x3
++ beq MCLK2X_Phase_CBR_Done_DDR2
++ b MCLK2X_Phase_CBR_Done_DDR3
++
++/******************************************************************************
++ MCLK2X lock to MCLK program
++ r0 - r3 = free
++ r5 = madjmax
++ r6 = dllend
++ 0x1E720200 = 0x96cnt:failcnt:dllmax:dllmin
++ ******************************************************************************/
++CBRDLL1_2300_Start:
++ ldr r0, =0x1e6e0064
++ ldr r5, [r0]
++ and r5, r5, #0xFF @ init madjmax
++ mov r6, r5 @ init dllend
++
++ ldr r1, =0x000000ff
++ ldr r0, =0x1e720200
++ str r1, [r0] @ init dllcnt2:dllmax:dllmin
++
++ mov r3, #0x0 @ init loop count
++cbrdll1_scan_start:
++ cmp r3, r6
++ bge cbrdll1_scan_end
++
++ ldr r0, =0x1e6e0018
++ ldr r1, =0x00008120
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0068
++ mov r1, r3
++ cmp r1, r5
++ subge r1, r1, r5
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0000 @ dummy read
++ ldr r1, [r0]
++
++ ldr r0, =0x1e6e0018
++ ldr r1, =0x00000120
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0000 @ dummy read
++ ldr r1, [r0]
++ ldr r0, =0x1e6e0000 @ dummy read
++ ldr r1, [r0]
++
++ ldr r0, =0x1e6e001c
++ ldr r1, [r0]
++ mov r1, r1, lsr #16
++ and r1, r1, #0xFF
++
++ and r2, r1, #0x96
++ cmp r2, #0x96
++ beq cbrdll1_scan_pass @ if (mclk2x_phase & 0x96) == 0x96
++ ldr r0, =0x1e720200
++ ldr r1, [r0]
++ mov r2, r1, lsr #8
++ ands r2, r2, #0xFF @ get dllmax
++ beq cbrdll1_scan_next @ if dllmax == 0
++ mov r2, r1, lsr #16
++ and r2, r2, #0xFF
++ add r2, r2, #0x01
++ cmp r2, #0x02
++ movge r6, r3
++ bic r1, r1, #0x00FF0000
++ orr r1, r1, r2, lsl #16
++ str r1, [r0]
++ b cbrdll1_scan_next
++
++cbrdll1_scan_pass:
++ cmp r3, #0x0 @ if dll = 0
++ moveq r3, #0x0F
++ addeq r6, r6, #0x10
++ beq cbrdll1_scan_next
++ ldr r0, =0x1e720200
++ ldr r2, [r0]
++ cmp r1, #0x96
++ bne cbrdll1_scan_pass2
++ mov r1, r2, lsr #24
++ add r1, r1, #0x01
++ bic r2, r2, #0xFF000000
++ orr r2, r2, r1, lsl #24
++ cmp r1, #0x03 @ check (phase == 0x96) count == 3
++ bicge r2, r2, #0x0000FF00
++ bicge r2, r2, #0x000000FF
++ orrge r2, r2, r3, lsl #8
++ orrge r2, r2, r3
++ str r2, [r0]
++ bge cbrdll1_scan_end
++
++cbrdll1_scan_pass2:
++ and r1, r2, #0xFF @ if(dllmin > dll)
++ cmp r1, r3
++ bicgt r2, r2, #0x000000FF
++ orrgt r2, r2, r3
++
++ mov r1, r2, lsr #8 @ if(dllmax < dll)
++ and r1, r1, #0xFF
++ cmp r1, r3
++ biclt r2, r2, #0x0000FF00
++ orrlt r2, r2, r3, lsl #8
++
++ bic r2, r2, #0x00FF0000
++ str r2, [r0]
++
++cbrdll1_scan_next:
++ add r3, r3, #0x01
++ b cbrdll1_scan_start
++
++cbrdll1_scan_end:
++ ldr r0, =0x1e720200
++ ldr r1, [r0]
++ mov r2, r1, lsr #8 @ get dllmax
++ ands r2, r2, #0xFF
++ bne cbrdll1_scan_done @ if(dllmax != 0)
++ ldr r0, =0x1e6e0064
++ ldr r3, [r0]
++ bic r1, r3, #0x000C0000
++ str r1, [r0]
++ add r0, r0, #0x04
++ mov r1, #0x0
++ str r1, [r0]
++
++ /* Delay about 10us */
++ ldr r2, =0x0000000A @ Set Timer3 Reload = 10 us
++ init_delay_timer
++delay0_1:
++ check_delay_timer
++ bne delay0_1
++ clear_delay_timer
++ /* end delay 10us */
++
++ ldr r0, =0x1e6e0064
++ str r3, [r0]
++
++ /* Delay about 10us */
++ ldr r2, =0x0000000A @ Set Timer3 Reload = 10 us
++ init_delay_timer
++delay0_2:
++ check_delay_timer
++ bne delay0_2
++ clear_delay_timer
++ /* end delay 10us */
++
++ b CBRDLL1_2300_Start
++
++cbrdll1_scan_done:
++ and r1, r1, #0xFF
++ add r1, r1, r2
++ mov r6, r1, lsr #1 @ dll1.0 = (dllmin + dllmax) >> 1
++ cmp r6, r5
++ subge r6, r6, r5
++ add r3, r6, r5, lsr #2 @ dll1.1 = dll1.0 + (MADJ >> 2)
++
++ ldr r0, =0x1e6e0004
++ ldr r1, [r0]
++ mov r1, r1, lsr #10
++ tst r1, #0x1
++ bne cbrdll1_scan_set_2400
++ cmp r3, r5
++ subge r3, r3, r5
++ mov r2, #0x0
++ tst r3, #0x08
++ beq cbrdll1_scan_set_2300_2 @ if !(dll & 8)
++cbrdll1_scan_set_2300_1: @ if (dll & 8)
++ mov r1, #0x0
++ tst r3, #0x08
++ addeq r1, r1, #0x01
++ cmp r2, #0x05
++ addge r1, r1, #0x01
++ cmp r1, #0x02
++ beq cbrdll1_scan_set
++ add r2, r2, #0x01
++ add r3, r3, #0x01
++ cmp r3, r5
++ subge r3, r3, r5
++ b cbrdll1_scan_set_2300_1
++
++cbrdll1_scan_set_2300_2:
++ and r1, r3, #0x07
++ cmp r1, #0x07
++ beq cbrdll1_scan_set
++ cmp r2, #0x05
++ bge cbrdll1_scan_set
++ add r2, r2, #0x01
++ add r3, r3, #0x01
++ cmp r3, r5
++ subge r3, r3, r5
++ b cbrdll1_scan_set_2300_2
++
++cbrdll1_scan_set_2400:
++ add r3, r3, #0x05 @ dll1.1 = dll1.0 + (MADJ >> 2) + 5
++ cmp r3, r5
++ subge r3, r3, r5
++
++cbrdll1_scan_set:
++ orr r1, r6, r3, lsl #8
++ ldr r0, =0x1e6e0068
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0120
++ ldr r1, [r0]
++ cmp r1, #0x0
++ beq MCLK2X_Phase_CBR_Done_DDR3
++ cmp r1, #0x1
++ beq MCLK2X_Phase_CBR_Done_DDR2
++ b CBRDLL1_2400_Call
++
++.LTORG
++
++/******************************************************************************
++ Calibration Code Start
++ SRAM buffer definition
++ 0x1E720000 : Pass 1, DLLI MIN value range
++ 0x1E720008 : DQS0 DLL valid range, 2nd time CBR
++ 0x1E72000C : DQS1 DLL valid range, 2nd time CBR
++ 0x1E720010 : DQ0 DLL valid range, Pass 1
++ 0x1E720014 : DQ1 DLL valid range, Pass 1
++ ....
++ 0x1E720048 : DQ14 DLL valid range, Pass 1
++ 0x1E72004C : DQ15 DLL valid range, Pass 1
++ 0x1E720090 : DLL1 SAdj record
++ 0x1E720094 : DQL Pass1 finetune result
++ 0x1E720098 : DQH Pass1 finetune result
++ 0x1E72009C : DRAM initial time, (us)
++ 0x1E7200A0 : CBR3 retry counter
++ 0x1E7200A4 : DRAM initial time, (us)
++ 0x1E7200A8 : Released date
++ 0x1E7200AC : Released SDK version
++ 0x1E7200B0 : DQS input mask window for MCR18[4] = 0
++ 0x1E7200B4 : DQS input mask window for MCR18[4] = 1
++ 0x1E720100 : DQIDLY=00, DLL valid range
++ 0x1E720104 : DQIDLY=01, DLL valid range
++ ....
++ 0x1E720178 : DQIDLY=30, DLL valid range
++ 0x1E72017C : DQIDLY=31, DLL valid range
++ 0x1E720180 : DQSI-MCLK2X P-phase pass record DLL2= 0-31
++ 0x1E720184 : DQSI-MCLK2X P-phase pass record DLL2=32-63
++ 0x1E720188 : DQSI-MCLK2X N-phase pass record DLL2= 0-31
++ 0x1E72018C : DQSI-MCLK2X N-phase pass record DLL2=32-63
++ ******************************************************************************/
++Calibration_Start_pre: @ Toggle DQSI mask delay
++ ldr r0, =0x1e6e0018
++ ldr r1, [r0]
++ eor r1, r1, #0x10
++ str r1, [r0]
++
++Calibration_Start:
++/* Init SRAM buffer */
++ ldr r1, =0x000000ff
++ ldr r0, =0x1e720000
++ ldr r2, =0x1e720100
++init_sram_start:
++ str r1, [r0]
++ add r0, r0, #4
++ cmp r0, r2
++ blt init_sram_start
++
++ ldr r1, =0x00ff00ff
++ ldr r0, =0x1e720100
++ ldr r2, =0x1e720180
++init_sram_start2:
++ str r1, [r0]
++ add r0, r0, #4
++ cmp r0, r2
++ blt init_sram_start2
++
++ ldr r1, =0x00000000
++ ldr r0, =0x1e720180
++ ldr r2, =0x1e720200
++init_sram_start3:
++ str r1, [r0]
++ add r0, r0, #4
++ cmp r0, r2
++ blt init_sram_start3
++
++ ldr r0, =0x1e6e0068 @ save the DLL1 SAdj initial value
++ ldr r1, [r0]
++ ldr r0, =0x1e720090
++ str r1, [r0]
++
++/* Start
++ r0 = free
++ r1 = free
++ r2 = free
++ r3 = free
++ r4 = record the return pc value, do not use
++ r5 = pattern table index
++ r6 = pass count
++ r7 = dram DLL2 parameter index (0x1e6e0068), max is 0x4C
++*/
++/******************************************************************************
++ Fine DQI delay and DQSI-MCLK phase
++ r8 = DQIDLY count
++ r9 = DQSI-MCLK2X phase count
++ r10 = pattern fail retry counter, initialize to 2 (fail 2 times)
++ r11 = passcnt accumulator for each DQIDLY
++ *****************************************************************************/
++CBR0_START:
++/* Debug - UART console message */
++ ldr r0, =0x1e784000
++ mov r1, #0x43 @ 'C'
++ str r1, [r0]
++ mov r1, #0x42 @ 'B'
++ str r1, [r0]
++ mov r1, #0x52 @ 'R'
++ str r1, [r0]
++ mov r1, #0x30 @ '0'
++ str r1, [r0]
++ mov r1, #0x2D @ '-'
++ str r1, [r0]
++/* Debug - UART console message */
++
++ ldr r0, =0x1e6e0018
++ ldr r1, [r0]
++ bic r1, r1, #0xFF000000
++ bic r1, r1, #0x00FF0000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0074 @ set the testing DRAM size = 1KB
++ ldr r1, =0x000003FF
++ str r1, [r0]
++
++ mov r8, #0x00 @ init DQIDLY
++ mov r9, #0x00 @ init DQSI-MCLK2X phase
++ mov r11, #0x01 @ init passcnt accumulator
++
++cbr0_next_dqidly:
++ cmp r9, #0x00
++ bne cbr0_next_dqsiphase
++ cmp r11, #0x00
++ addeq r8, r8, #0x01 @ jump 1 stage if no pass at previous stage
++ mov r11, #0x00
++ add r8, r8, #0x01
++ cmp r8, #0x1F @ max DQIDLY = 31
++ bgt CBR0_END
++
++/* Debug - UART console message */
++ ldr r0, =0x1e784000
++ and r1, r8, #0x07
++ add r1, r1, #0x30 @ '0-7'
++ str r1, [r0]
++/* Debug - UART console message */
++
++ ldr r0, =0x1e6e0018
++ ldr r1, [r0]
++ bic r1, r1, #0x00FF0000
++ orr r1, r1, r8, lsl #16
++ str r1, [r0]
++ mov r9, #0x01 @ '1':p_phase, '0':n_phase
++
++ /* Delay about 3us */ @ wait DQIDLY load
++ ldr r2, =0x00000003 @ Set Timer4 Reload = 3 us
++ init_delay_timer
++delay_4:
++ check_delay_timer
++ bne delay_4
++ clear_delay_timer
++ /* end delay 3us */
++
++ b cbr0_dll2_scan_start
++
++cbr0_next_dqsiphase:
++ ldr r0, =0x1e6e0018
++ ldr r1, [r0]
++ orr r1, r1, r9, lsl #23 @ set DQSI-MCLK2X phase
++ str r1, [r0]
++ mov r9, #0x00
++
++cbr0_dll2_scan_start:
++ mov r6, #0x00 @ init pass count
++ mov r7, #0x00 @ init DLL2 parameter index
++
++/****************************
++ DLL2 delay margin test loop
++ ***************************/
++cbr0_next_dll2_parameter:
++ ldr r0, =0x1e6e0068 @ load DLL2 parameter
++ ldr r1, [r0]
++ bic r1, r1, #0x00FF0000
++ bic r1, r1, #0xFF000000
++ orr r1, r1, r7, lsl #16
++ str r1, [r0]
++ ldr r2, =0x40404040 @ DLL2 max is 0x40404040
++ cmp r7, r2
++ bge cbr0_next_dqidly
++ ldr r2, =0x01010101
++ add r7, r7, r2
++
++/* CBRScan3() start */
++ adrl r5, PATTERN_TABLE @ init pattern table index
++/****************************
++ Test pattern iteration loop
++ ***************************/
++cbr0_next_test_pattern:
++ mov r10, #2 @ set the retry loop = 2 of each pattern
++ ldr r1, [r5] @ load test pattern
++ ldr r0, =0x1e6e007c
++ str r1, [r0]
++ cmp r1, #0x00 @ the last data in pattern is 0x00
++ bne cbr0_test_burst
++
++ and r3, r7, #0xFF
++ sub r3, r3, #0x01 @ we add 1 after loop check so we need to decrease 1
++ cmp r3, #0x00
++ beq cbr0_next_dqidly @ pass at dlli = 0, invalid
++ add r6, r6, #0x01 @ increment pass count
++ add r11, r11, #0x01 @ increment pass count
++
++ ldr r0, =0x1e720180 @ record DLL2 pass window
++ cmp r9, #0x00 @ DQSI-MCLK2X phase check
++ addeq r0, r0, #0x08
++ cmp r3, #32
++ addge r0, r0, #0x4
++ and r1, r3, #0x1F
++ mov r2, #0x1
++ mov r2, r2, lsl r1
++ ldr r1, [r0]
++ orr r1, r1, r2
++ str r1, [r0]
++
++ ldr r0, =0x1e720100 @ record DLL2 min:max value for each DQIDLY
++ add r0, r0, r8, lsl #2
++ cmp r9, #0x00 @ DQSI-MCLK2X phase check
++ beq cbr0_test_pass_dqsin
++ record_dll2_pass_range
++ b cbr0_next_dll2_parameter
++
++cbr0_test_pass_dqsin:
++ record_dll2_pass_range_h
++ b cbr0_next_dll2_parameter
++
++cbr0_test_pattern_fail:
++ cmp r6, #5 @ passcnt >= 5
++ bge cbr0_next_dqidly
++ ldr r0, =0x1e720100 @ reset DLL2 min:max value
++ add r0, r0, r8, lsl #2
++ ldr r1, [r0]
++ ldr r2, =0xFFFF0000
++ ldr r3, =0x000000FF
++ cmp r9, #0x00
++ moveq r2, r2, lsr #16
++ moveq r3, r3, lsl #16
++ and r1, r1, r2
++ orr r1, r1, r3
++ str r1, [r0]
++ b cbr0_next_dll2_parameter @ CBRScan3() end and test result fail, go to next step
++
++/****************************
++ Test fail retry loop
++ ***************************/
++cbr0_pattern_fail_retry:
++
++/* CBRTest3() start */
++cbr0_test_burst:
++ ldr r0, =0x1e6e0070
++ ldr r1, =0x00000000
++ str r1, [r0]
++ ldr r1, =0x000000C1
++ str r1, [r0]
++ ldr r3, =0x3000
++cbr0_wait_engine_idle_0:
++ ldr r2, [r0]
++ tst r2, r3 @ D[12] = idle bit
++ beq cbr0_wait_engine_idle_0
++
++ ldr r2, [r0] @ read fail bit status
++ mov r1, #0x0
++ str r1, [r0]
++ mov r2, r2, lsr #13 @ D[13] = fail bit
++ cmp r2, #0x00
++ bne cbr0_test_fail
++
++cbr0_test_single:
++ ldr r0, =0x1e6e0070
++ ldr r1, =0x00000000
++ str r1, [r0]
++ ldr r1, =0x00000085
++ str r1, [r0]
++ ldr r3, =0x3000
++cbr0_wait_engine_idle_1:
++ ldr r2, [r0]
++ tst r2, r3 @ D[12] = idle bit
++ beq cbr0_wait_engine_idle_1
++
++ ldr r2, [r0] @ read fail bit status
++ mov r1, #0x0
++ str r1, [r0]
++ mov r2, r2, lsr #13 @ D[13] = fail bit
++ cmp r2, #0x00
++ beq cbr0_test_pass
++
++/* CBRTest3() end */
++
++cbr0_test_fail:
++ subs r10, r10, #1
++ bne cbr0_pattern_fail_retry
++ b cbr0_test_pattern_fail @ CBRScan3() return(0)
++
++cbr0_test_pass:
++ add r5, r5, #0x04 @ increase the test pattern index
++ b cbr0_next_test_pattern
++
++CBR0_END:
++ mov r5, #0x0 @ init DQIDLY search count
++ mov r6, #0x0 @ init max_margin:g_margin
++ mov r8, #0x0 @ init g_side
++ mov r7, #0x0 @ init maximum margin DQIDLY,DQSI-MCLK2X phase
++cbr0_search_dll_margin_s:
++ ldr r0, =0x1e720100
++ add r0, r0, r5, lsl #2
++ ldr r1, [r0]
++ and r2, r1, #0xFF @ get dllmin_p
++ mov r1, r1, lsr #8
++ and r3, r1, #0xFF @ get dllmax_p
++ subs r2, r3, r2 @ get margin-P
++ movmi r2, #0x0
++ mov r1, r1, lsr #8
++ and r3, r1, #0xFF @ get dllmin_n
++ mov r1, r1, lsr #8
++ and r1, r1, #0xFF @ get dllmax_n
++ subs r3, r1, r3 @ get margin-N
++ movmi r3, #0x0
++ add r1, r2, r3
++ cmp r1, #0x0
++ beq cbr0_search_dll_margin_e @ if margin-P = 0 && margin-N = 0
++
++ ldr r9, [r0]
++ ldr r0, =0x1e720180
++ cmp r2, r3
++ orrlt r5, r5, #0x80 @ margin-N > margin-P
++ addlt r0, r0, #0x08
++ movlt r9, r9, lsr #16
++ movge r3, r2 @ max(margin-P/N)
++ add r2, r3, #0x2 @ define +/- 2 steps of variation
++ mov r1, r6, lsr #16
++ cmp r2, r1
++ blt cbr0_search_dll_margin_e @ if max(margin-P/N) + 2 < max_margin
++
++ and r1, r9, #0xFF @ r1 = dlli counter
++ cmp r1, #32
++ ldrge r2, [r0, #0x4] @ load pass window
++ ldrlt r2, [r0]
++ and r1, r1, #0x1F
++ mov r10, #0x1 @ init test bit mask
++ mov r10, r10, lsl r1
++ and r1, r9, #0xFF
++cbr0_search_dllmin_margin_s:
++ tst r2, r10
++ beq cbr0_search_dllmin_margin_e
++ mov r10, r10, lsr #1
++ cmp r1, #32
++ ldreq r2, [r0]
++ ldreq r10, =0x80000000
++ subs r1, r1, #0x1
++ bne cbr0_search_dllmin_margin_s
++
++cbr0_search_dllmin_margin_e:
++ and r2, r9, #0xFF
++ sub r11, r2, r1 @ get dllmin side margin
++
++ mov r9, r9, lsr #8
++ and r1, r9, #0xFF @ r1 = dlli counter
++ cmp r1, #32
++ ldrge r2, [r0, #0x4] @ load pass window
++ ldrlt r2, [r0]
++ and r1, r1, #0x1F
++ mov r10, #0x1 @ init test bit mask
++ mov r10, r10, lsl r1
++ and r1, r9, #0xFF
++cbr0_search_dllmax_margin_s:
++ tst r2, r10
++ beq cbr0_search_dllmax_margin_e
++ mov r10, r10, lsl #1
++ cmp r1, #31
++ ldreq r2, [r0, #0x4]
++ ldreq r10, =0x00000001
++ add r1, r1, #0x1
++ cmp r1, #64
++ bne cbr0_search_dllmax_margin_s
++
++cbr0_search_dllmax_margin_e:
++ and r2, r9, #0xFF
++ sub r1, r1, r2 @ get dllmax side margin
++ cmp r1, r11
++ movlt r11, r1 @ get side_margin
++
++cbr0_check_dll_margin: @ if max(margin-P/N) > g_margin && side_margin >= g_side && dqidly <= 20
++ cmp r5, #20
++ bgt cbr0_check_dll_margin2
++ and r1, r6, #0xFF
++ cmp r3, r1
++ ble cbr0_check_dll_margin3
++ cmp r11, r8
++ bge cbr0_set_dll_margin
++
++cbr0_check_dll_margin2: @ if max(margin-P/N) > g_margin+1 && side_margin >= g_side)
++ and r1, r6, #0xFF
++ add r2, r1, #0x1
++ cmp r3, r2
++ ble cbr0_check_dll_margin3
++ cmp r11, r8
++ bge cbr0_set_dll_margin
++
++cbr0_check_dll_margin3: @ if side_margin > g_side && g_side < 8
++ cmp r8, #8
++ bge cbr0_search_dll_margin_e
++ cmp r11, r8
++ ble cbr0_search_dll_margin_e
++
++cbr0_set_dll_margin:
++ mov r1, r6, lsr #16
++ cmp r3, r1
++ bicgt r6, r6, #0x00FF0000
++ orrgt r6, r6, r3, lsl #16
++ bic r6, r6, #0x000000FF
++ orr r6, r6, r3
++ mov r7, r5
++ mov r8, r11
++
++cbr0_search_dll_margin_e:
++ and r5, r5, #0x7F
++ add r5, r5, #0x01
++ cmp r5, #0x20 @ last DQIDLY
++ blt cbr0_search_dll_margin_s
++
++ ldr r0, =0x1e6e0018
++ ldr r1, [r0]
++ bic r1, r1, #0x00FF0000
++ orr r1, r1, r7, lsl #16
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0068
++ ldr r1, [r0]
++ bic r1, r1, #0x00FF0000
++ bic r1, r1, #0xFF000000
++ str r1, [r0]
++
++ /* Delay about 5us */
++ ldr r2, =0x00000005 @ Set Timer5 Reload = 5 us
++ init_delay_timer
++delay_5:
++ check_delay_timer
++ bne delay_5
++ clear_delay_timer
++ /* end delay 5us */
++
++ ldr r0, =0x1e6e000c @ Set refresh cycle
++ ldr r1, =0x00005C01
++ str r1, [r0]
++
++/******************************************************************************
++ Fine tune per bit DQ input delay -- Pass 1, left edge align
++ r8 = free
++ r9 = DQ fail bit accumulator
++ r10 = pattern fail counter, initialize to 5 (fail 5 times)
++ r11 = free
++ *****************************************************************************/
++CBR1_START:
++/* Debug - UART console message */
++ ldr r0, =0x1e784000
++ mov r1, #0x0D @ '\r'
++ str r1, [r0]
++ mov r1, #0x0A @ '\n'
++ str r1, [r0]
++ mov r1, #0x43 @ 'C'
++ str r1, [r0]
++ mov r1, #0x42 @ 'B'
++ str r1, [r0]
++ mov r1, #0x52 @ 'R'
++ str r1, [r0]
++ mov r1, #0x31 @ '1'
++ str r1, [r0]
++/* Debug - UART console message */
++
++ mov r6, #0x00 @ init pass count
++ mov r7, #0x00 @ init DLL2 parameter index
++
++/****************************
++ DLL2 delay margin test loop
++ ***************************/
++cbr1_next_dll2_parameter:
++ ldr r0, =0x1e6e0068 @ load DLL2 parameter
++ ldr r1, [r0]
++ bic r1, r1, #0x00FF0000
++ bic r1, r1, #0xFF000000
++ orr r1, r1, r7, lsl #16
++ str r1, [r0]
++ ldr r2, =0x40404040 @ parameter's max is to 0x40404040
++ cmp r7, r2
++ bge CBR1_END
++ ldr r2, =0x01010101
++ add r7, r7, r2
++
++ ldr r0, =0x1e6e0074 @ set the testing DRAM size = 4KB
++ ldr r1, =0x00000FFF
++ str r1, [r0]
++
++/* CBRScan2() start */
++ ldr r9, =0xFFFF @ init test status
++ adrl r5, PATTERN_TABLE @ init pattern table index
++/****************************
++ Test pattern iteration loop
++ ***************************/
++cbr1_next_test_pattern:
++ mov r10, #5 @ set the retry loop of each pattern
++ ldr r1, [r5] @ load test pattern
++ ldr r0, =0x1e6e007c
++ str r1, [r0]
++ cmp r1, #0x00 @ the last data in pattern is 0x00
++ bne cbr1_test_single
++
++cbr1_test_pattern_end:
++ cmp r9, #0x00
++ bne cbr1_test_pass_dqi
++ cmp r6, #10
++ bge CBR1_END
++ b cbr1_next_dll2_parameter @ CBRScan2() end and test result fail, go to next step
++
++cbr1_test_pass_dqi:
++ and r3, r7, #0xFF
++ sub r3, r3, #0x01 @ we add 1 after loop check so we need to decrease 1
++ add r6, r6, #0x01 @ increment pass count
++ ldr r0, =0x1e720010
++ mov r8, #0x01
++cbr1_test_pass_dqi_loop_s:
++ tst r9, r8
++ beq cbr1_test_pass_dqi_loop_e
++ record_dll2_pass_range
++
++cbr1_test_pass_dqi_loop_e:
++ add r0, r0, #0x04
++ mov r8, r8, lsl #1
++ ldr r1, =0xFFFF
++ tst r8, r1
++ bne cbr1_test_pass_dqi_loop_s
++ b cbr1_next_dll2_parameter
++
++/****************************
++ Test fail retry loop
++ ***************************/
++cbr1_pattern_fail_retry:
++
++/* CBRTest2() start */
++cbr1_test_single:
++ ldr r0, =0x1e6e0070
++ ldr r1, =0x00000000
++ str r1, [r0]
++ ldr r1, =0x00000005
++ str r1, [r0]
++ ldr r3, =0x1000
++ ldr r1, =0x1000
++cbr1_wait_engine_idle_0:
++ subs r1, r1, #1
++ beq cbr1_test_single_end
++ ldr r2, [r0]
++ tst r2, r3 @ D[12] = idle bit
++ beq cbr1_wait_engine_idle_0
++
++cbr1_test_single_end:
++ ldr r0, =0x1e6e0078 @ read fail bit status
++ ldr r11, [r0]
++ orr r11, r11, r11, lsr #16
++ bic r11, r11, #0xFF000000
++ bic r11, r11, #0x00FF0000
++
++ ldr r1, =0xFFFF
++ cmp r11, r1
++ beq cbr1_test_fail
++
++cbr1_test_burst:
++ ldr r0, =0x1e6e0070
++ ldr r2, =0x00000000
++ str r2, [r0]
++ ldr r2, =0x00000041
++ str r2, [r0]
++ ldr r3, =0x1000
++ ldr r1, =0x1000
++cbr1_wait_engine_idle_1:
++ subs r1, r1, #1
++ beq cbr1_test_burst_end
++ ldr r2, [r0]
++ tst r2, r3 @ D[12] = idle bit
++ beq cbr1_wait_engine_idle_1
++
++cbr1_test_burst_end:
++ ldr r0, =0x1e6e0078 @ read fail bit status
++ ldr r2, [r0]
++ orr r2, r2, r2, lsr #16
++ bic r2, r2, #0xFF000000
++ bic r2, r2, #0x00FF0000
++ orr r11, r11, r2
++
++ ldr r2, =0xFFFF
++ cmp r11, r2
++ bne cbr1_test_pass
++/* CBRTest2() end */
++
++cbr1_test_fail:
++ subs r10, r10, #1
++ bne cbr1_pattern_fail_retry
++ mov r9, #0x00
++ b cbr1_test_pattern_end @ CBRScan2() return(0)
++
++cbr1_test_pass:
++ ldr r1, =0xFFFF @ record the pass bit
++ eor r11, r11, r1
++ and r9, r9, r11 @ DQ pass bit
++ cmp r9, #0x00
++ beq cbr1_test_pattern_end @ CBRScan2() return(0)
++
++ add r5, r5, #0x04 @ increase the test pattern index
++ b cbr1_next_test_pattern
++
++CBR1_END:
++ mov r5, #0x0 @ init DQ DLL_min sum
++ mov r6, #0x0 @ init DQ DLL_min valid count
++ ldr r0, =0x1e72000c
++ ldr r3, =0x1e720050
++cbr1_search_dllmin_s:
++ add r0, r0, #0x04
++ cmp r0, r3
++ beq cbr1_search_dllmin_e
++ ldr r1, [r0]
++ mov r2, r1, lsr #8
++ and r2, r2, #0xFF @ get dllmax
++ and r1, r1, #0xFF @ get dllmin
++ subs r2, r2, r1 @ dllmax - dllmin
++ bmi cbr1_search_dllmin_s @ no valid margin found, bypass fine tune
++ cmp r2, #10 @ (dllmax - dllmin) < 10
++ blt cbr1_search_dllmin_s @ no enough margin found, bypass fine tune
++ add r5, r5, r1
++ add r6, r6, #1
++ b cbr1_search_dllmin_s
++
++cbr1_search_dllmin_e:
++ cmp r6, #16
++ bne Calibration_Start_pre @ not all bits valid, retry again
++
++ mov r5, r5, lsr #4
++ ldr r0, =0x1e720000
++ str r5, [r0]
++
++ mov r6, #0x00 @ init DQL CBR value
++ ldr r0, =0x1e720030
++ ldr r7, =0x1e72000c
++cbr1_set_result_dql:
++ sub r0, r0, #4
++ cmp r0, r7
++ beq cbr1_set_result_next
++ mov r6, r6, lsl #3
++ ldr r1, [r0]
++ mov r2, r1, lsr #8
++ and r2, r2, #0xFF @ get dllmax
++ and r1, r1, #0xFF @ get dllmin
++ mov r3, r1 @ dll = dllmin
++ cmp r5, r3
++ blt cbr1_set_result_dql_neg
++ sub r1, r5, r3
++ mov r2, #19
++ mul r1, r2, r1
++ mov r1, r1, lsr #5 @ dqi_tune = ((gold_dll - dll) * 19) >> 5
++ cmp r1, #2 @ dqi_tune max = 2
++ movgt r1, #2
++ orr r6, r6, r1
++ b cbr1_set_result_dql
++
++cbr1_set_result_dql_neg:
++ sub r1, r3, r5
++ mov r2, #19
++ mul r1, r2, r1
++ mov r1, r1, lsr #5 @ dqi_tune = ((gold_dll - dll) * 19) >> 5
++ cmp r1, #2 @ dqi_tune max = -2
++ movgt r1, #2
++ mov r2, #8
++ sub r1, r2, r1
++ and r1, r1, #7
++ orr r6, r6, r1
++ b cbr1_set_result_dql
++
++cbr1_set_result_next:
++ ldr r0, =0x1e6e0080 @ save DQL fine tune result
++ str r6, [r0]
++ ldr r0, =0x1e720094
++ str r6, [r0]
++
++ mov r6, #0x00 @ init DQH CBR value
++ ldr r0, =0x1e720050
++ ldr r7, =0x1e72002c
++cbr1_set_result_dqh:
++ sub r0, r0, #4
++ cmp r0, r7
++ beq cbr1_set_result_end
++ mov r6, r6, lsl #3
++ ldr r1, [r0]
++ mov r2, r1, lsr #8
++ and r2, r2, #0xFF @ get dllmax
++ and r1, r1, #0xFF @ get dllmin
++ mov r3, r1 @ dll = dllmin
++ cmp r5, r3
++ blt cbr1_set_result_dqh_neg
++ sub r1, r5, r3
++ mov r2, #19
++ mul r1, r2, r1
++ mov r1, r1, lsr #5 @ dqi_tune = ((gold_dll - dll) * 19) >> 5
++ cmp r1, #3 @ dqi_tune max = 2
++ movgt r1, #3
++ subs r1, r1, #1
++ movmi r1, #7
++ orr r6, r6, r1
++ b cbr1_set_result_dqh
++
++cbr1_set_result_dqh_neg:
++ sub r1, r3, r5
++ mov r2, #19
++ mul r1, r2, r1
++ mov r1, r1, lsr #5 @ dqi_tune = ((gold_dll - dll) * 19) >> 5
++ add r1, r1, #1
++ cmp r1, #2 @ dqi_tune max = -2
++ movgt r1, #2
++ mov r2, #8
++ sub r1, r2, r1
++ and r1, r1, #7
++ orr r6, r6, r1
++ b cbr1_set_result_dqh
++
++cbr1_set_result_end:
++ ldr r0, =0x1e6e0084 @ save DQH fine tune result
++ str r6, [r0]
++ ldr r0, =0x1e720098
++ str r6, [r0]
++
++/******************************************************************************
++ Search the DLL2 detail margin
++ *****************************************************************************/
++ ldr r0, =0x1e7200a0
++ mov r1, #0
++ str r1, [r0]
++
++CBR3_START:
++/* Debug - UART console message */
++ ldr r0, =0x1e784000
++ mov r1, #0x33 @ '3'
++ str r1, [r0]
++/* Debug - UART console message */
++
++ mov r6, #0x00 @ init pass count
++ mov r7, #0x00 @ init DLL2 parameter index
++ ldr r1, =0x000000ff
++ ldr r0, =0x1e720008 @ init DQL dllmax,dllmin
++ str r1, [r0]
++ ldr r0, =0x1e72000c @ init DQH dllmax,dllmin
++ str r1, [r0]
++
++ ldr r0, =0x1e7200a0 @ CBR3 iteration counter
++ ldr r1, [r0]
++ add r1, r1, #1
++ str r1, [r0]
++
++/****************************
++ DLL2 delay margin test loop
++ ***************************/
++cbr3_next_dll2_parameter:
++ ldr r0, =0x1e6e0068 @ load DLL2 parameter
++ ldr r1, [r0]
++ bic r1, r1, #0x00FF0000
++ bic r1, r1, #0xFF000000
++ orr r1, r1, r7, lsl #16
++ str r1, [r0]
++ ldr r2, =0x40404040 @ parameter's max is to 0x40404040
++ cmp r7, r2
++ bge CBR3_END
++ ldr r2, =0x01010101
++ add r7, r7, r2
++
++ ldr r0, =0x1e6e0074 @ set the testing DRAM size = 64KB
++ ldr r1, =0x0000FFFF
++ str r1, [r0]
++
++/* CBRScan() start */
++ mov r9, #0x03 @ init test status
++ adrl r5, PATTERN_TABLE @ init pattern table index
++/****************************
++ Test pattern iteration loop
++ ***************************/
++cbr3_next_test_pattern:
++ mov r10, #5 @ set the retry loop of each pattern
++ ldr r1, [r5] @ load test pattern
++ ldr r0, =0x1e6e007c
++ str r1, [r0]
++ cmp r1, #0x00 @ the last data in pattern is 0x00
++ bne cbr3_test_single
++
++cbr3_test_pattern_end:
++ cmp r9, #0x00
++ bne cbr3_test_pass_dql
++ cmp r6, #10
++ bge CBR3_END
++ b cbr3_next_dll2_parameter @ CBRScan() end and test result fail, go to next step
++
++cbr3_test_pass_dql:
++ and r3, r7, #0xFF
++ sub r3, r3, #0x01 @ we add one after loop check so we need to decrease 1
++ add r6, r6, #0x01 @ increment pass count
++ tst r9, #0x01
++ beq cbr3_test_pass_dqh
++
++ ldr r0, =0x1E720008
++ record_dll2_pass_range
++
++cbr3_test_pass_dqh:
++ tst r9, #0x02
++ beq cbr3_next_dll2_parameter
++ ldr r0, =0x1E72000c
++ record_dll2_pass_range
++ b cbr3_next_dll2_parameter
++
++/****************************
++ Test fail retry loop
++ ***************************/
++cbr3_pattern_fail_retry:
++
++/* CBRTest() start */
++cbr3_test_single:
++ ldr r0, =0x1e6e0070
++ ldr r1, =0x00000000
++ str r1, [r0]
++ ldr r1, =0x00000005
++ str r1, [r0]
++ ldr r3, =0x1000
++ ldr r8, =0x10000
++cbr3_wait_engine_idle_0:
++ subs r8, r8, #1
++ beq cbr3_test_single_end
++ ldr r2, [r0]
++ tst r2, r3 @ D[12] = idle bit
++ beq cbr3_wait_engine_idle_0
++
++cbr3_test_single_end:
++ ldr r0, =0x1e6e0078 @ read fail bit status
++ ldr r11, [r0]
++ orr r11, r11, r11, lsr #16
++ bic r11, r11, #0xFF000000
++ bic r11, r11, #0x00FF0000
++
++ ldr r1, =0xFF
++ tst r11, r1
++ beq cbr3_test_burst
++ tst r11, r1, lsl #8
++ bne cbr3_test_fail
++
++cbr3_test_burst:
++ mov r1, #0x00 @ initialize loop index, r1 is loop's index
++cbr3_test_burst_loop:
++ ldr r0, =0x1e6e0070
++ ldr r2, =0x00000000
++ str r2, [r0]
++ mov r2, r1, lsl #3
++ orr r2, r2, #0x41 @ test command = 0x41 | (datagen << 3)
++ str r2, [r0]
++ ldr r3, =0x1000
++ ldr r8, =0x10000
++cbr3_wait_engine_idle_1:
++ subs r8, r8, #1
++ beq cbr3_test_burst_end
++ ldr r2, [r0]
++ tst r2, r3 @ D[12] = idle bit
++ beq cbr3_wait_engine_idle_1
++
++cbr3_test_burst_end:
++ ldr r0, =0x1e6e0078 @ read fail bit status
++ ldr r2, [r0]
++ orr r2, r2, r2, lsr #16
++ bic r2, r2, #0xFF000000
++ bic r2, r2, #0x00FF0000
++ orr r11, r11, r2
++
++ ldr r2, =0xFF
++ tst r11, r2
++ beq cbr3_next_test_burst_mode
++ tst r11, r2, lsl #8
++ beq cbr3_next_test_burst_mode
++/* CBRTest() end */
++
++cbr3_test_fail:
++ subs r10, r10, #1
++ bne cbr3_pattern_fail_retry
++ mov r9, #0x00
++ b cbr3_test_pattern_end @ CBRScan() return(0)
++
++cbr3_next_test_burst_mode:
++ add r1, r1, #1 @ increase the test mode index
++ cmp r1, #0x08 @ there are 8 modes
++ bne cbr3_test_burst_loop
++
++ ldr r1, =0xFF @ record the pass byte
++ tst r11, r1
++ andne r9, r9, #0x02 @ DQL fail
++ tst r11, r1, lsl #8
++ andne r9, r9, #0x01 @ DQH fail
++ cmp r9, #0x00
++ beq cbr3_test_pattern_end @ CBRScan() return(0)
++
++ add r5, r5, #0x04 @ increase the test pattern index
++ b cbr3_next_test_pattern
++
++CBR3_END:
++ ldr r0, =0x1e72000c @ check DQH margin
++ ldr r1, [r0]
++ mov r2, r1, lsr #8
++ and r2, r2, #0xFF @ get dllmax
++ and r1, r1, #0xFF @ get dllmin
++ subs r5, r2, r1 @ dllmax - dllmin
++ bmi CBR3_START @ no valid margin found, retry again
++ cmp r5, #10 @ (dllmax - dllmin) < 10
++ blt CBR3_START @ no enough margin found, retry again
++ add r2, r1, r2 @ (dllmin[1] + dllmax[1] + 1) >> 1
++ add r2, r2, #0x01
++ mov r1, r2, lsr #1
++ mov r3, r1, lsl #8
++ ldr r1, [r0] @ store the dll search result
++ bic r1, r1, #0xFF000000
++ bic r1, r1, #0x00FF0000
++ orr r1, r1, r3, lsl #8
++ str r1, [r0]
++
++ ldr r0, =0x1e720008 @ check DQL margin
++ ldr r1, [r0]
++ mov r2, r1, lsr #8
++ and r2, r2, #0xFF @ get dllmax
++ and r1, r1, #0xFF @ get dllmin
++ subs r5, r2, r1 @ dllmax - dllmin
++ bmi CBR3_START @ no valid margin found, retry again
++ cmp r5, #10 @ (dllmax - dllmin) < 10
++ blt CBR3_START @ no enough margin found, retry again
++ add r2, r1, r2 @ (dllmin[0] + dllmax[0] + 1) >> 1
++ add r2, r2, #0x01
++ mov r1, r2, lsr #1
++ ldr r2, [r0] @ store the dll search result
++ bic r2, r2, #0xFF000000
++ bic r2, r2, #0x00FF0000
++ orr r2, r2, r1, lsl #16
++ str r2, [r0]
++ orr r3, r3, r1
++
++ ldr r0, =0x1e6e0068 @ save the result dll value
++ ldr r1, [r0]
++ bic r1, r1, #0xFF000000
++ bic r1, r1, #0x00FF0000
++ orr r1, r1, r3, lsl #16
++ str r1, [r0]
++ b CBR4_START
++
++.LTORG
++
++/******************************************************************************
++ Search the DQS input mask margin
++ *****************************************************************************/
++CBR4_START:
++/* Debug - UART console message */
++ ldr r0, =0x1e784000
++ mov r1, #0x34 @ '4'
++ str r1, [r0]
++/* Debug - UART console message */
++
++ ldr r0, =0x1e6e0074 @ set the testing DRAM size = 4KB
++ ldr r1, =0x00000FFF
++ str r1, [r0]
++
++ mov r8, #0x00 @ init MCR18[4]
++ ldr r1, =0x000000ff
++ ldr r0, =0x1e7200b0 @ init MCR18[4]=0 max,min
++ str r1, [r0]
++ ldr r0, =0x1e7200b4 @ init MCR18[4]=1 max,min
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0018
++ ldr r1, [r0]
++ bic r1, r1, #0x0000001F
++ str r1, [r0]
++
++ b cbr4_scan_start
++
++cbr4_next_maskdly:
++ add r8, r8, #0x01
++ and r2, r8, #0x01
++ ldr r0, =0x1e6e0018
++ ldr r1, [r0]
++ bic r1, r1, #0x0000001F
++ orr r1, r1, r2, lsl #4
++ str r1, [r0]
++ cmp r8, #0x02
++ bge CBR4_END
++
++cbr4_scan_start:
++ mov r6, #0x00 @ init pass count
++ mov r7, #0x00 @ init mask delay
++
++/****************************
++ DQS Mask delay margin test loop
++ ***************************/
++cbr4_next_parameter:
++ cmp r7, #0x10 @ max delay = 0xF
++ bge cbr4_next_maskdly
++ ldr r0, =0x1e6e0018 @ load MCR18 parameter
++ ldr r1, [r0]
++ bic r1, r1, #0x0000000F
++ orr r1, r1, r7
++ str r1, [r0]
++ add r7, r7, #0x01
++
++/* CBRScan3() start */
++ adrl r5, PATTERN_TABLE @ init pattern table index
++/****************************
++ Test pattern iteration loop
++ ***************************/
++cbr4_next_test_pattern:
++ mov r10, #2 @ set the retry loop = 2 of each pattern
++ ldr r1, [r5] @ load test pattern
++ ldr r0, =0x1e6e007c
++ str r1, [r0]
++ cmp r1, #0x00 @ the last data in pattern is 0x00
++ bne cbr4_test_burst
++
++ and r3, r7, #0xFF
++ sub r3, r3, #0x01 @ we add 1 after loop check so we need to decrease 1
++ add r6, r6, #0x01 @ increment pass count
++
++ ldr r0, =0x1e7200b0 @ record pass window
++ add r0, r0, r8, lsl #2
++ record_dll2_pass_range
++ mov r2, #0x01
++ add r1, r1, r2, lsl #16
++ str r1, [r0]
++ b cbr4_next_parameter
++
++cbr4_test_pattern_fail:
++ cmp r6, #5 @ passcnt >= 5
++ bge cbr4_next_maskdly
++ b cbr4_next_parameter
++
++/****************************
++ Test fail retry loop
++ ***************************/
++cbr4_pattern_fail_retry:
++
++/* CBRTest3() start */
++cbr4_test_burst:
++ ldr r0, =0x1e6e0070
++ ldr r1, =0x00000000
++ str r1, [r0]
++ ldr r1, =0x000000C1
++ str r1, [r0]
++ ldr r3, =0x3000
++cbr4_wait_engine_idle_0:
++ ldr r2, [r0]
++ tst r2, r3 @ D[12] = idle bit
++ beq cbr4_wait_engine_idle_0
++
++ ldr r2, [r0] @ read fail bit status
++ mov r1, #0x0
++ str r1, [r0]
++ mov r2, r2, lsr #13 @ D[13] = fail bit
++ cmp r2, #0x00
++ bne cbr4_test_fail
++
++cbr4_test_single:
++ ldr r0, =0x1e6e0070
++ ldr r1, =0x00000000
++ str r1, [r0]
++ ldr r1, =0x00000085
++ str r1, [r0]
++ ldr r3, =0x3000
++cbr4_wait_engine_idle_1:
++ ldr r2, [r0]
++ tst r2, r3 @ D[12] = idle bit
++ beq cbr4_wait_engine_idle_1
++
++ ldr r2, [r0] @ read fail bit status
++ mov r1, #0x0
++ str r1, [r0]
++ mov r2, r2, lsr #13 @ D[13] = fail bit
++ cmp r2, #0x00
++ beq cbr4_test_pass
++
++/* CBRTest3() end */
++
++cbr4_test_fail:
++ subs r10, r10, #1
++ bne cbr4_pattern_fail_retry
++ b cbr4_test_pattern_fail @ CBRScan3() return(0)
++
++cbr4_test_pass:
++ add r5, r5, #0x04 @ increase the test pattern index
++ b cbr4_next_test_pattern
++
++CBR4_END:
++ ldr r0, =0x1e7200b0 @ check mask margin
++ ldr r1, [r0]
++ add r0, r0, #0x04
++ ldr r2, [r0]
++ ands r6, r2, #0xFF @ get min of MCR18[4] = 1
++ bne cbr4_noset_delay
++ ands r5, r1, #0xFF @ get min of MCR18[4] = 0
++ bne cbr4_set_delay
++ mov r1, r1, lsr #8 @ get max of MCR18[4] = 0
++ and r1, r1, #0xFF
++ mov r2, r2, lsr #8 @ get max of MCR18[4] = 1
++ and r2, r2, #0xFF
++ sub r1, r1, r5
++ sub r2, r2, r6
++ cmp r1, r2
++ bge cbr4_noset_delay
++
++cbr4_set_delay:
++ ldr r0, =0x1e6e0018
++ ldr r1, [r0]
++ orr r1, r1, #0x10
++ str r1, [r0]
++
++cbr4_noset_delay:
++ ldr r0, =0x1e6e0070
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++/******************************************************************************
++ CBR Finish
++ *****************************************************************************/
++/******************************************************************************
++ Check DRAM Size
++ *****************************************************************************/
++ ldr r0, =0x1e6e2070
++ ldr r1, [r0]
++ bic r1, r1, #0xFEFFFFFF @ bit[24]=1 => DDR2
++ mov r2, r1, lsr #24
++ cmp r2, #0x01
++ beq check_ddr2_size
++
++ ldr r0, =0x1e6e0004
++ ldr r5, [r0]
++ bic r5, r5, #0x00000003 @ record MCR04
++ orr r1, r5, #0x3
++ str r1, [r0] @ set to 4Gbit
++ ldr r6, =0x003F2217
++#if defined(CONFIG_DRAM_336)
++ ldr r6, =0x00361C13
++#endif
++ b check_dram_size
++
++check_ddr2_size:
++ ldr r0, =0x1e6e0004
++ ldr r5, [r0]
++ bic r5, r5, #0x00000023 @ record MCR04
++ orr r1, r5, #0x23
++ str r1, [r0] @ set to 4Gbit
++ ldr r6, =0x3F2B1B16
++#if defined(CONFIG_DRAM_336)
++ ldr r6, =0x3B231612
++#endif
++
++ ldr r0, =0x40000000
++ ldr r1, =0x1817191A
++ str r1, [r0]
++ ldr r0, =0x40002000
++ ldr r1, =0x73616532
++ str r1, [r0]
++ ldr r0, =0x40000000
++ ldr r1, =0x1817191A
++ ldr r2, [r0]
++ cmp r1, r2
++ bne check_dram_size_end @ == 512Mbit
++ orr r5, r5, #0x20 @ >= 1Gbit
++ mov r6, r6, lsr #8
++
++check_dram_size:
++ ldr r0, =0x50100000
++ ldr r1, =0x41424344
++ str r1, [r0]
++ ldr r0, =0x48100000
++ ldr r1, =0x25262728
++ str r1, [r0]
++ ldr r0, =0x40100000
++ ldr r1, =0x191A1B1C
++ str r1, [r0]
++ ldr r0, =0x50100000
++ ldr r1, =0x41424344
++ ldr r2, [r0]
++ cmp r2, r1 @ == 4Gbit
++ orreq r5, r5, #0x03
++ moveq r6, r6, lsr #16
++ beq check_dram_size_end
++ ldr r0, =0x48100000
++ ldr r1, =0x25262728
++ ldr r2, [r0]
++ cmp r2, r1 @ == 2Gbit
++ orreq r5, r5, #0x02
++ moveq r6, r6, lsr #8
++ beq check_dram_size_end
++ orr r5, r5, #0x01 @ == 1Gbit
++
++check_dram_size_end:
++ ldr r0, =0x1e6e0004
++ str r5, [r0]
++ ldr r0, =0x1e6e0014
++ ldr r1, [r0]
++ bic r1, r1, #0x000000FF
++ and r6, r6, #0xFF
++ orr r1, r1, r6
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0120 @ VGA Compatible Mode
++ ldr r1, =0x000050C0 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x00004DC0
++#endif
++ str r1, [r0]
++
++/******************************************************************************
++ Version Number
++ *****************************************************************************/
++ ldr r0, =0x1e7200a8
++ ldr r1, =0x20141229 @ released date
++ str r1, [r0]
++
++ add r0, r0, #4
++ ldr r1, =0x00000060 @ released SDK version
++ str r1, [r0]
++
++/******************************************************************************
++ Calibration Code End
++ ******************************************************************************/
++
++set_scratch:
++ /*Set Scratch register Bit 6 after ddr initial finished */
++ ldr r0, =0x1e6e2040
++ ldr r1, [r0]
++ orr r1, r1, #0x40
++ str r1, [r0]
++
++/* Debug - UART console message */
++ ldr r0, =0x1e784000
++ mov r1, #0x44 @ 'D'
++ str r1, [r0]
++ mov r1, #0x6F @ 'o'
++ str r1, [r0]
++ mov r1, #0x6E @ 'n'
++ str r1, [r0]
++ mov r1, #0x65 @ 'e'
++ str r1, [r0]
++ mov r1, #0x0D @ '\r'
++ str r1, [r0]
++ mov r1, #0x0A @ '\n'
++ str r1, [r0]
++/* Debug - UART console message */
++
++/******************************************************************************
++ Solve PCIe ASPM issue, only applied to AST2300 series
++ ******************************************************************************/
++ ldr r0, =0x1e6e207c @ Check bounding for AST1150 existence
++ ldr r1, [r0]
++ mov r2, r1, lsr #24
++ cmp r2, #0x01
++ bne platform_exit @ not match AST2300
++ bic r1, r1, #0xFFFFFCFF
++ mov r1, r1, lsr #8
++ cmp r1, #0x02
++ beq platform_exit @ match AST1050
++
++ ldr r0, =0x1e6e2004 @ Disable I2C controller reset
++ ldr r1, [r0]
++ orr r1, r1, #0x04
++ str r1, [r0]
++ bic r1, r1, #0x04
++ str r1, [r0]
++
++ ldr r0, =0x1e78a054 @ Check I2C bus state, if busy then quit
++ ldr r1, [r0]
++ mov r1, r1, lsr #17
++ and r1, r1, #0x03
++ cmp r1, #0x03
++ bne platform_exit
++
++ ldr r0, =0x1e78a040 @ Init I2C1 controller
++ mov r1, #0x01
++ orr r1, r1, r1, lsl #16
++ str r1, [r0]
++
++ ldr r0, =0x1e78a044
++ ldr r1, =0x77776704
++ str r1, [r0]
++
++ mov r1, #0x0
++ ldr r0, =0x1e78a048
++ str r1, [r0]
++ ldr r0, =0x1e78a04c
++ str r1, [r0]
++
++ ldr r0, =0x1e78a050
++ ldr r1, =0xFFFFFFFF
++ str r1, [r0]
++
++ ldr r0, =0x1e78a200 @ Set AST1150 I2C password
++ ldr r1, =0x00A88FA8
++ str r1, [r0]
++
++ ldr r0, =0x1e78a05c
++ ldr r1, =0x00000200 @ Enable buffer mode transfering 3 bytes
++ str r1, [r0]
++
++ ldr r0, =0x1e78a054
++ ldr r1, =0x00000063 @ Fire commmand
++ str r1, [r0]
++
++ ldr r0, =0x1e78a050
++i2c_wait_cmddone_1:
++ ldr r1, [r0]
++ tst r1, #0x38
++ beq i2c_wait_cmddone_1
++ tst r1, #0x2A @ transmit error
++ bne platform_exit2
++ ldr r1, =0xFFFFFFFF
++ str r1, [r0]
++
++ ldr r0, =0x1e78a200 @ Disable ASPM capability
++ ldr r1, =0x04005DA8
++ str r1, [r0]
++
++ ldr r0, =0x1e78a204
++ ldr r1, =0x00000024
++ str r1, [r0]
++
++ ldr r0, =0x1e78a05c
++ ldr r1, =0x00000200 @ Enable buffer mode transfering 3 bytes
++ str r1, [r0]
++
++ ldr r0, =0x1e78a054
++ ldr r1, =0x00000063 @ Fire commmand
++ str r1, [r0]
++
++ ldr r0, =0x1e78a050
++i2c_wait_cmddone_2:
++ ldr r1, [r0]
++ tst r1, #0x38
++ beq i2c_wait_cmddone_2
++ tst r1, #0x2A @ transmit error
++ bne platform_exit2
++ ldr r1, =0xFFFFFFFF
++ str r1, [r0]
++
++platform_exit2:
++ ldr r0, =0x1e78a040 @ Disable I2C1 controller
++ mov r1, #0x00
++ str r1, [r0]
++
++ b platform_exit
++.LTORG
++
++platform_exit:
++#ifdef CONFIG_DRAM_ECC
++ ldr r0, =0x1e6e0004
++ ldr r1, [r0]
++ orr r1, r1, #0x80
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0054
++ ldr r1, =0x05000000 /* ECC protected memory size, default set at 80M */
++ str r1, [r0]
++
++ ldr r0, =0x1e6e007C
++ ldr r1, =0x00000000
++ str r1, [r0]
++ ldr r0, =0x1e6e0074
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0070
++ ldr r1, =0x00000221
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0070
++ ldr r2, =0x00001000
++ECC_Init_Flag:
++ ldr r1, [r0]
++ tst r1, r2 @ D[12] = 1, Done
++ beq ECC_Init_Flag
++
++ ldr r0, =0x1e6e0070
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0050
++ ldr r1, =0x80000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0050
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0070
++ ldr r1, =0x00000400
++ str r1, [r0]
++#endif
++ ldr r0, =0x1e6e2008 @ Set Video ECLK phase
++ ldr r1, [r0]
++ ldr r2, =0xfffffff3
++ and r1, r1, r2
++ orr r1, r1, #0x08
++ str r1, [r0]
++
++ ldr r0, =0x1e6e2004
++ ldr r1, [r0]
++ ldr r2, =0xFFBFFFFF @ Enable JTAG Master, solve ARM stucked by JTAG issue
++ and r1, r1, r2
++ str r1, [r0]
++
++ ldr r0, =0x1e6e2048 @ Set MAC interface delay timing
++ ldr r1, =0x2255
++ str r1, [r0]
++
++ ldr r0, =0x1e6e2070 @ Set MAC AHB bus clock
++ ldr r1, [r0]
++ mov r2, #0x04 @ Default RMII, set MHCLK = HPLL/10
++ tst r1, #0xC0
++ movne r2, #0x02 @ if RGMII, set MHCLK = HPLL/6
++ ldr r0, =0x1e6e2008
++ ldr r1, [r0]
++ bic r1, r1, #0x00070000
++ orr r1, r1, r2, lsl #16
++ str r1, [r0]
++
++/* Test - DRAM initial time */
++ ldr r0, =0x1e782040
++ ldr r1, [r0]
++ ldr r0, =0xFFFFFFFF
++ sub r1, r0, r1
++ ldr r0, =0x1e72009c
++ str r1, [r0]
++ ldr r0, =0x1e7200a4
++ str r1, [r0]
++ ldr r0, =0x1e782030
++ ldr r1, [r0]
++ bic r1, r1, #0x0000F000
++ str r1, [r0]
++/* Test - DRAM initial time */
++
++/******************************************************************************
++ Reset GPIO registers when watchdog reset
++ ******************************************************************************/
++ ldr r0, =0x1e6e207c @ Check Revision ID
++ ldr r1, [r0]
++ mov r1, r1, lsr #24
++ cmp r1, #0x02
++ bne platform_exit3 @ not match AST2400
++
++ ldr r0, =0x1e6e203c @ Check watchdog reset event
++ ldr r1, [r0]
++ and r1, r1, #0x06
++ cmp r1, #0x0
++ beq platform_exit3 @ no watchdog reset event
++
++ ldr r0, =0x1e6e209c @ Check watchdog GPIO selection
++ ldr r1, [r0]
++ mov r1, r1, lsr #21
++ tst r1, #0x01
++ beq platform_exit3 @ no watchdog reset selection
++
++ ldr r1, =0x00000000 @ clear GPIO register reset by PRST_N
++ ldr r2, =0xFFFFFFFF
++ ldr r0, =0x1e780008
++ str r1, [r0]
++ ldr r0, =0x1e78000c
++ str r1, [r0]
++ ldr r0, =0x1e780010
++ str r1, [r0]
++ ldr r0, =0x1e780014
++ str r1, [r0]
++ ldr r0, =0x1e780018
++ str r2, [r0]
++ ldr r0, =0x1e780028
++ str r1, [r0]
++ ldr r0, =0x1e78002c
++ str r1, [r0]
++ ldr r0, =0x1e780030
++ str r1, [r0]
++ ldr r0, =0x1e780034
++ str r1, [r0]
++ ldr r0, =0x1e780038
++ str r2, [r0]
++ ldr r0, =0x1e780040
++ str r1, [r0]
++ ldr r0, =0x1e780044
++ str r1, [r0]
++ ldr r0, =0x1e780048
++ str r1, [r0]
++ ldr r0, =0x1e78004c
++ str r1, [r0]
++ ldr r0, =0x1e780050
++ str r1, [r0]
++ ldr r0, =0x1e780054
++ str r1, [r0]
++ ldr r0, =0x1e780058
++ str r1, [r0]
++ ldr r0, =0x1e780060
++ str r1, [r0]
++ ldr r0, =0x1e780064
++ str r1, [r0]
++ ldr r0, =0x1e780068
++ str r1, [r0]
++ ldr r0, =0x1e78006c
++ str r1, [r0]
++ ldr r0, =0x1e780090
++ str r1, [r0]
++ ldr r0, =0x1e780094
++ str r1, [r0]
++ ldr r0, =0x1e780098
++ str r1, [r0]
++ ldr r0, =0x1e78009c
++ str r1, [r0]
++ ldr r0, =0x1e7800a0
++ str r1, [r0]
++ ldr r0, =0x1e7800a4
++ str r1, [r0]
++ ldr r0, =0x1e7800a8
++ str r2, [r0]
++ ldr r0, =0x1e7800b0
++ str r1, [r0]
++ ldr r0, =0x1e7800b4
++ str r1, [r0]
++ ldr r0, =0x1e7800b8
++ str r1, [r0]
++ ldr r0, =0x1e7800e0
++ str r1, [r0]
++ ldr r0, =0x1e7800e4
++ str r1, [r0]
++ ldr r0, =0x1e7800e8
++ str r1, [r0]
++ ldr r0, =0x1e7800ec
++ str r1, [r0]
++ ldr r0, =0x1e7800f0
++ str r1, [r0]
++ ldr r0, =0x1e7800f4
++ str r1, [r0]
++ ldr r0, =0x1e7800f8
++ str r2, [r0]
++ ldr r0, =0x1e780100
++ str r1, [r0]
++ ldr r0, =0x1e780104
++ str r1, [r0]
++ ldr r0, =0x1e780108
++ str r1, [r0]
++ ldr r0, =0x1e780110
++ str r1, [r0]
++ ldr r0, =0x1e780114
++ str r1, [r0]
++ ldr r0, =0x1e780118
++ str r1, [r0]
++ ldr r0, =0x1e78011c
++ str r1, [r0]
++ ldr r0, =0x1e780120
++ str r1, [r0]
++ ldr r0, =0x1e780124
++ str r1, [r0]
++ ldr r0, =0x1e780128
++ str r2, [r0]
++ ldr r0, =0x1e780130
++ str r1, [r0]
++ ldr r0, =0x1e780134
++ str r1, [r0]
++ ldr r0, =0x1e780138
++ str r1, [r0]
++ ldr r0, =0x1e780140
++ str r1, [r0]
++ ldr r0, =0x1e780144
++ str r1, [r0]
++ ldr r0, =0x1e780148
++ str r1, [r0]
++ ldr r0, =0x1e78014c
++ str r1, [r0]
++ ldr r0, =0x1e780150
++ str r1, [r0]
++ ldr r0, =0x1e780154
++ str r1, [r0]
++ ldr r0, =0x1e780158
++ str r2, [r0]
++ ldr r0, =0x1e780160
++ str r1, [r0]
++ ldr r0, =0x1e780164
++ str r1, [r0]
++ ldr r0, =0x1e780168
++ str r1, [r0]
++ ldr r0, =0x1e780170
++ str r1, [r0]
++ ldr r0, =0x1e780174
++ str r1, [r0]
++ ldr r0, =0x1e780178
++ str r1, [r0]
++ ldr r0, =0x1e78017c
++ str r1, [r0]
++ ldr r0, =0x1e780180
++ str r1, [r0]
++ ldr r0, =0x1e780184
++ str r1, [r0]
++ ldr r0, =0x1e780188
++ str r2, [r0]
++ ldr r0, =0x1e780190
++ str r1, [r0]
++ ldr r0, =0x1e780194
++ str r1, [r0]
++ ldr r0, =0x1e780198
++ str r1, [r0]
++ ldr r0, =0x1e7801d0
++ str r1, [r0]
++ ldr r0, =0x1e7801d4
++ str r1, [r0]
++
++ ldr r0, =0x1e780204 @ clear SGPIOM register reset by PRST_N
++ str r1, [r0]
++ ldr r0, =0x1e780208
++ str r1, [r0]
++ ldr r0, =0x1e78020c
++ str r1, [r0]
++ ldr r0, =0x1e780210
++ str r1, [r0]
++ ldr r0, =0x1e780214
++ str r2, [r0]
++ ldr r0, =0x1e780220
++ str r1, [r0]
++ ldr r0, =0x1e780224
++ str r1, [r0]
++ ldr r0, =0x1e780228
++ str r1, [r0]
++ ldr r0, =0x1e78022c
++ str r1, [r0]
++ ldr r0, =0x1e780230
++ str r2, [r0]
++ ldr r0, =0x1e78023c
++ str r1, [r0]
++ ldr r0, =0x1e780240
++ str r1, [r0]
++ ldr r0, =0x1e780244
++ str r1, [r0]
++ ldr r0, =0x1e780248
++ str r1, [r0]
++ ldr r0, =0x1e78024c
++ str r2, [r0]
++ ldr r0, =0x1e780254
++ ldr r3, =0x01000040
++ str r3, [r0]
++ ldr r0, =0x1e780258
++ str r1, [r0]
++ ldr r0, =0x1e78025c
++ str r1, [r0]
++ ldr r0, =0x1e780260
++ str r1, [r0]
++
++ ldr r0, =0x1e780300 @ clear SGPIOS register reset by PRST_N
++ str r1, [r0]
++ ldr r0, =0x1e780304
++ str r1, [r0]
++ ldr r0, =0x1e780308
++ str r1, [r0]
++ ldr r0, =0x1e78030c
++ str r1, [r0]
++ ldr r0, =0x1e780310
++ str r1, [r0]
++ ldr r0, =0x1e780314
++ str r1, [r0]
++ ldr r0, =0x1e780318
++ str r2, [r0]
++ ldr r0, =0x1e78031c
++ str r2, [r0]
++ ldr r0, =0x1e780320
++ str r2, [r0]
++
++platform_exit3:
++
++/******************************************************************************
++ SPI Timing Calibration, not applicable to AST2300 series
++ ******************************************************************************/
++ ldr r0, =0x1e6e207c @ Check Revision ID
++ ldr r1, [r0]
++ mov r1, r1, lsr #24
++ cmp r1, #0x02
++ blt platform_exit4 @ not match AST2400 or later
++
++ ldr r0, =0x1e6e2070 @ Check SPI flash
++ ldr r1, [r0]
++ and r1, r1, #0x03
++ cmp r1, #0x02
++ bne platform_exit4
++
++ mov r2, #0x0
++ mov r6, #0x0
++ mov r7, #0x0
++ init_spi_checksum
++spi_checksum_wait_0:
++ ldr r1, [r0]
++ tst r1, r2
++ beq spi_checksum_wait_0
++ ldr r0, =0x1e620090
++ ldr r5, [r0] @ record golden checksum
++ ldr r0, =0x1e620080
++ mov r1, #0x0
++ str r1, [r0]
++
++ ldr r0, =0x1e620010 @ set to fast read mode
++ ldr r1, =0x000B0041
++ str r1, [r0]
++
++ ldr r6, =0x00F7E6D0 @ Init spiclk loop
++ mov r8, #0x0 @ Init delay record
++
++spi_cbr_next_clkrate:
++ mov r6, r6, lsr #0x4
++ cmp r6, #0x0
++ beq spi_cbr_end
++
++ mov r7, #0x0 @ Init delay loop
++ mov r8, r8, lsl #4
++
++spi_cbr_next_delay_s:
++ mov r2, #0x8
++ init_spi_checksum
++spi_checksum_wait_1:
++ ldr r1, [r0]
++ tst r1, r2
++ beq spi_checksum_wait_1
++ ldr r0, =0x1e620090
++ ldr r2, [r0] @ read checksum
++ ldr r0, =0x1e620080
++ mov r1, #0x0
++ str r1, [r0]
++ cmp r2, r5
++ bne spi_cbr_next_delay_e
++
++ mov r2, #0x0
++ init_spi_checksum
++spi_checksum_wait_2:
++ ldr r1, [r0]
++ tst r1, r2
++ beq spi_checksum_wait_2
++ ldr r0, =0x1e620090
++ ldr r2, [r0] @ read checksum
++ ldr r0, =0x1e620080
++ mov r1, #0x0
++ str r1, [r0]
++ cmp r2, r5
++ bne spi_cbr_next_delay_e
++
++ orr r8, r8, r7 @ record passed delay
++ b spi_cbr_next_clkrate
++
++spi_cbr_next_delay_e:
++ add r7, r7, #0x1
++ cmp r7, #0x6
++ blt spi_cbr_next_delay_s
++ b spi_cbr_next_clkrate
++
++spi_cbr_end:
++ ldr r0, =0x1e620094
++ str r8, [r0]
++ ldr r0, =0x1e620010
++ mov r1, #0x0
++ str r1, [r0]
++
++platform_exit4:
++
++ /* restore lr */
++ mov lr, r4
++
++ /* back to arch calling code */
++ mov pc, lr
+diff --git a/board/aspeed/ast2300/rc4.c b/board/aspeed/ast2300/rc4.c
+new file mode 100755
+index 0000000..32e0ffa
+--- /dev/null
++++ b/board/aspeed/ast2300/rc4.c
+@@ -0,0 +1,68 @@
++/*
++ * 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
++ */
++struct rc4_state
++{
++ int x, y, m[256];
++};
++
++void rc4_setup( struct rc4_state *s, unsigned char *key, int length )
++{
++ int i, j, k, *m, a;
++
++ s->x = 0;
++ s->y = 0;
++ m = s->m;
++
++ for( i = 0; i < 256; i++ )
++ {
++ m[i] = i;
++ }
++
++ j = k = 0;
++
++ for( i = 0; i < 256; i++ )
++ {
++ a = m[i];
++ j = (unsigned char) ( j + a + key[k] );
++ m[i] = m[j]; m[j] = a;
++ if( ++k >= length ) k = 0;
++ }
++}
++
++void rc4_crypt( struct rc4_state *s, unsigned char *data, int length )
++{
++ int i, x, y, *m, a, b;
++
++ x = s->x;
++ y = s->y;
++ m = s->m;
++
++ for( i = 0; i < length; i++ )
++ {
++ x = (unsigned char) ( x + 1 ); a = m[x];
++ y = (unsigned char) ( y + a );
++ m[x] = b = m[y];
++ m[y] = a;
++ data[i] ^= m[(unsigned char) ( a + b )];
++ }
++
++ s->x = x;
++ s->y = y;
++}
++
++void rc4_crypt_sw(unsigned char *data, int ulMsgLength, unsigned char *rc4_key, unsigned long ulKeyLength )
++{
++ struct rc4_state s;
++
++ rc4_setup( &s, rc4_key, ulKeyLength );
++
++ rc4_crypt( &s, data, ulMsgLength );
++}
+diff --git a/board/aspeed/ast2300/regtest.c b/board/aspeed/ast2300/regtest.c
+new file mode 100755
+index 0000000..1cd75ae
+--- /dev/null
++++ b/board/aspeed/ast2300/regtest.c
+@@ -0,0 +1,91 @@
++/*
++ * 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
++ */
++
++/*
++ * Diagnostics support
++ */
++#include <common.h>
++#include <command.h>
++#include <post.h>
++#include "slt.h"
++
++#if ((CFG_CMD_SLT & CFG_CMD_REGTEST) && defined(CONFIG_SLT))
++#include "regtest.h"
++
++int do_regtest (void)
++{
++ _SOCRegTestInfo *pjSOCRegInfo;
++ _SOCRegTestTbl *pjRegTable;
++ unsigned long ulRegBase;
++ unsigned long ulIndex, ulBack, ulAND, ulMask, ulData, ulTemp;
++ unsigned long Flags = 0;
++
++ /* unlock reg */
++ *(unsigned long *) (0x1e600000) = 0xaeed1a03; /* AHBC */
++ *(unsigned long *) (0x1e6e0000) = 0xfc600309; /* MMC */
++ *(unsigned long *) (0x1e6e2000) = 0x1688a8a8; /* SCU */
++
++ /* SCU */
++
++ /* do test */
++ pjSOCRegInfo = SOCRegTestInfo;
++ while (strcmp(pjSOCRegInfo->jName, "END"))
++ {
++ /* Reg. Test Start */
++ ulRegBase = pjSOCRegInfo->ulRegOffset;
++ pjRegTable = pjSOCRegInfo->pjTblIndex;
++
++ while (pjRegTable->ulIndex != 0xFFFFFFFF)
++ {
++ ulIndex = ulRegBase + pjRegTable->ulIndex;
++
++ ulBack = *(unsigned long *) (ulIndex);
++
++ ulMask = pjRegTable->ulMask;
++ ulAND = ~pjRegTable->ulMask;
++
++ ulData = 0xFFFFFFFF & pjRegTable->ulMask;
++ *(unsigned long *) (ulIndex) = ulData;
++ ulTemp = *(volatile unsigned long *) (ulIndex) & pjRegTable->ulMask;
++ if (ulData != ulTemp)
++ {
++ Flags |= pjSOCRegInfo->ulFlags;
++ printf("[DBG] RegTest: Failed Index:%x, Data:%x, Temp:%x \n", ulIndex, ulData, ulTemp);
++ }
++
++ ulData = 0x00000000 & pjRegTable->ulMask;
++ *(unsigned long *) (ulIndex) = ulData;
++ ulTemp = *(volatile unsigned long *) (ulIndex) & pjRegTable->ulMask;
++ if (ulData != ulTemp)
++ {
++ Flags |= pjSOCRegInfo->ulFlags;
++ printf("[DBG] RegTest: Failed Index:%x, Data:%x, Temp:%x \n", ulIndex, ulData, ulTemp);
++ }
++
++ *(unsigned long *) (ulIndex) = ulBack;
++
++ pjRegTable++;
++
++ } /* Individual Reg. Test */
++
++ if (Flags & pjSOCRegInfo->ulFlags)
++ printf("[INFO] RegTest: %s Failed \n", pjSOCRegInfo->jName);
++
++ pjSOCRegInfo++;
++
++ } /* Reg. Test */
++
++ return Flags;
++
++}
++
++#endif /* CONFIG_SLT */
+diff --git a/board/aspeed/ast2300/regtest.h b/board/aspeed/ast2300/regtest.h
+new file mode 100755
+index 0000000..49a360e
+--- /dev/null
++++ b/board/aspeed/ast2300/regtest.h
+@@ -0,0 +1,255 @@
++/*
++ * 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
++ */
++typedef struct {
++ unsigned long ulIndex;
++ unsigned long ulMask;
++} _SOCRegTestTbl;
++
++typedef struct {
++ unsigned char jName[10];
++ unsigned long ulRegOffset;
++ _SOCRegTestTbl *pjTblIndex;
++ unsigned long ulFlags;
++} _SOCRegTestInfo;
++
++_SOCRegTestTbl SMCRegTestTbl[] = {
++ {0x00000000, 0x00001FF3},
++ {0x00000004, 0xFFFFFFFF},
++ {0x00000008, 0x0FFF17FF},
++ {0x0000000C, 0xFFFFFFFF},
++ {0x00000010, 0xFF5FFFF3},
++ {0x00000018, 0x0FFFFFFF},
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl AHBCRegTestTbl[] = {
++ {0x00000080, 0x0000FFFE},
++ {0x00000088, 0x01000000},
++ {0x0000008c, 0x00000031},
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl MICRegTestTbl[] = {
++/*
++ {0x00000000, 0x0FFFFFF8},
++ {0x00000004, 0x0FFFFFF8},
++ {0x00000008, 0x0000FFFF},
++ {0x0000000C, 0x0FFFF000},
++ {0x00000010, 0xFFFFFFFF},
++*/
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl MAC1RegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl MAC2RegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl USB2RegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl VICRegTestTbl[] = {
++ {0x0000000C, 0xFFFFFFFF},
++ {0x00000024, 0xFFFFFFFF},
++ {0x00000028, 0xFFFFFFFF},
++ {0x0000002C, 0xFFFFFFFF},
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl MMCRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl USB11RegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl SCURegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl HASERegTestTbl[] = {
++ {0x00000000, 0x0FFFFFF8},
++ {0x00000004, 0x0FFFFFF8},
++ {0x00000008, 0x0FFFFFF8},
++ {0x0000000C, 0x0FFFFFF8},
++ //{0x00000010, 0x00001FFF},
++ {0x00000020, 0x0FFFFFF8},
++ {0x00000024, 0x0FFFFFF8},
++ {0x00000028, 0x0FFFFFc0},
++ {0x0000002C, 0x0FFFFFFF},
++ //{0x00000030, 0x000003FF},
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl I2SRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl CRTRegTestTbl[] = {
++/*
++ {0x00000000, 0x001F3703},
++ {0x00000004, 0x0000FFC1},
++*/
++ {0x00000010, 0x0FFF0FFF},
++ {0x00000014, 0x0FFF0FFF},
++ {0x00000018, 0x07FF07FF},
++ {0x0000001C, 0x07FF07FF},
++ {0x00000020, 0x0FFFFFF8},
++ {0x00000024, 0x07FF3FF8},
++/*
++ {0x00000028, 0x003F003F},
++ {0x00000030, 0x003F003F},
++ {0x00000034, 0x0FFF0FFF},
++ {0x00000038, 0x0FFFFFF8},
++*/
++ {0x00000040, 0x0FFF0FFF},
++ {0x00000044, 0x07FF07FF},
++ {0x00000048, 0x0FFFFFF8},
++ {0x0000004C, 0x00FF07F8},
++ {0x00000050, 0x000F0F0F},
++/*
++ {0x00000060, 0x001F3703},
++ {0x00000064, 0x0000FFC1},
++*/
++ {0x00000070, 0x0FFF0FFF},
++ {0x00000074, 0x0FFF0FFF},
++ {0x00000078, 0x07FF07FF},
++ {0x0000007C, 0x07FF07FF},
++ {0x00000080, 0x0FFFFFF8},
++ {0x00000084, 0x07FF3FF8},
++/*
++ {0x00000088, 0x003F003F},
++ {0x00000090, 0x003F003F},
++ {0x00000094, 0x0FFF0FFF},
++ {0x00000098, 0x0FFFFFF8},
++*/
++ {0x000000A0, 0x0FFF0FFF},
++ {0x000000A4, 0x07FF07FF},
++ {0x000000A8, 0x0FFFFFF8},
++ {0x000000AC, 0x00FF07F8},
++ {0x000000B0, 0x000F0F0F},
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl VIDEORegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl A2PRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl MDMARegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl M2DRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl GPIORegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl RTCRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl TIMERRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl UART1RegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl UART2RegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl WDTRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl PWMRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl VUART1RegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl VUART2RegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl LPCRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl I2CRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl PECIRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl PCIARegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl PCIRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++
++/* Test List */
++_SOCRegTestInfo SOCRegTestInfo[] = {
++ /* Test Name, Reg. Offset, Test Table, Error Code */
++ { "SMCREG", 0x16000000, SMCRegTestTbl, 0x00000001},
++ { "AHBCREG", 0x1e600000, AHBCRegTestTbl, 0x00000002},
++ { "MICREG", 0x1e640000, MICRegTestTbl, 0x00000004},
++ { "MAC1REG", 0x1e660000, MAC1RegTestTbl, 0x00000008},
++ { "MAC2REG", 0x1e680000, MAC2RegTestTbl, 0x00000010},
++ { "USB2REG", 0x1e6a0000, USB2RegTestTbl, 0x00000020},
++ { "VICREG", 0x1e6c0000, VICRegTestTbl, 0x00000040},
++ { "MMCREG", 0x1e6e0000, MMCRegTestTbl, 0x00000080},
++ { "USB11REG", 0x1e6e1000, USB11RegTestTbl, 0x00000100},
++ { "SCUREG", 0x1e6e2000, SCURegTestTbl, 0x00000200},
++ { "HASEREG", 0x1e6e3000, HASERegTestTbl, 0x00000400},
++ { "I2SREG", 0x1e6e5000, I2SRegTestTbl, 0x00000800},
++ { "CRTREG", 0x1e6e6000, CRTRegTestTbl, 0x00001000},
++ { "VIDEOREG", 0x1e700000, VIDEORegTestTbl, 0x00002000},
++ { "A2PREG", 0x1e720000, A2PRegTestTbl, 0x00004000},
++ { "MDMAREG", 0x1e740000, MDMARegTestTbl, 0x00008000},
++ { "2DREG", 0x1e760000, M2DRegTestTbl, 0x00010000},
++ { "GPIOREG", 0x1e780000, GPIORegTestTbl, 0x00020000},
++ { "RTCREG", 0x1e781000, RTCRegTestTbl, 0x00040000},
++ { "TIMERREG", 0x1e782000, TIMERRegTestTbl, 0x00080000},
++ { "UART1REG", 0x1e783000, UART1RegTestTbl, 0x00100000},
++ { "UART2REG", 0x1e784000, UART2RegTestTbl, 0x00200000},
++ { "WDTREG", 0x1e785000, WDTRegTestTbl, 0x00400000},
++ { "PWMREG", 0x1e786000, PWMRegTestTbl, 0x00800000},
++ {"VUART1REG", 0x1e787000, VUART1RegTestTbl, 0x01000000},
++ {"VUART2REG", 0x1e788000, VUART2RegTestTbl, 0x02000000},
++ { "LPCREG", 0x1e789000, LPCRegTestTbl, 0x04000000},
++ { "I2CREG", 0x1e78A000, I2CRegTestTbl, 0x08000000},
++ { "PECIREG", 0x1e78B000, PECIRegTestTbl, 0x10000000},
++ { "PCIAREG", 0x1e78C000, PCIARegTestTbl, 0x20000000},
++ { "PCIREG", 0x60000000, PCIRegTestTbl, 0x40000000},
++ { "END", 0xffffffff, NULL, 0xffffffff}
++};
+diff --git a/board/aspeed/ast2300/slt.c b/board/aspeed/ast2300/slt.c
+new file mode 100755
+index 0000000..3283d34
+--- /dev/null
++++ b/board/aspeed/ast2300/slt.c
+@@ -0,0 +1,105 @@
++/*
++ * 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
++ */
++
++/*
++ * Diagnostics support
++ */
++#include <common.h>
++#include <command.h>
++#include <post.h>
++#include "slt.h"
++
++#if defined (CONFIG_SLT)
++
++int do_slt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
++{
++ int flags = 0;
++ int loop = 1;
++
++ if (argc > 1) {
++ loop = simple_strtoul(argv[1], NULL, 10);
++ }
++
++ do {
++
++do_slt_start:
++ /* Reg. Test */
++#if (CFG_CMD_SLT & CFG_CMD_REGTEST)
++ if (do_regtest())
++ {
++ flags |= FLAG_REGTEST_FAIL;
++ printf("[INFO] RegTest Failed \n");
++ }
++ else
++ printf("[INFO] RegTest Passed \n");
++#endif
++#if (CFG_CMD_SLT & CFG_CMD_MACTEST)
++ if (do_mactest())
++ {
++ flags |= FLAG_MACTEST_FAIL;
++ printf("[INFO] MACTest Failed \n");
++ }
++ else
++ printf("[INFO] MACTest Passed \n");
++#endif
++#if (CFG_CMD_SLT & CFG_CMD_VIDEOTEST)
++ if (do_videotest())
++ {
++ flags |= FLAG_VIDEOTEST_FAIL;
++ printf("[INFO] VideoTest Failed \n");
++ }
++ else
++ printf("[INFO] VideoTest Passed \n");
++#endif
++#if (CFG_CMD_SLT & CFG_CMD_HACTEST)
++ if (do_hactest())
++ {
++ flags |= FLAG_HACTEST_FAIL;
++ printf("[INFO] HACTest Failed \n");
++ }
++ else
++ printf("[INFO] HACTest Passed \n");
++#endif
++#if (CFG_CMD_SLT & CFG_CMD_MICTEST)
++ if (do_mictest())
++ {
++ flags |= FLAG_MICTEST_FAIL;
++ printf("[INFO] MICTest Failed \n");
++ }
++ else
++ printf("[INFO] MICTest Passed \n");
++#endif
++
++ /* Summary */
++ if (flags)
++ printf ("[INFO] SLT Test Failed!! \n");
++ else
++ printf ("[INFO] SLT Test Passed!! \n");
++
++ if (loop == 0) /* infinite */
++ goto do_slt_start;
++ else
++ loop--;
++
++ } while (loop);
++
++ return 0;
++}
++/***************************************************/
++
++U_BOOT_CMD(
++ slt, CONFIG_SYS_MAXARGS, 0, do_slt,
++ "slt - slt test program \n",
++ NULL
++);
++
++#endif /* CONFIG_SLT */
+diff --git a/board/aspeed/ast2300/slt.h b/board/aspeed/ast2300/slt.h
+new file mode 100755
+index 0000000..4e650bc
+--- /dev/null
++++ b/board/aspeed/ast2300/slt.h
+@@ -0,0 +1,29 @@
++/*
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#define CFG_CMD_REGTEST 0x00000001
++#define CFG_CMD_MACTEST 0x00000002
++#define CFG_CMD_VIDEOTEST 0x00000004
++#define CFG_CMD_HACTEST 0x00000008
++#define CFG_CMD_MICTEST 0x00000010
++#define CFG_CMD_OSDTEST 0x00000020
++#define CFG_CMD_2DTEST 0x00000040
++#define CFG_CMD_HWCTEST 0x00000080
++
++#define FLAG_REGTEST_FAIL 0x00000001
++#define FLAG_MACTEST_FAIL 0x00000002
++#define FLAG_VIDEOTEST_FAIL 0x00000004
++#define FLAG_HACTEST_FAIL 0x00000008
++#define FLAG_MICTEST_FAIL 0x00000010
++#define FLAG_OSDTEST_FAIL 0x00000020
++#define FLAG_2DTEST_FAIL 0x00000040
++#define FLAG_HWCTEST_FAIL 0x00000080
++
++
+diff --git a/board/aspeed/ast2300/type.h b/board/aspeed/ast2300/type.h
+new file mode 100755
+index 0000000..f57ee5a
+--- /dev/null
++++ b/board/aspeed/ast2300/type.h
+@@ -0,0 +1,116 @@
++/*
++ * 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 _TYPE_H_
++#define _TYPE_H_
++
++ typedef unsigned char BOOL;
++ typedef unsigned char UINT8;
++ typedef unsigned short UINT16;
++ typedef unsigned int UINT32;
++
++ #define FLONG unsigned long
++ #define BYTE unsigned char
++ #define INT int
++ #define VOID void
++ #define BOOLEAN unsigned short
++ #define ULONG unsigned long
++ #define USHORT unsigned short
++ #define UCHAR unsigned char
++ #define CHAR char
++ #define LONG long
++ #define PUCHAR UCHAR *
++ #define PULONG ULONG *
++
++ #define FAIL 1
++
++ #define intfunc int386
++
++ #define outdwport outpd
++ #define indwport inpd
++ #define outport outp
++ #define inport inp
++
++ //#define NULL ((void *)0)
++ #define FALSE 0
++ #define TRUE 1
++
++ #define ReadMemoryBYTE(baseaddress,offset) *(BYTE *)((ULONG)(baseaddress)+(ULONG)(offset))
++ #define ReadMemoryLong(baseaddress,offset) *(ULONG *)((ULONG)(baseaddress)+(ULONG)(offset))
++ #define ReadMemoryShort(baseaddress,offset) *(USHORT *)((ULONG)(baseaddress)+(ULONG)(offset))
++ #define WriteMemoryBYTE(baseaddress,offset,data) *(BYTE *)((ULONG)(baseaddress)+(ULONG)(offset)) = (BYTE)(data)
++ #define WriteMemoryLong(baseaddress,offset,data) *(ULONG *)((ULONG)(baseaddress)+(ULONG)(offset))=(ULONG)(data)
++ #define WriteMemoryShort(baseaddress,offset,data) *(USHORT *)((ULONG)(baseaddress)+(ULONG)(offset))=(USHORT)(data)
++ #define WriteMemoryLongWithANDData(baseaddress, offset, anddata, data) *(ULONG *)((ULONG)(baseaddress)+(ULONG)(offset)) = *(ULONG *)((ULONG)(baseaddress)+(ULONG)(offset)) & (ULONG)(anddata) | (ULONG)(data)
++
++ #define WriteMemoryLongWithMASK(baseaddress, offset, data, mask) \
++ *(volatile ULONG *)((ULONG)(baseaddress)+(ULONG)(offset)) = *(volatile ULONG *)(((ULONG)(baseaddress)+(ULONG)(offset)) & (ULONG)(~(mask))) | ((ULONG)(data) & (ULONG)(mask))
++
++ #define ReadMemoryLongHost(baseaddress,offset) *(volatile ULONG *)((ULONG)(baseaddress)+(ULONG)(offset))
++ #define WriteMemoryLongHost(baseaddress,offset,data) *(volatile ULONG *)((ULONG)(baseaddress)+(ULONG)(offset))=(ULONG)(data)
++ #define WriteMemoryBYTEHost(baseaddress,offset,data) *(volatile BYTE *)((ULONG)(baseaddress)+(ULONG)(offset)) = (BYTE)(data)
++#define WriteMemoryLongWithMASKHost(baseaddress, offset, data, mask) *(volatile ULONG *)((ULONG)(baseaddress)+(ULONG)(offset)) = (((*(volatile ULONG *)((ULONG)(baseaddress)+(ULONG)(offset)))&(~mask)) | (ULONG)((data)&(mask)))
++
++ #define ReadMemoryLongClient(baseaddress,offset) *(volatile ULONG *)((ULONG)(baseaddress)+(ULONG)(offset))
++ #define WriteMemoryLongClient(baseaddress,offset,data) *(volatile ULONG *)((ULONG)(baseaddress)+(ULONG)(offset))=(ULONG)(data)
++ #define WriteMemoryBYTEClient(baseaddress,offset,data) *(volatile BYTE *)((ULONG)(baseaddress)+(ULONG)(offset)) = (BYTE)(data)
++#define WriteMemoryLongWithMASKClient(baseaddress, offset, data, mask) *(volatile ULONG *)((ULONG)(baseaddress)+(ULONG)(offset)) = (((*(volatile ULONG *)((ULONG)(baseaddress)+(ULONG)(offset)))&(~mask)) | (ULONG)((data)&(mask)))
++
++#ifdef BUF_GLOBALS
++#define BUF_EXT
++#else
++#define BUF_EXT extern
++#endif
++
++BUF_EXT ULONG g_CAPTURE_VIDEO1_BUF1_ADDR; /* VIDEO1_BUF_1_ADDR*/
++BUF_EXT ULONG g_CAPTURE_VIDEO1_BUF2_ADDR; /* VIDEO1_BUF_2_ADDR*/
++BUF_EXT ULONG g_VIDEO1_COMPRESS_BUF_ADDR; /* Encode destination address */
++BUF_EXT ULONG g_VIDEO1_CRC_BUF_ADDR;
++BUF_EXT ULONG g_VIDEO1_FLAG_BUF_ADDR;
++BUF_EXT ULONG g_VIDEO1_RC4_BUF_ADDR;
++
++
++BUF_EXT ULONG g_CAPTURE_VIDEO2_BUF1_ADDR;
++BUF_EXT ULONG g_CAPTURE_VIDEO2_BUF2_ADDR;
++BUF_EXT ULONG g_VIDEO2_COMPRESS_BUF_ADDR;
++BUF_EXT ULONG g_VIDEO2_CRC_BUF_ADDR;
++BUF_EXT ULONG g_VIDEO2_FLAG_BUF_ADDR;
++BUF_EXT ULONG g_VIDEO2_RC4_BUF_ADDR;
++
++BUF_EXT ULONG g_VIDEO1_DECODE_BUF_1_ADDR;
++BUF_EXT ULONG g_VIDEO1_DECODE_BUF_2_ADDR;
++BUF_EXT ULONG g_VIDEO1_DECOMPRESS_BUF_ADDR;
++BUF_EXT ULONG g_VIDEO1_DECODE_RC4_BUF_ADDR;
++
++BUF_EXT ULONG g_VIDEO2_DECODE_BUF_1_ADDR;
++BUF_EXT ULONG g_VIDEO2_DECODE_BUF_2_ADDR;
++BUF_EXT ULONG g_VIDEO2_DECOMPRESS_BUF_ADDR;
++BUF_EXT ULONG g_VIDEO2_DECODE_RC4_BUF_ADDR;
++
++BUF_EXT ULONG g_CAPTURE_VIDEOM_BUF1_ADDR;
++BUF_EXT ULONG g_CAPTURE_VIDEOM_BUF2_ADDR;
++BUF_EXT ULONG g_VIDEOM_COMPRESS_BUF_ADDR;
++BUF_EXT ULONG g_VIDEOM_FLAG_BUF_ADDR;
++BUF_EXT ULONG g_VIDEOM_RC4_BUF_ADDR;
++
++BUF_EXT ULONG g_VIDEOM_DECODE_BUF_1_ADDR;
++BUF_EXT ULONG g_VIDEOM_DECODE_BUF_2_ADDR;
++BUF_EXT ULONG g_VIDEOM_DECOMPRESS_BUF_ADDR;
++BUF_EXT ULONG g_VIDEOM_DECODE_RC4_BUF_ADDR;
++
++#ifdef WIN_GLOBALS
++#define WIN_EXT
++#else
++#define WIN_EXT extern
++#endif
++
++WIN_EXT USHORT g_DefWidth, g_DefHeight;
++
++#endif
+diff --git a/board/aspeed/ast2300/u-boot.lds b/board/aspeed/ast2300/u-boot.lds
+new file mode 100755
+index 0000000..b5a90ef
+--- /dev/null
++++ b/board/aspeed/ast2300/u-boot.lds
+@@ -0,0 +1,45 @@
++/*
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
++/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
++OUTPUT_ARCH(arm)
++ENTRY(_start)
++SECTIONS
++{
++ . = 0x00000000;
++
++ . = ALIGN(4);
++ .text :
++ {
++ cpu/arm926ejs/start.o (.text)
++ *(.text)
++ }
++
++ . = ALIGN(4);
++ .rodata : { *(.rodata) }
++
++ . = ALIGN(4);
++ .data : { *(.data) }
++
++ . = ALIGN(4);
++ .got : { *(.got) }
++
++ __u_boot_cmd_start = .;
++ .u_boot_cmd : { *(.u_boot_cmd) }
++ __u_boot_cmd_end = .;
++
++ . = ALIGN(4);
++ __bss_start = .;
++ .bss : { *(.bss) }
++ _end = .;
++}
+diff --git a/board/aspeed/ast2300/vdef.h b/board/aspeed/ast2300/vdef.h
+new file mode 100755
+index 0000000..3c99b7e
+--- /dev/null
++++ b/board/aspeed/ast2300/vdef.h
+@@ -0,0 +1,500 @@
++/*
++ * 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 _VDEF_H_
++#define _VDEF_H_
++
++#define VIDEO1 0
++#define VIDEO1_ON 0x01
++#define VIDEO2 1
++#define VIDEO2_ON 0x02
++
++#define VIDEOM_ON 0x04
++#define VIDEOM 2
++
++#define CRT_1 0
++#define CRT_1_ON 0x01
++#define CRT_2 1
++#define CRT_2_ON 0x02
++
++#define SINGLE_CODEC_SINGLE_CAPTURE 0
++#define AUTO_CODEC_SINGLE_CAPTURE 2
++#define AUTO_CODEC_AUTO_CAPTURE 3
++
++#define MAC1_BASE 0x1E660000
++#define APB_BRIDGE_1_BASE 0x1E6E0000
++#define VIDEO_REG_BASE 0x1E700000
++#define APB_BRIDGE_2_BASE 0x1E780000
++
++#define DRAM_INIT_BASE 0x1E6E0000
++
++#define SDRAM_PROTECT_REG 0x00
++ #define SDRAM_WRITE_DISABLE 0
++ #define SDRAM_WRITE_ENABLE 1
++
++#define SCU_BASE 0x1E6E0000
++#define SCU_OFFSET 0x2000
++
++#define VIC_BASE 0x1E6C0000
++ #define VIDEO_INT_BIT 7
++
++#define IRQ_STATUS_REG 0x00
++#define RAW_INT_STATUS_REG 0x08
++#define INT_SEL_REG 0x0C
++ #define FIQ_INT 1
++ #define IRQ_INT 0
++#define INT_EN_REG 0x10
++#define INT_EN_CLEAR_REG 0x14
++#define INT_SOFT_REG 0x18
++#define INT_SOFT_CLEAR_REG 0x1C
++#define INT_SENSE_REG 0x24
++ #define LEVEL_SENSE 1
++ #define EDGE_SENSE 0
++#define INT_EVENT_REG 0x2C
++ #define HIGH_LEVEL_SENSE 1
++ #define LOW_LEVEL_SENSE 0
++
++#define SCU_HW_TRAPPING_REG 0x70 + SCU_OFFSET
++ #define CLIENT_MODE_EN_BIT 18
++ #define CLIENT_MODE_EN_MASK 0x00040000
++ #define BE_HOST_CHIP 0
++ #define BE_CLIENT_CHIP 1
++
++#define SCU_ULOCK_KEY 0x1688A8A8
++
++#define SCU_PROTECT_REG 0x00 + SCU_OFFSET
++ #define SCU_WRITE_DISABLE 0
++ #define SCU_WRITE_ENABLE 1
++
++#define SCU_CONTROL_REG 0x04 + SCU_OFFSET
++ #define VIDEO_ENGINE_RESET 0x00000040
++ #define VIDEO_ENGINE_RESET_BIT 6
++ #define VIDEO_ENGINE_RESET_MASK 0x00000040
++ #define VIDEO_RESET_EN 1
++ #define VIDEO_RESET_OFF 0
++
++#define SCU_CLOCK_SELECTION_REG 0x08 + SCU_OFFSET
++ #define PORTA_CLOCK_DELAY_MASK 7 << 8 //Video port A output clcok selection
++ #define PORTA_CLOCK_INV_DELAY_1NS 5 << 8 //Clock inversed and delay ~ 2ns
++ #define PORTA_CLOCK_INV_DELAY_2NS 6 << 8 //Clock inversed and delay ~ 3ns
++ #define PORTB_CLOCK_DELAY_MASK 7 << 12 //Video port B output clock delay
++ #define PORTB_CLOCK_INV_DELAY_1NS 5 << 12 //Clock inversed and delay ~ 3ns
++ #define PORTB_CLOCK_INV_DELAY_2NS 6 << 12 //Clock inversed and delay ~ 3ns
++ #define PORTB_CLOCK_SEL 1 << 15 //Video port B clock selection
++ #define PORTB_FROM_D1CLK 0 << 15
++ #define PORTB_FROM_D2CLK 1 << 15
++ #define ECLK_CLK_SEL_MASK (3 << 2)
++ #define ECLK_FROM_HPLL (1 << 2)
++
++ #define D2CLK_CLOCK_SELECTION 0x00020000
++ #define D2CLK_CLOCK_SELECTION_BIT 17
++ #define D2CLK_CLOCK_SELECTION_MASK 0x00060000
++ #define NORMAL_CRT1 0
++ #define V1CLK_VIDEO1 2
++ #define V1CLK_VIDEO2 3
++
++#define SCU_CLOCK_STOP_REG 0x0C + SCU_OFFSET
++ #define EN_ECLK 0 << 0 //Enable ECLK (For Video Engine)
++ #define STOP_ECLK_BIT 0
++ #define STOP_ECLK_MASK 1 << 0
++ #define EN_V1CLK 0 << 3 //Enable V1CLK (For Video Capture #1)
++ #define STOP_V1CLK_BIT 3
++ #define STOP_V1CLK_MASK 1 << 3
++ #define EN_D1CLK 0 << 10 //Enable D1CLK (For CRT1)
++ #define STOP_D1CLK_BIT 10
++ #define STOP_D1CLK_MASK 1 << 10
++ #define EN_D2CLK 0 << 11 //Stop D2CLK (For CRT2)
++ #define STOP_D2CLK (1 << 11)
++ #define STOP_D2CLK_BIT 11
++ #define STOP_D2CLK_MASK 1 << 11
++ #define EN_V2CLK 0 << 12 //Stop V2CLK (For Video Capture #2)
++ #define STOP_V2CLK_BIT 12
++ #define STOP_V2CLK_MASK 1 << 12
++ #define STOP_HACE_BIT 13
++ #define EN_HACE (0 << 13)
++ #define STOP_HACE_MASK (1 << 13)
++ #define EN_I2SCLK 0 << 18
++ #define STOP_I2SCLK_MASK 1 << 18
++
++#define SCU_PIN_CTRL1_REG 0x74 + SCU_OFFSET
++ #define I2C_5_PIN_EN 1 << 12 //Enable I2C #5 PIN
++ #define I2C_5_PIN_OFF 0 << 12 //Disable I2C #5 PIN
++ #define I2C_5_PIN_MASK 1 << 12
++ #define VGA_PIN_OFF 0 << 15 //Enable VGA pins
++ #define VGA_PIN_MASK 1 << 15
++ #define VIDEO_PORTA_EN 1 << 16 //Enable Video port A control pins
++ #define VIDEO_PORTA_MASK 1 << 16
++ #define VIDEO_PORTB_EN 1 << 17 //Enable Video port B control pins
++ #define VIDEO_PORTB_MASK 1 << 17
++ #define VIDEO_VP1_EN 1 << 22 //Enable VP[11:0]
++ #define VIDEO_VP1_MASK 1 << 22
++ #define VIDEO_VP2_EN 1 << 23 //Enable VP[23:12]
++ #define VIDEO_VP2_MASK 1 << 23
++ #define I2S_PIN_EN 1 << 29 //Enable I2S function pins
++ #define I2S_PIN_MASK 1 << 29
++
++#define SCU_PIN_CTRL2_REG 0x78 + SCU_OFFSET
++ #define VIDEO_PORTA_SINGLE_EDGE_MASK 1 << 0
++ #define VIDEO_PORTA_SINGLE_EDGE 1 << 0 //Enable Video port A single mode
++ #define VIDEO_PORTA_DUAL_EDGE 0 << 0
++ #define VIDEO_PORTB_SINGLE_EDGE_MASK 1 << 1
++ #define VIDEO_PORTB_DUAL_EDGE 0 << 1
++ #define VIDEO_PORTB_SINGLE_EDGE 1 << 1 //Enable Video port B single mode
++
++#define SCU_M_PLL_PARAM_REG 0x20 + SCU_OFFSET
++
++#define DRAM_BASE 0x40000000
++
++#define INPUT_BITCOUNT_YUV444 4
++#define INPUT_BITCOUNT_YUV420 2
++
++/* HW comment value */
++//PASSWORD
++#define VIDEO_UNLOCK_KEY 0x1A038AA8
++#define SCU_UNLOCK_KEY 0x1688A8A8
++#define SDRAM_UNLOCK_KEY 0xFC600309
++
++
++//#define SAMPLE_RATE 12000000.0
++#ifdef OSC_NEW
++ #define SAMPLE_RATE 24576000.0
++#else
++ #define SAMPLE_RATE 24000000.0
++#endif
++
++#define MODEDETECTION_VERTICAL_STABLE_MAXIMUM 0x4
++#define MODEDETECTION_HORIZONTAL_STABLE_MAXIMUM 0x4
++#define MODEDETECTION_VERTICAL_STABLE_THRESHOLD 0x4
++#define MODEDETECTION_HORIZONTAL_STABLE_THRESHOLD 0x8
++
++#define MODEDETECTION_EDGE_PIXEL_THRES_DIGITAL 2
++#define MODEDETECTION_EDGE_PIXEL_THRES_ANALOGE 0x0A
++
++#define MODEDETECTION_OK 0
++#define MODEDETECTION_ERROR 1
++#define JUDGE_MODE_ERROR 2
++
++//I2C Loop Count
++#define LOOP_COUNT 1000
++#define CAN_NOT_FIND_DEVICE 1
++#define SET_I2C_DONE 0
++#define I2C_BASE 0xA000
++#define AC_TIMING 0x77743355
++
++//I2C channel and Devices
++#define I2C_VIDEO1_EEPROM 0x2
++#define I2C_VIDEO2_EEPROM 0x5
++#define I2C_VIDEO2_9883 0x4
++/*
++ULONG CAPTURE1_ADDRESS = 0x1000000;
++ULONG CAPTURE2_ADDRESS = 0x3000000;
++ULONG PASS1_ENCODE_SOURCE_ADDRESS = 0x1000000;
++ULONG PASS1_ENCODE_DESTINATION_ADDRESS = 0x2000000;
++ULONG Buffer1_DECODE_SOURCE_ADDRESS = 0x1000000;
++ULONG Buffer2_DECODE_SOURCE_ADDRESS = 0x1400000;
++ULONG PASS1_DECODE_DESTINATION_ADDRESS = 0x600000;
++ULONG CAPTURE_2ND_ADDRESS = 0x1800000;
++ULONG PASS1_2ND_ENCODE_SOURCE_ADDRESS = 0x1800000;
++ULONG PASS1_2ND_ENCODE_DESTINATION_ADDRESS = 0x2800000;
++ULONG PASS1_2ND_DECODE_SOURCE_ADDRESS = 0x1000000;
++ULONG PASS1_2ND_DECODE_DESTINATION_ADDRESS = 0x600000;
++ULONG PASS2_ENCODE_SOURCE_ADDRESS = 0x000000;
++ULONG PASS2_ENCODE_DESTINATION_ADDRESS = 0xC00000;
++ULONG PASS2_DECODE_SOURCE_ADDRESS = 0xC00000;
++ULONG PASS2_DECODE_DESTINATION_ADDRESS = 0x600000;
++ULNG PASS2_DECODE_REFERENCE_ADDRESS = 0x600000;
++*/
++
++typedef struct _CTL_REG_G {
++ ULONG CompressMode:1;
++ ULONG SkipEmptyFrame:1;
++ ULONG MemBurstLen:2;
++ ULONG LineBufEn:2;
++ ULONG Unused:26;
++} CTL_REG_G;
++
++
++typedef union _U_CTL_G {
++ ULONG Value;
++ CTL_REG_G CtlReg;
++} U_CTL_G;
++
++typedef struct _MODE_DETECTION_PARAM_REG {
++ ULONG Unused1:8;
++ ULONG EdgePixelThres:8;
++ ULONG VerStableMax:4;
++ ULONG HorStableMax:4;
++ ULONG VerDiffMax:4;
++ ULONG HorDiffMax:4;
++} MODE_DETECTION_PARAM_REG;
++
++typedef struct _CRC_PRI_PARAM_REG {
++ ULONG Enable:1;
++ ULONG HighBitOnly:1;
++ ULONG SkipCountMax:6;
++ ULONG PolyLow:8;
++ ULONG PolyHigh:16;
++} CRC_PRI_PARAM_REG;
++
++typedef union _U_CRC_PRI_PARAM {
++ ULONG Value;
++ CRC_PRI_PARAM_REG CRCPriParam;
++} U_CRC_PRI_PARAM;
++
++typedef struct _CRC_SEC_PARAM_REG {
++ ULONG Unused1:8;
++ ULONG PolyLow:8;
++ ULONG PolyHigh:16;
++} CRC_SEC_PARAM_REG;
++
++typedef union _U_CRC_SEC_PARAM {
++ ULONG Value;
++ CRC_SEC_PARAM_REG CRCSecParam;
++} U_CRC_SEC_PARAM;
++
++typedef struct _GENERAL_INFO {
++ BYTE EnableVideoM;
++ BYTE CenterMode;
++ BYTE RC4NoResetFrame;
++ BYTE RC4TestMode;
++ U_CTL_G uCtlReg;
++ U_CRC_PRI_PARAM uCRCPriParam;
++ U_CRC_SEC_PARAM uCRCSecParam;
++} GENERAL_INFO, *PGENERAL_INFO;
++
++typedef struct _SEQ_CTL_REG {
++ ULONG Unused1:1;
++ ULONG Unused2:1;
++ ULONG Unused3:1;
++ ULONG CaptureAutoMode:1;
++ ULONG Unused4:1;
++ ULONG CodecAutoMode:1;
++ ULONG Unused5:1;
++ ULONG WatchDog:1;
++ ULONG CRTSel:1;
++ ULONG AntiTearing:1;
++ ULONG DataType:2;
++ ULONG Unused6:20;
++} SEQ_CTL_REG;
++
++typedef union _U_SEQ_CTL {
++ ULONG Value;
++ SEQ_CTL_REG SeqCtlReg;
++} U_SEQ_CTL;
++
++typedef struct _CTL_REG {
++ ULONG SrcHsync:1;
++ ULONG SrcVsync:1;
++ ULONG ExtSrc:1;
++ ULONG AnalongExtSrc:1;
++ ULONG IntTimingGen:1;
++ ULONG IntDataFrom:1;
++ ULONG WriteFmt:2;
++ ULONG VGACursor:1;
++ ULONG LinearMode:1;
++ ULONG ClockDelay:2;
++ ULONG CCIR656Src:1;
++ ULONG PortClock:1;
++ ULONG ExtPort:1;
++ ULONG Unused1:1;
++ ULONG FrameRate:8;
++ ULONG Unused2:8;
++} CTL_REG;
++
++typedef union _U_CTL {
++ ULONG Value;
++ CTL_REG CtlReg;
++} U_CTL_REG;
++
++typedef struct _TIMING_GEN_SETTING_H {
++ ULONG HDEEnd:13;
++ ULONG Unused1:3;
++ ULONG HDEStart:13;
++ ULONG Unused2:3;
++} TIMING_GEN_SETTING_H;
++
++typedef struct _TIMING_GEN_SETTING_V {
++ ULONG VDEEnd:13;
++ ULONG Unused1:3;
++ ULONG VDEStart:13;
++ ULONG Unused2:3;
++} TIMING_GEN_SETTING_V;
++
++typedef struct _BCD_CTL_REG {
++ ULONG Enable:1;
++ ULONG Unused1:15;
++ ULONG Tolerance:8;
++ ULONG Unused2:8;
++} BCD_CTL_REG;
++
++typedef union _U_BCD_CTL {
++ ULONG Value;
++ BCD_CTL_REG BCDCtlReg;
++} U_BCD_CTL;
++
++typedef struct _COMPRESS_WINDOW_REG {
++ ULONG VerLine:13;
++ ULONG Unused1:3;
++ ULONG HorPixel:13;
++ ULONG Unused2:3;
++} COMPRESS_WINDOW_REG;
++
++typedef struct _STREAM_BUF_SIZE {
++ ULONG PacketSize:3;
++ ULONG RingBufNum:2;
++ ULONG Unused1:11;
++ ULONG SkipHighMBThres:7;
++ ULONG SkipTestMode:2;
++ ULONG Unused2:7;
++} STREAM_BUF_SIZE;
++
++typedef union _U_STREAM_BUF {
++ ULONG Value;
++ STREAM_BUF_SIZE StreamBufSize;
++} U_STREAM_BUF;
++
++
++typedef struct _COMPRESS_CTL_REG {
++ ULONG JPEGOnly:1; /* True: Jpeg Only mode(Disable VQ), False:Jpeg and VQ mix mode */
++ ULONG En4VQ:1; /* True: 1, 2, 4 color mode, False: 1,2 color mode */
++ ULONG CodecMode:1; /* High and best Quantization encoding/decoding setting*/
++ ULONG DualQuality:1;
++ ULONG EnBest:1;
++ ULONG EnRC4:1;
++ ULONG NorChromaDCTTable:5;
++ ULONG NorLumaDCTTable:5;
++ ULONG EnHigh:1;
++ ULONG TestCtl:2;
++ ULONG UVFmt:1;
++ ULONG HufTable:2;
++ ULONG AlterValue1:5;
++ ULONG AlterValue2:5;
++} COMPRESS_CTL_REG;
++
++typedef union _U_COMPRESS_CTL {
++ ULONG Value;
++ COMPRESS_CTL_REG CompressCtlReg;
++} U_COMPRESS_CTL;
++
++typedef struct _QUANTI_TABLE_LOW_REG {
++ ULONG ChromaTable:5;
++ ULONG LumaTable:5;
++ ULONG Unused1:22;
++} QUANTI_TABLE_LOW_REG;
++
++typedef union _U_CQUANTI_TABLE_LOW {
++ ULONG Value;
++ QUANTI_TABLE_LOW_REG QTableLowReg;
++} U_QUANTI_TABLE_LOW;
++
++typedef struct _QUANTI_VALUE_REG {
++ ULONG High:15;
++ ULONG Unused1:1;
++ ULONG Best:15;
++ ULONG Unused2:1;
++} QUANTI_VALUE_REG;
++
++typedef union _U_QUANTI_VALUE {
++ ULONG Value;
++ QUANTI_VALUE_REG QValueReg;
++} U_QUANTI_VALUE;
++
++typedef struct _BSD_PARAM_REG {
++ ULONG HighThres:8;
++ ULONG LowThres:8;
++ ULONG HighCount:6;
++ ULONG Unused1:2;
++ ULONG LowCount:6;
++ ULONG Unused2:2;
++} BSD_PARAM_REG;
++
++typedef union _U_BSD_PARAM {
++ ULONG Value;
++ BSD_PARAM_REG BSDParamReg;
++} U_BSD_PARAM;
++
++typedef struct _VIDEO_INFO {
++ BYTE ExtADCAct; /* read from modection register */
++ BYTE EnableRC4;
++ BYTE DownScalingMethod;
++ USHORT AnalogDifferentialThreshold; /* BCD tolerance */
++ USHORT DigitalDifferentialThreshold; /* BCD tolerance */
++ USHORT DstWidth;
++ USHORT DstHeight;
++ USHORT SrcWidth;
++ USHORT SrcHeight;
++ BYTE HighLumaTable; /* if High and best Jpeg codec enable, use HighLumaTable and HighChromaTable, otherwise HighDeQuantiValue and BestDequantiValue*/
++ BYTE HighChromaTable;
++ BYTE HighDeQuantiValue;
++ BYTE BestDequantiValue;
++ U_SEQ_CTL uSeqCtlReg;
++ U_CTL_REG uCtlReg;
++ U_BCD_CTL uBCDCtlReg;
++ U_STREAM_BUF uStreamBufSize;
++ U_COMPRESS_CTL uCompressCtlReg;
++ U_QUANTI_TABLE_LOW uQTableLowReg;
++ U_QUANTI_VALUE uQValueReg;
++ U_BSD_PARAM uBSDParamReg;
++} VIDEO_INFO, *PVIDEO_INFO ;
++
++typedef struct _VIDEOM_SEQ_CTL_REG {
++ ULONG Unused1:1; //Bit 0
++ ULONG Unused2:1; //Bit 1
++ ULONG Unused3:1; //Bit 2
++ ULONG StreamMode:1; //Bit 3
++ ULONG Unused4:1; //Bit 4
++ ULONG CodecAutoMode:1; //Bit 5
++ ULONG Unused6:1; //Bit 6
++ ULONG Unused7:1; //Bit 7
++ ULONG SrcSel:1; //Bit 8
++ ULONG Unused9:1; //Bit 9
++ ULONG DataType:2; //Bit[11:10]
++ ULONG Unused12:20;
++} VIDEOM_SEQ_CTL_REG;
++
++typedef union _U_VIDEOM_SEQ_CTL {
++ ULONG Value;
++ VIDEOM_SEQ_CTL_REG SeqCtlReg;
++} U_VIDEOM_SEQ_CTL;
++
++typedef struct _VIDEOM_INFO {
++ BYTE DownScalingMethod;
++ USHORT AnalogDifferentialThreshold; /* BCD tolerance */
++ USHORT DigitalDifferentialThreshold; /* BCD tolerance */
++ USHORT DstWidth;
++ USHORT DstHeight;
++ USHORT SrcWidth;
++ USHORT SrcHeight;
++ BYTE HighLumaTable; /* if High and best Jpeg codec enable, use HighLumaTable and HighChromaTable, otherwise HighDeQuantiValue and BestDequantiValue*/
++ BYTE HighChromaTable;
++ BYTE HighDeQuantiValue;
++ BYTE BestDequantiValue;
++ BYTE PacketSize; //the same as video1 & video2
++ BYTE RingBufNum;
++ BYTE EnableRC4;
++ U_VIDEOM_SEQ_CTL uSeqCtlReg;
++ U_BCD_CTL uBCDCtlReg;
++ U_COMPRESS_CTL uCompressCtlReg;
++ U_QUANTI_TABLE_LOW uQTableLowReg;
++ U_QUANTI_VALUE uQValueReg;
++ U_BSD_PARAM uBSDParamReg;
++} VIDEOM_INFO, *PVIDEOM_INFO ;
++
++typedef struct _VIDEO_MODE_INFO
++{
++ USHORT X;
++ USHORT Y;
++ USHORT ColorDepth;
++ USHORT RefreshRate;
++ BYTE ModeIndex;
++} VIDEO_MODE_INFO, *PVIDEO_MODE_INFO;
++
++#endif
++
+diff --git a/board/aspeed/ast2300/vesa.h b/board/aspeed/ast2300/vesa.h
+new file mode 100755
+index 0000000..69aba90
+--- /dev/null
++++ b/board/aspeed/ast2300/vesa.h
+@@ -0,0 +1,163 @@
++/*
++ * 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 _VESA_H_
++#define _VESA_H_
++
++typedef enum
++{
++ VCLK25_175 = 0x00,
++ VCLK28_322 = 0x01,
++ VCLK31_5 = 0x02,
++ VCLK31_574 = 0x03,
++ VCLK32_76 = 0x04,
++ VCLK33_154 = 0x05,
++ VCLK36 = 0x06,
++ VCLK40 = 0x07,
++ VCLK45_978 = 0x08,
++ VCLK49_5 = 0x09,
++ VCLK50 = 0x0A,
++ VCLK52_95 = 0x0B,
++ VCLK56_25 = 0x0C,
++ VCLK65 = 0x0D,
++ VCLK74_48 = 0x0E,
++ VCLK75 = 0x0F,
++ VCLK78_75 = 0x10,
++ VCLK79_373 = 0x11,
++ VCLK81_624 = 0x12,
++ VCLK83_462 = 0x13,
++ VCLK84_715 = 0x14,
++ VCLK94_5 = 0x15,
++ VCLK106_5 = 0x16,
++ VCLK108 = 0x17,
++ VCLK119 = 0x18,
++ VCLK135 = 0x19,
++ VCLK136_358 = 0x1A,
++ VCLK146_25 = 0x1B,
++ VCLK154 = 0x1C,
++ VCLK157_5 = 0x1D,
++ VCLK162 = 0x1E
++} ePIXEL_CLOCK;
++
++typedef struct {
++ USHORT HorizontalTotal;
++ USHORT VerticalTotal;
++ USHORT HorizontalActive;
++ USHORT VerticalActive;
++ BYTE RefreshRate;
++ double HorizontalFrequency;
++ USHORT HSyncTime;
++ USHORT HBackPorch;
++ USHORT VSyncTime;
++ USHORT VBackPorch;
++ USHORT HLeftBorder;
++ USHORT HRightBorder;
++ USHORT VBottomBorder;
++ USHORT VTopBorder;
++ USHORT PixelClock;
++ BOOL HorPolarity;
++ BOOL VerPolarity;
++ BYTE ADCIndex1;
++ BYTE ADCIndex2;
++ BYTE ADCIndex3;
++ BYTE ADCIndex5;
++ BYTE ADCIndex6;
++ BYTE ADCIndex7;
++ BYTE ADCIndex8;
++ BYTE ADCIndex9;
++ BYTE ADCIndexA;
++ BYTE ADCIndexF;
++ BYTE ADCIndex15;
++ int HorizontalShift;
++ int VerticalShift;
++} VESA_MODE;
++
++#define HOR_POSITIVE 0
++#define HOR_NEGATIVE 1
++#define VER_POSITIVE 0
++#define VER_NEGATIVE 1
++
++#ifdef VESA_GLOBALS
++
++// Note: Modified for modes which have border issue
++VESA_MODE vModeTable[] = {
++////////////////////////// 60Hz mode
++// 720x480 done
++ {1056, 497, 720, 480, 60, 29.900, 88, 104, 3, 13, 0, 0, 0, 0, VCLK31_574, HOR_NEGATIVE, VER_NEGATIVE, 0x41, 0xF0, 0x48, 0x05, 0x20, 0x58, 0x60, 0x60, 0x60, 0x5E, 0xFE, 6, 2},
++// 848x480 done
++ {1064, 517, 848, 480, 60, 31.160, 88, 91, 3, 26, 0, 0, 0, 0, VCLK33_154, HOR_NEGATIVE, VER_NEGATIVE, 0x42, 0x70, 0x48, 0x05, 0x20, 0x58, 0x60, 0x60, 0x60, 0x5E, 0xFE, 6, 2},
++ {800, 525, 640, 480, 60, 31.469, 96, 40, 2, 25, 1, 1, 8, 8, VCLK25_175, HOR_NEGATIVE, VER_NEGATIVE, 0x31, 0xF0, 0x48, 0x05, 0x20, 0x60, 0x60, 0x60, 0x60, 0x5E, 0xFE, 6, 2},
++// 720x576
++ {912, 597, 720, 576, 60, 35.920, 72, 88, 3, 17, 0, 0, 0, 0, VCLK32_76, HOR_NEGATIVE, VER_NEGATIVE, 0x38, 0xF0, 0x48, 0x05, 0x20, 0x48, 0x60, 0x60, 0x60, 0x5E, 0xFE, 6, 2},
++// 960x600 GTF done
++ {1232, 622, 960, 600, 60, 37.320, 96, 136, 3, 18, 0, 0, 0, 0, VCLK45_978, HOR_NEGATIVE, VER_NEGATIVE, 0x4C, 0xF0, 0x60, 0x05, 0x20, 0x60, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {1056, 628, 800, 600, 60, 37.879, 128, 88, 4, 23, 0, 0, 0, 0, VCLK40, HOR_POSITIVE, VER_POSITIVE, 0x41, 0xF0, 0x60, 0x05, 0x20, 0x80, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++// 1088x612 GTF done
++ {1392, 634, 1088, 612, 60, 38.04, 112, 152, 3, 18, 0, 0, 0, 0, VCLK52_95, HOR_NEGATIVE, VER_NEGATIVE, 0x56, 0xF0, 0x60, 0x05, 0x20, 0x70, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++// 1280x720 GTF done
++ {1664, 746, 1280, 720, 60, 44.760, 136, 192, 3, 22, 0, 0, 0, 0, VCLK74_48, HOR_NEGATIVE, VER_NEGATIVE, 0x67, 0xF0, 0xA8, 0x05, 0x20, 0x88, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++// 1360x768 GTF done
++ {1776, 795, 1360, 768, 60, 47.700, 144, 208, 3, 23, 0, 0, 0, 0, VCLK84_715, HOR_NEGATIVE, VER_NEGATIVE, 0x6E, 0xF0, 0xA8, 0x05, 0x20, 0x90, 0x60, 0x60, 0x60, 0x5E, 0xFE, 7, 1},
++// 1280x768 done
++ {1664, 798, 1280, 768, 60, 47.700, 128, 184, 7, 20, 0, 0, 0, 0, VCLK79_373, HOR_NEGATIVE, VER_NEGATIVE, 0x67, 0xF0, 0xA8, 0x05, 0x20, 0x80, 0x60, 0x60, 0x60, 0x5E, 0xFE, 7, 1},
++ {1344, 806, 1024, 768, 60, 48.363, 136, 160, 6, 29, 0, 0, 0, 0, VCLK65, HOR_NEGATIVE, VER_NEGATIVE, 0x53, 0xF0, 0xA8, 0x05, 0x20, 0x88, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 7},
++// 1280x800 GTF done
++ {1680, 828, 1280, 800, 60, 49.680, 136, 200, 3, 24, 0, 0, 0, 0, VCLK83_462, HOR_NEGATIVE, VER_NEGATIVE, 0x68, 0xF0, 0xA8, 0x05, 0x20, 0x88, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++// 1152x864 GTF done
++ {1520, 895, 1152, 864, 60, 53.700, 120, 184, 3, 27, 0, 0, 0, 0, VCLK81_624, HOR_NEGATIVE, VER_NEGATIVE, 0x5E, 0xF0, 0xA8, 0x05, 0x20, 0x78, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++// 1600x900 GTF done
++ {2128, 932, 1600, 900, 60, 55.920, 168, 264, 3, 28, 0, 0, 0, 0, VCLK119, HOR_NEGATIVE, VER_NEGATIVE, 0x84, 0xF0, 0xA8, 0x05, 0x20, 0xA8, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++// 1440X900 CVT done
++ {1904, 933, 1440, 900, 60, 55.935, 152, 232, 6, 25, 0, 0, 0, 0, VCLK106_5, HOR_NEGATIVE, VER_POSITIVE, 0x76, 0xF0, 0xA8, 0x05, 0x20, 0x96, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {1800, 1000, 1280, 960, 60, 60.000, 112, 312, 3, 36, 0, 0, 0, 0, VCLK108, HOR_POSITIVE, VER_POSITIVE, 0x70, 0x70, 0xA8, 0x05, 0x20, 0x70, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++// 1600x1024 GTF done
++ {2144, 1060, 1600, 1024, 60, 63.600, 168, 272, 3, 32, 0, 0, 0, 0, VCLK136_358, HOR_NEGATIVE, VER_NEGATIVE, 0x85, 0xF0, 0xE8, 0x05, 0x20, 0xA8, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {1688, 1066, 1280, 1024, 60, 63.981, 112, 248, 3, 38, 0, 0, 0, 0, VCLK108, HOR_POSITIVE, VER_POSITIVE, 0x69, 0x70, 0xA8, 0x05, 0x20, 0x70, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++// 1680X1050 CVT done Reduced Blanking
++ {1840, 1080, 1680, 1050, 60, 64.674, 32, 80, 6, 21, 0, 0, 0, 0, VCLK119, HOR_POSITIVE, VER_NEGATIVE, 0x72, 0xF0, 0xA8, 0x05, 0x20, 0x20, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++// 1920X1200 CVT done Reduced Blanking
++ {2080, 1235, 1920, 1200, 60, 74.038, 32, 80, 6, 26, 0, 0, 0, 0, VCLK154, HOR_POSITIVE, VER_NEGATIVE, 0x81, 0xF0, 0xA8, 0x05, 0x20, 0x20, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ //{2160, 1250, 1600, 1200, 60,75.000, 192, 304, 3, 46, 0, 0, 0, 0, VCLK162, HOR_POSITIVE, VER_POSITIVE},
++ {2160, 1248, 1600, 1200, 60, 75.000, 192, 304, 3, 46, 0, 0, 0, 0, VCLK162, HOR_POSITIVE, VER_POSITIVE, 0x86, 0xF0, 0xE8, 0x05, 0x20, 0xC0, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++
++////////////////////// Not 60Hz mode
++ {900, 449, 720, 400, 70, 31.469, 108, 45, 2, 25, 1, 1, 8, 8, 0, HOR_NEGATIVE, VER_NEGATIVE, 0x38, 0x30, 0x48, 0x05, 0x20, 0x6C, 0x60, 0x60, 0x60, 0x5E, 0xFE, 6, 1},
++ {832, 520, 640, 480, 72, 37.861, 40, 120, 3, 20, 1, 1, 8, 8, 0, HOR_NEGATIVE, VER_NEGATIVE, 0x33, 0xF0, 0x48, 0x05, 0x20, 0x28, 0x60, 0x60, 0x60, 0x5E, 0xFE, 6, 3},
++ {840, 500, 640, 480, 75, 37.500, 64, 120, 3, 16, 0, 0, 0, 0, 0, HOR_NEGATIVE, VER_NEGATIVE, 0x34, 0x70, 0x48, 0x05, 0x20, 0x40, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 3},
++ {832, 509, 640, 480, 85, 43.269, 56, 80, 3, 25, 0, 0, 0, 0, 0, HOR_NEGATIVE, VER_NEGATIVE, 0x33, 0xF0, 0x48, 0x05, 0x20, 0x38, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 3},
++ {1024, 625, 800, 600, 56, 35.156, 72, 128, 2, 22, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x3F, 0xF0, 0x60, 0x05, 0x20, 0x48, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {1040, 666, 800, 600, 72, 48.077, 120, 64, 6, 23, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x40, 0xF0, 0x60, 0x05, 0x20, 0x78, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {1056, 625, 800, 600, 75, 46.875, 80, 160, 3, 21, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x41, 0xF0, 0x60, 0x05, 0x20, 0x50, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {1048, 631, 800, 600, 85, 53.674, 64, 152, 3, 27, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x41, 0x70, 0x60, 0x05, 0x20, 0x40, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {1328, 806, 1024, 768, 70, 56.476, 136, 144, 6, 29, 0, 0, 0, 0, 0, HOR_NEGATIVE, VER_NEGATIVE, 0x52, 0xF0, 0xA8, 0x05, 0x20, 0x88, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 7},
++ {1312, 800, 1024, 768, 75, 60.023, 96, 176, 3, 28, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x51, 0xF0, 0xA8, 0x05, 0x20, 0x60, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 1},
++ {1376, 808, 1024, 768, 85, 68.677, 96, 208, 3, 36, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x55, 0xF0, 0xA8, 0x05, 0x20, 0x60, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 1},
++ {1600, 900, 1152, 864, 75, 67.500, 128, 256, 3, 32, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x63, 0xF0, 0xA8, 0x05, 0x20, 0x80, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {1728, 1011, 1280, 960, 85, 85.938, 160, 224, 3, 47, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x6B, 0xF0, 0xA8, 0x05, 0x20, 0xA0, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {1688, 1066, 1280, 1024, 75, 79.976, 144, 248, 3, 38, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x69, 0x70, 0xE8, 0x05, 0x20, 0x90, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {1728, 1072, 1280, 1024, 85, 91.146, 160, 224, 3, 44, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x6B, 0xF0, 0xA8, 0x05, 0x20, 0xA0, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {2160, 1250, 1600, 1200, 65, 81.250, 192, 304, 3, 46, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x86, 0xF0, 0xA8, 0x05, 0x20, 0xC0, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {2160, 1250, 1600, 1200, 70, 87.500, 192, 304, 3, 46, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x86, 0xF0, 0xA8, 0x05, 0x20, 0xC0, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {2160, 1250, 1600, 1200, 75, 93.750, 192, 304, 3, 46, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x86, 0xF0, 0xA8, 0x05, 0x20, 0xC0, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {2160, 1250, 1600, 1200, 85, 106.250,192, 304, 3, 46, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x86, 0xF0, 0xA8, 0x05, 0x20, 0xC0, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0}
++};
++
++USHORT ModeNumberCount = sizeof (vModeTable) / sizeof (VESA_MODE);
++USHORT Mode60HZCount = 21;
++
++#else /* NOT VESA_GLOBALS */
++extern VESA_MODE vModeTable[];
++extern USHORT ModeNumberCount;
++extern USHORT Mode60HZCount;
++#endif
++
++#endif /* _VESA_H_ */
++
++
+diff --git a/board/aspeed/ast2300/vfun.c b/board/aspeed/ast2300/vfun.c
+new file mode 100755
+index 0000000..f707e80
+--- /dev/null
++++ b/board/aspeed/ast2300/vfun.c
+@@ -0,0 +1,545 @@
++/*
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#define BUF_GLOBALS
++#include "type.h"
++#include "vdef.h"
++#include "vreg.h"
++#include "crt.h"
++#include "vfun.h"
++
++ULONG UnlockSCURegHost(ULONG MMIOBase, ULONG Key)
++{
++ WriteMemoryLongHost(SCU_BASE, SCU_PROTECT_REG, Key);
++ return ReadMemoryLongHost(SCU_BASE,SCU_PROTECT_REG);
++}
++
++void ResetVideoHost(void)
++{
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CONTROL_REG, VIDEO_RESET_EN << VIDEO_ENGINE_RESET_BIT, VIDEO_ENGINE_RESET_MASK);
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CONTROL_REG, VIDEO_RESET_OFF << VIDEO_ENGINE_RESET_BIT, VIDEO_ENGINE_RESET_MASK);
++}
++
++void StartModeDetectionTriggerHost(ULONG MMIOBase, ULONG offset)
++{
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, offset, 0, MODE_DETECTION_TRIGGER);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, offset, MODE_DETECTION_TRIGGER, MODE_DETECTION_TRIGGER);
++}
++
++BOOL ReadVideoInterruptHost(ULONG MMIOBase, ULONG value)
++{
++ return ((ReadMemoryLongHost(VIDEO_REG_BASE, VIDEO_INT_CONTROL_READ_REG) & value) ? TRUE : FALSE);
++}
++
++ULONG UnlockVideoRegHost(ULONG MMIOBase, ULONG Key)
++{
++ WriteMemoryLongHost(VIDEO_REG_BASE, KEY_CONTROL_REG, Key);
++ return ReadMemoryLongHost(VIDEO_REG_BASE,KEY_CONTROL_REG);
++}
++
++void StartVideoCaptureTriggerHost(ULONG MMIOBase, ULONG offset)
++{
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, offset, 0, VIDEO_CAPTURE_TRIGGER);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, offset, VIDEO_CAPTURE_TRIGGER, VIDEO_CAPTURE_TRIGGER);
++}
++
++void StartVideoCodecTriggerHost(ULONG MMIOBase, ULONG offset)
++{
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, offset, 0, VIDEO_CODEC_TRIGGER);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, offset, VIDEO_CODEC_TRIGGER, VIDEO_CODEC_TRIGGER);
++}
++
++void StopModeDetectionTriggerHost(ULONG MMIOBase, ULONG offset)
++{
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, offset, 0, MODE_DETECTION_TRIGGER);
++}
++
++void ClearVideoInterruptHost(ULONG MMIOBase, ULONG value)
++{
++ //WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO_INT_CONTROL_CLEAR_REG, value, value);
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO_INT_CONTROL_CLEAR_REG, value);
++}
++
++/* UnLock SCU Host and Reset Engine */
++BOOL CheckOnStartHost(void)
++{
++ int i=0, dwValue=0;
++
++ do
++ {
++ dwValue = UnlockSCURegHost(0, SCU_UNLOCK_KEY);
++ i++;
++ }
++ while ((SCU_WRITE_ENABLE != dwValue) && (i<10));
++
++ //Clear SCU Reset Register
++ WriteMemoryLongHost(SCU_BASE, SCU_CONTROL_REG, 0);
++
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_STOP_REG, (EN_ECLK | EN_V1CLK | EN_V2CLK), (STOP_ECLK_MASK | STOP_V1CLK_MASK | STOP_V2CLK_MASK));
++
++#if defined(CONFIG_AST2300)
++ WriteMemoryLongWithMASKHost(SCU_BASE, (0x90 + SCU_OFFSET), 0x00000020, 0x00000030); //enable 24bits
++ WriteMemoryLongWithMASKHost(SCU_BASE, (0x88 + SCU_OFFSET), 0x000fff00, 0x000fff00); //enable video multi-pins
++#else //AST2100
++ //WriteMemoryLongWithMASKHost(SCU_BASE, SCU_PIN_CTRL1_REG, (VIDEO_PORTA_EN | VIDEO_PORTB_EN | VIDEO_VP1_EN | VIDEO_VP2_EN) ,
++ // (VIDEO_PORTA_MASK | VIDEO_PORTB_MASK | VIDEO_VP1_MASK | VIDEO_VP2_MASK));
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_PIN_CTRL2_REG, (VIDEO_PORTA_SINGLE_EDGE | VIDEO_PORTB_SINGLE_EDGE) ,
++ (VIDEO_PORTA_SINGLE_EDGE_MASK | VIDEO_PORTB_SINGLE_EDGE_MASK));
++#endif
++
++ ResetVideoHost();
++
++ return TRUE;
++}
++
++BOOL CheckOnStartClient(void)
++{
++ int i=0, dwValue=0;
++
++ do
++ {
++ dwValue = UnlockSCURegHost(0, SCU_UNLOCK_KEY);
++ i++;
++ }
++ while ((SCU_WRITE_ENABLE != dwValue) && (i<10));
++
++ //Clear SCU Reset Register
++ WriteMemoryLongClient(SCU_BASE, SCU_CONTROL_REG, 0);
++
++ WriteMemoryLongWithMASKClient(SCU_BASE, SCU_CLOCK_STOP_REG, (EN_ECLK | EN_V1CLK | EN_D1CLK | EN_D2CLK | EN_V2CLK),
++ (STOP_ECLK_MASK | STOP_D1CLK_MASK | STOP_D2CLK_MASK | STOP_V1CLK_MASK | STOP_V2CLK_MASK));
++
++ //WriteMemoryLongWithMASKClient(SCU_BASE, SCU_CLOCK_SELECTION_REG, PORTB_FROM_D2CLK | PORTB_CLOCK_INV_DELAY_3NS | PORTA_CLOCK_INV_DELAY_3NS, PORTB_CLOCK_SEL | PORTB_CLOCK_DELAY_MASK | PORTA_CLOCK_DELAY_MASK);
++ //A1EVA
++ WriteMemoryLongWithMASKClient(SCU_BASE, SCU_CLOCK_SELECTION_REG, (PORTB_FROM_D2CLK | PORTB_CLOCK_INV_DELAY_1NS | PORTA_CLOCK_INV_DELAY_1NS), (PORTB_CLOCK_SEL | PORTB_CLOCK_DELAY_MASK | PORTA_CLOCK_DELAY_MASK));
++ WriteMemoryLongWithMASKClient(SCU_BASE, 0x202C, (0x03<<9), (0x03<<9));
++
++ WriteMemoryLongWithMASKClient(SCU_BASE, SCU_PIN_CTRL1_REG, (VIDEO_PORTA_EN | VIDEO_PORTB_EN | VIDEO_VP1_EN | VIDEO_VP2_EN),
++ (VIDEO_PORTA_MASK | VIDEO_PORTB_MASK | VIDEO_VP1_MASK | VIDEO_VP2_MASK));
++
++#if CONFIG_AST3000
++ WriteMemoryLongWithMASKClient(SCU_BASE, SCU_PIN_CTRL2_REG, (VIDEO_PORTA_DUAL_EDGE | VIDEO_PORTB_DUAL_EDGE),
++ (VIDEO_PORTA_SINGLE_EDGE_MASK | VIDEO_PORTB_SINGLE_EDGE_MASK));
++#else
++ //2100 is single edge
++ WriteMemoryLongWithMASKClient(SCU_BASE, SCU_PIN_CTRL2_REG, (VIDEO_PORTA_SINGLE_EDGE | VIDEO_PORTB_SINGLE_EDGE),
++ (VIDEO_PORTA_SINGLE_EDGE_MASK | VIDEO_PORTB_SINGLE_EDGE_MASK));
++#endif
++
++ WriteMemoryLongWithMASKClient(SCU_BASE, SCU_CLOCK_STOP_REG, (EN_D1CLK | EN_D2CLK), (STOP_D1CLK_MASK | STOP_D2CLK_MASK));
++ WriteMemoryLongWithMASKClient(SCU_BASE, SCU_PIN_CTRL1_REG, VGA_PIN_OFF, VGA_PIN_MASK);
++
++ //ResetVideoHost();
++
++ return TRUE;
++}
++
++ULONG InitializeVideoEngineHost (ULONG MMIOBase,
++ int nVideo,
++ BOOL HorPolarity,
++ BOOL VerPolarity)
++{
++ //ULONG temp, temp1, temp2;
++ ULONG dwRegOffset = nVideo * 0x100;
++ ULONG dwValue;
++ int i;
++
++
++ /* General Video Control */
++ //LineBufEn 0
++ //dwValue = (COMPRESS_MODE << CODEC_DECOMPRESS_MODE_BIT) | DELAY_VSYNC_EN;
++ dwValue = 0;
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO_CONTROL_REG, dwValue);
++ //Video Data Truncation Register
++ WriteMemoryLongHost(VIDEO_REG_BASE, 0x328, 0);
++
++ //D2CLK clock must config according to video's line buffer
++ if (VIDEO1 == nVideo)
++ dwValue = LINE_BUFFER_VIDEO1;
++ else
++ dwValue = LINE_BUFFER_VIDEO2;
++
++ //D2CLK clock must config according to video's line buffer
++ switch (dwValue)
++ {
++ case LINE_BUFFER_OFF:
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_SELECTION_REG, NORMAL_CRT1, D2CLK_CLOCK_SELECTION_MASK);
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_STOP_REG, STOP_D2CLK, STOP_D2CLK_MASK);
++ break;
++ case LINE_BUFFER_VIDEO1:
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_SELECTION_REG, V1CLK_VIDEO1 << D2CLK_CLOCK_SELECTION_BIT, D2CLK_CLOCK_SELECTION_MASK);
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_STOP_REG, EN_D2CLK, STOP_D2CLK_MASK);
++ break;
++ case LINE_BUFFER_VIDEO2:
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_SELECTION_REG, V1CLK_VIDEO2 << D2CLK_CLOCK_SELECTION_BIT, D2CLK_CLOCK_SELECTION_MASK);
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_STOP_REG, EN_D2CLK, STOP_D2CLK_MASK);
++ break;
++ case LINE_BUFFER_VIDEOM:
++ //If select this option, it will config at videoM INIT
++ break;
++ default:
++ break;
++ }
++
++ dwValue = 0;
++ //VR30 now is capture window in the compression
++ dwValue = g_DefHeight << CAPTURE_VER_LINE_BIT |
++ g_DefWidth << CAPTURE_HOR_PIXEL_BIT;
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_CAPTURE_WINDOWS_REG + dwRegOffset, dwValue);
++
++ dwValue = 0;
++ //VR34 now is destionation window in the compression
++ dwValue = g_DefHeight << COMPRESS_VER_LINE_BIT |
++ g_DefWidth << COMPRESS_HOR_PIXEL_BIT;
++
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_WINDOWS_REG + dwRegOffset, dwValue);
++
++ //BitCOUNT according compress data format
++ dwValue = YUV444_MODE;
++ if (YUV444_MODE == dwValue)
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_LINE_OFFSET_REG + dwRegOffset, g_DefWidth * INPUT_BITCOUNT_YUV444, BUF_LINE_OFFSET_MASK);
++ else
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_LINE_OFFSET_REG + dwRegOffset, g_DefWidth * INPUT_BITCOUNT_YUV420, BUF_LINE_OFFSET_MASK);
++
++ // CRC
++ //Disable
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO_CRC_PRIMARY_REG, 0x0);
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO_CRC_SECOND_REG, 0x0);
++
++ /* Sequence Control register */
++ //Oonly Encoder need to set
++ /* Engine Sequence Contol Register */
++ dwValue = (WATCH_DOG_EN << WATCH_DOG_ENABLE_BIT) |
++ VIDEO_CAPTURE_AUTO_MODE |
++ VIDEO_CODEC_AUTO_MODE;
++
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG + dwRegOffset, dwValue);
++
++ /* Control register */
++ dwValue = (HOR_NEGATIVE == HorPolarity) ? NO_INVERSE_POL : INVERSE_POL;
++ dwValue = (((VER_NEGATIVE == VerPolarity) ? NO_INVERSE_POL : INVERSE_POL) << VIDEO_VSYNC_POLARITY_BIT) | dwValue;
++
++ /* HW Recommand*/
++ //dwValue = (TILE_MODE << 9) | dwValue;
++ dwValue = (EXTERNAL_VGA_SOURCE << EXTERNAL_SOURCE_BIT) | dwValue;
++
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_CONTROL_REG + dwRegOffset, dwValue);
++
++ /* BCD register */
++ //NO BCD
++ dwValue = 0;
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_BCD_CONTROL_REG + dwRegOffset, dwValue);
++
++ /* Stream Buffer Size register */
++ dwValue = (YUV_TEST << SKIP_TEST_MODE_BIT) |
++ (PACKET_SIZE_32KB << STREAM_PACKET_SIZE_BIT) |
++ (PACKETS_8 << RING_BUF_PACKET_NUM_BIT);
++ /* the same with Video1, Video2, and VideoM*/
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_STREAM_BUF_SIZE, dwValue);
++
++ /* Comression control register */
++ dwValue = (USE_UV_CIR656 << UV_CIR656_FORMAT_BIT)|
++ (JPEG_MIX_MODE << JPEG_ONLY_BIT)|
++ (VQ_4_COLOR_MODE << VQ_4_COLOR_BIT)|
++ (QUANTI_CODEC_MODE << QUALITY_CODEC_SETTING_BIT)|
++ (7 << NORMAL_QUANTI_CHROMI_TABLE_BIT) |
++ (23 << NORMAL_QUANTI_LUMI_TABLE_BIT);
++
++ //Video2 have same value as video1
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_CONTROL_REG, dwValue);
++
++ /* JPEG Quantization Table register */
++ dwValue = 0;
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_QUANTI_TABLE_LOW_REG, dwValue);
++
++ /* Quantization value register */
++ //Video2 have same value as video1
++ dwValue = 0;
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_QUANTI_VALUE_REG, dwValue);
++
++ //Video BSD Parameter Register
++ //Video2 have same value as video1
++ dwValue = 0;
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_BSD_PARA_REG, dwValue);
++
++ //no scale
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_SCALE_FACTOR_REG, 0x10001000);
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_SCALE_FACTOR_PARAMETER0_REG, 0x00200000);
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_SCALE_FACTOR_PARAMETER1_REG, 0x00200000);
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_SCALE_FACTOR_PARAMETER2_REG, 0x00200000);
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_SCALE_FACTOR_PARAMETER3_REG, 0x00200000);
++ return TRUE;
++}
++
++ULONG InitializeVideoEngineClient (ULONG MMIOBase,
++ int nVideo)
++{
++ //ULONG temp, temp1, temp2;
++ ULONG dwRegOffset = nVideo * 0x100;
++ ULONG dwValue;
++ int i;
++
++
++ /* General Video Control */
++ //LineBufEn 0
++ dwValue = (DECOMPRESS_MODE << CODEC_DECOMPRESS_MODE_BIT);
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO_CONTROL_REG, dwValue);
++ //Video Data Truncation Register
++ WriteMemoryLongHost(VIDEO_REG_BASE, 0x328, 0);
++
++ //VR30 now is capture window in the compression
++ dwValue = g_DefHeight << CAPTURE_VER_LINE_BIT |
++ g_DefWidth << CAPTURE_HOR_PIXEL_BIT;
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_CAPTURE_WINDOWS_REG + dwRegOffset, dwValue, CAPTURE_VER_LINE_MASK | CAPTURE_HOR_PIXEL_MASK);
++
++ //VR34 now is destionation window in the compression
++ dwValue = g_DefHeight << COMPRESS_VER_LINE_BIT |
++ g_DefWidth << COMPRESS_HOR_PIXEL_BIT;
++
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_WINDOWS_REG + dwRegOffset, dwValue, COMPRESS_VER_LINE_MASK | COMPRESS_HOR_PIXEL_MASK);
++
++ //BitCOUNT according compress data format
++ dwValue = YUV444_MODE;
++ if (YUV444_MODE == dwValue)
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_LINE_OFFSET_REG + dwRegOffset, g_DefWidth * INPUT_BITCOUNT_YUV444, BUF_LINE_OFFSET_MASK);
++ else
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_LINE_OFFSET_REG + dwRegOffset, g_DefWidth * INPUT_BITCOUNT_YUV420, BUF_LINE_OFFSET_MASK);
++
++ // CRC
++ //Disable
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO_CRC_PRIMARY_REG, 0x0);
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO_CRC_SECOND_REG, 0x0);
++
++ /* Sequence Control register */
++ //Oonly Encoder need to set
++ /* Engine Sequence Contol Register */
++ dwValue = VIDEO_CAPTURE_AUTO_MODE |
++ VIDEO_CODEC_AUTO_MODE;
++
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG + dwRegOffset, dwValue);
++
++ /* Control register */
++ /* HW Recommand*/
++ dwValue = (TILE_MODE << 9);
++
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_CONTROL_REG + dwRegOffset, dwValue);
++
++ /* BCD register */
++ //NO BCD
++ dwValue = 0;
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_BCD_CONTROL_REG + dwRegOffset, dwValue);
++
++ /* Stream Buffer Size register */
++ dwValue = (YUV_TEST << SKIP_TEST_MODE_BIT) |
++ (PACKET_SIZE_32KB << STREAM_PACKET_SIZE_BIT) |
++ (PACKETS_8 << RING_BUF_PACKET_NUM_BIT);
++ /* the same with Video1, Video2, and VideoM*/
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_STREAM_BUF_SIZE, dwValue);
++
++
++ /* Comression control register */
++ dwValue = (USE_UV_CIR656 << UV_CIR656_FORMAT_BIT)|
++ (JPEG_MIX_MODE << JPEG_ONLY_BIT)|
++ (VQ_4_COLOR_MODE << VQ_4_COLOR_BIT)|
++ (QUANTI_CODEC_MODE << QUALITY_CODEC_SETTING_BIT)|
++ (7 << NORMAL_QUANTI_CHROMI_TABLE_BIT) |
++ (23 << NORMAL_QUANTI_LUMI_TABLE_BIT);
++
++ //Video2 have same value as video1
++ if (VIDEO1 == nVideo)
++ {
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_CONTROL_REG, dwValue);
++ }
++ else
++ {
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEOM_COMPRESS_CONTROL_REG, dwValue);
++ }
++
++ /* JPEG Quantization Table register */
++ dwValue = 0;
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_QUANTI_TABLE_LOW_REG, dwValue);
++
++ /* Quantization value register */
++ //Video2 have same value as video1
++ dwValue = 0;
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_QUANTI_VALUE_REG, dwValue);
++
++ //Video BSD Parameter Register
++ //Video2 have same value as video1
++ dwValue = 0;
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_BSD_PARA_REG, dwValue);
++
++ return TRUE;
++}
++
++BYTE GetI2CRegClient(ULONG MMIOBase,
++ BYTE DeviceSelect,
++ BYTE DeviceAddress,
++ BYTE RegisterIndex)
++{
++ BYTE Data;
++ ULONG Status;
++
++// Reset
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x00, 0);
++// Set AC Timing and Speed
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x04, AC_TIMING);
++// Lower Speed
++// WriteMemoryLongWithANDData (VideoEngineInfo->VGAPCIInfo.ulMMIOBaseAddress, I2C_BASE + DeviceSelect * 0x40 + 0x04, 0, 0x33317805);
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x08, 0);
++// Clear Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF);
++// Enable Master Mode
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x00, 1);
++// Enable Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x0C, 0xAF);
++// BYTE I2C Mode
++// Start and Send Device Address
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20, DeviceAddress);
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x3);
++// Wait TX ACK
++ do {
++ Status = ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x03;
++ } while (Status != 1);
++// Clear Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF);
++// Send Device Register Index
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20, RegisterIndex);
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x2);
++// Wait Tx ACK
++ do {
++ Status = ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x03;
++ } while (Status != 1);
++// Clear Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF);
++// Start, Send Device Address + 1(Read Mode), Receive Data
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20, DeviceAddress + 1);
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x1B);
++// Wait Rx Done
++ do {
++ Status = (ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x04) >> 2;
++ } while (Status != 1);
++// Clear Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF);
++
++// Enable STOP Interrupt
++ WriteMemoryLongWithMASKClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x0C, 0x10, 0x10);
++// Issue STOP Command
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x20);
++// Wait STOP
++ do {
++ Status = (ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x10) >> 4;
++ } while (Status != 1);
++// Disable STOP Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x0C, 0x10);
++// Clear Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF);
++// Read Received Data
++ Data = (BYTE)((ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20) & 0xFF00) >> 8);
++
++ return Data;
++}
++
++ULONG SetI2CRegClient(ULONG MMIOBase,
++ BYTE DeviceSelect,
++ BYTE DeviceAddress,
++ BYTE RegisterIndex,
++ BYTE RegisterValue)
++{
++ ULONG Status;
++ ULONG Count = 0;
++
++// Reset
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x00, 0);
++// Set Speed
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x04, AC_TIMING);
++// Lower Speed
++// WriteMemoryLongWithANDData (VideoEngineInfo->VGAPCIInfo.ulMMIOBaseAddress, I2C_BASE + DeviceSelect * 0x40 + 0x04, 0, 0x33317805);
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x08, 0);
++// Clear Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF);
++// Enable Master Mode
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x00, 1);
++// Enable Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x0C, 0xAF);
++// BYTE I2C Mode
++// Start and Send Device Address
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20, DeviceAddress);
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x3);
++// Wait Tx ACK
++ do {
++ Count++;
++ Status = ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x03;
++
++ if (2 == Status)
++ {
++ //Clear Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF);
++ //Re-Send Start and Send Device Address while NACK return
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20, DeviceAddress);
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x3);
++ }
++ //else
++ {
++ if (Count > LOOP_COUNT) {
++ return CAN_NOT_FIND_DEVICE;
++ }
++ }
++ } while (Status != 1);
++ Count = 0;
++// Clear Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF);
++// Send Device Register Index
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20, RegisterIndex);
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x2);
++// Wait Tx ACK
++ do {
++ Count++;
++ Status = ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x03;
++ if (Count > LOOP_COUNT) {
++ return CAN_NOT_FIND_DEVICE;
++ }
++ } while (Status != 1);
++ Count = 0;
++// Clear Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF);
++// Send Device Register Value and Stop
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20, RegisterValue);
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x2);
++// Wait Tx ACK
++ do {
++ Count++;
++ Status = ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x03;
++ if (Count > LOOP_COUNT) {
++ return CAN_NOT_FIND_DEVICE;
++ }
++ } while (Status != 1);
++ Count = 0;
++// Clear Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF);
++// Enable STOP Interrupt
++ WriteMemoryLongWithMASKClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x0C, 0x10, 0x10);
++// Issue STOP Command
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x20);
++// Wait STOP
++ do {
++ Count++;
++ Status = (ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x10) >> 4;
++ if (Count > LOOP_COUNT) {
++ return CAN_NOT_FIND_DEVICE;
++ }
++ } while (Status != 1);
++// Disable STOP Interrupt
++ WriteMemoryLongWithMASKClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x0C, 0, 0x10);
++// Clear Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF);
++
++ return SET_I2C_DONE;
++}
+diff --git a/board/aspeed/ast2300/vfun.h b/board/aspeed/ast2300/vfun.h
+new file mode 100755
+index 0000000..90f9ec4
+--- /dev/null
++++ b/board/aspeed/ast2300/vfun.h
+@@ -0,0 +1,79 @@
++/*
++ * 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 _VFUN_H_
++#define _VFUN_H_
++
++//#define vBufAlign(x) ((x + 0x0000007F) & 0xFFFFFF80) //128 byte alignment
++#define vBufAlign(x) ((x + 0x000003FF) & 0xFFFFFC00) //128 byte alignment
++#define vBufAlign2(x) ((x + 0x0000FFFF) & 0xFFFF0000) //128 byte alignment
++#define v16byteAlign(x) ((x + 0x0000000F) & 0xFFFFFFF0)
++#define vBuf_ALIGNMENT 128
++
++#define HOST_TOTAL_SIZE 0x8000000 /* 128M */
++#define STATION_TOTAL_SIZE 0xF800000 /* 120M */
++
++#define VIDEO_SOURCE_SIZE 0x200000 /* 800X600X4 = 0x1D4C00 */
++#define VIDEO_MAX_STREAM_SIZE 0x400000 /* 32X128K = 0x400000 */
++#define VIDEO_FLAG_SIZE 0x5000 /* 1920X1200/128 = 0x4650*/
++#define VIDEO_CRC_SIZE 0x50000 /* 1920/64X1200X8 = 0x46500*/
++
++#define VIDEO1_EN_TOTAL_SIZE (VIDEO_SOURCE_SIZE*2+VIDEO_MAX_STREAM_SIZE+VIDEO_FLAG_SIZE+VIDEO_CRC_SIZE) /* 0x1655000 = about 23M*/
++#define VIDEO2_EN_TOTAL_SIZE VIDEO1_EN_TOTAL_SIZE
++//#define VIDEOM_EN_TOTAL_SIZE (VIDEO_SOURCE_SIZE*2+VIDEO_MAX_STREAM_SIZE+VIDEO_FLAG_SIZE) /* 0x1605000 = about 22.7M */
++//#define VIDEO_HOST_SIZE (VIDEO1_EN_TOTAL_SIZE + VIDEO2_EN_TOTAL_SIZE + VIDEOM_EN_TOTAL_SIZE) /* 0x69922816 = about 70M */
++#define VIDEO_HOST_SIZE (VIDEO1_EN_TOTAL_SIZE + VIDEO2_EN_TOTAL_SIZE) /* NOT NEED VIDEOM */
++
++#define VIDEO1_EN_BASE 0x100000
++#define VIDEO2_EN_BASE (VIDEO1_EN_BASE + VIDEO1_EN_TOTAL_SIZE)
++#define VIDEOM_EN_BASE (VIDEO2_EN_BASE + VIDEO2_EN_TOTAL_SIZE)
++
++#define VIDEO1_DE_TOTAL_SIZE (VIDEO_MAX_STREAM_SIZE + VIDEO_SOURCE_SIZE) /* 0xD00000 = 13M*/
++#define VIDEO2_DE_TOTAL_SIZE (VIDEO1_DE_TOTAL_SIZE)
++#define VIDEO_STATION_SIZE (VIDEO1_DE_TOTAL_SIZE + VIDEO2_DE_TOTAL_SIZE) /* 26M */
++
++#define VIDEO1_DE_BASE VIDEO_HOST_SIZE
++#define VIDEO2_DE_BASE (VIDEO1_DE_BASE + VIDEO1_DE_TOTAL_SIZE)
++#define VIDEO_ALL_SIZE (VIDEO_HOST_SIZE + VIDEO_STATION_SIZE) //Host and Station
++
++#define OutdwmBankModeHost(offset,data) WriteMemoryLongHost(DRAM_BASE,offset,data)
++#define IndwmBankModeHost(offset) ReadMemoryLongHost(DRAM_BASE,offset)
++
++ULONG UnlockVideoRegHost(ULONG MMIOBase, ULONG Key);
++BOOL CheckOnStartHost(void);
++BOOL CheckOnStartClient(void);
++void StartVideoCaptureTriggerHost(ULONG MMIOBase, ULONG offset);
++void StartVideoCaptureTriggerHost(ULONG MMIOBase, ULONG offset);
++void StartVideoCodecTriggerHost(ULONG MMIOBase, ULONG offset);
++ULONG UnlockSCURegHost(ULONG MMIOBase, ULONG Key);
++ULONG UnlockSCURegHost(ULONG MMIOBase, ULONG Key);
++void StartModeDetectionTriggerHost(ULONG MMIOBase, ULONG offset);
++void ClearVideoInterruptHost(ULONG MMIOBase, ULONG value);
++BOOL ReadVideoInterruptHost(ULONG MMIOBase, ULONG value);
++void StopModeDetectionTriggerHost(ULONG MMIOBase, ULONG offset);
++void ResetVideoHost(void);
++ULONG InitializeVideoEngineHost (ULONG MMIOBase,
++ int nVideo,
++ BOOL HorPolarity,
++ BOOL VerPolarity);
++ULONG InitializeVideoEngineClient (ULONG MMIOBase,
++ int nVideo);
++BYTE GetI2CRegClient(ULONG MMIOBase,
++ BYTE DeviceSelect,
++ BYTE DeviceAddress,
++ BYTE RegisterIndex);
++
++ULONG SetI2CRegClient(ULONG MMIOBase,
++ BYTE DeviceSelect,
++ BYTE DeviceAddress,
++ BYTE RegisterIndex,
++ BYTE RegisterValue);
++#endif //_VFUN_H_
++
+diff --git a/board/aspeed/ast2300/vgahw.h b/board/aspeed/ast2300/vgahw.h
+new file mode 100755
+index 0000000..7cbba0d
+--- /dev/null
++++ b/board/aspeed/ast2300/vgahw.h
+@@ -0,0 +1,175 @@
++/*
++ * 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
++ */
++/******************************************************************************
++ * Mode Stuff
++ ******************************************************************************/
++/* Default Settings */
++#define CRT_LOW_THRESHOLD_VALUE 0x12
++#define CRT_HIGH_THRESHOLD_VALUE 0x1E
++
++/* Output Selection */
++#define CRT1 0x00
++#define CRT2 0x01
++#define DVI1 0x10
++#define DVI2 0x11
++#define LVDS1 0x20
++#define LVDS2 0x21
++
++/* Mode Limitation */
++#define MAX_HResolution 1600
++#define MAX_VResolution 1200
++
++/* Std. Table Index Definition */
++#define TextModeIndex 0
++#define EGAModeIndex 1
++#define VGAModeIndex 2
++#define HiCModeIndex 3
++#define TrueCModeIndex 4
++
++/* DCLK Index */
++#define VCLK25_175 0x00
++#define VCLK28_322 0x01
++#define VCLK31_5 0x02
++#define VCLK36 0x03
++#define VCLK40 0x04
++#define VCLK49_5 0x05
++#define VCLK50 0x06
++#define VCLK56_25 0x07
++#define VCLK65 0x08
++#define VCLK75 0x09
++#define VCLK78_75 0x0A
++#define VCLK94_5 0x0B
++#define VCLK108 0x0C
++#define VCLK135 0x0D
++#define VCLK157_5 0x0E
++#define VCLK162 0x0F
++#define VCLK119 0x10
++
++/* Flags Definition */
++#define Charx8Dot 0x00000001
++#define HalfDCLK 0x00000002
++#define DoubleScanMode 0x00000004
++#define LineCompareOff 0x00000008
++#define SyncPP 0x00000000
++#define SyncPN 0x00000040
++#define SyncNP 0x00000080
++#define SyncNN 0x000000C0
++#define HBorder 0x00000020
++#define VBorder 0x00000010
++#define COLORINDEX 0x00000000
++#define MONOINDEX 0x00000100
++
++/* DAC Definition */
++#define DAC_NUM_TEXT 64
++#define DAC_NUM_EGA 64
++#define DAC_NUM_VGA 256
++
++/* AST3000 Reg. Definition */
++#define AST3000_VGAREG_BASE 0x1e6e6000
++#define AST3000_VGA1_CTLREG 0x00
++#define AST3000_VGA1_CTLREG2 0x04
++#define AST3000_VGA1_STATUSREG 0x08
++#define AST3000_VGA1_PLL 0x0C
++#define AST3000_VGA1_HTREG 0x10
++#define AST3000_VGA1_HRREG 0x14
++#define AST3000_VGA1_VTREG 0x18
++#define AST3000_VGA1_VRREG 0x1C
++#define AST3000_VGA1_STARTADDR 0x20
++#define AST3000_VGA1_OFFSETREG 0x24
++#define AST3000_VGA1_THRESHOLD 0x28
++#define AST3000_HWC1_OFFSET 0x30
++#define AST3000_HWC1_XY 0x34
++#define AST3000_HWC1_PBase 0x38
++#define AST3000_OSD1_H 0x40
++#define AST3000_OSD1_V 0x44
++#define AST3000_OSD1_PBase 0x48
++#define AST3000_OSD1_Offset 0x4C
++#define AST3000_OSD1_THRESHOLD 0x50
++
++#define AST3000_VGA2_CTLREG 0x60
++#define AST3000_VGA2_CTLREG2 0x64
++#define AST3000_VGA2_STATUSREG 0x68
++#define AST3000_VGA2_PLL 0x6C
++#define AST3000_VGA2_HTREG 0x70
++#define AST3000_VGA2_HRREG 0x74
++#define AST3000_VGA2_VTREG 0x78
++#define AST3000_VGA2_VRREG 0x7C
++#define AST3000_VGA2_STARTADDR 0x80
++#define AST3000_VGA2_OFFSETREG 0x84
++#define AST3000_VGA2_THRESHOLD 0x88
++#define AST3000_HWC2_OFFSET 0x90
++#define AST3000_HWC2_XY 0x94
++#define AST3000_HWC2_PBase 0x98
++#define AST3000_OSD2_H 0xA0
++#define AST3000_OSD2_V 0xA4
++#define AST3000_OSD2_PBase 0xA8
++#define AST3000_OSD2_Offset 0xAC
++#define AST3000_OSD2_THRESHOLD 0xB0
++
++/* Data Structure */
++typedef struct {
++ UCHAR ModeName[20];
++ USHORT usModeIndex;
++ USHORT usModeID;
++ USHORT usColorIndex;
++ USHORT usRefreshRateIndex;
++ USHORT usWidth;
++ USHORT usHeight;
++ USHORT usBitsPerPlane;
++ USHORT usRefreshRate;
++} ModeInfoStruct;
++
++typedef struct {
++
++ UCHAR MISC;
++ UCHAR SEQ[4];
++ UCHAR CRTC[25];
++ UCHAR AR[20];
++ UCHAR GR[9];
++
++} VBIOS_STDTABLE_STRUCT, *PVBIOS_STDTABLE_STRUCT;
++
++typedef struct {
++
++ ULONG HT;
++ ULONG HDE;
++ ULONG HFP;
++ ULONG HSYNC;
++ ULONG VT;
++ ULONG VDE;
++ ULONG VFP;
++ ULONG VSYNC;
++ ULONG DCLKIndex;
++ ULONG Flags;
++
++ ULONG ulRefreshRate;
++ ULONG ulRefreshRateIndex;
++ ULONG ulModeID;
++
++} VBIOS_ENHTABLE_STRUCT, *PVBIOS_ENHTABLE_STRUCT;
++
++typedef struct {
++ UCHAR Param1;
++ UCHAR Param2;
++ UCHAR Param3;
++} VBIOS_DCLK_INFO, *PVBIOS_DCLK_INFO;
++
++typedef struct {
++ UCHAR DACR;
++ UCHAR DACG;
++ UCHAR DACB;
++} VBIOS_DAC_INFO, *PVBIOS_DAC_INFO;
++
++typedef struct {
++ PVBIOS_STDTABLE_STRUCT pStdTableEntry;
++ PVBIOS_ENHTABLE_STRUCT pEnhTableEntry;
++
++} VBIOS_MODE_INFO, *PVBIOS_MODE_INFO;
+diff --git a/board/aspeed/ast2300/vhace.c b/board/aspeed/ast2300/vhace.c
+new file mode 100755
+index 0000000..d045cbd
+--- /dev/null
++++ b/board/aspeed/ast2300/vhace.c
+@@ -0,0 +1,66 @@
++/*
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#define HASH_GLOBALS
++#include "type.h"
++#include "vdef.h"
++#include "vhace.h"
++#include "vfun.h"
++
++void HashAst3000(ULONG ulLength, ULONG *output, ULONG ulHashMode)
++{
++ ULONG i, ulTemp, ulCommand, ulDigestLength;
++ ULONG ulValue;
++
++ /* Get Info */
++ switch (ulHashMode)
++ {
++ case VHASHMODE_MD5:
++ ulCommand = VHASH_ALG_SELECT_MD5;
++ ulDigestLength = 16;
++ break;
++ case VHASHMODE_SHA1:
++ ulCommand = VHASH_ALG_SELECT_SHA1;
++ ulDigestLength = 20;
++ break;
++ case VHASHMODE_SHA256:
++ ulCommand = VHASH_ALG_SELECT_SHA256;
++ ulDigestLength = 32;
++ break;
++ case VHASHMODE_SHA224:
++ ulCommand = VHASH_ALG_SELECT_SHA224;
++ ulDigestLength = 28;
++ break;
++ }
++
++ /* Init. HW */
++ WriteMemoryLongHost(VHAC_REG_BASE, VREG_HASH_SRC_BASE_OFFSET, g_HashSrcBuffer);
++ WriteMemoryLongHost(VHAC_REG_BASE, VREG_HASH_DST_BASE_OFFSET, g_HashDstBuffer);
++ WriteMemoryLongHost(VHAC_REG_BASE, VREG_HASH_LEN_OFFSET, ulLength);
++
++ /* write src */
++ //already fill in g_VIDEO1_COMPRESS_BUF_ADDR
++
++ /* fire cmd */
++ WriteMemoryLongHost(VHAC_REG_BASE, VREG_HASH_CMD_OFFSET, ulCommand);
++
++ /* get digest */
++ do {
++ ulTemp = ReadMemoryLongHost(VHAC_REG_BASE, VREG_HASH_STATUS_OFFSET);
++ } while (ulTemp & VHASH_BUSY);
++
++ for (i=0; i<ulDigestLength/4; i++)
++ {
++ ulValue = *(((ULONG *)g_HashDstBuffer) + i);
++
++ //output is ULONG pointer
++ *(output + i) = ulValue;
++ }
++}
+diff --git a/board/aspeed/ast2300/vhace.h b/board/aspeed/ast2300/vhace.h
+new file mode 100755
+index 0000000..460989b
+--- /dev/null
++++ b/board/aspeed/ast2300/vhace.h
+@@ -0,0 +1,58 @@
++/*
++ * 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 _VHACE_H_
++#define _VHACE_H_
++
++#define VHASHMODE_MD5 0x00
++#define VHASHMODE_SHA1 0x01
++#define VHASHMODE_SHA256 0x02
++#define VHASHMODE_SHA224 0x03
++
++#define VHASH_ALG_SELECT_MASK 0x70
++#define VHASH_ALG_SELECT_MD5 0x00
++#define VHASH_ALG_SELECT_SHA1 0x20
++#define VHASH_ALG_SELECT_SHA224 0x40
++#define VHASH_ALG_SELECT_SHA256 0x50
++
++#define VHASH_BUSY 0x01
++
++#define VHAC_REG_BASE 0x1e6e0000
++#define VHAC_REG_OFFSET 0x3000
++
++#define VREG_HASH_SRC_BASE_OFFSET (0x20+VHAC_REG_OFFSET)
++#define VREG_HASH_DST_BASE_OFFSET (0x24+VHAC_REG_OFFSET)
++#define VREG_HASH_KEY_BASE_OFFSET (0x28+VHAC_REG_OFFSET)
++#define VREG_HASH_LEN_OFFSET (0x2C+VHAC_REG_OFFSET)
++#define VREG_HASH_CMD_OFFSET (0x30+VHAC_REG_OFFSET)
++
++#define VREG_HASH_STATUS_OFFSET (0x1C+VHAC_REG_OFFSET)
++
++typedef struct
++{
++ int HashMode;
++ int DigestLen;
++} HASH_METHOD;
++
++
++#ifdef HASH_GLOBALS
++#define HASH_EXT
++#else
++#define HASH_EXT extern
++#endif
++
++HASH_EXT HASH_METHOD g_HashMethod;
++HASH_EXT BYTE g_DigestBuf[32];
++HASH_EXT ULONG g_HashSrcBuffer;
++HASH_EXT ULONG g_HashDstBuffer;
++
++void HashAst3000(ULONG ulLength, ULONG *output, ULONG ulHashMode);
++#endif
++
+diff --git a/board/aspeed/ast2300/videotest.c b/board/aspeed/ast2300/videotest.c
+new file mode 100755
+index 0000000..f2e4953
+--- /dev/null
++++ b/board/aspeed/ast2300/videotest.c
+@@ -0,0 +1,779 @@
++/*
++ * 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
++ */
++
++/*
++ * Diagnostics support
++ */
++#include <common.h>
++#include <command.h>
++#include <malloc.h>
++#include <post.h>
++
++#include "slt.h"
++#define WIN_GLOBALS
++#include "type.h"
++#include "vreg.h"
++#define VESA_GLOBALS
++#include "vesa.h"
++#include "vfun.h"
++#include "vdef.h"
++#include "vhace.h"
++#include "crt.h"
++#include "videotest.h"
++
++#define VHASH_ALIGNMENT 16
++#define VHASH_MAX_DST (32+VHASH_ALIGNMENT)
++
++
++#if ((CFG_CMD_SLT & CFG_CMD_VIDEOTEST) && defined(CONFIG_SLT))
++#include "videotest.h"
++
++#define RAND_MAX 32767 //2^16-1
++
++ULONG randSeed = 1;
++
++void srand(ULONG seed)
++{
++ randSeed = seed;
++}
++
++int rand(void)
++{
++ randSeed = randSeed * 214013 + 2531011;
++ return (int)(randSeed >> 17); //32 -15 = 17
++}
++
++//static unsigned char CaptureVideo1Buf1Addr[VIDEO_SOURCE_SIZE], CaptureVideo1Buf2Addr[VIDEO_SOURCE_SIZE], Video1CompressBufAddr[CRYPTO_MAX_CONTEXT];
++ULONG pCaptureVideo1Buf1Addr[VIDEO_SOURCE_SIZE/4], pCaptureVideo1Buf2Addr[VIDEO_SOURCE_SIZE/4], pVideo1CompressBufAddr[VIDEO_MAX_STREAM_SIZE/4], pVideo1FlagBufAddr[VIDEO_FLAG_SIZE];
++ULONG pCaptureVideo2Buf1Addr[VIDEO_SOURCE_SIZE/4], pCaptureVideo2Buf2Addr[VIDEO_SOURCE_SIZE/4], pVideo2CompressBufAddr[VIDEO_MAX_STREAM_SIZE/4], pVideo2FlagBufAddr[VIDEO_FLAG_SIZE];
++
++ULONG pVHashDstBuffer[VHASH_MAX_DST/4];
++
++ULONG pVideo1DecAddr[VIDEO_SOURCE_SIZE/4];
++ULONG pCrt1Addr[VIDEO_SOURCE_SIZE/4];
++//ULONG pCap1Addr[VIDEO_SOURCE_SIZE/4];
++
++BOOL AllocateEncodeBufHost(ULONG MMIOBase, int nVideo)
++{
++ //ULONG Addr;
++ //ULONG dwRegOffset = nVideo * 0x100;
++
++ if (VIDEO1 == nVideo)
++ {
++
++ //Addr = (ULONG)malloc(pVideoInfo->SrcWidth * pVideoInfo->SrcHeight * 4);
++ //pCaptureVideo1Buf1Addr = malloc(VIDEO_SOURCE_SIZE);
++
++ g_CAPTURE_VIDEO1_BUF1_ADDR = vBufAlign((ULONG)pCaptureVideo1Buf1Addr);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_1_ADDR_REG, g_CAPTURE_VIDEO1_BUF1_ADDR, BUF_1_ADDR_MASK);
++
++ //Addr = (ULONG)malloc(pVideoInfo->SrcWidth * pVideoInfo->SrcHeight * 4);
++ //pCaptureVideo1Buf2Addr = malloc(VIDEO_SOURCE_SIZE);
++
++ g_CAPTURE_VIDEO1_BUF2_ADDR = vBufAlign((ULONG)pCaptureVideo1Buf2Addr);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_2_ADDR_REG, g_CAPTURE_VIDEO1_BUF2_ADDR, BUF_2_ADDR_MASK);
++
++ //Addr = (ULONG)malloc(pVideoInfo->uStreamBufSize.StreamBufSize.RingBufNum * pVideoInfo->uStreamBufSize.StreamBufSize.PacketSize)
++ //pVideo1CompressBufAddr = malloc(VIDEO_MAX_STREAM_SIZE);
++ g_VIDEO1_COMPRESS_BUF_ADDR = vBufAlign((ULONG)pVideo1CompressBufAddr);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_BUF_ADDR_REG, g_VIDEO1_COMPRESS_BUF_ADDR, BUF_2_ADDR_MASK);
++
++ //Addr = (ULONG)malloc((pVideoInfo->SrcHeigh/64) * pVideoInfo->SrcWidth * 8);
++ //g_VIDEO1_CRC_BUF_ADDR = vBufAlign((ULONG)malloc(VIDEO_MAX_STREAM_SIZE));
++ //WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_CRC_BUF_ADDR_REG, g_VIDEO1_CRC_BUF_ADDR, BUF_2_ADDR_MASK);
++
++
++ //Addr = (ULONG)malloc(pVideoInfo->SrcHeigh * pVideoInfo->SrcWidth / 128 (/64*4/8));
++ //pVideo1FlagBufAddr = malloc(VIDEO_FLAG_SIZE);
++ g_VIDEO1_FLAG_BUF_ADDR = vBufAlign((ULONG)pVideo1FlagBufAddr);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_FLAG_BUF_ADDR_REG, g_VIDEO1_FLAG_BUF_ADDR, BUF_2_ADDR_MASK);
++ }
++ else if (VIDEO2 == nVideo)
++ {
++ //Addr = (ULONG)malloc(pVideoInfo->SrcWidth * pVideoInfo->SrcHeight * 4);
++ //pCaptureVideo2Buf1Addr = malloc(VIDEO_SOURCE_SIZE);
++ g_CAPTURE_VIDEO2_BUF1_ADDR = vBufAlign((ULONG)pCaptureVideo2Buf1Addr);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO2_BUF_1_ADDR_REG, g_CAPTURE_VIDEO2_BUF1_ADDR, BUF_1_ADDR_MASK);
++
++ //Addr = (ULONG)malloc(pVideoInfo->SrcWidth * pVideoInfo->SrcHeight * 4);
++ //pCaptureVideo2Buf2Addr = malloc(VIDEO_SOURCE_SIZE);
++ g_CAPTURE_VIDEO2_BUF2_ADDR = vBufAlign((ULONG)pCaptureVideo2Buf2Addr);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO2_BUF_2_ADDR_REG, g_CAPTURE_VIDEO2_BUF2_ADDR, BUF_2_ADDR_MASK);
++
++ //Addr = (ULONG)malloc(pVideoInfo->uStreamBufSize.StreamBufSize.RingBufNum * pVideoInfo->uStreamBufSize.StreamBufSize.PacketSize)
++ //pVideo2CompressBufAddr = malloc(VIDEO_MAX_STREAM_SIZE);
++ g_VIDEO2_COMPRESS_BUF_ADDR = vBufAlign((ULONG)pVideo2CompressBufAddr);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO2_COMPRESS_BUF_ADDR_REG, g_VIDEO2_COMPRESS_BUF_ADDR, BUF_2_ADDR_MASK);
++
++ //Addr = (ULONG)malloc((pVideoInfo->SrcHeigh/64) * pVideoInfo->SrcWidth * 8);
++ //g_VIDEO1_CRC_BUF_ADDR = vBufAlign((ULONG)malloc(VIDEO_MAX_STREAM_SIZE));
++ //WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_CRC_BUF_ADDR_REG, g_VIDEO1_CRC_BUF_ADDR, BUF_2_ADDR_MASK);
++
++
++ //Addr = (ULONG)malloc(pVideoInfo->SrcHeigh * pVideoInfo->SrcWidth / 128 (/64*4/8));
++ //pVideo2FlagBufAddr = malloc(VIDEO_FLAG_SIZE);
++ g_VIDEO2_FLAG_BUF_ADDR = vBufAlign((ULONG)pVideo2FlagBufAddr);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO2_FLAG_BUF_ADDR_REG, g_VIDEO2_FLAG_BUF_ADDR, BUF_2_ADDR_MASK);
++ }
++
++}
++
++/********************************************************/
++/* 1. product random data to encode */
++/* 2. use hash to verify encode function */
++/* 3. use encode stream to decompress original data */
++/********************************************************/
++int CodecTest(void)
++{
++ int num, i=0, j=0;
++ ULONG ulTemp = 0, ulTemp2;
++ int dwValue;
++ ULONG ulHWWp;
++ ULONG ulHWPt;
++
++ //max size
++ ULONG tArray[32/4];
++
++ //mode detection
++ BOOL bExternal = TRUE;
++ BOOL bAnalog = TRUE;
++ ULONG Status;
++
++#if defined(CONFIG_AST2300)
++ ULONG ulHashSha1[5] = {0x3f0c2ad6,0xc8eb7074,0xa9929352,0xfcd5b8b0,0x76fa8461};
++ ULONG aHashDecode[5] = {0xb23b62bb,0xd22a602b,0x113038a0,0x7217c6ab,0xcb156f06};
++#else
++ ULONG ulHashSha1[5] = {0x2a19e99f,0x99b1bb2d,0x9ac82862,0x49205e43,0x6bc4b4d7};
++ ULONG aHashDecode[5] = {0x2907a827,0xaf337079,0x47817f1f,0xb0b7cd68,0x8d33bd2};
++#endif
++
++ //Load pattern to src1 & src2 buffer
++ srand(1);
++
++ //Total size : DefWidth*DeHeight*4
++ //rand function: 16 bits one time is equal to 2 bytes
++ //OutdwmBankMode: 32 bits one time is equal to 4 bytes
++ for (i=0; i<g_DefWidth*g_DefHeight*2; i++)
++ {
++ if (i%2)
++ {
++ ulTemp2 = rand();
++ ulTemp = (ulTemp2 << 16) | ulTemp;
++ //WriteMemoryLongHost(DRAM_BASE, g_CAPTURE_VIDEO1_BUF1_ADDR + ((i-1)/2)*4, ulTemp);
++ *(((ULONG *)g_CAPTURE_VIDEO1_BUF1_ADDR) + (i-1)/2) = ulTemp;
++ ulTemp = 0;
++ }
++ else
++ {
++ ulTemp = rand();
++ }
++ }
++
++ /* init encoder engine */
++ InitializeVideoEngineHost (0,
++ VIDEO1,
++ vModeTable[2].HorPolarity,
++ vModeTable[2].VerPolarity);
++
++ /* reset offset pointer register*/
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG, 0, VIDEO_CODEC_TRIGGER | VIDEO_CAPTURE_TRIGGER);
++
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_BUF_READ_OFFSET_REG, 0, COMPRESS_BUF_READ_OFFSET_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_CODEC_OFFSET_READ, 0, BUF_CODEC_OFFSET_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_BUF_PROCESS_OFFSET_REG, 0, COMPRESS_BUF_PROCESS_OFFSET_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_FRAME_END_READ, 0, COMPRESS_FRAME_END_READ_MASK);
++
++ /* start compress stream */
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG, MODE_DETECTION_TRIGGER, MODE_DETECTION_TRIGGER);
++ //Stream mode: set CODEC trigger first
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG, VIDEO_CODEC_TRIGGER, VIDEO_CODEC_TRIGGER);
++
++ //Stream mode: start trigger (only trigger capture bit)
++ StartVideoCaptureTriggerHost(0, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG);
++
++ //stop engine
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG, 0, 0xFF);
++#if defined(CONFIG_AST2300)
++ do { /* wait compress engine idle */
++ ulTemp = ReadMemoryLongHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG);
++ } while (!(ulTemp & 0x40000));
++#endif
++
++ //read 30 times to get HW write pointer
++ for (i=0; i<30000; i++)
++ ulHWWp = ReadMemoryLongHost(VIDEO_REG_BASE, VIDEO1_BUF_CODEC_OFFSET_READ);
++
++ g_HashSrcBuffer = g_VIDEO1_COMPRESS_BUF_ADDR + 128; //skip encode data 128 byte
++ g_HashDstBuffer = v16byteAlign((unsigned long)pVHashDstBuffer);
++ ulTemp = 300;
++
++ //Enable hash clock
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_STOP_REG, EN_HACE, STOP_HACE_MASK);
++ g_HashMethod.HashMode = VHASHMODE_SHA1;
++ g_HashMethod.DigestLen = 20;
++ HashAst3000(ulTemp, tArray, g_HashMethod.HashMode);
++
++ if (strncmp((const char *)tArray, (const char *)ulHashSha1, g_HashMethod.DigestLen))
++ {
++ printf("[VIDEO] Encoder Test: Wrong\n");
++ //ExitVideoTest();
++ return VIDEO_ENCODE_FAIL;
++ }
++ else
++ {
++ printf("[VIDEO] Encoder Test: Pass\n");
++ }
++
++#if 0
++ /******** prepare for next decoding test at the same chip ***********/
++ ResetVideoHost();
++
++ dwValue=0;
++
++ do
++ {
++ dwValue = UnlockVideoRegHost(0, VIDEO_UNLOCK_KEY);
++ i++;
++ }
++ while ((VIDEO_UNLOCK != dwValue) && (i<10));
++
++ if (VIDEO_UNLOCK != dwValue)
++ {
++ printf("[VIDEO] Video register is locked");
++ return VIDEO_UNLOCK_FAIL;
++ }
++
++ // allocate decoding buffer
++ //Use Compress buffer last time, and Don't need to allocate
++ g_VIDEO1_DECODE_BUF_1_ADDR = g_VIDEO1_COMPRESS_BUF_ADDR;
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_1_ADDR_REG, g_VIDEO1_DECODE_BUF_1_ADDR, BUF_1_ADDR_MASK);
++
++ // pVideo1DecAddr = malloc(VIDEO_SOURCE_SIZE);
++ g_VIDEO1_DECOMPRESS_BUF_ADDR = vBufAlign((unsigned long)pVideo1DecAddr);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_BUF_ADDR_REG, g_VIDEO1_DECOMPRESS_BUF_ADDR, COMPRESS_BUF_ADDR_MASK);
++
++ //Addr = (ULONG)malloc(256);
++ //g_VIDEO1_RC4_BUF_ADDR = Addr;
++ //g_VIDEO1_DECODE_RC4_BUF_ADDR = g_VIDEO1_DECOMPRESS_BUF_ADDR + 0x800000; //assume video size is 8MB for umcompressed buf;
++ //WriteMemoryLongWithMASKClient(VIDEO_REG_BASE, VIDEO1_RC4_TABLE_ADDR, g_VIDEO1_DECODE_RC4_BUF_ADDR, RC4_TABLE_ADDR_MASK);
++
++ //HW recommanded value
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_2_ADDR_REG, g_VIDEO1_DECOMPRESS_BUF_ADDR, BUF_2_ADDR_MASK);
++ //WriteMemoryLongWithMASKClient(VIDEO_REG_BASE, VIDEO1_BUF_2_ADDR_REG, 0, BUF_2_ADDR_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_CRC_BUF_ADDR_REG, 0, BUF_2_ADDR_MASK);
++
++ /* init encoder engine */
++ InitializeVideoEngineClient (0, VIDEO1);
++
++ /* reset offset pointer register*/
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG, 0, VIDEO_CODEC_TRIGGER | VIDEO_CAPTURE_TRIGGER);
++
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_BUF_READ_OFFSET_REG, 0, COMPRESS_BUF_READ_OFFSET_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_CODEC_OFFSET_READ, 0, BUF_CODEC_OFFSET_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_BUF_PROCESS_OFFSET_REG, 0, COMPRESS_BUF_PROCESS_OFFSET_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_FRAME_END_READ, 0, COMPRESS_FRAME_END_READ_MASK);
++
++ StartVideoCodecTriggerHost(0, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG);
++
++ //wrtie SW write pointer
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_DECOMPRESS_BUF_PROCESS_OFFSET_REG, ulHWWp, COMPRESS_BUF_READ_OFFSET_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_DECOMPRESS_BUF_WRITE_OFFSET_REG, ulHWWp, COMPRESS_BUF_READ_OFFSET_MASK);
++
++ i = 0;
++
++ do
++ {
++ ulHWPt = ReadMemoryLongHost(VIDEO_REG_BASE, VIDEO1_BUF_CODEC_OFFSET_READ);
++ i++;
++ }while((ulHWPt != ulHWWp) && (i<10000));
++
++ if (10000 > i)
++ {
++ printf("[VIDEO] Decoder Pointer cannot move!!! /n");
++ //ExitVideoTest();
++ return VIDEO_DECODE_FAIL;
++ }
++
++ //8*8 YUVA block
++ for (i=24; i<g_DefWidth*g_DefHeight; i=i+32)
++ {
++ *(((ULONG *)g_VIDEO1_DECOMPRESS_BUF_ADDR) + i) = 0x0;
++ *(((ULONG *)g_VIDEO1_DECOMPRESS_BUF_ADDR) + i+1) = 0x0;
++ }
++
++ g_HashSrcBuffer = g_VIDEO1_DECOMPRESS_BUF_ADDR;
++ //g_HashDstBuffer = VIDEO1_EN_BASE + VIDEO_ALL_SIZE; //config forward
++
++ ulTemp = 300;
++
++ //Enable hash clock
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_STOP_REG, EN_HACE, STOP_HACE_MASK);
++ g_HashMethod.HashMode = VHASHMODE_SHA1;
++ g_HashMethod.DigestLen = 20;
++ HashAst3000(ulTemp, tArray, g_HashMethod.HashMode);
++
++ if (strncmp((const char *)tArray, (const char *)aHashDecode, g_HashMethod.DigestLen))
++ {
++ printf("[VIDEO] Decoder Test: Wrong\n");
++ //ExitVideoTest();
++ return VIDEO_DECODE_FAIL;
++ }
++ else
++ {
++ printf("[VIDEO] Decoder Test: Pass\n");
++ }
++#endif
++
++ return VIDEO_TEST_OK;
++}
++
++/********************************************************/
++/* Only used in the host */
++/* test function: Mode detection and Capture pattern */
++/********************************************************/
++int CapTest(void)
++{
++ ULONG dwValue, Status;
++ int i;
++ BOOL bAnalog;
++ ULONG HStart, HEnd, VStart, VEnd;
++ USHORT usCRTHor, usCRTVer;
++ ULONG ulHor, ulVer;
++ ULONG ulVGABaseAddr, ulCapAddr;
++ ULONG ulFlag;
++
++ printf("\n --------- Mode Detection Test --------- \n");
++ //clear clear register
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_CONTROL_REG, 0);
++ dwValue = ReadMemoryLongHost(VIDEO_REG_BASE, VIDEO1_CONTROL_REG);
++
++ // Note: Current mode detection procedure has to set signal input 1st
++ //Note: Clear and enable interrupt Encode
++ ClearVideoInterruptHost(0, VIDEO1_MODE_DETECTION_READY_CLEAR);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO_INT_CONTROL_EN_REG, VIDEO1_MODE_DETECTION_READY_INT_EN, VIDEO1_MODE_DETECTION_READY_INT_EN);
++ // Set input signal
++ dwValue |= EXTERNAL_VGA_SOURCE;
++
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_CONTROL_REG, (dwValue <<EXTERNAL_SOURCE_BIT), EXTERNAL_SOURCE_MASK);
++
++// Set H/V stable maximum
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO_MODE_DETECTION_PARAM_REG, (MODEDETECTION_VERTICAL_STABLE_MAXIMUM << VER_STABLE_MAX_BIT), 0x000F0000);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO_MODE_DETECTION_PARAM_REG, (MODEDETECTION_HORIZONTAL_STABLE_MAXIMUM << HOR_STABLE_MAX_BIT), HOR_STABLE_MAX_BIT_MASK);
++// Set H/V stable threshold
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO_MODE_DETECTION_PARAM_REG, (MODEDETECTION_VERTICAL_STABLE_THRESHOLD << VER_STABLE_THRES_BIT), VER_STABLE_THRES_BIT_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO_MODE_DETECTION_PARAM_REG, (MODEDETECTION_HORIZONTAL_STABLE_THRESHOLD << HOR_STABLE_THRES_BIT), HOR_STABLE_THRES_BIT_MASK);
++
++ //Trigger mode detection
++ // turn off WATCH_DOG first
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG, (WATCH_DOG_OFF << WATCH_DOG_ENABLE_BIT), WATCH_DOG_EN_MASK);
++
++ // Note: Clear mode detection ready interrupt
++ //ClearVideoInterrupt(MMIOBase, MODE_DETECTION_READY_CLEAR);
++ StartModeDetectionTriggerHost(0, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG);
++
++
++// Note: Polling mode detection ready interrupt
++ //it sometime take a long time, especially during change mode,
++ //so the loop count must be big, or you can't pull it by timer
++ i = 0;
++ do {
++
++ Status = ReadVideoInterruptHost(0, VIDEO1_MODE_DETECTION_READY_READ);
++ i++;
++ } while ((!Status) & (i<500000));
++
++ if (!Status)
++ {
++ printf("[VIDEO] Mode detection error\n");
++ //ExitVideoTest();
++ return VIDEO_TEST_FAIL;
++ }
++
++ HStart = (ReadMemoryLongHost(VIDEO_REG_BASE, VIDE1_MODE_DETECTION_EDGE_H_REG) & LEFT_EDGE_LOCATION_MASK) >> LEFT_EDGE_LOCATION_BIT;
++ HEnd = (ReadMemoryLongHost(VIDEO_REG_BASE, VIDE1_MODE_DETECTION_EDGE_H_REG) & RIGHT_EDGE_LOCATION_MASK) >> RIGHT_EDGE_LOCATION_BIT;
++
++ VStart = (ReadMemoryLongHost(VIDEO_REG_BASE, VIDE1_MODE_DETECTION_EDGE_V_REG) & TOP_EDGE_LOCATION_MASK) >> TOP_EDGE_LOCATION_BIT;
++ VEnd = (ReadMemoryLongHost(VIDEO_REG_BASE, VIDE1_MODE_DETECTION_EDGE_V_REG) & BOTTOM_EDGE_LOCATION_MASK) >> BOTTOM_EDGE_LOCATION_BIT;
++
++ ulHor = HEnd-HStart+1;
++ ulVer = VEnd-VStart+1;
++
++ printf("[VIDEO] Resolution: H[%d] * V[%d]\n", ulHor, ulVer);
++
++ if ((g_DefWidth == ulHor) & (g_DefHeight == ulVer))
++ {
++ printf("[VIDEO] Mode detection PASS\n");
++ }
++ else
++ {
++ printf("[VIDEO] Mode detection FAIL\n");
++ return VIDEO_TEST_FAIL;
++ }
++
++ if(!((ReadMemoryLongHost(VIDEO_REG_BASE, VIDEO1_MODE_DETECTION_STATUS_READ_REG) & ANALONG_DIGITAL_READ) >> ANALONG_DIGITAL_READ_BIT))
++ bAnalog = FALSE;
++ else
++ bAnalog = TRUE;
++
++ // Note: Clear mode detection ready interrupt
++ ClearVideoInterruptHost(0, VIDEO1_MODE_DETECTION_READY_CLEAR);
++
++ printf("\n --------- Capture Test --------- \n");
++
++ //capture engine
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_TIMEING_GEN_HOR_REG, (HEnd << VIDEO_HDE_END_BIT), VIDEO_HDE_END_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_TIMEING_GEN_HOR_REG, (HStart << VIDEO_HDE_START_BIT), VIDEO_HDE_START_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_TIMEING_GEN_V_REG, (VEnd << VIDEO_VDE_END_BIT), VIDEO_VDE_END_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_TIMEING_GEN_V_REG, (VStart << VIDEO_VDE_START_BIT), VIDEO_VDE_START_MASK);
++
++ ulCapAddr = vBufAlign2((ULONG)pCaptureVideo1Buf1Addr);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_1_ADDR_REG, ulCapAddr, BUF_1_ADDR_MASK);
++
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_2_ADDR_REG, 0, BUF_2_ADDR_MASK);
++
++ InitializeVideoEngineHost (0,
++ VIDEO1,
++ vModeTable[2].HorPolarity,
++ vModeTable[2].VerPolarity);
++
++ WriteMemoryLongHost(VIDEO_REG_BASE, 0x04, 0x01);
++ WriteMemoryLongHost(VIDEO_REG_BASE, 0x300, 0x0);
++#if defined(CONFIG_AST2300)
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, 0x8, 0x0880, 0x0ec0);
++#elif defined(CONFIG_AST3000)
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, 0x8, 0x2800, 0x2800);
++#else
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, 0x8, 0xa00, 0x2a80); //tile mode
++#endif
++
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_TIMEING_GEN_HOR_REG, 0xa0000000, 0xa0000000);
++
++ //only trigger capture, in source buffer (vr44), the front of data is correct.
++ //StartVideoCaptureTriggerHost(0, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG);
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG, VIDEO_CAPTURE_TRIGGER);
++
++ i = 0;
++ do {
++ Status = ReadMemoryLongHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG) & CAPTURE_READY_MASK;
++ i++;
++ } while ((!Status) & (i<500000));
++
++ if (!Status)
++ {
++ printf("[VIDEO] Capture is not READY\n");
++ return VIDEO_TEST_FAIL;
++ }
++
++#if !defined(CONFIG_AST2300)
++ ulVGABaseAddr = ulCapAddr + 0x1000;
++
++ /* check pattern */
++ ulFlag = 0; //no 0 is error
++
++ for (i=0; i<100; i++)
++ {
++ dwValue = *(ULONG *)(ulVGABaseAddr + i*32);
++ if (0x32323232 != dwValue)
++ {
++ printf("[VIDEO] Capture Test fail -- capture data doesn't match source \n");
++ printf("[VIDEO]1 i=%d value=%x\n", i, dwValue);
++ ulFlag = 1;
++ break;
++ }
++
++ dwValue = *(ULONG *)(ulVGABaseAddr + i*32 + 4);
++ if (0x32323232 != dwValue)
++ {
++ printf("[VIDEO] Capture Test fail -- capture data doesn't match source \n");
++ printf("[VIDEO]2 i=%d value=%x\n", i, dwValue);
++ ulFlag = 1;
++ break;
++ }
++
++ dwValue = *(ULONG *)(ulVGABaseAddr + i*32 + 8);
++ if (0x80808080 != dwValue)
++ {
++ printf("[VIDEO] Capture Test fail -- capture data doesn't match source \n");
++ printf("[VIDEO]3 i=%d value=%x\n", i, dwValue);
++ ulFlag = 1;
++ break;
++ }
++
++ dwValue = *(ULONG *)(ulVGABaseAddr + i*32 + 12);
++ if (0x80808080 != dwValue)
++ {
++ printf("[VIDEO] Capture Test fail -- capture data doesn't match source \n");
++ printf("4 i=%d value=%x\n", i, dwValue);
++ ulFlag = 1;
++ break;
++ }
++
++ dwValue = *(ULONG *)(ulVGABaseAddr + i*32 + 16);
++ if (0x80808080 != dwValue)
++ {
++ printf("[VIDEO] Capture Test fail -- capture data doesn't match source \n");
++ printf("5 i=%d value=%x\n", i, dwValue);
++ ulFlag = 1;
++ break;
++ }
++
++ dwValue = *(ULONG *)(ulVGABaseAddr + i*32 + 20);
++ if (0x80808080 != dwValue)
++ {
++ printf("[VIDEO] Capture Test fail -- capture data doesn't match source \n");
++ printf("6 i=%d value=%x\n", i, dwValue);
++ ulFlag = 1;
++ break;
++ }
++ }
++#endif
++
++ if (!ulFlag)
++ {
++ printf("[VIDEO] Capture Test OK\n");
++ }
++ else
++ {
++ printf("[VIDEO] Capture Test FAIL\n");
++ return VIDEO_TEST_FAIL;
++ }
++
++ return VIDEO_TEST_OK;
++}
++
++/********************************************************/
++/* Only used in the station */
++/********************************************************/
++int CRTTest(void)
++{
++ ULONG ulVGABaseAddr;
++ BYTE btCRTCenterMode, btCRTColorFmt;
++ USHORT usCRTHor, usCRTVer;
++ ULONG ulData;
++
++ int i,j;
++
++ //printf("\n --------- Turn on CRT --------- \n");
++
++ //Enable CRT1 first
++ ulVGABaseAddr = vBufAlign((unsigned long)pCrt1Addr);
++
++ btCRTCenterMode = 0;
++ btCRTColorFmt = YUV_444;
++ usCRTHor = g_DefWidth;
++ usCRTVer = g_DefHeight;
++
++ CheckOnStartClient();
++
++ /* Fill Pattern */
++ for (i=0; i<usCRTHor; i++)
++ {
++ for (j=0; j<usCRTVer/8; j++)
++ {
++ //Y
++ //ulData = 0x10101010;
++ ulData = 0x32323232;
++ *(ULONG *)(ulVGABaseAddr + (i*usCRTVer*4+j*32)) = ulData;
++ //ulData = 0x10101010;
++ ulData = 0x32323232;
++ *(ULONG *)(ulVGABaseAddr + (i*usCRTVer*4+j*32) +4) = ulData;
++ //U
++ ulData = 0x80808080;
++ //ulData = 0x77777777;
++ *(ULONG *)(ulVGABaseAddr + (i*usCRTVer*4+j*32) +8) = ulData;
++ ulData = 0x80808080;
++ //ulData = 0x77777777;
++ *(ULONG *)(ulVGABaseAddr + (i*usCRTVer*4+j*32) +12) = ulData;
++ //V
++ ulData = 0x80808080;
++ //ulData = 0x11111111;
++ *(ULONG *)(ulVGABaseAddr + (i*usCRTVer*4+j*32) +16) = ulData;
++ ulData = 0x80808080;
++ //ulData = 0x11111111;
++ *(ULONG *)(ulVGABaseAddr + (i*usCRTVer*4+j*32) +20) = ulData;
++ //A
++ ulData = 0xFFFFFFFFF;
++ *(ULONG *)(ulVGABaseAddr + (i*usCRTVer*4+j*32) +24) = ulData;
++ ulData = 0xFFFFFFFFF;
++ *(ULONG *)(ulVGABaseAddr + (i*usCRTVer*4+j*32) +28) = ulData;
++ }
++ } /* ~Fill Pattern */
++
++#if defined(CONFIG_AST2300)
++ if(!ASTSetModeV (0, CRT_2, ulVGABaseAddr, usCRTHor, usCRTVer, btCRTColorFmt, btCRTCenterMode))
++#else
++ if(!ASTSetModeV (0, CRT_1, ulVGABaseAddr, usCRTHor, usCRTVer, btCRTColorFmt, btCRTCenterMode))
++#endif
++ {
++ printf("[VIDEO] The resolution is not in mode table list\n");
++ return CRT_FAIL;
++ }
++
++ //printf("[VIDEO] CRT turn on\n");
++
++ return VIDEO_TEST_OK;
++}
++
++int do_videotest (void)
++{
++ int dwValue=0;
++ int i = 0;
++ int iRet;
++ ULONG ulRestore1, ulTemp;
++ BOOL bClient;
++
++
++ //InitVideoTest();
++ g_DefWidth = 640;
++ g_DefHeight= 480;
++
++ printf("\n --------- Codec Test --------- \n");
++
++#if defined(CONFIG_AST2300)
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CONTROL_REG, 0x00002000, 0x00002000);
++#endif
++
++ CheckOnStartHost();
++
++ do
++ {
++ dwValue = UnlockVideoRegHost(0, VIDEO_UNLOCK_KEY);
++ i++;
++ }
++ while ((VIDEO_UNLOCK != dwValue) && (i<1000));
++
++ if (VIDEO_UNLOCK != dwValue)
++ {
++ printf("[VIDEO] Video register is locked \n");
++ return VIDEO_TEST_FAIL;
++ }
++ AllocateEncodeBufHost(0, VIDEO1);
++
++ iRet = CodecTest();
++ if (iRet)
++ return VIDEO_TEST_FAIL;
++
++#if defined(CONFIG_AST2300)
++ /* Init SCU */
++ WriteMemoryLongWithMASKHost(SCU_BASE, (0x2c + SCU_OFFSET), 0x00040000, 0x00040010); /* Enable D2-PLL */
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_STOP_REG, 0, 0x00000400); /* Enable D2CLK */
++ udelay(10);
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CONTROL_REG, 0, 0x00002000);
++
++ WriteMemoryLongWithMASKHost(SCU_BASE, (0x90 + SCU_OFFSET), 0x20, 0x00000030); /* enable video mode single edge */
++ WriteMemoryLongWithMASKHost(SCU_BASE, (0x84 + SCU_OFFSET), 0xfffe0000, 0xfffe0000); /* multi-pins */
++ WriteMemoryLongWithMASKHost(SCU_BASE, (0x88 + SCU_OFFSET), 0x000fffff, 0x000fffff); /* multi-pins */
++
++ iRet = CRTTest();
++ if (iRet)
++ {
++ printf("[VIDEO] CRT Test Failed \n");
++ return VIDEO_TEST_FAIL;
++ }
++
++ iRet = CapTest();
++ if (iRet)
++ {
++ printf("[VIDEO] Capture Test Failed \n");
++ return VIDEO_TEST_FAIL;
++ }
++#else
++ //Host or Client
++ bClient = ((ReadMemoryLong(SCU_BASE, SCU_HW_TRAPPING_REG) & CLIENT_MODE_EN_MASK)?TRUE:FALSE);
++ //reset video for another testing
++ ResetVideoHost();
++ dwValue=0;
++ i = 0;
++ do
++ {
++ dwValue = UnlockVideoRegHost(0, VIDEO_UNLOCK_KEY);
++ i++;
++ }
++ while ((VIDEO_UNLOCK != dwValue) && (i<10));
++
++ if (VIDEO_UNLOCK != dwValue)
++ {
++ printf("[VIDEO] Video register is locked");
++ return VIDEO_UNLOCK_FAIL;
++ }
++
++ //check if 1e6e0008[3,0] is 0
++ ulRestore1 = ReadMemoryLongHost(0x1e6e0000, 8);
++ dwValue = ReadMemoryLongHost(0x1e6e0000, 8)&0xF;
++
++ //set 1e6e0008[3,0] to 0
++ if (dwValue)
++ {
++ WriteMemoryLongHost(0x1e6e0000, 0, 0xfc600309);
++
++ i=0;
++ do
++ {
++ i++;
++ dwValue = ReadMemoryLongHost(0x1e6e0000,0);
++ }while((1 != dwValue)&& (i<10));
++
++ if (1 != dwValue)
++ {
++ printf("0x1e6e0000 is locked");
++ return VIDEO_UNLOCK_FAIL;
++ }
++ }
++
++ //only clear 1e6e0008[3,0]
++ WriteMemoryLongWithMASKHost(0x1e6e0000, 8, 0, 0xf);
++
++ bClient = 0;
++ if (!bClient)
++ {
++ //To turn on crt, must be the client mode
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_HW_TRAPPING_REG, (BE_CLIENT_CHIP << CLIENT_MODE_EN_BIT), CLIENT_MODE_EN_MASK);
++
++ iRet = CRTTest();
++
++ if (iRet)
++ {
++ //trapping to host, the Vsync of CRT can't output and the host doesn't have video sync input
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_HW_TRAPPING_REG, (BE_HOST_CHIP << CLIENT_MODE_EN_BIT), CLIENT_MODE_EN_MASK);
++ //restore value
++ WriteMemoryLongHost(0x1e6e0000, 8, ulRestore1);
++ //lock register
++ WriteMemoryLongHost(0x1e6e0000, 0, 0x12345678);
++ return VIDEO_TEST_FAIL;
++ }
++
++ iRet = CapTest();
++
++ if (iRet)
++ {
++ //trapping to host, the Vsync of CRT can't output and the host doesn't have video sync input
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_HW_TRAPPING_REG, (BE_HOST_CHIP << CLIENT_MODE_EN_BIT), CLIENT_MODE_EN_MASK);
++ //restore value
++ WriteMemoryLongHost(0x1e6e0000, 8, ulRestore1);
++ //lock register
++ WriteMemoryLongHost(0x1e6e0000, 0, 0x12345678);
++
++ return VIDEO_TEST_FAIL;
++ }
++ //WriteMemoryLongWithMASKHost(SCU_BASE, SCU_HW_TRAPPING_REG, (BE_HOST_CHIP << CLIENT_MODE_EN_BIT), CLIENT_MODE_EN_MASK);
++ }
++ //trapping to host, the Vsync of CRT can't output and the host doesn't have video sync input
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_HW_TRAPPING_REG, (BE_HOST_CHIP << CLIENT_MODE_EN_BIT), CLIENT_MODE_EN_MASK);
++ //restore value
++ WriteMemoryLongHost(0x1e6e0000, 8, ulRestore1);
++ //lock register
++ WriteMemoryLongHost(0x1e6e0000, 0, 0x12345678);
++#endif
++
++ return VIDEO_TEST_OK;
++}
++#endif /* CONFIG_SLT */
+diff --git a/board/aspeed/ast2300/videotest.h b/board/aspeed/ast2300/videotest.h
+new file mode 100755
+index 0000000..79b8dd9
+--- /dev/null
++++ b/board/aspeed/ast2300/videotest.h
+@@ -0,0 +1,24 @@
++/*
++ * 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
++ */
++/* VideoTest.h */
++#ifndef _VIDEOTEST_H_
++#define _VIDEOTEST_H_
++
++#define VIDEO_TEST_OK 0
++#define VIDEO_TEST_FAIL 1
++
++#define VIDEO_UNLOCK_FAIL 1
++#define VIDEO_ENCODE_FAIL 2
++#define VIDEO_DECODE_FAIL 3
++#define CRT_FAIL 4
++
++#endif /* _VIDEOTEST_H_ */
++
+diff --git a/board/aspeed/ast2300/vreg.h b/board/aspeed/ast2300/vreg.h
+new file mode 100755
+index 0000000..9738548
+--- /dev/null
++++ b/board/aspeed/ast2300/vreg.h
+@@ -0,0 +1,845 @@
++/*
++ * 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 _VREG_H_
++#define _VREG_H_
++
++/********************************************************/
++/* CRT register */
++/********************************************************/
++#define CRT_BASE_ADDRESS 0x000400
++#define VGA_GRAPH_BASE_ADDRESS 0x600000
++#define VGA_CURSOR_BASE_ADDRESS 0x300000
++#define VGA_OSD_BASE_ADDRESS 0x300000
++#define RGB_565 0x0
++#define RGB_888 0x1
++#define YUV_444 0x2
++#define NO_SUPPORTED_CRT_FMT 0x3
++#define CRT_LOW_THRESHOLD_VALUE 0x12
++#define CRT_HIGH_THRESHOLD_VALUE 0x1E
++
++// AST3000's Registers
++#ifdef Watcom
++#define VIDEOBASE_OFFSET 0x10000
++#else
++#define VIDEOBASE_OFFSET 0x0
++#endif
++
++#define KEY_CONTROL_REG 0x00 + VIDEOBASE_OFFSET
++ #define VIDEO_LOCKED 0
++ #define VIDEO_UNLOCK 1
++
++// Registers for video1 and video2
++#define VIDEO1_ENGINE_SEQUENCE_CONTROL_REG 0x04 + VIDEOBASE_OFFSET
++#define VIDEO2_ENGINE_SEQUENCE_CONTROL_REG 0x104 + VIDEOBASE_OFFSET
++ #define MODE_DETECTION_TRIGGER 0x00000001 //Bit[0] trigger HW auto mode detection
++ #define VIDEO_CAPTURE_TRIGGER 0x00000002 //Bit[1] trigger HW to capture video
++ #define FORCE_HW_IDLE_MASK (1<<2) //Bit[2] Force engine into ready(idle) state
++ #define ENGINE_RESET (0<<2)
++ #define ENGINE_IDLE (1<<2)
++ #define VIDEO_CAPTURE_AUTO_MODE 0x00000008 //Bit[3]
++ #define CAPTURE_FRAME_MODE 0
++ #define CAPTURE_AUTO_MODE 1
++ #define CAPTURE_AUTO_MODE_BIT 3
++ #define CAPTURE_AUTO_MODE_MASK 0x00000008
++ #define VIDEO_CODEC_TRIGGER 0x00000010 //Bit[4] trigger HW to compress or decompress video
++ #define CODEC_TRIGGER_BIT 4
++ #define CODEC_TRIGGER_MASK 0x00000010
++ #define CLEAR_CODEC_TRIGGER 0
++ #define EN_CODEC_TRIGGER 1
++ #define VIDEO_CODEC_AUTO_MODE 0x00000020 //Bit[5]
++ #define CODEC_FRAME_MODE 0
++ #define CODEC_AUTO_MODE 1
++ #define CODEC_AUTO_MODE_BIT 5
++ #define CODEC_AUTO_MODE_MASK 0x00000020
++ #define INSERT_FULL_FRAME_MASK (1<<6) //Bit[6] Insert full frame compression
++ #define INSERT_FULL_FRAME_EN (1<<6)
++ #define INSERT_FULL_FRAME_OFF (0<<6)
++ #define WATCH_DOG_ENABLE 0x00000080 //Bit[7] Video Enable watch dog for mode change detection
++ #define WATCH_DOG_ENABLE_BIT 7
++ #define WATCH_DOG_OFF 0
++ #define WATCH_DOG_EN 1
++ #define WATCH_DOG_EN_MASK 0x00000080
++ #define VIDEO_CRT_SELECTION 0x00000100 //Bit[8]
++ #define CRT1 0
++ #define CRT2 1
++ #define ANTI_TEARING_ENABLE 0x00000200 //Bit[9] Anti-tearing mode enable for decoding
++ #define ANTI_TEARING_EN 1
++ #define STREAM_DATA_MODE 0x00000400 //Bit[11:10] Buffer and Stream Data type
++ #define STREAM_DATA_MODE_BIT 10
++ #define STREAM_DATA_MODE_MASK 0x00000C00
++ #define YUV444_MODE 0
++ #define YUV420_MODE 1
++ #define YUV420_MODE_WITH_AST2000 2 //AST2000 compatible
++ #define VIDEO_CAPTURE_READY 0x00010000 //Bit[16] Video capture ready status read back(read only)
++ #define CAPTURE_READY_MASK 0x00010000
++ #define HW_BUSY 0
++ #define HW_IDLE 1
++ #define VIDEO_CODEC_READY 0x00040000 //Bit[18] Video codec ready status read back(read only)
++ #define CODEC_READY_MASK 0x00040000
++ //#define HW_BUSY 0
++ //#define HW_IDLE 1
++
++#define VIDEO1_CONTROL_REG 0x08 + VIDEOBASE_OFFSET
++#define VIDEO2_CONTROL_REG 0x108 + VIDEOBASE_OFFSET
++ #define VIDEO_HSYNC_POLARITY 0x00000001 //Bit[0] Video source hsync polarity
++ #define VIDEO_HSYNC_POLARITY_BIT 0
++ #define NO_INVERSE_POL 0
++ #define INVERSE_POL 1
++ #define VIDEO_VSYNC_POLARITY 0x00000002 //Bit[1] Video source vsync polarity
++ #define VIDEO_VSYNC_POLARITY_BIT 1
++ //Setting defination the same as VIDEO_HSYNC_POLARITY
++ #define VIDEO_EXTERNAL_SOURCE 0x00000004 //Bit[2] Video external source
++ #define EXTERNAL_SOURCE_BIT 2
++ #define INTERNAL_VGA_SOURCE 0
++ #define EXTERNAL_VGA_SOURCE 1
++ #define EXTERNAL_SOURCE_MASK 0x00000004
++ #define VIDEO_ANALONG_EXTERNAL_SOURCE 0x00000008 //Bit[3] Video Analog external source
++ #define ANALONG_EXTERNAL_SOURCE_BIT 3
++ #define DVI_SOURCE 0
++ #define ANALOG_RGB_SOURCE 1
++ #define VIDEO_INTERNAL_TIMING_GEN 0x00000010 //Bit[4] Video Use internal timing generator
++ #define INTERNAL_TIMING_GEN_BIT 4
++ #define EXTERNAL_DE_SIGNAL 0 //DVI only
++ #define VR0C_VR10_DE_SINGAL 1 //use VR0C and VR10 for generate VDE signal
++ /****** Video2 Only from DAC ******/
++ #define VIDEO1_CAPTURE_FROM 0x00000020 //Bit[5] Video1 capture data direct from VGA frame buffer(internal VGA only)
++ #define FROM_DAC_PORT 0
++ #define FROM_FRAME_BUFFER 1
++ #define WRITE_DATA_FORMAT 0x00000040 //Bit[7:6] Write data format
++ #define WRITE_DATA_FORMAT_BIT 6
++ #define WRTIE_DATA_FORMAT_MASK 0x000000C0
++ #define CCIR601_2_YUV_FORMAT 0
++ #define FULL_YUV_FORMAT 1
++ #define RGB_FORMAT 2
++ #define VGA_CURSOR_DISABLE 0x00000100 //Bit[8] External video port slection
++ #define VGA_CURSOR_NORMAL 0
++ #define VGA_CURSOR_OFF 1
++ #define VIDEO_CAPTURE_LINEAR_MODE 0x00000200 //Bit[9] VIDEO_CAPTURE_LINEAR_MODE
++ #define LINEAR_MODE 0
++ #define TILE_MODE 1
++ #define VIDEO_CLOCK_DELAY 0x00000400 //Bit[11:10] Video clock delay control
++ #define VIDEO_CLOCK_DELAY_BIT 10
++ #define VIDEO_CLOCK_DELAY_MASK 0x00000C00
++ #define DELAY_0_NS 0
++ #define DELAY_1_NS 1
++ #define INV_AND_DELAY_0_NS 2
++ #define INV_AND_DELAY_1_NS 3
++ #define VIDEO_CCIR656_SOURCE_MODE 0x00001000 //Bit[12] Video CCIR656 source mode
++ #define RGB_SOURCE_MODE 0
++ #define CCIR656_SOURCE_MODE 1
++ #define SOURCE_PORT_CLOCK_MODE 0x00002000 //Bit[13] Video Source port clock mode
++ #define SINGLE_EDGE_MODE 0
++ #define DUAL_EDGE_MODE 1
++ #define EXTERNAL_PORT_SELECTION 0x00004000 //Bit[14] External video port slection
++ #define VIDEO_PORT_A 0
++ #define VIDEO_PORT_B 1
++ #define VIDEO_CAPTURE_FRAME_RATE 0x00010000 //Bit[23:16] Video capture frame rate control
++ #define VIDEO_CAPTURE_FRAME_RATE_BIT 16
++ #define VIDEO_CAPTURE_FRAME_RATE_MASK 0x00FF0000 //Maximum frame rate = XX * SourceFPS / 60
++
++#define VIDEO1_TIMEING_GEN_HOR_REG 0x0C + VIDEOBASE_OFFSET
++#define VIDEO2_TIMEING_GEN_HOR_REG 0x10C + VIDEOBASE_OFFSET
++ #define VIDEO_HDE_END 0x00000000 //Bit[12:0] Video HDE End timing generator
++ #define VIDEO_HDE_END_BIT 0 //Number of pixels from rising edge of Hsync for first active pixel
++ #define VIDEO_HDE_END_MASK 0x00001FFF
++ #define VIDEO_HDE_START 0x00010000 //Bit[28:16] Video HDE Start timing generator
++ #define VIDEO_HDE_START_BIT 16 //Number of pixels from rising edge of Hsync for last active pixel
++ #define VIDEO_HDE_START_MASK 0x1FFF0000
++ #define FRAME_RATE_OFF 0
++
++#define VIDEO1_TIMEING_GEN_V_REG 0x10 + VIDEOBASE_OFFSET
++#define VIDEO2_TIMEING_GEN_V_REG 0x110 + VIDEOBASE_OFFSET
++ #define VIDEO_VDE_END 0x00000001 //Bit[11:0] Video VDE End timing generator
++ #define VIDEO_VDE_END_BIT 0 //Number of pixels from rising edge of Vsync for first active pixel
++ #define VIDEO_VDE_END_MASK 0x00000FFF
++ #define VIDEO_VDE_START 0x00010000 //Bit[27:16] Video VDE Start timing generator
++ #define VIDEO_VDE_START_BIT 16 //Number of pixels from rising edge of Vsync for last active pixel
++ #define VIDEO_VDE_START_MASK 0x0FFF0000
++
++#define VIDEO1_SCALE_FACTOR_REG 0x14 + VIDEOBASE_OFFSET
++#define VIDEO2_SCALE_FACTOR_REG 0x114 + VIDEOBASE_OFFSET
++ #define HOR_SCALING_FACTOR 0x00000001 //Bit[15:0] Video Horizontal scaling factor
++ #define HOR_SCALING_FACTOR_BIT 0 //The formula=4096/(Horizontal scaling facotr)
++ #define HOR_SCALING_FACTOR_MASK 0x0000FFFF
++ #define VER_SCALING_FACTOR 0x00000000 //Bit[31:16] Video Vertical scaling factor
++ #define VER_SCALING_FACTOR_BIT 16 //The formula=4096/(Vertical scaling facotr)
++ #define VER_SCALING_FACTOR_MASK 0xFFFF0000
++
++#define VIDEO1_SCALE_FACTOR_PARAMETER0_REG 0x18 + VIDEOBASE_OFFSET //Scaling Parameters F00, F01, F02, F03
++#define VIDEO2_SCALE_FACTOR_PARAMETER0_REG 0x118 + VIDEOBASE_OFFSET
++
++#define VIDEO1_SCALE_FACTOR_PARAMETER1_REG 0x1C + VIDEOBASE_OFFSET //Scaling Parameters F10, F11, F12, F13
++#define VIDEO2_SCALE_FACTOR_PARAMETER1_REG 0x11C + VIDEOBASE_OFFSET
++
++#define VIDEO1_SCALE_FACTOR_PARAMETER2_REG 0x20 + VIDEOBASE_OFFSET //Scaling Parameters F20, F21, F22, F23
++#define VIDEO2_SCALE_FACTOR_PARAMETER2_REG 0x120 + VIDEOBASE_OFFSET
++
++#define VIDEO1_SCALE_FACTOR_PARAMETER3_REG 0x24 + VIDEOBASE_OFFSET //Scaling Parameters F30, F31, F32, F33
++#define VIDEO2_SCALE_FACTOR_PARAMETER3_REG 0x124 + VIDEOBASE_OFFSET
++
++#define VIDEO1_BCD_CONTROL_REG 0x2C + VIDEOBASE_OFFSET
++#define VIDEO2_BCD_CONTROL_REG 0x12C + VIDEOBASE_OFFSET
++ #define BCD_ENABLE 0x00000001 //Bit[0] Enable block change detection(BCD)
++ #define BCD_ENABLE_BIT 0
++ #define BCD_ENABLE_MASK 0x00000001
++ #define BCD_TOLERANCE 0x00010000 //Bit[23:16]
++ #define BCD_TOLERANCE_BIT 16 //flag as changed block when the video data difference greater
++ #define BCD_TOLERANCE_MASK 0x00FF0000
++
++#define VIDEO1_CAPTURE_WINDOWS_REG 0x30 + VIDEOBASE_OFFSET
++#define VIDEO2_CAPTURE_WINDOWS_REG 0x130 + VIDEOBASE_OFFSET
++ #define CAPTURE_VER_LINE 0x00000001 //Bit[10:0] Video compression vertical line total
++ #define CAPTURE_VER_LINE_BIT 0
++ #define CAPTURE_VER_LINE_MASK 0x000007FF
++ #define CAPTURE_HOR_PIXEL 0x00010000 //Bit[26:16] Video compression vertical line total
++ #define CAPTURE_HOR_PIXEL_BIT 16
++ #define CAPTURE_HOR_PIXEL_MASK 0x07FF0000
++
++#define VIDEO1_COMPRESS_WINDOWS_REG 0x34 + VIDEOBASE_OFFSET
++#define VIDEO2_COMPRESS_WINDOWS_REG 0x134 + VIDEOBASE_OFFSET
++ #define COMPRESS_VER_LINE 0x00000001 //Bit[10:0] Video compression vertical line total
++ #define COMPRESS_VER_LINE_BIT 0
++ #define COMPRESS_VER_LINE_MASK 0x000007FF
++ #define COMPRESS_HOR_PIXEL 0x00010000 //Bit[26:16] Video compression vertical line total
++ #define COMPRESS_HOR_PIXEL_BIT 16
++ #define COMPRESS_HOR_PIXEL_MASK 0x07FF0000
++
++#define VIDEO1_COMPRESS_BUF_PROCESS_OFFSET_REG 0x38
++#define VIDEO2_COMPRESS_BUF_PROCESS_OFFSET_REG 0x138
++ #define COMPRESS_BUF_PROCESS_OFFSET_ALIGN 127 //128 byte alignment
++ #define COMPRESS_BUF_PROCESS_OFFSET_MASK 0xFFFFFF
++
++#define VIDEO1_DECOMPRESS_BUF_PROCESS_OFFSET_REG 0x38
++#define VIDEO2_DECOMPRESS_BUF_PROCESS_OFFSET_REG 0x138
++ #define DECOMPRESS_BUF_PROCESS_OFFSET_ALIGN 127 //128 byte alignment
++ #define DECOMPRESS_BUF_PROCESS_OFFSET_MASK 0xFFFFFF
++
++
++//For Compression
++#define VIDEO1_COMPRESS_BUF_READ_OFFSET_REG 0x3C + VIDEOBASE_OFFSET //For stream mode
++#define VIDEO2_COMPRESS_BUF_READ_OFFSET_REG 0x13C + VIDEOBASE_OFFSET
++ #define COMPRESS_BUF_READ_OFFSET_ALIGN 127 //128 byte alignment
++ #define COMPRESS_BUF_READ_OFFSET_MASK 0x00FFFFFF
++//For Decompression
++#define VIDEO1_DECOMPRESS_BUF_WRITE_OFFSET_REG 0x3C + VIDEOBASE_OFFSET //For stream mode
++#define VIDEO2_DECOMPRESS_BUF_WRITE_OFFSET_REG 0x13C + VIDEOBASE_OFFSET
++ #define DECOMPRESS_BUF_WRITE_OFFSET_ALIGN 127 //128 byte alignment
++ #define DECOMPRESS_BUF_WRITE_OFFSET_MASK 0x00FFFFFF
++
++#define VIDEO1_CRC_BUF_ADDR_REG 0x40 + VIDEOBASE_OFFSET
++#define VIDEO2_CRC_BUF_ADDR_REG 0x140 + VIDEOBASE_OFFSET
++ #define CRC_BUF_ADDR_ALIGN 7 //8 byte alignment
++ #define CRC_BUF_ADDR_MASK 0x0FFFFFFF
++
++#define VIDEO1_BUF_1_ADDR_REG 0x44 + VIDEOBASE_OFFSET //For Source Buffer in frame mode
++#define VIDEO2_BUF_1_ADDR_REG 0x144 + VIDEOBASE_OFFSET
++ #define BUF_1_ADDR_ALIGN 255 //256 byte alignment
++ #define BUF_1_ADDR_MASK 0x1FFFFFFF
++
++#define VIDEO1_BUF_LINE_OFFSET_REG 0x48 + VIDEOBASE_OFFSET //Must set both in Frame/Stream mode
++#define VIDEO2_BUF_LINE_OFFSET_REG 0x148 + VIDEOBASE_OFFSET
++ #define BUF_LINE_OFFSET_ALIGN 7 //8 byte alignment
++ #define BUF_LINE_OFFSET_MASK 0x00003FFF
++
++#define VIDEO1_BUF_2_ADDR_REG 0x4C + VIDEOBASE_OFFSET //For BCD Buffer in frame mode
++#define VIDEO2_BUF_2_ADDR_REG 0x14C + VIDEOBASE_OFFSET
++ #define BUF_2_ADDR_ALIGN 255 //256 byte alignment
++ #define BUF_2_ADDR_MASK 0x1FFFFFFF
++
++#define VIDEO1_FLAG_BUF_ADDR_REG 0x50 + VIDEOBASE_OFFSET //For block change flag buffer
++#define VIDEO2_FLAG_BUF_ADDR_REG 0x150 + VIDEOBASE_OFFSET
++ #define FLAG_BUF_ADDR_ALIGN 7 //8 byte alignment
++ #define FLAG_BUF_ADDR_MASK 0x1FFFFFFF
++
++#define VIDEO1_COMPRESS_BUF_ADDR_REG 0x54 + VIDEOBASE_OFFSET //For stream mode
++#define VIDEO2_COMPRESS_BUF_ADDR_REG 0x154 + VIDEOBASE_OFFSET
++ #define COMPRESS_BUF_ADDR_ALIGN 127 //128 byte alignment
++ #define COMPRESS_BUF_ADDR_MASK 0x1FFFFFFF
++
++#define VIDEO1_STREAM_BUF_SIZE 0x58 + VIDEOBASE_OFFSET //For stream mode
++#define VIDEO2_STREAM_BUF_SIZE 0x158 + VIDEOBASE_OFFSET
++ #define STREAM_PACKET_SIZE 0x00000001
++ #define STREAM_PACKET_SIZE_BIT 0
++ #define STREAM_PACKET_SIZE_MASK 0x00000007
++ #define PACKET_SIZE_1KB 0
++ #define PACKET_SIZE_2KB 1
++ #define PACKET_SIZE_4KB 2
++ #define PACKET_SIZE_8KB 3
++ #define PACKET_SIZE_16KB 4
++ #define PACKET_SIZE_32KB 5
++ #define PACKET_SIZE_64KB 6
++ #define PACKET_SIZE_128KB 7
++ #define RING_BUF_PACKET_NUM 0x00000008
++ #define RING_BUF_PACKET_NUM_BIT 3
++ #define RING_BUF_PACKET_NUM_MASK 0x00000018
++ #define PACKETS_4 0
++ #define PACKETS_8 1
++ #define PACKETS_16 2
++ #define PACKETS_32 3
++ #define SKIP_HIGH_MB_THRES 0x00010000 //Bit[22:16] Skip high quality macro block threshold
++ #define SKIP_HIGH_MB_THRES_BIT 16
++ #define SKIP_HIGH_MB_THRES_MASK 0x007F0000
++ #define SKIP_TEST_MODE 0x00800000 //Bit[24:23] Skip test mode
++ #define SKIP_TEST_MODE_BIT 23
++ #define SKIP_TEST_MODE_MASK 0x01800000
++ #define YUV_TEST 2 //recommend
++
++#define VIDEO1_BUF_CODEC_OFFSET_READ 0x5C + VIDEOBASE_OFFSET //For stream mode,
++#define VIDEO2_BUF_CODEC_OFFSET_READ 0x15C + VIDEOBASE_OFFSET //Video stream buffer offset read back(HW)
++ #define BUF_CODEC_OFFSET_ALIGN 255 //256 byte alignment
++ #define BUF_CODEC_OFFSET_MASK 0x00FFFFFF
++
++#define VIDEO1_COMPRESS_CONTROL_REG 0x60 + VIDEOBASE_OFFSET
++#define VIDEO2_COMPRESS_CONTROL_REG 0x160 + VIDEOBASE_OFFSET
++ #define JPEG_ONLY_ENCODE 0x00000001 //Bit[0] JPEG only encoding
++ #define JPEG_ONLY_BIT 0
++ #define JPEG_MIX_MODE 0 //Enable JPEG/VQ mix mode encoding
++ #define JPEG_ONLY_MODE 1 //JPEG encoding mode only
++ #define VQ_4_COLOR_ENCODE 0x00000002 //Bit[1] Enable 4 color VQ encoding
++ #define VQ_4_COLOR_BIT 1
++ #define VQ_1_2_COLOR_MODE 0 //1 and 2 color mode VQ encoding
++ #define VQ_4_COLOR_MODE 1 //1, 2 and 4 color VQ encoding
++ #define QUALITY_CODEC_SETTING 0x00000004 //Bit[2] High and best video quality codec mode setting
++ #define QUALITY_CODEC_SETTING_BIT 2
++ #define JPEG_CODEC_MODE 0 //not supported in best video quality mode
++ #define QUANTI_CODEC_MODE 1
++ #define JPEG_DUAL_QUALITY_EN 0x00000008 //Bit[3] JPEG dual quality mode
++ #define EN_JPEG_DUAL_QUALITY 1 //enable(only for normal video quality mode)
++ #define BEST_QUALITY_EN 0x00000010 //Bit[4] Best quality video mode enable
++ #define BEST_QUALITY_EN_BIT 4
++ #define EN_BEST_QUALITY 1 //enable(only for quantization codec mode)
++ #define RC4_CRYPT_EN 0x00000020 //Bit[5] Enable RC4 encryption/decryption
++ #define RC4_CRYPT_EN_BIT 5
++ #define RC4_CRYPT_EN_MASK 0x00000020
++ #define RC4_CRYPT_ON 1 //enable
++ #define NORMAL_QUANTI_CHROMI_TABLE 0x00000040 //Bit[10:6] Normal video quality mode JPEG DCT chromi quantination table
++ #define NORMAL_QUANTI_CHROMI_TABLE_BIT 6
++ #define NORMAL_QUANTI_CHROMI_TABLE_MASK 0x000007C0
++ #define NORMAL_QUANTI_LUMI_TABLE 0x00000800 //Bit[15:11] Normal video quality mode JPEG DCT lumi quantination table
++ #define NORMAL_QUANTI_LUMI_TABLE_BIT 11
++ #define NORMAL_QUANTI_LUMI_TABLE_MASK 0x0000F800
++ #define HIGH_QUALITY_EN 0x00010000 //Bit[16] High video quality mode enable
++ #define HIGH_QUALITY_EN_BIT 16
++ #define EN_HIGH_QUALITY 1 //Enable
++ #define UV_CIR656_FORMAT 0x00080000 //Bit[19] UV fromat
++ #define UV_CIR656_FORMAT_BIT 19
++ #define USE_UV_CIR656 1 //recommand
++ #define HUFFMAN_TABLE_SELECT 0x00100000 //Bit[20] JPEG Huffman table combination
++ #define DUAL_TABLE 0 //Dual Y, UV table
++ #define SINGLE_TABLE 1 //Single Y table
++ #define SINGLE_UV_TABLE 0x00200000 //1x: Single UV table
++ #define HIGH_QUANTI_CHROMI_TABLE 0x00400000 //Bit[26:22] High quality JPEG DCT chromi quantization table
++ #define HIGH_QUANTI_CHROMI_TABLE_BIT 22
++ #define HIGH_QUANTI_CHROMI_TABLE_MASK 0x07C00000
++ #define HIGH_DEQUANTI_VALUE 0x00400000 //Bit[26:22] High quality de-quantization value
++ #define HIGH_DEQUANTI_VALUE_BIT 22
++ #define HIGH_DEQUANTI_VALUE_MASK 0x07C00000
++ #define HIGH_QUANTI_LUMI_TABLE 0x08000000 //Bit[31:27] High quality JPEG DCT lumi quantization table
++ #define HIGH_QUANTI_LUMI_TABLE_BIT 27
++ #define HIGH_QUANTI_LUMI_TABLE_MASK 0xF8000000
++ #define BEST_DEQUANTI_VALUE 0x08000000 //Bit[31:27] Best quality de-quantization value
++ #define BEST_DEQUANTI_VALUE_BIT 27
++ #define BEST_DEQUANTI_VALUE_MASK 0xF8000000
++
++
++#define VIDEO1_QUANTI_TABLE_LOW_REG 0x64 + VIDEOBASE_OFFSET //Match with 0x60 Bit[10:6], Bit[15:11]
++#define VIDEO2_QUANTI_TABLE_LOW_REG 0x164 + VIDEOBASE_OFFSET
++ #define QUANTI_CHROMI_TABLE_LOW 0x00000001 //Bit[4:0] Normal video low quality block chromi quantization table
++ #define QUANTI_CHROMI_TABLE_LOW_BIT 0
++ #define QUANTI_CHROMI_TABLE_LOW_MASK 0x0000001F
++ #define QUANTI_LUMI_TABLE_LOW 0x00000020 //Bit[9:5] Normal video low quality block lumi quantization table
++ #define QUANTI_LUMI_TABLE_LOW_BIT 5
++ #define QUANTI_LUMI_TABLE_LOW_MASK 0x000003E0
++
++#define VIDEO1_QUANTI_VALUE_REG 0x68 + VIDEOBASE_OFFSET //Match with 0x60 Bit[26:22],Bit[31:27]
++#define VIDEO2_QUANTI_VALUE_REG 0x168 + VIDEOBASE_OFFSET
++ #define HIGH_QUANTI_VALUE 0x00000001 //Bit[14:0] High quality quantization value. Format is 1.14
++ #define HIGH_QUANTI_VALUE_BIT 0
++ #define HIGH_QUANTI_VALUE_MASK 0x00007FFF
++ #define BEST_QUANTI_VALUE 0x00010000 //Bit[30:16] Best quality quantization value. Format is 1.14
++ #define BEST_QUANTI_VALUE_BIT 16
++ #define BEST_QUANTI_VALUE_MASK 0x7FFF0000
++
++#define VIDEO1_BSD_PARA_REG 0x6C + VIDEOBASE_OFFSET //Video BSD Parameters Register
++#define VIDEO2_BSD_PARA_REG 0x16C + VIDEOBASE_OFFSET
++ #define BSD_HIGH_THRES 0x00000001 //Bit[7:0] Block sharpness detection high threshold
++ #define BSD_HIGH_THRES_BIT 0
++ #define BSD_HIGH_THRES_MASK 0x000000FF
++ #define BSD_LOW_THRES 0x00000100 //Bit[15:8] Block shaprpness detection low threshold
++ #define BSD_LOW_THRES_BIT 8
++ #define BSD_LOW_THRES_MASK 0x0000FF00
++ #define BSD_HIGH_COUNTS 0x00010000 //Bit[21:16] Block sharpness detection high counts threshold
++ #define BSD_HIGH_COUNTS_BIT 16
++ #define BSD_HIGH_COUNTS_MASK 0x003F0000
++ #define BSD_LOW_COUNTS 0x00400000 //Bit[27:22] Block sharpness detection low counts threshold
++ #define BSD_LOW_COUNTS_BIT 22
++ #define BSD_LOW_COUNTS_MASK 0x0FC00000
++
++#define VIDEO1_COMPRESS_FRAME_SIZE_REG 0x70 + VIDEOBASE_OFFSET
++#define VIDEO2_COMPRESS_FRAME_SIZE_REG 0x170 + VIDEOBASE_OFFSET
++ #define COMPRESS_FRAME_SIZE_READ 0x00000001 //Bit[19:0] Video compression frame size read back(number of DW)
++ #define COMPRESS_FRAME_SIZE_READ_BIT 0
++ #define COMPRESS_FRAME_SIZE_READ_MASK 0x003FFFFF
++
++#define VIDEO1_COMPRESS_BLOCK_COUNT_REG 0x74 + VIDEOBASE_OFFSET
++#define VIDEO2_COMPRESS_BLOCK_COUNT_REG 0x174 + VIDEOBASE_OFFSET
++ #define PROCESS_BLOCK_COUNT_READ_BIT 0
++ #define PROCESS_BLOCK_COUNT_READ_MASK 0x00003FFF //Bit[13:0] Video processed total block counter read back(number of blocks)
++ #define COMPRESS_BLOCK_COUNT_READ_BIT 16
++ #define COMPRESS_BLOCK_COUNT_READ_MASK 0xFFFF0000 //Bit[29:16] Video processed total block counter read back(number of blocks)
++
++#define VIDEO1_COMPRESS_FRAME_END_READ 0x78 + VIDEOBASE_OFFSET //Video compression stream frame end pointer
++#define VIDEO2_COMPRESS_FRAME_END_READ 0x178 + VIDEOBASE_OFFSET
++ #define COMPRESS_FRAME_END_READ_ALIGN 7
++ #define COMPRESS_FRAME_END_READ_MASK 0x00FFFFFF
++
++#define VIDEO1_COMPRESS_FRAME_COUNT_READ 0x7C + VIDEOBASE_OFFSET
++#define VIDEO2_COMPRESS_FRAME_COUNT_READ 0x17C + VIDEOBASE_OFFSET
++ #define COMPRESS_FRAME_COUNT_READ 0x00000001 //Bit[15:0] Video compression frame count read back(number of frame)
++ #define COMPRESS_FRAME_COUNT_READ_BIT 0
++ #define COMPRESS_FRAME_COUNT_READ_MASK 0xFFFFFFFF
++
++#define VIDEO1_USER_DEFINE_HEADER 0x80 + VIDEOBASE_OFFSET
++#define VIDEO2_USER_DEFINE_HEADER 0x180 + VIDEOBASE_OFFSET
++ #define USER_DEFINE_HEADER 0x00000001 //Bit[15:0] Video user defined header parameter
++ #define USER_DEFINE_HEADER_BIT 0
++ #define USER_DEFINE_HEADER_MASK 0x0000FFFF
++
++#define VIDE1_MODE_DETECTION_EDGE_H_REG 0x90 + VIDEOBASE_OFFSET
++#define VIDE2_MODE_DETECTION_EDGE_H_REG 0x190 + VIDEOBASE_OFFSET
++ #define LEFT_EDGE_LOCATION 0x00000001 //Bit[11:0] Video source left edge location from sync rising edge
++ #define LEFT_EDGE_LOCATION_BIT 0
++ #define LEFT_EDGE_LOCATION_MASK 0x00000FFF
++ #define NO_VER_SYNC (1 << 12) //Bit[12] No Vertical sync detected
++ #define NO_HOR_SYNC (1 << 13) //Bit[13] No horizontal sync detected
++ #define NO_ACTIVE_DISP (1 << 14) //Bit[14] No active display detected
++ #define NO_DISP_CLOCK (1 << 15)
++ #define RIGHT_EDGE_LOCATION 0x00010000 //Bit[27:16] Video source right edge location from sync rising edge
++ #define RIGHT_EDGE_LOCATION_BIT 16
++ #define RIGHT_EDGE_LOCATION_MASK 0x0FFF0000
++
++#define VIDE1_MODE_DETECTION_EDGE_V_REG 0x94 + VIDEOBASE_OFFSET
++#define VIDE2_MODE_DETECTION_EDGE_V_REG 0x194 + VIDEOBASE_OFFSET
++ #define TOP_EDGE_LOCATION 0x00000001 //Bit[11:0] Video source top edge location from sync rising edge
++ #define TOP_EDGE_LOCATION_BIT 0
++ #define TOP_EDGE_LOCATION_MASK 0x00000FFF
++ #define BOTTOM_EDGE_LOCATION 0x00010000 //Bit[27:16] Video source bottom edge location from sync rising edge
++ #define BOTTOM_EDGE_LOCATION_BIT 16
++ #define BOTTOM_EDGE_LOCATION_MASK 0x0FFF0000
++
++#define VIDEO1_MODE_DETECTION_STATUS_READ_REG 0x98 + VIDEOBASE_OFFSET
++#define VIDEO2_MODE_DETECTION_STATUS_READ_REG 0x198 + VIDEOBASE_OFFSET
++ #define MODE_DETECTION_HOR_TIME_READ 0x00000001 //Bit[11:0] Mode detection Horizontal time read back (read only)
++ #define MODE_DETECTION_HOR_TIME_READ_BIT 0
++ #define MODE_DETECTION_HOR_TIME_READ_MASK 0x00000FFF
++ #define ANALONG_DIGITAL_READ 0x00001000 //Bit[12] Auto detection for external analog or digital source read back
++ #define ANALONG_DIGITAL_READ_BIT 12
++ #define DVI_SIGNAL 0
++ #define ADC_SIGNAL 1
++ #define MODE_DETECTION_HOR_STABLE_READ 0x00002000 //Bit[13] Mode detection horizontal stable read back
++ #define HOR_STABLE 1
++ #define MODE_DETECTION_VER_STABLE_READ 0x00004000 //Bit[14] Mode detection vertical stable read back
++ #define VER_STABLE 1
++ #define OUT_LOCK_READ 0x00008000 //Bit[15] Mode detection out of lock read back
++ #define SIGNAL_OUT_LOCK 1
++ #define MODE_DETECTION_VER_LINE_READ 0x00010000 //Bit[27:16] Mode detection Vertical lines read back
++ #define MODE_DETECTION_VER_LINE_READ_BIT 16
++ #define MODE_DETECTION_VER_LINE_READ_MASK 0x0FFF0000
++ #define VSYNC_POLARITY_READ 0x10000000 //Bit[28] Vsync polarity read back
++ #define HSYNC_POLARITY_READ 0x20000000 //Bit[29] Hsync polarity read back
++ #define MODE_DETECTION_VSYNC_READY 0x40000000 //Bit[30] Mode detection Vsync ready
++ #define MODE_DETECTION_HSYNC_READY 0x80000000 //Bit[31] Mode detection Hsync ready
++
++/****** VIDEO MEMAGER SETTING ******/
++#define VIDEOM_ENGINE_SEQUENCE_CONTROL_REG 0x204 + VIDEOBASE_OFFSET
++ #define VIDEOM_CAPTURE_TRIGGER 0x00000002 //Bit[1] trigger HW to capture video
++ #define VIDEOM_AUTO_MODE 0x00000008 //Bit[3]
++ #define DISABLE_AUTO_MODE 0
++ #define AUTO_COMPRESS 1
++ #define VIDEOM_CODEC_TRIGGER 0x00000010 //Bit[4] trigger HW to compress or decompress video
++ #define VIDEOM_SOURCE_SELECTION 0x00000100 //Bit[8]
++ #define VIDEO1 0
++ #define VIDEO2 1
++ //#define STREAM_DATA_MODE 0x00000400 //Bit[11:10] Buffer and Stream Data type
++ // #define STREAM_DATA_MODE_BIT 10
++ // #define STREAM_DATA_MODE_MASK 0x00000C00
++ // #define YUV444_MODE 0
++ // #define YUV420_MODE 1
++ // #define YUV420_MODE_WITH_AST2000 2 //AST2000 compatible
++ #define VIDEOM_CAPTURE_READY 0x00010000 //Bit[16] Video capture ready status read back(read only)
++ //#define HW_BUSY 0
++ //#define HW_IDLE 1
++ #define VIDEOM_CODEC_READY 0x00040000 //Bit[18] Video codec ready status read back(read only)
++ //#define HW_BUSY 0
++ //#define HW_IDLE 1
++
++#define VIDEOM_SCALE_FACTOR_REG 0x214 + VIDEOBASE_OFFSET
++// #define HOR_SCALING_FACTOR 0x00000001 //Bit[15:0] Video Horizontal scaling factor
++// #define HOR_SCALING_FACTOR_BIT 0 //The formula=4096/(Horizontal scaling facotr)
++// #define HOR_SCALING_FACTOR_MASK 0x0000FFFF
++// #define VER_SCALING_FACTOR 0x00000000 //Bit[31:16] Video Vertical scaling factor
++// #define VER_SCALING_FACTOR_BIT 16 //The formula=4096/(Vertical scaling facotr)
++// #define VER_SCALING_FACTOR_MASK 0xFFFF0000
++
++#define VIDEOM_SCALE_FACTOR_PARAMETER0_REG 0x218 + VIDEOBASE_OFFSET //Scaling Parameters F00, F01, F02, F03
++
++#define VIDEOM_SCALE_FACTOR_PARAMETER1_REG 0x21C + VIDEOBASE_OFFSET //Scaling Parameters F10, F11, F12, F13
++
++#define VIDEOM_SCALE_FACTOR_PARAMETER2_REG 0x220 + VIDEOBASE_OFFSET //Scaling Parameters F20, F21, F22, F23
++
++#define VIDEOM_SCALE_FACTOR_PARAMETER3_REG 0x224 + VIDEOBASE_OFFSET //Scaling Parameters F30, F31, F32, F33
++
++#define VIDEOM_BCD_CONTROL_REG 0x22C + VIDEOBASE_OFFSET
++ //#define BCD_ENABLE 0x00000001 //Bit[0] Enable block change detection(BCD)
++ //#define BCD_TOLERANCE 0x00010000 //Bit[23:16]
++ // #define BCD_TOLERANCE_BIT 16 //flag as changed block when the video data difference greater
++ // #define BCD_TOLERANCE_MASK 0x00FF0000
++
++#define VIDEOM_CAPTURE_WINDOWS_REG 0x230 + VIDEOBASE_OFFSET
++ //#define RC4_TABLE_ADDR_ALIGN 7 //8 byte alignment
++ //#define RC4_TABLE_ADDR_MASK 0x0FFFFFFF
++
++#define VIDEOM_COMPRESS_WINDOWS_REG 0x234 + VIDEOBASE_OFFSET
++ //#define COMPRESS_VER_LINE 0x00000001 //Bit[12:0] Video compression vertical line total
++ //#define COMPRESS_VER_LINE_BIT 0
++ //#define COMPRESS_VER_LINE_MASK 0x00001FFF
++ //#define COMPRESS_HOR_PIXEL 0x00010000 //Bit[12:0] Video compression vertical line total
++ //#define COMPRESS_HOR_PIXEL_BIT 16
++ //#define COMPRESS_HOR_PIXEL_MASK 0x1FFF0000
++
++#define VIDEOM_COMPRESS_BUF_PROCESS_OFFSET_REG 0x238
++ //#define COMPRESS_BUF_PROCESS_OFFSET_ALIGN 127 //128 byte alignment
++ //#define COMPRESS_BUF_PROCESS_OFFSET_MASK 0x3FFFFF
++
++
++//For Compression
++#define VIDEOM_COMPRESS_BUF_READ_OFFSET_REG 0x23C + VIDEOBASE_OFFSET //For stream mode
++ //#define COMPRESS_BUF_READ_OFFSET_ALIGN 127 //128 byte alignment
++ //#define COMPRESS_BUF_READ_OFFSET_MASK 0x003FFFFF
++//For Decompression
++#define VIDEOM_DECOMPRESS_BUF_WRITE_OFFSET_REG 0x23C + VIDEOBASE_OFFSET //For stream mode
++ //#define DECOMPRESS_BUF_WRITE_OFFSET_ALIGN 127 //128 byte alignment
++ //#define DECOMPRESS_BUF_WRITE_OFFSET_MASK 0x003FFFFF
++
++#define VIDEOM_BUF_1_ADDR_REG 0x244 + VIDEOBASE_OFFSET //For Source Buffer in frame mode
++ //#define BUF_1_ADDR_ALIGN 255 //256 byte alignment
++ //#define BUF_1_ADDR_MASK 0x0FFFFFFF
++
++#define VIDEOM_BUF_LINE_OFFSET_REG 0x248 + VIDEOBASE_OFFSET //Must set both in Frame/Stream mode
++ //#define BUF_LINE_OFFSET_ALIGN 7 //8 byte alignment
++ //#define BUF_LINE_OFFSET_MASK 0x00003FFF
++
++#define VIDEOM_BUF_2_ADDR_REG 0x24C + VIDEOBASE_OFFSET //For BCD Buffer in frame mode
++ //#define BUF_2_ADDR_ALIGN 255 //256 byte alignment
++ //#define BUF_2_ADDR_MASK 0x0FFFFFFF
++
++#define VIDEOM_FLAG_BUF_ADDR_REG 0x250 + VIDEOBASE_OFFSET //For block change flag buffer
++ //#define FLAG_BUF_ADDR_ALIGN 7 //8 byte alignment
++ //#define FLAG_BUF_ADDR_MASK 0x0FFFFFFF
++
++#define VIDEOM_COMPRESS_BUF_ADDR_REG 0x254 + VIDEOBASE_OFFSET //For stream mode
++ //#define FLAG_BUF_ADDR_ALIGN 7 //8 byte alignment
++ //#define FLAG_BUF_ADDR_MASK 0x0FFFFFFF
++
++#define VIDEOM_BUF_CODEC_OFFSET_READ 0x25C + VIDEOBASE_OFFSET //For stream mode,
++ //#define BUF_CODEC_OFFSET_ALIGN 255 //256 byte alignment
++ //#define BUF_CODEC_OFFSET_MASK 0x003FFFFF
++
++#define VIDEOM_COMPRESS_CONTROL_REG 0x260 + VIDEOBASE_OFFSET
++ //#define JPEG_ONLY_ENCODE 0x00000001 //Bit[0] JPEG only encoding
++ // #define JPEG_MIX_MODE 0 //Enable JPEG/VQ mix mode encoding
++ // #define JPEG_ONLY_MODE 1 //JPEG encoding mode only
++ //#define VQ_4_COLOR_ENCODE 0x00000002 //Bit[1] Enable 4 color VQ encoding
++ // #define VQ_1_2_COLOR_MODE 0 //1 and 2 color mode VQ encoding
++ // #define VQ_4_COLOR_MODE 1 //1, 2 and 4 color VQ encoding
++ //#define QUALITY_CODEC_SETTING 0x00000004 //Bit[2] High and best video quality codec mode setting
++ // #define JPEG_CODEC_MODE 0 //not supported in best video quality mode
++ // #define QUANTI_CODEC_MODE 1
++ //#define JPEG_DUAL_QUALITY_EN 0x00000008 //Bit[3] JPEG dual quality mode
++ // #define EN_JPEG_DUAL_QUALITY 1 //enable(only for normal video quality mode)
++ //#define BEST_QUALITY_EN 0x00000010 //Bit[4] Best quality video mode enable
++ // #define EN_BEST_QUALITY 1 //enable(only for quantization codec mode)
++ //#define RC4_CRYPT_EN 0x00000020 //Bit[5] Enable RC4 encryption/decryption
++ // #define EN_RC4_CRYPT 1 //enable
++ //#define NORMAL_QUANTI_CHROMI_TABLE 0x00000040 //Bit[10:6] Normal video quality mode JPEG DCT chromi quantination table
++ // #define NORMAL_QUANTI_CHROMI_TABLE_BIT 6
++ // #define NORMAL_QUANTI_CHROMI_TABLE_MASK 0x000007C0
++ //#define NORMAL_QUANTI_LUMI_TABLE 0x00000800 //Bit[15:11] Normal video quality mode JPEG DCT lumi quantination table
++ // #define NORMAL_QUANTI_LUMI_TABLE_BIT 11
++ // #define NORMAL_QUANTI_LUMI_TABLE_MASK 0x0000F800
++ //#define HIGH_QUALITY_EN 0x00010000 //Bit[16] High video quality mode enable
++ // #define EN_HIGH_QUALITY 1 //Enable
++ //#define UV_CIR656_FORMAT 0x00080000 //Bit[19] UV fromat
++ // #define USE_UV_CIR656 1 //recommand
++ //#define HUFFMAN_TABLE_SELECT 0x00100000 //Bit[20] JPEG Huffman table combination
++ // #define DUAL_TABLE 0 //Dual Y, UV table
++ // #define SINGLE_TABLE 1 //Single Y table
++ // #define SINGLE_UV_TABLE 0x00200000 //1x: Single UV table
++ //#define HIGH_QUANTI_CHROMI_TABLE 0x00400000 //Bit[26:22] High quality JPEG DCT chromi quantization table
++ // #define HIGH_QUANTI_CHROMI_TABLE_BIT 22
++ // #define HIGH_QUANTI_CHROMI_TABLE_MASK 0x07C00000
++ //#define HIGH_DEQUANTI_VALUE 0x00400000 //Bit[26:22] High quality de-quantization value
++ // #define HIGH_DEQUANTI_VALUE_BIT 22
++ // #define HIGH_DEQUANTI_VALUE_MASK 0x07C00000
++ //#define HIGH_QUANTI_LUMI_TABLE 0x08000000 //Bit[31:27] High quality JPEG DCT lumi quantization table
++ // #define HIGH_QUANTI_LUMI_TABLE_BIT 27
++ // #define HIGH_QUANTI_LUMI_TABLE_MASK 0xF8000000
++ //#define BEST_DEQUANTI_VALUE 0x08000000 //Bit[31:27] Best quality de-quantization value
++ // #define BEST_QUANTI_VALUE_BIT 27
++ // #define BEST_QUANTI_VALUE_MASK 0xF8000000
++
++#define VIDEOM_QUANTI_TABLE_LOW_REG 0x264 + VIDEOBASE_OFFSET //Match with 0x60 Bit[10:6], Bit[15:11]
++// #define QUANTI_CHROMI_TABLE_LOW 0x00000001 //Bit[4:0] Normal video low quality block chromi quantization table
++// #define QUANTI_CHROMI_TABLE_LOW_BIT 0
++// #define QUANTI_CHROMI_TABLE_LOW_MASK 0x0000001F
++// #define QUANTI_LUMI_TABLE_LOW 0x00000020 //Bit[9:5] Normal video low quality block lumi quantization table
++// #define QUANTI_CHROMI_TABLE_LOW_BIT 5
++// #define QUANTI_CHROMI_TABLE_LOW_MASK 0x000003E0
++
++#define VIDEOM_QUANTI_VALUE_REG 0x268 + VIDEOBASE_OFFSET //Match with 0x60 Bit[26:22],Bit[31:27]
++// #define HIGH_QUANTI_VALUE 0x00000001 //Bit[14:0] High quality quantization value. Format is 1.14
++// #define HIGH_QUANTI_VALUE_BIT 0
++// #define HIGH_QUANTI_VALUE_MASK 0x00007FFF
++// #define BEST_QUANTI_VALUE 0x00010000 //Bit[30:16] Best quality quantization value. Format is 1.14
++// #define BEST_QUANTI_VALUE_BIT 16
++// #define BEST_QUANTI_VALUE_MASK 0x7FFF0000
++
++#define VIDEOM_BSD_PARA_REG 0x26C + VIDEOBASE_OFFSET //Video BSD Parameters Register
++// #define BSD_HIGH_THRES 0x00000001 //Bit[7:0] Block sharpness detection high threshold
++// #define BSD_HIGH_THRES_BIT 0
++// #define BSD_HIGH_THRES_MASK 0x000000FF
++// #define BSD_LOW_THRES 0x00000100 //Bit[15:8] Block shaprpness detection low threshold
++// #define BSD_LOW_THRES_BIT 8
++// #define BSD_LOW_THRES_MASK 0x0000FF00
++// #define BSD_HIGH_COUNTS 0x00010000 //Bit[21:16] Block sharpness detection high counts threshold
++// #define BSD_HIGH_COUNTS_BIT 16
++// #define BSD_HIGH_COUNTS_MASK 0x003F0000
++// #define BSD_LOW_COUNTS 0x01000000 //Bit[27:24] Block sharpness detection low counts threshold
++// #define BSD_LOW_COUNTS_BIT 24
++// #define BSD_LOW_COUNTS_MASK 0x3F000000
++
++#define VIDEOM_COMPRESS_FRAME_SIZE_REG 0x270 + VIDEOBASE_OFFSET
++// #define COMPRESS_FRAME_SIZE_READ 0x00000001 //Bit[19:0] Video compression frame size read back(number of DW)
++// #define COMPRESS_FRAME_SIZE_READ_BIT 0
++// #define COMPRESS_FRAME_SIZE_READ_MASK 0x000FFFFF
++
++#define VIDEOM_COMPRESS_BLOCK_COUNT_REG 0x274 + VIDEOBASE_OFFSET
++// #define COMPRESS_BLOCK_COUNT_READ 0x00000001 //Bit[15:0] Video compress block counter read back(number of blocks)
++// #define COMPRESS_BLOCK_COUNT_READ_BIT 0
++// #define COMPRESS_BLOCK_COUNT_READ_MASK 0x0000FFFF
++
++#define VIDEOM_COMPRESS_FRAME_END_READ 0x278 + VIDEOBASE_OFFSET //Video compression stream frame end pointer
++ //#define COMPRESS_FRAME_END_READ_ALIGN 7
++ //#define COMPRESS_FRAME_END_READ_MASK 0x003FFFFF
++
++#define VIDEOM_USER_DEFINE_HEADER_REG 0x280 + VIDEOBASE_OFFSET
++// #define USER_DEFINE_HEADER 0x00000001 //Bit[15:0] Video user defined header parameter
++// #define USER_DEFINE_HEADER_BIT 0
++// #define USER_DEFINE_HEADER_MASK 0x0000FFFF
++
++/****** VR300-VR3FC: General Control registers *****/
++#define VIDEO_CONTROL_REG 0x300 + VIDEOBASE_OFFSET
++ #define CODEC_DECOMPRESS_MODE 0x00000001 //Bit[0] Codec in de-compression mode
++ #define CODEC_DECOMPRESS_MODE_BIT 0
++ #define CODEC_DECOMPRESS_MODE_MASK 0x00000001
++ #define COMPRESS_MODE 0
++ #define DECOMPRESS_MODE 1
++ #define VIDEO_SAFE_MODE 0x00000002 //Bit[1] VIDEO SAFE MODE
++ #define VIDEO_SAFE_MODE_BIT 1
++ #define VIDEO_SAFE_MODE_OFF 0
++ #define VIDEO_SAFE_MODE_ON 1
++ #define DELAY_VSYNC 0x00000004 //Bit[2] Delay Internal VSYNC
++ #define DELAY_VSYNC_BIT 2
++ #define DELAY_VSYNC_MASK (1<<2)
++ #define DELAY_VSYNC_OFF (0<<2)
++ #define DELAY_VSYNC_EN (1<<2)
++ #define VER_DOWNSCALING_LINE_BUFFER_EN 0x00000010 //Bit[5:4] Video vertical downscaling line buffer enable
++ #define VER_LINE_BUFFER_MASK (3<<4)
++ #define LINE_BUFFER_OFF (0<<4)
++ #define LINE_BUFFER_VIDEO1 1
++ #define LINE_BUFFER_VIDEO2 2
++ #define LINE_BUFFER_VIDEOM 3
++ #define RC4_KEY_BUFFER_SELECTION (1UL<<6) //Bit[7:6] RC4 Key Buffer Selection
++ #define RC4_KEY_BUFFER_SELECTION_BIT 6
++ #define RC4_KEY_BUFFER_SELECTION_MASK (3UL<<6)
++ #define RC4_KEY_BUFFER_VIDEO1 0
++ #define RC4_KEY_BUFFER_VIDEO2 1
++ #define RC4_KEY_BUFFER_VIDEOM 2
++ #define RC4_INIT_RESET (1UL<<8) //Bit[8] RC4 initial reset
++ #define RC4_INIT_RESET_BIT 8
++ #define RC4_INIT_RESET_MASK (1UL<<8)
++ #define RC4_NORMAL_MODE 0
++ #define RC4_RESET_COUNTER 1
++ #define RC4_TEST_MODE (1UL<<9) //Bit[9] RC4 test mode
++ #define RC4_TEST_MODE_BIT 9
++ #define RC4_TEST_OFF 0
++ #define RC4_TEST_ON 1
++ #define RC4_SAVE_MODE (1UL<<14) //Bit[14] RC4 save mode
++ #define RC4_SAVE_MODE_BIT 14
++ #define RC4_SAVE_MODE_MASK (1UL<<14)
++ #define RC4_SAVE_MODE_OFF 0
++ #define RC4_SAVE_MODE_ON 1
++ #define RC4_NO_RESET_FRAME (1UL<<15) //Bit[15] RC4 no reset when frame completed
++ #define RC4_NO_RESET_FRAME_BIT 15
++ #define RC4_NO_RESET_FRAME_MASK (1UL<<15)
++ #define RC4_NO_RESET_FRAME_OFF 0 //Always reset
++ #define RC4_NO_RESET_FRAME_ON 1
++
++#define VIDEO_INT_CONTROL_EN_REG 0x304 + VIDEOBASE_OFFSET
++ #define VIDEO1_WATCH_DOG_INT_EN 0x00000001 //Bit[0] Enable Video1 mode detection watch dog out of lock interrupt
++ #define VIDEO1_INPUT_COMPLETE_INT_EN 0x00000002 //Bit[1] Enable Video1 video input complete interrupt (frame complete only for frame mode)
++ #define VIDEO1_PACKET_READY_INT_EN 0x00000004 //Bit[2] Enable Video1 packet ready interrupt
++ #define VIDEO1_COMPRESS_COMPLETE_INT_EN 0x00000008 //Bit[3] Enable Video1 compression complete interrupt
++ #define VIDEO1_MODE_DETECTION_READY_INT_EN 0x00000010 //Bit[4] Enable video1 mode detection ready interrupt
++ #define VIDEO1_FRAME_COMPLETE_INT_EN 0x00000020 //Bit[5] Enable Video1 frame complete interrupt (only for stream mode)
++ #define VIDEO1_STREAM_ERR_INT_EN 0x00000040 //Bit[6] Enable Video1 decode stream error interrupt
++ #define VIDEO2_WATCH_DOG_INT_EN 0x00000100 //Bit[8] Enable Video2 mode detection watch dog out of lock interrupt
++ #define VIDEO2_INPUT_COMPLETE_INT_EN 0x00000200 //Bit[9] Enable Video2 video input complete interrupt (frame complete only for frame mode)
++ #define VIDEO2_PACKET_READY_INT_EN 0x00000400 //Bit[10] Enable Video2 packet ready interrupt
++ #define VIDEO2_COMPRESS_COMPLETE_INT_EN 0x00000800 //Bit[11] Enable Video2 compression complete interrupt
++ #define VIDEO2_MODE_DETECTION_READY_INT_EN 0x00001000 //Bit[12] Enable video2 mode detection ready interrupt
++ #define VIDEO2_FRAME_COMPLETE_INT_EN 0x00002000 //Bit[13] Enable Video2 frame complete interrupt (only for stream mode)
++ #define VIDEO2_STREAM_ERR_INT_EN 0x00004000 //Bit[14] Enable Video2 decode stream error interrupt
++ #define VIDEOM_INPUT_COMPLETE_INT_EN 0x00010000 //Bit[16] Enable VideoM video input complete interrupt
++ #define VIDEOM_COMPRESS_COMPLETE_INT_EN 0x00020000 //Bit[17] Enable VideoM compression complete interrupt
++ #define VIDEOM_PACKET_READY_INT_EN 0x00040000 //Bit[18] Enable VideoM packet ready interrupt
++ #define VIDEOM_FRAME_COMPLETE_INT_EN 0x00080000 //Bit[19] Enable VideoM frame complete interrupt (only for stream mode)
++
++#define VIDEO_INT_CONTROL_READ_REG 0x308 + VIDEOBASE_OFFSET //Clear when write 1
++ #define VIDEO1_WATCH_DOG_READ 0x00000001 //Bit[0] Video1 mode detection watch dog out of lock interrupt status read back
++ #define VIDEO1_WATCH_DOG_BIT 0
++ #define VIDEO1_WATCH_DOG_MASK 0x00000001
++ #define VIDEO1_INPUT_COMPLETE_READ 0x00000002 //Bit[1] Video1 video input complete interrupt status read back (frame complete only for frame mode)
++ #define VIDEO1_INPUT_COMPLETE_BIT 1
++ #define VIDEO1_INPUT_COMPLETE_MASK 0x00000002
++ #define VIDEO1_PACKET_READY_READ 0x00000004 //Bit[2] Video1 packet ready interrupt status read back
++ #define VIDEO1_PACKET_READY_BIT 2
++ #define VIDEO1_PACKET_READY_MASK 0x00000004
++ #define VIDEO1_COMPRESS_COMPLETE_READ 0x00000008 //Bit[3] Video1 compression complete interrupt status read back
++ #define VIDEO1_COMPRESS_COMPLETE_BIT 3
++ #define VIDEO1_COMPRESS_COMPLETE_MASK 0x00000008
++ #define VIDEO1_MODE_DETECTION_READY_READ 0x00000010 //Bit[4] Video1 mode detection ready interrupt status read back
++ #define VIDEO1_MODE_DETECTION_READY_BIT 4
++ #define VIDEO1_FRAME_COMPLETE_READ 0x00000020 //Bit[5] Video1 frame complete interrupt status read back
++ #define VIDEO1_FRAME_COMPLETE_BIT 5
++ #define VIDEO1_FRAME_COMPLETE_MASK 0x00000020
++ #define VIDEO1_STREAM_ERR_READ 0x00000040 //Bit[6] Video1 decode stream error interrupt status read back
++ #define VIDEO1_STREAM_ERR_BIT 6
++ #define VIDEO1_STREAM_ERR_MASK 0x00000040
++ #define VIDEO2_WATCH_DOG_READ 0x00000100 //Bit[8] Video2 mode detection watch dog out of lock interrupt status read back
++ #define VIDEO2_WATCH_DOG_BIT 8
++ #define VIDEO2_WATCH_DOG_MASK 0x00000100
++ #define VIDEO2_INPUT_COMPLETE_READ 0x00000200 //Bit[9] Video2 video input complete interrupt status read back (frame complete only for frame mode)
++ #define VIDEO2_INPUT_COMPLETE_BIT 9
++ #define VIDEO2_INPUT_COMPLETE_MASK 0x00000200
++ #define VIDEO2_PACKET_READY_READ 0x00000400 //Bit[10] Video2 packet ready interrupt status read back
++ #define VIDEO2_PACKET_READY_BIT 10
++ #define VIDEO2_PACKET_READY_MASK 0x00000400
++ #define VIDEO2_COMPRESS_COMPLETE_READ 0x00000800 //Bit[11] Video2 compression complete interrupt status read back
++ #define VIDEO2_COMPRESS_COMPLETE_BIT 11
++ #define VIDEO2_COMPRESS_COMPLETE_MASK 0x00000800
++ #define VIDEO2_MODE_DETECTION_READY_READ 0x00001000 //Bit[12] Video2 mode detection ready interrupt status read back
++ #define VIDEO2_MODE_DETECTION_READY_BIT 12
++ #define VIDEO2_FRAME_COMPLETE_READ 0x00002000 //Bit[13] Video2 frame complete interrupt status read back
++ #define VIDEO2_FRAME_COMPLETE_BIT 13
++ #define VIDEO2_FRAME_COMPLETE_MASK 0x00002000
++ #define VIDEO2_STREAM_ERR_READ 0x00004000 //Bit[14] Video2 decode stream error interrupt status read back
++ #define VIDEO2_STREAM_ERR_BIT 14
++ #define VIDEO2_STREAM_ERR_MASK 0x00004000
++ //need check spec
++ #define VIDEOM_INPUT_COMPLETE_READ 0x00010000 //Bit[16] VideoM video input complete interrupt status read back
++ #define VIDEOM_INPUT_COMPLETE_BIT 16
++ #define VIDEOM_INPUT_COMPLETE_MASK 0x00010000
++ #define VIDEOM_COMPRESS_COMPLETE_READ 0x00020000 //Bit[17] VideoM compression complete interrupt status read back
++ #define VIDEOM_COMPRESS_COMPLETE_BIT 17
++ #define VIDEOM_COMPRESS_COMPLETE_MASK 0x00020000
++ #define VIDEOM_PACKET_READY_READ 0x00040000 //Bit[18] Clear Packet ready interrupt when write 1
++ #define VIDEOM_PACKET_READY_BIT 18
++ #define VIDEOM_PACKET_READY_MASK 0x00040000
++ #define VIDEOM_FRAME_COMPLETE_READ 0x00080000 //Bit[19] Clear Frame complete interrupt when write 1
++ #define VIDEOM_FRAME_COMPLETE_BIT 19
++ #define VIDEOM_FRAME_COMPLETE_MASK 0x00080000
++
++#define VIDEO_INT_CONTROL_CLEAR_REG 0x308 + VIDEOBASE_OFFSET //Clear when write 1
++ //Clear when write 1
++ #define VIDEO1_WATCH_DOG_CLEAR 0x00000001 //Bit[0] Clear mode detection watch dog out of lock interrupt when write 1
++ #define VIDEO1_INPUT_COMPLETE_CLEAR 0x00000002 //Bit[1] Clear video input complete interrupt when write 1 (frame complete only for frame mode)
++ #define VIDEO1_PACKET_READY_CLEAR 0x00000004 //Bit[2] Clear Packet ready interrupt when write 1
++ #define VIDEO1_PACKET_READY_CLEAR_BIT 2
++ #define VIDEO1_PACKET_READY_CLEAR_MASK 0x00000004
++ #define VIDEO1_COMPRESS_COMPLETE_CLEAR 0x00000008 //Bit[3] Clear video compression interrupt when write 1
++ #define VIDEO1_MODE_DETECTION_READY_CLEAR 0x00000010 //Bit[4] Clear Video1 Mode detection ready interrupt when write 1
++ #define VIDEO1_FRAME_COMPLETE_CLEAR 0x00000020 //Bit[5] Clear Frame complete interrupt when write 1
++ #define VIDEO1_FRAME_COMPLETE_CLEAR_BIT 5
++ #define VIDEO1_FRAME_COMPLETE_CLEAR_MASK 0x00000020
++ #define VIDEO1_STREAM_ERR_CLEAR 0x00000040 //Bit[6] Clear decode stream error interrupt when write 1
++ #define VIDEO2_WATCH_DOG_CLEAR 0x00000100 //Bit[8] Clear Mode detection interrupt when write 1
++ #define VIDEO2_INPUT_COMPLETE_CLEAR 0x00000200 //Bit[9] Clear video input complete interrupt when write 1
++ #define VIDEO2_PACKET_READY_CLEAR 0x00000400 //Bit[10] Clear packet ready interrupt when write 1
++ #define VIDEO2_COMPRESS_COMPLETE_CLEAR 0x00000800 //Bit[11] Clear video compression complete interrupt when write 1
++ #define VIDEO2_MODE_DETECTION_READY_CLEAR 0x00001000 //Bit[12] Clear Video2 Mode detection ready interrupt when write 1
++ #define VIDEO2_FRAME_COMPLETE_CLEAR 0x00002000 //Bit[13] Clear Frame complete interrupt when write 1 (frame complete only for frame mode)
++ #define VIDEO2_STREAM_ERR_CLEAR 0x00004000 //Bit[14] Clear Decode stream error interrupt when write 1
++ //need check spec
++ #define VIDEOM_INPUT_COMPLETE_CLEAR 0x00010000 //Bit[16] Clear video input complete interrupt when write 1
++ #define VIDEOM_COMPRESS_COMPLETE_CLEAR 0x00020000 //Bit[17] Clear compression complete interrupt when write 1
++ #define VIDEOM_COMPRESS_COMPLETE_CLEAR_BIT 17
++ #define VIDEOM_COMPRESS_COMPLETE_CLEAR_MASK 0x00020000
++ #define VIDEOM_PACKET_READY_CLEAR 0x00040000 //Bit[18] Clear compression complete interrupt when write 1
++ #define VIDEOM_PACKET_READY_CLEAR_BIT 18
++ #define VIDEOM_PACKET_READY_CLEAR_MASK 0x00040000
++ #define VIDEOM_FRAME_COMPLETE_CLEAR 0x00100000 //Bit[20] Clear Frame complete interrupt when write 1
++ #define VIDEOM_FRAME_COMPLETE_CLEAR_BIT 20
++ #define VIDEOM_FRAME_COMPLETE_CLEAR_MASK 0x00100000
++ #define VIDEOM_STREAM_ERR_CLEAR 0x00200000 //Bit[21] Clear decode stream error interrupt when write 1
++
++#define VIDEO_MODE_DETECTION_PARAM_REG 0x30C + VIDEOBASE_OFFSET
++ #define EDGE_PIXEL_THRES_BIT 8 //Bit[15:8] Mode detection edge pixel threshold
++ #define EDGE_PIXEL_THRES_MASK 0x0000FF00
++ #define VER_STABLE_MAX_BIT 16 //Bit[19:16] Mode detection vertical stable maximum
++ #define VER_STABLE_MAX_BIT_MASK 0x000F0000
++ #define HOR_STABLE_MAX_BIT 20 //Bit[23:20] Mode detection horizontal stable maximum
++ #define HOR_STABLE_MAX_BIT_MASK 0x00F00000
++ #define VER_STABLE_THRES_BIT 24 //Bit[27:24] Mode detection vertical stable threshold
++ #define VER_STABLE_THRES_BIT_MASK 0x0F000000
++ #define HOR_STABLE_THRES_BIT 28 //Bit[31:28] Mode detection horizontal stable threshold
++ #define HOR_STABLE_THRES_BIT_MASK 0xF0000000
++
++#define VIDEO_CRC_PRIMARY_REG 0x320 + VIDEOBASE_OFFSET
++ #define CRC_CHECK_EN 0x00000001 //Bit[0] Video port 1/2 Enable video capture write CRC check
++ #define CRC_CHECK_EN_BIT 0
++ #define CRC_CHECK_HIGH 0x00000002 //Bit[1] Video port 1/2 CRC check high bit only
++ #define CRC_CHECK_HIGH_BIT 1
++ #define SKIP_COUNT_MAX 0x00000004 //Bit[7:2] Video port 1/2 Max capture write skip count
++ #define SKIP_COUNT_MAX_BIT 2
++ #define SKIP_COUNT_MAX_MASK 0x000000FC
++ #define CRC_PRIMARY_POLY_LOW 0x00000100 //Bit[15:8] Primary CRC low 8-bit polynomial
++ #define CRC_RIMARY_POLY_LOW_BIT 8
++ #define CRC_RIMARY_POLY_LOW_MASK 0x0000FF00
++ #define CRC_PRIMARY_POLY_HIGH 0x00010000 //Bit[31:16] Primary CRC high 8-bit polynomial
++ #define CRC_RIMARY_POLY_HIGH_BIT 16
++ #define CRC_RIMARY_POLY_HIGH_MASK 0xFFFF0000
++
++
++#define VIDEO_CRC_SECOND_REG 0x324 + VIDEOBASE_OFFSET
++ #define CRC_SECOND_POLY_LOW 0x00000100 //Bit[15:8] Secondary CRC low 8-bit polynomial
++ #define CRC_SECOND_POLY_LOW_BIT 8
++ #define CRC_SECOND_POLY_LOW_MASK 0x0000FF00
++ #define CRC_SECOND_POLY_HIGH 0x00010000 //Bit[31:16] Secondary CRC high 8-bit polynomial
++ #define CRC_SECOND_POLY_HIGH_BIT 16
++ #define CRC_SECOND_POLY_HIGH_MASK 0xFFFF0000
++
++#define VIDEO1_RC4_KEYS_REG 0x400 + VIDEOBASE_OFFSET //Total Video1 RC4 Keys
++#define VIDEO2_RC4_KEYS_REG 0x500 + VIDEOBASE_OFFSET //Total Video2 RC4 Keys
++#define VIDEOM_RC4_KEYS_REG 0x600 + VIDEOBASE_OFFSET //Total VideoM RC4 Keys
++
++#endif /* end of _VREG_H_ */
++
+diff --git a/board/aspeed/ast2400/Makefile b/board/aspeed/ast2400/Makefile
+new file mode 100644
+index 0000000..1970ea1
+--- /dev/null
++++ b/board/aspeed/ast2400/Makefile
+@@ -0,0 +1,44 @@
++# 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$(BOARD).a
++
++COBJS := ast2400.o flash.o flash_spi.o pci.o crc32.o slt.o regtest.o vfun.o vhace.o crt.o videotest.o mactest.o hactest.o mictest.o
++
++ifeq ($(CONFIG_FPGA_ASPEED),y)
++SOBJS := platform_fpga.o
++else ifeq ($(CONFIG_SLT_ASPEED),y)
++SOBJS := platform_slt.o
++else
++SOBJS := platform.o
++endif
++
++SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS))
++SOBJS := $(addprefix $(obj),$(SOBJS))
++
++$(LIB): $(obj).depend $(OBJS) $(SOBJS)
++ $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
++
++clean:
++ rm -f $(SOBJS) $(OBJS)
++
++distclean: clean
++ rm -f $(LIB) core *.bak $(obj).depend
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude .depend
++
++#########################################################################
+diff --git a/board/aspeed/ast2400/aes.c b/board/aspeed/ast2400/aes.c
+new file mode 100755
+index 0000000..76262e7
+--- /dev/null
++++ b/board/aspeed/ast2400/aes.c
+@@ -0,0 +1,579 @@
++/*
++ * AES implementation
++ *
++ * 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
++ */
++
++/* uncomment the following line to run the test suite */
++
++/* #define TEST */
++
++/* uncomment the following line to use pre-computed tables */
++/* otherwise the tables will be generated at the first run */
++
++#define FIXED_TABLES
++
++#ifndef FIXED_TABLES
++
++/* forward S-box & tables */
++
++uint32 FSb[256];
++uint32 FT0[256];
++uint32 FT1[256];
++uint32 FT2[256];
++uint32 FT3[256];
++
++/* reverse S-box & tables */
++
++uint32 RSb[256];
++uint32 RT0[256];
++uint32 RT1[256];
++uint32 RT2[256];
++uint32 RT3[256];
++
++/* round constants */
++
++uint32 RCON[10];
++
++/* tables generation flag */
++
++int do_init = 1;
++
++/* tables generation routine */
++
++#define ROTR8(x) ( ( ( x << 24 ) & 0xFFFFFFFF ) | \
++ ( ( x & 0xFFFFFFFF ) >> 8 ) )
++
++#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) )
++#define MUL(x,y) ( ( x && y ) ? pow[(log[x] + log[y]) % 255] : 0 )
++
++void aes_gen_tables( void )
++{
++ int i;
++ uint8 x, y;
++ uint8 pow[256];
++ uint8 log[256];
++
++ /* compute pow and log tables over GF(2^8) */
++
++ for( i = 0, x = 1; i < 256; i++, x ^= XTIME( x ) )
++ {
++ pow[i] = x;
++ log[x] = i;
++ }
++
++ /* calculate the round constants */
++
++ for( i = 0, x = 1; i < 10; i++, x = XTIME( x ) )
++ {
++ RCON[i] = (uint32) x << 24;
++ }
++
++ /* generate the forward and reverse S-boxes */
++
++ FSb[0x00] = 0x63;
++ RSb[0x63] = 0x00;
++
++ for( i = 1; i < 256; i++ )
++ {
++ x = pow[255 - log[i]];
++
++ y = x; y = ( y << 1 ) | ( y >> 7 );
++ x ^= y; y = ( y << 1 ) | ( y >> 7 );
++ x ^= y; y = ( y << 1 ) | ( y >> 7 );
++ x ^= y; y = ( y << 1 ) | ( y >> 7 );
++ x ^= y ^ 0x63;
++
++ FSb[i] = x;
++ RSb[x] = i;
++ }
++
++ /* generate the forward and reverse tables */
++
++ for( i = 0; i < 256; i++ )
++ {
++ x = (unsigned char) FSb[i]; y = XTIME( x );
++
++ FT0[i] = (uint32) ( x ^ y ) ^
++ ( (uint32) x << 8 ) ^
++ ( (uint32) x << 16 ) ^
++ ( (uint32) y << 24 );
++
++ FT0[i] &= 0xFFFFFFFF;
++
++ FT1[i] = ROTR8( FT0[i] );
++ FT2[i] = ROTR8( FT1[i] );
++ FT3[i] = ROTR8( FT2[i] );
++
++ y = (unsigned char) RSb[i];
++
++ RT0[i] = ( (uint32) MUL( 0x0B, y ) ) ^
++ ( (uint32) MUL( 0x0D, y ) << 8 ) ^
++ ( (uint32) MUL( 0x09, y ) << 16 ) ^
++ ( (uint32) MUL( 0x0E, y ) << 24 );
++
++ RT0[i] &= 0xFFFFFFFF;
++
++ RT1[i] = ROTR8( RT0[i] );
++ RT2[i] = ROTR8( RT1[i] );
++ RT3[i] = ROTR8( RT2[i] );
++ }
++}
++
++#else
++
++/* forward S-box */
++
++static const uint32 FSb[256] =
++{
++ 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
++ 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
++ 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
++ 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
++ 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
++ 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
++ 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
++ 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
++ 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
++ 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
++ 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
++ 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
++ 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
++ 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
++ 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
++ 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
++ 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
++ 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
++ 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
++ 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
++ 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
++ 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
++ 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
++ 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
++ 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
++ 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
++ 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
++ 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
++ 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
++ 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
++ 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
++ 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
++};
++
++/* forward tables */
++
++#define FT \
++\
++ V(C6,63,63,A5), V(F8,7C,7C,84), V(EE,77,77,99), V(F6,7B,7B,8D), \
++ V(FF,F2,F2,0D), V(D6,6B,6B,BD), V(DE,6F,6F,B1), V(91,C5,C5,54), \
++ V(60,30,30,50), V(02,01,01,03), V(CE,67,67,A9), V(56,2B,2B,7D), \
++ V(E7,FE,FE,19), V(B5,D7,D7,62), V(4D,AB,AB,E6), V(EC,76,76,9A), \
++ V(8F,CA,CA,45), V(1F,82,82,9D), V(89,C9,C9,40), V(FA,7D,7D,87), \
++ V(EF,FA,FA,15), V(B2,59,59,EB), V(8E,47,47,C9), V(FB,F0,F0,0B), \
++ V(41,AD,AD,EC), V(B3,D4,D4,67), V(5F,A2,A2,FD), V(45,AF,AF,EA), \
++ V(23,9C,9C,BF), V(53,A4,A4,F7), V(E4,72,72,96), V(9B,C0,C0,5B), \
++ V(75,B7,B7,C2), V(E1,FD,FD,1C), V(3D,93,93,AE), V(4C,26,26,6A), \
++ V(6C,36,36,5A), V(7E,3F,3F,41), V(F5,F7,F7,02), V(83,CC,CC,4F), \
++ V(68,34,34,5C), V(51,A5,A5,F4), V(D1,E5,E5,34), V(F9,F1,F1,08), \
++ V(E2,71,71,93), V(AB,D8,D8,73), V(62,31,31,53), V(2A,15,15,3F), \
++ V(08,04,04,0C), V(95,C7,C7,52), V(46,23,23,65), V(9D,C3,C3,5E), \
++ V(30,18,18,28), V(37,96,96,A1), V(0A,05,05,0F), V(2F,9A,9A,B5), \
++ V(0E,07,07,09), V(24,12,12,36), V(1B,80,80,9B), V(DF,E2,E2,3D), \
++ V(CD,EB,EB,26), V(4E,27,27,69), V(7F,B2,B2,CD), V(EA,75,75,9F), \
++ V(12,09,09,1B), V(1D,83,83,9E), V(58,2C,2C,74), V(34,1A,1A,2E), \
++ V(36,1B,1B,2D), V(DC,6E,6E,B2), V(B4,5A,5A,EE), V(5B,A0,A0,FB), \
++ V(A4,52,52,F6), V(76,3B,3B,4D), V(B7,D6,D6,61), V(7D,B3,B3,CE), \
++ V(52,29,29,7B), V(DD,E3,E3,3E), V(5E,2F,2F,71), V(13,84,84,97), \
++ V(A6,53,53,F5), V(B9,D1,D1,68), V(00,00,00,00), V(C1,ED,ED,2C), \
++ V(40,20,20,60), V(E3,FC,FC,1F), V(79,B1,B1,C8), V(B6,5B,5B,ED), \
++ V(D4,6A,6A,BE), V(8D,CB,CB,46), V(67,BE,BE,D9), V(72,39,39,4B), \
++ V(94,4A,4A,DE), V(98,4C,4C,D4), V(B0,58,58,E8), V(85,CF,CF,4A), \
++ V(BB,D0,D0,6B), V(C5,EF,EF,2A), V(4F,AA,AA,E5), V(ED,FB,FB,16), \
++ V(86,43,43,C5), V(9A,4D,4D,D7), V(66,33,33,55), V(11,85,85,94), \
++ V(8A,45,45,CF), V(E9,F9,F9,10), V(04,02,02,06), V(FE,7F,7F,81), \
++ V(A0,50,50,F0), V(78,3C,3C,44), V(25,9F,9F,BA), V(4B,A8,A8,E3), \
++ V(A2,51,51,F3), V(5D,A3,A3,FE), V(80,40,40,C0), V(05,8F,8F,8A), \
++ V(3F,92,92,AD), V(21,9D,9D,BC), V(70,38,38,48), V(F1,F5,F5,04), \
++ V(63,BC,BC,DF), V(77,B6,B6,C1), V(AF,DA,DA,75), V(42,21,21,63), \
++ V(20,10,10,30), V(E5,FF,FF,1A), V(FD,F3,F3,0E), V(BF,D2,D2,6D), \
++ V(81,CD,CD,4C), V(18,0C,0C,14), V(26,13,13,35), V(C3,EC,EC,2F), \
++ V(BE,5F,5F,E1), V(35,97,97,A2), V(88,44,44,CC), V(2E,17,17,39), \
++ V(93,C4,C4,57), V(55,A7,A7,F2), V(FC,7E,7E,82), V(7A,3D,3D,47), \
++ V(C8,64,64,AC), V(BA,5D,5D,E7), V(32,19,19,2B), V(E6,73,73,95), \
++ V(C0,60,60,A0), V(19,81,81,98), V(9E,4F,4F,D1), V(A3,DC,DC,7F), \
++ V(44,22,22,66), V(54,2A,2A,7E), V(3B,90,90,AB), V(0B,88,88,83), \
++ V(8C,46,46,CA), V(C7,EE,EE,29), V(6B,B8,B8,D3), V(28,14,14,3C), \
++ V(A7,DE,DE,79), V(BC,5E,5E,E2), V(16,0B,0B,1D), V(AD,DB,DB,76), \
++ V(DB,E0,E0,3B), V(64,32,32,56), V(74,3A,3A,4E), V(14,0A,0A,1E), \
++ V(92,49,49,DB), V(0C,06,06,0A), V(48,24,24,6C), V(B8,5C,5C,E4), \
++ V(9F,C2,C2,5D), V(BD,D3,D3,6E), V(43,AC,AC,EF), V(C4,62,62,A6), \
++ V(39,91,91,A8), V(31,95,95,A4), V(D3,E4,E4,37), V(F2,79,79,8B), \
++ V(D5,E7,E7,32), V(8B,C8,C8,43), V(6E,37,37,59), V(DA,6D,6D,B7), \
++ V(01,8D,8D,8C), V(B1,D5,D5,64), V(9C,4E,4E,D2), V(49,A9,A9,E0), \
++ V(D8,6C,6C,B4), V(AC,56,56,FA), V(F3,F4,F4,07), V(CF,EA,EA,25), \
++ V(CA,65,65,AF), V(F4,7A,7A,8E), V(47,AE,AE,E9), V(10,08,08,18), \
++ V(6F,BA,BA,D5), V(F0,78,78,88), V(4A,25,25,6F), V(5C,2E,2E,72), \
++ V(38,1C,1C,24), V(57,A6,A6,F1), V(73,B4,B4,C7), V(97,C6,C6,51), \
++ V(CB,E8,E8,23), V(A1,DD,DD,7C), V(E8,74,74,9C), V(3E,1F,1F,21), \
++ V(96,4B,4B,DD), V(61,BD,BD,DC), V(0D,8B,8B,86), V(0F,8A,8A,85), \
++ V(E0,70,70,90), V(7C,3E,3E,42), V(71,B5,B5,C4), V(CC,66,66,AA), \
++ V(90,48,48,D8), V(06,03,03,05), V(F7,F6,F6,01), V(1C,0E,0E,12), \
++ V(C2,61,61,A3), V(6A,35,35,5F), V(AE,57,57,F9), V(69,B9,B9,D0), \
++ V(17,86,86,91), V(99,C1,C1,58), V(3A,1D,1D,27), V(27,9E,9E,B9), \
++ V(D9,E1,E1,38), V(EB,F8,F8,13), V(2B,98,98,B3), V(22,11,11,33), \
++ V(D2,69,69,BB), V(A9,D9,D9,70), V(07,8E,8E,89), V(33,94,94,A7), \
++ V(2D,9B,9B,B6), V(3C,1E,1E,22), V(15,87,87,92), V(C9,E9,E9,20), \
++ V(87,CE,CE,49), V(AA,55,55,FF), V(50,28,28,78), V(A5,DF,DF,7A), \
++ V(03,8C,8C,8F), V(59,A1,A1,F8), V(09,89,89,80), V(1A,0D,0D,17), \
++ V(65,BF,BF,DA), V(D7,E6,E6,31), V(84,42,42,C6), V(D0,68,68,B8), \
++ V(82,41,41,C3), V(29,99,99,B0), V(5A,2D,2D,77), V(1E,0F,0F,11), \
++ V(7B,B0,B0,CB), V(A8,54,54,FC), V(6D,BB,BB,D6), V(2C,16,16,3A)
++
++#define V(a,b,c,d) 0x##a##b##c##d
++static const uint32 FT0[256] = { FT };
++#undef V
++
++#define V(a,b,c,d) 0x##d##a##b##c
++static const uint32 FT1[256] = { FT };
++#undef V
++
++#define V(a,b,c,d) 0x##c##d##a##b
++static const uint32 FT2[256] = { FT };
++#undef V
++
++#define V(a,b,c,d) 0x##b##c##d##a
++static const uint32 FT3[256] = { FT };
++#undef V
++
++#undef FT
++
++/* reverse S-box */
++
++static const uint32 RSb[256] =
++{
++ 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
++ 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
++ 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
++ 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
++ 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
++ 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
++ 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
++ 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
++ 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
++ 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
++ 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
++ 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
++ 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
++ 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
++ 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
++ 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
++ 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
++ 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
++ 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
++ 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
++ 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
++ 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
++ 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
++ 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
++ 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
++ 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
++ 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
++ 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
++ 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
++ 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
++ 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
++ 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
++};
++
++/* reverse tables */
++
++#define RT \
++\
++ V(51,F4,A7,50), V(7E,41,65,53), V(1A,17,A4,C3), V(3A,27,5E,96), \
++ V(3B,AB,6B,CB), V(1F,9D,45,F1), V(AC,FA,58,AB), V(4B,E3,03,93), \
++ V(20,30,FA,55), V(AD,76,6D,F6), V(88,CC,76,91), V(F5,02,4C,25), \
++ V(4F,E5,D7,FC), V(C5,2A,CB,D7), V(26,35,44,80), V(B5,62,A3,8F), \
++ V(DE,B1,5A,49), V(25,BA,1B,67), V(45,EA,0E,98), V(5D,FE,C0,E1), \
++ V(C3,2F,75,02), V(81,4C,F0,12), V(8D,46,97,A3), V(6B,D3,F9,C6), \
++ V(03,8F,5F,E7), V(15,92,9C,95), V(BF,6D,7A,EB), V(95,52,59,DA), \
++ V(D4,BE,83,2D), V(58,74,21,D3), V(49,E0,69,29), V(8E,C9,C8,44), \
++ V(75,C2,89,6A), V(F4,8E,79,78), V(99,58,3E,6B), V(27,B9,71,DD), \
++ V(BE,E1,4F,B6), V(F0,88,AD,17), V(C9,20,AC,66), V(7D,CE,3A,B4), \
++ V(63,DF,4A,18), V(E5,1A,31,82), V(97,51,33,60), V(62,53,7F,45), \
++ V(B1,64,77,E0), V(BB,6B,AE,84), V(FE,81,A0,1C), V(F9,08,2B,94), \
++ V(70,48,68,58), V(8F,45,FD,19), V(94,DE,6C,87), V(52,7B,F8,B7), \
++ V(AB,73,D3,23), V(72,4B,02,E2), V(E3,1F,8F,57), V(66,55,AB,2A), \
++ V(B2,EB,28,07), V(2F,B5,C2,03), V(86,C5,7B,9A), V(D3,37,08,A5), \
++ V(30,28,87,F2), V(23,BF,A5,B2), V(02,03,6A,BA), V(ED,16,82,5C), \
++ V(8A,CF,1C,2B), V(A7,79,B4,92), V(F3,07,F2,F0), V(4E,69,E2,A1), \
++ V(65,DA,F4,CD), V(06,05,BE,D5), V(D1,34,62,1F), V(C4,A6,FE,8A), \
++ V(34,2E,53,9D), V(A2,F3,55,A0), V(05,8A,E1,32), V(A4,F6,EB,75), \
++ V(0B,83,EC,39), V(40,60,EF,AA), V(5E,71,9F,06), V(BD,6E,10,51), \
++ V(3E,21,8A,F9), V(96,DD,06,3D), V(DD,3E,05,AE), V(4D,E6,BD,46), \
++ V(91,54,8D,B5), V(71,C4,5D,05), V(04,06,D4,6F), V(60,50,15,FF), \
++ V(19,98,FB,24), V(D6,BD,E9,97), V(89,40,43,CC), V(67,D9,9E,77), \
++ V(B0,E8,42,BD), V(07,89,8B,88), V(E7,19,5B,38), V(79,C8,EE,DB), \
++ V(A1,7C,0A,47), V(7C,42,0F,E9), V(F8,84,1E,C9), V(00,00,00,00), \
++ V(09,80,86,83), V(32,2B,ED,48), V(1E,11,70,AC), V(6C,5A,72,4E), \
++ V(FD,0E,FF,FB), V(0F,85,38,56), V(3D,AE,D5,1E), V(36,2D,39,27), \
++ V(0A,0F,D9,64), V(68,5C,A6,21), V(9B,5B,54,D1), V(24,36,2E,3A), \
++ V(0C,0A,67,B1), V(93,57,E7,0F), V(B4,EE,96,D2), V(1B,9B,91,9E), \
++ V(80,C0,C5,4F), V(61,DC,20,A2), V(5A,77,4B,69), V(1C,12,1A,16), \
++ V(E2,93,BA,0A), V(C0,A0,2A,E5), V(3C,22,E0,43), V(12,1B,17,1D), \
++ V(0E,09,0D,0B), V(F2,8B,C7,AD), V(2D,B6,A8,B9), V(14,1E,A9,C8), \
++ V(57,F1,19,85), V(AF,75,07,4C), V(EE,99,DD,BB), V(A3,7F,60,FD), \
++ V(F7,01,26,9F), V(5C,72,F5,BC), V(44,66,3B,C5), V(5B,FB,7E,34), \
++ V(8B,43,29,76), V(CB,23,C6,DC), V(B6,ED,FC,68), V(B8,E4,F1,63), \
++ V(D7,31,DC,CA), V(42,63,85,10), V(13,97,22,40), V(84,C6,11,20), \
++ V(85,4A,24,7D), V(D2,BB,3D,F8), V(AE,F9,32,11), V(C7,29,A1,6D), \
++ V(1D,9E,2F,4B), V(DC,B2,30,F3), V(0D,86,52,EC), V(77,C1,E3,D0), \
++ V(2B,B3,16,6C), V(A9,70,B9,99), V(11,94,48,FA), V(47,E9,64,22), \
++ V(A8,FC,8C,C4), V(A0,F0,3F,1A), V(56,7D,2C,D8), V(22,33,90,EF), \
++ V(87,49,4E,C7), V(D9,38,D1,C1), V(8C,CA,A2,FE), V(98,D4,0B,36), \
++ V(A6,F5,81,CF), V(A5,7A,DE,28), V(DA,B7,8E,26), V(3F,AD,BF,A4), \
++ V(2C,3A,9D,E4), V(50,78,92,0D), V(6A,5F,CC,9B), V(54,7E,46,62), \
++ V(F6,8D,13,C2), V(90,D8,B8,E8), V(2E,39,F7,5E), V(82,C3,AF,F5), \
++ V(9F,5D,80,BE), V(69,D0,93,7C), V(6F,D5,2D,A9), V(CF,25,12,B3), \
++ V(C8,AC,99,3B), V(10,18,7D,A7), V(E8,9C,63,6E), V(DB,3B,BB,7B), \
++ V(CD,26,78,09), V(6E,59,18,F4), V(EC,9A,B7,01), V(83,4F,9A,A8), \
++ V(E6,95,6E,65), V(AA,FF,E6,7E), V(21,BC,CF,08), V(EF,15,E8,E6), \
++ V(BA,E7,9B,D9), V(4A,6F,36,CE), V(EA,9F,09,D4), V(29,B0,7C,D6), \
++ V(31,A4,B2,AF), V(2A,3F,23,31), V(C6,A5,94,30), V(35,A2,66,C0), \
++ V(74,4E,BC,37), V(FC,82,CA,A6), V(E0,90,D0,B0), V(33,A7,D8,15), \
++ V(F1,04,98,4A), V(41,EC,DA,F7), V(7F,CD,50,0E), V(17,91,F6,2F), \
++ V(76,4D,D6,8D), V(43,EF,B0,4D), V(CC,AA,4D,54), V(E4,96,04,DF), \
++ V(9E,D1,B5,E3), V(4C,6A,88,1B), V(C1,2C,1F,B8), V(46,65,51,7F), \
++ V(9D,5E,EA,04), V(01,8C,35,5D), V(FA,87,74,73), V(FB,0B,41,2E), \
++ V(B3,67,1D,5A), V(92,DB,D2,52), V(E9,10,56,33), V(6D,D6,47,13), \
++ V(9A,D7,61,8C), V(37,A1,0C,7A), V(59,F8,14,8E), V(EB,13,3C,89), \
++ V(CE,A9,27,EE), V(B7,61,C9,35), V(E1,1C,E5,ED), V(7A,47,B1,3C), \
++ V(9C,D2,DF,59), V(55,F2,73,3F), V(18,14,CE,79), V(73,C7,37,BF), \
++ V(53,F7,CD,EA), V(5F,FD,AA,5B), V(DF,3D,6F,14), V(78,44,DB,86), \
++ V(CA,AF,F3,81), V(B9,68,C4,3E), V(38,24,34,2C), V(C2,A3,40,5F), \
++ V(16,1D,C3,72), V(BC,E2,25,0C), V(28,3C,49,8B), V(FF,0D,95,41), \
++ V(39,A8,01,71), V(08,0C,B3,DE), V(D8,B4,E4,9C), V(64,56,C1,90), \
++ V(7B,CB,84,61), V(D5,32,B6,70), V(48,6C,5C,74), V(D0,B8,57,42)
++
++#define V(a,b,c,d) 0x##a##b##c##d
++static const uint32 RT0[256] = { RT };
++#undef V
++
++#define V(a,b,c,d) 0x##d##a##b##c
++static const uint32 RT1[256] = { RT };
++#undef V
++
++#define V(a,b,c,d) 0x##c##d##a##b
++static const uint32 RT2[256] = { RT };
++#undef V
++
++#define V(a,b,c,d) 0x##b##c##d##a
++static const uint32 RT3[256] = { RT };
++#undef V
++
++#undef RT
++
++/* round constants */
++
++static const uint32 RCON[10] =
++{
++ 0x01000000, 0x02000000, 0x04000000, 0x08000000,
++ 0x10000000, 0x20000000, 0x40000000, 0x80000000,
++ 0x1B000000, 0x36000000
++};
++
++int do_init = 0;
++
++void aes_gen_tables( void )
++{
++}
++
++#endif
++
++/* platform-independant 32-bit integer manipulation macros */
++
++#define GET_UINT32_aes(n,b,i) \
++{ \
++ (n) = ( (uint32) (b)[(i) ] << 24 ) \
++ | ( (uint32) (b)[(i) + 1] << 16 ) \
++ | ( (uint32) (b)[(i) + 2] << 8 ) \
++ | ( (uint32) (b)[(i) + 3] ); \
++}
++
++#define PUT_UINT32_aes(n,b,i) \
++{ \
++ (b)[(i) ] = (uint8) ( (n) >> 24 ); \
++ (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \
++ (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \
++ (b)[(i) + 3] = (uint8) ( (n) ); \
++}
++
++/* decryption key schedule tables */
++
++int KT_init = 1;
++
++uint32 KT0[256];
++uint32 KT1[256];
++uint32 KT2[256];
++uint32 KT3[256];
++
++/* AES key scheduling routine */
++int aes_set_key( aes_context *ctx, uint8 *key, int nbits )
++{
++ int i;
++ uint32 *RK, *SK;
++
++ if( do_init )
++ {
++ aes_gen_tables();
++
++ do_init = 0;
++ }
++
++ switch( nbits )
++ {
++ case 128: ctx->nr = 10; break;
++ case 192: ctx->nr = 12; break;
++ case 256: ctx->nr = 14; break;
++ default : return( 1 );
++ }
++
++ RK = ctx->erk;
++
++ for( i = 0; i < (nbits >> 5); i++ )
++ {
++ GET_UINT32_aes( RK[i], key, i * 4 );
++ }
++
++ /* setup encryption round keys */
++
++ switch( nbits )
++ {
++ case 128:
++
++ for( i = 0; i < 10; i++, RK += 4 )
++ {
++ RK[4] = RK[0] ^ RCON[i] ^
++ ( FSb[ (uint8) ( RK[3] >> 16 ) ] << 24 ) ^
++ ( FSb[ (uint8) ( RK[3] >> 8 ) ] << 16 ) ^
++ ( FSb[ (uint8) ( RK[3] ) ] << 8 ) ^
++ ( FSb[ (uint8) ( RK[3] >> 24 ) ] );
++
++ RK[5] = RK[1] ^ RK[4];
++ RK[6] = RK[2] ^ RK[5];
++ RK[7] = RK[3] ^ RK[6];
++ }
++ break;
++
++ case 192:
++
++ for( i = 0; i < 8; i++, RK += 6 )
++ {
++ RK[6] = RK[0] ^ RCON[i] ^
++ ( FSb[ (uint8) ( RK[5] >> 16 ) ] << 24 ) ^
++ ( FSb[ (uint8) ( RK[5] >> 8 ) ] << 16 ) ^
++ ( FSb[ (uint8) ( RK[5] ) ] << 8 ) ^
++ ( FSb[ (uint8) ( RK[5] >> 24 ) ] );
++
++ RK[7] = RK[1] ^ RK[6];
++ RK[8] = RK[2] ^ RK[7];
++ RK[9] = RK[3] ^ RK[8];
++ RK[10] = RK[4] ^ RK[9];
++ RK[11] = RK[5] ^ RK[10];
++ }
++ break;
++
++ case 256:
++
++ for( i = 0; i < 7; i++, RK += 8 )
++ {
++ RK[8] = RK[0] ^ RCON[i] ^
++ ( FSb[ (uint8) ( RK[7] >> 16 ) ] << 24 ) ^
++ ( FSb[ (uint8) ( RK[7] >> 8 ) ] << 16 ) ^
++ ( FSb[ (uint8) ( RK[7] ) ] << 8 ) ^
++ ( FSb[ (uint8) ( RK[7] >> 24 ) ] );
++
++ RK[9] = RK[1] ^ RK[8];
++ RK[10] = RK[2] ^ RK[9];
++ RK[11] = RK[3] ^ RK[10];
++
++ RK[12] = RK[4] ^
++ ( FSb[ (uint8) ( RK[11] >> 24 ) ] << 24 ) ^
++ ( FSb[ (uint8) ( RK[11] >> 16 ) ] << 16 ) ^
++ ( FSb[ (uint8) ( RK[11] >> 8 ) ] << 8 ) ^
++ ( FSb[ (uint8) ( RK[11] ) ] );
++
++ RK[13] = RK[5] ^ RK[12];
++ RK[14] = RK[6] ^ RK[13];
++ RK[15] = RK[7] ^ RK[14];
++ }
++ break;
++ }
++
++ /* setup decryption round keys */
++
++ if( KT_init )
++ {
++ for( i = 0; i < 256; i++ )
++ {
++ KT0[i] = RT0[ FSb[i] ];
++ KT1[i] = RT1[ FSb[i] ];
++ KT2[i] = RT2[ FSb[i] ];
++ KT3[i] = RT3[ FSb[i] ];
++ }
++
++ KT_init = 0;
++ }
++
++ SK = ctx->drk;
++
++ *SK++ = *RK++;
++ *SK++ = *RK++;
++ *SK++ = *RK++;
++ *SK++ = *RK++;
++
++ for( i = 1; i < ctx->nr; i++ )
++ {
++ RK -= 8;
++
++ *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
++ KT1[ (uint8) ( *RK >> 16 ) ] ^
++ KT2[ (uint8) ( *RK >> 8 ) ] ^
++ KT3[ (uint8) ( *RK ) ]; RK++;
++
++ *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
++ KT1[ (uint8) ( *RK >> 16 ) ] ^
++ KT2[ (uint8) ( *RK >> 8 ) ] ^
++ KT3[ (uint8) ( *RK ) ]; RK++;
++
++ *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
++ KT1[ (uint8) ( *RK >> 16 ) ] ^
++ KT2[ (uint8) ( *RK >> 8 ) ] ^
++ KT3[ (uint8) ( *RK ) ]; RK++;
++
++ *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
++ KT1[ (uint8) ( *RK >> 16 ) ] ^
++ KT2[ (uint8) ( *RK >> 8 ) ] ^
++ KT3[ (uint8) ( *RK ) ]; RK++;
++ }
++
++ RK -= 8;
++
++ *SK++ = *RK++;
++ *SK++ = *RK++;
++ *SK++ = *RK++;
++ *SK++ = *RK++;
++
++ return( 0 );
++}
+diff --git a/board/aspeed/ast2400/ast2400.c b/board/aspeed/ast2400/ast2400.c
+new file mode 100644
+index 0000000..65bccbe
+--- /dev/null
++++ b/board/aspeed/ast2400/ast2400.c
+@@ -0,0 +1,304 @@
++/*
++ * 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 <common.h>
++#include <command.h>
++#include <pci.h>
++
++int board_init (void)
++{
++ DECLARE_GLOBAL_DATA_PTR;
++ unsigned char data;
++ unsigned long gpio;
++ unsigned long reg;
++
++ /* AHB Controller */
++ *((volatile ulong*) 0x1E600000) = 0xAEED1A03; /* unlock AHB controller */
++ *((volatile ulong*) 0x1E60008C) |= 0x01; /* map DRAM to 0x00000000 */
++
++ /* Flash Controller */
++#ifdef CONFIG_FLASH_AST2300
++ *((volatile ulong*) 0x1e620000) |= 0x800f0000; /* enable Flash Write */
++#else
++ *((volatile ulong*) 0x16000000) |= 0x00001c00; /* enable Flash Write */
++#endif
++
++ /* SCU */
++ *((volatile ulong*) 0x1e6e2000) = 0x1688A8A8; /* unlock SCU */
++ reg = *((volatile ulong*) 0x1e6e2008);
++ reg &= 0x1c0fffff;
++ reg |= 0x61800000; /* PCLK = HPLL/8 */
++#ifdef CONFIG_AST1070
++ //check lpc or lpc+ mode
++////////////////////////////////////////////////////////////////////////
++ gpio = *((volatile ulong*) 0x1e780070); /* mode check */
++ if(gpio & 0x2)
++ reg |= 0x100000; /* LHCLK = HPLL/4 */
++ else
++ reg |= 0x300000; /* LHCLK = HPLL/8 */
++
++ reg |= 0x80000; /* enable LPC Host Clock */
++
++ *((volatile ulong*) 0x1e6e2008) = reg;
++
++ reg = *((volatile ulong*) 0x1e6e200c); /* enable LPC clock */
++ *((volatile ulong*) 0x1e6e200c) &= ~(1 << 28);
++
++ if(gpio & 0x2) {
++
++ //use LPC+ for sys clk
++ // set OSCCLK = VPLL1
++ *((volatile ulong*) 0x1e6e2010) = 0x18;
++
++ // enable OSCCLK
++ reg = *((volatile ulong*) 0x1e6e202c);
++ reg |= 0x00000002;
++ *((volatile ulong*) 0x1e6e202c) = reg;
++ } else {
++ // USE LPC use D2 clk
++ /*set VPPL1 */
++ *((volatile ulong*) 0x1e6e201c) = 0x6420;
++
++ // set d2-pll & enable d2-pll D[21:20], D[4]
++ reg = *((volatile ulong*) 0x1e6e202c);
++ reg &= 0xffcfffef;
++ reg |= 0x00200010;
++ *((volatile ulong*) 0x1e6e202c) = reg;
++
++ // set OSCCLK = VPLL1
++ *((volatile ulong*) 0x1e6e2010) = 0x8;
++
++ // enable OSCCLK
++ reg = *((volatile ulong*) 0x1e6e202c);
++ reg &= 0xfffffffd;
++ reg |= 0x00000002;
++ *((volatile ulong*) 0x1e6e202c) = reg;
++ }
++#else
++ *((volatile ulong*) 0x1e6e2008) = reg;
++#endif
++ reg = *((volatile ulong*) 0x1e6e200c); /* enable 2D Clk */
++ *((volatile ulong*) 0x1e6e200c) &= 0xFFFFFFFD;
++/* enable wide screen. If your video driver does not support wide screen, don't
++enable this bit 0x1e6e2040 D[0]*/
++ reg = *((volatile ulong*) 0x1e6e2040);
++ *((volatile ulong*) 0x1e6e2040) |= 0x01;
++
++ /* arch number */
++ gd->bd->bi_arch_number = MACH_TYPE_ASPEED;
++
++ /* adress of boot parameters */
++ gd->bd->bi_boot_params = 0x40000100;
++
++ return 0;
++}
++
++int dram_init (void)
++{
++ DECLARE_GLOBAL_DATA_PTR;
++
++ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
++ gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
++
++ return 0;
++}
++
++/*
++SCU7C: Silicon Revision ID Register
++D[31:24]: Chip ID
++0: AST2050/AST2100/AST2150/AST2200/AST3000
++1: AST2300
++
++D[23:16] Silicon revision ID for AST2300 generation and later
++0: A0
++1: A1
++2: A2
++.
++.
++.
++FPGA revision starts from 0x80
++
++
++D[11:8] Bounding option
++
++D[7:0] Silicon revision ID for AST2050/AST2100 generation (for software compatible)
++0: A0
++1: A1
++2: A2
++3: A3
++.
++.
++FPGA revision starts from 0x08, 8~10 means A0, 11+ means A1, AST2300 should be assigned to 3
++*/
++int wait_calibration_done()
++{
++ DECLARE_GLOBAL_DATA_PTR;
++ unsigned char data;
++ unsigned long reg, count = 0;
++
++ do {
++ udelay(1000);
++ count++;
++ if (count >= 1000) {
++
++ return 1;
++ }
++ } while ((*(volatile ulong*) 0x1e6ec000) & 0xf00);
++
++// printf ("count = %d\n", count);
++
++ return 0;
++}
++
++/* AST1070 Calibration
++Program 0x101 to 0x1e6ec000
++Wait till 1e6ec000 [8] = 0
++Check 0x1e6ec004 = 0x5a5a5a5a
++*/
++int ast1070_calibration()
++{
++ DECLARE_GLOBAL_DATA_PTR;
++ unsigned char data;
++ unsigned long reg, i, j;
++
++ //only for 2 chip
++ for (i = 0; i < 2; i++) {
++ for (j = 0; j < 4; j++) {
++// printf ("chip = %d, delay = %d\n", i, j);
++ *((volatile ulong*) 0x1e6ec000) = (j << (12 + i * 2)) + (1 << (8 + i)) + 0x01;
++// printf ("1e6ec000 = %x\n", *(volatile ulong*)0x1e6ec000);
++ if (!wait_calibration_done()) {
++ if ((*(volatile ulong*) 0x1e6ec004) == 0x5a5a5a5a) {
++// printf ("calibration result: chip %d pass, timing = %d\n", i, j);
++ break;
++ }
++ else {
++// printf ("calibration result: chip %d fail, timing = %d\n", i, j);
++ }
++ }
++ }
++ }
++
++ return 0;
++}
++
++int misc_init_r(void)
++{
++ unsigned int reg, reg1, revision, chip_id, lpc_plus;
++
++#ifdef CONFIG_AST1070
++ //Reset AST1070 and AST2400 engine [bit 23:15]
++ reg = *((volatile ulong*) 0x1e7890a0);
++ reg &= ~0x808000;
++ *((volatile ulong*) 0x1e7890a0) = reg;
++
++ udelay(5000);
++
++ lpc_plus = (*((volatile ulong*) 0x1e780070)) & 0x2;
++
++ reg = *((volatile ulong*) 0x1e7890a0);
++ reg |= 0x800000;
++ *((volatile ulong*) 0x1e7890a0) = reg;
++
++ udelay(1000);
++
++ reg = *((volatile ulong*) 0x1e7890a0);
++ reg |= 0x008000;
++ *((volatile ulong*) 0x1e7890a0) = reg;
++
++
++ if(lpc_plus) {
++ *((volatile ulong*) 0x1E60008C) |= 0x011; /* map DRAM to 0x00000000 and LPC+ 0x70000000*/
++
++ //SCU multi-Function pin
++ reg = *((volatile ulong*) 0x1e6e2090);
++ reg |= (1 << 30);
++ *((volatile ulong*) 0x1e6e2090) = reg;
++ //LPC+ Engine Enable
++ reg = *((volatile ulong*) 0x1e6ec000);
++ reg |= 1;
++ *((volatile ulong*) 0x1e6ec000) = reg;
++
++ ast1070_calibration();
++
++ } else {
++ // enable AST1050's LPC master
++ reg = *((volatile ulong*) 0x1e7890a0);
++ *((volatile ulong*) 0x1e7890a0) |= 0x11;
++
++ }
++
++#endif
++ /* Show H/W Version */
++ reg1 = (unsigned int) (*((ulong*) 0x1e6e207c));
++ chip_id = (reg1 & 0xff000000) >> 24;
++ revision = (reg1 & 0xff0000) >> 16;
++
++ puts ("H/W: ");
++ if (chip_id == 1) {
++ if (revision >= 0x80) {
++ printf("AST2300 series FPGA Rev. %02x \n", revision);
++ }
++ else {
++ printf("AST2300 series chip Rev. %02x \n", revision);
++ }
++ }
++ else if (chip_id == 2) {
++ printf("AST2400 series chip Rev. %02x \n", revision);
++ }
++ else if (chip_id == 0) {
++ printf("AST2050/AST2150 series chip\n");
++ }
++
++#ifdef CONFIG_AST1070
++ if(lpc_plus) {
++ puts ("C/C: LPC+ :");
++ revision = (unsigned int) (*((ulong*) 0x70002034));
++ printf("AST1070 ID [%08x] ", revision);
++
++ if((*((volatile ulong*) 0x1e780070)) & 0x4) {
++ if((unsigned int) (*((ulong*) 0x70012034)) == 0x10700001)
++ printf(", 2nd : AST1070 ID [%08x] \n", (unsigned int) (*((ulong*) 0x70012034)));
++ else
++ printf("\n");
++ } else {
++ printf("\n");
++ }
++ } else {
++ puts ("C/C: LPC :");
++ revision = (unsigned int) (*((ulong*) 0x60002034));
++ printf("LPC : AST1070 ID [%08x] \n", revision);
++
++ }
++#endif
++
++#ifdef CONFIG_PCI
++ pci_init ();
++#endif
++
++ if (getenv ("verify") == NULL) {
++ setenv ("verify", "n");
++ }
++ if (getenv ("eeprom") == NULL) {
++ setenv ("eeprom", "y");
++ }
++}
++
++#ifdef CONFIG_PCI
++static struct pci_controller hose;
++
++extern void aspeed_init_pci (struct pci_controller *hose);
++
++void pci_init_board(void)
++{
++ aspeed_init_pci(&hose);
++}
++#endif
+diff --git a/board/aspeed/ast2400/config.mk b/board/aspeed/ast2400/config.mk
+new file mode 100755
+index 0000000..24ca09b
+--- /dev/null
++++ b/board/aspeed/ast2400/config.mk
+@@ -0,0 +1,18 @@
++# 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
++#
++
++# ROM version
++#TEXT_BASE = 0xBFC00000
++
++# RAM version
++TEXT_BASE = 0x40500000
++#TEXT_BASE = 0x00000000
++#TEXT_BASE = 0x00400000
+diff --git a/board/aspeed/ast2400/crc32.c b/board/aspeed/ast2400/crc32.c
+new file mode 100755
+index 0000000..cc8d2ac
+--- /dev/null
++++ b/board/aspeed/ast2400/crc32.c
+@@ -0,0 +1,127 @@
++/*
++ * 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 <common.h>
++#include <asm/processor.h>
++#include <asm/byteorder.h>
++#include <environment.h>
++
++#ifdef CONFIG_2SPIFLASH
++
++extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
++
++/* ========================================================================
++ * Table of CRC-32's of all single-byte values (made by make_aspeed_crc_table)
++ */
++unsigned long aspeed_crc_table[256] = {
++ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
++ 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
++ 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
++ 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
++ 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
++ 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
++ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
++ 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
++ 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
++ 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
++ 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
++ 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
++ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
++ 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
++ 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
++ 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
++ 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
++ 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
++ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
++ 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
++ 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
++ 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
++ 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
++ 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
++ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
++ 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
++ 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
++ 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
++ 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
++ 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
++ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
++ 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
++ 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
++ 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
++ 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
++ 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
++ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
++ 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
++ 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
++ 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
++ 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
++ 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
++ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
++ 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
++ 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
++ 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
++ 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
++ 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
++ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
++ 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
++ 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
++ 0x2d02ef8dL
++};
++
++/* ========================================================================= */
++#define ASPEED_DO1(buf) crc = aspeed_crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
++#define ASPEED_DO2(buf) ASPEED_DO1(buf); ASPEED_DO1(buf);
++#define ASPEED_DO4(buf) ASPEED_DO2(buf); ASPEED_DO2(buf);
++#define ASPEED_DO8(buf) ASPEED_DO4(buf); ASPEED_DO4(buf);
++
++/* ========================================================================= */
++unsigned long spi2_crc32(crc, buf, len)
++ unsigned long crc;
++ unsigned char *buf;
++ unsigned long len;
++{
++
++ size_t len1, len2;
++ char *s;
++
++ len1 = len2 = 0;
++ if ( (ulong)(buf) <= (flash_info[0].start[0] + flash_info[0].size) )
++ len1 = (flash_info[0].start[0] + flash_info[0].size) - (ulong)(buf);
++
++ len1 = (len < len1) ? len:len1;
++ len2 = (len < len1) ? 0: (len - len1);
++
++ crc = crc ^ 0xffffffffL;
++ while (len1 >= 8)
++ {
++ ASPEED_DO8(buf);
++ len1 -= 8;
++ }
++ if (len1) do {
++ ASPEED_DO1(buf);
++ } while (--len1);
++
++ //s = (char *) flash_info[1].start[0];
++ s= (char *) flash_make_addr (&flash_info[1], 0, 0);
++ while (len2 >= 8)
++ {
++ ASPEED_DO8(s);
++ len2 -= 8;
++ }
++ if (len2) do {
++ ASPEED_DO1(s);
++ } while (--len2);
++
++ return crc ^ 0xffffffffL;
++
++}
++
++#endif /* CONFIG_2SPIFLASH */
++
+diff --git a/board/aspeed/ast2400/crt.c b/board/aspeed/ast2400/crt.c
+new file mode 100755
+index 0000000..b67f669
+--- /dev/null
++++ b/board/aspeed/ast2400/crt.c
+@@ -0,0 +1,322 @@
++/*
++ * 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 <common.h>
++#include <command.h>
++
++#include "type.h"
++#include "vesa.h"
++#include "vdef.h"
++#include "vfun.h"
++#include "vreg.h"
++#include "crt.h"
++
++ULONG AST3000DCLKTableV [] = {
++ 0x00046515, /* 00: VCLK25_175 */
++ 0x00047255, /* 01: VCLK28_322 */
++ 0x0004682a, /* 02: VCLK31_5 */
++ 0x0004672a, /* 03: VCLK36 */
++ 0x00046c50, /* 04: VCLK40 */
++ 0x00046842, /* 05: VCLK49_5 */
++ 0x00006c32, /* 06: VCLK50 */
++ 0x00006a2f, /* 07: VCLK56_25 */
++ 0x00006c41, /* 08: VCLK65 */
++ 0x00006832, /* 09: VCLK75 */
++ 0x0000672e, /* 0A: VCLK78_75 */
++ 0x0000683f, /* 0B: VCLK94_5 */
++ 0x00004824, /* 0C: VCLK108 */
++ 0x00004723, /* 0D: VCLK119 */
++ 0x0000482d, /* 0E: VCLK135 */
++ 0x00004B37, /* 0F: VCLK146_25 */
++ 0x0000472e, /* 10: VCLK157_5 */
++ 0x00004836, /* 11: VCLK162 */
++
++};
++
++BOOL CheckDAC(int nCRTIndex)
++{
++ BYTE btValue;
++ BOOL bValue;
++
++ BYTE btDeviceSelect;
++
++ switch (nCRTIndex)
++ {
++ case CRT_1:
++ btDeviceSelect = DEVICE_ADDRESS_CH7301_CRT1;
++ break;
++ case CRT_2:
++ btDeviceSelect = DEVICE_ADDRESS_CH7301_CRT2;
++ break;
++ default:
++ printf("CRTIndex is not 1 or 2");
++ return FALSE;
++ break;
++ }
++
++ //Enable all DAC's and set register 21h[0] = '0'
++ //DVIP and DVIL disable for DAC
++ SetI2CRegClient(0, DEVICE_SELECT_CH7301, btDeviceSelect, CH7301_PM_REG, 0x00);
++
++ btValue = GetI2CRegClient(0, DEVICE_SELECT_CH7301, btDeviceSelect, CH7301_DC_REG);
++ btValue = btValue & 0xFE;
++ SetI2CRegClient(0, DEVICE_SELECT_CH7301, btDeviceSelect, CH7301_DC_REG, btValue);
++
++ //Set SENSE bit to 1
++ btValue = GetI2CRegClient(0, DEVICE_SELECT_CH7301, btDeviceSelect, CH7301_CD_REG);
++ btValue = btValue | 0x01;
++ SetI2CRegClient(0, DEVICE_SELECT_CH7301, btDeviceSelect, CH7301_CD_REG, btValue);
++
++ //Reset SENSE bit to 0
++ btValue = GetI2CRegClient(0, DEVICE_SELECT_CH7301, btDeviceSelect, CH7301_CD_REG);
++ btValue = btValue & 0xFE;
++ SetI2CRegClient(0, DEVICE_SELECT_CH7301, btDeviceSelect, CH7301_CD_REG, btValue);
++
++ bValue = (GetI2CRegClient(0, DEVICE_SELECT_CH7301, btDeviceSelect, CH7301_CD_REG) & CD_DACT) ? TRUE : FALSE;
++
++ return bValue;
++}
++
++VOID SetCH7301C(ULONG MMIOBase,
++ int nCRTIndex,
++ int inFreqRange,
++ int inOperating)
++{
++ BYTE btDeviceSelect;
++ BYTE btValue;
++
++//#ifdef EVB_CLIENT
++ //output RGB doesn't need to set CH7301
++ //if (1 == inOperating)
++ // return;
++//#endif
++
++ switch (nCRTIndex)
++ {
++ case CRT_1:
++ btDeviceSelect = 0xEA;
++
++ break;
++ case CRT_2:
++ btDeviceSelect = 0xEC;
++
++ break;
++ default:
++ printf("CRTIndex is not 1 or 2");
++ return;
++ break;
++ }
++
++ if (inFreqRange <= VCLK65)
++ {
++ printf("ch7301: low f \n");
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x33, 0x08);
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x34, 0x16);
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x36, 0x60);
++ }
++ else
++ {
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x33, 0x06);
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x34, 0x26);
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x36, 0xA0);
++ }
++
++ switch (inOperating)
++ {
++ case 0:
++ //DVI is normal function
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x49, 0xC0);
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x1D, 0x47);
++ break;
++ case 1:
++ //RGB
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x48, 0x18);
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x49, 0x0);
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x56, 0x0);
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x21, 0x9);
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x1D, 0x48);
++ SetI2CRegClient(MMIOBase, 0x3, btDeviceSelect, 0x1C, 0x00);
++ break;
++ default:
++ break;
++ };
++}
++
++void SetASTModeTiming (ULONG MMIOBase, int nCRTIndex, BYTE ModeIndex, BYTE ColorDepth)
++{
++ ULONG temp, RetraceStart, RetraceEnd, DisplayOffset, TerminalCount, bpp;
++
++// Access CRT Engine
++ // SetPolarity
++ WriteMemoryLongWithMASKClient(SCU_BASE, CRT1_CONTROL_REG + nCRTIndex*0x60, ((vModeTable[ModeIndex].HorPolarity << HOR_SYNC_SELECT_BIT) | (vModeTable[ModeIndex].VerPolarity << VER_SYNC_SELECT_BIT)), (HOR_SYNC_SELECT_MASK|VER_SYNC_SELECT_MASK));
++
++#if CONFIG_AST3000
++ WriteMemoryLongClient(SCU_BASE, CRT1_CONTROL2_REG + nCRTIndex*0x60, 0xc0);
++#else
++ //2100 is single edge
++ WriteMemoryLongClient(SCU_BASE, CRT1_CONTROL2_REG + nCRTIndex*0x60, 0x80);
++#endif
++ // Horizontal Timing
++ temp = 0;
++ temp = ((vModeTable[ModeIndex].HorizontalActive - 1) << HOR_ENABLE_END_BIT) | ((vModeTable[ModeIndex].HorizontalTotal - 1) << HOR_TOTAL_BIT);
++ WriteMemoryLongClient(SCU_BASE, CRT1_HOR_TOTAL_END_REG + nCRTIndex*0x60, temp);
++
++ RetraceStart = vModeTable[ModeIndex].HorizontalTotal - vModeTable[ModeIndex].HBackPorch - vModeTable[ModeIndex].HSyncTime - vModeTable[ModeIndex].HLeftBorder - 1;
++ RetraceEnd = (RetraceStart + vModeTable[ModeIndex].HSyncTime);
++ temp = 0;
++ temp = (RetraceEnd << HOR_RETRACE_END_BIT) | (RetraceStart << HOR_RETRACE_START_BIT);
++ WriteMemoryLongClient(SCU_BASE, CRT1_HOR_RETRACE_REG + nCRTIndex*0x60, temp);
++
++ // Vertical Timing
++ temp = 0;
++ temp = ((vModeTable[ModeIndex].VerticalActive - 1) << VER_ENABLE_END_BIT) | ((vModeTable[ModeIndex].VerticalTotal - 1) << VER_TOTAL_BIT);
++ WriteMemoryLongClient(SCU_BASE, CRT1_VER_TOTAL_END_REG + nCRTIndex*0x60, temp);
++
++ temp = 0;
++ RetraceStart = vModeTable[ModeIndex].VerticalTotal - vModeTable[ModeIndex].VBackPorch - vModeTable[ModeIndex].VSyncTime - vModeTable[ModeIndex].VTopBorder - 1;
++ RetraceEnd = (RetraceStart + vModeTable[ModeIndex].VSyncTime);
++ temp = (RetraceEnd << VER_RETRACE_END_BIT) | (RetraceStart << VER_RETRACE_START_BIT);
++ WriteMemoryLongClient(SCU_BASE, CRT1_VER_RETRACE_REG + nCRTIndex*0x60, temp);
++
++ // Set CRT Display Offset and Terminal Count
++ if (ColorDepth == RGB_565) {
++ bpp = 16;
++ }
++ else {
++ bpp = 32;
++ }
++
++ DisplayOffset = vModeTable[ModeIndex].HorizontalActive * bpp / 8;
++ TerminalCount = vModeTable[ModeIndex].HorizontalActive * bpp / 64;
++ if (ColorDepth == YUV_444) {
++ TerminalCount = TerminalCount * 3 / 4;
++ }
++ if (((vModeTable[ModeIndex].HorizontalActive * bpp) % 64) != 0) {
++ TerminalCount++;
++ }
++
++ WriteMemoryLongClient(SCU_BASE, CRT1_DISPLAY_OFFSET + nCRTIndex*0x60, ((TerminalCount << TERMINAL_COUNT_BIT) | DisplayOffset));
++
++ // Set Color Format
++ WriteMemoryLongWithMASKClient(SCU_BASE, CRT1_CONTROL_REG + nCRTIndex*0x60, (ColorDepth << FORMAT_SELECT_BIT), FORMAT_SELECT_MASK);
++
++ // Set Threshold
++ temp = 0;
++ temp = (CRT_HIGH_THRESHOLD_VALUE << THRES_HIGHT_BIT) | (CRT_LOW_THRESHOLD_VALUE << THRES_LOW_BIT);
++ WriteMemoryLongClient(SCU_BASE, CRT1_THRESHOLD_REG + nCRTIndex*0x60, temp);
++
++ WriteMemoryLongClient(SCU_BASE, CRT1_VIDEO_PLL_REG + nCRTIndex*0x60, AST3000DCLKTableV[vModeTable[ModeIndex].PixelClock]);
++}
++
++void SetASTCenter1024ModeTiming (ULONG MMIOBase, int nCRTIndex, BYTE ModeIndex, BYTE ColorDepth)
++{
++ ULONG temp, RetraceStart, RetraceEnd, DisplayOffset, TerminalCount, bpp;
++
++ // Access CRT Engine
++ // SetPolarity
++ WriteMemoryLongWithMASKClient(SCU_BASE, CRT1_CONTROL_REG + nCRTIndex*0x60, (HOR_NEGATIVE << HOR_SYNC_SELECT_BIT) | (VER_NEGATIVE << VER_SYNC_SELECT_BIT), HOR_SYNC_SELECT_MASK|VER_SYNC_SELECT_MASK);
++
++ WriteMemoryLongClient(SCU_BASE, CRT1_CONTROL2_REG + nCRTIndex*0x60, 0xC0);
++
++ // Horizontal Timing
++ temp = 0;
++ temp = ((vModeTable[ModeIndex].HorizontalActive - 1) << HOR_ENABLE_END_BIT) | ((vModeTable[10].HorizontalTotal - 1) << HOR_TOTAL_BIT);
++ WriteMemoryLongClient(SCU_BASE, CRT1_HOR_TOTAL_END_REG + nCRTIndex*0x60, temp);
++
++ RetraceStart = vModeTable[10].HorizontalTotal - vModeTable[10].HBackPorch - vModeTable[10].HSyncTime - vModeTable[10].HLeftBorder - 1;
++ RetraceStart = RetraceStart - (vModeTable[10].HorizontalActive - vModeTable[ModeIndex].HorizontalActive) / 2 - 1;
++ RetraceEnd = (RetraceStart + vModeTable[10].HSyncTime);
++ temp = 0;
++ temp = (RetraceEnd << HOR_RETRACE_END_BIT) | (RetraceStart << HOR_RETRACE_START_BIT);
++ WriteMemoryLongClient(SCU_BASE, CRT1_HOR_RETRACE_REG + nCRTIndex*0x60, temp);
++
++ // Vertical Timing
++ temp = 0;
++ temp = ((vModeTable[ModeIndex].VerticalActive - 1) << VER_ENABLE_END_BIT) | ((vModeTable[10].VerticalTotal - 1) << VER_TOTAL_BIT);
++ WriteMemoryLongClient(SCU_BASE, CRT1_VER_TOTAL_END_REG + nCRTIndex*0x60, temp);
++
++ RetraceStart = vModeTable[10].VerticalTotal - vModeTable[10].VBackPorch - vModeTable[10].VSyncTime - vModeTable[10].VTopBorder - 1;
++ RetraceStart = RetraceStart - (vModeTable[10].VerticalActive - vModeTable[ModeIndex].VerticalActive) / 2 - 1;
++ RetraceEnd = (RetraceStart + vModeTable[10].VSyncTime);
++ temp = (RetraceEnd << VER_RETRACE_END_BIT) | (RetraceStart << VER_RETRACE_START_BIT);
++ WriteMemoryLongClient(SCU_BASE, CRT1_VER_RETRACE_REG + nCRTIndex*0x60, temp);
++
++ // Set CRT Display Offset and Terminal Count
++ if (ColorDepth == RGB_565) {
++ bpp = 16;
++ }
++ else {
++ bpp = 32;
++ }
++ DisplayOffset = vModeTable[ModeIndex].HorizontalActive * bpp / 8;
++ TerminalCount = vModeTable[ModeIndex].HorizontalActive * bpp / 64;
++ if (ColorDepth == YUV_444) {
++ TerminalCount = TerminalCount * 3 / 4;
++ }
++ if (((vModeTable[ModeIndex].HorizontalActive * bpp) % 64) != 0) {
++ TerminalCount++;
++ }
++
++ WriteMemoryLongClient(SCU_BASE, CRT1_DISPLAY_OFFSET + nCRTIndex*0x60, (TerminalCount << TERMINAL_COUNT_BIT) | DisplayOffset);
++
++ // Set Color Format
++ WriteMemoryLongWithMASKClient(SCU_BASE, CRT1_CONTROL_REG + nCRTIndex*0x60, (ColorDepth << FORMAT_SELECT_BIT), FORMAT_SELECT_MASK);
++
++ // Set Threshold
++ temp = 0;
++ temp = (CRT_HIGH_THRESHOLD_VALUE << THRES_HIGHT_BIT) | (CRT_LOW_THRESHOLD_VALUE << THRES_LOW_BIT);
++ WriteMemoryLongClient(SCU_BASE, CRT1_THRESHOLD_REG + nCRTIndex*0x60, temp);
++
++ // Set DCLK
++ WriteMemoryLongClient(SCU_BASE, CRT1_VIDEO_PLL_REG + nCRTIndex*0x60, AST3000DCLKTableV[vModeTable[ModeIndex].PixelClock]);
++
++}
++
++BOOL ASTSetModeV (ULONG MMIOBase, int nCRTIndex, ULONG VGABaseAddr, USHORT Horizontal, USHORT Vertical, BYTE ColorFormat, BYTE CenterMode)
++{
++ BYTE i, ModeIndex;
++ BOOL bDAC;
++ ULONG ulTemp;
++
++ // Access CRT Engine
++ //Enable CRT1 graph
++ WriteMemoryLongWithMASKClient(SCU_BASE, CRT1_CONTROL_REG + 0x60*nCRTIndex, GRAPH_DISPLAY_ON, GRAPH_DISPLAY_MASK);
++
++ // Set CRT Display Start Address
++ WriteMemoryLongWithMASKClient(SCU_BASE, CRT1_DISPLAY_ADDRESS + 0x60*nCRTIndex, VGABaseAddr, DISPLAY_ADDRESS_MASK);
++
++ for (i = 0; i < Mode60HZCount; i++) {
++ if ((vModeTable[i].HorizontalActive == Horizontal) && (vModeTable[i].VerticalActive == Vertical)) {
++
++ ModeIndex = i;
++
++ if (CenterMode != 1) {
++ SetASTModeTiming(MMIOBase, nCRTIndex, i, ColorFormat);
++ }
++ else {
++ SetASTCenter1024ModeTiming (MMIOBase, nCRTIndex, i, ColorFormat);
++ }
++
++ //use internal video out sigal and don't need use 7301
++ /*
++ bDAC = CheckDAC(nCRTIndex);
++
++ SetCH7301C(0,
++ nCRTIndex,
++ vModeTable[ModeIndex].PixelClock,
++ bDAC); //For RGB
++ */
++ return TRUE;
++ }
++ }
++
++ return FALSE;
++}
++
+diff --git a/board/aspeed/ast2400/crt.h b/board/aspeed/ast2400/crt.h
+new file mode 100755
+index 0000000..e7483be
+--- /dev/null
++++ b/board/aspeed/ast2400/crt.h
+@@ -0,0 +1,121 @@
++/*
++ * 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 _CRT_H_
++#define _CRT_H_
++
++#ifdef Watcom
++#define CRT_REMAP_OFFSET 0x10000
++#else
++#define CRT_REMAP_OFFSET 0x0
++#endif
++
++/********************************************************/
++/* CRT register */
++/********************************************************/
++#define CRT_BASE_OFFSET 0x6000+CRT_REMAP_OFFSET
++
++#define CRT1_CONTROL_REG 0x00 + CRT_BASE_OFFSET
++ #define GRAPH_DISPLAY_BIT 0
++ #define GRAPH_DISPLAY_MASK (1<<0)
++ #define GRAPH_DISPLAY_ON 1
++ #define GRAPH_DISPLAY_OFF 0
++ #define FORMAT_SELECT_BIT 8
++ #define FORMAT_SELECT_MASK (3<<8)
++ #define HOR_SYNC_SELECT_BIT 16
++ #define HOR_SYNC_SELECT_MASK (1<<16)
++ #define HOR_NEGATIVE 1
++ #define HOR_POSITIVE 0
++ #define VER_SYNC_SELECT_BIT 17
++ #define VER_SYNC_SELECT_MASK (1<<17)
++ #define VER_NEGATIVE 1
++ #define VER_POSITIVE 0
++
++#define CRT1_CONTROL2_REG 0x04 + CRT_BASE_OFFSET
++
++#define CRT1_VIDEO_PLL_REG 0x0C + CRT_BASE_OFFSET
++ #define POST_DIV_BIT 18
++ #define POST_DIV_MASK 3<<18
++ #define DIV_1_1 0
++ //#define DIV_1_2 1
++ #define DIV_1_2 2
++ #define DIV_1_4 3
++
++#define CRT1_HOR_TOTAL_END_REG 0x10 + CRT_BASE_OFFSET
++ #define HOR_TOTAL_BIT 0
++ #define HOR_ENABLE_END_BIT 16
++
++#define CRT1_HOR_RETRACE_REG 0x14 + CRT_BASE_OFFSET
++ #define HOR_RETRACE_START_BIT 0
++ #define HOR_RETRACE_END_BIT 16
++
++#define CRT1_VER_TOTAL_END_REG 0x18 + CRT_BASE_OFFSET
++ #define VER_TOTAL_BIT 0
++ #define VER_ENABLE_END_BIT 16
++
++#define CRT1_VER_RETRACE_REG 0x1C + CRT_BASE_OFFSET
++ #define VER_RETRACE_START_BIT 0
++ #define VER_RETRACE_END_BIT 16
++
++#define CRT1_DISPLAY_ADDRESS 0x20 + CRT_BASE_OFFSET
++ #define DISPLAY_ADDRESS_MASK 0x0FFFFFFF
++
++#define CRT1_DISPLAY_OFFSET 0x24 + CRT_BASE_OFFSET
++ #define DISPLAY_OFFSET_ALIGN 7 /* 8 byte alignment*/
++ #define TERMINAL_COUNT_BIT 16
++
++#define CRT1_THRESHOLD_REG 0x28 + CRT_BASE_OFFSET
++ #define THRES_LOW_BIT 0
++ #define THRES_HIGHT_BIT 8
++
++#define CURSOR_POSITION 0x30 + OFFSET
++#define CURSOR_OFFSET 0x34 + OFFSET
++#define CURSOR_PATTERN 0x38 + OFFSET
++#define OSD_HORIZONTAL 0x40 + OFFSET
++#define OSD_VERTICAL 0x44 + OFFSET
++#define OSD_PATTERN 0x48 + OFFSET
++#define OSD_OFFSET 0x4C + OFFSET
++#define OSD_THRESHOLD 0x50 + OFFSET
++
++//Ch7301c
++#define DEVICE_ADDRESS_CH7301_CRT1 0xEA
++#define DEVICE_ADDRESS_CH7301_CRT2 0xEC
++
++
++#define DEVICE_SELECT_CH7301 0x3
++
++/* CH7301 Register Definition */
++#define CH7301_CD_REG 0x20
++ #define CD_DACT 0x0E
++ #define CD_DVIT 1 << 5
++#define CH7301_DC_REG 0x21
++#define CH7301_PM_REG 0x49
++
++BOOL CheckHotPlug(int nCRTIndex);
++BOOL CheckDAC(int nCRTIndex);
++
++BOOL ASTSetModeV (ULONG MMIOBase,
++ int nCRTIndex,
++ ULONG VGABaseAddr,
++ USHORT Horizontal,
++ USHORT Vertical,
++ BYTE ColorFormat,
++ BYTE CenterMode);
++
++BOOL SelCRTClock(ULONG MMIOBase,
++ int nCRTIndex,
++ USHORT Horizontal,
++ USHORT Vertical);
++
++void DisableCRT(ULONG MMIOBase, int nCRTIndex);
++void ClearCRTWithBlack(ULONG ulCRTAddr, int iWidth, int iHeight);
++
++#endif /* _CRT_H_ */
++
+diff --git a/board/aspeed/ast2400/flash.c b/board/aspeed/ast2400/flash.c
+new file mode 100755
+index 0000000..d611d0d
+--- /dev/null
++++ b/board/aspeed/ast2400/flash.c
+@@ -0,0 +1,1651 @@
++/*
++ * 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
++ *
++ * History
++ * 01/20/2004 - combined variants of original driver.
++ * 01/22/2004 - Write performance enhancements for parallel chips (Tolunay)
++ * 01/23/2004 - Support for x8/x16 chips (Rune Raknerud)
++ * 01/27/2004 - Little endian support Ed Okerson
++ *
++ * Tested Architectures
++ * Port Width Chip Width # of banks Flash Chip Board
++ * 32 16 1 28F128J3 seranoa/eagle
++ * 64 16 1 28F128J3 seranoa/falcon
++ */
++// (Sun) This CFI driver is written for fixed-width flash chips.
++// It was not designed for flexible 8-bit/16-bit chips, which are the norm.
++// When those chips are connected to a bus in 8-bit mode, the address wires
++// right-shifted by 1.
++//FIXME: Fix the driver to auto-detect "16-bit flash wired in 8-bit mode".
++// Left-shift CFI offsets by 1 bit instead of doubling the #define values.
++
++/* The DEBUG define must be before common to enable debugging */
++// (Sun) Changed to DEBUG_FLASH because flash debug()s are too numerous.
++// #define DEBUG
++
++#include <common.h>
++#include <asm/processor.h>
++#include <asm/byteorder.h>
++#include <environment.h>
++#ifdef CONFIG_SYS_FLASH_CFI
++
++/*
++ * This file implements a Common Flash Interface (CFI) driver for U-Boot.
++ * The width of the port and the width of the chips are determined at initialization.
++ * These widths are used to calculate the address for access CFI data structures.
++ * It has been tested on an Intel Strataflash implementation and AMD 29F016D.
++ *
++ * References
++ * JEDEC Standard JESD68 - Common Flash Interface (CFI)
++ * JEDEC Standard JEP137-A Common Flash Interface (CFI) ID Codes
++ * Intel Application Note 646 Common Flash Interface (CFI) and Command Sets
++ * Intel 290667-008 3 Volt Intel StrataFlash Memory datasheet
++ *
++ * TODO
++ *
++ * Use Primary Extended Query table (PRI) and Alternate Algorithm Query
++ * Table (ALT) to determine if protection is available
++ *
++ * Add support for other command sets Use the PRI and ALT to determine command set
++ * Verify erase and program timeouts.
++ */
++
++#ifndef CONFIG_FLASH_BANKS_LIST
++#define CONFIG_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE }
++#endif
++
++#define FLASH_CMD_CFI 0x98
++#define FLASH_CMD_READ_ID 0x90
++#define FLASH_CMD_RESET 0xff
++#define FLASH_CMD_BLOCK_ERASE 0x20
++#define FLASH_CMD_ERASE_CONFIRM 0xD0
++#define FLASH_CMD_WRITE 0x40
++#define FLASH_CMD_PROTECT 0x60
++#define FLASH_CMD_PROTECT_SET 0x01
++#define FLASH_CMD_PROTECT_CLEAR 0xD0
++#define FLASH_CMD_CLEAR_STATUS 0x50
++#define FLASH_CMD_WRITE_TO_BUFFER 0xE8
++#define FLASH_CMD_WRITE_BUFFER_CONFIRM 0xD0
++
++#define FLASH_STATUS_DONE 0x80
++#define FLASH_STATUS_ESS 0x40
++#define FLASH_STATUS_ECLBS 0x20
++#define FLASH_STATUS_PSLBS 0x10
++#define FLASH_STATUS_VPENS 0x08
++#define FLASH_STATUS_PSS 0x04
++#define FLASH_STATUS_DPS 0x02
++#define FLASH_STATUS_R 0x01
++#define FLASH_STATUS_PROTECT 0x01
++
++#define AMD_CMD_RESET 0xF0
++#define AMD_CMD_WRITE 0xA0
++#define AMD_CMD_ERASE_START 0x80
++#define AMD_CMD_ERASE_SECTOR 0x30
++#define AMD_CMD_UNLOCK_START 0xAA
++#define AMD_CMD_UNLOCK_ACK 0x55
++#define AMD_CMD_WRITE_TO_BUFFER 0x25
++#define AMD_CMD_BUFFER_TO_FLASH 0x29
++
++#define AMD_STATUS_TOGGLE 0x40
++#define AMD_STATUS_ERROR 0x20
++//FIXME: These 3 were also changed for 8-bit/16-bit flash chips.
++#define AMD_ADDR_ERASE_START (0xAAA/info->portwidth)
++#define AMD_ADDR_START (0xAAA/info->portwidth)
++#define AMD_ADDR_ACK (0x555/info->portwidth)
++
++//FIXME: Fix the driver to auto-detect "16-bit flash wired in 8-bit mode".
++// Left-shift CFI offsets by 1 bit instead of doubling the #define values.
++#define FLASH_OFFSET_CFI (0xAA/info->portwidth)
++#define FLASH_OFFSET_CFI_RESP (0x20/info->portwidth)
++#define FLASH_OFFSET_CFI_RESP1 (0x22/info->portwidth)
++#define FLASH_OFFSET_CFI_RESP2 (0x24/info->portwidth)
++#define FLASH_OFFSET_PRIMARY_VENDOR (0x26/info->portwidth)
++#define FLASH_OFFSET_WTOUT (0x3E/info->portwidth)
++#define FLASH_OFFSET_WBTOUT (0x40/info->portwidth)
++#define FLASH_OFFSET_ETOUT (0x42/info->portwidth)
++#define FLASH_OFFSET_CETOUT (0x44/info->portwidth)
++#define FLASH_OFFSET_WMAX_TOUT (0x46/info->portwidth)
++#define FLASH_OFFSET_WBMAX_TOUT (0x48/info->portwidth)
++#define FLASH_OFFSET_EMAX_TOUT (0x4A/info->portwidth)
++#define FLASH_OFFSET_CEMAX_TOUT (0x4C/info->portwidth)
++#define FLASH_OFFSET_SIZE (0x4E/info->portwidth)
++#define FLASH_OFFSET_INTERFACE (0x50/info->portwidth)
++#define FLASH_OFFSET_BUFFER_SIZE (0x54/info->portwidth)
++#define FLASH_OFFSET_NUM_ERASE_REGIONS (0x58/info->portwidth)
++#define FLASH_OFFSET_ERASE_REGIONS (0x5A/info->portwidth)
++#define FLASH_OFFSET_PROTECT (0x02/info->portwidth)
++#define FLASH_OFFSET_USER_PROTECTION (0x85/info->portwidth)
++#define FLASH_OFFSET_INTEL_PROTECTION (0x81/info->portwidth)
++
++#define MAX_NUM_ERASE_REGIONS 4
++
++#define FLASH_MAN_CFI 0x01000000
++
++#define CFI_CMDSET_NONE 0
++#define CFI_CMDSET_INTEL_EXTENDED 1
++#define CFI_CMDSET_AMD_STANDARD 2
++#define CFI_CMDSET_INTEL_STANDARD 3
++#define CFI_CMDSET_AMD_EXTENDED 4
++#define CFI_CMDSET_MITSU_STANDARD 256
++#define CFI_CMDSET_MITSU_EXTENDED 257
++#define CFI_CMDSET_SST 258
++
++
++#ifdef CONFIG_SYS_FLASH_CFI_AMD_RESET /* needed for STM_ID_29W320DB on UC100 */
++# undef FLASH_CMD_RESET
++# define FLASH_CMD_RESET AMD_CMD_RESET /* use AMD-Reset instead */
++#endif
++
++
++typedef union {
++ unsigned char c;
++ unsigned short w;
++ unsigned long l;
++ unsigned long long ll;
++} cfiword_t;
++
++typedef union {
++ volatile unsigned char *cp;
++ volatile unsigned short *wp;
++ volatile unsigned long *lp;
++ volatile unsigned long long *llp;
++} cfiptr_t;
++
++/* use CFG_MAX_FLASH_BANKS_DETECT if defined */
++#ifdef CONFIG_SYS_MAX_FLASH_BANKS_DETECT
++static ulong bank_base[CONFIG_SYS_MAX_FLASH_BANKS_DETECT] = CONFIG_FLASH_BANKS_LIST;
++flash_info_t flash_info[CFG_MAX_FLASH_BANKS_DETECT]; /* FLASH chips info */
++#else
++static ulong bank_base[CONFIG_SYS_MAX_FLASH_BANKS] = CONFIG_FLASH_BANKS_LIST;
++flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* FLASH chips info */
++#endif
++
++
++/*-----------------------------------------------------------------------
++ * Functions
++ */
++static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c);
++static void flash_make_cmd (flash_info_t * info, uchar cmd, void *cmdbuf);
++static void flash_write_cmd (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
++static void flash_write_cmd_nodbg (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
++static void flash_write_cmd_int (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd, int noDebug);
++static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect);
++static int flash_isequal (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
++static int flash_isset (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
++static int flash_toggle (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
++static int flash_detect_cfi (flash_info_t * info);
++ulong flash_get_size (ulong base, int banknum);
++static int flash_write_cfiword (flash_info_t * info, ulong dest, cfiword_t cword);
++static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
++ ulong tout, char *prompt);
++static void write_buffer_abort_reset(flash_info_t * info, flash_sect_t sector);
++#if defined(CFG_ENV_IS_IN_FLASH) || defined(CFG_ENV_ADDR_REDUND) || (CFG_MONITOR_BASE >= CFG_FLASH_BASE)
++static flash_info_t *flash_get_info(ulong base);
++#endif
++#ifdef CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp, int len);
++static int flash_write_cfibuffer_amd (flash_info_t * info, ulong dest, uchar * cp, int len);
++#endif
++
++/*-----------------------------------------------------------------------
++ * create an address based on the offset and the port width
++ */
++inline uchar *flash_make_addr (flash_info_t * info, flash_sect_t sect, uint offset)
++{
++ return ((uchar *) (info->start[sect] + (offset * info->portwidth)));
++}
++
++/*-----------------------------------------------------------------------
++ * Debug support
++ */
++#ifdef DEBUG_FLASH
++static void print_longlong (char *str, unsigned long long data)
++{
++ int i;
++ char *cp;
++
++ cp = (unsigned char *) &data;
++ for (i = 0; i < 8; i++)
++ sprintf (&str[i * 2], "%2.2x", *cp++);
++}
++#endif
++
++#if defined(DEBUG_FLASH)
++static void flash_printqry (flash_info_t * info, flash_sect_t sect)
++{
++ cfiptr_t cptr;
++ int x, y;
++
++ for (x = 0; x < 0x40; x += 16U / info->portwidth) {
++ cptr.cp =
++ flash_make_addr (info, sect,
++ x + FLASH_OFFSET_CFI_RESP);
++ debug ("%p : ", cptr.cp);
++ for (y = 0; y < 16; y++) {
++ debug ("%2.2x ", cptr.cp[y]);
++ }
++ debug (" ");
++ for (y = 0; y < 16; y++) {
++ if (cptr.cp[y] >= 0x20 && cptr.cp[y] <= 0x7e) {
++ debug ("%c", cptr.cp[y]);
++ } else {
++ debug (".");
++ }
++ }
++ debug ("\n");
++ }
++}
++#endif
++
++/*-----------------------------------------------------------------------
++ * read a character at a port width address
++ */
++inline uchar flash_read_uchar (flash_info_t * info, uint offset)
++{
++ uchar *cp;
++
++ cp = flash_make_addr (info, 0, offset);
++#if defined(__LITTLE_ENDIAN)
++ return (cp[0]);
++#else
++ return (cp[info->portwidth - 1]);
++#endif
++}
++
++/*-----------------------------------------------------------------------
++ * read a short word by swapping for ppc format.
++ */
++#if 0
++static ushort flash_read_ushort (flash_info_t * info, flash_sect_t sect, uint offset)
++{
++ uchar *addr;
++ ushort retval;
++
++#ifdef DEBUG_FLASH
++ int x;
++#endif
++ addr = flash_make_addr (info, sect, offset);
++
++#ifdef DEBUG_FLASH
++ debug ("ushort addr is at %p info->portwidth = %d\n", addr,
++ info->portwidth);
++ for (x = 0; x < 2 * info->portwidth; x++) {
++ debug ("addr[%x] = 0x%x\n", x, addr[x]);
++ }
++#endif
++#if defined(__LITTLE_ENDIAN)
++ if (info->interface == FLASH_CFI_X8X16) {
++ retval = (addr[0] | (addr[2] << 8));
++ } else {
++ retval = (addr[0] | (addr[(info->portwidth)] << 8));
++ }
++#else
++ retval = ((addr[(2 * info->portwidth) - 1] << 8) |
++ addr[info->portwidth - 1]);
++#endif
++
++ debug ("retval = 0x%x\n", retval);
++ return retval;
++}
++#endif
++
++/*-----------------------------------------------------------------------
++ * read a long word by picking the least significant byte of each maximum
++ * port size word. Swap for ppc format.
++ */
++static ulong flash_read_long (flash_info_t * info, flash_sect_t sect, uint offset)
++{
++ uchar *addr;
++ ulong retval;
++#ifdef DEBUG_FLASH
++ int x;
++#endif
++#if 0
++ switch (info->interface) {
++ case FLASH_CFI_X8:
++ case FLASH_CFI_X16:
++ break;
++ case FLASH_CFI_X8X16:
++ offset <<= 1;
++ }
++#endif
++ // flash_make_addr() multiplies offset by info->portwidth.
++ addr = flash_make_addr (info, sect, offset);
++
++#ifdef DEBUG_FLASH
++ debug ("long addr is at %p info->portwidth = %d\n", addr,
++ info->portwidth);
++ for (x = 0; x < 4 * info->portwidth; x++) {
++ debug ("addr[%x] = 0x%x\n", x, addr[x]);
++ }
++#endif
++#if defined(__LITTLE_ENDIAN)
++ if (info->interface == FLASH_CFI_X8X16) {
++ retval = (addr[0] | (addr[2] << 8) | (addr[4] << 16) | (addr[6] << 24));
++ } else {
++ retval = (addr[0] | (addr[(info->portwidth)] << 8) |
++ (addr[(2 * info->portwidth)] << 16) |
++ (addr[(3 * info->portwidth)] << 24));
++ }
++#else
++ //FIXME: This undocumented code appears to match broken bus wiring.
++ retval = (addr[(2 * info->portwidth) - 1] << 24) |
++ (addr[(info->portwidth) - 1] << 16) |
++ (addr[(4 * info->portwidth) - 1] << 8) |
++ addr[(3 * info->portwidth) - 1];
++#endif
++ return retval;
++}
++
++/*-----------------------------------------------------------------------
++ */
++unsigned long flash_init (void)
++{
++ unsigned long size = 0;
++ int i;
++
++ /* Init: no FLASHes known */
++ for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
++ flash_info[i].flash_id = FLASH_UNKNOWN;
++ size += flash_info[i].size = flash_get_size (bank_base[i], i);
++ if (flash_info[i].flash_id == FLASH_UNKNOWN) {
++#ifndef CFG_FLASH_QUIET_TEST
++ printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
++ i, flash_info[i].size, flash_info[i].size << 20);
++#endif /* CFG_FLASH_QUIET_TEST */
++ }
++ }
++
++ /* Monitor protection ON by default */
++#if (CONFIG_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
++ flash_protect (FLAG_PROTECT_SET,
++ CONFIG_MONITOR_BASE,
++ CONFIG_MONITOR_BASE + monitor_flash_len - 1,
++ flash_get_info(CONFIG_MONITOR_BASE));
++#endif
++
++ /* Environment protection ON by default */
++#ifdef CONFIG_ENV_IS_IN_FLASH
++ flash_protect (FLAG_PROTECT_SET,
++ CONFIG_ENV_ADDR,
++ CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
++ flash_get_info(CONFIG_ENV_ADDR));
++#endif
++
++ /* Redundant environment protection ON by default */
++#ifdef CONFIG_ENV_ADDR_REDUND
++ flash_protect (FLAG_PROTECT_SET,
++ CONFIG_ENV_ADDR_REDUND,
++ CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SIZE_REDUND - 1,
++ flash_get_info(CONFIG_ENV_ADDR_REDUND));
++#endif
++ return (size);
++}
++
++/*-----------------------------------------------------------------------
++ */
++#if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || (CONFIG_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
++static flash_info_t *flash_get_info(ulong base)
++{
++ int i;
++ flash_info_t * info = 0;
++
++ for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i ++) {
++ info = & flash_info[i];
++ if (info->size && info->start[0] <= base &&
++ base <= info->start[0] + info->size - 1)
++ break;
++ }
++
++ return i == CONFIG_SYS_MAX_FLASH_BANKS ? 0 : info;
++}
++#endif
++
++/*-----------------------------------------------------------------------
++ */
++int flash_erase (flash_info_t * info, int s_first, int s_last)
++{
++ int rcode = 0;
++ int prot;
++ flash_sect_t sect;
++ uchar ch;
++ uchar *addr;
++
++ if (info->flash_id != FLASH_MAN_CFI) {
++ puts ("Can't erase unknown flash type - aborted\n");
++ return 1;
++ }
++ if ((s_first < 0) || (s_first > s_last)) {
++ puts ("- no sectors to erase\n");
++ return 1;
++ }
++
++ prot = 0;
++ for (sect = s_first; sect <= s_last; ++sect) {
++ if (info->protect[sect]) {
++ prot++;
++ }
++ }
++ if (prot) {
++ printf ("- Warning: %d protected sectors will not be erased!\n", prot);
++ } else {
++ putc ('\n');
++ }
++
++
++ for (sect = s_first; sect <= s_last; sect++) {
++ if (info->protect[sect] == 0) { /* not protected */
++ switch (info->vendor) {
++ case CFI_CMDSET_INTEL_STANDARD:
++ case CFI_CMDSET_INTEL_EXTENDED:
++ flash_write_cmd (info, sect, 0, FLASH_CMD_CLEAR_STATUS);
++ flash_write_cmd (info, sect, 0, FLASH_CMD_BLOCK_ERASE);
++ flash_write_cmd (info, sect, 0, FLASH_CMD_ERASE_CONFIRM);
++ break;
++ case CFI_CMDSET_AMD_STANDARD:
++ case CFI_CMDSET_AMD_EXTENDED:
++ flash_unlock_seq (info, sect);
++ flash_write_cmd (info, sect, AMD_ADDR_ERASE_START,
++ AMD_CMD_ERASE_START);
++ flash_unlock_seq (info, sect);
++ flash_write_cmd (info, sect, 0, AMD_CMD_ERASE_SECTOR);
++
++ /* toggle */
++ addr = flash_make_addr (info, sect, 0);
++ do {
++ ch = *(volatile uchar *)(addr);
++ } while ( ((ch & 0x80) == 0) || (ch != 0xFF) );
++ break;
++ default:
++ debug ("Unkown flash vendor %d\n",
++ info->vendor);
++ break;
++ }
++
++ if (flash_full_status_check
++ (info, sect, info->erase_blk_tout, "erase")) {
++ rcode = 1;
++ } else
++ putc ('.');
++ }
++ }
++ puts (" done\n");
++ return rcode;
++}
++
++/*-----------------------------------------------------------------------
++ */
++void flash_print_info (flash_info_t * info)
++{
++ int i;
++
++ if (info->flash_id != FLASH_MAN_CFI) {
++ puts ("missing or unknown FLASH type\n");
++ return;
++ }
++
++ printf ("CFI conformant FLASH (%d x %d)",
++ (info->portwidth << 3), (info->chipwidth << 3));
++ printf (" Size: %ld MB in %d Sectors\n",
++ info->size >> 20, info->sector_count);
++ printf (" Erase timeout %ld ms, write timeout %ld ms, buffer write timeout %ld ms, buffer size %d\n",
++ info->erase_blk_tout,
++ info->write_tout,
++ info->buffer_write_tout,
++ info->buffer_size);
++
++ puts (" Sector Start Addresses:");
++ for (i = 0; i < info->sector_count; ++i) {
++#ifdef CFG_FLASH_EMPTY_INFO
++ int k;
++ int size;
++ int erased;
++ volatile unsigned long *flash;
++
++ /*
++ * Check if whole sector is erased
++ */
++ if (i != (info->sector_count - 1))
++ size = info->start[i + 1] - info->start[i];
++ else
++ size = info->start[0] + info->size - info->start[i];
++ erased = 1;
++ flash = (volatile unsigned long *) info->start[i];
++ size = size >> 2; /* divide by 4 for longword access */
++ for (k = 0; k < size; k++) {
++ if (*flash++ != 0xffffffff) {
++ erased = 0;
++ break;
++ }
++ }
++
++ if ((i % 5) == 0)
++ printf ("\n");
++ /* print empty and read-only info */
++ printf (" %08lX%s%s",
++ info->start[i],
++ erased ? " E" : " ",
++ info->protect[i] ? "RO " : " ");
++#else /* ! CFG_FLASH_EMPTY_INFO */
++ if ((i % 5) == 0)
++ printf ("\n ");
++ printf (" %08lX%s",
++ info->start[i], info->protect[i] ? " (RO)" : " ");
++#endif
++ }
++ putc ('\n');
++ return;
++}
++
++/*-----------------------------------------------------------------------
++ * Copy memory to flash, returns:
++ * 0 - OK
++ * 1 - write timeout
++ * 2 - Flash not erased
++ */
++int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
++{
++ ulong wp;
++ ulong cp;
++ int aln;
++ cfiword_t cword;
++ int i, rc;
++
++#ifdef CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++ unsigned char pat[] = {'|', '-', '/', '\\'};
++ int patcnt = 0;
++ int buffered_size;
++#endif
++ /* get lower aligned address */
++ /* get lower aligned address */
++ wp = (addr & ~(info->portwidth - 1));
++
++ /* handle unaligned start */
++ if ((aln = addr - wp) != 0) {
++ cword.l = 0;
++ cp = wp;
++ for (i = 0; i < aln; ++i, ++cp)
++ flash_add_byte (info, &cword, (*(uchar *) cp));
++
++ for (; (i < info->portwidth) && (cnt > 0); i++) {
++ flash_add_byte (info, &cword, *src++);
++ cnt--;
++ cp++;
++ }
++ for (; (cnt == 0) && (i < info->portwidth); ++i, ++cp)
++ flash_add_byte (info, &cword, (*(uchar *) cp));
++ if ((rc = flash_write_cfiword (info, wp, cword)) != 0)
++ return rc;
++ wp = cp;
++ }
++
++ /* handle the aligned part */
++#ifdef CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++ buffered_size = (info->portwidth / info->chipwidth);
++ buffered_size *= info->buffer_size;
++ while (cnt >= info->portwidth) {
++ /* Show processing */
++ if ((++patcnt % 256) == 0)
++ printf("%c\b", pat[(patcnt / 256) & 0x03]);
++
++ i = buffered_size > cnt ? cnt : buffered_size;
++ if ((rc = flash_write_cfibuffer (info, wp, src, i)) != ERR_OK)
++ return rc;
++ i -= i & (info->portwidth - 1);
++ wp += i;
++ src += i;
++ cnt -= i;
++ }
++#else
++ while (cnt >= info->portwidth) {
++ cword.l = 0;
++ for (i = 0; i < info->portwidth; i++) {
++ flash_add_byte (info, &cword, *src++);
++ }
++ if ((rc = flash_write_cfiword (info, wp, cword)) != 0)
++ return rc;
++ wp += info->portwidth;
++ cnt -= info->portwidth;
++ }
++#endif /* CONFIG_SYS_FLASH_USE_BUFFER_WRITE */
++ if (cnt == 0) {
++ return (0);
++ }
++
++ /*
++ * handle unaligned tail bytes
++ */
++ cword.l = 0;
++ for (i = 0, cp = wp; (i < info->portwidth) && (cnt > 0); ++i, ++cp) {
++ flash_add_byte (info, &cword, *src++);
++ --cnt;
++ }
++ for (; i < info->portwidth; ++i, ++cp) {
++ flash_add_byte (info, &cword, (*(uchar *) cp));
++ }
++
++ return flash_write_cfiword (info, wp, cword);
++}
++
++/*-----------------------------------------------------------------------
++ */
++#ifdef CFG_FLASH_PROTECTION
++
++int flash_real_protect (flash_info_t * info, long sector, int prot)
++{
++ int retcode = 0;
++
++ flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
++ flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT);
++ if (prot)
++ flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT_SET);
++ else
++ flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT_CLEAR);
++
++ if ((retcode =
++ flash_full_status_check (info, sector, info->erase_blk_tout,
++ prot ? "protect" : "unprotect")) == 0) {
++
++ info->protect[sector] = prot;
++ /* Intel's unprotect unprotects all locking */
++ if (prot == 0) {
++ flash_sect_t i;
++
++ for (i = 0; i < info->sector_count; i++) {
++ if (info->protect[i])
++ flash_real_protect (info, i, 1);
++ }
++ }
++ }
++ return retcode;
++}
++
++/*-----------------------------------------------------------------------
++ * flash_read_user_serial - read the OneTimeProgramming cells
++ */
++void flash_read_user_serial (flash_info_t * info, void *buffer, int offset,
++ int len)
++{
++ uchar *src;
++ uchar *dst;
++
++ dst = buffer;
++ src = flash_make_addr (info, 0, FLASH_OFFSET_USER_PROTECTION);
++ flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);
++ memcpy (dst, src + offset, len);
++ flash_write_cmd (info, 0, 0, info->cmd_reset);
++}
++
++/*
++ * flash_read_factory_serial - read the device Id from the protection area
++ */
++void flash_read_factory_serial (flash_info_t * info, void *buffer, int offset,
++ int len)
++{
++ uchar *src;
++
++ src = flash_make_addr (info, 0, FLASH_OFFSET_INTEL_PROTECTION);
++ flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);
++ memcpy (buffer, src + offset, len);
++ flash_write_cmd (info, 0, 0, info->cmd_reset);
++}
++
++#endif /* CFG_FLASH_PROTECTION */
++
++/*
++ * flash_is_busy - check to see if the flash is busy
++ * This routine checks the status of the chip and returns true if the chip is busy
++ */
++static int flash_is_busy (flash_info_t * info, flash_sect_t sect)
++{
++ int retval;
++
++ switch (info->vendor) {
++ case CFI_CMDSET_INTEL_STANDARD:
++ case CFI_CMDSET_INTEL_EXTENDED:
++ retval = !flash_isset (info, sect, 0, FLASH_STATUS_DONE);
++ break;
++ case CFI_CMDSET_AMD_STANDARD:
++ case CFI_CMDSET_AMD_EXTENDED:
++ retval = flash_toggle (info, sect, 0, AMD_STATUS_TOGGLE);
++ break;
++ default:
++ retval = 0;
++ }
++#ifdef DEBUG_FLASH
++ if (retval)
++ debug ("flash_is_busy: %d\n", retval);
++#endif
++ return retval;
++}
++
++/*-----------------------------------------------------------------------
++ * wait for XSR.7 to be set. Time out with an error if it does not.
++ * This routine does not set the flash to read-array mode.
++ */
++static int flash_status_check (flash_info_t * info, flash_sect_t sector,
++ ulong tout, char *prompt)
++{
++ ulong start, now;
++
++ /* Wait for command completion */
++ // (Sun) Fix order of checking time so it works when the CPU is very
++ // slow, e.g., single-stepping or emulation.
++ start = get_timer (0);
++ while (now = get_timer(start),
++ flash_is_busy (info, sector))
++ {
++ if (now > info->erase_blk_tout) {
++ printf ("Flash %s timeout at address %lx data %lx\n",
++ prompt, info->start[sector],
++ flash_read_long (info, sector, 0));
++ flash_write_cmd (info, sector, 0, info->cmd_reset);
++ return ERR_TIMOUT;
++ }
++ }
++ return ERR_OK;
++}
++
++/*-----------------------------------------------------------------------
++ * Wait for XSR.7 to be set, if it times out print an error, otherwise do a full status check.
++ * This routine sets the flash to read-array mode.
++ */
++static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
++ ulong tout, char *prompt)
++{
++ int retcode;
++
++ retcode = flash_status_check (info, sector, tout, prompt);
++ switch (info->vendor) {
++ case CFI_CMDSET_INTEL_EXTENDED:
++ case CFI_CMDSET_INTEL_STANDARD:
++ if ((retcode != ERR_OK)
++ && !flash_isequal (info, sector, 0, FLASH_STATUS_DONE)) {
++ retcode = ERR_INVAL;
++ printf ("Flash %s error at address %lx\n", prompt,
++ info->start[sector]);
++ if (flash_isset (info, sector, 0, FLASH_STATUS_ECLBS | FLASH_STATUS_PSLBS)) {
++ puts ("Command Sequence Error.\n");
++ } else if (flash_isset (info, sector, 0, FLASH_STATUS_ECLBS)) {
++ puts ("Block Erase Error.\n");
++ retcode = ERR_NOT_ERASED;
++ } else if (flash_isset (info, sector, 0, FLASH_STATUS_PSLBS)) {
++ puts ("Locking Error\n");
++ }
++ if (flash_isset (info, sector, 0, FLASH_STATUS_DPS)) {
++ puts ("Block locked.\n");
++ retcode = ERR_PROTECTED;
++ }
++ if (flash_isset (info, sector, 0, FLASH_STATUS_VPENS))
++ puts ("Vpp Low Error.\n");
++ }
++ flash_write_cmd (info, sector, 0, info->cmd_reset);
++ break;
++ default:
++ break;
++ }
++ return retcode;
++}
++
++static void write_buffer_abort_reset(flash_info_t * info, flash_sect_t sector)
++{
++ flash_write_cmd (info, sector, 0xaaa, 0xaa);
++ flash_write_cmd (info, sector, 0x555, 0x55);
++ flash_write_cmd (info, sector, 0xaaa, 0xf0);
++}
++
++/*-----------------------------------------------------------------------
++ */
++static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c)
++{
++#if defined(__LITTLE_ENDIAN)
++ unsigned short w;
++ unsigned int l;
++ unsigned long long ll;
++#endif
++
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ cword->c = c;
++ break;
++ case FLASH_CFI_16BIT:
++#if defined(__LITTLE_ENDIAN)
++ w = c;
++ w <<= 8;
++ cword->w = (cword->w >> 8) | w;
++#else
++ cword->w = (cword->w << 8) | c;
++#endif
++ break;
++ case FLASH_CFI_32BIT:
++#if defined(__LITTLE_ENDIAN)
++ l = c;
++ l <<= 24;
++ cword->l = (cword->l >> 8) | l;
++#else
++ cword->l = (cword->l << 8) | c;
++#endif
++ break;
++ case FLASH_CFI_64BIT:
++#if defined(__LITTLE_ENDIAN)
++ ll = c;
++ ll <<= 56;
++ cword->ll = (cword->ll >> 8) | ll;
++#else
++ cword->ll = (cword->ll << 8) | c;
++#endif
++ break;
++ }
++}
++
++
++/*-----------------------------------------------------------------------
++ * make a proper sized command based on the port and chip widths
++ */
++static void flash_make_cmd (flash_info_t * info, uchar cmd, void *cmdbuf)
++{
++ int i;
++ uchar *cp = (uchar *) cmdbuf;
++
++#if defined(__LITTLE_ENDIAN)
++ for (i = info->portwidth; i > 0; i--)
++#else
++ for (i = 1; i <= info->portwidth; i++)
++#endif
++ *cp++ = (i & (info->chipwidth - 1)) ? '\0' : cmd;
++}
++
++/*
++ * Write a proper sized command to the correct address
++ */
++static void
++flash_write_cmd (flash_info_t * info, flash_sect_t sect, uint offset,
++ uchar cmd)
++{
++#ifdef DEBUG_FLASH
++ const int noDebug = 0;
++#else
++ const int noDebug = 1;
++#endif
++ return flash_write_cmd_int(info, sect, offset, cmd, noDebug);
++}
++static void
++flash_write_cmd_nodbg (flash_info_t * info, flash_sect_t sect, uint offset,
++ uchar cmd)
++{
++ return flash_write_cmd_int(info, sect, offset, cmd, 1);
++}
++
++static void
++flash_write_cmd_int (flash_info_t * info, flash_sect_t sect, uint offset,
++ uchar cmd, int noDebug)
++{
++
++ volatile cfiptr_t addr;
++ cfiword_t cword;
++
++ addr.cp = flash_make_addr (info, sect, offset);
++ flash_make_cmd (info, cmd, &cword);
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ if (noDebug == 0)
++ debug ("fwc addr %p cmd %x %x 8bit x %d bit\n", addr.cp, cmd,
++ cword.c, info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
++ *addr.cp = cword.c;
++ break;
++ case FLASH_CFI_16BIT:
++ if (noDebug == 0)
++ debug ("fwc addr %p cmd %x %4.4x 16bit x %d bit\n", addr.wp,
++ cmd, cword.w,
++ info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
++ *addr.wp = cword.w;
++ break;
++ case FLASH_CFI_32BIT:
++ if (noDebug == 0)
++ debug ("fwc addr %p cmd %x %8.8lx 32bit x %d bit\n", addr.lp,
++ cmd, cword.l,
++ info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
++ *addr.lp = cword.l;
++ break;
++ case FLASH_CFI_64BIT:
++#ifdef DEBUG_FLASH
++ if (noDebug == 0)
++ {
++ char str[20];
++
++ print_longlong (str, cword.ll);
++
++ debug ("fwrite addr %p cmd %x %s 64 bit x %d bit\n",
++ addr.llp, cmd, str,
++ info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
++ }
++#endif
++ *addr.llp = cword.ll;
++ break;
++ }
++}
++
++static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect)
++{
++ flash_write_cmd_nodbg (info, sect, AMD_ADDR_START, AMD_CMD_UNLOCK_START);
++ flash_write_cmd_nodbg (info, sect, AMD_ADDR_ACK, AMD_CMD_UNLOCK_ACK);
++}
++
++/*-----------------------------------------------------------------------
++ */
++static int flash_isequal (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
++{
++ cfiptr_t cptr;
++ cfiword_t cword;
++ int retval;
++#ifdef DEBUG_FLASH
++ const int dbg = 1;
++#else
++ const int dbg = 0;
++#endif
++ cptr.cp = flash_make_addr (info, sect, offset);
++ flash_make_cmd (info, cmd, &cword);
++
++ if (dbg)
++ debug ("is= cmd %x(%c) addr %p ", cmd, cmd, cptr.cp);
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ if (dbg)
++ debug ("is= %x %x\n", cptr.cp[0], cword.c);
++ retval = (cptr.cp[0] == cword.c);
++ break;
++ case FLASH_CFI_16BIT:
++ if (dbg)
++ debug ("is= %4.4x %4.4x\n", cptr.wp[0], cword.w);
++ retval = (cptr.wp[0] == cword.w);
++ break;
++ case FLASH_CFI_32BIT:
++ if (dbg)
++ debug ("is= %8.8lx %8.8lx\n", cptr.lp[0], cword.l);
++ retval = (cptr.lp[0] == cword.l);
++ break;
++ case FLASH_CFI_64BIT:
++#ifdef DEBUG_FLASH
++ {
++ char str1[20];
++ char str2[20];
++
++ print_longlong (str1, cptr.llp[0]);
++ print_longlong (str2, cword.ll);
++ debug ("is= %s %s\n", str1, str2);
++ }
++#endif
++ retval = (cptr.llp[0] == cword.ll);
++ break;
++ default:
++ retval = 0;
++ break;
++ }
++ return retval;
++}
++
++/*-----------------------------------------------------------------------
++ */
++static int flash_isset (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
++{
++ cfiptr_t cptr;
++ cfiword_t cword;
++ int retval;
++
++ cptr.cp = flash_make_addr (info, sect, offset);
++ flash_make_cmd (info, cmd, &cword);
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ retval = ((cptr.cp[0] & cword.c) == cword.c);
++ break;
++ case FLASH_CFI_16BIT:
++ retval = ((cptr.wp[0] & cword.w) == cword.w);
++ break;
++ case FLASH_CFI_32BIT:
++ retval = ((cptr.lp[0] & cword.l) == cword.l);
++ break;
++ case FLASH_CFI_64BIT:
++ retval = ((cptr.llp[0] & cword.ll) == cword.ll);
++ break;
++ default:
++ retval = 0;
++ break;
++ }
++ return retval;
++}
++
++/*-----------------------------------------------------------------------
++ */
++static int flash_toggle (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
++{
++ cfiptr_t cptr;
++ cfiword_t cword;
++ int retval;
++
++ cptr.cp = flash_make_addr (info, sect, offset);
++ flash_make_cmd (info, cmd, &cword);
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ retval = ((cptr.cp[0] & cword.c) != (cptr.cp[0] & cword.c));
++ break;
++ case FLASH_CFI_16BIT:
++ retval = ((cptr.wp[0] & cword.w) != (cptr.wp[0] & cword.w));
++ break;
++ case FLASH_CFI_32BIT:
++ retval = ((cptr.lp[0] & cword.l) != (cptr.lp[0] & cword.l));
++ break;
++ case FLASH_CFI_64BIT:
++ retval = ((cptr.llp[0] & cword.ll) !=
++ (cptr.llp[0] & cword.ll));
++ break;
++ default:
++ retval = 0;
++ break;
++ }
++ return retval;
++}
++
++/*-----------------------------------------------------------------------
++ * detect if flash is compatible with the Common Flash Interface (CFI)
++ * http://www.jedec.org/download/search/jesd68.pdf
++ *
++*/
++static int flash_detect_cfi (flash_info_t * info)
++{
++ ulong data;
++
++ debug ("flash_detect_cfi()... ");
++
++#if defined(CONFIG_FLASH_AST2300)
++ data = *(ulong *)(0x1e6e2070); /* hardware traping */
++ if (data & 0x10) /* D[4]: 0/1 (8/16) */
++ info->portwidth = FLASH_CFI_16BIT;
++ else
++ info->portwidth = FLASH_CFI_8BIT;
++#else
++ info->portwidth = FLASH_CFI_8BIT;
++#endif
++
++ {
++ for (info->chipwidth = FLASH_CFI_BY8;
++ info->chipwidth <= info->portwidth;
++ info->chipwidth <<= 1) {
++ flash_write_cmd (info, 0, 0, FLASH_CMD_RESET);
++ flash_write_cmd (info, 0, FLASH_OFFSET_CFI, FLASH_CMD_CFI);
++ if (flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP, 'Q')
++ //FIXME: Next 3 lines were changed for 8-bit/16-bit flash chips.
++ && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP1, 'R')
++ && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP2, 'Y')) {
++ info->interface = flash_read_uchar (info, FLASH_OFFSET_INTERFACE);
++ debug ("device interface is %d\n",
++ info->interface);
++ debug ("found port %d chip %d ",
++ info->portwidth, info->chipwidth);
++ debug ("port %d bits chip %d bits\n",
++ info->portwidth << CFI_FLASH_SHIFT_WIDTH,
++ info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
++ return 1;
++ }
++ }
++ }
++ debug ("not found\n");
++ return 0;
++}
++
++/*
++ * The following code cannot be run from FLASH!
++ *
++ */
++ulong flash_get_size (ulong base, int banknum)
++{
++ flash_info_t *info = &flash_info[banknum];
++ int i, j;
++ flash_sect_t sect_cnt;
++ unsigned long sector;
++ unsigned long tmp;
++ int size_ratio;
++ uchar num_erase_regions;
++ int erase_region_size;
++ int erase_region_count;
++
++ info->start[0] = base;
++
++ if (flash_detect_cfi (info)) {
++ info->vendor = flash_read_uchar (info, FLASH_OFFSET_PRIMARY_VENDOR);
++#if defined(DEBUG_FLASH)
++ flash_printqry (info, 0);
++#endif
++ switch (info->vendor) {
++ case CFI_CMDSET_INTEL_STANDARD:
++ case CFI_CMDSET_INTEL_EXTENDED:
++ default:
++ info->cmd_reset = FLASH_CMD_RESET;
++ break;
++ case CFI_CMDSET_AMD_STANDARD:
++ case CFI_CMDSET_AMD_EXTENDED:
++ info->cmd_reset = AMD_CMD_RESET;
++ break;
++ }
++
++ debugX(2, "manufacturer is %d\n", info->vendor);
++ size_ratio = info->portwidth / info->chipwidth;
++ /* if the chip is x8/x16 reduce the ratio by half */
++#if 0
++ if ((info->interface == FLASH_CFI_X8X16)
++ && (info->chipwidth == FLASH_CFI_BY8)) {
++ size_ratio >>= 1;
++ }
++#endif
++ num_erase_regions = flash_read_uchar (info, FLASH_OFFSET_NUM_ERASE_REGIONS);
++ debugX(2, "size_ratio %d port %d bits chip %d bits\n",
++ size_ratio, info->portwidth << CFI_FLASH_SHIFT_WIDTH,
++ info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
++ debugX(2, "found %d erase regions\n", num_erase_regions);
++ sect_cnt = 0;
++ sector = base;
++ for (i = 0; i < num_erase_regions; i++) {
++ if (i > MAX_NUM_ERASE_REGIONS) {
++ printf ("%d erase regions found, only %d used\n",
++ num_erase_regions, MAX_NUM_ERASE_REGIONS);
++ break;
++ }
++ // CFI Erase Block Region Information:
++ // Bits[31:16] = sect_size/256, 0 means 128-byte
++ // Bits[15:0] = num_sectors - 1
++ tmp = flash_read_long(info, 0,
++ FLASH_OFFSET_ERASE_REGIONS + i * 4);
++ debug("CFI erase block region info[%d]: 0x%08x, ",
++ i, tmp);
++ erase_region_count = (tmp & 0xffff) + 1;
++ tmp >>= 16;
++ erase_region_size = (tmp ? tmp * 256 : 128);
++ debug ("erase_region_count=%d erase_region_size=%d\n",
++ erase_region_count, erase_region_size);
++#if 0
++ erase_region_size = CFG_FLASH_SECTOR_SIZE; // Commented out
++ erase_region_count = CFG_FLASH_SECTOR_COUNT; // Commented out
++#endif
++ if (sect_cnt + erase_region_count > CONFIG_SYS_MAX_FLASH_SECT) {
++ printf("Warning: Erase region %d adds too many flash sectors"
++ " %d+%d; reducing to fit total limit of %d\n",
++ i, sect_cnt, erase_region_count, CONFIG_SYS_MAX_FLASH_SECT);
++ erase_region_count = CONFIG_SYS_MAX_FLASH_SECT - sect_cnt;
++ }
++ for (j = 0; j < erase_region_count; j++) {
++ info->start[sect_cnt] = sector;
++ sector += (erase_region_size * size_ratio);
++
++ /*
++ * Only read protection status from supported devices (intel...)
++ */
++ switch (info->vendor) {
++ case CFI_CMDSET_INTEL_EXTENDED:
++ case CFI_CMDSET_INTEL_STANDARD:
++ info->protect[sect_cnt] =
++ flash_isset (info, sect_cnt,
++ FLASH_OFFSET_PROTECT,
++ FLASH_STATUS_PROTECT);
++ break;
++ default:
++ info->protect[sect_cnt] = 0; /* default: not protected */
++ }
++
++ sect_cnt++;
++ }
++ }
++
++ info->sector_count = sect_cnt;
++ /* multiply the size by the number of chips */
++ // info->size = (1 << flash_read_uchar (info, FLASH_OFFSET_SIZE)) * size_ratio;
++ // Use only the sectors that fit within the flash_info array size.
++ info->size = sector - base;
++ printf("Flash bank %d at %08x has 0x%x bytes in %d sectors"
++ " (chipSize 1<<%d, size_ratio %d).\n",
++ banknum, base, info->size, info->sector_count,
++ flash_read_uchar(info, FLASH_OFFSET_SIZE), size_ratio);
++
++ info->buffer_size = (1 << flash_read_uchar (info, FLASH_OFFSET_BUFFER_SIZE));
++ /* Limit the buffer size to 32bytes to meet most of AMD-styles flash's minimum requirement */
++ if (info->buffer_size > 32)
++ info->buffer_size = 32;
++ tmp = 1 << flash_read_uchar (info, FLASH_OFFSET_ETOUT);
++ info->erase_blk_tout = (tmp * (1 << flash_read_uchar (info, FLASH_OFFSET_EMAX_TOUT)));
++ tmp = 1 << flash_read_uchar (info, FLASH_OFFSET_WBTOUT);
++ info->buffer_write_tout = (tmp * (1 << flash_read_uchar (info, FLASH_OFFSET_WBMAX_TOUT)));
++ tmp = 1 << flash_read_uchar (info, FLASH_OFFSET_WTOUT);
++ info->write_tout = (tmp * (1 << flash_read_uchar (info, FLASH_OFFSET_WMAX_TOUT))) / 1000;
++ info->flash_id = FLASH_MAN_CFI;
++#if 0
++ if ((info->interface == FLASH_CFI_X8X16) && (info->chipwidth == FLASH_CFI_BY8)) {
++ info->portwidth >>= 1; /* XXX - Need to test on x8/x16 in parallel. */
++ }
++#endif
++ }
++
++ flash_write_cmd (info, 0, 0, info->cmd_reset);
++ return (info->size);
++}
++
++
++/*-----------------------------------------------------------------------
++ */
++static int flash_write_cfiword (flash_info_t * info, ulong dest,
++ cfiword_t cword)
++{
++
++ cfiptr_t ctladdr;
++ cfiptr_t cptr;
++ int flag;
++
++ ctladdr.cp = flash_make_addr (info, 0, 0);
++ cptr.cp = (uchar *) dest;
++
++
++ /* Check if Flash is (sufficiently) erased */
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ flag = ((cptr.cp[0] & cword.c) == cword.c);
++ break;
++ case FLASH_CFI_16BIT:
++ flag = ((cptr.wp[0] & cword.w) == cword.w);
++ break;
++ case FLASH_CFI_32BIT:
++ flag = ((cptr.lp[0] & cword.l) == cword.l);
++ break;
++ case FLASH_CFI_64BIT:
++ flag = ((cptr.llp[0] & cword.ll) == cword.ll);
++ break;
++ default:
++ return 2;
++ }
++ if (!flag)
++ return 2;
++
++ /* Disable interrupts which might cause a timeout here */
++ flag = disable_interrupts ();
++
++ switch (info->vendor) {
++ case CFI_CMDSET_INTEL_EXTENDED:
++ case CFI_CMDSET_INTEL_STANDARD:
++ flash_write_cmd_nodbg (info, 0, 0, FLASH_CMD_CLEAR_STATUS);
++ flash_write_cmd_nodbg (info, 0, 0, FLASH_CMD_WRITE);
++ break;
++ case CFI_CMDSET_AMD_EXTENDED:
++ case CFI_CMDSET_AMD_STANDARD:
++ flash_unlock_seq (info, 0);
++ flash_write_cmd_nodbg (info, 0, AMD_ADDR_START, AMD_CMD_WRITE);
++ break;
++ }
++
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ cptr.cp[0] = cword.c;
++ break;
++ case FLASH_CFI_16BIT:
++ cptr.wp[0] = cword.w;
++ break;
++ case FLASH_CFI_32BIT:
++ cptr.lp[0] = cword.l;
++ break;
++ case FLASH_CFI_64BIT:
++ cptr.llp[0] = cword.ll;
++ break;
++ }
++
++ /* re-enable interrupts if necessary */
++ if (flag)
++ enable_interrupts ();
++
++ return flash_full_status_check (info, 0, info->write_tout, "write");
++}
++
++#ifdef CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++
++/* loop through the sectors from the highest address
++ * when the passed address is greater or equal to the sector address
++ * we have a match
++ */
++static flash_sect_t find_sector (flash_info_t * info, ulong addr)
++{
++ flash_sect_t sector;
++
++ for (sector = info->sector_count - 1; sector >= 0; sector--) {
++ if (addr >= info->start[sector])
++ break;
++ }
++ return sector;
++}
++
++static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
++ int len)
++{
++ flash_sect_t sector;
++ int cnt;
++ int retcode;
++ volatile cfiptr_t src;
++ volatile cfiptr_t dst;
++
++/* Add AMD write buffer mode support, ycchen@102006 */
++#if 0
++ /* buffered writes in the AMD chip set is not supported yet */
++ if((info->vendor == CFI_CMDSET_AMD_STANDARD) ||
++ (info->vendor == CFI_CMDSET_AMD_EXTENDED))
++ return ERR_INVAL;
++#endif
++ if((info->vendor == CFI_CMDSET_AMD_STANDARD) ||
++ (info->vendor == CFI_CMDSET_AMD_EXTENDED))
++ {
++ retcode = flash_write_cfibuffer_amd(info, dest, cp, len);
++ return retcode;
++ }
++
++ src.cp = cp;
++ dst.cp = (uchar *) dest;
++ sector = find_sector (info, dest);
++ flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
++ flash_write_cmd (info, sector, 0, FLASH_CMD_WRITE_TO_BUFFER);
++ if ((retcode =
++ flash_status_check (info, sector, info->buffer_write_tout,
++ "write to buffer")) == ERR_OK) {
++ /* reduce the number of loops by the width of the port */
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ cnt = len;
++ break;
++ case FLASH_CFI_16BIT:
++ cnt = len >> 1;
++ break;
++ case FLASH_CFI_32BIT:
++ cnt = len >> 2;
++ break;
++ case FLASH_CFI_64BIT:
++ cnt = len >> 3;
++ break;
++ default:
++ return ERR_INVAL;
++ break;
++ }
++ flash_write_cmd (info, sector, 0, (uchar) cnt - 1);
++ while (cnt-- > 0) {
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ *dst.cp++ = *src.cp++;
++ break;
++ case FLASH_CFI_16BIT:
++ *dst.wp++ = *src.wp++;
++ break;
++ case FLASH_CFI_32BIT:
++ *dst.lp++ = *src.lp++;
++ break;
++ case FLASH_CFI_64BIT:
++ *dst.llp++ = *src.llp++;
++ break;
++ default:
++ return ERR_INVAL;
++ break;
++ }
++ }
++ flash_write_cmd (info, sector, 0,
++ FLASH_CMD_WRITE_BUFFER_CONFIRM);
++ retcode =
++ flash_full_status_check (info, sector,
++ info->buffer_write_tout,
++ "buffer write");
++ }
++ flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
++ return retcode;
++}
++
++
++static int flash_write_cfibuffer_amd (flash_info_t * info, ulong dest, uchar * cp,
++ int len)
++{
++ flash_sect_t sector;
++ int cnt;
++ int retcode;
++ volatile cfiptr_t src;
++ volatile cfiptr_t dst;
++ volatile cfiword_t tmpsrc, tmpdst;
++
++ src.cp = cp;
++ dst.cp = (uchar *) dest;
++ sector = find_sector (info, dest);
++ flash_unlock_seq (info, 0);
++ if ((retcode =
++ flash_status_check (info, sector, info->buffer_write_tout,
++ "write to buffer")) == ERR_OK) {
++ /* reduce the number of loops by the width of the port */
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ cnt = len;
++ *dst.cp = (uchar) (AMD_CMD_WRITE_TO_BUFFER);
++ *dst.cp = (uchar) (cnt -1);
++ break;
++ case FLASH_CFI_16BIT:
++ cnt = len >> 1;
++ *dst.wp = (unsigned short) (AMD_CMD_WRITE_TO_BUFFER);
++ *dst.wp = (unsigned short) (cnt -1);
++ break;
++ case FLASH_CFI_32BIT:
++ cnt = len >> 2;
++ *dst.lp = (unsigned long) (AMD_CMD_WRITE_TO_BUFFER);
++ *dst.lp = (unsigned long) (cnt -1);
++ break;
++ case FLASH_CFI_64BIT:
++ cnt = len >> 3;
++ *dst.llp = (unsigned long long) (AMD_CMD_WRITE_TO_BUFFER);
++ *dst.llp = (unsigned long long) (cnt -1);
++ break;
++ default:
++ return ERR_INVAL;
++ break;
++ }
++ while (cnt-- > 0) {
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ *dst.cp++ = *src.cp++;
++ break;
++ case FLASH_CFI_16BIT:
++ *dst.wp++ = *src.wp++;
++ break;
++ case FLASH_CFI_32BIT:
++ *dst.lp++ = *src.lp++;
++ break;
++ case FLASH_CFI_64BIT:
++ *dst.llp++ = *src.llp++;
++ break;
++ default:
++ return ERR_INVAL;
++ break;
++ }
++ }
++ switch (info->portwidth) {
++ case FLASH_CFI_8BIT:
++ src.cp--;
++ dst.cp--;
++ *dst.cp = (unsigned char) (AMD_CMD_BUFFER_TO_FLASH);
++ tmpsrc.c = *src.cp & 0x80;
++
++ do {
++ tmpdst.c = *(volatile uchar *)(dst.cp);
++
++ if (tmpdst.c & 0x20) { /* toggle DQ5 */
++ tmpdst.c = *(volatile uchar *)(dst.cp);
++ if ((tmpdst.c & 0x80) != tmpsrc.c)
++ {
++ printf("program error occurred\n");
++ flash_write_cmd (info, sector, 0, info->cmd_reset);
++ return ERR_PROG_ERROR;
++ }
++ }
++ else if (tmpdst.c & 0x02) { /* toggle DQ1 */
++ tmpdst.c = *(volatile uchar *)(dst.cp);
++ if ((tmpdst.c & 0x80) != tmpsrc.c)
++ {
++ printf("write buffer error occurred \n");
++ write_buffer_abort_reset(info, sector);
++ return ERR_PROG_ERROR;
++ }
++ }
++
++ } while ((tmpdst.c & 0x80) != tmpsrc.c);
++
++ break;
++ case FLASH_CFI_16BIT:
++ src.wp--;
++ dst.wp--;
++ *dst.wp = (unsigned short) (AMD_CMD_BUFFER_TO_FLASH);
++ tmpsrc.w = *src.wp & 0x80;
++
++ do {
++ tmpdst.w = *(volatile short *)(dst.wp);
++
++ if (tmpdst.w & 0x20) { /* toggle DQ5 */
++ tmpdst.w = *(volatile ushort *)(dst.wp);
++ if ((tmpdst.w & 0x80) != tmpsrc.w)
++ {
++ printf("program error occurred\n");
++ flash_write_cmd (info, sector, 0, info->cmd_reset);
++ return ERR_PROG_ERROR;
++ }
++ }
++ else if (tmpdst.w & 0x02) { /* toggle DQ1 */
++ tmpdst.w = *(volatile ushort *)(dst.wp);
++ if ((tmpdst.w & 0x80) != tmpsrc.w)
++ {
++ printf("write buffer error occurred \n");
++ write_buffer_abort_reset(info, sector);
++ return ERR_PROG_ERROR;
++ }
++ }
++
++ } while ((tmpdst.w & 0x80) != tmpsrc.w);
++
++ break;
++ case FLASH_CFI_32BIT:
++ src.lp--;
++ dst.lp--;
++ *dst.lp = (unsigned long) (AMD_CMD_BUFFER_TO_FLASH);
++ tmpsrc.l = *src.lp & 0x80;
++
++ do {
++ tmpdst.l = *(volatile ulong *)(dst.lp);
++
++ if (tmpdst.l & 0x20) { /* toggle DQ5 */
++ tmpdst.l = *(volatile ulong *)(dst.lp);
++ if ((tmpdst.l & 0x80) != tmpsrc.l)
++ {
++ printf("program error occurred\n");
++ flash_write_cmd (info, sector, 0, info->cmd_reset);
++ return ERR_PROG_ERROR;
++ }
++ }
++ else if (tmpdst.l & 0x02) { /* toggle DQ1 */
++ tmpdst.l = *(volatile ulong *)(dst.lp);
++ if ((tmpdst.l & 0x80) != tmpsrc.l)
++ {
++ printf("write buffer error occurred \n");
++ write_buffer_abort_reset(info, sector);
++ return ERR_PROG_ERROR;
++ }
++ }
++
++ } while ((tmpdst.l & 0x80) != tmpsrc.l);
++
++ break;
++ case FLASH_CFI_64BIT:
++ src.llp--;
++ dst.llp--;
++ *dst.llp = (unsigned long long) (AMD_CMD_BUFFER_TO_FLASH);
++ tmpsrc.ll = *src.llp & 0x80;
++
++ do {
++ tmpdst.ll = *(volatile unsigned long long *)(dst.llp);
++
++ if (tmpdst.ll & 0x20) { /* toggle DQ5 */
++ tmpdst.ll = *(volatile unsigned long long *)(dst.llp);
++ if ((tmpdst.ll & 0x80) != tmpsrc.ll)
++ {
++ printf("program error occurred\n");
++ flash_write_cmd (info, sector, 0, info->cmd_reset);
++ return ERR_PROG_ERROR;
++ }
++ }
++ else if (tmpdst.ll & 0x02) { /* toggle DQ1 */
++ tmpdst.ll = *(volatile unsigned long long *)(dst.llp);
++ if ((tmpdst.ll & 0x80) != tmpsrc.ll)
++ {
++ printf("write buffer error occurred \n");
++ write_buffer_abort_reset(info, sector);
++ return ERR_PROG_ERROR;
++ }
++ }
++
++ } while ((tmpdst.ll & 0x80) != tmpsrc.ll);
++
++ break;
++ default:
++ return ERR_INVAL;
++ break;
++ }
++
++ retcode =
++ flash_full_status_check (info, sector,
++ info->buffer_write_tout,
++ "buffer write");
++ }
++
++ return retcode;
++}
++#endif /* CONFIG_SYS_FLASH_USE_BUFFER_WRITE */
++
++#ifdef CONFIG_FLASH_AST2300_DMA
++#define STCBaseAddress 0x1e620000
++
++/* for DMA */
++#define REG_FLASH_INTERRUPT_STATUS 0x08
++#define REG_FLASH_DMA_CONTROL 0x80
++#define REG_FLASH_DMA_FLASH_BASE 0x84
++#define REG_FLASH_DMA_DRAM_BASE 0x88
++#define REG_FLASH_DMA_LENGTH 0x8c
++
++#define FLASH_STATUS_DMA_BUSY 0x0000
++#define FLASH_STATUS_DMA_READY 0x0800
++#define FLASH_STATUS_DMA_CLEAR 0x0800
++
++#define FLASH_DMA_ENABLE 0x01
++
++void * memmove_dma(void * dest,const void *src,size_t count)
++{
++ ulong count_align, poll_time, data;
++
++ count_align = (count + 3) & 0xFFFFFFFC; /* 4-bytes align */
++ poll_time = 100; /* set 100 us as default */
++
++ *(ulong *) (STCBaseAddress + REG_FLASH_DMA_CONTROL) = (ulong) (~FLASH_DMA_ENABLE);
++
++ *(ulong *) (STCBaseAddress + REG_FLASH_DMA_FLASH_BASE) = (ulong *) (src);
++ *(ulong *) (STCBaseAddress + REG_FLASH_DMA_DRAM_BASE) = (ulong *) (dest);
++ *(ulong *) (STCBaseAddress + REG_FLASH_DMA_LENGTH) = (ulong) (count_align);
++ udelay(10);
++ *(ulong *) (STCBaseAddress + REG_FLASH_DMA_CONTROL) = (ulong) (FLASH_DMA_ENABLE);
++
++ /* wait poll */
++ do {
++ udelay(poll_time);
++ data = *(ulong *) (STCBaseAddress + REG_FLASH_INTERRUPT_STATUS);
++ } while (!(data & FLASH_STATUS_DMA_READY));
++
++ /* clear status */
++ *(ulong *) (STCBaseAddress + REG_FLASH_INTERRUPT_STATUS) |= FLASH_STATUS_DMA_CLEAR;
++}
++#endif
++#endif /* CFG_FLASH_CFI */
+diff --git a/board/aspeed/ast2400/flash_spi.c b/board/aspeed/ast2400/flash_spi.c
+new file mode 100755
+index 0000000..ad89254
+--- /dev/null
++++ b/board/aspeed/ast2400/flash_spi.c
+@@ -0,0 +1,1634 @@
++/*
++ * 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
++ *
++ * History
++ * 01/20/2004 - combined variants of original driver.
++ * 01/22/2004 - Write performance enhancements for parallel chips (Tolunay)
++ * 01/23/2004 - Support for x8/x16 chips (Rune Raknerud)
++ * 01/27/2004 - Little endian support Ed Okerson
++ *
++ * Tested Architectures
++ * Port Width Chip Width # of banks Flash Chip Board
++ * 32 16 1 28F128J3 seranoa/eagle
++ * 64 16 1 28F128J3 seranoa/falcon
++ *
++ */
++
++/* The DEBUG define must be before common to enable debugging */
++/* #define DEBUG */
++
++#include <common.h>
++#include <asm/processor.h>
++#include <asm/byteorder.h>
++#include <environment.h>
++#ifdef CONFIG_FLASH_SPI
++
++/*
++ * This file implements a Common Flash Interface (CFI) driver for U-Boot.
++ * The width of the port and the width of the chips are determined at initialization.
++ * These widths are used to calculate the address for access CFI data structures.
++ * It has been tested on an Intel Strataflash implementation and AMD 29F016D.
++ *
++ * References
++ * JEDEC Standard JESD68 - Common Flash Interface (CFI)
++ * JEDEC Standard JEP137-A Common Flash Interface (CFI) ID Codes
++ * Intel Application Note 646 Common Flash Interface (CFI) and Command Sets
++ * Intel 290667-008 3 Volt Intel StrataFlash Memory datasheet
++ *
++ * TODO
++ *
++ * Use Primary Extended Query table (PRI) and Alternate Algorithm Query
++ * Table (ALT) to determine if protection is available
++ *
++ * Add support for other command sets Use the PRI and ALT to determine command set
++ * Verify erase and program timeouts.
++ */
++
++#ifndef CONFIG_FLASH_BANKS_LIST
++#define CONFIG_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE }
++#endif
++
++/* use CFG_MAX_FLASH_BANKS_DETECT if defined */
++#ifdef CONFIG_SYS_MAX_FLASH_BANKS_DETECT
++static ulong bank_base[CONFIG_SYS_MAX_FLASH_BANKS_DETECT] = CONFIG_FLASH_BANKS_LIST;
++flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS_DETECT]; /* FLASH chips info */
++#else
++static ulong bank_base[CONFIG_SYS_MAX_FLASH_BANKS] = CONFIG_FLASH_BANKS_LIST;
++flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* FLASH chips info */
++#endif
++
++/* Support Flash ID */
++#define STM25P64 0x172020
++#define STM25P128 0x182020
++#define N25Q256 0x19ba20
++#define N25Q512 0x20ba20
++#define S25FL064A 0x160201
++#define S25FL128P 0x182001
++#define S25FL256S 0x190201
++#define W25X16 0x1530ef
++#define W25X64 0x1730ef
++#define W25Q64BV 0x1740ef
++#define W25Q128BV 0x1840ef
++#define W25Q256FV 0x1940ef
++#define MX25L1605D 0x1520C2
++#define MX25L12805D 0x1820C2
++#define MX25L25635E 0x1920C2
++#define SST25VF016B 0x4125bf
++#define SST25VF064C 0x4b25bf
++#define AT25DF161 0x02461F
++#define AT25DF321 0x01471F
++
++/* SPI Define */
++#if defined(CONFIG_FLASH_AST2300) || defined(CONFIG_AST1300)
++#if defined(CONFIG_AST1300)
++#define STCBaseAddress 0x00620000
++#else
++#define STCBaseAddress 0x1e620000
++#endif
++#define SCU_REVISION_REGISTER 0x1e6e207c
++#define SCU_CACHE_CTRL_REGISTER 0x1e6e2118
++
++#define SPICtrlRegOffset 0x10
++#define SPICtrlRegOffset2 0x14
++
++#define SPIMiscCtrlRegOffset 0x54
++
++/* for DMA */
++#define REG_FLASH_INTERRUPT_STATUS 0x08
++#define REG_FLASH_DMA_CONTROL 0x80
++#define REG_FLASH_DMA_FLASH_BASE 0x84
++#define REG_FLASH_DMA_DRAM_BASE 0x88
++#define REG_FLASH_DMA_LENGTH 0x8c
++
++#define FLASH_STATUS_DMA_BUSY 0x0000
++#define FLASH_STATUS_DMA_READY 0x0800
++#define FLASH_STATUS_DMA_CLEAR 0x0800
++
++#define FLASH_DMA_ENABLE 0x01
++#else
++#define STCBaseAddress 0x16000000
++
++#define SPICtrlRegOffset 0x04
++#define SPICtrlRegOffset2 0x0C
++#endif /* CONFIG_FLASH_AST2300 */
++
++#define CMD_MASK 0xFFFFFFF8
++
++#define NORMALREAD 0x00
++#define FASTREAD 0x01
++#define NORMALWRITE 0x02
++#define USERMODE 0x03
++
++#define CE_LOW 0x00
++#define CE_HIGH 0x04
++
++/* AST2300 only */
++#define IOMODEx1 0x00000000
++#define IOMODEx2 0x20000000
++#define IOMODEx2_dummy 0x30000000
++#define IOMODEx4 0x40000000
++#define IOMODEx4_dummy 0x50000000
++
++#define DUMMY_COMMAND_OUT 0x00008000
++/* ~AST2300 only */
++
++/* specificspi */
++#define SpecificSPI_N25Q512 0x00000001
++
++static ulong AST2300_SPICLK_DIV[16] = {0x0F, 0x07, 0x0E, 0x06, 0x0D, 0x05, 0x0C, 0x04, \
++ 0x0B, 0x03, 0x0A, 0x02, 0x09, 0x01, 0x08, 0x00 };
++
++/*-----------------------------------------------------------------------
++ * Functions
++ */
++static void reset_flash (flash_info_t * info);
++static void enable_write (flash_info_t * info);
++static void write_status_register (flash_info_t * info, uchar data);
++static void enable4b (flash_info_t * info);
++static void enable4b_spansion (flash_info_t * info);
++static void enable4b_numonyx (flash_info_t * info);
++static ulong flash_get_size (ulong base, int banknum);
++static int flash_write_buffer (flash_info_t *info, uchar *src, ulong addr, int len);
++#if defined(CFG_ENV_IS_IN_FLASH) || defined(CFG_ENV_ADDR_REDUND) || (CFG_MONITOR_BASE >= CFG_FLASH_BASE)
++static flash_info_t *flash_get_info(ulong base);
++#endif
++
++
++/*-----------------------------------------------------------------------
++ * create an address based on the offset and the port width
++ */
++inline uchar *flash_make_addr (flash_info_t * info, flash_sect_t sect, uint offset)
++{
++#ifdef CONFIG_2SPIFLASH
++ if (info->start[0] >= PHYS_FLASH_2)
++ return ((uchar *) (info->start[sect] + (offset * 1) - (PHYS_FLASH_2 - PHYS_FLASH_2_BASE) ));
++ else
++ return ((uchar *) (info->start[sect] + (offset * 1)));
++#else
++ return ((uchar *) (info->start[sect] + (offset * 1)));
++#endif
++}
++
++/*-----------------------------------------------------------------------
++ * read a character at a port width address
++ */
++inline uchar flash_read_uchar (flash_info_t * info, uint offset)
++{
++ uchar *cp;
++
++ cp = flash_make_addr (info, 0, offset);
++#if defined(__LITTLE_ENDIAN)
++ return (cp[0]);
++#else
++ return (cp[1 - 1]);
++#endif
++}
++
++/*-----------------------------------------------------------------------
++ * read a short word by swapping for ppc format.
++ */
++ushort flash_read_ushort (flash_info_t * info, flash_sect_t sect, uint offset)
++{
++ uchar *addr;
++ ushort retval;
++
++#ifdef DEBUG
++ int x;
++#endif
++ addr = flash_make_addr (info, sect, offset);
++
++#ifdef DEBUG
++ debug ("ushort addr is at %p 1 = %d\n", addr,
++ 1);
++ for (x = 0; x < 2 * 1; x++) {
++ debug ("addr[%x] = 0x%x\n", x, addr[x]);
++ }
++#endif
++#if defined(__LITTLE_ENDIAN)
++ retval = ((addr[(1)] << 8) | addr[0]);
++#else
++ retval = ((addr[(2 * 1) - 1] << 8) |
++ addr[1 - 1]);
++#endif
++
++ debug ("retval = 0x%x\n", retval);
++ return retval;
++}
++
++/*-----------------------------------------------------------------------
++ * read a long word by picking the least significant byte of each maiximum
++ * port size word. Swap for ppc format.
++ */
++ulong flash_read_long (flash_info_t * info, flash_sect_t sect, uint offset)
++{
++ uchar *addr;
++ ulong retval;
++
++#ifdef DEBUG
++ int x;
++#endif
++ addr = flash_make_addr (info, sect, offset);
++
++#ifdef DEBUG
++ debug ("long addr is at %p 1 = %d\n", addr,
++ 1);
++ for (x = 0; x < 4 * 1; x++) {
++ debug ("addr[%x] = 0x%x\n", x, addr[x]);
++ }
++#endif
++#if defined(__LITTLE_ENDIAN)
++ retval = (addr[0] << 16) | (addr[(1)] << 24) |
++ (addr[(2 * 1)]) | (addr[(3 * 1)] << 8);
++#else
++ retval = (addr[(2 * 1) - 1] << 24) |
++ (addr[(1) - 1] << 16) |
++ (addr[(4 * 1) - 1] << 8) |
++ addr[(3 * 1) - 1];
++#endif
++ return retval;
++}
++
++/*-----------------------------------------------------------------------
++ */
++static void disable_cache(void)
++{
++#if defined(AST1300_CPU_CACHE_ENABLE)
++ ulong uldata;
++
++ uldata = *(volatile ulong *) (SCU_CACHE_CTRL_REGISTER);
++ uldata &= 0xfffffffd;
++ *(ulong *) (SCU_CACHE_CTRL_REGISTER) = uldata;
++#endif
++}
++
++static void enable_cache(void)
++{
++#if defined(AST1300_CPU_CACHE_ENABLE)
++ ulong uldata;
++
++ uldata = *(volatile ulong *) (SCU_CACHE_CTRL_REGISTER);
++ uldata |= 0x00000002;
++ *(ulong *) (SCU_CACHE_CTRL_REGISTER) = uldata;
++#endif
++}
++
++static void reset_flash (flash_info_t * info)
++{
++ ulong ulCtrlData, CtrlOffset, MiscCtrlOffset;
++
++ if (info->CE == 2)
++ {
++ CtrlOffset = SPICtrlRegOffset2;
++ }
++ else
++ {
++ CtrlOffset = SPICtrlRegOffset;
++ }
++
++#if defined(CONFIG_FLASH_AST2300) || defined(CONFIG_AST1300)
++ ulCtrlData = info->iomode | (info->readcmd << 16) | (info->tCK_Read << 8) | (info->dummybyte << 6) | FASTREAD;
++#if 0
++ if (info->quadport)
++ {
++ MiscCtrlOffset = SPIMiscCtrlRegOffset;
++ *(ulong *) (STCBaseAddress + MiscCtrlOffset) = info->dummydata;
++ ulCtrlData |= DUMMY_COMMAND_OUT;
++ }
++#endif
++#else
++ ulCtrlData = (info->readcmd << 16) | (info->tCK_Read << 8) | (info->dummybyte << 6) | FASTREAD;
++ if (info->dualport)
++ ulCtrlData |= 0x08;
++#endif
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++
++ enable_cache();
++}
++
++static void enable_write (flash_info_t * info)
++{
++ ulong base;
++ ulong ulCtrlData, CtrlOffset;
++ uchar jReg;
++
++ if (info->CE == 2)
++ {
++ CtrlOffset = SPICtrlRegOffset2;
++ }
++ else
++ {
++ CtrlOffset = SPICtrlRegOffset;
++ }
++
++ //base = info->start[0];
++ base = flash_make_addr (info, 0, 0);
++
++ ulCtrlData = (info->tCK_Write << 8);
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0x06);
++ udelay(10);
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0x05);
++ udelay(10);
++ do {
++ jReg = *(volatile uchar *) (base);
++ } while (!(jReg & 0x02));
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++}
++
++static void write_status_register (flash_info_t * info, uchar data)
++{
++ ulong base;
++ ulong ulSMMBase, ulCtrlData, CtrlOffset;
++ uchar jReg;
++
++ if (info->CE == 2)
++ {
++ CtrlOffset = SPICtrlRegOffset2;
++ }
++ else
++ {
++ CtrlOffset = SPICtrlRegOffset;
++ }
++
++ //base = info->start[0];
++ base = flash_make_addr (info, 0, 0);
++
++ enable_write (info);
++
++ ulCtrlData = (info->tCK_Write << 8);
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0x01);
++ udelay(10);
++ *(uchar *) (base) = (uchar) (data);
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0x05);
++ udelay(10);
++ do {
++ jReg = *(volatile uchar *) (base);
++ } while (jReg & 0x01);
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++}
++
++static void enable4b (flash_info_t * info)
++{
++ ulong base;
++ ulong ulSMMBase, ulCtrlData, CtrlOffset;
++ uchar jReg;
++
++ if (info->CE == 2)
++ {
++ CtrlOffset = SPICtrlRegOffset2;
++ }
++ else
++ {
++ CtrlOffset = SPICtrlRegOffset;
++ }
++
++ //base = info->start[0];
++ base = flash_make_addr (info, 0, 0);
++
++ ulCtrlData = (info->tCK_Write << 8);
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0xb7);
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++} /* enable4b */
++
++static void enable4b_spansion (flash_info_t * info)
++{
++ ulong base;
++ ulong ulSMMBase, ulCtrlData, CtrlOffset;
++ uchar jReg;
++
++ if (info->CE == 2)
++ {
++ CtrlOffset = SPICtrlRegOffset2;
++ }
++ else
++ {
++ CtrlOffset = SPICtrlRegOffset;
++ }
++
++ //base = info->start[0];
++ base = flash_make_addr (info, 0, 0);
++
++ /* Enable 4B: BAR0 D[7] = 1 */
++ ulCtrlData = (info->tCK_Write << 8);
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0x17);
++ udelay(10);
++ *(uchar *) (base) = (uchar) (0x80);
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0x16);
++ udelay(10);
++ do {
++ jReg = *(volatile uchar *) (base);
++ } while (!(jReg & 0x80));
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++} /* enable4b_spansion */
++
++static void enable4b_numonyx (flash_info_t * info)
++{
++ ulong base;
++ ulong ulSMMBase, ulCtrlData, CtrlOffset;
++ uchar jReg;
++
++ if (info->CE == 2)
++ {
++ CtrlOffset = SPICtrlRegOffset2;
++ }
++ else
++ {
++ CtrlOffset = SPICtrlRegOffset;
++ }
++
++ //base = info->start[0];
++ base = flash_make_addr (info, 0, 0);
++
++ /* Enable Write */
++ enable_write (info);
++
++ /* Enable 4B: CMD:0xB7 */
++ ulCtrlData = (info->tCK_Write << 8);
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0xB7);
++ udelay(10);
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++} /* enable4b_numonyx */
++
++/*
++ *
++ */
++static ulong flash_get_size (ulong base, int banknum)
++{
++ flash_info_t *info = &flash_info[banknum];
++ int j;
++ unsigned long sector;
++ int erase_region_size;
++ ulong ulCtrlData, CtrlOffset;
++ ulong ulID;
++ uchar ch[3];
++ ulong cpuclk, div, reg;
++ ulong WriteClk, EraseClk, ReadClk;
++ ulong vbase;
++ ulong SCURevision;
++
++ ulong ulRefPLL;
++ ulong ulDeNumerator;
++ ulong ulNumerator;
++ ulong ulOD;
++
++ disable_cache();
++
++ info->start[0] = base;
++ vbase = flash_make_addr (info, 0, 0);
++
++#if defined(CONFIG_FLASH_AST2300) || defined(CONFIG_AST1300)
++ CtrlOffset = SPICtrlRegOffset;
++ info->CE = 0;
++#else
++ if (vbase == PHYS_FLASH_1)
++ {
++ CtrlOffset = SPICtrlRegOffset2;
++ info->CE = 2;
++ }
++ else
++ {
++ CtrlOffset = SPICtrlRegOffset;
++ info->CE = 0;
++ }
++#endif
++
++ /* Get Flash ID */
++ ulCtrlData = *(ulong *) (STCBaseAddress + CtrlOffset) & CMD_MASK;
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (vbase) = (uchar) (0x9F);
++ udelay(10);
++ ch[0] = *(volatile uchar *)(vbase);
++ udelay(10);
++ ch[1] = *(volatile uchar *)(vbase);
++ udelay(10);
++ ch[2] = *(volatile uchar *)(vbase);
++ udelay(10);
++ ulCtrlData = *(ulong *) (STCBaseAddress + CtrlOffset) & CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ ulID = ((ulong)ch[0]) | ((ulong)ch[1] << 8) | ((ulong)ch[2] << 16) ;
++ info->flash_id = ulID;
++
++ //printf("SPI Flash ID: %x \n", ulID);
++
++ /* init default */
++ info->iomode = IOMODEx1;
++ info->address32 = 0;
++ info->quadport = 0;
++ info->specificspi = 0;
++
++ switch (info->flash_id)
++ {
++ case STM25P64:
++ info->sector_count = 128;
++ info->size = 0x800000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++ WriteClk = 40;
++ EraseClk = 20;
++ ReadClk = 40;
++ break;
++
++ case STM25P128:
++ info->sector_count = 64;
++ info->size = 0x1000000;
++ erase_region_size = 0x40000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++ WriteClk = 50;
++ EraseClk = 20;
++ ReadClk = 50;
++ break;
++
++ case N25Q256:
++ info->sector_count = 256;
++ info->size = 0x1000000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++ WriteClk = 50;
++ EraseClk = 20;
++ ReadClk = 50;
++#if defined(CONFIG_FLASH_AST2300) || defined(CONFIG_AST1300)
++ info->sector_count = 512;
++ info->size = 0x2000000;
++ info->address32 = 1;
++#endif
++ break;
++
++ case N25Q512:
++ info->sector_count = 256;
++ info->size = 0x1000000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++ info->specificspi = SpecificSPI_N25Q512;
++ WriteClk = 50;
++ EraseClk = 20;
++ ReadClk = 50;
++#if defined(CONFIG_FLASH_AST2300) || defined(CONFIG_AST1300)
++ info->sector_count = 1024;
++ info->size = 0x4000000;
++ info->address32 = 1;
++#endif
++ break;
++
++ case W25X16:
++ info->sector_count = 32;
++ info->size = 0x200000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x3b;
++ info->dualport = 1;
++ info->dummybyte = 1;
++ info->iomode = IOMODEx2;
++ info->buffersize = 256;
++ WriteClk = 50;
++ EraseClk = 25;
++ ReadClk = 50;
++ break;
++
++ case W25X64:
++ info->sector_count = 128;
++ info->size = 0x800000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x3b;
++ info->dualport = 1;
++ info->dummybyte = 1;
++ info->iomode = IOMODEx2;
++ info->buffersize = 256;
++ WriteClk = 50;
++ EraseClk = 25;
++ ReadClk = 50;
++ break;
++
++ case W25Q64BV:
++ info->sector_count = 128;
++ info->size = 0x800000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x3b;
++ info->dualport = 1;
++ info->dummybyte = 1;
++ info->iomode = IOMODEx2;
++ info->buffersize = 256;
++ WriteClk = 80;
++ EraseClk = 40;
++ ReadClk = 80;
++ break;
++
++ case W25Q128BV:
++ info->sector_count = 256;
++ info->size = 0x1000000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x3b;
++ info->dualport = 1;
++ info->dummybyte = 1;
++ info->iomode = IOMODEx2;
++ info->buffersize = 256;
++ WriteClk = 104;
++ EraseClk = 50;
++ ReadClk = 104;
++ break;
++
++ case W25Q256FV:
++ info->sector_count = 256;
++ info->size = 0x1000000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++ WriteClk = 50;
++ EraseClk = 20;
++ ReadClk = 50;
++#if defined(CONFIG_FLASH_AST2300) || defined(CONFIG_AST1300)
++ info->sector_count = 512;
++ info->size = 0x2000000;
++ info->address32 = 1;
++#endif
++ break;
++
++ case S25FL064A:
++ info->sector_count = 128;
++ info->size = 0x800000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++ WriteClk = 50;
++ EraseClk = 25;
++ ReadClk = 50;
++ break;
++
++ case S25FL128P:
++ info->sector_count = 256;
++ info->size = 0x1000000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++ WriteClk = 100;
++ EraseClk = 40;
++ ReadClk = 100;
++ break;
++
++ case S25FL256S:
++ info->sector_count = 256;
++ info->size = 0x1000000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++ WriteClk = 50;
++ EraseClk = 20;
++ ReadClk = 50;
++#if defined(CONFIG_FLASH_AST2300) || defined(CONFIG_AST1300)
++ info->sector_count = 512;
++ info->size = 0x2000000;
++ info->address32 = 1;
++#endif
++ break;
++
++ case MX25L25635E:
++ info->sector_count = 256;
++ info->size = 0x1000000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++ WriteClk = 50;
++ EraseClk = 20;
++ ReadClk = 50;
++#if defined(CONFIG_FLASH_AST2300) || defined(CONFIG_AST1300)
++ info->sector_count = 512;
++ info->size = 0x2000000;
++ info->address32 = 1;
++#if defined(CONFIG_FLASH_SPIx2_Dummy)
++ info->readcmd = 0xbb;
++ info->dummybyte = 1;
++ info->dualport = 1;
++ info->iomode = IOMODEx2_dummy;
++#elif defined(CONFIG_FLASH_SPIx4_Dummy)
++ info->readcmd = 0xeb;
++ info->dummybyte = 3;
++ info->dualport = 0;
++ info->iomode = IOMODEx4_dummy;
++ info->quadport = 1;
++ info->dummydata = 0xaa;
++#endif
++#endif
++ break;
++
++ case MX25L12805D:
++ info->sector_count = 256;
++ info->size = 0x1000000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++/*
++SCU7C: Silicon Revision ID Register
++D[31:24]: Chip ID
++0: AST2050/AST2100/AST2150/AST2200/AST3000
++1: AST2300
++
++D[23:16] Silicon revision ID for AST2300 generation and later
++0: A0
++1: A1
++2: A2
++.
++.
++.
++FPGA revision starts from 0x80
++
++AST2300 A0 SPI can't run faster than 50Mhz
++*/
++ WriteClk = 50;
++ EraseClk = 20;
++ ReadClk = 50;
++
++ SCURevision = *(ulong *) (SCU_REVISION_REGISTER);
++ if (((SCURevision >> 24) & 0xff) == 0x01) { //AST2300
++ if (((SCURevision >> 16) & 0xff) == 0x00) { //A0
++ WriteClk = 25;
++ EraseClk = 20;
++ ReadClk = 25;
++ }
++ }
++#if defined(CONFIG_FLASH_AST2300) || defined(CONFIG_AST1300)
++#if defined(CONFIG_FLASH_SPIx2_Dummy)
++ info->readcmd = 0xbb;
++ info->dummybyte = 1;
++ info->dualport = 1;
++ info->iomode = IOMODEx2_dummy;
++#elif defined(CONFIG_FLASH_SPIx4_Dummy)
++ info->readcmd = 0xeb;
++ info->dummybyte = 3;
++ info->dualport = 0;
++ info->iomode = IOMODEx4_dummy;
++ info->quadport = 1;
++ info->dummydata = 0xaa;
++#endif
++#endif
++ break;
++
++ case MX25L1605D:
++ info->sector_count = 32;
++ info->size = 0x200000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++ WriteClk = 50;
++ EraseClk = 20;
++ ReadClk = 50;
++ break;
++
++ case SST25VF016B:
++ info->sector_count = 32;
++ info->size = 0x200000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 1;
++ WriteClk = 50;
++ EraseClk = 25;
++ ReadClk = 50;
++ break;
++
++ case SST25VF064C:
++ info->sector_count = 128;
++ info->size = 0x800000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 1;
++ WriteClk = 50;
++ EraseClk = 25;
++ ReadClk = 50;
++ break;
++
++ case AT25DF161:
++ info->sector_count = 32;
++ info->size = 0x200000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 1;
++ WriteClk = 50;
++ EraseClk = 25;
++ ReadClk = 50;
++ break;
++
++ case AT25DF321:
++ info->sector_count = 32;
++ info->size = 0x400000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 1;
++ WriteClk = 50;
++ EraseClk = 25;
++ ReadClk = 50;
++ break;
++
++ default: /* use JEDEC ID */
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 1;
++ WriteClk = 50;
++ EraseClk = 25;
++ ReadClk = 50;
++ if ((info->flash_id & 0xFF) == 0x1F) /* Atmel */
++ {
++ switch (info->flash_id & 0x001F00)
++ {
++ case 0x000400:
++ info->sector_count = 8;
++ info->size = 0x80000;
++ break;
++ case 0x000500:
++ info->sector_count = 16;
++ info->size = 0x100000;
++ break;
++ case 0x000600:
++ info->sector_count = 32;
++ info->size = 0x200000;
++ break;
++ case 0x000700:
++ info->sector_count = 64;
++ info->size = 0x400000;
++ break;
++ case 0x000800:
++ info->sector_count = 128;
++ info->size = 0x800000;
++ break;
++ case 0x000900:
++ info->sector_count = 256;
++ info->size = 0x1000000;
++ break;
++ default:
++ printf("Can't support this SPI Flash!! \n");
++ return 0;
++ }
++ } /* Atmel JDEC */
++ else /* JDEC */
++ {
++ switch (info->flash_id & 0xFF0000)
++ {
++ case 0x120000:
++ info->sector_count = 4;
++ info->size = 0x40000;
++ break;
++ case 0x130000:
++ info->sector_count = 8;
++ info->size = 0x80000;
++ break;
++ case 0x140000:
++ info->sector_count =16;
++ info->size = 0x100000;
++ break;
++ case 0x150000:
++ info->sector_count =32;
++ info->size = 0x200000;
++ break;
++ case 0x160000:
++ info->sector_count =64;
++ info->size = 0x400000;
++ break;
++ case 0x170000:
++ info->sector_count =128;
++ info->size = 0x800000;
++ break;
++ case 0x180000:
++ info->sector_count =256;
++ info->size = 0x1000000;
++ break;
++ case 0x190000:
++ info->sector_count =256;
++ info->size = 0x1000000;
++#if defined(CONFIG_FLASH_AST2300) || defined(CONFIG_AST1300)
++ info->sector_count = 512;
++ info->size = 0x2000000;
++ info->address32 = 1;
++#if defined(CONFIG_FLASH_SPIx2_Dummy)
++ info->readcmd = 0xbb;
++ info->dummybyte = 1;
++ info->dualport = 1;
++ info->iomode = IOMODEx2_dummy;
++#elif defined(CONFIG_FLASH_SPIx4_Dummy)
++ info->readcmd = 0xeb;
++ info->dummybyte = 3;
++ info->dualport = 0;
++ info->iomode = IOMODEx4_dummy;
++ info->quadport = 1;
++ info->dummydata = 0xaa;
++#endif
++#endif
++ break;
++
++ case 0x200000:
++ info->sector_count =256;
++ info->size = 0x1000000;
++ if ((info->flash_id & 0xFF) == 0x20) /* numonyx */
++ info->specificspi = SpecificSPI_N25Q512;
++#if defined(CONFIG_FLASH_AST2300) || defined(CONFIG_AST1300)
++ info->sector_count = 1024;
++ info->size = 0x4000000;
++ info->address32 = 1;
++#if defined(CONFIG_FLASH_SPIx2_Dummy)
++ info->readcmd = 0xbb;
++ info->dummybyte = 1;
++ info->dualport = 1;
++ info->iomode = IOMODEx2_dummy;
++#elif defined(CONFIG_FLASH_SPIx4_Dummy)
++ info->readcmd = 0xeb;
++ info->dummybyte = 3;
++ info->dualport = 0;
++ info->iomode = IOMODEx4_dummy;
++ info->quadport = 1;
++ info->dummydata = 0xaa;
++#endif
++#endif
++ break;
++
++ default:
++ printf("Can't support this SPI Flash!! \n");
++ return 0;
++ }
++ } /* JDEC */
++ }
++
++ debug ("erase_region_count = %d erase_region_size = %d\n",
++ erase_region_count, erase_region_size);
++
++ sector = base;
++ for (j = 0; j < info->sector_count; j++) {
++
++ info->start[j] = sector;
++ sector += erase_region_size;
++ info->protect[j] = 0; /* default: not protected */
++ }
++
++ /* set SPI flash extended info */
++#if defined(CONFIG_AST1300)
++ if (info->size > 0x200000) /* limit MAX Flash to 2MB for AST1300 */
++ info->size = 0x200000;
++#endif
++#if defined(CONFIG_AST2400) || defined(CONFIG_AST2300) || defined(CONFIG_AST2300_FPGA_1) || defined(CONFIG_AST2300_FPGA_2) || defined(CONFIG_AST1300)
++ reg = *((volatile ulong*) 0x1e6e2024);
++ if (reg & 0x40000)
++ {
++ reg = *((volatile ulong*) 0x1e6e2070);
++
++ ulRefPLL = 24;
++ ulDeNumerator = reg & 0x0F;
++ ulNumerator = (reg & 0x07E0) >> 5;
++ ulOD = (reg & 0x10) ? 1:2;
++
++ cpuclk = ulRefPLL * ulOD * (ulNumerator + 2) / (ulDeNumerator + 1);
++ }
++ else
++ {
++ reg = *((volatile ulong*) 0x1e6e2070);
++#if defined(CONFIG_AST2400)
++ if (reg & 0x00800000) //ref. clk:25MHz
++ {
++ switch (reg & 0x300)
++ {
++ case 0x000:
++ cpuclk = 400;
++ break;
++ case 0x100:
++ cpuclk = 375;
++ break;
++ case 0x200:
++ cpuclk = 350;
++ break;
++ case 0x300:
++ cpuclk = 325;
++ break;
++ }
++ }
++ else
++ {
++ switch (reg & 0x300) //ref. clk:24MHz
++ {
++ case 0x000:
++ cpuclk = 384;
++ break;
++ case 0x100:
++ cpuclk = 360;
++ break;
++ case 0x200:
++ cpuclk = 336;
++ break;
++ case 0x300:
++ cpuclk = 312;
++ break;
++ }
++ }
++#else
++ switch (reg & 0x300)
++ {
++ case 0x000:
++ cpuclk = 384;
++ break;
++ case 0x100:
++ cpuclk = 360;
++ break;
++ case 0x200:
++ cpuclk = 336;
++ break;
++ case 0x300:
++ cpuclk = 408;
++ break;
++ }
++#endif
++ }
++
++ reg = *((volatile ulong*) 0x1e6e2070);
++ switch (reg & 0xc00)
++ {
++ case 0x000:
++ cpuclk /= 1;
++ break;
++ case 0x400:
++ cpuclk /= 2;
++ break;
++ case 0x800:
++ cpuclk /= 4;
++ break;
++ case 0xC00:
++ cpuclk /= 3;
++ break;
++ }
++#else /* AST2100 */
++ reg = *((volatile ulong*) 0x1e6e2070);
++ switch (reg & 0xe00)
++ {
++ case 0x000:
++ cpuclk = 266;
++ break;
++ case 0x200:
++ cpuclk = 233;
++ break;
++ case 0x400:
++ cpuclk = 200;
++ break;
++ case 0x600:
++ cpuclk = 166;
++ break;
++ case 0x800:
++ cpuclk = 133;
++ break;
++ case 0xA00:
++ cpuclk = 100;
++ break;
++ case 0xC00:
++ cpuclk = 300;
++ break;
++ case 0xE00:
++ cpuclk = 24;
++ break;
++ }
++ switch (reg & 0x3000)
++ {
++ case 0x1000:
++ cpuclk /= 2;
++ break;
++ case 0x2000:
++ cpuclk /= 4;
++ break;
++ case 0x3000:
++ cpuclk /= 3;
++ break;
++ }
++#endif
++
++#if defined(CONFIG_AST2400) || defined(CONFIG_AST2300) || defined(CONFIG_AST2300_FPGA_1) || defined(CONFIG_AST2300_FPGA_2) || defined(CONFIG_AST1300)
++
++#if defined(CONFIG_AST2300) || defined(CONFIG_AST1300)
++ /* limit Max SPI CLK to 50MHz (Datasheet v1.2) */
++ if (WriteClk > 50) WriteClk = 50;
++ if (EraseClk > 50) EraseClk = 50;
++ if (ReadClk > 50) ReadClk = 50;
++#endif
++
++ div = 1;
++ while ( ((cpuclk/div) > WriteClk) && (div < 16) )
++ {
++ div++;
++ }
++ info->tCK_Write = AST2300_SPICLK_DIV[div-1];
++
++ div = 1;
++ while ( ((cpuclk/div) > EraseClk) && (div < 16) )
++ {
++ div++;
++ }
++ info->tCK_Erase = AST2300_SPICLK_DIV[div-1];
++
++ div = 1;
++ while ( ((cpuclk/div) > ReadClk) && (div < 16) )
++ {
++ div++;
++ }
++ info->tCK_Read = AST2300_SPICLK_DIV[div-1];
++#else
++ div = 2;
++ info->tCK_Write = 7;
++ while ( (cpuclk/div) > WriteClk )
++ {
++ info->tCK_Write--;
++ div +=2;
++ }
++ div = 2;
++ info->tCK_Erase = 7;
++ while ( (cpuclk/div) > EraseClk )
++ {
++ info->tCK_Erase--;
++ div +=2;
++ }
++ div = 2;
++ info->tCK_Read = 7;
++ while ( (cpuclk/div) > ReadClk )
++ {
++ info->tCK_Read--;
++ div +=2;
++ }
++#endif
++
++ /* unprotect flash */
++ write_status_register(info, 0);
++
++ if (info->quadport)
++ write_status_register(info, 0x40); /* enable QE */
++
++ if (info->address32)
++ {
++ reg = *((volatile ulong*) 0x1e6e2070); /* set H/W Trappings */
++ reg |= 0x10;
++ *((volatile ulong*) 0x1e6e2070) = reg;
++
++ reg = *((volatile ulong*) 0x1e620004); /* enable 32b control bit*/
++ reg |= (0x01 << info->CE);
++ *((volatile ulong*) 0x1e620004) = reg;
++
++ /* set flash chips to 32bits addressing mode */
++ if ((info->flash_id & 0xFF) == 0x01) /* Spansion */
++ enable4b_spansion(info);
++ else if ((info->flash_id & 0xFF) == 0x20) /* Numonyx */
++ enable4b_numonyx(info);
++ else /* MXIC, Winbond */
++ enable4b(info);
++
++ }
++
++ reset_flash(info);
++
++ return (info->size);
++}
++
++
++/*-----------------------------------------------------------------------
++ */
++static int flash_write_buffer (flash_info_t *info, uchar *src, ulong addr, int len)
++{
++ ulong j, base, offset;
++ ulong ulSMMBase, ulCtrlData, CtrlOffset;
++ uchar jReg;
++
++ if (info->CE == 2)
++ {
++ CtrlOffset = SPICtrlRegOffset2;
++ }
++ else
++ {
++ CtrlOffset = SPICtrlRegOffset;
++ }
++
++ base = info->start[0];
++ offset = addr - base;
++ base = flash_make_addr (info, 0, 0);
++
++ enable_write (info);
++
++ ulCtrlData = (info->tCK_Write << 8);
++
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0x02);
++ udelay(10);
++ if (info->address32)
++ {
++ *(uchar *) (base) = (uchar) ((offset & 0xff000000) >> 24);
++ udelay(10);
++ }
++ *(uchar *) (base) = (uchar) ((offset & 0xff0000) >> 16);
++ udelay(10);
++ *(uchar *) (base) = (uchar) ((offset & 0x00ff00) >> 8);
++ udelay(10);
++ *(uchar *) (base) = (uchar) ((offset & 0x0000ff));
++ udelay(10);
++
++ for (j=0; j<len; j++)
++ {
++ *(uchar *) (base) = *(uchar *) (src++);
++ udelay(10);
++ }
++
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0x05);
++ udelay(10);
++ do {
++ jReg = *(volatile uchar *) (base);
++ } while ((jReg & 0x01));
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++ /* RFSR */
++ if (info->specificspi == SpecificSPI_N25Q512)
++ {
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0x70);
++ udelay(10);
++ do {
++ jReg = *(volatile uchar *) (base);
++ } while (!(jReg & 0x80));
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ }
++}
++
++/*-----------------------------------------------------------------------
++ *
++ * export functions
++ *
++ */
++
++/*-----------------------------------------------------------------------
++ *
++ */
++unsigned long flash_init (void)
++{
++ unsigned long size = 0;
++ int i;
++
++ /* Init: no FLASHes known */
++ for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
++ flash_info[i].flash_id = FLASH_UNKNOWN;
++ size += flash_info[i].size = flash_get_size (bank_base[i], i);
++ if (flash_info[i].flash_id == FLASH_UNKNOWN) {
++#ifndef CFG_FLASH_QUIET_TEST
++ printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
++ i, flash_info[i].size, flash_info[i].size << 20);
++#endif /* CFG_FLASH_QUIET_TEST */
++ }
++ }
++
++ /* Monitor protection ON by default */
++#if (CONFIG_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
++ flash_protect (FLAG_PROTECT_SET,
++ CONFIG_MONITOR_BASE,
++ CONFIG_MONITOR_BASE + monitor_flash_len - 1,
++ flash_get_info(CONFIG_MONITOR_BASE));
++#endif
++
++ /* Environment protection ON by default */
++#ifdef CONFIG_ENV_IS_IN_FLASH
++ flash_protect (FLAG_PROTECT_SET,
++ CONFIG_ENV_ADDR,
++ CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
++ flash_get_info(CONFIG_ENV_ADDR));
++#endif
++
++ /* Redundant environment protection ON by default */
++#ifdef CONFIG_ENV_ADDR_REDUND
++ flash_protect (FLAG_PROTECT_SET,
++ CONFIG_ENV_ADDR_REDUND,
++ CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SIZE_REDUND - 1,
++ flash_get_info(CONFIG_ENV_ADDR_REDUND));
++#endif
++ return (size);
++}
++
++/*-----------------------------------------------------------------------
++ */
++#if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || (CONFIG_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
++static flash_info_t *flash_get_info(ulong base)
++{
++ int i;
++ flash_info_t * info = 0;
++
++ for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i ++) {
++ info = & flash_info[i];
++ if (info->size && info->start[0] <= base &&
++ base <= info->start[0] + info->size - 1)
++ break;
++ }
++
++ return i == CONFIG_SYS_MAX_FLASH_BANKS ? 0 : info;
++}
++#endif
++
++/*-----------------------------------------------------------------------
++ */
++int flash_erase (flash_info_t * info, int s_first, int s_last)
++{
++ int rcode = 0;
++ int prot;
++ flash_sect_t sect;
++
++ ulong base, offset;
++ ulong ulSMMBase, ulCtrlData, CtrlOffset;
++ uchar jReg;
++
++ disable_cache();
++
++ if (info->CE == 2)
++ {
++ CtrlOffset = SPICtrlRegOffset2;
++ }
++ else
++ {
++ CtrlOffset = SPICtrlRegOffset;
++ }
++
++ if ((s_first < 0) || (s_first > s_last)) {
++ puts ("- no sectors to erase\n");
++ return 1;
++ }
++
++ prot = 0;
++ for (sect = s_first; sect <= s_last; ++sect) {
++ if (info->protect[sect]) {
++ prot++;
++ }
++ }
++ if (prot) {
++ printf ("- Warning: %d protected sectors will not be erased!\n", prot);
++ } else {
++ putc ('\n');
++ }
++
++ ulCtrlData = (info->tCK_Erase << 8);
++ for (sect = s_first; sect <= s_last; sect++) {
++ if (info->protect[sect] == 0) { /* not protected */
++ /* start erasing */
++ enable_write(info);
++
++ base = info->start[0];
++ offset = info->start[sect] - base;
++ base = flash_make_addr (info, 0, 0);
++
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0xd8);
++ udelay(10);
++ if (info->address32)
++ {
++ *(uchar *) (base) = (uchar) ((offset & 0xff000000) >> 24);
++ udelay(10);
++ }
++ *(uchar *) (base) = (uchar) ((offset & 0xff0000) >> 16);
++ udelay(10);
++ *(uchar *) (base) = (uchar) ((offset & 0x00ff00) >> 8);
++ udelay(10);
++ *(uchar *) (base) = (uchar) ((offset & 0x0000ff));
++ udelay(10);
++
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0x05);
++ udelay(10);
++ do {
++ jReg = *(volatile uchar *) (base);
++ } while ((jReg & 0x01));
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++
++ /* RFSR */
++ if (info->specificspi == SpecificSPI_N25Q512)
++ {
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_LOW | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ *(uchar *) (base) = (uchar) (0x70);
++ udelay(10);
++ do {
++ jReg = *(volatile uchar *) (base);
++ } while (!(jReg & 0x80));
++ ulCtrlData &= CMD_MASK;
++ ulCtrlData |= CE_HIGH | USERMODE;
++ *(ulong *) (STCBaseAddress + CtrlOffset) = ulCtrlData;
++ udelay(200);
++ }
++
++ putc ('.');
++ }
++ }
++ puts (" done\n");
++
++ reset_flash(info);
++
++ return rcode;
++}
++
++/*-----------------------------------------------------------------------
++ */
++void flash_print_info (flash_info_t * info)
++{
++ putc ('\n');
++ return;
++}
++
++/*-----------------------------------------------------------------------
++ * Copy memory to flash, returns:
++ * 0 - OK
++ * 1 - write timeout
++ * 2 - Flash not erased
++ */
++int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
++{
++ int count;
++ unsigned char pat[] = {'|', '-', '/', '\\'};
++ int patcnt;
++
++ disable_cache();
++
++ /* get lower aligned address */
++ if (addr & (info->buffersize - 1))
++ {
++ count = cnt >= info->buffersize ? (info->buffersize - (addr & 0xff)):cnt;
++ flash_write_buffer (info, src, addr, count);
++ addr+= count;
++ src += count;
++ cnt -= count;
++ }
++
++ /* prog */
++ while (cnt > 0) {
++ count = cnt >= info->buffersize ? info->buffersize:cnt;
++ flash_write_buffer (info, src, addr, count);
++ addr+= count;
++ src += count;
++ cnt -= count;
++ printf("%c\b", pat[(patcnt++) & 0x03]);
++ }
++
++ reset_flash(info);
++
++ return (0);
++}
++
++#ifdef CONFIG_FLASH_AST2300_DMA
++void * memmove_dma(void * dest,const void *src,size_t count)
++{
++ ulong count_align, poll_time, data;
++
++ count_align = (count + 3) & 0xFFFFFFFC; /* 4-bytes align */
++ poll_time = 100; /* set 100 us as default */
++
++ /* force end of burst read */
++ *(volatile ulong *) (STCBaseAddress + SPICtrlRegOffset) |= CE_HIGH;
++ *(volatile ulong *) (STCBaseAddress + SPICtrlRegOffset) &= ~CE_HIGH;
++
++ *(ulong *) (STCBaseAddress + REG_FLASH_DMA_CONTROL) = (ulong) (~FLASH_DMA_ENABLE);
++ *(ulong *) (STCBaseAddress + REG_FLASH_DMA_FLASH_BASE) = (ulong *) (src);
++ *(ulong *) (STCBaseAddress + REG_FLASH_DMA_DRAM_BASE) = (ulong *) (dest);
++ *(ulong *) (STCBaseAddress + REG_FLASH_DMA_LENGTH) = (ulong) (count_align);
++ *(ulong *) (STCBaseAddress + REG_FLASH_DMA_CONTROL) = (ulong) (FLASH_DMA_ENABLE);
++
++ /* wait poll */
++ do {
++ udelay(poll_time);
++ data = *(ulong *) (STCBaseAddress + REG_FLASH_INTERRUPT_STATUS);
++ } while (!(data & FLASH_STATUS_DMA_READY));
++
++ /* clear status */
++ *(ulong *) (STCBaseAddress + REG_FLASH_INTERRUPT_STATUS) |= FLASH_STATUS_DMA_CLEAR;
++}
++#endif
++#endif /* CONFIG_FLASH_SPI */
+diff --git a/board/aspeed/ast2400/hactest.c b/board/aspeed/ast2400/hactest.c
+new file mode 100755
+index 0000000..bfa87d5
+--- /dev/null
++++ b/board/aspeed/ast2400/hactest.c
+@@ -0,0 +1,762 @@
++/*
++ * 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
++ */
++
++/*
++ * Diagnostics support
++ */
++#include <common.h>
++#include <command.h>
++#include <post.h>
++#include "slt.h"
++
++#if ((CFG_CMD_SLT & CFG_CMD_HACTEST) && defined(CONFIG_SLT))
++#include "hactest.h"
++
++#include "aes.c"
++#include "rc4.c"
++
++static unsigned char crypto_src[CRYPTO_MAX_SRC], crypto_dst[CRYPTO_MAX_DST], crypto_context[CRYPTO_MAX_CONTEXT];
++static unsigned char hash_src[HASH_MAX_SRC], hash_dst[HASH_MAX_DST], hmac_key[HMAC_MAX_KEY];
++
++/*
++ * table
++ */
++static aes_test aestest[] = {
++ { CRYPTOMODE_ECB, 128,
++ {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, '\0'},
++ {0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34, '\0'},
++ {0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a, 0x0b, 0x32, '\0'} },
++ {0xFF, 0xFF, "", "", ""}, /* End Mark */
++};
++
++static rc4_test rc4test[] = {
++ {{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, '\0'},
++ {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, '\0'}},
++ {{0xff}, {0xff}}, /* End Mark */
++};
++
++static hash_test hashtest[] = {
++ {HASHMODE_SHA1, 20,
++ "abc",
++ {0x53, 0x20, 0xb0, 0x8c, 0xa1, 0xf5, 0x74, 0x62, 0x50, 0x71, 0x89, 0x41, 0xc5, 0x0a, 0xdf, 0x4e, 0xbb, 0x55, 0x76, 0x06, '\0'}},
++ {0xFF, 0xFF, "", ""}, /* End Mark */
++};
++
++static hmac_test hmactest[] = {
++ {HASHMODE_SHA1, 64, 20,
++ {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, '\0' },
++ "Sample #1",
++ {0xbf, 0x39, 0xda, 0xb1, 0x7d, 0xc2, 0xe1, 0x23, 0x0d, 0x28, 0x35, 0x3b, 0x8c, 0xcb, 0x14, 0xb6, 0x22, 0x02, 0x65, 0xb3, '\0'}},
++ {0xFF, 0xFF, 0xFF, "", "", ""}, /* End Mark */
++};
++
++void EnableHMAC(void)
++{
++ unsigned long ulData;
++
++ /* init SCU */
++ *(unsigned long *) (0x1e6e2000) = 0x1688a8a8;
++
++ ulData = *(volatile unsigned long *) (0x1e6e200c);
++ ulData &= 0xfdfff;
++ *(unsigned long *) (0x1e6e200c) = ulData;
++ udelay(100);
++ ulData = *(volatile unsigned long *) (0x1e6e2004);
++ ulData &= 0xfffef;
++ *(unsigned long *) (0x1e6e2004) = ulData;
++
++}
++
++/* AES */
++void aes_enc_ast3000(aes_context *ctx, uint8 *input, uint8 *iv, uint8 *output, uint32 ulMsgLength , uint32 ulAESMode)
++{
++
++ unsigned long i, ulTemp, ulCommand;
++ unsigned char ch;
++ unsigned char *pjsrc, *pjdst, *pjcontext;
++
++ ulCommand = CRYPTO_ENABLE_RW | CRYPTO_ENABLE_CONTEXT_LOAD | CRYPTO_ENABLE_CONTEXT_SAVE | \
++ CRYPTO_AES | CRYPTO_ENCRYPTO | CRYPTO_SYNC_MODE_ASYNC;
++
++ switch (ctx->nr)
++ {
++ case 10:
++ ulCommand |= CRYPTO_AES128;
++ break;
++ case 12:
++ ulCommand |= CRYPTO_AES192;
++ break;
++ case 14:
++ ulCommand |= CRYPTO_AES256;
++ break;
++ }
++
++ switch (ulAESMode)
++ {
++ case CRYPTOMODE_ECB:
++ ulCommand |= CRYPTO_AES_ECB;
++ break;
++ case CRYPTOMODE_CBC:
++ ulCommand |= CRYPTO_AES_CBC;
++ break;
++ case CRYPTOMODE_CFB:
++ ulCommand |= CRYPTO_AES_CFB;
++ break;
++ case CRYPTOMODE_OFB:
++ ulCommand |= CRYPTO_AES_OFB;
++ break;
++ case CRYPTOMODE_CTR:
++ ulCommand |= CRYPTO_AES_CTR;
++ break;
++ }
++
++ pjsrc = (unsigned char *) m16byteAlignment((unsigned long) crypto_src);
++ pjdst = (unsigned char *) m16byteAlignment((unsigned long) crypto_dst);
++ pjcontext = (unsigned char *) m16byteAlignment((unsigned long) crypto_context);
++
++ /* Init HW */
++ *(unsigned long *) (HAC_REG_BASE + REG_CRYPTO_SRC_BASE_OFFSET) = (unsigned long) pjsrc;
++ *(unsigned long *) (HAC_REG_BASE + REG_CRYPTO_DST_BASE_OFFSET) = (unsigned long) pjdst;
++ *(unsigned long *) (HAC_REG_BASE + REG_CRYPTO_CONTEXT_BASE_OFFSET) = (unsigned long) pjcontext;
++ *(unsigned long *) (HAC_REG_BASE + REG_CRYPTO_LEN_OFFSET) = ulMsgLength;
++
++ /* Set source */
++ for (i=0; i< ulMsgLength; i++)
++ {
++ ch = *(uint8 *)(input + i);
++ *(uint8 *) (pjsrc + i) = ch;
++ }
++
++ /* Set Context */
++ /* Set IV */
++ for (i=0; i<16; i++)
++ {
++ ch = *(uint8 *) (iv + i);
++ *(uint8 *) (pjcontext + i) = ch;
++ }
++
++ /* Set Expansion Key */
++ for (i=0; i<(4*(ctx->nr+1)); i++)
++ {
++ ulTemp = ((ctx->erk[i] & 0xFF) << 24) + ((ctx->erk[i] & 0xFF00) << 8) + ((ctx->erk[i] & 0xFF0000) >> 8) + ((ctx->erk[i] & 0xFF000000) >> 24);
++ *(uint32 *) (pjcontext + i*4 + 16) = ulTemp;
++ }
++
++ /* fire cmd */
++ *(unsigned long *) (HAC_REG_BASE + REG_CRYPTO_CMD_BASE_OFFSET) = ulCommand;
++ do {
++ ulTemp = *(volatile unsigned long *) (HAC_REG_BASE + REG_CRYPTO_STATUS_OFFSET);
++ } while (ulTemp & CRYPTO_BUSY);
++
++ /* Output */
++ for (i=0; i<ulMsgLength; i++)
++ {
++ ch = *(uint8 *) (pjdst + i);
++ *(uint8 *) (output + i) = ch;
++ }
++
++} /* aes_enc_ast3000 */
++
++
++void aes_dec_ast3000(aes_context *ctx, uint8 *input, uint8 *iv, uint8 *output, uint32 ulMsgLength , uint32 ulAESMode)
++{
++ unsigned long i, ulTemp, ulCommand;
++ unsigned char ch;
++ unsigned char *pjsrc, *pjdst, *pjcontext;
++
++ ulCommand = CRYPTO_ENABLE_RW | CRYPTO_ENABLE_CONTEXT_LOAD | CRYPTO_ENABLE_CONTEXT_SAVE | \
++ CRYPTO_AES | CRYPTO_DECRYPTO | CRYPTO_SYNC_MODE_ASYNC;
++
++ switch (ctx->nr)
++ {
++ case 10:
++ ulCommand |= CRYPTO_AES128;
++ break;
++ case 12:
++ ulCommand |= CRYPTO_AES192;
++ break;
++ case 14:
++ ulCommand |= CRYPTO_AES256;
++ break;
++ }
++
++ switch (ulAESMode)
++ {
++ case CRYPTOMODE_ECB:
++ ulCommand |= CRYPTO_AES_ECB;
++ break;
++ case CRYPTOMODE_CBC:
++ ulCommand |= CRYPTO_AES_CBC;
++ break;
++ case CRYPTOMODE_CFB:
++ ulCommand |= CRYPTO_AES_CFB;
++ break;
++ case CRYPTOMODE_OFB:
++ ulCommand |= CRYPTO_AES_OFB;
++ break;
++ case CRYPTOMODE_CTR:
++ ulCommand |= CRYPTO_AES_CTR;
++ break;
++ }
++
++ pjsrc = (unsigned char *) m16byteAlignment((unsigned long) crypto_src);
++ pjdst = (unsigned char *) m16byteAlignment((unsigned long) crypto_dst);
++ pjcontext = (unsigned char *) m16byteAlignment((unsigned long) crypto_context);
++
++ /* Init HW */
++ *(unsigned long *) (HAC_REG_BASE + REG_CRYPTO_SRC_BASE_OFFSET) = (unsigned long) pjsrc;
++ *(unsigned long *) (HAC_REG_BASE + REG_CRYPTO_DST_BASE_OFFSET) = (unsigned long) pjdst;
++ *(unsigned long *) (HAC_REG_BASE + REG_CRYPTO_CONTEXT_BASE_OFFSET) = (unsigned long) pjcontext;
++ *(unsigned long *) (HAC_REG_BASE + REG_CRYPTO_LEN_OFFSET) = ulMsgLength;
++
++ /* Set source */
++ for (i=0; i< ulMsgLength; i++)
++ {
++ ch = *(uint8 *)(input + i);
++ *(uint8 *) (pjsrc + i) = ch;
++ }
++
++ /* Set Context */
++ /* Set IV */
++ for (i=0; i<16; i++)
++ {
++ ch = *(uint8 *) (iv + i);
++ *(uint8 *) (pjcontext + i) = ch;
++ }
++
++ /* Set Expansion Key */
++ for (i=0; i<(4*(ctx->nr+1)); i++)
++ {
++ ulTemp = ((ctx->erk[i] & 0xFF) << 24) + ((ctx->erk[i] & 0xFF00) << 8) + ((ctx->erk[i] & 0xFF0000) >> 8) + ((ctx->erk[i] & 0xFF000000) >> 24);
++ *(uint32 *) (pjcontext + i*4 + 16) = ulTemp;
++ }
++
++ /* fire cmd */
++ *(unsigned long *) (HAC_REG_BASE + REG_CRYPTO_CMD_BASE_OFFSET) = ulCommand;
++ do {
++ ulTemp = *(volatile unsigned long *) (HAC_REG_BASE + REG_CRYPTO_STATUS_OFFSET);
++ } while (ulTemp & CRYPTO_BUSY);
++
++ /* Output */
++ for (i=0; i<ulMsgLength; i++)
++ {
++ ch = *(uint8 *) (pjdst + i);
++ *(uint8 *) (output + i) = ch;
++ }
++
++} /* aes_dec_ast3000 */
++
++void rc4_crypt_ast3000(uint8 *data, int ulMsgLength, uint8 *rc4_key, uint32 ulKeyLength)
++{
++ struct rc4_state s;
++ unsigned long i, ulTemp, ulCommand;
++ unsigned char ch;
++ unsigned char *pjsrc, *pjdst, *pjcontext;
++
++ ulCommand = CRYPTO_ENABLE_RW | CRYPTO_ENABLE_CONTEXT_LOAD | CRYPTO_ENABLE_CONTEXT_SAVE | \
++ CRYPTO_RC4 | CRYPTO_SYNC_MODE_ASYNC;
++
++ rc4_setup( &s, rc4_key, ulKeyLength );
++
++ pjsrc = (unsigned char *) m16byteAlignment((unsigned long) crypto_src);
++ pjdst = (unsigned char *) m16byteAlignment((unsigned long) crypto_dst);
++ pjcontext = (unsigned char *) m16byteAlignment((unsigned long) crypto_context);
++
++ /* Init HW */
++ *(uint32 *) (HAC_REG_BASE + REG_CRYPTO_SRC_BASE_OFFSET) = (unsigned long) pjsrc;
++ *(uint32 *) (HAC_REG_BASE + REG_CRYPTO_DST_BASE_OFFSET) = (unsigned long) pjdst;
++ *(uint32 *) (HAC_REG_BASE + REG_CRYPTO_CONTEXT_BASE_OFFSET) = (unsigned long) pjcontext;
++ *(uint32 *) (HAC_REG_BASE + REG_CRYPTO_LEN_OFFSET) = ulMsgLength;
++
++
++ /* Set source */
++ for (i=0; i< ulMsgLength; i++)
++ {
++ ch = *(uint8 *)(data + i);
++ *(uint8 *) (pjsrc + i) = ch;
++ }
++
++ /* Set Context */
++ /* Set i, j */
++ *(uint32 *) (pjcontext + 8) = 0x0001;
++
++ /* Set Expansion Key */
++ for (i=0; i<(256/4); i++)
++ {
++ ulTemp = (s.m[i * 4] & 0xFF) + ((s.m[i * 4 + 1] & 0xFF) << 8) + ((s.m[i * 4 + 2] & 0xFF) << 16) + ((s.m[i * 4+ 3] & 0xFF) << 24);
++ *(uint32 *) (pjcontext + i*4 + 16) = ulTemp;
++ }
++
++ /* fire cmd */
++ *(uint32 *) (HAC_REG_BASE + REG_CRYPTO_CMD_BASE_OFFSET) = ulCommand;
++ do {
++ ulTemp = *(volatile uint32 *) (HAC_REG_BASE + REG_CRYPTO_STATUS_OFFSET);
++ } while (ulTemp & CRYPTO_BUSY);
++
++ /* Output */
++ for (i=0; i<ulMsgLength; i++)
++ {
++ ch = *(volatile uint8 *) (pjdst + i);
++ *(uint8 *) (data + i) = ch;
++ }
++
++} /* rc4_crypt_ast3000 */
++
++/* Hash */
++void hash_ast3000(uint8 *msg, uint32 ulLength, unsigned char *output, uint32 ulHashMode)
++{
++ uint32 i, ulTemp, ulCommand, ulDigestLength, ulMyMsgLength;
++ uint8 ch;
++ unsigned char *pjsrc, *pjdst;
++
++ /* Get Info */
++ switch (ulHashMode)
++ {
++ case HASHMODE_MD5:
++ ulCommand = HASH_ALG_SELECT_MD5;
++ ulDigestLength = 16;
++ break;
++ case HASHMODE_SHA1:
++ ulCommand = HASH_ALG_SELECT_SHA1 | 0x08;
++ ulDigestLength = 20;
++ break;
++ case HASHMODE_SHA256:
++ ulCommand = HASH_ALG_SELECT_SHA256 | 0x08;
++ ulDigestLength = 32;
++ break;
++ case HASHMODE_SHA224:
++ ulCommand = HASH_ALG_SELECT_SHA224 | 0x08;
++ ulDigestLength = 28;
++ break;
++ }
++
++ pjsrc = (unsigned char *) m16byteAlignment((unsigned long) hash_src);
++ pjdst = (unsigned char *) m16byteAlignment((unsigned long) hash_dst);
++
++ /* 16byte alignment */
++ ulMyMsgLength = m16byteAlignment(ulLength);
++
++ /* Init. HW */
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_SRC_BASE_OFFSET) = (unsigned long) pjsrc;
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_DST_BASE_OFFSET) = (unsigned long) pjdst;
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_LEN_OFFSET) = ulMyMsgLength;
++
++ /* write src */
++ for (i=0; i<ulLength; i++)
++ {
++ ch = *(uint8 *)(msg+i);
++ *(uint8 *) (pjsrc + i) = ch;
++ }
++ for (i=ulLength; i<ulMyMsgLength; i++)
++ *(uint8 *) (pjsrc + i) = 0;
++
++ /* fire cmd */
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_CMD_OFFSET) = ulCommand;
++
++ /* get digest */
++ do {
++ ulTemp = *(volatile uint32 *) (HAC_REG_BASE + REG_HASH_STATUS_OFFSET);
++ } while (ulTemp & HASH_BUSY);
++
++ for (i=0; i<ulDigestLength; i++)
++ {
++ ch = *(volatile uint8 *) (pjdst + i);
++ *(uint8 *) (output + i) = ch;
++ }
++
++} /* hash_ast3000 */
++
++/* HMAC */
++void hmackey_ast3000(uint8 *key, uint32 ulKeyLength, uint32 ulHashMode)
++{
++ uint32 i, ulBlkLength, ulDigestLength, ulTemp, ulCommand;
++ uint8 k0[64], sum[32];
++ uint8 ch;
++ unsigned char *pjsrc, *pjdst, *pjkey;
++
++ /* Get Info */
++ switch (ulHashMode)
++ {
++ case HASHMODE_MD5:
++ ulCommand = HASH_ALG_SELECT_MD5;
++ ulDigestLength = 16;
++ break;
++ case HASHMODE_SHA1:
++ ulCommand = HASH_ALG_SELECT_SHA1 | 0x08;
++ ulDigestLength = 20;
++ break;
++ case HASHMODE_SHA256:
++ ulCommand = HASH_ALG_SELECT_SHA256 | 0x08;
++ ulDigestLength = 32;
++ break;
++ case HASHMODE_SHA224:
++ ulCommand = HASH_ALG_SELECT_SHA224 | 0x08;
++ ulDigestLength = 28;
++ break;
++ }
++ ulBlkLength = 64; /* MD5, SHA1/256/224: 64bytes */
++
++ /* Init */
++ memset( (void *) k0, 0, 64); /* reset to zero */
++ memset( (void *) sum, 0, 32); /* reset to zero */
++
++ /* Get k0 */
++ if (ulKeyLength <= ulBlkLength)
++ memcpy( (void *) k0, (void *) key, ulKeyLength );
++ else /* (ulKeyLength > ulBlkLength) */
++ {
++ hash_ast3000(key, ulKeyLength, sum, ulHashMode);
++ memcpy( (void *) k0, (void *) sum, ulDigestLength );
++ }
++
++ pjsrc = (unsigned char *) m16byteAlignment((unsigned long) hash_src);
++ pjdst = (unsigned char *) m16byteAlignment((unsigned long) hash_dst);
++ pjkey = (unsigned char *) m64byteAlignment((unsigned long) hmac_key);
++
++ /* Calculate digest */
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_SRC_BASE_OFFSET) = (unsigned long) pjsrc;
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_DST_BASE_OFFSET) = (unsigned long) pjdst;
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_KEY_BASE_OFFSET) = (unsigned long) pjkey;
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_LEN_OFFSET) = ulBlkLength;
++
++ /* write key to src */
++ for (i=0; i<ulBlkLength; i++)
++ {
++ ch = *(uint8 *)(k0+i);
++ *(uint8 *) (pjsrc + i) = ch;
++ }
++
++ /* fire cmd for calculate */
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_CMD_OFFSET) = ulCommand | HAC_DIGEST_CAL_ENABLE;
++ do {
++ ulTemp = *(volatile uint32 *) (HAC_REG_BASE + REG_HASH_STATUS_OFFSET);
++ } while (ulTemp & HASH_BUSY);
++
++} /* hmackey_ast3000 */
++
++void hmac_ast3000(uint8 *key, uint32 ulKeyLength, uint8 *msg, uint32 ulMsgLength, uint32 ulHashMode, unsigned char *output)
++{
++ uint32 i, ulTemp, ulCommand, ulDigestLength, ulMyMsgLength;;
++ uint8 ch;
++ unsigned char *pjsrc, *pjdst, *pjkey;
++
++ /* Calculate digest */
++ switch (ulHashMode)
++ {
++ case HASHMODE_MD5:
++ ulCommand = HASH_ALG_SELECT_MD5;
++ ulDigestLength = 16;
++ break;
++ case HASHMODE_SHA1:
++ ulCommand = HASH_ALG_SELECT_SHA1 | 0x08;
++ ulDigestLength = 20;
++ break;
++ case HASHMODE_SHA256:
++ ulCommand = HASH_ALG_SELECT_SHA256 | 0x08;
++ ulDigestLength = 32;
++ break;
++ case HASHMODE_SHA224:
++ ulCommand = HASH_ALG_SELECT_SHA224 | 0x08;
++ ulDigestLength = 28;
++ break;
++ }
++
++ pjsrc = (unsigned char *) m16byteAlignment((unsigned long) hash_src);
++ pjdst = (unsigned char *) m16byteAlignment((unsigned long) hash_dst);
++ pjkey = (unsigned char *) m64byteAlignment((unsigned long) hmac_key);
++
++ /* 16byte alignment */
++ ulMyMsgLength = m16byteAlignment(ulMsgLength);
++
++ /* Init. HW */
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_SRC_BASE_OFFSET) = (unsigned long) pjsrc;
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_DST_BASE_OFFSET) = (unsigned long) pjdst;
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_KEY_BASE_OFFSET) = (unsigned long) pjkey;
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_LEN_OFFSET) = ulMyMsgLength;
++
++ /* write Text to src */
++ for (i=0; i<ulMsgLength; i++)
++ {
++ ch = *(uint8 *)(msg+i);
++ *(uint8 *) (pjsrc + i) = ch;
++ }
++ for (i=ulMsgLength; i<ulMyMsgLength; i++)
++ *(uint8 *) (pjsrc + i) = 0;
++
++ /* fire cmd */
++ *(uint32 *) (HAC_REG_BASE + REG_HASH_CMD_OFFSET) = ulCommand | HAC_ENABLE;
++ do {
++ ulTemp = *(volatile uint32 *) (HAC_REG_BASE + REG_HASH_STATUS_OFFSET);
++ } while (ulTemp & HASH_BUSY);
++
++ /* Output Digest */
++ for (i=0; i<ulDigestLength; i++)
++ {
++ ch = *(uint8 *) (pjdst + i);
++ *(uint8 *) (output + i) = ch;
++ }
++
++} /* hmac_ast3000 */
++
++/* main hactest procedure */
++int do_hactest (void)
++{
++ unsigned long i, j, Flags = 0;
++ aes_test *pjaes_test;
++ aes_context aes_ctx;
++ unsigned char AES_Mode[8], aes_output[64];
++ unsigned long ulAESMsgLength;
++
++ rc4_test *pjrc4_test;
++ unsigned char rc4_buf_sw[64], rc4_buf_hw[64];
++ unsigned long ulRC4KeyLength, ulRC4MsgLength;
++
++ hash_test *pjhash_test;
++ unsigned char HASH_Mode[8], hash_out[64];
++
++ hmac_test *pjhmac_test;
++ unsigned char HMAC_Mode[8], hmac_out[64];
++
++ EnableHMAC();
++
++ /* AES Test */
++ pjaes_test = aestest;
++ while (pjaes_test->aes_mode != 0xFF)
++ {
++
++ if (pjaes_test->aes_mode == CRYPTOMODE_CBC)
++ strcpy (AES_Mode, "CBC");
++ else if (pjaes_test->aes_mode == CRYPTOMODE_CFB)
++ strcpy (AES_Mode, "CFB");
++ else if (pjaes_test->aes_mode == CRYPTOMODE_OFB)
++ strcpy (AES_Mode, "OFB");
++ else if (pjaes_test->aes_mode == CRYPTOMODE_CTR)
++ strcpy (AES_Mode, "CTR");
++ else
++ strcpy (AES_Mode, "ECB");
++
++ /* Get Msg. Length */
++ ulAESMsgLength = strlen(pjaes_test->plaintext);
++ j = ( (ulAESMsgLength + 15) >> 4) << 4;
++ for (i=ulAESMsgLength; i<j; i++)
++ pjaes_test->plaintext[i] = 0;
++ ulAESMsgLength = j;
++
++ aes_set_key(&aes_ctx, pjaes_test->key, pjaes_test->key_length);
++
++ /* Encryption Test */
++ aes_enc_ast3000(&aes_ctx, pjaes_test->plaintext, pjaes_test->key, aes_output, ulAESMsgLength, pjaes_test->aes_mode);
++ if (strncmp(aes_output, pjaes_test->ciphertext, ulAESMsgLength))
++ {
++ Flags |= FLAG_AESTEST_FAIL;
++ printf("[INFO] AES%d %s Mode Encryption Failed \n", pjaes_test->key_length, AES_Mode);
++ printf("[DBG] Golden Data Dump .... \n");
++ for (i=0; i< ulAESMsgLength; i++)
++ {
++ printf("%02x ", pjaes_test->ciphertext[i]);
++ if (((i+1) % 8) == 0)
++ printf("\n");
++ }
++ printf("\n [DBG] Error Data Dump .... \n");
++ for (i=0; i< ulAESMsgLength; i++)
++ {
++ printf("%02x ", aes_output[i]);
++ if (((i+1) % 8) == 0)
++ printf("\n");
++ }
++ printf("\n");
++ }
++ else
++ {
++ /*
++ printf("[INFO] AES%d %s Mode Encryption Passed \n", pjaes_test->key_length, AES_Mode);
++ */
++ }
++
++ /* Decryption Test */
++ aes_dec_ast3000(&aes_ctx, pjaes_test->ciphertext, pjaes_test->key, aes_output, ulAESMsgLength, pjaes_test->aes_mode);
++ if (strncmp(aes_output, pjaes_test->plaintext, ulAESMsgLength))
++ {
++ Flags |= FLAG_AESTEST_FAIL;
++ printf("[INFO] AES%d %s Mode Decryption Failed \n", pjaes_test->key_length, AES_Mode);
++ printf("[DBG] Golden Data Dump .... \n");
++ for (i=0; i< ulAESMsgLength; i++)
++ {
++ printf("%02x ", pjaes_test->plaintext[i]);
++ if (((i+1) % 8) == 0)
++ printf("\n");
++ }
++ printf("\n [DBG] Error Data Dump .... \n");
++ for (i=0; i< ulAESMsgLength; i++)
++ {
++ printf("%02x ", aes_output[i]);
++ if (((i+1) % 8) == 0)
++ printf("\n");
++ }
++ printf("\n");
++ }
++ else
++ {
++ /*
++ printf("[INFO] AES%d %s Mode Decryption Passed \n", pjaes_test->key_length, AES_Mode);
++ */
++ }
++
++ pjaes_test++;
++ } /* AES */
++
++ /* RC4 Test */
++ pjrc4_test = rc4test;
++ while ((pjrc4_test->key[0] != 0xff) && (pjrc4_test->data[0] != 0xff))
++ {
++
++ /* Get Info */
++ ulRC4KeyLength = strlen(pjrc4_test->key);
++ ulRC4MsgLength = strlen(pjrc4_test->data);
++ memcpy( (void *) rc4_buf_sw, (void *) pjrc4_test->data, ulRC4MsgLength );
++ memcpy( (void *) rc4_buf_hw, (void *) pjrc4_test->data, ulRC4MsgLength );
++
++ /* Crypto */
++ rc4_crypt_sw(rc4_buf_sw, ulRC4MsgLength, pjrc4_test->key, ulRC4KeyLength);
++ rc4_crypt_ast3000(rc4_buf_hw, ulRC4MsgLength, pjrc4_test->key, ulRC4KeyLength);
++
++ if (strncmp(rc4_buf_hw, rc4_buf_sw, ulRC4MsgLength))
++ {
++ Flags |= FLAG_RC4TEST_FAIL;
++ printf("[INFO] RC4 Encryption Failed \n");
++ printf("[DBG] Golden Data Dump .... \n");
++ for (i=0; i< ulRC4MsgLength; i++)
++ {
++ printf("%02x ", rc4_buf_sw[i]);
++ if (((i+1) % 8) == 0)
++ printf("\n");
++ }
++ printf("\n [DBG] Error Data Dump .... \n");
++ for (i=0; i< ulRC4MsgLength; i++)
++ {
++ printf("%02x ", rc4_buf_hw[i]);
++ if (((i+1) % 8) == 0)
++ printf("\n");
++ }
++ printf("\n");
++ }
++ else
++ {
++ /*
++ printf("[INFO] RC4 Encryption Passed \n");
++ */
++ }
++
++ pjrc4_test++;
++
++ } /* RC4 */
++
++ /* Hash Test */
++ pjhash_test = hashtest;
++ while (pjhash_test->hash_mode != 0xFF)
++ {
++
++ if (pjhash_test->hash_mode == HASHMODE_MD5)
++ strcpy (HASH_Mode, "MD5");
++ else if (pjhash_test->hash_mode == HASHMODE_SHA1)
++ strcpy (HASH_Mode, "SHA1");
++ else if (pjhash_test->hash_mode == HASHMODE_SHA256)
++ strcpy (HASH_Mode, "SHA256");
++ else if (pjhash_test->hash_mode == HASHMODE_SHA224)
++ strcpy (HASH_Mode, "SHA224");
++
++ /* Hash */
++ hash_ast3000(pjhash_test->input, strlen(pjhash_test->input), hash_out, pjhash_test->hash_mode);
++ if (strncmp(hash_out, pjhash_test->digest, pjhash_test->digest_length))
++ {
++ Flags |= FLAG_HASHTEST_FAIL;
++ printf("[INFO] HASH %s Failed \n", HASH_Mode);
++ printf("[DBG] Golden Data Dump .... \n");
++ for (i=0; i< pjhash_test->digest_length; i++)
++ {
++ printf("%02x ",pjhash_test->digest[i]);
++ if (((i+1) % 8) == 0)
++ printf("\n");
++ }
++ printf("\n [DBG] Error Data Dump .... \n");
++ for (i=0; i< pjhash_test->digest_length; i++)
++ {
++ printf("%02x ",hash_out[i]);
++ if (((i+1) % 8) == 0)
++ printf("\n");
++ }
++ printf("\n");
++ }
++ else
++ {
++ /*
++ printf("[INFO] HASH %s Passed \n", HASH_Mode);
++ */
++ }
++
++ pjhash_test++;
++
++ } /* Hash Test */
++
++ /* HMAC Test */
++ pjhmac_test = hmactest;
++ while (pjhmac_test->hash_mode != 0xFF)
++ {
++
++ if (pjhmac_test->hash_mode == HASHMODE_MD5)
++ strcpy (HMAC_Mode, "MD5");
++ else if (pjhmac_test->hash_mode == HASHMODE_SHA1)
++ strcpy (HMAC_Mode, "SHA1");
++ else if (pjhmac_test->hash_mode == HASHMODE_SHA256)
++ strcpy (HMAC_Mode, "SHA256");
++ else if (pjhmac_test->hash_mode == HASHMODE_SHA224)
++ strcpy (HMAC_Mode, "SHA224");
++
++ /* HMAC */
++ hmackey_ast3000(pjhmac_test->key, pjhmac_test->key_length, pjhmac_test->hash_mode);
++ hmac_ast3000(pjhmac_test->key, pjhmac_test->key_length, pjhmac_test->input, strlen(pjhmac_test->input), pjhmac_test->hash_mode, hmac_out);
++ if (strncmp(hmac_out, pjhmac_test->digest, pjhmac_test->digest_length))
++ {
++ Flags |= FLAG_HASHTEST_FAIL;
++ printf("[INFO] HMAC %s Failed \n", HMAC_Mode);
++ printf("[DBG] Golden Data Dump .... \n");
++ for (i=0; i< pjhmac_test->digest_length; i++)
++ {
++ printf("%02x ",pjhmac_test->digest[i]);
++ if (((i+1) % 8) == 0)
++ printf("\n");
++ }
++ printf("\n [DBG] Error Data Dump .... \n");
++ for (i=0; i< pjhmac_test->digest_length; i++)
++ {
++ printf("%02x ",hmac_out[i]);
++ if (((i+1) % 8) == 0)
++ printf("\n");
++ }
++ printf("\n");
++ }
++ else
++ {
++ /*
++ printf("[INFO] HMAC %s Passed \n", HMAC_Mode);
++ */
++ }
++
++ pjhmac_test++;
++
++ } /* HMAC Test */
++
++ return Flags;
++
++}
++
++#endif /* CONFIG_SLT */
+diff --git a/board/aspeed/ast2400/hactest.h b/board/aspeed/ast2400/hactest.h
+new file mode 100755
+index 0000000..fcf2186
+--- /dev/null
++++ b/board/aspeed/ast2400/hactest.h
+@@ -0,0 +1,194 @@
++/*
++ * 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
++ */
++/* Err Flags */
++#define FLAG_AESTEST_FAIL 0x00000001
++#define FLAG_RC4TEST_FAIL 0x00000002
++#define FLAG_HASHTEST_FAIL 0x00000004
++
++/* Specific */
++/*
++#define DRAM_BASE 0x40000000
++#define CRYPTO_SRC_BASE (DRAM_BASE + 0x100000)
++#define CRYPTO_DST_BASE (DRAM_BASE + 0x200000)
++#define CRYPTO_CONTEXT_BASE (DRAM_BASE + 0x300000)
++
++#define HASH_SRC_BASE (DRAM_BASE + 0x400000)
++#define HASH_DST_BASE (DRAM_BASE + 0x500000)
++#define HMAC_KEY_BASE (DRAM_BASE + 0x600000)
++*/
++#define m08byteAlignment(x) ((x + 0x00000007) & 0xFFFFFFF8)
++#define m16byteAlignment(x) ((x + 0x0000000F) & 0xFFFFFFF0)
++#define m64byteAlignment(x) ((x + 0x0000003F) & 0xFFFFFFC0)
++
++#define CRYPTO_ALIGNMENT 16
++#define CRYPTO_MAX_SRC (100+CRYPTO_ALIGNMENT)
++#define CRYPTO_MAX_DST (100+CRYPTO_ALIGNMENT)
++#define CRYPTO_MAX_CONTEXT (100+CRYPTO_ALIGNMENT)
++
++#define HASH_ALIGNMENT 16
++#define HMAC_KEY_ALIGNMENT 64
++#define HASH_MAX_SRC (100+HASH_ALIGNMENT)
++#define HASH_MAX_DST (32+HASH_ALIGNMENT)
++#define HMAC_MAX_KEY (64+HMAC_KEY_ALIGNMENT)
++
++/* General */
++#define HAC_REG_BASE 0x1e6e3000
++
++#define MAX_KEYLENGTH 100
++#define MAX_TEXTLENGTH 100
++#define MAX_AESTEXTLENGTH 256
++#define MAX_RC4TEXTLENGTH 256
++#define MAX_RC4KEYLENGTH 256
++
++#define CRYPTOMODE_ECB 0x00
++#define CRYPTOMODE_CBC 0x01
++#define CRYPTOMODE_CFB 0x02
++#define CRYPTOMODE_OFB 0x03
++#define CRYPTOMODE_CTR 0x04
++
++#define HASHMODE_MD5 0x00
++#define HASHMODE_SHA1 0x01
++#define HASHMODE_SHA256 0x02
++#define HASHMODE_SHA224 0x03
++
++#define MIXMODE_DISABLE 0x00
++#define MIXMODE_CRYPTO 0x02
++#define MIXMODE_HASH 0x03
++
++#define REG_CRYPTO_SRC_BASE_OFFSET 0x00
++#define REG_CRYPTO_DST_BASE_OFFSET 0x04
++#define REG_CRYPTO_CONTEXT_BASE_OFFSET 0x08
++#define REG_CRYPTO_LEN_OFFSET 0x0C
++#define REG_CRYPTO_CMD_BASE_OFFSET 0x10
++//#define REG_CRYPTO_ENABLE_OFFSET 0x14
++#define REG_CRYPTO_STATUS_OFFSET 0x1C
++
++#define REG_HASH_SRC_BASE_OFFSET 0x20
++#define REG_HASH_DST_BASE_OFFSET 0x24
++#define REG_HASH_KEY_BASE_OFFSET 0x28
++#define REG_HASH_LEN_OFFSET 0x2C
++#define REG_HASH_CMD_OFFSET 0x30
++//#define REG_HASH_ENABLE_OFFSET 0x14
++#define REG_HASH_STATUS_OFFSET 0x1C
++
++#define HASH_BUSY 0x01
++#define CRYPTO_BUSY 0x02
++
++//#define ENABLE_HASH 0x01
++//#define DISABLE_HASH 0x00
++//#define ENABLE_CRYPTO 0x02
++//#define DISABLE_CRYPTO 0x00
++
++#define CRYPTO_SYNC_MODE_MASK 0x03
++#define CRYPTO_SYNC_MODE_ASYNC 0x00
++#define CRYPTO_SYNC_MODE_PASSIVE 0x02
++#define CRYPTO_SYNC_MODE_ACTIVE 0x03
++
++#define CRYPTO_AES128 0x00
++#define CRYPTO_AES192 0x04
++#define CRYPTO_AES256 0x08
++
++#define CRYPTO_AES_ECB 0x00
++#define CRYPTO_AES_CBC 0x10
++#define CRYPTO_AES_CFB 0x20
++#define CRYPTO_AES_OFB 0x30
++#define CRYPTO_AES_CTR 0x40
++
++#define CRYPTO_ENCRYPTO 0x80
++#define CRYPTO_DECRYPTO 0x00
++
++#define CRYPTO_AES 0x000
++#define CRYPTO_RC4 0x100
++
++#define CRYPTO_ENABLE_RW 0x000
++#define CRYPTO_ENABLE_CONTEXT_LOAD 0x000
++#define CRYPTO_ENABLE_CONTEXT_SAVE 0x000
++
++#define HASH_SYNC_MODE_MASK 0x03
++#define HASH_SYNC_MODE_ASYNC 0x00
++#define HASH_SYNC_MODE_PASSIVE 0x02
++#define HASH_SYNC_MODE_ACTIVE 0x03
++
++#define HASH_READ_SWAP_ENABLE 0x04
++#define HMAC_SWAP_CONTROL_ENABLE 0x08
++
++#define HASH_ALG_SELECT_MASK 0x70
++#define HASH_ALG_SELECT_MD5 0x00
++#define HASH_ALG_SELECT_SHA1 0x20
++#define HASH_ALG_SELECT_SHA224 0x40
++#define HASH_ALG_SELECT_SHA256 0x50
++
++#define HAC_ENABLE 0x80
++#define HAC_DIGEST_CAL_ENABLE 0x180
++#define HASH_INT_ENABLE 0x200
++
++/* AES */
++#ifndef uint8
++#define uint8 unsigned char
++#endif
++
++#ifndef uint32
++#define uint32 unsigned long int
++#endif
++
++typedef struct
++{
++ uint32 erk[64]; /* encryption round keys */
++ uint32 drk[64]; /* decryption round keys */
++ int nr; /* number of rounds */
++}
++aes_context;
++
++typedef struct
++{
++ int aes_mode;
++ int key_length;
++
++ uint8 key[32]; /* as iv in CTR mode */
++ uint8 plaintext[64];
++ uint8 ciphertext[64];
++
++}
++aes_test;
++
++/* RC4 */
++typedef struct
++{
++ uint8 key[32];
++ uint8 data[64];
++}
++rc4_test;
++
++/* Hash */
++typedef struct
++{
++ int hash_mode;
++ int digest_length;
++
++ uint8 input[64];
++ uint8 digest[64];
++
++}
++hash_test;
++
++/* HMAC */
++typedef struct
++{
++ int hash_mode;
++ int key_length;
++ int digest_length;
++
++ uint8 key[100];
++ uint8 input[64];
++ uint8 digest[64];
++
++}
++hmac_test;
+diff --git a/board/aspeed/ast2400/mactest.c b/board/aspeed/ast2400/mactest.c
+new file mode 100755
+index 0000000..22054b9
+--- /dev/null
++++ b/board/aspeed/ast2400/mactest.c
+@@ -0,0 +1,510 @@
++/*
++ * 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
++ */
++/*
++ * (C) Copyright 2007 ASPEED Software
++ * MAC Manufacture Test in ASPEED's SDK version 0.20.01
++ *
++ * Release History
++ * 1. First Release, river@20071130
++ * 2. Fix the endless loop when PHY is not ready, river@20071204
++ *
++ * Test items:
++ * 1. Support MARVELL PHY only in this version
++ * 2. MDC/MDIO
++ * 3. GMAC/Duplex TX/RX Full_Size, Packet_Length Test
++ * 4. 100M/Duplex TX/RX Full_Size, Packet_Length Test
++ *
++ *
++ *
++*/
++
++
++/*
++* Diagnostics support
++*/
++#include <common.h>
++#include <command.h>
++#include <post.h>
++#include <malloc.h>
++#include <net.h>
++#include "slt.h"
++
++#if ((CFG_CMD_SLT & CFG_CMD_MACTEST) && defined(CONFIG_SLT))
++#include "mactest.h"
++
++static int INL(u_long base, u_long addr)
++{
++ return le32_to_cpu(*(volatile u_long *)(addr + base));
++}
++
++static void OUTL(u_long base, int command, u_long addr)
++{
++ *(volatile u_long *)(addr + base) = cpu_to_le32(command);
++}
++
++
++static void SCU_MAC1_Enable (u8 enable)
++{
++ unsigned int SCU_Register;
++
++ if(enable) {
++//MAC1 RESET/PHY_LINK in SCU
++ SCU_Register = INL(SCU_BASE, SCU_RESET_CONTROL_REG);
++ OUTL(SCU_BASE, SCU_Register & ~(0x800), SCU_RESET_CONTROL_REG);
++ } else {
++ SCU_Register = INL(SCU_BASE, SCU_RESET_CONTROL_REG);
++ OUTL(SCU_BASE, SCU_Register |(0x800), SCU_RESET_CONTROL_REG);
++
++}
++}
++
++/*------------------------------------------------------------
++ . Reads a register from the MII Management serial interface
++ .-------------------------------------------------------------*/
++static u16 phy_read_register (u8 PHY_Register, u8 PHY_Address)
++{
++ u32 Data, Status = 0, Loop_Count = 0, PHY_Ready = 1;
++ u16 Return_Data;
++
++ OUTL(MAC1_IO_BASE, (PHY_Register << 21) + (PHY_Address << 16) + MIIRD + MDC_CYCTHR, PHYCR_REG);
++ do {
++ Status = (INL (MAC1_IO_BASE, PHYCR_REG) & MIIRD);
++ Loop_Count++;
++ if (Loop_Count >= PHY_LOOP) {
++ PHY_Ready = 0;
++ break;
++ }
++ } while (Status == MIIRD);
++
++ if (PHY_Ready == 0) {
++ printf ("PHY NOT REDAY\n");
++ return 0;
++ }
++
++ udelay(5*1000);
++ Data = INL (MAC1_IO_BASE, PHYDATA_REG);
++ Return_Data = (Data >> 16);
++
++ return Return_Data;
++}
++
++static void phy_write_register (u8 PHY_Register, u8 PHY_Address, u16 PHY_Data)
++{
++ u32 Status = 0, Loop_Count = 0, PHY_Ready = 1;
++
++ OUTL(MAC1_IO_BASE, PHY_Data, PHYDATA_REG);
++ OUTL(MAC1_IO_BASE, (PHY_Register << 21) + (PHY_Address << 16) + MIIWR + MDC_CYCTHR, PHYCR_REG);
++ do {
++ Status = (INL (MAC1_IO_BASE, PHYCR_REG) & MIIWR);
++ Loop_Count++;
++ if (Loop_Count >= PHY_LOOP) {
++ PHY_Ready = 0;
++ break;
++ }
++ } while (Status == MIIWR);
++ if (PHY_Ready == 0) {
++ printf ("PHY NOT REDAY\n");
++ }
++}
++
++static int wait_link_resolve (void)
++{
++ int resolved_status, Loop_Count = 0, PHY_Ready = 1;
++
++ do {
++ resolved_status = (phy_read_register (0x11, 0) & (PHY_RESOLVED_bit | PHY_LINK_bit));
++ Loop_Count++;
++ if (Loop_Count >= PHY_LOOP) {
++ PHY_Ready = 0;
++ printf ("PHY NOT READY\n");
++ break;
++ }
++ } while (resolved_status != (PHY_RESOLVED_bit | PHY_LINK_bit));
++
++ return PHY_Ready;
++}
++
++static void set_phy_speed (int chip, int speed, int duplex)
++{
++ unsigned short data, status;
++
++
++ if (chip == PHYID_VENDOR_MARVELL) {
++ if ((speed == PHY_SPEED_1G) && (duplex == DUPLEX_FULL)) {
++//Manual Control
++ phy_write_register (18, 0, 0);
++ data = phy_read_register (9, 0);
++ phy_write_register (9, 0, data | 0x1800);
++//PHY Reset
++ phy_write_register (0, 0, 0x0140 | 0x8000);
++ do {
++ status = (phy_read_register (0, 0) & 0x8000);
++ } while (status != 0);
++
++//Force 1G
++ phy_write_register (29, 0, 0x07);
++ data = phy_read_register (30, 0);
++ phy_write_register (30, 0, data | 0x08);
++ phy_write_register (29, 0, 0x10);
++ data = phy_read_register (30, 0);
++ phy_write_register (30, 0, data | 0x02);
++ phy_write_register (29, 0, 0x12);
++ data = phy_read_register (30, 0);
++ phy_write_register (30, 0, data | 0x01);
++
++ printf ("FORCE MARVELL PHY to 1G/DUPLEX DONE\n");
++ }
++ else if ((speed == PHY_SPEED_100M) && (duplex == DUPLEX_FULL)) {
++//PHY Reset
++ phy_write_register (0, 0, 0x2100 | 0x8000);
++ do {
++ status = (phy_read_register (0, 0) & 0x8000);
++ } while (status != 0);
++
++//Force 100M
++ data = phy_read_register (0, 0);
++ phy_write_register (0, 0, data | 0x4000 | 0x8000);
++ do {
++ status = (phy_read_register (0, 0) & 0x8000);
++ } while (status != 0);
++ data = phy_read_register (0, 0);
++
++ printf ("FORCE MARVELL PHY to 100M/DUPLEX DONE\n");
++ }
++ }
++ else if ( (chip == PHYID_VENDOR_RTL8201E) || (chip == PHYID_VENDOR_BROADCOM) ){
++ /* basic setting */
++ data = phy_read_register (0, 0);
++ data &= 0x7140;
++ data |= 0x4000;
++ if (speed == PHY_SPEED_100M)
++ data |= 0x2000;
++ if (duplex == DUPLEX_FULL)
++ data |= 0x0100;
++ phy_write_register (0, 0, data);
++
++ /* reset */
++ phy_write_register (0, 0, data | 0x8000);
++ do {
++ status = (phy_read_register (0, 0) & 0x8000);
++ } while (status != 0);
++ udelay(100*1000);
++
++ /* basic setting */
++ phy_write_register (0, 0, data);
++
++ if (chip == PHYID_VENDOR_RTL8201E)
++ printf ("FORCE RTL8201E PHY to 100M/DUPLEX DONE\n");
++ else if (chip == PHYID_VENDOR_BROADCOM)
++ printf ("FORCE Broadcom PHY to 100M/DUPLEX DONE\n");
++
++ }
++
++}
++
++static void MAC1_reset (void)
++{
++ OUTL(MAC1_IO_BASE, SW_RST_bit, MACCR_REG);
++ for (; (INL(MAC1_IO_BASE, MACCR_REG ) & SW_RST_bit) != 0; ) {udelay(1000);}
++ OUTL(MAC1_IO_BASE, 0, IER_REG );
++}
++
++static int set_mac1_control_register (int Chip_ID)
++{
++ unsigned long MAC_CR_Register = 0;
++ int PHY_Ready = 1;
++ u16 PHY_Status, PHY_Speed, PHY_Duplex, Advertise, Link_Partner;
++
++ MAC_CR_Register = SPEED_100M_MODE_bit | RX_ALLADR_bit | FULLDUP_bit | RXMAC_EN_bit | RXDMA_EN_bit | TXMAC_EN_bit | TXDMA_EN_bit | CRC_APD_bit;
++
++ if ( (Chip_ID == PHYID_VENDOR_BROADCOM) || (Chip_ID == PHYID_VENDOR_RTL8201E)) {
++ Advertise = phy_read_register (0x04, 0);
++ Link_Partner = phy_read_register (0x05, 0);
++ Advertise = (Advertise & PHY_SPEED_DUPLEX_MASK);
++ Link_Partner = (Link_Partner & PHY_SPEED_DUPLEX_MASK);
++ if ((Advertise & Link_Partner) & PHY_100M_DUPLEX) {
++ MAC_CR_Register |= SPEED_100M_MODE_bit;
++ MAC_CR_Register |= FULLDUP_bit;
++ }
++ else if ((Advertise & Link_Partner) & PHY_100M_HALF) {
++ MAC_CR_Register |= SPEED_100M_MODE_bit;
++ MAC_CR_Register &= ~FULLDUP_bit;
++ }
++ else if ((Advertise & Link_Partner) & PHY_10M_DUPLEX) {
++ MAC_CR_Register &= ~SPEED_100M_MODE_bit;
++ MAC_CR_Register |= FULLDUP_bit;
++ }
++ else if ((Advertise & Link_Partner) & PHY_10M_HALF) {
++ MAC_CR_Register &= ~SPEED_100M_MODE_bit;
++ MAC_CR_Register &= ~FULLDUP_bit;
++ }
++ }
++ else if (Chip_ID == PHYID_VENDOR_MARVELL) {
++
++ PHY_Ready = wait_link_resolve ();
++
++ if (PHY_Ready == 1) {
++ PHY_Status = phy_read_register (0x11, 0);
++ PHY_Speed = (PHY_Status & PHY_SPEED_MASK) >> 14;
++ PHY_Duplex = (PHY_Status & PHY_DUPLEX_MASK) >> 13;
++
++ if (PHY_Speed == SPEED_1000M) {
++ MAC_CR_Register |= GMAC_MODE_bit;
++ }
++ else {
++ MAC_CR_Register &= ~GMAC_MODE_bit;
++ if (PHY_Speed == SPEED_10M) {
++ MAC_CR_Register &= ~SPEED_100M_MODE_bit;
++ }
++ }
++ if (PHY_Duplex == DUPLEX_HALF) {
++ MAC_CR_Register &= ~FULLDUP_bit;
++ }
++ }
++ }
++ OUTL(MAC1_IO_BASE, MAC_CR_Register, MACCR_REG);
++
++ return PHY_Ready;
++}
++
++static void ring_buffer_alloc (void)
++{
++ unsigned int i, j;
++
++//Write data into TX buffer
++ for (i = 0; i < NUM_TX; i++) {
++ for (j = 0; j < TX_BUFF_SZ; j++) {
++ tx_buffer[i][j] = i * 4 + j;
++ }
++ }
++//Initialize RX buffer to 0
++ for (i = 0; i < NUM_RX; i++) {
++ for (j = 0; j < RX_BUFF_SZ; j++) {
++ rx_buffer[i][j] = 0;
++ }
++ }
++//Prepare descriptor
++ for (i = 0; i < NUM_RX; i++) {
++ rx_ring[i].status = cpu_to_le32(RXPKT_RDY + RX_BUFF_SZ);
++ rx_ring[i].buf = ((u32) &rx_buffer[i]);
++ rx_ring[i].reserved = 0;
++ }
++ for (i = 0; i < NUM_TX; i++) {
++ tx_ring[i].status = 0;
++ tx_ring[i].des1 = 0;
++ tx_ring[i].buf = ((u32) &tx_buffer[i]);
++ tx_ring[i].reserved = 0;
++ }
++
++ rx_ring[NUM_RX - 1].status |= cpu_to_le32(EDORR);
++ tx_ring[NUM_TX - 1].status |= cpu_to_le32(EDOTR);
++
++ OUTL(MAC1_IO_BASE, ((u32) &tx_ring), TXR_BADR_REG);
++ OUTL(MAC1_IO_BASE, ((u32) &rx_ring), RXR_BADR_REG);
++
++ tx_new = 0;
++ rx_new = 0;
++}
++
++static int packet_test (void)
++{
++ unsigned int rx_status, length, i, Loop_Count = 0;
++
++ tx_ring[tx_new].status |= cpu_to_le32(LTS | FTS | TX_BUFF_SZ);
++ tx_ring[tx_new].status |= cpu_to_le32(TXDMA_OWN);
++ OUTL(MAC1_IO_BASE, POLL_DEMAND, TXPD_REG);
++
++//Compare result
++ do {
++ rx_status = rx_ring[rx_new].status;
++ Loop_Count++;
++ } while (!(rx_status & RXPKT_STATUS) && (Loop_Count < PHY_LOOP));
++ if (rx_status & (RX_ERR | CRC_ERR | FTL | RUNT | RX_ODD_NB)) {
++ /* There was an error.*/
++ printf("RX error status = 0x%08X\n", rx_status);
++ return PACKET_TEST_FAIL;
++ } else {
++ length = (rx_status & BYTE_COUNT_MASK);
++ for (i = 0; i < RX_BUFF_SZ / 4; i++) {
++ if (rx_buffer[rx_new][i] != tx_buffer[tx_new][i]) {
++ printf ("ERROR at packet %d, address %x\n", rx_new, i);
++ printf ("Gold = %8x, Real = %8x\n", tx_buffer[tx_new][i], rx_buffer[rx_new][i]);
++ return PACKET_TEST_FAIL;
++ }
++ }
++ }
++ tx_new = (tx_new + 1) % NUM_TX;
++ rx_new = (rx_new + 1) % NUM_RX;
++
++ return TEST_PASS;
++}
++
++static int packet_length_test (int packet_length)
++{
++ unsigned int rx_status, length, i, Loop_Count = 0;
++
++ tx_ring[tx_new].status &= (~(BYTE_COUNT_MASK));
++ tx_ring[tx_new].status |= cpu_to_le32(LTS | FTS | packet_length);
++ tx_ring[tx_new].status |= cpu_to_le32(TXDMA_OWN);
++ OUTL(MAC1_IO_BASE, POLL_DEMAND, TXPD_REG);
++
++//Compare result
++ do {
++ rx_status = rx_ring[rx_new].status;
++ Loop_Count++;
++ } while (!(rx_status & RXPKT_STATUS) && (Loop_Count < PHY_LOOP));
++ if (rx_status & (RX_ERR | CRC_ERR | FTL | RUNT | RX_ODD_NB)) {
++ /* There was an error.*/
++ printf("RX error status = 0x%08X\n", rx_status);
++ return PACKET_LENGTH_TEST_FAIL;
++ } else {
++ length = (rx_status & BYTE_COUNT_MASK) - 4;
++ if (length != packet_length) {
++ printf ("Received Length ERROR. Gold = %d, Fail = %d\n",packet_length, length);
++ printf ("rx_new = %d, tx_new = %d\n", rx_new, tx_new);
++ return PACKET_LENGTH_TEST_FAIL;
++ }
++ for (i = 0; i < length; i++) {
++ if (rx_buffer[rx_new][i] != tx_buffer[tx_new][i]) {
++ printf ("ERROR at packet %d, address %x\n", rx_new, i);
++ printf ("Gold = %8x, Real = %8x\n", tx_buffer[tx_new][i], rx_buffer[rx_new][i]);
++ return PACKET_LENGTH_TEST_FAIL;
++ }
++ }
++ }
++ rx_ring[rx_new].status &= (~(RXPKT_STATUS));
++ tx_new = (tx_new + 1) % NUM_TX;
++ rx_new = (rx_new + 1) % NUM_RX;
++
++ return TEST_PASS;
++}
++
++static int MAC1_init (int id)
++{
++ int phy_status = 0;
++
++ MAC1_reset ();
++ phy_status = set_mac1_control_register (id);
++ ring_buffer_alloc ();
++
++ return phy_status;
++}
++
++int do_mactest (void)
++{
++ unsigned int phy_id, i;
++ int test_result = 0, phy_status = 0;
++
++ SCU_MAC1_Enable(1);
++ phy_id = ((phy_read_register (0x02, 0) << 16) + phy_read_register (0x03, 0)) & PHYID_VENDOR_MASK;
++ if (phy_id == PHYID_VENDOR_MARVELL) {
++ printf ("PHY DETECTED ------> MARVELL\n");
++
++ set_phy_speed (phy_id, PHY_SPEED_1G, DUPLEX_FULL);
++ if ((phy_status = MAC1_init (phy_id)) != 0) {
++ for (i = 0; i < NUM_TX; i++) {
++ test_result |= packet_test ();
++ if (test_result != 0)
++ break;
++ }
++ }
++ else if (phy_status == 0) {
++ printf ("PHY FAIL: Please Check If you are using LOOP BACK Connector\n");
++ test_result = 3;
++ return test_result;
++ }
++ if ((phy_status = MAC1_init (phy_id)) != 0) {
++ for (i = 60; i < TX_BUFF_SZ; i++) {
++ test_result |= packet_length_test (i);
++ if (test_result != 0)
++ break;
++ }
++ }
++ else if (phy_status == 0) {
++ printf ("PHY FAIL: Please Check If you are using LOOP BACK Connector\n");
++ test_result = 3;
++ return test_result;
++ }
++ set_phy_speed (phy_id, PHY_SPEED_100M, DUPLEX_FULL);
++ if ((phy_status = MAC1_init (phy_id)) != 0) {
++ for (i = 0; i < NUM_TX; i++) {
++ test_result |= packet_test ();
++ if (test_result != 0)
++ break;
++ }
++ }
++ else if (phy_status == 0) {
++ printf ("PHY FAIL: Please Check If you are using LOOP BACK Connector\n");
++ test_result = 3;
++ return test_result;
++ }
++
++ if ((phy_status = MAC1_init (phy_id)) != 0) {
++ for (i = 60; i < TX_BUFF_SZ; i++) {
++ test_result |= packet_length_test (i);
++ if (test_result != 0)
++ break;
++ }
++ }
++ else if (phy_status == 0) {
++ printf ("PHY FAIL: Please Check If you are using LOOP BACK Connector\n");
++ test_result = 3;
++ return test_result;
++ }
++ }
++ else if ( (phy_id == PHYID_VENDOR_RTL8201E) || (phy_id == PHYID_VENDOR_BROADCOM) ){
++
++ if (phy_id == PHYID_VENDOR_RTL8201E)
++ printf ("PHY DETECTED ------> RTL 8201E \n");
++ else if (phy_id == PHYID_VENDOR_BROADCOM)
++ printf ("PHY DETECTED ------> Broadcom \n");
++
++ set_phy_speed (phy_id, PHY_SPEED_100M, DUPLEX_FULL);
++ if ((phy_status = MAC1_init (phy_id)) != 0) {
++ for (i = 0; i < NUM_TX; i++) {
++ test_result |= packet_test ();
++ if (test_result != 0)
++ break;
++ }
++ }
++ else if (phy_status == 0) {
++ printf ("PHY FAIL: Please Check If you are using LOOP BACK Connector\n");
++ test_result = 3;
++ return test_result;
++ }
++
++ if ((phy_status = MAC1_init (phy_id)) != 0) {
++ for (i = 60; i < TX_BUFF_SZ; i++) {
++ test_result |= packet_length_test (i);
++ if (test_result != 0)
++ break;
++ }
++ }
++ else if (phy_status == 0) {
++ printf ("PHY FAIL: Please Check If you are using LOOP BACK Connector\n");
++ test_result = 3;
++ return test_result;
++ }
++ }
++
++ if ((phy_status == 0) && (test_result & PACKET_TEST_FAIL)) {
++ printf ("Packet Test FAIL !\n");
++ }
++ else if ((phy_status == 0) && (test_result & PACKET_LENGTH_TEST_FAIL)) {
++ printf ("Packet Length Test FAIL !\n");
++ }
++
++ SCU_MAC1_Enable(0);
++ return test_result;
++
++}
++
++#endif /* CONFIG_SLT */
+diff --git a/board/aspeed/ast2400/mactest.h b/board/aspeed/ast2400/mactest.h
+new file mode 100755
+index 0000000..e75b7bb
+--- /dev/null
++++ b/board/aspeed/ast2400/mactest.h
+@@ -0,0 +1,215 @@
++/*
++ * 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
++ */
++/* MACTest.h */
++
++// --------------------------------------------------------------------
++// General Definition
++// --------------------------------------------------------------------
++#define MAC1_IO_BASE 0x1E660000
++#define PHY_LOOP 100000
++#define NUM_RX 48
++#define NUM_TX 48
++#define RX_BUFF_SZ 1514
++#define TX_BUFF_SZ 1514
++#define TOUT_LOOP 1000000
++#define ETH_ALEN 6
++#define POLL_DEMAND 1
++
++
++// --------------------------------------------------------------------
++// MAC Register Index
++// --------------------------------------------------------------------
++#define ISR_REG 0x00 // interrups status register
++#define IER_REG 0x04 // interrupt maks register
++#define MAC_MADR_REG 0x08 // MAC address (Most significant)
++#define MAC_LADR_REG 0x0c // MAC address (Least significant)
++#define MAHT0_REG 0x10 // Multicast Address Hash Table 0 register
++#define MAHT1_REG 0x14 // Multicast Address Hash Table 1 register
++#define TXPD_REG 0x18 // Transmit Poll Demand register
++#define RXPD_REG 0x1c // Receive Poll Demand register
++#define TXR_BADR_REG 0x20 // Transmit Ring Base Address register
++#define RXR_BADR_REG 0x24 // Receive Ring Base Address register
++#define HPTXPD_REG 0x28
++#define HPTXR_BADR_REG 0x2c
++#define ITC_REG 0x30 // interrupt timer control register
++#define APTC_REG 0x34 // Automatic Polling Timer control register
++#define DBLAC_REG 0x38 // DMA Burst Length and Arbitration control register
++#define DMAFIFOS_REG 0x3c
++#define FEAR_REG 0x44
++#define TPAFCR_REG 0x48
++#define RBSR_REG 0x4c
++#define MACCR_REG 0x50 // MAC control register
++#define MACSR_REG 0x54 // MAC status register
++#define PHYCR_REG 0x60 // PHY control register
++#define PHYDATA_REG 0x64 // PHY Write Data register
++
++// --------------------------------------------------------------------
++// PHYCR_REG
++// --------------------------------------------------------------------
++#define PHY_RE_AUTO_bit (1UL<<9)
++#define PHY_READ_bit (1UL<<26)
++#define PHY_WRITE_bit (1UL<<27)
++// --------------------------------------------------------------------
++// PHYCR_REG
++// --------------------------------------------------------------------
++#define PHY_AUTO_OK_bit (1UL<<5)
++// --------------------------------------------------------------------
++// PHY INT_STAT_REG
++// --------------------------------------------------------------------
++#define PHY_SPEED_CHG_bit (1UL<<14)
++#define PHY_DUPLEX_CHG_bit (1UL<<13)
++#define PHY_LINK_CHG_bit (1UL<<10)
++#define PHY_AUTO_COMP_bit (1UL<<11)
++// --------------------------------------------------------------------
++// PHY SPE_STAT_REG
++// --------------------------------------------------------------------
++#define PHY_RESOLVED_bit (1UL<<11)
++#define PHY_LINK_bit (1UL<<10)
++#define PHY_SPEED_mask 0xC000
++#define PHY_SPEED_10M 0x0
++#define PHY_SPEED_100M 0x1
++#define PHY_SPEED_1G 0x2
++#define PHY_DUPLEX_mask 0x2000
++#define PHY_SPEED_DUPLEX_MASK 0x01E0
++#define PHY_100M_DUPLEX 0x0100
++#define PHY_100M_HALF 0x0080
++#define PHY_10M_DUPLEX 0x0040
++#define PHY_10M_HALF 0x0020
++#define LINK_STATUS 0x04
++#define PHYID_VENDOR_MASK 0xfffffc00
++#define PHYID_VENDOR_MARVELL 0x01410c00
++#define PHYID_VENDOR_BROADCOM 0x00406000
++#define PHYID_VENDOR_RTL8201E 0x001cc800
++#define DUPLEX_FULL 0x01
++#define DUPLEX_HALF 0x00
++
++
++
++// --------------------------------------------------------------------
++// MACCR_REG
++// --------------------------------------------------------------------
++
++#define SW_RST_bit (1UL<<31) // software reset/
++#define DIRPATH_bit (1UL<<21)
++#define RX_IPCS_FAIL_bit (1UL<<20)
++#define SPEED_100M_MODE_bit (1UL<<19)
++#define RX_UDPCS_FAIL_bit (1UL<<18)
++#define RX_BROADPKT_bit (1UL<<17) // Receiving broadcast packet
++#define RX_MULTIPKT_bit (1UL<<16) // receiving multicast packet
++#define RX_HT_EN_bit (1UL<<15)
++#define RX_ALLADR_bit (1UL<<14) // not check incoming packet's destination address
++#define JUMBO_LF_bit (1UL<<13)
++#define RX_RUNT_bit (1UL<<12) // Store incoming packet even its length is les than 64 byte
++#define CRC_CHK_bit (1UL<<11)
++#define CRC_APD_bit (1UL<<10) // append crc to transmit packet
++#define GMAC_MODE_bit (1UL<<9)
++#define FULLDUP_bit (1UL<<8) // full duplex
++#define ENRX_IN_HALFTX_bit (1UL<<7)
++#define LOOP_EN_bit (1UL<<6) // Internal loop-back
++#define HPTXR_EN_bit (1UL<<5)
++#define REMOVE_VLAN_bit (1UL<<4)
++#define RXMAC_EN_bit (1UL<<3) // receiver enable
++#define TXMAC_EN_bit (1UL<<2) // transmitter enable
++#define RXDMA_EN_bit (1UL<<1) // enable DMA receiving channel
++#define TXDMA_EN_bit (1UL<<0) // enable DMA transmitting channel
++
++
++// --------------------------------------------------------------------
++// SCU_REG
++// --------------------------------------------------------------------
++#define SCU_BASE 0x1E6E2000
++#define SCU_PROTECT_KEY_REG 0x0
++#define SCU_PROT_KEY_MAGIC 0x1688a8a8
++#define SCU_RESET_CONTROL_REG 0x04
++#define SCU_RESET_MAC1 (1u << 11)
++#define SCU_RESET_MAC2 (1u << 12)
++#define SCU_HARDWARE_TRAPPING_REG 0x70
++#define SCU_HT_MAC_INTF_LSBIT 6
++#define SCU_HT_MAC_INTERFACE (0x7u << SCU_HT_MAC_INTF_LSBIT)
++#define MAC_INTF_SINGLE_PORT_MODES (1u<<0/*GMII*/ | 1u<<3/*MII_ONLY*/ | 1u<<4/*RMII_ONLY*/)
++#define SCU_HT_MAC_GMII 0x0u
++// MII and MII mode
++#define SCU_HT_MAC_MII_MII 0x1u
++#define SCU_HT_MAC_MII_ONLY 0x3u
++#define SCU_HT_MAC_RMII_ONLY 0x4u
++#define SCU_MULTIFUNCTION_PIN_REG 0x74
++#define SCU_MFP_MAC2_PHYLINK (1u << 26)
++#define SCU_MFP_MAC1_PHYLINK (1u << 25)
++#define SCU_MFP_MAC2_MII_INTF (1u << 21)
++#define SCU_MFP_MAC2_MDC_MDIO (1u << 20)
++#define SCU_SILICON_REVISION_REG 0x7C
++
++//---------------------------------------------------
++// PHY R/W Register Bit
++//---------------------------------------------------
++#define MIIWR (1UL<<27)
++#define MIIRD (1UL<<26)
++#define MDC_CYCTHR 0x34
++#define PHY_SPEED_MASK 0xC000
++#define PHY_DUPLEX_MASK 0x2000
++#define SPEED_1000M 0x02
++#define SPEED_100M 0x01
++#define SPEED_10M 0x00
++#define DUPLEX_FULL 0x01
++#define DUPLEX_HALF 0x00
++#define RESOLVED_BIT 0x800
++
++#define PHY_SPEED_DUPLEX_MASK 0x01E0
++#define PHY_100M_DUPLEX 0x0100
++#define PHY_100M_HALF 0x0080
++#define PHY_10M_DUPLEX 0x0040
++#define PHY_10M_HALF 0x0020
++
++//---------------------------------------------------
++// Descriptor bits.
++//---------------------------------------------------
++#define TXDMA_OWN 0x80000000 /* Own Bit */
++#define RXPKT_RDY 0x00000000
++#define RXPKT_STATUS 0x80000000
++#define EDORR 0x40000000 /* Receive End Of Ring */
++#define LRS 0x10000000 /* Last Descriptor */
++#define RD_ES 0x00008000 /* Error Summary */
++#define EDOTR 0x40000000 /* Transmit End Of Ring */
++#define T_OWN 0x80000000 /* Own Bit */
++#define LTS 0x10000000 /* Last Segment */
++#define FTS 0x20000000 /* First Segment */
++#define CRC_ERR 0x00080000
++#define TD_ES 0x00008000 /* Error Summary */
++#define TD_SET 0x08000000 /* Setup Packet */
++#define RX_ERR 0x00040000
++#define FTL 0x00100000
++#define RUNT 0x00200000
++#define RX_ODD_NB 0x00400000
++#define BYTE_COUNT_MASK 0x00003FFF
++
++//---------------------------------------------------
++// SPEED/DUPLEX Parameters
++//---------------------------------------------------
++
++//---------------------------------------------------
++// Return Status
++//---------------------------------------------------
++#define TEST_PASS 0
++#define PACKET_TEST_FAIL 1
++#define PACKET_LENGTH_TEST_FAIL 2
++
++struct mac_desc {
++ volatile s32 status;
++ u32 des1;
++ u32 reserved;
++ u32 buf;
++};
++static struct mac_desc rx_ring[NUM_RX] __attribute__ ((aligned(32))); /* RX descriptor ring */
++static struct mac_desc tx_ring[NUM_TX] __attribute__ ((aligned(32))); /* TX descriptor ring */
++static int rx_new; /* RX descriptor ring pointer */
++static int tx_new; /* TX descriptor ring pointer */
++static volatile unsigned char rx_buffer[NUM_RX][RX_BUFF_SZ] __attribute__ ((aligned(32))); /* RX buffer */
++static volatile unsigned char tx_buffer[NUM_TX][TX_BUFF_SZ] __attribute__ ((aligned(32))); /* TX buffer */
+diff --git a/board/aspeed/ast2400/mictest.c b/board/aspeed/ast2400/mictest.c
+new file mode 100755
+index 0000000..1b2b342
+--- /dev/null
++++ b/board/aspeed/ast2400/mictest.c
+@@ -0,0 +1,146 @@
++/*
++ * 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
++ */
++
++/*
++ * Diagnostics support
++ */
++#include <common.h>
++#include <command.h>
++#include <post.h>
++#include "slt.h"
++
++#if ((CFG_CMD_SLT & CFG_CMD_MICTEST) && defined(CONFIG_SLT))
++#include "mictest.h"
++
++static unsigned char ctrlbuf[MIC_MAX_CTRL];
++static unsigned char chksumbuf[MIC_MAX_CHKSUM];
++
++void vInitSCU(void)
++{
++ unsigned long ulData;
++
++ *(unsigned long *) (0x1e6e2000) = 0x1688A8A8;
++
++ udelay(100);
++
++ ulData = *(unsigned long *) (0x1e6e2004);
++ ulData &= 0xbffff;
++ *(unsigned long *) (0x1e6e2004) = ulData;
++
++}
++
++void vInitMIC(void)
++{
++ unsigned long i, j, ulPageNumber;
++ unsigned char *pjctrl, *pjsum;
++
++ ulPageNumber = DRAMSIZE >> 12;
++
++ pjctrl = (unsigned char *)(m16byteAlignment((unsigned long) ctrlbuf));
++ pjsum = (unsigned char *)(m16byteAlignment((unsigned long) chksumbuf));
++
++ /* init ctrl buffer (2bits for one page) */
++ for (i=0; i< (ulPageNumber/4); i++)
++ *(unsigned char *) (pjctrl + i) = DEFAULT_CTRL;
++
++ /* init chksum buf (4bytes for one page) */
++ for (i=0; i<ulPageNumber; i++)
++ *(unsigned long *) (pjsum + i*4) = DEFAULT_CHKSUM;
++
++ *(unsigned long *) (MIC_BASE + MIC_CTRLBUFF_REG) = (unsigned long) pjctrl;
++ *(unsigned long *) (MIC_BASE + MIC_CHKSUMBUF_REG) = (unsigned long) pjsum;
++ *(unsigned long *) (MIC_BASE + MIC_RATECTRL_REG) = (unsigned long) DEFAULT_RATE;
++ *(unsigned long *) (MIC_BASE + MIC_ENGINECTRL_REG) = MIC_ENABLE_MIC | (DRAMSIZE - 0x1000);
++
++}
++
++void vDisableMIC(void)
++{
++ *(unsigned long *) (MIC_BASE + MIC_ENGINECTRL_REG) = MIC_RESET_MIC;
++
++}
++
++int do_chksum(void)
++{
++ unsigned long i, j, k, ulPageNumber;
++ int Status = 0;
++ unsigned short tmp;
++ volatile unsigned long sum1, sum2;
++ unsigned long goldensum, chksum;
++ unsigned long len, tlen;
++ unsigned char *pjsum;
++
++ ulPageNumber = DRAMSIZE >> 12;
++ pjsum = (unsigned char *)(m16byteAlignment((unsigned long) chksumbuf));
++
++ /* start test */
++ for (i=0; i<ulPageNumber; i++)
++ {
++
++ sum1 = 0xffff, sum2 = 0xffff;
++ len = 0x0800;
++ j = 0;
++
++ while (len)
++ {
++ tlen = len > 360 ? 360 : len;
++ len -= tlen;
++ do {
++ tmp = *(unsigned short *) (DRAM_BASE + ((i << 12) + j));
++ sum1 += (unsigned long) tmp;
++ sum2 += sum1;
++ j+=2;
++ } while (--tlen);
++ sum1 = (sum1 & 0xffff) + (sum1 >> 16);
++ sum2 = (sum2 & 0xffff) + (sum2 >> 16);
++ }
++
++ sum1 = (sum1 & 0xffff) + (sum1 >> 16);
++ sum2 = (sum2 & 0xffff) + (sum2 >> 16);
++
++ goldensum = (sum2 << 16) | sum1;
++ k= 0;
++ do {
++ chksum = *(unsigned long *) (pjsum + i*4);
++ udelay(100);
++ k++;
++ } while ((chksum == 0) && (k<1000));
++
++ if (chksum != goldensum)
++ {
++ Status = 1;
++ printf("[FAIL] MIC Chksum Failed at Page %x \n", i);
++ }
++
++ } /* end of i loop */
++
++ return (Status);
++
++}
++
++int do_mictest (void)
++{
++ unsigned long Flags = 0;
++
++ vInitSCU();
++ vInitMIC();
++
++ if (do_chksum())
++ Flags = 1;
++
++ vDisableMIC();
++
++ return Flags;
++
++}
++
++#endif /* CONFIG_SLT */
+diff --git a/board/aspeed/ast2400/mictest.h b/board/aspeed/ast2400/mictest.h
+new file mode 100755
+index 0000000..e14bb41
+--- /dev/null
++++ b/board/aspeed/ast2400/mictest.h
+@@ -0,0 +1,55 @@
++/*
++ * 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
++ */
++/* Macro */
++#define m08byteAlignment(x) ((x + 0x00000007) & 0xFFFFFFF8)
++#define m16byteAlignment(x) ((x + 0x0000000F) & 0xFFFFFFF0)
++#define m64byteAlignment(x) ((x + 0x0000003F) & 0xFFFFFFC0)
++
++/* Options */
++#define MIC_TEST_PAGE 32
++#define DRAMSIZE (MIC_TEST_PAGE * 0x1000)
++#define MIC_MAX_CTRL (MIC_TEST_PAGE / 4 + 16)
++#define MIC_MAX_CHKSUM (MIC_TEST_PAGE * 4 + 16)
++
++/* Default Setting */
++#define DEFAULT_RATE 0x00000000
++#define DEFAULT_CTRL 0xFF
++#define DEFAULT_CHKSUM 0x00000000
++#define DEFAULT_WRITEBACK 0x08880000
++
++/* Reg. Definition */
++#define DRAM_BASE 0x40000000
++#define MIC_BASE 0x1e640000
++#define MIC_CTRLBUFF_REG 0x00
++#define MIC_CHKSUMBUF_REG 0x04
++#define MIC_RATECTRL_REG 0x08
++#define MIC_ENGINECTRL_REG 0x0C
++#define MIC_STOPPAGE_REG 0x10
++#define MIC_STATUS_REG 0x14
++#define MIC_STATUS1_REG 0x18
++#define MIC_STATUS2_REG 0x1C
++
++#define MIC_RESET_MIC 0x00000000
++#define MIC_ENABLE_MIC 0x10000000
++#define MIC_MAXPAGE_MASK 0x0FFFF000
++#define MIC_WRITEBACK_MASK 0xFFFF0000
++#define MIC_STOPPAGE_MASK 0x0000FFFF
++#define MIC_PAGEERROR 0x40000000
++#define MIC_PAGE1ERROR 0x10000000
++#define MIC_PAGE2ERROR 0x20000000
++#define MIC_INTMASK 0x00060000
++#define MIC_ERRPAGENO_MASK 0x0000FFFF
++
++#define MIC_CTRL_MASK 0x03
++#define MIC_CTRL_SKIP 0x00
++#define MIC_CTRL_CHK1 0x01
++#define MIC_CTRL_CHK2 0x02
++#define MIC_CTRL_CHK3 0x03
+diff --git a/board/aspeed/ast2400/pci.c b/board/aspeed/ast2400/pci.c
+new file mode 100755
+index 0000000..5b17466
+--- /dev/null
++++ b/board/aspeed/ast2400/pci.c
+@@ -0,0 +1,243 @@
++/*
++ * 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, or (at
++ * your option) any later version.
++ */
++
++#include <common.h>
++#include <pci.h>
++
++#ifdef CONFIG_PCI
++
++#define PCI_CSR_BASE 0x60000000
++#define ASPEED_PCI_IO_BASE 0x00000000
++#define ASPEED_PCI_IO_SIZE 0x00010000
++#define ASPEED_PCI_MEM_BASE 0x68000000
++#define ASPEED_PCI_MEM_SIZE 0x18000000
++
++#define CSR_CRP_CMD_OFFSET 0x00
++#define CSR_CRP_WRITE_OFFSET 0x04
++#define CSR_CRP_READ_OFFSET 0x08
++#define CSR_PCI_ADDR_OFFSET 0x0C
++#define CSR_PCI_CMD_OFFSET 0x10
++#define CSR_PCI_WRITE_OFFSET 0x14
++#define CSR_PCI_READ_OFFSET 0x18
++#define CSR_PCI_STATUS_OFFSET 0x1C
++
++#define CRP_ADDR_REG (volatile ulong*) (PCI_CSR_BASE + CSR_CRP_CMD_OFFSET)
++#define CRP_WRITE_REG (volatile ulong*) (PCI_CSR_BASE + CSR_CRP_WRITE_OFFSET)
++#define CRP_READ_REG (volatile ulong*) (PCI_CSR_BASE + CSR_CRP_READ_OFFSET)
++#define PCI_ADDR_REG (volatile ulong*) (PCI_CSR_BASE + CSR_PCI_ADDR_OFFSET)
++#define PCI_CMD_REG (volatile ulong*) (PCI_CSR_BASE + CSR_PCI_CMD_OFFSET)
++#define PCI_WRITE_REG (volatile ulong*) (PCI_CSR_BASE + CSR_PCI_WRITE_OFFSET)
++#define PCI_READ_REG (volatile ulong*) (PCI_CSR_BASE + CSR_PCI_READ_OFFSET)
++
++#define PCI_CMD_READ 0x0A
++#define PCI_CMD_WRITE 0x0B
++
++#define RESET_PCI_STATUS *(volatile ulong*) (PCI_CSR_BASE + CSR_PCI_STATUS_OFFSET) = 0x01
++#define CHK_PCI_STATUS (*(volatile ulong*) (PCI_CSR_BASE + CSR_PCI_STATUS_OFFSET) & 0x03)
++
++static int pci_config_access (u8 access_type, u32 dev, u32 reg, u32 * data)
++{
++ u32 bus;
++ u32 device;
++ u32 function;
++
++ bus = ((dev & 0xff0000) >> 16);
++ device = ((dev & 0xf800) >> 11);
++ function = (dev & 0x0700);
++
++ if (bus == 0) {
++ // Type 0 Configuration
++ *PCI_ADDR_REG = (u32) (1UL << device | function | (reg & 0xfc));
++ } else {
++ // Type 1 Configuration
++ *PCI_ADDR_REG = (u32) (dev | ((reg / 4) << 2) | 1);
++ }
++
++ RESET_PCI_STATUS;
++
++ if (access_type == PCI_CMD_WRITE) {
++ *PCI_CMD_REG = (ulong) PCI_CMD_WRITE;
++ *PCI_WRITE_REG = *data;
++ } else {
++ *PCI_CMD_REG = (ulong) PCI_CMD_READ;
++ *data = *PCI_READ_REG;
++ }
++
++ return (CHK_PCI_STATUS);
++}
++
++static int aspeed_pci_read_config_byte (u32 hose, u32 dev, u32 reg, u8 * val)
++{
++ u32 data;
++
++ if (pci_config_access (PCI_CMD_READ, dev, reg, &data)) {
++ *val = 0;
++ return -1;
++ }
++
++ *val = (data >> ((reg & 3) << 3)) & 0xff;
++
++ return 0;
++}
++
++
++static int aspeed_pci_read_config_word (u32 hose, u32 dev, u32 reg, u16 * val)
++{
++ u32 data;
++
++ if (reg & 1)
++ return -1;
++
++ if (pci_config_access (PCI_CMD_READ, dev, reg, &data)) {
++ *val = 0;
++ return -1;
++ }
++
++ *val = (data >> ((reg & 3) << 3)) & 0xffff;
++
++ return 0;
++}
++
++
++static int aspeed_pci_read_config_dword (u32 hose, u32 dev, u32 reg,
++ u32 * val)
++{
++ u32 data = 0;
++
++ if (reg & 3)
++ return -1;
++
++ if (pci_config_access (PCI_CMD_READ, dev, reg, &data)) {
++ *val = 0;
++ return -1;
++ }
++
++ *val = data;
++
++ return (0);
++}
++
++static int aspeed_pci_write_config_byte (u32 hose, u32 dev, u32 reg, u8 val)
++{
++ u32 data = 0;
++
++ if (pci_config_access (PCI_CMD_READ, dev, reg, &data))
++ return -1;
++
++ data = (data & ~(0xff << ((reg & 3) << 3))) | (val <<
++ ((reg & 3) << 3));
++
++ if (pci_config_access (PCI_CMD_WRITE, dev, reg, &data))
++ return -1;
++
++ return 0;
++}
++
++
++static int aspeed_pci_write_config_word (u32 hose, u32 dev, u32 reg, u16 val)
++{
++ u32 data = 0;
++
++ if (reg & 1)
++ return -1;
++
++ if (pci_config_access (PCI_CMD_READ, dev, reg, &data))
++ return -1;
++
++ data = (data & ~(0xffff << ((reg & 3) << 3))) | (val <<
++ ((reg & 3) << 3));
++
++ if (pci_config_access (PCI_CMD_WRITE, dev, reg, &data))
++ return -1;
++
++ return 0;
++}
++
++static int aspeed_pci_write_config_dword (u32 hose, u32 dev, u32 reg, u32 val)
++{
++ u32 data;
++
++ if (reg & 3) {
++ return -1;
++ }
++
++ data = val;
++
++ if (pci_config_access (PCI_CMD_WRITE, dev, reg, &data))
++ return -1;
++
++ return (0);
++}
++
++/*
++ * Initialize PCIU
++ */
++aspeed_pciu_init ()
++{
++
++ unsigned long reg;
++
++ /* Reset PCI Host */
++ reg = *((volatile ulong*) 0x1e6e2004);
++ *((volatile ulong*) 0x1e6e2004) = reg | 0x00280000;
++
++ reg = *((volatile ulong*) 0x1e6e2074); /* REQ2 */
++ *((volatile ulong*) 0x1e6e2074) = reg | 0x00000010;
++
++ *((volatile ulong*) 0x1e6e2008) |= 0x00080000;
++ reg = *((volatile ulong*) 0x1e6e200c);
++ *((volatile ulong*) 0x1e6e200c) = reg & 0xfff7ffff;
++ udelay(1);
++ *((volatile ulong*) 0x1e6e2004) &= 0xfff7ffff;
++
++ /* Initial PCI Host */
++ RESET_PCI_STATUS;
++
++ *CRP_ADDR_REG = ((ulong)(PCI_CMD_READ) << 16) | 0x04;
++ reg = *CRP_READ_REG;
++
++ *CRP_ADDR_REG = ((ulong)(PCI_CMD_WRITE) << 16) | 0x04;
++ *CRP_WRITE_REG = reg | 0x07;
++
++}
++
++/*
++ * Initialize Module
++ */
++
++void aspeed_init_pci (struct pci_controller *hose)
++{
++ hose->first_busno = 0;
++ hose->last_busno = 0xff;
++
++ aspeed_pciu_init (); /* Initialize PCIU */
++
++ /* PCI memory space #1 */
++ pci_set_region (hose->regions + 0,
++ ASPEED_PCI_MEM_BASE, ASPEED_PCI_MEM_BASE, ASPEED_PCI_MEM_SIZE, PCI_REGION_MEM);
++
++ /* PCI I/O space */
++ pci_set_region (hose->regions + 1,
++ ASPEED_PCI_IO_BASE, ASPEED_PCI_IO_BASE, ASPEED_PCI_IO_SIZE, PCI_REGION_IO);
++
++ hose->region_count = 2;
++
++ hose->read_byte = aspeed_pci_read_config_byte;
++ hose->read_word = aspeed_pci_read_config_word;
++ hose->read_dword = aspeed_pci_read_config_dword;
++ hose->write_byte = aspeed_pci_write_config_byte;
++ hose->write_word = aspeed_pci_write_config_word;
++ hose->write_dword = aspeed_pci_write_config_dword;
++
++ pci_register_hose (hose);
++
++ hose->last_busno = pci_hose_scan (hose);
++
++ return;
++}
++#endif /* CONFIG_PCI */
++
+diff --git a/board/aspeed/ast2400/platform.S b/board/aspeed/ast2400/platform.S
+new file mode 100644
+index 0000000..27e8f26
+--- /dev/null
++++ b/board/aspeed/ast2400/platform.S
+@@ -0,0 +1,3089 @@
++/*
++ * 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
++ */
++/*
++ * Board specific setup info
++ *
++ ******************************************************************************
++ * ASPEED Technology Inc.
++ * AST2300/AST2400 DDR2/DDR3 SDRAM controller initialization and calibration sequence
++ *
++ * Gary Hsu, <gary_hsu@aspeedtech.com>
++ *
++ * Release date: 2014.12.29 formal release for SDK0.60
++ *
++ * Modified list from v0.23
++ * EC1. Modify DQIDLY and DQSI-MCLK2X calibration algorithm
++ * EC2. Remove pass 2 DQIDLY finetune process
++ * EC3. Modify ECC code
++ * EC4. Add AST2400 supporting
++ * EC5. Add SPI timing calibration for AST2400
++ * EC6. Remove AST2300-A0 PCI-e workaround
++ * EC7. Add CK duty calibration for AST2400
++ * EC8. Remove #define CONFIG_DRAM_UART_OUT, default has message output to UART5
++ * EC9. Add DRAM size auto-detection
++ * EC10. Add GPIO register clear when watchdog reboot (only for AST2400)
++ * EC11. Move the "Solve ASPM" code position of AST2300 to avoid watchdog reset
++ *
++ * Modified list from v0.53
++ * EC1. Add solution of LPC lock issue due to watchdog reset. (AP note A2300-11)
++ *
++ * Modified list from v0.56
++ * EC1. Fix read DQS input mask window too late issue if DRAM's t_DQSCK is earlier too much
++ * (ex. Nanya NT5CB64M16FP)
++ * 1. Change init value of MCR18[4] from '1' to '0'
++ * 2. Add CBR4 code to finetune MCR18[4]
++ *
++ * Modified list from v0.59
++ * EC1. Add DQS input gating window delay tuning (1/2 T) when CBR retry
++ * EC2. Modify DLL1 MAdj = 0x4C
++ *
++ * Optional define variable
++ * 1. DRAM Speed //
++ * CONFIG_DRAM_336 // 336MHz (DDR-667)
++ * CONFIG_DRAM_408 // 408MHz (DDR-800) (default)
++ * 2. ECC Function enable
++ * CONFIG_DRAM_ECC // define to enable ECC function
++ * // when enabled, must define the ECC protected memory size at 0x1e6e0054
++ * 3. UART5 message output //
++ * CONFIG_DRAM_UART_38400 // set the UART baud rate to 38400, default is 115200
++ ******************************************************************************
++ */
++
++#include <config.h>
++#include <version.h>
++/******************************************************************************
++ Calibration Macro Start
++ Usable registers:
++ r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, r11
++ ******************************************************************************/
++/* PATTERN_TABLE,
++ init_delay_timer,
++ check_delay_timer,
++ clear_delay_timer,
++ record_dll2_pass_range,
++ record_dll2_pass_range_h,
++ are for DRAM calibration */
++
++PATTERN_TABLE:
++ .word 0xff00ff00
++ .word 0xcc33cc33
++ .word 0xaa55aa55
++ .word 0x88778877
++ .word 0x92cc4d6e @ 5
++ .word 0x543d3cde
++ .word 0xf1e843c7
++ .word 0x7c61d253
++ .word 0x00000000 @ 8
++
++ .macro init_delay_timer
++ ldr r0, =0x1e782024 @ Set Timer3 Reload
++ str r2, [r0]
++
++ ldr r0, =0x1e6c0038 @ Clear Timer3 ISR
++ ldr r1, =0x00040000
++ str r1, [r0]
++
++ ldr r0, =0x1e782030 @ Enable Timer3
++ ldr r1, [r0]
++ mov r2, #7
++ orr r1, r1, r2, lsl #8
++ str r1, [r0]
++
++ ldr r0, =0x1e6c0090 @ Check ISR for Timer3 timeout
++ .endm
++
++ .macro check_delay_timer
++ ldr r1, [r0]
++ bic r1, r1, #0xFFFBFFFF
++ mov r2, r1, lsr #18
++ cmp r2, #0x01
++ .endm
++
++ .macro clear_delay_timer
++ ldr r0, =0x1e782030 @ Disable Timer3
++ ldr r1, [r0]
++ bic r1, r1, #0x00000F00
++ str r1, [r0]
++
++ ldr r0, =0x1e6c0038 @ Clear Timer3 ISR
++ ldr r1, =0x00040000
++ str r1, [r0]
++ .endm
++
++ .macro record_dll2_pass_range
++ ldr r1, [r0]
++ bic r2, r1, #0xFFFFFF00
++ cmp r2, r3 @ record min
++ bicgt r1, r1, #0x000000FF
++ orrgt r1, r1, r3
++ bic r2, r1, #0xFFFF00FF
++ cmp r3, r2, lsr #8 @ record max
++ bicgt r1, r1, #0x0000FF00
++ orrgt r1, r1, r3, lsl #8
++ str r1, [r0]
++ .endm
++
++ .macro record_dll2_pass_range_h
++ ldr r1, [r0]
++ bic r2, r1, #0xFF00FFFF
++ mov r2, r2, lsr #16
++ cmp r2, r3 @ record min
++ bicgt r1, r1, #0x00FF0000
++ orrgt r1, r1, r3, lsl #16
++ bic r2, r1, #0x00FFFFFF
++ cmp r3, r2, lsr #24 @ record max
++ bicgt r1, r1, #0xFF000000
++ orrgt r1, r1, r3, lsl #24
++ str r1, [r0]
++ .endm
++
++ .macro init_spi_checksum
++ ldr r0, =0x1e620084
++ ldr r1, =0x20010000
++ str r1, [r0]
++ ldr r0, =0x1e62008C
++ ldr r1, =0x20000200
++ str r1, [r0]
++ ldr r0, =0x1e620080
++ ldr r1, =0x0000000D
++ orr r2, r2, r7
++ orr r1, r1, r2, lsl #8
++ and r2, r6, #0xF
++ orr r1, r1, r2, lsl #4
++ str r1, [r0]
++ ldr r0, =0x1e620008
++ ldr r2, =0x00000800
++ .endm
++
++/******************************************************************************
++ Calibration Macro End
++ ******************************************************************************/
++LPC_Patch: @ load to SRAM base 0x1e720400
++ str r1, [r0]
++ str r3, [r2]
++ bic r1, r1, #0xFF
++LPC_Patch_S1:
++ subs r5, r5, #0x01
++ moveq pc, r8
++ ldr r3, [r2]
++ tst r3, #0x01
++ movne pc, r8
++ mov pc, r7
++LPC_Patch_S2: @ load to SRAM base 0x1e720480
++ str r1, [r0]
++ mov pc, r9
++LPC_Patch_E:
++
++.globl lowlevel_init
++lowlevel_init:
++
++init_dram:
++ /* save lr */
++ mov r4, lr
++/* Test - DRAM initial time */
++ ldr r0, =0x1e782044
++ ldr r1, =0xFFFFFFFF
++ str r1, [r0]
++
++ ldr r0, =0x1e782030
++ ldr r1, [r0]
++ bic r1, r1, #0x0000F000
++ str r1, [r0]
++ mov r2, #3
++ orr r1, r1, r2, lsl #12
++ str r1, [r0]
++/* Test - DRAM initial time */
++
++ /*Set Scratch register Bit 7 before initialize*/
++ ldr r0, =0x1e6e2000
++ ldr r1, =0x1688a8a8
++ str r1, [r0]
++
++ ldr r0, =0x1e6e2040
++ ldr r1, [r0]
++ orr r1, r1, #0x80
++ str r1, [r0]
++
++ /* Fix LPC lock issue for AST2300 */
++ ldr r0, =0x1e6e207c @ Check AST2300
++ ldr r1, [r0]
++ mov r1, r1, lsr #24
++ cmp r1, #0x01
++ bne lpc_recover_end @ not match AST2300
++
++ mov r3, #0x0
++lpc_recover_check:
++ ldr r0, =0x1e78900c @ check HICR3[4]=0x1
++ ldr r1, [r0]
++ tst r1, #0x10
++ beq lpc_recover_end
++ ldr r0, =0x1e789004 @ check HICR1[7]=0x1
++ ldr r1, [r0]
++ tst r1, #0x80
++ beq lpc_recover_end
++ ldr r0, =0x1e7890a0 @ check LHCR0[27:24]=0x6
++ ldr r1, [r0]
++ mov r1, r1, lsr #24
++ and r1, r1, #0xF
++ cmp r1, #0x06
++ bne lpc_recover_end
++ add r3, r3, #0x01
++ cmp r3, #0x5 @ repeat 5 times
++ ble lpc_recover_check
++
++ mov r3, #0x0
++lpc_recover_init:
++ ldr r0, =0x1e7890a4 @ set LHCR1[1:0]=0x0
++ ldr r1, =0x00000000
++ str r1, [r0]
++ add r3, r3, #0x01
++ cmp r3, #0x20
++ bge lpc_recover_end
++ ldr r1, [r0]
++ tst r1, #0x01
++ bne lpc_recover_init
++
++ ldr r0, =0x1e7890b0 @ set LHCR4[7:0]=0xFF
++ ldr r1, =0x000000FF
++ str r1, [r0]
++ ldr r0, =0x1e7890b4 @ set LHCR5[31:0]=0xFFFFFFFF
++ ldr r1, =0xFFFFFFFF
++ str r1, [r0]
++ ldr r0, =0x1e7890b8 @ set LHCR6[31:0]=0xFFFFFFFF
++ str r1, [r0]
++
++ adr r6, LPC_Patch
++ adr r7, LPC_Patch_S2
++ ldr r0, =0x1e720400
++copy_lpc_patch_1:
++ ldr r1, [r6]
++ str r1, [r0]
++ add r6, r6, #0x4
++ add r0, r0, #0x4
++ cmp r6, r7
++ bne copy_lpc_patch_1
++
++ adr r6, LPC_Patch_S2
++ adr r7, LPC_Patch_E
++ ldr r0, =0x1e720480
++copy_lpc_patch_2:
++ ldr r1, [r6]
++ str r1, [r0]
++ add r6, r6, #0x4
++ add r0, r0, #0x4
++ cmp r6, r7
++ bne copy_lpc_patch_2
++
++ ldr r0, =0x1e7890a0 @ set LHCR0[31:0]=0xFFFFFF01
++ ldr r1, =0xFFFFFF01
++ add r2, r0, #0x4
++ mov r3, #0x01
++ mov r5, #0x10
++ adr r9, lpc_recover_end
++ adr r6, LPC_Patch
++ adr r7, LPC_Patch_S1
++ sub r6, r7, r6
++ ldr r7, =0x1e720400
++ add r7, r7, r6
++ ldr r8, =0x1e720480
++ ldr pc, =0x1e720400
++
++lpc_recover_end:
++ ldr r0, =0x1e7890a0 @ set LHCR0[31:0]=0xFFFFFF00
++ ldr r1, =0xFFFFFF00
++ str r1, [r0]
++ /* <END> Fix LPC lock issue for AST2300 */
++
++ /* Check Scratch Register Bit 6 */
++ ldr r0, =0x1e6e2040
++ ldr r1, [r0]
++ bic r1, r1, #0xFFFFFFBF
++ mov r2, r1, lsr #6
++ cmp r2, #0x01
++ beq platform_exit
++
++ ldr r2, =0x033103F1 @ load PLL parameter for 24Mhz CLKIN (396:324)
++/* ldr r2, =0x019001F0 @ load PLL parameter for 24Mhz CLKIN (408:336) */
++ ldr r0, =0x1e6e207c @ Check Revision ID
++ ldr r1, [r0]
++ mov r1, r1, lsr #24
++ cmp r1, #0x02
++ bne set_MPLL @ not match AST2400
++
++ ldr r0, =0x1e6e2070 @ Check CLKIN freq
++ ldr r1, [r0]
++ mov r1, r1, lsr #23
++ tst r1, #0x01
++ ldrne r2, =0x017001D0 @ load PLL parameter for 25Mhz CLKIN (400:325)
++
++set_MPLL:
++ ldr r0, =0x1e6e2020 @ M-PLL (DDR SDRAM) Frequency
++ ldr r1, =0xFFFF
++#if defined(CONFIG_DRAM_336)
++ mov r2, r2, lsr #16
++#endif
++ and r1, r2, r1
++ str r1, [r0]
++
++/* Debug - UART console message */
++ ldr r0, =0x1e78400c
++ mov r1, #0x83
++ str r1, [r0]
++
++ ldr r0, =0x1e6e202c
++ ldr r2, [r0]
++ mov r2, r2, lsr #12
++ tst r2, #0x01
++ ldr r0, =0x1e784000
++ moveq r1, #0x0D @ Baudrate 115200
++ movne r1, #0x01 @ Baudrate 115200, div13
++#if defined(CONFIG_DRAM_UART_38400)
++ moveq r1, #0x27 @ Baudrate 38400
++ movne r1, #0x03 @ Baudrate 38400 , div13
++#endif
++ str r1, [r0]
++
++ ldr r0, =0x1e784004
++ mov r1, #0x00
++ str r1, [r0]
++
++ ldr r0, =0x1e78400c
++ mov r1, #0x03
++ str r1, [r0]
++
++ ldr r0, =0x1e784008
++ mov r1, #0x07
++ str r1, [r0]
++
++ ldr r0, =0x1e784000
++ mov r1, #0x0D @ '\r'
++ str r1, [r0]
++ mov r1, #0x0A @ '\n'
++ str r1, [r0]
++ mov r1, #0x44 @ 'D'
++ str r1, [r0]
++ mov r1, #0x52 @ 'R'
++ str r1, [r0]
++ mov r1, #0x41 @ 'A'
++ str r1, [r0]
++ mov r1, #0x4D @ 'M'
++ str r1, [r0]
++ mov r1, #0x20 @ ' '
++ str r1, [r0]
++ mov r1, #0x49 @ 'I'
++ str r1, [r0]
++ mov r1, #0x6E @ 'n'
++ str r1, [r0]
++ mov r1, #0x69 @ 'i'
++ str r1, [r0]
++ mov r1, #0x74 @ 't'
++ str r1, [r0]
++ mov r1, #0x2D @ '-'
++ str r1, [r0]
++ mov r1, #0x44 @ 'D'
++ str r1, [r0]
++ mov r1, #0x44 @ 'D'
++ str r1, [r0]
++ mov r1, #0x52 @ 'R'
++ str r1, [r0]
++/* Debug - UART console message */
++
++ /* Delay about 100us */
++ ldr r0, =0x1e782030 @ Init Timer3 Control
++ ldr r1, [r0]
++ bic r1, r1, #0x00000F00
++ str r1, [r0]
++
++ ldr r2, =0x00000064 @ Set Timer3 Reload = 100 us
++ init_delay_timer
++delay_0:
++ check_delay_timer
++ bne delay_0
++ clear_delay_timer
++ /* end delay 100us */
++
++/******************************************************************************
++ Init DRAM common registers
++ ******************************************************************************/
++ ldr r0, =0x1e6e0000
++ ldr r1, =0xfc600309
++ str r1, [r0]
++
++ /* Reset MMC */
++ ldr r1, =0x00000000
++ ldr r0, =0x1e6e0034
++ str r1, [r0]
++ ldr r0, =0x1e6e0018
++ str r1, [r0]
++ ldr r0, =0x1e6e0024
++ str r1, [r0]
++ ldr r0, =0x1e6e0064 @ REG_MADJ, power down DLL
++ str r1, [r0]
++
++ ldr r1, =0x00034C4C @ REG_MADJ, reset DLL
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0068 @ REG_SADJ
++ ldr r1, =0x00001800
++ str r1, [r0]
++
++ /* Delay about 10us */
++ ldr r2, =0x0000000B @ Set Timer3 Reload = 10 us
++ init_delay_timer
++delay_1:
++ check_delay_timer
++ bne delay_1
++ clear_delay_timer
++ /* end delay 10us */
++
++ ldr r0, =0x1e6e0064 @ REG_MADJ | 0xC0000, enable DLL
++ ldr r1, [r0]
++ ldr r2, =0xC0000
++ orr r1, r1, r2
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0008
++ ldr r1, =0x0090040f /* VGA */
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0018
++ ldr r1, =0x4000A120
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0018
++ ldr r1, =0x00000120
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0038
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0040
++ ldr r1, =0xFF444444
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0044
++ ldr r1, =0x22222222
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0048
++ ldr r1, =0x22222222
++ str r1, [r0]
++
++ ldr r0, =0x1e6e004c
++ ldr r1, =0x22222222
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0050
++ ldr r1, =0x80000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0050
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0054
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0060 @ REG_DRV
++ ldr r1, =0x000000FA @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x000000FA
++#endif
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0070
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0074
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0078
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e007c
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0080
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0084
++ ldr r1, =0x00FFFFFF
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0088 @ REG_DQIDLY
++ ldr r1, =0x00000089 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x00000074
++#endif
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0020 @ REG_DQSIC
++ ldr r1, =0x000000E2 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x000000BA
++#endif
++ str r1, [r0]
++
++ /* Delay about 10us */
++ ldr r2, =0x0000000B @ Set Timer3 Reload = 10 us
++ init_delay_timer
++delay_2:
++ check_delay_timer
++ bne delay_2
++ clear_delay_timer
++ /* end delay 10us */
++
++ /* Check DRAM Type by H/W Trapping */
++ ldr r0, =0x1e6e2070
++ ldr r1, [r0]
++ bic r1, r1, #0xFEFFFFFF @ bit[24]=1 => DDR2
++ mov r2, r1, lsr #24
++ cmp r2, #0x01
++ beq ddr2_init
++ b ddr3_init
++.LTORG
++
++/******************************************************************************
++ DDR3 Init
++
++ tRCD = 15 ns
++ tRAS = 37.5 ns
++ tRRD = max(4 CK,10 ns)
++ tRP = 15 ns
++ tRFC = 110ns/1Gbit, 160ns/2Gbit, 300ns/4Gbit
++ tRTP = max(4 CK,7.5 ns)
++ tWR = 15 ns
++ tXSNR = max(10 CK,200 ns)
++ tWTR = max(4 CK,7.5 ns)
++ tFAW = 50 ns
++ tMRD = max(15 CK,20 ns)
++ ******************************************************************************/
++ddr3_init:
++/* Debug - UART console message */
++ ldr r0, =0x1e784000
++ mov r1, #0x33 @ '3'
++ str r1, [r0]
++ mov r1, #0x0D @ '\r'
++ str r1, [r0]
++ mov r1, #0x0A @ '\n'
++ str r1, [r0]
++/* Debug - UART console message */
++
++ ldr r0, =0x1e6e0004
++ ldr r1, =0x00000531 @ Default set to 1Gbit
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0010 @ REG_AC1
++ ldr r1, =0x33302825 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x22202725
++#endif
++ str r1, [r0]
++
++ /* Check DRAM CL Timing by H/W Trapping */
++ ldr r0, =0x1e6e2070
++ ldr r1, [r0]
++ bic r1, r1, #0xF9FFFFFF
++ mov r2, r1, lsr #9 @ Set CL
++ ldr r1, =0x00020000
++ add r2, r2, r1
++ ldr r1, [r0]
++ bic r1, r1, #0xFBFFFFFF
++ mov r1, r1, lsr #6 @ Set CWL
++ orr r2, r2, r1
++ ldr r1, =0x00300000
++ add r2, r2, r1
++
++ ldr r0, =0x1e6e0014 @ REG_AC2
++ ldr r1, =0xCC00963F @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0xAA007636
++#endif
++ orr r1, r1, r2
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0004 @ check 2400 mode
++ ldr r2, [r0]
++ mov r2, r2, lsr #10
++
++ ldr r0, =0x1e6e006c @ REG_IOZ
++ ldr r1, =0x00002312 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x00002312
++#endif
++ tst r2, #0x01
++ moveq r1, r1, lsr #8
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0120
++ mov r1, #0
++ str r1, [r0]
++ tst r2, #0x01 @ check AST2300
++ beq CBRDLL1_2300_Start
++ ldr r0, =0x1e6e207c @ check AST2400 revision A0
++ ldr r1, [r0]
++ mov r1, r1, lsr #16
++ and r1, r1, #0xFF
++ cmp r1, #0x0
++ beq CBRDLL1_2300_Start
++ b CBRDLL1_2400_Start
++MCLK2X_Phase_CBR_Done_DDR3:
++ ldr r0, =0x1e6e0018
++ ldr r1, [r0]
++ orr r1, r1, #0x40
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0034
++ ldr r1, =0x00000001
++ str r1, [r0]
++
++ ldr r0, =0x1e6e000c
++ ldr r1, =0x00000040
++ str r1, [r0]
++
++ /* Delay about 400us */
++ ldr r2, =0x00000190 @ Set Timer3 Reload = 400 us
++ init_delay_timer
++delay3_4:
++ check_delay_timer
++ bne delay3_4
++ clear_delay_timer
++ /* end delay 400us */
++
++ /* Check DRAM CL Timing by H/W Trapping */
++ ldr r0, =0x1e6e2070
++ ldr r1, [r0]
++ bic r1, r1, #0xF9FFFFFF
++ mov r2, r1, lsr #21 @ Set CL
++ ldr r1, =0x00000010
++ add r2, r2, r1
++ ldr r1, [r0]
++ bic r1, r1, #0xFBFFFFFF
++ mov r1, r1, lsr #7 @ Set CWL
++ orr r2, r2, r1
++
++ ldr r0, =0x1e6e002c @ REG_MRS
++ ldr r1, =0x04001700 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x04001500
++#endif
++ orr r1, r1, r2
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0030 @ REG_EMRS
++ ldr r1, =0x00000000 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x00000000
++#endif
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set EMRS2
++ ldr r1, =0x00000005
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set EMRS3
++ ldr r1, =0x00000007
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set EMRS
++ ldr r1, =0x00000003
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set MRS
++ ldr r1, =0x00000001
++ str r1, [r0]
++
++ ldr r0, =0x1e6e002c @ REG_MRS
++ ldr r1, =0x04001600 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x04001400
++#endif
++ orr r1, r1, r2
++ str r1, [r0]
++
++ ldr r0, =0x1e6e000c @ Refresh 8 times
++ ldr r1, =0x00005C48
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set MRS
++ ldr r1, =0x00000001
++ str r1, [r0]
++
++ ldr r0, =0x1e6e000c @ Set refresh cycle
++ ldr r1, =0x00002001
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0014
++ ldr r1, [r0]
++ bic r1, r1, #0xFFF9FFFF
++ mov r2, r1, lsr #3 @ get CL
++
++ ldr r0, =0x1e6e0034 @ REG_PWC
++ ldr r1, =0x00000303 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x00000303
++#endif
++ orr r1, r1, r2
++ str r1, [r0]
++
++ b Calibration_Start
++.LTORG
++/******************************************************************************
++ End DDR3 Init
++ ******************************************************************************/
++
++/******************************************************************************
++ DDR2 Init
++
++ tRCD = 15 ns
++ tRAS = 45 ns
++ tRRD = 10 ns
++ tRP = 15 ns
++ tRFC = 105ns/512Mbit, 127.5ns/1Gbit, 197.5ns/2Gbit, 327.5ns/4Gbit
++ tRTP = 7.5 ns
++ tWR = 15 ns
++ tXSNR = 200 ns
++ tWTR = 7.5 ns
++ tFAW = 50 ns
++ tMRD = 4 CK
++ ******************************************************************************/
++ddr2_init:
++/* Debug - UART console message */
++ ldr r0, =0x1e784000
++ mov r1, #0x32 @ '2'
++ str r1, [r0]
++ mov r1, #0x0D @ '\r'
++ str r1, [r0]
++ mov r1, #0x0A @ '\n'
++ str r1, [r0]
++/* Debug - UART console message */
++
++ ldr r0, =0x1e6e0004
++ ldr r1, =0x00000510 @ Default set to 512Mbit
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0010 @ REG_AC1
++ ldr r1, =0x33302714 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x22201613
++#endif
++ str r1, [r0]
++
++ /* Check DRAM CL Timing by H/W Trapping */
++ ldr r0, =0x1e6e2070
++ ldr r1, [r0]
++ bic r1, r1, #0xF9FFFFFF
++ mov r2, r1, lsr #5 @ Set CL
++ mov r1, r2, lsr #4 @ Set CWL
++ orr r2, r2, r1
++ ldr r1, =0x00110000
++ add r2, r2, r1
++
++ ldr r0, =0x1e6e0014 @ REG_AC2
++ ldr r1, =0xCC00B03F @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0xAA00903B
++#endif
++ orr r1, r1, r2
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0004 @ check 2400 mode
++ ldr r2, [r0]
++ mov r2, r2, lsr #10
++
++ ldr r0, =0x1e6e006c @ REG_IOZ
++ ldr r1, =0x00002312 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x00002312
++#endif
++ tst r2, #0x01
++ moveq r1, r1, lsr #8
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0120
++ mov r1, #1
++ str r1, [r0]
++ tst r2, #0x01 @ check AST2300
++ beq CBRDLL1_2300_Start
++ ldr r0, =0x1e6e207c @ check AST2400 revision A0
++ ldr r1, [r0]
++ mov r1, r1, lsr #16
++ and r1, r1, #0xFF
++ cmp r1, #0x0
++ beq CBRDLL1_2300_Start
++ b CBRDLL1_2400_Start
++MCLK2X_Phase_CBR_Done_DDR2:
++
++ ldr r0, =0x1e6e0034
++ ldr r1, =0x00000001
++ str r1, [r0]
++
++ ldr r0, =0x1e6e000c
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++ /* Delay about 400us */
++ ldr r2, =0x00000190 @ Set Timer3 Reload = 400 us
++ init_delay_timer
++delay2_4:
++ check_delay_timer
++ bne delay2_4
++ clear_delay_timer
++ /* end delay 400us */
++
++ /* Check DRAM CL Timing by H/W Trapping */
++ ldr r0, =0x1e6e2070
++ ldr r1, [r0]
++ bic r1, r1, #0xF9FFFFFF
++ mov r2, r1, lsr #21 @ Set CL
++ ldr r1, =0x00000040
++ orr r2, r2, r1
++
++ ldr r0, =0x1e6e002c @ REG_MRS
++ ldr r1, =0x00000D03 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x00000B03
++#endif
++ orr r1, r1, r2
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0030 @ REG_EMRS
++ ldr r1, =0x00000040 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x00000040
++#endif
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set EMRS2
++ ldr r1, =0x00000005
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set EMRS3
++ ldr r1, =0x00000007
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set EMRS
++ ldr r1, =0x00000003
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set MRS
++ ldr r1, =0x00000001
++ str r1, [r0]
++
++ ldr r0, =0x1e6e000c @ Refresh 8 times
++ ldr r1, =0x00005C08
++ str r1, [r0]
++
++ ldr r0, =0x1e6e002c @ REG_MRS
++ ldr r1, =0x00000C03 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x00000A03
++#endif
++ orr r1, r1, r2
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set MRS
++ ldr r1, =0x00000001
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0030 @ REG_EMRS
++ ldr r1, =0x000003C0 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x000003C0
++#endif
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set EMRS
++ ldr r1, =0x00000003
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0030 @ REG_EMRS
++ ldr r1, =0x00000040 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x00000040
++#endif
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0028 @ Set EMRS
++ ldr r1, =0x00000003
++ str r1, [r0]
++
++ ldr r0, =0x1e6e000c @ Set refresh cycle
++ ldr r1, =0x00002001
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0014
++ ldr r1, [r0]
++ bic r1, r1, #0xFFF9FFFF
++ mov r2, r1, lsr #3 @ get CL
++
++ ldr r0, =0x1e6e0034 @ REG_PWC
++ ldr r1, =0x00000503 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x00000503
++#endif
++ orr r1, r1, r2
++ str r1, [r0]
++
++ b Calibration_Start
++.LTORG
++/******************************************************************************
++ End DDR2 Init
++ ******************************************************************************/
++/******************************************************************************
++ DDR CK duty finetune program
++ SRAM buffer definition
++ 0x1E720204 : gdll golden DLL1 record
++ 0x1E720208 : gduty golden duty setting record
++ 0x1E72020C : gdutysum golden duty data record
++ 0x1E720210 : duty record of delay 0 invert
++ 0x1E720214 : duty record of delay 1 invert
++ ....
++ 0x1E72024C : duty record of delay 15 invert
++ 0x1E720250 : duty record of delay 0
++ 0x1E720254 : duty record of delay 1
++ ....
++ 0x1E72028C : duty record of delay 15
++
++ Register usage
++ r0 - r3 = free
++ r4 = record the return pc value, do not use
++ r5 = free
++ r6 = free
++ r7 = duty count
++ r8 = gdll
++ r9 = gduty
++ r10 = gdutysum
++ ******************************************************************************/
++CBRDLL1_2400_Start:
++ ldr r0, =0x1e6e0120
++ ldr r1, [r0]
++ orr r1, r1, #0x02
++ str r1, [r0]
++
++ ldr r1, =0x00000000
++ ldr r0, =0x1e720204
++ ldr r2, =0x1e7202a0
++init_sram_start0:
++ str r1, [r0]
++ add r0, r0, #4
++ cmp r0, r2
++ blt init_sram_start0
++
++ ldr r0, =0x1e6e0034
++ mov r1, #0x20
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0060
++ ldr r1, [r0]
++ mov r2, #0x01
++ orr r1, r1, r2, lsl #13
++ str r1, [r0]
++
++ mov r7, #0x0 @ init duty count
++ mov r8, #0x0 @ init gdll
++ mov r9, #0x0 @ init gduty
++ mov r10, #0x0 @ init gdutysum
++cbrdll1_duty_start:
++ cmp r7, #32
++ bge cbrdll1_duty_end
++
++ ldr r0, =0x1e6e0018
++ ldr r1, =0x00008120
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0060
++ ldr r1, [r0]
++ bic r1, r1, #0x00001F00
++ orr r1, r1, r7, lsl #8
++ mov r2, #0x10
++ eor r1, r1, r2, lsl #8
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0000 @ dummy read
++ ldr r1, [r0]
++
++ b CBRDLL1_2300_Start
++CBRDLL1_2400_Call:
++
++ mov r5, #0x01 @ init dqidly count
++ mov r6, #0x00 @ init duty sum
++cbrdll1_duty_cal_start:
++ cmp r5, #0x05
++ bge cbrdll1_duty_cal_end
++
++ ldr r0, =0x1e6e0018
++ ldr r1, =0x00200120
++ orr r1, r1, r5, lsl #16
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0000
++ ldr r1, [r0]
++
++ ldr r0, =0x1e6e0018
++ ldr r1, [r0]
++ mov r2, #0x10
++ orr r1, r1, r2, lsl #24
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0080
++ ldr r1, =0x80000000 @ init duty cal waiting
++cbrdll1_duty_cal_wait:
++ ldr r2, [r0]
++ tst r2, r1
++ beq cbrdll1_duty_cal_wait
++
++ ldr r0, =0x1e6e008c
++ ldr r2, [r0]
++
++ ldr r0, =0x1e720210
++ add r0, r0, r7, lsl #2
++ str r2, [r0]
++
++ ldr r1, =0xFFFF
++ and r3, r1, r2
++ cmp r3, r1
++ moveq r2, r2, lsr #16
++ and r3, r1, r2
++ add r6, r6, r3
++ ldr r1, =0xF000
++ cmp r3, r1
++ blt cbrdll1_duty_cal_end
++ add r5, r5, #0x01
++ b cbrdll1_duty_cal_start
++
++cbrdll1_duty_cal_end:
++ mov r6, r6, lsr #2 @ get dutysum
++ cmp r6, r10 @ check dutysum > gdutysum
++ ble cbrdll1_duty_next
++ ldr r0, =0x1e6e0068
++ ldr r8, [r0]
++ eor r9, r7, #0x10
++ mov r10, r6
++
++cbrdll1_duty_next:
++ add r7, r7, #0x01
++ cmp r7, #16 @ check duty >= 15
++ blt cbrdll1_duty_start
++ ldr r0, =0xFA00 @ check gdutysum > 0xFA00
++ cmp r10, r0
++ blt cbrdll1_duty_start
++
++cbrdll1_duty_end:
++ ldr r0, =0x1e6e0060
++ ldr r1, [r0]
++ bic r1, r1, #0x00001F00
++ orr r1, r1, r9, lsl #8
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0068
++ bic r8, r8, #0xFF000000
++ bic r8, r8, #0x00FF0000
++ str r8, [r0]
++
++ ldr r0, =0x1e720204 @ record result
++ str r8, [r0]
++ add r0, r0, #0x04
++ str r9, [r0]
++ add r0, r0, #0x04
++ str r10, [r0]
++
++ ldr r0, =0x1e6e0018
++ ldr r1, =0x00008120
++ str r1, [r0]
++ ldr r0, =0x1e6e0000 @ dummy read
++ ldr r1, [r0]
++ ldr r0, =0x1e6e0018
++ ldr r1, =0x00000120
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0120
++ ldr r1, [r0]
++ cmp r1, #0x3
++ beq MCLK2X_Phase_CBR_Done_DDR2
++ b MCLK2X_Phase_CBR_Done_DDR3
++
++/******************************************************************************
++ MCLK2X lock to MCLK program
++ r0 - r3 = free
++ r5 = madjmax
++ r6 = dllend
++ 0x1E720200 = 0x96cnt:failcnt:dllmax:dllmin
++ ******************************************************************************/
++CBRDLL1_2300_Start:
++ ldr r0, =0x1e6e0064
++ ldr r5, [r0]
++ and r5, r5, #0xFF @ init madjmax
++ mov r6, r5 @ init dllend
++
++ ldr r1, =0x000000ff
++ ldr r0, =0x1e720200
++ str r1, [r0] @ init dllcnt2:dllmax:dllmin
++
++ mov r3, #0x0 @ init loop count
++cbrdll1_scan_start:
++ cmp r3, r6
++ bge cbrdll1_scan_end
++
++ ldr r0, =0x1e6e0018
++ ldr r1, =0x00008120
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0068
++ mov r1, r3
++ cmp r1, r5
++ subge r1, r1, r5
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0000 @ dummy read
++ ldr r1, [r0]
++
++ ldr r0, =0x1e6e0018
++ ldr r1, =0x00000120
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0000 @ dummy read
++ ldr r1, [r0]
++ ldr r0, =0x1e6e0000 @ dummy read
++ ldr r1, [r0]
++
++ ldr r0, =0x1e6e001c
++ ldr r1, [r0]
++ mov r1, r1, lsr #16
++ and r1, r1, #0xFF
++
++ and r2, r1, #0x96
++ cmp r2, #0x96
++ beq cbrdll1_scan_pass @ if (mclk2x_phase & 0x96) == 0x96
++ ldr r0, =0x1e720200
++ ldr r1, [r0]
++ mov r2, r1, lsr #8
++ ands r2, r2, #0xFF @ get dllmax
++ beq cbrdll1_scan_next @ if dllmax == 0
++ mov r2, r1, lsr #16
++ and r2, r2, #0xFF
++ add r2, r2, #0x01
++ cmp r2, #0x02
++ movge r6, r3
++ bic r1, r1, #0x00FF0000
++ orr r1, r1, r2, lsl #16
++ str r1, [r0]
++ b cbrdll1_scan_next
++
++cbrdll1_scan_pass:
++ cmp r3, #0x0 @ if dll = 0
++ moveq r3, #0x0F
++ addeq r6, r6, #0x10
++ beq cbrdll1_scan_next
++ ldr r0, =0x1e720200
++ ldr r2, [r0]
++ cmp r1, #0x96
++ bne cbrdll1_scan_pass2
++ mov r1, r2, lsr #24
++ add r1, r1, #0x01
++ bic r2, r2, #0xFF000000
++ orr r2, r2, r1, lsl #24
++ cmp r1, #0x03 @ check (phase == 0x96) count == 3
++ bicge r2, r2, #0x0000FF00
++ bicge r2, r2, #0x000000FF
++ orrge r2, r2, r3, lsl #8
++ orrge r2, r2, r3
++ str r2, [r0]
++ bge cbrdll1_scan_end
++
++cbrdll1_scan_pass2:
++ and r1, r2, #0xFF @ if(dllmin > dll)
++ cmp r1, r3
++ bicgt r2, r2, #0x000000FF
++ orrgt r2, r2, r3
++
++ mov r1, r2, lsr #8 @ if(dllmax < dll)
++ and r1, r1, #0xFF
++ cmp r1, r3
++ biclt r2, r2, #0x0000FF00
++ orrlt r2, r2, r3, lsl #8
++
++ bic r2, r2, #0x00FF0000
++ str r2, [r0]
++
++cbrdll1_scan_next:
++ add r3, r3, #0x01
++ b cbrdll1_scan_start
++
++cbrdll1_scan_end:
++ ldr r0, =0x1e720200
++ ldr r1, [r0]
++ mov r2, r1, lsr #8 @ get dllmax
++ ands r2, r2, #0xFF
++ bne cbrdll1_scan_done @ if(dllmax != 0)
++ ldr r0, =0x1e6e0064
++ ldr r3, [r0]
++ bic r1, r3, #0x000C0000
++ str r1, [r0]
++ add r0, r0, #0x04
++ mov r1, #0x0
++ str r1, [r0]
++
++ /* Delay about 10us */
++ ldr r2, =0x0000000A @ Set Timer3 Reload = 10 us
++ init_delay_timer
++delay0_1:
++ check_delay_timer
++ bne delay0_1
++ clear_delay_timer
++ /* end delay 10us */
++
++ ldr r0, =0x1e6e0064
++ str r3, [r0]
++
++ /* Delay about 10us */
++ ldr r2, =0x0000000A @ Set Timer3 Reload = 10 us
++ init_delay_timer
++delay0_2:
++ check_delay_timer
++ bne delay0_2
++ clear_delay_timer
++ /* end delay 10us */
++
++ b CBRDLL1_2300_Start
++
++cbrdll1_scan_done:
++ and r1, r1, #0xFF
++ add r1, r1, r2
++ mov r6, r1, lsr #1 @ dll1.0 = (dllmin + dllmax) >> 1
++ cmp r6, r5
++ subge r6, r6, r5
++ add r3, r6, r5, lsr #2 @ dll1.1 = dll1.0 + (MADJ >> 2)
++
++ ldr r0, =0x1e6e0004
++ ldr r1, [r0]
++ mov r1, r1, lsr #10
++ tst r1, #0x1
++ bne cbrdll1_scan_set_2400
++ cmp r3, r5
++ subge r3, r3, r5
++ mov r2, #0x0
++ tst r3, #0x08
++ beq cbrdll1_scan_set_2300_2 @ if !(dll & 8)
++cbrdll1_scan_set_2300_1: @ if (dll & 8)
++ mov r1, #0x0
++ tst r3, #0x08
++ addeq r1, r1, #0x01
++ cmp r2, #0x05
++ addge r1, r1, #0x01
++ cmp r1, #0x02
++ beq cbrdll1_scan_set
++ add r2, r2, #0x01
++ add r3, r3, #0x01
++ cmp r3, r5
++ subge r3, r3, r5
++ b cbrdll1_scan_set_2300_1
++
++cbrdll1_scan_set_2300_2:
++ and r1, r3, #0x07
++ cmp r1, #0x07
++ beq cbrdll1_scan_set
++ cmp r2, #0x05
++ bge cbrdll1_scan_set
++ add r2, r2, #0x01
++ add r3, r3, #0x01
++ cmp r3, r5
++ subge r3, r3, r5
++ b cbrdll1_scan_set_2300_2
++
++cbrdll1_scan_set_2400:
++ add r3, r3, #0x05 @ dll1.1 = dll1.0 + (MADJ >> 2) + 5
++ cmp r3, r5
++ subge r3, r3, r5
++
++cbrdll1_scan_set:
++ orr r1, r6, r3, lsl #8
++ ldr r0, =0x1e6e0068
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0120
++ ldr r1, [r0]
++ cmp r1, #0x0
++ beq MCLK2X_Phase_CBR_Done_DDR3
++ cmp r1, #0x1
++ beq MCLK2X_Phase_CBR_Done_DDR2
++ b CBRDLL1_2400_Call
++
++.LTORG
++
++/******************************************************************************
++ Calibration Code Start
++ SRAM buffer definition
++ 0x1E720000 : Pass 1, DLLI MIN value range
++ 0x1E720008 : DQS0 DLL valid range, 2nd time CBR
++ 0x1E72000C : DQS1 DLL valid range, 2nd time CBR
++ 0x1E720010 : DQ0 DLL valid range, Pass 1
++ 0x1E720014 : DQ1 DLL valid range, Pass 1
++ ....
++ 0x1E720048 : DQ14 DLL valid range, Pass 1
++ 0x1E72004C : DQ15 DLL valid range, Pass 1
++ 0x1E720090 : DLL1 SAdj record
++ 0x1E720094 : DQL Pass1 finetune result
++ 0x1E720098 : DQH Pass1 finetune result
++ 0x1E72009C : DRAM initial time, (us)
++ 0x1E7200A0 : CBR3 retry counter
++ 0x1E7200A4 : DRAM initial time, (us)
++ 0x1E7200A8 : Released date
++ 0x1E7200AC : Released SDK version
++ 0x1E7200B0 : DQS input mask window for MCR18[4] = 0
++ 0x1E7200B4 : DQS input mask window for MCR18[4] = 1
++ 0x1E720100 : DQIDLY=00, DLL valid range
++ 0x1E720104 : DQIDLY=01, DLL valid range
++ ....
++ 0x1E720178 : DQIDLY=30, DLL valid range
++ 0x1E72017C : DQIDLY=31, DLL valid range
++ 0x1E720180 : DQSI-MCLK2X P-phase pass record DLL2= 0-31
++ 0x1E720184 : DQSI-MCLK2X P-phase pass record DLL2=32-63
++ 0x1E720188 : DQSI-MCLK2X N-phase pass record DLL2= 0-31
++ 0x1E72018C : DQSI-MCLK2X N-phase pass record DLL2=32-63
++ ******************************************************************************/
++Calibration_Start_pre: @ Toggle DQSI mask delay
++ ldr r0, =0x1e6e0018
++ ldr r1, [r0]
++ eor r1, r1, #0x10
++ str r1, [r0]
++
++Calibration_Start:
++/* Init SRAM buffer */
++ ldr r1, =0x000000ff
++ ldr r0, =0x1e720000
++ ldr r2, =0x1e720100
++init_sram_start:
++ str r1, [r0]
++ add r0, r0, #4
++ cmp r0, r2
++ blt init_sram_start
++
++ ldr r1, =0x00ff00ff
++ ldr r0, =0x1e720100
++ ldr r2, =0x1e720180
++init_sram_start2:
++ str r1, [r0]
++ add r0, r0, #4
++ cmp r0, r2
++ blt init_sram_start2
++
++ ldr r1, =0x00000000
++ ldr r0, =0x1e720180
++ ldr r2, =0x1e720200
++init_sram_start3:
++ str r1, [r0]
++ add r0, r0, #4
++ cmp r0, r2
++ blt init_sram_start3
++
++ ldr r0, =0x1e6e0068 @ save the DLL1 SAdj initial value
++ ldr r1, [r0]
++ ldr r0, =0x1e720090
++ str r1, [r0]
++
++/* Start
++ r0 = free
++ r1 = free
++ r2 = free
++ r3 = free
++ r4 = record the return pc value, do not use
++ r5 = pattern table index
++ r6 = pass count
++ r7 = dram DLL2 parameter index (0x1e6e0068), max is 0x4C
++*/
++/******************************************************************************
++ Fine DQI delay and DQSI-MCLK phase
++ r8 = DQIDLY count
++ r9 = DQSI-MCLK2X phase count
++ r10 = pattern fail retry counter, initialize to 2 (fail 2 times)
++ r11 = passcnt accumulator for each DQIDLY
++ *****************************************************************************/
++CBR0_START:
++/* Debug - UART console message */
++ ldr r0, =0x1e784000
++ mov r1, #0x43 @ 'C'
++ str r1, [r0]
++ mov r1, #0x42 @ 'B'
++ str r1, [r0]
++ mov r1, #0x52 @ 'R'
++ str r1, [r0]
++ mov r1, #0x30 @ '0'
++ str r1, [r0]
++ mov r1, #0x2D @ '-'
++ str r1, [r0]
++/* Debug - UART console message */
++
++ ldr r0, =0x1e6e0018
++ ldr r1, [r0]
++ bic r1, r1, #0xFF000000
++ bic r1, r1, #0x00FF0000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0074 @ set the testing DRAM size = 1KB
++ ldr r1, =0x000003FF
++ str r1, [r0]
++
++ mov r8, #0x00 @ init DQIDLY
++ mov r9, #0x00 @ init DQSI-MCLK2X phase
++ mov r11, #0x01 @ init passcnt accumulator
++
++cbr0_next_dqidly:
++ cmp r9, #0x00
++ bne cbr0_next_dqsiphase
++ cmp r11, #0x00
++ addeq r8, r8, #0x01 @ jump 1 stage if no pass at previous stage
++ mov r11, #0x00
++ add r8, r8, #0x01
++ cmp r8, #0x1F @ max DQIDLY = 31
++ bgt CBR0_END
++
++/* Debug - UART console message */
++ ldr r0, =0x1e784000
++ and r1, r8, #0x07
++ add r1, r1, #0x30 @ '0-7'
++ str r1, [r0]
++/* Debug - UART console message */
++
++ ldr r0, =0x1e6e0018
++ ldr r1, [r0]
++ bic r1, r1, #0x00FF0000
++ orr r1, r1, r8, lsl #16
++ str r1, [r0]
++ mov r9, #0x01 @ '1':p_phase, '0':n_phase
++
++ /* Delay about 3us */ @ wait DQIDLY load
++ ldr r2, =0x00000003 @ Set Timer4 Reload = 3 us
++ init_delay_timer
++delay_4:
++ check_delay_timer
++ bne delay_4
++ clear_delay_timer
++ /* end delay 3us */
++
++ b cbr0_dll2_scan_start
++
++cbr0_next_dqsiphase:
++ ldr r0, =0x1e6e0018
++ ldr r1, [r0]
++ orr r1, r1, r9, lsl #23 @ set DQSI-MCLK2X phase
++ str r1, [r0]
++ mov r9, #0x00
++
++cbr0_dll2_scan_start:
++ mov r6, #0x00 @ init pass count
++ mov r7, #0x00 @ init DLL2 parameter index
++
++/****************************
++ DLL2 delay margin test loop
++ ***************************/
++cbr0_next_dll2_parameter:
++ ldr r0, =0x1e6e0068 @ load DLL2 parameter
++ ldr r1, [r0]
++ bic r1, r1, #0x00FF0000
++ bic r1, r1, #0xFF000000
++ orr r1, r1, r7, lsl #16
++ str r1, [r0]
++ ldr r2, =0x40404040 @ DLL2 max is 0x40404040
++ cmp r7, r2
++ bge cbr0_next_dqidly
++ ldr r2, =0x01010101
++ add r7, r7, r2
++
++/* CBRScan3() start */
++ adrl r5, PATTERN_TABLE @ init pattern table index
++/****************************
++ Test pattern iteration loop
++ ***************************/
++cbr0_next_test_pattern:
++ mov r10, #2 @ set the retry loop = 2 of each pattern
++ ldr r1, [r5] @ load test pattern
++ ldr r0, =0x1e6e007c
++ str r1, [r0]
++ cmp r1, #0x00 @ the last data in pattern is 0x00
++ bne cbr0_test_burst
++
++ and r3, r7, #0xFF
++ sub r3, r3, #0x01 @ we add 1 after loop check so we need to decrease 1
++ cmp r3, #0x00
++ beq cbr0_next_dqidly @ pass at dlli = 0, invalid
++ add r6, r6, #0x01 @ increment pass count
++ add r11, r11, #0x01 @ increment pass count
++
++ ldr r0, =0x1e720180 @ record DLL2 pass window
++ cmp r9, #0x00 @ DQSI-MCLK2X phase check
++ addeq r0, r0, #0x08
++ cmp r3, #32
++ addge r0, r0, #0x4
++ and r1, r3, #0x1F
++ mov r2, #0x1
++ mov r2, r2, lsl r1
++ ldr r1, [r0]
++ orr r1, r1, r2
++ str r1, [r0]
++
++ ldr r0, =0x1e720100 @ record DLL2 min:max value for each DQIDLY
++ add r0, r0, r8, lsl #2
++ cmp r9, #0x00 @ DQSI-MCLK2X phase check
++ beq cbr0_test_pass_dqsin
++ record_dll2_pass_range
++ b cbr0_next_dll2_parameter
++
++cbr0_test_pass_dqsin:
++ record_dll2_pass_range_h
++ b cbr0_next_dll2_parameter
++
++cbr0_test_pattern_fail:
++ cmp r6, #5 @ passcnt >= 5
++ bge cbr0_next_dqidly
++ ldr r0, =0x1e720100 @ reset DLL2 min:max value
++ add r0, r0, r8, lsl #2
++ ldr r1, [r0]
++ ldr r2, =0xFFFF0000
++ ldr r3, =0x000000FF
++ cmp r9, #0x00
++ moveq r2, r2, lsr #16
++ moveq r3, r3, lsl #16
++ and r1, r1, r2
++ orr r1, r1, r3
++ str r1, [r0]
++ b cbr0_next_dll2_parameter @ CBRScan3() end and test result fail, go to next step
++
++/****************************
++ Test fail retry loop
++ ***************************/
++cbr0_pattern_fail_retry:
++
++/* CBRTest3() start */
++cbr0_test_burst:
++ ldr r0, =0x1e6e0070
++ ldr r1, =0x00000000
++ str r1, [r0]
++ ldr r1, =0x000000C1
++ str r1, [r0]
++ ldr r3, =0x3000
++cbr0_wait_engine_idle_0:
++ ldr r2, [r0]
++ tst r2, r3 @ D[12] = idle bit
++ beq cbr0_wait_engine_idle_0
++
++ ldr r2, [r0] @ read fail bit status
++ mov r1, #0x0
++ str r1, [r0]
++ mov r2, r2, lsr #13 @ D[13] = fail bit
++ cmp r2, #0x00
++ bne cbr0_test_fail
++
++cbr0_test_single:
++ ldr r0, =0x1e6e0070
++ ldr r1, =0x00000000
++ str r1, [r0]
++ ldr r1, =0x00000085
++ str r1, [r0]
++ ldr r3, =0x3000
++cbr0_wait_engine_idle_1:
++ ldr r2, [r0]
++ tst r2, r3 @ D[12] = idle bit
++ beq cbr0_wait_engine_idle_1
++
++ ldr r2, [r0] @ read fail bit status
++ mov r1, #0x0
++ str r1, [r0]
++ mov r2, r2, lsr #13 @ D[13] = fail bit
++ cmp r2, #0x00
++ beq cbr0_test_pass
++
++/* CBRTest3() end */
++
++cbr0_test_fail:
++ subs r10, r10, #1
++ bne cbr0_pattern_fail_retry
++ b cbr0_test_pattern_fail @ CBRScan3() return(0)
++
++cbr0_test_pass:
++ add r5, r5, #0x04 @ increase the test pattern index
++ b cbr0_next_test_pattern
++
++CBR0_END:
++ mov r5, #0x0 @ init DQIDLY search count
++ mov r6, #0x0 @ init max_margin:g_margin
++ mov r8, #0x0 @ init g_side
++ mov r7, #0x0 @ init maximum margin DQIDLY,DQSI-MCLK2X phase
++cbr0_search_dll_margin_s:
++ ldr r0, =0x1e720100
++ add r0, r0, r5, lsl #2
++ ldr r1, [r0]
++ and r2, r1, #0xFF @ get dllmin_p
++ mov r1, r1, lsr #8
++ and r3, r1, #0xFF @ get dllmax_p
++ subs r2, r3, r2 @ get margin-P
++ movmi r2, #0x0
++ mov r1, r1, lsr #8
++ and r3, r1, #0xFF @ get dllmin_n
++ mov r1, r1, lsr #8
++ and r1, r1, #0xFF @ get dllmax_n
++ subs r3, r1, r3 @ get margin-N
++ movmi r3, #0x0
++ add r1, r2, r3
++ cmp r1, #0x0
++ beq cbr0_search_dll_margin_e @ if margin-P = 0 && margin-N = 0
++
++ ldr r9, [r0]
++ ldr r0, =0x1e720180
++ cmp r2, r3
++ orrlt r5, r5, #0x80 @ margin-N > margin-P
++ addlt r0, r0, #0x08
++ movlt r9, r9, lsr #16
++ movge r3, r2 @ max(margin-P/N)
++ add r2, r3, #0x2 @ define +/- 2 steps of variation
++ mov r1, r6, lsr #16
++ cmp r2, r1
++ blt cbr0_search_dll_margin_e @ if max(margin-P/N) + 2 < max_margin
++
++ and r1, r9, #0xFF @ r1 = dlli counter
++ cmp r1, #32
++ ldrge r2, [r0, #0x4] @ load pass window
++ ldrlt r2, [r0]
++ and r1, r1, #0x1F
++ mov r10, #0x1 @ init test bit mask
++ mov r10, r10, lsl r1
++ and r1, r9, #0xFF
++cbr0_search_dllmin_margin_s:
++ tst r2, r10
++ beq cbr0_search_dllmin_margin_e
++ mov r10, r10, lsr #1
++ cmp r1, #32
++ ldreq r2, [r0]
++ ldreq r10, =0x80000000
++ subs r1, r1, #0x1
++ bne cbr0_search_dllmin_margin_s
++
++cbr0_search_dllmin_margin_e:
++ and r2, r9, #0xFF
++ sub r11, r2, r1 @ get dllmin side margin
++
++ mov r9, r9, lsr #8
++ and r1, r9, #0xFF @ r1 = dlli counter
++ cmp r1, #32
++ ldrge r2, [r0, #0x4] @ load pass window
++ ldrlt r2, [r0]
++ and r1, r1, #0x1F
++ mov r10, #0x1 @ init test bit mask
++ mov r10, r10, lsl r1
++ and r1, r9, #0xFF
++cbr0_search_dllmax_margin_s:
++ tst r2, r10
++ beq cbr0_search_dllmax_margin_e
++ mov r10, r10, lsl #1
++ cmp r1, #31
++ ldreq r2, [r0, #0x4]
++ ldreq r10, =0x00000001
++ add r1, r1, #0x1
++ cmp r1, #64
++ bne cbr0_search_dllmax_margin_s
++
++cbr0_search_dllmax_margin_e:
++ and r2, r9, #0xFF
++ sub r1, r1, r2 @ get dllmax side margin
++ cmp r1, r11
++ movlt r11, r1 @ get side_margin
++
++cbr0_check_dll_margin: @ if max(margin-P/N) > g_margin && side_margin >= g_side && dqidly <= 20
++ cmp r5, #20
++ bgt cbr0_check_dll_margin2
++ and r1, r6, #0xFF
++ cmp r3, r1
++ ble cbr0_check_dll_margin3
++ cmp r11, r8
++ bge cbr0_set_dll_margin
++
++cbr0_check_dll_margin2: @ if max(margin-P/N) > g_margin+1 && side_margin >= g_side)
++ and r1, r6, #0xFF
++ add r2, r1, #0x1
++ cmp r3, r2
++ ble cbr0_check_dll_margin3
++ cmp r11, r8
++ bge cbr0_set_dll_margin
++
++cbr0_check_dll_margin3: @ if side_margin > g_side && g_side < 8
++ cmp r8, #8
++ bge cbr0_search_dll_margin_e
++ cmp r11, r8
++ ble cbr0_search_dll_margin_e
++
++cbr0_set_dll_margin:
++ mov r1, r6, lsr #16
++ cmp r3, r1
++ bicgt r6, r6, #0x00FF0000
++ orrgt r6, r6, r3, lsl #16
++ bic r6, r6, #0x000000FF
++ orr r6, r6, r3
++ mov r7, r5
++ mov r8, r11
++
++cbr0_search_dll_margin_e:
++ and r5, r5, #0x7F
++ add r5, r5, #0x01
++ cmp r5, #0x20 @ last DQIDLY
++ blt cbr0_search_dll_margin_s
++
++ ldr r0, =0x1e6e0018
++ ldr r1, [r0]
++ bic r1, r1, #0x00FF0000
++ orr r1, r1, r7, lsl #16
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0068
++ ldr r1, [r0]
++ bic r1, r1, #0x00FF0000
++ bic r1, r1, #0xFF000000
++ str r1, [r0]
++
++ /* Delay about 5us */
++ ldr r2, =0x00000005 @ Set Timer5 Reload = 5 us
++ init_delay_timer
++delay_5:
++ check_delay_timer
++ bne delay_5
++ clear_delay_timer
++ /* end delay 5us */
++
++ ldr r0, =0x1e6e000c @ Set refresh cycle
++ ldr r1, =0x00005C01
++ str r1, [r0]
++
++/******************************************************************************
++ Fine tune per bit DQ input delay -- Pass 1, left edge align
++ r8 = free
++ r9 = DQ fail bit accumulator
++ r10 = pattern fail counter, initialize to 5 (fail 5 times)
++ r11 = free
++ *****************************************************************************/
++CBR1_START:
++/* Debug - UART console message */
++ ldr r0, =0x1e784000
++ mov r1, #0x0D @ '\r'
++ str r1, [r0]
++ mov r1, #0x0A @ '\n'
++ str r1, [r0]
++ mov r1, #0x43 @ 'C'
++ str r1, [r0]
++ mov r1, #0x42 @ 'B'
++ str r1, [r0]
++ mov r1, #0x52 @ 'R'
++ str r1, [r0]
++ mov r1, #0x31 @ '1'
++ str r1, [r0]
++/* Debug - UART console message */
++
++ mov r6, #0x00 @ init pass count
++ mov r7, #0x00 @ init DLL2 parameter index
++
++/****************************
++ DLL2 delay margin test loop
++ ***************************/
++cbr1_next_dll2_parameter:
++ ldr r0, =0x1e6e0068 @ load DLL2 parameter
++ ldr r1, [r0]
++ bic r1, r1, #0x00FF0000
++ bic r1, r1, #0xFF000000
++ orr r1, r1, r7, lsl #16
++ str r1, [r0]
++ ldr r2, =0x40404040 @ parameter's max is to 0x40404040
++ cmp r7, r2
++ bge CBR1_END
++ ldr r2, =0x01010101
++ add r7, r7, r2
++
++ ldr r0, =0x1e6e0074 @ set the testing DRAM size = 4KB
++ ldr r1, =0x00000FFF
++ str r1, [r0]
++
++/* CBRScan2() start */
++ ldr r9, =0xFFFF @ init test status
++ adrl r5, PATTERN_TABLE @ init pattern table index
++/****************************
++ Test pattern iteration loop
++ ***************************/
++cbr1_next_test_pattern:
++ mov r10, #5 @ set the retry loop of each pattern
++ ldr r1, [r5] @ load test pattern
++ ldr r0, =0x1e6e007c
++ str r1, [r0]
++ cmp r1, #0x00 @ the last data in pattern is 0x00
++ bne cbr1_test_single
++
++cbr1_test_pattern_end:
++ cmp r9, #0x00
++ bne cbr1_test_pass_dqi
++ cmp r6, #10
++ bge CBR1_END
++ b cbr1_next_dll2_parameter @ CBRScan2() end and test result fail, go to next step
++
++cbr1_test_pass_dqi:
++ and r3, r7, #0xFF
++ sub r3, r3, #0x01 @ we add 1 after loop check so we need to decrease 1
++ add r6, r6, #0x01 @ increment pass count
++ ldr r0, =0x1e720010
++ mov r8, #0x01
++cbr1_test_pass_dqi_loop_s:
++ tst r9, r8
++ beq cbr1_test_pass_dqi_loop_e
++ record_dll2_pass_range
++
++cbr1_test_pass_dqi_loop_e:
++ add r0, r0, #0x04
++ mov r8, r8, lsl #1
++ ldr r1, =0xFFFF
++ tst r8, r1
++ bne cbr1_test_pass_dqi_loop_s
++ b cbr1_next_dll2_parameter
++
++/****************************
++ Test fail retry loop
++ ***************************/
++cbr1_pattern_fail_retry:
++
++/* CBRTest2() start */
++cbr1_test_single:
++ ldr r0, =0x1e6e0070
++ ldr r1, =0x00000000
++ str r1, [r0]
++ ldr r1, =0x00000005
++ str r1, [r0]
++ ldr r3, =0x1000
++ ldr r1, =0x1000
++cbr1_wait_engine_idle_0:
++ subs r1, r1, #1
++ beq cbr1_test_single_end
++ ldr r2, [r0]
++ tst r2, r3 @ D[12] = idle bit
++ beq cbr1_wait_engine_idle_0
++
++cbr1_test_single_end:
++ ldr r0, =0x1e6e0078 @ read fail bit status
++ ldr r11, [r0]
++ orr r11, r11, r11, lsr #16
++ bic r11, r11, #0xFF000000
++ bic r11, r11, #0x00FF0000
++
++ ldr r1, =0xFFFF
++ cmp r11, r1
++ beq cbr1_test_fail
++
++cbr1_test_burst:
++ ldr r0, =0x1e6e0070
++ ldr r2, =0x00000000
++ str r2, [r0]
++ ldr r2, =0x00000041
++ str r2, [r0]
++ ldr r3, =0x1000
++ ldr r1, =0x1000
++cbr1_wait_engine_idle_1:
++ subs r1, r1, #1
++ beq cbr1_test_burst_end
++ ldr r2, [r0]
++ tst r2, r3 @ D[12] = idle bit
++ beq cbr1_wait_engine_idle_1
++
++cbr1_test_burst_end:
++ ldr r0, =0x1e6e0078 @ read fail bit status
++ ldr r2, [r0]
++ orr r2, r2, r2, lsr #16
++ bic r2, r2, #0xFF000000
++ bic r2, r2, #0x00FF0000
++ orr r11, r11, r2
++
++ ldr r2, =0xFFFF
++ cmp r11, r2
++ bne cbr1_test_pass
++/* CBRTest2() end */
++
++cbr1_test_fail:
++ subs r10, r10, #1
++ bne cbr1_pattern_fail_retry
++ mov r9, #0x00
++ b cbr1_test_pattern_end @ CBRScan2() return(0)
++
++cbr1_test_pass:
++ ldr r1, =0xFFFF @ record the pass bit
++ eor r11, r11, r1
++ and r9, r9, r11 @ DQ pass bit
++ cmp r9, #0x00
++ beq cbr1_test_pattern_end @ CBRScan2() return(0)
++
++ add r5, r5, #0x04 @ increase the test pattern index
++ b cbr1_next_test_pattern
++
++CBR1_END:
++ mov r5, #0x0 @ init DQ DLL_min sum
++ mov r6, #0x0 @ init DQ DLL_min valid count
++ ldr r0, =0x1e72000c
++ ldr r3, =0x1e720050
++cbr1_search_dllmin_s:
++ add r0, r0, #0x04
++ cmp r0, r3
++ beq cbr1_search_dllmin_e
++ ldr r1, [r0]
++ mov r2, r1, lsr #8
++ and r2, r2, #0xFF @ get dllmax
++ and r1, r1, #0xFF @ get dllmin
++ subs r2, r2, r1 @ dllmax - dllmin
++ bmi cbr1_search_dllmin_s @ no valid margin found, bypass fine tune
++ cmp r2, #10 @ (dllmax - dllmin) < 10
++ blt cbr1_search_dllmin_s @ no enough margin found, bypass fine tune
++ add r5, r5, r1
++ add r6, r6, #1
++ b cbr1_search_dllmin_s
++
++cbr1_search_dllmin_e:
++ cmp r6, #16
++ bne Calibration_Start_pre @ not all bits valid, retry again
++
++ mov r5, r5, lsr #4
++ ldr r0, =0x1e720000
++ str r5, [r0]
++
++ mov r6, #0x00 @ init DQL CBR value
++ ldr r0, =0x1e720030
++ ldr r7, =0x1e72000c
++cbr1_set_result_dql:
++ sub r0, r0, #4
++ cmp r0, r7
++ beq cbr1_set_result_next
++ mov r6, r6, lsl #3
++ ldr r1, [r0]
++ mov r2, r1, lsr #8
++ and r2, r2, #0xFF @ get dllmax
++ and r1, r1, #0xFF @ get dllmin
++ mov r3, r1 @ dll = dllmin
++ cmp r5, r3
++ blt cbr1_set_result_dql_neg
++ sub r1, r5, r3
++ mov r2, #19
++ mul r1, r2, r1
++ mov r1, r1, lsr #5 @ dqi_tune = ((gold_dll - dll) * 19) >> 5
++ cmp r1, #2 @ dqi_tune max = 2
++ movgt r1, #2
++ orr r6, r6, r1
++ b cbr1_set_result_dql
++
++cbr1_set_result_dql_neg:
++ sub r1, r3, r5
++ mov r2, #19
++ mul r1, r2, r1
++ mov r1, r1, lsr #5 @ dqi_tune = ((gold_dll - dll) * 19) >> 5
++ cmp r1, #2 @ dqi_tune max = -2
++ movgt r1, #2
++ mov r2, #8
++ sub r1, r2, r1
++ and r1, r1, #7
++ orr r6, r6, r1
++ b cbr1_set_result_dql
++
++cbr1_set_result_next:
++ ldr r0, =0x1e6e0080 @ save DQL fine tune result
++ str r6, [r0]
++ ldr r0, =0x1e720094
++ str r6, [r0]
++
++ mov r6, #0x00 @ init DQH CBR value
++ ldr r0, =0x1e720050
++ ldr r7, =0x1e72002c
++cbr1_set_result_dqh:
++ sub r0, r0, #4
++ cmp r0, r7
++ beq cbr1_set_result_end
++ mov r6, r6, lsl #3
++ ldr r1, [r0]
++ mov r2, r1, lsr #8
++ and r2, r2, #0xFF @ get dllmax
++ and r1, r1, #0xFF @ get dllmin
++ mov r3, r1 @ dll = dllmin
++ cmp r5, r3
++ blt cbr1_set_result_dqh_neg
++ sub r1, r5, r3
++ mov r2, #19
++ mul r1, r2, r1
++ mov r1, r1, lsr #5 @ dqi_tune = ((gold_dll - dll) * 19) >> 5
++ cmp r1, #3 @ dqi_tune max = 2
++ movgt r1, #3
++ subs r1, r1, #1
++ movmi r1, #7
++ orr r6, r6, r1
++ b cbr1_set_result_dqh
++
++cbr1_set_result_dqh_neg:
++ sub r1, r3, r5
++ mov r2, #19
++ mul r1, r2, r1
++ mov r1, r1, lsr #5 @ dqi_tune = ((gold_dll - dll) * 19) >> 5
++ add r1, r1, #1
++ cmp r1, #2 @ dqi_tune max = -2
++ movgt r1, #2
++ mov r2, #8
++ sub r1, r2, r1
++ and r1, r1, #7
++ orr r6, r6, r1
++ b cbr1_set_result_dqh
++
++cbr1_set_result_end:
++ ldr r0, =0x1e6e0084 @ save DQH fine tune result
++ str r6, [r0]
++ ldr r0, =0x1e720098
++ str r6, [r0]
++
++/******************************************************************************
++ Search the DLL2 detail margin
++ *****************************************************************************/
++ ldr r0, =0x1e7200a0
++ mov r1, #0
++ str r1, [r0]
++
++CBR3_START:
++/* Debug - UART console message */
++ ldr r0, =0x1e784000
++ mov r1, #0x33 @ '3'
++ str r1, [r0]
++/* Debug - UART console message */
++
++ mov r6, #0x00 @ init pass count
++ mov r7, #0x00 @ init DLL2 parameter index
++ ldr r1, =0x000000ff
++ ldr r0, =0x1e720008 @ init DQL dllmax,dllmin
++ str r1, [r0]
++ ldr r0, =0x1e72000c @ init DQH dllmax,dllmin
++ str r1, [r0]
++
++ ldr r0, =0x1e7200a0 @ CBR3 iteration counter
++ ldr r1, [r0]
++ add r1, r1, #1
++ str r1, [r0]
++
++/****************************
++ DLL2 delay margin test loop
++ ***************************/
++cbr3_next_dll2_parameter:
++ ldr r0, =0x1e6e0068 @ load DLL2 parameter
++ ldr r1, [r0]
++ bic r1, r1, #0x00FF0000
++ bic r1, r1, #0xFF000000
++ orr r1, r1, r7, lsl #16
++ str r1, [r0]
++ ldr r2, =0x40404040 @ parameter's max is to 0x40404040
++ cmp r7, r2
++ bge CBR3_END
++ ldr r2, =0x01010101
++ add r7, r7, r2
++
++ ldr r0, =0x1e6e0074 @ set the testing DRAM size = 64KB
++ ldr r1, =0x0000FFFF
++ str r1, [r0]
++
++/* CBRScan() start */
++ mov r9, #0x03 @ init test status
++ adrl r5, PATTERN_TABLE @ init pattern table index
++/****************************
++ Test pattern iteration loop
++ ***************************/
++cbr3_next_test_pattern:
++ mov r10, #5 @ set the retry loop of each pattern
++ ldr r1, [r5] @ load test pattern
++ ldr r0, =0x1e6e007c
++ str r1, [r0]
++ cmp r1, #0x00 @ the last data in pattern is 0x00
++ bne cbr3_test_single
++
++cbr3_test_pattern_end:
++ cmp r9, #0x00
++ bne cbr3_test_pass_dql
++ cmp r6, #10
++ bge CBR3_END
++ b cbr3_next_dll2_parameter @ CBRScan() end and test result fail, go to next step
++
++cbr3_test_pass_dql:
++ and r3, r7, #0xFF
++ sub r3, r3, #0x01 @ we add one after loop check so we need to decrease 1
++ add r6, r6, #0x01 @ increment pass count
++ tst r9, #0x01
++ beq cbr3_test_pass_dqh
++
++ ldr r0, =0x1E720008
++ record_dll2_pass_range
++
++cbr3_test_pass_dqh:
++ tst r9, #0x02
++ beq cbr3_next_dll2_parameter
++ ldr r0, =0x1E72000c
++ record_dll2_pass_range
++ b cbr3_next_dll2_parameter
++
++/****************************
++ Test fail retry loop
++ ***************************/
++cbr3_pattern_fail_retry:
++
++/* CBRTest() start */
++cbr3_test_single:
++ ldr r0, =0x1e6e0070
++ ldr r1, =0x00000000
++ str r1, [r0]
++ ldr r1, =0x00000005
++ str r1, [r0]
++ ldr r3, =0x1000
++ ldr r8, =0x10000
++cbr3_wait_engine_idle_0:
++ subs r8, r8, #1
++ beq cbr3_test_single_end
++ ldr r2, [r0]
++ tst r2, r3 @ D[12] = idle bit
++ beq cbr3_wait_engine_idle_0
++
++cbr3_test_single_end:
++ ldr r0, =0x1e6e0078 @ read fail bit status
++ ldr r11, [r0]
++ orr r11, r11, r11, lsr #16
++ bic r11, r11, #0xFF000000
++ bic r11, r11, #0x00FF0000
++
++ ldr r1, =0xFF
++ tst r11, r1
++ beq cbr3_test_burst
++ tst r11, r1, lsl #8
++ bne cbr3_test_fail
++
++cbr3_test_burst:
++ mov r1, #0x00 @ initialize loop index, r1 is loop's index
++cbr3_test_burst_loop:
++ ldr r0, =0x1e6e0070
++ ldr r2, =0x00000000
++ str r2, [r0]
++ mov r2, r1, lsl #3
++ orr r2, r2, #0x41 @ test command = 0x41 | (datagen << 3)
++ str r2, [r0]
++ ldr r3, =0x1000
++ ldr r8, =0x10000
++cbr3_wait_engine_idle_1:
++ subs r8, r8, #1
++ beq cbr3_test_burst_end
++ ldr r2, [r0]
++ tst r2, r3 @ D[12] = idle bit
++ beq cbr3_wait_engine_idle_1
++
++cbr3_test_burst_end:
++ ldr r0, =0x1e6e0078 @ read fail bit status
++ ldr r2, [r0]
++ orr r2, r2, r2, lsr #16
++ bic r2, r2, #0xFF000000
++ bic r2, r2, #0x00FF0000
++ orr r11, r11, r2
++
++ ldr r2, =0xFF
++ tst r11, r2
++ beq cbr3_next_test_burst_mode
++ tst r11, r2, lsl #8
++ beq cbr3_next_test_burst_mode
++/* CBRTest() end */
++
++cbr3_test_fail:
++ subs r10, r10, #1
++ bne cbr3_pattern_fail_retry
++ mov r9, #0x00
++ b cbr3_test_pattern_end @ CBRScan() return(0)
++
++cbr3_next_test_burst_mode:
++ add r1, r1, #1 @ increase the test mode index
++ cmp r1, #0x08 @ there are 8 modes
++ bne cbr3_test_burst_loop
++
++ ldr r1, =0xFF @ record the pass byte
++ tst r11, r1
++ andne r9, r9, #0x02 @ DQL fail
++ tst r11, r1, lsl #8
++ andne r9, r9, #0x01 @ DQH fail
++ cmp r9, #0x00
++ beq cbr3_test_pattern_end @ CBRScan() return(0)
++
++ add r5, r5, #0x04 @ increase the test pattern index
++ b cbr3_next_test_pattern
++
++CBR3_END:
++ ldr r0, =0x1e72000c @ check DQH margin
++ ldr r1, [r0]
++ mov r2, r1, lsr #8
++ and r2, r2, #0xFF @ get dllmax
++ and r1, r1, #0xFF @ get dllmin
++ subs r5, r2, r1 @ dllmax - dllmin
++ bmi CBR3_START @ no valid margin found, retry again
++ cmp r5, #10 @ (dllmax - dllmin) < 10
++ blt CBR3_START @ no enough margin found, retry again
++ add r2, r1, r2 @ (dllmin[1] + dllmax[1] + 1) >> 1
++ add r2, r2, #0x01
++ mov r1, r2, lsr #1
++ mov r3, r1, lsl #8
++ ldr r1, [r0] @ store the dll search result
++ bic r1, r1, #0xFF000000
++ bic r1, r1, #0x00FF0000
++ orr r1, r1, r3, lsl #8
++ str r1, [r0]
++
++ ldr r0, =0x1e720008 @ check DQL margin
++ ldr r1, [r0]
++ mov r2, r1, lsr #8
++ and r2, r2, #0xFF @ get dllmax
++ and r1, r1, #0xFF @ get dllmin
++ subs r5, r2, r1 @ dllmax - dllmin
++ bmi CBR3_START @ no valid margin found, retry again
++ cmp r5, #10 @ (dllmax - dllmin) < 10
++ blt CBR3_START @ no enough margin found, retry again
++ add r2, r1, r2 @ (dllmin[0] + dllmax[0] + 1) >> 1
++ add r2, r2, #0x01
++ mov r1, r2, lsr #1
++ ldr r2, [r0] @ store the dll search result
++ bic r2, r2, #0xFF000000
++ bic r2, r2, #0x00FF0000
++ orr r2, r2, r1, lsl #16
++ str r2, [r0]
++ orr r3, r3, r1
++
++ ldr r0, =0x1e6e0068 @ save the result dll value
++ ldr r1, [r0]
++ bic r1, r1, #0xFF000000
++ bic r1, r1, #0x00FF0000
++ orr r1, r1, r3, lsl #16
++ str r1, [r0]
++ b CBR4_START
++
++.LTORG
++
++/******************************************************************************
++ Search the DQS input mask margin
++ *****************************************************************************/
++CBR4_START:
++/* Debug - UART console message */
++ ldr r0, =0x1e784000
++ mov r1, #0x34 @ '4'
++ str r1, [r0]
++/* Debug - UART console message */
++
++ ldr r0, =0x1e6e0074 @ set the testing DRAM size = 4KB
++ ldr r1, =0x00000FFF
++ str r1, [r0]
++
++ mov r8, #0x00 @ init MCR18[4]
++ ldr r1, =0x000000ff
++ ldr r0, =0x1e7200b0 @ init MCR18[4]=0 max,min
++ str r1, [r0]
++ ldr r0, =0x1e7200b4 @ init MCR18[4]=1 max,min
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0018
++ ldr r1, [r0]
++ bic r1, r1, #0x0000001F
++ str r1, [r0]
++
++ b cbr4_scan_start
++
++cbr4_next_maskdly:
++ add r8, r8, #0x01
++ and r2, r8, #0x01
++ ldr r0, =0x1e6e0018
++ ldr r1, [r0]
++ bic r1, r1, #0x0000001F
++ orr r1, r1, r2, lsl #4
++ str r1, [r0]
++ cmp r8, #0x02
++ bge CBR4_END
++
++cbr4_scan_start:
++ mov r6, #0x00 @ init pass count
++ mov r7, #0x00 @ init mask delay
++
++/****************************
++ DQS Mask delay margin test loop
++ ***************************/
++cbr4_next_parameter:
++ cmp r7, #0x10 @ max delay = 0xF
++ bge cbr4_next_maskdly
++ ldr r0, =0x1e6e0018 @ load MCR18 parameter
++ ldr r1, [r0]
++ bic r1, r1, #0x0000000F
++ orr r1, r1, r7
++ str r1, [r0]
++ add r7, r7, #0x01
++
++/* CBRScan3() start */
++ adrl r5, PATTERN_TABLE @ init pattern table index
++/****************************
++ Test pattern iteration loop
++ ***************************/
++cbr4_next_test_pattern:
++ mov r10, #2 @ set the retry loop = 2 of each pattern
++ ldr r1, [r5] @ load test pattern
++ ldr r0, =0x1e6e007c
++ str r1, [r0]
++ cmp r1, #0x00 @ the last data in pattern is 0x00
++ bne cbr4_test_burst
++
++ and r3, r7, #0xFF
++ sub r3, r3, #0x01 @ we add 1 after loop check so we need to decrease 1
++ add r6, r6, #0x01 @ increment pass count
++
++ ldr r0, =0x1e7200b0 @ record pass window
++ add r0, r0, r8, lsl #2
++ record_dll2_pass_range
++ mov r2, #0x01
++ add r1, r1, r2, lsl #16
++ str r1, [r0]
++ b cbr4_next_parameter
++
++cbr4_test_pattern_fail:
++ cmp r6, #5 @ passcnt >= 5
++ bge cbr4_next_maskdly
++ b cbr4_next_parameter
++
++/****************************
++ Test fail retry loop
++ ***************************/
++cbr4_pattern_fail_retry:
++
++/* CBRTest3() start */
++cbr4_test_burst:
++ ldr r0, =0x1e6e0070
++ ldr r1, =0x00000000
++ str r1, [r0]
++ ldr r1, =0x000000C1
++ str r1, [r0]
++ ldr r3, =0x3000
++cbr4_wait_engine_idle_0:
++ ldr r2, [r0]
++ tst r2, r3 @ D[12] = idle bit
++ beq cbr4_wait_engine_idle_0
++
++ ldr r2, [r0] @ read fail bit status
++ mov r1, #0x0
++ str r1, [r0]
++ mov r2, r2, lsr #13 @ D[13] = fail bit
++ cmp r2, #0x00
++ bne cbr4_test_fail
++
++cbr4_test_single:
++ ldr r0, =0x1e6e0070
++ ldr r1, =0x00000000
++ str r1, [r0]
++ ldr r1, =0x00000085
++ str r1, [r0]
++ ldr r3, =0x3000
++cbr4_wait_engine_idle_1:
++ ldr r2, [r0]
++ tst r2, r3 @ D[12] = idle bit
++ beq cbr4_wait_engine_idle_1
++
++ ldr r2, [r0] @ read fail bit status
++ mov r1, #0x0
++ str r1, [r0]
++ mov r2, r2, lsr #13 @ D[13] = fail bit
++ cmp r2, #0x00
++ beq cbr4_test_pass
++
++/* CBRTest3() end */
++
++cbr4_test_fail:
++ subs r10, r10, #1
++ bne cbr4_pattern_fail_retry
++ b cbr4_test_pattern_fail @ CBRScan3() return(0)
++
++cbr4_test_pass:
++ add r5, r5, #0x04 @ increase the test pattern index
++ b cbr4_next_test_pattern
++
++CBR4_END:
++ ldr r0, =0x1e7200b0 @ check mask margin
++ ldr r1, [r0]
++ add r0, r0, #0x04
++ ldr r2, [r0]
++ ands r6, r2, #0xFF @ get min of MCR18[4] = 1
++ bne cbr4_noset_delay
++ ands r5, r1, #0xFF @ get min of MCR18[4] = 0
++ bne cbr4_set_delay
++ mov r1, r1, lsr #8 @ get max of MCR18[4] = 0
++ and r1, r1, #0xFF
++ mov r2, r2, lsr #8 @ get max of MCR18[4] = 1
++ and r2, r2, #0xFF
++ sub r1, r1, r5
++ sub r2, r2, r6
++ cmp r1, r2
++ bge cbr4_noset_delay
++
++cbr4_set_delay:
++ ldr r0, =0x1e6e0018
++ ldr r1, [r0]
++ orr r1, r1, #0x10
++ str r1, [r0]
++
++cbr4_noset_delay:
++ ldr r0, =0x1e6e0070
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++/******************************************************************************
++ CBR Finish
++ *****************************************************************************/
++/******************************************************************************
++ Check DRAM Size
++ *****************************************************************************/
++ ldr r0, =0x1e6e2070
++ ldr r1, [r0]
++ bic r1, r1, #0xFEFFFFFF @ bit[24]=1 => DDR2
++ mov r2, r1, lsr #24
++ cmp r2, #0x01
++ beq check_ddr2_size
++
++ ldr r0, =0x1e6e0004
++ ldr r5, [r0]
++ bic r5, r5, #0x00000003 @ record MCR04
++ orr r1, r5, #0x3
++ str r1, [r0] @ set to 4Gbit
++ ldr r6, =0x003F2217
++#if defined(CONFIG_DRAM_336)
++ ldr r6, =0x00361C13
++#endif
++ b check_dram_size
++
++check_ddr2_size:
++ ldr r0, =0x1e6e0004
++ ldr r5, [r0]
++ bic r5, r5, #0x00000023 @ record MCR04
++ orr r1, r5, #0x23
++ str r1, [r0] @ set to 4Gbit
++ ldr r6, =0x3F2B1B16
++#if defined(CONFIG_DRAM_336)
++ ldr r6, =0x3B231612
++#endif
++
++ ldr r0, =0x40000000
++ ldr r1, =0x1817191A
++ str r1, [r0]
++ ldr r0, =0x40002000
++ ldr r1, =0x73616532
++ str r1, [r0]
++ ldr r0, =0x40000000
++ ldr r1, =0x1817191A
++ ldr r2, [r0]
++ cmp r1, r2
++ bne check_dram_size_end @ == 512Mbit
++ orr r5, r5, #0x20 @ >= 1Gbit
++ mov r6, r6, lsr #8
++
++check_dram_size:
++ ldr r0, =0x50100000
++ ldr r1, =0x41424344
++ str r1, [r0]
++ ldr r0, =0x48100000
++ ldr r1, =0x25262728
++ str r1, [r0]
++ ldr r0, =0x40100000
++ ldr r1, =0x191A1B1C
++ str r1, [r0]
++ ldr r0, =0x50100000
++ ldr r1, =0x41424344
++ ldr r2, [r0]
++ cmp r2, r1 @ == 4Gbit
++ orreq r5, r5, #0x03
++ moveq r6, r6, lsr #16
++ beq check_dram_size_end
++ ldr r0, =0x48100000
++ ldr r1, =0x25262728
++ ldr r2, [r0]
++ cmp r2, r1 @ == 2Gbit
++ orreq r5, r5, #0x02
++ moveq r6, r6, lsr #8
++ beq check_dram_size_end
++ orr r5, r5, #0x01 @ == 1Gbit
++
++check_dram_size_end:
++ ldr r0, =0x1e6e0004
++ str r5, [r0]
++ ldr r0, =0x1e6e0014
++ ldr r1, [r0]
++ bic r1, r1, #0x000000FF
++ and r6, r6, #0xFF
++ orr r1, r1, r6
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0120 @ VGA Compatible Mode
++ ldr r1, =0x000050C0 @ 408 MHz
++#if defined(CONFIG_DRAM_336)
++ ldr r1, =0x00004DC0
++#endif
++ str r1, [r0]
++
++/******************************************************************************
++ Version Number
++ *****************************************************************************/
++ ldr r0, =0x1e7200a8
++ ldr r1, =0x20141229 @ released date
++ str r1, [r0]
++
++ add r0, r0, #4
++ ldr r1, =0x00000060 @ released SDK version
++ str r1, [r0]
++
++/******************************************************************************
++ Calibration Code End
++ ******************************************************************************/
++
++set_scratch:
++ /*Set Scratch register Bit 6 after ddr initial finished */
++ ldr r0, =0x1e6e2040
++ ldr r1, [r0]
++ orr r1, r1, #0x40
++ str r1, [r0]
++
++/* Debug - UART console message */
++ ldr r0, =0x1e784000
++ mov r1, #0x44 @ 'D'
++ str r1, [r0]
++ mov r1, #0x6F @ 'o'
++ str r1, [r0]
++ mov r1, #0x6E @ 'n'
++ str r1, [r0]
++ mov r1, #0x65 @ 'e'
++ str r1, [r0]
++ mov r1, #0x0D @ '\r'
++ str r1, [r0]
++ mov r1, #0x0A @ '\n'
++ str r1, [r0]
++/* Debug - UART console message */
++
++/******************************************************************************
++ Solve PCIe ASPM issue, only applied to AST2300 series
++ ******************************************************************************/
++ ldr r0, =0x1e6e207c @ Check bounding for AST1150 existence
++ ldr r1, [r0]
++ mov r2, r1, lsr #24
++ cmp r2, #0x01
++ bne platform_exit @ not match AST2300
++ bic r1, r1, #0xFFFFFCFF
++ mov r1, r1, lsr #8
++ cmp r1, #0x02
++ beq platform_exit @ match AST1050
++
++ ldr r0, =0x1e6e2004 @ Disable I2C controller reset
++ ldr r1, [r0]
++ orr r1, r1, #0x04
++ str r1, [r0]
++ bic r1, r1, #0x04
++ str r1, [r0]
++
++ ldr r0, =0x1e78a054 @ Check I2C bus state, if busy then quit
++ ldr r1, [r0]
++ mov r1, r1, lsr #17
++ and r1, r1, #0x03
++ cmp r1, #0x03
++ bne platform_exit
++
++ ldr r0, =0x1e78a040 @ Init I2C1 controller
++ mov r1, #0x01
++ orr r1, r1, r1, lsl #16
++ str r1, [r0]
++
++ ldr r0, =0x1e78a044
++ ldr r1, =0x77776704
++ str r1, [r0]
++
++ mov r1, #0x0
++ ldr r0, =0x1e78a048
++ str r1, [r0]
++ ldr r0, =0x1e78a04c
++ str r1, [r0]
++
++ ldr r0, =0x1e78a050
++ ldr r1, =0xFFFFFFFF
++ str r1, [r0]
++
++ ldr r0, =0x1e78a200 @ Set AST1150 I2C password
++ ldr r1, =0x00A88FA8
++ str r1, [r0]
++
++ ldr r0, =0x1e78a05c
++ ldr r1, =0x00000200 @ Enable buffer mode transfering 3 bytes
++ str r1, [r0]
++
++ ldr r0, =0x1e78a054
++ ldr r1, =0x00000063 @ Fire commmand
++ str r1, [r0]
++
++ ldr r0, =0x1e78a050
++i2c_wait_cmddone_1:
++ ldr r1, [r0]
++ tst r1, #0x38
++ beq i2c_wait_cmddone_1
++ tst r1, #0x2A @ transmit error
++ bne platform_exit2
++ ldr r1, =0xFFFFFFFF
++ str r1, [r0]
++
++ ldr r0, =0x1e78a200 @ Disable ASPM capability
++ ldr r1, =0x04005DA8
++ str r1, [r0]
++
++ ldr r0, =0x1e78a204
++ ldr r1, =0x00000024
++ str r1, [r0]
++
++ ldr r0, =0x1e78a05c
++ ldr r1, =0x00000200 @ Enable buffer mode transfering 3 bytes
++ str r1, [r0]
++
++ ldr r0, =0x1e78a054
++ ldr r1, =0x00000063 @ Fire commmand
++ str r1, [r0]
++
++ ldr r0, =0x1e78a050
++i2c_wait_cmddone_2:
++ ldr r1, [r0]
++ tst r1, #0x38
++ beq i2c_wait_cmddone_2
++ tst r1, #0x2A @ transmit error
++ bne platform_exit2
++ ldr r1, =0xFFFFFFFF
++ str r1, [r0]
++
++platform_exit2:
++ ldr r0, =0x1e78a040 @ Disable I2C1 controller
++ mov r1, #0x00
++ str r1, [r0]
++
++ b platform_exit
++.LTORG
++
++platform_exit:
++#ifdef CONFIG_DRAM_ECC
++ ldr r0, =0x1e6e0004
++ ldr r1, [r0]
++ orr r1, r1, #0x80
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0054
++ ldr r1, =0x05000000 /* ECC protected memory size, default set at 80M */
++ str r1, [r0]
++
++ ldr r0, =0x1e6e007C
++ ldr r1, =0x00000000
++ str r1, [r0]
++ ldr r0, =0x1e6e0074
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0070
++ ldr r1, =0x00000221
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0070
++ ldr r2, =0x00001000
++ECC_Init_Flag:
++ ldr r1, [r0]
++ tst r1, r2 @ D[12] = 1, Done
++ beq ECC_Init_Flag
++
++ ldr r0, =0x1e6e0070
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0050
++ ldr r1, =0x80000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0050
++ ldr r1, =0x00000000
++ str r1, [r0]
++
++ ldr r0, =0x1e6e0070
++ ldr r1, =0x00000400
++ str r1, [r0]
++#endif
++ ldr r0, =0x1e6e2008 @ Set Video ECLK phase
++ ldr r1, [r0]
++ ldr r2, =0xfffffff3
++ and r1, r1, r2
++ orr r1, r1, #0x08
++ str r1, [r0]
++
++ ldr r0, =0x1e6e2004
++ ldr r1, [r0]
++ ldr r2, =0xFFBFFFFF @ Enable JTAG Master, solve ARM stucked by JTAG issue
++ and r1, r1, r2
++ str r1, [r0]
++
++ ldr r0, =0x1e6e2048 @ Set MAC interface delay timing
++ ldr r1, =0x2255
++ str r1, [r0]
++
++ ldr r0, =0x1e6e2070 @ Set MAC AHB bus clock
++ ldr r1, [r0]
++ mov r2, #0x04 @ Default RMII, set MHCLK = HPLL/10
++ tst r1, #0xC0
++ movne r2, #0x02 @ if RGMII, set MHCLK = HPLL/6
++ ldr r0, =0x1e6e2008
++ ldr r1, [r0]
++ bic r1, r1, #0x00070000
++ orr r1, r1, r2, lsl #16
++ str r1, [r0]
++
++/* Test - DRAM initial time */
++ ldr r0, =0x1e782040
++ ldr r1, [r0]
++ ldr r0, =0xFFFFFFFF
++ sub r1, r0, r1
++ ldr r0, =0x1e72009c
++ str r1, [r0]
++ ldr r0, =0x1e7200a4
++ str r1, [r0]
++ ldr r0, =0x1e782030
++ ldr r1, [r0]
++ bic r1, r1, #0x0000F000
++ str r1, [r0]
++/* Test - DRAM initial time */
++
++/******************************************************************************
++ Reset GPIO registers when watchdog reset
++ ******************************************************************************/
++ ldr r0, =0x1e6e207c @ Check Revision ID
++ ldr r1, [r0]
++ mov r1, r1, lsr #24
++ cmp r1, #0x02
++ bne platform_exit3 @ not match AST2400
++
++ ldr r0, =0x1e6e203c @ Check watchdog reset event
++ ldr r1, [r0]
++ and r1, r1, #0x06
++ cmp r1, #0x0
++ beq platform_exit3 @ no watchdog reset event
++
++ ldr r0, =0x1e6e209c @ Check watchdog GPIO selection
++ ldr r1, [r0]
++ mov r1, r1, lsr #21
++ tst r1, #0x01
++ beq platform_exit3 @ no watchdog reset selection
++
++ ldr r1, =0x00000000 @ clear GPIO register reset by PRST_N
++ ldr r2, =0xFFFFFFFF
++ ldr r0, =0x1e780008
++ str r1, [r0]
++ ldr r0, =0x1e78000c
++ str r1, [r0]
++ ldr r0, =0x1e780010
++ str r1, [r0]
++ ldr r0, =0x1e780014
++ str r1, [r0]
++ ldr r0, =0x1e780018
++ str r2, [r0]
++ ldr r0, =0x1e780028
++ str r1, [r0]
++ ldr r0, =0x1e78002c
++ str r1, [r0]
++ ldr r0, =0x1e780030
++ str r1, [r0]
++ ldr r0, =0x1e780034
++ str r1, [r0]
++ ldr r0, =0x1e780038
++ str r2, [r0]
++ ldr r0, =0x1e780040
++ str r1, [r0]
++ ldr r0, =0x1e780044
++ str r1, [r0]
++ ldr r0, =0x1e780048
++ str r1, [r0]
++ ldr r0, =0x1e78004c
++ str r1, [r0]
++ ldr r0, =0x1e780050
++ str r1, [r0]
++ ldr r0, =0x1e780054
++ str r1, [r0]
++ ldr r0, =0x1e780058
++ str r1, [r0]
++ ldr r0, =0x1e780060
++ str r1, [r0]
++ ldr r0, =0x1e780064
++ str r1, [r0]
++ ldr r0, =0x1e780068
++ str r1, [r0]
++ ldr r0, =0x1e78006c
++ str r1, [r0]
++ ldr r0, =0x1e780090
++ str r1, [r0]
++ ldr r0, =0x1e780094
++ str r1, [r0]
++ ldr r0, =0x1e780098
++ str r1, [r0]
++ ldr r0, =0x1e78009c
++ str r1, [r0]
++ ldr r0, =0x1e7800a0
++ str r1, [r0]
++ ldr r0, =0x1e7800a4
++ str r1, [r0]
++ ldr r0, =0x1e7800a8
++ str r2, [r0]
++ ldr r0, =0x1e7800b0
++ str r1, [r0]
++ ldr r0, =0x1e7800b4
++ str r1, [r0]
++ ldr r0, =0x1e7800b8
++ str r1, [r0]
++ ldr r0, =0x1e7800e0
++ str r1, [r0]
++ ldr r0, =0x1e7800e4
++ str r1, [r0]
++ ldr r0, =0x1e7800e8
++ str r1, [r0]
++ ldr r0, =0x1e7800ec
++ str r1, [r0]
++ ldr r0, =0x1e7800f0
++ str r1, [r0]
++ ldr r0, =0x1e7800f4
++ str r1, [r0]
++ ldr r0, =0x1e7800f8
++ str r2, [r0]
++ ldr r0, =0x1e780100
++ str r1, [r0]
++ ldr r0, =0x1e780104
++ str r1, [r0]
++ ldr r0, =0x1e780108
++ str r1, [r0]
++ ldr r0, =0x1e780110
++ str r1, [r0]
++ ldr r0, =0x1e780114
++ str r1, [r0]
++ ldr r0, =0x1e780118
++ str r1, [r0]
++ ldr r0, =0x1e78011c
++ str r1, [r0]
++ ldr r0, =0x1e780120
++ str r1, [r0]
++ ldr r0, =0x1e780124
++ str r1, [r0]
++ ldr r0, =0x1e780128
++ str r2, [r0]
++ ldr r0, =0x1e780130
++ str r1, [r0]
++ ldr r0, =0x1e780134
++ str r1, [r0]
++ ldr r0, =0x1e780138
++ str r1, [r0]
++ ldr r0, =0x1e780140
++ str r1, [r0]
++ ldr r0, =0x1e780144
++ str r1, [r0]
++ ldr r0, =0x1e780148
++ str r1, [r0]
++ ldr r0, =0x1e78014c
++ str r1, [r0]
++ ldr r0, =0x1e780150
++ str r1, [r0]
++ ldr r0, =0x1e780154
++ str r1, [r0]
++ ldr r0, =0x1e780158
++ str r2, [r0]
++ ldr r0, =0x1e780160
++ str r1, [r0]
++ ldr r0, =0x1e780164
++ str r1, [r0]
++ ldr r0, =0x1e780168
++ str r1, [r0]
++ ldr r0, =0x1e780170
++ str r1, [r0]
++ ldr r0, =0x1e780174
++ str r1, [r0]
++ ldr r0, =0x1e780178
++ str r1, [r0]
++ ldr r0, =0x1e78017c
++ str r1, [r0]
++ ldr r0, =0x1e780180
++ str r1, [r0]
++ ldr r0, =0x1e780184
++ str r1, [r0]
++ ldr r0, =0x1e780188
++ str r2, [r0]
++ ldr r0, =0x1e780190
++ str r1, [r0]
++ ldr r0, =0x1e780194
++ str r1, [r0]
++ ldr r0, =0x1e780198
++ str r1, [r0]
++ ldr r0, =0x1e7801d0
++ str r1, [r0]
++ ldr r0, =0x1e7801d4
++ str r1, [r0]
++
++ ldr r0, =0x1e780204 @ clear SGPIOM register reset by PRST_N
++ str r1, [r0]
++ ldr r0, =0x1e780208
++ str r1, [r0]
++ ldr r0, =0x1e78020c
++ str r1, [r0]
++ ldr r0, =0x1e780210
++ str r1, [r0]
++ ldr r0, =0x1e780214
++ str r2, [r0]
++ ldr r0, =0x1e780220
++ str r1, [r0]
++ ldr r0, =0x1e780224
++ str r1, [r0]
++ ldr r0, =0x1e780228
++ str r1, [r0]
++ ldr r0, =0x1e78022c
++ str r1, [r0]
++ ldr r0, =0x1e780230
++ str r2, [r0]
++ ldr r0, =0x1e78023c
++ str r1, [r0]
++ ldr r0, =0x1e780240
++ str r1, [r0]
++ ldr r0, =0x1e780244
++ str r1, [r0]
++ ldr r0, =0x1e780248
++ str r1, [r0]
++ ldr r0, =0x1e78024c
++ str r2, [r0]
++ ldr r0, =0x1e780254
++ ldr r3, =0x01000040
++ str r3, [r0]
++ ldr r0, =0x1e780258
++ str r1, [r0]
++ ldr r0, =0x1e78025c
++ str r1, [r0]
++ ldr r0, =0x1e780260
++ str r1, [r0]
++
++ ldr r0, =0x1e780300 @ clear SGPIOS register reset by PRST_N
++ str r1, [r0]
++ ldr r0, =0x1e780304
++ str r1, [r0]
++ ldr r0, =0x1e780308
++ str r1, [r0]
++ ldr r0, =0x1e78030c
++ str r1, [r0]
++ ldr r0, =0x1e780310
++ str r1, [r0]
++ ldr r0, =0x1e780314
++ str r1, [r0]
++ ldr r0, =0x1e780318
++ str r2, [r0]
++ ldr r0, =0x1e78031c
++ str r2, [r0]
++ ldr r0, =0x1e780320
++ str r2, [r0]
++
++platform_exit3:
++
++/******************************************************************************
++ SPI Timing Calibration, not applicable to AST2300 series
++ ******************************************************************************/
++ ldr r0, =0x1e6e207c @ Check Revision ID
++ ldr r1, [r0]
++ mov r1, r1, lsr #24
++ cmp r1, #0x02
++ blt platform_exit4 @ not match AST2400 or later
++
++ ldr r0, =0x1e6e2070 @ Check SPI flash
++ ldr r1, [r0]
++ and r1, r1, #0x03
++ cmp r1, #0x02
++ bne platform_exit4
++
++ mov r2, #0x0
++ mov r6, #0x0
++ mov r7, #0x0
++ init_spi_checksum
++spi_checksum_wait_0:
++ ldr r1, [r0]
++ tst r1, r2
++ beq spi_checksum_wait_0
++ ldr r0, =0x1e620090
++ ldr r5, [r0] @ record golden checksum
++ ldr r0, =0x1e620080
++ mov r1, #0x0
++ str r1, [r0]
++
++ ldr r0, =0x1e620010 @ set to fast read mode
++ ldr r1, =0x000B0041
++ str r1, [r0]
++
++ ldr r6, =0x00F7E6D0 @ Init spiclk loop
++ mov r8, #0x0 @ Init delay record
++
++spi_cbr_next_clkrate:
++ mov r6, r6, lsr #0x4
++ cmp r6, #0x0
++ beq spi_cbr_end
++
++ mov r7, #0x0 @ Init delay loop
++ mov r8, r8, lsl #4
++
++spi_cbr_next_delay_s:
++ mov r2, #0x8
++ init_spi_checksum
++spi_checksum_wait_1:
++ ldr r1, [r0]
++ tst r1, r2
++ beq spi_checksum_wait_1
++ ldr r0, =0x1e620090
++ ldr r2, [r0] @ read checksum
++ ldr r0, =0x1e620080
++ mov r1, #0x0
++ str r1, [r0]
++ cmp r2, r5
++ bne spi_cbr_next_delay_e
++
++ mov r2, #0x0
++ init_spi_checksum
++spi_checksum_wait_2:
++ ldr r1, [r0]
++ tst r1, r2
++ beq spi_checksum_wait_2
++ ldr r0, =0x1e620090
++ ldr r2, [r0] @ read checksum
++ ldr r0, =0x1e620080
++ mov r1, #0x0
++ str r1, [r0]
++ cmp r2, r5
++ bne spi_cbr_next_delay_e
++
++ orr r8, r8, r7 @ record passed delay
++ b spi_cbr_next_clkrate
++
++spi_cbr_next_delay_e:
++ add r7, r7, #0x1
++ cmp r7, #0x6
++ blt spi_cbr_next_delay_s
++ b spi_cbr_next_clkrate
++
++spi_cbr_end:
++ ldr r0, =0x1e620094
++ str r8, [r0]
++ ldr r0, =0x1e620010
++ mov r1, #0x0
++ str r1, [r0]
++
++platform_exit4:
++
++ /* restore lr */
++ mov lr, r4
++
++ /* back to arch calling code */
++ mov pc, lr
+diff --git a/board/aspeed/ast2400/rc4.c b/board/aspeed/ast2400/rc4.c
+new file mode 100755
+index 0000000..32e0ffa
+--- /dev/null
++++ b/board/aspeed/ast2400/rc4.c
+@@ -0,0 +1,68 @@
++/*
++ * 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
++ */
++struct rc4_state
++{
++ int x, y, m[256];
++};
++
++void rc4_setup( struct rc4_state *s, unsigned char *key, int length )
++{
++ int i, j, k, *m, a;
++
++ s->x = 0;
++ s->y = 0;
++ m = s->m;
++
++ for( i = 0; i < 256; i++ )
++ {
++ m[i] = i;
++ }
++
++ j = k = 0;
++
++ for( i = 0; i < 256; i++ )
++ {
++ a = m[i];
++ j = (unsigned char) ( j + a + key[k] );
++ m[i] = m[j]; m[j] = a;
++ if( ++k >= length ) k = 0;
++ }
++}
++
++void rc4_crypt( struct rc4_state *s, unsigned char *data, int length )
++{
++ int i, x, y, *m, a, b;
++
++ x = s->x;
++ y = s->y;
++ m = s->m;
++
++ for( i = 0; i < length; i++ )
++ {
++ x = (unsigned char) ( x + 1 ); a = m[x];
++ y = (unsigned char) ( y + a );
++ m[x] = b = m[y];
++ m[y] = a;
++ data[i] ^= m[(unsigned char) ( a + b )];
++ }
++
++ s->x = x;
++ s->y = y;
++}
++
++void rc4_crypt_sw(unsigned char *data, int ulMsgLength, unsigned char *rc4_key, unsigned long ulKeyLength )
++{
++ struct rc4_state s;
++
++ rc4_setup( &s, rc4_key, ulKeyLength );
++
++ rc4_crypt( &s, data, ulMsgLength );
++}
+diff --git a/board/aspeed/ast2400/regtest.c b/board/aspeed/ast2400/regtest.c
+new file mode 100755
+index 0000000..1cd75ae
+--- /dev/null
++++ b/board/aspeed/ast2400/regtest.c
+@@ -0,0 +1,91 @@
++/*
++ * 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
++ */
++
++/*
++ * Diagnostics support
++ */
++#include <common.h>
++#include <command.h>
++#include <post.h>
++#include "slt.h"
++
++#if ((CFG_CMD_SLT & CFG_CMD_REGTEST) && defined(CONFIG_SLT))
++#include "regtest.h"
++
++int do_regtest (void)
++{
++ _SOCRegTestInfo *pjSOCRegInfo;
++ _SOCRegTestTbl *pjRegTable;
++ unsigned long ulRegBase;
++ unsigned long ulIndex, ulBack, ulAND, ulMask, ulData, ulTemp;
++ unsigned long Flags = 0;
++
++ /* unlock reg */
++ *(unsigned long *) (0x1e600000) = 0xaeed1a03; /* AHBC */
++ *(unsigned long *) (0x1e6e0000) = 0xfc600309; /* MMC */
++ *(unsigned long *) (0x1e6e2000) = 0x1688a8a8; /* SCU */
++
++ /* SCU */
++
++ /* do test */
++ pjSOCRegInfo = SOCRegTestInfo;
++ while (strcmp(pjSOCRegInfo->jName, "END"))
++ {
++ /* Reg. Test Start */
++ ulRegBase = pjSOCRegInfo->ulRegOffset;
++ pjRegTable = pjSOCRegInfo->pjTblIndex;
++
++ while (pjRegTable->ulIndex != 0xFFFFFFFF)
++ {
++ ulIndex = ulRegBase + pjRegTable->ulIndex;
++
++ ulBack = *(unsigned long *) (ulIndex);
++
++ ulMask = pjRegTable->ulMask;
++ ulAND = ~pjRegTable->ulMask;
++
++ ulData = 0xFFFFFFFF & pjRegTable->ulMask;
++ *(unsigned long *) (ulIndex) = ulData;
++ ulTemp = *(volatile unsigned long *) (ulIndex) & pjRegTable->ulMask;
++ if (ulData != ulTemp)
++ {
++ Flags |= pjSOCRegInfo->ulFlags;
++ printf("[DBG] RegTest: Failed Index:%x, Data:%x, Temp:%x \n", ulIndex, ulData, ulTemp);
++ }
++
++ ulData = 0x00000000 & pjRegTable->ulMask;
++ *(unsigned long *) (ulIndex) = ulData;
++ ulTemp = *(volatile unsigned long *) (ulIndex) & pjRegTable->ulMask;
++ if (ulData != ulTemp)
++ {
++ Flags |= pjSOCRegInfo->ulFlags;
++ printf("[DBG] RegTest: Failed Index:%x, Data:%x, Temp:%x \n", ulIndex, ulData, ulTemp);
++ }
++
++ *(unsigned long *) (ulIndex) = ulBack;
++
++ pjRegTable++;
++
++ } /* Individual Reg. Test */
++
++ if (Flags & pjSOCRegInfo->ulFlags)
++ printf("[INFO] RegTest: %s Failed \n", pjSOCRegInfo->jName);
++
++ pjSOCRegInfo++;
++
++ } /* Reg. Test */
++
++ return Flags;
++
++}
++
++#endif /* CONFIG_SLT */
+diff --git a/board/aspeed/ast2400/regtest.h b/board/aspeed/ast2400/regtest.h
+new file mode 100755
+index 0000000..49a360e
+--- /dev/null
++++ b/board/aspeed/ast2400/regtest.h
+@@ -0,0 +1,255 @@
++/*
++ * 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
++ */
++typedef struct {
++ unsigned long ulIndex;
++ unsigned long ulMask;
++} _SOCRegTestTbl;
++
++typedef struct {
++ unsigned char jName[10];
++ unsigned long ulRegOffset;
++ _SOCRegTestTbl *pjTblIndex;
++ unsigned long ulFlags;
++} _SOCRegTestInfo;
++
++_SOCRegTestTbl SMCRegTestTbl[] = {
++ {0x00000000, 0x00001FF3},
++ {0x00000004, 0xFFFFFFFF},
++ {0x00000008, 0x0FFF17FF},
++ {0x0000000C, 0xFFFFFFFF},
++ {0x00000010, 0xFF5FFFF3},
++ {0x00000018, 0x0FFFFFFF},
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl AHBCRegTestTbl[] = {
++ {0x00000080, 0x0000FFFE},
++ {0x00000088, 0x01000000},
++ {0x0000008c, 0x00000031},
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl MICRegTestTbl[] = {
++/*
++ {0x00000000, 0x0FFFFFF8},
++ {0x00000004, 0x0FFFFFF8},
++ {0x00000008, 0x0000FFFF},
++ {0x0000000C, 0x0FFFF000},
++ {0x00000010, 0xFFFFFFFF},
++*/
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl MAC1RegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl MAC2RegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl USB2RegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl VICRegTestTbl[] = {
++ {0x0000000C, 0xFFFFFFFF},
++ {0x00000024, 0xFFFFFFFF},
++ {0x00000028, 0xFFFFFFFF},
++ {0x0000002C, 0xFFFFFFFF},
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl MMCRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl USB11RegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl SCURegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl HASERegTestTbl[] = {
++ {0x00000000, 0x0FFFFFF8},
++ {0x00000004, 0x0FFFFFF8},
++ {0x00000008, 0x0FFFFFF8},
++ {0x0000000C, 0x0FFFFFF8},
++ //{0x00000010, 0x00001FFF},
++ {0x00000020, 0x0FFFFFF8},
++ {0x00000024, 0x0FFFFFF8},
++ {0x00000028, 0x0FFFFFc0},
++ {0x0000002C, 0x0FFFFFFF},
++ //{0x00000030, 0x000003FF},
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl I2SRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl CRTRegTestTbl[] = {
++/*
++ {0x00000000, 0x001F3703},
++ {0x00000004, 0x0000FFC1},
++*/
++ {0x00000010, 0x0FFF0FFF},
++ {0x00000014, 0x0FFF0FFF},
++ {0x00000018, 0x07FF07FF},
++ {0x0000001C, 0x07FF07FF},
++ {0x00000020, 0x0FFFFFF8},
++ {0x00000024, 0x07FF3FF8},
++/*
++ {0x00000028, 0x003F003F},
++ {0x00000030, 0x003F003F},
++ {0x00000034, 0x0FFF0FFF},
++ {0x00000038, 0x0FFFFFF8},
++*/
++ {0x00000040, 0x0FFF0FFF},
++ {0x00000044, 0x07FF07FF},
++ {0x00000048, 0x0FFFFFF8},
++ {0x0000004C, 0x00FF07F8},
++ {0x00000050, 0x000F0F0F},
++/*
++ {0x00000060, 0x001F3703},
++ {0x00000064, 0x0000FFC1},
++*/
++ {0x00000070, 0x0FFF0FFF},
++ {0x00000074, 0x0FFF0FFF},
++ {0x00000078, 0x07FF07FF},
++ {0x0000007C, 0x07FF07FF},
++ {0x00000080, 0x0FFFFFF8},
++ {0x00000084, 0x07FF3FF8},
++/*
++ {0x00000088, 0x003F003F},
++ {0x00000090, 0x003F003F},
++ {0x00000094, 0x0FFF0FFF},
++ {0x00000098, 0x0FFFFFF8},
++*/
++ {0x000000A0, 0x0FFF0FFF},
++ {0x000000A4, 0x07FF07FF},
++ {0x000000A8, 0x0FFFFFF8},
++ {0x000000AC, 0x00FF07F8},
++ {0x000000B0, 0x000F0F0F},
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl VIDEORegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl A2PRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl MDMARegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl M2DRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl GPIORegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl RTCRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl TIMERRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl UART1RegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl UART2RegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl WDTRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl PWMRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl VUART1RegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl VUART2RegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl LPCRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl I2CRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl PECIRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl PCIARegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++_SOCRegTestTbl PCIRegTestTbl[] = {
++ {0xFFFFFFFF, 0xFFFFFFFF},
++};
++
++
++/* Test List */
++_SOCRegTestInfo SOCRegTestInfo[] = {
++ /* Test Name, Reg. Offset, Test Table, Error Code */
++ { "SMCREG", 0x16000000, SMCRegTestTbl, 0x00000001},
++ { "AHBCREG", 0x1e600000, AHBCRegTestTbl, 0x00000002},
++ { "MICREG", 0x1e640000, MICRegTestTbl, 0x00000004},
++ { "MAC1REG", 0x1e660000, MAC1RegTestTbl, 0x00000008},
++ { "MAC2REG", 0x1e680000, MAC2RegTestTbl, 0x00000010},
++ { "USB2REG", 0x1e6a0000, USB2RegTestTbl, 0x00000020},
++ { "VICREG", 0x1e6c0000, VICRegTestTbl, 0x00000040},
++ { "MMCREG", 0x1e6e0000, MMCRegTestTbl, 0x00000080},
++ { "USB11REG", 0x1e6e1000, USB11RegTestTbl, 0x00000100},
++ { "SCUREG", 0x1e6e2000, SCURegTestTbl, 0x00000200},
++ { "HASEREG", 0x1e6e3000, HASERegTestTbl, 0x00000400},
++ { "I2SREG", 0x1e6e5000, I2SRegTestTbl, 0x00000800},
++ { "CRTREG", 0x1e6e6000, CRTRegTestTbl, 0x00001000},
++ { "VIDEOREG", 0x1e700000, VIDEORegTestTbl, 0x00002000},
++ { "A2PREG", 0x1e720000, A2PRegTestTbl, 0x00004000},
++ { "MDMAREG", 0x1e740000, MDMARegTestTbl, 0x00008000},
++ { "2DREG", 0x1e760000, M2DRegTestTbl, 0x00010000},
++ { "GPIOREG", 0x1e780000, GPIORegTestTbl, 0x00020000},
++ { "RTCREG", 0x1e781000, RTCRegTestTbl, 0x00040000},
++ { "TIMERREG", 0x1e782000, TIMERRegTestTbl, 0x00080000},
++ { "UART1REG", 0x1e783000, UART1RegTestTbl, 0x00100000},
++ { "UART2REG", 0x1e784000, UART2RegTestTbl, 0x00200000},
++ { "WDTREG", 0x1e785000, WDTRegTestTbl, 0x00400000},
++ { "PWMREG", 0x1e786000, PWMRegTestTbl, 0x00800000},
++ {"VUART1REG", 0x1e787000, VUART1RegTestTbl, 0x01000000},
++ {"VUART2REG", 0x1e788000, VUART2RegTestTbl, 0x02000000},
++ { "LPCREG", 0x1e789000, LPCRegTestTbl, 0x04000000},
++ { "I2CREG", 0x1e78A000, I2CRegTestTbl, 0x08000000},
++ { "PECIREG", 0x1e78B000, PECIRegTestTbl, 0x10000000},
++ { "PCIAREG", 0x1e78C000, PCIARegTestTbl, 0x20000000},
++ { "PCIREG", 0x60000000, PCIRegTestTbl, 0x40000000},
++ { "END", 0xffffffff, NULL, 0xffffffff}
++};
+diff --git a/board/aspeed/ast2400/slt.c b/board/aspeed/ast2400/slt.c
+new file mode 100755
+index 0000000..3283d34
+--- /dev/null
++++ b/board/aspeed/ast2400/slt.c
+@@ -0,0 +1,105 @@
++/*
++ * 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
++ */
++
++/*
++ * Diagnostics support
++ */
++#include <common.h>
++#include <command.h>
++#include <post.h>
++#include "slt.h"
++
++#if defined (CONFIG_SLT)
++
++int do_slt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
++{
++ int flags = 0;
++ int loop = 1;
++
++ if (argc > 1) {
++ loop = simple_strtoul(argv[1], NULL, 10);
++ }
++
++ do {
++
++do_slt_start:
++ /* Reg. Test */
++#if (CFG_CMD_SLT & CFG_CMD_REGTEST)
++ if (do_regtest())
++ {
++ flags |= FLAG_REGTEST_FAIL;
++ printf("[INFO] RegTest Failed \n");
++ }
++ else
++ printf("[INFO] RegTest Passed \n");
++#endif
++#if (CFG_CMD_SLT & CFG_CMD_MACTEST)
++ if (do_mactest())
++ {
++ flags |= FLAG_MACTEST_FAIL;
++ printf("[INFO] MACTest Failed \n");
++ }
++ else
++ printf("[INFO] MACTest Passed \n");
++#endif
++#if (CFG_CMD_SLT & CFG_CMD_VIDEOTEST)
++ if (do_videotest())
++ {
++ flags |= FLAG_VIDEOTEST_FAIL;
++ printf("[INFO] VideoTest Failed \n");
++ }
++ else
++ printf("[INFO] VideoTest Passed \n");
++#endif
++#if (CFG_CMD_SLT & CFG_CMD_HACTEST)
++ if (do_hactest())
++ {
++ flags |= FLAG_HACTEST_FAIL;
++ printf("[INFO] HACTest Failed \n");
++ }
++ else
++ printf("[INFO] HACTest Passed \n");
++#endif
++#if (CFG_CMD_SLT & CFG_CMD_MICTEST)
++ if (do_mictest())
++ {
++ flags |= FLAG_MICTEST_FAIL;
++ printf("[INFO] MICTest Failed \n");
++ }
++ else
++ printf("[INFO] MICTest Passed \n");
++#endif
++
++ /* Summary */
++ if (flags)
++ printf ("[INFO] SLT Test Failed!! \n");
++ else
++ printf ("[INFO] SLT Test Passed!! \n");
++
++ if (loop == 0) /* infinite */
++ goto do_slt_start;
++ else
++ loop--;
++
++ } while (loop);
++
++ return 0;
++}
++/***************************************************/
++
++U_BOOT_CMD(
++ slt, CONFIG_SYS_MAXARGS, 0, do_slt,
++ "slt - slt test program \n",
++ NULL
++);
++
++#endif /* CONFIG_SLT */
+diff --git a/board/aspeed/ast2400/slt.h b/board/aspeed/ast2400/slt.h
+new file mode 100755
+index 0000000..4e650bc
+--- /dev/null
++++ b/board/aspeed/ast2400/slt.h
+@@ -0,0 +1,29 @@
++/*
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#define CFG_CMD_REGTEST 0x00000001
++#define CFG_CMD_MACTEST 0x00000002
++#define CFG_CMD_VIDEOTEST 0x00000004
++#define CFG_CMD_HACTEST 0x00000008
++#define CFG_CMD_MICTEST 0x00000010
++#define CFG_CMD_OSDTEST 0x00000020
++#define CFG_CMD_2DTEST 0x00000040
++#define CFG_CMD_HWCTEST 0x00000080
++
++#define FLAG_REGTEST_FAIL 0x00000001
++#define FLAG_MACTEST_FAIL 0x00000002
++#define FLAG_VIDEOTEST_FAIL 0x00000004
++#define FLAG_HACTEST_FAIL 0x00000008
++#define FLAG_MICTEST_FAIL 0x00000010
++#define FLAG_OSDTEST_FAIL 0x00000020
++#define FLAG_2DTEST_FAIL 0x00000040
++#define FLAG_HWCTEST_FAIL 0x00000080
++
++
+diff --git a/board/aspeed/ast2400/type.h b/board/aspeed/ast2400/type.h
+new file mode 100755
+index 0000000..f57ee5a
+--- /dev/null
++++ b/board/aspeed/ast2400/type.h
+@@ -0,0 +1,116 @@
++/*
++ * 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 _TYPE_H_
++#define _TYPE_H_
++
++ typedef unsigned char BOOL;
++ typedef unsigned char UINT8;
++ typedef unsigned short UINT16;
++ typedef unsigned int UINT32;
++
++ #define FLONG unsigned long
++ #define BYTE unsigned char
++ #define INT int
++ #define VOID void
++ #define BOOLEAN unsigned short
++ #define ULONG unsigned long
++ #define USHORT unsigned short
++ #define UCHAR unsigned char
++ #define CHAR char
++ #define LONG long
++ #define PUCHAR UCHAR *
++ #define PULONG ULONG *
++
++ #define FAIL 1
++
++ #define intfunc int386
++
++ #define outdwport outpd
++ #define indwport inpd
++ #define outport outp
++ #define inport inp
++
++ //#define NULL ((void *)0)
++ #define FALSE 0
++ #define TRUE 1
++
++ #define ReadMemoryBYTE(baseaddress,offset) *(BYTE *)((ULONG)(baseaddress)+(ULONG)(offset))
++ #define ReadMemoryLong(baseaddress,offset) *(ULONG *)((ULONG)(baseaddress)+(ULONG)(offset))
++ #define ReadMemoryShort(baseaddress,offset) *(USHORT *)((ULONG)(baseaddress)+(ULONG)(offset))
++ #define WriteMemoryBYTE(baseaddress,offset,data) *(BYTE *)((ULONG)(baseaddress)+(ULONG)(offset)) = (BYTE)(data)
++ #define WriteMemoryLong(baseaddress,offset,data) *(ULONG *)((ULONG)(baseaddress)+(ULONG)(offset))=(ULONG)(data)
++ #define WriteMemoryShort(baseaddress,offset,data) *(USHORT *)((ULONG)(baseaddress)+(ULONG)(offset))=(USHORT)(data)
++ #define WriteMemoryLongWithANDData(baseaddress, offset, anddata, data) *(ULONG *)((ULONG)(baseaddress)+(ULONG)(offset)) = *(ULONG *)((ULONG)(baseaddress)+(ULONG)(offset)) & (ULONG)(anddata) | (ULONG)(data)
++
++ #define WriteMemoryLongWithMASK(baseaddress, offset, data, mask) \
++ *(volatile ULONG *)((ULONG)(baseaddress)+(ULONG)(offset)) = *(volatile ULONG *)(((ULONG)(baseaddress)+(ULONG)(offset)) & (ULONG)(~(mask))) | ((ULONG)(data) & (ULONG)(mask))
++
++ #define ReadMemoryLongHost(baseaddress,offset) *(volatile ULONG *)((ULONG)(baseaddress)+(ULONG)(offset))
++ #define WriteMemoryLongHost(baseaddress,offset,data) *(volatile ULONG *)((ULONG)(baseaddress)+(ULONG)(offset))=(ULONG)(data)
++ #define WriteMemoryBYTEHost(baseaddress,offset,data) *(volatile BYTE *)((ULONG)(baseaddress)+(ULONG)(offset)) = (BYTE)(data)
++#define WriteMemoryLongWithMASKHost(baseaddress, offset, data, mask) *(volatile ULONG *)((ULONG)(baseaddress)+(ULONG)(offset)) = (((*(volatile ULONG *)((ULONG)(baseaddress)+(ULONG)(offset)))&(~mask)) | (ULONG)((data)&(mask)))
++
++ #define ReadMemoryLongClient(baseaddress,offset) *(volatile ULONG *)((ULONG)(baseaddress)+(ULONG)(offset))
++ #define WriteMemoryLongClient(baseaddress,offset,data) *(volatile ULONG *)((ULONG)(baseaddress)+(ULONG)(offset))=(ULONG)(data)
++ #define WriteMemoryBYTEClient(baseaddress,offset,data) *(volatile BYTE *)((ULONG)(baseaddress)+(ULONG)(offset)) = (BYTE)(data)
++#define WriteMemoryLongWithMASKClient(baseaddress, offset, data, mask) *(volatile ULONG *)((ULONG)(baseaddress)+(ULONG)(offset)) = (((*(volatile ULONG *)((ULONG)(baseaddress)+(ULONG)(offset)))&(~mask)) | (ULONG)((data)&(mask)))
++
++#ifdef BUF_GLOBALS
++#define BUF_EXT
++#else
++#define BUF_EXT extern
++#endif
++
++BUF_EXT ULONG g_CAPTURE_VIDEO1_BUF1_ADDR; /* VIDEO1_BUF_1_ADDR*/
++BUF_EXT ULONG g_CAPTURE_VIDEO1_BUF2_ADDR; /* VIDEO1_BUF_2_ADDR*/
++BUF_EXT ULONG g_VIDEO1_COMPRESS_BUF_ADDR; /* Encode destination address */
++BUF_EXT ULONG g_VIDEO1_CRC_BUF_ADDR;
++BUF_EXT ULONG g_VIDEO1_FLAG_BUF_ADDR;
++BUF_EXT ULONG g_VIDEO1_RC4_BUF_ADDR;
++
++
++BUF_EXT ULONG g_CAPTURE_VIDEO2_BUF1_ADDR;
++BUF_EXT ULONG g_CAPTURE_VIDEO2_BUF2_ADDR;
++BUF_EXT ULONG g_VIDEO2_COMPRESS_BUF_ADDR;
++BUF_EXT ULONG g_VIDEO2_CRC_BUF_ADDR;
++BUF_EXT ULONG g_VIDEO2_FLAG_BUF_ADDR;
++BUF_EXT ULONG g_VIDEO2_RC4_BUF_ADDR;
++
++BUF_EXT ULONG g_VIDEO1_DECODE_BUF_1_ADDR;
++BUF_EXT ULONG g_VIDEO1_DECODE_BUF_2_ADDR;
++BUF_EXT ULONG g_VIDEO1_DECOMPRESS_BUF_ADDR;
++BUF_EXT ULONG g_VIDEO1_DECODE_RC4_BUF_ADDR;
++
++BUF_EXT ULONG g_VIDEO2_DECODE_BUF_1_ADDR;
++BUF_EXT ULONG g_VIDEO2_DECODE_BUF_2_ADDR;
++BUF_EXT ULONG g_VIDEO2_DECOMPRESS_BUF_ADDR;
++BUF_EXT ULONG g_VIDEO2_DECODE_RC4_BUF_ADDR;
++
++BUF_EXT ULONG g_CAPTURE_VIDEOM_BUF1_ADDR;
++BUF_EXT ULONG g_CAPTURE_VIDEOM_BUF2_ADDR;
++BUF_EXT ULONG g_VIDEOM_COMPRESS_BUF_ADDR;
++BUF_EXT ULONG g_VIDEOM_FLAG_BUF_ADDR;
++BUF_EXT ULONG g_VIDEOM_RC4_BUF_ADDR;
++
++BUF_EXT ULONG g_VIDEOM_DECODE_BUF_1_ADDR;
++BUF_EXT ULONG g_VIDEOM_DECODE_BUF_2_ADDR;
++BUF_EXT ULONG g_VIDEOM_DECOMPRESS_BUF_ADDR;
++BUF_EXT ULONG g_VIDEOM_DECODE_RC4_BUF_ADDR;
++
++#ifdef WIN_GLOBALS
++#define WIN_EXT
++#else
++#define WIN_EXT extern
++#endif
++
++WIN_EXT USHORT g_DefWidth, g_DefHeight;
++
++#endif
+diff --git a/board/aspeed/ast2400/u-boot.lds b/board/aspeed/ast2400/u-boot.lds
+new file mode 100755
+index 0000000..ff0fe22
+--- /dev/null
++++ b/board/aspeed/ast2400/u-boot.lds
+@@ -0,0 +1,56 @@
++/*
++ * (C) Copyright 2004
++ * Wolfgang Denk, DENX Software Engineering, <wg@denx.de>
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
++/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
++OUTPUT_ARCH(arm)
++ENTRY(_start)
++SECTIONS
++{
++ . = 0x00000000;
++
++ . = ALIGN(4);
++ .text :
++ {
++ cpu/arm926ejs/start.o (.text)
++ *(.text)
++ }
++
++ . = ALIGN(4);
++ .rodata : { *(.rodata) }
++
++ . = ALIGN(4);
++ .data : { *(.data) }
++
++ . = ALIGN(4);
++ .got : { *(.got) }
++
++ __u_boot_cmd_start = .;
++ .u_boot_cmd : { *(.u_boot_cmd) }
++ __u_boot_cmd_end = .;
++
++ . = ALIGN(4);
++ __bss_start = .;
++ .bss : { *(.bss) }
++ _end = .;
++}
+diff --git a/board/aspeed/ast2400/vdef.h b/board/aspeed/ast2400/vdef.h
+new file mode 100755
+index 0000000..3c99b7e
+--- /dev/null
++++ b/board/aspeed/ast2400/vdef.h
+@@ -0,0 +1,500 @@
++/*
++ * 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 _VDEF_H_
++#define _VDEF_H_
++
++#define VIDEO1 0
++#define VIDEO1_ON 0x01
++#define VIDEO2 1
++#define VIDEO2_ON 0x02
++
++#define VIDEOM_ON 0x04
++#define VIDEOM 2
++
++#define CRT_1 0
++#define CRT_1_ON 0x01
++#define CRT_2 1
++#define CRT_2_ON 0x02
++
++#define SINGLE_CODEC_SINGLE_CAPTURE 0
++#define AUTO_CODEC_SINGLE_CAPTURE 2
++#define AUTO_CODEC_AUTO_CAPTURE 3
++
++#define MAC1_BASE 0x1E660000
++#define APB_BRIDGE_1_BASE 0x1E6E0000
++#define VIDEO_REG_BASE 0x1E700000
++#define APB_BRIDGE_2_BASE 0x1E780000
++
++#define DRAM_INIT_BASE 0x1E6E0000
++
++#define SDRAM_PROTECT_REG 0x00
++ #define SDRAM_WRITE_DISABLE 0
++ #define SDRAM_WRITE_ENABLE 1
++
++#define SCU_BASE 0x1E6E0000
++#define SCU_OFFSET 0x2000
++
++#define VIC_BASE 0x1E6C0000
++ #define VIDEO_INT_BIT 7
++
++#define IRQ_STATUS_REG 0x00
++#define RAW_INT_STATUS_REG 0x08
++#define INT_SEL_REG 0x0C
++ #define FIQ_INT 1
++ #define IRQ_INT 0
++#define INT_EN_REG 0x10
++#define INT_EN_CLEAR_REG 0x14
++#define INT_SOFT_REG 0x18
++#define INT_SOFT_CLEAR_REG 0x1C
++#define INT_SENSE_REG 0x24
++ #define LEVEL_SENSE 1
++ #define EDGE_SENSE 0
++#define INT_EVENT_REG 0x2C
++ #define HIGH_LEVEL_SENSE 1
++ #define LOW_LEVEL_SENSE 0
++
++#define SCU_HW_TRAPPING_REG 0x70 + SCU_OFFSET
++ #define CLIENT_MODE_EN_BIT 18
++ #define CLIENT_MODE_EN_MASK 0x00040000
++ #define BE_HOST_CHIP 0
++ #define BE_CLIENT_CHIP 1
++
++#define SCU_ULOCK_KEY 0x1688A8A8
++
++#define SCU_PROTECT_REG 0x00 + SCU_OFFSET
++ #define SCU_WRITE_DISABLE 0
++ #define SCU_WRITE_ENABLE 1
++
++#define SCU_CONTROL_REG 0x04 + SCU_OFFSET
++ #define VIDEO_ENGINE_RESET 0x00000040
++ #define VIDEO_ENGINE_RESET_BIT 6
++ #define VIDEO_ENGINE_RESET_MASK 0x00000040
++ #define VIDEO_RESET_EN 1
++ #define VIDEO_RESET_OFF 0
++
++#define SCU_CLOCK_SELECTION_REG 0x08 + SCU_OFFSET
++ #define PORTA_CLOCK_DELAY_MASK 7 << 8 //Video port A output clcok selection
++ #define PORTA_CLOCK_INV_DELAY_1NS 5 << 8 //Clock inversed and delay ~ 2ns
++ #define PORTA_CLOCK_INV_DELAY_2NS 6 << 8 //Clock inversed and delay ~ 3ns
++ #define PORTB_CLOCK_DELAY_MASK 7 << 12 //Video port B output clock delay
++ #define PORTB_CLOCK_INV_DELAY_1NS 5 << 12 //Clock inversed and delay ~ 3ns
++ #define PORTB_CLOCK_INV_DELAY_2NS 6 << 12 //Clock inversed and delay ~ 3ns
++ #define PORTB_CLOCK_SEL 1 << 15 //Video port B clock selection
++ #define PORTB_FROM_D1CLK 0 << 15
++ #define PORTB_FROM_D2CLK 1 << 15
++ #define ECLK_CLK_SEL_MASK (3 << 2)
++ #define ECLK_FROM_HPLL (1 << 2)
++
++ #define D2CLK_CLOCK_SELECTION 0x00020000
++ #define D2CLK_CLOCK_SELECTION_BIT 17
++ #define D2CLK_CLOCK_SELECTION_MASK 0x00060000
++ #define NORMAL_CRT1 0
++ #define V1CLK_VIDEO1 2
++ #define V1CLK_VIDEO2 3
++
++#define SCU_CLOCK_STOP_REG 0x0C + SCU_OFFSET
++ #define EN_ECLK 0 << 0 //Enable ECLK (For Video Engine)
++ #define STOP_ECLK_BIT 0
++ #define STOP_ECLK_MASK 1 << 0
++ #define EN_V1CLK 0 << 3 //Enable V1CLK (For Video Capture #1)
++ #define STOP_V1CLK_BIT 3
++ #define STOP_V1CLK_MASK 1 << 3
++ #define EN_D1CLK 0 << 10 //Enable D1CLK (For CRT1)
++ #define STOP_D1CLK_BIT 10
++ #define STOP_D1CLK_MASK 1 << 10
++ #define EN_D2CLK 0 << 11 //Stop D2CLK (For CRT2)
++ #define STOP_D2CLK (1 << 11)
++ #define STOP_D2CLK_BIT 11
++ #define STOP_D2CLK_MASK 1 << 11
++ #define EN_V2CLK 0 << 12 //Stop V2CLK (For Video Capture #2)
++ #define STOP_V2CLK_BIT 12
++ #define STOP_V2CLK_MASK 1 << 12
++ #define STOP_HACE_BIT 13
++ #define EN_HACE (0 << 13)
++ #define STOP_HACE_MASK (1 << 13)
++ #define EN_I2SCLK 0 << 18
++ #define STOP_I2SCLK_MASK 1 << 18
++
++#define SCU_PIN_CTRL1_REG 0x74 + SCU_OFFSET
++ #define I2C_5_PIN_EN 1 << 12 //Enable I2C #5 PIN
++ #define I2C_5_PIN_OFF 0 << 12 //Disable I2C #5 PIN
++ #define I2C_5_PIN_MASK 1 << 12
++ #define VGA_PIN_OFF 0 << 15 //Enable VGA pins
++ #define VGA_PIN_MASK 1 << 15
++ #define VIDEO_PORTA_EN 1 << 16 //Enable Video port A control pins
++ #define VIDEO_PORTA_MASK 1 << 16
++ #define VIDEO_PORTB_EN 1 << 17 //Enable Video port B control pins
++ #define VIDEO_PORTB_MASK 1 << 17
++ #define VIDEO_VP1_EN 1 << 22 //Enable VP[11:0]
++ #define VIDEO_VP1_MASK 1 << 22
++ #define VIDEO_VP2_EN 1 << 23 //Enable VP[23:12]
++ #define VIDEO_VP2_MASK 1 << 23
++ #define I2S_PIN_EN 1 << 29 //Enable I2S function pins
++ #define I2S_PIN_MASK 1 << 29
++
++#define SCU_PIN_CTRL2_REG 0x78 + SCU_OFFSET
++ #define VIDEO_PORTA_SINGLE_EDGE_MASK 1 << 0
++ #define VIDEO_PORTA_SINGLE_EDGE 1 << 0 //Enable Video port A single mode
++ #define VIDEO_PORTA_DUAL_EDGE 0 << 0
++ #define VIDEO_PORTB_SINGLE_EDGE_MASK 1 << 1
++ #define VIDEO_PORTB_DUAL_EDGE 0 << 1
++ #define VIDEO_PORTB_SINGLE_EDGE 1 << 1 //Enable Video port B single mode
++
++#define SCU_M_PLL_PARAM_REG 0x20 + SCU_OFFSET
++
++#define DRAM_BASE 0x40000000
++
++#define INPUT_BITCOUNT_YUV444 4
++#define INPUT_BITCOUNT_YUV420 2
++
++/* HW comment value */
++//PASSWORD
++#define VIDEO_UNLOCK_KEY 0x1A038AA8
++#define SCU_UNLOCK_KEY 0x1688A8A8
++#define SDRAM_UNLOCK_KEY 0xFC600309
++
++
++//#define SAMPLE_RATE 12000000.0
++#ifdef OSC_NEW
++ #define SAMPLE_RATE 24576000.0
++#else
++ #define SAMPLE_RATE 24000000.0
++#endif
++
++#define MODEDETECTION_VERTICAL_STABLE_MAXIMUM 0x4
++#define MODEDETECTION_HORIZONTAL_STABLE_MAXIMUM 0x4
++#define MODEDETECTION_VERTICAL_STABLE_THRESHOLD 0x4
++#define MODEDETECTION_HORIZONTAL_STABLE_THRESHOLD 0x8
++
++#define MODEDETECTION_EDGE_PIXEL_THRES_DIGITAL 2
++#define MODEDETECTION_EDGE_PIXEL_THRES_ANALOGE 0x0A
++
++#define MODEDETECTION_OK 0
++#define MODEDETECTION_ERROR 1
++#define JUDGE_MODE_ERROR 2
++
++//I2C Loop Count
++#define LOOP_COUNT 1000
++#define CAN_NOT_FIND_DEVICE 1
++#define SET_I2C_DONE 0
++#define I2C_BASE 0xA000
++#define AC_TIMING 0x77743355
++
++//I2C channel and Devices
++#define I2C_VIDEO1_EEPROM 0x2
++#define I2C_VIDEO2_EEPROM 0x5
++#define I2C_VIDEO2_9883 0x4
++/*
++ULONG CAPTURE1_ADDRESS = 0x1000000;
++ULONG CAPTURE2_ADDRESS = 0x3000000;
++ULONG PASS1_ENCODE_SOURCE_ADDRESS = 0x1000000;
++ULONG PASS1_ENCODE_DESTINATION_ADDRESS = 0x2000000;
++ULONG Buffer1_DECODE_SOURCE_ADDRESS = 0x1000000;
++ULONG Buffer2_DECODE_SOURCE_ADDRESS = 0x1400000;
++ULONG PASS1_DECODE_DESTINATION_ADDRESS = 0x600000;
++ULONG CAPTURE_2ND_ADDRESS = 0x1800000;
++ULONG PASS1_2ND_ENCODE_SOURCE_ADDRESS = 0x1800000;
++ULONG PASS1_2ND_ENCODE_DESTINATION_ADDRESS = 0x2800000;
++ULONG PASS1_2ND_DECODE_SOURCE_ADDRESS = 0x1000000;
++ULONG PASS1_2ND_DECODE_DESTINATION_ADDRESS = 0x600000;
++ULONG PASS2_ENCODE_SOURCE_ADDRESS = 0x000000;
++ULONG PASS2_ENCODE_DESTINATION_ADDRESS = 0xC00000;
++ULONG PASS2_DECODE_SOURCE_ADDRESS = 0xC00000;
++ULONG PASS2_DECODE_DESTINATION_ADDRESS = 0x600000;
++ULNG PASS2_DECODE_REFERENCE_ADDRESS = 0x600000;
++*/
++
++typedef struct _CTL_REG_G {
++ ULONG CompressMode:1;
++ ULONG SkipEmptyFrame:1;
++ ULONG MemBurstLen:2;
++ ULONG LineBufEn:2;
++ ULONG Unused:26;
++} CTL_REG_G;
++
++
++typedef union _U_CTL_G {
++ ULONG Value;
++ CTL_REG_G CtlReg;
++} U_CTL_G;
++
++typedef struct _MODE_DETECTION_PARAM_REG {
++ ULONG Unused1:8;
++ ULONG EdgePixelThres:8;
++ ULONG VerStableMax:4;
++ ULONG HorStableMax:4;
++ ULONG VerDiffMax:4;
++ ULONG HorDiffMax:4;
++} MODE_DETECTION_PARAM_REG;
++
++typedef struct _CRC_PRI_PARAM_REG {
++ ULONG Enable:1;
++ ULONG HighBitOnly:1;
++ ULONG SkipCountMax:6;
++ ULONG PolyLow:8;
++ ULONG PolyHigh:16;
++} CRC_PRI_PARAM_REG;
++
++typedef union _U_CRC_PRI_PARAM {
++ ULONG Value;
++ CRC_PRI_PARAM_REG CRCPriParam;
++} U_CRC_PRI_PARAM;
++
++typedef struct _CRC_SEC_PARAM_REG {
++ ULONG Unused1:8;
++ ULONG PolyLow:8;
++ ULONG PolyHigh:16;
++} CRC_SEC_PARAM_REG;
++
++typedef union _U_CRC_SEC_PARAM {
++ ULONG Value;
++ CRC_SEC_PARAM_REG CRCSecParam;
++} U_CRC_SEC_PARAM;
++
++typedef struct _GENERAL_INFO {
++ BYTE EnableVideoM;
++ BYTE CenterMode;
++ BYTE RC4NoResetFrame;
++ BYTE RC4TestMode;
++ U_CTL_G uCtlReg;
++ U_CRC_PRI_PARAM uCRCPriParam;
++ U_CRC_SEC_PARAM uCRCSecParam;
++} GENERAL_INFO, *PGENERAL_INFO;
++
++typedef struct _SEQ_CTL_REG {
++ ULONG Unused1:1;
++ ULONG Unused2:1;
++ ULONG Unused3:1;
++ ULONG CaptureAutoMode:1;
++ ULONG Unused4:1;
++ ULONG CodecAutoMode:1;
++ ULONG Unused5:1;
++ ULONG WatchDog:1;
++ ULONG CRTSel:1;
++ ULONG AntiTearing:1;
++ ULONG DataType:2;
++ ULONG Unused6:20;
++} SEQ_CTL_REG;
++
++typedef union _U_SEQ_CTL {
++ ULONG Value;
++ SEQ_CTL_REG SeqCtlReg;
++} U_SEQ_CTL;
++
++typedef struct _CTL_REG {
++ ULONG SrcHsync:1;
++ ULONG SrcVsync:1;
++ ULONG ExtSrc:1;
++ ULONG AnalongExtSrc:1;
++ ULONG IntTimingGen:1;
++ ULONG IntDataFrom:1;
++ ULONG WriteFmt:2;
++ ULONG VGACursor:1;
++ ULONG LinearMode:1;
++ ULONG ClockDelay:2;
++ ULONG CCIR656Src:1;
++ ULONG PortClock:1;
++ ULONG ExtPort:1;
++ ULONG Unused1:1;
++ ULONG FrameRate:8;
++ ULONG Unused2:8;
++} CTL_REG;
++
++typedef union _U_CTL {
++ ULONG Value;
++ CTL_REG CtlReg;
++} U_CTL_REG;
++
++typedef struct _TIMING_GEN_SETTING_H {
++ ULONG HDEEnd:13;
++ ULONG Unused1:3;
++ ULONG HDEStart:13;
++ ULONG Unused2:3;
++} TIMING_GEN_SETTING_H;
++
++typedef struct _TIMING_GEN_SETTING_V {
++ ULONG VDEEnd:13;
++ ULONG Unused1:3;
++ ULONG VDEStart:13;
++ ULONG Unused2:3;
++} TIMING_GEN_SETTING_V;
++
++typedef struct _BCD_CTL_REG {
++ ULONG Enable:1;
++ ULONG Unused1:15;
++ ULONG Tolerance:8;
++ ULONG Unused2:8;
++} BCD_CTL_REG;
++
++typedef union _U_BCD_CTL {
++ ULONG Value;
++ BCD_CTL_REG BCDCtlReg;
++} U_BCD_CTL;
++
++typedef struct _COMPRESS_WINDOW_REG {
++ ULONG VerLine:13;
++ ULONG Unused1:3;
++ ULONG HorPixel:13;
++ ULONG Unused2:3;
++} COMPRESS_WINDOW_REG;
++
++typedef struct _STREAM_BUF_SIZE {
++ ULONG PacketSize:3;
++ ULONG RingBufNum:2;
++ ULONG Unused1:11;
++ ULONG SkipHighMBThres:7;
++ ULONG SkipTestMode:2;
++ ULONG Unused2:7;
++} STREAM_BUF_SIZE;
++
++typedef union _U_STREAM_BUF {
++ ULONG Value;
++ STREAM_BUF_SIZE StreamBufSize;
++} U_STREAM_BUF;
++
++
++typedef struct _COMPRESS_CTL_REG {
++ ULONG JPEGOnly:1; /* True: Jpeg Only mode(Disable VQ), False:Jpeg and VQ mix mode */
++ ULONG En4VQ:1; /* True: 1, 2, 4 color mode, False: 1,2 color mode */
++ ULONG CodecMode:1; /* High and best Quantization encoding/decoding setting*/
++ ULONG DualQuality:1;
++ ULONG EnBest:1;
++ ULONG EnRC4:1;
++ ULONG NorChromaDCTTable:5;
++ ULONG NorLumaDCTTable:5;
++ ULONG EnHigh:1;
++ ULONG TestCtl:2;
++ ULONG UVFmt:1;
++ ULONG HufTable:2;
++ ULONG AlterValue1:5;
++ ULONG AlterValue2:5;
++} COMPRESS_CTL_REG;
++
++typedef union _U_COMPRESS_CTL {
++ ULONG Value;
++ COMPRESS_CTL_REG CompressCtlReg;
++} U_COMPRESS_CTL;
++
++typedef struct _QUANTI_TABLE_LOW_REG {
++ ULONG ChromaTable:5;
++ ULONG LumaTable:5;
++ ULONG Unused1:22;
++} QUANTI_TABLE_LOW_REG;
++
++typedef union _U_CQUANTI_TABLE_LOW {
++ ULONG Value;
++ QUANTI_TABLE_LOW_REG QTableLowReg;
++} U_QUANTI_TABLE_LOW;
++
++typedef struct _QUANTI_VALUE_REG {
++ ULONG High:15;
++ ULONG Unused1:1;
++ ULONG Best:15;
++ ULONG Unused2:1;
++} QUANTI_VALUE_REG;
++
++typedef union _U_QUANTI_VALUE {
++ ULONG Value;
++ QUANTI_VALUE_REG QValueReg;
++} U_QUANTI_VALUE;
++
++typedef struct _BSD_PARAM_REG {
++ ULONG HighThres:8;
++ ULONG LowThres:8;
++ ULONG HighCount:6;
++ ULONG Unused1:2;
++ ULONG LowCount:6;
++ ULONG Unused2:2;
++} BSD_PARAM_REG;
++
++typedef union _U_BSD_PARAM {
++ ULONG Value;
++ BSD_PARAM_REG BSDParamReg;
++} U_BSD_PARAM;
++
++typedef struct _VIDEO_INFO {
++ BYTE ExtADCAct; /* read from modection register */
++ BYTE EnableRC4;
++ BYTE DownScalingMethod;
++ USHORT AnalogDifferentialThreshold; /* BCD tolerance */
++ USHORT DigitalDifferentialThreshold; /* BCD tolerance */
++ USHORT DstWidth;
++ USHORT DstHeight;
++ USHORT SrcWidth;
++ USHORT SrcHeight;
++ BYTE HighLumaTable; /* if High and best Jpeg codec enable, use HighLumaTable and HighChromaTable, otherwise HighDeQuantiValue and BestDequantiValue*/
++ BYTE HighChromaTable;
++ BYTE HighDeQuantiValue;
++ BYTE BestDequantiValue;
++ U_SEQ_CTL uSeqCtlReg;
++ U_CTL_REG uCtlReg;
++ U_BCD_CTL uBCDCtlReg;
++ U_STREAM_BUF uStreamBufSize;
++ U_COMPRESS_CTL uCompressCtlReg;
++ U_QUANTI_TABLE_LOW uQTableLowReg;
++ U_QUANTI_VALUE uQValueReg;
++ U_BSD_PARAM uBSDParamReg;
++} VIDEO_INFO, *PVIDEO_INFO ;
++
++typedef struct _VIDEOM_SEQ_CTL_REG {
++ ULONG Unused1:1; //Bit 0
++ ULONG Unused2:1; //Bit 1
++ ULONG Unused3:1; //Bit 2
++ ULONG StreamMode:1; //Bit 3
++ ULONG Unused4:1; //Bit 4
++ ULONG CodecAutoMode:1; //Bit 5
++ ULONG Unused6:1; //Bit 6
++ ULONG Unused7:1; //Bit 7
++ ULONG SrcSel:1; //Bit 8
++ ULONG Unused9:1; //Bit 9
++ ULONG DataType:2; //Bit[11:10]
++ ULONG Unused12:20;
++} VIDEOM_SEQ_CTL_REG;
++
++typedef union _U_VIDEOM_SEQ_CTL {
++ ULONG Value;
++ VIDEOM_SEQ_CTL_REG SeqCtlReg;
++} U_VIDEOM_SEQ_CTL;
++
++typedef struct _VIDEOM_INFO {
++ BYTE DownScalingMethod;
++ USHORT AnalogDifferentialThreshold; /* BCD tolerance */
++ USHORT DigitalDifferentialThreshold; /* BCD tolerance */
++ USHORT DstWidth;
++ USHORT DstHeight;
++ USHORT SrcWidth;
++ USHORT SrcHeight;
++ BYTE HighLumaTable; /* if High and best Jpeg codec enable, use HighLumaTable and HighChromaTable, otherwise HighDeQuantiValue and BestDequantiValue*/
++ BYTE HighChromaTable;
++ BYTE HighDeQuantiValue;
++ BYTE BestDequantiValue;
++ BYTE PacketSize; //the same as video1 & video2
++ BYTE RingBufNum;
++ BYTE EnableRC4;
++ U_VIDEOM_SEQ_CTL uSeqCtlReg;
++ U_BCD_CTL uBCDCtlReg;
++ U_COMPRESS_CTL uCompressCtlReg;
++ U_QUANTI_TABLE_LOW uQTableLowReg;
++ U_QUANTI_VALUE uQValueReg;
++ U_BSD_PARAM uBSDParamReg;
++} VIDEOM_INFO, *PVIDEOM_INFO ;
++
++typedef struct _VIDEO_MODE_INFO
++{
++ USHORT X;
++ USHORT Y;
++ USHORT ColorDepth;
++ USHORT RefreshRate;
++ BYTE ModeIndex;
++} VIDEO_MODE_INFO, *PVIDEO_MODE_INFO;
++
++#endif
++
+diff --git a/board/aspeed/ast2400/vesa.h b/board/aspeed/ast2400/vesa.h
+new file mode 100755
+index 0000000..69aba90
+--- /dev/null
++++ b/board/aspeed/ast2400/vesa.h
+@@ -0,0 +1,163 @@
++/*
++ * 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 _VESA_H_
++#define _VESA_H_
++
++typedef enum
++{
++ VCLK25_175 = 0x00,
++ VCLK28_322 = 0x01,
++ VCLK31_5 = 0x02,
++ VCLK31_574 = 0x03,
++ VCLK32_76 = 0x04,
++ VCLK33_154 = 0x05,
++ VCLK36 = 0x06,
++ VCLK40 = 0x07,
++ VCLK45_978 = 0x08,
++ VCLK49_5 = 0x09,
++ VCLK50 = 0x0A,
++ VCLK52_95 = 0x0B,
++ VCLK56_25 = 0x0C,
++ VCLK65 = 0x0D,
++ VCLK74_48 = 0x0E,
++ VCLK75 = 0x0F,
++ VCLK78_75 = 0x10,
++ VCLK79_373 = 0x11,
++ VCLK81_624 = 0x12,
++ VCLK83_462 = 0x13,
++ VCLK84_715 = 0x14,
++ VCLK94_5 = 0x15,
++ VCLK106_5 = 0x16,
++ VCLK108 = 0x17,
++ VCLK119 = 0x18,
++ VCLK135 = 0x19,
++ VCLK136_358 = 0x1A,
++ VCLK146_25 = 0x1B,
++ VCLK154 = 0x1C,
++ VCLK157_5 = 0x1D,
++ VCLK162 = 0x1E
++} ePIXEL_CLOCK;
++
++typedef struct {
++ USHORT HorizontalTotal;
++ USHORT VerticalTotal;
++ USHORT HorizontalActive;
++ USHORT VerticalActive;
++ BYTE RefreshRate;
++ double HorizontalFrequency;
++ USHORT HSyncTime;
++ USHORT HBackPorch;
++ USHORT VSyncTime;
++ USHORT VBackPorch;
++ USHORT HLeftBorder;
++ USHORT HRightBorder;
++ USHORT VBottomBorder;
++ USHORT VTopBorder;
++ USHORT PixelClock;
++ BOOL HorPolarity;
++ BOOL VerPolarity;
++ BYTE ADCIndex1;
++ BYTE ADCIndex2;
++ BYTE ADCIndex3;
++ BYTE ADCIndex5;
++ BYTE ADCIndex6;
++ BYTE ADCIndex7;
++ BYTE ADCIndex8;
++ BYTE ADCIndex9;
++ BYTE ADCIndexA;
++ BYTE ADCIndexF;
++ BYTE ADCIndex15;
++ int HorizontalShift;
++ int VerticalShift;
++} VESA_MODE;
++
++#define HOR_POSITIVE 0
++#define HOR_NEGATIVE 1
++#define VER_POSITIVE 0
++#define VER_NEGATIVE 1
++
++#ifdef VESA_GLOBALS
++
++// Note: Modified for modes which have border issue
++VESA_MODE vModeTable[] = {
++////////////////////////// 60Hz mode
++// 720x480 done
++ {1056, 497, 720, 480, 60, 29.900, 88, 104, 3, 13, 0, 0, 0, 0, VCLK31_574, HOR_NEGATIVE, VER_NEGATIVE, 0x41, 0xF0, 0x48, 0x05, 0x20, 0x58, 0x60, 0x60, 0x60, 0x5E, 0xFE, 6, 2},
++// 848x480 done
++ {1064, 517, 848, 480, 60, 31.160, 88, 91, 3, 26, 0, 0, 0, 0, VCLK33_154, HOR_NEGATIVE, VER_NEGATIVE, 0x42, 0x70, 0x48, 0x05, 0x20, 0x58, 0x60, 0x60, 0x60, 0x5E, 0xFE, 6, 2},
++ {800, 525, 640, 480, 60, 31.469, 96, 40, 2, 25, 1, 1, 8, 8, VCLK25_175, HOR_NEGATIVE, VER_NEGATIVE, 0x31, 0xF0, 0x48, 0x05, 0x20, 0x60, 0x60, 0x60, 0x60, 0x5E, 0xFE, 6, 2},
++// 720x576
++ {912, 597, 720, 576, 60, 35.920, 72, 88, 3, 17, 0, 0, 0, 0, VCLK32_76, HOR_NEGATIVE, VER_NEGATIVE, 0x38, 0xF0, 0x48, 0x05, 0x20, 0x48, 0x60, 0x60, 0x60, 0x5E, 0xFE, 6, 2},
++// 960x600 GTF done
++ {1232, 622, 960, 600, 60, 37.320, 96, 136, 3, 18, 0, 0, 0, 0, VCLK45_978, HOR_NEGATIVE, VER_NEGATIVE, 0x4C, 0xF0, 0x60, 0x05, 0x20, 0x60, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {1056, 628, 800, 600, 60, 37.879, 128, 88, 4, 23, 0, 0, 0, 0, VCLK40, HOR_POSITIVE, VER_POSITIVE, 0x41, 0xF0, 0x60, 0x05, 0x20, 0x80, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++// 1088x612 GTF done
++ {1392, 634, 1088, 612, 60, 38.04, 112, 152, 3, 18, 0, 0, 0, 0, VCLK52_95, HOR_NEGATIVE, VER_NEGATIVE, 0x56, 0xF0, 0x60, 0x05, 0x20, 0x70, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++// 1280x720 GTF done
++ {1664, 746, 1280, 720, 60, 44.760, 136, 192, 3, 22, 0, 0, 0, 0, VCLK74_48, HOR_NEGATIVE, VER_NEGATIVE, 0x67, 0xF0, 0xA8, 0x05, 0x20, 0x88, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++// 1360x768 GTF done
++ {1776, 795, 1360, 768, 60, 47.700, 144, 208, 3, 23, 0, 0, 0, 0, VCLK84_715, HOR_NEGATIVE, VER_NEGATIVE, 0x6E, 0xF0, 0xA8, 0x05, 0x20, 0x90, 0x60, 0x60, 0x60, 0x5E, 0xFE, 7, 1},
++// 1280x768 done
++ {1664, 798, 1280, 768, 60, 47.700, 128, 184, 7, 20, 0, 0, 0, 0, VCLK79_373, HOR_NEGATIVE, VER_NEGATIVE, 0x67, 0xF0, 0xA8, 0x05, 0x20, 0x80, 0x60, 0x60, 0x60, 0x5E, 0xFE, 7, 1},
++ {1344, 806, 1024, 768, 60, 48.363, 136, 160, 6, 29, 0, 0, 0, 0, VCLK65, HOR_NEGATIVE, VER_NEGATIVE, 0x53, 0xF0, 0xA8, 0x05, 0x20, 0x88, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 7},
++// 1280x800 GTF done
++ {1680, 828, 1280, 800, 60, 49.680, 136, 200, 3, 24, 0, 0, 0, 0, VCLK83_462, HOR_NEGATIVE, VER_NEGATIVE, 0x68, 0xF0, 0xA8, 0x05, 0x20, 0x88, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++// 1152x864 GTF done
++ {1520, 895, 1152, 864, 60, 53.700, 120, 184, 3, 27, 0, 0, 0, 0, VCLK81_624, HOR_NEGATIVE, VER_NEGATIVE, 0x5E, 0xF0, 0xA8, 0x05, 0x20, 0x78, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++// 1600x900 GTF done
++ {2128, 932, 1600, 900, 60, 55.920, 168, 264, 3, 28, 0, 0, 0, 0, VCLK119, HOR_NEGATIVE, VER_NEGATIVE, 0x84, 0xF0, 0xA8, 0x05, 0x20, 0xA8, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++// 1440X900 CVT done
++ {1904, 933, 1440, 900, 60, 55.935, 152, 232, 6, 25, 0, 0, 0, 0, VCLK106_5, HOR_NEGATIVE, VER_POSITIVE, 0x76, 0xF0, 0xA8, 0x05, 0x20, 0x96, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {1800, 1000, 1280, 960, 60, 60.000, 112, 312, 3, 36, 0, 0, 0, 0, VCLK108, HOR_POSITIVE, VER_POSITIVE, 0x70, 0x70, 0xA8, 0x05, 0x20, 0x70, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++// 1600x1024 GTF done
++ {2144, 1060, 1600, 1024, 60, 63.600, 168, 272, 3, 32, 0, 0, 0, 0, VCLK136_358, HOR_NEGATIVE, VER_NEGATIVE, 0x85, 0xF0, 0xE8, 0x05, 0x20, 0xA8, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {1688, 1066, 1280, 1024, 60, 63.981, 112, 248, 3, 38, 0, 0, 0, 0, VCLK108, HOR_POSITIVE, VER_POSITIVE, 0x69, 0x70, 0xA8, 0x05, 0x20, 0x70, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++// 1680X1050 CVT done Reduced Blanking
++ {1840, 1080, 1680, 1050, 60, 64.674, 32, 80, 6, 21, 0, 0, 0, 0, VCLK119, HOR_POSITIVE, VER_NEGATIVE, 0x72, 0xF0, 0xA8, 0x05, 0x20, 0x20, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++// 1920X1200 CVT done Reduced Blanking
++ {2080, 1235, 1920, 1200, 60, 74.038, 32, 80, 6, 26, 0, 0, 0, 0, VCLK154, HOR_POSITIVE, VER_NEGATIVE, 0x81, 0xF0, 0xA8, 0x05, 0x20, 0x20, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ //{2160, 1250, 1600, 1200, 60,75.000, 192, 304, 3, 46, 0, 0, 0, 0, VCLK162, HOR_POSITIVE, VER_POSITIVE},
++ {2160, 1248, 1600, 1200, 60, 75.000, 192, 304, 3, 46, 0, 0, 0, 0, VCLK162, HOR_POSITIVE, VER_POSITIVE, 0x86, 0xF0, 0xE8, 0x05, 0x20, 0xC0, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++
++////////////////////// Not 60Hz mode
++ {900, 449, 720, 400, 70, 31.469, 108, 45, 2, 25, 1, 1, 8, 8, 0, HOR_NEGATIVE, VER_NEGATIVE, 0x38, 0x30, 0x48, 0x05, 0x20, 0x6C, 0x60, 0x60, 0x60, 0x5E, 0xFE, 6, 1},
++ {832, 520, 640, 480, 72, 37.861, 40, 120, 3, 20, 1, 1, 8, 8, 0, HOR_NEGATIVE, VER_NEGATIVE, 0x33, 0xF0, 0x48, 0x05, 0x20, 0x28, 0x60, 0x60, 0x60, 0x5E, 0xFE, 6, 3},
++ {840, 500, 640, 480, 75, 37.500, 64, 120, 3, 16, 0, 0, 0, 0, 0, HOR_NEGATIVE, VER_NEGATIVE, 0x34, 0x70, 0x48, 0x05, 0x20, 0x40, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 3},
++ {832, 509, 640, 480, 85, 43.269, 56, 80, 3, 25, 0, 0, 0, 0, 0, HOR_NEGATIVE, VER_NEGATIVE, 0x33, 0xF0, 0x48, 0x05, 0x20, 0x38, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 3},
++ {1024, 625, 800, 600, 56, 35.156, 72, 128, 2, 22, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x3F, 0xF0, 0x60, 0x05, 0x20, 0x48, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {1040, 666, 800, 600, 72, 48.077, 120, 64, 6, 23, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x40, 0xF0, 0x60, 0x05, 0x20, 0x78, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {1056, 625, 800, 600, 75, 46.875, 80, 160, 3, 21, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x41, 0xF0, 0x60, 0x05, 0x20, 0x50, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {1048, 631, 800, 600, 85, 53.674, 64, 152, 3, 27, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x41, 0x70, 0x60, 0x05, 0x20, 0x40, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {1328, 806, 1024, 768, 70, 56.476, 136, 144, 6, 29, 0, 0, 0, 0, 0, HOR_NEGATIVE, VER_NEGATIVE, 0x52, 0xF0, 0xA8, 0x05, 0x20, 0x88, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 7},
++ {1312, 800, 1024, 768, 75, 60.023, 96, 176, 3, 28, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x51, 0xF0, 0xA8, 0x05, 0x20, 0x60, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 1},
++ {1376, 808, 1024, 768, 85, 68.677, 96, 208, 3, 36, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x55, 0xF0, 0xA8, 0x05, 0x20, 0x60, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 1},
++ {1600, 900, 1152, 864, 75, 67.500, 128, 256, 3, 32, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x63, 0xF0, 0xA8, 0x05, 0x20, 0x80, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {1728, 1011, 1280, 960, 85, 85.938, 160, 224, 3, 47, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x6B, 0xF0, 0xA8, 0x05, 0x20, 0xA0, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {1688, 1066, 1280, 1024, 75, 79.976, 144, 248, 3, 38, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x69, 0x70, 0xE8, 0x05, 0x20, 0x90, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {1728, 1072, 1280, 1024, 85, 91.146, 160, 224, 3, 44, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x6B, 0xF0, 0xA8, 0x05, 0x20, 0xA0, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {2160, 1250, 1600, 1200, 65, 81.250, 192, 304, 3, 46, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x86, 0xF0, 0xA8, 0x05, 0x20, 0xC0, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {2160, 1250, 1600, 1200, 70, 87.500, 192, 304, 3, 46, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x86, 0xF0, 0xA8, 0x05, 0x20, 0xC0, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {2160, 1250, 1600, 1200, 75, 93.750, 192, 304, 3, 46, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x86, 0xF0, 0xA8, 0x05, 0x20, 0xC0, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0},
++ {2160, 1250, 1600, 1200, 85, 106.250,192, 304, 3, 46, 0, 0, 0, 0, 0, HOR_POSITIVE, VER_POSITIVE, 0x86, 0xF0, 0xA8, 0x05, 0x20, 0xC0, 0x60, 0x60, 0x60, 0x5E, 0xFE, -1, 0}
++};
++
++USHORT ModeNumberCount = sizeof (vModeTable) / sizeof (VESA_MODE);
++USHORT Mode60HZCount = 21;
++
++#else /* NOT VESA_GLOBALS */
++extern VESA_MODE vModeTable[];
++extern USHORT ModeNumberCount;
++extern USHORT Mode60HZCount;
++#endif
++
++#endif /* _VESA_H_ */
++
++
+diff --git a/board/aspeed/ast2400/vfun.c b/board/aspeed/ast2400/vfun.c
+new file mode 100755
+index 0000000..f707e80
+--- /dev/null
++++ b/board/aspeed/ast2400/vfun.c
+@@ -0,0 +1,545 @@
++/*
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#define BUF_GLOBALS
++#include "type.h"
++#include "vdef.h"
++#include "vreg.h"
++#include "crt.h"
++#include "vfun.h"
++
++ULONG UnlockSCURegHost(ULONG MMIOBase, ULONG Key)
++{
++ WriteMemoryLongHost(SCU_BASE, SCU_PROTECT_REG, Key);
++ return ReadMemoryLongHost(SCU_BASE,SCU_PROTECT_REG);
++}
++
++void ResetVideoHost(void)
++{
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CONTROL_REG, VIDEO_RESET_EN << VIDEO_ENGINE_RESET_BIT, VIDEO_ENGINE_RESET_MASK);
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CONTROL_REG, VIDEO_RESET_OFF << VIDEO_ENGINE_RESET_BIT, VIDEO_ENGINE_RESET_MASK);
++}
++
++void StartModeDetectionTriggerHost(ULONG MMIOBase, ULONG offset)
++{
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, offset, 0, MODE_DETECTION_TRIGGER);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, offset, MODE_DETECTION_TRIGGER, MODE_DETECTION_TRIGGER);
++}
++
++BOOL ReadVideoInterruptHost(ULONG MMIOBase, ULONG value)
++{
++ return ((ReadMemoryLongHost(VIDEO_REG_BASE, VIDEO_INT_CONTROL_READ_REG) & value) ? TRUE : FALSE);
++}
++
++ULONG UnlockVideoRegHost(ULONG MMIOBase, ULONG Key)
++{
++ WriteMemoryLongHost(VIDEO_REG_BASE, KEY_CONTROL_REG, Key);
++ return ReadMemoryLongHost(VIDEO_REG_BASE,KEY_CONTROL_REG);
++}
++
++void StartVideoCaptureTriggerHost(ULONG MMIOBase, ULONG offset)
++{
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, offset, 0, VIDEO_CAPTURE_TRIGGER);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, offset, VIDEO_CAPTURE_TRIGGER, VIDEO_CAPTURE_TRIGGER);
++}
++
++void StartVideoCodecTriggerHost(ULONG MMIOBase, ULONG offset)
++{
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, offset, 0, VIDEO_CODEC_TRIGGER);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, offset, VIDEO_CODEC_TRIGGER, VIDEO_CODEC_TRIGGER);
++}
++
++void StopModeDetectionTriggerHost(ULONG MMIOBase, ULONG offset)
++{
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, offset, 0, MODE_DETECTION_TRIGGER);
++}
++
++void ClearVideoInterruptHost(ULONG MMIOBase, ULONG value)
++{
++ //WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO_INT_CONTROL_CLEAR_REG, value, value);
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO_INT_CONTROL_CLEAR_REG, value);
++}
++
++/* UnLock SCU Host and Reset Engine */
++BOOL CheckOnStartHost(void)
++{
++ int i=0, dwValue=0;
++
++ do
++ {
++ dwValue = UnlockSCURegHost(0, SCU_UNLOCK_KEY);
++ i++;
++ }
++ while ((SCU_WRITE_ENABLE != dwValue) && (i<10));
++
++ //Clear SCU Reset Register
++ WriteMemoryLongHost(SCU_BASE, SCU_CONTROL_REG, 0);
++
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_STOP_REG, (EN_ECLK | EN_V1CLK | EN_V2CLK), (STOP_ECLK_MASK | STOP_V1CLK_MASK | STOP_V2CLK_MASK));
++
++#if defined(CONFIG_AST2300)
++ WriteMemoryLongWithMASKHost(SCU_BASE, (0x90 + SCU_OFFSET), 0x00000020, 0x00000030); //enable 24bits
++ WriteMemoryLongWithMASKHost(SCU_BASE, (0x88 + SCU_OFFSET), 0x000fff00, 0x000fff00); //enable video multi-pins
++#else //AST2100
++ //WriteMemoryLongWithMASKHost(SCU_BASE, SCU_PIN_CTRL1_REG, (VIDEO_PORTA_EN | VIDEO_PORTB_EN | VIDEO_VP1_EN | VIDEO_VP2_EN) ,
++ // (VIDEO_PORTA_MASK | VIDEO_PORTB_MASK | VIDEO_VP1_MASK | VIDEO_VP2_MASK));
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_PIN_CTRL2_REG, (VIDEO_PORTA_SINGLE_EDGE | VIDEO_PORTB_SINGLE_EDGE) ,
++ (VIDEO_PORTA_SINGLE_EDGE_MASK | VIDEO_PORTB_SINGLE_EDGE_MASK));
++#endif
++
++ ResetVideoHost();
++
++ return TRUE;
++}
++
++BOOL CheckOnStartClient(void)
++{
++ int i=0, dwValue=0;
++
++ do
++ {
++ dwValue = UnlockSCURegHost(0, SCU_UNLOCK_KEY);
++ i++;
++ }
++ while ((SCU_WRITE_ENABLE != dwValue) && (i<10));
++
++ //Clear SCU Reset Register
++ WriteMemoryLongClient(SCU_BASE, SCU_CONTROL_REG, 0);
++
++ WriteMemoryLongWithMASKClient(SCU_BASE, SCU_CLOCK_STOP_REG, (EN_ECLK | EN_V1CLK | EN_D1CLK | EN_D2CLK | EN_V2CLK),
++ (STOP_ECLK_MASK | STOP_D1CLK_MASK | STOP_D2CLK_MASK | STOP_V1CLK_MASK | STOP_V2CLK_MASK));
++
++ //WriteMemoryLongWithMASKClient(SCU_BASE, SCU_CLOCK_SELECTION_REG, PORTB_FROM_D2CLK | PORTB_CLOCK_INV_DELAY_3NS | PORTA_CLOCK_INV_DELAY_3NS, PORTB_CLOCK_SEL | PORTB_CLOCK_DELAY_MASK | PORTA_CLOCK_DELAY_MASK);
++ //A1EVA
++ WriteMemoryLongWithMASKClient(SCU_BASE, SCU_CLOCK_SELECTION_REG, (PORTB_FROM_D2CLK | PORTB_CLOCK_INV_DELAY_1NS | PORTA_CLOCK_INV_DELAY_1NS), (PORTB_CLOCK_SEL | PORTB_CLOCK_DELAY_MASK | PORTA_CLOCK_DELAY_MASK));
++ WriteMemoryLongWithMASKClient(SCU_BASE, 0x202C, (0x03<<9), (0x03<<9));
++
++ WriteMemoryLongWithMASKClient(SCU_BASE, SCU_PIN_CTRL1_REG, (VIDEO_PORTA_EN | VIDEO_PORTB_EN | VIDEO_VP1_EN | VIDEO_VP2_EN),
++ (VIDEO_PORTA_MASK | VIDEO_PORTB_MASK | VIDEO_VP1_MASK | VIDEO_VP2_MASK));
++
++#if CONFIG_AST3000
++ WriteMemoryLongWithMASKClient(SCU_BASE, SCU_PIN_CTRL2_REG, (VIDEO_PORTA_DUAL_EDGE | VIDEO_PORTB_DUAL_EDGE),
++ (VIDEO_PORTA_SINGLE_EDGE_MASK | VIDEO_PORTB_SINGLE_EDGE_MASK));
++#else
++ //2100 is single edge
++ WriteMemoryLongWithMASKClient(SCU_BASE, SCU_PIN_CTRL2_REG, (VIDEO_PORTA_SINGLE_EDGE | VIDEO_PORTB_SINGLE_EDGE),
++ (VIDEO_PORTA_SINGLE_EDGE_MASK | VIDEO_PORTB_SINGLE_EDGE_MASK));
++#endif
++
++ WriteMemoryLongWithMASKClient(SCU_BASE, SCU_CLOCK_STOP_REG, (EN_D1CLK | EN_D2CLK), (STOP_D1CLK_MASK | STOP_D2CLK_MASK));
++ WriteMemoryLongWithMASKClient(SCU_BASE, SCU_PIN_CTRL1_REG, VGA_PIN_OFF, VGA_PIN_MASK);
++
++ //ResetVideoHost();
++
++ return TRUE;
++}
++
++ULONG InitializeVideoEngineHost (ULONG MMIOBase,
++ int nVideo,
++ BOOL HorPolarity,
++ BOOL VerPolarity)
++{
++ //ULONG temp, temp1, temp2;
++ ULONG dwRegOffset = nVideo * 0x100;
++ ULONG dwValue;
++ int i;
++
++
++ /* General Video Control */
++ //LineBufEn 0
++ //dwValue = (COMPRESS_MODE << CODEC_DECOMPRESS_MODE_BIT) | DELAY_VSYNC_EN;
++ dwValue = 0;
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO_CONTROL_REG, dwValue);
++ //Video Data Truncation Register
++ WriteMemoryLongHost(VIDEO_REG_BASE, 0x328, 0);
++
++ //D2CLK clock must config according to video's line buffer
++ if (VIDEO1 == nVideo)
++ dwValue = LINE_BUFFER_VIDEO1;
++ else
++ dwValue = LINE_BUFFER_VIDEO2;
++
++ //D2CLK clock must config according to video's line buffer
++ switch (dwValue)
++ {
++ case LINE_BUFFER_OFF:
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_SELECTION_REG, NORMAL_CRT1, D2CLK_CLOCK_SELECTION_MASK);
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_STOP_REG, STOP_D2CLK, STOP_D2CLK_MASK);
++ break;
++ case LINE_BUFFER_VIDEO1:
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_SELECTION_REG, V1CLK_VIDEO1 << D2CLK_CLOCK_SELECTION_BIT, D2CLK_CLOCK_SELECTION_MASK);
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_STOP_REG, EN_D2CLK, STOP_D2CLK_MASK);
++ break;
++ case LINE_BUFFER_VIDEO2:
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_SELECTION_REG, V1CLK_VIDEO2 << D2CLK_CLOCK_SELECTION_BIT, D2CLK_CLOCK_SELECTION_MASK);
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_STOP_REG, EN_D2CLK, STOP_D2CLK_MASK);
++ break;
++ case LINE_BUFFER_VIDEOM:
++ //If select this option, it will config at videoM INIT
++ break;
++ default:
++ break;
++ }
++
++ dwValue = 0;
++ //VR30 now is capture window in the compression
++ dwValue = g_DefHeight << CAPTURE_VER_LINE_BIT |
++ g_DefWidth << CAPTURE_HOR_PIXEL_BIT;
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_CAPTURE_WINDOWS_REG + dwRegOffset, dwValue);
++
++ dwValue = 0;
++ //VR34 now is destionation window in the compression
++ dwValue = g_DefHeight << COMPRESS_VER_LINE_BIT |
++ g_DefWidth << COMPRESS_HOR_PIXEL_BIT;
++
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_WINDOWS_REG + dwRegOffset, dwValue);
++
++ //BitCOUNT according compress data format
++ dwValue = YUV444_MODE;
++ if (YUV444_MODE == dwValue)
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_LINE_OFFSET_REG + dwRegOffset, g_DefWidth * INPUT_BITCOUNT_YUV444, BUF_LINE_OFFSET_MASK);
++ else
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_LINE_OFFSET_REG + dwRegOffset, g_DefWidth * INPUT_BITCOUNT_YUV420, BUF_LINE_OFFSET_MASK);
++
++ // CRC
++ //Disable
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO_CRC_PRIMARY_REG, 0x0);
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO_CRC_SECOND_REG, 0x0);
++
++ /* Sequence Control register */
++ //Oonly Encoder need to set
++ /* Engine Sequence Contol Register */
++ dwValue = (WATCH_DOG_EN << WATCH_DOG_ENABLE_BIT) |
++ VIDEO_CAPTURE_AUTO_MODE |
++ VIDEO_CODEC_AUTO_MODE;
++
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG + dwRegOffset, dwValue);
++
++ /* Control register */
++ dwValue = (HOR_NEGATIVE == HorPolarity) ? NO_INVERSE_POL : INVERSE_POL;
++ dwValue = (((VER_NEGATIVE == VerPolarity) ? NO_INVERSE_POL : INVERSE_POL) << VIDEO_VSYNC_POLARITY_BIT) | dwValue;
++
++ /* HW Recommand*/
++ //dwValue = (TILE_MODE << 9) | dwValue;
++ dwValue = (EXTERNAL_VGA_SOURCE << EXTERNAL_SOURCE_BIT) | dwValue;
++
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_CONTROL_REG + dwRegOffset, dwValue);
++
++ /* BCD register */
++ //NO BCD
++ dwValue = 0;
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_BCD_CONTROL_REG + dwRegOffset, dwValue);
++
++ /* Stream Buffer Size register */
++ dwValue = (YUV_TEST << SKIP_TEST_MODE_BIT) |
++ (PACKET_SIZE_32KB << STREAM_PACKET_SIZE_BIT) |
++ (PACKETS_8 << RING_BUF_PACKET_NUM_BIT);
++ /* the same with Video1, Video2, and VideoM*/
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_STREAM_BUF_SIZE, dwValue);
++
++ /* Comression control register */
++ dwValue = (USE_UV_CIR656 << UV_CIR656_FORMAT_BIT)|
++ (JPEG_MIX_MODE << JPEG_ONLY_BIT)|
++ (VQ_4_COLOR_MODE << VQ_4_COLOR_BIT)|
++ (QUANTI_CODEC_MODE << QUALITY_CODEC_SETTING_BIT)|
++ (7 << NORMAL_QUANTI_CHROMI_TABLE_BIT) |
++ (23 << NORMAL_QUANTI_LUMI_TABLE_BIT);
++
++ //Video2 have same value as video1
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_CONTROL_REG, dwValue);
++
++ /* JPEG Quantization Table register */
++ dwValue = 0;
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_QUANTI_TABLE_LOW_REG, dwValue);
++
++ /* Quantization value register */
++ //Video2 have same value as video1
++ dwValue = 0;
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_QUANTI_VALUE_REG, dwValue);
++
++ //Video BSD Parameter Register
++ //Video2 have same value as video1
++ dwValue = 0;
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_BSD_PARA_REG, dwValue);
++
++ //no scale
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_SCALE_FACTOR_REG, 0x10001000);
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_SCALE_FACTOR_PARAMETER0_REG, 0x00200000);
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_SCALE_FACTOR_PARAMETER1_REG, 0x00200000);
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_SCALE_FACTOR_PARAMETER2_REG, 0x00200000);
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_SCALE_FACTOR_PARAMETER3_REG, 0x00200000);
++ return TRUE;
++}
++
++ULONG InitializeVideoEngineClient (ULONG MMIOBase,
++ int nVideo)
++{
++ //ULONG temp, temp1, temp2;
++ ULONG dwRegOffset = nVideo * 0x100;
++ ULONG dwValue;
++ int i;
++
++
++ /* General Video Control */
++ //LineBufEn 0
++ dwValue = (DECOMPRESS_MODE << CODEC_DECOMPRESS_MODE_BIT);
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO_CONTROL_REG, dwValue);
++ //Video Data Truncation Register
++ WriteMemoryLongHost(VIDEO_REG_BASE, 0x328, 0);
++
++ //VR30 now is capture window in the compression
++ dwValue = g_DefHeight << CAPTURE_VER_LINE_BIT |
++ g_DefWidth << CAPTURE_HOR_PIXEL_BIT;
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_CAPTURE_WINDOWS_REG + dwRegOffset, dwValue, CAPTURE_VER_LINE_MASK | CAPTURE_HOR_PIXEL_MASK);
++
++ //VR34 now is destionation window in the compression
++ dwValue = g_DefHeight << COMPRESS_VER_LINE_BIT |
++ g_DefWidth << COMPRESS_HOR_PIXEL_BIT;
++
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_WINDOWS_REG + dwRegOffset, dwValue, COMPRESS_VER_LINE_MASK | COMPRESS_HOR_PIXEL_MASK);
++
++ //BitCOUNT according compress data format
++ dwValue = YUV444_MODE;
++ if (YUV444_MODE == dwValue)
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_LINE_OFFSET_REG + dwRegOffset, g_DefWidth * INPUT_BITCOUNT_YUV444, BUF_LINE_OFFSET_MASK);
++ else
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_LINE_OFFSET_REG + dwRegOffset, g_DefWidth * INPUT_BITCOUNT_YUV420, BUF_LINE_OFFSET_MASK);
++
++ // CRC
++ //Disable
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO_CRC_PRIMARY_REG, 0x0);
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO_CRC_SECOND_REG, 0x0);
++
++ /* Sequence Control register */
++ //Oonly Encoder need to set
++ /* Engine Sequence Contol Register */
++ dwValue = VIDEO_CAPTURE_AUTO_MODE |
++ VIDEO_CODEC_AUTO_MODE;
++
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG + dwRegOffset, dwValue);
++
++ /* Control register */
++ /* HW Recommand*/
++ dwValue = (TILE_MODE << 9);
++
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_CONTROL_REG + dwRegOffset, dwValue);
++
++ /* BCD register */
++ //NO BCD
++ dwValue = 0;
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_BCD_CONTROL_REG + dwRegOffset, dwValue);
++
++ /* Stream Buffer Size register */
++ dwValue = (YUV_TEST << SKIP_TEST_MODE_BIT) |
++ (PACKET_SIZE_32KB << STREAM_PACKET_SIZE_BIT) |
++ (PACKETS_8 << RING_BUF_PACKET_NUM_BIT);
++ /* the same with Video1, Video2, and VideoM*/
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_STREAM_BUF_SIZE, dwValue);
++
++
++ /* Comression control register */
++ dwValue = (USE_UV_CIR656 << UV_CIR656_FORMAT_BIT)|
++ (JPEG_MIX_MODE << JPEG_ONLY_BIT)|
++ (VQ_4_COLOR_MODE << VQ_4_COLOR_BIT)|
++ (QUANTI_CODEC_MODE << QUALITY_CODEC_SETTING_BIT)|
++ (7 << NORMAL_QUANTI_CHROMI_TABLE_BIT) |
++ (23 << NORMAL_QUANTI_LUMI_TABLE_BIT);
++
++ //Video2 have same value as video1
++ if (VIDEO1 == nVideo)
++ {
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_CONTROL_REG, dwValue);
++ }
++ else
++ {
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEOM_COMPRESS_CONTROL_REG, dwValue);
++ }
++
++ /* JPEG Quantization Table register */
++ dwValue = 0;
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_QUANTI_TABLE_LOW_REG, dwValue);
++
++ /* Quantization value register */
++ //Video2 have same value as video1
++ dwValue = 0;
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_QUANTI_VALUE_REG, dwValue);
++
++ //Video BSD Parameter Register
++ //Video2 have same value as video1
++ dwValue = 0;
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_BSD_PARA_REG, dwValue);
++
++ return TRUE;
++}
++
++BYTE GetI2CRegClient(ULONG MMIOBase,
++ BYTE DeviceSelect,
++ BYTE DeviceAddress,
++ BYTE RegisterIndex)
++{
++ BYTE Data;
++ ULONG Status;
++
++// Reset
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x00, 0);
++// Set AC Timing and Speed
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x04, AC_TIMING);
++// Lower Speed
++// WriteMemoryLongWithANDData (VideoEngineInfo->VGAPCIInfo.ulMMIOBaseAddress, I2C_BASE + DeviceSelect * 0x40 + 0x04, 0, 0x33317805);
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x08, 0);
++// Clear Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF);
++// Enable Master Mode
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x00, 1);
++// Enable Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x0C, 0xAF);
++// BYTE I2C Mode
++// Start and Send Device Address
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20, DeviceAddress);
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x3);
++// Wait TX ACK
++ do {
++ Status = ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x03;
++ } while (Status != 1);
++// Clear Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF);
++// Send Device Register Index
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20, RegisterIndex);
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x2);
++// Wait Tx ACK
++ do {
++ Status = ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x03;
++ } while (Status != 1);
++// Clear Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF);
++// Start, Send Device Address + 1(Read Mode), Receive Data
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20, DeviceAddress + 1);
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x1B);
++// Wait Rx Done
++ do {
++ Status = (ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x04) >> 2;
++ } while (Status != 1);
++// Clear Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF);
++
++// Enable STOP Interrupt
++ WriteMemoryLongWithMASKClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x0C, 0x10, 0x10);
++// Issue STOP Command
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x20);
++// Wait STOP
++ do {
++ Status = (ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x10) >> 4;
++ } while (Status != 1);
++// Disable STOP Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x0C, 0x10);
++// Clear Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF);
++// Read Received Data
++ Data = (BYTE)((ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20) & 0xFF00) >> 8);
++
++ return Data;
++}
++
++ULONG SetI2CRegClient(ULONG MMIOBase,
++ BYTE DeviceSelect,
++ BYTE DeviceAddress,
++ BYTE RegisterIndex,
++ BYTE RegisterValue)
++{
++ ULONG Status;
++ ULONG Count = 0;
++
++// Reset
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x00, 0);
++// Set Speed
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x04, AC_TIMING);
++// Lower Speed
++// WriteMemoryLongWithANDData (VideoEngineInfo->VGAPCIInfo.ulMMIOBaseAddress, I2C_BASE + DeviceSelect * 0x40 + 0x04, 0, 0x33317805);
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x08, 0);
++// Clear Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF);
++// Enable Master Mode
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x00, 1);
++// Enable Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x0C, 0xAF);
++// BYTE I2C Mode
++// Start and Send Device Address
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20, DeviceAddress);
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x3);
++// Wait Tx ACK
++ do {
++ Count++;
++ Status = ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x03;
++
++ if (2 == Status)
++ {
++ //Clear Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF);
++ //Re-Send Start and Send Device Address while NACK return
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20, DeviceAddress);
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x3);
++ }
++ //else
++ {
++ if (Count > LOOP_COUNT) {
++ return CAN_NOT_FIND_DEVICE;
++ }
++ }
++ } while (Status != 1);
++ Count = 0;
++// Clear Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF);
++// Send Device Register Index
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20, RegisterIndex);
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x2);
++// Wait Tx ACK
++ do {
++ Count++;
++ Status = ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x03;
++ if (Count > LOOP_COUNT) {
++ return CAN_NOT_FIND_DEVICE;
++ }
++ } while (Status != 1);
++ Count = 0;
++// Clear Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF);
++// Send Device Register Value and Stop
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20, RegisterValue);
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x2);
++// Wait Tx ACK
++ do {
++ Count++;
++ Status = ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x03;
++ if (Count > LOOP_COUNT) {
++ return CAN_NOT_FIND_DEVICE;
++ }
++ } while (Status != 1);
++ Count = 0;
++// Clear Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF);
++// Enable STOP Interrupt
++ WriteMemoryLongWithMASKClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x0C, 0x10, 0x10);
++// Issue STOP Command
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x20);
++// Wait STOP
++ do {
++ Count++;
++ Status = (ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x10) >> 4;
++ if (Count > LOOP_COUNT) {
++ return CAN_NOT_FIND_DEVICE;
++ }
++ } while (Status != 1);
++// Disable STOP Interrupt
++ WriteMemoryLongWithMASKClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x0C, 0, 0x10);
++// Clear Interrupt
++ WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF);
++
++ return SET_I2C_DONE;
++}
+diff --git a/board/aspeed/ast2400/vfun.h b/board/aspeed/ast2400/vfun.h
+new file mode 100755
+index 0000000..90f9ec4
+--- /dev/null
++++ b/board/aspeed/ast2400/vfun.h
+@@ -0,0 +1,79 @@
++/*
++ * 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 _VFUN_H_
++#define _VFUN_H_
++
++//#define vBufAlign(x) ((x + 0x0000007F) & 0xFFFFFF80) //128 byte alignment
++#define vBufAlign(x) ((x + 0x000003FF) & 0xFFFFFC00) //128 byte alignment
++#define vBufAlign2(x) ((x + 0x0000FFFF) & 0xFFFF0000) //128 byte alignment
++#define v16byteAlign(x) ((x + 0x0000000F) & 0xFFFFFFF0)
++#define vBuf_ALIGNMENT 128
++
++#define HOST_TOTAL_SIZE 0x8000000 /* 128M */
++#define STATION_TOTAL_SIZE 0xF800000 /* 120M */
++
++#define VIDEO_SOURCE_SIZE 0x200000 /* 800X600X4 = 0x1D4C00 */
++#define VIDEO_MAX_STREAM_SIZE 0x400000 /* 32X128K = 0x400000 */
++#define VIDEO_FLAG_SIZE 0x5000 /* 1920X1200/128 = 0x4650*/
++#define VIDEO_CRC_SIZE 0x50000 /* 1920/64X1200X8 = 0x46500*/
++
++#define VIDEO1_EN_TOTAL_SIZE (VIDEO_SOURCE_SIZE*2+VIDEO_MAX_STREAM_SIZE+VIDEO_FLAG_SIZE+VIDEO_CRC_SIZE) /* 0x1655000 = about 23M*/
++#define VIDEO2_EN_TOTAL_SIZE VIDEO1_EN_TOTAL_SIZE
++//#define VIDEOM_EN_TOTAL_SIZE (VIDEO_SOURCE_SIZE*2+VIDEO_MAX_STREAM_SIZE+VIDEO_FLAG_SIZE) /* 0x1605000 = about 22.7M */
++//#define VIDEO_HOST_SIZE (VIDEO1_EN_TOTAL_SIZE + VIDEO2_EN_TOTAL_SIZE + VIDEOM_EN_TOTAL_SIZE) /* 0x69922816 = about 70M */
++#define VIDEO_HOST_SIZE (VIDEO1_EN_TOTAL_SIZE + VIDEO2_EN_TOTAL_SIZE) /* NOT NEED VIDEOM */
++
++#define VIDEO1_EN_BASE 0x100000
++#define VIDEO2_EN_BASE (VIDEO1_EN_BASE + VIDEO1_EN_TOTAL_SIZE)
++#define VIDEOM_EN_BASE (VIDEO2_EN_BASE + VIDEO2_EN_TOTAL_SIZE)
++
++#define VIDEO1_DE_TOTAL_SIZE (VIDEO_MAX_STREAM_SIZE + VIDEO_SOURCE_SIZE) /* 0xD00000 = 13M*/
++#define VIDEO2_DE_TOTAL_SIZE (VIDEO1_DE_TOTAL_SIZE)
++#define VIDEO_STATION_SIZE (VIDEO1_DE_TOTAL_SIZE + VIDEO2_DE_TOTAL_SIZE) /* 26M */
++
++#define VIDEO1_DE_BASE VIDEO_HOST_SIZE
++#define VIDEO2_DE_BASE (VIDEO1_DE_BASE + VIDEO1_DE_TOTAL_SIZE)
++#define VIDEO_ALL_SIZE (VIDEO_HOST_SIZE + VIDEO_STATION_SIZE) //Host and Station
++
++#define OutdwmBankModeHost(offset,data) WriteMemoryLongHost(DRAM_BASE,offset,data)
++#define IndwmBankModeHost(offset) ReadMemoryLongHost(DRAM_BASE,offset)
++
++ULONG UnlockVideoRegHost(ULONG MMIOBase, ULONG Key);
++BOOL CheckOnStartHost(void);
++BOOL CheckOnStartClient(void);
++void StartVideoCaptureTriggerHost(ULONG MMIOBase, ULONG offset);
++void StartVideoCaptureTriggerHost(ULONG MMIOBase, ULONG offset);
++void StartVideoCodecTriggerHost(ULONG MMIOBase, ULONG offset);
++ULONG UnlockSCURegHost(ULONG MMIOBase, ULONG Key);
++ULONG UnlockSCURegHost(ULONG MMIOBase, ULONG Key);
++void StartModeDetectionTriggerHost(ULONG MMIOBase, ULONG offset);
++void ClearVideoInterruptHost(ULONG MMIOBase, ULONG value);
++BOOL ReadVideoInterruptHost(ULONG MMIOBase, ULONG value);
++void StopModeDetectionTriggerHost(ULONG MMIOBase, ULONG offset);
++void ResetVideoHost(void);
++ULONG InitializeVideoEngineHost (ULONG MMIOBase,
++ int nVideo,
++ BOOL HorPolarity,
++ BOOL VerPolarity);
++ULONG InitializeVideoEngineClient (ULONG MMIOBase,
++ int nVideo);
++BYTE GetI2CRegClient(ULONG MMIOBase,
++ BYTE DeviceSelect,
++ BYTE DeviceAddress,
++ BYTE RegisterIndex);
++
++ULONG SetI2CRegClient(ULONG MMIOBase,
++ BYTE DeviceSelect,
++ BYTE DeviceAddress,
++ BYTE RegisterIndex,
++ BYTE RegisterValue);
++#endif //_VFUN_H_
++
+diff --git a/board/aspeed/ast2400/vgahw.h b/board/aspeed/ast2400/vgahw.h
+new file mode 100755
+index 0000000..7cbba0d
+--- /dev/null
++++ b/board/aspeed/ast2400/vgahw.h
+@@ -0,0 +1,175 @@
++/*
++ * 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
++ */
++/******************************************************************************
++ * Mode Stuff
++ ******************************************************************************/
++/* Default Settings */
++#define CRT_LOW_THRESHOLD_VALUE 0x12
++#define CRT_HIGH_THRESHOLD_VALUE 0x1E
++
++/* Output Selection */
++#define CRT1 0x00
++#define CRT2 0x01
++#define DVI1 0x10
++#define DVI2 0x11
++#define LVDS1 0x20
++#define LVDS2 0x21
++
++/* Mode Limitation */
++#define MAX_HResolution 1600
++#define MAX_VResolution 1200
++
++/* Std. Table Index Definition */
++#define TextModeIndex 0
++#define EGAModeIndex 1
++#define VGAModeIndex 2
++#define HiCModeIndex 3
++#define TrueCModeIndex 4
++
++/* DCLK Index */
++#define VCLK25_175 0x00
++#define VCLK28_322 0x01
++#define VCLK31_5 0x02
++#define VCLK36 0x03
++#define VCLK40 0x04
++#define VCLK49_5 0x05
++#define VCLK50 0x06
++#define VCLK56_25 0x07
++#define VCLK65 0x08
++#define VCLK75 0x09
++#define VCLK78_75 0x0A
++#define VCLK94_5 0x0B
++#define VCLK108 0x0C
++#define VCLK135 0x0D
++#define VCLK157_5 0x0E
++#define VCLK162 0x0F
++#define VCLK119 0x10
++
++/* Flags Definition */
++#define Charx8Dot 0x00000001
++#define HalfDCLK 0x00000002
++#define DoubleScanMode 0x00000004
++#define LineCompareOff 0x00000008
++#define SyncPP 0x00000000
++#define SyncPN 0x00000040
++#define SyncNP 0x00000080
++#define SyncNN 0x000000C0
++#define HBorder 0x00000020
++#define VBorder 0x00000010
++#define COLORINDEX 0x00000000
++#define MONOINDEX 0x00000100
++
++/* DAC Definition */
++#define DAC_NUM_TEXT 64
++#define DAC_NUM_EGA 64
++#define DAC_NUM_VGA 256
++
++/* AST3000 Reg. Definition */
++#define AST3000_VGAREG_BASE 0x1e6e6000
++#define AST3000_VGA1_CTLREG 0x00
++#define AST3000_VGA1_CTLREG2 0x04
++#define AST3000_VGA1_STATUSREG 0x08
++#define AST3000_VGA1_PLL 0x0C
++#define AST3000_VGA1_HTREG 0x10
++#define AST3000_VGA1_HRREG 0x14
++#define AST3000_VGA1_VTREG 0x18
++#define AST3000_VGA1_VRREG 0x1C
++#define AST3000_VGA1_STARTADDR 0x20
++#define AST3000_VGA1_OFFSETREG 0x24
++#define AST3000_VGA1_THRESHOLD 0x28
++#define AST3000_HWC1_OFFSET 0x30
++#define AST3000_HWC1_XY 0x34
++#define AST3000_HWC1_PBase 0x38
++#define AST3000_OSD1_H 0x40
++#define AST3000_OSD1_V 0x44
++#define AST3000_OSD1_PBase 0x48
++#define AST3000_OSD1_Offset 0x4C
++#define AST3000_OSD1_THRESHOLD 0x50
++
++#define AST3000_VGA2_CTLREG 0x60
++#define AST3000_VGA2_CTLREG2 0x64
++#define AST3000_VGA2_STATUSREG 0x68
++#define AST3000_VGA2_PLL 0x6C
++#define AST3000_VGA2_HTREG 0x70
++#define AST3000_VGA2_HRREG 0x74
++#define AST3000_VGA2_VTREG 0x78
++#define AST3000_VGA2_VRREG 0x7C
++#define AST3000_VGA2_STARTADDR 0x80
++#define AST3000_VGA2_OFFSETREG 0x84
++#define AST3000_VGA2_THRESHOLD 0x88
++#define AST3000_HWC2_OFFSET 0x90
++#define AST3000_HWC2_XY 0x94
++#define AST3000_HWC2_PBase 0x98
++#define AST3000_OSD2_H 0xA0
++#define AST3000_OSD2_V 0xA4
++#define AST3000_OSD2_PBase 0xA8
++#define AST3000_OSD2_Offset 0xAC
++#define AST3000_OSD2_THRESHOLD 0xB0
++
++/* Data Structure */
++typedef struct {
++ UCHAR ModeName[20];
++ USHORT usModeIndex;
++ USHORT usModeID;
++ USHORT usColorIndex;
++ USHORT usRefreshRateIndex;
++ USHORT usWidth;
++ USHORT usHeight;
++ USHORT usBitsPerPlane;
++ USHORT usRefreshRate;
++} ModeInfoStruct;
++
++typedef struct {
++
++ UCHAR MISC;
++ UCHAR SEQ[4];
++ UCHAR CRTC[25];
++ UCHAR AR[20];
++ UCHAR GR[9];
++
++} VBIOS_STDTABLE_STRUCT, *PVBIOS_STDTABLE_STRUCT;
++
++typedef struct {
++
++ ULONG HT;
++ ULONG HDE;
++ ULONG HFP;
++ ULONG HSYNC;
++ ULONG VT;
++ ULONG VDE;
++ ULONG VFP;
++ ULONG VSYNC;
++ ULONG DCLKIndex;
++ ULONG Flags;
++
++ ULONG ulRefreshRate;
++ ULONG ulRefreshRateIndex;
++ ULONG ulModeID;
++
++} VBIOS_ENHTABLE_STRUCT, *PVBIOS_ENHTABLE_STRUCT;
++
++typedef struct {
++ UCHAR Param1;
++ UCHAR Param2;
++ UCHAR Param3;
++} VBIOS_DCLK_INFO, *PVBIOS_DCLK_INFO;
++
++typedef struct {
++ UCHAR DACR;
++ UCHAR DACG;
++ UCHAR DACB;
++} VBIOS_DAC_INFO, *PVBIOS_DAC_INFO;
++
++typedef struct {
++ PVBIOS_STDTABLE_STRUCT pStdTableEntry;
++ PVBIOS_ENHTABLE_STRUCT pEnhTableEntry;
++
++} VBIOS_MODE_INFO, *PVBIOS_MODE_INFO;
+diff --git a/board/aspeed/ast2400/vhace.c b/board/aspeed/ast2400/vhace.c
+new file mode 100755
+index 0000000..d045cbd
+--- /dev/null
++++ b/board/aspeed/ast2400/vhace.c
+@@ -0,0 +1,66 @@
++/*
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#define HASH_GLOBALS
++#include "type.h"
++#include "vdef.h"
++#include "vhace.h"
++#include "vfun.h"
++
++void HashAst3000(ULONG ulLength, ULONG *output, ULONG ulHashMode)
++{
++ ULONG i, ulTemp, ulCommand, ulDigestLength;
++ ULONG ulValue;
++
++ /* Get Info */
++ switch (ulHashMode)
++ {
++ case VHASHMODE_MD5:
++ ulCommand = VHASH_ALG_SELECT_MD5;
++ ulDigestLength = 16;
++ break;
++ case VHASHMODE_SHA1:
++ ulCommand = VHASH_ALG_SELECT_SHA1;
++ ulDigestLength = 20;
++ break;
++ case VHASHMODE_SHA256:
++ ulCommand = VHASH_ALG_SELECT_SHA256;
++ ulDigestLength = 32;
++ break;
++ case VHASHMODE_SHA224:
++ ulCommand = VHASH_ALG_SELECT_SHA224;
++ ulDigestLength = 28;
++ break;
++ }
++
++ /* Init. HW */
++ WriteMemoryLongHost(VHAC_REG_BASE, VREG_HASH_SRC_BASE_OFFSET, g_HashSrcBuffer);
++ WriteMemoryLongHost(VHAC_REG_BASE, VREG_HASH_DST_BASE_OFFSET, g_HashDstBuffer);
++ WriteMemoryLongHost(VHAC_REG_BASE, VREG_HASH_LEN_OFFSET, ulLength);
++
++ /* write src */
++ //already fill in g_VIDEO1_COMPRESS_BUF_ADDR
++
++ /* fire cmd */
++ WriteMemoryLongHost(VHAC_REG_BASE, VREG_HASH_CMD_OFFSET, ulCommand);
++
++ /* get digest */
++ do {
++ ulTemp = ReadMemoryLongHost(VHAC_REG_BASE, VREG_HASH_STATUS_OFFSET);
++ } while (ulTemp & VHASH_BUSY);
++
++ for (i=0; i<ulDigestLength/4; i++)
++ {
++ ulValue = *(((ULONG *)g_HashDstBuffer) + i);
++
++ //output is ULONG pointer
++ *(output + i) = ulValue;
++ }
++}
+diff --git a/board/aspeed/ast2400/vhace.h b/board/aspeed/ast2400/vhace.h
+new file mode 100755
+index 0000000..460989b
+--- /dev/null
++++ b/board/aspeed/ast2400/vhace.h
+@@ -0,0 +1,58 @@
++/*
++ * 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 _VHACE_H_
++#define _VHACE_H_
++
++#define VHASHMODE_MD5 0x00
++#define VHASHMODE_SHA1 0x01
++#define VHASHMODE_SHA256 0x02
++#define VHASHMODE_SHA224 0x03
++
++#define VHASH_ALG_SELECT_MASK 0x70
++#define VHASH_ALG_SELECT_MD5 0x00
++#define VHASH_ALG_SELECT_SHA1 0x20
++#define VHASH_ALG_SELECT_SHA224 0x40
++#define VHASH_ALG_SELECT_SHA256 0x50
++
++#define VHASH_BUSY 0x01
++
++#define VHAC_REG_BASE 0x1e6e0000
++#define VHAC_REG_OFFSET 0x3000
++
++#define VREG_HASH_SRC_BASE_OFFSET (0x20+VHAC_REG_OFFSET)
++#define VREG_HASH_DST_BASE_OFFSET (0x24+VHAC_REG_OFFSET)
++#define VREG_HASH_KEY_BASE_OFFSET (0x28+VHAC_REG_OFFSET)
++#define VREG_HASH_LEN_OFFSET (0x2C+VHAC_REG_OFFSET)
++#define VREG_HASH_CMD_OFFSET (0x30+VHAC_REG_OFFSET)
++
++#define VREG_HASH_STATUS_OFFSET (0x1C+VHAC_REG_OFFSET)
++
++typedef struct
++{
++ int HashMode;
++ int DigestLen;
++} HASH_METHOD;
++
++
++#ifdef HASH_GLOBALS
++#define HASH_EXT
++#else
++#define HASH_EXT extern
++#endif
++
++HASH_EXT HASH_METHOD g_HashMethod;
++HASH_EXT BYTE g_DigestBuf[32];
++HASH_EXT ULONG g_HashSrcBuffer;
++HASH_EXT ULONG g_HashDstBuffer;
++
++void HashAst3000(ULONG ulLength, ULONG *output, ULONG ulHashMode);
++#endif
++
+diff --git a/board/aspeed/ast2400/videotest.c b/board/aspeed/ast2400/videotest.c
+new file mode 100755
+index 0000000..f2e4953
+--- /dev/null
++++ b/board/aspeed/ast2400/videotest.c
+@@ -0,0 +1,779 @@
++/*
++ * 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
++ */
++
++/*
++ * Diagnostics support
++ */
++#include <common.h>
++#include <command.h>
++#include <malloc.h>
++#include <post.h>
++
++#include "slt.h"
++#define WIN_GLOBALS
++#include "type.h"
++#include "vreg.h"
++#define VESA_GLOBALS
++#include "vesa.h"
++#include "vfun.h"
++#include "vdef.h"
++#include "vhace.h"
++#include "crt.h"
++#include "videotest.h"
++
++#define VHASH_ALIGNMENT 16
++#define VHASH_MAX_DST (32+VHASH_ALIGNMENT)
++
++
++#if ((CFG_CMD_SLT & CFG_CMD_VIDEOTEST) && defined(CONFIG_SLT))
++#include "videotest.h"
++
++#define RAND_MAX 32767 //2^16-1
++
++ULONG randSeed = 1;
++
++void srand(ULONG seed)
++{
++ randSeed = seed;
++}
++
++int rand(void)
++{
++ randSeed = randSeed * 214013 + 2531011;
++ return (int)(randSeed >> 17); //32 -15 = 17
++}
++
++//static unsigned char CaptureVideo1Buf1Addr[VIDEO_SOURCE_SIZE], CaptureVideo1Buf2Addr[VIDEO_SOURCE_SIZE], Video1CompressBufAddr[CRYPTO_MAX_CONTEXT];
++ULONG pCaptureVideo1Buf1Addr[VIDEO_SOURCE_SIZE/4], pCaptureVideo1Buf2Addr[VIDEO_SOURCE_SIZE/4], pVideo1CompressBufAddr[VIDEO_MAX_STREAM_SIZE/4], pVideo1FlagBufAddr[VIDEO_FLAG_SIZE];
++ULONG pCaptureVideo2Buf1Addr[VIDEO_SOURCE_SIZE/4], pCaptureVideo2Buf2Addr[VIDEO_SOURCE_SIZE/4], pVideo2CompressBufAddr[VIDEO_MAX_STREAM_SIZE/4], pVideo2FlagBufAddr[VIDEO_FLAG_SIZE];
++
++ULONG pVHashDstBuffer[VHASH_MAX_DST/4];
++
++ULONG pVideo1DecAddr[VIDEO_SOURCE_SIZE/4];
++ULONG pCrt1Addr[VIDEO_SOURCE_SIZE/4];
++//ULONG pCap1Addr[VIDEO_SOURCE_SIZE/4];
++
++BOOL AllocateEncodeBufHost(ULONG MMIOBase, int nVideo)
++{
++ //ULONG Addr;
++ //ULONG dwRegOffset = nVideo * 0x100;
++
++ if (VIDEO1 == nVideo)
++ {
++
++ //Addr = (ULONG)malloc(pVideoInfo->SrcWidth * pVideoInfo->SrcHeight * 4);
++ //pCaptureVideo1Buf1Addr = malloc(VIDEO_SOURCE_SIZE);
++
++ g_CAPTURE_VIDEO1_BUF1_ADDR = vBufAlign((ULONG)pCaptureVideo1Buf1Addr);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_1_ADDR_REG, g_CAPTURE_VIDEO1_BUF1_ADDR, BUF_1_ADDR_MASK);
++
++ //Addr = (ULONG)malloc(pVideoInfo->SrcWidth * pVideoInfo->SrcHeight * 4);
++ //pCaptureVideo1Buf2Addr = malloc(VIDEO_SOURCE_SIZE);
++
++ g_CAPTURE_VIDEO1_BUF2_ADDR = vBufAlign((ULONG)pCaptureVideo1Buf2Addr);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_2_ADDR_REG, g_CAPTURE_VIDEO1_BUF2_ADDR, BUF_2_ADDR_MASK);
++
++ //Addr = (ULONG)malloc(pVideoInfo->uStreamBufSize.StreamBufSize.RingBufNum * pVideoInfo->uStreamBufSize.StreamBufSize.PacketSize)
++ //pVideo1CompressBufAddr = malloc(VIDEO_MAX_STREAM_SIZE);
++ g_VIDEO1_COMPRESS_BUF_ADDR = vBufAlign((ULONG)pVideo1CompressBufAddr);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_BUF_ADDR_REG, g_VIDEO1_COMPRESS_BUF_ADDR, BUF_2_ADDR_MASK);
++
++ //Addr = (ULONG)malloc((pVideoInfo->SrcHeigh/64) * pVideoInfo->SrcWidth * 8);
++ //g_VIDEO1_CRC_BUF_ADDR = vBufAlign((ULONG)malloc(VIDEO_MAX_STREAM_SIZE));
++ //WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_CRC_BUF_ADDR_REG, g_VIDEO1_CRC_BUF_ADDR, BUF_2_ADDR_MASK);
++
++
++ //Addr = (ULONG)malloc(pVideoInfo->SrcHeigh * pVideoInfo->SrcWidth / 128 (/64*4/8));
++ //pVideo1FlagBufAddr = malloc(VIDEO_FLAG_SIZE);
++ g_VIDEO1_FLAG_BUF_ADDR = vBufAlign((ULONG)pVideo1FlagBufAddr);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_FLAG_BUF_ADDR_REG, g_VIDEO1_FLAG_BUF_ADDR, BUF_2_ADDR_MASK);
++ }
++ else if (VIDEO2 == nVideo)
++ {
++ //Addr = (ULONG)malloc(pVideoInfo->SrcWidth * pVideoInfo->SrcHeight * 4);
++ //pCaptureVideo2Buf1Addr = malloc(VIDEO_SOURCE_SIZE);
++ g_CAPTURE_VIDEO2_BUF1_ADDR = vBufAlign((ULONG)pCaptureVideo2Buf1Addr);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO2_BUF_1_ADDR_REG, g_CAPTURE_VIDEO2_BUF1_ADDR, BUF_1_ADDR_MASK);
++
++ //Addr = (ULONG)malloc(pVideoInfo->SrcWidth * pVideoInfo->SrcHeight * 4);
++ //pCaptureVideo2Buf2Addr = malloc(VIDEO_SOURCE_SIZE);
++ g_CAPTURE_VIDEO2_BUF2_ADDR = vBufAlign((ULONG)pCaptureVideo2Buf2Addr);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO2_BUF_2_ADDR_REG, g_CAPTURE_VIDEO2_BUF2_ADDR, BUF_2_ADDR_MASK);
++
++ //Addr = (ULONG)malloc(pVideoInfo->uStreamBufSize.StreamBufSize.RingBufNum * pVideoInfo->uStreamBufSize.StreamBufSize.PacketSize)
++ //pVideo2CompressBufAddr = malloc(VIDEO_MAX_STREAM_SIZE);
++ g_VIDEO2_COMPRESS_BUF_ADDR = vBufAlign((ULONG)pVideo2CompressBufAddr);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO2_COMPRESS_BUF_ADDR_REG, g_VIDEO2_COMPRESS_BUF_ADDR, BUF_2_ADDR_MASK);
++
++ //Addr = (ULONG)malloc((pVideoInfo->SrcHeigh/64) * pVideoInfo->SrcWidth * 8);
++ //g_VIDEO1_CRC_BUF_ADDR = vBufAlign((ULONG)malloc(VIDEO_MAX_STREAM_SIZE));
++ //WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_CRC_BUF_ADDR_REG, g_VIDEO1_CRC_BUF_ADDR, BUF_2_ADDR_MASK);
++
++
++ //Addr = (ULONG)malloc(pVideoInfo->SrcHeigh * pVideoInfo->SrcWidth / 128 (/64*4/8));
++ //pVideo2FlagBufAddr = malloc(VIDEO_FLAG_SIZE);
++ g_VIDEO2_FLAG_BUF_ADDR = vBufAlign((ULONG)pVideo2FlagBufAddr);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO2_FLAG_BUF_ADDR_REG, g_VIDEO2_FLAG_BUF_ADDR, BUF_2_ADDR_MASK);
++ }
++
++}
++
++/********************************************************/
++/* 1. product random data to encode */
++/* 2. use hash to verify encode function */
++/* 3. use encode stream to decompress original data */
++/********************************************************/
++int CodecTest(void)
++{
++ int num, i=0, j=0;
++ ULONG ulTemp = 0, ulTemp2;
++ int dwValue;
++ ULONG ulHWWp;
++ ULONG ulHWPt;
++
++ //max size
++ ULONG tArray[32/4];
++
++ //mode detection
++ BOOL bExternal = TRUE;
++ BOOL bAnalog = TRUE;
++ ULONG Status;
++
++#if defined(CONFIG_AST2300)
++ ULONG ulHashSha1[5] = {0x3f0c2ad6,0xc8eb7074,0xa9929352,0xfcd5b8b0,0x76fa8461};
++ ULONG aHashDecode[5] = {0xb23b62bb,0xd22a602b,0x113038a0,0x7217c6ab,0xcb156f06};
++#else
++ ULONG ulHashSha1[5] = {0x2a19e99f,0x99b1bb2d,0x9ac82862,0x49205e43,0x6bc4b4d7};
++ ULONG aHashDecode[5] = {0x2907a827,0xaf337079,0x47817f1f,0xb0b7cd68,0x8d33bd2};
++#endif
++
++ //Load pattern to src1 & src2 buffer
++ srand(1);
++
++ //Total size : DefWidth*DeHeight*4
++ //rand function: 16 bits one time is equal to 2 bytes
++ //OutdwmBankMode: 32 bits one time is equal to 4 bytes
++ for (i=0; i<g_DefWidth*g_DefHeight*2; i++)
++ {
++ if (i%2)
++ {
++ ulTemp2 = rand();
++ ulTemp = (ulTemp2 << 16) | ulTemp;
++ //WriteMemoryLongHost(DRAM_BASE, g_CAPTURE_VIDEO1_BUF1_ADDR + ((i-1)/2)*4, ulTemp);
++ *(((ULONG *)g_CAPTURE_VIDEO1_BUF1_ADDR) + (i-1)/2) = ulTemp;
++ ulTemp = 0;
++ }
++ else
++ {
++ ulTemp = rand();
++ }
++ }
++
++ /* init encoder engine */
++ InitializeVideoEngineHost (0,
++ VIDEO1,
++ vModeTable[2].HorPolarity,
++ vModeTable[2].VerPolarity);
++
++ /* reset offset pointer register*/
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG, 0, VIDEO_CODEC_TRIGGER | VIDEO_CAPTURE_TRIGGER);
++
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_BUF_READ_OFFSET_REG, 0, COMPRESS_BUF_READ_OFFSET_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_CODEC_OFFSET_READ, 0, BUF_CODEC_OFFSET_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_BUF_PROCESS_OFFSET_REG, 0, COMPRESS_BUF_PROCESS_OFFSET_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_FRAME_END_READ, 0, COMPRESS_FRAME_END_READ_MASK);
++
++ /* start compress stream */
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG, MODE_DETECTION_TRIGGER, MODE_DETECTION_TRIGGER);
++ //Stream mode: set CODEC trigger first
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG, VIDEO_CODEC_TRIGGER, VIDEO_CODEC_TRIGGER);
++
++ //Stream mode: start trigger (only trigger capture bit)
++ StartVideoCaptureTriggerHost(0, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG);
++
++ //stop engine
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG, 0, 0xFF);
++#if defined(CONFIG_AST2300)
++ do { /* wait compress engine idle */
++ ulTemp = ReadMemoryLongHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG);
++ } while (!(ulTemp & 0x40000));
++#endif
++
++ //read 30 times to get HW write pointer
++ for (i=0; i<30000; i++)
++ ulHWWp = ReadMemoryLongHost(VIDEO_REG_BASE, VIDEO1_BUF_CODEC_OFFSET_READ);
++
++ g_HashSrcBuffer = g_VIDEO1_COMPRESS_BUF_ADDR + 128; //skip encode data 128 byte
++ g_HashDstBuffer = v16byteAlign((unsigned long)pVHashDstBuffer);
++ ulTemp = 300;
++
++ //Enable hash clock
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_STOP_REG, EN_HACE, STOP_HACE_MASK);
++ g_HashMethod.HashMode = VHASHMODE_SHA1;
++ g_HashMethod.DigestLen = 20;
++ HashAst3000(ulTemp, tArray, g_HashMethod.HashMode);
++
++ if (strncmp((const char *)tArray, (const char *)ulHashSha1, g_HashMethod.DigestLen))
++ {
++ printf("[VIDEO] Encoder Test: Wrong\n");
++ //ExitVideoTest();
++ return VIDEO_ENCODE_FAIL;
++ }
++ else
++ {
++ printf("[VIDEO] Encoder Test: Pass\n");
++ }
++
++#if 0
++ /******** prepare for next decoding test at the same chip ***********/
++ ResetVideoHost();
++
++ dwValue=0;
++
++ do
++ {
++ dwValue = UnlockVideoRegHost(0, VIDEO_UNLOCK_KEY);
++ i++;
++ }
++ while ((VIDEO_UNLOCK != dwValue) && (i<10));
++
++ if (VIDEO_UNLOCK != dwValue)
++ {
++ printf("[VIDEO] Video register is locked");
++ return VIDEO_UNLOCK_FAIL;
++ }
++
++ // allocate decoding buffer
++ //Use Compress buffer last time, and Don't need to allocate
++ g_VIDEO1_DECODE_BUF_1_ADDR = g_VIDEO1_COMPRESS_BUF_ADDR;
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_1_ADDR_REG, g_VIDEO1_DECODE_BUF_1_ADDR, BUF_1_ADDR_MASK);
++
++ // pVideo1DecAddr = malloc(VIDEO_SOURCE_SIZE);
++ g_VIDEO1_DECOMPRESS_BUF_ADDR = vBufAlign((unsigned long)pVideo1DecAddr);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_BUF_ADDR_REG, g_VIDEO1_DECOMPRESS_BUF_ADDR, COMPRESS_BUF_ADDR_MASK);
++
++ //Addr = (ULONG)malloc(256);
++ //g_VIDEO1_RC4_BUF_ADDR = Addr;
++ //g_VIDEO1_DECODE_RC4_BUF_ADDR = g_VIDEO1_DECOMPRESS_BUF_ADDR + 0x800000; //assume video size is 8MB for umcompressed buf;
++ //WriteMemoryLongWithMASKClient(VIDEO_REG_BASE, VIDEO1_RC4_TABLE_ADDR, g_VIDEO1_DECODE_RC4_BUF_ADDR, RC4_TABLE_ADDR_MASK);
++
++ //HW recommanded value
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_2_ADDR_REG, g_VIDEO1_DECOMPRESS_BUF_ADDR, BUF_2_ADDR_MASK);
++ //WriteMemoryLongWithMASKClient(VIDEO_REG_BASE, VIDEO1_BUF_2_ADDR_REG, 0, BUF_2_ADDR_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_CRC_BUF_ADDR_REG, 0, BUF_2_ADDR_MASK);
++
++ /* init encoder engine */
++ InitializeVideoEngineClient (0, VIDEO1);
++
++ /* reset offset pointer register*/
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG, 0, VIDEO_CODEC_TRIGGER | VIDEO_CAPTURE_TRIGGER);
++
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_BUF_READ_OFFSET_REG, 0, COMPRESS_BUF_READ_OFFSET_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_CODEC_OFFSET_READ, 0, BUF_CODEC_OFFSET_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_BUF_PROCESS_OFFSET_REG, 0, COMPRESS_BUF_PROCESS_OFFSET_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_FRAME_END_READ, 0, COMPRESS_FRAME_END_READ_MASK);
++
++ StartVideoCodecTriggerHost(0, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG);
++
++ //wrtie SW write pointer
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_DECOMPRESS_BUF_PROCESS_OFFSET_REG, ulHWWp, COMPRESS_BUF_READ_OFFSET_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_DECOMPRESS_BUF_WRITE_OFFSET_REG, ulHWWp, COMPRESS_BUF_READ_OFFSET_MASK);
++
++ i = 0;
++
++ do
++ {
++ ulHWPt = ReadMemoryLongHost(VIDEO_REG_BASE, VIDEO1_BUF_CODEC_OFFSET_READ);
++ i++;
++ }while((ulHWPt != ulHWWp) && (i<10000));
++
++ if (10000 > i)
++ {
++ printf("[VIDEO] Decoder Pointer cannot move!!! /n");
++ //ExitVideoTest();
++ return VIDEO_DECODE_FAIL;
++ }
++
++ //8*8 YUVA block
++ for (i=24; i<g_DefWidth*g_DefHeight; i=i+32)
++ {
++ *(((ULONG *)g_VIDEO1_DECOMPRESS_BUF_ADDR) + i) = 0x0;
++ *(((ULONG *)g_VIDEO1_DECOMPRESS_BUF_ADDR) + i+1) = 0x0;
++ }
++
++ g_HashSrcBuffer = g_VIDEO1_DECOMPRESS_BUF_ADDR;
++ //g_HashDstBuffer = VIDEO1_EN_BASE + VIDEO_ALL_SIZE; //config forward
++
++ ulTemp = 300;
++
++ //Enable hash clock
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_STOP_REG, EN_HACE, STOP_HACE_MASK);
++ g_HashMethod.HashMode = VHASHMODE_SHA1;
++ g_HashMethod.DigestLen = 20;
++ HashAst3000(ulTemp, tArray, g_HashMethod.HashMode);
++
++ if (strncmp((const char *)tArray, (const char *)aHashDecode, g_HashMethod.DigestLen))
++ {
++ printf("[VIDEO] Decoder Test: Wrong\n");
++ //ExitVideoTest();
++ return VIDEO_DECODE_FAIL;
++ }
++ else
++ {
++ printf("[VIDEO] Decoder Test: Pass\n");
++ }
++#endif
++
++ return VIDEO_TEST_OK;
++}
++
++/********************************************************/
++/* Only used in the host */
++/* test function: Mode detection and Capture pattern */
++/********************************************************/
++int CapTest(void)
++{
++ ULONG dwValue, Status;
++ int i;
++ BOOL bAnalog;
++ ULONG HStart, HEnd, VStart, VEnd;
++ USHORT usCRTHor, usCRTVer;
++ ULONG ulHor, ulVer;
++ ULONG ulVGABaseAddr, ulCapAddr;
++ ULONG ulFlag;
++
++ printf("\n --------- Mode Detection Test --------- \n");
++ //clear clear register
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_CONTROL_REG, 0);
++ dwValue = ReadMemoryLongHost(VIDEO_REG_BASE, VIDEO1_CONTROL_REG);
++
++ // Note: Current mode detection procedure has to set signal input 1st
++ //Note: Clear and enable interrupt Encode
++ ClearVideoInterruptHost(0, VIDEO1_MODE_DETECTION_READY_CLEAR);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO_INT_CONTROL_EN_REG, VIDEO1_MODE_DETECTION_READY_INT_EN, VIDEO1_MODE_DETECTION_READY_INT_EN);
++ // Set input signal
++ dwValue |= EXTERNAL_VGA_SOURCE;
++
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_CONTROL_REG, (dwValue <<EXTERNAL_SOURCE_BIT), EXTERNAL_SOURCE_MASK);
++
++// Set H/V stable maximum
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO_MODE_DETECTION_PARAM_REG, (MODEDETECTION_VERTICAL_STABLE_MAXIMUM << VER_STABLE_MAX_BIT), 0x000F0000);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO_MODE_DETECTION_PARAM_REG, (MODEDETECTION_HORIZONTAL_STABLE_MAXIMUM << HOR_STABLE_MAX_BIT), HOR_STABLE_MAX_BIT_MASK);
++// Set H/V stable threshold
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO_MODE_DETECTION_PARAM_REG, (MODEDETECTION_VERTICAL_STABLE_THRESHOLD << VER_STABLE_THRES_BIT), VER_STABLE_THRES_BIT_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO_MODE_DETECTION_PARAM_REG, (MODEDETECTION_HORIZONTAL_STABLE_THRESHOLD << HOR_STABLE_THRES_BIT), HOR_STABLE_THRES_BIT_MASK);
++
++ //Trigger mode detection
++ // turn off WATCH_DOG first
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG, (WATCH_DOG_OFF << WATCH_DOG_ENABLE_BIT), WATCH_DOG_EN_MASK);
++
++ // Note: Clear mode detection ready interrupt
++ //ClearVideoInterrupt(MMIOBase, MODE_DETECTION_READY_CLEAR);
++ StartModeDetectionTriggerHost(0, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG);
++
++
++// Note: Polling mode detection ready interrupt
++ //it sometime take a long time, especially during change mode,
++ //so the loop count must be big, or you can't pull it by timer
++ i = 0;
++ do {
++
++ Status = ReadVideoInterruptHost(0, VIDEO1_MODE_DETECTION_READY_READ);
++ i++;
++ } while ((!Status) & (i<500000));
++
++ if (!Status)
++ {
++ printf("[VIDEO] Mode detection error\n");
++ //ExitVideoTest();
++ return VIDEO_TEST_FAIL;
++ }
++
++ HStart = (ReadMemoryLongHost(VIDEO_REG_BASE, VIDE1_MODE_DETECTION_EDGE_H_REG) & LEFT_EDGE_LOCATION_MASK) >> LEFT_EDGE_LOCATION_BIT;
++ HEnd = (ReadMemoryLongHost(VIDEO_REG_BASE, VIDE1_MODE_DETECTION_EDGE_H_REG) & RIGHT_EDGE_LOCATION_MASK) >> RIGHT_EDGE_LOCATION_BIT;
++
++ VStart = (ReadMemoryLongHost(VIDEO_REG_BASE, VIDE1_MODE_DETECTION_EDGE_V_REG) & TOP_EDGE_LOCATION_MASK) >> TOP_EDGE_LOCATION_BIT;
++ VEnd = (ReadMemoryLongHost(VIDEO_REG_BASE, VIDE1_MODE_DETECTION_EDGE_V_REG) & BOTTOM_EDGE_LOCATION_MASK) >> BOTTOM_EDGE_LOCATION_BIT;
++
++ ulHor = HEnd-HStart+1;
++ ulVer = VEnd-VStart+1;
++
++ printf("[VIDEO] Resolution: H[%d] * V[%d]\n", ulHor, ulVer);
++
++ if ((g_DefWidth == ulHor) & (g_DefHeight == ulVer))
++ {
++ printf("[VIDEO] Mode detection PASS\n");
++ }
++ else
++ {
++ printf("[VIDEO] Mode detection FAIL\n");
++ return VIDEO_TEST_FAIL;
++ }
++
++ if(!((ReadMemoryLongHost(VIDEO_REG_BASE, VIDEO1_MODE_DETECTION_STATUS_READ_REG) & ANALONG_DIGITAL_READ) >> ANALONG_DIGITAL_READ_BIT))
++ bAnalog = FALSE;
++ else
++ bAnalog = TRUE;
++
++ // Note: Clear mode detection ready interrupt
++ ClearVideoInterruptHost(0, VIDEO1_MODE_DETECTION_READY_CLEAR);
++
++ printf("\n --------- Capture Test --------- \n");
++
++ //capture engine
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_TIMEING_GEN_HOR_REG, (HEnd << VIDEO_HDE_END_BIT), VIDEO_HDE_END_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_TIMEING_GEN_HOR_REG, (HStart << VIDEO_HDE_START_BIT), VIDEO_HDE_START_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_TIMEING_GEN_V_REG, (VEnd << VIDEO_VDE_END_BIT), VIDEO_VDE_END_MASK);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_TIMEING_GEN_V_REG, (VStart << VIDEO_VDE_START_BIT), VIDEO_VDE_START_MASK);
++
++ ulCapAddr = vBufAlign2((ULONG)pCaptureVideo1Buf1Addr);
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_1_ADDR_REG, ulCapAddr, BUF_1_ADDR_MASK);
++
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_2_ADDR_REG, 0, BUF_2_ADDR_MASK);
++
++ InitializeVideoEngineHost (0,
++ VIDEO1,
++ vModeTable[2].HorPolarity,
++ vModeTable[2].VerPolarity);
++
++ WriteMemoryLongHost(VIDEO_REG_BASE, 0x04, 0x01);
++ WriteMemoryLongHost(VIDEO_REG_BASE, 0x300, 0x0);
++#if defined(CONFIG_AST2300)
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, 0x8, 0x0880, 0x0ec0);
++#elif defined(CONFIG_AST3000)
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, 0x8, 0x2800, 0x2800);
++#else
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, 0x8, 0xa00, 0x2a80); //tile mode
++#endif
++
++ WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_TIMEING_GEN_HOR_REG, 0xa0000000, 0xa0000000);
++
++ //only trigger capture, in source buffer (vr44), the front of data is correct.
++ //StartVideoCaptureTriggerHost(0, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG);
++ WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG, VIDEO_CAPTURE_TRIGGER);
++
++ i = 0;
++ do {
++ Status = ReadMemoryLongHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG) & CAPTURE_READY_MASK;
++ i++;
++ } while ((!Status) & (i<500000));
++
++ if (!Status)
++ {
++ printf("[VIDEO] Capture is not READY\n");
++ return VIDEO_TEST_FAIL;
++ }
++
++#if !defined(CONFIG_AST2300)
++ ulVGABaseAddr = ulCapAddr + 0x1000;
++
++ /* check pattern */
++ ulFlag = 0; //no 0 is error
++
++ for (i=0; i<100; i++)
++ {
++ dwValue = *(ULONG *)(ulVGABaseAddr + i*32);
++ if (0x32323232 != dwValue)
++ {
++ printf("[VIDEO] Capture Test fail -- capture data doesn't match source \n");
++ printf("[VIDEO]1 i=%d value=%x\n", i, dwValue);
++ ulFlag = 1;
++ break;
++ }
++
++ dwValue = *(ULONG *)(ulVGABaseAddr + i*32 + 4);
++ if (0x32323232 != dwValue)
++ {
++ printf("[VIDEO] Capture Test fail -- capture data doesn't match source \n");
++ printf("[VIDEO]2 i=%d value=%x\n", i, dwValue);
++ ulFlag = 1;
++ break;
++ }
++
++ dwValue = *(ULONG *)(ulVGABaseAddr + i*32 + 8);
++ if (0x80808080 != dwValue)
++ {
++ printf("[VIDEO] Capture Test fail -- capture data doesn't match source \n");
++ printf("[VIDEO]3 i=%d value=%x\n", i, dwValue);
++ ulFlag = 1;
++ break;
++ }
++
++ dwValue = *(ULONG *)(ulVGABaseAddr + i*32 + 12);
++ if (0x80808080 != dwValue)
++ {
++ printf("[VIDEO] Capture Test fail -- capture data doesn't match source \n");
++ printf("4 i=%d value=%x\n", i, dwValue);
++ ulFlag = 1;
++ break;
++ }
++
++ dwValue = *(ULONG *)(ulVGABaseAddr + i*32 + 16);
++ if (0x80808080 != dwValue)
++ {
++ printf("[VIDEO] Capture Test fail -- capture data doesn't match source \n");
++ printf("5 i=%d value=%x\n", i, dwValue);
++ ulFlag = 1;
++ break;
++ }
++
++ dwValue = *(ULONG *)(ulVGABaseAddr + i*32 + 20);
++ if (0x80808080 != dwValue)
++ {
++ printf("[VIDEO] Capture Test fail -- capture data doesn't match source \n");
++ printf("6 i=%d value=%x\n", i, dwValue);
++ ulFlag = 1;
++ break;
++ }
++ }
++#endif
++
++ if (!ulFlag)
++ {
++ printf("[VIDEO] Capture Test OK\n");
++ }
++ else
++ {
++ printf("[VIDEO] Capture Test FAIL\n");
++ return VIDEO_TEST_FAIL;
++ }
++
++ return VIDEO_TEST_OK;
++}
++
++/********************************************************/
++/* Only used in the station */
++/********************************************************/
++int CRTTest(void)
++{
++ ULONG ulVGABaseAddr;
++ BYTE btCRTCenterMode, btCRTColorFmt;
++ USHORT usCRTHor, usCRTVer;
++ ULONG ulData;
++
++ int i,j;
++
++ //printf("\n --------- Turn on CRT --------- \n");
++
++ //Enable CRT1 first
++ ulVGABaseAddr = vBufAlign((unsigned long)pCrt1Addr);
++
++ btCRTCenterMode = 0;
++ btCRTColorFmt = YUV_444;
++ usCRTHor = g_DefWidth;
++ usCRTVer = g_DefHeight;
++
++ CheckOnStartClient();
++
++ /* Fill Pattern */
++ for (i=0; i<usCRTHor; i++)
++ {
++ for (j=0; j<usCRTVer/8; j++)
++ {
++ //Y
++ //ulData = 0x10101010;
++ ulData = 0x32323232;
++ *(ULONG *)(ulVGABaseAddr + (i*usCRTVer*4+j*32)) = ulData;
++ //ulData = 0x10101010;
++ ulData = 0x32323232;
++ *(ULONG *)(ulVGABaseAddr + (i*usCRTVer*4+j*32) +4) = ulData;
++ //U
++ ulData = 0x80808080;
++ //ulData = 0x77777777;
++ *(ULONG *)(ulVGABaseAddr + (i*usCRTVer*4+j*32) +8) = ulData;
++ ulData = 0x80808080;
++ //ulData = 0x77777777;
++ *(ULONG *)(ulVGABaseAddr + (i*usCRTVer*4+j*32) +12) = ulData;
++ //V
++ ulData = 0x80808080;
++ //ulData = 0x11111111;
++ *(ULONG *)(ulVGABaseAddr + (i*usCRTVer*4+j*32) +16) = ulData;
++ ulData = 0x80808080;
++ //ulData = 0x11111111;
++ *(ULONG *)(ulVGABaseAddr + (i*usCRTVer*4+j*32) +20) = ulData;
++ //A
++ ulData = 0xFFFFFFFFF;
++ *(ULONG *)(ulVGABaseAddr + (i*usCRTVer*4+j*32) +24) = ulData;
++ ulData = 0xFFFFFFFFF;
++ *(ULONG *)(ulVGABaseAddr + (i*usCRTVer*4+j*32) +28) = ulData;
++ }
++ } /* ~Fill Pattern */
++
++#if defined(CONFIG_AST2300)
++ if(!ASTSetModeV (0, CRT_2, ulVGABaseAddr, usCRTHor, usCRTVer, btCRTColorFmt, btCRTCenterMode))
++#else
++ if(!ASTSetModeV (0, CRT_1, ulVGABaseAddr, usCRTHor, usCRTVer, btCRTColorFmt, btCRTCenterMode))
++#endif
++ {
++ printf("[VIDEO] The resolution is not in mode table list\n");
++ return CRT_FAIL;
++ }
++
++ //printf("[VIDEO] CRT turn on\n");
++
++ return VIDEO_TEST_OK;
++}
++
++int do_videotest (void)
++{
++ int dwValue=0;
++ int i = 0;
++ int iRet;
++ ULONG ulRestore1, ulTemp;
++ BOOL bClient;
++
++
++ //InitVideoTest();
++ g_DefWidth = 640;
++ g_DefHeight= 480;
++
++ printf("\n --------- Codec Test --------- \n");
++
++#if defined(CONFIG_AST2300)
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CONTROL_REG, 0x00002000, 0x00002000);
++#endif
++
++ CheckOnStartHost();
++
++ do
++ {
++ dwValue = UnlockVideoRegHost(0, VIDEO_UNLOCK_KEY);
++ i++;
++ }
++ while ((VIDEO_UNLOCK != dwValue) && (i<1000));
++
++ if (VIDEO_UNLOCK != dwValue)
++ {
++ printf("[VIDEO] Video register is locked \n");
++ return VIDEO_TEST_FAIL;
++ }
++ AllocateEncodeBufHost(0, VIDEO1);
++
++ iRet = CodecTest();
++ if (iRet)
++ return VIDEO_TEST_FAIL;
++
++#if defined(CONFIG_AST2300)
++ /* Init SCU */
++ WriteMemoryLongWithMASKHost(SCU_BASE, (0x2c + SCU_OFFSET), 0x00040000, 0x00040010); /* Enable D2-PLL */
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_STOP_REG, 0, 0x00000400); /* Enable D2CLK */
++ udelay(10);
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CONTROL_REG, 0, 0x00002000);
++
++ WriteMemoryLongWithMASKHost(SCU_BASE, (0x90 + SCU_OFFSET), 0x20, 0x00000030); /* enable video mode single edge */
++ WriteMemoryLongWithMASKHost(SCU_BASE, (0x84 + SCU_OFFSET), 0xfffe0000, 0xfffe0000); /* multi-pins */
++ WriteMemoryLongWithMASKHost(SCU_BASE, (0x88 + SCU_OFFSET), 0x000fffff, 0x000fffff); /* multi-pins */
++
++ iRet = CRTTest();
++ if (iRet)
++ {
++ printf("[VIDEO] CRT Test Failed \n");
++ return VIDEO_TEST_FAIL;
++ }
++
++ iRet = CapTest();
++ if (iRet)
++ {
++ printf("[VIDEO] Capture Test Failed \n");
++ return VIDEO_TEST_FAIL;
++ }
++#else
++ //Host or Client
++ bClient = ((ReadMemoryLong(SCU_BASE, SCU_HW_TRAPPING_REG) & CLIENT_MODE_EN_MASK)?TRUE:FALSE);
++ //reset video for another testing
++ ResetVideoHost();
++ dwValue=0;
++ i = 0;
++ do
++ {
++ dwValue = UnlockVideoRegHost(0, VIDEO_UNLOCK_KEY);
++ i++;
++ }
++ while ((VIDEO_UNLOCK != dwValue) && (i<10));
++
++ if (VIDEO_UNLOCK != dwValue)
++ {
++ printf("[VIDEO] Video register is locked");
++ return VIDEO_UNLOCK_FAIL;
++ }
++
++ //check if 1e6e0008[3,0] is 0
++ ulRestore1 = ReadMemoryLongHost(0x1e6e0000, 8);
++ dwValue = ReadMemoryLongHost(0x1e6e0000, 8)&0xF;
++
++ //set 1e6e0008[3,0] to 0
++ if (dwValue)
++ {
++ WriteMemoryLongHost(0x1e6e0000, 0, 0xfc600309);
++
++ i=0;
++ do
++ {
++ i++;
++ dwValue = ReadMemoryLongHost(0x1e6e0000,0);
++ }while((1 != dwValue)&& (i<10));
++
++ if (1 != dwValue)
++ {
++ printf("0x1e6e0000 is locked");
++ return VIDEO_UNLOCK_FAIL;
++ }
++ }
++
++ //only clear 1e6e0008[3,0]
++ WriteMemoryLongWithMASKHost(0x1e6e0000, 8, 0, 0xf);
++
++ bClient = 0;
++ if (!bClient)
++ {
++ //To turn on crt, must be the client mode
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_HW_TRAPPING_REG, (BE_CLIENT_CHIP << CLIENT_MODE_EN_BIT), CLIENT_MODE_EN_MASK);
++
++ iRet = CRTTest();
++
++ if (iRet)
++ {
++ //trapping to host, the Vsync of CRT can't output and the host doesn't have video sync input
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_HW_TRAPPING_REG, (BE_HOST_CHIP << CLIENT_MODE_EN_BIT), CLIENT_MODE_EN_MASK);
++ //restore value
++ WriteMemoryLongHost(0x1e6e0000, 8, ulRestore1);
++ //lock register
++ WriteMemoryLongHost(0x1e6e0000, 0, 0x12345678);
++ return VIDEO_TEST_FAIL;
++ }
++
++ iRet = CapTest();
++
++ if (iRet)
++ {
++ //trapping to host, the Vsync of CRT can't output and the host doesn't have video sync input
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_HW_TRAPPING_REG, (BE_HOST_CHIP << CLIENT_MODE_EN_BIT), CLIENT_MODE_EN_MASK);
++ //restore value
++ WriteMemoryLongHost(0x1e6e0000, 8, ulRestore1);
++ //lock register
++ WriteMemoryLongHost(0x1e6e0000, 0, 0x12345678);
++
++ return VIDEO_TEST_FAIL;
++ }
++ //WriteMemoryLongWithMASKHost(SCU_BASE, SCU_HW_TRAPPING_REG, (BE_HOST_CHIP << CLIENT_MODE_EN_BIT), CLIENT_MODE_EN_MASK);
++ }
++ //trapping to host, the Vsync of CRT can't output and the host doesn't have video sync input
++ WriteMemoryLongWithMASKHost(SCU_BASE, SCU_HW_TRAPPING_REG, (BE_HOST_CHIP << CLIENT_MODE_EN_BIT), CLIENT_MODE_EN_MASK);
++ //restore value
++ WriteMemoryLongHost(0x1e6e0000, 8, ulRestore1);
++ //lock register
++ WriteMemoryLongHost(0x1e6e0000, 0, 0x12345678);
++#endif
++
++ return VIDEO_TEST_OK;
++}
++#endif /* CONFIG_SLT */
+diff --git a/board/aspeed/ast2400/videotest.h b/board/aspeed/ast2400/videotest.h
+new file mode 100755
+index 0000000..79b8dd9
+--- /dev/null
++++ b/board/aspeed/ast2400/videotest.h
+@@ -0,0 +1,24 @@
++/*
++ * 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
++ */
++/* VideoTest.h */
++#ifndef _VIDEOTEST_H_
++#define _VIDEOTEST_H_
++
++#define VIDEO_TEST_OK 0
++#define VIDEO_TEST_FAIL 1
++
++#define VIDEO_UNLOCK_FAIL 1
++#define VIDEO_ENCODE_FAIL 2
++#define VIDEO_DECODE_FAIL 3
++#define CRT_FAIL 4
++
++#endif /* _VIDEOTEST_H_ */
++
+diff --git a/board/aspeed/ast2400/vreg.h b/board/aspeed/ast2400/vreg.h
+new file mode 100755
+index 0000000..9738548
+--- /dev/null
++++ b/board/aspeed/ast2400/vreg.h
+@@ -0,0 +1,845 @@
++/*
++ * 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 _VREG_H_
++#define _VREG_H_
++
++/********************************************************/
++/* CRT register */
++/********************************************************/
++#define CRT_BASE_ADDRESS 0x000400
++#define VGA_GRAPH_BASE_ADDRESS 0x600000
++#define VGA_CURSOR_BASE_ADDRESS 0x300000
++#define VGA_OSD_BASE_ADDRESS 0x300000
++#define RGB_565 0x0
++#define RGB_888 0x1
++#define YUV_444 0x2
++#define NO_SUPPORTED_CRT_FMT 0x3
++#define CRT_LOW_THRESHOLD_VALUE 0x12
++#define CRT_HIGH_THRESHOLD_VALUE 0x1E
++
++// AST3000's Registers
++#ifdef Watcom
++#define VIDEOBASE_OFFSET 0x10000
++#else
++#define VIDEOBASE_OFFSET 0x0
++#endif
++
++#define KEY_CONTROL_REG 0x00 + VIDEOBASE_OFFSET
++ #define VIDEO_LOCKED 0
++ #define VIDEO_UNLOCK 1
++
++// Registers for video1 and video2
++#define VIDEO1_ENGINE_SEQUENCE_CONTROL_REG 0x04 + VIDEOBASE_OFFSET
++#define VIDEO2_ENGINE_SEQUENCE_CONTROL_REG 0x104 + VIDEOBASE_OFFSET
++ #define MODE_DETECTION_TRIGGER 0x00000001 //Bit[0] trigger HW auto mode detection
++ #define VIDEO_CAPTURE_TRIGGER 0x00000002 //Bit[1] trigger HW to capture video
++ #define FORCE_HW_IDLE_MASK (1<<2) //Bit[2] Force engine into ready(idle) state
++ #define ENGINE_RESET (0<<2)
++ #define ENGINE_IDLE (1<<2)
++ #define VIDEO_CAPTURE_AUTO_MODE 0x00000008 //Bit[3]
++ #define CAPTURE_FRAME_MODE 0
++ #define CAPTURE_AUTO_MODE 1
++ #define CAPTURE_AUTO_MODE_BIT 3
++ #define CAPTURE_AUTO_MODE_MASK 0x00000008
++ #define VIDEO_CODEC_TRIGGER 0x00000010 //Bit[4] trigger HW to compress or decompress video
++ #define CODEC_TRIGGER_BIT 4
++ #define CODEC_TRIGGER_MASK 0x00000010
++ #define CLEAR_CODEC_TRIGGER 0
++ #define EN_CODEC_TRIGGER 1
++ #define VIDEO_CODEC_AUTO_MODE 0x00000020 //Bit[5]
++ #define CODEC_FRAME_MODE 0
++ #define CODEC_AUTO_MODE 1
++ #define CODEC_AUTO_MODE_BIT 5
++ #define CODEC_AUTO_MODE_MASK 0x00000020
++ #define INSERT_FULL_FRAME_MASK (1<<6) //Bit[6] Insert full frame compression
++ #define INSERT_FULL_FRAME_EN (1<<6)
++ #define INSERT_FULL_FRAME_OFF (0<<6)
++ #define WATCH_DOG_ENABLE 0x00000080 //Bit[7] Video Enable watch dog for mode change detection
++ #define WATCH_DOG_ENABLE_BIT 7
++ #define WATCH_DOG_OFF 0
++ #define WATCH_DOG_EN 1
++ #define WATCH_DOG_EN_MASK 0x00000080
++ #define VIDEO_CRT_SELECTION 0x00000100 //Bit[8]
++ #define CRT1 0
++ #define CRT2 1
++ #define ANTI_TEARING_ENABLE 0x00000200 //Bit[9] Anti-tearing mode enable for decoding
++ #define ANTI_TEARING_EN 1
++ #define STREAM_DATA_MODE 0x00000400 //Bit[11:10] Buffer and Stream Data type
++ #define STREAM_DATA_MODE_BIT 10
++ #define STREAM_DATA_MODE_MASK 0x00000C00
++ #define YUV444_MODE 0
++ #define YUV420_MODE 1
++ #define YUV420_MODE_WITH_AST2000 2 //AST2000 compatible
++ #define VIDEO_CAPTURE_READY 0x00010000 //Bit[16] Video capture ready status read back(read only)
++ #define CAPTURE_READY_MASK 0x00010000
++ #define HW_BUSY 0
++ #define HW_IDLE 1
++ #define VIDEO_CODEC_READY 0x00040000 //Bit[18] Video codec ready status read back(read only)
++ #define CODEC_READY_MASK 0x00040000
++ //#define HW_BUSY 0
++ //#define HW_IDLE 1
++
++#define VIDEO1_CONTROL_REG 0x08 + VIDEOBASE_OFFSET
++#define VIDEO2_CONTROL_REG 0x108 + VIDEOBASE_OFFSET
++ #define VIDEO_HSYNC_POLARITY 0x00000001 //Bit[0] Video source hsync polarity
++ #define VIDEO_HSYNC_POLARITY_BIT 0
++ #define NO_INVERSE_POL 0
++ #define INVERSE_POL 1
++ #define VIDEO_VSYNC_POLARITY 0x00000002 //Bit[1] Video source vsync polarity
++ #define VIDEO_VSYNC_POLARITY_BIT 1
++ //Setting defination the same as VIDEO_HSYNC_POLARITY
++ #define VIDEO_EXTERNAL_SOURCE 0x00000004 //Bit[2] Video external source
++ #define EXTERNAL_SOURCE_BIT 2
++ #define INTERNAL_VGA_SOURCE 0
++ #define EXTERNAL_VGA_SOURCE 1
++ #define EXTERNAL_SOURCE_MASK 0x00000004
++ #define VIDEO_ANALONG_EXTERNAL_SOURCE 0x00000008 //Bit[3] Video Analog external source
++ #define ANALONG_EXTERNAL_SOURCE_BIT 3
++ #define DVI_SOURCE 0
++ #define ANALOG_RGB_SOURCE 1
++ #define VIDEO_INTERNAL_TIMING_GEN 0x00000010 //Bit[4] Video Use internal timing generator
++ #define INTERNAL_TIMING_GEN_BIT 4
++ #define EXTERNAL_DE_SIGNAL 0 //DVI only
++ #define VR0C_VR10_DE_SINGAL 1 //use VR0C and VR10 for generate VDE signal
++ /****** Video2 Only from DAC ******/
++ #define VIDEO1_CAPTURE_FROM 0x00000020 //Bit[5] Video1 capture data direct from VGA frame buffer(internal VGA only)
++ #define FROM_DAC_PORT 0
++ #define FROM_FRAME_BUFFER 1
++ #define WRITE_DATA_FORMAT 0x00000040 //Bit[7:6] Write data format
++ #define WRITE_DATA_FORMAT_BIT 6
++ #define WRTIE_DATA_FORMAT_MASK 0x000000C0
++ #define CCIR601_2_YUV_FORMAT 0
++ #define FULL_YUV_FORMAT 1
++ #define RGB_FORMAT 2
++ #define VGA_CURSOR_DISABLE 0x00000100 //Bit[8] External video port slection
++ #define VGA_CURSOR_NORMAL 0
++ #define VGA_CURSOR_OFF 1
++ #define VIDEO_CAPTURE_LINEAR_MODE 0x00000200 //Bit[9] VIDEO_CAPTURE_LINEAR_MODE
++ #define LINEAR_MODE 0
++ #define TILE_MODE 1
++ #define VIDEO_CLOCK_DELAY 0x00000400 //Bit[11:10] Video clock delay control
++ #define VIDEO_CLOCK_DELAY_BIT 10
++ #define VIDEO_CLOCK_DELAY_MASK 0x00000C00
++ #define DELAY_0_NS 0
++ #define DELAY_1_NS 1
++ #define INV_AND_DELAY_0_NS 2
++ #define INV_AND_DELAY_1_NS 3
++ #define VIDEO_CCIR656_SOURCE_MODE 0x00001000 //Bit[12] Video CCIR656 source mode
++ #define RGB_SOURCE_MODE 0
++ #define CCIR656_SOURCE_MODE 1
++ #define SOURCE_PORT_CLOCK_MODE 0x00002000 //Bit[13] Video Source port clock mode
++ #define SINGLE_EDGE_MODE 0
++ #define DUAL_EDGE_MODE 1
++ #define EXTERNAL_PORT_SELECTION 0x00004000 //Bit[14] External video port slection
++ #define VIDEO_PORT_A 0
++ #define VIDEO_PORT_B 1
++ #define VIDEO_CAPTURE_FRAME_RATE 0x00010000 //Bit[23:16] Video capture frame rate control
++ #define VIDEO_CAPTURE_FRAME_RATE_BIT 16
++ #define VIDEO_CAPTURE_FRAME_RATE_MASK 0x00FF0000 //Maximum frame rate = XX * SourceFPS / 60
++
++#define VIDEO1_TIMEING_GEN_HOR_REG 0x0C + VIDEOBASE_OFFSET
++#define VIDEO2_TIMEING_GEN_HOR_REG 0x10C + VIDEOBASE_OFFSET
++ #define VIDEO_HDE_END 0x00000000 //Bit[12:0] Video HDE End timing generator
++ #define VIDEO_HDE_END_BIT 0 //Number of pixels from rising edge of Hsync for first active pixel
++ #define VIDEO_HDE_END_MASK 0x00001FFF
++ #define VIDEO_HDE_START 0x00010000 //Bit[28:16] Video HDE Start timing generator
++ #define VIDEO_HDE_START_BIT 16 //Number of pixels from rising edge of Hsync for last active pixel
++ #define VIDEO_HDE_START_MASK 0x1FFF0000
++ #define FRAME_RATE_OFF 0
++
++#define VIDEO1_TIMEING_GEN_V_REG 0x10 + VIDEOBASE_OFFSET
++#define VIDEO2_TIMEING_GEN_V_REG 0x110 + VIDEOBASE_OFFSET
++ #define VIDEO_VDE_END 0x00000001 //Bit[11:0] Video VDE End timing generator
++ #define VIDEO_VDE_END_BIT 0 //Number of pixels from rising edge of Vsync for first active pixel
++ #define VIDEO_VDE_END_MASK 0x00000FFF
++ #define VIDEO_VDE_START 0x00010000 //Bit[27:16] Video VDE Start timing generator
++ #define VIDEO_VDE_START_BIT 16 //Number of pixels from rising edge of Vsync for last active pixel
++ #define VIDEO_VDE_START_MASK 0x0FFF0000
++
++#define VIDEO1_SCALE_FACTOR_REG 0x14 + VIDEOBASE_OFFSET
++#define VIDEO2_SCALE_FACTOR_REG 0x114 + VIDEOBASE_OFFSET
++ #define HOR_SCALING_FACTOR 0x00000001 //Bit[15:0] Video Horizontal scaling factor
++ #define HOR_SCALING_FACTOR_BIT 0 //The formula=4096/(Horizontal scaling facotr)
++ #define HOR_SCALING_FACTOR_MASK 0x0000FFFF
++ #define VER_SCALING_FACTOR 0x00000000 //Bit[31:16] Video Vertical scaling factor
++ #define VER_SCALING_FACTOR_BIT 16 //The formula=4096/(Vertical scaling facotr)
++ #define VER_SCALING_FACTOR_MASK 0xFFFF0000
++
++#define VIDEO1_SCALE_FACTOR_PARAMETER0_REG 0x18 + VIDEOBASE_OFFSET //Scaling Parameters F00, F01, F02, F03
++#define VIDEO2_SCALE_FACTOR_PARAMETER0_REG 0x118 + VIDEOBASE_OFFSET
++
++#define VIDEO1_SCALE_FACTOR_PARAMETER1_REG 0x1C + VIDEOBASE_OFFSET //Scaling Parameters F10, F11, F12, F13
++#define VIDEO2_SCALE_FACTOR_PARAMETER1_REG 0x11C + VIDEOBASE_OFFSET
++
++#define VIDEO1_SCALE_FACTOR_PARAMETER2_REG 0x20 + VIDEOBASE_OFFSET //Scaling Parameters F20, F21, F22, F23
++#define VIDEO2_SCALE_FACTOR_PARAMETER2_REG 0x120 + VIDEOBASE_OFFSET
++
++#define VIDEO1_SCALE_FACTOR_PARAMETER3_REG 0x24 + VIDEOBASE_OFFSET //Scaling Parameters F30, F31, F32, F33
++#define VIDEO2_SCALE_FACTOR_PARAMETER3_REG 0x124 + VIDEOBASE_OFFSET
++
++#define VIDEO1_BCD_CONTROL_REG 0x2C + VIDEOBASE_OFFSET
++#define VIDEO2_BCD_CONTROL_REG 0x12C + VIDEOBASE_OFFSET
++ #define BCD_ENABLE 0x00000001 //Bit[0] Enable block change detection(BCD)
++ #define BCD_ENABLE_BIT 0
++ #define BCD_ENABLE_MASK 0x00000001
++ #define BCD_TOLERANCE 0x00010000 //Bit[23:16]
++ #define BCD_TOLERANCE_BIT 16 //flag as changed block when the video data difference greater
++ #define BCD_TOLERANCE_MASK 0x00FF0000
++
++#define VIDEO1_CAPTURE_WINDOWS_REG 0x30 + VIDEOBASE_OFFSET
++#define VIDEO2_CAPTURE_WINDOWS_REG 0x130 + VIDEOBASE_OFFSET
++ #define CAPTURE_VER_LINE 0x00000001 //Bit[10:0] Video compression vertical line total
++ #define CAPTURE_VER_LINE_BIT 0
++ #define CAPTURE_VER_LINE_MASK 0x000007FF
++ #define CAPTURE_HOR_PIXEL 0x00010000 //Bit[26:16] Video compression vertical line total
++ #define CAPTURE_HOR_PIXEL_BIT 16
++ #define CAPTURE_HOR_PIXEL_MASK 0x07FF0000
++
++#define VIDEO1_COMPRESS_WINDOWS_REG 0x34 + VIDEOBASE_OFFSET
++#define VIDEO2_COMPRESS_WINDOWS_REG 0x134 + VIDEOBASE_OFFSET
++ #define COMPRESS_VER_LINE 0x00000001 //Bit[10:0] Video compression vertical line total
++ #define COMPRESS_VER_LINE_BIT 0
++ #define COMPRESS_VER_LINE_MASK 0x000007FF
++ #define COMPRESS_HOR_PIXEL 0x00010000 //Bit[26:16] Video compression vertical line total
++ #define COMPRESS_HOR_PIXEL_BIT 16
++ #define COMPRESS_HOR_PIXEL_MASK 0x07FF0000
++
++#define VIDEO1_COMPRESS_BUF_PROCESS_OFFSET_REG 0x38
++#define VIDEO2_COMPRESS_BUF_PROCESS_OFFSET_REG 0x138
++ #define COMPRESS_BUF_PROCESS_OFFSET_ALIGN 127 //128 byte alignment
++ #define COMPRESS_BUF_PROCESS_OFFSET_MASK 0xFFFFFF
++
++#define VIDEO1_DECOMPRESS_BUF_PROCESS_OFFSET_REG 0x38
++#define VIDEO2_DECOMPRESS_BUF_PROCESS_OFFSET_REG 0x138
++ #define DECOMPRESS_BUF_PROCESS_OFFSET_ALIGN 127 //128 byte alignment
++ #define DECOMPRESS_BUF_PROCESS_OFFSET_MASK 0xFFFFFF
++
++
++//For Compression
++#define VIDEO1_COMPRESS_BUF_READ_OFFSET_REG 0x3C + VIDEOBASE_OFFSET //For stream mode
++#define VIDEO2_COMPRESS_BUF_READ_OFFSET_REG 0x13C + VIDEOBASE_OFFSET
++ #define COMPRESS_BUF_READ_OFFSET_ALIGN 127 //128 byte alignment
++ #define COMPRESS_BUF_READ_OFFSET_MASK 0x00FFFFFF
++//For Decompression
++#define VIDEO1_DECOMPRESS_BUF_WRITE_OFFSET_REG 0x3C + VIDEOBASE_OFFSET //For stream mode
++#define VIDEO2_DECOMPRESS_BUF_WRITE_OFFSET_REG 0x13C + VIDEOBASE_OFFSET
++ #define DECOMPRESS_BUF_WRITE_OFFSET_ALIGN 127 //128 byte alignment
++ #define DECOMPRESS_BUF_WRITE_OFFSET_MASK 0x00FFFFFF
++
++#define VIDEO1_CRC_BUF_ADDR_REG 0x40 + VIDEOBASE_OFFSET
++#define VIDEO2_CRC_BUF_ADDR_REG 0x140 + VIDEOBASE_OFFSET
++ #define CRC_BUF_ADDR_ALIGN 7 //8 byte alignment
++ #define CRC_BUF_ADDR_MASK 0x0FFFFFFF
++
++#define VIDEO1_BUF_1_ADDR_REG 0x44 + VIDEOBASE_OFFSET //For Source Buffer in frame mode
++#define VIDEO2_BUF_1_ADDR_REG 0x144 + VIDEOBASE_OFFSET
++ #define BUF_1_ADDR_ALIGN 255 //256 byte alignment
++ #define BUF_1_ADDR_MASK 0x1FFFFFFF
++
++#define VIDEO1_BUF_LINE_OFFSET_REG 0x48 + VIDEOBASE_OFFSET //Must set both in Frame/Stream mode
++#define VIDEO2_BUF_LINE_OFFSET_REG 0x148 + VIDEOBASE_OFFSET
++ #define BUF_LINE_OFFSET_ALIGN 7 //8 byte alignment
++ #define BUF_LINE_OFFSET_MASK 0x00003FFF
++
++#define VIDEO1_BUF_2_ADDR_REG 0x4C + VIDEOBASE_OFFSET //For BCD Buffer in frame mode
++#define VIDEO2_BUF_2_ADDR_REG 0x14C + VIDEOBASE_OFFSET
++ #define BUF_2_ADDR_ALIGN 255 //256 byte alignment
++ #define BUF_2_ADDR_MASK 0x1FFFFFFF
++
++#define VIDEO1_FLAG_BUF_ADDR_REG 0x50 + VIDEOBASE_OFFSET //For block change flag buffer
++#define VIDEO2_FLAG_BUF_ADDR_REG 0x150 + VIDEOBASE_OFFSET
++ #define FLAG_BUF_ADDR_ALIGN 7 //8 byte alignment
++ #define FLAG_BUF_ADDR_MASK 0x1FFFFFFF
++
++#define VIDEO1_COMPRESS_BUF_ADDR_REG 0x54 + VIDEOBASE_OFFSET //For stream mode
++#define VIDEO2_COMPRESS_BUF_ADDR_REG 0x154 + VIDEOBASE_OFFSET
++ #define COMPRESS_BUF_ADDR_ALIGN 127 //128 byte alignment
++ #define COMPRESS_BUF_ADDR_MASK 0x1FFFFFFF
++
++#define VIDEO1_STREAM_BUF_SIZE 0x58 + VIDEOBASE_OFFSET //For stream mode
++#define VIDEO2_STREAM_BUF_SIZE 0x158 + VIDEOBASE_OFFSET
++ #define STREAM_PACKET_SIZE 0x00000001
++ #define STREAM_PACKET_SIZE_BIT 0
++ #define STREAM_PACKET_SIZE_MASK 0x00000007
++ #define PACKET_SIZE_1KB 0
++ #define PACKET_SIZE_2KB 1
++ #define PACKET_SIZE_4KB 2
++ #define PACKET_SIZE_8KB 3
++ #define PACKET_SIZE_16KB 4
++ #define PACKET_SIZE_32KB 5
++ #define PACKET_SIZE_64KB 6
++ #define PACKET_SIZE_128KB 7
++ #define RING_BUF_PACKET_NUM 0x00000008
++ #define RING_BUF_PACKET_NUM_BIT 3
++ #define RING_BUF_PACKET_NUM_MASK 0x00000018
++ #define PACKETS_4 0
++ #define PACKETS_8 1
++ #define PACKETS_16 2
++ #define PACKETS_32 3
++ #define SKIP_HIGH_MB_THRES 0x00010000 //Bit[22:16] Skip high quality macro block threshold
++ #define SKIP_HIGH_MB_THRES_BIT 16
++ #define SKIP_HIGH_MB_THRES_MASK 0x007F0000
++ #define SKIP_TEST_MODE 0x00800000 //Bit[24:23] Skip test mode
++ #define SKIP_TEST_MODE_BIT 23
++ #define SKIP_TEST_MODE_MASK 0x01800000
++ #define YUV_TEST 2 //recommend
++
++#define VIDEO1_BUF_CODEC_OFFSET_READ 0x5C + VIDEOBASE_OFFSET //For stream mode,
++#define VIDEO2_BUF_CODEC_OFFSET_READ 0x15C + VIDEOBASE_OFFSET //Video stream buffer offset read back(HW)
++ #define BUF_CODEC_OFFSET_ALIGN 255 //256 byte alignment
++ #define BUF_CODEC_OFFSET_MASK 0x00FFFFFF
++
++#define VIDEO1_COMPRESS_CONTROL_REG 0x60 + VIDEOBASE_OFFSET
++#define VIDEO2_COMPRESS_CONTROL_REG 0x160 + VIDEOBASE_OFFSET
++ #define JPEG_ONLY_ENCODE 0x00000001 //Bit[0] JPEG only encoding
++ #define JPEG_ONLY_BIT 0
++ #define JPEG_MIX_MODE 0 //Enable JPEG/VQ mix mode encoding
++ #define JPEG_ONLY_MODE 1 //JPEG encoding mode only
++ #define VQ_4_COLOR_ENCODE 0x00000002 //Bit[1] Enable 4 color VQ encoding
++ #define VQ_4_COLOR_BIT 1
++ #define VQ_1_2_COLOR_MODE 0 //1 and 2 color mode VQ encoding
++ #define VQ_4_COLOR_MODE 1 //1, 2 and 4 color VQ encoding
++ #define QUALITY_CODEC_SETTING 0x00000004 //Bit[2] High and best video quality codec mode setting
++ #define QUALITY_CODEC_SETTING_BIT 2
++ #define JPEG_CODEC_MODE 0 //not supported in best video quality mode
++ #define QUANTI_CODEC_MODE 1
++ #define JPEG_DUAL_QUALITY_EN 0x00000008 //Bit[3] JPEG dual quality mode
++ #define EN_JPEG_DUAL_QUALITY 1 //enable(only for normal video quality mode)
++ #define BEST_QUALITY_EN 0x00000010 //Bit[4] Best quality video mode enable
++ #define BEST_QUALITY_EN_BIT 4
++ #define EN_BEST_QUALITY 1 //enable(only for quantization codec mode)
++ #define RC4_CRYPT_EN 0x00000020 //Bit[5] Enable RC4 encryption/decryption
++ #define RC4_CRYPT_EN_BIT 5
++ #define RC4_CRYPT_EN_MASK 0x00000020
++ #define RC4_CRYPT_ON 1 //enable
++ #define NORMAL_QUANTI_CHROMI_TABLE 0x00000040 //Bit[10:6] Normal video quality mode JPEG DCT chromi quantination table
++ #define NORMAL_QUANTI_CHROMI_TABLE_BIT 6
++ #define NORMAL_QUANTI_CHROMI_TABLE_MASK 0x000007C0
++ #define NORMAL_QUANTI_LUMI_TABLE 0x00000800 //Bit[15:11] Normal video quality mode JPEG DCT lumi quantination table
++ #define NORMAL_QUANTI_LUMI_TABLE_BIT 11
++ #define NORMAL_QUANTI_LUMI_TABLE_MASK 0x0000F800
++ #define HIGH_QUALITY_EN 0x00010000 //Bit[16] High video quality mode enable
++ #define HIGH_QUALITY_EN_BIT 16
++ #define EN_HIGH_QUALITY 1 //Enable
++ #define UV_CIR656_FORMAT 0x00080000 //Bit[19] UV fromat
++ #define UV_CIR656_FORMAT_BIT 19
++ #define USE_UV_CIR656 1 //recommand
++ #define HUFFMAN_TABLE_SELECT 0x00100000 //Bit[20] JPEG Huffman table combination
++ #define DUAL_TABLE 0 //Dual Y, UV table
++ #define SINGLE_TABLE 1 //Single Y table
++ #define SINGLE_UV_TABLE 0x00200000 //1x: Single UV table
++ #define HIGH_QUANTI_CHROMI_TABLE 0x00400000 //Bit[26:22] High quality JPEG DCT chromi quantization table
++ #define HIGH_QUANTI_CHROMI_TABLE_BIT 22
++ #define HIGH_QUANTI_CHROMI_TABLE_MASK 0x07C00000
++ #define HIGH_DEQUANTI_VALUE 0x00400000 //Bit[26:22] High quality de-quantization value
++ #define HIGH_DEQUANTI_VALUE_BIT 22
++ #define HIGH_DEQUANTI_VALUE_MASK 0x07C00000
++ #define HIGH_QUANTI_LUMI_TABLE 0x08000000 //Bit[31:27] High quality JPEG DCT lumi quantization table
++ #define HIGH_QUANTI_LUMI_TABLE_BIT 27
++ #define HIGH_QUANTI_LUMI_TABLE_MASK 0xF8000000
++ #define BEST_DEQUANTI_VALUE 0x08000000 //Bit[31:27] Best quality de-quantization value
++ #define BEST_DEQUANTI_VALUE_BIT 27
++ #define BEST_DEQUANTI_VALUE_MASK 0xF8000000
++
++
++#define VIDEO1_QUANTI_TABLE_LOW_REG 0x64 + VIDEOBASE_OFFSET //Match with 0x60 Bit[10:6], Bit[15:11]
++#define VIDEO2_QUANTI_TABLE_LOW_REG 0x164 + VIDEOBASE_OFFSET
++ #define QUANTI_CHROMI_TABLE_LOW 0x00000001 //Bit[4:0] Normal video low quality block chromi quantization table
++ #define QUANTI_CHROMI_TABLE_LOW_BIT 0
++ #define QUANTI_CHROMI_TABLE_LOW_MASK 0x0000001F
++ #define QUANTI_LUMI_TABLE_LOW 0x00000020 //Bit[9:5] Normal video low quality block lumi quantization table
++ #define QUANTI_LUMI_TABLE_LOW_BIT 5
++ #define QUANTI_LUMI_TABLE_LOW_MASK 0x000003E0
++
++#define VIDEO1_QUANTI_VALUE_REG 0x68 + VIDEOBASE_OFFSET //Match with 0x60 Bit[26:22],Bit[31:27]
++#define VIDEO2_QUANTI_VALUE_REG 0x168 + VIDEOBASE_OFFSET
++ #define HIGH_QUANTI_VALUE 0x00000001 //Bit[14:0] High quality quantization value. Format is 1.14
++ #define HIGH_QUANTI_VALUE_BIT 0
++ #define HIGH_QUANTI_VALUE_MASK 0x00007FFF
++ #define BEST_QUANTI_VALUE 0x00010000 //Bit[30:16] Best quality quantization value. Format is 1.14
++ #define BEST_QUANTI_VALUE_BIT 16
++ #define BEST_QUANTI_VALUE_MASK 0x7FFF0000
++
++#define VIDEO1_BSD_PARA_REG 0x6C + VIDEOBASE_OFFSET //Video BSD Parameters Register
++#define VIDEO2_BSD_PARA_REG 0x16C + VIDEOBASE_OFFSET
++ #define BSD_HIGH_THRES 0x00000001 //Bit[7:0] Block sharpness detection high threshold
++ #define BSD_HIGH_THRES_BIT 0
++ #define BSD_HIGH_THRES_MASK 0x000000FF
++ #define BSD_LOW_THRES 0x00000100 //Bit[15:8] Block shaprpness detection low threshold
++ #define BSD_LOW_THRES_BIT 8
++ #define BSD_LOW_THRES_MASK 0x0000FF00
++ #define BSD_HIGH_COUNTS 0x00010000 //Bit[21:16] Block sharpness detection high counts threshold
++ #define BSD_HIGH_COUNTS_BIT 16
++ #define BSD_HIGH_COUNTS_MASK 0x003F0000
++ #define BSD_LOW_COUNTS 0x00400000 //Bit[27:22] Block sharpness detection low counts threshold
++ #define BSD_LOW_COUNTS_BIT 22
++ #define BSD_LOW_COUNTS_MASK 0x0FC00000
++
++#define VIDEO1_COMPRESS_FRAME_SIZE_REG 0x70 + VIDEOBASE_OFFSET
++#define VIDEO2_COMPRESS_FRAME_SIZE_REG 0x170 + VIDEOBASE_OFFSET
++ #define COMPRESS_FRAME_SIZE_READ 0x00000001 //Bit[19:0] Video compression frame size read back(number of DW)
++ #define COMPRESS_FRAME_SIZE_READ_BIT 0
++ #define COMPRESS_FRAME_SIZE_READ_MASK 0x003FFFFF
++
++#define VIDEO1_COMPRESS_BLOCK_COUNT_REG 0x74 + VIDEOBASE_OFFSET
++#define VIDEO2_COMPRESS_BLOCK_COUNT_REG 0x174 + VIDEOBASE_OFFSET
++ #define PROCESS_BLOCK_COUNT_READ_BIT 0
++ #define PROCESS_BLOCK_COUNT_READ_MASK 0x00003FFF //Bit[13:0] Video processed total block counter read back(number of blocks)
++ #define COMPRESS_BLOCK_COUNT_READ_BIT 16
++ #define COMPRESS_BLOCK_COUNT_READ_MASK 0xFFFF0000 //Bit[29:16] Video processed total block counter read back(number of blocks)
++
++#define VIDEO1_COMPRESS_FRAME_END_READ 0x78 + VIDEOBASE_OFFSET //Video compression stream frame end pointer
++#define VIDEO2_COMPRESS_FRAME_END_READ 0x178 + VIDEOBASE_OFFSET
++ #define COMPRESS_FRAME_END_READ_ALIGN 7
++ #define COMPRESS_FRAME_END_READ_MASK 0x00FFFFFF
++
++#define VIDEO1_COMPRESS_FRAME_COUNT_READ 0x7C + VIDEOBASE_OFFSET
++#define VIDEO2_COMPRESS_FRAME_COUNT_READ 0x17C + VIDEOBASE_OFFSET
++ #define COMPRESS_FRAME_COUNT_READ 0x00000001 //Bit[15:0] Video compression frame count read back(number of frame)
++ #define COMPRESS_FRAME_COUNT_READ_BIT 0
++ #define COMPRESS_FRAME_COUNT_READ_MASK 0xFFFFFFFF
++
++#define VIDEO1_USER_DEFINE_HEADER 0x80 + VIDEOBASE_OFFSET
++#define VIDEO2_USER_DEFINE_HEADER 0x180 + VIDEOBASE_OFFSET
++ #define USER_DEFINE_HEADER 0x00000001 //Bit[15:0] Video user defined header parameter
++ #define USER_DEFINE_HEADER_BIT 0
++ #define USER_DEFINE_HEADER_MASK 0x0000FFFF
++
++#define VIDE1_MODE_DETECTION_EDGE_H_REG 0x90 + VIDEOBASE_OFFSET
++#define VIDE2_MODE_DETECTION_EDGE_H_REG 0x190 + VIDEOBASE_OFFSET
++ #define LEFT_EDGE_LOCATION 0x00000001 //Bit[11:0] Video source left edge location from sync rising edge
++ #define LEFT_EDGE_LOCATION_BIT 0
++ #define LEFT_EDGE_LOCATION_MASK 0x00000FFF
++ #define NO_VER_SYNC (1 << 12) //Bit[12] No Vertical sync detected
++ #define NO_HOR_SYNC (1 << 13) //Bit[13] No horizontal sync detected
++ #define NO_ACTIVE_DISP (1 << 14) //Bit[14] No active display detected
++ #define NO_DISP_CLOCK (1 << 15)
++ #define RIGHT_EDGE_LOCATION 0x00010000 //Bit[27:16] Video source right edge location from sync rising edge
++ #define RIGHT_EDGE_LOCATION_BIT 16
++ #define RIGHT_EDGE_LOCATION_MASK 0x0FFF0000
++
++#define VIDE1_MODE_DETECTION_EDGE_V_REG 0x94 + VIDEOBASE_OFFSET
++#define VIDE2_MODE_DETECTION_EDGE_V_REG 0x194 + VIDEOBASE_OFFSET
++ #define TOP_EDGE_LOCATION 0x00000001 //Bit[11:0] Video source top edge location from sync rising edge
++ #define TOP_EDGE_LOCATION_BIT 0
++ #define TOP_EDGE_LOCATION_MASK 0x00000FFF
++ #define BOTTOM_EDGE_LOCATION 0x00010000 //Bit[27:16] Video source bottom edge location from sync rising edge
++ #define BOTTOM_EDGE_LOCATION_BIT 16
++ #define BOTTOM_EDGE_LOCATION_MASK 0x0FFF0000
++
++#define VIDEO1_MODE_DETECTION_STATUS_READ_REG 0x98 + VIDEOBASE_OFFSET
++#define VIDEO2_MODE_DETECTION_STATUS_READ_REG 0x198 + VIDEOBASE_OFFSET
++ #define MODE_DETECTION_HOR_TIME_READ 0x00000001 //Bit[11:0] Mode detection Horizontal time read back (read only)
++ #define MODE_DETECTION_HOR_TIME_READ_BIT 0
++ #define MODE_DETECTION_HOR_TIME_READ_MASK 0x00000FFF
++ #define ANALONG_DIGITAL_READ 0x00001000 //Bit[12] Auto detection for external analog or digital source read back
++ #define ANALONG_DIGITAL_READ_BIT 12
++ #define DVI_SIGNAL 0
++ #define ADC_SIGNAL 1
++ #define MODE_DETECTION_HOR_STABLE_READ 0x00002000 //Bit[13] Mode detection horizontal stable read back
++ #define HOR_STABLE 1
++ #define MODE_DETECTION_VER_STABLE_READ 0x00004000 //Bit[14] Mode detection vertical stable read back
++ #define VER_STABLE 1
++ #define OUT_LOCK_READ 0x00008000 //Bit[15] Mode detection out of lock read back
++ #define SIGNAL_OUT_LOCK 1
++ #define MODE_DETECTION_VER_LINE_READ 0x00010000 //Bit[27:16] Mode detection Vertical lines read back
++ #define MODE_DETECTION_VER_LINE_READ_BIT 16
++ #define MODE_DETECTION_VER_LINE_READ_MASK 0x0FFF0000
++ #define VSYNC_POLARITY_READ 0x10000000 //Bit[28] Vsync polarity read back
++ #define HSYNC_POLARITY_READ 0x20000000 //Bit[29] Hsync polarity read back
++ #define MODE_DETECTION_VSYNC_READY 0x40000000 //Bit[30] Mode detection Vsync ready
++ #define MODE_DETECTION_HSYNC_READY 0x80000000 //Bit[31] Mode detection Hsync ready
++
++/****** VIDEO MEMAGER SETTING ******/
++#define VIDEOM_ENGINE_SEQUENCE_CONTROL_REG 0x204 + VIDEOBASE_OFFSET
++ #define VIDEOM_CAPTURE_TRIGGER 0x00000002 //Bit[1] trigger HW to capture video
++ #define VIDEOM_AUTO_MODE 0x00000008 //Bit[3]
++ #define DISABLE_AUTO_MODE 0
++ #define AUTO_COMPRESS 1
++ #define VIDEOM_CODEC_TRIGGER 0x00000010 //Bit[4] trigger HW to compress or decompress video
++ #define VIDEOM_SOURCE_SELECTION 0x00000100 //Bit[8]
++ #define VIDEO1 0
++ #define VIDEO2 1
++ //#define STREAM_DATA_MODE 0x00000400 //Bit[11:10] Buffer and Stream Data type
++ // #define STREAM_DATA_MODE_BIT 10
++ // #define STREAM_DATA_MODE_MASK 0x00000C00
++ // #define YUV444_MODE 0
++ // #define YUV420_MODE 1
++ // #define YUV420_MODE_WITH_AST2000 2 //AST2000 compatible
++ #define VIDEOM_CAPTURE_READY 0x00010000 //Bit[16] Video capture ready status read back(read only)
++ //#define HW_BUSY 0
++ //#define HW_IDLE 1
++ #define VIDEOM_CODEC_READY 0x00040000 //Bit[18] Video codec ready status read back(read only)
++ //#define HW_BUSY 0
++ //#define HW_IDLE 1
++
++#define VIDEOM_SCALE_FACTOR_REG 0x214 + VIDEOBASE_OFFSET
++// #define HOR_SCALING_FACTOR 0x00000001 //Bit[15:0] Video Horizontal scaling factor
++// #define HOR_SCALING_FACTOR_BIT 0 //The formula=4096/(Horizontal scaling facotr)
++// #define HOR_SCALING_FACTOR_MASK 0x0000FFFF
++// #define VER_SCALING_FACTOR 0x00000000 //Bit[31:16] Video Vertical scaling factor
++// #define VER_SCALING_FACTOR_BIT 16 //The formula=4096/(Vertical scaling facotr)
++// #define VER_SCALING_FACTOR_MASK 0xFFFF0000
++
++#define VIDEOM_SCALE_FACTOR_PARAMETER0_REG 0x218 + VIDEOBASE_OFFSET //Scaling Parameters F00, F01, F02, F03
++
++#define VIDEOM_SCALE_FACTOR_PARAMETER1_REG 0x21C + VIDEOBASE_OFFSET //Scaling Parameters F10, F11, F12, F13
++
++#define VIDEOM_SCALE_FACTOR_PARAMETER2_REG 0x220 + VIDEOBASE_OFFSET //Scaling Parameters F20, F21, F22, F23
++
++#define VIDEOM_SCALE_FACTOR_PARAMETER3_REG 0x224 + VIDEOBASE_OFFSET //Scaling Parameters F30, F31, F32, F33
++
++#define VIDEOM_BCD_CONTROL_REG 0x22C + VIDEOBASE_OFFSET
++ //#define BCD_ENABLE 0x00000001 //Bit[0] Enable block change detection(BCD)
++ //#define BCD_TOLERANCE 0x00010000 //Bit[23:16]
++ // #define BCD_TOLERANCE_BIT 16 //flag as changed block when the video data difference greater
++ // #define BCD_TOLERANCE_MASK 0x00FF0000
++
++#define VIDEOM_CAPTURE_WINDOWS_REG 0x230 + VIDEOBASE_OFFSET
++ //#define RC4_TABLE_ADDR_ALIGN 7 //8 byte alignment
++ //#define RC4_TABLE_ADDR_MASK 0x0FFFFFFF
++
++#define VIDEOM_COMPRESS_WINDOWS_REG 0x234 + VIDEOBASE_OFFSET
++ //#define COMPRESS_VER_LINE 0x00000001 //Bit[12:0] Video compression vertical line total
++ //#define COMPRESS_VER_LINE_BIT 0
++ //#define COMPRESS_VER_LINE_MASK 0x00001FFF
++ //#define COMPRESS_HOR_PIXEL 0x00010000 //Bit[12:0] Video compression vertical line total
++ //#define COMPRESS_HOR_PIXEL_BIT 16
++ //#define COMPRESS_HOR_PIXEL_MASK 0x1FFF0000
++
++#define VIDEOM_COMPRESS_BUF_PROCESS_OFFSET_REG 0x238
++ //#define COMPRESS_BUF_PROCESS_OFFSET_ALIGN 127 //128 byte alignment
++ //#define COMPRESS_BUF_PROCESS_OFFSET_MASK 0x3FFFFF
++
++
++//For Compression
++#define VIDEOM_COMPRESS_BUF_READ_OFFSET_REG 0x23C + VIDEOBASE_OFFSET //For stream mode
++ //#define COMPRESS_BUF_READ_OFFSET_ALIGN 127 //128 byte alignment
++ //#define COMPRESS_BUF_READ_OFFSET_MASK 0x003FFFFF
++//For Decompression
++#define VIDEOM_DECOMPRESS_BUF_WRITE_OFFSET_REG 0x23C + VIDEOBASE_OFFSET //For stream mode
++ //#define DECOMPRESS_BUF_WRITE_OFFSET_ALIGN 127 //128 byte alignment
++ //#define DECOMPRESS_BUF_WRITE_OFFSET_MASK 0x003FFFFF
++
++#define VIDEOM_BUF_1_ADDR_REG 0x244 + VIDEOBASE_OFFSET //For Source Buffer in frame mode
++ //#define BUF_1_ADDR_ALIGN 255 //256 byte alignment
++ //#define BUF_1_ADDR_MASK 0x0FFFFFFF
++
++#define VIDEOM_BUF_LINE_OFFSET_REG 0x248 + VIDEOBASE_OFFSET //Must set both in Frame/Stream mode
++ //#define BUF_LINE_OFFSET_ALIGN 7 //8 byte alignment
++ //#define BUF_LINE_OFFSET_MASK 0x00003FFF
++
++#define VIDEOM_BUF_2_ADDR_REG 0x24C + VIDEOBASE_OFFSET //For BCD Buffer in frame mode
++ //#define BUF_2_ADDR_ALIGN 255 //256 byte alignment
++ //#define BUF_2_ADDR_MASK 0x0FFFFFFF
++
++#define VIDEOM_FLAG_BUF_ADDR_REG 0x250 + VIDEOBASE_OFFSET //For block change flag buffer
++ //#define FLAG_BUF_ADDR_ALIGN 7 //8 byte alignment
++ //#define FLAG_BUF_ADDR_MASK 0x0FFFFFFF
++
++#define VIDEOM_COMPRESS_BUF_ADDR_REG 0x254 + VIDEOBASE_OFFSET //For stream mode
++ //#define FLAG_BUF_ADDR_ALIGN 7 //8 byte alignment
++ //#define FLAG_BUF_ADDR_MASK 0x0FFFFFFF
++
++#define VIDEOM_BUF_CODEC_OFFSET_READ 0x25C + VIDEOBASE_OFFSET //For stream mode,
++ //#define BUF_CODEC_OFFSET_ALIGN 255 //256 byte alignment
++ //#define BUF_CODEC_OFFSET_MASK 0x003FFFFF
++
++#define VIDEOM_COMPRESS_CONTROL_REG 0x260 + VIDEOBASE_OFFSET
++ //#define JPEG_ONLY_ENCODE 0x00000001 //Bit[0] JPEG only encoding
++ // #define JPEG_MIX_MODE 0 //Enable JPEG/VQ mix mode encoding
++ // #define JPEG_ONLY_MODE 1 //JPEG encoding mode only
++ //#define VQ_4_COLOR_ENCODE 0x00000002 //Bit[1] Enable 4 color VQ encoding
++ // #define VQ_1_2_COLOR_MODE 0 //1 and 2 color mode VQ encoding
++ // #define VQ_4_COLOR_MODE 1 //1, 2 and 4 color VQ encoding
++ //#define QUALITY_CODEC_SETTING 0x00000004 //Bit[2] High and best video quality codec mode setting
++ // #define JPEG_CODEC_MODE 0 //not supported in best video quality mode
++ // #define QUANTI_CODEC_MODE 1
++ //#define JPEG_DUAL_QUALITY_EN 0x00000008 //Bit[3] JPEG dual quality mode
++ // #define EN_JPEG_DUAL_QUALITY 1 //enable(only for normal video quality mode)
++ //#define BEST_QUALITY_EN 0x00000010 //Bit[4] Best quality video mode enable
++ // #define EN_BEST_QUALITY 1 //enable(only for quantization codec mode)
++ //#define RC4_CRYPT_EN 0x00000020 //Bit[5] Enable RC4 encryption/decryption
++ // #define EN_RC4_CRYPT 1 //enable
++ //#define NORMAL_QUANTI_CHROMI_TABLE 0x00000040 //Bit[10:6] Normal video quality mode JPEG DCT chromi quantination table
++ // #define NORMAL_QUANTI_CHROMI_TABLE_BIT 6
++ // #define NORMAL_QUANTI_CHROMI_TABLE_MASK 0x000007C0
++ //#define NORMAL_QUANTI_LUMI_TABLE 0x00000800 //Bit[15:11] Normal video quality mode JPEG DCT lumi quantination table
++ // #define NORMAL_QUANTI_LUMI_TABLE_BIT 11
++ // #define NORMAL_QUANTI_LUMI_TABLE_MASK 0x0000F800
++ //#define HIGH_QUALITY_EN 0x00010000 //Bit[16] High video quality mode enable
++ // #define EN_HIGH_QUALITY 1 //Enable
++ //#define UV_CIR656_FORMAT 0x00080000 //Bit[19] UV fromat
++ // #define USE_UV_CIR656 1 //recommand
++ //#define HUFFMAN_TABLE_SELECT 0x00100000 //Bit[20] JPEG Huffman table combination
++ // #define DUAL_TABLE 0 //Dual Y, UV table
++ // #define SINGLE_TABLE 1 //Single Y table
++ // #define SINGLE_UV_TABLE 0x00200000 //1x: Single UV table
++ //#define HIGH_QUANTI_CHROMI_TABLE 0x00400000 //Bit[26:22] High quality JPEG DCT chromi quantization table
++ // #define HIGH_QUANTI_CHROMI_TABLE_BIT 22
++ // #define HIGH_QUANTI_CHROMI_TABLE_MASK 0x07C00000
++ //#define HIGH_DEQUANTI_VALUE 0x00400000 //Bit[26:22] High quality de-quantization value
++ // #define HIGH_DEQUANTI_VALUE_BIT 22
++ // #define HIGH_DEQUANTI_VALUE_MASK 0x07C00000
++ //#define HIGH_QUANTI_LUMI_TABLE 0x08000000 //Bit[31:27] High quality JPEG DCT lumi quantization table
++ // #define HIGH_QUANTI_LUMI_TABLE_BIT 27
++ // #define HIGH_QUANTI_LUMI_TABLE_MASK 0xF8000000
++ //#define BEST_DEQUANTI_VALUE 0x08000000 //Bit[31:27] Best quality de-quantization value
++ // #define BEST_QUANTI_VALUE_BIT 27
++ // #define BEST_QUANTI_VALUE_MASK 0xF8000000
++
++#define VIDEOM_QUANTI_TABLE_LOW_REG 0x264 + VIDEOBASE_OFFSET //Match with 0x60 Bit[10:6], Bit[15:11]
++// #define QUANTI_CHROMI_TABLE_LOW 0x00000001 //Bit[4:0] Normal video low quality block chromi quantization table
++// #define QUANTI_CHROMI_TABLE_LOW_BIT 0
++// #define QUANTI_CHROMI_TABLE_LOW_MASK 0x0000001F
++// #define QUANTI_LUMI_TABLE_LOW 0x00000020 //Bit[9:5] Normal video low quality block lumi quantization table
++// #define QUANTI_CHROMI_TABLE_LOW_BIT 5
++// #define QUANTI_CHROMI_TABLE_LOW_MASK 0x000003E0
++
++#define VIDEOM_QUANTI_VALUE_REG 0x268 + VIDEOBASE_OFFSET //Match with 0x60 Bit[26:22],Bit[31:27]
++// #define HIGH_QUANTI_VALUE 0x00000001 //Bit[14:0] High quality quantization value. Format is 1.14
++// #define HIGH_QUANTI_VALUE_BIT 0
++// #define HIGH_QUANTI_VALUE_MASK 0x00007FFF
++// #define BEST_QUANTI_VALUE 0x00010000 //Bit[30:16] Best quality quantization value. Format is 1.14
++// #define BEST_QUANTI_VALUE_BIT 16
++// #define BEST_QUANTI_VALUE_MASK 0x7FFF0000
++
++#define VIDEOM_BSD_PARA_REG 0x26C + VIDEOBASE_OFFSET //Video BSD Parameters Register
++// #define BSD_HIGH_THRES 0x00000001 //Bit[7:0] Block sharpness detection high threshold
++// #define BSD_HIGH_THRES_BIT 0
++// #define BSD_HIGH_THRES_MASK 0x000000FF
++// #define BSD_LOW_THRES 0x00000100 //Bit[15:8] Block shaprpness detection low threshold
++// #define BSD_LOW_THRES_BIT 8
++// #define BSD_LOW_THRES_MASK 0x0000FF00
++// #define BSD_HIGH_COUNTS 0x00010000 //Bit[21:16] Block sharpness detection high counts threshold
++// #define BSD_HIGH_COUNTS_BIT 16
++// #define BSD_HIGH_COUNTS_MASK 0x003F0000
++// #define BSD_LOW_COUNTS 0x01000000 //Bit[27:24] Block sharpness detection low counts threshold
++// #define BSD_LOW_COUNTS_BIT 24
++// #define BSD_LOW_COUNTS_MASK 0x3F000000
++
++#define VIDEOM_COMPRESS_FRAME_SIZE_REG 0x270 + VIDEOBASE_OFFSET
++// #define COMPRESS_FRAME_SIZE_READ 0x00000001 //Bit[19:0] Video compression frame size read back(number of DW)
++// #define COMPRESS_FRAME_SIZE_READ_BIT 0
++// #define COMPRESS_FRAME_SIZE_READ_MASK 0x000FFFFF
++
++#define VIDEOM_COMPRESS_BLOCK_COUNT_REG 0x274 + VIDEOBASE_OFFSET
++// #define COMPRESS_BLOCK_COUNT_READ 0x00000001 //Bit[15:0] Video compress block counter read back(number of blocks)
++// #define COMPRESS_BLOCK_COUNT_READ_BIT 0
++// #define COMPRESS_BLOCK_COUNT_READ_MASK 0x0000FFFF
++
++#define VIDEOM_COMPRESS_FRAME_END_READ 0x278 + VIDEOBASE_OFFSET //Video compression stream frame end pointer
++ //#define COMPRESS_FRAME_END_READ_ALIGN 7
++ //#define COMPRESS_FRAME_END_READ_MASK 0x003FFFFF
++
++#define VIDEOM_USER_DEFINE_HEADER_REG 0x280 + VIDEOBASE_OFFSET
++// #define USER_DEFINE_HEADER 0x00000001 //Bit[15:0] Video user defined header parameter
++// #define USER_DEFINE_HEADER_BIT 0
++// #define USER_DEFINE_HEADER_MASK 0x0000FFFF
++
++/****** VR300-VR3FC: General Control registers *****/
++#define VIDEO_CONTROL_REG 0x300 + VIDEOBASE_OFFSET
++ #define CODEC_DECOMPRESS_MODE 0x00000001 //Bit[0] Codec in de-compression mode
++ #define CODEC_DECOMPRESS_MODE_BIT 0
++ #define CODEC_DECOMPRESS_MODE_MASK 0x00000001
++ #define COMPRESS_MODE 0
++ #define DECOMPRESS_MODE 1
++ #define VIDEO_SAFE_MODE 0x00000002 //Bit[1] VIDEO SAFE MODE
++ #define VIDEO_SAFE_MODE_BIT 1
++ #define VIDEO_SAFE_MODE_OFF 0
++ #define VIDEO_SAFE_MODE_ON 1
++ #define DELAY_VSYNC 0x00000004 //Bit[2] Delay Internal VSYNC
++ #define DELAY_VSYNC_BIT 2
++ #define DELAY_VSYNC_MASK (1<<2)
++ #define DELAY_VSYNC_OFF (0<<2)
++ #define DELAY_VSYNC_EN (1<<2)
++ #define VER_DOWNSCALING_LINE_BUFFER_EN 0x00000010 //Bit[5:4] Video vertical downscaling line buffer enable
++ #define VER_LINE_BUFFER_MASK (3<<4)
++ #define LINE_BUFFER_OFF (0<<4)
++ #define LINE_BUFFER_VIDEO1 1
++ #define LINE_BUFFER_VIDEO2 2
++ #define LINE_BUFFER_VIDEOM 3
++ #define RC4_KEY_BUFFER_SELECTION (1UL<<6) //Bit[7:6] RC4 Key Buffer Selection
++ #define RC4_KEY_BUFFER_SELECTION_BIT 6
++ #define RC4_KEY_BUFFER_SELECTION_MASK (3UL<<6)
++ #define RC4_KEY_BUFFER_VIDEO1 0
++ #define RC4_KEY_BUFFER_VIDEO2 1
++ #define RC4_KEY_BUFFER_VIDEOM 2
++ #define RC4_INIT_RESET (1UL<<8) //Bit[8] RC4 initial reset
++ #define RC4_INIT_RESET_BIT 8
++ #define RC4_INIT_RESET_MASK (1UL<<8)
++ #define RC4_NORMAL_MODE 0
++ #define RC4_RESET_COUNTER 1
++ #define RC4_TEST_MODE (1UL<<9) //Bit[9] RC4 test mode
++ #define RC4_TEST_MODE_BIT 9
++ #define RC4_TEST_OFF 0
++ #define RC4_TEST_ON 1
++ #define RC4_SAVE_MODE (1UL<<14) //Bit[14] RC4 save mode
++ #define RC4_SAVE_MODE_BIT 14
++ #define RC4_SAVE_MODE_MASK (1UL<<14)
++ #define RC4_SAVE_MODE_OFF 0
++ #define RC4_SAVE_MODE_ON 1
++ #define RC4_NO_RESET_FRAME (1UL<<15) //Bit[15] RC4 no reset when frame completed
++ #define RC4_NO_RESET_FRAME_BIT 15
++ #define RC4_NO_RESET_FRAME_MASK (1UL<<15)
++ #define RC4_NO_RESET_FRAME_OFF 0 //Always reset
++ #define RC4_NO_RESET_FRAME_ON 1
++
++#define VIDEO_INT_CONTROL_EN_REG 0x304 + VIDEOBASE_OFFSET
++ #define VIDEO1_WATCH_DOG_INT_EN 0x00000001 //Bit[0] Enable Video1 mode detection watch dog out of lock interrupt
++ #define VIDEO1_INPUT_COMPLETE_INT_EN 0x00000002 //Bit[1] Enable Video1 video input complete interrupt (frame complete only for frame mode)
++ #define VIDEO1_PACKET_READY_INT_EN 0x00000004 //Bit[2] Enable Video1 packet ready interrupt
++ #define VIDEO1_COMPRESS_COMPLETE_INT_EN 0x00000008 //Bit[3] Enable Video1 compression complete interrupt
++ #define VIDEO1_MODE_DETECTION_READY_INT_EN 0x00000010 //Bit[4] Enable video1 mode detection ready interrupt
++ #define VIDEO1_FRAME_COMPLETE_INT_EN 0x00000020 //Bit[5] Enable Video1 frame complete interrupt (only for stream mode)
++ #define VIDEO1_STREAM_ERR_INT_EN 0x00000040 //Bit[6] Enable Video1 decode stream error interrupt
++ #define VIDEO2_WATCH_DOG_INT_EN 0x00000100 //Bit[8] Enable Video2 mode detection watch dog out of lock interrupt
++ #define VIDEO2_INPUT_COMPLETE_INT_EN 0x00000200 //Bit[9] Enable Video2 video input complete interrupt (frame complete only for frame mode)
++ #define VIDEO2_PACKET_READY_INT_EN 0x00000400 //Bit[10] Enable Video2 packet ready interrupt
++ #define VIDEO2_COMPRESS_COMPLETE_INT_EN 0x00000800 //Bit[11] Enable Video2 compression complete interrupt
++ #define VIDEO2_MODE_DETECTION_READY_INT_EN 0x00001000 //Bit[12] Enable video2 mode detection ready interrupt
++ #define VIDEO2_FRAME_COMPLETE_INT_EN 0x00002000 //Bit[13] Enable Video2 frame complete interrupt (only for stream mode)
++ #define VIDEO2_STREAM_ERR_INT_EN 0x00004000 //Bit[14] Enable Video2 decode stream error interrupt
++ #define VIDEOM_INPUT_COMPLETE_INT_EN 0x00010000 //Bit[16] Enable VideoM video input complete interrupt
++ #define VIDEOM_COMPRESS_COMPLETE_INT_EN 0x00020000 //Bit[17] Enable VideoM compression complete interrupt
++ #define VIDEOM_PACKET_READY_INT_EN 0x00040000 //Bit[18] Enable VideoM packet ready interrupt
++ #define VIDEOM_FRAME_COMPLETE_INT_EN 0x00080000 //Bit[19] Enable VideoM frame complete interrupt (only for stream mode)
++
++#define VIDEO_INT_CONTROL_READ_REG 0x308 + VIDEOBASE_OFFSET //Clear when write 1
++ #define VIDEO1_WATCH_DOG_READ 0x00000001 //Bit[0] Video1 mode detection watch dog out of lock interrupt status read back
++ #define VIDEO1_WATCH_DOG_BIT 0
++ #define VIDEO1_WATCH_DOG_MASK 0x00000001
++ #define VIDEO1_INPUT_COMPLETE_READ 0x00000002 //Bit[1] Video1 video input complete interrupt status read back (frame complete only for frame mode)
++ #define VIDEO1_INPUT_COMPLETE_BIT 1
++ #define VIDEO1_INPUT_COMPLETE_MASK 0x00000002
++ #define VIDEO1_PACKET_READY_READ 0x00000004 //Bit[2] Video1 packet ready interrupt status read back
++ #define VIDEO1_PACKET_READY_BIT 2
++ #define VIDEO1_PACKET_READY_MASK 0x00000004
++ #define VIDEO1_COMPRESS_COMPLETE_READ 0x00000008 //Bit[3] Video1 compression complete interrupt status read back
++ #define VIDEO1_COMPRESS_COMPLETE_BIT 3
++ #define VIDEO1_COMPRESS_COMPLETE_MASK 0x00000008
++ #define VIDEO1_MODE_DETECTION_READY_READ 0x00000010 //Bit[4] Video1 mode detection ready interrupt status read back
++ #define VIDEO1_MODE_DETECTION_READY_BIT 4
++ #define VIDEO1_FRAME_COMPLETE_READ 0x00000020 //Bit[5] Video1 frame complete interrupt status read back
++ #define VIDEO1_FRAME_COMPLETE_BIT 5
++ #define VIDEO1_FRAME_COMPLETE_MASK 0x00000020
++ #define VIDEO1_STREAM_ERR_READ 0x00000040 //Bit[6] Video1 decode stream error interrupt status read back
++ #define VIDEO1_STREAM_ERR_BIT 6
++ #define VIDEO1_STREAM_ERR_MASK 0x00000040
++ #define VIDEO2_WATCH_DOG_READ 0x00000100 //Bit[8] Video2 mode detection watch dog out of lock interrupt status read back
++ #define VIDEO2_WATCH_DOG_BIT 8
++ #define VIDEO2_WATCH_DOG_MASK 0x00000100
++ #define VIDEO2_INPUT_COMPLETE_READ 0x00000200 //Bit[9] Video2 video input complete interrupt status read back (frame complete only for frame mode)
++ #define VIDEO2_INPUT_COMPLETE_BIT 9
++ #define VIDEO2_INPUT_COMPLETE_MASK 0x00000200
++ #define VIDEO2_PACKET_READY_READ 0x00000400 //Bit[10] Video2 packet ready interrupt status read back
++ #define VIDEO2_PACKET_READY_BIT 10
++ #define VIDEO2_PACKET_READY_MASK 0x00000400
++ #define VIDEO2_COMPRESS_COMPLETE_READ 0x00000800 //Bit[11] Video2 compression complete interrupt status read back
++ #define VIDEO2_COMPRESS_COMPLETE_BIT 11
++ #define VIDEO2_COMPRESS_COMPLETE_MASK 0x00000800
++ #define VIDEO2_MODE_DETECTION_READY_READ 0x00001000 //Bit[12] Video2 mode detection ready interrupt status read back
++ #define VIDEO2_MODE_DETECTION_READY_BIT 12
++ #define VIDEO2_FRAME_COMPLETE_READ 0x00002000 //Bit[13] Video2 frame complete interrupt status read back
++ #define VIDEO2_FRAME_COMPLETE_BIT 13
++ #define VIDEO2_FRAME_COMPLETE_MASK 0x00002000
++ #define VIDEO2_STREAM_ERR_READ 0x00004000 //Bit[14] Video2 decode stream error interrupt status read back
++ #define VIDEO2_STREAM_ERR_BIT 14
++ #define VIDEO2_STREAM_ERR_MASK 0x00004000
++ //need check spec
++ #define VIDEOM_INPUT_COMPLETE_READ 0x00010000 //Bit[16] VideoM video input complete interrupt status read back
++ #define VIDEOM_INPUT_COMPLETE_BIT 16
++ #define VIDEOM_INPUT_COMPLETE_MASK 0x00010000
++ #define VIDEOM_COMPRESS_COMPLETE_READ 0x00020000 //Bit[17] VideoM compression complete interrupt status read back
++ #define VIDEOM_COMPRESS_COMPLETE_BIT 17
++ #define VIDEOM_COMPRESS_COMPLETE_MASK 0x00020000
++ #define VIDEOM_PACKET_READY_READ 0x00040000 //Bit[18] Clear Packet ready interrupt when write 1
++ #define VIDEOM_PACKET_READY_BIT 18
++ #define VIDEOM_PACKET_READY_MASK 0x00040000
++ #define VIDEOM_FRAME_COMPLETE_READ 0x00080000 //Bit[19] Clear Frame complete interrupt when write 1
++ #define VIDEOM_FRAME_COMPLETE_BIT 19
++ #define VIDEOM_FRAME_COMPLETE_MASK 0x00080000
++
++#define VIDEO_INT_CONTROL_CLEAR_REG 0x308 + VIDEOBASE_OFFSET //Clear when write 1
++ //Clear when write 1
++ #define VIDEO1_WATCH_DOG_CLEAR 0x00000001 //Bit[0] Clear mode detection watch dog out of lock interrupt when write 1
++ #define VIDEO1_INPUT_COMPLETE_CLEAR 0x00000002 //Bit[1] Clear video input complete interrupt when write 1 (frame complete only for frame mode)
++ #define VIDEO1_PACKET_READY_CLEAR 0x00000004 //Bit[2] Clear Packet ready interrupt when write 1
++ #define VIDEO1_PACKET_READY_CLEAR_BIT 2
++ #define VIDEO1_PACKET_READY_CLEAR_MASK 0x00000004
++ #define VIDEO1_COMPRESS_COMPLETE_CLEAR 0x00000008 //Bit[3] Clear video compression interrupt when write 1
++ #define VIDEO1_MODE_DETECTION_READY_CLEAR 0x00000010 //Bit[4] Clear Video1 Mode detection ready interrupt when write 1
++ #define VIDEO1_FRAME_COMPLETE_CLEAR 0x00000020 //Bit[5] Clear Frame complete interrupt when write 1
++ #define VIDEO1_FRAME_COMPLETE_CLEAR_BIT 5
++ #define VIDEO1_FRAME_COMPLETE_CLEAR_MASK 0x00000020
++ #define VIDEO1_STREAM_ERR_CLEAR 0x00000040 //Bit[6] Clear decode stream error interrupt when write 1
++ #define VIDEO2_WATCH_DOG_CLEAR 0x00000100 //Bit[8] Clear Mode detection interrupt when write 1
++ #define VIDEO2_INPUT_COMPLETE_CLEAR 0x00000200 //Bit[9] Clear video input complete interrupt when write 1
++ #define VIDEO2_PACKET_READY_CLEAR 0x00000400 //Bit[10] Clear packet ready interrupt when write 1
++ #define VIDEO2_COMPRESS_COMPLETE_CLEAR 0x00000800 //Bit[11] Clear video compression complete interrupt when write 1
++ #define VIDEO2_MODE_DETECTION_READY_CLEAR 0x00001000 //Bit[12] Clear Video2 Mode detection ready interrupt when write 1
++ #define VIDEO2_FRAME_COMPLETE_CLEAR 0x00002000 //Bit[13] Clear Frame complete interrupt when write 1 (frame complete only for frame mode)
++ #define VIDEO2_STREAM_ERR_CLEAR 0x00004000 //Bit[14] Clear Decode stream error interrupt when write 1
++ //need check spec
++ #define VIDEOM_INPUT_COMPLETE_CLEAR 0x00010000 //Bit[16] Clear video input complete interrupt when write 1
++ #define VIDEOM_COMPRESS_COMPLETE_CLEAR 0x00020000 //Bit[17] Clear compression complete interrupt when write 1
++ #define VIDEOM_COMPRESS_COMPLETE_CLEAR_BIT 17
++ #define VIDEOM_COMPRESS_COMPLETE_CLEAR_MASK 0x00020000
++ #define VIDEOM_PACKET_READY_CLEAR 0x00040000 //Bit[18] Clear compression complete interrupt when write 1
++ #define VIDEOM_PACKET_READY_CLEAR_BIT 18
++ #define VIDEOM_PACKET_READY_CLEAR_MASK 0x00040000
++ #define VIDEOM_FRAME_COMPLETE_CLEAR 0x00100000 //Bit[20] Clear Frame complete interrupt when write 1
++ #define VIDEOM_FRAME_COMPLETE_CLEAR_BIT 20
++ #define VIDEOM_FRAME_COMPLETE_CLEAR_MASK 0x00100000
++ #define VIDEOM_STREAM_ERR_CLEAR 0x00200000 //Bit[21] Clear decode stream error interrupt when write 1
++
++#define VIDEO_MODE_DETECTION_PARAM_REG 0x30C + VIDEOBASE_OFFSET
++ #define EDGE_PIXEL_THRES_BIT 8 //Bit[15:8] Mode detection edge pixel threshold
++ #define EDGE_PIXEL_THRES_MASK 0x0000FF00
++ #define VER_STABLE_MAX_BIT 16 //Bit[19:16] Mode detection vertical stable maximum
++ #define VER_STABLE_MAX_BIT_MASK 0x000F0000
++ #define HOR_STABLE_MAX_BIT 20 //Bit[23:20] Mode detection horizontal stable maximum
++ #define HOR_STABLE_MAX_BIT_MASK 0x00F00000
++ #define VER_STABLE_THRES_BIT 24 //Bit[27:24] Mode detection vertical stable threshold
++ #define VER_STABLE_THRES_BIT_MASK 0x0F000000
++ #define HOR_STABLE_THRES_BIT 28 //Bit[31:28] Mode detection horizontal stable threshold
++ #define HOR_STABLE_THRES_BIT_MASK 0xF0000000
++
++#define VIDEO_CRC_PRIMARY_REG 0x320 + VIDEOBASE_OFFSET
++ #define CRC_CHECK_EN 0x00000001 //Bit[0] Video port 1/2 Enable video capture write CRC check
++ #define CRC_CHECK_EN_BIT 0
++ #define CRC_CHECK_HIGH 0x00000002 //Bit[1] Video port 1/2 CRC check high bit only
++ #define CRC_CHECK_HIGH_BIT 1
++ #define SKIP_COUNT_MAX 0x00000004 //Bit[7:2] Video port 1/2 Max capture write skip count
++ #define SKIP_COUNT_MAX_BIT 2
++ #define SKIP_COUNT_MAX_MASK 0x000000FC
++ #define CRC_PRIMARY_POLY_LOW 0x00000100 //Bit[15:8] Primary CRC low 8-bit polynomial
++ #define CRC_RIMARY_POLY_LOW_BIT 8
++ #define CRC_RIMARY_POLY_LOW_MASK 0x0000FF00
++ #define CRC_PRIMARY_POLY_HIGH 0x00010000 //Bit[31:16] Primary CRC high 8-bit polynomial
++ #define CRC_RIMARY_POLY_HIGH_BIT 16
++ #define CRC_RIMARY_POLY_HIGH_MASK 0xFFFF0000
++
++
++#define VIDEO_CRC_SECOND_REG 0x324 + VIDEOBASE_OFFSET
++ #define CRC_SECOND_POLY_LOW 0x00000100 //Bit[15:8] Secondary CRC low 8-bit polynomial
++ #define CRC_SECOND_POLY_LOW_BIT 8
++ #define CRC_SECOND_POLY_LOW_MASK 0x0000FF00
++ #define CRC_SECOND_POLY_HIGH 0x00010000 //Bit[31:16] Secondary CRC high 8-bit polynomial
++ #define CRC_SECOND_POLY_HIGH_BIT 16
++ #define CRC_SECOND_POLY_HIGH_MASK 0xFFFF0000
++
++#define VIDEO1_RC4_KEYS_REG 0x400 + VIDEOBASE_OFFSET //Total Video1 RC4 Keys
++#define VIDEO2_RC4_KEYS_REG 0x500 + VIDEOBASE_OFFSET //Total Video2 RC4 Keys
++#define VIDEOM_RC4_KEYS_REG 0x600 + VIDEOBASE_OFFSET //Total VideoM RC4 Keys
++
++#endif /* end of _VREG_H_ */
++
+diff --git a/boards.cfg b/boards.cfg
+index 6a368de..674896b 100644
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -72,6 +72,7 @@ mini2440 arm arm920t mini2440 friendl
+ VCMA9 arm arm920t vcma9 mpl s3c24x0
+ smdk2410 arm arm920t - samsung s3c24x0
+ omap1510inn arm arm925t - ti
++ast2400 arm arm926ejs ast2400 aspeed aspeed
+ integratorap_cm926ejs arm arm926ejs integrator armltd - integratorap:CM926EJ_S
+ integratorcp_cm926ejs arm arm926ejs integrator armltd - integratorcp:CM924EJ_S
+ aspenite arm arm926ejs - Marvell armada100
+diff --git a/common/Makefile b/common/Makefile
+index 53c92ef..6ba5f38 100644
+--- a/common/Makefile
++++ b/common/Makefile
+@@ -190,6 +190,8 @@ COBJS-$(CONFIG_CMD_ZIP) += cmd_zip.o
+ COBJS-$(CONFIG_CMD_ZFS) += cmd_zfs.o
+
+ # others
++OBJS-$(CONFIG_CMD_NETTEST) += cmd_nettest.o
++COBJS-$(CONFIG_CMD_SLT) += cmd_slt.o
+ COBJS-$(CONFIG_BOOTSTAGE) += bootstage.o
+ COBJS-$(CONFIG_CONSOLE_MUX) += iomux.o
+ COBJS-y += flash.o
+diff --git a/common/cmd_nettest.c b/common/cmd_nettest.c
+new file mode 100644
+index 0000000..249d7b6
+--- /dev/null
++++ b/common/cmd_nettest.c
+@@ -0,0 +1,214 @@
++/*
++ * 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 <common.h>
++#include <command.h>
++#include <COMMINF.H>
++
++#ifdef SLT_UBOOT
++extern int main_function(int argc, char *argv[]);
++
++int do_mactest (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
++{
++ ModeSwitch = MODE_DEDICATED;
++ return main_function( argc, argv);
++}
++
++int do_ncsitest (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
++{
++ ModeSwitch = MODE_NSCI;
++ return main_function( argc, argv);
++}
++
++U_BOOT_CMD(
++ mactest, CONFIG_SYS_MAXARGS, 0, do_mactest,
++ "mactest - Dedicated LAN test program \n",
++ NULL
++);
++U_BOOT_CMD(
++ ncsitest, CONFIG_SYS_MAXARGS, 0, do_ncsitest,
++ "ncsitest- Share LAN (NC-SI) test program \n",
++ NULL
++);
++
++// ------------------------------------------------------------------------------
++int do_phyread (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
++{
++ int MACnum;
++ int PHYreg;
++ ULONG result_data;
++ int ret = 0;
++ int PHYaddr;
++ int timeout = 0;
++
++ do {
++ if ( argc != 4 ) {
++ printf(" Wrong parameter number.\n" );
++ printf(" phyr mac addr reg\n" );
++ printf(" mac : 0 or 1. [hex]\n" );
++ printf(" PHY addr: 0 to 31. [hex]\n" );
++ printf(" register: 0 to 0xFF.[hex]\n" );
++ printf(" example: phyr 0 0 1\n" );
++ ret = -1;
++ break;
++ }
++
++ MACnum = strtoul(argv[1], NULL, 16);
++ PHYaddr = strtoul(argv[2], NULL, 16);
++ PHYreg = strtoul(argv[3], NULL, 16);
++
++ if ( MACnum == 0 ) {
++ // Set MAC 0
++ H_MAC_BASE = MAC_BASE1;
++ }
++ else if ( MACnum == 1 ) {
++ // Set MAC 1
++ H_MAC_BASE = MAC_BASE2;
++ }
++ else {
++ printf("wrong parameter (mac number)\n");
++ ret = -1;
++ break;
++ }
++ MAC_PHYBASE = H_MAC_BASE;
++
++ if ( ( PHYaddr < 0 ) || ( PHYaddr > 31 ) ) {
++ printf("wrong parameter (PHY address)\n");
++ ret = -1;
++ break;
++ }
++
++ MAC_40h_old = ReadSOC_DD( H_MAC_BASE + 0x40 );
++ AST2300_NewMDIO = (MAC_40h_old & 0x80000000) ? 1 : 0;
++
++ if ( AST2300_NewMDIO ) {
++ WriteSOC_DD( MAC_PHYBASE + 0x60, MAC_PHYRd_New | (PHYaddr << 5) | ( PHYreg & 0x1f ) );
++ while ( ReadSOC_DD( MAC_PHYBASE + 0x60 ) & MAC_PHYBusy_New ) {
++ if ( ++timeout > TIME_OUT_PHY_RW ) {
++ ret = -1;
++ break;
++ }
++ }
++ DELAY(Delay_PHYRd);
++ result_data = ReadSOC_DD( MAC_PHYBASE + 0x64 ) & 0xffff;
++ }
++ else {
++ WriteSOC_DD( MAC_PHYBASE + 0x60, MDC_Thres | MAC_PHYRd | (PHYaddr << 16) | ((PHYreg & 0x1f) << 21) );
++ while ( ReadSOC_DD( MAC_PHYBASE + 0x60 ) & MAC_PHYRd ) {
++ if ( ++timeout > TIME_OUT_PHY_RW ) {
++ ret = -1;
++ break;
++ }
++ }
++ DELAY( Delay_PHYRd );
++ result_data = ReadSOC_DD( MAC_PHYBASE + 0x64 ) >> 16;
++ }
++ printf(" PHY[%d] reg[%2X] = %08lX\n", PHYaddr, PHYreg, result_data );
++ } while ( 0 );
++
++ return ret;
++}
++
++
++int do_phywrite (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
++{
++ int MACnum;
++ int PHYreg;
++ int PHYaddr;
++ ULONG reg_data;
++ int ret = 0;
++ int timeout = 0;
++
++ do {
++ if ( argc != 5 )
++ {
++ printf(" Wrong parameter number.\n" );
++ printf(" phyw mac addr reg data\n" );
++ printf(" mac : 0 or 1. [hex]\n" );
++ printf(" PHY addr: 0 to 31. [hex]\n" );
++ printf(" register: 0 to 0xFF. [hex]\n" );
++ printf(" data : 0 to 0xFFFF.[hex]\n" );
++ printf(" example: phyw 0 0 0 610\n" );
++ ret = -1;
++ break;
++ }
++
++ MACnum = strtoul(argv[1], NULL, 16);
++ PHYaddr = strtoul(argv[2], NULL, 16);
++ PHYreg = strtoul(argv[3], NULL, 16);
++ reg_data = strtoul(argv[4], NULL, 16);
++
++ if ( MACnum == 0 ) {
++ // Set MAC 0
++ H_MAC_BASE = MAC_BASE1;
++ }
++ else if ( MACnum == 1 ) {
++ // Set MAC 1
++ H_MAC_BASE = MAC_BASE2;
++ }
++ else {
++ printf("wrong parameter (mac number)\n");
++ ret = -1;
++ break;
++ }
++ MAC_PHYBASE = H_MAC_BASE;
++
++ if ( ( PHYaddr < 0 ) || ( PHYaddr > 31 ) ) {
++ printf("wrong parameter (PHY address)\n");
++ ret = -1;
++ break;
++ }
++
++ MAC_40h_old = ReadSOC_DD( H_MAC_BASE + 0x40 );
++ AST2300_NewMDIO = (MAC_40h_old & 0x80000000) ? 1 : 0;
++
++ if (AST2300_NewMDIO) {
++ WriteSOC_DD( MAC_PHYBASE + 0x60, ( reg_data << 16 ) | MAC_PHYWr_New | (PHYaddr<<5) | (PHYreg & 0x1f));
++
++ while ( ReadSOC_DD( MAC_PHYBASE + 0x60 ) & MAC_PHYBusy_New ) {
++ if ( ++timeout > TIME_OUT_PHY_RW ) {
++ ret = -1;
++ break;
++ }
++ }
++ }
++ else {
++ WriteSOC_DD( MAC_PHYBASE + 0x64, reg_data );
++ WriteSOC_DD( MAC_PHYBASE + 0x60, MDC_Thres | MAC_PHYWr | (PHYaddr<<16) | ((PHYreg & 0x1f) << 21));
++
++ while ( ReadSOC_DD( MAC_PHYBASE + 0x60 ) & MAC_PHYWr ) {
++ if ( ++timeout > TIME_OUT_PHY_RW ) {
++ ret = -1;
++ break;
++ }
++ }
++ } // End if (AST2300_NewMDIO)
++
++ printf("Write: PHY[%d] reg[%2X] = %08lX\n", PHYaddr, PHYreg, reg_data );
++ } while ( 0 );
++
++ return ret;
++}
++
++U_BOOT_CMD(
++ phyr, CONFIG_SYS_MAXARGS, 0, do_phyread,
++ "phyr - Read PHY register. (phyr mac addr reg)\n",
++ NULL
++);
++
++U_BOOT_CMD(
++ phyw, CONFIG_SYS_MAXARGS, 0, do_phywrite,
++ "phyw - Write PHY register. (phyw mac addr reg data)\n",
++ NULL
++);
++
++#endif // End SLT_UBOOT
++
+diff --git a/common/cmd_slt.c b/common/cmd_slt.c
+new file mode 100644
+index 0000000..9763692
+--- /dev/null
++++ b/common/cmd_slt.c
+@@ -0,0 +1,49 @@
++/*
++ * 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 <command.h>
++
++extern int pll_function(int argc, char *argv[]);
++extern int trap_function(int argc, char *argv[]);
++extern int dram_stress_function(int argc, char *argv[]);
++
++int do_plltest (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
++{
++ return pll_function( argc, argv);
++}
++
++U_BOOT_CMD(
++ plltest, CONFIG_SYS_MAXARGS, 0, do_plltest,
++ "plltest - PLLTest [pll mode] [err rate] \n",
++ NULL
++);
++
++int do_traptest (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
++{
++ return trap_function( argc, argv);
++}
++
++U_BOOT_CMD(
++ traptest, CONFIG_SYS_MAXARGS, 0, do_traptest,
++ "traptest- Check hardware trap for CPU clock and CPU\\AHB ratio.\n",
++ NULL
++);
++
++int do_dramtest (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
++{
++ return dram_stress_function( argc, argv);
++}
++
++U_BOOT_CMD(
++ dramtest, CONFIG_SYS_MAXARGS, 0, do_dramtest,
++ "dramtest- Stress DRAM.\n",
++ NULL
++);
+diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
+index 72e85a3..2b35587 100644
+--- a/drivers/i2c/Makefile
++++ b/drivers/i2c/Makefile
+@@ -43,6 +43,7 @@ COBJS-$(CONFIG_S3C44B0_I2C) += s3c44b0_i2c.o
+ COBJS-$(CONFIG_SOFT_I2C) += soft_i2c.o
+ COBJS-$(CONFIG_TEGRA_I2C) += tegra_i2c.o
+ COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
++COBJS-$(CONFIG_DRIVER_ASPEED_I2C) += aspeed_i2c.o
+ COBJS-$(CONFIG_U8500_I2C) += u8500_i2c.o
+ COBJS-$(CONFIG_SH_I2C) += sh_i2c.o
+ COBJS-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o
+diff --git a/drivers/i2c/aspeed_i2c.c b/drivers/i2c/aspeed_i2c.c
+new file mode 100755
+index 0000000..ff6c756
+--- /dev/null
++++ b/drivers/i2c/aspeed_i2c.c
+@@ -0,0 +1,286 @@
++/*
++ * 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 <common.h>
++#include <asm/arch/aspeed_i2c.h>
++
++#ifdef CONFIG_DRIVER_ASPEED_I2C
++
++void i2c_init (int speed, int slaveadd)
++{
++ unsigned long SCURegister;
++//I2C Reset
++ SCURegister = inl (SCU_BASE + SCU_RESET_CONTROL);
++ outl (SCURegister & ~(0x04), SCU_BASE + SCU_RESET_CONTROL);
++//I2C Multi-Pin
++ SCURegister = inl (SCU_BASE + SCU_MULTIFUNCTION_PIN_CTL5_REG);
++ outl ((SCURegister | 0x30000), SCU_BASE + SCU_MULTIFUNCTION_PIN_CTL5_REG);
++//Reset
++ outl (0, I2C_FUNCTION_CONTROL_REGISTER);
++//Set AC Timing, we use fix AC timing for eeprom in u-boot
++ outl (AC_TIMING, I2C_AC_TIMING_REGISTER_1);
++ outl (0, I2C_AC_TIMING_REGISTER_2);
++//Clear Interrupt
++ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
++//Enable Master Mode
++ outl (MASTER_ENABLE, I2C_FUNCTION_CONTROL_REGISTER);
++//Enable Interrupt, STOP Interrupt has bug in AST2000
++ outl (0xAF, I2C_INTERRUPT_CONTROL_REGISTER);
++//Set Slave address, should not use for eeprom
++ outl (slaveadd, I2C_DEVICE_ADDRESS_REGISTER);
++}
++
++static int i2c_read_byte (u8 devaddr, u16 regoffset, u8 * value, int alen)
++{
++ int i2c_error = 0;
++ u32 status, count = 0;
++
++//Start and Send Device Address
++ outl (devaddr, I2C_BYTE_BUFFER_REGISTER);
++ outl (MASTER_START_COMMAND | MASTER_TX_COMMAND, I2C_COMMAND_REGISTER);
++//Wait Tx ACK
++ do {
++ status = (inl (I2C_INTERRUPT_STATUS_REGISTER) & (TX_ACK | TX_NACK));
++ count++;
++ if (count == LOOP_COUNT) {
++ i2c_error = 1;
++ printf ("Start and Send Device Address can't get ACK back\n");
++ return i2c_error;
++ }
++ } while (status != TX_ACK);
++ count = 0;
++//Clear Interrupt
++ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
++//Check if address length equals to 16bits
++ if (alen != 1) {
++//Send Device Register Offset (HIGH BYTE)
++ outl ((regoffset & 0xFF00) >> 8, I2C_BYTE_BUFFER_REGISTER);
++ outl (MASTER_TX_COMMAND, I2C_COMMAND_REGISTER);
++//Wait Tx ACK
++ do {
++ status = (inl (I2C_INTERRUPT_STATUS_REGISTER) & (TX_ACK | TX_NACK));
++ count++;
++ if (count == LOOP_COUNT) {
++ i2c_error = 1;
++ printf ("Send Device Register Offset can't get ACK back\n");
++ return i2c_error;
++ }
++ } while (status != TX_ACK);
++ count = 0;
++//Clear Interrupt
++ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
++ }
++//Send Device Register Offset(LOW)
++ outl (regoffset & 0xFF, I2C_BYTE_BUFFER_REGISTER);
++ outl (MASTER_TX_COMMAND, I2C_COMMAND_REGISTER);
++//Wait Tx ACK
++ do {
++ status = (inl (I2C_INTERRUPT_STATUS_REGISTER) & (TX_ACK | TX_NACK));
++ count++;
++ if (count == LOOP_COUNT) {
++ i2c_error = 1;
++ printf ("Send Device Register Offset can't get ACK back\n");
++ return i2c_error;
++ }
++ } while (status != TX_ACK);
++ count = 0;
++//Clear Interrupt
++ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
++//Start, Send Device Address + 1 (Read Mode), Receive Data
++ outl (devaddr + 1, I2C_BYTE_BUFFER_REGISTER);
++ outl (MASTER_START_COMMAND | MASTER_TX_COMMAND | MASTER_RX_COMMAND | RX_COMMAND_LIST, I2C_COMMAND_REGISTER);
++//Wait Rx Done
++ do {
++ status = (inl (I2C_INTERRUPT_STATUS_REGISTER) & RX_DONE);
++ count++;
++ if (count == LOOP_COUNT) {
++ i2c_error = 1;
++ printf ("Can't get RX_DONE back\n");
++ return i2c_error;
++ }
++ } while (status != RX_DONE);
++ count = 0;
++//Clear Interrupt
++ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
++//Enable Interrupt + Stop Interrupt
++ outl (0xBF, I2C_INTERRUPT_CONTROL_REGISTER);
++//Issue Stop Command
++ outl (MASTER_STOP_COMMAND, I2C_COMMAND_REGISTER);
++//Wait Stop
++ do {
++ status = (inl (I2C_INTERRUPT_STATUS_REGISTER) & STOP_DONE);
++ count++;
++ if (count == LOOP_COUNT) {
++ i2c_error = 1;
++ printf ("Can't get STOP back\n");
++ return i2c_error;
++ }
++ } while (status != STOP_DONE);
++//Disable Stop Interrupt
++ outl (0xAF, I2C_INTERRUPT_CONTROL_REGISTER);
++//Clear Interrupt
++ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
++//Read Received Data
++ *value = ((inl (I2C_BYTE_BUFFER_REGISTER) & 0xFF00) >> 8);
++
++ return i2c_error;
++}
++
++static int i2c_write_byte (u8 devaddr, u16 regoffset, u8 value, int alen)
++{
++ int i2c_error = 0;
++ u32 status, count = 0;
++
++//Start and Send Device Address
++ outl (devaddr, I2C_BYTE_BUFFER_REGISTER);
++ outl (MASTER_START_COMMAND | MASTER_TX_COMMAND, I2C_COMMAND_REGISTER);
++//Wait Tx ACK
++ do {
++ status = (inl (I2C_INTERRUPT_STATUS_REGISTER) & (TX_ACK | TX_NACK));
++ count++;
++ if (status == TX_NACK) {
++//Clear Interrupt
++ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
++//Re-send Start and Send Device Address while NACK return
++ outl (devaddr, I2C_BYTE_BUFFER_REGISTER);
++ outl (MASTER_START_COMMAND | MASTER_TX_COMMAND, I2C_COMMAND_REGISTER);
++ }
++ else {
++ if (count == LOOP_COUNT) {
++ i2c_error = 1;
++ printf ("Start and Send Device Address can't get ACK back\n");
++ return i2c_error;
++ }
++ }
++ } while (status != TX_ACK);
++ count = 0;
++//Clear Interrupt
++ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
++//Check if address length equals to 16bits
++ if (alen != 1) {
++//Send Device Register Offset (HIGH BYTE)
++ outl ((regoffset & 0xFF00) >> 8, I2C_BYTE_BUFFER_REGISTER);
++ outl (MASTER_TX_COMMAND, I2C_COMMAND_REGISTER);
++//Wait Tx ACK
++ do {
++ status = (inl (I2C_INTERRUPT_STATUS_REGISTER) & (TX_ACK | TX_NACK));
++ count++;
++ if (count == LOOP_COUNT) {
++ i2c_error = 1;
++ printf ("Send Device Register Offset can't get ACK back\n");
++ return i2c_error;
++ }
++ } while (status != TX_ACK);
++ count = 0;
++//Clear Interrupt
++ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
++ }
++//Send Device Register Offset
++ outl (regoffset & 0xFF, I2C_BYTE_BUFFER_REGISTER);
++ outl (MASTER_TX_COMMAND, I2C_COMMAND_REGISTER);
++//Wait Tx ACK
++ do {
++ status = (inl (I2C_INTERRUPT_STATUS_REGISTER) & (TX_ACK | TX_NACK));
++ count++;
++ if (count == LOOP_COUNT) {
++ i2c_error = 1;
++ printf ("Send Device Register Offset can't get ACK back\n");
++ return i2c_error;
++ }
++ } while (status != TX_ACK);
++ count = 0;
++//Clear Interrupt
++ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
++//Send Device Register Value
++ outl (value, I2C_BYTE_BUFFER_REGISTER);
++ outl (MASTER_TX_COMMAND, I2C_COMMAND_REGISTER);
++//Wait Tx ACK
++ do {
++ status = (inl (I2C_INTERRUPT_STATUS_REGISTER) & (TX_ACK | TX_NACK));
++ count++;
++ if (count == LOOP_COUNT) {
++ i2c_error = 1;
++ printf ("Send Device Register Value can't get ACK back\n");
++ return i2c_error;
++ }
++ } while (status != TX_ACK);
++ count = 0;
++//Clear Interrupt
++ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
++//Enable Interrupt + Stop Interrupt
++ outl (0xBF, I2C_INTERRUPT_CONTROL_REGISTER);
++//Issue Stop Command
++ outl (MASTER_STOP_COMMAND, I2C_COMMAND_REGISTER);
++//Wait Stop
++ do {
++ status = (inl (I2C_INTERRUPT_STATUS_REGISTER) & STOP_DONE);
++ count++;
++ if (count == LOOP_COUNT) {
++ i2c_error = 1;
++ printf ("Can't get STOP back\n");
++ return i2c_error;
++ }
++ } while (status != STOP_DONE);
++//Disable Stop Interrupt
++ outl (0xAF, I2C_INTERRUPT_CONTROL_REGISTER);
++//Clear Interrupt
++ outl (ALL_CLEAR, I2C_INTERRUPT_STATUS_REGISTER);
++
++ return i2c_error;
++}
++
++int i2c_probe (uchar chip)
++{
++//Suppose IP is always on chip
++ int res = 0;
++
++ return res;
++}
++
++int i2c_read (uchar device_addr, uint register_offset, int alen, uchar * buffer, int len)
++{
++ int i;
++
++ if ((alen == 1) && ((register_offset + len) > 256)) {
++ printf ("Register index overflow\n");
++ }
++
++ for (i = 0; i < len; i++) {
++ if (i2c_read_byte (device_addr, register_offset + i, &buffer[i], alen)) {
++ printf ("I2C read: I/O error\n");
++ i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
++ return 1;
++ }
++ }
++
++ return 0;
++}
++
++int i2c_write (uchar device_addr, uint register_offset, int alen, uchar * buffer, int len)
++{
++ int i;
++
++ if ((alen == 1) && ((register_offset + len) > 256)) {
++ printf ("Register index overflow\n");
++ }
++
++ for (i = 0; i < len; i++) {
++ if (i2c_write_byte (device_addr, register_offset + i, buffer[i], alen)) {
++ printf ("I2C read: I/O error\n");
++ i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
++ return 1;
++ }
++ }
++
++ return 0;
++}
++
++#endif /* CONFIG_DRIVER_ASPEED_I2C */
+diff --git a/drivers/net/Makefile b/drivers/net/Makefile
+index 9cf2983..a1d19ca 100644
+--- a/drivers/net/Makefile
++++ b/drivers/net/Makefile
+@@ -68,6 +68,7 @@ COBJS-$(CONFIG_PLB2800_ETHER) += plb2800_eth.o
+ COBJS-$(CONFIG_RTL8139) += rtl8139.o
+ COBJS-$(CONFIG_RTL8169) += rtl8169.o
+ COBJS-$(CONFIG_SH_ETHER) += sh_eth.o
++COBJS-$(CONFIG_ASPEEDNIC) += aspeednic.o
+ COBJS-$(CONFIG_SMC91111) += smc91111.o
+ COBJS-$(CONFIG_SMC911X) += smc911x.o
+ COBJS-$(CONFIG_SUNXI_WEMAC) += sunxi_wemac.o
+diff --git a/drivers/net/aspeednic.c b/drivers/net/aspeednic.c
+new file mode 100644
+index 0000000..6b1ce05
+--- /dev/null
++++ b/drivers/net/aspeednic.c
+@@ -0,0 +1,1528 @@
++/*
++ * 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 <common.h>
++
++#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) && defined(CONFIG_ASPEEDNIC)
++
++#include <malloc.h>
++#include <net.h>
++#include <pci.h>
++
++
++/*
++ SCU88 D[31]: MAC1 MDIO
++ SCU88 D[30]: MAC1 MDC
++ SCU90 D[2]: MAC2 MDC/MDIO
++ SCU80 D[0]: MAC1 Link
++ SCU80 D[1]: MAC2 Link
++*/
++#define pci_find_devices NULL
++#define pci_read_config_dword NULL
++#if defined(CONFIG_AST1300)
++#define SCU_BASE CONFIG_SCUREG_BASE
++#else
++#define SCU_BASE 0x1E6E2000
++#endif
++#define SCU_RESET_CONTROL 0x04
++#define SCU_CLOCK_SELECTION 0x08
++#define SCU_CLOCK_CONTROL 0x0C
++#define SCU_MAC_CLOCK_DELAY 0x48
++#define SCU_SCRATCH_REGISTER 0x40
++#define SCU_HARDWARE_TRAPPING 0x70
++#define SCU_PIN_MUX 0x74
++#define SCU_MULTIFUNCTION_PIN_CTL1_REG 0x80
++#define SCU_MULTIFUNCTION_PIN_CTL3_REG 0x88
++#define SCU_MULTIFUNCTION_PIN_CTL5_REG 0x90
++#define MAC_INTERFACE 0x1C0
++#define GMII 0x0
++#define MII 0x40
++#define MAC1_CLOCK_ENABLE (1 << 20)
++#define MAC2_CLOCK_ENABLE (1 << 21)
++#define MAC_AHB_CLOCK_DIVIDER (0x07 << 16)
++#if defined(CONFIG_AST2300_FPGA_2) || defined(CONFIG_AST2300) || defined(CONFIG_AST3100) || defined(CONFIG_AST2400)
++#define MAC1_MDIO (1 << 31)
++#define MAC1_MDC (1 << 30)
++#define MAC1_PHY_LINK (1 << 0)
++#define MAC2_MDC_MDIO (1 << 2)
++#define MAC1_PHY_LINK (1 << 0)
++#define MAC2_PHY_LINK (1 << 1)
++#else
++#define MAC2_MDC_MDIO (1 << 20)
++#define MAC2_MII (1 << 21)
++#define MAC1_PHY_LINK (1 << 25)
++#define MAC2_PHY_LINK (1 << 26)
++#endif
++
++#if defined(CONFIG_AST1300)
++unsigned int aspeednic_iobase[1] = {CONFIG_MACREG_BASE};
++#else
++unsigned int aspeednic_iobase[CONFIG_ASPEED_MAC_NUMBER] = {
++ 0x1E660000, 0x1E680000};
++#endif
++
++#undef DEBUG_SROM
++#undef DEBUG_SROM2
++
++#undef UPDATE_SROM
++
++/* PCI Registers.
++ */
++#define PCI_CFDA_PSM 0x43
++
++#define CFRV_RN 0x000000f0 /* Revision Number */
++
++#define WAKEUP 0x00 /* Power Saving Wakeup */
++#define SLEEP 0x80 /* Power Saving Sleep Mode */
++
++#define DC2114x_BRK 0x0020 /* CFRV break between DC21142 & DC21143 */
++
++/* MAC chip register */
++#define ISR_REG 0x00 // interrups status register
++#define IER_REG 0x04 // interrupt maks register
++#define MAC_MADR_REG 0x08 // MAC address (Most significant)
++#define MAC_LADR_REG 0x0c // MAC address (Least significant)
++
++#define MAHT0_REG 0x10 // Multicast Address Hash Table 0 register
++#define MAHT1_REG 0x14 // Multicast Address Hash Table 1 register
++#define TXPD_REG 0x18 // Transmit Poll Demand register
++#define RXPD_REG 0x1c // Receive Poll Demand register
++#define TXR_BADR_REG 0x20 // Transmit Ring Base Address register
++#define RXR_BADR_REG 0x24 // Receive Ring Base Address register
++
++#define HPTXPD_REG 0x28 //
++#define HPTXR_BADR_REG 0x2c //
++
++#define ITC_REG 0x30 // interrupt timer control register
++#define APTC_REG 0x34 // Automatic Polling Timer control register
++#define DBLAC_REG 0x38 // DMA Burst Length and Arbitration control register
++
++#define DMAFIFOS_REG 0x3c //
++#define FEAR_REG 0x44 //
++#define TPAFCR_REG 0x48 //
++#define RBSR_REG 0x4c //for NC Body
++#define MACCR_REG 0x50 // MAC control register
++#define MACSR_REG 0x54 // MAC status register
++#define PHYCR_REG 0x60 // PHY control register
++#define PHYDATA_REG 0x64 // PHY Write Data register
++#define FCR_REG 0x68 // Flow Control register
++#define BPR_REG 0x6c // back pressure register
++#define WOLCR_REG 0x70 // Wake-On-Lan control register
++#define WOLSR_REG 0x74 // Wake-On-Lan status register
++#define WFCRC_REG 0x78 // Wake-up Frame CRC register
++#define WFBM1_REG 0x80 // wake-up frame byte mask 1st double word register
++#define WFBM2_REG 0x84 // wake-up frame byte mask 2nd double word register
++#define WFBM3_REG 0x88 // wake-up frame byte mask 3rd double word register
++#define WFBM4_REG 0x8c // wake-up frame byte mask 4th double word register
++
++
++// --------------------------------------------------------------------
++// MACCR_REG
++// --------------------------------------------------------------------
++
++#define SW_RST_bit (1UL<<31) // software reset/
++#define DIRPATH_bit (1UL<<21)
++#define RX_IPCS_FAIL_bit (1UL<<20) //
++#define RX_TCPCS_FAIL_bit (1UL<<19) //
++#define SPEED_100M_MODE_bit (1UL<<19)
++#define RX_UDPCS_FAIL_bit (1UL<<18) //
++#define RX_BROADPKT_bit (1UL<<17) // Receiving broadcast packet
++#define RX_MULTIPKT_bit (1UL<<16) // receiving multicast packet
++#define RX_HT_EN_bit (1UL<<15)
++#define RX_ALLADR_bit (1UL<<14) // not check incoming packet's destination address
++#define JUMBO_LF_bit (1UL<<13) //
++#define RX_RUNT_bit (1UL<<12) // Store incoming packet even its length is les than 64 byte
++#define CRC_CHK_bit (1UL<<11) //
++#define CRC_APD_bit (1UL<<10) // append crc to transmit packet
++#define GMAC_MODE_bit (1UL<<9) //
++#define FULLDUP_bit (1UL<<8) // full duplex
++#define ENRX_IN_HALFTX_bit (1UL<<7) //
++#define LOOP_EN_bit (1UL<<6) // Internal loop-back
++#define HPTXR_EN_bit (1UL<<5) //
++#define REMOVE_VLAN_bit (1UL<<4) //
++#define RXMAC_EN_bit (1UL<<3) // receiver enable
++#define TXMAC_EN_bit (1UL<<2) // transmitter enable
++#define RXDMA_EN_bit (1UL<<1) // enable DMA receiving channel
++#define TXDMA_EN_bit (1UL<<0) // enable DMA transmitting channel
++
++//---------------------------------------------------
++// PHY R/W Register Bit
++//---------------------------------------------------
++#define MIIWR (1UL<<27)
++#define MIIRD (1UL<<26)
++#define MDC_CYCTHR 0x34
++#define PHY_SPEED_MASK 0xC000
++#define PHY_DUPLEX_MASK 0x2000
++#define SPEED_1000M 0x02
++#define SPEED_100M 0x01
++#define SPEED_10M 0x00
++#define DUPLEX_FULL 0x01
++#define DUPLEX_HALF 0x00
++#define RESOLVED_BIT 0x800
++
++#define PHY_SPEED_DUPLEX_MASK 0x01E0
++#define PHY_100M_DUPLEX 0x0100
++#define PHY_100M_HALF 0x0080
++#define PHY_10M_DUPLEX 0x0040
++#define PHY_10M_HALF 0x0020
++
++
++
++/* Descriptor bits.
++ */
++#define TXDMA_OWN 0x80000000 /* Own Bit */
++#define RXPKT_RDY 0x00000000
++#define RXPKT_STATUS 0x80000000
++//#define EDORR 0x00008000 /* Receive End Of Ring */
++#define EDORR 0x40000000 /* Receive End Of Ring */
++#define LRS 0x10000000 /* Last Descriptor */
++#define RD_ES 0x00008000 /* Error Summary */
++//#define EDOTR 0x00008000 /* Transmit End Of Ring */
++#define EDOTR 0x40000000 /* Transmit End Of Ring */
++#define T_OWN 0x80000000 /* Own Bit */
++#define LTS 0x10000000 /* Last Segment */
++#define FTS 0x20000000 /* First Segment */
++#define CRC_ERR 0x00080000
++#define TD_ES 0x00008000 /* Error Summary */
++#define TD_SET 0x08000000 /* Setup Packet */
++#define RX_ERR 0x00040000
++#define FTL 0x00100000
++#define RUNT 0x00200000
++#define RX_ODD_NB 0x00400000
++
++#define POLL_DEMAND 1
++#define RESET_DE4X5(dev) { \
++ int i; \
++ i=INL(dev, MACCR_REG); \
++ udelay(1000); \
++ OUTL(dev, i | SW_RST_bit, MACCR_REG); \
++ for (; (INL(dev, MACCR_REG ) & SW_RST_bit) != 0; ) {udelay(1000);} \
++ OUTL(dev, 0, IER_REG ); \
++ }
++
++#define START_MAC(dev) { \
++ s32 omr; \
++ omr = INL(dev, MACCR_REG); \
++ omr |= RXMAC_EN_bit | TXMAC_EN_bit | RXDMA_EN_bit | TXDMA_EN_bit; \
++ OUTL(dev, omr, MACCR_REG); /* Enable the TX and/or RX */ \
++ }
++
++#define STOP_MAC(dev) { \
++ s32 omr; \
++ omr = INL(dev, MACCR_REG); \
++ omr &= ~(RXMAC_EN_bit | TXMAC_EN_bit | RXDMA_EN_bit | TXDMA_EN_bit); \
++ OUTL(dev, omr, MACCR_REG); /* Disable the TX and/or RX */ \
++ }
++
++#define NUM_RX_DESC PKTBUFSRX
++#define NUM_TX_DESC 1 /* Number of TX descriptors */
++#define RX_BUFF_SZ PKTSIZE_ALIGN
++#define TX_BUFF_SZ 1514
++
++#define TOUT_LOOP 1000000
++#define PHY_LOOP 250
++#define ETH_ALEN 6
++#define NCSI_LOOP 1500000
++#define RETRY_COUNT 1
++
++struct de4x5_desc {
++ volatile s32 status;
++ u32 des1;
++ u32 reserved;
++ u32 buf;
++};
++
++//PHY Information
++#define PHYID_VENDOR_MASK 0xfffffc00
++#define PHYID_VENDOR_MODEL_MASK 0xfffffff0
++#define PHYID_VENDOR_MARVELL 0x01410c00
++#define PHYID_VENDOR_BROADCOM 0x00406000
++#define PHYID_VENDOR_REALTEK 0x001cc800
++#define PHYID_RTL8201EL 0x001cc810
++#define PHYID_RTL8211 0x001cc910
++#define PHYID_BCM54612E 0x03625E6A
++
++//NCSI define & structure
++//NC-SI Command Packet
++typedef struct {
++//Ethernet Header
++ unsigned char DA[6];
++ unsigned char SA[6];
++ unsigned short EtherType; //DMTF NC-SI
++//NC-SI Control Packet
++ unsigned char MC_ID; //Management Controller should set this field to 0x00
++ unsigned char Header_Revision; //For NC-SI 1.0 spec, this field has to set 0x01
++ unsigned char Reserved_1; //Reserved has to set to 0x00
++ unsigned char IID; //Instance ID
++ unsigned char Command;
++ unsigned char Channel_ID;
++ unsigned short Payload_Length; //Payload Length = 12 bits, 4 bits are reserved
++ unsigned long Reserved_2;
++ unsigned long Reserved_3;
++} NCSI_Command_Packet;
++
++unsigned char Payload_Data[16];
++unsigned char Payload_Pad[4] = {0x00, 0x00, 0x00, 0x00};
++unsigned long Payload_Checksum = 0x00000000;
++
++
++//Command and Response Type
++#define CLEAR_INITIAL_STATE 0x00 //M
++#define SELECT_PACKAGE 0x01 //M
++#define DESELECT_PACKAGE 0x02 //M
++#define ENABLE_CHANNEL 0x03 //M
++#define DISABLE_CHANNEL 0x04 //M
++#define RESET_CHANNEL 0x05 //M
++#define ENABLE_CHANNEL_NETWORK_TX 0x06 //M
++#define DISABLE_CHANNEL_NETWORK_TX 0x07 //M
++#define AEN_ENABLE 0x08
++#define SET_LINK 0x09 //M
++#define GET_LINK_STATUS 0x0A //M
++#define SET_VLAN_FILTER 0x0B //M
++#define ENABLE_VLAN 0x0C //M
++#define DISABLE_VLAN 0x0D //M
++#define SET_MAC_ADDRESS 0x0E //M
++#define ENABLE_BROADCAST_FILTERING 0x10 //M
++#define DISABLE_BROADCAST_FILTERING 0x11 //M
++#define ENABLE_GLOBAL_MULTICAST_FILTERING 0x12
++#define DISABLE_GLOBAL_MULTICAST_FILTERING 0x13
++#define SET_NCSI_FLOW_CONTROL 0x14
++#define GET_VERSION_ID 0x15 //M
++#define GET_CAPABILITIES 0x16 //M
++#define GET_PARAMETERS 0x17 //M
++#define GET_CONTROLLER_PACKET_STATISTICS 0x18
++#define GET_NCSI_STATISTICS 0x19
++#define GET_NCSI_PASS_THROUGH_STATISTICS 0x1A
++
++//NC-SI Response Packet
++typedef struct {
++ unsigned char DA[6];
++ unsigned char SA[6];
++ unsigned short EtherType; //DMTF NC-SI
++//NC-SI Control Packet
++ unsigned char MC_ID; //Management Controller should set this field to 0x00
++ unsigned char Header_Revision; //For NC-SI 1.0 spec, this field has to set 0x01
++ unsigned char Reserved_1; //Reserved has to set to 0x00
++ unsigned char IID; //Instance ID
++ unsigned char Command;
++ unsigned char Channel_ID;
++ unsigned short Payload_Length; //Payload Length = 12 bits, 4 bits are reserved
++ unsigned short Reserved_2;
++ unsigned short Reserved_3;
++ unsigned short Reserved_4;
++ unsigned short Reserved_5;
++ unsigned short Response_Code;
++ unsigned short Reason_Code;
++ unsigned char Payload_Data[64];
++} NCSI_Response_Packet;
++
++NCSI_Command_Packet NCSI_Request;
++NCSI_Response_Packet NCSI_Respond;
++
++//Standard Response Code
++#define COMMAND_COMPLETED 0x00
++#define COMMAND_FAILED 0x01
++#define COMMAND_UNAVAILABLE 0x02
++#define COMMAND_UNSUPPORTED 0x03
++
++//Standard Reason Code
++#define NO_ERROR 0x0000
++#define INTERFACE_INITIALIZATION_REQUIRED 0x0001
++#define PARAMETER_IS_INVALID 0x0002
++#define CHANNEL_NOT_READY 0x0003
++#define PACKAGE_NOT_READY 0x0004
++#define INVALID_PAYLOAD_LENGTH 0x0005
++#define UNKNOWN_COMMAND_TYPE 0x7FFF
++
++
++struct AEN_Packet {
++//Ethernet Header
++ unsigned char DA[6];
++ unsigned char SA[6]; //Network Controller SA = FF:FF:FF:FF:FF:FF
++ unsigned short EtherType; //DMTF NC-SI
++//AEN Packet Format
++ unsigned char MC_ID; //Network Controller should set this field to 0x00
++ unsigned char Header_Revision; //For NC-SI 1.0 spec, this field has to set 0x01
++ unsigned char Reserved_1; //Reserved has to set to 0x00
++// unsigned char IID = 0x00; //Instance ID = 0 in Network Controller
++// unsigned char Command = 0xFF; //AEN = 0xFF
++ unsigned char Channel_ID;
++// unsigned short Payload_Length = 0x04; //Payload Length = 4 in Network Controller AEN Packet
++ unsigned long Reserved_2;
++ unsigned long Reserved_3;
++ unsigned char AEN_Type;
++// unsigned char Reserved_4[3] = {0x00, 0x00, 0x00};
++ unsigned long Optional_AEN_Data;
++ unsigned long Payload_Checksum;
++};
++
++//AEN Type
++#define LINK_STATUS_CHANGE 0x0
++#define CONFIGURATION_REQUIRED 0x1
++#define HOST_NC_DRIVER_STATUS_CHANGE 0x2
++
++typedef struct {
++ unsigned char Package_ID;
++ unsigned char Channel_ID;
++ unsigned long Capabilities_Flags;
++ unsigned long Broadcast_Packet_Filter_Capabilities;
++ unsigned long Multicast_Packet_Filter_Capabilities;
++ unsigned long Buffering_Capabilities;
++ unsigned long AEN_Control_Support;
++} NCSI_Capability;
++NCSI_Capability NCSI_Cap;
++
++//SET_MAC_ADDRESS
++#define UNICAST (0x00 << 5)
++#define MULTICAST (0x01 << 5)
++#define DISABLE_MAC_ADDRESS_FILTER 0x00
++#define ENABLE_MAC_ADDRESS_FILTER 0x01
++
++//GET_LINK_STATUS
++#define LINK_DOWN 0
++#define LINK_UP 1
++
++static struct de4x5_desc rx_ring[NUM_RX_DESC] __attribute__ ((aligned(32))); /* RX descriptor ring */
++static struct de4x5_desc tx_ring[NUM_TX_DESC] __attribute__ ((aligned(32))); /* TX descriptor ring */
++static int rx_new; /* RX descriptor ring pointer */
++static int tx_new; /* TX descriptor ring pointer */
++static unsigned char tx_buffer[NUM_TX_DESC][TX_BUFF_SZ] __attribute__ ((aligned(32)));
++static unsigned char rx_buffer[NUM_RX_DESC][RX_BUFF_SZ] __attribute__ ((aligned(32)));
++
++
++static char rxRingSize;
++static char txRingSize;
++static unsigned int InstanceID = 0;
++static int Retry = 0;
++
++static int aspeednic_init(struct eth_device* dev, bd_t* bis);
++static int aspeednic_send(struct eth_device* dev, volatile void *packet, int length);
++static int aspeednic_recv(struct eth_device* dev);
++static void aspeednic_halt(struct eth_device* dev);
++static void set_mac_address (struct eth_device* dev, bd_t* bis);
++static void phy_write_register (struct eth_device* dev, u8 PHY_Register, u8 PHY_Address, u16 PHY_Data);
++static u16 phy_read_register (struct eth_device* dev, u8 PHY_Register, u8 PHY_Address);
++static void set_mac_control_register(struct eth_device* dev);
++
++#if defined(CONFIG_E500)
++#define phys_to_bus(a) (a)
++#else
++#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a)
++#endif
++
++static int INL(struct eth_device* dev, u_long addr)
++{
++ return le32_to_cpu(*(volatile u_long *)(addr + dev->iobase));
++}
++
++static void OUTL(struct eth_device* dev, int command, u_long addr)
++{
++ *(volatile u_long *)(addr + dev->iobase) = cpu_to_le32(command);
++}
++
++
++struct eth_device aspeednic_device[CONFIG_ASPEED_MAC_NUMBER];
++
++void NCSI_Struct_Initialize(void)
++{
++ unsigned long i;
++
++ for (i = 0; i < 6; i++) {
++ NCSI_Request.DA[i] = 0xFF;
++ NCSI_Respond.DA[i] = 0xFF;
++ NCSI_Respond.SA[i] = 0xFF;
++ }
++ NCSI_Request.EtherType = 0xF888;
++ NCSI_Request.MC_ID = 0;
++ NCSI_Request.Header_Revision = 0x01;
++ NCSI_Request.Reserved_1 = 0;
++ NCSI_Request.Reserved_2 = 0;
++ NCSI_Request.Reserved_3 = 0;
++ NCSI_Respond.EtherType = 0xF888;
++ NCSI_Respond.MC_ID = 0;
++ NCSI_Respond.Header_Revision = 0x01;
++ NCSI_Respond.Reserved_1 = 0;
++ NCSI_Respond.Reserved_2 = 0;
++ NCSI_Respond.Reserved_3 = 0;
++}
++
++int aspeednic_initialize(bd_t *bis)
++{
++ int card_number = 0;
++ unsigned int iobase, SCURegister;
++ struct eth_device* dev;
++
++#if defined(CONFIG_AST2300_FPGA_2) || defined(CONFIG_AST2300) || defined(CONFIG_AST3100) || defined(CONFIG_AST2400)
++//AST2300
++//MAC1 CLOCK/RESET/PHY_LINK/MDC_MDIO in SCU
++ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL));
++ *(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL) = cpu_to_le32(SCURegister | 0x800);
++ udelay(100);
++ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_CLOCK_CONTROL));
++ *(volatile u_long *)(SCU_BASE + SCU_CLOCK_CONTROL) = cpu_to_le32(SCURegister & ~(MAC1_CLOCK_ENABLE));
++ udelay(10000);
++//Add Clock Selection in AST2300 A1, Please check the datasheet for more detail
++//The current sample code uses 0: H-PLL/2 because all EVBs have RGMII interface
++// SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_CLOCK_SELECTION));
++// *(volatile u_long *)(SCU_BASE + SCU_CLOCK_SELECTION) = cpu_to_le32(SCURegister & ~(MAC_AHB_CLOCK_DIVIDER));
++ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL));
++ *(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL) = cpu_to_le32(SCURegister & ~(0x800));
++ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_MULTIFUNCTION_PIN_CTL3_REG));
++ *(volatile u_long *)(SCU_BASE + SCU_MULTIFUNCTION_PIN_CTL3_REG) = cpu_to_le32(SCURegister | (MAC1_MDIO | MAC1_MDC));
++// SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_MAC_CLOCK_DELAY));
++//Currently we use fix value in MAC timing on EVB
++// *(volatile u_long *)(SCU_BASE + SCU_MAC_CLOCK_DELAY) = CONFIG_MAC_INTERFACE_CLOCK_DELAY;
++#ifdef CONFIG_MAC1_PHY_LINK_INTERRUPT
++ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_MULTIFUNCTION_PIN_CTL1_REG));
++ *(volatile u_long *)(SCU_BASE + SCU_MULTIFUNCTION_PIN_CTL1_REG) = cpu_to_le32(SCURegister | (MAC1_PHY_LINK));
++#endif
++
++//MAC2 CLOCK/RESET/PHY_LINK/MDC_MDIO
++#ifdef CONFIG_MAC2_ENABLE
++ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL));
++ *(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL) = cpu_to_le32(SCURegister | 0x1000);
++ udelay(10);
++ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_CLOCK_CONTROL));
++ *(volatile u_long *)(SCU_BASE + SCU_CLOCK_CONTROL) = cpu_to_le32(SCURegister & ~(MAC2_CLOCK_ENABLE));
++ udelay(10000);
++ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL));
++ *(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL) = cpu_to_le32(SCURegister & ~(0x1000));
++ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_MULTIFUNCTION_PIN_CTL5_REG));
++ *(volatile u_long *)(SCU_BASE + SCU_MULTIFUNCTION_PIN_CTL5_REG) = cpu_to_le32(SCURegister | (MAC2_MDC_MDIO));
++#endif
++#ifdef CONFIG_MAC2_PHY_LINK_INTERRUPT
++ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_MULTIFUNCTION_PIN_CTL1_REG));
++ *(volatile u_long *)(SCU_BASE + SCU_MULTIFUNCTION_PIN_CTL1_REG) = cpu_to_le32(SCURegister | (MAC2_PHY_LINK));
++#endif
++#else
++//AST1100/AST2050/AST2100
++//MAC1 RESET/PHY_LINK in SCU
++ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL));
++ *(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL) = cpu_to_le32(SCURegister & ~(0x800));
++#ifdef CONFIG_MAC1_PHY_LINK_INTERRUPT
++ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_PIN_MUX));
++ *(volatile u_long *)(SCU_BASE + SCU_PIN_MUX) = cpu_to_le32(SCURegister | (MAC1_PHY_LINK));
++#endif
++
++//MAC2
++#ifdef CONFIG_MAC2_ENABLE
++ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL));
++ *(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL) = cpu_to_le32(SCURegister & ~(0x1000));
++ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_PIN_MUX));
++ *(volatile u_long *)(SCU_BASE + SCU_PIN_MUX) = cpu_to_le32(SCURegister | (MAC2_MDC_MDIO));
++#endif
++#ifdef CONFIG_MAC2_MII_ENABLE
++ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_PIN_MUX));
++ *(volatile u_long *)(SCU_BASE + SCU_PIN_MUX) = cpu_to_le32(SCURegister | (MAC2_MII));
++#endif
++#ifdef CONFIG_MAC2_PHY_LINK_INTERRUPT
++ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_PIN_MUX));
++ *(volatile u_long *)(SCU_BASE + SCU_PIN_MUX) = cpu_to_le32(SCURegister | (MAC2_PHY_LINK));
++#endif
++#endif
++
++ iobase = aspeednic_iobase[card_number];
++
++ dev = &aspeednic_device[card_number];
++
++
++ sprintf(dev->name, "aspeednic#%d", card_number);
++
++ dev->iobase = iobase;
++
++ if (CONFIG_MAC1_PHY_SETTING >= 1) {
++//NCSI Struct Initialize
++ NCSI_Struct_Initialize();
++ }
++//Set Scratch register (0x1E6E2040 D[15:14])(0x1E6E2041 D[7:6]) to inform kernel MAC1 driver
++ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_SCRATCH_REGISTER));
++ *(volatile u_long *)(SCU_BASE + SCU_SCRATCH_REGISTER) = cpu_to_le32((SCURegister & ~(0xc000)) | (CONFIG_MAC1_PHY_SETTING << 14));
++//Set Scratch register (0x1E6E2040 D[13:12])(0x1E6E2041 D[5:4]) to inform kernel MAC2 driver
++ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_SCRATCH_REGISTER));
++ *(volatile u_long *)(SCU_BASE + SCU_SCRATCH_REGISTER) = cpu_to_le32((SCURegister & ~(0x3000)) | (CONFIG_MAC2_PHY_SETTING << 12));
++
++
++ dev->init = aspeednic_init;
++ dev->halt = aspeednic_halt;
++ dev->send = aspeednic_send;
++ dev->recv = aspeednic_recv;
++
++ /* Ensure we're not sleeping. */
++ if (CONFIG_MAC1_PHY_SETTING >= 1) {
++ udelay(2000000); //2.0 sec
++ }
++ else {
++ udelay(10 * 1000);
++ }
++
++
++ dev->init(dev, bis);
++
++ eth_register(dev);
++
++
++ return card_number;
++}
++
++void Calculate_Checksum(unsigned char *buffer_base, int Length)
++{
++ unsigned int i, CheckSum = 0;
++ unsigned int Data, Data1;
++
++ for (i = 0; i < ((Length - 14) / 2); i++) {
++ Data = buffer_base[i * 2];
++ Data1 = buffer_base[i * 2 + 1];
++ CheckSum += ((Data << 8) + Data1);
++ }
++ Payload_Checksum = (~(CheckSum) + 1); //2's complement
++//Inverse for insert into buffer
++ Data = (Payload_Checksum & 0xFF000000) >> 24;
++ Data1 = (Payload_Checksum & 0x000000FF) << 24;
++ Payload_Checksum = (Payload_Checksum & 0x00FFFF00) + Data + Data1;
++ Data = (Payload_Checksum & 0x00FF0000) >> 8;
++ Data1 = (Payload_Checksum & 0x0000FF00) << 8;
++ Payload_Checksum = (Payload_Checksum & 0xFF0000FF) + Data + Data1;
++}
++
++void copy_data (int Length)
++{
++ memcpy ((unsigned char *)(tx_ring[tx_new].buf + 30), &Payload_Data, Length);
++ Calculate_Checksum((unsigned char *)(tx_ring[tx_new].buf + 14), 30 + Length);
++ memcpy ((unsigned char *)(tx_ring[tx_new].buf + 30 + Length), &Payload_Checksum, 4);
++}
++
++void NCSI_Rx (void)
++{
++ unsigned long status, length, i = 0;
++
++ do {
++ status = (s32)le32_to_cpu(rx_ring[rx_new].status);
++ i++;
++ } while (!(((status & RXPKT_STATUS) != 0) || (i >= NCSI_LOOP)));
++
++ if (i < NCSI_LOOP) {
++ if (status & LRS) {
++ length = (le32_to_cpu(rx_ring[rx_new].status) & 0x3FFF);
++ memcpy (&NCSI_Respond, (unsigned char *)rx_ring[rx_new].buf, length);
++ }
++ rx_ring[rx_new].status &= cpu_to_le32(0x7FFFFFFF);
++ rx_new = (rx_new + 1) % rxRingSize;
++ }
++}
++
++void DeSelect_Package (struct eth_device* dev, int Package_ID)
++{
++ unsigned long Combined_Channel_ID;
++
++//TX
++ do {
++ InstanceID++;
++ NCSI_Request.IID = InstanceID;
++ NCSI_Request.Command = DESELECT_PACKAGE;
++ Combined_Channel_ID = (Package_ID << 5) + 0x1F; //Internal Channel ID = 0x1F, 0x1F means all channel
++ NCSI_Request.Channel_ID = Combined_Channel_ID;
++ NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
++ copy_data (NCSI_Request.Payload_Length);
++ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
++//RX
++ NCSI_Rx();
++ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (DESELECT_PACKAGE | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
++ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
++ Retry++;
++ InstanceID--;
++ }
++ else {
++ Retry = 0;
++ }
++ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
++ Retry = 0;
++}
++
++int Select_Package (struct eth_device* dev, int Package_ID)
++{
++ unsigned long Combined_Channel_ID, Found = 0;
++
++//TX
++ do {
++ InstanceID++;
++ NCSI_Request.IID = InstanceID;
++ NCSI_Request.Command = SELECT_PACKAGE;
++ Combined_Channel_ID = (Package_ID << 5) + 0x1F; //Internal Channel ID = 0x1F
++ NCSI_Request.Channel_ID = Combined_Channel_ID;
++ NCSI_Request.Payload_Length = (4 << 8);
++ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
++ NCSI_Request.Payload_Length = 4;
++ memset ((void *)Payload_Data, 0, 4);
++ Payload_Data[3] = 1; //Arbitration Disable
++ copy_data (NCSI_Request.Payload_Length);
++ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
++//RX
++ NCSI_Rx();
++ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (SELECT_PACKAGE | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
++ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
++ Retry++;
++ Found = 0;
++ InstanceID--;
++ }
++ else {
++ Retry = 0;
++ Found = 1;
++ }
++ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
++ Retry = 0;
++
++ return Found;
++}
++
++void DeSelect_Active_Package (struct eth_device* dev)
++{
++ unsigned long Combined_Channel_ID;
++//TX
++ do {
++ InstanceID++;
++ NCSI_Request.IID = InstanceID;
++ NCSI_Request.Command = DESELECT_PACKAGE;
++ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + 0x1F; //Internal Channel ID = 0x1F, 0x1F means all channel
++ NCSI_Request.Channel_ID = Combined_Channel_ID;
++ NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
++ copy_data (NCSI_Request.Payload_Length);
++ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
++//RX
++ NCSI_Rx();
++ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (DESELECT_PACKAGE | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
++ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
++ Retry++;
++ InstanceID--;
++ }
++ else {
++ Retry = 0;
++ }
++ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
++ Retry = 0;
++}
++
++int Select_Active_Package (struct eth_device* dev)
++{
++ unsigned long Combined_Channel_ID, Found = 0;
++//TX
++ do {
++ InstanceID++;
++ NCSI_Request.IID = InstanceID;
++ NCSI_Request.Command = SELECT_PACKAGE;
++ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + 0x1F; //Internal Channel ID = 0x1F
++ NCSI_Request.Channel_ID = Combined_Channel_ID;
++ NCSI_Request.Payload_Length = (4 << 8);
++ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
++ NCSI_Request.Payload_Length = 4;
++ memset ((void *)Payload_Data, 0, 4);
++ Payload_Data[3] = 1; //Arbitration Disable
++ copy_data (NCSI_Request.Payload_Length);
++ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
++//RX
++ NCSI_Rx();
++ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (SELECT_PACKAGE | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
++ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
++ Retry++;
++ Found = 0;
++ InstanceID--;
++ }
++ else {
++ Retry = 0;
++ Found = 1;
++ }
++ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
++ Retry = 0;
++
++ return Found;
++}
++
++int Clear_Initial_State (struct eth_device* dev, int Channel_ID)
++{
++ unsigned long Combined_Channel_ID, Found = 0;
++//TX
++ do {
++ InstanceID++;
++ NCSI_Request.IID = InstanceID;
++ NCSI_Request.Command = CLEAR_INITIAL_STATE;
++ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + Channel_ID; //Internal Channel ID = 0
++ NCSI_Request.Channel_ID = Combined_Channel_ID;
++ NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
++ copy_data (NCSI_Request.Payload_Length);
++ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
++//RX
++ NCSI_Rx();
++ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (CLEAR_INITIAL_STATE | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
++ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
++ Retry++;
++ Found = 0;
++ InstanceID--;
++ }
++ else {
++ Retry = 0;
++ Found = 1;
++ }
++ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
++ Retry = 0;
++
++ return Found;
++}
++
++void Get_Version_ID (struct eth_device* dev)
++{
++ unsigned long Combined_Channel_ID;
++//TX
++ do {
++ InstanceID++;
++ NCSI_Request.IID = InstanceID;
++ NCSI_Request.Command = GET_VERSION_ID;
++ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + NCSI_Cap.Channel_ID;
++ NCSI_Request.Channel_ID = Combined_Channel_ID;
++ NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
++ copy_data (NCSI_Request.Payload_Length);
++ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
++//RX
++ NCSI_Rx();
++ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (GET_VERSION_ID | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
++ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
++ Retry++;
++ InstanceID--;
++ }
++ else {
++ Retry = 0;
++ }
++ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
++ Retry = 0;
++}
++
++void Get_Capabilities (struct eth_device* dev)
++{
++ unsigned long Combined_Channel_ID;
++//TX
++ do {
++ InstanceID++;
++ NCSI_Request.IID = InstanceID;
++ NCSI_Request.Command = GET_CAPABILITIES;
++ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + NCSI_Cap.Channel_ID;
++ NCSI_Request.Channel_ID = Combined_Channel_ID;
++ NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
++ copy_data (NCSI_Request.Payload_Length);
++ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
++//RX
++ NCSI_Rx();
++ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (GET_CAPABILITIES | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
++ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
++ Retry++;
++ InstanceID--;
++ }
++ else {
++ Retry = 0;
++ NCSI_Cap.Capabilities_Flags = NCSI_Respond.Payload_Data[0];
++ NCSI_Cap.Broadcast_Packet_Filter_Capabilities = NCSI_Respond.Payload_Data[1];
++ NCSI_Cap.Multicast_Packet_Filter_Capabilities = NCSI_Respond.Payload_Data[2];
++ NCSI_Cap.Buffering_Capabilities = NCSI_Respond.Payload_Data[3];
++ NCSI_Cap.AEN_Control_Support = NCSI_Respond.Payload_Data[4];
++ }
++ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
++ Retry = 0;
++}
++
++void Enable_Set_MAC_Address (struct eth_device* dev)
++{
++ unsigned long Combined_Channel_ID, i;
++//TX
++ do {
++ InstanceID++;
++ NCSI_Request.IID = InstanceID;
++ NCSI_Request.Command = SET_MAC_ADDRESS;
++ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + NCSI_Cap.Channel_ID;
++ NCSI_Request.Channel_ID = Combined_Channel_ID;
++ NCSI_Request.Payload_Length = (8 << 8);
++ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
++ NCSI_Request.Payload_Length = 8;
++ for (i = 0; i < 6; i++) {
++ Payload_Data[i] = NCSI_Request.SA[i];
++ }
++ Payload_Data[6] = 1; //MAC Address Num = 1 --> address filter 1, fixed in sample code
++ Payload_Data[7] = UNICAST + 0 + ENABLE_MAC_ADDRESS_FILTER; //AT + Reserved + E
++ copy_data (NCSI_Request.Payload_Length);
++ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
++//RX
++ NCSI_Rx();
++ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (SET_MAC_ADDRESS | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
++ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
++ Retry++;
++ InstanceID--;
++ }
++ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
++ Retry = 0;
++}
++
++void Enable_Broadcast_Filter (struct eth_device* dev)
++{
++ unsigned long Combined_Channel_ID;
++//TX
++ do {
++ InstanceID++;
++ NCSI_Request.IID = InstanceID;
++ NCSI_Request.Command = ENABLE_BROADCAST_FILTERING;
++ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + NCSI_Cap.Channel_ID;
++ NCSI_Request.Channel_ID = Combined_Channel_ID;
++ NCSI_Request.Payload_Length = (4 << 8);
++ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
++ NCSI_Request.Payload_Length = 4;
++ memset ((void *)Payload_Data, 0, 4);
++ Payload_Data[3] = 0xF; //ARP, DHCP, NetBIOS
++ copy_data (NCSI_Request.Payload_Length);
++ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
++//RX
++ NCSI_Rx();
++ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (ENABLE_BROADCAST_FILTERING | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
++ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
++ Retry++;
++ InstanceID--;
++ }
++ else {
++ Retry = 0;
++ }
++ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
++ Retry = 0;
++}
++
++void Enable_AEN (struct eth_device* dev)
++{
++ unsigned long Combined_Channel_ID;
++//TX
++ do {
++ InstanceID++;
++ NCSI_Request.IID = InstanceID;
++ NCSI_Request.Command = AEN_ENABLE;
++ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + NCSI_Cap.Channel_ID;
++ NCSI_Request.Channel_ID = Combined_Channel_ID;
++ NCSI_Request.Payload_Length = (8 << 8);
++ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
++ NCSI_Request.Payload_Length = 8;
++ memset ((void *)Payload_Data, 0, 8);
++ Payload_Data[3] = 0x00; //MC ID
++ Payload_Data[7] = 0x01; //Link Status only
++ copy_data (NCSI_Request.Payload_Length);
++ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
++//RX
++ NCSI_Rx();
++ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (AEN_ENABLE | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
++ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
++ Retry++;
++ InstanceID--;
++ }
++ else {
++ Retry = 0;
++ }
++ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
++ Retry = 0;
++}
++
++void Enable_Network_TX (struct eth_device* dev)
++{
++ unsigned long Combined_Channel_ID;
++//TX
++ do {
++ InstanceID++;
++ NCSI_Request.IID = InstanceID;
++ NCSI_Request.Command = ENABLE_CHANNEL_NETWORK_TX;
++ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + NCSI_Cap.Channel_ID;
++ NCSI_Request.Channel_ID = Combined_Channel_ID;
++ NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
++ copy_data (NCSI_Request.Payload_Length);
++ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
++//RX
++ NCSI_Rx();
++ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (ENABLE_CHANNEL_NETWORK_TX | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
++ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
++ Retry++;
++ InstanceID--;
++ }
++ else {
++ Retry = 0;
++ }
++ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
++ Retry = 0;
++}
++
++void Disable_Network_TX (struct eth_device* dev)
++{
++ unsigned long Combined_Channel_ID;
++//TX
++ do {
++ InstanceID++;
++ NCSI_Request.IID = InstanceID;
++ NCSI_Request.Command = DISABLE_CHANNEL_NETWORK_TX;
++ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + NCSI_Cap.Channel_ID;
++ NCSI_Request.Channel_ID = Combined_Channel_ID;
++ NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
++ copy_data (NCSI_Request.Payload_Length);
++ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
++//RX
++ NCSI_Rx();
++ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (DISABLE_CHANNEL_NETWORK_TX | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
++ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
++ Retry++;
++ InstanceID--;
++ }
++ else {
++ Retry = 0;
++ }
++ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
++ Retry = 0;
++}
++
++void Enable_Channel (struct eth_device* dev)
++{
++ unsigned long Combined_Channel_ID;
++//TX
++ do {
++ InstanceID++;
++ NCSI_Request.IID = InstanceID;
++ NCSI_Request.Command = ENABLE_CHANNEL;
++ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + NCSI_Cap.Channel_ID;
++ NCSI_Request.Channel_ID = Combined_Channel_ID;
++ NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
++ copy_data (NCSI_Request.Payload_Length);
++ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
++//RX
++ NCSI_Rx();
++ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (ENABLE_CHANNEL | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
++ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
++ Retry++;
++ InstanceID--;
++ }
++ else {
++ Retry = 0;
++ }
++ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
++ Retry = 0;
++}
++
++void Disable_Channel (struct eth_device* dev)
++{
++ unsigned long Combined_Channel_ID;
++//TX
++ do {
++ InstanceID++;
++ NCSI_Request.IID = InstanceID;
++ NCSI_Request.Command = DISABLE_CHANNEL;
++ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + NCSI_Cap.Channel_ID;
++ NCSI_Request.Channel_ID = Combined_Channel_ID;
++ NCSI_Request.Payload_Length = (4 << 8);
++ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
++ NCSI_Request.Payload_Length = 4;
++ memset ((void *)Payload_Data, 0, 4);
++ Payload_Data[3] = 0x1; //ALD
++ copy_data (NCSI_Request.Payload_Length);
++ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
++//RX
++ NCSI_Rx();
++ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (DISABLE_CHANNEL | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
++ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
++ Retry++;
++ InstanceID--;
++ }
++ else {
++ Retry = 0;
++ }
++ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
++ Retry = 0;
++}
++
++int Get_Link_Status (struct eth_device* dev)
++{
++ unsigned long Combined_Channel_ID;
++//TX
++ do {
++ InstanceID++;
++ NCSI_Request.IID = InstanceID;
++ NCSI_Request.Command = GET_LINK_STATUS;
++ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + NCSI_Cap.Channel_ID;
++ NCSI_Request.Channel_ID = Combined_Channel_ID;
++ NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
++ copy_data (NCSI_Request.Payload_Length);
++ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
++//RX
++ NCSI_Rx();
++ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (GET_LINK_STATUS | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
++ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
++ Retry++;
++ InstanceID--;
++ }
++ else {
++ Retry = 0;
++ }
++ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
++ Retry = 0;
++ if (NCSI_Respond.Payload_Data[3] & 0x40) {
++ return (NCSI_Respond.Payload_Data[3] & 0x01); //Link Up or Not
++ }
++ else {
++ return 0; //Auto Negotiate did not finish
++ }
++}
++
++void Set_Link (struct eth_device* dev)
++{
++ unsigned long Combined_Channel_ID;
++//TX
++ do {
++ InstanceID++;
++ NCSI_Request.IID = InstanceID;
++ NCSI_Request.Command = SET_LINK;
++ Combined_Channel_ID = (NCSI_Cap.Package_ID << 5) + NCSI_Cap.Channel_ID;
++ NCSI_Request.Channel_ID = Combined_Channel_ID;
++ NCSI_Request.Payload_Length = (8 << 8);
++ memcpy ((unsigned char *)tx_ring[tx_new].buf, &NCSI_Request, 30);
++ NCSI_Request.Payload_Length = 8;
++ memset ((void *)Payload_Data, 0, 8);
++ Payload_Data[2] = 0x02; //full duplex
++ Payload_Data[3] = 0x04; //100M, auto-disable
++ copy_data (NCSI_Request.Payload_Length);
++ aspeednic_send (dev, (void *)tx_ring[tx_new].buf, 30 + NCSI_Request.Payload_Length + 4);
++//RX
++ NCSI_Rx();
++ if ((NCSI_Respond.IID != InstanceID) || (NCSI_Respond.Command != (SET_LINK | 0x80)) || (NCSI_Respond.Response_Code != COMMAND_COMPLETED)) {
++ printf ("Retry: Command = %x, Response_Code = %x\n", NCSI_Request.Command, NCSI_Respond.Response_Code);
++ Retry++;
++ InstanceID--;
++ }
++ else {
++ Retry = 0;
++ }
++ } while ((Retry != 0) && (Retry <= RETRY_COUNT));
++ Retry = 0;
++}
++
++static int aspeednic_init(struct eth_device* dev, bd_t* bis)
++{
++ unsigned long i, Package_Found = 0, Channel_Found = 0, Re_Send = 0, Link_Status;
++
++ RESET_DE4X5(dev);
++ set_mac_address (dev, bis);
++ set_mac_control_register (dev);
++
++ for (i = 0; i < NUM_RX_DESC; i++) {
++ rx_ring[i].status = cpu_to_le32(RXPKT_RDY + RX_BUFF_SZ);
++ rx_ring[i].buf = (u32)(&rx_buffer[i]);
++ rx_ring[i].reserved = 0;
++ }
++
++ for (i=0; i < NUM_TX_DESC; i++) {
++ tx_ring[i].status = 0;
++ tx_ring[i].des1 = 0;
++ tx_ring[i].buf = (u32)(&tx_buffer[i]);
++ tx_ring[i].reserved = 0;
++ }
++
++ rxRingSize = NUM_RX_DESC;
++ txRingSize = NUM_TX_DESC;
++
++ rx_ring[rxRingSize - 1].status |= cpu_to_le32(EDORR);
++ tx_ring[txRingSize - 1].status |= cpu_to_le32(EDOTR);
++
++ OUTL(dev, ((u32) &tx_ring), TXR_BADR_REG);
++ OUTL(dev, ((u32) &rx_ring), RXR_BADR_REG);
++
++ START_MAC(dev);
++
++ tx_new = 0;
++ rx_new = 0;
++
++ if (CONFIG_MAC1_PHY_SETTING >= 1) {
++//NCSI Start
++//DeSelect Package/ Select Package
++ for (i = 0; i < 4; i++) {
++ DeSelect_Package (dev, i);
++ Package_Found = Select_Package (dev, i);
++ if (Package_Found == 1) {
++//AST2100/AST2050/AST1100 supports 1 package only in current firmware version
++ NCSI_Cap.Package_ID = i;
++// Package_Found = 0;
++ break;
++ }
++ }
++ if (Package_Found != 0) {
++//Initiali State
++ for (i = 0; i < 2; i++) { //Suppose 2 channels in current version, You could modify it to 0x1F to support 31 channels
++ Channel_Found = Clear_Initial_State(dev, i);
++ if (Channel_Found == 1) {
++ NCSI_Cap.Channel_ID = i;
++ printf ("Found NCSI Network Controller at (%d, %d)\n", NCSI_Cap.Package_ID, NCSI_Cap.Channel_ID);
++//Get Version and Capabilities
++ Get_Version_ID(dev);
++ Get_Capabilities(dev);
++ Select_Active_Package(dev);
++//Configuration
++ Enable_Set_MAC_Address(dev);
++ Enable_Broadcast_Filter(dev);
++//Enable TX
++ Enable_Network_TX(dev);
++//Enable Channel
++ Enable_Channel(dev);
++//Get Link Status
++ Re_Get_Link_Status:
++ Link_Status = Get_Link_Status(dev);
++ if (Link_Status == LINK_UP) {
++ printf ("Using NCSI Network Controller (%d, %d)\n", NCSI_Cap.Package_ID, NCSI_Cap.Channel_ID);
++ break;
++ }
++ else if ((Link_Status == LINK_DOWN) && (Re_Send < 2)) {
++ Re_Send++;
++ goto Re_Get_Link_Status;
++ }
++//Disable TX
++ Disable_Network_TX(dev);
++//Disable Channel
++// Disable_Channel(dev);
++ Re_Send = 0;
++ Channel_Found = 0;
++ }
++ }
++ }
++ }
++ return 1;
++}
++
++static int aspeednic_send(struct eth_device* dev, volatile void *packet, int length)
++{
++ int status = -1, oldlength = 0, fail = 0;
++ int i;
++
++ if (length <= 0) {
++ printf("%s: bad packet size: %d\n", dev->name, length);
++ goto Done;
++ }
++
++
++ for(i = 0; (tx_ring[tx_new].status & cpu_to_le32(TXDMA_OWN)) == 0x80000000; i++) {
++ if (i >= TOUT_LOOP) {
++ printf("%s: tx error buffer not ready\n", dev->name);
++ fail = 1;
++ goto Done;
++ }
++ }
++
++
++ if (length < 60) {
++ oldlength = length;
++// memset ((void *)cpu_to_le32((u32) (packet + length)), 0, 60 - length);
++ length = 60;
++ }
++ tx_ring[tx_new].buf = cpu_to_le32(((u32) packet));
++ tx_ring[tx_new].status &= (~(0x3FFF));
++ tx_ring[tx_new].status |= cpu_to_le32(LTS | FTS | length);
++ tx_ring[tx_new].status |= cpu_to_le32(TXDMA_OWN);
++
++ OUTL(dev, POLL_DEMAND, TXPD_REG);
++
++ for (i = 0; (tx_ring[tx_new].status & cpu_to_le32(TXDMA_OWN)) == 0x80000000; i++)
++ {
++ if (i >= TOUT_LOOP)
++ {
++ printf(".%s: tx buffer not ready\n", dev->name);
++ fail = 1;
++ goto Done;
++ }
++ }
++
++ if (fail != 1) {
++ status = oldlength;
++ }
++
++ Done:
++ tx_new = (tx_new+1) % NUM_TX_DESC;
++
++ return status;
++}
++
++static int aspeednic_recv(struct eth_device* dev)
++{
++ s32 status;
++ int length = 0;
++
++ for ( ; ; )
++ {
++ status = (s32)le32_to_cpu(rx_ring[rx_new].status);
++
++ if ((status & RXPKT_STATUS) == 0) {
++ break;
++ }
++
++ if (status & LRS) {
++ /* Valid frame status.
++ */
++ if (status & (RX_ERR | CRC_ERR | FTL | RUNT | RX_ODD_NB)) {
++
++ /* There was an error.
++ */
++ printf("RX error status = 0x%08X\n", status);
++ } else {
++ /* A valid frame received.
++ */
++ length = (le32_to_cpu(rx_ring[rx_new].status) & 0x3FFF);
++ debug("%s(): RX buffer %d, %x received\n",
++ __func__, rx_new, length);
++
++
++ /* Pass the packet up to the protocol
++ * layers.
++ */
++ NetReceive(rx_buffer[rx_new], length - 4);
++ }
++
++ /* Change buffer ownership for this frame, back
++ * to the adapter.
++ */
++ rx_ring[rx_new].status &= cpu_to_le32(0x7FFFFFFF);
++// rx_ring[rx_new].status = cpu_to_le32(RXPKT_RDY);
++ }
++
++ /* Update entry information.
++ */
++ rx_new = (rx_new + 1) % rxRingSize;
++ }
++
++ return length;
++}
++
++static void aspeednic_halt(struct eth_device* dev)
++{
++ STOP_MAC(dev);
++}
++
++static void set_mac_address (struct eth_device* dev, bd_t* bis)
++{
++ unsigned char mac_address[6]; // 6 bytes mac address
++ unsigned char ethaddress[20]; // string for setenv function
++ char *s;
++ int i, env; // env variable 0: eeprom, 1: environment parameters
++
++ s = getenv ("eeprom");
++ env = (s && (*s == 'y')) ? 0 : 1;
++
++ if (env == 0) {
++ env = 1;
++ eeprom_init ();
++ eeprom_read (0xA0, 0, mac_address, 6);
++
++ for (i = 0; i < 6; i++) {
++ if (mac_address[i] != 0xFF) {
++ env = 0; //Suppose not all 0xFF is valid
++ }
++ }
++ }
++
++ if (env == 0) { // EEPROM
++ sprintf (ethaddress, "%02X:%02X:%02X:%02X:%02X:%02X", mac_address[0], mac_address[1], mac_address[2], mac_address[3], mac_address[4], mac_address[5]);
++ setenv ("ethaddr", ethaddress);
++ OUTL(dev, ((mac_address[2] << 24) | (mac_address[3] << 16) | (mac_address[4] << 8) | mac_address[5]), MAC_LADR_REG);
++ OUTL(dev, ((mac_address[0] << 8) | mac_address[1]), MAC_MADR_REG);
++ if (CONFIG_MAC1_PHY_SETTING >= 1) {
++ for (i = 0; i < 6; i++) {
++ NCSI_Request.SA[i] = mac_address[i];
++ }
++ }
++ }
++ else { // Environment Parameters
++ OUTL(dev, ((bis->bi_enetaddr[2] << 24) | (bis->bi_enetaddr[3] << 16) | (bis->bi_enetaddr[4] << 8) | bis->bi_enetaddr[5]), MAC_LADR_REG);
++ OUTL(dev, ((bis->bi_enetaddr[0] << 8) | bis->bi_enetaddr[1]), MAC_MADR_REG);
++ if (CONFIG_MAC1_PHY_SETTING >= 1) {
++ for (i = 0; i < 6; i++) {
++ NCSI_Request.SA[i] = bis->bi_enetaddr[i];
++ }
++ }
++ }
++
++}
++
++
++static u16 phy_read_register (struct eth_device* dev, u8 PHY_Register, u8 PHY_Address)
++{
++ u32 Data, Status = 0, Loop_Count = 0, PHY_Ready = 1;
++ u16 Return_Data;
++
++#ifdef REALTEK_PHY_SUPPORT
++ PHY_Address = 0x01;
++#endif
++//20us * 100 = 2ms > (1 / 2.5Mhz) * 0x34
++ OUTL(dev, (PHY_Register << 21) + (PHY_Address << 16) + MIIRD + MDC_CYCTHR, PHYCR_REG);
++ do {
++ udelay(20);
++ Status = (INL (dev, PHYCR_REG) & MIIRD);
++ Loop_Count++;
++ if (Loop_Count >= 100) {
++ PHY_Ready = 0;
++ break;
++ }
++ } while (Status == MIIRD);
++
++ if (PHY_Ready == 0) {
++ printf ("PHY NOT REDAY ");
++ return 0;
++ }
++ Data = INL (dev, PHYDATA_REG);
++ Return_Data = (Data >> 16);
++
++ return Return_Data;
++}
++
++
++static void phy_write_register (struct eth_device* dev, u8 PHY_Register, u8 PHY_Address, u16 PHY_Data)
++{
++ u32 Status = 0, Loop_Count = 0, PHY_Ready = 1;
++
++#ifdef REALTEK_PHY_SUPPORT
++ PHY_Address = 0x01;
++#endif
++//20us * 100 = 2ms > (1 / 2.5Mhz) * 0x34
++ OUTL(dev, PHY_Data, PHYDATA_REG);
++ OUTL(dev, (PHY_Register << 21) + (PHY_Address << 16) + MIIWR + MDC_CYCTHR, PHYCR_REG);
++ do {
++ udelay(20);
++ Status = (INL (dev, PHYCR_REG) & MIIWR);
++ Loop_Count++;
++ if (Loop_Count >= 100) {
++ PHY_Ready = 0;
++ break;
++ }
++ } while (Status == MIIWR);
++ if (PHY_Ready == 0) {
++ printf ("PHY NOT REDAY ");
++ }
++}
++
++static void set_mac_control_register (struct eth_device* dev)
++{
++ unsigned long MAC_CR_Register = 0;
++ unsigned long Loop_Count = 0, PHY_Ready = 1, Chip_ID;
++ u16 PHY_Status, PHY_Speed, PHY_Duplex, Resolved_Status = 0, Advertise, Link_Partner;
++
++ if (CONFIG_MAC1_PHY_SETTING >= 1) {
++ MAC_CR_Register = SPEED_100M_MODE_bit | RX_BROADPKT_bit | FULLDUP_bit | RXMAC_EN_bit | RXDMA_EN_bit | TXMAC_EN_bit | TXDMA_EN_bit | CRC_APD_bit;
++ }
++ else {
++ MAC_CR_Register = SPEED_100M_MODE_bit | FULLDUP_bit | RXMAC_EN_bit | RXDMA_EN_bit | TXMAC_EN_bit | TXDMA_EN_bit | CRC_APD_bit;
++ }
++
++ if (CONFIG_MAC1_PHY_SETTING != 2) {
++ Chip_ID = ((phy_read_register (dev, 0x02, 0)) << 16);
++ Chip_ID |= (phy_read_register (dev, 0x03, 0) & 0xffff);
++ if (((Chip_ID & PHYID_VENDOR_MASK) == PHYID_VENDOR_BROADCOM) ||
++ ((Chip_ID & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8201EL)) {
++ Advertise = phy_read_register (dev, 0x04, 0);
++ Link_Partner = phy_read_register (dev, 0x05, 0);
++ Advertise = (Advertise & PHY_SPEED_DUPLEX_MASK);
++ Link_Partner = (Link_Partner & PHY_SPEED_DUPLEX_MASK);
++ if ((Advertise & Link_Partner) & PHY_100M_DUPLEX) {
++ MAC_CR_Register |= SPEED_100M_MODE_bit;
++ MAC_CR_Register |= FULLDUP_bit;
++ }
++ else if ((Advertise & Link_Partner) & PHY_100M_HALF) {
++ MAC_CR_Register |= SPEED_100M_MODE_bit;
++ MAC_CR_Register &= ~FULLDUP_bit;
++ }
++ else if ((Advertise & Link_Partner) & PHY_10M_DUPLEX) {
++ MAC_CR_Register &= ~SPEED_100M_MODE_bit;
++ MAC_CR_Register |= FULLDUP_bit;
++ }
++ else if ((Advertise & Link_Partner) & PHY_10M_HALF) {
++ MAC_CR_Register &= ~SPEED_100M_MODE_bit;
++ MAC_CR_Register &= ~FULLDUP_bit;
++ }
++ }
++ else if (((Chip_ID & PHYID_VENDOR_MASK) == PHYID_VENDOR_MARVELL) ||
++ ((Chip_ID & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8211)) {
++//Max waiting time = (20 + 2)ms * 250(PHY_LOOP) = 5.5s
++ do {
++ udelay (20000);
++ Resolved_Status = (phy_read_register (dev, 0x11, 0) & RESOLVED_BIT);
++ Loop_Count++;
++ if (Loop_Count >= PHY_LOOP) {
++ PHY_Ready = 0;
++ printf ("PHY NOT READY ");
++ break;
++ }
++ } while (Resolved_Status != RESOLVED_BIT);
++
++ if (PHY_Ready == 1) {
++ PHY_Status = phy_read_register (dev, 0x11, 0);
++ PHY_Speed = (PHY_Status & PHY_SPEED_MASK) >> 14;
++ PHY_Duplex = (PHY_Status & PHY_DUPLEX_MASK) >> 13;
++
++ if (PHY_Speed == SPEED_1000M) {
++ MAC_CR_Register |= GMAC_MODE_bit;
++ }
++ else {
++ MAC_CR_Register &= ~GMAC_MODE_bit;
++ if (PHY_Speed == SPEED_10M) {
++ MAC_CR_Register &= ~SPEED_100M_MODE_bit;
++ }
++ }
++ if (PHY_Duplex == DUPLEX_HALF) {
++ MAC_CR_Register &= ~FULLDUP_bit;
++ }
++ }
++//LED Control
++// if (Chip_ID == 0x1C) {
++// PHY_Status = phy_read_register (dev, 0x18, 0);
++// phy_write_register (dev, 0x18, 0, (PHY_Status | 0x09));
++// }
++//LED Control D[0], D[6]
++// if (Chip_ID == 0x141) {
++// PHY_Status = phy_read_register (dev, 0x18, 0);
++// phy_write_register (dev, 0x18, 0, ((PHY_Status & ~(0x41)) | 0x01));
++// }
++ }
++ else if (Chip_ID == PHYID_BCM54612E ) {
++ phy_write_register ( dev, 0x1C, 1, 0x8C00 ); // Disable GTXCLK Clock Delay Enable
++ phy_write_register ( dev, 0x18, 1, 0xF0E7 ); // Disable RGMII RXD to RXC Skew
++
++ Advertise = phy_read_register (dev, 0x04, 1);
++ Link_Partner = phy_read_register (dev, 0x05, 1);
++ Advertise = (Advertise & PHY_SPEED_DUPLEX_MASK);
++ Link_Partner = (Link_Partner & PHY_SPEED_DUPLEX_MASK);
++ if ((Advertise & Link_Partner) & PHY_100M_DUPLEX) {
++ MAC_CR_Register |= SPEED_100M_MODE_bit;
++ MAC_CR_Register |= FULLDUP_bit;
++ }
++ else if ((Advertise & Link_Partner) & PHY_100M_HALF) {
++ MAC_CR_Register |= SPEED_100M_MODE_bit;
++ MAC_CR_Register &= ~FULLDUP_bit;
++ }
++ else if ((Advertise & Link_Partner) & PHY_10M_DUPLEX) {
++ MAC_CR_Register &= ~SPEED_100M_MODE_bit;
++ MAC_CR_Register |= FULLDUP_bit;
++ }
++ else if ((Advertise & Link_Partner) & PHY_10M_HALF) {
++ MAC_CR_Register &= ~SPEED_100M_MODE_bit;
++ MAC_CR_Register &= ~FULLDUP_bit;
++ }
++ }else {
++ printf("Unknow Chip_ID %x\n",Chip_ID);
++ }
++ }
++ OUTL(dev, MAC_CR_Register, MACCR_REG);
++}
++
++#endif /* CFG_CMD_NET && CONFIG_NET_MULTI && CONFIG_ASPEEDMAC */
+diff --git a/include/configs/ast1100.h b/include/configs/ast1100.h
+new file mode 100755
+index 0000000..dbd656e
+--- /dev/null
++++ b/include/configs/ast1100.h
+@@ -0,0 +1,257 @@
++/*
++ * (C) Copyright 2004
++ * Peter Chen <peterc@socle-tech.com.tw>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++/*
++ * Version Identity
++ */
++#define CONFIG_IDENT_STRING " ASPEED (v.0.12) "
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++//#define CONFIG_INIT_CRITICAL /* define for U-BOOT 1.1.1 */
++#undef CONFIG_INIT_CRITICAL /* undef for U-BOOT 1.1.4 */
++#define CONFIG_ARM926EJS 1 /* This is an arm926ejs CPU */
++#define CONFIG_ASPEED 1
++#define CONFIG_AST1100 1
++//#define CONFIG_AST1100_FPGA
++#undef CONFIG_AST1100_FPGA /* undef if real chip */
++//#define CONFIG_AST1100A2_PATCH
++#undef CONFIG_AST1100A2_PATCH
++//#define CONFIG_2SPIFLASH /* Boot SPI: CS2, 2nd SPI: CS0 */ /* Not ready */
++#undef CONFIG_2SPIFLASH
++#undef CONFIG_DDR512_200
++#define CONFIG_DDRII1G_200 1
++#undef CONFIG_ASPEED_SLT
++
++//#define CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
++#define CONFIG_MISC_INIT_R
++
++/*
++ * Environment Config
++ */
++#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
++#define CONFIG_SETUP_MEMORY_TAGS 1
++#define CONFIG_INITRD_TAG 1
++#define CONFIG_BOOTARGS "debug console=ttyS1,115200n8 ramdisk_size=16384 root=/dev/ram rw init=/linuxrc mem=80M"
++#ifdef CONFIG_ASPEED_SLT
++#define CONFIG_BOOTDELAY 1 /* autoboot after 3 seconds */
++#else
++#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
++#endif
++#define CONFIG_BOOTCOMMAND "bootm 14080000 14300000"
++#define CONFIG_BOOTFILE "all.bin"
++#define CONFIG_ENV_OVERWRITE
++
++/*
++ * Command line configuration.
++ */
++#include <config_cmd_default.h>
++
++#define CONFIG_CMD_DFL
++#define CONFIG_CMD_ENV
++#define CONFIG_CMD_FLASH
++#define CONFIG_CMD_NET
++#define CONFIG_CMD_PING
++#define CONFIG_CMD_I2C
++#define CONFIG_CMD_EEPROM
++
++/*
++ * CPU Setting
++ */
++#define CPU_CLOCK_RATE 18000000 /* 16.5 MHz clock for the ARM core */
++
++/*
++ * Size of malloc() pool
++ */
++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 128*1024)
++#define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
++
++/*
++ * Stack sizes, The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE (128*1024) /* regular stack */
++#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
++
++/*
++ * Memory Configuration
++ */
++#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
++#define PHYS_SDRAM_1 0x40000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE 0x4000000 /* 64 MB */
++
++#define CONFIG_SYS_SDRAM_BASE 0x40000000
++
++/*
++ * FLASH Configuration
++ */
++#define PHYS_FLASH_1 0x14000000 /* Flash Bank #1 */
++#define PHYS_FLASH_2 0x14800000 /* Flash Bank #2 */
++#define PHYS_FLASH_2_BASE 0x10000000
++
++#ifdef CONFIG_2SPIFLASH
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_2_BASE
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1, PHYS_FLASH_2 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 2
++#define CONFIG_SYS_MAX_FLASH_SECT (256) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#else
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (256) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#endif
++
++#define __LITTLE_ENDIAN
++#define CONFIG_FLASH_SPI
++
++#define CONFIG_MONITOR_BASE TEXT_BASE
++#define CONFIG_MONITOR_LEN (192 << 10)
++
++/* timeout values are in ticks */
++#define CONFIG_SYS_FLASH_ERASE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Erase */
++#define CONFIG_SYS_FLASH_WRITE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Write */
++
++/*
++ * Miscellaneous configurable options
++ */
++#define CONFIG_SYS_LONGHELP /* undef to save memory */
++
++#define CONFIG_SYS_PROMPT "boot# " /* Monitor Command Prompt */
++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */
++#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
++
++#define CONFIG_SYS_MEMTEST_START 0x40000000 /* memtest works on */
++#define CONFIG_SYS_MEMTEST_END 0x44FFFFFF /* 256 MB in DRAM */
++
++#define CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++#undef CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++
++#define CONFIG_SYS_LOAD_ADDR 0x43000000 /* default load address */
++
++#define CONFIG_SYS_TIMERBASE 0x1E782000 /* use timer 1 */
++#define CONFIG_SYS_HZ (1*1000*1000) /* use external clk (1M) */
++
++/*
++ * Serial Configuration
++ */
++#define CONFIG_SYS_NS16550
++#define CONFIG_SYS_NS16550_SERIAL
++#define CONFIG_SYS_NS16550_REG_SIZE 4
++#define CONFIG_SYS_NS16550_CLK 24000000
++#define CONFIG_SYS_NS16550_COM1 0x1e783000
++#define CONFIG_SYS_NS16550_COM2 0x1e784000
++#define CONFIG_SYS_LOADS_BAUD_CHANGE
++#define CONFIG_SERIAL1 1
++#define CONFIG_CONS_INDEX 2
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++
++/*
++ * USB device configuration
++ */
++/*
++#define CONFIG_USB_DEVICE 1
++#define CONFIG_USB_TTY 1
++
++#define CONFIG_USBD_VENDORID 0x1234
++#define CONFIG_USBD_PRODUCTID 0x5678
++#define CONFIG_USBD_MANUFACTURER "Siemens"
++#define CONFIG_USBD_PRODUCT_NAME "SX1"
++*/
++
++/*
++ * I2C configuration
++ */
++#define CONFIG_HARD_I2C
++#define CONFIG_SYS_I2C_SPEED 100000
++#define CONFIG_SYS_I2C_SLAVE 1
++#define CONFIG_DRIVER_ASPEED_I2C
++
++/*
++* EEPROM configuration
++*/
++#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
++#define CONFIG_SYS_I2C_EEPROM_ADDR 0xa0
++
++/*
++ * NIC configuration
++ */
++#define __BYTE_ORDER __LITTLE_ENDIAN
++#define __LITTLE_ENDIAN_BITFIELD
++#define CONFIG_MAC_PARTITION
++#define CONFIG_ASPEEDNIC
++//#define CONFIG_MAC1_PHY_LINK_INTERRUPT
++//#define CONFIG_MAC2_ENABLE
++//#define CONFIG_MAC2_MII_ENABLE
++//#define CONFIG_MAC2_PHY_LINK_INTERRUPT
++
++/*
++*-------------------------------------------------------------------------------
++* NOTICE: MAC1 and MAC2 now have their own seperate PHY configuration.
++* We use 2 bits for each MAC in the scratch register(D[15:11] in 0x1E6E2040) to
++* inform kernel driver.
++* The meanings of the 2 bits are:
++* 00(0): Dedicated PHY
++* 01(1): ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 10(2): ASPEED's MAC is connected to NC-SI PHY chip directly
++* 11: Reserved
++*
++* We use CONFIG_MAC1_PHY_SETTING and CONFIG_MAC2_PHY_SETTING in U-Boot
++* 0: Dedicated PHY
++* 1: ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 2: ASPEED's MAC is connected to NC-SI PHY chip directly
++* 3: Reserved
++*-------------------------------------------------------------------------------
++*/
++#define CONFIG_MAC1_PHY_SETTING 0
++#define CONFIG_MAC2_PHY_SETTING 0
++#define CONFIG_NET_MULTI
++#define CONFIG_ETHACT aspeednic#0
++#define CONFIG_GATEWAYIP 192.168.0.1
++#define CONFIG_NETMASK 255.255.255.0
++#define CONFIG_IPADDR 192.168.0.188
++#define CONFIG_SERVERIP 192.168.0.126
++#define CONFIG_ETHADDR 00:C0:A8:12:34:56
++#define CONFIG_ETH1ADDR 00:C0:A8:12:34:57
++
++/*
++ * SLT
++ */
++/*
++#define CONFIG_SLT
++#define CFG_CMD_SLT (CFG_CMD_REGTEST | CFG_CMD_MACTEST | CFG_CMD_VIDEOTEST | CFG_CMD_HACTEST | CFG_CMD_MICTEST)
++*/
++
++#endif /* __CONFIG_H */
+diff --git a/include/configs/ast2100.h b/include/configs/ast2100.h
+new file mode 100644
+index 0000000..07733b9
+--- /dev/null
++++ b/include/configs/ast2100.h
+@@ -0,0 +1,272 @@
++/*
++ * (C) Copyright 2004
++ * Peter Chen <peterc@socle-tech.com.tw>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++//#define CONFIG_INIT_CRITICAL /* define for U-BOOT 1.1.1 */
++#undef CONFIG_INIT_CRITICAL /* undef for U-BOOT 1.1.4 */
++#define CONFIG_ARM926EJS 1 /* This is an arm926ejs CPU */
++#define CONFIG_ASPEED 1
++#define CONFIG_AST2100 1
++//#define CONFIG_AST2100_FPGA
++#undef CONFIG_AST2100_FPGA /* undef if real chip */
++//#define CONFIG_AST2100A2_PATCH
++#undef CONFIG_AST2100A2_PATCH
++#define CONFIG_SYS_FLASH_CFI /* CONFIG_FLASH_CFI, CONFIG_FLASH_SPI is exclusive*/
++//#define CONFIG_FLASH_SPI
++//#define CONFIG_2SPIFLASH /* Boot SPI: CS2, 2nd SPI: CS0 */
++#undef CONFIG_DDRII1G_266
++#undef CONFIG_2SPIFLASH
++#undef CONFIG_ASPEED_SLT
++
++//#define CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
++#define CONFIG_MISC_INIT_R
++
++/*
++ * Environment Config
++ */
++#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
++#define CONFIG_SETUP_MEMORY_TAGS 1
++#define CONFIG_INITRD_TAG 1
++#define CONFIG_BOOTARGS "debug console=ttyS1,115200n8 ramdisk_size=16384 root=/dev/ram rw init=/linuxrc mem=80M"
++#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
++#ifdef CONFIG_SYS_FLASH_CFI
++#define CONFIG_BOOTCOMMAND "bootm 10080000 10300000"
++#else
++#define CONFIG_BOOTCOMMAND "bootm 14080000 14300000"
++#endif
++#define CONFIG_BOOTFILE "all.bin"
++#define CONFIG_ENV_OVERWRITE
++
++/*
++ * Command line configuration.
++ */
++#include <config_cmd_default.h>
++
++#define CONFIG_CMD_DFL
++#define CONFIG_CMD_ENV
++#define CONFIG_CMD_FLASH
++#define CONFIG_CMD_NET
++#define CONFIG_CMD_PING
++#define CONFIG_CMD_I2C
++#define CONFIG_CMD_EEPROM
++
++/*
++ * CPU Setting
++ */
++#define CPU_CLOCK_RATE 18000000 /* 16.5 MHz clock for the ARM core */
++
++/*
++ * Size of malloc() pool
++ */
++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 128*1024)
++#define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
++
++/*
++ * Stack sizes, The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE (128*1024) /* regular stack */
++#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
++
++/*
++ * Memory Configuration
++ */
++#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
++#define PHYS_SDRAM_1 0x40000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE 0x4000000 /* 64 MB */
++
++#define CONFIG_SYS_SDRAM_BASE 0x40000000
++
++/*
++ * FLASH Configuration
++ */
++#ifdef CONFIG_SYS_FLASH_CFI /* NOR Flash */
++
++#define PHYS_FLASH_1 0x10000000 /* Flash Bank #1 */
++
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (256) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x60000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
++
++#define CONFIG_SYS_FLASH_CFI_AMD_RESET
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++
++#else /* SPI Flash */
++
++#define PHYS_FLASH_1 0x14000000 /* Flash Bank #1 */
++#define PHYS_FLASH_2 0x14800000 /* Flash Bank #2 */
++#define PHYS_FLASH_2_BASE 0x10000000
++
++#ifdef CONFIG_2SPIFLASH
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_2_BASE
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1, PHYS_FLASH_2 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 2
++#define CONFIG_SYS_MAX_FLASH_SECT (256) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#else
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (256) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#endif
++
++#endif
++
++#define __LITTLE_ENDIAN
++
++#define CONFIG_MONITOR_BASE TEXT_BASE
++#define CONFIG_MONITOR_LEN (192 << 10)
++
++/* timeout values are in ticks */
++#define CONFIG_SYS_FLASH_ERASE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Erase */
++#define CONFIG_SYS_FLASH_WRITE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Write */
++
++/*
++ * Miscellaneous configurable options
++ */
++#define CONFIG_SYS_LONGHELP /* undef to save memory */
++
++#define CONFIG_SYS_PROMPT "boot# " /* Monitor Command Prompt */
++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */
++#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
++
++#define CONFIG_SYS_MEMTEST_START 0x40000000 /* memtest works on */
++#define CONFIG_SYS_MEMTEST_END 0x44FFFFFF /* 256 MB in DRAM */
++
++#define CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++#undef CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++
++#define CONFIG_SYS_LOAD_ADDR 0x43000000 /* default load address */
++
++#define CONFIG_SYS_TIMERBASE 0x1E782000 /* use timer 1 */
++#define CONFIG_SYS_HZ (1*1000*1000) /* use external clk (1M) */
++
++/*
++ * Serial Configuration
++ */
++#define CONFIG_SYS_NS16550
++#define CONFIG_SYS_NS16550_SERIAL
++#define CONFIG_SYS_NS16550_REG_SIZE 4
++#define CONFIG_SYS_NS16550_CLK 24000000
++#define CONFIG_SYS_NS16550_COM1 0x1e783000
++#define CONFIG_SYS_NS16550_COM2 0x1e784000
++#define CONFIG_SYS_LOADS_BAUD_CHANGE
++#define CONFIG_SERIAL1 1
++#define CONFIG_CONS_INDEX 2
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++
++/*
++ * USB device configuration
++ */
++/*
++#define CONFIG_USB_DEVICE 1
++#define CONFIG_USB_TTY 1
++
++#define CONFIG_USBD_VENDORID 0x1234
++#define CONFIG_USBD_PRODUCTID 0x5678
++#define CONFIG_USBD_MANUFACTURER "Siemens"
++#define CONFIG_USBD_PRODUCT_NAME "SX1"
++*/
++
++/*
++ * I2C configuration
++ */
++#define CONFIG_HARD_I2C
++#define CONFIG_SYS_I2C_SPEED 100000
++#define CONFIG_SYS_I2C_SLAVE 1
++#define CONFIG_DRIVER_ASPEED_I2C
++
++/*
++* EEPROM configuration
++*/
++#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
++#define CONFIG_SYS_I2C_EEPROM_ADDR 0xa0
++
++/*
++ * NIC configuration
++ */
++#define __BYTE_ORDER __LITTLE_ENDIAN
++#define __LITTLE_ENDIAN_BITFIELD
++#define CONFIG_MAC_PARTITION
++#define CONFIG_ASPEEDNIC
++#define CONFIG_MAC1_PHY_LINK_INTERRUPT
++#define CONFIG_MAC2_ENABLE
++#define CONFIG_MAC2_MII_ENABLE
++//#define CONFIG_MAC2_PHY_LINK_INTERRUPT
++/*
++*-------------------------------------------------------------------------------
++* NOTICE: MAC1 and MAC2 now have their own seperate PHY configuration.
++* We use 2 bits for each MAC in the scratch register(D[15:11] in 0x1E6E2040) to
++* inform kernel driver.
++* The meanings of the 2 bits are:
++* 00(0): Dedicated PHY
++* 01(1): ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 10(2): ASPEED's MAC is connected to NC-SI PHY chip directly
++* 11: Reserved
++*
++* We use CONFIG_MAC1_PHY_SETTING and CONFIG_MAC2_PHY_SETTING in U-Boot
++* 0: Dedicated PHY
++* 1: ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 2: ASPEED's MAC is connected to NC-SI PHY chip directly
++* 3: Reserved
++*-------------------------------------------------------------------------------
++*/
++#define CONFIG_MAC1_PHY_SETTING 0
++#define CONFIG_MAC2_PHY_SETTING 0
++#define CONFIG_NET_MULTI
++#define CONFIG_ETHACT aspeednic#0
++#define CONFIG_GATEWAYIP 192.168.0.1
++#define CONFIG_NETMASK 255.255.255.0
++#define CONFIG_IPADDR 192.168.0.188
++#define CONFIG_SERVERIP 192.168.0.106
++#define CONFIG_ETHADDR 00:C0:A8:12:34:56
++#define CONFIG_ETH1ADDR 00:C0:A8:12:34:57
++
++/*
++ * SLT
++ */
++/*
++#define CONFIG_SLT
++#define CONFIG_CMD_SLT (CONFIG_CMD_REGTEST | CONFIG_CMD_MACTEST | CONFIG_CMD_VIDEOTEST | CONFIG_CMD_HACTEST | CONFIG_CMD_MICTEST)
++*/
++
++#endif /* __CONFIG_H */
+diff --git a/include/configs/ast2300.h b/include/configs/ast2300.h
+new file mode 100644
+index 0000000..678e7c3
+--- /dev/null
++++ b/include/configs/ast2300.h
+@@ -0,0 +1,325 @@
++/*
++ * (C) Copyright 2004
++ * Peter Chen <peterc@socle-tech.com.tw>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++//#define CONFIG_INIT_CRITICAL /* define for U-BOOT 1.1.1 */
++#undef CONFIG_INIT_CRITICAL /* undef for U-BOOT 1.1.4 */
++#define CONFIG_ARM926EJS 1 /* This is an arm926ejs CPU */
++#define CONFIG_ASPEED 1
++#define CONFIG_AST2300 1
++//#define CONFIG_AST1070 1
++//#define CONFIG_SYS_FLASH_CFI /* CONFIG_FLASH_CFI, CONFIG_FLASH_SPI is exclusive*/
++#define CONFIG_FLASH_SPI
++//#define CONFIG_2SPIFLASH /* Boot SPI: CS2, 2nd SPI: CS0 */
++#undef CONFIG_2SPIFLASH
++#undef CONFIG_ASPEED_SLT
++#define CONFIG_FLASH_AST2300
++#define CONFIG_FLASH_AST2300_DMA
++//#define CONFIG_FLASH_SPIx2_Dummy
++//#define CONFIG_FLASH_SPIx4_Dummy
++#define CONFIG_CRT_DISPLAY 1 /* undef if not support CRT */
++
++//#define CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
++#define CONFIG_MISC_INIT_R
++
++/*
++ * DRAM Config
++ *
++ * 1. DRAM Size //
++ * CONFIG_DRAM_512MBIT // 512M bit
++ * CONFIG_DRAM_1GBIT // 1G bit (default)
++ * CONFIG_DRAM_2GBIT // 2G bit
++ * CONFIG_DRAM_4GBIT // 4G bit
++ * 2. DRAM Speed //
++ * CONFIG_DRAM_336 // 336MHz (DDR-667)
++ * CONFIG_DRAM_408 // 408MHz (DDR-800) (default)
++ * 3. VGA Mode
++ * CONFIG_CRT_DISPLAY // define to disable VGA function
++ * 4. ECC Function enable
++ * CONFIG_DRAM_ECC // define to enable ECC function
++ * 5. UART Debug Message
++ * CONFIG_DRAM_UART_OUT // enable output message at UART5
++ * CONFIG_DRAM_UART_38400 // set the UART baud rate to 38400, default is 115200
++ */
++
++//1. DRAM Size
++//#define CONFIG_DRAM_512MBIT
++#define CONFIG_DRAM_1GBIT
++//#define CONFIG_DRAM_2GBIT
++//#define CONFIG_DRAM_4GBIT
++//2. DRAM Speed
++//#define CONFIG_DRAM_336
++#define CONFIG_DRAM_408
++//3. VGA Mode
++//#define CONFIG_CRT_DISPLAY
++//4. ECC Function enable
++//#define CONFIG_DRAM_ECC
++//5. UART Debug Message
++#define CONFIG_DRAM_UART_OUT
++//#define CONFIG_DRAM_UART_38400
++
++
++
++/*
++ * Environment Config
++ */
++#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
++#define CONFIG_SETUP_MEMORY_TAGS 1
++#define CONFIG_INITRD_TAG 1
++#define CONFIG_BOOTARGS "debug console=ttyS0,115200n8 ramdisk_size=16384 root=/dev/ram rw init=/linuxrc mem=80M"
++#define CONFIG_UPDATE "tftp 40800000 ast2300.scr; so 40800000'"
++
++#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
++#ifdef CONFIG_FLASH_AST2300
++#define CONFIG_BOOTCOMMAND "bootm 20080000 20300000"
++#else
++#ifdef CONFIG_SYS_FLASH_CFI
++#define CONFIG_BOOTCOMMAND "bootm 10080000 10300000"
++#else
++#define CONFIG_BOOTCOMMAND "bootm 14080000 14300000"
++#endif
++#endif
++#define CONFIG_BOOTFILE "all.bin"
++#define CONFIG_ENV_OVERWRITE
++
++/*
++ * Command line configuration.
++ */
++#include <config_cmd_default.h>
++
++#define CONFIG_CMD_DFL
++#define CONFIG_CMD_ENV
++#define CONFIG_CMD_FLASH
++#define CONFIG_CMD_NET
++#define CONFIG_CMD_PING
++#define CONFIG_CMD_I2C
++#define CONFIG_CMD_EEPROM
++
++/*
++ * CPU Setting
++ */
++#define CPU_CLOCK_RATE 18000000 /* 16.5 MHz clock for the ARM core */
++
++/*
++ * Size of malloc() pool
++ */
++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 768*1024)
++#define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
++
++/*
++ * Stack sizes, The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE (128*1024) /* regular stack */
++#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
++
++/*
++ * Memory Configuration
++ */
++#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
++#define PHYS_SDRAM_1 0x40000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE 0x4000000 /* 64 MB */
++
++#define CONFIG_SYS_SDRAM_BASE 0x40000000
++
++/*
++ * FLASH Configuration
++ */
++#ifdef CONFIG_SYS_FLASH_CFI /* NOR Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x10000000 /* Flash Bank #1 */
++#endif
++
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (256) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x60000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
++
++#define CONFIG_SYS_FLASH_CFI_AMD_RESET
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++
++#else /* SPI Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x14000000 /* Flash Bank #1 */
++#define PHYS_FLASH_2 0x14800000 /* Flash Bank #2 */
++#define PHYS_FLASH_2_BASE 0x10000000
++#endif
++
++#ifdef CONFIG_2SPIFLASH
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_2_BASE
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1, PHYS_FLASH_2 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 2
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#else
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#endif
++
++#endif
++
++#define __LITTLE_ENDIAN
++
++#define CONFIG_MONITOR_BASE TEXT_BASE
++#define CONFIG_MONITOR_LEN (192 << 10)
++
++/* timeout values are in ticks */
++#define CONFIG_SYS_FLASH_ERASE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Erase */
++#define CONFIG_SYS_FLASH_WRITE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Write */
++
++/*
++ * Miscellaneous configurable options
++ */
++#define CONFIG_SYS_LONGHELP /* undef to save memory */
++
++#define CONFIG_SYS_PROMPT "boot# " /* Monitor Command Prompt */
++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */
++#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
++
++#define CONFIG_SYS_MEMTEST_START 0x40000000 /* memtest works on */
++#define CONFIG_SYS_MEMTEST_END 0x44FFFFFF /* 256 MB in DRAM */
++
++#define CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++#undef CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++
++#define CONFIG_SYS_LOAD_ADDR 0x43000000 /* default load address */
++
++#define CONFIG_SYS_TIMERBASE 0x1E782000 /* use timer 1 */
++#define CONFIG_SYS_HZ (1*1000*1000) /* use external clk (1M) */
++
++/*
++ * Serial Configuration
++ */
++#define CONFIG_SYS_NS16550
++#define CONFIG_SYS_NS16550_SERIAL
++#define CONFIG_SYS_NS16550_REG_SIZE 4
++#define CONFIG_SYS_NS16550_CLK 24000000
++#define CONFIG_SYS_NS16550_COM1 0x1e783000
++#define CONFIG_SYS_NS16550_COM2 0x1e784000
++#define CONFIG_SYS_LOADS_BAUD_CHANGE
++#define CONFIG_SERIAL1 1
++#define CONFIG_CONS_INDEX 2
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++
++/*
++ * USB device configuration
++ */
++/*
++#define CONFIG_USB_DEVICE 1
++#define CONFIG_USB_TTY 1
++
++#define CONFIG_USBD_VENDORID 0x1234
++#define CONFIG_USBD_PRODUCTID 0x5678
++#define CONFIG_USBD_MANUFACTURER "Siemens"
++#define CONFIG_USBD_PRODUCT_NAME "SX1"
++*/
++
++/*
++ * I2C configuration
++ */
++#define CONFIG_HARD_I2C
++#define CONFIG_SYS_I2C_SPEED 100000
++#define CONFIG_SYS_I2C_SLAVE 1
++#define CONFIG_DRIVER_ASPEED_I2C
++
++/*
++* EEPROM configuration
++*/
++#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
++#define CONFIG_SYS_I2C_EEPROM_ADDR 0xa0
++
++/*
++ * NIC configuration
++ */
++#define __BYTE_ORDER __LITTLE_ENDIAN
++#define __LITTLE_ENDIAN_BITFIELD
++#define CONFIG_MAC_PARTITION
++#define CONFIG_ASPEEDNIC
++//#define CONFIG_MAC1_PHY_LINK_INTERRUPT
++#define CONFIG_MAC2_ENABLE
++#define CONFIG_MAC2_PHY_LINK_INTERRUPT
++/*
++*-------------------------------------------------------------------------------
++* NOTICE: MAC1 and MAC2 now have their own seperate PHY configuration.
++* We use 2 bits for each MAC in the scratch register(D[15:11] in 0x1E6E2040) to
++* inform kernel driver.
++* The meanings of the 2 bits are:
++* 00(0): Dedicated PHY
++* 01(1): ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 10(2): ASPEED's MAC is connected to NC-SI PHY chip directly
++* 11: Reserved
++*
++* We use CONFIG_MAC1_PHY_SETTING and CONFIG_MAC2_PHY_SETTING in U-Boot
++* 0: Dedicated PHY
++* 1: ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 2: ASPEED's MAC is connected to NC-SI PHY chip directly
++* 3: Reserved
++*-------------------------------------------------------------------------------
++*/
++#define CONFIG_MAC1_PHY_SETTING 0
++#define CONFIG_MAC2_PHY_SETTING 0
++#define CONFIG_MAC_INTERFACE_CLOCK_DELAY 0x2255
++#define CONFIG_NET_MULTI
++#define CONFIG_ETHACT aspeednic#0
++#define CONFIG_GATEWAYIP 192.168.0.1
++#define CONFIG_NETMASK 255.255.255.0
++#define CONFIG_IPADDR 192.168.0.45
++#define CONFIG_SERVERIP 192.168.0.81
++#define CONFIG_ETHADDR 00:C0:A8:12:34:56
++#define CONFIG_ETH1ADDR 00:C0:A8:12:34:57
++
++/*
++ * SLT
++ */
++/*
++#define CONFIG_SLT
++#define CFG_CMD_SLT (CFG_CMD_VIDEOTEST | CFG_CMD_MACTEST | CFG_CMD_HACTEST | CFG_CMD_MICTEST)
++*/
++
++#endif /* __CONFIG_H */
+diff --git a/include/configs/ast2300_ast1070.h b/include/configs/ast2300_ast1070.h
+new file mode 100644
+index 0000000..a7abdf5
+--- /dev/null
++++ b/include/configs/ast2300_ast1070.h
+@@ -0,0 +1,323 @@
++/*
++ * (C) Copyright 2004
++ * Peter Chen <peterc@socle-tech.com.tw>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++//#define CONFIG_INIT_CRITICAL /* define for U-BOOT 1.1.1 */
++#undef CONFIG_INIT_CRITICAL /* undef for U-BOOT 1.1.4 */
++#define CONFIG_ARM926EJS 1 /* This is an arm926ejs CPU */
++#define CONFIG_ASPEED 1
++#define CONFIG_AST2300 1
++#define CONFIG_AST1070 1
++//#define CONFIG_SYS_FLASH_CFI /* CONFIG_FLASH_CFI, CONFIG_FLASH_SPI is exclusive*/
++#define CONFIG_FLASH_SPI
++//#define CONFIG_2SPIFLASH /* Boot SPI: CS2, 2nd SPI: CS0 */
++#undef CONFIG_2SPIFLASH
++#undef CONFIG_ASPEED_SLT
++#define CONFIG_FLASH_AST2300
++#define CONFIG_FLASH_AST2300_DMA
++//#define CONFIG_FLASH_SPIx2_Dummy
++//#define CONFIG_FLASH_SPIx4_Dummy
++#define CONFIG_CRT_DISPLAY 1 /* undef if not support CRT */
++
++//#define CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
++#define CONFIG_MISC_INIT_R
++
++/*
++ * DRAM Config
++ *
++ * 1. DRAM Size //
++ * CONFIG_DRAM_512MBIT // 512M bit
++ * CONFIG_DRAM_1GBIT // 1G bit (default)
++ * CONFIG_DRAM_2GBIT // 2G bit
++ * CONFIG_DRAM_4GBIT // 4G bit
++ * 2. DRAM Speed //
++ * CONFIG_DRAM_336 // 336MHz (DDR-667)
++ * CONFIG_DRAM_408 // 408MHz (DDR-800) (default)
++ * 3. VGA Mode
++ * CONFIG_CRT_DISPLAY // define to disable VGA function
++ * 4. ECC Function enable
++ * CONFIG_DRAM_ECC // define to enable ECC function
++ * 5. UART Debug Message
++ * CONFIG_DRAM_UART_OUT // enable output message at UART5
++ * CONFIG_DRAM_UART_38400 // set the UART baud rate to 38400, default is 115200
++ */
++
++//1. DRAM Size
++//#define CONFIG_DRAM_512MBIT
++#define CONFIG_DRAM_1GBIT
++//#define CONFIG_DRAM_2GBIT
++//#define CONFIG_DRAM_4GBIT
++//2. DRAM Speed
++//#define CONFIG_DRAM_336
++#define CONFIG_DRAM_408
++//3. VGA Mode
++//#define CONFIG_CRT_DISPLAY
++//4. ECC Function enable
++//#define CONFIG_DRAM_ECC
++//5. UART Debug Message
++#define CONFIG_DRAM_UART_OUT
++//#define CONFIG_DRAM_UART_38400
++
++
++
++/*
++ * Environment Config
++ */
++#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
++#define CONFIG_SETUP_MEMORY_TAGS 1
++#define CONFIG_INITRD_TAG 1
++#define CONFIG_BOOTARGS "debug console=ttyS0,115200n8 ramdisk_size=16384 root=/dev/ram rw init=/linuxrc mem=80M"
++#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
++#ifdef CONFIG_FLASH_AST2300
++#define CONFIG_BOOTCOMMAND "bootm 20080000 20300000"
++#else
++#ifdef CONFIG_SYS_FLASH_CFI
++#define CONFIG_BOOTCOMMAND "bootm 10080000 10300000"
++#else
++#define CONFIG_BOOTCOMMAND "bootm 14080000 14300000"
++#endif
++#endif
++#define CONFIG_BOOTFILE "all.bin"
++#define CONFIG_ENV_OVERWRITE
++
++/*
++ * Command line configuration.
++ */
++#include <config_cmd_default.h>
++
++#define CONFIG_CMD_DFL
++#define CONFIG_CMD_ENV
++#define CONFIG_CMD_FLASH
++#define CONFIG_CMD_NET
++#define CONFIG_CMD_PING
++#define CONFIG_CMD_I2C
++#define CONFIG_CMD_EEPROM
++
++/*
++ * CPU Setting
++ */
++#define CPU_CLOCK_RATE 18000000 /* 16.5 MHz clock for the ARM core */
++
++/*
++ * Size of malloc() pool
++ */
++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 768*1024)
++#define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
++
++/*
++ * Stack sizes, The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE (128*1024) /* regular stack */
++#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
++
++/*
++ * Memory Configuration
++ */
++#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
++#define PHYS_SDRAM_1 0x40000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE 0x4000000 /* 64 MB */
++
++#define CONFIG_SYS_SDRAM_BASE 0x40000000
++
++/*
++ * FLASH Configuration
++ */
++#ifdef CONFIG_SYS_FLASH_CFI /* NOR Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x10000000 /* Flash Bank #1 */
++#endif
++
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (256) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x60000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
++
++#define CONFIG_SYS_FLASH_CFI_AMD_RESET
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++
++#else /* SPI Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x14000000 /* Flash Bank #1 */
++#define PHYS_FLASH_2 0x14800000 /* Flash Bank #2 */
++#define PHYS_FLASH_2_BASE 0x10000000
++#endif
++
++#ifdef CONFIG_2SPIFLASH
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_2_BASE
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1, PHYS_FLASH_2 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 2
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#else
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#endif
++
++#endif
++
++#define __LITTLE_ENDIAN
++
++#define CONFIG_MONITOR_BASE TEXT_BASE
++#define CONFIG_MONITOR_LEN (192 << 10)
++
++/* timeout values are in ticks */
++#define CONFIG_SYS_FLASH_ERASE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Erase */
++#define CONFIG_SYS_FLASH_WRITE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Write */
++
++/*
++ * Miscellaneous configurable options
++ */
++#define CONFIG_SYS_LONGHELP /* undef to save memory */
++
++#define CONFIG_SYS_PROMPT "boot# " /* Monitor Command Prompt */
++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */
++#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
++
++#define CONFIG_SYS_MEMTEST_START 0x40000000 /* memtest works on */
++#define CONFIG_SYS_MEMTEST_END 0x44FFFFFF /* 256 MB in DRAM */
++
++#define CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++#undef CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++
++#define CONFIG_SYS_LOAD_ADDR 0x43000000 /* default load address */
++
++#define CONFIG_SYS_TIMERBASE 0x1E782000 /* use timer 1 */
++#define CONFIG_SYS_HZ (1*1000*1000) /* use external clk (1M) */
++
++/*
++ * Serial Configuration
++ */
++#define CONFIG_SYS_NS16550
++#define CONFIG_SYS_NS16550_SERIAL
++#define CONFIG_SYS_NS16550_REG_SIZE 4
++#define CONFIG_SYS_NS16550_CLK 24000000
++#define CONFIG_SYS_NS16550_COM1 0x1e783000
++#define CONFIG_SYS_NS16550_COM2 0x1e784000
++#define CONFIG_SYS_LOADS_BAUD_CHANGE
++#define CONFIG_SERIAL1 1
++#define CONFIG_CONS_INDEX 2
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++
++/*
++ * USB device configuration
++ */
++/*
++#define CONFIG_USB_DEVICE 1
++#define CONFIG_USB_TTY 1
++
++#define CONFIG_USBD_VENDORID 0x1234
++#define CONFIG_USBD_PRODUCTID 0x5678
++#define CONFIG_USBD_MANUFACTURER "Siemens"
++#define CONFIG_USBD_PRODUCT_NAME "SX1"
++*/
++
++/*
++ * I2C configuration
++ */
++#define CONFIG_HARD_I2C
++#define CONFIG_SYS_I2C_SPEED 100000
++#define CONFIG_SYS_I2C_SLAVE 1
++#define CONFIG_DRIVER_ASPEED_I2C
++
++/*
++* EEPROM configuration
++*/
++#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
++#define CONFIG_SYS_I2C_EEPROM_ADDR 0xa0
++
++/*
++ * NIC configuration
++ */
++#define __BYTE_ORDER __LITTLE_ENDIAN
++#define __LITTLE_ENDIAN_BITFIELD
++#define CONFIG_MAC_PARTITION
++#define CONFIG_ASPEEDNIC
++//#define CONFIG_MAC1_PHY_LINK_INTERRUPT
++#define CONFIG_MAC2_ENABLE
++#define CONFIG_MAC2_PHY_LINK_INTERRUPT
++/*
++*-------------------------------------------------------------------------------
++* NOTICE: MAC1 and MAC2 now have their own seperate PHY configuration.
++* We use 2 bits for each MAC in the scratch register(D[15:11] in 0x1E6E2040) to
++* inform kernel driver.
++* The meanings of the 2 bits are:
++* 00(0): Dedicated PHY
++* 01(1): ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 10(2): ASPEED's MAC is connected to NC-SI PHY chip directly
++* 11: Reserved
++*
++* We use CONFIG_MAC1_PHY_SETTING and CONFIG_MAC2_PHY_SETTING in U-Boot
++* 0: Dedicated PHY
++* 1: ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 2: ASPEED's MAC is connected to NC-SI PHY chip directly
++* 3: Reserved
++*-------------------------------------------------------------------------------
++*/
++#define CONFIG_MAC1_PHY_SETTING 0
++#define CONFIG_MAC2_PHY_SETTING 0
++#define CONFIG_MAC_INTERFACE_CLOCK_DELAY 0x2255
++#define CONFIG_NET_MULTI
++#define CONFIG_ETHACT aspeednic#0
++#define CONFIG_GATEWAYIP 192.168.0.1
++#define CONFIG_NETMASK 255.255.255.0
++#define CONFIG_IPADDR 192.168.0.45
++#define CONFIG_SERVERIP 192.168.0.81
++#define CONFIG_ETHADDR 00:C0:A8:12:34:56
++#define CONFIG_ETH1ADDR 00:C0:A8:12:34:57
++
++/*
++ * SLT
++ */
++/*
++#define CONFIG_SLT
++#define CFG_CMD_SLT (CFG_CMD_VIDEOTEST | CFG_CMD_MACTEST | CFG_CMD_HACTEST | CFG_CMD_MICTEST)
++*/
++
++#endif /* __CONFIG_H */
+diff --git a/include/configs/ast2300_nor.h b/include/configs/ast2300_nor.h
+new file mode 100644
+index 0000000..77b8fe3
+--- /dev/null
++++ b/include/configs/ast2300_nor.h
+@@ -0,0 +1,322 @@
++/*
++ * (C) Copyright 2004
++ * Peter Chen <peterc@socle-tech.com.tw>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++//#define CONFIG_INIT_CRITICAL /* define for U-BOOT 1.1.1 */
++#undef CONFIG_INIT_CRITICAL /* undef for U-BOOT 1.1.4 */
++#define CONFIG_ARM926EJS 1 /* This is an arm926ejs CPU */
++#define CONFIG_ASPEED 1
++#define CONFIG_AST2300 1
++#define CONFIG_SYS_FLASH_CFI /* CONFIG_FLASH_CFI, CONFIG_FLASH_SPI is exclusive*/
++//#define CONFIG_FLASH_SPI
++//#define CONFIG_2SPIFLASH /* Boot SPI: CS2, 2nd SPI: CS0 */
++#undef CONFIG_2SPIFLASH
++#undef CONFIG_ASPEED_SLT
++#define CONFIG_FLASH_AST2300
++#define CONFIG_FLASH_AST2300_DMA
++//#define CONFIG_FLASH_SPIx2_Dummy
++//#define CONFIG_FLASH_SPIx4_Dummy
++#define CONFIG_CRT_DISPLAY 1 /* undef if not support CRT */
++
++//#define CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
++#define CONFIG_MISC_INIT_R
++
++/*
++ * DRAM Config
++ *
++ * 1. DRAM Size //
++ * CONFIG_DRAM_512MBIT // 512M bit
++ * CONFIG_DRAM_1GBIT // 1G bit (default)
++ * CONFIG_DRAM_2GBIT // 2G bit
++ * CONFIG_DRAM_4GBIT // 4G bit
++ * 2. DRAM Speed //
++ * CONFIG_DRAM_336 // 336MHz (DDR-667)
++ * CONFIG_DRAM_408 // 408MHz (DDR-800) (default)
++ * 3. VGA Mode
++ * CONFIG_CRT_DISPLAY // define to disable VGA function
++ * 4. ECC Function enable
++ * CONFIG_DRAM_ECC // define to enable ECC function
++ * 5. UART Debug Message
++ * CONFIG_DRAM_UART_OUT // enable output message at UART5
++ * CONFIG_DRAM_UART_38400 // set the UART baud rate to 38400, default is 115200
++ */
++
++//1. DRAM Size
++//#define CONFIG_DRAM_512MBIT
++#define CONFIG_DRAM_1GBIT
++//#define CONFIG_DRAM_2GBIT
++//#define CONFIG_DRAM_4GBIT
++//2. DRAM Speed
++//#define CONFIG_DRAM_336
++#define CONFIG_DRAM_408
++//3. VGA Mode
++//#define CONFIG_CRT_DISPLAY
++//4. ECC Function enable
++//#define CONFIG_DRAM_ECC
++//5. UART Debug Message
++#define CONFIG_DRAM_UART_OUT
++//#define CONFIG_DRAM_UART_38400
++
++
++
++/*
++ * Environment Config
++ */
++#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
++#define CONFIG_SETUP_MEMORY_TAGS 1
++#define CONFIG_INITRD_TAG 1
++#define CONFIG_BOOTARGS "debug console=ttyS0,115200n8 ramdisk_size=16384 root=/dev/ram rw init=/linuxrc mem=80M"
++#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
++#ifdef CONFIG_FLASH_AST2300
++#define CONFIG_BOOTCOMMAND "bootm 20080000 20300000"
++#else
++#ifdef CONFIG_SYS_FLASH_CFI
++#define CONFIG_BOOTCOMMAND "bootm 10080000 10300000"
++#else
++#define CONFIG_BOOTCOMMAND "bootm 14080000 14300000"
++#endif
++#endif
++#define CONFIG_BOOTFILE "all.bin"
++#define CONFIG_ENV_OVERWRITE
++
++/*
++ * Command line configuration.
++ */
++#include <config_cmd_default.h>
++
++#define CONFIG_CMD_DFL
++#define CONFIG_CMD_ENV
++#define CONFIG_CMD_FLASH
++#define CONFIG_CMD_NET
++#define CONFIG_CMD_PING
++#define CONFIG_CMD_I2C
++#define CONFIG_CMD_EEPROM
++
++/*
++ * CPU Setting
++ */
++#define CPU_CLOCK_RATE 18000000 /* 16.5 MHz clock for the ARM core */
++
++/*
++ * Size of malloc() pool
++ */
++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 768*1024)
++#define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
++
++/*
++ * Stack sizes, The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE (128*1024) /* regular stack */
++#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
++
++/*
++ * Memory Configuration
++ */
++#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
++#define PHYS_SDRAM_1 0x40000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE 0x4000000 /* 64 MB */
++
++#define CONFIG_SYS_SDRAM_BASE 0x40000000
++
++/*
++ * FLASH Configuration
++ */
++#ifdef CONFIG_SYS_FLASH_CFI /* NOR Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x10000000 /* Flash Bank #1 */
++#endif
++
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (256) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x60000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
++
++#define CONFIG_SYS_FLASH_CFI_AMD_RESET
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++
++#else /* SPI Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x14000000 /* Flash Bank #1 */
++#define PHYS_FLASH_2 0x14800000 /* Flash Bank #2 */
++#define PHYS_FLASH_2_BASE 0x10000000
++#endif
++
++#ifdef CONFIG_2SPIFLASH
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_2_BASE
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1, PHYS_FLASH_2 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 2
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#else
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#endif
++
++#endif
++
++#define __LITTLE_ENDIAN
++
++#define CONFIG_MONITOR_BASE TEXT_BASE
++#define CONFIG_MONITOR_LEN (192 << 10)
++
++/* timeout values are in ticks */
++#define CONFIG_SYS_FLASH_ERASE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Erase */
++#define CONFIG_SYS_FLASH_WRITE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Write */
++
++/*
++ * Miscellaneous configurable options
++ */
++#define CONFIG_SYS_LONGHELP /* undef to save memory */
++
++#define CONFIG_SYS_PROMPT "boot# " /* Monitor Command Prompt */
++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */
++#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
++
++#define CONFIG_SYS_MEMTEST_START 0x40000000 /* memtest works on */
++#define CONFIG_SYS_MEMTEST_END 0x44FFFFFF /* 256 MB in DRAM */
++
++#define CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++#undef CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++
++#define CONFIG_SYS_LOAD_ADDR 0x43000000 /* default load address */
++
++#define CONFIG_SYS_TIMERBASE 0x1E782000 /* use timer 1 */
++#define CONFIG_SYS_HZ (1*1000*1000) /* use external clk (1M) */
++
++/*
++ * Serial Configuration
++ */
++#define CONFIG_SYS_NS16550
++#define CONFIG_SYS_NS16550_SERIAL
++#define CONFIG_SYS_NS16550_REG_SIZE 4
++#define CONFIG_SYS_NS16550_CLK 24000000
++#define CONFIG_SYS_NS16550_COM1 0x1e783000
++#define CONFIG_SYS_NS16550_COM2 0x1e784000
++#define CONFIG_SYS_LOADS_BAUD_CHANGE
++#define CONFIG_SERIAL1 1
++#define CONFIG_CONS_INDEX 2
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++
++/*
++ * USB device configuration
++ */
++/*
++#define CONFIG_USB_DEVICE 1
++#define CONFIG_USB_TTY 1
++
++#define CONFIG_USBD_VENDORID 0x1234
++#define CONFIG_USBD_PRODUCTID 0x5678
++#define CONFIG_USBD_MANUFACTURER "Siemens"
++#define CONFIG_USBD_PRODUCT_NAME "SX1"
++*/
++
++/*
++ * I2C configuration
++ */
++#define CONFIG_HARD_I2C
++#define CONFIG_SYS_I2C_SPEED 100000
++#define CONFIG_SYS_I2C_SLAVE 1
++#define CONFIG_DRIVER_ASPEED_I2C
++
++/*
++* EEPROM configuration
++*/
++#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
++#define CONFIG_SYS_I2C_EEPROM_ADDR 0xa0
++
++/*
++ * NIC configuration
++ */
++#define __BYTE_ORDER __LITTLE_ENDIAN
++#define __LITTLE_ENDIAN_BITFIELD
++#define CONFIG_MAC_PARTITION
++#define CONFIG_ASPEEDNIC
++//#define CONFIG_MAC1_PHY_LINK_INTERRUPT
++#define CONFIG_MAC2_ENABLE
++#define CONFIG_MAC2_PHY_LINK_INTERRUPT
++/*
++*-------------------------------------------------------------------------------
++* NOTICE: MAC1 and MAC2 now have their own seperate PHY configuration.
++* We use 2 bits for each MAC in the scratch register(D[15:11] in 0x1E6E2040) to
++* inform kernel driver.
++* The meanings of the 2 bits are:
++* 00(0): Dedicated PHY
++* 01(1): ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 10(2): ASPEED's MAC is connected to NC-SI PHY chip directly
++* 11: Reserved
++*
++* We use CONFIG_MAC1_PHY_SETTING and CONFIG_MAC2_PHY_SETTING in U-Boot
++* 0: Dedicated PHY
++* 1: ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 2: ASPEED's MAC is connected to NC-SI PHY chip directly
++* 3: Reserved
++*-------------------------------------------------------------------------------
++*/
++#define CONFIG_MAC1_PHY_SETTING 0
++#define CONFIG_MAC2_PHY_SETTING 0
++#define CONFIG_MAC_INTERFACE_CLOCK_DELAY 0x2255
++#define CONFIG_NET_MULTI
++#define CONFIG_ETHACT aspeednic#0
++#define CONFIG_GATEWAYIP 192.168.0.1
++#define CONFIG_NETMASK 255.255.255.0
++#define CONFIG_IPADDR 192.168.0.188
++#define CONFIG_SERVERIP 192.168.0.106
++#define CONFIG_ETHADDR 00:C0:A8:12:34:56
++#define CONFIG_ETH1ADDR 00:C0:A8:12:34:57
++
++/*
++ * SLT
++ */
++/*
++#define CONFIG_SLT
++#define CFG_CMD_SLT (CFG_CMD_VIDEOTEST | CFG_CMD_MACTEST | CFG_CMD_HACTEST | CFG_CMD_MICTEST)
++*/
++
++#endif /* __CONFIG_H */
+diff --git a/include/configs/ast2300_spi.h b/include/configs/ast2300_spi.h
+new file mode 100644
+index 0000000..bc65530
+--- /dev/null
++++ b/include/configs/ast2300_spi.h
+@@ -0,0 +1,322 @@
++/*
++ * (C) Copyright 2004
++ * Peter Chen <peterc@socle-tech.com.tw>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++//#define CONFIG_INIT_CRITICAL /* define for U-BOOT 1.1.1 */
++#undef CONFIG_INIT_CRITICAL /* undef for U-BOOT 1.1.4 */
++#define CONFIG_ARM926EJS 1 /* This is an arm926ejs CPU */
++#define CONFIG_ASPEED 1
++#define CONFIG_AST2300 1
++//#define CONFIG_SYS_FLASH_CFI /* CONFIG_FLASH_CFI, CONFIG_FLASH_SPI is exclusive*/
++#define CONFIG_FLASH_SPI
++//#define CONFIG_2SPIFLASH /* Boot SPI: CS2, 2nd SPI: CS0 */
++#undef CONFIG_2SPIFLASH
++#undef CONFIG_ASPEED_SLT
++#define CONFIG_FLASH_AST2300
++#define CONFIG_FLASH_AST2300_DMA
++//#define CONFIG_FLASH_SPIx2_Dummy
++//#define CONFIG_FLASH_SPIx4_Dummy
++#define CONFIG_CRT_DISPLAY 1 /* undef if not support CRT */
++
++//#define CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
++#define CONFIG_MISC_INIT_R
++
++/*
++ * DRAM Config
++ *
++ * 1. DRAM Size //
++ * CONFIG_DRAM_512MBIT // 512M bit
++ * CONFIG_DRAM_1GBIT // 1G bit (default)
++ * CONFIG_DRAM_2GBIT // 2G bit
++ * CONFIG_DRAM_4GBIT // 4G bit
++ * 2. DRAM Speed //
++ * CONFIG_DRAM_336 // 336MHz (DDR-667)
++ * CONFIG_DRAM_408 // 408MHz (DDR-800) (default)
++ * 3. VGA Mode
++ * CONFIG_CRT_DISPLAY // define to disable VGA function
++ * 4. ECC Function enable
++ * CONFIG_DRAM_ECC // define to enable ECC function
++ * 5. UART Debug Message
++ * CONFIG_DRAM_UART_OUT // enable output message at UART5
++ * CONFIG_DRAM_UART_38400 // set the UART baud rate to 38400, default is 115200
++ */
++
++//1. DRAM Size
++//#define CONFIG_DRAM_512MBIT
++#define CONFIG_DRAM_1GBIT
++//#define CONFIG_DRAM_2GBIT
++//#define CONFIG_DRAM_4GBIT
++//2. DRAM Speed
++//#define CONFIG_DRAM_336
++#define CONFIG_DRAM_408
++//3. VGA Mode
++//#define CONFIG_CRT_DISPLAY
++//4. ECC Function enable
++//#define CONFIG_DRAM_ECC
++//5. UART Debug Message
++#define CONFIG_DRAM_UART_OUT
++//#define CONFIG_DRAM_UART_38400
++
++
++
++/*
++ * Environment Config
++ */
++#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
++#define CONFIG_SETUP_MEMORY_TAGS 1
++#define CONFIG_INITRD_TAG 1
++#define CONFIG_BOOTARGS "debug console=ttyS0,115200n8 ramdisk_size=16384 root=/dev/ram rw init=/linuxrc mem=80M"
++#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
++#ifdef CONFIG_FLASH_AST2300
++#define CONFIG_BOOTCOMMAND "bootm 20080000 20300000"
++#else
++#ifdef CONFIG_SYS_FLASH_CFI
++#define CONFIG_BOOTCOMMAND "bootm 10080000 10300000"
++#else
++#define CONFIG_BOOTCOMMAND "bootm 14080000 14300000"
++#endif
++#endif
++#define CONFIG_BOOTFILE "all.bin"
++#define CONFIG_ENV_OVERWRITE
++
++/*
++ * Command line configuration.
++ */
++#include <config_cmd_default.h>
++
++#define CONFIG_CMD_DFL
++#define CONFIG_CMD_ENV
++#define CONFIG_CMD_FLASH
++#define CONFIG_CMD_NET
++#define CONFIG_CMD_PING
++#define CONFIG_CMD_I2C
++#define CONFIG_CMD_EEPROM
++
++/*
++ * CPU Setting
++ */
++#define CPU_CLOCK_RATE 18000000 /* 16.5 MHz clock for the ARM core */
++
++/*
++ * Size of malloc() pool
++ */
++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 768*1024)
++#define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
++
++/*
++ * Stack sizes, The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE (128*1024) /* regular stack */
++#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
++
++/*
++ * Memory Configuration
++ */
++#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
++#define PHYS_SDRAM_1 0x40000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE 0x4000000 /* 64 MB */
++
++#define CONFIG_SYS_SDRAM_BASE 0x40000000
++
++/*
++ * FLASH Configuration
++ */
++#ifdef CONFIG_SYS_FLASH_CFI /* NOR Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x10000000 /* Flash Bank #1 */
++#endif
++
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (256) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x60000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
++
++#define CONFIG_SYS_FLASH_CFI_AMD_RESET
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++
++#else /* SPI Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x14000000 /* Flash Bank #1 */
++#define PHYS_FLASH_2 0x14800000 /* Flash Bank #2 */
++#define PHYS_FLASH_2_BASE 0x10000000
++#endif
++
++#ifdef CONFIG_2SPIFLASH
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_2_BASE
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1, PHYS_FLASH_2 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 2
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#else
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#endif
++
++#endif
++
++#define __LITTLE_ENDIAN
++
++#define CONFIG_MONITOR_BASE TEXT_BASE
++#define CONFIG_MONITOR_LEN (192 << 10)
++
++/* timeout values are in ticks */
++#define CONFIG_SYS_FLASH_ERASE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Erase */
++#define CONFIG_SYS_FLASH_WRITE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Write */
++
++/*
++ * Miscellaneous configurable options
++ */
++#define CONFIG_SYS_LONGHELP /* undef to save memory */
++
++#define CONFIG_SYS_PROMPT "boot# " /* Monitor Command Prompt */
++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */
++#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
++
++#define CONFIG_SYS_MEMTEST_START 0x40000000 /* memtest works on */
++#define CONFIG_SYS_MEMTEST_END 0x44FFFFFF /* 256 MB in DRAM */
++
++#define CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++#undef CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++
++#define CONFIG_SYS_LOAD_ADDR 0x43000000 /* default load address */
++
++#define CONFIG_SYS_TIMERBASE 0x1E782000 /* use timer 1 */
++#define CONFIG_SYS_HZ (1*1000*1000) /* use external clk (1M) */
++
++/*
++ * Serial Configuration
++ */
++#define CONFIG_SYS_NS16550
++#define CONFIG_SYS_NS16550_SERIAL
++#define CONFIG_SYS_NS16550_REG_SIZE 4
++#define CONFIG_SYS_NS16550_CLK 24000000
++#define CONFIG_SYS_NS16550_COM1 0x1e783000
++#define CONFIG_SYS_NS16550_COM2 0x1e784000
++#define CONFIG_SYS_LOADS_BAUD_CHANGE
++#define CONFIG_SERIAL1 1
++#define CONFIG_CONS_INDEX 2
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++
++/*
++ * USB device configuration
++ */
++/*
++#define CONFIG_USB_DEVICE 1
++#define CONFIG_USB_TTY 1
++
++#define CONFIG_USBD_VENDORID 0x1234
++#define CONFIG_USBD_PRODUCTID 0x5678
++#define CONFIG_USBD_MANUFACTURER "Siemens"
++#define CONFIG_USBD_PRODUCT_NAME "SX1"
++*/
++
++/*
++ * I2C configuration
++ */
++#define CONFIG_HARD_I2C
++#define CONFIG_SYS_I2C_SPEED 100000
++#define CONFIG_SYS_I2C_SLAVE 1
++#define CONFIG_DRIVER_ASPEED_I2C
++
++/*
++* EEPROM configuration
++*/
++#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
++#define CONFIG_SYS_I2C_EEPROM_ADDR 0xa0
++
++/*
++ * NIC configuration
++ */
++#define __BYTE_ORDER __LITTLE_ENDIAN
++#define __LITTLE_ENDIAN_BITFIELD
++#define CONFIG_MAC_PARTITION
++#define CONFIG_ASPEEDNIC
++//#define CONFIG_MAC1_PHY_LINK_INTERRUPT
++#define CONFIG_MAC2_ENABLE
++#define CONFIG_MAC2_PHY_LINK_INTERRUPT
++/*
++*-------------------------------------------------------------------------------
++* NOTICE: MAC1 and MAC2 now have their own seperate PHY configuration.
++* We use 2 bits for each MAC in the scratch register(D[15:11] in 0x1E6E2040) to
++* inform kernel driver.
++* The meanings of the 2 bits are:
++* 00(0): Dedicated PHY
++* 01(1): ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 10(2): ASPEED's MAC is connected to NC-SI PHY chip directly
++* 11: Reserved
++*
++* We use CONFIG_MAC1_PHY_SETTING and CONFIG_MAC2_PHY_SETTING in U-Boot
++* 0: Dedicated PHY
++* 1: ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 2: ASPEED's MAC is connected to NC-SI PHY chip directly
++* 3: Reserved
++*-------------------------------------------------------------------------------
++*/
++#define CONFIG_MAC1_PHY_SETTING 0
++#define CONFIG_MAC2_PHY_SETTING 0
++#define CONFIG_MAC_INTERFACE_CLOCK_DELAY 0x2255
++#define CONFIG_NET_MULTI
++#define CONFIG_ETHACT aspeednic#0
++#define CONFIG_GATEWAYIP 192.168.0.1
++#define CONFIG_NETMASK 255.255.255.0
++#define CONFIG_IPADDR 192.168.0.188
++#define CONFIG_SERVERIP 192.168.0.106
++#define CONFIG_ETHADDR 00:C0:A8:12:34:56
++#define CONFIG_ETH1ADDR 00:C0:A8:12:34:57
++
++/*
++ * SLT
++ */
++/*
++#define CONFIG_SLT
++#define CFG_CMD_SLT (CFG_CMD_VIDEOTEST | CFG_CMD_MACTEST | CFG_CMD_HACTEST | CFG_CMD_MICTEST)
++*/
++
++#endif /* __CONFIG_H */
+diff --git a/include/configs/ast2400.h b/include/configs/ast2400.h
+new file mode 100644
+index 0000000..670fcfd
+--- /dev/null
++++ b/include/configs/ast2400.h
+@@ -0,0 +1,328 @@
++/*
++ * (C) Copyright 2004
++ * Peter Chen <peterc@socle-tech.com.tw>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++//#define CONFIG_INIT_CRITICAL /* define for U-BOOT 1.1.1 */
++#undef CONFIG_INIT_CRITICAL /* undef for U-BOOT 1.1.4 */
++//#define CONFIG_FPGA_ASPEED 1
++#define CONFIG_ARM926EJS 1 /* This is an arm926ejs CPU */
++#define CONFIG_ASPEED 1
++#define CONFIG_AST2400 1
++//#define CONFIG_AST1070 1
++//#define CONFIG_SYS_FLASH_CFI /* CONFIG_FLASH_CFI, CONFIG_FLASH_SPI is exclusive*/
++#define CONFIG_FLASH_SPI
++//#define CONFIG_2SPIFLASH /* Boot SPI: CS2, 2nd SPI: CS0 */
++#undef CONFIG_2SPIFLASH
++#undef CONFIG_ASPEED_SLT
++#define CONFIG_FLASH_AST2300
++//#define CONFIG_FLASH_AST2300_DMA
++//#define CONFIG_FLASH_SPIx2_Dummy
++//#define CONFIG_FLASH_SPIx4_Dummy
++#define CONFIG_CRT_DISPLAY 1 /* undef if not support CRT */
++
++//#define CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
++#define CONFIG_MISC_INIT_R
++
++/*
++ * DRAM Config
++ *
++ * 1. DRAM Size //
++ * CONFIG_DRAM_512MBIT // 512M bit
++ * CONFIG_DRAM_1GBIT // 1G bit (default)
++ * CONFIG_DRAM_2GBIT // 2G bit
++ * CONFIG_DRAM_4GBIT // 4G bit
++ * 2. DRAM Speed //
++ * CONFIG_DRAM_336 // 336MHz (DDR-667)
++ * CONFIG_DRAM_408 // 408MHz (DDR-800) (default)
++ * 3. VGA Mode
++ * CONFIG_CRT_DISPLAY // define to disable VGA function
++ * 4. ECC Function enable
++ * CONFIG_DRAM_ECC // define to enable ECC function
++ * 5. UART Debug Message
++ * CONFIG_DRAM_UART_OUT // enable output message at UART5
++ * CONFIG_DRAM_UART_38400 // set the UART baud rate to 38400, default is 115200
++ */
++
++//1. DRAM Size
++//#define CONFIG_DRAM_512MBIT
++#define CONFIG_DRAM_1GBIT
++//#define CONFIG_DRAM_2GBIT
++//#define CONFIG_DRAM_4GBIT
++//2. DRAM Speed
++//#define CONFIG_DRAM_336
++#define CONFIG_DRAM_408
++//3. VGA Mode
++//#define CONFIG_CRT_DISPLAY
++//4. ECC Function enable
++//#define CONFIG_DRAM_ECC
++//5. UART Debug Message
++#define CONFIG_DRAM_UART_OUT
++//#define CONFIG_DRAM_UART_38400
++
++
++
++/*
++ * Environment Config
++ */
++#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
++#define CONFIG_SETUP_MEMORY_TAGS 1
++#define CONFIG_INITRD_TAG 1
++#define CONFIG_BOOTARGS "debug console=ttyS0,115200n8 ramdisk_size=16384 root=/dev/ram rw init=/linuxrc mem=80M"
++#define CONFIG_UPDATE "tftp 40800000 ast2400.scr; so 40800000'"
++
++#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
++#ifdef CONFIG_FLASH_AST2300
++#define CONFIG_BOOTCOMMAND "bootm 20080000 20300000"
++#else
++#ifdef CONFIG_SYS_FLASH_CFI
++#define CONFIG_BOOTCOMMAND "bootm 10080000 10300000"
++#else
++#define CONFIG_BOOTCOMMAND "bootm 14080000 14300000"
++#endif
++#endif
++#define CONFIG_BOOTFILE "all.bin"
++#define CONFIG_ENV_OVERWRITE
++
++/*
++ * Command line configuration.
++ */
++#include <config_cmd_default.h>
++
++#define CONFIG_CMD_DFL
++#define CONFIG_CMD_ENV
++#define CONFIG_CMD_FLASH
++#define CONFIG_CMD_NET
++#define CONFIG_CMD_PING
++#define CONFIG_CMD_I2C
++#define CONFIG_CMD_EEPROM
++#define CONFIG_CMD_NETTEST
++#define CONFIG_CMD_SLT
++
++/*
++ * CPU Setting
++ */
++#define CPU_CLOCK_RATE 18000000 /* 16.5 MHz clock for the ARM core */
++
++/*
++ * Size of malloc() pool
++ */
++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 768*1024)
++#define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
++
++/*
++ * Stack sizes, The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE (128*1024) /* regular stack */
++#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
++
++/*
++ * Memory Configuration
++ */
++#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
++#define PHYS_SDRAM_1 0x40000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE 0x4000000 /* 64 MB */
++
++#define CONFIG_SYS_SDRAM_BASE 0x40000000
++
++/*
++ * FLASH Configuration
++ */
++#ifdef CONFIG_SYS_FLASH_CFI /* NOR Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x10000000 /* Flash Bank #1 */
++#endif
++
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (256) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x60000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
++
++#define CONFIG_SYS_FLASH_CFI_AMD_RESET
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++
++#else /* SPI Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x14000000 /* Flash Bank #1 */
++#define PHYS_FLASH_2 0x14800000 /* Flash Bank #2 */
++#define PHYS_FLASH_2_BASE 0x10000000
++#endif
++
++#ifdef CONFIG_2SPIFLASH
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_2_BASE
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1, PHYS_FLASH_2 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 2
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#else
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#endif
++
++#endif
++
++#define __LITTLE_ENDIAN
++
++#define CONFIG_MONITOR_BASE TEXT_BASE
++#define CONFIG_MONITOR_LEN (192 << 10)
++
++/* timeout values are in ticks */
++#define CONFIG_SYS_FLASH_ERASE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Erase */
++#define CONFIG_SYS_FLASH_WRITE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Write */
++
++/*
++ * Miscellaneous configurable options
++ */
++#define CONFIG_SYS_LONGHELP /* undef to save memory */
++
++#define CONFIG_SYS_PROMPT "boot# " /* Monitor Command Prompt */
++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */
++#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
++
++#define CONFIG_SYS_MEMTEST_START 0x40000000 /* memtest works on */
++#define CONFIG_SYS_MEMTEST_END 0x44FFFFFF /* 256 MB in DRAM */
++
++#define CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++#undef CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++
++#define CONFIG_SYS_LOAD_ADDR 0x43000000 /* default load address */
++
++#define CONFIG_SYS_TIMERBASE 0x1E782000 /* use timer 1 */
++#define CONFIG_SYS_HZ (1*1000*1000) /* use external clk (1M) */
++
++/*
++ * Serial Configuration
++ */
++#define CONFIG_SYS_NS16550
++#define CONFIG_SYS_NS16550_SERIAL
++#define CONFIG_SYS_NS16550_REG_SIZE 4
++#define CONFIG_SYS_NS16550_CLK 24000000
++#define CONFIG_SYS_NS16550_COM1 0x1e783000
++#define CONFIG_SYS_NS16550_COM2 0x1e784000
++#define CONFIG_SYS_LOADS_BAUD_CHANGE
++#define CONFIG_SERIAL1 1
++#define CONFIG_CONS_INDEX 2
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++
++/*
++ * USB device configuration
++ */
++/*
++#define CONFIG_USB_DEVICE 1
++#define CONFIG_USB_TTY 1
++
++#define CONFIG_USBD_VENDORID 0x1234
++#define CONFIG_USBD_PRODUCTID 0x5678
++#define CONFIG_USBD_MANUFACTURER "Siemens"
++#define CONFIG_USBD_PRODUCT_NAME "SX1"
++*/
++
++/*
++ * I2C configuration
++ */
++#define CONFIG_HARD_I2C
++#define CONFIG_SYS_I2C_SPEED 100000
++#define CONFIG_SYS_I2C_SLAVE 1
++#define CONFIG_DRIVER_ASPEED_I2C
++
++/*
++* EEPROM configuration
++*/
++#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
++#define CONFIG_SYS_I2C_EEPROM_ADDR 0xa0
++
++/*
++ * NIC configuration
++ */
++#define __BYTE_ORDER __LITTLE_ENDIAN
++#define __LITTLE_ENDIAN_BITFIELD
++#define CONFIG_MAC_PARTITION
++#define CONFIG_ASPEEDNIC
++#define CONFIG_MAC1_PHY_LINK_INTERRUPT
++#define CONFIG_MAC2_ENABLE
++#define CONFIG_MAC2_PHY_LINK_INTERRUPT
++/*
++*-------------------------------------------------------------------------------
++* NOTICE: MAC1 and MAC2 now have their own seperate PHY configuration.
++* We use 2 bits for each MAC in the scratch register(D[15:11] in 0x1E6E2040) to
++* inform kernel driver.
++* The meanings of the 2 bits are:
++* 00(0): Dedicated PHY
++* 01(1): ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 10(2): ASPEED's MAC is connected to NC-SI PHY chip directly
++* 11: Reserved
++*
++* We use CONFIG_MAC1_PHY_SETTING and CONFIG_MAC2_PHY_SETTING in U-Boot
++* 0: Dedicated PHY
++* 1: ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 2: ASPEED's MAC is connected to NC-SI PHY chip directly
++* 3: Reserved
++*-------------------------------------------------------------------------------
++*/
++#define CONFIG_MAC1_PHY_SETTING 0
++#define CONFIG_MAC2_PHY_SETTING 0
++#define CONFIG_MAC_INTERFACE_CLOCK_DELAY 0x2255
++#define CONFIG_NET_MULTI
++#define CONFIG_ETHACT aspeednic#0
++#define CONFIG_GATEWAYIP 192.168.0.1
++#define CONFIG_NETMASK 255.255.255.0
++#define CONFIG_IPADDR 192.168.0.45
++#define CONFIG_SERVERIP 192.168.0.81
++#define CONFIG_ETHADDR 00:C0:A8:12:34:56
++#define CONFIG_ETH1ADDR 00:C0:A8:12:34:57
++
++/*
++ * SLT
++ */
++/*
++#define CONFIG_SLT
++#define CFG_CMD_SLT (CFG_CMD_VIDEOTEST | CFG_CMD_MACTEST | CFG_CMD_HACTEST | CFG_CMD_MICTEST)
++*/
++
++#endif /* __CONFIG_H */
+diff --git a/include/configs/ast2400_ast1070.h b/include/configs/ast2400_ast1070.h
+new file mode 100644
+index 0000000..df6c44b
+--- /dev/null
++++ b/include/configs/ast2400_ast1070.h
+@@ -0,0 +1,326 @@
++/*
++ * (C) Copyright 2004
++ * Peter Chen <peterc@socle-tech.com.tw>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++//#define CONFIG_INIT_CRITICAL /* define for U-BOOT 1.1.1 */
++#undef CONFIG_INIT_CRITICAL /* undef for U-BOOT 1.1.4 */
++//#define CONFIG_FPGA_ASPEED 1
++#define CONFIG_ARM926EJS 1 /* This is an arm926ejs CPU */
++#define CONFIG_ASPEED 1
++#define CONFIG_AST2400 1
++#define CONFIG_AST1070 1
++//#define CONFIG_CALIBRATION 1
++//#define CONFIG_SYS_FLASH_CFI /* CONFIG_FLASH_CFI, CONFIG_FLASH_SPI is exclusive*/
++#define CONFIG_FLASH_SPI
++//#define CONFIG_2SPIFLASH /* Boot SPI: CS2, 2nd SPI: CS0 */
++#undef CONFIG_2SPIFLASH
++#undef CONFIG_ASPEED_SLT
++#define CONFIG_FLASH_AST2300
++#define CONFIG_FLASH_AST2300_DMA
++//#define CONFIG_FLASH_SPIx2_Dummy
++//#define CONFIG_FLASH_SPIx4_Dummy
++#define CONFIG_CRT_DISPLAY 1 /* undef if not support CRT */
++
++//#define CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
++#define CONFIG_MISC_INIT_R
++
++/*
++ * DRAM Config
++ *
++ * 1. DRAM Size //
++ * CONFIG_DRAM_512MBIT // 512M bit
++ * CONFIG_DRAM_1GBIT // 1G bit (default)
++ * CONFIG_DRAM_2GBIT // 2G bit
++ * CONFIG_DRAM_4GBIT // 4G bit
++ * 2. DRAM Speed //
++ * CONFIG_DRAM_336 // 336MHz (DDR-667)
++ * CONFIG_DRAM_408 // 408MHz (DDR-800) (default)
++ * 3. VGA Mode
++ * CONFIG_CRT_DISPLAY // define to disable VGA function
++ * 4. ECC Function enable
++ * CONFIG_DRAM_ECC // define to enable ECC function
++ * 5. UART Debug Message
++ * CONFIG_DRAM_UART_OUT // enable output message at UART5
++ * CONFIG_DRAM_UART_38400 // set the UART baud rate to 38400, default is 115200
++ */
++
++//1. DRAM Size
++//#define CONFIG_DRAM_512MBIT
++#define CONFIG_DRAM_1GBIT
++//#define CONFIG_DRAM_2GBIT
++//#define CONFIG_DRAM_4GBIT
++//2. DRAM Speed
++//#define CONFIG_DRAM_336
++#define CONFIG_DRAM_408
++//3. VGA Mode
++//#define CONFIG_CRT_DISPLAY
++//4. ECC Function enable
++//#define CONFIG_DRAM_ECC
++//5. UART Debug Message
++#define CONFIG_DRAM_UART_OUT
++//#define CONFIG_DRAM_UART_38400
++
++
++
++/*
++ * Environment Config
++ */
++#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
++#define CONFIG_SETUP_MEMORY_TAGS 1
++#define CONFIG_INITRD_TAG 1
++#define CONFIG_BOOTARGS "debug console=ttyS0,115200n8 ramdisk_size=16384 root=/dev/ram rw init=/linuxrc mem=80M"
++#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
++#ifdef CONFIG_FLASH_AST2300
++#define CONFIG_BOOTCOMMAND "bootm 20080000 20300000"
++#else
++#ifdef CONFIG_SYS_FLASH_CFI
++#define CONFIG_BOOTCOMMAND "bootm 10080000 10300000"
++#else
++#define CONFIG_BOOTCOMMAND "bootm 14080000 14300000"
++#endif
++#endif
++#define CONFIG_BOOTFILE "all.bin"
++#define CONFIG_ENV_OVERWRITE
++
++/*
++ * Command line configuration.
++ */
++#include <config_cmd_default.h>
++
++#define CONFIG_CMD_DFL
++#define CONFIG_CMD_ENV
++#define CONFIG_CMD_FLASH
++#define CONFIG_CMD_NET
++#define CONFIG_CMD_PING
++#define CONFIG_CMD_I2C
++#define CONFIG_CMD_EEPROM
++#define CONFIG_CMD_NETTEST
++
++/*
++ * CPU Setting
++ */
++#define CPU_CLOCK_RATE 18000000 /* 16.5 MHz clock for the ARM core */
++
++/*
++ * Size of malloc() pool
++ */
++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 768*1024)
++#define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
++
++/*
++ * Stack sizes, The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE (128*1024) /* regular stack */
++#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
++
++/*
++ * Memory Configuration
++ */
++#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
++#define PHYS_SDRAM_1 0x40000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE 0x4000000 /* 64 MB */
++
++#define CONFIG_SYS_SDRAM_BASE 0x40000000
++
++/*
++ * FLASH Configuration
++ */
++#ifdef CONFIG_SYS_FLASH_CFI /* NOR Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x10000000 /* Flash Bank #1 */
++#endif
++
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (256) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x60000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
++
++#define CONFIG_SYS_FLASH_CFI_AMD_RESET
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++
++#else /* SPI Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x14000000 /* Flash Bank #1 */
++#define PHYS_FLASH_2 0x14800000 /* Flash Bank #2 */
++#define PHYS_FLASH_2_BASE 0x10000000
++#endif
++
++#ifdef CONFIG_2SPIFLASH
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_2_BASE
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1, PHYS_FLASH_2 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 2
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#else
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#endif
++
++#endif
++
++#define __LITTLE_ENDIAN
++
++#define CONFIG_MONITOR_BASE TEXT_BASE
++#define CONFIG_MONITOR_LEN (192 << 10)
++
++/* timeout values are in ticks */
++#define CONFIG_SYS_FLASH_ERASE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Erase */
++#define CONFIG_SYS_FLASH_WRITE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Write */
++
++/*
++ * Miscellaneous configurable options
++ */
++#define CONFIG_SYS_LONGHELP /* undef to save memory */
++
++#define CONFIG_SYS_PROMPT "boot# " /* Monitor Command Prompt */
++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */
++#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
++
++#define CONFIG_SYS_MEMTEST_START 0x40000000 /* memtest works on */
++#define CONFIG_SYS_MEMTEST_END 0x44FFFFFF /* 256 MB in DRAM */
++
++#define CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++#undef CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++
++#define CONFIG_SYS_LOAD_ADDR 0x43000000 /* default load address */
++
++#define CONFIG_SYS_TIMERBASE 0x1E782000 /* use timer 1 */
++#define CONFIG_SYS_HZ (1*1000*1000) /* use external clk (1M) */
++
++/*
++ * Serial Configuration
++ */
++#define CONFIG_SYS_NS16550
++#define CONFIG_SYS_NS16550_SERIAL
++#define CONFIG_SYS_NS16550_REG_SIZE 4
++#define CONFIG_SYS_NS16550_CLK 24000000
++#define CONFIG_SYS_NS16550_COM1 0x1e783000
++#define CONFIG_SYS_NS16550_COM2 0x1e784000
++#define CONFIG_SYS_LOADS_BAUD_CHANGE
++#define CONFIG_SERIAL1 1
++#define CONFIG_CONS_INDEX 2
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++
++/*
++ * USB device configuration
++ */
++/*
++#define CONFIG_USB_DEVICE 1
++#define CONFIG_USB_TTY 1
++
++#define CONFIG_USBD_VENDORID 0x1234
++#define CONFIG_USBD_PRODUCTID 0x5678
++#define CONFIG_USBD_MANUFACTURER "Siemens"
++#define CONFIG_USBD_PRODUCT_NAME "SX1"
++*/
++
++/*
++ * I2C configuration
++ */
++#define CONFIG_HARD_I2C
++#define CONFIG_SYS_I2C_SPEED 100000
++#define CONFIG_SYS_I2C_SLAVE 1
++#define CONFIG_DRIVER_ASPEED_I2C
++
++/*
++* EEPROM configuration
++*/
++#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
++#define CONFIG_SYS_I2C_EEPROM_ADDR 0xa0
++
++/*
++ * NIC configuration
++ */
++#define __BYTE_ORDER __LITTLE_ENDIAN
++#define __LITTLE_ENDIAN_BITFIELD
++#define CONFIG_MAC_PARTITION
++#define CONFIG_ASPEEDNIC
++#define CONFIG_MAC1_PHY_LINK_INTERRUPT
++#define CONFIG_MAC2_ENABLE
++#define CONFIG_MAC2_PHY_LINK_INTERRUPT
++/*
++*-------------------------------------------------------------------------------
++* NOTICE: MAC1 and MAC2 now have their own seperate PHY configuration.
++* We use 2 bits for each MAC in the scratch register(D[15:11] in 0x1E6E2040) to
++* inform kernel driver.
++* The meanings of the 2 bits are:
++* 00(0): Dedicated PHY
++* 01(1): ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 10(2): ASPEED's MAC is connected to NC-SI PHY chip directly
++* 11: Reserved
++*
++* We use CONFIG_MAC1_PHY_SETTING and CONFIG_MAC2_PHY_SETTING in U-Boot
++* 0: Dedicated PHY
++* 1: ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 2: ASPEED's MAC is connected to NC-SI PHY chip directly
++* 3: Reserved
++*-------------------------------------------------------------------------------
++*/
++#define CONFIG_MAC1_PHY_SETTING 0
++#define CONFIG_MAC2_PHY_SETTING 0
++#define CONFIG_MAC_INTERFACE_CLOCK_DELAY 0x2255
++#define CONFIG_NET_MULTI
++#define CONFIG_ETHACT aspeednic#0
++#define CONFIG_GATEWAYIP 192.168.0.1
++#define CONFIG_NETMASK 255.255.255.0
++#define CONFIG_IPADDR 192.168.0.41
++#define CONFIG_SERVERIP 192.168.0.81
++#define CONFIG_ETHADDR 00:C0:A8:12:34:56
++#define CONFIG_ETH1ADDR 00:C0:A8:12:34:57
++
++/*
++ * SLT
++ */
++/*
++#define CONFIG_SLT
++#define CFG_CMD_SLT (CFG_CMD_VIDEOTEST | CFG_CMD_MACTEST | CFG_CMD_HACTEST | CFG_CMD_MICTEST)
++*/
++
++#endif /* __CONFIG_H */
+diff --git a/include/configs/ast2400_ast10701.h b/include/configs/ast2400_ast10701.h
+new file mode 100644
+index 0000000..4553535
+--- /dev/null
++++ b/include/configs/ast2400_ast10701.h
+@@ -0,0 +1,327 @@
++/*
++ * (C) Copyright 2004
++ * Peter Chen <peterc@socle-tech.com.tw>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++//#define CONFIG_INIT_CRITICAL /* define for U-BOOT 1.1.1 */
++#undef CONFIG_INIT_CRITICAL /* undef for U-BOOT 1.1.4 */
++//#define CONFIG_FPGA_ASPEED 1
++#define CONFIG_ARM926EJS 1 /* This is an arm926ejs CPU */
++#define CONFIG_ASPEED 1
++#define CONFIG_AST2400 1
++#define CONFIG_AST1070 1
++#define CONFIG_LPC_PLUS 1
++//#define CONFIG_CALIBRATION 1
++//#define CONFIG_SYS_FLASH_CFI /* CONFIG_FLASH_CFI, CONFIG_FLASH_SPI is exclusive*/
++#define CONFIG_FLASH_SPI
++//#define CONFIG_2SPIFLASH /* Boot SPI: CS2, 2nd SPI: CS0 */
++#undef CONFIG_2SPIFLASH
++#undef CONFIG_ASPEED_SLT
++#define CONFIG_FLASH_AST2300
++#define CONFIG_FLASH_AST2300_DMA
++//#define CONFIG_FLASH_SPIx2_Dummy
++//#define CONFIG_FLASH_SPIx4_Dummy
++#define CONFIG_CRT_DISPLAY 1 /* undef if not support CRT */
++
++//#define CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
++#define CONFIG_MISC_INIT_R
++
++/*
++ * DRAM Config
++ *
++ * 1. DRAM Size //
++ * CONFIG_DRAM_512MBIT // 512M bit
++ * CONFIG_DRAM_1GBIT // 1G bit (default)
++ * CONFIG_DRAM_2GBIT // 2G bit
++ * CONFIG_DRAM_4GBIT // 4G bit
++ * 2. DRAM Speed //
++ * CONFIG_DRAM_336 // 336MHz (DDR-667)
++ * CONFIG_DRAM_408 // 408MHz (DDR-800) (default)
++ * 3. VGA Mode
++ * CONFIG_CRT_DISPLAY // define to disable VGA function
++ * 4. ECC Function enable
++ * CONFIG_DRAM_ECC // define to enable ECC function
++ * 5. UART Debug Message
++ * CONFIG_DRAM_UART_OUT // enable output message at UART5
++ * CONFIG_DRAM_UART_38400 // set the UART baud rate to 38400, default is 115200
++ */
++
++//1. DRAM Size
++//#define CONFIG_DRAM_512MBIT
++#define CONFIG_DRAM_1GBIT
++//#define CONFIG_DRAM_2GBIT
++//#define CONFIG_DRAM_4GBIT
++//2. DRAM Speed
++//#define CONFIG_DRAM_336
++#define CONFIG_DRAM_408
++//3. VGA Mode
++//#define CONFIG_CRT_DISPLAY
++//4. ECC Function enable
++//#define CONFIG_DRAM_ECC
++//5. UART Debug Message
++#define CONFIG_DRAM_UART_OUT
++//#define CONFIG_DRAM_UART_38400
++
++
++
++/*
++ * Environment Config
++ */
++#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
++#define CONFIG_SETUP_MEMORY_TAGS 1
++#define CONFIG_INITRD_TAG 1
++#define CONFIG_BOOTARGS "debug console=ttyS0,115200n8 ramdisk_size=16384 root=/dev/ram rw init=/linuxrc mem=80M"
++#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
++#ifdef CONFIG_FLASH_AST2300
++#define CONFIG_BOOTCOMMAND "bootm 20080000 20300000"
++#else
++#ifdef CONFIG_SYS_FLASH_CFI
++#define CONFIG_BOOTCOMMAND "bootm 10080000 10300000"
++#else
++#define CONFIG_BOOTCOMMAND "bootm 14080000 14300000"
++#endif
++#endif
++#define CONFIG_BOOTFILE "all.bin"
++#define CONFIG_ENV_OVERWRITE
++
++/*
++ * Command line configuration.
++ */
++#include <config_cmd_default.h>
++
++#define CONFIG_CMD_DFL
++#define CONFIG_CMD_ENV
++#define CONFIG_CMD_FLASH
++#define CONFIG_CMD_NET
++#define CONFIG_CMD_PING
++#define CONFIG_CMD_I2C
++#define CONFIG_CMD_EEPROM
++#define CONFIG_CMD_NETTEST
++
++/*
++ * CPU Setting
++ */
++#define CPU_CLOCK_RATE 18000000 /* 16.5 MHz clock for the ARM core */
++
++/*
++ * Size of malloc() pool
++ */
++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 768*1024)
++#define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
++
++/*
++ * Stack sizes, The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE (128*1024) /* regular stack */
++#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
++
++/*
++ * Memory Configuration
++ */
++#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
++#define PHYS_SDRAM_1 0x40000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE 0x4000000 /* 64 MB */
++
++#define CONFIG_SYS_SDRAM_BASE 0x40000000
++
++/*
++ * FLASH Configuration
++ */
++#ifdef CONFIG_SYS_FLASH_CFI /* NOR Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x10000000 /* Flash Bank #1 */
++#endif
++
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (256) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0xFE0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x020000 /* Total Size of Environment Sector */
++
++#define CONFIG_SYS_FLASH_CFI_AMD_RESET
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++
++#else /* SPI Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x14000000 /* Flash Bank #1 */
++#define PHYS_FLASH_2 0x14800000 /* Flash Bank #2 */
++#define PHYS_FLASH_2_BASE 0x10000000
++#endif
++
++#ifdef CONFIG_2SPIFLASH
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_2_BASE
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1, PHYS_FLASH_2 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 2
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#else
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#endif
++
++#endif
++
++#define __LITTLE_ENDIAN
++
++#define CONFIG_MONITOR_BASE TEXT_BASE
++#define CONFIG_MONITOR_LEN (192 << 10)
++
++/* timeout values are in ticks */
++#define CONFIG_SYS_FLASH_ERASE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Erase */
++#define CONFIG_SYS_FLASH_WRITE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Write */
++
++/*
++ * Miscellaneous configurable options
++ */
++#define CONFIG_SYS_LONGHELP /* undef to save memory */
++
++#define CONFIG_SYS_PROMPT "boot# " /* Monitor Command Prompt */
++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */
++#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
++
++#define CONFIG_SYS_MEMTEST_START 0x40000000 /* memtest works on */
++#define CONFIG_SYS_MEMTEST_END 0x44FFFFFF /* 256 MB in DRAM */
++
++#define CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++#undef CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++
++#define CONFIG_SYS_LOAD_ADDR 0x43000000 /* default load address */
++
++#define CONFIG_SYS_TIMERBASE 0x1E782000 /* use timer 1 */
++#define CONFIG_SYS_HZ (1*1000*1000) /* use external clk (1M) */
++
++/*
++ * Serial Configuration
++ */
++#define CONFIG_SYS_NS16550
++#define CONFIG_SYS_NS16550_SERIAL
++#define CONFIG_SYS_NS16550_REG_SIZE 4
++#define CONFIG_SYS_NS16550_CLK 24000000
++#define CONFIG_SYS_NS16550_COM1 0x1e783000
++#define CONFIG_SYS_NS16550_COM2 0x1e784000
++#define CONFIG_SYS_LOADS_BAUD_CHANGE
++#define CONFIG_SERIAL1 1
++#define CONFIG_CONS_INDEX 2
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++
++/*
++ * USB device configuration
++ */
++/*
++#define CONFIG_USB_DEVICE 1
++#define CONFIG_USB_TTY 1
++
++#define CONFIG_USBD_VENDORID 0x1234
++#define CONFIG_USBD_PRODUCTID 0x5678
++#define CONFIG_USBD_MANUFACTURER "Siemens"
++#define CONFIG_USBD_PRODUCT_NAME "SX1"
++*/
++
++/*
++ * I2C configuration
++ */
++#define CONFIG_HARD_I2C
++#define CONFIG_SYS_I2C_SPEED 100000
++#define CONFIG_SYS_I2C_SLAVE 1
++#define CONFIG_DRIVER_ASPEED_I2C
++
++/*
++* EEPROM configuration
++*/
++#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
++#define CONFIG_SYS_I2C_EEPROM_ADDR 0xa0
++
++/*
++ * NIC configuration
++ */
++#define __BYTE_ORDER __LITTLE_ENDIAN
++#define __LITTLE_ENDIAN_BITFIELD
++#define CONFIG_MAC_PARTITION
++#define CONFIG_ASPEEDNIC
++#define CONFIG_MAC1_PHY_LINK_INTERRUPT
++#define CONFIG_MAC2_ENABLE
++#define CONFIG_MAC2_PHY_LINK_INTERRUPT
++/*
++*-------------------------------------------------------------------------------
++* NOTICE: MAC1 and MAC2 now have their own seperate PHY configuration.
++* We use 2 bits for each MAC in the scratch register(D[15:11] in 0x1E6E2040) to
++* inform kernel driver.
++* The meanings of the 2 bits are:
++* 00(0): Dedicated PHY
++* 01(1): ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 10(2): ASPEED's MAC is connected to NC-SI PHY chip directly
++* 11: Reserved
++*
++* We use CONFIG_MAC1_PHY_SETTING and CONFIG_MAC2_PHY_SETTING in U-Boot
++* 0: Dedicated PHY
++* 1: ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 2: ASPEED's MAC is connected to NC-SI PHY chip directly
++* 3: Reserved
++*-------------------------------------------------------------------------------
++*/
++#define CONFIG_MAC1_PHY_SETTING 0
++#define CONFIG_MAC2_PHY_SETTING 0
++#define CONFIG_MAC_INTERFACE_CLOCK_DELAY 0x2255
++#define CONFIG_NET_MULTI
++#define CONFIG_ETHACT aspeednic#0
++#define CONFIG_GATEWAYIP 192.168.0.1
++#define CONFIG_NETMASK 255.255.255.0
++#define CONFIG_IPADDR 192.168.0.45
++#define CONFIG_SERVERIP 192.168.0.53
++#define CONFIG_ETHADDR 00:C0:A8:12:34:56
++#define CONFIG_ETH1ADDR 00:C0:A8:12:34:57
++
++/*
++ * SLT
++ */
++/*
++#define CONFIG_SLT
++#define CFG_CMD_SLT (CFG_CMD_VIDEOTEST | CFG_CMD_MACTEST | CFG_CMD_HACTEST | CFG_CMD_MICTEST)
++*/
++
++#endif /* __CONFIG_H */
+diff --git a/include/configs/ast2400_nor.h b/include/configs/ast2400_nor.h
+new file mode 100644
+index 0000000..5b10b36
+--- /dev/null
++++ b/include/configs/ast2400_nor.h
+@@ -0,0 +1,322 @@
++/*
++ * (C) Copyright 2004
++ * Peter Chen <peterc@socle-tech.com.tw>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++//#define CONFIG_INIT_CRITICAL /* define for U-BOOT 1.1.1 */
++#undef CONFIG_INIT_CRITICAL /* undef for U-BOOT 1.1.4 */
++#define CONFIG_ARM926EJS 1 /* This is an arm926ejs CPU */
++#define CONFIG_ASPEED 1
++#define CONFIG_AST2400 1
++#define CONFIG_SYS_FLASH_CFI /* CONFIG_FLASH_CFI, CONFIG_FLASH_SPI is exclusive*/
++//#define CONFIG_FLASH_SPI
++//#define CONFIG_2SPIFLASH /* Boot SPI: CS2, 2nd SPI: CS0 */
++#undef CONFIG_2SPIFLASH
++#undef CONFIG_ASPEED_SLT
++#define CONFIG_FLASH_AST2300
++#define CONFIG_FLASH_AST2300_DMA
++//#define CONFIG_FLASH_SPIx2_Dummy
++//#define CONFIG_FLASH_SPIx4_Dummy
++#define CONFIG_CRT_DISPLAY 1 /* undef if not support CRT */
++
++//#define CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
++#define CONFIG_MISC_INIT_R
++
++/*
++ * DRAM Config
++ *
++ * 1. DRAM Size //
++ * CONFIG_DRAM_512MBIT // 512M bit
++ * CONFIG_DRAM_1GBIT // 1G bit (default)
++ * CONFIG_DRAM_2GBIT // 2G bit
++ * CONFIG_DRAM_4GBIT // 4G bit
++ * 2. DRAM Speed //
++ * CONFIG_DRAM_336 // 336MHz (DDR-667)
++ * CONFIG_DRAM_408 // 408MHz (DDR-800) (default)
++ * 3. VGA Mode
++ * CONFIG_CRT_DISPLAY // define to disable VGA function
++ * 4. ECC Function enable
++ * CONFIG_DRAM_ECC // define to enable ECC function
++ * 5. UART Debug Message
++ * CONFIG_DRAM_UART_OUT // enable output message at UART5
++ * CONFIG_DRAM_UART_38400 // set the UART baud rate to 38400, default is 115200
++ */
++
++//1. DRAM Size
++//#define CONFIG_DRAM_512MBIT
++#define CONFIG_DRAM_1GBIT
++//#define CONFIG_DRAM_2GBIT
++//#define CONFIG_DRAM_4GBIT
++//2. DRAM Speed
++//#define CONFIG_DRAM_336
++#define CONFIG_DRAM_408
++//3. VGA Mode
++//#define CONFIG_CRT_DISPLAY
++//4. ECC Function enable
++//#define CONFIG_DRAM_ECC
++//5. UART Debug Message
++#define CONFIG_DRAM_UART_OUT
++//#define CONFIG_DRAM_UART_38400
++
++
++
++/*
++ * Environment Config
++ */
++#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
++#define CONFIG_SETUP_MEMORY_TAGS 1
++#define CONFIG_INITRD_TAG 1
++#define CONFIG_BOOTARGS "debug console=ttyS0,115200n8 ramdisk_size=16384 root=/dev/ram rw init=/linuxrc mem=80M"
++#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
++#ifdef CONFIG_FLASH_AST2300
++#define CONFIG_BOOTCOMMAND "bootm 20080000 20300000"
++#else
++#ifdef CONFIG_SYS_FLASH_CFI
++#define CONFIG_BOOTCOMMAND "bootm 10080000 10300000"
++#else
++#define CONFIG_BOOTCOMMAND "bootm 14080000 14300000"
++#endif
++#endif
++#define CONFIG_BOOTFILE "all.bin"
++#define CONFIG_ENV_OVERWRITE
++
++/*
++ * Command line configuration.
++ */
++#include <config_cmd_default.h>
++
++#define CONFIG_CMD_DFL
++#define CONFIG_CMD_ENV
++#define CONFIG_CMD_FLASH
++#define CONFIG_CMD_NET
++#define CONFIG_CMD_PING
++#define CONFIG_CMD_I2C
++#define CONFIG_CMD_EEPROM
++
++/*
++ * CPU Setting
++ */
++#define CPU_CLOCK_RATE 18000000 /* 16.5 MHz clock for the ARM core */
++
++/*
++ * Size of malloc() pool
++ */
++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 768*1024)
++#define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
++
++/*
++ * Stack sizes, The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE (128*1024) /* regular stack */
++#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
++
++/*
++ * Memory Configuration
++ */
++#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
++#define PHYS_SDRAM_1 0x40000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE 0x4000000 /* 64 MB */
++
++#define CONFIG_SYS_SDRAM_BASE 0x40000000
++
++/*
++ * FLASH Configuration
++ */
++#ifdef CONFIG_SYS_FLASH_CFI /* NOR Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x10000000 /* Flash Bank #1 */
++#endif
++
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (256) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x60000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
++
++#define CONFIG_SYS_FLASH_CFI_AMD_RESET
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++
++#else /* SPI Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x14000000 /* Flash Bank #1 */
++#define PHYS_FLASH_2 0x14800000 /* Flash Bank #2 */
++#define PHYS_FLASH_2_BASE 0x10000000
++#endif
++
++#ifdef CONFIG_2SPIFLASH
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_2_BASE
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1, PHYS_FLASH_2 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 2
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#else
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#endif
++
++#endif
++
++#define __LITTLE_ENDIAN
++
++#define CONFIG_MONITOR_BASE TEXT_BASE
++#define CONFIG_MONITOR_LEN (192 << 10)
++
++/* timeout values are in ticks */
++#define CONFIG_SYS_FLASH_ERASE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Erase */
++#define CONFIG_SYS_FLASH_WRITE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Write */
++
++/*
++ * Miscellaneous configurable options
++ */
++#define CONFIG_SYS_LONGHELP /* undef to save memory */
++
++#define CONFIG_SYS_PROMPT "boot# " /* Monitor Command Prompt */
++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */
++#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
++
++#define CONFIG_SYS_MEMTEST_START 0x40000000 /* memtest works on */
++#define CONFIG_SYS_MEMTEST_END 0x44FFFFFF /* 256 MB in DRAM */
++
++#define CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++#undef CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++
++#define CONFIG_SYS_LOAD_ADDR 0x43000000 /* default load address */
++
++#define CONFIG_SYS_TIMERBASE 0x1E782000 /* use timer 1 */
++#define CONFIG_SYS_HZ (1*1000*1000) /* use external clk (1M) */
++
++/*
++ * Serial Configuration
++ */
++#define CONFIG_SYS_NS16550
++#define CONFIG_SYS_NS16550_SERIAL
++#define CONFIG_SYS_NS16550_REG_SIZE 4
++#define CONFIG_SYS_NS16550_CLK 24000000
++#define CONFIG_SYS_NS16550_COM1 0x1e783000
++#define CONFIG_SYS_NS16550_COM2 0x1e784000
++#define CONFIG_SYS_LOADS_BAUD_CHANGE
++#define CONFIG_SERIAL1 1
++#define CONFIG_CONS_INDEX 2
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++
++/*
++ * USB device configuration
++ */
++/*
++#define CONFIG_USB_DEVICE 1
++#define CONFIG_USB_TTY 1
++
++#define CONFIG_USBD_VENDORID 0x1234
++#define CONFIG_USBD_PRODUCTID 0x5678
++#define CONFIG_USBD_MANUFACTURER "Siemens"
++#define CONFIG_USBD_PRODUCT_NAME "SX1"
++*/
++
++/*
++ * I2C configuration
++ */
++#define CONFIG_HARD_I2C
++#define CONFIG_SYS_I2C_SPEED 100000
++#define CONFIG_SYS_I2C_SLAVE 1
++#define CONFIG_DRIVER_ASPEED_I2C
++
++/*
++* EEPROM configuration
++*/
++#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
++#define CONFIG_SYS_I2C_EEPROM_ADDR 0xa0
++
++/*
++ * NIC configuration
++ */
++#define __BYTE_ORDER __LITTLE_ENDIAN
++#define __LITTLE_ENDIAN_BITFIELD
++#define CONFIG_MAC_PARTITION
++#define CONFIG_ASPEEDNIC
++#define CONFIG_MAC1_PHY_LINK_INTERRUPT
++#define CONFIG_MAC2_ENABLE
++#define CONFIG_MAC2_PHY_LINK_INTERRUPT
++/*
++*-------------------------------------------------------------------------------
++* NOTICE: MAC1 and MAC2 now have their own seperate PHY configuration.
++* We use 2 bits for each MAC in the scratch register(D[15:11] in 0x1E6E2040) to
++* inform kernel driver.
++* The meanings of the 2 bits are:
++* 00(0): Dedicated PHY
++* 01(1): ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 10(2): ASPEED's MAC is connected to NC-SI PHY chip directly
++* 11: Reserved
++*
++* We use CONFIG_MAC1_PHY_SETTING and CONFIG_MAC2_PHY_SETTING in U-Boot
++* 0: Dedicated PHY
++* 1: ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 2: ASPEED's MAC is connected to NC-SI PHY chip directly
++* 3: Reserved
++*-------------------------------------------------------------------------------
++*/
++#define CONFIG_MAC1_PHY_SETTING 0
++#define CONFIG_MAC2_PHY_SETTING 0
++#define CONFIG_MAC_INTERFACE_CLOCK_DELAY 0x2255
++#define CONFIG_NET_MULTI
++#define CONFIG_ETHACT aspeednic#0
++#define CONFIG_GATEWAYIP 192.168.0.1
++#define CONFIG_NETMASK 255.255.255.0
++#define CONFIG_IPADDR 192.168.0.188
++#define CONFIG_SERVERIP 192.168.0.106
++#define CONFIG_ETHADDR 00:C0:A8:12:34:56
++#define CONFIG_ETH1ADDR 00:C0:A8:12:34:57
++
++/*
++ * SLT
++ */
++/*
++#define CONFIG_SLT
++#define CFG_CMD_SLT (CFG_CMD_VIDEOTEST | CFG_CMD_MACTEST | CFG_CMD_HACTEST | CFG_CMD_MICTEST)
++*/
++
++#endif /* __CONFIG_H */
+diff --git a/include/configs/ast2400_slt.h b/include/configs/ast2400_slt.h
+new file mode 100644
+index 0000000..cfa1c31
+--- /dev/null
++++ b/include/configs/ast2400_slt.h
+@@ -0,0 +1,329 @@
++/*
++ * (C) Copyright 2004
++ * Peter Chen <peterc@socle-tech.com.tw>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++//#define CONFIG_INIT_CRITICAL /* define for U-BOOT 1.1.1 */
++#undef CONFIG_INIT_CRITICAL /* undef for U-BOOT 1.1.4 */
++//#define CONFIG_FPGA_ASPEED 1
++#define CONFIG_ARM926EJS 1 /* This is an arm926ejs CPU */
++#define CONFIG_ASPEED 1
++#define CONFIG_AST2400 1
++#define CONFIG_SLT_ASPEED 1
++//#define CONFIG_AST1070 1
++//#define CONFIG_SYS_FLASH_CFI /* CONFIG_FLASH_CFI, CONFIG_FLASH_SPI is exclusive*/
++#define CONFIG_FLASH_SPI
++//#define CONFIG_2SPIFLASH /* Boot SPI: CS2, 2nd SPI: CS0 */
++#undef CONFIG_2SPIFLASH
++#undef CONFIG_ASPEED_SLT
++#define CONFIG_FLASH_AST2300
++//#define CONFIG_FLASH_AST2300_DMA
++//#define CONFIG_FLASH_SPIx2_Dummy
++//#define CONFIG_FLASH_SPIx4_Dummy
++#define CONFIG_CRT_DISPLAY 1 /* undef if not support CRT */
++
++//#define CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
++#define CONFIG_MISC_INIT_R
++
++/*
++ * DRAM Config
++ *
++ * 1. DRAM Size //
++ * CONFIG_DRAM_512MBIT // 512M bit
++ * CONFIG_DRAM_1GBIT // 1G bit (default)
++ * CONFIG_DRAM_2GBIT // 2G bit
++ * CONFIG_DRAM_4GBIT // 4G bit
++ * 2. DRAM Speed //
++ * CONFIG_DRAM_336 // 336MHz (DDR-667)
++ * CONFIG_DRAM_408 // 408MHz (DDR-800) (default)
++ * 3. VGA Mode
++ * CONFIG_CRT_DISPLAY // define to disable VGA function
++ * 4. ECC Function enable
++ * CONFIG_DRAM_ECC // define to enable ECC function
++ * 5. UART Debug Message
++ * CONFIG_DRAM_UART_OUT // enable output message at UART5
++ * CONFIG_DRAM_UART_38400 // set the UART baud rate to 38400, default is 115200
++ */
++
++//1. DRAM Size
++//#define CONFIG_DRAM_512MBIT
++#define CONFIG_DRAM_1GBIT
++//#define CONFIG_DRAM_2GBIT
++//#define CONFIG_DRAM_4GBIT
++//2. DRAM Speed
++//#define CONFIG_DRAM_336
++#define CONFIG_DRAM_408
++//3. VGA Mode
++//#define CONFIG_CRT_DISPLAY
++//4. ECC Function enable
++//#define CONFIG_DRAM_ECC
++//5. UART Debug Message
++#define CONFIG_DRAM_UART_OUT
++//#define CONFIG_DRAM_UART_38400
++
++
++
++/*
++ * Environment Config
++ */
++#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
++#define CONFIG_SETUP_MEMORY_TAGS 1
++#define CONFIG_INITRD_TAG 1
++#define CONFIG_BOOTARGS "debug console=ttyS0,115200n8 ramdisk_size=16384 root=/dev/ram rw init=/linuxrc mem=32M"
++#define CONFIG_UPDATE "tftp 40800000 ast2400.scr; so 40800000'"
++
++#define CONFIG_BOOTDELAY 0 /* autoboot after 3 seconds */
++#ifdef CONFIG_FLASH_AST2300
++#define CONFIG_BOOTCOMMAND "mactest 0 0 24 2 0 0 0; mactest 1 0 24 2 0 0 0; bootm 20080000 20300000"
++#else
++#ifdef CONFIG_SYS_FLASH_CFI
++#define CONFIG_BOOTCOMMAND "bootm 10080000 10300000"
++#else
++#define CONFIG_BOOTCOMMAND "bootm 14080000 14300000"
++#endif
++#endif
++#define CONFIG_BOOTFILE "all.bin"
++#define CONFIG_ENV_OVERWRITE
++
++/*
++ * Command line configuration.
++ */
++#include <config_cmd_default.h>
++
++#define CONFIG_CMD_DFL
++#define CONFIG_CMD_ENV
++#define CONFIG_CMD_FLASH
++#define CONFIG_CMD_NET
++#define CONFIG_CMD_PING
++#define CONFIG_CMD_I2C
++#define CONFIG_CMD_EEPROM
++#define CONFIG_CMD_NETTEST
++#define CONFIG_CMD_SLT
++
++/*
++ * CPU Setting
++ */
++#define CPU_CLOCK_RATE 18000000 /* 16.5 MHz clock for the ARM core */
++
++/*
++ * Size of malloc() pool
++ */
++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 768*1024)
++#define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
++
++/*
++ * Stack sizes, The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE (128*1024) /* regular stack */
++#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
++
++/*
++ * Memory Configuration
++ */
++#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
++#define PHYS_SDRAM_1 0x40000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE 0x4000000 /* 64 MB */
++
++#define CONFIG_SYS_SDRAM_BASE 0x40000000
++
++/*
++ * FLASH Configuration
++ */
++#ifdef CONFIG_SYS_FLASH_CFI /* NOR Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x10000000 /* Flash Bank #1 */
++#endif
++
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (256) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0xFE0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x020000 /* Total Size of Environment Sector */
++
++#define CONFIG_SYS_FLASH_CFI_AMD_RESET
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++
++#else /* SPI Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x14000000 /* Flash Bank #1 */
++#define PHYS_FLASH_2 0x14800000 /* Flash Bank #2 */
++#define PHYS_FLASH_2_BASE 0x10000000
++#endif
++
++#ifdef CONFIG_2SPIFLASH
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_2_BASE
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1, PHYS_FLASH_2 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 2
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#else
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#endif
++
++#endif
++
++#define __LITTLE_ENDIAN
++
++#define CONFIG_MONITOR_BASE TEXT_BASE
++#define CONFIG_MONITOR_LEN (192 << 10)
++
++/* timeout values are in ticks */
++#define CONFIG_SYS_FLASH_ERASE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Erase */
++#define CONFIG_SYS_FLASH_WRITE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Write */
++
++/*
++ * Miscellaneous configurable options
++ */
++#define CONFIG_SYS_LONGHELP /* undef to save memory */
++
++#define CONFIG_SYS_PROMPT "boot# " /* Monitor Command Prompt */
++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */
++#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
++
++#define CONFIG_SYS_MEMTEST_START 0x40000000 /* memtest works on */
++#define CONFIG_SYS_MEMTEST_END 0x44FFFFFF /* 256 MB in DRAM */
++
++#define CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++#undef CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++
++#define CONFIG_SYS_LOAD_ADDR 0x43000000 /* default load address */
++
++#define CONFIG_SYS_TIMERBASE 0x1E782000 /* use timer 1 */
++#define CONFIG_SYS_HZ (1*1000*1000) /* use external clk (1M) */
++
++/*
++ * Serial Configuration
++ */
++#define CONFIG_SYS_NS16550
++#define CONFIG_SYS_NS16550_SERIAL
++#define CONFIG_SYS_NS16550_REG_SIZE 4
++#define CONFIG_SYS_NS16550_CLK 24000000
++#define CONFIG_SYS_NS16550_COM1 0x1e783000
++#define CONFIG_SYS_NS16550_COM2 0x1e784000
++#define CONFIG_SYS_LOADS_BAUD_CHANGE
++#define CONFIG_SERIAL1 1
++#define CONFIG_CONS_INDEX 2
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++
++/*
++ * USB device configuration
++ */
++/*
++#define CONFIG_USB_DEVICE 1
++#define CONFIG_USB_TTY 1
++
++#define CONFIG_USBD_VENDORID 0x1234
++#define CONFIG_USBD_PRODUCTID 0x5678
++#define CONFIG_USBD_MANUFACTURER "Siemens"
++#define CONFIG_USBD_PRODUCT_NAME "SX1"
++*/
++
++/*
++ * I2C configuration
++ */
++#define CONFIG_HARD_I2C
++#define CONFIG_SYS_I2C_SPEED 100000
++#define CONFIG_SYS_I2C_SLAVE 1
++#define CONFIG_DRIVER_ASPEED_I2C
++
++/*
++* EEPROM configuration
++*/
++#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
++#define CONFIG_SYS_I2C_EEPROM_ADDR 0xa0
++
++/*
++ * NIC configuration
++ */
++#define __BYTE_ORDER __LITTLE_ENDIAN
++#define __LITTLE_ENDIAN_BITFIELD
++#define CONFIG_MAC_PARTITION
++/*#define CONFIG_ASPEEDNIC*/
++#define CONFIG_MAC1_PHY_LINK_INTERRUPT
++#define CONFIG_MAC2_ENABLE
++#define CONFIG_MAC2_PHY_LINK_INTERRUPT
++/*
++*-------------------------------------------------------------------------------
++* NOTICE: MAC1 and MAC2 now have their own seperate PHY configuration.
++* We use 2 bits for each MAC in the scratch register(D[15:11] in 0x1E6E2040) to
++* inform kernel driver.
++* The meanings of the 2 bits are:
++* 00(0): Dedicated PHY
++* 01(1): ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 10(2): ASPEED's MAC is connected to NC-SI PHY chip directly
++* 11: Reserved
++*
++* We use CONFIG_MAC1_PHY_SETTING and CONFIG_MAC2_PHY_SETTING in U-Boot
++* 0: Dedicated PHY
++* 1: ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 2: ASPEED's MAC is connected to NC-SI PHY chip directly
++* 3: Reserved
++*-------------------------------------------------------------------------------
++*/
++#define CONFIG_MAC1_PHY_SETTING 0
++#define CONFIG_MAC2_PHY_SETTING 0
++#define CONFIG_MAC_INTERFACE_CLOCK_DELAY 0x2255
++#define CONFIG_NET_MULTI
++#define CONFIG_ETHACT aspeednic#0
++#define CONFIG_GATEWAYIP 192.168.0.1
++#define CONFIG_NETMASK 255.255.255.0
++#define CONFIG_IPADDR 192.168.0.45
++#define CONFIG_SERVERIP 192.168.0.81
++#define CONFIG_ETHADDR 00:C0:A8:12:34:56
++#define CONFIG_ETH1ADDR 00:C0:A8:12:34:57
++
++/*
++ * SLT
++ */
++/*
++#define CONFIG_SLT
++#define CFG_CMD_SLT (CFG_CMD_VIDEOTEST | CFG_CMD_MACTEST | CFG_CMD_HACTEST | CFG_CMD_MICTEST)
++*/
++
++#endif /* __CONFIG_H */
+diff --git a/include/configs/ast2400_spi.h b/include/configs/ast2400_spi.h
+new file mode 100644
+index 0000000..398e168
+--- /dev/null
++++ b/include/configs/ast2400_spi.h
+@@ -0,0 +1,322 @@
++/*
++ * (C) Copyright 2004
++ * Peter Chen <peterc@socle-tech.com.tw>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++//#define CONFIG_INIT_CRITICAL /* define for U-BOOT 1.1.1 */
++#undef CONFIG_INIT_CRITICAL /* undef for U-BOOT 1.1.4 */
++#define CONFIG_ARM926EJS 1 /* This is an arm926ejs CPU */
++#define CONFIG_ASPEED 1
++#define CONFIG_AST2400 1
++//#define CONFIG_SYS_FLASH_CFI /* CONFIG_FLASH_CFI, CONFIG_FLASH_SPI is exclusive*/
++#define CONFIG_FLASH_SPI
++//#define CONFIG_2SPIFLASH /* Boot SPI: CS2, 2nd SPI: CS0 */
++#undef CONFIG_2SPIFLASH
++#undef CONFIG_ASPEED_SLT
++#define CONFIG_FLASH_AST2300
++#define CONFIG_FLASH_AST2300_DMA
++//#define CONFIG_FLASH_SPIx2_Dummy
++//#define CONFIG_FLASH_SPIx4_Dummy
++#define CONFIG_CRT_DISPLAY 1 /* undef if not support CRT */
++
++//#define CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
++#define CONFIG_MISC_INIT_R
++
++/*
++ * DRAM Config
++ *
++ * 1. DRAM Size //
++ * CONFIG_DRAM_512MBIT // 512M bit
++ * CONFIG_DRAM_1GBIT // 1G bit (default)
++ * CONFIG_DRAM_2GBIT // 2G bit
++ * CONFIG_DRAM_4GBIT // 4G bit
++ * 2. DRAM Speed //
++ * CONFIG_DRAM_336 // 336MHz (DDR-667)
++ * CONFIG_DRAM_408 // 408MHz (DDR-800) (default)
++ * 3. VGA Mode
++ * CONFIG_CRT_DISPLAY // define to disable VGA function
++ * 4. ECC Function enable
++ * CONFIG_DRAM_ECC // define to enable ECC function
++ * 5. UART Debug Message
++ * CONFIG_DRAM_UART_OUT // enable output message at UART5
++ * CONFIG_DRAM_UART_38400 // set the UART baud rate to 38400, default is 115200
++ */
++
++//1. DRAM Size
++//#define CONFIG_DRAM_512MBIT
++#define CONFIG_DRAM_1GBIT
++//#define CONFIG_DRAM_2GBIT
++//#define CONFIG_DRAM_4GBIT
++//2. DRAM Speed
++//#define CONFIG_DRAM_336
++#define CONFIG_DRAM_408
++//3. VGA Mode
++//#define CONFIG_CRT_DISPLAY
++//4. ECC Function enable
++//#define CONFIG_DRAM_ECC
++//5. UART Debug Message
++#define CONFIG_DRAM_UART_OUT
++//#define CONFIG_DRAM_UART_38400
++
++
++
++/*
++ * Environment Config
++ */
++#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
++#define CONFIG_SETUP_MEMORY_TAGS 1
++#define CONFIG_INITRD_TAG 1
++#define CONFIG_BOOTARGS "debug console=ttyS0,115200n8 ramdisk_size=16384 root=/dev/ram rw init=/linuxrc mem=80M"
++#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
++#ifdef CONFIG_FLASH_AST2300
++#define CONFIG_BOOTCOMMAND "bootm 20080000 20300000"
++#else
++#ifdef CONFIG_SYS_FLASH_CFI
++#define CONFIG_BOOTCOMMAND "bootm 10080000 10300000"
++#else
++#define CONFIG_BOOTCOMMAND "bootm 14080000 14300000"
++#endif
++#endif
++#define CONFIG_BOOTFILE "all.bin"
++#define CONFIG_ENV_OVERWRITE
++
++/*
++ * Command line configuration.
++ */
++#include <config_cmd_default.h>
++
++#define CONFIG_CMD_DFL
++#define CONFIG_CMD_ENV
++#define CONFIG_CMD_FLASH
++#define CONFIG_CMD_NET
++#define CONFIG_CMD_PING
++#define CONFIG_CMD_I2C
++#define CONFIG_CMD_EEPROM
++
++/*
++ * CPU Setting
++ */
++#define CPU_CLOCK_RATE 18000000 /* 16.5 MHz clock for the ARM core */
++
++/*
++ * Size of malloc() pool
++ */
++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 768*1024)
++#define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
++
++/*
++ * Stack sizes, The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE (128*1024) /* regular stack */
++#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
++
++/*
++ * Memory Configuration
++ */
++#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
++#define PHYS_SDRAM_1 0x40000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE 0x4000000 /* 64 MB */
++
++#define CONFIG_SYS_SDRAM_BASE 0x40000000
++
++/*
++ * FLASH Configuration
++ */
++#ifdef CONFIG_SYS_FLASH_CFI /* NOR Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x10000000 /* Flash Bank #1 */
++#endif
++
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (256) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x60000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
++
++#define CONFIG_SYS_FLASH_CFI_AMD_RESET
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++
++#else /* SPI Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x14000000 /* Flash Bank #1 */
++#define PHYS_FLASH_2 0x14800000 /* Flash Bank #2 */
++#define PHYS_FLASH_2_BASE 0x10000000
++#endif
++
++#ifdef CONFIG_2SPIFLASH
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_2_BASE
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1, PHYS_FLASH_2 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 2
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#else
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#endif
++
++#endif
++
++#define __LITTLE_ENDIAN
++
++#define CONFIG_MONITOR_BASE TEXT_BASE
++#define CONFIG_MONITOR_LEN (192 << 10)
++
++/* timeout values are in ticks */
++#define CONFIG_SYS_FLASH_ERASE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Erase */
++#define CONFIG_SYS_FLASH_WRITE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Write */
++
++/*
++ * Miscellaneous configurable options
++ */
++#define CONFIG_SYS_LONGHELP /* undef to save memory */
++
++#define CONFIG_SYS_PROMPT "boot# " /* Monitor Command Prompt */
++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */
++#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
++
++#define CONFIG_SYS_MEMTEST_START 0x40000000 /* memtest works on */
++#define CONFIG_SYS_MEMTEST_END 0x44FFFFFF /* 256 MB in DRAM */
++
++#define CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++#undef CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++
++#define CONFIG_SYS_LOAD_ADDR 0x43000000 /* default load address */
++
++#define CONFIG_SYS_TIMERBASE 0x1E782000 /* use timer 1 */
++#define CONFIG_SYS_HZ (1*1000*1000) /* use external clk (1M) */
++
++/*
++ * Serial Configuration
++ */
++#define CONFIG_SYS_NS16550
++#define CONFIG_SYS_NS16550_SERIAL
++#define CONFIG_SYS_NS16550_REG_SIZE 4
++#define CONFIG_SYS_NS16550_CLK 24000000
++#define CONFIG_SYS_NS16550_COM1 0x1e783000
++#define CONFIG_SYS_NS16550_COM2 0x1e784000
++#define CONFIG_SYS_LOADS_BAUD_CHANGE
++#define CONFIG_SERIAL1 1
++#define CONFIG_CONS_INDEX 2
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++
++/*
++ * USB device configuration
++ */
++/*
++#define CONFIG_USB_DEVICE 1
++#define CONFIG_USB_TTY 1
++
++#define CONFIG_USBD_VENDORID 0x1234
++#define CONFIG_USBD_PRODUCTID 0x5678
++#define CONFIG_USBD_MANUFACTURER "Siemens"
++#define CONFIG_USBD_PRODUCT_NAME "SX1"
++*/
++
++/*
++ * I2C configuration
++ */
++#define CONFIG_HARD_I2C
++#define CONFIG_SYS_I2C_SPEED 100000
++#define CONFIG_SYS_I2C_SLAVE 1
++#define CONFIG_DRIVER_ASPEED_I2C
++
++/*
++* EEPROM configuration
++*/
++#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
++#define CONFIG_SYS_I2C_EEPROM_ADDR 0xa0
++
++/*
++ * NIC configuration
++ */
++#define __BYTE_ORDER __LITTLE_ENDIAN
++#define __LITTLE_ENDIAN_BITFIELD
++#define CONFIG_MAC_PARTITION
++#define CONFIG_ASPEEDNIC
++#define CONFIG_MAC1_PHY_LINK_INTERRUPT
++#define CONFIG_MAC2_ENABLE
++#define CONFIG_MAC2_PHY_LINK_INTERRUPT
++/*
++*-------------------------------------------------------------------------------
++* NOTICE: MAC1 and MAC2 now have their own seperate PHY configuration.
++* We use 2 bits for each MAC in the scratch register(D[15:11] in 0x1E6E2040) to
++* inform kernel driver.
++* The meanings of the 2 bits are:
++* 00(0): Dedicated PHY
++* 01(1): ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 10(2): ASPEED's MAC is connected to NC-SI PHY chip directly
++* 11: Reserved
++*
++* We use CONFIG_MAC1_PHY_SETTING and CONFIG_MAC2_PHY_SETTING in U-Boot
++* 0: Dedicated PHY
++* 1: ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 2: ASPEED's MAC is connected to NC-SI PHY chip directly
++* 3: Reserved
++*-------------------------------------------------------------------------------
++*/
++#define CONFIG_MAC1_PHY_SETTING 0
++#define CONFIG_MAC2_PHY_SETTING 0
++#define CONFIG_MAC_INTERFACE_CLOCK_DELAY 0x2255
++#define CONFIG_NET_MULTI
++#define CONFIG_ETHACT aspeednic#0
++#define CONFIG_GATEWAYIP 192.168.0.1
++#define CONFIG_NETMASK 255.255.255.0
++#define CONFIG_IPADDR 192.168.0.45
++#define CONFIG_SERVERIP 192.168.0.81
++#define CONFIG_ETHADDR 00:C0:A8:12:34:56
++#define CONFIG_ETH1ADDR 00:C0:A8:12:34:57
++
++/*
++ * SLT
++ */
++/*
++#define CONFIG_SLT
++#define CFG_CMD_SLT (CFG_CMD_VIDEOTEST | CFG_CMD_MACTEST | CFG_CMD_HACTEST | CFG_CMD_MICTEST)
++*/
++
++#endif /* __CONFIG_H */
+diff --git a/include/configs/ast3100.h b/include/configs/ast3100.h
+new file mode 100644
+index 0000000..f2a2aed
+--- /dev/null
++++ b/include/configs/ast3100.h
+@@ -0,0 +1,325 @@
++/*
++ * (C) Copyright 2004
++ * Peter Chen <peterc@socle-tech.com.tw>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++//#define CONFIG_INIT_CRITICAL /* define for U-BOOT 1.1.1 */
++#undef CONFIG_INIT_CRITICAL /* undef for U-BOOT 1.1.4 */
++#define CONFIG_ARM926EJS 1 /* This is an arm926ejs CPU */
++#define CONFIG_ASPEED 1
++//#define CONFIG_AST2300 1
++#define CONFIG_AST3100 1
++#define CONFIG_AST3100_D200 1 /* Clientron D200*/
++//#define CONFIG_SYS_FLASH_CFI /* CONFIG_FLASH_CFI, CONFIG_FLASH_SPI is exclusive*/
++#define CONFIG_FLASH_SPI
++//#define CONFIG_2SPIFLASH /* Boot SPI: CS2, 2nd SPI: CS0 */
++#undef CONFIG_2SPIFLASH
++#undef CONFIG_ASPEED_SLT
++#define CONFIG_FLASH_AST2300
++//#define CONFIG_FLASH_AST2300_DMA
++//#define CONFIG_FLASH_SPIx2_Dummy
++//#define CONFIG_FLASH_SPIx4_Dummy
++#define CONFIG_CRT_DISPLAY 1 /* undef if not support CRT */
++
++//#define CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
++#define CONFIG_MISC_INIT_R
++
++/*
++ * DRAM Config
++ *
++ * 1. DRAM Size //
++ * CONFIG_DRAM_512MBIT // 512M bit
++ * CONFIG_DRAM_1GBIT // 1G bit (default)
++ * CONFIG_DRAM_2GBIT // 2G bit
++ * CONFIG_DRAM_4GBIT // 4G bit
++ * 2. DRAM Speed //
++ * CONFIG_DRAM_336 // 336MHz (DDR-667)
++ * CONFIG_DRAM_408 // 408MHz (DDR-800) (default)
++ * 3. VGA Mode
++ * CONFIG_CRT_DISPLAY // define to disable VGA function
++ * 4. ECC Function enable
++ * CONFIG_DRAM_ECC // define to enable ECC function
++ * 5. UART Debug Message
++ * CONFIG_DRAM_UART_OUT // enable output message at UART5
++ * CONFIG_DRAM_UART_38400 // set the UART baud rate to 38400, default is 115200
++ */
++
++//1. DRAM Size
++//#define CONFIG_DRAM_512MBIT
++#define CONFIG_DRAM_1GBIT
++//#define CONFIG_DRAM_2GBIT
++//#define CONFIG_DRAM_4GBIT
++//2. DRAM Speed
++//#define CONFIG_DRAM_336
++#define CONFIG_DRAM_408
++//3. VGA Mode
++//#define CONFIG_CRT_DISPLAY
++//4. ECC Function enable
++//#define CONFIG_DRAM_ECC
++//5. UART Debug Message
++#define CONFIG_DRAM_UART_OUT
++//#define CONFIG_DRAM_UART_38400
++
++
++
++/*
++ * Environment Config
++ */
++#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
++#define CONFIG_SETUP_MEMORY_TAGS 1
++#define CONFIG_INITRD_TAG 1
++#define CONFIG_BOOTARGS "debug console=ttyS1,115200n8 ramdisk_size=16384 root=/dev/ram rw init=/linuxrc mem=80M"
++#define CONFIG_BOOTDELAY 4 /* autoboot after 4 seconds */
++#ifdef CONFIG_FLASH_AST2300
++#define CONFIG_BOOTCOMMAND "bootm 20080000 20300000"
++#else
++#ifdef CONFIG_SYS_FLASH_CFI
++#define CONFIG_BOOTCOMMAND "bootm 10080000 10300000"
++#else
++#define CONFIG_BOOTCOMMAND "bootm 14080000 14300000"
++#endif
++#endif
++#define CONFIG_BOOTFILE "allc.bin"
++#define CONFIG_ENV_OVERWRITE
++
++/*
++ * Command line configuration.
++ */
++#include <config_cmd_default.h>
++
++#define CONFIG_CMD_DFL
++#define CONFIG_CMD_ENV
++#define CONFIG_CMD_FLASH
++#define CONFIG_CMD_NET
++#define CONFIG_CMD_PING
++#define CONFIG_CMD_I2C
++#define CONFIG_CMD_EEPROM
++
++/*
++ * CPU Setting
++ */
++#define CPU_CLOCK_RATE 18000000 /* 16.5 MHz clock for the ARM core */
++
++/*
++ * Size of malloc() pool
++ */
++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 768*1024)
++#define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
++
++/*
++ * Stack sizes, The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE (128*1024) /* regular stack */
++#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
++
++/*
++ * Memory Configuration
++ */
++#define CONFIG_DRAM_528
++#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
++#define PHYS_SDRAM_1 0x40000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE 0x4000000 /* 64 MB */
++
++#define CONFIG_SYS_SDRAM_BASE 0x40000000
++
++/*
++ * FLASH Configuration
++ */
++#ifdef CONFIG_SYS_FLASH_CFI /* NOR Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x10000000 /* Flash Bank #1 */
++#endif
++
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (256) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x60000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
++
++#define CONFIG_SYS_FLASH_CFI_AMD_RESET
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++
++#else /* SPI Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x14000000 /* Flash Bank #1 */
++#define PHYS_FLASH_2 0x14800000 /* Flash Bank #2 */
++#define PHYS_FLASH_2_BASE 0x10000000
++#endif
++
++#ifdef CONFIG_2SPIFLASH
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_2_BASE
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1, PHYS_FLASH_2 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 2
++#define CONFIG_SYS_MAX_FLASH_SECT (512) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#else
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (512) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#endif
++
++#endif
++
++#define __LITTLE_ENDIAN
++
++#define CONFIG_MONITOR_BASE TEXT_BASE
++#define CONFIG_MONITOR_LEN (192 << 10)
++
++/* timeout values are in ticks */
++#define CONFIG_SYS_FLASH_ERASE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Erase */
++#define CONFIG_SYS_FLASH_WRITE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Write */
++
++/*
++ * Miscellaneous configurable options
++ */
++#define CONFIG_SYS_LONGHELP /* undef to save memory */
++
++#define CONFIG_SYS_PROMPT "boot# " /* Monitor Command Prompt */
++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */
++#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
++
++#define CONFIG_SYS_MEMTEST_START 0x40000000 /* memtest works on */
++#define CONFIG_SYS_MEMTEST_END 0x44FFFFFF /* 256 MB in DRAM */
++
++#define CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++#undef CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */
++
++#define CONFIG_SYS_LOAD_ADDR 0x43000000 /* default load address */
++
++#define CONFIG_SYS_TIMERBASE 0x1E782000 /* use timer 1 */
++#define CONFIG_SYS_HZ (1*1000*1000) /* use external clk (1M) */
++
++/*
++ * Serial Configuration
++ */
++#define CONFIG_SYS_NS16550
++#define CONFIG_SYS_NS16550_SERIAL
++#define CONFIG_SYS_NS16550_REG_SIZE 4
++#define CONFIG_SYS_NS16550_CLK 24000000
++#define CONFIG_SYS_NS16550_COM1 0x1e783000
++#define CONFIG_SYS_NS16550_COM2 0x1e784000
++#define CONFIG_SYS_LOADS_BAUD_CHANGE
++#define CONFIG_SERIAL1 1
++#define CONFIG_CONS_INDEX 2
++#define CONFIG_BAUDRATE 115200
++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++
++/*
++ * USB device configuration
++ */
++/*
++#define CONFIG_USB_DEVICE 1
++#define CONFIG_USB_TTY 1
++
++#define CONFIG_USBD_VENDORID 0x1234
++#define CONFIG_USBD_PRODUCTID 0x5678
++#define CONFIG_USBD_MANUFACTURER "Siemens"
++#define CONFIG_USBD_PRODUCT_NAME "SX1"
++*/
++
++/*
++ * I2C configuration
++ */
++#define CONFIG_HARD_I2C
++#define CONFIG_SYS_I2C_SPEED 100000
++#define CONFIG_SYS_I2C_SLAVE 1
++#define CONFIG_DRIVER_ASPEED_I2C
++
++/*
++* EEPROM configuration
++*/
++#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
++#define CONFIG_SYS_I2C_EEPROM_ADDR 0xa0
++
++/*
++ * NIC configuration
++ */
++#define __BYTE_ORDER __LITTLE_ENDIAN
++#define __LITTLE_ENDIAN_BITFIELD
++#define CONFIG_MAC_PARTITION
++#define CONFIG_ASPEEDNIC
++//#define CONFIG_MAC1_PHY_LINK_INTERRUPT
++#define CONFIG_MAC2_ENABLE
++#define CONFIG_MAC2_PHY_LINK_INTERRUPT
++/*
++*-------------------------------------------------------------------------------
++* NOTICE: MAC1 and MAC2 now have their own seperate PHY configuration.
++* We use 2 bits for each MAC in the scratch register(D[15:11] in 0x1E6E2040) to
++* inform kernel driver.
++* The meanings of the 2 bits are:
++* 00(0): Dedicated PHY
++* 01(1): ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 10(2): ASPEED's MAC is connected to NC-SI PHY chip directly
++* 11: Reserved
++*
++* We use CONFIG_MAC1_PHY_SETTING and CONFIG_MAC2_PHY_SETTING in U-Boot
++* 0: Dedicated PHY
++* 1: ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 2: ASPEED's MAC is connected to NC-SI PHY chip directly
++* 3: Reserved
++*-------------------------------------------------------------------------------
++*/
++#define CONFIG_MAC1_PHY_SETTING 0
++#define CONFIG_MAC2_PHY_SETTING 0
++#define CONFIG_MAC_INTERFACE_CLOCK_DELAY 0x2255
++#define CONFIG_NET_MULTI
++#define CONFIG_ETHACT aspeednic#0
++#define CONFIG_GATEWAYIP 192.168.0.1
++#define CONFIG_NETMASK 255.255.255.0
++#define CONFIG_IPADDR 192.168.0.249
++#define CONFIG_SERVERIP 192.168.0.156
++#define CONFIG_ETHADDR 00:D0:A8:12:34:58
++#define CONFIG_ETH1ADDR 00:D0:A8:12:34:59
++
++/*
++ * SLT
++ */
++/*
++#define CONFIG_SLT
++#define CFG_CMD_SLT (CFG_CMD_VIDEOTEST | CFG_CMD_MACTEST | CFG_CMD_HACTEST | CFG_CMD_MICTEST)
++*/
++
++#endif /* __CONFIG_H */
+diff --git a/include/flash.h b/include/flash.h
+index c7acc97..e77be1f 100644
+--- a/include/flash.h
++++ b/include/flash.h
+@@ -57,6 +57,21 @@ typedef struct {
+ ulong addr_unlock2; /* unlock address 2 for AMD flash roms */
+ const char *name; /* human-readable name */
+ #endif
++#ifdef CONFIG_FLASH_SPI
++ ulong readcmd;
++ ulong dualport;
++ ulong dummybyte;
++ ulong tCK_Write;
++ ulong tCK_Erase;
++ ulong tCK_Read;
++ ulong CE;
++ ulong iomode;
++ ulong address32;
++ ulong quadport;
++ ulong dummydata;
++ ulong buffersize;
++ ulong specificspi;
++#endif
+ } flash_info_t;
+
+ extern flash_info_t flash_info[]; /* info for FLASH chips */
diff --git a/meta-aspeed/recipes-bsp/u-boot/files/patch-2013.07/0001-u-boot-openbmc.patch b/meta-aspeed/recipes-bsp/u-boot/files/patch-2013.07/0001-u-boot-openbmc.patch
new file mode 100644
index 0000000..e38ae5a
--- /dev/null
+++ b/meta-aspeed/recipes-bsp/u-boot/files/patch-2013.07/0001-u-boot-openbmc.patch
@@ -0,0 +1,1580 @@
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/IO.c b/arch/arm/cpu/arm926ejs/aspeed/IO.c
+index 86e9918..b06fdba 100644
+--- a/arch/arm/cpu/arm926ejs/aspeed/IO.c
++++ b/arch/arm/cpu/arm926ejs/aspeed/IO.c
+@@ -31,7 +31,7 @@ static const char ThisFile[] = "IO.c";
+ #include <post.h>
+ #include <malloc.h>
+ #include <net.h>
+- #include <COMMINF.H>
++ #include "COMMINF.H"
+ #endif
+ #ifdef SLT_DOS
+ #include <stdlib.h>
+@@ -353,4 +353,3 @@ ULONG ReadSOC_DD(ULONG addr)
+ #endif
+ return 0;
+ }
+-
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/LAN9303.c b/arch/arm/cpu/arm926ejs/aspeed/LAN9303.c
+index 498d4fd..fdabd45 100644
+--- a/arch/arm/cpu/arm926ejs/aspeed/LAN9303.c
++++ b/arch/arm/cpu/arm926ejs/aspeed/LAN9303.c
+@@ -13,9 +13,9 @@ static const char ThisFile[] = "LAN9303.c";
+
+ #include "SWFUNC.H"
+ #ifdef SLT_UBOOT
+- #include <COMMINF.H>
+- #include <MAC.H>
+- #include <IO.H>
++ #include "COMMINF.H"
++ #include "MAC.H"
++ #include "IO.H"
+ #endif
+
+ #ifdef SLT_DOS
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/MAC.c b/arch/arm/cpu/arm926ejs/aspeed/MAC.c
+index 829da92..b4182f5 100644
+--- a/arch/arm/cpu/arm926ejs/aspeed/MAC.c
++++ b/arch/arm/cpu/arm926ejs/aspeed/MAC.c
+@@ -16,7 +16,7 @@ static const char ThisFile[] = "MAC.c";
+ #ifdef SLT_UBOOT
+ #include <common.h>
+ #include <command.h>
+- #include <COMMINF.H>
++ #include "COMMINF.H"
+ #include "STDUBOOT.H"
+ #endif
+ #ifdef SLT_DOS
+@@ -2081,5 +2081,3 @@ char TestingLoop (ULONG loop_checknum) {
+
+ return(0);
+ } // End char TestingLoop (ULONG loop_checknum)
+-
+-
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/Makefile b/arch/arm/cpu/arm926ejs/aspeed/Makefile
+index 378745e..4c4e239 100644
+--- a/arch/arm/cpu/arm926ejs/aspeed/Makefile
++++ b/arch/arm/cpu/arm926ejs/aspeed/Makefile
+@@ -16,7 +16,7 @@
+
+ include $(TOPDIR)/config.mk
+
+-LIB = $(obj)lib$(SOC).a
++LIB = $(obj)lib$(SOC).o
+
+ COBJS = timer.o
+ COBJS += reset.o
+@@ -41,7 +41,7 @@ START := $(addprefix $(obj),$(START))
+ all: $(obj).depend $(LIB)
+
+ $(LIB): $(OBJS)
+- $(AR) $(ARFLAGS) $@ $(OBJS)
++ $(call cmd_link_o_target, $(OBJS))
+
+ #########################################################################
+
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/NCSI.c b/arch/arm/cpu/arm926ejs/aspeed/NCSI.c
+index 7de06c3..7e86fb6 100644
+--- a/arch/arm/cpu/arm926ejs/aspeed/NCSI.c
++++ b/arch/arm/cpu/arm926ejs/aspeed/NCSI.c
+@@ -16,9 +16,9 @@ static const char ThisFile[] = "NCSI.c";
+ #ifdef SLT_UBOOT
+ #include <common.h>
+ #include <command.h>
+- #include <COMMINF.H>
+- #include <NCSI.H>
+- #include <IO.H>
++ #include "COMMINF.H"
++ #include "NCSI.H"
++ #include "IO.H"
+ #endif
+ #ifdef SLT_DOS
+ #include <stdio.h>
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/PHY.c b/arch/arm/cpu/arm926ejs/aspeed/PHY.c
+index 6afed9d..db73a70 100644
+--- a/arch/arm/cpu/arm926ejs/aspeed/PHY.c
++++ b/arch/arm/cpu/arm926ejs/aspeed/PHY.c
+@@ -16,7 +16,7 @@ static const char ThisFile[] = "PHY.c";
+ #ifdef SLT_UBOOT
+ #include <common.h>
+ #include <command.h>
+- #include <COMMINF.H>
++ #include "COMMINF.H"
+ #include "STDUBOOT.H"
+ #endif
+ #ifdef SLT_DOS
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/PLLTESTU.c b/arch/arm/cpu/arm926ejs/aspeed/PLLTESTU.c
+index 95958b0..2414d57 100644
+--- a/arch/arm/cpu/arm926ejs/aspeed/PLLTESTU.c
++++ b/arch/arm/cpu/arm926ejs/aspeed/PLLTESTU.c
+@@ -13,11 +13,11 @@ static const char ThisFile[] = "PLLTEST.c";
+
+ #include "SWFUNC.H"
+
+-#include <COMMINF.H>
+-#include <STDUBOOT.H>
+-#include <TYPEDEF.H>
+-#include <IO.H>
+-#include <PLLTESTU.H>
++#include "COMMINF.H"
++#include "STDUBOOT.H"
++#include "TYPEDEF.H"
++#include "IO.H"
++#include "PLLTESTU.H"
+
+ /*
+ * static
+@@ -407,5 +407,3 @@ int pll_function(int argc, char *argv[])
+ return (ERR_FATAL);
+ }
+ }
+-
+-
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/STDUBOOT.H b/arch/arm/cpu/arm926ejs/aspeed/STDUBOOT.H
+index 7fbf590..4e0adf6 100644
+--- a/arch/arm/cpu/arm926ejs/aspeed/STDUBOOT.H
++++ b/arch/arm/cpu/arm926ejs/aspeed/STDUBOOT.H
+@@ -13,6 +13,5 @@
+
+ unsigned long int strtoul(char *string, char **endPtr, int base);
+ int atoi( char s[] );
+-int rand(void);
+
+ #endif // End STDUBOOT_H
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/STDUBOOT.c b/arch/arm/cpu/arm926ejs/aspeed/STDUBOOT.c
+index 90e2997..4b1f439 100644
+--- a/arch/arm/cpu/arm926ejs/aspeed/STDUBOOT.c
++++ b/arch/arm/cpu/arm926ejs/aspeed/STDUBOOT.c
+@@ -19,11 +19,11 @@ int isspace ( char c )
+ {
+ if ( ( c == ' ' ) || ( c == 9 ) || ( c == 13 ) )
+ return 1;
+-
++
+ return 0;
+ }
+
+-/*
++/*
+ * strtoul.c --
+ *
+ * Source code for the "strtoul" library procedure.
+@@ -111,7 +111,7 @@ strtoul(char *string, char **endPtr, int base)
+ * If no base was provided, pick one from the leading characters
+ * of the string.
+ */
+-
++
+ if (base == 0)
+ {
+ if (*p == '0') {
+@@ -219,17 +219,6 @@ int atoi( char s[] )
+ ans = ( 10 * ans ) + ( s[i] - '0' );
+
+ return ans;
+-}
+-
+-// -----------------------------------------------------------------------------
+-/* rand:return pseudo-random integer on 0...32767 */
+-int rand(void)
+-{
+- static unsigned long int next = 1;
+-
+- next = next * 1103515245 + 12345;
+-
+- return (unsigned int) ( next / 65536 ) % 32768;
+ }
+
+ #endif // End SLT_UBOOT
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/STRESS.c b/arch/arm/cpu/arm926ejs/aspeed/STRESS.c
+index dffd64f..e86685e 100644
+--- a/arch/arm/cpu/arm926ejs/aspeed/STRESS.c
++++ b/arch/arm/cpu/arm926ejs/aspeed/STRESS.c
+@@ -12,8 +12,8 @@
+ static const char ThisFile[] = "STRESS.c";
+
+ #include "SWFUNC.H"
+-#include <COMMINF.H>
+-#include <IO.H>
++#include "COMMINF.H"
++#include "IO.H"
+
+ #define TIMEOUT_DRAM 5000000
+
+@@ -142,4 +142,3 @@ int dram_stress_function(int argc, char *argv[])
+
+ return( ret );
+ }
+-
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/TRAPTEST.c b/arch/arm/cpu/arm926ejs/aspeed/TRAPTEST.c
+index 72936c0..24ec0c5 100644
+--- a/arch/arm/cpu/arm926ejs/aspeed/TRAPTEST.c
++++ b/arch/arm/cpu/arm926ejs/aspeed/TRAPTEST.c
+@@ -13,9 +13,9 @@ static const char ThisFile[] = "PLLTEST.c";
+
+ #include "SWFUNC.H"
+
+-#include <COMMINF.H>
+-#include <TYPEDEF.H>
+-#include <IO.H>
++#include "COMMINF.H"
++#include "TYPEDEF.H"
++#include "IO.H"
+
+ #define ASTCHIP_2400 0
+ #define ASTCHIP_2300 1
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/mactest.c b/arch/arm/cpu/arm926ejs/aspeed/mactest.c
+index 95bd560..62a696d 100644
+--- a/arch/arm/cpu/arm926ejs/aspeed/mactest.c
++++ b/arch/arm/cpu/arm926ejs/aspeed/mactest.c
+@@ -19,9 +19,9 @@ static const char ThisFile[] = "MACTEST.c";
+ #include <post.h>
+ #include <malloc.h>
+ #include <net.h>
+- #include <COMMINF.H>
+- #include <STDUBOOT.H>
+- #include <IO.H>
++ #include "COMMINF.H"
++ #include "STDUBOOT.H"
++ #include "IO.H"
+ #else
+ #include <stdlib.h>
+ #include <string.h>
+@@ -1212,4 +1212,3 @@ Find_Err_IOMargin:;
+ return(Finish_Check(0));
+
+ }
+-
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/reset.c b/arch/arm/cpu/arm926ejs/aspeed/reset.c
+index e0a57f9..ce8dba1 100644
+--- a/arch/arm/cpu/arm926ejs/aspeed/reset.c
++++ b/arch/arm/cpu/arm926ejs/aspeed/reset.c
+@@ -17,7 +17,7 @@ void reset_cpu(ulong addr)
+ {
+ __raw_writel(0x10 , AST_WDT_BASE+0x04);
+ __raw_writel(0x4755, AST_WDT_BASE+0x08);
+- __raw_writel(0x3, AST_WDT_BASE+0x0c);
++ __raw_writel(0x23, AST_WDT_BASE+0x0c); /* reset the full chip */
+
+ while (1)
+ /*nothing*/;
+diff --git a/arch/arm/cpu/arm926ejs/aspeed/timer.c b/arch/arm/cpu/arm926ejs/aspeed/timer.c
+index 4bba5c5..add4c0e 100644
+--- a/arch/arm/cpu/arm926ejs/aspeed/timer.c
++++ b/arch/arm/cpu/arm926ejs/aspeed/timer.c
+@@ -16,12 +16,17 @@
+ */
+
+ #include <common.h>
+-#include <arm926ejs.h>
++
++#if CONFIG_ASPEED_TIMER_CLK < CONFIG_SYS_HZ
++#error "CONFIG_ASPEED_TIMER_CLK must be as large as CONFIG_SYS_HZ"
++#endif
+
+ #define TIMER_LOAD_VAL 0xffffffff
++#define CLK_PER_HZ (CONFIG_ASPEED_TIMER_CLK / CONFIG_SYS_HZ)
+
+ /* macro to read the 32 bit timer */
+-#define READ_TIMER (*(volatile ulong *)(CONFIG_SYS_TIMERBASE+0))
++#define READ_CLK (*(volatile ulong *)(CONFIG_SYS_TIMERBASE + 0))
++#define READ_TIMER (READ_CLK / CLK_PER_HZ)
+
+ static ulong timestamp;
+ static ulong lastdec;
+@@ -57,27 +62,25 @@ void set_timer (ulong t)
+ }
+
+ /* delay x useconds AND perserve advance timstamp value */
+-void udelay (unsigned long usec)
++void __udelay (unsigned long usec)
+ {
+- ulong tmo, tmp;
+-
+- if(usec >= 1000){ /* if "big" number, spread normalization to seconds */
+- tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
+- tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */
+- tmo /= 1000; /* finish normalize. */
+- }else{ /* else small number, don't kill it prior to HZ multiply */
+- tmo = usec * CONFIG_SYS_HZ;
+- tmo /= (1000*1000);
+- }
+-
+- tmp = get_timer (0); /* get current timestamp */
+- if( (tmo + tmp + 1) < tmp ) /* if setting this fordward will roll time stamp */
+- reset_timer_masked (); /* reset "advancing" timestamp to 0, set lastdec value */
+- else
+- tmo += tmp; /* else, set advancing stamp wake up time */
+-
+- while (get_timer_masked () < tmo)/* loop till event */
+- /*NOP*/;
++ ulong last = READ_CLK;
++ ulong clks;
++ ulong elapsed = 0;
++
++ /* translate usec to clocks */
++ clks = (usec / 1000) * CLK_PER_HZ;
++ clks += (usec % 1000) * CLK_PER_HZ / 1000;
++
++ while (clks > elapsed) {
++ ulong now = READ_CLK;
++ if (now <= last) {
++ elapsed += last - now;
++ } else {
++ elapsed += TIMER_LOAD_VAL - (now - last);
++ }
++ last = now;
++ }
+ }
+
+ void reset_timer_masked (void)
+@@ -100,7 +103,7 @@ ulong get_timer_masked (void)
+ * (TLV-now) amount of time after passing though -1
+ * nts = new "advancing time stamp"...it could also roll and cause problems.
+ */
+- timestamp += lastdec + TIMER_LOAD_VAL - now;
++ timestamp += lastdec + (TIMER_LOAD_VAL / CLK_PER_HZ) - now;
+ }
+ lastdec = now;
+
+@@ -110,25 +113,7 @@ ulong get_timer_masked (void)
+ /* waits specified delay value and resets timestamp */
+ void udelay_masked (unsigned long usec)
+ {
+- ulong tmo;
+- ulong endtime;
+- signed long diff;
+-
+- if (usec >= 1000) { /* if "big" number, spread normalization to seconds */
+- tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
+- tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */
+- tmo /= 1000; /* finish normalize. */
+- } else { /* else small number, don't kill it prior to HZ multiply */
+- tmo = usec * CONFIG_SYS_HZ;
+- tmo /= (1000*1000);
+- }
+-
+- endtime = get_timer_masked () + tmo;
+-
+- do {
+- ulong now = get_timer_masked ();
+- diff = endtime - now;
+- } while (diff >= 0);
++ __udelay(usec);
+ }
+
+ /*
+@@ -146,8 +131,5 @@ unsigned long long get_ticks(void)
+ */
+ ulong get_tbclk (void)
+ {
+- ulong tbclk;
+-
+- tbclk = CONFIG_SYS_HZ;
+- return tbclk;
++ return CONFIG_SYS_HZ;
+ }
+diff --git a/board/aspeed/ast2400/Makefile b/board/aspeed/ast2400/Makefile
+index 1970ea1..fb77fc9 100644
+--- a/board/aspeed/ast2400/Makefile
++++ b/board/aspeed/ast2400/Makefile
+@@ -11,7 +11,7 @@
+
+ include $(TOPDIR)/config.mk
+
+-LIB = $(obj)lib$(BOARD).a
++LIB = $(obj)lib$(BOARD).o
+
+ COBJS := ast2400.o flash.o flash_spi.o pci.o crc32.o slt.o regtest.o vfun.o vhace.o crt.o videotest.o mactest.o hactest.o mictest.o
+
+@@ -28,17 +28,13 @@ OBJS := $(addprefix $(obj),$(COBJS))
+ SOBJS := $(addprefix $(obj),$(SOBJS))
+
+ $(LIB): $(obj).depend $(OBJS) $(SOBJS)
+- $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
++ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
+
+-clean:
+- rm -f $(SOBJS) $(OBJS)
+-
+-distclean: clean
+- rm -f $(LIB) core *.bak $(obj).depend
++#########################################################################
+
+ # defines $(obj).depend target
+ include $(SRCTREE)/rules.mk
+
+-sinclude .depend
++sinclude $(obj).depend
+
+ #########################################################################
+diff --git a/board/aspeed/ast2400/ast2400.c b/board/aspeed/ast2400/ast2400.c
+index 65bccbe..55ed6b7 100644
+--- a/board/aspeed/ast2400/ast2400.c
++++ b/board/aspeed/ast2400/ast2400.c
+@@ -10,6 +10,7 @@
+ */
+
+ #include <common.h>
++#include <asm/io.h>
+ #include <command.h>
+ #include <pci.h>
+
+@@ -105,8 +106,8 @@ int dram_init (void)
+ {
+ DECLARE_GLOBAL_DATA_PTR;
+
+- gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+- gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
++ /* dram_init must store complete ramsize in gd->ram_size */
++ gd->ram_size = get_ram_size((void *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
+
+ return 0;
+ }
+@@ -190,6 +191,22 @@ int ast1070_calibration()
+ return 0;
+ }
+
++static void watchdog_init()
++{
++#ifdef CONFIG_ASPEED_ENABLE_WATCHDOG
++#define AST_WDT_BASE 0x1e785000
++#define AST_WDT_CLK (1*1000*1000) /* 1M clock source */
++ u32 reload = AST_WDT_CLK * CONFIG_ASPEED_WATCHDOG_TIMEOUT;
++ /* set the reload value */
++ __raw_writel(reload, AST_WDT_BASE + 0x04);
++ /* magic word to reload */
++ __raw_writel(0x4755, AST_WDT_BASE + 0x08);
++ /* start the watchdog with 1M clk src and reset whole chip */
++ __raw_writel(0x33, AST_WDT_BASE + 0x0c);
++ printf("Watchdog: %us\n", CONFIG_ASPEED_WATCHDOG_TIMEOUT);
++#endif
++}
++
+ int misc_init_r(void)
+ {
+ unsigned int reg, reg1, revision, chip_id, lpc_plus;
+@@ -290,6 +307,8 @@ int misc_init_r(void)
+ if (getenv ("eeprom") == NULL) {
+ setenv ("eeprom", "y");
+ }
++
++ watchdog_init();
+ }
+
+ #ifdef CONFIG_PCI
+@@ -302,3 +321,15 @@ void pci_init_board(void)
+ aspeed_init_pci(&hose);
+ }
+ #endif
++
++int board_eth_init(bd_t *bis)
++{
++ int ret = -1;
++#if defined(CONFIG_ASPEEDNIC)
++ ret = aspeednic_initialize(bis);
++#else
++ printf("No ETH, ");
++#endif
++
++ return ret;
++}
+diff --git a/board/aspeed/ast2400/config.mk b/board/aspeed/ast2400/config.mk
+index 24ca09b..eddc3bf 100755
+--- a/board/aspeed/ast2400/config.mk
++++ b/board/aspeed/ast2400/config.mk
+@@ -9,10 +9,5 @@
+ # MA 02111-1307 USA
+ #
+
+-# ROM version
+-#TEXT_BASE = 0xBFC00000
+-
+-# RAM version
+-TEXT_BASE = 0x40500000
+-#TEXT_BASE = 0x00000000
+-#TEXT_BASE = 0x00400000
++# SPI flash is mapped to 0x00000000 initially
++CONFIG_SYS_TEXT_BASE = 0x00000000
+diff --git a/board/aspeed/ast2400/flash_spi.c b/board/aspeed/ast2400/flash_spi.c
+index ad89254..339e531 100755
+--- a/board/aspeed/ast2400/flash_spi.c
++++ b/board/aspeed/ast2400/flash_spi.c
+@@ -23,7 +23,7 @@
+ */
+
+ /* The DEBUG define must be before common to enable debugging */
+-/* #define DEBUG */
++/* #define DEBUG */
+
+ #include <common.h>
+ #include <asm/processor.h>
+@@ -68,6 +68,7 @@ flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* FLASH chips info */
+ /* Support Flash ID */
+ #define STM25P64 0x172020
+ #define STM25P128 0x182020
++#define N25Q128 0x18ba20
+ #define N25Q256 0x19ba20
+ #define N25Q512 0x20ba20
+ #define S25FL064A 0x160201
+@@ -581,7 +582,7 @@ static ulong flash_get_size (ulong base, int banknum)
+ ulID = ((ulong)ch[0]) | ((ulong)ch[1] << 8) | ((ulong)ch[2] << 16) ;
+ info->flash_id = ulID;
+
+- //printf("SPI Flash ID: %x \n", ulID);
++ printf("SPI Flash ID: %x \n", ulID);
+
+ /* init default */
+ info->iomode = IOMODEx1;
+@@ -617,6 +618,19 @@ static ulong flash_get_size (ulong base, int banknum)
+ ReadClk = 50;
+ break;
+
++ case N25Q128:
++ info->sector_count = 256;
++ info->size = 0x1000000;
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++ WriteClk = 50;
++ EraseClk = 20;
++ ReadClk = 50;
++ break;
++
+ case N25Q256:
+ info->sector_count = 256;
+ info->size = 0x1000000;
+@@ -1051,8 +1065,7 @@ AST2300 A0 SPI can't run faster than 50Mhz
+ } /* JDEC */
+ }
+
+- debug ("erase_region_count = %d erase_region_size = %d\n",
+- erase_region_count, erase_region_size);
++ debug ("erase_region_size = %d\n", erase_region_size);
+
+ sector = base;
+ for (j = 0; j < info->sector_count; j++) {
+diff --git a/board/aspeed/ast2400/platform.S b/board/aspeed/ast2400/platform.S
+index 27e8f26..dd94da0 100644
+--- a/board/aspeed/ast2400/platform.S
++++ b/board/aspeed/ast2400/platform.S
+@@ -334,7 +334,11 @@ set_MPLL:
+ str r1, [r0]
+
+ /* Debug - UART console message */
+- ldr r0, =0x1e78400c
++ ldr r0, =0x1e6e2080
++ ldr r1, =0xFFFF0000 @ enable UART3 and UART4
++ str r1, [r0]
++
++ ldr r0, =CONFIG_ASPEED_COM_LCR
+ mov r1, #0x83
+ str r1, [r0]
+
+@@ -342,28 +346,38 @@ set_MPLL:
+ ldr r2, [r0]
+ mov r2, r2, lsr #12
+ tst r2, #0x01
+- ldr r0, =0x1e784000
++ ldr r0, =CONFIG_ASPEED_COM
++#if CONFIG_BAUDRATE == 115200
+ moveq r1, #0x0D @ Baudrate 115200
+ movne r1, #0x01 @ Baudrate 115200, div13
+-#if defined(CONFIG_DRAM_UART_38400)
++#endif
++#if CONFIG_BAUDRATE == 57600
++ moveq r1, #0x1A @ Baudrate 57600
++ movne r1, #0x02 @ Baudrate 57600, div13
++#endif
++#if CONFIG_BAUDRATE == 38400
+ moveq r1, #0x27 @ Baudrate 38400
+ movne r1, #0x03 @ Baudrate 38400 , div13
+ #endif
++#if CONFIG_BAUDRATE == 9600
++ moveq r1, #0x9c @ Baudrate 9600
++ movne r1, #0x0C @ Baudrate 9600 , div13
++#endif
+ str r1, [r0]
+
+- ldr r0, =0x1e784004
++ ldr r0, =CONFIG_ASPEED_COM_IER
+ mov r1, #0x00
+ str r1, [r0]
+
+- ldr r0, =0x1e78400c
++ ldr r0, =CONFIG_ASPEED_COM_LCR
+ mov r1, #0x03
+ str r1, [r0]
+
+- ldr r0, =0x1e784008
++ ldr r0, =CONFIG_ASPEED_COM_IIR
+ mov r1, #0x07
+ str r1, [r0]
+
+- ldr r0, =0x1e784000
++ ldr r0, =CONFIG_ASPEED_COM
+ mov r1, #0x0D @ '\r'
+ str r1, [r0]
+ mov r1, #0x0A @ '\n'
+@@ -575,7 +589,7 @@ delay_2:
+ ******************************************************************************/
+ ddr3_init:
+ /* Debug - UART console message */
+- ldr r0, =0x1e784000
++ ldr r0, =CONFIG_ASPEED_COM
+ mov r1, #0x33 @ '3'
+ str r1, [r0]
+ mov r1, #0x0D @ '\r'
+@@ -764,7 +778,7 @@ delay3_4:
+ ******************************************************************************/
+ ddr2_init:
+ /* Debug - UART console message */
+- ldr r0, =0x1e784000
++ ldr r0, =CONFIG_ASPEED_COM
+ mov r1, #0x32 @ '2'
+ str r1, [r0]
+ mov r1, #0x0D @ '\r'
+@@ -1416,7 +1430,7 @@ init_sram_start3:
+ *****************************************************************************/
+ CBR0_START:
+ /* Debug - UART console message */
+- ldr r0, =0x1e784000
++ ldr r0, =CONFIG_ASPEED_COM
+ mov r1, #0x43 @ 'C'
+ str r1, [r0]
+ mov r1, #0x42 @ 'B'
+@@ -1454,7 +1468,7 @@ cbr0_next_dqidly:
+ bgt CBR0_END
+
+ /* Debug - UART console message */
+- ldr r0, =0x1e784000
++ ldr r0, =CONFIG_ASPEED_COM
+ and r1, r8, #0x07
+ add r1, r1, #0x30 @ '0-7'
+ str r1, [r0]
+@@ -1776,7 +1790,7 @@ delay_5:
+ *****************************************************************************/
+ CBR1_START:
+ /* Debug - UART console message */
+- ldr r0, =0x1e784000
++ ldr r0, =CONFIG_ASPEED_COM
+ mov r1, #0x0D @ '\r'
+ str r1, [r0]
+ mov r1, #0x0A @ '\n'
+@@ -2057,7 +2071,7 @@ cbr1_set_result_end:
+
+ CBR3_START:
+ /* Debug - UART console message */
+- ldr r0, =0x1e784000
++ ldr r0, =CONFIG_ASPEED_COM
+ mov r1, #0x33 @ '3'
+ str r1, [r0]
+ /* Debug - UART console message */
+@@ -2276,7 +2290,7 @@ CBR3_END:
+ *****************************************************************************/
+ CBR4_START:
+ /* Debug - UART console message */
+- ldr r0, =0x1e784000
++ ldr r0, =CONFIG_ASPEED_COM
+ mov r1, #0x34 @ '4'
+ str r1, [r0]
+ /* Debug - UART console message */
+@@ -2556,7 +2570,7 @@ set_scratch:
+ str r1, [r0]
+
+ /* Debug - UART console message */
+- ldr r0, =0x1e784000
++ ldr r0, =CONFIG_ASPEED_COM
+ mov r1, #0x44 @ 'D'
+ str r1, [r0]
+ mov r1, #0x6F @ 'o'
+@@ -2724,11 +2738,13 @@ ECC_Init_Flag:
+ orr r1, r1, #0x08
+ str r1, [r0]
+
++#ifndef CONFIG_ASPEED_ENABLE_JTAG
+ ldr r0, =0x1e6e2004
+ ldr r1, [r0]
+ ldr r2, =0xFFBFFFFF @ Enable JTAG Master, solve ARM stucked by JTAG issue
+ and r1, r1, r2
+ str r1, [r0]
++#endif
+
+ ldr r0, =0x1e6e2048 @ Set MAC interface delay timing
+ ldr r1, =0x2255
+diff --git a/board/aspeed/ast2400/u-boot.lds b/board/aspeed/ast2400/u-boot.lds
+deleted file mode 100755
+index ff0fe22..0000000
+--- a/board/aspeed/ast2400/u-boot.lds
++++ /dev/null
+@@ -1,56 +0,0 @@
+-/*
+- * (C) Copyright 2004
+- * Wolfgang Denk, DENX Software Engineering, <wg@denx.de>
+- *
+- * See file CREDITS for list of people who contributed to this
+- * project.
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License as
+- * published by the Free Software Foundation; either version 2 of
+- * the License, or (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+- * MA 02111-1307 USA
+- */
+-
+-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+-/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
+-OUTPUT_ARCH(arm)
+-ENTRY(_start)
+-SECTIONS
+-{
+- . = 0x00000000;
+-
+- . = ALIGN(4);
+- .text :
+- {
+- cpu/arm926ejs/start.o (.text)
+- *(.text)
+- }
+-
+- . = ALIGN(4);
+- .rodata : { *(.rodata) }
+-
+- . = ALIGN(4);
+- .data : { *(.data) }
+-
+- . = ALIGN(4);
+- .got : { *(.got) }
+-
+- __u_boot_cmd_start = .;
+- .u_boot_cmd : { *(.u_boot_cmd) }
+- __u_boot_cmd_end = .;
+-
+- . = ALIGN(4);
+- __bss_start = .;
+- .bss : { *(.bss) }
+- _end = .;
+-}
+diff --git a/boards.cfg b/boards.cfg
+index 674896b..ce6bff1 100644
+--- a/boards.cfg
++++ b/boards.cfg
+@@ -72,7 +72,7 @@ mini2440 arm arm920t mini2440 friendl
+ VCMA9 arm arm920t vcma9 mpl s3c24x0
+ smdk2410 arm arm920t - samsung s3c24x0
+ omap1510inn arm arm925t - ti
+-ast2400 arm arm926ejs ast2400 aspeed aspeed
++wedge arm arm926ejs ast2400 aspeed aspeed
+ integratorap_cm926ejs arm arm926ejs integrator armltd - integratorap:CM926EJ_S
+ integratorcp_cm926ejs arm arm926ejs integrator armltd - integratorcp:CM924EJ_S
+ aspenite arm arm926ejs - Marvell armada100
+diff --git a/common/cmd_slt.c b/common/cmd_slt.c
+index 9763692..6296416 100644
+--- a/common/cmd_slt.c
++++ b/common/cmd_slt.c
+@@ -9,6 +9,7 @@
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
++#include <common.h>
+ #include <command.h>
+
+ extern int pll_function(int argc, char *argv[]);
+diff --git a/common/env_common.c b/common/env_common.c
+index 906b41f..f5af537 100644
+--- a/common/env_common.c
++++ b/common/env_common.c
+@@ -203,6 +203,9 @@ void env_relocate(void)
+ #else
+ bootstage_error(BOOTSTAGE_ID_NET_CHECKSUM);
+ set_default_env("!bad CRC");
++#ifdef CONFIG_ASPEED_WRITE_DEFAULT_ENV
++ saveenv();
++#endif
+ #endif
+ } else {
+ env_relocate_spec();
+diff --git a/common/image.c b/common/image.c
+index f5ad097..2fc071b 100644
+--- a/common/image.c
++++ b/common/image.c
+@@ -902,6 +902,11 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
+ rd_data = image_get_data(rd_hdr);
+ rd_len = image_get_data_size(rd_hdr);
+ rd_load = image_get_load(rd_hdr);
++#ifdef CONFIG_ASPEED
++ /* Need to copy the initrd into RAM */
++ memmove_wd((void *)rd_load, (void *)rd_data, rd_len, CHUNKSZ);
++ rd_data = rd_load;
++#endif
+ break;
+ #if defined(CONFIG_FIT)
+ case IMAGE_FORMAT_FIT:
+diff --git a/drivers/net/aspeednic.c b/drivers/net/aspeednic.c
+index 6b1ce05..d75ef67 100644
+--- a/drivers/net/aspeednic.c
++++ b/drivers/net/aspeednic.c
+@@ -16,6 +16,7 @@
+ #include <malloc.h>
+ #include <net.h>
+ #include <pci.h>
++#include <linux/mii.h>
+
+
+ /*
+@@ -53,7 +54,6 @@
+ #define MAC1_MDC (1 << 30)
+ #define MAC1_PHY_LINK (1 << 0)
+ #define MAC2_MDC_MDIO (1 << 2)
+-#define MAC1_PHY_LINK (1 << 0)
+ #define MAC2_PHY_LINK (1 << 1)
+ #else
+ #define MAC2_MDC_MDIO (1 << 20)
+@@ -69,6 +69,9 @@ unsigned int aspeednic_iobase[CONFIG_ASPEED_MAC_NUMBER] = {
+ 0x1E660000, 0x1E680000};
+ #endif
+
++/* PHY address */
++static u8 g_phy_addr = 0;
++
+ #undef DEBUG_SROM
+ #undef DEBUG_SROM2
+
+@@ -249,6 +252,7 @@ struct de4x5_desc {
+ #define PHYID_RTL8201EL 0x001cc810
+ #define PHYID_RTL8211 0x001cc910
+ #define PHYID_BCM54612E 0x03625E6A
++#define PHYID_BCM54616S 0x03625D12
+
+ //NCSI define & structure
+ //NC-SI Command Packet
+@@ -410,6 +414,12 @@ static void aspeednic_halt(struct eth_device* dev);
+ static void set_mac_address (struct eth_device* dev, bd_t* bis);
+ static void phy_write_register (struct eth_device* dev, u8 PHY_Register, u8 PHY_Address, u16 PHY_Data);
+ static u16 phy_read_register (struct eth_device* dev, u8 PHY_Register, u8 PHY_Address);
++#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
++static int faraday_mdio_read(const char *devname, uint8_t addr, uint8_t reg,
++ uint16_t *value);
++static int faraday_mdio_write(const char *devname, uint8_t addr, uint8_t reg,
++ uint16_t value);
++#endif
+ static void set_mac_control_register(struct eth_device* dev);
+
+ #if defined(CONFIG_E500)
+@@ -456,7 +466,7 @@ void NCSI_Struct_Initialize(void)
+
+ int aspeednic_initialize(bd_t *bis)
+ {
+- int card_number = 0;
++ int card_number = CONFIG_ASPEED_MAC_CONFIG - 1;
+ unsigned int iobase, SCURegister;
+ struct eth_device* dev;
+
+@@ -538,7 +548,7 @@ int aspeednic_initialize(bd_t *bis)
+
+ dev->iobase = iobase;
+
+- if (CONFIG_MAC1_PHY_SETTING >= 1) {
++ if (CONFIG_ASPEED_MAC_PHY_SETTING >= 1) {
+ //NCSI Struct Initialize
+ NCSI_Struct_Initialize();
+ }
+@@ -556,20 +566,22 @@ int aspeednic_initialize(bd_t *bis)
+ dev->recv = aspeednic_recv;
+
+ /* Ensure we're not sleeping. */
+- if (CONFIG_MAC1_PHY_SETTING >= 1) {
++ if (CONFIG_ASPEED_MAC_PHY_SETTING >= 1) {
+ udelay(2000000); //2.0 sec
+ }
+ else {
+ udelay(10 * 1000);
+ }
+
+-
+ dev->init(dev, bis);
+
+ eth_register(dev);
+
++#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
++ miiphy_register(dev->name, faraday_mdio_read, faraday_mdio_write);
++#endif
+
+- return card_number;
++ return 1;
+ }
+
+ void Calculate_Checksum(unsigned char *buffer_base, int Length)
+@@ -1114,11 +1126,37 @@ void Set_Link (struct eth_device* dev)
+ Retry = 0;
+ }
+
++static void aspeednic_probe_phy(struct eth_device *dev)
++{
++ u8 phy_addr;
++ u16 phy_id;
++
++ /* assume it as 0 */
++ g_phy_addr = 0;
++
++ /* Check if the PHY is up to snuff..., max phy addr is 0x1f */
++ for (phy_addr = 0; phy_addr <= 0x1f; phy_addr++) {
++ phy_id = phy_read_register(dev, MII_PHYSID1, phy_addr);
++ /*
++ * When it is unable to found PHY,
++ * the interface usually return 0xffff or 0x0000
++ */
++ if (phy_id != 0xffff && phy_id != 0x0) {
++ g_phy_addr = phy_addr;
++ break;
++ }
++ }
++ printf("%s: PHY at 0x%02x\n", dev->name, phy_addr);
++}
++
+ static int aspeednic_init(struct eth_device* dev, bd_t* bis)
+ {
+ unsigned long i, Package_Found = 0, Channel_Found = 0, Re_Send = 0, Link_Status;
+
+ RESET_DE4X5(dev);
++
++ aspeednic_probe_phy(dev);
++
+ set_mac_address (dev, bis);
+ set_mac_control_register (dev);
+
+@@ -1149,7 +1187,7 @@ static int aspeednic_init(struct eth_device* dev, bd_t* bis)
+ tx_new = 0;
+ rx_new = 0;
+
+- if (CONFIG_MAC1_PHY_SETTING >= 1) {
++ if (CONFIG_ASPEED_MAC_PHY_SETTING >= 1) {
+ //NCSI Start
+ //DeSelect Package/ Select Package
+ for (i = 0; i < 4; i++) {
+@@ -1313,58 +1351,23 @@ static void aspeednic_halt(struct eth_device* dev)
+
+ static void set_mac_address (struct eth_device* dev, bd_t* bis)
+ {
+- unsigned char mac_address[6]; // 6 bytes mac address
+- unsigned char ethaddress[20]; // string for setenv function
+- char *s;
+- int i, env; // env variable 0: eeprom, 1: environment parameters
+-
+- s = getenv ("eeprom");
+- env = (s && (*s == 'y')) ? 0 : 1;
+-
+- if (env == 0) {
+- env = 1;
+- eeprom_init ();
+- eeprom_read (0xA0, 0, mac_address, 6);
+-
+- for (i = 0; i < 6; i++) {
+- if (mac_address[i] != 0xFF) {
+- env = 0; //Suppose not all 0xFF is valid
+- }
+- }
++ if (!eth_getenv_enetaddr_by_index("eth", 0, dev->enetaddr)) {
++ eth_random_enetaddr(dev->enetaddr);
+ }
+
+- if (env == 0) { // EEPROM
+- sprintf (ethaddress, "%02X:%02X:%02X:%02X:%02X:%02X", mac_address[0], mac_address[1], mac_address[2], mac_address[3], mac_address[4], mac_address[5]);
+- setenv ("ethaddr", ethaddress);
+- OUTL(dev, ((mac_address[2] << 24) | (mac_address[3] << 16) | (mac_address[4] << 8) | mac_address[5]), MAC_LADR_REG);
+- OUTL(dev, ((mac_address[0] << 8) | mac_address[1]), MAC_MADR_REG);
+- if (CONFIG_MAC1_PHY_SETTING >= 1) {
+- for (i = 0; i < 6; i++) {
+- NCSI_Request.SA[i] = mac_address[i];
+- }
+- }
+- }
+- else { // Environment Parameters
+- OUTL(dev, ((bis->bi_enetaddr[2] << 24) | (bis->bi_enetaddr[3] << 16) | (bis->bi_enetaddr[4] << 8) | bis->bi_enetaddr[5]), MAC_LADR_REG);
+- OUTL(dev, ((bis->bi_enetaddr[0] << 8) | bis->bi_enetaddr[1]), MAC_MADR_REG);
+- if (CONFIG_MAC1_PHY_SETTING >= 1) {
+- for (i = 0; i < 6; i++) {
+- NCSI_Request.SA[i] = bis->bi_enetaddr[i];
+- }
+- }
++ OUTL(dev, ((dev->enetaddr[2] << 24) | (dev->enetaddr[3] << 16)
++ | (dev->enetaddr[4] << 8) | dev->enetaddr[5]), MAC_LADR_REG);
++ OUTL(dev, ((dev->enetaddr[0] << 8) | dev->enetaddr[1]), MAC_MADR_REG);
++ if (CONFIG_ASPEED_MAC_PHY_SETTING >= 1) {
++ memcpy(NCSI_Request.SA, dev->enetaddr, 6);
+ }
+-
+ }
+
+-
+ static u16 phy_read_register (struct eth_device* dev, u8 PHY_Register, u8 PHY_Address)
+ {
+ u32 Data, Status = 0, Loop_Count = 0, PHY_Ready = 1;
+ u16 Return_Data;
+
+-#ifdef REALTEK_PHY_SUPPORT
+- PHY_Address = 0x01;
+-#endif
+ //20us * 100 = 2ms > (1 / 2.5Mhz) * 0x34
+ OUTL(dev, (PHY_Register << 21) + (PHY_Address << 16) + MIIRD + MDC_CYCTHR, PHYCR_REG);
+ do {
+@@ -1378,7 +1381,6 @@ static u16 phy_read_register (struct eth_device* dev, u8 PHY_Register, u8 PHY_Ad
+ } while (Status == MIIRD);
+
+ if (PHY_Ready == 0) {
+- printf ("PHY NOT REDAY ");
+ return 0;
+ }
+ Data = INL (dev, PHYDATA_REG);
+@@ -1392,9 +1394,6 @@ static void phy_write_register (struct eth_device* dev, u8 PHY_Register, u8 PHY_
+ {
+ u32 Status = 0, Loop_Count = 0, PHY_Ready = 1;
+
+-#ifdef REALTEK_PHY_SUPPORT
+- PHY_Address = 0x01;
+-#endif
+ //20us * 100 = 2ms > (1 / 2.5Mhz) * 0x34
+ OUTL(dev, PHY_Data, PHYDATA_REG);
+ OUTL(dev, (PHY_Register << 21) + (PHY_Address << 16) + MIIWR + MDC_CYCTHR, PHYCR_REG);
+@@ -1407,31 +1406,66 @@ static void phy_write_register (struct eth_device* dev, u8 PHY_Register, u8 PHY_
+ break;
+ }
+ } while (Status == MIIWR);
+- if (PHY_Ready == 0) {
+- printf ("PHY NOT REDAY ");
++}
++
++#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
++
++static int faraday_mdio_read(
++ const char *devname, uint8_t addr, uint8_t reg, uint16_t *value)
++{
++ int ret = 0;
++ struct eth_device *dev;
++
++ dev = eth_get_dev_by_name(devname);
++ if (dev == NULL) {
++ printf("%s: no such device\n", devname);
++ ret = -1;
++ } else {
++ *value = phy_read_register(dev, reg, addr);
++ }
++
++ return ret;
++}
++
++static int faraday_mdio_write(
++ const char *devname, uint8_t addr, uint8_t reg, uint16_t value)
++{
++ int ret = 0;
++ struct eth_device *dev;
++
++ dev = eth_get_dev_by_name(devname);
++ if (dev == NULL) {
++ printf("%s: no such device\n", devname);
++ ret = -1;
++ } else {
++ phy_write_register(dev, reg, addr, value);
+ }
++
++ return ret;
+ }
+
++#endif /* #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) */
++
+ static void set_mac_control_register (struct eth_device* dev)
+ {
+ unsigned long MAC_CR_Register = 0;
+- unsigned long Loop_Count = 0, PHY_Ready = 1, Chip_ID;
++ unsigned int Loop_Count = 0, PHY_Ready = 1, Chip_ID;
+ u16 PHY_Status, PHY_Speed, PHY_Duplex, Resolved_Status = 0, Advertise, Link_Partner;
+
+- if (CONFIG_MAC1_PHY_SETTING >= 1) {
++ if (CONFIG_ASPEED_MAC_PHY_SETTING >= 1) {
+ MAC_CR_Register = SPEED_100M_MODE_bit | RX_BROADPKT_bit | FULLDUP_bit | RXMAC_EN_bit | RXDMA_EN_bit | TXMAC_EN_bit | TXDMA_EN_bit | CRC_APD_bit;
+ }
+ else {
+ MAC_CR_Register = SPEED_100M_MODE_bit | FULLDUP_bit | RXMAC_EN_bit | RXDMA_EN_bit | TXMAC_EN_bit | TXDMA_EN_bit | CRC_APD_bit;
+ }
+
+- if (CONFIG_MAC1_PHY_SETTING != 2) {
+- Chip_ID = ((phy_read_register (dev, 0x02, 0)) << 16);
+- Chip_ID |= (phy_read_register (dev, 0x03, 0) & 0xffff);
++ if (CONFIG_ASPEED_MAC_PHY_SETTING != 2) {
++ Chip_ID = ((phy_read_register (dev, 0x02, g_phy_addr)) << 16);
++ Chip_ID |= (phy_read_register (dev, 0x03, g_phy_addr) & 0xffff);
+ if (((Chip_ID & PHYID_VENDOR_MASK) == PHYID_VENDOR_BROADCOM) ||
+ ((Chip_ID & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8201EL)) {
+- Advertise = phy_read_register (dev, 0x04, 0);
+- Link_Partner = phy_read_register (dev, 0x05, 0);
++ Advertise = phy_read_register (dev, 0x04, g_phy_addr);
++ Link_Partner = phy_read_register (dev, 0x05, g_phy_addr);
+ Advertise = (Advertise & PHY_SPEED_DUPLEX_MASK);
+ Link_Partner = (Link_Partner & PHY_SPEED_DUPLEX_MASK);
+ if ((Advertise & Link_Partner) & PHY_100M_DUPLEX) {
+@@ -1456,7 +1490,8 @@ static void set_mac_control_register (struct eth_device* dev)
+ //Max waiting time = (20 + 2)ms * 250(PHY_LOOP) = 5.5s
+ do {
+ udelay (20000);
+- Resolved_Status = (phy_read_register (dev, 0x11, 0) & RESOLVED_BIT);
++ Resolved_Status = (phy_read_register (dev, 0x11, g_phy_addr)
++ & RESOLVED_BIT);
+ Loop_Count++;
+ if (Loop_Count >= PHY_LOOP) {
+ PHY_Ready = 0;
+@@ -1466,7 +1501,7 @@ static void set_mac_control_register (struct eth_device* dev)
+ } while (Resolved_Status != RESOLVED_BIT);
+
+ if (PHY_Ready == 1) {
+- PHY_Status = phy_read_register (dev, 0x11, 0);
++ PHY_Status = phy_read_register (dev, 0x11, g_phy_addr);
+ PHY_Speed = (PHY_Status & PHY_SPEED_MASK) >> 14;
+ PHY_Duplex = (PHY_Status & PHY_DUPLEX_MASK) >> 13;
+
+@@ -1485,40 +1520,54 @@ static void set_mac_control_register (struct eth_device* dev)
+ }
+ //LED Control
+ // if (Chip_ID == 0x1C) {
+-// PHY_Status = phy_read_register (dev, 0x18, 0);
+-// phy_write_register (dev, 0x18, 0, (PHY_Status | 0x09));
++// PHY_Status = phy_read_register (dev, 0x18, g_phy_addr);
++// phy_write_register (dev, 0x18, g_phy_addr, (PHY_Status | 0x09));
+ // }
+ //LED Control D[0], D[6]
+ // if (Chip_ID == 0x141) {
+-// PHY_Status = phy_read_register (dev, 0x18, 0);
+-// phy_write_register (dev, 0x18, 0, ((PHY_Status & ~(0x41)) | 0x01));
++// PHY_Status = phy_read_register (dev, 0x18, g_phy_addr);
++// phy_write_register (dev, 0x18, g_phy_addr, ((PHY_Status & ~(0x41)) | 0x01));
+ // }
+ }
+- else if (Chip_ID == PHYID_BCM54612E ) {
+- phy_write_register ( dev, 0x1C, 1, 0x8C00 ); // Disable GTXCLK Clock Delay Enable
+- phy_write_register ( dev, 0x18, 1, 0xF0E7 ); // Disable RGMII RXD to RXC Skew
+-
+- Advertise = phy_read_register (dev, 0x04, 1);
+- Link_Partner = phy_read_register (dev, 0x05, 1);
+- Advertise = (Advertise & PHY_SPEED_DUPLEX_MASK);
+- Link_Partner = (Link_Partner & PHY_SPEED_DUPLEX_MASK);
+- if ((Advertise & Link_Partner) & PHY_100M_DUPLEX) {
+- MAC_CR_Register |= SPEED_100M_MODE_bit;
+- MAC_CR_Register |= FULLDUP_bit;
++ else if (Chip_ID == PHYID_BCM54612E || Chip_ID == PHYID_BCM54616S) {
++ // Disable GTXCLK Clock Delay Enable
++ phy_write_register( dev, 0x1C, g_phy_addr, 0x8C00);
++ // Disable RGMII RXD to RXC Skew
++ phy_write_register( dev, 0x18, g_phy_addr, 0xF0E7);
++ // First Switch shadow register selector
++ phy_write_register(dev, 0x1C, g_phy_addr, 0x2000);
++ PHY_Status = phy_read_register(dev, 0x1C, g_phy_addr);
++ PHY_Duplex = (PHY_Status & 0x0080);
++ switch (PHY_Status & 0x0018) {
++ case 0x0000:
++ PHY_Speed = SPEED_1000M;
++ break;
++ case 0x0008:
++ PHY_Speed = SPEED_100M;
++ break;
++ case 0x0010:
++ PHY_Speed = SPEED_10M;
++ break;
++ default:
++ PHY_Speed = SPEED_100M;
++ break;
+ }
+- else if ((Advertise & Link_Partner) & PHY_100M_HALF) {
+- MAC_CR_Register |= SPEED_100M_MODE_bit;
+- MAC_CR_Register &= ~FULLDUP_bit;
++ if (PHY_Speed == SPEED_1000M) {
++ MAC_CR_Register |= GMAC_MODE_bit;
++ } else {
++ MAC_CR_Register &= ~GMAC_MODE_bit;
++ if (PHY_Speed == SPEED_100M) {
++ MAC_CR_Register |= SPEED_100M_MODE_bit;
++ } else {
++ MAC_CR_Register &= ~SPEED_100M_MODE_bit;
++ }
+ }
+- else if ((Advertise & Link_Partner) & PHY_10M_DUPLEX) {
+- MAC_CR_Register &= ~SPEED_100M_MODE_bit;
++ if (PHY_Duplex) {
+ MAC_CR_Register |= FULLDUP_bit;
+- }
+- else if ((Advertise & Link_Partner) & PHY_10M_HALF) {
+- MAC_CR_Register &= ~SPEED_100M_MODE_bit;
++ } else {
+ MAC_CR_Register &= ~FULLDUP_bit;
+ }
+- }else {
++ } else {
+ printf("Unknow Chip_ID %x\n",Chip_ID);
+ }
+ }
+diff --git a/include/configs/wedge.h b/include/configs/wedge.h
+new file mode 100644
+index 0000000..6bb7639
+--- /dev/null
++++ b/include/configs/wedge.h
+@@ -0,0 +1,350 @@
++/*
++ * Copyright 2004-present Facebook. All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++/* Uncommit the following line to enable JTAG in u-boot */
++//#define CONFIG_ASPEED_ENABLE_JTAG
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++//#define CONFIG_INIT_CRITICAL /* define for U-BOOT 1.1.1 */
++#undef CONFIG_INIT_CRITICAL /* undef for U-BOOT 1.1.4 */
++//#define CONFIG_FPGA_ASPEED 1
++#define CONFIG_ARM926EJS 1 /* This is an arm926ejs CPU */
++#define CONFIG_ASPEED 1
++#define CONFIG_AST2400 1
++//#define CONFIG_AST1070 1
++//#define CONFIG_SYS_FLASH_CFI /* CONFIG_FLASH_CFI, CONFIG_FLASH_SPI is exclusive*/
++#define CONFIG_FLASH_SPI
++//#define CONFIG_2SPIFLASH /* Boot SPI: CS2, 2nd SPI: CS0 */
++#undef CONFIG_2SPIFLASH
++#undef CONFIG_ASPEED_SLT
++#define CONFIG_FLASH_AST2300
++//#define CONFIG_FLASH_AST2300_DMA
++//#define CONFIG_FLASH_SPIx2_Dummy
++//#define CONFIG_FLASH_SPIx4_Dummy
++#define CONFIG_CRT_DISPLAY 1 /* undef if not support CRT */
++
++//#define CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
++#define CONFIG_MISC_INIT_R
++
++/*
++ * DRAM Config
++ *
++ * 1. DRAM Size //
++ * CONFIG_DRAM_512MBIT // 512M bit
++ * CONFIG_DRAM_1GBIT // 1G bit (default)
++ * CONFIG_DRAM_2GBIT // 2G bit
++ * CONFIG_DRAM_4GBIT // 4G bit
++ * 2. DRAM Speed //
++ * CONFIG_DRAM_336 // 336MHz (DDR-667)
++ * CONFIG_DRAM_408 // 408MHz (DDR-800) (default)
++ * 3. VGA Mode
++ * CONFIG_CRT_DISPLAY // define to disable VGA function
++ * 4. ECC Function enable
++ * CONFIG_DRAM_ECC // define to enable ECC function
++ * 5. UART Debug Message
++ * CONFIG_DRAM_UART_OUT // enable output message at UART5
++ * CONFIG_DRAM_UART_38400 // set the UART baud rate to 38400, default is 115200
++ */
++
++//1. DRAM Size
++//#define CONFIG_DRAM_512MBIT
++#define CONFIG_DRAM_1GBIT
++//#define CONFIG_DRAM_2GBIT
++//#define CONFIG_DRAM_4GBIT
++//2. DRAM Speed
++//#define CONFIG_DRAM_336
++#define CONFIG_DRAM_408
++//3. VGA Mode
++//#define CONFIG_CRT_DISPLAY
++//4. ECC Function enable
++//#define CONFIG_DRAM_ECC
++//5. UART Debug Message
++#define CONFIG_DRAM_UART_OUT
++//#define CONFIG_DRAM_UART_38400
++
++
++
++/*
++ * Environment Config
++ */
++#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
++#define CONFIG_SETUP_MEMORY_TAGS 1
++#define CONFIG_INITRD_TAG 1
++#define CONFIG_BOOTARGS "debug console=ttyS2,9600n8 root=/dev/ram rw"
++#define CONFIG_UPDATE "tftp 40800000 ast2400.scr; so 40800000'"
++
++#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
++#define CONFIG_AUTOBOOT_KEYED
++#define CONFIG_AUTOBOOT_PROMPT \
++ "autoboot in %d seconds (stop with 'Delete' key)...\n", bootdelay
++#define CONFIG_AUTOBOOT_STOP_STR "\x1b\x5b\x33\x7e" /* 'Delete', ESC[3~ */
++#define CONFIG_ZERO_BOOTDELAY_CHECK
++
++#ifdef CONFIG_FLASH_AST2300
++#define CONFIG_BOOTCOMMAND "bootm 20080000 20300000"
++#else
++#ifdef CONFIG_SYS_FLASH_CFI
++#define CONFIG_BOOTCOMMAND "bootm 10080000 10300000"
++#else
++#define CONFIG_BOOTCOMMAND "bootm 14080000 14300000"
++#endif
++#endif
++#define CONFIG_BOOTFILE "all.bin"
++#define CONFIG_ENV_OVERWRITE
++
++/*
++ * Command line configuration.
++ */
++#include <config_cmd_default.h>
++
++#define CONFIG_CMD_DFL
++#define CONFIG_CMD_ENV
++#define CONFIG_CMD_FLASH
++#define CONFIG_CMD_MII
++#define CONFIG_CMD_NET
++#define CONFIG_CMD_PING
++#define CONFIG_CMD_I2C
++#define CONFIG_CMD_EEPROM
++#define CONFIG_CMD_NETTEST
++#define CONFIG_CMD_SLT
++
++/*
++ * CPU Setting
++ */
++#define CPU_CLOCK_RATE 18000000 /* 16.5 MHz clock for the ARM core */
++
++/*
++ * Size of malloc() pool
++ */
++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 768*1024)
++#define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
++
++/*
++ * Stack sizes, The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE (128*1024) /* regular stack */
++#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
++
++/*
++ * Memory Configuration
++ */
++#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
++#define PHYS_SDRAM_1 0x40000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE 0x10000000 /* 256 MB */
++
++#define CONFIG_SYS_SDRAM_BASE 0x40000000
++
++/*
++ * FLASH Configuration
++ */
++#ifdef CONFIG_SYS_FLASH_CFI /* NOR Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x10000000 /* Flash Bank #1 */
++#endif
++
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (256) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x60000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
++
++#define CONFIG_SYS_FLASH_CFI_AMD_RESET
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++
++#else /* SPI Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x14000000 /* Flash Bank #1 */
++#define PHYS_FLASH_2 0x14800000 /* Flash Bank #2 */
++#define PHYS_FLASH_2_BASE 0x10000000
++#endif
++
++#ifdef CONFIG_2SPIFLASH
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_2_BASE
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1, PHYS_FLASH_2 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 2
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#else
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x60000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
++#define CONFIG_ASPEED_WRITE_DEFAULT_ENV
++#endif
++
++#endif
++
++#define __LITTLE_ENDIAN 1
++
++#define CONFIG_MONITOR_BASE TEXT_BASE
++#define CONFIG_MONITOR_LEN (192 << 10)
++
++/* timeout values are in ticks */
++#define CONFIG_SYS_FLASH_ERASE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Erase */
++#define CONFIG_SYS_FLASH_WRITE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Write */
++
++/*
++ * Miscellaneous configurable options
++ */
++#define CONFIG_SYS_LONGHELP /* undef to save memory */
++
++#define CONFIG_SYS_PROMPT "boot# " /* Monitor Command Prompt */
++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */
++#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
++
++#define CONFIG_SYS_MEMTEST_START 0x40000000 /* memtest works on */
++#define CONFIG_SYS_MEMTEST_END 0x44FFFFFF /* 256 MB in DRAM */
++
++#define CONFIG_SYS_LOAD_ADDR 0x43000000 /* default load address */
++
++#define CONFIG_SYS_TIMERBASE 0x1E782000 /* use timer 1 */
++#define CONFIG_SYS_HZ 1000
++#define CONFIG_ASPEED_TIMER_CLK (1*1000*1000) /* use external clk (1M) */
++
++/*
++ * Serial Configuration
++ */
++#define CONFIG_SYS_NS16550
++#define CONFIG_SYS_NS16550_SERIAL
++#define CONFIG_SYS_NS16550_MEM32
++#define CONFIG_SYS_NS16550_REG_SIZE -4
++#define CONFIG_SYS_NS16550_CLK 24000000
++#define CONFIG_SYS_NS16550_COM1 0x1e783000
++#define CONFIG_SYS_NS16550_COM2 0x1e784000
++#define CONFIG_SYS_NS16550_COM3 0x1e78e000
++#define CONFIG_SYS_LOADS_BAUD_CHANGE
++#define CONFIG_CONS_INDEX 3
++#define CONFIG_BAUDRATE 9600
++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++#define CONFIG_ASPEED_COM 0x1e78e000 // COM3
++#define CONFIG_ASPEED_COM_IER (CONFIG_ASPEED_COM + 0x4)
++#define CONFIG_ASPEED_COM_IIR (CONFIG_ASPEED_COM + 0x8)
++#define CONFIG_ASPEED_COM_LCR (CONFIG_ASPEED_COM + 0xc)
++
++/*
++ * USB device configuration
++ */
++/*
++#define CONFIG_USB_DEVICE 1
++#define CONFIG_USB_TTY 1
++
++#define CONFIG_USBD_VENDORID 0x1234
++#define CONFIG_USBD_PRODUCTID 0x5678
++#define CONFIG_USBD_MANUFACTURER "Siemens"
++#define CONFIG_USBD_PRODUCT_NAME "SX1"
++*/
++
++/*
++ * I2C configuration
++ */
++#define CONFIG_HARD_I2C
++#define CONFIG_SYS_I2C_SPEED 100000
++#define CONFIG_SYS_I2C_SLAVE 1
++#define CONFIG_DRIVER_ASPEED_I2C
++
++/*
++* EEPROM configuration
++*/
++#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
++#define CONFIG_SYS_I2C_EEPROM_ADDR 0xa0
++
++#define __BYTE_ORDER __LITTLE_ENDIAN
++#define __LITTLE_ENDIAN_BITFIELD
++
++/*
++ * NIC configuration
++ */
++#define CONFIG_ASPEEDNIC
++#define CONFIG_NET_MULTI
++#define CONFIG_MAC1_PHY_LINK_INTERRUPT
++#define CONFIG_MAC2_ENABLE
++#define CONFIG_MAC2_PHY_LINK_INTERRUPT
++/*
++*-------------------------------------------------------------------------------
++* NOTICE: MAC1 and MAC2 now have their own seperate PHY configuration.
++* We use 2 bits for each MAC in the scratch register(D[15:11] in 0x1E6E2040) to
++* inform kernel driver.
++* The meanings of the 2 bits are:
++* 00(0): Dedicated PHY
++* 01(1): ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 10(2): ASPEED's MAC is connected to NC-SI PHY chip directly
++* 11: Reserved
++*
++* We use CONFIG_MAC1_PHY_SETTING and CONFIG_MAC2_PHY_SETTING in U-Boot
++* 0: Dedicated PHY
++* 1: ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 2: ASPEED's MAC is connected to NC-SI PHY chip directly
++* 3: Reserved
++*-------------------------------------------------------------------------------
++*/
++#define CONFIG_MAC1_PHY_SETTING 0
++#define CONFIG_MAC2_PHY_SETTING 0
++#define CONFIG_ASPEED_MAC_NUMBER 2
++#define CONFIG_ASPEED_MAC_CONFIG 2 // config MAC2
++#define _PHY_SETTING_CONCAT(mac) CONFIG_MAC##mac##_PHY_SETTING
++#define _GET_MAC_PHY_SETTING(mac) _PHY_SETTING_CONCAT(mac)
++#define CONFIG_ASPEED_MAC_PHY_SETTING \
++ _GET_MAC_PHY_SETTING(CONFIG_ASPEED_MAC_CONFIG)
++#define CONFIG_MAC_INTERFACE_CLOCK_DELAY 0x2255
++#define CONFIG_RANDOM_MACADDR
++//#define CONFIG_GATEWAYIP 192.168.0.1
++//#define CONFIG_NETMASK 255.255.255.0
++//#define CONFIG_IPADDR 192.168.0.45
++//#define CONFIG_SERVERIP 192.168.0.81
++
++/*
++ * SLT
++ */
++/*
++#define CONFIG_SLT
++#define CFG_CMD_SLT (CFG_CMD_VIDEOTEST | CFG_CMD_MACTEST | CFG_CMD_HACTEST | CFG_CMD_MICTEST)
++*/
++
++#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x1000 - GENERATED_GBL_DATA_SIZE)
++
++#define CONFIG_ASPEED_ENABLE_WATCHDOG
++#define CONFIG_ASPEED_WATCHDOG_TIMEOUT (5*60) // 5m
++
++#endif /* __CONFIG_H */
diff --git a/meta-aspeed/recipes-bsp/u-boot/u-boot-fw-utils_2013.07%.bbappend b/meta-aspeed/recipes-bsp/u-boot/u-boot-fw-utils_2013.07%.bbappend
new file mode 100644
index 0000000..c93571b
--- /dev/null
+++ b/meta-aspeed/recipes-bsp/u-boot/u-boot-fw-utils_2013.07%.bbappend
@@ -0,0 +1,5 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+SRC_URI += "file://patch-2013.07/0000-u-boot-aspeed-064.patch \
+ file://patch-2013.07/0001-u-boot-openbmc.patch \
+ "
diff --git a/meta-aspeed/recipes-bsp/u-boot/u-boot_2013.07%.bbappend b/meta-aspeed/recipes-bsp/u-boot/u-boot_2013.07%.bbappend
new file mode 100644
index 0000000..d4e347b
--- /dev/null
+++ b/meta-aspeed/recipes-bsp/u-boot/u-boot_2013.07%.bbappend
@@ -0,0 +1,12 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+SRC_URI += "file://fw_env.config \
+ file://patch-2013.07/0000-u-boot-aspeed-064.patch \
+ file://patch-2013.07/0001-u-boot-openbmc.patch \
+ "
+
+# Do not install u-boot in rootfs
+do_install[postfuncs] += "remove_uboot_from_rootfs"
+remove_uboot_from_rootfs() {
+ rm -rf ${D}/boot/u-boot*
+}
diff --git a/meta-aspeed/recipes-core/images/aspeed-dev.inc b/meta-aspeed/recipes-core/images/aspeed-dev.inc
new file mode 100644
index 0000000..ea3d97f
--- /dev/null
+++ b/meta-aspeed/recipes-core/images/aspeed-dev.inc
@@ -0,0 +1,5 @@
+
+# linux 2.6.28 does not support devtmpfs, manually populate dev
+USE_DEVFS = "0"
+
+IMAGE_DEVICE_TABLES += "recipes-core/images/files/aspeed_device_table" \ No newline at end of file
diff --git a/meta-aspeed/recipes-core/images/files/aspeed_device_table b/meta-aspeed/recipes-core/images/files/aspeed_device_table
new file mode 100644
index 0000000..fac26b9
--- /dev/null
+++ b/meta-aspeed/recipes-core/images/files/aspeed_device_table
@@ -0,0 +1,41 @@
+#<path> <type> <mode> <uid> <gid> <major> <minor> <start> <inc> <count>
+#/dev/mem c 640 0 0 1 1 0 0 -
+#
+#type can be one of:
+# f A regular file
+# d Directory
+# c Character special device file
+# b Block special device file
+# p Fifo (named pipe)
+
+/dev d 755 root root - - - - -
+/dev/console c 662 root tty 5 1 - - -
+/dev/fb0 c 600 root root 29 0 - - -
+/dev/hda b 660 root disk 3 0 - - -
+/dev/hda b 660 root disk 3 1 1 1 4
+/dev/kmem c 640 root kmem 1 2 - - -
+/dev/kmsg c 600 root root 1 11 - - -
+/dev/mem c 640 root kmem 1 1 - - -
+/dev/mmcblk0 b 660 root disk 179 0 - - -
+/dev/mmcblk0p b 660 root disk 179 1 1 1 4
+/dev/mtd c 660 root disk 90 0 0 2 8
+/dev/mtdblock b 640 root root 31 0 0 1 8
+/dev/null c 666 root root 1 3 - - -
+/dev/ram b 640 root root 1 0 0 1 4
+/dev/random c 644 root root 1 8 - - -
+/dev/rtc c 644 root root 254 0 0 1 2
+/dev/sda b 660 root disk 8 0 - - -
+/dev/sda b 660 root disk 8 1 1 1 4
+/dev/sdb b 660 root disk 8 16 - - -
+/dev/sdb b 660 root disk 8 17 1 1 4
+/dev/tty c 662 root tty 5 0 - - -
+/dev/tty c 666 root tty 4 0 0 1 8
+/dev/ttyS c 666 root tty 4 64 0 1 5
+/dev/ttyGS c 666 root tty 253 0 0 1 1
+/dev/urandom c 644 root root 1 9 - - -
+/dev/watchdog c 660 root root 10 130 - - -
+/dev/zero c 644 root root 1 5 - - -
+/dev/i2c- c 600 root root 89 0 0 1 10
+/dev/i2c- c 600 root root 89 11 11 1 2
+/dev/net d 755 root root - - - - -
+/dev/net/tun c 600 root root 10 200 - - -
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0000-linux-aspeed-064.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0000-linux-aspeed-064.patch
new file mode 100644
index 0000000..903cd75
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0000-linux-aspeed-064.patch
@@ -0,0 +1,50917 @@
+diff --git a/Documentation/spi/Makefile b/Documentation/spi/Makefile
+index a5b03c8..6155d94 100644
+--- a/Documentation/spi/Makefile
++++ b/Documentation/spi/Makefile
+@@ -1,6 +1,7 @@
+ # kbuild trick to avoid linker error. Can be omitted if a module is built.
+ obj- := dummy.o
+
++CC = $(CROSS_COMPILE)gcc
+ # List of programs to build
+ hostprogs-y := spidev_test spidev_fdx
+
+diff --git a/Makefile b/Makefile
+index 17bfe08..9ca7825 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1670,3 +1670,16 @@ FORCE:
+ # Declare the contents of the .PHONY variable as phony. We keep that
+ # information in a variable se we can use it in if_changed and friends.
+ .PHONY: $(PHONY)
++
++pub:
++ cp arch/arm/boot/uImage /tftpboot/
++
++m68:
++ m68k-uclinux-objcopy vmlinux -O binary uc.bin
++ mv uc.bin /tftpboot/
++
++opub:
++ cp arch/arm/boot/Image .
++ gzip -f -9 Image
++ mkimage -A arm -O linux -T kernel -C gzip -a 40008000 -e 40008000 -d Image.gz uImage
++ cp uImage /tftpboot/
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index 9722f8b..71db83f 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -199,6 +199,14 @@ choice
+ prompt "ARM system type"
+ default ARCH_VERSATILE
+
++config ARCH_ASPEED
++ bool "ASPEED AST Family"
++ select ARM_AMBA
++ select PLAT_ASPEED
++ select GENERIC_GPIO
++ select ARCH_REQUIRE_GPIOLIB
++
++
+ config ARCH_AAEC2000
+ bool "Agilent AAEC-2000 based"
+ select ARM_AMBA
+@@ -551,6 +559,8 @@ config ARCH_MSM
+
+ endchoice
+
++source "arch/arm/mach-aspeed/Kconfig"
++
+ source "arch/arm/mach-clps711x/Kconfig"
+
+ source "arch/arm/mach-ep93xx/Kconfig"
+@@ -637,6 +647,9 @@ config PLAT_IOP
+ config PLAT_ORION
+ bool
+
++config PLAT_ASPEED
++ bool
++
+ source arch/arm/mm/Kconfig
+
+ config IWMMXT
+diff --git a/arch/arm/Makefile b/arch/arm/Makefile
+index bd6e281..b039927 100644
+--- a/arch/arm/Makefile
++++ b/arch/arm/Makefile
+@@ -144,6 +144,8 @@ endif
+ machine-$(CONFIG_ARCH_MSM) := msm
+ machine-$(CONFIG_ARCH_LOKI) := loki
+ machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0
++ machine-$(CONFIG_ARCH_ASPEED) := aspeed
++ plat-$(CONFIG_PLAT_ASPEED) := aspeed
+
+ ifeq ($(CONFIG_ARCH_EBSA110),y)
+ # This is what happens if you forget the IOCS16 line.
+diff --git a/arch/arm/configs/ast2300_ast1070_defconfig b/arch/arm/configs/ast2300_ast1070_defconfig
+new file mode 100644
+index 0000000..2285e61
+--- /dev/null
++++ b/arch/arm/configs/ast2300_ast1070_defconfig
+@@ -0,0 +1,1037 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.28.9
++# Fri Nov 1 16:40:08 2013
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++# CONFIG_GENERIC_TIME is not set
++# CONFIG_GENERIC_CLOCKEVENTS is not set
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=16
++# CONFIG_CGROUPS is not set
++# CONFIG_GROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++CONFIG_KALLSYMS_EXTRA_PASS=y
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++CONFIG_COMPAT_BRK=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_ARCH_ASPEED=y
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM is not set
++CONFIG_IRMP=y
++# CONFIG_PCEXT is not set
++# CONFIG_REMOTEFX is not set
++# CONFIG_ARCH_AST1100 is not set
++# CONFIG_ARCH_AST2100 is not set
++# CONFIG_ARCH_AST2200 is not set
++CONFIG_ARCH_AST2300=y
++# CONFIG_ARCH_AST2400 is not set
++# CONFIG_ARCH_AST2500 is not set
++
++#
++# FLASH Chip Select
++#
++CONFIG_AST_CS0_NOR=y
++# CONFIG_AST_CS0_NAND is not set
++# CONFIG_AST_CS0_SPI is not set
++# CONFIG_AST_CS0_NONE is not set
++CONFIG_AST_CS1_NOR=y
++# CONFIG_AST_CS1_NAND is not set
++# CONFIG_AST_CS1_SPI is not set
++# CONFIG_AST_CS1_NONE is not set
++CONFIG_AST_CS2_NOR=y
++# CONFIG_AST_CS2_NAND is not set
++# CONFIG_AST_CS2_SPI is not set
++# CONFIG_AST_CS2_NONE is not set
++CONFIG_AST_CS3_NOR=y
++# CONFIG_AST_CS3_NAND is not set
++# CONFIG_AST_CS3_SPI is not set
++# CONFIG_AST_CS3_NONE is not set
++CONFIG_AST_CS4_NOR=y
++# CONFIG_AST_CS4_NAND is not set
++# CONFIG_AST_CS4_SPI is not set
++# CONFIG_AST_CS4_NONE is not set
++CONFIG_ARCH_AST1070=y
++CONFIG_AST1070_NR=1
++# CONFIG_AST_LPC_PLUS is not set
++CONFIG_AST_LPC=y
++# CONFIG_AST_SCU_LOCK is not set
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++CONFIG_PLAT_ASPEED=y
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_NOIFAR=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++# CONFIG_OUTER_CACHE is not set
++
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++# CONFIG_AEABI is not set
++CONFIG_ARCH_FLATMEM_HAS_HOLES=y
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_UNEVICTABLE_LRU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++CONFIG_CMDLINE=""
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++CONFIG_FPE_NWFPE_XP=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_VFP=y
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
++CONFIG_BINFMT_AOUT=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++
++#
++# Power management options
++#
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++CONFIG_PM_SLEEP=y
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_APM_EMULATION is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++CONFIG_WAN_ROUTER=y
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++# CONFIG_PHONET is not set
++# CONFIG_WIRELESS is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_SYS_HYPERVISOR is not set
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++# CONFIG_MTD is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++CONFIG_BLK_DEV_NBD=m
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=16384
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ICS932S401 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_C2PORT is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++CONFIG_SCSI_TGT=y
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++CONFIG_SCSI_SCAN_ASYNC=y
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++CONFIG_SCSI_ISCSI_ATTRS=m
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_NET_ETHERNET is not set
++CONFIG_NETDEV_1000=y
++CONFIG_ASPEEDMAC=y
++# CONFIG_MAC0_PHY_LINK is not set
++# CONFIG_NETDEV_10000 is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++# CONFIG_IWLWIFI_LEDS is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_GPIO is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_ELANTECH is not set
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++CONFIG_MOUSE_SERIAL=y
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_AMBAKMI is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++CONFIG_DEVKMEM=y
++CONFIG_SERIAL_NONSTANDARD=y
++# CONFIG_N_HDLC is not set
++# CONFIG_RISCOM8 is not set
++# CONFIG_SPECIALIX is not set
++# CONFIG_RIO is not set
++# CONFIG_STALDRV is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=3
++CONFIG_SERIAL_8250_RUNTIME_UARTS=3
++CONFIG_SERIAL_AST_DMA_UART=y
++CONFIG_AST_NR_DMA_UARTS=8
++CONFIG_AST_RUNTIME_DMA_UARTS=8
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++# CONFIG_SERIAL_AMBA_PL011 is not set
++# CONFIG_SERIAL_AST is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_AST_MISC is not set
++# CONFIG_HW_RANDOM is not set
++CONFIG_NVRAM=y
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_HELPER_AUTO=y
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++CONFIG_I2C_AST=y
++CONFIG_I2C_AST1070=y
++CONFIG_AST_I2C_SLAVE_MODE=y
++CONFIG_AST_I2C_SLAVE_EEPROM=y
++# CONFIG_AST_I2C_SLAVE_RDWR is not set
++# CONFIG_I2C_SIMTEC is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_STUB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++# CONFIG_AT24 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_PCF8575 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++# CONFIG_SPI is not set
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO expanders:
++#
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++# CONFIG_THERMAL_HWMON is not set
++# CONFIG_WATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM8350_I2C is not set
++
++#
++# Multimedia devices
++#
++
++#
++# Multimedia core support
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_VIDEO_MEDIA is not set
++
++#
++# Multimedia drivers
++#
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_SOUND is not set
++# CONFIG_HID_SUPPORT is not set
++# CONFIG_USB_SUPPORT is not set
++# CONFIG_MMC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++# CONFIG_RTC_CLASS is not set
++# CONFIG_DMADEVICES is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++CONFIG_EXT2_FS_XATTR=y
++CONFIG_EXT2_FS_POSIX_ACL=y
++CONFIG_EXT2_FS_SECURITY=y
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4_FS is not set
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_FILE_LOCKING=y
++# CONFIG_XFS_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++CONFIG_GENERIC_ACL=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=y
++# CONFIG_NTFS_DEBUG is not set
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=m
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_NFS_V4 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_REGISTER_V4 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf8"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++CONFIG_NLS_CODEPAGE_936=y
++CONFIG_NLS_CODEPAGE_950=y
++CONFIG_NLS_CODEPAGE_932=y
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++# CONFIG_ENABLE_WARN_DEPRECATED is not set
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_MEMORY_INIT=y
++CONFIG_FRAME_POINTER=y
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_LATENCYTOP is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++
++#
++# Tracers
++#
++# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++# CONFIG_CRYPTO_FIPS is not set
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD=m
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_NULL=y
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_AUTHENC=m
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++# CONFIG_CRYPTO_ECB is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_XCBC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++CONFIG_CRYPTO_SHA1=y
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=m
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++# CONFIG_CRYPTO_HW is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++CONFIG_CRC_ITU_T=m
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff --git a/arch/arm/configs/ast2300_defconfig b/arch/arm/configs/ast2300_defconfig
+new file mode 100644
+index 0000000..5ac2120
+--- /dev/null
++++ b/arch/arm/configs/ast2300_defconfig
+@@ -0,0 +1,1464 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.28.9
++# Wed Aug 7 16:52:42 2013
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++# CONFIG_GENERIC_TIME is not set
++# CONFIG_GENERIC_CLOCKEVENTS is not set
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=16
++# CONFIG_CGROUPS is not set
++# CONFIG_GROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++CONFIG_KALLSYMS_EXTRA_PASS=y
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++CONFIG_COMPAT_BRK=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_ARCH_ASPEED=y
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM is not set
++CONFIG_IRMP=y
++# CONFIG_PCEXT is not set
++# CONFIG_REMOTEFX is not set
++# CONFIG_ARCH_AST1100 is not set
++# CONFIG_ARCH_AST2100 is not set
++# CONFIG_ARCH_AST2200 is not set
++CONFIG_ARCH_AST2300=y
++# CONFIG_ARCH_AST2400 is not set
++# CONFIG_ARCH_AST2500 is not set
++
++#
++# FLASH Chip Select
++#
++CONFIG_AST_CS0_NOR=y
++# CONFIG_AST_CS0_NAND is not set
++# CONFIG_AST_CS0_SPI is not set
++# CONFIG_AST_CS0_NONE is not set
++CONFIG_AST_CS1_NOR=y
++# CONFIG_AST_CS1_NAND is not set
++# CONFIG_AST_CS1_SPI is not set
++# CONFIG_AST_CS1_NONE is not set
++CONFIG_AST_CS2_NOR=y
++# CONFIG_AST_CS2_NAND is not set
++# CONFIG_AST_CS2_SPI is not set
++# CONFIG_AST_CS2_NONE is not set
++CONFIG_AST_CS3_NOR=y
++# CONFIG_AST_CS3_NAND is not set
++# CONFIG_AST_CS3_SPI is not set
++# CONFIG_AST_CS3_NONE is not set
++CONFIG_AST_CS4_NOR=y
++# CONFIG_AST_CS4_NAND is not set
++# CONFIG_AST_CS4_SPI is not set
++# CONFIG_AST_CS4_NONE is not set
++# CONFIG_ARCH_AST1070 is not set
++# CONFIG_AST_SCU_LOCK is not set
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++CONFIG_PLAT_ASPEED=y
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_NOIFAR=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++# CONFIG_OUTER_CACHE is not set
++
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++# CONFIG_AEABI is not set
++CONFIG_ARCH_FLATMEM_HAS_HOLES=y
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_UNEVICTABLE_LRU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++CONFIG_CMDLINE=""
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++CONFIG_FPE_NWFPE_XP=y
++# CONFIG_FPE_FASTFPE is not set
++# CONFIG_VFP is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
++CONFIG_BINFMT_AOUT=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++
++#
++# Power management options
++#
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++CONFIG_PM_SLEEP=y
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_APM_EMULATION is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++CONFIG_XFRM_IPCOMP=m
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=m
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++CONFIG_IPV6=m
++CONFIG_IPV6_PRIVACY=y
++CONFIG_IPV6_ROUTER_PREF=y
++CONFIG_IPV6_ROUTE_INFO=y
++CONFIG_IPV6_OPTIMISTIC_DAD=y
++CONFIG_INET6_AH=m
++CONFIG_INET6_ESP=m
++CONFIG_INET6_IPCOMP=m
++CONFIG_IPV6_MIP6=m
++CONFIG_INET6_XFRM_TUNNEL=m
++CONFIG_INET6_TUNNEL=m
++CONFIG_INET6_XFRM_MODE_TRANSPORT=m
++CONFIG_INET6_XFRM_MODE_TUNNEL=m
++CONFIG_INET6_XFRM_MODE_BEET=m
++CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
++CONFIG_IPV6_SIT=m
++CONFIG_IPV6_NDISC_NODETYPE=y
++CONFIG_IPV6_TUNNEL=m
++CONFIG_IPV6_MULTIPLE_TABLES=y
++CONFIG_IPV6_SUBTREES=y
++# CONFIG_IPV6_MROUTE is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++CONFIG_WAN_ROUTER=y
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++# CONFIG_PHONET is not set
++CONFIG_FIB_RULES=y
++# CONFIG_WIRELESS is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_SYS_HYPERVISOR is not set
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_CONCAT=y
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++CONFIG_MTD_DATAFLASH=y
++# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
++# CONFIG_MTD_DATAFLASH_OTP is not set
++CONFIG_MTD_M25P80=y
++CONFIG_M25PXX_USE_FAST_READ=y
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++CONFIG_MTD_NAND=y
++# CONFIG_MTD_NAND_VERIFY_WRITE is not set
++# CONFIG_MTD_NAND_ECC_SMC is not set
++# CONFIG_MTD_NAND_MUSEUM_IDS is not set
++CONFIG_MTD_NAND_AST=y
++# CONFIG_MTD_NAND_GPIO is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++# CONFIG_MTD_ALAUDA is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++CONFIG_BLK_DEV_NBD=m
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=16384
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ICS932S401 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_C2PORT is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++CONFIG_SCSI_TGT=y
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++CONFIG_SCSI_SCAN_ASYNC=y
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++CONFIG_SCSI_ISCSI_ATTRS=m
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++CONFIG_BONDING=y
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_NET_ETHERNET is not set
++CONFIG_NETDEV_1000=y
++CONFIG_ASPEEDMAC=y
++CONFIG_MAC0_PHY_LINK=y
++# CONFIG_NETDEV_10000 is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++# CONFIG_IWLWIFI_LEDS is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_GPIO is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_ELANTECH is not set
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++CONFIG_MOUSE_SERIAL=y
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_BCM5974 is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_AMBAKMI is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++CONFIG_DEVKMEM=y
++CONFIG_SERIAL_NONSTANDARD=y
++# CONFIG_N_HDLC is not set
++# CONFIG_RISCOM8 is not set
++# CONFIG_SPECIALIX is not set
++# CONFIG_RIO is not set
++# CONFIG_STALDRV is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=2
++CONFIG_SERIAL_8250_RUNTIME_UARTS=2
++# CONFIG_SERIAL_AST_DMA_UART is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++# CONFIG_SERIAL_AMBA_PL011 is not set
++# CONFIG_SERIAL_AST is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_AST_MISC is not set
++# CONFIG_HW_RANDOM is not set
++CONFIG_NVRAM=y
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_HELPER_AUTO=y
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++# CONFIG_I2C_AST is not set
++# CONFIG_I2C_SIMTEC is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_STUB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++CONFIG_AT24=y
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_PCF8575 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
++
++#
++# SPI Master Controller Drivers
++#
++# CONFIG_SPI_AST is not set
++CONFIG_SPI_FMC=y
++CONFIG_SPI_BITBANG=y
++
++#
++# SPI Protocol Masters
++#
++# CONFIG_SPI_AT25 is not set
++# CONFIG_SPI_SPIDEV is not set
++# CONFIG_SPI_TLE62X0 is not set
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO expanders:
++#
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_AD7414 is not set
++# CONFIG_SENSORS_AD7418 is not set
++# CONFIG_SENSORS_ADCXX is not set
++# CONFIG_SENSORS_ADM1021 is not set
++# CONFIG_SENSORS_ADM1025 is not set
++# CONFIG_SENSORS_ADM1026 is not set
++# CONFIG_SENSORS_ADM1029 is not set
++# CONFIG_SENSORS_ADM1031 is not set
++# CONFIG_SENSORS_ADM9240 is not set
++# CONFIG_SENSORS_ADT7462 is not set
++# CONFIG_SENSORS_ADT7470 is not set
++# CONFIG_SENSORS_ADT7473 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_F75375S is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_LM63 is not set
++# CONFIG_SENSORS_LM70 is not set
++# CONFIG_SENSORS_LM75 is not set
++# CONFIG_SENSORS_LM77 is not set
++# CONFIG_SENSORS_LM78 is not set
++# CONFIG_SENSORS_LM80 is not set
++# CONFIG_SENSORS_LM83 is not set
++# CONFIG_SENSORS_LM85 is not set
++# CONFIG_SENSORS_LM87 is not set
++# CONFIG_SENSORS_LM90 is not set
++# CONFIG_SENSORS_LM92 is not set
++# CONFIG_SENSORS_LM93 is not set
++# CONFIG_SENSORS_MAX1111 is not set
++# CONFIG_SENSORS_MAX1619 is not set
++# CONFIG_SENSORS_MAX6650 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_DME1737 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_ADS7828 is not set
++# CONFIG_SENSORS_THMC50 is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_W83781D is not set
++# CONFIG_SENSORS_W83791D is not set
++# CONFIG_SENSORS_W83792D is not set
++# CONFIG_SENSORS_W83793 is not set
++# CONFIG_SENSORS_W83L785TS is not set
++# CONFIG_SENSORS_W83L786NG is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++# CONFIG_SENSORS_AST_ADC is not set
++CONFIG_SENSORS_AST_PWM_FAN=y
++# CONFIG_HWMON_DEBUG_CHIP is not set
++# CONFIG_THERMAL is not set
++# CONFIG_THERMAL_HWMON is not set
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++# CONFIG_AST_WATCHDOG is not set
++
++#
++# USB-based Watchdog Cards
++#
++# CONFIG_USBPCWATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM8350_I2C is not set
++
++#
++# Multimedia devices
++#
++
++#
++# Multimedia core support
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_VIDEO_MEDIA is not set
++
++#
++# Multimedia drivers
++#
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_SOUND is not set
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++CONFIG_HID_DEBUG=y
++# CONFIG_HIDRAW is not set
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++# CONFIG_HID_PID is not set
++# CONFIG_USB_HIDDEV is not set
++
++#
++# Special HID drivers
++#
++CONFIG_HID_COMPAT=y
++CONFIG_HID_A4TECH=y
++CONFIG_HID_APPLE=y
++CONFIG_HID_BELKIN=y
++CONFIG_HID_BRIGHT=y
++CONFIG_HID_CHERRY=y
++CONFIG_HID_CHICONY=y
++CONFIG_HID_CYPRESS=y
++CONFIG_HID_DELL=y
++CONFIG_HID_EZKEY=y
++CONFIG_HID_GYRATION=y
++CONFIG_HID_LOGITECH=y
++# CONFIG_LOGITECH_FF is not set
++# CONFIG_LOGIRUMBLEPAD2_FF is not set
++CONFIG_HID_MICROSOFT=y
++CONFIG_HID_MONTEREY=y
++CONFIG_HID_PANTHERLORD=y
++# CONFIG_PANTHERLORD_FF is not set
++CONFIG_HID_PETALYNX=y
++CONFIG_HID_SAMSUNG=y
++CONFIG_HID_SONY=y
++CONFIG_HID_SUNPLUS=y
++# CONFIG_THRUSTMASTER_FF is not set
++# CONFIG_ZEROPLUS_FF is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++# CONFIG_USB_ARCH_HAS_OHCI is not set
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=y
++# CONFIG_USB_DEBUG is not set
++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_SUSPEND is not set
++# CONFIG_USB_OTG is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++# CONFIG_USB_EHCI_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_HWA_HCD is not set
++
++#
++# AST USB Drivers
++#
++CONFIG_AST_USB_UHCI_HCD=y
++# CONFIG_AST_USB_UHCI_MULTIPORT_1 is not set
++# CONFIG_AST_USB_UHCI_MULTIPORT_2 is not set
++CONFIG_AST_USB_UHCI_MULTIPORT_4=y
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
++#
++
++#
++# see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=y
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_VST is not set
++# CONFIG_USB_GADGET is not set
++CONFIG_MMC=y
++# CONFIG_MMC_DEBUG is not set
++# CONFIG_MMC_UNSAFE_RESUME is not set
++
++#
++# MMC/SD/SDIO Card Drivers
++#
++CONFIG_MMC_BLOCK=y
++CONFIG_MMC_BLOCK_BOUNCE=y
++# CONFIG_SDIO_UART is not set
++# CONFIG_MMC_TEST is not set
++
++#
++# MMC/SD/SDIO Host Controller Drivers
++#
++# CONFIG_MMC_ARMMMCI is not set
++# CONFIG_MMC_SDHCI is not set
++# CONFIG_MMC_AST is not set
++# CONFIG_MMC_SPI is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++# CONFIG_RTC_HCTOSYS is not set
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++# CONFIG_RTC_DRV_DS1307 is not set
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++
++#
++# SPI RTC drivers
++#
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
++# CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_PL030 is not set
++# CONFIG_RTC_DRV_PL031 is not set
++CONFIG_RTC_DRV_ASPEED=y
++# CONFIG_DMADEVICES is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++CONFIG_EXT2_FS_XATTR=y
++CONFIG_EXT2_FS_POSIX_ACL=y
++CONFIG_EXT2_FS_SECURITY=y
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4_FS is not set
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_FILE_LOCKING=y
++# CONFIG_XFS_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++CONFIG_GENERIC_ACL=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=y
++# CONFIG_NTFS_DEBUG is not set
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=m
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_YAFFS_FS=y
++CONFIG_YAFFS_YAFFS1=y
++# CONFIG_YAFFS_9BYTE_TAGS is not set
++# CONFIG_YAFFS_DOES_ECC is not set
++CONFIG_YAFFS_YAFFS2=y
++CONFIG_YAFFS_AUTO_YAFFS2=y
++# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set
++# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
++# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
++# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
++CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
++# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set
++# CONFIG_JFFS2_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_NFS_V4 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_REGISTER_V4 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf8"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++CONFIG_NLS_CODEPAGE_936=y
++CONFIG_NLS_CODEPAGE_950=y
++CONFIG_NLS_CODEPAGE_932=y
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++# CONFIG_ENABLE_WARN_DEPRECATED is not set
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_MEMORY_INIT=y
++CONFIG_FRAME_POINTER=y
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_LATENCYTOP is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++
++#
++# Tracers
++#
++# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++# CONFIG_CRYPTO_FIPS is not set
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD=m
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_NULL=y
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_AUTHENC=m
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++# CONFIG_CRYPTO_ECB is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_XCBC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++CONFIG_CRYPTO_SHA1=y
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=m
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++# CONFIG_CRYPTO_HW is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++CONFIG_CRC_ITU_T=m
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff --git a/arch/arm/configs/ast2300_fb_defconfig b/arch/arm/configs/ast2300_fb_defconfig
+new file mode 100644
+index 0000000..817e089
+--- /dev/null
++++ b/arch/arm/configs/ast2300_fb_defconfig
+@@ -0,0 +1,1514 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.28.9
++# Thu Jan 10 10:44:05 2013
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++# CONFIG_GENERIC_TIME is not set
++# CONFIG_GENERIC_CLOCKEVENTS is not set
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=16
++# CONFIG_CGROUPS is not set
++# CONFIG_GROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++CONFIG_KALLSYMS_EXTRA_PASS=y
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++CONFIG_COMPAT_BRK=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_ARCH_ASPEED=y
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM is not set
++CONFIG_IRMP=y
++# CONFIG_PCEXT is not set
++# CONFIG_REMOTEFX is not set
++# CONFIG_ARCH_AST1100 is not set
++# CONFIG_ARCH_AST2100 is not set
++# CONFIG_ARCH_AST2200 is not set
++CONFIG_ARCH_AST2300=y
++# CONFIG_ARCH_AST2400 is not set
++
++#
++# FLASH Chip Select
++#
++# CONFIG_ASPEED_CS0_NOR is not set
++# CONFIG_ASPEED_CS0_NAND is not set
++CONFIG_ASPEED_CS0_SPI=y
++# CONFIG_ASPEED_CS0_NONE is not set
++# CONFIG_ASPEED_CS1_NOR is not set
++# CONFIG_ASPEED_CS1_NAND is not set
++# CONFIG_ASPEED_CS1_SPI is not set
++CONFIG_ASPEED_CS1_NONE=y
++# CONFIG_ASPEED_CS2_NOR is not set
++# CONFIG_ASPEED_CS2_NAND is not set
++# CONFIG_ASPEED_CS2_SPI is not set
++CONFIG_ASPEED_CS2_NONE=y
++# CONFIG_ASPEED_CS3_NOR is not set
++# CONFIG_ASPEED_CS3_NAND is not set
++# CONFIG_ASPEED_CS3_SPI is not set
++CONFIG_ASPEED_CS3_NONE=y
++# CONFIG_ASPEED_CS4_NOR is not set
++CONFIG_ASPEED_CS4_NAND=y
++# CONFIG_ASPEED_CS4_SPI is not set
++# CONFIG_ASPEED_CS4_NONE is not set
++# CONFIG_ARCH_AST1070 is not set
++# CONFIG_ASPEED_SCU_LOCK is not set
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++CONFIG_PLAT_ASPEED=y
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_NOIFAR=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++# CONFIG_OUTER_CACHE is not set
++
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++# CONFIG_AEABI is not set
++CONFIG_ARCH_FLATMEM_HAS_HOLES=y
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_UNEVICTABLE_LRU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++CONFIG_CMDLINE=""
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++CONFIG_FPE_NWFPE_XP=y
++# CONFIG_FPE_FASTFPE is not set
++# CONFIG_VFP is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
++CONFIG_BINFMT_AOUT=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++
++#
++# Power management options
++#
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++CONFIG_PM_SLEEP=y
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_APM_EMULATION is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++CONFIG_XFRM_IPCOMP=m
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=m
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++CONFIG_IPV6=m
++CONFIG_IPV6_PRIVACY=y
++CONFIG_IPV6_ROUTER_PREF=y
++CONFIG_IPV6_ROUTE_INFO=y
++CONFIG_IPV6_OPTIMISTIC_DAD=y
++CONFIG_INET6_AH=m
++CONFIG_INET6_ESP=m
++CONFIG_INET6_IPCOMP=m
++CONFIG_IPV6_MIP6=m
++CONFIG_INET6_XFRM_TUNNEL=m
++CONFIG_INET6_TUNNEL=m
++CONFIG_INET6_XFRM_MODE_TRANSPORT=m
++CONFIG_INET6_XFRM_MODE_TUNNEL=m
++CONFIG_INET6_XFRM_MODE_BEET=m
++CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
++CONFIG_IPV6_SIT=m
++CONFIG_IPV6_NDISC_NODETYPE=y
++CONFIG_IPV6_TUNNEL=m
++CONFIG_IPV6_MULTIPLE_TABLES=y
++CONFIG_IPV6_SUBTREES=y
++# CONFIG_IPV6_MROUTE is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++CONFIG_WAN_ROUTER=y
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++# CONFIG_PHONET is not set
++CONFIG_FIB_RULES=y
++# CONFIG_WIRELESS is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_SYS_HYPERVISOR is not set
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_CONCAT=y
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++CONFIG_MTD_DATAFLASH=y
++# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
++# CONFIG_MTD_DATAFLASH_OTP is not set
++CONFIG_MTD_M25P80=y
++CONFIG_M25PXX_USE_FAST_READ=y
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++CONFIG_MTD_NAND=y
++# CONFIG_MTD_NAND_VERIFY_WRITE is not set
++# CONFIG_MTD_NAND_ECC_SMC is not set
++# CONFIG_MTD_NAND_MUSEUM_IDS is not set
++CONFIG_MTD_NAND_AST=y
++# CONFIG_MTD_NAND_GPIO is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++# CONFIG_MTD_ALAUDA is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++CONFIG_BLK_DEV_NBD=m
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=16384
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ICS932S401 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_C2PORT is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++CONFIG_SCSI_TGT=y
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++CONFIG_SCSI_SCAN_ASYNC=y
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++CONFIG_SCSI_ISCSI_ATTRS=m
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++CONFIG_BONDING=y
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_NET_ETHERNET is not set
++CONFIG_NETDEV_1000=y
++CONFIG_ASPEEDMAC=y
++CONFIG_MAC0_PHY_LINK=y
++# CONFIG_NETDEV_10000 is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++# CONFIG_IWLWIFI_LEDS is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_GPIO is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_ELANTECH is not set
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++CONFIG_MOUSE_SERIAL=y
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_BCM5974 is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_AMBAKMI is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++CONFIG_DEVKMEM=y
++CONFIG_SERIAL_NONSTANDARD=y
++# CONFIG_N_HDLC is not set
++# CONFIG_RISCOM8 is not set
++# CONFIG_SPECIALIX is not set
++# CONFIG_RIO is not set
++# CONFIG_STALDRV is not set
++
++#
++# Serial drivers
++#
++# CONFIG_SERIAL_8250 is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++# CONFIG_SERIAL_AMBA_PL011 is not set
++CONFIG_SERIAL_ASPEED=y
++CONFIG_SERIAL_ASPEED_CONSOLE=y
++CONFIG_SERIAL_ASPEED_CONSOLE_BAUD=115200
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_HW_RANDOM is not set
++CONFIG_NVRAM=y
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_HELPER_AUTO=y
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++CONFIG_I2C_ASPEED=y
++CONFIG_AST_I2C_SLAVE_MODE=y
++# CONFIG_I2C_SIMTEC is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_STUB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++CONFIG_AT24=y
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_PCF8575 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
++
++#
++# SPI Master Controller Drivers
++#
++CONFIG_SPI_AST=y
++# CONFIG_SPI_FMC is not set
++CONFIG_SPI_BITBANG=y
++
++#
++# SPI Protocol Masters
++#
++# CONFIG_SPI_AT25 is not set
++# CONFIG_SPI_SPIDEV is not set
++# CONFIG_SPI_TLE62X0 is not set
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO expanders:
++#
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_AD7414 is not set
++# CONFIG_SENSORS_AD7418 is not set
++# CONFIG_SENSORS_ADCXX is not set
++# CONFIG_SENSORS_ADM1021 is not set
++# CONFIG_SENSORS_ADM1025 is not set
++# CONFIG_SENSORS_ADM1026 is not set
++# CONFIG_SENSORS_ADM1029 is not set
++# CONFIG_SENSORS_ADM1031 is not set
++# CONFIG_SENSORS_ADM9240 is not set
++# CONFIG_SENSORS_ADT7462 is not set
++# CONFIG_SENSORS_ADT7470 is not set
++# CONFIG_SENSORS_ADT7473 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_F75375S is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_LM63 is not set
++# CONFIG_SENSORS_LM70 is not set
++# CONFIG_SENSORS_LM75 is not set
++# CONFIG_SENSORS_LM77 is not set
++# CONFIG_SENSORS_LM78 is not set
++# CONFIG_SENSORS_LM80 is not set
++# CONFIG_SENSORS_LM83 is not set
++# CONFIG_SENSORS_LM85 is not set
++# CONFIG_SENSORS_LM87 is not set
++# CONFIG_SENSORS_LM90 is not set
++# CONFIG_SENSORS_LM92 is not set
++# CONFIG_SENSORS_LM93 is not set
++# CONFIG_SENSORS_MAX1111 is not set
++# CONFIG_SENSORS_MAX1619 is not set
++# CONFIG_SENSORS_MAX6650 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_DME1737 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_ADS7828 is not set
++# CONFIG_SENSORS_THMC50 is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_W83781D is not set
++# CONFIG_SENSORS_W83791D is not set
++# CONFIG_SENSORS_W83792D is not set
++# CONFIG_SENSORS_W83793 is not set
++# CONFIG_SENSORS_W83L785TS is not set
++# CONFIG_SENSORS_W83L786NG is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++# CONFIG_SENSORS_AST_ADC is not set
++CONFIG_SENSORS_AST_PWM_FAN=y
++# CONFIG_SENSORS_AST_PECI is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++# CONFIG_THERMAL is not set
++# CONFIG_THERMAL_HWMON is not set
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++CONFIG_ASPEED_WATCHDOG=y
++
++#
++# USB-based Watchdog Cards
++#
++# CONFIG_USBPCWATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM8350_I2C is not set
++
++#
++# Multimedia devices
++#
++
++#
++# Multimedia core support
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_VIDEO_MEDIA is not set
++
++#
++# Multimedia drivers
++#
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++CONFIG_FIRMWARE_EDID=y
++# CONFIG_FB_DDC is not set
++# CONFIG_FB_BOOT_VESA_SUPPORT is not set
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_FOREIGN_ENDIAN is not set
++# CONFIG_FB_SYS_FOPS is not set
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++CONFIG_FB_MODE_HELPERS=y
++CONFIG_FB_TILEBLITTING=y
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_ARMCLCD is not set
++# CONFIG_FB_UVESA is not set
++# CONFIG_FB_S1D13XXX is not set
++CONFIG_FB_AST=y
++CONFIG_AST_DAC=y
++# CONFIG_AST_DVO is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_MB862XX is not set
++CONFIG_BACKLIGHT_LCD_SUPPORT=y
++CONFIG_LCD_CLASS_DEVICE=m
++# CONFIG_LCD_LTV350QV is not set
++# CONFIG_LCD_ILI9320 is not set
++# CONFIG_LCD_TDO24M is not set
++# CONFIG_LCD_VGG2432A4 is not set
++# CONFIG_LCD_PLATFORM is not set
++CONFIG_BACKLIGHT_CLASS_DEVICE=m
++# CONFIG_BACKLIGHT_CORGI is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
++# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
++CONFIG_FONTS=y
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_7x14 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++# CONFIG_FONT_MINI_4x6 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_10x18 is not set
++# CONFIG_LOGO is not set
++# CONFIG_SOUND is not set
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++CONFIG_HID_DEBUG=y
++# CONFIG_HIDRAW is not set
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++# CONFIG_HID_PID is not set
++# CONFIG_USB_HIDDEV is not set
++
++#
++# Special HID drivers
++#
++CONFIG_HID_COMPAT=y
++CONFIG_HID_A4TECH=y
++CONFIG_HID_APPLE=y
++CONFIG_HID_BELKIN=y
++CONFIG_HID_BRIGHT=y
++CONFIG_HID_CHERRY=y
++CONFIG_HID_CHICONY=y
++CONFIG_HID_CYPRESS=y
++CONFIG_HID_DELL=y
++CONFIG_HID_EZKEY=y
++CONFIG_HID_GYRATION=y
++CONFIG_HID_LOGITECH=y
++# CONFIG_LOGITECH_FF is not set
++# CONFIG_LOGIRUMBLEPAD2_FF is not set
++CONFIG_HID_MICROSOFT=y
++CONFIG_HID_MONTEREY=y
++CONFIG_HID_PANTHERLORD=y
++# CONFIG_PANTHERLORD_FF is not set
++CONFIG_HID_PETALYNX=y
++CONFIG_HID_SAMSUNG=y
++CONFIG_HID_SONY=y
++CONFIG_HID_SUNPLUS=y
++# CONFIG_THRUSTMASTER_FF is not set
++# CONFIG_ZEROPLUS_FF is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++# CONFIG_USB_ARCH_HAS_OHCI is not set
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=y
++# CONFIG_USB_DEBUG is not set
++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_SUSPEND is not set
++# CONFIG_USB_OTG is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++# CONFIG_USB_EHCI_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_HWA_HCD is not set
++
++#
++# AST USB Drivers
++#
++CONFIG_AST_USB_UHCI_HCD=y
++# CONFIG_AST_USB_UHCI_MULTIPORT_1 is not set
++# CONFIG_AST_USB_UHCI_MULTIPORT_2 is not set
++CONFIG_AST_USB_UHCI_MULTIPORT_4=y
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
++#
++
++#
++# see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=y
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_VST is not set
++# CONFIG_USB_GADGET is not set
++CONFIG_MMC=y
++# CONFIG_MMC_DEBUG is not set
++# CONFIG_MMC_UNSAFE_RESUME is not set
++
++#
++# MMC/SD/SDIO Card Drivers
++#
++CONFIG_MMC_BLOCK=y
++CONFIG_MMC_BLOCK_BOUNCE=y
++# CONFIG_SDIO_UART is not set
++# CONFIG_MMC_TEST is not set
++
++#
++# MMC/SD/SDIO Host Controller Drivers
++#
++# CONFIG_MMC_ARMMMCI is not set
++# CONFIG_MMC_SDHCI is not set
++CONFIG_MMC_ASPEED=y
++# CONFIG_MMC_SPI is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++# CONFIG_RTC_HCTOSYS is not set
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++# CONFIG_RTC_DRV_DS1307 is not set
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++
++#
++# SPI RTC drivers
++#
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
++# CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_PL030 is not set
++# CONFIG_RTC_DRV_PL031 is not set
++CONFIG_RTC_DRV_ASPEED=y
++# CONFIG_DMADEVICES is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++CONFIG_EXT2_FS_XATTR=y
++CONFIG_EXT2_FS_POSIX_ACL=y
++CONFIG_EXT2_FS_SECURITY=y
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4_FS is not set
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_FILE_LOCKING=y
++# CONFIG_XFS_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++CONFIG_GENERIC_ACL=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=y
++# CONFIG_NTFS_DEBUG is not set
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=m
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_YAFFS_FS=y
++CONFIG_YAFFS_YAFFS1=y
++# CONFIG_YAFFS_9BYTE_TAGS is not set
++# CONFIG_YAFFS_DOES_ECC is not set
++CONFIG_YAFFS_YAFFS2=y
++CONFIG_YAFFS_AUTO_YAFFS2=y
++# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set
++# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
++# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
++# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
++CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
++# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set
++# CONFIG_JFFS2_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_NFS_V4 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_REGISTER_V4 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf8"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++CONFIG_NLS_CODEPAGE_936=y
++CONFIG_NLS_CODEPAGE_950=y
++CONFIG_NLS_CODEPAGE_932=y
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++# CONFIG_ENABLE_WARN_DEPRECATED is not set
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_MEMORY_INIT=y
++CONFIG_FRAME_POINTER=y
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_LATENCYTOP is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++
++#
++# Tracers
++#
++# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++# CONFIG_CRYPTO_FIPS is not set
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD=m
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_NULL=y
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_AUTHENC=m
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++# CONFIG_CRYPTO_ECB is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_XCBC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++CONFIG_CRYPTO_SHA1=y
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=m
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++# CONFIG_CRYPTO_HW is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++CONFIG_CRC_ITU_T=m
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff --git a/arch/arm/configs/ast2400_ast1070-1_defconfig b/arch/arm/configs/ast2400_ast1070-1_defconfig
+new file mode 100644
+index 0000000..93f3df9
+--- /dev/null
++++ b/arch/arm/configs/ast2400_ast1070-1_defconfig
+@@ -0,0 +1,1038 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.28.9
++# Fri Nov 8 16:04:52 2013
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++# CONFIG_GENERIC_TIME is not set
++# CONFIG_GENERIC_CLOCKEVENTS is not set
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=16
++# CONFIG_CGROUPS is not set
++# CONFIG_GROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++CONFIG_KALLSYMS_EXTRA_PASS=y
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++CONFIG_COMPAT_BRK=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_ARCH_ASPEED=y
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM is not set
++CONFIG_IRMP=y
++# CONFIG_PCEXT is not set
++# CONFIG_REMOTEFX is not set
++# CONFIG_ARCH_AST1100 is not set
++# CONFIG_ARCH_AST2100 is not set
++# CONFIG_ARCH_AST2200 is not set
++# CONFIG_ARCH_AST2300 is not set
++CONFIG_ARCH_AST2400=y
++# CONFIG_ARCH_AST2500 is not set
++
++#
++# FLASH Chip Select
++#
++CONFIG_AST_CS0_NOR=y
++# CONFIG_AST_CS0_NAND is not set
++# CONFIG_AST_CS0_SPI is not set
++# CONFIG_AST_CS0_NONE is not set
++CONFIG_AST_CS1_NOR=y
++# CONFIG_AST_CS1_NAND is not set
++# CONFIG_AST_CS1_SPI is not set
++# CONFIG_AST_CS1_NONE is not set
++CONFIG_AST_CS2_NOR=y
++# CONFIG_AST_CS2_NAND is not set
++# CONFIG_AST_CS2_SPI is not set
++# CONFIG_AST_CS2_NONE is not set
++CONFIG_AST_CS3_NOR=y
++# CONFIG_AST_CS3_NAND is not set
++# CONFIG_AST_CS3_SPI is not set
++# CONFIG_AST_CS3_NONE is not set
++CONFIG_AST_CS4_NOR=y
++# CONFIG_AST_CS4_NAND is not set
++# CONFIG_AST_CS4_SPI is not set
++# CONFIG_AST_CS4_NONE is not set
++CONFIG_ARCH_AST1070=y
++CONFIG_AST1070_NR=1
++CONFIG_AST_LPC_PLUS=y
++# CONFIG_AST_LPC is not set
++# CONFIG_AST_SCU_LOCK is not set
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++CONFIG_PLAT_ASPEED=y
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_NOIFAR=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++# CONFIG_OUTER_CACHE is not set
++
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++# CONFIG_AEABI is not set
++CONFIG_ARCH_FLATMEM_HAS_HOLES=y
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_UNEVICTABLE_LRU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++CONFIG_CMDLINE=""
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++CONFIG_FPE_NWFPE_XP=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_VFP=y
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
++CONFIG_BINFMT_AOUT=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++
++#
++# Power management options
++#
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++CONFIG_PM_SLEEP=y
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_APM_EMULATION is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++CONFIG_WAN_ROUTER=y
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++# CONFIG_PHONET is not set
++# CONFIG_WIRELESS is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_SYS_HYPERVISOR is not set
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++# CONFIG_MTD is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++CONFIG_BLK_DEV_NBD=m
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=16384
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ICS932S401 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_C2PORT is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++CONFIG_SCSI_TGT=y
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++CONFIG_SCSI_SCAN_ASYNC=y
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++CONFIG_SCSI_ISCSI_ATTRS=m
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_NET_ETHERNET is not set
++CONFIG_NETDEV_1000=y
++CONFIG_ASPEEDMAC=y
++# CONFIG_MAC0_PHY_LINK is not set
++# CONFIG_NETDEV_10000 is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++# CONFIG_IWLWIFI_LEDS is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_GPIO is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_ELANTECH is not set
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++CONFIG_MOUSE_SERIAL=y
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_AMBAKMI is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++CONFIG_DEVKMEM=y
++CONFIG_SERIAL_NONSTANDARD=y
++# CONFIG_N_HDLC is not set
++# CONFIG_RISCOM8 is not set
++# CONFIG_SPECIALIX is not set
++# CONFIG_RIO is not set
++# CONFIG_STALDRV is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=3
++CONFIG_SERIAL_8250_RUNTIME_UARTS=3
++CONFIG_SERIAL_AST_DMA_UART=y
++CONFIG_AST_NR_DMA_UARTS=4
++CONFIG_AST_RUNTIME_DMA_UARTS=4
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++# CONFIG_SERIAL_AMBA_PL011 is not set
++# CONFIG_SERIAL_AST is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_AST_MISC is not set
++# CONFIG_HW_RANDOM is not set
++CONFIG_NVRAM=y
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_HELPER_AUTO=y
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++CONFIG_I2C_AST=y
++CONFIG_I2C_AST1070=y
++CONFIG_AST_I2C_SLAVE_MODE=y
++CONFIG_AST_I2C_SLAVE_EEPROM=y
++# CONFIG_AST_I2C_SLAVE_RDWR is not set
++# CONFIG_I2C_SIMTEC is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_STUB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++# CONFIG_AT24 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_PCF8575 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++# CONFIG_SPI is not set
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO expanders:
++#
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++# CONFIG_THERMAL_HWMON is not set
++# CONFIG_WATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM8350_I2C is not set
++
++#
++# Multimedia devices
++#
++
++#
++# Multimedia core support
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_VIDEO_MEDIA is not set
++
++#
++# Multimedia drivers
++#
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_SOUND is not set
++# CONFIG_HID_SUPPORT is not set
++# CONFIG_USB_SUPPORT is not set
++CONFIG_USB_ARCH_HAS_EHCI=y
++# CONFIG_MMC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++# CONFIG_RTC_CLASS is not set
++# CONFIG_DMADEVICES is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++CONFIG_EXT2_FS_XATTR=y
++CONFIG_EXT2_FS_POSIX_ACL=y
++CONFIG_EXT2_FS_SECURITY=y
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4_FS is not set
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_FILE_LOCKING=y
++# CONFIG_XFS_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++CONFIG_GENERIC_ACL=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=y
++# CONFIG_NTFS_DEBUG is not set
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=m
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_NFS_V4 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_REGISTER_V4 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf8"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++CONFIG_NLS_CODEPAGE_936=y
++CONFIG_NLS_CODEPAGE_950=y
++CONFIG_NLS_CODEPAGE_932=y
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++# CONFIG_ENABLE_WARN_DEPRECATED is not set
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_MEMORY_INIT=y
++CONFIG_FRAME_POINTER=y
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_LATENCYTOP is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++
++#
++# Tracers
++#
++# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++# CONFIG_CRYPTO_FIPS is not set
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD=m
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_NULL=y
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_AUTHENC=m
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++# CONFIG_CRYPTO_ECB is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_XCBC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++CONFIG_CRYPTO_SHA1=y
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=m
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++# CONFIG_CRYPTO_HW is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++CONFIG_CRC_ITU_T=m
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff --git a/arch/arm/configs/ast2400_ast1070_defconfig b/arch/arm/configs/ast2400_ast1070_defconfig
+new file mode 100644
+index 0000000..552523e
+--- /dev/null
++++ b/arch/arm/configs/ast2400_ast1070_defconfig
+@@ -0,0 +1,1036 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.28.9
++# Mon Jul 15 18:21:08 2013
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++# CONFIG_GENERIC_TIME is not set
++# CONFIG_GENERIC_CLOCKEVENTS is not set
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=16
++# CONFIG_CGROUPS is not set
++# CONFIG_GROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++CONFIG_KALLSYMS_EXTRA_PASS=y
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++CONFIG_COMPAT_BRK=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_ARCH_ASPEED=y
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM is not set
++CONFIG_IRMP=y
++# CONFIG_PCEXT is not set
++# CONFIG_REMOTEFX is not set
++# CONFIG_ARCH_AST1100 is not set
++# CONFIG_ARCH_AST2100 is not set
++# CONFIG_ARCH_AST2200 is not set
++# CONFIG_ARCH_AST2300 is not set
++CONFIG_ARCH_AST2400=y
++# CONFIG_ARCH_AST2500 is not set
++
++#
++# FLASH Chip Select
++#
++CONFIG_AST_CS0_NOR=y
++# CONFIG_AST_CS0_NAND is not set
++# CONFIG_AST_CS0_SPI is not set
++# CONFIG_AST_CS0_NONE is not set
++CONFIG_AST_CS1_NOR=y
++# CONFIG_AST_CS1_NAND is not set
++# CONFIG_AST_CS1_SPI is not set
++# CONFIG_AST_CS1_NONE is not set
++CONFIG_AST_CS2_NOR=y
++# CONFIG_AST_CS2_NAND is not set
++# CONFIG_AST_CS2_SPI is not set
++# CONFIG_AST_CS2_NONE is not set
++CONFIG_AST_CS3_NOR=y
++# CONFIG_AST_CS3_NAND is not set
++# CONFIG_AST_CS3_SPI is not set
++# CONFIG_AST_CS3_NONE is not set
++CONFIG_AST_CS4_NOR=y
++# CONFIG_AST_CS4_NAND is not set
++# CONFIG_AST_CS4_SPI is not set
++# CONFIG_AST_CS4_NONE is not set
++CONFIG_ARCH_AST1070=y
++CONFIG_AST1070_NR=2
++CONFIG_AST_LPC_PLUS=y
++# CONFIG_AST_LPC is not set
++# CONFIG_AST_SCU_LOCK is not set
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++CONFIG_PLAT_ASPEED=y
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_NOIFAR=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++# CONFIG_OUTER_CACHE is not set
++
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++# CONFIG_AEABI is not set
++CONFIG_ARCH_FLATMEM_HAS_HOLES=y
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_UNEVICTABLE_LRU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++CONFIG_CMDLINE=""
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++CONFIG_FPE_NWFPE_XP=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_VFP=y
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
++CONFIG_BINFMT_AOUT=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++
++#
++# Power management options
++#
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++CONFIG_PM_SLEEP=y
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_APM_EMULATION is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++CONFIG_WAN_ROUTER=y
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++# CONFIG_PHONET is not set
++# CONFIG_WIRELESS is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_SYS_HYPERVISOR is not set
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++# CONFIG_MTD is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++CONFIG_BLK_DEV_NBD=m
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=16384
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ICS932S401 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_C2PORT is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++CONFIG_SCSI_TGT=y
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++CONFIG_SCSI_SCAN_ASYNC=y
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++CONFIG_SCSI_ISCSI_ATTRS=m
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_NET_ETHERNET is not set
++CONFIG_NETDEV_1000=y
++CONFIG_ASPEEDMAC=y
++# CONFIG_MAC0_PHY_LINK is not set
++# CONFIG_NETDEV_10000 is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++# CONFIG_IWLWIFI_LEDS is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_GPIO is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_ELANTECH is not set
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++CONFIG_MOUSE_SERIAL=y
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_AMBAKMI is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++CONFIG_DEVKMEM=y
++CONFIG_SERIAL_NONSTANDARD=y
++# CONFIG_N_HDLC is not set
++# CONFIG_RISCOM8 is not set
++# CONFIG_SPECIALIX is not set
++# CONFIG_RIO is not set
++# CONFIG_STALDRV is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=3
++CONFIG_SERIAL_8250_RUNTIME_UARTS=3
++CONFIG_SERIAL_AST_DMA_UART=y
++CONFIG_AST_NR_DMA_UARTS=8
++CONFIG_AST_RUNTIME_DMA_UARTS=8
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++# CONFIG_SERIAL_AMBA_PL011 is not set
++# CONFIG_SERIAL_AST is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_AST_MISC is not set
++# CONFIG_HW_RANDOM is not set
++CONFIG_NVRAM=y
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_HELPER_AUTO=y
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++CONFIG_I2C_AST=y
++CONFIG_I2C_AST1070=y
++CONFIG_AST_I2C_SLAVE_MODE=y
++# CONFIG_I2C_SIMTEC is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_STUB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++# CONFIG_AT24 is not set
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_PCF8575 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++# CONFIG_SPI is not set
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO expanders:
++#
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++# CONFIG_THERMAL_HWMON is not set
++# CONFIG_WATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM8350_I2C is not set
++
++#
++# Multimedia devices
++#
++
++#
++# Multimedia core support
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_VIDEO_MEDIA is not set
++
++#
++# Multimedia drivers
++#
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_SOUND is not set
++# CONFIG_HID_SUPPORT is not set
++# CONFIG_USB_SUPPORT is not set
++CONFIG_USB_ARCH_HAS_EHCI=y
++# CONFIG_MMC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++# CONFIG_RTC_CLASS is not set
++# CONFIG_DMADEVICES is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++CONFIG_EXT2_FS_XATTR=y
++CONFIG_EXT2_FS_POSIX_ACL=y
++CONFIG_EXT2_FS_SECURITY=y
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4_FS is not set
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_FILE_LOCKING=y
++# CONFIG_XFS_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++CONFIG_GENERIC_ACL=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=y
++# CONFIG_NTFS_DEBUG is not set
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=m
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_NFS_V4 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_REGISTER_V4 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf8"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++CONFIG_NLS_CODEPAGE_936=y
++CONFIG_NLS_CODEPAGE_950=y
++CONFIG_NLS_CODEPAGE_932=y
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++# CONFIG_ENABLE_WARN_DEPRECATED is not set
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_MEMORY_INIT=y
++CONFIG_FRAME_POINTER=y
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_LATENCYTOP is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++
++#
++# Tracers
++#
++# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++# CONFIG_CRYPTO_FIPS is not set
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD=m
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_NULL=y
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_AUTHENC=m
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++# CONFIG_CRYPTO_ECB is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_XCBC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++CONFIG_CRYPTO_SHA1=y
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=m
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++# CONFIG_CRYPTO_HW is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++CONFIG_CRC_ITU_T=m
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff --git a/arch/arm/configs/ast2400_defconfig b/arch/arm/configs/ast2400_defconfig
+new file mode 100644
+index 0000000..22b76fe
+--- /dev/null
++++ b/arch/arm/configs/ast2400_defconfig
+@@ -0,0 +1,1412 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.28.9
++# Tue Jan 20 09:41:35 2015
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++# CONFIG_GENERIC_TIME is not set
++# CONFIG_GENERIC_CLOCKEVENTS is not set
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=16
++# CONFIG_CGROUPS is not set
++# CONFIG_GROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++CONFIG_KALLSYMS_EXTRA_PASS=y
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++CONFIG_COMPAT_BRK=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_ARCH_ASPEED=y
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM is not set
++CONFIG_IRMP=y
++# CONFIG_PCEXT is not set
++# CONFIG_REMOTEFX is not set
++# CONFIG_ARCH_AST1100 is not set
++# CONFIG_ARCH_AST2100 is not set
++# CONFIG_ARCH_AST2200 is not set
++# CONFIG_ARCH_AST2300 is not set
++CONFIG_ARCH_AST2400=y
++# CONFIG_ARCH_AST2500 is not set
++
++#
++# FLASH Chip Select
++#
++# CONFIG_AST_CS0_NOR is not set
++# CONFIG_AST_CS0_NAND is not set
++# CONFIG_AST_CS0_SPI is not set
++CONFIG_AST_CS0_NONE=y
++# CONFIG_AST_CS1_NOR is not set
++# CONFIG_AST_CS1_NAND is not set
++# CONFIG_AST_CS1_SPI is not set
++CONFIG_AST_CS1_NONE=y
++# CONFIG_AST_CS2_NOR is not set
++# CONFIG_AST_CS2_NAND is not set
++# CONFIG_AST_CS2_SPI is not set
++CONFIG_AST_CS2_NONE=y
++# CONFIG_AST_CS3_NOR is not set
++# CONFIG_AST_CS3_NAND is not set
++# CONFIG_AST_CS3_SPI is not set
++CONFIG_AST_CS3_NONE=y
++# CONFIG_AST_CS4_NOR is not set
++# CONFIG_AST_CS4_NAND is not set
++# CONFIG_AST_CS4_SPI is not set
++CONFIG_AST_CS4_NONE=y
++# CONFIG_ARCH_AST1070 is not set
++# CONFIG_AST_SCU_LOCK is not set
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++CONFIG_PLAT_ASPEED=y
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_NOIFAR=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++# CONFIG_OUTER_CACHE is not set
++
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++# CONFIG_AEABI is not set
++CONFIG_ARCH_FLATMEM_HAS_HOLES=y
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_UNEVICTABLE_LRU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++CONFIG_CMDLINE=""
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++CONFIG_FPE_NWFPE_XP=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_VFP=y
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
++CONFIG_BINFMT_AOUT=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++
++#
++# Power management options
++#
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++CONFIG_PM_SLEEP=y
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_APM_EMULATION is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++CONFIG_WAN_ROUTER=y
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++# CONFIG_PHONET is not set
++# CONFIG_WIRELESS is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_SYS_HYPERVISOR is not set
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_CONCAT=y
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++CONFIG_BLK_DEV_NBD=y
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=16384
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ICS932S401 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_C2PORT is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++CONFIG_SCSI_TGT=y
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++CONFIG_SCSI_SCAN_ASYNC=y
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++CONFIG_SCSI_ISCSI_ATTRS=m
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++CONFIG_BONDING=y
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_NET_ETHERNET is not set
++CONFIG_NETDEV_1000=y
++CONFIG_ASPEEDMAC=y
++# CONFIG_NETDEV_10000 is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++# CONFIG_IWLWIFI_LEDS is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_GPIO is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_ELANTECH is not set
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++CONFIG_MOUSE_SERIAL=y
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_BCM5974 is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_AMBAKMI is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++CONFIG_DEVKMEM=y
++CONFIG_SERIAL_NONSTANDARD=y
++# CONFIG_N_HDLC is not set
++# CONFIG_RISCOM8 is not set
++# CONFIG_SPECIALIX is not set
++# CONFIG_RIO is not set
++# CONFIG_STALDRV is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=4
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++# CONFIG_SERIAL_AST_DMA_UART is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++# CONFIG_SERIAL_AMBA_PL011 is not set
++# CONFIG_SERIAL_AST is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_AST_MISC=y
++# CONFIG_AST_VIDEO is not set
++# CONFIG_ADC_CAT9883 is not set
++# CONFIG_AST_SPI_BIOS is not set
++CONFIG_AST_PECI=y
++# CONFIG_AST_KCS is not set
++# CONFIG_AST_GPIO is not set
++# CONFIG_HW_RANDOM is not set
++CONFIG_NVRAM=y
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_HELPER_AUTO=y
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++CONFIG_I2C_AST=y
++CONFIG_AST_I2C_SLAVE_MODE=y
++CONFIG_AST_I2C_SLAVE_EEPROM=y
++# CONFIG_AST_I2C_SLAVE_RDWR is not set
++# CONFIG_I2C_SIMTEC is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_STUB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++CONFIG_AT24=y
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_PCF8575 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++# CONFIG_SPI is not set
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO expanders:
++#
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_AD7414 is not set
++# CONFIG_SENSORS_AD7418 is not set
++# CONFIG_SENSORS_ADM1021 is not set
++# CONFIG_SENSORS_ADM1025 is not set
++# CONFIG_SENSORS_ADM1026 is not set
++# CONFIG_SENSORS_ADM1029 is not set
++# CONFIG_SENSORS_ADM1031 is not set
++# CONFIG_SENSORS_ADM9240 is not set
++# CONFIG_SENSORS_ADT7462 is not set
++# CONFIG_SENSORS_ADT7470 is not set
++# CONFIG_SENSORS_ADT7473 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_F75375S is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_LM63 is not set
++# CONFIG_SENSORS_LM75 is not set
++# CONFIG_SENSORS_LM77 is not set
++# CONFIG_SENSORS_LM78 is not set
++# CONFIG_SENSORS_LM80 is not set
++# CONFIG_SENSORS_LM83 is not set
++# CONFIG_SENSORS_LM85 is not set
++# CONFIG_SENSORS_LM87 is not set
++# CONFIG_SENSORS_LM90 is not set
++# CONFIG_SENSORS_LM92 is not set
++# CONFIG_SENSORS_LM93 is not set
++# CONFIG_SENSORS_MAX1619 is not set
++# CONFIG_SENSORS_MAX6650 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_DME1737 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_ADS7828 is not set
++# CONFIG_SENSORS_THMC50 is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_W83781D is not set
++# CONFIG_SENSORS_W83791D is not set
++# CONFIG_SENSORS_W83792D is not set
++# CONFIG_SENSORS_W83793 is not set
++# CONFIG_SENSORS_W83L785TS is not set
++# CONFIG_SENSORS_W83L786NG is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++CONFIG_SENSORS_AST_ADC=y
++CONFIG_SENSORS_AST_PWM_FAN=y
++# CONFIG_HWMON_DEBUG_CHIP is not set
++# CONFIG_THERMAL is not set
++# CONFIG_THERMAL_HWMON is not set
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++CONFIG_AST_WATCHDOG=y
++
++#
++# USB-based Watchdog Cards
++#
++# CONFIG_USBPCWATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM8350_I2C is not set
++
++#
++# Multimedia devices
++#
++
++#
++# Multimedia core support
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_VIDEO_MEDIA is not set
++
++#
++# Multimedia drivers
++#
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_SOUND is not set
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++CONFIG_HID_DEBUG=y
++# CONFIG_HIDRAW is not set
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++# CONFIG_HID_PID is not set
++# CONFIG_USB_HIDDEV is not set
++
++#
++# Special HID drivers
++#
++CONFIG_HID_COMPAT=y
++CONFIG_HID_A4TECH=y
++CONFIG_HID_APPLE=y
++CONFIG_HID_BELKIN=y
++CONFIG_HID_BRIGHT=y
++CONFIG_HID_CHERRY=y
++CONFIG_HID_CHICONY=y
++CONFIG_HID_CYPRESS=y
++CONFIG_HID_DELL=y
++CONFIG_HID_EZKEY=y
++CONFIG_HID_GYRATION=y
++CONFIG_HID_LOGITECH=y
++# CONFIG_LOGITECH_FF is not set
++# CONFIG_LOGIRUMBLEPAD2_FF is not set
++CONFIG_HID_MICROSOFT=y
++CONFIG_HID_MONTEREY=y
++CONFIG_HID_PANTHERLORD=y
++# CONFIG_PANTHERLORD_FF is not set
++CONFIG_HID_PETALYNX=y
++CONFIG_HID_SAMSUNG=y
++CONFIG_HID_SONY=y
++CONFIG_HID_SUNPLUS=y
++# CONFIG_THRUSTMASTER_FF is not set
++# CONFIG_ZEROPLUS_FF is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++# CONFIG_USB_ARCH_HAS_OHCI is not set
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=y
++# CONFIG_USB_DEBUG is not set
++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_SUSPEND is not set
++# CONFIG_USB_OTG is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++CONFIG_USB_EHCI_HCD=y
++# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
++CONFIG_USB_EHCI_TT_NEWSCHED=y
++CONFIG_USB_EHCI_AST=y
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_HWA_HCD is not set
++
++#
++# AST USB Drivers
++#
++CONFIG_AST_USB_UHCI_HCD=y
++# CONFIG_AST_USB_UHCI_MULTIPORT_1 is not set
++# CONFIG_AST_USB_UHCI_MULTIPORT_2 is not set
++CONFIG_AST_USB_UHCI_MULTIPORT_4=y
++# CONFIG_USB_EHCI_SPLIT_ISO is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
++#
++
++#
++# see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=y
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_SISUSBVGA is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_VST is not set
++# CONFIG_USB_GADGET is not set
++CONFIG_MMC=y
++# CONFIG_MMC_DEBUG is not set
++# CONFIG_MMC_UNSAFE_RESUME is not set
++
++#
++# MMC/SD/SDIO Card Drivers
++#
++CONFIG_MMC_BLOCK=y
++CONFIG_MMC_BLOCK_BOUNCE=y
++# CONFIG_SDIO_UART is not set
++# CONFIG_MMC_TEST is not set
++
++#
++# MMC/SD/SDIO Host Controller Drivers
++#
++# CONFIG_MMC_ARMMMCI is not set
++# CONFIG_MMC_SDHCI is not set
++CONFIG_MMC_AST=y
++# CONFIG_MEMSTICK is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++# CONFIG_RTC_HCTOSYS is not set
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++# CONFIG_RTC_DRV_DS1307 is not set
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++
++#
++# SPI RTC drivers
++#
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_PL030 is not set
++# CONFIG_RTC_DRV_PL031 is not set
++CONFIG_RTC_DRV_ASPEED=y
++# CONFIG_DMADEVICES is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++CONFIG_EXT2_FS_XATTR=y
++CONFIG_EXT2_FS_POSIX_ACL=y
++CONFIG_EXT2_FS_SECURITY=y
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4_FS is not set
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_FILE_LOCKING=y
++# CONFIG_XFS_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++CONFIG_GENERIC_ACL=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=y
++# CONFIG_NTFS_DEBUG is not set
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=m
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_YAFFS_FS=y
++CONFIG_YAFFS_YAFFS1=y
++# CONFIG_YAFFS_9BYTE_TAGS is not set
++# CONFIG_YAFFS_DOES_ECC is not set
++CONFIG_YAFFS_YAFFS2=y
++CONFIG_YAFFS_AUTO_YAFFS2=y
++# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set
++# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
++# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
++# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
++CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
++# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set
++# CONFIG_JFFS2_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_NFS_V4 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_REGISTER_V4 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf8"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++CONFIG_NLS_CODEPAGE_936=y
++CONFIG_NLS_CODEPAGE_950=y
++CONFIG_NLS_CODEPAGE_932=y
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++# CONFIG_ENABLE_WARN_DEPRECATED is not set
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_MEMORY_INIT=y
++CONFIG_FRAME_POINTER=y
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_LATENCYTOP is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++
++#
++# Tracers
++#
++# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++# CONFIG_CRYPTO_FIPS is not set
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD=m
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_NULL=y
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_AUTHENC=m
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++# CONFIG_CRYPTO_ECB is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_XCBC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++CONFIG_CRYPTO_SHA1=y
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=m
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++# CONFIG_CRYPTO_HW is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++CONFIG_CRC_ITU_T=m
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff --git a/arch/arm/configs/ast2400_fb_defconfig b/arch/arm/configs/ast2400_fb_defconfig
+new file mode 100644
+index 0000000..71a1239
+--- /dev/null
++++ b/arch/arm/configs/ast2400_fb_defconfig
+@@ -0,0 +1,1516 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.28.9
++# Thu Jan 10 10:40:53 2013
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++# CONFIG_GENERIC_TIME is not set
++# CONFIG_GENERIC_CLOCKEVENTS is not set
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=16
++# CONFIG_CGROUPS is not set
++# CONFIG_GROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++CONFIG_KALLSYMS_EXTRA_PASS=y
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++CONFIG_COMPAT_BRK=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_ARCH_ASPEED=y
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM is not set
++CONFIG_IRMP=y
++# CONFIG_PCEXT is not set
++# CONFIG_REMOTEFX is not set
++# CONFIG_ARCH_AST1100 is not set
++# CONFIG_ARCH_AST2100 is not set
++# CONFIG_ARCH_AST2200 is not set
++# CONFIG_ARCH_AST2300 is not set
++CONFIG_ARCH_AST2400=y
++
++#
++# FLASH Chip Select
++#
++# CONFIG_ASPEED_CS0_NOR is not set
++# CONFIG_ASPEED_CS0_NAND is not set
++CONFIG_ASPEED_CS0_SPI=y
++# CONFIG_ASPEED_CS0_NONE is not set
++# CONFIG_ASPEED_CS1_NOR is not set
++# CONFIG_ASPEED_CS1_NAND is not set
++# CONFIG_ASPEED_CS1_SPI is not set
++CONFIG_ASPEED_CS1_NONE=y
++# CONFIG_ASPEED_CS2_NOR is not set
++# CONFIG_ASPEED_CS2_NAND is not set
++# CONFIG_ASPEED_CS2_SPI is not set
++CONFIG_ASPEED_CS2_NONE=y
++# CONFIG_ASPEED_CS3_NOR is not set
++# CONFIG_ASPEED_CS3_NAND is not set
++# CONFIG_ASPEED_CS3_SPI is not set
++CONFIG_ASPEED_CS3_NONE=y
++# CONFIG_ASPEED_CS4_NOR is not set
++CONFIG_ASPEED_CS4_NAND=y
++# CONFIG_ASPEED_CS4_SPI is not set
++# CONFIG_ASPEED_CS4_NONE is not set
++# CONFIG_ARCH_AST1070 is not set
++# CONFIG_ASPEED_SCU_LOCK is not set
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++CONFIG_PLAT_ASPEED=y
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_NOIFAR=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++# CONFIG_OUTER_CACHE is not set
++
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++# CONFIG_AEABI is not set
++CONFIG_ARCH_FLATMEM_HAS_HOLES=y
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_UNEVICTABLE_LRU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++CONFIG_CMDLINE=""
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++CONFIG_FPE_NWFPE_XP=y
++# CONFIG_FPE_FASTFPE is not set
++# CONFIG_VFP is not set
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
++CONFIG_BINFMT_AOUT=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++
++#
++# Power management options
++#
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++CONFIG_PM_SLEEP=y
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_APM_EMULATION is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++CONFIG_XFRM_IPCOMP=m
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=m
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++CONFIG_IPV6=m
++CONFIG_IPV6_PRIVACY=y
++CONFIG_IPV6_ROUTER_PREF=y
++CONFIG_IPV6_ROUTE_INFO=y
++CONFIG_IPV6_OPTIMISTIC_DAD=y
++CONFIG_INET6_AH=m
++CONFIG_INET6_ESP=m
++CONFIG_INET6_IPCOMP=m
++CONFIG_IPV6_MIP6=m
++CONFIG_INET6_XFRM_TUNNEL=m
++CONFIG_INET6_TUNNEL=m
++CONFIG_INET6_XFRM_MODE_TRANSPORT=m
++CONFIG_INET6_XFRM_MODE_TUNNEL=m
++CONFIG_INET6_XFRM_MODE_BEET=m
++CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
++CONFIG_IPV6_SIT=m
++CONFIG_IPV6_NDISC_NODETYPE=y
++CONFIG_IPV6_TUNNEL=m
++CONFIG_IPV6_MULTIPLE_TABLES=y
++CONFIG_IPV6_SUBTREES=y
++# CONFIG_IPV6_MROUTE is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++CONFIG_WAN_ROUTER=y
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++# CONFIG_PHONET is not set
++CONFIG_FIB_RULES=y
++# CONFIG_WIRELESS is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_SYS_HYPERVISOR is not set
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_CONCAT=y
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++CONFIG_MTD_DATAFLASH=y
++# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
++# CONFIG_MTD_DATAFLASH_OTP is not set
++CONFIG_MTD_M25P80=y
++CONFIG_M25PXX_USE_FAST_READ=y
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++CONFIG_MTD_NAND=y
++# CONFIG_MTD_NAND_VERIFY_WRITE is not set
++# CONFIG_MTD_NAND_ECC_SMC is not set
++# CONFIG_MTD_NAND_MUSEUM_IDS is not set
++CONFIG_MTD_NAND_AST=y
++# CONFIG_MTD_NAND_GPIO is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++# CONFIG_MTD_ALAUDA is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++CONFIG_BLK_DEV_NBD=m
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=16384
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ICS932S401 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_C2PORT is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++CONFIG_SCSI_TGT=y
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++CONFIG_SCSI_SCAN_ASYNC=y
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++CONFIG_SCSI_ISCSI_ATTRS=m
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++CONFIG_BONDING=y
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++# CONFIG_VETH is not set
++# CONFIG_NET_ETHERNET is not set
++CONFIG_NETDEV_1000=y
++CONFIG_ASPEEDMAC=y
++CONFIG_MAC0_PHY_LINK=y
++# CONFIG_NETDEV_10000 is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++# CONFIG_IWLWIFI_LEDS is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_GPIO is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_ELANTECH is not set
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++CONFIG_MOUSE_SERIAL=y
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_BCM5974 is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_AMBAKMI is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++CONFIG_DEVKMEM=y
++CONFIG_SERIAL_NONSTANDARD=y
++# CONFIG_N_HDLC is not set
++# CONFIG_RISCOM8 is not set
++# CONFIG_SPECIALIX is not set
++# CONFIG_RIO is not set
++# CONFIG_STALDRV is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=3
++CONFIG_SERIAL_8250_RUNTIME_UARTS=3
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++# CONFIG_SERIAL_AMBA_PL011 is not set
++# CONFIG_SERIAL_ASPEED is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++# CONFIG_HW_RANDOM is not set
++CONFIG_NVRAM=y
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_HELPER_AUTO=y
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++CONFIG_I2C_ASPEED=y
++CONFIG_AST_I2C_SLAVE_MODE=y
++# CONFIG_I2C_SIMTEC is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_STUB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++CONFIG_AT24=y
++# CONFIG_SENSORS_EEPROM is not set
++# CONFIG_SENSORS_PCF8574 is not set
++# CONFIG_PCF8575 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
++
++#
++# SPI Master Controller Drivers
++#
++# CONFIG_SPI_AST is not set
++CONFIG_SPI_FMC=y
++CONFIG_SPI_BITBANG=y
++
++#
++# SPI Protocol Masters
++#
++# CONFIG_SPI_AT25 is not set
++# CONFIG_SPI_SPIDEV is not set
++# CONFIG_SPI_TLE62X0 is not set
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO expanders:
++#
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_AD7414 is not set
++# CONFIG_SENSORS_AD7418 is not set
++# CONFIG_SENSORS_ADCXX is not set
++# CONFIG_SENSORS_ADM1021 is not set
++# CONFIG_SENSORS_ADM1025 is not set
++# CONFIG_SENSORS_ADM1026 is not set
++# CONFIG_SENSORS_ADM1029 is not set
++# CONFIG_SENSORS_ADM1031 is not set
++# CONFIG_SENSORS_ADM9240 is not set
++# CONFIG_SENSORS_ADT7462 is not set
++# CONFIG_SENSORS_ADT7470 is not set
++# CONFIG_SENSORS_ADT7473 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_F75375S is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_LM63 is not set
++# CONFIG_SENSORS_LM70 is not set
++# CONFIG_SENSORS_LM75 is not set
++# CONFIG_SENSORS_LM77 is not set
++# CONFIG_SENSORS_LM78 is not set
++# CONFIG_SENSORS_LM80 is not set
++# CONFIG_SENSORS_LM83 is not set
++# CONFIG_SENSORS_LM85 is not set
++# CONFIG_SENSORS_LM87 is not set
++# CONFIG_SENSORS_LM90 is not set
++# CONFIG_SENSORS_LM92 is not set
++# CONFIG_SENSORS_LM93 is not set
++# CONFIG_SENSORS_MAX1111 is not set
++# CONFIG_SENSORS_MAX1619 is not set
++# CONFIG_SENSORS_MAX6650 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_DME1737 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++# CONFIG_SENSORS_ADS7828 is not set
++# CONFIG_SENSORS_THMC50 is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_W83781D is not set
++# CONFIG_SENSORS_W83791D is not set
++# CONFIG_SENSORS_W83792D is not set
++# CONFIG_SENSORS_W83793 is not set
++# CONFIG_SENSORS_W83L785TS is not set
++# CONFIG_SENSORS_W83L786NG is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++# CONFIG_SENSORS_AST_ADC is not set
++CONFIG_SENSORS_AST_PWM_FAN=y
++# CONFIG_SENSORS_AST_PECI is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++# CONFIG_THERMAL is not set
++# CONFIG_THERMAL_HWMON is not set
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++CONFIG_ASPEED_WATCHDOG=y
++
++#
++# USB-based Watchdog Cards
++#
++# CONFIG_USBPCWATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM8350_I2C is not set
++
++#
++# Multimedia devices
++#
++
++#
++# Multimedia core support
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_VIDEO_MEDIA is not set
++
++#
++# Multimedia drivers
++#
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++CONFIG_FB=y
++CONFIG_FIRMWARE_EDID=y
++# CONFIG_FB_DDC is not set
++# CONFIG_FB_BOOT_VESA_SUPPORT is not set
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
++# CONFIG_FB_SYS_FILLRECT is not set
++# CONFIG_FB_SYS_COPYAREA is not set
++# CONFIG_FB_SYS_IMAGEBLIT is not set
++# CONFIG_FB_FOREIGN_ENDIAN is not set
++# CONFIG_FB_SYS_FOPS is not set
++# CONFIG_FB_SVGALIB is not set
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_BACKLIGHT is not set
++CONFIG_FB_MODE_HELPERS=y
++CONFIG_FB_TILEBLITTING=y
++
++#
++# Frame buffer hardware drivers
++#
++# CONFIG_FB_ARMCLCD is not set
++CONFIG_FB_UVESA=y
++# CONFIG_FB_S1D13XXX is not set
++CONFIG_FB_AST=y
++CONFIG_AST_DAC=y
++# CONFIG_AST_DVO is not set
++# CONFIG_FB_VIRTUAL is not set
++# CONFIG_FB_METRONOME is not set
++# CONFIG_FB_MB862XX is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
++# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
++CONFIG_FONTS=y
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++# CONFIG_FONT_6x11 is not set
++# CONFIG_FONT_7x14 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++# CONFIG_FONT_MINI_4x6 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_10x18 is not set
++CONFIG_LOGO=y
++CONFIG_LOGO_LINUX_MONO=y
++CONFIG_LOGO_LINUX_VGA16=y
++CONFIG_LOGO_LINUX_CLUT224=y
++# CONFIG_SOUND is not set
++CONFIG_HID_SUPPORT=y
++CONFIG_HID=y
++CONFIG_HID_DEBUG=y
++# CONFIG_HIDRAW is not set
++
++#
++# USB Input Devices
++#
++CONFIG_USB_HID=y
++# CONFIG_HID_PID is not set
++# CONFIG_USB_HIDDEV is not set
++
++#
++# Special HID drivers
++#
++CONFIG_HID_COMPAT=y
++CONFIG_HID_A4TECH=y
++CONFIG_HID_APPLE=y
++CONFIG_HID_BELKIN=y
++CONFIG_HID_BRIGHT=y
++CONFIG_HID_CHERRY=y
++CONFIG_HID_CHICONY=y
++CONFIG_HID_CYPRESS=y
++CONFIG_HID_DELL=y
++CONFIG_HID_EZKEY=y
++CONFIG_HID_GYRATION=y
++CONFIG_HID_LOGITECH=y
++# CONFIG_LOGITECH_FF is not set
++# CONFIG_LOGIRUMBLEPAD2_FF is not set
++CONFIG_HID_MICROSOFT=y
++CONFIG_HID_MONTEREY=y
++CONFIG_HID_PANTHERLORD=y
++# CONFIG_PANTHERLORD_FF is not set
++CONFIG_HID_PETALYNX=y
++CONFIG_HID_SAMSUNG=y
++CONFIG_HID_SONY=y
++CONFIG_HID_SUNPLUS=y
++# CONFIG_THRUSTMASTER_FF is not set
++# CONFIG_ZEROPLUS_FF is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++# CONFIG_USB_ARCH_HAS_OHCI is not set
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=y
++# CONFIG_USB_DEBUG is not set
++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_SUSPEND is not set
++# CONFIG_USB_OTG is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++CONFIG_USB_EHCI_HCD=y
++# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
++CONFIG_USB_EHCI_TT_NEWSCHED=y
++CONFIG_USB_EHCI_AST=y
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_HWA_HCD is not set
++
++#
++# AST USB Drivers
++#
++CONFIG_AST_USB_UHCI_HCD=y
++# CONFIG_AST_USB_UHCI_MULTIPORT_1 is not set
++# CONFIG_AST_USB_UHCI_MULTIPORT_2 is not set
++CONFIG_AST_USB_UHCI_MULTIPORT_4=y
++# CONFIG_USB_EHCI_SPLIT_ISO is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
++#
++
++#
++# see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=y
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_SISUSBVGA is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_VST is not set
++# CONFIG_USB_GADGET is not set
++CONFIG_MMC=y
++# CONFIG_MMC_DEBUG is not set
++# CONFIG_MMC_UNSAFE_RESUME is not set
++
++#
++# MMC/SD/SDIO Card Drivers
++#
++CONFIG_MMC_BLOCK=y
++CONFIG_MMC_BLOCK_BOUNCE=y
++# CONFIG_SDIO_UART is not set
++# CONFIG_MMC_TEST is not set
++
++#
++# MMC/SD/SDIO Host Controller Drivers
++#
++# CONFIG_MMC_ARMMMCI is not set
++# CONFIG_MMC_SDHCI is not set
++CONFIG_MMC_ASPEED=y
++# CONFIG_MMC_SPI is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++# CONFIG_RTC_HCTOSYS is not set
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++# CONFIG_RTC_DRV_DS1307 is not set
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++
++#
++# SPI RTC drivers
++#
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
++# CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_PL030 is not set
++# CONFIG_RTC_DRV_PL031 is not set
++CONFIG_RTC_DRV_ASPEED=y
++# CONFIG_DMADEVICES is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++CONFIG_EXT2_FS_XATTR=y
++CONFIG_EXT2_FS_POSIX_ACL=y
++CONFIG_EXT2_FS_SECURITY=y
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4_FS is not set
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_FILE_LOCKING=y
++# CONFIG_XFS_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++CONFIG_GENERIC_ACL=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=y
++# CONFIG_NTFS_DEBUG is not set
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=m
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_YAFFS_FS=y
++CONFIG_YAFFS_YAFFS1=y
++# CONFIG_YAFFS_9BYTE_TAGS is not set
++# CONFIG_YAFFS_DOES_ECC is not set
++CONFIG_YAFFS_YAFFS2=y
++CONFIG_YAFFS_AUTO_YAFFS2=y
++# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set
++# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
++# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
++# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
++CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
++# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set
++# CONFIG_JFFS2_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_NFS_V4 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_REGISTER_V4 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf8"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++CONFIG_NLS_CODEPAGE_936=y
++CONFIG_NLS_CODEPAGE_950=y
++CONFIG_NLS_CODEPAGE_932=y
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++# CONFIG_ENABLE_WARN_DEPRECATED is not set
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_MEMORY_INIT=y
++CONFIG_FRAME_POINTER=y
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_LATENCYTOP is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++
++#
++# Tracers
++#
++# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++# CONFIG_CRYPTO_FIPS is not set
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD=m
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_NULL=y
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_AUTHENC=m
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++# CONFIG_CRYPTO_ECB is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_XCBC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++CONFIG_CRYPTO_SHA1=y
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=m
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++# CONFIG_CRYPTO_HW is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++CONFIG_CRC_ITU_T=m
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff --git a/arch/arm/configs/ast2400_slt_defconfig b/arch/arm/configs/ast2400_slt_defconfig
+new file mode 100644
+index 0000000..fece826
+--- /dev/null
++++ b/arch/arm/configs/ast2400_slt_defconfig
+@@ -0,0 +1,1015 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.28.9
++# Thu Mar 27 14:10:01 2014
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++# CONFIG_GENERIC_TIME is not set
++# CONFIG_GENERIC_CLOCKEVENTS is not set
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_IKCONFIG is not set
++CONFIG_LOG_BUF_SHIFT=16
++# CONFIG_CGROUPS is not set
++# CONFIG_GROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++CONFIG_KALLSYMS_EXTRA_PASS=y
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++CONFIG_COMPAT_BRK=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_ARCH_ASPEED=y
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM is not set
++CONFIG_IRMP=y
++# CONFIG_PCEXT is not set
++# CONFIG_REMOTEFX is not set
++# CONFIG_ARCH_AST1100 is not set
++# CONFIG_ARCH_AST2100 is not set
++# CONFIG_ARCH_AST2200 is not set
++# CONFIG_ARCH_AST2300 is not set
++CONFIG_ARCH_AST2400=y
++# CONFIG_ARCH_AST2500 is not set
++
++#
++# FLASH Chip Select
++#
++# CONFIG_AST_CS0_NOR is not set
++# CONFIG_AST_CS0_NAND is not set
++CONFIG_AST_CS0_SPI=y
++# CONFIG_AST_CS0_NONE is not set
++# CONFIG_AST_CS1_NOR is not set
++# CONFIG_AST_CS1_NAND is not set
++# CONFIG_AST_CS1_SPI is not set
++CONFIG_AST_CS1_NONE=y
++# CONFIG_AST_CS2_NOR is not set
++# CONFIG_AST_CS2_NAND is not set
++# CONFIG_AST_CS2_SPI is not set
++CONFIG_AST_CS2_NONE=y
++# CONFIG_AST_CS3_NOR is not set
++# CONFIG_AST_CS3_NAND is not set
++# CONFIG_AST_CS3_SPI is not set
++CONFIG_AST_CS3_NONE=y
++# CONFIG_AST_CS4_NOR is not set
++# CONFIG_AST_CS4_NAND is not set
++# CONFIG_AST_CS4_SPI is not set
++CONFIG_AST_CS4_NONE=y
++# CONFIG_ARCH_AST1070 is not set
++# CONFIG_AST_SCU_LOCK is not set
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++CONFIG_PLAT_ASPEED=y
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_NOIFAR=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++# CONFIG_OUTER_CACHE is not set
++
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++# CONFIG_AEABI is not set
++CONFIG_ARCH_FLATMEM_HAS_HOLES=y
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_UNEVICTABLE_LRU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++CONFIG_CMDLINE=""
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++CONFIG_FPE_NWFPE_XP=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_VFP=y
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
++CONFIG_BINFMT_AOUT=y
++# CONFIG_BINFMT_MISC is not set
++# CONFIG_ARTHUR is not set
++
++#
++# Power management options
++#
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++CONFIG_PM_SLEEP=y
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_APM_EMULATION is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++# CONFIG_NET is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_SYS_HYPERVISOR is not set
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_CONCAT=y
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++# CONFIG_MTD_CMDLINE_PARTS is not set
++# CONFIG_MTD_AFS_PARTS is not set
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++CONFIG_MTD_DATAFLASH=y
++# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
++# CONFIG_MTD_DATAFLASH_OTP is not set
++CONFIG_MTD_M25P80=y
++CONFIG_M25PXX_USE_FAST_READ=y
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++CONFIG_MTD_NAND=y
++# CONFIG_MTD_NAND_VERIFY_WRITE is not set
++# CONFIG_MTD_NAND_ECC_SMC is not set
++# CONFIG_MTD_NAND_MUSEUM_IDS is not set
++CONFIG_MTD_NAND_AST=y
++# CONFIG_MTD_NAND_GPIO is not set
++CONFIG_MTD_NAND_IDS=y
++# CONFIG_MTD_NAND_DISKONCHIP is not set
++# CONFIG_MTD_NAND_NANDSIM is not set
++# CONFIG_MTD_NAND_PLATFORM is not set
++# CONFIG_MTD_ALAUDA is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=16384
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_CDROM_PKTCDVD is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_C2PORT is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++CONFIG_SCSI_TGT=y
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++CONFIG_SCSI_SCAN_ASYNC=y
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_GPIO is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_ELANTECH is not set
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++CONFIG_MOUSE_SERIAL=y
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_BCM5974 is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_AMBAKMI is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++CONFIG_DEVKMEM=y
++CONFIG_SERIAL_NONSTANDARD=y
++# CONFIG_N_HDLC is not set
++# CONFIG_RISCOM8 is not set
++# CONFIG_SPECIALIX is not set
++# CONFIG_RIO is not set
++# CONFIG_STALDRV is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=4
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++# CONFIG_SERIAL_AST_DMA_UART is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++# CONFIG_SERIAL_AMBA_PL011 is not set
++# CONFIG_SERIAL_AST is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_AST_MISC=y
++# CONFIG_AST_VIDEO is not set
++# CONFIG_ADC_CAT9883 is not set
++# CONFIG_AST_SPI_BIOS is not set
++CONFIG_AST_PECI=y
++# CONFIG_AST_KCS is not set
++# CONFIG_AST_GPIO is not set
++# CONFIG_HW_RANDOM is not set
++CONFIG_NVRAM=y
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++# CONFIG_I2C is not set
++# CONFIG_AST_I2C_SLAVE_EEPROM is not set
++# CONFIG_AST_I2C_SLAVE_RDWR is not set
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
++
++#
++# SPI Master Controller Drivers
++#
++# CONFIG_SPI_AST is not set
++CONFIG_SPI_FMC=y
++# CONFIG_SPI_BITBANG is not set
++
++#
++# SPI Protocol Masters
++#
++# CONFIG_SPI_AT25 is not set
++CONFIG_SPI_SPIDEV=y
++# CONFIG_SPI_TLE62X0 is not set
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO expanders:
++#
++
++#
++# I2C GPIO expanders:
++#
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++# CONFIG_HWMON is not set
++# CONFIG_THERMAL is not set
++# CONFIG_THERMAL_HWMON is not set
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++CONFIG_AST_WATCHDOG=y
++
++#
++# USB-based Watchdog Cards
++#
++# CONFIG_USBPCWATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_TC6393XB is not set
++
++#
++# Multimedia devices
++#
++
++#
++# Multimedia core support
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_VIDEO_MEDIA is not set
++
++#
++# Multimedia drivers
++#
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_SOUND is not set
++# CONFIG_HID_SUPPORT is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++# CONFIG_USB_ARCH_HAS_OHCI is not set
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=y
++# CONFIG_USB_DEBUG is not set
++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_SUSPEND is not set
++# CONFIG_USB_OTG is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++CONFIG_USB_EHCI_HCD=y
++# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
++CONFIG_USB_EHCI_TT_NEWSCHED=y
++CONFIG_USB_EHCI_AST=y
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_HWA_HCD is not set
++
++#
++# AST USB Drivers
++#
++CONFIG_AST_USB_UHCI_HCD=y
++# CONFIG_AST_USB_UHCI_MULTIPORT_1 is not set
++# CONFIG_AST_USB_UHCI_MULTIPORT_2 is not set
++CONFIG_AST_USB_UHCI_MULTIPORT_4=y
++# CONFIG_USB_EHCI_SPLIT_ISO is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
++#
++
++#
++# see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=y
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_SISUSBVGA is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_VST is not set
++# CONFIG_USB_GADGET is not set
++CONFIG_MMC=y
++# CONFIG_MMC_DEBUG is not set
++# CONFIG_MMC_UNSAFE_RESUME is not set
++
++#
++# MMC/SD/SDIO Card Drivers
++#
++CONFIG_MMC_BLOCK=y
++CONFIG_MMC_BLOCK_BOUNCE=y
++# CONFIG_SDIO_UART is not set
++# CONFIG_MMC_TEST is not set
++
++#
++# MMC/SD/SDIO Host Controller Drivers
++#
++# CONFIG_MMC_ARMMMCI is not set
++# CONFIG_MMC_SDHCI is not set
++CONFIG_MMC_AST=y
++# CONFIG_MMC_SPI is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++# CONFIG_RTC_CLASS is not set
++# CONFIG_DMADEVICES is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++CONFIG_EXT2_FS_XATTR=y
++CONFIG_EXT2_FS_POSIX_ACL=y
++CONFIG_EXT2_FS_SECURITY=y
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4_FS is not set
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_FILE_LOCKING=y
++# CONFIG_XFS_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++CONFIG_GENERIC_ACL=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=y
++# CONFIG_NTFS_DEBUG is not set
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=m
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_YAFFS_FS=y
++CONFIG_YAFFS_YAFFS1=y
++# CONFIG_YAFFS_9BYTE_TAGS is not set
++# CONFIG_YAFFS_DOES_ECC is not set
++CONFIG_YAFFS_YAFFS2=y
++CONFIG_YAFFS_AUTO_YAFFS2=y
++# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set
++# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
++# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
++# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
++CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
++# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set
++# CONFIG_JFFS2_FS is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf8"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++CONFIG_NLS_CODEPAGE_936=y
++CONFIG_NLS_CODEPAGE_950=y
++CONFIG_NLS_CODEPAGE_932=y
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++# CONFIG_ENABLE_WARN_DEPRECATED is not set
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_MEMORY_INIT=y
++CONFIG_FRAME_POINTER=y
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_LATENCYTOP is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++
++#
++# Tracers
++#
++# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++# CONFIG_CRYPTO is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++CONFIG_CRC_ITU_T=m
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
+index 21e17dc..8ff0e23 100644
+--- a/arch/arm/kernel/head.S
++++ b/arch/arm/kernel/head.S
+@@ -21,6 +21,7 @@
+ #include <asm/memory.h>
+ #include <asm/thread_info.h>
+ #include <asm/system.h>
++#include <asm/mach-types.h>
+
+ #if (PHYS_OFFSET & 0x001fffff)
+ #error "PHYS_OFFSET must be at an even 2MiB boundary!"
+@@ -76,13 +77,14 @@
+ */
+ .section ".text.head", "ax"
+ ENTRY(stext)
++ ldr r5, =machine_arch_type @ find the machine type
+ msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
+ @ and irqs disabled
+ mrc p15, 0, r9, c0, c0 @ get processor id
+ bl __lookup_processor_type @ r5=procinfo r9=cpuid
+ movs r10, r5 @ invalid processor (r5=0)?
+ beq __error_p @ yes, error 'p'
+- bl __lookup_machine_type @ r5=machinfo
++@ bl __lookup_machine_type @ r5=machinfo
+ movs r8, r5 @ invalid machine (r5=0)?
+ beq __error_a @ yes, error 'a'
+ bl __vet_atags
+diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
+new file mode 100644
+index 0000000..a948ab8
+--- /dev/null
++++ b/arch/arm/mach-aspeed/Kconfig
+@@ -0,0 +1,214 @@
++if ARCH_ASPEED
++
++choice
++ prompt "ASPEED Processor Family"
++ default CONFIG_IRMP
++
++config IRMP
++ bool "IRMP Serials"
++
++config PCEXT
++ bool "PC Extender Serials"
++
++config REMOTEFX
++ bool "RemoteFX Zero-Client Serials"
++
++endchoice
++
++if IRMP
++
++choice
++ prompt "IRMP Serials"
++ default CONFIG_ARCH_AST2300
++
++config ARCH_AST1100
++ bool "AST1100"
++
++config ARCH_AST2100
++ bool "AST2100"
++
++config ARCH_AST2200
++ bool "AST2200"
++
++config ARCH_AST2300
++ bool "AST2300"
++
++config ARCH_AST2400
++ select USB_ARCH_HAS_EHCI
++ bool "AST2400"
++
++config ARCH_AST2500
++ select USB_ARCH_HAS_EHCI
++ bool "AST2500"
++
++endchoice
++
++endif
++
++if PCEXT
++
++choice
++ prompt "PC Extender Serials"
++ default CONFIG_ARCH_AST1510
++
++config ARCH_AST1500
++ bool "AST1500"
++
++config ARCH_AST1510
++ bool "AST1510"
++
++config ARCH_AST1520
++ select USB_ARCH_HAS_EHCI
++ bool "AST1520"
++
++endchoice
++
++endif
++
++if REMOTEFX
++
++choice
++ prompt "RemoteFX Zero-Client Serials"
++ default CONFIG_ARCH_AST3100
++
++config ARCH_AST3100
++ select USB_ARCH_HAS_EHCI
++ bool "AST3100"
++
++config ARCH_AST3200
++ select USB_ARCH_HAS_EHCI
++ bool "AST3200"
++
++endchoice
++
++endif
++
++menu "FLASH Chip Select"
++
++choice
++ prompt "CS0 Config"
++ default CONFIG_AST_CS0_SPI
++
++config AST_CS0_NOR
++ bool "NOR"
++
++config AST_CS0_NAND
++ bool "NAND"
++
++config AST_CS0_SPI
++ bool "SPI_NOR"
++
++config AST_CS0_NONE
++ bool "NONE"
++
++endchoice
++
++choice
++ prompt "CS1 Config"
++ default CONFIG_AST_CS1_SPI
++
++config AST_CS1_NOR
++ bool "NOR"
++
++config AST_CS1_NAND
++ bool "NAND"
++
++config AST_CS1_SPI
++ bool "SPI_NOR"
++
++config AST_CS1_NONE
++ bool "NONE"
++
++endchoice
++
++choice
++ prompt "CS2 Config"
++ default CONFIG_AST_CS2_SPI
++
++config AST_CS2_NOR
++ bool "NOR"
++
++config AST_CS2_NAND
++ bool "NAND"
++
++config AST_CS2_SPI
++ bool "SPI_NOR"
++
++config AST_CS2_NONE
++ bool "NONE"
++
++endchoice
++
++choice
++ prompt "CS3 Config"
++ default CONFIG_AST_CS3_SPI
++
++config AST_CS3_NOR
++ bool "NOR"
++
++config AST_CS3_NAND
++ bool "NAND"
++
++config AST_CS3_SPI
++ bool "SPI_NOR"
++
++config AST_CS3_NONE
++ bool "NONE"
++
++endchoice
++
++choice
++ prompt "CS4 Config"
++ default CONFIG_AST_CS4_SPI
++
++config AST_CS4_NOR
++ bool "NOR"
++
++config AST_CS4_NAND
++ bool "NAND"
++
++config AST_CS4_SPI
++ bool "SPI_NOR"
++
++config AST_CS4_NONE
++ bool "NONE"
++
++endchoice
++
++endmenu
++
++config ARCH_AST1070
++ bool "AST1070 Comapnion chip combination"
++
++config AST1070_NR
++ int "Number of AST1070 Comapniion Chip combination"
++ depends on ARCH_AST1070
++ default "1"
++ help
++ Set this to the number of ast1070
++
++choice
++ prompt "Connect Bus Interface"
++ depends on ARCH_AST1070
++ default CONFIG_AST_LPC_PLUS
++
++config AST_LPC_PLUS
++ bool "LPC PLUS"
++
++config AST_LPC
++ bool "LPC"
++
++endchoice
++
++config AST_SCU_LOCK
++ bool "AST SCU Protection Key"
++
++# Support PCIE
++config PCIE
++ bool "ASPEED PCIE support"
++ depends on PCI && ARCH_ASPEED
++ select ARCH_SUPPORTS_MSI
++ help
++ Socle PCIE support
++
++endif
+diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
+new file mode 100644
+index 0000000..ae63d8c
+--- /dev/null
++++ b/arch/arm/mach-aspeed/Makefile
+@@ -0,0 +1,22 @@
++#
++# Makefile for the linux kernel.
++#
++
++# Common support (must be linked before board specific support)
++
++# Specific board support
++obj-$(CONFIG_ARCH_AST1100) += ast1100.o
++obj-$(CONFIG_ARCH_AST2100) += ast2100.o
++obj-$(CONFIG_ARCH_AST2300) += ast2300.o gpio.o ast-lpc.o
++obj-$(CONFIG_ARCH_AST2400) += ast2400.o gpio.o ast-lpc.o ast-lpc_plus.o
++obj-$(CONFIG_ARCH_AST2500) += ast2500.o ast-mctp.o
++#PC Ext
++obj-$(CONFIG_ARCH_AST1510) += ast1510.o gpio.o
++obj-$(CONFIG_ARCH_AST1520) += ast1520.o ast-mctp.o
++
++#RemoteFx Zero client
++obj-$(CONFIG_ARCH_AST3100) += ast3100.o gpio.o
++obj-$(CONFIG_ARCH_AST3200) += ast3200.o ast-mctp.o
++
++#BMC Comapnion Controller
++obj-$(CONFIG_ARCH_AST1070) += ast1070.o
+diff --git a/arch/arm/mach-aspeed/Makefile.boot b/arch/arm/mach-aspeed/Makefile.boot
+new file mode 100644
+index 0000000..a1e3bf8
+--- /dev/null
++++ b/arch/arm/mach-aspeed/Makefile.boot
+@@ -0,0 +1,42 @@
++ifeq ($(CONFIG_ARCH_AST1510),y)
++ zreladdr-y := 0x40008000
++params_phys-y := 0x40000100
++initrd_phys-y := 0x40800000
++endif
++
++ifeq ($(CONFIG_ARCH_AST2300),y)
++ zreladdr-y := 0x40008000
++params_phys-y := 0x40000100
++initrd_phys-y := 0x40800000
++endif
++
++ifeq ($(CONFIG_ARCH_AST2400),y)
++ zreladdr-y := 0x40008000
++params_phys-y := 0x40000100
++initrd_phys-y := 0x40800000
++endif
++
++ifeq ($(CONFIG_ARCH_AST2500),y)
++ zreladdr-y := 0x80008000
++params_phys-y := 0x80000100
++initrd_phys-y := 0x80800000
++endif
++
++ifeq ($(CONFIG_ARCH_AST3100),y)
++ zreladdr-y := 0x40008000
++params_phys-y := 0x40000100
++initrd_phys-y := 0x40800000
++endif
++
++ifeq ($(CONFIG_ARCH_AST1520),y)
++ zreladdr-y := 0x80008000
++params_phys-y := 0x80000100
++initrd_phys-y := 0x80800000
++endif
++
++ifeq ($(CONFIG_ARCH_AST3200),y)
++ zreladdr-y := 0x80008000
++params_phys-y := 0x80000100
++initrd_phys-y := 0x80800000
++endif
++
+diff --git a/arch/arm/mach-aspeed/ast-lpc.c b/arch/arm/mach-aspeed/ast-lpc.c
+new file mode 100644
+index 0000000..b26e2cc
+--- /dev/null
++++ b/arch/arm/mach-aspeed/ast-lpc.c
+@@ -0,0 +1,423 @@
++/********************************************************************************
++* File Name : arch/arm/mach-aspeed/ast-lpc.c
++* Author : Ryan Chen
++* Description : AST LPC
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2013/05/15 Ryan Chen Create
++*
++********************************************************************************/
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/delay.h>
++
++#include <mach/platform.h>
++#include <asm/io.h>
++#include <linux/interrupt.h>
++
++#include <mach/hardware.h>
++
++#include <plat/regs-lpc.h>
++#include <plat/ast-snoop.h>
++#include <plat/ast-lpc.h>
++#ifdef CONFIG_ARCH_AST1070
++#include <plat/ast1070-scu.h>
++#include <plat/ast1070-devs.h>
++#include <plat/regs-ast1070-intc.h>
++#include <plat/ast1070-uart-dma.h>
++#endif
++
++//#define AST_LPC_DEBUG
++
++#ifdef AST_LPC_DEBUG
++#define LPCDBUG(fmt, args...) printk("%s() " fmt, __FUNCTION__, ## args)
++#else
++#define LPCDBUG(fmt, args...)
++#endif
++
++#if 0
++static inline u32
++ast_lpc_read(u32 reg)
++{
++ u32 val;
++
++ val = readl(ast_lpc_base + reg);
++
++ LPCDBUG("ast_lpc_read : reg = 0x%08x, val = 0x%08x\n", reg, val);
++
++ return val;
++}
++
++static inline void
++ast_lpc_write(u32 val, u32 reg)
++{
++ LPCDBUG("ast_lpc_write : reg = 0x%08x, val = 0x%08x\n", reg, val);
++ writel(val, ast_lpc_base + reg);
++}
++
++/******************************************************************************/
++
++//Suppose you are going to snoop 0x80 ~ 0x87
++//snoop_init(0x80, 0x7, WORD_MODE, buf_dma, (SNOOP_DMA_BOUNDARY / 4)); //register in unit of DWORD
++#if 0
++extern void
++ast_lpc_snoop_dma_enable(u16 port_number, u8 port_mask, u8 mode, dma_addr_t dma_base, u16 size)
++{
++ write_register(0x1e789134, (port_mask << 16) + port_number);
++ write_register(0x1e7890d0, dma_base);
++ write_register(0x1e7890d4, (size - 1));
++ write_register(0x1e789130, (mode << 4) | ENABLE_DMA_INTERRUPT | ENABLE_POST_CODE_FUNCTION | ENABLE_SNOOP_DMA_MODE);
++
++ //Enable error interrupt to check LPC reset
++ write_register_or(0x1e789008, 1);
++
++}
++
++EXPORT_SYMBOL(ast_lpc_snoop_dma_init);
++#endif
++
++extern irqreturn_t ast_snoop_handler(int this_irq, void *dev_id)
++{
++ u32 snoop_sts;
++ struct ast_snoop *snoop = dev_id;
++
++ snoop_sts = ast_lpc_read(AST_LPC_HICR6);
++ if((snoop_sts & (LPC_HICR6_STR_SNP1W | LPC_HICR6_STR_SNP0W)) == 0)
++ return IRQ_NONE;
++
++ if(snoop_sts & LPC_HICR6_STR_SNP0W) {
++ snoop->snoop_ch0->snoop_data = GET_LPC_SNPD0(ast_lpc_read(AST_LPC_SNPWDR));
++ //clear
++ ast_lpc_write(LPC_HICR6_STR_SNP0W, AST_LPC_HICR6);
++ }
++
++ if(snoop_sts & LPC_HICR6_STR_SNP1W) {
++ snoop->snoop_ch1->snoop_data = GET_LPC_SNPD1(ast_lpc_read(AST_LPC_SNPWDR));
++ //clear
++ ast_lpc_write(LPC_HICR6_STR_SNP1W, AST_LPC_HICR6);
++
++ }
++
++ return IRQ_HANDLED;
++
++}
++EXPORT_SYMBOL(ast_snoop_handler);
++
++extern irqreturn_t ast_snoop_dma_handler(int this_irq, void *dev_id)
++{
++ u32 snoop_dma_sts, lpc_sts;
++ struct ast_snoop_dma_channel *snoop_dma_ch = dev_id;
++
++ snoop_dma_sts = ast_lpc_read(AST_LPC_PCCR2);
++
++ lpc_sts = ast_lpc_read(AST_LPC_HICR2);
++
++ printk("ISR : snoop_dma_sts = %x , lpc_sts = %x \n",snoop_dma_sts, lpc_sts);
++
++ if(lpc_sts & LPC_LRST) {
++ printk("LPC RST === > \n");
++ //clear fifo ??
++ ast_lpc_write(ast_lpc_read(AST_LPC_PCCR0) | LPC_RX_FIFO_CLR, AST_LPC_PCCR0);
++ //clear
++ ast_lpc_write(lpc_sts & ~LPC_LRST, AST_LPC_HICR2);
++
++ }
++
++ if(snoop_dma_sts & LPC_POST_CODE_DMA_RDY) {
++
++
++ }
++
++
++ return IRQ_HANDLED;
++
++}
++EXPORT_SYMBOL(ast_snoop_dma_handler);
++
++extern void ast_snoop_channel_int_enable(struct ast_snoop_channel *ast_ch, u8 enable)
++{
++ printk("ch[%d]int : %s , snoop port : %x",ast_ch->snoop_ch, enable? "Enable":"Disable", ast_ch->snoop_port);
++
++ if(enable) {
++ switch(ast_ch->snoop_ch) {
++ case 0:
++ //enable
++ ast_lpc_write(ast_lpc_read(AST_LPC_HICR5) | LPC_HICR5_SNP0INT_EN,
++ AST_LPC_HICR5);
++ break;
++ case 1:
++ //enable
++ ast_lpc_write(ast_lpc_read(AST_LPC_HICR5) | LPC_HICR5_SNP1INT_EN,
++ AST_LPC_HICR5);
++ break;
++ };
++
++ } else {
++ switch(ast_ch->snoop_ch) {
++ case 0:
++ //disable
++ ast_lpc_write(ast_lpc_read(AST_LPC_HICR5) & ~LPC_HICR5_SNP0INT_EN,
++ AST_LPC_HICR5);
++
++ break;
++ case 1:
++ //disable
++ ast_lpc_write(ast_lpc_read(AST_LPC_HICR5) & ~LPC_HICR5_SNP1INT_EN,
++ AST_LPC_HICR5);
++ };
++
++ }
++
++}
++EXPORT_SYMBOL(ast_snoop_channel_int_enable);
++
++extern void ast_snoop_channel_enable(struct ast_snoop_channel *ast_ch, u8 enable)
++{
++ printk("ch[%d] : %s , snoop port : %x",ast_ch->snoop_ch, enable? "Enable":"Disable", ast_ch->snoop_port);
++
++ if(enable) {
++ switch(ast_ch->snoop_ch) {
++ case 0:
++ //disable
++ ast_lpc_write(ast_lpc_read(AST_LPC_HICR5) & ~LPC_HICR5_SNP0W_EN,
++ AST_LPC_HICR5);
++
++ //set port address
++ ast_lpc_write((ast_lpc_read(AST_LPC_SNPWADR) & ~LPC_SNOOP_ADDR0_MASK) |
++ ast_ch->snoop_port,
++ AST_LPC_SNPWADR);
++ //enable
++ ast_lpc_write(ast_lpc_read(AST_LPC_HICR5) | LPC_HICR5_SNP0W_EN,
++ AST_LPC_HICR5);
++ break;
++ case 1:
++ //disable
++ ast_lpc_write(ast_lpc_read(AST_LPC_HICR5) & ~LPC_HICR5_SNP1W_EN,
++ AST_LPC_HICR5);
++
++ //set port address
++ ast_lpc_write((ast_lpc_read(AST_LPC_SNPWADR) & ~LPC_SNOOP_ADDR1_MASK) |
++ ast_ch->snoop_port,
++ AST_LPC_SNPWADR);
++ //enable
++ ast_lpc_write(ast_lpc_read(AST_LPC_HICR5) | LPC_HICR5_SNP1W_EN,
++ AST_LPC_HICR5);
++ break;
++ };
++
++ } else {
++ switch(ast_ch->snoop_ch) {
++ case 0:
++ //disable
++ ast_lpc_write(ast_lpc_read(AST_LPC_HICR5) & ~LPC_HICR5_SNP0W_EN,
++ AST_LPC_HICR5);
++
++ break;
++ case 1:
++ //disable
++ ast_lpc_write(ast_lpc_read(AST_LPC_HICR5) & ~LPC_HICR5_SNP1W_EN,
++ AST_LPC_HICR5);
++
++ };
++
++ }
++
++}
++EXPORT_SYMBOL(ast_snoop_channel_enable);
++
++extern void ast_snoop_dma_ch_enable(struct ast_snoop_dma_channel *ast_dma_ch, u8 enable)
++{
++ printk("ch[%d] : %s , snoop port : %x",ast_dma_ch->snoop_ch, enable? "Enable":"Disable", ast_dma_ch->snoop_port);
++
++ if(enable) {
++ //disable
++ ast_lpc_write(ast_lpc_read(AST_LPC_PCCR0) & ~LPC_POST_CODE_EN,
++ AST_LPC_PCCR0);
++
++ //set port address
++ ast_lpc_write((ast_lpc_read(AST_LPC_PCCR0) & ~LPC_POST_ADDR_MASK) |
++ LPC_CAPTURE_ADDR_MASK(ast_dma_ch->snoop_mask) |
++ LPC_CAPTURE_BASE_ADDR(ast_dma_ch->snoop_port),
++ AST_LPC_PCCR0);
++
++ ast_lpc_write(ast_dma_ch->dma_addr, AST_LPC_PCCR4);
++ ast_lpc_write(ast_dma_ch->dma_size - 1 , AST_LPC_PCCR5);
++
++ //enable
++ ast_lpc_write((ast_lpc_read(AST_LPC_PCCR0) & ~LPC_POST_CODE_MODE_MASK) |
++ LPC_POST_CODE_MODE(ast_dma_ch->snoop_mode) |
++ LPC_POST_DMA_MODE_EN |
++ LPC_POST_CODE_EN,
++ AST_LPC_PCCR0);
++
++ } else {
++ //disable
++ ast_lpc_write(ast_lpc_read(AST_LPC_PCCR0) & ~LPC_POST_CODE_EN,
++ AST_LPC_PCCR0);
++ }
++
++}
++EXPORT_SYMBOL(ast_snoop_dma_ch_enable);
++
++extern int ast_snoop_init(struct ast_snoop *snoop)
++{
++ int ret=0;
++
++ ast_snoop_channel_enable(snoop->snoop_ch0, 1);
++ ast_snoop_channel_enable(snoop->snoop_ch1, 1);
++ //request irq
++ ret = request_irq(IRQ_LPC, ast_snoop_handler, IRQF_SHARED,
++ "ast-snoop", snoop);
++
++ //enable irq
++ ast_lpc_write(ast_lpc_read(AST_LPC_HICR5) | LPC_HICR5_SNP0INT_EN | LPC_HICR5_SNP1INT_EN,
++ AST_LPC_HICR5);
++ return ret;
++}
++EXPORT_SYMBOL(ast_snoop_init);
++
++extern void ast_snoop_dma_init(struct ast_snoop_dma_channel *ast_dma_ch)
++{
++ int ret=0;
++
++ ast_snoop_dma_ch_enable(ast_dma_ch, 1);
++
++ //request irq
++ ret = request_irq(IRQ_LPC, ast_snoop_dma_handler, IRQF_SHARED,
++ "ast-snoop", ast_dma_ch);
++
++ //enable irq
++ ast_lpc_write(ast_lpc_read(AST_LPC_PCCR0) |
++ LPC_POST_DMA_INT_EN,
++ AST_LPC_PCCR0);
++
++ return ret;
++
++}
++EXPORT_SYMBOL(ast_snoop_dma_init);
++#endif
++static struct ast_lpc_driver_data *lpc_driver_data;
++
++static int __devinit ast_lpc_probe(struct platform_device *pdev)
++{
++// const struct platform_device_id *id = platform_get_device_id(pdev);
++ struct resource *res;
++ int ret = 0;
++ int i;
++
++ lpc_driver_data = kzalloc(sizeof(struct ast_lpc_driver_data), GFP_KERNEL);
++ if (lpc_driver_data == NULL) {
++ dev_err(&pdev->dev, "failed to allocate memory\n");
++ return -ENOMEM;
++ }
++
++ lpc_driver_data->pdev = pdev;
++
++ lpc_driver_data->bus_info = pdev->dev.platform_data;
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (res == NULL) {
++ dev_err(&pdev->dev, "no memory resource defined\n");
++ ret = -ENODEV;
++ goto err_free;
++ }
++
++ res = request_mem_region(res->start, resource_size(res), pdev->name);
++ if (res == NULL) {
++ dev_err(&pdev->dev, "failed to request memory resource\n");
++ ret = -EBUSY;
++ goto err_free;
++ }
++
++ lpc_driver_data->reg_base = ioremap(res->start, resource_size(res));
++ if (lpc_driver_data->reg_base == NULL) {
++ dev_err(&pdev->dev, "failed to ioremap() registers\n");
++ ret = -ENODEV;
++ goto err_free_mem;
++ }
++
++#ifdef CONFIG_ARCH_AST1070
++ if(lpc_driver_data->bus_info->bus_scan) {
++ printk("LPC Scan Device... \n");
++ for(i=0;i<lpc_driver_data->bus_info->scan_node;i++) {
++ ast1070_scu_init(i ,lpc_driver_data->bus_info->bridge_phy_addr + i*0x10000);
++ printk("C%d-[%x] ", i, ast1070_revision_id_info(i));
++ ast1070_vic_init(i, (lpc_driver_data->bus_info->bridge_phy_addr + i*0x10000), IRQ_C0_VIC_CHAIN + i, IRQ_C0_VIC_CHAIN_START + (i*AST_CVIC_NUM));
++ ast1070_scu_dma_init(i);
++ ast1070_uart_dma_init(i, lpc_driver_data->bus_info->bridge_phy_addr);
++ ast_add_device_cuart(i,lpc_driver_data->bus_info->bridge_phy_addr + i*0x10000);
++ ast_add_device_ci2c(i,lpc_driver_data->bus_info->bridge_phy_addr + i*0x10000);
++ }
++ printk("\n");
++
++ }
++
++#endif
++
++ platform_set_drvdata(pdev, lpc_driver_data);
++ return 0;
++
++err_free_mem:
++ release_mem_region(res->start, resource_size(res));
++err_free:
++ kfree(lpc_driver_data);
++
++ return ret;
++}
++
++static int __devexit ast_lpc_remove(struct platform_device *pdev)
++{
++ struct ast_lpc_driver_data *lpc_driver_data;
++ struct resource *res;
++
++ lpc_driver_data = platform_get_drvdata(pdev);
++ if (lpc_driver_data == NULL)
++ return -ENODEV;
++
++ iounmap(lpc_driver_data->reg_base);
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ release_mem_region(res->start, resource_size(res));
++
++ kfree(lpc_driver_data);
++
++ return 0;
++}
++
++static struct platform_driver ast_lpc_driver = {
++ .driver = {
++ .name = "ast_lpc",
++ .owner = THIS_MODULE,
++ },
++ .probe = ast_lpc_probe,
++ .remove = __devexit_p(ast_lpc_remove),
++// .id_table = pwm_id_table,
++};
++
++static int __init ast_lpc_init(void)
++{
++ return platform_driver_register(&ast_lpc_driver);
++}
++arch_initcall(ast_lpc_init);
++
++static void __exit ast_lpc_exit(void)
++{
++ platform_driver_unregister(&ast_lpc_driver);
++}
++module_exit(ast_lpc_exit);
++
++MODULE_LICENSE("GPL v2");
+diff --git a/arch/arm/mach-aspeed/ast-lpc_plus.c b/arch/arm/mach-aspeed/ast-lpc_plus.c
+new file mode 100644
+index 0000000..187b8b8
+--- /dev/null
++++ b/arch/arm/mach-aspeed/ast-lpc_plus.c
+@@ -0,0 +1,182 @@
++/********************************************************************************
++* File Name : arch/arm/mach-aspeed/ast-lpc_plus.c
++* Author : Ryan Chen
++* Description : AST LPC
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2013/05/15 Ryan Chen Create
++*
++********************************************************************************/
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/delay.h>
++
++#include <mach/platform.h>
++#include <asm/io.h>
++#include <linux/interrupt.h>
++
++#include <mach/hardware.h>
++
++#include <plat/regs-lpc.h>
++#include <plat/ast-snoop.h>
++#include <plat/ast-lpc.h>
++#ifdef CONFIG_ARCH_AST1070
++#include <plat/ast1070-scu.h>
++#include <plat/ast1070-devs.h>
++#include <plat/regs-ast1070-intc.h>
++#include <plat/ast1070-uart-dma.h>
++#endif
++
++//#define AST_LPCP_DEBUG
++
++#ifdef AST_LPCP_DEBUG
++#define LPCP_DBUG(fmt, args...) printk("%s() " fmt, __FUNCTION__, ## args)
++#else
++#define LPCP_DBUG(fmt, args...)
++#endif
++
++#if 0
++static inline u32
++ast_lpc_plus_write(u32 reg)
++{
++ u32 val;
++
++ val = readl(ast_lpc_base + reg);
++
++ LPCDBUG("ast_lpc_read : reg = 0x%08x, val = 0x%08x\n", reg, val);
++
++ return val;
++}
++
++static inline void
++ast_lpc_plus_write(u32 val, u32 reg)
++{
++ LPCDBUG("ast_lpc_write : reg = 0x%08x, val = 0x%08x\n", reg, val);
++ writel(val, ast_lpc_base + reg);
++}
++#endif
++
++static int __devinit ast_lpc_plus_probe(struct platform_device *pdev)
++{
++ static struct ast_lpc_driver_data *lpc_plus_driver_data;
++// const struct platform_device_id *id = platform_get_device_id(pdev);
++ struct resource *res;
++ int ret = 0;
++ int i;
++
++ lpc_plus_driver_data = kzalloc(sizeof(struct ast_lpc_driver_data), GFP_KERNEL);
++ if (lpc_plus_driver_data == NULL) {
++ dev_err(&pdev->dev, "failed to allocate memory\n");
++ return -ENOMEM;
++ }
++
++ lpc_plus_driver_data->pdev = pdev;
++
++ lpc_plus_driver_data->bus_info = pdev->dev.platform_data;
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (res == NULL) {
++ dev_err(&pdev->dev, "no memory resource defined\n");
++ ret = -ENODEV;
++ goto err_free;
++ }
++
++ res = request_mem_region(res->start, resource_size(res), pdev->name);
++ if (res == NULL) {
++ dev_err(&pdev->dev, "failed to request memory resource\n");
++ ret = -EBUSY;
++ goto err_free;
++ }
++
++ lpc_plus_driver_data->reg_base = ioremap(res->start, resource_size(res));
++ if (lpc_plus_driver_data->reg_base == NULL) {
++ dev_err(&pdev->dev, "failed to ioremap() registers\n");
++ ret = -ENODEV;
++ goto err_free_mem;
++ }
++
++#ifdef CONFIG_ARCH_AST1070
++ if(lpc_plus_driver_data->bus_info->bus_scan) {
++ printk("LPC PLUS Scan Device... ");
++ for(i=0;i<lpc_plus_driver_data->bus_info->scan_node;i++) {
++ ast1070_scu_init(i ,lpc_plus_driver_data->bus_info->bridge_phy_addr + i*0x10000);
++ printk("C%d-[%x] ", i, ast1070_revision_id_info(i));
++ ast1070_vic_init(i, (lpc_plus_driver_data->bus_info->bridge_phy_addr + i*0x10000), IRQ_C0_VIC_CHAIN + i, IRQ_C0_VIC_CHAIN_START + (i*AST_CVIC_NUM));
++ ast1070_scu_dma_init(i);
++ ast1070_uart_dma_init(i, lpc_plus_driver_data->bus_info->bridge_phy_addr);
++ ast_add_device_cuart(i,lpc_plus_driver_data->bus_info->bridge_phy_addr + i*0x10000);
++ ast_add_device_ci2c(i,lpc_plus_driver_data->bus_info->bridge_phy_addr + i*0x10000);
++ }
++ printk("\n");
++
++ }
++
++#endif
++
++ platform_set_drvdata(pdev, lpc_plus_driver_data);
++ return 0;
++
++err_free_mem:
++ release_mem_region(res->start, resource_size(res));
++err_free:
++ kfree(lpc_plus_driver_data);
++
++ return ret;
++}
++
++static int __devexit ast_lpc_plus_remove(struct platform_device *pdev)
++{
++ struct ast_lpc_driver_data *lpc_plus_driver_data;
++ struct resource *res;
++
++ lpc_plus_driver_data = platform_get_drvdata(pdev);
++ if (lpc_plus_driver_data == NULL)
++ return -ENODEV;
++
++ iounmap(lpc_plus_driver_data->reg_base);
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ release_mem_region(res->start, resource_size(res));
++
++ kfree(lpc_plus_driver_data);
++
++ return 0;
++}
++
++static struct platform_driver ast_lpc_plus_driver = {
++ .driver = {
++ .name = "ast_lpc_plus",
++ .owner = THIS_MODULE,
++ },
++ .probe = ast_lpc_plus_probe,
++ .remove = __devexit_p(ast_lpc_plus_remove),
++// .id_table = pwm_id_table,
++};
++
++static int __init ast_lpc_plus_init(void)
++{
++ return platform_driver_register(&ast_lpc_plus_driver);
++}
++arch_initcall(ast_lpc_plus_init);
++
++static void __exit ast_lpc_plus_exit(void)
++{
++ platform_driver_unregister(&ast_lpc_plus_driver);
++}
++module_exit(ast_lpc_plus_exit);
++
++MODULE_LICENSE("GPL v2");
+diff --git a/arch/arm/mach-aspeed/ast-mctp.c b/arch/arm/mach-aspeed/ast-mctp.c
+new file mode 100644
+index 0000000..1dd746b
+--- /dev/null
++++ b/arch/arm/mach-aspeed/ast-mctp.c
+@@ -0,0 +1,153 @@
++/********************************************************************************
++* File Name : arch/arm/mach-aspeed/ast-mctp.c
++* Author : Ryan Chen
++* Description : AST MCTP Ctrl
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++
++* History :
++* 1. 2013/07/15 Ryan Chen Create
++*
++********************************************************************************/
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/delay.h>
++
++#include <mach/platform.h>
++#include <asm/io.h>
++
++#include <mach/hardware.h>
++#include <plat/regs-mctp.h>
++#include <plat/ast_mctp.h>
++
++//#define AST_MCTP_DEBUG 1
++
++#ifdef AST_MCTP_DEBUG
++#define MCTPDBUG(fmt, args...) printk("%s() " fmt, __FUNCTION__, ## args)
++#else
++#define MCTPDBUG(fmt, args...)
++#endif
++
++static u32 ast_mctp_base = 0;
++static u8 txTag = 0;
++static inline u32
++ast_mctp_read(u32 reg)
++{
++ u32 val;
++
++ val = readl(ast_mctp_base + reg);
++
++ MCTPDBUG("reg = 0x%08x, val = 0x%08x\n", reg, val);
++
++ return val;
++}
++
++static inline void
++ast_mctp_write(u32 val, u32 reg)
++{
++ MCTPDBUG("reg = 0x%08x, val = 0x%08x\n", reg, val);
++
++ writel(val, ast_mctp_base + reg);
++}
++
++//***********************************Information ***********************************
++
++extern void ast_pcie_cfg_read(u8 type, u32 bdf_offset, u32 *value)
++{
++ u32 timeout =0;
++ u32 desc3,desc2;
++ txTag %= 0xf;
++// printf("type = %d, busfunc = %x \n",type, bdf);
++ if((ast_mctp_read(AST_MCTP_INT) & MCTP_RX_COMPLETE) != 0)
++ printk("EEEEEEEE \n");
++
++ ast_mctp_write(0x4000001 | (type << 24), AST_MCTP_TX_DESC3);
++ ast_mctp_write(0x200f | (txTag << 8), AST_MCTP_TX_DESC2);
++ ast_mctp_write(bdf_offset, AST_MCTP_TX_DESC1);
++ ast_mctp_write(0, AST_MCTP_TX_DESC0);
++// ast_mctp_write(0, AST_MCTP_TX_DATA);
++
++ //trigger
++ ast_mctp_write(7, AST_MCTP_CTRL);
++ //wait
++// printf("trigger \n");
++ while(!(ast_mctp_read(AST_MCTP_INT) & MCTP_RX_COMPLETE)) {
++ timeout++;
++ if(timeout > 10000) {
++ printk("time out \n");
++ *value = 0xffffffff;
++ goto out;
++ }
++ };
++
++ //read
++ desc3 = ast_mctp_read(AST_MCTP_RX_DESC3);
++ desc2 = ast_mctp_read(AST_MCTP_RX_DESC2);
++ ast_mctp_read(AST_MCTP_RX_DESC1);
++
++ if( ((desc3 >> 24) == 0x4A) &&
++ ((desc3 & 0xfff) == 0x1) &&
++ ((desc2 & 0xe000) == 0)) {
++ *value = ast_mctp_read(AST_MCTP_RX_DATA);
++
++ } else {
++ *value = 0xffffffff;
++
++ }
++
++out:
++ txTag++;
++ ast_mctp_write(0x15, AST_MCTP_CTRL);
++ ast_mctp_write(0x3, AST_MCTP_INT);
++ //wait
++ while(ast_mctp_read(AST_MCTP_INT) & MCTP_RX_COMPLETE);
++
++}
++
++extern void ast_pcie_cfg_write(u8 type, u32 bdf_offset, u32 data)
++{
++ txTag %= 0xf;
++
++ ast_mctp_write(0x44000001 | (type << 24), AST_MCTP_TX_DESC3);
++ ast_mctp_write(0x200f | (txTag << 8), AST_MCTP_TX_DESC2);
++ ast_mctp_write(bdf_offset, AST_MCTP_TX_DESC1);
++ ast_mctp_write(0, AST_MCTP_TX_DESC0);
++ ast_mctp_write(data, AST_MCTP_TX_DATA);
++
++ //trigger
++ ast_mctp_write(7, AST_MCTP_CTRL);
++// printf("trigger \n");
++ //wait
++ while(!(ast_mctp_read(AST_MCTP_INT) & MCTP_RX_COMPLETE));
++
++ //read
++ ast_mctp_read(AST_MCTP_RX_DESC3);
++ ast_mctp_read(AST_MCTP_RX_DESC2);
++ ast_mctp_read(AST_MCTP_RX_DESC1);
++ txTag++;
++ ast_mctp_write(0x15, AST_MCTP_CTRL);
++ ast_mctp_write(0x3, AST_MCTP_INT);
++ //wait
++ while(ast_mctp_read(AST_MCTP_INT) & MCTP_RX_COMPLETE);
++
++}
++
++static int __init ast_mctp_init(void)
++{
++ MCTPDBUG("\n");
++ ast_mctp_base = (u32)ioremap(AST_MCTP_BASE , SZ_256);
++ return 0;
++}
++
++subsys_initcall(ast_mctp_init);
++
+diff --git a/arch/arm/mach-aspeed/ast1070.c b/arch/arm/mach-aspeed/ast1070.c
+new file mode 100644
+index 0000000..12ede8b
+--- /dev/null
++++ b/arch/arm/mach-aspeed/ast1070.c
+@@ -0,0 +1,60 @@
++/*
++ * linux/arch/arm/mach-ast1070/ast1070.c
++ *
++ * 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 <linux/config.h>
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <linux/interrupt.h>
++#include <linux/init.h>
++#include <asm/mach/arch.h>
++#include <asm/mach/map.h>
++#include <plat/devs.h>
++#include <plat/ast1070-scu.h>
++#include <plat/ast1070-uart-dma.h>
++#include <mach/time.h>
++#include <mach/gpio.h>
++
++static int __init ast1070_init(void)
++{
++ int i=0;
++ u8 num = 0;
++ if(gpio_get_value(PIN_GPIOI2))
++ num = 2; //dual 1070
++ else
++ num = 1; //single 1070
++
++ if(CONFIG_AST1070_NR != num)
++ printk("Please check Configuration !!! \n");
++
++#if 0
++ if(gpio_get_value(PIN_GPIOI1))
++ printk("Use LPC+ Bus Access \n");
++ else
++ printk("Use LPC Bus Access \n");
++#endif
++
++ for(i=0; i< CONFIG_AST1070_NR;i++) {
++ ast1070_scu_revision_id(i);
++ ast1070_dma_init(i);
++ ast1070_uart_dma_init(i);
++ }
++
++ return 0;
++}
++
++subsys_initcall(ast1070_init);
++
+diff --git a/arch/arm/mach-aspeed/ast1100.c b/arch/arm/mach-aspeed/ast1100.c
+new file mode 100644
+index 0000000..e2629f1
+--- /dev/null
++++ b/arch/arm/mach-aspeed/ast1100.c
+@@ -0,0 +1,49 @@
++/*
++ * linux/arch/arm/mach-ast2000/ast2000.c
++ *
++ * 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 <linux/config.h>
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <linux/interrupt.h>
++#include <linux/init.h>
++
++#include <mach/hardware.h>
++#include <asm/irq.h>
++#include <asm/setup.h>
++#include <asm/mach-types.h>
++
++#include <asm/mach/arch.h>
++#include <mach/time.h>
++
++extern void aspeed_map_io(void);
++extern void aspeed_init_irq(void);
++extern struct sys_timer aspeed_timer;
++
++static void __init aspeed_init(void)
++{
++ ast_add_all_devices();
++}
++
++MACHINE_START(ASPEED, "AST1100")
++ .phys_io = ASPEED_IO_START,
++// .phys_ram = ASPEED_SDRAM_BASE,
++ .io_pg_offst = (IO_ADDRESS(IO_START)>>18) & 0xfffc,
++ .map_io = aspeed_map_io,
++ .timer = &aspeed_timer,
++ .init_irq = aspeed_init_irq,
++ .init_machine = aspeed_init,
++MACHINE_END
+diff --git a/arch/arm/mach-aspeed/ast2100.c b/arch/arm/mach-aspeed/ast2100.c
+new file mode 100644
+index 0000000..06da653
+--- /dev/null
++++ b/arch/arm/mach-aspeed/ast2100.c
+@@ -0,0 +1,49 @@
++/*
++ * linux/arch/arm/mach-ast2100/ast2100.c
++ *
++ * 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 <linux/config.h>
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <linux/interrupt.h>
++#include <linux/init.h>
++
++#include <mach/hardware.h>
++#include <asm/irq.h>
++#include <asm/setup.h>
++#include <asm/mach-types.h>
++
++#include <asm/mach/arch.h>
++#include <mach/time.h>
++
++extern void aspeed_map_io(void);
++extern void aspeed_init_irq(void);
++extern struct sys_timer aspeed_timer;
++
++static void __init aspeed_init(void)
++{
++ ast_add_all_devices();
++}
++
++MACHINE_START(ASPEED, "AST1100")
++ .phys_io = ASPEED_IO_START,
++// .phys_ram = ASPEED_SDRAM_BASE,
++ .io_pg_offst = (IO_ADDRESS(IO_START)>>18) & 0xfffc,
++ .map_io = aspeed_map_io,
++ .timer = &aspeed_timer,
++ .init_irq = aspeed_init_irq,
++ .init_machine = aspeed_init,
++MACHINE_END
+diff --git a/arch/arm/mach-aspeed/ast2300.c b/arch/arm/mach-aspeed/ast2300.c
+new file mode 100644
+index 0000000..a223d74
+--- /dev/null
++++ b/arch/arm/mach-aspeed/ast2300.c
+@@ -0,0 +1,206 @@
++/*
++ * linux/arch/arm/mach-ast2300/ast2300.c
++ *
++ * 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 <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/sysdev.h>
++#include <asm/mach-types.h>
++#include <asm/mach/irq.h>
++#include <asm/mach/arch.h>
++#include <asm/mach/map.h>
++#include <mach/time.h>
++#include <mach/hardware.h>
++#include <plat/devs.h>
++
++#include "core.h"
++
++static struct map_desc ast_io_desc[] __initdata = {
++ {
++ .virtual = IO_ADDRESS(AST_VIC_BASE),
++ .pfn = __phys_to_pfn(AST_VIC_BASE),
++ .length = SZ_64K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_SCU_BASE),
++ .pfn = __phys_to_pfn(AST_SCU_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_SDMC_BASE),
++ .pfn = __phys_to_pfn(AST_SDMC_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_MAC0_BASE),
++ .pfn = __phys_to_pfn(AST_MAC0_BASE),
++ .length = SZ_64K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_MAC1_BASE),
++ .pfn = __phys_to_pfn(AST_MAC1_BASE),
++ .length = SZ_64K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_CRYPTO_BASE),
++ .pfn = __phys_to_pfn(AST_CRYPTO_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_XDMA_BASE),
++ .pfn = __phys_to_pfn(AST_XDMA_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_MCTP_BASE),
++ .pfn = __phys_to_pfn(AST_MCTP_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_SRAM_BASE),
++ .pfn = __phys_to_pfn(AST_SRAM_BASE),
++ .length = SZ_64K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_2D_BASE),
++ .pfn = __phys_to_pfn(AST_2D_BASE),
++ .length = SZ_64K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_GPIO_BASE),
++ .pfn = __phys_to_pfn(AST_GPIO_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_TIMER_BASE),
++ .pfn = __phys_to_pfn(AST_TIMER_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_UART0_BASE),
++ .pfn = __phys_to_pfn(AST_UART0_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_UART4_BASE),
++ .pfn = __phys_to_pfn(AST_UART4_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_WDT_BASE),
++ .pfn = __phys_to_pfn(AST_WDT_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_VUART0_BASE),
++ .pfn = __phys_to_pfn(AST_VUART0_BASE),
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_PUART_BASE),
++ .pfn = __phys_to_pfn(AST_PUART_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_LPC_BASE),
++ .pfn = __phys_to_pfn(AST_LPC_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_PECI_BASE),
++ .pfn = __phys_to_pfn(AST_PECI_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++#if defined(CONFIG_ARCH_AST1070)
++ .virtual = IO_ADDRESS2(AST_C0_VIC_BASE),
++ .pfn = __phys_to_pfn(AST_C0_VIC_BASE),
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS2(AST_C0_SCU_BASE),
++ .pfn = __phys_to_pfn(AST_C0_SCU_BASE),
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS2(AST_C0_I2C_BASE),
++ .pfn = __phys_to_pfn(AST_C0_I2C_BASE),
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS2(AST_C0_UART0_BASE),
++ .pfn = __phys_to_pfn(AST_C0_UART0_BASE),
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS2(AST_C0_UART1_BASE),
++ .pfn = __phys_to_pfn(AST_C0_UART0_BASE),
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS2(AST_C0_UART2_BASE),
++ .pfn = __phys_to_pfn(AST_C0_UART0_BASE),
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS2(AST_C0_UART3_BASE),
++ .pfn = __phys_to_pfn(AST_C0_UART0_BASE),
++
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++#endif
++ .virtual = IO_ADDRESS(AST_UART1_BASE),
++ .pfn = __phys_to_pfn(AST_UART1_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_UART2_BASE),
++ .pfn = __phys_to_pfn(AST_UART2_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_UART3_BASE),
++ .pfn = __phys_to_pfn(AST_UART3_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ },
++};
++
++void __init ast_map_io(void)
++{
++ iotable_init(ast_io_desc, ARRAY_SIZE(ast_io_desc));
++}
++
++static void __init ast_init(void)
++{
++ ast_add_all_devices();
++}
++
++MACHINE_START(ASPEED, "AST2300")
++ .phys_io = AST_IO_START,
++// .phys_ram = AST_SDRAM_BASE,
++ .io_pg_offst = (IO_ADDRESS(AST_IO_START)>>18) & 0xfffc,
++ .boot_params = 0x40000100,
++ .map_io = ast_map_io,
++ .timer = &ast_timer,
++ .init_irq = ast_init_irq,
++ .init_machine = ast_init,
++MACHINE_END
+diff --git a/arch/arm/mach-aspeed/ast2400.c b/arch/arm/mach-aspeed/ast2400.c
+new file mode 100644
+index 0000000..3567d3c
+--- /dev/null
++++ b/arch/arm/mach-aspeed/ast2400.c
+@@ -0,0 +1,255 @@
++/*
++ * linux/arch/arm/mach-ast2300/ast2300.c
++ *
++ * 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 <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/sysdev.h>
++#include <asm/mach-types.h>
++#include <asm/mach/irq.h>
++#include <asm/mach/arch.h>
++#include <asm/mach/map.h>
++#include <mach/time.h>
++#include <mach/hardware.h>
++#include <plat/devs.h>
++
++#include "core.h"
++
++static struct map_desc ast_io_desc[] __initdata = {
++ {
++ .virtual = IO_ADDRESS(AST_VIC_BASE),
++ .pfn = __phys_to_pfn(AST_VIC_BASE),
++ .length = SZ_64K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_SCU_BASE),
++ .pfn = __phys_to_pfn(AST_SCU_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_SDMC_BASE),
++ .pfn = __phys_to_pfn(AST_SDMC_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_VIDEO_BASE),
++ .pfn = __phys_to_pfn(AST_VIDEO_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_MAC0_BASE),
++ .pfn = __phys_to_pfn(AST_MAC0_BASE),
++ .length = SZ_64K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_MAC1_BASE),
++ .pfn = __phys_to_pfn(AST_MAC1_BASE),
++ .length = SZ_64K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_CRYPTO_BASE),
++ .pfn = __phys_to_pfn(AST_CRYPTO_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_JTAG_BASE),
++ .pfn = __phys_to_pfn(AST_JTAG_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_XDMA_BASE),
++ .pfn = __phys_to_pfn(AST_XDMA_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_MCTP_BASE),
++ .pfn = __phys_to_pfn(AST_MCTP_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_SRAM_BASE),
++ .pfn = __phys_to_pfn(AST_SRAM_BASE),
++ .length = SZ_16K*2,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_2D_BASE),
++ .pfn = __phys_to_pfn(AST_2D_BASE),
++ .length = SZ_64K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_GPIO_BASE),
++ .pfn = __phys_to_pfn(AST_GPIO_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_TIMER_BASE),
++ .pfn = __phys_to_pfn(AST_TIMER_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_UART0_BASE),
++ .pfn = __phys_to_pfn(AST_UART0_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_UART4_BASE),
++ .pfn = __phys_to_pfn(AST_UART4_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_WDT_BASE),
++ .pfn = __phys_to_pfn(AST_WDT_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_UDC11_BASE ),
++ .pfn = __phys_to_pfn(AST_UDC11_BASE),
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_VUART0_BASE),
++ .pfn = __phys_to_pfn(AST_VUART0_BASE),
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_PUART_BASE),
++ .pfn = __phys_to_pfn(AST_PUART_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_LPC_BASE),
++ .pfn = __phys_to_pfn(AST_LPC_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_PECI_BASE),
++ .pfn = __phys_to_pfn(AST_PECI_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++#if defined(CONFIG_ARCH_AST1070)
++ .virtual = IO_ADDRESS2(AST_C0_VIC_BASE),
++ .pfn = __phys_to_pfn(AST_C0_VIC_BASE),
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS2(AST_C0_SCU_BASE),
++ .pfn = __phys_to_pfn(AST_C0_SCU_BASE),
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS2(AST_C0_I2C_BASE),
++ .pfn = __phys_to_pfn(AST_C0_I2C_BASE),
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS2(AST_C1_VIC_BASE),
++ .pfn = __phys_to_pfn(AST_C1_VIC_BASE),
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS2(AST_C1_SCU_BASE),
++ .pfn = __phys_to_pfn(AST_C1_SCU_BASE),
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS2(AST_C1_I2C_BASE),
++ .pfn = __phys_to_pfn(AST_C1_I2C_BASE),
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS2(AST_C0_UART0_BASE),
++ .pfn = __phys_to_pfn(AST_C0_UART0_BASE),
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS2(AST_C0_UART1_BASE),
++ .pfn = __phys_to_pfn(AST_C0_UART0_BASE),
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS2(AST_C0_UART2_BASE),
++ .pfn = __phys_to_pfn(AST_C0_UART0_BASE),
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS2(AST_C0_UART3_BASE),
++ .pfn = __phys_to_pfn(AST_C0_UART0_BASE),
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS2(AST_C1_UART0_BASE),
++ .pfn = __phys_to_pfn(AST_C1_UART0_BASE),
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS2(AST_C1_UART1_BASE),
++ .pfn = __phys_to_pfn(AST_C1_UART0_BASE),
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS2(AST_C1_UART2_BASE),
++ .pfn = __phys_to_pfn(AST_C1_UART0_BASE),
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS2(AST_C1_UART3_BASE),
++ .pfn = __phys_to_pfn(AST_C1_UART0_BASE),
++ .length = SZ_1K,
++ .type = MT_DEVICE,
++ }, {
++#endif
++ .virtual = IO_ADDRESS(AST_UART1_BASE),
++ .pfn = __phys_to_pfn(AST_UART1_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_UART2_BASE),
++ .pfn = __phys_to_pfn(AST_UART2_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_UART3_BASE),
++ .pfn = __phys_to_pfn(AST_UART3_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ },
++};
++
++void __init ast_map_io(void)
++{
++ iotable_init(ast_io_desc, ARRAY_SIZE(ast_io_desc));
++}
++
++static void __init ast_init(void)
++{
++ ast_add_all_devices();
++}
++
++MACHINE_START(ASPEED, "AST2400")
++ .phys_io = AST_IO_START,
++// .phys_ram = AST_SDRAM_BASE,
++ .io_pg_offst = (IO_ADDRESS(AST_IO_START)>>18) & 0xfffc,
++ .boot_params = 0x40000100,
++ .map_io = ast_map_io,
++ .timer = &ast_timer,
++ .init_irq = ast_init_irq,
++ .init_machine = ast_init,
++MACHINE_END
+diff --git a/arch/arm/mach-aspeed/ast3100.c b/arch/arm/mach-aspeed/ast3100.c
+new file mode 100644
+index 0000000..cf220e7
+--- /dev/null
++++ b/arch/arm/mach-aspeed/ast3100.c
+@@ -0,0 +1,230 @@
++/*
++ * linux/arch/arm/mach-ast2300/ast2300.c
++ *
++ * 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 <linux/config.h>
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <linux/interrupt.h>
++#include <linux/init.h>
++
++#include <mach/hardware.h>
++#include <asm/irq.h>
++#include <asm/setup.h>
++#include <asm/mach-types.h>
++
++#include <asm/mach/arch.h>
++#include <mach/time.h>
++
++#include <asm/mach/map.h>
++#include <plat/devs.h>
++
++#include "core.h"
++
++static struct map_desc ast_io_desc[] __initdata = {
++ {
++ .virtual = IO_ADDRESS(AST_AHB_CTRL_BASE),
++ .pfn = __phys_to_pfn(AST_AHB_CTRL_BASE),
++ .length = SZ_64K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_NEW_SMC_CONTROLLER_BASE),
++ .pfn = __phys_to_pfn(AST_NEW_SMC_CONTROLLER_BASE),
++ .length = SZ_64K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_LPC_SPI_CONTROLLER_BASE),
++ .pfn = __phys_to_pfn(AST_LPC_SPI_CONTROLLER_BASE),
++ .length = SZ_64K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_MIC_BASE),
++ .pfn = __phys_to_pfn(AST_MIC_BASE),
++ .length = SZ_64K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_MAC1_BASE),
++ .pfn = __phys_to_pfn(AST_MAC1_BASE),
++ .length = SZ_64K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_MAC2_BASE),
++ .pfn = __phys_to_pfn(AST_MAC2_BASE),
++ .length = SZ_64K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_VIC_BASE),
++ .pfn = __phys_to_pfn(AST_VIC_BASE),
++ .length = SZ_64K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_SCU_BASE),
++ .pfn = __phys_to_pfn(AST_SCU_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_CRYPTO_BASE),
++ .pfn = __phys_to_pfn(AST_CRYPTO_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_JTAG_BASE),
++ .pfn = __phys_to_pfn(AST_JTAG_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_I2S_BASE),
++ .pfn = __phys_to_pfn(AST_I2S_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_GRAPHIC_BASE),
++ .pfn = __phys_to_pfn(AST_GRAPHIC_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_XDMA_BASE),
++ .pfn = __phys_to_pfn(AST_XDMA_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_MCTP_BASE),
++ .pfn = __phys_to_pfn(AST_MCTP_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_ADC_BASE),
++ .pfn = __phys_to_pfn(AST_ADC_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_VIDEO_BASE),
++ .pfn = __phys_to_pfn(AST_VIDEO_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_SRAM_BASE),
++ .pfn = __phys_to_pfn(AST_SRAM_BASE),
++ .length = SZ_64K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_SDHC_BASE),
++ .pfn = __phys_to_pfn(AST_SDHC_BASE),
++ .length = SZ_64K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_2D_BASE),
++ .pfn = __phys_to_pfn(AST_2D_BASE),
++ .length = SZ_64K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_GPIO_BASE),
++ .pfn = __phys_to_pfn(AST_GPIO_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_RTC_BASE),
++ .pfn = __phys_to_pfn(AST_RTC_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_TIMER_BASE),
++ .pfn = __phys_to_pfn(AST_TIMER_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_UART0_BASE),
++ .pfn = __phys_to_pfn(AST_UART0_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_UART1_BASE),
++ .pfn = __phys_to_pfn(AST_UART1_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_WDT_BASE),
++ .pfn = __phys_to_pfn(AST_WDT_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_PWM_BASE),
++ .pfn = __phys_to_pfn(AST_PWM_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_VUART0_BASE),
++ .pfn = __phys_to_pfn(AST_VUART0_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_PUART_BASE),
++ .pfn = __phys_to_pfn(AST_PUART_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_LPC_BASE),
++ .pfn = __phys_to_pfn(AST_LPC_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_I2C_BASE),
++ .pfn = __phys_to_pfn(AST_I2C_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_PECI_BASE),
++ .pfn = __phys_to_pfn(AST_PECI_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_UART2_BASE),
++ .pfn = __phys_to_pfn(AST_UART2_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_UART3_BASE),
++ .pfn = __phys_to_pfn(AST_UART2_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ }, {
++ .virtual = IO_ADDRESS(AST_UART4_BASE),
++ .pfn = __phys_to_pfn(AST_UART2_BASE),
++ .length = SZ_4K,
++ .type = MT_DEVICE,
++ },
++};
++
++void __init ast_map_io(void)
++{
++ iotable_init(ast_io_desc, ARRAY_SIZE(ast_io_desc));
++}
++
++static void __init ast_init(void)
++{
++ ast_add_all_devices();
++}
++
++MACHINE_START(ASPEED, "AST2300")
++ .phys_io = AST_IO_START,
++// .phys_ram = AST_SDRAM_BASE,
++ .io_pg_offst = (IO_ADDRESS(AST_IO_START)>>18) & 0xfffc,
++ .boot_params = 0x40000100,
++ .map_io = ast_map_io,
++ .timer = &ast_timer,
++ .init_irq = ast_init_irq,
++ .init_machine = ast_init,
++MACHINE_END
+diff --git a/arch/arm/mach-aspeed/core.h b/arch/arm/mach-aspeed/core.h
+new file mode 100644
+index 0000000..eb5ac89
+--- /dev/null
++++ b/arch/arm/mach-aspeed/core.h
+@@ -0,0 +1,25 @@
++/*
++ * linux/arch/arm/mach-aspeed/core.h
++ *
++* Copyright (C) ASPEED Tech. Corp.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++*
++ */
++
++#ifndef __ASM_ARCH_ASPEED_CORE_H
++#define __ASM_ARCH_ASPEED_CORE_H
++
++extern struct sys_timer ast_timer;
++
++extern void __init ast_init_irq(void);
++#endif
+diff --git a/arch/arm/mach-aspeed/gpio.c b/arch/arm/mach-aspeed/gpio.c
+new file mode 100644
+index 0000000..3a633e9
+--- /dev/null
++++ b/arch/arm/mach-aspeed/gpio.c
+@@ -0,0 +1,635 @@
++/*
++ * linux/arch/arm/plat-aspeed/gpio.c
++ *
++ * Support functions for ASPEED GPIO
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ * Written by Ryan Chen <ryan_chen@aspeedtech.com>
++ *
++ * 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.
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/interrupt.h>
++#include <linux/sysdev.h>
++#include <linux/err.h>
++#include <linux/clk.h>
++#include <linux/io.h>
++
++#include <mach/hardware.h>
++#include <asm/irq.h>
++#include <mach/irqs.h>
++#include <mach/gpio.h>
++#include <asm/mach/irq.h>
++
++#include <plat/regs-gpio.h>
++#include <asm-generic/gpio.h>
++
++//#define AST_GPIO_DEBUG
++
++#ifdef AST_GPIO_DEBUG
++//#define GPIODBUG(fmt, args...) printk("%s() " fmt, __FUNCTION__, ## args)
++#define GPIODBUG(fmt, args...) printk(fmt, ## args)
++
++#else
++#define GPIODBUG(fmt, args...)
++#endif
++
++/*************************************************************/
++//GPIO group structure
++struct ast_gpio_bank {
++ int irq;
++ u32 base;
++//TODO remove base
++ u32 index;
++ u32 data_offset;
++ u32 dir_offset;
++ u32 int_en_offset;
++ u32 int_type_offset;
++ u32 int_sts_offset;
++ u32 rst_tol_offset;
++ u32 debounce_offset;
++ u32 cmd_source_offset;
++ struct gpio_chip chip;
++
++//#ifdef CONFIG_PM
++//#define NR_REGS (7)
++// u32 regs[NR_REGS];
++//#endif
++};
++
++int ast_gpio_to_irq(unsigned gpio)
++{
++ return (gpio + IRQ_GPIO_CHAIN_START);
++}
++
++EXPORT_SYMBOL(ast_gpio_to_irq);
++
++int ast_irq_to_gpio(unsigned irq)
++{
++ return (irq - IRQ_GPIO_CHAIN_START);
++}
++
++EXPORT_SYMBOL(ast_irq_to_gpio);
++
++static inline u32
++ast_gpio_read(struct ast_gpio_bank *ast_gpio ,u32 offset)
++{
++ GPIODBUG("base = 0x%08x, offset = 0x%08x \n", ast_gpio->base, offset);
++
++ return readl(ast_gpio->base + offset);
++}
++
++static inline void
++ast_gpio_write(struct ast_gpio_bank *ast_gpio , u32 val, u32 offset)
++{
++ GPIODBUG("base = 0x%08x, offset = 0x%08x, val = 0x%08x\n", ast_gpio->base, offset, val);
++ writel(val, ast_gpio->base + offset);
++}
++
++/***************************************************************************************/
++static int
++ast_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
++{
++ struct ast_gpio_bank *ast_gpio = container_of(chip, struct ast_gpio_bank, chip);
++ unsigned long flags;
++ u32 v;
++ int ret = -1;
++
++ GPIODBUG("dir_in %s[%d] \n",chip->label, offset);
++
++ local_irq_save(flags);
++
++ v = ast_gpio_read(ast_gpio, ast_gpio->dir_offset);
++
++ v &= ~(GPIO_OUTPUT_MODE << (offset + (ast_gpio->index * 8)));
++ ast_gpio_write(ast_gpio, v, ast_gpio->dir_offset);
++
++ ret = 0;
++
++ local_irq_restore(flags);
++ return ret;
++
++}
++
++static int
++ast_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int val)
++{
++ struct ast_gpio_bank *ast_gpio = container_of(chip, struct ast_gpio_bank, chip);
++ unsigned long flags;
++ u32 v;
++ int ret = -1;
++ GPIODBUG("dir_out %s[%d], val %d \n",chip->label, offset, val);
++
++ local_irq_save(flags);
++
++ /* Drive as an output */
++ v = ast_gpio_read(ast_gpio, ast_gpio->dir_offset);
++
++ v |= (GPIO_OUTPUT_MODE << (offset + (ast_gpio->index * 8)));
++
++ ast_gpio_write(ast_gpio, v, ast_gpio->dir_offset);
++
++ local_irq_restore(flags);
++
++ ret = 0;
++ return ret;
++}
++
++static int
++ast_gpio_get(struct gpio_chip *chip, unsigned offset)
++{
++ struct ast_gpio_bank *ast_gpio = container_of(chip, struct ast_gpio_bank, chip);
++ unsigned long flags;
++ u32 v;
++
++ GPIODBUG("Get %s[%d] \n",chip->label, offset);
++
++ local_irq_save(flags);
++
++ v = ast_gpio_read(ast_gpio, ast_gpio->data_offset);
++
++ v &= (1 << (offset + (ast_gpio->index * 8)));
++
++ if(v)
++ v = 1;
++ else
++ v = 0;
++
++ local_irq_restore(flags);
++
++ return v;
++}
++
++static void
++ast_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
++{
++ struct ast_gpio_bank *ast_gpio = container_of(chip, struct ast_gpio_bank, chip);
++ unsigned long flags;
++ u32 v;
++ GPIODBUG("Set %s[%d] = %d\n",chip->label, offset, val);
++
++ local_irq_save(flags);
++
++ /* Set the value */
++
++ v = ast_gpio_read(ast_gpio, ast_gpio->data_offset);
++
++ if (val)
++ v |= (1 << (offset + (ast_gpio->index * 8)));
++ else
++ v &= ~(1 << (offset + (ast_gpio->index * 8)));
++
++ ast_gpio_write(ast_gpio, v, ast_gpio->data_offset);
++
++ local_irq_restore(flags);
++}
++
++
++#define AST_GPIO_BANK(name, gpio_base, index_no, data, dir, int_en, int_type, int_sts, rst_tol, debounce, cmd_s) \
++ { \
++ .base = gpio_base, \
++ .index = index_no, \
++ .data_offset = data, \
++ .dir_offset = dir, \
++ .int_en_offset = int_en, \
++ .int_type_offset = int_type, \
++ .int_sts_offset = int_sts, \
++ .rst_tol_offset = rst_tol, \
++ .debounce_offset = debounce, \
++ .cmd_source_offset = cmd_s, \
++ .chip = { \
++ .label = name, \
++ .direction_input = ast_gpio_direction_input, \
++ .direction_output = ast_gpio_direction_output, \
++ .get = ast_gpio_get, \
++ .set = ast_gpio_set, \
++ .ngpio = GPIO_PER_PORT_PIN_NUM, \
++ }, \
++ }
++
++static struct ast_gpio_bank ast_gpio_gp[] = {
++ AST_GPIO_BANK("GPIOA", IO_ADDRESS(AST_GPIO_BASE), 0, 0x000, 0x004, 0x008, 0x00c, 0x018, 0x01c, 0x040, 0x060),
++ AST_GPIO_BANK("GPIOB", IO_ADDRESS(AST_GPIO_BASE), 1, 0x000, 0x004, 0x008, 0x00c, 0x018, 0x01c, 0x040, 0x060),
++ AST_GPIO_BANK("GPIOC", IO_ADDRESS(AST_GPIO_BASE), 2, 0x000, 0x004, 0x008, 0x00c, 0x018, 0x01c, 0x040, 0x060),
++ AST_GPIO_BANK("GPIOD", IO_ADDRESS(AST_GPIO_BASE), 3, 0x000, 0x004, 0x008, 0x00c, 0x018, 0x01c, 0x040, 0x060),
++ AST_GPIO_BANK("GPIOE", IO_ADDRESS(AST_GPIO_BASE), 0, 0x020, 0x024, 0x028, 0x02c, 0x038, 0x03c, 0x048, 0x068),
++ AST_GPIO_BANK("GPIOF", IO_ADDRESS(AST_GPIO_BASE), 1, 0x020, 0x024, 0x028, 0x02c, 0x038, 0x03c, 0x048, 0x068),
++ AST_GPIO_BANK("GPIOG", IO_ADDRESS(AST_GPIO_BASE), 2, 0x020, 0x024, 0x028, 0x02c, 0x038, 0x03c, 0x048, 0x068),
++ AST_GPIO_BANK("GPIOH", IO_ADDRESS(AST_GPIO_BASE), 3, 0x020, 0x024, 0x028, 0x02c, 0x038, 0x03c, 0x048, 0x068),
++ AST_GPIO_BANK("GPIOI", IO_ADDRESS(AST_GPIO_BASE), 0, 0x070, 0x074, 0x098, 0x09c, 0x0a8, 0x0ac, 0x0b0, 0x090),
++ AST_GPIO_BANK("GPIOJ", IO_ADDRESS(AST_GPIO_BASE), 1, 0x070, 0x074, 0x098, 0x09c, 0x0a8, 0x0ac, 0x0b0, 0x090),
++ AST_GPIO_BANK("GPIOK", IO_ADDRESS(AST_GPIO_BASE), 2, 0x070, 0x074, 0x098, 0x09c, 0x0a8, 0x0ac, 0x0b0, 0x090),
++ AST_GPIO_BANK("GPIOL", IO_ADDRESS(AST_GPIO_BASE), 3, 0x070, 0x074, 0x098, 0x09c, 0x0a8, 0x0ac, 0x0b0, 0x090),
++ AST_GPIO_BANK("GPIOM", IO_ADDRESS(AST_GPIO_BASE), 0, 0x078, 0x07c, 0x0e8, 0x0ec, 0x0f8, 0x0fc, 0x100, 0x0e0),
++ AST_GPIO_BANK("GPION", IO_ADDRESS(AST_GPIO_BASE), 1, 0x078, 0x07c, 0x0e8, 0x0ec, 0x0f8, 0x0fc, 0x100, 0x0e0),
++ AST_GPIO_BANK("GPIOO", IO_ADDRESS(AST_GPIO_BASE), 2, 0x078, 0x07c, 0x0e8, 0x0ec, 0x0f8, 0x0fc, 0x100, 0x0e0),
++ AST_GPIO_BANK("GPIOP", IO_ADDRESS(AST_GPIO_BASE), 3, 0x078, 0x07c, 0x0e8, 0x0ec, 0x0f8, 0x0fc, 0x100, 0x0e0),
++ AST_GPIO_BANK("GPIOQ", IO_ADDRESS(AST_GPIO_BASE), 0, 0x080, 0x084, 0x118, 0x11c, 0x128, 0x12c, 0x130, 0x110),
++ AST_GPIO_BANK("GPIOR", IO_ADDRESS(AST_GPIO_BASE), 1, 0x080, 0x084, 0x118, 0x11c, 0x128, 0x12c, 0x130, 0x110),
++ AST_GPIO_BANK("GPIOS", IO_ADDRESS(AST_GPIO_BASE), 2, 0x080, 0x084, 0x118, 0x11c, 0x128, 0x12c, 0x130, 0x110),
++#if defined(CONFIG_ARCH_AST2400)
++ AST_GPIO_BANK("GPIOT", IO_ADDRESS(AST_GPIO_BASE), 4, 0x080, 0x084, 0x118, 0x11c, 0x128, 0x12c, 0x130, 0x110),
++ AST_GPIO_BANK("GPIOU", IO_ADDRESS(AST_GPIO_BASE), 0, 0x088, 0x08c, 0x148, 0x14c, 0x158, 0x15c, 0x160, 0x140),
++ AST_GPIO_BANK("GPIOV", IO_ADDRESS(AST_GPIO_BASE), 1, 0x088, 0x08c, 0x148, 0x14c, 0x158, 0x15c, 0x160, 0x140),
++ AST_GPIO_BANK("GPIOW", IO_ADDRESS(AST_GPIO_BASE), 2, 0x088, 0x08c, 0x148, 0x14c, 0x158, 0x15c, 0x160, 0x140),
++ AST_GPIO_BANK("GPIOX", IO_ADDRESS(AST_GPIO_BASE), 3, 0x088, 0x08c, 0x148, 0x14c, 0x158, 0x15c, 0x160, 0x140),
++ AST_GPIO_BANK("GPIOY", IO_ADDRESS(AST_GPIO_BASE), 0, 0x1e0, 0x1e4, 0x178, 0x17c, 0x188, 0x18c, 0x190, 0x170),
++ AST_GPIO_BANK("GPIOZ", IO_ADDRESS(AST_GPIO_BASE), 1, 0x1e0, 0x1e4, 0x178, 0x17c, 0x188, 0x18c, 0x190, 0x170),
++ AST_GPIO_BANK("GPIOAA", IO_ADDRESS(AST_GPIO_BASE), 2, 0x1e0, 0x1e4, 0x178, 0x17c, 0x188, 0x18c, 0x190, 0x170),
++ AST_GPIO_BANK("GPIOAB", IO_ADDRESS(AST_GPIO_BASE), 3, 0x1e0, 0x1e4, 0x178, 0x17c, 0x188, 0x18c, 0x190, 0x170),
++#endif
++};
++
++
++/***************************************************************************************/
++/*
++ * assuming the pin is muxed as a gpio output, set its value.
++ */
++int ast_set_gpio_value(unsigned gpio_pin, int value)
++{
++ u32 data;
++ u32 gp, pin;
++ gp = gpio_pin / 8;
++ pin = gpio_pin % 32;
++ data = ast_gpio_read(&ast_gpio_gp[gp], ast_gpio_gp[gp].data_offset);
++ if(value)
++ data |= (1 << pin);
++ else
++ data &= ~(1 << pin);
++
++ GPIODBUG("gp : %d, pin %d, data = %x \n ", gp, pin, data);
++ ast_gpio_write(&ast_gpio_gp[gp], data, ast_gpio_gp[gp].data_offset);
++
++ return 0;
++}
++EXPORT_SYMBOL(ast_set_gpio_value);
++
++
++/*
++ * read the pin's value (works even if it's not muxed as a gpio).
++ */
++int ast_get_gpio_value(unsigned gpio_pin)
++{
++ u32 data;
++ u32 gp, pin;
++ gp = gpio_pin / 8;
++ pin = gpio_pin % 32;
++ data = ast_gpio_read(&ast_gpio_gp[gp], ast_gpio_gp[gp].data_offset);
++
++ GPIODBUG("gp : %d, pin %d, data = %x, value = %d \n ", gp, pin, data, (data >> pin) & 1);
++
++ return ((data >> pin) & 1);
++}
++EXPORT_SYMBOL(ast_get_gpio_value);
++
++//timer 0/1/2
++//Debounce time = PCLK * (val+1)
++void ast_set_gpio_debounce_timer(int timer, int val)
++{
++ switch(timer) {
++ case 0:
++ writel(val, IO_ADDRESS(AST_GPIO_BASE) + 0x50);
++ break;
++ case 1:
++ writel(val, IO_ADDRESS(AST_GPIO_BASE) + 0x54);
++ break;
++ case 2:
++ writel(val, IO_ADDRESS(AST_GPIO_BASE) + 0x58);
++ break;
++ }
++}
++
++EXPORT_SYMBOL(ast_set_gpio_debounce_timer);
++
++//TODO ......
++//mode 0 : no debounce , 1: set 0x50, 2: 0x54, 3: 0x58
++void ast_set_gpio_debounce(int gpio_port, int mode)
++{
++#if 0
++ u32 set0, set1;
++ u16 gp, port;
++ gp = gpio_port / 4;
++ port = gpio_port % 4;
++ set0 = ast_gpio_read(&ast_gpio_gp[gp], ast_gpio_gp[gp].debounce_offset);
++ set1 = ast_gpio_read(&ast_gpio_gp[gp], ast_gpio_gp[gp].debounce_offset + 0x04);
++
++ switch(port) {
++ case 0: //A , H , ......
++ set0 = port
++ ast_gpio_write(ast_gpio, val, 0x50);
++ break;
++ case 1:
++ ast_gpio_write(ast_gpio, val, 0x54);
++ break;
++ case 2:
++ ast_gpio_write(ast_gpio, val, 0x58);
++ break;
++ case 3:
++ ast_gpio_write(ast_gpio, val, 0x58);
++ break;
++ default:
++ GPIODBUG("not support \n");
++ return;
++ break;
++
++ }
++
++ ast_gpio_write(&ast_gpio_gp[gp], set0, ast_gpio_gp[gp].debounce_offset);
++ ast_gpio_write(&ast_gpio_gp[gp], set1, ast_gpio_gp[gp].debounce_offset + 0x04);
++#endif
++}
++
++EXPORT_SYMBOL(ast_set_gpio_debounce);
++
++//TODO ......
++//
++void ast_set_gpio_tolerant(int gpio_port, int mode)
++{
++#if 0
++ u32 set0, set1;
++ u16 gp, port;
++ gp = gpio_port / 4;
++ port = gpio_port % 4;
++ set0 = ast_gpio_read(&ast_gpio_gp[gp], ast_gpio_gp[gp].debounce_offset);
++ set1 = ast_gpio_read(&ast_gpio_gp[gp], ast_gpio_gp[gp].debounce_offset + 0x04);
++
++ switch(port) {
++ case 0: //A , H , ......
++ set0 = port
++ ast_gpio_write(ast_gpio, val, 0x50);
++ break;
++ case 1:
++ ast_gpio_write(ast_gpio, val, 0x54);
++ break;
++ case 2:
++ ast_gpio_write(ast_gpio, val, 0x58);
++ break;
++ case 3:
++ ast_gpio_write(ast_gpio, val, 0x58);
++ break;
++ default:
++ GPIODBUG("not support \n");
++ return;
++ break;
++
++ }
++
++ ast_gpio_write(&ast_gpio_gp[gp], set0, ast_gpio_gp[gp].debounce_offset);
++ ast_gpio_write(&ast_gpio_gp[gp], set1, ast_gpio_gp[gp].debounce_offset + 0x04);
++#endif
++}
++
++EXPORT_SYMBOL(ast_set_gpio_tolerant);
++
++/*
++ * We need to unmask the GPIO bank interrupt as soon as possible to
++ * avoid missing GPIO interrupts for other lines in the bank.
++ * Then we need to mask-read-clear-unmask the triggered GPIO lines
++ * in the bank to avoid missing nested interrupts for a GPIO line.
++ * If we wait to unmask individual GPIO lines in the bank after the
++ * line's interrupt handler has been run, we may miss some nested
++ * interrupts.
++ */
++static void
++ast_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
++{
++ u32 isr;
++ int i,j;
++ struct ast_gpio_bank *ast_gpio;
++
++ if(irq != IRQ_GPIO)
++ BUG();
++
++ GPIODBUG("ast_gpio_irq_handler %d \n ", irq);
++
++// ast_gpio = get_irq_data(irq);
++
++// GPIODBUG("[%s] ------\n ",ast_gpio->chip.label );
++
++ desc->chip->ack(IRQ_GPIO);
++
++ for (i = 0; i < GPIO_PORT_NUM; i++) {
++ ast_gpio = &ast_gpio_gp[i];
++ isr = ast_gpio_read(ast_gpio, ast_gpio->int_sts_offset);
++ GPIODBUG("isr %x \n", isr);
++ isr = (isr >> (8 * ast_gpio->index)) & 0xff;
++ GPIODBUG("[%s] isr %x \n", ast_gpio->chip.label, isr);
++ if(isr != 0) {
++ //get gpio isr and --> to IRQ number ....
++ for (j=0; j<8;j++) {
++ if((1<<j) & isr) {
++ // dispach interrupt
++// GPIODBUG("[%s] pin %d -> irq [%d]\n",ast_gpio->chip.label, j, j + IRQ_GPIO_CHAIN_START + (8 * i));
++ generic_handle_irq(j + IRQ_GPIO_CHAIN_START + (8 * i));
++ }
++ }
++// GPIODBUG("isr -- ? %x \n",ast_gpio_read(ast_gpio, ast_gpio->int_sts_offset));
++ }
++ }
++
++#if 0
++ while(1) {
++ isr = ast_gpio_read(ast_gpio, ast_gpio->int_sts_offset);
++ printk("isr %x \n", isr);
++ isr = isr >> (8 * ast_gpio->index);
++ //get gpio isr and --> to IRQ number ....
++ for (i=0; i<8;i++) {
++ if((1<<i) & isr) {
++ // dispach interrupt
++ printk("[%s] pin %d -> irq [%d]\n",ast_gpio->chip.label, i,i + IRQ_GPIO_CHAIN_START + (8 * ast_gpio->index));
++ generic_handle_irq(i + IRQ_GPIO_CHAIN_START + (8 * ast_gpio->index));
++ }
++ }
++ if(isr == 0)
++ break;
++ }
++#endif
++ desc->chip->unmask(IRQ_GPIO);
++ /* now it may re-trigger */
++
++}
++
++static void ast_gpio_ack_irq(unsigned int irq)
++{
++ struct ast_gpio_bank *ast_gpio = get_irq_chip_data(irq);
++
++ unsigned int gpio_irq = irq - IRQ_GPIO_CHAIN_START;
++
++ gpio_irq = gpio_irq % 8;
++
++ GPIODBUG("irq [%d] : ast_gpio_ack_irq [%s] pin %d\n ",irq, ast_gpio->chip.label, gpio_irq);
++
++ GPIODBUG("write clr [%x] %x\n ",ast_gpio->int_sts_offset, 1<< (gpio_irq + (ast_gpio->index * 8)));
++
++ ast_gpio_write(ast_gpio, 1<< (gpio_irq + (ast_gpio->index * 8)), ast_gpio->int_sts_offset);
++
++ GPIODBUG("read sts %x\n ",ast_gpio_read(ast_gpio, ast_gpio->int_sts_offset));
++
++}
++
++static void ast_gpio_mask_irq(unsigned int irq)
++{
++ struct ast_gpio_bank *ast_gpio = get_irq_chip_data(irq);
++ unsigned int gpio_irq = irq - IRQ_GPIO_CHAIN_START;
++ gpio_irq = gpio_irq%8;
++
++
++ GPIODBUG("irq [%d] : ast_gpio_mask_irq [%s] pin %d\n ",irq, ast_gpio->chip.label, gpio_irq);
++
++ //disable irq
++ ast_gpio_write(ast_gpio, ast_gpio_read(ast_gpio, ast_gpio->int_en_offset) &
++ ~(1<< (gpio_irq + (ast_gpio->index * 8))), ast_gpio->int_en_offset);
++}
++
++static void ast_gpio_unmask_irq(unsigned int irq)
++{
++ struct ast_gpio_bank *ast_gpio = get_irq_chip_data(irq);
++ unsigned int gpio_irq = irq - IRQ_GPIO_CHAIN_START;
++ gpio_irq = gpio_irq%8;
++
++
++ GPIODBUG("irq[%d], [%s] pin %d\n",irq, ast_gpio->chip.label, gpio_irq);
++
++ //Enable IRQ ..
++ ast_gpio_write(ast_gpio, 1<< (gpio_irq + (ast_gpio->index * 8)), ast_gpio->int_sts_offset);
++
++ ast_gpio_write(ast_gpio, ast_gpio_read(ast_gpio, ast_gpio->int_en_offset) |
++ (1<< (gpio_irq + (ast_gpio->index * 8))), ast_gpio->int_en_offset);
++
++}
++
++static int
++ast_gpio_irq_type(unsigned int irq, unsigned int type)
++{
++ u32 type0, type1, type2;
++ struct ast_gpio_bank *ast_gpio;
++ int retval = 0;
++ unsigned int gpio_irq = irq - IRQ_GPIO_CHAIN_START;
++ gpio_irq = gpio_irq%32;
++
++
++
++ GPIODBUG("ast_gpio_irq_type %d : %x \n",irq,type);
++ if (type & ~IRQ_TYPE_SENSE_MASK)
++ return -EINVAL;
++
++ ast_gpio = get_irq_chip_data(irq);
++
++ type0 = ast_gpio_read(ast_gpio, ast_gpio->int_type_offset);
++ type1 = ast_gpio_read(ast_gpio, ast_gpio->int_type_offset + 0x04);
++ type2 = ast_gpio_read(ast_gpio, ast_gpio->int_type_offset + 0x08);
++
++ switch(type) {
++ /* Edge rising type */
++ case IRQ_TYPE_EDGE_RISING:
++ type0 |=(1<<irq);
++ type1 &=~(1<<irq);
++ type2 &=~(1<<irq);
++ break;
++ /* Edge falling type */
++ case IRQ_TYPE_EDGE_FALLING:
++ type2 |=(1<<irq);
++ break;
++ case IRQ_TYPE_EDGE_BOTH:
++ type0 &=~(1<<irq);
++ type1 |=(1<<irq);
++ type2 &=~(1<<irq);
++ break;
++ case IRQ_TYPE_LEVEL_HIGH:
++ type0 |=(1<<irq);
++ type1 |=(1<<irq);
++ type2 &=~(1<<irq);
++ break;
++ case IRQ_TYPE_LEVEL_LOW:
++ type0 &=~(1<<irq);
++ type1 |=(1<<irq);
++ type2 &=~(1<<irq);
++ break;
++ default:
++ GPIODBUG("not support trigger");
++ return -EINVAL;
++ break;
++ }
++
++ ast_gpio_write(ast_gpio, type0, ast_gpio->int_type_offset);
++ ast_gpio_write(ast_gpio, type1, ast_gpio->int_type_offset + 0x04);
++ ast_gpio_write(ast_gpio, type2, ast_gpio->int_type_offset + 0x08);
++
++ return retval;
++
++}
++
++static struct irq_chip ast_gpio_irq_chip = {
++ .name = "GPIO",
++ .ack = ast_gpio_ack_irq,
++ .mask = ast_gpio_mask_irq,
++ .unmask = ast_gpio_unmask_irq,
++ .set_type = ast_gpio_irq_type,
++};
++
++/*---------------------------------------------------------------------*/
++static int __init ast_gpio_init(void)
++{
++ int i,j;
++ struct ast_gpio_bank *ast_gpio;
++
++ GPIODBUG("gpio port num %d, total gpio pin : %d\n",
++ GPIO_PORT_NUM, ARCH_NR_GPIOS);
++
++ GPIODBUG("gpio chain start %d \n",IRQ_GPIO_CHAIN_START);
++ for (i = 0; i < GPIO_PORT_NUM; i++) {
++ ast_gpio = &ast_gpio_gp[i];
++
++ GPIODBUG("add gpio_chip [%s] : %d\n",ast_gpio->chip.label, i);
++
++#if 0
++ bank->chip.direction_input = ast_gpio_direction_input;
++ bank->chip.get = ast_gpio_get;
++ bank->chip.direction_output = ast_gpio_direction_output;
++ bank->chip.set = ast_gpio_set;
++
++ bank->chip.label = "gpio";
++#endif
++ ast_gpio->chip.base = i*8;
++ ast_gpio->chip.ngpio = 8;
++
++ gpiochip_add(&ast_gpio->chip);
++
++#if 1
++ //Set Level Trigger
++ ast_gpio_write(ast_gpio, 0xffffffff, ast_gpio->int_type_offset);
++ ast_gpio_write(ast_gpio, 0xffffffff, ast_gpio->int_type_offset + 0x04);
++ ast_gpio_write(ast_gpio, 0, ast_gpio->int_type_offset + 0x08);
++ //remove clear direction for keep orignal state
++// ast_gpio_write(ast_gpio, 0, ast_gpio->dir_offset);
++ //Enable IRQ
++// ast_gpio_write(ast_gpio, 0xffffffff, ast_gpio->int_en_offset);
++
++#endif
++
++ for(j=0;j<8;j++) {
++ GPIODBUG("inst chip data %d\n",i*8 + j + IRQ_GPIO_CHAIN_START);
++ set_irq_chip_data(i*8 + j + IRQ_GPIO_CHAIN_START, ast_gpio);
++ set_irq_chip(i*8 + j + IRQ_GPIO_CHAIN_START, &ast_gpio_irq_chip);
++ set_irq_handler(i*8 + j + IRQ_GPIO_CHAIN_START, handle_level_irq);
++ set_irq_flags(i*8 + j + IRQ_GPIO_CHAIN_START, IRQF_VALID);
++ }
++ set_irq_chained_handler(IRQ_GPIO, ast_gpio_irq_handler);
++// set_irq_chip_data(IRQ_GPIO, ast_gpio);
++// set_irq_data(IRQ_GPIO, ast_gpio_gp[]);
++
++
++ }
++
++ return 0;
++
++}
++
++core_initcall(ast_gpio_init);
++
++//arch_initcall(ast_gpio_init);
++
+diff --git a/arch/arm/mach-aspeed/include/mach/aspeed_serial.h b/arch/arm/mach-aspeed/include/mach/aspeed_serial.h
+new file mode 100644
+index 0000000..33bf333
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/aspeed_serial.h
+@@ -0,0 +1,61 @@
++/*
++ * file : aspeed_serial.h
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#ifndef ASM_ARM_HARDWARE_AST_SERIAL_H
++#define ASM_ARM_HARDWARE_AST_SERIAL_H
++
++#define UART_RBR 0x00 /* Receiver Buffer Register */
++#define UART_THR 0x00 /* Transmit Holding Register */
++#define UART_DLL 0x00 /* Divisor Latch Low Register */
++#define UART_DLH 0x04 /* Divisor Latch High Register */
++#define UART_IER 0x04 /* Interrupt Enable Register */
++#define UART_IIR 0x08 /* Interrupt Identity Register */
++#define UART_FCR 0x08 /* FIFO Control Register */
++#define UART_LCR 0x0C /* Line Control Register */
++#define UART_MCR 0x10 /* Modem Control Register */
++#define UART_LSR 0x14 /* Line Status Register */
++#define UART_MSR 0x18 /* Modem Status Register */
++#define UART_SCR 0x1C /* Scratch Register */
++
++/* Interrupt Enable Register */
++#define UART_IER_EMSI 0x08 /* Enable Modem Status Interrupt */
++#define UART_IER_ELSI 0x04 /* Enable Line Status Interrupt */
++#define UART_IER_ETEI 0x02 /* Enable Transmit Holding Empty Interrupt */
++#define UART_IER_ERDI 0X01 /* Enable Received Data Interrupt */
++
++/* FIFO Control Register */
++#define UART_FCR_XMITR 0x04 /* XMIT FIFO Reset */
++#define UART_FCR_RCVRR 0x02 /* RCVR FIFO Reset */
++#define UART_FCR_FIFOE 0x01 /* FIEO Enable */
++
++/* Line Control Register */
++#define UART_LCR_DLAB 0x80 /* Divisor Latch Address Bit */
++#define UART_LCR_BRK 0x40 /* Break Control */
++#define UART_LCR_EPS 0x10 /* Even Parity Select */
++#define UART_LCR_PEN 0x08 /* Parity Enable */
++#define UART_LCR_STOP 0x04 /* Stop Bit */
++#define UART_LCR_WLEN_MASK 0x03 /* bits per character mask */
++#define UART_LCR_WLEN_8 0x03 /* 8 bits per character */
++#define UART_LCR_WLEN_7 0x02 /* 7 bits per character */
++#define UART_LCR_WLEN_6 0x01 /* 6 bits per character */
++#define UART_LCR_WLEN_5 0x00 /* 5 bits per character */
++
++/* Line Status Register */
++#define UART_LSR_TEMT 0x40 /* Transmitter Empty */
++#define UART_LSR_THRE 0x20 /* Transmitter Holding Register Empty */
++#define UART_LSR_BE 0x10 /* Break Error */
++#define UART_LSR_FE 0x08 /* Framing Error */
++#define UART_LSR_PE 0x04 /* Parity Error */
++#define UART_LSR_OE 0x02 /* Overrun Error */
++#define UART_LSR_DR 0x01 /* Data Ready */
++#define UART_LSR_ANY (UART_LSR_BE|UART_LSR_FE|UART_LSR_PE|UART_LSR_OE)
++
++#endif
+diff --git a/arch/arm/mach-aspeed/include/mach/ast-uart-dma.h b/arch/arm/mach-aspeed/include/mach/ast-uart-dma.h
+new file mode 100644
+index 0000000..2ac2b41
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/ast-uart-dma.h
+@@ -0,0 +1,86 @@
++/********************************************************************************
++* File Name : ast-uart-dma.h
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++********************************************************************************/
++#ifndef AST_UART_DMA_H_INCLUDED
++#define AST_UART_DMA_H_INCLUDED
++
++
++#define DMA_BUFF_SIZE 0x1000 //4096
++
++struct ast_uart_dma_data {
++ u8 chip_no; //campain chip number
++ u8 dma_ch; //dma channel number
++};
++
++
++/* enum ast_uart_chan_op
++ *
++ * operation codes passed to the DMA code by the user, and also used
++ * to inform the current channel owner of any changes to the system state
++*/
++
++enum ast_uart_chan_op {
++ AST_UART_DMAOP_TRIGGER,
++ AST_UART_DMAOP_STOP,
++};
++
++struct ast1070_dma_ch;
++
++/* ast_uart_dma_cbfn_t * * buffer callback routine type */
++typedef void (*ast_uart_dma_cbfn_t)(struct ast1070_dma_ch *,void *dev_id, u16 len);
++
++struct uart_dma_desc {
++ u32 desc0;
++ u32 desc1;
++ u32 desc2;
++ u32 desc3;
++} __attribute__ ((aligned(16)));
++
++struct ast1070_dma_ch {
++ u8 ch_no;
++ u8 direction;
++ u8 enable;
++ u32 ctrl_offset;
++ u32 desc_offset;
++ void *priv;
++ struct uart_dma_desc *desc;
++ dma_addr_t desc_dma_addr; /* Mapped descr. table */
++ /* cdriver callbacks */
++ ast_uart_dma_cbfn_t callback_fn; /* buffer done callback */
++};
++
++#define AST1070_UART_DMA_CH 4
++
++struct ast1070_dma {
++ void __iomem *reg_base;
++ struct ast1070_dma_ch dma_tx_ch[AST1070_UART_DMA_CH];
++ struct ast1070_dma_ch dma_rx_ch[AST1070_UART_DMA_CH];
++};
++
++
++/* ast_uart_dma_request * * request a dma channel exclusivley */
++extern int ast_uart_rx_dma_request(u8 node, u8 channel, ast_uart_dma_cbfn_t rtn, void *id);
++extern int ast_uart_tx_dma_request(u8 node, u8 channel, ast_uart_dma_cbfn_t rtn, void *id);
++
++/* ast_uart_dma_ctrl * * change the state of the dma channel */
++extern int ast_uart_rx_dma_ctrl(u8 node, u8 ch, enum ast_uart_chan_op op);
++extern int ast_uart_tx_dma_ctrl(u8 node, u8 ch, enum ast_uart_chan_op op);
++
++extern int ast_uart_rx_dma_enqueue(u8 node, u8 ch, dma_addr_t rx_buff, u16 len);
++extern int ast_uart_tx_dma_enqueue(u8 node, u8 ch, dma_addr_t tx_buff, u16 len);
++
++
++
++#endif
++
+diff --git a/arch/arm/mach-aspeed/include/mach/ast1070_irqs.h b/arch/arm/mach-aspeed/include/mach/ast1070_irqs.h
+new file mode 100644
+index 0000000..0774417
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/ast1070_irqs.h
+@@ -0,0 +1,142 @@
++/*
++ * arch/arm/plat-aspeed/include/plat/irqs.h
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#ifndef _AST1070_IRQS_H_
++#define _AST1070_IRQS_H_ 1
++
++#define IRQ_C0_VIC_CHAIN IRQ_EXT0
++#define IRQ_C0_VIC_CHAIN_START (AST_VIC_NUM)
++
++#define IRQ_C1_VIC_CHAIN IRQ_EXT1
++#define IRQ_C1_VIC_CHAIN_START (IRQ_C0_VIC_CHAIN_START + AST_CVIC_NUM)
++
++#define IRQ_C2_VIC_CHAIN IRQ_EXT2
++#define IRQ_C2_VIC_CHAIN_START (IRQ_C1_VIC_CHAIN_START + AST_CVIC_NUM)
++
++#define IRQ_C3_VIC_CHAIN IRQ_EXT3
++#define IRQ_C3_VIC_CHAIN_START (IRQ_C2_VIC_CHAIN_START + AST_CVIC_NUM)
++
++#define AST_CVIC_NUM 25
++
++#define IRQ_C0_N1_KCS (IRQ_C0_VIC_CHAIN_START + 0)
++#define IRQ_C0_N1_UART (IRQ_C0_VIC_CHAIN_START + 1)
++#define IRQ_C0_N1_MAILBOX (IRQ_C0_VIC_CHAIN_START + 2)
++#define IRQ_C0_N1_PORT80 (IRQ_C0_VIC_CHAIN_START + 3)
++#define IRQ_C0_N1_RESET (IRQ_C0_VIC_CHAIN_START + 4)
++#define IRQ_C0_N2_KCS (IRQ_C0_VIC_CHAIN_START + 5)
++#define IRQ_C0_N2_UART (IRQ_C0_VIC_CHAIN_START + 6)
++#define IRQ_C0_N2_MAILBOX (IRQ_C0_VIC_CHAIN_START + 7)
++#define IRQ_C0_N2_PORT80 (IRQ_C0_VIC_CHAIN_START + 8)
++#define IRQ_C0_N2_RESET (IRQ_C0_VIC_CHAIN_START + 9)
++#define IRQ_C0_N3_KCS (IRQ_C0_VIC_CHAIN_START + 10)
++#define IRQ_C0_N3_UART (IRQ_C0_VIC_CHAIN_START + 11)
++#define IRQ_C0_N3_MAILBOX (IRQ_C0_VIC_CHAIN_START + 12)
++#define IRQ_C0_N3_PORT80 (IRQ_C0_VIC_CHAIN_START + 13)
++#define IRQ_C0_N3_RESET (IRQ_C0_VIC_CHAIN_START + 14)
++#define IRQ_C0_N4_KCS (IRQ_C0_VIC_CHAIN_START + 15)
++#define IRQ_C0_N4_UART (IRQ_C0_VIC_CHAIN_START + 16)
++#define IRQ_C0_N4_MAILBOX (IRQ_C0_VIC_CHAIN_START + 17)
++#define IRQ_C0_N4_PORT80 (IRQ_C0_VIC_CHAIN_START + 18)
++#define IRQ_C0_N4_RESET (IRQ_C0_VIC_CHAIN_START + 19)
++#define IRQ_C0_N1_UART_DMA (IRQ_C0_VIC_CHAIN_START + 20)
++#define IRQ_C0_N2_UART_DMA (IRQ_C0_VIC_CHAIN_START + 21)
++#define IRQ_C0_N3_UART_DMA (IRQ_C0_VIC_CHAIN_START + 22)
++#define IRQ_C0_N4_UART_DMA (IRQ_C0_VIC_CHAIN_START + 23)
++#define IRQ_C0_I2C (IRQ_C0_VIC_CHAIN_START + 24)
++
++#define IRQ_C1_N1_KCS (IRQ_C1_VIC_CHAIN_START + 0)
++#define IRQ_C1_N1_UART (IRQ_C1_VIC_CHAIN_START + 1)
++#define IRQ_C1_N1_MAILBOX (IRQ_C1_VIC_CHAIN_START + 2)
++#define IRQ_C1_N1_PORT80 (IRQ_C1_VIC_CHAIN_START + 3)
++#define IRQ_C1_N1_RESET (IRQ_C1_VIC_CHAIN_START + 4)
++#define IRQ_C1_N2_KCS (IRQ_C1_VIC_CHAIN_START + 5)
++#define IRQ_C1_N2_UART (IRQ_C1_VIC_CHAIN_START + 6)
++#define IRQ_C1_N2_MAILBOX (IRQ_C1_VIC_CHAIN_START + 7)
++#define IRQ_C1_N2_PORT80 (IRQ_C1_VIC_CHAIN_START + 8)
++#define IRQ_C1_N2_RESET (IRQ_C1_VIC_CHAIN_START + 9)
++#define IRQ_C1_N3_KCS (IRQ_C1_VIC_CHAIN_START + 10)
++#define IRQ_C1_N3_UART (IRQ_C1_VIC_CHAIN_START + 11)
++#define IRQ_C1_N3_MAILBOX (IRQ_C1_VIC_CHAIN_START + 12)
++#define IRQ_C1_N3_PORT80 (IRQ_C1_VIC_CHAIN_START + 13)
++#define IRQ_C1_N3_RESET (IRQ_C1_VIC_CHAIN_START + 14)
++#define IRQ_C1_N4_KCS (IRQ_C1_VIC_CHAIN_START + 15)
++#define IRQ_C1_N4_UART (IRQ_C1_VIC_CHAIN_START + 16)
++#define IRQ_C1_N4_MAILBOX (IRQ_C1_VIC_CHAIN_START + 17)
++#define IRQ_C1_N4_PORT80 (IRQ_C1_VIC_CHAIN_START + 18)
++#define IRQ_C1_N4_RESET (IRQ_C1_VIC_CHAIN_START + 19)
++#define IRQ_C1_N1_UART_DMA (IRQ_C1_VIC_CHAIN_START + 20)
++#define IRQ_C1_N2_UART_DMA (IRQ_C1_VIC_CHAIN_START + 21)
++#define IRQ_C1_N3_UART_DMA (IRQ_C1_VIC_CHAIN_START + 22)
++#define IRQ_C1_N4_UART_DMA (IRQ_C1_VIC_CHAIN_START + 23)
++#define IRQ_C1_I2C (IRQ_C1_VIC_CHAIN_START + 24)
++
++#define IRQ_C2_N1_KCS (IRQ_C2_VIC_CHAIN_START + 0)
++#define IRQ_C2_N1_UART (IRQ_C2_VIC_CHAIN_START + 1)
++#define IRQ_C2_N1_MAILBOX (IRQ_C2_VIC_CHAIN_START + 2)
++#define IRQ_C2_N1_PORT80 (IRQ_C2_VIC_CHAIN_START + 3)
++#define IRQ_C2_N1_RESET (IRQ_C2_VIC_CHAIN_START + 4)
++#define IRQ_C2_N2_KCS (IRQ_C2_VIC_CHAIN_START + 5)
++#define IRQ_C2_N2_UART (IRQ_C2_VIC_CHAIN_START + 6)
++#define IRQ_C2_N2_MAILBOX (IRQ_C2_VIC_CHAIN_START + 7)
++#define IRQ_C2_N2_PORT80 (IRQ_C2_VIC_CHAIN_START + 8)
++#define IRQ_C2_N2_RESET (IRQ_C2_VIC_CHAIN_START + 9)
++#define IRQ_C2_N3_KCS (IRQ_C2_VIC_CHAIN_START + 10)
++#define IRQ_C2_N3_UART (IRQ_C2_VIC_CHAIN_START + 11)
++#define IRQ_C2_N3_MAILBOX (IRQ_C2_VIC_CHAIN_START + 12)
++#define IRQ_C2_N3_PORT80 (IRQ_C2_VIC_CHAIN_START + 13)
++#define IRQ_C2_N3_RESET (IRQ_C2_VIC_CHAIN_START + 14)
++#define IRQ_C2_N4_KCS (IRQ_C2_VIC_CHAIN_START + 15)
++#define IRQ_C2_N4_UART (IRQ_C2_VIC_CHAIN_START + 16)
++#define IRQ_C2_N4_MAILBOX (IRQ_C2_VIC_CHAIN_START + 17)
++#define IRQ_C2_N4_PORT80 (IRQ_C2_VIC_CHAIN_START + 18)
++#define IRQ_C2_N4_RESET (IRQ_C2_VIC_CHAIN_START + 19)
++#define IRQ_C2_N1_UART_DMA (IRQ_C2_VIC_CHAIN_START + 20)
++#define IRQ_C2_N2_UART_DMA (IRQ_C2_VIC_CHAIN_START + 21)
++#define IRQ_C2_N3_UART_DMA (IRQ_C2_VIC_CHAIN_START + 22)
++#define IRQ_C2_N4_UART_DMA (IRQ_C2_VIC_CHAIN_START + 23)
++#define IRQ_C2_I2C (IRQ_C2_VIC_CHAIN_START + 24)
++
++#define IRQ_C3_N1_KCS (IRQ_C3_VIC_CHAIN_START + 0)
++#define IRQ_C3_N1_UART (IRQ_C3_VIC_CHAIN_START + 1)
++#define IRQ_C3_N1_MAILBOX (IRQ_C3_VIC_CHAIN_START + 2)
++#define IRQ_C3_N1_PORT80 (IRQ_C3_VIC_CHAIN_START + 3)
++#define IRQ_C3_N1_RESET (IRQ_C3_VIC_CHAIN_START + 4)
++#define IRQ_C3_N2_KCS (IRQ_C3_VIC_CHAIN_START + 5)
++#define IRQ_C3_N2_UART (IRQ_C3_VIC_CHAIN_START + 6)
++#define IRQ_C3_N2_MAILBOX (IRQ_C3_VIC_CHAIN_START + 7)
++#define IRQ_C3_N2_PORT80 (IRQ_C3_VIC_CHAIN_START + 8)
++#define IRQ_C3_N2_RESET (IRQ_C3_VIC_CHAIN_START + 9)
++#define IRQ_C3_N3_KCS (IRQ_C3_VIC_CHAIN_START + 10)
++#define IRQ_C3_N3_UART (IRQ_C3_VIC_CHAIN_START + 11)
++#define IRQ_C3_N3_MAILBOX (IRQ_C3_VIC_CHAIN_START + 12)
++#define IRQ_C3_N3_PORT80 (IRQ_C3_VIC_CHAIN_START + 13)
++#define IRQ_C3_N3_RESET (IRQ_C3_VIC_CHAIN_START + 14)
++#define IRQ_C3_N4_KCS (IRQ_C3_VIC_CHAIN_START + 15)
++#define IRQ_C3_N4_UART (IRQ_C3_VIC_CHAIN_START + 16)
++#define IRQ_C3_N4_MAILBOX (IRQ_C3_VIC_CHAIN_START + 17)
++#define IRQ_C3_N4_PORT80 (IRQ_C3_VIC_CHAIN_START + 18)
++#define IRQ_C3_N4_RESET (IRQ_C3_VIC_CHAIN_START + 19)
++#define IRQ_C3_N1_UART_DMA (IRQ_C3_VIC_CHAIN_START + 20)
++#define IRQ_C3_N2_UART_DMA (IRQ_C3_VIC_CHAIN_START + 21)
++#define IRQ_C3_N3_UART_DMA (IRQ_C3_VIC_CHAIN_START + 22)
++#define IRQ_C3_N4_UART_DMA (IRQ_C3_VIC_CHAIN_START + 23)
++#define IRQ_C3_I2C (IRQ_C3_VIC_CHAIN_START + 24)
++
++#endif
+diff --git a/arch/arm/mach-aspeed/include/mach/ast1070_platform.h b/arch/arm/mach-aspeed/include/mach/ast1070_platform.h
+new file mode 100644
+index 0000000..feefd91
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/ast1070_platform.h
+@@ -0,0 +1,100 @@
++/*
++ * 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 _AST1070_PLATFORM_H_
++#define _AST1070_PLATFORM_H_ 1
++
++#define AST_C0_BASE (AST_LPC_BRIDGE)
++
++#define AST_C0_UART0_BASE (AST_C0_BASE) /* Companion UART1 */
++#define AST_C0_UART1_BASE (AST_C0_BASE + 0x400) /* Companion UART2 */
++#define AST_C0_UART2_BASE (AST_C0_BASE + 0x800) /* Companion UART3 */
++#define AST_C0_UART3_BASE (AST_C0_BASE + 0xc00) /* Companion UART4 */
++#define AST_C0_LPC0_BASE (AST_C0_BASE + 0x1000) /* Companion LPC1 */
++#define AST_C0_LPC1_BASE (AST_C0_BASE + 0x1400) /* Companion LPC2 */
++#define AST_C0_LPC2_BASE (AST_C0_BASE + 0x1800) /* Companion LPC3 */
++#define AST_C0_LPC3_BASE (AST_C0_BASE + 0x1c00) /* Companion LPC4 */
++#define AST_C0_SCU_BASE (AST_C0_BASE + 0x2000) /* Companion SCU */
++#define AST_C0_VIC_BASE (AST_C0_BASE + 0x2400) /* Companion VIC */
++#define AST_C0_LPC_SLAVE_BASE (AST_C0_BASE + 0x2c00) /* Companion LPC SlLAVE */
++#define AST_C0_I2C_BASE (AST_C0_BASE + 0x3000) /* Companion I2C */
++#define AST_C0_SPI_BASE (AST_C0_BASE + 0x4000) /* Companion SPI */
++#define AST_C0_LPC_SPI_BASE (AST_C0_BASE + 0x4400) /* Companion LPC SPI */
++#define AST_C0_UART_DMA_BASE (AST_C0_BASE + 0x4800) /* Companion UART DMA */
++#define AST_C0_SPI_CONTROL_BASE (AST_C0_BASE + 0x4c00) /* Companion SPI CONTROL */
++#define AST_C0_SPI_SHADOW_SRAM_BASE (AST_C0_BASE + 0x5000) /* Companion SPI SHADOW SRAM */
++
++#define AST_C1_BASE (AST_LPC_BRIDGE + 0x10000)
++
++#define AST_C1_UART0_BASE (AST_C1_BASE) /* Companion UART1 */
++#define AST_C1_UART1_BASE (AST_C1_BASE + 0x400) /* Companion UART2 */
++#define AST_C1_UART2_BASE (AST_C1_BASE + 0x800) /* Companion UART3 */
++#define AST_C1_UART3_BASE (AST_C1_BASE + 0xc00) /* Companion UART4 */
++#define AST_C1_LPC0_BASE (AST_C1_BASE + 0x1000) /* Companion LPC1 */
++#define AST_C1_LPC1_BASE (AST_C1_BASE + 0x1400) /* Companion LPC2 */
++#define AST_C1_LPC2_BASE (AST_C1_BASE + 0x1800) /* Companion LPC3 */
++#define AST_C1_LPC3_BASE (AST_C1_BASE + 0x1c00) /* Companion LPC4 */
++#define AST_C1_SCU_BASE (AST_C1_BASE + 0x2000) /* Companion SCU */
++#define AST_C1_VIC_BASE (AST_C1_BASE + 0x2400) /* Companion VIC */
++#define AST_C1_LPC_SLAVE_BASE (AST_C1_BASE + 0x2c00) /* Companion LPC SlLAVE */
++#define AST_C1_I2C_BASE (AST_C1_BASE + 0x3000) /* Companion I2C */
++#define AST_C1_SPI_BASE (AST_C1_BASE + 0x4000) /* Companion SPI */
++#define AST_C1_LPC_SPI_BASE (AST_C1_BASE + 0x4400) /* Companion LPC SPI */
++#define AST_C1_UART_DMA_BASE (AST_C1_BASE + 0x4800) /* Companion UART DMA */
++#define AST_C1_SPI_CONTROL_BASE (AST_C1_BASE + 0x4c00) /* Companion SPI CONTROL */
++#define AST_C1_SPI_SHADOW_SRAM_BASE (AST_C1_BASE + 0x5000) /* Companion SPI SHADOW SRAM */
++
++#define AST_C2_BASE (AST_LPC_BRIDGE + 0x20000)
++
++#define AST_C2_UART0_BASE (AST_C2_BASE) /* Companion UART1 */
++#define AST_C2_UART1_BASE (AST_C2_BASE + 0x400) /* Companion UART2 */
++#define AST_C2_UART2_BASE (AST_C2_BASE + 0x800) /* Companion UART3 */
++#define AST_C2_UART3_BASE (AST_C2_BASE + 0xc00) /* Companion UART4 */
++#define AST_C2_LPC1_BASE (AST_C2_BASE + 0x1000) /* Companion LPC1 */
++#define AST_C2_LPC2_BASE (AST_C2_BASE + 0x1400) /* Companion LPC2 */
++#define AST_C2_LPC3_BASE (AST_C2_BASE + 0x1800) /* Companion LPC3 */
++#define AST_C2_LPC4_BASE (AST_C2_BASE + 0x1c00) /* Companion LPC4 */
++#define AST_C2_SCU_BASE (AST_C2_BASE + 0x2000) /* Companion SCU */
++#define AST_C2_VIC_BASE (AST_C2_BASE + 0x2400) /* Companion VIC */
++#define AST_C2_LPC_SLAVE_BASE (AST_C2_BASE + 0x2c00) /* Companion LPC SlLAVE */
++#define AST_C2_I2C_BASE (AST_C2_BASE + 0x3000) /* Companion I2C */
++#define AST_C2_SPI_BASE (AST_C2_BASE + 0x4000) /* Companion SPI */
++#define AST_C2_LPC_SPI_BASE (AST_C2_BASE + 0x4400) /* Companion LPC SPI */
++#define AST_C2_UART_DMA_BASE (AST_C2_BASE + 0x4800) /* Companion UART DMA */
++#define AST_C2_SPI_CONTROL_BASE (AST_C2_BASE + 0x4c00) /* Companion SPI CONTROL */
++#define AST_C2_SPI_SHADOW_SRAM_BASE (AST_C2_BASE + 0x5000) /* Companion SPI SHADOW SRAM */
++
++#define AST_C3_BASE (AST_LPC_BRIDGE + 0x30000)
++
++#define AST_C3_UART0_BASE (AST_C3_BASE) /* Companion UART1 */
++#define AST_C3_UART1_BASE (AST_C3_BASE + 0x400) /* Companion UART2 */
++#define AST_C3_UART2_BASE (AST_C3_BASE + 0x800) /* Companion UART3 */
++#define AST_C3_UART3_BASE (AST_C3_BASE + 0xc00) /* Companion UART4 */
++#define AST_C3_LPC0_BASE (AST_C3_BASE + 0x1000) /* Companion LPC1 */
++#define AST_C3_LPC1_BASE (AST_C3_BASE + 0x1400) /* Companion LPC2 */
++#define AST_C3_LPC2_BASE (AST_C3_BASE + 0x1800) /* Companion LPC3 */
++#define AST_C3_LPC3_BASE (AST_C3_BASE + 0x1c00) /* Companion LPC4 */
++#define AST_C3_SCU_BASE (AST_C3_BASE + 0x2000) /* Companion SCU */
++#define AST_C3_VIC_BASE (AST_C3_BASE + 0x2400) /* Companion VIC */
++#define AST_C3_LPC_SLAVE_BASE (AST_C3_BASE + 0x2c00) /* Companion LPC SlLAVE */
++#define AST_C3_I2C_BASE (AST_C3_BASE + 0x3000) /* Companion I2C */
++#define AST_C3_SPI_BASE (AST_C3_BASE + 0x4000) /* Companion SPI */
++#define AST_C3_LPC_SPI_BASE (AST_C3_BASE + 0x4400) /* Companion LPC SPI */
++#define AST_C3_UART_DMA_BASE (AST_C3_BASE + 0x4800) /* Companion UART DMA */
++#define AST_C3_SPI_CONTROL_BASE (AST_C3_BASE + 0x4c00) /* Companion SPI CONTROL */
++#define AST_C3_SPI_SHADOW_SRAM_BASE (AST_C3_BASE + 0x5000) /* Companion SPI SHADOW SRAM */
++
++#endif
+diff --git a/arch/arm/mach-aspeed/include/mach/ast1520_irqs.h b/arch/arm/mach-aspeed/include/mach/ast1520_irqs.h
+new file mode 100644
+index 0000000..3ebc91b
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/ast1520_irqs.h
+@@ -0,0 +1,107 @@
++/*
++ * arch/arm/plat-aspeed/include/plat/irqs.h
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#ifndef _AST1520_IRQS_H_
++#define _AST1520_IRQS_H_ 1
++
++
++#ifdef CONFIG_PCIE
++#define NR_IRQS (ARCH_NR_GPIOS +ARCH_NR_PCIE + AST_VIC_NUM)
++
++//--------------GPIO ---------------------------------------------------------------
++#define ARCH_NR_GPIOS (GPIO_PORT_NUM*8)
++#define IRQ_GPIO_CHAIN_START AST_VIC_NUM
++//------------------- ---------------------------------------------------------------
++
++#define ARCH_NR_PCIE 5
++#define IRQ_PCIE_CHAIN IRQ_PCIE
++#define IRQ_PCIE_CHAIN_START (ARCH_NR_GPIOS + AST_VIC_NUM)
++
++#define IRQ_PCIE_INTA (IRQ_PCIE_CHAIN_START)
++#define IRQ_PCIE_INTB (IRQ_PCIE_CHAIN_START + 1)
++#define IRQ_PCIE_INTC (IRQ_PCIE_CHAIN_START + 2)
++#define IRQ_PCIE_INTD (IRQ_PCIE_CHAIN_START + 3)
++#define IRQ_PCIE_MSI0 (IRQ_PCIE_INTD + 1) // support max 32 MSI
++
++#else
++#define NR_IRQS (AST_VIC_NUM + ARCH_NR_GPIOS)
++//--------------GPIO ---------------------------------------------------------------
++#define ARCH_NR_GPIOS (GPIO_PORT_NUM*8)
++#define IRQ_GPIO_CHAIN_START AST_VIC_NUM
++//------------------- ---------------------------------------------------------------
++#endif
++
++#define AST_VIC_NUM 51
++
++//#define IRQ_SDRAM_ECC 0
++//#define IRQ_MIC 1
++#define IRQ_MAC0 2 /* MAC 1 interrupt */
++//#define IRQ_MAC1 3 /* MAC 2 interrupt */
++#define IRQ_CRYPTO 4
++#define IRQ_USB20_HUB 5
++#define IRQ_EHCI 5
++#define IRQ_XDMA 6
++#define IRQ_VIDEO 7
++//#define IRQ_LPC 8
++#define IRQ_UART1 9 /* UART 1 interrupt */
++#define IRQ_UART0 10 /* UART 3 interrupt */
++//11 Reserved
++#define IRQ_I2C 12
++//#define IRQ_UDC11 13
++#define IRQ_UHCI 14
++//#define IRQ_PECI 15
++#define IRQ_TIMER0 16 /* TIMER 1 interrupt */
++#define IRQ_TIMER1 17 /* TIMER 2 interrupt */
++#define IRQ_TIMER2 18 /* TIMER 3 interrupt */
++//#define IRQ_SMC 19
++#define IRQ_GPIO 20
++#define IRQ_SCU 21
++#define IRQ_RTC 22
++//23 , 24 reserverd
++#define IRQ_CRT 25
++#define IRQ_SDHC 26
++#define IRQ_WDT 27
++#define IRQ_TACHO 28
++#define IRQ_2D 29
++#define IRQ_SYS_WAKEUP 30
++//#define IRQ_ADC 31
++#define IRQ_UART2 32 /* UART 2 interrupt */
++//#define IRQ_UART2 33 /* UART 3 interrupt */
++//#define IRQ_UART3 34 /* UART 4 interrupt */
++//#define IRQ_TIMER3 35 /* TIMER 4 interrupt */
++//#define IRQ_TIMER4 36
++//#define IRQ_TIMER5 37
++//#define IRQ_TIMER6 38
++//#define IRQ_TIMER7 39 /* TIMER 8 interrupt */
++//#define IRQ_SGPIO_MASTER 40
++//#define IRQ_SGPIO_SLAVE 41
++#define IRQ_PCIE 41
++
++#define IRQ_MCTP 42
++//#define IRQ_JTAG 43
++#define IRQ_PS2 44
++#define IRQ_CPU1 45
++//#define IRQ_MAILBOX 46
++#define IRQ_EXT0_GPIOL1 47
++#define IRQ_EXT1_GPIOL3 48
++#define IRQ_EXT2_GPIOM3 49
++#define IRQ_EXT3_GPIOM3 50
++
++#endif
+diff --git a/arch/arm/mach-aspeed/include/mach/ast1520_platform.h b/arch/arm/mach-aspeed/include/mach/ast1520_platform.h
+new file mode 100644
+index 0000000..daded5d
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/ast1520_platform.h
+@@ -0,0 +1,61 @@
++/*
++ * 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 _AST1520_PLATFORM_H_
++#define _AST1520_PLATFORM_H_ 1
++
++#define AST_SRAM_SIZE (SZ_8K)
++
++#define AST_AHB_CTRL_BASE 0x1E600000 /* AHB CONTROLLER */
++
++#define AST_SPI_BASE 0x1E620000 /* SPI CONTROLLER */
++
++#define AST_MAC0_BASE 0x1E660000 /* MAC1 */
++
++#define AST_USB20_BASE 0x1E6A0000 /* USB 2.0 VIRTUAL HUB CONTROLLER */
++#define AST_EHCI_BASE 0x1E6A1000 /* USB 2.0 HOST CONTROLLER */
++#define AST_UHCI_BASE 0x1E6B0000 /* USB 1.1 HOST CONTROLLER */
++#define AST_VIC_BASE 0x1E6C0000 /* VIC */
++#define AST_SDMC_BASE 0x1E6E0000 /* MMC SDRAM*/
++#define AST_SCU_BASE 0x1E6E2000 /* SCU */
++#define AST_CRYPTO_BASE 0x1E6E3000 /* Crypto */
++
++#define AST_I2S_BASE 0x1E6E5000 /* I2S */
++#define AST_GRAPHIC_BASE 0x1E6E6000 /* Graphics */
++#define AST_XDMA_BASE 0x1E6E7000 /* XDMA */
++#define AST_MCTP_BASE 0x1E6E8000 /* MCTP */
++#define AST_PCIE_BASE 0x1E6ED000 /* PCIE */
++
++#define AST_VIDEO_BASE 0x1E700000 /* VIDEO ENGINE */
++#define AST_SRAM_BASE 0x1E720000 /* SRAM */
++#define AST_SDHC_BASE 0x1E740000 /* SD */
++#define AST_2D_BASE 0x1E760000 /* 2D */
++#define AST_GPIO_BASE 0x1E780000 /* GPIO */
++#define AST_RTC_BASE 0x1E781000 /* RTC */
++#define AST_TIMER_BASE 0x1E782000 /* TIMER #0~2*/
++#define AST_UART1_BASE 0x1E783000 /* UART1 */
++#define AST_UART0_BASE 0x1E784000 /* UART3 */
++#define AST_WDT_BASE 0x1E785000 /* WDT */
++
++#define AST_I2C_BASE 0x1E78A000 /* I2C */
++#define AST_UART2_BASE 0x1E78D000 /* UART2 */
++
++#define AST_SPI0_MEM 0x20000000
++
++#define AST_PCIE_WIN_BASE 0x70000000
++#define AST_PCIE_WIN_SIZE 0x01000000
++
++#endif
+diff --git a/arch/arm/mach-aspeed/include/mach/ast2000_irqs.h b/arch/arm/mach-aspeed/include/mach/ast2000_irqs.h
+new file mode 100644
+index 0000000..50aece9
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/ast2000_irqs.h
+@@ -0,0 +1,64 @@
++/*
++ * arch/arm/plat-aspeed/include/plat/irqs.h
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#ifndef _AST2000_IRQS_H_
++#define _AST2000_IRQS_H_ 1
++
++#define NR_IRQS (AST_VIC_NUM + ARCH_NR_GPIOS)
++//--------------GPIO ---------------------------------------------------------------
++#define ARCH_NR_GPIOS (GPIO_PORT_NUM*8)
++#define IRQ_GPIO_CHAIN_START AST_VIC_NUM
++
++#define AST_VIC_NUM 32
++
++#define IRQ_SPI 0
++#define IRQ_UART0 1
++#define IRQ_UART1 2
++#define IRQ_TIMER0 3
++#define IRQ_TIMER1 4
++#define IRQ_TIMER2 5
++#define IRQ_RTC 6
++#define IRQ_MAC0 7
++#define IRQ_GPIO_B0 8
++#define IRQ_UDC 9
++#define IRQ_PCI 10
++#define IRQ_GPIO_B1 11
++#define IRQ_GPIO_B2 12
++#define IRQ_GPIO_B3 13
++#define IRQ_LPC 14
++#define IRQ_I2C 15
++#define IRQ_USB11 16
++#define IRQ_VIDEO 17
++#define IRQ_CRYPTO 18
++#define IRQ_SCU 19
++#define IRQ_GPIO_B4 20
++#define IRQ_GPIO_B5 21
++#define IRQ_GPIO_B6 22
++#define IRQ_GPIO_A0 23
++#define IRQ_GPIO_A1 24
++#define IRQ_GPIO_A2 25
++#define IRQ_GPIO_A3 26
++#define IRQ_HDMA 27
++#define IRQ_GPIO_A4 28
++#define IRQ_GPIO_A5 29
++#define IRQ_GPIO_A6 30
++#define IRQ_WDT 31
++
++#endif
+diff --git a/arch/arm/mach-aspeed/include/mach/ast2000_platform.h b/arch/arm/mach-aspeed/include/mach/ast2000_platform.h
+new file mode 100644
+index 0000000..ff34f5b
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/ast2000_platform.h
+@@ -0,0 +1,40 @@
++/*
++ * 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 _AST2000_PLATFORM_H_
++#define _AST2000_PLATFORM_H_ 1
++
++#define AST_MAC0_BASE 0x19c80000 /* MAC1 */
++#define AST_CRYPTO_BASE 0x1E6E0040 /* Crypto */
++#define AST_UDC11_BASE 0x1E6E0080 /* USB11 */
++#define AST_SCU0_BASE 0x1E6E0100 /* SCU1 */
++#define AST_LPC_BASE 0x1E6E0400 /* LPC */
++#define AST_I2C_BASE 0x1E6E0800 /* I2C */
++//---//
++#define AST_VIDEO_BASE 0x1E700000 /* VIDEO ENGINE */
++#define AST_AHB_TO_PBUS_BASE 0x1E720000 /* APB -> PBUS */
++//...//
++#define AST_HDMA_BASE 0x1E7c0000 /* HDMA */
++#define AST_TIMER_BASE 0x1E800000 /* TIMER0/1/2 */
++#define AST_RTC_BASE 0x1E820000 /* RTC */
++#define AST_UART0_BASE 0x1E840000 /* UART0 */
++#define AST_UART1_BASE 0x1E860000 /* UART1 */
++#define AST_SPI_BASE 0x1E880000 /* SPI */
++#define AST_GPIO_BASE 0x1E8A0000 /* GPIO */
++#define AST_WDT_BASE 0x1E8C0000 /* WDT */
++#define AST_SCU0_BASE 0x1E8E000c /* SCU2 */
++
++#endif
+diff --git a/arch/arm/mach-aspeed/include/mach/ast2100_irqs.h b/arch/arm/mach-aspeed/include/mach/ast2100_irqs.h
+new file mode 100644
+index 0000000..8513909
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/ast2100_irqs.h
+@@ -0,0 +1,64 @@
++/*
++ * arch/arm/plat-aspeed/include/plat/irqs.h
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#ifndef _AST2100_IRQS_H_
++#define _AST2100_IRQS_H_ 1
++
++
++#define NR_IRQS (AST_VIC_NUM + ARCH_NR_GPIOS)
++//--------------GPIO ---------------------------------------------------------------
++#define ARCH_NR_GPIOS (GPIO_PORT_NUM*8)
++#define IRQ_GPIO_CHAIN_START AST_VIC_NUM
++
++#define AST_VIC_NUM 32
++#define IRQ_SDRAM_ECC 0
++#define IRQ_MIC 1
++#define IRQ_MAC0 2 /* MAC 1 interrupt */
++#define IRQ_MAC1 3 /* MAC 2 interrupt */
++#define IRQ_CRYPTO 4
++#define IRQ_USB20_HUB 5
++#define IRQ_EHCI 5
++#define IRQ_XDMA 6
++#define IRQ_VIDEO 7
++#define IRQ_LPC 8
++#define IRQ_UART0 9 /* UART 1 interrupt */
++#define IRQ_UART1 10 /* UART 2 interrupt */
++//11 reserved
++#define IRQ_I2C 12
++#define IRQ_UDC11 13
++//14 reserved
++#define IRQ_PECI 15
++#define IRQ_TIMER0 16 /* TIMER 1 interrupt */
++#define IRQ_TIMER1 17 /* TIMER 2 interrupt */
++#define IRQ_TIMER2 18 /* TIMER 3 interrupt */
++#define IRQ_SMC 19
++#define IRQ_GPIO 20
++#define IRQ_SCU 21
++#define IRQ_RTC_SEC 22
++#define IRQ_RTC_DAY 23
++#define IRQ_RTC_HOUR 24
++#define IRQ_RTC_MIN 25
++#define IRQ_RTC 26
++#define IRQ_WDT 27
++#define IRQ_TACHO 28
++#define IRQ_2D 29
++#define IRQ_PCI 30
++#define IRQ_AHBC 31
++#endif
+diff --git a/arch/arm/mach-aspeed/include/mach/ast2100_platform.h b/arch/arm/mach-aspeed/include/mach/ast2100_platform.h
+new file mode 100644
+index 0000000..6d59ca4
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/ast2100_platform.h
+@@ -0,0 +1,56 @@
++/*
++ * 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 _AST2100_PLATFORM_H_
++#define _AST2100_PLATFORM_H_ 1
++
++#define AST_OLD_SMC_BASE 0x10000000 /*Legacy BMC Static Memory */
++#define AST_OLD_SMC_CTRL_BASE 0x16000000 /*Legacy BMC Static Memory Ctrl*/
++
++#define AST_AHB_CTRL_BASE 0x1E600000 /* AHB CONTROLLER */
++
++#define AST_MIC_BASE 0x1E640000 /* MIC CONTROLLER */
++#define AST_MAC1_BASE 0x1E660000 /* MAC1 */
++#define AST_MAC2_BASE 0x1E680000 /* MAC2 */
++
++#define AST_USB20_BASE 0x1E6A0000 /* USB 2.0 VIRTUAL HUB CONTROLLER */
++#define AST_VIC_BASE 0x1E6C0000 /* VIC */
++#define AST_SDMC_BASE 0x1E6E0000 /* MMC */
++#define AST_UDC11_BASE 0x1E6E1000 /* USB11 */
++#define AST_SCU_BASE 0x1E6E2000 /* SCU */
++#define AST_CRYPTO_BASE 0x1E6E3000 /* Crypto */
++
++#define AST_GRAPHIC_BASE 0x1E6E6000 /* Graphics */
++
++#define AST_VIDEO_BASE 0x1E700000 /* VIDEO ENGINE */
++#define AST_AHB_TO_PBUS_BASE 0x1E720000 /* APB -> PBUS */
++#define AST_MDMA_BASE 0x1E740000 /* MDMA */
++#define AST_2D_BASE 0x1E760000 /* 2D */
++#define AST_GPIO_BASE 0x1E780000 /* GPIO */
++#define AST_RTC_BASE 0x1E781000 /* RTC */
++#define AST_TIMER_BASE 0x1E782000 /* TIMER #0~7*/
++#define AST_UART0_BASE 0x1E783000 /* UART1 */
++#define AST_UART1_BASE 0x1E784000 /* UART2 */
++#define AST_WDT_BASE 0x1E785000 /* WDT */
++#define AST_PWM_BASE 0x1E786000 /* PWM */
++#define AST_VUART0_BASE 0x1E787000 /* VUART1 */
++#define AST_PUART_BASE 0x1E788000 /* PUART */
++#define AST_LPC_BASE 0x1E789000 /* LPC */
++#define AST_I2C_BASE 0x1E78A000 /* I2C */
++#define AST_PECI_BASE 0x1E78B000 /* PECI */
++#define AST_PCIARBITER_BASE 0x1E78C000 /* PCI ARBITER */
++
++#endif
+diff --git a/arch/arm/mach-aspeed/include/mach/ast2200_irqs.h b/arch/arm/mach-aspeed/include/mach/ast2200_irqs.h
+new file mode 100644
+index 0000000..f0b880f
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/ast2200_irqs.h
+@@ -0,0 +1,65 @@
++/*
++ * arch/arm/plat-aspeed/include/plat/irqs.h
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#ifndef _AST2200_IRQS_H_
++#define _AST2200_IRQS_H_ 1
++
++#define NR_IRQS (AST_VIC_NUM + ARCH_NR_GPIOS)
++//--------------GPIO ---------------------------------------------------------------
++#define ARCH_NR_GPIOS (GPIO_PORT_NUM*8)
++#define IRQ_GPIO_CHAIN_START AST_VIC_NUM
++
++#define AST_VIC_NUM 32
++
++#define IRQ_SDRAM_ECC 0
++#define IRQ_MIC 1
++#define IRQ_MAC0 2 /* MAC 1 interrupt */
++#define IRQ_MAC1 3 /* MAC 2 interrupt */
++#define IRQ_CRYPTO 4
++#define IRQ_USB20_HUB 5
++#define IRQ_EHCI 5
++#define IRQ_XDMA 6
++#define IRQ_VIDEO 7
++#define IRQ_LPC 8
++#define IRQ_UART0 9 /* UART 1 interrupt */
++#define IRQ_UART1 10 /* UART 2 interrupt */
++//11 reserved
++#define IRQ_I2C 12
++#define IRQ_UDC11 13
++//14 reserved
++#define IRQ_PECI 15
++#define IRQ_TIMER0 16 /* TIMER 1 interrupt */
++#define IRQ_TIMER1 17 /* TIMER 2 interrupt */
++#define IRQ_TIMER2 18 /* TIMER 3 interrupt */
++#define IRQ_SMC 19
++#define IRQ_GPIO 20
++#define IRQ_SCU 21
++#define IRQ_RTC_SEC 22
++#define IRQ_RTC_DAY 23
++#define IRQ_RTC_HOUR 24
++#define IRQ_RTC_MIN 25
++#define IRQ_RTC 26
++#define IRQ_WDT 27
++#define IRQ_TACHO 28
++#define IRQ_2D 29
++#define IRQ_PCI 30
++#define IRQ_AHBC 31
++
++#endif
+diff --git a/arch/arm/mach-aspeed/include/mach/ast2200_platform.h b/arch/arm/mach-aspeed/include/mach/ast2200_platform.h
+new file mode 100644
+index 0000000..324e15b
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/ast2200_platform.h
+@@ -0,0 +1,55 @@
++/*
++ * 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 _AST2200_PLATFORM_H_
++#define _AST2200_PLATFORM_H_ 1
++
++#define AST_OLD_SMC_BASE 0x10000000 /*Legacy BMC Static Memory */
++#define AST_OLD_SMC_CTRL_BASE 0x16000000 /*Legacy BMC Static Memory Ctrl*/
++
++#define AST_AHB_CTRL_BASE 0x1E600000 /* AHB CONTROLLER */
++
++#define AST_MIC_BASE 0x1E640000 /* MIC CONTROLLER */
++#define AST_MAC1_BASE 0x1E660000 /* MAC1 */
++#define AST_MAC2_BASE 0x1E680000 /* MAC2 */
++
++#define AST_USB20_BASE 0x1E6A0000 /* USB 2.0 VIRTUAL HUB CONTROLLER */
++#define AST_VIC_BASE 0x1E6C0000 /* VIC */
++#define AST_SDMC_BASE 0x1E6E0000 /* MMC */
++#define AST_UDC11_BASE 0x1E6E1000 /* USB11 */
++#define AST_SCU_BASE 0x1E6E2000 /* SCU */
++#define AST_CRYPTO_BASE 0x1E6E3000 /* Crypto */
++
++#define AST_GRAPHIC_BASE 0x1E6E6000 /* Graphics */
++
++#define AST_VIDEO_BASE 0x1E700000 /* VIDEO ENGINE */
++#define AST_AHB_TO_PBUS_BASE 0x1E720000 /* APB -> PBUS */
++#define AST_MDMA_BASE 0x1E740000 /* MDMA */
++#define AST_2D_BASE 0x1E760000 /* 2D */
++#define AST_GPIO_BASE 0x1E780000 /* GPIO */
++#define AST_RTC_BASE 0x1E781000 /* RTC */
++#define AST_TIMER_BASE 0x1E782000 /* TIMER #0~7*/
++#define AST_UART0_BASE 0x1E783000 /* UART1 */
++#define AST_UART1_BASE 0x1E784000 /* UART2 */
++#define AST_WDT_BASE 0x1E785000 /* WDT */
++#define AST_PWM_BASE 0x1E786000 /* PWM */
++#define AST_VUART0_BASE 0x1E787000 /* VUART1 */
++#define AST_PUART_BASE 0x1E788000 /* PUART */
++#define AST_LPC_BASE 0x1E789000 /* LPC */
++#define AST_I2C_BASE 0x1E78A000 /* I2C */
++#define AST_PECI_BASE 0x1E78B000 /* PECI */
++
++#endif
+diff --git a/arch/arm/mach-aspeed/include/mach/ast2300_irqs.h b/arch/arm/mach-aspeed/include/mach/ast2300_irqs.h
+new file mode 100644
+index 0000000..2d7b0c8
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/ast2300_irqs.h
+@@ -0,0 +1,92 @@
++/*
++ * arch/arm/plat-aspeed/include/plat/irqs.h
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#ifndef _AST2300_IRQS_H_
++#define _AST2300_IRQS_H_ 1
++
++#if defined(CONFIG_ARCH_AST1070)
++//----------VIC + GPIO + CVIC chain--------------------------------------------------
++#define NR_IRQS (AST_VIC_NUM + ARCH_NR_GPIOS + AST_CVIC_NUM)
++//--------------GPIO ---------------------------------------------------------------
++#define ARCH_NR_GPIOS (GPIO_PORT_NUM*8)
++#define IRQ_GPIO_CHAIN_START (AST_VIC_NUM)
++//---------------CVIC---------------------------------------------------------------
++#define IRQ_C0_VIC_CHAIN IRQ_GPIOL1
++#define IRQ_C0_VIC_CHAIN_START (AST_VIC_NUM + ARCH_NR_GPIOS)
++//------------------- ---------------------------------------------------------------
++#else
++#define NR_IRQS (AST_VIC_NUM + ARCH_NR_GPIOS)
++//--------------GPIO ---------------------------------------------------------------
++#define ARCH_NR_GPIOS (GPIO_PORT_NUM*8)
++#define IRQ_GPIO_CHAIN_START AST_VIC_NUM
++
++#endif
++
++
++#define AST_VIC_NUM 46
++
++#define IRQ_SDRAM_ECC 0
++#define IRQ_MIC 1
++#define IRQ_MAC0 2 /* MAC 1 interrupt */
++#define IRQ_MAC1 3 /* MAC 2 interrupt */
++#define IRQ_CRYPTO 4
++#define IRQ_USB20_HUB 5
++#define IRQ_EHCI 5
++#define IRQ_XDMA 6
++#define IRQ_VIDEO 7
++#define IRQ_LPC 8
++#define IRQ_UART1 9 /* UART 1 interrupt */
++#define IRQ_UART0 10 /* UART 5 interrupt */
++//11 Reserved
++#define IRQ_I2C 12
++#define IRQ_UDC11 13
++#define IRQ_UHCI 14
++#define IRQ_PECI 15
++#define IRQ_TIMER0 16 /* TIMER 1 interrupt */
++#define IRQ_TIMER1 17 /* TIMER 2 interrupt */
++#define IRQ_TIMER2 18 /* TIMER 3 interrupt */
++#define IRQ_SMC 19
++#define IRQ_GPIO 20
++#define IRQ_SCU 21
++#define IRQ_RTC 22
++//23 , 24 reserverd
++#define IRQ_CRT 25
++#define IRQ_SDHC 26
++#define IRQ_WDT 27
++#define IRQ_TACHO 28
++#define IRQ_2D 29
++#define IRQ_SYS_WAKEUP 30
++#define IRQ_ADC 31
++#define IRQ_UART2 32 /* UART 2 interrupt */
++#define IRQ_UART3 33 /* UART 3 interrupt */
++#define IRQ_UART4 34 /* UART 4 interrupt */
++#define IRQ_TIMER3 35 /* TIMER 4 interrupt */
++#define IRQ_TIMER4 36
++#define IRQ_TIMER5 37
++#define IRQ_TIMER6 38
++#define IRQ_TIMER7 39 /* TIMER 8 interrupt */
++#define IRQ_SGPIO_MASTER 40
++#define IRQ_SGPIO_SLAVE 41
++#define IRQ_MCTP 42
++#define IRQ_JTAG 43
++//#define IRQ_RESERVED 44
++#define IRQ_CPU1 45
++
++#endif
+diff --git a/arch/arm/mach-aspeed/include/mach/ast2300_platform.h b/arch/arm/mach-aspeed/include/mach/ast2300_platform.h
+new file mode 100644
+index 0000000..4898856
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/ast2300_platform.h
+@@ -0,0 +1,72 @@
++/*
++ * 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 _AST2300_PLATFORM_H_
++#define _AST2300_PLATFORM_H_ 1
++
++#define AST_DRAM_BASE 0x40000000
++#define AST_SRAM_SIZE (SZ_16K)
++
++#define AST_OLD_SMC_BASE 0x10000000 /*Legacy BMC Static Memory */
++#define AST_OLD_SMC_CTRL_BASE 0x16000000 /*Legacy BMC Static Memory Ctrl*/
++
++#define AST_AHB_CTRL_BASE 0x1E600000 /* AHB CONTROLLER */
++
++#define AST_FMC_BASE 0x1E620000 /* NEW SMC CONTROLLER */
++#define AST_SPI_BASE 0x1E630000 /* SPI CONTROLLER */
++#define AST_MIC_BASE 0x1E640000 /* MIC CONTROLLER */
++#define AST_MAC0_BASE 0x1E660000 /* MAC1 */
++#define AST_MAC1_BASE 0x1E680000 /* MAC2 */
++
++#define AST_USB20_BASE 0x1E6A0000 /* USB 2.0 VIRTUAL HUB CONTROLLER */
++#define AST_UHCI_BASE 0x1E6B0000 /* USB 1.1 HOST CONTROLLER */
++#define AST_VIC_BASE 0x1E6C0000 /* VIC */
++#define AST_SDMC_BASE 0x1E6E0000 /* SDRAM CTRL */
++#define AST_UDC11_BASE 0x1E6E1000 /* USB11 */
++#define AST_SCU_BASE 0x1E6E2000 /* SCU */
++#define AST_CRYPTO_BASE 0x1E6E3000 /* Crypto */
++#define AST_JTAG_BASE 0x1E6E4000 /* JTAG */
++#define AST_GRAPHIC_BASE 0x1E6E6000 /* Graphics */
++#define AST_XDMA_BASE 0x1E6E7000 /* XDMA */
++#define AST_MCTP_BASE 0x1E6E8000 /* MCTP */
++#define AST_ADC_BASE 0x1E6E9000 /* ADC */
++
++#define AST_LPC_PLUS_BASE 0x1E6EC000 /* LPC+ Controller */
++
++#define AST_VIDEO_BASE 0x1E700000 /* VIDEO ENGINE */
++#define AST_SRAM_BASE 0x1E720000 /* SRAM */
++#define AST_SDHC_BASE 0x1E740000 /* SDHC */
++#define AST_2D_BASE 0x1E760000 /* 2D */
++#define AST_GPIO_BASE 0x1E780000 /* GPIO */
++#define AST_RTC_BASE 0x1E781000 /* RTC */
++#define AST_TIMER_BASE 0x1E782000 /* TIMER #0~7*/
++#define AST_UART1_BASE 0x1E783000 /* UART1 */
++#define AST_UART0_BASE 0x1E784000 /* UART5 */
++#define AST_WDT_BASE 0x1E785000 /* WDT */
++#define AST_PWM_BASE 0x1E786000 /* PWM */
++#define AST_VUART0_BASE 0x1E787000 /* VUART1 */
++#define AST_PUART_BASE 0x1E788000 /* PUART */
++#define AST_LPC_BASE 0x1E789000 /* LPC */
++#define AST_MBX_BASE 0x1E789200 /* MailBox */
++#define AST_I2C_BASE 0x1E78A000 /* I2C */
++#define AST_PECI_BASE 0x1E78B000 /* PECI */
++#define AST_UART2_BASE 0x1E78D000 /* UART2 */
++#define AST_UART3_BASE 0x1E78E000 /* UART3 */
++#define AST_UART4_BASE 0x1E78F000 /* UART4 */
++
++#define AST_LPC_BRIDGE 0x60000000
++
++#endif
+diff --git a/arch/arm/mach-aspeed/include/mach/ast2400_irqs.h b/arch/arm/mach-aspeed/include/mach/ast2400_irqs.h
+new file mode 100644
+index 0000000..17c59da
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/ast2400_irqs.h
+@@ -0,0 +1,96 @@
++/*
++ * arch/arm/plat-aspeed/include/plat/irqs.h
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#ifndef _AST2400_IRQS_H_
++#define _AST2400_IRQS_H_ 1
++
++#if defined(CONFIG_ARCH_AST1070)
++#include <mach/ast1070_irqs.h>
++#define MAX_AST1070_NR 2
++//----------VIC + CVIC + GPIO chain--------------------------------------------------
++#define NR_IRQS (AST_VIC_NUM + (AST_CVIC_NUM * MAX_AST1070_NR) + ARCH_NR_GPIOS)
++//--------------GPIO ---------------------------------------------------------------
++#define ARCH_NR_GPIOS (GPIO_PORT_NUM*8)
++#define IRQ_GPIO_CHAIN_START (AST_VIC_NUM + (AST_CVIC_NUM * MAX_AST1070_NR))
++//------------------- ---------------------------------------------------------------
++#else
++//--------------GPIO ---------------------------------------------------------------
++#define ARCH_NR_GPIOS (GPIO_PORT_NUM*8)
++#define IRQ_GPIO_CHAIN_START (AST_VIC_NUM)
++//------------------- ---------------------------------------------------------------
++#define NR_IRQS (AST_VIC_NUM + ARCH_NR_GPIOS)
++
++#endif
++
++#define AST_VIC_NUM 51
++
++#define IRQ_SDRAM_ECC 0
++#define IRQ_MIC 1
++#define IRQ_MAC0 2 /* MAC 1 interrupt */
++#define IRQ_MAC1 3 /* MAC 2 interrupt */
++#define IRQ_CRYPTO 4
++#define IRQ_USB20_HUB 5
++#define IRQ_EHCI 5
++#define IRQ_XDMA 6
++#define IRQ_VIDEO 7
++#define IRQ_LPC 8
++#define IRQ_UART1 9 /* UART 1 interrupt */
++#define IRQ_UART0 10 /* UART 5 interrupt */
++//11 Reserved
++#define IRQ_I2C 12
++#define IRQ_UDC11 13
++#define IRQ_UHCI 14
++#define IRQ_PECI 15
++#define IRQ_TIMER0 16 /* TIMER 1 interrupt */
++#define IRQ_TIMER1 17 /* TIMER 2 interrupt */
++#define IRQ_TIMER2 18 /* TIMER 3 interrupt */
++#define IRQ_SMC 19
++#define IRQ_GPIO 20
++#define IRQ_SCU 21
++#define IRQ_RTC 22
++//23 , 24 reserverd
++#define IRQ_CRT 25
++#define IRQ_SDHC 26
++#define IRQ_WDT 27
++#define IRQ_TACHO 28
++#define IRQ_2D 29
++#define IRQ_SYS_WAKEUP 30
++#define IRQ_ADC 31
++#define IRQ_UART2 32 /* UART 2 interrupt */
++#define IRQ_UART3 33 /* UART 3 interrupt */
++#define IRQ_UART4 34 /* UART 4 interrupt */
++#define IRQ_TIMER3 35 /* TIMER 4 interrupt */
++#define IRQ_TIMER4 36
++#define IRQ_TIMER5 37
++#define IRQ_TIMER6 38
++#define IRQ_TIMER7 39 /* TIMER 8 interrupt */
++#define IRQ_SGPIO_MASTER 40
++#define IRQ_SGPIO_SLAVE 41
++#define IRQ_MCTP 42
++#define IRQ_JTAG 43
++//#define IRQ_RESERVED 44
++#define IRQ_CPU1 45
++#define IRQ_MAILBOX 46
++#define IRQ_EXT0 47
++#define IRQ_EXT1 48
++#define IRQ_EXT2 49
++#define IRQ_EXT3 50
++
++#endif
+diff --git a/arch/arm/mach-aspeed/include/mach/ast2400_platform.h b/arch/arm/mach-aspeed/include/mach/ast2400_platform.h
+new file mode 100644
+index 0000000..e507953
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/ast2400_platform.h
+@@ -0,0 +1,79 @@
++/*
++ * 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 _AST2400_PLATFORM_H_
++#define _AST2400_PLATFORM_H_ 1
++
++#define AST_DRAM_BASE 0x40000000
++
++#define AST_SRAM_SIZE (SZ_16K*2)
++
++#define AST_OLD_SMC_BASE 0x10000000 /*Legacy BMC Static Memory */
++#define AST_OLD_SMC_CTRL_BASE 0x16000000 /*Legacy BMC Static Memory Ctrl*/
++
++#define AST_AHB_CTRL_BASE 0x1E600000 /* AHB CONTROLLER */
++
++#define AST_FMC_BASE 0x1E620000 /* NEW SMC CONTROLLER */
++#define AST_SPI_BASE 0x1E630000 /* SPI CONTROLLER */
++#define AST_MIC_BASE 0x1E640000 /* MIC CONTROLLER */
++#define AST_MAC0_BASE 0x1E660000 /* MAC1 */
++#define AST_MAC1_BASE 0x1E680000 /* MAC2 */
++
++#define AST_USB20_BASE 0x1E6A0000 /* USB 2.0 VIRTUAL HUB CONTROLLER */
++#define AST_EHCI_BASE 0x1E6A1000 /* USB 2.0 HOST CONTROLLER */
++#define AST_UHCI_BASE 0x1E6B0000 /* USB 1.1 HOST CONTROLLER */
++#define AST_VIC_BASE 0x1E6C0000 /* VIC */
++#define AST_SDMC_BASE 0x1E6E0000 /* SDRAM CTRL */
++#define AST_UDC11_BASE 0x1E6E1000 /* USB11 */
++#define AST_SCU_BASE 0x1E6E2000 /* SCU */
++#define AST_CRYPTO_BASE 0x1E6E3000 /* Crypto */
++#define AST_JTAG_BASE 0x1E6E4000 /* JTAG */
++#define AST_GRAPHIC_BASE 0x1E6E6000 /* Graphics */
++#define AST_XDMA_BASE 0x1E6E7000 /* XDMA */
++#define AST_MCTP_BASE 0x1E6E8000 /* MCTP */
++#define AST_ADC_BASE 0x1E6E9000 /* ADC */
++
++#define AST_LPC_PLUS_BASE 0x1E6EC000 /* LPC+ Controller */
++
++#define AST_VIDEO_BASE 0x1E700000 /* VIDEO ENGINE */
++#define AST_SRAM_BASE 0x1E720000 /* SRAM */
++#define AST_SDHC_BASE 0x1E740000 /* SDHC */
++#define AST_2D_BASE 0x1E760000 /* 2D */
++#define AST_GPIO_BASE 0x1E780000 /* GPIO */
++#define AST_RTC_BASE 0x1E781000 /* RTC */
++#define AST_TIMER_BASE 0x1E782000 /* TIMER #0~7*/
++#define AST_UART1_BASE 0x1E783000 /* UART1 */
++#define AST_UART0_BASE 0x1E784000 /* UART5 */
++#define AST_WDT_BASE 0x1E785000 /* WDT */
++#define AST_PWM_BASE 0x1E786000 /* PWM */
++#define AST_VUART0_BASE 0x1E787000 /* VUART1 */
++#define AST_PUART_BASE 0x1E788000 /* PUART */
++#define AST_LPC_BASE 0x1E789000 /* LPC */
++#define AST_MBX_BASE 0x1E789200 /* MailBox */
++#define AST_I2C_BASE 0x1E78A000 /* I2C */
++#define AST_PECI_BASE 0x1E78B000 /* PECI */
++#define AST_PCIARBITER_BASE 0x1E78C000 /* PCI ARBITER */
++#define AST_UART2_BASE 0x1E78D000 /* UART2 */
++#define AST_UART3_BASE 0x1E78E000 /* UART3 */
++#define AST_UART4_BASE 0x1E78F000 /* UART4 */
++#define AST_SPI0_MEM 0x30000000
++
++#define AST_LPC_PLUS_BRIDGE 0x70000000
++
++#define AST_LPC_BRIDGE 0x60000000
++
++
++#endif
+diff --git a/arch/arm/mach-aspeed/include/mach/ast_gpio_irqs.h b/arch/arm/mach-aspeed/include/mach/ast_gpio_irqs.h
+new file mode 100644
+index 0000000..3bae742
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/ast_gpio_irqs.h
+@@ -0,0 +1,272 @@
++/*
++ * file : gpio_irqs.h
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#ifndef _GPIO_IRQS_H_
++#define _GPIO_IRQS_H_ 1
++
++#if defined(CONFIG_ARCH_AST1010)
++#define GPIO_PORT_NUM 19
++#elif defined(CONFIG_ARCH_AST2000)
++#define GPIO_PORT_NUM 19
++#elif defined(CONFIG_ARCH_AST2100)
++#define GPIO_PORT_NUM 19
++#elif defined(CONFIG_ARCH_AST2200)
++#define GPIO_PORT_NUM 19
++#elif defined(CONFIG_ARCH_AST2300)
++#define GPIO_PORT_NUM 19
++#elif defined(CONFIG_ARCH_AST2400)
++#define GPIO_PORT_NUM 28
++#elif defined(CONFIG_ARCH_AST1520)
++#define GPIO_PORT_NUM 28
++#else
++#err "no define for gpio irqs.h"
++#endif
++
++
++#define IRQ_GPIOA0 (IRQ_GPIO_CHAIN_START + 0)
++#define IRQ_GPIOA1 (IRQ_GPIO_CHAIN_START + 1)
++#define IRQ_GPIOA2 (IRQ_GPIO_CHAIN_START + 2)
++#define IRQ_GPIOA3 (IRQ_GPIO_CHAIN_START + 3)
++#define IRQ_GPIOA4 (IRQ_GPIO_CHAIN_START + 4)
++#define IRQ_GPIOA5 (IRQ_GPIO_CHAIN_START + 5)
++#define IRQ_GPIOA6 (IRQ_GPIO_CHAIN_START + 6)
++#define IRQ_GPIOA7 (IRQ_GPIO_CHAIN_START + 7)
++#define IRQ_GPIOB0 (IRQ_GPIO_CHAIN_START + 8)
++#define IRQ_GPIOB1 (IRQ_GPIO_CHAIN_START + 9)
++#define IRQ_GPIOB2 (IRQ_GPIO_CHAIN_START + 10)
++#define IRQ_GPIOB3 (IRQ_GPIO_CHAIN_START + 11)
++#define IRQ_GPIOB4 (IRQ_GPIO_CHAIN_START + 12)
++#define IRQ_GPIOB5 (IRQ_GPIO_CHAIN_START + 13)
++#define IRQ_GPIOB6 (IRQ_GPIO_CHAIN_START + 14)
++#define IRQ_GPIOB7 (IRQ_GPIO_CHAIN_START + 15)
++#define IRQ_GPIOC0 (IRQ_GPIO_CHAIN_START + 16)
++#define IRQ_GPIOC1 (IRQ_GPIO_CHAIN_START + 17)
++#define IRQ_GPIOC2 (IRQ_GPIO_CHAIN_START + 18)
++#define IRQ_GPIOC3 (IRQ_GPIO_CHAIN_START + 19)
++#define IRQ_GPIOC4 (IRQ_GPIO_CHAIN_START + 20)
++#define IRQ_GPIOC5 (IRQ_GPIO_CHAIN_START + 21)
++#define IRQ_GPIOC6 (IRQ_GPIO_CHAIN_START + 22)
++#define IRQ_GPIOC7 (IRQ_GPIO_CHAIN_START + 23)
++#define IRQ_GPIOD0 (IRQ_GPIO_CHAIN_START + 24)
++#define IRQ_GPIOD1 (IRQ_GPIO_CHAIN_START + 25)
++#define IRQ_GPIOD2 (IRQ_GPIO_CHAIN_START + 26)
++#define IRQ_GPIOD3 (IRQ_GPIO_CHAIN_START + 27)
++#define IRQ_GPIOD4 (IRQ_GPIO_CHAIN_START + 28)
++#define IRQ_GPIOD5 (IRQ_GPIO_CHAIN_START + 29)
++#define IRQ_GPIOD6 (IRQ_GPIO_CHAIN_START + 30)
++#define IRQ_GPIOD7 (IRQ_GPIO_CHAIN_START + 31)
++#define IRQ_GPIOE0 (IRQ_GPIO_CHAIN_START + 32)
++#define IRQ_GPIOE1 (IRQ_GPIO_CHAIN_START + 33)
++#define IRQ_GPIOE2 (IRQ_GPIO_CHAIN_START + 34)
++#define IRQ_GPIOE3 (IRQ_GPIO_CHAIN_START + 35)
++#define IRQ_GPIOE4 (IRQ_GPIO_CHAIN_START + 36)
++#define IRQ_GPIOE5 (IRQ_GPIO_CHAIN_START + 37)
++#define IRQ_GPIOE6 (IRQ_GPIO_CHAIN_START + 38)
++#define IRQ_GPIOE7 (IRQ_GPIO_CHAIN_START + 39)
++#define IRQ_GPIOF0 (IRQ_GPIO_CHAIN_START + 40)
++#define IRQ_GPIOF1 (IRQ_GPIO_CHAIN_START + 41)
++#define IRQ_GPIOF2 (IRQ_GPIO_CHAIN_START + 42)
++#define IRQ_GPIOF3 (IRQ_GPIO_CHAIN_START + 43)
++#define IRQ_GPIOF4 (IRQ_GPIO_CHAIN_START + 44)
++#define IRQ_GPIOF5 (IRQ_GPIO_CHAIN_START + 45)
++#define IRQ_GPIOF6 (IRQ_GPIO_CHAIN_START + 46)
++#define IRQ_GPIOF7 (IRQ_GPIO_CHAIN_START + 47)
++#define IRQ_GPIOG0 (IRQ_GPIO_CHAIN_START + 48)
++#define IRQ_GPIOG1 (IRQ_GPIO_CHAIN_START + 49)
++#define IRQ_GPIOG2 (IRQ_GPIO_CHAIN_START + 50)
++#define IRQ_GPIOG3 (IRQ_GPIO_CHAIN_START + 51)
++#define IRQ_GPIOG4 (IRQ_GPIO_CHAIN_START + 52)
++#define IRQ_GPIOG5 (IRQ_GPIO_CHAIN_START + 53)
++#define IRQ_GPIOG6 (IRQ_GPIO_CHAIN_START + 54)
++#define IRQ_GPIOG7 (IRQ_GPIO_CHAIN_START + 55)
++#define IRQ_GPIOH0 (IRQ_GPIO_CHAIN_START + 56)
++#define IRQ_GPIOH1 (IRQ_GPIO_CHAIN_START + 57)
++#define IRQ_GPIOH2 (IRQ_GPIO_CHAIN_START + 58)
++#define IRQ_GPIOH3 (IRQ_GPIO_CHAIN_START + 59)
++#define IRQ_GPIOH4 (IRQ_GPIO_CHAIN_START + 60)
++#define IRQ_GPIOH5 (IRQ_GPIO_CHAIN_START + 61)
++#define IRQ_GPIOH6 (IRQ_GPIO_CHAIN_START + 62)
++#define IRQ_GPIOH7 (IRQ_GPIO_CHAIN_START + 63)
++#define IRQ_GPIOI0 (IRQ_GPIO_CHAIN_START + 64)
++#define IRQ_GPIOI1 (IRQ_GPIO_CHAIN_START + 65)
++#define IRQ_GPIOI2 (IRQ_GPIO_CHAIN_START + 66)
++#define IRQ_GPIOI3 (IRQ_GPIO_CHAIN_START + 67)
++#define IRQ_GPIOI4 (IRQ_GPIO_CHAIN_START + 68)
++#define IRQ_GPIOI5 (IRQ_GPIO_CHAIN_START + 69)
++#define IRQ_GPIOI6 (IRQ_GPIO_CHAIN_START + 70)
++#define IRQ_GPIOI7 (IRQ_GPIO_CHAIN_START + 71)
++#define IRQ_GPIOJ0 (IRQ_GPIO_CHAIN_START + 72)
++#define IRQ_GPIOJ1 (IRQ_GPIO_CHAIN_START + 73)
++#define IRQ_GPIOJ2 (IRQ_GPIO_CHAIN_START + 74)
++#define IRQ_GPIOJ3 (IRQ_GPIO_CHAIN_START + 75)
++#define IRQ_GPIOJ4 (IRQ_GPIO_CHAIN_START + 76)
++#define IRQ_GPIOJ5 (IRQ_GPIO_CHAIN_START + 77)
++#define IRQ_GPIOJ6 (IRQ_GPIO_CHAIN_START + 78)
++#define IRQ_GPIOJ7 (IRQ_GPIO_CHAIN_START + 79)
++#define IRQ_GPIOK0 (IRQ_GPIO_CHAIN_START + 80)
++#define IRQ_GPIOK1 (IRQ_GPIO_CHAIN_START + 81)
++#define IRQ_GPIOK2 (IRQ_GPIO_CHAIN_START + 82)
++#define IRQ_GPIOK3 (IRQ_GPIO_CHAIN_START + 83)
++#define IRQ_GPIOK4 (IRQ_GPIO_CHAIN_START + 84)
++#define IRQ_GPIOK5 (IRQ_GPIO_CHAIN_START + 85)
++#define IRQ_GPIOK6 (IRQ_GPIO_CHAIN_START + 86)
++#define IRQ_GPIOK7 (IRQ_GPIO_CHAIN_START + 87)
++#define IRQ_GPIOL0 (IRQ_GPIO_CHAIN_START + 88)
++#define IRQ_GPIOL1 (IRQ_GPIO_CHAIN_START + 89)
++#define IRQ_GPIOL2 (IRQ_GPIO_CHAIN_START + 90)
++#define IRQ_GPIOL3 (IRQ_GPIO_CHAIN_START + 91)
++#define IRQ_GPIOL4 (IRQ_GPIO_CHAIN_START + 92)
++#define IRQ_GPIOL5 (IRQ_GPIO_CHAIN_START + 93)
++#define IRQ_GPIOL6 (IRQ_GPIO_CHAIN_START + 94)
++#define IRQ_GPIOL7 (IRQ_GPIO_CHAIN_START + 95)
++#define IRQ_GPIOM0 (IRQ_GPIO_CHAIN_START + 96)
++#define IRQ_GPIOM1 (IRQ_GPIO_CHAIN_START + 97)
++#define IRQ_GPIOM2 (IRQ_GPIO_CHAIN_START + 98)
++#define IRQ_GPIOM3 (IRQ_GPIO_CHAIN_START + 99)
++#define IRQ_GPIOM4 (IRQ_GPIO_CHAIN_START + 100)
++#define IRQ_GPIOM5 (IRQ_GPIO_CHAIN_START + 101)
++#define IRQ_GPIOM6 (IRQ_GPIO_CHAIN_START + 102)
++#define IRQ_GPIOM7 (IRQ_GPIO_CHAIN_START + 103)
++#define IRQ_GPION0 (IRQ_GPIO_CHAIN_START + 104)
++#define IRQ_GPION1 (IRQ_GPIO_CHAIN_START + 105)
++#define IRQ_GPION2 (IRQ_GPIO_CHAIN_START + 106)
++#define IRQ_GPION3 (IRQ_GPIO_CHAIN_START + 107)
++#define IRQ_GPION4 (IRQ_GPIO_CHAIN_START + 108)
++#define IRQ_GPION5 (IRQ_GPIO_CHAIN_START + 109)
++#define IRQ_GPION6 (IRQ_GPIO_CHAIN_START + 110)
++#define IRQ_GPION7 (IRQ_GPIO_CHAIN_START + 111)
++#define IRQ_GPIOO0 (IRQ_GPIO_CHAIN_START + 112)
++#define IRQ_GPIOO1 (IRQ_GPIO_CHAIN_START + 113)
++#define IRQ_GPIOO2 (IRQ_GPIO_CHAIN_START + 114)
++#define IRQ_GPIOO3 (IRQ_GPIO_CHAIN_START + 115)
++#define IRQ_GPIOO4 (IRQ_GPIO_CHAIN_START + 116)
++#define IRQ_GPIOO5 (IRQ_GPIO_CHAIN_START + 117)
++#define IRQ_GPIOO6 (IRQ_GPIO_CHAIN_START + 118)
++#define IRQ_GPIOO7 (IRQ_GPIO_CHAIN_START + 119)
++#define IRQ_GPIOP0 (IRQ_GPIO_CHAIN_START + 120)
++#define IRQ_GPIOP1 (IRQ_GPIO_CHAIN_START + 121)
++#define IRQ_GPIOP2 (IRQ_GPIO_CHAIN_START + 122)
++#define IRQ_GPIOP3 (IRQ_GPIO_CHAIN_START + 123)
++#define IRQ_GPIOP4 (IRQ_GPIO_CHAIN_START + 124)
++#define IRQ_GPIOP5 (IRQ_GPIO_CHAIN_START + 125)
++#define IRQ_GPIOP6 (IRQ_GPIO_CHAIN_START + 126)
++#define IRQ_GPIOP7 (IRQ_GPIO_CHAIN_START + 127)
++#define IRQ_GPIOQ0 (IRQ_GPIO_CHAIN_START + 128)
++#define IRQ_GPIOQ1 (IRQ_GPIO_CHAIN_START + 129)
++#define IRQ_GPIOQ2 (IRQ_GPIO_CHAIN_START + 130)
++#define IRQ_GPIOQ3 (IRQ_GPIO_CHAIN_START + 131)
++#define IRQ_GPIOQ4 (IRQ_GPIO_CHAIN_START + 132)
++#define IRQ_GPIOQ5 (IRQ_GPIO_CHAIN_START + 133)
++#define IRQ_GPIOQ6 (IRQ_GPIO_CHAIN_START + 134)
++#define IRQ_GPIOQ7 (IRQ_GPIO_CHAIN_START + 135)
++#define IRQ_GPIOR0 (IRQ_GPIO_CHAIN_START + 136)
++#define IRQ_GPIOR1 (IRQ_GPIO_CHAIN_START + 137)
++#define IRQ_GPIOR2 (IRQ_GPIO_CHAIN_START + 138)
++#define IRQ_GPIOR3 (IRQ_GPIO_CHAIN_START + 139)
++#define IRQ_GPIOR4 (IRQ_GPIO_CHAIN_START + 140)
++#define IRQ_GPIOR5 (IRQ_GPIO_CHAIN_START + 141)
++#define IRQ_GPIOR6 (IRQ_GPIO_CHAIN_START + 142)
++#define IRQ_GPIOR7 (IRQ_GPIO_CHAIN_START + 143)
++#define IRQ_GPIOS0 (IRQ_GPIO_CHAIN_START + 144)
++#define IRQ_GPIOS1 (IRQ_GPIO_CHAIN_START + 145)
++#define IRQ_GPIOS2 (IRQ_GPIO_CHAIN_START + 146)
++#define IRQ_GPIOS3 (IRQ_GPIO_CHAIN_START + 147)
++#define IRQ_GPIOS4 (IRQ_GPIO_CHAIN_START + 148)
++#define IRQ_GPIOS5 (IRQ_GPIO_CHAIN_START + 149)
++#define IRQ_GPIOS6 (IRQ_GPIO_CHAIN_START + 150)
++#define IRQ_GPIOS7 (IRQ_GPIO_CHAIN_START + 151)
++
++#if defined(CONFIG_ARCH_AST2400) || defined(CONFIG_ARCH_AST1520)
++
++#define IRQ_GPIOT0 (IRQ_GPIO_CHAIN_START + 152)
++#define IRQ_GPIOT1 (IRQ_GPIO_CHAIN_START + 153)
++#define IRQ_GPIOT2 (IRQ_GPIO_CHAIN_START + 154)
++#define IRQ_GPIOT3 (IRQ_GPIO_CHAIN_START + 155)
++#define IRQ_GPIOT4 (IRQ_GPIO_CHAIN_START + 156)
++#define IRQ_GPIOT5 (IRQ_GPIO_CHAIN_START + 157)
++#define IRQ_GPIOT6 (IRQ_GPIO_CHAIN_START + 158)
++#define IRQ_GPIOT7 (IRQ_GPIO_CHAIN_START + 159)
++#define IRQ_GPIOU0 (IRQ_GPIO_CHAIN_START + 161)
++#define IRQ_GPIOU1 (IRQ_GPIO_CHAIN_START + 162)
++#define IRQ_GPIOU2 (IRQ_GPIO_CHAIN_START + 163)
++#define IRQ_GPIOU3 (IRQ_GPIO_CHAIN_START + 164)
++#define IRQ_GPIOU4 (IRQ_GPIO_CHAIN_START + 165)
++#define IRQ_GPIOU5 (IRQ_GPIO_CHAIN_START + 166)
++#define IRQ_GPIOU6 (IRQ_GPIO_CHAIN_START + 167)
++#define IRQ_GPIOU7 (IRQ_GPIO_CHAIN_START + 168)
++#define IRQ_GPIOV0 (IRQ_GPIO_CHAIN_START + 169)
++#define IRQ_GPIOV1 (IRQ_GPIO_CHAIN_START + 170)
++#define IRQ_GPIOV2 (IRQ_GPIO_CHAIN_START + 171)
++#define IRQ_GPIOV3 (IRQ_GPIO_CHAIN_START + 172)
++#define IRQ_GPIOV4 (IRQ_GPIO_CHAIN_START + 173)
++#define IRQ_GPIOV5 (IRQ_GPIO_CHAIN_START + 174)
++#define IRQ_GPIOV6 (IRQ_GPIO_CHAIN_START + 175)
++#define IRQ_GPIOV7 (IRQ_GPIO_CHAIN_START + 176)
++#define IRQ_GPIOW0 (IRQ_GPIO_CHAIN_START + 177)
++#define IRQ_GPIOW1 (IRQ_GPIO_CHAIN_START + 178)
++#define IRQ_GPIOW2 (IRQ_GPIO_CHAIN_START + 179)
++#define IRQ_GPIOW3 (IRQ_GPIO_CHAIN_START + 181)
++#define IRQ_GPIOW4 (IRQ_GPIO_CHAIN_START + 182)
++#define IRQ_GPIOW5 (IRQ_GPIO_CHAIN_START + 183)
++#define IRQ_GPIOW6 (IRQ_GPIO_CHAIN_START + 184)
++#define IRQ_GPIOW7 (IRQ_GPIO_CHAIN_START + 185)
++#define IRQ_GPIOX0 (IRQ_GPIO_CHAIN_START + 186)
++#define IRQ_GPIOX1 (IRQ_GPIO_CHAIN_START + 187)
++#define IRQ_GPIOX2 (IRQ_GPIO_CHAIN_START + 188)
++#define IRQ_GPIOX3 (IRQ_GPIO_CHAIN_START + 189)
++#define IRQ_GPIOX4 (IRQ_GPIO_CHAIN_START + 190)
++#define IRQ_GPIOX5 (IRQ_GPIO_CHAIN_START + 191)
++#define IRQ_GPIOX6 (IRQ_GPIO_CHAIN_START + 192)
++#define IRQ_GPIOX7 (IRQ_GPIO_CHAIN_START + 193)
++#define IRQ_GPIOY0 (IRQ_GPIO_CHAIN_START + 194)
++#define IRQ_GPIOY1 (IRQ_GPIO_CHAIN_START + 195)
++#define IRQ_GPIOY2 (IRQ_GPIO_CHAIN_START + 196)
++#define IRQ_GPIOY3 (IRQ_GPIO_CHAIN_START + 197)
++#define IRQ_GPIOY4 (IRQ_GPIO_CHAIN_START + 198)
++#define IRQ_GPIOY5 (IRQ_GPIO_CHAIN_START + 199)
++#define IRQ_GPIOY6 (IRQ_GPIO_CHAIN_START + 200)
++#define IRQ_GPIOY7 (IRQ_GPIO_CHAIN_START + 201)
++#define IRQ_GPIOZ0 (IRQ_GPIO_CHAIN_START + 202)
++#define IRQ_GPIOZ1 (IRQ_GPIO_CHAIN_START + 203)
++#define IRQ_GPIOZ2 (IRQ_GPIO_CHAIN_START + 204)
++#define IRQ_GPIOZ3 (IRQ_GPIO_CHAIN_START + 205)
++#define IRQ_GPIOZ4 (IRQ_GPIO_CHAIN_START + 206)
++#define IRQ_GPIOZ5 (IRQ_GPIO_CHAIN_START + 207)
++#define IRQ_GPIOZ6 (IRQ_GPIO_CHAIN_START + 208)
++#define IRQ_GPIOZ7 (IRQ_GPIO_CHAIN_START + 209)
++#define IRQ_GPIOAA0 (IRQ_GPIO_CHAIN_START + 210)
++#define IRQ_GPIOAA1 (IRQ_GPIO_CHAIN_START + 211)
++#define IRQ_GPIOAA2 (IRQ_GPIO_CHAIN_START + 212)
++#define IRQ_GPIOAA3 (IRQ_GPIO_CHAIN_START + 213)
++#define IRQ_GPIOAA4 (IRQ_GPIO_CHAIN_START + 214)
++#define IRQ_GPIOAA5 (IRQ_GPIO_CHAIN_START + 215)
++#define IRQ_GPIOAA6 (IRQ_GPIO_CHAIN_START + 216)
++#define IRQ_GPIOAA7 (IRQ_GPIO_CHAIN_START + 217)
++#define IRQ_GPIOBB0 (IRQ_GPIO_CHAIN_START + 218)
++#define IRQ_GPIOBB1 (IRQ_GPIO_CHAIN_START + 219)
++#define IRQ_GPIOBB2 (IRQ_GPIO_CHAIN_START + 220)
++#define IRQ_GPIOBB3 (IRQ_GPIO_CHAIN_START + 221)
++#define IRQ_GPIOBB4 (IRQ_GPIO_CHAIN_START + 222)
++#define IRQ_GPIOBB5 (IRQ_GPIO_CHAIN_START + 223)
++#define IRQ_GPIOBB6 (IRQ_GPIO_CHAIN_START + 224)
++#define IRQ_GPIOBB7 (IRQ_GPIO_CHAIN_START + 225)
++#endif
++
++#endif
+diff --git a/arch/arm/mach-aspeed/include/mach/ast_lcd.h b/arch/arm/mach-aspeed/include/mach/ast_lcd.h
+new file mode 100755
+index 0000000..20963eb
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/ast_lcd.h
+@@ -0,0 +1,61 @@
++ /********************************************************************************
++* File Name : drivers/video/ast_lcd.h
++* Author : Ryan Chen
++* Description : ASPEED LCD Panel Timing
++*
++* Copyright (C) ASPEED Tech. Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/12/27 Ryan Chen create this file
++*
++*
++********************************************************************************/
++#include <linux/fb.h>
++
++//# Define IO __ for control
++#define YUV_MODE 0x4630
++#define CHANGE_YUV_ADDR 0x4631
++#define CHANGE_ADDR 0x4632
++#define OVERSCAN 0x4634
++
++
++enum astfb_color_format {
++ ASTFB_COLOR_RGB565 = 0,
++ ASTFB_COLOR_RGB888,
++ ASTFB_COLOR_YUV444,
++ ASTFB_COLOR_YUV420,
++};
++
++struct aspeed_lcd_panel {
++ struct fb_videomode mode;
++ signed short width; /* width in mm */
++ signed short height; /* height in mm */
++};
++
++struct ast_monitor_info {
++ int status; //0: no data 1:get data
++ int type; //0:dvi 1:hdmi
++ struct fb_monspecs specs;
++ char edid[256];
++};
++
++struct ast_fb_plat_data {
++ u32 (*get_clk)(void);
++};
++
++int ast_vga_get_info(struct fb_info *fb_info);
++int ast_hdmi_get_info(struct fb_info *fb_info);
++void ast_hdmi_enable(int en);
++int vga_read_edid(void);
++
+diff --git a/arch/arm/mach-aspeed/include/mach/ast_lpc_irqs.h b/arch/arm/mach-aspeed/include/mach/ast_lpc_irqs.h
+new file mode 100644
+index 0000000..bbb3878
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/ast_lpc_irqs.h
+@@ -0,0 +1,34 @@
++/*
++ * arch/arm/plat-aspeed/include/plat/gpio_irqs.h
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#ifndef _LPC_IRQS_H_
++#define _LPC_IRQS_H_ 1
++
++#define AST_LPC_IRQ_NUM 7
++
++#define IRQ_KCS0 (IRQ_LPC_CHAIN_START + 0)
++#define IRQ_KCS1 (IRQ_LPC_CHAIN_START + 1)
++#define IRQ_KCS2 (IRQ_LPC_CHAIN_START + 2)
++#define IRQ_KCS3 (IRQ_LPC_CHAIN_START + 3)
++#define IRQ_KCS4 (IRQ_LPC_CHAIN_START + 4)
++#define IRQ_SNOOP0 (IRQ_LPC_CHAIN_START + 5)
++#define IRQ_SNOOP1 (IRQ_LPC_CHAIN_START + 6)
++
++#endif
+diff --git a/arch/arm/mach-aspeed/include/mach/ast_pwm_techo.h b/arch/arm/mach-aspeed/include/mach/ast_pwm_techo.h
+new file mode 100644
+index 0000000..51d4ae3
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/ast_pwm_techo.h
+@@ -0,0 +1,13 @@
++/*
++ * ast_pwm_techo_h
++ *
++ *
++ * 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.
++ */
++struct ast_pwm_driver_data {
++ u32 (*get_pwm_clock)(void);
++};
++
+diff --git a/arch/arm/mach-aspeed/include/mach/ast_spi.h b/arch/arm/mach-aspeed/include/mach/ast_spi.h
+new file mode 100755
+index 0000000..d612967
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/ast_spi.h
+@@ -0,0 +1,14 @@
++/*
++ * ast_spi_h
++ *
++ *
++ * 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.
++ */
++
++struct ast_spi_driver_data {
++ u32 (*get_div)(u32 max_speed_hz);
++ u16 num_chipselect;
++};
+diff --git a/arch/arm/mach-aspeed/include/mach/ast_video.h b/arch/arm/mach-aspeed/include/mach/ast_video.h
+new file mode 100644
+index 0000000..18f9189
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/ast_video.h
+@@ -0,0 +1,89 @@
++ /********************************************************************************
++* File Name : drivers/video/ast_video.h
++* Author : Ryan Chen
++* Description : ASPEED Video Engine
++*
++* Copyright (C) ASPEED Tech. Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/12/27 Ryan Chen create this file
++*
++*
++********************************************************************************/
++typedef enum ast_video_mode {
++ VIDEO_SINGLE_MODE = 0,
++ VIDEO_FRAME_MODE,
++ VIDEO_STREAM_MODE,
++} video_mode;
++
++//VR08[2]
++typedef enum ast_video_source {
++ VIDEO_SOURCE_UNKNOW = 0, //maybe memory .. TODO ...
++ VIDEO_SOURCE_INTERNAL,
++ VIDEO_SOURCE_EXTERNAL,
++} video_source;
++
++//VR08[5]
++typedef enum ast_vga_mode {
++ VIDEO_VGA_DIRECT_MODE = 0,
++ VIDEO_VGA_CAPTURE_MODE,
++} vga_mode;
++
++//VR08[4]
++typedef enum ast_video_dis_en {
++ VIDEO_EXT_DE_SIGNAL = 0,
++ VIDEO_INT_DE_SIGNAL,
++} display_enable;
++
++typedef enum video_compress_format {
++ VIDEO_YUV444 = 0,
++ VIDEO_YUV420,
++} compress_formate;
++
++typedef enum video_color_format {
++ VIDEO_COLOR_RGB565 = 0,
++ VIDEO_COLOR_RGB888,
++ VIDEO_COLOR_YUV444,
++ VIDEO_COLOR_YUV420,
++} color_formate;
++
++typedef enum vga_color_mode {
++ VGA_NO_SIGNAL = 0,
++ EGA_MODE,
++ VGA_MODE,
++ VGA_15BPP_MODE,
++ VGA_16BPP_MODE,
++ VGA_32BPP_MODE,
++} color_mode;
++
++typedef enum video_stage {
++ NONE,
++ POLARITY,
++ RESOLUTION,
++ INIT,
++ RUN,
++} stage;
++
++struct ast_video_plat_data {
++ u32 (*get_clk)(void);
++ void (*ctrl_reset)(void);
++ void (*vga_display)(u8 enable);
++ u32 (*get_vga_base)(void);
++ video_source input_source;
++ video_mode mode;
++ u8 rc4_enable;
++ u8 scaling;
++ compress_formate compress;
++};
++
+diff --git a/arch/arm/mach-aspeed/include/mach/ast_wdt.h b/arch/arm/mach-aspeed/include/mach/ast_wdt.h
+new file mode 100755
+index 0000000..6d7d7f47
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/ast_wdt.h
+@@ -0,0 +1,11 @@
++/*
++ * ast_wdt_h
++ *
++ *
++ * 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.
++ */
++
++ extern void ast_soc_wdt_reset(void);
+diff --git a/arch/arm/mach-aspeed/include/mach/debug-macro.S b/arch/arm/mach-aspeed/include/mach/debug-macro.S
+new file mode 100644
+index 0000000..0b7c927
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/debug-macro.S
+@@ -0,0 +1,22 @@
++/* debug-macro.S
++ *
++ * Debugging macro include header
++ *
++ * 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.
++ *
++*/
++#include <mach/platform.h>
++#include <mach/hardware.h>
++
++ .macro addruart, rx, tmp
++ mrc p15, 0, \rx, c1, c0
++ tst \rx, #1 @ MMU enabled?
++ ldreq \rx, =AST_UART0_BASE
++ ldrne \rx, =IO_ADDRESS(AST_UART0_BASE)
++ orr \rx, \rx, #0x00012000
++ .endm
++
++#define UART_SHIFT 2
++#include <asm/hardware/debug-8250.S>
+diff --git a/arch/arm/mach-aspeed/include/mach/dma.h b/arch/arm/mach-aspeed/include/mach/dma.h
+new file mode 100644
+index 0000000..36c141d
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/dma.h
+@@ -0,0 +1,25 @@
++/*
++ * dma.h
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#ifndef __ASM_ARCH_DMA_H
++#define __ASM_ARCH_DMA_H
++
++#define MAX_DMA_ADDRESS 0xffffffff
++
++#define MAX_DMA_CHANNELS 0
++
++#endif /* _ASM_ARCH_DMA_H */
+diff --git a/arch/arm/mach-aspeed/include/mach/entry-macro.S b/arch/arm/mach-aspeed/include/mach/entry-macro.S
+new file mode 100644
+index 0000000..88b4417
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/entry-macro.S
+@@ -0,0 +1,191 @@
++/*
++ * entry-macro.S
++ *
++ * This file is licensed under the terms of the GNU General Public
++ * License version 2. This program is licensed "as is" without any
++ * warranty of any kind, whether express or implied.
++ */
++#include <mach/hardware.h>
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <plat/regs-intr.h>
++
++ .macro disable_fiq
++ .endm
++
++ .macro get_irqnr_preamble, base, tmp
++ ldr \base, =IO_ADDRESS(AST_VIC_BASE)
++ .endm
++
++ .macro arch_ret_to_user, tmp1, tmp2
++ .endm
++#if 1
++
++#if defined(NEW_VIC)
++ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
++
++ ldr \tmp, =IO_ADDRESS(AST_SCU_BASE)
++ ldr \irqnr, [\tmp, #0x44]
++
++ cmp \irqnr, #0
++ beq 2000f
++
++1000: /* pass1 */
++ cmp \irqnr, #32
++ ble 1001f
++ ldr \tmp, =IO_ADDRESS(AST_VIC_BASE)
++ ldr \irqstat, [\tmp, #0x84]
++ sub \irqnr, \irqnr, #32
++ mov \tmp, #32
++ sub \tmp, \tmp, \irqnr
++ mov \irqstat, \irqstat, lsl \tmp /* mask uncompare parts */
++ mov \irqstat, \irqstat, lsr \tmp
++ mov \irqnr, #63
++ clz \tmp, \irqstat
++ cmp \tmp, #32
++ bne 3000f
++ mov \irqnr, #32
++1001:
++ ldr \tmp, =IO_ADDRESS(AST_VIC_BASE)
++ ldr \irqstat, [\tmp, #0x00]
++ mov \tmp, #32
++ sub \tmp, \tmp, \irqnr
++ mov \irqstat, \irqstat, lsl \tmp /* mask uncompare parts */
++ mov \irqstat, \irqstat, lsr \tmp
++ mov \irqnr, #31
++ clz \tmp, \irqstat
++ cmp \tmp, #32
++ bne 3000f
++
++2000: /* pass 2 */
++ ldr \tmp, =IO_ADDRESS(AST_VIC_BASE)
++ ldr \irqstat, [\tmp, #0x84]
++ mov \irqnr, #63
++ clz \tmp, \irqstat
++ cmp \tmp, #32
++ bne 3000f
++2001:
++ ldr \tmp, =IO_ADDRESS(AST_VIC_BASE)
++ ldr \irqstat, [\tmp, #0x00]
++ mov \irqnr, #31
++ clz \tmp, \irqstat
++ cmp \tmp, #32
++ beq 4000f /* not find */
++
++3000: /* find */
++ sub \irqnr, \irqnr, \tmp
++ ldr \tmp, =IO_ADDRESS(AST_SCU_BASE)
++ str \irqnr, [\tmp, #0x44]
++ cmp \irqnr, #64
++4000: /* done */
++ .endm
++#else
++ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
++/* FIXME: should not be using soo many LDRs here */
++ ldr \irqnr, =IO_ADDRESS(AST_VIC_BASE)
++ ldr \irqstat, [\irqnr, #ASPEED_VIC_STATUS_OFFSET] @ get masked status
++
++ mov \irqnr, #0
++1001: tst \irqstat, #1
++ bne 1002f
++ add \irqnr, \irqnr, #1
++ mov \irqstat, \irqstat, lsr #1
++ cmp \irqnr, #31
++ bcc 1001b
++1002: /* EQ will be set if we reach 31 */
++ .endm
++
++#endif
++#else
++
++ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
++
++ /*********************************************/
++ /* load VIC (VIC1) status value into irqstat */
++ /*********************************************/
++ ldr \irqnr, =IO_ADDRESS(MVP2_VIC_BASE)
++ ldr \irqstat, [\irqnr, #MVP2_VIC_STATUS_OFFSET]
++
++
++ /**********************************************/
++ /* check each status bit and start from bit 0 */
++ /**********************************************/
++ mov \irqnr, #0
++1000: tst \irqstat, #1 /* Check irqstat[irqnr] is 1 or not. */
++ bne 1100f /* If irqstat[irqnr] is 1, service */
++ /* this interrupt. */
++1001:
++ /* check next bit */
++ add \irqnr, \irqnr, #1
++ mov \irqstat, \irqstat, lsr #1
++
++ cmp \irqnr, #32 /* If irqnr is number 32, all bits on VIC1 */
++ beq 1300f /* have been checked and leave this macro. */
++ /* Note that the Zero bit should be 1. */
++
++ bne 1000b /* continue to check next bit */
++
++
++
++1100: ldr \irqstat, =INT_VIC2IRQ /* interrupt from VIC2? */
++ cmp \irqnr, \irqstat
++
++ bne 1300f /* Interupt isn't from VIC2 (i.e. irqnr != INT_VIC2IRQ). */
++ /* Leave this macro with irqnr isn't changed and keep Zero */
++ /* flag not set */
++
++
++ /***************************************/
++ /* load VIC2 status value into irqstat */
++ /***************************************/
++#if 0
++ ldr \irqnr, =IO_ADDRESS(MVP2_VIC2_BASE)
++ ldr \irqstat, [\irqnr, #MVP2_VIC_STATUS_OFFSET]
++#else
++ ldr \irqnr, =IO_ADDRESS(MVP2_VIC_BASE)
++ ldr \irqstat, =0x1000
++ add \irqnr, \irqnr, \irqstat
++ ldr \irqstat, [\irqnr, #MVP2_VIC_STATUS_OFFSET]
++#endif
++
++ /***********************************************/
++ /* Check each status bit and start from bit 0. */
++ /* Note that bit 0 in VIC2 is IRQ number 32. */
++ /***********************************************/
++ mov \irqnr, #32
++1200: tst \irqstat, #1
++ bne 1300f
++
++
++ /* check next bit */
++ add \irqnr, \irqnr, #1
++ mov \irqstat, \irqstat, lsr #1
++
++ cmp \irqnr, #64 /* If irqnr isn't reach 64 */
++ bne 1200b /* continue check irqstat. */
++
++
++
++ /*************************************************************************/
++ /* Examine all the other interrupt bits larger than INT_VIC2IRQ on VIC1. */
++ /*************************************************************************/
++ ldr \irqnr, =IO_ADDRESS(MVP2_VIC_BASE)
++ ldr \irqstat, [\irqnr, #MVP2_VIC_STATUS_OFFSET]
++ mov \irqnr, #INT_VIC2IRQ
++ mov \irqstat, \irqstat, lsr #INT_VIC2IRQ
++ b 1001b
++
++ /* TODO : if needed */
++ /* All interrupt bits on VIC2 have been checked and no bit with value */
++ /* 1 is found. Write 1 to EdgeClearReg[INT_VIC2IRQ] to clear interrupt. */
++
++1300:
++ .endm
++
++#endif
++
++
++
++ .macro irq_prio_table
++ .endm
++
+diff --git a/arch/arm/mach-aspeed/include/mach/ftgmac100_drv.h b/arch/arm/mach-aspeed/include/mach/ftgmac100_drv.h
+new file mode 100644
+index 0000000..40a59e3
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/ftgmac100_drv.h
+@@ -0,0 +1,18 @@
++/*
++ * 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.
++ */
++
++/* store this information for the driver.. */
++
++struct ftgmac100_eth_data
++{
++ unsigned char dev_addr[6]; //MAC address
++ unsigned char phy_addr; //Phy Address
++ unsigned char phy_id; //Phy ID
++ unsigned char DF_support; //Defragment support
++ unsigned long NCSI_support;
++ unsigned long INTEL_NCSI_EVA_support;
++};
+diff --git a/arch/arm/mach-aspeed/include/mach/gpio.h b/arch/arm/mach-aspeed/include/mach/gpio.h
+new file mode 100644
+index 0000000..9ff3863
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/gpio.h
+@@ -0,0 +1,352 @@
++/*
++ * arch/arm/mach-aspeed/include/mach/gpio.h
++ *
++ * Support functions for ASPEED GPIO
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ * Written by Ryan Chen <ryan_chen@aspeedtech.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __ASM_ARCH_ASPEED_GPIO_H
++#define __ASM_ARCH_ASPEED_GPIO_H
++
++#include <linux/kernel.h>
++#include <mach/irqs.h>
++#include <plat/aspeed.h>
++
++/*************************************************************/
++#define GPIO_PORTA 0x0
++#define GPIO_PORTB 0x1
++#define GPIO_PORTC 0x2
++#define GPIO_PORTD 0x3
++#define GPIO_PORTE 0x4
++#define GPIO_PORTF 0x5
++#define GPIO_PORTG 0x6
++#define GPIO_PORTH 0x7
++#define GPIO_PORTI 0x8
++#define GPIO_PORTJ 0x9
++#define GPIO_PORTK 0xa
++#define GPIO_PORTL 0xb
++#define GPIO_PORTM 0xc
++#define GPIO_PORTN 0xd
++#define GPIO_PORTO 0xe
++#define GPIO_PORTP 0xf
++#define GPIO_PORTQ 0x10
++#define GPIO_PORTR 0x11
++#define GPIO_PORTS 0x12
++//AST2300 didn't have PORT TT
++#define GPIO_PORTT 0x13
++#if defined(AST_SOC_G4) || defined(CONFIG_AST2400_BMC)
++#define GPIO_PORTU 0x14
++#define GPIO_PORTV 0x15
++#define GPIO_PORTW 0x16
++#define GPIO_PORTX 0x17
++#define GPIO_PORTY 0x18
++#define GPIO_PORTZ 0x19
++#define GPIO_PORTAA 0x1a
++#define GPIO_PORTAB 0x1b
++#endif
++
++#define GPIO_PER_PORT_PIN_NUM 8
++
++#define GPIO_INPUT_MODE 0
++#define GPIO_OUTPUT_MODE 1
++
++#define GPIO_RISING_EDGE 1
++#define GPIO_FALLING_EDGE 0
++
++#define GPIO_LEVEL_HIGH 1
++#define GPIO_LEVEL_LOW 1
++
++#define GPIO_EDGE_MODE 0
++#define GPIO_LEVEL_MODE 1
++
++#define GPIO_EDGE_LEVEL_MODE 0
++#define GPIO_DUAL_EDGE_MODE 1
++
++#define GPIO_NO_DEBOUNCE 0
++#define GPIO_DEBOUNCE_TIMER0 2 //GPIO 50 as debounce timer
++#define GPIO_DEBOUNCE_TIMER1 1 //GPIO 54 as debounce timer
++#define GPIO_DEBOUNCE_TIMER2 3 //GPIO 58 as debounce timer
++
++#define GPIO_CMD_ARM 0
++#define GPIO_CMD_LPC 1
++#define GPIO_CMD_COPROCESSOR 2
++
++#define PIN_GPIOA0 (0)
++#define PIN_GPIOA1 (1)
++#define PIN_GPIOA2 (2)
++#define PIN_GPIOA3 (3)
++#define PIN_GPIOA4 (4)
++#define PIN_GPIOA5 (5)
++#define PIN_GPIOA6 (6)
++#define PIN_GPIOA7 (7)
++#define PIN_GPIOB0 (8)
++#define PIN_GPIOB1 (9)
++#define PIN_GPIOB2 (10)
++#define PIN_GPIOB3 (11)
++#define PIN_GPIOB4 (12)
++#define PIN_GPIOB5 (13)
++#define PIN_GPIOB6 (14)
++#define PIN_GPIOB7 (15)
++#define PIN_GPIOC0 (16)
++#define PIN_GPIOC1 (17)
++#define PIN_GPIOC2 (18)
++#define PIN_GPIOC3 (19)
++#define PIN_GPIOC4 (20)
++#define PIN_GPIOC5 (21)
++#define PIN_GPIOC6 (22)
++#define PIN_GPIOC7 (23)
++#define PIN_GPIOD0 (24)
++#define PIN_GPIOD1 (25)
++#define PIN_GPIOD2 (26)
++#define PIN_GPIOD3 (27)
++#define PIN_GPIOD4 (28)
++#define PIN_GPIOD5 (29)
++#define PIN_GPIOD6 (30)
++#define PIN_GPIOD7 (31)
++#define PIN_GPIOE0 (32)
++#define PIN_GPIOE1 (33)
++#define PIN_GPIOE2 (34)
++#define PIN_GPIOE3 (35)
++#define PIN_GPIOE4 (36)
++#define PIN_GPIOE5 (37)
++#define PIN_GPIOE6 (38)
++#define PIN_GPIOE7 (39)
++#define PIN_GPIOF0 (40)
++#define PIN_GPIOF1 (41)
++#define PIN_GPIOF2 (42)
++#define PIN_GPIOF3 (43)
++#define PIN_GPIOF4 (44)
++#define PIN_GPIOF5 (45)
++#define PIN_GPIOF6 (46)
++#define PIN_GPIOF7 (47)
++#define PIN_GPIOG0 (48)
++#define PIN_GPIOG1 (49)
++#define PIN_GPIOG2 (50)
++#define PIN_GPIOG3 (51)
++#define PIN_GPIOG4 (52)
++#define PIN_GPIOG5 (53)
++#define PIN_GPIOG6 (54)
++#define PIN_GPIOG7 (55)
++#define PIN_GPIOH0 (56)
++#define PIN_GPIOH1 (57)
++#define PIN_GPIOH2 (58)
++#define PIN_GPIOH3 (59)
++#define PIN_GPIOH4 (60)
++#define PIN_GPIOH5 (61)
++#define PIN_GPIOH6 (62)
++#define PIN_GPIOH7 (63)
++#define PIN_GPIOI0 (64)
++#define PIN_GPIOI1 (65)
++#define PIN_GPIOI2 (66)
++#define PIN_GPIOI3 (67)
++#define PIN_GPIOI4 (68)
++#define PIN_GPIOI5 (69)
++#define PIN_GPIOI6 (70)
++#define PIN_GPIOI7 (71)
++#define PIN_GPIOJ0 (72)
++#define PIN_GPIOJ1 (73)
++#define PIN_GPIOJ2 (74)
++#define PIN_GPIOJ3 (75)
++#define PIN_GPIOJ4 (76)
++#define PIN_GPIOJ5 (77)
++#define PIN_GPIOJ6 (78)
++#define PIN_GPIOJ7 (79)
++#define PIN_GPIOK0 (80)
++#define PIN_GPIOK1 (81)
++#define PIN_GPIOK2 (82)
++#define PIN_GPIOK3 (83)
++#define PIN_GPIOK4 (84)
++#define PIN_GPIOK5 (85)
++#define PIN_GPIOK6 (86)
++#define PIN_GPIOK7 (87)
++#define PIN_GPIOL0 (88)
++#define PIN_GPIOL1 (89)
++#define PIN_GPIOL2 (90)
++#define PIN_GPIOL3 (91)
++#define PIN_GPIOL4 (92)
++#define PIN_GPIOL5 (93)
++#define PIN_GPIOL6 (94)
++#define PIN_GPIOL7 (95)
++#define PIN_GPIOM0 (96)
++#define PIN_GPIOM1 (97)
++#define PIN_GPIOM2 (98)
++#define PIN_GPIOM3 (99)
++#define PIN_GPIOM4 (100)
++#define PIN_GPIOM5 (101)
++#define PIN_GPIOM6 (102)
++#define PIN_GPIOM7 (103)
++#define PIN_GPION0 (104)
++#define PIN_GPION1 (105)
++#define PIN_GPION2 (106)
++#define PIN_GPION3 (107)
++#define PIN_GPION4 (108)
++#define PIN_GPION5 (109)
++#define PIN_GPION6 (110)
++#define PIN_GPION7 (111)
++#define PIN_GPIOO0 (112)
++#define PIN_GPIOO1 (113)
++#define PIN_GPIOO2 (114)
++#define PIN_GPIOO3 (115)
++#define PIN_GPIOO4 (116)
++#define PIN_GPIOO5 (117)
++#define PIN_GPIOO6 (118)
++#define PIN_GPIOO7 (119)
++#define PIN_GPIOP0 (120)
++#define PIN_GPIOP1 (121)
++#define PIN_GPIOP2 (122)
++#define PIN_GPIOP3 (123)
++#define PIN_GPIOP4 (124)
++#define PIN_GPIOP5 (125)
++#define PIN_GPIOP6 (126)
++#define PIN_GPIOP7 (127)
++#define PIN_GPIOQ0 (128)
++#define PIN_GPIOQ1 (129)
++#define PIN_GPIOQ2 (130)
++#define PIN_GPIOQ3 (131)
++#define PIN_GPIOQ4 (132)
++#define PIN_GPIOQ5 (133)
++#define PIN_GPIOQ6 (134)
++#define PIN_GPIOQ7 (135)
++#define PIN_GPIOR0 (136)
++#define PIN_GPIOR1 (137)
++#define PIN_GPIOR2 (138)
++#define PIN_GPIOR3 (139)
++#define PIN_GPIOR4 (140)
++#define PIN_GPIOR5 (141)
++#define PIN_GPIOR6 (142)
++#define PIN_GPIOR7 (143)
++#define PIN_GPIOS0 (144)
++#define PIN_GPIOS1 (145)
++#define PIN_GPIOS2 (146)
++#define PIN_GPIOS3 (147)
++#define PIN_GPIOS4 (148)
++#define PIN_GPIOS5 (149)
++#define PIN_GPIOS6 (150)
++#define PIN_GPIOS7 (151)
++#if defined(AST_SOC_G4) || defined(CONFIG_AST2400_BMC)
++#define PIN_GPIOT0 (152)
++#define PIN_GPIOT1 (153)
++#define PIN_GPIOT2 (154)
++#define PIN_GPIOT3 (155)
++#define PIN_GPIOT4 (156)
++#define PIN_GPIOT5 (157)
++#define PIN_GPIOT6 (158)
++#define PIN_GPIOT7 (159)
++#define PIN_GPIOU0 (161)
++#define PIN_GPIOU1 (162)
++#define PIN_GPIOU2 (163)
++#define PIN_GPIOU3 (164)
++#define PIN_GPIOU4 (165)
++#define PIN_GPIOU5 (166)
++#define PIN_GPIOU6 (167)
++#define PIN_GPIOU7 (168)
++#define PIN_GPIOV0 (169)
++#define PIN_GPIOV1 (170)
++#define PIN_GPIOV2 (171)
++#define PIN_GPIOV3 (172)
++#define PIN_GPIOV4 (173)
++#define PIN_GPIOV5 (174)
++#define PIN_GPIOV6 (175)
++#define PIN_GPIOV7 (176)
++#define PIN_GPIOW0 (177)
++#define PIN_GPIOW1 (178)
++#define PIN_GPIOW2 (179)
++#define PIN_GPIOW3 (181)
++#define PIN_GPIOW4 (182)
++#define PIN_GPIOW5 (183)
++#define PIN_GPIOW6 (184)
++#define PIN_GPIOW7 (185)
++#define PIN_GPIOX0 (186)
++#define PIN_GPIOX1 (187)
++#define PIN_GPIOX2 (188)
++#define PIN_GPIOX3 (189)
++#define PIN_GPIOX4 (190)
++#define PIN_GPIOX5 (191)
++#define PIN_GPIOX6 (192)
++#define PIN_GPIOX7 (193)
++#define PIN_GPIOY0 (194)
++#define PIN_GPIOY1 (195)
++#define PIN_GPIOY2 (196)
++#define PIN_GPIOY3 (197)
++#define PIN_GPIOY4 (198)
++#define PIN_GPIOY5 (199)
++#define PIN_GPIOY6 (200)
++#define PIN_GPIOY7 (201)
++#define PIN_GPIOZ0 (202)
++#define PIN_GPIOZ1 (203)
++#define PIN_GPIOZ2 (204)
++#define PIN_GPIOZ3 (205)
++#define PIN_GPIOZ4 (206)
++#define PIN_GPIOZ5 (207)
++#define PIN_GPIOZ6 (208)
++#define PIN_GPIOZ7 (209)
++#define PIN_GPIOAA0 (210)
++#define PIN_GPIOAA1 (211)
++#define PIN_GPIOAA2 (212)
++#define PIN_GPIOAA3 (213)
++#define PIN_GPIOAA4 (214)
++#define PIN_GPIOAA5 (215)
++#define PIN_GPIOAA6 (216)
++#define PIN_GPIOAA7 (217)
++#define PIN_GPIOBB0 (218)
++#define PIN_GPIOBB1 (219)
++#define PIN_GPIOBB2 (220)
++#define PIN_GPIOBB3 (221)
++#define PIN_GPIOBB4 (222)
++#define PIN_GPIOBB5 (223)
++#define PIN_GPIOBB6 (224)
++#define PIN_GPIOBB7 (225)
++#endif
++/*************************************************************/
++#ifndef __ASSEMBLY__
++
++/* callable at any time */
++extern int ast_set_gpio_value(unsigned gpio_pin, int value);
++extern int ast_get_gpio_value(unsigned gpio_pin);
++
++/*-------------------------------------------------------------------------*/
++
++/* wrappers for "new style" GPIO calls. the old AT91-specfic ones should
++ * eventually be removed (along with this errno.h inclusion), and the
++ * gpio request/free calls should probably be implemented.
++ */
++
++//extern int gpio_direction_input(unsigned gpio);
++//extern int gpio_direction_output(unsigned gpio, int value);
++
++static inline int gpio_get_value(unsigned gpio)
++{
++ return ast_get_gpio_value(gpio);
++}
++
++static inline void gpio_set_value(unsigned gpio, int value)
++{
++ ast_set_gpio_value(gpio, value);
++}
++
++#include <asm-generic/gpio.h> /* cansleep wrappers */
++
++#define gpio_to_irq(gpio) (IRQ_GPIO_CHAIN_START + (gpio))
++#define irq_to_gpio(irq) ((irq) - IRQ_GPIO_CHAIN_START)
++
++#endif /* __ASSEMBLY__ */
++
++
++#endif
+diff --git a/arch/arm/mach-aspeed/include/mach/hardware.h b/arch/arm/mach-aspeed/include/mach/hardware.h
+new file mode 100644
+index 0000000..be3f23d
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/hardware.h
+@@ -0,0 +1,51 @@
++/*
++ * hardware.h
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#ifndef __ASM_ARCH_HARDWARE_H
++#define __ASM_ARCH_HARDWARE_H
++
++#include <mach/platform.h>
++
++/*
++ * Where in virtual memory the IO devices (timers, system controllers
++ * and so on)
++ */
++
++#define IO_BASE 0xF8000000 // VA of IO
++/*#define IO_BASE2 0xE0000000 // VA of IO2 (AST1070) */
++
++#ifdef CONFIG_AST_PCIE_EXT
++#define ASPEED_IO_START2 AST_PCIE_WIN_BASE
++#else
++#define ASPEED_IO_START2 AST_LPC_BRIDGE
++#endif
++
++/* macro to get at IO space when running virtually */
++//#define IO_ADDRESS(x) (((x) >> 4) + IO_BASE)
++/*#define IO_ADDRESS(x) (x - 0x10000000 + IO_BASE) */
++#define IO_ADDRESS(x) (x - 0x1e600000 + IO_BASE)
++/*#define IO_ADDRESS2(x) (x - ASPEED_IO_START2 + IO_BASE2) */
++
++//PCIE
++#ifdef CONFIG_AST_PCIE
++#define PCIBIOS_MIN_IO 0x0
++#define PCIBIOS_MIN_MEM 0x0
++#define pcibios_assign_all_busses() 1
++#endif
++
++#endif /* __ASM_ARCH_HARDWARE_H END */
++
+diff --git a/arch/arm/mach-aspeed/include/mach/io.h b/arch/arm/mach-aspeed/include/mach/io.h
+new file mode 100644
+index 0000000..baf86d2
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/io.h
+@@ -0,0 +1,28 @@
++/*
++ * io.h
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#ifndef __ASM_ARM_ARCH_IO_H
++#define __ASM_ARM_ARCH_IO_H
++
++#include <mach/hardware.h>
++#define IO_SPACE_LIMIT 0xffffffff
++
++#define __io(a) ((void __iomem *)(a))
++#define __mem_pci(a) (a)
++#define __mem_isa(a) (a)
++#endif
++
+diff --git a/arch/arm/mach-aspeed/include/mach/irqs.h b/arch/arm/mach-aspeed/include/mach/irqs.h
+new file mode 100644
+index 0000000..d133251
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/irqs.h
+@@ -0,0 +1,61 @@
++/*
++ * arch/arm/plat-aspeed/include/plat/irqs.h
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#include <plat/aspeed.h>
++
++#if defined(CONFIG_ARCH_AST1010)
++#include <mach/ast1010_irqs.h>
++#elif defined(CONFIG_ARCH_AST1510)
++#include <mach/ast1510_irqs.h>
++#elif defined(CONFIG_ARCH_AST1520)
++#include <mach/ast1520_irqs.h>
++#elif defined(CONFIG_ARCH_AST2000)
++#include <mach/ast2000_irqs.h>
++#elif defined(CONFIG_ARCH_AST2100)
++#include <mach/ast2100_irqs.h>
++#elif defined(CONFIG_ARCH_AST2200)
++#include <mach/ast2200_irqs.h>
++#elif defined(CONFIG_ARCH_AST2300)
++#include <mach/ast2300_irqs.h>
++#elif defined(CONFIG_ARCH_AST2400)
++#include <mach/ast2400_irqs.h>
++#elif defined(CONFIG_ARCH_AST2500)
++#include <mach/ast2500_irqs.h>
++#elif defined(CONFIG_ARCH_AST3100)
++#include <mach/ast3100_irqs.h>
++#elif defined(CONFIG_ARCH_AST3200)
++#include <mach/ast3200_irqs.h>
++#else
++#err "no define for irqs.h"
++#endif
++
++#include <mach/ast_gpio_irqs.h>
++//#include <mach/ast_lpc_irqs.h>
++
++/*********************************************************************************/
++//CVIC
++#if defined(CONFIG_ARCH_AST1070)
++//Companion chip irq
++#include <mach/ast1070_irqs.h>
++#endif
++
++#if defined(CONFIG_AST2400_BMC)
++#include <mach/ext_ast2400_irqs.h>
++#endif
+diff --git a/arch/arm/mach-aspeed/include/mach/memory.h b/arch/arm/mach-aspeed/include/mach/memory.h
+new file mode 100644
+index 0000000..d9927b2
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/memory.h
+@@ -0,0 +1,48 @@
++/*
++ * memory.h
++ *
++ * 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 <mach/platform.h>
++#include <plat/aspeed.h>
++
++#ifndef __ASM_ARCH_MEMORY_H
++#define __ASM_ARCH_MEMORY_H
++
++/*
++ * Physical DRAM offset.
++ */
++#if defined(AST_SOC_G3) || defined(AST_SOC_G4)
++#define PHYS_OFFSET UL(0x40000000)
++#define BUS_OFFSET UL(0x40000000)
++#elif defined(AST_SOC_G5)
++#define PHYS_OFFSET UL(0x80000000)
++#define BUS_OFFSET UL(0x80000000)
++#else
++#define PHYS_OFFSET UL(0x40000000)
++#define BUS_OFFSET UL(0x40000000)
++#endif
++
++/*
++ * Virtual view <-> DMA view memory address translations
++ * virt_to_bus: Used to translate the virtual address to an
++ * address suitable to be passed to set_dma_addr
++ * bus_to_virt: Used to convert an address for DMA operations
++ * to an address that the kernel can use.
++ */
++#define __virt_to_bus(x) (x - PAGE_OFFSET + BUS_OFFSET)
++#define __bus_to_virt(x) (x - BUS_OFFSET + PAGE_OFFSET)
++
++#endif
+diff --git a/arch/arm/mach-aspeed/include/mach/platform.h b/arch/arm/mach-aspeed/include/mach/platform.h
+new file mode 100644
+index 0000000..8951ffc
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/platform.h
+@@ -0,0 +1,66 @@
++/*
++ * 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 _AST_PLATFORM_H_
++#define _AST_PLATFORM_H_ 1
++
++#define AST_PLL_25MHZ 25000000
++#define AST_PLL_24MHZ 24000000
++#define AST_PLL_12MHZ 12000000
++
++#define AST_IO_START 0x1E600000
++#define AST_IO_SIZE 0x00200000
++
++/*********************************************************************************/
++#if defined(CONFIG_ARCH_AST1520)
++#include <mach/ast1520_platform.h>
++#elif defined(CONFIG_ARCH_AST2000)
++#include <mach/ast2000_platform.h>
++#elif defined(CONFIG_ARCH_AST2100)
++#include <mach/ast2100_platform.h>
++#elif defined(CONFIG_ARCH_AST2200)
++#include <mach/ast2200_platform.h>
++#elif defined(CONFIG_ARCH_AST2300)
++#include <mach/ast2300_platform.h>
++#elif defined(CONFIG_ARCH_AST2400)
++#include <mach/ast2400_platform.h>
++#elif defined(CONFIG_ARCH_AST2500)
++#include <mach/ast2500_platform.h>
++#elif defined(CONFIG_ARCH_AST3200)
++#include <mach/ast3200_platform.h>
++#else
++#err "No define for platform.h"
++#endif
++/*********************************************************************************/
++/* Companion Base Address */
++#if defined(CONFIG_ARCH_AST1070)
++#include <mach/ast1070_platform.h>
++#endif
++/*********************************************************************************/
++#define AST_CS0_DEF_BASE 0x20000000 /* CS0 */
++#define AST_CS1_DEF_BASE 0x24000000 /* CS1 */
++#define AST_CS2_DEF_BASE 0x26000000 /* CS2 */
++#define AST_CS3_DEF_BASE 0x28000000 /* CS3 */
++#define AST_CS4_DEF_BASE 0x2a000000 /* CS4 */
++
++#define AST_NOR_SIZE 0x01000000 /* AST2300 NOR size 16MB */
++
++/*
++ * Watchdog
++ */
++#define AST_WDT_VA_BASE (IO_ADDRESS(AST_WDT_BASE))
++
++#endif
+diff --git a/arch/arm/mach-aspeed/include/mach/system.h b/arch/arm/mach-aspeed/include/mach/system.h
+new file mode 100644
+index 0000000..96e90da
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/system.h
+@@ -0,0 +1,44 @@
++/*
++ * system.h
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#ifndef __ASM_ARCH_SYSTEM_H
++#define __ASM_ARCH_SYSTEM_H
++
++#include <mach/hardware.h>
++#include <asm/io.h>
++#include <mach/ast_wdt.h>
++
++static inline void arch_idle(void)
++{
++ /*
++ * This should do all the clock switching
++ * and wait for interrupt tricks
++ */
++ cpu_do_idle();
++}
++
++static inline void arch_reset(char mode)
++{
++ /*
++ * Use WDT to restart system
++ */
++#if defined(CONFIG_AST_WATCHDOG) || defined(CONFIG_AST_WATCHDOG_MODULE)
++ ast_soc_wdt_reset();
++#endif
++}
++
++#endif
+diff --git a/arch/arm/mach-aspeed/include/mach/time.h b/arch/arm/mach-aspeed/include/mach/time.h
+new file mode 100644
+index 0000000..973a0b0
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/time.h
+@@ -0,0 +1,73 @@
++/*
++ * time.h
++ *
++ * 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 <asm/system.h>
++#include <asm/mach/time.h>
++#include <asm/param.h>
++
++/*
++ * How long is the timer interval?
++ */
++#define TIMER_INTERVAL (ASPEED_TIMER_CLKRATE / HZ)
++#define TIMER_RELOAD (TIMER_INTERVAL)
++#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
++
++/*
++ * Timer
++ */
++#define ASPEED_TIMER0_OFFSET 0x0000 /* Timer0 Offset */
++#define ASPEED_TIMER1_OFFSET 0x0010 /* Timer1 Offset */
++#define ASPEED_TIMER2_OFFSET 0x0020 /* Timer2 Offset */
++#define ASPEED_TIMERRC_OFFSET 0x0030 /* Timer RC Offset */
++
++#define ASPEED_TIMER_CLKRATE (ASPEED_EXTCLK)
++#define ASPEED_EXTCLK (1*1000*1000) /* 1M */
++
++/*
++ * Ticks
++ */
++//#define TICKS_PER_uSEC 40 // IP Cam
++//#define TICKS_PER_uSEC 24 // FPGA
++#define TICKS_PER_uSEC 1 /* ASPEED_EXTCLK / 10 ^ 6 */
++
++#define mSEC_1 1000
++#define mSEC_5 (mSEC_1 * 5)
++#define mSEC_10 (mSEC_1 * 10)
++#define mSEC_25 (mSEC_1 * 25)
++#define SEC_1 (mSEC_1 * 1000)
++
++/*
++ * Timer Control
++ */
++#define TIMER0_ENABLE 0x0001
++#define TIMER1_ENABLE 0x0010
++#define TIMER2_ENABLE 0x0100
++
++#define TIMER0_RefExt 0x0002
++#define TIMER1_RefExt 0x0020
++#define TIMER2_RefExt 0x0200
++
++/*
++ * What does it look like?
++ */
++typedef struct TimerStruct {
++ unsigned long TimerValue;
++ unsigned long TimerLoad;
++ unsigned long TimerMatch1;
++ unsigned long TimerMatch2;
++} TimerStruct_t;
++
+diff --git a/arch/arm/mach-aspeed/include/mach/timex.h b/arch/arm/mach-aspeed/include/mach/timex.h
+new file mode 100644
+index 0000000..e907a30
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/timex.h
+@@ -0,0 +1,21 @@
++/*
++ * timex.h
++ *
++ * Integrator architecture timex specifications
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#define CLOCK_TICK_RATE (50000000 / 16)
+diff --git a/arch/arm/mach-aspeed/include/mach/uncompress.h b/arch/arm/mach-aspeed/include/mach/uncompress.h
+new file mode 100644
+index 0000000..896b854
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/uncompress.h
+@@ -0,0 +1,38 @@
++/*
++ * uncompress.h
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef __ASM_ARCH_UNCOMPRESS_H
++#define __ASM_ARCH_UNCOMPRESS_H
++
++#include <mach/platform.h>
++#include <mach/aspeed_serial.h>
++
++#define UART_PUT_CHAR (*(volatile unsigned char *)(AST_UART0_BASE + UART_THR))
++#define UART_GET_LSR (*(volatile unsigned char *)(AST_UART0_BASE + UART_LSR))
++
++static void putc(int c)
++{
++
++ /* wait for space in the UART's transmitter */
++ while (!(UART_GET_LSR & UART_LSR_THRE))
++ barrier();
++
++ /* send the character out. */
++ UART_PUT_CHAR = c;
++}
++
++static inline void flush(void)
++{
++ while (UART_GET_LSR & (1 << 3))
++ barrier();
++}
++
++#define arch_decomp_setup()
++#define arch_decomp_wdog()
++
++#endif /* __ASM_ARCH_UNCOMPRESS_H */
+diff --git a/arch/arm/mach-aspeed/include/mach/vmalloc.h b/arch/arm/mach-aspeed/include/mach/vmalloc.h
+new file mode 100644
+index 0000000..3706cf1
+--- /dev/null
++++ b/arch/arm/mach-aspeed/include/mach/vmalloc.h
+@@ -0,0 +1,29 @@
++/*
++ * vmalloc.h
++ *
++ * 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
++ */
++
++/*
++ * Just any arbitrary offset to the start of the vmalloc VM area: the
++ * current 8MB value just means that there will be a 8MB "hole" after the
++ * physical memory until the kernel virtual memory starts. That means that
++ * any out-of-bounds memory accesses will hopefully be caught.
++ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
++ * area for the same reason. ;)
++ */
++#if 0
++#define VMALLOC_OFFSET (8*1024*1024)
++#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
++#define VMALLOC_VMADDR(x) ((unsigned long)(x))
++#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
++#else
++#define VMALLOC_END 0xf8000000UL
++#endif
+\ No newline at end of file
+diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
+index ab5f7a2..d7b499a 100644
+--- a/arch/arm/mm/Kconfig
++++ b/arch/arm/mm/Kconfig
+@@ -180,7 +180,7 @@ config CPU_ARM925T
+ # ARM926T
+ config CPU_ARM926T
+ bool "Support ARM926T processor"
+- depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || \
++ depends on ARCH_ASPEED || ARCH_INTEGRATOR || ARCH_VERSATILE_PB || \
+ MACH_VERSATILE_AB || ARCH_OMAP730 || \
+ ARCH_OMAP16XX || MACH_REALVIEW_EB || \
+ ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || \
+@@ -188,7 +188,7 @@ config CPU_ARM926T
+ ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || \
+ ARCH_AT91SAM9G20 || ARCH_AT91CAP9 || \
+ ARCH_NS9XXX || ARCH_DAVINCI || ARCH_MX2
+- default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || \
++ default y if ARCH_ASPEED || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || \
+ ARCH_OMAP730 || ARCH_OMAP16XX || \
+ ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || \
+ ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || \
+diff --git a/arch/arm/plat-aspeed/Makefile b/arch/arm/plat-aspeed/Makefile
+new file mode 100644
+index 0000000..faba830
+--- /dev/null
++++ b/arch/arm/plat-aspeed/Makefile
+@@ -0,0 +1,35 @@
++#
++# Makefile for the linux kernel.
++#
++
++obj-y += irq.o timer.o devs.o ast-scu.o ast-sdmc.o
++
++obj-$(CONFIG_ARCH_AST1070) += ast1070_irq.o ast1070-scu.o ast1070-uart-dma.o dev-ci2c.o dev-cuart.o dev-clpc.o
++
++obj-$(CONFIG_AST_I2C_SLAVE_MODE) += i2c-slave-eeprom.o
++
++obj-$(CONFIG_AST2400_BMC) += ast2400-irq.o ast2400-scu.o dev-ast2400-uart.o #dev-ast2400-i2c.o
++
++#obj-n := dummy.o
++#platform
++obj-y += dev-uart.o dev-vuart.o dev-wdt.o dev-rtc.o dev-gpio.o dev-sgpio.o
++
++#Storage
++obj-y += dev-nor.o dev-nand.o dev-sdhci.o
++
++#bus
++obj-y += dev-i2c.o dev-spi.o dev-ehci.o dev-uhci.o dev-lpc.o dev-peci.o dev-kcs.o dev-mbx.o dev-snoop.o
++
++#dev
++#obj-y += dev-udc11.o
++#net
++obj-y += dev-eth.o
++
++#hwmon
++obj-y += dev-pwm-fan.o dev-adc.o
++
++#video
++obj-y += dev-fb.o dev-video.o
++#obj-m :=
++#obj-n :=
++#obj- :=
+diff --git a/arch/arm/plat-aspeed/ast-scu.c b/arch/arm/plat-aspeed/ast-scu.c
+new file mode 100644
+index 0000000..1f1dde2
+--- /dev/null
++++ b/arch/arm/plat-aspeed/ast-scu.c
+@@ -0,0 +1,1202 @@
++/********************************************************************************
++* File Name : arch/arm/plat-aspeed/ast-scu.c
++* Author : Ryan Chen
++* Description : AST SCU
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++CLK24M
++ |
++ |--> H-PLL -->HCLK
++ |
++ |--> M-PLL -xx->MCLK
++ |
++ |--> V-PLL1 -xx->DCLK
++ |
++ |--> V-PLL2 -xx->D2CLK
++ |
++ |--> USB2PHY -->UTMICLK
++
++
++* History :
++* 1. 2012/08/15 Ryan Chen Create
++*
++********************************************************************************/
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/delay.h>
++
++#include <mach/platform.h>
++#include <asm/io.h>
++
++#include <mach/hardware.h>
++
++#include <plat/ast-scu.h>
++#include <plat/regs-scu.h>
++
++//#define ASPEED_SCU_LOCK
++//#define ASPEED_SCU_DEBUG
++
++#ifdef ASPEED_SCU_DEBUG
++#define SCUDBUG(fmt, args...) printk("%s() " fmt, __FUNCTION__, ## args)
++#else
++#define SCUDBUG(fmt, args...)
++#endif
++
++#define SCUMSG(fmt, args...) printk(fmt, ## args)
++
++static u32 ast_scu_base = IO_ADDRESS(AST_SCU_BASE);
++
++static inline u32
++ast_scu_read(u32 reg)
++{
++ u32 val;
++
++ val = readl(ast_scu_base + reg);
++
++ SCUDBUG("ast_scu_read : reg = 0x%08x, val = 0x%08x\n", reg, val);
++
++ return val;
++}
++
++static inline void
++ast_scu_write(u32 val, u32 reg)
++{
++ SCUDBUG("ast_scu_write : reg = 0x%08x, val = 0x%08x\n", reg, val);
++#ifdef CONFIG_AST_SCU_LOCK
++ //unlock
++ writel(SCU_PROTECT_UNLOCK, ast_scu_base);
++ writel(val, ast_scu_base + reg);
++ //lock
++ writel(0xaa,ast_scu_base);
++#else
++ writel(val, ast_scu_base + reg);
++#endif
++}
++
++//SoC mapping Table
++struct soc_id {
++ const char * name;
++ u32 rev_id;
++};
++
++static struct soc_id soc_map_table[] = {
++ [0] = {
++ .name = "AST1100/AST2050-A0",
++ .rev_id = 0x00000200,
++ },
++ [1] = {
++ .name = "AST1100/AST2050-A1",
++ .rev_id = 0x00000201,
++ },
++ [2] = {
++ .name = "AST1100/AST2050-A2,3/AST2150-A0,1",
++ .rev_id = 0x00000202,
++ },
++ [3] = {
++ .name = "AST1510/AST2100-A0",
++ .rev_id = 0x00000300,
++ },
++ [4] = {
++ .name = "AST1510/AST2100-A1",
++ .rev_id = 0x00000301,
++ },
++ [5] = {
++ .name = "AST1510/AST2100-A2,3",
++ .rev_id = 0x00000302,
++ },
++ [6] = {
++ .name = "AST2200-A0,1",
++ .rev_id = 0x00000102,
++ },
++ [7] = {
++ .name = "AST2300-A0",
++ .rev_id = 0x01000003,
++ },
++ [8] = {
++ .name = "AST2300-A1",
++ .rev_id = 0x01010303,
++ },
++ [9] = {
++ .name = "AST1300-A1",
++ .rev_id = 0x01010003,
++ },
++ [10] = {
++ .name = "AST1050-A1",
++ .rev_id = 0x01010203,
++ },
++ [11] = {
++ .name = "AST2400-A0",
++ .rev_id = 0x02000303,
++ },
++ [12] = {
++ .name = "AST2400-A1",
++ .rev_id = 0x02010303,
++ },
++ [13] = {
++ .name = "AST1010-A0",
++ .rev_id = 0x03000003,
++ },
++ [14] = {
++ .name = "AST1010-A1",
++ .rev_id = 0x03010003,
++ },
++ [15] = {
++ .name = "AST1520-A0",
++ .rev_id = 0x03000003,
++ },
++ [16] = {
++ .name = "AST3200-A0",
++ .rev_id = 0x03000003,
++ },
++};
++
++//***********************************Initial control***********************************
++extern void
++ast_scu_reset_video(void)
++{
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_VIDEO, AST_SCU_RESET);
++ udelay(100);
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_VIDEO, AST_SCU_RESET);
++}
++
++EXPORT_SYMBOL(ast_scu_reset_video);
++
++extern void
++ast_scu_init_video(u8 dynamic_en)
++{
++ //Video Engine Clock Enable and Reset
++ // Enable Clock & ECLK = inverse of (M-PLL / 2)
++ if(dynamic_en)
++ ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_CLK_VIDEO_SLOW_MASK) | SCU_CLK_VIDEO_SLOW_EN | SCU_CLK_VIDEO_SLOW_SET(0), AST_SCU_CLK_SEL);
++ else
++ ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_ECLK_SOURCE_MASK) | SCU_ECLK_SOURCE(2), AST_SCU_CLK_SEL);
++
++ // Enable CLK
++ ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~(SCU_ECLK_STOP_EN | SCU_VCLK_STOP_EN), AST_SCU_CLK_STOP);
++ mdelay(10);
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_VIDEO, AST_SCU_RESET);
++ udelay(100);
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_VIDEO, AST_SCU_RESET);
++}
++
++EXPORT_SYMBOL(ast_scu_init_video);
++
++extern void
++ast_scu_init_eth(u8 num)
++{
++ //AST2300 max clk to 125Mhz, AST2400 max clk to 198Mhz
++ if(ast_scu_read(AST_SCU_HW_STRAP1) && (SCU_HW_STRAP_MAC1_RGMII | SCU_HW_STRAP_MAC0_RGMII)) //RGMII --> H-PLL/6
++ ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_CLK_MAC_MASK) | SCU_CLK_MAC_DIV(2), AST_SCU_CLK_SEL);
++ else //RMII --> H-PLL/10
++ ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_CLK_MAC_MASK) | SCU_CLK_MAC_DIV(4), AST_SCU_CLK_SEL);
++
++ //Set MAC delay Timing
++ ast_scu_write(0x2255, AST_SCU_MAC_CLK);
++
++ switch(num) {
++ case 0:
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_MAC0,
++ AST_SCU_RESET);
++ udelay(100);
++ ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~SCU_MAC0CLK_STOP_EN,
++ AST_SCU_CLK_STOP);
++ udelay(1000);
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_MAC0,
++ AST_SCU_RESET);
++
++ break;
++ case 1:
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_MAC1,
++ AST_SCU_RESET);
++ udelay(100);
++ ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~SCU_MAC1CLK_STOP_EN,
++ AST_SCU_CLK_STOP);
++ udelay(1000);
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_MAC1,
++ AST_SCU_RESET);
++ break;
++
++ }
++}
++
++
++extern void
++ast_scu_init_usb20(void)
++{
++ /* EHCI controller engine init. Process similar to VHub. */
++ /* Following reset sequence can resolve "vhub dead on first power on" issue on V4 board. */
++ //reset USB20
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_USB20, AST_SCU_RESET);
++
++ //enable USB20 clock
++ ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) | SCU_USB20_CLK_EN, AST_SCU_CLK_STOP);
++ mdelay(10);
++
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_USB20, AST_SCU_RESET);
++
++ udelay(500);
++
++// printk("%x \n",ast_scu_read(AST_SCU_RESET));
++
++
++}
++
++EXPORT_SYMBOL(ast_scu_init_usb20);
++
++extern void
++ast_scu_init_uhci(void)
++{
++ //USB1.1 Host's Clock Enable and Reset
++ ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~SCU_USB11CLK_STOP_EN, AST_SCU_CLK_STOP);
++ mdelay(10);
++
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_USB11, AST_SCU_RESET);
++}
++
++EXPORT_SYMBOL(ast_scu_init_uhci);
++
++extern void
++ast_scu_init_udc11(void)
++{
++ //USB1.1 device Clock Enable and Reset
++ ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~SCU_UCLK_STOP_EN, AST_SCU_CLK_STOP);
++ mdelay(10);
++
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_USB11_HID, AST_SCU_RESET);
++}
++
++EXPORT_SYMBOL(ast_scu_init_udc11);
++
++///
++extern void
++ast_scu_init_sdhci(void)
++{
++ //SDHCI Host's Clock Enable and Reset
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_SD, AST_SCU_RESET);
++
++ ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~SCU_SDCLK_STOP_EN, AST_SCU_CLK_STOP);
++ mdelay(10);
++
++ ast_scu_write(ast_scu_read(AST_SCU_CLK_SEL) | SCU_CLK_SD_EN, AST_SCU_CLK_SEL);
++ mdelay(10);
++
++ // SDCLK = H-PLL / 4
++ ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_CLK_SD_MASK) | SCU_CLK_SD_DIV(1),
++ AST_SCU_CLK_SEL);
++ mdelay(10);
++
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_SD, AST_SCU_RESET);
++}
++
++EXPORT_SYMBOL(ast_scu_init_sdhci);
++
++extern void
++ast_scu_init_i2c(void)
++{
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_I2C, AST_SCU_RESET);
++}
++
++EXPORT_SYMBOL(ast_scu_init_i2c);
++
++extern void
++ast_scu_init_pwm_tacho(void)
++{
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_PWM, AST_SCU_RESET);
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_PWM, AST_SCU_RESET);
++}
++
++EXPORT_SYMBOL(ast_scu_init_pwm_tacho);
++
++extern void
++ast_scu_init_adc(void)
++{
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_ADC, AST_SCU_RESET);
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_ADC, AST_SCU_RESET);
++}
++
++EXPORT_SYMBOL(ast_scu_init_adc);
++
++extern void
++ast_scu_init_peci(void)
++{
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_PECI, AST_SCU_RESET);
++ udelay(3);
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_PECI, AST_SCU_RESET);
++}
++
++EXPORT_SYMBOL(ast_scu_init_peci);
++
++extern void
++ast_scu_init_jtag(void)
++{
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_JTAG, AST_SCU_RESET);
++ udelay(3);
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_JTAG, AST_SCU_RESET);
++}
++
++EXPORT_SYMBOL(ast_scu_init_jtag);
++
++extern void
++ast_scu_init_lpc(void)
++{
++ //Note .. It have been enable in U-boot.....
++// ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_LPC, AST_SCU_RESET);
++
++ //enable LPC clock LHCLK = H-PLL/8
++ ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) |
++ SCU_SET_LHCLK_DIV(3) |
++ SCU_LHCLK_SOURCE_EN,
++ AST_SCU_CLK_STOP);
++
++}
++
++EXPORT_SYMBOL(ast_scu_init_lpc);
++
++//////1 : lpc plus modes
++extern u8
++ast_scu_get_lpc_plus_enable(void)
++{
++ if(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & SCU_FUN_PIN_LPC_PLUS)
++ return 1;
++ else
++ return 0;
++}
++
++EXPORT_SYMBOL(ast_scu_get_lpc_plus_enable);
++
++extern void
++ast_scu_init_crt(void)
++{
++ //enable D2 pll , //enable DVO (bit18) is VGA , enable DAC (bit16) is CRT
++#if defined(CONFIG_AST_DAC) || defined(CONFIG_AST_DVO)
++ ast_scu_write((ast_scu_read(AST_SCU_MISC1_CTRL) & ~(SCU_MISC_D2_PLL_DIS | SCU_MISC_DAC_MASK))
++ | SCU_MISC_DAC_SOURCE_CRT | SCU_MISC_DVO_SOURCE_CRT | SCU_MISC_2D_CRT_EN , AST_SCU_MISC1_CTRL);
++#elif defined(CONFIG_AST_DVO)
++ ast_scu_write((ast_scu_read(AST_SCU_MISC1_CTRL) & ~(SCU_MISC_D2_PLL_DIS)) |
++ SCU_MISC_DVO_SOURCE_CRT| SCU_MISC_2D_CRT_EN, AST_SCU_MISC1_CTRL);
++#else //default(CONFIG_AST_DAC)
++ ast_scu_write((ast_scu_read(AST_SCU_MISC1_CTRL) & ~(SCU_MISC_D2_PLL_DIS | SCU_MISC_DAC_MASK))
++ | SCU_MISC_DAC_SOURCE_CRT | SCU_MISC_2D_CRT_EN, AST_SCU_MISC1_CTRL);
++#endif
++ /* Set Delay 5 Compensation TODO ...*/
++ ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_CLK_VIDEO_DELAY_MASK) |
++ SCU_CLK_VIDEO_DELAY(5), AST_SCU_CLK_SEL);
++
++ /* Reset CRT */
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_CRT, AST_SCU_RESET);
++
++ //enable D2 CLK
++ ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~SCU_D2CLK_STOP_EN , AST_SCU_CLK_STOP);
++
++ udelay(10);
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_CRT, AST_SCU_RESET);
++
++}
++
++EXPORT_SYMBOL(ast_scu_init_crt);
++//***********************************CLK control***********************************
++extern void
++ast_scu_clk_stop(u32 clk_name,u8 stop_enable)
++{
++ switch(clk_name){
++ default:
++ SCUMSG("ERRO clk_name :%d \n",clk_name);
++ break;
++ }
++}
++
++EXPORT_SYMBOL(ast_scu_clk_stop);
++
++
++//***********************************CLK Information***********************************
++extern u32
++ast_get_clk_source(void)
++{
++ if(ast_scu_read(AST_SCU_HW_STRAP1) & CLK_25M_IN)
++ return AST_PLL_25MHZ;
++ else
++ return AST_PLL_24MHZ;
++}
++
++EXPORT_SYMBOL(ast_get_clk_source);
++
++
++extern u32
++ast_get_h_pll_clk(void)
++{
++ u32 speed,clk=0;
++ u32 h_pll_set = ast_scu_read(AST_SCU_H_PLL);
++
++ if(h_pll_set & SCU_H_PLL_OFF)
++ return 0;
++
++ if(h_pll_set & SCU_H_PLL_PARAMETER) {
++ // Programming
++ clk = ast_get_clk_source();
++ if(h_pll_set & SCU_H_PLL_BYPASS_EN) {
++ return clk;
++ } else {
++ //OD == SCU24[4]
++ //OD = SCU_H_PLL_GET_DIV(h_pll_set);
++ //Numerator == SCU24[10:5]
++ //num = SCU_H_PLL_GET_NUM(h_pll_set);
++ //Denumerator == SCU24[3:0]
++ //denum = SCU_H_PLL_GET_DENUM(h_pll_set);
++
++ //hpll = 24MHz * (2-OD) * ((Numerator+2)/(Denumerator+1))
++ clk = ((clk * (2-SCU_H_PLL_GET_DIV(h_pll_set)) * (SCU_H_PLL_GET_NUM(h_pll_set)+2))/(SCU_H_PLL_GET_DENUM(h_pll_set)+1));
++ }
++ } else {
++ // HW Trap
++ speed = SCU_HW_STRAP_GET_H_PLL_CLK(ast_scu_read(AST_SCU_HW_STRAP1));
++ switch (speed) {
++ case 0:
++ clk = 384000000;
++ break;
++ case 1:
++ clk = 360000000;
++ break;
++ case 2:
++ clk = 336000000;
++ break;
++ case 3:
++ clk = 408000000;
++ break;
++ default:
++ BUG();
++ break;
++ }
++ }
++ SCUDBUG("h_pll = %d\n",clk);
++ return clk;
++}
++
++EXPORT_SYMBOL(ast_get_h_pll_clk);
++
++extern u32
++ast_get_m_pll_clk(void)
++{
++ u32 clk=0;
++ u32 m_pll_set = ast_scu_read(AST_SCU_M_PLL);
++
++ if(m_pll_set & SCU_M_PLL_OFF)
++ return 0;
++
++ // Programming
++ clk = ast_get_clk_source();
++ if(m_pll_set & SCU_M_PLL_BYPASS_EN) {
++ return clk;
++ } else {
++ //OD == SCU24[4]
++ //OD = SCU_M_PLL_GET_DIV(h_pll_set);
++ //Numerator == SCU24[10:5]
++ //num = SCU_M_PLL_GET_NUM(h_pll_set);
++ //Denumerator == SCU24[3:0]
++ //denum = SCU_M_PLL_GET_DENUM(h_pll_set);
++
++ //hpll = 24MHz * (2-OD) * ((Numerator+2)/(Denumerator+1))
++ clk = (clk * (2-SCU_M_PLL_GET_DIV(m_pll_set)) * ((SCU_M_PLL_GET_NUM(m_pll_set)+2)/(SCU_M_PLL_GET_DENUM(m_pll_set)+1)));
++ }
++ SCUDBUG("m_pll = %d\n",clk);
++ return clk;
++}
++
++EXPORT_SYMBOL(ast_get_m_pll_clk);
++
++extern u32
++ast_get_ahbclk(void)
++{
++ unsigned int div, hpll;
++
++ hpll = ast_get_h_pll_clk();
++ div = SCU_HW_STRAP_GET_CPU_AHB_RATIO(ast_scu_read(AST_SCU_HW_STRAP1));
++ switch(div) {
++ case 0:
++ div = 1;
++ break;
++ case 1:
++ div = 2;
++ break;
++ case 2:
++ div = 3;
++ break;
++ case 3:
++ div = 4;
++ break;
++
++ }
++
++ SCUDBUG("HPLL=%d, Div=%d, AHB CLK=%d\n", hpll, div, hpll/div);
++ return (hpll/div);
++
++}
++EXPORT_SYMBOL(ast_get_ahbclk);
++
++extern u32
++ast_get_pclk(void)
++{
++ unsigned int div, hpll;
++
++ hpll = ast_get_h_pll_clk();
++ div = SCU_GET_PCLK_DIV(ast_scu_read(AST_SCU_CLK_SEL));
++ div = (div+1) << 1;
++
++ SCUDBUG("HPLL=%d, Div=%d, PCLK=%d\n", hpll, div, hpll/div);
++ return (hpll/div);
++
++}
++EXPORT_SYMBOL(ast_get_pclk);
++
++extern u32
++ast_get_lhclk(void)
++{
++ unsigned int div, hpll;
++ u32 clk_sel = ast_scu_read(AST_SCU_CLK_SEL);
++//FPGA AST1070 is default 100/2 Mhz input
++// return 50000000;
++ hpll = ast_get_h_pll_clk();
++ if(SCU_LHCLK_SOURCE_EN & clk_sel) {
++ div = SCU_GET_LHCLK_DIV(clk_sel);
++ switch(div) {
++ case 0:
++ div = 2;
++ break;
++ case 1:
++ div = 4;
++ break;
++ case 2:
++ div = 6;
++ break;
++ case 3:
++ div = 8;
++ break;
++ case 4:
++ div = 10;
++ break;
++ case 5:
++ div = 12;
++ break;
++ case 6:
++ div = 14;
++ break;
++ case 7:
++ div = 16;
++ break;
++ }
++
++ SCUDBUG("HPLL=%d, Div=%d, LHCLK = %d\n", hpll, div, hpll/div);
++ return (hpll/div);
++ } else {
++ SCUMSG("LPC CLK not enable \n");
++ return 0;
++ }
++
++}
++
++EXPORT_SYMBOL(ast_get_lhclk);
++
++extern u32
++ast_get_d2_pll_clk(void)
++{
++ u32 clk=0;
++ u32 d2_pll_set = ast_scu_read(AST_SCU_D2_PLL);
++ u32 OD,NUM,DENUM,PD,PD2;
++
++ if(d2_pll_set & SCU_D2_PLL_OFF)
++ return 0;
++
++ // Programming
++ clk = ast_get_clk_source();
++ if(d2_pll_set & SCU_D2_PLL_BYPASS_EN) {
++ return clk;
++ } else {
++ NUM = SCU_D2_PLL_GET_NUM(d2_pll_set);
++ DENUM = SCU_D2_PLL_GET_DENUM(d2_pll_set);
++ OD = SCU_D2_PLL_GET_OD(d2_pll_set);
++ OD = (1 << (OD - 1));
++ PD = SCU_D2_PLL_GET_PD(d2_pll_set);
++ switch(PD) {
++ case 0:
++ PD = 1;
++ break;
++ case 1:
++ PD = 2;
++ break;
++ case 2:
++ PD = 2;
++ break;
++ case 3:
++ PD = 4;
++ break;
++ }
++ PD2 = SCU_D2_PLL_GET_PD2(d2_pll_set);
++ PD2 = PD2+1;
++// printk("clk %d ,num %d ,denum %d ,od %d ,pd %d ,pd2 %d \n",clk, NUM , DENUM, OD, PD, PD2);
++ //hpll = 24MHz * (Numerator * 2) / (Denumerator * OD * PD * PD2)
++ clk = (clk * NUM * 2) / (DENUM* OD * PD * PD2);
++ }
++
++ SCUDBUG("d2_pll = %d\n",clk);
++ return clk;
++}
++
++EXPORT_SYMBOL(ast_get_d2_pll_clk);
++
++//Because value 0 is not allowed in SDIO12C D[15:8]: Host Control Settings #1 Register, we have to increase the maximum
++//host's clock in case that system will not ask host to set 1 in the sdhci_set_clock() function
++/*
++SCU7C: Silicon Revision ID Register
++D[31:24]: Chip ID
++0: AST2050/AST2100/AST2150/AST2200/AST3000
++1: AST2300
++
++D[23:16] Silicon revision ID for AST2300 generation and later
++0: A0
++1: A1
++2: A2
++.
++.
++.
++FPGA revision starts from 0x80
++
++
++D[11:8] Bounding option
++
++D[7:0] Silicon revision ID for AST2050/AST2100 generation (for software compatible)
++0: A0
++1: A1
++2: A2
++3: A3
++.
++.
++FPGA revision starts from 0x08, 8~10 means A0, 11+ means A1, AST2300 should be assigned to 3
++*/
++
++extern u32
++ast_get_sd_clock_src(void)
++{
++ u32 clk=0, sd_div;
++
++#if defined(FPGA)
++ clk = 100000000;
++#else
++ clk = ast_get_h_pll_clk();
++ //get div
++ sd_div = SCU_CLK_SD_GET_DIV(ast_scu_read(AST_SCU_CLK_SEL));
++ SCUDBUG("div %d, sdclk =%d \n",((sd_div + 1) * 2),clk/((sd_div + 1) * 2));
++ clk /= ((sd_div + 1) * 2);
++
++#endif
++ return clk;
++}
++
++EXPORT_SYMBOL(ast_get_sd_clock_src);
++
++extern void
++ast_scu_show_system_info (void)
++{
++ u32 h_pll, div;
++
++ h_pll = ast_get_h_pll_clk();
++
++ div = SCU_HW_STRAP_GET_CPU_AHB_RATIO(ast_scu_read(AST_SCU_HW_STRAP1));
++ switch(div) {
++ case 0:
++ div = 1;
++ break;
++ case 1:
++ div = 2;
++ break;
++ case 2:
++ div = 3;
++ break;
++ case 3:
++ div = 4;
++ break;
++
++ }
++
++ SCUMSG("CPU = %d MHz ,AHB = %d MHz (%d:1) \n", h_pll/1000000, h_pll/div/1000000,div);
++
++ return ;
++}
++
++EXPORT_SYMBOL(ast_scu_show_system_info);
++
++//*********************************** Multi-function pin control ***********************************
++extern void
++ast_scu_multi_func_uart(u8 uart)
++{
++ switch(uart) {
++ case 1:
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
++ SCU_FUN_PIN_UART1_RXD |
++ SCU_FUN_PIN_UART1_TXD |
++ SCU_FUN_PIN_UART1_NRTS |
++ SCU_FUN_PIN_UART1_NDTR |
++ SCU_FUN_PIN_UART1_NRI |
++ SCU_FUN_PIN_UART1_NDSR |
++ SCU_FUN_PIN_UART1_NDCD |
++ SCU_FUN_PIN_UART1_NCTS,
++ AST_SCU_FUN_PIN_CTRL1);
++ break;
++ case 2:
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
++ SCU_FUN_PIN_UART2_RXD |
++ SCU_FUN_PIN_UART2_TXD |
++ SCU_FUN_PIN_UART2_NRTS |
++ SCU_FUN_PIN_UART2_NDTR |
++ SCU_FUN_PIN_UART2_NRI |
++ SCU_FUN_PIN_UART2_NDSR |
++ SCU_FUN_PIN_UART2_NDCD |
++ SCU_FUN_PIN_UART2_NCTS,
++ AST_SCU_FUN_PIN_CTRL1);
++ break;
++ case 3:
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
++ SCU_FUN_PIN_UART3_RXD |
++ SCU_FUN_PIN_UART3_TXD |
++ SCU_FUN_PIN_UART3_NRTS |
++ SCU_FUN_PIN_UART3_NDTR |
++ SCU_FUN_PIN_UART3_NRI |
++ SCU_FUN_PIN_UART3_NDSR |
++ SCU_FUN_PIN_UART3_NDCD |
++ SCU_FUN_PIN_UART3_NCTS,
++ AST_SCU_FUN_PIN_CTRL1);
++ break;
++ case 4:
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
++ SCU_FUN_PIN_UART4_RXD |
++ SCU_FUN_PIN_UART4_TXD |
++ SCU_FUN_PIN_UART4_NRTS |
++ SCU_FUN_PIN_UART4_NDTR |
++ SCU_FUN_PIN_UART4_NRI |
++ SCU_FUN_PIN_UART4_NDSR |
++ SCU_FUN_PIN_UART4_NDCD |
++ SCU_FUN_PIN_UART4_NCTS,
++ AST_SCU_FUN_PIN_CTRL1);
++ break;
++ }
++
++
++}
++
++extern void
++ast_scu_multi_func_video()
++{
++#if defined(CONFIG_ARCH_2100) || defined(CONFIG_ARCH_2200)
++ ast_scu_write(ast_scu_read(AST_SCU_MULTI_FUNC_2) |
++ MULTI_FUNC_VIDEO_RGB18 |
++ MULTI_FUNC_VIDEO_SINGLE_EDGE,
++ AST_SCU_MULTI_FUNC_2);
++#elif defined(CONFIG_ARCH_1100) || defined(CONFIG_ARCH_2050)
++ ast_scu_write(ast_scu_read(AST_SCU_MULTI_FUNC_2) |
++ MULTI_FUNC_VIDEO_RGB18 |
++ MULTI_FUNC_VIDEO_SINGLE_EDGE,
++ AST_SCU_MULTI_FUNC_2);
++#else
++
++#endif
++}
++
++extern void
++ast_scu_multi_func_eth(u8 num)
++{
++ switch(num) {
++ case 0:
++ if(ast_scu_read(AST_SCU_HW_STRAP1) && SCU_HW_STRAP_MAC0_RGMII) {
++ SCUMSG("MAC0 : RGMII \n");
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
++ SCU_FUN_PIN_MAC0_PHY_LINK,
++ AST_SCU_FUN_PIN_CTRL1);
++ } else {
++ SCUMSG("MAC0 : RMII/NCSI \n");
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) &
++ ~SCU_FUN_PIN_MAC0_PHY_LINK,
++ AST_SCU_FUN_PIN_CTRL1);
++ }
++
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL3) |
++ SCU_FUN_PIN_MAC0_MDIO |
++ SCU_FUN_PIN_MAC0_MDC,
++ AST_SCU_FUN_PIN_CTRL3);
++
++ break;
++ case 1:
++ if(ast_scu_read(AST_SCU_HW_STRAP1) && SCU_HW_STRAP_MAC1_RGMII) {
++ SCUMSG("MAC1 : RGMII \n");
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
++ SCU_FUN_PIN_MAC1_PHY_LINK,
++ AST_SCU_FUN_PIN_CTRL1);
++ } else {
++ SCUMSG("MAC1 : RMII/NCSI \n");
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) &
++ ~SCU_FUN_PIN_MAC1_PHY_LINK,
++ AST_SCU_FUN_PIN_CTRL1);
++ }
++
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) |
++ SCU_FUC_PIN_MAC1_MDIO,
++ AST_SCU_FUN_PIN_CTRL5);
++
++ break;
++ }
++}
++
++extern void
++ast_scu_multi_func_nand(void)
++{
++ //enable NAND flash multipin FLBUSY and FLWP
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL2) |
++ SCU_FUN_PIN_NAND_FLBUSY | SCU_FUN_PIN_NAND_FLWP,
++ AST_SCU_FUN_PIN_CTRL2);
++
++}
++
++extern void
++ast_scu_multi_func_nor(void)
++{
++ //Address
++ //ROMA2~17
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL8) |
++ SCU_FUN_PIN_ROMA2 | SCU_FUN_PIN_ROMA3 |
++ SCU_FUN_PIN_ROMA4 | SCU_FUN_PIN_ROMA5 |
++ SCU_FUN_PIN_ROMA6 | SCU_FUN_PIN_ROMA7 |
++ SCU_FUN_PIN_ROMA8 | SCU_FUN_PIN_ROMA9 |
++ SCU_FUN_PIN_ROMA10 | SCU_FUN_PIN_ROMA11 |
++ SCU_FUN_PIN_ROMA12 | SCU_FUN_PIN_ROMA13 |
++ SCU_FUN_PIN_ROMA14 | SCU_FUN_PIN_ROMA15 |
++ SCU_FUN_PIN_ROMA16 | SCU_FUN_PIN_ROMA17,
++ AST_SCU_FUN_PIN_CTRL8);
++
++ //ROMA18~21
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL9) |
++ SCU_FUN_PIN_ROMA18 | SCU_FUN_PIN_ROMA19 |
++ SCU_FUN_PIN_ROMA20 | SCU_FUN_PIN_ROMA21,
++ AST_SCU_FUN_PIN_CTRL9);
++
++ //ROMA22,23
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL4) | SCU_FUN_PIN_ROMA22 | SCU_FUN_PIN_ROMA23,
++ AST_SCU_FUN_PIN_CTRL4);
++
++ //ROMA24,25
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL3) | SCU_FUN_PIN_ROMA24 | SCU_FUN_PIN_ROMA25,
++ AST_SCU_FUN_PIN_CTRL3);
++
++ //SCU94 [1] = 0
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL6) & SCU_VIDEO_OUT_MASK,
++ AST_SCU_FUN_PIN_CTRL6);
++
++
++ //data
++ //ROMD 4~7 //ROMWE#, OE#
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL4) |
++ SCU_FUN_PIN_ROMOE | SCU_FUN_PIN_ROMWE |
++ SCU_FUN_PIN_ROMD4 | SCU_FUN_PIN_ROMD5 |
++ SCU_FUN_PIN_ROMD6 | SCU_FUN_PIN_ROMD7,
++ AST_SCU_FUN_PIN_CTRL4);
++
++ //ROMD 8~15
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) |
++ SCU_FUC_PIN_ROM_16BIT,
++ AST_SCU_FUN_PIN_CTRL5);
++
++}
++
++extern void
++ast_scu_multi_func_romcs(u8 num)
++{
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL3) |
++ SCU_FUN_PIN_ROMCS(num),
++ AST_SCU_FUN_PIN_CTRL3);
++}
++
++extern void
++ast_scu_multi_func_i2c(void)
++{
++ //TODO check ... //In AST2400 Due to share pin with SD , please not enable I2C 10 ~14
++ // AST 2400 have 14 , AST 2300 9 ...
++#ifdef CONFIG_MMC_AST
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) |
++ SCU_FUC_PIN_I2C3 |
++ SCU_FUC_PIN_I2C4 |
++ SCU_FUC_PIN_I2C5 |
++ SCU_FUC_PIN_I2C6 |
++ SCU_FUC_PIN_I2C7 |
++ SCU_FUC_PIN_I2C8 |
++ SCU_FUC_PIN_I2C9,
++ AST_SCU_FUN_PIN_CTRL5);
++#else
++ ast_scu_write((ast_scu_read(AST_SCU_FUN_PIN_CTRL5) |
++ SCU_FUC_PIN_I2C3 |
++ SCU_FUC_PIN_I2C4 |
++ SCU_FUC_PIN_I2C5 |
++ SCU_FUC_PIN_I2C6 |
++ SCU_FUC_PIN_I2C7 |
++ SCU_FUC_PIN_I2C8 |
++ SCU_FUC_PIN_I2C9 |
++ SCU_FUC_PIN_I2C10 |
++ SCU_FUC_PIN_I2C11 |
++ SCU_FUC_PIN_I2C12 |
++ SCU_FUC_PIN_I2C13 |
++ SCU_FUC_PIN_I2C14) &
++ ~(SCU_FUC_PIN_SD1 | SCU_FUC_PIN_SD2),
++ AST_SCU_FUN_PIN_CTRL5);
++#endif
++}
++
++EXPORT_SYMBOL(ast_scu_multi_func_i2c);
++
++extern void
++ast_scu_multi_func_pwm_tacho(void)
++{
++ //TODO check
++ u32 sts = ast_scu_read(AST_SCU_FUN_PIN_CTRL3) &~0xcfffff;
++ ast_scu_write(sts | 0xc000ff, AST_SCU_FUN_PIN_CTRL3);
++}
++
++EXPORT_SYMBOL(ast_scu_multi_func_pwm_tacho);
++
++//0 : hub mode , 1: usb host mode
++extern void
++ast_scu_multi_func_usb20_host_hub(u8 mode)
++{
++ if(mode)
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_USB20_HOST,
++ AST_SCU_FUN_PIN_CTRL5);
++ else
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_USB20_HOST,
++ AST_SCU_FUN_PIN_CTRL5);
++}
++
++EXPORT_SYMBOL(ast_scu_multi_func_usb20_host_hub);
++
++//0 : gpioQ6,7 mode , 1: usb1.1 host port 4 mode
++extern void
++ast_scu_multi_func_usb11_host_port4(u8 mode)
++{
++ if(mode)
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_USB11_PORT4,
++ AST_SCU_FUN_PIN_CTRL5);
++ else
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_USB11_PORT4,
++ AST_SCU_FUN_PIN_CTRL5);
++}
++
++EXPORT_SYMBOL(ast_scu_multi_func_usb11_host_port4);
++
++//0 : USB 1.1 HID mode , 1: usb1.1 host port 2 mode
++extern void
++ast_scu_multi_func_usb11_host_port2(u8 mode)
++{
++ if(mode)
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_USB11_PORT2,
++ AST_SCU_FUN_PIN_CTRL5);
++ else
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_USB11_PORT2,
++ AST_SCU_FUN_PIN_CTRL5);
++}
++
++EXPORT_SYMBOL(ast_scu_multi_func_usb11_host_port2);
++
++//0 : 1: SD1 function
++extern void
++ast_scu_multi_func_sdhc_slot1(u8 mode)
++{
++ if(mode)
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_SD1,
++ AST_SCU_FUN_PIN_CTRL5);
++ else
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_SD1,
++ AST_SCU_FUN_PIN_CTRL5);
++}
++
++EXPORT_SYMBOL(ast_scu_multi_func_sdhc_slot1);
++
++extern void
++ast_scu_multi_func_sdhc_slot2(u8 mode)
++{
++ if(mode)
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_SD2,
++ AST_SCU_FUN_PIN_CTRL5);
++ else
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_SD2,
++ AST_SCU_FUN_PIN_CTRL5);
++
++}
++
++EXPORT_SYMBOL(ast_scu_multi_func_sdhc_slot2);
++
++extern void
++ast_scu_multi_func_crt(void)
++{
++ /* multi-pin for DVO */
++
++ //Digital vodeo input function pins : 00 disable, 10 24bits mode 888,
++ ast_scu_write((ast_scu_read(AST_SCU_FUN_PIN_CTRL5) &
++ ~SCU_FUC_PIN_DIGI_V_OUT_MASK) |
++ SCU_FUC_PIN_DIGI_V_OUT(VIDEO_24BITS),AST_SCU_FUN_PIN_CTRL5);
++
++ //VPI input
++#if 0
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL2) |
++ SCU_FUN_PIN_VPIB9 | SCU_FUN_PIN_VPIB8 |
++ SCU_FUN_PIN_VPIB7 | SCU_FUN_PIN_VPIB6 |
++ SCU_FUN_PIN_VPIB5 | SCU_FUN_PIN_VPIB4 |
++ SCU_FUN_PIN_VPIB3 | SCU_FUN_PIN_VPIB2 |
++ SCU_FUN_PIN_VPIB1 | SCU_FUN_PIN_VPIB0 |
++ SCU_FUN_PIN_VPICLK | SCU_FUN_PIN_VPIVS |
++ SCU_FUN_PIN_VPIHS | SCU_FUN_PIN_VPIODD |
++ SCU_FUN_PIN_VPIDE ,AST_SCU_FUN_PIN_CTRL2);
++
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL3) |
++ SCU_FUN_PIN_VPIR9 | SCU_FUN_PIN_VPIR8 |
++ SCU_FUN_PIN_VPIR7 | SCU_FUN_PIN_VPIR6 |
++ SCU_FUN_PIN_VPIR5 | SCU_FUN_PIN_VPIR4 |
++ SCU_FUN_PIN_VPIR3 | SCU_FUN_PIN_VPIR2 |
++ SCU_FUN_PIN_VPIR1 | SCU_FUN_PIN_VPIR0 |
++ SCU_FUN_PIN_VPIG9 | SCU_FUN_PIN_VPIG8 |
++ SCU_FUN_PIN_VPIG7 | SCU_FUN_PIN_VPIG6 |
++ SCU_FUN_PIN_VPIG5 | SCU_FUN_PIN_VPIG4 |
++ SCU_FUN_PIN_VPIG3 | SCU_FUN_PIN_VPIG2 |
++ SCU_FUN_PIN_VPIG1 | SCU_FUN_PIN_VPIG0 ,AST_SCU_FUN_PIN_CTRL3);
++#endif
++}
++
++EXPORT_SYMBOL(ast_scu_multi_func_crt);
++//***********************************Information ***********************************
++extern u32
++ast_scu_revision_id(void)
++{
++ int i;
++ u32 rev_id = ast_scu_read(AST_SCU_REVISION_ID);
++ for(i=0;i<ARRAY_SIZE(soc_map_table);i++) {
++ if(rev_id == soc_map_table[i].rev_id)
++ break;
++ }
++ if(i == ARRAY_SIZE(soc_map_table))
++ SCUMSG("UnKnow-SOC : %x \n",rev_id);
++ else
++ SCUMSG("SOC : %4s \n",soc_map_table[i].name);
++
++ return rev_id;
++}
++
++EXPORT_SYMBOL(ast_scu_revision_id);
++
++/*
++* D[15:11] in 0x1E6E2040 is NCSI scratch from U-Boot. D[15:14] = MAC1, D[13:12] = MAC2
++* The meanings of the 2 bits are:
++* 00(0): Dedicated PHY
++* 01(1): ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 10(2): ASPEED's MAC is connected to NC-SI PHY chip directly
++* 11: Reserved
++*/
++
++extern u32
++ast_scu_get_phy_config(u8 mac_num)
++{
++ u32 scatch = ast_scu_read(AST_SCU_SOC_SCRATCH0);
++
++ switch(mac_num) {
++ case 0:
++ return (SCU_MAC0_GET_PHY_MODE(scatch));
++ break;
++ case 1:
++ return (SCU_MAC1_GET_PHY_MODE(scatch));
++ break;
++ default:
++ SCUMSG("error mac number \n");
++ break;
++ }
++ return -1;
++}
++EXPORT_SYMBOL(ast_scu_get_phy_config);
++
++extern u32
++ast_scu_get_phy_interface(u8 mac_num)
++{
++ u32 trap1 = ast_scu_read(AST_SCU_HW_STRAP1);
++
++ switch(mac_num) {
++ case 0:
++ if(SCU_HW_STRAP_MAC0_RGMII & trap1)
++ return 1;
++ else
++ return 0;
++ break;
++ case 1:
++ if(SCU_HW_STRAP_MAC1_RGMII & trap1)
++ return 1;
++ else
++ return 0;
++ break;
++ default:
++ SCUMSG("error mac number \n");
++ break;
++ }
++ return -1;
++}
++EXPORT_SYMBOL(ast_scu_get_phy_interface);
++
++extern void
++ast_scu_set_vga_display(u8 enable)
++{
++ if(enable)
++ printk("111111");
++}
++
++EXPORT_SYMBOL(ast_scu_set_vga_display);
++
++extern u32
++ast_scu_get_vga_memsize(void)
++{
++ u32 size=0;
++
++ switch(SCU_HW_STRAP_VGA_SIZE_GET(ast_scu_read(AST_SCU_HW_STRAP1))) {
++ case 0:
++ size = 8*1024*1024;
++ break;
++ case 1:
++ size = 16*1024*1024;
++ break;
++ case 2:
++ size = 32*1024*1024;
++ break;
++ case 3:
++ size = 64*1024*1024;
++ break;
++ default:
++ SCUMSG("error vga size \n");
++ break;
++ }
++ return size;
++}
++
++EXPORT_SYMBOL(ast_scu_get_vga_memsize);
++
++extern void
++ast_scu_get_who_init_dram(void)
++{
++ switch(SCU_VGA_DRAM_INIT_MASK(ast_scu_read(AST_SCU_VGA0))) {
++ case 0:
++ SCUMSG("VBIOS init \n");
++ break;
++ case 1:
++ SCUMSG("SOC init \n");
++ break;
++ default:
++ SCUMSG("error vga size \n");
++ break;
++ }
++}
+diff --git a/arch/arm/plat-aspeed/ast-sdmc.c b/arch/arm/plat-aspeed/ast-sdmc.c
+new file mode 100644
+index 0000000..238cf79
+--- /dev/null
++++ b/arch/arm/plat-aspeed/ast-sdmc.c
+@@ -0,0 +1,100 @@
++/********************************************************************************
++* File Name : arch/arm/mach-aspeed/ast-sdmc.c
++* Author : Ryan Chen
++* Description : AST SDRAM Memory Ctrl
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++
++* History :
++* 1. 2013/03/15 Ryan Chen Create
++*
++********************************************************************************/
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/delay.h>
++#include <asm/io.h>
++
++#include <mach/platform.h>
++#include <mach/hardware.h>
++
++#include <plat/ast-sdmc.h>
++#include <plat/regs-sdmc.h>
++
++//#define AST_SDMC_LOCK
++//#define AST_SDMC_DEBUG
++
++#ifdef AST_SDMC_DEBUG
++#define SDMCDBUG(fmt, args...) printk("%s() " fmt, __FUNCTION__, ## args)
++#else
++#define SDMCDBUG(fmt, args...)
++#endif
++
++#define SDMCMSG(fmt, args...) printk(fmt, ## args)
++
++static u32 ast_sdmc_base = IO_ADDRESS(AST_SDMC_BASE);
++
++static inline u32
++ast_sdmc_read(u32 reg)
++{
++ u32 val;
++
++ val = readl(ast_sdmc_base + reg);
++
++ SDMCDBUG("ast_sdmc_read : reg = 0x%08x, val = 0x%08x\n", reg, val);
++
++ return val;
++}
++
++static inline void
++ast_sdmc_write(u32 val, u32 reg)
++{
++ SDMCDBUG("ast_sdmc_write : reg = 0x%08x, val = 0x%08x\n", reg, val);
++#ifdef CONFIG_AST_SDMC_LOCK
++ //unlock
++ writel(SDMC_PROTECT_UNLOCK, ast_sdmc_base);
++ writel(val, ast_sdmc_base + reg);
++ //lock
++ writel(0xaa,ast_sdmc_base);
++#else
++ writel(SDMC_PROTECT_UNLOCK, ast_sdmc_base);
++
++ writel(val, ast_sdmc_base + reg);
++#endif
++}
++
++//***********************************Information ***********************************
++extern u32
++ast_sdmc_get_mem_size(void)
++{
++ u32 size=0;
++ switch(SDMC_CONFIG_MEM_GET(ast_sdmc_read(AST_SDMC_CONFIG))) {
++ case 0:
++ size = 64*1024*1024;
++ break;
++ case 1:
++ size = 128*1024*1024;
++ break;
++ case 2:
++ size = 256*1024*1024;
++ break;
++ case 3:
++ size = 512*1024*1024;
++ break;
++
++ default:
++ SDMCMSG("error ddr size \n");
++ break;
++ }
++ return size;
++}
++
+diff --git a/arch/arm/plat-aspeed/ast1070-scu.c b/arch/arm/plat-aspeed/ast1070-scu.c
+new file mode 100644
+index 0000000..4ad12c7
+--- /dev/null
++++ b/arch/arm/plat-aspeed/ast1070-scu.c
+@@ -0,0 +1,178 @@
++/********************************************************************************
++* File Name : arch/arm/mach-aspeed/ast1070-scu.c
++* Author : Ryan Chen
++* Description : AST1070 SCU
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2013/05/15 Ryan Chen Create
++*
++********************************************************************************/
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/delay.h>
++
++#include <mach/platform.h>
++#include <asm/io.h>
++
++#include <mach/hardware.h>
++
++#include <plat/ast1070-scu.h>
++#include <plat/regs-ast1070-scu.h>
++
++#define CONFIG_AST1070_SCU_LOCK
++//#define AST1070_SCU_DEBUG
++
++#ifdef AST1070_SCU_DEBUG
++#define SCUDBUG(fmt, args...) printk("%s() " fmt, __FUNCTION__, ## args)
++#else
++#define SCUDBUG(fmt, args...)
++#endif
++
++#define SCUMSG(fmt, args...) printk(fmt, ## args)
++
++static u32 ast1070_scu_base = IO_ADDRESS2(AST_C0_SCU_BASE);
++
++static inline u32
++ast1070_scu_read(u8 node, u32 reg)
++{
++ u32 val;
++
++ val = readl(ast1070_scu_base + (node * 0x10000) + reg);
++
++ SCUDBUG("ast1070_scu_read : reg = 0x%08x, val = 0x%08x\n", reg, val);
++
++ return val;
++}
++
++static inline void
++ast1070_scu_write(u8 node, u32 val, u32 reg)
++{
++ SCUDBUG("ast1070_scu_write : reg = 0x%08x, val = 0x%08x\n", reg, val);
++#ifdef CONFIG_AST1070_SCU_LOCK
++ //unlock
++ writel(AST1070_SCU_PROTECT_UNLOCK, ast1070_scu_base + (node * 0x10000));
++ writel(val, ast1070_scu_base + (node * 0x10000) + reg);
++ //lock
++// writel(0xaa,ast1070_scu_base + (node * 0x10000));
++#else
++ writel(val, ast1070_scu_base + (node * 0x10000) + reg);
++#endif
++}
++
++extern void
++ast1070_scu_init_uart(u8 node)
++{
++ //SCU UART Reset
++ ast1070_scu_write(node, ast1070_scu_read(node, AST1070_SCU_RESET) &
++ ~(SCU_RESET_N1_UART | SCU_RESET_N2_UART |
++ SCU_RESET_N3_UART | SCU_RESET_N4_UART),
++ AST1070_SCU_RESET);
++}
++
++EXPORT_SYMBOL(ast1070_scu_init_uart);
++
++extern void
++ast1070_scu_init_i2c(u8 node)
++{
++ //SCU I2C Reset
++ ast1070_scu_write(node, ast1070_scu_read(node, AST1070_SCU_RESET) & ~SCU_RESET_I2C, AST1070_SCU_RESET);
++}
++
++EXPORT_SYMBOL(ast1070_scu_init_i2c);
++
++extern void
++ast1070_dma_init(u8 node)
++{
++ u32 val =0;
++
++ //let the uart_dma engine leave the reset state
++ ast1070_scu_write(node, ast1070_scu_read(node, AST1070_SCU_RESET) & ~SCU_RESET_DMA, AST1070_SCU_RESET);
++
++ val = ast1070_scu_read(node, AST1070_SCU_MISC_CTRL) & ~SCU_DMA_M_S_MASK;
++
++ if(ast1070_scu_read(node, AST1070_SCU_TRAP) & TRAP_MULTI_MASTER) {
++ //AST1070 multi Initial DMA
++ if(ast1070_scu_read(node, AST1070_SCU_TRAP) & TRAP_DEVICE_SLAVE)
++ ast1070_scu_write(node, val | SCU_DMA_SLAVE_EN, AST1070_SCU_MISC_CTRL);
++ else
++ //Enable DMA master
++ ast1070_scu_write(node, val | SCU_DMA_MASTER_EN, AST1070_SCU_MISC_CTRL);
++
++ } else {
++ //AST1070 single
++ ast1070_scu_write(node, val, AST1070_SCU_MISC_CTRL);
++ }
++}
++EXPORT_SYMBOL(ast1070_dma_init);
++
++
++extern void
++ast1070_scu_init_lpc(void)
++{
++
++}
++
++EXPORT_SYMBOL(ast1070_scu_init_lpc);
++
++//***********************************Multi-function pin control***********************************
++
++extern void
++ast1070_multi_func_uart(u8 node, u8 uart)
++{
++ ast1070_scu_write(node, (ast1070_scu_read(node, AST1070_SCU_UART_MUX) &
++ ~UART_MUX_MASK(uart)) |
++ SET_UART_IO_PAD(uart,PAD_FROM_BMC) |
++ SET_NODE_UART_CTRL(uart, NODE_UART_FROM_NONE) |
++ SET_BMC_UART_CTRL(uart, BMC_UART_FROM_PAD1),
++ AST1070_SCU_UART_MUX);
++
++}
++
++EXPORT_SYMBOL(ast1070_multi_func_uart);
++
++
++//***********************************CLK control***********************************
++
++
++//***********************************CLK Information***********************************
++extern u32
++ast1070_get_clk_source(void)
++{
++
++}
++EXPORT_SYMBOL(ast1070_get_clk_source);
++
++//***********************************Information ***********************************
++extern void
++ast1070_scu_revision_id(u8 node)
++{
++ u32 rev_id;
++
++#if 0
++ if(gpio_get_value(PIN_GPIOI1))
++ printk("Use LPC+ Bus Access \n");
++ else
++ printk("Use LPC Bus Access \n");
++#endif
++
++ rev_id = ast1070_scu_read(node, AST1070_SCU_CHIP_ID);
++ if (ast1070_scu_read(node, AST1070_SCU_TRAP) & TRAP_LPC_PLUS_MODE) {
++ printk("LPC+ : ");
++ } else
++ printk("LPC : ");
++
++ printk("AST1070-[C%d] rev_id[%x] \n",node,rev_id);
++}
++
++EXPORT_SYMBOL(ast1070_scu_revision_id);
+diff --git a/arch/arm/plat-aspeed/ast1070-uart-dma.c b/arch/arm/plat-aspeed/ast1070-uart-dma.c
+new file mode 100644
+index 0000000..9da401e
+--- /dev/null
++++ b/arch/arm/plat-aspeed/ast1070-uart-dma.c
+@@ -0,0 +1,572 @@
++/*
++ * ast1070-uart-dma.c
++ *
++ * UART DMA for the AST1070 UART access.
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * 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.
++ *
++ * History:
++ * 2012.05.26: Initial version [Ryan Chen]
++ */
++
++#include <linux/sysdev.h>
++#include <linux/dma-mapping.h>
++#include <linux/interrupt.h>
++#include <asm/io.h>
++#include <mach/irqs.h>
++#include <mach/hardware.h>
++#include <mach/ast-uart-dma.h>
++#include <plat/regs-uart-dma.h>
++
++//#define AST_UART_DMA_DEBUG
++
++#ifdef AST_UART_DMA_DEBUG
++#define DMADUG(fmt, args...) printk("%s() " fmt, __FUNCTION__, ## args)
++#else
++#define DMADUG(fmt, args...)
++#endif
++
++//#define AST1070_FPGA 1
++
++struct ast1070_dma uart_dma[CONFIG_AST1070_NR];
++
++static inline void
++ast1070_uart_dma_write(struct ast1070_dma *dma, u32 val, u32 reg)
++{
++ //printk("uart dma write : val: %x , reg : %x \n",val,reg);
++ writel(val, dma->reg_base+ reg);
++}
++
++static inline u32
++ast1070_uart_dma_read(struct ast1070_dma *dma, u32 reg)
++{
++#if 0
++ u32 val = readl(i2c_dev->reg_base + reg);
++ printk("R : reg %x , val: %x \n",reg, val);
++ return val;
++#else
++ return readl(dma->reg_base + reg);
++#endif
++}
++
++/* *****************************************************************************/
++int ast_uart_rx_dma_enqueue(u8 node, u8 ch, dma_addr_t rx_buff, u16 len)
++{
++ unsigned long flags;
++ struct ast1070_dma *dma = &uart_dma[node];
++ struct ast1070_dma_ch *dma_ch = &(dma->dma_rx_ch[ch]);
++ struct uart_dma_desc *rx_desc = dma_ch->desc;
++
++ if(len > 4096)
++ printk("ERROR !!! Please Check ...\n");
++
++ local_irq_save(flags);
++
++ //fill to rx desc -->
++ rx_desc->desc0 = DESC0_END | DESC0_INT_EN | DESC0_HW_OWN;
++ rx_desc->desc1 = DESC1_LEN(len);
++ rx_desc->desc2 = rx_buff;
++ rx_desc->desc3 = 0;
++
++ DMADUG("[c%d]: ch = %d, rx buff = %x, len = %d \n",node, ch, rx_buff, len);
++
++ //fill in tx descriptor base register
++ DMADUG("desc_addr : %x, reg offset %x \n",dma_ch->desc_dma_addr, dma_ch->desc_offset);
++ ast1070_uart_dma_write(dma, dma_ch->desc_dma_addr, dma_ch->desc_offset);
++
++ local_irq_restore(flags);
++
++ return 0;
++}
++
++EXPORT_SYMBOL(ast_uart_rx_dma_enqueue);
++
++int ast_uart_tx_dma_enqueue(u8 node, u8 ch, dma_addr_t tx_buff, u16 len)
++{
++ unsigned long flags;
++ struct ast1070_dma *dma = &uart_dma[node];
++ struct ast1070_dma_ch *dma_ch = &(dma->dma_tx_ch[ch]);
++ struct uart_dma_desc *tx_desc = dma_ch->desc;
++
++ DMADUG("[c%d]: ch = %d, tx buff = %x, len = %d \n",node, ch, tx_buff, len);
++
++ local_irq_save(flags);
++
++ //fill to rx desc -->
++ tx_desc->desc0 = DESC0_END | DESC0_INT_EN | DESC0_HW_OWN;
++ tx_desc->desc1 = DESC1_LEN(len);
++ tx_desc->desc2 = tx_buff;
++ tx_desc->desc3 = 0;
++
++// DMADUG("desc vir = %x, tx desc = %x, %x, %x, %x ===\n",tx_desc, tx_desc->desc0 ,tx_desc->desc1,tx_desc->desc2,tx_desc->desc3);
++ //fill in tx descriptor base register
++ DMADUG("desc_addr : %x, in offset %x \n",dma_ch->desc_dma_addr, dma_ch->desc_offset);
++ ast1070_uart_dma_write(dma, dma_ch->desc_dma_addr, dma_ch->desc_offset);
++
++ local_irq_restore(flags);
++
++ return 0;
++}
++
++EXPORT_SYMBOL(ast_uart_tx_dma_enqueue);
++
++int ast_uart_rx_dma_ctrl(u8 node, u8 ch, enum ast_uart_chan_op op)
++{
++ unsigned long flags;
++ struct ast1070_dma *dma = &uart_dma[node];
++ struct ast1070_dma_ch *dma_ch = &(dma->dma_rx_ch[ch]);
++ DMADUG("[c%d]: ch = %d \n",node, ch);
++
++ local_irq_save(flags);
++
++ switch (op) {
++ case AST_UART_DMAOP_TRIGGER:
++ //trigger
++ DMADUG("Trigger \n");
++ dma_ch->enable = 1;
++// ast1070_uart_dma_write(dma, DMA_ENABLE, dma_ch->ctrl_offset);
++ ast1070_uart_dma_write(dma, DMA_TRIGGER | DMA_ENABLE, dma_ch->ctrl_offset);
++ break;
++
++ case AST_UART_DMAOP_STOP:
++ //disable engine
++ DMADUG("Stop \n");
++ dma_ch->enable = 0;
++ ast1070_uart_dma_write(dma, 0, dma_ch->ctrl_offset);
++ break;
++ }
++
++
++ return 0;
++}
++EXPORT_SYMBOL(ast_uart_rx_dma_ctrl);
++
++int ast_uart_tx_dma_ctrl(u8 node, u8 ch, enum ast_uart_chan_op op)
++{
++ unsigned long flags;
++ struct ast1070_dma *dma = &uart_dma[node];
++ struct ast1070_dma_ch *dma_ch = &(dma->dma_tx_ch[ch]);
++ DMADUG("TX DMA CTRL [c%d]: ch = %d \n",node, ch);
++
++ local_irq_save(flags);
++
++ switch (op) {
++ case AST_UART_DMAOP_TRIGGER:
++ //trigger
++ DMADUG("Trigger \n");
++ ast1070_uart_dma_write(dma, DMA_ENABLE, dma_ch->ctrl_offset);
++ ast1070_uart_dma_write(dma, DMA_TRIGGER | DMA_ENABLE, dma_ch->ctrl_offset);
++ break;
++
++ case AST_UART_DMAOP_STOP:
++ //disable engine
++ DMADUG("STOP \n");
++ ast1070_uart_dma_write(dma, 0, dma_ch->ctrl_offset);
++ break;
++ }
++
++
++ return 0;
++}
++EXPORT_SYMBOL(ast_uart_tx_dma_ctrl);
++
++int ast_uart_tx_dma_request(u8 node, u8 ch, ast_uart_dma_cbfn_t rtn, void *id)
++{
++ unsigned long flags;
++ struct ast1070_dma *dma = &uart_dma[node];
++ struct ast1070_dma_ch *dma_ch = &(dma->dma_tx_ch[ch]);
++
++ DMADUG("TX DMA REQUEST [c%d]: ch = %d \n",node, ch);
++
++ local_irq_save(flags);
++
++ if (dma_ch->enable) {
++ local_irq_restore(flags);
++ return -EBUSY;
++ }
++
++ dma_ch->priv = id;
++ dma_ch->enable = 1;
++ dma_ch->callback_fn = rtn;
++ //DMA IRQ En
++ ast1070_uart_dma_write(dma,
++ ast1070_uart_dma_read(dma, UART_DMA_IER) |
++ (1 << ch)
++ , UART_DMA_IER);
++
++ //enable engine
++// ast1070_uart_dma_write(dma, DMA_ENABLE, dma_ch->ctrl_offset);
++ local_irq_restore(flags);
++
++ return 0;
++
++}
++
++EXPORT_SYMBOL(ast_uart_tx_dma_request);
++
++int ast_uart_rx_dma_request(u8 node, u8 ch, ast_uart_dma_cbfn_t rtn, void *id)
++{
++ unsigned long flags;
++ struct ast1070_dma *dma = &uart_dma[node];
++ struct ast1070_dma_ch *dma_ch = &(dma->dma_rx_ch[ch]);
++
++ DMADUG("RX DMA REQUEST [c%d] : ch = %d \n",node, ch);
++
++ local_irq_save(flags);
++
++ if (dma->dma_rx_ch[ch].enable) {
++ local_irq_restore(flags);
++ return -EBUSY;
++ }
++ dma_ch->priv = id;
++// dma_ch->enable = 1;
++ dma_ch->callback_fn = rtn;
++// dma_ch->name
++ //DMA IRQ En
++ ast1070_uart_dma_write(dma,
++ ast1070_uart_dma_read(dma, UART_DMA_IER) |
++ (1 << (4+ch))
++ , UART_DMA_IER);
++
++ //enable engine
++// ast1070_uart_dma_write(dma, DMA_ENABLE, dma_ch->ctrl_offset);
++ local_irq_restore(flags);
++
++ return 0;
++
++}
++
++EXPORT_SYMBOL(ast_uart_rx_dma_request);
++/* *****************************************************************************/
++static inline void ast_dma_bufffdone(struct ast1070_dma_ch *dma_ch)
++{
++ ////TODO desc -- remove ......
++ //workaround : Issue RX dma can;t be stoped , close open close
++ if(dma_ch->enable == 0) {
++// printk("workaround \n");
++ return;
++ }
++
++// u32 sts = ast1070_uart_dma_read(dma, dma_ch->ctrl_offset);
++ DMADUG("dma dwn : ch[%d] : %s ,len : %d \n", dma_ch->ch_no, dma_ch->direction ? "tx" : "rx", DESC3_GET_LEN(dma_ch->desc->desc3));
++
++ DMADUG(" == desc = %x, %x, %x, %x ===\n",dma_ch->desc->desc0,dma_ch->desc->desc1,dma_ch->desc->desc2,dma_ch->desc->desc3);
++
++
++ if(dma_ch->desc->desc0 & DESC0_HW_OWN)
++ printk("ERROR ..... \n");
++
++ if (dma_ch->callback_fn != NULL)
++ (dma_ch->callback_fn)(dma_ch, dma_ch->priv, DESC3_GET_LEN(dma_ch->desc->desc3));
++}
++
++
++static irqreturn_t
++ast1070_c0_uart_dma_irq(int irq, void *dev_id)
++{
++// struct ast1070_dma *dma = dev_id;
++ int i;
++ struct ast1070_dma *dma = &uart_dma[0];
++ u32 sts = ast1070_uart_dma_read(dma, UART_DMA_ISR);
++ DMADUG("C0 int -- > \n");
++ DMADUG("isr sts = %x\n", sts);
++
++ for(i = 0;i < 17 ; i++)
++ DMADUG("offset : %x , val %x \n",i*4, ast1070_uart_dma_read(dma, i*4));
++
++ if (sts & UART_DMA3_RX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA3_RX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_rx_ch[3]));
++ } else if (sts & UART_DMA2_RX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA2_RX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_rx_ch[2]));
++ } else if (sts & UART_DMA1_RX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA1_RX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_rx_ch[1]));
++ } else if (sts & UART_DMA0_RX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA0_RX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_rx_ch[0]));
++ } else if (sts & UART_DMA3_TX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA3_TX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_tx_ch[3]));
++ } else if (sts & UART_DMA2_TX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA2_TX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_tx_ch[2]));
++ } else if (sts & UART_DMA1_TX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA1_TX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_tx_ch[1]));
++ } else if (sts & UART_DMA0_TX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA0_TX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_tx_ch[0]));
++ } else {
++ printk("No body .. !!! \n");
++ }
++
++ return IRQ_HANDLED;
++}
++
++#if (CONFIG_AST1070_NR >=2)
++static irqreturn_t
++ast1070_c1_uart_dma_irq(int irq, void *dev_id)
++{
++// struct ast1070_dma *dma = dev_id;
++ struct ast1070_dma *dma = &uart_dma[1];
++ u32 sts = ast1070_uart_dma_read(dma, UART_DMA_ISR);
++ DMADUG("C1 int -- > \n");
++
++// DMADUG("isr sts = %x\n", sts);
++ if (sts & UART_DMA3_RX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA3_RX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_rx_ch[3]));
++ } else if (sts & UART_DMA2_RX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA2_RX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_rx_ch[2]));
++ } else if (sts & UART_DMA1_RX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA1_RX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_rx_ch[1]));
++ } else if (sts & UART_DMA0_RX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA0_RX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_rx_ch[0]));
++ } else if (sts & UART_DMA3_TX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA3_TX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_tx_ch[3]));
++ } else if (sts & UART_DMA2_TX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA2_TX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_tx_ch[2]));
++ } else if (sts & UART_DMA1_TX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA1_TX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_tx_ch[1]));
++ } else if (sts & UART_DMA0_TX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA0_TX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_tx_ch[0]));
++ } else {
++ printk("No body .. !!! \n");
++ }
++
++ return IRQ_HANDLED;
++}
++#endif
++
++#if (CONFIG_AST1070_NR >=3)
++static irqreturn_t
++ast1070_c2_uart_dma_irq(int irq, void *dev_id)
++{
++ struct ast1070_dma *dma = dev_id;
++ u32 sts = ast1070_uart_dma_read(dma, UART_DMA_ISR);
++
++// DMADUG("isr sts = %x\n", sts);
++ if (sts & UART_DMA3_RX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA3_RX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_rx_ch[3]));
++ } else if (sts & UART_DMA2_RX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA2_RX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_rx_ch[2]));
++ } else if (sts & UART_DMA1_RX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA1_RX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_rx_ch[1]));
++ } else if (sts & UART_DMA0_RX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA0_RX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_rx_ch[0]));
++ } else if (sts & UART_DMA3_TX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA3_TX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_tx_ch[3]));
++ } else if (sts & UART_DMA2_TX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA2_TX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_tx_ch[2]));
++ } else if (sts & UART_DMA1_TX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA1_TX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_tx_ch[1]));
++ } else if (sts & UART_DMA0_TX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA0_TX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_tx_ch[0]));
++ } else {
++ printk("No body .. !!! \n");
++ }
++
++ return IRQ_HANDLED;
++}
++#endif
++
++#if (CONFIG_AST1070_NR >=4)
++static irqreturn_t
++ast1070_c3_uart_dma_irq(int irq, void *dev_id)
++{
++ struct ast1070_dma *dma = dev_id;
++ u32 sts = ast1070_uart_dma_read(dma, UART_DMA_ISR);
++
++// DMADUG("isr sts = %x\n", sts);
++ if (sts & UART_DMA3_RX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA3_RX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_rx_ch[3]));
++ } else if (sts & UART_DMA2_RX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA2_RX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_rx_ch[2]));
++ } else if (sts & UART_DMA1_RX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA1_RX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_rx_ch[1]));
++ } else if (sts & UART_DMA0_RX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA0_RX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_rx_ch[0]));
++ } else if (sts & UART_DMA3_TX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA3_TX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_tx_ch[3]));
++ } else if (sts & UART_DMA2_TX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA2_TX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_tx_ch[2]));
++ } else if (sts & UART_DMA1_TX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA1_TX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_tx_ch[1]));
++ } else if (sts & UART_DMA0_TX_INT) {
++ ast1070_uart_dma_write(dma, UART_DMA0_TX_INT, UART_DMA_ISR);
++ ast_dma_bufffdone(&(dma->dma_tx_ch[0]));
++ } else {
++ printk("No body .. !!! \n");
++ }
++
++ return IRQ_HANDLED;
++}
++#endif
++
++extern int
++ast1070_uart_dma_init(u8 node)
++{
++ int ret,i;
++ struct ast1070_dma *dma = &uart_dma[node];
++
++ DMADUG("ast1070 uart_dma_init [c%d]\n", node);
++
++ if(node == 0) {
++ dma->reg_base = ioremap(AST_C0_UART_DMA_BASE, 0x100);
++#if (CONFIG_AST1070_NR >=2)
++ } else if (node == 1) {
++ dma->reg_base = ioremap(AST_C1_UART_DMA_BASE, 0x100);
++#endif
++#if (CONFIG_AST1070_NR >=3)
++ } else if (node == 2) {
++ dma->reg_base = ioremap(AST_C2_UART_DMA_BASE, 0x100);
++#endif
++#if (CONFIG_AST1070_NR >=4)
++ } else if (node == 3) {
++ dma->reg_base = ioremap(AST_C3_UART_DMA_BASE, 0x100);
++#endif
++ } else {
++ printk("node out of range !! \n");
++ return 1;
++ }
++
++ if (!dma->reg_base) {
++ printk(KERN_ERR "%s: failed to ioremap()\n", __func__);
++ return -ENXIO;
++ }
++
++ ast1070_uart_dma_write(dma, 0xff, UART_DMA_ISR);
++ ast1070_uart_dma_write(dma, 0, UART_DMA_IER);
++
++ for(i=0;i<4;i++) {
++ //TX ------------------------
++ dma->dma_tx_ch[i].enable = 0;
++ dma->dma_tx_ch[i].ch_no = i;
++ dma->dma_tx_ch[i].direction = 1;
++ //tx descriptor allocation
++ dma->dma_tx_ch[i].desc = dma_alloc_coherent(NULL, sizeof(struct uart_dma_desc), &(dma->dma_tx_ch[i].desc_dma_addr), GFP_KERNEL);
++ if (dma->dma_tx_ch[i].desc == NULL) {
++ DMADUG("Can't allocate tx descriptor\n");
++ return 0;
++ }
++ memset(dma->dma_tx_ch[i].desc, 0, sizeof(struct uart_dma_desc));
++ DMADUG("tx_desc [%d] virt = %x, dma = %x\n", i, (u32)dma->dma_tx_ch[i].desc, dma->dma_tx_ch[i].desc_dma_addr);
++
++ ast1070_uart_dma_write(dma, 0, UART_DMA0_TX_CTRL + (i*8));
++ dma->dma_tx_ch[i].ctrl_offset = UART_DMA0_TX_CTRL + (i*8);
++ dma->dma_tx_ch[i].desc_offset = UART_DMA0_TX_DESCPT + (i*8);
++
++ //RX ------------------------
++ dma->dma_rx_ch[i].enable = 0;
++ dma->dma_rx_ch[i].ch_no = i;
++ dma->dma_rx_ch[i].direction = 0;
++ //rx descriptor allocation
++ dma->dma_rx_ch[i].desc = dma_alloc_coherent(NULL, sizeof(struct uart_dma_desc), &(dma->dma_rx_ch[i].desc_dma_addr), GFP_KERNEL);
++ if (dma->dma_rx_ch[i].desc == NULL) {
++ DMADUG("Can't allocate tx descriptor\n");
++ return 0;
++ }
++ memset(dma->dma_rx_ch[i].desc, 0, sizeof(struct uart_dma_desc));
++ DMADUG("rx_desc [%d] virt = %x, dma = %x\n", i, (u32)dma->dma_rx_ch[i].desc, dma->dma_rx_ch[i].desc_dma_addr);
++ ast1070_uart_dma_write(dma, 0, UART_DMA0_RX_CTRL + (i*8));
++ dma->dma_rx_ch[i].ctrl_offset = UART_DMA0_RX_CTRL + (i*8);
++ dma->dma_rx_ch[i].desc_offset = UART_DMA0_RX_DESCPT + (i*8);
++ }
++
++ DMADUG("reg base = %x \n", (u32)dma->reg_base);
++
++ if(node == 0) {
++ for(i=0;i<4;i++) {
++ ret = request_irq(IRQ_C0_N1_UART_DMA + i,
++ ast1070_c0_uart_dma_irq, IRQF_SHARED,
++ "ast1070_n1_uart_dma", dma);
++ if (ret)
++ printk ("Unable to get UART DMA IRQ !!!!!!!!!!!!!!!!!!!!\n");
++ }
++#if (CONFIG_AST1070_NR >=2)
++ } else if (node == 1) {
++ for(i=0;i<4;i++) {
++ ret = request_irq(IRQ_C1_N1_UART_DMA + i,
++ ast1070_c1_uart_dma_irq, IRQF_SHARED,
++ "ast1070_n1_uart_dma", dma);
++ if (ret)
++ printk ("Unable to get UART DMA IRQ !!!!!!!!!!!!!!!!!!!!\n");
++ }
++#endif
++#if (CONFIG_AST1070_NR >=3)
++ } else if (node == 2) {
++ for(i=0;i<4;i++) {
++ ret = request_irq(IRQ_C2_N1_UART_DMA + i,
++ ast1070_c2_uart_dma_irq, IRQF_SHARED,
++ "ast1070_n1_uart_dma", dma);
++ if (ret)
++ printk ("Unable to get UART DMA IRQ !!!!!!!!!!!!!!!!!!!!\n");
++ }
++#endif
++#if (CONFIG_AST1070_NR >=4)
++ } else if (node == 3) {
++ for(i=0;i<4;i++) {
++ ret = request_irq(IRQ_C3_N1_UART_DMA + i,
++ ast1070_c3_uart_dma_irq, IRQF_SHARED,
++ "ast1070_n1_uart_dma", dma);
++ if (ret)
++ printk ("Unable to get UART DMA IRQ !!!!!!!!!!!!!!!!!!!!\n");
++ }
++#endif
++ } else {
++ printk("ERROR !! \n");
++ }
++
++ //Limit : AST1070 4* SPI CLK < AST2400 HCLK
++
++#ifdef AST1070_FPGA
++ //Low SPI clk setting == PCLK/8 , set 11
++ ast1070_uart_dma_write(dma,
++ (ast1070_uart_dma_read(dma, UART_DMA_CTRL) & ~SPI_CLK_MASK) |
++ SPI_CLK_SET(0x3) |
++ DMA_RX_TIMEOUT(0xfff) |
++ TXDESC_AUTO_POLLING |
++ RXDESC_AUTO_POLLING
++ , UART_DMA_CTRL);
++#else
++ ast1070_uart_dma_write(dma,
++ (ast1070_uart_dma_read(dma, UART_DMA_CTRL) &
++ ~DMA_BURST_MASK) |
++ DMA_RX_TIMEOUT(0xfff) |
++ TXDESC_AUTO_POLLING |
++ RXDESC_AUTO_POLLING
++ , UART_DMA_CTRL);
++#endif
++
++ return 0;
++}
++
++EXPORT_SYMBOL(ast1070_uart_dma_init);
+diff --git a/arch/arm/plat-aspeed/ast1070_irq.c b/arch/arm/plat-aspeed/ast1070_irq.c
+new file mode 100644
+index 0000000..e859cd1
+--- /dev/null
++++ b/arch/arm/plat-aspeed/ast1070_irq.c
+@@ -0,0 +1,220 @@
++/*
++ * linux/arch/arm/plat-aspeed/ast1070_irq.c
++ *
++ * 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 <linux/init.h>
++#include <linux/stddef.h>
++#include <linux/list.h>
++#include <linux/timer.h>
++
++#include <linux/device.h>
++#include <linux/dma-mapping.h>
++#include <linux/platform_device.h>
++#include <linux/sysdev.h>
++#include <linux/interrupt.h>
++#include <asm/system.h>
++#include <linux/irq.h>
++
++#include <mach/hardware.h>
++#include <asm/mach/irq.h>
++
++#include <asm/irq.h>
++#include <asm/io.h>
++
++#include <plat/regs-ast1070-intc.h>
++
++#define irq_to_c0_vic(irq_no) (irq_no-IRQ_C0_VIC_CHAIN_START)
++
++static void ast1070_c0_mask_irq(unsigned int irq)
++{
++ u32 regVal;
++// printk("ast_c0_mask_irq %d\n",irq);
++ irq = irq_to_c0_vic(irq);
++// printk("ast_c0_mask_irq cvic %d\n",irq);
++ regVal = readl(AST_INTR_DIS(0));
++ regVal |= (1 << irq);
++ writel(regVal, AST_INTR_DIS(0));
++
++}
++
++static void ast1070_c0_unmask_irq(unsigned int irq)
++{
++ u32 regVal;
++// printk("ast_c0_unmask_irq %d\n",irq);
++ irq = irq_to_c0_vic(irq);
++// printk("ast_c0_unmask_irq cvic %d\n",irq);
++ regVal = readl(AST_INTR_EN(0));
++ regVal |= (1 << irq);
++ writel(regVal, AST_INTR_EN(0));
++}
++
++static struct irq_chip ast1070_c0_irq_chip = {
++ .name = "ast1070_c0",
++ .ack = ast1070_c0_mask_irq,
++ .mask = ast1070_c0_mask_irq,
++ .unmask = ast1070_c0_unmask_irq,
++};
++
++static void
++ast1070_c0_handle_irq(unsigned int irq, struct irq_desc *desc)
++{
++ int i,cvic_irq=0;
++ unsigned long sts = readl(AST_IRQ_STS(0));
++
++ if(irq != IRQ_C0_VIC_CHAIN)
++ BUG();
++
++ desc->chip->ack(IRQ_C0_VIC_CHAIN);
++
++ if (sts == 0) {
++ do_bad_IRQ(irq, desc);
++ return;
++ }
++
++ do {
++ for(i=0; i<AST_CVIC_NUM; i++) {
++ if((1<<i)& readl(AST_IRQ_STS(0))) {
++ cvic_irq =i;
++ break;
++ }
++ }
++ cvic_irq += IRQ_C0_VIC_CHAIN_START;
++ //dispatch IRQ
++// printk("dispatch ast1070 IRQ %d\n",cvic_irq);
++ generic_handle_irq(cvic_irq);
++
++ } while (readl(AST_IRQ_STS(0)));
++
++ desc->chip->unmask(IRQ_C0_VIC_CHAIN);
++
++}
++
++static int __init ast1070_c0_init_irq(void)
++{
++ unsigned int i;
++// printk("ast1070_c0_init_irq **==== Start ---------------\n");
++ /* CVIC */
++ writel(0, AST_INTR_EN(0));
++ writel(0xFFFFFFFF, AST_INTR_DIS(0));
++
++ //AST1070 total IRQ# 25
++ for (i = 0; i < AST_CVIC_NUM; i++)
++ {
++ IRQ_SET_HIGH_LEVEL(0,i);
++ IRQ_SET_LEVEL_TRIGGER(0,i);
++ set_irq_chip(i + IRQ_C0_VIC_CHAIN_START, &ast1070_c0_irq_chip);
++ set_irq_handler(i + IRQ_C0_VIC_CHAIN_START, handle_level_irq);
++ set_irq_flags(i + IRQ_C0_VIC_CHAIN_START, IRQF_VALID);
++ }
++ set_irq_chained_handler(IRQ_C0_VIC_CHAIN, ast1070_c0_handle_irq);
++// printk("ast1070_init_irq **==== END ----------\n");
++ return 0;
++}
++
++arch_initcall(ast1070_c0_init_irq);
++
++#if (CONFIG_AST1070_NR >= 2)
++#define irq_to_c1_vic(irq_no) (irq_no-IRQ_C1_VIC_CHAIN_START)
++
++static void ast1070_c1_mask_irq(unsigned int irq)
++{
++ u32 regVal;
++// printk("ast_mask_irq %d\n",irq);
++ irq = irq_to_c1_vic(irq);
++// printk("ast_mask_irq cvic %d\n",irq);
++ regVal = readl(AST_INTR_DIS(1));
++ regVal |= (1 << irq);
++ writel(regVal, AST_INTR_DIS(1));
++
++}
++
++static void ast1070_c1_unmask_irq(unsigned int irq)
++{
++ u32 regVal;
++// printk("ast_unmask_irq %d\n",irq);
++ irq = irq_to_c1_vic(irq);
++// printk("ast_unmask_irq cvic %d\n",irq);
++ regVal = readl(AST_INTR_EN(1));
++ regVal |= (1 << irq);
++ writel(regVal, AST_INTR_EN(1));
++}
++
++static struct irq_chip ast1070_c1_irq_chip = {
++ .name = "ast1070_c1",
++ .ack = ast1070_c1_mask_irq,
++ .mask = ast1070_c1_mask_irq,
++ .unmask = ast1070_c1_unmask_irq,
++};
++
++static void
++ast1070_c1_handle_irq(unsigned int irq, struct irq_desc *desc)
++{
++ int i,cvic_irq=0;
++ unsigned long sts = readl(AST_IRQ_STS(1));
++
++ if(irq != IRQ_C1_VIC_CHAIN)
++ BUG();
++
++ desc->chip->ack(IRQ_C1_VIC_CHAIN);
++
++ if (sts == 0) {
++ do_bad_IRQ(irq, desc);
++ return;
++ }
++
++ do {
++ for(i=0; i<AST_CVIC_NUM; i++) {
++ if((1<<i)& readl(AST_IRQ_STS(1))) {
++ cvic_irq =i;
++ break;
++ }
++ }
++ cvic_irq += IRQ_C1_VIC_CHAIN_START;
++ //dispatch IRQ
++// printk("dispatch ast1070 IRQ %d\n",cvic_irq);
++ generic_handle_irq(cvic_irq);
++
++ } while (readl(AST_IRQ_STS(1)));
++
++ desc->chip->unmask(IRQ_C1_VIC_CHAIN);
++
++}
++
++static int __init ast1070_c1_init_irq(void)
++{
++ unsigned int i;
++// printk("ast1070_c1_init_irq **==== Start ---------------\n");
++ /* CVIC */
++ writel(0, AST_INTR_EN(1));
++ writel(0xFFFFFFFF, AST_INTR_DIS(1));
++
++ //AST1070 total IRQ# 25
++ for (i = 0; i < AST_CVIC_NUM; i++)
++ {
++ IRQ_SET_HIGH_LEVEL(1,i);
++ IRQ_SET_LEVEL_TRIGGER(1,i);
++ set_irq_chip(i + IRQ_C1_VIC_CHAIN_START, &ast1070_c1_irq_chip);
++ set_irq_handler(i + IRQ_C1_VIC_CHAIN_START, handle_level_irq);
++ set_irq_flags(i + IRQ_C1_VIC_CHAIN_START, IRQF_VALID);
++ }
++ set_irq_chained_handler(IRQ_C1_VIC_CHAIN, ast1070_c1_handle_irq);
++// printk("ast1070_init_irq **==== END ----------\n");
++ return 0;
++}
++
++arch_initcall(ast1070_c1_init_irq);
++
++#endif
+diff --git a/arch/arm/plat-aspeed/dev-adc.c b/arch/arm/plat-aspeed/dev-adc.c
+new file mode 100644
+index 0000000..e8d325a
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-adc.c
+@@ -0,0 +1,76 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-adc.c
++* Author : Ryan chen
++* Description : ASPEED ADC Device
++*
++* Copyright (C) ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/08/06 ryan chen create this file
++*
++********************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++
++#if defined(CONFIG_COLDFIRE)
++#include <asm/sizes.h>
++
++#include <asm/arch/irqs.h>
++#include <asm/arch/platform.h>
++#include <asm/arch/devs.h>
++#include <asm/arch/ast-scu.h>
++#else
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <plat/devs.h>
++#include <plat/ast-scu.h>
++#endif
++
++/* --------------------------------------------------------------------
++ * ADC
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_SENSORS_AST_ADC) || defined(CONFIG_SENSORS_AST_ADC_MODULE) || defined(CONFIG_SENSORS_AST1010_ADC) || defined(CONFIG_SENSORS_AST1010_ADC_MODULE)
++static struct resource ast_adc_resources[] = {
++ [0] = {
++ .start = AST_ADC_BASE,
++ .end = AST_ADC_BASE + SZ_4K - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_ADC,
++ .end = IRQ_ADC,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_adc_device = {
++ .name = "ast_adc",
++ .id = 0,
++ .resource = ast_adc_resources,
++ .num_resources = ARRAY_SIZE(ast_adc_resources),
++};
++
++void __init ast_add_device_adc(void)
++{
++ //SCU ADC CTRL Reset
++ ast_scu_init_adc();
++
++ platform_device_register(&ast_adc_device);
++}
++#else
++void __init ast_add_device_adc(void) {}
++#endif
+diff --git a/arch/arm/plat-aspeed/dev-ci2c.c b/arch/arm/plat-aspeed/dev-ci2c.c
+new file mode 100644
+index 0000000..875639f
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-ci2c.c
+@@ -0,0 +1,521 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-ci2c.c
++* Author : Ryan chen
++* Description : ASPEED I2C Device
++*
++* Copyright (C) ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/07/30 ryan chen create this file
++*
++********************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++#include <linux/i2c.h>
++
++#include <asm/io.h>
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <plat/ast_i2c.h>
++
++#include <plat/devs.h>
++#include <plat/regs-iic.h>
++#include <plat/ast-scu.h>
++#include <plat/ast1070-scu.h>
++/* --------------------------------------------------------------------
++ * CI2C
++ * -------------------------------------------------------------------- */
++#if defined(CONFIG_I2C_AST1070) || defined(CONFIG_I2C_AST1070_MODULE)
++
++static struct ast_i2c_driver_data ast_ci2c_data = {
++ .bus_clk = 100000, //bus clock 100KHz
++ .master_dma = DMA_MODE,
++ .slave_dma = BYTE_MODE,
++#ifdef CONFIG_AST_I2C_SLAVE_MODE
++ .slave_xfer = i2c_slave_xfer,
++ .slave_init = i2c_slave_init,
++#endif
++#ifdef CONFIG_AST_LPC_PLUS
++ //use lpc+ clock
++ .get_i2c_clock = ast_get_lhclk,
++#else
++ .get_i2c_clock = ast_get_d2_pll_clk,
++#endif
++};
++
++static u64 ast_i2c_dma_mask = 0xffffffffUL;
++static struct resource ast_ci2c_dev1_resources[] = {
++ [0] = {
++ .start = AST_C0_I2C_BASE + AST_CI2C_DEVICE1,
++ .end = AST_C0_I2C_BASE + AST_CI2C_DEVICE1 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_C0_I2C,
++ .end = IRQ_C0_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_ci2c_dev1_device = {
++ .name = "ast-i2c",
++ .id = NUM_BUS + 0,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_ci2c_data,
++ },
++ .resource = ast_ci2c_dev1_resources,
++ .num_resources = ARRAY_SIZE(ast_ci2c_dev1_resources),
++};
++
++static struct resource ast_ci2c_dev2_resources[] = {
++ [0] = {
++ .start = AST_C0_I2C_BASE + AST_CI2C_DEVICE2,
++ .end = AST_C0_I2C_BASE + AST_CI2C_DEVICE2 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_C0_I2C,
++ .end = IRQ_C0_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_ci2c_dev2_device = {
++ .name = "ast-i2c",
++ .id = NUM_BUS + 1,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_ci2c_data,
++ },
++ .resource = ast_ci2c_dev2_resources,
++ .num_resources = ARRAY_SIZE(ast_ci2c_dev2_resources),
++};
++
++static struct resource ast_ci2c_dev3_resources[] = {
++ [0] = {
++ .start = AST_C0_I2C_BASE + AST_CI2C_DEVICE3,
++ .end = AST_C0_I2C_BASE + AST_CI2C_DEVICE3 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_C0_I2C,
++ .end = IRQ_C0_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_ci2c_dev3_device = {
++ .name = "ast-i2c",
++ .id = NUM_BUS + 2,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_ci2c_data,
++ },
++ .resource = ast_ci2c_dev3_resources,
++ .num_resources = ARRAY_SIZE(ast_ci2c_dev3_resources),
++};
++
++static struct resource ast_ci2c_dev4_resources[] = {
++ [0] = {
++ .start = AST_C0_I2C_BASE + AST_CI2C_DEVICE4,
++ .end = AST_C0_I2C_BASE + AST_CI2C_DEVICE4 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_C0_I2C,
++ .end = IRQ_C0_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_ci2c_dev4_device = {
++ .name = "ast-i2c",
++ .id = NUM_BUS + 3,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_ci2c_data,
++ },
++ .resource = ast_ci2c_dev4_resources,
++ .num_resources = ARRAY_SIZE(ast_ci2c_dev4_resources),
++};
++
++static struct resource ast_ci2c_dev5_resources[] = {
++ [0] = {
++ .start = AST_C0_I2C_BASE + AST_CI2C_DEVICE5,
++ .end = AST_C0_I2C_BASE + AST_CI2C_DEVICE5 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_C0_I2C,
++ .end = IRQ_C0_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_ci2c_dev5_device = {
++ .name = "ast-i2c",
++ .id = NUM_BUS + 4,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_ci2c_data,
++ },
++ .resource = ast_ci2c_dev5_resources,
++ .num_resources = ARRAY_SIZE(ast_ci2c_dev5_resources),
++};
++
++static struct resource ast_ci2c_dev6_resources[] = {
++ [0] = {
++ .start = AST_C0_I2C_BASE + AST_CI2C_DEVICE6,
++ .end = AST_C0_I2C_BASE + AST_CI2C_DEVICE6 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_C0_I2C,
++ .end = IRQ_C0_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_ci2c_dev6_device = {
++ .name = "ast-i2c",
++ .id = NUM_BUS + 5,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_ci2c_data,
++ },
++ .resource = ast_ci2c_dev6_resources,
++ .num_resources = ARRAY_SIZE(ast_ci2c_dev6_resources),
++};
++
++static struct resource ast_ci2c_dev7_resources[] = {
++ [0] = {
++ .start = AST_C0_I2C_BASE + AST_CI2C_DEVICE7,
++ .end = AST_C0_I2C_BASE + AST_CI2C_DEVICE7 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_C0_I2C,
++ .end = IRQ_C0_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_ci2c_dev7_device = {
++ .name = "ast-i2c",
++ .id = NUM_BUS + 6,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_ci2c_data,
++ },
++ .resource = ast_ci2c_dev7_resources,
++ .num_resources = ARRAY_SIZE(ast_ci2c_dev7_resources),
++};
++
++static struct resource ast_ci2c_dev8_resources[] = {
++ [0] = {
++ .start = AST_C0_I2C_BASE + AST_CI2C_DEVICE8,
++ .end = AST_C0_I2C_BASE + AST_CI2C_DEVICE8 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_C0_I2C,
++ .end = IRQ_C0_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_ci2c_dev8_device = {
++ .name = "ast-i2c",
++ .id = NUM_BUS + 7,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_ci2c_data,
++ },
++ .resource = ast_ci2c_dev8_resources,
++ .num_resources = ARRAY_SIZE(ast_ci2c_dev8_resources),
++};
++
++//
++#if (CONFIG_AST1070_NR >= 2)
++
++static struct ast_i2c_driver_data ast_c1_i2c_data = {
++ .bus_clk = 100000, //bus clock 100KHz
++ .master_dma = DMA_MODE,
++ .slave_dma = BYTE_MODE,
++#ifdef CONFIG_AST_I2C_SLAVE_MODE
++ .slave_xfer = i2c_slave_xfer,
++ .slave_init = i2c_slave_init,
++#endif
++#ifdef CONFIG_ARCH_AST2300
++ .get_i2c_clock = ast_get_d2_pll_clk,
++#else //AST2400 use lpc+ clock
++ .get_i2c_clock = ast_get_lhclk,
++#endif
++};
++
++static struct resource ast_c1_i2c_dev1_resources[] = {
++ [0] = {
++ .start = AST_C1_I2C_BASE + AST_CI2C_DEVICE1,
++ .end = AST_C1_I2C_BASE + AST_CI2C_DEVICE1 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_C1_I2C,
++ .end = IRQ_C1_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_c1_i2c_dev1_device = {
++ .name = "ast-i2c",
++ .id = NUM_BUS + 8 + 0,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_c1_i2c_data,
++ },
++ .resource = ast_c1_i2c_dev1_resources,
++ .num_resources = ARRAY_SIZE(ast_c1_i2c_dev1_resources),
++};
++
++static struct resource ast_c1_i2c_dev2_resources[] = {
++ [0] = {
++ .start = AST_C1_I2C_BASE + AST_CI2C_DEVICE2,
++ .end = AST_C1_I2C_BASE + AST_CI2C_DEVICE2 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_C1_I2C,
++ .end = IRQ_C1_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_c1_i2c_dev2_device = {
++ .name = "ast-i2c",
++ .id = NUM_BUS + 8 + 1,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_c1_i2c_data,
++ },
++ .resource = ast_c1_i2c_dev2_resources,
++ .num_resources = ARRAY_SIZE(ast_c1_i2c_dev2_resources),
++};
++
++static struct resource ast_c1_i2c_dev3_resources[] = {
++ [0] = {
++ .start = AST_C1_I2C_BASE + AST_CI2C_DEVICE3,
++ .end = AST_C1_I2C_BASE + AST_CI2C_DEVICE3 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_C1_I2C,
++ .end = IRQ_C1_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_c1_i2c_dev3_device = {
++ .name = "ast-i2c",
++ .id = NUM_BUS + 8 + 2,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_c1_i2c_data,
++ },
++ .resource = ast_c1_i2c_dev3_resources,
++ .num_resources = ARRAY_SIZE(ast_c1_i2c_dev3_resources),
++};
++
++static struct resource ast_c1_i2c_dev4_resources[] = {
++ [0] = {
++ .start = AST_C1_I2C_BASE + AST_CI2C_DEVICE4,
++ .end = AST_C1_I2C_BASE + AST_CI2C_DEVICE4 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_C1_I2C,
++ .end = IRQ_C1_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_c1_i2c_dev4_device = {
++ .name = "ast-i2c",
++ .id = NUM_BUS + 8 + 3,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_c1_i2c_data,
++ },
++ .resource = ast_c1_i2c_dev4_resources,
++ .num_resources = ARRAY_SIZE(ast_c1_i2c_dev4_resources),
++};
++
++static struct resource ast_c1_i2c_dev5_resources[] = {
++ [0] = {
++ .start = AST_C1_I2C_BASE + AST_CI2C_DEVICE5,
++ .end = AST_C1_I2C_BASE + AST_CI2C_DEVICE5 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_C1_I2C,
++ .end = IRQ_C1_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_c1_i2c_dev5_device = {
++ .name = "ast-i2c",
++ .id = NUM_BUS + 8 + 4,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_c1_i2c_data,
++ },
++ .resource = ast_c1_i2c_dev5_resources,
++ .num_resources = ARRAY_SIZE(ast_c1_i2c_dev5_resources),
++};
++
++static struct resource ast_c1_i2c_dev6_resources[] = {
++ [0] = {
++ .start = AST_C1_I2C_BASE + AST_CI2C_DEVICE6,
++ .end = AST_C1_I2C_BASE + AST_CI2C_DEVICE6 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_C1_I2C,
++ .end = IRQ_C1_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_c1_i2c_dev6_device = {
++ .name = "ast-i2c",
++ .id = NUM_BUS + 8 + 5,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_c1_i2c_data,
++ },
++ .resource = ast_c1_i2c_dev6_resources,
++ .num_resources = ARRAY_SIZE(ast_c1_i2c_dev6_resources),
++};
++
++static struct resource ast_c1_i2c_dev7_resources[] = {
++ [0] = {
++ .start = AST_C1_I2C_BASE + AST_CI2C_DEVICE7,
++ .end = AST_C1_I2C_BASE + AST_CI2C_DEVICE7 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_C1_I2C,
++ .end = IRQ_C1_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_c1_i2c_dev7_device = {
++ .name = "ast-i2c",
++ .id = NUM_BUS + 8 + 6,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_c1_i2c_data,
++ },
++ .resource = ast_c1_i2c_dev7_resources,
++ .num_resources = ARRAY_SIZE(ast_c1_i2c_dev7_resources),
++};
++
++static struct resource ast_c1_i2c_dev8_resources[] = {
++ [0] = {
++ .start = AST_C1_I2C_BASE + AST_CI2C_DEVICE8,
++ .end = AST_C1_I2C_BASE + AST_CI2C_DEVICE8 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_C1_I2C,
++ .end = IRQ_C1_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_c1_i2c_dev8_device = {
++ .name = "ast-i2c",
++ .id = NUM_BUS + 8 + 7,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_c1_i2c_data,
++ },
++ .resource = ast_c1_i2c_dev8_resources,
++ .num_resources = ARRAY_SIZE(ast_c1_i2c_dev8_resources),
++};
++#endif
++//
++/*-------------------------------------*/
++void __init ast_add_device_ci2c(void)
++{
++ ast1070_scu_init_i2c(0);
++
++ ast_ci2c_data.reg_gr = IO_ADDRESS2(AST_C0_I2C_BASE);
++ if (!ast_ci2c_data.reg_gr) {
++ printk("ast_add_device_i2c ERROR \n");
++ return;
++ }
++ platform_device_register(&ast_ci2c_dev1_device);
++ platform_device_register(&ast_ci2c_dev2_device);
++ platform_device_register(&ast_ci2c_dev3_device);
++ platform_device_register(&ast_ci2c_dev4_device);
++ platform_device_register(&ast_ci2c_dev5_device);
++ platform_device_register(&ast_ci2c_dev6_device);
++ platform_device_register(&ast_ci2c_dev7_device);
++ platform_device_register(&ast_ci2c_dev8_device);
++
++
++#if (CONFIG_AST1070_NR >= 2)
++
++ ast1070_scu_init_i2c(1);
++
++ ast_c1_i2c_data.reg_gr = IO_ADDRESS2(AST_C1_I2C_BASE);
++ if (!ast_c1_i2c_data.reg_gr) {
++ printk("ast_add_device_i2c ERROR \n");
++ return;
++ }
++ platform_device_register(&ast_c1_i2c_dev1_device);
++ platform_device_register(&ast_c1_i2c_dev2_device);
++ platform_device_register(&ast_c1_i2c_dev3_device);
++ platform_device_register(&ast_c1_i2c_dev4_device);
++ platform_device_register(&ast_c1_i2c_dev5_device);
++ platform_device_register(&ast_c1_i2c_dev6_device);
++ platform_device_register(&ast_c1_i2c_dev7_device);
++ platform_device_register(&ast_c1_i2c_dev8_device);
++#endif
++
++}
++#else
++void __init ast_add_device_ci2c(void) {}
++#endif
+diff --git a/arch/arm/plat-aspeed/dev-clpc.c b/arch/arm/plat-aspeed/dev-clpc.c
+new file mode 100644
+index 0000000..d9fde7a
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-clpc.c
+@@ -0,0 +1,240 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-clpc.c
++* Author : Ryan chen
++* Description : ASPEED LPC Controller
++*
++* Copyright (C) ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/11/29 ryan chen create this file
++*
++********************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <plat/devs.h>
++#include <plat/ast-scu.h>
++
++
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <plat/devs.h>
++#include <plat/ast-scu.h>
++
++
++/* --------------------------------------------------------------------
++ * LPC
++ * -------------------------------------------------------------------- */
++#if defined(CONFIG_CLPC) || defined(CONFIG_CLPC_MODULE)
++static u64 aspeed_lpc_dma_mask = 0xffffffffUL;
++
++static struct resource aspeed_clpc0_resource[] = {
++ [0] = {
++ .start = AST_CLPC1_BASE,
++ .end = AST_CLPC1_BASE + SZ_4K,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_N1_KCS,
++ .end = IRQ_N1_KCS,
++ .flags = IORESOURCE_IRQ,
++ },
++ [2] = {
++ .start = IRQ_N1_UART,
++ .end = IRQ_N1_UART,
++ .flags = IORESOURCE_IRQ,
++ },
++ [3] = {
++ .start = IRQ_N1_MAILBOX,
++ .end = IRQ_N1_MAILBOX,
++ .flags = IORESOURCE_IRQ,
++ },
++ [4] = {
++ .start = IRQ_N1_PORT80,
++ .end = IRQ_N1_PORT80,
++ .flags = IORESOURCE_IRQ,
++ },
++ [4] = {
++ .start = IRQ_N1_RESET,
++ .end = IRQ_N1_RESET,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device aspeed_clpc0_device = {
++ .name = "aspeed_lpc",
++ .id = 0,
++ .dev = {
++ .dma_mask = &aspeed_lpc_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ },
++ .resource = aspeed_clpc0_resource,
++ .num_resources = ARRAY_SIZE(aspeed_clpc0_resource),
++};
++
++static struct resource aspeed_clpc1_resource[] = {
++ [0] = {
++ .start = AST_CLPC2_BASE,
++ .end = AST_CLPC2_BASE + SZ_4K,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_N2_KCS,
++ .end = IRQ_N2_KCS,
++ .flags = IORESOURCE_IRQ,
++ },
++ [2] = {
++ .start = IRQ_N2_UART,
++ .end = IRQ_N2_UART,
++ .flags = IORESOURCE_IRQ,
++ },
++ [3] = {
++ .start = IRQ_N2_MAILBOX,
++ .end = IRQ_N2_MAILBOX,
++ .flags = IORESOURCE_IRQ,
++ },
++ [4] = {
++ .start = IRQ_N2_PORT80,
++ .end = IRQ_N2_PORT80,
++ .flags = IORESOURCE_IRQ,
++ },
++ [4] = {
++ .start = IRQ_N2_RESET,
++ .end = IRQ_N2_RESET,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device aspeed_clpc1_device = {
++ .name = "aspeed_lpc",
++ .id = 1,
++ .dev = {
++ .dma_mask = &aspeed_lpc_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ },
++ .resource = aspeed_clpc1_resource,
++ .num_resources = ARRAY_SIZE(aspeed_clpc1_resource),
++};
++
++static struct resource aspeed_clpc2_resource[] = {
++ [0] = {
++ .start = AST_CLPC3_BASE,
++ .end = AST_CLPC3_BASE + SZ_4K,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_N3_KCS,
++ .end = IRQ_N3_KCS,
++ .flags = IORESOURCE_IRQ,
++ },
++ [2] = {
++ .start = IRQ_N3_UART,
++ .end = IRQ_N3_UART,
++ .flags = IORESOURCE_IRQ,
++ },
++ [3] = {
++ .start = IRQ_N3_MAILBOX,
++ .end = IRQ_N3_MAILBOX,
++ .flags = IORESOURCE_IRQ,
++ },
++ [4] = {
++ .start = IRQ_N3_PORT80,
++ .end = IRQ_N3_PORT80,
++ .flags = IORESOURCE_IRQ,
++ },
++ [4] = {
++ .start = IRQ_N3_RESET,
++ .end = IRQ_N3_RESET,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device aspeed_clpc2_device = {
++ .name = "aspeed_lpc",
++ .id = 2,
++ .dev = {
++ .dma_mask = &aspeed_lpc_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ },
++ .resource = aspeed_clpc2_resource,
++ .num_resources = ARRAY_SIZE(aspeed_clpc2_resource),
++};
++
++static struct resource aspeed_clpc3_resource[] = {
++ [0] = {
++ .start = AST_CLPC4_BASE,
++ .end = AST_CLPC4_BASE + SZ_4K,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_N4_KCS,
++ .end = IRQ_N4_KCS,
++ .flags = IORESOURCE_IRQ,
++ },
++ [2] = {
++ .start = IRQ_N4_UART,
++ .end = IRQ_N4_UART,
++ .flags = IORESOURCE_IRQ,
++ },
++ [3] = {
++ .start = IRQ_N4_MAILBOX,
++ .end = IRQ_N4_MAILBOX,
++ .flags = IORESOURCE_IRQ,
++ },
++ [4] = {
++ .start = IRQ_N4_PORT80,
++ .end = IRQ_N4_PORT80,
++ .flags = IORESOURCE_IRQ,
++ },
++ [4] = {
++ .start = IRQ_N4_RESET,
++ .end = IRQ_N4_RESET,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device aspeed_clpc3_device = {
++ .name = "aspeed_lpc",
++ .id = 3,
++ .dev = {
++ .dma_mask = &aspeed_lpc_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ },
++ .resource = aspeed_clpc3_resource,
++ .num_resources = ARRAY_SIZE(aspeed_clpc3_resource),
++};
++
++void __init aspeed_add_device_clpc(void)
++{
++// it should enable at u-boot
++// aspeed_scu_init_lpc();
++
++ platform_device_register(&aspeed_clpc0_device);
++ platform_device_register(&aspeed_clpc1_device);
++ platform_device_register(&aspeed_clpc2_device);
++ platform_device_register(&aspeed_clpc3_device);
++}
++#else
++void __init aspeed_add_device_clpc(void) {}
++#endif
++
+diff --git a/arch/arm/plat-aspeed/dev-cuart.c b/arch/arm/plat-aspeed/dev-cuart.c
+new file mode 100644
+index 0000000..8731f7c
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-cuart.c
+@@ -0,0 +1,197 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-cuart.c
++* Author : Ryan chen
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/09/15 ryan chen create this file
++*
++********************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++#include <linux/serial.h>
++#include <linux/tty.h>
++#include <linux/serial_8250.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <mach/hardware.h>
++#include <mach/ast-uart-dma.h>
++
++#include <plat/ast1070-devs.h>
++#include <plat/ast1070-scu.h>
++
++/* --------------------------------------------------------------------
++ * UART
++ * -------------------------------------------------------------------- */
++#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_ARCH_AST1070)
++static struct ast_uart_dma_data c0_uart0_dma_data = {
++ .chip_no = 0,
++ .dma_ch = 0,
++};
++
++static struct ast_uart_dma_data c0_uart1_dma_data = {
++ .chip_no = 0,
++ .dma_ch = 1,
++};
++
++static struct ast_uart_dma_data c0_uart2_dma_data = {
++ .chip_no = 0,
++ .dma_ch = 2,
++};
++
++static struct ast_uart_dma_data c0_uart3_dma_data = {
++ .chip_no = 0,
++ .dma_ch = 3,
++};
++
++#if (CONFIG_AST1070_NR >=2)
++static struct ast_uart_dma_data c1_uart0_dma_data = {
++ .chip_no = 1,
++ .dma_ch = 0,
++};
++
++static struct ast_uart_dma_data c1_uart1_dma_data = {
++ .chip_no = 1,
++ .dma_ch = 1,
++};
++
++static struct ast_uart_dma_data c1_uart2_dma_data = {
++ .chip_no = 1,
++ .dma_ch = 2,
++};
++
++static struct ast_uart_dma_data c1_uart3_dma_data = {
++ .chip_no = 1,
++ .dma_ch = 3,
++};
++#endif
++
++static struct plat_serial8250_port ast1070_c_uart_data[] = {
++ {
++ .mapbase = AST_C0_UART0_BASE,
++ .membase = (char*)(IO_ADDRESS2(AST_C0_UART0_BASE)),
++ .irq = IRQ_C0_N1_UART,
++ .uartclk = (24*1000000L),
++ .regshift = 2,
++ .iotype = UPIO_MEM,
++ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++ .private_data = &c0_uart0_dma_data,
++ },
++ {
++ .mapbase = AST_C0_UART1_BASE,
++ .membase = (char*)(IO_ADDRESS2(AST_C0_UART1_BASE)),
++ .irq = IRQ_C0_N2_UART,
++ .uartclk = (24*1000000L),
++ .regshift = 2,
++ .iotype = UPIO_MEM,
++ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++ .private_data = &c0_uart1_dma_data,
++ },
++ {
++ .mapbase = AST_C0_UART2_BASE,
++ .membase = (char*)(IO_ADDRESS2(AST_C0_UART2_BASE)),
++ .irq = IRQ_C0_N3_UART,
++ .uartclk = (24*1000000L),
++ .regshift = 2,
++ .iotype = UPIO_MEM,
++ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++ .private_data = &c0_uart2_dma_data,
++ },
++ {
++ .mapbase = AST_C0_UART3_BASE,
++ .membase = (char*)(IO_ADDRESS2(AST_C0_UART3_BASE)),
++ .irq = IRQ_C0_N4_UART,
++ .uartclk = (24*1000000L),
++ .regshift = 2,
++ .iotype = UPIO_MEM,
++ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++ .private_data = &c0_uart3_dma_data,
++ },
++#if (CONFIG_AST1070_NR >=2)
++ {
++ .mapbase = AST_C1_UART0_BASE,
++ .membase = (char*)(IO_ADDRESS2(AST_C1_UART0_BASE)),
++ .irq = IRQ_C1_N1_UART,
++ .uartclk = (24*1000000L),
++ .regshift = 2,
++ .iotype = UPIO_MEM,
++ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++ .private_data = &c1_uart0_dma_data,
++ },
++ {
++ .mapbase = AST_C1_UART1_BASE,
++ .membase = (char*)(IO_ADDRESS2(AST_C1_UART1_BASE)),
++ .irq = IRQ_C1_N2_UART,
++ .uartclk = (24*1000000L),
++ .regshift = 2,
++ .iotype = UPIO_MEM,
++ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++ .private_data = &c1_uart1_dma_data,
++ },
++ {
++ .mapbase = AST_C1_UART2_BASE,
++ .membase = (char*)(IO_ADDRESS2(AST_C1_UART2_BASE)),
++ .irq = IRQ_C1_N3_UART,
++ .uartclk = (24*1000000L),
++ .regshift = 2,
++ .iotype = UPIO_MEM,
++ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++ .private_data = &c1_uart2_dma_data,
++ },
++ {
++ .mapbase = AST_C1_UART3_BASE,
++ .membase = (char*)(IO_ADDRESS2(AST_C1_UART3_BASE)),
++ .irq = IRQ_C1_N4_UART,
++ .uartclk = (24*1000000L),
++ .regshift = 2,
++ .iotype = UPIO_MEM,
++ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++ .private_data = &c1_uart3_dma_data,
++ },
++#endif
++ { },
++};
++
++struct platform_device ast1070_c_uart_device = {
++#ifdef CONFIG_SERIAL_AST_DMA_UART
++ .name = "ast-uart-dma",
++#else
++ .name = "serial8250",
++#endif
++ .id = PLAT8250_DEV_PLATFORM1,
++ .dev = {
++ .platform_data = ast1070_c_uart_data,
++ },
++};
++
++void __init ast_add_device_cuart(void)
++{
++ int i;//j;
++ for(i=0;i<CONFIG_AST1070_NR;i++) {
++ //reset 4 UART
++ ast1070_scu_init_uart(i);
++ //Please don't enable : Feature remove
++// for(j=0;j<4;j++)
++// ast1070_multi_func_uart(i, j);
++ }
++
++ platform_device_register(&ast1070_c_uart_device);
++}
++#else
++void __init ast_add_device_cuart(void) {}
++#endif
+diff --git a/arch/arm/plat-aspeed/dev-ehci.c b/arch/arm/plat-aspeed/dev-ehci.c
+new file mode 100644
+index 0000000..8c34a63
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-ehci.c
+@@ -0,0 +1,73 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-ehci.c
++* Author : Ryan chen
++* Description : ASPEED EHCI Device
++*
++* Copyright (C) ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/07/30 ryan chen create this file
++*
++********************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <plat/devs.h>
++#include <plat/ast-scu.h>
++
++
++/* --------------------------------------------------------------------
++ * EHCI
++ * -------------------------------------------------------------------- */
++#if defined(CONFIG_USB_EHCI_AST) || defined(CONFIG_USB_EHCI_AST_MODULE)
++static struct resource ast_echi_resource[] = {
++ [0] = {
++ .start = AST_EHCI_BASE,
++ .end = AST_EHCI_BASE + SZ_256,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_EHCI,
++ .end = IRQ_EHCI,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static u64 ast_ehci_dma_mask = 0xffffffffUL;
++
++static struct platform_device ast_ehci_device = {
++ .name = "ehci-ast",
++ .id = 0,
++ .dev = {
++ .dma_mask = &ast_ehci_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ },
++ .resource = ast_echi_resource,
++ .num_resources = ARRAY_SIZE(ast_echi_resource),
++};
++
++void __init ast_add_device_ehci(void)
++{
++ ast_scu_multi_func_usb20_host_hub(1);
++ ast_scu_init_usb20();
++
++ platform_device_register(&ast_ehci_device);
++}
++#else
++void __init ast_add_device_ehci(void) {}
++#endif
+diff --git a/arch/arm/plat-aspeed/dev-eth.c b/arch/arm/plat-aspeed/dev-eth.c
+new file mode 100644
+index 0000000..5d33e33
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-eth.c
+@@ -0,0 +1,201 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-eth.c
++* Author : Ryan Chen
++* Description : Aspeed Ethernet Device
++*
++* Copyright (C) ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/08/24 Ryan Chen initial
++*
++********************************************************************************/
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <mach/ftgmac100_drv.h>
++
++#include <plat/devs.h>
++#include <plat/ast-scu.h>
++
++/* --------------------------------------------------------------------
++ * Ethernet
++ * -------------------------------------------------------------------- */
++#if defined(CONFIG_ASPEEDMAC) || defined(CONFIG_ASPEEDMAC_MODULE)
++#ifdef AST_MAC0_BASE
++static struct ftgmac100_eth_data ast_eth0_data = {
++ .dev_addr = { 0x00, 0x84, 0x14, 0xA0, 0xB0, 0x22},
++ .phy_id = 1,
++};
++
++static u64 ast_eth_dmamask = 0xffffffffUL;
++static struct resource ast_mac0_resources[] = {
++ [0] = {
++ .start = AST_MAC0_BASE,
++ .end = AST_MAC0_BASE + SZ_128K - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_MAC0,
++ .end = IRQ_MAC0,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device ast_eth0_device = {
++ .name = "ast_gmac",
++ .id = 0,
++ .dev = {
++ .dma_mask = &ast_eth_dmamask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_eth0_data,
++ },
++ .resource = ast_mac0_resources,
++ .num_resources = ARRAY_SIZE(ast_mac0_resources),
++};
++#endif
++#ifdef AST_MAC1_BASE
++static struct ftgmac100_eth_data ast_eth1_data = {
++ .dev_addr = { 0x00, 0x84, 0x14, 0xA0, 0xB0, 0x23},
++ .phy_id = 1,
++};
++
++static struct resource ast_mac1_resources[] = {
++ [0] = {
++ .start = AST_MAC1_BASE,
++ .end = AST_MAC1_BASE + SZ_128K - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_MAC1,
++ .end = IRQ_MAC1,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device ast_eth1_device = {
++ .name = "ast_gmac",
++ .id = 1,
++ .dev = {
++ .dma_mask = &ast_eth_dmamask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_eth1_data,
++ },
++ .resource = ast_mac1_resources,
++ .num_resources = ARRAY_SIZE(ast_mac1_resources),
++};
++#endif
++
++/*
++ * MAC1 always has MII MDC+MDIO pins to access PHY registers. We assume MAC1
++ * always has a PHY chip, if MAC1 is enabled.
++ * U-Boot can enable MAC2 MDC+MDIO pins for a 2nd PHY, or MAC2 might be
++ * disabled (only one port), or it's sideband-RMII which has no PHY chip.
++ *
++ * Return miiPhyId==0 if the MAC cannot be accessed.
++ * Return miiPhyId==1 if the MAC registers are OK but it cannot carry traffic.
++ * Return miiPhyId==2 if the MAC can send/receive but it has no PHY chip.
++ * Else return the PHY 22-bit vendor ID, 6-bit model and 4-bit revision.
++ */
++
++void __init ast_add_device_gmac(void)
++{
++
++ u8 phy_mode,phy_inter;
++ u32 isRevA0;
++ u32 rev_id;
++
++ rev_id = ast_scu_revision_id() & 0xff;
++
++
++ if (rev_id >= 0x08 && rev_id <= 0x0f) {
++ // AST2100 FPGA board: up to 10 means rev.A0, 11 means rev.A1
++ isRevA0 = (rev_id < 11);
++ } else {
++ // Real silicon: rev.A0 has 0x00 in bits[7:0]. rev A2 = 0x02 in bits[7:0]
++ isRevA0 = 0; //((regVal & 0x00ff) == 0x00);
++// out->isRevA2 = 1; //((regVal & 0x00ff) == 0x02);
++ }
++
++ ast_eth0_data.DF_support = !isRevA0;
++
++ ast_scu_init_eth(0);
++ ast_scu_multi_func_eth(0);
++
++
++ /*
++ * D[15:11] in 0x1E6E2040 is NCSI scratch from U-Boot. D[15:14] = MAC1, D[13:12] = MAC2
++ * The meanings of the 2 bits are:
++ * 00(0): Dedicated PHY
++ * 01(1): ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++ * 10(2): ASPEED's MAC is connected to NC-SI PHY chip directly
++ * 11: Reserved
++ */
++
++ phy_mode = ast_scu_get_phy_config(0);
++ switch(phy_mode) {
++ case 0:
++ ast_eth0_data.INTEL_NCSI_EVA_support = 0;
++ ast_eth0_data.NCSI_support = 0;
++ break;
++ case 1:
++ ast_eth0_data.NCSI_support = 1;
++ break;
++ case 2:
++ ast_eth0_data.INTEL_NCSI_EVA_support = 1;
++ break;
++
++ }
++
++ phy_inter = ast_scu_get_phy_interface(0);
++
++ // We assume the Clock Stop register does not disable the MAC1 or MAC2 clock
++ // unless Reset Control also holds the MAC in reset.
++
++
++ platform_device_register(&ast_eth0_device);
++
++#ifdef AST_MAC1_BASE
++ ast_scu_init_eth(1);
++ ast_scu_multi_func_eth(1);
++
++ ast_eth1_data.DF_support = !isRevA0;
++
++ phy_mode = ast_scu_get_phy_config(1);
++ switch(phy_mode) {
++ case 0:
++ ast_eth1_data.INTEL_NCSI_EVA_support = 0;
++ ast_eth1_data.NCSI_support = 0;
++ break;
++ case 1:
++ ast_eth1_data.NCSI_support = 1;
++ break;
++ case 2:
++ ast_eth1_data.INTEL_NCSI_EVA_support = 1;
++ break;
++
++ }
++ phy_inter = ast_scu_get_phy_interface(1);
++
++ platform_device_register(&ast_eth1_device);
++
++#endif
++
++}
++#else
++void __init ast_add_device_gmac(void) {}
++#endif
++
+diff --git a/arch/arm/plat-aspeed/dev-fb.c b/arch/arm/plat-aspeed/dev-fb.c
+new file mode 100644
+index 0000000..3673160
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-fb.c
+@@ -0,0 +1,80 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-fb.c
++* Author : Ryan Chen
++* Description : ASPEED Frambuffer Driver
++*
++* Copyright (C) ASPEED Tech. Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/12/15 Ryan Chen initial
++*
++********************************************************************************/
++#include <linux/kernel.h>
++#include <linux/platform_device.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++
++#include <plat/devs.h>
++#include <plat/ast-scu.h>
++
++#include <mach/ast_lcd.h>
++
++/* --------------------------------------------------------------------
++ * ASPEED FB
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_FB_AST) || defined(CONFIG_FB_AST_MODULE)
++static struct ast_fb_plat_data fb_plat_data = {
++ .get_clk = ast_get_d2_pll_clk,
++};
++
++
++static struct resource ast_fb_resources[] = {
++ [0] = {
++ .start = AST_GRAPHIC_BASE,
++ .end = AST_GRAPHIC_BASE + SZ_1K - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_CRT,
++ .end = IRQ_CRT,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static u64 ast_device_fb_dmamask = 0xffffffffUL;
++struct platform_device ast_fb_device = {
++ .name = "ast-fb",
++ .id = 0,
++ .dev = {
++ .dma_mask = &ast_device_fb_dmamask,
++ .coherent_dma_mask = 0xffffffffUL,
++ .platform_data= &fb_plat_data,
++ },
++ .resource = ast_fb_resources,
++ .num_resources = ARRAY_SIZE(ast_fb_resources),
++};
++
++void __init ast_add_device_fb(void)
++{
++ ast_scu_multi_func_crt();
++
++ ast_scu_init_crt();
++
++ platform_device_register(&ast_fb_device);
++}
++#else
++void __init ast_add_device_fb(void) {}
++#endif
+diff --git a/arch/arm/plat-aspeed/dev-gpio.c b/arch/arm/plat-aspeed/dev-gpio.c
+new file mode 100644
+index 0000000..356fd53
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-gpio.c
+@@ -0,0 +1,68 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-rtc.c
++* Author : Ryan chen
++* Description : Socle Real Time Clock Device (RTC)
++*
++* Copyright (C) Socle Tech. Corp.
++* 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
++
++* History :
++* 1. 2010/09/15 ryan chen create this file
++*
++********************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <plat/regs-gpio.h>
++
++#include <plat/devs.h>
++
++/* --------------------------------------------------------------------
++ * ASPEED GPIO
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_GPIO_AST) || defined(CONFIG_GPIO_AST_MODULE)
++static struct resource ast_gpio_resource[] = {
++ [0] = {
++ .start = AST_GPIO_BASE,
++ .end = AST_GPIO_BASE + SZ_4K - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_GPIO,
++ .end = IRQ_GPIO,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device ast_device_gpio = {
++ .name = "ast-gpio",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(ast_gpio_resource),
++ .resource = ast_gpio_resource,
++};
++
++extern void __init
++ast_add_device_gpio(void)
++{
++ platform_device_register(&ast_device_gpio);
++}
++
++#else
++extern void __init ast_add_device_gpio(void) {}
++#endif
++
+diff --git a/arch/arm/plat-aspeed/dev-i2c.c b/arch/arm/plat-aspeed/dev-i2c.c
+new file mode 100644
+index 0000000..47cd152
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-i2c.c
+@@ -0,0 +1,669 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-i2c.c
++* Author : Ryan chen
++* Description : ASPEED I2C Device
++*
++* Copyright (C) ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/07/30 ryan chen create this file
++*
++********************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++#include <linux/i2c.h>
++#include <asm/io.h>
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <plat/ast_i2c.h>
++#include <plat/devs.h>
++#include <plat/regs-iic.h>
++#include <plat/ast-scu.h>
++
++/* --------------------------------------------------------------------
++ * I2C
++ * -------------------------------------------------------------------- */
++#ifdef AST_I2C_DEBUG
++#define I2CDBUG(fmt, args...) printk("%s() " fmt, __FUNCTION__, ## args)
++#else
++#define I2CDBUG(fmt, args...)
++#endif
++
++#if defined(CONFIG_I2C_AST) || defined(CONFIG_I2C_AST_MODULE)
++
++#if defined (CONFIG_ARCH_AST2400)
++#define I2C_PAGE_SIZE 8
++struct buf_page page_info[I2C_PAGE_SIZE] =
++{
++ [0] = {
++ .flag = 0,
++ .page_no = 0,
++ .page_size = 256,
++ .page_addr_point = 0,
++ },
++ [1] = {
++ .flag = 0,
++ .page_no = 1,
++ .page_size = 256,
++ .page_addr_point = 0,
++ },
++ [2] = {
++ .flag = 0,
++ .page_no = 2,
++ .page_size = 256,
++ .page_addr_point = 0,
++ },
++ [3] = {
++ .flag = 0,
++ .page_no = 3,
++ .page_size = 256,
++ .page_addr_point = 0,
++ },
++ [4] = {
++ .flag = 0,
++ .page_no = 4,
++ .page_size = 256,
++ .page_addr_point = 0,
++ },
++ [5] = {
++ .flag = 0,
++ .page_no = 5,
++ .page_size = 256,
++ .page_addr_point = 0,
++ },
++ [6] = {
++ .flag = 0,
++ .page_no = 6,
++ .page_size = 256,
++ .page_addr_point = 0,
++ },
++ [7] = {
++ .flag = 0,
++ .page_no = 7,
++ .page_size = 256,
++ .page_addr_point = 0,
++ },
++};
++
++static void pool_buff_page_init(u32 buf_pool_addr)
++{
++ u32 offset;
++ int i ,j;
++
++ for(i=0;i<I2C_PAGE_SIZE;i++) {
++ offset = 0;
++ for(j=0;j<i;j++)
++ offset += page_info[i].page_size;
++
++ page_info[i].page_addr = buf_pool_addr + offset;
++// I2CDBUG( "page[%d],addr :%x \n", i, page_info[i].page_addr);
++ }
++
++}
++
++static u8 request_pool_buff_page(struct buf_page **req_page)
++{
++ int i;
++ //TODO
++ spinlock_t lock;
++ spin_lock(&lock);
++ for(i=0;i<I2C_PAGE_SIZE;i++) {
++ if(page_info[i].flag ==0) {
++ page_info[i].flag = 1;
++ *req_page = &page_info[i];
++// I2CDBUG( "request page addr %x \n", page_info[i].page_addr);
++ break;
++ }
++ }
++ spin_unlock(&lock);
++ return 0;
++}
++
++static void free_pool_buff_page(struct buf_page *req_page)
++{
++ req_page->flag = 0;
++// I2CDBUG( "free page addr %x \n", req_page->page_addr);
++ req_page = NULL;
++}
++
++#elif defined (CONFIG_ARCH_AST2300)
++#define I2C_PAGE_SIZE 5
++
++struct buf_page page_info[I2C_PAGE_SIZE] =
++{
++ [0] = {
++ .flag = 0,
++ .page_size = 128,
++ },
++ [1] = {
++ .flag = 0,
++ .page_size = 32,
++ },
++ [2] = {
++ .flag = 0,
++ .page_size = 32,
++ },
++ [3] = {
++ .flag = 0,
++ .page_size = 32,
++ },
++ [4] = {
++ .flag = 0,
++ .page_size = 32,
++ },
++};
++
++static void pool_buff_page_init(u32 buf_pool_addr)
++{
++
++ u32 offset;
++ int i ,j;
++
++ for(i=0;i<I2C_PAGE_SIZE;i++) {
++ offset = 0;
++ for(j=0;j<i;j++)
++ offset += page_info[i].page_size;
++
++ page_info[i].page_addr = buf_pool_addr + offset;
++ page_info[i].page_addr_point = page_info[i].page_addr/4;
++// printk("page[%d],addr :%x , point : %d\n", i, page_info[i].page_addr, page_info[i].page_addr_point);
++ }
++}
++
++static u8 request_pool_buff_page(struct buf_page **req_page)
++{
++ int i;
++ //TODO
++ spinlock_t lock;
++ spin_lock(&lock);
++ for(i=0;i<I2C_PAGE_SIZE;i++) {
++ if(page_info[i].flag ==0) {
++ page_info[i].flag = 1;
++ *req_page = &page_info[i];
++ spin_unlock(&lock);
++ return 1;
++ }
++ }
++ spin_unlock(&lock);
++ return 0;
++
++}
++
++//TODO check free ?
++static void free_pool_buff_page(struct buf_page *req_page)
++{
++ req_page->flag = 0;
++ req_page = NULL;
++}
++
++#else
++//DO nothing
++static void pool_buff_page_init(void) {}
++static u8 request_pool_buff_page(struct buf_page **req_page) {return 0;}
++static void free_pool_buff_page(struct buf_page *req_page) {}
++#endif
++
++static struct ast_i2c_driver_data ast_i2c_data = {
++ .bus_clk = 100000, //bus clock 100KHz
++ .master_dma = BUFF_MODE,
++ .slave_dma = BYTE_MODE,
++ .request_pool_buff_page = request_pool_buff_page,
++ .free_pool_buff_page = free_pool_buff_page,
++#ifdef CONFIG_AST_I2C_SLAVE_MODE
++ .slave_xfer = i2c_slave_xfer,
++ .slave_init = i2c_slave_init,
++#endif
++ .get_i2c_clock = ast_get_pclk,
++};
++
++static u64 ast_i2c_dma_mask = 0xffffffffUL;
++static struct resource ast_i2c_dev1_resources[] = {
++ [0] = {
++ .start = AST_I2C_BASE + AST_I2C_DEVICE1,
++ .end = AST_I2C_BASE + AST_I2C_DEVICE1 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_I2C,
++ .end = IRQ_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_i2c_dev1_device = {
++ .name = "ast-i2c",
++ .id = 0,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_i2c_data,
++ },
++ .resource = ast_i2c_dev1_resources,
++ .num_resources = ARRAY_SIZE(ast_i2c_dev1_resources),
++};
++
++static struct resource ast_i2c_dev2_resources[] = {
++ [0] = {
++ .start = AST_I2C_BASE + AST_I2C_DEVICE2,
++ .end = AST_I2C_BASE + AST_I2C_DEVICE2 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_I2C,
++ .end = IRQ_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_i2c_dev2_device = {
++ .name = "ast-i2c",
++ .id = 1,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_i2c_data,
++ },
++ .resource = ast_i2c_dev2_resources,
++ .num_resources = ARRAY_SIZE(ast_i2c_dev2_resources),
++};
++
++static struct resource ast_i2c_dev3_resources[] = {
++ [0] = {
++ .start = AST_I2C_BASE + AST_I2C_DEVICE3,
++ .end = AST_I2C_BASE + AST_I2C_DEVICE3 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_I2C,
++ .end = IRQ_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_i2c_dev3_device = {
++ .name = "ast-i2c",
++ .id = 2,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_i2c_data,
++ },
++ .resource = ast_i2c_dev3_resources,
++ .num_resources = ARRAY_SIZE(ast_i2c_dev3_resources),
++};
++
++static struct resource ast_i2c_dev4_resources[] = {
++ [0] = {
++ .start = AST_I2C_BASE + AST_I2C_DEVICE4,
++ .end = AST_I2C_BASE + AST_I2C_DEVICE4 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_I2C,
++ .end = IRQ_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_i2c_dev4_device = {
++ .name = "ast-i2c",
++ .id = 3,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_i2c_data,
++ },
++ .resource = ast_i2c_dev4_resources,
++ .num_resources = ARRAY_SIZE(ast_i2c_dev4_resources),
++};
++
++static struct resource ast_i2c_dev5_resources[] = {
++ [0] = {
++ .start = AST_I2C_BASE + AST_I2C_DEVICE5,
++ .end = AST_I2C_BASE + AST_I2C_DEVICE5 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_I2C,
++ .end = IRQ_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_i2c_dev5_device = {
++ .name = "ast-i2c",
++ .id = 4,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_i2c_data,
++ },
++ .resource = ast_i2c_dev5_resources,
++ .num_resources = ARRAY_SIZE(ast_i2c_dev5_resources),
++};
++
++static struct resource ast_i2c_dev6_resources[] = {
++ [0] = {
++ .start = AST_I2C_BASE + AST_I2C_DEVICE6,
++ .end = AST_I2C_BASE + AST_I2C_DEVICE6 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_I2C,
++ .end = IRQ_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_i2c_dev6_device = {
++ .name = "ast-i2c",
++ .id = 5,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_i2c_data,
++ },
++ .resource = ast_i2c_dev6_resources,
++ .num_resources = ARRAY_SIZE(ast_i2c_dev6_resources),
++};
++
++static struct resource ast_i2c_dev7_resources[] = {
++ [0] = {
++ .start = AST_I2C_BASE + AST_I2C_DEVICE7,
++ .end = AST_I2C_BASE + AST_I2C_DEVICE7 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_I2C,
++ .end = IRQ_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_i2c_dev7_device = {
++ .name = "ast-i2c",
++ .id = 6,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_i2c_data,
++ },
++ .resource = ast_i2c_dev7_resources,
++ .num_resources = ARRAY_SIZE(ast_i2c_dev7_resources),
++};
++
++static struct resource ast_i2c_dev8_resources[] = {
++ [0] = {
++ .start = AST_I2C_BASE + AST_I2C_DEVICE8,
++ .end = AST_I2C_BASE + AST_I2C_DEVICE8 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_I2C,
++ .end = IRQ_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_i2c_dev8_device = {
++ .name = "ast-i2c",
++ .id = 7,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_i2c_data,
++ },
++ .resource = ast_i2c_dev8_resources,
++ .num_resources = ARRAY_SIZE(ast_i2c_dev8_resources),
++};
++
++static struct resource ast_i2c_dev9_resources[] = {
++ [0] = {
++ .start = AST_I2C_BASE + AST_I2C_DEVICE9,
++ .end = AST_I2C_BASE + AST_I2C_DEVICE9 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_I2C,
++ .end = IRQ_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_i2c_dev9_device = {
++ .name = "ast-i2c",
++ .id = 8,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_i2c_data,
++ },
++ .resource = ast_i2c_dev9_resources,
++ .num_resources = ARRAY_SIZE(ast_i2c_dev9_resources),
++};
++
++#if defined(CONFIG_ARCH_AST2400)
++static struct resource ast_i2c_dev10_resources[] = {
++ [0] = {
++ .start = AST_I2C_BASE + AST_I2C_DEVICE10,
++ .end = AST_I2C_BASE + AST_I2C_DEVICE10 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_I2C,
++ .end = IRQ_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_i2c_dev10_device = {
++ .name = "ast-i2c",
++ .id = 9,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_i2c_data,
++ },
++ .resource = ast_i2c_dev10_resources,
++ .num_resources = ARRAY_SIZE(ast_i2c_dev10_resources),
++};
++
++static struct resource ast_i2c_dev11_resources[] = {
++ [0] = {
++ .start = AST_I2C_BASE + AST_I2C_DEVICE11,
++ .end = AST_I2C_BASE + AST_I2C_DEVICE11 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_I2C,
++ .end = IRQ_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_i2c_dev11_device = {
++ .name = "ast-i2c",
++ .id = 10,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_i2c_data,
++ },
++ .resource = ast_i2c_dev11_resources,
++ .num_resources = ARRAY_SIZE(ast_i2c_dev11_resources),
++};
++
++static struct resource ast_i2c_dev12_resources[] = {
++ [0] = {
++ .start = AST_I2C_BASE + AST_I2C_DEVICE12,
++ .end = AST_I2C_BASE + AST_I2C_DEVICE12 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_I2C,
++ .end = IRQ_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_i2c_dev12_device = {
++ .name = "ast-i2c",
++ .id = 11,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_i2c_data,
++ },
++ .resource = ast_i2c_dev12_resources,
++ .num_resources = ARRAY_SIZE(ast_i2c_dev12_resources),
++};
++
++static struct resource ast_i2c_dev13_resources[] = {
++ [0] = {
++ .start = AST_I2C_BASE + AST_I2C_DEVICE13,
++ .end = AST_I2C_BASE + AST_I2C_DEVICE13 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_I2C,
++ .end = IRQ_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_i2c_dev13_device = {
++ .name = "ast-i2c",
++ .id = 12,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_i2c_data,
++ },
++ .resource = ast_i2c_dev13_resources,
++ .num_resources = ARRAY_SIZE(ast_i2c_dev13_resources),
++};
++
++static struct resource ast_i2c_dev14_resources[] = {
++ [0] = {
++ .start = AST_I2C_BASE + AST_I2C_DEVICE14,
++ .end = AST_I2C_BASE + AST_I2C_DEVICE14 + 4*SZ_16 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_I2C,
++ .end = IRQ_I2C,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_i2c_dev14_device = {
++ .name = "ast-i2c",
++ .id = 13,
++ .dev = {
++ .dma_mask = &ast_i2c_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_i2c_data,
++ },
++ .resource = ast_i2c_dev14_resources,
++ .num_resources = ARRAY_SIZE(ast_i2c_dev14_resources),
++};
++#endif
++
++/*--------- I2C Board devices ------------*/
++//ASPEED AST2300 EVB I2C Device
++#if defined(CONFIG_ARCH_AST2300) || defined(CONFIG_ARCH_AST2400)
++//Under I2C Dev 1
++static struct i2c_board_info __initdata ast_i2c_board_info_1[] = {
++ {
++ I2C_BOARD_INFO("cat9883", 0x4d),
++ }
++};
++
++//Under I2C Dev 4
++static struct i2c_board_info __initdata ast_i2c_board_info_4[] = {
++ {
++ I2C_BOARD_INFO("24c128", 0x50),
++
++
++ }
++};
++//Under I2C Dev 8
++static struct i2c_board_info __initdata ast_i2c_board_info_8[] = {
++ {
++ I2C_BOARD_INFO("lm75b", 0x4a),
++ }
++};
++
++#endif
++
++/*-------------------------------------*/
++void __init ast_add_device_i2c(void)
++{
++ //I2C Multi-Pin
++ ast_scu_multi_func_i2c();
++
++ //SCU I2C Reset
++ ast_scu_init_i2c();
++
++ ast_i2c_data.reg_gr = ioremap(AST_I2C_BASE, 4*SZ_16);
++ if (!ast_i2c_data.reg_gr) {
++ printk("ast_add_device_i2c ERROR \n");
++ return;
++ }
++
++#if defined (CONFIG_ARCH_AST2400)
++ ast_i2c_data.buf_pool= ioremap(AST_I2C_BASE+0x800, 2048);
++ if (!ast_i2c_data.buf_pool) {
++ printk("ast_add_device_i2c ERROR \n");
++ return;
++ }
++#else
++ ast_i2c_data.buf_pool = ioremap(AST_I2C_BASE+0x200, 256);
++ if (!ast_i2c_data.buf_pool) {
++ printk("ast_add_device_i2c ERROR \n");
++ return;
++ }
++#endif
++ //TODO
++ pool_buff_page_init(ast_i2c_data.buf_pool);
++ platform_device_register(&ast_i2c_dev1_device);
++ i2c_register_board_info(0, ast_i2c_board_info_1, ARRAY_SIZE(ast_i2c_board_info_1));
++ platform_device_register(&ast_i2c_dev2_device);
++ platform_device_register(&ast_i2c_dev3_device);
++ platform_device_register(&ast_i2c_dev4_device);
++ i2c_register_board_info(3, ast_i2c_board_info_4, ARRAY_SIZE(ast_i2c_board_info_4));
++ platform_device_register(&ast_i2c_dev5_device);
++ platform_device_register(&ast_i2c_dev6_device);
++ platform_device_register(&ast_i2c_dev7_device);
++ platform_device_register(&ast_i2c_dev8_device);
++ i2c_register_board_info(7, ast_i2c_board_info_8, ARRAY_SIZE(ast_i2c_board_info_8));
++ platform_device_register(&ast_i2c_dev9_device);
++
++#if defined(CONFIG_ARCH_AST2400)
++ platform_device_register(&ast_i2c_dev10_device);
++#if defined(CONFIG_MMC_AST)
++ //Due to share pin with SD
++#else
++ platform_device_register(&ast_i2c_dev11_device);
++ platform_device_register(&ast_i2c_dev12_device);
++ platform_device_register(&ast_i2c_dev13_device);
++ platform_device_register(&ast_i2c_dev14_device);
++#endif
++#endif
++}
++#else
++void __init ast_add_device_i2c(void) {}
++#endif
+diff --git a/arch/arm/plat-aspeed/dev-kcs.c b/arch/arm/plat-aspeed/dev-kcs.c
+new file mode 100644
+index 0000000..726dbf7
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-kcs.c
+@@ -0,0 +1,129 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-kcs.c
++* Author : Ryan chen
++* Description : ASPEED KCS
++*
++* Copyright (C) ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/11/29 ryan chen create this file
++*
++********************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <plat/devs.h>
++#include <plat/ast-scu.h>
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <plat/devs.h>
++#include <plat/ast-scu.h>
++
++/* --------------------------------------------------------------------
++ * KCS
++ * -------------------------------------------------------------------- */
++#if defined(CONFIG_AST_KCS) || defined(CONFIG_AST_KCS_MODULE)
++static u64 ast_kcs_dma_mask = 0xffffffffUL;
++
++static struct resource ast_kcs0_resource[] = {
++ [0] = {
++ .start = AST_LPC_BASE,
++ .end = AST_LPC_BASE + SZ_256,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_LPC,
++ .end = IRQ_LPC,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device ast_kcs0_device = {
++ .name = "ast-kcs",
++ .id = 0,
++ .dev = {
++ .dma_mask = &ast_kcs_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ },
++ .resource = ast_kcs0_resource,
++ .num_resources = ARRAY_SIZE(ast_kcs0_resource),
++};
++
++static struct resource ast_kcs1_resource[] = {
++ [0] = {
++ .start = AST_LPC_BASE,
++ .end = AST_LPC_BASE + SZ_256,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_LPC,
++ .end = IRQ_LPC,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device ast_kcs1_device = {
++ .name = "ast-kcs",
++ .id = 1,
++ .dev = {
++ .dma_mask = &ast_kcs_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ },
++ .resource = ast_kcs1_resource,
++ .num_resources = ARRAY_SIZE(ast_kcs1_resource),
++};
++
++static struct resource ast_kcs2_resource[] = {
++ [0] = {
++ .start = AST_LPC_BASE,
++ .end = AST_LPC_BASE + SZ_256,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_LPC,
++ .end = IRQ_LPC,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device ast_kcs2_device = {
++ .name = "ast-kcs",
++ .id = 2,
++ .dev = {
++ .dma_mask = &ast_kcs_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ },
++ .resource = ast_kcs2_resource,
++ .num_resources = ARRAY_SIZE(ast_kcs2_resource),
++};
++
++void __init ast_add_device_kcs(void)
++{
++// platform_device_register(&ast_kcs0_device);
++// platform_device_register(&ast_kcs1_device);
++ platform_device_register(&ast_kcs2_device);
++}
++#else
++void __init ast_add_device_kcs(void) {}
++#endif
++
+diff --git a/arch/arm/plat-aspeed/dev-lpc.c b/arch/arm/plat-aspeed/dev-lpc.c
+new file mode 100644
+index 0000000..50eb4e6
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-lpc.c
+@@ -0,0 +1,105 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-lpc.c
++* Author : Ryan chen
++* Description : ASPEED LPC Controller
++*
++* Copyright (C) ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/11/29 ryan chen create this file
++*
++********************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <plat/devs.h>
++#include <plat/ast-scu.h>
++
++
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <plat/devs.h>
++#include <plat/ast-scu.h>
++
++
++/* --------------------------------------------------------------------
++ * LPC
++ * -------------------------------------------------------------------- */
++#if defined(CONFIG_LPC) || defined(CONFIG_LPC_MODULE)
++static struct resource ast_lpc_resource[] = {
++ [0] = {
++ .start = AST_LPC_BASE,
++ .end = AST_LPC_BASE + SZ_4K,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_LPC,
++ .end = IRQ_LPC,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static u64 ast_lpc_dma_mask = 0xffffffffUL;
++
++static struct platform_device ast_lpc_device = {
++ .name = "ast_lpc",
++ .id = 0,
++ .dev = {
++ .dma_mask = &ast_lpc_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ },
++ .resource = ast_lpc_resource,
++ .num_resources = ARRAY_SIZE(ast_lpc_resource),
++};
++
++static struct resource ast_lpc_plus_resource[] = {
++ [0] = {
++ .start = AST_LPC_PLUS_BASE,
++ .end = AST_LPC_PLUS_BASE + SZ_4K,
++ .flags = IORESOURCE_MEM,
++ },
++};
++
++static struct platform_device ast_lpc_plus_device = {
++ .name = "ast_lpc_plus",
++ .id = 1,
++ .dev = {
++ .dma_mask = &ast_lpc_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ },
++ .resource = ast_lpc_plus_resource,
++ .num_resources = ARRAY_SIZE(ast_lpc_plus_resource),
++};
++
++void __init ast_add_device_lpc(void)
++{
++// it should enable at u-boot
++// ast_scu_init_lpc();
++
++ platform_device_register(&ast_lpc_device);
++ platform_device_register(&ast_lpc_plus_device);
++}
++#else
++void __init ast_add_device_lpc(void) {}
++#endif
++
+diff --git a/arch/arm/plat-aspeed/dev-mbx.c b/arch/arm/plat-aspeed/dev-mbx.c
+new file mode 100644
+index 0000000..75baf87
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-mbx.c
+@@ -0,0 +1,79 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-mbx.c
++* Author : Ryan chen
++* Description : ASPEED MailBox Controller
++*
++* Copyright (C) ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/11/29 ryan chen create this file
++*
++********************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <plat/devs.h>
++#include <plat/ast-scu.h>
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <plat/devs.h>
++#include <plat/ast-scu.h>
++
++/* --------------------------------------------------------------------
++ * MailBox
++ * -------------------------------------------------------------------- */
++#if defined(CONFIG_AST_MBX) || defined(CONFIG_AST_MBX_MODULE)
++static struct resource ast_mbx_resource[] = {
++ [0] = {
++ .start = AST_MBX_BASE,
++ .end = AST_MBX_BASE + SZ_256,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_MAILBOX,
++ .end = IRQ_MAILBOX,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static u64 ast_mbx_dma_mask = 0xffffffffUL;
++
++static struct platform_device ast_mbx_device = {
++ .name = "ast-mailbox",
++ .id = 0,
++ .dev = {
++ .dma_mask = &ast_mbx_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ },
++ .resource = ast_mbx_resource,
++ .num_resources = ARRAY_SIZE(ast_mbx_resource),
++};
++
++void __init ast_add_device_mailbox(void)
++{
++ platform_device_register(&ast_mbx_device);
++}
++#else
++void __init ast_add_device_mailbox(void) {}
++#endif
++
+diff --git a/arch/arm/plat-aspeed/dev-nand.c b/arch/arm/plat-aspeed/dev-nand.c
+new file mode 100644
+index 0000000..f11ff31
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-nand.c
+@@ -0,0 +1,331 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-nand.c
++* Author : Ryan chen
++* Description : ASPEED NAND Device
++*
++* Copyright (C) ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/10/15 ryan chen create this file
++*
++********************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++#include <asm/mach/flash.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <plat/devs.h>
++#include <plat/regs-fmc.h>
++#include <asm/io.h>
++
++#include <linux/mtd/nand.h>
++
++#include <plat/ast-scu.h>
++#include <linux/mtd/mtd.h>
++
++
++
++/* --------------------------------------------------------------------
++ * NAND Flash
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_MTD_NAND_AST) || defined(CONFIG_MTD_NAND_AST_MODULE)
++static void __iomem *fmc_regs;
++
++/* returns 0 if the nand is busy, returns 1 if the nand is ready */
++static int
++ast_nand_dev_ready(struct mtd_info *mtd)
++{
++ int status;
++ status = (readl(fmc_regs + FMC_MISC_CTRL1) & READ_BUSY_PIN_STS) >> 3;
++ return status;
++}
++
++/* We use 2 256bytes as ECC's data length in sample code */
++static void
++ast_enable_hwecc(struct mtd_info *mtd, int cmd)
++{
++ writel(NAND_ECC_DATA_BLK_256 | NAND_ECC_ENABLE , fmc_regs + FMC_NAND_ECC);
++
++ writel(NAND_ECC_RESET , fmc_regs + FMC_NAND_ECC);
++
++ writel(NAND_ECC_DATA_BLK_256 | NAND_ECC_ENABLE , fmc_regs + FMC_NAND_ECC);
++}
++
++static int
++ast_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
++{
++ uint32_t ecc_1, ecc_2, ecc_3;
++
++ ecc_1 = readl(fmc_regs + FMC_NAND_ECC_GEN1);
++ ecc_2 = readl(fmc_regs + FMC_NAND_ECC_GEN2);
++ ecc_3 = readl(fmc_regs + FMC_NAND_ECC_GEN3);
++
++ ecc_code[0] = ecc_1;
++ ecc_code[1] = ecc_1 >> 8;
++ ecc_code[2] = ecc_1 >> 16;
++ ecc_code[3] = ecc_1 >> 24;
++ ecc_code[4] = ecc_2;
++ ecc_code[5] = (((ecc_2 >> 8) & 0x0F) | 0xF0); //Becase flash's data value will be 0xff after flash is erased. The 256bytes mode will use 44bits to do ECC, the software needs to add 0xF0 for the last 4 bits.
++
++ return 0;
++}
++
++static int
++ast_nand_correct_data(struct mtd_info *mtd, u_char *dat,
++ u_char *read_ecc, u_char *calc_ecc)
++{
++ unsigned int dw_read_data[3], dw_calc_data[3];
++ unsigned int data1_check_status, data2_check_status;
++ unsigned int i, ecc_position, ecc_bit;
++
++ for (i = 0; i < 3; i++) {
++ dw_read_data[i] = 0;
++ dw_calc_data[i] = 0;
++ }
++ memcpy (dw_read_data, read_ecc, 6);
++ memcpy (dw_calc_data, calc_ecc, 6);
++ for (i = 0; i < 2; i++) {
++ writel(dw_read_data[i], fmc_regs + FMC_NAND_ECC_CK1 + (i*4));
++ writel(dw_calc_data[i], fmc_regs + FMC_NAND_ECC_GEN1 + (i*4));
++ }
++
++ data1_check_status = readl(fmc_regs + FMC_NAND_ECC_CK_R1) & 0xffff;
++ data2_check_status = (readl(fmc_regs + FMC_NAND_ECC_CK_R1) & 0xffff0000) >> 16;
++
++ if ((data1_check_status & 0x1000) && (data2_check_status & 0x1000)) {
++ return 0;
++ }
++
++ if ((data1_check_status & 0x8000) || (data2_check_status & 0x8000)) {
++ printk(KERN_ERR "uncorrectable error : ");
++ return -1;
++ }
++
++ if ((data1_check_status & 0x4000) || (data2_check_status & 0x4000)) {
++ printk ("error in ecc data\n");
++ return 1; /* error in ecc data; no action needed */
++ }
++
++//Correctable
++ if (data1_check_status & 0x2000) {
++ printk ("correctable in data area 1\n");
++ ecc_position = (data1_check_status & 0xff8) >> 3;
++ ecc_bit = (data1_check_status & 0x07);
++ dat[ecc_position] ^= (1 << ecc_bit);
++ }
++ if (data2_check_status & 0x2000) {
++ printk ("correctable in data area 2\n");
++ ecc_position = (data2_check_status & 0xff8) >> 3;
++ ecc_bit = (data2_check_status & 0x07);
++ dat[128 + ecc_position] ^= (1 << ecc_bit);
++ }
++
++ return 1;
++}
++
++/*---------------------------------------------------------
++ * AST2300 1 NAND * 128MB
++ *--------------------------------------------------------*/
++
++static struct mtd_partition ast_nand_partition_info[] = {
++ [0] = {
++ .name = "ASPEED NAND Flash 0",
++ .offset = 0,
++ .size = SZ_64M,
++ },
++ [1] = {
++ .name = "ASPEED NAND Flash 1",
++ .offset = MTDPART_OFS_APPEND,
++ .size = MTDPART_SIZ_FULL
++ },
++};
++
++static const char *ast_nand_part_probes[] = { "cmdlinepart", NULL };
++
++struct platform_nand_data ast_nand_platdata = {
++ .chip = {
++ .nr_chips = 1,
++ .chip_offset = 0,
++ .nr_partitions = ARRAY_SIZE(ast_nand_partition_info),
++ .partitions = ast_nand_partition_info,
++ /* 50 us command delay time */
++ .chip_delay = 50,
++ .options = NAND_NO_AUTOINCR,
++ .part_probe_types = ast_nand_part_probes,
++ },
++ .ctrl = {
++ .hwcontrol = ast_enable_hwecc,
++ .dev_ready = ast_nand_dev_ready,
++ .select_chip = 0,
++ .calculate = ast_calculate_ecc,
++ .correct = ast_nand_correct_data,
++ },
++};
++
++#if defined(CONFIG_AST_CS0_NAND)
++static struct resource ast_nand_resource0[] = {
++ {
++ .start = AST_CS0_DEF_BASE,
++ .end = AST_CS0_DEF_BASE + 0x10000,
++ .flags = IORESOURCE_MEM,
++ },
++};
++
++static struct platform_device ast_nand_device0 = {
++ .name = "ast-nand",
++ .id = 0,
++ .dev = {
++ .platform_data = &ast_nand_platdata,
++ },
++ .num_resources = ARRAY_SIZE(ast_nand_resource0),
++ .resource = ast_nand_resource0,
++};
++#endif
++
++#if defined(CONFIG_AST_CS1_NAND)
++static struct resource ast_nand_resource1[] = {
++ {
++ .start = AST_CS1_DEF_BASE,
++ .end = AST_CS1_DEF_BASE + 0x10000,
++ .flags = IORESOURCE_MEM,
++ },
++};
++
++static struct platform_device ast_nand_device1 = {
++ .name = "ast-nand",
++ .id = 1,
++ .dev = {
++ .platform_data = &ast_nand_platdata,
++ },
++ .num_resources = ARRAY_SIZE(ast_nand_resource1),
++ .resource = ast_nand_resource1,
++};
++#endif
++
++#if defined(CONFIG_AST_CS2_NAND)
++static struct resource ast_nand_resource2[] = {
++ {
++ .start = AST_CS2_DEF_BASE,
++ .end = AST_CS2_DEF_BASE + 0x10000,
++ .flags = IORESOURCE_MEM,
++ },
++};
++
++static struct platform_device ast_nand_device2 = {
++ .name = "ast-nand",
++ .id = 2,
++ .dev = {
++ .platform_data = &ast_nand_platdata,
++ },
++ .num_resources = ARRAY_SIZE(ast_nand_resource2),
++ .resource = ast_nand_resource2,
++};
++#endif
++
++#if defined(CONFIG_AST_CS3_NAND)
++static struct resource ast_nand_resource3[] = {
++ {
++ .start = AST_CS3_DEF_BASE,
++ .end = AST_CS3_DEF_BASE + 0x10000,
++ .flags = IORESOURCE_MEM,
++ },
++};
++
++static struct platform_device ast_nand_device3 = {
++ .name = "ast-nand",
++ .id = 3,
++ .dev = {
++ .platform_data = &ast_nand_platdata,
++ },
++ .num_resources = ARRAY_SIZE(ast_nand_resource3),
++ .resource = ast_nand_resource3,
++};
++#endif
++
++#if defined(CONFIG_AST_CS4_NAND)
++static struct resource ast_nand_resource4[] = {
++ {
++ .start = AST_CS4_DEF_BASE,
++ .end = AST_CS4_DEF_BASE + 0x10000,
++ .flags = IORESOURCE_MEM,
++ },
++};
++
++static struct platform_device ast_nand_device4 = {
++ .name = "ast-nand",
++ .id = 4,
++ .dev = {
++ .platform_data = &ast_nand_platdata,
++ },
++ .num_resources = ARRAY_SIZE(ast_nand_resource4),
++ .resource = ast_nand_resource4,
++};
++#endif
++
++/*-------------------------------------*/
++void __init ast_add_device_nand(void)
++{
++ u32 tmp;
++ fmc_regs = ioremap(AST_FMC_BASE, 4*SZ_16);
++
++ ast_scu_multi_func_nand();
++ writel(0x31 , fmc_regs + FMC_MISC_CTRL1);
++
++#if defined(CONFIG_AST_CS0_NAND)
++ platform_device_register(&ast_nand_device0);
++ tmp = (readl(fmc_regs) | FMC_SET_WRITE_CS(0)) & FMC_MASK_TYPE_CS(0);
++ writel( tmp | FMC_SET_TYPE_NAND_CS(0), fmc_regs);
++ writel(0x9 , fmc_regs + FMC_CE0_CTRL);
++#endif
++
++#if defined(CONFIG_AST_CS1_NAND)
++ ast_scu_multi_func_romcs(1);
++ tmp = (readl(fmc_regs) | FMC_SET_WRITE_CS(1)) & FMC_MASK_TYPE_CS(1);
++ writel( tmp | FMC_SET_TYPE_NAND_CS(1), fmc_regs);
++ writel(0x9 , fmc_regs + FMC_CE1_CTRL);
++ platform_device_register(&ast_nand_device1);
++#endif
++#if defined(CONFIG_AST_CS2_NAND)
++ ast_scu_multi_func_romcs(2);
++ tmp = (readl(fmc_regs) | FMC_SET_WRITE_CS(2)) & FMC_MASK_TYPE_CS(2);
++ writel( tmp | FMC_SET_TYPE_NAND_CS(2), fmc_regs);
++ writel(0x9 , fmc_regs + FMC_CE2_CTRL);
++ platform_device_register(&ast_nand_device2);
++#endif
++#if defined(CONFIG_AST_CS3_NAND)
++ ast_scu_multi_func_romcs(3);
++ tmp = (readl(fmc_regs) | FMC_SET_WRITE_CS(3)) & FMC_MASK_TYPE_CS(3);
++ writel( tmp | FMC_SET_TYPE_NAND_CS(3), fmc_regs);
++ writel(0x9 , fmc_regs + FMC_CE3_CTRL);
++ platform_device_register(&ast_nand_device3);
++#endif
++#if defined(CONFIG_AST_CS4_NAND)
++ ast_scu_multi_func_romcs(4);
++ tmp = (readl(fmc_regs) | FMC_SET_WRITE_CS(4)) & FMC_MASK_TYPE_CS(4);
++ writel( tmp | FMC_SET_TYPE_NAND_CS(4), fmc_regs);
++ writel(0x9 , fmc_regs + FMC_CE4_CTRL);
++ platform_device_register(&ast_nand_device4);
++#endif
++ iounmap(fmc_regs);
++
++}
++#else
++void __init ast_add_device_nand(void) {}
++#endif
+diff --git a/arch/arm/plat-aspeed/dev-nor.c b/arch/arm/plat-aspeed/dev-nor.c
+new file mode 100644
+index 0000000..abf49c0
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-nor.c
+@@ -0,0 +1,219 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-nor.c
++* Author : Ryan chen
++* Description : ASPEED NOR Device
++*
++* Copyright (C) ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/08/01 ryan chen create this file
++*
++********************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++#include <asm/mach/flash.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <plat/devs.h>
++#include <plat/regs-fmc.h>
++#include <asm/io.h>
++#include <plat/ast-scu.h>
++
++
++/* --------------------------------------------------------------------
++ * NOR Flash
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_MTD_AST) || defined(CONFIG_MTD_AST_MODULE)
++/*---------------------------------------------------------
++ * AST2300 1 NOR * 16MB
++ *--------------------------------------------------------*/
++static struct mtd_partition nor_partitions[] = {
++ /* bootloader (U-Boot, etc) in first sector */
++ {
++ .name = "u-boot",
++ .offset = 0,
++ .size = 0x80000,
++ .mask_flags = MTD_WRITEABLE, /* force read-only */
++ },
++ /* kernel */
++ {
++ .name = "kernel",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 0x300000,
++ },
++ /* file system */
++ {
++ .name = "ramdisk",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 0x500000,
++ },
++ {
++ .name = "data",
++ .offset = MTDPART_OFS_APPEND,
++ .size = MTDPART_SIZ_FULL,
++ }
++};
++
++static struct flash_platform_data ast_nor_data = {
++ .map_name = "cfi_probe",
++ .width = 2,
++ .parts = nor_partitions,
++ .nr_parts = ARRAY_SIZE(nor_partitions),
++};
++
++#if defined(CONFIG_AST_CS0_NOR)
++static struct resource ast_nor_resource0[] = {
++ {
++ .start = AST_CS0_DEF_BASE,
++ .end = AST_CS0_DEF_BASE + AST_NOR_SIZE- 1,
++ .flags = IORESOURCE_MEM,
++ },
++};
++
++static struct platform_device ast_nor_device0 = {
++ .name = "ast-nor",
++ .id = 0,
++ .dev = {
++ .platform_data = &ast_nor_data,
++ },
++ .num_resources = ARRAY_SIZE(ast_nor_resource0),
++ .resource = ast_nor_resource0,
++};
++#endif
++
++#if defined(CONFIG_AST_CS1_NOR)
++static struct resource ast_nor_resource1[] = {
++ {
++ .start = AST_CS1_DEF_BASE,
++ .end = AST_CS1_DEF_BASE + AST_NOR_SIZE- 1,
++ .flags = IORESOURCE_MEM,
++ },
++};
++
++static struct platform_device ast_nor_device1 = {
++ .name = "ast-nor",
++ .id = 1,
++ .dev = {
++ .platform_data = &ast_nor_data,
++ },
++ .num_resources = ARRAY_SIZE(ast_nor_resource1),
++ .resource = ast_nor_resource1,
++};
++#endif
++
++#if defined(CONFIG_AST_CS2_NOR)
++static struct resource ast_nor_resource2[] = {
++ {
++ .start = AST_CS2_DEF_BASE,
++ .end = AST_CS2_DEF_BASE + AST_NOR_SIZE- 1,
++ .flags = IORESOURCE_MEM,
++ },
++};
++
++static struct platform_device ast_nor_device2 = {
++ .name = "ast-nor",
++ .id = 2,
++ .dev = {
++ .platform_data = &ast_nor_data,
++ },
++ .num_resources = ARRAY_SIZE(ast_nor_resource2),
++ .resource = ast_nor_resource2,
++};
++#endif
++
++#if defined(CONFIG_AST_CS3_NOR)
++static struct resource ast_nor_resource3[] = {
++ {
++ .start = AST_CS3_DEF_BASE,
++ .end = AST_CS3_DEF_BASE + AST_NOR_SIZE- 1,
++ .flags = IORESOURCE_MEM,
++ },
++};
++
++static struct platform_device ast_nor_device3 = {
++ .name = "ast-nor",
++ .id = 3,
++ .dev = {
++ .platform_data = &ast_nor_data,
++ },
++ .num_resources = ARRAY_SIZE(ast_nor_resource3),
++ .resource = ast_nor_resource3,
++};
++#endif
++
++#if defined(CONFIG_AST_CS4_NOR)
++static struct resource ast_nor_resource4[] = {
++ {
++ .start = AST_CS4_DEF_BASE,
++ .end = AST_CS4_DEF_BASE + AST_NOR_SIZE- 1,
++ .flags = IORESOURCE_MEM,
++ },
++};
++
++static struct platform_device ast_nor_device4 = {
++ .name = "ast-nor",
++ .id = 4,
++ .dev = {
++ .platform_data = &ast_nor_data,
++ },
++ .num_resources = ARRAY_SIZE(ast_nor_resource4),
++ .resource = ast_nor_resource4,
++};
++#endif
++
++/*-------------------------------------*/
++void __init ast_add_device_flash(void)
++{
++ void __iomem *fmc_regs = ioremap(AST_FMC_BASE, 4*SZ_16);
++
++ ast_scu_multi_func_nor();
++
++#if defined(CONFIG_AST_CS0_NOR)
++ //Enable NOR ACK
++ ast_scu_multi_func_romcs(0);
++ platform_device_register(&ast_nor_device0);
++ writel((readl(fmc_regs) | FMC_SET_WRITE_CS(0)) & FMC_MASK_TYPE_CS(0), fmc_regs);
++#endif
++#if defined(CONFIG_AST_CS1_NOR)
++ ast_scu_multi_func_romcs(1);
++ writel((readl(fmc_regs) | FMC_SET_WRITE_CS(1)) & FMC_MASK_TYPE_CS(1), fmc_regs);
++ platform_device_register(&ast_nor_device1);
++#endif
++#if defined(CONFIG_AST_CS2_NOR)
++ ast_scu_multi_func_romcs(2);
++ writel((readl(fmc_regs) | FMC_SET_WRITE_CS(2)) & FMC_MASK_TYPE_CS(2), fmc_regs);
++ platform_device_register(&ast_nor_device2);
++#endif
++#if defined(CONFIG_AST_CS3_NOR)
++ ast_scu_multi_func_romcs(3);
++ writel((readl(fmc_regs) | FMC_SET_WRITE_CS(3)) & FMC_MASK_TYPE_CS(3), fmc_regs);
++ platform_device_register(&ast_nor_device3);
++#endif
++#if defined(CONFIG_AST_CS4_NOR)
++ ast_scu_multi_func_romcs(4);
++ writel((readl(fmc_regs) | FMC_SET_WRITE_CS(4)) & FMC_MASK_TYPE_CS(4), fmc_regs);
++ platform_device_register(&ast_nor_device4);
++#endif
++ iounmap(fmc_regs);
++
++}
++#else
++void __init ast_add_device_flash(void) {}
++#endif
+diff --git a/arch/arm/plat-aspeed/dev-peci.c b/arch/arm/plat-aspeed/dev-peci.c
+new file mode 100644
+index 0000000..28ad1a5
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-peci.c
+@@ -0,0 +1,68 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-peci.c
++* Author : Ryan chen
++* Description : ASPEED PECI Device
++*
++* Copyright (C) ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/08/06 ryan chen create this file
++*
++********************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <plat/devs.h>
++#include <plat/ast-scu.h>
++
++
++/* --------------------------------------------------------------------
++ * PECI
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_AST_PECI) || defined(CONFIG_AST_PECI_MODULE)
++static struct resource ast_peci_resources[] = {
++ [0] = {
++ .start = AST_PECI_BASE,
++ .end = AST_PECI_BASE + SZ_4K - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_PECI,
++ .end = IRQ_PECI,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device ast_peci_device = {
++ .name = "ast_peci",
++ .id = 0,
++ .resource = ast_peci_resources,
++ .num_resources = ARRAY_SIZE(ast_peci_resources),
++};
++
++void __init ast_add_device_peci(void)
++{
++ //SCU PECI CTRL Reset
++ ast_scu_init_peci();
++
++ platform_device_register(&ast_peci_device);
++}
++#else
++void __init ast_add_device_peci(void) {}
++#endif
+diff --git a/arch/arm/plat-aspeed/dev-pwm-fan.c b/arch/arm/plat-aspeed/dev-pwm-fan.c
+new file mode 100644
+index 0000000..85570bb
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-pwm-fan.c
+@@ -0,0 +1,80 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-pwm-fan.c
++* Author : Ryan chen
++* Description : ASPEED PWM-FAN Device
++*
++* Copyright (C) ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/08/06 ryan chen create this file
++*
++********************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <plat/devs.h>
++#include <plat/ast-scu.h>
++#include <mach/ast_pwm_techo.h>
++
++/* --------------------------------------------------------------------
++ * PWM-FAN
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_SENSORS_AST_PWM_FAN) || defined(CONFIG_SENSORS_AST_PWM_FAN_MODULE)
++static struct resource ast_pwm_fan_resources[] = {
++ [0] = {
++ .start = AST_PWM_BASE,
++ .end = AST_PWM_BASE + SZ_4K - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_TACHO,
++ .end = IRQ_TACHO,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct ast_pwm_driver_data ast_pwm_data = {
++ .get_pwm_clock = ast_get_h_pll_clk,
++};
++
++struct platform_device ast_pwm_fan_device = {
++ .name = "ast_pwm_tacho",
++ .id = 0,
++ .dev = {
++ .platform_data = &ast_pwm_data,
++ },
++ .resource = ast_pwm_fan_resources,
++ .num_resources = ARRAY_SIZE(ast_pwm_fan_resources),
++};
++
++void __init ast_add_device_pwm_fan(void)
++{
++ //SCU Initial
++
++ //SCU Pin-MUX //PWM & TACHO
++ ast_scu_multi_func_pwm_tacho();
++
++ //SCU PWM CTRL Reset
++ ast_scu_init_pwm_tacho();
++
++ platform_device_register(&ast_pwm_fan_device);
++}
++#else
++void __init ast_add_device_pwm_fan(void) {}
++#endif
+diff --git a/arch/arm/plat-aspeed/dev-rtc.c b/arch/arm/plat-aspeed/dev-rtc.c
+new file mode 100644
+index 0000000..214aa68
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-rtc.c
+@@ -0,0 +1,65 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-wdt.c
++* Author : Ryan Chen
++* Description : AST WDT Device
++*
++* Copyright (C) ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/09/15 Ryan Chen initial
++*
++********************************************************************************/
++#include <linux/kernel.h>
++#include <linux/platform_device.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++
++#include <plat/devs.h>
++
++
++/* --------------------------------------------------------------------
++ * Watchdog
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_RTC_DRV_AST) || defined(CONFIG_RTC_DRV_AST_MODULE)
++
++static struct resource ast_rtc_resource[] = {
++ [0] = {
++ .start = AST_RTC_BASE,
++ .end = AST_RTC_BASE + SZ_4K - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_RTC,
++ .end = IRQ_RTC,
++ .flags = IORESOURCE_IRQ,
++ },
++
++};
++
++static struct platform_device ast_device_rtc = {
++ .name = "ast_rtc",
++ .id = -1,
++ .resource = ast_rtc_resource,
++ .num_resources = ARRAY_SIZE(ast_rtc_resource),
++};
++
++void __init ast_add_device_rtc(void)
++{
++ platform_device_register(&ast_device_rtc);
++}
++#else
++void __init ast_add_device_rtc(void) {}
++#endif
+diff --git a/arch/arm/plat-aspeed/dev-sdhci.c b/arch/arm/plat-aspeed/dev-sdhci.c
+new file mode 100644
+index 0000000..bcc8cce
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-sdhci.c
+@@ -0,0 +1,110 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-sdhc.c
++* Author : Ryan chen
++* Description : ASPEED SDHC Device
++*
++* Copyright (C) ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/07/30 ryan chen create this file
++*
++********************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <plat/devs.h>
++#include <plat/ast_sdhci.h>
++#include <plat/ast-scu.h>
++
++
++/* --------------------------------------------------------------------
++ * SDHC
++ * -------------------------------------------------------------------- */
++#if defined(CONFIG_MMC_AST) || defined(CONFIG_MMC_AST_MODULE)
++static struct ast_sdhc_platform_data ast_sdhc_info = {
++ .sd_clock_src_get = ast_get_sd_clock_src,
++};
++
++static struct resource ast_sdhci0_resource[] = {
++ [0] = {
++ .start = AST_SDHC_BASE + 0x100,
++ .end = AST_SDHC_BASE + 0x100 + 0xFF,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_SDHC,
++ .end = IRQ_SDHC,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct resource ast_sdhci1_resource[] = {
++ [0] = {
++ .start = AST_SDHC_BASE + 0x200,
++ .end = AST_SDHC_BASE + 0x200 + 0xFF,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_SDHC,
++ .end = IRQ_SDHC,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static u64 ast_sdhc_dma_mask = 0xffffffffUL;
++
++static struct platform_device ast_sdhci_device0 = {
++ .name = "ast_sdhci",
++ .id = 0,
++ .dev = {
++ .dma_mask = &ast_sdhc_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_sdhc_info,
++ },
++ .resource = ast_sdhci0_resource,
++ .num_resources = ARRAY_SIZE(ast_sdhci0_resource),
++};
++
++static struct platform_device ast_sdhci_device1 = {
++ .name = "ast_sdhci",
++ .id = 1,
++ .dev = {
++ .dma_mask = &ast_sdhc_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &ast_sdhc_info,
++ },
++ .resource = ast_sdhci1_resource,
++ .num_resources = ARRAY_SIZE(ast_sdhci1_resource),
++};
++
++void __init ast_add_device_sdhci(void)
++{
++ ast_scu_init_sdhci();
++ //multipin. Remind: AST2300FPGA only supports one port at a time
++
++ ast_scu_multi_func_sdhc_slot1(1);
++
++ platform_device_register(&ast_sdhci_device0);
++
++ ast_scu_multi_func_sdhc_slot2(1);
++
++ platform_device_register(&ast_sdhci_device1);
++}
++#else
++void __init ast_add_device_sdhci(void) {}
++#endif
+diff --git a/arch/arm/plat-aspeed/dev-sgpio.c b/arch/arm/plat-aspeed/dev-sgpio.c
+new file mode 100644
+index 0000000..c6ca2c4
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-sgpio.c
+@@ -0,0 +1,68 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-rtc.c
++* Author : Ryan chen
++* Description : Socle Real Time Clock Device (RTC)
++*
++* Copyright (C) Socle Tech. Corp.
++* 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
++
++* History :
++* 1. 2010/09/15 ryan chen create this file
++*
++********************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++//#include <plat/regs-sgpio.h>
++
++#include <plat/devs.h>
++
++/* --------------------------------------------------------------------
++ * ASPEED SGPIO
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_SGPIO_AST) || defined(CONFIG_SGPIO_AST_MODULE)
++static struct resource ast_sgpio_resource[] = {
++ [0] = {
++ .start = AST_SGPIO_BASE,
++ .end = AST_SGPIO_BASE + SZ_4K - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_SGPIO,
++ .end = IRQ_SGPIO,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device ast_device_sgpio = {
++ .name = "ast-sgpio",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(ast_sgpio_resource),
++ .resource = ast_sgpio_resource,
++};
++
++extern void __init
++ast_add_device_sgpio(void)
++{
++ platform_device_register(&ast_device_sgpio);
++}
++
++#else
++extern void __init ast_add_device_sgpio(void) {}
++#endif
++
+diff --git a/arch/arm/plat-aspeed/dev-snoop.c b/arch/arm/plat-aspeed/dev-snoop.c
+new file mode 100644
+index 0000000..9e286bc
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-snoop.c
+@@ -0,0 +1,94 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-snoop.c
++* Author : Ryan chen
++* Description : ASPEED SNOOP Device
++*
++* Copyright (C) ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/11/29 ryan chen create this file
++*
++********************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <plat/devs.h>
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++
++#include <mach/platform.h>
++#include <plat/devs.h>
++#include <plat/ast-snoop.h>
++
++/* --------------------------------------------------------------------
++ * AST SNOOP -- DMA or 80Port SNOOP
++ * -------------------------------------------------------------------- */
++#if defined(CONFIG_SNOOP_AST) || defined(CONFIG_SNOOP_AST_MODULE)
++static u64 ast_snoop_dma_mask = 0xffffffffUL;
++
++static struct ast_snoop_channel snoop_ch0 = {
++ .snoop_ch = 0,
++ .snoop_port = 0x80,
++};
++
++static struct ast_snoop_channel snoop_ch1 = {
++ .snoop_ch = 1,
++ .snoop_port = 0x81,
++};
++
++static struct ast_snoop snoop = {
++ .snoop_ch0 = &snoop_ch0,
++ .snoop_ch1 = &snoop_ch1,
++};
++
++static struct platform_device ast_snoop_device = {
++ .name = "ast_snoop",
++ .id = 0,
++ .dev = {
++ .dma_mask = &ast_snoop_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &snoop,
++ },
++};
++
++struct ast_snoop_dma_channel snoop_dma_ch0 = {
++ .snoop_ch = 0,
++ .snoop_port = 0x3f8,
++ .snoop_mask = 7,
++};
++
++static struct platform_device ast_snoop_dma_device = {
++ .name = "ast_snoop_dma",
++ .id = 0,
++ .dev = {
++ .dma_mask = &ast_snoop_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &snoop_dma_ch0,
++ },
++};
++
++void __init ast_add_device_snoop(void)
++{
++ platform_device_register(&ast_snoop_device);
++ platform_device_register(&ast_snoop_dma_device);
++}
++#else
++void __init ast_add_device_snoop(void) {}
++#endif
++
+diff --git a/arch/arm/plat-aspeed/dev-spi.c b/arch/arm/plat-aspeed/dev-spi.c
+new file mode 100644
+index 0000000..7ddd2e4
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-spi.c
+@@ -0,0 +1,448 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-spi.c
++* Author : Ryan chen
++* Description : ASPEED SPI device
++*
++* Copyright (C) ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/08/01 ryan chen create this file
++*
++********************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++#include <linux/spi/flash.h>
++
++#include <linux/spi/spi.h>
++
++
++#include <asm/io.h>
++#if defined(CONFIG_COLDFIRE)
++#include <asm/sizes.h>
++#include <asm/arch/ast_spi.h>
++#include <asm/arch/ast-scu.h>
++#include <asm/arch/irqs.h>
++#include <asm/arch/platform.h>
++#include <asm/arch/devs.h>
++#else
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <plat/devs.h>
++#include <plat/regs-fmc.h>
++#include <plat/ast-scu.h>
++#include <mach/ast_spi.h>
++#endif
++
++/* --------------------------------------------------------------------
++ * SPI Ctrl, (AST SPI + FMC SPI)
++ * -------------------------------------------------------------------- */
++#if defined(CONFIG_SPI_FMC) || defined(CONFIG_SPI_FMC_MODULE) || defined(CONFIG_SPI_AST) || defined(CONFIG_SPI_AST_MODULE)
++static u32 ast_spi_calculate_divisor(u32 max_speed_hz)
++{
++ // [0] ->15 : HCLK , HCLK/16
++ u8 SPI_DIV[16] = {16, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 0};
++ u32 i, hclk, spi_cdvr=0;
++
++ hclk = ast_get_h_pll_clk();
++ for(i=1;i<17;i++) {
++ if(max_speed_hz >= (hclk/i)) {
++ spi_cdvr = SPI_DIV[i-1];
++ break;
++ }
++ }
++
++// printk("hclk is %d, divisor is %d, target :%d , cal speed %d\n", hclk, spi_cdvr, spi->max_speed_hz, hclk/i);
++ return spi_cdvr;
++}
++#endif
++
++#if defined(CONFIG_SPI_FMC) || defined(CONFIG_SPI_FMC_MODULE)
++static struct ast_spi_driver_data fmc_spi_data = {
++ .get_div = ast_spi_calculate_divisor,
++ .num_chipselect = 1,
++};
++
++#if defined(CONFIG_AST_CS0_SPI)
++static struct resource ast_fmc_spi_resource0[] = {
++ {
++ .start = AST_FMC_BASE + 0x10,
++ .end = AST_FMC_BASE + 0x10 + SZ_16,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .start = AST_CS0_DEF_BASE,
++ .end = AST_CS0_DEF_BASE + SZ_16,
++ .flags = IORESOURCE_IO,
++ },
++};
++static struct platform_device ast_fmc_spi_device0 = {
++ .name = "fmc-spi",
++ .id = 0,
++ .dev = {
++ .platform_data = &fmc_spi_data,
++ },
++ .num_resources = ARRAY_SIZE(ast_fmc_spi_resource0),
++ .resource = ast_fmc_spi_resource0,
++};
++#endif
++
++#if defined(CONFIG_AST_CS1_SPI)
++static struct resource ast_fmc_spi_resource1[] = {
++ {
++ .start = AST_FMC_BASE + 0x14,
++ .end = AST_FMC_BASE + 0x14 + SZ_16,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .start = AST_CS1_DEF_BASE,
++ .end = AST_CS1_DEF_BASE + SZ_16,
++ .flags = IORESOURCE_IO,
++ },
++};
++static struct platform_device ast_fmc_spi_device1 = {
++ .name = "fmc-spi",
++ .id = 1,
++ .dev = {
++ .platform_data = &fmc_spi_data,
++ },
++ .num_resources = ARRAY_SIZE(ast_fmc_spi_resource1),
++ .resource = ast_fmc_spi_resource1,
++};
++#endif
++
++#if defined(CONFIG_AST_CS2_SPI)
++static struct resource ast_fmc_spi_resource2[] = {
++ {
++ .start = AST_FMC_BASE + 0x18,
++ .end = AST_FMC_BASE + 0x18 + SZ_16,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .start = AST_CS2_DEF_BASE,
++ .end = AST_CS2_DEF_BASE + SZ_16,
++ .flags = IORESOURCE_IO,
++ },
++};
++
++static struct platform_device ast_fmc_spi_device2 = {
++ .name = "fmc-spi",
++ .id = 2,
++ .dev = {
++ .platform_data = &fmc_spi_data,
++ },
++ .num_resources = ARRAY_SIZE(ast_fmc_spi_resource2),
++ .resource = ast_fmc_spi_resource2,
++};
++#endif
++
++#if defined(CONFIG_AST_CS3_SPI)
++static struct resource ast_fmc_spi_resource3[] = {
++ {
++ .start = AST_FMC_BASE + 0x1c,
++ .end = AST_FMC_BASE + 0x1c + SZ_16,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .start = AST_CS3_DEF_BASE,
++ .end = AST_CS3_DEF_BASE + SZ_16,
++ .flags = IORESOURCE_IO,
++ },
++};
++
++static struct platform_device ast_fmc_spi_device3 = {
++ .name = "fmc-spi",
++ .id = 3,
++ .dev = {
++ .platform_data = &fmc_spi_data,
++ },
++ .num_resources = ARRAY_SIZE(ast_fmc_spi_resource3),
++ .resource = ast_fmc_spi_resource3,
++};
++#endif
++
++#if defined(CONFIG_AST_CS4_SPI)
++static struct resource ast_fmc_spi_resource4[] = {
++ {
++ .start = AST_FMC_BASE + 0x20,
++ .end = AST_FMC_BASE + 0x20 + SZ_16,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .start = AST_CS4_DEF_BASE,
++ .end = AST_CS4_DEF_BASE + SZ_16,
++ .flags = IORESOURCE_IO,
++ },
++};
++
++static struct platform_device ast_fmc_spi_device4 = {
++ .name = "fmc-spi",
++ .id = 4,
++ .dev = {
++ .platform_data = &fmc_spi_data,
++ },
++ .num_resources = ARRAY_SIZE(ast_fmc_spi_resource4),
++ .resource = ast_fmc_spi_resource4,
++};
++#endif
++
++#endif //CONFIG_SPI_FMC
++
++#if defined(CONFIG_SPI_AST) || defined(CONFIG_SPI_AST_MODULE)
++static struct ast_spi_driver_data ast_spi0_data = {
++ .get_div = ast_spi_calculate_divisor,
++ .num_chipselect = 1,
++};
++
++static struct resource ast_spi_resource0[] = {
++ {
++ .start = AST_SPI0_BASE,
++ .end = AST_SPI0_BASE + SZ_16,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .start = AST_SPI0_MEM + 0x04,
++ .end = AST_SPI0_MEM + SZ_16,
++ .flags = IORESOURCE_IO,
++ },
++};
++
++static struct platform_device ast_spi_device0 = {
++ .name = "ast-spi",
++#if defined(CONFIG_ARCH_AST1010)
++ .id = 0,
++#else
++ .id = 5,
++#endif
++ .dev = {
++ .platform_data = &ast_spi0_data,
++ },
++ .num_resources = ARRAY_SIZE(ast_spi_resource0),
++ .resource = ast_spi_resource0,
++};
++
++#if defined(AST_SPI1_BASE)
++static struct ast_spi_driver_data ast_spi1_data = {
++ .get_div = ast_spi_calculate_divisor,
++ .num_chipselect = 1,
++};
++
++static struct resource aspeed_spi1_resource[] = {
++ {
++ .start = AST_SPI1_BASE,
++ .end = AST_SPI1_BASE + SZ_16,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .start = AST_SPI1_MEM,
++ .end = AST_SPI1_MEM + SZ_16,
++ .flags = IORESOURCE_IO,
++ },
++};
++
++static struct platform_device aspeed_spi_device1 = {
++ .name = "ast-spi",
++ .id = 1,
++ .dev = {
++ .platform_data = &ast_spi1_data,
++ },
++ .num_resources = ARRAY_SIZE(aspeed_spi1_resource),
++ .resource = aspeed_spi1_resource,
++};
++
++#endif
++
++#endif //CONFIG_SPI_AST
++
++#if defined(CONFIG_ARCH_AST1010)
++static struct mtd_partition ast_spi_flash_partitions[] = {
++ {
++ .name = "uboot",
++ .offset = 0,
++ .size = 0x00030000,
++ .mask_flags = MTD_WRITEABLE,
++ },
++ {
++ .name = "uboot-env",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 0x00010000,
++// .mask_flags = MTD_WRITEABLE,
++ },
++ {
++ .name = "uCLinux",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 0x003c0000,
++// .mask_flags = MTD_CAP_NORFLASH,
++ },
++ {
++ .name = "data",
++ .offset = MTDPART_OFS_APPEND,
++ .size = MTDPART_SIZ_FULL,
++// .mask_flags = MTD_CAP_NORFLASH,
++ }
++};
++#else
++static struct mtd_partition ast_spi_flash_partitions[] = {
++ {
++ .name = "u-boot",
++ .offset = 0,
++ .size = 0x80000,
++ .mask_flags = MTD_WRITEABLE,
++ }, {
++ .name = "kernel",
++ .offset = 0x80000,
++ .size = 0x200000,
++ }, {
++ .name = "rootfs",
++ .offset = 0x300000,
++ .size = 0x4F0000,
++ }, {
++ .name = "env",
++ .offset = 0x7f0000,
++ .size = 0x10000,
++ }, {
++ .name = "data0",
++ .offset = MTDPART_OFS_APPEND,
++ .size = MTDPART_SIZ_FULL,
++ },
++};
++#endif
++
++static struct flash_platform_data ast_spi_flash_data = {
++#if defined(CONFIG_ARCH_AST2400)
++ .type = "mx25l25635e", //AST2400 A1
++#elif defined(CONFIG_ARCH_AST1010)
++ .type = "mx25l6405d",
++#else
++ .type = "mx25l12805d", //old AST2300
++#endif
++ .nr_parts = ARRAY_SIZE(ast_spi_flash_partitions),
++ .parts = ast_spi_flash_partitions,
++};
++
++static struct spi_board_info ast_spi_devices[] = {
++ {
++ .modalias = "m25p80",
++ .platform_data = &ast_spi_flash_data,
++ .chip_select = 0, //.chip_select This tells your device driver which chipselect to use.
++ .max_speed_hz = 50 * 1000 * 1000,
++ .bus_num = 0, // This chooses if SPI0 or SPI1 of the SoC is used.
++ .mode = SPI_MODE_0,
++ },
++ {
++ .modalias = "spidev",
++ .chip_select = 0,
++ .max_speed_hz = 30 * 1000 * 1000,
++ .bus_num = 1,
++ .mode = SPI_MODE_0,
++ },
++};
++
++#if defined(AST_SPI1_BASE)
++static struct mtd_partition ast_spi_flash1_partitions[] = {
++ {
++ .name = "bios",
++ .offset = 0,
++ .size = MTDPART_SIZ_FULL,
++ }
++};
++
++static struct flash_platform_data ast_spi_flash1_data = {
++ .type = "mx25l6405d",
++// .type = "w25q64",
++ .nr_parts = ARRAY_SIZE(ast_spi_flash1_partitions),
++ .parts = ast_spi_flash1_partitions,
++};
++
++
++static struct spi_board_info ast_spi1_devices[] = {
++ {
++ .modalias = "m25p80",
++ .platform_data = &ast_spi_flash1_data,
++ .chip_select = 0, //.chip_select This tells your device driver which chipselect to use.
++ .max_speed_hz = 100 * 1000 * 1000,
++ .bus_num = 1, // This chooses if SPI0 or SPI1 of the SoC is used.
++ .mode = SPI_MODE_0,
++ },
++};
++#endif
++
++#if defined(CONFIG_SPI_FMC) || defined(CONFIG_SPI_FMC_MODULE) || defined(CONFIG_SPI_AST) || defined(CONFIG_SPI_AST_MODULE)
++
++/*-------------------------------------*/
++void __init ast_add_device_spi(void)
++{
++#if defined(CONFIG_SPI_FMC) || defined(CONFIG_SPI_FMC_MODULE)
++ void __iomem *fmc_regs = ioremap(AST_FMC_BASE, 4*SZ_16);
++ u32 tmp = 0;
++
++#if defined(CONFIG_AST_CS0_SPI)
++ platform_device_register(&ast_fmc_spi_device0);
++ tmp = (readl(fmc_regs) | FMC_SET_WRITE_CS(0)) & FMC_MASK_TYPE_CS(0);
++ writel( tmp | FMC_SET_TYPE_SPI_CS(0), fmc_regs);
++#endif
++
++#if defined(CONFIG_AST_CS1_SPI)
++ ast_scu_multi_func_romcs(1);
++ tmp = (readl(fmc_regs) | FMC_SET_WRITE_CS(1)) & FMC_MASK_TYPE_CS(1);
++ writel( tmp | FMC_SET_TYPE_SPI_CS(1), fmc_regs);
++ platform_device_register(&ast_fmc_spi_device1);
++#endif
++
++#if defined(CONFIG_AST_CS2_SPI)
++ ast_scu_multi_func_romcs(2);
++ tmp = (readl(fmc_regs) | FMC_SET_WRITE_CS(2)) & FMC_MASK_TYPE_CS(2);
++ writel( tmp | FMC_SET_TYPE_SPI_CS(2), fmc_regs);
++ platform_device_register(&ast_fmc_spi_device2);
++#endif
++#if defined(CONFIG_AST_CS3_SPI)
++ ast_scu_multi_func_romcs(3);
++ tmp = (readl(fmc_regs) | FMC_SET_WRITE_CS(3)) & FMC_MASK_TYPE_CS(3);
++ writel( tmp | FMC_SET_TYPE_SPI_CS(3), fmc_regs);
++ platform_device_register(&ast_fmc_spi_device3);
++#endif
++#if defined(CONFIG_AST_CS4_SPI)
++ ast_scu_multi_func_romcs(4);
++ tmp = (readl(fmc_regs) | FMC_SET_WRITE_CS(4)) & FMC_MASK_TYPE_CS(4);
++ writel( tmp | FMC_SET_TYPE_SPI_CS(4), fmc_regs);
++ platform_device_register(&ast_fmc_spi_device4);
++#endif
++
++ iounmap(fmc_regs);
++
++#endif
++
++#if defined(CONFIG_SPI_AST) || defined(CONFIG_SPI_AST_MODULE)
++ //pin switch by trap[13:12]
++ platform_device_register(&ast_spi_device0);
++#endif
++
++ spi_register_board_info(ast_spi_devices, ARRAY_SIZE(ast_spi_devices));
++
++#if defined(AST_SPI1_BASE)
++ //AST1010 SCU CONFIG TODO .......
++ writel(readl(AST_SCU_BASE + 0x70) | 0x10,AST_SCU_BASE + 0x70);
++ platform_device_register(&aspeed_spi_device1);
++ spi_register_board_info(ast_spi1_devices, ARRAY_SIZE(ast_spi1_devices));
++#endif
++
++}
++#else
++void __init ast_add_device_spi(void) {}
++#endif
++
++
+diff --git a/arch/arm/plat-aspeed/dev-uart.c b/arch/arm/plat-aspeed/dev-uart.c
+new file mode 100644
+index 0000000..592ef4f
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-uart.c
+@@ -0,0 +1,144 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-uart.c
++* Author : Ryan chen
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/09/15 ryan chen create this file
++*
++********************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++#include <linux/serial.h>
++#include <linux/tty.h>
++#include <linux/serial_8250.h>
++
++#if defined(CONFIG_COLDFIRE)
++#include <asm/sizes.h>
++#include <asm/arch/devs.h>
++#include <asm/arch/platform.h>
++#include <asm/arch/irqs.h>
++#else
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <mach/hardware.h>
++#include <plat/ast-scu.h>
++#include <plat/devs.h>
++#endif
++
++/* --------------------------------------------------------------------
++ * UART
++ * -------------------------------------------------------------------- */
++#ifdef CONFIG_SERIAL_8250
++static struct plat_serial8250_port ast_uart_data[] = {
++ {
++ .mapbase = AST_UART0_BASE,
++ .irq = IRQ_UART0,
++ .uartclk = (24*1000000L),
++ .regshift = 2,
++#if defined(CONFIG_COLDFIRE)
++ .iotype = UPIO_MEM32,
++#else
++ .iotype = UPIO_MEM,
++#endif
++ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++ },
++#if defined(CONFIG_ARCH_AST1010)
++ {
++ .mapbase = AST_UART1_BASE,
++ .irq = IRQ_UART1,
++ .uartclk = (24*1000000L),
++ .regshift = 2,
++ .iotype = UPIO_MEM32,
++ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++ },
++ {
++ .mapbase = AST_UART2_BASE,
++ .irq = IRQ_UART2,
++ .uartclk = (24*1000000L),
++ .regshift = 2,
++ .iotype = UPIO_MEM32,
++ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++ },
++#else
++//BMC UART 1 ,2 default to LPC
++#ifdef CONFIG_ARCH_AST1070
++#ifdef AST_UART1_BASE
++ {
++ .mapbase = AST_UART1_BASE,
++ .irq = IRQ_UART1,
++ .uartclk = (24*1000000L),
++ .regshift = 2,
++ .iotype = UPIO_MEM,
++ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++ },
++#endif
++#ifdef AST_UART2_BASE
++ {
++ .mapbase = AST_UART2_BASE,
++ .irq = IRQ_UART2,
++ .uartclk = (24*1000000L),
++ .regshift = 2,
++ .iotype = UPIO_MEM,
++ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++ },
++#endif
++#endif
++#ifdef AST_UART3_BASE
++ {
++ .mapbase = AST_UART3_BASE,
++ .irq = IRQ_UART3,
++ .uartclk = (24*1000000L),
++ .regshift = 2,
++ .iotype = UPIO_MEM,
++ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++ },
++#endif
++#ifdef AST_UART4_BASE
++ {
++ .mapbase = AST_UART4_BASE,
++ .irq = IRQ_UART4,
++ .uartclk = (24*1000000L),
++ .regshift = 2,
++ .iotype = UPIO_MEM,
++ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++ },
++#endif
++#endif
++ { },
++};
++
++struct platform_device ast_uart_device = {
++ .name = "serial8250",
++ .id = PLAT8250_DEV_PLATFORM,
++ .dev = {
++ .platform_data = ast_uart_data,
++ },
++};
++
++void __init ast_add_device_uart(void)
++{
++#if defined(CONFIG_ARCH_AST1010)
++#else
++ ast_scu_multi_func_uart(3);
++ ast_scu_multi_func_uart(4);
++#endif
++ platform_device_register(&ast_uart_device);
++}
++#else
++void __init ast_add_device_uart(void) {}
++#endif
+diff --git a/arch/arm/plat-aspeed/dev-uhci.c b/arch/arm/plat-aspeed/dev-uhci.c
+new file mode 100644
+index 0000000..961ec9b
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-uhci.c
+@@ -0,0 +1,82 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-uhci.c
++* Author : Ryan chen
++* Description : ASPEED EHCI Device
++*
++* Copyright (C) ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/07/30 ryan chen create this file
++*
++********************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <plat/devs.h>
++#include <plat/ast-scu.h>
++
++/* --------------------------------------------------------------------
++ * UHCI
++ * -------------------------------------------------------------------- */
++#if defined(CONFIG_AST_USB_UHCI_HCD) || defined(CONFIG_AST_USB_UHCI_HCD_MODULE)
++static struct resource ast_uchi_resource[] = {
++ [0] = {
++ .start = AST_UHCI_BASE,
++ .end = AST_UHCI_BASE + SZ_256,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_UHCI,
++ .end = IRQ_UHCI,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static u64 ast_uhci_dma_mask = 0xffffffffUL;
++
++static struct platform_device ast_uhci_device = {
++ .name = "ast_uhci",
++ .id = 0,
++ .dev = {
++ .dma_mask = &ast_uhci_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ },
++ .resource = ast_uchi_resource,
++ .num_resources = ARRAY_SIZE(ast_uchi_resource),
++};
++
++void __init ast_add_device_uhci(void)
++{
++
++#if defined (CONFIG_AST_USB_UHCI_MULTIPORT_2)
++ ast_scu_multi_func_usb11_host_port2(1);
++#elif defined (CONFIG_AST_USB_UHCI_MULTIPORT_4)
++ ast_scu_multi_func_usb11_host_port2(1);
++ ast_scu_multi_func_usb11_host_port4(1);
++#else
++ ast_scu_multi_func_usb11_host_port2(0);
++ ast_scu_multi_func_usb11_host_port4(0);
++#endif
++
++ ast_scu_init_uhci();
++
++ platform_device_register(&ast_uhci_device);
++}
++#else
++void __init ast_add_device_uhci(void) {}
++#endif
+diff --git a/arch/arm/plat-aspeed/dev-video.c b/arch/arm/plat-aspeed/dev-video.c
+new file mode 100644
+index 0000000..3d66eff
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-video.c
+@@ -0,0 +1,102 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-video.c
++* Author : Ryan Chen
++* Description : ASPEED Video Driver
++*
++* Copyright (C) ASPEED Tech. Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2013/04/15 Ryan Chen initial
++*
++********************************************************************************/
++#include <linux/kernel.h>
++#include <linux/platform_device.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++
++#include <plat/devs.h>
++#include <plat/ast-scu.h>
++#include <plat/ast-sdmc.h>
++
++#include <mach/ast_video.h>
++
++/* --------------------------------------------------------------------
++ * AST VIDEO
++ * -------------------------------------------------------------------- */
++#if defined(CONFIG_AST_VIDEO) || defined(CONFIG_AST_VIDEO_MODULE)
++
++#define ASR_VIDEO_MEM AST_DRAM_BASE + SZ_8M*10
++static u32 get_vga_mem_base(void)
++{
++ u32 vga_mem_size, mem_size;
++ mem_size = ast_sdmc_get_mem_size();
++ vga_mem_size = ast_scu_get_vga_memsize();
++ printk("VGA Info : MEM Size %d, VGA Mem Size %d \n",mem_size, vga_mem_size);
++ return (mem_size - vga_mem_size);
++}
++
++static struct ast_video_plat_data video_plat_data = {
++ .get_clk = ast_get_m_pll_clk,
++ .ctrl_reset = ast_scu_reset_video,
++ .vga_display = ast_scu_set_vga_display,
++ .get_vga_base = get_vga_mem_base,
++ .input_source = VIDEO_SOURCE_INTERNAL,
++ .mode = VIDEO_FRAME_MODE,
++ .rc4_enable = 0,
++ .compress = VIDEO_YUV444,
++ .scaling = 0,
++};
++
++
++static struct resource ast_video_resources[] = {
++ [0] = {
++ .start = AST_VIDEO_BASE,
++ .end = AST_VIDEO_BASE + SZ_1K*2 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_VIDEO,
++ .end = IRQ_VIDEO,
++ .flags = IORESOURCE_IRQ,
++ },
++ [2] = {
++ .start = ASR_VIDEO_MEM,
++ .end = ASR_VIDEO_MEM + SZ_32M,
++ .flags = IORESOURCE_DMA,
++ },
++};
++
++static u64 ast_device_video_dmamask = 0xffffffffUL;
++struct platform_device ast_video_device = {
++ .name = "ast-video",
++ .id = 0,
++ .dev = {
++ .dma_mask = &ast_device_video_dmamask,
++ .coherent_dma_mask = 0xffffffffUL,
++ .platform_data= &video_plat_data,
++ },
++ .resource = ast_video_resources,
++ .num_resources = ARRAY_SIZE(ast_video_resources),
++};
++
++void __init ast_add_device_video(void)
++{
++ ast_scu_init_video(0);
++ ast_scu_multi_func_video();
++ platform_device_register(&ast_video_device);
++}
++#else
++void __init ast_add_device_video(void) {}
++#endif
+diff --git a/arch/arm/plat-aspeed/dev-vuart.c b/arch/arm/plat-aspeed/dev-vuart.c
+new file mode 100644
+index 0000000..0e2ab8a
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-vuart.c
+@@ -0,0 +1,100 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-uart.c
++* Author : Ryan chen
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/09/15 ryan chen create this file
++*
++********************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++#include <linux/serial.h>
++#include <linux/tty.h>
++#include <linux/serial_8250.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <mach/hardware.h>
++#include <asm/io.h>
++
++#include <plat/ast-scu.h>
++#include <plat/devs.h>
++
++#include <plat/regs-vuart.h>
++
++#define AST_COM_PORT PORT_3F8
++#define AST_SIRQ SIRQ4
++
++#define PORT_2F8 0x2f8
++#define PORT_3F8 0x3f8
++
++typedef enum SIO_serial_irq {
++ SIRQ0 = 0,
++ SIRQ1,
++ SIRQ2,
++ SIRQ3,
++ SIRQ4,
++ SIRQ5,
++ SIRQ6,
++ SIRQ7,
++ SIRQ8,
++ SIRQ9,
++};
++
++/* --------------------------------------------------------------------
++ * UART
++ * -------------------------------------------------------------------- */
++#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_AST_VUART)
++static struct plat_serial8250_port ast_vuart_data[] = {
++ {
++ .mapbase = AST_VUART0_BASE,
++ .membase = (char*)(IO_ADDRESS(AST_VUART0_BASE)),
++ .irq = IRQ_LPC,
++ .uartclk = (24*1000000L),
++ .regshift = 2,
++ .iotype = UPIO_MEM,
++ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ,
++ },
++ { },
++};
++
++struct platform_device ast_vuart_device = {
++ .name = "serial8250",
++ .id = PLAT8250_DEV_PLATFORM1,
++ .dev = {
++ .platform_data = ast_vuart_data,
++ },
++};
++
++void __init ast_add_device_vuart(void)
++{
++ u32 vuart_base = ioremap(AST_VUART0_BASE, SZ_256);
++
++ writel(0x0, vuart_base + AST_VUART_CTRLA);
++ writel(SET_SIRQ_NUM(AST_SIRQ) |0x3, vuart_base + AST_VUART_CTRLB);
++ writel(AST_COM_PORT & 0xff, vuart_base + AST_VUART_ADDRL);
++ writel(AST_COM_PORT >> 8, vuart_base + AST_VUART_ADDRH);
++ writel(0x0, vuart_base + AST_VUART_CTRLF);
++ writel(VUART_ENABLE | VUART_SIRQ_POLARITY | VUART_DISABLE_H_TX_DISCARD, vuart_base + AST_VUART_CTRLA);
++
++ iounmap(vuart_base);
++ platform_device_register(&ast_vuart_device);
++}
++#else
++void __init ast_add_device_vuart(void) {}
++#endif
+diff --git a/arch/arm/plat-aspeed/dev-wdt.c b/arch/arm/plat-aspeed/dev-wdt.c
+new file mode 100644
+index 0000000..079d1a9
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-wdt.c
+@@ -0,0 +1,76 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/dev-wdt.c
++* Author : Ryan Chen
++* Description : AST WDT Device
++*
++* Copyright (C) ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/09/15 Ryan Chen initial
++*
++********************************************************************************/
++#include <linux/kernel.h>
++#include <linux/platform_device.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++
++#include <plat/devs.h>
++
++/* --------------------------------------------------------------------
++ * Watchdog
++ * -------------------------------------------------------------------- */
++
++#if defined(CONFIG_AST_WATCHDOG) || defined(CONFIG_AST_WATCHDOG_MODULE)
++
++static struct resource ast_wdt_resource0[] = {
++ [0] = {
++ .start = AST_WDT_BASE,
++ .end = AST_WDT_BASE + (SZ_16*2) - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_WDT,
++ .end = IRQ_WDT,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct resource ast_wdt_resource1[] = {
++ [0] = {
++ .start = AST_WDT_BASE + (SZ_16*2),
++ .end = AST_WDT_BASE + (SZ_16*4) - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_WDT,
++ .end = IRQ_WDT,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device ast_device_wdt = {
++ .name = "ast-wdt",
++ .id = -1,
++ .resource = ast_wdt_resource0,
++ .num_resources = ARRAY_SIZE(ast_wdt_resource0),
++};
++
++void __init ast_add_device_watchdog(void)
++{
++ platform_device_register(&ast_device_wdt);
++}
++#else
++void __init ast_add_device_watchdog(void) {}
++#endif
+diff --git a/arch/arm/plat-aspeed/devs.c b/arch/arm/plat-aspeed/devs.c
+new file mode 100644
+index 0000000..7906b9c
+--- /dev/null
++++ b/arch/arm/plat-aspeed/devs.c
+@@ -0,0 +1,69 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/devs.c
++* Author : Ryan chen
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/08/10 create this file [Ryan Chen]
++*
++********************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++
++#include <mach/platform.h>
++
++#include <plat/devs.h>
++
++typedef void (init_fnc_t) (void);
++
++init_fnc_t __initdata *init_all_device[] = {
++ ast_add_device_uart,
++ ast_add_device_vuart,
++ ast_add_device_watchdog,
++ ast_add_device_rtc,
++ ast_add_device_i2c,
++ ast_add_device_spi,
++ ast_add_device_ehci,
++ ast_add_device_nand,
++ ast_add_device_flash,
++ ast_add_device_pwm_fan,
++ ast_add_device_adc,
++ ast_add_device_gpio,
++ ast_add_device_sgpio,
++ ast_add_device_peci,
++ ast_add_device_fb,
++ ast_add_device_sdhci,
++ ast_add_device_uhci,
++ ast_add_device_video,
++ ast_add_device_kcs,
++ ast_add_device_mailbox,
++ ast_add_device_snoop,
++ ast_add_device_gmac,
++// ast_add_device_nand,
++ NULL,
++};
++
++void __init ast_add_all_devices(void)
++{
++ init_fnc_t **init_fnc_ptr;
++
++ for (init_fnc_ptr = init_all_device; *init_fnc_ptr; ++init_fnc_ptr) {
++ (*init_fnc_ptr)();
++ }
++
++ return;
++}
+diff --git a/arch/arm/plat-aspeed/i2c-slave-eeprom.c b/arch/arm/plat-aspeed/i2c-slave-eeprom.c
+new file mode 100644
+index 0000000..fd53f1a
+--- /dev/null
++++ b/arch/arm/plat-aspeed/i2c-slave-eeprom.c
+@@ -0,0 +1,141 @@
++/********************************************************************************
++* File Name : linux/arch/arm/plat-aspeed/i2c-slave-eeprom.c
++* Author : Ryan chen
++* Description : ASPEED I2C Device
++*
++* Copyright (C) ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2013/05/30 ryan chen create this file
++*
++********************************************************************************/
++#include <linux/i2c.h>
++#if defined(CONFIG_COLDFIRE)
++#include <asm/arch/ast_i2c.h>
++#else
++#include <plat/ast_i2c.h>
++#endif
++
++#ifdef I2C_EEPROM
++#define EEPROM_DBUG(fmt, args...) printk("%s() " fmt, __FUNCTION__, ## args)
++#else
++#define EEPROM_DBUG(fmt, args...)
++#endif
++
++static u8 cmd_buf[1] = {0};
++static struct i2c_msg cmd_msg = {
++ .addr = 0x04,
++ .len = 1,
++ .buf = cmd_buf,
++};
++
++//Note 10 byte data memory share for all bus slave device ...........
++#define BUF_SIZE 10
++
++static u8 store_memory[BUF_SIZE] = {0x03,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};
++ // RO, RW, .................
++static struct i2c_msg data_msg = {
++ .addr = 0x04,
++ .len = BUF_SIZE,
++ .buf = store_memory,
++};
++static u8 mem_index = 0;
++static u8 slave_stage = INIT_STAGE;
++
++extern void i2c_slave_init(struct i2c_msg **msgs)
++{
++ *msgs = &cmd_msg;
++}
++
++extern void i2c_slave_xfer(i2c_slave_event_t event, struct i2c_msg **msgs)
++{
++ EEPROM_DBUG("[event %d] \n",event);
++ switch(event) {
++ case I2C_SLAVE_EVENT_START_READ:
++ cmd_msg.flags = I2C_M_RD;
++ data_msg.flags = I2C_M_RD;
++ if(slave_stage == INIT_STAGE) {
++ EEPROM_DBUG("Rt DATA_MSG [%x]\n",data_msg.buf[0]);
++ slave_stage = DATA_STAGE;
++ *msgs = &data_msg;
++ } else {
++ //CMD_STAGE
++ if(cmd_msg.buf[0] != ((cmd_msg.addr << 1)|1))
++ printk("START READ ADDR Error %x\n",cmd_msg.buf[0]);
++
++ EEPROM_DBUG("Rt CMD_DATA_MSG data [%x]\n",store_memory[mem_index]);
++ cmd_msg.buf[0] = store_memory[mem_index];
++ mem_index++;
++ mem_index %=BUF_SIZE;
++ slave_stage = CMD_DATA_STAGE;
++ *msgs = &cmd_msg;
++ }
++ break;
++ case I2C_SLAVE_EVENT_START_WRITE:
++ EEPROM_DBUG("Rt CMD_MSG START_WRITE %x\n",cmd_msg.buf[0]);
++ cmd_msg.flags = 0;
++ if(cmd_msg.buf[0] != cmd_msg.addr <<1)
++ printk("ERROR ADDRESS Match [%x] \n", cmd_msg.buf[0]);
++ slave_stage = CMD_STAGE;
++
++ *msgs = &cmd_msg;
++
++ break;
++
++ case I2C_SLAVE_EVENT_WRITE:
++ cmd_msg.flags = 0;
++ if(slave_stage == CMD_STAGE) {
++ EEPROM_DBUG("w CMD = [index %x] \n",cmd_msg.buf[0]);
++ mem_index = cmd_msg.buf[0];
++ mem_index %= BUF_SIZE;
++ slave_stage = CMD_DATA_STAGE;
++ *msgs = &cmd_msg;
++ } else {
++ EEPROM_DBUG("w index %d CMD_DATA [%x] \n",mem_index, cmd_msg.buf[0]);
++ if(mem_index !=0)
++ store_memory[mem_index] = cmd_msg.buf[0];
++ mem_index++;
++ mem_index %=BUF_SIZE;
++ EEPROM_DBUG("Rt CMD_DATA_MSG \n");
++ *msgs = &cmd_msg;
++ }
++ break;
++ case I2C_SLAVE_EVENT_READ:
++ cmd_msg.flags = I2C_M_RD;
++ if(slave_stage == CMD_DATA_STAGE) {
++ cmd_msg.buf[0] = store_memory[mem_index];
++ mem_index++;
++ mem_index %=BUF_SIZE;
++ EEPROM_DBUG("Rt CMD_DATA_MSG [%x]\n",cmd_msg.buf[0]);
++ *msgs = &cmd_msg;
++ } else {
++ EEPROM_DBUG("Rt DATA_MSG [%x]\n",data_msg.buf[0]);
++ *msgs = &data_msg;
++ }
++ break;
++ case I2C_SLAVE_EVENT_NACK:
++ cmd_msg.flags = I2C_M_RD;
++ slave_stage = INIT_STAGE;
++ *msgs = &cmd_msg;
++
++ break;
++
++ case I2C_SLAVE_EVENT_STOP:
++ cmd_msg.flags = I2C_M_RD;
++ slave_stage = INIT_STAGE;
++ *msgs = &cmd_msg;
++ break;
++ }
++
++}
+diff --git a/arch/arm/plat-aspeed/include/plat/aspeed.h b/arch/arm/plat-aspeed/include/plat/aspeed.h
+new file mode 100644
+index 0000000..4f7c240
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/aspeed.h
+@@ -0,0 +1,44 @@
++/*
++ * arch/arm/plat-aspeed/include/plat/aspeed.h
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#if defined(CONFIG_ARCH_AST3200) || defined(CONFIG_ARCH_AST2500) || defined(CONFIG_ARCH_AST1520)
++#define AST_SOC_G5
++#define NEW_VIC
++#define SRAM_SIZE SZ_32K
++#elif defined(CONFIG_ARCH_AST1400) || defined(CONFIG_ARCH_AST2400) || defined(CONFIG_ARCH_AST3100)
++#define AST_SOC_G4
++#define NEW_VIC
++#define SRAM_SIZE SZ_32K
++#elif defined(CONFIG_ARCH_AST1300) || defined(CONFIG_ARCH_AST2300) || defined(CONFIG_ARCH_AST1510)
++#define AST_SOC_G3
++#define NEW_VIC
++#define SRAM_SIZE SZ_16K
++#elif defined(CONFIG_ARCH_AST2150) || defined(CONFIG_ARCH_AST2200)
++#define AST_SOC_G2_5
++#elif defined(CONFIG_ARCH_AST1100) || defined(CONFIG_ARCH_AST2050) || defined(CONFIG_ARCH_AST2100)
++#define AST_SOC_G2
++#elif defined(CONFIG_ARCH_AST2000) || defined(CONFIG_ARCH_AST1000)
++#define AST_SOC_G1
++#else
++#error "Not define SoC generation"
++#endif
++
++
++
+diff --git a/arch/arm/plat-aspeed/include/plat/ast-lpc.h b/arch/arm/plat-aspeed/include/plat/ast-lpc.h
+new file mode 100644
+index 0000000..1bf2bef
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/ast-lpc.h
+@@ -0,0 +1,34 @@
++/*
++ * Platform data for AST LPC .
++ *
++ * Copyright (C) ASPEED Technology Inc.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation version 2.
++ *
++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
++ * kind, whether express or implied; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++struct ast_lpc_bus_info
++{
++ u8 lpc_dev_mode; /* 0: host mode , 1: dev mode*/
++ u8 bus_scan;
++ u8 scan_node;
++ u8 lpc_mode; /* 0: lpc , 1: lpc+ */
++ u32 bridge_phy_addr;
++};
++
++struct ast_lpc_driver_data
++{
++ struct platform_device *pdev;
++ void __iomem *reg_base; /* virtual */
++ int irq; //I2C IRQ number
++ u32 bus_id; //for i2c dev# IRQ number check
++ struct ast_lpc_bus_info *bus_info;
++};
++
++extern struct ast_lpc_info *ast_get_lpc_info(void);
+diff --git a/arch/arm/plat-aspeed/include/plat/ast-pcie.h b/arch/arm/plat-aspeed/include/plat/ast-pcie.h
+new file mode 100644
+index 0000000..d099c57
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/ast-pcie.h
+@@ -0,0 +1,28 @@
++/*
++ * Platform data for AST PCIe Root Complex module.
++ *
++ * Copyright (C) ASPEED Technology Inc.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation version 2.
++ *
++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
++ * kind, whether express or implied; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#ifndef __AST_PCIE_H_
++#define __AST_PCIE_H_
++
++struct ast_pcie_data {
++ int msi_irq_base;
++ int msi_irq_num;
++ int force_x1;
++ int msi_inv; /* 1 = MSI ack requires "write 0 to clear" */
++ unsigned short int device_id;
++};
++
++#endif
++
+diff --git a/arch/arm/plat-aspeed/include/plat/ast-scu.h b/arch/arm/plat-aspeed/include/plat/ast-scu.h
+new file mode 100644
+index 0000000..77169ee
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/ast-scu.h
+@@ -0,0 +1,92 @@
++/********************************************************************************
++* File Name : arch/arm/mach-aspeed/include/plat/ast-scu.h
++* Author : Ryan Chen
++* Description : AST SCU Service Header
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/08/03 Ryan Chen create this file
++*
++********************************************************************************/
++
++#ifndef __AST_SCU_H_INCLUDED
++#define __AST_SCU_H_INCLUDED
++
++//information
++extern void ast_scu_show_system_info (void);
++extern u32 ast_scu_revision_id(void);
++extern u32 ast_scu_get_phy_interface(u8 mac_num);
++extern u32 ast_scu_get_phy_config(u8 mac_num);
++
++
++//CLK
++extern u32 ast_get_clk_source(void);
++extern u32 ast_get_h_pll_clk(void);
++extern u32 ast_get_m_pll_clk(void);
++extern u32 ast_get_pclk(void);
++extern u32 ast_get_sd_clock_src(void);
++extern u32 ast_get_d2_pll_clk(void);
++extern u32 ast_get_lhclk(void);
++
++extern void ast_scu_set_vga_display(u8 enable);
++extern u32 ast_scu_get_vga_memsize(void);
++
++//Ctrl Initial
++extern void ast_scu_init_video(u8 dynamic_en);
++extern void ast_scu_reset_video(void);
++extern void ast_scu_init_eth(u8 num);
++extern void ast_scu_init_lpc(void);
++extern u8 ast_scu_get_lpc_plus_enable(void);
++extern void ast_scu_init_udc11(void);
++extern void ast_scu_init_usb20(void);
++extern void ast_scu_init_uhci(void);
++extern void ast_scu_init_sdhci(void);
++extern void ast_scu_init_i2c(void);
++extern void ast_scu_init_pwm_tacho(void);
++extern void ast_scu_init_adc(void);
++extern void ast_scu_init_peci(void);
++extern void ast_scu_init_jtag(void);
++extern void ast_scu_init_crt(void);
++
++
++
++//Share pin
++extern void ast_scu_multi_func_uart(u8 uart);
++extern void ast_scu_multi_func_video(void);
++
++extern void ast_scu_multi_func_eth(u8 num);
++
++extern void ast_scu_multi_func_nand(void);
++
++extern void ast_scu_multi_func_nor(void);
++
++extern void ast_scu_multi_func_romcs(u8 num);
++
++extern void ast_scu_multi_func_i2c(void);
++extern void ast_scu_multi_func_pwm_tacho(void);
++//0 : hub mode , 1: usb host mode
++extern void ast_scu_multi_func_usb20_host_hub(u8 mode);
++//0 : gpioQ6,7 mode , 1: usb1.1 host port 4 mode
++extern void ast_scu_multi_func_usb11_host_port4(u8 mode);
++//0 : USB 1.1 HID mode , 1: usb1.1 host port 2 mode
++extern void ast_scu_multi_func_usb11_host_port2(u8 mode);
++
++extern void ast_scu_multi_func_sdhc_slot1(u8 mode);
++extern void ast_scu_multi_func_sdhc_slot2(u8 mode);
++extern void ast_scu_multi_func_crt(void);
++
++
++
++
++
++#endif
+diff --git a/arch/arm/plat-aspeed/include/plat/ast-sdmc.h b/arch/arm/plat-aspeed/include/plat/ast-sdmc.h
+new file mode 100644
+index 0000000..72d8d72
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/ast-sdmc.h
+@@ -0,0 +1,26 @@
++/********************************************************************************
++* File Name : arch/arm/mach-aspeed/include/plat/ast-scu.h
++* Author : Ryan Chen
++* Description : AST SCU Service Header
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/08/03 Ryan Chen create this file
++*
++********************************************************************************/
++
++#ifndef __AST_SDMC_H_INCLUDED
++#define __AST_SDMC_H_INCLUDED
++
++extern u32 ast_sdmc_get_mem_size(void);
++#endif
+diff --git a/arch/arm/plat-aspeed/include/plat/ast-snoop.h b/arch/arm/plat-aspeed/include/plat/ast-snoop.h
+new file mode 100644
+index 0000000..76ea7611
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/ast-snoop.h
+@@ -0,0 +1,37 @@
++/*
++ * ast-snoop_h
++ *
++ *
++ * 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.
++ */
++
++struct ast_snoop_channel {
++ u8 snoop_ch;
++ u8 snoop_port;
++ u8 snoop_data;
++};
++
++struct ast_snoop {
++ struct ast_snoop_channel *snoop_ch0;
++ struct ast_snoop_channel *snoop_ch1;
++};
++
++struct ast_snoop_dma_channel {
++ u8 snoop_ch;
++ u8 snoop_port;
++ u8 snoop_mask;
++ u8 snoop_mode;
++ u8 snoop_index;
++ u32 dma_virt;
++ dma_addr_t dma_addr;
++ u16 dma_size;
++};
++
++extern int ast_snoop_init(struct ast_snoop *snoop);
++extern void ast_snoop_dma_init(struct ast_snoop_dma_channel *ast_dma_ch);
++
++
++
+diff --git a/arch/arm/plat-aspeed/include/plat/ast1070-devs.h b/arch/arm/plat-aspeed/include/plat/ast1070-devs.h
+new file mode 100644
+index 0000000..b3aa799
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/ast1070-devs.h
+@@ -0,0 +1,25 @@
++/********************************************************************************
++* arch/arm/plat-aspeed/include/plat/devs.h
++*
++* Copyright (C) ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++********************************************************************************/
++#ifndef __ASM_PLAT_AST1070_H
++#define __ASM_PLAT_AST1070_H
++
++//ast1070
++extern void __init ast_add_device_cuart(u8 chip, u32 lpc_base);
++extern void __init ast_add_device_clpc(u8 chip, u32 lpc_base);
++extern void __init ast_add_device_ci2c(u8 chip, u32 lpc_base);
++
++#endif
+diff --git a/arch/arm/plat-aspeed/include/plat/ast1070-scu.h b/arch/arm/plat-aspeed/include/plat/ast1070-scu.h
+new file mode 100644
+index 0000000..70c63e2
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/ast1070-scu.h
+@@ -0,0 +1,34 @@
++/********************************************************************************
++* File Name : arch/arm/mach-aspeed/include/plat/ast1070-scu.h
++* Author : Ryan Chen
++* Description : AST1070 SCU Service Header
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2013/05/03 Ryan Chen create this file
++*
++********************************************************************************/
++
++#ifndef __AST1070_SCU_H_INCLUDED
++#define __AST1070_SCU_H_INCLUDED
++
++extern void ast1070_scu_init_i2c(u8 node);
++extern void ast1070_scu_init_uart(u8 node);
++extern void ast1070_scu_revision_id(u8 node);
++extern void ast1070_dma_init(u8 node);
++extern void ast1070_multi_func_uart(u8 node, u8 uart);
++
++
++
++
++#endif
+diff --git a/arch/arm/plat-aspeed/include/plat/ast1070-uart-dma.h b/arch/arm/plat-aspeed/include/plat/ast1070-uart-dma.h
+new file mode 100644
+index 0000000..c4edd75
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/ast1070-uart-dma.h
+@@ -0,0 +1,27 @@
++/********************************************************************************
++* File Name : arch/arm/mach-aspeed/include/plat/ast1070-scu.h
++* Author : Ryan Chen
++* Description : AST1070 SCU Service Header
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2013/05/03 Ryan Chen create this file
++*
++********************************************************************************/
++
++#ifndef __AST1070_UART_DMA_H_INCLUDED
++#define __AST1070_UART_DMA_H_INCLUDED
++
++extern void ast1070_uart_dma_init(u8 node);
++
++#endif
+diff --git a/arch/arm/plat-aspeed/include/plat/ast_i2c.h b/arch/arm/plat-aspeed/include/plat/ast_i2c.h
+new file mode 100644
+index 0000000..b0ff995
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/ast_i2c.h
+@@ -0,0 +1,64 @@
++/*
++ * ast_i2c_h
++ *
++ *
++ * 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.
++ */
++
++//I2C MEMORY Device state machine
++typedef enum i2c_slave_stage {
++ INIT_STAGE,
++ CMD_STAGE,
++ CMD_DATA_STAGE,
++ DATA_STAGE
++} stage;
++
++typedef enum i2c_xfer_mode {
++ BYTE_XFER,
++ BUFF_XFER,
++ DMA_XFER
++} i2c_xfer_mode_t;
++
++//1. usage flag , 2 size, 3. request address
++struct buf_page
++{
++ u8 flag; //0:free to usage, 1: used
++ u8 page_no; //for AST2400 usage
++ u16 page_size;
++ u32 page_addr;
++ u32 page_addr_point;
++};
++
++typedef enum i2c_slave_event_e {
++ I2C_SLAVE_EVENT_START_READ,
++ I2C_SLAVE_EVENT_READ,
++ I2C_SLAVE_EVENT_START_WRITE,
++ I2C_SLAVE_EVENT_WRITE,
++ I2C_SLAVE_EVENT_NACK,
++ I2C_SLAVE_EVENT_STOP
++} i2c_slave_event_t;
++
++#define BYTE_MODE 0
++#define BUFF_MODE 1
++#define DMA_MODE 2
++
++struct ast_i2c_driver_data {
++ void __iomem *reg_gr;
++ u32 bus_clk;
++ u8 master_dma; //0,byte mode 1,Buffer pool mode 256 , or 2048 , 2: DMA mode
++ u8 slave_dma; //0,byte mode 1,Buffer pool mode 256 , or 2048 , 2: DMA mode
++ u8 (*request_pool_buff_page)(struct buf_page **page);
++ void (*free_pool_buff_page)(struct buf_page *page);
++ unsigned char *buf_pool;
++ void (*slave_xfer)(i2c_slave_event_t event, struct i2c_msg **msgs);
++ void (*slave_init)(struct i2c_msg **msgs);
++ u32 (*get_i2c_clock)(void);
++};
++
++#ifdef CONFIG_AST_I2C_SLAVE_MODE
++extern void i2c_slave_init(struct i2c_msg **msgs);
++extern void i2c_slave_xfer(i2c_slave_event_t event, struct i2c_msg **msgs);
++#endif
+\ No newline at end of file
+diff --git a/arch/arm/plat-aspeed/include/plat/ast_mctp.h b/arch/arm/plat-aspeed/include/plat/ast_mctp.h
+new file mode 100644
+index 0000000..51396ff
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/ast_mctp.h
+@@ -0,0 +1,31 @@
++/********************************************************************************
++* File Name : arch/arm/mach-aspeed/include/plat/ast-scu.h
++* Author : Ryan Chen
++* Description : AST SCU Service Header
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/08/03 Ryan Chen create this file
++*
++********************************************************************************/
++
++#ifndef __AST_P2X_H_INCLUDED
++#define __AST_P2X_H_INCLUDED
++
++extern void ast_pcie_cfg_read(u8 type, u32 bdf_offset, u32 *value);
++//extern void ast_pcie_cfg_write(u8 type, u32 bdf_offset, u32 data);
++extern void ast_pcie_cfg_write(u8 type, u8 byte_en, u32 bdf_offset, u32 data);
++extern void ast_mctp_addr_map(u32 mask, u32 addr);
++
++#endif
++
+diff --git a/arch/arm/plat-aspeed/include/plat/ast_sdhci.h b/arch/arm/plat-aspeed/include/plat/ast_sdhci.h
+new file mode 100644
+index 0000000..13547af
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/ast_sdhci.h
+@@ -0,0 +1,290 @@
++/*
++ * sdhci.h - Secure Digital Host Controller Interface driver
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or (at
++ * your option) any later version.
++ */
++
++#include <linux/scatterlist.h>
++#include <linux/leds.h>
++#include <linux/interrupt.h>
++
++
++/*
++ * Controller registers
++ */
++
++#define SDHCI_DMA_ADDRESS 0x00
++
++#define SDHCI_BLOCK_SIZE 0x04
++#define SDHCI_MAKE_BLKSZ(dma, blksz) (((dma & 0x7) << 12) | (blksz & 0xFFF))
++
++#define SDHCI_BLOCK_COUNT 0x06
++
++#define SDHCI_ARGUMENT 0x08
++
++#define SDHCI_TRANSFER_MODE 0x0C
++#define SDHCI_TRNS_DMA 0x01
++#define SDHCI_TRNS_BLK_CNT_EN 0x02
++#define SDHCI_TRNS_ACMD12 0x04
++#define SDHCI_TRNS_READ 0x10
++#define SDHCI_TRNS_MULTI 0x20
++
++#define SDHCI_COMMAND 0x0E
++#define SDHCI_CMD_RESP_MASK 0x03
++#define SDHCI_CMD_CRC 0x08
++#define SDHCI_CMD_INDEX 0x10
++#define SDHCI_CMD_DATA 0x20
++
++#define SDHCI_CMD_RESP_NONE 0x00
++#define SDHCI_CMD_RESP_LONG 0x01
++#define SDHCI_CMD_RESP_SHORT 0x02
++#define SDHCI_CMD_RESP_SHORT_BUSY 0x03
++
++#define SDHCI_MAKE_CMD(c, f) (((c & 0xff) << 8) | (f & 0xff))
++
++#define SDHCI_RESPONSE 0x10
++
++#define SDHCI_BUFFER 0x20
++
++#define SDHCI_PRESENT_STATE 0x24
++#define SDHCI_CMD_INHIBIT 0x00000001
++#define SDHCI_DATA_INHIBIT 0x00000002
++#define SDHCI_DOING_WRITE 0x00000100
++#define SDHCI_DOING_READ 0x00000200
++#define SDHCI_SPACE_AVAILABLE 0x00000400
++#define SDHCI_DATA_AVAILABLE 0x00000800
++#define SDHCI_CARD_PRESENT 0x00010000
++#define SDHCI_WRITE_PROTECT 0x00080000
++
++#define SDHCI_HOST_CONTROL 0x28
++#define SDHCI_CTRL_LED 0x01
++#define SDHCI_CTRL_4BITBUS 0x02
++#define SDHCI_CTRL_HISPD 0x04
++#define SDHCI_CTRL_DMA_MASK 0x18
++#define SDHCI_CTRL_SDMA 0x00
++#define SDHCI_CTRL_ADMA1 0x08
++#define SDHCI_CTRL_ADMA32 0x10
++#define SDHCI_CTRL_ADMA64 0x18
++
++#define SDHCI_POWER_CONTROL 0x29
++#define SDHCI_POWER_ON 0x01
++#define SDHCI_POWER_180 0x0A
++#define SDHCI_POWER_300 0x0C
++#define SDHCI_POWER_330 0x0E
++
++#define SDHCI_BLOCK_GAP_CONTROL 0x2A
++
++#define SDHCI_WAKE_UP_CONTROL 0x2B
++
++#define SDHCI_CLOCK_CONTROL 0x2C
++#define SDHCI_DIVIDER_SHIFT 8
++#define SDHCI_CLOCK_CARD_EN 0x0004
++#define SDHCI_CLOCK_INT_STABLE 0x0002
++#define SDHCI_CLOCK_INT_EN 0x0001
++
++#define SDHCI_TIMEOUT_CONTROL 0x2E
++
++#define SDHCI_SOFTWARE_RESET 0x2F
++#define SDHCI_RESET_ALL 0x01
++#define SDHCI_RESET_CMD 0x02
++#define SDHCI_RESET_DATA 0x04
++
++#define SDHCI_INT_STATUS 0x30
++#define SDHCI_INT_ENABLE 0x34
++#define SDHCI_SIGNAL_ENABLE 0x38
++#define SDHCI_INT_RESPONSE 0x00000001
++#define SDHCI_INT_DATA_END 0x00000002
++#define SDHCI_INT_DMA_END 0x00000008
++#define SDHCI_INT_SPACE_AVAIL 0x00000010
++#define SDHCI_INT_DATA_AVAIL 0x00000020
++#define SDHCI_INT_CARD_INSERT 0x00000040
++#define SDHCI_INT_CARD_REMOVE 0x00000080
++#define SDHCI_INT_CARD_INT 0x00000100
++#define SDHCI_INT_ERROR 0x00008000
++#define SDHCI_INT_TIMEOUT 0x00010000
++#define SDHCI_INT_CRC 0x00020000
++#define SDHCI_INT_END_BIT 0x00040000
++#define SDHCI_INT_INDEX 0x00080000
++#define SDHCI_INT_DATA_TIMEOUT 0x00100000
++#define SDHCI_INT_DATA_CRC 0x00200000
++#define SDHCI_INT_DATA_END_BIT 0x00400000
++#define SDHCI_INT_BUS_POWER 0x00800000
++#define SDHCI_INT_ACMD12ERR 0x01000000
++#define SDHCI_INT_ADMA_ERROR 0x02000000
++
++#define SDHCI_INT_NORMAL_MASK 0x00007FFF
++#define SDHCI_INT_ERROR_MASK 0xFFFF8000
++
++#define SDHCI_INT_CMD_MASK (SDHCI_INT_RESPONSE | SDHCI_INT_TIMEOUT | \
++ SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX)
++#define SDHCI_INT_DATA_MASK (SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \
++ SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \
++ SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \
++ SDHCI_INT_DATA_END_BIT)
++
++#define SDHCI_ACMD12_ERR 0x3C
++
++/* 3E-3F reserved */
++
++#define SDHCI_CAPABILITIES 0x40
++#define SDHCI_TIMEOUT_CLK_MASK 0x0000003F
++#define SDHCI_TIMEOUT_CLK_SHIFT 0
++#define SDHCI_TIMEOUT_CLK_UNIT 0x00000080
++#define SDHCI_CLOCK_BASE_MASK 0x00003F00
++#define SDHCI_CLOCK_BASE_SHIFT 8
++#define SDHCI_MAX_BLOCK_MASK 0x00030000
++#define SDHCI_MAX_BLOCK_SHIFT 16
++#define SDHCI_CAN_DO_ADMA2 0x00080000
++#define SDHCI_CAN_DO_ADMA1 0x00100000
++#define SDHCI_CAN_DO_HISPD 0x00200000
++#define SDHCI_CAN_DO_DMA 0x00400000
++#define SDHCI_CAN_VDD_330 0x01000000
++#define SDHCI_CAN_VDD_300 0x02000000
++#define SDHCI_CAN_VDD_180 0x04000000
++#define SDHCI_CAN_64BIT 0x10000000
++
++/* 44-47 reserved for more caps */
++
++#define SDHCI_MAX_CURRENT 0x48
++
++/* 4C-4F reserved for more max current */
++
++#define SDHCI_SET_ACMD12_ERROR 0x50
++#define SDHCI_SET_INT_ERROR 0x52
++
++#define SDHCI_ADMA_ERROR 0x54
++
++/* 55-57 reserved */
++
++#define SDHCI_ADMA_ADDRESS 0x58
++
++/* 60-FB reserved */
++
++#define SDHCI_SLOT_INT_STATUS 0xFC
++
++#define SDHCI_HOST_VERSION 0xFE
++#define SDHCI_VENDOR_VER_MASK 0xFF00
++#define SDHCI_VENDOR_VER_SHIFT 8
++#define SDHCI_SPEC_VER_MASK 0x00FF
++#define SDHCI_SPEC_VER_SHIFT 0
++#define SDHCI_SPEC_100 0
++#define SDHCI_SPEC_200 1
++
++struct sdhci_ops;
++
++struct sdhci_host {
++ /* Data set by hardware interface driver */
++ const char *hw_name; /* Hardware bus name */
++
++ unsigned int quirks; /* Deviations from spec. */
++
++/* Controller doesn't honor resets unless we touch the clock register */
++#define SDHCI_QUIRK_CLOCK_BEFORE_RESET (1<<0)
++/* Controller has bad caps bits, but really supports DMA */
++#define SDHCI_QUIRK_FORCE_DMA (1<<1)
++/* Controller doesn't like to be reset when there is no card inserted. */
++#define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2)
++/* Controller doesn't like clearing the power reg before a change */
++#define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3)
++/* Controller has flaky internal state so reset it on each ios change */
++#define SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS (1<<4)
++/* Controller has an unusable DMA engine */
++#define SDHCI_QUIRK_BROKEN_DMA (1<<5)
++/* Controller has an unusable ADMA engine */
++#define SDHCI_QUIRK_BROKEN_ADMA (1<<6)
++/* Controller can only DMA from 32-bit aligned addresses */
++#define SDHCI_QUIRK_32BIT_DMA_ADDR (1<<7)
++/* Controller can only DMA chunk sizes that are a multiple of 32 bits */
++#define SDHCI_QUIRK_32BIT_DMA_SIZE (1<<8)
++/* Controller can only ADMA chunks that are a multiple of 32 bits */
++#define SDHCI_QUIRK_32BIT_ADMA_SIZE (1<<9)
++/* Controller needs to be reset after each request to stay stable */
++#define SDHCI_QUIRK_RESET_AFTER_REQUEST (1<<10)
++/* Controller needs voltage and power writes to happen separately */
++#define SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER (1<<11)
++/* Controller provides an incorrect timeout value for transfers */
++#define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL (1<<12)
++/* Controller has an issue with buffer bits for small transfers */
++#define SDHCI_QUIRK_BROKEN_SMALL_PIO (1<<13)
++/* Controller supports high speed but doesn't have the caps bit set */
++#define SDHCI_QUIRK_FORCE_HIGHSPEED (1<<14)
++/* Controller does not provide transfer-complete interrupt when not busy */
++#define SDHCI_QUIRK_NO_BUSY_IRQ (1<<15)
++
++ int irq; /* Device IRQ */
++ void __iomem * ioaddr; /* Mapped address */
++
++ const struct sdhci_ops *ops; /* Low level hw interface */
++
++ /* Internal data */
++ struct mmc_host *mmc; /* MMC structure */
++ u64 dma_mask; /* custom DMA mask */
++
++#ifdef CONFIG_LEDS_CLASS
++ struct led_classdev led; /* LED control */
++ char led_name[32];
++#endif
++
++ spinlock_t lock; /* Mutex */
++
++ int flags; /* Host attributes */
++#define SDHCI_USE_DMA (1<<0) /* Host is DMA capable */
++#define SDHCI_USE_ADMA (1<<1) /* Host is ADMA capable */
++#define SDHCI_REQ_USE_DMA (1<<2) /* Use DMA for this req. */
++#define SDHCI_DEVICE_DEAD (1<<3) /* Device unresponsive */
++
++ unsigned int version; /* SDHCI spec. version */
++
++ unsigned int max_clk; /* Max possible freq (MHz) */
++ unsigned int timeout_clk; /* Timeout freq (KHz) */
++
++ unsigned int clock; /* Current clock (MHz) */
++ unsigned short power; /* Current voltage */
++
++ struct mmc_request *mrq; /* Current request */
++ struct mmc_command *cmd; /* Current command */
++ struct mmc_data *data; /* Current data request */
++ unsigned int data_early:1; /* Data finished before cmd */
++
++ struct sg_mapping_iter sg_miter; /* SG state for PIO */
++ unsigned int blocks; /* remaining PIO blocks */
++
++ int sg_count; /* Mapped sg entries */
++
++ u8 *adma_desc; /* ADMA descriptor table */
++ u8 *align_buffer; /* Bounce buffer */
++
++ dma_addr_t adma_addr; /* Mapped ADMA descr. table */
++ dma_addr_t align_addr; /* Mapped bounce buffer */
++
++ struct tasklet_struct card_tasklet; /* Tasklet structures */
++ struct tasklet_struct finish_tasklet;
++
++ struct timer_list timer; /* Timer for timeouts */
++
++ unsigned long private[0] ____cacheline_aligned;
++};
++
++struct ast_sdhc_platform_data {
++ u32 (*sd_clock_src_get)(void);
++};
++
++extern struct sdhci_host *sdhci_alloc_host(struct device *dev,
++ size_t priv_size);
++extern void sdhci_free_host(struct sdhci_host *host);
++
++static inline void *sdhci_priv(struct sdhci_host *host)
++{
++ return (void *)host->private;
++}
++
++extern int sdhci_add_host(struct sdhci_host *host);
++extern void sdhci_remove_host(struct sdhci_host *host, int dead);
++
++#ifdef CONFIG_PM
++extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state);
++extern int sdhci_resume_host(struct sdhci_host *host);
++#endif
+diff --git a/arch/arm/plat-aspeed/include/plat/devs.h b/arch/arm/plat-aspeed/include/plat/devs.h
+new file mode 100644
+index 0000000..41cbea9
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/devs.h
+@@ -0,0 +1,65 @@
++/********************************************************************************
++* arch/arm/plat-aspeed/include/plat/devs.h
++*
++* Copyright (C) ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++********************************************************************************/
++#ifndef __ASM_PLAT_ASPEED_H
++#define __ASM_PLAT_ASPEED_H
++
++extern void __init ast_add_all_devices(void);
++
++//platform
++extern void __init ast_add_device_uart(void);
++extern void __init ast_add_device_vuart(void);
++extern void __init ast_add_device_watchdog(void);
++extern void __init ast_add_device_rtc(void);
++extern void __init ast_add_device_gpio(void);
++extern void __init ast_add_device_sgpio(void);
++
++//ADC
++
++//Bus
++extern void __init ast_add_device_lpc(void);
++extern void __init ast_add_device_snoop(void);
++extern void __init ast_add_device_kcs(void);
++extern void __init ast_add_device_mailbox(void);
++extern void __init ast_add_device_i2c(void);
++extern void __init ast_add_device_spi(void);
++extern void __init ast_add_device_ehci(void);
++extern void __init ast_add_device_uhci(void);
++extern void __init ast_add_device_gmac(void);
++extern void __init ast_add_device_udc11(void);
++extern void __init ast_add_device_hid(void);
++
++extern void __init ast_add_device_pcie(void);
++
++extern void __init ast_add_device_peci(void);
++extern void __init ast_add_device_jtag(void);
++
++//hwmon
++extern void __init ast_add_device_pwm_fan(void);
++extern void __init ast_add_device_adc(void);
++
++
++//Storage
++extern void __init ast_add_device_nand(void);
++extern void __init ast_add_device_flash(void);
++extern void __init ast_add_device_sdhci(void);
++extern void __init ast_add_device_nand(void);
++
++//video
++extern void __init ast_add_device_fb(void);
++extern void __init ast_add_device_video(void);
++
++#endif
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-1070_lpc.h b/arch/arm/plat-aspeed/include/plat/regs-1070_lpc.h
+new file mode 100644
+index 0000000..ef8cd8c
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-1070_lpc.h
+@@ -0,0 +1,32 @@
++/* arch/arm/plat-aspeed/include/mach/regs-1070_lpc.h
++ *
++ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
++ * http://www.aspeedtech.com/
++ *
++ * 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.
++ *
++ * ASPEED AST1070 LPC Controller
++*/
++
++#ifndef __ASM_ARCH_REGS_LPC_H
++#define __ASM_ARCH_REGS_LPC_H __FILE__
++
++#define AST1070_LPC_HICR0 0x00
++#define AST1070_LPC_HICR1 0x04
++#define AST1070_LPC_HICR2 0x08
++#define AST1070_LPC_HICR3 0x0c
++#define AST1070_LPC_HICR4 0x10
++
++//for snoop driver
++#define AST1070_LPC_L_80H_ADDR 0x220
++#define AST1070_LPC_H_80H_ADDR 0x224
++#define AST1070_LPC_80H_DATA 0x228
++#define AST1070_LPC_80H_CTRL 0x22c
++
++
++#define AST1070_LPC_80H_CLR (0x1 << 4)
++
++#define AST1070_LPC_80H_EN 0x1
++#endif /* __ASM_ARCH_REGS_LPC_H */
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-adc.h b/arch/arm/plat-aspeed/include/plat/regs-adc.h
+new file mode 100644
+index 0000000..97f5919
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-adc.h
+@@ -0,0 +1,191 @@
++/* arch/arm/plat-aspeed/include/mach/regs-adc.h
++ *
++ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
++ * http://www.aspeedtech.com/
++ *
++ * 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.
++ *
++ * ASPEED ADC Controller
++*/
++
++#ifndef __ASM_ARCH_REGS_ADC_H
++#define __ASM_ARCH_REGS_ADC_H __FILE__
++
++#if defined(CONFIG_ARCH_AST2300)
++#define MAX_CH_NO 12
++#elif defined(CONFIG_ARCH_AST2400) || defined(CONFIG_ARCH_AST2500)
++#define MAX_CH_NO 16
++#elif defined(CONFIG_ARCH_AST1010)
++#define MAX_CH_NO 8
++#else
++#err "ADC NO define MAX CHANNEL NO"
++#endif
++
++#if defined(CONFIG_ARCH_AST2500)
++#define TEMPER_CH_NO 2
++#endif
++
++/*AST ADC Register Definition */
++#define AST_ADC_CTRL 0x00
++#define AST_ADC_IER 0x04
++#define AST_ADC_VGA 0x08
++#if defined(CONFIG_ARCH_AST1010)
++#define AST_ADC_TRIM 0x08
++#endif
++#define AST_ADC_CLK 0x0c
++#define AST_ADC_CH0_1 0x10
++#define AST_ADC_CH2_3 0x14
++#define AST_ADC_CH4_5 0x18
++#define AST_ADC_CH6_7 0x1c
++#define AST_ADC_CH8_9 0x20
++#define AST_ADC_CH10_11 0x24
++#define AST_ADC_CH12_13 0x28
++#define AST_ADC_CH14_15 0x2c
++#define AST_ADC_BOUND0 0x30
++#define AST_ADC_BOUND1 0x34
++#define AST_ADC_BOUND2 0x38
++#define AST_ADC_BOUND3 0x3c
++#define AST_ADC_BOUND4 0x40
++#define AST_ADC_BOUND5 0x44
++#define AST_ADC_BOUND6 0x48
++#define AST_ADC_BOUND7 0x4c
++#define AST_ADC_BOUND8 0x50
++#define AST_ADC_BOUND9 0x54
++#define AST_ADC_BOUND10 0x58
++#define AST_ADC_BOUND11 0x5c
++#define AST_ADC_BOUND12 0x60
++#define AST_ADC_BOUND13 0x64
++#define AST_ADC_BOUND14 0x68
++#define AST_ADC_BOUND15 0x6c
++#define AST_ADC_HYSTER0 0x70
++#define AST_ADC_HYSTER1 0x74
++#define AST_ADC_HYSTER2 0x78
++#define AST_ADC_HYSTER3 0x7c
++#define AST_ADC_HYSTER4 0x80
++#define AST_ADC_HYSTER5 0x84
++#define AST_ADC_HYSTER6 0x88
++#define AST_ADC_HYSTER7 0x8c
++#define AST_ADC_HYSTER8 0x90
++#define AST_ADC_HYSTER9 0x94
++#define AST_ADC_HYSTER10 0x98
++#define AST_ADC_HYSTER11 0x9c
++#define AST_ADC_HYSTER12 0xa0
++#define AST_ADC_HYSTER13 0xa4
++#define AST_ADC_HYSTER14 0xa8
++#define AST_ADC_HYSTER15 0xac
++#define AST_ADC_INTR_SEL 0xC0
++#if defined(CONFIG_ARCH_AST2500)
++#define AST_ADC_CH16 0xD0
++#define AST_ADC_CH17 0xD4
++#endif
++
++
++#define AST_ADC_TRIM 0xC4
++
++// AST_ADC_CTRL:0x00 - ADC Engine Control Register
++#define AST_ADC_CTRL_CH15_EN (0x1 << 31)
++#define AST_ADC_CTRL_CH14_EN (0x1 << 30)
++#define AST_ADC_CTRL_CH13_EN (0x1 << 29)
++#define AST_ADC_CTRL_CH12_EN (0x1 << 28)
++#define AST_ADC_CTRL_CH11_EN (0x1 << 27)
++#define AST_ADC_CTRL_CH10_EN (0x1 << 26)
++#define AST_ADC_CTRL_CH9_EN (0x1 << 25)
++#define AST_ADC_CTRL_CH8_EN (0x1 << 24)
++#define AST_ADC_CTRL_CH7_EN (0x1 << 23)
++#define AST_ADC_CTRL_CH6_EN (0x1 << 22)
++#define AST_ADC_CTRL_CH5_EN (0x1 << 21)
++#define AST_ADC_CTRL_CH4_EN (0x1 << 20)
++#define AST_ADC_CTRL_CH3_EN (0x1 << 19)
++#define AST_ADC_CTRL_CH2_EN (0x1 << 18)
++#define AST_ADC_CTRL_CH1_EN (0x1 << 17)
++#define AST_ADC_CTRL_CH0_EN (0x1 << 16)
++
++#if defined(CONFIG_ARCH_AST2300)
++#define AST_ADC_CTRL_COMPEN_CLR (0x1 << 6)
++#define AST_ADC_CTRL_COMPEN (0x1 << 5)
++#elif defined(CONFIG_ARCH_AST2400)
++#define AST_ADC_CTRL_COMPEN (0x1 << 4)
++#elif defined(CONFIG_ARCH_AST2500)
++#define AST_ADC_CTRL_INIT_RDY (0x1 << 8)
++#define AST_ADC_CTRL_COMPEN (0x1 << 5)
++#else
++#err "ERROR define COMPEN ADC"
++#endif
++
++#if defined(CONFIG_ARCH_AST1010)
++#define AST_ADC_CTRL_OTP (0x1 << 3)
++#define AST_ADC_CTRL_PWR_DWN (0x1 << 2)
++#define AST_ADC_CTRL_TEST (0x1 << 1)
++#endif
++
++#define AST_ADC_CTRL_NORMAL (0x7 << 1)
++
++#define AST_ADC_CTRL_EN (0x1)
++
++
++/* AST_ADC_IER : 0x04 - Interrupt Enable and Interrupt status */
++#define AST_ADC_IER_CH15 (0x1 << 31)
++#define AST_ADC_IER_CH14 (0x1 << 30)
++#define AST_ADC_IER_CH13 (0x1 << 29)
++#define AST_ADC_IER_CH12 (0x1 << 28)
++#define AST_ADC_IER_CH11 (0x1 << 27)
++#define AST_ADC_IER_CH10 (0x1 << 26)
++#define AST_ADC_IER_CH9 (0x1 << 25)
++#define AST_ADC_IER_CH8 (0x1 << 24)
++#define AST_ADC_IER_CH7 (0x1 << 23)
++#define AST_ADC_IER_CH6 (0x1 << 22)
++#define AST_ADC_IER_CH5 (0x1 << 21)
++#define AST_ADC_IER_CH4 (0x1 << 20)
++#define AST_ADC_IER_CH3 (0x1 << 19)
++#define AST_ADC_IER_CH2 (0x1 << 18)
++#define AST_ADC_IER_CH1 (0x1 << 17)
++#define AST_ADC_IER_CH0 (0x1 << 16)
++#define AST_ADC_STS_CH15 (0x1 << 15)
++#define AST_ADC_STS_CH14 (0x1 << 14)
++#define AST_ADC_STS_CH13 (0x1 << 13)
++#define AST_ADC_STS_CH12 (0x1 << 12)
++#define AST_ADC_STS_CH11 (0x1 << 11)
++#define AST_ADC_STS_CH10 (0x1 << 10)
++#define AST_ADC_STS_CH9 (0x1 << 9)
++#define AST_ADC_STS_CH8 (0x1 << 8)
++#define AST_ADC_STS_CH7 (0x1 << 7)
++#define AST_ADC_STS_CH6 (0x1 << 6)
++#define AST_ADC_STS_CH5 (0x1 << 5)
++#define AST_ADC_STS_CH4 (0x1 << 4)
++#define AST_ADC_STS_CH3 (0x1 << 3)
++#define AST_ADC_STS_CH2 (0x1 << 2)
++#define AST_ADC_STS_CH1 (0x1 << 1)
++#define AST_ADC_STS_CH0 (0x1)
++
++/* AST_ADC_VGA : 0x08 - VGA Detect Control */
++#define AST_ADC_VGA_EN (0x1 << 16)
++#define AST_ADC_VGA_DIV_MASK (0x3ff)
++
++/* AST_ADC_CLK : 0x0c - ADC CLK Control */
++#define AST_ADC_CLK_PRE_DIV_MASK (0x7fff << 17)
++#define AST_ADC_CLK_PRE_DIV (0x1 << 17)
++#define AST_ADC_CLK_INVERT (0x1 << 16) //only for ast2300
++#define AST_ADC_CLK_DIV_MASK (0x3ff)
++
++#define AST_ADC_H_CH_MASK (0x3ff << 16)
++#define AST_ADC_L_CH_MASK (0x3ff)
++
++#define AST_ADC_H_BOUND (0x3ff << 16)
++#define AST_ADC_L_BOUND (0x3ff)
++
++#define AST_ADC_HYSTER_EN (0x1 << 31)
++
++#if defined(CONFIG_ARCH_AST2500)
++/* AST_ADC_CH16 : 0xD0 - */
++/* AST_ADC_CH17 : 0xD4 - */
++#define AST_TEMP_CH_RDY (0x1 << 31)
++#define AST_GET_TEMP_A_MASK(x) ((x >>16) & 0xfff)
++#define AST_TEMP_CH_EN (0x1 << 15)
++#define AST_GET_TEMP_B_MASK(x) (x & 0xfff)
++
++
++#endif
++
++#endif /* __ASM_ARCH_REGS_ADC_H */
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-ast1070-intc.h b/arch/arm/plat-aspeed/include/plat/regs-ast1070-intc.h
+new file mode 100644
+index 0000000..00dd1cb
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-ast1070-intc.h
+@@ -0,0 +1,42 @@
++/* arch/arm/mach-aspeed/include/mach/regs-intr.h
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * 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.
++ *
++ * History :
++ * 1. 2012/08/15 Ryan Chen Create
++ *
++********************************************************************************/
++#ifndef __ASPEED_AST1070_INTR_H
++#define __ASPEED_AST1070_INTR_H 1
++
++#include <asm/io.h>
++#include <mach/platform.h>
++#include <mach/irqs.h>
++
++/*
++ * VIC Register (VA)
++ */
++
++#define VIC_BASE_VA(x) IO_ADDRESS2(AST_C0_VIC_BASE + (0x10000*x))
++
++#define AST_IRQ_STS(x) (VIC_BASE_VA(x) + 0x00)
++#define AST_RAW_STS(x) (VIC_BASE_VA(x) + 0x08)
++#define AST_INTR_EN(x) (VIC_BASE_VA(x) + 0x10)
++#define AST_INTR_DIS(x) (VIC_BASE_VA(x) + 0x14)
++#define AST_INTR_SENSE(x) (VIC_BASE_VA(x) + 0x24)
++#define AST_INTR_BOTH_EDGE(x) (VIC_BASE_VA(x) + 0x28)
++#define AST_INTR_EVENT(x) (VIC_BASE_VA(x) + 0x2C)
++
++#define IRQ_SET_LEVEL_TRIGGER(x,irq_no) *((volatile unsigned long*)AST_INTR_SENSE(x)) |= 1 << (irq_no)
++#define IRQ_SET_EDGE_TRIGGER(x,irq_no) *((volatile unsigned long*)AST_INTR_SENSE(x)) &= ~(1 << (irq_no))
++#define IRQ_SET_RISING_EDGE(x,irq_no) *((volatile unsigned long*)AST_INTR_EVENT(x)) |= 1 << (irq_no)
++#define IRQ_SET_FALLING_EDGE(x,irq_no) *((volatile unsigned long*)AST_INTR_EVENT(x)) &= ~(1 << (irq_no))
++#define IRQ_SET_HIGH_LEVEL(x,irq_no) *((volatile unsigned long*)AST_INTR_EVENT(x)) |= 1 << (irq_no)
++#define IRQ_SET_LOW_LEVEL(x,irq_no) *((volatile unsigned long*)AST_INTR_EVENT(x)) &= ~(1 << (irq_no))
++
++
++#endif
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-ast1070-lpc.h b/arch/arm/plat-aspeed/include/plat/regs-ast1070-lpc.h
+new file mode 100644
+index 0000000..22f8475
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-ast1070-lpc.h
+@@ -0,0 +1,117 @@
++/* arch/arm/plat-aspeed/include/mach/regs-lpc.h
++ *
++ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
++ * http://www.aspeedtech.com/
++ *
++ * 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.
++ *
++ * ASPEED LPC Controller
++*/
++
++#ifndef __AST1070_LPC_H_
++#define __AST1070_LPC_H_
++
++#define AST_LPC_HICR0 0x000
++#define AST_LPC_HICR1 0x004
++#define AST_LPC_HICR2 0x008
++#define AST_LPC_HICR3 0x00C
++#define AST_LPC_HICR4 0x010
++#define AST_LPC_LADR3H 0x014
++#define AST_LPC_LADR3L 0x018
++#define AST_LPC_LADR12H 0x01C
++#define AST_LPC_LADR12L 0x020
++#define AST_LPC_IDR1 0x024
++#define AST_LPC_IDR2 0x028
++#define AST_LPC_IDR3 0x02C
++#define AST_LPC_ODR1 0x030
++#define AST_LPC_ODR2 0x034
++#define AST_LPC_ODR3 0x038
++#define AST_LPC_STR1 0x03C
++#define AST_LPC_STR2 0x040
++#define AST_LPC_STR3 0x044
++////
++#define AST_LPC_SIRQCR0 0x048
++#define AST_LPC_SIRQCR1 0x04C
++#define AST_LPC_SIRQCR2 0x050
++#define AST_LPC_SIRQCR3 0x06C
++////
++#define AST_LPC_ADR1 0x070
++#define AST_LPC_IRQ1 0x074
++#define AST_LPC_ADR2 0x078
++#define AST_LPC_IRQ2 0x07C
++#define AST_LPC_ADR3 0x080
++#define AST_LPC_IRQ3 0x084
++
++#define AST_LPC_DEV_ADDRM0 0x100
++#define AST_LPC_DEV_ADDRM1 0x104
++#define AST_LPC_DEV_ADDRM2 0x108
++#define AST_LPC_DEV_ADDRM3 0x10C
++#define AST_LPC_DEV_ADDR0 0x110
++#define AST_LPC_DEV_ADDR1 0x114
++#define AST_LPC_DEV_ADDR2 0x118
++#define AST_LPC_DEV_ADDR3 0x11C
++#define AST_LPC_DEC_ADDR0 0x120
++#define AST_LPC_DEC_ADDR1 0x124
++#define AST_LPC_DEC_RANGE0 0x128
++#define AST_LPC_DEC_RANGE1 0x12C
++
++#define AST_LPC_MBXDAT0 0x180
++#define AST_LPC_MBXDAT1 0x184
++#define AST_LPC_MBXDAT2 0x188
++#define AST_LPC_MBXDAT3 0x18C
++#define AST_LPC_MBXDAT4 0x190
++#define AST_LPC_MBXDAT5 0x194
++#define AST_LPC_MBXDAT6 0x198
++#define AST_LPC_MBXDAT7 0x19C
++#define AST_LPC_MBXDAT8 0x1A0
++#define AST_LPC_MBXDAT9 0x1A4
++#define AST_LPC_MBXDATA 0x1A8
++#define AST_LPC_MBXDATB 0x1AC
++#define AST_LPC_MBXDATC 0x1B0
++#define AST_LPC_MBXDATD 0x1B4
++#define AST_LPC_MBXDATE 0x1B8
++#define AST_LPC_MBXDATF 0x1BC
++
++#define AST_LPC_MBXSTS0 0x1C0
++#define AST_LPC_MBXSTS1 0x1C4
++
++#define AST_LPC_MBXBICR 0x1C8
++#define AST_LPC_MBXHICR 0x1CC
++#define AST_LPC_MBXBIE0 0x1D0
++#define AST_LPC_MBXBIE1 0x1D4
++#define AST_LPC_MBXHIE0 0x1D8
++#define AST_LPC_MBXHIE1 0x1DC
++
++#define AST_LPC_PIN_MON 0x200
++#define AST_LPC_SIRQ_CTRL 0x208
++#define AST_LPC_INT_STS 0x20C
++#define AST_LPC_CTRL_STS 0x210
++#define AST_LPC_PME 0x218
++#define AST_LPC_SMI 0x21C
++#define AST_LPC_80H_ADDR0 0x220
++#define AST_LPC_80H_ADDR1 0x224
++#define AST_LPC_80H_DATA 0x228
++#define AST_LPC_80H_CTRL 0x22C
++
++#define AST_LPC_CHIP_VER 0x240
++#define AST_LPC_CHIP_REVER 0x244
++#define AST_LPC_BMC_SCH0 0x248
++#define AST_LPC_BMC_SCH1 0x24C
++#define AST_LPC_NODE_SCH0 0x250
++#define AST_LPC_NODE_SCH1 0x254
++#define AST_LPC_NODE_SCH2 0x258
++#define AST_LPC_NODE_SCH3 0x25C
++
++
++
++
++
++
++
++
++
++
++
++#endif
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-ast1070-scu.h b/arch/arm/plat-aspeed/include/plat/regs-ast1070-scu.h
+new file mode 100644
+index 0000000..a5a4f95
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-ast1070-scu.h
+@@ -0,0 +1,95 @@
++/* arch/arm/mach-aspeed/include/mach/regs-ast1070-scu.h
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * 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.
++ *
++ * History :
++ * 1. 2013/05/15 Ryan Chen Create
++ *
++********************************************************************************/
++#ifndef __AST1070_SCU_H
++#define __AST1070_SCU_H 1
++
++/*
++ * Register for SCU
++ * */
++#define AST1070_SCU_PROTECT 0x00 /* protection key register */
++#define AST1070_SCU_RESET 0x04 /* system reset control register */
++#define AST1070_SCU_MISC_CTRL 0x08 /* misc control register */
++#define AST1070_SCU_UART_MUX 0x0C /* UART Mux control register */
++#define AST1070_SCU_SPI_USB_MUX 0x10 /* SPI/USB Mux control register */
++#define AST1070_SCU_IO_DRIVING 0x14 /* I/O Driving Strength control register */
++#define AST1070_SCU_IO_PULL 0x18 /* I/O Internal Pull control register */
++#define AST1070_SCU_IO_SLEW 0x1C /* I/O Slew Rate control register */
++#define AST1070_SCU_IO_SCHMITT 0x20 /* I/O Schmitt Trigger Control register */
++#define AST1070_SCU_IO_SELECT 0x24 /* I/O Port Selection register */
++#define AST1070_SCU_TRAP 0x30 /* HW TRAPPING register */
++#define AST1070_SCU_CHIP_ID 0x34 /* CHIP ID register */
++
++
++/* AST1070_SCU_PROTECT: 0x00 - protection key register */
++#define AST1070_SCU_PROTECT_UNLOCK 0x16881A78
++
++/* AST1070_SCU_RESET :0x04 - system reset control register */
++#define SCU_RESET_DMA (0x1 << 11)
++#define SCU_RESET_SPI_M (0x1 << 10)
++#define SCU_RESET_SPI_S (0x1 << 9)
++#define SCU_RESET_N4_LPC (0x1 << 8)
++#define SCU_RESET_N3_LPC (0x1 << 7)
++#define SCU_RESET_N2_LPC (0x1 << 6)
++#define SCU_RESET_N1_LPC (0x1 << 5)
++#define SCU_RESET_I2C (0x1 << 4)
++#define SCU_RESET_N4_UART (0x1 << 3)
++#define SCU_RESET_N3_UART (0x1 << 2)
++#define SCU_RESET_N2_UART (0x1 << 1)
++#define SCU_RESET_N1_UART (0x1 << 0)
++
++/* AST1070_SCU_MISC_CTRL 0x08 misc control register */
++#define SCU_DMA_M_S_MASK (0x3 << 9)
++
++#define SCU_DMA_SLAVE_EN (0x1 << 10)
++#define SCU_DMA_MASTER_EN (0x1 << 9)
++
++/* AST1070_SCU_UART_MUX 0x0C UART Mux control register */
++#define UART_MUX_MASK(x) (0xff << (x*8))
++
++#define BMC_UART_CTRL(x) (6 + (x*8))
++#define BMC_UART_CTRL_MASK(x) (0x3 << (6 + (x*8)))
++#define SET_BMC_UART_CTRL(x,v) ((v) << (6 + (x*8)))
++#define BMC_UART_FROM_N1 0
++#define BMC_UART_FROM_PAD1 1
++#define BMC_UART_FROM_NONE 2
++
++#define NODE_UART_CTRL(x) (3 + (x*8))
++#define NODE_UART_CTRL_MASK(x) (0x7 << (3 + (x*8)))
++#define SET_NODE_UART_CTRL(x,v) ((v) << (3 + (x*8)))
++#define NODE_UART_FROM_BMC 0
++#define NODE_UART_FROM_PAD1 1
++#define NODE_UART_FROM_PAD2 2
++#define NODE_UART_FROM_PAD3 3
++#define NODE_UART_FROM_PAD4 4
++#define NODE_UART_FROM_NONE 5
++#define NODE_UART_FROM_N2 6
++#define NODE_UART_FROM_N3 7
++
++
++#define SCU_UART_IO_PAD(x) (x*8)
++#define UART_IO_PAD_MASK(x) (0x7 << (x*8))
++#define SET_UART_IO_PAD(x,v) ((v) << (x*8))
++#define PAD_FROM_NONE 0
++#define PAD_FROM_N1_UART 1
++#define PAD_FROM_N2_UART 2
++#define PAD_FROM_N3_UART 3
++#define PAD_FROM_N4_UART 4
++#define PAD_FROM_BMC 5
++
++/* AST1070_SCU_TRAP 0x30 HW TRAPPING register */
++#define TRAP_DEVICE_SLAVE (0x1 << 2)
++#define TRAP_MULTI_MASTER (0x1 << 1)
++#define TRAP_LPC_PLUS_MODE (0x1 << 0)
++
++#endif
++
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-crt.h b/arch/arm/plat-aspeed/include/plat/regs-crt.h
+new file mode 100644
+index 0000000..6749285
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-crt.h
+@@ -0,0 +1,183 @@
++/* linux/include/asm-arm/arch-aspeed/regs-crt.h
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++*/
++
++#ifndef ___ASM_ARCH_REGS_CRT_H
++#define ___ASM_ARCH_REGS_CRT_H
++
++/* CRT control registers */
++
++
++//////////////////////////////////////////////////////////////////
++#define AST3000_VGA1_CTLREG 0x00
++#define AST3000_VGA1_CTLREG2 0x04
++#define AST3000_VGA1_STATUSREG 0x08
++#define AST3000_VGA1_PLL 0x0C
++#define AST3000_VGA1_HTREG 0x10
++#define AST3000_VGA1_HRREG 0x14
++#define AST3000_VGA1_VTREG 0x18
++#define AST3000_VGA1_VRREG 0x1C
++#define AST3000_VGA1_STARTADDR 0x20
++#define AST3000_VGA1_OFFSETREG 0x24
++#define AST3000_VGA1_THRESHOLD 0x28
++
++#define AST3000_VGA2_CTLREG 0x60
++#define AST3000_VGA2_CTLREG2 0x64
++#define AST3000_VGA2_STATUSREG 0x68
++#define AST3000_VGA2_PLL 0x6C
++#define AST3000_VGA2_HTREG 0x70
++#define AST3000_VGA2_HRREG 0x74
++#define AST3000_VGA2_VTREG 0x78
++#define AST3000_VGA2_VRREG 0x7C
++#define AST3000_VGA2_STARTADDR 0x80
++#define AST3000_VGA2_OFFSETREG 0x84
++#define AST3000_VGA2_THRESHOLD 0x88
++//////////////////////////////////////////////////////////////////
++
++//0x00 ~ 0x5F Reserved - FB0
++//0x60 ~ 90 FB1
++#define AST_CRT_CTRL1 0x60
++#define AST_CRT_CTRL2 0x64
++#define AST_CRT_STS 0x68
++#define AST_CRT_PLL 0x6C
++#define AST_CRT_HORIZ0 0x70
++#define AST_CRT_HORIZ1 0x74
++#define AST_CRT_VERTI0 0x78
++#define AST_CRT_VERTI1 0x7C
++#define AST_CRT_ADDR 0x80
++#define AST_CRT_OFFSET 0x84
++#define AST_CRT_THROD 0x88
++#define AST_CRT_XSCALING 0x8C
++//0x8c Reserved
++//0x90 ~ Cursor
++#define AST_CRT_CURSOR0 0x90
++#define AST_CRT_CURSOR1 0x94
++#define AST_CRT_CURSOR2 0x98
++#define AST_CRT_UADDR 0x9C
++//0x9c Reserved
++//0xA0 ~ OSD
++#define AST_CRT_OSDH 0xA0
++#define AST_CRT_OSDV 0xA4
++#define AST_CRT_OSDADDR 0xA8
++#define AST_CRT_OSDDISP 0xAC
++#define AST_CRT_OSDTHROD 0xB0
++#define AST_CRT_VADDR 0xB4
++
++//0xb4 Reserved
++#define AST_CRT_STS_V 0xB8
++#define AST_CRT_SCRATCH 0xBC
++#define AST_CRT_X 0xC0
++//0xC4
++#define AST_CRT_OSD_COLOR 0xE0
++
++/* AST_CRT_CTRL1 - 0x60 : CRT Control Register I */
++#define CRT_CTRL_VERTICAL_INTR_STS (0x1 << 31)
++#define CRT_CTRL_VERTICAL_INTR_EN (0x1 << 30)
++//24~28 reserved
++#define CRT_CTRL_DESK_OFF (0x1 << 23)
++#define CRT_CTRL_FSYNC_OFF (0x1 << 22)
++#define CRT_CTRL_FSYNC_POLARITY (0x1 << 21)
++#define CRT_CTRL_SCREEN_OFF (0x1 << 20)
++#define CRT_CTRL_VSYNC_OFF (0x1 << 19)
++#define CRT_CTRL_HSYNC_OFF (0x1 << 18)
++#define CRT_CTRL_VSYNC_POLARITY (0x1 << 17)
++#define CRT_CTRL_HSYNC_POLARITY (0x1 << 16)
++#define CRT_CTRL_TILE_EN (0x1 << 15)
++#define CRT_CTRL_HDTVYUV_EN (0x1 << 14)
++#define CRT_CTRL_YUV_FORMAT(x) (x << 12)
++#define YUV_MODE0 0
++#define YUV_MODE1 1
++#define YUV_MODE2 2
++// bit 11 reserved
++#define CRT_CTRL_HW_CURSOR_FORMAT (0x1 << 10) // 0: XRGB4444, 1:ARGB4444
++#define CRT_CTRL_FORMAT_MASK (0x7 << 7)
++#define CRT_CTRL_FORMAT(x) (x << 7)
++#define COLOR_RGB565 (0)
++#define COLOR_YUV444 (1)
++#define COLOR_XRGB8888 (2)
++#define COLOR_YUV444_2RGB (5)
++#define CRT_CTRL_ENVEFLIP (0x1 << 6)
++//bit 5
++#define CRT_CTRL_SCALING_X (0x1 << 4)
++#define CRT_CTRL_INTER_TIMING (0x1 << 3)
++#define CRT_CTRL_OSD_EN (0x1 << 2)
++#define CRT_CTRL_HW_CURSOR_EN (0x1 << 1)
++#define CRT_CTRL_GRAPHIC_EN (0x1)
++
++/*AST_CRT_CTRL2 - 0x64 : CRT Control Register II */
++#define CRT_CTRL_VLINE_NUM_MASK (0xfff << 20)
++#define CRT_CTRL_VLINE_NUM(x) (x << 20)
++#define CRT_CTRL_TESTDVO_MASK (0xfff << 8)
++#define CRT_CTRL_TESTDVO(x) (x << 8)
++#define CRT_CTRL_DVO_EN (0x1 << 7)
++#define CRT_CTRL_DVO_DUAL (0x1 << 6)
++#define CRT_CTRL_FIFO_FULL (0x1 << 5)
++#define CRT_CTRL_TEST_EN (0x1 << 4)
++#define CRT_CTRL_SIGN_DON (0x1 << 3)
++#define CRT_CTRL_SIGN_TRIGGER (0x1 << 2)
++#define CRT_CTRL_DAC_TEST_EN (0x1 << 1)
++#define CRT_CTRL_DAC_PWR_EN (0x1)
++
++/* AST_CRT_STS - 0x68 : CRT Status Register */
++#define CRT_STS_RED_RB(x) (x << 24)
++#define CRT_STS_GREEN_RB(x) (x << 16)
++#define CRT_STS_BLUE_RB(x) (x << 8)
++#define CRT_STS_DAC_SENSE_EN (0x1 << 7)
++//6 reserved
++#define CRT_STS_ODDFIELD_SYNC (0x1 << 5)
++#define CRT_STS_ODDFIELD (0x1 << 4)
++#define CRT_STS_HDISPLAY_RB (0x1 << 3)
++#define CRT_STS_HRETRACE_RB (0x1 << 2)
++#define CRT_STS_VDISPLAY_RB (0x1 << 1)
++#define CRT_STS_VRETRACE_RB (0x1)
++
++/* AST_CRT_PLL - 0x6C : CRT Video PLL Setting Register */
++#define CRT_PLL_DAC_MODE_SENSE(x) (x << 30)
++#define CRT_PLL_DAC_SENSE(x) (x << 28)
++#define CRT_PLL_BYPASS (0x1 << 17)
++#define CRT_PLL_PWR_DWN (0x1 << 16)
++#define CRT_PLL_POST_DIVIDER(x) (((x & 0x3) << 13) | (((x >> 2) & 0xf) << 18) | (((x >> 6) & 0x1) << 23) | (((x >> 7) & 0x1) << 22))
++#define CRT_PLL_DENUM(x) (x << 8)
++#define CRT_PLL_NUM(x) (x)
++
++/* AST_CRT_HORIZ0 - 0x70 : CRT Horizontal Total & Display Enable End Register */
++#define CRT_H_TOTAL(x) (x)
++#define CRT_H_DE(x) (x << 16)
++
++/* AST_ 0x74 : CRT Horizontal Retrace Start & End Register */
++#define CRT_H_RS_START(x) (x)
++#define CRT_H_RS_END(x) (x << 16)
++
++/* AST_CRT_ - 0x78 : CRT Horizontal Total & Display Enable End Register */
++#define CRT_V_TOTAL(x) (x)
++#define CRT_V_DE(x) (x << 16)
++
++/* AST_ 0x7C : CRT Horizontal Retrace Start & End Register */
++#define CRT_V_RS_START(x) (x)
++#define CRT_V_RS_END(x) (x << 16)
++
++/* AST_CRT_OFFSET - 0x84 : CRT Display Offset & Terminal Count Register */
++#define CRT_DISP_OFFSET(x) (x)
++#define CRT_TERM_COUNT(x) (x << 16)
++
++/* AST_CRT_THROD - 0x88 : CRT Threadhold Register */
++#define CRT_THROD_LOW(x) (x)
++#define CRT_THROD_HIGH(x) (x << 8)
++#define CRT_THROD_X_SCALING(x) (x << 16)
++#define CRT_THROD_CRT2Y (0x1 << 20)
++
++/* AST_CRT_XSCALING - 0x8C : CRT X Scaling-up Factor Register */
++
++
++/* AST_CRT_CURSOR0 : 0x90 - CRT Hardware Cursor X & Y Offset Register */
++#define CRT_HW_CURSOR_X_OFFSET(x) (x)
++#define CRT_HW_CURSOR_Y_OFFSET(x) (x << 16)
++
++/* AST_CRT_CURSOR1 : 0x94 - CRT Hardware Cursor X & Y Position Register */
++#define CRT_HW_CURSOR_X_POSITION(x) (x)
++#define CRT_HW_CURSOR_Y_POSITION(x) (x << 16)
++
++#endif /* ___ASM_ARCH_REGS_CRT_H */
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-fmc.h b/arch/arm/plat-aspeed/include/plat/regs-fmc.h
+new file mode 100644
+index 0000000..25c3046
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-fmc.h
+@@ -0,0 +1,112 @@
++/* arch/arm/plat-aspeed/include/mach/regs-smc.h
++ *
++ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
++ * http://www.aspeedtech.com/
++ *
++ * 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.
++ *
++ * ASPEED Static memory ctrol
++*/
++
++#ifndef __ASM_ARCH_REGS_FMC_H
++#define __ASM_ARCH_REGS_FMC_H __FILE__
++
++#define FMC_CE_TYPE 0x00
++#define FMC_CE_CTRL 0x04
++#define FMC_INTR_CTRL 0x08
++#define FMC_CE0_CTRL 0x10
++#define FMC_CE1_CTRL 0x14
++#define FMC_CE2_CTRL 0x18
++#define FMC_CE3_CTRL 0x1c
++#define FMC_CE4_CTRL 0x20
++
++#define FMC_CE0_ADDR 0x30
++#define FMC_CE1_ADDR 0x34
++#define FMC_CE2_ADDR 0x38
++#define FMC_CE3_ADDR 0x3c
++#define FMC_CE4_ADDR 0x40
++
++#define FMC_MISC_CTRL1 0x50
++#define FMC_MISC_CTRL2 0x54
++#define FMC_NAND_CTRL 0x58
++#define FMC_NAND_ECC 0x5c
++#define FMC_NAND_ECC_CK1 0x60
++#define FMC_NAND_ECC_CK2 0x64
++#define FMC_NAND_ECC_CK3 0x68
++#define FMC_NAND_ECC_GEN1 0x6c
++#define FMC_NAND_ECC_GEN2 0x70
++#define FMC_NAND_ECC_GEN3 0x74
++#define FMC_NAND_ECC_CK_R1 0x78
++#define FMC_NAND_ECC_CK_R2 0x7c
++#define FMC_DMA_CTRL 0x80
++#define FMC_DMA_FLASH_ADDR 0x84
++#define FMC_DMA_DRAM_ADDR 0x88
++#define FMC_DMA_LEN 0x8C
++#define FMC_CHECK_SUM 0x90
++#define FMC_SPI_TIMING 0x94
++
++/* FMC_CE_TYPE 0x00 */
++#define FMC_SET_WRITE_CS(x) (0x1 << (x+16))
++#define FMC_MASK_TYPE_CS(x) (~(0x3 << (2*x)))
++#define FMC_SET_TYPE_NAND_CS(x) (0x1 << (2*x))
++#define FMC_SET_TYPE_SPI_CS(x) (0x2 << (2*x))
++
++#define FMC_TYPE_NOR 0
++#define FMC_TYPE_NAND 1
++#define FMC_TYPE_SPI 2
++
++
++/* FMC_CE0_CTRL for NAND 0x10, 0x14, 0x18, 0x1c, 0x20 */
++#define NAND_T_WEH(x) (x << 28)
++#define NAND_T_WEL(x) (x << 24)
++#define NAND_T_REH(x) (x << 20)
++#define NAND_T_REL(x) (x << 16)
++#define NAND_T_CESH(x) (x << 12)
++#define NAND_T_WTR(x) (x << 10)
++#define NAND_T_R(x) (x << 4)
++#define NAND_ADDR_CYCLE (1 << 3)
++#define NAND_CE_ACTIVE (1 << 2)
++#define NAND_OP_MODE (1 << 0)
++
++/* FMC_CE0_CTRL for SPI 0x10, 0x14, 0x18, 0x1c, 0x20 */
++#define SPI_IO_MODE(x) (x << 28)
++#define SPI_CE_WIDTH(x) (x << 24)
++#define SPI_CMD_DATA(x) (x << 16)
++#define SPI_DUMMY_CMD (1 << 15)
++#define SPI_DUMMY_HIGH (1 << 14)
++#define SPI_CLK_DIV (1 << 13)
++#define SPI_ADDR_CYCLE (1 << 13)
++#define SPI_CMD_MERGE_DIS (1 << 12)
++#define SPI_T_CLK (x << 8)
++#define SPI_DUMMY_LOW (x << 6)
++#define SPI_LSB_FIRST_CTRL (1 << 5)
++#define SPI_CPOL_1 (1 << 4)
++#define SPI_DUAL_DATA (1 << 3)
++#define SPI_CE_INACTIVE (1 << 2)
++#define SPI_CMD_MODE (x)
++#define SPI_CMD_NOR_R_MODE 0
++#define SPI_CMD_FAST_R_MODE 1
++#define SPI_CMD_NOR_W_MODE 2
++#define SPI_CMD_USER_MODE 3
++
++
++/* FMC_CE0_ADDR 0x30 0x34 0x38 0x3c 0x40*/
++#define FMC_END_ADDR(x) (x << 24)
++#define FMC_START_ADDR(x) (x << 16)
++
++
++/* FMC_MISC_CTRL1 0x50 */
++#define READ_BUSY_PIN_STS (1 << 3)
++
++/* FMC_NAND_ECC 0x5c */
++#define NAND_ECC_RESET (1 << 3)
++#define NAND_ECC_ENABLE (1 << 2)
++#define NAND_ECC_DATA_BLK_512 2
++#define NAND_ECC_DATA_BLK_256 1
++#define NAND_ECC_DATA_BLK_128 0
++
++
++
++#endif /* __ASM_ARCH_REGS_FMC_H */
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-gpio.h b/arch/arm/plat-aspeed/include/plat/regs-gpio.h
+new file mode 100644
+index 0000000..d6e7de0
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-gpio.h
+@@ -0,0 +1,338 @@
++/* arch/arm/plat-aspeed/include/mach/regs-gpio.h
++ *
++ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
++ * http://www.aspeedtech.com/
++ *
++ * 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.
++ *
++ * ASPEED I2C Controller
++*/
++
++#ifndef __ASM_ARCH_REGS_GPIO_H
++#define __ASM_ARCH_REGS_GPIO_H __FILE__
++
++/*AST GPIO Register Definition */
++#define AST_GPIO_DATA 0x000
++#define AST_GPIO_DIR 0x004
++#define AST_GPIO_INT_EN 0x008
++#define AST_GPIO_INT_SEN_T0 0x00c
++#define AST_GPIO_INT_SEN_T1 0x010
++#define AST_GPIO_INT_SEN_T2 0x014
++#define AST_GPIO_INT_STS 0x018
++#define AST_GPIO_RST_TOR 0x01c
++#define AST_EXT_GPIO_DATA 0x020
++#define AST_EXT_GPIO_DIR 0x024
++#define AST_EXT_GPIO_INT_EN 0x028
++#define AST_EXT_GPIO_INT_SEN_T0 0x02c
++#define AST_EXT_GPIO_INT_SEN_T1 0x030
++#define AST_EXT_GPIO_INT_SEN_T2 0x034
++#define AST_EXT_GPIO_INT_STS 0x038
++#define AST_EXT_GPIO_RST_TOR 0x03c
++#define AST_GPIO_DEBOUNCE_SET1 0x040 //A/B/C/D
++#define AST_GPIO_DEBOUNCE_SET2 0x044 //A/B/C/D
++#define AST_EXT_GPIO_DEBOUNCE_SET1 0x048 //E/F/G/H
++#define AST_EXT_GPIO_DEBOUNCE_SET2 0x04C //E/F/G/H
++#define AST_DEBOUNCE_TIME_SET1 0x050
++#define AST_DEBOUNCE_TIME_SET2 0x054
++#define AST_DEBOUNCE_TIME_SET3 0x058
++#define AST_GPIO_CMD_S0 0x060
++#define AST_GPIO_CMD_S1 0x064
++#define AST_EXT_GPIO_CMD_S0 0x068
++#define AST_EXT_GPIO_CMD_S1 0x06C
++#define AST_SIMPLE_GPIO_DATA0 0x070
++#define AST_SIMPLE_GPIO_DIR0 0x074
++#define AST_SIMPLE_GPIO_DATA1 0x078
++#define AST_SIMPLE_GPIO_DIR1 0x07C
++#define AST_SIMPLE_GPIO_DATA2 0x080
++#define AST_SIMPLE_GPIO_DIR2 0x084
++#define AST_SIMPLE_GPIO_DATA3 0x088
++#define AST_SIMPLE_GPIO_DIR3 0x08C
++#define AST_SIMPLE_GPIO0_CMD_S0 0x090
++#define AST_SIMPLE_GPIO0_CMD_S1 0x094
++#define AST_SIMPLE_GPIO0_INT_EN 0x098
++#define AST_SIMPLE_GPIO0_INT_SEN_T0 0x09c
++#define AST_SIMPLE_GPIO0_INT_SEN_T1 0x0a0
++#define AST_SIMPLE_GPIO0_INT_SEN_T2 0x0a4
++#define AST_SIMPLE_GPIO0_INT_STS 0x0a8
++#define AST_SIMPLE_GPIO0_RST_TOR 0x0ac
++#define AST_SIMPLE_GPIO0_DEBOUNCE_SET1 0x0b0
++#define AST_SIMPLE_GPIO0_DEBOUNCE_SET2 0x0b4
++#define AST_SIMPLE_GPIO0_INT_MASK 0x0b8
++#define AST_GPIO_DATA_READ 0x0c0
++#define AST_EXT_GPIO_DATA_READ 0x0c4
++#define AST_SIMPLE_GPIO0_DATA_READ 0x0c8
++#define AST_SIMPLE_GPIO1_DATA_READ 0x0cc
++#define AST_SIMPLE_GPIO2_DATA_READ 0x0d0
++#define AST_SIMPLE_GPIO3_DATA_READ 0x0d4
++#define AST_SIMPLE_GPIO4_DATA_READ 0x0d8
++#define AST_SIMPLE_GPIO1_CMD_S0 0x0e0
++#define AST_SIMPLE_GPIO1_CMD_S1 0x0e4
++#define AST_SIMPLE_GPIO1_INT_EN 0x0e8
++#define AST_SIMPLE_GPIO1_INT_SEN_T0 0x0ec
++#define AST_SIMPLE_GPIO1_INT_SEN_T1 0x0f0
++#define AST_SIMPLE_GPIO1_INT_SEN_T2 0x0f4
++#define AST_SIMPLE_GPIO1_INT_STS 0x0f8
++#define AST_SIMPLE_GPIO1_RST_TOR 0x0fc
++#define AST_SIMPLE_GPIO1_DEBOUNCE_SET1 0x100
++#define AST_SIMPLE_GPIO1_DEBOUNCE_SET2 0x104
++#define AST_SIMPLE_GPIO1_INT_MASK 0x108
++#define AST_SIMPLE_GPIO2_CMD_S0 0x110
++#define AST_SIMPLE_GPIO2_CMD_S1 0x114
++#define AST_SIMPLE_GPIO2_INT_EN 0x118
++#define AST_SIMPLE_GPIO2_INT_SEN_T0 0x11c
++#define AST_SIMPLE_GPIO2_INT_SEN_T1 0x120
++#define AST_SIMPLE_GPIO2_INT_SEN_T2 0x124
++#define AST_SIMPLE_GPIO2_INT_STS 0x128
++#define AST_SIMPLE_GPIO2_RST_TOR 0x12c
++#define AST_SIMPLE_GPIO2_DEBOUNCE_SET1 0x130
++#define AST_SIMPLE_GPIO2_DEBOUNCE_SET2 0x134
++#define AST_SIMPLE_GPIO2_INT_MASK 0x138
++#define AST_SIMPLE_GPIO3_CMD_S0 0x140
++#define AST_SIMPLE_GPIO3_CMD_S1 0x144
++#define AST_SIMPLE_GPIO3_INT_EN 0x148
++#define AST_SIMPLE_GPIO3_INT_SEN_T0 0x14c
++#define AST_SIMPLE_GPIO3_INT_SEN_T1 0x150
++#define AST_SIMPLE_GPIO3_INT_SEN_T2 0x154
++#define AST_SIMPLE_GPIO3_INT_STS 0x158
++#define AST_SIMPLE_GPIO3_RST_TOR 0x15c
++#define AST_SIMPLE_GPIO3_DEBOUNCE_SET1 0x160
++#define AST_SIMPLE_GPIO3_DEBOUNCE_SET2 0x164
++#define AST_SIMPLE_GPIO3_INT_MASK 0x168
++#define AST_SIMPLE_GPIO4_CMD_S0 0x170
++#define AST_SIMPLE_GPIO4_CMD_S1 0x174
++#define AST_SIMPLE_GPIO4_INT_EN 0x178
++#define AST_SIMPLE_GPIO4_INT_SEN_T0 0x17c
++#define AST_SIMPLE_GPIO4_INT_SEN_T1 0x180
++#define AST_SIMPLE_GPIO4_INT_SEN_T2 0x184
++#define AST_SIMPLE_GPIO4_INT_STS 0x188
++#define AST_SIMPLE_GPIO4_RST_TOR 0x18c
++#define AST_SIMPLE_GPIO4_DEBOUNCE_SET1 0x190
++#define AST_SIMPLE_GPIO4_DEBOUNCE_SET2 0x194
++#define AST_SIMPLE_GPIO4_INT_MASK 0x198
++#define AST_GPIO_INT_MASK 0x1d0
++#define AST_EXT_GPIO_INT_MASK 0x1d4
++#ifdef CONFIG_ARCH_AST1010
++#else
++#define AST_SIMPLE_GPIO_DATA4 0x1e0
++#define AST_SIMPLE_GPIO_DIR4 0x1e4
++#endif
++
++//Serial GPIO
++#define AST_SGPIO_DATA 0x200
++#define AST_SGPIO_INT_EN 0x204
++#define AST_SGPIO_INT_SEN_T0 0x208
++#define AST_SGPIO_INT_SEN_T1 0x20c
++#define AST_SGPIO_INT_SEN_T2 0x210
++#define AST_SGPIO_INT_STS 0x214
++#define AST_SGPIO_RST_TOR 0x218
++#define AST_EXT_SGPIO_DATA 0x21c
++#define AST_EXT_SGPIO_INT_EN 0x220
++#define AST_EXT_SGPIO_INT_SEN_T0 0x224
++#define AST_EXT_SGPIO_INT_SEN_T1 0x228
++#define AST_EXT_SGPIO_INT_SEN_T2 0x22c
++#define AST_EXT_SGPIO_INT_STS 0x230
++#define AST_EXT_SGPIO_RST_TOR 0x234
++#define AST_SGPIO_CTRL 0x254
++#define AST_SGPIO_DATA_READ 0x270
++#define AST_EXT_SGPIO_DAT 0x274
++
++//Serial GPIO Slave Monitor
++#define AST_SGPIO_SLAVE_DATA_INIT 0x300
++#define AST_SGPIO_SLAVE_DATA_TARGET 0x304
++#define AST_SGPIO_SLAVE_DATA_LOAD 0x308
++#define AST_SGPIO_SLAVE_INT_EN0 0x30c
++#define AST_SGPIO_SLAVE_INT_EN1 0x310
++#define AST_SGPIO_SLAVE_INT_EN2 0x314
++#define AST_SGPIO_SLAVE_INT_STS0 0x318
++#define AST_SGPIO_SLAVE_INT_STS1 0x31c
++#define AST_SGPIO_SLAVE_INT_STS2 0x320
++
++/**********************************************************************************/
++/* AST_GPIO_DATA - 0x000 : A/B/C/D Data Vale */
++#define GET_GPIOD_DATA(x) ((x&0xff000000) >> 24)
++#define SET_GPIOD_DATA(x) (x << 24)
++#define GET_GPIOD_PIN_DATA(x,pin) ((x >> (pin + 24)) & 1)
++#define SET_GPIOD_PIN_DATA(pin) (1<<(pin + 24))
++#define GET_GPIOC_DATA(x) ((x&0xff0000) >> 16)
++#define SET_GPIOC_DATA(x) (x << 16)
++#define GET_GPIOC_PIN_DATA(x,pin) ((x >> (pin + 16)) & 1)
++#define SET_GPIOC_PIN_DATA(pin) (1<<(pin + 16))
++#define GET_GPIOB_DATA(x) ((x&0xff00) >> 8)
++#define SET_GPIOB_DATA(x) (x << 8)
++#define GET_GPIOB_PIN_DATA(x,pin) ((x >> (pin + 8)) & 1)
++#define SET_GPIOB_PIN_DATA(pin) (1<<(pin + 8))
++#define GET_GPIOA_DATA(x) (x&0xff)
++#define SET_GPIOA_DATA(x) (x)
++#define GET_GPIOA_PIN_DATA(x,pin) ((x >> pin) & 1)
++#define SET_GPIOA_PIN_DATA(pin) (1<<pin)
++
++/* AST_GPIO_DIR - 0x004 : Direction */
++#define GET_GPIOD_DIR(x) ((x&0xff000000) >> 24)
++#define SET_GPIOD_DIR(x) (x << 24)
++#define GET_GPIOD_PIN_DIR(x,pin) ((x >> (pin + 24)) & 1)
++#define SET_GPIOD_PIN_DIR(pin) (1<<(pin + 24))
++#define GET_GPIOC_DIR(x) ((x&0xff0000) >> 16)
++#define SET_GPIOC_DIR(x) (x << 16)
++#define GET_GPIOC_PIN_DIR(x,pin) ((x >> (pin + 16)) & 1)
++#define SET_GPIOC_PIN_DIR(pin) (1<<(pin + 16))
++#define GET_GPIOB_DIR(x) ((x&0xff00) >> 8)
++#define SET_GPIOB_DIR(x) (x << 8)
++#define GET_GPIOB_PIN_DIR(x,pin) ((x >> (pin + 8)) & 1)
++#define SET_GPIOB_PIN_DIR(pin) (1<<(pin + 8))
++#define GET_GPIOA_DIR(x) (x&0xff)
++#define SET_GPIOA_DIR(x) (x)
++#define GET_GPIOA_PIN_DIR(x,pin) ((x >> pin) & 1)
++#define SET_GPIOA_PIN_DIR(pin) (1<<pin)
++
++/* AST_GPIO_INT_EN - 0x008 : Interrupt Enable */
++#define GET_GPIOD_INT_EN(x) ((x&0xff000000) >> 24)
++#define SET_GPIOD_INT_EN(x) (x << 24)
++#define GET_GPIOD_PIN_INT_EN(x,pin) ((x >> (pin + 24)) & 1)
++#define SET_GPIOD_PIN_INT_EN(pin) (1<<(pin + 24))
++#define GET_GPIOC_INT_EN(x) ((x&0xff0000) >> 16)
++#define SET_GPIOC_INT_EN(x) (x << 16)
++#define GET_GPIOC_PIN_INT_EN(x,pin) ((x >> (pin + 16)) & 1)
++#define SET_GPIOC_PIN_INT_EN(pin) (1<<(pin + 16))
++#define GET_GPIOB_INT_EN(x) ((x&0xff00) >> 8)
++#define SET_GPIOB_INT_EN(x) (x << 8)
++#define GET_GPIOB_PIN_INT_EN(x,pin) ((x >> (pin + 8)) & 1)
++#define SET_GPIOB_PIN_INT_EN(pin) (1<<(pin + 8))
++#define GET_GPIOA_INT_EN(x) (x&0xff)
++#define SET_GPIOA_INT_EN(x) (x)
++#define GET_GPIOA_PIN_INT_EN(x,pin) ((x >> pin) & 1)
++#define SET_GPIOA_PIN_INT_EN(pin) (1<<pin)
++
++/* AST_GPIO_INT_SEN_T0/1/2 - 0x00c/0x010/0x014 : Interrupt Sensitivity Type 0/1/2 */
++#define GET_GPIOD_INT_MODE(x) ((x&0xff000000) >> 24)
++#define SET_GPIOD_INT_MODE(x) (x << 24)
++#define GET_GPIOD_PIN_INT_MODE(x,pin) ((x >> (pin + 24)) & 1)
++#define SET_GPIOD_PIN_INT_MODE(pin) (1<<(pin + 24))
++#define GET_GPIOC_INT_MODE(x) ((x&0xff0000) >> 16)
++#define SET_GPIOC_INT_MODE(x) (x << 16)
++#define GET_GPIOC_PIN_INT_MODE(x,pin) ((x >> (pin + 16)) & 1)
++#define SET_GPIOC_PIN_INT_MODE(pin) (1<<(pin + 16))
++#define GET_GPIOB_INT_MODE(x) ((x&0xff00) >> 8)
++#define SET_GPIOB_INT_MODE(x) (x << 16)
++#define GET_GPIOB_PIN_INT_MODE(x,pin) ((x >> (pin + 8)) & 1)
++#define SET_GPIOB_PIN_INT_MODE(pin) (1<<(pin + 8))
++#define GET_GPIOA_INT_MODE(x) (x&0xff)
++#define SET_GPIOA_INT_MODE(x) (x)
++#define GET_GPIOA_PIN_INT_MODE(x,pin) ((x >> pin) & 1)
++#define SET_GPIOA_PIN_INT_MODE(pin) (1 << pin)
++
++/* AST_GPIO_INT_STS - 0x018 : Interrupt Status */
++#define GET_GPIOD_INT_STS(x) ((x&0xff000000) >> 24)
++#define SET_GPIOD_INT_STS(x) (x << 24)
++#define GET_GPIOD_PIN_INT_STS(x,pin) ((x >> (pin + 24)) & 1)
++#define SET_GPIOD_PIN_INT_STS(pin) (1<<(pin + 24))
++#define GET_GPIOC_INT_STS(x) ((x&0xff0000) >> 16)
++#define SET_GPIOC_INT_STS(x) (x << 16)
++#define GET_GPIOC_PIN_INT_STS(x,pin) ((x >> (pin + 16)) & 1)
++#define SET_GPIOC_PIN_INT_STS(pin) (1<<(pin + 16))
++#define GET_GPIOB_INT_STS(x) ((x&0xff00) >> 8)
++#define SET_GPIOB_INT_STS(x) (x << 16)
++#define GET_GPIOB_PIN_INT_STS(x,pin) ((x >> (pin + 8)) & 1)
++#define SET_GPIOB_PIN_INT_STS(pin) (1<<(pin + 8))
++#define GET_GPIOA_INT_STS(x) (x&0xff)
++#define SET_GPIOA_INT_STS(x) (x)
++#define GET_GPIOA_PIN_INT_STS(x,pin) ((x >> pin) & 1)
++#define SET_GPIOA_PIN_INT_STS(pin) (1 << pin)
++
++/* AST_GPIO_RST_TOR - 0x01c : Reset Tolerant */
++#define GET_GPIOD_RST_EN(x) ((x&0xff000000) >> 24)
++#define SET_GPIOD_RST_EN(x) (x << 24)
++#define GET_GPIOD_PIN_RST_EN(x,pin) ((x >> (pin + 24)) & 1)
++#define SET_GPIOD_PIN_RST_EN(pin) (1<<(pin + 24))
++#define GET_GPIOC_RST_EN(x) ((x&0xff0000) >> 16)
++#define SET_GPIOC_RST_EN(x) (x << 16)
++#define GET_GPIOC_PIN_RST_EN(x,pin) ((x >> (pin + 16)) & 1)
++#define SET_GPIOC_PIN_RST_EN(pin) (1<<(pin + 16))
++#define GET_GPIOB_RST_EN(x) ((x&0xff00) >> 8)
++#define SET_GPIOB_RST_EN(x) (x << 16)
++#define GET_GPIOB_PIN_RST_EN(x,pin) ((x >> (pin + 8)) & 1)
++#define SET_GPIOB_PIN_RST_EN(pin) (1<<(pin + 8))
++#define GET_GPIOA_RST_EN(x) (x&0xff)
++#define SET_GPIOA_RST_EN(x) (x)
++#define GET_GPIOA_PIN_RST_EN(x,pin) ((x >> pin) & 1)
++#define SET_GPIOA_PIN_RST_EN(pin) (1 << pin)
++
++/* AST_EXT_GPIO_DATA - 0x020 : E/F/G/H Data Vale */
++#define GET_GPIOH_DATA(x) ((x&0xff000000) >> 24)
++#define SET_GPIOH_DATA(x) (x << 24)
++#define GET_GPIOH_PIN_DATA(x,pin) ((x >> (pin + 24)) & 1)
++#define SET_GPIOH_PIN_DATA(pin) (1<<(pin + 24))
++#define GET_GPIOG_DATA(x) ((x&0xff0000) >> 16)
++#define SET_GPIOG_DATA(x) (x << 16)
++#define GET_GPIOG_PIN_DATA(x,pin) ((x >> (pin + 16)) & 1)
++#define SET_GPIOG_PIN_DATA(pin) (1<<(pin + 16))
++#define GET_GPIOF_DATA(x) ((x&0xff00) >> 8)
++#define SET_GPIOF_DATA(x) (x << 8)
++#define GET_GPIOF_PIN_DATA(x,pin) ((x >> (pin + 8)) & 1)
++#define SET_GPIOF_PIN_DATA(pin) (1<<(pin + 8))
++#define GET_GPIOE_DATA(x) (x&0xff)
++#define SET_GPIOE_DATA(x) (x)
++#define GET_GPIOE_PIN_DATA(x,pin) ((x >> pin) & 1)
++#define SET_GPIOE_PIN_DATA(pin) (1<<pin)
++
++/* AST_EXT_GPIO_DIR - 0x024 : */
++#define GET_GPIOH_DIR(x) ((x&0xff000000) >> 24)
++#define SET_GPIOH_DIR(x) (x << 24)
++#define GET_GPIOH_PIN_DIR(x,pin) ((x >> (pin + 24)) & 1)
++#define SET_GPIOH_PIN_DIR(pin) (1<<(pin + 24))
++#define GET_GPIOG_DIR(x) ((x&0xff0000) >> 16)
++#define SET_GPIOG_DIR(x) (x << 16)
++#define GET_GPIOG_PIN_DIR(x,pin) ((x >> (pin + 16)) & 1)
++#define SET_GPIOG_PIN_DIR(pin) (1<<(pin + 16))
++#define GET_GPIOF_DIR(x) ((x&0xff00) >> 8)
++#define SET_GPIOF_DIR(x) (x << 8)
++#define GET_GPIOF_PIN_DIR(x,pin) ((x >> (pin + 8)) & 1)
++#define SET_GPIOF_PIN_DIR(pin) (1<<(pin + 8))
++#define GET_GPIOE_DIR(x) (x&0xff)
++#define SET_GPIOE_DIR(x) (x)
++#define GET_GPIOE_PIN_DIR(x,pin) ((x >> pin) & 1)
++#define SET_GPIOE_PIN_DIR(pin) (1<<pin)
++
++/* AST_EXT_GPIO_INT_EN - 0x028 */
++#define GET_GPIOH_INT_EN(x) ((x&0xff000000) >> 24)
++#define SET_GPIOH_INT_EN(x) (x << 24)
++#define GET_GPIOH_PIN_INT_EN(x,pin) ((x >> (pin + 24)) & 1)
++#define SET_GPIOH_PIN_INT_EN(pin) (1<<(pin + 24))
++#define GET_GPIOG_INT_EN(x) ((x&0xff0000) >> 16)
++#define SET_GPIOG_INT_EN(x) (x << 16)
++#define GET_GPIOG_PIN_INT_EN(x,pin) ((x >> (pin + 16)) & 1)
++#define SET_GPIOG_PIN_INT_EN(pin) (1<<(pin + 16))
++#define GET_GPIOF_INT_EN(x) ((x&0xff00) >> 8)
++#define SET_GPIOF_INT_EN(x) (x << 8)
++#define GET_GPIOF_PIN_INT_EN(x,pin) ((x >> (pin + 8)) & 1)
++#define SET_GPIOF_PIN_INT_EN(pin) (1<<(pin + 8))
++#define GET_GPIOE_INT_EN(x) (x&0xff)
++#define SET_GPIOE_INT_EN(x) (x)
++#define GET_GPIOE_PIN_INT_EN(x,pin) ((x >> pin) & 1)
++#define SET_GPIOE_PIN_INT_EN(pin) (1<<pin)
++
++/* AST_EXT_GPIO_INT_SEN_T0/1/2 - 0x02c/0x30/0x34 : */
++/* AST_EXT_GPIO_INT_STS 0x038 */
++/* AST_EXT_GPIO_RST_TOR 0x03c */
++
++/* AST_GPIO_DEBOUNCE_SET1 - 0x040 : Debounce Setting #1 */
++#define GET_GPIO3_DEBOUNCE(x) ((x&0xff000000) >> 24)
++#define SET_GPIO3_DEBOUNCE(x) (x << 24)
++#define GET_GPIO3_PIN_DEBOUNCE(x,pin) ((x >> (pin + 24)) & 1)
++#define SET_GPIO3_PIN_DEBOUNCE(pin) (1<<(pin + 24))
++#define GET_GPIO2_DEBOUNCE(x) ((x&0xff0000) >> 16)
++#define SET_GPIO2_DEBOUNCE(x) (x << 16)
++#define GET_GPIO2_PIN_DEBOUNCE(x,pin) ((x >> (pin + 16)) & 1)
++#define SET_GPIO2_PIN_DEBOUNCE(pin) (1<<(pin + 16))
++#define GET_GPIO1_DEBOUNCE(x) ((x&0xff00) >> 8)
++#define SET_GPIO1_DEBOUNCE(x) (x << 8)
++#define GET_GPIO1_PIN_DEBOUNCE(x,pin) ((x >> (pin + 8)) & 1)
++#define SET_GPIO1_PIN_DEBOUNCE(pin) (1<<(pin + 8))
++#define GET_GPIO0_DEBOUNCE(x) (x&0xff)
++#define SET_GPIO0_DEBOUNCE(x) (x)
++#define GET_GPIO0_PIN_DEBOUNCE(x,pin) ((x >> pin) & 1)
++#define SET_GPIO0_PIN_DEBOUNCE(pin) (1<<pin)
++
++
++#endif /* __ASM_ARCH_REGS_GPIO_H */
+\ No newline at end of file
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-iic.h b/arch/arm/plat-aspeed/include/plat/regs-iic.h
+new file mode 100644
+index 0000000..14db73c
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-iic.h
+@@ -0,0 +1,286 @@
++/* arch/arm/plat-aspeed/include/mach/regs-iic.h
++ *
++ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
++ * http://www.aspeedtech.com/
++ *
++ * 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.
++ *
++ * ASPEED I2C Controller
++*/
++
++#ifndef __ASM_ARCH_REGS_IIC_H
++#define __ASM_ARCH_REGS_IIC_H __FILE__
++
++#ifdef CONFIG_ARCH_AST1010
++#define AST_I2C_DMA_SIZE 512
++#else
++#define AST_I2C_DMA_SIZE 4096
++#endif
++
++#define AST_I2C_PAGE_SIZE 256
++
++#if defined(CONFIG_ARCH_AST2300)
++#define MASTER_XFER_MODE BUFF_MODE
++#define SLAVE_XFER_MODE BYTE_MODE
++#define NUM_BUS 9
++#elif defined(CONFIG_ARCH_AST2400)
++#define MASTER_XFER_MODE BUFF_MODE
++#define SLAVE_XFER_MODE BYTE_MODE
++#define NUM_BUS 14
++#elif defined(CONFIG_ARCH_AST1010)
++#define MASTER_XFER_MODE BYTE_MODE
++#define SLAVE_XFER_MODE BYTE_MODE
++#define NUM_BUS 15
++#elif defined(CONFIG_ARCH_AST1520) || defined(CONFIG_ARCH_AST3200) || defined(CONFIG_ARCH_AST2500)
++#define MASTER_XFER_MODE BYTE_MODE
++#define SLAVE_XFER_MODE BYTE_MODE
++#define NUM_BUS 4
++#else
++#err "NO define NUM_BUS"
++#endif
++
++#if defined(CONFIG_ARCH_AST1070)
++#define AST_CI2C_GLOBAL_REG 0x00
++#define AST_CI2C_DEVICE1 0x40
++#define AST_CI2C_DEVICE2 0x80
++#define AST_CI2C_DEVICE3 0xc0
++#define AST_CI2C_DEVICE4 0x100
++#define AST_CI2C_DEVICE5 0x140
++#define AST_CI2C_DEVICE6 0x180
++#define AST_CI2C_DEVICE7 0x1c0
++#define AST_CI2C_DEVICE8 0x200
++#endif
++
++/*AST I2C Register Definition */
++#if defined(CONFIG_ARCH_AST2400) || defined(CONFIG_AST2400_BMC)
++#define AST_I2C_POOL_BUFF_2048
++#define AST_I2C_GLOBAL_REG 0x00
++#define AST_I2C_DEVICE1 0x40
++#define AST_I2C_DEVICE2 0x80
++#define AST_I2C_DEVICE3 0xc0
++#define AST_I2C_DEVICE4 0x100
++#define AST_I2C_DEVICE5 0x140
++#define AST_I2C_DEVICE6 0x180
++#define AST_I2C_DEVICE7 0x1c0
++#define AST_I2C_BUFFER_POOL2 0x200
++#define AST_I2C_DEVICE8 0x300
++#define AST_I2C_DEVICE9 0x340
++#define AST_I2C_DEVICE10 0x380
++#define AST_I2C_DEVICE11 0x3c0
++#define AST_I2C_DEVICE12 0x400
++#define AST_I2C_DEVICE13 0x440
++#define AST_I2C_DEVICE14 0x480
++#define AST_I2C_BUFFER_POOL1 0x800
++
++#elif defined(CONFIG_ARCH_AST2300)
++#define AST_I2C_POOL_BUFF_256
++#define AST_I2C_GLOBAL_REG 0x00
++#define AST_I2C_DEVICE1 0x40
++#define AST_I2C_DEVICE2 0x80
++#define AST_I2C_DEVICE3 0xc0
++#define AST_I2C_DEVICE4 0x100
++#define AST_I2C_DEVICE5 0x140
++#define AST_I2C_DEVICE6 0x180
++#define AST_I2C_DEVICE7 0x1c0
++#define AST_I2C_BUFFER_POOL2 0x200
++#define AST_I2C_DEVICE8 0x300
++#define AST_I2C_DEVICE9 0x340
++#elif defined(CONFIG_ARCH_AST1010)
++#define AST_I2C_GLOBAL_REG 0x00
++#define AST_I2C_DEVICE1 0x40
++#define AST_I2C_DEVICE2 0x80
++#define AST_I2C_DEVICE3 0xc0
++#define AST_I2C_DEVICE4 0x100
++#define AST_I2C_DEVICE5 0x140
++#define AST_I2C_DEVICE6 0x180
++#define AST_I2C_DEVICE7 0x1c0
++#define AST_I2C_DEVICE8 0x200
++#define AST_I2C_DEVICE9 0x240
++#define AST_I2C_DEVICE10 0x280
++#define AST_I2C_DEVICE11 0x2c0
++#define AST_I2C_DEVICE12 0x300
++#define AST_I2C_DEVICE13 0x340
++#define AST_I2C_DEVICE14 0x380
++#define AST_I2C_DEVICE15 0x3c0
++#elif defined(CONFIG_ARCH_AST1520) || defined(CONFIG_ARCH_AST3200) || defined(CONFIG_ARCH_AST2500)
++#define AST_I2C_GLOBAL_REG 0x00
++#define AST_I2C_DEVICE1 0x40
++#define AST_I2C_DEVICE2 0x80
++#define AST_I2C_DEVICE3 0xc0
++#define AST_I2C_DEVICE4 0x100
++#else
++#err "NO define for I2C"
++#endif
++
++
++
++/* I2C Register */
++#define I2C_FUN_CTRL_REG 0x00
++#define I2C_AC_TIMING_REG1 0x04
++#define I2C_AC_TIMING_REG2 0x08
++#define I2C_INTR_CTRL_REG 0x0c
++#define I2C_INTR_STS_REG 0x10
++#define I2C_CMD_REG 0x14
++#define I2C_DEV_ADDR_REG 0x18
++#define I2C_BUF_CTRL_REG 0x1c
++#define I2C_BYTE_BUF_REG 0x20
++#define I2C_DMA_BASE_REG 0x24
++#define I2C_DMA_LEN_REG 0x28
++
++
++/* Gloable Register Definition */
++/* 0x00 : I2C Interrupt Status Register */
++/* 0x08 : I2C Interrupt Target Assignment */
++#if defined(CONFIG_ARCH_AST2400)
++#define AST_I2CG_INTR14 (0x1 << 13)
++#define AST_I2CG_INTR13 (0x1 << 12)
++#define AST_I2CG_INTR12 (0x1 << 11)
++#define AST_I2CG_INTR11 (0x1 << 10)
++#define AST_I2CG_INTR10 (0x1 << 9)
++#elif defined(CONFIG_ARCH_AST1010)
++#define AST_I2CG_INTR14 (0x1 << 13)
++#define AST_I2CG_INTR13 (0x1 << 12)
++#define AST_I2CG_INTR12 (0x1 << 11)
++#define AST_I2CG_INTR11 (0x1 << 10)
++#define AST_I2CG_INTR10 (0x1 << 9)
++#endif
++#define AST_I2CG_INTR09 (0x1 << 8)
++#define AST_I2CG_INTR08 (0x1 << 7)
++#define AST_I2CG_INTR07 (0x1 << 6)
++#define AST_I2CG_INTR06 (0x1 << 5)
++#define AST_I2CG_INTR05 (0x1 << 4)
++#define AST_I2CG_INTR04 (0x1 << 3)
++#define AST_I2CG_INTR03 (0x1 << 2)
++#define AST_I2CG_INTR02 (0x1 << 1)
++#define AST_I2CG_INTR01 (0x1 )
++
++/* Device Register Definition */
++/* 0x00 : I2CD Function Control Register */
++#define AST_I2CD_BUFF_SEL_MASK (0x7 << 20)
++#define AST_I2CD_BUFF_SEL(x) (x << 20) // page 0 ~ 7
++#define AST_I2CD_M_SDA_LOCK_EN (0x1 << 16)
++#define AST_I2CD_MULTI_MASTER_DIS (0x1 << 15)
++#define AST_I2CD_M_SCL_DRIVE_EN (0x1 << 14)
++#define AST_I2CD_MSB_STS (0x1 << 9)
++#define AST_I2CD_SDA_DRIVE_1T_EN (0x1 << 8)
++#define AST_I2CD_M_SDA_DRIVE_1T_EN (0x1 << 7)
++#define AST_I2CD_M_HIGH_SPEED_EN (0x1 << 6)
++#define AST_I2CD_DEF_ADDR_EN (0x1 << 5)
++#define AST_I2CD_DEF_ALERT_EN (0x1 << 4)
++#define AST_I2CD_DEF_ARP_EN (0x1 << 3)
++#define AST_I2CD_DEF_GCALL_EN (0x1 << 2)
++#define AST_I2CD_SLAVE_EN (0x1 << 1)
++#define AST_I2CD_MASTER_EN (0x1 )
++
++/* 0x04 : I2CD Clock and AC Timing Control Register #1 */
++#define AST_I2CD_tBUF (0x1 << 28) // 0~7
++#define AST_I2CD_tHDSTA (0x1 << 24) // 0~7
++#define AST_I2CD_tACST (0x1 << 20) // 0~7
++#define AST_I2CD_tCKHIGH (0x1 << 16) // 0~7
++#define AST_I2CD_tCKLOW (0x1 << 12) // 0~7
++#define AST_I2CD_tHDDAT (0x1 << 10) // 0~7
++#define AST_I2CD_CLK_TO_BASE_DIV (0x1 << 8) // 0~3
++#define AST_I2CD_CLK_BASE_DIV (0x1 ) // 0~0xf
++
++/* 0x08 : I2CD Clock and AC Timing Control Register #2 */
++#define AST_I2CD_tTIMEOUT (0x1 ) // 0~7
++#define AST_NO_TIMEOUT_CTRL 0x0
++
++
++/* 0x0c : I2CD Interrupt Control Register */
++#define AST_I2CD_SDA_DL_TO_INTR_EN (0x1 << 14)
++#define AST_I2CD_BUS_RECOVER_INTR_EN (0x1 << 13)
++#define AST_I2CD_SMBUS_ALT_INTR_EN (0x1 << 12)
++#define AST_I2CD_SLAVE_MATCH_INTR_EN (0x1 << 7)
++#define AST_I2CD_SCL_TO_INTR_EN (0x1 << 6)
++#define AST_I2CD_ABNORMAL_INTR_EN (0x1 << 5)
++#define AST_I2CD_NORMAL_STOP_INTR_EN (0x1 << 4)
++#define AST_I2CD_ARBIT_LOSS_INTR_EN (0x1 << 3)
++#define AST_I2CD_RX_DOWN_INTR_EN (0x1 << 2)
++#define AST_I2CD_TX_NAK_INTR_EN (0x1 << 1)
++#define AST_I2CD_TX_ACK_INTR_EN (0x1 )
++
++/* 0x10 : I2CD Interrupt Status Register : WC */
++#define AST_I2CD_INTR_STS_SDA_DL_TO (0x1 << 14)
++#define AST_I2CD_INTR_STS_BUS_RECOVER (0x1 << 13)
++#define AST_I2CD_INTR_STS_SMBUS_ALT (0x1 << 12)
++#define AST_I2CD_INTR_STS_SMBUS_ARP_ADDR (0x1 << 11)
++#define AST_I2CD_INTR_STS_SMBUS_DEV_ALT (0x1 << 10)
++#define AST_I2CD_INTR_STS_SMBUS_DEF_ADDR (0x1 << 9)
++#define AST_I2CD_INTR_STS_GCALL_ADDR (0x1 << 8)
++#define AST_I2CD_INTR_STS_SLAVE_MATCH (0x1 << 7)
++#define AST_I2CD_INTR_STS_SCL_TO (0x1 << 6)
++#define AST_I2CD_INTR_STS_ABNORMAL (0x1 << 5)
++#define AST_I2CD_INTR_STS_NORMAL_STOP (0x1 << 4)
++#define AST_I2CD_INTR_STS_ARBIT_LOSS (0x1 << 3)
++#define AST_I2CD_INTR_STS_RX_DOWN (0x1 << 2)
++#define AST_I2CD_INTR_STS_TX_NAK (0x1 << 1)
++#define AST_I2CD_INTR_STS_TX_ACK (0x1 )
++
++/* 0x14 : I2CD Command/Status Register */
++#define AST_I2CD_SDA_OE (0x1 << 28)
++#define AST_I2CD_SDA_O (0x1 << 27)
++#define AST_I2CD_SCL_OE (0x1 << 26)
++#define AST_I2CD_SCL_O (0x1 << 25)
++#define AST_I2CD_TX_TIMING (0x1 << 24) // 0 ~3
++#define AST_I2CD_TX_STATUS (0x1 << 23)
++// Tx State Machine
++#define AST_I2CD_IDLE 0x0
++#define AST_I2CD_MACTIVE 0x8
++#define AST_I2CD_MSTART 0x9
++#define AST_I2CD_MSTARTR 0xa
++#define AST_I2CD_MSTOP 0xb
++#define AST_I2CD_MTXD 0xc
++#define AST_I2CD_MRXACK 0xd
++#define AST_I2CD_MRXD 0xe
++#define AST_I2CD_MTXACK 0xf
++#define AST_I2CD_SWAIT 0x1
++#define AST_I2CD_SRXD 0x4
++#define AST_I2CD_STXACK 0x5
++#define AST_I2CD_STXD 0x6
++#define AST_I2CD_SRXACK 0x7
++#define AST_I2CD_RECOVER 0x3
++
++#define AST_I2CD_SCL_LINE_STS (0x1 << 18)
++#define AST_I2CD_SDA_LINE_STS (0x1 << 17)
++#define AST_I2CD_BUS_BUSY_STS (0x1 << 16)
++#define AST_I2CD_SDA_OE_OUT_DIR (0x1 << 15)
++#define AST_I2CD_SDA_O_OUT_DIR (0x1 << 14)
++#define AST_I2CD_SCL_OE_OUT_DIR (0x1 << 13)
++#define AST_I2CD_SCL_O_OUT_DIR (0x1 << 12)
++#define AST_I2CD_BUS_RECOVER_CMD_EN (0x1 << 11)
++#define AST_I2CD_S_ALT_EN (0x1 << 10)
++// 0 : DMA Buffer, 1: Pool Buffer
++//AST1070 DMA register
++#define AST_I2CD_RX_DMA_ENABLE (0x1 << 9)
++#define AST_I2CD_TX_DMA_ENABLE (0x1 << 8)
++
++/* Command Bit */
++#define AST_I2CD_RX_BUFF_ENABLE (0x1 << 7)
++#define AST_I2CD_TX_BUFF_ENABLE (0x1 << 6)
++#define AST_I2CD_M_STOP_CMD (0x1 << 5)
++#define AST_I2CD_M_S_RX_CMD_LAST (0x1 << 4)
++#define AST_I2CD_M_RX_CMD (0x1 << 3)
++#define AST_I2CD_S_TX_CMD (0x1 << 2)
++#define AST_I2CD_M_TX_CMD (0x1 << 1)
++#define AST_I2CD_M_START_CMD (0x1 )
++
++/* 0x18 : I2CD Slave Device Address Register */
++
++/* 0x1C : I2CD Pool Buffer Control Register */
++#define AST_I2CD_RX_BUF_ADDR_GET(x) ((x>> 24)& 0xff)
++#define AST_I2CD_RX_BUF_END_ADDR_SET(x) (x << 16)
++#define AST_I2CD_TX_DATA_BUF_END_SET(x) ((x&0xff) << 8)
++#define AST_I2CD_TX_DATA_BUF_GET(x) ((x >>8) & 0xff)
++#define AST_I2CD_BUF_BASE_ADDR_SET(x) (x & 0x3f)
++
++/* 0x20 : I2CD Transmit/Receive Byte Buffer Register */
++#define AST_I2CD_GET_MODE(x) ((x >> 8) & 0x1)
++
++#define AST_I2CD_RX_BYTE_BUFFER (0xff << 8)
++#define AST_I2CD_TX_BYTE_BUFFER (0xff )
++
++
++#endif /* __ASM_ARCH_REGS_IIC_H */
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-intr.h b/arch/arm/plat-aspeed/include/plat/regs-intr.h
+new file mode 100644
+index 0000000..cea0132
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-intr.h
+@@ -0,0 +1,74 @@
++/* arch/arm/mach-aspeed/include/mach/regs-intr.h
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * 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.
++ *
++ * History :
++ * 1. 2012/08/15 Ryan Chen Create
++ *
++********************************************************************************/
++#ifndef __ASPEED_AST_INTR_H
++#define __ASPEED_AST_INTR_H 1
++
++#ifndef __ASSEMBLY__
++#include <asm/io.h>
++#endif
++//============== INTERRUPT========================================
++#include <mach/platform.h>
++#include <mach/irqs.h>
++#include <plat/aspeed.h>
++
++/*
++ * VIC Register (VA)
++ */
++
++#define VIC_BASE_VA IO_ADDRESS(AST_VIC_BASE)
++
++#if defined(NEW_VIC)
++//New Mappling
++
++#define AST_IRQ_STS(x) (VIC_BASE_VA + 0x80 + (x*0x04))
++#define AST_FIQ_STS(x) (VIC_BASE_VA + 0x88 + (x*0x04))
++#define AST_RAW_STS(x) (VIC_BASE_VA + 0x90 + (x*0x04))
++#define AST_INTR_SEL(x) (VIC_BASE_VA + 0x98 + (x*0x04))
++#define AST_INTR_EN(x) (VIC_BASE_VA + 0xA0 + (x*0x04))
++#define AST_INTR_DIS(x) (VIC_BASE_VA + 0xA8 + (x*0x04))
++#define AST_INTR_SW_EN(x) (VIC_BASE_VA + 0xB0 + (x*0x04))
++#define AST_INTR_SW_CLR(x) (VIC_BASE_VA + 0xB8 + (x*0x04))
++#define AST_INTR_SENSE(x) (VIC_BASE_VA + 0xC0 + (x*0x04))
++#define AST_INTR_BOTH_EDGE(x) (VIC_BASE_VA + 0xC8 + (x*0x04))
++#define AST_INTR_EVENT(x) (VIC_BASE_VA + 0xD0 + (x*0x04))
++#define AST_INTR_EDGE_CLR(x) (VIC_BASE_VA + 0xD8 + (x*0x04))
++#define AST_INTR_EDGE_STS(x) (VIC_BASE_VA + 0xE0 + (x*0x04))
++
++#else
++
++//Legacy Maping
++
++#define AST_IRQ_STS(x) (VIC_BASE_VA + 0x00)
++#define AST_FIQ_STS(x) (VIC_BASE_VA + 0x04)
++#define AST_RAW_STS(x) (VIC_BASE_VA + 0x08)
++#define AST_INTR_SEL(x) (VIC_BASE_VA + 0x0C)
++#define AST_INTR_EN(x) (VIC_BASE_VA + 0x10)
++#define AST_INTR_DIS(x) (VIC_BASE_VA + 0x14)
++#define AST_INTR_SW_EN(x) (VIC_BASE_VA + 0x18)
++#define AST_INTR_SW_CLR(x) (VIC_BASE_VA + 0x1C)
++#define AST_INTR_SENSE(x) (VIC_BASE_VA + 0x24)
++#define AST_INTR_BOTH_EDGE(x) (VIC_BASE_VA + 0x28)
++#define AST_INTR_EVENT(x) (VIC_BASE_VA + 0x2C)
++#define AST_INTR_EDGE_CLR(x) (VIC_BASE_VA + 0x38)
++#endif
++
++#define IRQ_SET_LEVEL_TRIGGER(x, irq_no) *((volatile unsigned long*)AST_INTR_SENSE(x)) |= 1 << (irq_no)
++#define IRQ_SET_EDGE_TRIGGER(x, irq_no) *((volatile unsigned long*)AST_INTR_SENSE(x)) &= ~(1 << (irq_no))
++#define IRQ_SET_RISING_EDGE(x, irq_no) *((volatile unsigned long*)AST_INTR_EVENT(x)) |= 1 << (irq_no)
++#define IRQ_SET_FALLING_EDGE(x, irq_no) *((volatile unsigned long*)AST_INTR_EVENT(x)) &= ~(1 << (irq_no))
++#define IRQ_SET_HIGH_LEVEL(x,irq_no) *((volatile unsigned long*)AST_INTR_EVENT(x)) |= 1 << (irq_no)
++#define IRQ_SET_LOW_LEVEL(x, irq_no) *((volatile unsigned long*)AST_INTR_EVENT(x)) &= ~(1 << (irq_no))
++#define IRQ_EDGE_CLEAR(x, irq_no) *((volatile unsigned long*)AST_INTR_EDGE_CLR(x)) |= 1 << (irq_no)
++
++#endif
++
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-jtag.h b/arch/arm/plat-aspeed/include/plat/regs-jtag.h
+new file mode 100644
+index 0000000..7df385d
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-jtag.h
+@@ -0,0 +1,65 @@
++/* arch/arm/plat-aspeed/include/mach/regs-jtag.h
++ *
++ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
++ * http://www.aspeedtech.com/
++ *
++ * 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.
++ *
++ * ASPEED JTAG Controller
++*/
++
++#define AST_JTAG_DATA 0x00
++#define AST_JTAG_INST 0x04
++#define AST_JTAG_CTRL 0x08
++#define AST_JTAG_ISR 0x0C
++#define AST_JTAG_SW 0x10
++#define AST_JTAG_TCK 0x14
++#define AST_JTAG_IDLE 0x18
++
++/* AST_JTAG_CTRL - 0x08 : Engine Control */
++#define JTAG_ENG_EN (0x1 << 31)
++#define JTAG_ENG_OUT_EN (0x1 << 30)
++#define JTAG_FORCE_TMS (0x1 << 29)
++
++#define JTAG_IR_UPDATE (0x1 << 26) //AST2500 only
++#define JTAG_INST_LEN_MASK (0x3f << 20)
++#define JTAG_SET_INST_LEN(x) (x << 20)
++#define JTAG_SET_INST_MSB (0x1 << 19)
++#define JTAG_TERMINATE_INST (0x1 << 18)
++#define JTAG_LAST_INST (0x1 << 17)
++#define JTAG_INST_EN (0x1 << 16)
++#define JTAG_DATA_LEN_MASK (0x3f << 4)
++
++#define JTAG_DR_UPDATE (0x1 << 10) //AST2500 only
++#define JTAG_DATA_LEN(x) (x << 4)
++#define JTAG_SET_DATA_MSB (0x1 << 3)
++#define JTAG_TERMINATE_DATA (0x1 << 2)
++#define JTAG_LAST_DATA (0x1 << 1)
++#define JTAG_DATA_EN (0x1)
++
++/* AST_JTAG_ISR - 0x0C : INterrupt status and enable */
++#define JTAG_INST_PAUSE (0x1 << 19)
++#define JTAG_INST_COMPLETE (0x1 << 18)
++#define JTAG_DATA_PAUSE (0x1 << 17)
++#define JTAG_DATA_COMPLETE (0x1 << 16)
++
++#define JTAG_INST_PAUSE_EN (0x1 << 3)
++#define JTAG_INST_COMPLETE_EN (0x1 << 2)
++#define JTAG_DATA_PAUSE_EN (0x1 << 1)
++#define JTAG_DATA_COMPLETE_EN (0x1)
++
++
++/* AST_JTAG_SW - 0x10 : Software Mode and Status */
++#define JTAG_SW_MODE_EN (0x1 << 19)
++#define JTAG_SW_MODE_TCK (0x1 << 18)
++#define JTAG_SW_MODE_TMS (0x1 << 17)
++#define JTAG_SW_MODE_TDIO (0x1 << 16)
++//
++#define JTAG_STS_INST_PAUSE (0x1 << 2)
++#define JTAG_STS_DATA_PAUSE (0x1 << 1)
++#define JTAG_STS_ENG_IDLE (0x1)
++
++/* AST_JTAG_IDLE - 0x18 : Ctroller set for go to IDLE */
++#define JTAG_GO_IDLE (0x1)
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-lpc.h b/arch/arm/plat-aspeed/include/plat/regs-lpc.h
+new file mode 100644
+index 0000000..f4523d7
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-lpc.h
+@@ -0,0 +1,215 @@
++/* arch/arm/plat-aspeed/include/mach/regs-lpc.h
++ *
++ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
++ * http://www.aspeedtech.com/
++ *
++ * 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.
++ *
++ * ASPEED LPC Controller
++*/
++
++#ifndef __AST_LPC_H_
++#define __AST_LPC_H_
++
++#define AST_LPC_HICR0 0x000
++#define AST_LPC_HICR1 0x004
++#define AST_LPC_HICR2 0x008 /* Host Interface Control Register 2 */
++#define AST_LPC_HICR3 0x00C
++#define AST_LPC_HICR4 0x010
++#define AST_LPC_LADR3H 0x014
++#define AST_LPC_LADR3L 0x018
++#define AST_LPC_LADR12H 0x01C
++#define AST_LPC_LADR12L 0x020
++#define AST_LPC_IDR1 0x024
++#define AST_LPC_IDR2 0x028
++#define AST_LPC_IDR3 0x02C
++#define AST_LPC_ODR1 0x030
++#define AST_LPC_ODR2 0x034
++#define AST_LPC_ODR3 0x038
++#define AST_LPC_STR1 0x03C
++#define AST_LPC_STR2 0x040
++#define AST_LPC_STR3 0x044
++#define AST_LPC_BTR0 0x048
++#define AST_LPC_BTR1 0x04C
++#define AST_LPC_BTCSR0 0x050
++#define AST_LPC_BTCSR1 0x054
++#define AST_LPC_BTCR 0x058
++#define AST_LPC_BTDTR 0x05C
++#define AST_LPC_BTIMSR 0x060
++#define AST_LPC_BTFVSR0 0x064
++#define AST_LPC_BTFVSR1 0x068
++#define AST_LPC_SIRQCR0 0x06C
++#define AST_LPC_SIRQCR1 0x070
++#define AST_LPC_SIRQCR2 0x074
++#define AST_LPC_SIRQCR3 0x078
++
++//////
++#define AST_LPC_HICR5 0x080 /* LPC Host interface Control Register 5 */
++#define AST_LPC_HICR6 0x084 /* LPC Host Interface Control Register 6 */
++#define AST_LPC_HICR7 0x088
++#define AST_LPC_HICR8 0x08C
++#define AST_LPC_SNPWADR 0x090 /* LPC Snoop Address Register */
++#define AST_LPC_SNPWDR 0x094 /* LPC SNoop Data Register */
++#define AST_LPC_HICR9 0x098
++#define AST_LPC_HICRA 0x09C
++#define AST_LPC_LHCR0 0x0A0
++#define AST_LPC_LHCR1 0x0A4
++#define AST_LPC_LHCR2 0x0A8
++#define AST_LPC_LHCR3 0x0AC
++#define AST_LPC_LHCR4 0x0B0
++#define AST_LPC_LHCR5 0x0B4
++#define AST_LPC_LHCR6 0x0B8
++#define AST_LPC_LHCR7 0x0BC
++#define AST_LPC_LHCR8 0x0C0
++#define AST_LPC_PCCR6 0x0C4
++#define AST_LPC_LHCRA 0x0C8
++#define AST_LPC_LHCRB 0x0CC
++
++
++#define AST_LPC_PCCR4 0x0D0 /* Post Code Control Regiter 4 */
++#define AST_LPC_PCCR5 0x0D4 /* Post Code Control Regiter 5 */
++
++#define AST_LPC_HICRB 0x0D8
++#define AST_LPC_HICRC 0x0DC
++#define AST_LPC_HISR0 0x0E0
++#define AST_LPC_HISR1 0x0E4
++#define AST_LPC_LADR4 0x0E8
++#define AST_LPC_IDR4 0x0EC
++#define AST_LPC_ODR4 0x0F0
++#define AST_LPC_STR4 0x0F4
++#define AST_LPC_LSADR12 0x0F8
++#define AST_LPC_IDR5 0x0FC
++#define AST_LPC_ODR5 0x100
++#define AST_LPC_STR5 0x104
++
++
++
++#define AST_LPC_PCCR0 0x130 /*Post Code Contol Register 0 */
++#define AST_LPC_PCCR1 0x134 /*Post Code Contol Register 1 */
++#define AST_LPC_PCCR2 0x138 /*Post Code Contol Register 2 */
++#define AST_LPC_PCCR3 0x13C /*Post Code Contol Register 3 */
++
++
++#define AST_LPC_IBTCR0 0x140
++#define AST_LPC_IBTCR1 0x144
++#define AST_LPC_IBTCR2 0x148
++#define AST_LPC_IBTCR3 0x14C
++#define AST_LPC_IBTCR4 0x150
++#define AST_LPC_IBTCR5 0x154
++#define AST_LPC_IBTCR6 0x158
++#define AST_LPC_SRUART1 0x15C
++#define AST_LPC_SRUART2 0x160
++#define AST_LPC_SRUART3 0x164
++#define AST_LPC_SRUART4 0x168
++#define AST_LPC_SCR0SIO 0x16C
++#define AST_LPC_SCR0SI1 0x170
++#define AST_LPC_SCR0SI2 0x174
++#define AST_LPC_SCR0SI3 0x17C
++
++#define AST_LPC_SWCR0300 0x180
++#define AST_LPC_SWCR0704 0x184
++#define AST_LPC_SWCR0B08 0x188
++#define AST_LPC_SWCR0F0C 0x18C
++#define AST_LPC_SWCR1310 0x190
++#define AST_LPC_SWCR1714 0x194
++#define AST_LPC_SWCR1B18 0x198
++#define AST_LPC_SWCR1F1C 0x19C
++#define AST_LPC_ACPIE3E0 0x1A0
++#define AST_LPC_ACPIC1C0 0x1A4
++#define AST_LPC_ACPIB3B0 0x1A8
++#define AST_LPC_ACPIB7B4 0x1AC
++
++/* AST_LPC_HICR0 0x000 */
++#define LPC_LPC3_EN (1 << 7)
++#define LPC_LPC2_EN (1 << 6)
++#define LPC_LPC1_EN (1 << 5)
++
++#define LPC_SDWNE (1 << 3)
++#define LPC_PMEE (1 << 2)
++
++/* AST_LPC_HICR2 0x008 */
++#define LPC_LRST (1 << 6)
++#define LPC_SDWN (1 << 5)
++#define LPC_ABRT (1 << 4)
++#define LPC_IBFIF3 (1 << 3)
++#define LPC_IBFIF2 (1 << 2)
++#define LPC_IBFIF1 (1 << 1)
++#define LPC_EERIE (1)
++
++
++
++
++
++
++
++/* AST_LPC_HICR4 0x010 */
++#define LPC_HICS_LADR12AS (1 << 7)
++#define LPC_HICS_CLRINTLRSTR (1 << 6)
++#define LPC_HICS_STSINTLRSTR (1 << 5)
++#define LPC_HICS_ENINTLRSTR (1 << 4)
++/* bit 3 reserved */
++#define LPC_HICS_KCSENBL (1 << 2)
++/* bit 1 reserved */
++#define LPC_HICS_BTENBL (1)
++
++
++/* AST_LPC_STR1 0: 0x03C, 1: 0x40, 2 : 0x44, 3: 4: */
++#define LPC_STR_DBU4 (1 << 7)
++#define LPC_STR_DBU3 (1 << 6)
++#define LPC_STR_DBU2 (1 << 5)
++#define LPC_STR_DBU1 (1 << 4)
++#define LPC_STR_CMD_DAT (1 << 3)
++#define LPC_STR_DBU0 (1 << 2)
++#define LPC_STR_IBF (1 << 1)
++#define LPC_STR_OBF (1)
++
++
++/* AST_LPC_HICR5 0x080 - LPC Host interface Control Register */
++#define LPC_HICR5_SNP1INT_EN (1 << 3)
++#define LPC_HICR5_SNP1W_EN (1 << 2)
++#define LPC_HICR5_SNP0INT_EN (1 << 1)
++#define LPC_HICR5_SNP0W_EN (1)
++
++/* AST_LPC_HICR6 0x084 - LPC Host Interface Control Register 6 */
++#define LPC_HICR6_STR_BAUD (1 << 3)
++#define LPC_HICR6_STR_PME (1 << 2)
++#define LPC_HICR6_STR_SNP1W (1 << 1)
++#define LPC_HICR6_STR_SNP0W (1)
++
++/* AST_LPC_SNPWADR 0x090 - LPC Snoop Address Register*/
++#define LPC_SNOOP_ADDR1_MASK (0xffff << 16)
++#define LPC_SNOOP_ADDR0_MASK (0xffff)
++
++/* AST_LPC_SNPWDR 0x094 - LPC SNoop Data Register */
++#define GET_LPC_SNPD1(x) ((x >> 7) & 0xff)
++#define GET_LPC_SNPD0(x) (x & 0xff)
++
++/*AST_LPC_PCCR0 0x130 - Post Code Contol Register 0 */
++#define LPC_POST_DMA_INT_EN (1 << 31)
++#define LPC_POST_DMA_MODE_EN (1 << 14)
++#define LPC_RX_FIFO_CLR (1 << 7)
++#define LPC_POST_
++#define LPC_POST_CODE_MODE_MASK (0x3 << 4)
++#define LPC_POST_CODE_MODE(x) (x << 4)
++#define BYTE_MODE 0
++#define WORD_MODE 1
++#define DWORD_MODE 2
++#define FULL_MODE 3
++
++#define LPC_POST_CODE_RXOVR (1 << 3)
++#define LPC_POST_CODE_RXTO (1 << 2)
++#define LPC_POST_CODE_RXAVA (1 << 1)
++#define LPC_POST_CODE_EN (1)
++
++/*AST_LPC_PCCR1 0x134 Post Code Contol Register 1 */
++#define LPC_POST_ADDR_MASK 0x3fffff
++#define LPC_CAPTURE_ADDR_MASK(x) (x << 16)
++#define LPC_CAPTURE_BASE_ADDR(x) (x)
++
++/*AST_LPC_PCCR2 0x138 Post Code Contol Register 2 */
++#define LPC_POST_CODE_DMA_RDY (1 << 4)
++#define LPC_POST_CODE_STS (1)
++
++#endif
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-mbx.h b/arch/arm/plat-aspeed/include/plat/regs-mbx.h
+new file mode 100644
+index 0000000..636207f
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-mbx.h
+@@ -0,0 +1,48 @@
++/* arch/arm/plat-aspeed/include/mach/regs-lpc.h
++ *
++ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
++ * http://www.aspeedtech.com/
++ *
++ * 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.
++ *
++ * ASPEED LPC Controller
++*/
++
++#ifndef __AST_MBX_H_
++#define __AST_MBX_H_
++
++#define AST_MBX_DAT0 0x00
++#define AST_MBX_DAT1 0x04
++#define AST_MBX_DAT2 0x08
++#define AST_MBX_DAT3 0x0C
++#define AST_MBX_DAT4 0x10
++#define AST_MBX_DAT5 0x14
++#define AST_MBX_DAT6 0x18
++#define AST_MBX_DAT7 0x1C
++#define AST_MBX_DAT8 0x20
++#define AST_MBX_DAT9 0x24
++#define AST_MBX_DATA 0x28
++#define AST_MBX_DATB 0x2C
++#define AST_MBX_DATC 0x30
++#define AST_MBX_DATD 0x34
++#define AST_MBX_DATE 0x38
++#define AST_MBX_DATF 0x3C
++#define AST_MBX_STS0 0x40
++#define AST_MBX_STS1 0x44
++#define AST_MBX_BCR 0x48
++#define AST_MBX_HCR 0x4C
++#define AST_MBX_BIE0 0x50
++#define AST_MBX_BIE1 0x54
++#define AST_MBX_HIE0 0x58
++#define AST_MBX_HIE1 0x5C
++
++/* AST_MBX_BCR 0x48 */
++#define MBHIST (1 << 7)
++#define MBHMK (1 << 1)
++#define MBBINT (1)
++
++
++
++#endif
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-mctp.h b/arch/arm/plat-aspeed/include/plat/regs-mctp.h
+new file mode 100644
+index 0000000..2237cfe
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-mctp.h
+@@ -0,0 +1,47 @@
++/* arch/arm/mach-aspeed/include/mach/regs-ast1010-scu.h
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * 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.
++ *
++ * History :
++ * 1. 2012/12/29 Ryan Chen Create
++ *
++********************************************************************************/
++#ifndef __AST_MCTP_H
++#define __AST_MCTP_H 1
++
++/*
++ * Register for MCTP
++ * */
++#define AST_MCTP_CTRL 0x00 /* Engine Status and Engine Control */
++#define AST_MCTP_INT 0x04 /* Interrupt Enable and Status Register */
++#define AST_MCTP_ID 0x08 /* Target ID and Mask */
++#define AST_MCTP_TX_DESC3 0x10 /* Sending Descriptor [127:96] */
++#define AST_MCTP_TX_DESC2 0x14 /* Sending Descriptor [95:64] */
++#define AST_MCTP_TX_DESC1 0x18 /* Sending Descriptor [63:32] */
++#define AST_MCTP_TX_DESC0 0x1C /* Sending Descriptor [31:0] */
++#define AST_MCTP_TX_DATA 0x20 /* Sending Data Port */
++#define AST_MCTP_RX_DESC3 0x40 /* Received Descriptor [127:96] */
++#define AST_MCTP_RX_DESC2 0x44 /* Received Descriptor [95:64] */
++#define AST_MCTP_RX_DESC1 0x48 /* Received Descriptor [63:32] */
++#define AST_MCTP_RX_DESC0 0x4C /* Received Descriptor [31:0] */
++#define AST_MCTP_RX_DATA 0x50 /* Received Data Port */
++
++#define AST_MCTP_DEC_ADDR 0x80 /* ADDR */
++#define AST_MCTP_DEC_MASK 0x84 /* MASK */
++#define AST_MCTP_DEC_TAG 0x88 /* TAG */
++
++/* AST_MCTP_CTRL 0x00 Engine Status and Engine Control */
++
++/* AST_MCTP_INT 0x04 Interrupt Enable and Status Register */
++#define MCTP_RX_INT_EN (1 << 17)
++#define MCTP_TX_INT_EN (1 << 16)
++
++#define MCTP_RX_COMPLETE (1 << 1)
++#define MCTP_TX_COMPLETE (1)
++
++#endif
++
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-pcie.h b/arch/arm/plat-aspeed/include/plat/regs-pcie.h
+new file mode 100644
+index 0000000..bd699fc
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-pcie.h
+@@ -0,0 +1,68 @@
++/* arch/arm/mach-aspeed/include/mach/regs-ast1010-scu.h
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * 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.
++ *
++ * History :
++ * 1. 2012/12/29 Ryan Chen Create
++ *
++********************************************************************************/
++#ifndef __AST_PCIE_H
++#define __AST_PCIE_H 1
++
++/*
++ * Register for PCIE
++ * */
++#define AST_PCIE_CFG2 0x04
++#define AST_PCIE_SSID 0x28
++#define AST_PCIE_GLOBAL 0x30
++#define AST_PCIE_LOCK 0x7C
++
++#define AST_PCIE_LINK 0xC0
++#define AST_PCIE_INT 0xC4
++
++/* AST_PCIE_CFG2 0x04 */
++#define PCIE_CFG_CLASS_CODE(x) (x << 8)
++#define PCIE_CFG_REV_ID(x) (x)
++
++
++/*SSID: 1E6ED028h[19:4]*/
++/*SSVID: 1E6ED028h[3:0], 1E6ED024h[31:20]*/
++
++/* AST_PCIE_SSID_A 0x24 */
++/* 31:20 */
++#define PCIE_SSVID_H(x) (x)
++
++/* AST_PCIE_SSID_B 0x28 */
++/* 19:14 */
++#define PCIE_SSID(x) (x << 4)
++/* 3:0 */
++#define PCIE_SSVID_L(x) (x)
++
++
++/* AST_PCIE_GLOBAL 0x30 */
++#define ROOT_COMPLEX_ID(x) (x << 4)
++
++
++/* AST_PCIE_LOCK 0x7C */
++#define PCIE_UNLOCK 0xa8
++
++/* AST_PCIE_LINK 0xC0 */
++#define PCIE_LINK_STS (1 << 5)
++
++/* AST_PCIE_INT 0xC4 */
++#define PCIE_INTD (1 << 16)
++#define PCIE_INTC (1 << 15)
++#define PCIE_INTB (1 << 14)
++#define PCIE_INTA (1 << 13)
++
++#define AST_PCIE_NONP_MEM_BASE AST_PCIE0_WIN_BASE0
++#define AST_PCIE_NONP_MEM_SIZE AST_PCIE0_WIN_SIZE0
++#define AST_PCIE_PREF_MEM_BASE 0x0
++#define AST_PCIE_PREF_MEM_SIZE 0x0
++
++#endif
++
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-peci.h b/arch/arm/plat-aspeed/include/plat/regs-peci.h
+new file mode 100644
+index 0000000..266daca
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-peci.h
+@@ -0,0 +1,106 @@
++/* arch/arm/plat-aspeed/include/mach/regs-peci.h
++ *
++ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
++ * http://www.aspeedtech.com/
++ *
++ * 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.
++ *
++ * ASPEED PECI Controller
++*/
++
++#ifndef __ASM_ARCH_REGS_PECI_H
++#define __ASM_ARCH_REGS_PECI_H __FILE__
++
++/*AST PECI Register Definition */
++#define AST_PECI_CTRL 0x00
++#define AST_PECI_TIMING 0x04
++#define AST_PECI_CMD 0x08
++#define AST_PECI_CMD_CTRL 0x0C
++#define AST_PECI_EXP_FCS 0x10
++#define AST_PECI_CAP_FCS 0x14
++#define AST_PECI_INT_CTRL 0x18
++#define AST_PECI_INT_STS 0x1C
++#define AST_PECI_W_DATA0 0x20
++#define AST_PECI_W_DATA1 0x24
++#define AST_PECI_W_DATA2 0x28
++#define AST_PECI_W_DATA3 0x2c
++#define AST_PECI_R_DATA0 0x30
++#define AST_PECI_R_DATA1 0x34
++#define AST_PECI_R_DATA2 0x38
++#define AST_PECI_R_DATA3 0x3c
++#define AST_PECI_W_DATA4 0x40
++#define AST_PECI_W_DATA5 0x44
++#define AST_PECI_W_DATA6 0x48
++#define AST_PECI_W_DATA7 0x4c
++#define AST_PECI_R_DATA4 0x50
++#define AST_PECI_R_DATA5 0x54
++#define AST_PECI_R_DATA6 0x58
++#define AST_PECI_R_DATA7 0x5c
++
++
++/* AST_PECI_CTRL - 0x00 : Control Register */
++#define PECI_CTRL_SAMPLING_MASK (0xf << 16)
++#define PECI_CTRL_SAMPLING(x) (x << 16)
++#define PECI_CTRL_READ_MODE_MASK (0xf << 12)
++#define PECI_CTRL_CONT_MODE (1 << 16)
++#define PECI_CTRL_DBG_MODE (2 << 16)
++#define PECI_CTRL_CLK_SOURCE (0x1 << 11) //0: 24Mhz, 1: MCLK
++#define PECI_CTRL_CLK_DIV_MASK (0x3 << 8)
++#define PECI_CTRL_CLK_DIV(x) (x << 8)
++#define PECI_CTRL_INVERT_OUT (0x1 << 7)
++#define PECI_CTRL_INVERT_IN (0x1 << 6)
++#define PECI_CTRL_BUS_CONTENT_EN (0x1 << 5)
++#define PECI_CTRL_PECI_EN (0x1 << 4)
++#define PECI_CTRL_PECI_CLK_EN (0x1)
++
++/* AST_PECI_TIMING - 0x04 : Timing Negotiation */
++#define PECI_TIMING_MESSAGE_GET(x) ((x & 0xff00) >> 8)
++#define PECI_TIMING_MESSAGE(x) (x << 8)
++#define PECI_TIMING_ADDRESS_GET(x) (x & 0xff)
++#define PECI_TIMING_ADDRESS(x) (x)
++
++/* AST_PECI_CMD - 0x08 : Command Register */
++#define PECI_CMD_PIN_MON (0x1 << 31)
++#define PECI_CMD_STS (0xf << 24)
++#define PECI_CMD_FIRE (0x1)
++
++/* AST_PECI_LEN - 0x0C : Read/Write Length Register */
++#define PECI_AW_FCS_EN (0x1 << 31)
++#define PECI_READ_LEN_MASK (0xff << 16)
++#define PECI_READ_LEN(x) (x << 16)
++#define PECI_WRITE_LEN_MASK (0xff << 8)
++#define PECI_WRITE_LEN(x) (x << 8)
++#define PECI_TAGET_ADDR_MASK (0xff)
++#define PECI_TAGET_ADDR(x) (x)
++
++
++/* AST_PECI_EXP_FCS - 0x10 : Expected FCS Data Register */
++#define PECI_PROGRAM_AW_FCS (0xf << 24)
++#define PECI_EXPECT_READ_FCS (0xf << 16)
++#define PECI_EXPECT_AW_FCS_AUTO (0xf << 8)
++#define PECI_EXPECT_WRITE_FCS (0xf)
++
++/* AST_PECI_CAP_FCS - 0x14 : Captured FCS Data Register */
++#define PECI_CAPTURE_READ_FCS(x) ((x & 0xff) >> 16)
++#define PECI_CAPTURE_WRITE_FCS (0xff)
++
++/* AST_PECI_INT_CTRL/ STS - 0x18/0x1c : Interrupt Register */
++#define PECI_INT_TIMING_RESULT_MASK (0x3 << 30)
++#define PECI_INT_TIMEOUT (0x1 << 4)
++#define PECI_INT_CONNECT (0x1 << 3)
++#define PECI_INT_W_FCS_BAD (0x1 << 2)
++#define PECI_INT_W_FCS_ABORT (0x1 << 1)
++#define PECI_INT_CMD_DONE (0x1)
++
++#define AUTO_GEN_AWFCS 1
++//#define ENABLE_BUS_CONTENTION 0x20
++
++#define DISABLE_ENGINE 0
++#define ENABLE_RX_ENGINE (1 << 0)
++#define ENABLE_TX_ENGINE (1 << 1)
++#define LEFT_CHANNEL_HIGH (1 << 16)
++#define DELAY_CLOCK_CYCLE (1 << 17)
++
++#endif /* __ASM_ARCH_REGS_PECI_H */
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-pwm_fan.h b/arch/arm/plat-aspeed/include/plat/regs-pwm_fan.h
+new file mode 100644
+index 0000000..23d5b77
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-pwm_fan.h
+@@ -0,0 +1,250 @@
++/* arch/arm/plat-aspeed/include/mach/regs-pwm-fan.h
++ *
++ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
++ * http://www.aspeedtech.com/
++ *
++ * 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.
++ *
++ * ASPEED PWM & Fan Tacho Controller
++*/
++
++#ifndef __ASM_ARCH_REGS_PWM_FAN_H
++#define __ASM_ARCH_REGS_PWM_FAN_H __FILE__
++
++/*AST PWM & FAN Register Definition */
++#define AST_PTCR_CTRL 0x00
++#define AST_PTCR_CLK_CTRL 0x04
++#define AST_PTCR_DUTY0_CTRL 0x08
++#define AST_PTCR_DUTY1_CTRL 0x0c
++#define AST_PTCR_TYPEM_CTRL0 0x10
++#define AST_PTCR_TYPEM_CTRL1 0x14
++#define AST_PTCR_TYPEN_CTRL0 0x18
++#define AST_PTCR_TYPEN_CTRL1 0x1c
++#define AST_PTCR_TACH_SOURCE 0x20
++// no 0x24
++#define AST_PTCR_TRIGGER 0x28
++#define AST_PTCR_RESULT 0x2c
++#define AST_PTCR_INTR_CTRL 0x30
++#define AST_PTCR_INTR_STS 0x34
++#define AST_PTCR_TYPEM_LIMIT 0x38
++#define AST_PTCR_TYPEN_LIMIT 0x3C
++#define AST_PTCR_CTRL_EXT 0x40
++#define AST_PTCR_CLK_EXT_CTRL 0x44
++#define AST_PTCR_DUTY2_CTRL 0x48
++#define AST_PTCR_DUTY3_CTRL 0x4c
++#define AST_PTCR_TYPEO_CTRL0 0x50
++#define AST_PTCR_TYPEO_CTRL1 0x54
++#define AST_PTCR_TACH_SOURCE_EXT 0x60
++#define AST_PTCR_TYPEO_LIMIT 0x78
++
++//COMMON Definition
++#define FALL_EDGE (0)
++#define RISE_EDGE (0x1)
++#define BOTH_EDGE (0x2)
++
++#ifdef CONFIG_ARCH_AST1010
++#define PWM_TYPE_NUM 2
++#define PWM_TYPE_M 0x0
++#define PWM_TYPE_N 0x1
++#define PWM_TYPE_MASK 0x1
++#else
++#define PWM_TYPE_NUM 3
++#define PWM_TYPE_M 0x0
++#define PWM_TYPE_N 0x1
++#define PWM_TYPE_O 0x2
++#define PWM_TYPE_MASK 0x3
++
++#endif
++
++#define TACHO_NUM 16
++#define PWM_CH_NUM 8
++#define PWMA 0x0
++#define PWMB 0x1
++#define PWMC 0x2
++#define PWMD 0x3
++#define PWME 0x4
++#define PWMF 0x5
++#define PWMG 0x6
++#define PWMH 0x7
++
++
++// AST_PTCR_CTRL:0x00 - PWM-FAN General Control Register
++#define AST_PTCR_CTRL_SET_PWMD_TYPE(x) ((x&0x1)<<15 | (x&0x2) <<6)
++#define AST_PTCR_CTRL_GET_PWMD_TYPE(x) (((x&(0x1<<7))>>6) | ((x&(0x1<<15))>>15))
++#define AST_PTCR_CTRL_SET_PWMD_TYPE_MASK ((0x1<<7) | (0x1<<15))
++
++#define AST_PTCR_CTRL_SET_PWMC_TYPE(x) ((x&0x1)<<14 | (x&0x2) <<5)
++#define AST_PTCR_CTRL_GET_PWMC_TYPE(x) (((x&(0x1<<6))>>5) | ((x&(0x1<<14))>>14))
++#define AST_PTCR_CTRL_SET_PWMC_TYPE_MASK ((0x1<<6) | (0x1<<14))
++
++#define AST_PTCR_CTRL_SET_PWMB_TYPE(x) ((x&0x1)<<13 | (x&0x2) <<4)
++#define AST_PTCR_CTRL_GET_PWMB_TYPE(x) (((x&(0x1<<5))>>4) | ((x&(0x1<<13))>>13))
++#define AST_PTCR_CTRL_SET_PWMB_TYPE_MASK ((0x1<<5) | (0x1<<13))
++
++
++#define AST_PTCR_CTRL_SET_PWMA_TYPE(x) ((x&0x1)<<12 | (x&0x2) <<3)
++#define AST_PTCR_CTRL_GET_PWMA_TYPE(x) (((x&(0x1<<4))>>3) | ((x&(0x1<<12))>>12))
++#define AST_PTCR_CTRL_SET_PWMA_TYPE_MASK ((0x1<<4) | (0x1<<12))
++
++#define AST_PTCR_CTRL_FAN_NUM_EN(x) (0x1 << (16+x))
++
++#define AST_PTCR_CTRL_PMWD (11)
++#define AST_PTCR_CTRL_PMWD_EN (0x1 << 11)
++#define AST_PTCR_CTRL_PMWC (10)
++#define AST_PTCR_CTRL_PMWC_EN (0x1 << 10)
++#define AST_PTCR_CTRL_PMWB (9)
++#define AST_PTCR_CTRL_PMWB_EN (0x1 << 9)
++#define AST_PTCR_CTRL_PMWA (8)
++#define AST_PTCR_CTRL_PMWA_EN (0x1 << 8)
++
++#define AST_PTCR_CTRL_CLK_MCLK 0x2 //0:24Mhz, 1:MCLK
++#define AST_PTCR_CTRL_CLK_EN 0x1
++
++// AST_PTCR_CLK_CTRL:0x04 - PWM-FAN Clock Control Register
++//TYPE N
++#define AST_PTCR_CLK_CTRL_TYPEN_UNIT (24)
++#define AST_PTCR_CLK_CTRL_TYPEN_UNIT_MASK (0xff<<24)
++#define AST_PTCR_CLK_CTRL_TYPEN_H (20)
++#define AST_PTCR_CLK_CTRL_TYPEN_H_MASK (0xf<<20)
++#define AST_PTCR_CLK_CTRL_TYPEN_L (16)
++#define AST_PTCR_CLK_CTRL_TYPEN_L_MASK (0xf<<16)
++//TYPE M
++#define AST_PTCR_CLK_CTRL_TYPEM_UNIT (8)
++#define AST_PTCR_CLK_CTRL_TYPEM_UNIT_MASK (0xff<<8)
++#define AST_PTCR_CLK_CTRL_TYPEM_H (4)
++#define AST_PTCR_CLK_CTRL_TYPEM_H_MASK (0xf<<4)
++#define AST_PTCR_CLK_CTRL_TYPEM_L (0)
++#define AST_PTCR_CLK_CTRL_TYPEM_L_MASK (0xf)
++
++
++// AST_PTCR_DUTY_CTRL0:0x08 - PWM-FAN duty control 0 register
++#define DUTY_CTRL0_PWMB_FALL_POINT (24)
++#define DUTY_CTRL0_PWMB_FALL_POINT_MASK (0xff<<24)
++#define DUTY_CTRL0_PWMB_RISE_POINT (16)
++#define DUTY_CTRL0_PWMB_RISE_POINT_MASK (0xff<<16)
++#define DUTY_CTRL0_PWMA_FALL_POINT (8)
++#define DUTY_CTRL0_PWMA_FALL_POINT_MASK (0xff<<8)
++#define DUTY_CTRL0_PWMA_RISE_POINT (0)
++#define DUTY_CTRL0_PWMA_RISE_POINT_MASK (0xff)
++
++
++// AST_PTCR_DUTY_CTRL1 : 0x0c - PWM-FAN duty control 1 register
++#define DUTY_CTRL1_PWMD_FALL_POINT (24)
++#define DUTY_CTRL1_PWMD_FALL_POINT_MASK (0xff<<24)
++#define DUTY_CTRL1_PWMD_RISE_POINT (16)
++#define DUTY_CTRL1_PWMD_RISE_POINT_MASK (0xff<<16)
++#define DUTY_CTRL1_PWMC_FALL_POINT (8)
++#define DUTY_CTRL1_PWMC_FALL_POINT_MASK (0xff<<8)
++#define DUTY_CTRL1_PWMC_RISE_POINT (0)
++#define DUTY_CTRL1_PWMC_RISE_POINT_MASK (0xff)
++
++
++// AST_PTCR_TYPEM_CTRL0 : 0x10/0x18/0x50 - Type M/N/O Ctrl 0 Register
++#define TYPE_CTRL0_FAN_PERIOD (16)
++#define TYPE_CTRL0_FAN_PERIOD_MASK (0xffff<<16)
++//Type O not have this
++#define TYPE_CTRL0_FLAT_EN (0x1<<7)
++
++
++// 0 : FALL_EDGE, 0x1 : RISE_EDGE , 0x2 :BOTH_EDGE
++#define TYPE_CTRL0_FAN_MODE (4)
++#define TYPE_CTRL0_FAN_MODE_MASK (0x3<<4)
++
++
++
++#define TYPE_CTRL0_CLK_DIVISION (1)
++#define TYPE_CTRL0_CLK_DIVISION_MASK (0x7<<1)
++
++#define TYPE_CTRL0_FAN_TYPE_EN (1)
++
++
++// AST_PTCR_TYPEM_CTRL1 : 0x14/0x1c/0x54 - Type M/N/O Ctrl 1 Register
++#define TYPE_CTRL1_FALL_POINT (16)
++#define TYPE_CTRL1_FALL_POINT_MASK (0xff<<16)
++#define TYPE_CTRL1_RISE_POINT (0)
++#define TYPE_CTRL1_RISE_POINT_MASK (0xff)
++
++
++// AST_PTCR_TACH_SOURCE : 0x20/0x60 - Tach Source Register
++//bit [0,1] at 0x20, bit [2] at 0x60
++#define TACH_PWM_SOURCE_BIT01(x) (x*2)
++#define TACH_PWM_SOURCE_BIT2(x) (x*2)
++
++#define TACH_PWM_SOURCE_MASK_BIT01(x) (0x3<<(x*2))
++#define TACH_PWM_SOURCE_MASK_BIT2(x) (0x1<<(x*2))
++
++// AST_PTCR_TRIGGER : 0x28 - Trigger Register
++#define TRIGGER_READ_FAN_NUM(x) (0x1<<x)
++
++// AST_PTCR_RESULT : 0x2c - Result Register
++#define RESULT_STATUS (31)
++
++#define RESULT_VALUE_MASK (0xfffff)
++
++// AST_PTCR_INTR_CTRL : 0x30 - Interrupt Ctrl Register
++#define INTR_CTRL_EN_NUM(x) (0x1<<x)
++
++// AST_PTCR_INTR_STS : 0x34 - Interrupt Status Register
++#define INTR_CTRL_NUM(x) (0x1<<x)
++
++//AST_PTCR_TYPEM_LIMIT, AST_PTCR_TYPEN_LIMIT,AST_PTCR_TYPEO_LIMIT : 0x38/0x3C/0x78 - Type M / N / O Limit Register
++#define FAN_LIMIT_MASK (0xfffff)
++
++// AST_PTCR_CTRL_EXT : 0x40 - General Ctrl Extension #1
++#define AST_PTCR_CTRL_SET_PWMH_TYPE(x) ((x&0x1)<<15 | (x&0x2) <<6)
++#define AST_PTCR_CTRL_GET_PWMH_TYPE(x) (((x&(0x1<<7))>>6) | ((x&(0x1<<15))>>15))
++#define AST_PTCR_CTRL_SET_PWMH_TYPE_MASK ((0x1<<7) | (0x1<<15))
++
++#define AST_PTCR_CTRL_SET_PWMG_TYPE(x) ((x&0x1)<<14 | (x&0x2) <<5)
++#define AST_PTCR_CTRL_GET_PWMG_TYPE(x) (((x&(0x1<<6))>>5) | ((x&(0x1<<14))>>14))
++#define AST_PTCR_CTRL_SET_PWMG_TYPE_MASK ((0x1<<6) | (0x1<<14))
++
++#define AST_PTCR_CTRL_SET_PWMF_TYPE(x) ((x&0x1)<<13 | (x&0x2) <<4)
++#define AST_PTCR_CTRL_GET_PWMF_TYPE(x) (((x&(0x1<<5))>>4) | ((x&(0x1<<13))>>13))
++#define AST_PTCR_CTRL_SET_PWMF_TYPE_MASK ((0x1<<5) | (0x1<<13))
++
++#define AST_PTCR_CTRL_SET_PWME_TYPE(x) ((x&0x1)<<12 | (x&0x2) <<3)
++#define AST_PTCR_CTRL_GET_PWME_TYPE(x) (((x&(0x1<<4))>>3) | ((x&(0x1<<12))>>12))
++#define AST_PTCR_CTRL_SET_PWME_TYPE_MASK ((0x1<<4) | (0x1<<12))
++
++#define AST_PTCR_CTRL_PMWH (11)
++#define AST_PTCR_CTRL_PMWH_EN (0x1 << 11)
++#define AST_PTCR_CTRL_PMWG (10)
++#define AST_PTCR_CTRL_PMWG_EN (0x1 << 10)
++#define AST_PTCR_CTRL_PMWF (9)
++#define AST_PTCR_CTRL_PMWF_EN (0x1 << 9)
++#define AST_PTCR_CTRL_PMWE (8)
++#define AST_PTCR_CTRL_PMWE_EN (0x1 << 8)
++
++// AST_PTCR_CLK_EXT_CTRL : 0x44 - Clock Control Extension #1
++//TYPE O
++#define AST_PTCR_CLK_CTRL_TYPEO_UNIT (8)
++#define AST_PTCR_CLK_CTRL_TYPEO_UNIT_MASK (0xff<<8)
++#define AST_PTCR_CLK_CTRL_TYPEO_H (4)
++#define AST_PTCR_CLK_CTRL_TYPEO_H_MASK (0xf<<4)
++#define AST_PTCR_CLK_CTRL_TYPEO_L (0)
++#define AST_PTCR_CLK_CTRL_TYPEO_L_MASK (0xf)
++
++// AST_PTCR_DUTY2_CTRL : 0x48 - Duty Control 2 Register
++#define DUTY_CTRL2_PWMF_FALL_POINT (24)
++#define DUTY_CTRL2_PWMF_FALL_POINT_MASK (0xff<<24)
++#define DUTY_CTRL2_PWMF_RISE_POINT (16)
++#define DUTY_CTRL2_PWMF_RISE_POINT_MASK (0xff<<16)
++#define DUTY_CTRL2_PWME_FALL_POINT (8)
++#define DUTY_CTRL2_PWME_FALL_POINT_MASK (0xff<<8)
++#define DUTY_CTRL2_PWME_RISE_POINT (0)
++#define DUTY_CTRL2_PWME_RISE_POINT_MASK (0xff)
++
++// AST_PTCR_DUTY3_CTRL : 0x4c - Duty Control 3 Register
++#define DUTY_CTRL3_PWMH_FALL_POINT (24)
++#define DUTY_CTRL3_PWMH_FALL_POINT_MASK (0xff<<24)
++#define DUTY_CTRL3_PWMH_RISE_POINT (16)
++#define DUTY_CTRL3_PWMH_RISE_POINT_MASK (0xff<<16)
++#define DUTY_CTRL3_PWMG_FALL_POINT (8)
++#define DUTY_CTRL3_PWMG_FALL_POINT_MASK (0xff<<8)
++#define DUTY_CTRL3_PWMG_RISE_POINT (0)
++#define DUTY_CTRL3_PWMG_RISE_POINT_MASK (0xff)
++
++#endif /* __ASM_ARCH_REGS_PWM_FAN_H */
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-rtc.h b/arch/arm/plat-aspeed/include/plat/regs-rtc.h
+new file mode 100644
+index 0000000..8a09a4b
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-rtc.h
+@@ -0,0 +1,64 @@
++/* arch/arm/plat-aspeed/include/mach/regs-iic.h
++ *
++ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
++ * http://www.aspeedtech.com/
++ *
++ * 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.
++ *
++ * ASPEED I2C Controller
++*/
++
++#ifndef __ASM_ARCH_REGS_RTC_H
++#define __ASM_ARCH_REGS_RTC_H __FILE__
++
++#define RTC_CNTR_STS_1 0x00
++#define RTC_CNTR_STS_2 0x04
++#define RTC_ALARM 0x08
++#define RTC_CONTROL 0x10
++#define RTC_ALARM_STS 0x14
++
++/* RTC_CNTR_STS_1 0x00 */
++/* RTC_ALARM 0x08 */
++#define GET_DAY_VAL(x) ((x >> 24)&0x1f)
++#define GET_HOUR_VAL(x) ((x >> 16)&0x1f)
++#define GET_MIN_VAL(x) ((x >> 8)&0x3f)
++#define GET_SEC_VAL(x) (x & 0x3f)
++
++#define SET_DAY_VAL(x) ((x&0x1f) << 24)
++#define SET_HOUR_VAL(x) ((x&0x1f) << 16)
++#define SET_MIN_VAL(x) ((x&0x3f) << 8)
++#define SET_SEC_VAL(x) (x & 0x3f)
++
++/* RTC_CNTR_STS_2 0x04 */
++#define GET_CENT_VAL(x) ((x >> 16)&0x1f)
++#define GET_YEAR_VAL(x) ((x >> 8)&0x7f)
++#define GET_MON_VAL(x) (x & 0xf)
++
++#define SET_CENT_VAL(x) ((x &0x1f) << 16)
++#define SET_YEAR_VAL(x) ((x &0x7f) << 8)
++#define SET_MON_VAL(x) (x & 0xf)
++
++/* RTC_CONTROL 0x10 */
++#define ENABLE_SEC_INTERRUPT (1 << 7)
++#define ENABLE_DAY_ALARM (1 << 6)
++#define ENABLE_HOUR_ALARM (1 << 5)
++#define ENABLE_MIN_ALARM (1 << 4)
++#define ENABLE_SEC_ALARM (1 << 3)
++#define ALARM_MODE_SELECT (1 << 2)
++#define RTC_LOCK (1 << 1)
++#define RTC_ENABLE (1 << 0)
++#define ENABLE_ALL_ALARM 0x0000007c
++
++
++/* RTC_ALARM_STS 0x14 */
++#define SEC_INTERRUPT_STATUS (1 << 4)
++#define DAY_ALARM_STATUS (1 << 3)
++#define HOUR_ALARM_STATUS (1 << 2)
++#define MIN_ALARM_STATUS (1 << 1)
++#define SEC_ALARM_STATUS (1 << 0)
++
++
++
++#endif /* __ASM_ARCH_REGS_RTC_H */
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-scu-g5.h b/arch/arm/plat-aspeed/include/plat/regs-scu-g5.h
+new file mode 100644
+index 0000000..0720be5
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-scu-g5.h
+@@ -0,0 +1,702 @@
++/* arch/arm/mach-aspeed/include/mach/regs-ast2300-scu.h
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * 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.
++ *
++ * History :
++ * 1. 2012/12/29 Ryan Chen Create
++ *
++********************************************************************************/
++#ifndef __AST_SCU_G5_REGS_H
++#define __AST_SCU_G5_REGS_H 1
++
++/*
++ * Register for SCU
++ * */
++#define AST_SCU_PROTECT 0x00 /* protection key register */
++#define AST_SCU_RESET 0x04 /* system reset control register */
++#define AST_SCU_CLK_SEL 0x08 /* clock selection register */
++#define AST_SCU_CLK_STOP 0x0C /* clock stop control register */
++#define AST_SCU_COUNT_CTRL 0x10 /* frequency counter control register */
++#define AST_SCU_INTR_CTRL 0x14 /* Interrupt control and status register */
++#define AST_SCU_D1_PLL 0x18 /* D1-PLL Parameter register */
++#define AST_SCU_D2_PLL 0x1C /* D2-PLL Parameter register */
++#define AST_SCU_M_PLL 0x20 /* M-PLL Parameter register */
++#define AST_SCU_H_PLL 0x24 /* H-PLL Parameter register */
++#define AST_SCU_FREQ_LIMIT 0x28 /* frequency counter comparsion register */
++#define AST_SCU_MISC1_CTRL 0x2C /* Misc. Control register */
++#define AST_SCU_PCI_CONF1 0x30 /* PCI configuration setting register#1 */
++#define AST_SCU_PCI_CONF2 0x34 /* PCI configuration setting register#2 */
++#define AST_SCU_PCI_CONF3 0x38 /* PCI configuration setting register#3 */
++#define AST_SCU_SYS_CTRL 0x3C /* System reset contrl/status register*/
++#define AST_SCU_SOC_SCRATCH0 0x40 /* SOC scratch 0~31 register */
++#define AST_SCU_SOC_SCRATCH1 0x44 /* SOC scratch 32~63 register */
++#define AST_SCU_VGA0 0x40 /* VGA fuction handshake register */
++#define AST_SCU_VGA1 0x44 /* VGA fuction handshake register */
++#define AST_SCU_MAC_CLK 0x48 /* MAC interface clock delay setting register */
++#define AST_SCU_MISC2_CTRL 0x4C /* Misc. 2 Control register */
++#define AST_SCU_VGA_SCRATCH0 0x50 /* VGA Scratch register */
++#define AST_SCU_VGA_SCRATCH1 0x54 /* VGA Scratch register */
++#define AST_SCU_VGA_SCRATCH2 0x58 /* VGA Scratch register */
++#define AST_SCU_VGA_SCRATCH3 0x5c /* VGA Scratch register */
++#define AST_SCU_VGA_SCRATCH4 0x60 /* VGA Scratch register */
++#define AST_SCU_VGA_SCRATCH5 0x64 /* VGA Scratch register */
++#define AST_SCU_VGA_SCRATCH6 0x68 /* VGA Scratch register */
++#define AST_SCU_VGA_SCRATCH7 0x6c /* VGA Scratch register */
++#define AST_SCU_HW_STRAP1 0x70 /* hardware strapping register */
++#define AST_SCU_RAMDOM_GEN 0x74 /* random number generator register */
++#if defined(CONFIG_ARCH_1100) || defined(CONFIG_ARCH_2050) || defined(CONFIG_ARCH_2100) || defined(CONFIG_ARCH_2200)
++#define AST_SCU_MULTI_FUNC_2 0x78
++#else
++#define AST_SCU_RAMDOM_DATA 0x78 /* random number generator data output*/
++#endif
++#define AST_SCU_REVISION_ID 0x7C /* Silicon revision ID register */
++#define AST_SCU_FUN_PIN_CTRL1 0x80 /* Multi-function Pin Control#1*/
++#define AST_SCU_FUN_PIN_CTRL2 0x84 /* Multi-function Pin Control#2*/
++#define AST_SCU_FUN_PIN_CTRL3 0x88 /* Multi-function Pin Control#3*/
++#define AST_SCU_FUN_PIN_CTRL4 0x8C /* Multi-function Pin Control#4*/
++#define AST_SCU_FUN_PIN_CTRL5 0x90 /* Multi-function Pin Control#5*/
++#define AST_SCU_FUN_PIN_CTRL6 0x94 /* Multi-function Pin Control#6*/
++#define AST_SCU_WDT_RESET 0x9C /* Watchdog Reset Selection */
++#define AST_SCU_FUN_PIN_CTRL7 0xA0 /* Multi-function Pin Control#7*/
++#define AST_SCU_FUN_PIN_CTRL8 0xA4 /* Multi-function Pin Control#8*/
++#define AST_SCU_FUN_PIN_CTRL9 0xA8 /* Multi-function Pin Control#9*/
++#define AST_SCU_PWR_SAVING_EN 0xC0 /* Power Saving Wakeup Enable*/
++#define AST_SCU_PWR_SAVING_CTRL 0xC4 /* Power Saving Wakeup Control*/
++#define AST_SCU_HW_STRAP2 0xD0 /* Haardware strapping register set 2*/
++#define AST_SCU_COUNTER4 0xE0 /* SCU Free Run Counter Read Back #4*/
++#define AST_SCU_COUNTER4_EXT 0xE4 /* SCU Free Run Counter Extended Read Back #4*/
++
++//CPU 2
++#define AST_SCU_CPU2_CTRL 0x100 /* CPU2 Control Register*/
++#define AST_SCU_CPU2_BASE0_ADDR 0x104 /* CPU2 Base Address for Segment 0x00:0000~0x1F:FFFF*/
++#define AST_SCU_CPU2_BASE1_ADDR 0x108 /* CPU2 Base Address for Segment 0x20:0000~0x3F:FFFF*/
++#define AST_SCU_CPU2_BASE2_ADDR 0x10C /* CPU2 Base Address for Segment 0x40:0000~0x5F:FFFF*/
++#define AST_SCU_CPU2_BASE3_ADDR 0x110 /* CPU2 Base Address for Segment 0x60:0000~0x7F:FFFF*/
++#define AST_SCU_CPU2_BASE4_ADDR 0x114 /* CPU2 Base Address for Segment 0x80:0000~0xFF:FFFF*/
++#define AST_SCU_CPU2_CACHE_CTRL 0x118 /* CPU2 Cache Function Control */
++
++//
++#define AST_SCU_UART24_REF 0x160 /* Generate UART 24Mhz Ref from H-PLL when CLKIN is 25Mhz */
++#define AST_SCU_PCIE_CONFIG_SET 0x180 /* PCI-E Configuration Setting Control Register */
++#define AST_SCU_BMC_MMIO_DEC 0x184 /* BMC MMIO Decode Setting Register */
++#define AST_SCU_DEC_AREA1 0x188 /* 1st relocated controller decode area location */
++#define AST_SCU_DEC_AREA2 0x18C /* 2nd relocated controller decode area location */
++#define AST_SCU_MBOX_DEC_AREA 0x190 /* Mailbox decode area location*/
++#define AST_SCU_SRAM_DEC_AREA0 0x194 /* Shared SRAM area decode location*/
++#define AST_SCU_SRAM_DEC_AREA1 0x198 /* Shared SRAM area decode location*/
++#define AST_SCU_BMC_CLASS 0x19C /* BMC device class code and revision ID */
++#define AST_SCU_BMC_DEV_ID 0x1A4 /* BMC device ID */
++
++
++/* AST_SCU_PROTECT: 0x00 - protection key register */
++#define SCU_PROTECT_UNLOCK 0x1688A8A8
++
++/* AST_SCU_RESET :0x04 - system reset control register */
++#define SCU_RESET_I2S (0x1 << 31)
++#define SCU_RESET_IR (0x1 << 30)
++#define SCU_RESET_PS21 (0x1 << 29)
++#define SCU_RESET_PS20 (0x1 << 28)
++#define SCU_PWAKE_PIN_EN (0x1 << 27)
++#define SCU_PWAKE_PIN_OUT (0x1 << 26
++#define SCU_RESET_X_DMA (0x1 << 25)
++#define SCU_RESET_MCTP (0x1 << 24)
++//#define SCU_RESET_ADC (0x1 << 23) reserved
++#define SCU_RESET_JTAG (0x1 << 22)
++#define SCU_RESET_PCIE_EN (0x1 << 21)
++#define SCU_RESET_PCIE_OUT (0x1 << 20)
++#define SCU_RESET_PCIE (0x1 << 19)
++#define SCU_RESET_H264 (0x1 << 18)
++#define SCU_RESET_RFX (0x1 << 17)
++#define SCU_RESET_SD (0x1 << 16)
++#define SCU_RESET_USB11 (0x1 << 15)
++#define SCU_RESET_USB20 (0x1 << 14)
++#define SCU_RESET_CRT (0x1 << 13)
++//#define SCU_RESET_MAC1 (0x1 << 12) reserved
++#define SCU_RESET_MAC0 (0x1 << 11)
++//#define SCU_RESET_PECI (0x1 << 10)
++//#define SCU_RESET_PWM (0x1 << 9)
++#define SCU_PCI_VGA_DIS (0x1 << 8)
++#define SCU_RESET_2D (0x1 << 7)
++#define SCU_RESET_VIDEO (0x1 << 6)
++//#define SCU_RESET_LPC (0x1 << 5)
++#define SCU_RESET_HAC (0x1 << 4)
++//#define SCU_RESET_USB11_HID (0x1 << 3)
++#define SCU_RESET_I2C (0x1 << 2)
++#define SCU_RESET_AHB (0x1 << 1)
++#define SCU_RESET_SRAM_CTRL (0x1 << 0)
++
++/* AST_SCU_CLK_SEL : 0x08 - clock selection register */
++#define SCU_CLK_VIDEO_SLOW_EN (0x1 << 31)
++#define SCU_CLK_VIDEO_SLOW_SET(x) ((x & 0x7) << 28)
++#define SCU_CLK_VIDEO_SLOW_MASK (0x7 << 28)
++#define SCU_CLK_2D_ENG_GCLK_INVERT (0x1 << 27) //valid only at CRT mode SCU2C[7]
++#define SCU_CLK_2D_ENG_THROT_EN (0x1 << 26) //valid only at CRT mode SCU2C[7]
++#define SCU_PCLK_APB_DIV(x) ((x & 0x7) << 23)
++#define SCU_GET_PCLK_DIV(x) ((x >> 23) & 0x7)
++#define SCU_PCLK_APB_DIV_MASK (0x7 << 23) //limitation on PCLK .. PCLK > 0.5*LCLK (33Mhz)
++//#define SCU_GET_LHCLK_DIV(x) ((x >> 20) & 0x7)
++//#define SCU_SET_LHCLK_DIV(x) (x << 20)
++//#define SCU_LHCLK_DIV_MASK (0x7 << 20)
++//#define SCU_LHCLK_SOURCE_EN (0x1 << 19) //0: ext , 1:internel
++#define SCU_SET_MAC_DIV(x) ((x & 0x7) << 16)
++#define SCU_GET_MAC_DIV(x) ((x >> 16) & 0x7)
++#define SCU_CLK_MAC_MASK (0x7 << 16)
++#define SCU_CLK_SD_EN (0x1 << 15)
++#define SCU_SET_SD_DIV(x) ((x & 0x7) << 12)
++#define SCU_GET_SD_DIV(x) ((x >> 12) & 0x7)
++#define SCU_CLK_SD_MASK (0x7 << 12)
++//
++#define SCU_CLK_VIDEO_DELAY(x) ((x & 0xf) << 8)
++#define SCU_CLK_VIDEO_DELAY_MASK (0xf << 8)
++#define SCU_CLK_CPU_AHB_SLOW_EN (0x1 << 7)
++#define SCU_CLK_CPU_AHB_SLOW(x) ((x & 0x7) << 4)
++#define SCU_CLK_CPU_AHB_SLOW_MASK (0x7 << 4)
++#define SCU_GET_CPU_AHB_DIV(x) ((x >> 4) & 0x7)
++#define SCU_ECLK_SOURCE(x) (x << 2)
++#define SCU_ECLK_SOURCE_MASK (0x3 << 2)
++#define SCU_CLK_CPU_AHB_SLOW_IDLE (0x1 << 1)
++#define SCU_CLK_CPU_AHB_DYN_SLOW_EN (0x1 << 0)
++
++/* AST_SCU_CLK_STOP : 0x0C - clock stop control register */
++//#define SCU_LHCLK_STOP_EN (0x1 << 28)
++#define SCU_SDCLK_STOP_EN (0x1 << 27)
++#define SCU_IRCLK_STOP_EN (0x1 << 26)
++#define SCU_I2SCLK_STOP_EN (0x1 << 25)
++#define SCU_RSACLK_STOP_EN (0x1 << 24)
++#define SCU_H264CLK_STOP_EN (0x1 << 23)
++//bit 22 must keep 1
++//#define SCU_MAC1CLK_STOP_EN (0x1 << 21)
++#define SCU_MAC0CLK_STOP_EN (0x1 << 20)
++#define SCU_BBCLK_STOP_EN (0x1 << 19)
++#define SCU_RFXCLK_STOP_EN (0x1 << 18)
++#define SCU_UART0_CLK_STOP_EN (0x1 << 17)
++#define SCU_UART2_CLK_STOP_EN (0x1 << 16)
++#define SCU_UART1_CLK_STOP_EN (0x1 << 15)
++#define SCU_USB20_CLK_EN (0x1 << 14)
++#define SCU_YCLK_STOP_EN (0x1 << 13)
++#define SCU_PS2CLK_STOP_EN (0x1 << 12)
++//
++#define SCU_D1CLK_STOP_EN (0x1 << 10)
++#define SCU_USB11CLK_STOP_EN (0x1 << 9)
++#define SCU_D4CLK_STOP_EN (0x1 << 8)
++#define SCU_D3CLK_STOP_EN (0x1 << 7)
++#define SCU_REFCLK_STOP_EN (0x1 << 6)
++#define SCU_D2CLK_STOP_EN (0x1 << 5)
++#define SCU_SACLK_STOP_EN (0x1 << 4)
++#define SCU_VCLK_STOP_EN (0x1 << 3)
++#define SCU_MCLK_STOP_EN (0x1 << 2)
++#define SCU_GCLK_STOP_EN (0x1 << 1)
++#define SCU_ECLK_STOP_EN (0x1 << 0)
++
++/* AST_SCU_COUNT_CTRL : 0x10 - frequency counter control register */
++#define SCU_FREQ_COMP_RESULT (0x1 << 7)
++#define SCU_FREQ_MEASU_FINISH (0x1 << 6)
++#define SCU_FREQ_SOURCE_FOR_MEASU(x) ((x & 0xf) << 2)
++#define SCU_FREQ_SOURCE_FOR_MEASU_MASK (0xf << 2)
++
++#define SCU_SOURCE_6M 0xf
++#define SCU_SOURCE_12M 0xe
++#define SCU_SOURCE_I2SM_CLK 0xd
++#define SCU_SOURCE_H_CLK 0xc
++#define SCU_SOURCE_B_CLK 0xb
++#define SCU_SOURCE_D2_PLL 0xa
++
++#define SCU_SOURCE_VIDEO_CLK 0x7
++#define SCU_SOURCE_LPC_CLK 0x6
++#define SCU_SOURCE_JITTER_CLK 0x5
++#define SCU_SOURCE_M_CLK 0x4
++#define SCU_SOURCE_XP_CLK 0x3
++#define SCU_SOURCE_D_PLL 0x2
++#define SCU_SOURCE_NAND 0x1
++#define SCU_SOURCE_DEL_CELL 0x0
++
++#define SCU_OSC_COUNT_EN (0x1 << 1)
++#define SCU_RING_OSC_EN (0x1 << 0)
++
++/* AST_SCU_INTR_CTRL : 0x14 - Interrupt control and status register */
++//#define INTR_LPC_H_L_RESET (0x1 << 21)
++//#define INTR_LPC_L_H_RESET (0x1 << 20)
++#define INTR_PCIE_H_L_RESET (0x1 << 17)
++#define INTR_PCIE_L_H_RESET (0x1 << 16)
++//#define INTR_VGA_SCRATCH_CHANGE (0x1 << 17)
++//#define INTR_VGA_CURSOR_CHANGE (0x1 << 16)
++#define INTR_MSI_EN (0x1 << 2)
++//#define INTR_LPC_H_L_RESET_EN (0x1 << 1)
++//#define INTR_LPC_L_H_RESET_EN (0x1 << 0)
++#define INTR_PCIE_H_L_RESET_EN (0x1 << 1)
++#define INTR_PCIE_L_H_RESET_EN (0x1 << 0)
++//#define INTR_VGA_SCRATCH_CHANGE_EN (0x1 << 1)
++//#define INTR_VGA_CURSOR_CHANGE_EN (0x1 << 0)
++
++
++/* AST_SCU_D1_PLL: 0x18 - D1-PLL Parameter register */
++#define SCU_D1_PLL_SET_PD2(x) ((x & 0x7) << 19)
++#define SCU_D1_PLL_GET_PD2(x) ((x >> 19) & 0x7)
++#define SCU_D1_PLL_PD2_MASK (0x7 << 19)
++#define SCU_D1_PLL_BYPASS_EN (0x1 << 18)
++#define SCU_D1_PLL_OFF (0x1 << 17)
++#define SCU_D1_PLL_SET_PD(x) ((x & 0x3) << 15)
++#define SCU_D1_PLL_GET_PD(x) ((x >> 15) & 0x3)
++#define SCU_D1_PLL_PD_MASK (0x3 << 15)
++#define SCU_D1_PLL_SET_OD(x) ((x & 0x3) << 13)
++#define SCU_D1_PLL_GET_OD(x) ((x >> 13) & 0x3)
++#define SCU_D1_PLL_OD_MASK (0x3 << 13)
++#define SCU_D1_PLL_SET_DENUM(x) ((x & 0x1f) << 8)
++#define SCU_D1_PLL_GET_DENUM(x) ((x >> 8) & 0x1f)
++#define SCU_D1_PLL_DENUM_MASK (0x1f << 8)
++#define SCU_D1_PLL_SET_NUM(x) (x & 0xff)
++#define SCU_D1_PLL_GET_NUM(x) (x & 0xff)
++#define SCU_D1_PLL_NUM_MASK (0xff)
++
++/* AST_SCU_D2_PLL: 0x1C - D2-PLL Parameter register */
++#define SCU_D2_PLL_SET_PD2(x) ((x & 0x7) << 19)
++#define SCU_D2_PLL_GET_PD2(x) ((x >> 19) & 0x7)
++#define SCU_D2_PLL_PD2_MASK (0x7 << 19)
++#define SCU_D2_PLL_BYPASS_EN (0x1 << 18)
++#define SCU_D2_PLL_OFF (0x1 << 17)
++#define SCU_D2_PLL_SET_PD(x) ((x & 0x3) << 15)
++#define SCU_D2_PLL_GET_PD(x) ((x >> 15) & 0x3)
++#define SCU_D2_PLL_PD_MASK (0x3 << 15)
++#define SCU_D2_PLL_SET_OD(x) ((x & 0x3) << 13)
++#define SCU_D2_PLL_GET_OD(x) ((x >> 13) & 0x3)
++#define SCU_D2_PLL_OD_MASK (0x3 << 13)
++#define SCU_D2_PLL_SET_DENUM(x) ((x & 0x1f) << 8)
++#define SCU_D2_PLL_GET_DENUM(x) ((x >> 8) & 0x1f)
++#define SCU_D2_PLL_DENUM_MASK (0x1f << 8)
++#define SCU_D2_PLL_SET_NUM(x) (x & 0xff)
++#define SCU_D2_PLL_GET_NUM(x) (x & 0xff)
++#define SCU_D2_PLL_NUM_MASK (0xff)
++
++/* AST_SCU_M_PLL : 0x20 - M-PLL Parameter register */
++#define SCU_M_PLL_BYPASS_EN (0x1 << 17)
++#define SCU_M_PLL_OFF (0x1 << 16)
++#define SCU_M_PLL_NUM(x) ((x & 0x3f) << 5)
++#define SCU_M_PLL_GET_NUM(x) ((x >> 5) & 0x3f)
++#define SCU_M_PLL_NUM_MASK (0x3f << 5)
++#define SCU_M_PLL_OUT_DIV (0x1 << 4)
++#define SCU_M_PLL_GET_DIV(x) ((x >> 4) & 0x1)
++#define SCU_M_PLL_SET_DENUM(x) (x & 0xf)
++#define SCU_M_PLL_GET_DENUM(x) (x & 0xf)
++
++/* AST_SCU_H_PLL: 0x24- H-PLL Parameter register */
++#define SCU_H_PLL_BYPASS_EN (0x1 << 17)
++#define SCU_H_PLL_OFF (0x1 << 16)
++#define SCU_H_PLL_SET_NUM(x) ((x & 0x3f) << 5)
++#define SCU_H_PLL_GET_NUM(x) ((x >> 5) & 0x3f)
++#define SCU_H_PLL_NUM_MASK (0x3f << 5)
++#define SCU_H_PLL_OUT_DIV (0x1 << 4)
++#define SCU_H_PLL_GET_DIV(x) ((x >> 4) & 0x1)
++#define SCU_H_PLL_SET_DENUM(x) (x & 0xf)
++#define SCU_H_PLL_GET_DENUM(x) (x & 0xf)
++#define SCU_H_PLL_DENUM_MASK (0xf)
++
++/* AST_SCU_FREQ_LIMIT : 0x28 - frequency counter comparsion register */
++#define SCU_FREQ_U_LIMIT(x) ((x & 0x3fff) << 16)
++#define SCU_FREQ_U_LIMIT_MASK (0x3fff << 16)
++#define SCU_FREQ_L_LIMIT(x) (x & 0x3fff)
++#define SCU_FREQ_L_LIMIT_MASK (0x3fff)
++
++/* AST_SCU_MISC_CTRL : 0x2C - Misc. Control register */
++#define HPLL_MPLL 0
++#define HPLL_DIV2 1
++#define SCU_MISC_24MHZ_BCLK (0x1 << 28)
++#define SCU_MISC_RFX_CLK_SEL(x) ((x & 0x1) << 27)
++#define SCU_MISC_RFX_CLK_HPLL_DIV2 (0x1 << 27)
++#define SCU_MISC_JTAG_MASTER_DIS (0x1 << 26)
++#define SCU_MISC_ST_CLK_HPLL_DIV2 (0x1 << 25)
++#define SCU_MISC_H264_CLK_HPLL_DIV2 (0x1 << 24)
++#define SCU_MISC_AX_CLK_HPLL_DIV2 (0x1 << 23)
++#define SCU_MISC_BB_CLK_HPLL_DIV2 (0x1 << 22)
++#define SCU_MISC_D4_CLK_D2_PLL (0x1 << 21)
++#define SCU_MISC_D3_CLK_D2_PLL (0x1 << 20)
++#define SCU_MISC_D2_CLK_D2_PLL (0x1 << 19)
++#define SCU_MISC_D1_CLK_D2_PLL (0x1 << 18)
++#define SCU_MISC_DAC_MASK (0x3 << 16)
++#define SCU_MISC_DAC_SOURCE_CRT (0x1 << 16) //00 VGA, 01: CRT, 1x: PASS-Through DVO
++#define SCU_MISC_DAC_SOURCE_MASK (0x3 << 16)
++#define SCU_MISC_RST_CRT1_EN (0x1 << 15)
++#define SCU_MISC_RST_CRT2_EN (0x1 << 14)
++#define SCU_MISC_RST_CRT3_EN (0x1 << 13)
++#define SCU_MISC_RST_CRT4_EN (0x1 << 12)
++#define SCU_MISC_Y_CLK_INVERT (0x1 << 11)
++
++#define SCU_MISC_OUT_DELAY (0x1 << 9)
++#define SCU_MISC_PCI_TO_AHB_DIS (0x1 << 8)
++//#define SCU_MISC_2D_CRT_EN (0x1 << 7)
++//#define SCU_MISC_VGA_CRT_DIS (0x1 << 6)
++//#define SCU_MISC_VGA_REG_ACCESS_EN (0x1 << 5)
++#define SCU_MISC_D2_PLL_DIS (0x1 << 4)
++#define SCU_MISC_DAC_DIS (0x1 << 3)
++#define SCU_MISC_D1_PLL_DIS (0x1 << 2)
++#define SCU_MISC_OSC_CLK_OUT_PIN (0x1 << 1)
++//#define SCU_MISC_LPC_TO_SPI_DIS (0x1 << 0)
++
++/* AST_SCU_PCI_CONF1 : 0x30 - PCI configuration setting register#1 */
++#define SCU_PCI_DEVICE_ID(x) (x << 16)
++#define SCU_PCI_VENDOR_ID(x) (x)
++
++/* AST_SCU_PCI_CONF2 0x34 PCI configuration setting register#2 */
++#define SCU_PCI_SUB_SYS_ID(x) (x << 16)
++#define SCU_PCI_SUB_VENDOR_ID(x) (x)
++
++/* AST_SCU_PCI_CONF3 0x38 PCI configuration setting register#3 */
++#define SCU_PCI_CLASS_CODE(x) (x << 8)
++#define SCU_PCI_REVISION_ID(x) (x)
++
++/* AST_SCU_SYS_CTRL 0x3C System reset contrl/status register*/
++#define SCU_SYS_EXT_SOC_RESET_EN (0x1 << 3)
++#define SCU_SYS_EXT_RESET_FLAG (0x1 << 2)
++#define SCU_SYS_WDT_RESET_FLAG (0x1 << 1)
++#define SCU_SYS_PWR_RESET_FLAG (0x1 << 0)
++
++/* AST_SCU_SOC_SCRATCH0 0x40 SOC scratch 0~31 register */
++
++
++
++
++/* AST_SCU_SOC_SCRATCH1 0x44 SOC scratch 32~63 register */
++
++
++/* AST_SCU_VGA0 0x40 VGA fuction handshake register */
++#define SCU_VGA_SLT_HANDSHAKE(x) (x << 24)
++#define SCU_VGA_SLT_HANDSHAKE_MASK (0xff << 24)
++#define SCU_VGA_CTM_DEF(x) (x << 16)
++#define SCU_VGA_CTM_DEF_MASK (0xff << 16)
++#define SCU_MAC0_PHY_MODE(x) (x << 14)
++#define SCU_MAC0_GET_PHY_MODE(x) ((x >> 14) & 0x3)
++#define SCU_MAC0_PHY_MODE_MASK(x) (0x3 << 14)
++#define SCU_MAC1_PHY_MODE(x) (x << 12)
++#define SCU_MAC1_PHY_MODE_MASK (0x3 << 12)
++#define SCU_MAC1_GET_PHY_MODE(x) ((x >> 12) & 0x3)
++
++#define SCU_VGA_ASPEED_DEF(x) (x << 8)
++#define SCU_VGA_ASPEED_DEF_MASK (0xf << 8)
++
++#define SCU_VGA_DRAM_INIT_MASK(x) ((x >> 7) & 0x1)
++
++/* AST_SCU_VGA1 0x44 VGA fuction handshake register */
++
++
++/* AST_SCU_MAC_CLK 0x48 MAC interface clock delay setting register */
++
++
++
++/* AST_SCU_MISC_CTRL 0x4C Misc. 2 Control register */
++/* AST_SCU_VGA_SCRATCH0 0x50 VGA Scratch register */
++/* AST_SCU_VGA_SCRATCH1 0x54 VGA Scratch register */
++/* AST_SCU_VGA_SCRATCH2 0x58 VGA Scratch register */
++/* AST_SCU_VGA_SCRATCH3 0x5c VGA Scratch register */
++/* AST_SCU_VGA_SCRATCH4 0x60 VGA Scratch register */
++/* AST_SCU_VGA_SCRATCH5 0x64 VGA Scratch register */
++/* AST_SCU_VGA_SCRATCH6 0x68 VGA Scratch register */
++/* AST_SCU_VGA_SCRATCH7 0x6c VGA Scratch register */
++
++/* AST_SCU_HW_STRAP1 0x70 hardware strapping register */
++#define SCU_HW_STRAP_SW_DEFINE(x) (x << 29)
++#define SCU_HW_STRAP_SW_DEFINE_MASK (0x3 << 29)
++#define SCU_HW_STRAP_DRAM_SIZE(x) (x << 27)
++#define SCU_HW_STRAP_DRAM_SIZE_MASK (0x3 << 27)
++
++#define VGA_64M_DRAM 0
++#define VGA_128M_DRAM 1
++#define VGA_256M_DRAM 2
++#define VGA_512M_DRAM 3
++
++#define SCU_HW_STRAP_DRAM_CONFIG(x) ((x & 0x7) << 24)
++#define SCU_HW_STRAP_DRAM_CONFIG_MASK (0x7 << 24)
++
++#define SCU_HW_STRAP_SPI_MODE(x) ((x & 0x3) << 12)
++#define SCU_HW_STRAP_SPI_MODE_MASK (0x3 << 12)
++#define SPI_MODE_DIS (0)
++#define SPI_MODE_MASTER_EN (1)
++#define SPI_MODE_M_S_EN (2)
++#define SPI_MODE_PS (3)
++
++#define SCU_HW_STRAP_SET_CPU_AHB_RATIO(x) (x << 10)
++#define SCU_HW_STRAP_GET_CPU_AHB_RATIO(x) ((x >> 10) & 3)
++#define SCU_HW_STRAP_CPU_AHB_RATIO_MASK (0x3 << 10)
++
++
++#define CPU_AHB_RATIO_1_1 0
++#define CPU_AHB_RATIO_2_1 1
++#define CPU_AHB_RATIO_4_1 2
++#define CPU_AHB_RATIO_3_1 3
++
++#define SCU_HW_STRAP_GET_H_PLL_CLK(x) ((x >> 8 )& 0x3)
++#define SCU_HW_STRAP_H_PLL_CLK_MASK (0x3 << 8)
++#define CPU_384MHZ 0
++#define CPU_360MHZ 1
++#define CPU_336MHZ 2
++#define CPU_408MHZ 3
++
++//#define SCU_HW_STRAP_MAC1_INF (0x1 << 7)
++#define SCU_HW_STRAP_MAC0_INF (0x1 << 6)
++//#define SCU_HW_STRAP_VGA_BIOS_ROM (0x1 << 5)
++#define SCU_HW_STRAP_SPI_WIDTH (0x1 << 4)
++//#define SCU_HW_STRAP_VGA_SIZE_GET(x) ((x >> 2)& 0x3)
++
++#define SCU_HW_STRAP_BOOT_MODE(x) (x)
++#define NOR_BOOT 0
++#define NAND_BOOT 1
++#define SPI_BOOT 2
++#define DIS_BOOT 3
++
++/* AST_SCU_RAMDOM_GEN 0x74 random number generator register */
++/* AST_SCU_RAMDOM_DATA 0x78 random number generator data output*/
++
++/* AST_SCU_MULTI_FUNC_2 0x78 */
++
++/* AST_SCU_REVISION_ID 0x7C Silicon revision ID register */
++#define AST1100_A0 0x00000200
++#define AST1100_A1 0x00000201
++#define AST1100_A2 0x00000202
++#define AST1100_A3 0x00000202
++
++#define AST2050_A0 0x00000200
++#define AST2050_A1 0x00000201
++#define AST2050_A2 0x00000202
++#define AST2050_A3 0x00000202
++
++#define AST2100_A0 0x00000300
++#define AST2100_A1 0x00000301
++#define AST2100_A2 0x00000302
++#define AST2100_A3 0x00000302
++
++#define AST2200_A0 0x00000102
++#define AST2200_A1 0x00000102
++
++#define AST2300_A0 0x01000003
++#define AST2300_A1 0x01010303
++#define AST1300_A1 0x01010003
++#define AST1050_A1 0x01010203
++
++#define AST2400_A0 0x02000303
++
++
++/* AST_SCU_FUN_PIN_CTRL1 0x80 Multi-function Pin Control#1*/
++#define SCU_FUN_PIN_UART4_RXD (0x1 << 31)
++#define SCU_FUN_PIN_UART4_TXD (0x1 << 30)
++#define SCU_FUN_PIN_UART4_NRTS (0x1 << 29)
++#define SCU_FUN_PIN_UART4_NDTR (0x1 << 28)
++#define SCU_FUN_PIN_UART4_NRI (0x1 << 27)
++#define SCU_FUN_PIN_UART4_NDSR (0x1 << 26)
++#define SCU_FUN_PIN_UART4_NDCD (0x1 << 25)
++#define SCU_FUN_PIN_UART4_NCTS (0x1 << 24)
++#define SCU_FUN_PIN_UART3_RXD (0x1 << 23)
++#define SCU_FUN_PIN_UART3_TXD (0x1 << 22)
++#define SCU_FUN_PIN_UART3_NRTS (0x1 << 21)
++#define SCU_FUN_PIN_UART3_NDTR (0x1 << 20)
++#define SCU_FUN_PIN_UART3_NRI (0x1 << 19)
++#define SCU_FUN_PIN_UART3_NDSR (0x1 << 18)
++#define SCU_FUN_PIN_UART3_NDCD (0x1 << 17)
++#define SCU_FUN_PIN_UART3_NCTS (0x1 << 16)
++#define SCU_FUN_PIN_SPICS1 (0x1 << 15)
++#define SCU_FUN_PIN_LPCPME (0x1 << 14)
++#define SCU_FUN_PIN_LPCPD (0x1 << 13)
++#define SCU_FUN_PIN_LPCRST (0x1 << 12)
++#define SCU_FUN_PIN_I2C_SALT4 (0x1 << 11)
++#define SCU_FUN_PIN_I2C_SALT3 (0x1 << 10)
++#define SCU_FUN_PIN_I2C_SALT2 (0x1 << 9)
++#define SCU_FUN_PIN_I2C_SALT1 (0x1 << 8)
++#define SCU_FUN_PIN_TIMER8 (0x1 << 7)
++#define SCU_FUN_PIN_TIMER7 (0x1 << 6)
++#define SCU_FUN_PIN_TIMER6 (0x1 << 5)
++#define SCU_FUN_PIN_TIMER5 (0x1 << 4)
++#define SCU_FUN_PIN_TIMER4 (0x1 << 3)
++#define SCU_FUN_PIN_TIMER3 (0x1 << 2)
++#define SCU_FUN_PIN_MAC1_PHY_LINK (0x1 << 1)
++#define SCU_FUN_PIN_MAC0_PHY_LINK (0x1)
++
++/* AST_SCU_FUN_PIN_CTRL2 0x84 Multi-function Pin Control#2*/
++#define SCU_FUN_PIN_VPIB9 (0x1 << 31)
++#define SCU_FUN_PIN_VPIB8 (0x1 << 30)
++#define SCU_FUN_PIN_VPIB7 (0x1 << 29)
++#define SCU_FUN_PIN_VPIB6 (0x1 << 28)
++#define SCU_FUN_PIN_VPIB5 (0x1 << 27)
++#define SCU_FUN_PIN_VPIB4 (0x1 << 26)
++#define SCU_FUN_PIN_VPIB3 (0x1 << 25)
++#define SCU_FUN_PIN_VPIB2 (0x1 << 24)
++#define SCU_FUN_PIN_VPIB1 (0x1 << 23)
++#define SCU_FUN_PIN_VPIB0 (0x1 << 22)
++#define SCU_FUN_PIN_VPICLK (0x1 << 21)
++#define SCU_FUN_PIN_VPIVS (0x1 << 20)
++#define SCU_FUN_PIN_VPIHS (0x1 << 19)
++#define SCU_FUN_PIN_VPIODD (0x1 << 18)
++#define SCU_FUN_PIN_VPIDE (0x1 << 17)
++
++#define SCU_FUN_PIN_UART2_RXD (0x1 << 31)
++#define SCU_FUN_PIN_UART2_TXD (0x1 << 30)
++#define SCU_FUN_PIN_UART2_NRTS (0x1 << 29)
++#define SCU_FUN_PIN_UART2_NDTR (0x1 << 28)
++#define SCU_FUN_PIN_UART2_NRI (0x1 << 27)
++#define SCU_FUN_PIN_UART2_NDSR (0x1 << 26)
++#define SCU_FUN_PIN_UART2_NDCD (0x1 << 25)
++#define SCU_FUN_PIN_UART2_NCTS (0x1 << 24)
++#define SCU_FUN_PIN_UART1_RXD (0x1 << 23)
++#define SCU_FUN_PIN_UART1_TXD (0x1 << 22)
++#define SCU_FUN_PIN_UART1_NRTS (0x1 << 21)
++#define SCU_FUN_PIN_UART1_NDTR (0x1 << 20)
++#define SCU_FUN_PIN_UART1_NRI (0x1 << 19)
++#define SCU_FUN_PIN_UART1_NDSR (0x1 << 18)
++#define SCU_FUN_PIN_UART1_NDCD (0x1 << 17)
++#define SCU_FUN_PIN_UART1_NCTS (0x1 << 16)
++
++
++#define SCU_FUN_PIN_NAND_FLWP (0x1 << 7)
++#define SCU_FUN_PIN_NAND_FLBUSY (0x1 << 6)
++
++/* AST_SCU_FUN_PIN_CTRL3 0x88 Multi-function Pin Control#3*/
++#define SCU_FUN_PIN_MAC0_MDIO (0x1 << 31)
++#define SCU_FUN_PIN_MAC0_MDC (0x1 << 30)
++#define SCU_FUN_PIN_ROMA25 (0x1 << 29)
++#define SCU_FUN_PIN_ROMA24 (0x1 << 28)
++#define SCU_FUN_PIN_ROMCS4 (0x1 << 27)
++#define SCU_FUN_PIN_ROMCS3 (0x1 << 26)
++#define SCU_FUN_PIN_ROMCS2 (0x1 << 25)
++#define SCU_FUN_PIN_ROMCS1 (0x1 << 24)
++#define SCU_FUN_PIN_ROMCS(x) (0x1 << (23+x))
++
++//Video pin
++#define SCU_FUN_PIN_VPIR9 (0x1 << 19)
++#define SCU_FUN_PIN_VPIR8 (0x1 << 18)
++#define SCU_FUN_PIN_VPIR7 (0x1 << 17)
++#define SCU_FUN_PIN_VPIR6 (0x1 << 16)
++#define SCU_FUN_PIN_VPIR5 (0x1 << 15)
++#define SCU_FUN_PIN_VPIR4 (0x1 << 14)
++#define SCU_FUN_PIN_VPIR3 (0x1 << 13)
++#define SCU_FUN_PIN_VPIR2 (0x1 << 12)
++#define SCU_FUN_PIN_VPIR1 (0x1 << 11)
++#define SCU_FUN_PIN_VPIR0 (0x1 << 10)
++#define SCU_FUN_PIN_VPIG9 (0x1 << 9)
++#define SCU_FUN_PIN_VPIG8 (0x1 << 8)
++#define SCU_FUN_PIN_VPIG7 (0x1 << 7)
++#define SCU_FUN_PIN_VPIG6 (0x1 << 6)
++#define SCU_FUN_PIN_VPIG5 (0x1 << 5)
++#define SCU_FUN_PIN_VPIG4 (0x1 << 4)
++#define SCU_FUN_PIN_VPIG3 (0x1 << 3)
++#define SCU_FUN_PIN_VPIG2 (0x1 << 2)
++#define SCU_FUN_PIN_VPIG1 (0x1 << 1)
++#define SCU_FUN_PIN_VPIG0 (0x1 << 0)
++
++//pwm pin
++#define SCU_FUN_PIN_PWM_TACHO (0)
++
++/* AST_SCU_FUN_PIN_CTRL4 0x8C Multi-function Pin Control#4*/
++#define SCU_FUN_PIN_ROMA23 (0x1 << 7)
++#define SCU_FUN_PIN_ROMA22 (0x1 << 6)
++
++#define SCU_FUN_PIN_ROMWE (0x1 << 5)
++#define SCU_FUN_PIN_ROMOE (0x1 << 4)
++#define SCU_FUN_PIN_ROMD7 (0x1 << 3)
++#define SCU_FUN_PIN_ROMD6 (0x1 << 2)
++#define SCU_FUN_PIN_ROMD5 (0x1 << 1)
++#define SCU_FUN_PIN_ROMD4 (0x1)
++
++/* AST_SCU_FUN_PIN_CTRL5 0x90 Multi-function Pin Control#5*/
++#define SCU_FUN_PIN_SPICS1 (0x1 << 31)
++#define SCU_FUN_PIN_LPC_PLUS (0x1 << 30)
++#define SCU_FUC_PIN_USB20_HOST (0x1 << 29)
++#define SCU_FUC_PIN_USB11_PORT4 (0x1 << 28)
++#define SCU_FUC_PIN_I2C14 (0x1 << 27)
++#define SCU_FUC_PIN_I2C13 (0x1 << 26)
++#define SCU_FUC_PIN_I2C12 (0x1 << 25)
++#define SCU_FUC_PIN_I2C11 (0x1 << 24)
++#define SCU_FUC_PIN_I2C10 (0x1 << 23)
++#define SCU_FUC_PIN_I2C9 (0x1 << 22)
++#define SCU_FUC_PIN_I2C8 (0x1 << 21)
++#define SCU_FUC_PIN_I2C7 (0x1 << 20)
++#define SCU_FUC_PIN_I2C6 (0x1 << 19)
++#define SCU_FUC_PIN_I2C5 (0x1 << 18)
++#define SCU_FUC_PIN_I2C4 (0x1 << 17)
++#define SCU_FUC_PIN_I2C3 (0x1 << 16)
++#define SCU_FUC_PIN_MII2_RX_DWN_DIS (0x1 << 15)
++#define SCU_FUC_PIN_MII2_TX_DWN_DIS (0x1 << 14)
++#define SCU_FUC_PIN_MII1_RX_DWN_DIS (0x1 << 13)
++#define SCU_FUC_PIN_MII1_TX_DWN_DIS (0x1 << 12)
++
++#define SCU_FUC_PIN_MII2_TX_DRIV(x) (x << 10)
++#define SCU_FUC_PIN_MII2_TX_DRIV_MASK (0x3 << 10)
++#define SCU_FUC_PIN_MII1_TX_DRIV(x) (x << 8)
++#define SCU_FUC_PIN_MII1_TX_DRIV_MASK (0x3 << 8)
++
++#define MII_NORMAL_DRIV 0x0
++#define MII_HIGH_DRIV 0x2
++
++#define SCU_FUC_PIN_UART6 (0x1 << 7)
++#define SCU_FUC_PIN_ROM_16BIT (0x1 << 6)
++#define SCU_FUC_PIN_DIGI_V_OUT(x) (x << 4)
++#define SCU_FUC_PIN_DIGI_V_OUT_MASK (0x3 << 4)
++
++#define VIDEO_DISABLE 0x0
++#define VIDEO_12BITS 0x1
++#define VIDEO_24BITS 0x2
++//#define VIDEO_DISABLE 0x3
++
++#define SCU_FUC_PIN_USB11_PORT2 (0x1 << 3)
++#define SCU_FUC_PIN_MAC1_MDIO (0x1 << 2)
++#define SCU_FUC_PIN_SD2 (0x1 << 1)
++#define SCU_FUC_PIN_SD1 (0x1 << 0)
++
++
++/* AST_SCU_FUN_PIN_CTRL6 0x94 Multi-function Pin Control#6*/
++#define SCU_VIDEO_OUT_MASK (~0x3)
++
++/* AST_SCU_WDT_RESET 0x9C Watchdog Reset Selection */
++/* AST_SCU_FUN_PIN_CTRL7 0xA0 Multi-function Pin Control#7*/
++/* AST_SCU_FUN_PIN_CTRL8 0xA4 Multi-function Pin Control#8*/
++#define SCU_FUN_PIN_ROMA17 (0x1 << 31)
++#define SCU_FUN_PIN_ROMA16 (0x1 << 30)
++#define SCU_FUN_PIN_ROMA15 (0x1 << 29)
++#define SCU_FUN_PIN_ROMA14 (0x1 << 28)
++#define SCU_FUN_PIN_ROMA13 (0x1 << 27)
++#define SCU_FUN_PIN_ROMA12 (0x1 << 26)
++#define SCU_FUN_PIN_ROMA11 (0x1 << 25)
++#define SCU_FUN_PIN_ROMA10 (0x1 << 24)
++#define SCU_FUN_PIN_ROMA9 (0x1 << 23)
++#define SCU_FUN_PIN_ROMA8 (0x1 << 22)
++#define SCU_FUN_PIN_ROMA7 (0x1 << 21)
++#define SCU_FUN_PIN_ROMA6 (0x1 << 20)
++#define SCU_FUN_PIN_ROMA5 (0x1 << 19)
++#define SCU_FUN_PIN_ROMA4 (0x1 << 18)
++#define SCU_FUN_PIN_ROMA3 (0x1 << 17)
++#define SCU_FUN_PIN_ROMA2 (0x1 << 16)
++
++/* AST_SCU_FUN_PIN_CTRL9 0xA8 Multi-function Pin Control#9*/
++#define SCU_FUN_PIN_ROMA21 (0x1 << 3)
++#define SCU_FUN_PIN_ROMA20 (0x1 << 2)
++#define SCU_FUN_PIN_ROMA19 (0x1 << 1)
++#define SCU_FUN_PIN_ROMA18 (0x1)
++
++/* AST_SCU_PWR_SAVING_EN 0xC0 Power Saving Wakeup Enable*/
++/* AST_SCU_PWR_SAVING_CTRL 0xC4 Power Saving Wakeup Control*/
++/* AST_SCU_HW_STRAP2 0xD0 Haardware strapping register set 2*/
++/* AST_SCU_COUNTER4 0xE0 SCU Free Run Counter Read Back #4*/
++/* AST_SCU_COUNTER4_EXT 0xE4 SCU Free Run Counter Extended Read Back #4*/
++
++//CPU 2
++/* AST_SCU_CPU2_CTRL 0x100 CPU2 Control Register*/
++/* AST_SCU_CPU2_BASE0_ADDR 0x104 CPU2 Base Address for Segment 0x00:0000~0x1F:FFFF*/
++/* AST_SCU_CPU2_BASE1_ADDR 0x108 CPU2 Base Address for Segment 0x20:0000~0x3F:FFFF*/
++/* AST_SCU_CPU2_BASE2_ADDR 0x10C CPU2 Base Address for Segment 0x40:0000~0x5F:FFFF*/
++/* AST_SCU_CPU2_BASE3_ADDR 0x110 CPU2 Base Address for Segment 0x60:0000~0x7F:FFFF*/
++/* AST_SCU_CPU2_BASE4_ADDR 0x114 CPU2 Base Address for Segment 0x80:0000~0xFF:FFFF*/
++/* AST_SCU_CPU2_CACHE_CTRL 0x118 CPU2 Cache Function Control */
++
++//
++/* AST_SCU_UART24_REF 0x160 Generate UART 24Mhz Ref from H-PLL when CLKIN is 25Mhz */
++/* AST_SCU_PCIE_CONFIG_SET 0x180 PCI-E Configuration Setting Control Register */
++/* AST_SCU_BMC_MMIO_DEC 0x184 BMC MMIO Decode Setting Register */
++/* AST_SCU_DEC_AREA1 0x188 1st relocated controller decode area location */
++/* AST_SCU_DEC_AREA2 0x18C 2nd relocated controller decode area location */
++/* AST_SCU_MBOX_DEC_AREA 0x190 Mailbox decode area location*/
++/* AST_SCU_SRAM_DEC_AREA0 0x194 Shared SRAM area decode location*/
++/* AST_SCU_SRAM_DEC_AREA1 0x198 Shared SRAM area decode location*/
++/* AST_SCU_BMC_CLASS 0x19C BMC device class code and revision ID */
++/* AST_SCU_BMC_DEV_ID 0x1A4 BMC device ID */
++
++#endif /* __AST_SCU_G5_REGS_H */
++
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-scu.h b/arch/arm/plat-aspeed/include/plat/regs-scu.h
+new file mode 100644
+index 0000000..0abdcbd
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-scu.h
+@@ -0,0 +1,740 @@
++/* arch/arm/mach-aspeed/include/mach/regs-ast2300-scu.h
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * 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.
++ *
++ * History :
++ * 1. 2012/12/29 Ryan Chen Create
++ *
++********************************************************************************/
++#ifndef __AST_SCU_H
++#define __AST_SCU_H 1
++
++/*
++ * Register for SCU
++ * */
++#define AST_SCU_PROTECT 0x00 /* protection key register */
++#define AST_SCU_RESET 0x04 /* system reset control register */
++#define AST_SCU_CLK_SEL 0x08 /* clock selection register */
++#define AST_SCU_CLK_STOP 0x0C /* clock stop control register */
++#define AST_SCU_COUNT_CTRL 0x10 /* frequency counter control register */
++#define AST_SCU_COUNT_VAL 0x14 /* frequency counter measure register */
++#define AST_SCU_INTR_CTRL 0x18 /* Interrupt control and status register */
++#define AST_SCU_D2_PLL 0x1C /* D2-PLL Parameter register */
++#define AST_SCU_M_PLL 0x20 /* M-PLL Parameter register */
++#define AST_SCU_H_PLL 0x24 /* H-PLL Parameter register */
++#define AST_SCU_FREQ_LIMIT 0x28 /* frequency counter comparsion register */
++#define AST_SCU_MISC1_CTRL 0x2C /* Misc. Control register */
++#define AST_SCU_PCI_CONF1 0x30 /* PCI configuration setting register#1 */
++#define AST_SCU_PCI_CONF2 0x34 /* PCI configuration setting register#2 */
++#define AST_SCU_PCI_CONF3 0x38 /* PCI configuration setting register#3 */
++#define AST_SCU_SYS_CTRL 0x3C /* System reset contrl/status register*/
++#define AST_SCU_SOC_SCRATCH0 0x40 /* SOC scratch 0~31 register */
++#define AST_SCU_SOC_SCRATCH1 0x44 /* SOC scratch 32~63 register */
++#define AST_SCU_VGA0 0x40 /* VGA fuction handshake register */
++#define AST_SCU_VGA1 0x44 /* VGA fuction handshake register */
++#define AST_SCU_MAC_CLK 0x48 /* MAC interface clock delay setting register */
++#define AST_SCU_MISC2_CTRL 0x4C /* Misc. 2 Control register */
++#define AST_SCU_VGA_SCRATCH0 0x50 /* VGA Scratch register */
++#define AST_SCU_VGA_SCRATCH1 0x54 /* VGA Scratch register */
++#define AST_SCU_VGA_SCRATCH2 0x58 /* VGA Scratch register */
++#define AST_SCU_VGA_SCRATCH3 0x5c /* VGA Scratch register */
++#define AST_SCU_VGA_SCRATCH4 0x60 /* VGA Scratch register */
++#define AST_SCU_VGA_SCRATCH5 0x64 /* VGA Scratch register */
++#define AST_SCU_VGA_SCRATCH6 0x68 /* VGA Scratch register */
++#define AST_SCU_VGA_SCRATCH7 0x6c /* VGA Scratch register */
++#define AST_SCU_HW_STRAP1 0x70 /* hardware strapping register */
++#define AST_SCU_RAMDOM_GEN 0x74 /* random number generator register */
++#if defined(CONFIG_ARCH_1100) || defined(CONFIG_ARCH_2050) || defined(CONFIG_ARCH_2100) || defined(CONFIG_ARCH_2200)
++#define AST_SCU_MULTI_FUNC_2 0x78
++#else
++#define AST_SCU_RAMDOM_DATA 0x78 /* random number generator data output*/
++#endif
++#define AST_SCU_REVISION_ID 0x7C /* Silicon revision ID register */
++#define AST_SCU_FUN_PIN_CTRL1 0x80 /* Multi-function Pin Control#1*/
++#define AST_SCU_FUN_PIN_CTRL2 0x84 /* Multi-function Pin Control#2*/
++#define AST_SCU_FUN_PIN_CTRL3 0x88 /* Multi-function Pin Control#3*/
++#define AST_SCU_FUN_PIN_CTRL4 0x8C /* Multi-function Pin Control#4*/
++#define AST_SCU_FUN_PIN_CTRL5 0x90 /* Multi-function Pin Control#5*/
++#define AST_SCU_FUN_PIN_CTRL6 0x94 /* Multi-function Pin Control#6*/
++#define AST_SCU_WDT_RESET 0x9C /* Watchdog Reset Selection */
++#define AST_SCU_FUN_PIN_CTRL7 0xA0 /* Multi-function Pin Control#7*/
++#define AST_SCU_FUN_PIN_CTRL8 0xA4 /* Multi-function Pin Control#8*/
++#define AST_SCU_FUN_PIN_CTRL9 0xA8 /* Multi-function Pin Control#9*/
++#define AST_SCU_PWR_SAVING_EN 0xC0 /* Power Saving Wakeup Enable*/
++#define AST_SCU_PWR_SAVING_CTRL 0xC4 /* Power Saving Wakeup Control*/
++#define AST_SCU_HW_STRAP2 0xD0 /* Haardware strapping register set 2*/
++#define AST_SCU_COUNTER4 0xE0 /* SCU Free Run Counter Read Back #4*/
++#define AST_SCU_COUNTER4_EXT 0xE4 /* SCU Free Run Counter Extended Read Back #4*/
++
++//CPU 2
++#define AST_SCU_CPU2_CTRL 0x100 /* CPU2 Control Register*/
++#define AST_SCU_CPU2_BASE0_ADDR 0x104 /* CPU2 Base Address for Segment 0x00:0000~0x1F:FFFF*/
++#define AST_SCU_CPU2_BASE1_ADDR 0x108 /* CPU2 Base Address for Segment 0x20:0000~0x3F:FFFF*/
++#define AST_SCU_CPU2_BASE2_ADDR 0x10C /* CPU2 Base Address for Segment 0x40:0000~0x5F:FFFF*/
++#define AST_SCU_CPU2_BASE3_ADDR 0x110 /* CPU2 Base Address for Segment 0x60:0000~0x7F:FFFF*/
++#define AST_SCU_CPU2_BASE4_ADDR 0x114 /* CPU2 Base Address for Segment 0x80:0000~0xFF:FFFF*/
++#define AST_SCU_CPU2_CACHE_CTRL 0x118 /* CPU2 Cache Function Control */
++
++//
++#define AST_SCU_UART24_REF 0x160 /* Generate UART 24Mhz Ref from H-PLL when CLKIN is 25Mhz */
++#define AST_SCU_PCIE_CONFIG_SET 0x180 /* PCI-E Configuration Setting Control Register */
++#define AST_SCU_BMC_MMIO_DEC 0x184 /* BMC MMIO Decode Setting Register */
++#define AST_SCU_DEC_AREA1 0x188 /* 1st relocated controller decode area location */
++#define AST_SCU_DEC_AREA2 0x18C /* 2nd relocated controller decode area location */
++#define AST_SCU_MBOX_DEC_AREA 0x190 /* Mailbox decode area location*/
++#define AST_SCU_SRAM_DEC_AREA0 0x194 /* Shared SRAM area decode location*/
++#define AST_SCU_SRAM_DEC_AREA1 0x198 /* Shared SRAM area decode location*/
++#define AST_SCU_BMC_CLASS 0x19C /* BMC device class code and revision ID */
++#define AST_SCU_BMC_DEV_ID 0x1A4 /* BMC device ID */
++
++
++/* AST_SCU_PROTECT: 0x00 - protection key register */
++#define SCU_PROTECT_UNLOCK 0x1688A8A8
++
++/* AST_SCU_RESET :0x04 - system reset control register */
++#if defined (CONFIG_ARCH_AST1010)
++#define SCU_RESET_ADC (0x1 << 6)
++#define SCU_RESET_JTAG (0x1 << 5)
++#define SCU_RESET_MAC0 (0x1 << 4)
++#define SCU_RESET_PECI (0x1 << 3)
++#define SCU_RESET_PWM (0x1 << 2)
++#define SCU_RESET_LPC (0x1 << 1)
++#define SCU_RESET_I2C (0x1)
++#else
++#define SCU_RESET_X_DMA (0x1 << 25)
++#define SCU_RESET_MCTP (0x1 << 24)
++#define SCU_RESET_ADC (0x1 << 23)
++#define SCU_RESET_JTAG (0x1 << 22)
++#define SCU_PWAKE_PIN_EN (0x1 << 20)
++#define SCU_PWAKE_PIN_OUT (0x1 << 19)
++#define SCU_RESET_MIC (0x1 << 18)
++#define SCU_RESET_RESV (0x1 << 17) //must keep 1
++#define SCU_RESET_SD (0x1 << 16)
++#define SCU_RESET_USB11 (0x1 << 15)
++#define SCU_RESET_USB20 (0x1 << 14)
++#define SCU_RESET_CRT (0x1 << 13)
++#define SCU_RESET_MAC1 (0x1 << 12)
++#define SCU_RESET_MAC0 (0x1 << 11)
++#define SCU_RESET_PECI (0x1 << 10)
++#define SCU_RESET_PWM (0x1 << 9)
++#define SCU_PCI_VGA_DIS (0x1 << 8)
++#define SCU_RESET_2D (0x1 << 7)
++#define SCU_RESET_VIDEO (0x1 << 6)
++#define SCU_RESET_LPC (0x1 << 5)
++#define SCU_RESET_HAC (0x1 << 4)
++#define SCU_RESET_USB11_HID (0x1 << 3)
++#define SCU_RESET_I2C (0x1 << 2)
++#define SCU_RESET_AHB (0x1 << 1)
++#define SCU_RESET_SRAM_CTRL (0x1 << 0)
++#endif
++
++/* AST_SCU_CLK_SEL : 0x08 - clock selection register */
++#if defined(CONFIG_ARCH_AST1010)
++#define SCU_CLK_MAC_DIV(x) (x << 12)
++#define SCU_CLK_MAC_MASK (0x3 << 12)
++#define SCU_LHCLK_SOURCE_EN (0x1 << 11) //0: ext , 1:internel
++#define SCU_LHCLK_LPC_DIV(x) (x << 8)
++#define SCU_LHCLK_LPC_MASK (0x7 << 8)
++#define SCU_PCLK_APB_DIV(x) (x << 5)
++#define SCU_GET_PCLK_DIV(x) ((x >> 5) & 0x7)
++#define SCU_PCLK_APB_DIV_MASK (0x7 << 5) //limitation on PCLK .. PCLK > 0.5*LCLK (33Mhz)
++#define SCU_CLK_CPU_AHB_SLOW_EN (0x1 << 4)
++#define SCU_CLK_CPU_AHB_SLOW(x) (x << 3)
++#define SCU_CLK_CPU_AHB_SLOW_MASK (0x3 << 3)
++#define SCU_GET_AHB_DIV(x) ((x >> 3) & 0x3)
++#define SCU_CLK_CPU_AHB_SLOW_IDLE (0x1 << 1)
++#define SCU_CLK_CPU_AHB_DYN_SLOW_EN (0x1)
++#else
++#define SCU_CLK_VIDEO_SLOW_EN (0x1 << 31)
++#define SCU_CLK_VIDEO_SLOW_SET(x) (x << 28)
++#define SCU_CLK_VIDEO_SLOW_MASK (0x7 << 28)
++#define SCU_CLK_2D_ENG_GCLK_INVERT (0x1 << 27) //valid only at CRT mode SCU2C[7]
++#define SCU_CLK_2D_ENG_THROT_EN (0x1 << 26) //valid only at CRT mode SCU2C[7]
++#define SCU_PCLK_APB_DIV(x) (x << 23)
++#define SCU_GET_PCLK_DIV(x) ((x >> 23) & 0x7)
++#define SCU_PCLK_APB_DIV_MASK (0x7 << 23) //limitation on PCLK .. PCLK > 0.5*LCLK (33Mhz)
++#define SCU_GET_LHCLK_DIV(x) ((x >> 20) & 0x7)
++#define SCU_SET_LHCLK_DIV(x) (x << 20)
++#define SCU_LHCLK_DIV_MASK (0x7 << 20)
++#define SCU_LHCLK_SOURCE_EN (0x1 << 19) //0: ext , 1:internel
++#define SCU_CLK_MAC_DIV(x) (x << 16)
++#define SCU_CLK_MAC_MASK (0x7 << 16)
++#define SCU_CLK_SD_EN (0x1 << 15)
++#define SCU_CLK_SD_DIV(x) (x << 12)
++#define SCU_CLK_SD_GET_DIV(x) ((x >> 12) & 0x7)
++#define SCU_CLK_SD_MASK (0x7 << 12)
++#define SCU_CLK_VIDEO_DELAY(x) (x << 8)
++#define SCU_CLK_VIDEO_DELAY_MASK (0xf << 8)
++#define SCU_CLK_CPU_AHB_SLOW_EN (0x1 << 7)
++#define SCU_CLK_CPU_AHB_SLOW(x) (x << 4)
++#define SCU_CLK_CPU_AHB_SLOW_MASK (0x7 << 4)
++#define SCU_GET_AHB_DIV(x) ((x >> 4) & 0x7)
++#define SCU_ECLK_SOURCE(x) (x << 2)
++#define SCU_ECLK_SOURCE_MASK (0x3 << 2)
++#define SCU_CLK_CPU_AHB_SLOW_IDLE (0x1 << 1)
++#define SCU_CLK_CPU_AHB_DYN_SLOW_EN (0x1 << 0)
++
++#endif
++
++/* AST_SCU_CLK_STOP : 0x0C - clock stop control register */
++#if defined(CONFIG_ARCH_AST1010)
++#define SCU_LHCLK_STOP_EN (0x1 << 7)
++#define SCU_MAC0CLK_STOP_EN (0x1 << 6)
++#define SCU_UART3_CLK_STOP_EN (0x1 << 5)
++#define SCU_UART2_CLK_STOP_EN (0x1 << 4)
++#define SCU_UART1_CLK_STOP_EN (0x1 << 3)
++#define SCU_LCLK_STOP_EN (0x1 << 2)
++#define SCU_REFCLK_STOP_EN (0x1 << 1)
++#define SCU_MCLK_STOP_EN (0x1)
++#else
++#define SCU_LHCLK_STOP_EN (0x1 << 28)
++#define SCU_SDCLK_STOP_EN (0x1 << 27)
++#define SCU_UART4CLK_STOP_EN (0x1 << 26)
++#define SCU_UART3CLK_STOP_EN (0x1 << 25)
++#define SCU_RSACLK_STOP_EN (0x1 << 24)
++//bit 22~23 must keep 1
++#define SCU_MAC1CLK_STOP_EN (0x1 << 21)
++#define SCU_MAC0CLK_STOP_EN (0x1 << 20)
++//bit 18~19 must keep 1
++#define SCU_UART5_CLK_STOP_EN (0x1 << 17)
++#define SCU_UART2_CLK_STOP_EN (0x1 << 16)
++#define SCU_UART1_CLK_STOP_EN (0x1 << 15)
++#define SCU_USB20_CLK_EN (0x1 << 14)
++#define SCU_YCLK_STOP_EN (0x1 << 13)
++#define SCU_D2CLK_STOP_EN (0x1 << 10)
++#define SCU_USB11CLK_STOP_EN (0x1 << 9)
++#define SCU_LCLK_STOP_EN (0x1 << 8)
++#define SCU_UCLK_STOP_EN (0x1 << 7)
++#define SCU_REFCLK_STOP_EN (0x1 << 6)
++#define SCU_DCLK_STOP_EN (0x1 << 5)
++#define SCU_SACLK_STOP_EN (0x1 << 4)
++#define SCU_VCLK_STOP_EN (0x1 << 3)
++#define SCU_MCLK_STOP_EN (0x1 << 2)
++#define SCU_GCLK_STOP_EN (0x1 << 1)
++#define SCU_ECLK_STOP_EN (0x1 << 0)
++#endif
++
++/* AST_SCU_COUNT_CTRL : 0x10 - frequency counter control register */
++#define SCU_FREQ_COMP_RESULT (0x1 << 7)
++#define SCU_FREQ_MEASU_FINISH (0x1 << 6)
++#define SCU_FREQ_SOURCE_FOR_MEASU(x) (x << 2)
++#define SCU_FREQ_SOURCE_FOR_MEASU_MASK (0xf << 2)
++
++#define SCU_SOURCE_6M 0xf
++#define SCU_SOURCE_12M 0xe
++#define SCU_SOURCE_I2SM_CLK 0xd
++#define SCU_SOURCE_H_CLK 0xc
++#define SCU_SOURCE_B_CLK 0xb
++#define SCU_SOURCE_D2_PLL 0xa
++
++#define SCU_SOURCE_VIDEO_CLK 0x7
++#define SCU_SOURCE_LPC_CLK 0x6
++#define SCU_SOURCE_I2S_CLK 0x5
++#define SCU_SOURCE_M_CLK 0x4
++#define SCU_SOURCE_SALI_CLK 0x3
++#define SCU_SOURCE_D_PLL 0x2
++#define SCU_SOURCE_NAND 0x1
++#define SCU_SOURCE_DEL_CELL 0x0
++
++#define SCU_OSC_COUNT_EN (0x1 << 1)
++#define SCU_RING_OSC_EN (0x1 << 0)
++
++
++/* AST_SCU_INTR_CTRL : 0x18 - Interrupt control and status register */
++#define INTR_LPC_H_L_RESET (0x1 << 21)
++#define INTR_LPC_L_H_RESET (0x1 << 20)
++#define INTR_PCIE_H_L_RESET (0x1 << 19)
++#define INTR_PCIE_L_H_RESET (0x1 << 18)
++#define INTR_VGA_SCRATCH_CHANGE (0x1 << 17)
++#define INTR_VGA_CURSOR_CHANGE (0x1 << 16)
++#define INTR_MSI_EN (0x1 << 6)
++#define INTR_LPC_H_L_RESET_EN (0x1 << 5)
++#define INTR_LPC_L_H_RESET_EN (0x1 << 4)
++#define INTR_PCIE_H_L_RESET_EN (0x1 << 3)
++#define INTR_PCIE_L_H_RESET_EN (0x1 << 2)
++#define INTR_VGA_SCRATCH_CHANGE_EN (0x1 << 1)
++#define INTR_VGA_CURSOR_CHANGE_EN (0x1 << 0)
++
++/* AST_SCU_D2_PLL: 0x1C - D2-PLL Parameter register */
++#define SCU_D2_PLL_SET_PD2(x) (x << 19)
++#define SCU_D2_PLL_GET_PD2(x) ((x >> 19)&0x7)
++#define SCU_D2_PLL_PD2_MASK (0x7 << 19)
++#define SCU_D2_PLL_BYPASS_EN (0x1 << 18)
++#define SCU_D2_PLL_OFF (0x1 << 17)
++#define SCU_D2_PLL_SET_PD(x) (x << 15)
++#define SCU_D2_PLL_GET_PD(x) ((x >> 15) &0x3)
++#define SCU_D2_PLL_PD_MASK (0x3 << 15)
++#define SCU_D2_PLL_SET_OD(x) (x << 13)
++#define SCU_D2_PLL_GET_OD(x) ((x >> 13) & 0x3)
++#define SCU_D2_PLL_OD_MASK (0x3 << 13)
++#define SCU_D2_PLL_SET_DENUM(x) (x << 8)
++#define SCU_D2_PLL_GET_DENUM(x) ((x >>8)&0x1f)
++#define SCU_D2_PLL_DENUM_MASK (0x1f << 8)
++#define SCU_D2_PLL_SET_NUM(x) (x)
++#define SCU_D2_PLL_GET_NUM(x) (x & 0xff)
++#define SCU_D2_PLL_NUM_MASK (0xff)
++
++
++/* AST_SCU_M_PLL : 0x20 - M-PLL Parameter register */
++#define SCU_M_PLL_BYPASS_EN (0x1 << 17)
++#define SCU_M_PLL_OFF (0x1 << 16)
++#define SCU_M_PLL_NUM(x) (x << 5)
++#define SCU_M_PLL_GET_NUM(x) ((x >> 5) & 0x3f)
++#define SCU_M_PLL_NUM_MASK (0x3f << 5)
++#define SCU_M_PLL_OUT_DIV (0x1 << 4)
++#define SCU_M_PLL_GET_DIV(x) ((x >> 4) & 0x1)
++#define SCU_M_PLL_DENUM(x) (x)
++#define SCU_M_PLL_GET_DENUM(x) (x & 0xf)
++
++
++/* AST_SCU_H_PLL: 0x24- H-PLL Parameter register */
++#if defined(CONFIG_ARCH_AST1010)
++#define SCU_H_PLL_MASK_EN (0x1 << 10)
++#define SCU_H_PLL_REST_EN (0x1 << 9)
++#define SCU_H_PLL_OUT_DIV(x) (x << 7)
++#define SCU_H_PLL_GET_DIV(x) ((x >> 7) & 0x3)
++#define SCU_H_PLL_GET_DENUM(x) ((x >> 6) & 0x1)
++#define SCU_H_PLL_NUM(x) (x)
++#define SCU_H_PLL_GET_NUM(x) (x & 0x3f)
++#define SCU_H_PLL_NUM_MASK (0x3f)
++
++#else
++#define SCU_H_PLL_PARAMETER (0x1 << 18)
++#define SCU_H_PLL_BYPASS_EN (0x1 << 17)
++#define SCU_H_PLL_OFF (0x1 << 16)
++#define SCU_H_PLL_NUM(x) (x << 5)
++#define SCU_H_PLL_GET_NUM(x) ((x >> 5) & 0x3f)
++#define SCU_H_PLL_NUM_MASK (0x3f << 5)
++#define SCU_H_PLL_OUT_DIV (0x1 << 4)
++#define SCU_H_PLL_GET_DIV(x) ((x >> 4) & 0x1)
++#define SCU_H_PLL_DENUM(x) (x)
++#define SCU_H_PLL_GET_DENUM(x) (x & 0xf)
++#define SCU_H_PLL_DENUM_MASK (0xf)
++#endif
++
++/* AST_SCU_FREQ_LIMIT : 0x28 - frequency counter comparsion register */
++#define SCU_FREQ_U_LIMIT(x) (x << 16)
++#define SCU_FREQ_U_LIMIT_MASK (0x3fff << 16)
++#define SCU_FREQ_L_LIMIT(x) (x)
++#define SCU_FREQ_L_LIMIT_MASK (0x3fff)
++
++
++/* AST_SCU_MISC_CTRL : 0x2C - Misc. Control register */
++#define SCU_MISC_JTAG_MASTER_DIS (0x1 << 26)
++#define SCU_MISC_DRAM_W_P2A_DIS (0x1 << 25)
++#define SCU_MISC_SPI_W_P2A_DIS (0x1 << 24)
++#define SCU_MISC_SOC_W_P2A_DIS (0x1 << 23)
++#define SCU_MISC_FLASH_W_P2A_DIS (0x1 << 22)
++#define SCU_MISC_D_PLL_ASSIGN(x) (x << 20)
++#define SCU_MISC_D_PLL_ASSIGN_MASK (0x3 << 20)
++#define SCU_MISC_VGA_CONFIG_PREFETCH (0x1 << 19)
++#define SCU_MISC_DVO_SOURCE_CRT (0x1 << 18) //0:VGA , 1:CRT
++#define SCU_MISC_DAC_MASK (0x3 << 16)
++#define SCU_MISC_DAC_SOURCE_CRT (0x1 << 16) //00 VGA, 01: CRT, 1x: PASS-Through DVO
++#define SCU_MISC_DAC_SOURCE_MASK (0x3 << 16)
++#define SCU_MISC_JTAG_TO_PCIE_EN (0x1 << 15)
++#define SCU_MISC_JTAG__M_TO_PCIE_EN (0x1 << 14)
++#define SCU_MISC_VUART_TO_CTRL (0x1 << 13)
++#define SCU_MISC_DIV13_EN (0x1 << 12)
++#define SCU_MISC_Y_CLK_INVERT (0x1 << 11)
++#define SCU_MISC_OUT_DELAY (0x1 << 9)
++#define SCU_MISC_PCI_TO_AHB_DIS (0x1 << 8)
++#define SCU_MISC_2D_CRT_EN (0x1 << 7)
++#define SCU_MISC_VGA_CRT_DIS (0x1 << 6)
++#define SCU_MISC_VGA_REG_ACCESS_EN (0x1 << 5)
++#define SCU_MISC_D2_PLL_DIS (0x1 << 4)
++#define SCU_MISC_DAC_DIS (0x1 << 3)
++#define SCU_MISC_D_PLL_DIS (0x1 << 2)
++#define SCU_MISC_OSC_CLK_OUT_PIN (0x1 << 1)
++#define SCU_MISC_LPC_TO_SPI_DIS (0x1 << 0)
++
++/* AST_SCU_PCI_CONF1 : 0x30 - PCI configuration setting register#1 */
++#define SCU_PCI_DEVICE_ID(x) (x << 16)
++#define SCU_PCI_VENDOR_ID(x) (x)
++
++/* AST_SCU_PCI_CONF2 0x34 PCI configuration setting register#2 */
++#define SCU_PCI_SUB_SYS_ID(x) (x << 16)
++#define SCU_PCI_SUB_VENDOR_ID(x) (x)
++
++/* AST_SCU_PCI_CONF3 0x38 PCI configuration setting register#3 */
++#define SCU_PCI_CLASS_CODE(x) (x << 8)
++#define SCU_PCI_REVISION_ID(x) (x)
++
++/* AST_SCU_SYS_CTRL 0x3C System reset contrl/status register*/
++#define SCU_SYS_EXT_SOC_RESET_EN (0x1 << 3)
++#define SCU_SYS_EXT_RESET_FLAG (0x1 << 2)
++#define SCU_SYS_WDT_RESET_FLAG (0x1 << 1)
++#define SCU_SYS_PWR_RESET_FLAG (0x1 << 0)
++
++/* AST_SCU_SOC_SCRATCH0 0x40 SOC scratch 0~31 register */
++
++
++
++
++/* AST_SCU_SOC_SCRATCH1 0x44 SOC scratch 32~63 register */
++
++
++/* AST_SCU_VGA0 0x40 VGA fuction handshake register */
++#define SCU_VGA_SLT_HANDSHAKE(x) (x << 24)
++#define SCU_VGA_SLT_HANDSHAKE_MASK (0xff << 24)
++#define SCU_VGA_CTM_DEF(x) (x << 16)
++#define SCU_VGA_CTM_DEF_MASK (0xff << 16)
++#define SCU_MAC0_PHY_MODE(x) (x << 14)
++#define SCU_MAC0_GET_PHY_MODE(x) ((x >> 14) & 0x3)
++#define SCU_MAC0_PHY_MODE_MASK(x) (0x3 << 14)
++#define SCU_MAC1_PHY_MODE(x) (x << 12)
++#define SCU_MAC1_PHY_MODE_MASK (0x3 << 12)
++#define SCU_MAC1_GET_PHY_MODE(x) ((x >> 12) & 0x3)
++
++#define SCU_VGA_ASPEED_DEF(x) (x << 8)
++#define SCU_VGA_ASPEED_DEF_MASK (0xf << 8)
++
++#define SCU_VGA_DRAM_INIT_MASK(x) ((x >> 7) & 0x1)
++
++/* AST_SCU_VGA1 0x44 VGA fuction handshake register */
++
++
++/* AST_SCU_MAC_CLK 0x48 MAC interface clock delay setting register */
++
++
++
++/* AST_SCU_MISC_CTRL 0x4C Misc. 2 Control register */
++/* AST_SCU_VGA_SCRATCH0 0x50 VGA Scratch register */
++/* AST_SCU_VGA_SCRATCH1 0x54 VGA Scratch register */
++/* AST_SCU_VGA_SCRATCH2 0x58 VGA Scratch register */
++/* AST_SCU_VGA_SCRATCH3 0x5c VGA Scratch register */
++/* AST_SCU_VGA_SCRATCH4 0x60 VGA Scratch register */
++/* AST_SCU_VGA_SCRATCH5 0x64 VGA Scratch register */
++/* AST_SCU_VGA_SCRATCH6 0x68 VGA Scratch register */
++/* AST_SCU_VGA_SCRATCH7 0x6c VGA Scratch register */
++
++/* AST_SCU_HW_STRAP1 0x70 hardware strapping register */
++#define SCU_HW_STRAP_SW_DEFINE(x) (x << 29)
++#define SCU_HW_STRAP_SW_DEFINE_MASK (0x3 << 29)
++#define SCU_HW_STRAP_DRAM_SIZE (x << 29)
++#define SCU_HW_STRAP_DRAM_SIZE_MASK (0x3 << 29)
++
++#define VGA_64M_DRAM 0
++#define VGA_128M_DRAM 1
++#define VGA_256M_DRAM 2
++#define VGA_512M_DRAM 3
++
++#define SCU_HW_STRAP_DRAM_CONFIG (x << 24)
++#define SCU_HW_STRAP_DRAM_CONFIG_MASK (0x7 << 24)
++
++#define SCU_HW_STRAP_GPIOE_PT_EN (0x1 << 22)
++#define SCU_HW_STRAP_GPIOD_PT_EN (0x1 << 21)
++#define SCU_HW_STRAP_LPC_DEC_SUPER_IO (0x1 << 20)
++#define SCU_HW_STRAP_ACPI_DIS (0x1 << 19)
++
++//bit 23, 18 [1,0]
++#define SCU_HW_STRAP_SET_CLK_SOURCE(x) ((((x&0x3) >> 1)<<23)||((x&0x1) << 18))
++#define SCU_HW_STRAP_GET_CLK_SOURCE(x) (((x>>23)&0x1<<1) | ((x>>18)&0x1))
++#define SCU_HW_STRAP_CLK_SOURCE_MASK ((0x1 << 23) | (0x1 << 18))
++
++#define CLK_25M_IN (0x1 << 23)
++#define CLK_24M_IN 0
++#define CLK_48M_IN 1
++#define CLK_25M_IN_24M_USB_CKI 3
++#define CLK_25M_IN_48M_USB_CKI 3
++
++#define SCU_HW_STRAP_2ND_BOOT_WDT (0x1 << 17)
++#define SCU_HW_STRAP_SUPER_IO_CONFIG (0x1 << 16)
++#define SCU_HW_STRAP_VGA_CLASS_CODE (0x1 << 15)
++#define SCU_HW_STRAP_LPC_RESET_PIN (0x1 << 14)
++#define SCU_HW_STRAP_SPI_MODE(x) (x << 12)
++#define SCU_HW_STRAP_SPI_MODE_MASK (0x3 << 12)
++#define SPI_MODE_DIS (0)
++#define SPI_MODE_MASTER_EN (1)
++#define SPI_MODE_M_S_EN (2)
++#define SPI_MODE_PS (3)
++
++#define SCU_HW_STRAP_SET_CPU_AHB_RATIO(x) (x << 10)
++#define SCU_HW_STRAP_GET_CPU_AHB_RATIO(x) ((x >> 10) & 3)
++#define SCU_HW_STRAP_CPU_AHB_RATIO_MASK (0x3 << 10)
++
++
++#define CPU_AHB_RATIO_1_1 0
++#define CPU_AHB_RATIO_2_1 1
++#define CPU_AHB_RATIO_4_1 2
++#define CPU_AHB_RATIO_3_1 3
++
++#define SCU_HW_STRAP_GET_H_PLL_CLK(x) ((x >> 8 )& 0x3)
++#define SCU_HW_STRAP_H_PLL_CLK_MASK (0x3 << 8)
++#define CPU_384MHZ 0
++#define CPU_360MHZ 1
++#define CPU_336MHZ 2
++#define CPU_408MHZ 3
++
++#define SCU_HW_STRAP_MAC1_RGMII (0x1 << 7)
++#define SCU_HW_STRAP_MAC0_RGMII (0x1 << 6)
++#define SCU_HW_STRAP_VGA_BIOS_ROM (0x1 << 5)
++#define SCU_HW_STRAP_SPI_WIDTH (0x1 << 4)
++#define SCU_HW_STRAP_VGA_SIZE_GET(x) ((x >> 2)& 0x3)
++
++#define SCU_HW_STRAP_BOOT_MODE(x) (x)
++#define NOR_BOOT 0
++#define NAND_BOOT 1
++#define SPI_BOOT 2
++#define DIS_BOOT 3
++
++/* AST_SCU_RAMDOM_GEN 0x74 random number generator register */
++/* AST_SCU_RAMDOM_DATA 0x78 random number generator data output*/
++
++/* AST_SCU_MULTI_FUNC_2 0x78 */
++
++#define MULTI_FUNC_VIDEO_RGB18 (0x1 << 2)
++#define MULTI_FUNC_VIDEO_SINGLE_EDGE (0x1 << 0)
++
++
++
++/* AST_SCU_REVISION_ID 0x7C Silicon revision ID register */
++#define AST1100_A0 0x00000200
++#define AST1100_A1 0x00000201
++#define AST1100_A2 0x00000202
++#define AST1100_A3 0x00000202
++
++#define AST2050_A0 0x00000200
++#define AST2050_A1 0x00000201
++#define AST2050_A2 0x00000202
++#define AST2050_A3 0x00000202
++
++#define AST2100_A0 0x00000300
++#define AST2100_A1 0x00000301
++#define AST2100_A2 0x00000302
++#define AST2100_A3 0x00000302
++
++#define AST2200_A0 0x00000102
++#define AST2200_A1 0x00000102
++
++#define AST2300_A0 0x01000003
++#define AST2300_A1 0x01010303
++#define AST1300_A1 0x01010003
++#define AST1050_A1 0x01010203
++
++#define AST2400_A0 0x02000303
++
++
++/* AST_SCU_FUN_PIN_CTRL1 0x80 Multi-function Pin Control#1*/
++#define SCU_FUN_PIN_UART4_RXD (0x1 << 31)
++#define SCU_FUN_PIN_UART4_TXD (0x1 << 30)
++#define SCU_FUN_PIN_UART4_NRTS (0x1 << 29)
++#define SCU_FUN_PIN_UART4_NDTR (0x1 << 28)
++#define SCU_FUN_PIN_UART4_NRI (0x1 << 27)
++#define SCU_FUN_PIN_UART4_NDSR (0x1 << 26)
++#define SCU_FUN_PIN_UART4_NDCD (0x1 << 25)
++#define SCU_FUN_PIN_UART4_NCTS (0x1 << 24)
++#define SCU_FUN_PIN_UART3_RXD (0x1 << 23)
++#define SCU_FUN_PIN_UART3_TXD (0x1 << 22)
++#define SCU_FUN_PIN_UART3_NRTS (0x1 << 21)
++#define SCU_FUN_PIN_UART3_NDTR (0x1 << 20)
++#define SCU_FUN_PIN_UART3_NRI (0x1 << 19)
++#define SCU_FUN_PIN_UART3_NDSR (0x1 << 18)
++#define SCU_FUN_PIN_UART3_NDCD (0x1 << 17)
++#define SCU_FUN_PIN_UART3_NCTS (0x1 << 16)
++
++
++
++
++#define SCU_FUN_PIN_MAC1_PHY_LINK (0x1 << 1)
++#define SCU_FUN_PIN_MAC0_PHY_LINK (0x1)
++
++
++/* AST_SCU_FUN_PIN_CTRL2 0x84 Multi-function Pin Control#2*/
++#define SCU_FUN_PIN_VPIB9 (0x1 << 31)
++#define SCU_FUN_PIN_VPIB8 (0x1 << 30)
++#define SCU_FUN_PIN_VPIB7 (0x1 << 29)
++#define SCU_FUN_PIN_VPIB6 (0x1 << 28)
++#define SCU_FUN_PIN_VPIB5 (0x1 << 27)
++#define SCU_FUN_PIN_VPIB4 (0x1 << 26)
++#define SCU_FUN_PIN_VPIB3 (0x1 << 25)
++#define SCU_FUN_PIN_VPIB2 (0x1 << 24)
++#define SCU_FUN_PIN_VPIB1 (0x1 << 23)
++#define SCU_FUN_PIN_VPIB0 (0x1 << 22)
++#define SCU_FUN_PIN_VPICLK (0x1 << 21)
++#define SCU_FUN_PIN_VPIVS (0x1 << 20)
++#define SCU_FUN_PIN_VPIHS (0x1 << 19)
++#define SCU_FUN_PIN_VPIODD (0x1 << 18)
++#define SCU_FUN_PIN_VPIDE (0x1 << 17)
++
++#define SCU_FUN_PIN_UART2_RXD (0x1 << 31)
++#define SCU_FUN_PIN_UART2_TXD (0x1 << 30)
++#define SCU_FUN_PIN_UART2_NRTS (0x1 << 29)
++#define SCU_FUN_PIN_UART2_NDTR (0x1 << 28)
++#define SCU_FUN_PIN_UART2_NRI (0x1 << 27)
++#define SCU_FUN_PIN_UART2_NDSR (0x1 << 26)
++#define SCU_FUN_PIN_UART2_NDCD (0x1 << 25)
++#define SCU_FUN_PIN_UART2_NCTS (0x1 << 24)
++#define SCU_FUN_PIN_UART1_RXD (0x1 << 23)
++#define SCU_FUN_PIN_UART1_TXD (0x1 << 22)
++#define SCU_FUN_PIN_UART1_NRTS (0x1 << 21)
++#define SCU_FUN_PIN_UART1_NDTR (0x1 << 20)
++#define SCU_FUN_PIN_UART1_NRI (0x1 << 19)
++#define SCU_FUN_PIN_UART1_NDSR (0x1 << 18)
++#define SCU_FUN_PIN_UART1_NDCD (0x1 << 17)
++#define SCU_FUN_PIN_UART1_NCTS (0x1 << 16)
++
++
++#define SCU_FUN_PIN_NAND_FLWP (0x1 << 7)
++#define SCU_FUN_PIN_NAND_FLBUSY (0x1 << 6)
++
++/* AST_SCU_FUN_PIN_CTRL3 0x88 Multi-function Pin Control#3*/
++#if defined(CONFIG_ARCH_AST1010)
++#define SCU_FUN_PIN_MAC0_MDIO (0x1 << 23)
++#define SCU_FUN_PIN_MAC0_MDC (0x1 << 22)
++#else
++#define SCU_FUN_PIN_MAC0_MDIO (0x1 << 31)
++#define SCU_FUN_PIN_MAC0_MDC (0x1 << 30)
++#define SCU_FUN_PIN_ROMA25 (0x1 << 29)
++#define SCU_FUN_PIN_ROMA24 (0x1 << 28)
++#define SCU_FUN_PIN_ROMCS4 (0x1 << 27)
++#define SCU_FUN_PIN_ROMCS3 (0x1 << 26)
++#define SCU_FUN_PIN_ROMCS2 (0x1 << 25)
++#define SCU_FUN_PIN_ROMCS1 (0x1 << 24)
++#define SCU_FUN_PIN_ROMCS(x) (0x1 << (23+x))
++
++//Video pin
++#define SCU_FUN_PIN_VPIR9 (0x1 << 19)
++#define SCU_FUN_PIN_VPIR8 (0x1 << 18)
++#define SCU_FUN_PIN_VPIR7 (0x1 << 17)
++#define SCU_FUN_PIN_VPIR6 (0x1 << 16)
++#define SCU_FUN_PIN_VPIR5 (0x1 << 15)
++#define SCU_FUN_PIN_VPIR4 (0x1 << 14)
++#define SCU_FUN_PIN_VPIR3 (0x1 << 13)
++#define SCU_FUN_PIN_VPIR2 (0x1 << 12)
++#define SCU_FUN_PIN_VPIR1 (0x1 << 11)
++#define SCU_FUN_PIN_VPIR0 (0x1 << 10)
++#define SCU_FUN_PIN_VPIG9 (0x1 << 9)
++#define SCU_FUN_PIN_VPIG8 (0x1 << 8)
++#define SCU_FUN_PIN_VPIG7 (0x1 << 7)
++#define SCU_FUN_PIN_VPIG6 (0x1 << 6)
++#define SCU_FUN_PIN_VPIG5 (0x1 << 5)
++#define SCU_FUN_PIN_VPIG4 (0x1 << 4)
++#define SCU_FUN_PIN_VPIG3 (0x1 << 3)
++#define SCU_FUN_PIN_VPIG2 (0x1 << 2)
++#define SCU_FUN_PIN_VPIG1 (0x1 << 1)
++#define SCU_FUN_PIN_VPIG0 (0x1 << 0)
++#endif
++
++
++//pwm pin
++#define SCU_FUN_PIN_PWM_TACHO (0)
++/* AST_SCU_FUN_PIN_CTRL4 0x8C Multi-function Pin Control#4*/
++#define SCU_FUN_PIN_ROMA23 (0x1 << 7)
++#define SCU_FUN_PIN_ROMA22 (0x1 << 6)
++
++#define SCU_FUN_PIN_ROMWE (0x1 << 5)
++#define SCU_FUN_PIN_ROMOE (0x1 << 4)
++#define SCU_FUN_PIN_ROMD7 (0x1 << 3)
++#define SCU_FUN_PIN_ROMD6 (0x1 << 2)
++#define SCU_FUN_PIN_ROMD5 (0x1 << 1)
++#define SCU_FUN_PIN_ROMD4 (0x1)
++
++/* AST_SCU_FUN_PIN_CTRL5 0x90 Multi-function Pin Control#5*/
++#define SCU_FUN_PIN_SPICS1 (0x1 << 31)
++#define SCU_FUN_PIN_LPC_PLUS (0x1 << 30)
++#define SCU_FUC_PIN_USB20_HOST (0x1 << 29)
++#define SCU_FUC_PIN_USB11_PORT4 (0x1 << 28)
++#define SCU_FUC_PIN_I2C14 (0x1 << 27)
++#define SCU_FUC_PIN_I2C13 (0x1 << 26)
++#define SCU_FUC_PIN_I2C12 (0x1 << 25)
++#define SCU_FUC_PIN_I2C11 (0x1 << 24)
++#define SCU_FUC_PIN_I2C10 (0x1 << 23)
++#define SCU_FUC_PIN_I2C9 (0x1 << 22)
++#define SCU_FUC_PIN_I2C8 (0x1 << 21)
++#define SCU_FUC_PIN_I2C7 (0x1 << 20)
++#define SCU_FUC_PIN_I2C6 (0x1 << 19)
++#define SCU_FUC_PIN_I2C5 (0x1 << 18)
++#define SCU_FUC_PIN_I2C4 (0x1 << 17)
++#define SCU_FUC_PIN_I2C3 (0x1 << 16)
++#define SCU_FUC_PIN_MII2_RX_DWN_DIS (0x1 << 15)
++#define SCU_FUC_PIN_MII2_TX_DWN_DIS (0x1 << 14)
++#define SCU_FUC_PIN_MII1_RX_DWN_DIS (0x1 << 13)
++#define SCU_FUC_PIN_MII1_TX_DWN_DIS (0x1 << 12)
++
++#define SCU_FUC_PIN_MII2_TX_DRIV(x) (x << 10)
++#define SCU_FUC_PIN_MII2_TX_DRIV_MASK (0x3 << 10)
++#define SCU_FUC_PIN_MII1_TX_DRIV(x) (x << 8)
++#define SCU_FUC_PIN_MII1_TX_DRIV_MASK (0x3 << 8)
++
++#define MII_NORMAL_DRIV 0x0
++#define MII_HIGH_DRIV 0x2
++
++#define SCU_FUC_PIN_UART6 (0x1 << 7)
++#define SCU_FUC_PIN_ROM_16BIT (0x1 << 6)
++#define SCU_FUC_PIN_DIGI_V_OUT(x) (x << 4)
++#define SCU_FUC_PIN_DIGI_V_OUT_MASK (0x3 << 4)
++
++#define VIDEO_DISABLE 0x0
++#define VIDEO_12BITS 0x1
++#define VIDEO_24BITS 0x2
++//#define VIDEO_DISABLE 0x3
++
++#define SCU_FUC_PIN_USB11_PORT2 (0x1 << 3)
++#define SCU_FUC_PIN_MAC1_MDIO (0x1 << 2)
++#define SCU_FUC_PIN_SD2 (0x1 << 1)
++#define SCU_FUC_PIN_SD1 (0x1 << 0)
++
++
++/* AST_SCU_FUN_PIN_CTRL6 0x94 Multi-function Pin Control#6*/
++#define SCU_VIDEO_OUT_MASK (~0x3)
++
++/* AST_SCU_WDT_RESET 0x9C Watchdog Reset Selection */
++/* AST_SCU_FUN_PIN_CTRL7 0xA0 Multi-function Pin Control#7*/
++/* AST_SCU_FUN_PIN_CTRL8 0xA4 Multi-function Pin Control#8*/
++#define SCU_FUN_PIN_ROMA17 (0x1 << 31)
++#define SCU_FUN_PIN_ROMA16 (0x1 << 30)
++#define SCU_FUN_PIN_ROMA15 (0x1 << 29)
++#define SCU_FUN_PIN_ROMA14 (0x1 << 28)
++#define SCU_FUN_PIN_ROMA13 (0x1 << 27)
++#define SCU_FUN_PIN_ROMA12 (0x1 << 26)
++#define SCU_FUN_PIN_ROMA11 (0x1 << 25)
++#define SCU_FUN_PIN_ROMA10 (0x1 << 24)
++#define SCU_FUN_PIN_ROMA9 (0x1 << 23)
++#define SCU_FUN_PIN_ROMA8 (0x1 << 22)
++#define SCU_FUN_PIN_ROMA7 (0x1 << 21)
++#define SCU_FUN_PIN_ROMA6 (0x1 << 20)
++#define SCU_FUN_PIN_ROMA5 (0x1 << 19)
++#define SCU_FUN_PIN_ROMA4 (0x1 << 18)
++#define SCU_FUN_PIN_ROMA3 (0x1 << 17)
++#define SCU_FUN_PIN_ROMA2 (0x1 << 16)
++
++/* AST_SCU_FUN_PIN_CTRL9 0xA8 Multi-function Pin Control#9*/
++#define SCU_FUN_PIN_ROMA21 (0x1 << 3)
++#define SCU_FUN_PIN_ROMA20 (0x1 << 2)
++#define SCU_FUN_PIN_ROMA19 (0x1 << 1)
++#define SCU_FUN_PIN_ROMA18 (0x1)
++
++/* AST_SCU_PWR_SAVING_EN 0xC0 Power Saving Wakeup Enable*/
++/* AST_SCU_PWR_SAVING_CTRL 0xC4 Power Saving Wakeup Control*/
++/* AST_SCU_HW_STRAP2 0xD0 Haardware strapping register set 2*/
++/* AST_SCU_COUNTER4 0xE0 SCU Free Run Counter Read Back #4*/
++/* AST_SCU_COUNTER4_EXT 0xE4 SCU Free Run Counter Extended Read Back #4*/
++
++//CPU 2
++/* AST_SCU_CPU2_CTRL 0x100 CPU2 Control Register*/
++/* AST_SCU_CPU2_BASE0_ADDR 0x104 CPU2 Base Address for Segment 0x00:0000~0x1F:FFFF*/
++/* AST_SCU_CPU2_BASE1_ADDR 0x108 CPU2 Base Address for Segment 0x20:0000~0x3F:FFFF*/
++/* AST_SCU_CPU2_BASE2_ADDR 0x10C CPU2 Base Address for Segment 0x40:0000~0x5F:FFFF*/
++/* AST_SCU_CPU2_BASE3_ADDR 0x110 CPU2 Base Address for Segment 0x60:0000~0x7F:FFFF*/
++/* AST_SCU_CPU2_BASE4_ADDR 0x114 CPU2 Base Address for Segment 0x80:0000~0xFF:FFFF*/
++/* AST_SCU_CPU2_CACHE_CTRL 0x118 CPU2 Cache Function Control */
++
++//
++/* AST_SCU_UART24_REF 0x160 Generate UART 24Mhz Ref from H-PLL when CLKIN is 25Mhz */
++/* AST_SCU_PCIE_CONFIG_SET 0x180 PCI-E Configuration Setting Control Register */
++/* AST_SCU_BMC_MMIO_DEC 0x184 BMC MMIO Decode Setting Register */
++/* AST_SCU_DEC_AREA1 0x188 1st relocated controller decode area location */
++/* AST_SCU_DEC_AREA2 0x18C 2nd relocated controller decode area location */
++/* AST_SCU_MBOX_DEC_AREA 0x190 Mailbox decode area location*/
++/* AST_SCU_SRAM_DEC_AREA0 0x194 Shared SRAM area decode location*/
++/* AST_SCU_SRAM_DEC_AREA1 0x198 Shared SRAM area decode location*/
++/* AST_SCU_BMC_CLASS 0x19C BMC device class code and revision ID */
++/* AST_SCU_BMC_DEV_ID 0x1A4 BMC device ID */
++
++#endif
++
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-sdmc.h b/arch/arm/plat-aspeed/include/plat/regs-sdmc.h
+new file mode 100644
+index 0000000..2bcc948
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-sdmc.h
+@@ -0,0 +1,31 @@
++/* arch/arm/mach-aspeed/include/mach/regs-ast1010-scu.h
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * 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.
++ *
++ * History :
++ * 1. 2012/12/29 Ryan Chen Create
++ *
++********************************************************************************/
++#ifndef __AST_SDMC_H
++#define __AST_SDMC_H 1
++
++/*
++ * Register for SDMC
++ * */
++#define AST_SDMC_PROTECT 0x00 /* protection key register */
++#define AST_SDMC_CONFIG 0x04 /* Configuration register */
++
++
++/* AST_SDMC_PROTECT: 0x00 - protection key register */
++#define SDMC_PROTECT_UNLOCK 0xFC600309
++
++/* AST_SDMC_CONFIG :0x04 - Configuration register */
++#define SDMC_CONFIG_MEM_GET(x) (x & 0x3)
++
++
++#endif
++
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-smc.h b/arch/arm/plat-aspeed/include/plat/regs-smc.h
+new file mode 100644
+index 0000000..d4e0252
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-smc.h
+@@ -0,0 +1,54 @@
++/* arch/arm/plat-aspeed/include/mach/regs-smc.h
++ *
++ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
++ * http://www.aspeedtech.com/
++ *
++ * 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.
++ *
++ * ASPEED Static memory ctrol
++*/
++
++#ifndef __ASM_ARCH_REGS_FMC_H
++#define __ASM_ARCH_REGS_FMC_H __FILE__
++
++#define FMC_CE_TYPE 0x00
++#define FMC_CE_CTRL 0x04
++#define FMC_INTR_CTRL 0x08
++#define FMC_CE0_CTRL 0x10
++#define FMC_CE1_CTRL 0x14
++#define FMC_CE2_CTRL 0x18
++#define FMC_CE3_CTRL 0x1c
++#define FMC_CE4_CTRL 0x20
++
++#define FMC_CE0_ADDR 0x30
++#define FMC_CE1_ADDR 0x34
++#define FMC_CE2_ADDR 0x38
++#define FMC_CE3_ADDR 0x3c
++#define FMC_CE4_ADDR 0x40
++
++#define FMC_MISC_CTRL1 0x50
++#define FMC_MISC_CTRL2 0x54
++#define FMC_NAND_CTRL 0x58
++#define FMC_NAND_ECC 0x5c
++#define FMC_NAND_ECC_CK1 0x60
++#define FMC_NAND_ECC_CK2 0x64
++#define FMC_NAND_ECC_CK3 0x68
++#define FMC_NAND_ECC_GEN1 0x6c
++#define FMC_NAND_ECC_GEN2 0x70
++#define FMC_NAND_ECC_GEN3 0x74
++#define FMC_NAND_ECC_CK_R1 0x78
++#define FMC_NAND_ECC_CK_R2 0x7c
++#define FMC_DMA_CTRL 0x80
++#define FMC_DMA_FLASH_ADDR 0x84
++#define FMC_DMA_DRAM_ADDR 0x88
++#define FMC_DMA_LEN 0x8C
++#define FMC_CHECK_SUM 0x90
++#define FMC_SPI_TIMING 0x94
++
++
++
++
++
++#endif /* __ASM_ARCH_REGS_FMC_H */
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-spi.h b/arch/arm/plat-aspeed/include/plat/regs-spi.h
+new file mode 100644
+index 0000000..9b20cf8
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-spi.h
+@@ -0,0 +1,51 @@
++/********************************************************************************
++* File Name : regs-spi.h
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++********************************************************************************/
++
++/* Register offsets */
++#define AST_SPI_CONFIG 0x00
++#define AST_SPI_CTRL 0x04
++#define AST_SPI_MISC 0x10
++#define AST_SPI_TIMING 0x14
++
++/* AST_SPI_CONFIG 0x00 : SPI Flash Configuration Register */
++#define SPI_CONF_CLKX2 (0x1 << 1)
++#define SPI_CONF_WRITE_EN (0x1)
++
++/* FMC_CE0_CTRL for SPI 0x10, 0x14, 0x18, 0x1c, 0x20 */
++#define SPI_IO_MODE(x) (x << 28)
++#define SPI_SINGLE_BIT 0
++#define SPI_DUAL_BIT_D 2
++#define SPI_DUAL_BIT_DA 3
++#define SPI_CE_WIDTH(x) (x << 24)
++#define SPI_CMD_DATA(x) (x << 16)
++#define SPI_DUMMY_CMD (1 << 15)
++#define SPI_DUMMY_HIGH (1 << 14)
++//#define SPI_CLK_DIV (1 << 13) ?? TODO ask....
++//#define SPI_ADDR_CYCLE (1 << 13) ?? TODO ask....
++#define SPI_CMD_MERGE_DIS (1 << 12)
++#define SPI_CLK_DIV(x) (x << 8)
++#define SPI_CLK_DIV_MASK (0xf << 8)
++
++#define SPI_DUMMY_LOW (x << 6)
++#define SPI_LSB_FIRST_CTRL (1 << 5)
++#define SPI_CPOL_1 (1 << 4)
++#define SPI_DUAL_DATA (1 << 3)
++#define SPI_CE_INACTIVE (1 << 2)
++#define SPI_CMD_MODE (x)
++#define SPI_CMD_NOR_R_MODE 0
++#define SPI_CMD_FAST_R_MODE 1
++#define SPI_CMD_NOR_W_MODE 2
++#define SPI_CMD_USER_MODE 3
++
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-uart-dma.h b/arch/arm/plat-aspeed/include/plat/regs-uart-dma.h
+new file mode 100644
+index 0000000..2282bb1
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-uart-dma.h
+@@ -0,0 +1,79 @@
++/* arch/arm/mach-aspeed/include/mach/regs-uart-dma.h
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * 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.
++ *
++ * History :
++ * 1. 2013/05/15 Ryan Chen Create
++ *
++********************************************************************************/
++#ifndef __AST1070_UART_DMA_H
++#define __AST1070_UART_DMA_H 1
++
++#define UART_DMA0_TX_CTRL 0x00
++#define UART_DMA0_TX_DESCPT 0x04
++#define UART_DMA1_TX_CTRL 0x08
++#define UART_DMA1_TX_DESCPT 0x0C
++#define UART_DMA2_TX_CTRL 0x10
++#define UART_DMA2_TX_DESCPT 0x14
++#define UART_DMA3_TX_CTRL 0x18
++#define UART_DMA3_TX_DESCPT 0x1C
++#define UART_DMA0_RX_CTRL 0x20
++#define UART_DMA0_RX_DESCPT 0x24
++#define UART_DMA1_RX_CTRL 0x28
++#define UART_DMA1_RX_DESCPT 0x2C
++#define UART_DMA2_RX_CTRL 0x30
++#define UART_DMA2_RX_DESCPT 0x34
++#define UART_DMA3_RX_CTRL 0x38
++#define UART_DMA3_RX_DESCPT 0x3C
++#define UART_DMA_CTRL 0x40
++#define UART_DMA_IER 0x44
++#define UART_DMA_ISR 0x48
++
++/* */
++#define DMA_TRIGGER (1 << 2)
++#define DMA_ENABLE (1 << 0)
++
++/* UART_DMA_CTRL 0x40 */
++#define SPI_CLK_MASK (0x1f << 16)
++#define SPI_CLK_SET(x) ((x) << 16)
++#define DMA_RX_TIMEOUT(x) ((x) << 4)
++#define DMA_BURST_LEN(x) ((x) << 2)
++#define DMA_BURST_MASK (0x3 << 2)
++#define BURST_1 0
++#define BURST_2 1
++#define BURST_4 2
++#define BURST_8 3
++#define RXDESC_AUTO_POLLING (1 << 1)
++#define TXDESC_AUTO_POLLING (1 << 0)
++
++/* UART_DMA_IER / UART_DMA_ISR 0x44 0x48 */
++
++#define UART_DMA3_RX_INT (1 << 7)
++#define UART_DMA2_RX_INT (1 << 6)
++#define UART_DMA1_RX_INT (1 << 5)
++#define UART_DMA0_RX_INT (1 << 4)
++#define UART_DMA3_TX_INT (1 << 3)
++#define UART_DMA2_TX_INT (1 << 2)
++#define UART_DMA1_TX_INT (1 << 1)
++#define UART_DMA0_TX_INT (1 << 0)
++
++
++/* UART DESC #0 Command Register */
++#define DESC0_INT_EN (1 << 9)
++#define DESC0_END (1 << 8)
++#define DESC0_HW_OWN (1 << 0)
++
++/* UART DESC #1 Base Address of Data */
++#define DESC1_LEN(x) ((x) << 16)
++#define DESC1_NEXT(x) (x)
++
++/* UART DESC #2 Base Address of Data */
++
++/* UART DESC #3 Descriptor Status Register */
++#define DESC3_TIMEOUT_STS (1 << 16)
++#define DESC3_GET_LEN(x) ((x) & 0xffff)
++#endif
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-udc11.h b/arch/arm/plat-aspeed/include/plat/regs-udc11.h
+new file mode 100644
+index 0000000..3b74d63
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-udc11.h
+@@ -0,0 +1,98 @@
++/* arch/arm/plat-aspeed/include/mach/regs-udc11.h
++ *
++ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
++ * http://www.aspeedtech.com/
++ *
++ * 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.
++ *
++ * ASPEED UDC11 Controller
++*/
++
++#ifndef __ASM_ARCH_REGS_UDC11_H
++#define __ASM_ARCH_REGS_UDC11_H __FILE__
++
++#define AST_UDC11_CTRL 0x00 /* Function Control and Status Register */
++#define AST_UDC11_CONF 0x04 /* Function Configuration Setting Register */
++#define AST_UDC11_REST 0x08 /* Endpoint Toggle Bit Reset Register */
++#define AST_UDC11_STS 0x0C /* USB Status Register */
++#define AST_UDC11_IER 0x10 /* Interrupt Control Register */
++#define AST_UDC11_ISR 0x14 /* Interrupt Status Register */
++#define AST_UDC11_EP0_CTRL 0x18 /* Endpoint 0 Control and Status Register */
++#define AST_UDC11_EP1_CTRL 0x1C /* Endpoint 1 Control and Status Register */
++#define AST_UDC11_EP2_CTRL 0x20 /* Endpoint 2 Control and Status Register */
++#define AST_UDC11_EP0_SETUP0 0x24 /* Endpoint 0 Setup/OUT Data Buffer LOW Register */
++#define AST_UDC11_EP0_SETUP1 0x28 /* Endpoint 0 Setup/OUT Data Buffer HIGH Register */
++#define AST_UDC11_EP0_DATA0 0x2C /* Endpoint 0 IN DATA Buffer LOW Register */
++#define AST_UDC11_EP0_DATA1 0x30 /* Endpoint 0 IN DATA Buffer HIGH Register */
++#define AST_UDC11_EP1_DATA0 0x34 /* Endpoint 1 IN DATA Buffer LOW Register */
++#define AST_UDC11_EP1_DATA1 0x38 /* Endpoint 1 IN DATA Buffer HIGH Register */
++#define AST_UDC11_EP2_DATA0 0x3C /* Endpoint 2 IN DATA Buffer LOW Register */
++#define AST_UDC11_EP2_DATA1 0x40 /* Endpoint 2 IN DATA Buffer HIGH Register */
++
++/* AST_UDC11_CTRL 0x00 Function Control and Status Register */
++#define UDC11_CTRL_TEST_RESULT (1 << 10)
++#define UDC11_CTRL_TEST_STS (1 << 9)
++#define UDC11_CTRL_TEST_MODE(x) ((x) << 6)
++#define UDC11_CTRL_WKP(x) ((x) << 4)
++#define UDC11_CTRL_WKP_EN (1 << 3)
++#define UDC11_CTRL_CLK_STOP (1 << 2)
++#define UDC11_CTRL_LS_EN (1 << 1)
++#define UDC11_CTRL_CONNECT_EN (1)
++
++/* AST_UDC11_CONF 0x04 Function Configuration Setting Register */
++#define UDC11_CONF_ADDR_MASK (0x3f << 1)
++#define UDC11_CONF_SET_ADDR(x) (x << 1)
++#define UDC11_CONF_SET_CONF (1)
++
++/* AST_UDC11_REST 0x08 Endpoint Toggle Bit Reset Register */
++#define UDC11_REST_EP2 (1 << 1)
++#define UDC11_REST_EP1 (1)
++
++
++/* AST_UDC11_STS 0x0C USB Status Register */
++#define UDC11_STS_SUSPEND (1 << 31)
++#define UDC11_STS_BUS_RST (1 << 30)
++#define UDC11_STS_LINE_DP (1 << 29)
++#define UDC11_STS_LINE_DN (1 << 28)
++#define UDC11_STS_FRAM_NUM_MASK (0x7ff << 16)
++#define UDC11_STS_GET_FRAM_NUM(x) ((x >> 16) & 0x7ff)
++#define UDC11_STS_LAST_ADDR (0x7f << 4)
++#define UDC11_STS_LAST_EP (0xf)
++
++/* AST_UDC11_IER 0x10 Interrupt Control Register */
++/* AST_UDC11_ISR 0x14 Interrupt Status Register */
++#define UDC11_EP0_OUT (1 << 9)
++#define UDC11_EP0_NAK (1 << 8)
++#define UDC11_EP2_IN_ACK (1 << 7)
++#define UDC11_EP1_IN_ACK (1 << 6)
++#define UDC11_EP0_IN_ACK (1 << 5)
++#define UDC11_EP0_OUT_ACK (1 << 4)
++#define UDC11_EP0_SETUP (1 << 3)
++#define UDC11_SUSPEND_RESUME (1 << 2)
++#define UDC11_SUSPEND_ENTRY (1 << 1)
++#define UDC11_BUS_REST (1)
++
++/* AST_UDC11_EP0_CTRL 0x18 Endpoint 0 Control and Status Register */
++/* AST_UDC11_EP1_CTRL 0x1C Endpoint 1 Control and Status Register */
++/* AST_UDC11_EP2_CTRL 0x20 Endpoint 2 Control and Status Register */
++#define GET_EP_OUT_RX_LEN(x) ((x & 0xf) >> 8) //only for EP0
++#define GET_EP_IN_TX_LEN(x) ((x & 0xf) >> 4)
++#define SET_EP_IN_TX_LEN(x) ((x & 0xf) << 4)
++#define EP_OUT_BUFF_RX_RDY (1 << 2) //only for EP0
++#define EP_IN_BUFF_TX_RDY (1 << 1)
++#define EP_CTRL_STALL
++
++
++
++
++
++
++
++
++
++
++
++
++#endif /* __ASM_ARCH_REGS_UDC11_H */
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-video.h b/arch/arm/plat-aspeed/include/plat/regs-video.h
+new file mode 100644
+index 0000000..ee99075
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-video.h
+@@ -0,0 +1,348 @@
++/* arch/arm/mach-aspeed/include/mach/regs-video.h
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * 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.
++ *
++ * History :
++ * 1. 2012/08/15 Ryan Chen Create
++ *
++********************************************************************************/
++#ifndef __AST_VIDEO_H
++#define __AST_VIDEO_H 1
++
++/*
++ * Register for VIDEO
++ * */
++#define AST_VIDEO_PROTECT 0x000 /* protection key register */
++#define AST_VIDEO_SEQ_CTRL 0x004 /* Video Sequence Control register */
++#define AST_VIDEO_PASS_CTRL 0x008 /* Video Pass 1 Control register */
++
++#define AST_VIDEO_DIRECT_BASE 0x00C /* Video Direct Frame buffer mode control Register VR008[5]=1 */
++#define AST_VIDEO_DIRECT_CTRL 0x010 /* Video Direct Frame buffer mode control Register VR008[5]=1 */
++
++#define AST_VIDEO_TIMING_H 0x00C /* Video Timing Generation Setting Register */
++#define AST_VIDEO_TIMING_V 0x010 /* Video Timing Generation Setting Register */
++#define AST_VIDEO_SCAL_FACTOR 0x014 /* Video Scaling Factor Register */
++
++#define AST_VIDEO_SCALING0 0x018 /* Video Scaling Filter Parameter Register #0 */
++#define AST_VIDEO_SCALING1 0x01C /* Video Scaling Filter Parameter Register #1 */
++#define AST_VIDEO_SCALING2 0x020 /* Video Scaling Filter Parameter Register #2 */
++#define AST_VIDEO_SCALING3 0x024 /* Video Scaling Filter Parameter Register #3 */
++
++#define AST_VIDEO_BCD_CTRL 0x02C /* Video BCD Control Register */
++#define AST_VIDEO_CAPTURE_WIN 0x030 /* Video Capturing Window Setting Register */
++#define AST_VIDEO_COMPRESS_WIN 0x034 /* Video Compression Window Setting Register */
++
++
++#define AST_VIDEO_COMPRESS_PRO 0x038 /* Video Compression Stream Buffer Processing Offset Register */
++#define AST_VIDEO_COMPRESS_READ 0x03C /* Video Compression Stream Buffer Read Offset Register */
++
++#define AST_VIDEO_SOURCE_BUFF0 0x044 /* Video Based Address of Video Source Buffer #1 Register */
++#define AST_VIDEO_SOURCE_SCAN_LINE 0x048 /* Video Scan Line Offset of Video Source Buffer Register */
++#define AST_VIDEO_SOURCE_BUFF1 0x04C /* Video Based Address of Video Source Buffer #2 Register */
++#define AST_VIDEO_BCD_BUFF 0x050 /* Video Base Address of BCD Flag Buffer Register */
++#define AST_VIDEO_STREAM_BUFF 0x054 /* Video Base Address of Compressed Video Stream Buffer Register */
++#define AST_VIDEO_STREAM_SIZE 0x058 /* Video Stream Buffer Size Register */
++
++
++#define AST_VIDEO_COMPRESS_CTRL 0x060 /* Video Compression Control Register */
++
++
++#define AST_VIDEO_DEF_HEADER 0x080 /* Video User Defined Header Parameter Setting with Compression */
++
++#define AST_VIDEO_H_DETECT_STS 0x090 /* Video Source Left/Right Edge Detection Read Back Register */
++#define AST_VIDEO_V_DETECT_STS 0x094 /* Video Source Top/Bottom Edge Detection Read Back Register */
++
++
++#define AST_VIDEO_MODE_DET_STS 0x098 /* Video Mode Detection Status Read Back Register */
++
++#define AST_VIDEO_MODE_DET1 0x0A4 /* Video Mode Detection Control Register 1*/
++
++
++#define AST_VIDEO_CTRL 0x300 /* Video Control Register */
++#define AST_VIDEO_INT_EN 0x304 /* Video interrupt Enable */
++#define AST_VIDEO_INT_STS 0x308 /* Video interrupt status */
++#define AST_VIDEO_MODE_DETECT 0x30C /* Video Mode Detection Parameter Register */
++
++#define AST_VIDEO_CRC1 0x320 /* Primary CRC Parameter Register */
++#define AST_VIDEO_CRC2 0x324 /* Second CRC Parameter Register */
++#define AST_VIDEO_DATA_TRUNCA 0x328 /* Video Data Truncation Register */
++
++
++#define AST_VIDEO_SCRATCH_340 0x340 /* Video Scratch Remap Read Back */
++#define AST_VIDEO_SCRATCH_344 0x344 /* Video Scratch Remap Read Back */
++#define AST_VIDEO_SCRATCH_348 0x348 /* Video Scratch Remap Read Back */
++#define AST_VIDEO_SCRATCH_34C 0x34C /* Video Scratch Remap Read Back */
++#define AST_VIDEO_SCRATCH_350 0x350 /* Video Scratch Remap Read Back */
++#define AST_VIDEO_SCRATCH_354 0x354 /* Video Scratch Remap Read Back */
++#define AST_VIDEO_SCRATCH_358 0x358 /* Video Scratch Remap Read Back */
++#define AST_VIDEO_SCRATCH_35C 0x35C /* Video Scratch Remap Read Back */
++#define AST_VIDEO_SCRATCH_360 0x360 /* Video Scratch Remap Read Back */
++#define AST_VIDEO_SCRATCH_364 0x364 /* Video Scratch Remap Read Back */
++
++
++#define AST_VIDEO_ENCRYPT_SRAM 0x400 /* Video RC4/AES128 Encryption Key Register #0 ~ #63 */
++
++/////////////////////////////////////////////////////////////////////////////
++
++/* AST_VIDEO_PROTECT: 0x000 - protection key register */
++#define VIDEO_PROTECT_UNLOCK 0x1A038AA8
++
++/* AST_VIDEO_SEQ_CTRL 0x004 Video Sequence Control register */
++#define VIDEO_HALT_ENG_STS (1 << 21)
++#define VIDEO_COMPRESS_BUSY (1 << 18)
++#define VIDEO_CAPTURE_BUSY (1 << 16)
++#define VIDEO_HALT_ENG_TRIGGER (1 << 12)
++#define VIDEO_COMPRESS_FORMAT_MASK (3 << 10)
++#define VIDEO_COMPRESS_FORMAT(x) (x << 10) // 0 YUV444
++#define YUV420 1
++#define VIDEO_COMPRESS_JPEG_CPB (1 << 8)
++//if bit 0 : 1
++#define VIDEO_INPUT_MODE_CHG_WDT (1 << 7)
++#define VIDEO_INSERT_FULL_COMPRESS (1 << 6)
++#define VIDEO_AUTO_COMPRESS (1 << 5)
++#define VIDEO_COMPRESS_TRIGGER (1 << 4)
++#define VIDEO_CAPTURE_MULTI_FRAME (1 << 3)
++#define VIDEO_COMPRESS_FORCE_IDLE (1 << 2)
++#define VIDEO_CAPTURE_TIRGGER (1 << 1)
++#define VIDEO_DETECT_TRIGGER (1 << 0)
++
++
++#define VIDEO_HALT_ENG_RB (1 << 21)
++#define VIDEO_HALT_ENG_RB (1 << 21)
++#define VIDEO_HALT_ENG_RB (1 << 21)
++#define VIDEO_HALT_ENG_RB (1 << 21)
++#define VIDEO_HALT_ENG_RB (1 << 21)
++#define VIDEO_HALT_ENG_RB (1 << 21)
++
++
++/* AST_VIDEO_PASS_CTRL 0x008 Video Pass1 Control register */
++//x * source frame rate / 60
++#define VIDEO_FRAME_RATE_CTRL(x) (x << 16)
++#define VIDEO_HSYNC_POLARITY_CTRL (1 << 15)
++#define VIDEO_INTERLANCE_MODE (1 << 14)
++#define VIDEO_DUAL_EDGE_MODE (1 << 13) //0 : Single edage
++#define VIDEO_18BIT_SINGLE_EDGE (1 << 12) //0: 24bits
++#define VIDEO_DVO_INPUT_DELAY_MASK (7 << 9)
++#define VIDEO_DVO_INPUT_DELAY(x) (x << 9) //0 : no delay , 1: 1ns, 2: 2ns, 3:3ns
++// if biit 5 : 0
++#define VIDEO_HW_CURSOR_DIS (1 << 8)
++// if biit 5 : 1
++#define VIDEO_AUTO_FATCH (1 << 8)
++#define VIDEO_CAPTURE_MODE(x) (x << 6)
++#define YUV_MODE 1
++#define RGB_MODE 2
++#define GRAY_MODE 3
++#define VIDEO_DIRT_FATCH (1 << 5)
++// if biit 5 : 0
++#define VIDEO_INTERNAL_DE (1 << 4)
++#define VIDEO_EXT_ADC_ATTRIBUTE (1 << 3)
++
++// if biit 5 : 1
++#define VIDEO_16BPP_MODE (1 << 4)
++#define VIDEO_16BPP_MODE_555 (1 << 3) //0:565
++
++#define VIDEO_FROM_EXT_SOURCE (1 << 2)
++#define VIDEO_SO_VSYNC_POLARITY (1 << 1)
++#define VIDEO_SO_HSYNC_POLARITY (1 << 0)
++
++/* AST_VIDEO_TIMING_H 0x00C Video Timing Generation Setting Register */
++#define VIDEO_HSYNC_PIXEL_FIRST_SET(x) ((x) << 16)
++#define VIDEO_HSYNC_PIXEL_LAST_SET(x) (x)
++
++
++/* AST_VIDEO_DIRECT_CTRL 0x010 Video Direct Frame buffer mode control Register VR008[5]=1 */
++#define VIDEO_FETCH_TIMING(x) ((x) << 16)
++#define VIDEO_FETCH_LINE_OFFSET(x) (x)
++
++/* AST_VIDEO_TIMING_V 0x010 Video Timing Generation Setting Register */
++#define VIDEO_VSYNC_PIXEL_FIRST_SET(x) ((x) << 16)
++#define VIDEO_VSYNC_PIXEL_LAST_SET(x) (x)
++
++
++/* AST_VIDEO_SCAL_FACTOR 0x014 Video Scaling Factor Register */
++#define VIDEO_V_SCAL_FACTOR(x) (((x) & 0xffff) << 16)
++#define VIDEO_H_SCAL_FACTOR(x) (x & 0xffff)
++
++
++/* AST_VIDEO_SCALING0 0x018 Video Scaling Filter Parameter Register #0 */
++/* AST_VIDEO_SCALING1 0x01C Video Scaling Filter Parameter Register #1 */
++/* AST_VIDEO_SCALING2 0x020 Video Scaling Filter Parameter Register #2 */
++/* AST_VIDEO_SCALING3 0x024 Video Scaling Filter Parameter Register #3 */
++
++
++/* AST_VIDEO_BCD_CTRL 0x02C Video BCD Control Register */
++#define VIDEO_ABCD_TOL(x) (x << 24)
++#define VIDEO_BCD_TOL(x) (x << 16)
++#define VIDEO_ABCD_CHG_EN (1 << 1)
++#define VIDEO_BCD_CHG_EN (1 << 0)
++
++
++
++/* AST_VIDEO_CAPTURE_WIN 0x030 Video Capturing Window Setting Register */
++#define VIDEO_CAPTURE_V(x) (x & 0x7ff)
++#define VIDEO_CAPTURE_H(x) ((x & 0x7ff) << 16)
++
++/* AST_VIDEO_COMPRESS_WIN 0x034 Video Compression Window Setting Register */
++#define VIDEO_COMPRESS_V(x) (x & 0x7ff)
++#define VIDEO_COMPRESS_H(x) ((x & 0x7ff) << 16)
++
++
++
++/* AST_VIDEO_RESET :0x03c - system reset control register */
++
++/* AST_VIDEO_STREAM_SIZE 0x058 Video Stream Buffer Size Register */
++#define VIDEO_STREAM_PKT_N(x) (x << 3)
++#define STREAM_4_PKTS 0
++#define STREAM_8_PKTS 1
++#define STREAM_16_PKTS 2
++#define STREAM_32_PKTS 3
++#define STREAM_64_PKTS 4
++#define STREAM_128_PKTS 5
++
++#define VIDEO_STREAM_PKT_SIZE(x) (x)
++#define STREAM_1KB 0
++#define STREAM_2KB 1
++#define STREAM_4KB 2
++#define STREAM_8KB 3
++#define STREAM_16KB 4
++#define STREAM_32KB 5
++#define STREAM_64KB 6
++#define STREAM_128KB 7
++
++
++
++
++
++
++
++
++/* AST_VIDEO_COMPRESS_CTRL 0x060 Video Compression Control Register */
++#define VIDEO_HQ_DCT_LUM(x) ((x) << 27)
++#define VIDEO_HQ_DCT_CHROM(x) ((x) << 22)
++#define VIDEO_DCT_HUFFMAN_ENCODE(x) ((x) << 20)
++#define VIDEO_DCT_RESET (1 << 17)
++#define VIDEO_HQ_ENABLE (1 << 16)
++#define VIDEO_DCT_LUM(x) ((x) << 11)
++#define VIDEO_DCT_CHROM(x) ((x) << 6)
++#define VIDEO_RC4_ENABLE (1 << 5)
++#define VIDEO_COMPRESS_QUANTIZ_MODE (1 << 2)
++#define VIDEO_4COLOR_VQ_ENCODE (1 << 1)
++#define VIDEO_DCT_ONLY_ENCODE (1 << 0)
++
++
++/* AST_VIDEO_H_DETECT_STS 0x090 Video Source Left/Right Edge Detection Read Back Register */
++#define VIDEO_DET_INTERLANCE_MODE (1 << 31)
++#define VIDEO_GET_HSYNC_RIGHT(x) ((x & 0x0FFF0000) >> 16)
++#define VIDEO_GET_HSYNC_LEFT(x) (x & 0xFFF)
++#define VIDEO_NO_DISPLAY_CLOCK_DET (1 << 15)
++#define VIDEO_NO_ACT_DISPLAY_DET (1 << 14)
++#define VIDEO_NO_HSYNC_DET (1 << 13)
++#define VIDEO_NO_VSYNC_DET (1 << 12)
++
++/* AST_VIDEO_V_DETECT_STS 0x094 Video Source Top/Bottom Edge Detection Read Back Register */
++#define VIDEO_GET_VSYNC_BOTTOM(x) ((x & 0x0FFF0000) >> 16)
++#define VIDEO_GET_VSYNC_TOP(x) (x & 0xFFF)
++
++
++/* AST_VIDEO_MODE_DET_STS 0x098 Video Mode Detection Status Read Back Register */
++#define VIDEO_DET_HSYNC_RDY (1 << 31)
++#define VIDEO_DET_VSYNC_RDY (1 << 30)
++#define VIDEO_DET_HSYNC_POLAR (1 << 29)
++#define VIDEO_DET_VSYNC_POLAR (1 << 28)
++#define VIDEO_GET_VER_SCAN_LINE(x) ((x >> 16) & 0xfff)
++#define VIDEO_OUT_SYNC (1 << 15)
++#define VIDEO_DET_VER_STABLE (1 << 14)
++#define VIDEO_DET_HOR_STABLE (1 << 13)
++#define VIDEO_DET_FROM_ADC (1 << 12)
++#define VIDEO_DET_HOR_PERIOD(x) (x & 0xfff)
++
++
++/* AST_VIDEO_MODE_DET1 0x0A4 Video Mode Detection Control Register 1*/
++#define VIDEO_DET_HSYNC_DELAY_MASK (0xff << 16)
++#define VIDEO_DET_LONG_H_STABLE_EN (1 << 29)
++
++
++/* AST_VIDEO_CTRL 0x300 Video Control Register */
++#define VIDEO_CTRL_CRYPTO(x) (x << 17)
++#define VIDEO_CTRL_CRYPTO_MASK (1 << 17)
++#define CRYPTO_RC4_MODE 0
++#define CRYPTO_AES_MODE 1
++#define VIDEO_CTRL_CRYPTO_FAST (1 << 16)
++//15 reserved
++#define VIDEO_CTRL_RC4_VC (1 << 14)
++#define VIDEO_CTRL_CAPTURE_MASK (3 << 12)
++#define VIDEO_CTRL_CAPTURE_MODE(x) (x << 12)
++#define VIDEO_CTRL_COMPRESS_MASK (3 << 10)
++#define VIDEO_CTRL_COMPRESS_MODE(x) (x << 10)
++#define MODE_32BPP_YUV444 0
++#define MODE_24BPP_YUV444 1
++#define MODE_16BPP_YUV422 3
++
++#define VIDEO_CTRL_RC4_TEST_MODE (1 << 9)
++#define VIDEO_CTRL_RC4_RST (1 << 8)
++#define VIDEO_CTRL_RC4_VIDEO_M_SEL (1 << 7) //video management
++#define VIDEO_CTRL_RC4_VIDEO_2_SEL (1 << 6) // Video 2
++
++#define VIDEO_CTRL_DWN_SCALING_MASK (0x3 << 4)
++#define VIDEO_CTRL_DWN_SCALING(x) (x << 4)
++#define DWN_V1 0x1
++#define DWN_V2 0x2
++#define DWN_VM 0x3
++
++
++
++#define VIDEO_CTRL_VSYNC_DELAY_MASK (3 << 2)
++#define VIDEO_CTRL_VSYNC_DELAY(x) (x << 2)
++#define NO_DELAY 0
++#define DELAY_DIV12_HSYNC 1
++#define AUTO_DELAY 2
++
++
++/* AST_VIDEO_INT_EN 0x304 Video interrupt Enable */
++/* AST_VIDEO_INT_STS 0x308 Video interrupt status */
++#define VIDEO_FRAME_COMPLETE (1 << 5)
++#define VIDEO_MODE_DETECT_RDY (1 << 4)
++#define VIDEO_COMPRESS_COMPLETE (1 << 3)
++#define VIDEO_COMPRESS_PKT_COMPLETE (1 << 2)
++#define VIDEO_CAPTURE_COMPLETE (1 << 1)
++#define VIDEO_MODE_DETECT_WDT (1 << 0)
++
++/* AST_VIDEO_MODE_DETECT 0x30C Video Mode Detection Parameter Register */
++#define VIDEO_MODE_HOR_TOLER(x) (x << 28)
++#define VIDEO_MODE_VER_TOLER(x) (x << 24)
++#define VIDEO_MODE_HOR_STABLE(x) (x << 20)
++#define VIDEO_MODE_VER_STABLE(x) (x << 16)
++#define VIDEO_MODE_EDG_THROD(x) (x << 8)
++
++#define MODEDETECTION_VERTICAL_STABLE_MAXIMUM 0x6
++#define MODEDETECTION_HORIZONTAL_STABLE_MAXIMUM 0x6
++#define MODEDETECTION_VERTICAL_STABLE_THRESHOLD 0x2
++#define MODEDETECTION_HORIZONTAL_STABLE_THRESHOLD 0x2
++
++/* AST_VIDEO_SCRATCH_34C 0x34C Video Scratch Remap Read Back */
++#define SCRATCH_VGA_GET_REFLASH_RATE(x) ((x >> 8) & 0xf)
++#define SCRATCH_VGA_GET_COLOR_MODE(x) ((x >> 4) & 0xf)
++
++/* AST_VIDEO_SCRATCH_350 0x350 Video Scratch Remap Read Back */
++#define SCRATCH_VGA_GET_MODE_HEADER(x) ((x >> 8) & 0xff)
++#define SCRATCH_VGA_GET_NEW_COLOR_MODE(x) ((x >> 16) & 0xff)
++#define SCRATCH_VGA_GET_NEW_PIXEL_CLK(x) ((x >> 24) & 0xff)
++
++
++/* AST_VIDEO_SCRATCH_35C 0x35C Video Scratch Remap Read Back */
++#define SCRATCH_VGA_PWR_STS_HSYNC (1 << 31)
++#define SCRATCH_VGA_PWR_STS_VSYNC (1 << 30)
++#define SCRATCH_VGA_ATTRIBTE_INDEX_BIT5 (1 << 29)
++#define SCRATCH_VGA_MASK_REG (1 << 28)
++#define SCRATCH_VGA_CRT_RST (1 << 27)
++#define SCRATCH_VGA_SCREEN_OFF (1 << 26)
++#define SCRATCH_VGA_RESET (1 << 25)
++#define SCRATCH_VGA_ENABLE (1 << 24)
++
++
++#endif
++
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-vuart.h b/arch/arm/plat-aspeed/include/plat/regs-vuart.h
+new file mode 100644
+index 0000000..b4bb88a
+--- /dev/null
++++ b/arch/arm/plat-aspeed/include/plat/regs-vuart.h
+@@ -0,0 +1,39 @@
++/* arch/arm/plat-aspeed/include/mach/regs-iic.h
++ *
++ * Copyright (c) 2012 ASPEED Technology Inc. <ryan_chen@aspeedtech.com>
++ * http://www.aspeedtech.com/
++ *
++ * 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.
++ *
++ * ASPEED VUART Controller
++*/
++
++#ifndef __AST_VUART_H_
++#define __AST_VUART_H_
++
++#define AST_VUART_CTRLA 0x20
++#define AST_VUART_CTRLB 0x24
++#define AST_VUART_ADDRL 0x28
++#define AST_VUART_ADDRH 0x2C
++#define AST_VUART_CTRLE 0x30
++#define AST_VUART_CTRLF 0x34
++#define AST_VUART_CTRLG 0x38
++#define AST_VUART_CTRLH 0x3C
++
++
++
++/* AST_VUART_CTRLA 0x20 */
++#define VUART_ENABLE (1 << 0)
++#define VUART_SIRQ_POLARITY (1 << 1)
++#define VUART_DISABLE_H_TX_DISCARD (1 << 5)
++
++
++/* AST_VUART_CTRLB 0x24 */
++#define SET_SIRQ_NUM(x) (x << 4)
++
++
++
++
++#endif
+diff --git a/arch/arm/plat-aspeed/irq.c b/arch/arm/plat-aspeed/irq.c
+new file mode 100644
+index 0000000..b118359
+--- /dev/null
++++ b/arch/arm/plat-aspeed/irq.c
+@@ -0,0 +1,136 @@
++/*
++ * linux/arch/arm/plat-aspeed/irq.c
++ *
++ * 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 <linux/init.h>
++#include <linux/stddef.h>
++#include <linux/list.h>
++#include <linux/timer.h>
++
++#include <linux/device.h>
++#include <linux/dma-mapping.h>
++#include <linux/platform_device.h>
++#include <linux/sysdev.h>
++#include <linux/interrupt.h>
++#include <linux/irq.h>
++#include <asm/system.h>
++#include <asm/irq.h>
++#include <asm/io.h>
++#include <asm/mach/irq.h>
++#include <mach/hardware.h>
++
++#include <plat/regs-intr.h>
++
++static void ast_mask_irq(unsigned int irq)
++{
++ int i=0;
++ u32 regVal;
++ u8 timer;
++
++#ifdef IRQ_TIMER7
++ if(((irq >= IRQ_TIMER0) && (irq <= IRQ_TIMER2)) || ((i >= IRQ_TIMER3) && (i <= IRQ_TIMER7)))
++ timer = 1;
++
++#else
++ if((irq >= IRQ_TIMER0) && (irq <= IRQ_TIMER2))
++ timer = 1;
++#endif
++
++ if (irq > 32) {
++ i=1;
++ irq = irq - 32;
++ } else
++ i=0;
++
++ regVal = readl(AST_INTR_DIS(i));
++ regVal |= (1 << irq);
++ writel(regVal, AST_INTR_DIS(i));
++
++ /*
++ * clear the interrupt
++ */
++ if(timer)
++ IRQ_EDGE_CLEAR(i,irq);
++
++}
++
++static void ast_unmask_irq(unsigned int irq)
++{
++ int i;
++ u32 regVal;
++
++ if (irq > 32) {
++ i=1;
++ irq = irq - 32;
++ } else
++ i=0;
++
++ regVal = readl(AST_INTR_EN(i));
++ regVal |= (1 << irq);
++ writel(regVal, AST_INTR_EN(i));
++}
++
++static struct irq_chip ast_irq_chip = {
++ .name = "ast_irq",
++ .ack = ast_mask_irq,
++ .mask = ast_mask_irq,
++ .unmask = ast_unmask_irq,
++};
++
++void __init ast_init_irq(void)
++{
++ unsigned int i;
++
++ /* VIC1 */
++ writel(0, AST_INTR_SEL(0));
++ writel(0, AST_INTR_EN(0));
++ writel(0xFFFFFFFF, AST_INTR_DIS(0));
++ writel(0xFFFFFFFF, AST_INTR_EDGE_CLR(0));
++
++#if defined(NEW_VIC)
++ writel(0, AST_INTR_SEL(1));
++ writel(0, AST_INTR_EN(1));
++ writel(0xFFFFFFFF, AST_INTR_DIS(1));
++ writel(0xFFFFFFFF, AST_INTR_EDGE_CLR(1));
++#endif
++
++ //TOTAL IRQ NUM =
++ for (i = 0; i < AST_VIC_NUM; i++)
++ {
++ if(i<32) {
++ if((i >= IRQ_TIMER0) && (i <= IRQ_TIMER2)) //Timer0/1/2
++ IRQ_SET_RISING_EDGE(0,i);
++ else {
++ IRQ_SET_HIGH_LEVEL(0,i);
++ IRQ_SET_LEVEL_TRIGGER(0,i);
++ }
++#ifdef IRQ_TIMER7
++ } else {
++ if((i >= IRQ_TIMER3) && (i <= IRQ_TIMER7)) //Timer3/4/5/6/7
++ IRQ_SET_RISING_EDGE(0,i-32);
++ else {
++ IRQ_SET_HIGH_LEVEL(1,i-32);
++ IRQ_SET_LEVEL_TRIGGER(1,i-32);
++ }
++#endif
++ }
++
++ set_irq_chip(i, &ast_irq_chip);
++ set_irq_handler(i, handle_level_irq);
++ set_irq_flags(i, IRQF_VALID);
++ }
++
++}
+diff --git a/arch/arm/plat-aspeed/timer.c b/arch/arm/plat-aspeed/timer.c
+new file mode 100644
+index 0000000..079d958
+--- /dev/null
++++ b/arch/arm/plat-aspeed/timer.c
+@@ -0,0 +1,137 @@
++/*
++ * timer.c
++ *
++ * 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 <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/device.h>
++#include <linux/spinlock.h>
++#include <linux/interrupt.h>
++#include <linux/sched.h>
++
++#include <linux/irq.h>
++#include <asm/system.h>
++#include <asm/io.h>
++#include <mach/hardware.h>
++#include <mach/irqs.h>
++#include <mach/time.h>
++#include <plat/ast-scu.h>
++
++#define ASPEED_TIMER0_VA_BASE (IO_ADDRESS(AST_TIMER_BASE)+ASPEED_TIMER0_OFFSET)
++#define ASPEED_TIMER1_VA_BASE (IO_ADDRESS(AST_TIMER_BASE)+ASPEED_TIMER1_OFFSET)
++#define ASPEED_TIMER2_VA_BASE (IO_ADDRESS(AST_TIMER_BASE)+ASPEED_TIMER2_OFFSET)
++#define ASPEED_TIMERC_VA_BASE (IO_ADDRESS(AST_TIMER_BASE)+ASPEED_TIMERRC_OFFSET)
++
++/*
++ * Returns number of ms since last clock interrupt. Note that interrupts
++ * will have been disabled by do_gettimeoffset()
++ */
++static unsigned long ast_gettimeoffset(void)
++{
++ volatile TimerStruct_t *timer0 = (TimerStruct_t *) ASPEED_TIMER0_VA_BASE;
++ unsigned long ticks1, ticks2;//, status;
++
++ /*
++ * Get the current number of ticks. Note that there is a race
++ * condition between us reading the timer and checking for
++ * an interrupt. We get around this by ensuring that the
++ * counter has not reloaded between our two reads.
++ */
++ ticks2 = timer0->TimerValue;
++ do {
++ ticks1 = ticks2;
++// status = readl(AST_RAW_STS(0));// __raw_readl(IO_ADDRESS(ASPEED_VIC_BASE) + ASPEED_VIC_RAW_STATUS_OFFSET);
++ ticks2 = timer0->TimerValue;
++ } while (ticks2 > ticks1);
++
++ /*
++ * Number of ticks since last interrupt.
++ */
++ ticks1 = TIMER_RELOAD - ticks2;
++
++ /*
++ * Interrupt pending? If so, we've reloaded once already.
++ */
++// if (status & (1 << IRQ_TIMER0))
++// ticks1 += TIMER_RELOAD;
++
++ /*
++ * Convert the ticks to usecs
++ */
++ return TICKS2USECS(ticks1);
++}
++
++
++/*
++ * IRQ handler for the timer
++ */
++static irqreturn_t
++ast_timer_interrupt(int irq, void *dev_id)
++{
++
++// write_seqlock(&xtime_lock);
++
++ /*
++ * clear the interrupt in Irq.c
++ */
++// IRQ_EDGE_CLEAR(0,IRQ_TIMER0);
++
++ timer_tick();
++
++
++// write_sequnlock(&xtime_lock);
++
++ return IRQ_HANDLED;
++}
++
++static struct irqaction ast_timer_irq = {
++ .name = "ast timer",
++ .flags = IRQF_DISABLED | IRQF_TIMER,
++ .handler = ast_timer_interrupt,
++};
++
++/*
++ * Set up timer interrupt, and return the current time in seconds.
++ */
++static void __init ast_setup_timer(void)
++{
++ volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *) ASPEED_TIMER0_VA_BASE;
++ volatile __u32 *timerc = (volatile __u32*) ASPEED_TIMERC_VA_BASE;
++
++ /*
++ * Initialise to a known state (all timers off)
++ */
++ *timerc = 0;
++
++ timer0->TimerLoad = TIMER_RELOAD - 1;
++ timer0->TimerValue = TIMER_RELOAD - 1;
++ *timerc = TIMER0_ENABLE | TIMER0_RefExt;
++
++ /*
++ * Make irqs happen for the system timer
++ */
++ ast_scu_show_system_info();
++
++ setup_irq(IRQ_TIMER0, &ast_timer_irq);
++
++}
++
++struct sys_timer ast_timer = {
++ .init = ast_setup_timer,
++// .offset = ast_gettimeoffset,
++};
+diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
+index 43aa202..d2bf539 100644
+--- a/arch/arm/tools/mach-types
++++ b/arch/arm/tools/mach-types
+@@ -1899,3 +1899,4 @@ rut100 MACH_RUT100 RUT100 1908
+ asusp535 MACH_ASUSP535 ASUSP535 1909
+ htcraphael MACH_HTCRAPHAEL HTCRAPHAEL 1910
+ sygdg1 MACH_SYGDG1 SYGDG1 1911
++aspeed MACH_ASPEED ASPEED 8888
+diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
+index 43d6ba8..a714292 100644
+--- a/drivers/char/Kconfig
++++ b/drivers/char/Kconfig
+@@ -665,6 +665,7 @@ config IBM_BSR
+ between several cores on a system
+
+ source "drivers/char/ipmi/Kconfig"
++source "drivers/char/aspeed/Kconfig"
+
+ config DS1620
+ tristate "NetWinder thermometer support"
+diff --git a/drivers/char/Makefile b/drivers/char/Makefile
+index 438f713..ee197cb 100644
+--- a/drivers/char/Makefile
++++ b/drivers/char/Makefile
+@@ -85,6 +85,7 @@ obj-$(CONFIG_TOSHIBA) += toshiba.o
+ obj-$(CONFIG_I8K) += i8k.o
+ obj-$(CONFIG_DS1620) += ds1620.o
+ obj-$(CONFIG_HW_RANDOM) += hw_random/
++obj-$(CONFIG_AST_MISC) += aspeed/
+ obj-$(CONFIG_PPDEV) += ppdev.o
+ obj-$(CONFIG_NWBUTTON) += nwbutton.o
+ obj-$(CONFIG_NWFLASH) += nwflash.o
+diff --git a/drivers/char/aspeed/Kconfig b/drivers/char/aspeed/Kconfig
+new file mode 100644
+index 0000000..7aee8d3
+--- /dev/null
++++ b/drivers/char/aspeed/Kconfig
+@@ -0,0 +1,52 @@
++#
++# MISC configuration for ASPEED SOCs
++#
++
++if ARCH_ASPEED
++menuconfig AST_MISC
++ tristate 'MISC drivers for ASPEED SOCs'
++ help
++ We can select misc drivers for ASPEED SOC in this sub-function.
++
++if AST_MISC
++config AST_VIDEO
++ tristate "ASPEED Video Engine driver"
++ default n
++ help
++ Driver for AST Video Engine
++
++config ADC_CAT9883
++ tristate "CAT 9883 ADC driver"
++ default n
++ help
++ Driver for CAT 9883
++
++config AST_SPI_BIOS
++ tristate "ASPEED SPI BIOS flash register"
++ default n
++ help
++ Driver for SPI BIOS flash register
++
++config AST_PECI
++ tristate "ASPEED PECI Controller"
++ default n
++ help
++ Driver for PECI Controller
++
++config AST_KCS
++ tristate 'ASPEED KCS support'
++ help
++ Support for the KCS channels on the ASPEED chips,
++ providing /dev/kcs0, 1 and 2 (note, some machines may not
++ provide all of these ports, depending on how the serial port
++ pins are configured.
++
++config AST_GPIO
++ tristate "ASPEED GPIO Controller"
++ default n
++ help
++ Driver for GPIO Controller included in ASPEED SOCs.
++
++endif # CONFIG_AST_MISC
++endif # CONFIG_AST
++
+diff --git a/drivers/char/aspeed/Makefile b/drivers/char/aspeed/Makefile
+new file mode 100644
+index 0000000..517b2b7
+--- /dev/null
++++ b/drivers/char/aspeed/Makefile
+@@ -0,0 +1,9 @@
++#
++# Makefile for the ASPEED drivers.
++#
++
++obj-$(CONFIG_AST_VIDEO) += ast_video.o
++obj-$(CONFIG_ADC_CAT9883) += adc_cat9883.o
++obj-$(CONFIG_AST_KCS) += ast_kcs.o
++obj-$(CONFIG_AST_GPIO) += ast_gpio.o
++obj-$(CONFIG_AST_PECI) += ast_peci.o
+diff --git a/drivers/char/aspeed/ast_peci.c b/drivers/char/aspeed/ast_peci.c
+new file mode 100644
+index 0000000..1f7cae3
+--- /dev/null
++++ b/drivers/char/aspeed/ast_peci.c
+@@ -0,0 +1,508 @@
++/********************************************************************************
++* File Name : ast_peci.c
++* Author : Ryan Chen
++* Description : AST PECI Controller
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++*
++* Version : 1.0
++* History :
++* 1. 2013/01/30 Ryan Chen create this file
++*
++********************************************************************************/
++
++#include <linux/module.h>
++#include <linux/fs.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/types.h>
++#include <linux/interrupt.h>
++#include <asm/uaccess.h>
++
++#include <asm/io.h>
++#include <linux/delay.h>
++#include <linux/miscdevice.h>
++#ifdef CONFIG_COLDFIRE
++#include <asm/arch/regs-peci.h>
++#else
++#include <plat/regs-peci.h>
++#endif
++
++//#define CONFIG_AST_PECI_DEBUG
++
++#ifdef CONFIG_AST_PECI_DEBUG
++ #define PECI_DBG(fmt, args...) printk("%s(): " fmt, __FUNCTION__, ## args)
++#else
++ #define PECI_DBG(fmt, args...)
++#endif
++
++/***********************************************************************/
++struct timing_negotiation {
++ u8 msg_timing;
++ u8 addr_timing;
++};
++
++struct xfer_msg {
++ u8 client_addr;
++ u8 tx_len;
++ u8 rx_len;
++ u8 tx_fcs;
++ u8 rx_fcs;
++ u8 fcs_en;
++ u8 sw_fcs;
++ u8 *tx_buf;
++ u8 *rx_buf;
++ u32 sts;
++};
++
++#define PECI_DEVICE "/dev/ast-peci"
++
++//IOCTL ..
++#define PECIIOC_BASE 'P'
++
++#define AST_PECI_IOCRTIMING _IOR(PECIIOC_BASE, 0, struct timing_negotiation*)
++#define AST_PECI_IOCWTIMING _IOW(PECIIOC_BASE, 1, struct timing_negotiation*)
++#define AST_PECI_IOCXFER _IOWR(PECIIOC_BASE, 2, struct xfer_msg*)
++
++
++/***********************************************************************/
++
++static struct ast_peci_data {
++ struct device *misc_dev;
++ void __iomem *reg_base; /* virtual */
++ int irq; //PECI IRQ number
++ int open_count;
++ struct completion xfer_complete;
++ u32 sts;
++ struct mutex lock;
++} ast_peci;
++
++static inline void
++ast_peci_write(u32 val, u32 reg)
++{
++ PECI_DBG("write offset: %x, val: %x \n",reg,val);
++ writel(val, ast_peci.reg_base + reg);
++}
++
++static inline u32
++ast_peci_read(u32 reg)
++{
++ u32 val = readl(ast_peci.reg_base + reg);
++ PECI_DBG("read offset: %x, val: %x \n",reg,val);
++ return val;
++}
++
++static long ast_peci_ioctl(struct file *fp,
++ unsigned int cmd, unsigned long arg)
++{
++ long ret = 0;
++ void __user *argp = (void __user *)arg;
++ struct xfer_msg msg;
++ struct timing_negotiation tim_ng;
++ u32 peci_head;
++ int i=0;
++ u32 *tx_buf0 = (u32 *) (ast_peci.reg_base + AST_PECI_W_DATA0);
++ u32 *tx_buf1 = (u32 *) (ast_peci.reg_base + AST_PECI_W_DATA4);
++ u32 *rx_buf0 = (u32 *) (ast_peci.reg_base + AST_PECI_R_DATA0);
++ u32 *rx_buf1 = (u32 *) (ast_peci.reg_base + AST_PECI_R_DATA4);
++ u32 rx_data;
++
++ PECI_DBG("ast_peci_ioctl cmd %x \n", cmd);
++
++ switch(cmd) {
++ case AST_PECI_IOCRTIMING:
++ tim_ng.msg_timing = PECI_TIMING_MESSAGE_GET(ast_peci_read(AST_PECI_TIMING));
++ tim_ng.addr_timing = PECI_TIMING_ADDRESS_GET(ast_peci_read(AST_PECI_TIMING));
++ if (copy_to_user(argp, &tim_ng, sizeof(struct timing_negotiation)))
++ ret = -EFAULT;
++ break;
++
++ case AST_PECI_IOCWTIMING:
++ if (copy_from_user(&tim_ng, argp, sizeof(struct timing_negotiation))) {
++ ret = -EFAULT;
++ } else {
++ ast_peci_write(PECI_TIMING_MESSAGE(tim_ng.msg_timing) |
++ PECI_TIMING_ADDRESS(tim_ng.addr_timing), AST_PECI_TIMING);
++ }
++ break;
++
++ case AST_PECI_IOCXFER:
++ //Check cmd operation sts
++ while(ast_peci_read(AST_PECI_CMD) & PECI_CMD_FIRE) {
++ printk("wait for free \n");
++ };
++
++ if (copy_from_user(&msg, argp, sizeof(struct xfer_msg))) {
++ ret = -EFAULT;
++ break;
++ }
++
++#ifdef CONFIG_AST_PECI_DEBUG
++ printk("fcs_en %d, client_addr %x, tx_len %d, rx_len %d",msg.fcs_en ,msg.client_addr, msg.tx_len, msg.rx_len);
++ printk("\ntx_buf : ");
++ for(i = 0;i< msg.tx_len; i++)
++ printk(" %x ",msg.tx_buf[i]);
++ printk("\n");
++#endif
++
++ if(msg.fcs_en)
++ peci_head = PECI_TAGET_ADDR(msg.client_addr) |
++ PECI_WRITE_LEN(msg.tx_len) |
++ PECI_READ_LEN(msg.rx_len) | PECI_AW_FCS_EN;
++ else
++ peci_head = PECI_TAGET_ADDR(msg.client_addr) |
++ PECI_WRITE_LEN(msg.tx_len) |
++ PECI_READ_LEN(msg.rx_len);
++
++
++ ast_peci_write(peci_head, AST_PECI_CMD_CTRL);
++
++ for(i = 0; i < msg.tx_len; i++) {
++ if(i < 16) {
++ if(i%4 == 0)
++ tx_buf0[i/4] = 0;
++ tx_buf0[i/4] |= (msg.tx_buf[i] << ((i%4)*8)) ;
++ } else {
++ if(i%4 == 0)
++ tx_buf1[i/4] = 0;
++ tx_buf1[i/4] |= (msg.tx_buf[i] << ((i%4)*8)) ;
++ }
++ }
++
++#ifdef CONFIG_AST_PECI_DEBUG
++ printk("\nWD \n ");
++ ast_peci_read(AST_PECI_W_DATA0);
++ ast_peci_read(AST_PECI_W_DATA1);
++ ast_peci_read(AST_PECI_W_DATA2);
++ ast_peci_read(AST_PECI_W_DATA3);
++ ast_peci_read(AST_PECI_W_DATA4);
++ ast_peci_read(AST_PECI_W_DATA5);
++ ast_peci_read(AST_PECI_W_DATA6);
++ ast_peci_read(AST_PECI_W_DATA7);
++#endif
++ init_completion(&ast_peci.xfer_complete);
++ //Fire Command
++ ast_peci_write(PECI_CMD_FIRE, AST_PECI_CMD);
++
++
++ ret = wait_for_completion_interruptible_timeout(&ast_peci.xfer_complete, 30*HZ);
++
++ if (ret == 0)
++ printk("peci controller timed out\n");
++
++ for(i = 0; i < msg.rx_len; i++) {
++ if(i < 16) {
++ switch(i%4) {
++ case 0:
++ rx_data = rx_buf0[i/4];
++
++ msg.rx_buf[i] = rx_data & 0xff;
++ break;
++ case 1:
++ msg.rx_buf[i] = (rx_data & 0xff00) >> 8;
++ break;
++ case 2:
++ msg.rx_buf[i] = (rx_data & 0xff0000) >> 16;
++ break;
++ case 3:
++ msg.rx_buf[i] = (rx_data & 0xff000000) >> 24;
++ break;
++
++ }
++ } else {
++ switch(i%4) {
++ case 0:
++ rx_data = rx_buf1[i/4];
++ msg.rx_buf[i] = rx_data & 0xff;
++ break;
++ case 1:
++ msg.rx_buf[i] = (rx_data & 0xff00) >> 8;
++ break;
++ case 2:
++ msg.rx_buf[i] = (rx_data & 0xff0000) >> 16;
++ break;
++ case 3:
++ msg.rx_buf[i] = (rx_data & 0xff000000) >> 24;
++ break;
++
++ }
++ }
++ }
++#ifdef CONFIG_AST_PECI_DEBUG
++ printk("\nRD \n");
++ ast_peci_read(AST_PECI_R_DATA0);
++ ast_peci_read(AST_PECI_R_DATA1);
++ ast_peci_read(AST_PECI_R_DATA2);
++ ast_peci_read(AST_PECI_R_DATA3);
++ ast_peci_read(AST_PECI_R_DATA4);
++ ast_peci_read(AST_PECI_R_DATA5);
++ ast_peci_read(AST_PECI_R_DATA6);
++ ast_peci_read(AST_PECI_R_DATA7);
++
++ printk("rx_buf : ");
++ for(i = 0;i< msg.rx_len; i++)
++ printk("%x ",msg.rx_buf[i]);
++ printk("\n");
++#endif
++ msg.sts = ast_peci.sts;
++ msg.rx_fcs = PECI_CAPTURE_READ_FCS(ast_peci_read(AST_PECI_CAP_FCS));
++ if (copy_to_user(argp, &msg, sizeof(struct xfer_msg)))
++ ret = -EFAULT;
++
++ break;
++ default:
++ printk("ast_peci_ioctl command fail\n");
++ ret = -ENOTTY;
++ break;
++ }
++
++ return ret;
++}
++
++static int ast_peci_open(struct inode *inode, struct file *file)
++{
++ PECI_DBG("ast_peci_open\n");
++
++
++ /* Flush input queue on first open */
++ if (ast_peci.open_count)
++ return -1;
++
++ ast_peci.open_count++;
++
++
++ return 0;
++}
++
++static int ast_peci_release(struct inode *inode, struct file *file)
++{
++ PECI_DBG("ast_peci_release\n");
++ ast_peci.open_count--;
++
++ return 0;
++}
++
++static irqreturn_t ast_peci_handler(int this_irq, void *dev_id)
++{
++ ast_peci.sts = (0x1f & ast_peci_read(AST_PECI_INT_STS));
++
++ switch(ast_peci.sts) {
++ case PECI_INT_TIMEOUT:
++ printk("PECI_INT_TIMEOUT \n");
++ ast_peci_write(PECI_INT_TIMEOUT, AST_PECI_INT_STS);
++ break;
++ case PECI_INT_CONNECT:
++ printk("PECI_INT_CONNECT \n");
++ ast_peci_write(PECI_INT_CONNECT, AST_PECI_INT_STS);
++ break;
++ case PECI_INT_W_FCS_BAD:
++ printk("PECI_INT_W_FCS_BAD \n");
++ ast_peci_write(PECI_INT_W_FCS_BAD, AST_PECI_INT_STS);
++ break;
++ case PECI_INT_W_FCS_ABORT:
++ printk("PECI_INT_W_FCS_ABORT \n");
++ ast_peci_write(PECI_INT_W_FCS_ABORT, AST_PECI_INT_STS);
++ break;
++ case PECI_INT_CMD_DONE:
++ printk("PECI_INT_CMD_DONE \n");
++ ast_peci_write(PECI_INT_CMD_DONE, AST_PECI_INT_STS);
++ ast_peci_write(0, AST_PECI_CMD);
++ break;
++ default:
++ printk("no one handle .... \n");
++ break;
++
++ }
++
++ complete(&ast_peci.xfer_complete);
++
++ return IRQ_HANDLED;
++
++}
++
++static void ast_peci_ctrl_init(void)
++{
++ //PECI Timing Setting : should 4 times of peci clk period 64 = 16 * 4 ??
++ ast_peci_write(PECI_TIMING_MESSAGE(64) | PECI_TIMING_ADDRESS(64), AST_PECI_TIMING);
++
++
++ //PECI Programmable AWFCS
++ //ast_peci_write(ast_peci, PECI_PROGRAM_AW_FCS, AST_PECI_EXP_FCS);
++
++ //TODO .....
++ //Clear Interrupt
++ ast_peci_write(PECI_INT_TIMEOUT | PECI_INT_CONNECT |
++ PECI_INT_W_FCS_BAD | PECI_INT_W_FCS_ABORT |
++ PECI_INT_CMD_DONE, AST_PECI_INT_STS);
++
++ //PECI Negotiation Selection , interrupt enable
++ //Set nego mode : 1st bit of addr negotiation
++ ast_peci_write(PECI_INT_TIMEOUT | PECI_INT_CONNECT |
++ PECI_INT_W_FCS_BAD | PECI_INT_W_FCS_ABORT |
++ PECI_INT_CMD_DONE, AST_PECI_INT_CTRL);
++
++ //PECI Spec wide speed rangs [2kbps~2Mbps]
++ //Sampling 8/16, READ mode : Point Sampling , CLK source : 24Mhz , DIV by 8 : 3 --> CLK is 3Mhz
++ //PECI CTRL Enable
++
++ ast_peci_write(PECI_CTRL_SAMPLING(8) | PECI_CTRL_CLK_DIV(3) |
++ PECI_CTRL_PECI_EN |
++ PECI_CTRL_PECI_CLK_EN, AST_PECI_CTRL);
++}
++
++static const struct file_operations ast_peci_fops = {
++ .owner = THIS_MODULE,
++ .llseek = no_llseek,
++ .unlocked_ioctl = ast_peci_ioctl,
++ .open = ast_peci_open,
++ .release = ast_peci_release,
++};
++
++struct miscdevice ast_peci_misc = {
++ .minor = MISC_DYNAMIC_MINOR,
++ .name = "ast-peci",
++ .fops = &ast_peci_fops,
++};
++
++static int ast_peci_probe(struct platform_device *pdev)
++{
++ struct resource *res;
++ int ret=0;
++
++
++ PECI_DBG("ast_peci_probe\n");
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (NULL == res) {
++ dev_err(&pdev->dev, "cannot get IORESOURCE_MEM\n");
++ ret = -ENOENT;
++ goto out;
++ }
++
++ if (!request_mem_region(res->start, resource_size(res), res->name)) {
++ dev_err(&pdev->dev, "cannot reserved region\n");
++ ret = -ENXIO;
++ goto out;
++ }
++
++ ast_peci.reg_base = ioremap(res->start, resource_size(res));
++ if (!ast_peci.reg_base) {
++ ret = -EIO;
++ goto out_region;
++ }
++
++ ast_peci.irq = platform_get_irq(pdev, 0);
++ if (ast_peci.irq < 0) {
++ dev_err(&pdev->dev, "no irq specified\n");
++ ret = -ENOENT;
++ goto out_region;
++ }
++
++ ret = request_irq(ast_peci.irq, ast_peci_handler, IRQF_SHARED,
++ "ast-peci", &ast_peci);
++
++ if (ret) {
++ printk(KERN_INFO "PECI: Failed request irq %d\n", ast_peci.irq);
++ goto out_region;
++ }
++
++ ret = misc_register(&ast_peci_misc);
++ if (ret){
++ printk(KERN_ERR "PECI : failed to request interrupt\n");
++ goto out_irq;
++ }
++
++ ast_peci_ctrl_init();
++
++ printk(KERN_INFO "ast_peci: driver successfully loaded.\n");
++
++ return 0;
++
++
++out_irq:
++ free_irq(ast_peci.irq, NULL);
++out_region:
++ release_mem_region(res->start, res->end - res->start + 1);
++out:
++ printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
++ return ret;
++}
++
++static int ast_peci_remove(struct platform_device *pdev)
++{
++ struct resource *res;
++
++ PECI_DBG("ast_peci_remove\n");
++
++ misc_deregister(&ast_peci_misc);
++
++ free_irq(ast_peci.irq, &ast_peci);
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++
++ iounmap(ast_peci.reg_base);
++
++ release_mem_region(res->start, res->end - res->start + 1);
++
++ return 0;
++}
++
++#ifdef CONFIG_PM
++static int
++ast_peci_suspend(struct platform_device *pdev, pm_message_t state)
++{
++ printk("ast_peci_suspend : TODO \n");
++ return 0;
++}
++
++static int
++ast_peci_resume(struct platform_device *pdev)
++{
++ ast_peci_ctrl_init();
++ return 0;
++}
++
++#else
++#define ast_peci_suspend NULL
++#define ast_peci_resume NULL
++#endif
++
++static struct platform_driver ast_peci_driver = {
++ .probe = ast_peci_probe,
++ .remove = __devexit_p(ast_peci_remove),
++ .suspend = ast_peci_suspend,
++ .resume = ast_peci_resume,
++ .driver = {
++ .name = "ast_peci",
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init
++ast_peci_init(void)
++{
++ return platform_driver_register(&ast_peci_driver);
++}
++
++static void __exit
++ast_peci_exit(void)
++{
++ platform_driver_unregister(&ast_peci_driver);
++}
++
++module_init(ast_peci_init);
++module_exit(ast_peci_exit);
++
++MODULE_AUTHOR("Ryan Chen <ryan_chen@aspeedtech.com>");
++MODULE_DESCRIPTION("PECI driver");
++MODULE_LICENSE("GPL");
++
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+index a4424c8..1963ba6 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -265,9 +265,13 @@ static ssize_t gpio_value_store(struct device *dev,
+
+ if (!test_bit(FLAG_EXPORT, &desc->flags))
+ status = -EIO;
+- else if (!test_bit(FLAG_IS_OUT, &desc->flags))
++#if 0 //Ryan Modify for AST GPIO Feature
++ else if (!test_bit(FLAG_IS_OUT, &desc->flags)) {
+ status = -EPERM;
++ } else {
++#else
+ else {
++#endif
+ long value;
+
+ status = strict_strtol(buf, 0, &value);
+diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
+index c709e82..681782b 100644
+--- a/drivers/hwmon/Kconfig
++++ b/drivers/hwmon/Kconfig
+@@ -854,6 +854,22 @@ config SENSORS_LIS3LV02D
+ This driver can also be built as a module. If so, the module
+ will be called lis3lv02d.
+
++config SENSORS_AST_ADC
++ tristate "ASPEED ADC Controller Driver"
++ depends on ARCH_ASPEED
++ default n
++ help
++ This driver provides support for the ASPEED ADC
++ Controller, which provides an Voltage Sensor.
++
++config SENSORS_AST_PWM_FAN
++ tristate "ASPEED PWM & FAN Tacho Controller Driver"
++ depends on ARCH_ASPEED
++ default n
++ help
++ This driver provides support for the ASPEED PWM & FAN Tacho
++ Controller, which provides an Sensor, fan control.
++
+ config SENSORS_APPLESMC
+ tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)"
+ depends on INPUT && X86
+diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
+index 58fc5be..5629727 100644
+--- a/drivers/hwmon/Makefile
++++ b/drivers/hwmon/Makefile
+@@ -29,6 +29,8 @@ obj-$(CONFIG_SENSORS_ADT7462) += adt7462.o
+ obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o
+ obj-$(CONFIG_SENSORS_ADT7473) += adt7473.o
+ obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o
++obj-$(CONFIG_SENSORS_AST_ADC) += ast_adc.o
++obj-$(CONFIG_SENSORS_AST_PWM_FAN) += ast_pwm_fan.o
+ obj-$(CONFIG_SENSORS_AMS) += ams/
+ obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o
+ obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o
+diff --git a/drivers/hwmon/ast_adc.c b/drivers/hwmon/ast_adc.c
+new file mode 100644
+index 0000000..0969e39
+--- /dev/null
++++ b/drivers/hwmon/ast_adc.c
+@@ -0,0 +1,734 @@
++/*
++ * ast_adc.c
++ *
++ * ASPEED ADC controller driver
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * 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.
++ *
++ * History:
++ * 2012.11.26: Initial version [Ryan Chen]
++ */
++
++/* attr ADC sysfs 0~max adc channel
++* 0 - show/store enable
++* 3 - show value
++* 1 - show/store alarm_en set enable
++* 2 - show alarm get statuse
++* 4 - show/store upper
++* 5 - show/store lower */
++
++
++#include <linux/delay.h>
++#include <linux/platform_device.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/timer.h>
++#include <linux/mutex.h>
++#include <linux/hwmon-sysfs.h>
++#include <linux/hwmon.h>
++#include <linux/workqueue.h>
++#include <linux/sysfs.h>
++#include <linux/err.h>
++
++#include <mach/hardware.h>
++#include <asm/irq.h>
++#include <asm/io.h>
++
++#include <plat/regs-adc.h>
++#include <plat/ast-scu.h>
++
++
++#define REST_DESIGN 0
++
++struct adc_vcc_ref_data {
++ int v2;
++ int r1;
++ int r2;
++};
++
++static struct adc_vcc_ref_data adc_vcc_ref[5] = {
++ [0] = {
++ .v2 = 0,
++ .r1 = 5600,
++ .r2 = 1000,
++ },
++ [1] = {
++ .v2 = -12,
++ .r1 = 1000,
++ .r2 = 10000,
++ },
++ [2] = {
++ .v2 = 0,
++ .r1 = 1800,
++ .r2 = 1000,
++ },
++ [3] = {
++ .v2 = -5,
++ .r1 = 2200,
++ .r2 = 10000,
++ },
++ [4] = {
++ .v2 = 0,
++ .r1 = 56000,
++ .r2 = 1000,
++ },
++};
++
++struct ast_adc_data {
++ struct device *hwmon_dev;
++ void __iomem *reg_base; /* virtual */
++ int irq; //ADC IRQ number
++ int compen_value; //Compensating value
++};
++
++struct ast_adc_data *ast_adc;
++
++static u8 ast_get_adc_en(struct ast_adc_data *ast_adc, u8 adc_ch);
++
++
++static inline void
++ast_adc_write(struct ast_adc_data *ast_adc, u32 val, u32 reg)
++{
++// printk("write offset: %x, val: %x \n",reg,val);
++ writel(val, ast_adc->reg_base+ reg);
++}
++
++static inline u32
++ast_adc_read(struct ast_adc_data *ast_adc, u32 reg)
++{
++ u32 val = readl(ast_adc->reg_base + reg);
++// printk("read offset: %x, val: %x \n",reg,val);
++ return val;
++}
++
++static void ast_adc_ctrl_init(void)
++{
++ u32 pclk;
++ ast_adc_write(ast_adc, AST_ADC_CTRL_COMPEN | AST_ADC_CTRL_NORMAL | AST_ADC_CTRL_EN, AST_ADC_CTRL);
++
++ //Set wait a sensing cycle t (s) = 1000 * 12 * (1/PCLK) * 2 * (ADC0c[31:17] + 1) * (ADC0c[9:0] +1)
++ //ex : pclk = 48Mhz , ADC0c[31:17] = 0, ADC0c[9:0] = 0x40 : 64, ADC0c[31:17] = 0x3e7 : 999
++ // --> 0.0325s = 12 * 2 * (0x3e7 + 1) *(64+1) / 48000000
++ // --> 0.0005s = 12 * 2 * (0x3e7 + 1) / 48000000
++
++ pclk = ast_get_pclk();
++
++#if defined(CONFIG_ARCH_AST2300)
++ ast_adc_write(ast_adc, 0x3e7, AST_ADC_CLK);
++
++ ast_adc_write(ast_adc, AST_ADC_CTRL_CH12_EN | AST_ADC_CTRL_COMPEN_CLR| ast_adc_read(ast_adc, AST_ADC_CTRL), AST_ADC_CTRL);
++
++ mdelay(50);
++
++ //compensating value = 0x200 - ADC10[9:0]
++ if(ast_adc_read(ast_adc, AST_ADC_CH12_13) & (0x1 << 8))
++ ast_adc->compen_value = 0x200 - (ast_adc_read(ast_adc, AST_ADC_CH12_13) & AST_ADC_L_CH_MASK);
++ else
++ ast_adc->compen_value = 0 - (ast_adc_read(ast_adc, AST_ADC_CH12_13) & AST_ADC_L_CH_MASK);
++
++ printk("compensating value %d \n",ast_adc->compen_value);
++
++#elif defined(CONFIG_ARCH_AST2400)
++
++ //For AST2400 A0 workaround ... ADC0c = 1 ;
++// ast_adc_write(ast_adc, 1, AST_ADC_CLK);
++// ast_adc_write(ast_adc, (0x3e7<< 17) | 0x40, AST_ADC_CLK);
++ ast_adc_write(ast_adc, 0x40, AST_ADC_CLK);
++
++ ast_adc_write(ast_adc, AST_ADC_CTRL_CH0_EN | AST_ADC_CTRL_COMPEN | AST_ADC_CTRL_NORMAL | AST_ADC_CTRL_EN, AST_ADC_CTRL);
++
++ ast_adc_read(ast_adc, AST_ADC_CTRL);
++
++ mdelay(1);
++
++ //compensating value = 0x200 - ADC10[9:0]
++ ast_adc->compen_value = 0x200 - (ast_adc_read(ast_adc, AST_ADC_CH0_1) & AST_ADC_L_CH_MASK);
++ printk("compensating value %d \n",ast_adc->compen_value);
++
++#elif defined(CONFIG_ARCH_AST2500)
++// TODO ...
++// scu read trim
++// write trim 0xc4 [3:0]
++
++ ast_adc_write(ast_adc, 0x40, AST_ADC_CLK);
++
++ ast_adc_write(ast_adc, AST_ADC_CTRL_NORMAL | AST_ADC_CTRL_EN, AST_ADC_CTRL);
++
++ while(!ast_adc_read(ast_adc, AST_ADC_CTRL) & 0x100);
++
++ ast_adc_write(ast_adc, AST_ADC_CTRL_COMPEN | AST_ADC_CTRL_NORMAL | AST_ADC_CTRL_EN, AST_ADC_CTRL);
++
++ while(ast_adc_read(ast_adc, AST_ADC_CTRL) & AST_ADC_CTRL_COMPEN);
++
++ //compensating value = 0x200 - ADC10[9:0]
++ ast_adc->compen_value = 0x200 - ((ast_adc_read(ast_adc, AST_ADC_TRIM) >> 16) & 0x3ff);
++ printk("compensating value %d \n",ast_adc->compen_value);
++
++#else
++#err "No define for ADC "
++#endif
++
++ ast_adc_write(ast_adc, AST_ADC_CTRL_NORMAL | AST_ADC_CTRL_EN, AST_ADC_CTRL);
++
++}
++
++static u16
++ast_get_adc_hyster_lower(struct ast_adc_data *ast_adc, u8 adc_ch)
++{
++ u16 tmp=0;
++ tmp = ast_adc_read(ast_adc, AST_ADC_HYSTER0 + (adc_ch *4)) & AST_ADC_L_BOUND;
++
++// printk("read val = %d \n",tmp);
++
++ return tmp;
++
++}
++
++static void
++ast_set_adc_hyster_lower(struct ast_adc_data *ast_adc, u8 adc_ch, u16 value)
++{
++ ast_adc_write(ast_adc,
++ (ast_adc_read(ast_adc, AST_ADC_HYSTER0 + (adc_ch *4)) & ~AST_ADC_L_BOUND) |
++ value,
++ AST_ADC_HYSTER0 + (adc_ch *4));
++
++}
++
++static u16
++ast_get_adc_hyster_upper(struct ast_adc_data *ast_adc, u8 adc_ch)
++{
++ u16 tmp=0;
++ tmp = ((ast_adc_read(ast_adc, AST_ADC_HYSTER0 + (adc_ch *4)) & AST_ADC_H_BOUND) >> 16);
++
++// printk("read val = %d \n",tmp);
++
++ return tmp;
++}
++
++static void
++ast_set_adc_hyster_upper(struct ast_adc_data *ast_adc, u8 adc_ch, u32 value)
++{
++ ast_adc_write(ast_adc,
++ (ast_adc_read(ast_adc, AST_ADC_HYSTER0 + (adc_ch *4)) & ~AST_ADC_H_BOUND) |
++ (value << 16),
++ AST_ADC_HYSTER0 + (adc_ch *4));
++
++}
++
++static u8
++ast_get_adc_hyster_en(struct ast_adc_data *ast_adc, u8 adc_ch)
++{
++ //tacho source
++ if(ast_adc_read(ast_adc, AST_ADC_HYSTER0 + (adc_ch *4)) & AST_ADC_HYSTER_EN)
++ return 1;
++ else
++ return 0;
++}
++
++static void
++ast_set_adc_hyster_en(struct ast_adc_data *ast_adc, u8 adc_ch, u8 enable)
++{
++ //tacho source
++ if(enable == 1)
++ ast_adc_write(ast_adc,
++ ast_adc_read(ast_adc, AST_ADC_HYSTER0 + (adc_ch *4)) | AST_ADC_HYSTER_EN,
++ AST_ADC_HYSTER0 + (adc_ch *4));
++ else
++ ast_adc_write(ast_adc,
++ ast_adc_read(ast_adc, AST_ADC_HYSTER0 + (adc_ch *4)) & ~AST_ADC_HYSTER_EN,
++ AST_ADC_HYSTER0 + (adc_ch *4));
++}
++
++static u16
++ast_get_adc_lower(struct ast_adc_data *ast_adc, u8 adc_ch)
++{
++ u16 tmp=0;
++ tmp = ast_adc_read(ast_adc, AST_ADC_BOUND0 + (adc_ch *4)) & AST_ADC_L_BOUND;
++
++// printk("read val = %d \n",tmp);
++
++ return tmp;
++
++}
++
++static void
++ast_set_adc_lower(struct ast_adc_data *ast_adc, u8 adc_ch, u16 value)
++{
++ ast_adc_write(ast_adc,
++ (ast_adc_read(ast_adc, AST_ADC_BOUND0 + (adc_ch *4)) & ~AST_ADC_L_BOUND) |
++ value,
++ AST_ADC_BOUND0 + (adc_ch *4));
++
++}
++
++static u16
++ast_get_adc_upper(struct ast_adc_data *ast_adc, u8 adc_ch)
++{
++ u16 tmp=0;
++ tmp = ((ast_adc_read(ast_adc, AST_ADC_BOUND0 + (adc_ch *4)) & AST_ADC_H_BOUND) >> 16);
++
++ printk("read val = %d \n",tmp);
++
++ return tmp;
++
++
++}
++
++static void
++ast_set_adc_upper(struct ast_adc_data *ast_adc, u8 adc_ch, u32 value)
++{
++ ast_adc_write(ast_adc,
++ (ast_adc_read(ast_adc, AST_ADC_BOUND0 + (adc_ch *4)) & ~AST_ADC_H_BOUND) |
++ (value << 16),
++ AST_ADC_BOUND0 + (adc_ch *4));
++
++}
++
++
++static u8
++ast_get_adc_alarm(struct ast_adc_data *ast_adc, u8 adc_ch)
++{
++ //adc ch source
++ if(ast_adc_read(ast_adc, AST_ADC_IER) & (0x1 << adc_ch))
++ return 1;
++ else
++ return 0;
++}
++
++static u16
++ast_get_adc_value(struct ast_adc_data *ast_adc, u8 adc_ch)
++{
++ int tmp;
++
++ switch(adc_ch) {
++ case 0:
++ tmp = ast_adc_read(ast_adc, AST_ADC_CH0_1) & AST_ADC_L_CH_MASK;
++ break;
++ case 1:
++ tmp = (ast_adc_read(ast_adc, AST_ADC_CH0_1) & AST_ADC_H_CH_MASK) >> 16;
++ break;
++ case 2:
++ tmp = ast_adc_read(ast_adc, AST_ADC_CH2_3) & AST_ADC_L_CH_MASK;
++ break;
++ case 3:
++ tmp = (ast_adc_read(ast_adc, AST_ADC_CH2_3) & AST_ADC_H_CH_MASK) >> 16;
++ break;
++ case 4:
++ tmp = ast_adc_read(ast_adc, AST_ADC_CH4_5) & AST_ADC_L_CH_MASK;
++ break;
++ case 5:
++ tmp = (ast_adc_read(ast_adc, AST_ADC_CH4_5) & AST_ADC_H_CH_MASK) >> 16;
++ break;
++ case 6:
++ tmp = ast_adc_read(ast_adc, AST_ADC_CH6_7) & AST_ADC_L_CH_MASK;
++ break;
++ case 7:
++ tmp = (ast_adc_read(ast_adc, AST_ADC_CH6_7) & AST_ADC_H_CH_MASK) >> 16;
++ break;
++ case 8:
++ tmp = ast_adc_read(ast_adc, AST_ADC_CH8_9) & AST_ADC_L_CH_MASK;
++ break;
++ case 9:
++ tmp = (ast_adc_read(ast_adc, AST_ADC_CH8_9) & AST_ADC_H_CH_MASK) >> 16;
++ break;
++ case 10:
++ tmp = ast_adc_read(ast_adc, AST_ADC_CH10_11) & AST_ADC_L_CH_MASK;
++ break;
++ case 11:
++ tmp = (ast_adc_read(ast_adc, AST_ADC_CH10_11) & AST_ADC_H_CH_MASK) >> 16;
++ break;
++ case 12:
++ tmp = ast_adc_read(ast_adc, AST_ADC_CH12_13) & AST_ADC_L_CH_MASK;
++ break;
++ case 13:
++ tmp = (ast_adc_read(ast_adc, AST_ADC_CH12_13) & AST_ADC_H_CH_MASK) >> 16;
++ break;
++ case 14:
++ tmp = ast_adc_read(ast_adc, AST_ADC_CH14_15) & AST_ADC_L_CH_MASK;
++ break;
++ case 15:
++ tmp = (ast_adc_read(ast_adc, AST_ADC_CH14_15) & AST_ADC_H_CH_MASK) >> 16;
++ break;
++
++ }
++
++ tmp += ast_adc->compen_value;
++
++// printk("voltage = %d \n",tmp);
++
++ return tmp;
++
++}
++
++static u8
++ast_get_adc_en(struct ast_adc_data *ast_adc, u8 adc_ch)
++{
++ u8 tmp=0;
++
++ if(ast_adc_read(ast_adc, AST_ADC_CTRL) & (0x1 << (16+adc_ch)))
++ tmp = 1;
++ else
++ tmp = 0;
++
++ return tmp;
++
++}
++
++static void
++ast_set_adc_en(struct ast_adc_data *ast_adc, u8 adc_ch, u8 enable)
++{
++ if(enable)
++ ast_adc_write(ast_adc, ast_adc_read(ast_adc, AST_ADC_CTRL) | (0x1 << (16+adc_ch)), AST_ADC_CTRL);
++ else
++ ast_adc_write(ast_adc, ast_adc_read(ast_adc, AST_ADC_CTRL) & ~(0x1 << (16+adc_ch)), AST_ADC_CTRL);
++}
++
++
++/* attr ADC sysfs 0~max adc channel
++* 0 - show/store channel enable
++* 1 - show value
++* 2 - show alarm get statuse
++* 3 - show/store upper
++* 4 - show/store lower
++* 5 - show/store hystersis enable
++* 6 - show/store hystersis upper
++* 7 - show/store hystersis low
++*/
++
++static ssize_t
++ast_show_adc(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
++{
++ struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
++ u16 tmp;
++ u32 voltage,tmp1, tmp2,tmp3;
++
++ //sensor_attr->index : pwm_ch#
++ //sensor_attr->nr : attr#
++ switch(sensor_attr->nr)
++ {
++ case 0: //channel enable, disable
++ return sprintf(sysfsbuf, "%d : %s\n", ast_get_adc_en(ast_adc,sensor_attr->index),ast_get_adc_en(ast_adc,sensor_attr->index) ? "Enable":"Disable");
++ break;
++ case 1: //value
++ tmp = ast_get_adc_value(ast_adc, sensor_attr->index);
++ //Voltage Sense Method
++ tmp1 = (adc_vcc_ref[REST_DESIGN].r1 + adc_vcc_ref[REST_DESIGN].r2) * tmp * 25 * 10;
++ tmp2 = adc_vcc_ref[REST_DESIGN].r2 * 1023 ;
++
++ tmp3 = (adc_vcc_ref[REST_DESIGN].r1 * adc_vcc_ref[REST_DESIGN].v2) / adc_vcc_ref[REST_DESIGN].r2;
++ // printk("tmp3 = %d \n",tmp3);
++ voltage = (tmp1/tmp2) - tmp3;
++
++ return sprintf(sysfsbuf, "%d.%d (V)\n",voltage/100, voltage%100);
++ break;
++ case 2: //alarm
++ return sprintf(sysfsbuf, "%d \n", ast_get_adc_alarm(ast_adc,sensor_attr->index));
++ break;
++ case 3: //upper
++ return sprintf(sysfsbuf, "%d \n", ast_get_adc_upper(ast_adc,sensor_attr->index));
++ break;
++ case 4: //lower
++ return sprintf(sysfsbuf, "%d \n", ast_get_adc_lower(ast_adc,sensor_attr->index));
++ break;
++ case 5: //hystersis enable
++ return sprintf(sysfsbuf, "%d : %s\n", ast_get_adc_hyster_en(ast_adc,sensor_attr->index),ast_get_adc_hyster_en(ast_adc,sensor_attr->index) ? "Enable":"Disable");
++ break;
++ case 6: //hystersis upper
++ return sprintf(sysfsbuf, "%d \n", ast_get_adc_hyster_upper(ast_adc,sensor_attr->index));
++ break;
++ case 7: //hystersis lower
++ return sprintf(sysfsbuf, "%d \n", ast_get_adc_hyster_lower(ast_adc,sensor_attr->index));
++ break;
++
++ default:
++ return -EINVAL;
++ break;
++ }
++}
++
++static ssize_t
++ast_store_adc(struct device *dev, struct device_attribute *attr, const char *sysfsbuf, size_t count)
++{
++ u32 input_val;
++ struct sensor_device_attribute_2 *sensor_attr =
++ to_sensor_dev_attr_2(attr);
++
++ input_val = simple_strtoul(sysfsbuf, NULL, 10);
++
++ //sensor_attr->index : pwm_ch#
++ //sensor_attr->nr : attr#
++ switch(sensor_attr->nr)
++ {
++ case 0: //enable, disable
++ ast_set_adc_en(ast_adc, sensor_attr->index, input_val);
++ break;
++ case 1: //value
++
++ break;
++ case 2: //alarm
++ break;
++ case 3:
++ ast_set_adc_upper(ast_adc, sensor_attr->index, input_val);
++ break;
++ case 4:
++ ast_set_adc_lower(ast_adc, sensor_attr->index, input_val);
++ break;
++ case 5: //hystersis
++ ast_set_adc_hyster_en(ast_adc, sensor_attr->index, input_val);
++ break;
++ case 6:
++ ast_set_adc_hyster_upper(ast_adc, sensor_attr->index, input_val);
++ break;
++ case 7:
++ ast_set_adc_hyster_lower(ast_adc, sensor_attr->index, input_val);
++ break;
++
++ default:
++ return -EINVAL;
++ break;
++ }
++
++ return count;
++}
++
++/* attr ADC sysfs 0~max adc channel
++* 0 - show/store channel enable
++* 1 - show value
++* 2 - show alarm get statuse
++* 3 - show/store upper
++* 4 - show/store lower
++* 5 - show/store hystersis enable
++* 6 - show/store hystersis upper
++* 7 - show/store hystersis low
++*/
++
++#define sysfs_adc_ch(index) \
++static SENSOR_DEVICE_ATTR_2(adc##index##_en, S_IRUGO | S_IWUSR, \
++ ast_show_adc, ast_store_adc, 0, index); \
++\
++static SENSOR_DEVICE_ATTR_2(adc##index##_value, S_IRUGO | S_IWUSR, \
++ ast_show_adc, NULL, 1, index); \
++\
++static SENSOR_DEVICE_ATTR_2(adc##index##_alarm, S_IRUGO | S_IWUSR, \
++ ast_show_adc, NULL, 2, index); \
++\
++static SENSOR_DEVICE_ATTR_2(adc##index##_upper, S_IRUGO | S_IWUSR, \
++ ast_show_adc, ast_store_adc, 3, index); \
++\
++static SENSOR_DEVICE_ATTR_2(adc##index##_lower, S_IRUGO | S_IWUSR, \
++ ast_show_adc, ast_store_adc, 4, index); \
++\
++static SENSOR_DEVICE_ATTR_2(adc##index##_hyster_en, S_IRUGO | S_IWUSR, \
++ ast_show_adc, ast_store_adc, 5, index); \
++\
++static SENSOR_DEVICE_ATTR_2(adc##index##_hyster_upper, S_IRUGO | S_IWUSR, \
++ ast_show_adc, ast_store_adc, 6, index); \
++\
++static SENSOR_DEVICE_ATTR_2(adc##index##_hyster_lower, S_IRUGO | S_IWUSR, \
++ ast_show_adc, ast_store_adc, 7, index); \
++\
++static struct attribute *adc##index##_attributes[] = { \
++ &sensor_dev_attr_adc##index##_en.dev_attr.attr, \
++ &sensor_dev_attr_adc##index##_value.dev_attr.attr, \
++ &sensor_dev_attr_adc##index##_alarm.dev_attr.attr, \
++ &sensor_dev_attr_adc##index##_upper.dev_attr.attr, \
++ &sensor_dev_attr_adc##index##_lower.dev_attr.attr, \
++ &sensor_dev_attr_adc##index##_hyster_en.dev_attr.attr, \
++ &sensor_dev_attr_adc##index##_hyster_upper.dev_attr.attr, \
++ &sensor_dev_attr_adc##index##_hyster_lower.dev_attr.attr, \
++ NULL \
++};
++
++/*
++ * Create the needed functions for each pwm using the macro defined above
++ * (4 pwms are supported)
++ */
++sysfs_adc_ch(0);
++sysfs_adc_ch(1);
++sysfs_adc_ch(2);
++sysfs_adc_ch(3);
++sysfs_adc_ch(4);
++sysfs_adc_ch(5);
++sysfs_adc_ch(6);
++sysfs_adc_ch(7);
++sysfs_adc_ch(8);
++sysfs_adc_ch(9);
++sysfs_adc_ch(10);
++sysfs_adc_ch(11);
++#if defined(CONFIG_ARCH_AST2400) || defined(CONFIG_ARCH_AST2500)
++sysfs_adc_ch(12);
++sysfs_adc_ch(13);
++sysfs_adc_ch(14);
++sysfs_adc_ch(15);
++#endif
++
++static const struct attribute_group adc_attribute_groups[] = {
++ { .attrs = adc0_attributes },
++ { .attrs = adc1_attributes },
++ { .attrs = adc2_attributes },
++ { .attrs = adc3_attributes },
++ { .attrs = adc4_attributes },
++ { .attrs = adc5_attributes },
++ { .attrs = adc6_attributes },
++ { .attrs = adc7_attributes },
++ { .attrs = adc8_attributes },
++ { .attrs = adc9_attributes },
++ { .attrs = adc10_attributes },
++ { .attrs = adc11_attributes },
++#if defined(CONFIG_ARCH_AST2400) || defined(CONFIG_ARCH_AST2500)
++ { .attrs = adc12_attributes },
++ { .attrs = adc13_attributes },
++ { .attrs = adc14_attributes },
++ { .attrs = adc15_attributes },
++#endif
++};
++
++
++static int
++ast_adc_probe(struct platform_device *pdev)
++{
++ struct resource *res;
++ int err;
++ int ret=0;
++ int i;
++
++ dev_dbg(&pdev->dev, "ast_adc_probe \n");
++
++ ast_adc = kzalloc(sizeof(struct ast_adc_data), GFP_KERNEL);
++ if (!ast_adc) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (NULL == res) {
++ dev_err(&pdev->dev, "cannot get IORESOURCE_MEM\n");
++ ret = -ENOENT;
++ goto out_mem;
++ }
++
++ if (!request_mem_region(res->start, resource_size(res), res->name)) {
++ dev_err(&pdev->dev, "cannot reserved region\n");
++ ret = -ENXIO;
++ goto out_mem;
++ }
++
++ ast_adc->reg_base = ioremap(res->start, resource_size(res));
++ if (!ast_adc->reg_base) {
++ ret = -EIO;
++ goto out_region;
++ }
++
++ ast_adc->irq = platform_get_irq(pdev, 0);
++ if (ast_adc->irq < 0) {
++ dev_err(&pdev->dev, "no irq specified\n");
++ ret = -ENOENT;
++ goto out_region;
++ }
++
++ /* Register sysfs hooks */
++ ast_adc->hwmon_dev = hwmon_device_register(&pdev->dev);
++ if (IS_ERR(ast_adc->hwmon_dev)) {
++ ret = PTR_ERR(ast_adc->hwmon_dev);
++ goto out_region;
++ }
++
++ for(i=0; i<MAX_CH_NO; i++) {
++ err = sysfs_create_group(&pdev->dev.kobj, &adc_attribute_groups[i]);
++ if (err)
++ goto out_region;
++ }
++
++ ast_adc_ctrl_init();
++
++ printk(KERN_INFO "ast_adc: driver successfully loaded.\n");
++
++ return 0;
++
++
++//out_irq:
++// free_irq(ast_adc->irq, NULL);
++out_region:
++ release_mem_region(res->start, res->end - res->start + 1);
++out_mem:
++ kfree(ast_adc);
++out:
++ printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
++ return ret;
++}
++
++static int
++ast_adc_remove(struct platform_device *pdev)
++{
++ int i=0;
++ struct ast_adc_data *ast_adc = platform_get_drvdata(pdev);
++ struct resource *res;
++ printk(KERN_INFO "ast_adc: driver unloaded.\n");
++
++ hwmon_device_unregister(ast_adc->hwmon_dev);
++
++ for(i=0; i<5; i++)
++ sysfs_remove_group(&pdev->dev.kobj, &adc_attribute_groups[i]);
++
++ platform_set_drvdata(pdev, NULL);
++// free_irq(ast_adc->irq, ast_adc);
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ iounmap(ast_adc->reg_base);
++ release_mem_region(res->start, res->end - res->start + 1);
++ kfree(ast_adc);
++ return 0;
++}
++
++#ifdef CONFIG_PM
++static int
++ast_adc_suspend(struct platform_device *pdev, pm_message_t state)
++{
++ printk("ast_adc_suspend : TODO \n");
++ return 0;
++}
++
++static int
++ast_adc_resume(struct platform_device *pdev)
++{
++ ast_adc_ctrl_init();
++ return 0;
++}
++
++#else
++#define ast_adc_suspend NULL
++#define ast_adc_resume NULL
++#endif
++
++static struct platform_driver ast_adc_driver = {
++ .probe = ast_adc_probe,
++ .remove = __devexit_p(ast_adc_remove),
++ .suspend = ast_adc_suspend,
++ .resume = ast_adc_resume,
++ .driver = {
++ .name = "ast_adc",
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init
++ast_adc_init(void)
++{
++ return platform_driver_register(&ast_adc_driver);
++}
++
++static void __exit
++ast_adc_exit(void)
++{
++ platform_driver_unregister(&ast_adc_driver);
++}
++
++module_init(ast_adc_init);
++module_exit(ast_adc_exit);
++
++MODULE_AUTHOR("Ryan Chen <ryan_chen@aspeedtech.com>");
++MODULE_DESCRIPTION("ADC driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/hwmon/ast_lcp_80h.c b/drivers/hwmon/ast_lcp_80h.c
+new file mode 100755
+index 0000000..681d2d6
+--- /dev/null
++++ b/drivers/hwmon/ast_lcp_80h.c
+@@ -0,0 +1,312 @@
++/*
++ * ast_lpc_snoop.c
++ *
++ * ASPEED LPC Snoop controller driver
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * 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.
++ *
++ * History:
++ * 2012.11.26: Initial version [Ryan Chen]
++ */
++
++#include <linux/delay.h>
++#include <linux/platform_device.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/timer.h>
++#include <linux/mutex.h>
++#include <linux/hwmon-sysfs.h>
++#include <linux/hwmon.h>
++#include <linux/workqueue.h>
++#include <linux/sysfs.h>
++#include <linux/err.h>
++
++#include <mach/hardware.h>
++#include <asm/irq.h>
++#include <asm/io.h>
++
++#include <plat/regs-1070_lpc.h>
++
++struct ast_clpc_data {
++ struct device *hwmon_dev;
++ void __iomem *reg_base; /* virtual */
++ int irq; //ADC IRQ number
++ u8 80h_data; //80h_data
++};
++
++static inline void
++ast_clpc_write(struct ast_clpc_data *ast_clpc, u32 val, u32 reg)
++{
++// printk("write offset: %x, val: %x \n",reg,val);
++ writel(val, ast_clpc->reg_base+ reg);
++}
++
++static inline u32
++ast_clpc_read(struct ast_adc_data *ast_clpc, u32 reg)
++{
++ u32 val = readl(ast_clpc->reg_base + reg);
++// printk("read offset: %x, val: %x \n",reg,val);
++ return val;
++}
++
++static irqreturn_t ast_lpc_80h_handler(int irq, void *dev_id)
++{
++ struct ast_clpc_data *ast_clpc = dev_id;
++ u32 sts = ast_clpc_read(ast_clpc, AST1070_LPC_80H_CTRL);
++
++ if(isr_sts & AST1070_LPC_80H_CLR) {
++ ast_clpc->80h_data = ast_clpc_read(ast_clpc, AST1070_LPC_80H_DATA);
++ ast_clpc_write(ast_clpc, AST1070_LPC_80H_CLR, AST1070_LPC_80H_DATA);
++ } else
++ printk("IRQ ISSUE bug \n");
++
++ return IRQ_HANDLED;
++
++}
++
++static void ast_clpc_80h_init(struct ast_clpc_data *ast_clpc, u16 addr)
++{
++ ast_clpc_write(ast_clpc, AST1070_LPC_80H_CLR, AST1070_LPC_80H_CTRL);
++
++ //Snoop Port
++ ast_clpc_write(ast_clpc, addr & 0xff, AST1070_LPC_L_80H_ADDR);
++ ast_clpc_write(ast_clpc, (addr & 0xff) >> 8 , AST1070_LPC_H_80H_ADDR);
++ //Clear Interrupt and Enable
++ //AST1070 BUG :===: D[4] W1C
++ ast_clpc_write(ast_clpc, AST1070_LPC_80H_CLR, AST1070_LPC_80H_DATA);
++ ast_clpc_write(ast_clpc, AST1070_LPC_80H_CLR | AST1070_LPC_80H_EN, AST1070_LPC_80H_CTRL);
++}
++
++/* attr 80H sysfs 0~max adc channel
++* 0 - show/store 80h addr
++* 1 - show 80h data
++*/
++
++static ssize_t
++ast_show_clpc(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
++{
++ struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
++ u16 tmp;
++ u32 voltage,tmp1, tmp2,tmp3;
++
++ //sensor_attr->index : pwm_ch#
++ //sensor_attr->nr : attr#
++ switch(sensor_attr->nr)
++ {
++ case 0: //channel enable, disable
++ return sprintf(sysfsbuf, "%d \n", ast_clpc->80h_data);
++ break;
++
++ default:
++ return -EINVAL;
++ break;
++ }
++}
++
++static ssize_t
++ast_store_clpc(struct device *dev, struct device_attribute *attr, const char *sysfsbuf, size_t count)
++{
++ u32 input_val;
++ struct sensor_device_attribute_2 *sensor_attr =
++ to_sensor_dev_attr_2(attr);
++
++ input_val = simple_strtoul(sysfsbuf, NULL, 10);
++
++ //sensor_attr->index : pwm_ch#
++ //sensor_attr->nr : attr#
++ switch(sensor_attr->nr)
++ {
++ case 0: //enable, disable
++
++ break;
++ default:
++ return -EINVAL;
++ break;
++ }
++
++ return count;
++}
++
++/* attr ADC sysfs 0~max adc channel
++* 0 - show 80h data
++*/
++
++#define sysfs_clpc(index) \
++static SENSOR_DEVICE_ATTR_2(clpc##index##_en, S_IRUGO | S_IWUSR, \
++ ast_show_clpc, NULL, 0, index); \
++\
++static struct attribute *clpc##index##_attributes[] = { \
++ &sensor_dev_attr_clpc##index##_80h.dev_attr.attr, \
++ NULL \
++};
++
++/*
++ * Create the needed functions for each pwm using the macro defined above
++ * (4 pwms are supported)
++ */
++sysfs_clpc(0);
++
++static const struct attribute_group clpc_attribute_groups[] = {
++ { .attrs = clpc0_attributes },
++};
++
++
++static int
++ast_clpc_probe(struct platform_device *pdev)
++{
++ struct ast_clpc_data *ast_clpc;
++ struct resource *res;
++ int err;
++ int ret=0;
++ int i;
++
++ dev_dbg(&pdev->dev, "ast_clpc_probe \n");
++
++ ast_clpc = kzalloc(sizeof(struct ast_clpc_data), GFP_KERNEL);
++ if (!ast_adc) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (NULL == res) {
++ dev_err(&pdev->dev, "cannot get IORESOURCE_MEM\n");
++ ret = -ENOENT;
++ goto out_mem;
++ }
++
++ if (!request_mem_region(res->start, resource_size(res), res->name)) {
++ dev_err(&pdev->dev, "cannot reserved region\n");
++ ret = -ENXIO;
++ goto out_mem;
++ }
++
++ ast_clpc->reg_base = ioremap(res->start, resource_size(res));
++ if (!ast_clpc->reg_base) {
++ ret = -EIO;
++ goto out_region;
++ }
++
++ ast_clpc->irq = platform_get_irq(pdev, 3);
++ if (ast_clpc->irq < 0) {
++ dev_err(&pdev->dev, "no irq specified\n");
++ ret = -ENOENT;
++ goto out_region;
++ }
++
++
++ /* Register sysfs hooks */
++ ast_clpc->hwmon_dev = hwmon_device_register(&pdev->dev);
++ if (IS_ERR(ast_clpc->hwmon_dev)) {
++ ret = PTR_ERR(ast_clpc->hwmon_dev);
++ goto out_region;
++ }
++
++ for(i=0; i< MAX_CH_NO; i++) {
++ err = sysfs_create_group(&pdev->dev.kobj, &clpc_attribute_groups[i]);
++ if (err)
++ goto out_region;
++ }
++
++ ast_clpc_80h_init();
++
++ ret = request_irq(ast_clpc->irq, ast_lpc_handler, IRQF_SHARED,
++ i2c_dev->adap.name, i2c_dev);
++ if (ret) {
++ printk(KERN_INFO "I2C: Failed request irq %d\n", i2c_dev->irq);
++ goto out_region;
++ }
++
++ platform_set_drvdata(pdev, ast_clpc);
++
++ printk(KERN_INFO "ast_adc: driver successfully loaded.\n");
++
++ return 0;
++
++
++//out_irq:
++// free_irq(ast_clpc->irq, NULL);
++out_region:
++ release_mem_region(res->start, res->end - res->start + 1);
++out_mem:
++ kfree(ast_clpc);
++out:
++ printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
++ return ret;
++}
++
++static int
++ast_adc_remove(struct platform_device *pdev)
++{
++ int i=0;
++ struct ast_adc_data *ast_clpc = platform_get_drvdata(pdev);
++ struct resource *res;
++ printk(KERN_INFO "ast_adc: driver unloaded.\n");
++
++ hwmon_device_unregister(ast_clpc->hwmon_dev);
++
++ for(i=0; i<5; i++)
++ sysfs_remove_group(&pdev->dev.kobj, &clpc_attribute_groups[i]);
++
++ platform_set_drvdata(pdev, NULL);
++// free_irq(ast_adc->irq, ast_adc);
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ iounmap(ast_clpc->reg_base);
++ release_mem_region(res->start, res->end - res->start + 1);
++ kfree(ast_clpc);
++ return 0;
++}
++
++#ifdef CONFIG_PM
++static int
++ast_adc_suspend(struct platform_device *pdev, pm_message_t state)
++{
++ printk("ast_adc_suspend : TODO \n");
++ return 0;
++}
++
++static int
++ast_adc_resume(struct platform_device *pdev)
++{
++ ast_adc_ctrl_init();
++ return 0;
++}
++
++#else
++#define ast_adc_suspend NULL
++#define ast_adc_resume NULL
++#endif
++
++static struct platform_driver ast_adc_driver = {
++ .probe = ast_adc_probe,
++ .remove = __devexit_p(ast_adc_remove),
++ .suspend = ast_adc_suspend,
++ .resume = ast_adc_resume,
++ .driver = {
++ .name = "ast_adc",
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init
++ast_adc_init(void)
++{
++ return platform_driver_register(&ast_adc_driver);
++}
++
++static void __exit
++ast_adc_exit(void)
++{
++ platform_driver_unregister(&ast_adc_driver);
++}
++
++module_init(ast_adc_init);
++module_exit(ast_adc_exit);
++
++MODULE_AUTHOR("Ryan Chen <ryan_chen@aspeedtech.com>");
++MODULE_DESCRIPTION("ADC driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/hwmon/ast_pwm_fan.c b/drivers/hwmon/ast_pwm_fan.c
+new file mode 100644
+index 0000000..02784c5
+--- /dev/null
++++ b/drivers/hwmon/ast_pwm_fan.c
+@@ -0,0 +1,2129 @@
++/*
++ * ast_pwm_fan.c
++ *
++ * ASPEED PWM & Fan Tacho controller driver
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * 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.
++ *
++ * History:
++ * 2012.08.06: Initial version [Ryan Chen]
++ */
++/* CLK sysfs
++* 0 : enable
++* 1 : clk_source */
++
++/* PWM sysfs A~H (0~7)
++* 0 - show/store enable
++* 1 - show/store type
++* 2 - show/store falling
++* 3 - show/store rising */
++
++/*PWM M/N/O Type sysfs
++* 0 - show/store unit
++* 1 - show/store division_l
++* 2 - show/store division_h */
++
++/* FAN sysfs (0~15)
++* - show/store enable
++* - show/store source
++* - show/store rpm
++* - show/store alarm
++* - show/store alarm_en */
++
++/* Fan M/N/O Type sysfs
++* 0 - show/store enable
++* 1 - show/store mode
++* 2 - show/store unit
++* 3 - show/store division
++* 4 - show/store limit */
++
++#include <linux/delay.h>
++#include <linux/platform_device.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/timer.h>
++#include <linux/mutex.h>
++#include <linux/hwmon-sysfs.h>
++#include <linux/hwmon.h>
++#include <linux/workqueue.h>
++#include <linux/sysfs.h>
++#include <linux/err.h>
++#include <linux/slab.h>
++
++#include <asm/irq.h>
++#include <asm/io.h>
++
++#ifdef CONFIG_COLDFIRE
++#include <asm/arch/regs-pwm_fan.h>
++#include <asm/arch/ast_pwm_techo.h>
++#else
++#include <plat/regs-pwm_fan.h>
++#include <mach/ast_pwm_techo.h>
++#endif
++
++//#define MCLK 1
++
++struct ast_pwm_tacho_data {
++ struct device *hwmon_dev;
++ void __iomem *reg_base; /* virtual */
++ int irq;
++ struct ast_pwm_driver_data *ast_pwm_data;
++};
++
++struct ast_pwm_tacho_data *ast_pwm_tacho;
++
++static u8 ast_get_pwm_type(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch);
++static u8 ast_get_pwm_en(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch);
++static u8 ast_get_tacho_type_division(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type);
++static u16 ast_get_tacho_type_unit(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type);
++static u8 ast_get_pwm_clock_division_h(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type);
++static u8 ast_get_pwm_clock_division_l(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type);
++static u8 ast_get_pwm_clock_unit(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type);
++
++static inline void
++ast_pwm_tacho_write(struct ast_pwm_tacho_data *ast_pwm_tacho, u32 val, u32 reg)
++{
++// printk("write offset: %x, val: %x \n",reg,val);
++ writel(val, ast_pwm_tacho->reg_base+ reg);
++}
++
++static inline u32
++ast_pwm_tacho_read(struct ast_pwm_tacho_data *ast_pwm_tacho, u32 reg)
++{
++ u32 val = readl(ast_pwm_tacho->reg_base + reg);
++// printk("read offset: %x, val: %x \n",reg,val);
++ return val;
++}
++
++/////////////////////////////////////////
++/*
++//1. The PWM base clock = 24Mhz / (Clock_Division_H D[7:4] in PTCR04 * Clock_Division_L D[3:0] in PTCR04)
++//2. The frequency of PWM = The PWM base clock / (PWM period D[15:8] in PTCR04 + 1)
++//3. If you plan to output 25Khz PWM frequency and 10% step of duty cycle, we suggest to set 0x943 in PTCR04 register.
++// The PWM frequency = 24Mhz / (16 * 6 * (9 + 1)) = 25Khz
++// duty cycle settings in the PTCR08 register:
++// 0x1e786008 D[15:0] = 0x0900, duty = 90%
++// 0x1e786008 D[15:0] = 0x0902, duty = 70%
++// .
++// .
++// .
++// 0x1e786008 D[15:0] = 0x0908, duty = 10%
++// 0x1e786008 D[15:0] = 0x0909, duty = 100%
++// 0x1e786008 D[15:0] = 0x0000, duty = 100%
++ (falling) - (rising+1) /unit
++*/
++
++static void ast_pwm_taco_init(void)
++{
++ //Enable PWM TACH CLK **************************************************
++ // Set M/N/O out is 25Khz
++ //The PWM frequency = 24Mhz / (16 * 6 * (9 + 1)) = 25Khz
++ ast_pwm_tacho_write(ast_pwm_tacho, 0x09430943, AST_PTCR_CLK_CTRL);
++ ast_pwm_tacho_write(ast_pwm_tacho, 0x0943, AST_PTCR_CLK_EXT_CTRL);
++
++ //FULL SPEED at initialize 100% pwm A~H
++ ast_pwm_tacho_write(ast_pwm_tacho, 0x0, AST_PTCR_DUTY0_CTRL);
++ ast_pwm_tacho_write(ast_pwm_tacho, 0x0, AST_PTCR_DUTY1_CTRL);
++ ast_pwm_tacho_write(ast_pwm_tacho, 0x0, AST_PTCR_DUTY2_CTRL);
++ ast_pwm_tacho_write(ast_pwm_tacho, 0x0, AST_PTCR_DUTY3_CTRL);
++
++ //Set TACO M/N/O initial unit 0x1000, falling , divide 4 , Enable
++ ast_pwm_tacho_write(ast_pwm_tacho, 0x10000001, AST_PTCR_TYPEM_CTRL0);
++ ast_pwm_tacho_write(ast_pwm_tacho, 0x10000001, AST_PTCR_TYPEN_CTRL0);
++#ifdef PWM_TYPE_O
++ ast_pwm_tacho_write(ast_pwm_tacho, 0x10000001, AST_PTCR_TYPEO_CTRL0);
++#endif
++
++ // TACO measure period = 24000000 / 2 / 2 / 256 / 4096 / 1 (only enable 1 TACHO) = 5.72Hz, it means that software needs to
++ // wait at least 0.2 sec to get refreshed TACO value. If you will enable more TACO or require faster response, you have to
++ // control the clock divisor and the period to be smaller
++
++ //Full Range to do measure unit 0x1000
++ ast_pwm_tacho_write(ast_pwm_tacho, 0x10000000, AST_PTCR_TYPEM_CTRL1);
++ ast_pwm_tacho_write(ast_pwm_tacho, 0x10000000, AST_PTCR_TYPEN_CTRL1);
++#ifdef PWM_TYPE_O
++ ast_pwm_tacho_write(ast_pwm_tacho, 0x10000000, AST_PTCR_TYPEO_CTRL1);
++#endif
++
++ //TACO Source Selection, PWMA for fan0~15
++ ast_pwm_tacho_write(ast_pwm_tacho, 0x0, AST_PTCR_TACH_SOURCE);
++ ast_pwm_tacho_write(ast_pwm_tacho, 0x0, AST_PTCR_TACH_SOURCE_EXT);
++
++ //PWM A~D -> Disable , type M,
++ //Tacho 0~15 Disable
++ //CLK source 24Mhz
++#ifdef MCLK
++ ast_pwm_tacho_write(ast_pwm_tacho, AST_PTCR_CTRL_CLK_MCLK | AST_PTCR_CTRL_CLK_EN, AST_PTCR_CTRL);
++#else
++ ast_pwm_tacho_write(ast_pwm_tacho, AST_PTCR_CTRL_CLK_EN, AST_PTCR_CTRL);
++#endif
++
++}
++
++/*index 0 : clk_en , 1: clk_source*/
++static ssize_t
++ast_store_clk(struct device *dev, struct device_attribute *attr, const char *sysfsbuf, size_t count)
++{
++ u32 input_val;
++ struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
++
++ input_val = simple_strtoul(sysfsbuf, NULL, 10);
++
++ if ((input_val > 1) || (input_val < 0))
++ return -EINVAL;
++
++ //sensor_attr->index : tacho#
++ //sensor_attr->nr : attr#
++ switch(sensor_attr->nr)
++ {
++ case 0: //clk_en
++ if(input_val)
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_CLK_EN,
++ AST_PTCR_CTRL);
++ else
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_CLK_EN,
++ AST_PTCR_CTRL);
++ break;
++ case 1: //clk_source
++ if(input_val) {
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_CLK_MCLK,
++ AST_PTCR_CTRL);
++ } else {
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_CLK_MCLK,
++ AST_PTCR_CTRL);
++ }
++ break;
++ default:
++ return -EINVAL;
++ break;
++ }
++
++ return count;
++
++}
++
++
++static ssize_t
++ast_show_clk(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
++{
++ struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
++
++ //sensor_attr->index : fan#
++ //sensor_attr->nr : attr#
++ switch(sensor_attr->nr)
++ {
++ case 0: //clk_en
++ if(AST_PTCR_CTRL_CLK_EN & ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL))
++ return sprintf(sysfsbuf, "1: Enable\n");
++ else
++ return sprintf(sysfsbuf, "0: Disable\n");
++ break;
++ case 1: //clk_source
++ if(AST_PTCR_CTRL_CLK_MCLK & ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL))
++ return sprintf(sysfsbuf, "1: MCLK \n");
++ else
++ return sprintf(sysfsbuf, "0: 24Mhz\n");
++
++ break;
++ default:
++ return sprintf(sysfsbuf, "ERROR CLK Index\n");
++ break;
++ }
++}
++
++static u32
++ast_get_tacho_measure_period(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type)
++{
++ u32 clk,clk_unit,div_h,div_l,tacho_unit,tacho_div;
++ //TODO ... 266
++ if(AST_PTCR_CTRL_CLK_MCLK & ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL)) {
++ //TODO .....
++ clk = ast_pwm_tacho->ast_pwm_data->get_pwm_clock();
++ } else
++ clk = 24*1000*1000;
++
++ clk_unit = ast_get_pwm_clock_unit(ast_pwm_tacho,pwm_type);
++ div_h = ast_get_pwm_clock_division_h(ast_pwm_tacho,pwm_type);
++ div_h = 0x1 << div_h;
++ div_l = ast_get_pwm_clock_division_l(ast_pwm_tacho,pwm_type);
++// div_l = (div_l) << 1;
++ if(div_l == 0)
++ div_l = 1;
++ else
++ div_l = div_l * 2;
++
++ tacho_unit = ast_get_tacho_type_unit(ast_pwm_tacho,pwm_type);
++ tacho_div = ast_get_tacho_type_division(ast_pwm_tacho,pwm_type);
++
++ tacho_div = 0x4 << (tacho_div*2);
++// printk("clk %d,clk_unit %d, div_h %d, div_l %d, tacho_unit %d, tacho_div %d\n",clk,clk_unit, div_h, div_l, tacho_unit, tacho_div);
++ return clk/(clk_unit*div_h*div_l*tacho_div*tacho_unit);
++}
++
++static u8
++ast_get_tacho_type_division(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type)
++{
++ u32 tmp = 0;
++ switch(pwm_type) {
++ case PWM_TYPE_M:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEM_CTRL0);
++ break;
++ case PWM_TYPE_N:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEN_CTRL0);
++ break;
++#ifdef PWM_TYPE_O
++ case PWM_TYPE_O:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEO_CTRL0);
++ break;
++#endif
++ default:
++ printk("error type !! \n");
++ break;
++
++ }
++
++ return ((tmp & TYPE_CTRL0_CLK_DIVISION_MASK) >> TYPE_CTRL0_CLK_DIVISION);
++}
++
++static void
++ast_set_tacho_type_division(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type, u32 division)
++{
++ u32 tmp = 0;
++ if(division > 0x7)
++ return;
++
++ switch(pwm_type) {
++ case PWM_TYPE_M:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEM_CTRL0);
++ break;
++ case PWM_TYPE_N:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEN_CTRL0);
++ break;
++#ifdef PWM_TYPE_O
++ case PWM_TYPE_O:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEO_CTRL0);
++ break;
++#endif
++ default:
++ printk("ERROR type !! \n");
++ break;
++ }
++
++ tmp &= ~TYPE_CTRL0_CLK_DIVISION_MASK;
++ tmp |= (division << TYPE_CTRL0_CLK_DIVISION);
++
++ switch(pwm_type) {
++ case PWM_TYPE_M:
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_TYPEM_CTRL0);
++ break;
++ case PWM_TYPE_N:
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_TYPEN_CTRL0);
++ break;
++#ifdef PWM_TYPE_O
++ case PWM_TYPE_O:
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_TYPEO_CTRL0);
++ break;
++#endif
++ default:
++ printk("ERROR type !! \n");
++ break;
++ }
++
++}
++
++static u16
++ast_get_tacho_type_unit(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type)
++{
++ u32 tmp = 0;
++
++ switch(pwm_type) {
++ case PWM_TYPE_M:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEM_CTRL0);
++ break;
++ case PWM_TYPE_N:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEN_CTRL0);
++ break;
++#ifdef PWM_TYPE_O
++ case PWM_TYPE_O:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEO_CTRL0);
++ break;
++#endif
++ default:
++ printk("ERROR type !! \n");
++ break;
++ }
++
++ return ((tmp & TYPE_CTRL0_FAN_PERIOD_MASK) >> TYPE_CTRL0_FAN_PERIOD);
++}
++
++static void
++ast_set_tacho_type_unit(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type,u32 unit)
++{
++ u32 tmp = 0;
++
++ if(unit > 0xffff)
++ return;
++
++ switch(pwm_type) {
++ case PWM_TYPE_M:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEM_CTRL0);
++ break;
++ case PWM_TYPE_N:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEN_CTRL0);
++ break;
++#ifdef PWM_TYPE_O
++ case PWM_TYPE_O:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEO_CTRL0);
++ break;
++#endif
++ default:
++ printk("ERROR type !! \n");
++ break;
++ }
++
++ tmp &= ~TYPE_CTRL0_FAN_PERIOD_MASK;
++ tmp |= (unit << TYPE_CTRL0_FAN_PERIOD);
++
++ switch(pwm_type) {
++ case PWM_TYPE_M:
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_TYPEM_CTRL0);
++ break;
++ case PWM_TYPE_N:
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_TYPEN_CTRL0);
++ break;
++#ifdef PWM_TYPE_O
++ case PWM_TYPE_O:
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_TYPEO_CTRL0);
++ break;
++#endif
++ default:
++ printk("ERROR type !! \n");
++ break;
++ }
++
++}
++
++static u32
++ast_get_tacho_type_mode(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type)
++{
++ u32 tmp = 0;
++
++ switch(pwm_type) {
++ case PWM_TYPE_M:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEM_CTRL0);
++ break;
++ case PWM_TYPE_N:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEN_CTRL0);
++ break;
++#ifdef PWM_TYPE_O
++ case PWM_TYPE_O:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEO_CTRL0);
++ break;
++#endif
++ default:
++ printk("ERROR type !! \n");
++ break;
++ }
++
++ return ((tmp & TYPE_CTRL0_FAN_MODE_MASK) >> TYPE_CTRL0_FAN_MODE);
++}
++
++static void
++ast_set_tacho_type_mode(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type,u32 mode)
++{
++ u32 tmp = 0;
++ if(mode > 0x2)
++ return;
++
++ switch(pwm_type) {
++ case PWM_TYPE_M:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEM_CTRL0);
++ break;
++ case PWM_TYPE_N:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEN_CTRL0);
++ break;
++#ifdef PWM_TYPE_O
++ case PWM_TYPE_O:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEO_CTRL0);
++ break;
++#endif
++ default:
++ printk("ERROR type !! \n");
++ break;
++ }
++
++ tmp &= ~TYPE_CTRL0_FAN_MODE_MASK;
++ tmp |= (mode << TYPE_CTRL0_FAN_MODE);
++
++ switch(pwm_type) {
++ case PWM_TYPE_M:
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_TYPEM_CTRL0);
++ break;
++ case PWM_TYPE_N:
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_TYPEN_CTRL0);
++ break;
++#ifdef PWM_TYPE_O
++ case PWM_TYPE_O:
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_TYPEO_CTRL0);
++ break;
++#endif
++ default:
++ printk("ERROR type !! \n");
++ break;
++ }
++
++}
++
++static u8
++ast_get_tacho_type_en(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type)
++{
++ u8 tmp;
++ switch(pwm_type) {
++ case PWM_TYPE_M:
++ tmp = (TYPE_CTRL0_FAN_TYPE_EN & ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEM_CTRL0));
++ break;
++ case PWM_TYPE_N:
++ tmp = (TYPE_CTRL0_FAN_TYPE_EN & ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEN_CTRL0));
++ break;
++#ifdef PWM_TYPE_O
++ case PWM_TYPE_O:
++ tmp = (TYPE_CTRL0_FAN_TYPE_EN & ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEO_CTRL0));
++ break;
++#endif
++ default:
++ printk("ERROR type !! \n");
++ break;
++ }
++
++ return tmp;
++}
++
++static void
++ast_set_tacho_type_en(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type,u32 enable)
++{
++ switch(pwm_type) {
++ case PWM_TYPE_M:
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEM_CTRL0) | enable,
++ AST_PTCR_TYPEM_CTRL0);
++
++ break;
++ case PWM_TYPE_N:
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEN_CTRL0) | enable,
++ AST_PTCR_TYPEN_CTRL0);
++
++ break;
++#ifdef PWM_TYPE_O
++ case PWM_TYPE_O:
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEO_CTRL0) | enable,
++ AST_PTCR_TYPEO_CTRL0);
++
++ break;
++#endif
++ default:
++ printk("ERROR type !! \n");
++ break;
++ }
++}
++
++static u32
++ast_get_tacho_type_limit(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type)
++{
++ switch(pwm_type) {
++ case PWM_TYPE_M:
++ return (FAN_LIMIT_MASK & ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEM_LIMIT));
++ break;
++ case PWM_TYPE_N:
++ return (FAN_LIMIT_MASK & ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEN_LIMIT));
++ break;
++#ifdef PWM_TYPE_O
++ case PWM_TYPE_O:
++ return (FAN_LIMIT_MASK & ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TYPEO_LIMIT));
++ break;
++#endif
++ default:
++ printk("ERROR type !! \n");
++ break;
++ }
++}
++
++static void
++ast_set_tacho_type_limit(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type,u32 limit)
++{
++ if(limit > FAN_LIMIT_MASK)
++ return;
++
++ switch(pwm_type) {
++ case PWM_TYPE_M:
++ ast_pwm_tacho_write(ast_pwm_tacho, limit, AST_PTCR_TYPEM_LIMIT);
++ break;
++ case PWM_TYPE_N:
++ ast_pwm_tacho_write(ast_pwm_tacho, limit, AST_PTCR_TYPEN_LIMIT);
++ break;
++#ifdef PWM_TYPE_O
++ case PWM_TYPE_O:
++ ast_pwm_tacho_write(ast_pwm_tacho, limit, AST_PTCR_TYPEO_LIMIT);
++ break;
++#endif
++ default:
++ printk("ERROR type !! \n");
++ break;
++ }
++
++}
++
++static u8
++ast_get_tacho_alarm_en(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 tacho_ch)
++{
++ //tacho source
++ if( ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_INTR_CTRL) & INTR_CTRL_EN_NUM(tacho_ch))
++ return 1;
++ else
++ return 0;
++}
++
++static void
++ast_set_tacho_alarm_en(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 tacho_ch, u8 enable)
++{
++ //tacho source
++ if(enable == 1)
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_INTR_CTRL) | INTR_CTRL_EN_NUM(tacho_ch),
++ AST_PTCR_INTR_CTRL);
++ else
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_INTR_CTRL) & ~(INTR_CTRL_EN_NUM(tacho_ch)),
++ AST_PTCR_INTR_CTRL);
++}
++
++static u8
++ast_get_tacho_alarm(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 tacho_ch)
++{
++ //tacho source
++ if(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_INTR_STS) & INTR_CTRL_NUM(tacho_ch))
++ return 1;
++ else
++ return 0;
++}
++
++static u8
++ast_get_tacho_en(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 tacho_ch)
++{
++ if(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_FAN_NUM_EN(tacho_ch))
++ return 1;
++ else
++ return 0;
++}
++
++static void
++ast_set_tacho_en(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 tacho_ch, u8 enable)
++{
++ //tacho number enable
++ if(enable)
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_FAN_NUM_EN(tacho_ch),
++ AST_PTCR_CTRL);
++ else
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~(AST_PTCR_CTRL_FAN_NUM_EN(tacho_ch)),
++ AST_PTCR_CTRL);
++}
++
++static u8
++ast_get_tacho_source(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 tacho_ch)
++{
++ u32 tmp1, tmp2;
++
++ //tacho source
++ tmp1 = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TACH_SOURCE);
++ tmp1 &= TACH_PWM_SOURCE_MASK_BIT01(tacho_ch);
++ tmp1 = tmp1 >> (TACH_PWM_SOURCE_BIT01(tacho_ch));
++
++ tmp2 = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TACH_SOURCE_EXT);
++ tmp2 &= TACH_PWM_SOURCE_MASK_BIT2(tacho_ch);
++ tmp2 = tmp2 >> (TACH_PWM_SOURCE_BIT2(tacho_ch));
++ tmp2 = tmp2 << 2;
++
++ return (tmp2 | tmp1);
++}
++
++static void
++ast_set_tacho_source(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 tacho_ch, u8 tacho_source)
++{
++ u32 tmp1, tmp2;
++ if(tacho_source > 7)
++ return;
++
++ //tacho source
++ tmp1 = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TACH_SOURCE);
++ tmp1 &= ~(TACH_PWM_SOURCE_MASK_BIT01(tacho_ch));
++ tmp1 |= ((tacho_source &0x3) << (TACH_PWM_SOURCE_BIT01(tacho_ch)));
++
++ tmp2 = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_TACH_SOURCE_EXT);
++ tmp2 &= ~(TACH_PWM_SOURCE_MASK_BIT2(tacho_ch));
++ tmp2 |= (((tacho_source &0x4)>>2) << (TACH_PWM_SOURCE_BIT2(tacho_ch)));
++
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp1, AST_PTCR_TACH_SOURCE);
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp2, AST_PTCR_TACH_SOURCE_EXT);
++
++}
++
++static u32
++ast_get_tacho_rpm(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 tacho_ch)
++{
++ u32 raw_data, rpm, tacho_clk_div, clk_source, timeout=0;
++ u8 tacho_source, pwm_type,tacho_type_en;
++
++ if(!(ast_get_tacho_en(ast_pwm_tacho,tacho_ch)))
++ return 0;
++
++ //write 0
++ ast_pwm_tacho_write(ast_pwm_tacho, 0, AST_PTCR_TRIGGER);
++
++ //write 1
++ ast_pwm_tacho_write(ast_pwm_tacho, 0x1 << tacho_ch, AST_PTCR_TRIGGER);
++
++ tacho_source = ast_get_tacho_source(ast_pwm_tacho, tacho_ch);
++ pwm_type = ast_get_pwm_type(ast_pwm_tacho, tacho_source);
++ tacho_type_en = ast_get_tacho_type_en(ast_pwm_tacho, pwm_type);
++
++// printk("source: %d,type: %d,en: %d \n",tacho_source,pwm_type,tacho_type_en);
++
++ //check pwm_type and get clock division
++ if(!tacho_type_en)
++ return 0;
++
++ //Wait ready
++ while(!(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_RESULT) & (0x1 << RESULT_STATUS))) {
++ timeout++;
++ if(timeout > 25)
++ return 0;
++ };
++
++ raw_data = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_RESULT)& RESULT_VALUE_MASK;
++ tacho_clk_div = ast_get_tacho_type_division(ast_pwm_tacho, pwm_type);
++
++// printk("raw div = %d \n",tacho_clk_div);
++
++ tacho_clk_div = 0x4 << (tacho_clk_div*2);
++// printk("raw div = %d \n",tacho_clk_div);
++
++ //TODO 166
++ if(AST_PTCR_CTRL_CLK_MCLK & ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL))
++ clk_source = 166*1000*1000;
++ else
++ clk_source = 24*1000*1000;
++
++ printk("raw_data %d, clk_source %d, tacho_clk_div %d \n",raw_data, clk_source, tacho_clk_div);
++ rpm = (clk_source * 60) / (2 * raw_data * tacho_clk_div);
++
++ return rpm;
++}
++
++static u8
++ast_get_pwm_clock_division_h(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type)
++{
++ u8 tmp=0;
++
++ switch (pwm_type) {
++ case PWM_TYPE_M:
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & AST_PTCR_CLK_CTRL_TYPEM_H_MASK) >> AST_PTCR_CLK_CTRL_TYPEM_H;
++ break;
++ case PWM_TYPE_N:
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & AST_PTCR_CLK_CTRL_TYPEN_H_MASK) >> AST_PTCR_CLK_CTRL_TYPEN_H;
++ break;
++#ifdef PWM_TYPE_O
++ case PWM_TYPE_O:
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_EXT_CTRL) & AST_PTCR_CLK_CTRL_TYPEO_H_MASK) >> AST_PTCR_CLK_CTRL_TYPEO_H;
++ break;
++#endif
++ default:
++ printk("error channel ast_get_pwm_clock_division_h %d \n",pwm_type);
++ break;
++ }
++ return tmp;
++}
++
++static void
++ast_set_pwm_clock_division_h(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type, u8 div_high)
++{
++ if(div_high > 0xf)
++ return;
++ switch (pwm_type) {
++ case PWM_TYPE_M:
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & ~AST_PTCR_CLK_CTRL_TYPEM_H_MASK) | (div_high << AST_PTCR_CLK_CTRL_TYPEM_H),
++ AST_PTCR_CLK_CTRL);
++ break;
++ case PWM_TYPE_N:
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & ~AST_PTCR_CLK_CTRL_TYPEN_H_MASK) | (div_high << AST_PTCR_CLK_CTRL_TYPEN_H),
++ AST_PTCR_CLK_CTRL);
++ break;
++#ifdef PWM_TYPE_O
++ case PWM_TYPE_O:
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_EXT_CTRL) & ~AST_PTCR_CLK_CTRL_TYPEO_H_MASK) | (div_high << AST_PTCR_CLK_CTRL_TYPEO_H),
++ AST_PTCR_CLK_EXT_CTRL);
++ break;
++#endif
++ default:
++ printk("error channel ast_get_pwm_type %d \n",pwm_type);
++ break;
++ }
++
++}
++
++static u8
++ast_get_pwm_clock_division_l(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type)
++{
++ u8 tmp=0;
++
++ switch (pwm_type) {
++ case PWM_TYPE_M:
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & AST_PTCR_CLK_CTRL_TYPEM_L_MASK) >> AST_PTCR_CLK_CTRL_TYPEM_L;
++ break;
++ case PWM_TYPE_N:
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & AST_PTCR_CLK_CTRL_TYPEN_L_MASK) >> AST_PTCR_CLK_CTRL_TYPEN_L;
++ break;
++#ifdef PWM_TYPE_O
++ case PWM_TYPE_O:
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_EXT_CTRL) & AST_PTCR_CLK_CTRL_TYPEO_L_MASK) >> AST_PTCR_CLK_CTRL_TYPEO_L;
++ break;
++#endif
++ default:
++ printk("error channel ast_get_pwm_clock_division_l %d \n",pwm_type);
++ break;
++ }
++ return tmp;
++}
++
++static void
++ast_set_pwm_clock_division_l(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type, u8 div_low)
++{
++ if(div_low> 0xf)
++ return;
++ switch (pwm_type) {
++ case PWM_TYPE_M:
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & ~AST_PTCR_CLK_CTRL_TYPEM_L_MASK) | (div_low << AST_PTCR_CLK_CTRL_TYPEM_L),
++ AST_PTCR_CLK_CTRL);
++ break;
++ case PWM_TYPE_N:
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & ~AST_PTCR_CLK_CTRL_TYPEN_L_MASK) | (div_low << AST_PTCR_CLK_CTRL_TYPEN_L),
++ AST_PTCR_CLK_CTRL);
++ break;
++#ifdef PWM_TYPE_O
++ case PWM_TYPE_O:
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_EXT_CTRL) & ~AST_PTCR_CLK_CTRL_TYPEO_L_MASK) | (div_low << AST_PTCR_CLK_CTRL_TYPEO_L),
++ AST_PTCR_CLK_EXT_CTRL);
++ break;
++#endif
++ default:
++ printk("error channel ast_get_pwm_type %d \n",pwm_type);
++ break;
++ }
++}
++
++static u8
++ast_get_pwm_clock_unit(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type)
++{
++ u8 tmp=0;
++
++ switch (pwm_type) {
++ case PWM_TYPE_M:
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & AST_PTCR_CLK_CTRL_TYPEM_UNIT_MASK) >> AST_PTCR_CLK_CTRL_TYPEM_UNIT;
++ break;
++ case PWM_TYPE_N:
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & AST_PTCR_CLK_CTRL_TYPEN_UNIT_MASK) >> AST_PTCR_CLK_CTRL_TYPEN_UNIT;
++ break;
++#ifdef PWM_TYPE_O
++ case PWM_TYPE_O:
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_EXT_CTRL) & AST_PTCR_CLK_CTRL_TYPEO_UNIT_MASK) >> AST_PTCR_CLK_CTRL_TYPEO_UNIT;
++ break;
++#endif
++ default:
++ printk("error channel ast_get_pwm_clock_unit %d \n",pwm_type);
++ break;
++ }
++ return tmp;
++}
++
++static void
++ast_set_pwm_clock_unit(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type, u8 unit)
++{
++ if(unit > 0xff)
++ return;
++ switch (pwm_type) {
++ case PWM_TYPE_M:
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & ~AST_PTCR_CLK_CTRL_TYPEM_UNIT_MASK) | (unit << AST_PTCR_CLK_CTRL_TYPEM_UNIT),
++ AST_PTCR_CLK_CTRL);
++ break;
++ case PWM_TYPE_N:
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_CTRL) & ~AST_PTCR_CLK_CTRL_TYPEN_UNIT_MASK) | (unit << AST_PTCR_CLK_CTRL_TYPEN_UNIT),
++ AST_PTCR_CLK_CTRL);
++ break;
++#ifdef PWM_TYPE_O
++ case PWM_TYPE_O:
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CLK_EXT_CTRL) & ~AST_PTCR_CLK_CTRL_TYPEO_UNIT_MASK) | (unit << AST_PTCR_CLK_CTRL_TYPEO_UNIT),
++ AST_PTCR_CLK_EXT_CTRL);
++ break;
++#endif
++ default:
++ printk("error channel ast_get_pwm_type %d \n",pwm_type);
++ break;
++ }
++}
++
++static u32
++ast_get_pwm_clock(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_type)
++{
++ u32 unit, div_low, div_high, clk_source;
++
++ unit = ast_get_pwm_clock_unit(ast_pwm_tacho,pwm_type);
++
++ div_high = ast_get_pwm_clock_division_h(ast_pwm_tacho,pwm_type);
++ div_high = (0x1<<div_high);
++
++ div_low = ast_get_pwm_clock_division_l(ast_pwm_tacho,pwm_type);
++ if(div_low == 0)
++ div_low = 1;
++ else
++ div_low = div_low*2;
++ //TODO 266
++
++ if(AST_PTCR_CTRL_CLK_MCLK & ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL))
++ clk_source = ast_pwm_tacho->ast_pwm_data->get_pwm_clock();
++ else
++ clk_source = 24*1000*1000;
++
++// printk("%d, %d, %d, %d \n",clk_source,div_high,div_low,unit);
++ return (clk_source/(div_high*div_low*(unit+1)));
++}
++
++static u8
++ast_get_pwm_en(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch)
++{
++ u8 tmp=0;
++
++ switch (pwm_ch) {
++ case PWMA:
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PMWA_EN) >> AST_PTCR_CTRL_PMWA;
++ break;
++ case PWMB:
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PMWB_EN) >> AST_PTCR_CTRL_PMWB;
++ break;
++ case PWMC:
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PMWC_EN) >> AST_PTCR_CTRL_PMWC;
++ break;
++ case PWMD:
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PMWD_EN) >> AST_PTCR_CTRL_PMWD;
++ break;
++ case PWME:
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PMWE_EN) >> AST_PTCR_CTRL_PMWE;
++ break;
++ case PWMF:
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PMWF_EN) >> AST_PTCR_CTRL_PMWF;
++ break;
++ case PWMG:
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PMWG_EN) >> AST_PTCR_CTRL_PMWG;
++ break;
++ case PWMH:
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PMWH_EN) >> AST_PTCR_CTRL_PMWH;
++ break;
++ default:
++ printk("error channel ast_get_pwm_type %d \n",pwm_ch);
++ break;
++ }
++
++ return tmp;
++
++}
++
++static void
++ast_set_pwm_en(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch, u8 enable)
++{
++ switch (pwm_ch) {
++ case PWMA:
++ if(enable)
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PMWA_EN,
++ AST_PTCR_CTRL);
++ else
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PMWA_EN,
++ AST_PTCR_CTRL);
++
++ break;
++ case PWMB:
++ if(enable)
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PMWB_EN),
++ AST_PTCR_CTRL);
++ else
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PMWB_EN),
++ AST_PTCR_CTRL);
++ break;
++ case PWMC:
++ if(enable)
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PMWC_EN),
++ AST_PTCR_CTRL);
++ else
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PMWC_EN),
++ AST_PTCR_CTRL);
++
++ break;
++ case PWMD:
++ if(enable)
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PMWD_EN),
++ AST_PTCR_CTRL);
++ else
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PMWD_EN),
++ AST_PTCR_CTRL);
++
++ break;
++ case PWME:
++ if(enable)
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PMWE_EN),
++ AST_PTCR_CTRL_EXT);
++ else
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PMWE_EN),
++ AST_PTCR_CTRL_EXT);
++
++ break;
++ case PWMF:
++ if(enable)
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PMWF_EN),
++ AST_PTCR_CTRL_EXT);
++ else
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PMWF_EN),
++ AST_PTCR_CTRL_EXT);
++
++ break;
++ case PWMG:
++ if(enable)
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PMWG_EN),
++ AST_PTCR_CTRL_EXT);
++ else
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PMWG_EN),
++ AST_PTCR_CTRL_EXT);
++
++ break;
++ case PWMH:
++ if(enable)
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PMWH_EN),
++ AST_PTCR_CTRL_EXT);
++ else
++ ast_pwm_tacho_write(ast_pwm_tacho,
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PMWH_EN),
++ AST_PTCR_CTRL_EXT);
++
++ break;
++ default:
++ printk("error channel ast_get_pwm_type %d \n",pwm_ch);
++ break;
++ }
++}
++
++static u8
++ast_get_pwm_type(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch)
++{
++ u8 tmp=0;
++
++ switch (pwm_ch) {
++ case PWMA:
++ tmp = AST_PTCR_CTRL_GET_PWMA_TYPE(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL));
++ break;
++ case PWMB:
++ tmp = AST_PTCR_CTRL_GET_PWMB_TYPE(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL));
++ break;
++ case PWMC:
++ tmp = AST_PTCR_CTRL_GET_PWMC_TYPE(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL));
++ break;
++ case PWMD:
++ tmp = AST_PTCR_CTRL_GET_PWMD_TYPE(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL));
++ break;
++ case PWME:
++ tmp = AST_PTCR_CTRL_GET_PWME_TYPE(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT));
++ break;
++ case PWMF:
++ tmp = AST_PTCR_CTRL_GET_PWMF_TYPE(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT));
++ break;
++ case PWMG:
++ tmp = AST_PTCR_CTRL_GET_PWMG_TYPE(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT));
++ break;
++ case PWMH:
++ tmp = AST_PTCR_CTRL_GET_PWMH_TYPE(ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT));
++ break;
++ default:
++ printk("error channel ast_get_pwm_type %d \n",pwm_ch);
++ break;
++ }
++
++ return tmp;
++}
++
++static void
++ast_set_pwm_type(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch, u8 type)
++{
++ u32 tmp1,tmp2;
++
++ if(type > 0x2)
++ return;
++
++ tmp1 = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL);
++ tmp2 = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT);
++
++ switch (pwm_ch) {
++ case PWMA:
++ tmp1 &= ~AST_PTCR_CTRL_SET_PWMA_TYPE_MASK;
++ tmp1 |= AST_PTCR_CTRL_SET_PWMA_TYPE(type);
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp1, AST_PTCR_CTRL);
++ break;
++ case PWMB:
++ tmp1 &= ~AST_PTCR_CTRL_SET_PWMB_TYPE_MASK;
++ tmp1 |= AST_PTCR_CTRL_SET_PWMB_TYPE(type);
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp1, AST_PTCR_CTRL);
++ break;
++ case PWMC:
++ tmp1 &= ~AST_PTCR_CTRL_SET_PWMC_TYPE_MASK;
++ tmp1 |= AST_PTCR_CTRL_SET_PWMC_TYPE(type);
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp1, AST_PTCR_CTRL);
++ break;
++ case PWMD:
++ tmp1 &= ~AST_PTCR_CTRL_SET_PWMD_TYPE_MASK;
++ tmp1 |= AST_PTCR_CTRL_SET_PWMD_TYPE(type);
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp1, AST_PTCR_CTRL);
++ break;
++ case PWME:
++ tmp2 &= ~AST_PTCR_CTRL_SET_PWME_TYPE_MASK;
++ tmp2 |= AST_PTCR_CTRL_SET_PWME_TYPE(type);
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp2, AST_PTCR_CTRL_EXT);
++ break;
++ case PWMF:
++ tmp2 &= ~AST_PTCR_CTRL_SET_PWMF_TYPE_MASK;
++ tmp2 |= AST_PTCR_CTRL_SET_PWMF_TYPE(type);
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp2, AST_PTCR_CTRL_EXT);
++ break;
++ case PWMG:
++ tmp2 &= ~AST_PTCR_CTRL_SET_PWMG_TYPE_MASK;
++ tmp2 |= AST_PTCR_CTRL_SET_PWMG_TYPE(type);
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp2, AST_PTCR_CTRL_EXT);
++ break;
++ case PWMH:
++ tmp2 &= ~AST_PTCR_CTRL_SET_PWMH_TYPE_MASK;
++ tmp2 |= AST_PTCR_CTRL_SET_PWMH_TYPE(type);
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp2, AST_PTCR_CTRL_EXT);
++ break;
++ default:
++ printk("error channel %d \n",pwm_ch);
++ break;
++ }
++}
++
++// PWM DUTY
++static u8
++ast_get_pwm_duty_rising(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch)
++{
++ u32 tmp=0;
++ switch (pwm_ch) {
++ case PWMA:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY0_CTRL);
++ tmp &= DUTY_CTRL0_PWMA_RISE_POINT_MASK;
++ break;
++ case PWMB:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY0_CTRL);
++ tmp &= DUTY_CTRL0_PWMB_RISE_POINT_MASK;
++ tmp = (tmp >> DUTY_CTRL0_PWMB_RISE_POINT);
++ break;
++ case PWMC:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY1_CTRL);
++ tmp &= DUTY_CTRL1_PWMC_RISE_POINT_MASK;
++ break;
++ case PWMD:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY1_CTRL);
++ tmp &= DUTY_CTRL1_PWMD_RISE_POINT_MASK;
++ tmp = (tmp >> DUTY_CTRL1_PWMD_RISE_POINT);
++ break;
++ case PWME:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY2_CTRL);
++ tmp &= DUTY_CTRL2_PWME_RISE_POINT_MASK;
++ break;
++ case PWMF:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY2_CTRL);
++ tmp &= DUTY_CTRL2_PWMF_RISE_POINT_MASK;
++ tmp = (tmp >> DUTY_CTRL2_PWMF_RISE_POINT);
++ break;
++ case PWMG:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY3_CTRL);
++ tmp &= DUTY_CTRL3_PWMG_RISE_POINT_MASK;
++ break;
++ case PWMH:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY3_CTRL);
++ tmp &= DUTY_CTRL3_PWMH_RISE_POINT_MASK;
++ tmp = (tmp >> DUTY_CTRL3_PWMH_RISE_POINT);
++ break;
++ default:
++ printk("error pwm channel %d with duty R \n",pwm_ch);
++ break;
++ }
++
++ return tmp;
++}
++
++static void
++ast_set_pwm_duty_rising(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch, u8 rising)
++{
++ u32 tmp=0;
++ u32 pwm_type = ast_get_pwm_type(ast_pwm_tacho,pwm_ch);
++
++ if((rising > 0xff) || (rising > ast_get_pwm_clock_unit(ast_pwm_tacho,pwm_type)))
++ return;
++
++ switch (pwm_ch) {
++ case PWMA:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY0_CTRL);
++ tmp &= ~DUTY_CTRL0_PWMA_RISE_POINT_MASK;
++ tmp |= rising;
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY0_CTRL);
++ break;
++ case PWMB:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY0_CTRL);
++ tmp &= ~DUTY_CTRL0_PWMB_RISE_POINT_MASK;
++ tmp |= (rising << DUTY_CTRL0_PWMB_RISE_POINT);
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY0_CTRL);
++ break;
++ case PWMC:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY1_CTRL);
++ tmp &= ~DUTY_CTRL1_PWMC_RISE_POINT_MASK;
++ tmp |= rising;
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY1_CTRL);
++ break;
++ case PWMD:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY1_CTRL);
++ tmp &= ~DUTY_CTRL1_PWMD_RISE_POINT_MASK;
++ tmp |= (rising << DUTY_CTRL1_PWMD_RISE_POINT);
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY1_CTRL);
++ break;
++ case PWME:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY2_CTRL);
++ tmp &= ~DUTY_CTRL2_PWME_RISE_POINT_MASK;
++ tmp |= rising;
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY2_CTRL);
++ break;
++ case PWMF:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY2_CTRL);
++ tmp &= ~DUTY_CTRL2_PWMF_RISE_POINT_MASK;
++ tmp |= (rising << DUTY_CTRL2_PWMF_RISE_POINT);
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY2_CTRL);
++ break;
++ case PWMG:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY3_CTRL);
++ tmp &= ~DUTY_CTRL3_PWMG_RISE_POINT_MASK;
++ tmp |= rising;
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY3_CTRL);
++ break;
++ case PWMH:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY3_CTRL);
++ tmp &= ~DUTY_CTRL3_PWMH_RISE_POINT_MASK;
++ tmp |= (rising << DUTY_CTRL3_PWMH_RISE_POINT);
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY3_CTRL);
++ break;
++
++ default:
++ printk("error pwm channel %d with duty \n",pwm_ch);
++ break;
++ }
++}
++
++static u8
++ast_get_pwm_duty_falling(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch)
++{
++ u32 tmp=0;
++ switch (pwm_ch) {
++ case PWMA:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY0_CTRL);
++ tmp &= DUTY_CTRL0_PWMA_FALL_POINT_MASK;
++ tmp = (tmp >> DUTY_CTRL0_PWMA_FALL_POINT);
++ break;
++ case PWMB:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY0_CTRL);
++ tmp &= DUTY_CTRL0_PWMB_FALL_POINT_MASK;
++ tmp = (tmp >> DUTY_CTRL0_PWMB_FALL_POINT);
++ break;
++ case PWMC:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY1_CTRL);
++ tmp &= DUTY_CTRL1_PWMC_FALL_POINT_MASK;
++ tmp = (tmp >> DUTY_CTRL1_PWMC_FALL_POINT);
++ break;
++ case PWMD:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY1_CTRL);
++ tmp &= DUTY_CTRL1_PWMD_FALL_POINT_MASK;
++ tmp = (tmp >> DUTY_CTRL1_PWMD_FALL_POINT);
++ break;
++ case PWME:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY2_CTRL);
++ tmp &= DUTY_CTRL2_PWME_FALL_POINT_MASK;
++ tmp = (tmp >> DUTY_CTRL2_PWME_FALL_POINT);
++ break;
++ case PWMF:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY2_CTRL);
++ tmp &= DUTY_CTRL2_PWMF_FALL_POINT_MASK;
++ tmp = (tmp >> DUTY_CTRL2_PWMF_FALL_POINT);
++ break;
++ case PWMG:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY3_CTRL);
++ tmp &= DUTY_CTRL3_PWMG_FALL_POINT_MASK;
++ tmp = (tmp >> DUTY_CTRL3_PWMG_FALL_POINT);
++ break;
++ case PWMH:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY3_CTRL);
++ tmp &= DUTY_CTRL3_PWMH_FALL_POINT_MASK;
++ tmp = (tmp >> DUTY_CTRL3_PWMH_FALL_POINT);
++ break;
++
++ default:
++ printk("error pwm channel %d with duty F \n",pwm_ch);
++ break;
++ }
++
++ return tmp;
++}
++
++static void
++ast_set_pwm_duty_falling(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch, u8 falling)
++{
++ u32 tmp =0;
++ u32 pwm_type = ast_get_pwm_type(ast_pwm_tacho,pwm_ch);
++
++ if((falling > 0xff) || (falling > ast_get_pwm_clock_unit(ast_pwm_tacho,pwm_type)))
++ return;
++
++ switch (pwm_ch) {
++ case PWMA:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY0_CTRL);
++ tmp &= ~DUTY_CTRL0_PWMA_FALL_POINT_MASK;
++ tmp |= (falling << DUTY_CTRL0_PWMA_FALL_POINT);
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY0_CTRL);
++ break;
++ case PWMB:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY0_CTRL);
++ tmp &= ~DUTY_CTRL0_PWMB_FALL_POINT_MASK;
++ tmp |= (falling << DUTY_CTRL0_PWMB_FALL_POINT);
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY0_CTRL);
++ break;
++ case PWMC:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY1_CTRL);
++ tmp &= ~DUTY_CTRL1_PWMC_FALL_POINT_MASK;
++ tmp |= (falling << DUTY_CTRL1_PWMC_FALL_POINT);
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY1_CTRL);
++ break;
++ case PWMD:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY1_CTRL);
++ tmp &= ~DUTY_CTRL1_PWMD_FALL_POINT_MASK;
++ tmp |= (falling << DUTY_CTRL1_PWMD_FALL_POINT);
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY1_CTRL);
++ break;
++ case PWME:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY2_CTRL);
++ tmp &= ~DUTY_CTRL2_PWME_FALL_POINT_MASK;
++ tmp |= (falling << DUTY_CTRL2_PWME_FALL_POINT);
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY2_CTRL);
++ break;
++ case PWMF:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY2_CTRL);
++ tmp &= ~DUTY_CTRL2_PWMF_FALL_POINT_MASK;
++ tmp |= (falling << DUTY_CTRL2_PWMF_FALL_POINT);
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY2_CTRL);
++ break;
++ case PWMG:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY3_CTRL);
++ tmp &= ~DUTY_CTRL3_PWMG_FALL_POINT_MASK;
++ tmp |= (falling << DUTY_CTRL3_PWMG_FALL_POINT);
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY3_CTRL);
++ break;
++ case PWMH:
++ tmp = ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_DUTY3_CTRL);
++ tmp &= ~DUTY_CTRL3_PWMH_FALL_POINT_MASK;
++ tmp |= (falling << DUTY_CTRL3_PWMH_FALL_POINT);
++ ast_pwm_tacho_write(ast_pwm_tacho, tmp, AST_PTCR_DUTY3_CTRL);
++ break;
++
++ default:
++ printk("error pwm channel %d with duty \n",pwm_ch);
++ break;
++ }
++
++}
++
++/*PWM M/N/O Type sysfs*/
++/*
++ * Macro defining SENSOR_DEVICE_ATTR for a pwm sysfs entries.
++ * 0 - show/store unit
++ * 1 - show/store division_l
++ * 2 - show/store division_h
++ */
++
++static ssize_t
++ast_show_pwm_type_clock(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
++{
++ struct sensor_device_attribute_2 *sensor_attr =
++ to_sensor_dev_attr_2(attr);
++
++
++ //sensor_attr->index : M/N/O#
++ //sensor_attr->nr : attr#
++ switch(sensor_attr->nr)
++ {
++ case 0: //unit : 0~256
++ return sprintf(sysfsbuf, "%d (0~255)\n", ast_get_pwm_clock_unit(ast_pwm_tacho,sensor_attr->index));
++ break;
++ case 1: //division_l
++ return sprintf(sysfsbuf, "%d (0~15) \n", ast_get_pwm_clock_division_l(ast_pwm_tacho,sensor_attr->index));
++ break;
++ case 2: //division_h
++ return sprintf(sysfsbuf, "%d (0~15) \n", ast_get_pwm_clock_division_h(ast_pwm_tacho,sensor_attr->index));
++
++ break;
++ case 3: //expect clock
++
++ return sprintf(sysfsbuf, "%d \n", ast_get_pwm_clock(ast_pwm_tacho,sensor_attr->index));
++
++ break;
++
++ default:
++ return -EINVAL;
++ break;
++ }
++
++ return sprintf(sysfsbuf, "%d : %d\n", sensor_attr->nr,sensor_attr->index);
++
++
++}
++
++static ssize_t
++ast_store_pwm_type_clock(struct device *dev, struct device_attribute *attr, const char *sysfsbuf, size_t count)
++{
++ u32 input_val;
++ struct sensor_device_attribute_2 *sensor_attr =
++ to_sensor_dev_attr_2(attr);
++
++ input_val = simple_strtoul(sysfsbuf, NULL, 10);
++
++ switch(sensor_attr->nr)
++ {
++ case 0: //unit : 0~256
++ ast_set_pwm_clock_unit(ast_pwm_tacho, sensor_attr->index, input_val);
++ break;
++ case 1: //division_l
++ ast_set_pwm_clock_division_l(ast_pwm_tacho, sensor_attr->index, input_val);
++ break;
++ case 2: //division_h
++ ast_set_pwm_clock_division_h(ast_pwm_tacho, sensor_attr->index, input_val);
++ break;
++ default:
++ return -EINVAL;
++ break;
++ }
++
++ return count;
++}
++
++/* attr
++ * 0 - show/store enable
++ * 1 - show/store type
++ * 2 - show/store falling
++ * 3 - show/store rising */
++static ssize_t
++ast_show_pwm_speed(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
++{
++ struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
++
++ //sensor_attr->index : pwm_ch#
++ //sensor_attr->nr : attr#
++ switch(sensor_attr->nr)
++ {
++ case 0: //enable, disable
++ return sprintf(sysfsbuf, "%d : %s\n", ast_get_pwm_en(ast_pwm_tacho,sensor_attr->index),ast_get_pwm_en(ast_pwm_tacho,sensor_attr->index) ? "Enable":"Disable");
++ break;
++ case 1: //pwm type M/N/O
++ return sprintf(sysfsbuf, "%d (0:M/1:N/2:O)\n",ast_get_pwm_type(ast_pwm_tacho, sensor_attr->index));
++ break;
++ case 2: //rising
++ return sprintf(sysfsbuf, "%x : unit limit (0~%d)\n",ast_get_pwm_duty_rising(ast_pwm_tacho, sensor_attr->index),
++ ast_get_pwm_clock_unit(ast_pwm_tacho, ast_get_pwm_type(ast_pwm_tacho, sensor_attr->index)));
++ break;
++ case 3: //falling
++ return sprintf(sysfsbuf, "%x : unit limit (0~%d)\n",ast_get_pwm_duty_falling(ast_pwm_tacho, sensor_attr->index),
++ ast_get_pwm_clock_unit(ast_pwm_tacho, ast_get_pwm_type(ast_pwm_tacho, sensor_attr->index)));
++ break;
++ default:
++ return -EINVAL;
++ break;
++ }
++}
++
++static ssize_t
++ast_store_pwm_speed(struct device *dev, struct device_attribute *attr, const char *sysfsbuf, size_t count)
++{
++ u32 input_val;
++ struct sensor_device_attribute_2 *sensor_attr =
++ to_sensor_dev_attr_2(attr);
++
++ input_val = simple_strtoul(sysfsbuf, NULL, 10);
++
++ //sensor_attr->index : pwm_ch#
++ //sensor_attr->nr : attr#
++ switch(sensor_attr->nr)
++ {
++ case 0: //enable, disable
++ ast_set_pwm_en(ast_pwm_tacho, sensor_attr->index, input_val);
++ break;
++ case 1: //pwm type M/N/O
++ ast_set_pwm_type(ast_pwm_tacho, sensor_attr->index, input_val);
++ break;
++ case 2: //rising
++ ast_set_pwm_duty_rising(ast_pwm_tacho, sensor_attr->index, input_val);
++ break;
++ case 3: //falling
++ ast_set_pwm_duty_falling(ast_pwm_tacho, sensor_attr->index, input_val);
++ break;
++ default:
++ return -EINVAL;
++ break;
++ }
++
++ return count;
++}
++
++/* Fan Type */
++/* Fan M/N/O Type sysfs
++ * Macro defining SENSOR_DEVICE_ATTR for a pwm sysfs entries.
++ * 0 - show/store enable
++ * 1 - show/store mode
++ * 2 - show/store unit
++ * 3 - show/store division
++ * 4 - show/store limit
++ */
++
++static ssize_t
++ast_show_tacho_type(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
++{
++ struct sensor_device_attribute_2 *sensor_attr =
++ to_sensor_dev_attr_2(attr);
++
++ //sensor_attr->index : M/N/O
++ //sensor_attr->nr : attr#
++ switch(sensor_attr->nr)
++ {
++ case 0: //enable, disable
++ return sprintf(sysfsbuf, "%d : %s\n", ast_get_tacho_type_en(ast_pwm_tacho,sensor_attr->index),ast_get_tacho_type_en(ast_pwm_tacho,sensor_attr->index) ? "Enable":"Disable");
++ break;
++ case 1: //fan tacho mode
++ if(ast_get_tacho_type_mode(ast_pwm_tacho, sensor_attr->index) == FALL_EDGE)
++ return sprintf(sysfsbuf, "0: falling\n");
++ else if(ast_get_tacho_type_mode(ast_pwm_tacho, sensor_attr->index) == RISE_EDGE)
++ return sprintf(sysfsbuf, "1: rising\n");
++ else if (ast_get_tacho_type_mode(ast_pwm_tacho, sensor_attr->index) == BOTH_EDGE)
++ return sprintf(sysfsbuf, "2: both\n");
++ else
++ return sprintf(sysfsbuf, "3: unknown\n");
++ break;
++ case 2: //unit
++ return sprintf(sysfsbuf, "%d (0~65535)\n",ast_get_tacho_type_unit(ast_pwm_tacho, sensor_attr->index));
++
++ break;
++ case 3: //division
++ return sprintf(sysfsbuf, "%d (0~7) \n",ast_get_tacho_type_division(ast_pwm_tacho, sensor_attr->index));
++ break;
++ case 4: //limit
++ return sprintf(sysfsbuf, "%d (0~1048575)\n",ast_get_tacho_type_limit(ast_pwm_tacho, sensor_attr->index));
++ break;
++ case 5: //measure period
++ return sprintf(sysfsbuf, "%d \n",ast_get_tacho_measure_period(ast_pwm_tacho, sensor_attr->index));
++ break;
++ default:
++ return -EINVAL;
++ break;
++ }
++}
++
++static ssize_t
++ast_store_tacho_type(struct device *dev, struct device_attribute *attr, const char *sysfsbuf, size_t count)
++{
++ u32 input_val;
++ struct sensor_device_attribute_2 *sensor_attr =
++ to_sensor_dev_attr_2(attr);
++
++ input_val = simple_strtoul(sysfsbuf, NULL, 10);
++
++ //sensor_attr->index : pwm_ch#
++ //sensor_attr->nr : attr#
++ switch(sensor_attr->nr)
++ {
++ case 0: //enable, disable
++ ast_set_tacho_type_en(ast_pwm_tacho,sensor_attr->index, input_val);
++ break;
++ case 1: //fan tacho mode
++ ast_set_tacho_type_mode(ast_pwm_tacho, sensor_attr->index, input_val);
++ break;
++ case 2: //unit
++ ast_set_tacho_type_unit(ast_pwm_tacho, sensor_attr->index, input_val);
++ break;
++ case 3: //division
++ ast_set_tacho_type_division(ast_pwm_tacho, sensor_attr->index, input_val);
++ break;
++ case 4: //limit
++ ast_set_tacho_type_limit(ast_pwm_tacho, sensor_attr->index, input_val);
++ break;
++ default:
++ return -EINVAL;
++ break;
++ }
++ return count;
++
++}
++
++/* fan detect */
++/* FAN sysfs
++ * Macro defining SENSOR_DEVICE_ATTR for a tacho sysfs entries.
++ * - show/store enable
++ * - show/store source
++ * - show/store rpm
++ * - show/store alarm
++ * - show/store alarm_en
++*/
++static ssize_t
++ast_show_tacho_speed(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
++{
++ struct sensor_device_attribute_2 *sensor_attr =
++ to_sensor_dev_attr_2(attr);
++
++ //sensor_attr->index : pwm_ch#
++ //sensor_attr->nr : attr#
++ switch(sensor_attr->nr)
++ {
++ case 0: //enable, disable
++ return sprintf(sysfsbuf, "%d : %s\n", ast_get_tacho_en(ast_pwm_tacho,sensor_attr->index),ast_get_tacho_en(ast_pwm_tacho,sensor_attr->index) ? "Enable":"Disable");
++ break;
++ case 1: //tacho source PWMA~H - 0~7
++ return sprintf(sysfsbuf, "PWM%d (0~7)\n", ast_get_tacho_source(ast_pwm_tacho,sensor_attr->index));
++ break;
++ case 2: //rpm
++ return sprintf(sysfsbuf, "%d \n", ast_get_tacho_rpm(ast_pwm_tacho,sensor_attr->index));
++ break;
++ case 3: //alarm
++ return sprintf(sysfsbuf, "%d \n", ast_get_tacho_alarm(ast_pwm_tacho,sensor_attr->index));
++ break;
++ case 4: //alarm_en
++ return sprintf(sysfsbuf, "%d : %s\n",
++ ast_get_tacho_alarm_en(ast_pwm_tacho,sensor_attr->index),
++ ast_get_tacho_alarm_en(ast_pwm_tacho,sensor_attr->index) ? "Enable":"Disable");
++ break;
++ default:
++ return -EINVAL;
++ break;
++ }
++
++}
++
++static ssize_t
++ast_store_tacho_speed(struct device *dev, struct device_attribute *attr, const char *sysfsbuf, size_t count)
++{
++ u32 input_val;
++ struct sensor_device_attribute_2 *sensor_attr =
++ to_sensor_dev_attr_2(attr);
++
++ input_val = simple_strtoul(sysfsbuf, NULL, 10);
++
++
++ //sensor_attr->index : tacho_ch#
++ //sensor_attr->nr : attr#
++ switch(sensor_attr->nr)
++ {
++ case 0: //enable, disable
++ ast_set_tacho_en(ast_pwm_tacho,sensor_attr->index,input_val);
++ break;
++ case 1: //tacho source PWMA~H - 0~7
++ ast_set_tacho_source(ast_pwm_tacho,sensor_attr->index,input_val);
++ break;
++ case 2: //rpm
++ return -EINVAL;
++ break;
++ case 3: //alarm
++ return -EINVAL;
++ break;
++ case 4: //alarm_en
++ ast_set_tacho_alarm_en(ast_pwm_tacho,sensor_attr->index,input_val);
++ break;
++ default:
++ return -EINVAL;
++ break;
++ }
++ return count;
++}
++
++/*
++ * sysfs attributes
++ */
++/* CLK sysfs*/
++static SENSOR_DEVICE_ATTR_2(clk_en, S_IRUGO | S_IWUSR, ast_show_clk, ast_store_clk, 0, 0);
++static SENSOR_DEVICE_ATTR_2(clk_source, S_IRUGO | S_IWUSR, ast_show_clk, ast_store_clk, 1, 0);
++
++
++static struct attribute *clk_attributes[] = {
++ &sensor_dev_attr_clk_source.dev_attr.attr,
++ &sensor_dev_attr_clk_en.dev_attr.attr,
++ NULL
++};
++
++static const struct attribute_group clk_attribute_groups = {
++ .attrs = clk_attributes,
++};
++
++/*PWM M/N/O Type sysfs*/
++/*
++ * Macro defining SENSOR_DEVICE_ATTR for a pwm sysfs entries.
++ * 0 - show/store unit
++ * 1 - show/store division_l
++ * 2 - show/store division_h
++ */
++
++#define sysfs_pwm_type(type,index) \
++static SENSOR_DEVICE_ATTR_2(pwm_type_##type##_unit, S_IRUGO | S_IWUSR, \
++ ast_show_pwm_type_clock, ast_store_pwm_type_clock, 0, index); \
++\
++static SENSOR_DEVICE_ATTR_2(pwm_type_##type##_division_l, S_IRUGO | S_IWUSR, \
++ ast_show_pwm_type_clock, ast_store_pwm_type_clock, 1, index); \
++\
++static SENSOR_DEVICE_ATTR_2(pwm_type_##type##_division_h, S_IRUGO | S_IWUSR, \
++ ast_show_pwm_type_clock, ast_store_pwm_type_clock, 2, index); \
++\
++static SENSOR_DEVICE_ATTR_2(pwm_type_##type##_clk, S_IRUGO, \
++ ast_show_pwm_type_clock, NULL, 3, index); \
++\
++static struct attribute *pwm_type_##type##_attributes[] = { \
++ &sensor_dev_attr_pwm_type_##type##_unit.dev_attr.attr, \
++ &sensor_dev_attr_pwm_type_##type##_division_l.dev_attr.attr, \
++ &sensor_dev_attr_pwm_type_##type##_division_h.dev_attr.attr, \
++ &sensor_dev_attr_pwm_type_##type##_clk.dev_attr.attr, \
++ NULL \
++};
++
++/*
++ * Create the needed functions for each pwm using the macro defined above
++ * (4 pwms are supported)
++ */
++sysfs_pwm_type(m,0);
++sysfs_pwm_type(n,1);
++#ifdef PWM_TYPE_O
++sysfs_pwm_type(o,2);
++#endif
++
++static const struct attribute_group pwm_type_attribute_groups[] = {
++ { .attrs = pwm_type_m_attributes },
++ { .attrs = pwm_type_n_attributes },
++#ifdef PWM_TYPE_O
++ { .attrs = pwm_type_o_attributes },
++#endif
++};
++
++/* PWM sysfs
++ * Macro defining SENSOR_DEVICE_ATTR for a pwm sysfs entries.
++ * 0 - show/store enable
++ * 1 - show/store type
++ * 2 - show/store rising
++ * 3 - show/store falling
++ */
++
++#define sysfs_pwm_speeds_num(index) \
++static SENSOR_DEVICE_ATTR_2(pwm##index##_en, S_IRUGO | S_IWUSR, \
++ ast_show_pwm_speed, ast_store_pwm_speed, 0, index); \
++\
++static SENSOR_DEVICE_ATTR_2(pwm##index##_type, S_IRUGO | S_IWUSR, \
++ ast_show_pwm_speed, ast_store_pwm_speed, 1, index); \
++\
++static SENSOR_DEVICE_ATTR_2(pwm##index##_rising, S_IRUGO | S_IWUSR, \
++ ast_show_pwm_speed, ast_store_pwm_speed, 2, index); \
++\
++static SENSOR_DEVICE_ATTR_2(pwm##index##_falling, S_IRUGO | S_IWUSR, \
++ ast_show_pwm_speed, ast_store_pwm_speed, 3, index); \
++\
++static struct attribute *pwm##index##_attributes[] = { \
++ &sensor_dev_attr_pwm##index##_en.dev_attr.attr, \
++ &sensor_dev_attr_pwm##index##_type.dev_attr.attr, \
++ &sensor_dev_attr_pwm##index##_rising.dev_attr.attr, \
++ &sensor_dev_attr_pwm##index##_falling.dev_attr.attr, \
++ NULL \
++};
++
++/*
++ * Create the needed functions for each pwm using the macro defined above
++ * (4 pwms are supported)
++ */
++sysfs_pwm_speeds_num(0);
++sysfs_pwm_speeds_num(1);
++sysfs_pwm_speeds_num(2);
++sysfs_pwm_speeds_num(3);
++sysfs_pwm_speeds_num(4);
++sysfs_pwm_speeds_num(5);
++sysfs_pwm_speeds_num(6);
++sysfs_pwm_speeds_num(7);
++
++static const struct attribute_group pwm_attribute_groups[] = {
++ { .attrs = pwm0_attributes },
++ { .attrs = pwm1_attributes },
++ { .attrs = pwm2_attributes },
++ { .attrs = pwm3_attributes },
++ { .attrs = pwm4_attributes },
++ { .attrs = pwm5_attributes },
++ { .attrs = pwm6_attributes },
++ { .attrs = pwm7_attributes },
++};
++
++/* Fan M/N/O Type sysfs
++ * Macro defining SENSOR_DEVICE_ATTR for a pwm sysfs entries.
++ * 0 - show/store enable
++ * 1 - show/store mode
++ * 2 - show/store unit
++ * 3 - show/store division
++ * 4 - show/store limit
++ */
++
++#define sysfs_tacho_type(type,index) \
++static SENSOR_DEVICE_ATTR_2(tacho_type_##type##_en, S_IRUGO | S_IWUSR, \
++ ast_show_tacho_type, ast_store_tacho_type, 0, index); \
++\
++static SENSOR_DEVICE_ATTR_2(tacho_type_##type##_mode, S_IRUGO | S_IWUSR, \
++ ast_show_tacho_type, ast_store_tacho_type, 1, index); \
++\
++static SENSOR_DEVICE_ATTR_2(tacho_type_##type##_unit, S_IRUGO | S_IWUSR, \
++ ast_show_tacho_type, ast_store_tacho_type, 2, index); \
++\
++static SENSOR_DEVICE_ATTR_2(tacho_type_##type##_division, S_IRUGO | S_IWUSR, \
++ ast_show_tacho_type, ast_store_tacho_type, 3, index); \
++\
++static SENSOR_DEVICE_ATTR_2(tacho_type_##type##_limit, S_IRUGO | S_IWUSR, \
++ ast_show_tacho_type, ast_store_tacho_type, 4, index); \
++\
++static SENSOR_DEVICE_ATTR_2(tacho_type_##type##_measure_period, S_IRUGO | S_IWUSR, \
++ ast_show_tacho_type, ast_store_tacho_type, 5, index); \
++\
++static struct attribute *tacho_type_##type##_attributes[] = { \
++ &sensor_dev_attr_tacho_type_##type##_en.dev_attr.attr, \
++ &sensor_dev_attr_tacho_type_##type##_mode.dev_attr.attr, \
++ &sensor_dev_attr_tacho_type_##type##_unit.dev_attr.attr, \
++ &sensor_dev_attr_tacho_type_##type##_division.dev_attr.attr, \
++ &sensor_dev_attr_tacho_type_##type##_limit.dev_attr.attr, \
++ &sensor_dev_attr_tacho_type_##type##_measure_period.dev_attr.attr, \
++ NULL \
++};
++
++/*
++ * Create the needed functions for each pwm using the macro defined above
++ * (4 pwms are supported)
++ */
++sysfs_tacho_type(m,0);
++sysfs_tacho_type(n,1);
++#ifdef PWM_TYPE_O
++sysfs_tacho_type(o,2);
++#endif
++
++static const struct attribute_group tacho_type_attribute_groups[] = {
++ { .attrs = tacho_type_m_attributes },
++ { .attrs = tacho_type_n_attributes },
++#ifdef PWM_TYPE_O
++ { .attrs = tacho_type_o_attributes },
++#endif
++};
++
++/* FAN sysfs
++ * Macro defining SENSOR_DEVICE_ATTR for a tacho sysfs entries.
++ * - show/store enable
++ * - show/store source
++ * - show/store rpm
++ * - show/store alarm
++ * - show/store alarm_en
++ */
++#define sysfs_tacho_speeds_num(index) \
++static SENSOR_DEVICE_ATTR_2(tacho##index##_en, S_IRUGO | S_IWUSR, \
++ ast_show_tacho_speed, ast_store_tacho_speed, 0, index); \
++\
++static SENSOR_DEVICE_ATTR_2(tacho##index##_source, S_IRUGO | S_IWUSR, \
++ ast_show_tacho_speed, ast_store_tacho_speed, 1, index); \
++\
++static SENSOR_DEVICE_ATTR_2(tacho##index##_rpm, S_IRUGO, \
++ ast_show_tacho_speed, NULL, 2, index); \
++\
++static SENSOR_DEVICE_ATTR_2(tacho##index##_alarm, S_IRUGO, \
++ ast_show_tacho_speed, ast_store_tacho_speed, 3, index); \
++\
++static SENSOR_DEVICE_ATTR_2(tacho##index##_alarm_en, S_IRUGO | S_IWUSR, \
++ ast_show_tacho_speed, ast_store_tacho_speed, 4, index); \
++\
++static struct attribute *tacho##index##_attributes[] = { \
++ &sensor_dev_attr_tacho##index##_en.dev_attr.attr, \
++ &sensor_dev_attr_tacho##index##_source.dev_attr.attr, \
++ &sensor_dev_attr_tacho##index##_rpm.dev_attr.attr, \
++ &sensor_dev_attr_tacho##index##_alarm.dev_attr.attr, \
++ &sensor_dev_attr_tacho##index##_alarm_en.dev_attr.attr, \
++ NULL \
++};
++
++/*
++ * Create the needed functions for each tacho using the macro defined above
++ * (4 tachos are supported)
++ */
++sysfs_tacho_speeds_num(0);
++sysfs_tacho_speeds_num(1);
++sysfs_tacho_speeds_num(2);
++sysfs_tacho_speeds_num(3);
++sysfs_tacho_speeds_num(4);
++sysfs_tacho_speeds_num(5);
++sysfs_tacho_speeds_num(6);
++sysfs_tacho_speeds_num(7);
++sysfs_tacho_speeds_num(8);
++sysfs_tacho_speeds_num(9);
++sysfs_tacho_speeds_num(10);
++sysfs_tacho_speeds_num(11);
++sysfs_tacho_speeds_num(12);
++sysfs_tacho_speeds_num(13);
++sysfs_tacho_speeds_num(14);
++sysfs_tacho_speeds_num(15);
++
++static const struct attribute_group tacho_attribute_groups[] = {
++ { .attrs = tacho0_attributes },
++ { .attrs = tacho1_attributes },
++ { .attrs = tacho2_attributes },
++ { .attrs = tacho3_attributes },
++ { .attrs = tacho4_attributes },
++ { .attrs = tacho5_attributes },
++ { .attrs = tacho6_attributes },
++ { .attrs = tacho7_attributes },
++ { .attrs = tacho8_attributes },
++ { .attrs = tacho9_attributes },
++ { .attrs = tacho10_attributes },
++ { .attrs = tacho11_attributes },
++ { .attrs = tacho12_attributes },
++ { .attrs = tacho13_attributes },
++ { .attrs = tacho14_attributes },
++ { .attrs = tacho15_attributes },
++};
++
++static int
++ast_pwm_tacho_probe(struct platform_device *pdev)
++{
++ struct resource *res;
++ int err;
++ int ret=0;
++ int i;
++
++ dev_dbg(&pdev->dev, "ast_pwm_fan_probe \n");
++
++ ast_pwm_tacho = kzalloc(sizeof(struct ast_pwm_tacho_data), GFP_KERNEL);
++ if (!ast_pwm_tacho) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ ast_pwm_tacho->ast_pwm_data = pdev->dev.platform_data;
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (NULL == res) {
++ dev_err(&pdev->dev, "cannot get IORESOURCE_MEM\n");
++ ret = -ENOENT;
++ goto out_mem;
++ }
++
++ if (!request_mem_region(res->start, resource_size(res), res->name)) {
++ dev_err(&pdev->dev, "cannot reserved region\n");
++ ret = -ENXIO;
++ goto out_mem;
++ }
++
++ ast_pwm_tacho->reg_base = ioremap(res->start, resource_size(res));
++ if (!ast_pwm_tacho->reg_base) {
++ ret = -EIO;
++ goto out_region;
++ }
++
++ ast_pwm_tacho->irq = platform_get_irq(pdev, 0);
++ if (ast_pwm_tacho->irq < 0) {
++ dev_err(&pdev->dev, "no irq specified\n");
++ ret = -ENOENT;
++ goto out_region;
++ }
++
++ /* Register sysfs hooks */
++ err = sysfs_create_group(&pdev->dev.kobj, &clk_attribute_groups);
++ if (err)
++ goto out_region;
++
++ ast_pwm_tacho->hwmon_dev = hwmon_device_register(&pdev->dev);
++ if (IS_ERR(ast_pwm_tacho->hwmon_dev)) {
++ ret = PTR_ERR(ast_pwm_tacho->hwmon_dev);
++ goto out_sysfs0;
++ }
++
++ for(i=0; i< PWM_CH_NUM; i++) {
++ err = sysfs_create_group(&pdev->dev.kobj, &pwm_attribute_groups[i]);
++ if (err)
++ goto out_sysfs0;
++ }
++
++ for(i=0; i< PWM_TYPE_NUM; i++) {
++ err = sysfs_create_group(&pdev->dev.kobj, &pwm_type_attribute_groups[i]);
++ if (err)
++ goto out_sysfs1;
++ }
++
++
++ for(i=0; i< TACHO_NUM; i++) {
++ err = sysfs_create_group(&pdev->dev.kobj, &tacho_attribute_groups[i]);
++ if (err)
++ goto out_sysfs2;
++ }
++
++ for(i=0; i< PWM_TYPE_NUM; i++) {
++ err = sysfs_create_group(&pdev->dev.kobj, &tacho_type_attribute_groups[i]);
++ if (err)
++ goto out_sysfs3;
++ }
++
++ ast_pwm_taco_init();
++
++ printk(KERN_INFO "ast_pwm_tacho: driver successfully loaded.\n");
++
++ return 0;
++
++out_sysfs3:
++ for(i=0; i< TACHO_NUM; i++)
++ sysfs_remove_group(&pdev->dev.kobj, &tacho_attribute_groups[i]);
++
++out_sysfs2:
++ for(i=0; i< PWM_TYPE_NUM; i++)
++ sysfs_remove_group(&pdev->dev.kobj, &pwm_type_attribute_groups[i]);
++
++out_sysfs1:
++ for(i=0; i< PWM_CH_NUM; i++)
++ sysfs_remove_group(&pdev->dev.kobj, &pwm_attribute_groups[i]);
++out_sysfs0:
++ sysfs_remove_group(&pdev->dev.kobj, &clk_attribute_groups);
++
++//out_irq:
++// free_irq(ast_pwm_tacho->irq, NULL);
++out_region:
++ release_mem_region(res->start, res->end - res->start + 1);
++out_mem:
++ kfree(ast_pwm_tacho);
++out:
++ printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
++ return ret;
++}
++
++static int
++ast_pwm_tacho_remove(struct platform_device *pdev)
++{
++ int i=0;
++ struct ast_pwm_tacho_data *ast_pwm_tacho = platform_get_drvdata(pdev);
++ struct resource *res;
++ printk(KERN_INFO "ast_pwm_tacho: driver unloaded.\n");
++
++ hwmon_device_unregister(ast_pwm_tacho->hwmon_dev);
++
++ for(i=0; i<16; i++)
++ sysfs_remove_group(&pdev->dev.kobj, &tacho_attribute_groups[i]);
++
++ for(i=0; i<3; i++)
++ sysfs_remove_group(&pdev->dev.kobj, &pwm_type_attribute_groups[i]);
++
++ for(i=0; i<8; i++)
++ sysfs_remove_group(&pdev->dev.kobj, &pwm_attribute_groups[i]);
++
++ sysfs_remove_group(&pdev->dev.kobj, &clk_attribute_groups);
++
++ platform_set_drvdata(pdev, NULL);
++// free_irq(ast_pwm_tacho->irq, ast_pwm_tacho);
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ iounmap(ast_pwm_tacho->reg_base);
++ release_mem_region(res->start, res->end - res->start + 1);
++ kfree(ast_pwm_tacho);
++ return 0;
++}
++
++#ifdef CONFIG_PM
++static int
++ast_pwm_tacho_suspend(struct platform_device *pdev, pm_message_t state)
++{
++ printk("ast_pwm_tacho_suspend : TODO \n");
++ return 0;
++}
++
++static int
++ast_pwm_tacho_resume(struct platform_device *pdev)
++{
++ ast_pwm_taco_init();
++ return 0;
++}
++
++#else
++#define ast_pwm_tacho_suspend NULL
++#define ast_pwm_tacho_resume NULL
++#endif
++
++static struct platform_driver ast_pwm_tacho_driver = {
++ .probe = ast_pwm_tacho_probe,
++ .remove = __devexit_p(ast_pwm_tacho_remove),
++ .suspend = ast_pwm_tacho_suspend,
++ .resume = ast_pwm_tacho_resume,
++ .driver = {
++ .name = "ast_pwm_tacho",
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init
++ast_pwm_tacho_init(void)
++{
++ return platform_driver_register(&ast_pwm_tacho_driver);
++}
++
++static void __exit
++ast_pwm_tacho_exit(void)
++{
++ platform_driver_unregister(&ast_pwm_tacho_driver);
++}
++
++module_init(ast_pwm_tacho_init);
++module_exit(ast_pwm_tacho_exit);
++
++MODULE_AUTHOR("Ryan Chen <ryan_chen@aspeedtech.com>");
++MODULE_DESCRIPTION("PWM TACHO driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
+index 7f95905..2ed0928 100644
+--- a/drivers/i2c/busses/Kconfig
++++ b/drivers/i2c/busses/Kconfig
+@@ -454,6 +454,51 @@ config I2C_PXA_SLAVE
+ is necessary for systems where the PXA may be a target on the
+ I2C bus.
+
++config I2C_AST
++ tristate "ASPEED AST I2C adapter "
++# depends on ARCH_ASPEED
++ help
++ If you have devices in the AST I2C bus, say yes to this option.
++ This driver can also be built as a module. If so, the module
++ will be called i2c-ast.
++
++config I2C_AST1070
++ tristate "ASPEED AST1070 I2C adapter "
++ depends on ARCH_AST1070
++ help
++ If you have devices in the AST1070 I2C bus, say yes to this option.
++ This driver can also be built as a module. If so, the module
++ will be called i2c-ast.
++
++config AST_I2C_SLAVE_MODE
++ bool "AST I2C Slave mode"
++ depends on I2C_AST
++
++if AST_I2C_SLAVE_MODE
++
++choice
++ prompt "I2C slave config"
++ default AST_I2C_SLAVE_EEPROM
++
++config AST_I2C_SLAVE_EEPROM
++ bool "10 byte EEPROM Device"
++ help
++ Support I2C slave mode communications on the AST I2C bus. This
++ is necessary for systems where the AST may be a target on the
++ I2C bus.
++
++config AST_I2C_SLAVE_RDWR
++ bool "I2C Slave RD/WR via ioctl"
++
++ help
++ Support I2C slave mode communications on the AST I2C bus. This
++ is necessary for systems where the AST may be a target on the
++ I2C bus.
++
++endchoice
++
++endif
++
+ config I2C_S3C2410
+ tristate "S3C2410 I2C Driver"
+ depends on ARCH_S3C2410
+diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
+index 0c2c4b2..a3b523e 100644
+--- a/drivers/i2c/busses/Makefile
++++ b/drivers/i2c/busses/Makefile
+@@ -42,6 +42,7 @@ obj-$(CONFIG_I2C_OMAP) += i2c-omap.o
+ obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.o
+ obj-$(CONFIG_I2C_PNX) += i2c-pnx.o
+ obj-$(CONFIG_I2C_PXA) += i2c-pxa.o
++obj-$(CONFIG_I2C_AST) += i2c-ast.o
+ obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o
+ obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o
+ obj-$(CONFIG_I2C_SH_MOBILE) += i2c-sh_mobile.o
+diff --git a/drivers/i2c/busses/i2c-ast.c b/drivers/i2c/busses/i2c-ast.c
+new file mode 100644
+index 0000000..bccf5a3
+--- /dev/null
++++ b/drivers/i2c/busses/i2c-ast.c
+@@ -0,0 +1,1725 @@
++/*
++ * i2c_adap_ast.c
++ *
++ * I2C adapter for the ASPEED I2C bus access.
++ *
++ * Copyright (C) 2012-2020 ASPEED Technology Inc.
++ *
++ * 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.
++ *
++ * History:
++ * 2012.07.26: Initial version [Ryan Chen]
++ */
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/i2c.h>
++#include <linux/i2c-id.h>
++#include <linux/init.h>
++#include <linux/time.h>
++#include <linux/delay.h>
++#include <linux/errno.h>
++#include <linux/interrupt.h>
++#include <linux/completion.h>
++
++#include <linux/platform_device.h>
++#include <linux/err.h>
++#include <linux/clk.h>
++
++#include <linux/dma-mapping.h>
++
++#include <asm/irq.h>
++#include <asm/io.h>
++
++#if defined(CONFIG_COLDFIRE)
++#include <asm/arch/regs-iic.h>
++#include <asm/arch/ast_i2c.h>
++#else
++#include <plat/regs-iic.h>
++#include <plat/ast_i2c.h>
++#endif
++
++//AST2400 buffer mode issue , force I2C slave write use byte mode , read use buffer mode
++/* Use platform_data instead of module parameters */
++/* Fast Mode = 400 kHz, Standard = 100 kHz */
++//static int clock = 100; /* Default: 100 kHz */
++
++
++/***************************************************************************/
++struct ast_i2c_dev {
++ struct ast_i2c_driver_data *ast_i2c_data;
++ struct device *dev;
++ void __iomem *reg_base; /* virtual */
++ int irq; //I2C IRQ number
++ u32 bus_id; //for i2c dev# IRQ number check
++ u32 state; //I2C xfer mode state matchine
++ struct i2c_adapter adap;
++ struct buf_page *req_page;
++//dma or buff mode needed
++ unsigned char *dma_buf;
++ dma_addr_t dma_addr;
++
++//master
++ int xfer_last; //cur xfer is last msgs for stop msgs
++ struct i2c_msg *master_msgs; //cur xfer msgs
++ int master_xfer_len; //cur xfer len
++ int master_xfer_cnt; //total xfer count
++ u32 master_xfer_mode; //cur xfer mode ... 0 : no_op , master: 1 byte , 2 : buffer , 3: dma , slave : xxxx
++ struct completion cmd_complete;
++ int cmd_err;
++ u8 blk_r_flag; //for smbus block read
++ void (*do_master_xfer)(struct ast_i2c_dev *i2c_dev);
++//Slave structure
++ u8 slave_operation;
++ u8 slave_event;
++ struct i2c_msg *slave_msgs; //cur slave xfer msgs
++ int slave_xfer_len;
++ int slave_xfer_cnt;
++ u32 slave_xfer_mode; //cur xfer mode ... 0 : no_op , master: 1 byte , 2 : buffer , 3: dma , slave : xxxx
++ void (*do_slave_xfer)(struct ast_i2c_dev *i2c_dev);
++};
++
++#ifdef CONFIG_AST_I2C_SLAVE_RDWR
++#define I2C_S_BUF_SIZE 64
++#define I2C_S_RX_BUF_NUM 4
++#define BUFF_FULL 0xff00
++#define BUFF_ONGOING 1
++
++struct i2c_msg slave_rx_msg[I2C_S_RX_BUF_NUM + 1];
++struct i2c_msg slave_tx_msg;
++#endif
++
++
++static inline void
++ast_i2c_write(struct ast_i2c_dev *i2c_dev, u32 val, u32 reg)
++{
++// dev_dbg(i2c_dev->dev, "ast_i2c_write : val: %x , reg : %x \n",val,reg);
++ writel(val, i2c_dev->reg_base+ reg);
++}
++
++static inline u32
++ast_i2c_read(struct ast_i2c_dev *i2c_dev, u32 reg)
++{
++#if 0
++ u32 val = readl(i2c_dev->reg_base + reg);
++ printk("R : reg %x , val: %x \n",reg, val);
++ return val;
++#else
++ return readl(i2c_dev->reg_base + reg);
++#endif
++}
++
++static u32 select_i2c_clock(struct ast_i2c_dev *i2c_dev)
++{
++
++ unsigned int clk, inc = 0, div, divider_ratio;
++ u32 SCL_Low, SCL_High, data;
++
++ clk = i2c_dev->ast_i2c_data->get_i2c_clock();
++// printk("pclk = %d \n",clk);
++ divider_ratio = clk / i2c_dev->ast_i2c_data->bus_clk;
++ for (div = 0; divider_ratio >= 16; div++)
++ {
++ inc |= (divider_ratio & 1);
++ divider_ratio >>= 1;
++ }
++ divider_ratio += inc;
++ SCL_Low = (divider_ratio >> 1) - 1;
++ SCL_High = divider_ratio - SCL_Low - 2;
++ data = 0x77700300 | (SCL_High << 16) | (SCL_Low << 12) | div;
++// printk("I2CD04 for %d = %08X\n", target_speed, data);
++ return data;
++}
++
++#ifdef CONFIG_AST_I2C_SLAVE_MODE
++/* AST I2C Slave mode */
++static void ast_slave_issue_alert(struct ast_i2c_dev *i2c_dev, u8 enable)
++{
++ //only support dev0~3
++ if(i2c_dev->bus_id > 3)
++ return;
++ else {
++ if(enable)
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_CMD_REG) | AST_I2CD_S_ALT_EN, I2C_CMD_REG);
++ else
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_CMD_REG) & ~AST_I2CD_S_ALT_EN, I2C_CMD_REG);
++ }
++}
++
++static void ast_slave_mode_enable(struct ast_i2c_dev *i2c_dev, struct i2c_msg *msgs)
++{
++ if(msgs->buf[0] == 1) {
++ ast_i2c_write(i2c_dev, msgs->addr, I2C_DEV_ADDR_REG);
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_FUN_CTRL_REG) | AST_I2CD_SLAVE_EN, I2C_FUN_CTRL_REG);
++ } else
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_FUN_CTRL_REG) & ~AST_I2CD_SLAVE_EN, I2C_FUN_CTRL_REG);
++}
++
++#endif
++
++static void ast_i2c_dev_init(struct ast_i2c_dev *i2c_dev)
++{
++ //I2CG Reset
++ ast_i2c_write(i2c_dev, 0, I2C_FUN_CTRL_REG);
++
++#ifdef CONFIG_AST_I2C_SLAVE_EEPROM
++ i2c_dev->ast_i2c_data->slave_init(&(i2c_dev->slave_msgs));
++ ast_slave_mode_enable(i2c_dev, i2c_dev->slave_msgs);
++#endif
++
++ //Enable Master Mode
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev, I2C_FUN_CTRL_REG) | AST_I2CD_MASTER_EN, I2C_FUN_CTRL_REG);
++
++
++ /* Set AC Timing */
++#if defined(CONFIG_ARCH_AST2400)
++ if(i2c_dev->ast_i2c_data->bus_clk/1000 > 400) {
++ printk("high speed mode enable clk [%dkhz]\n",i2c_dev->ast_i2c_data->bus_clk/1000);
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev, I2C_FUN_CTRL_REG) |
++ AST_I2CD_M_HIGH_SPEED_EN |
++ AST_I2CD_M_SDA_DRIVE_1T_EN |
++ AST_I2CD_SDA_DRIVE_1T_EN
++ , I2C_FUN_CTRL_REG);
++
++ /* Set AC Timing */
++ ast_i2c_write(i2c_dev, 0x3, I2C_AC_TIMING_REG2);
++ ast_i2c_write(i2c_dev, select_i2c_clock(i2c_dev), I2C_AC_TIMING_REG1);
++ }else {
++ /* target apeed is xxKhz*/
++ ast_i2c_write(i2c_dev, select_i2c_clock(i2c_dev), I2C_AC_TIMING_REG1);
++ ast_i2c_write(i2c_dev, AST_NO_TIMEOUT_CTRL, I2C_AC_TIMING_REG2);
++ }
++#else
++ /* target apeed is xxKhz*/
++ ast_i2c_write(i2c_dev, select_i2c_clock(i2c_dev), I2C_AC_TIMING_REG1);
++ ast_i2c_write(i2c_dev, AST_NO_TIMEOUT_CTRL, I2C_AC_TIMING_REG2);
++#endif
++// ast_i2c_write(i2c_dev, 0x77743335, I2C_AC_TIMING_REG1);
++/////
++
++
++ //Clear Interrupt
++ ast_i2c_write(i2c_dev, 0xfffffff, I2C_INTR_STS_REG);
++
++ //TODO
++// ast_i2c_write(i2c_dev, 0xAF, I2C_INTR_CTRL_REG);
++ //Enable Interrupt, STOP Interrupt has bug in AST2000
++
++ /* Set interrupt generation of I2C controller */
++ ast_i2c_write(i2c_dev,
++ AST_I2CD_SDA_DL_TO_INTR_EN |
++ AST_I2CD_BUS_RECOVER_INTR_EN |
++ AST_I2CD_SMBUS_ALT_INTR_EN |
++// AST_I2CD_SLAVE_MATCH_INTR_EN |
++ AST_I2CD_SCL_TO_INTR_EN |
++ AST_I2CD_ABNORMAL_INTR_EN |
++ AST_I2CD_NORMAL_STOP_INTR_EN |
++ AST_I2CD_ARBIT_LOSS_INTR_EN |
++ AST_I2CD_RX_DOWN_INTR_EN |
++ AST_I2CD_TX_NAK_INTR_EN |
++ AST_I2CD_TX_ACK_INTR_EN,
++ I2C_INTR_CTRL_REG);
++
++}
++
++#ifdef CONFIG_AST_I2C_SLAVE_RDWR
++//for memory buffer initial
++static void ast_i2c_slave_buff_init(struct ast_i2c_dev *i2c_dev)
++{
++ int i;
++ //Tx buf 1
++ slave_tx_msg.len = I2C_S_BUF_SIZE;
++ slave_tx_msg.buf = kzalloc(I2C_S_BUF_SIZE, GFP_KERNEL);
++ //Rx buf 4
++ for(i=0; i<I2C_S_RX_BUF_NUM+1; i++) {
++ slave_rx_msg[i].addr = ~BUFF_ONGOING;
++ slave_rx_msg[i].flags = 0; //mean empty buffer
++ slave_rx_msg[i].len = I2C_S_BUF_SIZE;
++ slave_rx_msg[i].buf = kzalloc(I2C_S_BUF_SIZE, GFP_KERNEL);
++ }
++}
++
++static void ast_i2c_slave_rdwr_xfer(struct ast_i2c_dev *i2c_dev)
++{
++ int i;
++ spinlock_t lock;
++ spin_lock(&lock);
++
++ switch(i2c_dev->slave_event) {
++ case I2C_SLAVE_EVENT_START_WRITE:
++ for(i=0; i<I2C_S_RX_BUF_NUM; i++) {
++ if((slave_rx_msg[i].flags == 0) && (slave_rx_msg[i].addr != BUFF_ONGOING)) {
++ slave_rx_msg[i].addr = BUFF_ONGOING;
++ break;
++ }
++ }
++ if(i == I2C_S_RX_BUF_NUM) {
++ printk("RX buffer full ........use tmp msgs buff \n");
++ //TODO...
++ }
++ printk("I2C_SLAVE_EVENT_START_WRITE ... %d \n", i);
++
++ i2c_dev->slave_msgs = &slave_rx_msg[i];
++ break;
++ case I2C_SLAVE_EVENT_START_READ:
++ printk("I2C_SLAVE_EVENT_START_READ ERROR .. not imple \n");
++ i2c_dev->slave_msgs = &slave_tx_msg;
++ break;
++ case I2C_SLAVE_EVENT_WRITE:
++ printk("I2C_SLAVE_EVENT_WRITE next write ERROR ...\n");
++ i2c_dev->slave_msgs = &slave_tx_msg;
++ break;
++ case I2C_SLAVE_EVENT_READ:
++ printk("I2C_SLAVE_EVENT_READ ERROR ... \n");
++ i2c_dev->slave_msgs = &slave_tx_msg;
++ break;
++ case I2C_SLAVE_EVENT_NACK:
++ printk("I2C_SLAVE_EVENT_NACK ERROR ... \n");
++ i2c_dev->slave_msgs = &slave_tx_msg;
++ break;
++ case I2C_SLAVE_EVENT_STOP:
++ printk("I2C_SLAVE_EVENT_STOP \n");
++ for(i=0; i<I2C_S_RX_BUF_NUM; i++) {
++ if(slave_rx_msg[i].addr == BUFF_ONGOING) {
++ slave_rx_msg[i].flags = BUFF_FULL;
++ slave_rx_msg[i].addr = 0;
++ break;
++ }
++ }
++
++ i2c_dev->slave_msgs = &slave_tx_msg;
++ break;
++ }
++ spin_unlock(&lock);
++
++}
++
++static int ast_i2c_slave_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs)
++{
++ struct ast_i2c_dev *i2c_dev = adap->algo_data;
++ int ret=0, i;
++
++ switch(msgs->flags) {
++ case 0:
++// printk("slave read \n");
++ //cur_msg = get_free_msg;
++ for(i=0; i<I2C_S_RX_BUF_NUM; i++) {
++ if((slave_rx_msg[i].addr == 0) && (slave_rx_msg[i].flags == BUFF_FULL)) {
++ memcpy(msgs->buf, slave_rx_msg[i].buf, slave_rx_msg[i].len);
++ msgs->len = slave_rx_msg[i].len;
++ slave_rx_msg[i].flags = 0;
++ slave_rx_msg[i].len = 0;
++ break;
++ }
++ }
++
++ if(i == I2C_S_RX_BUF_NUM) {
++ printk("No buffer ........ \n");
++ msgs->len = 0;
++ ret = -1;
++ }
++ break;
++ case I2C_M_RD: //slave write
++// printk("slave write \n");
++ memcpy(msgs->buf, slave_tx_msg.buf, I2C_S_BUF_SIZE);
++ break;
++ case I2C_S_EN:
++ if((msgs->addr < 0x1) || (msgs->addr > 0xff)) {
++ ret = -1;
++ printk("addrsss not correct !! \n");
++ return ret;
++ }
++ if(msgs->len != 1) printk("ERROR \n");
++ ast_slave_mode_enable(i2c_dev, msgs);
++ break;
++ case I2C_S_ALT:
++// printk("slave issue alt\n");
++ if(msgs->len != 1) printk("ERROR \n");
++ if(msgs->buf[0]==1)
++ ast_slave_issue_alert(i2c_dev, 1);
++ else
++ ast_slave_issue_alert(i2c_dev, 0);
++ break;
++
++ default:
++ printk("slave xfer error \n");
++ break;
++
++ }
++ return ret;
++}
++
++
++#endif
++
++static u8
++ast_i2c_bus_error_recover(struct ast_i2c_dev *i2c_dev)
++{
++ u32 sts;
++ int r;
++ u32 i = 0;
++
++ //Check 0x14's SDA and SCL status
++ sts = ast_i2c_read(i2c_dev,I2C_CMD_REG);
++
++ if ((sts & AST_I2CD_SDA_LINE_STS) && (sts & AST_I2CD_SCL_LINE_STS)) {
++ //Means bus is idle.
++ dev_dbg(i2c_dev->dev, "I2C bus (%d) is idle. I2C slave doesn't exist?!\n", i2c_dev->bus_id);
++ return -1;
++ }
++
++ dev_dbg(i2c_dev->dev, "ERROR!! I2C(%d) bus hanged, try to recovery it!\n", i2c_dev->bus_id);
++
++
++ if ((sts & AST_I2CD_SDA_LINE_STS) && !(sts & AST_I2CD_SCL_LINE_STS)) {
++ //if SDA == 1 and SCL == 0, it means the master is locking the bus.
++ //Send a stop command to unlock the bus.
++ dev_dbg(i2c_dev->dev, "I2C's master is locking the bus, try to stop it.\n");
++//
++ init_completion(&i2c_dev->cmd_complete);
++
++ ast_i2c_write(i2c_dev, AST_I2CD_M_STOP_CMD, I2C_CMD_REG);
++
++ r = wait_for_completion_interruptible_timeout(&i2c_dev->cmd_complete,
++ i2c_dev->adap.timeout*HZ);
++
++ if(i2c_dev->cmd_err) {
++ dev_dbg(i2c_dev->dev, "recovery error \n");
++ return -1;
++ }
++
++ if (r == 0) {
++ dev_dbg(i2c_dev->dev, "recovery timed out\n");
++ return -1;
++ } else {
++ dev_dbg(i2c_dev->dev, "Recovery successfully\n");
++ return 0;
++ }
++
++
++ } else if (!(sts & AST_I2CD_SDA_LINE_STS)) {
++ //else if SDA == 0, the device is dead. We need to reset the bus
++ //And do the recovery command.
++ dev_dbg(i2c_dev->dev, "I2C's slave is dead, try to recover it\n");
++ //Let's retry 10 times
++ for (i = 0; i < 10; i++) {
++ ast_i2c_dev_init(i2c_dev);
++ //Do the recovery command BIT11
++ init_completion(&i2c_dev->cmd_complete);
++ ast_i2c_write(i2c_dev, AST_I2CD_BUS_RECOVER_CMD_EN, I2C_CMD_REG);
++
++ r = wait_for_completion_interruptible_timeout(&i2c_dev->cmd_complete,
++ i2c_dev->adap.timeout*HZ);
++ if (i2c_dev->cmd_err != 0) {
++ dev_dbg(i2c_dev->dev, "ERROR!! Failed to do recovery command(0x%08x)\n", i2c_dev->cmd_err);
++ return -1;
++ }
++ //Check 0x14's SDA and SCL status
++ sts = ast_i2c_read(i2c_dev,I2C_CMD_REG);
++ if (sts & AST_I2CD_SDA_LINE_STS) //Recover OK
++ break;
++ }
++ if (i == 10) {
++ dev_dbg(i2c_dev->dev, "ERROR!! recover failed\n");
++ return -1;
++ }
++ } else {
++ dev_dbg(i2c_dev->dev, "Don't know how to handle this case?!\n");
++ return -1;
++ }
++ dev_dbg(i2c_dev->dev, "Recovery successfully\n");
++ return 0;
++}
++
++static void ast_master_alert_recv(struct ast_i2c_dev *i2c_dev)
++{
++ printk("ast_master_alert_recv bus id %d, Disable Alt, Please Imple \n",i2c_dev->bus_id);
++}
++
++static int ast_i2c_wait_bus_not_busy(struct ast_i2c_dev *i2c_dev)
++{
++ int timeout = 32; //TODO number
++// printk("ast_i2c_wait_bus_not_busy \n");
++ while (ast_i2c_read(i2c_dev,I2C_CMD_REG) & AST_I2CD_BUS_BUSY_STS) {
++ ast_i2c_bus_error_recover(i2c_dev);
++ if(timeout<=0)
++ break;
++ timeout--;
++ msleep(2);
++ }
++
++ return timeout <= 0 ? EAGAIN : 0;
++}
++
++static void ast_i2c_do_dma_xfer(struct ast_i2c_dev *i2c_dev)
++{
++ u32 cmd = 0;
++ int i;
++
++ i2c_dev->master_xfer_mode = DMA_XFER;
++ i2c_dev->slave_xfer_mode = DMA_XFER;
++
++ if(i2c_dev->slave_operation == 1) {
++ if(i2c_dev->slave_msgs->flags & I2C_M_RD) {
++ //DMA tx mode
++ if(i2c_dev->slave_msgs->len > AST_I2C_DMA_SIZE)
++ i2c_dev->slave_xfer_len = AST_I2C_DMA_SIZE;
++ else
++ i2c_dev->slave_xfer_len = i2c_dev->slave_msgs->len;
++
++ dev_dbg(i2c_dev->dev, "(<--) slave tx DMA \n");
++ for(i=0; i<i2c_dev->slave_xfer_len; i++)
++ i2c_dev->dma_buf[i] = i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt + i];
++
++ ast_i2c_write(i2c_dev, i2c_dev->dma_addr, I2C_DMA_BASE_REG);
++ ast_i2c_write(i2c_dev, (i2c_dev->slave_xfer_len-1), I2C_DMA_LEN_REG);
++ ast_i2c_write(i2c_dev, AST_I2CD_TX_DMA_ENABLE | AST_I2CD_S_TX_CMD,I2C_CMD_REG);
++ } else {
++ //DMA prepare rx
++ dev_dbg(i2c_dev->dev, "(-->) slave rx DMA \n");
++ ast_i2c_write(i2c_dev, i2c_dev->dma_addr, I2C_DMA_BASE_REG);
++ ast_i2c_write(i2c_dev, (AST_I2C_DMA_SIZE-1), I2C_DMA_LEN_REG);
++ ast_i2c_write(i2c_dev, AST_I2CD_RX_DMA_ENABLE, I2C_CMD_REG);
++ }
++ } else {
++ dev_dbg(i2c_dev->dev,"M cnt %d, xf len %d \n",i2c_dev->master_xfer_cnt, i2c_dev->master_msgs->len);
++ if(i2c_dev->master_xfer_cnt == -1) {
++ //send start
++ dev_dbg(i2c_dev->dev, " %sing %d byte%s %s 0x%02x\n",
++ i2c_dev->master_msgs->flags & I2C_M_RD ? "read" : "write",
++ i2c_dev->master_msgs->len, i2c_dev->master_msgs->len > 1 ? "s" : "",
++ i2c_dev->master_msgs->flags & I2C_M_RD ? "from" : "to", i2c_dev->master_msgs->addr);
++
++ if(i2c_dev->master_msgs->flags & I2C_M_RD) {
++ //workaround .. HW can;t send start read addr with buff mode
++ cmd = AST_I2CD_M_START_CMD | AST_I2CD_M_TX_CMD;
++ ast_i2c_write(i2c_dev, (i2c_dev->master_msgs->addr <<1) |0x1, I2C_BYTE_BUF_REG);
++
++// tx_buf[0] = (i2c_dev->master_msgs->addr <<1); //+1
++ i2c_dev->master_xfer_len = 1;
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ } else {
++ //tx
++ cmd = AST_I2CD_M_START_CMD | AST_I2CD_M_TX_CMD | AST_I2CD_TX_DMA_ENABLE;
++
++ i2c_dev->dma_buf[0] = (i2c_dev->master_msgs->addr <<1); //+1
++ //next data write
++ if((i2c_dev->master_msgs->len + 1) > AST_I2C_DMA_SIZE)
++ i2c_dev->master_xfer_len = AST_I2C_DMA_SIZE;
++ else
++ i2c_dev->master_xfer_len = i2c_dev->master_msgs->len + 1;
++
++ for(i = 1; i < i2c_dev->master_xfer_len; i++)
++ i2c_dev->dma_buf[i] = i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt+i];
++
++ if (i2c_dev->xfer_last == 1) {
++ dev_dbg(i2c_dev->dev, "last stop \n");
++ cmd |= AST_I2CD_M_STOP_CMD;
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
++ ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++
++ } else {
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ }
++ ast_i2c_write(i2c_dev, i2c_dev->dma_addr, I2C_DMA_BASE_REG);
++ ast_i2c_write(i2c_dev, (i2c_dev->master_xfer_len-1), I2C_DMA_LEN_REG);
++
++ }
++ ast_i2c_write(i2c_dev, cmd, I2C_CMD_REG);
++ dev_dbg(i2c_dev->dev, "txfer size %d , cmd = %x \n",i2c_dev->master_xfer_len, cmd);
++
++ } else if (i2c_dev->master_xfer_cnt < i2c_dev->master_msgs->len){
++ //Next send
++ if(i2c_dev->master_msgs->flags & I2C_M_RD) {
++ //Rx data
++ cmd = AST_I2CD_M_RX_CMD | AST_I2CD_RX_DMA_ENABLE;
++
++ if((i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt) > AST_I2C_DMA_SIZE) {
++ i2c_dev->master_xfer_len = AST_I2C_DMA_SIZE;
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
++ AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
++
++ } else {
++ i2c_dev->master_xfer_len = i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt;
++ if((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->blk_r_flag == 0)) {
++ dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN \n");
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
++ AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
++ } else {
++#ifdef CONFIG_AST1010
++ //Workaround for ast1010 can't send NACK
++ if((i2c_dev->master_xfer_len == 1) && (i2c_dev->xfer_last == 1)) {
++ //change to byte mode
++ cmd |= AST_I2CD_M_STOP_CMD | AST_I2CD_M_S_RX_CMD_LAST;
++ cmd &= ~AST_I2CD_RX_DMA_ENABLE;
++ i2c_dev->master_xfer_mode = BYTE_XFER;
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
++ ~AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
++
++ } else if (i2c_dev->master_xfer_len > 1) {
++ i2c_dev->master_xfer_len -=1;
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
++ AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
++ } else {
++ printk(" Fix Me !! \n");
++ }
++#else
++ if(i2c_dev->xfer_last == 1) {
++ dev_dbg(i2c_dev->dev, "last stop \n");
++ cmd |= AST_I2CD_M_STOP_CMD;
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
++ ~AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
++ } else {
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
++ AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
++ }
++ //TODO check....
++ cmd |= AST_I2CD_M_S_RX_CMD_LAST;
++#endif
++ }
++
++ }
++ ast_i2c_write(i2c_dev, i2c_dev->dma_addr, I2C_DMA_BASE_REG);
++ ast_i2c_write(i2c_dev, i2c_dev->master_xfer_len-1, I2C_DMA_LEN_REG);
++ ast_i2c_write(i2c_dev, cmd, I2C_CMD_REG);
++ dev_dbg(i2c_dev->dev, "rxfer size %d , cmd = %x \n",i2c_dev->master_xfer_len, cmd);
++ } else {
++ //Tx data
++ //next data write
++ cmd = AST_I2CD_M_TX_CMD | AST_I2CD_TX_DMA_ENABLE;
++ if((i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt) > AST_I2C_DMA_SIZE) {
++ i2c_dev->master_xfer_len = AST_I2C_DMA_SIZE;
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++
++ } else {
++ i2c_dev->master_xfer_len = i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt;
++ if(i2c_dev->xfer_last == 1) {
++ dev_dbg(i2c_dev->dev, "last stop \n");
++ cmd |= AST_I2CD_M_STOP_CMD;
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
++ ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++
++ } else {
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ }
++ }
++
++ for(i = 0; i < i2c_dev->master_xfer_len; i++)
++ i2c_dev->dma_buf[i] = i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt + i];
++
++ ast_i2c_write(i2c_dev, i2c_dev->dma_addr, I2C_DMA_BASE_REG);
++ ast_i2c_write(i2c_dev, (i2c_dev->master_xfer_len-1), I2C_DMA_LEN_REG);
++ ast_i2c_write(i2c_dev, cmd , I2C_CMD_REG);
++ dev_dbg(i2c_dev->dev, "txfer size %d , cmd = %x \n",i2c_dev->master_xfer_len, cmd);
++
++ }
++ }else {
++ //should send next msg
++ if(i2c_dev->master_xfer_cnt != i2c_dev->master_msgs->len)
++ printk("complete rx ... ERROR \n");
++
++ dev_dbg(i2c_dev->dev, "ast_i2c_do_byte_xfer complete \n");
++ i2c_dev->cmd_err = 0;
++ complete(&i2c_dev->cmd_complete);
++ }
++
++ }
++
++
++}
++
++static void ast_i2c_do_pool_xfer(struct ast_i2c_dev *i2c_dev)
++{
++ u32 cmd = 0;
++ int i;
++ u32 *tx_buf;
++
++ i2c_dev->master_xfer_mode = BUFF_XFER;
++ i2c_dev->slave_xfer_mode = BUFF_XFER;
++
++#if defined(CONFIG_ARCH_AST2400)
++ ast_i2c_write(i2c_dev,
++ (ast_i2c_read(i2c_dev, I2C_FUN_CTRL_REG) &
++ ~AST_I2CD_BUFF_SEL_MASK) |
++ AST_I2CD_BUFF_SEL(i2c_dev->req_page->page_no),
++ I2C_FUN_CTRL_REG);
++#endif
++
++ tx_buf = (u32 *) i2c_dev->req_page->page_addr;
++
++
++ if(i2c_dev->slave_operation == 1) {
++ if(i2c_dev->slave_msgs->flags & I2C_M_RD) {
++ dev_dbg(i2c_dev->dev, "(<--) slave tx buf \n");
++
++ if(i2c_dev->slave_msgs->len > i2c_dev->req_page->page_size)
++ i2c_dev->slave_xfer_len = i2c_dev->req_page->page_size;
++ else
++ i2c_dev->slave_xfer_len = i2c_dev->slave_msgs->len;
++
++ for(i = 0; i< i2c_dev->slave_xfer_len; i++) {
++ if(i%4 == 0)
++ tx_buf[i/4] = 0;
++ tx_buf[i/4] |= (i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt + i] << ((i%4)*8)) ;
++ dev_dbg(i2c_dev->dev, "[%x] ",tx_buf[i/4]);
++ }
++ dev_dbg(i2c_dev->dev, "\n");
++
++ ast_i2c_write(i2c_dev, AST_I2CD_TX_DATA_BUF_END_SET((i2c_dev->slave_xfer_len-1)) |
++ AST_I2CD_BUF_BASE_ADDR_SET((i2c_dev->req_page->page_addr_point)),
++ I2C_BUF_CTRL_REG);
++
++ ast_i2c_write(i2c_dev, AST_I2CD_TX_BUFF_ENABLE | AST_I2CD_S_TX_CMD, I2C_CMD_REG);
++ } else {
++ //prepare for new rx
++ dev_dbg(i2c_dev->dev, "(-->) slave prepare rx buf \n");
++ ast_i2c_write(i2c_dev,
++ AST_I2CD_RX_BUF_END_ADDR_SET((i2c_dev->req_page->page_size-1)) |
++ AST_I2CD_BUF_BASE_ADDR_SET((i2c_dev->req_page->page_addr_point)),
++ I2C_BUF_CTRL_REG);
++
++ ast_i2c_write(i2c_dev, AST_I2CD_RX_BUFF_ENABLE, I2C_CMD_REG);
++
++ }
++ } else {
++ dev_dbg(i2c_dev->dev,"M cnt %d, xf len %d \n",i2c_dev->master_xfer_cnt, i2c_dev->master_msgs->len);
++ if(i2c_dev->master_xfer_cnt == -1) {
++ //send start
++ dev_dbg(i2c_dev->dev, " %sing %d byte%s %s 0x%02x\n",
++ i2c_dev->master_msgs->flags & I2C_M_RD ? "read" : "write",
++ i2c_dev->master_msgs->len, i2c_dev->master_msgs->len > 1 ? "s" : "",
++ i2c_dev->master_msgs->flags & I2C_M_RD ? "from" : "to", i2c_dev->master_msgs->addr);
++
++ if(i2c_dev->master_msgs->flags & I2C_M_RD) {
++//workaround .. HW can;t send start read addr with buff mode
++ cmd = AST_I2CD_M_START_CMD | AST_I2CD_M_TX_CMD;
++ ast_i2c_write(i2c_dev, (i2c_dev->master_msgs->addr <<1) |0x1, I2C_BYTE_BUF_REG);
++
++// tx_buf[0] = (i2c_dev->master_msgs->addr <<1); //+1
++ i2c_dev->master_xfer_len = 1;
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ } else {
++ cmd = AST_I2CD_M_START_CMD | AST_I2CD_M_TX_CMD | AST_I2CD_TX_BUFF_ENABLE;
++ tx_buf[0] = (i2c_dev->master_msgs->addr <<1); //+1
++ //next data write
++ if((i2c_dev->master_msgs->len + 1) > i2c_dev->req_page->page_size)
++ i2c_dev->master_xfer_len = i2c_dev->req_page->page_size;
++ else
++ i2c_dev->master_xfer_len = i2c_dev->master_msgs->len + 1;
++
++ for(i = 1; i < i2c_dev->master_xfer_len; i++) {
++ if(i%4 == 0)
++ tx_buf[i/4] = 0;
++ tx_buf[i/4] |= (i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt + i] << ((i%4)*8)) ;
++ }
++
++ if (i2c_dev->xfer_last == 1) {
++ dev_dbg(i2c_dev->dev, "last stop \n");
++ cmd |= AST_I2CD_M_STOP_CMD;
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
++ ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++
++ } else {
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ }
++ ast_i2c_write(i2c_dev,
++ AST_I2CD_TX_DATA_BUF_END_SET((i2c_dev->master_xfer_len - 1)) |
++ AST_I2CD_BUF_BASE_ADDR_SET(i2c_dev->req_page->page_addr_point),
++ I2C_BUF_CTRL_REG);
++ }
++ ast_i2c_write(i2c_dev, cmd, I2C_CMD_REG);
++ dev_dbg(i2c_dev->dev, "txfer size %d , cmd = %x \n",i2c_dev->master_xfer_len, cmd);
++
++ } else if (i2c_dev->master_xfer_cnt < i2c_dev->master_msgs->len){
++ //Next send
++ if(i2c_dev->master_msgs->flags & I2C_M_RD) {
++ //Rx data
++ cmd = AST_I2CD_M_RX_CMD | AST_I2CD_RX_BUFF_ENABLE;
++
++ if((i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt) > i2c_dev->req_page->page_size) {
++ i2c_dev->master_xfer_len = i2c_dev->req_page->page_size;
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
++ AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
++ } else {
++ i2c_dev->master_xfer_len = i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt;
++ if((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->blk_r_flag == 0)) {
++ dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN \n");
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
++ AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
++ } else {
++ if(i2c_dev->xfer_last == 1) {
++ dev_dbg(i2c_dev->dev, "last stop \n");
++ cmd |= AST_I2CD_M_STOP_CMD;
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
++ ~AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
++ } else {
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
++ AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
++ }
++ cmd |= AST_I2CD_M_S_RX_CMD_LAST;
++ }
++ }
++ ast_i2c_write(i2c_dev,
++ AST_I2CD_RX_BUF_END_ADDR_SET((i2c_dev->master_xfer_len-1))|
++ AST_I2CD_BUF_BASE_ADDR_SET((i2c_dev->req_page->page_addr_point)),
++ I2C_BUF_CTRL_REG);
++ ast_i2c_write(i2c_dev, cmd, I2C_CMD_REG);
++ dev_dbg(i2c_dev->dev, "rxfer size %d , cmd = %x \n",i2c_dev->master_xfer_len, cmd);
++ } else {
++ //Tx data
++ //next data write
++ cmd = AST_I2CD_M_TX_CMD | AST_I2CD_TX_BUFF_ENABLE;
++ if((i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt) > i2c_dev->req_page->page_size) {
++ i2c_dev->master_xfer_len = i2c_dev->req_page->page_size;
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++
++ } else {
++ i2c_dev->master_xfer_len = i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt;
++ if(i2c_dev->xfer_last == 1) {
++ dev_dbg(i2c_dev->dev, "last stop \n");
++ cmd |= AST_I2CD_M_STOP_CMD;
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
++ ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++
++ } else {
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ }
++ }
++
++ for(i = 0; i < i2c_dev->master_xfer_len; i++) {
++ if(i%4 == 0)
++ tx_buf[i/4] = 0;
++ tx_buf[i/4] |= (i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt + i] << ((i%4)*8)) ;
++ }
++// printk("count %x \n",ast_i2c_read(i2c_dev,I2C_CMD_REG));
++ ast_i2c_write(i2c_dev,
++ AST_I2CD_TX_DATA_BUF_END_SET((i2c_dev->master_xfer_len - 1)) |
++ AST_I2CD_BUF_BASE_ADDR_SET(i2c_dev->req_page->page_addr_point),
++ I2C_BUF_CTRL_REG);
++
++ ast_i2c_write(i2c_dev, cmd , I2C_CMD_REG);
++ dev_dbg(i2c_dev->dev, "txfer size %d , cmd = %x \n",i2c_dev->master_xfer_len, cmd);
++ }
++ } else {
++ //should send next msg
++ if(i2c_dev->master_xfer_cnt != i2c_dev->master_msgs->len)
++ printk("complete rx ... ERROR \n");
++
++ dev_dbg(i2c_dev->dev, "ast_i2c_do_byte_xfer complete \n");
++ i2c_dev->cmd_err = 0;
++ complete(&i2c_dev->cmd_complete);
++ }
++
++ }
++}
++static void ast_i2c_do_byte_xfer(struct ast_i2c_dev *i2c_dev)
++{
++ u8 *xfer_buf;
++ u32 cmd = 0;
++
++ i2c_dev->master_xfer_mode = BYTE_XFER;
++ i2c_dev->master_xfer_len = 1;
++
++ i2c_dev->slave_xfer_mode = BYTE_XFER;
++ i2c_dev->slave_xfer_len = 1;
++
++ if(i2c_dev->slave_operation == 1) {
++ dev_dbg(i2c_dev->dev,"S cnt %d, xf len %d \n",i2c_dev->slave_xfer_cnt, i2c_dev->slave_msgs->len);
++ if(i2c_dev->slave_msgs->flags & I2C_M_RD) {
++ //READ <-- TX
++ dev_dbg(i2c_dev->dev, "(<--) slave(tx) buf %d [%x]\n", i2c_dev->slave_xfer_cnt, i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt]);
++ ast_i2c_write(i2c_dev, i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt], I2C_BYTE_BUF_REG);
++ ast_i2c_write(i2c_dev, AST_I2CD_S_TX_CMD, I2C_CMD_REG);
++ } else {
++ // Write -->Rx
++ //no need to handle in byte mode
++ dev_dbg(i2c_dev->dev, "(-->) slave(rx) BYTE do nothing\n");
++
++ }
++ } else {
++ dev_dbg(i2c_dev->dev,"M cnt %d, xf len %d \n",i2c_dev->master_xfer_cnt, i2c_dev->master_msgs->len);
++ if(i2c_dev->master_xfer_cnt == -1) {
++ //first start
++ dev_dbg(i2c_dev->dev, " %sing %d byte%s %s 0x%02x\n",
++ i2c_dev->master_msgs->flags & I2C_M_RD ? "read" : "write",
++ i2c_dev->master_msgs->len, i2c_dev->master_msgs->len > 1 ? "s" : "",
++ i2c_dev->master_msgs->flags & I2C_M_RD ? "from" : "to", i2c_dev->master_msgs->addr);
++
++
++ if(i2c_dev->master_msgs->flags & I2C_M_RD)
++ ast_i2c_write(i2c_dev, (i2c_dev->master_msgs->addr <<1) |0x1, I2C_BYTE_BUF_REG);
++ else
++ ast_i2c_write(i2c_dev, (i2c_dev->master_msgs->addr <<1), I2C_BYTE_BUF_REG);
++
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++
++ ast_i2c_write(i2c_dev, AST_I2CD_M_TX_CMD | AST_I2CD_M_START_CMD, I2C_CMD_REG);
++
++
++ } else if (i2c_dev->master_xfer_cnt < i2c_dev->master_msgs->len){
++ xfer_buf = i2c_dev->master_msgs->buf;
++ if(i2c_dev->master_msgs->flags & I2C_M_RD) {
++ //Rx data
++ cmd = AST_I2CD_M_RX_CMD;
++ if((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->master_xfer_cnt == 0)) {
++ dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN \n");
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
++ AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
++
++ } else if((i2c_dev->xfer_last == 1) && (i2c_dev->master_xfer_cnt + 1 == i2c_dev->master_msgs->len)) {
++ cmd |= AST_I2CD_M_S_RX_CMD_LAST | AST_I2CD_M_STOP_CMD;
++ // disable rx_dwn isr
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
++ ~AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
++ } else {
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
++ AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
++ }
++
++ dev_dbg(i2c_dev->dev, "(<--) rx byte, cmd = %x \n",cmd);
++
++ ast_i2c_write(i2c_dev, cmd, I2C_CMD_REG);
++
++
++ } else {
++ //Tx data
++ dev_dbg(i2c_dev->dev, "(-->) xfer byte data index[%02x]:%02x \n",i2c_dev->master_xfer_cnt, *(xfer_buf + i2c_dev->master_xfer_cnt));
++ ast_i2c_write(i2c_dev, *(xfer_buf + i2c_dev->master_xfer_cnt), I2C_BYTE_BUF_REG);
++ if((i2c_dev->xfer_last == 1) && (i2c_dev->master_xfer_cnt + 1 == i2c_dev->master_msgs->len)) {
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
++ ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ ast_i2c_write(i2c_dev, AST_I2CD_M_TX_CMD | AST_I2CD_M_STOP_CMD, I2C_CMD_REG);
++ } else {
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ ast_i2c_write(i2c_dev, AST_I2CD_M_TX_CMD, I2C_CMD_REG);
++ }
++ }
++
++ } else {
++ //should send next msg
++ if(i2c_dev->master_xfer_cnt != i2c_dev->master_msgs->len)
++ printk("CNT ERROR \n");
++
++ dev_dbg(i2c_dev->dev, "ast_i2c_do_byte_xfer complete \n");
++ i2c_dev->cmd_err = 0;
++ complete(&i2c_dev->cmd_complete);
++
++ }
++ }
++
++}
++
++static void ast_i2c_slave_xfer_done(struct ast_i2c_dev *i2c_dev)
++{
++ u32 xfer_len;
++ int i;
++ u8 *rx_buf;
++
++ dev_dbg(i2c_dev->dev, "ast_i2c_slave_xfer_done [%d]\n",i2c_dev->slave_xfer_mode);
++
++ if (i2c_dev->slave_msgs->flags & I2C_M_RD) {
++ //tx done , only check tx count ...
++ if(i2c_dev->master_xfer_mode == BYTE_XFER) {
++ xfer_len = 1;
++ } else if (i2c_dev->master_xfer_mode == BUFF_XFER) {
++ xfer_len = AST_I2CD_TX_DATA_BUF_GET(ast_i2c_read(i2c_dev, I2C_BUF_CTRL_REG));
++ xfer_len++;
++ dev_dbg(i2c_dev->dev,"S tx buff done len %d \n",xfer_len);
++ } else {
++ //DMA mode
++ xfer_len = ast_i2c_read(i2c_dev, I2C_DMA_LEN_REG);
++ if(xfer_len == 0)
++ xfer_len = i2c_dev->slave_xfer_len;
++ else
++ xfer_len = i2c_dev->slave_xfer_len - xfer_len - 1;
++
++ dev_dbg(i2c_dev->dev,"S tx rx dma done len %d \n",xfer_len);
++ }
++
++ } else {
++ //rx done
++ if(i2c_dev->slave_xfer_mode == BYTE_XFER) {
++ //TODO
++ xfer_len = 1;
++ if(i2c_dev->slave_event == I2C_SLAVE_EVENT_STOP) {
++ i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt] = 0;
++ i2c_dev->slave_msgs->len = i2c_dev->slave_xfer_cnt;
++ } else {
++ i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt] = ast_i2c_read(i2c_dev,I2C_BYTE_BUF_REG) >> 8;
++ }
++ dev_dbg(i2c_dev->dev,"rx buff %d, [%x] \n",i2c_dev->slave_xfer_cnt ,i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt]);
++ } else if (i2c_dev->master_xfer_mode == BUFF_XFER) {
++ xfer_len = AST_I2CD_RX_BUF_ADDR_GET(ast_i2c_read(i2c_dev, I2C_BUF_CTRL_REG));
++ if(xfer_len == 0)
++ xfer_len = AST_I2C_PAGE_SIZE;
++
++ dev_dbg(i2c_dev->dev,"rx buff done len %d \n",xfer_len);
++
++ rx_buf = (u8 *)i2c_dev->req_page->page_addr;
++
++ for(i=0;i<xfer_len;i++) {
++ i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt+i] = rx_buf[i];
++ dev_dbg(i2c_dev->dev,"%d, [%x] \n",i2c_dev->slave_xfer_cnt+i ,i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt+i]);
++ }
++
++ } else {
++ //RX DMA DOWN
++ xfer_len = ast_i2c_read(i2c_dev, I2C_DMA_LEN_REG);
++ if(xfer_len == 0)
++ xfer_len = i2c_dev->slave_xfer_len;
++ else
++ xfer_len = i2c_dev->slave_xfer_len - xfer_len - 1;
++
++ dev_dbg(i2c_dev->dev, " rx dma done len %d \n", xfer_len);
++
++ for(i=0;i<xfer_len;i++) {
++ i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt+i] = i2c_dev->dma_buf[i];
++ dev_dbg(i2c_dev->dev,"%d, [%x] \n",i2c_dev->slave_xfer_cnt+i ,i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt+i]);
++ }
++ }
++
++ }
++
++ if(xfer_len !=i2c_dev->slave_xfer_len) {
++ //TODO..
++ printk(" **slave xfer error ====\n");
++ //should goto stop....
++ } else
++ i2c_dev->slave_xfer_cnt += i2c_dev->slave_xfer_len;
++
++
++ if((i2c_dev->slave_event == I2C_SLAVE_EVENT_NACK) || (i2c_dev->slave_event == I2C_SLAVE_EVENT_STOP)) {
++#ifdef CONFIG_AST_I2C_SLAVE_RDWR
++ ast_i2c_slave_rdwr_xfer(i2c_dev);
++#else
++ i2c_dev->ast_i2c_data->slave_xfer(i2c_dev->slave_event, &(i2c_dev->slave_msgs));
++#endif
++ i2c_dev->slave_xfer_cnt = 0;
++ } else {
++ if(i2c_dev->slave_xfer_cnt == i2c_dev->slave_msgs->len) {
++ dev_dbg(i2c_dev->dev,"slave next msgs \n");
++#ifdef CONFIG_AST_I2C_SLAVE_RDWR
++ ast_i2c_slave_rdwr_xfer(i2c_dev);
++#else
++ i2c_dev->ast_i2c_data->slave_xfer(i2c_dev->slave_event, &(i2c_dev->slave_msgs));
++#endif
++
++ i2c_dev->slave_xfer_cnt = 0;
++ }
++ i2c_dev->do_slave_xfer(i2c_dev);
++ }
++
++
++ if(AST_I2CD_IDLE == i2c_dev->state) {
++ dev_dbg(i2c_dev->dev,"** Slave go IDLE **\n");
++ i2c_dev->slave_operation = 0;
++
++ if(i2c_dev->slave_xfer_mode == BUFF_XFER) {
++ i2c_dev->ast_i2c_data->free_pool_buff_page(i2c_dev->req_page);
++ }
++
++ }
++
++}
++
++//TX/Rx Done
++static void ast_i2c_master_xfer_done(struct ast_i2c_dev *i2c_dev)
++{
++ u32 xfer_len;
++ int i;
++ u8 *pool_buf;
++
++ dev_dbg(i2c_dev->dev, "ast_i2c_master_xfer_done mode[%d]\n",i2c_dev->master_xfer_mode);
++
++ if (i2c_dev->master_msgs->flags & I2C_M_RD) {
++ if(i2c_dev->master_xfer_cnt == -1) {
++ xfer_len = 1;
++ goto next_xfer;
++ }
++ if(i2c_dev->master_xfer_mode == BYTE_XFER) {
++ if ((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->blk_r_flag == 0)) {
++ i2c_dev->master_msgs->len += (ast_i2c_read(i2c_dev,I2C_BYTE_BUF_REG) & AST_I2CD_RX_BYTE_BUFFER) >> 8;
++ i2c_dev->blk_r_flag = 1;
++ dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN %d \n", i2c_dev->master_msgs->len -1);
++ }
++ xfer_len = 1;
++ i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt] = (ast_i2c_read(i2c_dev,I2C_BYTE_BUF_REG) & AST_I2CD_RX_BYTE_BUFFER) >> 8;
++ } else if (i2c_dev->master_xfer_mode == BUFF_XFER) {
++ pool_buf = (u8 *)i2c_dev->req_page->page_addr;
++ xfer_len = AST_I2CD_RX_BUF_ADDR_GET(ast_i2c_read(i2c_dev, I2C_BUF_CTRL_REG));
++
++ if(xfer_len == 0)
++ xfer_len = AST_I2C_PAGE_SIZE;
++
++ for(i = 0; i< xfer_len; i++) {
++ i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt + i] = pool_buf[i];
++ dev_dbg(i2c_dev->dev, "rx %d buff[%x]\n",i2c_dev->master_xfer_cnt+i, i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt+i]);
++ }
++
++ if ((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->blk_r_flag == 0)) {
++ i2c_dev->master_msgs->len += pool_buf[0];
++ i2c_dev->blk_r_flag = 1;
++ dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN %d \n", i2c_dev->master_msgs->len -1);
++ }
++ } else {
++ //DMA Mode
++ xfer_len = ast_i2c_read(i2c_dev, I2C_DMA_LEN_REG);
++
++ if(xfer_len == 0)
++ xfer_len = i2c_dev->master_xfer_len;
++ else
++ xfer_len = i2c_dev->master_xfer_len - xfer_len - 1;
++
++ for(i = 0; i < xfer_len; i++) {
++ i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt + i] = i2c_dev->dma_buf[i];
++ dev_dbg(i2c_dev->dev, "buf[%x] \n", i2c_dev->dma_buf[i]);
++ dev_dbg(i2c_dev->dev, "buf[%x] \n", i2c_dev->dma_buf[i+1]);
++ }
++
++ if ((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->blk_r_flag == 0)) {
++ i2c_dev->master_msgs->len += i2c_dev->dma_buf[0];
++ i2c_dev->blk_r_flag = 1;
++ dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN %d \n", i2c_dev->master_msgs->len -1);
++ }
++
++ }
++
++ }else {
++ if(i2c_dev->master_xfer_mode == BYTE_XFER) {
++ xfer_len = 1;
++ } else if(i2c_dev->master_xfer_mode == BUFF_XFER) {
++ xfer_len = AST_I2CD_TX_DATA_BUF_GET(ast_i2c_read(i2c_dev, I2C_BUF_CTRL_REG));
++ xfer_len++;
++ dev_dbg(i2c_dev->dev,"tx buff done len %d \n",xfer_len);
++ } else {
++ //DMA
++ xfer_len = ast_i2c_read(i2c_dev, I2C_DMA_LEN_REG);
++ if(xfer_len == 0)
++ xfer_len = i2c_dev->master_xfer_len;
++ else
++ xfer_len = i2c_dev->master_xfer_len - xfer_len - 1;
++
++ dev_dbg(i2c_dev->dev,"tx dma done len %d \n",xfer_len);
++ }
++ }
++
++next_xfer:
++
++ if(xfer_len !=i2c_dev->master_xfer_len) {
++ //TODO..
++ printk(" ** xfer error \n");
++ //should goto stop....
++ i2c_dev->cmd_err = 1;
++ goto done_out;
++ } else
++ i2c_dev->master_xfer_cnt += i2c_dev->master_xfer_len;
++
++ if(i2c_dev->master_xfer_cnt != i2c_dev->master_msgs->len) {
++ dev_dbg(i2c_dev->dev,"do next cnt \n");
++ i2c_dev->do_master_xfer(i2c_dev);
++ } else {
++#if 0
++ int i;
++ printk(" ===== \n");
++ for(i=0;i<i2c_dev->master_msgs->len;i++)
++ printk("rx buf i,[%x]\n",i,i2c_dev->master_msgs->buf[i]);
++ printk(" ===== \n");
++#endif
++ i2c_dev->cmd_err = 0;
++
++done_out:
++ dev_dbg(i2c_dev->dev,"msgs complete \n");
++ complete(&i2c_dev->cmd_complete);
++ }
++}
++
++static void ast_i2c_slave_addr_match(struct ast_i2c_dev *i2c_dev)
++{
++ u8 match;
++
++ i2c_dev->slave_operation = 1;
++ i2c_dev->slave_xfer_cnt = 0;
++ match = ast_i2c_read(i2c_dev,I2C_BYTE_BUF_REG) >> 8;
++ i2c_dev->slave_msgs->buf[0] = match;
++ dev_dbg(i2c_dev->dev, "S Start Addr match [%x] \n",match);
++
++
++ if(match & 1) {
++ i2c_dev->slave_event = I2C_SLAVE_EVENT_START_READ;
++ } else {
++ i2c_dev->slave_event = I2C_SLAVE_EVENT_START_WRITE;
++ }
++
++#ifdef CONFIG_AST_I2C_SLAVE_RDWR
++ ast_i2c_slave_rdwr_xfer(i2c_dev);
++ i2c_dev->slave_msgs->buf[0] = match;
++ i2c_dev->slave_xfer_cnt = 1;
++#else
++ i2c_dev->ast_i2c_data->slave_xfer(i2c_dev->slave_event, &(i2c_dev->slave_msgs));
++ i2c_dev->slave_xfer_cnt = 0;
++#endif
++
++ //request
++ if(i2c_dev->ast_i2c_data->slave_dma == BYTE_MODE)
++ i2c_dev->do_slave_xfer = ast_i2c_do_byte_xfer;
++ else if (i2c_dev->ast_i2c_data->slave_dma == DMA_MODE)
++ i2c_dev->do_slave_xfer = ast_i2c_do_dma_xfer;
++ else {
++ if(i2c_dev->ast_i2c_data->request_pool_buff_page(&(i2c_dev->req_page)) == 0)
++ i2c_dev->do_slave_xfer = ast_i2c_do_pool_xfer;
++ else
++ i2c_dev->do_slave_xfer = ast_i2c_do_byte_xfer;
++ }
++
++ i2c_dev->do_slave_xfer(i2c_dev);
++
++}
++
++static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
++{
++ u32 sts;
++
++ struct ast_i2c_dev *i2c_dev = dev_id;
++ u32 isr_sts = readl(i2c_dev->ast_i2c_data->reg_gr);
++
++ if(!(isr_sts & (1<< i2c_dev->bus_id)))
++ return IRQ_NONE;
++
++ i2c_dev->state = (ast_i2c_read(i2c_dev,I2C_CMD_REG) >> 19) & 0xf;
++ sts = ast_i2c_read(i2c_dev,I2C_INTR_STS_REG);
++// printk("ISR : %x , sts [%x]\n",sts , xfer_sts);
++// dev_dbg(i2c_dev->dev,"ISR : %x , sts [%x]\n",sts , xfer_sts);
++
++// dev_dbg(i2c_dev->dev,"sts machine %x, slave_op %d \n", xfer_sts,i2c_dev->slave_operation);
++
++ if(AST_I2CD_INTR_STS_SMBUS_ALT & sts) {
++ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_SMBUS_ALT= %x\n",sts);
++ //Disable ALT INT
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev, I2C_INTR_CTRL_REG) &
++ ~AST_I2CD_SMBUS_ALT_INTR_EN,
++ I2C_INTR_CTRL_REG);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_SMBUS_ALT, I2C_INTR_STS_REG);
++ ast_master_alert_recv(i2c_dev);
++ sts &= ~AST_I2CD_SMBUS_ALT_INTR_EN;
++ }
++
++ switch(sts) {
++ case AST_I2CD_INTR_STS_TX_ACK:
++ if(i2c_dev->slave_operation == 1) {
++ i2c_dev->slave_event = I2C_SLAVE_EVENT_READ;
++ ast_i2c_slave_xfer_done(i2c_dev);
++ dev_dbg(i2c_dev->dev, "S clear isr: AST_I2CD_INTR_STS_TX_ACK = %x\n",sts);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_ACK, I2C_INTR_STS_REG);
++ } else {
++ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_TX_ACK = %x\n",sts);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_ACK, I2C_INTR_STS_REG);
++ ast_i2c_master_xfer_done(i2c_dev);
++ }
++ break;
++ case AST_I2CD_INTR_STS_TX_ACK | AST_I2CD_INTR_STS_NORMAL_STOP:
++ if((i2c_dev->xfer_last == 1) && (i2c_dev->slave_operation == 0)) {
++ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_TX_ACK | AST_I2CD_INTR_STS_NORMAL_STOP= %x\n",sts);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_ACK | AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);
++ //take care
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ ast_i2c_master_xfer_done(i2c_dev);
++
++ } else {
++ printk("TODO ...\n");
++ }
++ break;
++
++ case AST_I2CD_INTR_STS_TX_NAK:
++ if(i2c_dev->slave_operation == 1) {
++ i2c_dev->slave_event = I2C_SLAVE_EVENT_NACK;
++ ast_i2c_slave_xfer_done(i2c_dev);
++ dev_dbg(i2c_dev->dev, "S clear isr: AST_I2CD_INTR_STS_TX_NAK = %x\n",sts);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_NAK, I2C_INTR_STS_REG);
++
++ } else {
++ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_TX_NAK = %x\n",sts);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_NAK, I2C_INTR_STS_REG);
++ if(i2c_dev->master_msgs->flags == I2C_M_IGNORE_NAK) {
++ dev_dbg(i2c_dev->dev, "I2C_M_IGNORE_NAK next send\n");
++ i2c_dev->cmd_err = 0;
++ } else {
++ dev_dbg(i2c_dev->dev, "NAK error\n");
++ i2c_dev->cmd_err = AST_I2CD_INTR_STS_TX_NAK;
++ }
++ complete(&i2c_dev->cmd_complete);
++ }
++ break;
++
++ case AST_I2CD_INTR_STS_TX_NAK | AST_I2CD_INTR_STS_NORMAL_STOP:
++ if(i2c_dev->slave_operation == 1) {
++ printk("SLAVE TODO .... \n");
++
++ } else {
++ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_TX_NAK| AST_I2CD_INTR_STS_NORMAL_STOP = %x\n",sts);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_NAK | AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);
++ dev_dbg(i2c_dev->dev, "M TX NAK | NORMAL STOP \n");
++ i2c_dev->cmd_err = AST_I2CD_INTR_STS_TX_NAK | AST_I2CD_INTR_STS_NORMAL_STOP;
++ complete(&i2c_dev->cmd_complete);
++ }
++ break;
++
++ //Issue : Workaround for I2C slave mode
++ case AST_I2CD_INTR_STS_TX_NAK | AST_I2CD_INTR_STS_SLAVE_MATCH:
++ if(i2c_dev->slave_operation == 1) {
++ i2c_dev->slave_event = I2C_SLAVE_EVENT_NACK;
++ ast_i2c_slave_xfer_done(i2c_dev);
++ ast_i2c_slave_addr_match(i2c_dev);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_NAK | AST_I2CD_INTR_STS_SLAVE_MATCH , I2C_INTR_STS_REG);
++ } else {
++ printk("ERROR !!!!\n");
++ }
++ break;
++ case AST_I2CD_INTR_STS_RX_DOWN | AST_I2CD_INTR_STS_SLAVE_MATCH:
++ ast_i2c_slave_addr_match(i2c_dev);
++ dev_dbg(i2c_dev->dev, "S clear isr: AST_I2CD_INTR_STS_RX_DOWN | AST_I2CD_INTR_STS_SLAVE_MATCH = %x\n",sts);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_RX_DOWN | AST_I2CD_INTR_STS_SLAVE_MATCH, I2C_INTR_STS_REG);
++ break;
++
++ case AST_I2CD_INTR_STS_RX_DOWN:
++ if(i2c_dev->slave_operation == 1) {
++ i2c_dev->slave_event = I2C_SLAVE_EVENT_WRITE;
++ ast_i2c_slave_xfer_done(i2c_dev);
++ dev_dbg(i2c_dev->dev, "S clear isr: AST_I2CD_INTR_STS_RX_DOWN = %x\n",sts);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_RX_DOWN, I2C_INTR_STS_REG);
++ } else {
++ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_RX_DOWN = %x\n",sts);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_RX_DOWN, I2C_INTR_STS_REG);
++ ast_i2c_master_xfer_done(i2c_dev);
++
++ }
++ break;
++
++ case AST_I2CD_INTR_STS_NORMAL_STOP:
++ if(i2c_dev->slave_operation == 1) {
++ i2c_dev->slave_event = I2C_SLAVE_EVENT_STOP;
++ ast_i2c_slave_xfer_done(i2c_dev);
++ dev_dbg(i2c_dev->dev, "S clear isr: AST_I2CD_INTR_STS_NORMAL_STOP = %x\n",sts);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);
++ dev_dbg(i2c_dev->dev, "state [%x] \n",i2c_dev->state);
++ } else {
++ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_NORMAL_STOP = %x\n",sts);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);
++ i2c_dev->cmd_err = 0;
++ complete(&i2c_dev->cmd_complete);
++ }
++ break;
++ case (AST_I2CD_INTR_STS_RX_DOWN | AST_I2CD_INTR_STS_NORMAL_STOP):
++ if((i2c_dev->xfer_last == 1) && (i2c_dev->slave_operation == 0)) {
++ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_RX_DOWN | AST_I2CD_INTR_STS_NORMAL_STOP = %x\n",sts);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_RX_DOWN | AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);
++ //take care
++ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
++ AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
++ ast_i2c_master_xfer_done(i2c_dev);
++ } else {
++ printk("TODO .. .. ..\n");
++ }
++ break;
++ case AST_I2CD_INTR_STS_ARBIT_LOSS:
++ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_ARBIT_LOSS = %x\n",sts);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_ARBIT_LOSS, I2C_INTR_STS_REG);
++ i2c_dev->cmd_err = AST_I2CD_INTR_STS_ARBIT_LOSS;
++ complete(&i2c_dev->cmd_complete);
++ break;
++ case AST_I2CD_INTR_STS_ABNORMAL:
++ i2c_dev->cmd_err = AST_I2CD_INTR_STS_ABNORMAL;
++ complete(&i2c_dev->cmd_complete);
++ break;
++ case AST_I2CD_INTR_STS_SCL_TO:
++ i2c_dev->cmd_err = AST_I2CD_INTR_STS_SCL_TO;
++ complete(&i2c_dev->cmd_complete);
++
++ break;
++ case AST_I2CD_INTR_STS_GCALL_ADDR:
++ i2c_dev->cmd_err = AST_I2CD_INTR_STS_GCALL_ADDR;
++ complete(&i2c_dev->cmd_complete);
++
++ break;
++ case AST_I2CD_INTR_STS_SMBUS_DEF_ADDR:
++ break;
++ case AST_I2CD_INTR_STS_SMBUS_DEV_ALT:
++
++ break;
++
++ case AST_I2CD_INTR_STS_SMBUS_ARP_ADDR:
++ break;
++ case AST_I2CD_INTR_STS_SDA_DL_TO:
++ break;
++ case AST_I2CD_INTR_STS_BUS_RECOVER:
++ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_BUS_RECOVER= %x\n",sts);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_BUS_RECOVER, I2C_INTR_STS_REG);
++ i2c_dev->cmd_err = 0;
++ complete(&i2c_dev->cmd_complete);
++ break;
++ default:
++ if(sts)
++ printk("GR %x : No one care : %x, bus_id %d\n",i2c_dev->ast_i2c_data->reg_gr, sts, i2c_dev->bus_id);
++ return IRQ_NONE;
++ }
++
++ return IRQ_HANDLED;
++
++}
++
++static int ast_i2c_do_msgs_xfer(struct ast_i2c_dev *i2c_dev, struct i2c_msg *msgs, int num)
++{
++ int i;
++ int ret = 1;
++
++ //request
++ if(i2c_dev->ast_i2c_data->master_dma == BYTE_MODE)
++ i2c_dev->do_master_xfer = ast_i2c_do_byte_xfer;
++ else if (i2c_dev->ast_i2c_data->master_dma == DMA_MODE)
++ i2c_dev->do_master_xfer = ast_i2c_do_dma_xfer;
++ else {
++ if(i2c_dev->ast_i2c_data->request_pool_buff_page(&(i2c_dev->req_page)) == 0)
++ i2c_dev->do_master_xfer = ast_i2c_do_pool_xfer;
++ else
++ i2c_dev->do_master_xfer = ast_i2c_do_byte_xfer;
++ }
++
++// printk("start xfer ret = %d \n",ret);
++
++ for (i=0; i < num; i++) {
++ i2c_dev->blk_r_flag = 0;
++ i2c_dev->master_msgs = &msgs[i];
++ if(num == i+1)
++ i2c_dev->xfer_last = 1;
++ else
++ i2c_dev->xfer_last = 0;
++
++ i2c_dev->blk_r_flag = 0;
++ init_completion(&i2c_dev->cmd_complete);
++
++ if(i2c_dev->master_msgs->flags & I2C_M_NOSTART)
++ i2c_dev->master_xfer_cnt = 0;
++ else
++ i2c_dev->master_xfer_cnt = -1;
++
++ i2c_dev->do_master_xfer(i2c_dev);
++
++ ret = wait_for_completion_interruptible_timeout(&i2c_dev->cmd_complete,
++ i2c_dev->adap.timeout*HZ);
++
++ if (ret == 0) {
++ dev_dbg(i2c_dev->dev, "controller timed out\n");
++ i2c_dev->state = (ast_i2c_read(i2c_dev,I2C_CMD_REG) >> 19) & 0xf;
++// printk("sts [%x], isr sts [%x] \n",i2c_dev->state, ast_i2c_read(i2c_dev,I2C_INTR_STS_REG));
++ ret = -ETIMEDOUT;
++ goto stop;
++ }
++
++ if(i2c_dev->cmd_err != 0) {
++ ret = -EAGAIN;
++ goto stop;
++ }
++
++ }
++
++ if(i2c_dev->cmd_err == 0) {
++ ret = num;
++ goto out;
++
++ }
++stop:
++ init_completion(&i2c_dev->cmd_complete);
++ ast_i2c_write(i2c_dev, AST_I2CD_M_STOP_CMD, I2C_CMD_REG);
++ wait_for_completion_interruptible_timeout(&i2c_dev->cmd_complete,
++ i2c_dev->adap.timeout*HZ);
++
++out:
++ //Free ..
++ if(i2c_dev->master_xfer_mode == BUFF_XFER) {
++ i2c_dev->ast_i2c_data->free_pool_buff_page(i2c_dev->req_page);
++
++ }
++ dev_dbg(i2c_dev->dev, "end xfer ret = %d, xfer mode[%d]\n",ret, i2c_dev->master_xfer_mode);
++ return ret;
++
++}
++
++static int ast_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
++{
++ struct ast_i2c_dev *i2c_dev = adap->algo_data;
++ int ret, i;
++ int sts;
++
++ sts = ast_i2c_read(i2c_dev,I2C_CMD_REG);
++ dev_dbg(i2c_dev->dev, "state[%x],SCL[%d],SDA[%d],BUS[%d]\n", (sts >> 19) & 0xf, (sts >> 18) & 0x1,(sts >> 17) & 0x1,(sts >> 16) & 1);
++ /*
++ * Wait for the bus to become free.
++ */
++
++ ret = ast_i2c_wait_bus_not_busy(i2c_dev);
++ if (ret) {
++ dev_err(&i2c_dev->adap.dev, "i2c_ast: timeout waiting for bus free\n");
++ goto out;
++ }
++
++ for (i = adap->retries; i >= 0; i--) {
++
++ ret = ast_i2c_do_msgs_xfer(i2c_dev, msgs, num);
++ if (ret != -EAGAIN)
++ goto out;
++ dev_dbg(&adap->dev, "Retrying transmission [%d]\n",i);
++ udelay(100);
++ }
++
++ ret = -EREMOTEIO;
++out:
++
++ return ret;
++}
++
++static u32 ast_i2c_functionality(struct i2c_adapter *adap)
++{
++ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_BLOCK_DATA;
++}
++
++static const struct i2c_algorithm i2c_ast_algorithm = {
++ .master_xfer = ast_i2c_xfer,
++#ifdef CONFIG_AST_I2C_SLAVE_RDWR
++ .slave_xfer = ast_i2c_slave_xfer,
++#endif
++ .functionality = ast_i2c_functionality,
++};
++
++static int ast_i2c_probe(struct platform_device *pdev)
++{
++ struct ast_i2c_dev *i2c_dev;
++ struct resource *res;
++ int ret;
++
++ dev_dbg(&pdev->dev, "ast_i2c_probe \n");
++
++ i2c_dev = kzalloc(sizeof(struct ast_i2c_dev), GFP_KERNEL);
++ if (!i2c_dev) {
++ ret = -ENOMEM;
++ goto err_no_mem;
++ }
++
++ i2c_dev->ast_i2c_data = pdev->dev.platform_data;
++ if(i2c_dev->ast_i2c_data->master_dma == BUFF_MODE) {
++ dev_dbg(&pdev->dev, "use buffer pool mode 256\n");
++
++ } else if ((i2c_dev->ast_i2c_data->master_dma == DMA_MODE) || (i2c_dev->ast_i2c_data->slave_dma == DMA_MODE)) {
++ dev_dbg(&pdev->dev, "use dma mode \n");
++ if (!i2c_dev->dma_buf) {
++ i2c_dev->dma_buf = dma_alloc_coherent(NULL, AST_I2C_DMA_SIZE, &i2c_dev->dma_addr, GFP_KERNEL);
++ if (!i2c_dev->dma_buf) {
++ printk("unable to allocate tx Buffer memory\n");
++ ret = -ENOMEM;
++ goto err_no_dma;
++ }
++ if(i2c_dev->dma_addr%4 !=0) {
++ printk("not 4 byte boundary \n");
++ ret = -ENOMEM;
++ goto err_no_dma;
++ }
++// printk("dma_buf = [0x%x] dma_addr = [0x%x], please check 4byte boundary \n",i2c_dev->dma_buf,i2c_dev->dma_addr);
++ memset (i2c_dev->dma_buf, 0, AST_I2C_DMA_SIZE);
++ }
++
++ } else {
++ //master_mode 0: use byte mode
++ dev_dbg(&pdev->dev, "use default byte mode \n");
++ }
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (NULL == res) {
++ dev_err(&pdev->dev, "cannot get IORESOURCE_MEM\n");
++ ret = -ENOENT;
++ goto err_no_io_res;
++ }
++ if (!request_mem_region(res->start, resource_size(res), res->name)) {
++ dev_err(&pdev->dev, "cannot reserved region\n");
++ ret = -ENXIO;
++ goto err_no_io_res;
++ }
++
++ i2c_dev->reg_base = ioremap(res->start, resource_size(res));
++ if (!i2c_dev->reg_base) {
++ ret = -EIO;
++ goto release_mem;
++ }
++
++ i2c_dev->irq = platform_get_irq(pdev, 0);
++ if (i2c_dev->irq < 0) {
++ dev_err(&pdev->dev, "no irq specified\n");
++ ret = -ENOENT;
++ goto ereqirq;
++ }
++
++ i2c_dev->dev = &pdev->dev;
++
++#if defined (CONFIG_ARCH_AST1070)
++ if(i2c_dev->irq == IRQ_C0_I2C) {
++ i2c_dev->bus_id = pdev->id - NUM_BUS;
++ dev_dbg(&pdev->dev, "C0 :: pdev->id %d , i2c_dev->bus_id = %d, i2c_dev->irq =%d\n",pdev->id, i2c_dev->bus_id,i2c_dev->irq);
++#if (CONFIG_AST1070_NR >= 2)
++ } else if(i2c_dev->irq == IRQ_C1_I2C) {
++ i2c_dev->bus_id = pdev->id - (NUM_BUS + 8);
++ dev_dbg(&pdev->dev, "C1 :: pdev->id %d , i2c_dev->bus_id = %d, i2c_dev->irq =%d\n",pdev->id, i2c_dev->bus_id,i2c_dev->irq);
++#endif
++ } else {
++ i2c_dev->bus_id = pdev->id;
++ dev_dbg(&pdev->dev, "AST pdev->id %d , i2c_dev->bus_id = %d, i2c_dev->irq =%d\n",pdev->id, i2c_dev->bus_id,i2c_dev->irq);
++ }
++#else
++ i2c_dev->bus_id = pdev->id;
++#endif
++
++ /* Initialize the I2C adapter */
++ i2c_dev->adap.owner = THIS_MODULE;
++//TODO
++ i2c_dev->adap.retries = 0;
++
++// i2c_dev->adap.retries = 3;
++
++ i2c_dev->adap.timeout = 5;
++
++ i2c_dev->master_xfer_mode = BYTE_XFER;
++
++ /*
++ * If "pdev->id" is negative we consider it as zero.
++ * The reason to do so is to avoid sysfs names that only make
++ * sense when there are multiple adapters.
++ */
++ i2c_dev->adap.nr = pdev->id != -1 ? pdev->id : 0;
++ snprintf(i2c_dev->adap.name, sizeof(i2c_dev->adap.name), "ast_i2c.%u",
++ i2c_dev->adap.nr);
++
++ i2c_dev->slave_operation = 0;
++ i2c_dev->blk_r_flag = 0;
++ i2c_dev->adap.algo = &i2c_ast_algorithm;
++
++ ret = request_irq(i2c_dev->irq, i2c_ast_handler, IRQF_SHARED,
++ i2c_dev->adap.name, i2c_dev);
++ if (ret) {
++ printk(KERN_INFO "I2C: Failed request irq %d\n", i2c_dev->irq);
++ goto ereqirq;
++ }
++
++ ast_i2c_dev_init(i2c_dev);
++
++#ifdef CONFIG_AST_I2C_SLAVE_RDWR
++ ast_i2c_slave_buff_init(i2c_dev);
++#endif
++
++ i2c_dev->adap.algo_data = i2c_dev;
++ i2c_dev->adap.dev.parent = &pdev->dev;
++
++ i2c_dev->adap.id = pdev->id;
++
++ ret = i2c_add_numbered_adapter(&i2c_dev->adap);
++ if (ret < 0) {
++ printk(KERN_INFO "I2C: Failed to add bus\n");
++ goto eadapt;
++ }
++
++ platform_set_drvdata(pdev, i2c_dev);
++
++ printk(KERN_INFO "I2C: %s: AST I2C adapter [%d khz]\n",
++ i2c_dev->adap.dev.bus_id,i2c_dev->ast_i2c_data->bus_clk/1000);
++
++ return 0;
++
++eadapt:
++ free_irq(i2c_dev->irq, i2c_dev);
++ereqirq:
++ iounmap(i2c_dev->reg_base);
++
++release_mem:
++ release_mem_region(res->start, resource_size(res));
++err_no_io_res:
++err_no_dma:
++ kfree(i2c_dev);
++
++err_no_mem:
++ return ret;
++}
++
++static int ast_i2c_remove(struct platform_device *pdev)
++{
++ struct ast_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
++ struct resource *res;
++
++ platform_set_drvdata(pdev, NULL);
++ i2c_del_adapter(&i2c_dev->adap);
++
++ free_irq(i2c_dev->irq, i2c_dev);
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ iounmap(i2c_dev->reg_base);
++ release_mem_region(res->start, res->end - res->start + 1);
++
++ kfree(i2c_dev);
++
++ return 0;
++}
++
++#ifdef CONFIG_PM
++static int ast_i2c_suspend(struct platform_device *pdev, pm_message_t state)
++{
++ //TODO
++// struct ast_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
++ return 0;
++}
++
++static int ast_i2c_resume(struct platform_device *pdev)
++{
++ //TODO
++// struct ast_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
++ //Should reset i2c ???
++ return 0;
++}
++#else
++#define ast_i2c_suspend NULL
++#define ast_i2c_resume NULL
++#endif
++
++static struct platform_driver i2c_ast_driver = {
++ .probe = ast_i2c_probe,
++ .remove = __devexit_p(ast_i2c_remove),
++ .suspend = ast_i2c_suspend,
++ .resume = ast_i2c_resume,
++ .driver = {
++ .name = "ast-i2c",
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init ast_i2c_init(void)
++{
++ return platform_driver_register(&i2c_ast_driver);
++}
++
++static void __exit ast_i2c_exit(void)
++{
++ platform_driver_unregister(&i2c_ast_driver);
++}
++//TODO : check module init sequence
++module_init(ast_i2c_init);
++module_exit(ast_i2c_exit);
++
++MODULE_AUTHOR("Ryan Chen <ryan_chen@aspeedtech.com>");
++MODULE_DESCRIPTION("ASPEED AST I2C Bus Driver");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:ast_i2c");
+diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
+index feb00df..5ced92c 100644
+--- a/drivers/i2c/i2c-core.c
++++ b/drivers/i2c/i2c-core.c
+@@ -1063,6 +1063,32 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)
+ }
+ EXPORT_SYMBOL(i2c_transfer);
+
++#ifdef CONFIG_AST_I2C_SLAVE_RDWR
++int i2c_slave_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs)
++{
++ unsigned long orig_jiffies;
++ int ret, try;
++
++ if (adap->algo->slave_xfer) {
++#ifdef DEBUG
++ dev_dbg(&adap->dev, "slave_xfer %c, addr=0x%02x, "
++ "len=%d\n", (msgs->flags & I2C_S_RD)
++ ? 'R' : 'W', msgs->addr, msgs->len);
++#endif
++ i2c_lock_adapter(adap);
++ ret = adap->algo->slave_xfer(adap, msgs);
++ i2c_unlock_adapter(adap);
++
++ return ret;
++ } else {
++ dev_dbg(&adap->dev, "I2C level transfers not supported\n");
++ return -EOPNOTSUPP;
++ }
++}
++EXPORT_SYMBOL(i2c_slave_transfer);
++
++#endif
++
+ /**
+ * i2c_master_send - issue a single I2C message in master transmit mode
+ * @client: Handle to slave device
+diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
+index c171988..7d1f7e9 100644
+--- a/drivers/i2c/i2c-dev.c
++++ b/drivers/i2c/i2c-dev.c
+@@ -37,6 +37,10 @@
+ #include <linux/smp_lock.h>
+ #include <asm/uaccess.h>
+
++#ifdef CONFIG_AST_I2C_SLAVE_RDWR
++#include <asm/arch/ast_i2c.h>
++#endif
++
+ static struct i2c_driver i2cdev_driver;
+
+ /*
+@@ -415,6 +419,11 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ case I2C_RDWR:
+ return i2cdev_ioctl_rdrw(client, arg);
+
++#ifdef CONFIG_AST_I2C_SLAVE_RDWR
++ case I2C_SLAVE_RDWR:
++ return i2cdev_ioctl_slave_rdrw(client->adapter, (struct i2c_msg __user *)arg);
++#endif
++
+ case I2C_SMBUS:
+ return i2cdev_ioctl_smbus(client, arg);
+
+diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
+index fdd7c76..1928a42 100644
+--- a/drivers/mmc/core/mmc.c
++++ b/drivers/mmc/core/mmc.c
+@@ -113,20 +113,29 @@ static int mmc_decode_cid(struct mmc_card *card)
+ static int mmc_decode_csd(struct mmc_card *card)
+ {
+ struct mmc_csd *csd = &card->csd;
+- unsigned int e, m, csd_struct;
++ unsigned int e, m;
+ u32 *resp = card->raw_csd;
+
+ /*
+ * We only understand CSD structure v1.1 and v1.2.
+ * v1.2 has extra information in bits 15, 11 and 10.
++ * We also support eMMC v4.4 & v4.41.
+ */
++#if 0
+ csd_struct = UNSTUFF_BITS(resp, 126, 2);
+ if (csd_struct != 1 && csd_struct != 2) {
+ printk(KERN_ERR "%s: unrecognised CSD structure version %d\n",
+ mmc_hostname(card->host), csd_struct);
+ return -EINVAL;
+ }
+-
++#else
++ csd->structure = UNSTUFF_BITS(resp, 126, 2);
++ if (csd->structure == 0) {
++ printk(KERN_ERR "%s: unrecognised CSD structure version %d\n",
++ mmc_hostname(card->host), csd->structure);
++ return -EINVAL;
++ }
++#endif
+ csd->mmca_vsn = UNSTUFF_BITS(resp, 122, 4);
+ m = UNSTUFF_BITS(resp, 115, 4);
+ e = UNSTUFF_BITS(resp, 112, 3);
+@@ -207,6 +216,7 @@ static int mmc_read_ext_csd(struct mmc_card *card)
+ goto out;
+ }
+
++#if 0
+ ext_csd_struct = ext_csd[EXT_CSD_REV];
+ if (ext_csd_struct > 2) {
+ printk(KERN_ERR "%s: unrecognised EXT_CSD structure "
+@@ -215,7 +225,7 @@ static int mmc_read_ext_csd(struct mmc_card *card)
+ err = -EINVAL;
+ goto out;
+ }
+-
++
+ if (ext_csd_struct >= 2) {
+ card->ext_csd.sectors =
+ ext_csd[EXT_CSD_SEC_CNT + 0] << 0 |
+@@ -224,7 +234,8 @@ static int mmc_read_ext_csd(struct mmc_card *card)
+ ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
+ if (card->ext_csd.sectors)
+ mmc_card_set_blockaddr(card);
+- }
++ }
++
+
+ switch (ext_csd[EXT_CSD_CARD_TYPE]) {
+ case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26:
+@@ -239,8 +250,86 @@ static int mmc_read_ext_csd(struct mmc_card *card)
+ "support any high-speed modes.\n",
+ mmc_hostname(card->host));
+ goto out;
++ }
++#else
++ /* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */
++ if (card->csd.structure == 3) {
++ int ext_csd_struct = ext_csd[EXT_CSD_STRUCTURE];
++ if (ext_csd_struct > 2) {
++ printk(KERN_ERR "%s: unrecognised EXT_CSD structure "
++ "version %d\n", mmc_hostname(card->host),
++ ext_csd_struct);
++ err = -EINVAL;
++ goto out;
++ }
+ }
+
++ card->ext_csd.rev = ext_csd[EXT_CSD_REV];
++ if (card->ext_csd.rev > 6) {
++ printk(KERN_ERR "%s: unrecognised EXT_CSD revision %d\n",
++ mmc_hostname(card->host), card->ext_csd.rev);
++ err = -EINVAL;
++ goto out;
++ }
++
++ if (card->ext_csd.rev >= 2) {
++ card->ext_csd.sectors =
++ ext_csd[EXT_CSD_SEC_CNT + 0] << 0 |
++ ext_csd[EXT_CSD_SEC_CNT + 1] << 8 |
++ ext_csd[EXT_CSD_SEC_CNT + 2] << 16 |
++ ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
++
++ /* Cards with density > 2GiB are sector addressed */
++ if (card->ext_csd.sectors > (2u * 1024 * 1024 * 1024) / 512)
++ mmc_card_set_blockaddr(card);
++ }
++
++ switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) {
++ case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26:
++ card->ext_csd.hs_max_dtr = 52000000;
++ break;
++ case EXT_CSD_CARD_TYPE_26:
++ card->ext_csd.hs_max_dtr = 26000000;
++ break;
++ default:
++ /* MMC v4 spec says this cannot happen */
++ printk(KERN_WARNING "%s: card is mmc v4 but doesn't "
++ "support any high-speed modes.\n",
++ mmc_hostname(card->host));
++ }
++
++ if (card->ext_csd.rev >= 3) {
++ u8 sa_shift = ext_csd[EXT_CSD_S_A_TIMEOUT];
++
++ /* Sleep / awake timeout in 100ns units */
++ if (sa_shift > 0 && sa_shift <= 0x17)
++ card->ext_csd.sa_timeout =
++ 1 << ext_csd[EXT_CSD_S_A_TIMEOUT];
++ card->ext_csd.erase_group_def =
++ ext_csd[EXT_CSD_ERASE_GROUP_DEF];
++ card->ext_csd.hc_erase_timeout = 300 *
++ ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT];
++ card->ext_csd.hc_erase_size =
++ ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] << 10;
++ }
++
++ if (card->ext_csd.rev >= 4) {
++ card->ext_csd.sec_trim_mult =
++ ext_csd[EXT_CSD_SEC_TRIM_MULT];
++ card->ext_csd.sec_erase_mult =
++ ext_csd[EXT_CSD_SEC_ERASE_MULT];
++ card->ext_csd.sec_feature_support =
++ ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT];
++ card->ext_csd.trim_timeout = 300 *
++ ext_csd[EXT_CSD_TRIM_MULT];
++ }
++
++ if (ext_csd[EXT_CSD_ERASED_MEM_CONT])
++ card->erased_byte = 0xFF;
++ else
++ card->erased_byte = 0x0;
++#endif
++
+ out:
+ kfree(ext_csd);
+
+diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
+index dfa585f..ce66df5 100644
+--- a/drivers/mmc/host/Kconfig
++++ b/drivers/mmc/host/Kconfig
+@@ -37,6 +37,17 @@ config MMC_SDHCI
+
+ If unsure, say N.
+
++config MMC_AST
++ tristate "ASPEED Secure Digital Host Controller Interface support"
++ depends on HAS_DMA
++ help
++ This selects the ASPEED Secure Digital Host Controller Interface.
++
++ If you have a controller with this interface, say Y or M here. You
++ also need to enable an appropriate bus interface.
++
++ If unsure, say N.
++
+ config MMC_SDHCI_PCI
+ tristate "SDHCI support on PCI bus"
+ depends on MMC_SDHCI && PCI
+diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
+index c794cc5..5078ba2 100644
+--- a/drivers/mmc/host/Makefile
++++ b/drivers/mmc/host/Makefile
+@@ -10,6 +10,7 @@ obj-$(CONFIG_MMC_ARMMMCI) += mmci.o
+ obj-$(CONFIG_MMC_PXA) += pxamci.o
+ obj-$(CONFIG_MMC_IMX) += imxmmc.o
+ obj-$(CONFIG_MMC_SDHCI) += sdhci.o
++obj-$(CONFIG_MMC_AST) += ast_sdhci.o
+ obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o
+ obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o
+ obj-$(CONFIG_MMC_WBSD) += wbsd.o
+diff --git a/drivers/mmc/host/ast_sdhci.c b/drivers/mmc/host/ast_sdhci.c
+new file mode 100644
+index 0000000..8b5d80d
+--- /dev/null
++++ b/drivers/mmc/host/ast_sdhci.c
+@@ -0,0 +1,1929 @@
++/*
++ * aspeed_sdhci.c - ASPEED Secure Digital Host Controller Interface driver
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or (at
++ * your option) any later version.
++ *
++ */
++
++#include <linux/delay.h>
++#include <linux/highmem.h>
++#include <linux/io.h>
++#include <linux/dma-mapping.h>
++#include <linux/scatterlist.h>
++#include <linux/platform_device.h>
++#include <mach/hardware.h>
++#include <mach/platform.h>
++
++#include <linux/leds.h>
++
++#include <linux/mmc/host.h>
++
++#include <plat/ast_sdhci.h>
++
++
++#define DRIVER_NAME "ast_sdhci"
++
++#define DBG(f, x...) \
++ pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x)
++
++static unsigned int debug_quirks = 0;
++
++struct ast_sdhc_platform_data *ast_sdhc_info;
++
++static void sdhci_prepare_data(struct sdhci_host *, struct mmc_data *);
++static void sdhci_finish_data(struct sdhci_host *);
++
++static void sdhci_send_command(struct sdhci_host *, struct mmc_command *);
++static void sdhci_finish_command(struct sdhci_host *);
++
++static void sdhci_dumpregs(struct sdhci_host *host)
++{
++ printk(KERN_DEBUG DRIVER_NAME ": ============== REGISTER DUMP ==============\n");
++
++ printk(KERN_DEBUG DRIVER_NAME ": Sys addr: 0x%08x | Version: 0x%08x\n",
++ readl(host->ioaddr + SDHCI_DMA_ADDRESS),
++ readw(host->ioaddr + SDHCI_HOST_VERSION));
++ printk(KERN_DEBUG DRIVER_NAME ": Blk size: 0x%08x | Blk cnt: 0x%08x\n",
++ readw(host->ioaddr + SDHCI_BLOCK_SIZE),
++ readw(host->ioaddr + SDHCI_BLOCK_COUNT));
++ printk(KERN_DEBUG DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n",
++ readl(host->ioaddr + SDHCI_ARGUMENT),
++ readw(host->ioaddr + SDHCI_TRANSFER_MODE));
++ printk(KERN_DEBUG DRIVER_NAME ": Present: 0x%08x | Host ctl: 0x%08x\n",
++ readl(host->ioaddr + SDHCI_PRESENT_STATE),
++ readb(host->ioaddr + SDHCI_HOST_CONTROL));
++ printk(KERN_DEBUG DRIVER_NAME ": Power: 0x%08x | Blk gap: 0x%08x\n",
++ readb(host->ioaddr + SDHCI_POWER_CONTROL),
++ readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL));
++ printk(KERN_DEBUG DRIVER_NAME ": Wake-up: 0x%08x | Clock: 0x%08x\n",
++ readb(host->ioaddr + SDHCI_WAKE_UP_CONTROL),
++ readw(host->ioaddr + SDHCI_CLOCK_CONTROL));
++ printk(KERN_DEBUG DRIVER_NAME ": Timeout: 0x%08x | Int stat: 0x%08x\n",
++ readb(host->ioaddr + SDHCI_TIMEOUT_CONTROL),
++ readl(host->ioaddr + SDHCI_INT_STATUS));
++ printk(KERN_DEBUG DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n",
++ readl(host->ioaddr + SDHCI_INT_ENABLE),
++ readl(host->ioaddr + SDHCI_SIGNAL_ENABLE));
++ printk(KERN_DEBUG DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
++ readw(host->ioaddr + SDHCI_ACMD12_ERR),
++ readw(host->ioaddr + SDHCI_SLOT_INT_STATUS));
++ printk(KERN_DEBUG DRIVER_NAME ": Caps: 0x%08x | Max curr: 0x%08x\n",
++ readl(host->ioaddr + SDHCI_CAPABILITIES),
++ readl(host->ioaddr + SDHCI_MAX_CURRENT));
++
++ printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n");
++}
++
++/*****************************************************************************\
++ * *
++ * Low level functions *
++ * *
++\*****************************************************************************/
++
++static void sdhci_reset(struct sdhci_host *host, u8 mask)
++{
++ unsigned long timeout;
++
++ if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
++ if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) &
++ SDHCI_CARD_PRESENT))
++ return;
++ }
++
++ writeb(mask, host->ioaddr + SDHCI_SOFTWARE_RESET);
++
++ if (mask & SDHCI_RESET_ALL)
++ host->clock = 0;
++
++ /* Wait max 100 ms */
++ timeout = 100;
++
++ /* hw clears the bit when it's done */
++ while (readb(host->ioaddr + SDHCI_SOFTWARE_RESET) & mask) {
++ if (timeout == 0) {
++ printk(KERN_ERR "%s: Reset 0x%x never completed.\n",
++ mmc_hostname(host->mmc), (int)mask);
++ sdhci_dumpregs(host);
++ return;
++ }
++ timeout--;
++ mdelay(1);
++ }
++}
++
++static void sdhci_init(struct sdhci_host *host)
++{
++ u32 intmask;
++
++ sdhci_reset(host, SDHCI_RESET_ALL);
++
++ intmask = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
++ SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX |
++ SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT |
++ SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT |
++ SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL |
++ SDHCI_INT_DMA_END | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE |
++ SDHCI_INT_ADMA_ERROR;
++
++ writel(intmask, host->ioaddr + SDHCI_INT_ENABLE);
++ writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE);
++}
++
++static void sdhci_activate_led(struct sdhci_host *host)
++{
++ u8 ctrl;
++
++ ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
++ ctrl |= SDHCI_CTRL_LED;
++ writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
++}
++
++static void sdhci_deactivate_led(struct sdhci_host *host)
++{
++ u8 ctrl;
++
++ ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
++ ctrl &= ~SDHCI_CTRL_LED;
++ writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
++}
++
++#ifdef CONFIG_LEDS_CLASS
++static void sdhci_led_control(struct led_classdev *led,
++ enum led_brightness brightness)
++{
++ struct sdhci_host *host = container_of(led, struct sdhci_host, led);
++ unsigned long flags;
++
++ spin_lock_irqsave(&host->lock, flags);
++
++ if (brightness == LED_OFF)
++ sdhci_deactivate_led(host);
++ else
++ sdhci_activate_led(host);
++
++ spin_unlock_irqrestore(&host->lock, flags);
++}
++#endif
++
++/*****************************************************************************\
++ * *
++ * Core functions *
++ * *
++\*****************************************************************************/
++
++static void sdhci_read_block_pio(struct sdhci_host *host)
++{
++ unsigned long flags;
++ size_t blksize, len, chunk;
++ u32 uninitialized_var(scratch);
++ u8 *buf;
++
++ DBG("PIO reading\n");
++
++ blksize = host->data->blksz;
++ chunk = 0;
++
++ local_irq_save(flags);
++
++ while (blksize) {
++ if (!sg_miter_next(&host->sg_miter))
++ BUG();
++
++ len = min(host->sg_miter.length, blksize);
++
++ blksize -= len;
++ host->sg_miter.consumed = len;
++
++ buf = host->sg_miter.addr;
++
++ while (len) {
++ if (chunk == 0) {
++ scratch = readl(host->ioaddr + SDHCI_BUFFER);
++ chunk = 4;
++ }
++
++ *buf = scratch & 0xFF;
++
++ buf++;
++ scratch >>= 8;
++ chunk--;
++ len--;
++ }
++ }
++
++ sg_miter_stop(&host->sg_miter);
++
++ local_irq_restore(flags);
++}
++
++static void sdhci_write_block_pio(struct sdhci_host *host)
++{
++ unsigned long flags;
++ size_t blksize, len, chunk;
++ u32 scratch;
++ u8 *buf;
++
++ DBG("PIO writing\n");
++
++ blksize = host->data->blksz;
++ chunk = 0;
++ scratch = 0;
++
++ local_irq_save(flags);
++
++ while (blksize) {
++ if (!sg_miter_next(&host->sg_miter))
++ BUG();
++
++ len = min(host->sg_miter.length, blksize);
++
++ blksize -= len;
++ host->sg_miter.consumed = len;
++
++ buf = host->sg_miter.addr;
++
++ while (len) {
++ scratch |= (u32)*buf << (chunk * 8);
++
++ buf++;
++ chunk++;
++ len--;
++
++ if ((chunk == 4) || ((len == 0) && (blksize == 0))) {
++ writel(scratch, host->ioaddr + SDHCI_BUFFER);
++ chunk = 0;
++ scratch = 0;
++ }
++ }
++ }
++
++ sg_miter_stop(&host->sg_miter);
++
++ local_irq_restore(flags);
++}
++
++static void sdhci_transfer_pio(struct sdhci_host *host)
++{
++ u32 mask;
++
++ BUG_ON(!host->data);
++
++ if (host->blocks == 0)
++ return;
++
++ if (host->data->flags & MMC_DATA_READ)
++ mask = SDHCI_DATA_AVAILABLE;
++ else
++ mask = SDHCI_SPACE_AVAILABLE;
++
++ /*
++ * Some controllers (JMicron JMB38x) mess up the buffer bits
++ * for transfers < 4 bytes. As long as it is just one block,
++ * we can ignore the bits.
++ */
++ if ((host->quirks & SDHCI_QUIRK_BROKEN_SMALL_PIO) &&
++ (host->data->blocks == 1))
++ mask = ~0;
++
++ while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) {
++ if (host->data->flags & MMC_DATA_READ)
++ sdhci_read_block_pio(host);
++ else
++ sdhci_write_block_pio(host);
++
++ host->blocks--;
++ if (host->blocks == 0)
++ break;
++ }
++
++ DBG("PIO transfer complete.\n");
++}
++
++static char *sdhci_kmap_atomic(struct scatterlist *sg, unsigned long *flags)
++{
++ local_irq_save(*flags);
++ return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
++}
++
++static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags)
++{
++ kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
++ local_irq_restore(*flags);
++}
++
++static int sdhci_adma_table_pre(struct sdhci_host *host,
++ struct mmc_data *data)
++{
++ int direction;
++
++ u8 *desc;
++ u8 *align;
++ dma_addr_t addr;
++ dma_addr_t align_addr;
++ int len, offset;
++
++ struct scatterlist *sg;
++ int i;
++ char *buffer;
++ unsigned long flags;
++
++ /*
++ * The spec does not specify endianness of descriptor table.
++ * We currently guess that it is LE.
++ */
++
++ if (data->flags & MMC_DATA_READ)
++ direction = DMA_FROM_DEVICE;
++ else
++ direction = DMA_TO_DEVICE;
++
++ /*
++ * The ADMA descriptor table is mapped further down as we
++ * need to fill it with data first.
++ */
++
++ host->align_addr = dma_map_single(mmc_dev(host->mmc),
++ host->align_buffer, 128 * 4, direction);
++ if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr))
++ goto fail;
++ BUG_ON(host->align_addr & 0x3);
++
++ host->sg_count = dma_map_sg(mmc_dev(host->mmc),
++ data->sg, data->sg_len, direction);
++ if (host->sg_count == 0)
++ goto unmap_align;
++
++ desc = host->adma_desc;
++ align = host->align_buffer;
++
++ align_addr = host->align_addr;
++
++ for_each_sg(data->sg, sg, host->sg_count, i) {
++ addr = sg_dma_address(sg);
++ len = sg_dma_len(sg);
++
++ /*
++ * The SDHCI specification states that ADMA
++ * addresses must be 32-bit aligned. If they
++ * aren't, then we use a bounce buffer for
++ * the (up to three) bytes that screw up the
++ * alignment.
++ */
++ offset = (4 - (addr & 0x3)) & 0x3;
++ if (offset) {
++ if (data->flags & MMC_DATA_WRITE) {
++ buffer = sdhci_kmap_atomic(sg, &flags);
++ WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - 3));
++ memcpy(align, buffer, offset);
++ sdhci_kunmap_atomic(buffer, &flags);
++ }
++
++ desc[7] = (align_addr >> 24) & 0xff;
++ desc[6] = (align_addr >> 16) & 0xff;
++ desc[5] = (align_addr >> 8) & 0xff;
++ desc[4] = (align_addr >> 0) & 0xff;
++
++ BUG_ON(offset > 65536);
++
++ desc[3] = (offset >> 8) & 0xff;
++ desc[2] = (offset >> 0) & 0xff;
++
++ desc[1] = 0x00;
++ desc[0] = 0x21; /* tran, valid */
++
++ align += 4;
++ align_addr += 4;
++
++ desc += 8;
++
++ addr += offset;
++ len -= offset;
++ }
++
++ desc[7] = (addr >> 24) & 0xff;
++ desc[6] = (addr >> 16) & 0xff;
++ desc[5] = (addr >> 8) & 0xff;
++ desc[4] = (addr >> 0) & 0xff;
++
++ BUG_ON(len > 65536);
++
++ desc[3] = (len >> 8) & 0xff;
++ desc[2] = (len >> 0) & 0xff;
++
++ desc[1] = 0x00;
++ desc[0] = 0x21; /* tran, valid */
++
++ desc += 8;
++
++ /*
++ * If this triggers then we have a calculation bug
++ * somewhere. :/
++ */
++ WARN_ON((desc - host->adma_desc) > (128 * 2 + 1) * 4);
++ }
++
++ /*
++ * Add a terminating entry.
++ */
++ desc[7] = 0;
++ desc[6] = 0;
++ desc[5] = 0;
++ desc[4] = 0;
++
++ desc[3] = 0;
++ desc[2] = 0;
++
++ desc[1] = 0x00;
++ desc[0] = 0x03; /* nop, end, valid */
++
++ /*
++ * Resync align buffer as we might have changed it.
++ */
++ if (data->flags & MMC_DATA_WRITE) {
++ dma_sync_single_for_device(mmc_dev(host->mmc),
++ host->align_addr, 128 * 4, direction);
++ }
++
++ host->adma_addr = dma_map_single(mmc_dev(host->mmc),
++ host->adma_desc, (128 * 2 + 1) * 4, DMA_TO_DEVICE);
++ if (dma_mapping_error(mmc_dev(host->mmc), host->adma_addr))
++ goto unmap_entries;
++ BUG_ON(host->adma_addr & 0x3);
++
++ return 0;
++
++unmap_entries:
++ dma_unmap_sg(mmc_dev(host->mmc), data->sg,
++ data->sg_len, direction);
++unmap_align:
++ dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
++ 128 * 4, direction);
++fail:
++ return -EINVAL;
++}
++
++static void sdhci_adma_table_post(struct sdhci_host *host,
++ struct mmc_data *data)
++{
++ int direction;
++
++ struct scatterlist *sg;
++ int i, size;
++ u8 *align;
++ char *buffer;
++ unsigned long flags;
++
++ if (data->flags & MMC_DATA_READ)
++ direction = DMA_FROM_DEVICE;
++ else
++ direction = DMA_TO_DEVICE;
++
++ dma_unmap_single(mmc_dev(host->mmc), host->adma_addr,
++ (128 * 2 + 1) * 4, DMA_TO_DEVICE);
++
++ dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
++ 128 * 4, direction);
++
++ if (data->flags & MMC_DATA_READ) {
++ dma_sync_sg_for_cpu(mmc_dev(host->mmc), data->sg,
++ data->sg_len, direction);
++
++ align = host->align_buffer;
++
++ for_each_sg(data->sg, sg, host->sg_count, i) {
++ if (sg_dma_address(sg) & 0x3) {
++ size = 4 - (sg_dma_address(sg) & 0x3);
++
++ buffer = sdhci_kmap_atomic(sg, &flags);
++ WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - 3));
++ memcpy(buffer, align, size);
++ sdhci_kunmap_atomic(buffer, &flags);
++
++ align += 4;
++ }
++ }
++ }
++
++ dma_unmap_sg(mmc_dev(host->mmc), data->sg,
++ data->sg_len, direction);
++}
++
++static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_data *data)
++{
++ u8 count;
++ unsigned target_timeout, current_timeout;
++
++ /*
++ * If the host controller provides us with an incorrect timeout
++ * value, just skip the check and use 0xE. The hardware may take
++ * longer to time out, but that's much better than having a too-short
++ * timeout value.
++ */
++ if ((host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL))
++ return 0xE;
++
++ /* timeout in us */
++ target_timeout = data->timeout_ns / 1000 +
++ data->timeout_clks / host->clock;
++
++ /*
++ * Figure out needed cycles.
++ * We do this in steps in order to fit inside a 32 bit int.
++ * The first step is the minimum timeout, which will have a
++ * minimum resolution of 6 bits:
++ * (1) 2^13*1000 > 2^22,
++ * (2) host->timeout_clk < 2^16
++ * =>
++ * (1) / (2) > 2^6
++ */
++ count = 0;
++ current_timeout = (1 << 13) * 1000 / host->timeout_clk;
++ while (current_timeout < target_timeout) {
++ count++;
++ current_timeout <<= 1;
++ if (count >= 0xF)
++ break;
++ }
++
++ if (count >= 0xF) {
++ printk(KERN_WARNING "%s: Too large timeout requested!\n",
++ mmc_hostname(host->mmc));
++ count = 0xE;
++ }
++
++ return count;
++}
++
++static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
++{
++ u8 count;
++ u8 ctrl;
++ int ret;
++
++ WARN_ON(host->data);
++
++ if (data == NULL)
++ return;
++
++ /* Sanity checks */
++ BUG_ON(data->blksz * data->blocks > 524288);
++ BUG_ON(data->blksz > host->mmc->max_blk_size);
++ BUG_ON(data->blocks > 65535);
++
++ host->data = data;
++ host->data_early = 0;
++
++ count = sdhci_calc_timeout(host, data);
++ writeb(count, host->ioaddr + SDHCI_TIMEOUT_CONTROL);
++
++ if (host->flags & SDHCI_USE_DMA)
++ host->flags |= SDHCI_REQ_USE_DMA;
++
++ /*
++ * FIXME: This doesn't account for merging when mapping the
++ * scatterlist.
++ */
++ if (host->flags & SDHCI_REQ_USE_DMA) {
++ int broken, i;
++ struct scatterlist *sg;
++
++ broken = 0;
++ if (host->flags & SDHCI_USE_ADMA) {
++ if (host->quirks & SDHCI_QUIRK_32BIT_ADMA_SIZE)
++ broken = 1;
++ } else {
++ if (host->quirks & SDHCI_QUIRK_32BIT_DMA_SIZE)
++ broken = 1;
++ }
++
++ if (unlikely(broken)) {
++ for_each_sg(data->sg, sg, data->sg_len, i) {
++ if (sg->length & 0x3) {
++ DBG("Reverting to PIO because of "
++ "transfer size (%d)\n",
++ sg->length);
++ host->flags &= ~SDHCI_REQ_USE_DMA;
++ break;
++ }
++ }
++ }
++ }
++
++ /*
++ * The assumption here being that alignment is the same after
++ * translation to device address space.
++ */
++ if (host->flags & SDHCI_REQ_USE_DMA) {
++ int broken, i;
++ struct scatterlist *sg;
++
++ broken = 0;
++ if (host->flags & SDHCI_USE_ADMA) {
++ /*
++ * As we use 3 byte chunks to work around
++ * alignment problems, we need to check this
++ * quirk.
++ */
++ if (host->quirks & SDHCI_QUIRK_32BIT_ADMA_SIZE)
++ broken = 1;
++ } else {
++ if (host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR)
++ broken = 1;
++ }
++
++ if (unlikely(broken)) {
++ for_each_sg(data->sg, sg, data->sg_len, i) {
++ if (sg->offset & 0x3) {
++ DBG("Reverting to PIO because of "
++ "bad alignment\n");
++ host->flags &= ~SDHCI_REQ_USE_DMA;
++ break;
++ }
++ }
++ }
++ }
++
++ if (host->flags & SDHCI_REQ_USE_DMA) {
++ if (host->flags & SDHCI_USE_ADMA) {
++ ret = sdhci_adma_table_pre(host, data);
++ if (ret) {
++ /*
++ * This only happens when someone fed
++ * us an invalid request.
++ */
++ WARN_ON(1);
++ host->flags &= ~SDHCI_REQ_USE_DMA;
++ } else {
++ writel(host->adma_addr,
++ host->ioaddr + SDHCI_ADMA_ADDRESS);
++ }
++ } else {
++ int sg_cnt;
++
++ sg_cnt = dma_map_sg(mmc_dev(host->mmc),
++ data->sg, data->sg_len,
++ (data->flags & MMC_DATA_READ) ?
++ DMA_FROM_DEVICE :
++ DMA_TO_DEVICE);
++ if (sg_cnt == 0) {
++ /*
++ * This only happens when someone fed
++ * us an invalid request.
++ */
++ WARN_ON(1);
++ host->flags &= ~SDHCI_REQ_USE_DMA;
++ } else {
++ WARN_ON(sg_cnt != 1);
++ writel(sg_dma_address(data->sg),
++ host->ioaddr + SDHCI_DMA_ADDRESS);
++ }
++ }
++ }
++
++ /*
++ * Always adjust the DMA selection as some controllers
++ * (e.g. JMicron) can't do PIO properly when the selection
++ * is ADMA.
++ */
++ if (host->version >= SDHCI_SPEC_200) {
++ ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
++ ctrl &= ~SDHCI_CTRL_DMA_MASK;
++ if ((host->flags & SDHCI_REQ_USE_DMA) &&
++ (host->flags & SDHCI_USE_ADMA))
++ ctrl |= SDHCI_CTRL_ADMA32;
++ else
++ ctrl |= SDHCI_CTRL_SDMA;
++ writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
++ }
++
++ if (!(host->flags & SDHCI_REQ_USE_DMA)) {
++ sg_miter_start(&host->sg_miter,
++ data->sg, data->sg_len, SG_MITER_ATOMIC);
++ host->blocks = data->blocks;
++ }
++
++ /* We do not handle DMA boundaries, so set it to max (512 KiB) */
++ writew(SDHCI_MAKE_BLKSZ(7, data->blksz),
++ host->ioaddr + SDHCI_BLOCK_SIZE);
++ writew(data->blocks, host->ioaddr + SDHCI_BLOCK_COUNT);
++}
++
++static void sdhci_set_transfer_mode(struct sdhci_host *host,
++ struct mmc_data *data)
++{
++ u16 mode;
++
++ if (data == NULL)
++ return;
++
++ WARN_ON(!host->data);
++
++ mode = SDHCI_TRNS_BLK_CNT_EN;
++ if (data->blocks > 1)
++ mode |= SDHCI_TRNS_MULTI | SDHCI_TRNS_ACMD12;
++// mode |= SDHCI_TRNS_MULTI;
++ if (data->flags & MMC_DATA_READ)
++ mode |= SDHCI_TRNS_READ;
++ if (host->flags & SDHCI_REQ_USE_DMA)
++ mode |= SDHCI_TRNS_DMA;
++
++ writew(mode, host->ioaddr + SDHCI_TRANSFER_MODE);
++}
++
++static void sdhci_finish_data(struct sdhci_host *host)
++{
++ struct mmc_data *data;
++
++ BUG_ON(!host->data);
++
++ data = host->data;
++ host->data = NULL;
++
++ if (host->flags & SDHCI_REQ_USE_DMA) {
++ if (host->flags & SDHCI_USE_ADMA)
++ sdhci_adma_table_post(host, data);
++ else {
++ dma_unmap_sg(mmc_dev(host->mmc), data->sg,
++ data->sg_len, (data->flags & MMC_DATA_READ) ?
++ DMA_FROM_DEVICE : DMA_TO_DEVICE);
++ }
++ }
++
++ /*
++ * The specification states that the block count register must
++ * be updated, but it does not specify at what point in the
++ * data flow. That makes the register entirely useless to read
++ * back so we have to assume that nothing made it to the card
++ * in the event of an error.
++ */
++ if (data->error)
++ data->bytes_xfered = 0;
++ else
++ data->bytes_xfered = data->blksz * data->blocks;
++
++ if (data->stop) {
++ /*
++ * The controller needs a reset of internal state machines
++ * upon error conditions.
++ */
++ if (data->error) {
++ sdhci_reset(host, SDHCI_RESET_CMD);
++ sdhci_reset(host, SDHCI_RESET_DATA);
++ }
++
++ sdhci_send_command(host, data->stop);
++ } else
++ tasklet_schedule(&host->finish_tasklet);
++}
++
++static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
++{
++ int flags;
++ u32 mask;
++ unsigned long timeout;
++
++ WARN_ON(host->cmd);
++
++ /* Wait max 10 ms */
++ timeout = 10;
++
++ mask = SDHCI_CMD_INHIBIT;
++ if ((cmd->data != NULL) || (cmd->flags & MMC_RSP_BUSY))
++ mask |= SDHCI_DATA_INHIBIT;
++
++ /* We shouldn't wait for data inihibit for stop commands, even
++ though they might use busy signaling */
++ if (host->mrq->data && (cmd == host->mrq->data->stop))
++ mask &= ~SDHCI_DATA_INHIBIT;
++
++ while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) {
++ if (timeout == 0) {
++ printk(KERN_ERR "%s: Controller never released "
++ "inhibit bit(s).\n", mmc_hostname(host->mmc));
++ sdhci_dumpregs(host);
++ cmd->error = -EIO;
++ tasklet_schedule(&host->finish_tasklet);
++ return;
++ }
++ timeout--;
++ mdelay(1);
++ }
++
++ mod_timer(&host->timer, jiffies + 10 * HZ);
++
++ host->cmd = cmd;
++
++ sdhci_prepare_data(host, cmd->data);
++
++ writel(cmd->arg, host->ioaddr + SDHCI_ARGUMENT);
++
++ sdhci_set_transfer_mode(host, cmd->data);
++
++ if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) {
++ printk(KERN_ERR "%s: Unsupported response type!\n",
++ mmc_hostname(host->mmc));
++ cmd->error = -EINVAL;
++ tasklet_schedule(&host->finish_tasklet);
++ return;
++ }
++
++ if (!(cmd->flags & MMC_RSP_PRESENT))
++ flags = SDHCI_CMD_RESP_NONE;
++ else if (cmd->flags & MMC_RSP_136)
++ flags = SDHCI_CMD_RESP_LONG;
++ else if (cmd->flags & MMC_RSP_BUSY)
++ flags = SDHCI_CMD_RESP_SHORT_BUSY;
++ else
++ flags = SDHCI_CMD_RESP_SHORT;
++
++ if (cmd->flags & MMC_RSP_CRC)
++ flags |= SDHCI_CMD_CRC;
++ if (cmd->flags & MMC_RSP_OPCODE)
++ flags |= SDHCI_CMD_INDEX;
++ if (cmd->data)
++ flags |= SDHCI_CMD_DATA;
++
++ writew(SDHCI_MAKE_CMD(cmd->opcode, flags),
++ host->ioaddr + SDHCI_COMMAND);
++}
++
++static void sdhci_finish_command(struct sdhci_host *host)
++{
++ int i;
++
++ BUG_ON(host->cmd == NULL);
++
++ if (host->cmd->flags & MMC_RSP_PRESENT) {
++ if (host->cmd->flags & MMC_RSP_136) {
++ /* CRC is stripped so we need to do some shifting. */
++ for (i = 0;i < 4;i++) {
++ host->cmd->resp[i] = readl(host->ioaddr +
++ SDHCI_RESPONSE + (3-i)*4) << 8;
++ if (i != 3)
++ host->cmd->resp[i] |=
++ readb(host->ioaddr +
++ SDHCI_RESPONSE + (3-i)*4-1);
++ }
++ } else {
++ host->cmd->resp[0] = readl(host->ioaddr + SDHCI_RESPONSE);
++ }
++ }
++
++ host->cmd->error = 0;
++
++ if (host->data && host->data_early)
++ sdhci_finish_data(host);
++
++ if (!host->cmd->data)
++ tasklet_schedule(&host->finish_tasklet);
++
++ host->cmd = NULL;
++}
++
++static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
++{
++ int div;
++ u16 clk;
++ unsigned long timeout;
++
++ if (clock == host->clock)
++ return;
++
++ writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
++
++ if (clock == 0)
++ goto out;
++
++ for (div = 1;div < 256;div *= 2) {
++ if ((host->max_clk / div) <= clock)
++ break;
++ }
++ div >>= 1;
++
++ //Issue : For ast2300, ast2400 couldn't set div = 0 means /1 , so set source is ~50Mhz up
++
++ clk = div << SDHCI_DIVIDER_SHIFT;
++ clk |= SDHCI_CLOCK_INT_EN;
++ writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);
++
++ /* Wait max 10 ms */
++ timeout = 10;
++ while (!((clk = readw(host->ioaddr + SDHCI_CLOCK_CONTROL))
++ & SDHCI_CLOCK_INT_STABLE)) {
++ if (timeout == 0) {
++ printk(KERN_ERR "%s: Internal clock never "
++ "stabilised.\n", mmc_hostname(host->mmc));
++ sdhci_dumpregs(host);
++ return;
++ }
++ timeout--;
++ mdelay(1);
++ }
++
++ clk |= SDHCI_CLOCK_CARD_EN;
++ writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);
++
++out:
++ host->clock = clock;
++}
++
++static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
++{
++ u8 pwr;
++
++ if (host->power == power)
++ return;
++
++ if (power == (unsigned short)-1) {
++ writeb(0, host->ioaddr + SDHCI_POWER_CONTROL);
++ goto out;
++ }
++
++ /*
++ * Spec says that we should clear the power reg before setting
++ * a new value. Some controllers don't seem to like this though.
++ */
++ if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
++ writeb(0, host->ioaddr + SDHCI_POWER_CONTROL);
++
++ pwr = SDHCI_POWER_ON;
++
++ switch (1 << power) {
++ case MMC_VDD_165_195:
++ pwr |= SDHCI_POWER_180;
++ break;
++ case MMC_VDD_29_30:
++ case MMC_VDD_30_31:
++ pwr |= SDHCI_POWER_300;
++ break;
++ case MMC_VDD_32_33:
++ case MMC_VDD_33_34:
++ pwr |= SDHCI_POWER_330;
++ break;
++ default:
++ BUG();
++ }
++
++ /*
++ * At least the Marvell CaFe chip gets confused if we set the voltage
++ * and set turn on power at the same time, so set the voltage first.
++ */
++ if ((host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER))
++ writeb(pwr & ~SDHCI_POWER_ON,
++ host->ioaddr + SDHCI_POWER_CONTROL);
++
++ writeb(pwr, host->ioaddr + SDHCI_POWER_CONTROL);
++
++out:
++ host->power = power;
++}
++
++/*****************************************************************************\
++ * *
++ * MMC callbacks *
++ * *
++\*****************************************************************************/
++
++static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
++{
++ struct sdhci_host *host;
++ unsigned long flags;
++
++ host = mmc_priv(mmc);
++
++ spin_lock_irqsave(&host->lock, flags);
++
++ WARN_ON(host->mrq != NULL);
++
++#ifndef CONFIG_LEDS_CLASS
++ sdhci_activate_led(host);
++#endif
++
++ host->mrq = mrq;
++
++ if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)
++ || (host->flags & SDHCI_DEVICE_DEAD)) {
++ host->mrq->cmd->error = -ENOMEDIUM;
++ tasklet_schedule(&host->finish_tasklet);
++ } else
++ sdhci_send_command(host, mrq->cmd);
++
++ mmiowb();
++ spin_unlock_irqrestore(&host->lock, flags);
++}
++
++static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
++{
++ struct sdhci_host *host;
++ unsigned long flags;
++ u8 ctrl;
++
++ host = mmc_priv(mmc);
++
++ spin_lock_irqsave(&host->lock, flags);
++
++ if (host->flags & SDHCI_DEVICE_DEAD)
++ goto out;
++
++ /*
++ * Reset the chip on each power off.
++ * Should clear out any weird states.
++ */
++ if (ios->power_mode == MMC_POWER_OFF) {
++ writel(0, host->ioaddr + SDHCI_SIGNAL_ENABLE);
++ sdhci_init(host);
++ }
++
++ sdhci_set_clock(host, ios->clock);
++
++ if (ios->power_mode == MMC_POWER_OFF)
++ sdhci_set_power(host, -1);
++ else
++ sdhci_set_power(host, ios->vdd);
++
++ ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
++
++ if (ios->bus_width == MMC_BUS_WIDTH_4)
++ ctrl |= SDHCI_CTRL_4BITBUS;
++ else
++ ctrl &= ~SDHCI_CTRL_4BITBUS;
++
++ if (ios->timing == MMC_TIMING_SD_HS)
++ ctrl |= SDHCI_CTRL_HISPD;
++ else
++ ctrl &= ~SDHCI_CTRL_HISPD;
++
++ writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
++
++ /*
++ * Some (ENE) controllers go apeshit on some ios operation,
++ * signalling timeout and CRC errors even on CMD0. Resetting
++ * it on each ios seems to solve the problem.
++ */
++ if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
++ sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
++
++out:
++ mmiowb();
++ spin_unlock_irqrestore(&host->lock, flags);
++}
++
++static int sdhci_get_ro(struct mmc_host *mmc)
++{
++ struct sdhci_host *host;
++ unsigned long flags;
++ int present;
++
++ host = mmc_priv(mmc);
++
++ spin_lock_irqsave(&host->lock, flags);
++
++ if (host->flags & SDHCI_DEVICE_DEAD)
++ present = 0;
++ else
++ present = readl(host->ioaddr + SDHCI_PRESENT_STATE);
++
++ spin_unlock_irqrestore(&host->lock, flags);
++
++ return !(present & SDHCI_WRITE_PROTECT);
++}
++
++static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
++{
++ struct sdhci_host *host;
++ unsigned long flags;
++ u32 ier;
++
++ host = mmc_priv(mmc);
++
++ spin_lock_irqsave(&host->lock, flags);
++
++ if (host->flags & SDHCI_DEVICE_DEAD)
++ goto out;
++
++ ier = readl(host->ioaddr + SDHCI_INT_ENABLE);
++
++ ier &= ~SDHCI_INT_CARD_INT;
++ if (enable)
++ ier |= SDHCI_INT_CARD_INT;
++
++ writel(ier, host->ioaddr + SDHCI_INT_ENABLE);
++ writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE);
++
++out:
++ mmiowb();
++
++ spin_unlock_irqrestore(&host->lock, flags);
++}
++
++static const struct mmc_host_ops sdhci_ops = {
++ .request = sdhci_request,
++ .set_ios = sdhci_set_ios,
++ .get_ro = sdhci_get_ro,
++ .enable_sdio_irq = sdhci_enable_sdio_irq,
++};
++
++/*****************************************************************************\
++ * *
++ * Tasklets *
++ * *
++\*****************************************************************************/
++
++static void sdhci_tasklet_card(unsigned long param)
++{
++ struct sdhci_host *host;
++ unsigned long flags;
++
++ host = (struct sdhci_host*)param;
++
++ spin_lock_irqsave(&host->lock, flags);
++
++ if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
++ if (host->mrq) {
++ printk(KERN_ERR "%s: Card removed during transfer!\n",
++ mmc_hostname(host->mmc));
++ printk(KERN_ERR "%s: Resetting controller.\n",
++ mmc_hostname(host->mmc));
++
++ sdhci_reset(host, SDHCI_RESET_CMD);
++ sdhci_reset(host, SDHCI_RESET_DATA);
++
++ host->mrq->cmd->error = -ENOMEDIUM;
++ tasklet_schedule(&host->finish_tasklet);
++ }
++ }
++
++ spin_unlock_irqrestore(&host->lock, flags);
++
++ mmc_detect_change(host->mmc, msecs_to_jiffies(200));
++}
++
++static void sdhci_tasklet_finish(unsigned long param)
++{
++ struct sdhci_host *host;
++ unsigned long flags;
++ struct mmc_request *mrq;
++
++ host = (struct sdhci_host*)param;
++
++ spin_lock_irqsave(&host->lock, flags);
++
++ del_timer(&host->timer);
++
++ mrq = host->mrq;
++
++ /*
++ * The controller needs a reset of internal state machines
++ * upon error conditions.
++ */
++ if (!(host->flags & SDHCI_DEVICE_DEAD) &&
++ (mrq->cmd->error ||
++ (mrq->data && (mrq->data->error ||
++ (mrq->data->stop && mrq->data->stop->error))) ||
++ (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST))) {
++
++ /* Some controllers need this kick or reset won't work here */
++ if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) {
++ unsigned int clock;
++
++ /* This is to force an update */
++ clock = host->clock;
++ host->clock = 0;
++ sdhci_set_clock(host, clock);
++ }
++
++ /* Spec says we should do both at the same time, but Ricoh
++ controllers do not like that. */
++ sdhci_reset(host, SDHCI_RESET_CMD);
++ sdhci_reset(host, SDHCI_RESET_DATA);
++ }
++
++ host->mrq = NULL;
++ host->cmd = NULL;
++ host->data = NULL;
++
++#ifndef CONFIG_LEDS_CLASS
++ sdhci_deactivate_led(host);
++#endif
++
++ mmiowb();
++ spin_unlock_irqrestore(&host->lock, flags);
++
++ mmc_request_done(host->mmc, mrq);
++}
++
++static void sdhci_timeout_timer(unsigned long data)
++{
++ struct sdhci_host *host;
++ unsigned long flags;
++
++ host = (struct sdhci_host*)data;
++
++ spin_lock_irqsave(&host->lock, flags);
++
++ if (host->mrq) {
++ printk(KERN_ERR "%s: Timeout waiting for hardware "
++ "interrupt.\n", mmc_hostname(host->mmc));
++ sdhci_dumpregs(host);
++
++ if (host->data) {
++ host->data->error = -ETIMEDOUT;
++ sdhci_finish_data(host);
++ } else {
++ if (host->cmd)
++ host->cmd->error = -ETIMEDOUT;
++ else
++ host->mrq->cmd->error = -ETIMEDOUT;
++
++ tasklet_schedule(&host->finish_tasklet);
++ }
++ }
++
++ mmiowb();
++ spin_unlock_irqrestore(&host->lock, flags);
++}
++
++/*****************************************************************************\
++ * *
++ * Interrupt handling *
++ * *
++\*****************************************************************************/
++
++static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
++{
++ BUG_ON(intmask == 0);
++
++ if (!host->cmd) {
++ printk(KERN_ERR "%s: Got command interrupt 0x%08x even "
++ "though no command operation was in progress.\n",
++ mmc_hostname(host->mmc), (unsigned)intmask);
++ sdhci_dumpregs(host);
++ return;
++ }
++
++ if (intmask & SDHCI_INT_TIMEOUT)
++ host->cmd->error = -ETIMEDOUT;
++ else if (intmask & (SDHCI_INT_CRC | SDHCI_INT_END_BIT |
++ SDHCI_INT_INDEX))
++ host->cmd->error = -EILSEQ;
++
++ if (host->cmd->error) {
++ tasklet_schedule(&host->finish_tasklet);
++ return;
++ }
++
++ /*
++ * The host can send and interrupt when the busy state has
++ * ended, allowing us to wait without wasting CPU cycles.
++ * Unfortunately this is overloaded on the "data complete"
++ * interrupt, so we need to take some care when handling
++ * it.
++ *
++ * Note: The 1.0 specification is a bit ambiguous about this
++ * feature so there might be some problems with older
++ * controllers.
++ */
++ if (host->cmd->flags & MMC_RSP_BUSY) {
++ if (host->cmd->data)
++ DBG("Cannot wait for busy signal when also "
++ "doing a data transfer");
++ else if (!(host->quirks & SDHCI_QUIRK_NO_BUSY_IRQ))
++ return;
++
++ /* The controller does not support the end-of-busy IRQ,
++ * fall through and take the SDHCI_INT_RESPONSE */
++ }
++
++ if (intmask & SDHCI_INT_RESPONSE)
++ sdhci_finish_command(host);
++}
++
++static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
++{
++ BUG_ON(intmask == 0);
++
++ if (!host->data) {
++ /*
++ * The "data complete" interrupt is also used to
++ * indicate that a busy state has ended. See comment
++ * above in sdhci_cmd_irq().
++ */
++ if (host->cmd && (host->cmd->flags & MMC_RSP_BUSY)) {
++ if (intmask & SDHCI_INT_DATA_END) {
++ sdhci_finish_command(host);
++ return;
++ }
++ }
++
++ printk(KERN_ERR "%s: Got data interrupt 0x%08x even "
++ "though no data operation was in progress.\n",
++ mmc_hostname(host->mmc), (unsigned)intmask);
++ sdhci_dumpregs(host);
++
++ return;
++ }
++
++ if (intmask & SDHCI_INT_DATA_TIMEOUT)
++ host->data->error = -ETIMEDOUT;
++ else if (intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_END_BIT))
++ host->data->error = -EILSEQ;
++ else if (intmask & SDHCI_INT_ADMA_ERROR)
++ host->data->error = -EIO;
++
++ if (host->data->error)
++ sdhci_finish_data(host);
++ else {
++ if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL))
++ sdhci_transfer_pio(host);
++
++ /*
++ * We currently don't do anything fancy with DMA
++ * boundaries, but as we can't disable the feature
++ * we need to at least restart the transfer.
++ */
++ if (intmask & SDHCI_INT_DMA_END)
++ writel(readl(host->ioaddr + SDHCI_DMA_ADDRESS),
++ host->ioaddr + SDHCI_DMA_ADDRESS);
++
++ if (intmask & SDHCI_INT_DATA_END) {
++ if (host->cmd) {
++ /*
++ * Data managed to finish before the
++ * command completed. Make sure we do
++ * things in the proper order.
++ */
++ host->data_early = 1;
++ } else {
++ sdhci_finish_data(host);
++ }
++ }
++ }
++}
++
++static irqreturn_t sdhci_irq(int irq, void *dev_id)
++{
++ irqreturn_t result;
++ struct sdhci_host* host = dev_id;
++ u32 intmask;
++ int cardint = 0;
++
++ spin_lock(&host->lock);
++
++ intmask = readl(host->ioaddr + SDHCI_INT_STATUS);
++
++ if (!intmask || intmask == 0xffffffff) {
++ result = IRQ_NONE;
++ goto out;
++ }
++
++ DBG("*** %s got interrupt: 0x%08x\n",
++ mmc_hostname(host->mmc), intmask);
++
++ if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
++ writel(intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE),
++ host->ioaddr + SDHCI_INT_STATUS);
++ tasklet_schedule(&host->card_tasklet);
++ }
++
++ intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
++
++ if (intmask & SDHCI_INT_CMD_MASK) {
++ writel(intmask & SDHCI_INT_CMD_MASK,
++ host->ioaddr + SDHCI_INT_STATUS);
++ sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
++ }
++
++ if (intmask & SDHCI_INT_DATA_MASK) {
++ writel(intmask & SDHCI_INT_DATA_MASK,
++ host->ioaddr + SDHCI_INT_STATUS);
++ sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
++ }
++
++ intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK);
++
++ intmask &= ~SDHCI_INT_ERROR;
++
++ if (intmask & SDHCI_INT_BUS_POWER) {
++ printk(KERN_ERR "%s: Card is consuming too much power!\n",
++ mmc_hostname(host->mmc));
++ writel(SDHCI_INT_BUS_POWER, host->ioaddr + SDHCI_INT_STATUS);
++ }
++
++ intmask &= ~SDHCI_INT_BUS_POWER;
++
++ if (intmask & SDHCI_INT_CARD_INT)
++ cardint = 1;
++
++ intmask &= ~SDHCI_INT_CARD_INT;
++
++ if (intmask) {
++ printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n",
++ mmc_hostname(host->mmc), intmask);
++ sdhci_dumpregs(host);
++
++ writel(intmask, host->ioaddr + SDHCI_INT_STATUS);
++ }
++
++ result = IRQ_HANDLED;
++
++ mmiowb();
++out:
++ spin_unlock(&host->lock);
++
++ /*
++ * We have to delay this as it calls back into the driver.
++ */
++ if (cardint)
++ mmc_signal_sdio_irq(host->mmc);
++
++ return result;
++}
++
++/*****************************************************************************\
++ * *
++ * Suspend/resume *
++ * *
++\*****************************************************************************/
++
++#ifdef CONFIG_PM
++
++int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state)
++{
++ int ret;
++
++ ret = mmc_suspend_host(host->mmc, state);
++ if (ret)
++ return ret;
++
++ free_irq(host->irq, host);
++
++ return 0;
++}
++
++EXPORT_SYMBOL_GPL(sdhci_suspend_host);
++
++int sdhci_resume_host(struct sdhci_host *host)
++{
++ int ret;
++
++ if (host->flags & SDHCI_USE_DMA) {
++/*
++ if (host->ops->enable_dma)
++ host->ops->enable_dma(host);
++*/
++ }
++
++ ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
++ mmc_hostname(host->mmc), host);
++ if (ret)
++ return ret;
++
++ sdhci_init(host);
++ mmiowb();
++
++ ret = mmc_resume_host(host->mmc);
++ if (ret)
++ return ret;
++
++ return 0;
++}
++
++EXPORT_SYMBOL_GPL(sdhci_resume_host);
++
++#endif /* CONFIG_PM */
++
++/*****************************************************************************\
++ * *
++ * Device allocation/registration *
++ * *
++\*****************************************************************************/
++
++struct sdhci_host *sdhci_alloc_host(struct device *dev,
++ size_t priv_size)
++{
++ struct mmc_host *mmc;
++ struct sdhci_host *host;
++
++ WARN_ON(dev == NULL);
++
++ mmc = mmc_alloc_host(sizeof(struct sdhci_host) + priv_size, dev);
++ if (!mmc)
++ return ERR_PTR(-ENOMEM);
++
++ host = mmc_priv(mmc);
++ host->mmc = mmc;
++
++ return host;
++}
++
++//EXPORT_SYMBOL_GPL(sdhci_alloc_host);
++
++int sdhci_add_host(struct sdhci_host *host)
++{
++ struct mmc_host *mmc;
++ unsigned int caps, temp;
++ int ret;
++
++ WARN_ON(host == NULL);
++ if (host == NULL)
++ return -EINVAL;
++#if 0
++ //TODO
++//Both ports's capabilities are 0, software needs to reset SDIO
++#define SDIO000 0x1e740000
++#define SDIO004 0x1e740004
++
++#define SDIO_ALL_SOFTWARE_RESET 0x01
++
++ if ((*(unsigned int*)(IO_ADDRESS(0x1E740140)) == 0) && (*(unsigned int*)(IO_ADDRESS(0x1E740240)) == 0)) {
++ temp = *(unsigned int*)(IO_ADDRESS(SDIO000));
++ *(unsigned int*)(IO_ADDRESS(SDIO000)) = temp | SDIO_ALL_SOFTWARE_RESET;
++ barrier();
++ do {
++ temp = (*(unsigned int*)(IO_ADDRESS(SDIO000)) & SDIO_ALL_SOFTWARE_RESET);
++ } while (temp == SDIO_ALL_SOFTWARE_RESET);
++ }
++ //Card detect debounce timing
++ *(unsigned int*)(IO_ADDRESS(SDIO004)) = 0x1000;
++#endif
++ ///////////////////////////////////////////////////////////////////
++
++ mmc = host->mmc;
++
++ if (debug_quirks)
++ host->quirks = debug_quirks;
++
++ sdhci_reset(host, SDHCI_RESET_ALL);
++
++ host->version = readw(host->ioaddr + SDHCI_HOST_VERSION);
++ host->version = (host->version & SDHCI_SPEC_VER_MASK)
++ >> SDHCI_SPEC_VER_SHIFT;
++ if (host->version > SDHCI_SPEC_200) {
++ printk(KERN_ERR "%s: Unknown controller version (%d). "
++ "You may experience problems.\n", mmc_hostname(mmc),
++ host->version);
++ }
++
++ caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
++
++ //Ryan Add for timeout
++ host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
++// host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12;
++
++ if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
++ host->flags |= SDHCI_USE_DMA;
++ else if (!(caps & SDHCI_CAN_DO_DMA))
++ DBG("Controller doesn't have DMA capability\n");
++ else
++ host->flags |= SDHCI_USE_DMA;
++
++ if ((host->quirks & SDHCI_QUIRK_BROKEN_DMA) &&
++ (host->flags & SDHCI_USE_DMA)) {
++ DBG("Disabling DMA as it is marked broken\n");
++ host->flags &= ~SDHCI_USE_DMA;
++ }
++
++ if (host->flags & SDHCI_USE_DMA) {
++ if ((host->version >= SDHCI_SPEC_200) &&
++ (caps & SDHCI_CAN_DO_ADMA2))
++ host->flags |= SDHCI_USE_ADMA;
++ }
++
++ if ((host->quirks & SDHCI_QUIRK_BROKEN_ADMA) &&
++ (host->flags & SDHCI_USE_ADMA)) {
++ DBG("Disabling ADMA as it is marked broken\n");
++ host->flags &= ~SDHCI_USE_ADMA;
++ }
++
++ if (host->flags & SDHCI_USE_DMA) {
++/*
++ if (host->ops->enable_dma) {
++ if (host->ops->enable_dma(host)) {
++ printk(KERN_WARNING "%s: No suitable DMA "
++ "available. Falling back to PIO.\n",
++ mmc_hostname(mmc));
++ host->flags &= ~(SDHCI_USE_DMA | SDHCI_USE_ADMA);
++ }
++ }
++*/
++ }
++
++ if (host->flags & SDHCI_USE_ADMA) {
++ /*
++ * We need to allocate descriptors for all sg entries
++ * (128) and potentially one alignment transfer for
++ * each of those entries.
++ */
++ host->adma_desc = kmalloc((128 * 2 + 1) * 4, GFP_KERNEL);
++ host->align_buffer = kmalloc(128 * 4, GFP_KERNEL);
++ if (!host->adma_desc || !host->align_buffer) {
++ kfree(host->adma_desc);
++ kfree(host->align_buffer);
++ printk(KERN_WARNING "%s: Unable to allocate ADMA "
++ "buffers. Falling back to standard DMA.\n",
++ mmc_hostname(mmc));
++ host->flags &= ~SDHCI_USE_ADMA;
++ }
++ }
++
++ /*
++ * If we use DMA, then it's up to the caller to set the DMA
++ * mask, but PIO does not need the hw shim so we set a new
++ * mask here in that case.
++ */
++ if (!(host->flags & SDHCI_USE_DMA)) {
++ host->dma_mask = DMA_BIT_MASK(64);
++ mmc_dev(host->mmc)->dma_mask = &host->dma_mask;
++ }
++
++// host->max_clk =
++// (caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT;
++
++ host->max_clk = ast_sdhc_info->sd_clock_src_get()/1000000;
++// printk("host->max_clk = %d Mhz\n",host->max_clk);
++
++ if (host->max_clk == 0) {
++ printk(KERN_ERR "%s: Hardware doesn't specify base clock "
++ "frequency.\n", mmc_hostname(mmc));
++ return -ENODEV;
++ }
++ host->max_clk *= 1000000;
++
++ //Ryan modify for calc timeout issue
++ host->timeout_clk = ast_sdhc_info->sd_clock_src_get()/1000000;
++// (caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
++ if (host->timeout_clk == 0) {
++ printk(KERN_ERR "%s: Hardware doesn't specify timeout clock "
++ "frequency.\n", mmc_hostname(mmc));
++ return -ENODEV;
++ }
++ if (caps & SDHCI_TIMEOUT_CLK_UNIT)
++ host->timeout_clk *= 1000;
++
++ /*
++ * Set host parameters.
++ */
++ mmc->ops = &sdhci_ops;
++ mmc->f_min = host->max_clk / 256;
++ mmc->f_max = host->max_clk;
++ mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
++
++ if ((caps & SDHCI_CAN_DO_HISPD) ||
++ (host->quirks & SDHCI_QUIRK_FORCE_HIGHSPEED))
++ mmc->caps |= MMC_CAP_SD_HIGHSPEED;
++
++ mmc->caps |= MMC_CAP_MMC_HIGHSPEED;
++
++ mmc->ocr_avail = 0;
++ if (caps & SDHCI_CAN_VDD_330)
++ mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34;
++ if (caps & SDHCI_CAN_VDD_300)
++ mmc->ocr_avail |= MMC_VDD_29_30|MMC_VDD_30_31;
++ if (caps & SDHCI_CAN_VDD_180)
++ mmc->ocr_avail |= MMC_VDD_165_195;
++
++ if (mmc->ocr_avail == 0) {
++ printk(KERN_ERR "%s: Hardware doesn't report any "
++ "support voltages.\n", mmc_hostname(mmc));
++ return -ENODEV;
++ }
++
++ spin_lock_init(&host->lock);
++
++ /*
++ * Maximum number of segments. Depends on if the hardware
++ * can do scatter/gather or not.
++ */
++ if (host->flags & SDHCI_USE_ADMA)
++ mmc->max_hw_segs = 128;
++ else if (host->flags & SDHCI_USE_DMA)
++ mmc->max_hw_segs = 1;
++ else /* PIO */
++ mmc->max_hw_segs = 128;
++ mmc->max_phys_segs = 128;
++
++ /*
++ * Maximum number of sectors in one transfer. Limited by DMA boundary
++ * size (512KiB).
++ */
++ mmc->max_req_size = 524288;
++
++ /*
++ * Maximum segment size. Could be one segment with the maximum number
++ * of bytes. When doing hardware scatter/gather, each entry cannot
++ * be larger than 64 KiB though.
++ */
++ if (host->flags & SDHCI_USE_ADMA)
++ mmc->max_seg_size = 65536;
++ else
++ mmc->max_seg_size = mmc->max_req_size;
++
++ /*
++ * Maximum block size. This varies from controller to controller and
++ * is specified in the capabilities register.
++ */
++ mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT;
++ if (mmc->max_blk_size >= 3) {
++ printk(KERN_WARNING "%s: Invalid maximum block size, "
++ "assuming 512 bytes\n", mmc_hostname(mmc));
++ mmc->max_blk_size = 512;
++ } else
++ mmc->max_blk_size = 512 << mmc->max_blk_size;
++
++ /*
++ * Maximum block count.
++ */
++ mmc->max_blk_count = 65535;
++
++ /*
++ * Init tasklets.
++ */
++ tasklet_init(&host->card_tasklet,
++ sdhci_tasklet_card, (unsigned long)host);
++ tasklet_init(&host->finish_tasklet,
++ sdhci_tasklet_finish, (unsigned long)host);
++
++ setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host);
++
++ ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
++ mmc_hostname(mmc), host);
++ if (ret)
++ goto untasklet;
++
++ sdhci_init(host);
++
++#ifdef CONFIG_MMC_DEBUG
++ sdhci_dumpregs(host);
++#endif
++
++#ifdef CONFIG_LEDS_CLASS
++ snprintf(host->led_name, sizeof(host->led_name),
++ "%s::", mmc_hostname(mmc));
++ host->led.name = host->led_name;
++ host->led.brightness = LED_OFF;
++ host->led.default_trigger = mmc_hostname(mmc);
++ host->led.brightness_set = sdhci_led_control;
++
++ ret = led_classdev_register(mmc_dev(mmc), &host->led);
++ if (ret)
++ goto reset;
++#endif
++
++ mmiowb();
++
++ mmc_add_host(mmc);
++
++ printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s%s\n",
++ mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)),
++ (host->flags & SDHCI_USE_ADMA)?"A":"",
++ (host->flags & SDHCI_USE_DMA)?"DMA":"PIO");
++
++ return 0;
++
++#ifdef CONFIG_LEDS_CLASS
++reset:
++ sdhci_reset(host, SDHCI_RESET_ALL);
++ free_irq(host->irq, host);
++#endif
++untasklet:
++ tasklet_kill(&host->card_tasklet);
++ tasklet_kill(&host->finish_tasklet);
++
++ return ret;
++}
++
++//EXPORT_SYMBOL_GPL(sdhci_add_host);
++
++static int sdhci_probe(struct platform_device *pdev)
++{
++ struct sdhci_host *host;
++ struct resource *res;
++ int ret;
++ ast_sdhc_info = pdev->dev.platform_data;
++
++ host = sdhci_alloc_host(&pdev->dev, sizeof(struct sdhci_host));
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (NULL == res) {
++ dev_err(&pdev->dev, "cannot get IORESOURCE_MEM\n");
++ ret = -ENOENT;
++ return ret;
++ }
++
++ if (!request_mem_region(res->start, resource_size(res), res->name)) {
++ dev_err(&pdev->dev, "cannot reserved region\n");
++ ret = -ENXIO;
++ return ret;
++ }
++
++ host->ioaddr = ioremap(res->start, resource_size(res));
++ if (!host->ioaddr) {
++ ret = -EIO;
++ return ret;
++ }
++
++ host->hw_name = res->name;
++ host->irq = platform_get_irq(pdev, 0);
++ if (host->irq < 0) {
++ dev_err(&pdev->dev, "no irq specified\n");
++ ret = -ENOENT;
++ return ret;
++ }
++
++ ret = sdhci_add_host(host);
++
++ return ret;
++}
++
++void sdhci_remove_host(struct sdhci_host *host, int dead)
++{
++ unsigned long flags;
++
++ if (dead) {
++ spin_lock_irqsave(&host->lock, flags);
++
++ host->flags |= SDHCI_DEVICE_DEAD;
++
++ if (host->mrq) {
++ printk(KERN_ERR "%s: Controller removed during "
++ " transfer!\n", mmc_hostname(host->mmc));
++
++ host->mrq->cmd->error = -ENOMEDIUM;
++ tasklet_schedule(&host->finish_tasklet);
++ }
++
++ spin_unlock_irqrestore(&host->lock, flags);
++ }
++
++ mmc_remove_host(host->mmc);
++
++#ifdef CONFIG_LEDS_CLASS
++ led_classdev_unregister(&host->led);
++#endif
++
++ if (!dead)
++ sdhci_reset(host, SDHCI_RESET_ALL);
++
++ free_irq(host->irq, host);
++
++ del_timer_sync(&host->timer);
++
++ tasklet_kill(&host->card_tasklet);
++ tasklet_kill(&host->finish_tasklet);
++
++ kfree(host->adma_desc);
++ kfree(host->align_buffer);
++
++ host->adma_desc = NULL;
++ host->align_buffer = NULL;
++}
++
++EXPORT_SYMBOL_GPL(sdhci_remove_host);
++
++void sdhci_free_host(struct sdhci_host *host)
++{
++ mmc_free_host(host->mmc);
++}
++
++EXPORT_SYMBOL_GPL(sdhci_free_host);
++
++/*****************************************************************************\
++ * *
++ * Driver init/exit *
++ * *
++\*****************************************************************************/
++
++static struct platform_driver ast_sdhci_driver = {
++ .driver.name = "ast_sdhci",
++ .driver.owner = THIS_MODULE,
++ .probe = sdhci_probe,
++ .remove = __exit_p(sdhci_remove_host),
++#ifdef CONFIG_PM
++ .resume = sdhci_resume_host,
++ .suspend = sdhci_suspend_host,
++#endif
++};
++
++static int __init ast_sdhci_drv_init(void)
++{
++ return platform_driver_register(&ast_sdhci_driver);
++}
++
++static void __exit ast_sdhci_drv_exit(void)
++{
++ platform_driver_unregister(&ast_sdhci_driver);
++}
++
++module_init(ast_sdhci_drv_init);
++module_exit(ast_sdhci_drv_exit);
++
++module_param(debug_quirks, uint, 0444);
++
++MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx> & River Huang");
++MODULE_DESCRIPTION("ASPEED Secure Digital Host Controller Interface core driver");
++MODULE_LICENSE("GPL");
++
++MODULE_PARM_DESC(debug_quirks, "Force certain quirks.");
+diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
+index 6659b22..45cb05a 100644
+--- a/drivers/mtd/devices/m25p80.c
++++ b/drivers/mtd/devices/m25p80.c
+@@ -503,6 +503,15 @@ static struct flash_info __devinitdata m25p_data [] = {
+ { "at26df161a", 0x1f4601, 0, 64 * 1024, 32, SECT_4K, },
+ { "at26df321", 0x1f4701, 0, 64 * 1024, 64, SECT_4K, },
+
++ /* Macronix */
++ { "mx25l4005a", 0xc22013, 0, 64 * 1024, 8, SECT_4K },
++ { "mx25l3205d", 0xc22016, 0, 64 * 1024, 64, 0 },
++ { "mx25l6405d", 0xc22017, 0, 64 * 1024, 128, 0 },
++ { "mx25l12805d", 0xc22018, 0, 64 * 1024, 256, 0 },
++
++ { "mx25l12855e", 0xc22618, 0, 64 * 1024, 256, 0 },
++ { "mx25l25635e", 0xc22019, 0, 64 * 1024, 512, 0 },
++
+ /* Spansion -- single (large) sector size only, at least
+ * for the chips listed here (without boot sectors).
+ */
+@@ -511,7 +520,7 @@ static struct flash_info __devinitdata m25p_data [] = {
+ { "s25sl016a", 0x010214, 0, 64 * 1024, 32, },
+ { "s25sl032a", 0x010215, 0, 64 * 1024, 64, },
+ { "s25sl064a", 0x010216, 0, 64 * 1024, 128, },
+- { "s25sl12800", 0x012018, 0x0300, 256 * 1024, 64, },
++ { "s25sl12800", 0x012018, 0x0300, 256 * 1024, 64, },
+ { "s25sl12801", 0x012018, 0x0301, 64 * 1024, 256, },
+
+ /* SST -- large erase sizes are "overlays", "sectors" are 4K */
+diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
+index 5ea1693..bafa60c 100644
+--- a/drivers/mtd/maps/Kconfig
++++ b/drivers/mtd/maps/Kconfig
+@@ -351,6 +351,10 @@ config MTD_ARM_INTEGRATOR
+ tristate "CFI Flash device mapped on ARM Integrator/P720T"
+ depends on ARM && MTD_CFI
+
++config MTD_AST
++ tristate "CFI Flash device mapped on ASPEED"
++ depends on ARCH_ASPEED && MTD_CFI
++
+ config MTD_CDB89712
+ tristate "Cirrus CDB89712 evaluation board mappings"
+ depends on MTD_CFI && ARCH_CDB89712
+diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
+index 6d9ba35..3d8b1f2 100644
+--- a/drivers/mtd/maps/Makefile
++++ b/drivers/mtd/maps/Makefile
+@@ -9,6 +9,7 @@ endif
+ # Chip mappings
+ obj-$(CONFIG_MTD_CDB89712) += cdb89712.o
+ obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o
++obj-$(CONFIG_MTD_AST) += ast-nor.o
+ obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o
+ obj-$(CONFIG_MTD_DC21285) += dc21285.o
+ obj-$(CONFIG_MTD_DILNETPC) += dilnetpc.o
+diff --git a/drivers/mtd/maps/ast-nor.c b/drivers/mtd/maps/ast-nor.c
+new file mode 100644
+index 0000000..7cc4741
+--- /dev/null
++++ b/drivers/mtd/maps/ast-nor.c
+@@ -0,0 +1,221 @@
++/*======================================================================
++
++ drivers/mtd/maps/ast-nor.c: ASPEED flash map driver
++
++ Copyright (C) 2012-2020 ASPEED Technology Inc.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 2 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++ This is access code for flashes using ARM's flash partitioning
++ standards.
++
++* History:
++* 2012.10.11: Initial version [Ryan Chen]
++
++======================================================================*/
++
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/ioport.h>
++#include <linux/platform_device.h>
++#include <linux/init.h>
++
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/map.h>
++#include <linux/mtd/partitions.h>
++
++#include <asm/mach/flash.h>
++#include <mach/hardware.h>
++#include <asm/io.h>
++#include <asm/system.h>
++#include <mach/platform.h>
++
++#define PFX "ast-flash: "
++
++struct ast_flash_info {
++ struct mtd_info *mtd;
++ struct map_info map;
++ struct resource *res;
++ struct mtd_partition *partitions;
++// struct flash_platform_data *plat;
++};
++
++static int ast_flash_probe(struct platform_device *pdev)
++{
++ struct ast_flash_info *info;
++ struct flash_platform_data *pdata = pdev->dev.platform_data;
++ struct resource *res = NULL;
++
++ int ret;
++ static int no_partitions;
++ info = kzalloc(sizeof(struct ast_flash_info), GFP_KERNEL);
++ if (info == NULL) {
++ printk(KERN_ERR PFX "no memory for flash info\n");
++ return -ENOMEM;
++ }
++
++ /* request register map resource & check */
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res) {
++ dev_err(&pdev->dev, "register resources unusable\n");
++ ret = -ENXIO;
++ goto free_dev;
++ }
++
++ if (!request_mem_region(res->start, res->end - res->start + 1, pdev->name)) {
++ ret = -EBUSY;
++ goto free_something_1;
++ }
++
++ info->map.virt = ioremap(res->start, (res->end - res->start) + 1);
++ if (!info->map.virt) {
++ dev_err(&pdev->dev, "cannot map ast_flash_info registers\n");
++ ret = -ENOMEM;
++ goto release_mem;
++ }
++ info->map.phys = res->start;
++ info->map.size = res->end - res->start + 1;
++ info->map.name = (char *) pdata->map_name;
++#ifdef CONFIG_MTD_MAP_BANK_WIDTH_1
++ info->map.bankwidth = 1;
++#endif
++#ifdef CONFIG_MTD_MAP_BANK_WIDTH_2
++ info->map.bankwidth = 2;
++#endif
++ platform_set_drvdata(pdev, info);
++
++ printk("%s %x, %x, %s \n",__FUNCTION__,res->start,res->end,pdev->dev.bus_id);
++
++ printk("%s: area %08lx, size %lx\n", __FUNCTION__, info->map.phys, info->map.size);
++
++ printk("%s: virt at %08x, res->start %x \n", __FUNCTION__, (int)info->map.virt,res->start);
++
++ info->partitions = pdata->parts;
++
++ simple_map_init(&info->map);
++
++ /* probe for the device(s) */
++
++ info->mtd = do_map_probe(pdata->map_name, &info->map);
++ if (!info->mtd) {
++ ret = -EIO;
++ goto reset_drvdata;
++ }
++
++ /* mark ourselves as the owner */
++ info->mtd->owner = THIS_MODULE;
++
++ no_partitions = pdata->nr_parts;//ARRAY_SIZE(nor_partitions);
++ ret = add_mtd_partitions(info->mtd, info->partitions, no_partitions);
++ if (ret){
++ printk(KERN_ERR PFX "cannot add/parse partitions\n");
++ goto free_something_2;
++ }
++
++ return 0;
++
++ /* fall through to exit error */
++
++free_something_2:
++ del_mtd_partitions(info->mtd);
++ map_destroy(info->mtd);
++reset_drvdata:
++ //kfree(info->partitions);
++ platform_set_drvdata(pdev, NULL);
++//unmap_regs:
++ iounmap(info->map.virt);
++release_mem:
++ release_mem_region(res->start, (res->end - res->start) + 1);
++free_something_1:
++
++free_dev:
++ kfree(info);
++
++ return ret;
++}
++
++static int ast_flash_remove(struct platform_device *pdev)
++{
++ struct ast_flash_info *info = platform_get_drvdata(pdev);
++ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++
++ if(info) {
++ if (info->mtd) {
++ del_mtd_partitions(info->mtd);
++ map_destroy(info->mtd);
++ }
++ platform_set_drvdata(pdev, NULL);
++ iounmap(info->map.virt);
++
++ release_mem_region(res->start, (res->end - res->start) + 1);
++ kfree(info);
++ }
++
++ return 0;
++}
++
++
++#ifdef CONFIG_PM
++static int
++ast_flash_suspend(struct platform_device *pdev, pm_message_t msg)
++{
++ pr_debug("ast_flash_suspend\n");
++
++ return 0;
++}
++
++static int
++ast_flash_resume(struct platform_device *pdev)
++{
++ pr_debug("ast_flash_resume\n");
++
++ return 0;
++}
++#else
++#define ast_flash_suspend NULL
++#define ast_flash_resume NULL
++#endif
++
++static struct platform_driver ast_flash_driver = {
++ .probe = ast_flash_probe,
++ .remove = ast_flash_remove,
++ .suspend = ast_flash_suspend,
++ .resume = ast_flash_resume,
++ .driver = {
++ .name = "ast-nor",
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init ast_flash_init(void)
++{
++ printk("ASPEED NOR-Flash Driver, (c) 2012 Aspeed Tech \n");
++ return platform_driver_register(&ast_flash_driver);
++}
++
++static void __exit ast_flash_exit(void)
++{
++ platform_driver_unregister(&ast_flash_driver);
++}
++
++module_init(ast_flash_init);
++module_exit(ast_flash_exit);
++
++MODULE_AUTHOR("Ryan Chen");
++MODULE_DESCRIPTION("ASPEED AST CFI map driver");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:astflash");
+diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
+index 1c2e945..e1ab76b 100644
+--- a/drivers/mtd/nand/Kconfig
++++ b/drivers/mtd/nand/Kconfig
+@@ -56,6 +56,12 @@ config MTD_NAND_H1900
+ help
+ This enables the driver for the iPAQ h1900 flash.
+
++config MTD_NAND_AST
++ tristate "AST NAND flash"
++ depends on MTD_NAND && ARCH_ASPEED && MTD_PARTITIONS
++ help
++ This enables the driver for the ASPEED NAND flash.
++
+ config MTD_NAND_GPIO
+ tristate "GPIO NAND Flash driver"
+ depends on GENERIC_GPIO && ARM
+diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
+index b661586..129dfd3 100644
+--- a/drivers/mtd/nand/Makefile
++++ b/drivers/mtd/nand/Makefile
+@@ -36,5 +36,6 @@ obj-$(CONFIG_MTD_NAND_FSL_ELBC) += fsl_elbc_nand.o
+ obj-$(CONFIG_MTD_NAND_FSL_UPM) += fsl_upm.o
+ obj-$(CONFIG_MTD_NAND_SH_FLCTL) += sh_flctl.o
+ obj-$(CONFIG_MTD_NAND_MXC) += mxc_nand.o
++obj-$(CONFIG_MTD_NAND_AST) += ast_nand.o
+
+ nand-objs := nand_base.o nand_bbt.o
+diff --git a/drivers/mtd/nand/ast_nand.c b/drivers/mtd/nand/ast_nand.c
+new file mode 100755
+index 0000000..240a832
+--- /dev/null
++++ b/drivers/mtd/nand/ast_nand.c
+@@ -0,0 +1,197 @@
++/********************************************************************************
++* File Name : drivers/mtd/nand/aspeed_nand.c
++* Author : Ryan Chen
++* Description : ASPEED NAND driver
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* Overview:
++* This is a device driver for the NAND flash device found on the
++* ASPEED board which utilizes the Samsung K9F2808 part. This is
++* a 128Mibit (16MiB x 8 bits) NAND flash device.
++
++* History :
++* 1. 2012/10/20 Ryan Chen create this file
++*
++********************************************************************************/
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/nand.h>
++#include <linux/mtd/partitions.h>
++
++struct ast_nand_data {
++ struct nand_chip chip;
++ struct mtd_info mtd;
++ void __iomem *io_base;
++#ifdef CONFIG_MTD_PARTITIONS
++ int nr_parts;
++ struct mtd_partition *parts;
++#endif
++};
++
++static struct nand_ecclayout aspeed_nand_hw_eccoob = {
++ .eccbytes = 24,
++ .eccpos = {40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63},
++};
++
++/* hardware specific access to control-lines */
++static void
++ast_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
++{
++ struct nand_chip *chip = mtd->priv;
++
++ if (cmd != NAND_CMD_NONE) {
++ //writeb(cmd, chip->IO_ADDR_W + ((ctrl & 0x6) << 11));
++ //user mode cmd addr[13:12]
++ if(ctrl & NAND_CLE)
++ writeb(cmd, chip->IO_ADDR_W + (0x1 << 12));
++ else if (ctrl & NAND_ALE)
++ writeb(cmd, chip->IO_ADDR_W + (0x2 << 12));
++ else
++ writeb(cmd, chip->IO_ADDR_W + (1 << 12));
++ }
++}
++
++/*
++ * Main initialization routine
++ */
++static int __init
++ast_nand_probe(struct platform_device *pdev)
++{
++ struct ast_nand_data *data;
++ struct platform_nand_data *pdata = pdev->dev.platform_data;
++ int res = 0;
++
++ /* Allocate memory for the device structure (and zero it) */
++ data = kzalloc(sizeof(struct ast_nand_data), GFP_KERNEL);
++ if (!data) {
++ dev_err(&pdev->dev, "failed to allocate device structure.\n");
++ return -ENOMEM;
++ }
++
++ data->io_base = ioremap(pdev->resource[0].start,
++ pdev->resource[0].end - pdev->resource[0].start );
++ if (data->io_base == NULL) {
++ dev_err(&pdev->dev, "ioremap failed\n");
++ kfree(data);
++ return -EIO;
++ }
++
++ data->chip.priv = &data;
++ data->mtd.priv = &data->chip;
++ data->mtd.owner = THIS_MODULE;
++ data->mtd.name = pdev->dev.bus_id;
++
++ data->chip.IO_ADDR_R = data->io_base;
++ data->chip.IO_ADDR_W = data->io_base;
++ data->chip.cmd_ctrl = ast_hwcontrol;
++ data->chip.dev_ready = pdata->ctrl.dev_ready;
++ data->chip.select_chip = pdata->ctrl.select_chip;
++ data->chip.chip_delay = pdata->chip.chip_delay;
++ data->chip.options |= pdata->chip.options;
++
++ data->chip.ecc.hwctl = pdata->ctrl.hwcontrol;
++ data->chip.ecc.calculate = pdata->ctrl.calculate;
++ data->chip.ecc.correct = pdata->ctrl.correct;
++// data->chip.ecc.layout = pdata->chip.ecclayout;
++ data->chip.ecc.layout = &aspeed_nand_hw_eccoob;
++
++ data->chip.ecc.bytes = 6;
++ data->chip.ecc.size = 512;
++ data->chip.ecc.mode = NAND_ECC_HW; //NAND_ECC_SOFT;
++
++ platform_set_drvdata(pdev, data);
++
++ /* Scan to find existance of the device */
++ if (nand_scan(&data->mtd, 1)) {
++ res = -ENXIO;
++ goto out;
++ }
++#ifdef CONFIG_MTD_PARTITIONS
++ if (pdata->chip.part_probe_types) {
++ res = parse_mtd_partitions(&data->mtd,
++ pdata->chip.part_probe_types,
++ &data->parts, 0);
++ if (res > 0) {
++ add_mtd_partitions(&data->mtd, data->parts, res);
++ return 0;
++ }
++ }
++ if (pdata->chip.partitions) {
++ data->parts = pdata->chip.partitions;
++ res = add_mtd_partitions(&data->mtd, data->parts,
++ pdata->chip.nr_partitions);
++ } else
++#endif
++ res = add_mtd_device(&data->mtd);
++
++ if (!res)
++ return res;
++
++ nand_release(&data->mtd);
++out:
++ platform_set_drvdata(pdev, NULL);
++ iounmap(data->io_base);
++ kfree(data);
++
++ return res;
++
++}
++
++static int __devexit ast_nand_remove(struct platform_device *pdev)
++{
++ struct ast_nand_data *data = platform_get_drvdata(pdev);
++#ifdef CONFIG_MTD_PARTITIONS
++ struct platform_nand_data *pdata = pdev->dev.platform_data;
++#endif
++
++ nand_release(&data->mtd);
++#ifdef CONFIG_MTD_PARTITIONS
++ if (data->parts && data->parts != pdata->chip.partitions)
++ kfree(data->parts);
++#endif
++ iounmap(data->io_base);
++ kfree(data);
++
++ return 0;
++}
++
++static struct platform_driver ast_nand_driver = {
++ .probe = ast_nand_probe,
++ .remove = ast_nand_remove,
++ .driver = {
++ .name = "ast-nand",
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init ast_nand_init(void)
++{
++ return platform_driver_register(&ast_nand_driver);
++}
++
++static void __exit ast_nand_exit(void)
++{
++ platform_driver_unregister(&ast_nand_driver);
++}
++
++module_init(ast_nand_init);
++module_exit(ast_nand_exit);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Ryan Chen");
++MODULE_DESCRIPTION("NAND flash driver for ASPEED");
+diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
+index 231eeaf..e017c36 100644
+--- a/drivers/net/Kconfig
++++ b/drivers/net/Kconfig
+@@ -1889,6 +1889,9 @@ menuconfig NETDEV_1000
+
+ if NETDEV_1000
+
++config ASPEEDMAC
++ tristate "ASPEED MAC support"
++
+ config ACENIC
+ tristate "Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support"
+ depends on PCI
+diff --git a/drivers/net/Makefile b/drivers/net/Makefile
+index 017383a..3c04c0b 100644
+--- a/drivers/net/Makefile
++++ b/drivers/net/Makefile
+@@ -85,6 +85,7 @@ obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
+ obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
+ obj-$(CONFIG_RIONET) += rionet.o
+ obj-$(CONFIG_SH_ETH) += sh_eth.o
++obj-$(CONFIG_ASPEEDMAC) += ftgmac100_26.o
+
+ #
+ # end link order section
+diff --git a/drivers/net/ftgmac100_26.c b/drivers/net/ftgmac100_26.c
+new file mode 100644
+index 0000000..8575293
+--- /dev/null
++++ b/drivers/net/ftgmac100_26.c
+@@ -0,0 +1,1883 @@
++/********************************************************************************
++* File Name : ftgmac100_26.c
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++********************************************************************************/
++//-----------------------------------------------------------------------------
++// "ASPEED MAC Driver, (Linux Kernel 2.6.15.7) 10/02/07 - by ASPEED\n"
++// Further improvements:
++//
++// -- Assume MAC1 has a PHY chip. Read the chip type and handle Marvell
++// or Broadcom, else don't touch PHY chip (if present).
++//
++// -- If MAC2 is on, check if U-Boot enabled the MII2DC+MII2DIO pins.
++// If yes, handle Marvell or Broadcom PHY. If no, assume sideband RMII
++// interface with no PHY chip.
++// 1.12/27/07 - by river@aspeed
++// Workaround for the gigabit hash function
++// 2.12/27/07 - by river@aspeed
++// Synchronize the EDORR bit with document, D[30], D[15] both are EDORR
++// 3.12/31/07 - by river@aspeed
++// Add aspeed_i2c_init and aspeed_i2c_read function for DHCP
++// 4.04/10/2008 - by river@aspeed
++// Synchronize the EDOTR bit with document, D[30] is EDOTR
++// 5.04/10/2008 - by river@aspeed
++// Remove the workaround for multicast hash function in A2 chip
++// SDK 0.19
++// 6.05/15/2008 - by river@aspeed
++// Fix bug of free sk_buff in wrong routine
++// 7.05/16/2008 - by river@aspeed
++// Fix bug of skb_over_panic()
++// 8.05/22/2008 - by river@aspeed
++// Support NCSI Feature
++// SDK 0.20
++// 9.07/02/2008 - by river@aspeed
++// Fix TX will drop packet bug
++// SDK 0.21
++//10.08/06/2008 - by river@aspeed
++// Add the netif_carrier_on() and netif_carrier_off()
++//11.08/06/2008 - by river@aspeed
++// Fix the timer did not work after device closed
++// SDK0.22
++//12.08/12/2008 - by river@aspeed
++// Support different PHY configuration
++// SDK0.23
++//13.10/14/2008 - by river@aspeed
++// Support Realtek RTL8211BN Gigabit PHY
++//14.11/17/2008 - by river@aspeed
++// Modify the allocate buffer to alignment to IP header
++// SDK0.26
++//15.07/28/2009 - by river@aspeed
++// Fix memory leakage problem in using multicast
++//16.07/28/2009 - by river@aspeed
++// tx_free field in the local structure should be integer
++//
++//
++//
++//AST2300 SDK 0.12
++//17.03/30/2010 - by river@aspeed
++// Modify for AST2300's hardware CLOCK/RESET/MULTI-PIN configuration
++//18.03/30/2010 - by river@aspeed
++// Fix does not report netif_carrier_on() and netif_carrier_off() when use MARVELL PHY
++//AST2300 SDK 0.13
++//17.06/10/2010 - by river@aspeed
++// Support AST2300 A0
++//18.06/10/2010 - by river@aspeed
++// EEPROM is at I2C channel 4 on AST2300 A0 EVB
++//AST2300 SDK 0.14
++//19.09/13/2010 - by river@aspeed
++// Support Realtek RTL8201EL 10/100M PHY
++//AST2400
++//20.06/25/2013 - by CC@aspeed
++// Support BCM54612E 10/100/1000M PHY
++//-----------------------------------------------------------------------------
++
++#include <linux/module.h>
++#include <linux/version.h>
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/types.h>
++#include <linux/fcntl.h>
++#include <linux/interrupt.h>
++#include <linux/ptrace.h>
++#include <linux/ioport.h>
++#include <linux/in.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/init.h>
++#include <linux/proc_fs.h>
++#include <asm/bitops.h>
++#include <asm/io.h>
++#include <linux/pci.h>
++#include <linux/errno.h>
++#include <linux/delay.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/platform_device.h>
++#include <mach/ftgmac100_drv.h>
++
++#include <linux/skbuff.h>
++
++#include "ftgmac100_26.h"
++
++#if defined(CONFIG_ARM)
++#include <mach/hardware.h>
++#include <asm/cacheflush.h>
++
++#elif defined(CONFIG_COLDFIRE)
++#include <asm/astsim.h>
++
++#else
++#err "Not define include for GMAC"
++#endif
++
++/*------------------------------------------------------------------------
++ .
++ . Configuration options, for the experienced user to change.
++ .
++ -------------------------------------------------------------------------*/
++
++/*
++ . DEBUGGING LEVELS
++ .
++ . 0 for normal operation
++ . 1 for slightly more details
++ . >2 for various levels of increasingly useless information
++ . 2 for interrupt tracking, status flags
++ . 3 for packet info
++ . 4 for complete packet dumps
++*/
++
++#define DO_PRINT(args...) printk(": " args)
++
++#define FTMAC100_DEBUG 1
++
++#if (FTMAC100_DEBUG > 2 )
++#define PRINTK3(args...) DO_PRINT(args)
++#else
++#define PRINTK3(args...)
++#endif
++
++#if FTMAC100_DEBUG > 1
++#define PRINTK2(args...) DO_PRINT(args)
++#else
++#define PRINTK2(args...)
++#endif
++
++#ifdef FTMAC100_DEBUG
++#define PRINTK(args...) DO_PRINT(args)
++#else
++#define PRINTK(args...)
++#endif
++
++/*
++ . A rather simple routine to print out a packet for debugging purposes.
++*/
++#if FTMAC100_DEBUG > 2
++static void print_packet( u8 *, int );
++#endif
++
++static int ftgmac100_wait_to_send_packet(struct sk_buff * skb, struct net_device * dev);
++
++static volatile int trans_busy = 0;
++
++
++void ftgmac100_phy_rw_waiting(unsigned int ioaddr)
++{
++ unsigned int tmp;
++
++ do {
++ mdelay(10);
++ tmp =inl(ioaddr + PHYCR_REG);
++ } while ((tmp&(PHY_READ_bit|PHY_WRITE_bit)) > 0);
++}
++
++
++/*------------------------------------------------------------
++ . Reads a register from the MII Management serial interface
++ .-------------------------------------------------------------*/
++static u16 ftgmac100_read_phy_register(unsigned int ioaddr, u8 phyaddr, u8 phyreg)
++{
++ unsigned int tmp;
++
++ if (phyaddr > 0x1f) // MII chip IDs are 5 bits long
++ return 0xffff;
++
++ tmp = inl(ioaddr + PHYCR_REG);
++ tmp &= 0x3000003F;
++ tmp |=(phyaddr<<16);
++ tmp |=(phyreg<<(16+5));
++ tmp |=PHY_READ_bit;
++
++ outl( tmp, ioaddr + PHYCR_REG );
++ ftgmac100_phy_rw_waiting(ioaddr);
++
++ return (inl(ioaddr + PHYDATA_REG)>>16);
++}
++
++
++/*------------------------------------------------------------
++ . Writes a register to the MII Management serial interface
++ .-------------------------------------------------------------*/
++static void ftgmac100_write_phy_register(unsigned int ioaddr,
++ u8 phyaddr, u8 phyreg, u16 phydata)
++{
++ unsigned int tmp;
++
++ if (phyaddr > 0x1f) // MII chip IDs are 5 bits long
++ return;
++
++ tmp = inl(ioaddr + PHYCR_REG);
++ tmp &= 0x3000003F;
++ tmp |=(phyaddr<<16);
++ tmp |=(phyreg<<(16+5));
++ tmp |=PHY_WRITE_bit;
++
++ outl( phydata, ioaddr + PHYDATA_REG );
++ outl( tmp, ioaddr + PHYCR_REG );
++ ftgmac100_phy_rw_waiting(ioaddr);
++}
++
++static void ast_gmac_set_mac(struct ftgmac100_priv *priv, const unsigned char *mac)
++{
++ unsigned int maddr = mac[0] << 8 | mac[1];
++ unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5];
++
++ iowrite32(maddr, priv->netdev->base_addr + MAC_MADR_REG);
++ iowrite32(laddr, priv->netdev->base_addr + MAC_LADR_REG);
++}
++
++/*
++ * MAC1 always has MII MDC+MDIO pins to access PHY registers. We assume MAC1
++ * always has a PHY chip, if MAC1 is enabled.
++ * U-Boot can enable MAC2 MDC+MDIO pins for a 2nd PHY, or MAC2 might be
++ * disabled (only one port), or it's sideband-RMII which has no PHY chip.
++ *
++ * Return miiPhyId==0 if the MAC cannot be accessed.
++ * Return miiPhyId==1 if the MAC registers are OK but it cannot carry traffic.
++ * Return miiPhyId==2 if the MAC can send/receive but it has no PHY chip.
++ * Else return the PHY 22-bit vendor ID, 6-bit model and 4-bit revision.
++ */
++static void getMacHwConfig( struct net_device* dev, struct AstMacHwConfig* out )
++{
++ struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
++
++// out->macId = dev->dev_id;
++//.. getMacAndPhy(dev, out);
++ out->miiPhyId = 0;
++
++ // We assume the Clock Stop register does not disable the MAC1 or MAC2 clock
++ // unless Reset Control also holds the MAC in reset.
++ // For now, we only support a PHY chip on the MAC's own MDC+MDIO bus.
++ if (out->phyAddr > 0x1f) {
++no_phy_access:
++ out->phyAddr = 0xff;
++ return;
++ }
++
++ if (priv->NCSI_support == 0) {
++ out->miiPhyId = ftgmac100_read_phy_register(dev->base_addr, out->phyAddr, 0x02);
++ if (out->miiPhyId == 0xFFFF) { //Realtek PHY at address 1
++ out->phyAddr = 1;
++ }
++ if (out->miiPhyId == 0x0362) {
++ out->phyAddr = 1;
++ }
++ out->miiPhyId = ftgmac100_read_phy_register(dev->base_addr, out->phyAddr, 0x02);
++ out->miiPhyId = (out->miiPhyId & 0xffff) << 16;
++ out->miiPhyId |= ftgmac100_read_phy_register(dev->base_addr, out->phyAddr, 0x03) & 0xffff;
++
++ switch (out->miiPhyId >> 16) {
++ case 0x0040: // Broadcom
++ case 0x0141: // Marvell
++ case 0x001c: // Realtek
++ case 0x0362: // BCM54612
++ break;
++
++ default:
++ // Leave miiPhyId for DO_PRINT(), but reset phyAddr.
++ // out->miiPhyId = 2;
++ goto no_phy_access;
++ break;
++ }
++ }
++ return;
++}
++
++
++static void ftgmac100_reset( struct net_device* dev )
++{
++ struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
++ struct AstMacHwConfig* ids = &priv->ids;
++ unsigned int tmp, speed, duplex;
++
++ getMacHwConfig(dev, ids);
++ PRINTK("%s:ftgmac100_reset, phyAddr=0x%x, miiPhyId=0x%04x_%04x\n",
++ dev->name, ids->phyAddr, (ids->miiPhyId >> 16), (ids->miiPhyId & 0xffff));
++
++ if (ids->miiPhyId < 1)
++ return; // Cannot access MAC registers
++
++ // Check the link speed and duplex.
++ // They are not valid until auto-neg is resolved, which is reg.1 bit[5],
++ // or the link is up, which is reg.1 bit[2].
++
++ if (ids->phyAddr < 0xff)
++ tmp = ftgmac100_read_phy_register(dev->base_addr, ids->phyAddr, 0x1);
++ else tmp = 0;
++
++ if (0==(tmp & (1u<<5 | 1u<<2)) || ids->phyAddr >= 0xff) {
++ // No PHY chip, or link has not negotiated.
++ speed = PHY_SPEED_100M;
++ duplex = 1;
++ netif_carrier_off(dev);
++ }
++ else if (((ids->miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8201EL)) {
++ tmp = ftgmac100_read_phy_register(dev->base_addr, priv->ids.phyAddr, 0x00);
++ duplex = (tmp & 0x0100) ? 1 : 0;
++ speed = (tmp & 0x2000) ? PHY_SPEED_100M : PHY_SPEED_10M;
++ }
++ else if (((ids->miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_MARVELL) ||
++ ((ids->miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8211)) {
++ // Use reg.17_0.bit[15:13] for {speed[1:0], duplex}.
++ tmp = ftgmac100_read_phy_register(dev->base_addr, ids->phyAddr, 0x11);
++ duplex = (tmp & PHY_DUPLEX_mask)>>13;
++ speed = (tmp & PHY_SPEED_mask)>>14;
++ netif_carrier_on(dev);
++ }
++ else if (priv->ids.miiPhyId == PHYID_BCM54612E) {
++ // Get link status
++ // First Switch shadow register selector
++ ftgmac100_write_phy_register(dev->base_addr, priv->ids.phyAddr, 0x1C, 0x2000);
++ tmp = ftgmac100_read_phy_register(dev->base_addr, priv->ids.phyAddr, 0x1C);
++ if ( (tmp & 0x0080) == 0x0080 )
++ duplex = 0;
++ else
++ duplex = 1;
++
++ switch(tmp & 0x0018) {
++ case 0x0000:
++ speed = PHY_SPEED_1G; break;
++ case 0x0008:
++ speed = PHY_SPEED_100M; break;
++ case 0x0010:
++ speed = PHY_SPEED_10M; break;
++ default:
++ speed = PHY_SPEED_100M;
++ }
++ }
++ else {
++ // Assume Broadcom BCM5221. Use reg.18 bits [1:0] for {100Mb/s, fdx}.
++ tmp = ftgmac100_read_phy_register(dev->base_addr, ids->phyAddr, 0x18);
++ duplex = (tmp & 0x0001);
++ speed = (tmp & 0x0002) ? PHY_SPEED_100M : PHY_SPEED_10M;
++ }
++
++ if (speed == PHY_SPEED_1G) {
++ // Set SPEED_100_bit too, for consistency.
++ priv->maccr_val |= GMAC_MODE_bit | SPEED_100_bit;
++ tmp = inl( dev->base_addr + MACCR_REG );
++ tmp |= GMAC_MODE_bit | SPEED_100_bit;
++ outl(tmp, dev->base_addr + MACCR_REG );
++ } else {
++ priv->maccr_val &= ~(GMAC_MODE_bit | SPEED_100_bit);
++ tmp = inl( dev->base_addr + MACCR_REG );
++ tmp &= ~(GMAC_MODE_bit | SPEED_100_bit);
++ if (speed == PHY_SPEED_100M) {
++ priv->maccr_val |= SPEED_100_bit;
++ tmp |= SPEED_100_bit;
++ }
++ outl(tmp, dev->base_addr + MACCR_REG );
++ }
++ if (duplex)
++ priv->maccr_val |= FULLDUP_bit;
++ else
++ priv->maccr_val &= ~FULLDUP_bit;
++
++ outl( SW_RST_bit, dev->base_addr + MACCR_REG );
++
++#ifdef not_complete_yet
++ /* Setup for fast accesses if requested */
++ /* If the card/system can't handle it then there will */
++ /* be no recovery except for a hard reset or power cycle */
++ if (dev->dma)
++ {
++ outw( inw( dev->base_addr + CONFIG_REG ) | CONFIG_NO_WAIT,
++ dev->base_addr + CONFIG_REG );
++ }
++#endif /* end_of_not */
++
++ /* this should pause enough for the chip to be happy */
++ for (; (inl( dev->base_addr + MACCR_REG ) & SW_RST_bit) != 0; )
++ {
++ mdelay(10);
++ PRINTK3("RESET: reset not complete yet\n" );
++ }
++
++ outl( 0, dev->base_addr + IER_REG ); /* Disable all interrupts */
++}
++
++static void ftgmac100_enable( struct net_device *dev )
++{
++ int i;
++ struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
++ unsigned int tmp_rsize; //Richard
++ unsigned int rfifo_rsize; //Richard
++ unsigned int tfifo_rsize; //Richard
++ unsigned int rxbuf_size;
++
++ rxbuf_size = RX_BUF_SIZE & 0x3fff;
++ outl( rxbuf_size , dev->base_addr + RBSR_REG); //for NC Body
++
++ for (i=0; i<RXDES_NUM; ++i)
++ priv->rx_descs[i].RXPKT_RDY = RX_OWNBY_FTGMAC100; // owned by FTMAC100
++
++ priv->rx_idx = 0;
++
++ for (i=0; i<TXDES_NUM; ++i) {
++ priv->tx_descs[i].TXDMA_OWN = TX_OWNBY_SOFTWARE; // owned by software
++ priv->tx_skbuff[i] = 0;
++ }
++
++ priv->tx_idx = 0;
++ priv->old_tx = 0;
++ priv->tx_free=TXDES_NUM;
++
++ /* Set the MAC address */
++ ast_gmac_set_mac(priv, dev->dev_addr);
++
++ outl( priv->rx_descs_dma, dev->base_addr + RXR_BADR_REG);
++ outl( priv->tx_descs_dma, dev->base_addr + TXR_BADR_REG);
++ outl( 0x00001010, dev->base_addr + ITC_REG);
++
++ outl( (0UL<<TXPOLL_CNT)|(0x1<<RXPOLL_CNT), dev->base_addr + APTC_REG);
++ outl( 0x44f97, dev->base_addr + DBLAC_REG );
++
++ /// outl( inl(FCR_REG)|0x1, ioaddr + FCR_REG ); // enable flow control
++ /// outl( inl(BPR_REG)|0x1, ioaddr + BPR_REG ); // enable back pressure register
++
++ // +++++ Richard +++++ //
++ tmp_rsize = inl( dev->base_addr + FEAR_REG );
++ rfifo_rsize = tmp_rsize & 0x00000007;
++ tfifo_rsize = (tmp_rsize >> 3)& 0x00000007;
++
++ tmp_rsize = inl( dev->base_addr + TPAFCR_REG );
++ tmp_rsize &= ~0x3f000000;
++ tmp_rsize |= (tfifo_rsize << 27);
++ tmp_rsize |= (rfifo_rsize << 24);
++
++ outl(tmp_rsize, dev->base_addr + TPAFCR_REG);
++ // ----- Richard ----- //
++
++//river set MAHT0, MAHT1
++ if (priv->maccr_val & GMAC_MODE_bit) {
++ outl (priv->GigaBit_MAHT0, dev->base_addr + MAHT0_REG);
++ outl (priv->GigaBit_MAHT1, dev->base_addr + MAHT1_REG);
++ }
++ else {
++ outl (priv->Not_GigaBit_MAHT0, dev->base_addr + MAHT0_REG);
++ outl (priv->Not_GigaBit_MAHT1, dev->base_addr + MAHT1_REG);
++ }
++
++ /// enable trans/recv,...
++ outl(priv->maccr_val, dev->base_addr + MACCR_REG );
++#if 0
++//NCSI Start
++//DeSelect Package/ Select Package
++ if ((priv->NCSI_support == 1) || (priv->INTEL_NCSI_EVA_support == 1)) {
++ NCSI_Struct_Initialize(dev);
++ for (i = 0; i < 4; i++) {
++ DeSelect_Package (dev, i);
++ Package_Found = Select_Package (dev, i);
++ if (Package_Found == 1) {
++//AST2100/AST2050/AST1100 supports 1 slave only
++ priv->NCSI_Cap.Package_ID = i;
++ break;
++ }
++ }
++ if (Package_Found != 0) {
++//Initiali State
++ for (i = 0; i < 2; i++) { //Suppose 2 channels in current version, You could modify it to 0x1F to support 31 channels
++ Channel_Found = Clear_Initial_State(dev, i);
++ if (Channel_Found == 1) {
++ priv->NCSI_Cap.Channel_ID = i;
++ printk ("Found NCSI Network Controller at (%d, %d)\n", priv->NCSI_Cap.Package_ID, priv->NCSI_Cap.Channel_ID);
++//Get Version and Capabilities
++ Get_Version_ID(dev);
++ Get_Capabilities(dev);
++//Configuration
++ Select_Active_Package(dev);
++//Set MAC Address
++ Enable_Set_MAC_Address(dev);
++//Enable Broadcast Filter
++ Enable_Broadcast_Filter(dev);
++//Disable VLAN
++ Disable_VLAN(dev);
++//Enable AEN
++ Enable_AEN(dev);
++//Get Parameters
++ Get_Parameters(dev);
++//Enable TX
++ Enable_Network_TX(dev);
++//Enable Channel
++ Enable_Channel(dev);
++//Get Link Status
++Re_Get_Link_Status:
++ Link_Status = Get_Link_Status(dev);
++ if (Link_Status == LINK_UP) {
++ printk ("Using NCSI Network Controller (%d, %d)\n", priv->NCSI_Cap.Package_ID, priv->NCSI_Cap.Channel_ID);
++ netif_carrier_on(dev);
++ break;
++ }
++ else if ((Link_Status == LINK_DOWN) && (Re_Send < 2)) {
++ Re_Send++;
++ netif_carrier_off(dev);
++ goto Re_Get_Link_Status;
++ }
++//Disable TX
++ Disable_Network_TX(dev);
++//Disable Channel
++// Disable_Channel(dev);
++ Re_Send = 0;
++ Channel_Found = 0;
++ }
++ }
++ }
++ }
++ /* now, enable interrupts */
++#endif
++ if (((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_MARVELL) ||
++ ((priv->ids.miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8211)) {
++ outl(
++ PHYSTS_CHG_bit |
++ AHB_ERR_bit |
++ TPKT_LOST_bit |
++ TPKT2E_bit |
++ RXBUF_UNAVA_bit |
++ RPKT2B_bit
++ ,dev->base_addr + IER_REG
++ );
++ }
++ else if (((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_BROADCOM) ||
++ ((priv->ids.miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8201EL)) {
++ outl(
++ AHB_ERR_bit |
++ TPKT_LOST_bit |
++ TPKT2E_bit |
++ RXBUF_UNAVA_bit |
++ RPKT2B_bit
++ ,dev->base_addr + IER_REG
++ );
++ }
++ else if (priv->ids.miiPhyId == PHYID_BCM54612E) {
++ outl(
++// no link PHY link status pin PHYSTS_CHG_bit |
++ AHB_ERR_bit |
++ TPKT_LOST_bit |
++ TPKT2E_bit |
++ RXBUF_UNAVA_bit |
++ RPKT2B_bit
++ ,dev->base_addr + IER_REG
++ );
++ } else {
++ outl(
++// no link PHY link status pin PHYSTS_CHG_bit |
++ AHB_ERR_bit |
++ TPKT_LOST_bit |
++ TPKT2E_bit |
++ RXBUF_UNAVA_bit |
++ RPKT2B_bit
++ ,dev->base_addr + IER_REG
++ );
++ }
++}
++
++static void aspeed_mac_timer(unsigned long data)
++{
++ struct net_device *dev = (struct net_device *)data;
++ struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
++ unsigned int status, tmp, speed, duplex, macSpeed;
++
++#ifdef CONFIG_ARCH_AST2300
++ //Fix issue for tx/rx arbiter lock
++ outl( 0xffffffff, dev->base_addr + TXPD_REG);
++#endif
++ status = ftgmac100_read_phy_register(dev->base_addr, priv->ids.phyAddr, 0x01);
++
++ if (status & LINK_STATUS) { // Bit[2], Link Status, link is up
++ priv->timer.expires = jiffies + 10 * HZ;
++
++ if ((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_BROADCOM) {
++ tmp = ftgmac100_read_phy_register(dev->base_addr, priv->ids.phyAddr, 0x18);
++ duplex = (tmp & 0x0001);
++ speed = (tmp & 0x0002) ? PHY_SPEED_100M : PHY_SPEED_10M;
++ }
++ else if ((priv->ids.miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8201EL) {
++ tmp = ftgmac100_read_phy_register(dev->base_addr, priv->ids.phyAddr, 0x00);
++ duplex = (tmp & 0x0100) ? 1 : 0;
++ speed = (tmp & 0x2000) ? PHY_SPEED_100M : PHY_SPEED_10M;
++ }
++ else if (((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_MARVELL) ||
++ ((priv->ids.miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8211)) {
++ tmp = ftgmac100_read_phy_register(dev->base_addr, priv->ids.phyAddr, 0x11);
++ duplex = (tmp & PHY_DUPLEX_mask)>>13;
++ speed = (tmp & PHY_SPEED_mask)>>14;
++ }
++ else if (priv->ids.miiPhyId == PHYID_BCM54612E) {
++ // Get link status
++ // First Switch shadow register selector
++ ftgmac100_write_phy_register(dev->base_addr, priv->ids.phyAddr, 0x1C, 0x2000);
++ tmp = ftgmac100_read_phy_register(dev->base_addr, priv->ids.phyAddr, 0x1C);
++ if ( (tmp & 0x0080) == 0x0080 )
++ duplex = 0;
++ else
++ duplex = 1;
++
++ switch(tmp & 0x0018) {
++ case 0x0000:
++ speed = PHY_SPEED_1G;
++
++ break;
++ case 0x0008:
++ speed = PHY_SPEED_100M;
++
++ break;
++ case 0x0010:
++ speed = PHY_SPEED_10M;
++
++ break;
++ default:
++ speed = PHY_SPEED_100M;
++ }
++ }
++ else {
++ duplex = 1; speed = PHY_SPEED_100M;
++ }
++
++ macSpeed = ((priv->maccr_val & GMAC_MODE_bit)>>8 // Move bit[9] to bit[1]
++ | (priv->maccr_val & SPEED_100_bit)>>19); // bit[19] to bit[0]
++ // The MAC hardware ignores SPEED_100_bit if GMAC_MODE_bit is set.
++ if (macSpeed > PHY_SPEED_1G) macSpeed = PHY_SPEED_1G; // 0x3 --> 0x2
++
++ if ( ((priv->maccr_val & FULLDUP_bit)!=0) != duplex
++ || macSpeed != speed )
++ {
++ PRINTK("%s:aspeed_mac_timer, priv->maccr_val=0x%05x, PHY {speed,duplex}=%d,%d\n",
++ dev->name, priv->maccr_val, speed, duplex);
++ ftgmac100_reset(dev);
++ ftgmac100_enable(dev);
++ }
++ netif_carrier_on(dev);
++ }
++ else {
++ netif_carrier_off(dev);
++ priv->timer.expires = jiffies + 1 * HZ;
++ }
++ add_timer(&priv->timer);
++}
++
++/*
++ . Function: ftgmac100_shutdown
++ . Purpose: closes down the SMC91xxx chip.
++ . Method:
++ . 1. zero the interrupt mask
++ . 2. clear the enable receive flag
++ . 3. clear the enable xmit flags
++ .
++ . TODO:
++ . (1) maybe utilize power down mode.
++ . Why not yet? Because while the chip will go into power down mode,
++ . the manual says that it will wake up in response to any I/O requests
++ . in the register space. Empirical results do not show this working.
++*/
++static void ftgmac100_shutdown( unsigned int ioaddr )
++{
++ ///interrupt mask register
++ outl( 0, ioaddr + IER_REG );
++ /* enable trans/recv,... */
++ outl( 0, ioaddr + MACCR_REG );
++}
++
++/*
++ . Function: ftgmac100_wait_to_send_packet( struct sk_buff * skb, struct device * )
++ . Purpose:
++ . Attempt to allocate memory for a packet, if chip-memory is not
++ . available, then tell the card to generate an interrupt when it
++ . is available.
++ .
++ . Algorithm:
++ .
++ . o if the saved_skb is not currently null, then drop this packet
++ . on the floor. This should never happen, because of TBUSY.
++ . o if the saved_skb is null, then replace it with the current packet,
++ . o See if I can sending it now.
++ . o (NO): Enable interrupts and let the interrupt handler deal with it.
++ . o (YES):Send it now.
++*/
++static int ftgmac100_wait_to_send_packet( struct sk_buff * skb, struct net_device * dev )
++{
++ struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
++ unsigned long ioaddr = dev->base_addr;
++ volatile TX_DESC *cur_desc;
++ int length;
++ unsigned long flags;
++
++ spin_lock_irqsave(&priv->tx_lock,flags);
++
++ if (skb==NULL)
++ {
++ DO_PRINT("%s(%d): NULL skb???\n", __FILE__,__LINE__);
++ spin_unlock_irqrestore(&priv->tx_lock, flags);
++ return 0;
++ }
++
++ PRINTK3("%s:ftgmac100_wait_to_send_packet, skb=%x\n", dev->name, skb);
++ cur_desc = &priv->tx_descs[priv->tx_idx];
++
++#ifdef not_complete_yet
++ if (cur_desc->TXDMA_OWN != TX_OWNBY_SOFTWARE) /// no empty transmit descriptor
++ {
++ DO_PRINT("no empty transmit descriptor\n");
++ DO_PRINT("jiffies = %d\n", jiffies);
++ priv->stats.tx_dropped++;
++ netif_stop_queue(dev); /// waiting to do:
++ spin_unlock_irqrestore(&priv->tx_lock, flags);
++
++ return 1;
++ }
++#endif /* end_of_not */
++
++ if (cur_desc->TXDMA_OWN != TX_OWNBY_SOFTWARE) /// no empty transmit descriptor
++ {
++ DO_PRINT("no empty TX descriptor:0x%x:0x%x\n",
++ (unsigned int)cur_desc,((unsigned int *)cur_desc)[0]);
++ priv->stats.tx_dropped++;
++ netif_stop_queue(dev); /// waiting to do:
++ spin_unlock_irqrestore(&priv->tx_lock, flags);
++
++ return 1;
++ }
++ priv->tx_skbuff[priv->tx_idx] = skb;
++ length = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
++ length = min(length, TX_BUF_SIZE);
++
++#if FTMAC100_DEBUG > 2
++ DO_PRINT("Transmitting Packet at 0x%x, skb->data = %x, len = %x\n",
++ (unsigned int)cur_desc->VIR_TXBUF_BADR, skb->data, length);
++ print_packet( skb->data, length );
++#endif
++
++ cur_desc->VIR_TXBUF_BADR = (unsigned long)skb->data;
++ cur_desc->TXBUF_BADR = virt_to_phys(skb->data);
++#ifndef CONFIG_CPU_FA52x_DCE
++ dmac_clean_range((void *)skb->data, (void *)(skb->data + length));
++#endif
++
++ //clean_dcache_range(skb->data, (char*)(skb->data + length));
++
++ cur_desc->TXBUF_Size = length;
++ cur_desc->LTS = 1;
++ cur_desc->FTS = 1;
++
++ cur_desc->TX2FIC = 0;
++ cur_desc->TXIC = 0;
++
++ cur_desc->TXDMA_OWN = TX_OWNBY_FTGMAC100;
++
++ outl( 0xffffffff, ioaddr + TXPD_REG);
++
++ priv->tx_idx = (priv->tx_idx + 1) % TXDES_NUM;
++ priv->stats.tx_packets++;
++ priv->tx_free--;
++
++ if (priv->tx_free <= 0) {
++ netif_stop_queue(dev);
++
++ }
++
++
++ dev->trans_start = jiffies;
++ spin_unlock_irqrestore(&priv->tx_lock, flags);
++
++ return 0;
++}
++
++static int ftgmac100_ringbuf_alloc(struct ftgmac100_priv *priv)
++{
++ int i;
++ struct sk_buff *skb;
++
++ priv->rx_descs = dma_alloc_coherent(priv->dev,
++ sizeof(RX_DESC)*RXDES_NUM,
++ &priv->rx_descs_dma, GFP_KERNEL);
++
++ if(!priv->rx_descs)
++ return -ENOMEM;
++
++ memset(priv->rx_descs, 0, sizeof(RX_DESC)*RXDES_NUM);
++ priv->rx_descs[RXDES_NUM-1].EDORR = 1;
++
++ for (i=0; i<RXDES_NUM; i++) {
++ dma_addr_t mapping;
++ skb = dev_alloc_skb(RX_BUF_SIZE + NET_IP_ALIGN);
++ skb_reserve(skb, NET_IP_ALIGN);
++
++ priv->rx_skbuff[i] = skb;
++ if (skb == NULL) {
++ printk ("alloc_list: allocate Rx buffer error! ");
++ break;
++ }
++ mapping = dma_map_single(priv->dev, skb->data, skb->len, DMA_FROM_DEVICE);
++ skb->dev = priv->netdev; /* Mark as being used by this device. */
++ priv->rx_descs[i].RXBUF_BADR = mapping;
++ priv->rx_descs[i].VIR_RXBUF_BADR = skb->data;
++ }
++
++ priv->tx_descs = dma_alloc_coherent(priv->dev,
++ sizeof(TX_DESC)*TXDES_NUM,
++ &priv->tx_descs_dma ,GFP_KERNEL);
++
++ if(!priv->tx_descs)
++ return -ENOMEM;
++
++ memset((void*)priv->tx_descs, 0, sizeof(TX_DESC)*TXDES_NUM);
++ priv->tx_descs[TXDES_NUM-1].EDOTR = 1; // is last descriptor
++
++}
++
++#if FTMAC100_DEBUG > 2
++static void print_packet( u8 * buf, int length )
++{
++#if 1
++#if FTMAC100_DEBUG > 3
++ int i;
++ int remainder;
++ int lines;
++#endif
++
++
++#if FTMAC100_DEBUG > 3
++ lines = length / 16;
++ remainder = length % 16;
++
++ for ( i = 0; i < lines ; i ++ ) {
++ int cur;
++
++ for ( cur = 0; cur < 8; cur ++ ) {
++ u8 a, b;
++
++ a = *(buf ++ );
++ b = *(buf ++ );
++ DO_PRINT("%02x%02x ", a, b );
++ }
++ DO_PRINT("\n");
++ }
++ for ( i = 0; i < remainder/2 ; i++ ) {
++ u8 a, b;
++
++ a = *(buf ++ );
++ b = *(buf ++ );
++ DO_PRINT("%02x%02x ", a, b );
++ }
++ DO_PRINT("\n");
++#endif
++#endif
++}
++#endif
++
++/*------------------------------------------------------------
++ . Configures the specified PHY using Autonegotiation.
++ .-------------------------------------------------------------*/
++static void ftgmac100_phy_configure(struct net_device* dev)
++{
++ struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
++ unsigned long ioaddr = dev->base_addr;
++ u32 tmp;
++// printk("priv->ids.miiPhyId = %x \n",priv->ids.miiPhyId);
++ switch (priv->ids.miiPhyId & PHYID_VENDOR_MASK) {
++ case PHYID_VENDOR_MARVELL:
++ ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x12, 0x4400);
++ tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x13 );
++ break;
++ case PHYID_VENDOR_REALTEK:
++ switch (priv->ids.miiPhyId) {
++ case PHYID_RTL8211:
++ ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x12, 0x4400);
++ tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x13 );
++ break;
++ case PHYID_RTL8201EL:
++ break;
++ case PHYID_RTL8201F:
++ ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x1f, 0x0007);
++ tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x13 );
++ tmp &= ~(0x0030);
++ tmp |= 0x0008;
++ ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x13, (u16) tmp);
++ tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x11);
++ tmp &= ~(0x0fff);
++ tmp |= 0x0008;
++ ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x11, (u16) tmp);
++ ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x1f, 0x0000);
++ break;
++ }
++ break;
++ case PHYID_VENDOR_BROADCOM:
++ switch (priv->ids.miiPhyId) {
++ case PHYID_BCM54612E:
++ ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x1C, 0x8C00); // Disable GTXCLK Clock Delay Enable
++ ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x18, 0xF0E7); // Disable RGMII RXD to RXC Skew
++ break;
++ case PHYID_BCM5221A4:
++ default:
++ tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x1b);
++ tmp |= 0x0004;
++ ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x1b, (u16) tmp);
++ break;
++ }
++ break;
++ }
++}
++
++
++/*--------------------------------------------------------
++ . Called by the kernel to send a packet out into the void
++ . of the net. This routine is largely based on
++ . skeleton.c, from Becker.
++ .--------------------------------------------------------
++*/
++static void ftgmac100_timeout (struct net_device *dev)
++{
++ /* If we get here, some higher level has decided we are broken.
++ There should really be a "kick me" function call instead. */
++ DO_PRINT(KERN_WARNING "%s: transmit timed out? (jiffies=%ld)\n",
++ dev->name, jiffies);
++ /* "kick" the adaptor */
++ ftgmac100_reset( dev );
++ ftgmac100_enable( dev );
++
++ /* Reconfigure the PHY */
++ ftgmac100_phy_configure(dev);
++
++ netif_wake_queue(dev);
++ dev->trans_start = jiffies;
++}
++
++
++static void ftgmac100_free_tx (struct net_device *dev)
++{
++ struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
++ int entry = priv->old_tx % TXDES_NUM;
++ unsigned long flags = 0;
++
++ spin_lock_irqsave(&priv->tx_lock,flags);
++
++ /* Free used tx skbuffs */
++
++ while ((priv->tx_descs[entry].TXDMA_OWN == TX_OWNBY_SOFTWARE) && (priv->tx_skbuff[entry] != NULL)) {
++ struct sk_buff *skb;
++
++ skb = priv->tx_skbuff[entry];
++ dev_kfree_skb_any (skb);
++ priv->tx_skbuff[entry] = 0;
++ entry = (entry + 1) % TXDES_NUM;
++ priv->tx_free++;
++ }
++
++ spin_unlock_irqrestore(&priv->tx_lock, flags);
++ priv->old_tx = entry;
++ if ((netif_queue_stopped(dev)) && (priv->tx_free > 0)) {
++ netif_wake_queue (dev);
++ }
++}
++
++
++/*-------------------------------------------------------------
++ .
++ . ftgmac100_rcv - receive a packet from the card
++ .
++ . There is ( at least ) a packet waiting to be read from
++ . chip-memory.
++ .
++ . o Read the status
++ . o If an error, record it
++ . o otherwise, read in the packet
++ --------------------------------------------------------------
++*/
++// extern dce_dcache_invalidate_range(unsigned int start, unsigned int end);
++
++static void ftgmac100_rcv(struct net_device *dev)
++{
++ struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
++ unsigned long ioaddr = dev->base_addr;
++ int packet_length;
++ int rcv_cnt;
++ volatile RX_DESC *cur_desc;
++ int cur_idx;
++ int have_package;
++ int have_frs;
++ int start_idx;
++ int count = 0;
++ int packet_full = 0;
++ int data_not_fragment = 1;
++
++ start_idx = priv->rx_idx;
++
++ for (rcv_cnt=0; rcv_cnt<RXDES_NUM ; ++rcv_cnt)
++ {
++ packet_length = 0;
++ cur_idx = priv->rx_idx;
++
++ have_package = 0;
++ have_frs = 0;
++
++ for (; (cur_desc = &priv->rx_descs[priv->rx_idx])->RXPKT_RDY==RX_OWNBY_SOFTWARE; )
++ {
++ have_package = 1;
++ priv->rx_idx = (priv->rx_idx+1)%RXDES_NUM;
++ count++;
++ if (count == RXDES_NUM) {
++ packet_full = 1;
++ }
++//DF_support
++ if (data_not_fragment == 1) {
++ if (!(cur_desc->DF)) {
++ data_not_fragment = 0;
++ }
++ }
++
++ if (cur_desc->FRS)
++ {
++ have_frs = 1;
++ if (cur_desc->RX_ERR || cur_desc->CRC_ERR || cur_desc->FTL ||
++ cur_desc->RUNT || cur_desc->RX_ODD_NB
++ // cur_desc->IPCS_FAIL || cur_desc->UDPCS_FAIL || cur_desc->TCPCS_FAIL
++ )
++ {
++ // #ifdef not_complete_yet
++ if (cur_desc->RX_ERR)
++ {
++ DO_PRINT("err: RX_ERR\n");
++ }
++ if (cur_desc->CRC_ERR)
++ {
++ // DO_PRINT("err: CRC_ERR\n");
++ }
++ if (cur_desc->FTL)
++ {
++ DO_PRINT("err: FTL\n");
++ }
++ if (cur_desc->RX_ODD_NB)
++ {
++ // DO_PRINT("err: RX_ODD_NB\n");
++ }
++// if (cur_desc->IPCS_FAIL || cur_desc->UDPCS_FAIL || cur_desc->TCPCS_FAIL)
++// {
++// DO_PRINT("err: CS FAIL\n");
++// }
++ // #endif /* end_of_not */
++ priv->stats.rx_errors++; // error frame....
++ break;
++ }
++//DF_support
++ if (cur_desc->DF) {
++ if (cur_desc->IPCS_FAIL || cur_desc->UDPCS_FAIL || cur_desc->TCPCS_FAIL)
++ {
++ DO_PRINT("err: CS FAIL\n");
++ priv->stats.rx_errors++; // error frame....
++ break;
++ }
++ }
++
++ if (cur_desc->MULTICAST)
++ {
++ priv->stats.multicast++;
++ }
++ if ((priv->NCSI_support == 1) || (priv->INTEL_NCSI_EVA_support == 1)) {
++ if (cur_desc->BROADCAST) {
++ if (*(unsigned short *)(cur_desc->VIR_RXBUF_BADR + 12) == NCSI_HEADER) {
++ printk ("AEN PACKET ARRIVED\n");
++ ftgmac100_reset(dev);
++ ftgmac100_enable(dev);
++ return;
++ }
++ }
++ }
++ }
++
++ packet_length += cur_desc->VDBC;
++
++// if ( cur_desc->LRS ) // packet's last frame
++// {
++ break;
++// }
++ }
++ if (have_package==0)
++ {
++ goto done;
++ }
++ if (!have_frs)
++ {
++ DO_PRINT("error, loss first\n");
++ priv->stats.rx_over_errors++;
++ }
++
++ if (packet_length > 0)
++ {
++ struct sk_buff * skb;
++ u8 * data = 0; if (data) { }
++
++ packet_length -= 4;
++
++ skb_put (skb = priv->rx_skbuff[cur_idx], packet_length);
++
++// Rx Offload DF_support
++
++ if (data_not_fragment) {
++ skb->ip_summed = CHECKSUM_UNNECESSARY;
++ data_not_fragment = 1;
++ }
++
++#if FTMAC100_DEBUG > 2
++ DO_PRINT("Receiving Packet at 0x%x, packet len = %x\n",(unsigned int)data, packet_length);
++ print_packet( data, packet_length );
++#endif
++
++ skb->protocol = eth_type_trans(skb, dev );
++ netif_rx(skb);
++ priv->stats.rx_packets++;
++ priv->rx_skbuff[cur_idx] = NULL;
++ }
++ if (packet_full) {
++// DO_PRINT ("RX Buffer full before driver entered ISR\n");
++ goto done;
++ }
++ }
++
++done:
++
++ if (packet_full) {
++
++ struct sk_buff *skb;
++
++ for (cur_idx = 0; cur_idx < RXDES_NUM; cur_idx++)
++ {
++ if (priv->rx_skbuff[cur_idx] == NULL) {
++ skb = dev_alloc_skb (RX_BUF_SIZE + 16);
++ if (skb == NULL) {
++ printk (KERN_INFO
++ "%s: receive_packet: "
++ "Unable to re-allocate Rx skbuff.#%d\n",
++ dev->name, cur_idx);
++ }
++ priv->rx_skbuff[cur_idx] = skb;
++ skb->dev = dev;
++ // ASPEED: See earlier skb_reserve() cache alignment
++ skb_reserve (skb, 2);
++ dmac_inv_range ((void *)skb->data, (void *)skb->data + RX_BUF_SIZE);
++ priv->rx_descs[cur_idx].RXBUF_BADR = cpu_to_le32(virt_to_phys(skb->tail));
++ priv->rx_descs[cur_idx].VIR_RXBUF_BADR = cpu_to_le32((u32)skb->tail);
++ }
++ priv->rx_descs[cur_idx].RXPKT_RDY = RX_OWNBY_FTGMAC100;
++ }
++ packet_full = 0;
++
++ }
++ else {
++ if (start_idx != priv->rx_idx) {
++ struct sk_buff *skb;
++
++ for (cur_idx = (start_idx+1)%RXDES_NUM; cur_idx != priv->rx_idx; cur_idx = (cur_idx+1)%RXDES_NUM)
++ {
++
++
++ //struct sk_buff *skb;
++ /* Dropped packets don't need to re-allocate */
++ if (priv->rx_skbuff[cur_idx] == NULL) {
++ skb = dev_alloc_skb (RX_BUF_SIZE + 16);
++ if (skb == NULL) {
++ printk (KERN_INFO
++ "%s: receive_packet: "
++ "Unable to re-allocate Rx skbuff.#%d\n",
++ dev->name, cur_idx);
++ break;
++ }
++ priv->rx_skbuff[cur_idx] = skb;
++ skb->dev = dev;
++ /* 16 byte align the IP header */
++ skb_reserve (skb, 2);
++ dmac_inv_range ((void *)skb->data,
++ (void *)skb->data + RX_BUF_SIZE);
++ priv->rx_descs[cur_idx].RXBUF_BADR = cpu_to_le32(virt_to_phys(skb->tail));
++ priv->rx_descs[cur_idx].VIR_RXBUF_BADR = cpu_to_le32((u32)skb->tail);
++ }
++
++ priv->rx_descs[cur_idx].RXPKT_RDY = RX_OWNBY_FTGMAC100;
++ }
++
++
++ //struct sk_buff *skb;
++ /* Dropped packets don't need to re-allocate */
++ if (priv->rx_skbuff[start_idx] == NULL) {
++ skb = dev_alloc_skb (RX_BUF_SIZE + 16);
++ if (skb == NULL) {
++ printk (KERN_INFO
++ "%s: receive_packet: "
++ "Unable to re-allocate Rx skbuff.#%d\n",
++ dev->name, start_idx);
++ }
++ priv->rx_skbuff[start_idx] = skb;
++ skb->dev = dev;
++ /* 16 byte align the IP header */
++ skb_reserve (skb, 2);
++ dmac_inv_range ((void *)skb->data,
++ (void *)skb->data + RX_BUF_SIZE);
++ priv->rx_descs[start_idx].RXBUF_BADR = cpu_to_le32(virt_to_phys(skb->tail));
++ priv->rx_descs[start_idx].VIR_RXBUF_BADR = cpu_to_le32((u32)skb->tail);
++ }
++
++
++ priv->rx_descs[start_idx].RXPKT_RDY = RX_OWNBY_FTGMAC100;
++ }
++ }
++ if (trans_busy == 1)
++ {
++ /// priv->maccr_val |= RXMAC_EN_bit;
++ outl( priv->maccr_val, ioaddr + MACCR_REG );
++ outl( inl(ioaddr + IER_REG) | RXBUF_UNAVA_bit, ioaddr + IER_REG);
++ }
++ return;
++}
++
++/*--------------------------------------------------------------------
++ .
++ . This is the main routine of the driver, to handle the net_device when
++ . it needs some attention.
++ .
++ . So:
++ . first, save state of the chipset
++ . branch off into routines to handle each case, and acknowledge
++ . each to the interrupt register
++ . and finally restore state.
++ .
++ ---------------------------------------------------------------------*/
++static irqreturn_t ftgmac100_interrupt(int irq, void * dev_id, struct pt_regs * regs)
++{
++ struct net_device *dev = dev_id;
++ struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
++ unsigned long ioaddr = dev->base_addr;
++ int timeout;
++ unsigned int tmp;
++ unsigned int mask; // interrupt mask
++ unsigned int status; // interrupt status
++
++// PRINTK3("%s: ftgmac100 interrupt started \n", dev->name);
++
++ if (dev == NULL) {
++ DO_PRINT(KERN_WARNING "%s: irq %d for unknown device.\n", dev->name, irq);
++ return IRQ_HANDLED;
++ }
++
++ /* read the interrupt status register */
++ mask = inl( ioaddr + IER_REG );
++
++ /* set a timeout value, so I don't stay here forever */
++
++ for (timeout=1; timeout>0; --timeout)
++ {
++ /* read the status flag, and mask it */
++ status = inl( ioaddr + ISR_REG ) & mask;
++
++ outl(status, ioaddr + ISR_REG ); //Richard, write to clear
++
++ if (!status )
++ {
++ break;
++ }
++
++ if (status & PHYSTS_CHG_bit) {
++ DO_PRINT("PHYSTS_CHG \n");
++ // Is this interrupt for changes of the PHYLINK pin?
++ // Note: PHYLINK is optional; not all boards connect it.
++ if (((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_MARVELL) ||
++ ((priv->ids.miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8211))
++ {
++ tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x13);
++ PRINTK("%s: PHY interrupt status, read_phy_reg(0x13) = 0x%04x\n",
++ dev->name, tmp);
++ tmp &= (PHY_SPEED_CHG_bit | PHY_DUPLEX_CHG_bit | PHY_LINK_CHG_bit);
++ }
++ else if ((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_BROADCOM)
++ {
++ tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x1a);
++ PRINTK("%s: PHY interrupt status, read_phy_reg(0x1a) = 0x%04x\n",
++ dev->name, tmp);
++ // Bits [3:1] are {duplex, speed, link} change interrupts.
++ tmp &= 0x000e;
++ }
++ else if (priv->ids.miiPhyId == PHYID_BCM54612E) {
++ tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x1A);
++ PRINTK("%s: PHY interrupt status, read_phy_reg(0x1A) = 0x%04x\n",
++ dev->name, tmp);
++ tmp &= 0x000E;
++ }
++ else tmp = 0;
++
++ if (tmp) {
++ ftgmac100_reset(dev);
++ ftgmac100_enable(dev);
++ }
++ }
++
++#ifdef not_complete_yet
++ if (status & AHB_ERR_bit)
++ {
++ DO_PRINT("AHB_ERR \n");
++ }
++
++ if (status & RPKT_LOST_bit)
++ {
++ DO_PRINT("RPKT_LOST ");
++ }
++ if (status & RPKT2F_bit)
++ {
++ PRINTK2("RPKT_SAV ");
++ }
++
++ if (status & TPKT_LOST_bit)
++ {
++ PRINTK("XPKT_LOST ");
++ }
++ if (status & TPKT2E_bit)
++ {
++ PRINTK("XPKT_OK ");
++ }
++ if (status & NPTXBUF_UNAVA_bit)
++ {
++ PRINTK("NOTXBUF ");
++ }
++ if (status & TPKT2F_bit)
++ {
++ PRINTK("XPKT_FINISH ");
++ }
++
++ if (status & RPKT2B_bit)
++ {
++ DO_PRINT("RPKT_FINISH ");
++ }
++ PRINTK2("\n");
++#endif /* end_of_not */
++
++// PRINTK3(KERN_WARNING "%s: Handling interrupt status %x \n", dev->name, status);
++
++ if ( status & (TPKT2E_bit|TPKT_LOST_bit))
++ {
++ //free tx skb buf
++ ftgmac100_free_tx(dev);
++
++ }
++
++ if ( status & RPKT2B_bit )
++ {
++ ftgmac100_rcv(dev); //Richard
++ }
++ else if (status & RXBUF_UNAVA_bit)
++ {
++ outl( mask & ~RXBUF_UNAVA_bit, ioaddr + IER_REG);
++ trans_busy = 1;
++ /*
++ rcv_tq.sync = 0;
++ rcv_tq.routine = ftgmac100_rcv;
++ rcv_tq.data = dev;
++ queue_task(&rcv_tq, &tq_timer);
++ */
++
++ } else if (status & AHB_ERR_bit)
++ {
++ DO_PRINT("AHB ERR \n");
++ }
++ }
++
++// PRINTK3("%s: Interrupt done\n", dev->name);
++ return IRQ_HANDLED;
++}
++
++/*------------------------------------------------------------
++ . Get the current statistics.
++ . This may be called with the card open or closed.
++ .-------------------------------------------------------------*/
++static struct net_device_stats* ftgmac100_query_statistics(struct net_device *dev)
++{
++ struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
++
++ return &priv->stats;
++}
++
++#ifdef HAVE_MULTICAST
++
++// --------------------------------------------------------------------
++// Finds the CRC32 of a set of bytes.
++// Again, from Peter Cammaert's code.
++// --------------------------------------------------------------------
++static int crc32( char * s, int length )
++{
++ /* indices */
++ int perByte;
++ int perBit;
++ /* crc polynomial for Ethernet */
++ const u32 poly = 0xedb88320;
++ /* crc value - preinitialized to all 1's */
++ u32 crc_value = 0xffffffff;
++
++ for ( perByte = 0; perByte < length; perByte ++ ) {
++ unsigned char c;
++
++ c = *(s++);
++ for ( perBit = 0; perBit < 8; perBit++ ) {
++ crc_value = (crc_value>>1)^
++ (((crc_value^c)&0x01)?poly:0);
++ c >>= 1;
++ }
++ }
++ return crc_value;
++}
++
++/*
++ . Function: ftgmac100_setmulticast( struct net_device *dev, int count, struct dev_mc_list * addrs )
++ . Purpose:
++ . This sets the internal hardware table to filter out unwanted multicast
++ . packets before they take up memory.
++*/
++
++static void ftgmac100_setmulticast( struct net_device *dev, int count, struct dev_mc_list * addrs )
++{
++ struct dev_mc_list * cur_addr;
++ int crc_val;
++ unsigned int ioaddr = dev->base_addr;
++ struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
++ struct AstMacHwConfig* ids = &priv->ids;
++ unsigned long Combined_Channel_ID, i;
++ struct sk_buff * skb;
++ cur_addr = addrs;
++
++//TX
++#if 0
++ if (priv->NCSI_support == 1) {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ priv->InstanceID++;
++ priv->NCSI_Request.IID = priv->InstanceID;
++ priv->NCSI_Request.Command = SET_MAC_ADDRESS;
++ Combined_Channel_ID = (priv->NCSI_Cap.Package_ID << 5) + priv->NCSI_Cap.Channel_ID;
++ priv->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ priv->NCSI_Request.Payload_Length = (8 << 8);
++ memcpy ((unsigned char *)skb->data, &priv->NCSI_Request, 30);
++ priv->NCSI_Request.Payload_Length = 8;
++ for (i = 0; i < 6; i++) {
++ priv->Payload_Data[i] = cur_addr->dmi_addr[i];
++ }
++ priv->Payload_Data[6] = 2; //MAC Address Num = 1 --> address filter 1, fixed in sample code
++ priv->Payload_Data[7] = MULTICAST_ADDRESS + 0 + ENABLE_MAC_ADDRESS_FILTER; //AT + Reserved + E
++ copy_data (dev, skb, priv->NCSI_Request.Payload_Length);
++ skb->len = 30 + priv->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet(skb, dev);
++ }
++#endif
++ for (cur_addr = addrs ; cur_addr!=NULL ; cur_addr = cur_addr->next )
++ {
++ /* make sure this is a multicast address - shouldn't this be a given if we have it here ? */
++ if ( !( *cur_addr->dmi_addr & 1 ) )
++ {
++ continue;
++ }
++#if 1
++//A0, A1
++ crc_val = crc32( cur_addr->dmi_addr, 5 );
++ crc_val = (~(crc_val>>2)) & 0x3f;
++ if (crc_val >= 32)
++ {
++ outl(inl(ioaddr+MAHT1_REG) | (1UL<<(crc_val-32)), ioaddr+MAHT1_REG);
++ priv->GigaBit_MAHT1 = inl (ioaddr + MAHT1_REG);
++ }
++ else
++ {
++ outl(inl(ioaddr+MAHT0_REG) | (1UL<<crc_val), ioaddr+MAHT0_REG);
++ priv->GigaBit_MAHT0 = inl (ioaddr + MAHT0_REG);
++ }
++//10/100M
++ crc_val = crc32( cur_addr->dmi_addr, 6 );
++ crc_val = (~(crc_val>>2)) & 0x3f;
++ if (crc_val >= 32)
++ {
++ outl(inl(ioaddr+MAHT1_REG) | (1UL<<(crc_val-32)), ioaddr+MAHT1_REG);
++ priv->Not_GigaBit_MAHT1 = inl (ioaddr + MAHT1_REG);
++ }
++ else
++ {
++ outl(inl(ioaddr+MAHT0_REG) | (1UL<<crc_val), ioaddr+MAHT0_REG);
++ priv->Not_GigaBit_MAHT0 = inl (ioaddr + MAHT0_REG);
++ }
++#else
++//A2
++ crc_val = crc32( cur_addr->dmi_addr, 6 );
++ crc_val = (~(crc_val>>2)) & 0x3f;
++ if (crc_val >= 32)
++ {
++ outl(inl(ioaddr+MAHT1_REG) | (1UL<<(crc_val-32)), ioaddr+MAHT1_REG);
++ priv->Not_GigaBit_MAHT1 = inl (ioaddr + MAHT1_REG);
++ priv->GigaBit_MAHT1 = inl (ioaddr + MAHT1_REG);
++ }
++ else
++ {
++ outl(inl(ioaddr+MAHT0_REG) | (1UL<<crc_val), ioaddr+MAHT0_REG);
++ priv->Not_GigaBit_MAHT0 = inl (ioaddr + MAHT0_REG);
++ priv->GigaBit_MAHT0 = inl (ioaddr + MAHT0_REG);
++ }
++#endif
++ }
++}
++
++/*-----------------------------------------------------------
++ . ftgmac100_set_multicast_list
++ .
++ . This routine will, depending on the values passed to it,
++ . either make it accept multicast packets, go into
++ . promiscuous mode ( for TCPDUMP and cousins ) or accept
++ . a select set of multicast packets
++*/
++static void ftgmac100_set_multicast_list(struct net_device *dev)
++{
++ unsigned int ioaddr = dev->base_addr;
++ struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
++
++ PRINTK2("%s:ftgmac100_set_multicast_list\n", dev->name);
++
++ if (dev->flags & IFF_PROMISC)
++ priv->maccr_val |= RX_ALLADR_bit;
++ else
++ priv->maccr_val &= ~RX_ALLADR_bit;
++
++ if (dev->flags & IFF_ALLMULTI)
++ priv->maccr_val |= RX_MULTIPKT_bit;
++ else
++ priv->maccr_val &= ~RX_MULTIPKT_bit;
++
++ if (dev->mc_count)
++ {
++// PRINTK("set multicast\n");
++ priv->maccr_val |= RX_HT_EN_bit;
++ ftgmac100_setmulticast( dev, dev->mc_count, dev->mc_list );
++ }
++ else
++ {
++ priv->maccr_val &= ~RX_HT_EN_bit;
++ }
++
++ outl( priv->maccr_val, ioaddr + MACCR_REG );
++
++}
++#endif
++
++static int ast_gmac_stop(struct net_device *dev)
++{
++ struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
++
++ netif_stop_queue(dev);
++
++ /* clear everything */
++ ftgmac100_shutdown(dev->base_addr);
++ free_irq(dev->irq, dev);
++
++ if (priv->timer.function != NULL) {
++ del_timer_sync(&priv->timer);
++ }
++
++ if (priv->rx_descs)
++ dma_free_coherent( NULL, sizeof(RX_DESC)*RXDES_NUM, (void*)priv->rx_descs, (dma_addr_t)priv->rx_descs_dma );
++ if (priv->tx_descs)
++ dma_free_coherent( NULL, sizeof(TX_DESC)*TXDES_NUM, (void*)priv->tx_descs, (dma_addr_t)priv->tx_descs_dma );
++ if (priv->tx_buf)
++ dma_free_coherent( NULL, TX_BUF_SIZE*TXDES_NUM, (void*)priv->tx_buf, (dma_addr_t)priv->tx_buf_dma );
++ priv->rx_descs = NULL; priv->rx_descs_dma = 0;
++ priv->tx_descs = NULL; priv->tx_descs_dma = 0;
++ priv->tx_buf = NULL; priv->tx_buf_dma = 0;
++
++
++ return 0;
++}
++
++static struct proc_dir_entry *proc_ftgmac100;
++
++static int ftgmac100_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
++{
++ struct net_device *dev = (struct net_device *)data;
++ struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
++ int num;
++ int i;
++
++ num = sprintf(page, "priv->rx_idx = %d\n", priv->rx_idx);
++ for (i=0; i<RXDES_NUM; ++i)
++ {
++ num += sprintf(page + num, "[%d].RXDMA_OWN = %d\n", i, priv->rx_descs[i].RXPKT_RDY);
++ }
++ return num;
++}
++
++static int ftgmac100_open(struct net_device *netdev)
++{
++ struct ftgmac100_priv *priv = netdev_priv(netdev);
++ int err;
++
++ DO_PRINT("%s:ftgmac100_open\n", netdev->name);
++
++ priv->maccr_val = (CRC_APD_bit | RXMAC_EN_bit | TXMAC_EN_bit | RXDMA_EN_bit
++ | TXDMA_EN_bit | CRC_CHK_bit | RX_BROADPKT_bit | SPEED_100_bit | FULLDUP_bit);
++
++ ftgmac100_ringbuf_alloc(priv);
++
++
++ /* Grab the IRQ next. Beyond this, we will free the IRQ. */
++ err = request_irq(netdev->irq, (void *)&ftgmac100_interrupt,
++ IRQF_DISABLED, netdev->name, netdev);
++ if (err)
++ {
++ DO_PRINT("%s: unable to get IRQ %d (retval=%d).\n",
++ netdev->name, netdev->irq, err);
++ kfree(netdev->priv);
++ netdev->priv = NULL;
++ return err;
++ }
++
++
++ netif_start_queue(netdev);
++
++ /* reset the hardware */
++ ftgmac100_reset(netdev);
++ ftgmac100_enable(netdev);
++
++ if (((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_BROADCOM) ||
++ ((priv->ids.miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8201EL) ||
++ (priv->ids.miiPhyId == PHYID_BCM54612E)) {
++
++ init_timer(&priv->timer);
++ priv->timer.data = (unsigned long)netdev;
++ priv->timer.function = aspeed_mac_timer;
++ priv->timer.expires = jiffies + 1 * HZ;
++ add_timer (&priv->timer);
++ }
++
++ /* Configure the PHY */
++ ftgmac100_phy_configure(netdev);
++
++ netif_start_queue(netdev);
++ return 0;
++}
++
++static int __init ast_gmac_probe(struct platform_device *pdev)
++{
++ struct resource *res;
++ struct net_device *netdev;
++ struct ftgmac100_priv *priv;
++ struct ftgmac100_eth_data *ast_eth_data = pdev->dev.platform_data;;
++ int err;
++
++ if (!pdev)
++ return -ENODEV;
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res)
++ return -ENXIO;
++
++ /* setup net_device */
++ netdev = alloc_etherdev(sizeof(*priv));
++ if (!netdev) {
++ err = -ENOMEM;
++ goto err_alloc_etherdev;
++ }
++
++ netdev->irq = platform_get_irq(pdev, 0);
++ if (netdev->irq < 0) {
++ err = -ENXIO;
++ goto err_netdev;
++ }
++
++ SET_NETDEV_DEV(netdev, &pdev->dev);
++
++
++// SET_ETHTOOL_OPS(netdev, &ftgmac100_ethtool_ops);
++
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30))
++ netdev->netdev_ops = &ftgmac100_netdev_ops;
++#else
++ printk("ast_gmac_probe 5\n");
++
++ ether_setup(netdev);
++
++ netdev->open = ftgmac100_open;
++ netdev->stop = ast_gmac_stop;
++ netdev->hard_start_xmit = ftgmac100_wait_to_send_packet;
++ netdev->tx_timeout = ftgmac100_timeout;
++ netdev->get_stats = ftgmac100_query_statistics;
++//#ifdef HAVE_MULTICAST
++#if 0
++ netdev->set_multicast_list = &ftgmac100_set_multicast_list;
++#endif
++
++#endif
++
++
++#ifdef CONFIG_AST_NPAI
++// netdev->features = NETIF_F_GRO;
++// netdev->features = NETIF_F_IP_CSUM | NETIF_F_GRO;
++#endif
++
++ platform_set_drvdata(pdev, netdev);
++
++ /* setup private data */
++ priv = netdev_priv(netdev);
++ priv->netdev = netdev;
++ priv->dev = &pdev->dev;
++
++
++ priv->ids.macId = pdev->id;
++
++ priv->NCSI_support = ast_eth_data->NCSI_support;
++ priv->INTEL_NCSI_EVA_support= ast_eth_data->INTEL_NCSI_EVA_support;
++ spin_lock_init(&priv->tx_lock);
++
++#if 0
++ /* initialize NAPI */
++ netif_napi_add(netdev, &priv->napi, ftgmac100_poll, 64);
++#endif
++ /* map io memory */
++ res = request_mem_region(res->start, resource_size(res),
++ dev_name(&pdev->dev));
++ if (!res) {
++ dev_err(&pdev->dev, "Could not reserve memory region\n");
++ err = -ENOMEM;
++ goto err_req_mem;
++ }
++
++ netdev->base_addr = (u32)ioremap(res->start, resource_size(res));
++
++ if (!netdev->base_addr) {
++ dev_err(&pdev->dev, "Failed to ioremap ethernet registers\n");
++ err = -EIO;
++ goto err_ioremap;
++ }
++
++// priv->irq = irq;
++#if 0//CONFIG_AST_MDIO
++ /* initialize mdio bus */
++ priv->mii_bus = mdiobus_alloc();
++ if (!priv->mii_bus) {
++ err = -EIO;
++ goto err_alloc_mdiobus;
++ }
++
++ priv->mii_bus->name = "ftgmac100_mdio";
++ snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "ftgmac100_mii.%d",pdev->id);
++
++ priv->mii_bus->priv = netdev;
++ priv->mii_bus->read = ftgmac100_mdiobus_read;
++ priv->mii_bus->write = ftgmac100_mdiobus_write;
++ priv->mii_bus->reset = ftgmac100_mdiobus_reset;
++ priv->mii_bus->irq = priv->phy_irq;
++
++ for (i = 0; i < PHY_MAX_ADDR; i++)
++ priv->mii_bus->irq[i] = PHY_POLL;
++
++ err = mdiobus_register(priv->mii_bus);
++ if (err) {
++ dev_err(&pdev->dev, "Cannot register MDIO bus!\n");
++ goto err_register_mdiobus;
++ }
++
++ err = ftgmac100_mii_probe(priv);
++ if (err) {
++ dev_err(&pdev->dev, "MII Probe failed!\n");
++ goto err_mii_probe;
++ }
++#endif
++ /* register network device */
++ err = register_netdev(netdev);
++ if (err) {
++ dev_err(&pdev->dev, "Failed to register netdev\n");
++ goto err_alloc_mdiobus;
++ }
++
++// printk("irq %d, mapped at %x\n", netdev->irq, (u32)netdev->base_addr);
++
++ if (!is_valid_ether_addr(netdev->dev_addr)) {
++ random_ether_addr(netdev->dev_addr);
++ printk("generated random MAC address %pM\n",
++ netdev->dev_addr);
++ }
++#if 0
++ if ((proc_ftgmac100 = create_proc_entry( dev->name, 0, 0 )))
++ {
++ proc_ftgmac100->read_proc = ftgmac100_read_proc;
++ proc_ftgmac100->data = dev;
++ proc_ftgmac100->owner = THIS_MODULE;
++ }
++#endif
++ return 0;
++
++//err_register_netdev:
++// phy_disconnect(priv->phydev);
++//err_mii_probe:
++// mdiobus_unregister(priv->mii_bus);
++//err_register_mdiobus:
++// mdiobus_free(priv->mii_bus);
++err_alloc_mdiobus:
++ iounmap((void __iomem *)netdev->base_addr);
++err_ioremap:
++ release_resource(res);
++err_req_mem:
++// netif_napi_del(&priv->napi);
++ platform_set_drvdata(pdev, NULL);
++err_netdev:
++ free_netdev(netdev);
++err_alloc_etherdev:
++ return err;
++
++}
++
++static int __devexit ast_gmac_remove(struct platform_device *pdev)
++{
++ struct net_device *dev = platform_get_drvdata(pdev);
++// struct ftgmac100_priv *priv = netdev_priv(dev);
++
++// remove_proc_entry(dev->name, 0);
++
++ unregister_netdev(dev);
++
++#ifdef CONFIG_MII_PHY
++ phy_disconnect(priv->phydev);
++ mdiobus_unregister(priv->mii_bus);
++ mdiobus_free(priv->mii_bus);
++#endif
++
++ iounmap((void __iomem *)dev->base_addr);
++
++#ifdef CONFIG_AST_NPAI
++ netif_napi_del(&priv->napi);
++#endif
++
++ platform_set_drvdata(pdev, NULL);
++ free_netdev(dev);
++ return 0;
++}
++
++static struct platform_driver ast_gmac_driver = {
++ .remove = __devexit_p(ast_gmac_remove),
++ .driver = {
++ .name = "ast_gmac",
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init ast_gmac_init(void)
++{
++ return platform_driver_probe(&ast_gmac_driver, ast_gmac_probe);
++}
++
++static void __exit ast_gmac_exit(void)
++{
++ platform_driver_unregister(&ast_gmac_driver);
++}
++
++module_init(ast_gmac_init)
++module_exit(ast_gmac_exit)
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("ASPEED Technology Inc.");
++MODULE_DESCRIPTION("NIC driver for AST Series");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/net/ftgmac100_26.h b/drivers/net/ftgmac100_26.h
+new file mode 100644
+index 0000000..f145b05
+--- /dev/null
++++ b/drivers/net/ftgmac100_26.h
+@@ -0,0 +1,580 @@
++/********************************************************************************
++* File Name : ftgmac100_26.h
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++********************************************************************************/
++// --------------------------------------------------------------------
++
++#ifndef FTMAC100_H
++#define FTMAC100_H
++
++#define HAVE_MULTICAST
++
++#define ISR_REG 0x00 // interrups status register
++#define IER_REG 0x04 // interrupt maks register
++#define MAC_MADR_REG 0x08 // MAC address (Most significant)
++#define MAC_LADR_REG 0x0c // MAC address (Least significant)
++
++#define MAHT0_REG 0x10 // Multicast Address Hash Table 0 register
++#define MAHT1_REG 0x14 // Multicast Address Hash Table 1 register
++#define TXPD_REG 0x18 // Transmit Poll Demand register
++#define RXPD_REG 0x1c // Receive Poll Demand register
++#define TXR_BADR_REG 0x20 // Transmit Ring Base Address register
++#define RXR_BADR_REG 0x24 // Receive Ring Base Address register
++
++#define HPTXPD_REG 0x28 //
++#define HPTXR_BADR_REG 0x2c //
++
++#define ITC_REG 0x30 // interrupt timer control register
++#define APTC_REG 0x34 // Automatic Polling Timer control register
++#define DBLAC_REG 0x38 // DMA Burst Length and Arbitration control register
++
++#define DMAFIFOS_REG 0x3c //
++#define FEAR_REG 0x44 //
++#define TPAFCR_REG 0x48 //
++#define RBSR_REG 0x4c //for NC Body
++#define MACCR_REG 0x50 // MAC control register
++#define MACSR_REG 0x54 // MAC status register
++#define PHYCR_REG 0x60 // PHY control register
++#define PHYDATA_REG 0x64 // PHY Write Data register
++#define FCR_REG 0x68 // Flow Control register
++#define BPR_REG 0x6c // back pressure register
++#define WOLCR_REG 0x70 // Wake-On-Lan control register
++#define WOLSR_REG 0x74 // Wake-On-Lan status register
++#define WFCRC_REG 0x78 // Wake-up Frame CRC register
++#define WFBM1_REG 0x80 // wake-up frame byte mask 1st double word register
++#define WFBM2_REG 0x84 // wake-up frame byte mask 2nd double word register
++#define WFBM3_REG 0x88 // wake-up frame byte mask 3rd double word register
++#define WFBM4_REG 0x8c // wake-up frame byte mask 4th double word register
++
++#define NPTXR_PTR_REG 0x90 //
++#define HPTXR_PTR_REG 0x94 //
++#define RXR_PTR_REG 0x98 //
++
++
++// --------------------------------------------------------------------
++// ISR_REG ¤Î IMR_REG
++// --------------------------------------------------------------------
++#define HPTXBUF_UNAVA_bit (1UL<<10)
++#define PHYSTS_CHG_bit (1UL<<9)
++#define AHB_ERR_bit (1UL<<8)
++#define TPKT_LOST_bit (1UL<<7)
++#define NPTXBUF_UNAVA_bit (1UL<<6)
++#define TPKT2F_bit (1UL<<5)
++#define TPKT2E_bit (1UL<<4)
++#define RPKT_LOST_bit (1UL<<3)
++#define RXBUF_UNAVA_bit (1UL<<2)
++#define RPKT2F_bit (1UL<<1)
++#define RPKT2B_bit (1UL<<0)
++
++
++// --------------------------------------------------------------------
++// APTC_REG
++// --------------------------------------------------------------------
++
++
++typedef struct
++{
++ u32 RXPOLL_CNT:4;
++ u32 RXPOLL_TIME_SEL:1;
++ u32 Reserved1:3;
++ u32 TXPOLL_CNT:4;
++ u32 TXPOLL_TIME_SEL:1;
++ u32 Reserved2:19;
++}FTGMAC100_APTCR_Status;
++
++// --------------------------------------------------------------------
++// PHYCR_REG
++// --------------------------------------------------------------------
++#define PHY_RE_AUTO_bit (1UL<<9)
++#define PHY_READ_bit (1UL<<26)
++#define PHY_WRITE_bit (1UL<<27)
++// --------------------------------------------------------------------
++// PHYCR_REG
++// --------------------------------------------------------------------
++#define PHY_AUTO_OK_bit (1UL<<5)
++// --------------------------------------------------------------------
++// PHY INT_STAT_REG
++// --------------------------------------------------------------------
++#define PHY_SPEED_CHG_bit (1UL<<14)
++#define PHY_DUPLEX_CHG_bit (1UL<<13)
++#define PHY_LINK_CHG_bit (1UL<<10)
++#define PHY_AUTO_COMP_bit (1UL<<11)
++// --------------------------------------------------------------------
++// PHY SPE_STAT_REG
++// --------------------------------------------------------------------
++#define PHY_RESOLVED_bit (1UL<<11)
++#define PHY_SPEED_mask 0xC000
++#define PHY_SPEED_10M 0x0
++#define PHY_SPEED_100M 0x1
++#define PHY_SPEED_1G 0x2
++#define PHY_DUPLEX_mask 0x2000
++//#define PHY_FULLDUPLEX 0x1
++#define PHY_SPEED_DUPLEX_MASK 0x01E0
++#define PHY_100M_DUPLEX 0x0100
++#define PHY_100M_HALF 0x0080
++#define PHY_10M_DUPLEX 0x0040
++#define PHY_10M_HALF 0x0020
++#define LINK_STATUS 0x04
++
++
++// --------------------------------------------------------------------
++// MACCR_REG
++// --------------------------------------------------------------------
++
++#define SW_RST_bit (1UL<<31) // software reset/
++#define DIRPATH_bit (1UL<<21)
++#define RX_IPCS_FAIL_bit (1UL<<20) //
++#define SPEED_100_bit (1UL<<19) //
++#define RX_UDPCS_FAIL_bit (1UL<<18) //
++#define RX_BROADPKT_bit (1UL<<17) // Receiving broadcast packet
++#define RX_MULTIPKT_bit (1UL<<16) // receiving multicast packet
++#define RX_HT_EN_bit (1UL<<15)
++#define RX_ALLADR_bit (1UL<<14) // not check incoming packet's destination address
++#define JUMBO_LF_bit (1UL<<13) //
++#define RX_RUNT_bit (1UL<<12) // Store incoming packet even its length is les than 64 byte
++#define CRC_CHK_bit (1UL<<11) //
++#define CRC_APD_bit (1UL<<10) // append crc to transmit packet
++#define GMAC_MODE_bit (1UL<<9) //
++#define FULLDUP_bit (1UL<<8) // full duplex
++#define ENRX_IN_HALFTX_bit (1UL<<7) //
++#define LOOP_EN_bit (1UL<<6) // Internal loop-back
++#define HPTXR_EN_bit (1UL<<5) //
++#define REMOVE_VLAN_bit (1UL<<4) //
++//#define MDC_SEL_bit (1UL<<13) // set MDC as TX_CK/10
++//#define RX_FTL_bit (1UL<<11) // Store incoming packet even its length is great than 1518 byte
++#define RXMAC_EN_bit (1UL<<3) // receiver enable
++#define TXMAC_EN_bit (1UL<<2) // transmitter enable
++#define RXDMA_EN_bit (1UL<<1) // enable DMA receiving channel
++#define TXDMA_EN_bit (1UL<<0) // enable DMA transmitting channel
++
++
++// --------------------------------------------------------------------
++// SCU_REG
++// --------------------------------------------------------------------
++#define SCU_PROTECT_KEY_REG 0x0
++#define SCU_PROT_KEY_MAGIC 0x1688a8a8
++#define SCU_RESET_CONTROL_REG 0x04
++#define SCU_RESET_MAC1 (1u << 11)
++#define SCU_RESET_MAC2 (1u << 12)
++
++#define SCU_HARDWARE_TRAPPING_REG 0x70
++#define SCU_HT_MAC_INTF_LSBIT 6
++#define SCU_HT_MAC_INTERFACE (0x7u << SCU_HT_MAC_INTF_LSBIT)
++#define MAC_INTF_SINGLE_PORT_MODES (1u<<0/*GMII*/ | 1u<<3/*MII_ONLY*/ | 1u<<4/*RMII_ONLY*/)
++#define SCU_HT_MAC_GMII 0x0u
++// MII and MII mode
++#define SCU_HT_MAC_MII_MII 0x1u
++#define SCU_HT_MAC_MII_ONLY 0x3u
++#define SCU_HT_MAC_RMII_ONLY 0x4u
++
++/*
++SCU88 D[31]: MAC1 MDIO
++SCU88 D[30]: MAC1 MDC
++SCU90 D[2]: MAC2 MDC/MDIO
++SCU80 D[0]: MAC1 Link
++SCU80 D[1]: MAC2 Link
++*/
++#define SCU_MULTIFUNCTION_PIN_REG 0x74
++#define SCU_MULTIFUNCTION_PIN_CTL1_REG 0x80
++#define SCU_MULTIFUNCTION_PIN_CTL3_REG 0x88
++#define SCU_MULTIFUNCTION_PIN_CTL5_REG 0x90
++#define SCU_MFP_MAC2_PHYLINK (1u << 1)
++#define SCU_MFP_MAC1_PHYLINK (1u << 0)
++#define SCU_MFP_MAC2_MII_INTF (1u << 21)
++#define SCU_MFP_MAC2_MDC_MDIO (1u << 2)
++#define SCU_MFP_MAC1_MDIO (1u << 31)
++#define SCU_MFP_MAC1_MDC (1u << 30)
++#define SCU_SILICON_REVISION_REG 0x7C
++#define SCU_SCRATCH_REG 0x40
++
++
++
++// --------------------------------------------------------------------
++// NCSI
++// --------------------------------------------------------------------
++
++//NCSI define & structure
++//NC-SI Command Packet
++typedef struct {
++//Ethernet Header
++ unsigned char DA[6];
++ unsigned char SA[6];
++ unsigned short EtherType; //DMTF NC-SI
++//NC-SI Control Packet
++ unsigned char MC_ID; //Management Controller should set this field to 0x00
++ unsigned char Header_Revision; //For NC-SI 1.0 spec, this field has to set 0x01
++ unsigned char Reserved_1; //Reserved has to set to 0x00
++ unsigned char IID; //Instance ID
++ unsigned char Command;
++ unsigned char Channel_ID;
++ unsigned short Payload_Length; //Payload Length = 12 bits, 4 bits are reserved
++ unsigned long Reserved_2;
++ unsigned long Reserved_3;
++} NCSI_Command_Packet;
++
++//Command and Response Type
++#define CLEAR_INITIAL_STATE 0x00 //M
++#define SELECT_PACKAGE 0x01 //M
++#define DESELECT_PACKAGE 0x02 //M
++#define ENABLE_CHANNEL 0x03 //M
++#define DISABLE_CHANNEL 0x04 //M
++#define RESET_CHANNEL 0x05 //M
++#define ENABLE_CHANNEL_NETWORK_TX 0x06 //M
++#define DISABLE_CHANNEL_NETWORK_TX 0x07 //M
++#define AEN_ENABLE 0x08
++#define SET_LINK 0x09 //M
++#define GET_LINK_STATUS 0x0A //M
++#define SET_VLAN_FILTER 0x0B //M
++#define ENABLE_VLAN 0x0C //M
++#define DISABLE_VLAN 0x0D //M
++#define SET_MAC_ADDRESS 0x0E //M
++#define ENABLE_BROADCAST_FILTERING 0x10 //M
++#define DISABLE_BROADCAST_FILTERING 0x11 //M
++#define ENABLE_GLOBAL_MULTICAST_FILTERING 0x12
++#define DISABLE_GLOBAL_MULTICAST_FILTERING 0x13
++#define SET_NCSI_FLOW_CONTROL 0x14
++#define GET_VERSION_ID 0x15 //M
++#define GET_CAPABILITIES 0x16 //M
++#define GET_PARAMETERS 0x17 //M
++#define GET_CONTROLLER_PACKET_STATISTICS 0x18
++#define GET_NCSI_STATISTICS 0x19
++#define GET_NCSI_PASS_THROUGH_STATISTICS 0x1A
++
++//NC-SI Response Packet
++typedef struct {
++ unsigned char DA[6];
++ unsigned char SA[6];
++ unsigned short EtherType; //DMTF NC-SI
++//NC-SI Control Packet
++ unsigned char MC_ID; //Management Controller should set this field to 0x00
++ unsigned char Header_Revision; //For NC-SI 1.0 spec, this field has to set 0x01
++ unsigned char Reserved_1; //Reserved has to set to 0x00
++ unsigned char IID; //Instance ID
++ unsigned char Command;
++ unsigned char Channel_ID;
++ unsigned short Payload_Length; //Payload Length = 12 bits, 4 bits are reserved
++ unsigned short Reserved_2;
++ unsigned short Reserved_3;
++ unsigned short Reserved_4;
++ unsigned short Reserved_5;
++ unsigned short Response_Code;
++ unsigned short Reason_Code;
++ unsigned char Payload_Data[64];
++} NCSI_Response_Packet;
++
++//Standard Response Code
++#define COMMAND_COMPLETED 0x00
++#define COMMAND_FAILED 0x01
++#define COMMAND_UNAVAILABLE 0x02
++#define COMMAND_UNSUPPORTED 0x03
++
++//Standard Reason Code
++#define NO_ERROR 0x0000
++#define INTERFACE_INITIALIZATION_REQUIRED 0x0001
++#define PARAMETER_IS_INVALID 0x0002
++#define CHANNEL_NOT_READY 0x0003
++#define PACKAGE_NOT_READY 0x0004
++#define INVALID_PAYLOAD_LENGTH 0x0005
++#define UNKNOWN_COMMAND_TYPE 0x7FFF
++
++
++struct AEN_Packet {
++//Ethernet Header
++ unsigned char DA[6];
++ unsigned char SA[6]; //Network Controller SA = FF:FF:FF:FF:FF:FF
++ unsigned short EtherType; //DMTF NC-SI
++//AEN Packet Format
++ unsigned char MC_ID; //Network Controller should set this field to 0x00
++ unsigned char Header_Revision; //For NC-SI 1.0 spec, this field has to set 0x01
++ unsigned char Reserved_1; //Reserved has to set to 0x00
++// unsigned char IID = 0x00; //Instance ID = 0 in Network Controller
++// unsigned char Command = 0xFF; //AEN = 0xFF
++ unsigned char Channel_ID;
++// unsigned short Payload_Length = 0x04; //Payload Length = 4 in Network Controller AEN Packet
++ unsigned long Reserved_2;
++ unsigned long Reserved_3;
++ unsigned char AEN_Type;
++// unsigned char Reserved_4[3] = {0x00, 0x00, 0x00};
++ unsigned long Optional_AEN_Data;
++ unsigned long Payload_Checksum;
++};
++
++//AEN Type
++#define LINK_STATUS_CHANGE 0x0
++#define CONFIGURATION_REQUIRED 0x1
++#define HOST_NC_DRIVER_STATUS_CHANGE 0x2
++
++typedef struct {
++ unsigned char Package_ID;
++ unsigned char Channel_ID;
++ unsigned long Capabilities_Flags;
++ unsigned long Broadcast_Packet_Filter_Capabilities;
++ unsigned long Multicast_Packet_Filter_Capabilities;
++ unsigned long Buffering_Capabilities;
++ unsigned long AEN_Control_Support;
++} NCSI_Capability;
++NCSI_Capability NCSI_Cap;
++
++//SET_MAC_ADDRESS
++#define UNICAST (0x00 << 5)
++#define MULTICAST_ADDRESS (0x01 << 5)
++#define DISABLE_MAC_ADDRESS_FILTER 0x00
++#define ENABLE_MAC_ADDRESS_FILTER 0x01
++
++//GET_LINK_STATUS
++#define LINK_DOWN 0
++#define LINK_UP 1
++
++#define NCSI_LOOP 1500000
++#define RETRY_COUNT 1
++
++#define NCSI_HEADER 0xF888 //Reversed because of 0x88 is low byte, 0xF8 is high byte in memory
++
++// --------------------------------------------------------------------
++// Receive Ring descriptor structure
++// --------------------------------------------------------------------
++
++typedef struct
++{
++ // RXDES0
++ u32 VDBC:14;//0~10
++ u32 Reserved1:1; //11~15
++ u32 Reserved3:1;
++ u32 MULTICAST:1; //16
++ u32 BROADCAST:1; //17
++ u32 RX_ERR:1; //18
++ u32 CRC_ERR:1; //19
++ u32 FTL:1;
++ u32 RUNT:1;
++ u32 RX_ODD_NB:1;
++ u32 FIFO_FULL:1;
++ u32 PAUSE_OPCODE:1;
++ u32 PAUSE_FRAME:1;
++ u32 Reserved2:2;
++ u32 LRS:1;
++ u32 FRS:1;
++ u32 EDORR:1;
++ u32 RXPKT_RDY:1; // 1 ==> owned by FTMAC100, 0 ==> owned by software
++
++ // RXDES1
++ u32 VLAN_TAGC:16;
++ u32 Reserved4:4;
++ u32 PROTL_TYPE:2;
++ u32 LLC_PKT:1;
++ u32 DF:1;
++ u32 VLAN_AVA:1;
++ u32 TCPCS_FAIL:1;
++ u32 UDPCS_FAIL:1;
++ u32 IPCS_FAIL:1;
++ u32 Reserved5:4;
++
++ // RXDES2
++ u32 Reserved6:32;
++
++ // RXDES3
++ u32 RXBUF_BADR;
++
++ u32 VIR_RXBUF_BADR; // not defined, the virtual address of receive buffer is placed here
++
++ u32 RESERVED;
++ u32 RESERVED1;
++ u32 RESERVED2;
++}RX_DESC;
++
++
++typedef struct
++{
++ // TXDES0
++ u32 TXBUF_Size:14;
++ u32 Reserved1:1;
++ u32 Reserved2:1;
++ u32 Reserved3:3;
++ u32 CRC_ERR:1;
++ u32 Reserved4:8;
++ u32 LTS:1;
++ u32 FTS:1;
++ u32 EDOTR:1;
++ u32 TXDMA_OWN:1;
++
++ // TXDES1
++ u32 VLAN_TAGC:16;
++ u32 INS_VLAN:1;
++ u32 TCPCS_EN:1;
++ u32 UDPCS_EN:1;
++ u32 IPCS_EN:1;
++ u32 Reserved5:2;
++ u32 LLC_PKT:1;
++ u32 Reserved6:7;
++ u32 TX2FIC:1;
++ u32 TXIC:1;
++
++ // TXDES2
++ u32 Reserved7:32;
++
++ // TXDES3
++ u32 TXBUF_BADR;
++
++ u32 VIR_TXBUF_BADR; // Reserve, the virtual address of transmit buffer is placed here
++
++ u32 RESERVED;
++ u32 RESERVED1;
++ u32 RESERVED2;
++
++}TX_DESC;
++
++
++
++// waiting to do:
++#define TXPOLL_CNT 8
++#define RXPOLL_CNT 0
++
++#define TX_OWNBY_SOFTWARE 0
++#define TX_OWNBY_FTGMAC100 1
++
++
++#define RX_OWNBY_SOFTWARE 1
++#define RX_OWNBY_FTGMAC100 0
++
++// --------------------------------------------------------------------
++// driver related definition
++// --------------------------------------------------------------------
++
++
++//#define RXDES_NUM 64//64 // we defined 32 descriptor for OTG issue
++#define RXDES_NUM 32
++
++#define RX_BUF_SIZE 1536
++
++#define TXDES_NUM 32
++#define TX_BUF_SIZE 1536
++
++#define PHYID_VENDOR_MASK 0xfffffc00
++#define PHYID_VENDOR_MODEL_MASK 0xfffffff0
++#define PHYID_MODEL_MASK 0x000003f0
++#define PHYID_REVISION_MASK 0x0000000f
++#define PHYID_VENDOR_MARVELL 0x01410c00
++#define PHYID_VENDOR_BROADCOM 0x00406000
++#define PHYID_VENDOR_REALTEK 0x001cc800
++
++#define PHYID_BCM5221A4 0x004061e4
++//#define PHYID_RTL8201EL 0x001cc815
++#define PHYID_RTL8201EL 0x001cc810
++#define PHYID_RTL8201F 0x001cc816
++#define PHYID_RTL8211 0x001cc910
++#define PHYID_RTL8211E 0x001cc915
++#define PHYID_BCM54612E 0x03625E6A
++
++
++/* store this information for the driver.. */
++
++struct AstMacHwConfig {
++ unsigned char phyAddr; // See IP_phy_addr[] encoding
++ unsigned char macId;
++ unsigned char isRevA0;
++ unsigned char isRevA2;
++ unsigned char pad[1];
++ unsigned int miiPhyId;
++};
++
++struct ftgmac100_priv {
++
++ // these are things that the kernel wants me to keep, so users
++ // can find out semi-useless statistics of how well the card is
++ // performing
++ struct net_device_stats stats;
++
++ struct AstMacHwConfig ids;
++
++ struct net_device *netdev;
++ struct device *dev;
++
++ // Set to true during the auto-negotiation sequence
++ int autoneg_active;
++
++ // Last contents of PHY Register 18
++ u32 lastPhy18;
++
++ spinlock_t tx_lock;
++
++ //RX ..
++ volatile RX_DESC *rx_descs; // receive ring base address
++ struct sk_buff *rx_skbuff[RXDES_NUM];
++ u32 rx_descs_dma; // receive ring physical base address
++ int rx_idx; // receive descriptor
++
++ //TX ..
++ volatile TX_DESC *tx_descs;
++ u32 tx_descs_dma;
++ char *tx_buf;
++ int tx_buf_dma;
++ int tx_idx;
++ int old_tx;
++ struct sk_buff *tx_skbuff[TXDES_NUM];
++
++ int maccr_val;
++ struct timer_list timer;
++ u32 GigaBit_MAHT0;
++ u32 GigaBit_MAHT1;
++ u32 Not_GigaBit_MAHT0;
++ u32 Not_GigaBit_MAHT1;
++ NCSI_Command_Packet NCSI_Request;
++ NCSI_Response_Packet NCSI_Respond;
++ NCSI_Capability NCSI_Cap;
++ unsigned int InstanceID;
++ unsigned int Retry;
++ unsigned char Payload_Data[16];
++ unsigned char Payload_Pad[4];
++ unsigned long Payload_Checksum;
++ int tx_free;
++ unsigned long NCSI_support;
++ unsigned long INTEL_NCSI_EVA_support;
++};
++
++
++#define FTGMAC100_STROBE_TIME (10*HZ)
++///#define FTMAC100_STROBE_TIME 1
++
++//I2C define for EEPROM
++#define AC_TIMING 0x77743335
++#define ALL_CLEAR 0xFFFFFFFF
++#define MASTER_ENABLE 0x01
++#define SLAVE_ENABLE 0x02
++#define LOOP_COUNT 0x100000
++
++
++#define I2C_BASE 0x1e78A000
++#define I2C_FUNCTION_CONTROL_REGISTER 0x00
++#define I2C_AC_TIMING_REGISTER_1 0x04
++#define I2C_AC_TIMING_REGISTER_2 0x08
++#define I2C_INTERRUPT_CONTROL_REGISTER 0x0C
++#define I2C_INTERRUPT_STATUS_REGISTER 0x10
++#define I2C_COMMAND_REGISTER 0x14
++#define I2C_BYTE_BUFFER_REGISTER 0x20
++
++
++#define MASTER_START_COMMAND (1 << 0)
++#define MASTER_TX_COMMAND (1 << 1)
++#define MASTER_RX_COMMAND (1 << 3)
++#define RX_COMMAND_LIST (1 << 4)
++#define MASTER_STOP_COMMAND (1 << 5)
++
++#define TX_ACK (1 << 0)
++#define TX_NACK (1 << 1)
++#define RX_DONE (1 << 2)
++#define STOP_DONE (1 << 4)
++
++
++
++#endif /* _SMC_91111_H_ */
++
++
+diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
+index 123092d..f60078c7 100644
+--- a/drivers/rtc/Kconfig
++++ b/drivers/rtc/Kconfig
+@@ -679,4 +679,10 @@ config RTC_DRV_STARFIRE
+ If you say Y here you will get support for the RTC found on
+ Starfire systems.
+
++config RTC_DRV_ASPEED
++ bool "ASPEED RTC"
++ depends on ARM
++ help
++ RTC driver for ASPEED chips.
++
+ endif # RTC_CLASS
+diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
+index 6e79c91..7a16fed 100644
+--- a/drivers/rtc/Makefile
++++ b/drivers/rtc/Makefile
+@@ -70,3 +70,4 @@ obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o
+ obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o
+ obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o
+ obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o
++obj-$(CONFIG_RTC_DRV_ASPEED) += rtc-aspeed.o
+diff --git a/drivers/rtc/rtc-aspeed.c b/drivers/rtc/rtc-aspeed.c
+new file mode 100755
+index 0000000..477032e
+--- /dev/null
++++ b/drivers/rtc/rtc-aspeed.c
+@@ -0,0 +1,495 @@
++/********************************************************************************
++* File Name : drivers/rtc/rtc-ast.c
++* Author : Ryan chen
++* Description : ASPEED Real Time Clock Driver (RTC)
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/09/21 ryan chen create this file
++*
++********************************************************************************/
++
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/interrupt.h>
++#include <linux/rtc.h>
++#include <linux/delay.h>
++#include <linux/slab.h>
++#include <asm/io.h>
++
++#include <plat/regs-rtc.h>
++
++struct ast_rtc {
++ void __iomem *base;
++ int irq;
++ struct resource *res;
++ struct rtc_device *rtc_dev;
++ spinlock_t lock;
++};
++
++//static char banner[] = "ASPEED RTC, (C) ASPEED Technology Inc.\n";
++//#define CONFIG_RTC_DEBUG
++
++
++static inline u32
++rtc_read(void __iomem *base, u32 reg)
++{
++#ifdef CONFIG_RTC_DEBUG
++ int val = readl(base + reg);
++ pr_debug("base = 0x%p, offset = 0x%08x, value = 0x%08x\n", base, reg, val);
++ return val;
++#else
++ return readl(base + reg);
++#endif
++}
++
++static inline void
++rtc_write(void __iomem * base, u32 val, u32 reg)
++{
++ pr_debug("base = 0x%p, offset = 0x%08x, data = 0x%08x\n", base, reg, val);
++ writel(val, base + reg);
++}
++
++static int
++ast_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
++{
++ struct ast_rtc *ast_rtc = dev_get_drvdata(dev);
++ pr_debug("cmd = 0x%08x, arg = 0x%08lx\n", cmd, arg);
++
++ switch (cmd) {
++ case RTC_AIE_ON: /* alarm on */
++ {
++ rtc_write(ast_rtc->base, rtc_read(ast_rtc->base, RTC_CONTROL) | ENABLE_ALL_ALARM, RTC_CONTROL);
++ return 0;
++ }
++
++ case RTC_AIE_OFF: /* alarm off */
++ {
++ rtc_write(ast_rtc->base, rtc_read(ast_rtc->base, RTC_CONTROL) &~ENABLE_ALL_ALARM, RTC_CONTROL);
++ return 0;
++ }
++ case RTC_UIE_ON: /* update on */
++ {
++ pr_debug("no such function \n");
++ return 0;
++ }
++ case RTC_UIE_OFF: /* update off */
++ {
++ pr_debug("no such function \n");
++ return 0;
++ }
++ case RTC_PIE_OFF: /* periodic off */
++ {
++ rtc_write(ast_rtc->base, rtc_read(ast_rtc->base, RTC_CONTROL) | ENABLE_SEC_INTERRUPT, RTC_CONTROL);
++
++ return 0;
++ }
++ case RTC_PIE_ON: /* periodic on */
++ {
++ rtc_write(ast_rtc->base, rtc_read(ast_rtc->base, RTC_CONTROL) & ~ENABLE_SEC_INTERRUPT, RTC_CONTROL);
++
++ return 0;
++ }
++ default:
++ return -ENOTTY;
++ }
++
++ return 0;
++}
++
++
++/* Time read/write */
++static int
++ast_rtc_get_time(struct device *dev, struct rtc_time *rtc_tm)
++{
++ struct ast_rtc *ast_rtc = dev_get_drvdata(dev);
++ unsigned long flags;
++ u32 reg_time, reg_date;
++
++ spin_lock_irqsave(&ast_rtc->lock, flags);
++
++ reg_time = rtc_read(ast_rtc->base, RTC_CNTR_STS_1);
++ reg_date = rtc_read(ast_rtc->base, RTC_CNTR_STS_2);
++
++ spin_unlock_irqrestore(&ast_rtc->lock, flags);
++
++ rtc_tm->tm_year = GET_CENT_VAL(reg_date)*1000 | GET_YEAR_VAL(reg_date);
++ rtc_tm->tm_mon = GET_MON_VAL(reg_date);
++
++ rtc_tm->tm_mday = GET_DAY_VAL(reg_time);
++ rtc_tm->tm_hour = GET_HOUR_VAL(reg_time);
++ rtc_tm->tm_min = GET_MIN_VAL(reg_time);
++ rtc_tm->tm_sec = GET_SEC_VAL(reg_time);
++
++ pr_debug("read time %02x.%02x.%02x %02x/%02x/%02x\n",
++ rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday,
++ rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec);
++ return 0;
++
++}
++
++static int
++ast_rtc_set_time(struct device *dev, struct rtc_time *tm)
++{
++ struct ast_rtc *ast_rtc = dev_get_drvdata(dev);
++ unsigned long flags;
++ u32 reg_time, reg_date;
++
++ pr_debug("set time %02d.%02d.%02d %02d/%02d/%02d\n",
++ tm->tm_year, tm->tm_mon, tm->tm_mday,
++ tm->tm_hour, tm->tm_min, tm->tm_sec);
++
++ spin_lock_irqsave(&ast_rtc->lock, flags);
++
++ /* set hours */
++ reg_time = SET_DAY_VAL(tm->tm_mday) | SET_HOUR_VAL(tm->tm_hour) | SET_MIN_VAL(tm->tm_min) | SET_SEC_VAL(tm->tm_sec);
++
++ /* set century */
++ /* set mon */
++ reg_date = SET_CENT_VAL(tm->tm_year / 1000) | SET_YEAR_VAL(tm->tm_year % 1000) | SET_MON_VAL(tm->tm_mon);
++
++ rtc_write(ast_rtc->base, rtc_read(ast_rtc->base, RTC_CONTROL) | RTC_LOCK, RTC_CONTROL);
++
++ rtc_write(ast_rtc->base, reg_time, RTC_CNTR_STS_1);
++ rtc_write(ast_rtc->base, reg_date, RTC_CNTR_STS_2);
++
++ rtc_write(ast_rtc->base, rtc_read(ast_rtc->base, RTC_CONTROL) &~RTC_LOCK , RTC_CONTROL);
++
++ spin_unlock_irqrestore(&ast_rtc->lock, flags);
++
++ return 0;
++}
++static int
++ast_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
++{
++ struct ast_rtc *ast_rtc = dev_get_drvdata(dev);
++ unsigned long flags;
++ struct rtc_time *alm_tm = &alarm->time;
++ u32 alarm_reg;
++
++ spin_lock_irqsave(&ast_rtc->lock, flags);
++ alarm_reg = rtc_read(ast_rtc->base, RTC_ALARM);
++ spin_unlock_irqrestore(&ast_rtc->lock, flags);
++
++//DAY
++ alm_tm->tm_mday = GET_DAY_VAL(alarm_reg);
++
++//HR
++ alm_tm->tm_hour = GET_HOUR_VAL(alarm_reg);
++
++//MIN
++ alm_tm->tm_min= GET_MIN_VAL(alarm_reg);
++
++//SEC
++ alm_tm->tm_sec= GET_SEC_VAL(alarm_reg);
++
++ pr_debug("ast_rtc_read_alarm: %d, %02x %02x.%02x.%02x\n",
++ alarm->enabled,
++ alm_tm->tm_mday & 0xff, alm_tm->tm_hour & 0xff, alm_tm->tm_min & 0xff, alm_tm->tm_sec);
++
++ return 0;
++
++
++}
++
++static int
++ast_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
++{
++ struct ast_rtc *ast_rtc = dev_get_drvdata(dev);
++ struct rtc_time *tm = &alarm->time;
++ unsigned long flags;
++ u32 reg_alarm = 0;
++
++ pr_debug("ast_rtc_setalarm: %d, %02x %02x.%02x.%02x\n",
++ alarm->enabled,
++ tm->tm_mday & 0xff, tm->tm_hour & 0xff, tm->tm_min & 0xff, tm->tm_sec);
++
++//DAY
++ /* set day of week */
++ if (tm->tm_mday <= 31 && tm->tm_mday >= 1) {
++ reg_alarm |= SET_DAY_VAL(tm->tm_mday);
++ }
++
++//HR
++ /* set ten hours */
++ if (tm->tm_hour <= 23 && tm->tm_hour >= 0) {
++ reg_alarm |= SET_HOUR_VAL(tm->tm_hour);
++ }
++
++//MIN
++ /* set ten minutes */
++ if (tm->tm_min <= 59 && tm->tm_min >= 0) {
++ reg_alarm |= SET_MIN_VAL(tm->tm_min);
++ }
++
++//SEC
++ /* set ten secondss */
++ if (tm->tm_sec <= 59 && tm->tm_sec >= 0) {
++ reg_alarm |= SET_SEC_VAL(tm->tm_sec);
++ }
++
++ pr_debug("ast_rtc_set alarm reg: %x \n", reg_alarm);
++
++ spin_lock_irqsave(&ast_rtc->lock, flags);
++
++ rtc_write(ast_rtc->base, reg_alarm, RTC_ALARM);
++
++ if(alarm->enabled)
++ rtc_write(ast_rtc->base, reg_alarm, RTC_CONTROL);
++ else
++ rtc_write(ast_rtc->base, reg_alarm, RTC_CONTROL);
++
++ spin_unlock_irqrestore(&ast_rtc->lock, flags);
++ return 0;
++
++}
++static int
++ast_rtc_proc(struct device *dev, struct seq_file *seq)
++{
++ struct ast_rtc *ast_rtc = dev_get_drvdata(dev);
++ u32 ctrl_reg;
++
++ ctrl_reg = rtc_read(ast_rtc->base, RTC_CONTROL);
++
++ pr_debug("ctrl_reg = 0x%08x\n", ctrl_reg);
++
++ seq_printf(seq, "periodic_IRQ\t: %s\n",
++ (ctrl_reg & ENABLE_SEC_INTERRUPT) ? "yes" : "no" );
++
++ return 0;
++}
++
++static int
++ast_rtc_irq_set_freq(struct device *dev, int freq)
++{
++ struct ast_rtc *ast_rtc = dev_get_drvdata(dev);
++ pr_debug("freq = %d\n", freq);
++
++ spin_lock_irq(&ast_rtc->lock);
++
++ if(freq == 0)
++ rtc_write(ast_rtc->base, rtc_read(ast_rtc->base, RTC_CONTROL)&~ENABLE_SEC_INTERRUPT, RTC_CONTROL);
++ else
++ rtc_write(ast_rtc->base, rtc_read(ast_rtc->base, RTC_CONTROL)|ENABLE_SEC_INTERRUPT, RTC_CONTROL);
++
++ spin_unlock_irq(&ast_rtc->lock);
++
++ return 0;
++}
++
++static irqreturn_t
++ast_rtc_interrupt(int irq, void *dev_id)
++{
++ struct ast_rtc *ast_rtc = dev_id;
++
++ unsigned int status = rtc_read(ast_rtc->base, RTC_ALARM_STS);
++ rtc_write(ast_rtc->base, status, RTC_ALARM_STS);
++
++ if (status & SEC_INTERRUPT_STATUS) {
++ printk("RTC Alarm SEC_INTERRUPT_STATUS!!\n");
++ }
++
++ if (status & DAY_ALARM_STATUS) {
++ printk("RTC Alarm DAY_ALARM_STATUS!!\n");
++ }
++
++ if (status & HOUR_ALARM_STATUS) {
++ printk("RTC Alarm HOUR_ALARM_STATUS!!\n");
++ }
++
++ if (status & MIN_ALARM_STATUS) {
++ printk("RTC Alarm MIN_ALARM_STATUS!!\n");
++ }
++
++ if (status & SEC_ALARM_STATUS) {
++ printk("RTC Alarm SEC_ALARM_STATUS!!\n");
++ }
++
++ rtc_update_irq(ast_rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
++
++ return (IRQ_HANDLED);
++}
++
++static struct rtc_class_ops ast_rtcops = {
++ .ioctl = ast_rtc_ioctl,
++ .read_time = ast_rtc_get_time,
++ .set_time = ast_rtc_set_time,
++ .read_alarm = ast_rtc_read_alarm,
++ .set_alarm = ast_rtc_set_alarm,
++ .proc = ast_rtc_proc,
++ .irq_set_freq = ast_rtc_irq_set_freq,
++};
++
++/*
++ * Initialize and install RTC driver
++ */
++static int __init ast_rtc_probe(struct platform_device *pdev)
++{
++ struct ast_rtc *ast_rtc;
++ struct rtc_device *rtc_dev;
++ struct resource *res;
++ int ret;
++
++ pr_debug("%s: probe=%p\n", __func__, pdev);
++
++ ast_rtc = kzalloc(sizeof *ast_rtc, GFP_KERNEL);
++ if (!ast_rtc)
++ return -ENOMEM;
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res) {
++ dev_err(&pdev->dev, "register resources unusable\n");
++ ret = -ENXIO;
++ goto free_rtc;
++ }
++
++ ast_rtc->irq = platform_get_irq(pdev, 0);
++ if (ast_rtc->irq < 0) {
++ dev_err(&pdev->dev, "unable to get irq\n");
++ ret = -ENXIO;
++ goto free_rtc;
++ }
++
++ if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
++ ret = -EBUSY;
++ goto free_rtc;
++ }
++
++ ast_rtc->base = ioremap(res->start, resource_size(res));
++ if (!ast_rtc->base) {
++ dev_err(&pdev->dev, "cannot map SocleDev registers\n");
++ ret = -ENOMEM;
++ goto release_mem;
++ }
++
++ pr_debug("base = 0x%p, irq = %d\n", ast_rtc->base, ast_rtc->irq);
++
++ rtc_dev = rtc_device_register(pdev->name, &pdev->dev, &ast_rtcops, THIS_MODULE);
++ if (IS_ERR(rtc_dev)) {
++ ret = PTR_ERR(rtc_dev);
++ goto unmap;
++ }
++
++ ast_rtc->res = res;
++ ast_rtc->rtc_dev = rtc_dev;
++ spin_lock_init(&ast_rtc->lock);
++
++ platform_set_drvdata(pdev, ast_rtc);
++
++// ast_rtc_irq_set_freq(&pdev->dev, 1);
++
++ /* start the RTC from dddd:hh:mm:ss = 0000:00:00:00 */
++ spin_lock_irq(&ast_rtc->lock);
++ if(!(rtc_read(ast_rtc->base, RTC_CONTROL) & RTC_ENABLE)) {
++ //combination mode
++ rtc_write(ast_rtc->base, ALARM_MODE_SELECT | RTC_LOCK | RTC_ENABLE, RTC_CONTROL);
++
++ rtc_write(ast_rtc->base, 0, RTC_CNTR_STS_1);
++
++ rtc_write(ast_rtc->base, 0, RTC_CNTR_STS_2);
++
++ rtc_write(ast_rtc->base, 0, RTC_ALARM);
++ rtc_write(ast_rtc->base, ~RTC_LOCK & rtc_read(ast_rtc->base, RTC_CONTROL), RTC_CONTROL);
++ } else
++ printk("no need to enable RTC \n");
++
++ spin_unlock_irq(&ast_rtc->lock);
++
++ /* register ISR */
++ ret = request_irq(ast_rtc->irq, ast_rtc_interrupt, IRQF_DISABLED, dev_name(&rtc_dev->dev), ast_rtc);
++ if (ret) {
++ printk(KERN_ERR "ast_rtc: IRQ %d already in use.\n",
++ ast_rtc->irq);
++ goto unregister;
++ }
++
++ return 0;
++
++unregister:
++ rtc_device_unregister(rtc_dev);
++ platform_set_drvdata(pdev, NULL);
++unmap:
++ iounmap(ast_rtc->base);
++release_mem:
++ release_mem_region(res->start, resource_size(res));
++free_rtc:
++ kfree(ast_rtc);
++ return ret;
++
++}
++
++/*
++ * Disable and remove the RTC driver
++ */
++static int __exit ast_rtc_remove(struct platform_device *pdev)
++{
++ struct ast_rtc *ast_rtc = platform_get_drvdata(pdev);
++
++ free_irq(IRQ_RTC, pdev);
++ rtc_device_unregister(ast_rtc->rtc_dev);
++ platform_set_drvdata(pdev, NULL);
++ iounmap(ast_rtc->base);
++ release_resource(ast_rtc->res);
++ kfree(ast_rtc);
++
++ return 0;
++}
++
++#ifdef CONFIG_PM
++
++/* ASPEED RTC Power management control */
++static int ast_rtc_suspend(struct platform_device *pdev, pm_message_t state)
++{
++ return 0;
++}
++
++static int ast_rtc_resume(struct platform_device *pdev)
++{
++ return 0;
++}
++#else
++#define ast_rtc_suspend NULL
++#define ast_rtc_resume NULL
++#endif
++
++static struct platform_driver ast_rtc_driver = {
++ .probe = ast_rtc_probe,
++ .remove = __exit_p(ast_rtc_remove),
++ .suspend = ast_rtc_suspend,
++ .resume = ast_rtc_resume,
++ .driver = {
++ .name = "ast_rtc",
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init ast_rtc_init(void)
++{
++ return platform_driver_register(&ast_rtc_driver);
++}
++
++static void __exit ast_rtc_exit(void)
++{
++ platform_driver_unregister(&ast_rtc_driver);
++}
++
++module_init(ast_rtc_init);
++module_exit(ast_rtc_exit);
++
++MODULE_AUTHOR("Ryan Chen");
++MODULE_DESCRIPTION("RTC driver for ASPEED AST ");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:ast_rtc");
++
+diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
+index 579d63a..5666583 100644
+--- a/drivers/serial/Kconfig
++++ b/drivers/serial/Kconfig
+@@ -137,6 +137,34 @@ config SERIAL_8250_RUNTIME_UARTS
+ with the module parameter "nr_uarts", or boot-time parameter
+ 8250.nr_uarts
+
++config SERIAL_AST_DMA_UART
++ tristate "AST UART driver with DMA"
++ depends on ARCH_ASPEED
++ select SERIAL_CORE
++ help
++ The ASPEED UART driver with DMA supporting. The device node is /dev/ttyDMA
++
++config AST_NR_DMA_UARTS
++ int "Maximum number of ast1070 uart dma serial ports"
++ depends on SERIAL_AST_DMA_UART
++ default "4"
++ help
++ Set this to the number of serial ports you want the driver
++ to support. This includes any ports discovered via ACPI or
++ PCI enumeration and any ports that may be added at run-time
++ via hot-plug, or any ISA multi-port serial cards.
++
++config AST_RUNTIME_DMA_UARTS
++ int "Number of ast1070 uart dma serial ports to register at runtime"
++ depends on SERIAL_AST_DMA_UART
++ range 0 AST_NR_DMA_UARTS
++ default "4"
++ help
++ Set this to the maximum number of serial ports you want
++ the kernel to register at boot time. This can be overridden
++ with the module parameter "nr_uarts", or boot-time parameter
++ 8250.nr_uarts
++
+ config SERIAL_8250_EXTENDED
+ bool "Extended 8250/16550 serial driver options"
+ depends on SERIAL_8250
+@@ -510,6 +538,39 @@ config SERIAL_S3C2440
+
+
+
++config SERIAL_AST
++ tristate "ASPEED serial port support"
++ depends on ARCH_ASPEED
++ select SERIAL_CORE
++ help
++ Support for the on-chip UARTs on the ASPEED chips,
++ providing /dev/ttySAC0, 1 and 2 (note, some machines may not
++ provide all of these ports, depending on how the serial port
++ pins are configured.
++
++config SERIAL_ASPEED_CONSOLE
++ bool "Support for console on ASPEED serial port"
++ depends on SERIAL_AST=y
++ select SERIAL_CORE_CONSOLE
++ help
++ Allow selection of the ASPEED on-board serial ports for use as
++ an virtual console.
++
++ Even if you say Y here, the currently visible virtual console
++ (/dev/ttyS0) will still be used as the system console by default, but
++ you can alter that using a kernel command line option such as
++ "console=ttySx". (Try "man bootparam" or see the documentation of
++ your boot loader about how to pass options to the kernel at
++ boot time.)
++
++config SERIAL_ASPEED_CONSOLE_BAUD
++ int "ASPEED serial port baud"
++ depends on SERIAL_ASPEED_CONSOLE=y
++ default "115200"
++ help
++ Select the ASPEED console baud rate.
++ This value is only used if the bootloader doesn't pass in the
++
+ config SERIAL_DZ
+ bool "DECstation DZ serial driver"
+ depends on MACH_DECSTATION && 32BIT
+diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
+index 0c17c8d..9a0059f 100644
+--- a/drivers/serial/Makefile
++++ b/drivers/serial/Makefile
+@@ -19,6 +19,7 @@ obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o
+ obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o
+ obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o
+ obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o
++obj-$(CONFIG_SERIAL_AST) += ast_serial.o
+ obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o
+ obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o
+ obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o
+@@ -28,6 +29,7 @@ obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
+ obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o
+ obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
+ obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o
++obj-$(CONFIG_SERIAL_AST_DMA_UART) += ast1070_dma_uart.o
+ obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
+ obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
+ obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
+diff --git a/drivers/serial/ast1070_dma_uart.c b/drivers/serial/ast1070_dma_uart.c
+new file mode 100644
+index 0000000..16eb3c5
+--- /dev/null
++++ b/drivers/serial/ast1070_dma_uart.c
+@@ -0,0 +1,1511 @@
++/********************************************************************************
++* File Name : ast1070_dma_uart.c
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++********************************************************************************/
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/ioport.h>
++#include <linux/init.h>
++#include <linux/console.h>
++#include <linux/delay.h>
++#include <linux/platform_device.h>
++#include <linux/tty.h>
++#include <linux/tty_flip.h>
++#include <linux/serial_reg.h>
++#include <linux/serial_core.h>
++#include <linux/serial.h>
++#include <linux/serial_8250.h>
++#include <linux/nmi.h>
++#include <linux/mutex.h>
++
++#include <asm/io.h>
++#include <asm/irq.h>
++
++#include "8250.h"
++#include <linux/dma-mapping.h>
++#include <linux/miscdevice.h>
++#include <plat/regs-uart-dma.h>
++#include <mach/ast-uart-dma.h>
++
++//#define CONFIG_UART_DMA_DEBUG
++
++#ifdef CONFIG_UART_DMA_DEBUG
++ #define DBG(fmt, args...) printk("%s() " fmt, __FUNCTION__, ## args)
++#else
++ #define DBG(fmt, args...)
++#endif
++
++/*
++ * Configuration:
++ * share_irqs - whether we pass IRQF_SHARED to request_irq(). This option
++ * is unsafe when used on edge-triggered interrupts.
++ */
++static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
++
++static unsigned int nr_uarts = CONFIG_AST_RUNTIME_DMA_UARTS;
++
++/*
++ * Debugging.
++ */
++#if 0
++#define DEBUG_AUTOCONF(fmt...) printk(fmt)
++#else
++#define DEBUG_AUTOCONF(fmt...) do { } while (0)
++#endif
++
++#if 0
++#define DEBUG_INTR(fmt...) printk(fmt)
++#else
++#define DEBUG_INTR(fmt...) do { } while (0)
++#endif
++
++#define PASS_LIMIT 256
++
++#include <asm/serial.h>
++
++
++#define UART_DMA_NR CONFIG_AST_NR_DMA_UARTS
++
++struct ast_uart_port {
++ struct uart_port port;
++ unsigned short capabilities; /* port capabilities */
++ unsigned short bugs; /* port bugs */
++ unsigned int tx_loadsz; /* transmit fifo load size */
++ unsigned char acr;
++ unsigned char ier;
++ unsigned char lcr;
++ unsigned char mcr;
++ unsigned char mcr_mask; /* mask of user bits */
++ unsigned char mcr_force; /* mask of forced bits */
++ struct circ_buf rx_dma_buf;
++ struct circ_buf tx_dma_buf;
++ dma_addr_t dma_rx_addr; /* Mapped ADMA descr. table */
++ dma_addr_t dma_tx_addr; /* Mapped ADMA descr. table */
++ unsigned int dma_buf_size; //total allocation dma size ..
++ struct tasklet_struct rx_tasklet;
++ int rx_tasklet_done;
++ struct tasklet_struct tx_tasklet;
++ spinlock_t lock;
++ int tx_done;
++ int tx_count;
++ /*
++ * Some bits in registers are cleared on a read, so they must
++ * be saved whenever the register is read but the bits will not
++ * be immediately processed.
++ */
++#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS
++ unsigned char lsr_saved_flags;
++#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
++ unsigned char msr_saved_flags;
++
++ /*
++ * We provide a per-port pm hook.
++ */
++ void (*pm)(struct uart_port *port,
++ unsigned int state, unsigned int old);
++};
++
++static struct ast_uart_port ast_uart_ports[UART_DMA_NR];
++
++static inline struct ast_uart_port *
++to_ast_dma_uart_port(struct uart_port *uart)
++{
++ return container_of(uart, struct ast_uart_port, port);
++}
++
++struct irq_info {
++ spinlock_t lock;
++ struct ast_uart_port *up;
++};
++
++static struct irq_info ast_uart_irq[1];
++static DEFINE_MUTEX(ast_uart_mutex);
++
++/*
++ * Here we define the default xmit fifo size used for each type of UART.
++ */
++static const struct serial8250_config uart_config[] = {
++ [PORT_UNKNOWN] = {
++ .name = "unknown",
++ .fifo_size = 1,
++ .tx_loadsz = 1,
++ },
++ [PORT_8250] = {
++ .name = "8250",
++ .fifo_size = 1,
++ .tx_loadsz = 1,
++ },
++ [PORT_16450] = {
++ .name = "16450",
++ .fifo_size = 1,
++ .tx_loadsz = 1,
++ },
++ [PORT_16550] = {
++ .name = "16550",
++ .fifo_size = 1,
++ .tx_loadsz = 1,
++ },
++ [PORT_16550A] = {
++ .name = "16550A",
++ .fifo_size = 16,
++ .tx_loadsz = 16,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 | UART_FCR_DMA_SELECT,
++ .flags = UART_CAP_FIFO,
++ },
++};
++
++/* sane hardware needs no mapping */
++#define map_8250_in_reg(up, offset) (offset)
++#define map_8250_out_reg(up, offset) (offset)
++
++void ast_uart_unregister_port(int line);
++int ast_uart_register_port(struct uart_port *port);
++
++static unsigned int serial_in(struct ast_uart_port *up, int offset)
++{
++ offset = map_8250_in_reg(up, offset) << up->port.regshift;
++
++ return readb(up->port.membase + offset);
++}
++
++static void
++serial_out(struct ast_uart_port *up, int offset, int value)
++{
++ /* Save the offset before it's remapped */
++ offset = map_8250_out_reg(up, offset) << up->port.regshift;
++
++ writeb(value, up->port.membase + offset);
++}
++
++
++/*
++ * We used to support using pause I/O for certain machines. We
++ * haven't supported this for a while, but just in case it's badly
++ * needed for certain old 386 machines, I've left these #define's
++ * in....
++ */
++#define serial_inp(up, offset) serial_in(up, offset)
++#define serial_outp(up, offset, value) serial_out(up, offset, value)
++
++/* Uart divisor latch read */
++static inline int _serial_dl_read(struct ast_uart_port *up)
++{
++ return serial_inp(up, UART_DLL) | serial_inp(up, UART_DLM) << 8;
++}
++
++/* Uart divisor latch write */
++static inline void _serial_dl_write(struct ast_uart_port *up, int value)
++{
++ serial_outp(up, UART_DLL, value & 0xff);
++ serial_outp(up, UART_DLM, value >> 8 & 0xff);
++}
++
++#define serial_dl_read(up) _serial_dl_read(up)
++#define serial_dl_write(up, value) _serial_dl_write(up, value)
++
++static void ast_uart_tx_tasklet_func(unsigned long data)
++{
++ struct ast_uart_port *up = to_ast_dma_uart_port((struct uart_port *)data);
++ struct circ_buf *xmit = &up->port.info->xmit;
++ struct ast_uart_dma_data *uart_dma_data = up->port.private_data;
++
++ up->tx_done = 0;
++ DBG("line [%d], xmit->head =%d, xmit->tail = %d\n",up->port.line,xmit->head, xmit->tail);
++
++ if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
++ up->tx_count = 0;
++ up->tx_done = 1;
++ return;
++ }
++
++ if (up->port.x_char) {
++ serial_outp(up, UART_TX, up->port.x_char);
++ up->port.icount.tx++;
++ up->port.x_char = 0;
++ return;
++ }
++
++ up->tx_count = CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE);
++
++ if (up->tx_count > (UART_XMIT_SIZE - xmit->tail)) {
++ up->tx_count = UART_XMIT_SIZE - xmit->tail;
++ }
++
++ if (up->tx_count > 4095) {
++ printk("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! TODO ....\n");
++ up->tx_count = 4095;
++ }
++
++ ast_uart_tx_dma_ctrl(uart_dma_data->chip_no,
++ uart_dma_data->dma_ch, AST_UART_DMAOP_STOP);
++
++ ast_uart_tx_dma_enqueue(uart_dma_data->chip_no,
++ uart_dma_data->dma_ch, up->dma_tx_addr, up->tx_count);
++
++ dma_sync_single_for_device(up->port.dev,
++ up->dma_tx_addr,
++ up->tx_count,
++ DMA_TO_DEVICE);
++
++ ast_uart_tx_dma_ctrl(uart_dma_data->chip_no,
++ uart_dma_data->dma_ch, AST_UART_DMAOP_TRIGGER);
++
++
++}
++
++static void ast_uart_tx_buffdone(struct ast1070_dma_ch *dma_ch, void *dev_id, u16 len)
++{
++ struct ast_uart_port *up = (struct ast_uart_port *) dev_id;
++ struct circ_buf *xmit = &up->port.info->xmit;
++
++ DBG("line [%d] : tx len = %d \n", up->port.line, len);
++
++ spin_lock(&up->port.lock);
++//TODO .....................................len ---->
++ xmit->tail = (xmit->tail + up->tx_count) & (UART_XMIT_SIZE - 1);
++ up->port.icount.tx += up->tx_count;
++
++ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
++ uart_write_wakeup(&up->port);
++
++ tasklet_schedule(&up->tx_tasklet);
++
++ spin_unlock(&up->port.lock);
++}
++
++static void ast_uart_rx_tasklet_func(unsigned long data)
++{
++ struct ast_uart_port *up = to_ast_dma_uart_port((struct uart_port *)data);
++ struct circ_buf *rx_ring = &up->rx_dma_buf;
++ struct tty_struct *tty = up->port.info->port.tty;
++ char flag;
++ DBG("line [%d]\n",up->port.line);
++ DBG("rx_ring->head = %d, rx_ring->tail = %d , buff addr = %x \n",rx_ring->head, rx_ring->tail, rx_ring->buf);
++
++ spin_lock_irq(&up->lock);
++#if 1
++ DBG("\n rx data : -- >");
++
++ while (rx_ring->head != rx_ring->tail) {
++ DBG(" %x ",rx_ring->buf[rx_ring->tail]);
++ flag = TTY_NORMAL;
++ uart_insert_char(&up->port, 0, UART_LSR_OE, \
++ rx_ring->buf[rx_ring->tail], flag);
++
++// tty_insert_flip_string
++
++ rx_ring->tail++;
++ if (rx_ring->tail == up->dma_buf_size)
++ rx_ring->tail = 0;
++ }
++ DBG("\n");
++#else
++
++ tty_insert_flip_string(tty, rx_ring->buf + rx_ring->tail, (rx_ring->head - rx_ring->tail));
++ rx_ring->tail = rx_ring->head;
++#endif
++ spin_unlock_irq(&up->lock);
++
++ spin_unlock(&up->port.lock);
++ tty_flip_buffer_push(tty);
++ spin_lock(&up->port.lock);
++
++
++}
++
++static void ast_uart_rx_buffdone(struct ast1070_dma_ch *dma_ch,
++ void *dev_id, u16 len)
++{
++ struct ast_uart_port *up = (struct ast_uart_port *)dev_id;
++// struct tty_struct *tty = up->port.info->port.tty;
++ struct circ_buf *rx_ring = &up->rx_dma_buf;
++ struct ast_uart_dma_data *uart_dma_data = up->port.private_data;
++ u16 remain_size;
++
++ DBG("line [%d]\n",up->port.line);
++#if 0
++ int i;
++ printk("Buff virt addr = %x \n",rx_ring->buf);
++ for(i=0;i<len;i++)
++ printk("Buff [%x] \n", rx_ring->buf[up->rx_dma_buf.head + i]);
++#endif
++ DBG("head = %d, len : %d\n",up->rx_dma_buf.head, len);
++
++
++ //FOR NEXT ......
++ rx_ring->head += len;
++
++ if (rx_ring->head == up->dma_buf_size) {
++ rx_ring->head = 0;
++ }
++
++ remain_size = up->dma_buf_size - rx_ring->head;
++
++ //Trigger Next RX dma
++ DBG("trigger next size = %d \n",remain_size);
++
++ ast_uart_rx_dma_ctrl(uart_dma_data->chip_no,
++ uart_dma_data->dma_ch, AST_UART_DMAOP_STOP);
++
++ if(remain_size > DMA_BUFF_SIZE)
++ printk("Please check ---> \n");
++
++ if(remain_size != 0) {
++ ast_uart_rx_dma_enqueue(uart_dma_data->chip_no,
++ uart_dma_data->dma_ch, up->dma_rx_addr + up->rx_dma_buf.head, remain_size);
++ }
++ ast_uart_rx_dma_ctrl(uart_dma_data->chip_no,
++ uart_dma_data->dma_ch, AST_UART_DMAOP_TRIGGER);
++
++ tasklet_schedule(&up->rx_tasklet);
++
++}
++
++/*
++ * FIFO support.
++ */
++static inline void serial8250_clear_fifos(struct ast_uart_port *p)
++{
++ serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO);
++ serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO |
++ UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
++ serial_outp(p, UART_FCR, 0);
++}
++
++
++/*
++ * This routine is called by rs_init() to initialize a specific serial
++ * port.
++ */
++static void autoconfig(struct ast_uart_port *up, unsigned int probeflags)
++{
++ unsigned long flags;
++
++ if (!up->port.iobase && !up->port.mapbase && !up->port.membase)
++ return;
++
++ DEBUG_AUTOCONF("ttyDMA%d: autoconf (0x%04x, 0x%p): ",
++ up->port.line, up->port.iobase, up->port.membase);
++
++ spin_lock_irqsave(&up->port.lock, flags);
++
++ up->capabilities = 0;
++ up->bugs = 0;
++
++ up->port.type = PORT_16550A;
++ up->capabilities |= UART_CAP_FIFO;
++
++ up->port.fifosize = uart_config[up->port.type].fifo_size;
++ up->capabilities = uart_config[up->port.type].flags;
++ up->tx_loadsz = uart_config[up->port.type].tx_loadsz;
++
++ if (up->port.type == PORT_UNKNOWN)
++ goto out;
++
++ /*
++ * Reset the UART.
++ */
++ serial8250_clear_fifos(up);
++ serial_in(up, UART_RX);
++ serial_outp(up, UART_IER, 0);
++
++ out:
++ spin_unlock_irqrestore(&up->port.lock, flags);
++ DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name);
++}
++
++
++static inline void __stop_tx(struct ast_uart_port *p)
++{
++ if (p->ier & UART_IER_THRI) {
++ p->ier &= ~UART_IER_THRI;
++ serial_out(p, UART_IER, p->ier);
++ }
++}
++
++static void serial8250_stop_tx(struct uart_port *port)
++{
++ struct ast_uart_port *up = to_ast_dma_uart_port(port);
++
++ __stop_tx(up);
++
++}
++
++static void transmit_chars(struct ast_uart_port *up);
++
++static void serial8250_start_tx(struct uart_port *port)
++{
++ struct ast_uart_port *up = to_ast_dma_uart_port(port);
++
++ DBG("line [%d] --> \n", port->line);
++ if (up->tx_done)
++ tasklet_schedule(&up->tx_tasklet);
++}
++
++static void serial8250_stop_rx(struct uart_port *port)
++{
++ struct ast_uart_port *up = to_ast_dma_uart_port(port);
++
++ DBG("line [%d] --> \n", port->line);
++ up->ier &= ~UART_IER_RLSI;
++ up->port.read_status_mask &= ~UART_LSR_DR;
++ serial_out(up, UART_IER, up->ier);
++}
++
++static void serial8250_enable_ms(struct uart_port *port)
++{
++ struct ast_uart_port *up = to_ast_dma_uart_port(port);
++
++ up->ier |= UART_IER_MSI;
++ serial_out(up, UART_IER, up->ier);
++}
++
++static void transmit_chars(struct ast_uart_port *up)
++{
++ struct circ_buf *xmit = &up->port.info->xmit;
++ int count;
++
++ if (up->port.x_char) {
++ serial_outp(up, UART_TX, up->port.x_char);
++ up->port.icount.tx++;
++ up->port.x_char = 0;
++ return;
++ }
++ if (uart_tx_stopped(&up->port)) {
++ serial8250_stop_tx(&up->port);
++ return;
++ }
++ if (uart_circ_empty(xmit)) {
++ __stop_tx(up);
++ return;
++ }
++
++// printk("uart_circ_chars_pending=%d\n",uart_circ_chars_pending(xmit));
++
++ count = up->tx_loadsz;
++ do {
++//printk("TX : buf = 0x%x\n", xmit->buf[xmit->tail]);
++ serial_out(up, UART_TX, xmit->buf[xmit->tail]);
++ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
++ up->port.icount.tx++;
++ if (uart_circ_empty(xmit))
++ break;
++ } while (--count > 0);
++
++ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
++ uart_write_wakeup(&up->port);
++
++ DEBUG_INTR("THRE...");
++
++ if (uart_circ_empty(xmit))
++ __stop_tx(up);
++}
++
++static unsigned int check_modem_status(struct ast_uart_port *up)
++{
++ unsigned int status = serial_in(up, UART_MSR);
++
++ status |= up->msr_saved_flags;
++ up->msr_saved_flags = 0;
++ if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI &&
++ up->port.info != NULL) {
++ if (status & UART_MSR_TERI)
++ up->port.icount.rng++;
++ if (status & UART_MSR_DDSR)
++ up->port.icount.dsr++;
++ if (status & UART_MSR_DDCD)
++ uart_handle_dcd_change(&up->port, status & UART_MSR_DCD);
++ if (status & UART_MSR_DCTS)
++ uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
++
++ wake_up_interruptible(&up->port.info->delta_msr_wait);
++ }
++
++ return status;
++}
++
++/*
++ * This handles the interrupt from one port.
++ */
++static inline void
++serial8250_handle_port(struct ast_uart_port *up)
++{
++ unsigned int status;
++ unsigned long flags;
++
++ spin_lock_irqsave(&up->port.lock, flags);
++ DEBUG_INTR("serial8250_handle_port \n");
++
++ status = serial_inp(up, UART_LSR);
++
++ DEBUG_INTR("status = %x...", status);
++
++ check_modem_status(up);
++ if (status & UART_LSR_THRE)
++ transmit_chars(up);
++
++ spin_unlock_irqrestore(&up->port.lock, flags);
++}
++
++/*
++ * This is the serial driver's interrupt routine.
++ */
++static irqreturn_t ast_uart_interrupt(int irq, void *dev_id)
++{
++ struct irq_info *i = dev_id;
++ int pass_counter = 0, handled = 0, end = 0;
++
++ DEBUG_INTR("ast_uart_interrupt(%d)...", irq);
++ spin_lock(&i->lock);
++
++ do {
++ struct ast_uart_port *up;
++ unsigned int iir;
++
++ up = (struct ast_uart_port *)(i->up);
++
++ iir = serial_in(up, UART_IIR);
++ DEBUG_INTR("iir %x \n", iir);
++ if (!(iir & UART_IIR_NO_INT)) {
++ printk("handle port \n");
++ serial8250_handle_port(up);
++ handled = 1;
++
++ }
++ else
++ end = 1;
++
++ if (pass_counter++ > PASS_LIMIT) {
++ /* If we hit this, we're dead. */
++ printk(KERN_ERR "ast-uart-dma: too much work for "
++ "irq%d\n", irq);
++ break;
++ }
++ } while (end);
++
++ spin_unlock(&i->lock);
++
++ DEBUG_INTR("end.\n");
++
++ return IRQ_RETVAL(handled);
++}
++
++static unsigned int serial8250_tx_empty(struct uart_port *port)
++{
++ struct ast_uart_port *up = to_ast_dma_uart_port(port);
++ unsigned long flags;
++ unsigned int lsr;
++
++ spin_lock_irqsave(&up->port.lock, flags);
++ lsr = serial_in(up, UART_LSR);
++ up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
++ spin_unlock_irqrestore(&up->port.lock, flags);
++
++ return lsr & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
++}
++
++static unsigned int serial8250_get_mctrl(struct uart_port *port)
++{
++ struct ast_uart_port *up = to_ast_dma_uart_port(port);
++ unsigned int status;
++ unsigned int ret;
++
++ status = check_modem_status(up);
++
++ ret = 0;
++ if (status & UART_MSR_DCD)
++ ret |= TIOCM_CAR;
++ if (status & UART_MSR_RI)
++ ret |= TIOCM_RNG;
++ if (status & UART_MSR_DSR)
++ ret |= TIOCM_DSR;
++ if (status & UART_MSR_CTS)
++ ret |= TIOCM_CTS;
++ return ret;
++}
++
++static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
++{
++ struct ast_uart_port *up = to_ast_dma_uart_port(port);
++ unsigned char mcr = 0;
++
++ if (mctrl & TIOCM_RTS)
++ mcr |= UART_MCR_RTS;
++ if (mctrl & TIOCM_DTR)
++ mcr |= UART_MCR_DTR;
++ if (mctrl & TIOCM_OUT1)
++ mcr |= UART_MCR_OUT1;
++ if (mctrl & TIOCM_OUT2)
++ mcr |= UART_MCR_OUT2;
++ if (mctrl & TIOCM_LOOP)
++ mcr |= UART_MCR_LOOP;
++
++ mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr;
++
++ serial_out(up, UART_MCR, mcr);
++}
++
++static void serial8250_break_ctl(struct uart_port *port, int break_state)
++{
++ struct ast_uart_port *up = to_ast_dma_uart_port(port);
++ unsigned long flags;
++
++ spin_lock_irqsave(&up->port.lock, flags);
++ if (break_state == -1)
++ up->lcr |= UART_LCR_SBC;
++ else
++ up->lcr &= ~UART_LCR_SBC;
++ serial_out(up, UART_LCR, up->lcr);
++ spin_unlock_irqrestore(&up->port.lock, flags);
++}
++
++static int serial8250_startup(struct uart_port *port)
++{
++ struct ast_uart_port *up = to_ast_dma_uart_port(port);
++ //TX DMA
++ struct circ_buf *xmit = &port->info->xmit;
++ struct ast_uart_dma_data *uart_dma_data = up->port.private_data;
++ unsigned long flags;
++ unsigned char lsr, iir;
++ int retval;
++ int irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0;
++
++ DBG("line [%d] \n",port->line);
++
++ up->capabilities = uart_config[up->port.type].flags;
++ up->mcr = 0;
++
++ /*
++ * Clear the FIFO buffers and disable them.
++ * (they will be reenabled in set_termios())
++ */
++ serial8250_clear_fifos(up);
++
++ /*
++ * Clear the interrupt registers.
++ */
++ (void) serial_inp(up, UART_LSR);
++ (void) serial_inp(up, UART_RX);
++ (void) serial_inp(up, UART_IIR);
++ (void) serial_inp(up, UART_MSR);
++
++ ast_uart_irq[0].up = up;
++ retval = request_irq(up->port.irq, ast_uart_interrupt,
++ irq_flags, "ast-uart-dma", ast_uart_irq);
++ if (retval)
++ return retval;
++
++ /*
++ * Now, initialize the UART
++ */
++ serial_outp(up, UART_LCR, UART_LCR_WLEN8);
++
++ spin_lock_irqsave(&up->port.lock, flags);
++ up->port.mctrl |= TIOCM_OUT2;
++
++ serial8250_set_mctrl(&up->port, up->port.mctrl);
++
++ /*
++ * Do a quick test to see if we receive an
++ * interrupt when we enable the TX irq.
++ */
++ serial_outp(up, UART_IER, UART_IER_THRI);
++ lsr = serial_in(up, UART_LSR);
++ iir = serial_in(up, UART_IIR);
++ serial_outp(up, UART_IER, 0);
++
++ if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) {
++ if (!(up->bugs & UART_BUG_TXEN)) {
++ up->bugs |= UART_BUG_TXEN;
++ printk("ttyDMA%d - enabling bad tx status \n",
++ port->line);
++ }
++ } else {
++ up->bugs &= ~UART_BUG_TXEN;
++ }
++
++ spin_unlock_irqrestore(&up->port.lock, flags);
++
++ /*
++ * Clear the interrupt registers again for luck, and clear the
++ * saved flags to avoid getting false values from polling
++ * routines or the previous session.
++ */
++ serial_inp(up, UART_LSR);
++ serial_inp(up, UART_RX);
++ serial_inp(up, UART_IIR);
++ serial_inp(up, UART_MSR);
++ up->lsr_saved_flags = 0;
++ up->msr_saved_flags = 0;
++
++ //RX DMA
++ up->rx_dma_buf.head = 0;
++ up->rx_dma_buf.tail = 0;
++ up->dma_buf_size = 2048;//DMA_BUFF_SIZE -1; //4096 is dma size please check
++#if 0
++ up->dma_rx_addr = dma_map_single(port->dev,
++ up->rx_dma_buf.buf,
++ up->dma_buf_size,
++ DMA_FROM_DEVICE);
++#else
++ up->rx_dma_buf.buf = (unsigned char *)dma_alloc_coherent(NULL,
++ up->dma_buf_size, &up->dma_rx_addr, GFP_KERNEL);
++#endif
++ DBG("RX buff vir = %x, phy = %x \n", up->rx_dma_buf.buf, up->dma_rx_addr);
++
++ ast_uart_rx_dma_ctrl(uart_dma_data->chip_no, uart_dma_data->dma_ch, AST_UART_DMAOP_STOP);
++
++ ast_uart_rx_dma_enqueue(uart_dma_data->chip_no, uart_dma_data->dma_ch, up->dma_rx_addr, up->dma_buf_size);
++
++ up->rx_tasklet_done = 1;
++ ast_uart_rx_dma_ctrl(uart_dma_data->chip_no, uart_dma_data->dma_ch, AST_UART_DMAOP_TRIGGER);
++
++ up->tx_dma_buf.head = 0;
++ up->tx_dma_buf.buf = xmit->buf;
++ up->dma_tx_addr = dma_map_single(port->dev,
++ up->tx_dma_buf.buf,
++ UART_XMIT_SIZE,
++ DMA_TO_DEVICE);
++ up->tx_done = 1;
++ up->tx_count = 0;
++
++ return 0;
++}
++
++static void serial8250_shutdown(struct uart_port *port)
++{
++ struct ast_uart_port *up = to_ast_dma_uart_port(port);
++ struct ast_uart_dma_data *uart_dma_data = up->port.private_data;
++ unsigned long flags;
++ //int i;
++ DBG("line [%d]\n",port->line);
++ /*
++ * Disable interrupts from this port
++ */
++#if 0
++ for(i=0; i<100; i++) {
++ printk("tx_count_table[%d] = %d\n", i, tx_count_table[i]);
++ }
++#endif
++
++ up->ier = 0;
++ serial_outp(up, UART_IER, 0);
++
++ spin_lock_irqsave(&up->port.lock, flags);
++ up->port.mctrl &= ~TIOCM_OUT2;
++
++ serial8250_set_mctrl(&up->port, up->port.mctrl);
++ spin_unlock_irqrestore(&up->port.lock, flags);
++
++ /*
++ * Disable break condition and FIFOs
++ */
++ serial_out(up, UART_LCR, serial_inp(up, UART_LCR) & ~UART_LCR_SBC);
++ serial8250_clear_fifos(up);
++
++ (void) serial_in(up, UART_RX);
++
++ ast_uart_rx_dma_ctrl(uart_dma_data->chip_no, uart_dma_data->dma_ch, AST_UART_DMAOP_STOP);
++
++ ast_uart_tx_dma_ctrl(uart_dma_data->chip_no, uart_dma_data->dma_ch, AST_UART_DMAOP_STOP);
++ //TODO .... Free ---- dma
++ DBG("free TX , RX buffer \n");
++#if 1
++ dma_unmap_single(port->dev, up->dma_rx_addr,
++ up->dma_buf_size,
++ DMA_FROM_DEVICE);
++#else
++ dma_free_coherent(port->dev, up->dma_buf_size,
++ up->rx_dma_buf.buf, up->dma_rx_addr);
++#endif
++
++ dma_unmap_single(port->dev, up->dma_tx_addr,
++ UART_XMIT_SIZE,
++ DMA_TO_DEVICE);
++
++
++ free_irq(up->port.irq, ast_uart_irq);
++
++}
++
++static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud)
++{
++ unsigned int quot;
++
++ quot = uart_get_divisor(port, baud);
++
++ return quot;
++}
++
++static void
++serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
++ struct ktermios *old)
++{
++ struct ast_uart_port *up = to_ast_dma_uart_port(port);
++ unsigned char cval, fcr = 0;
++ unsigned long flags;
++ unsigned int baud, quot;
++
++ switch (termios->c_cflag & CSIZE) {
++ case CS5:
++ cval = UART_LCR_WLEN5;
++ break;
++ case CS6:
++ cval = UART_LCR_WLEN6;
++ break;
++ case CS7:
++ cval = UART_LCR_WLEN7;
++ break;
++ default:
++ case CS8:
++ cval = UART_LCR_WLEN8;
++ break;
++ }
++
++ if (termios->c_cflag & CSTOPB)
++ cval |= UART_LCR_STOP;
++ if (termios->c_cflag & PARENB)
++ cval |= UART_LCR_PARITY;
++ if (!(termios->c_cflag & PARODD))
++ cval |= UART_LCR_EPAR;
++#ifdef CMSPAR
++ if (termios->c_cflag & CMSPAR)
++ cval |= UART_LCR_SPAR;
++#endif
++
++ /*
++ * Ask the core to calculate the divisor for us.
++ */
++ baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
++ quot = serial8250_get_divisor(port, baud);
++
++ if (up->capabilities & UART_CAP_FIFO && up->port.fifosize > 1) {
++ if (baud < 2400)
++ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
++ else
++ fcr = uart_config[up->port.type].fcr;
++ }
++
++ /*
++ * Ok, we're now changing the port state. Do it with
++ * interrupts disabled.
++ */
++ spin_lock_irqsave(&up->port.lock, flags);
++
++ /*
++ * Update the per-port timeout.
++ */
++ uart_update_timeout(port, termios->c_cflag, baud);
++
++ up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
++ if (termios->c_iflag & INPCK)
++ up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;
++ if (termios->c_iflag & (BRKINT | PARMRK))
++ up->port.read_status_mask |= UART_LSR_BI;
++
++ /*
++ * Characteres to ignore
++ */
++ up->port.ignore_status_mask = 0;
++ if (termios->c_iflag & IGNPAR)
++ up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
++ if (termios->c_iflag & IGNBRK) {
++ up->port.ignore_status_mask |= UART_LSR_BI;
++ /*
++ * If we're ignoring parity and break indicators,
++ * ignore overruns too (for real raw support).
++ */
++ if (termios->c_iflag & IGNPAR)
++ up->port.ignore_status_mask |= UART_LSR_OE;
++ }
++
++ /*
++ * ignore all characters if CREAD is not set
++ */
++ if ((termios->c_cflag & CREAD) == 0)
++ up->port.ignore_status_mask |= UART_LSR_DR;
++
++ /*
++ * CTS flow control flag and modem status interrupts
++ */
++ up->ier &= ~UART_IER_MSI;
++ if (UART_ENABLE_MS(&up->port, termios->c_cflag))
++ up->ier |= UART_IER_MSI;
++
++ serial_out(up, UART_IER, up->ier);
++
++
++ serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
++
++ serial_dl_write(up, quot);
++
++ /*
++ * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
++ * is written without DLAB set, this mode will be disabled.
++ */
++
++ serial_outp(up, UART_LCR, cval); /* reset DLAB */
++ up->lcr = cval; /* Save LCR */
++ if (fcr & UART_FCR_ENABLE_FIFO) {
++ /* emulated UARTs (Lucent Venus 167x) need two steps */
++ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
++ }
++ serial_outp(up, UART_FCR, fcr); /* set fcr */
++ serial8250_set_mctrl(&up->port, up->port.mctrl);
++ spin_unlock_irqrestore(&up->port.lock, flags);
++ /* Don't rewrite B0 */
++ if (tty_termios_baud_rate(termios))
++ tty_termios_encode_baud_rate(termios, baud, baud);
++}
++
++static void
++serial8250_pm(struct uart_port *port, unsigned int state,
++ unsigned int oldstate)
++{
++ struct ast_uart_port *p = (struct ast_uart_port *)port;
++
++ if (p->pm)
++ p->pm(port, state, oldstate);
++}
++
++/*
++ * Resource handling.
++ */
++static int serial8250_request_std_resource(struct ast_uart_port *up)
++{
++ unsigned int size = 8 << up->port.regshift;
++ int ret = 0;
++
++ if (!up->port.mapbase)
++ return ret;
++
++ if (!request_mem_region(up->port.mapbase, size, "ast-uart-dma")) {
++ ret = -EBUSY;
++ return ret;
++ }
++
++ if (up->port.flags & UPF_IOREMAP) {
++ up->port.membase = ioremap_nocache(up->port.mapbase,
++ size);
++ if (!up->port.membase) {
++ release_mem_region(up->port.mapbase, size);
++ ret = -ENOMEM;
++ return ret;
++ }
++ }
++ return ret;
++}
++
++static void serial8250_release_std_resource(struct ast_uart_port *up)
++{
++ unsigned int size = 8 << up->port.regshift;
++
++ if (!up->port.mapbase)
++ return;
++
++ if (up->port.flags & UPF_IOREMAP) {
++ iounmap(up->port.membase);
++ up->port.membase = NULL;
++ }
++
++ release_mem_region(up->port.mapbase, size);
++}
++
++
++static void serial8250_release_port(struct uart_port *port)
++{
++ struct ast_uart_port *up = (struct ast_uart_port *)port;
++
++ serial8250_release_std_resource(up);
++}
++
++static int serial8250_request_port(struct uart_port *port)
++{
++ struct ast_uart_port *up = (struct ast_uart_port *)port;
++ int ret = 0;
++
++ ret = serial8250_request_std_resource(up);
++ if (ret == 0 )
++ serial8250_release_std_resource(up);
++
++ return ret;
++}
++
++static void serial8250_config_port(struct uart_port *port, int flags)
++{
++ struct ast_uart_port *up = (struct ast_uart_port *)port;
++ int probeflags = PROBE_ANY;
++ int ret;
++
++ /*
++ * Find the region that we can probe for. This in turn
++ * tells us whether we can probe for the type of port.
++ */
++ ret = serial8250_request_std_resource(up);
++ if (ret < 0)
++ return;
++
++ if (flags & UART_CONFIG_TYPE)
++ autoconfig(up, probeflags);
++
++ if (up->port.type == PORT_UNKNOWN)
++ serial8250_release_std_resource(up);
++}
++
++static int
++serial8250_verify_port(struct uart_port *port, struct serial_struct *ser)
++{
++ return 0;
++}
++
++static const char *
++serial8250_type(struct uart_port *port)
++{
++ int type = port->type;
++
++ if (type >= ARRAY_SIZE(uart_config))
++ type = 0;
++ return uart_config[type].name;
++}
++
++static struct uart_ops serial8250_pops = {
++ .tx_empty = serial8250_tx_empty,
++ .set_mctrl = serial8250_set_mctrl,
++ .get_mctrl = serial8250_get_mctrl,
++ .stop_tx = serial8250_stop_tx,
++ .start_tx = serial8250_start_tx,
++ .stop_rx = serial8250_stop_rx,
++ .enable_ms = serial8250_enable_ms,
++ .break_ctl = serial8250_break_ctl,
++ .startup = serial8250_startup,
++ .shutdown = serial8250_shutdown,
++ .set_termios = serial8250_set_termios,
++ .pm = serial8250_pm,
++ .type = serial8250_type,
++ .release_port = serial8250_release_port,
++ .request_port = serial8250_request_port,
++ .config_port = serial8250_config_port,
++ .verify_port = serial8250_verify_port,
++};
++
++static void __init serial8250_isa_init_ports(void)
++{
++ static int first = 1;
++ int i;
++
++ if (!first)
++ return;
++ first = 0;
++
++ for (i = 0; i < nr_uarts; i++) {
++ struct ast_uart_port *up = &ast_uart_ports[i];
++
++ up->port.line = i;
++ spin_lock_init(&up->port.lock);
++
++ /*
++ * ALPHA_KLUDGE_MCR needs to be killed.
++ */
++ up->mcr_mask = ~ALPHA_KLUDGE_MCR;
++ up->mcr_force = ALPHA_KLUDGE_MCR;
++
++ up->port.ops = &serial8250_pops;
++ }
++
++}
++
++static void __init
++serial8250_register_ports(struct uart_driver *drv, struct device *dev)
++{
++ int i;
++ printk("serial8250_register_ports \n");
++
++ serial8250_isa_init_ports();
++
++ for (i = 0; i < nr_uarts; i++) {
++ struct ast_uart_port *up = &ast_uart_ports[i];
++ up->port.dev = dev;
++ uart_add_one_port(drv, &up->port);
++ }
++}
++
++#define SERIAL8250_CONSOLE NULL
++
++static struct uart_driver serial8250_reg = {
++ .owner = THIS_MODULE,
++ .driver_name = "ast-uart-dma",
++ .dev_name = "ttyDMA",
++#if 0
++ .major = TTY_MAJOR,
++ .minor = 64,
++#else
++ .major = 204, // like atmel_serial
++ .minor = 155,
++#endif
++ .nr = UART_DMA_NR,
++ .cons = SERIAL8250_CONSOLE,
++};
++
++
++#if 0
++/**
++ * serial8250_suspend_port - suspend one serial port
++ * @line: serial line number
++ *
++ * Suspend one serial port.
++ */
++void serial8250_suspend_port(int line)
++{
++ uart_suspend_port(&serial8250_reg, &ast_uart_ports[line].port);
++}
++
++/**
++ * serial8250_resume_port - resume one serial port
++ * @line: serial line number
++ *
++ * Resume one serial port.
++ */
++void serial8250_resume_port(int line)
++{
++ struct ast_uart_port *up = &ast_uart_ports[line];
++
++ uart_resume_port(&serial8250_reg, &up->port);
++}
++#endif
++
++/*
++ * Register a set of serial devices attached to a platform device. The
++ * list is terminated with a zero flags entry, which means we expect
++ * all entries to have at least UPF_BOOT_AUTOCONF set.
++ */
++static int __devinit serial8250_probe(struct platform_device *dev)
++{
++ struct plat_serial8250_port *p = dev->dev.platform_data;
++ struct uart_port port;
++ struct ast_uart_dma_data *uart_dma_data;
++ int ret, i;
++
++ if(UART_XMIT_SIZE > DMA_BUFF_SIZE)
++ printk("UART_XMIT_SIZE > DMA_BUFF_SIZE : Please Check \n");
++
++ memset(&port, 0, sizeof(struct uart_port));
++
++ for (i = 0; p && p->flags != 0; p++, i++) {
++ port.iobase = p->iobase;
++ port.membase = p->membase;
++ port.irq = p->irq;
++ port.uartclk = p->uartclk;
++ port.regshift = p->regshift;
++ port.iotype = p->iotype;
++ port.flags = p->flags;
++ port.mapbase = p->mapbase;
++ port.hub6 = p->hub6;
++ port.private_data = p->private_data;
++ port.dev = &dev->dev;
++ uart_dma_data = p->private_data;
++ if (share_irqs)
++ port.flags |= UPF_SHARE_IRQ;
++ ret = ast_uart_register_port(&port);
++ if (ret < 0) {
++ dev_err(&dev->dev, "unable to register port at index %d "
++ "(IO%lx MEM%llx IRQ%d): %d\n", i,
++ p->iobase, (unsigned long long)p->mapbase,
++ p->irq, ret);
++ }
++// printk("TODO ...... line = %d \n",i);
++ ret = ast_uart_rx_dma_request(uart_dma_data->chip_no, uart_dma_data->dma_ch, ast_uart_rx_buffdone, &ast_uart_ports[i]);
++ if (ret < 0) {
++ printk("Error : failed to get rx dma channel[%d]\n", uart_dma_data->dma_ch);
++ goto out_ast_uart_unregister_port;
++ }
++
++ ret = ast_uart_tx_dma_request(uart_dma_data->chip_no, uart_dma_data->dma_ch, ast_uart_tx_buffdone, &ast_uart_ports[i]);
++ if (ret < 0) {
++ printk("Error : failed to get tx dma channel[%d]\n", uart_dma_data->dma_ch);
++ return ret;
++ }
++ }
++
++ return 0;
++
++out_ast_uart_unregister_port:
++ for (i = 0; i < nr_uarts; i++) {
++ struct ast_uart_port *up = &ast_uart_ports[i];
++
++ if (up->port.dev == &dev->dev)
++ ast_uart_unregister_port(i);
++ };
++ return ret;
++
++}
++
++/*
++ * Remove serial ports registered against a platform device.
++ */
++static int __devexit serial8250_remove(struct platform_device *dev)
++{
++ int i;
++
++ for (i = 0; i < nr_uarts; i++) {
++ struct ast_uart_port *up = &ast_uart_ports[i];
++
++ if (up->port.dev == &dev->dev)
++ ast_uart_unregister_port(i);
++ }
++ //TODO ..
++// pl080_dma_free(uart_dma_rx.channel, (void *)uart_dma_rx.client);
++// pl080_dma_free(uart_dma_tx.channel, (void *)uart_dma_tx.client);
++
++ return 0;
++}
++
++static int serial8250_suspend(struct platform_device *dev, pm_message_t state)
++{
++ int i;
++
++ for (i = 0; i < UART_DMA_NR; i++) {
++ struct ast_uart_port *up = &ast_uart_ports[i];
++
++ if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
++ uart_suspend_port(&serial8250_reg, &up->port);
++ }
++
++ return 0;
++}
++
++static int serial8250_resume(struct platform_device *dev)
++{
++ int i;
++
++ for (i = 0; i < UART_DMA_NR; i++) {
++ struct ast_uart_port *up = &ast_uart_ports[i];
++
++ if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
++ serial8250_resume_port(i);
++ }
++
++ return 0;
++}
++
++static struct platform_driver serial8250_ast_dma_driver = {
++ .probe = serial8250_probe,
++ .remove = __devexit_p(serial8250_remove),
++ .suspend = serial8250_suspend,
++ .resume = serial8250_resume,
++ .driver = {
++ .name = "ast-uart-dma",
++ .owner = THIS_MODULE,
++ },
++};
++
++/*
++ * This "device" covers _all_ ISA 8250-compatible serial devices listed
++ * in the table in include/asm/serial.h
++ */
++static struct platform_device *serial8250_isa_devs;
++
++/*
++ * serial8250_register_port and serial8250_unregister_port allows for
++ * 16x50 serial ports to be configured at run-time, to support PCMCIA
++ * modems and PCI multiport cards.
++ */
++
++static struct ast_uart_port *serial8250_find_match_or_unused(struct uart_port *port)
++{
++ int i;
++
++ /*
++ * First, find a port entry which matches.
++ */
++ for (i = 0; i < nr_uarts; i++)
++ if (uart_match_port(&ast_uart_ports[i].port, port))
++ return &ast_uart_ports[i];
++
++ /*
++ * We didn't find a matching entry, so look for the first
++ * free entry. We look for one which hasn't been previously
++ * used (indicated by zero iobase).
++ */
++ for (i = 0; i < nr_uarts; i++)
++ if (ast_uart_ports[i].port.type == PORT_UNKNOWN &&
++ ast_uart_ports[i].port.iobase == 0)
++ return &ast_uart_ports[i];
++
++ /*
++ * That also failed. Last resort is to find any entry which
++ * doesn't have a real port associated with it.
++ */
++ for (i = 0; i < nr_uarts; i++)
++ if (ast_uart_ports[i].port.type == PORT_UNKNOWN)
++ return &ast_uart_ports[i];
++
++ return NULL;
++}
++
++/**
++ * serial8250_register_port - register a serial port
++ * @port: serial port template
++ *
++ * Configure the serial port specified by the request. If the
++ * port exists and is in use, it is hung up and unregistered
++ * first.
++ *
++ * The port is then probed and if necessary the IRQ is autodetected
++ * If this fails an error is returned.
++ *
++ * On success the port is ready to use and the line number is returned.
++ */
++int ast_uart_register_port(struct uart_port *port)
++{
++ struct ast_uart_port *uart;
++ int ret = -ENOSPC;
++
++ if (port->uartclk == 0)
++ return -EINVAL;
++printk("register port line %d\n",port->line);
++ mutex_lock(&ast_uart_mutex);
++
++ uart = serial8250_find_match_or_unused(port);
++ if (uart) {
++ uart_remove_one_port(&serial8250_reg, &uart->port);
++
++ uart->port.iobase = port->iobase;
++ uart->port.membase = port->membase;
++ uart->port.irq = port->irq;
++ uart->port.uartclk = port->uartclk;
++ uart->port.fifosize = port->fifosize;
++ uart->port.regshift = port->regshift;
++ uart->port.iotype = port->iotype;
++ uart->port.flags = port->flags | UPF_BOOT_AUTOCONF;
++ uart->port.mapbase = port->mapbase;
++ uart->port.private_data = port->private_data;
++ if (port->dev)
++ uart->port.dev = port->dev;
++
++ ret = uart_add_one_port(&serial8250_reg, &uart->port);
++ if (ret == 0)
++ ret = uart->port.line;
++
++ spin_lock_init(&uart->lock);
++
++ tasklet_init(&uart->rx_tasklet, ast_uart_rx_tasklet_func,
++ (unsigned long)uart);
++
++ tasklet_init(&uart->tx_tasklet, ast_uart_tx_tasklet_func,
++ (unsigned long)uart);
++
++ }
++
++ mutex_unlock(&ast_uart_mutex);
++
++ return ret;
++}
++EXPORT_SYMBOL(ast_uart_register_port);
++
++/**
++ * serial8250_unregister_port - remove a 16x50 serial port at runtime
++ * @line: serial line number
++ *
++ * Remove one serial port. This may not be called from interrupt
++ * context. We hand the port back to the our control.
++ */
++void ast_uart_unregister_port(int line)
++{
++ struct ast_uart_port *uart = &ast_uart_ports[line];
++
++ mutex_lock(&ast_uart_mutex);
++ uart_remove_one_port(&serial8250_reg, &uart->port);
++ if (serial8250_isa_devs) {
++ uart->port.flags &= ~UPF_BOOT_AUTOCONF;
++ uart->port.type = PORT_UNKNOWN;
++ uart->port.dev = &serial8250_isa_devs->dev;
++ uart_add_one_port(&serial8250_reg, &uart->port);
++ } else {
++ uart->port.dev = NULL;
++ }
++ mutex_unlock(&ast_uart_mutex);
++}
++EXPORT_SYMBOL(ast_uart_unregister_port);
++
++static int __init ast_uart_init(void)
++{
++ int ret;
++
++ if (nr_uarts > UART_DMA_NR)
++ nr_uarts = UART_DMA_NR;
++
++ printk(KERN_INFO "ast-uart-dma: UART driver with DMA "
++ "%d ports, IRQ sharing %sabled\n", nr_uarts,
++ share_irqs ? "en" : "dis");
++
++ spin_lock_init(&ast_uart_irq[0].lock);
++
++ ret = uart_register_driver(&serial8250_reg);
++ if (ret)
++ goto out;
++
++ serial8250_isa_devs = platform_device_alloc("ast-uart-dma",
++ PLAT8250_DEV_LEGACY);
++ if (!serial8250_isa_devs) {
++ ret = -ENOMEM;
++ goto unreg_uart_drv;
++ }
++
++ ret = platform_device_add(serial8250_isa_devs);
++ if (ret)
++ goto put_dev;
++
++ serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);
++
++ ret = platform_driver_register(&serial8250_ast_dma_driver);
++ if (ret == 0)
++ goto out;
++
++ platform_device_del(serial8250_isa_devs);
++ put_dev:
++ platform_device_put(serial8250_isa_devs);
++ unreg_uart_drv:
++ uart_unregister_driver(&serial8250_reg);
++ out:
++ return ret;
++}
++
++static void __exit ast_uart_exit(void)
++{
++ struct platform_device *isa_dev = serial8250_isa_devs;
++
++ /*
++ * This tells serial8250_unregister_port() not to re-register
++ * the ports (thereby making serial8250_ast_dma_driver permanently
++ * in use.)
++ */
++ serial8250_isa_devs = NULL;
++
++ platform_driver_unregister(&serial8250_ast_dma_driver);
++ platform_device_unregister(isa_dev);
++
++ uart_unregister_driver(&serial8250_reg);
++}
++
++late_initcall(ast_uart_init);
++module_exit(ast_uart_exit);
++
++#if 0
++EXPORT_SYMBOL(serial8250_suspend_port);
++EXPORT_SYMBOL(serial8250_resume_port);
++#endif
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("AST DMA serial driver");
++MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR);
+diff --git a/drivers/serial/ast_serial.c b/drivers/serial/ast_serial.c
+new file mode 100644
+index 0000000..d1822e4
+--- /dev/null
++++ b/drivers/serial/ast_serial.c
+@@ -0,0 +1,675 @@
++/********************************************************************************
++* File Name : ast_serial.c
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++********************************************************************************/
++
++#include <linux/module.h>
++#include <linux/tty.h>
++#include <linux/ioport.h>
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/serial.h>
++#include <linux/console.h>
++#include <linux/sysrq.h>
++
++#include <asm/io.h>
++#include <asm/irq.h>
++
++#if defined(CONFIG_SERIAL_ASPEED_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
++#define SUPPORT_SYSRQ
++#endif
++
++#include <linux/serial_core.h>
++
++#if defined(CONFIG_COLDFIRE)
++#include <asm/astsim.h>
++#include <asm/ast_serial.h>
++#define UART_NR 1
++
++#elif defined(CONFIG_ARM)
++#include <mach/hardware.h>
++#include <mach/aspeed_serial.h>
++#define UART_NR 2
++
++#else
++#err "NO CONFIG CPU for Serial UART"
++#endif
++
++#define PORT_AST 255
++
++
++
++#define SERIAL_AST_CONSLE_NAME "ttyS"
++#define SERIAL_AST_TTY_NAME "ttyS"
++#define SERIAL_AST_DEVFS_NAME "tts/"
++#define SERIAL_AST_MAJOR 4
++#define SERIAL_AST_MINOR 64
++#define SERIAL_AST_NR UART_NR
++
++#define CALLOUT_AST_NAME "cuaam"
++#define CALLOUT_AST_MAJOR 4
++#define CALLOUT_AST_MINOR 65
++#define CALLOUT_AST_NR UART_NR
++
++
++#ifdef SUPPORT_SYSRQ
++static struct console ast_console;
++#endif
++
++#define MVP2000_ISR_PASS_LIMIT 256
++
++
++/*
++ * Access macros for the UARTs
++ */
++#define UART_GET_CHAR(p) readl((p)->membase + UART_RBR)
++#define UART_PUT_CHAR(p, v) writel((v), (p)->membase + UART_THR)
++#define UART_GET_DLL(p) readl((p)->membase + UART_DLL)
++#define UART_PUT_DLL(p, v) writel((v), (p)->membase + UART_DLL)
++#define UART_GET_DLH(p) readl((p)->membase + UART_DLH)
++#define UART_PUT_DLH(p, v) writel((v), (p)->membase + UART_DLH)
++#define UART_GET_IER(p) readl((p)->membase + UART_IER)
++#define UART_PUT_IER(p, v) writel((v), (p)->membase + UART_IER)
++#define UART_GET_IIR(p) readl((p)->membase + UART_IIR)
++#define UART_GET_FCR(p) readl((p)->membase + UART_FCR)
++#define UART_PUT_FCR(p, v) writel((v), (p)->membase + UART_FCR)
++#define UART_GET_LCR(p) readl((p)->membase + UART_LCR)
++#define UART_PUT_LCR(p, v) writel((v), (p)->membase + UART_LCR)
++#define UART_GET_LSR(p) readl((p)->membase + UART_LSR)
++
++#define UART_DUMMY_RSR_RX 256
++#define UART_PORT_SIZE 64
++
++/*
++ * We wrap our port structure around the generic uart_port.
++ */
++struct uart_ast_port {
++ struct uart_port port;
++};
++
++static void ast_uart_stop_tx(struct uart_port *port)
++{
++ unsigned int cr;
++
++ cr = UART_GET_IER(port);
++ cr &= ~UART_IER_ETEI;
++ UART_PUT_IER(port, cr);
++}
++
++static void ast_uart_start_tx(struct uart_port *port)
++{
++ unsigned int cr;
++
++ cr = UART_GET_IER(port);
++ cr |= UART_IER_ETEI;
++ UART_PUT_IER(port, cr);
++}
++
++static void ast_uart_stop_rx(struct uart_port *port)
++{
++ unsigned int cr;
++
++ cr = UART_GET_IER(port);
++ cr &= ~UART_IER_ERDI;
++ UART_PUT_IER(port, cr);
++}
++
++static void ast_uart_enable_ms(struct uart_port *port)
++{
++ /* printk(KERN_WARNING "ASPEED UART DO NOT Support MODEM operations(emable_ms)\n"); */
++}
++
++static void
++ast_uart_rx_chars(struct uart_port *port)
++{
++ struct tty_struct *tty = port->info->port.tty;
++ unsigned int status, ch, flag, lsr, max_count = 256;
++
++ status = UART_GET_LSR(port);;
++ while ((status & UART_LSR_DR) && max_count--) {
++
++ ch = UART_GET_CHAR(port);
++ flag = TTY_NORMAL;
++ port->icount.rx++;
++
++ /*
++ * Note that the error handling code is
++ * out of the main execution path
++ */
++ lsr = UART_GET_LSR(port);
++ if (unlikely(lsr & UART_LSR_ANY)) {
++ if (lsr & UART_LSR_BE) {
++ lsr &= ~(UART_LSR_FE | UART_LSR_PE);
++ port->icount.brk++;
++ if (uart_handle_break(port))
++ goto ignore_char;
++ } else if (lsr & UART_LSR_PE)
++ port->icount.parity++;
++ else if (lsr & UART_LSR_FE)
++ port->icount.frame++;
++ if (lsr & UART_LSR_OE)
++ port->icount.overrun++;
++
++ lsr &= port->read_status_mask;
++
++ if (lsr & UART_LSR_BE)
++ flag = TTY_BREAK;
++ else if (lsr & UART_LSR_PE)
++ flag = TTY_PARITY;
++ else if (lsr & UART_LSR_FE)
++ flag = TTY_FRAME;
++ }
++
++ if (uart_handle_sysrq_char(port, ch & 255))
++ goto ignore_char;
++
++ uart_insert_char(port, lsr, UART_LSR_OE, ch, flag);
++
++ ignore_char:
++ status = UART_GET_LSR(port);
++ }
++ tty_flip_buffer_push(tty);
++ return;
++}
++
++static void ast_uart_tx_chars(struct uart_port *port)
++{
++ struct circ_buf *xmit = &port->info->xmit;
++ int count;
++
++ if (port->x_char) {
++ UART_PUT_CHAR(port, port->x_char);
++ port->icount.tx++;
++ port->x_char = 0;
++ return;
++ }
++ if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
++ ast_uart_stop_tx(port);
++ return;
++ }
++
++ count = port->fifosize >> 1;
++ do {
++ UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
++ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
++ port->icount.tx++;
++ if (uart_circ_empty(xmit))
++ break;
++ } while (--count > 0);
++
++ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
++ uart_write_wakeup(port);
++
++ if (uart_circ_empty(xmit))
++ ast_uart_stop_tx(port);
++}
++
++static irqreturn_t ast_uart_int(int irq, void *dev_id)
++{
++ struct uart_port *port = dev_id;
++ unsigned int status, iir, pass_counter = MVP2000_ISR_PASS_LIMIT;
++
++ spin_lock(&port->lock);
++
++ status = UART_GET_LSR(port);
++ do {
++ if (status & UART_LSR_DR)
++ ast_uart_rx_chars(port);
++
++ if (status & UART_LSR_THRE) {
++ ast_uart_tx_chars(port);
++ iir = UART_GET_IIR(port);
++ }
++
++ if (pass_counter-- == 0)
++ break;
++
++ status = UART_GET_LSR(port);
++ } while (status & (UART_LSR_THRE|UART_LSR_DR));
++
++ spin_unlock(&port->lock);
++
++ return IRQ_HANDLED;
++}
++
++static unsigned int ast_uart_tx_empty(struct uart_port *port)
++{
++ return UART_GET_LSR(port) & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
++}
++
++static unsigned int ast_uart_get_mctrl(struct uart_port *port)
++{
++ /* printk(KERN_WARNING "ASPEED UART DO NOT Support MODEM operations(get_mctrl)\n"); */
++ return 0;
++}
++
++static void ast_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
++{
++ /* printk(KERN_WARNING "ASPEED UART DO NOT Support MODEM operations(set_mctrl)\n"); */
++}
++
++static void ast_uart_break_ctl(struct uart_port *port, int break_state)
++{
++ unsigned long flags;
++ unsigned int lcr;
++
++ spin_lock_irqsave(&port->lock, flags);
++ lcr = UART_GET_LCR(port);
++ if (break_state == -1)
++ lcr |= UART_LCR_BRK;
++ else
++ lcr &= ~UART_LCR_BRK;
++ UART_PUT_LCR(port, lcr);
++ spin_unlock_irqrestore(&port->lock, flags);
++}
++
++static int ast_uart_startup(struct uart_port *port)
++{
++ int retval;
++
++ /*
++ * Allocate the IRQ
++ */
++ retval = request_irq(port->irq, ast_uart_int, IRQF_DISABLED, "ast_serial", port);
++ if (retval)
++ {
++ printk("ast_uart_startup: Can't Get IRQ\n");
++ return retval;
++ }
++
++ /*
++ * Finally, enable interrupts
++ */
++// IRQ_SET_HIGH_LEVEL(port->irq);
++// IRQ_SET_LEVEL_TRIGGER(port->irq);
++ UART_PUT_IER(port, UART_IER_ERDI);
++
++ return 0;
++}
++
++static void ast_uart_shutdown(struct uart_port *port)
++{
++ /*
++ * Free the interrupt
++ */
++ free_irq(port->irq, port);
++
++ /*
++ * disable all interrupts, disable the port
++ */
++ UART_PUT_IER(port, 0);
++
++ /* disable break condition and fifos */
++ UART_PUT_LCR(port, UART_GET_LCR(port)&(~UART_LCR_BRK));
++ UART_PUT_FCR(port, UART_GET_FCR(port)&(~UART_FCR_FIFOE));
++}
++
++static void
++ast_set_termios(struct uart_port *port, struct ktermios *termios,
++ struct ktermios *old)
++{
++ unsigned int lcr, fcr = 0;
++ unsigned long flags;
++ unsigned int baud, quot;
++ int ch, i;
++
++ /*
++ * Ask the core to calculate the divisor for us.
++ */
++ baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
++ quot = port->uartclk / (16 * baud);
++
++ switch (termios->c_cflag & CSIZE) {
++ case CS5:
++ lcr = UART_LCR_WLEN_5;
++ break;
++ case CS6:
++ lcr = UART_LCR_WLEN_6;
++ break;
++ case CS7:
++ lcr = UART_LCR_WLEN_7;
++ break;
++ default: // CS8
++ lcr = UART_LCR_WLEN_8;
++ break;
++ }
++ if (termios->c_cflag & CSTOPB)
++ lcr |= UART_LCR_STOP;
++ if (termios->c_cflag & PARENB) {
++ lcr |= UART_LCR_PEN;
++ if (!(termios->c_cflag & PARODD))
++ lcr |= UART_LCR_EPS;
++ }
++ if (port->fifosize > 1)
++ fcr |= (UART_FCR_XMITR|UART_FCR_RCVRR|UART_FCR_FIFOE);
++
++
++ spin_lock_irqsave(&port->lock, flags);
++
++ /*
++ * Update the per-port timeout.
++ */
++ uart_update_timeout(port, termios->c_cflag, baud);
++
++ port->read_status_mask = UART_LSR_OE;
++ if (termios->c_iflag & INPCK)
++ port->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
++ if (termios->c_iflag & (BRKINT | PARMRK))
++ port->read_status_mask |= UART_LSR_BE;
++
++ /*
++ * Characters to ignore
++ */
++ port->ignore_status_mask = 0;
++ if (termios->c_iflag & IGNPAR)
++ port->ignore_status_mask |= UART_LSR_FE | UART_LSR_PE;
++ if (termios->c_iflag & IGNBRK) {
++ port->ignore_status_mask |= UART_LSR_BE;
++ /*
++ * If we're ignoring parity and break indicators,
++ * ignore overruns too (for real raw support).
++ */
++ if (termios->c_iflag & IGNPAR)
++ port->ignore_status_mask |= UART_LSR_OE;
++ }
++
++ /*
++ * Ignore all characters if CREAD is not set.
++ */
++ if ((termios->c_cflag & CREAD) == 0)
++ port->ignore_status_mask |= UART_DUMMY_RSR_RX;
++
++
++ /* Set baud rate */
++ UART_PUT_LCR(port, UART_LCR_DLAB); /* enable Divisor Latach Address Bit */
++ UART_PUT_DLH(port, ((quot >> 8) & 0xFF));
++ UART_PUT_DLL(port, (quot & 0xff));
++
++ UART_PUT_FCR(port, fcr);
++ UART_PUT_LCR(port, lcr);
++ for (i = 0; i < 16; i++) {
++ ch = UART_GET_CHAR (port); /* Clear Timeout Interrupt */
++ }
++
++ spin_unlock_irqrestore(&port->lock, flags);
++}
++
++static const char *ast_uart_type(struct uart_port *port)
++{
++ return port->type == PORT_AST ? "AST UART" : NULL;
++}
++
++/*
++ * Release the memory region(s) being used by 'port'
++ */
++static void ast_uart_release_port(struct uart_port *port)
++{
++ release_mem_region(port->mapbase, UART_PORT_SIZE);
++}
++
++/*
++ * Request the memory region(s) being used by 'port'
++ */
++static int ast_uart_request_port(struct uart_port *port)
++{
++ return request_mem_region(port->mapbase, UART_PORT_SIZE, "serial_ast")
++ != NULL ? 0 : -EBUSY;
++}
++
++/*
++ * Configure/autoconfigure the port.
++ */
++static void ast_uart_config_port(struct uart_port *port, int flags)
++{
++ if (flags & UART_CONFIG_TYPE) {
++ port->type = PORT_AST;
++ ast_uart_request_port(port);
++ }
++}
++
++/*
++ * verify the new serial_struct (for TIOCSSERIAL).
++ */
++static int ast_uart_verify_port(struct uart_port *port, struct serial_struct *ser)
++{
++ int ret = 0;
++ if (ser->type != PORT_UNKNOWN && ser->type != PORT_AST)
++ ret = -EINVAL;
++ if (ser->irq < 0 || ser->irq >= NR_IRQS)
++ ret = -EINVAL;
++ if (ser->baud_base < 9600)
++ ret = -EINVAL;
++ return ret;
++}
++
++static struct uart_ops ast_pops = {
++ .tx_empty = ast_uart_tx_empty,
++ .set_mctrl = ast_uart_set_mctrl,
++ .get_mctrl = ast_uart_get_mctrl,
++ .stop_tx = ast_uart_stop_tx,
++ .start_tx = ast_uart_start_tx,
++ .stop_rx = ast_uart_stop_rx,
++ .enable_ms = ast_uart_enable_ms,
++ .break_ctl = ast_uart_break_ctl,
++ .startup = ast_uart_startup,
++ .shutdown = ast_uart_shutdown,
++ .set_termios = ast_set_termios,
++ .type = ast_uart_type,
++ .release_port = ast_uart_release_port,
++ .request_port = ast_uart_request_port,
++ .config_port = ast_uart_config_port,
++ .verify_port = ast_uart_verify_port,
++};
++
++#if defined(CONFIG_COLDFIRE)
++static struct uart_ast_port ast_ports[UART_NR] = {
++ {
++ .port = {
++ .membase = (void *) AST_UART0_BASE,
++ .mapbase = AST_UART0_BASE,
++ .iotype = SERIAL_IO_MEM,
++ .irq = IRQ_UART0,
++ .uartclk = (24*1000000L),
++ .fifosize = 16,
++ .ops = &ast_pops,
++ .flags = ASYNC_BOOT_AUTOCONF,
++ .line = 0,
++ },
++ }
++};
++
++#elif defined (CONFIG_ARM)
++static struct uart_ast_port ast_ports[UART_NR] = {
++ {
++ .port = {
++ .membase = (void *) (IO_ADDRESS(AST_UART0_BASE)),
++ .mapbase = AST_UART0_BASE,
++ .iotype = SERIAL_IO_MEM,
++ .irq = IRQ_UART0,
++ .uartclk = (24*1000000L),
++ .fifosize = 16,
++ .ops = &ast_pops,
++ .flags = ASYNC_BOOT_AUTOCONF,
++ .line = 0,
++ },
++ }
++};
++#else
++#err "ERROR~~~"
++#endif
++
++#ifdef CONFIG_SERIAL_ASPEED_CONSOLE
++
++static void aspeed_console_putchar(struct uart_port *port, int ch)
++{
++ while (!(UART_GET_LSR(port) & UART_LSR_THRE))
++ barrier();
++ UART_PUT_CHAR(port, ch);
++}
++
++static void ast_uart_console_write(struct console *co, const char *s, unsigned int count)
++{
++ struct uart_port *port = &ast_ports[co->index].port;
++ unsigned int status, old_ier;
++
++ /*
++ * First save the IER then disable the interrupts
++ */
++ old_ier = UART_GET_IER(port);
++ UART_PUT_IER(port, 0);
++
++ /*
++ * Now, do each character
++ */
++ uart_console_write(port, s, count, aspeed_console_putchar);
++
++ /*
++ * Finally, wait for transmitter to become empty
++ * and restore the IER
++ */
++ do {
++ status = UART_GET_LSR(port);
++ } while (!(status & UART_LSR_TEMT));
++ UART_PUT_IER(port, old_ier);
++}
++
++static void __init
++ast_uart_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
++{
++ if (UART_GET_IER(port) & UART_IER_ERDI) {
++ unsigned int lcr, quot;
++ lcr = UART_GET_LCR(port);
++
++ *parity = 'n';
++ if (lcr & UART_LCR_PEN) {
++ if (lcr & UART_LCR_EPS)
++ *parity = 'e';
++ else
++ *parity = 'o';
++ }
++
++ switch (lcr & UART_LCR_WLEN_MASK) {
++ case UART_LCR_WLEN_8:
++ default:
++ *bits = 8;
++ break;
++ case UART_LCR_WLEN_7:
++ *bits = 7;
++ break;
++ case UART_LCR_WLEN_6:
++ *bits = 6;
++ break;
++ case UART_LCR_WLEN_5:
++ *bits = 5;
++ break;
++ }
++
++ UART_PUT_LCR(port, UART_LCR_DLAB); /* enable Divisor Latach Address Bit */
++ quot = UART_GET_DLL(port) | (UART_GET_DLH(port) << 8);
++ *baud = port->uartclk / (16 * quot);
++ UART_PUT_LCR(port, lcr);
++ }
++}
++
++static int __init ast_uart_console_setup(struct console *co, char *options)
++{
++ struct uart_port *port;
++ int baud = CONFIG_SERIAL_ASPEED_CONSOLE_BAUD;
++ int bits = 8;
++ int parity = 'n';
++ int flow = 'n';
++
++ /*
++ * Check whether an invalid uart number has been specified, and
++ * if so, search for the first available port that does have
++ * console support.
++ */
++ if (co->index >= UART_NR)
++ co->index = 0;
++ port = &ast_ports[co->index].port;
++
++
++ if (options)
++ uart_parse_options(options, &baud, &parity, &bits, &flow);
++ else
++ ast_uart_console_get_options(port, &baud, &parity, &bits);
++
++
++ return uart_set_options(port, co, baud, parity, bits, flow);
++}
++
++static struct uart_driver ast_reg;
++
++static struct console ast_console = {
++ .name = SERIAL_AST_CONSLE_NAME,
++ .write = ast_uart_console_write,
++ .device = uart_console_device,
++ .setup = ast_uart_console_setup,
++ .flags = CON_PRINTBUFFER,
++ .index = -1,
++ .data = &ast_reg,
++};
++
++int __init ast_uart_console_init(void)
++{
++ register_console(&ast_console);
++ return 0;
++}
++
++console_initcall(ast_uart_console_init);
++
++#define MVP2000_CONSOLE &ast_console
++#else
++#define MVP2000_CONSOLE NULL
++#endif
++
++
++static struct uart_driver ast_reg = {
++ .owner = THIS_MODULE,
++ .major = SERIAL_AST_MAJOR,
++ .minor = SERIAL_AST_MINOR,
++ .dev_name = SERIAL_AST_TTY_NAME,
++ .nr = UART_NR,
++ .cons = MVP2000_CONSOLE,
++};
++
++static int __init ast_uart_init(void)
++{
++ int ret;
++
++ ret = uart_register_driver(&ast_reg);
++ if (ret == 0) {
++ int i;
++
++ for (i = 0; i < UART_NR; i++)
++ uart_add_one_port(&ast_reg, &ast_ports[i].port);
++ }
++ return ret;
++}
++
++static void __exit ast_uart_exit(void)
++{
++ int i;
++
++ for (i = 0; i < UART_NR; i++)
++ uart_remove_one_port(&ast_reg, &ast_ports[i].port);
++
++ uart_unregister_driver(&ast_reg);
++}
++
++module_init(ast_uart_init);
++module_exit(ast_uart_exit);
++
++MODULE_AUTHOR("ASPEED Technology Inc.");
++MODULE_DESCRIPTION("ASPEED serial port driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
+index b9d0efb..d95c2c8 100644
+--- a/drivers/spi/Kconfig
++++ b/drivers/spi/Kconfig
+@@ -53,6 +53,19 @@ if SPI_MASTER
+
+ comment "SPI Master Controller Drivers"
+
++config SPI_AST
++ tristate "Aspeed SPI Controller"
++ depends on ARCH_ASPEED
++ select SPI_BITBANG
++ help
++ This selects a driver for the AST SPI Controller
++
++config SPI_FMC
++ tristate "Aspeed FMC SPI Controller"
++ depends on ARCH_ASPEED
++ help
++ This selects a driver for the AST FMC SPI Controller
++
+ config SPI_ATMEL
+ tristate "Atmel SPI Controller"
+ depends on (ARCH_AT91 || AVR32)
+diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
+index ccf18de..3d1286e 100644
+--- a/drivers/spi/Makefile
++++ b/drivers/spi/Makefile
+@@ -29,6 +29,8 @@ obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o
+ obj-$(CONFIG_SPI_TXX9) += spi_txx9.o
+ obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o
+ obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o
++obj-$(CONFIG_SPI_AST) += ast_spi.o
++obj-$(CONFIG_SPI_FMC) += fmc_spi.o
+ # ... add above this line ...
+
+ # SPI protocol drivers (device/link on bus)
+diff --git a/drivers/spi/ast_spi.c b/drivers/spi/ast_spi.c
+new file mode 100644
+index 0000000..e8f80e8
+--- /dev/null
++++ b/drivers/spi/ast_spi.c
+@@ -0,0 +1,416 @@
++/********************************************************************************
++* File Name : driver/spi/ast-spi.c
++* Author : Ryan Chen
++* Description : ASPEED SPI host driver
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/10/20 Ryan Chen create this file
++* 1. 2013/01/05 Ryan Chen modify
++*
++********************************************************************************/
++//#define DEBUG
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/interrupt.h>
++#include <linux/ioport.h>
++#include <linux/platform_device.h>
++#include <linux/err.h>
++#include <linux/errno.h>
++#include <linux/wait.h>
++#include <linux/delay.h>
++#include <linux/spi/spi.h>
++#include <asm/io.h>
++#include <mach/ast_spi.h>
++#include <plat/regs-spi.h>
++
++struct ast_spi_host {
++ void __iomem *reg;
++ void __iomem *buff;
++ struct ast_spi_driver_data *spi_data;
++ struct spi_master *master;
++ struct spi_device *spi_dev;
++ struct device *dev;
++ spinlock_t lock;
++};
++
++static inline void
++ast_spi_write(struct ast_spi_host *spi, u32 val, u32 reg)
++{
++// dev_dbg(i2c_dev->dev, "ast_i2c_write : val: %x , reg : %x \n",val,reg);
++ writel(val, spi->reg+ reg);
++}
++
++static inline u32
++ast_spi_read(struct ast_spi_host *spi, u32 reg)
++{
++ return readl(spi->reg + reg);
++}
++
++/* the spi->mode bits understood by this driver: */
++#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH)
++
++static int
++ast_spi_setup(struct spi_device *spi)
++{
++ struct ast_spi_host *host = (struct ast_spi_host *)spi_master_get_devdata(spi->master);
++ unsigned int bits = spi->bits_per_word;
++ u32 spi_ctrl;
++ u32 divisor;
++
++ int err = 0;
++ return err;
++
++ dev_dbg(host->dev, "ast_spi_setup() , cs %d\n", spi->chip_select);
++
++ host->spi_dev = spi;
++
++ spi_ctrl = ast_spi_read(host, AST_SPI_CTRL);
++
++ if (spi->chip_select > spi->master->num_chipselect) {
++ dev_dbg(&spi->dev,
++ "setup: invalid chipselect %u (%u defined)\n",
++ spi->chip_select, spi->master->num_chipselect);
++ return -EINVAL;
++ }
++
++ if (bits == 0)
++ bits = 8;
++
++ if (bits < 8 || bits > 16) {
++ dev_dbg(&spi->dev,
++ "setup: invalid bits_per_word %u (8 to 16)\n",
++ bits);
++ return -EINVAL;
++ }
++
++ if (spi->mode & ~MODEBITS) {
++ dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n",
++ spi->mode & ~MODEBITS);
++ return -EINVAL;
++ }
++
++ /* see notes above re chipselect */
++ if((spi->chip_select == 0) && (spi->mode & SPI_CS_HIGH)) {
++ dev_dbg(&spi->dev, "setup: can't be active-high\n");
++ return -EINVAL;
++ }
++
++ /*
++ * Pre-new_1 chips start out at half the peripheral
++ * bus speed.
++ */
++
++ if (spi->max_speed_hz) {
++ /* Set the SPI slaves select and characteristic control register */
++ divisor = host->spi_data->get_div(spi->max_speed_hz);
++ } else {
++ /* speed zero means "as slow as possible" */
++ divisor = 15;
++ }
++
++ //TODO MASK first
++ spi_ctrl |= (divisor << 8);
++
++ if (spi->chip_select > (spi->master->num_chipselect - 1)) {
++ dev_err(&spi->dev, "chipselect %d exceed the number of chipselect master supoort\n", spi->chip_select);
++ return -EINVAL;
++ }
++
++#if 0
++ if (SPI_CPHA & spi->mode)
++ cpha = SPI_CPHA_1;
++ else
++ cpha = SPI_CPHA_0;
++#endif
++
++// if (SPI_CPOL & spi->mode)
++// spi_ctrl |= SPI_CPOL_1;
++// else
++// spi_ctrl &= ~SPI_CPOL_1;
++
++ //ISSUE : ast spi ctrl couldn't use mode 3, so fix mode 0
++ spi_ctrl &= ~SPI_CPOL_1;
++
++
++ if (SPI_LSB_FIRST & spi->mode)
++ spi_ctrl |= SPI_LSB_FIRST_CTRL;
++ else
++ spi_ctrl &= ~SPI_LSB_FIRST_CTRL;
++
++
++ /* Configure SPI controller */
++ ast_spi_write(host, spi_ctrl, AST_SPI_CTRL);
++
++ dev_dbg(&spi->dev, "%s: mode %d, %u bpw, %d hz\n", __FUNCTION__, spi->mode, spi->bits_per_word, spi->max_speed_hz);
++ return err;
++}
++
++static int ast_spi_transfer(struct spi_device *spi, struct spi_message *msg)
++{
++ struct ast_spi_host *host = (struct ast_spi_host *)spi_master_get_devdata(spi->master);
++ struct spi_transfer *xfer;
++ const u8 *tx_buf;
++ u8 *rx_buf;
++
++
++ int i=0,j=0;
++
++ dev_dbg(host->dev, "new message %p submitted for %s\n",
++ msg, spi->dev.bus_id);
++
++ ast_spi_write(host, ast_spi_read(host, AST_SPI_CONFIG) | SPI_CONF_WRITE_EN, AST_SPI_CONFIG);
++// writel( (readl(host->spi_data->ctrl_reg) | SPI_CMD_USER_MODE) | SPI_CE_INACTIVE,host->spi_data->ctrl_reg);
++ ast_spi_write(host, ast_spi_read(host, AST_SPI_CTRL) | SPI_CMD_USER_MODE, AST_SPI_CTRL);
++
++// writel( ~SPI_CE_INACTIVE & readl(host->spi_data->ctrl_reg),host->spi_data->ctrl_reg);
++ msg->actual_length = 0;
++ msg->status = 0;
++
++
++ list_for_each_entry(xfer, &msg->transfers, transfer_list) {
++ dev_dbg(host->dev,
++ "xfer[%d] %p: width %d, len %u, tx %p/%08x, rx %p/%08x\n",
++ j, xfer,
++ xfer->bits_per_word, xfer->len,
++ xfer->tx_buf, xfer->tx_dma,
++ xfer->rx_buf, xfer->rx_dma);
++
++ //TX ----
++ if(xfer->tx_buf) {
++#if 0
++ if(xfer->bits_per_word == 16)
++ const u16 *tx_buf;
++ else
++ const u8 *tx_buf;
++#endif
++ tx_buf = xfer->tx_buf;
++ for(i=0;i<xfer->len;i++) {
++ dev_dbg(host->dev, "[%d] : %x \n",i, tx_buf[i]);
++ writeb(tx_buf[i], host->buff);
++// writeb(tx_buf[i], host->spi_data->buf_reg);
++ }
++ }
++ udelay(1);
++ //RX----
++ if(xfer->rx_buf) {
++
++ rx_buf = xfer->rx_buf;
++ dev_dbg(host->dev, "rx len [%d] \n",xfer->len );
++ for(i=0;i<xfer->len;i++) {
++// rx_buf[i] = readb(host->spi_data->buf_reg);
++ rx_buf[i] = readb(host->buff);
++ dev_dbg(host->dev, "[%d] : %x \n",i, rx_buf[i]);
++ }
++ }
++ msg->actual_length += xfer->len;
++ j++;
++ }
++
++// writel( SPI_CE_INACTIVE | readl(host->spi_data->ctrl_reg),host->spi_data->ctrl_reg);
++ ast_spi_write(host, (ast_spi_read(host, AST_SPI_CTRL) & ~SPI_CMD_USER_MODE) | SPI_CMD_FAST_R_MODE, AST_SPI_CTRL);
++
++ ast_spi_write(host, ast_spi_read(host, AST_SPI_CONFIG) & ~SPI_CONF_WRITE_EN, AST_SPI_CONFIG);
++
++ msg->status = 0;
++
++ spin_unlock(&host->lock);
++ msg->complete(msg->context);
++ spin_lock(&host->lock);
++
++ return 0;
++
++}
++static void ast_spi_cleanup(struct spi_device *spi)
++{
++ struct ast_spi_host *host = spi_master_get_devdata(spi->master);
++ unsigned long flags;
++ dev_dbg(host->dev, "ast_spi_cleanup() \n");
++
++ spin_lock_irqsave(&host->lock, flags);
++// if (host->stay == spi) {
++// host->stay = NULL;
++// cs_deactivate(host, spi);
++// }
++ spin_unlock_irqrestore(&host->lock, flags);
++}
++
++static int ast_spi_probe(struct platform_device *pdev)
++{
++ struct resource *res0, *res1;
++ struct ast_spi_host *host;
++ struct spi_master *master;
++ int err;
++
++ dev_dbg(&pdev->dev, "ast_spi_probe() \n\n\n");
++
++ master = spi_alloc_master(&pdev->dev, sizeof(struct ast_spi_host));
++ if (NULL == master) {
++ dev_err(&pdev->dev, "No memory for spi_master\n");
++ err = -ENOMEM;
++ goto err_nomem;
++ }
++ host = spi_master_get_devdata(master);
++ memset(host, 0, sizeof(struct ast_spi_host));
++
++ res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res0) {
++ dev_err(&pdev->dev, "cannot get IORESOURCE_MEM 0\n");
++ err = -ENXIO;
++ goto err_no_io_res;
++ }
++
++ host->reg = ioremap(res0->start, resource_size(res0));
++ if (!host->reg) {
++ dev_err(&pdev->dev, "cannot remap register\n");
++ err = -EIO;
++ goto release_mem;
++ }
++
++ dev_dbg(&pdev->dev, "remap phy %x, virt %x \n",(u32)res0->start, (u32)host->reg);
++
++ res1 = platform_get_resource(pdev, IORESOURCE_IO, 0);
++ if (!res1) {
++ dev_err(&pdev->dev, "cannot get IORESOURCE_IO 0\n");
++ return -ENXIO;
++ }
++
++ host->buff = ioremap(res1->start, resource_size(res1));
++ if (!host->buff) {
++ dev_err(&pdev->dev, "cannot remap buffer \n");
++ err = -EIO;
++ goto release_mem;
++ }
++
++ dev_dbg(&pdev->dev, "remap io phy %x, virt %x \n",(u32)res1->start, (u32)host->buff);
++
++ host->master = spi_master_get(master);
++ host->master->bus_num = pdev->id;
++ host->master->num_chipselect = 1;
++ host->dev = &pdev->dev;
++
++ /* Setup the state for bitbang driver */
++ host->master->setup = ast_spi_setup;
++ host->master->transfer = ast_spi_transfer;
++ host->master->cleanup = ast_spi_cleanup;
++
++ /* Find and claim our resources */
++ host->spi_data = pdev->dev.driver_data;
++
++ platform_set_drvdata(pdev, host);
++
++ /* Register our spi controller */
++ err = spi_register_master(host->master);
++ if (err) {
++ dev_err(&pdev->dev, "failed to register SPI master\n");
++ goto err_register;
++ }
++
++ dev_dbg(&pdev->dev, "ast_spi_probe() return \n\n\n");
++
++ return 0;
++
++err_register:
++ spi_master_put(host->master);
++ iounmap(host->reg);
++ iounmap(host->buff);
++
++release_mem:
++ release_mem_region(res0->start, res0->end - res0->start + 1);
++ release_mem_region(res1->start, res1->end - res1->start + 1);
++
++err_no_io_res:
++ kfree(master);
++ kfree(host);
++
++err_nomem:
++ return err;
++
++}
++
++static int
++ast_spi_remove(struct platform_device *pdev)
++{
++ struct resource *res0, *res1;
++ struct ast_spi_host *host = platform_get_drvdata(pdev);
++
++ dev_dbg(host->dev, "ast_spi_remove()\n");
++
++ if (!host)
++ return -1;
++
++ res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ res1 = platform_get_resource(pdev, IORESOURCE_IO, 0);
++ release_mem_region(res0->start, res0->end - res0->start + 1);
++ release_mem_region(res1->start, res1->end - res1->start + 1);
++ iounmap(host->reg);
++ iounmap(host->buff);
++
++ platform_set_drvdata(pdev, NULL);
++ spi_unregister_master(host->master);
++ spi_master_put(host->master);
++ return 0;
++}
++
++#ifdef CONFIG_PM
++static int
++ast_spi_suspend(struct platform_device *pdev, pm_message_t msg)
++{
++ return 0;
++}
++
++static int
++ast_spi_resume(struct platform_device *pdev)
++{
++ return 0;
++}
++#else
++#define ast_spi_suspend NULL
++#define ast_spi_resume NULL
++#endif
++
++static struct platform_driver ast_spi_driver = {
++ .probe = ast_spi_probe,
++ .remove = ast_spi_remove,
++ .suspend = ast_spi_suspend,
++ .resume = ast_spi_resume,
++ .driver = {
++ .name = "ast-spi",
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init
++ast_spi_init(void)
++{
++ return platform_driver_register(&ast_spi_driver);
++}
++
++static void __exit
++ast_spi_exit(void)
++{
++ platform_driver_unregister(&ast_spi_driver);
++}
++
++subsys_initcall(ast_spi_init);
++//module_init(ast_spi_init);
++module_exit(ast_spi_exit);
++
++MODULE_DESCRIPTION("AST SPI Driver");
++MODULE_AUTHOR("Ryan Chen");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/spi/fmc_spi.c b/drivers/spi/fmc_spi.c
+new file mode 100644
+index 0000000..ccc0d1c
+--- /dev/null
++++ b/drivers/spi/fmc_spi.c
+@@ -0,0 +1,436 @@
++/********************************************************************************
++* File Name : driver/spi/ast-spi.c
++* Author : Ryan Chen
++* Description : ASPEED SPI host driver
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/10/20 Ryan Chen create this file
++* 1. 2013/01/05 Ryan Chen modify
++*
++********************************************************************************/
++//#define DEBUG
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/interrupt.h>
++#include <linux/ioport.h>
++#include <linux/platform_device.h>
++#include <linux/err.h>
++#include <linux/errno.h>
++#include <linux/wait.h>
++#include <linux/delay.h>
++#include <linux/spi/spi.h>
++#include <asm/io.h>
++#include <mach/ast_spi.h>
++#include <plat/regs-spi.h>
++
++//IN FMC SPI always control offset 0x00
++
++struct fmc_spi_host {
++ void __iomem *reg;
++ void __iomem *buff;
++ struct ast_spi_driver_data *spi_data;
++ struct spi_master *master;
++ struct spi_device *spi_dev;
++ struct device *dev;
++ spinlock_t lock;
++};
++
++static inline void
++fmc_spi_write(struct fmc_spi_host *host, u32 val, u32 reg)
++{
++// printk("write : val: %x , offset : %x \n",val, reg);
++ writel(val, host->reg + reg);
++}
++
++static inline u32
++fmc_spi_read(struct fmc_spi_host *host, u32 reg)
++{
++ return readl(host->reg + reg);
++}
++
++/* the spi->mode bits understood by this driver: */
++#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH)
++
++static int
++fmc_spi_setup(struct spi_device *spi)
++{
++ struct fmc_spi_host *host = (struct fmc_spi_host *)spi_master_get_devdata(spi->master);
++ unsigned int bits = spi->bits_per_word;
++ u32 spi_ctrl;
++ u32 divisor;
++
++ int err = 0;
++ dev_dbg(host->dev, "fmc_spi_setup() ======================>>\n");
++
++
++ dev_dbg(host->dev, "fmc_spi_setup() ======================>>\n");
++
++ host->spi_dev = spi;
++
++ spi_ctrl = fmc_spi_read(host, 0x00);
++// printk("trl : %x \n",spi_ctrl);
++
++ if (spi->chip_select > spi->master->num_chipselect) {
++ dev_dbg(&spi->dev,
++ "setup: invalid chipselect %u (%u defined)\n",
++ spi->chip_select, spi->master->num_chipselect);
++ return -EINVAL;
++ }
++
++ if (bits == 0)
++ bits = 8;
++
++ if (bits < 8 || bits > 16) {
++ dev_dbg(&spi->dev,
++ "setup: invalid bits_per_word %u (8 to 16)\n",
++ bits);
++ return -EINVAL;
++ }
++
++ if (spi->mode & ~MODEBITS) {
++ dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n",
++ spi->mode & ~MODEBITS);
++ return -EINVAL;
++ }
++
++ /* see notes above re chipselect */
++ if((spi->chip_select == 0) && (spi->mode & SPI_CS_HIGH)) {
++ dev_dbg(&spi->dev, "setup: can't be active-high\n");
++ return -EINVAL;
++ }
++
++ /*
++ * Pre-new_1 chips start out at half the peripheral
++ * bus speed.
++ */
++
++ if (spi->max_speed_hz) {
++ /* Set the SPI slaves select and characteristic control register */
++ divisor = host->spi_data->get_div(spi->max_speed_hz);
++ } else {
++ /* speed zero means "as slow as possible" */
++ divisor = 15;
++ }
++
++ spi_ctrl &= ~SPI_CLK_DIV_MASK;
++// printk("set div %x \n",divisor);
++ //TODO MASK first
++ spi_ctrl |= SPI_CLK_DIV(divisor);
++
++ if (spi->chip_select > (spi->master->num_chipselect - 1)) {
++ dev_err(&spi->dev, "chipselect %d exceed the number of chipselect master supoort\n", spi->chip_select);
++ return -EINVAL;
++ }
++
++#if 0
++ if (SPI_CPHA & spi->mode)
++ cpha = SPI_CPHA_1;
++ else
++ cpha = SPI_CPHA_0;
++#endif
++
++// if (SPI_CPOL & spi->mode)
++// spi_ctrl |= SPI_CPOL_1;
++// else
++// spi_ctrl &= ~SPI_CPOL_1;
++
++ //ISSUE : ast spi ctrl couldn't use mode 3, so fix mode 0
++ spi_ctrl &= ~SPI_CPOL_1;
++
++
++ if (SPI_LSB_FIRST & spi->mode)
++ spi_ctrl |= SPI_LSB_FIRST_CTRL;
++ else
++ spi_ctrl &= ~SPI_LSB_FIRST_CTRL;
++
++
++ /* Configure SPI controller */
++ fmc_spi_write(host, spi_ctrl, 0x00);
++
++ dev_dbg(&spi->dev, "%s: mode %d, %u bpw, %d hz\n", __FUNCTION__, spi->mode, spi->bits_per_word, spi->max_speed_hz);
++ return err;
++}
++
++static int fmc_spi_transfer(struct spi_device *spi, struct spi_message *msg)
++{
++ struct fmc_spi_host *host = (struct fmc_spi_host *)spi_master_get_devdata(spi->master);
++ struct spi_transfer *xfer;
++ const u8 *tx_buf;
++ u8 *rx_buf;
++ unsigned long flags;
++
++ int i=0,j=0;
++
++ dev_dbg(host->dev, "new message %p submitted for %s \n",
++ msg, dev_name(&spi->dev));
++
++ spin_lock_irqsave(&host->lock, flags);
++// writel( (readl(host->spi_data->ctrl_reg) | SPI_CMD_USER_MODE) | SPI_CE_INACTIVE,host->spi_data->ctrl_reg);
++ fmc_spi_write(host, fmc_spi_read(host, 0x00) | SPI_CMD_USER_MODE, 0x00);
++ msg->actual_length = 0;
++ msg->status = 0;
++
++// writel( ~SPI_CE_INACTIVE & readl(host->spi_data->ctrl_reg),host->spi_data->ctrl_reg);
++
++ list_for_each_entry(xfer, &msg->transfers, transfer_list) {
++ dev_dbg(host->dev,
++ "xfer[%d] %p: width %d, len %u, tx %p/%08x, rx %p/%08x\n",
++ j, xfer,
++ xfer->bits_per_word, xfer->len,
++ xfer->tx_buf, xfer->tx_dma,
++ xfer->rx_buf, xfer->rx_dma);
++
++ tx_buf = xfer->tx_buf;
++ rx_buf = xfer->rx_buf;
++
++
++ if(tx_buf != 0) {
++#if 0
++ printk("tx : ");
++ if(xfer->len > 10) {
++ for(i=0;i<10;i++)
++ printk("%x ",tx_buf[i]);
++ } else {
++ for(i=0;i<xfer->len;i++)
++ printk("%x ",tx_buf[i]);
++ }
++ printk("\n");
++#endif
++ for(i=0;i<xfer->len;i++) {
++ writeb(tx_buf[i], host->buff);
++ }
++ }
++ //Issue need clarify
++ udelay(1);
++ if(rx_buf != 0) {
++ for(i=0;i<xfer->len;i++) {
++ rx_buf[i] = readb(host->buff);
++ }
++#if 0
++ printk("rx : ");
++ if(xfer->len > 10) {
++ for(i=0;i<10;i++)
++ printk(" %x",rx_buf[i]);
++ } else {
++ for(i=0;i<xfer->len;i++)
++ printk(" %x",rx_buf[i]);
++ }
++ printk("\n");
++#endif
++ }
++ dev_dbg(host->dev,"old msg->actual_length %d , +len %d \n",msg->actual_length, xfer->len);
++ msg->actual_length += xfer->len;
++ dev_dbg(host->dev,"new msg->actual_length %d \n",msg->actual_length);
++// j++;
++
++ }
++
++// writel( SPI_CE_INACTIVE | readl(host->spi_data->ctrl_reg),host->spi_data->ctrl_reg);
++ fmc_spi_write(host, (fmc_spi_read(host, 0x00) & ~SPI_CMD_USER_MODE), 0x00);
++ msg->status = 0;
++
++ msg->complete(msg->context);
++
++// spin_unlock(&host->lock);
++ spin_unlock_irqrestore(&host->lock, flags);
++
++
++
++
++ return 0;
++
++}
++static void fmc_spi_cleanup(struct spi_device *spi)
++{
++ struct fmc_spi_host *host = spi_master_get_devdata(spi->master);
++ unsigned long flags;
++ dev_dbg(host->dev, "fmc_spi_cleanup() \n");
++
++ spin_lock_irqsave(&host->lock, flags);
++// if (host->stay == spi) {
++// host->stay = NULL;
++// cs_deactivate(host, spi);
++// }
++ spin_unlock_irqrestore(&host->lock, flags);
++}
++
++static int fmc_spi_probe(struct platform_device *pdev)
++{
++ struct resource *res0, *res1=0;
++ struct fmc_spi_host *host;
++ struct spi_master *master;
++ int err;
++
++ dev_dbg(&pdev->dev, "fmc_spi_probe() \n\n\n");
++
++ master = spi_alloc_master(&pdev->dev, sizeof(struct fmc_spi_host));
++ if (NULL == master) {
++ dev_err(&pdev->dev, "No memory for spi_master\n");
++ err = -ENOMEM;
++ goto err_nomem;
++ }
++ host = spi_master_get_devdata(master);
++ memset(host, 0, sizeof(struct fmc_spi_host));
++
++ res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res0) {
++ dev_err(&pdev->dev, "cannot get IORESOURCE_MEM 0\n");
++ err = -ENXIO;
++ goto err_no_io_res;
++ }
++
++ host->reg = ioremap(res0->start, resource_size(res0));
++ if (!host->reg) {
++ dev_err(&pdev->dev, "cannot remap register\n");
++ err = -EIO;
++ goto release_mem;
++ }
++
++ dev_dbg(&pdev->dev, "remap phy %x, virt %x \n",(u32)res0->start, (u32)host->reg);
++
++ res1 = platform_get_resource(pdev, IORESOURCE_IO, 0);
++ if (!res1) {
++ dev_err(&pdev->dev, "cannot get IORESOURCE_IO 0\n");
++ return -ENXIO;
++ }
++
++ host->buff = ioremap(res1->start, resource_size(res1));
++ if (!host->buff) {
++ dev_err(&pdev->dev, "cannot remap buffer \n");
++ err = -EIO;
++ goto release_mem;
++ }
++
++ dev_dbg(&pdev->dev, "remap io phy %x, virt %x \n",(u32)res1->start, (u32)host->buff);
++
++ host->master = spi_master_get(master);
++ host->master->bus_num = pdev->id;
++ host->master->num_chipselect = 1;
++ host->dev = &pdev->dev;
++
++ /* Setup the state for bitbang driver */
++ host->master->setup = fmc_spi_setup;
++ host->master->transfer = fmc_spi_transfer;
++ host->master->cleanup = fmc_spi_cleanup;
++
++ /* Find and claim our resources */
++ host->spi_data = pdev->dev.platform_data;
++
++ platform_set_drvdata(pdev, host);
++
++ /* Register our spi controller */
++ err = spi_register_master(host->master);
++ if (err) {
++ dev_err(&pdev->dev, "failed to register SPI master\n");
++ goto err_register;
++ }
++
++ dev_dbg(&pdev->dev, "fmc_spi_probe() return \n\n\n");
++
++ return 0;
++
++err_register:
++ spi_master_put(host->master);
++ iounmap(host->reg);
++ iounmap(host->buff);
++
++release_mem:
++ release_mem_region(res0->start, res0->end - res0->start + 1);
++ release_mem_region(res1->start, res1->end - res1->start + 1);
++
++err_no_io_res:
++ kfree(master);
++ kfree(host);
++
++err_nomem:
++ return err;
++
++}
++
++static int
++fmc_spi_remove(struct platform_device *pdev)
++{
++ struct resource *res0, *res1;
++ struct fmc_spi_host *host = platform_get_drvdata(pdev);
++
++ dev_dbg(host->dev, "fmc_spi_remove()\n");
++
++ if (!host)
++ return -1;
++
++ res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ res1 = platform_get_resource(pdev, IORESOURCE_IO, 0);
++ release_mem_region(res0->start, res0->end - res0->start + 1);
++ release_mem_region(res1->start, res1->end - res1->start + 1);
++ iounmap(host->reg);
++ iounmap(host->buff);
++
++ platform_set_drvdata(pdev, NULL);
++ spi_unregister_master(host->master);
++ spi_master_put(host->master);
++ return 0;
++}
++
++#ifdef CONFIG_PM
++static int
++fmc_spi_suspend(struct platform_device *pdev, pm_message_t msg)
++{
++ return 0;
++}
++
++static int
++fmc_spi_resume(struct platform_device *pdev)
++{
++ return 0;
++}
++#else
++#define fmc_spi_suspend NULL
++#define fmc_spi_resume NULL
++#endif
++
++static struct platform_driver fmc_spi_driver = {
++ .probe = fmc_spi_probe,
++ .remove = fmc_spi_remove,
++ .suspend = fmc_spi_suspend,
++ .resume = fmc_spi_resume,
++ .driver = {
++ .name = "fmc-spi",
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init
++fmc_spi_init(void)
++{
++ return platform_driver_register(&fmc_spi_driver);
++}
++
++static void __exit
++fmc_spi_exit(void)
++{
++ platform_driver_unregister(&fmc_spi_driver);
++}
++
++subsys_initcall(fmc_spi_init);
++//module_init(fmc_spi_init);
++module_exit(fmc_spi_exit);
++
++MODULE_DESCRIPTION("FMC SPI Driver");
++MODULE_AUTHOR("Ryan Chen");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
+index 3734dc9..ec88fc7 100644
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -652,54 +652,61 @@ static u8 *buf;
+ * Performance-sensitive or bulk transfer code should instead use
+ * spi_{async,sync}() calls with dma-safe buffers.
+ */
+-int spi_write_then_read(struct spi_device *spi,
+- const u8 *txbuf, unsigned n_tx,
+- u8 *rxbuf, unsigned n_rx)
+-{
+- static DEFINE_MUTEX(lock);
+-
+- int status;
+- struct spi_message message;
+- struct spi_transfer x;
+- u8 *local_buf;
+-
+- /* Use preallocated DMA-safe buffer. We can't avoid copying here,
+- * (as a pure convenience thing), but we can keep heap costs
+- * out of the hot path ...
+- */
+- if ((n_tx + n_rx) > SPI_BUFSIZ)
+- return -EINVAL;
+-
+- spi_message_init(&message);
+- memset(&x, 0, sizeof x);
+- x.len = n_tx + n_rx;
+- spi_message_add_tail(&x, &message);
+-
+- /* ... unless someone else is using the pre-allocated buffer */
+- if (!mutex_trylock(&lock)) {
+- local_buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL);
+- if (!local_buf)
+- return -ENOMEM;
+- } else
+- local_buf = buf;
+-
+- memcpy(local_buf, txbuf, n_tx);
+- x.tx_buf = local_buf;
+- x.rx_buf = local_buf;
+-
+- /* do the i/o */
+- status = spi_sync(spi, &message);
+- if (status == 0)
+- memcpy(rxbuf, x.rx_buf + n_tx, n_rx);
+-
+- if (x.tx_buf == buf)
+- mutex_unlock(&lock);
+- else
+- kfree(local_buf);
++ int spi_write_then_read(struct spi_device *spi,
++ const u8 *txbuf, unsigned n_tx,
++ u8 *rxbuf, unsigned n_rx)
++ {
++ static DEFINE_MUTEX(lock);
++
++ int status;
++ struct spi_message message;
++ struct spi_transfer x[2];
++ u8 *local_buf;
++
++ /* Use preallocated DMA-safe buffer. We can't avoid copying here,
++ * (as a pure convenience thing), but we can keep heap costs
++ * out of the hot path ...
++ */
++ if ((n_tx + n_rx) > SPI_BUFSIZ)
++ return -EINVAL;
++
++ spi_message_init(&message);
++ memset(x, 0, sizeof x);
++ if (n_tx) {
++ x[0].len = n_tx;
++ spi_message_add_tail(&x[0], &message);
++ }
++ if (n_rx) {
++ x[1].len = n_rx;
++ spi_message_add_tail(&x[1], &message);
++ }
++
++ /* ... unless someone else is using the pre-allocated buffer */
++ if (!mutex_trylock(&lock)) {
++ local_buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL);
++ if (!local_buf)
++ return -ENOMEM;
++ } else
++ local_buf = buf;
++
++ memcpy(local_buf, txbuf, n_tx);
++ x[0].tx_buf = local_buf;
++ x[1].rx_buf = local_buf + n_tx;
++
++ /* do the i/o */
++ status = spi_sync(spi, &message);
++ if (status == 0)
++ memcpy(rxbuf, x[1].rx_buf, n_rx);
++
++ if (x[0].tx_buf == buf)
++ mutex_unlock(&lock);
++ else
++ kfree(local_buf);
++
++ return status;
++ }
++ EXPORT_SYMBOL_GPL(spi_write_then_read);
+
+- return status;
+-}
+-EXPORT_SYMBOL_GPL(spi_write_then_read);
+
+ /*-------------------------------------------------------------------------*/
+
+diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
+index 289d81a..2cba323 100644
+--- a/drivers/usb/Kconfig
++++ b/drivers/usb/Kconfig
+@@ -56,6 +56,7 @@ config USB_ARCH_HAS_EHCI
+ default y if PPC_83xx
+ default y if SOC_AU1200
+ default y if ARCH_IXP4XX
++ default y if ARCH_ASPEED
+ default PCI
+
+ # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
+@@ -102,6 +103,8 @@ source "drivers/usb/wusbcore/Kconfig"
+
+ source "drivers/usb/host/Kconfig"
+
++source "drivers/usb/astuhci/Kconfig"
++
+ source "drivers/usb/musb/Kconfig"
+
+ source "drivers/usb/class/Kconfig"
+diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
+index 8b7c419..f6f180c 100644
+--- a/drivers/usb/Makefile
++++ b/drivers/usb/Makefile
+@@ -8,6 +8,8 @@ obj-$(CONFIG_USB) += core/
+
+ obj-$(CONFIG_USB_MON) += mon/
+
++obj-$(CONFIG_AST_USB_UHCI_HCD) += astuhci/
++
+ obj-$(CONFIG_PCI) += host/
+ obj-$(CONFIG_USB_EHCI_HCD) += host/
+ obj-$(CONFIG_USB_ISP116X_HCD) += host/
+diff --git a/drivers/usb/astuhci/Kconfig b/drivers/usb/astuhci/Kconfig
+new file mode 100644
+index 0000000..69c6d79
+--- /dev/null
++++ b/drivers/usb/astuhci/Kconfig
+@@ -0,0 +1,56 @@
++#
++# USB Host Controller Drivers
++#
++comment "AST USB Drivers"
++ depends on USB
++
++
++config AST_USB_UHCI_HCD
++ tristate "AST UHCI (USB 1.1) support"
++ depends on USB
++ ---help---
++ The AST Universal Host Controller Interface (UHCI) is standard for
++ USB 1.1 host controller hardware. It is an embedded HC based on AMBA bus.
++ You may want to read <file:Documentation/usb/uhci.txt>.
++
++ To compile this driver as a module, choose M here: the
++ module will be called uhci-hcd.
++
++choice
++ prompt "Config AST USB UHCI Number of Ports"
++ default AST_USB_UHCI_MULTIPORT_4
++
++config AST_USB_UHCI_MULTIPORT_1
++ bool "AST UHCI support 1 ports"
++ depends on AST_USB_UHCI_HCD
++
++config AST_USB_UHCI_MULTIPORT_2
++ bool "AST UHCI support 2 ports"
++ depends on AST_USB_UHCI_HCD
++
++config AST_USB_UHCI_MULTIPORT_4
++ bool "AST UHCI support 4 ports"
++ depends on AST_USB_UHCI_HCD
++
++endchoice
++
++config USB_EHCI_SPLIT_ISO
++ bool "Full speed ISO transactions (EXPERIMENTAL)"
++ depends on USB_EHCI_HCD
++ default n
++ ---help---
++ This code is new and hasn't been used with many different
++ EHCI or USB 2.0 transaction translator implementations.
++ It should work for ISO-OUT transfers, like audio.
++
++config USB_EHCI_ROOT_HUB_TT
++ bool "Root Hub Transaction Translators (EXPERIMENTAL)"
++ depends on USB_EHCI_HCD
++ ---help---
++ Some EHCI chips have vendor-specific extensions to integrate
++ transaction translators, so that no OHCI or UHCI companion
++ controller is needed. It's safe to say "y" even if your
++ controller doesn't support this feature.
++
++ This supports the EHCI implementation from TransDimension Inc.
++
+diff --git a/drivers/usb/astuhci/Makefile b/drivers/usb/astuhci/Makefile
+new file mode 100644
+index 0000000..6b858f7
+--- /dev/null
++++ b/drivers/usb/astuhci/Makefile
+@@ -0,0 +1,10 @@
++#
++# Makefile for USB Host Controller Drivers
++#
++
++ifeq ($(CONFIG_USB_DEBUG),y)
++ EXTRA_CFLAGS += -DDEBUG
++endif
++
++
++obj-$(CONFIG_AST_USB_UHCI_HCD) += uhci-hcd.o
+diff --git a/drivers/usb/astuhci/uhci-debug.c b/drivers/usb/astuhci/uhci-debug.c
+new file mode 100644
+index 0000000..c617644
+--- /dev/null
++++ b/drivers/usb/astuhci/uhci-debug.c
+@@ -0,0 +1,595 @@
++/********************************************************************************
++* File Name : uhci-debug.c
++*
++* port from uhci-debug.c
++* 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 <linux/kernel.h>
++#include <linux/debugfs.h>
++#include <linux/smp_lock.h>
++#include <asm/io.h>
++
++#include "uhci-hcd.h"
++
++#define uhci_debug_operations (* (const struct file_operations *) NULL)
++static struct dentry *uhci_debugfs_root;
++
++#ifdef DEBUG
++
++/* Handle REALLY large printks so we don't overflow buffers */
++static void lprintk(char *buf)
++{
++ char *p;
++
++ /* Just write one line at a time */
++ while (buf) {
++ p = strchr(buf, '\n');
++ if (p)
++ *p = 0;
++ printk(KERN_DEBUG "%s\n", buf);
++ buf = p;
++ if (buf)
++ buf++;
++ }
++}
++
++static int uhci_show_td(struct uhci_td *td, char *buf, int len, int space)
++{
++ char *out = buf;
++ char *spid;
++ u32 status, token;
++
++ /* Try to make sure there's enough memory */
++ if (len < 160)
++ return 0;
++
++ status = td_status(td);
++ out += sprintf(out, "%*s[%p] link (%08x) ", space, "", td, le32_to_cpu(td->link));
++ out += sprintf(out, "e%d %s%s%s%s%s%s%s%s%s%sLength=%x ",
++ ((status >> 27) & 3),
++ (status & TD_CTRL_SPD) ? "SPD " : "",
++ (status & TD_CTRL_LS) ? "LS " : "",
++ (status & TD_CTRL_IOC) ? "IOC " : "",
++ (status & TD_CTRL_ACTIVE) ? "Active " : "",
++ (status & TD_CTRL_STALLED) ? "Stalled " : "",
++ (status & TD_CTRL_DBUFERR) ? "DataBufErr " : "",
++ (status & TD_CTRL_BABBLE) ? "Babble " : "",
++ (status & TD_CTRL_NAK) ? "NAK " : "",
++ (status & TD_CTRL_CRCTIMEO) ? "CRC/Timeo " : "",
++ (status & TD_CTRL_BITSTUFF) ? "BitStuff " : "",
++ status & 0x7ff);
++
++ token = td_token(td);
++ switch (uhci_packetid(token)) {
++ case USB_PID_SETUP:
++ spid = "SETUP";
++ break;
++ case USB_PID_OUT:
++ spid = "OUT";
++ break;
++ case USB_PID_IN:
++ spid = "IN";
++ break;
++ default:
++ spid = "?";
++ break;
++ }
++
++ out += sprintf(out, "MaxLen=%x DT%d EndPt=%x Dev=%x, PID=%x(%s) ",
++ token >> 21,
++ ((token >> 19) & 1),
++ (token >> 15) & 15,
++ (token >> 8) & 127,
++ (token & 0xff),
++ spid);
++ out += sprintf(out, "(buf=%08x)\n", le32_to_cpu(td->buffer));
++
++ return out - buf;
++}
++
++static int uhci_show_urbp(struct urb_priv *urbp, char *buf, int len, int space)
++{
++ char *out = buf;
++ struct uhci_td *td;
++ int i, nactive, ninactive;
++ char *ptype;
++
++ if (len < 200)
++ return 0;
++
++ out += sprintf(out, "urb_priv [%p] ", urbp);
++ out += sprintf(out, "urb [%p] ", urbp->urb);
++ out += sprintf(out, "qh [%p] ", urbp->qh);
++ out += sprintf(out, "Dev=%d ", usb_pipedevice(urbp->urb->pipe));
++ out += sprintf(out, "EP=%x(%s) ", usb_pipeendpoint(urbp->urb->pipe),
++ (usb_pipein(urbp->urb->pipe) ? "IN" : "OUT"));
++
++ switch (usb_pipetype(urbp->urb->pipe)) {
++ case PIPE_ISOCHRONOUS: ptype = "ISO"; break;
++ case PIPE_INTERRUPT: ptype = "INT"; break;
++ case PIPE_BULK: ptype = "BLK"; break;
++ default:
++ case PIPE_CONTROL: ptype = "CTL"; break;
++ }
++
++ out += sprintf(out, "%s%s", ptype, (urbp->fsbr ? " FSBR" : ""));
++ out += sprintf(out, " Actlen=%d", urbp->urb->actual_length);
++
++ if (urbp->urb->unlinked)
++ out += sprintf(out, " Unlinked=%d", urbp->urb->unlinked);
++ out += sprintf(out, "\n");
++
++ i = nactive = ninactive = 0;
++ list_for_each_entry(td, &urbp->td_list, list) {
++ if (urbp->qh->type != USB_ENDPOINT_XFER_ISOC &&
++ (++i <= 10 || debug > 2)) {
++ out += sprintf(out, "%*s%d: ", space + 2, "", i);
++ out += uhci_show_td(td, out, len - (out - buf), 0);
++ } else {
++ if (td_status(td) & TD_CTRL_ACTIVE)
++ ++nactive;
++ else
++ ++ninactive;
++ }
++ }
++ if (nactive + ninactive > 0)
++ out += sprintf(out, "%*s[skipped %d inactive and %d active "
++ "TDs]\n",
++ space, "", ninactive, nactive);
++
++ return out - buf;
++}
++
++static int uhci_show_qh(struct uhci_hcd *uhci,
++ struct uhci_qh *qh, char *buf, int len, int space)
++{
++ char *out = buf;
++ int i, nurbs;
++ __le32 element = qh_element(qh);
++ char *qtype;
++
++ /* Try to make sure there's enough memory */
++ if (len < 80 * 7)
++ return 0;
++
++ switch (qh->type) {
++ case USB_ENDPOINT_XFER_ISOC: qtype = "ISO"; break;
++ case USB_ENDPOINT_XFER_INT: qtype = "INT"; break;
++ case USB_ENDPOINT_XFER_BULK: qtype = "BLK"; break;
++ case USB_ENDPOINT_XFER_CONTROL: qtype = "CTL"; break;
++ default: qtype = "Skel" ; break;
++ }
++
++ out += sprintf(out, "%*s[%p] %s QH link (%08x) element (%08x)\n",
++ space, "", qh, qtype,
++ le32_to_cpu(qh->link), le32_to_cpu(element));
++ if (qh->type == USB_ENDPOINT_XFER_ISOC)
++ out += sprintf(out, "%*s period %d phase %d load %d us, "
++ "frame %x desc [%p]\n",
++ space, "", qh->period, qh->phase, qh->load,
++ qh->iso_frame, qh->iso_packet_desc);
++ else if (qh->type == USB_ENDPOINT_XFER_INT)
++ out += sprintf(out, "%*s period %d phase %d load %d us\n",
++ space, "", qh->period, qh->phase, qh->load);
++
++ if (element & UHCI_PTR_QH)
++ out += sprintf(out, "%*s Element points to QH (bug?)\n", space, "");
++
++ if (element & UHCI_PTR_DEPTH)
++ out += sprintf(out, "%*s Depth traverse\n", space, "");
++
++ if (element & cpu_to_le32(8))
++ out += sprintf(out, "%*s Bit 3 set (bug?)\n", space, "");
++
++ if (!(element & ~(UHCI_PTR_QH | UHCI_PTR_DEPTH)))
++ out += sprintf(out, "%*s Element is NULL (bug?)\n", space, "");
++
++ if (list_empty(&qh->queue)) {
++ out += sprintf(out, "%*s queue is empty\n", space, "");
++ if (qh == uhci->skel_async_qh)
++ out += uhci_show_td(uhci->term_td, out,
++ len - (out - buf), 0);
++ } else {
++ struct urb_priv *urbp = list_entry(qh->queue.next,
++ struct urb_priv, node);
++ struct uhci_td *td = list_entry(urbp->td_list.next,
++ struct uhci_td, list);
++
++ if (element != LINK_TO_TD(td))
++ out += sprintf(out, "%*s Element != First TD\n",
++ space, "");
++ i = nurbs = 0;
++ list_for_each_entry(urbp, &qh->queue, node) {
++ if (++i <= 10)
++ out += uhci_show_urbp(urbp, out,
++ len - (out - buf), space + 2);
++ else
++ ++nurbs;
++ }
++ if (nurbs > 0)
++ out += sprintf(out, "%*s Skipped %d URBs\n",
++ space, "", nurbs);
++ }
++
++ if (qh->dummy_td) {
++ out += sprintf(out, "%*s Dummy TD\n", space, "");
++ out += uhci_show_td(qh->dummy_td, out, len - (out - buf), 0);
++ }
++
++ return out - buf;
++}
++
++static int uhci_show_sc(int port, unsigned short status, char *buf, int len)
++{
++ char *out = buf;
++
++ /* Try to make sure there's enough memory */
++ if (len < 160)
++ return 0;
++
++ out += sprintf(out, " stat%d = %04x %s%s%s%s%s%s%s%s%s%s\n",
++ port,
++ status,
++ (status & USBPORTSC_SUSP) ? " Suspend" : "",
++ (status & USBPORTSC_OCC) ? " OverCurrentChange" : "",
++ (status & USBPORTSC_OC) ? " OverCurrent" : "",
++ (status & USBPORTSC_PR) ? " Reset" : "",
++ (status & USBPORTSC_LSDA) ? " LowSpeed" : "",
++ (status & USBPORTSC_RD) ? " ResumeDetect" : "",
++ (status & USBPORTSC_PEC) ? " EnableChange" : "",
++ (status & USBPORTSC_PE) ? " Enabled" : "",
++ (status & USBPORTSC_CSC) ? " ConnectChange" : "",
++ (status & USBPORTSC_CCS) ? " Connected" : "");
++
++ return out - buf;
++}
++
++static int uhci_show_root_hub_state(struct uhci_hcd *uhci, char *buf, int len)
++{
++ char *out = buf;
++ char *rh_state;
++
++ /* Try to make sure there's enough memory */
++ if (len < 60)
++ return 0;
++
++ switch (uhci->rh_state) {
++ case UHCI_RH_RESET:
++ rh_state = "reset"; break;
++ case UHCI_RH_SUSPENDED:
++ rh_state = "suspended"; break;
++ case UHCI_RH_AUTO_STOPPED:
++ rh_state = "auto-stopped"; break;
++ case UHCI_RH_RESUMING:
++ rh_state = "resuming"; break;
++ case UHCI_RH_SUSPENDING:
++ rh_state = "suspending"; break;
++ case UHCI_RH_RUNNING:
++ rh_state = "running"; break;
++ case UHCI_RH_RUNNING_NODEVS:
++ rh_state = "running, no devs"; break;
++ default:
++ rh_state = "?"; break;
++ }
++ out += sprintf(out, "Root-hub state: %s FSBR: %d\n",
++ rh_state, uhci->fsbr_is_on);
++ return out - buf;
++}
++
++static int uhci_show_status(struct uhci_hcd *uhci, char *buf, int len)
++{
++ char *out = buf;
++ unsigned long io_addr = uhci->io_addr;
++ unsigned short usbcmd, usbstat, usbint, usbfrnum;
++ unsigned int flbaseadd;
++ unsigned char sof;
++ unsigned short portsc1, portsc2;
++
++ /* Try to make sure there's enough memory */
++ if (len < 80 * 9)
++ return 0;
++
++ usbcmd = inw(io_addr + 0);
++ usbstat = inw(io_addr + 2);
++ usbint = inw(io_addr + 4);
++ usbfrnum = inw(io_addr + 6);
++ flbaseadd = inl(io_addr + 8);
++ sof = inb(io_addr + 12);
++ portsc1 = inw(io_addr + 16);
++ portsc2 = inw(io_addr + 18);
++
++ out += sprintf(out, " usbcmd = %04x %s%s%s%s%s%s%s%s\n",
++ usbcmd,
++ (usbcmd & USBCMD_MAXP) ? "Maxp64 " : "Maxp32 ",
++ (usbcmd & USBCMD_CF) ? "CF " : "",
++ (usbcmd & USBCMD_SWDBG) ? "SWDBG " : "",
++ (usbcmd & USBCMD_FGR) ? "FGR " : "",
++ (usbcmd & USBCMD_EGSM) ? "EGSM " : "",
++ (usbcmd & USBCMD_GRESET) ? "GRESET " : "",
++ (usbcmd & USBCMD_HCRESET) ? "HCRESET " : "",
++ (usbcmd & USBCMD_RS) ? "RS " : "");
++
++ out += sprintf(out, " usbstat = %04x %s%s%s%s%s%s\n",
++ usbstat,
++ (usbstat & USBSTS_HCH) ? "HCHalted " : "",
++ (usbstat & USBSTS_HCPE) ? "HostControllerProcessError " : "",
++ (usbstat & USBSTS_HSE) ? "HostSystemError " : "",
++ (usbstat & USBSTS_RD) ? "ResumeDetect " : "",
++ (usbstat & USBSTS_ERROR) ? "USBError " : "",
++ (usbstat & USBSTS_USBINT) ? "USBINT " : "");
++
++ out += sprintf(out, " usbint = %04x\n", usbint);
++ out += sprintf(out, " usbfrnum = (%d)%03x\n", (usbfrnum >> 10) & 1,
++ 0xfff & (4*(unsigned int)usbfrnum));
++ out += sprintf(out, " flbaseadd = %08x\n", flbaseadd);
++ out += sprintf(out, " sof = %02x\n", sof);
++ out += uhci_show_sc(1, portsc1, out, len - (out - buf));
++ out += uhci_show_sc(2, portsc2, out, len - (out - buf));
++ out += sprintf(out, "Most recent frame: %x (%d) "
++ "Last ISO frame: %x (%d)\n",
++ uhci->frame_number, uhci->frame_number & 1023,
++ uhci->last_iso_frame, uhci->last_iso_frame & 1023);
++
++ return out - buf;
++}
++
++static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
++{
++ char *out = buf;
++ int i, j;
++ struct uhci_qh *qh;
++ struct uhci_td *td;
++ struct list_head *tmp, *head;
++ int nframes, nerrs;
++ __le32 link;
++ __le32 fsbr_link;
++
++ static const char * const qh_names[] = {
++ "unlink", "iso", "int128", "int64", "int32", "int16",
++ "int8", "int4", "int2", "async", "term"
++ };
++
++ out += uhci_show_root_hub_state(uhci, out, len - (out - buf));
++ out += sprintf(out, "HC status\n");
++ out += uhci_show_status(uhci, out, len - (out - buf));
++
++ out += sprintf(out, "Periodic load table\n");
++ for (i = 0; i < MAX_PHASE; ++i) {
++ out += sprintf(out, "\t%d", uhci->load[i]);
++ if (i % 8 == 7)
++ *out++ = '\n';
++ }
++ out += sprintf(out, "Total: %d, #INT: %d, #ISO: %d\n",
++ uhci->total_load,
++ uhci_to_hcd(uhci)->self.bandwidth_int_reqs,
++ uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs);
++ if (debug <= 1)
++ return out - buf;
++
++ out += sprintf(out, "Frame List\n");
++ nframes = 10;
++ nerrs = 0;
++ for (i = 0; i < UHCI_NUMFRAMES; ++i) {
++ __le32 qh_dma;
++
++ j = 0;
++ td = uhci->frame_cpu[i];
++ link = uhci->frame[i];
++ if (!td)
++ goto check_link;
++
++ if (nframes > 0) {
++ out += sprintf(out, "- Frame %d -> (%08x)\n",
++ i, le32_to_cpu(link));
++ j = 1;
++ }
++
++ head = &td->fl_list;
++ tmp = head;
++ do {
++ td = list_entry(tmp, struct uhci_td, fl_list);
++ tmp = tmp->next;
++ if (link != LINK_TO_TD(td)) {
++ if (nframes > 0)
++ out += sprintf(out, " link does "
++ "not match list entry!\n");
++ else
++ ++nerrs;
++ }
++ if (nframes > 0)
++ out += uhci_show_td(td, out,
++ len - (out - buf), 4);
++ link = td->link;
++ } while (tmp != head);
++
++check_link:
++ qh_dma = uhci_frame_skel_link(uhci, i);
++ if (link != qh_dma) {
++ if (nframes > 0) {
++ if (!j) {
++ out += sprintf(out,
++ "- Frame %d -> (%08x)\n",
++ i, le32_to_cpu(link));
++ j = 1;
++ }
++ out += sprintf(out, " link does not match "
++ "QH (%08x)!\n", le32_to_cpu(qh_dma));
++ } else
++ ++nerrs;
++ }
++ nframes -= j;
++ }
++ if (nerrs > 0)
++ out += sprintf(out, "Skipped %d bad links\n", nerrs);
++
++ out += sprintf(out, "Skeleton QHs\n");
++
++ fsbr_link = 0;
++ for (i = 0; i < UHCI_NUM_SKELQH; ++i) {
++ int cnt = 0;
++
++ qh = uhci->skelqh[i];
++ out += sprintf(out, "- skel_%s_qh\n", qh_names[i]); \
++ out += uhci_show_qh(uhci, qh, out, len - (out - buf), 4);
++
++ /* Last QH is the Terminating QH, it's different */
++ if (i == SKEL_TERM) {
++ if (qh_element(qh) != LINK_TO_TD(uhci->term_td))
++ out += sprintf(out, " skel_term_qh element is not set to term_td!\n");
++ link = fsbr_link;
++ if (!link)
++ link = LINK_TO_QH(uhci->skel_term_qh);
++ goto check_qh_link;
++ }
++
++ head = &qh->node;
++ tmp = head->next;
++
++ while (tmp != head) {
++ qh = list_entry(tmp, struct uhci_qh, node);
++ tmp = tmp->next;
++ if (++cnt <= 10)
++ out += uhci_show_qh(uhci, qh, out,
++ len - (out - buf), 4);
++ if (!fsbr_link && qh->skel >= SKEL_FSBR)
++ fsbr_link = LINK_TO_QH(qh);
++ }
++ if ((cnt -= 10) > 0)
++ out += sprintf(out, " Skipped %d QHs\n", cnt);
++
++ link = UHCI_PTR_TERM;
++ if (i <= SKEL_ISO)
++ ;
++ else if (i < SKEL_ASYNC)
++ link = LINK_TO_QH(uhci->skel_async_qh);
++ else if (!uhci->fsbr_is_on)
++ ;
++ else
++ link = LINK_TO_QH(uhci->skel_term_qh);
++check_qh_link:
++ if (qh->link != link)
++ out += sprintf(out, " last QH not linked to next skeleton!\n");
++ }
++
++ return out - buf;
++}
++
++#ifdef CONFIG_DEBUG_FS
++
++#define MAX_OUTPUT (64 * 1024)
++
++struct uhci_debug {
++ int size;
++ char *data;
++};
++
++static int uhci_debug_open(struct inode *inode, struct file *file)
++{
++ struct uhci_hcd *uhci = inode->i_private;
++ struct uhci_debug *up;
++ int ret = -ENOMEM;
++ unsigned long flags;
++
++ lock_kernel();
++ up = kmalloc(sizeof(*up), GFP_KERNEL);
++ if (!up)
++ goto out;
++
++ up->data = kmalloc(MAX_OUTPUT, GFP_KERNEL);
++ if (!up->data) {
++ kfree(up);
++ goto out;
++ }
++
++ up->size = 0;
++ spin_lock_irqsave(&uhci->lock, flags);
++ if (uhci->is_initialized)
++ up->size = uhci_sprint_schedule(uhci, up->data, MAX_OUTPUT);
++ spin_unlock_irqrestore(&uhci->lock, flags);
++
++ file->private_data = up;
++
++ ret = 0;
++out:
++ unlock_kernel();
++ return ret;
++}
++
++static loff_t uhci_debug_lseek(struct file *file, loff_t off, int whence)
++{
++ struct uhci_debug *up;
++ loff_t new = -1;
++
++ lock_kernel();
++ up = file->private_data;
++
++ switch (whence) {
++ case 0:
++ new = off;
++ break;
++ case 1:
++ new = file->f_pos + off;
++ break;
++ }
++ if (new < 0 || new > up->size) {
++ unlock_kernel();
++ return -EINVAL;
++ }
++ unlock_kernel();
++ return (file->f_pos = new);
++}
++
++static ssize_t uhci_debug_read(struct file *file, char __user *buf,
++ size_t nbytes, loff_t *ppos)
++{
++ struct uhci_debug *up = file->private_data;
++ return simple_read_from_buffer(buf, nbytes, ppos, up->data, up->size);
++}
++
++static int uhci_debug_release(struct inode *inode, struct file *file)
++{
++ struct uhci_debug *up = file->private_data;
++
++ kfree(up->data);
++ kfree(up);
++
++ return 0;
++}
++
++#undef uhci_debug_operations
++static const struct file_operations uhci_debug_operations = {
++ .owner = THIS_MODULE,
++ .open = uhci_debug_open,
++ .llseek = uhci_debug_lseek,
++ .read = uhci_debug_read,
++ .release = uhci_debug_release,
++};
++
++#endif /* CONFIG_DEBUG_FS */
++
++#else /* DEBUG */
++
++static inline void lprintk(char *buf)
++{}
++
++static inline int uhci_show_qh(struct uhci_hcd *uhci,
++ struct uhci_qh *qh, char *buf, int len, int space)
++{
++ return 0;
++}
++
++static inline int uhci_sprint_schedule(struct uhci_hcd *uhci,
++ char *buf, int len)
++{
++ return 0;
++}
++
++#endif
+diff --git a/drivers/usb/astuhci/uhci-hcd.c b/drivers/usb/astuhci/uhci-hcd.c
+new file mode 100644
+index 0000000..fcfb6dbb
+--- /dev/null
++++ b/drivers/usb/astuhci/uhci-hcd.c
+@@ -0,0 +1,1229 @@
++/********************************************************************************
++* File Name : uhci-hcd.c
++*
++* port from uhci-hcd.c
++* 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 <linux/module.h>
++#include <linux/pci.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/ioport.h>
++#include <linux/slab.h>
++#include <linux/errno.h>
++#include <linux/unistd.h>
++#include <linux/interrupt.h>
++#include <linux/spinlock.h>
++#include <linux/debugfs.h>
++#include <linux/pm.h>
++#include <linux/dmapool.h>
++#include <linux/dma-mapping.h>
++#include <linux/usb.h>
++#include <linux/bitops.h>
++#include <linux/dmi.h>
++#include <linux/platform_device.h>
++
++#include <asm/uaccess.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/system.h>
++
++#include <mach/platform.h>
++#include "../core/hcd.h"
++#include "uhci-hcd.h"
++//#include "pci-quirks.h"
++
++/*
++ * Version Information
++ */
++#define DRIVER_AUTHOR "Linus 'Frodo Rabbit' Torvalds, Johannes Erdfelt, \
++Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber, \
++Alan Stern"
++#define DRIVER_DESC "USB Universal Host Controller Interface driver"
++
++/* for flakey hardware, ignore overcurrent indicators */
++static int ignore_oc;
++module_param(ignore_oc, bool, S_IRUGO);
++MODULE_PARM_DESC(ignore_oc, "ignore hardware overcurrent indications");
++
++/*
++ * debug = 0, no debugging messages
++ * debug = 1, dump failed URBs except for stalls
++ * debug = 2, dump all failed URBs (including stalls)
++ * show all queues in /debug/uhci/[pci_addr]
++ * debug = 3, show all TDs in URBs when dumping
++ */
++#ifdef DEBUG
++#define DEBUG_CONFIGURED 1
++static int debug = 1;
++module_param(debug, int, S_IRUGO | S_IWUSR);
++MODULE_PARM_DESC(debug, "Debug level");
++
++#else
++#define DEBUG_CONFIGURED 0
++#define debug 0
++#endif
++
++
++
++static char *errbuf;
++#define ERRBUF_LEN (32 * 1024)
++
++static struct kmem_cache *uhci_up_cachep; /* urb_priv */
++
++void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state);
++void wakeup_rh(struct uhci_hcd *uhci);
++void uhci_get_current_frame_number(struct uhci_hcd *uhci);
++
++void uhci_reset_hc(struct uhci_hcd *uhci);
++int uhci_check_and_reset_hc(struct uhci_hcd *uhci);
++
++/*
++ * Calculate the link pointer DMA value for the first Skeleton QH in a frame.
++ */
++static __le32 uhci_frame_skel_link(struct uhci_hcd *uhci, int frame)
++{
++ int skelnum;
++
++ /*
++ * The interrupt queues will be interleaved as evenly as possible.
++ * There's not much to be done about period-1 interrupts; they have
++ * to occur in every frame. But we can schedule period-2 interrupts
++ * in odd-numbered frames, period-4 interrupts in frames congruent
++ * to 2 (mod 4), and so on. This way each frame only has two
++ * interrupt QHs, which will help spread out bandwidth utilization.
++ *
++ * ffs (Find First bit Set) does exactly what we need:
++ * 1,3,5,... => ffs = 0 => use period-2 QH = skelqh[8],
++ * 2,6,10,... => ffs = 1 => use period-4 QH = skelqh[7], etc.
++ * ffs >= 7 => not on any high-period queue, so use
++ * period-1 QH = skelqh[9].
++ * Add in UHCI_NUMFRAMES to insure at least one bit is set.
++ */
++ skelnum = 8 - (int) __ffs(frame | UHCI_NUMFRAMES);
++ if (skelnum <= 1)
++ skelnum = 9;
++ return LINK_TO_QH(uhci->skelqh[skelnum]);
++}
++
++#include "uhci-debug.c"
++#include "uhci-q.c"
++#include "uhci-hub.c"
++
++/*
++ * Finish up a host controller reset and update the recorded state.
++ */
++void finish_reset(struct uhci_hcd *uhci)
++{
++ int port;
++
++ /* HCRESET doesn't affect the Suspend, Reset, and Resume Detect
++ * bits in the port status and control registers.
++ * We have to clear them by hand.
++ */
++ for (port = 0; port < uhci->rh_numports; ++port)
++ writel(0, uhci->regbase + USBPORTSC1 + (port * 1));
++
++ uhci->port_c_suspend = uhci->resuming_ports = 0;
++ uhci->rh_state = UHCI_RH_RESET;
++ uhci->is_stopped = UHCI_IS_STOPPED;
++ uhci_to_hcd(uhci)->state = HC_STATE_HALT;
++ uhci_to_hcd(uhci)->poll_rh = 0;
++
++ uhci->dead = 0; /* Full reset resurrects the controller */
++}
++
++/*
++ * Last rites for a defunct/nonfunctional controller
++ * or one we don't want to use any more.
++ */
++void uhci_hc_died(struct uhci_hcd *uhci)
++{
++ uhci_get_current_frame_number(uhci);
++//yriver
++// uhci_reset_hc(to_pci_dev(uhci_dev(uhci)), uhci->io_addr);
++ uhci_reset_hc(uhci);
++ finish_reset(uhci);
++ uhci->dead = 1;
++
++ /* The current frame may already be partway finished */
++ ++uhci->frame_number;
++}
++
++/*
++ * Initialize a controller that was newly discovered or has lost power
++ * or otherwise been reset while it was suspended. In none of these cases
++ * can we be sure of its previous state.
++ */
++void check_and_reset_hc(struct uhci_hcd *uhci)
++{
++//yriver
++// if (uhci_check_and_reset_hc(to_pci_dev(uhci_dev(uhci)), uhci->io_addr))
++ if (uhci_check_and_reset_hc(uhci))
++ finish_reset(uhci);
++}
++
++/*
++ * Store the basic register settings needed by the controller.
++ */
++void configure_hc(struct uhci_hcd *uhci)
++{
++ /* Set the frame length to the default: 1 ms exactly */
++// outb(USBSOF_DEFAULT, uhci->io_addr + USBSOF);
++ writel(USBSOF_DEFAULT, uhci->regbase + USBSOF);
++
++ /* Store the frame list base address */
++// outl(uhci->frame_dma_handle, uhci->io_addr + USBFLBASEADD);
++ writel(uhci->frame_dma_handle, uhci->regbase + USBFLBASEADD);
++
++ /* Set the current frame number */
++// outw(uhci->frame_number & UHCI_MAX_SOF_NUMBER,
++// uhci->io_addr + USBFRNUM);
++ writel(uhci->frame_number & UHCI_MAX_SOF_NUMBER,
++ uhci->regbase + USBFRNUM);
++
++ /* Mark controller as not halted before we enable interrupts */
++ uhci_to_hcd(uhci)->state = HC_STATE_SUSPENDED;
++ mb();
++ /* Enable PIRQ */
++//yriver
++// pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
++// USBLEGSUP_DEFAULT);
++}
++
++
++int resume_detect_interrupts_are_broken(struct uhci_hcd *uhci)
++{
++/*
++
++ int port;
++
++
++ if (ignore_oc)
++ return 1;
++
++ switch (to_pci_dev(uhci_dev(uhci))->vendor) {
++ default:
++ break;
++
++ case PCI_VENDOR_ID_GENESYS:
++ return 1;
++
++ case PCI_VENDOR_ID_INTEL:
++ for (port = 0; port < uhci->rh_numports; ++port) {
++ if (inw(uhci->io_addr + USBPORTSC1 + port * 2) &
++ USBPORTSC_OC)
++ return 1;
++ }
++ break;
++ }
++*/
++ return 0;
++}
++
++int global_suspend_mode_is_broken(struct uhci_hcd *uhci)
++{
++ int port;
++ const char *sys_info;
++ static char bad_Asus_board[] = "A7V8X";
++
++ /* One of Asus's motherboards has a bug which causes it to
++ * wake up immediately from suspend-to-RAM if any of the ports
++ * are connected. In such cases we will not set EGSM.
++ */
++ sys_info = dmi_get_system_info(DMI_BOARD_NAME);
++ if (sys_info && !strcmp(sys_info, bad_Asus_board)) {
++ for (port = 0; port < uhci->rh_numports; ++port) {
++//yriver
++// if (inw(uhci->io_addr + USBPORTSC1 + port * 2) &
++ if (readl(uhci->regbase + USBPORTSC1 + port * 1) &
++ USBPORTSC_CCS)
++ return 1;
++ }
++ }
++
++ return 0;
++}
++
++void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state)
++__releases(uhci->lock)
++__acquires(uhci->lock)
++{
++ int auto_stop;
++ int int_enable, egsm_enable, wakeup_enable;
++ struct usb_device *rhdev = uhci_to_hcd(uhci)->self.root_hub;
++
++ auto_stop = (new_state == UHCI_RH_AUTO_STOPPED);
++ dev_dbg(&rhdev->dev, "%s%s\n", __func__,
++ (auto_stop ? " (auto-stop)" : ""));
++
++ /* Start off by assuming Resume-Detect interrupts and EGSM work
++ * and that remote wakeups should be enabled.
++ */
++ egsm_enable = USBCMD_EGSM;
++ uhci->RD_enable = 1;
++ int_enable = USBINTR_RESUME;
++ wakeup_enable = 1;
++/*
++ if (auto_stop) {
++ if (!device_may_wakeup(&rhdev->dev))
++ int_enable = 0;
++
++ } else {
++#ifdef CONFIG_PM
++ if (!rhdev->do_remote_wakeup)
++ wakeup_enable = 0;
++#endif
++ }
++
++ if (!wakeup_enable || global_suspend_mode_is_broken(uhci))
++ egsm_enable = 0;
++*/
++ /* If we're ignoring wakeup events then there's no reason to
++ * enable Resume-Detect interrupts. We also shouldn't enable
++ * them if they are broken or disallowed.
++ *
++ * This logic may lead us to enabling RD but not EGSM. The UHCI
++ * spec foolishly says that RD works only when EGSM is on, but
++ * there's no harm in enabling it anyway -- perhaps some chips
++ * will implement it!
++ */
++//yriver
++// if (!wakeup_enable || resume_detect_interrupts_are_broken(uhci) ||
++// !int_enable)
++// uhci->RD_enable = int_enable = 0;
++
++// outw(int_enable, uhci->io_addr + USBINTR);
++// outw(egsm_enable | USBCMD_CF, uhci->io_addr + USBCMD);
++ writel(int_enable, uhci->regbase + USBINTR);
++// writel(egsm_enable | USBCMD_CF, uhci->regbase + USBCMD);
++ writel(USBCMD_EGSM | USBCMD_CF, uhci->regbase + USBCMD);
++ mb();
++ udelay(5);
++
++ /* If we're auto-stopping then no devices have been attached
++ * for a while, so there shouldn't be any active URBs and the
++ * controller should stop after a few microseconds. Otherwise
++ * we will give the controller one frame to stop.
++ */
++//yriver
++// if (!auto_stop && !(inw(uhci->io_addr + USBSTS) & USBSTS_HCH)) {
++ if (!auto_stop && !(readl(uhci->regbase + USBSTS) & USBSTS_HCH)) {
++ uhci->rh_state = UHCI_RH_SUSPENDING;
++ spin_unlock_irq(&uhci->lock);
++ msleep(1);
++ spin_lock_irq(&uhci->lock);
++ if (uhci->dead)
++ return;
++ }
++//yriver
++// if (!(inw(uhci->io_addr + USBSTS) & USBSTS_HCH))
++// if (!(readl(uhci->regbase + USBSTS) & USBSTS_HCH))
++// dev_warn(uhci_dev(uhci), "Controller not stopped yet!\n");
++
++ uhci_get_current_frame_number(uhci);
++
++ uhci->rh_state = new_state;
++ uhci->is_stopped = UHCI_IS_STOPPED;
++
++ /* If interrupts don't work and remote wakeup is enabled then
++ * the suspended root hub needs to be polled.
++ */
++//yriver
++// uhci_to_hcd(uhci)->poll_rh = (!int_enable && wakeup_enable);
++ uhci_to_hcd(uhci)->poll_rh = !int_enable;
++
++ uhci_scan_schedule(uhci);
++ uhci_fsbr_off(uhci);
++}
++
++void start_rh(struct uhci_hcd *uhci)
++{
++ uhci_to_hcd(uhci)->state = HC_STATE_RUNNING;
++ uhci->is_stopped = 0;
++ /* Mark it configured and running with a 64-byte max packet.
++ * All interrupts are enabled, even though RESUME won't do anything.
++ */
++//yriver
++// outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, uhci->io_addr + USBCMD);
++// outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP,
++// uhci->io_addr + USBINTR);
++
++ writel(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, uhci->regbase + USBCMD);
++ writel(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP,
++ uhci->regbase + USBINTR);
++ mb();
++ uhci->rh_state = UHCI_RH_RUNNING;
++ uhci_to_hcd(uhci)->poll_rh = 1;
++}
++
++void wakeup_rh(struct uhci_hcd *uhci)
++__releases(uhci->lock)
++__acquires(uhci->lock)
++{
++ dev_dbg(&uhci_to_hcd(uhci)->self.root_hub->dev,
++ "%s%s\n", __func__,
++ uhci->rh_state == UHCI_RH_AUTO_STOPPED ?
++ " (auto-start)" : "");
++
++ /* If we are auto-stopped then no devices are attached so there's
++ * no need for wakeup signals. Otherwise we send Global Resume
++ * for 20 ms.
++ */
++ if (uhci->rh_state == UHCI_RH_SUSPENDED) {
++ uhci->rh_state = UHCI_RH_RESUMING;
++ }
++
++ start_rh(uhci);
++
++ /* Restart root hub polling */
++ mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies);
++}
++
++void wakeup_hc(struct uhci_hcd *uhci) {
++// printk("wake_uhci\n");
++ wakeup_rh(uhci);
++
++
++}
++
++irqreturn_t uhci_irq(struct usb_hcd *hcd)
++{
++ struct uhci_hcd *uhci = hcd_to_uhci(hcd);
++ unsigned short status;
++
++ /*
++ * Read the interrupt status, and write it back to clear the
++ * interrupt cause. Contrary to the UHCI specification, the
++ * "HC Halted" status bit is persistent: it is RO, not R/WC.
++ */
++//yriver
++// status = inw(uhci->io_addr + USBSTS);
++ status = readl(uhci->regbase + USBSTS);
++ if (!(status & ~USBSTS_HCH)) /* shared interrupt, not mine */
++ return IRQ_NONE;
++// outw(status, uhci->io_addr + USBSTS); /* Clear it */
++ writel(status, uhci->regbase + USBSTS); /* Clear it */
++
++ if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) {
++ if (status & USBSTS_HSE)
++ dev_err(uhci_dev(uhci), "host system error, "
++ "PCI problems?\n");
++ if (status & USBSTS_HCPE)
++ dev_err(uhci_dev(uhci), "host controller process "
++ "error, something bad happened!\n");
++ if (status & USBSTS_HCH) {
++ spin_lock(&uhci->lock);
++ if (uhci->rh_state >= UHCI_RH_RUNNING) {
++ dev_err(uhci_dev(uhci),
++ "host controller halted, "
++ "very bad!\n");
++ if (debug > 1 && errbuf) {
++ /* Print the schedule for debugging */
++ uhci_sprint_schedule(uhci,
++ errbuf, ERRBUF_LEN);
++ lprintk(errbuf);
++ }
++ uhci_hc_died(uhci);
++
++ /* Force a callback in case there are
++ * pending unlinks */
++//yriver
++// mod_timer(&hcd->rh_timer, jiffies);
++ mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies);
++ }
++ spin_unlock(&uhci->lock);
++ }
++ }
++
++ if (status & USBSTS_RD)
++ usb_hcd_poll_rh_status(hcd);
++ else {
++ spin_lock(&uhci->lock);
++ uhci_scan_schedule(uhci);
++ spin_unlock(&uhci->lock);
++ }
++
++ return IRQ_HANDLED;
++}
++
++/*
++ * Store the current frame number in uhci->frame_number if the controller
++ * is runnning. Expand from 11 bits (of which we use only 10) to a
++ * full-sized integer.
++ *
++ * Like many other parts of the driver, this code relies on being polled
++ * more than once per second as long as the controller is running.
++ */
++void uhci_get_current_frame_number(struct uhci_hcd *uhci)
++{
++ if (!uhci->is_stopped) {
++ unsigned delta;
++//yriver
++// delta = (inw(uhci->io_addr + USBFRNUM) - uhci->frame_number) &
++// (UHCI_NUMFRAMES - 1);
++ delta = (readl(uhci->regbase + USBFRNUM) - uhci->frame_number) &
++ (UHCI_NUMFRAMES - 1);
++ uhci->frame_number += delta;
++ }
++}
++
++/*
++ * De-allocate all resources
++ */
++void release_uhci(struct uhci_hcd *uhci)
++{
++ int i;
++
++ if (DEBUG_CONFIGURED) {
++ spin_lock_irq(&uhci->lock);
++ uhci->is_initialized = 0;
++ spin_unlock_irq(&uhci->lock);
++
++ debugfs_remove(uhci->dentry);
++ }
++
++ for (i = 0; i < UHCI_NUM_SKELQH; i++)
++ uhci_free_qh(uhci, uhci->skelqh[i]);
++
++ uhci_free_td(uhci, uhci->term_td);
++
++ dma_pool_destroy(uhci->qh_pool);
++
++ dma_pool_destroy(uhci->td_pool);
++
++ kfree(uhci->frame_cpu);
++
++ dma_free_coherent(uhci_dev(uhci),
++ UHCI_NUMFRAMES * sizeof(*uhci->frame),
++ uhci->frame, uhci->frame_dma_handle);
++}
++
++void uhci_reset_hc(struct uhci_hcd *uhci)
++{
++ /* Reset the HC - this will force us to get a
++ * new notification of any already connected
++ * ports due to the virtual disconnect that it
++ * implies.
++ */
++ writel(0,(uhci->regbase + USBINTR));
++ writel(USBCMD_GRESET,(uhci->regbase + USBCMD));
++ mdelay(50);
++
++ writel(0,(uhci->regbase + USBCMD));
++ mdelay(10);
++}
++
++int uhci_check_and_reset_hc(struct uhci_hcd *uhci)
++{
++ unsigned int cmd, intr;
++
++ cmd = readl((uhci->regbase + USBCMD));
++ if ((cmd & USBCMD_RS) || !(cmd & USBCMD_CF) ||
++ !(cmd & USBCMD_EGSM)) {
++ printk("%s: cmd = 0x%04x\n", __FUNCTION__, cmd);
++ goto reset_needed;
++ }
++
++ //intr = inw(base + UHCI_USBINTR);
++ intr = readl((uhci->regbase + USBINTR));
++ if (intr & (~USBINTR_RESUME)) {
++ printk("%s: intr = 0x%04x\n", __FUNCTION__, intr);
++ goto reset_needed;
++ }
++ return 0;
++
++reset_needed:
++// printk("Performing full reset\n");
++ uhci_reset_hc(uhci);
++ return 1;
++}
++
++int uhci_reset(struct usb_hcd *hcd)
++{
++ struct uhci_hcd *uhci = hcd_to_uhci(hcd);
++
++
++#ifdef CONFIG_GUC_USB_UHCI_MULTIPORT_2
++ uhci->rh_numports = 2;
++#elif defined (CONFIG_GUC_USB_UHCI_MULTIPORT_4)
++ uhci->rh_numports = 4;
++#else
++ uhci->rh_numports = 1;
++#endif
++
++ /* Kick BIOS off this hardware and reset if the controller
++ * isn't already safely quiescent.
++ */
++ check_and_reset_hc(uhci);
++ return 0;
++}
++
++int uhci_init(struct usb_hcd *hcd)
++{
++ struct uhci_hcd *uhci = hcd_to_uhci(hcd);
++ //unsigned io_size = (unsigned) hcd->rsrc_len;
++ int port;
++
++ uhci->io_addr = (unsigned long) hcd->rsrc_start;
++
++ /* The UHCI spec says devices must have 2 ports, and goes on to say
++ * they may have more but gives no way to determine how many there
++ * are. However according to the UHCI spec, Bit 7 of the port
++ * status and control register is always set to 1. So we try to
++ * use this to our advantage. Another common failure mode when
++ * a nonexistent register is addressed is to return all ones, so
++ * we test for that also.
++ */
++ for (port = 0; port < UHCI_RH_MAXCHILD; port++) {
++ unsigned int portstatus;
++//yriver
++// portstatus = inw(uhci->io_addr + USBPORTSC1 + (port * 2));
++ portstatus = readl(uhci->regbase + USBPORTSC1 + (port * 1));
++ if (!(portstatus & 0x0080) || portstatus == 0xffff)
++ break;
++ }
++ if (debug) {
++ dev_info(uhci_dev(uhci), "detected %d ports\n", port);
++ }
++
++ /* Anything greater than 7 is weird so we'll ignore it. */
++ if (port > UHCI_RH_MAXCHILD) {
++ dev_info(uhci_dev(uhci), "port count misdetected? "
++ "forcing to 2 ports\n");
++ port = 2;
++ }
++ uhci->rh_numports = port;
++
++ /* Kick BIOS off this hardware and reset if the controller
++ * isn't already safely quiescent.
++ */
++ check_and_reset_hc(uhci);
++ return 0;
++}
++
++/* Make sure the controller is quiescent and that we're not using it
++ * any more. This is mainly for the benefit of programs which, like kexec,
++ * expect the hardware to be idle: not doing DMA or generating IRQs.
++ *
++ * This routine may be called in a damaged or failing kernel. Hence we
++ * do not acquire the spinlock before shutting down the controller.
++ */
++void uhci_shutdown(struct pci_dev *pdev)
++{
++ struct usb_hcd *hcd = (struct usb_hcd *) pci_get_drvdata(pdev);
++
++ uhci_hc_died(hcd_to_uhci(hcd));
++}
++
++/*
++ * Allocate a frame list, and then setup the skeleton
++ *
++ * The hardware doesn't really know any difference
++ * in the queues, but the order does matter for the
++ * protocols higher up. The order in which the queues
++ * are encountered by the hardware is:
++ *
++ * - All isochronous events are handled before any
++ * of the queues. We don't do that here, because
++ * we'll create the actual TD entries on demand.
++ * - The first queue is the high-period interrupt queue.
++ * - The second queue is the period-1 interrupt and async
++ * (low-speed control, full-speed control, then bulk) queue.
++ * - The third queue is the terminating bandwidth reclamation queue,
++ * which contains no members, loops back to itself, and is present
++ * only when FSBR is on and there are no full-speed control or bulk QHs.
++ */
++int uhci_start(struct usb_hcd *hcd)
++{
++ struct uhci_hcd *uhci = hcd_to_uhci(hcd);
++ int retval = -EBUSY;
++ int i;
++ struct dentry *dentry;
++
++ hcd->uses_new_polling = 1;
++
++ spin_lock_init(&uhci->lock);
++ setup_timer(&uhci->fsbr_timer, uhci_fsbr_timeout,
++ (unsigned long) uhci);
++ INIT_LIST_HEAD(&uhci->idle_qh_list);
++ init_waitqueue_head(&uhci->waitqh);
++
++ if (DEBUG_CONFIGURED) {
++ dentry = debugfs_create_file(hcd->self.bus_name,
++ S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root,
++ uhci, &uhci_debug_operations);
++ if (!dentry) {
++ dev_err(uhci_dev(uhci), "couldn't create uhci "
++ "debugfs entry\n");
++ retval = -ENOMEM;
++ goto err_create_debug_entry;
++ }
++ uhci->dentry = dentry;
++ }
++
++ uhci->frame = dma_alloc_coherent(uhci_dev(uhci),
++ UHCI_NUMFRAMES * sizeof(*uhci->frame),
++ &uhci->frame_dma_handle, 0);
++ if (!uhci->frame) {
++ dev_err(uhci_dev(uhci), "unable to allocate "
++ "consistent memory for frame list\n");
++ goto err_alloc_frame;
++ }
++
++ memset(uhci->frame, 0, UHCI_NUMFRAMES * sizeof(*uhci->frame));
++
++ uhci->frame_cpu = kcalloc(UHCI_NUMFRAMES, sizeof(*uhci->frame_cpu),
++ GFP_KERNEL);
++ if (!uhci->frame_cpu) {
++ dev_err(uhci_dev(uhci), "unable to allocate "
++ "memory for frame pointers\n");
++ goto err_alloc_frame_cpu;
++ }
++
++ uhci->td_pool = dma_pool_create("uhci_td", uhci_dev(uhci),
++ sizeof(struct uhci_td), 16, 0);
++ if (!uhci->td_pool) {
++ dev_err(uhci_dev(uhci), "unable to create td dma_pool\n");
++ goto err_create_td_pool;
++ }
++
++ uhci->qh_pool = dma_pool_create("uhci_qh", uhci_dev(uhci),
++ sizeof(struct uhci_qh), 16, 0);
++ if (!uhci->qh_pool) {
++ dev_err(uhci_dev(uhci), "unable to create qh dma_pool\n");
++ goto err_create_qh_pool;
++ }
++
++ uhci->term_td = uhci_alloc_td(uhci);
++ if (!uhci->term_td) {
++ dev_err(uhci_dev(uhci), "unable to allocate terminating TD\n");
++ goto err_alloc_term_td;
++ }
++
++ for (i = 0; i < UHCI_NUM_SKELQH; i++) {
++ uhci->skelqh[i] = uhci_alloc_qh(uhci, NULL, NULL);
++ if (!uhci->skelqh[i]) {
++ dev_err(uhci_dev(uhci), "unable to allocate QH\n");
++ goto err_alloc_skelqh;
++ }
++ }
++
++ /*
++ * 8 Interrupt queues; link all higher int queues to int1 = async
++ */
++ for (i = SKEL_ISO + 1; i < SKEL_ASYNC; ++i)
++ uhci->skelqh[i]->link = LINK_TO_QH(uhci->skel_async_qh);
++ uhci->skel_async_qh->link = UHCI_PTR_TERM;
++ uhci->skel_term_qh->link = LINK_TO_QH(uhci->skel_term_qh);
++
++ /* This dummy TD is to work around a bug in Intel PIIX controllers */
++ uhci_fill_td(uhci->term_td, 0, uhci_explen(0) |
++ (0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0);
++ uhci->term_td->link = UHCI_PTR_TERM;
++ uhci->skel_async_qh->element = uhci->skel_term_qh->element =
++ LINK_TO_TD(uhci->term_td);
++
++ /*
++ * Fill the frame list: make all entries point to the proper
++ * interrupt queue.
++ */
++ for (i = 0; i < UHCI_NUMFRAMES; i++) {
++
++ /* Only place we don't use the frame list routines */
++ uhci->frame[i] = uhci_frame_skel_link(uhci, i);
++ }
++
++ /*
++ * Some architectures require a full mb() to enforce completion of
++ * the memory writes above before the I/O transfers in configure_hc().
++ */
++ mb();
++
++ configure_hc(uhci);
++
++ uhci->is_initialized = 1;
++ start_rh(uhci);
++
++ return 0;
++
++/*
++ * error exits:
++ */
++err_alloc_skelqh:
++ for (i = 0; i < UHCI_NUM_SKELQH; i++) {
++ if (uhci->skelqh[i])
++ uhci_free_qh(uhci, uhci->skelqh[i]);
++ }
++
++ uhci_free_td(uhci, uhci->term_td);
++
++err_alloc_term_td:
++ dma_pool_destroy(uhci->qh_pool);
++
++err_create_qh_pool:
++ dma_pool_destroy(uhci->td_pool);
++
++err_create_td_pool:
++ kfree(uhci->frame_cpu);
++
++err_alloc_frame_cpu:
++ dma_free_coherent(uhci_dev(uhci),
++ UHCI_NUMFRAMES * sizeof(*uhci->frame),
++ uhci->frame, uhci->frame_dma_handle);
++
++err_alloc_frame:
++ debugfs_remove(uhci->dentry);
++
++err_create_debug_entry:
++ return retval;
++}
++
++void uhci_stop(struct usb_hcd *hcd)
++{
++ struct uhci_hcd *uhci = hcd_to_uhci(hcd);
++
++ spin_lock_irq(&uhci->lock);
++ if (test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) && !uhci->dead)
++ uhci_hc_died(uhci);
++ uhci_scan_schedule(uhci);
++ spin_unlock_irq(&uhci->lock);
++
++ del_timer_sync(&uhci->fsbr_timer);
++ release_uhci(uhci);
++}
++
++void stop_hc(struct uhci_hcd *uhci)
++{
++ // Disable all interrupts
++ writel(0, (uhci->regbase + USBINTR));
++ writel(USBCMD_MAXP,(uhci->regbase + USBCMD)); // disable hc
++
++}
++
++#ifdef CONFIG_PM
++int uhci_rh_suspend(struct usb_hcd *hcd)
++{
++ struct uhci_hcd *uhci = hcd_to_uhci(hcd);
++ int rc = 0;
++
++ spin_lock_irq(&uhci->lock);
++ if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
++ rc = -ESHUTDOWN;
++ else if (!uhci->dead)
++ suspend_rh(uhci, UHCI_RH_SUSPENDED);
++ spin_unlock_irq(&uhci->lock);
++ return rc;
++}
++
++int uhci_rh_resume(struct usb_hcd *hcd)
++{
++ struct uhci_hcd *uhci = hcd_to_uhci(hcd);
++ int rc = 0;
++
++ spin_lock_irq(&uhci->lock);
++ if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
++ rc = -ESHUTDOWN;
++ else if (!uhci->dead)
++ wakeup_rh(uhci);
++ spin_unlock_irq(&uhci->lock);
++ return rc;
++}
++
++int uhci_pci_suspend(struct usb_hcd *hcd, pm_message_t message)
++{
++ struct uhci_hcd *uhci = hcd_to_uhci(hcd);
++ int rc = 0;
++
++ dev_dbg(uhci_dev(uhci), "%s\n", __func__);
++
++ spin_lock_irq(&uhci->lock);
++ if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) || uhci->dead)
++ goto done_okay; /* Already suspended or dead */
++
++ if (uhci->rh_state > UHCI_RH_SUSPENDED) {
++ dev_warn(uhci_dev(uhci), "Root hub isn't suspended!\n");
++ rc = -EBUSY;
++ goto done;
++ };
++
++ /* All PCI host controllers are required to disable IRQ generation
++ * at the source, so we must turn off PIRQ.
++ */
++ pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0);
++ mb();
++ hcd->poll_rh = 0;
++
++ /* FIXME: Enable non-PME# remote wakeup? */
++
++ /* make sure snapshot being resumed re-enumerates everything */
++ if (message.event == PM_EVENT_PRETHAW)
++ uhci_hc_died(uhci);
++
++done_okay:
++ clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
++done:
++ spin_unlock_irq(&uhci->lock);
++ return rc;
++}
++
++int uhci_pci_resume(struct usb_hcd *hcd)
++{
++ struct uhci_hcd *uhci = hcd_to_uhci(hcd);
++
++ dev_dbg(uhci_dev(uhci), "%s\n", __func__);
++
++ /* Since we aren't in D3 any more, it's safe to set this flag
++ * even if the controller was dead.
++ */
++ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
++ mb();
++
++ spin_lock_irq(&uhci->lock);
++
++ /* FIXME: Disable non-PME# remote wakeup? */
++
++ /* The firmware or a boot kernel may have changed the controller
++ * settings during a system wakeup. Check it and reconfigure
++ * to avoid problems.
++ */
++ check_and_reset_hc(uhci);
++
++ /* If the controller was dead before, it's back alive now */
++ configure_hc(uhci);
++
++ if (uhci->rh_state == UHCI_RH_RESET) {
++
++ /* The controller had to be reset */
++ usb_root_hub_lost_power(hcd->self.root_hub);
++ suspend_rh(uhci, UHCI_RH_SUSPENDED);
++ }
++
++ spin_unlock_irq(&uhci->lock);
++
++ /* If interrupts don't work and remote wakeup is enabled then
++ * the suspended root hub needs to be polled.
++ */
++ if (!uhci->RD_enable && hcd->self.root_hub->do_remote_wakeup) {
++ hcd->poll_rh = 1;
++ usb_hcd_poll_rh_status(hcd);
++ }
++ return 0;
++}
++#endif
++
++/* Wait until a particular device/endpoint's QH is idle, and free it */
++void uhci_hcd_endpoint_disable(struct usb_hcd *hcd,
++ struct usb_host_endpoint *hep)
++{
++ struct uhci_hcd *uhci = hcd_to_uhci(hcd);
++ struct uhci_qh *qh;
++
++ spin_lock_irq(&uhci->lock);
++ qh = (struct uhci_qh *) hep->hcpriv;
++ if (qh == NULL)
++ goto done;
++
++ while (qh->state != UHCI_QH_STATE_IDLE) {
++ ++uhci->num_waiting;
++ spin_unlock_irq(&uhci->lock);
++ wait_event_interruptible(uhci->waitqh,
++ qh->state == UHCI_QH_STATE_IDLE);
++ spin_lock_irq(&uhci->lock);
++ --uhci->num_waiting;
++ }
++
++ uhci_free_qh(uhci, qh);
++done:
++ spin_unlock_irq(&uhci->lock);
++}
++
++int uhci_hcd_get_frame_number(struct usb_hcd *hcd)
++{
++ struct uhci_hcd *uhci = hcd_to_uhci(hcd);
++ unsigned frame_number;
++ unsigned delta;
++
++ /* Minimize latency by avoiding the spinlock */
++ frame_number = uhci->frame_number;
++ barrier();
++//yriver
++// delta = (inw(uhci->io_addr + USBFRNUM) - frame_number) &
++// (UHCI_NUMFRAMES - 1);
++ delta = (readl(uhci->regbase + USBFRNUM) - frame_number) &
++ (UHCI_NUMFRAMES - 1);
++ return frame_number + delta;
++}
++
++//static const char hcd_name[] = "uhci_hcd";
++
++static const struct hc_driver _uhci_driver = {
++//yriver
++// .description = hcd_name,
++ .description = "ast uhci",
++ .product_desc = "UHCI Host Controller",
++ .hcd_priv_size = sizeof(struct uhci_hcd),
++
++ /* Generic hardware linkage */
++ .irq = uhci_irq,
++ .flags = HCD_USB11,
++
++ /* Basic lifecycle operations */
++// .reset = uhci_init,
++ .reset = uhci_reset,
++ .start = uhci_start,
++#ifdef CONFIG_PM
++ .pci_suspend = uhci_pci_suspend,
++ .pci_resume = uhci_pci_resume,
++ .bus_suspend = uhci_rh_suspend,
++ .bus_resume = uhci_rh_resume,
++#endif
++ .stop = uhci_stop,
++
++ .urb_enqueue = uhci_urb_enqueue,
++ .urb_dequeue = uhci_urb_dequeue,
++
++ .endpoint_disable = uhci_hcd_endpoint_disable,
++ .get_frame_number = uhci_hcd_get_frame_number,
++
++ .hub_status_data = uhci_hub_status_data,
++ .hub_control = uhci_hub_control,
++};
++
++int __init uhci_hcd_init(void)
++{
++ int retval = -ENOMEM;
++
++ if (usb_disabled())
++ return -ENODEV;
++
++ printk(KERN_INFO "uhci_hcd: " DRIVER_DESC "%s\n",
++ ignore_oc ? ", overcurrent ignored" : "");
++ set_bit(USB_UHCI_LOADED, &usb_hcds_loaded);
++
++ if (DEBUG_CONFIGURED) {
++ errbuf = kmalloc(ERRBUF_LEN, GFP_KERNEL);
++ if (!errbuf)
++ goto errbuf_failed;
++ uhci_debugfs_root = debugfs_create_dir("uhci", NULL);
++ if (!uhci_debugfs_root)
++ goto debug_failed;
++ }
++
++ uhci_up_cachep = kmem_cache_create("uhci_urb_priv",
++ sizeof(struct urb_priv), 0, 0, NULL);
++ if (!uhci_up_cachep)
++ goto up_failed;
++/*
++ retval = pci_register_driver(&uhci_pci_driver);
++ if (retval)
++ goto init_failed;
++*/
++ return 0;
++
++//init_failed:
++// kmem_cache_destroy(uhci_up_cachep);
++
++up_failed:
++ debugfs_remove(uhci_debugfs_root);
++
++debug_failed:
++ kfree(errbuf);
++
++errbuf_failed:
++
++ clear_bit(USB_UHCI_LOADED, &usb_hcds_loaded);
++ return retval;
++}
++
++void uhci_hcd_cleanup(void)
++{
++// pci_unregister_driver(&uhci_pci_driver);
++ kmem_cache_destroy(uhci_up_cachep);
++ debugfs_remove(uhci_debugfs_root);
++ kfree(errbuf);
++ clear_bit(USB_UHCI_LOADED, &usb_hcds_loaded);
++}
++
++void __exit cleanup_UHCI(void)
++{
++ uhci_hcd_cleanup();
++}
++
++/*-------------------------------------------------------------------------*/
++static int usb_hcd_guc_probe (const struct hc_driver *driver,
++ struct platform_device *pdev)
++{
++ unsigned int *base, temp;
++ int retval;
++ struct resource *res;
++ struct usb_hcd *hcd = 0;
++ struct uhci_hcd *uhci;
++ int irq;
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq <= 0) {
++ dev_err(&pdev->dev,
++ "Found HC with no IRQ. Check %s setup!\n",
++ dev_name(&pdev->dev));
++ retval = -ENODEV;
++ goto err1;
++ }
++
++ hcd = usb_create_hcd (driver, &pdev->dev, dev_name(&pdev->dev));
++// printk("alloc_uhci(2): uhci_dev:%x, _uhci_hcd.state:%x\n", &uhci_dev, _uhci_hcd->state);
++ if (!hcd) {
++ retval = -ENOMEM;
++ return retval;
++ }
++
++
++ uhci = hcd_to_uhci(hcd);
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res) {
++ dev_err(&pdev->dev,
++ "Found HC with no register addr. Check %s setup!\n",
++ dev_name(&pdev->dev));
++ retval = -ENODEV;
++ goto err1;
++ }
++
++ if (!request_mem_region(res->start, res->end - res->start + 1,
++ res->name)) {
++ dev_dbg(&pdev->dev, "controller already in use\n");
++ retval = -EBUSY;
++ goto err1;
++ }
++
++ base = ioremap_nocache(res->start, res->end - res->start + 1);
++ if (base == NULL) {
++ dev_dbg(&pdev->dev, "error mapping memory\n");
++ retval = -ENOMEM;
++ goto err1;
++ }
++
++ uhci->regbase = (unsigned int *)base;
++ uhci->io_addr = (unsigned int)base;
++
++// printk("UHCI Base address is %x, phy %08x\n",(unsigned int)base, UHC_BASE_ADDR);
++
++ retval = usb_add_hcd (hcd, irq, IRQF_SHARED);
++
++ // printk("alloc_uhci(3): uhci_dev:%x, _uhci_hcd.state:%x\n", &uhci_dev, _uhci_hcd->state);
++
++ if (retval == 0)
++ return retval;
++
++ //BruceToDo. Stop USB 1.1 Host's clock.
++ iounmap((void*)uhci->io_addr);
++err1:
++ usb_put_hcd(hcd);
++
++ printk("add UHCI to USB host controller list failed!\n");
++ return retval;
++}
++
++
++static inline void
++usb_hcd_guc_remove (struct usb_hcd *hcd, struct platform_device *pdev)
++{
++ struct uhci_hcd *uhci = hcd_to_uhci(hcd);
++
++ usb_remove_hcd(hcd);
++ //BruceToDo. Stop USB 1.1 Host's clock.
++ iounmap((void*)uhci->io_addr);
++ usb_put_hcd(hcd);
++}
++
++/*-------------------------------------------------------------------------*/
++#ifdef CONFIG_PM
++static int uhci_guc_suspend(struct platform_device *dev, pm_message_t message)
++{
++ struct uhci_hcd *uhci = hcd_to_uhci(platform_get_drvdata(dev));
++#if 0
++ if (time_before(jiffies, ohci->next_statechange))
++ msleep(5);
++ ohci->next_statechange = jiffies;
++ omap_ohci_clock_power(0);
++#endif
++ uhci_to_hcd(uhci)->state = HC_STATE_SUSPENDED;
++ return 0;
++}
++static int uhci_guc_resume(struct platform_device *dev)
++{
++ struct usb_hcd *hcd = platform_get_drvdata(dev);
++#if 0
++ struct uhci_hcd *uhci = hcd_to_uhci(hcd);
++
++ if (time_before(jiffies, ohci->next_statechange))
++ msleep(5);
++ ohci->next_statechange = jiffies;
++ omap_ohci_clock_power(1);
++ ohci_finish_controller_resume(hcd);
++#endif
++
++ /*Bruce111220. This line is copied from AST1510 uhci-hcd.c and OMAP kernel 2.6.15*/
++ usb_hcd_resume_root_hub(hcd);
++ return 0;
++}
++#endif
++/*-------------------------------------------------------------------------*/
++
++static int uhci_hcd_guc_drv_probe(struct platform_device *dev)
++{
++ return usb_hcd_guc_probe(&_uhci_driver, dev);
++}
++static int uhci_hcd_guc_drv_remove(struct platform_device *dev)
++{
++ struct usb_hcd *hcd = platform_get_drvdata(dev);
++
++ usb_hcd_guc_remove(hcd, dev);
++ platform_set_drvdata(dev, NULL);
++ return 0;
++}
++
++/*
++ * Driver definition to register
++ */
++static struct platform_driver uhci_hcd_guc_driver = {
++ .probe = uhci_hcd_guc_drv_probe,
++ .remove = uhci_hcd_guc_drv_remove,
++#ifdef CONFIG_PM
++ .suspend = uhci_guc_suspend,
++ .resume = uhci_guc_resume,
++#endif
++ .driver = {
++ .owner = THIS_MODULE,
++ .name = "ast_uhci",
++ },
++};
++
++static int __init uhci_hcd_guc_init (void)
++{
++ uhci_hcd_init();
++ return platform_driver_register(&uhci_hcd_guc_driver);
++}
++
++static void __exit uhci_hcd_guc_cleanup (void)
++{
++ uhci_hcd_cleanup();
++ platform_driver_unregister(&uhci_hcd_guc_driver);
++}
++
++module_init(uhci_hcd_guc_init);
++module_exit(uhci_hcd_guc_cleanup);
++
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_DESCRIPTION(DRIVER_DESC);
++MODULE_LICENSE("GPL");
+diff --git a/drivers/usb/astuhci/uhci-hcd.h b/drivers/usb/astuhci/uhci-hcd.h
+new file mode 100644
+index 0000000..c4a903e
+--- /dev/null
++++ b/drivers/usb/astuhci/uhci-hcd.h
+@@ -0,0 +1,496 @@
++/********************************************************************************
++* File Name : uhci-hcd.h
++*
++* port from uhci-hcd.h
++* 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 __LINUX_UHCI_HCD_H
++#define __LINUX_UHCI_HCD_H
++
++#include <linux/list.h>
++#include <linux/usb.h>
++
++#define usb_packetid(pipe) (usb_pipein(pipe) ? USB_PID_IN : USB_PID_OUT)
++#define PIPE_DEVEP_MASK 0x0007ff00
++
++
++/*
++ * Universal Host Controller Interface data structures and defines
++ */
++
++/* Command register */
++#define USBCMD 0
++#define USBCMD_RS 0x0001 /* Run/Stop */
++#define USBCMD_HCRESET 0x0002 /* Host reset */
++#define USBCMD_GRESET 0x0004 /* Global reset */
++#define USBCMD_EGSM 0x0008 /* Global Suspend Mode */
++#define USBCMD_FGR 0x0010 /* Force Global Resume */
++#define USBCMD_SWDBG 0x0020 /* SW Debug mode */
++#define USBCMD_CF 0x0040 /* Config Flag (sw only) */
++#define USBCMD_MAXP 0x0080 /* Max Packet (0 = 32, 1 = 64) */
++
++/* Status register */
++//#define USBSTS 2
++#define USBSTS 1
++#define USBSTS_USBINT 0x0001 /* Interrupt due to IOC */
++#define USBSTS_ERROR 0x0002 /* Interrupt due to error */
++#define USBSTS_RD 0x0004 /* Resume Detect */
++#define USBSTS_HSE 0x0008 /* Host System Error: PCI problems */
++#define USBSTS_HCPE 0x0010 /* Host Controller Process Error:
++ * the schedule is buggy */
++#define USBSTS_HCH 0x0020 /* HC Halted */
++
++/* Interrupt enable register */
++//#define USBINTR 4
++#define USBINTR 2
++#define USBINTR_TIMEOUT 0x0001 /* Timeout/CRC error enable */
++#define USBINTR_RESUME 0x0002 /* Resume interrupt enable */
++#define USBINTR_IOC 0x0004 /* Interrupt On Complete enable */
++#define USBINTR_SP 0x0008 /* Short packet interrupt enable */
++
++//#define USBFRNUM 6
++//#define USBFLBASEADD 8
++//#define USBSOF 12
++#define USBFRNUM 32
++#define USBFLBASEADD 3
++#define USBSOF 33
++#define USBSOF_DEFAULT 64 /* Frame length is exactly 1 ms */
++
++/* USB port status and control registers */
++//#define USBPORTSC1 16
++//#define USBPORTSC2 18
++#define USBPORTSC1 (34)
++#define USBPORTSC2 (35)
++#define USBPORTSC_CCS 0x0001 /* Current Connect Status
++ * ("device present") */
++#define USBPORTSC_CSC 0x0002 /* Connect Status Change */
++#define USBPORTSC_PE 0x0004 /* Port Enable */
++#define USBPORTSC_PEC 0x0008 /* Port Enable Change */
++#define USBPORTSC_DPLUS 0x0010 /* D+ high (line status) */
++#define USBPORTSC_DMINUS 0x0020 /* D- high (line status) */
++#define USBPORTSC_RD 0x0040 /* Resume Detect */
++#define USBPORTSC_RES1 0x0080 /* reserved, always 1 */
++#define USBPORTSC_LSDA 0x0100 /* Low Speed Device Attached */
++#define USBPORTSC_PR 0x0200 /* Port Reset */
++/* OC and OCC from Intel 430TX and later (not UHCI 1.1d spec) */
++#define USBPORTSC_OC 0x0400 /* Over Current condition */
++#define USBPORTSC_OCC 0x0800 /* Over Current Change R/WC */
++#define USBPORTSC_SUSP 0x1000 /* Suspend */
++#define USBPORTSC_RES2 0x2000 /* reserved, write zeroes */
++#define USBPORTSC_RES3 0x4000 /* reserved, write zeroes */
++#define USBPORTSC_RES4 0x8000 /* reserved, write zeroes */
++
++/* Legacy support register */
++#define USBLEGSUP 0xc0
++#define USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */
++#define USBLEGSUP_RWC 0x8f00 /* the R/WC bits */
++#define USBLEGSUP_RO 0x5040 /* R/O and reserved bits */
++
++#define UHCI_PTR_BITS __constant_cpu_to_le32(0x000F)
++#define UHCI_PTR_TERM __constant_cpu_to_le32(0x0001)
++#define UHCI_PTR_QH __constant_cpu_to_le32(0x0002)
++#define UHCI_PTR_DEPTH __constant_cpu_to_le32(0x0004)
++#define UHCI_PTR_BREADTH __constant_cpu_to_le32(0x0000)
++
++#define UHCI_NUMFRAMES 1024 /* in the frame list [array] */
++#define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */
++#define CAN_SCHEDULE_FRAMES 1000 /* how far in the future frames
++ * can be scheduled */
++#define MAX_PHASE 32 /* Periodic scheduling length */
++
++/* Otg Features*/
++#define RH_PORT_BHNP_ENABLE 0x03
++#define RH_PORT_AHNP_SUPPORT 0x04
++#define SF_BHNP_ENABLE 0x34
++
++/* When no queues need Full-Speed Bandwidth Reclamation,
++ * delay this long before turning FSBR off */
++#define FSBR_OFF_DELAY msecs_to_jiffies(10)
++
++/* If a queue hasn't advanced after this much time, assume it is stuck */
++#define QH_WAIT_TIMEOUT msecs_to_jiffies(200)
++
++
++/*
++ * Queue Headers
++ */
++
++/*
++ * One role of a QH is to hold a queue of TDs for some endpoint. One QH goes
++ * with each endpoint, and qh->element (updated by the HC) is either:
++ * - the next unprocessed TD in the endpoint's queue, or
++ * - UHCI_PTR_TERM (when there's no more traffic for this endpoint).
++ *
++ * The other role of a QH is to serve as a "skeleton" framelist entry, so we
++ * can easily splice a QH for some endpoint into the schedule at the right
++ * place. Then qh->element is UHCI_PTR_TERM.
++ *
++ * In the schedule, qh->link maintains a list of QHs seen by the HC:
++ * skel1 --> ep1-qh --> ep2-qh --> ... --> skel2 --> ...
++ *
++ * qh->node is the software equivalent of qh->link. The differences
++ * are that the software list is doubly-linked and QHs in the UNLINKING
++ * state are on the software list but not the hardware schedule.
++ *
++ * For bookkeeping purposes we maintain QHs even for Isochronous endpoints,
++ * but they never get added to the hardware schedule.
++ */
++#define QH_STATE_IDLE 1 /* QH is not being used */
++#define UHCI_QH_STATE_IDLE 1 /* QH is not being used */
++#define QH_STATE_UNLINKING 2 /* QH has been removed from the
++ * schedule but the hardware may
++ * still be using it */
++#define QH_STATE_ACTIVE 3 /* QH is on the schedule */
++
++struct uhci_qh {
++ /* Hardware fields */
++ __le32 link; /* Next QH in the schedule */
++ __le32 element; /* Queue element (TD) pointer */
++
++ /* Software fields */
++ dma_addr_t dma_handle;
++
++ struct list_head node; /* Node in the list of QHs */
++ struct usb_host_endpoint *hep; /* Endpoint information */
++ struct usb_device *udev;
++ struct list_head queue; /* Queue of urbps for this QH */
++ struct uhci_td *dummy_td; /* Dummy TD to end the queue */
++ struct uhci_td *post_td; /* Last TD completed */
++
++ struct usb_iso_packet_descriptor *iso_packet_desc;
++ /* Next urb->iso_frame_desc entry */
++ unsigned long advance_jiffies; /* Time of last queue advance */
++ unsigned int unlink_frame; /* When the QH was unlinked */
++ unsigned int period; /* For Interrupt and Isochronous QHs */
++ short phase; /* Between 0 and period-1 */
++ short load; /* Periodic time requirement, in us */
++ unsigned int iso_frame; /* Frame # for iso_packet_desc */
++
++ int state; /* QH_STATE_xxx; see above */
++ int type; /* Queue type (control, bulk, etc) */
++ int skel; /* Skeleton queue number */
++
++ unsigned int initial_toggle:1; /* Endpoint's current toggle value */
++ unsigned int needs_fixup:1; /* Must fix the TD toggle values */
++ unsigned int is_stopped:1; /* Queue was stopped by error/unlink */
++ unsigned int wait_expired:1; /* QH_WAIT_TIMEOUT has expired */
++ unsigned int bandwidth_reserved:1; /* Periodic bandwidth has
++ * been allocated */
++} __attribute__((aligned(16)));
++
++/*
++ * We need a special accessor for the element pointer because it is
++ * subject to asynchronous updates by the controller.
++ */
++static inline __le32 qh_element(struct uhci_qh *qh) {
++ __le32 element = qh->element;
++
++ barrier();
++ return element;
++}
++
++#define LINK_TO_QH(qh) (UHCI_PTR_QH | cpu_to_le32((qh)->dma_handle))
++
++
++/*
++ * Transfer Descriptors
++ */
++
++/*
++ * for TD <status>:
++ */
++#define TD_CTRL_SPD (1 << 29) /* Short Packet Detect */
++#define TD_CTRL_C_ERR_MASK (3 << 27) /* Error Counter bits */
++#define TD_CTRL_C_ERR_SHIFT 27
++#define TD_CTRL_LS (1 << 26) /* Low Speed Device */
++#define TD_CTRL_IOS (1 << 25) /* Isochronous Select */
++#define TD_CTRL_IOC (1 << 24) /* Interrupt on Complete */
++#define TD_CTRL_ACTIVE (1 << 23) /* TD Active */
++#define TD_CTRL_STALLED (1 << 22) /* TD Stalled */
++#define TD_CTRL_DBUFERR (1 << 21) /* Data Buffer Error */
++#define TD_CTRL_BABBLE (1 << 20) /* Babble Detected */
++#define TD_CTRL_NAK (1 << 19) /* NAK Received */
++#define TD_CTRL_CRCTIMEO (1 << 18) /* CRC/Time Out Error */
++#define TD_CTRL_BITSTUFF (1 << 17) /* Bit Stuff Error */
++#define TD_CTRL_ACTLEN_MASK 0x7FF /* actual length, encoded as n - 1 */
++
++#define TD_CTRL_ANY_ERROR (TD_CTRL_STALLED | TD_CTRL_DBUFERR | \
++ TD_CTRL_BABBLE | TD_CTRL_CRCTIME | \
++ TD_CTRL_BITSTUFF)
++
++#define uhci_maxerr(err) ((err) << TD_CTRL_C_ERR_SHIFT)
++#define uhci_status_bits(ctrl_sts) ((ctrl_sts) & 0xF60000)
++#define uhci_actual_length(ctrl_sts) (((ctrl_sts) + 1) & \
++ TD_CTRL_ACTLEN_MASK) /* 1-based */
++
++/*
++ * for TD <info>: (a.k.a. Token)
++ */
++#define td_token(td) le32_to_cpu((td)->token)
++#define TD_TOKEN_DEVADDR_SHIFT 8
++#define TD_TOKEN_TOGGLE_SHIFT 19
++#define TD_TOKEN_TOGGLE (1 << 19)
++#define TD_TOKEN_EXPLEN_SHIFT 21
++#define TD_TOKEN_EXPLEN_MASK 0x7FF /* expected length, encoded as n-1 */
++#define TD_TOKEN_PID_MASK 0xFF
++
++#define uhci_explen(len) ((((len) - 1) & TD_TOKEN_EXPLEN_MASK) << \
++ TD_TOKEN_EXPLEN_SHIFT)
++
++#define uhci_expected_length(token) ((((token) >> TD_TOKEN_EXPLEN_SHIFT) + \
++ 1) & TD_TOKEN_EXPLEN_MASK)
++#define uhci_toggle(token) (((token) >> TD_TOKEN_TOGGLE_SHIFT) & 1)
++#define uhci_endpoint(token) (((token) >> 15) & 0xf)
++#define uhci_devaddr(token) (((token) >> TD_TOKEN_DEVADDR_SHIFT) & 0x7f)
++#define uhci_devep(token) (((token) >> TD_TOKEN_DEVADDR_SHIFT) & 0x7ff)
++#define uhci_packetid(token) ((token) & TD_TOKEN_PID_MASK)
++#define uhci_packetout(token) (uhci_packetid(token) != USB_PID_IN)
++#define uhci_packetin(token) (uhci_packetid(token) == USB_PID_IN)
++
++/*
++ * The documentation says "4 words for hardware, 4 words for software".
++ *
++ * That's silly, the hardware doesn't care. The hardware only cares that
++ * the hardware words are 16-byte aligned, and we can have any amount of
++ * sw space after the TD entry.
++ *
++ * td->link points to either another TD (not necessarily for the same urb or
++ * even the same endpoint), or nothing (PTR_TERM), or a QH.
++ */
++struct uhci_td {
++ /* Hardware fields */
++ __le32 link;
++ __le32 status;
++ __le32 token;
++ __le32 buffer;
++
++ /* Software fields */
++ dma_addr_t dma_handle;
++
++ struct list_head list;
++
++ int frame; /* for iso: what frame? */
++ struct list_head fl_list;
++} __attribute__((aligned(16)));
++
++/*
++ * We need a special accessor for the control/status word because it is
++ * subject to asynchronous updates by the controller.
++ */
++static inline u32 td_status(struct uhci_td *td) {
++ __le32 status = td->status;
++
++ barrier();
++ return le32_to_cpu(status);
++}
++
++#define LINK_TO_TD(td) (cpu_to_le32((td)->dma_handle))
++
++
++/*
++ * Skeleton Queue Headers
++ */
++
++/*
++ * The UHCI driver uses QHs with Interrupt, Control and Bulk URBs for
++ * automatic queuing. To make it easy to insert entries into the schedule,
++ * we have a skeleton of QHs for each predefined Interrupt latency.
++ * Asynchronous QHs (low-speed control, full-speed control, and bulk)
++ * go onto the period-1 interrupt list, since they all get accessed on
++ * every frame.
++ *
++ * When we want to add a new QH, we add it to the list starting from the
++ * appropriate skeleton QH. For instance, the schedule can look like this:
++ *
++ * skel int128 QH
++ * dev 1 interrupt QH
++ * dev 5 interrupt QH
++ * skel int64 QH
++ * skel int32 QH
++ * ...
++ * skel int1 + async QH
++ * dev 5 low-speed control QH
++ * dev 1 bulk QH
++ * dev 2 bulk QH
++ *
++ * There is a special terminating QH used to keep full-speed bandwidth
++ * reclamation active when no full-speed control or bulk QHs are linked
++ * into the schedule. It has an inactive TD (to work around a PIIX bug,
++ * see the Intel errata) and it points back to itself.
++ *
++ * There's a special skeleton QH for Isochronous QHs which never appears
++ * on the schedule. Isochronous TDs go on the schedule before the
++ * the skeleton QHs. The hardware accesses them directly rather than
++ * through their QH, which is used only for bookkeeping purposes.
++ * While the UHCI spec doesn't forbid the use of QHs for Isochronous,
++ * it doesn't use them either. And the spec says that queues never
++ * advance on an error completion status, which makes them totally
++ * unsuitable for Isochronous transfers.
++ *
++ * There's also a special skeleton QH used for QHs which are in the process
++ * of unlinking and so may still be in use by the hardware. It too never
++ * appears on the schedule.
++ */
++
++#define UHCI_NUM_SKELQH 11
++#define SKEL_UNLINK 0
++#define skel_unlink_qh skelqh[SKEL_UNLINK]
++#define SKEL_ISO 1
++#define skel_iso_qh skelqh[SKEL_ISO]
++ /* int128, int64, ..., int1 = 2, 3, ..., 9 */
++#define SKEL_INDEX(exponent) (9 - exponent)
++#define SKEL_ASYNC 9
++#define skel_async_qh skelqh[SKEL_ASYNC]
++#define SKEL_TERM 10
++#define skel_term_qh skelqh[SKEL_TERM]
++
++/* The following entries refer to sublists of skel_async_qh */
++#define SKEL_LS_CONTROL 20
++#define SKEL_FS_CONTROL 21
++#define SKEL_FSBR SKEL_FS_CONTROL
++#define SKEL_BULK 22
++
++/*
++ * The UHCI controller and root hub
++ */
++
++/*
++ * States for the root hub:
++ *
++ * To prevent "bouncing" in the presence of electrical noise,
++ * when there are no devices attached we delay for 1 second in the
++ * RUNNING_NODEVS state before switching to the AUTO_STOPPED state.
++ *
++ * (Note that the AUTO_STOPPED state won't be necessary once the hub
++ * driver learns to autosuspend.)
++ */
++enum uhci_rh_state {
++ /* In the following states the HC must be halted.
++ * These two must come first. */
++ UHCI_RH_RESET,
++ UHCI_RH_SUSPENDED,
++
++ UHCI_RH_AUTO_STOPPED,
++ UHCI_RH_RESUMING,
++
++ /* In this state the HC changes from running to halted,
++ * so it can legally appear either way. */
++ UHCI_RH_SUSPENDING,
++
++ /* In the following states it's an error if the HC is halted.
++ * These two must come last. */
++ UHCI_RH_RUNNING, /* The normal state */
++ UHCI_RH_RUNNING_NODEVS, /* Running with no devices attached */
++};
++
++/*
++ * The full UHCI controller information:
++ */
++struct uhci_hcd {
++
++ /* debugfs */
++ struct dentry *dentry;
++
++ /* Grabbed from PCI */
++ unsigned long io_addr;
++
++ struct dma_pool *qh_pool;
++ struct dma_pool *td_pool;
++
++ struct uhci_td *term_td; /* Terminating TD, see UHCI bug */
++ struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QHs */
++ struct uhci_qh *next_qh; /* Next QH to scan */
++
++ spinlock_t lock;
++
++ dma_addr_t frame_dma_handle; /* Hardware frame list */
++ __le32 *frame;
++ void **frame_cpu; /* CPU's frame list */
++
++ enum uhci_rh_state rh_state;
++ unsigned long auto_stop_time; /* When to AUTO_STOP */
++
++ unsigned int frame_number; /* As of last check */
++ unsigned int is_stopped;
++#define UHCI_IS_STOPPED 9999 /* Larger than a frame # */
++ unsigned int last_iso_frame; /* Frame of last scan */
++ unsigned int cur_iso_frame; /* Frame for current scan */
++
++ unsigned int scan_in_progress:1; /* Schedule scan is running */
++ unsigned int need_rescan:1; /* Redo the schedule scan */
++ unsigned int dead:1; /* Controller has died */
++ unsigned int RD_enable:1; /* Suspended root hub with
++ Resume-Detect interrupts
++ enabled */
++ unsigned int is_initialized:1; /* Data structure is usable */
++ unsigned int fsbr_is_on:1; /* FSBR is turned on */
++ unsigned int fsbr_is_wanted:1; /* Does any URB want FSBR? */
++ unsigned int fsbr_expiring:1; /* FSBR is timing out */
++
++ struct timer_list fsbr_timer; /* For turning off FBSR */
++
++ /* Support for port suspend/resume/reset */
++ unsigned long port_c_suspend; /* Bit-arrays of ports */
++ unsigned long resuming_ports;
++ unsigned long ports_timeout; /* Time to stop signalling */
++
++ struct list_head idle_qh_list; /* Where the idle QHs live */
++
++ int rh_numports; /* Number of root-hub ports */
++
++ wait_queue_head_t waitqh; /* endpoint_disable waiters */
++ int num_waiting; /* Number of waiters */
++
++ int total_load; /* Sum of array values */
++ short load[MAX_PHASE]; /* Periodic allocations */
++ int is_suspended;
++ unsigned int *regbase; // eric
++ unsigned int *ptr_usb_hcd; // eric
++};
++
++/* Convert between a usb_hcd pointer and the corresponding uhci_hcd */
++static inline struct uhci_hcd *hcd_to_uhci(struct usb_hcd *hcd)
++{
++ return (struct uhci_hcd *) (hcd->hcd_priv);
++}
++static inline struct usb_hcd *uhci_to_hcd(struct uhci_hcd *uhci)
++{
++ return container_of((void *) uhci, struct usb_hcd, hcd_priv);
++}
++
++#define uhci_dev(u) (uhci_to_hcd(u)->self.controller)
++
++/* Utility macro for comparing frame numbers */
++#define uhci_frame_before_eq(f1, f2) (0 <= (int) ((f2) - (f1)))
++
++
++/*
++ * Private per-URB data
++ */
++struct urb_priv {
++ struct list_head node; /* Node in the QH's urbp list */
++
++ struct urb *urb;
++
++ struct uhci_qh *qh; /* QH for this URB */
++ struct list_head td_list;
++
++ unsigned fsbr:1; /* URB wants FSBR */
++};
++
++
++/* Some special IDs */
++
++#define PCI_VENDOR_ID_GENESYS 0x17a0
++#define PCI_DEVICE_ID_GL880S_UHCI 0x8083
++
++#endif
+diff --git a/drivers/usb/astuhci/uhci-hub.c b/drivers/usb/astuhci/uhci-hub.c
+new file mode 100644
+index 0000000..64a4496
+--- /dev/null
++++ b/drivers/usb/astuhci/uhci-hub.c
+@@ -0,0 +1,437 @@
++/********************************************************************************
++* File Name : uhci-hub.c
++*
++* port from uhci-hub.c
++* 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
++********************************************************************************/
++
++static const __u8 root_hub_hub_des[] =
++{
++ 0x09, /* __u8 bLength; */
++ 0x29, /* __u8 bDescriptorType; Hub-descriptor */
++ 0x02, /* __u8 bNbrPorts; */
++ 0x0a, /* __u16 wHubCharacteristics; */
++ 0x00, /* (per-port OC, no power switching) */
++ 0x01, /* __u8 bPwrOn2pwrGood; 2ms */
++ 0x00, /* __u8 bHubContrCurrent; 0 mA */
++ 0x00, /* __u8 DeviceRemovable; *** 7 Ports max *** */
++ 0xff /* __u8 PortPwrCtrlMask; *** 7 ports max *** */
++};
++
++#define UHCI_RH_MAXCHILD 7
++
++/* must write as zeroes */
++#define WZ_BITS (USBPORTSC_RES2 | USBPORTSC_RES3 | USBPORTSC_RES4)
++
++/* status change bits: nonzero writes will clear */
++#define RWC_BITS (USBPORTSC_OCC | USBPORTSC_PEC | USBPORTSC_CSC)
++
++/* suspend/resume bits: port suspended or port resuming */
++#define SUSPEND_BITS (USBPORTSC_SUSP | USBPORTSC_RD)
++
++/* A port that either is connected or has a changed-bit set will prevent
++ * us from AUTO_STOPPING.
++ */
++static int any_ports_active(struct uhci_hcd *uhci)
++{
++ int port;
++
++ for (port = 0; port < uhci->rh_numports; ++port) {
++//yriver
++// if ((inw(uhci->io_addr + USBPORTSC1 + port * 2) &
++ if ((readl(uhci->regbase + USBPORTSC1 + port * 1) &
++ (USBPORTSC_CCS | RWC_BITS)) ||
++ test_bit(port, &uhci->port_c_suspend))
++ return 1;
++ }
++ return 0;
++}
++
++static inline int get_hub_status_data(struct uhci_hcd *uhci, char *buf)
++{
++ int port;
++ int mask = RWC_BITS;
++
++ /* Some boards (both VIA and Intel apparently) report bogus
++ * overcurrent indications, causing massive log spam unless
++ * we completely ignore them. This doesn't seem to be a problem
++ * with the chipset so much as with the way it is connected on
++ * the motherboard; if the overcurrent input is left to float
++ * then it may constantly register false positives. */
++ if (ignore_oc)
++ mask &= ~USBPORTSC_OCC;
++
++ *buf = 0;
++ for (port = 0; port < uhci->rh_numports; ++port) {
++//yriver
++// if ((inw(uhci->io_addr + USBPORTSC1 + port * 2) & mask) ||
++ if ((readl(uhci->regbase + USBPORTSC1 + port * 1) & mask) ||
++ test_bit(port, &uhci->port_c_suspend))
++ *buf |= (1 << (port + 1));
++ }
++ return !!*buf;
++}
++
++#define OK(x) len = (x); break
++//yriver
++#define CLR_RH_PORTSTAT(x) \
++ status = readl(port_addr); \
++ status &= ~(RWC_BITS|WZ_BITS); \
++ status &= ~(x); \
++ status |= RWC_BITS & (x); \
++ writel(status, port_addr)
++
++#define SET_RH_PORTSTAT(x) \
++ status = readl(port_addr); \
++ status |= (x); \
++ status &= ~(RWC_BITS|WZ_BITS); \
++ writel(status, port_addr)
++
++/* UHCI controllers don't automatically stop resume signalling after 20 msec,
++ * so we have to poll and check timeouts in order to take care of it.
++ */
++static void uhci_finish_suspend(struct uhci_hcd *uhci, int port,
++ unsigned long port_addr)
++{
++ int status;
++ int i;
++//yriver
++// if (inw(port_addr) & SUSPEND_BITS) {
++ if (readl(port_addr) & SUSPEND_BITS) {
++ CLR_RH_PORTSTAT(SUSPEND_BITS);
++ if (test_bit(port, &uhci->resuming_ports))
++ set_bit(port, &uhci->port_c_suspend);
++
++ /* The controller won't actually turn off the RD bit until
++ * it has had a chance to send a low-speed EOP sequence,
++ * which is supposed to take 3 bit times (= 2 microseconds).
++ * Experiments show that some controllers take longer, so
++ * we'll poll for completion. */
++ for (i = 0; i < 10; ++i) {
++//yriver
++// if (!(inw(port_addr) & SUSPEND_BITS))
++ if (!(readl(port_addr) & SUSPEND_BITS))
++ break;
++ udelay(1);
++ }
++ }
++ clear_bit(port, &uhci->resuming_ports);
++}
++
++/* Wait for the UHCI controller in HP's iLO2 server management chip.
++ * It can take up to 250 us to finish a reset and set the CSC bit.
++ */
++static void wait_for_HP(unsigned long port_addr)
++{
++ int i;
++
++ for (i = 10; i < 250; i += 10) {
++//yriver
++// if (inw(port_addr) & USBPORTSC_CSC)
++ if (readl(port_addr) & USBPORTSC_CSC)
++ return;
++ udelay(10);
++ }
++ /* Log a warning? */
++}
++
++static void uhci_check_ports(struct uhci_hcd *uhci)
++{
++ unsigned int port;
++ unsigned long port_addr;
++ int status;
++
++ for (port = 0; port < uhci->rh_numports; ++port) {
++//yriver
++// port_addr = uhci->io_addr + USBPORTSC1 + 2 * port;
++// status = inw(port_addr);
++ port_addr = uhci->regbase + USBPORTSC1 + 1 * port;
++ status = readl(port_addr);
++ if (unlikely(status & USBPORTSC_PR)) {
++ if (time_after_eq(jiffies, uhci->ports_timeout)) {
++ CLR_RH_PORTSTAT(USBPORTSC_PR);
++ udelay(10);
++
++ /* HP's server management chip requires
++ * a longer delay. */
++ if (to_pci_dev(uhci_dev(uhci))->vendor ==
++ PCI_VENDOR_ID_HP)
++ wait_for_HP(port_addr);
++
++ /* If the port was enabled before, turning
++ * reset on caused a port enable change.
++ * Turning reset off causes a port connect
++ * status change. Clear these changes. */
++ CLR_RH_PORTSTAT(USBPORTSC_CSC | USBPORTSC_PEC);
++ SET_RH_PORTSTAT(USBPORTSC_PE);
++ }
++ }
++ if (unlikely(status & USBPORTSC_RD)) {
++ if (!test_bit(port, &uhci->resuming_ports)) {
++
++ /* Port received a wakeup request */
++ set_bit(port, &uhci->resuming_ports);
++ uhci->ports_timeout = jiffies +
++ msecs_to_jiffies(20);
++
++ /* Make sure we see the port again
++ * after the resuming period is over. */
++ mod_timer(&uhci_to_hcd(uhci)->rh_timer,
++ uhci->ports_timeout);
++ } else if (time_after_eq(jiffies,
++ uhci->ports_timeout)) {
++ uhci_finish_suspend(uhci, port, port_addr);
++ }
++ }
++ }
++}
++
++static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf)
++{
++ struct uhci_hcd *uhci = hcd_to_uhci(hcd);
++ unsigned long flags;
++ int status = 0;
++
++ spin_lock_irqsave(&uhci->lock, flags);
++
++ uhci_scan_schedule(uhci);
++ if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) || uhci->dead)
++ goto done;
++ uhci_check_ports(uhci);
++
++ status = get_hub_status_data(uhci, buf);
++
++ switch (uhci->rh_state) {
++ case UHCI_RH_SUSPENDING:
++ case UHCI_RH_SUSPENDED:
++ /* if port change, ask to be resumed */
++ if (status)
++ usb_hcd_resume_root_hub(hcd);
++ break;
++
++ case UHCI_RH_AUTO_STOPPED:
++ /* if port change, auto start */
++ if (status)
++ wakeup_rh(uhci);
++ break;
++
++ case UHCI_RH_RUNNING:
++ /* are any devices attached? */
++ if (!any_ports_active(uhci)) {
++ uhci->rh_state = UHCI_RH_RUNNING_NODEVS;
++ uhci->auto_stop_time = jiffies + HZ;
++ }
++ break;
++
++ case UHCI_RH_RUNNING_NODEVS:
++ /* auto-stop if nothing connected for 1 second */
++ if (any_ports_active(uhci))
++ uhci->rh_state = UHCI_RH_RUNNING;
++//yriver
++// else if (time_after_eq(jiffies, uhci->auto_stop_time))
++// suspend_rh(uhci, UHCI_RH_AUTO_STOPPED);
++ break;
++
++ default:
++ break;
++ }
++
++done:
++ spin_unlock_irqrestore(&uhci->lock, flags);
++ return status;
++}
++
++/* size of returned buffer is part of USB spec */
++static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
++ u16 wIndex, char *buf, u16 wLength)
++{
++ struct uhci_hcd *uhci = hcd_to_uhci(hcd);
++ int status, lstatus, retval = 0, len = 0;
++//yriver
++// unsigned int port = wIndex - 1;
++// unsigned long port_addr = uhci->io_addr + USBPORTSC1 + 2 * port;
++ unsigned int port = wIndex - 1;
++ unsigned long port_addr = uhci->regbase + USBPORTSC1 + 1 * port;
++ u16 wPortChange, wPortStatus;
++ unsigned long flags;
++
++ if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) || uhci->dead)
++ return -ETIMEDOUT;
++
++ spin_lock_irqsave(&uhci->lock, flags);
++ switch (typeReq) {
++
++ case GetHubStatus:
++ *(__le32 *)buf = cpu_to_le32(0);
++ OK(4); /* hub power */
++ case GetPortStatus:
++ if (port >= uhci->rh_numports)
++ goto err;
++
++ uhci_check_ports(uhci);
++//yriver
++// status = inw(port_addr);
++ status = readl(port_addr);
++
++ /* Intel controllers report the OverCurrent bit active on.
++ * VIA controllers report it active off, so we'll adjust the
++ * bit value. (It's not standardized in the UHCI spec.)
++ */
++ if (to_pci_dev(hcd->self.controller)->vendor ==
++ PCI_VENDOR_ID_VIA)
++ status ^= USBPORTSC_OC;
++
++ /* UHCI doesn't support C_RESET (always false) */
++ wPortChange = lstatus = 0;
++ if (status & USBPORTSC_CSC)
++ wPortChange |= USB_PORT_STAT_C_CONNECTION;
++ if (status & USBPORTSC_PEC)
++ wPortChange |= USB_PORT_STAT_C_ENABLE;
++ if ((status & USBPORTSC_OCC) && !ignore_oc)
++ wPortChange |= USB_PORT_STAT_C_OVERCURRENT;
++
++ if (test_bit(port, &uhci->port_c_suspend)) {
++ wPortChange |= USB_PORT_STAT_C_SUSPEND;
++ lstatus |= 1;
++ }
++ if (test_bit(port, &uhci->resuming_ports))
++ lstatus |= 4;
++
++ /* UHCI has no power switching (always on) */
++ wPortStatus = USB_PORT_STAT_POWER;
++ if (status & USBPORTSC_CCS)
++ wPortStatus |= USB_PORT_STAT_CONNECTION;
++ if (status & USBPORTSC_PE) {
++ wPortStatus |= USB_PORT_STAT_ENABLE;
++ if (status & SUSPEND_BITS)
++ wPortStatus |= USB_PORT_STAT_SUSPEND;
++ }
++ if (status & USBPORTSC_OC)
++ wPortStatus |= USB_PORT_STAT_OVERCURRENT;
++ if (status & USBPORTSC_PR)
++ wPortStatus |= USB_PORT_STAT_RESET;
++ if (status & USBPORTSC_LSDA)
++ wPortStatus |= USB_PORT_STAT_LOW_SPEED;
++
++ if (wPortChange)
++ dev_dbg(uhci_dev(uhci), "port %d portsc %04x,%02x\n",
++ wIndex, status, lstatus);
++
++ *(__le16 *)buf = cpu_to_le16(wPortStatus);
++ *(__le16 *)(buf + 2) = cpu_to_le16(wPortChange);
++ OK(4);
++ case SetHubFeature: /* We don't implement these */
++ case ClearHubFeature:
++ switch (wValue) {
++ case C_HUB_OVER_CURRENT:
++ case C_HUB_LOCAL_POWER:
++ OK(0);
++ default:
++ goto err;
++ }
++ break;
++ case SetPortFeature:
++ if (port >= uhci->rh_numports)
++ goto err;
++
++ switch (wValue) {
++ case USB_PORT_FEAT_SUSPEND:
++ SET_RH_PORTSTAT(USBPORTSC_SUSP);
++ OK(0);
++ case USB_PORT_FEAT_RESET:
++ SET_RH_PORTSTAT(USBPORTSC_PR);
++
++ /* Reset terminates Resume signalling */
++ uhci_finish_suspend(uhci, port, port_addr);
++
++ /* USB v2.0 7.1.7.5 */
++ uhci->ports_timeout = jiffies + msecs_to_jiffies(50);
++ OK(0);
++ case USB_PORT_FEAT_POWER:
++ /* UHCI has no power switching */
++ OK(0);
++ default:
++ goto err;
++ }
++ break;
++ case ClearPortFeature:
++ if (port >= uhci->rh_numports)
++ goto err;
++
++ switch (wValue) {
++ case USB_PORT_FEAT_ENABLE:
++ CLR_RH_PORTSTAT(USBPORTSC_PE);
++
++ /* Disable terminates Resume signalling */
++ uhci_finish_suspend(uhci, port, port_addr);
++ OK(0);
++ case USB_PORT_FEAT_C_ENABLE:
++ CLR_RH_PORTSTAT(USBPORTSC_PEC);
++ OK(0);
++ case USB_PORT_FEAT_SUSPEND:
++//yriver
++// if (!(inw(port_addr) & USBPORTSC_SUSP)) {
++ if (!(readl(port_addr) & USBPORTSC_SUSP)) {
++
++ /* Make certain the port isn't suspended */
++ uhci_finish_suspend(uhci, port, port_addr);
++ } else if (!test_and_set_bit(port,
++ &uhci->resuming_ports)) {
++ SET_RH_PORTSTAT(USBPORTSC_RD);
++
++ /* The controller won't allow RD to be set
++ * if the port is disabled. When this happens
++ * just skip the Resume signalling.
++ */
++//yriver
++// if (!(inw(port_addr) & USBPORTSC_RD))
++ if (!(readl(port_addr) & USBPORTSC_RD))
++ uhci_finish_suspend(uhci, port,
++ port_addr);
++ else
++ /* USB v2.0 7.1.7.7 */
++ uhci->ports_timeout = jiffies +
++ msecs_to_jiffies(20);
++ }
++ OK(0);
++ case USB_PORT_FEAT_C_SUSPEND:
++ clear_bit(port, &uhci->port_c_suspend);
++ OK(0);
++ case USB_PORT_FEAT_POWER:
++ /* UHCI has no power switching */
++ goto err;
++ case USB_PORT_FEAT_C_CONNECTION:
++ CLR_RH_PORTSTAT(USBPORTSC_CSC);
++ OK(0);
++ case USB_PORT_FEAT_C_OVER_CURRENT:
++ CLR_RH_PORTSTAT(USBPORTSC_OCC);
++ OK(0);
++ case USB_PORT_FEAT_C_RESET:
++ /* this driver won't report these */
++ OK(0);
++ default:
++ goto err;
++ }
++ break;
++ case GetHubDescriptor:
++ len = min_t(unsigned int, sizeof(root_hub_hub_des), wLength);
++ memcpy(buf, root_hub_hub_des, len);
++ if (len > 2)
++ buf[2] = uhci->rh_numports;
++ OK(len);
++ default:
++err:
++ retval = -EPIPE;
++ }
++ spin_unlock_irqrestore(&uhci->lock, flags);
++
++ return retval;
++}
+diff --git a/drivers/usb/astuhci/uhci-q.c b/drivers/usb/astuhci/uhci-q.c
+new file mode 100644
+index 0000000..eb24599
+--- /dev/null
++++ b/drivers/usb/astuhci/uhci-q.c
+@@ -0,0 +1,1760 @@
++/********************************************************************************
++* File Name : uhci-q.c
++*
++* port from uhci-q.c
++* 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
++********************************************************************************/
++static void uhci_set_next_interrupt(struct uhci_hcd *uhci)
++{
++ if (uhci->is_stopped)
++ mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies);
++ uhci->term_td->status |= cpu_to_le32(TD_CTRL_IOC);
++}
++
++static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci)
++{
++ uhci->term_td->status &= ~cpu_to_le32(TD_CTRL_IOC);
++}
++
++
++/*
++ * Full-Speed Bandwidth Reclamation (FSBR).
++ * We turn on FSBR whenever a queue that wants it is advancing,
++ * and leave it on for a short time thereafter.
++ */
++static void uhci_fsbr_on(struct uhci_hcd *uhci)
++{
++ struct uhci_qh *lqh;
++
++ /* The terminating skeleton QH always points back to the first
++ * FSBR QH. Make the last async QH point to the terminating
++ * skeleton QH. */
++ uhci->fsbr_is_on = 1;
++ lqh = list_entry(uhci->skel_async_qh->node.prev,
++ struct uhci_qh, node);
++ lqh->link = LINK_TO_QH(uhci->skel_term_qh);
++}
++
++static void uhci_fsbr_off(struct uhci_hcd *uhci)
++{
++ struct uhci_qh *lqh;
++
++ /* Remove the link from the last async QH to the terminating
++ * skeleton QH. */
++ uhci->fsbr_is_on = 0;
++ lqh = list_entry(uhci->skel_async_qh->node.prev,
++ struct uhci_qh, node);
++ lqh->link = UHCI_PTR_TERM;
++}
++
++static void uhci_add_fsbr(struct uhci_hcd *uhci, struct urb *urb)
++{
++ struct urb_priv *urbp = urb->hcpriv;
++
++ if (!(urb->transfer_flags & URB_NO_FSBR))
++ urbp->fsbr = 1;
++}
++
++static void uhci_urbp_wants_fsbr(struct uhci_hcd *uhci, struct urb_priv *urbp)
++{
++ if (urbp->fsbr) {
++ uhci->fsbr_is_wanted = 1;
++ if (!uhci->fsbr_is_on)
++ uhci_fsbr_on(uhci);
++ else if (uhci->fsbr_expiring) {
++ uhci->fsbr_expiring = 0;
++ del_timer(&uhci->fsbr_timer);
++ }
++ }
++}
++
++static void uhci_fsbr_timeout(unsigned long _uhci)
++{
++ struct uhci_hcd *uhci = (struct uhci_hcd *) _uhci;
++ unsigned long flags;
++
++ spin_lock_irqsave(&uhci->lock, flags);
++ if (uhci->fsbr_expiring) {
++ uhci->fsbr_expiring = 0;
++ uhci_fsbr_off(uhci);
++ }
++ spin_unlock_irqrestore(&uhci->lock, flags);
++}
++
++
++static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci)
++{
++ dma_addr_t dma_handle;
++ struct uhci_td *td;
++
++ td = dma_pool_alloc(uhci->td_pool, GFP_ATOMIC, &dma_handle);
++ if (!td)
++ return NULL;
++
++ td->dma_handle = dma_handle;
++ td->frame = -1;
++
++ INIT_LIST_HEAD(&td->list);
++ INIT_LIST_HEAD(&td->fl_list);
++
++ return td;
++}
++
++static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td)
++{
++ if (!list_empty(&td->list))
++ dev_WARN(uhci_dev(uhci), "td %p still in list!\n", td);
++ if (!list_empty(&td->fl_list))
++ dev_WARN(uhci_dev(uhci), "td %p still in fl_list!\n", td);
++
++ dma_pool_free(uhci->td_pool, td, td->dma_handle);
++}
++
++static inline void uhci_fill_td(struct uhci_td *td, u32 status,
++ u32 token, u32 buffer)
++{
++ td->status = cpu_to_le32(status);
++ td->token = cpu_to_le32(token);
++ td->buffer = cpu_to_le32(buffer);
++}
++
++static void uhci_add_td_to_urbp(struct uhci_td *td, struct urb_priv *urbp)
++{
++ list_add_tail(&td->list, &urbp->td_list);
++}
++
++static void uhci_remove_td_from_urbp(struct uhci_td *td)
++{
++ list_del_init(&td->list);
++}
++
++/*
++ * We insert Isochronous URBs directly into the frame list at the beginning
++ */
++static inline void uhci_insert_td_in_frame_list(struct uhci_hcd *uhci,
++ struct uhci_td *td, unsigned framenum)
++{
++ framenum &= (UHCI_NUMFRAMES - 1);
++
++ td->frame = framenum;
++
++ /* Is there a TD already mapped there? */
++ if (uhci->frame_cpu[framenum]) {
++ struct uhci_td *ftd, *ltd;
++
++ ftd = uhci->frame_cpu[framenum];
++ ltd = list_entry(ftd->fl_list.prev, struct uhci_td, fl_list);
++
++ list_add_tail(&td->fl_list, &ftd->fl_list);
++
++ td->link = ltd->link;
++ wmb();
++ ltd->link = LINK_TO_TD(td);
++ } else {
++ td->link = uhci->frame[framenum];
++ wmb();
++ uhci->frame[framenum] = LINK_TO_TD(td);
++ uhci->frame_cpu[framenum] = td;
++ }
++}
++
++static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci,
++ struct uhci_td *td)
++{
++ /* If it's not inserted, don't remove it */
++ if (td->frame == -1) {
++ WARN_ON(!list_empty(&td->fl_list));
++ return;
++ }
++
++ if (uhci->frame_cpu[td->frame] == td) {
++ if (list_empty(&td->fl_list)) {
++ uhci->frame[td->frame] = td->link;
++ uhci->frame_cpu[td->frame] = NULL;
++ } else {
++ struct uhci_td *ntd;
++
++ ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list);
++ uhci->frame[td->frame] = LINK_TO_TD(ntd);
++ uhci->frame_cpu[td->frame] = ntd;
++ }
++ } else {
++ struct uhci_td *ptd;
++
++ ptd = list_entry(td->fl_list.prev, struct uhci_td, fl_list);
++ ptd->link = td->link;
++ }
++
++ list_del_init(&td->fl_list);
++ td->frame = -1;
++}
++
++static inline void uhci_remove_tds_from_frame(struct uhci_hcd *uhci,
++ unsigned int framenum)
++{
++ struct uhci_td *ftd, *ltd;
++
++ framenum &= (UHCI_NUMFRAMES - 1);
++
++ ftd = uhci->frame_cpu[framenum];
++ if (ftd) {
++ ltd = list_entry(ftd->fl_list.prev, struct uhci_td, fl_list);
++ uhci->frame[framenum] = ltd->link;
++ uhci->frame_cpu[framenum] = NULL;
++
++ while (!list_empty(&ftd->fl_list))
++ list_del_init(ftd->fl_list.prev);
++ }
++}
++
++/*
++ * Remove all the TDs for an Isochronous URB from the frame list
++ */
++static void uhci_unlink_isochronous_tds(struct uhci_hcd *uhci, struct urb *urb)
++{
++ struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
++ struct uhci_td *td;
++
++ list_for_each_entry(td, &urbp->td_list, list)
++ uhci_remove_td_from_frame_list(uhci, td);
++}
++
++static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci,
++ struct usb_device *udev, struct usb_host_endpoint *hep)
++{
++ dma_addr_t dma_handle;
++ struct uhci_qh *qh;
++
++ qh = dma_pool_alloc(uhci->qh_pool, GFP_ATOMIC, &dma_handle);
++ if (!qh)
++ return NULL;
++
++ memset(qh, 0, sizeof(*qh));
++ qh->dma_handle = dma_handle;
++
++ qh->element = UHCI_PTR_TERM;
++ qh->link = UHCI_PTR_TERM;
++
++ INIT_LIST_HEAD(&qh->queue);
++ INIT_LIST_HEAD(&qh->node);
++
++ if (udev) { /* Normal QH */
++ qh->type = hep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
++ if (qh->type != USB_ENDPOINT_XFER_ISOC) {
++ qh->dummy_td = uhci_alloc_td(uhci);
++ if (!qh->dummy_td) {
++ dma_pool_free(uhci->qh_pool, qh, dma_handle);
++ return NULL;
++ }
++ }
++//yriver
++// qh->state = QH_STATE_IDLE;
++ qh->state = UHCI_QH_STATE_IDLE;
++ qh->hep = hep;
++ qh->udev = udev;
++ hep->hcpriv = qh;
++
++ if (qh->type == USB_ENDPOINT_XFER_INT ||
++ qh->type == USB_ENDPOINT_XFER_ISOC)
++ qh->load = usb_calc_bus_time(udev->speed,
++ usb_endpoint_dir_in(&hep->desc),
++ qh->type == USB_ENDPOINT_XFER_ISOC,
++ le16_to_cpu(hep->desc.wMaxPacketSize))
++ / 1000 + 1;
++
++ } else { /* Skeleton QH */
++ qh->state = QH_STATE_ACTIVE;
++ qh->type = -1;
++ }
++ return qh;
++}
++
++static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
++{
++//yriver
++// WARN_ON(qh->state != QH_STATE_IDLE && qh->udev);
++ WARN_ON(qh->state != UHCI_QH_STATE_IDLE && qh->udev);
++ if (!list_empty(&qh->queue))
++ dev_WARN(uhci_dev(uhci), "qh %p list not empty!\n", qh);
++
++ list_del(&qh->node);
++ if (qh->udev) {
++ qh->hep->hcpriv = NULL;
++ if (qh->dummy_td)
++ uhci_free_td(uhci, qh->dummy_td);
++ }
++ dma_pool_free(uhci->qh_pool, qh, qh->dma_handle);
++}
++
++/*
++ * When a queue is stopped and a dequeued URB is given back, adjust
++ * the previous TD link (if the URB isn't first on the queue) or
++ * save its toggle value (if it is first and is currently executing).
++ *
++ * Returns 0 if the URB should not yet be given back, 1 otherwise.
++ */
++static int uhci_cleanup_queue(struct uhci_hcd *uhci, struct uhci_qh *qh,
++ struct urb *urb)
++{
++ struct urb_priv *urbp = urb->hcpriv;
++ struct uhci_td *td;
++ int ret = 1;
++
++ /* Isochronous pipes don't use toggles and their TD link pointers
++ * get adjusted during uhci_urb_dequeue(). But since their queues
++ * cannot truly be stopped, we have to watch out for dequeues
++ * occurring after the nominal unlink frame. */
++ if (qh->type == USB_ENDPOINT_XFER_ISOC) {
++ ret = (uhci->frame_number + uhci->is_stopped !=
++ qh->unlink_frame);
++ goto done;
++ }
++
++ /* If the URB isn't first on its queue, adjust the link pointer
++ * of the last TD in the previous URB. The toggle doesn't need
++ * to be saved since this URB can't be executing yet. */
++ if (qh->queue.next != &urbp->node) {
++ struct urb_priv *purbp;
++ struct uhci_td *ptd;
++
++ purbp = list_entry(urbp->node.prev, struct urb_priv, node);
++ WARN_ON(list_empty(&purbp->td_list));
++ ptd = list_entry(purbp->td_list.prev, struct uhci_td,
++ list);
++ td = list_entry(urbp->td_list.prev, struct uhci_td,
++ list);
++ ptd->link = td->link;
++ goto done;
++ }
++
++ /* If the QH element pointer is UHCI_PTR_TERM then then currently
++ * executing URB has already been unlinked, so this one isn't it. */
++ if (qh_element(qh) == UHCI_PTR_TERM)
++ goto done;
++ qh->element = UHCI_PTR_TERM;
++
++ /* Control pipes don't have to worry about toggles */
++ if (qh->type == USB_ENDPOINT_XFER_CONTROL)
++ goto done;
++
++ /* Save the next toggle value */
++ WARN_ON(list_empty(&urbp->td_list));
++ td = list_entry(urbp->td_list.next, struct uhci_td, list);
++ qh->needs_fixup = 1;
++ qh->initial_toggle = uhci_toggle(td_token(td));
++
++done:
++ return ret;
++}
++
++/*
++ * Fix up the data toggles for URBs in a queue, when one of them
++ * terminates early (short transfer, error, or dequeued).
++ */
++static void uhci_fixup_toggles(struct uhci_qh *qh, int skip_first)
++{
++ struct urb_priv *urbp = NULL;
++ struct uhci_td *td;
++ unsigned int toggle = qh->initial_toggle;
++ unsigned int pipe;
++
++ /* Fixups for a short transfer start with the second URB in the
++ * queue (the short URB is the first). */
++ if (skip_first)
++ urbp = list_entry(qh->queue.next, struct urb_priv, node);
++
++ /* When starting with the first URB, if the QH element pointer is
++ * still valid then we know the URB's toggles are okay. */
++ else if (qh_element(qh) != UHCI_PTR_TERM)
++ toggle = 2;
++
++ /* Fix up the toggle for the URBs in the queue. Normally this
++ * loop won't run more than once: When an error or short transfer
++ * occurs, the queue usually gets emptied. */
++ urbp = list_prepare_entry(urbp, &qh->queue, node);
++ list_for_each_entry_continue(urbp, &qh->queue, node) {
++
++ /* If the first TD has the right toggle value, we don't
++ * need to change any toggles in this URB */
++ td = list_entry(urbp->td_list.next, struct uhci_td, list);
++ if (toggle > 1 || uhci_toggle(td_token(td)) == toggle) {
++ td = list_entry(urbp->td_list.prev, struct uhci_td,
++ list);
++ toggle = uhci_toggle(td_token(td)) ^ 1;
++
++ /* Otherwise all the toggles in the URB have to be switched */
++ } else {
++ list_for_each_entry(td, &urbp->td_list, list) {
++ td->token ^= __constant_cpu_to_le32(
++ TD_TOKEN_TOGGLE);
++ toggle ^= 1;
++ }
++ }
++ }
++
++ wmb();
++ pipe = list_entry(qh->queue.next, struct urb_priv, node)->urb->pipe;
++ usb_settoggle(qh->udev, usb_pipeendpoint(pipe),
++ usb_pipeout(pipe), toggle);
++ qh->needs_fixup = 0;
++}
++
++/*
++ * Link an Isochronous QH into its skeleton's list
++ */
++static inline void link_iso(struct uhci_hcd *uhci, struct uhci_qh *qh)
++{
++ list_add_tail(&qh->node, &uhci->skel_iso_qh->node);
++
++ /* Isochronous QHs aren't linked by the hardware */
++}
++
++/*
++ * Link a high-period interrupt QH into the schedule at the end of its
++ * skeleton's list
++ */
++static void link_interrupt(struct uhci_hcd *uhci, struct uhci_qh *qh)
++{
++ struct uhci_qh *pqh;
++
++ list_add_tail(&qh->node, &uhci->skelqh[qh->skel]->node);
++
++ pqh = list_entry(qh->node.prev, struct uhci_qh, node);
++ qh->link = pqh->link;
++ wmb();
++ pqh->link = LINK_TO_QH(qh);
++}
++
++/*
++ * Link a period-1 interrupt or async QH into the schedule at the
++ * correct spot in the async skeleton's list, and update the FSBR link
++ */
++static void link_async(struct uhci_hcd *uhci, struct uhci_qh *qh)
++{
++ struct uhci_qh *pqh;
++ __le32 link_to_new_qh;
++
++ /* Find the predecessor QH for our new one and insert it in the list.
++ * The list of QHs is expected to be short, so linear search won't
++ * take too long. */
++ list_for_each_entry_reverse(pqh, &uhci->skel_async_qh->node, node) {
++ if (pqh->skel <= qh->skel)
++ break;
++ }
++ list_add(&qh->node, &pqh->node);
++
++ /* Link it into the schedule */
++ qh->link = pqh->link;
++ wmb();
++ link_to_new_qh = LINK_TO_QH(qh);
++ pqh->link = link_to_new_qh;
++
++ /* If this is now the first FSBR QH, link the terminating skeleton
++ * QH to it. */
++ if (pqh->skel < SKEL_FSBR && qh->skel >= SKEL_FSBR)
++ uhci->skel_term_qh->link = link_to_new_qh;
++}
++
++/*
++ * Put a QH on the schedule in both hardware and software
++ */
++static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
++{
++ WARN_ON(list_empty(&qh->queue));
++
++ /* Set the element pointer if it isn't set already.
++ * This isn't needed for Isochronous queues, but it doesn't hurt. */
++ if (qh_element(qh) == UHCI_PTR_TERM) {
++ struct urb_priv *urbp = list_entry(qh->queue.next,
++ struct urb_priv, node);
++ struct uhci_td *td = list_entry(urbp->td_list.next,
++ struct uhci_td, list);
++
++ qh->element = LINK_TO_TD(td);
++ }
++
++ /* Treat the queue as if it has just advanced */
++ qh->wait_expired = 0;
++ qh->advance_jiffies = jiffies;
++
++ if (qh->state == QH_STATE_ACTIVE)
++ return;
++ qh->state = QH_STATE_ACTIVE;
++
++ /* Move the QH from its old list to the correct spot in the appropriate
++ * skeleton's list */
++ if (qh == uhci->next_qh)
++ uhci->next_qh = list_entry(qh->node.next, struct uhci_qh,
++ node);
++ list_del(&qh->node);
++
++ if (qh->skel == SKEL_ISO)
++ link_iso(uhci, qh);
++ else if (qh->skel < SKEL_ASYNC)
++ link_interrupt(uhci, qh);
++ else
++ link_async(uhci, qh);
++}
++
++/*
++ * Unlink a high-period interrupt QH from the schedule
++ */
++static void unlink_interrupt(struct uhci_hcd *uhci, struct uhci_qh *qh)
++{
++ struct uhci_qh *pqh;
++
++ pqh = list_entry(qh->node.prev, struct uhci_qh, node);
++ pqh->link = qh->link;
++ mb();
++}
++
++/*
++ * Unlink a period-1 interrupt or async QH from the schedule
++ */
++static void unlink_async(struct uhci_hcd *uhci, struct uhci_qh *qh)
++{
++ struct uhci_qh *pqh;
++ __le32 link_to_next_qh = qh->link;
++
++ pqh = list_entry(qh->node.prev, struct uhci_qh, node);
++ pqh->link = link_to_next_qh;
++
++ /* If this was the old first FSBR QH, link the terminating skeleton
++ * QH to the next (new first FSBR) QH. */
++ if (pqh->skel < SKEL_FSBR && qh->skel >= SKEL_FSBR)
++ uhci->skel_term_qh->link = link_to_next_qh;
++ mb();
++}
++
++/*
++ * Take a QH off the hardware schedule
++ */
++static void uhci_unlink_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
++{
++ if (qh->state == QH_STATE_UNLINKING)
++ return;
++ WARN_ON(qh->state != QH_STATE_ACTIVE || !qh->udev);
++ qh->state = QH_STATE_UNLINKING;
++
++ /* Unlink the QH from the schedule and record when we did it */
++ if (qh->skel == SKEL_ISO)
++ ;
++ else if (qh->skel < SKEL_ASYNC)
++ unlink_interrupt(uhci, qh);
++ else
++ unlink_async(uhci, qh);
++
++ uhci_get_current_frame_number(uhci);
++ qh->unlink_frame = uhci->frame_number;
++
++ /* Force an interrupt so we know when the QH is fully unlinked */
++ if (list_empty(&uhci->skel_unlink_qh->node))
++ uhci_set_next_interrupt(uhci);
++
++ /* Move the QH from its old list to the end of the unlinking list */
++ if (qh == uhci->next_qh)
++ uhci->next_qh = list_entry(qh->node.next, struct uhci_qh,
++ node);
++ list_move_tail(&qh->node, &uhci->skel_unlink_qh->node);
++}
++
++/*
++ * When we and the controller are through with a QH, it becomes IDLE.
++ * This happens when a QH has been off the schedule (on the unlinking
++ * list) for more than one frame, or when an error occurs while adding
++ * the first URB onto a new QH.
++ */
++static void uhci_make_qh_idle(struct uhci_hcd *uhci, struct uhci_qh *qh)
++{
++ WARN_ON(qh->state == QH_STATE_ACTIVE);
++
++ if (qh == uhci->next_qh)
++ uhci->next_qh = list_entry(qh->node.next, struct uhci_qh,
++ node);
++ list_move(&qh->node, &uhci->idle_qh_list);
++//yriver
++// qh->state = QH_STATE_IDLE;
++ qh->state = UHCI_QH_STATE_IDLE;
++
++ /* Now that the QH is idle, its post_td isn't being used */
++ if (qh->post_td) {
++ uhci_free_td(uhci, qh->post_td);
++ qh->post_td = NULL;
++ }
++
++ /* If anyone is waiting for a QH to become idle, wake them up */
++ if (uhci->num_waiting)
++ wake_up_all(&uhci->waitqh);
++}
++
++/*
++ * Find the highest existing bandwidth load for a given phase and period.
++ */
++static int uhci_highest_load(struct uhci_hcd *uhci, int phase, int period)
++{
++ int highest_load = uhci->load[phase];
++
++ for (phase += period; phase < MAX_PHASE; phase += period)
++ highest_load = max_t(int, highest_load, uhci->load[phase]);
++ return highest_load;
++}
++
++/*
++ * Set qh->phase to the optimal phase for a periodic transfer and
++ * check whether the bandwidth requirement is acceptable.
++ */
++static int uhci_check_bandwidth(struct uhci_hcd *uhci, struct uhci_qh *qh)
++{
++ int minimax_load;
++
++ /* Find the optimal phase (unless it is already set) and get
++ * its load value. */
++ if (qh->phase >= 0)
++ minimax_load = uhci_highest_load(uhci, qh->phase, qh->period);
++ else {
++ int phase, load;
++ int max_phase = min_t(int, MAX_PHASE, qh->period);
++
++ qh->phase = 0;
++ minimax_load = uhci_highest_load(uhci, qh->phase, qh->period);
++ for (phase = 1; phase < max_phase; ++phase) {
++ load = uhci_highest_load(uhci, phase, qh->period);
++ if (load < minimax_load) {
++ minimax_load = load;
++ qh->phase = phase;
++ }
++ }
++ }
++
++ /* Maximum allowable periodic bandwidth is 90%, or 900 us per frame */
++ if (minimax_load + qh->load > 900) {
++ dev_dbg(uhci_dev(uhci), "bandwidth allocation failed: "
++ "period %d, phase %d, %d + %d us\n",
++ qh->period, qh->phase, minimax_load, qh->load);
++ return -ENOSPC;
++ }
++ return 0;
++}
++
++/*
++ * Reserve a periodic QH's bandwidth in the schedule
++ */
++static void uhci_reserve_bandwidth(struct uhci_hcd *uhci, struct uhci_qh *qh)
++{
++ int i;
++ int load = qh->load;
++ char *p = "??";
++
++ for (i = qh->phase; i < MAX_PHASE; i += qh->period) {
++ uhci->load[i] += load;
++ uhci->total_load += load;
++ }
++ uhci_to_hcd(uhci)->self.bandwidth_allocated =
++ uhci->total_load / MAX_PHASE;
++ switch (qh->type) {
++ case USB_ENDPOINT_XFER_INT:
++ ++uhci_to_hcd(uhci)->self.bandwidth_int_reqs;
++ p = "INT";
++ break;
++ case USB_ENDPOINT_XFER_ISOC:
++ ++uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs;
++ p = "ISO";
++ break;
++ }
++ qh->bandwidth_reserved = 1;
++ dev_dbg(uhci_dev(uhci),
++ "%s dev %d ep%02x-%s, period %d, phase %d, %d us\n",
++ "reserve", qh->udev->devnum,
++ qh->hep->desc.bEndpointAddress, p,
++ qh->period, qh->phase, load);
++}
++
++/*
++ * Release a periodic QH's bandwidth reservation
++ */
++static void uhci_release_bandwidth(struct uhci_hcd *uhci, struct uhci_qh *qh)
++{
++ int i;
++ int load = qh->load;
++ char *p = "??";
++
++ for (i = qh->phase; i < MAX_PHASE; i += qh->period) {
++ uhci->load[i] -= load;
++ uhci->total_load -= load;
++ }
++ uhci_to_hcd(uhci)->self.bandwidth_allocated =
++ uhci->total_load / MAX_PHASE;
++ switch (qh->type) {
++ case USB_ENDPOINT_XFER_INT:
++ --uhci_to_hcd(uhci)->self.bandwidth_int_reqs;
++ p = "INT";
++ break;
++ case USB_ENDPOINT_XFER_ISOC:
++ --uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs;
++ p = "ISO";
++ break;
++ }
++ qh->bandwidth_reserved = 0;
++ dev_dbg(uhci_dev(uhci),
++ "%s dev %d ep%02x-%s, period %d, phase %d, %d us\n",
++ "release", qh->udev->devnum,
++ qh->hep->desc.bEndpointAddress, p,
++ qh->period, qh->phase, load);
++}
++
++static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci,
++ struct urb *urb)
++{
++ struct urb_priv *urbp;
++
++ urbp = kmem_cache_zalloc(uhci_up_cachep, GFP_ATOMIC);
++ if (!urbp)
++ return NULL;
++
++ urbp->urb = urb;
++ urb->hcpriv = urbp;
++
++ INIT_LIST_HEAD(&urbp->node);
++ INIT_LIST_HEAD(&urbp->td_list);
++
++ return urbp;
++}
++
++static void uhci_free_urb_priv(struct uhci_hcd *uhci,
++ struct urb_priv *urbp)
++{
++ struct uhci_td *td, *tmp;
++
++ if (!list_empty(&urbp->node))
++ dev_WARN(uhci_dev(uhci), "urb %p still on QH's list!\n",
++ urbp->urb);
++
++ list_for_each_entry_safe(td, tmp, &urbp->td_list, list) {
++ uhci_remove_td_from_urbp(td);
++ uhci_free_td(uhci, td);
++ }
++
++ kmem_cache_free(uhci_up_cachep, urbp);
++}
++
++/*
++ * Map status to standard result codes
++ *
++ * <status> is (td_status(td) & 0xF60000), a.k.a.
++ * uhci_status_bits(td_status(td)).
++ * Note: <status> does not include the TD_CTRL_NAK bit.
++ * <dir_out> is True for output TDs and False for input TDs.
++ */
++static int uhci_map_status(int status, int dir_out)
++{
++ if (!status)
++ return 0;
++ if (status & TD_CTRL_BITSTUFF) /* Bitstuff error */
++ return -EPROTO;
++ if (status & TD_CTRL_CRCTIMEO) { /* CRC/Timeout */
++ if (dir_out)
++ return -EPROTO;
++ else
++ return -EILSEQ;
++ }
++ if (status & TD_CTRL_BABBLE) /* Babble */
++ return -EOVERFLOW;
++ if (status & TD_CTRL_DBUFERR) /* Buffer error */
++ return -ENOSR;
++ if (status & TD_CTRL_STALLED) /* Stalled */
++ return -EPIPE;
++ return 0;
++}
++
++/*
++ * Control transfers
++ */
++static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
++ struct uhci_qh *qh)
++{
++ struct uhci_td *td;
++ unsigned long destination, status;
++ int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize);
++ int len = urb->transfer_buffer_length;
++ dma_addr_t data = urb->transfer_dma;
++ __le32 *plink;
++ struct urb_priv *urbp = urb->hcpriv;
++ int skel;
++
++ /* The "pipe" thing contains the destination in bits 8--18 */
++ destination = (urb->pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP;
++
++ /* 3 errors, dummy TD remains inactive */
++ status = uhci_maxerr(3);
++ if (urb->dev->speed == USB_SPEED_LOW)
++ status |= TD_CTRL_LS;
++
++ /*
++ * Build the TD for the control request setup packet
++ */
++ td = qh->dummy_td;
++ uhci_add_td_to_urbp(td, urbp);
++ uhci_fill_td(td, status, destination | uhci_explen(8),
++ urb->setup_dma);
++ plink = &td->link;
++ status |= TD_CTRL_ACTIVE;
++
++ /*
++ * If direction is "send", change the packet ID from SETUP (0x2D)
++ * to OUT (0xE1). Else change it from SETUP to IN (0x69) and
++ * set Short Packet Detect (SPD) for all data packets.
++ *
++ * 0-length transfers always get treated as "send".
++ */
++ if (usb_pipeout(urb->pipe) || len == 0)
++ destination ^= (USB_PID_SETUP ^ USB_PID_OUT);
++ else {
++ destination ^= (USB_PID_SETUP ^ USB_PID_IN);
++ status |= TD_CTRL_SPD;
++ }
++
++ /*
++ * Build the DATA TDs
++ */
++ while (len > 0) {
++ int pktsze = maxsze;
++
++ if (len <= pktsze) { /* The last data packet */
++ pktsze = len;
++ status &= ~TD_CTRL_SPD;
++ }
++
++ td = uhci_alloc_td(uhci);
++ if (!td)
++ goto nomem;
++ *plink = LINK_TO_TD(td);
++
++ /* Alternate Data0/1 (start with Data1) */
++ destination ^= TD_TOKEN_TOGGLE;
++
++ uhci_add_td_to_urbp(td, urbp);
++ uhci_fill_td(td, status, destination | uhci_explen(pktsze),
++ data);
++ plink = &td->link;
++
++ data += pktsze;
++ len -= pktsze;
++ }
++
++ /*
++ * Build the final TD for control status
++ */
++ td = uhci_alloc_td(uhci);
++ if (!td)
++ goto nomem;
++ *plink = LINK_TO_TD(td);
++
++ /* Change direction for the status transaction */
++ destination ^= (USB_PID_IN ^ USB_PID_OUT);
++ destination |= TD_TOKEN_TOGGLE; /* End in Data1 */
++
++ uhci_add_td_to_urbp(td, urbp);
++ uhci_fill_td(td, status | TD_CTRL_IOC,
++ destination | uhci_explen(0), 0);
++ plink = &td->link;
++
++ /*
++ * Build the new dummy TD and activate the old one
++ */
++ td = uhci_alloc_td(uhci);
++ if (!td)
++ goto nomem;
++ *plink = LINK_TO_TD(td);
++
++ uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0);
++ wmb();
++ qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE);
++ qh->dummy_td = td;
++
++ /* Low-speed transfers get a different queue, and won't hog the bus.
++ * Also, some devices enumerate better without FSBR; the easiest way
++ * to do that is to put URBs on the low-speed queue while the device
++ * isn't in the CONFIGURED state. */
++ if (urb->dev->speed == USB_SPEED_LOW ||
++ urb->dev->state != USB_STATE_CONFIGURED)
++ skel = SKEL_LS_CONTROL;
++ else {
++ skel = SKEL_FS_CONTROL;
++ uhci_add_fsbr(uhci, urb);
++ }
++ if (qh->state != QH_STATE_ACTIVE)
++ qh->skel = skel;
++
++ urb->actual_length = -8; /* Account for the SETUP packet */
++ return 0;
++
++nomem:
++ /* Remove the dummy TD from the td_list so it doesn't get freed */
++ uhci_remove_td_from_urbp(qh->dummy_td);
++ return -ENOMEM;
++}
++
++/*
++ * Common submit for bulk and interrupt
++ */
++static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
++ struct uhci_qh *qh)
++{
++ struct uhci_td *td;
++ unsigned long destination, status;
++ int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize);
++ int len = urb->transfer_buffer_length;
++ dma_addr_t data = urb->transfer_dma;
++ __le32 *plink;
++ struct urb_priv *urbp = urb->hcpriv;
++ unsigned int toggle;
++
++ if (len < 0)
++ return -EINVAL;
++
++ /* The "pipe" thing contains the destination in bits 8--18 */
++ destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe);
++ toggle = usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
++ usb_pipeout(urb->pipe));
++
++ /* 3 errors, dummy TD remains inactive */
++ status = uhci_maxerr(3);
++ if (urb->dev->speed == USB_SPEED_LOW)
++ status |= TD_CTRL_LS;
++ if (usb_pipein(urb->pipe))
++ status |= TD_CTRL_SPD;
++
++ /*
++ * Build the DATA TDs
++ */
++ plink = NULL;
++ td = qh->dummy_td;
++ do { /* Allow zero length packets */
++ int pktsze = maxsze;
++
++ if (len <= pktsze) { /* The last packet */
++ pktsze = len;
++ if (!(urb->transfer_flags & URB_SHORT_NOT_OK))
++ status &= ~TD_CTRL_SPD;
++ }
++
++ if (plink) {
++ td = uhci_alloc_td(uhci);
++ if (!td)
++ goto nomem;
++ *plink = LINK_TO_TD(td);
++ }
++ uhci_add_td_to_urbp(td, urbp);
++ uhci_fill_td(td, status,
++ destination | uhci_explen(pktsze) |
++ (toggle << TD_TOKEN_TOGGLE_SHIFT),
++ data);
++ plink = &td->link;
++ status |= TD_CTRL_ACTIVE;
++
++ data += pktsze;
++ len -= maxsze;
++ toggle ^= 1;
++ } while (len > 0);
++
++ /*
++ * URB_ZERO_PACKET means adding a 0-length packet, if direction
++ * is OUT and the transfer_length was an exact multiple of maxsze,
++ * hence (len = transfer_length - N * maxsze) == 0
++ * however, if transfer_length == 0, the zero packet was already
++ * prepared above.
++ */
++ if ((urb->transfer_flags & URB_ZERO_PACKET) &&
++ usb_pipeout(urb->pipe) && len == 0 &&
++ urb->transfer_buffer_length > 0) {
++ td = uhci_alloc_td(uhci);
++ if (!td)
++ goto nomem;
++ *plink = LINK_TO_TD(td);
++
++ uhci_add_td_to_urbp(td, urbp);
++ uhci_fill_td(td, status,
++ destination | uhci_explen(0) |
++ (toggle << TD_TOKEN_TOGGLE_SHIFT),
++ data);
++ plink = &td->link;
++
++ toggle ^= 1;
++ }
++
++ /* Set the interrupt-on-completion flag on the last packet.
++ * A more-or-less typical 4 KB URB (= size of one memory page)
++ * will require about 3 ms to transfer; that's a little on the
++ * fast side but not enough to justify delaying an interrupt
++ * more than 2 or 3 URBs, so we will ignore the URB_NO_INTERRUPT
++ * flag setting. */
++ td->status |= __constant_cpu_to_le32(TD_CTRL_IOC);
++
++ /*
++ * Build the new dummy TD and activate the old one
++ */
++ td = uhci_alloc_td(uhci);
++ if (!td)
++ goto nomem;
++ *plink = LINK_TO_TD(td);
++
++ uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0);
++ wmb();
++ qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE);
++ qh->dummy_td = td;
++
++ usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
++ usb_pipeout(urb->pipe), toggle);
++ return 0;
++
++nomem:
++ /* Remove the dummy TD from the td_list so it doesn't get freed */
++ uhci_remove_td_from_urbp(qh->dummy_td);
++ return -ENOMEM;
++}
++
++static int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb,
++ struct uhci_qh *qh)
++{
++ int ret;
++
++ /* Can't have low-speed bulk transfers */
++ if (urb->dev->speed == USB_SPEED_LOW)
++ return -EINVAL;
++
++ if (qh->state != QH_STATE_ACTIVE)
++ qh->skel = SKEL_BULK;
++ ret = uhci_submit_common(uhci, urb, qh);
++ if (ret == 0)
++ uhci_add_fsbr(uhci, urb);
++ return ret;
++}
++
++static int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb,
++ struct uhci_qh *qh)
++{
++ int ret;
++
++ /* USB 1.1 interrupt transfers only involve one packet per interval.
++ * Drivers can submit URBs of any length, but longer ones will need
++ * multiple intervals to complete.
++ */
++
++ if (!qh->bandwidth_reserved) {
++ int exponent;
++
++ /* Figure out which power-of-two queue to use */
++ for (exponent = 7; exponent >= 0; --exponent) {
++ if ((1 << exponent) <= urb->interval)
++ break;
++ }
++ if (exponent < 0)
++ return -EINVAL;
++
++ /* If the slot is full, try a lower period */
++ do {
++ qh->period = 1 << exponent;
++ qh->skel = SKEL_INDEX(exponent);
++
++ /* For now, interrupt phase is fixed by the layout
++ * of the QH lists.
++ */
++ qh->phase = (qh->period / 2) & (MAX_PHASE - 1);
++ ret = uhci_check_bandwidth(uhci, qh);
++ } while (ret != 0 && --exponent >= 0);
++ if (ret)
++ return ret;
++ } else if (qh->period > urb->interval)
++ return -EINVAL; /* Can't decrease the period */
++
++ ret = uhci_submit_common(uhci, urb, qh);
++ if (ret == 0) {
++ urb->interval = qh->period;
++ if (!qh->bandwidth_reserved)
++ uhci_reserve_bandwidth(uhci, qh);
++ }
++ return ret;
++}
++
++/*
++ * Fix up the data structures following a short transfer
++ */
++static int uhci_fixup_short_transfer(struct uhci_hcd *uhci,
++ struct uhci_qh *qh, struct urb_priv *urbp)
++{
++ struct uhci_td *td;
++ struct list_head *tmp;
++ int ret;
++
++ td = list_entry(urbp->td_list.prev, struct uhci_td, list);
++ if (qh->type == USB_ENDPOINT_XFER_CONTROL) {
++
++ /* When a control transfer is short, we have to restart
++ * the queue at the status stage transaction, which is
++ * the last TD. */
++ WARN_ON(list_empty(&urbp->td_list));
++ qh->element = LINK_TO_TD(td);
++ tmp = td->list.prev;
++ ret = -EINPROGRESS;
++
++ } else {
++
++ /* When a bulk/interrupt transfer is short, we have to
++ * fix up the toggles of the following URBs on the queue
++ * before restarting the queue at the next URB. */
++ qh->initial_toggle = uhci_toggle(td_token(qh->post_td)) ^ 1;
++ uhci_fixup_toggles(qh, 1);
++
++ if (list_empty(&urbp->td_list))
++ td = qh->post_td;
++ qh->element = td->link;
++ tmp = urbp->td_list.prev;
++ ret = 0;
++ }
++
++ /* Remove all the TDs we skipped over, from tmp back to the start */
++ while (tmp != &urbp->td_list) {
++ td = list_entry(tmp, struct uhci_td, list);
++ tmp = tmp->prev;
++
++ uhci_remove_td_from_urbp(td);
++ uhci_free_td(uhci, td);
++ }
++ return ret;
++}
++
++/*
++ * Common result for control, bulk, and interrupt
++ */
++static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb)
++{
++ struct urb_priv *urbp = urb->hcpriv;
++ struct uhci_qh *qh = urbp->qh;
++ struct uhci_td *td, *tmp;
++ unsigned status;
++ int ret = 0;
++
++ list_for_each_entry_safe(td, tmp, &urbp->td_list, list) {
++ unsigned int ctrlstat;
++ int len;
++
++ ctrlstat = td_status(td);
++ status = uhci_status_bits(ctrlstat);
++ if (status & TD_CTRL_ACTIVE)
++ return -EINPROGRESS;
++
++ len = uhci_actual_length(ctrlstat);
++ urb->actual_length += len;
++
++ if (status) {
++ ret = uhci_map_status(status,
++ uhci_packetout(td_token(td)));
++ if ((debug == 1 && ret != -EPIPE) || debug > 1) {
++ /* Some debugging code */
++ dev_dbg(&urb->dev->dev,
++ "%s: failed with status %x\n",
++ __func__, status);
++
++ if (debug > 1 && errbuf) {
++ /* Print the chain for debugging */
++ uhci_show_qh(uhci, urbp->qh, errbuf,
++ ERRBUF_LEN, 0);
++ lprintk(errbuf);
++ }
++ }
++
++ /* Did we receive a short packet? */
++ } else if (len < uhci_expected_length(td_token(td))) {
++
++ /* For control transfers, go to the status TD if
++ * this isn't already the last data TD */
++ if (qh->type == USB_ENDPOINT_XFER_CONTROL) {
++ if (td->list.next != urbp->td_list.prev)
++ ret = 1;
++ }
++
++ /* For bulk and interrupt, this may be an error */
++ else if (urb->transfer_flags & URB_SHORT_NOT_OK)
++ ret = -EREMOTEIO;
++
++ /* Fixup needed only if this isn't the URB's last TD */
++ else if (&td->list != urbp->td_list.prev)
++ ret = 1;
++ }
++
++ uhci_remove_td_from_urbp(td);
++ if (qh->post_td)
++ uhci_free_td(uhci, qh->post_td);
++ qh->post_td = td;
++
++ if (ret != 0)
++ goto err;
++ }
++ return ret;
++
++err:
++ if (ret < 0) {
++ /* Note that the queue has stopped and save
++ * the next toggle value */
++ qh->element = UHCI_PTR_TERM;
++ qh->is_stopped = 1;
++ qh->needs_fixup = (qh->type != USB_ENDPOINT_XFER_CONTROL);
++ qh->initial_toggle = uhci_toggle(td_token(td)) ^
++ (ret == -EREMOTEIO);
++
++ } else /* Short packet received */
++ ret = uhci_fixup_short_transfer(uhci, qh, urbp);
++ return ret;
++}
++
++/*
++ * Isochronous transfers
++ */
++static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
++ struct uhci_qh *qh)
++{
++ struct uhci_td *td = NULL; /* Since urb->number_of_packets > 0 */
++ int i, frame;
++ unsigned long destination, status;
++ struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
++
++ /* Values must not be too big (could overflow below) */
++ if (urb->interval >= UHCI_NUMFRAMES ||
++ urb->number_of_packets >= UHCI_NUMFRAMES)
++ return -EFBIG;
++
++ /* Check the period and figure out the starting frame number */
++ if (!qh->bandwidth_reserved) {
++ qh->period = urb->interval;
++ if (urb->transfer_flags & URB_ISO_ASAP) {
++ qh->phase = -1; /* Find the best phase */
++ i = uhci_check_bandwidth(uhci, qh);
++ if (i)
++ return i;
++
++ /* Allow a little time to allocate the TDs */
++ uhci_get_current_frame_number(uhci);
++ frame = uhci->frame_number + 10;
++
++ /* Move forward to the first frame having the
++ * correct phase */
++ urb->start_frame = frame + ((qh->phase - frame) &
++ (qh->period - 1));
++ } else {
++ i = urb->start_frame - uhci->last_iso_frame;
++ if (i <= 0 || i >= UHCI_NUMFRAMES)
++ return -EINVAL;
++ qh->phase = urb->start_frame & (qh->period - 1);
++ i = uhci_check_bandwidth(uhci, qh);
++ if (i)
++ return i;
++ }
++
++ } else if (qh->period != urb->interval) {
++ return -EINVAL; /* Can't change the period */
++
++ } else {
++ /* Find the next unused frame */
++ if (list_empty(&qh->queue)) {
++ frame = qh->iso_frame;
++ } else {
++ struct urb *lurb;
++
++ lurb = list_entry(qh->queue.prev,
++ struct urb_priv, node)->urb;
++ frame = lurb->start_frame +
++ lurb->number_of_packets *
++ lurb->interval;
++ }
++ if (urb->transfer_flags & URB_ISO_ASAP) {
++ /* Skip some frames if necessary to insure
++ * the start frame is in the future.
++ */
++ uhci_get_current_frame_number(uhci);
++ if (uhci_frame_before_eq(frame, uhci->frame_number)) {
++ frame = uhci->frame_number + 1;
++ frame += ((qh->phase - frame) &
++ (qh->period - 1));
++ }
++ } /* Otherwise pick up where the last URB leaves off */
++ urb->start_frame = frame;
++ }
++
++ /* Make sure we won't have to go too far into the future */
++ if (uhci_frame_before_eq(uhci->last_iso_frame + UHCI_NUMFRAMES,
++ urb->start_frame + urb->number_of_packets *
++ urb->interval))
++ return -EFBIG;
++
++ status = TD_CTRL_ACTIVE | TD_CTRL_IOS;
++ destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe);
++
++ for (i = 0; i < urb->number_of_packets; i++) {
++ td = uhci_alloc_td(uhci);
++ if (!td)
++ return -ENOMEM;
++
++ uhci_add_td_to_urbp(td, urbp);
++ uhci_fill_td(td, status, destination |
++ uhci_explen(urb->iso_frame_desc[i].length),
++ urb->transfer_dma +
++ urb->iso_frame_desc[i].offset);
++ }
++
++ /* Set the interrupt-on-completion flag on the last packet. */
++ td->status |= __constant_cpu_to_le32(TD_CTRL_IOC);
++
++ /* Add the TDs to the frame list */
++ frame = urb->start_frame;
++ list_for_each_entry(td, &urbp->td_list, list) {
++ uhci_insert_td_in_frame_list(uhci, td, frame);
++ frame += qh->period;
++ }
++
++ if (list_empty(&qh->queue)) {
++ qh->iso_packet_desc = &urb->iso_frame_desc[0];
++ qh->iso_frame = urb->start_frame;
++ }
++
++ qh->skel = SKEL_ISO;
++ if (!qh->bandwidth_reserved)
++ uhci_reserve_bandwidth(uhci, qh);
++ return 0;
++}
++
++static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb)
++{
++ struct uhci_td *td, *tmp;
++ struct urb_priv *urbp = urb->hcpriv;
++ struct uhci_qh *qh = urbp->qh;
++
++ list_for_each_entry_safe(td, tmp, &urbp->td_list, list) {
++ unsigned int ctrlstat;
++ int status;
++ int actlength;
++
++ if (uhci_frame_before_eq(uhci->cur_iso_frame, qh->iso_frame))
++ return -EINPROGRESS;
++
++ uhci_remove_tds_from_frame(uhci, qh->iso_frame);
++
++ ctrlstat = td_status(td);
++ if (ctrlstat & TD_CTRL_ACTIVE) {
++ status = -EXDEV; /* TD was added too late? */
++ } else {
++ status = uhci_map_status(uhci_status_bits(ctrlstat),
++ usb_pipeout(urb->pipe));
++ actlength = uhci_actual_length(ctrlstat);
++
++ urb->actual_length += actlength;
++ qh->iso_packet_desc->actual_length = actlength;
++ qh->iso_packet_desc->status = status;
++ }
++ if (status)
++ urb->error_count++;
++
++ uhci_remove_td_from_urbp(td);
++ uhci_free_td(uhci, td);
++ qh->iso_frame += qh->period;
++ ++qh->iso_packet_desc;
++ }
++ return 0;
++}
++
++static int uhci_urb_enqueue(struct usb_hcd *hcd,
++ struct urb *urb, gfp_t mem_flags)
++{
++ int ret;
++ struct uhci_hcd *uhci = hcd_to_uhci(hcd);
++ unsigned long flags;
++ struct urb_priv *urbp;
++ struct uhci_qh *qh;
++
++ spin_lock_irqsave(&uhci->lock, flags);
++
++ ret = usb_hcd_link_urb_to_ep(hcd, urb);
++ if (ret)
++ goto done_not_linked;
++
++ ret = -ENOMEM;
++ urbp = uhci_alloc_urb_priv(uhci, urb);
++ if (!urbp)
++ goto done;
++
++ if (urb->ep->hcpriv)
++ qh = urb->ep->hcpriv;
++ else {
++ qh = uhci_alloc_qh(uhci, urb->dev, urb->ep);
++ if (!qh)
++ goto err_no_qh;
++ }
++ urbp->qh = qh;
++
++ switch (qh->type) {
++ case USB_ENDPOINT_XFER_CONTROL:
++ ret = uhci_submit_control(uhci, urb, qh);
++ break;
++ case USB_ENDPOINT_XFER_BULK:
++ ret = uhci_submit_bulk(uhci, urb, qh);
++ break;
++ case USB_ENDPOINT_XFER_INT:
++ ret = uhci_submit_interrupt(uhci, urb, qh);
++ break;
++ case USB_ENDPOINT_XFER_ISOC:
++ urb->error_count = 0;
++ ret = uhci_submit_isochronous(uhci, urb, qh);
++ break;
++ }
++ if (ret != 0)
++ goto err_submit_failed;
++
++ /* Add this URB to the QH */
++ urbp->qh = qh;
++ list_add_tail(&urbp->node, &qh->queue);
++
++ /* If the new URB is the first and only one on this QH then either
++ * the QH is new and idle or else it's unlinked and waiting to
++ * become idle, so we can activate it right away. But only if the
++ * queue isn't stopped. */
++ if (qh->queue.next == &urbp->node && !qh->is_stopped) {
++ uhci_activate_qh(uhci, qh);
++ uhci_urbp_wants_fsbr(uhci, urbp);
++ }
++ goto done;
++
++err_submit_failed:
++//yriver
++// if (qh->state == QH_STATE_IDLE)
++ if (qh->state == UHCI_QH_STATE_IDLE)
++ uhci_make_qh_idle(uhci, qh); /* Reclaim unused QH */
++err_no_qh:
++ uhci_free_urb_priv(uhci, urbp);
++done:
++ if (ret)
++ usb_hcd_unlink_urb_from_ep(hcd, urb);
++done_not_linked:
++ spin_unlock_irqrestore(&uhci->lock, flags);
++ return ret;
++}
++
++static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
++{
++ struct uhci_hcd *uhci = hcd_to_uhci(hcd);
++ unsigned long flags;
++ struct uhci_qh *qh;
++ int rc;
++
++ spin_lock_irqsave(&uhci->lock, flags);
++ rc = usb_hcd_check_unlink_urb(hcd, urb, status);
++ if (rc)
++ goto done;
++
++ qh = ((struct urb_priv *) urb->hcpriv)->qh;
++
++ /* Remove Isochronous TDs from the frame list ASAP */
++ if (qh->type == USB_ENDPOINT_XFER_ISOC) {
++ uhci_unlink_isochronous_tds(uhci, urb);
++ mb();
++
++ /* If the URB has already started, update the QH unlink time */
++ uhci_get_current_frame_number(uhci);
++ if (uhci_frame_before_eq(urb->start_frame, uhci->frame_number))
++ qh->unlink_frame = uhci->frame_number;
++ }
++
++ uhci_unlink_qh(uhci, qh);
++
++done:
++ spin_unlock_irqrestore(&uhci->lock, flags);
++ return rc;
++}
++
++/*
++ * Finish unlinking an URB and give it back
++ */
++static void uhci_giveback_urb(struct uhci_hcd *uhci, struct uhci_qh *qh,
++ struct urb *urb, int status)
++__releases(uhci->lock)
++__acquires(uhci->lock)
++{
++ struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv;
++
++ if (qh->type == USB_ENDPOINT_XFER_CONTROL) {
++
++ /* urb->actual_length < 0 means the setup transaction didn't
++ * complete successfully. Either it failed or the URB was
++ * unlinked first. Regardless, don't confuse people with a
++ * negative length. */
++ urb->actual_length = max(urb->actual_length, 0);
++ }
++
++ /* When giving back the first URB in an Isochronous queue,
++ * reinitialize the QH's iso-related members for the next URB. */
++ else if (qh->type == USB_ENDPOINT_XFER_ISOC &&
++ urbp->node.prev == &qh->queue &&
++ urbp->node.next != &qh->queue) {
++ struct urb *nurb = list_entry(urbp->node.next,
++ struct urb_priv, node)->urb;
++
++ qh->iso_packet_desc = &nurb->iso_frame_desc[0];
++ qh->iso_frame = nurb->start_frame;
++ }
++
++ /* Take the URB off the QH's queue. If the queue is now empty,
++ * this is a perfect time for a toggle fixup. */
++ list_del_init(&urbp->node);
++ if (list_empty(&qh->queue) && qh->needs_fixup) {
++ usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
++ usb_pipeout(urb->pipe), qh->initial_toggle);
++ qh->needs_fixup = 0;
++ }
++
++ uhci_free_urb_priv(uhci, urbp);
++ usb_hcd_unlink_urb_from_ep(uhci_to_hcd(uhci), urb);
++
++ spin_unlock(&uhci->lock);
++ usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb, status);
++ spin_lock(&uhci->lock);
++
++ /* If the queue is now empty, we can unlink the QH and give up its
++ * reserved bandwidth. */
++ if (list_empty(&qh->queue)) {
++ uhci_unlink_qh(uhci, qh);
++ if (qh->bandwidth_reserved)
++ uhci_release_bandwidth(uhci, qh);
++ }
++}
++
++/*
++ * Scan the URBs in a QH's queue
++ */
++#define QH_FINISHED_UNLINKING(qh) \
++ (qh->state == QH_STATE_UNLINKING && \
++ uhci->frame_number + uhci->is_stopped != qh->unlink_frame)
++
++static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
++{
++ struct urb_priv *urbp;
++ struct urb *urb;
++ int status;
++
++ while (!list_empty(&qh->queue)) {
++ urbp = list_entry(qh->queue.next, struct urb_priv, node);
++ urb = urbp->urb;
++
++ if (qh->type == USB_ENDPOINT_XFER_ISOC)
++ status = uhci_result_isochronous(uhci, urb);
++ else
++ status = uhci_result_common(uhci, urb);
++ if (status == -EINPROGRESS)
++ break;
++
++ /* Dequeued but completed URBs can't be given back unless
++ * the QH is stopped or has finished unlinking. */
++ if (urb->unlinked) {
++ if (QH_FINISHED_UNLINKING(qh))
++ qh->is_stopped = 1;
++ else if (!qh->is_stopped)
++ return;
++ }
++
++ uhci_giveback_urb(uhci, qh, urb, status);
++ if (status < 0)
++ break;
++ }
++
++ /* If the QH is neither stopped nor finished unlinking (normal case),
++ * our work here is done. */
++ if (QH_FINISHED_UNLINKING(qh))
++ qh->is_stopped = 1;
++ else if (!qh->is_stopped)
++ return;
++
++ /* Otherwise give back each of the dequeued URBs */
++restart:
++ list_for_each_entry(urbp, &qh->queue, node) {
++ urb = urbp->urb;
++ if (urb->unlinked) {
++
++ /* Fix up the TD links and save the toggles for
++ * non-Isochronous queues. For Isochronous queues,
++ * test for too-recent dequeues. */
++ if (!uhci_cleanup_queue(uhci, qh, urb)) {
++ qh->is_stopped = 0;
++ return;
++ }
++ uhci_giveback_urb(uhci, qh, urb, 0);
++ goto restart;
++ }
++ }
++ qh->is_stopped = 0;
++
++ /* There are no more dequeued URBs. If there are still URBs on the
++ * queue, the QH can now be re-activated. */
++ if (!list_empty(&qh->queue)) {
++ if (qh->needs_fixup)
++ uhci_fixup_toggles(qh, 0);
++
++ /* If the first URB on the queue wants FSBR but its time
++ * limit has expired, set the next TD to interrupt on
++ * completion before reactivating the QH. */
++ urbp = list_entry(qh->queue.next, struct urb_priv, node);
++ if (urbp->fsbr && qh->wait_expired) {
++ struct uhci_td *td = list_entry(urbp->td_list.next,
++ struct uhci_td, list);
++
++ td->status |= __cpu_to_le32(TD_CTRL_IOC);
++ }
++
++ uhci_activate_qh(uhci, qh);
++ }
++
++ /* The queue is empty. The QH can become idle if it is fully
++ * unlinked. */
++ else if (QH_FINISHED_UNLINKING(qh))
++ uhci_make_qh_idle(uhci, qh);
++}
++
++/*
++ * Check for queues that have made some forward progress.
++ * Returns 0 if the queue is not Isochronous, is ACTIVE, and
++ * has not advanced since last examined; 1 otherwise.
++ *
++ * Early Intel controllers have a bug which causes qh->element sometimes
++ * not to advance when a TD completes successfully. The queue remains
++ * stuck on the inactive completed TD. We detect such cases and advance
++ * the element pointer by hand.
++ */
++static int uhci_advance_check(struct uhci_hcd *uhci, struct uhci_qh *qh)
++{
++ struct urb_priv *urbp = NULL;
++ struct uhci_td *td;
++ int ret = 1;
++ unsigned status;
++
++ if (qh->type == USB_ENDPOINT_XFER_ISOC)
++ goto done;
++
++ /* Treat an UNLINKING queue as though it hasn't advanced.
++ * This is okay because reactivation will treat it as though
++ * it has advanced, and if it is going to become IDLE then
++ * this doesn't matter anyway. Furthermore it's possible
++ * for an UNLINKING queue not to have any URBs at all, or
++ * for its first URB not to have any TDs (if it was dequeued
++ * just as it completed). So it's not easy in any case to
++ * test whether such queues have advanced. */
++ if (qh->state != QH_STATE_ACTIVE) {
++ urbp = NULL;
++ status = 0;
++
++ } else {
++ urbp = list_entry(qh->queue.next, struct urb_priv, node);
++ td = list_entry(urbp->td_list.next, struct uhci_td, list);
++ status = td_status(td);
++ if (!(status & TD_CTRL_ACTIVE)) {
++
++ /* We're okay, the queue has advanced */
++ qh->wait_expired = 0;
++ qh->advance_jiffies = jiffies;
++ goto done;
++ }
++ ret = 0;
++ }
++
++ /* The queue hasn't advanced; check for timeout */
++ if (qh->wait_expired)
++ goto done;
++
++ if (time_after(jiffies, qh->advance_jiffies + QH_WAIT_TIMEOUT)) {
++
++ /* Detect the Intel bug and work around it */
++ if (qh->post_td && qh_element(qh) == LINK_TO_TD(qh->post_td)) {
++ qh->element = qh->post_td->link;
++ qh->advance_jiffies = jiffies;
++ ret = 1;
++ goto done;
++ }
++
++ qh->wait_expired = 1;
++
++ /* If the current URB wants FSBR, unlink it temporarily
++ * so that we can safely set the next TD to interrupt on
++ * completion. That way we'll know as soon as the queue
++ * starts moving again. */
++ if (urbp && urbp->fsbr && !(status & TD_CTRL_IOC))
++ uhci_unlink_qh(uhci, qh);
++
++ } else {
++ /* Unmoving but not-yet-expired queues keep FSBR alive */
++ if (urbp)
++ uhci_urbp_wants_fsbr(uhci, urbp);
++ }
++
++done:
++ return ret;
++}
++
++/*
++ * Process events in the schedule, but only in one thread at a time
++ */
++static void uhci_scan_schedule(struct uhci_hcd *uhci)
++{
++ int i;
++ struct uhci_qh *qh;
++
++ /* Don't allow re-entrant calls */
++ if (uhci->scan_in_progress) {
++ uhci->need_rescan = 1;
++ return;
++ }
++ uhci->scan_in_progress = 1;
++rescan:
++ uhci->need_rescan = 0;
++ uhci->fsbr_is_wanted = 0;
++
++ uhci_clear_next_interrupt(uhci);
++ uhci_get_current_frame_number(uhci);
++ uhci->cur_iso_frame = uhci->frame_number;
++
++ /* Go through all the QH queues and process the URBs in each one */
++ for (i = 0; i < UHCI_NUM_SKELQH - 1; ++i) {
++ uhci->next_qh = list_entry(uhci->skelqh[i]->node.next,
++ struct uhci_qh, node);
++ while ((qh = uhci->next_qh) != uhci->skelqh[i]) {
++ uhci->next_qh = list_entry(qh->node.next,
++ struct uhci_qh, node);
++
++ if (uhci_advance_check(uhci, qh)) {
++ uhci_scan_qh(uhci, qh);
++ if (qh->state == QH_STATE_ACTIVE) {
++ uhci_urbp_wants_fsbr(uhci,
++ list_entry(qh->queue.next, struct urb_priv, node));
++ }
++ }
++ }
++ }
++
++ uhci->last_iso_frame = uhci->cur_iso_frame;
++ if (uhci->need_rescan)
++ goto rescan;
++ uhci->scan_in_progress = 0;
++
++ if (uhci->fsbr_is_on && !uhci->fsbr_is_wanted &&
++ !uhci->fsbr_expiring) {
++ uhci->fsbr_expiring = 1;
++ mod_timer(&uhci->fsbr_timer, jiffies + FSBR_OFF_DELAY);
++ }
++
++ if (list_empty(&uhci->skel_unlink_qh->node))
++ uhci_clear_next_interrupt(uhci);
++ else
++ uhci_set_next_interrupt(uhci);
++}
+diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
+index f3a75a9..97a22b9 100644
+--- a/drivers/usb/host/Kconfig
++++ b/drivers/usb/host/Kconfig
+@@ -88,6 +88,13 @@ config USB_EHCI_FSL
+ ---help---
+ Variation of ARC USB block used in some Freescale chips.
+
++config USB_EHCI_AST
++ bool "Support for ASPEED SoC EHCI USB controller"
++ depends on USB_EHCI_HCD && ARCH_ASPEED
++# select USB_EHCI_ROOT_HUB_TT
++ ---help---
++ Variation of ARC USB block used in some ASPEED SoC chips.
++
+ config USB_EHCI_HCD_PPC_OF
+ bool "EHCI support for PPC USB controller on OF platform bus"
+ depends on USB_EHCI_HCD && PPC_OF
+diff --git a/drivers/usb/host/ehci-ast.c b/drivers/usb/host/ehci-ast.c
+new file mode 100644
+index 0000000..503df9a
+--- /dev/null
++++ b/drivers/usb/host/ehci-ast.c
+@@ -0,0 +1,297 @@
++/********************************************************************************
++* File Name : drivers/usb/host/ehci-aspeed.c
++* Author : Ryan Chen
++* Description : EHCI HCD (Host Controller Driver) for USB
++*
++* Copyright (C) ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/08/17 ryan chen create this file
++*
++********************************************************************************/
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++
++#include <mach/hardware.h>
++
++
++/* ASPEED EHCI USB Host Controller */
++
++/*-------------------------------------------------------------------------*/
++
++/* configure so an HC device and id are always provided */
++/* always called with process context; sleeping is OK */
++
++static int ehci_ast_setup(struct usb_hcd *hcd)
++{
++ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
++ int retval;
++
++ ehci->caps = hcd->regs;
++ ehci->regs = hcd->regs +
++ HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
++ dbg_hcs_params(ehci, "reset");
++
++ /* cache this readonly data; minimize chip reads */
++ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
++
++#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT
++ hcd->has_tt = 1;
++#else
++ hcd->has_tt = 0;
++#endif
++
++ ehci->sbrn = 0x20;
++
++// retval = ehci_halt(ehci);
++// if (retval)
++// return retval;
++
++
++ /*
++ * data structure init
++ */
++ retval = ehci_init(hcd);
++ if (retval)
++ return retval;
++
++ ehci_reset(ehci);
++ ehci_port_power(ehci, 0);
++
++ return retval;
++}
++
++static const struct hc_driver ehci_ast_hc_driver = {
++ .description = hcd_name,
++ .product_desc = "ASPEED On-Chip EHCI Host Controller",
++ .hcd_priv_size = sizeof(struct ehci_hcd),
++ /*
++ * generic hardware linkage
++ */
++ .irq = ehci_irq,
++ .flags = HCD_USB2,
++ /*
++ * basic lifecycle operations
++ */
++ .reset = ehci_ast_setup,
++ .start = ehci_run,
++ .stop = ehci_stop,
++ .shutdown = ehci_shutdown,
++ /*
++ * managing i/o requests and associated device resources
++ */
++ .urb_enqueue = ehci_urb_enqueue,
++ .urb_dequeue = ehci_urb_dequeue,
++ .endpoint_disable = ehci_endpoint_disable,
++ /*
++ * scheduling support
++ */
++ .get_frame_number = ehci_get_frame,
++ /*
++ * root hub support
++ */
++ .hub_status_data = ehci_hub_status_data,
++ .hub_control = ehci_hub_control,
++ .bus_suspend = ehci_bus_suspend,
++ .bus_resume = ehci_bus_resume,
++ .relinquish_port = ehci_relinquish_port,
++ .port_handed_over = ehci_port_handed_over,
++};
++
++static int ehci_ast_drv_probe(struct platform_device *pdev)
++{
++ struct resource *res;
++ struct usb_hcd *hcd;
++// struct ehci_hcd *ehci;
++ void __iomem *regs;
++ int irq, err;
++
++ if (usb_disabled())
++ return -ENODEV;
++
++ pr_debug("Initializing ASPEED-SoC USB Host Controller\n");
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq <= 0) {
++ dev_err(&pdev->dev,
++ "Found HC with no IRQ. Check %s setup!\n",
++ dev_name(&pdev->dev));
++ err = -ENODEV;
++ goto err1;
++ }
++
++ //TODO
++// IRQ_SET_HIGH_LEVEL (irq);
++// IRQ_SET_LEVEL_TRIGGER (irq);
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res) {
++ dev_err(&pdev->dev,
++ "Found HC with no register addr. Check %s setup!\n",
++ dev_name(&pdev->dev));
++ err = -ENODEV;
++ goto err1;
++ }
++
++ if (!request_mem_region(res->start, res->end - res->start + 1,
++ res->name)) {
++ dev_dbg(&pdev->dev, "controller already in use\n");
++ err = -EBUSY;
++ goto err1;
++ }
++
++ regs = ioremap_nocache(res->start, res->end - res->start + 1);
++ if (regs == NULL) {
++ dev_dbg(&pdev->dev, "error mapping memory\n");
++ err = -EFAULT;
++ goto err2;
++ }
++
++ hcd = usb_create_hcd(&ehci_ast_hc_driver,
++ &pdev->dev, dev_name(&pdev->dev));
++ if (!hcd) {
++ err = -ENOMEM;
++ goto err3;
++ }
++
++ hcd->rsrc_start = res->start;
++ hcd->rsrc_len = res->end - res->start + 1;
++ hcd->regs = regs;
++
++ err = usb_add_hcd(hcd, irq, IRQF_DISABLED);
++ if (err)
++ goto err4;
++
++ return 0;
++
++ err4:
++ usb_put_hcd(hcd);
++ err3:
++ iounmap(regs);
++ err2:
++ release_mem_region(res->start, res->end - res->start + 1);
++ err1:
++ dev_err(&pdev->dev, "init %s fail, %d\n",
++ dev_name(&pdev->dev), err);
++
++ return err;
++
++
++}
++
++static int ehci_ast_drv_remove(struct platform_device *pdev)
++{
++ struct usb_hcd *hcd = platform_get_drvdata(pdev);
++
++ usb_remove_hcd(hcd);
++ iounmap(hcd->regs);
++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
++ usb_put_hcd(hcd);
++
++ return 0;
++}
++
++ /*TBD*/
++#ifdef CONFIG_PM
++static int ehci_hcd_ast_drv_suspend(struct platform_device *pdev, pm_message_t msg)
++{
++ struct usb_hcd *hcd = platform_get_drvdata(pdev);
++ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
++ unsigned long flags;
++ int rc = 0;
++
++ if (time_before(jiffies, ehci->next_statechange))
++ msleep(10);
++
++ /* Root hub was already suspended. Disable irq emission and
++ * mark HW unaccessible, bail out if RH has been resumed. Use
++ * the spinlock to properly synchronize with possible pending
++ * RH suspend or resume activity.
++ *
++ * This is still racy as hcd->state is manipulated outside of
++ * any locks =P But that will be a different fix.
++ */
++ spin_lock_irqsave (&ehci->lock, flags);
++ if (hcd->state != HC_STATE_SUSPENDED) {
++ rc = -EINVAL;
++ goto bail;
++ }
++ ehci_writel(ehci, 0, &ehci->regs->intr_enable);
++ (void)ehci_readl(ehci, &ehci->regs->intr_enable);
++
++ clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
++ bail:
++ spin_unlock_irqrestore (&ehci->lock, flags);
++
++ // could save FLADJ in case of Vaux power loss
++ // ... we'd only use it to handle clock skew
++
++ return rc;
++}
++static int ehci_hcd_ast_drv_resume(struct platform_device *pdev)
++{
++ struct usb_hcd *hcd = platform_get_drvdata(pdev);
++ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
++
++ // maybe restore FLADJ
++
++ if (time_before(jiffies, ehci->next_statechange))
++ msleep(100);
++
++ /* Mark hardware accessible again as we are out of D3 state by now */
++ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
++
++ usb_root_hub_lost_power(hcd->self.root_hub);
++
++ /* Else reset, to cope with power loss or flush-to-storage
++ * style "resume" having let BIOS kick in during reboot.
++ */
++ (void) ehci_halt(ehci);
++ (void) ehci_reset(ehci);
++
++ /* emptying the schedule aborts any urbs */
++ spin_lock_irq(&ehci->lock);
++ if (ehci->reclaim)
++ end_unlink_async(ehci);
++ ehci_work(ehci);
++ spin_unlock_irq(&ehci->lock);
++
++ ehci_writel(ehci, ehci->command, &ehci->regs->command);
++ ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
++ ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
++
++ /* here we "know" root ports should always stay powered */
++ ehci_port_power(ehci, 1);
++
++ hcd->state = HC_STATE_SUSPENDED;
++ return 0;
++}
++#endif
++
++MODULE_ALIAS("platform:ehci_ast");
++
++static struct platform_driver ehci_hcd_ast_driver = {
++ .probe = ehci_ast_drv_probe,
++ .remove = ehci_ast_drv_remove,
++ .shutdown = usb_hcd_platform_shutdown,
++#ifdef CONFIG_PM
++ .suspend = ehci_hcd_ast_drv_suspend,
++ .resume = ehci_hcd_ast_drv_resume,
++#endif
++ .driver = {
++ .name = "ehci-ast",
++ },
++};
+diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
+index e551bb3..a34a4cf 100644
+--- a/drivers/usb/host/ehci-hcd.c
++++ b/drivers/usb/host/ehci-hcd.c
+@@ -581,6 +581,7 @@ static int ehci_run (struct usb_hcd *hcd)
+ * Scsi_Host.highmem_io, and so forth. It's readonly to all
+ * host side drivers though.
+ */
++
+ hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params);
+ if (HCC_64BIT_ADDR(hcc_params)) {
+ ehci_writel(ehci, 0, &ehci->regs->segment);
+@@ -1036,6 +1037,11 @@ MODULE_LICENSE ("GPL");
+ #define PLATFORM_DRIVER ixp4xx_ehci_driver
+ #endif
+
++#ifdef CONFIG_USB_EHCI_AST
++#include "ehci-ast.c"
++#define PLATFORM_DRIVER ehci_hcd_ast_driver
++#endif
++
+ #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
+ !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER)
+ #error "missing bus glue for ehci-hcd"
+@@ -1117,7 +1123,10 @@ err_debug:
+ clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
+ return retval;
+ }
+-module_init(ehci_hcd_init);
++
++//ehci must after uhci driver module load. Ryan Modify
++late_initcall(ehci_hcd_init);
++//module_init(ehci_hcd_init);
+
+ static void __exit ehci_hcd_cleanup(void)
+ {
+diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
+index 3f3ce13..a8be29b 100644
+--- a/drivers/video/Kconfig
++++ b/drivers/video/Kconfig
+@@ -1473,6 +1473,30 @@ config FB_SAVAGE_ACCEL
+ the resulting framebuffer console has bothersome glitches, then
+ choose N here.
+
++menuconfig FB_AST
++ tristate "ASPEED Framebuffer Driver"
++ depends on FB
++ select FB_CFB_FILLRECT
++ select FB_CFB_COPYAREA
++ select FB_CFB_IMAGEBLIT
++ default n
++
++if FB_AST
++
++config AST_DAC
++ bool "CRT DAC output"
++
++config AST_DVO
++ bool "CRT DVO output"
++
++config HDMI_CAT6613
++ bool "Enable CAT6613 HDMI TX"
++ depends on FB_AST && AST_DVO
++ help
++ This option will support CAT6613 HDMI TX driver
++
++endif
++
+ config FB_SIS
+ tristate "SiS/XGI display support"
+ depends on FB && PCI
+diff --git a/drivers/video/Makefile b/drivers/video/Makefile
+index e39e33e..97bc000 100644
+--- a/drivers/video/Makefile
++++ b/drivers/video/Makefile
+@@ -41,6 +41,8 @@ obj-$(CONFIG_FB_NVIDIA) += nvidia/
+ obj-$(CONFIG_FB_ATY) += aty/ macmodes.o
+ obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o
+ obj-$(CONFIG_FB_RADEON) += aty/
++obj-$(CONFIG_FB_AST) += astfb.o
++obj-$(CONFIG_HDMI_CAT6613) += hdmi_cat6613.o
+ obj-$(CONFIG_FB_SIS) += sis/
+ obj-$(CONFIG_FB_VIA) += via/
+ obj-$(CONFIG_FB_KYRO) += kyro/
+diff --git a/drivers/video/astfb.c b/drivers/video/astfb.c
+new file mode 100644
+index 0000000..8292bb8
+--- /dev/null
++++ b/drivers/video/astfb.c
+@@ -0,0 +1,1056 @@
++ /********************************************************************************
++* File Name : drivers/video/astfb.c
++* Author : Ryan Chen
++* Description : ASPEED Framebuffer Driver
++*
++* Copyright (C) ASPEED Tech. Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/12/27 Ryan Chen create this file
++*
++*
++********************************************************************************/
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/string.h>
++#include <linux/mm.h>
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/fb.h>
++#include <linux/init.h>
++#include <linux/dma-mapping.h>
++#include <linux/interrupt.h>
++#include <linux/wait.h>
++#include <linux/platform_device.h>
++
++#include <asm/io.h>
++#include <asm/uaccess.h>
++#include <asm/mach/map.h>
++#include <plat/regs-crt.h>
++#include <mach/ast_lcd.h>
++
++#ifdef CONFIG_DOUBLE_BUFFER
++#define NUMBER_OF_BUFFERS 2
++#else
++#define NUMBER_OF_BUFFERS 1
++#endif
++
++//////////////////////////////////////////////////////////////
++/* H/W Feature Definition */
++#define DEFAULT_MMIO_SIZE 0x00020000
++#define DEFAULT_CMDQ_SIZE 0x00100000
++#define MIN_CMDQ_SIZE 0x00040000
++#define CMD_QUEUE_GUARD_BAND 0x00000020
++#define DEFAULT_HWC_NUM 0x00000002
++
++////////////////////////////////////////////////////////////////
++static wait_queue_head_t wq;
++static int gNoPanDisplay;
++static int gGUIWaitVsync;
++
++#define ASTFB_GET_DFBINFO _IOR(0xF3,0x00,struct astfb_dfbinfo)
++
++/* Default Threshold Seting */
++#define CRT_LOW_THRESHOLD_VALUE 0x12
++#define CRT_HIGH_THRESHOLD_VALUE 0x1E
++
++//#define CRT_LOW_THRESHOLD_VALUE 0x60
++//#define CRT_HIGH_THRESHOLD_VALUE 0x78
++//for fix 1920X1080
++//#define CRT_LOW_THRESHOLD_VALUE 0x16
++//#define CRT_HIGH_THRESHOLD_VALUE 0x1E
++
++////////////////////////////////////////////////////////////
++
++/* Debugging stuff */
++
++#define FBDBG 1
++
++#define dprintk(msg...) if (FBDBG) { printk(KERN_DEBUG "astfb: " msg); }
++
++struct pixel_freq_pll_data {
++ u32 pixel_freq; //*10000
++ u32 pll_set;
++};
++
++static struct pixel_freq_pll_data pll_table[] = {
++ {39721, 0x00046515}, /* 00: VCLK25_175 */
++ {35308, 0x00047255}, /* 01: VCLK28_322 */
++ {31746, 0x0004682a}, /* 02: VCLK31_5 */
++ {27777, 0x0004672a}, /* 03: VCLK36 */
++ {25000, 0x00046c50}, /* 04: VCLK40 */
++ {20202, 0x00046842}, /* 05: VCLK49_5 */
++ {20000, 0x00006c32}, /* 06: VCLK50 */
++ {17777, 0x00006a2f}, /* 07: VCLK56_25 */
++ {15384, 0x00006c41}, /* 08: VCLK65 */
++ {13333, 0x00006832}, /* 09: VCLK75 */
++ {12690, 0x0000672e}, /* 0A: VCLK78_75 */
++ {10582, 0x0000683f}, /* 0B: VCLK94_5 */
++ {9259, 0x00004824}, /* 0C: VCLK108 */
++ {7407, 0x0000482d}, /* 0D: VCLK135 */
++ {6349, 0x0000472e}, /* 0E: VCLK157_5 */
++ {6172, 0x00004836}, /* 0F: VCLK162 */
++};
++
++// ARGB4444 format
++unsigned short cursor_8x8[] = {
++ 0x0FFF, 0x1FFF, 0x2FFF, 0x3777, 0x4777, 0x5777, 0x6777, 0x7888,
++ 0x8FFF, 0xF000, 0xAFFF, 0xB777, 0xC777, 0xD777, 0xE777, 0xF888,
++ 0x0FFF, 0x1FFF, 0x2FFF, 0x3FFF, 0x4777, 0x5777, 0x6777, 0x7888,
++ 0x8FFF, 0x9FFF, 0xAFFF, 0xBFFF, 0xCFFF, 0xD777, 0xE777, 0xF888,
++ 0x0FFF, 0x1FFF, 0x2FFF, 0x3FFF, 0x4FFF, 0x5FFF, 0x6FFF, 0x7888,
++ 0x8FFF, 0x9FFF, 0xAFFF, 0xBFFF, 0xCFFF, 0xDFFF, 0xEFFF, 0xFFFF,
++ 0x0FFF, 0x1FFF, 0x2777, 0x3FFF, 0x4FFF, 0x5FFF, 0x6FFF, 0x7FFF,
++ 0x8FFF, 0x9777, 0xA777, 0xB777, 0xC777, 0xDFFF, 0xEFFF, 0xFFFF,
++};
++
++// XRGB4444 format
++unsigned short cursor_16x16[] = {
++ 0x8777, 0x8777, 0x8777, 0x8777, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF,
++ 0x8777, 0xC888, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF,
++ 0x8777, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF,
++ 0x8777, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF,
++ 0x8777, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF,
++ 0x4777, 0x4FFF, 0x4FFF, 0x4FFF, 0x4FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF,
++ 0x4FFF, 0x4FFF, 0x4FFF, 0x4FFF, 0x4FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF,
++ 0x0FFF, 0x0FFF, 0x0FFF, 0x0FFF, 0x4FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF,
++ 0x0FFF, 0x0FFF, 0x0FFF, 0x0FFF, 0x4FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF,
++ 0x0FFF, 0x0FFF, 0x0FFF, 0x0FFF, 0x4FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF,
++ 0x0FFF, 0x0FFF, 0x0FFF, 0x0FFF, 0x4FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF,
++ 0xCFFF, 0xCFFF, 0xCFFF, 0xCFFF, 0x4FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF,
++ 0xCFFF, 0xCFFF, 0xCFFF, 0xCFFF, 0x4FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF,
++ 0xCFFF, 0xCFFF, 0xCFFF, 0xCFFF, 0x4FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF,
++ 0xCFFF, 0xCFFF, 0xCFFF, 0xCFFF, 0x4FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF,
++ 0xCFFF, 0xCFFF, 0xCFFF, 0xCFFF, 0x4FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF, 0x8FFF,
++};
++
++struct astfb_device {
++ int state;
++ struct mutex rqueue_mutex;
++ int palette_size;
++ u32 pseudo_palette[17];
++ struct platform_device *pdev;
++ struct fb_var_screeninfo new_var; /* for mode changes */
++};
++
++
++/* data structure */
++struct astfb_info {
++ struct platform_device *pdev;
++ struct fb_info *info;
++ struct resource *reg_res;
++ struct resource *fb_res;
++ void __iomem *base;
++ int addr_assign;
++ int irq;
++ int yuv_mode;
++ u32 pseudo_palette[17];
++
++ struct timer_list timer;
++
++ /* driver registered */
++ int registered;
++ /* console control */
++ int currcon;
++
++ int need_wakeup;
++ void __iomem *next_addr;
++
++
++ u8 hwcursor; //0: disable , 1 : enable
++ u8 dac; //0: disable , 1 : enable
++ u8 dvo; //0: disable , 1 : enable
++ u8 xmiter; //0: dvi, 1:hdmi;
++ struct ast_fb_plat_data *fb_plat_data;
++
++};
++
++static inline void
++astfb_write(struct astfb_info *fbinfo, u32 val, u32 reg)
++{
++// dprintk("astfb_write : val: %x , reg : %x \n",val,reg);
++ writel(val, fbinfo->base+ reg);
++}
++
++static inline u32
++astfb_read(struct astfb_info *fbinfo, u32 reg)
++{
++ return readl(fbinfo->base + reg);
++}
++
++static void astfb_osd_enable(struct astfb_info *sfb, u8 enable)
++{
++ if(enable)
++ astfb_write(sfb, astfb_read(sfb, AST_CRT_CTRL1) | CRT_CTRL_OSD_EN, AST_CRT_CTRL1);
++ else
++ astfb_write(sfb, astfb_read(sfb, AST_CRT_CTRL1) & ~CRT_CTRL_OSD_EN, AST_CRT_CTRL1);
++}
++
++static void astfb_cursor_enable(struct astfb_info *sfb, u8 enable)
++{
++ if(enable) {
++ astfb_write(sfb, astfb_read(sfb, AST_CRT_CTRL1) | CRT_CTRL_HW_CURSOR_EN, AST_CRT_CTRL1);
++ } else {
++ astfb_write(sfb, astfb_read(sfb, AST_CRT_CTRL1) & ~CRT_CTRL_HW_CURSOR_EN, AST_CRT_CTRL1);
++ }
++}
++
++int
++astfb_crtc_to_var(struct fb_var_screeninfo *var, struct astfb_info *sfb)
++{
++
++ /* crtc */
++ var->xoffset = var->yoffset = 0;
++
++ /* palette */
++ switch(var->bits_per_pixel) {
++ case 8:
++ var->red.offset = var->green.offset = var->blue.offset = 0;
++ var->red.length = var->green.length = var->blue.length = 6;
++ break;
++ case 16:
++ var->red.offset = 11;
++ var->red.length = 5;
++ var->green.offset = 5;
++ var->green.length = 6;
++ var->blue.offset = 0;
++ var->blue.length = 5;
++ var->transp.offset = 0;
++ var->transp.length = 0;
++ break;
++ case 24:
++ case 32:
++ var->red.offset = 16;
++ var->red.length = 8;
++ var->green.offset = 8;
++ var->green.length = 8;
++ var->blue.offset = 0;
++ var->blue.length = 8;
++ var->transp.offset = 24;
++ var->transp.length = 8;
++ break;
++ }
++
++ var->red.msb_right =
++ var->green.msb_right =
++ var->blue.msb_right =
++ var->transp.offset =
++ var->transp.length =
++ var->transp.msb_right = 0;
++
++ return 0;
++}
++
++/*-------------------------------------------------------------------------*/
++static int astfb_hw_cursor(struct fb_info *info, struct fb_cursor *cursor)
++{
++// printk("astfb_hw_cursor \n");
++ return 0;
++}
++
++#if (NUMBER_OF_BUFFERS > 1)
++static int astfb_pan_display(struct fb_var_screeninfo *var, struct fb_info* info)
++{
++ struct astfb_info *sfb = info->par;
++ u32 addr;
++ s32 timeout;
++
++ if(gNoPanDisplay)
++ return 0;
++
++ addr = var->yoffset * info->fix.line_length + info->fix.smem_start;
++
++ astfb_write(sfb, addr, AST_CRT_ADDR);
++
++ if(gGUIWaitVsync)
++ {
++ timeout = interruptible_sleep_on_timeout(&wq,HZ/60);
++ if(timeout<0)
++ dprintk("%s: interruptible_sleep_on_timeout, may lost interrupt! timeout=%d\n",__FUNCTION__,timeout);
++ }
++ return 0;
++
++} /* astfb_pan_display */
++#endif
++
++static int astfb_set_par(struct fb_info *info)
++{
++ struct astfb_info *sfb = info->par;
++ struct fb_var_screeninfo *var = &info->var;
++ u32 i,ctrl1, ctrl2, htt, hde, hrs_s, hrs_e, vtt, vde, vrs_s, vrs_e;
++ u32 d_offset, t_count, thshld;
++ u32 d2_pll;
++
++ //S1 : set H / V
++ // Horizontal Timing
++ htt = var->xres + var->left_margin + var->right_margin + var->hsync_len;
++ hde = var->xres;
++ astfb_write(sfb, CRT_H_TOTAL((htt - 1)) | CRT_H_DE((hde - 1)), AST_CRT_HORIZ0);
++
++ hrs_s = var->xres + var->right_margin;
++ hrs_e = var->xres + var->right_margin + var->hsync_len;
++ astfb_write(sfb, CRT_H_RS_START((hrs_s - 1)) | CRT_H_RS_END((hrs_e - 1)), AST_CRT_HORIZ1);
++
++ dprintk("var->upper_margin= %d, var->lower_margin= %d, var->vsync_len = %d \n",var->upper_margin, var->lower_margin, var->vsync_len);
++
++ vtt = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
++ vde = var->yres;
++ astfb_write(sfb, CRT_V_TOTAL((vtt - 1)) | CRT_V_DE((vde - 1)), AST_CRT_VERTI0);
++ vrs_s = var->yres + var->lower_margin;
++ vrs_e = var->yres + var->lower_margin + var->vsync_len;
++ astfb_write(sfb, CRT_V_RS_START((vrs_s - 1)) | CRT_V_RS_END((vrs_e - 1)), AST_CRT_VERTI1);
++
++ if(var->nonstd != 0)
++ printk("TODO Check .... nonstd \n");
++
++ switch (var->nonstd) {
++ case 0:
++ break;
++ case ASTFB_COLOR_YUV444:
++ var->bits_per_pixel = 32;
++ return 0;
++ case ASTFB_COLOR_YUV420:
++ var->bits_per_pixel = 32;
++ return 0;
++ }
++
++ //S2 : Offset , TODO ... (x + 0x1f) & ~0x1f
++ d_offset = var->xres * var->bits_per_pixel /8;
++// dprintk("d_offset %d\n",d_offset);
++
++ switch (var->nonstd) {
++ case 0:
++ break;
++ case ASTFB_COLOR_YUV444:
++ var->bits_per_pixel = 24;
++ return 0;
++ case ASTFB_COLOR_YUV420:
++ var->bits_per_pixel = 16;
++ return 0;
++ }
++
++ t_count =(var->xres * var->bits_per_pixel + 63) / 64;
++// dprintk("t_count %d \n",t_count);
++ astfb_write(sfb, CRT_DISP_OFFSET(d_offset) | CRT_TERM_COUNT(t_count), AST_CRT_OFFSET);
++
++
++ //S3 : DCLK
++ dprintk("var->pixclock = %d \n",var->pixclock);
++
++ for(i=0; i<sizeof(pll_table)/sizeof(struct pixel_freq_pll_data); i++) {
++ if(pll_table[i].pixel_freq == var->pixclock) {
++ astfb_write(sfb, pll_table[i].pll_set, AST_CRT_PLL);
++ dprintk("find pixclk in table set 0x%x \n",pll_table[i].pll_set);
++ break;
++ }
++ }
++ if(i == sizeof(pll_table)/sizeof(struct pixel_freq_pll_data))
++ printk("ERROR pixclk in table ... FIXME \n");
++#if 0
++ d2_pll = sfb->fb_plat_data->get_clk();
++ u32 num, denum, div0,
++ num = pll_table[i].pll_set & 0xff;
++ denum = (pll_table[i].pll_set >> 8) & 0x1f;
++ div0 = (pll_table[i].pll_set >> 13) & 0x3;
++ div1 = (pll_table[i].pll_set >> 13) & 0x3;
++ printk
++#endif
++
++ //S4
++ astfb_write(sfb, sfb->info->fix.smem_start, AST_CRT_ADDR);
++
++ thshld = CRT_THROD_HIGH(CRT_HIGH_THRESHOLD_VALUE) | CRT_THROD_LOW(CRT_LOW_THRESHOLD_VALUE);
++ astfb_write(sfb, thshld, AST_CRT_THROD);
++
++
++ info->fix.line_length = (var->xres*var->bits_per_pixel)/8;
++ dprintk("x :%d , y : %d , bpp = %d \n",var->xres, var->yres, var->bits_per_pixel);
++ //disable crt first .....
++ astfb_write(sfb, astfb_read(sfb, AST_CRT_CTRL2) & ~(CRT_CTRL_DAC_PWR_EN | CRT_CTRL_DVO_EN), AST_CRT_CTRL2);
++
++ ctrl1 = astfb_read(sfb, AST_CRT_CTRL1);
++ //CTRL 1
++ // SetPolarity
++ dprintk("var->sync : %x , var->vmode = %d \n",var->sync, var->vmode);
++
++ if(var->sync & FB_SYNC_HOR_HIGH_ACT)
++ ctrl1 &= ~CRT_CTRL_HSYNC_POLARITY;
++ else
++ ctrl1 |= CRT_CTRL_HSYNC_POLARITY;
++
++ if(var->sync & FB_SYNC_VERT_HIGH_ACT)
++ ctrl1 &= ~CRT_CTRL_VSYNC_POLARITY;
++ else
++ ctrl1 |= CRT_CTRL_VSYNC_POLARITY;
++
++ /* Mode Type Setting */
++
++ if(var->bits_per_pixel==16)
++ ctrl1 &= ~CRT_CTRL_FORMAT_MASK; //RGB565
++ else
++ ctrl1 |= CRT_CTRL_FORMAT(COLOR_XRGB8888);
++
++ if (var->vmode & FB_VMODE_INTERLACED)
++ ctrl1 |= CRT_CTRL_INTER_TIMING;
++ else
++ ctrl1 &= ~CRT_CTRL_INTER_TIMING;
++
++ //enable crt ...
++ astfb_write(sfb, ctrl1 | CRT_CTRL_GRAPHIC_EN, AST_CRT_CTRL1);
++
++ dprintk("var->left_margin= %d, var->right_margin= %d, var->hsync_len = %d \n",var->left_margin, var->right_margin, var->hsync_len);
++
++
++ //enable dac / dvo
++ //CTRL 2
++ ctrl2 = 0;//astfb_read(sfb, AST_CRT_CTRL2);
++
++ // SoC V2 add CRT interrupt support. We should not touch this setting when changing video timing.
++ ctrl2 &= ~CRT_CTRL_VLINE_NUM_MASK;
++
++#ifdef CONFIG_AST_DAC
++ ctrl2 |= CRT_CTRL_DAC_PWR_EN;
++#endif
++
++#ifdef CONFIG_AST_DVO
++ ctrl2 |= CRT_CTRL_DVO_EN;
++#endif
++
++ astfb_write(sfb, ctrl2 , AST_CRT_CTRL2);
++
++ return 0;
++}
++
++static int astfb_get_cmap_len(struct fb_var_screeninfo *var)
++{
++ return (var->bits_per_pixel == 8) ? 256 : 16;
++}
++
++static int astfb_setcolreg(unsigned regno,
++ unsigned red, unsigned green, unsigned blue,
++ unsigned transp, struct fb_info *info)
++{
++ if(regno >= astfb_get_cmap_len(&info->var))
++ return 1;
++
++ switch(info->var.bits_per_pixel) {
++ case 8:
++ return 1;
++ break;
++ case 16:
++ ((u32 *)(info->pseudo_palette))[regno] =
++ (red & 0xf800) |
++ ((green & 0xfc00) >> 5) |
++ ((blue & 0xf800) >> 11);
++ break;
++ case 24:
++ case 32:
++ red >>= 8;
++ green >>= 8;
++ blue >>= 8;
++ ((u32 *)(info->pseudo_palette))[regno] =
++ (red << 16) | (green << 8) | (blue);
++ break;
++ }
++ return 0;
++
++}
++
++/*
++ * Blank the screen if blank_mode != 0, else unblank. Return 0 if blanking
++ * succeeded, != 0 if un-/blanking failed.
++ * blank_mode == 2: suspend vsync
++ * blank_mode == 3: suspend hsync
++ * blank_mode == 4: powerdown
++ */
++static int astfb_blank(int blank_mode, struct fb_info *info)
++{
++ u32 ctrl;
++ struct astfb_info *sfb = info->par;
++
++ printk(KERN_DEBUG "astfb: astfb_blank mode %d \n",blank_mode);
++ ctrl = astfb_read(sfb, AST_CRT_CTRL1);
++
++ switch(blank_mode) {
++ case FB_BLANK_UNBLANK: /* on */
++ ctrl &= ~CRT_CTRL_SCREEN_OFF;
++ break;
++ case FB_BLANK_NORMAL: /* blank */
++ ctrl |= CRT_CTRL_SCREEN_OFF;
++ break;
++ case FB_BLANK_VSYNC_SUSPEND: /* no vsync */
++ ctrl |= CRT_CTRL_VSYNC_OFF;
++ break;
++ case FB_BLANK_HSYNC_SUSPEND: /* no hsync */
++ ctrl |= CRT_CTRL_HSYNC_OFF;
++ break;
++ case FB_BLANK_POWERDOWN: /* off */
++ ctrl |= (CRT_CTRL_SCREEN_OFF | CRT_CTRL_VSYNC_OFF | CRT_CTRL_HSYNC_OFF);
++ break;
++ default:
++ return 1;
++ }
++
++ /* set reg */
++ astfb_write(sfb, ctrl, AST_CRT_CTRL1);
++
++ return 0;
++
++} /* astfb_blank */
++
++static int astfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
++{
++ var->xres_virtual = var->xres;
++ var->yres_virtual =var->yres * NUMBER_OF_BUFFERS;
++////////////////////////////////////////////////////////////////////
++ /* Sanity check for offsets */
++ if(var->xoffset < 0) var->xoffset = 0;
++ if(var->yoffset < 0) var->yoffset = 0;
++
++ if(var->xres > var->xres_virtual)
++ var->xres_virtual = var->xres;
++
++ /* Truncate offsets to maximum if too high */
++ if(var->xoffset > var->xres_virtual - var->xres) {
++ var->xoffset = var->xres_virtual - var->xres - 1;
++ }
++
++ if(var->yoffset > var->yres_virtual - var->yres) {
++ var->yoffset = var->yres_virtual - var->yres - 1;
++ }
++////////////////////////////////////////////////////////////////////
++ switch(var->bits_per_pixel) {
++ case 8:
++ var->red.offset = var->green.offset = var->blue.offset = 0;
++ var->red.length = var->green.length = var->blue.length = 6;
++ break;
++ case 16:
++ var->red.offset = 11;
++ var->red.length = 5;
++ var->green.offset = 5;
++ var->green.length = 6;
++ var->blue.offset = 0;
++ var->blue.length = 5;
++ var->transp.offset = 0;
++ var->transp.length = 0;
++ break;
++ case 24:
++ case 32:
++ var->red.offset = 16;
++ var->red.length = 8;
++ var->green.offset = 8;
++ var->green.length = 8;
++ var->blue.offset = 0;
++ var->blue.length = 8;
++ var->transp.length = 8;
++ var->transp.offset = 24;
++ break;
++ default:
++ dprintk("bpp=%d not support\n",var->bits_per_pixel);
++ return -EINVAL;
++ break;
++ }
++ return 0;
++}
++
++static int
++astfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
++{
++ struct astfb_info *sfb = info->par;
++
++ printk(KERN_DEBUG "astfb: astfb_ioctl is called \n");
++
++ switch(cmd) {
++// case AST_COLOR_FORMAT:
++// return 0;
++
++ default:
++ return -EINVAL;
++ }
++
++ return 0;
++
++} /* astfb_ioctl */
++
++/* fb ops */
++static struct fb_ops astfb_ops = {
++ .owner = THIS_MODULE,
++ .fb_check_var = astfb_check_var,
++ .fb_set_par = astfb_set_par,
++ .fb_blank = astfb_blank,
++ .fb_setcolreg = astfb_setcolreg,
++ .fb_fillrect = cfb_fillrect,
++ .fb_copyarea = cfb_copyarea,
++ .fb_imageblit = cfb_imageblit,
++ .fb_ioctl = astfb_ioctl,
++ .fb_cursor = astfb_hw_cursor,
++#if (NUMBER_OF_BUFFERS > 1)
++ .fb_pan_display = astfb_pan_display,
++#endif
++};
++
++static void ast_fbmem_free(struct astfb_info *sfb)
++{
++ iounmap(sfb->info->screen_base);
++}
++
++static irqreturn_t
++astfb_isr(int irq, void *parm)
++{
++ u32 status;
++ struct astfb_info *sfb=parm;
++ status = astfb_read(sfb, AST_CRT_CTRL1);
++ astfb_write(sfb, status, AST_CRT_CTRL1);
++ if (status & CRT_CTRL_VERTICAL_INTR_STS)
++ wake_up_interruptible(&wq);
++
++ return IRQ_HANDLED;
++}
++
++//TODO ..
++static int astfb_setup(struct astfb_info *sfb)
++{
++ char *this_opt = NULL;
++ char *options = NULL;
++ char tmp[128];
++ char *tmp_opt;
++ char name[10];
++ int i;
++
++ fb_get_options("astfb", &options);
++ dprintk("%s\n", options);
++
++ if (!options || !*options)
++ return -1;
++
++ strcpy(tmp, options);
++ tmp_opt=tmp;
++ while ((this_opt = strsep(&tmp_opt, ",")) != NULL) {
++ printk("x %s \n",this_opt);
++ if (!strncmp(this_opt, "mode:", 5)) {
++ printk("%s \n",this_opt);
++ } else if(!strncmp(this_opt, "hwcursor:", 9)) {
++ printk("%s \n",this_opt);
++ } else if(!strncmp(this_opt, "osd:", 4)) {
++ printk("%s \n",this_opt);
++ } else if (!strncmp(this_opt, "vram:", 8)) {
++ printk("%s \n",this_opt);
++ } else if(!strncmp(this_opt, "dac:", 4)) {
++ printk("%s \n",this_opt);
++ } else if(!strncmp(this_opt, "dvo:", 4)) {
++ printk("%s \n",this_opt);
++ } else {
++ printk("f %s \n",this_opt);
++ }
++
++ }
++
++ return 0;
++
++} /* astfb_setup */
++
++static void sfb_timer(unsigned long private)
++{
++ struct astfb_info *sfb = (void *) private;
++ if(sfb->need_wakeup)
++ {
++ sfb->need_wakeup=0;
++ wake_up_interruptible(&wq);
++ }
++ if(sfb->next_addr)
++ {
++ astfb_write(sfb, (u32)sfb->next_addr, AST_CRT_ADDR);
++ sfb->need_wakeup=1;
++ }
++ mod_timer(&sfb->timer, jiffies + HZ/24);
++}
++
++#ifdef CONFIG_HDMI_CAT6613
++static ssize_t show_hdmi_status(struct device *device,
++ struct device_attribute *attr, char *buf)
++{
++ struct fb_info *fb_info = dev_get_drvdata(device);
++ ssize_t len = 0;
++ int rc;
++
++ rc=ast_hdmi_get_info(fb_info);
++ if(rc==1)
++ len=sprintf(buf, "UNPLUG\n");
++ else if(rc==0)
++ len=sprintf(buf, "PLUG\n");
++ else
++ len=sprintf(buf, "UNKNOWN\n");
++ return len;
++}
++
++static ssize_t show_hdmi_enable(struct device *device,
++ struct device_attribute *attr, char *buf)
++{
++ struct fb_info *info = dev_get_drvdata(device);
++ struct astfb_info *sfb = info->par;
++
++ return sprintf(buf, "%d\n",sfb->hdmi_en);
++}
++
++static ssize_t store_hdmi_enable(struct device *device,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct fb_info *info = dev_get_drvdata(device);
++ struct astfb_info *sfb = info->par;
++ if(buf[0]=='1') {
++ ast_hdmi_enable(1);
++ sfb->hdmi_en=1;
++ }
++ else {
++ ast_hdmi_enable(0);
++ sfb->hdmi_en=0;
++ }
++
++ return count;
++}
++#endif
++
++static ssize_t show_lcd_enable(struct device *device,
++ struct device_attribute *attr, char *buf)
++{
++ struct fb_info *info = dev_get_drvdata(device);
++ struct astfb_info *sfb = info->par;
++ if(astfb_read(sfb, AST_CRT_CTRL1) & CRT_CTRL_GRAPHIC_EN)
++ return sprintf(buf, "%d\n",1);
++ else
++ return sprintf(buf, "%d\n",0);
++}
++
++static ssize_t store_lcd_enable(struct device *device,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct fb_info *info = dev_get_drvdata(device);
++ struct astfb_info *sfb = info->par;
++ if(buf[0]=='1') {
++ astfb_write(sfb, astfb_read(sfb, AST_CRT_CTRL1) | CRT_CTRL_GRAPHIC_EN, AST_CRT_CTRL1);
++ }
++ else {
++ astfb_write(sfb, astfb_read(sfb, AST_CRT_CTRL1) & ~CRT_CTRL_GRAPHIC_EN, AST_CRT_CTRL1);
++ }
++
++ return count;
++}
++
++static ssize_t show_pix_clk(struct device *device,
++ struct device_attribute *attr, char *buf)
++{
++ struct fb_info *info = dev_get_drvdata(device);
++ struct astfb_info *sfb = info->par;
++
++// return sprintf(buf, "target_clk=%d\ncalc_clk=%d\n",sfb->target_clk,sfb->calc_clk);
++}
++
++static ssize_t no_pan_display_show(struct device *device,
++ struct device_attribute *attr, char *buf)
++{
++ return sprintf(buf, "%hu\n", gNoPanDisplay);
++}
++
++static ssize_t no_pan_display_store(struct device *device,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ unsigned short value;
++
++ if (sscanf(buf, "%hu", &value) != 1 ||
++ (value != 0 && value != 1 )) {
++ dprintk(KERN_ERR "no_pan_display_store : Invalid value\n");
++ return -EINVAL;
++ }
++
++ if(value == 0)
++ gNoPanDisplay = 0;
++ else if(value == 1)
++ gNoPanDisplay = 1;
++
++ return count;
++}
++
++static ssize_t phys_addr_show(struct device *device,
++ struct device_attribute *attr, char *buf)
++{
++ struct fb_info *info = dev_get_drvdata(device);
++ return sprintf(buf, "%hu\n", info->fix.smem_start);
++}
++
++static ssize_t virt_addr_show(struct device *device,
++ struct device_attribute *attr, char *buf)
++{
++ struct fb_info *info = dev_get_drvdata(device);
++ return sprintf(buf, "%hu\n", info->screen_base);
++}
++
++static struct device_attribute device_attrs[] = {
++ __ATTR(virt_addr, S_IRUGO | S_IWUGO, virt_addr_show, NULL),
++ __ATTR(phys_addr, S_IRUGO | S_IWUGO, phys_addr_show, NULL),
++ __ATTR(no_pan_display, S_IRUGO | S_IWUGO, no_pan_display_show, no_pan_display_store),
++ __ATTR(lcd_enable, S_IRUGO | S_IWUGO, show_lcd_enable, store_lcd_enable),
++ __ATTR(pixel_clock, S_IRUGO, show_pix_clk, NULL),
++// __ATTR(osd_enable, S_IRUGO, show_osd_enable, store_osd_enable),
++// __ATTR(cursor_enable, S_IRUGO, show_cursor_enable, store_cursor_enable),
++#ifdef CONFIG_HDMI_CAT6613
++ __ATTR(hdmi_status, S_IRUGO, show_hdmi_status, NULL),
++ __ATTR(hdmi_enable, S_IRUGO | S_IWUGO, show_hdmi_enable, store_hdmi_enable),
++#endif
++#ifdef CONFIG_VGA_EDID
++ __ATTR(vga_status, S_IRUGO, show_vga_status, NULL),
++ __ATTR(vga_detect, S_IRUGO | S_IWUGO, show_vga_edid, NULL),
++#endif
++};
++
++static int astfb_probe(struct platform_device *pdev)
++{
++ struct astfb_device *astfbdev = NULL;
++ struct astfb_info *sfb;
++ struct fb_info *info;
++ struct device *dev = &pdev->dev;
++ int ret,i,retval;
++ char *mode_option;
++
++ dprintk("astfb_probe \n");
++
++ info = framebuffer_alloc(sizeof(struct astfb_info), dev);
++ if (!info) {
++ dev_err(dev, "cannot allocate memory\n");
++ return -ENOMEM;
++ }
++
++ sfb = info->par;
++ sfb->info = info;
++ sfb->pdev = pdev;
++ sfb->fb_plat_data = (struct ast_fb_plat_data *)dev->platform_data;
++ strcpy(info->fix.id, sfb->pdev->name);
++
++ sfb->reg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!sfb->reg_res) {
++ dev_err(dev, "register resources unusable\n");
++ ret = -ENXIO;
++ goto free_info;
++ }
++
++ sfb->irq = platform_get_irq(pdev, 0);
++ if (!sfb->irq) {
++ dev_err(dev, "unable to get irq\n");
++ ret = -ENXIO;
++ goto free_info;
++ }
++
++ if(!sfb->fb_plat_data) {
++ dev_err(dev, "unable to get ast fb platform data\n");
++ ret = -ENXIO;
++ goto free_info;
++ }
++
++ info->fix.mmio_start = sfb->reg_res->start;
++ info->fix.mmio_len = sfb->reg_res->end - sfb->reg_res->start + 1;
++
++ if (!request_mem_region(info->fix.mmio_start, info->fix.mmio_len, pdev->name)) {
++ dev_err(dev, "cannot request CRT registers\n");
++ ret = -EBUSY;
++ goto free_info;
++ }
++
++ sfb->base = ioremap(info->fix.mmio_start, info->fix.mmio_len);
++ if (!sfb->base) {
++ dev_err(dev, "cannot map LCDC registers\n");
++ ret = -ENOMEM;
++ goto free_res;
++ }
++
++ info->fbops = &astfb_ops;
++
++ if(astfb_setup(sfb)) {
++ dev_warn(dev, "cannot get fb boot options will use default !!!\n");
++ }
++// if (!mode_option) {
++ mode_option = "640x480-32@60";
++ info->fix.smem_start = 0x47000000;
++
++// }
++
++ if(fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8) != 1) {
++ dev_err(dev, "cannot find db modes \n");
++ ret = -ENOMEM;
++ goto free_res;
++ }
++
++
++ /* resource allocation */
++ info->fix.smem_len = SZ_2M * ((info->var.bits_per_pixel)/8 * NUMBER_OF_BUFFERS); //assign 16M for 1920*1080*32it double-buffering
++
++ printk("info->fix.smem_start = %x , len = %d , bpp = %d\n",info->fix.smem_start, info->fix.smem_len, info->var.bits_per_pixel);
++
++ if (!request_mem_region(info->fix.smem_start, info->fix.smem_len, pdev->name)) {
++ dev_err(dev, "cannot request CRT mem\n");
++ ret = -EBUSY;
++ goto free_io;
++ }
++
++ info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
++ if (!info->screen_base) {
++ dev_err(dev, "cannot map CRT mem\n");
++ ret = -ENOMEM;
++ goto free_addr;
++ }
++
++ printk(KERN_INFO "FB Phys:%x, Virtual:%x \n", info->fix.smem_start, info->screen_base);
++
++ info->fix.type = FB_TYPE_PACKED_PIXELS;
++ info->fix.type_aux = 0;
++
++#if (NUMBER_OF_BUFFERS > 1)
++ info->fix.ypanstep = 1;
++#else
++ info->fix.ypanstep = 0;
++#endif
++
++ info->fix.xpanstep = 0;
++ info->fix.ywrapstep = 0;
++ info->fix.visual = FB_VISUAL_TRUECOLOR,
++ info->fix.accel = FB_ACCEL_NONE;
++ info->flags = FBINFO_FLAG_DEFAULT;
++ info->pseudo_palette = sfb->pseudo_palette;
++
++ /*
++ * Allocate colourmap.
++ */
++ ret=fb_alloc_cmap(&(info->cmap), 256, 0);
++ if(ret) {
++ dev_err(dev, "Alloc color map failed\n");
++ goto free_mem;
++ }
++
++ ret = request_irq(sfb->irq, astfb_isr, IRQF_SHARED, pdev->name, sfb);
++ if (ret) {
++ dev_err(dev, "Can't request LCD irq");
++ ret = -EBUSY;
++ goto free_cmap;
++ }
++ init_waitqueue_head(&wq);
++
++ ret = astfb_check_var(&info->var, info);
++ if (ret)
++ goto free_irq;
++
++ init_timer(&sfb->timer);
++ sfb->timer.data = (long) sfb;
++ sfb->timer.function = sfb_timer;
++ astfb_set_par(info);
++ platform_set_drvdata(pdev, sfb);
++ ret = register_framebuffer(info);
++ if (!ret) {
++ for(i=0;i<sizeof(device_attrs)/sizeof(struct device_attribute);i++)
++ device_create_file(info->dev, &device_attrs[i]);
++ return 0;
++ }
++
++ dev_err(dev, "Failed to register framebuffer device: %d\n", ret);
++
++ astfb_write(sfb, astfb_read(sfb, AST_CRT_CTRL1) & ~CRT_CTRL_GRAPHIC_EN, AST_CRT_CTRL1);
++ platform_set_drvdata(pdev, NULL);
++free_irq:
++ free_irq(sfb->irq,sfb);
++free_cmap:
++ fb_dealloc_cmap(&info->cmap);
++free_mem:
++ ast_fbmem_free(sfb);
++free_addr:
++ if(sfb->addr_assign)
++ release_mem_region(info->fix.smem_start, info->fix.smem_len);
++free_io:
++ iounmap(sfb->base);
++free_res:
++ release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
++free_info:
++ framebuffer_release(info);
++ return ret;
++
++}
++
++static int
++astfb_remove(struct platform_device *pdev)
++{
++ struct astfb_info *sfb = platform_get_drvdata(pdev);
++
++ unregister_framebuffer(sfb->info);
++ astfb_write(sfb, astfb_read(sfb, AST_CRT_CTRL1) & ~CRT_CTRL_GRAPHIC_EN, AST_CRT_CTRL1);
++ free_irq(sfb->irq,sfb);
++ fb_dealloc_cmap(&sfb->info->cmap);
++ iounmap(sfb->info->screen_base);
++ if(sfb->addr_assign)
++ release_mem_region(sfb->info->fix.smem_start, sfb->info->fix.smem_len);
++ iounmap(sfb->base);
++ release_mem_region(sfb->info->fix.mmio_start, sfb->info->fix.mmio_len);
++ framebuffer_release(sfb->info);
++ platform_set_drvdata(pdev, NULL);
++ dprintk("astfb_remove \n");
++
++ return 0;
++}
++
++#ifdef CONFIG_PM
++static int astfb_suspend(struct platform_device *pdev, pm_message_t state)
++{
++ /* TODO */
++ return 0;
++}
++
++static int astfb_resume(struct platform_device *pdev)
++{
++ /* TODO */
++ return 0;
++}
++#else
++#define astfb_suspend NULL
++#define astfb_resume NULL
++#endif
++
++/* driver ops */
++static struct platform_driver astfb_driver = {
++ .probe = astfb_probe,
++ .remove = astfb_remove,
++ .suspend = astfb_suspend,
++ .resume = astfb_resume,
++ .driver = {
++ .name = "ast-fb",
++ .owner = THIS_MODULE,
++ },
++
++};
++int __devinit astfb_init(void)
++{
++ return platform_driver_register(&astfb_driver);
++}
++
++static void __exit astfb_cleanup(void)
++{
++ printk(KERN_DEBUG "astfb: astfb_remove_module is called \n");
++
++ platform_driver_unregister(&astfb_driver);
++}
++
++module_init(astfb_init);
++module_exit(astfb_cleanup);
++
++MODULE_AUTHOR("Ryan Chen");
++MODULE_DESCRIPTION("Framebuffer driver for the ASPEED");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/video/hdmi_cat6613.c b/drivers/video/hdmi_cat6613.c
+new file mode 100755
+index 0000000..2a6d21f
+--- /dev/null
++++ b/drivers/video/hdmi_cat6613.c
+@@ -0,0 +1,545 @@
++/********************************************************************************
++* File Name : drivers/video/hdmi_cat6613.c
++* Author : Ryan Chen
++* Description : HDMI CAT6613 driver
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++*
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++*
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++* History :
++* 1. 2012/08/24 Ryan Chen create this file
++*
++********************************************************************************/
++
++#include <linux/i2c.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/fb.h>
++
++#include <mach/regs-cat6613.h>
++#include "edid.h"
++
++#define DEVICE_NAME "cat6613"
++#define CAT6613_DEVICE_ID 0xCA13
++
++struct cat6613_info {
++ struct i2c_client *client;
++ struct fb_info *fb_info;
++ struct aspeed_monitor_info *mon_info;
++ struct work_struct cat6613_work;
++ int state;//0:unplug 1:plug
++ int irq;
++};
++
++static struct cat6613_info cat6613_device;
++struct aspeed_monitor_info monitor_info;
++
++
++static void get_detailed_timing(unsigned char *block,
++ struct fb_videomode *mode)
++{
++ mode->xres = H_ACTIVE;
++ mode->yres = V_ACTIVE;
++ mode->pixclock = PIXEL_CLOCK;
++ mode->pixclock /= 1000;
++ mode->pixclock = KHZ2PICOS(mode->pixclock);
++ mode->right_margin = H_SYNC_OFFSET;
++ mode->left_margin = (H_ACTIVE + H_BLANKING) -
++ (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH);
++ mode->upper_margin = V_BLANKING - V_SYNC_OFFSET -
++ V_SYNC_WIDTH;
++ mode->lower_margin = V_SYNC_OFFSET;
++ mode->hsync_len = H_SYNC_WIDTH;
++ mode->vsync_len = V_SYNC_WIDTH;
++ if (HSYNC_POSITIVE)
++ mode->sync |= FB_SYNC_HOR_HIGH_ACT;
++ if (VSYNC_POSITIVE)
++ mode->sync |= FB_SYNC_VERT_HIGH_ACT;
++ mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) *
++ (V_ACTIVE + V_BLANKING));
++ if (INTERLACED) {
++ mode->yres *= 2;
++ mode->upper_margin *= 2;
++ mode->lower_margin *= 2;
++ mode->vsync_len *= 2;
++ mode->vmode |= FB_VMODE_INTERLACED;
++ }
++ else
++ mode->vmode=0;
++ mode->flag = FB_MODE_IS_DETAILED;
++
++}
++
++static void cat6613_parse_cea(void)
++{
++ int timing_offset,cea_data_offset=0,data_tag,data_len,vic,i;
++ char *ext=&cat6613_device.mon_info->edid[128];
++ struct fb_monspecs *specs=&cat6613_device.mon_info->specs;
++
++ if(cat6613_device.mon_info->edid[126]==0 || ext[0]!=0x2) {
++ printk("DVI mode\n");
++ cat6613_device.mon_info->type=0; //dvi mode
++ return;
++ }
++
++ printk("CEA Revision=%d\n", ext[1]);
++
++ if(ext[3]& (1<<6)) {
++ printk("HDMI mode\n");
++ cat6613_device.mon_info->type=1; //hdmi mode
++ }
++ else {
++ printk("HDMI mode without audio\n");
++ cat6613_device.mon_info->type=0; //dvi mode
++ }
++
++ if(ext[2]==0) //no timing & cea data for parsing
++ return;
++
++ timing_offset=ext[2];
++
++ //parsing cea data
++ if(timing_offset!=4) {
++ while((cea_data_offset+4)!=timing_offset) {
++ data_tag=(ext[cea_data_offset+4]>>5)&0x7; //bit 5~7
++ data_len=ext[cea_data_offset+4]&0x1f; //bit 0~4
++ switch(data_tag) {
++ case 1:
++ //printk("audio data block\n");
++ break;
++ case 2:
++ //printk("video data block\n");
++ for(i=1;i<=data_len;i++) {
++ vic=ext[cea_data_offset+4+i]&0x7f;
++ //add 720p60 timing
++ if(vic==4) {
++ //printk("add 1280x720p60 timing\n");
++ memcpy(&specs->modedb[specs->modedb_len], &(panels[8].mode),sizeof(struct fb_videomode));
++ specs->modedb_len++;
++ }
++ //add 1080p60 timing
++ if(vic==16) {
++ //printk("add 1920x1080p60 timing\n");
++ memcpy(&specs->modedb[specs->modedb_len], &(panels[9].mode),sizeof(struct fb_videomode));
++ specs->modedb_len++;
++ }
++ if(vic==2 || vic==3) {
++ //printk("add 720x480p60 timing\n");
++ memcpy(&specs->modedb[specs->modedb_len], &(panels[10].mode),sizeof(struct fb_videomode));
++ specs->modedb_len++;
++ }
++
++ }
++ break;
++ case 3:
++ //printk("vendor data block\n");
++ break;
++ case 4:
++ //printk("speaker data block\n");
++ break;
++ default:
++ //printk("unknown data block tag=%d\n",data_tag);
++ break;
++ }
++ cea_data_offset+=(data_len+1); //go to next block
++ }
++ }
++ while(ext[timing_offset]!=0) {
++ //printk("%x\n",ext[timing_offset+17]);
++ get_detailed_timing(&ext[timing_offset], &specs->modedb[specs->modedb_len]);
++ specs->modedb_len++;
++ timing_offset+=18;
++ }
++
++}
++
++static int cat6613_reset(struct i2c_client *client)
++{
++ int rc;
++ rc = i2c_smbus_write_byte_data(client, REG_TX_BANK_CTRL, 0x00);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_SW_RST, 0x3d);
++ msleep(2);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_SW_RST, 0x1d);
++ msleep(2);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_HDMI_MODE, 0x00);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AV_MUTE, 0x01);
++
++ //set int
++ rc |=i2c_smbus_write_byte_data(client,REG_TX_INT_CTRL, 0x40);
++ rc |=i2c_smbus_write_byte_data(client,REG_TX_INT_MASK1, 0xfd);
++ rc |=i2c_smbus_write_byte_data(client,REG_TX_INT_MASK2, 0xff) ;
++ rc |=i2c_smbus_write_byte_data(client,REG_TX_INT_MASK3, 0x7f);
++
++ return rc;
++
++}
++
++static int cat6613_afe(struct i2c_client *client)
++{
++ int tmds,rc=0;
++ if(cat6613_device.fb_info) {
++ tmds=1000000/(cat6613_device.fb_info->var.pixclock);
++ if(tmds > 80) {
++ rc = i2c_smbus_write_byte_data(client, REG_TX_AFE_DRV_CTRL,0x10);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AFE_XP_CTRL,0x88);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AFE_ISW_CTRL,0x10);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AFE_IP_CTRL,0x84);
++
++ }
++ else {
++
++ rc = i2c_smbus_write_byte_data(client, REG_TX_AFE_DRV_CTRL,0x10);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AFE_XP_CTRL,0x18);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AFE_ISW_CTRL,0x10);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AFE_IP_CTRL,0x0c);
++ }
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AFE_DRV_CTRL,0x00);
++ }
++
++ return rc;
++}
++
++static int cat6613_set_av(struct i2c_client *client)
++{
++ int rc=0;
++
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_SW_RST,0xd); //reset av
++ msleep(1);
++ if(cat6613_device.mon_info->type==0) {
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_HDMI_MODE,0); //dvi mode
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_SW_RST,5);
++ msleep(1);
++ return rc;
++ }
++
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_BANK_CTRL,1); //switch bank 1
++
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB1,0x12); //set underscan
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB2,0x8);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB3,0x0);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB4,0x0);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB5,0x0);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB6,0x0);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB7,0x0);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB8,0x0);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB9,0x0);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB10,0x0);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB11,0x0);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB12,0x0);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_DB13,0x0);
++
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AVIINFO_SUM,0x55); //check sum
++
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_BANK_CTRL,0); //switch bank 0
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_PKT_GENERAL_CTRL,1);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_NULL_CTRL,1);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_ACP_CTRL,0);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AVI_INFOFRM_CTRL,3);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AUD_INFOFRM_CTRL,1);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_MPG_INFOFRM_CTRL,0);
++
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_HDMI_MODE,1); //hdmi mode
++
++ rc |= i2c_smbus_write_byte_data(client, 0xf8,0xc3);
++ rc |= i2c_smbus_write_byte_data(client, 0xf8,0xa5);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_PKT_SINGLE_CTRL,0x0); //set auto cts
++
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AUDIO_CTRL0,0x0);
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AUDIO_CTRL0,0x1); //set i2s 16bit
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_AUDIO_CTRL1,0x1); //set not full packet mode & 32bit i2s
++
++ rc |= i2c_smbus_write_byte_data(client, REG_TX_SW_RST,1);
++ msleep(1);
++
++ return rc;
++
++}
++
++static int cat6613_clear_mute(struct i2c_client *client)
++{
++ int rc;
++ rc = i2c_smbus_write_byte_data(client, REG_TX_AV_MUTE,0);
++ return rc;
++}
++
++
++static int cat6613_wait_ddc(struct i2c_client *client)
++{
++ int rc,count;
++
++ for(count=0;count<10;count++) {
++ rc=i2c_smbus_read_byte_data(client,REG_TX_DDC_STATUS);
++ if(rc & B_DDC_DONE)
++ return 0;
++ msleep(1);
++ }
++ printk("ddc timeout\n");
++ i2c_smbus_write_byte_data(client,REG_TX_DDC_MASTER_CTRL, B_MASTERHOST ) ;
++ i2c_smbus_write_byte_data(client,REG_TX_DDC_CMD, CMD_DDC_ABORT) ;
++ return -1;
++
++}
++
++static int cat6613_read_edid(struct i2c_client *client)
++{
++ int j ;
++ int remained_byte, offset, count;
++ remained_byte = 256 ;
++ offset=0;
++
++ while(offset<256) {
++ count = (remained_byte<32)?remained_byte:32 ;
++ i2c_smbus_write_byte_data(cat6613_device.client,REG_TX_DDC_MASTER_CTRL, B_MASTERDDC|B_MASTERHOST ) ;
++ i2c_smbus_write_byte_data(cat6613_device.client,REG_TX_DDC_CMD, CMD_FIFO_CLR);
++ if(cat6613_wait_ddc(cat6613_device.client)) {
++ return -1;
++ }
++
++ i2c_smbus_write_byte_data(client,REG_TX_DDC_HEADER, 0xA0) ;
++ i2c_smbus_write_byte_data(client,REG_TX_DDC_REQOFF, offset) ;
++ i2c_smbus_write_byte_data(client,REG_TX_DDC_REQCOUNT, count) ;
++ i2c_smbus_write_byte_data(client,REG_TX_DDC_EDIDSEG, 0) ;
++ i2c_smbus_write_byte_data(client,REG_TX_DDC_CMD, 3);
++ if(cat6613_wait_ddc(cat6613_device.client)) {
++ return -1;
++ }
++ for( j = 0 ; j < count ; j++)
++ {
++ cat6613_device.mon_info->edid[offset+j] = i2c_smbus_read_byte_data(client,REG_TX_DDC_READFIFO); ;
++ }
++ remained_byte -= count ;
++ offset += count ;
++ }
++ return 0;
++
++}
++
++static void cat6613_add_modes(void)
++{
++ int i;
++ struct fb_monspecs *specs=&cat6613_device.mon_info->specs;
++ struct fb_info *info=cat6613_device.fb_info;
++
++ for(i=0;i<specs->modedb_len;i++) {
++ fb_add_videomode(&specs->modedb[i],&info->modelist);
++ }
++
++}
++
++static void cat6613_del_modes(void)
++{
++ int i;
++ struct fb_monspecs *specs=&cat6613_device.mon_info->specs;
++ struct fb_info *info=cat6613_device.fb_info;
++ if(!info)
++ return;
++
++ for(i=0;i<specs->modedb_len;i++) {
++ fb_delete_videomode(&specs->modedb[i],&info->modelist);
++ }
++}
++
++static void cat6613_handle(struct work_struct *work)
++{
++ char int_status,sys_status,rc,int_status3;
++ struct fb_var_screeninfo tmp_var;
++ int_status=i2c_smbus_read_byte_data(cat6613_device.client,REG_TX_INT_STAT1);
++ sys_status=i2c_smbus_read_byte_data(cat6613_device.client, REG_TX_SYS_STATUS);
++ int_status3=i2c_smbus_read_byte_data(cat6613_device.client,REG_TX_INT_STAT3);
++ if(!(sys_status&B_INT_ACTIVE))
++ printk("cat6613_handle: no int\n");
++ else {
++#if 0
++ if(int_status & B_INT_DDCFIFO_ERR) {
++ printk("B_INT_DDCFIFO_ERR\n");
++ i2c_smbus_write_byte_data(cat6613_device.client,REG_TX_DDC_MASTER_CTRL, B_MASTERHOST ) ;
++ i2c_smbus_write_byte_data(cat6613_device.client,REG_TX_DDC_CMD, CMD_FIFO_CLR);
++ }
++
++ if(int_status & B_INT_DDC_BUS_HANG) {
++ printk("B_INT_DDC_BUS_HANG\n");
++ i2c_smbus_write_byte_data(cat6613_device.client,REG_TX_DDC_MASTER_CTRL, B_MASTERHOST ) ;
++ i2c_smbus_write_byte_data(cat6613_device.client,REG_TX_DDC_CMD, CMD_DDC_ABORT) ;
++ }
++ if(int_status & B_INT_HPD_PLUG) {
++ if(sys_status & B_HPDETECT)
++ printk("HPD PLUG\n");
++ else
++ printk("HPD UN PLUG 0\n");
++ i2c_smbus_write_byte_data(cat6613_device.client,REG_TX_INT_CLR0,B_CLR_HPD);
++ }
++ if(int_status3 & B_INT_VIDSTABLE) {
++ if(sys_status & B_TXVIDSTABLE) {
++ printk("VIDSTABLE\n");
++ i2c_smbus_write_byte_data(cat6613_device.client, REG_TX_AFE_DRV_CTRL,0x00);
++ }
++ else
++ printk("UN VIDSTABLE\n");
++ i2c_smbus_write_byte_data(cat6613_device.client,REG_TX_INT_CLR1,B_CLR_VIDSTABLE);
++ }
++#endif
++ if(int_status & B_INT_RX_SENSE) {
++ if(sys_status& B_RXSENDETECT) {
++ if(cat6613_device.state==0) {
++ rc=cat6613_read_edid(cat6613_device.client);
++ if(!rc) {
++ rc=fb_parse_edid(cat6613_device.mon_info->edid,&tmp_var);
++ if(!rc)
++ cat6613_device.state=1;
++ }
++ }
++ }
++ else {
++ printk("HPD UN PLUG 0\n");
++ if(cat6613_device.state==1) {
++ printk("HPD UN PLUG 1\n");
++ cat6613_del_modes();
++ cat6613_device.mon_info->status=0;
++ cat6613_device.state=0;
++ }
++ }
++ i2c_smbus_write_byte_data(cat6613_device.client,REG_TX_INT_CLR0,B_CLR_RXSENSE);
++ }
++ }
++
++ i2c_smbus_write_byte_data(cat6613_device.client,REG_TX_SYS_STATUS, sys_status | B_INTACTDONE );
++ i2c_smbus_write_byte_data(cat6613_device.client,REG_TX_SYS_STATUS, sys_status);
++ enable_irq(cat6613_device.irq);
++}
++
++static irqreturn_t cat6613_isr(int irq, void *parm)
++{
++
++ disable_irq_nosync(cat6613_device.irq);
++ schedule_work(&cat6613_device.cat6613_work);
++ return IRQ_HANDLED;
++}
++
++static int hdmi_cat6613_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ int rc=0;
++ if (!i2c_check_functionality(client->adapter,
++ I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C))
++ return -ENODEV;
++
++ rc=(i2c_smbus_read_byte_data(client, REG_TX_VENDOR_ID1)<<8)&0xff00;
++ rc|=i2c_smbus_read_byte_data(client, REG_TX_DEVICE_ID0);
++ if(rc != CAT6613_DEVICE_ID) {
++ printk(KERN_ERR "%s: read id fail\n", __func__);
++ return -ENODEV;
++ }
++
++ cat6613_device.client=client;
++ cat6613_device.irq=client->irq;
++ cat6613_device.mon_info=&monitor_info;
++
++ //reset
++ rc=cat6613_reset(client);
++ if(rc)
++ printk(KERN_ERR "%s: reset fail\n", __func__);
++
++ INIT_WORK(&cat6613_device.cat6613_work, cat6613_handle);
++ rc = request_irq(cat6613_device.irq, cat6613_isr, IRQF_DISABLED, DEVICE_NAME, NULL);
++ if(rc) {
++ printk(KERN_ERR "%s: request irq fail\n", __func__);
++ return rc;
++ }
++
++ return rc;
++}
++
++static int __devexit hdmi_cat6613_remove(struct i2c_client *client)
++{
++
++ return 0;
++}
++
++
++static const struct i2c_device_id hmdi_cat6613_id[] = {
++ { DEVICE_NAME, 0 },
++ { }
++};
++
++static struct i2c_driver hdmi_cat6613_i2c_driver = {
++ .driver = {
++ .name = DEVICE_NAME,
++ .owner = THIS_MODULE,
++ },
++ .probe = hdmi_cat6613_probe,
++ .remove = __exit_p(hdmi_cat6613_remove),
++ .id_table = hmdi_cat6613_id,
++};
++
++
++int aspeed_hdmi_get_info(struct fb_info *fb_info)
++{
++
++ if(!fb_info) {
++ printk("no fb_info\n");
++ return -1;
++ }
++ cat6613_device.fb_info=fb_info;
++
++ if(cat6613_device.state==0)
++ return 1;
++
++ if(cat6613_device.mon_info->status==0) {
++ if(monitor_info.specs.modedb)
++ fb_destroy_modedb(monitor_info.specs.modedb);
++ fb_edid_to_monspecs(cat6613_device.mon_info->edid, &cat6613_device.mon_info->specs);
++ cat6613_parse_cea();
++ cat6613_add_modes();
++ cat6613_device.mon_info->status=1;
++ }
++ return 0;
++}
++
++void aspeed_hdmi_enable(int en)
++{
++ if(en==0) {
++ i2c_smbus_write_byte_data(cat6613_device.client, REG_TX_HDMI_MODE, 0x00);
++ i2c_smbus_write_byte_data(cat6613_device.client, REG_TX_AV_MUTE, 0x01);
++ }
++ else {
++ cat6613_set_av(cat6613_device.client);
++ cat6613_afe(cat6613_device.client);
++ cat6613_clear_mute(cat6613_device.client);
++ }
++}
++
++static int __init hdmi_cat6613_init(void)
++{
++ int ret;
++
++ ret = i2c_add_driver(&hdmi_cat6613_i2c_driver);
++ if (ret)
++ printk(KERN_ERR "%s: failed to add i2c driver\n", __func__);
++
++ return ret;
++}
++
++static void __exit hdmi_cat6613_exit(void)
++{
++ i2c_del_driver(&hdmi_cat6613_i2c_driver);
++}
++
++module_init(hdmi_cat6613_init);
++module_exit(hdmi_cat6613_exit);
++
++EXPORT_SYMBOL(aspeed_hdmi_get_info);
++EXPORT_SYMBOL(aspeed_hdmi_enable);
++
++MODULE_AUTHOR("Ryan Chen <jsho@aspeed-tech.com>");
++MODULE_DESCRIPTION("CAT6023 HDMI Driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
+index 9d285f6..5702145 100644
+--- a/drivers/watchdog/Kconfig
++++ b/drivers/watchdog/Kconfig
+@@ -233,6 +233,12 @@ config ORION5X_WATCHDOG
+ To compile this driver as a module, choose M here: the
+ module will be called orion5x_wdt.
+
++config AST_WATCHDOG
++ tristate "ASPEED GUC watchdog"
++ depends on WATCHDOG
++ help
++ Watchdog timer for ASPEED chips.
++
+ # ARM26 Architecture
+
+ # AVR32 Architecture
+diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
+index e352bbb..ba47642 100644
+--- a/drivers/watchdog/Makefile
++++ b/drivers/watchdog/Makefile
+@@ -41,6 +41,7 @@ obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o
+ obj-$(CONFIG_IOP_WATCHDOG) += iop_wdt.o
+ obj-$(CONFIG_DAVINCI_WATCHDOG) += davinci_wdt.o
+ obj-$(CONFIG_ORION5X_WATCHDOG) += orion5x_wdt.o
++obj-$(CONFIG_AST_WATCHDOG) += ast_wdt.o
+
+ # ARM26 Architecture
+
+diff --git a/drivers/watchdog/ast_wdt.c b/drivers/watchdog/ast_wdt.c
+new file mode 100644
+index 0000000..845f1db
+--- /dev/null
++++ b/drivers/watchdog/ast_wdt.c
+@@ -0,0 +1,519 @@
++/********************************************************************************
++* File Name : ast_wdt
++*
++* Copyright (C) 2012-2020 ASPEED Technology Inc.
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License as published by the Free Software Foundation;
++* either version 2 of the License, or (at your option) any later version.
++* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++* without even the implied warranty of MERCHANTABILITY or
++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
++* You should have received a copy of the GNU General Public License
++* along with this program; if not, write to the Free Software
++* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++********************************************************************************/
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/poll.h>
++#include <linux/interrupt.h>
++#include <linux/errno.h>
++#include <linux/types.h>
++#include <linux/string.h>
++#include <linux/delay.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/mm.h>
++#include <linux/miscdevice.h>
++#include <linux/watchdog.h>
++#include <linux/fs.h>
++#include <linux/notifier.h>
++#include <linux/reboot.h>
++#include <linux/init.h>
++#include <linux/semaphore.h>
++#include <asm/uaccess.h>
++
++#include <linux/platform_device.h>
++#include <asm/io.h>
++
++#ifdef CONFIG_COLDFIRE
++#include <asm/arch/irqs.h>
++#include <asm/arch/ast_wdt.h>
++#include <asm/arch/platform.h>
++#else
++#include <mach/irqs.h>
++#include <mach/ast_wdt.h>
++#include <mach/platform.h>
++#endif
++
++#define TICKS_PER_uSEC 1
++
++
++typedef unsigned char bool_T;
++
++#ifdef TRUE
++#undef TRUE
++#endif
++
++#ifdef FALSE
++#undef FALSE
++#endif
++
++#define TRUE 1
++#define FALSE 0
++
++#if defined(CONFIG_COLDFIRE)
++#define WDT_BASE_VA AST_WDT_BASE
++
++#else
++#define WDT_BASE_VA (IO_ADDRESS(AST_WDT_BASE))
++#endif
++
++#define WDT_CntSts (WDT_BASE_VA+0x00)
++#define WDT_Reload (WDT_BASE_VA+0x04)
++#define WDT_Restart (WDT_BASE_VA+0x08)
++#define WDT_Ctrl (WDT_BASE_VA+0x0C)
++#define WDT_TimeOut (WDT_BASE_VA+0x10)
++#define WDT_Clr (WDT_BASE_VA+0x14)
++#define WDT_RstWd (WDT_BASE_VA+0x18)
++
++
++#define AST_READ_REG(r) (*((volatile unsigned int *) (r)))
++#define AST_WRITE_REG(r,v) (*((volatile unsigned int *) (r)) = ((unsigned int) (v)))
++
++
++#define WDT_CLK_SRC_EXT 0
++#define WDT_CLK_SRC_PCLK 1
++
++//Global Variables
++#define WD_TIMO 6 /* Default heartbeat = 6 seconds */
++
++static int heartbeat = WD_TIMO;
++module_param(heartbeat, int, 0);
++MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WD_TIMO) ")");
++
++static int nowayout = WATCHDOG_NOWAYOUT;
++module_param(nowayout, int, 0);
++MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
++
++static unsigned long wdt_is_open;
++static char expect_close;
++
++//Function Declaration
++int __init wdt_init(void);
++
++static irqreturn_t wdt_isr(int irq, void *devid, struct pt_regs *regs)
++{
++ /* clear timeout */
++ AST_WRITE_REG(WDT_Clr, 1);
++
++ return (IRQ_HANDLED);
++}
++
++void wdt_disable(void)
++{
++ register unsigned int regVal;
++
++ /* reset WDT_Ctrl[0] as 0 */
++ regVal = AST_READ_REG(WDT_Ctrl);
++ regVal &= 0xFFFFFFFE;
++ AST_WRITE_REG(WDT_Ctrl, regVal);
++}
++
++void wdt_sel_clk_src(unsigned char sourceClk)
++{
++ register unsigned int regVal;
++
++ regVal = AST_READ_REG(WDT_Ctrl);
++ if (sourceClk == WDT_CLK_SRC_PCLK)
++ {
++ /* reset WDT_Ctrl[4] as 0 */
++ regVal &= 0xFFFFFFEF;
++ }
++ else
++ {
++ /* set WDT_Ctrl[4] as 1 */
++ regVal |= 0x00000010;
++ }
++ AST_WRITE_REG(WDT_Ctrl, regVal);
++}
++
++void wdt_set_timeout_action(bool_T bResetOut, bool_T bIntrSys, bool_T bResetSys)
++{
++ register unsigned int regVal;
++
++ regVal = AST_READ_REG(WDT_Ctrl);
++
++ if (bResetOut)
++ {
++ /* set WDT_Ctrl[3] = 1 */
++ regVal |= 0x00000008;
++ }
++ else
++ {
++ /* reset WDT_Ctrl[3] = 0 */
++ regVal &= 0xFFFFFFF7;
++ }
++
++ if (bIntrSys)
++ {
++ /* set WDT_Ctrl[2] = 1 */
++ regVal |= 0x00000004;
++ }
++ else
++ {
++ /* reset WDT_Ctrl[2] = 0 */
++ regVal &= 0xFFFFFFFB;
++ }
++
++ if (bResetSys)
++ {
++ /* set WDT_Ctrl[1] = 1 */
++ regVal |= 0x00000002;
++ }
++ else
++ {
++ /* reset WDT_Ctrl[1] = 0 */
++ regVal &= 0xFFFFFFFD;
++ }
++
++ AST_WRITE_REG(WDT_Ctrl, regVal);
++}
++
++void wdt_enable(void)
++{
++ register unsigned int regVal;
++
++ /* set WDT_Ctrl[0] as 1 */
++ regVal = AST_READ_REG(WDT_Ctrl);
++ regVal |= 1;
++ AST_WRITE_REG(WDT_Ctrl, regVal);
++}
++
++void wdt_restart_new(unsigned int nPeriod, int sourceClk, bool_T bResetOut, bool_T bIntrSys, bool_T bResetSys, bool_T bUpdated)
++{
++ wdt_disable();
++
++ AST_WRITE_REG(WDT_Reload, nPeriod);
++
++ wdt_sel_clk_src(sourceClk);
++
++ wdt_set_timeout_action(bResetOut, bIntrSys, bResetSys);
++
++ AST_WRITE_REG(WDT_Restart, 0x4755); /* reload! */
++
++ if (!bUpdated)
++ wdt_enable();
++}
++
++void wdt_restart(void)
++{
++ wdt_disable();
++ AST_WRITE_REG(WDT_Restart, 0x4755); /* reload! */
++ wdt_enable();
++}
++
++
++/**
++ * wdt_set_heartbeat:
++ * @t: the new heartbeat value that needs to be set.
++ *
++ * Set a new heartbeat value for the watchdog device. If the heartbeat value is
++ * incorrect we keep the old value and return -EINVAL. If successfull we
++ * return 0.
++ */
++static int wdt_set_heartbeat(int t)
++{
++ if ((t < 1) || (t > 1000))
++ return -EINVAL;
++
++ heartbeat=t;
++
++ wdt_restart_new(TICKS_PER_uSEC*1000000*t, WDT_CLK_SRC_EXT, FALSE, TRUE, FALSE, FALSE);
++ return 0;
++}
++
++/*
++ Kernel Interfaces
++*/
++
++/**
++ * ast_wdt_write:
++ * @file: file handle to the watchdog
++ * @buf: buffer to write (unused as data does not matter here
++ * @count: count of bytes
++ * @ppos: pointer to the position to write. No seeks allowed
++ *
++ * A write to a watchdog device is defined as a keepalive signal. Any
++ * write of data will do, as we we don't define content meaning.
++ */
++
++ static ssize_t ast_wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
++ {
++ if(count)
++ {
++ if (!nowayout)
++ {
++ size_t i;
++
++ /* In case it was set long ago */
++ expect_close = 0;
++
++ for (i = 0; i != count; i++)
++ {
++ char c;
++ if (get_user(c, buf + i))
++ return -EFAULT;
++ if (c == 'V')
++ expect_close = 42;
++ }
++ }
++ wdt_restart();
++ }
++ return count;
++ }
++
++/**
++ * ast_wdt_ioctl:
++ * @inode: inode of the device
++ * @file: file handle to the device
++ * @cmd: watchdog command
++ * @arg: argument pointer
++ * * The watchdog API defines a common set of functions for all watchdogs
++ * according to their available features. We only actually usefully support
++ * querying capabilities and current status.
++ */
++
++static int ast_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
++{
++ void __user *argp = (void __user *)arg;
++ int __user *p = argp;
++ int new_heartbeat;
++
++ static struct watchdog_info ident =
++ {
++ .options = WDIOF_SETTIMEOUT|
++ WDIOF_MAGICCLOSE|
++ WDIOF_KEEPALIVEPING,
++ .firmware_version = 1,
++ .identity = "AST WDT",
++ };
++
++ switch(cmd)
++ {
++ default:
++ return -ENOIOCTLCMD;
++ case WDIOC_GETSUPPORT:
++ return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
++ case WDIOC_GETSTATUS:
++ case WDIOC_GETBOOTSTATUS:
++ return put_user(0, p);
++ case WDIOC_KEEPALIVE:
++ wdt_restart();
++ return 0;
++ case WDIOC_SETTIMEOUT:
++ if (get_user(new_heartbeat, p))
++ return -EFAULT;
++
++ if (wdt_set_heartbeat(new_heartbeat))
++ return -EINVAL;
++
++ /* Fall */
++ case WDIOC_GETTIMEOUT:
++ return put_user(heartbeat, p);
++ }
++}
++/**
++* ast_wdt_open:
++* @inode: inode of device
++* @file: file handle to device
++*
++* The watchdog device has been opened. The watchdog device is single
++* open and on opening we load the counters. Counter zero is a 100Hz
++* cascade, into counter 1 which downcounts to reboot. When the counter
++* triggers counter 2 downcounts the length of the reset pulse which
++* set set to be as long as possible.
++*/
++
++static int ast_wdt_open(struct inode *inode, struct file *file)
++{
++ if(test_and_set_bit(0, &wdt_is_open))
++ return -EBUSY;
++ /*
++ * Activate
++ */
++ // wdt_init();
++ wdt_restart();
++ return nonseekable_open(inode, file);
++}
++
++/**
++* ast_wdt_release:
++* @inode: inode to board
++* @file: file handle to board
++*
++* The watchdog has a configurable API. There is a religious dispute
++* between people who want their watchdog to be able to shut down and
++* those who want to be sure if the watchdog manager dies the machine
++* reboots. In the former case we disable the counters, in the latter
++* case you have to open it again very soon.
++*/
++
++static int ast_wdt_release(struct inode *inode, struct file *file)
++{
++ if (expect_close == 42 || !nowayout)
++ {
++ wdt_disable();
++ clear_bit(0, &wdt_is_open);
++ }
++ else
++ {
++ printk(KERN_CRIT "wdt: WDT device closed unexpectedly. WDT will not stop!\n");
++ wdt_restart();
++ }
++ expect_close = 0;
++ return 0;
++}
++
++/**
++* notify_sys:
++* @this: our notifier block
++* @code: the event being reported
++* @unused: unused
++*
++* Our notifier is called on system shutdowns. We want to turn the card
++* off at reboot otherwise the machine will reboot again during memory
++* test or worse yet during the following fsck. This would suck, in fact
++* trust me - if it happens it does suck.
++*/
++
++static int ast_wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused)
++{
++ if(code==SYS_DOWN || code==SYS_HALT)
++ {
++ /* Turn the WDT off */
++ wdt_disable();
++ }
++ return NOTIFY_DONE;
++}
++
++extern void ast_soc_wdt_reset(void)
++{
++ writel(0x10 , WDT_BASE_VA+0x04);
++ writel(0x4755, WDT_BASE_VA+0x08);
++ writel(0x3, WDT_BASE_VA+0x0c);
++}
++
++EXPORT_SYMBOL(ast_soc_wdt_reset);
++
++static struct file_operations ast_wdt_fops =
++{
++ .owner = THIS_MODULE,
++ .llseek = no_llseek,
++ .write = ast_wdt_write,
++ .ioctl = ast_wdt_ioctl,
++ .open = ast_wdt_open,
++ .release = ast_wdt_release,
++};
++
++static struct miscdevice ast_wdt_miscdev =
++{
++ .minor = WATCHDOG_MINOR,
++ .name = "watchdog",
++ .fops = &ast_wdt_fops,
++};
++
++static struct notifier_block ast_wdt_notifier =
++{
++ .notifier_call=ast_wdt_notify_sys,
++};
++
++static int ast_wdt_probe(struct platform_device *pdev)
++{
++ int ret;
++
++ wdt_disable();
++ wdt_sel_clk_src(WDT_CLK_SRC_EXT);
++ wdt_set_timeout_action(FALSE, FALSE, FALSE);
++
++ /* register ISR */
++ if (request_irq(IRQ_WDT, (void *)wdt_isr, IRQF_DISABLED, "WDT", NULL))
++ {
++ printk("unable to register interrupt INT_WDT = %d\n", IRQ_WDT);
++ return (-1);
++ }
++ else
++ printk("success to register interrupt for INT_WDT (%d)\n", IRQ_WDT);
++
++ ret = register_reboot_notifier(&ast_wdt_notifier);
++ if(ret)
++ {
++ printk(KERN_ERR "wdt: cannot register reboot notifier (err=%d)\n", ret);
++ free_irq(IRQ_WDT, NULL);
++ return ret;
++ }
++
++ ret = misc_register(&ast_wdt_miscdev);
++ if (ret)
++ {
++ printk(KERN_ERR "wdt: cannot register miscdev on minor=%d (err=%d)\n",WATCHDOG_MINOR, ret);
++ unregister_reboot_notifier(&ast_wdt_notifier);
++ return ret;
++ }
++
++ /* interrupt the system while WDT timeout */
++ wdt_restart_new(TICKS_PER_uSEC*1000000*heartbeat, WDT_CLK_SRC_EXT, FALSE, TRUE, FALSE, TRUE);
++
++ printk(KERN_INFO "AST WDT is installed.(irq = %d, heartbeat = %d secs, nowayout = %d)\n",IRQ_WDT,heartbeat,nowayout);
++
++ return (0);
++}
++
++static int ast_wdt_remove(struct platform_device *dev)
++{
++ misc_deregister(&ast_wdt_miscdev);
++ disable_irq(IRQ_WDT);
++ free_irq(IRQ_WDT, NULL);
++ return 0;
++}
++
++static void ast_wdt_shutdown(struct platform_device *dev)
++{
++ wdt_disable();
++}
++
++static struct platform_driver ast_wdt_driver = {
++ .probe = ast_wdt_probe,
++ .remove = ast_wdt_remove,
++ .shutdown = ast_wdt_shutdown,
++#if 0
++ .suspend = ast_wdt_suspend,
++ .resume = ast_wdt_resume,
++#endif
++ .driver = {
++ .owner = THIS_MODULE,
++ .name = "ast-wdt",
++ },
++};
++
++static char banner[] __initdata = KERN_INFO "ASPEED Watchdog Timer, ASPEED Technology Inc.\n";
++
++static int __init watchdog_init(void)
++{
++ printk(banner);
++
++ return platform_driver_register(&ast_wdt_driver);
++}
++
++static void __exit watchdog_exit(void)
++{
++ platform_driver_unregister(&ast_wdt_driver);
++}
++
++module_init(watchdog_init);
++module_exit(watchdog_exit);
++
++MODULE_DESCRIPTION("Driver for AST Watch Dog");
++MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
++MODULE_LICENSE("GPL");
+diff --git a/fs/Kconfig b/fs/Kconfig
+index 522469a..382fa76 100644
+--- a/fs/Kconfig
++++ b/fs/Kconfig
+@@ -907,6 +907,10 @@ config EFS_FS
+ To compile the EFS file system support as a module, choose M here: the
+ module will be called efs.
+
++
++# Patched by YAFFS
++#source "fs/yaffs2/Kconfig"
++
+ source "fs/jffs2/Kconfig"
+ # UBIFS File system configuration
+ source "fs/ubifs/Kconfig"
+diff --git a/fs/Makefile b/fs/Makefile
+index d9f8afe..cbb1738 100644
+--- a/fs/Makefile
++++ b/fs/Makefile
+@@ -122,3 +122,6 @@ obj-$(CONFIG_HPPFS) += hppfs/
+ obj-$(CONFIG_DEBUG_FS) += debugfs/
+ obj-$(CONFIG_OCFS2_FS) += ocfs2/
+ obj-$(CONFIG_GFS2_FS) += gfs2/
++
++# Patched by YAFFS
++#obj-$(CONFIG_YAFFS_FS) += yaffs2/
+diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
+index 403aa50..b0068f7 100644
+--- a/include/linux/mmc/card.h
++++ b/include/linux/mmc/card.h
+@@ -24,12 +24,14 @@ struct mmc_cid {
+ };
+
+ struct mmc_csd {
++ unsigned char structure;
+ unsigned char mmca_vsn;
+ unsigned short cmdclass;
+ unsigned short tacc_clks;
+ unsigned int tacc_ns;
+ unsigned int r2w_factor;
+ unsigned int max_dtr;
++ unsigned int erase_size; /* In sectors */
+ unsigned int read_blkbits;
+ unsigned int write_blkbits;
+ unsigned int capacity;
+@@ -40,8 +42,17 @@ struct mmc_csd {
+ };
+
+ struct mmc_ext_csd {
++ u8 rev;
++ u8 erase_group_def;
++ u8 sec_feature_support;
++ unsigned int sa_timeout; /* Units: 100ns */
+ unsigned int hs_max_dtr;
+ unsigned int sectors;
++ unsigned int hc_erase_size; /* In sectors */
++ unsigned int hc_erase_timeout; /* In milliseconds */
++ unsigned int sec_trim_mult; /* Secure trim multiplier */
++ unsigned int sec_erase_mult; /* Secure erase multiplier */
++ unsigned int trim_timeout; /* In milliseconds */
+ };
+
+ struct sd_scr {
+@@ -89,12 +100,18 @@ struct mmc_card {
+ #define MMC_TYPE_MMC 0 /* MMC card */
+ #define MMC_TYPE_SD 1 /* SD card */
+ #define MMC_TYPE_SDIO 2 /* SDIO card */
++#define MMC_TYPE_SD_COMBO 3 /* SD combo (IO+mem) card */
+ unsigned int state; /* (our) card state */
+ #define MMC_STATE_PRESENT (1<<0) /* present in sysfs */
+ #define MMC_STATE_READONLY (1<<1) /* card is read-only */
+ #define MMC_STATE_HIGHSPEED (1<<2) /* card is in high speed mode */
+ #define MMC_STATE_BLOCKADDR (1<<3) /* card uses block-addressing */
+
++ unsigned int erase_size; /* erase size in sectors */
++ unsigned int erase_shift; /* if erase unit is power 2 */
++ unsigned int pref_erase; /* in sectors */
++ u8 erased_byte; /* value of erased bytes */
++
+ u32 raw_cid[4]; /* raw card CID */
+ u32 raw_csd[4]; /* raw card CSD */
+ u32 raw_scr[2]; /* raw card SCR */
+diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
+index 14b81f3..dd11ae5 100644
+--- a/include/linux/mmc/mmc.h
++++ b/include/linux/mmc/mmc.h
+@@ -31,6 +31,7 @@
+ #define MMC_ALL_SEND_CID 2 /* bcr R2 */
+ #define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */
+ #define MMC_SET_DSR 4 /* bc [31:16] RCA */
++#define MMC_SLEEP_AWAKE 5 /* ac [31:16] RCA 15:flg R1b */
+ #define MMC_SWITCH 6 /* ac [31:0] See below R1b */
+ #define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */
+ #define MMC_SEND_EXT_CSD 8 /* adtc R1 */
+@@ -127,6 +128,7 @@
+ #define R1_STATUS(x) (x & 0xFFFFE000)
+ #define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */
+ #define R1_READY_FOR_DATA (1 << 8) /* sx, a */
++#define R1_SWITCH_ERROR (1 << 7) /* sx, c */
+ #define R1_APP_CMD (1 << 5) /* sr, c */
+
+ /*
+@@ -249,11 +251,21 @@ struct _mmc_csd {
+ * EXT_CSD fields
+ */
+
+-#define EXT_CSD_BUS_WIDTH 183 /* R/W */
+-#define EXT_CSD_HS_TIMING 185 /* R/W */
+-#define EXT_CSD_CARD_TYPE 196 /* RO */
+-#define EXT_CSD_REV 192 /* RO */
+-#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */
++#define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */
++#define EXT_CSD_ERASED_MEM_CONT 181 /* RO */
++#define EXT_CSD_BUS_WIDTH 183 /* R/W */
++#define EXT_CSD_HS_TIMING 185 /* R/W */
++#define EXT_CSD_REV 192 /* RO */
++#define EXT_CSD_STRUCTURE 194 /* RO */
++#define EXT_CSD_CARD_TYPE 196 /* RO */
++#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */
++#define EXT_CSD_S_A_TIMEOUT 217 /* RO */
++#define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */
++#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */
++#define EXT_CSD_SEC_TRIM_MULT 229 /* RO */
++#define EXT_CSD_SEC_ERASE_MULT 230 /* RO */
++#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
++#define EXT_CSD_TRIM_MULT 232 /* RO */
+
+ /*
+ * EXT_CSD field definitions
+@@ -265,11 +277,16 @@ struct _mmc_csd {
+
+ #define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */
+ #define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */
++#define EXT_CSD_CARD_TYPE_MASK 0x3 /* Mask out reserved and DDR bits */
+
+ #define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
+ #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
+ #define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
+
++#define EXT_CSD_SEC_ER_EN BIT(0)
++#define EXT_CSD_SEC_BD_BLK_EN BIT(2)
++#define EXT_CSD_SEC_GB_CL_EN BIT(4)
++
+ /*
+ * MMC_SWITCH access modes
+ */
+diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
+index 733d3f3..ff8a124 100644
+--- a/include/linux/mtd/nand.h
++++ b/include/linux/mtd/nand.h
+@@ -599,6 +599,12 @@ struct platform_nand_ctrl {
+ void (*select_chip)(struct mtd_info *mtd, int chip);
+ void (*cmd_ctrl)(struct mtd_info *mtd, int dat,
+ unsigned int ctrl);
++ int (*calculate)(struct mtd_info *mtd,
++ const uint8_t *dat,
++ uint8_t *ecc_code);
++ int (*correct)(struct mtd_info *mtd, uint8_t *dat,
++ uint8_t *read_ecc,
++ uint8_t *calc_ecc);
+ void *priv;
+ };
+
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0000-linux-openbmc.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0000-linux-openbmc.patch
new file mode 100644
index 0000000..434a873
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0000-linux-openbmc.patch
@@ -0,0 +1,13400 @@
+diff --git a/Documentation/hwmon/pmbus b/Documentation/hwmon/pmbus
+new file mode 100644
+index 0000000..bc342af
+--- /dev/null
++++ b/Documentation/hwmon/pmbus
+@@ -0,0 +1,214 @@
++Kernel driver pmbus
++====================
++
++Supported chips:
++ * Ericsson BMR453, BMR454
++ Prefixes: 'bmr453', 'bmr454'
++ Addresses scanned: -
++ Datasheet:
++ http://archive.ericsson.net/service/internet/picov/get?DocNo=28701-EN/LZT146395
++ * ON Semiconductor ADP4000, NCP4200, NCP4208
++ Prefixes: 'adp4000', 'ncp4200', 'ncp4208'
++ Addresses scanned: -
++ Datasheets:
++ http://www.onsemi.com/pub_link/Collateral/ADP4000-D.PDF
++ http://www.onsemi.com/pub_link/Collateral/NCP4200-D.PDF
++ http://www.onsemi.com/pub_link/Collateral/JUNE%202009-%20REV.%200.PDF
++ * Lineage Power
++ Prefixes: 'mdt040', 'pdt003', 'pdt006', 'pdt012', 'udt020'
++ Addresses scanned: -
++ Datasheets:
++ http://www.lineagepower.com/oem/pdf/PDT003A0X.pdf
++ http://www.lineagepower.com/oem/pdf/PDT006A0X.pdf
++ http://www.lineagepower.com/oem/pdf/PDT012A0X.pdf
++ http://www.lineagepower.com/oem/pdf/UDT020A0X.pdf
++ http://www.lineagepower.com/oem/pdf/MDT040A0X.pdf
++ * Texas Instruments TPS40400, TPS40422
++ Prefixes: 'tps40400', 'tps40422'
++ Addresses scanned: -
++ Datasheets:
++ http://www.ti.com/lit/gpn/tps40400
++ http://www.ti.com/lit/gpn/tps40422
++ * Generic PMBus devices
++ Prefix: 'pmbus'
++ Addresses scanned: -
++ Datasheet: n.a.
++
++Author: Guenter Roeck <linux@roeck-us.net>
++
++
++Description
++-----------
++
++This driver supports hardware montoring for various PMBus compliant devices.
++It supports voltage, current, power, and temperature sensors as supported
++by the device.
++
++Each monitored channel has its own high and low limits, plus a critical
++limit.
++
++Fan support will be added in a later version of this driver.
++
++
++Usage Notes
++-----------
++
++This driver does not probe for PMBus devices, since there is no register
++which can be safely used to identify the chip (The MFG_ID register is not
++supported by all chips), and since there is no well defined address range for
++PMBus devices. You will have to instantiate the devices explicitly.
++
++Example: the following will load the driver for an LTC2978 at address 0x60
++on I2C bus #1:
++$ modprobe pmbus
++[KML: Not for the backport]
++$ echo ltc2978 0x60 > /sys/bus/i2c/devices/i2c-1/new_device
++
++
++Platform data support
++---------------------
++
++Support for additional PMBus chips can be added by defining chip parameters in
++a new chip specific driver file. For example, (untested) code to add support for
++Emerson DS1200 power modules might look as follows.
++
++static struct pmbus_driver_info ds1200_info = {
++ .pages = 1,
++ /* Note: All other sensors are in linear mode */
++ .direct[PSC_VOLTAGE_OUT] = true,
++ .direct[PSC_TEMPERATURE] = true,
++ .direct[PSC_CURRENT_OUT] = true,
++ .m[PSC_VOLTAGE_IN] = 1,
++ .b[PSC_VOLTAGE_IN] = 0,
++ .R[PSC_VOLTAGE_IN] = 3,
++ .m[PSC_VOLTAGE_OUT] = 1,
++ .b[PSC_VOLTAGE_OUT] = 0,
++ .R[PSC_VOLTAGE_OUT] = 3,
++ .m[PSC_TEMPERATURE] = 1,
++ .b[PSC_TEMPERATURE] = 0,
++ .R[PSC_TEMPERATURE] = 3,
++ .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_STATUS_INPUT
++ | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
++ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
++ | PMBUS_HAVE_PIN | PMBUS_HAVE_POUT
++ | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP
++ | PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12,
++};
++
++static int ds1200_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ return pmbus_do_probe(client, id, &ds1200_info);
++}
++
++static int ds1200_remove(struct i2c_client *client)
++{
++ return pmbus_do_remove(client);
++}
++
++static const struct i2c_device_id ds1200_id[] = {
++ {"ds1200", 0},
++ {}
++};
++
++MODULE_DEVICE_TABLE(i2c, ds1200_id);
++
++/* This is the driver that will be inserted */
++static struct i2c_driver ds1200_driver = {
++ .driver = {
++ .name = "ds1200",
++ },
++ .probe = ds1200_probe,
++ .remove = ds1200_remove,
++ .id_table = ds1200_id,
++};
++
++static int __init ds1200_init(void)
++{
++ return i2c_add_driver(&ds1200_driver);
++}
++
++static void __exit ds1200_exit(void)
++{
++ i2c_del_driver(&ds1200_driver);
++}
++
++
++Sysfs entries
++-------------
++
++When probing the chip, the driver identifies which PMBus registers are
++supported, and determines available sensors from this information.
++Attribute files only exist if respective sensors are supported by the chip.
++Labels are provided to inform the user about the sensor associated with
++a given sysfs entry.
++
++The following attributes are supported. Limits are read-write; all other
++attributes are read-only.
++
++inX_input Measured voltage. From READ_VIN or READ_VOUT register.
++inX_min Minimum Voltage.
++ From VIN_UV_WARN_LIMIT or VOUT_UV_WARN_LIMIT register.
++inX_max Maximum voltage.
++ From VIN_OV_WARN_LIMIT or VOUT_OV_WARN_LIMIT register.
++inX_lcrit Critical minimum Voltage.
++ From VIN_UV_FAULT_LIMIT or VOUT_UV_FAULT_LIMIT register.
++inX_crit Critical maximum voltage.
++ From VIN_OV_FAULT_LIMIT or VOUT_OV_FAULT_LIMIT register.
++inX_min_alarm Voltage low alarm. From VOLTAGE_UV_WARNING status.
++inX_max_alarm Voltage high alarm. From VOLTAGE_OV_WARNING status.
++inX_lcrit_alarm Voltage critical low alarm.
++ From VOLTAGE_UV_FAULT status.
++inX_crit_alarm Voltage critical high alarm.
++ From VOLTAGE_OV_FAULT status.
++inX_label "vin", "vcap", or "voutY"
++
++currX_input Measured current. From READ_IIN or READ_IOUT register.
++currX_max Maximum current.
++ From IIN_OC_WARN_LIMIT or IOUT_OC_WARN_LIMIT register.
++currX_lcrit Critical minimum output current.
++ From IOUT_UC_FAULT_LIMIT register.
++currX_crit Critical maximum current.
++ From IIN_OC_FAULT_LIMIT or IOUT_OC_FAULT_LIMIT register.
++currX_alarm Current high alarm.
++ From IIN_OC_WARNING or IOUT_OC_WARNING status.
++currX_max_alarm Current high alarm.
++ From IIN_OC_WARN_LIMIT or IOUT_OC_WARN_LIMIT status.
++currX_lcrit_alarm Output current critical low alarm.
++ From IOUT_UC_FAULT status.
++currX_crit_alarm Current critical high alarm.
++ From IIN_OC_FAULT or IOUT_OC_FAULT status.
++currX_label "iin" or "ioutY"
++
++powerX_input Measured power. From READ_PIN or READ_POUT register.
++powerX_cap Output power cap. From POUT_MAX register.
++powerX_max Power limit. From PIN_OP_WARN_LIMIT or
++ POUT_OP_WARN_LIMIT register.
++powerX_crit Critical output power limit.
++ From POUT_OP_FAULT_LIMIT register.
++powerX_alarm Power high alarm.
++ From PIN_OP_WARNING or POUT_OP_WARNING status.
++powerX_crit_alarm Output power critical high alarm.
++ From POUT_OP_FAULT status.
++powerX_label "pin" or "poutY"
++
++tempX_input Measured temperature.
++ From READ_TEMPERATURE_X register.
++tempX_min Mimimum temperature. From UT_WARN_LIMIT register.
++tempX_max Maximum temperature. From OT_WARN_LIMIT register.
++tempX_lcrit Critical low temperature.
++ From UT_FAULT_LIMIT register.
++tempX_crit Critical high temperature.
++ From OT_FAULT_LIMIT register.
++tempX_min_alarm Chip temperature low alarm. Set by comparing
++ READ_TEMPERATURE_X with UT_WARN_LIMIT if
++ TEMP_UT_WARNING status is set.
++tempX_max_alarm Chip temperature high alarm. Set by comparing
++ READ_TEMPERATURE_X with OT_WARN_LIMIT if
++ TEMP_OT_WARNING status is set.
++tempX_lcrit_alarm Chip temperature critical low alarm. Set by comparing
++ READ_TEMPERATURE_X with UT_FAULT_LIMIT if
++ TEMP_UT_FAULT status is set.
++tempX_crit_alarm Chip temperature critical high alarm. Set by comparing
++ READ_TEMPERATURE_X with OT_FAULT_LIMIT if
++ TEMP_OT_FAULT status is set.
+diff --git a/Documentation/hwmon/pmbus-core b/Documentation/hwmon/pmbus-core
+new file mode 100644
+index 0000000..31e4720
+--- /dev/null
++++ b/Documentation/hwmon/pmbus-core
+@@ -0,0 +1,283 @@
++PMBus core driver and internal API
++==================================
++
++Introduction
++============
++
++[from pmbus.org] The Power Management Bus (PMBus) is an open standard
++power-management protocol with a fully defined command language that facilitates
++communication with power converters and other devices in a power system. The
++protocol is implemented over the industry-standard SMBus serial interface and
++enables programming, control, and real-time monitoring of compliant power
++conversion products. This flexible and highly versatile standard allows for
++communication between devices based on both analog and digital technologies, and
++provides true interoperability which will reduce design complexity and shorten
++time to market for power system designers. Pioneered by leading power supply and
++semiconductor companies, this open power system standard is maintained and
++promoted by the PMBus Implementers Forum (PMBus-IF), comprising 30+ adopters
++with the objective to provide support to, and facilitate adoption among, users.
++
++Unfortunately, while PMBus commands are standardized, there are no mandatory
++commands, and manufacturers can add as many non-standard commands as they like.
++Also, different PMBUs devices act differently if non-supported commands are
++executed. Some devices return an error, some devices return 0xff or 0xffff and
++set a status error flag, and some devices may simply hang up.
++
++Despite all those difficulties, a generic PMBus device driver is still useful
++and supported since kernel version 2.6.39. However, it was necessary to support
++device specific extensions in addition to the core PMBus driver, since it is
++simply unknown what new device specific functionality PMBus device developers
++come up with next.
++
++To make device specific extensions as scalable as possible, and to avoid having
++to modify the core PMBus driver repeatedly for new devices, the PMBus driver was
++split into core, generic, and device specific code. The core code (in
++pmbus_core.c) provides generic functionality. The generic code (in pmbus.c)
++provides support for generic PMBus devices. Device specific code is responsible
++for device specific initialization and, if needed, maps device specific
++functionality into generic functionality. This is to some degree comparable
++to PCI code, where generic code is augmented as needed with quirks for all kinds
++of devices.
++
++PMBus device capabilities auto-detection
++========================================
++
++For generic PMBus devices, code in pmbus.c attempts to auto-detect all supported
++PMBus commands. Auto-detection is somewhat limited, since there are simply too
++many variables to consider. For example, it is almost impossible to autodetect
++which PMBus commands are paged and which commands are replicated across all
++pages (see the PMBus specification for details on multi-page PMBus devices).
++
++For this reason, it often makes sense to provide a device specific driver if not
++all commands can be auto-detected. The data structures in this driver can be
++used to inform the core driver about functionality supported by individual
++chips.
++
++Some commands are always auto-detected. This applies to all limit commands
++(lcrit, min, max, and crit attributes) as well as associated alarm attributes.
++Limits and alarm attributes are auto-detected because there are simply too many
++possible combinations to provide a manual configuration interface.
++
++PMBus internal API
++==================
++
++The API between core and device specific PMBus code is defined in
++drivers/hwmon/pmbus/pmbus.h. In addition to the internal API, pmbus.h defines
++standard PMBus commands and virtual PMBus commands.
++
++Standard PMBus commands
++-----------------------
++
++Standard PMBus commands (commands values 0x00 to 0xff) are defined in the PMBUs
++specification.
++
++Virtual PMBus commands
++----------------------
++
++Virtual PMBus commands are provided to enable support for non-standard
++functionality which has been implemented by several chip vendors and is thus
++desirable to support.
++
++Virtual PMBus commands start with command value 0x100 and can thus easily be
++distinguished from standard PMBus commands (which can not have values larger
++than 0xff). Support for virtual PMBus commands is device specific and thus has
++to be implemented in device specific code.
++
++Virtual commands are named PMBUS_VIRT_xxx and start with PMBUS_VIRT_BASE. All
++virtual commands are word sized.
++
++There are currently two types of virtual commands.
++
++- READ commands are read-only; writes are either ignored or return an error.
++- RESET commands are read/write. Reading reset registers returns zero
++ (used for detection), writing any value causes the associated history to be
++ reset.
++
++Virtual commands have to be handled in device specific driver code. Chip driver
++code returns non-negative values if a virtual command is supported, or a
++negative error code if not. The chip driver may return -ENODATA or any other
++Linux error code in this case, though an error code other than -ENODATA is
++handled more efficiently and thus preferred. Either case, the calling PMBus
++core code will abort if the chip driver returns an error code when reading
++or writing virtual registers (in other words, the PMBus core code will never
++send a virtual command to a chip).
++
++PMBus driver information
++------------------------
++
++PMBus driver information, defined in struct pmbus_driver_info, is the main means
++for device specific drivers to pass information to the core PMBus driver.
++Specifically, it provides the following information.
++
++- For devices supporting its data in Direct Data Format, it provides coefficients
++ for converting register values into normalized data. This data is usually
++ provided by chip manufacturers in device datasheets.
++- Supported chip functionality can be provided to the core driver. This may be
++ necessary for chips which react badly if non-supported commands are executed,
++ and/or to speed up device detection and initialization.
++- Several function entry points are provided to support overriding and/or
++ augmenting generic command execution. This functionality can be used to map
++ non-standard PMBus commands to standard commands, or to augment standard
++ command return values with device specific information.
++
++ API functions
++ -------------
++
++ Functions provided by chip driver
++ ---------------------------------
++
++ All functions return the command return value (read) or zero (write) if
++ successful. A return value of -ENODATA indicates that there is no manufacturer
++ specific command, but that a standard PMBus command may exist. Any other
++ negative return value indicates that the commands does not exist for this
++ chip, and that no attempt should be made to read or write the standard
++ command.
++
++ As mentioned above, an exception to this rule applies to virtual commands,
++ which _must_ be handled in driver specific code. See "Virtual PMBus Commands"
++ above for more details.
++
++ Command execution in the core PMBus driver code is as follows.
++
++ if (chip_access_function) {
++ status = chip_access_function();
++ if (status != -ENODATA)
++ return status;
++ }
++ if (command >= PMBUS_VIRT_BASE) /* For word commands/registers only */
++ return -EINVAL;
++ return generic_access();
++
++ Chip drivers may provide pointers to the following functions in struct
++ pmbus_driver_info. All functions are optional.
++
++ int (*read_byte_data)(struct i2c_client *client, int page, int reg);
++
++ Read byte from page <page>, register <reg>.
++ <page> may be -1, which means "current page".
++
++ int (*read_word_data)(struct i2c_client *client, int page, int reg);
++
++ Read word from page <page>, register <reg>.
++
++ int (*write_word_data)(struct i2c_client *client, int page, int reg,
++ u16 word);
++
++ Write word to page <page>, register <reg>.
++
++ int (*write_byte)(struct i2c_client *client, int page, u8 value);
++
++ Write byte to page <page>, register <reg>.
++ <page> may be -1, which means "current page".
++
++ int (*identify)(struct i2c_client *client, struct pmbus_driver_info *info);
++
++ Determine supported PMBus functionality. This function is only necessary
++ if a chip driver supports multiple chips, and the chip functionality is not
++ pre-determined. It is currently only used by the generic pmbus driver
++ (pmbus.c).
++
++ Functions exported by core driver
++ ---------------------------------
++
++ Chip drivers are expected to use the following functions to read or write
++ PMBus registers. Chip drivers may also use direct I2C commands. If direct I2C
++ commands are used, the chip driver code must not directly modify the current
++ page, since the selected page is cached in the core driver and the core driver
++ will assume that it is selected. Using pmbus_set_page() to select a new page
++ is mandatory.
++
++ int pmbus_set_page(struct i2c_client *client, u8 page);
++
++ Set PMBus page register to <page> for subsequent commands.
++
++ int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg);
++
++ Read word data from <page>, <reg>. Similar to i2c_smbus_read_word_data(), but
++ selects page first.
++
++ int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg,
++ u16 word);
++
++ Write word data to <page>, <reg>. Similar to i2c_smbus_write_word_data(), but
++ selects page first.
++
++ int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg);
++
++ Read byte data from <page>, <reg>. Similar to i2c_smbus_read_byte_data(), but
++ selects page first. <page> may be -1, which means "current page".
++
++ int pmbus_write_byte(struct i2c_client *client, int page, u8 value);
++
++ Write byte data to <page>, <reg>. Similar to i2c_smbus_write_byte(), but
++ selects page first. <page> may be -1, which means "current page".
++
++ void pmbus_clear_faults(struct i2c_client *client);
++
++ Execute PMBus "Clear Fault" command on all chip pages.
++ This function calls the device specific write_byte function if defined.
++ Therefore, it must _not_ be called from that function.
++
++ bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg);
++
++ Check if byte register exists. Return true if the register exists, false
++ otherwise.
++ This function calls the device specific write_byte function if defined to
++ obtain the chip status. Therefore, it must _not_ be called from that function.
++
++ bool pmbus_check_word_register(struct i2c_client *client, int page, int reg);
++
++ Check if word register exists. Return true if the register exists, false
++ otherwise.
++ This function calls the device specific write_byte function if defined to
++ obtain the chip status. Therefore, it must _not_ be called from that function.
++
++ int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id,
++ struct pmbus_driver_info *info);
++
++ Execute probe function. Similar to standard probe function for other drivers,
++ with the pointer to struct pmbus_driver_info as additional argument. Calls
++ identify function if supported. Must only be called from device probe
++ function.
++
++ void pmbus_do_remove(struct i2c_client *client);
++
++ Execute driver remove function. Similar to standard driver remove function.
++
++ const struct pmbus_driver_info
++ *pmbus_get_driver_info(struct i2c_client *client);
++
++ Return pointer to struct pmbus_driver_info as passed to pmbus_do_probe().
++
++
++PMBus driver platform data
++==========================
++
++PMBus platform data is defined in include/linux/i2c/pmbus.h. Platform data
++currently only provides a flag field with a single bit used.
++
++#define PMBUS_SKIP_STATUS_CHECK (1 << 0)
++
++struct pmbus_platform_data {
++ u32 flags; /* Device specific flags */
++};
++
++
++Flags
++-----
++
++PMBUS_SKIP_STATUS_CHECK
++
++During register detection, skip checking the status register for
++communication or command errors.
++
++Some PMBus chips respond with valid data when trying to read an unsupported
++register. For such chips, checking the status register is mandatory when
++trying to determine if a chip register exists or not.
++Other PMBus chips don't support the STATUS_CML register, or report
++communication errors for no explicable reason. For such chips, checking the
++status register must be disabled.
++
++Some i2c controllers do not support single-byte commands (write commands with
++no data, i2c_smbus_write_byte()). With such controllers, clearing the status
++register is impossible, and the PMBUS_SKIP_STATUS_CHECK flag must be set.
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index 71db83f..1869327 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -203,8 +203,10 @@ config ARCH_ASPEED
+ bool "ASPEED AST Family"
+ select ARM_AMBA
+ select PLAT_ASPEED
+- select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
++ select GENERIC_GPIO
++ select GENERIC_TIME
++ select GENERIC_CLOCKEVENTS
+
+
+ config ARCH_AAEC2000
+diff --git a/arch/arm/configs/wedge_defconfig b/arch/arm/configs/wedge_defconfig
+new file mode 100644
+index 0000000..23a9fe3
+--- /dev/null
++++ b/arch/arm/configs/wedge_defconfig
+@@ -0,0 +1,1479 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.28.9
++# Tue Feb 3 16:41:40 2015
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_KERNEL_GZIP=y
++# CONFIG_KERNEL_BZIP2 is not set
++# CONFIG_KERNEL_LZMA is not set
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++CONFIG_IKCONFIG=m
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=16
++# CONFIG_CGROUPS is not set
++# CONFIG_GROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++CONFIG_KALLSYMS_EXTRA_PASS=y
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++CONFIG_COMPAT_BRK=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_ARCH_ASPEED=y
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM is not set
++CONFIG_IRMP=y
++# CONFIG_PCEXT is not set
++# CONFIG_REMOTEFX is not set
++# CONFIG_ARCH_AST1100 is not set
++# CONFIG_ARCH_AST2100 is not set
++# CONFIG_ARCH_AST2200 is not set
++# CONFIG_ARCH_AST2300 is not set
++CONFIG_ARCH_AST2400=y
++# CONFIG_ARCH_AST2500 is not set
++
++#
++# FLASH Chip Select
++#
++# CONFIG_AST_CS0_NOR is not set
++# CONFIG_AST_CS0_NAND is not set
++CONFIG_AST_CS0_SPI=y
++# CONFIG_AST_CS0_NONE is not set
++# CONFIG_AST_CS1_NOR is not set
++# CONFIG_AST_CS1_NAND is not set
++# CONFIG_AST_CS1_SPI is not set
++CONFIG_AST_CS1_NONE=y
++# CONFIG_AST_CS2_NOR is not set
++# CONFIG_AST_CS2_NAND is not set
++# CONFIG_AST_CS2_SPI is not set
++CONFIG_AST_CS2_NONE=y
++# CONFIG_AST_CS3_NOR is not set
++# CONFIG_AST_CS3_NAND is not set
++# CONFIG_AST_CS3_SPI is not set
++CONFIG_AST_CS3_NONE=y
++# CONFIG_AST_CS4_NOR is not set
++# CONFIG_AST_CS4_NAND is not set
++# CONFIG_AST_CS4_SPI is not set
++CONFIG_AST_CS4_NONE=y
++# CONFIG_ARCH_AST1070 is not set
++# CONFIG_AST_SCU_LOCK is not set
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++CONFIG_PLAT_ASPEED=y
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_NOIFAR=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++# CONFIG_OUTER_CACHE is not set
++
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_TICK_ONESHOT=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++CONFIG_ARCH_FLATMEM_HAS_HOLES=y
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_UNEVICTABLE_LRU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++CONFIG_CMDLINE=""
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++CONFIG_FPE_NWFPE_XP=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_VFP=y
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
++CONFIG_BINFMT_AOUT=y
++# CONFIG_BINFMT_MISC is not set
++
++#
++# Power management options
++#
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++CONFIG_PM_SLEEP=y
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_APM_EMULATION is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=m
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++CONFIG_IPV6=m
++# CONFIG_IPV6_PRIVACY is not set
++# CONFIG_IPV6_ROUTER_PREF is not set
++# CONFIG_IPV6_OPTIMISTIC_DAD is not set
++# CONFIG_INET6_AH is not set
++# CONFIG_INET6_ESP is not set
++# CONFIG_INET6_IPCOMP is not set
++# CONFIG_IPV6_MIP6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++CONFIG_INET6_XFRM_MODE_TRANSPORT=m
++CONFIG_INET6_XFRM_MODE_TUNNEL=m
++CONFIG_INET6_XFRM_MODE_BEET=m
++# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
++CONFIG_IPV6_SIT=m
++CONFIG_IPV6_NDISC_NODETYPE=y
++# CONFIG_IPV6_TUNNEL is not set
++# CONFIG_IPV6_MULTIPLE_TABLES is not set
++# CONFIG_IPV6_MROUTE is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
++CONFIG_VLAN_8021Q=m
++# CONFIG_VLAN_8021Q_GVRP is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++CONFIG_WAN_ROUTER=y
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++# CONFIG_PHONET is not set
++# CONFIG_WIRELESS is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_SYS_HYPERVISOR is not set
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_CONCAT=y
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++CONFIG_MTD_DATAFLASH=m
++CONFIG_MTD_DATAFLASH_WRITE_VERIFY=y
++# CONFIG_MTD_DATAFLASH_OTP is not set
++CONFIG_MTD_M25P80=y
++CONFIG_M25PXX_USE_FAST_READ=y
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++CONFIG_BLK_DEV_NBD=y
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=16384
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_RD_BZIP2 is not set
++CONFIG_RD_LZMA=y
++CONFIG_RD_GZIP=y
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ICS932S401 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_C2PORT is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++CONFIG_SCSI_TGT=y
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++CONFIG_SCSI_SCAN_ASYNC=y
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++CONFIG_SCSI_ISCSI_ATTRS=m
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++CONFIG_BONDING=m
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++CONFIG_TUN=m
++# CONFIG_VETH is not set
++# CONFIG_NET_ETHERNET is not set
++CONFIG_NETDEV_1000=y
++CONFIG_ASPEEDMAC=y
++# CONFIG_NETDEV_10000 is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++# CONFIG_IWLWIFI_LEDS is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_GPIO is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_ELANTECH is not set
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++CONFIG_MOUSE_SERIAL=y
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_BCM5974 is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_AMBAKMI is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++CONFIG_DEVKMEM=y
++CONFIG_SERIAL_NONSTANDARD=y
++# CONFIG_N_HDLC is not set
++# CONFIG_RISCOM8 is not set
++# CONFIG_SPECIALIX is not set
++# CONFIG_RIO is not set
++# CONFIG_STALDRV is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=4
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++# CONFIG_SERIAL_AST_DMA_UART is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++# CONFIG_SERIAL_AMBA_PL011 is not set
++# CONFIG_SERIAL_AST is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_AST_MISC=y
++# CONFIG_AST_VIDEO is not set
++# CONFIG_ADC_CAT9883 is not set
++# CONFIG_AST_SPI_BIOS is not set
++CONFIG_AST_PECI=y
++# CONFIG_AST_KCS is not set
++# CONFIG_AST_GPIO is not set
++# CONFIG_HW_RANDOM is not set
++CONFIG_NVRAM=y
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_HELPER_AUTO=y
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++CONFIG_I2C_AST=y
++CONFIG_AST_I2C_SLAVE_MODE=y
++CONFIG_AST_I2C_SLAVE_EEPROM=y
++# CONFIG_AST_I2C_SLAVE_RDWR is not set
++# CONFIG_I2C_SIMTEC is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_STUB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++CONFIG_AT24=m
++# CONFIG_SENSORS_EEPROM is not set
++CONFIG_SENSORS_PCF8574=m
++# CONFIG_PCF8575 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
++
++#
++# SPI Master Controller Drivers
++#
++CONFIG_SPI_AST=y
++CONFIG_SPI_FMC=y
++CONFIG_SPI_BITBANG=y
++
++#
++# SPI Protocol Masters
++#
++CONFIG_SPI_AT25=m
++# CONFIG_SPI_SPIDEV is not set
++# CONFIG_SPI_TLE62X0 is not set
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO expanders:
++#
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_AD7414 is not set
++# CONFIG_SENSORS_AD7418 is not set
++# CONFIG_SENSORS_ADCXX is not set
++# CONFIG_SENSORS_ADM1021 is not set
++# CONFIG_SENSORS_ADM1025 is not set
++# CONFIG_SENSORS_ADM1026 is not set
++# CONFIG_SENSORS_ADM1029 is not set
++# CONFIG_SENSORS_ADM1031 is not set
++# CONFIG_SENSORS_ADM9240 is not set
++# CONFIG_SENSORS_ADT7462 is not set
++# CONFIG_SENSORS_ADT7470 is not set
++# CONFIG_SENSORS_ADT7473 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_F75375S is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_LM63 is not set
++# CONFIG_SENSORS_LM70 is not set
++CONFIG_SENSORS_LM75=m
++# CONFIG_SENSORS_LM77 is not set
++# CONFIG_SENSORS_LM78 is not set
++# CONFIG_SENSORS_LM80 is not set
++# CONFIG_SENSORS_LM83 is not set
++# CONFIG_SENSORS_LM85 is not set
++# CONFIG_SENSORS_LM87 is not set
++# CONFIG_SENSORS_LM90 is not set
++# CONFIG_SENSORS_LM92 is not set
++# CONFIG_SENSORS_LM93 is not set
++CONFIG_SENSORS_MAX127=m
++# CONFIG_SENSORS_MAX1111 is not set
++# CONFIG_SENSORS_MAX1619 is not set
++# CONFIG_SENSORS_MAX6650 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_DME1737 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++CONFIG_SENSORS_ADS7828=m
++# CONFIG_SENSORS_THMC50 is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_W83781D is not set
++# CONFIG_SENSORS_W83791D is not set
++# CONFIG_SENSORS_W83792D is not set
++# CONFIG_SENSORS_W83793 is not set
++# CONFIG_SENSORS_W83L785TS is not set
++# CONFIG_SENSORS_W83L786NG is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++CONFIG_SENSORS_AST_ADC=y
++CONFIG_SENSORS_AST_PWM_FAN=y
++CONFIG_SENSORS_FB_PANTHER_PLUS=m
++CONFIG_PMBUS=m
++CONFIG_SENSORS_PMBUS=m
++CONFIG_SENSORS_ADM1275=m
++# CONFIG_SENSORS_LM25066 is not set
++# CONFIG_SENSORS_LTC2978 is not set
++# CONFIG_SENSORS_MAX16064 is not set
++# CONFIG_SENSORS_MAX34440 is not set
++# CONFIG_SENSORS_MAX8688 is not set
++CONFIG_SENSORS_PFE1100=m
++CONFIG_SENSORS_PFE3000=m
++# CONFIG_SENSORS_UCD9000 is not set
++# CONFIG_SENSORS_UCD9200 is not set
++# CONFIG_SENSORS_ZL6100 is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++CONFIG_THERMAL=y
++CONFIG_THERMAL_HWMON=y
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++CONFIG_AST_WATCHDOG=y
++
++#
++# USB-based Watchdog Cards
++#
++# CONFIG_USBPCWATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM8350_I2C is not set
++
++#
++# Multimedia devices
++#
++
++#
++# Multimedia core support
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_VIDEO_MEDIA is not set
++
++#
++# Multimedia drivers
++#
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_SOUND is not set
++# CONFIG_HID_SUPPORT is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++# CONFIG_USB_ARCH_HAS_OHCI is not set
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=m
++# CONFIG_USB_DEBUG is not set
++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_SUSPEND is not set
++# CONFIG_USB_OTG is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++# CONFIG_USB_EHCI_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_HWA_HCD is not set
++
++#
++# AST USB Drivers
++#
++CONFIG_AST_USB_UHCI_HCD=y
++# CONFIG_AST_USB_UHCI_MULTIPORT_1 is not set
++# CONFIG_AST_USB_UHCI_MULTIPORT_2 is not set
++CONFIG_AST_USB_UHCI_MULTIPORT_4=y
++# CONFIG_USB_EHCI_SPLIT_ISO is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
++#
++
++#
++# see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=m
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_VST is not set
++CONFIG_USB_GADGET=y
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_VBUS_DRAW=2
++CONFIG_USB_GADGET_SELECTED=y
++# CONFIG_USB_GADGET_AT91 is not set
++# CONFIG_USB_GADGET_ATMEL_USBA is not set
++# CONFIG_USB_GADGET_FSL_USB2 is not set
++# CONFIG_USB_GADGET_LH7A40X is not set
++# CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_PXA25X is not set
++# CONFIG_USB_GADGET_PXA27X is not set
++# CONFIG_USB_GADGET_S3C2410 is not set
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_FSL_QE is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_GOKU is not set
++CONFIG_USB_GADGET_ASPEED_AST=y
++CONFIG_USB_ASPEED_AST=y
++# CONFIG_USB_GADGET_DUMMY_HCD is not set
++CONFIG_USB_GADGET_DUALSPEED=y
++CONFIG_USB_ZERO=m
++CONFIG_USB_ETH=m
++CONFIG_USB_ETH_RNDIS=y
++CONFIG_USB_GADGETFS=m
++CONFIG_USB_FILE_STORAGE=m
++# CONFIG_USB_FILE_STORAGE_TEST is not set
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++CONFIG_USB_CDC_COMPOSITE=m
++# CONFIG_MMC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++# CONFIG_RTC_HCTOSYS is not set
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++# CONFIG_RTC_DRV_DS1307 is not set
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++
++#
++# SPI RTC drivers
++#
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
++# CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_PL030 is not set
++# CONFIG_RTC_DRV_PL031 is not set
++CONFIG_RTC_DRV_ASPEED=y
++# CONFIG_DMADEVICES is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++CONFIG_EXT2_FS_XATTR=y
++CONFIG_EXT2_FS_POSIX_ACL=y
++CONFIG_EXT2_FS_SECURITY=y
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4_FS is not set
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_FILE_LOCKING=y
++# CONFIG_XFS_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++CONFIG_GENERIC_ACL=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=y
++# CONFIG_NTFS_DEBUG is not set
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=m
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_YAFFS_FS=y
++CONFIG_YAFFS_YAFFS1=y
++# CONFIG_YAFFS_9BYTE_TAGS is not set
++# CONFIG_YAFFS_DOES_ECC is not set
++CONFIG_YAFFS_YAFFS2=y
++CONFIG_YAFFS_AUTO_YAFFS2=y
++# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set
++# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
++# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
++# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
++CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
++# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++# CONFIG_JFFS2_SUMMARY is not set
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_NFS_V4 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_REGISTER_V4 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf8"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++CONFIG_NLS_CODEPAGE_936=y
++CONFIG_NLS_CODEPAGE_950=y
++CONFIG_NLS_CODEPAGE_932=y
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++# CONFIG_ENABLE_WARN_DEPRECATED is not set
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_MEMORY_INIT=y
++CONFIG_FRAME_POINTER=y
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_LATENCYTOP is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++
++#
++# Tracers
++#
++# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++# CONFIG_CRYPTO_FIPS is not set
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD=m
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_NULL=y
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_AUTHENC=m
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++# CONFIG_CRYPTO_ECB is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_XCBC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++CONFIG_CRYPTO_SHA1=y
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=m
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++# CONFIG_CRYPTO_HW is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++CONFIG_CRC_ITU_T=m
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++
++
++# GUC USB Drivers
++#
++CONFIG_GUC_USB_UHCI_HCD=m
++# CONFIG_GUC_USB_UHCI_MULTIPORT_1 is not set
++# CONFIG_GUC_USB_UHCI_MULTIPORT_2 is not set
++CONFIG_GUC_USB_UHCI_MULTIPORT_4=y
++# CONFIG_USB_GADGET_MUSB_HDRC is not set
+diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
+index 8ff0e23..21e17dc 100644
+--- a/arch/arm/kernel/head.S
++++ b/arch/arm/kernel/head.S
+@@ -21,7 +21,6 @@
+ #include <asm/memory.h>
+ #include <asm/thread_info.h>
+ #include <asm/system.h>
+-#include <asm/mach-types.h>
+
+ #if (PHYS_OFFSET & 0x001fffff)
+ #error "PHYS_OFFSET must be at an even 2MiB boundary!"
+@@ -77,14 +76,13 @@
+ */
+ .section ".text.head", "ax"
+ ENTRY(stext)
+- ldr r5, =machine_arch_type @ find the machine type
+ msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
+ @ and irqs disabled
+ mrc p15, 0, r9, c0, c0 @ get processor id
+ bl __lookup_processor_type @ r5=procinfo r9=cpuid
+ movs r10, r5 @ invalid processor (r5=0)?
+ beq __error_p @ yes, error 'p'
+-@ bl __lookup_machine_type @ r5=machinfo
++ bl __lookup_machine_type @ r5=machinfo
+ movs r8, r5 @ invalid machine (r5=0)?
+ beq __error_a @ yes, error 'a'
+ bl __vet_atags
+diff --git a/arch/arm/mach-aspeed/include/mach/ast_wdt.h b/arch/arm/mach-aspeed/include/mach/ast_wdt.h
+index 6d7d7f47..f9125a1 100755
+--- a/arch/arm/mach-aspeed/include/mach/ast_wdt.h
++++ b/arch/arm/mach-aspeed/include/mach/ast_wdt.h
+@@ -8,4 +8,4 @@
+ * your option) any later version.
+ */
+
+- extern void ast_soc_wdt_reset(void);
++ extern void ast_wdt_reset_full(void);
+diff --git a/arch/arm/mach-aspeed/include/mach/debug-macro.S b/arch/arm/mach-aspeed/include/mach/debug-macro.S
+index 0b7c927..ff3195a 100644
+--- a/arch/arm/mach-aspeed/include/mach/debug-macro.S
++++ b/arch/arm/mach-aspeed/include/mach/debug-macro.S
+@@ -13,9 +13,8 @@
+ .macro addruart, rx, tmp
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1 @ MMU enabled?
+- ldreq \rx, =AST_UART0_BASE
+- ldrne \rx, =IO_ADDRESS(AST_UART0_BASE)
+- orr \rx, \rx, #0x00012000
++ ldreq \rx, =AST_UART3_BASE
++ ldrne \rx, =IO_ADDRESS(AST_UART3_BASE)
+ .endm
+
+ #define UART_SHIFT 2
+diff --git a/arch/arm/mach-aspeed/include/mach/system.h b/arch/arm/mach-aspeed/include/mach/system.h
+index 96e90da..926268b 100644
+--- a/arch/arm/mach-aspeed/include/mach/system.h
++++ b/arch/arm/mach-aspeed/include/mach/system.h
+@@ -37,7 +37,7 @@ static inline void arch_reset(char mode)
+ * Use WDT to restart system
+ */
+ #if defined(CONFIG_AST_WATCHDOG) || defined(CONFIG_AST_WATCHDOG_MODULE)
+- ast_soc_wdt_reset();
++ ast_wdt_reset_full();
+ #endif
+ }
+
+diff --git a/arch/arm/mach-aspeed/include/mach/uncompress.h b/arch/arm/mach-aspeed/include/mach/uncompress.h
+index 896b854..80e560d 100644
+--- a/arch/arm/mach-aspeed/include/mach/uncompress.h
++++ b/arch/arm/mach-aspeed/include/mach/uncompress.h
+@@ -12,8 +12,8 @@
+ #include <mach/platform.h>
+ #include <mach/aspeed_serial.h>
+
+-#define UART_PUT_CHAR (*(volatile unsigned char *)(AST_UART0_BASE + UART_THR))
+-#define UART_GET_LSR (*(volatile unsigned char *)(AST_UART0_BASE + UART_LSR))
++#define UART_PUT_CHAR (*(volatile unsigned char *)(AST_UART3_BASE + UART_THR))
++#define UART_GET_LSR (*(volatile unsigned char *)(AST_UART3_BASE + UART_LSR))
+
+ static void putc(int c)
+ {
+diff --git a/arch/arm/mach-aspeed/include/mach/vmalloc.h b/arch/arm/mach-aspeed/include/mach/vmalloc.h
+index 3706cf1..51912ae 100644
+--- a/arch/arm/mach-aspeed/include/mach/vmalloc.h
++++ b/arch/arm/mach-aspeed/include/mach/vmalloc.h
+@@ -23,7 +23,7 @@
+ #define VMALLOC_OFFSET (8*1024*1024)
+ #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+ #define VMALLOC_VMADDR(x) ((unsigned long)(x))
+-#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
++#define VMALLOC_END (PAGE_OFFSET + 0x20000000)
+ #else
+ #define VMALLOC_END 0xf8000000UL
+ #endif
+\ No newline at end of file
+diff --git a/arch/arm/plat-aspeed/Makefile b/arch/arm/plat-aspeed/Makefile
+index faba830..b63191c 100644
+--- a/arch/arm/plat-aspeed/Makefile
++++ b/arch/arm/plat-aspeed/Makefile
+@@ -18,7 +18,7 @@ obj-y += dev-uart.o dev-vuart.o dev-wdt.o dev-rtc.o dev-gpio.o dev-sgpio.o
+ obj-y += dev-nor.o dev-nand.o dev-sdhci.o
+
+ #bus
+-obj-y += dev-i2c.o dev-spi.o dev-ehci.o dev-uhci.o dev-lpc.o dev-peci.o dev-kcs.o dev-mbx.o dev-snoop.o
++obj-y += dev-i2c.o dev-spi.o dev-ehci.o dev-uhci.o dev-lpc.o dev-peci.o dev-kcs.o dev-mbx.o dev-snoop.o dev-lpc.o
+
+ #dev
+ #obj-y += dev-udc11.o
+@@ -33,3 +33,6 @@ obj-y += dev-fb.o dev-video.o
+ #obj-m :=
+ #obj-n :=
+ #obj- :=
++
++#usbdevicegadgetthing
++obj-y += dev-virthub.o
+diff --git a/arch/arm/plat-aspeed/ast-scu.c b/arch/arm/plat-aspeed/ast-scu.c
+index 1f1dde2..76722f4 100644
+--- a/arch/arm/plat-aspeed/ast-scu.c
++++ b/arch/arm/plat-aspeed/ast-scu.c
+@@ -251,6 +251,15 @@ ast_scu_init_usb20(void)
+
+ }
+
++extern void
++ast_scu_init_vhub(void) {
++ //start USB20 clock
++ ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) | SCU_USB20_CLK_EN, AST_SCU_CLK_STOP);
++ mdelay(10);
++ //disable USB20 reset
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_USB20, AST_SCU_RESET);
++}
++
+ EXPORT_SYMBOL(ast_scu_init_usb20);
+
+ extern void
+@@ -739,7 +748,7 @@ ast_scu_multi_func_uart(u8 uart)
+ {
+ switch(uart) {
+ case 1:
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL2) |
+ SCU_FUN_PIN_UART1_RXD |
+ SCU_FUN_PIN_UART1_TXD |
+ SCU_FUN_PIN_UART1_NRTS |
+@@ -748,10 +757,10 @@ ast_scu_multi_func_uart(u8 uart)
+ SCU_FUN_PIN_UART1_NDSR |
+ SCU_FUN_PIN_UART1_NDCD |
+ SCU_FUN_PIN_UART1_NCTS,
+- AST_SCU_FUN_PIN_CTRL1);
++ AST_SCU_FUN_PIN_CTRL2);
+ break;
+ case 2:
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL2) |
+ SCU_FUN_PIN_UART2_RXD |
+ SCU_FUN_PIN_UART2_TXD |
+ SCU_FUN_PIN_UART2_NRTS |
+@@ -760,7 +769,7 @@ ast_scu_multi_func_uart(u8 uart)
+ SCU_FUN_PIN_UART2_NDSR |
+ SCU_FUN_PIN_UART2_NDCD |
+ SCU_FUN_PIN_UART2_NCTS,
+- AST_SCU_FUN_PIN_CTRL1);
++ AST_SCU_FUN_PIN_CTRL2);
+ break;
+ case 3:
+ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
+diff --git a/arch/arm/plat-aspeed/dev-i2c.c b/arch/arm/plat-aspeed/dev-i2c.c
+index 47cd152..9905390 100644
+--- a/arch/arm/plat-aspeed/dev-i2c.c
++++ b/arch/arm/plat-aspeed/dev-i2c.c
+@@ -46,7 +46,8 @@
+
+ #if defined (CONFIG_ARCH_AST2400)
+ #define I2C_PAGE_SIZE 8
+-struct buf_page page_info[I2C_PAGE_SIZE] =
++static spinlock_t page_info_lock = SPIN_LOCK_UNLOCKED;
++static struct buf_page page_info[I2C_PAGE_SIZE] =
+ {
+ [0] = {
+ .flag = 0,
+@@ -117,9 +118,10 @@ static void pool_buff_page_init(u32 buf_pool_addr)
+ static u8 request_pool_buff_page(struct buf_page **req_page)
+ {
+ int i;
++ unsigned long flags;
+ //TODO
+- spinlock_t lock;
+- spin_lock(&lock);
++
++ spin_lock_irqsave(&page_info_lock, flags);
+ for(i=0;i<I2C_PAGE_SIZE;i++) {
+ if(page_info[i].flag ==0) {
+ page_info[i].flag = 1;
+@@ -128,21 +130,26 @@ static u8 request_pool_buff_page(struct buf_page **req_page)
+ break;
+ }
+ }
+- spin_unlock(&lock);
+- return 0;
++ spin_unlock_irqrestore(&page_info_lock, flags);
++ return (i >= I2C_PAGE_SIZE);
+ }
+
+ static void free_pool_buff_page(struct buf_page *req_page)
+ {
++ unsigned long flags;
++ spin_lock_irqsave(&page_info_lock, flags);
++
+ req_page->flag = 0;
+ // I2CDBUG( "free page addr %x \n", req_page->page_addr);
+ req_page = NULL;
++ spin_unlock_irqrestore(&page_info_lock, flags);
+ }
+
+ #elif defined (CONFIG_ARCH_AST2300)
+ #define I2C_PAGE_SIZE 5
+
+-struct buf_page page_info[I2C_PAGE_SIZE] =
++static spinlock_t page_info_lock = SPIN_LOCK_UNLOCKED;
++static struct buf_page page_info[I2C_PAGE_SIZE] =
+ {
+ [0] = {
+ .flag = 0,
+@@ -186,27 +193,31 @@ static void pool_buff_page_init(u32 buf_pool_addr)
+ static u8 request_pool_buff_page(struct buf_page **req_page)
+ {
+ int i;
++ unsigned long flags;
+ //TODO
+- spinlock_t lock;
+- spin_lock(&lock);
++
++ spin_lock_irqsave(&page_info_lock, flags);
+ for(i=0;i<I2C_PAGE_SIZE;i++) {
+ if(page_info[i].flag ==0) {
+ page_info[i].flag = 1;
+ *req_page = &page_info[i];
+- spin_unlock(&lock);
+- return 1;
++ spin_unlock_irqrestore(&page_info_lock, flags);
++ return 0;
+ }
+ }
+- spin_unlock(&lock);
+- return 0;
++ spin_unlock_irqrestore(&page_info_lock, flags);
++ return 1;
+
+ }
+
+ //TODO check free ?
+ static void free_pool_buff_page(struct buf_page *req_page)
+ {
++ unsigned long flags;
++ spin_lock_irqsave(&page_info_lock, flags);
+ req_page->flag = 0;
+ req_page = NULL;
++ spin_unlock_irqrestore(&page_info_lock, flags);
+ }
+
+ #else
+@@ -592,19 +603,148 @@ static struct i2c_board_info __initdata ast_i2c_board_info_1[] = {
+ }
+ };
+
++
++//Under I2C Dev 2
++static struct i2c_board_info __initdata ast_i2c_board_info_2[] = {
++ // Looks like ncp4200 i2c address could be floating depending
++ // on the system. List all possibilities here (0x60 - 0x63).
++ // Hope the address will not change after probing.
++ {
++ I2C_BOARD_INFO("ncp4200", 0x60),
++ },
++ {
++ I2C_BOARD_INFO("ncp4200", 0x61),
++ },
++ {
++ I2C_BOARD_INFO("ncp4200", 0x62),
++ },
++ {
++ I2C_BOARD_INFO("ncp4200", 0x63),
++ },
++};
++
++
++//Under I2C Dev 3
++static struct i2c_board_info __initdata ast_i2c_board_info_3[] = {
++ // Looks like ncp4200 i2c address could be floating depending
++ // on the system. List all possibilities here (0x60 - 0x63)
++ // Hope the address will not change after probing.
++ {
++ I2C_BOARD_INFO("ncp4200", 0x60),
++ },
++ {
++ I2C_BOARD_INFO("ncp4200", 0x61),
++ },
++ {
++ I2C_BOARD_INFO("ncp4200", 0x62),
++ },
++ {
++ I2C_BOARD_INFO("ncp4200", 0x63),
++ },
++};
++
++
+ //Under I2C Dev 4
+ static struct i2c_board_info __initdata ast_i2c_board_info_4[] = {
++ // Temperature sensors on Wedge:
++ {
++ I2C_BOARD_INFO("tmp75", 0x48),
++ },
++ {
++ I2C_BOARD_INFO("tmp75", 0x49),
++ },
+ {
+- I2C_BOARD_INFO("24c128", 0x50),
++ I2C_BOARD_INFO("tmp75", 0x4a),
++ },
++};
+
++//Under I2C Dev 5
++static struct i2c_board_info __initdata ast_i2c_board_info_5[] = {
++ /* Panther+ microserver */
++ {
++ I2C_BOARD_INFO("fb_panther_plus", 0x40),
++ },
++ // Temperature sensor on uServer:
++ {
++ I2C_BOARD_INFO("tmp75", 0x4c),
++ },
++ {
++ I2C_BOARD_INFO("ads7828", 0x4b),
++ },
++ {
++ I2C_BOARD_INFO("24c128", 0x51),
++ },
++};
+
++//Under I2C Dev 7
++static struct i2c_board_info __initdata ast_i2c_board_info_7[] = {
++ // Wedge devices
++ {
++ I2C_BOARD_INFO("max127", 0x28),
++ },
++ {
++ // Differs from the schematic, but appears to be correct
++ I2C_BOARD_INFO("pcf8574", 0x3f),
++ },
++ {
++ I2C_BOARD_INFO("24c64", 0x50),
+ }
+ };
++
++
+ //Under I2C Dev 8
+ static struct i2c_board_info __initdata ast_i2c_board_info_8[] = {
+ {
++ // Eval board:
+ I2C_BOARD_INFO("lm75b", 0x4a),
+- }
++ },
++ // EEPROMS on the pfe1100 power supplies
++ {
++ I2C_BOARD_INFO("24c64", 0x51),
++ },
++ {
++ I2C_BOARD_INFO("24c64", 0x52),
++ },
++ {
++ I2C_BOARD_INFO("pfe1100", 0x59),
++ },
++ {
++ I2C_BOARD_INFO("pfe1100", 0x5a),
++ },
++};
++
++
++//Under I2C Dev 9
++static struct i2c_board_info __initdata ast_i2c_board_info_9[] = {
++ // Looks like ncp4200 i2c address could be floating depending
++ // on the system. List all possibilities here (0x60 - 0x63)
++ // Hope the address will not change after probing.
++ {
++ I2C_BOARD_INFO("ncp4200", 0x60),
++ },
++ {
++ I2C_BOARD_INFO("ncp4200", 0x61),
++ },
++ {
++ I2C_BOARD_INFO("ncp4200", 0x62),
++ },
++ {
++ I2C_BOARD_INFO("ncp4200", 0x63),
++ },
++};
++
++//Under I2C Dev 12
++static struct i2c_board_info __initdata ast_i2c_board_info_12[] = {
++ {
++ I2C_BOARD_INFO("pfe3000", 0x10),
++ },
++};
++
++//Under I2C Dev 13
++static struct i2c_board_info __initdata ast_i2c_board_info_13[] = {
++ {
++ I2C_BOARD_INFO("adm1278", 0x10),
++ },
+ };
+
+ #endif
+@@ -642,25 +782,36 @@ void __init ast_add_device_i2c(void)
+ platform_device_register(&ast_i2c_dev1_device);
+ i2c_register_board_info(0, ast_i2c_board_info_1, ARRAY_SIZE(ast_i2c_board_info_1));
+ platform_device_register(&ast_i2c_dev2_device);
++ i2c_register_board_info(1, ast_i2c_board_info_2, ARRAY_SIZE(ast_i2c_board_info_2));
+ platform_device_register(&ast_i2c_dev3_device);
++ i2c_register_board_info(2, ast_i2c_board_info_3, ARRAY_SIZE(ast_i2c_board_info_3));
+ platform_device_register(&ast_i2c_dev4_device);
+ i2c_register_board_info(3, ast_i2c_board_info_4, ARRAY_SIZE(ast_i2c_board_info_4));
+ platform_device_register(&ast_i2c_dev5_device);
++ i2c_register_board_info(4, ast_i2c_board_info_5, ARRAY_SIZE(ast_i2c_board_info_5));
+ platform_device_register(&ast_i2c_dev6_device);
+ platform_device_register(&ast_i2c_dev7_device);
++ i2c_register_board_info(6, ast_i2c_board_info_7, ARRAY_SIZE(ast_i2c_board_info_7));
+ platform_device_register(&ast_i2c_dev8_device);
+ i2c_register_board_info(7, ast_i2c_board_info_8, ARRAY_SIZE(ast_i2c_board_info_8));
+ platform_device_register(&ast_i2c_dev9_device);
++ i2c_register_board_info(8, ast_i2c_board_info_9, ARRAY_SIZE(ast_i2c_board_info_9));
+
+ #if defined(CONFIG_ARCH_AST2400)
+ platform_device_register(&ast_i2c_dev10_device);
+ #if defined(CONFIG_MMC_AST)
+ //Due to share pin with SD
+ #else
+- platform_device_register(&ast_i2c_dev11_device);
++ /*
++ * On Wedge, bus 13 is used as i2c bus. Bus 12 is used on other
++ * hardware. Pins for bus 11, 12, and 14 are used as GPIOs, on
++ * various hardware, but enabling the i2c bus does not seem to
++ * interfere with the GPIOs.
++ */
+ platform_device_register(&ast_i2c_dev12_device);
++ i2c_register_board_info(11, ast_i2c_board_info_12, ARRAY_SIZE(ast_i2c_board_info_12));
+ platform_device_register(&ast_i2c_dev13_device);
+- platform_device_register(&ast_i2c_dev14_device);
++ i2c_register_board_info(12, ast_i2c_board_info_13, ARRAY_SIZE(ast_i2c_board_info_13));
+ #endif
+ #endif
+ }
+diff --git a/arch/arm/plat-aspeed/dev-lpc.c b/arch/arm/plat-aspeed/dev-lpc.c
+index 50eb4e6..945e320 100644
+--- a/arch/arm/plat-aspeed/dev-lpc.c
++++ b/arch/arm/plat-aspeed/dev-lpc.c
+@@ -25,22 +25,14 @@
+ #include <linux/string.h>
+ #include <linux/platform_device.h>
+
++#include <asm/io.h>
+ #include <mach/irqs.h>
+ #include <mach/platform.h>
+ #include <plat/devs.h>
+ #include <plat/ast-scu.h>
++#include <plat/regs-lpc.h>
+
+-
+-
+-#include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <linux/platform_device.h>
+-
+-#include <mach/irqs.h>
+-#include <mach/platform.h>
+-#include <plat/devs.h>
+-#include <plat/ast-scu.h>
+-
++static u32 ast_lpc_base = IO_ADDRESS(AST_LPC_BASE);
+
+ /* --------------------------------------------------------------------
+ * LPC
+@@ -100,6 +92,12 @@ void __init ast_add_device_lpc(void)
+ platform_device_register(&ast_lpc_plus_device);
+ }
+ #else
+-void __init ast_add_device_lpc(void) {}
++void __init ast_add_device_lpc(void) {
++ // Since we disable LPC, bring the UART1 and UART2 out from LPC control
++ writel((readl(ast_lpc_base + AST_LPC_HICR9)
++ & ~(LPC_HICR9_SOURCE_UART1|LPC_HICR9_SOURCE_UART2
++ |LPC_HICR9_SOURCE_UART3|LPC_HICR9_SOURCE_UART4)),
++ ast_lpc_base + AST_LPC_HICR9);
++}
+ #endif
+
+diff --git a/arch/arm/plat-aspeed/dev-pwm-fan.c b/arch/arm/plat-aspeed/dev-pwm-fan.c
+index 85570bb..c667194 100644
+--- a/arch/arm/plat-aspeed/dev-pwm-fan.c
++++ b/arch/arm/plat-aspeed/dev-pwm-fan.c
+@@ -65,14 +65,6 @@ struct platform_device ast_pwm_fan_device = {
+
+ void __init ast_add_device_pwm_fan(void)
+ {
+- //SCU Initial
+-
+- //SCU Pin-MUX //PWM & TACHO
+- ast_scu_multi_func_pwm_tacho();
+-
+- //SCU PWM CTRL Reset
+- ast_scu_init_pwm_tacho();
+-
+ platform_device_register(&ast_pwm_fan_device);
+ }
+ #else
+diff --git a/arch/arm/plat-aspeed/dev-rtc.c b/arch/arm/plat-aspeed/dev-rtc.c
+index 214aa68..a8d9b2f 100644
+--- a/arch/arm/plat-aspeed/dev-rtc.c
++++ b/arch/arm/plat-aspeed/dev-rtc.c
+@@ -33,7 +33,7 @@
+ * Watchdog
+ * -------------------------------------------------------------------- */
+
+-#if defined(CONFIG_RTC_DRV_AST) || defined(CONFIG_RTC_DRV_AST_MODULE)
++#if defined(CONFIG_RTC_DRV_ASPEED) || defined(CONFIG_RTC_DRV_ASPEED_MODULE)
+
+ static struct resource ast_rtc_resource[] = {
+ [0] = {
+diff --git a/arch/arm/plat-aspeed/dev-spi.c b/arch/arm/plat-aspeed/dev-spi.c
+index 7ddd2e4..e22c49e 100644
+--- a/arch/arm/plat-aspeed/dev-spi.c
++++ b/arch/arm/plat-aspeed/dev-spi.c
+@@ -210,8 +210,8 @@ static struct ast_spi_driver_data ast_spi0_data = {
+
+ static struct resource ast_spi_resource0[] = {
+ {
+- .start = AST_SPI0_BASE,
+- .end = AST_SPI0_BASE + SZ_16,
++ .start = AST_SPI_BASE,
++ .end = AST_SPI_BASE + SZ_16,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+@@ -299,21 +299,21 @@ static struct mtd_partition ast_spi_flash_partitions[] = {
+ static struct mtd_partition ast_spi_flash_partitions[] = {
+ {
+ .name = "u-boot",
+- .offset = 0,
+- .size = 0x80000,
++ .offset = 0, /* From 0 */
++ .size = 0x60000, /* Size 384K */
+ .mask_flags = MTD_WRITEABLE,
++ }, {
++ .name = "env",
++ .offset = 0x60000, /* From 384K */
++ .size = 0x20000, /* Size 128K, two sectors */
+ }, {
+- .name = "kernel",
+- .offset = 0x80000,
+- .size = 0x200000,
++ .name = "kernel",
++ .offset = 0x80000, /* From 512K */
++ .size = 0x200000, /* Size 2M */
+ }, {
+- .name = "rootfs",
+- .offset = 0x300000,
+- .size = 0x4F0000,
+- }, {
+- .name = "env",
+- .offset = 0x7f0000,
+- .size = 0x10000,
++ .name = "rootfs",
++ .offset = 0x300000, /* From 3M */
++ .size = 0xC00000, /* Size 12M */
+ }, {
+ .name = "data0",
+ .offset = MTDPART_OFS_APPEND,
+@@ -334,7 +334,34 @@ static struct flash_platform_data ast_spi_flash_data = {
+ .parts = ast_spi_flash_partitions,
+ };
+
++#ifdef CONFIG_ARCH_AST2400
++static struct flash_platform_data wedge_spi_flash_data = {
++ .type = "n25q128a13",
++ .nr_parts = ARRAY_SIZE(ast_spi_flash_partitions),
++ .parts = ast_spi_flash_partitions,
++};
++#endif
++
++
++/* Device info for the flash on ast-spi */
++#ifdef CONFIG_ARCH_AST2400
++static struct mtd_partition ast_spi5_flash_partitions[] = {
++ {
++ .name = "led-fpga",
++ .offset = 0, /* From 0 */
++ .size = MTDPART_SIZ_FULL,
++ },
++};
++
++static struct flash_platform_data wedge_spi5_flash_data = {
++ .type = "at45db011d",
++ .nr_parts = ARRAY_SIZE(ast_spi5_flash_partitions),
++ .parts = ast_spi5_flash_partitions,
++};
++#endif
++
+ static struct spi_board_info ast_spi_devices[] = {
++#if 0
+ {
+ .modalias = "m25p80",
+ .platform_data = &ast_spi_flash_data,
+@@ -343,6 +370,25 @@ static struct spi_board_info ast_spi_devices[] = {
+ .bus_num = 0, // This chooses if SPI0 or SPI1 of the SoC is used.
+ .mode = SPI_MODE_0,
+ },
++#endif
++#ifdef CONFIG_ARCH_AST2400
++ {
++ .modalias = "mtd_dataflash",
++ .platform_data = &wedge_spi5_flash_data,
++ .chip_select = 0,
++ .max_speed_hz = 33 * 1000 * 1000,
++ .bus_num = 5,
++ .mode = SPI_MODE_0,
++ },
++ {
++ .modalias = "m25p80",
++ .platform_data = &wedge_spi_flash_data,
++ .chip_select = 0, //.chip_select This tells your device driver which chipselect to use.
++ .max_speed_hz = 50 * 1000 * 1000,
++ .bus_num = 0, // This chooses if SPI0 or SPI1 of the SoC is used.
++ .mode = SPI_MODE_0,
++ },
++#endif
+ {
+ .modalias = "spidev",
+ .chip_select = 0,
+diff --git a/arch/arm/plat-aspeed/dev-uart.c b/arch/arm/plat-aspeed/dev-uart.c
+index 592ef4f..0b7b614 100644
+--- a/arch/arm/plat-aspeed/dev-uart.c
++++ b/arch/arm/plat-aspeed/dev-uart.c
+@@ -98,6 +98,17 @@ static struct plat_serial8250_port ast_uart_data[] = {
+ },
+ #endif
+ #endif
++#ifdef AST_UART1_BASE
++ {
++ .mapbase = AST_UART1_BASE,
++ .membase = (char*)(IO_ADDRESS(AST_UART1_BASE)),
++ .irq = IRQ_UART1,
++ .uartclk = (24*1000000L),
++ .regshift = 2,
++ .iotype = UPIO_MEM,
++ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++ },
++#endif
+ #ifdef AST_UART3_BASE
+ {
+ .mapbase = AST_UART3_BASE,
+@@ -134,6 +145,7 @@ void __init ast_add_device_uart(void)
+ {
+ #if defined(CONFIG_ARCH_AST1010)
+ #else
++ ast_scu_multi_func_uart(1);
+ ast_scu_multi_func_uart(3);
+ ast_scu_multi_func_uart(4);
+ #endif
+diff --git a/arch/arm/plat-aspeed/dev-virthub.c b/arch/arm/plat-aspeed/dev-virthub.c
+new file mode 100644
+index 0000000..34a5ae1
+--- /dev/null
++++ b/arch/arm/plat-aspeed/dev-virthub.c
+@@ -0,0 +1,62 @@
++/*
++ * dev-virthub
++ *
++ * Copyright 2014-present Facebook. All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/platform_device.h>
++
++#include <mach/irqs.h>
++#include <mach/platform.h>
++#include <plat/devs.h>
++#include <plat/ast-scu.h>
++
++static struct resource ast_virthub_resource[] = {
++ [0] = {
++ .start = AST_USB20_BASE,
++ .end = AST_USB20_BASE + SZ_1K,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_USB20_HUB,
++ .end = IRQ_USB20_HUB,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static u64 ast_virthub_dma_mask = 0xfffffff8UL;
++
++static struct platform_device ast_virthub_device = {
++ .name = "aspeed_udc",
++ .id = 0,
++ .dev = {
++ .dma_mask = &ast_virthub_dma_mask,
++ .coherent_dma_mask = 0xffffffff,
++ },
++ .resource = ast_virthub_resource,
++ .num_resources = ARRAY_SIZE(ast_virthub_resource),
++};
++
++void __init ast_add_device_virthub(void)
++{
++ ast_scu_multi_func_usb20_host_hub(0);
++ ast_scu_init_vhub();
++ printk("virtual hub inited?\n");
++ platform_device_register(&ast_virthub_device);
++}
+diff --git a/arch/arm/plat-aspeed/devs.c b/arch/arm/plat-aspeed/devs.c
+index 7906b9c..be6d7f4 100644
+--- a/arch/arm/plat-aspeed/devs.c
++++ b/arch/arm/plat-aspeed/devs.c
+@@ -31,13 +31,14 @@
+ typedef void (init_fnc_t) (void);
+
+ init_fnc_t __initdata *init_all_device[] = {
++ ast_add_device_lpc,
+ ast_add_device_uart,
+ ast_add_device_vuart,
+ ast_add_device_watchdog,
+ ast_add_device_rtc,
+ ast_add_device_i2c,
+ ast_add_device_spi,
+- ast_add_device_ehci,
++//ast_add_device_ehci, disabled by tfang for USB HUB mode
+ ast_add_device_nand,
+ ast_add_device_flash,
+ ast_add_device_pwm_fan,
+@@ -46,13 +47,14 @@ init_fnc_t __initdata *init_all_device[] = {
+ ast_add_device_sgpio,
+ ast_add_device_peci,
+ ast_add_device_fb,
+- ast_add_device_sdhci,
+- ast_add_device_uhci,
+- ast_add_device_video,
++// ast_add_device_sdhci, disabled by tfang
++// ast_add_device_uhci, disabled by tfang
++// ast_add_device_video, disabled by tfang
+ ast_add_device_kcs,
+ ast_add_device_mailbox,
+ ast_add_device_snoop,
+ ast_add_device_gmac,
++ ast_add_device_virthub,
+ // ast_add_device_nand,
+ NULL,
+ };
+diff --git a/arch/arm/plat-aspeed/include/plat/ast-scu.h b/arch/arm/plat-aspeed/include/plat/ast-scu.h
+index 77169ee..14a437f 100644
+--- a/arch/arm/plat-aspeed/include/plat/ast-scu.h
++++ b/arch/arm/plat-aspeed/include/plat/ast-scu.h
+@@ -49,6 +49,7 @@ extern void ast_scu_init_lpc(void);
+ extern u8 ast_scu_get_lpc_plus_enable(void);
+ extern void ast_scu_init_udc11(void);
+ extern void ast_scu_init_usb20(void);
++extern void ast_scu_init_vhub(void);
+ extern void ast_scu_init_uhci(void);
+ extern void ast_scu_init_sdhci(void);
+ extern void ast_scu_init_i2c(void);
+diff --git a/arch/arm/plat-aspeed/include/plat/devs.h b/arch/arm/plat-aspeed/include/plat/devs.h
+index 41cbea9..8653e95 100644
+--- a/arch/arm/plat-aspeed/include/plat/devs.h
++++ b/arch/arm/plat-aspeed/include/plat/devs.h
+@@ -41,6 +41,8 @@ extern void __init ast_add_device_uhci(void);
+ extern void __init ast_add_device_gmac(void);
+ extern void __init ast_add_device_udc11(void);
+ extern void __init ast_add_device_hid(void);
++extern void __init ast_add_device_lpc(void);
++extern void __init ast_add_device_virthub(void);
+
+ extern void __init ast_add_device_pcie(void);
+
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-lpc.h b/arch/arm/plat-aspeed/include/plat/regs-lpc.h
+index f4523d7..92c5130 100644
+--- a/arch/arm/plat-aspeed/include/plat/regs-lpc.h
++++ b/arch/arm/plat-aspeed/include/plat/regs-lpc.h
+@@ -186,6 +186,12 @@
+ #define GET_LPC_SNPD1(x) ((x >> 7) & 0xff)
+ #define GET_LPC_SNPD0(x) (x & 0xff)
+
++/* AST_LPC_HICR9 0x098 - LPC Host Interface Control Register 9 */
++#define LPC_HICR9_SOURCE_UART1 (1 << 4)
++#define LPC_HICR9_SOURCE_UART2 (1 << 5)
++#define LPC_HICR9_SOURCE_UART3 (1 << 6)
++#define LPC_HICR9_SOURCE_UART4 (1 << 7)
++
+ /*AST_LPC_PCCR0 0x130 - Post Code Contol Register 0 */
+ #define LPC_POST_DMA_INT_EN (1 << 31)
+ #define LPC_POST_DMA_MODE_EN (1 << 14)
+diff --git a/arch/arm/plat-aspeed/include/plat/regs-pwm_fan.h b/arch/arm/plat-aspeed/include/plat/regs-pwm_fan.h
+index 23d5b77..f1c474c 100644
+--- a/arch/arm/plat-aspeed/include/plat/regs-pwm_fan.h
++++ b/arch/arm/plat-aspeed/include/plat/regs-pwm_fan.h
+@@ -90,14 +90,14 @@
+
+ #define AST_PTCR_CTRL_FAN_NUM_EN(x) (0x1 << (16+x))
+
+-#define AST_PTCR_CTRL_PMWD (11)
+-#define AST_PTCR_CTRL_PMWD_EN (0x1 << 11)
+-#define AST_PTCR_CTRL_PMWC (10)
+-#define AST_PTCR_CTRL_PMWC_EN (0x1 << 10)
+-#define AST_PTCR_CTRL_PMWB (9)
+-#define AST_PTCR_CTRL_PMWB_EN (0x1 << 9)
+-#define AST_PTCR_CTRL_PMWA (8)
+-#define AST_PTCR_CTRL_PMWA_EN (0x1 << 8)
++#define AST_PTCR_CTRL_PWMD (11)
++#define AST_PTCR_CTRL_PWMD_EN (0x1 << 11)
++#define AST_PTCR_CTRL_PWMC (10)
++#define AST_PTCR_CTRL_PWMC_EN (0x1 << 10)
++#define AST_PTCR_CTRL_PWMB (9)
++#define AST_PTCR_CTRL_PWMB_EN (0x1 << 9)
++#define AST_PTCR_CTRL_PWMA (8)
++#define AST_PTCR_CTRL_PWMA_EN (0x1 << 8)
+
+ #define AST_PTCR_CTRL_CLK_MCLK 0x2 //0:24Mhz, 1:MCLK
+ #define AST_PTCR_CTRL_CLK_EN 0x1
+@@ -209,14 +209,14 @@
+ #define AST_PTCR_CTRL_GET_PWME_TYPE(x) (((x&(0x1<<4))>>3) | ((x&(0x1<<12))>>12))
+ #define AST_PTCR_CTRL_SET_PWME_TYPE_MASK ((0x1<<4) | (0x1<<12))
+
+-#define AST_PTCR_CTRL_PMWH (11)
+-#define AST_PTCR_CTRL_PMWH_EN (0x1 << 11)
+-#define AST_PTCR_CTRL_PMWG (10)
+-#define AST_PTCR_CTRL_PMWG_EN (0x1 << 10)
+-#define AST_PTCR_CTRL_PMWF (9)
+-#define AST_PTCR_CTRL_PMWF_EN (0x1 << 9)
+-#define AST_PTCR_CTRL_PMWE (8)
+-#define AST_PTCR_CTRL_PMWE_EN (0x1 << 8)
++#define AST_PTCR_CTRL_PWMH (11)
++#define AST_PTCR_CTRL_PWMH_EN (0x1 << 11)
++#define AST_PTCR_CTRL_PWMG (10)
++#define AST_PTCR_CTRL_PWMG_EN (0x1 << 10)
++#define AST_PTCR_CTRL_PWMF (9)
++#define AST_PTCR_CTRL_PWMF_EN (0x1 << 9)
++#define AST_PTCR_CTRL_PWME (8)
++#define AST_PTCR_CTRL_PWME_EN (0x1 << 8)
+
+ // AST_PTCR_CLK_EXT_CTRL : 0x44 - Clock Control Extension #1
+ //TYPE O
+diff --git a/arch/arm/plat-aspeed/timer.c b/arch/arm/plat-aspeed/timer.c
+index 079d958..6805beb 100644
+--- a/arch/arm/plat-aspeed/timer.c
++++ b/arch/arm/plat-aspeed/timer.c
+@@ -16,19 +16,13 @@
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
++#include <asm/io.h>
++#include <linux/clocksource.h>
++#include <linux/clockchips.h>
+ #include <linux/types.h>
+-#include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/device.h>
+-#include <linux/spinlock.h>
+ #include <linux/interrupt.h>
+-#include <linux/sched.h>
+-
+ #include <linux/irq.h>
+-#include <asm/system.h>
+-#include <asm/io.h>
+-#include <mach/hardware.h>
+-#include <mach/irqs.h>
+ #include <mach/time.h>
+ #include <plat/ast-scu.h>
+
+@@ -37,72 +31,145 @@
+ #define ASPEED_TIMER2_VA_BASE (IO_ADDRESS(AST_TIMER_BASE)+ASPEED_TIMER2_OFFSET)
+ #define ASPEED_TIMERC_VA_BASE (IO_ADDRESS(AST_TIMER_BASE)+ASPEED_TIMERRC_OFFSET)
+
+-/*
+- * Returns number of ms since last clock interrupt. Note that interrupts
+- * will have been disabled by do_gettimeoffset()
+- */
+-static unsigned long ast_gettimeoffset(void)
++#define ASPEED_TIMER_RELOAD_MAX 0xFFFFFFFF
++#define ASPEED_TIMER_RELOAD_MIN 1
++
++static struct clock_event_device clockevent_ast;
++
++static inline unsigned long ast_timer_read_count(void *base)
+ {
+- volatile TimerStruct_t *timer0 = (TimerStruct_t *) ASPEED_TIMER0_VA_BASE;
+- unsigned long ticks1, ticks2;//, status;
++ volatile TimerStruct_t *timer = (volatile TimerStruct_t *)(base);
++ return timer->TimerValue;
++}
+
+- /*
+- * Get the current number of ticks. Note that there is a race
+- * condition between us reading the timer and checking for
+- * an interrupt. We get around this by ensuring that the
+- * counter has not reloaded between our two reads.
+- */
+- ticks2 = timer0->TimerValue;
+- do {
+- ticks1 = ticks2;
+-// status = readl(AST_RAW_STS(0));// __raw_readl(IO_ADDRESS(ASPEED_VIC_BASE) + ASPEED_VIC_RAW_STATUS_OFFSET);
+- ticks2 = timer0->TimerValue;
+- } while (ticks2 > ticks1);
++/* change the timer count and load value (if requeseted) */
++static inline void ast_timer_set_count(void *base, unsigned long count,
++ unsigned long reload)
++{
++ volatile TimerStruct_t *timer = (volatile TimerStruct_t *)(base);
++ timer->TimerValue = count;
++ timer->TimerLoad = reload;
++}
+
+- /*
+- * Number of ticks since last interrupt.
+- */
+- ticks1 = TIMER_RELOAD - ticks2;
++#define AST_TIMER_DISABLE 0
++#define AST_TIMER_ENABLE 1
+
+- /*
+- * Interrupt pending? If so, we've reloaded once already.
+- */
+-// if (status & (1 << IRQ_TIMER0))
+-// ticks1 += TIMER_RELOAD;
++static inline void ast_timer0_ctrl(int enable)
++{
++ volatile __u32 *timerc = (volatile __u32*) ASPEED_TIMERC_VA_BASE;
++ if (enable == AST_TIMER_ENABLE) {
++ *timerc |= TIMER0_ENABLE | TIMER0_RefExt;
++ } else {
++ *timerc &= ~TIMER0_ENABLE;
++ }
++}
+
+- /*
+- * Convert the ticks to usecs
+- */
+- return TICKS2USECS(ticks1);
++static inline void ast_timer1_ctrl(int enable)
++{
++ volatile __u32 *timerc = (volatile __u32*) ASPEED_TIMERC_VA_BASE;
++ if (enable == AST_TIMER_ENABLE) {
++ *timerc |= TIMER1_ENABLE | TIMER1_RefExt;
++ } else {
++ *timerc &= ~TIMER1_ENABLE;
++ }
+ }
+
++static inline void ast_timer_disable_all()
++{
++ volatile __u32 *timerc = (volatile __u32*) ASPEED_TIMERC_VA_BASE;
++ *timerc = 0;
++}
+
+ /*
+- * IRQ handler for the timer
++ * clocksource
+ */
+-static irqreturn_t
+-ast_timer_interrupt(int irq, void *dev_id)
++static irqreturn_t ast_clocksource_interrupt(int irq, void *dev_id)
+ {
++ return IRQ_HANDLED;
++}
+
+-// write_seqlock(&xtime_lock);
++static struct irqaction ast_clocksource_irq = {
++ .name = "ast-clocksource",
++ .flags = IRQF_DISABLED | IRQF_TIMER,
++ .handler = ast_clocksource_interrupt,
++};
++
++static cycle_t read_cycles(void)
++{
++#if 1
++ return (cycles_t)(ASPEED_TIMER_RELOAD_MAX
++ - ast_timer_read_count(ASPEED_TIMER1_VA_BASE));
++#else
++ return (cycles_t) ast_timer_read_count(ASPEED_TIMER1_VA_BASE);
++#endif
++}
++
++static struct clocksource clocksource_ast = {
++ .name = "ast-clocksource",
++ .rating = 300,
++ .read = read_cycles,
++ .mask = CLOCKSOURCE_MASK(32),
++ .shift = 20,
++ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
++};
+
+ /*
+- * clear the interrupt in Irq.c
++ * clockevent
+ */
+-// IRQ_EDGE_CLEAR(0,IRQ_TIMER0);
+-
+- timer_tick();
++/* IRQ handler for the timer */
++static irqreturn_t ast_clockevent_interrupt(int irq, void *dev_id)
++{
++ struct clock_event_device *evt = &clockevent_ast;
++ evt->event_handler(evt);
++ return IRQ_HANDLED;
++}
+
++static struct irqaction ast_clockevent_irq = {
++ .name = "ast-clockevent",
++ .flags = IRQF_DISABLED | IRQF_TIMER,
++ .handler = ast_clockevent_interrupt,
++};
+
+-// write_sequnlock(&xtime_lock);
++static int ast_timer_set_next_event(unsigned long cycles,
++ struct clock_event_device *evt)
++{
++ /* In this case, we shall not set the load value. */
++ ast_timer_set_count(ASPEED_TIMER0_VA_BASE, cycles, 0);
++ /* turn on the timer */
++ ast_timer0_ctrl(AST_TIMER_ENABLE);
++ return 0;
++}
+
+- return IRQ_HANDLED;
++static void ast_timer_set_mode(enum clock_event_mode mode,
++ struct clock_event_device *evt)
++{
++ /* stop timer first */
++ ast_timer0_ctrl(AST_TIMER_DISABLE);
++ switch (mode) {
++ case CLOCK_EVT_MODE_PERIODIC:
++ ast_timer_set_count(ASPEED_TIMER0_VA_BASE,
++ TIMER_RELOAD - 1, TIMER_RELOAD - 1);
++ ast_timer0_ctrl(AST_TIMER_ENABLE);
++ break;
++ case CLOCK_EVT_MODE_ONESHOT:
++ /*
++ * Leave the timer disabled, ast_timer_set_next_event() will
++ * enable it later
++ */
++ break;
++ case CLOCK_EVT_MODE_UNUSED:
++ case CLOCK_EVT_MODE_SHUTDOWN:
++ case CLOCK_EVT_MODE_RESUME:
++ break;
++ }
+ }
+
+-static struct irqaction ast_timer_irq = {
+- .name = "ast timer",
+- .flags = IRQF_DISABLED | IRQF_TIMER,
+- .handler = ast_timer_interrupt,
++static struct clock_event_device clockevent_ast = {
++ .name = "ast-clockevent",
++ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
++ .shift = 32,
++ .set_next_event = ast_timer_set_next_event,
++ .set_mode = ast_timer_set_mode,
+ };
+
+ /*
+@@ -110,28 +177,50 @@ static struct irqaction ast_timer_irq = {
+ */
+ static void __init ast_setup_timer(void)
+ {
+- volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *) ASPEED_TIMER0_VA_BASE;
+- volatile __u32 *timerc = (volatile __u32*) ASPEED_TIMERC_VA_BASE;
+-
+ /*
+ * Initialise to a known state (all timers off)
+ */
+- *timerc = 0;
+-
+- timer0->TimerLoad = TIMER_RELOAD - 1;
+- timer0->TimerValue = TIMER_RELOAD - 1;
+- *timerc = TIMER0_ENABLE | TIMER0_RefExt;
++ ast_timer_disable_all();
+
+ /*
+- * Make irqs happen for the system timer
++ * For clock event, set the value and reload to 0, so that no interrupt even
++ * after enabling timer.
+ */
++ ast_timer_set_count(ASPEED_TIMER0_VA_BASE, 0, 0);
++ /*
++ * For clock source, set the value and reload to the max
++ */
++ ast_timer_set_count(ASPEED_TIMER1_VA_BASE,
++ ASPEED_TIMER_RELOAD_MAX, ASPEED_TIMER_RELOAD_MAX);
++
++ /* Enable timer */
++ ast_timer0_ctrl(AST_TIMER_ENABLE);
++ ast_timer1_ctrl(AST_TIMER_ENABLE);
++
+ ast_scu_show_system_info();
+
+- setup_irq(IRQ_TIMER0, &ast_timer_irq);
+-
++ /* irqs happen for the system timer */
++ setup_irq(IRQ_TIMER0, &ast_clockevent_irq);
++ setup_irq(IRQ_TIMER1, &ast_clocksource_irq);
++
++ /* setup clocksource */
++ clocksource_ast.mult = clocksource_hz2mult(ASPEED_TIMER_CLKRATE,
++ clocksource_ast.shift);
++ if (clocksource_register(&clocksource_ast)) {
++ printk(KERN_ERR "Failed to register clock source %s", clocksource_ast.name);
++ }
++
++ /* setup clockevent */
++ clockevent_ast.mult = div_sc(ASPEED_TIMER_CLKRATE, NSEC_PER_SEC,
++ clockevent_ast.shift);
++ clockevent_ast.max_delta_ns = clockevent_delta2ns(ASPEED_TIMER_RELOAD_MAX,
++ &clockevent_ast);
++ clockevent_ast.min_delta_ns = clockevent_delta2ns(ASPEED_TIMER_RELOAD_MIN,
++ &clockevent_ast);
++ clockevent_ast.cpumask = cpumask_of_cpu(0);
++ clockevents_register_device(&clockevent_ast);
+ }
+
+ struct sys_timer ast_timer = {
+ .init = ast_setup_timer,
+-// .offset = ast_gettimeoffset,
+ };
+diff --git a/drivers/Makefile b/drivers/Makefile
+index fceb71a..0f19c40f 100644
+--- a/drivers/Makefile
++++ b/drivers/Makefile
+@@ -102,3 +102,4 @@ obj-$(CONFIG_SSB) += ssb/
+ obj-$(CONFIG_VIRTIO) += virtio/
+ obj-$(CONFIG_REGULATOR) += regulator/
+ obj-$(CONFIG_STAGING) += staging/
++
+diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
+index 681782b..6055720 100644
+--- a/drivers/hwmon/Kconfig
++++ b/drivers/hwmon/Kconfig
+@@ -548,6 +548,16 @@ config SENSORS_LM93
+ This driver can also be built as a module. If so, the module
+ will be called lm93.
+
++config SENSORS_MAX127
++ tristate "Maxim MAX127 sensor chip"
++ depends on I2C
++ help
++ If you say yes here you get support for the MAX127,
++ 5 channel, 12-bit DAC sensor chip.
++
++ This driver can also be built as a module. If so, the module
++ will be called max127.
++
+ config SENSORS_MAX1111
+ tristate "Maxim MAX1111 Multichannel, Serial 8-bit ADC chip"
+ depends on SPI_MASTER
+@@ -870,6 +880,15 @@ config SENSORS_AST_PWM_FAN
+ This driver provides support for the ASPEED PWM & FAN Tacho
+ Controller, which provides an Sensor, fan control.
+
++config SENSORS_FB_PANTHER_PLUS
++ tristate "Facebook Panther+ Microserver Driver"
++ depends on ARCH_ASPEED && I2C
++ default n
++ help
++ This driver provides support for Facebook Panther+ microserver.
++
++ Say Y here if you run on the BMC which connects to Panther+ microserver
++
+ config SENSORS_APPLESMC
+ tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)"
+ depends on INPUT && X86
+@@ -895,6 +914,8 @@ config SENSORS_APPLESMC
+ Say Y here if you have an applicable laptop and want to experience
+ the awesome power of applesmc.
+
++source drivers/hwmon/pmbus/Kconfig
++
+ config HWMON_DEBUG_CHIP
+ bool "Hardware Monitoring Chip debugging messages"
+ default n
+diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
+index 5629727..8039515 100644
+--- a/drivers/hwmon/Makefile
++++ b/drivers/hwmon/Makefile
+@@ -31,6 +31,7 @@ obj-$(CONFIG_SENSORS_ADT7473) += adt7473.o
+ obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o
+ obj-$(CONFIG_SENSORS_AST_ADC) += ast_adc.o
+ obj-$(CONFIG_SENSORS_AST_PWM_FAN) += ast_pwm_fan.o
++obj-$(CONFIG_SENSORS_FB_PANTHER_PLUS) += fb_panther_plus.o
+ obj-$(CONFIG_SENSORS_AMS) += ams/
+ obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o
+ obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o
+@@ -64,6 +65,7 @@ obj-$(CONFIG_SENSORS_LM87) += lm87.o
+ obj-$(CONFIG_SENSORS_LM90) += lm90.o
+ obj-$(CONFIG_SENSORS_LM92) += lm92.o
+ obj-$(CONFIG_SENSORS_LM93) += lm93.o
++obj-$(CONFIG_SENSORS_MAX127) += max127.o
+ obj-$(CONFIG_SENSORS_MAX1111) += max1111.o
+ obj-$(CONFIG_SENSORS_MAX1619) += max1619.o
+ obj-$(CONFIG_SENSORS_MAX6650) += max6650.o
+@@ -81,6 +83,8 @@ obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o
+ obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o
+ obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o
+
++obj-$(CONFIG_PMBUS) += pmbus/
++
+ ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y)
+ EXTRA_CFLAGS += -DDEBUG
+ endif
+diff --git a/drivers/hwmon/ast_adc.c b/drivers/hwmon/ast_adc.c
+index 0969e39..3f95dc6 100644
+--- a/drivers/hwmon/ast_adc.c
++++ b/drivers/hwmon/ast_adc.c
+@@ -42,7 +42,7 @@
+ #include <plat/ast-scu.h>
+
+
+-#define REST_DESIGN 0
++#define REST_DESIGN 5
+
+ struct adc_vcc_ref_data {
+ int v2;
+@@ -50,7 +50,7 @@ struct adc_vcc_ref_data {
+ int r2;
+ };
+
+-static struct adc_vcc_ref_data adc_vcc_ref[5] = {
++static struct adc_vcc_ref_data adc_vcc_ref[6] = {
+ [0] = {
+ .v2 = 0,
+ .r1 = 5600,
+@@ -76,8 +76,20 @@ static struct adc_vcc_ref_data adc_vcc_ref[5] = {
+ .r1 = 56000,
+ .r2 = 1000,
+ },
++ [5] = {
++ .v2 = 0,
++ .r1 = 1000,
++ .r2 = 1000,
++ },
+ };
+
++/* Divisors for voltage sense; right now adc5 & adc6 divide by 2 */
++
++static int adc_divisor[] = { 1, 1, 1, 1,
++ 1, 2, 2, 1,
++ 1, 1, 1, 1,
++ 1, 1, 1, 1};
++
+ struct ast_adc_data {
+ struct device *hwmon_dev;
+ void __iomem *reg_base; /* virtual */
+@@ -388,6 +400,22 @@ ast_set_adc_en(struct ast_adc_data *ast_adc, u8 adc_ch, u8 enable)
+ }
+
+
++/* NAME sysfs */
++static ssize_t
++show_name(struct device *dev, struct device_attribute *devattr,
++ char *buf)
++{
++ return sprintf(buf, "ast_adc\n");
++}
++static SENSOR_DEVICE_ATTR_2(name, S_IRUGO, show_name, NULL, 0, 0);
++static struct attribute *name_attributes[] = {
++ &sensor_dev_attr_name.dev_attr.attr,
++ NULL
++};
++static const struct attribute_group name_attribute_groups = {
++ .attrs = name_attributes,
++};
++
+ /* attr ADC sysfs 0~max adc channel
+ * 0 - show/store channel enable
+ * 1 - show value
+@@ -399,12 +427,31 @@ ast_set_adc_en(struct ast_adc_data *ast_adc, u8 adc_ch, u8 enable)
+ * 7 - show/store hystersis low
+ */
+
++static u32
++ast_get_voltage(int idx) {
++ u16 tmp;
++ u32 voltage, tmp1, tmp2, tmp3;
++ tmp = ast_get_adc_value(ast_adc, idx);
++ // Voltage Sense Method
++ tmp1 = (adc_vcc_ref[REST_DESIGN].r1 + adc_vcc_ref[REST_DESIGN].r2) * tmp * 25 * 10;
++ tmp2 = adc_vcc_ref[REST_DESIGN].r2 * 1024 ;
++ tmp3 = (adc_vcc_ref[REST_DESIGN].r1 * adc_vcc_ref[REST_DESIGN].v2) / adc_vcc_ref[REST_DESIGN].r2;
++ // printk("tmp3 = %d \n",tmp3);
++ voltage = (tmp1/tmp2) - tmp3;
++
++ // Higher voltage inputs require a divisor
++
++ if (adc_divisor[idx])
++ voltage /= adc_divisor[idx];
++
++ return voltage;
++}
++
+ static ssize_t
+ ast_show_adc(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
+ {
+ struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
+- u16 tmp;
+- u32 voltage,tmp1, tmp2,tmp3;
++ u32 voltage;
+
+ //sensor_attr->index : pwm_ch#
+ //sensor_attr->nr : attr#
+@@ -414,15 +461,7 @@ ast_show_adc(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
+ return sprintf(sysfsbuf, "%d : %s\n", ast_get_adc_en(ast_adc,sensor_attr->index),ast_get_adc_en(ast_adc,sensor_attr->index) ? "Enable":"Disable");
+ break;
+ case 1: //value
+- tmp = ast_get_adc_value(ast_adc, sensor_attr->index);
+- //Voltage Sense Method
+- tmp1 = (adc_vcc_ref[REST_DESIGN].r1 + adc_vcc_ref[REST_DESIGN].r2) * tmp * 25 * 10;
+- tmp2 = adc_vcc_ref[REST_DESIGN].r2 * 1023 ;
+-
+- tmp3 = (adc_vcc_ref[REST_DESIGN].r1 * adc_vcc_ref[REST_DESIGN].v2) / adc_vcc_ref[REST_DESIGN].r2;
+- // printk("tmp3 = %d \n",tmp3);
+- voltage = (tmp1/tmp2) - tmp3;
+-
++ voltage = ast_get_voltage(sensor_attr->index);
+ return sprintf(sysfsbuf, "%d.%d (V)\n",voltage/100, voltage%100);
+ break;
+ case 2: //alarm
+@@ -443,6 +482,9 @@ ast_show_adc(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
+ case 7: //hystersis lower
+ return sprintf(sysfsbuf, "%d \n", ast_get_adc_hyster_lower(ast_adc,sensor_attr->index));
+ break;
++ case 8:
++ voltage = ast_get_voltage(sensor_attr->index);
++ return sprintf(sysfsbuf, "%d\n",voltage * 10);
+
+ default:
+ return -EINVAL;
+@@ -504,6 +546,7 @@ ast_store_adc(struct device *dev, struct device_attribute *attr, const char *sys
+ * 5 - show/store hystersis enable
+ * 6 - show/store hystersis upper
+ * 7 - show/store hystersis low
++* 8 - show value as 1000s, expected by lm-sensors
+ */
+
+ #define sysfs_adc_ch(index) \
+@@ -531,6 +574,9 @@ static SENSOR_DEVICE_ATTR_2(adc##index##_hyster_upper, S_IRUGO | S_IWUSR, \
+ static SENSOR_DEVICE_ATTR_2(adc##index##_hyster_lower, S_IRUGO | S_IWUSR, \
+ ast_show_adc, ast_store_adc, 7, index); \
+ \
++static SENSOR_DEVICE_ATTR_2(in##index##_input, S_IRUGO | S_IWUSR, \
++ ast_show_adc, NULL, 8, index); \
++\
+ static struct attribute *adc##index##_attributes[] = { \
+ &sensor_dev_attr_adc##index##_en.dev_attr.attr, \
+ &sensor_dev_attr_adc##index##_value.dev_attr.attr, \
+@@ -540,6 +586,7 @@ static struct attribute *adc##index##_attributes[] = { \
+ &sensor_dev_attr_adc##index##_hyster_en.dev_attr.attr, \
+ &sensor_dev_attr_adc##index##_hyster_upper.dev_attr.attr, \
+ &sensor_dev_attr_adc##index##_hyster_lower.dev_attr.attr, \
++ &sensor_dev_attr_in##index##_input.dev_attr.attr, \
+ NULL \
+ };
+
+@@ -637,10 +684,14 @@ ast_adc_probe(struct platform_device *pdev)
+ goto out_region;
+ }
+
++ err = sysfs_create_group(&pdev->dev.kobj, &name_attribute_groups);
++ if (err)
++ goto out_region;
++
+ for(i=0; i<MAX_CH_NO; i++) {
+ err = sysfs_create_group(&pdev->dev.kobj, &adc_attribute_groups[i]);
+ if (err)
+- goto out_region;
++ goto out_sysfs00;
+ }
+
+ ast_adc_ctrl_init();
+@@ -652,6 +703,8 @@ ast_adc_probe(struct platform_device *pdev)
+
+ //out_irq:
+ // free_irq(ast_adc->irq, NULL);
++out_sysfs00:
++ sysfs_remove_group(&pdev->dev.kobj, &name_attribute_groups);
+ out_region:
+ release_mem_region(res->start, res->end - res->start + 1);
+ out_mem:
+@@ -674,6 +727,8 @@ ast_adc_remove(struct platform_device *pdev)
+ for(i=0; i<5; i++)
+ sysfs_remove_group(&pdev->dev.kobj, &adc_attribute_groups[i]);
+
++ sysfs_remove_group(&pdev->dev.kobj, &name_attribute_groups);
++
+ platform_set_drvdata(pdev, NULL);
+ // free_irq(ast_adc->irq, ast_adc);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+diff --git a/drivers/hwmon/ast_pwm_fan.c b/drivers/hwmon/ast_pwm_fan.c
+index 02784c5..5864f5c 100644
+--- a/drivers/hwmon/ast_pwm_fan.c
++++ b/drivers/hwmon/ast_pwm_fan.c
+@@ -65,6 +65,8 @@
+ #include <mach/ast_pwm_techo.h>
+ #endif
+
++#include <plat/ast-scu.h>
++
+ //#define MCLK 1
+
+ struct ast_pwm_tacho_data {
+@@ -119,6 +121,8 @@ ast_pwm_tacho_read(struct ast_pwm_tacho_data *ast_pwm_tacho, u32 reg)
+
+ static void ast_pwm_taco_init(void)
+ {
++ uint32_t val;
++
+ //Enable PWM TACH CLK **************************************************
+ // Set M/N/O out is 25Khz
+ //The PWM frequency = 24Mhz / (16 * 6 * (9 + 1)) = 25Khz
+@@ -153,15 +157,20 @@ static void ast_pwm_taco_init(void)
+ ast_pwm_tacho_write(ast_pwm_tacho, 0x0, AST_PTCR_TACH_SOURCE);
+ ast_pwm_tacho_write(ast_pwm_tacho, 0x0, AST_PTCR_TACH_SOURCE_EXT);
+
+- //PWM A~D -> Disable , type M,
++ //PWM A~H -> Disable , type M,
+ //Tacho 0~15 Disable
+ //CLK source 24Mhz
++ val = AST_PTCR_CTRL_PWMA_EN | AST_PTCR_CTRL_PWMB_EN
++ | AST_PTCR_CTRL_PWMC_EN | AST_PTCR_CTRL_PWMD_EN
++ | AST_PTCR_CTRL_CLK_EN;
+ #ifdef MCLK
+- ast_pwm_tacho_write(ast_pwm_tacho, AST_PTCR_CTRL_CLK_MCLK | AST_PTCR_CTRL_CLK_EN, AST_PTCR_CTRL);
++ ast_pwm_tacho_write(ast_pwm_tacho, val|AST_PTCR_CTRL_CLK_MCLK, AST_PTCR_CTRL);
+ #else
+- ast_pwm_tacho_write(ast_pwm_tacho, AST_PTCR_CTRL_CLK_EN, AST_PTCR_CTRL);
++ ast_pwm_tacho_write(ast_pwm_tacho, val, AST_PTCR_CTRL);
+ #endif
+-
++ val = AST_PTCR_CTRL_PWME_EN | AST_PTCR_CTRL_PWMF_EN
++ | AST_PTCR_CTRL_PWMG_EN | AST_PTCR_CTRL_PWMH_EN;
++ ast_pwm_tacho_write(ast_pwm_tacho, val, AST_PTCR_CTRL_EXT);
+ }
+
+ /*index 0 : clk_en , 1: clk_source*/
+@@ -724,7 +733,7 @@ ast_get_tacho_rpm(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 tacho_ch)
+ else
+ clk_source = 24*1000*1000;
+
+- printk("raw_data %d, clk_source %d, tacho_clk_div %d \n",raw_data, clk_source, tacho_clk_div);
++ // printk("raw_data %d, clk_source %d, tacho_clk_div %d \n",raw_data, clk_source, tacho_clk_div);
+ rpm = (clk_source * 60) / (2 * raw_data * tacho_clk_div);
+
+ return rpm;
+@@ -923,28 +932,28 @@ ast_get_pwm_en(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch)
+
+ switch (pwm_ch) {
+ case PWMA:
+- tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PMWA_EN) >> AST_PTCR_CTRL_PMWA;
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PWMA_EN) >> AST_PTCR_CTRL_PWMA;
+ break;
+ case PWMB:
+- tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PMWB_EN) >> AST_PTCR_CTRL_PMWB;
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PWMB_EN) >> AST_PTCR_CTRL_PWMB;
+ break;
+ case PWMC:
+- tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PMWC_EN) >> AST_PTCR_CTRL_PMWC;
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PWMC_EN) >> AST_PTCR_CTRL_PWMC;
+ break;
+ case PWMD:
+- tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PMWD_EN) >> AST_PTCR_CTRL_PMWD;
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & AST_PTCR_CTRL_PWMD_EN) >> AST_PTCR_CTRL_PWMD;
+ break;
+ case PWME:
+- tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PMWE_EN) >> AST_PTCR_CTRL_PMWE;
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PWME_EN) >> AST_PTCR_CTRL_PWME;
+ break;
+ case PWMF:
+- tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PMWF_EN) >> AST_PTCR_CTRL_PMWF;
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PWMF_EN) >> AST_PTCR_CTRL_PWMF;
+ break;
+ case PWMG:
+- tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PMWG_EN) >> AST_PTCR_CTRL_PMWG;
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PWMG_EN) >> AST_PTCR_CTRL_PWMG;
+ break;
+ case PWMH:
+- tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PMWH_EN) >> AST_PTCR_CTRL_PMWH;
++ tmp = (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & AST_PTCR_CTRL_PWMH_EN) >> AST_PTCR_CTRL_PWMH;
+ break;
+ default:
+ printk("error channel ast_get_pwm_type %d \n",pwm_ch);
+@@ -962,87 +971,87 @@ ast_set_pwm_en(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch, u8 enable)
+ case PWMA:
+ if(enable)
+ ast_pwm_tacho_write(ast_pwm_tacho,
+- ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PMWA_EN,
++ ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PWMA_EN,
+ AST_PTCR_CTRL);
+ else
+ ast_pwm_tacho_write(ast_pwm_tacho,
+- ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PMWA_EN,
++ ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PWMA_EN,
+ AST_PTCR_CTRL);
+
+ break;
+ case PWMB:
+ if(enable)
+ ast_pwm_tacho_write(ast_pwm_tacho,
+- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PMWB_EN),
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PWMB_EN),
+ AST_PTCR_CTRL);
+ else
+ ast_pwm_tacho_write(ast_pwm_tacho,
+- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PMWB_EN),
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PWMB_EN),
+ AST_PTCR_CTRL);
+ break;
+ case PWMC:
+ if(enable)
+ ast_pwm_tacho_write(ast_pwm_tacho,
+- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PMWC_EN),
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PWMC_EN),
+ AST_PTCR_CTRL);
+ else
+ ast_pwm_tacho_write(ast_pwm_tacho,
+- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PMWC_EN),
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PWMC_EN),
+ AST_PTCR_CTRL);
+
+ break;
+ case PWMD:
+ if(enable)
+ ast_pwm_tacho_write(ast_pwm_tacho,
+- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PMWD_EN),
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) | AST_PTCR_CTRL_PWMD_EN),
+ AST_PTCR_CTRL);
+ else
+ ast_pwm_tacho_write(ast_pwm_tacho,
+- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PMWD_EN),
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL) & ~AST_PTCR_CTRL_PWMD_EN),
+ AST_PTCR_CTRL);
+
+ break;
+ case PWME:
+ if(enable)
+ ast_pwm_tacho_write(ast_pwm_tacho,
+- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PMWE_EN),
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PWME_EN),
+ AST_PTCR_CTRL_EXT);
+ else
+ ast_pwm_tacho_write(ast_pwm_tacho,
+- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PMWE_EN),
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PWME_EN),
+ AST_PTCR_CTRL_EXT);
+
+ break;
+ case PWMF:
+ if(enable)
+ ast_pwm_tacho_write(ast_pwm_tacho,
+- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PMWF_EN),
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PWMF_EN),
+ AST_PTCR_CTRL_EXT);
+ else
+ ast_pwm_tacho_write(ast_pwm_tacho,
+- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PMWF_EN),
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PWMF_EN),
+ AST_PTCR_CTRL_EXT);
+
+ break;
+ case PWMG:
+ if(enable)
+ ast_pwm_tacho_write(ast_pwm_tacho,
+- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PMWG_EN),
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PWMG_EN),
+ AST_PTCR_CTRL_EXT);
+ else
+ ast_pwm_tacho_write(ast_pwm_tacho,
+- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PMWG_EN),
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PWMG_EN),
+ AST_PTCR_CTRL_EXT);
+
+ break;
+ case PWMH:
+ if(enable)
+ ast_pwm_tacho_write(ast_pwm_tacho,
+- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PMWH_EN),
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) | AST_PTCR_CTRL_PWMH_EN),
+ AST_PTCR_CTRL_EXT);
+ else
+ ast_pwm_tacho_write(ast_pwm_tacho,
+- (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PMWH_EN),
++ (ast_pwm_tacho_read(ast_pwm_tacho, AST_PTCR_CTRL_EXT) & ~AST_PTCR_CTRL_PWMH_EN),
+ AST_PTCR_CTRL_EXT);
+
+ break;
+@@ -1383,6 +1392,22 @@ ast_set_pwm_duty_falling(struct ast_pwm_tacho_data *ast_pwm_tacho, u8 pwm_ch, u8
+
+ }
+
++/* NAME sysfs */
++static ssize_t
++show_name(struct device *dev, struct device_attribute *devattr,
++ char *buf)
++{
++ return sprintf(buf, "ast_pwm\n");
++}
++static SENSOR_DEVICE_ATTR_2(name, S_IRUGO, show_name, NULL, 0, 0);
++static struct attribute *name_attributes[] = {
++ &sensor_dev_attr_name.dev_attr.attr,
++ NULL
++};
++static const struct attribute_group name_attribute_groups = {
++ .attrs = name_attributes,
++};
++
+ /*PWM M/N/O Type sysfs*/
+ /*
+ * Macro defining SENSOR_DEVICE_ATTR for a pwm sysfs entries.
+@@ -1937,6 +1962,51 @@ static const struct attribute_group tacho_attribute_groups[] = {
+ { .attrs = tacho15_attributes },
+ };
+
++/* Create fan sysfs for lm-sensors, index starts from 1 */
++#define sysfs_fan_speeds_num(index) \
++static SENSOR_DEVICE_ATTR_2(fan##index##_input, S_IRUGO, \
++ ast_show_tacho_speed, NULL, 2, index - 1); \
++static struct attribute *fan##index##_attributes[] = { \
++ &sensor_dev_attr_fan##index##_input.dev_attr.attr, \
++ NULL \
++};
++
++sysfs_fan_speeds_num(1);
++sysfs_fan_speeds_num(2);
++sysfs_fan_speeds_num(3);
++sysfs_fan_speeds_num(4);
++sysfs_fan_speeds_num(5);
++sysfs_fan_speeds_num(6);
++sysfs_fan_speeds_num(7);
++sysfs_fan_speeds_num(8);
++sysfs_fan_speeds_num(9);
++sysfs_fan_speeds_num(10);
++sysfs_fan_speeds_num(11);
++sysfs_fan_speeds_num(12);
++sysfs_fan_speeds_num(13);
++sysfs_fan_speeds_num(14);
++sysfs_fan_speeds_num(15);
++sysfs_fan_speeds_num(16);
++
++static const struct attribute_group fan_attribute_groups[] = {
++ { .attrs = fan1_attributes },
++ { .attrs = fan2_attributes },
++ { .attrs = fan3_attributes },
++ { .attrs = fan4_attributes },
++ { .attrs = fan5_attributes },
++ { .attrs = fan6_attributes },
++ { .attrs = fan7_attributes },
++ { .attrs = fan8_attributes },
++ { .attrs = fan9_attributes },
++ { .attrs = fan10_attributes },
++ { .attrs = fan11_attributes },
++ { .attrs = fan12_attributes },
++ { .attrs = fan13_attributes },
++ { .attrs = fan14_attributes },
++ { .attrs = fan15_attributes },
++ { .attrs = fan16_attributes },
++};
++
+ static int
+ ast_pwm_tacho_probe(struct platform_device *pdev)
+ {
+@@ -1947,6 +2017,12 @@ ast_pwm_tacho_probe(struct platform_device *pdev)
+
+ dev_dbg(&pdev->dev, "ast_pwm_fan_probe \n");
+
++ //SCU Pin-MUX //PWM & TACHO
++ ast_scu_multi_func_pwm_tacho();
++
++ //SCU PWM CTRL Reset
++ ast_scu_init_pwm_tacho();
++
+ ast_pwm_tacho = kzalloc(sizeof(struct ast_pwm_tacho_data), GFP_KERNEL);
+ if (!ast_pwm_tacho) {
+ ret = -ENOMEM;
+@@ -1982,10 +2058,14 @@ ast_pwm_tacho_probe(struct platform_device *pdev)
+ }
+
+ /* Register sysfs hooks */
+- err = sysfs_create_group(&pdev->dev.kobj, &clk_attribute_groups);
++ err = sysfs_create_group(&pdev->dev.kobj, &name_attribute_groups);
+ if (err)
+ goto out_region;
+
++ err = sysfs_create_group(&pdev->dev.kobj, &clk_attribute_groups);
++ if (err)
++ goto out_sysfs00;
++
+ ast_pwm_tacho->hwmon_dev = hwmon_device_register(&pdev->dev);
+ if (IS_ERR(ast_pwm_tacho->hwmon_dev)) {
+ ret = PTR_ERR(ast_pwm_tacho->hwmon_dev);
+@@ -2017,12 +2097,22 @@ ast_pwm_tacho_probe(struct platform_device *pdev)
+ goto out_sysfs3;
+ }
+
++ for(i=0; i< TACHO_NUM; i++) {
++ err = sysfs_create_group(&pdev->dev.kobj, &fan_attribute_groups[i]);
++ if (err)
++ goto out_sysfs4;
++ }
++
+ ast_pwm_taco_init();
+
+ printk(KERN_INFO "ast_pwm_tacho: driver successfully loaded.\n");
+
+ return 0;
+
++out_sysfs4:
++ for(i=0; i< PWM_TYPE_NUM; i++)
++ sysfs_remove_group(&pdev->dev.kobj, &tacho_type_attribute_groups[i]);
++
+ out_sysfs3:
+ for(i=0; i< TACHO_NUM; i++)
+ sysfs_remove_group(&pdev->dev.kobj, &tacho_attribute_groups[i]);
+@@ -2036,6 +2126,8 @@ out_sysfs1:
+ sysfs_remove_group(&pdev->dev.kobj, &pwm_attribute_groups[i]);
+ out_sysfs0:
+ sysfs_remove_group(&pdev->dev.kobj, &clk_attribute_groups);
++out_sysfs00:
++ sysfs_remove_group(&pdev->dev.kobj, &name_attribute_groups);
+
+ //out_irq:
+ // free_irq(ast_pwm_tacho->irq, NULL);
+@@ -2058,9 +2150,10 @@ ast_pwm_tacho_remove(struct platform_device *pdev)
+
+ hwmon_device_unregister(ast_pwm_tacho->hwmon_dev);
+
+- for(i=0; i<16; i++)
++ for(i=0; i<16; i++) {
+ sysfs_remove_group(&pdev->dev.kobj, &tacho_attribute_groups[i]);
+-
++ sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[i]);
++ }
+ for(i=0; i<3; i++)
+ sysfs_remove_group(&pdev->dev.kobj, &pwm_type_attribute_groups[i]);
+
+@@ -2069,6 +2162,8 @@ ast_pwm_tacho_remove(struct platform_device *pdev)
+
+ sysfs_remove_group(&pdev->dev.kobj, &clk_attribute_groups);
+
++ sysfs_remove_group(&pdev->dev.kobj, &name_attribute_groups);
++
+ platform_set_drvdata(pdev, NULL);
+ // free_irq(ast_pwm_tacho->irq, ast_pwm_tacho);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+diff --git a/drivers/hwmon/fb_panther_plus.c b/drivers/hwmon/fb_panther_plus.c
+new file mode 100644
+index 0000000..1dde2ec
+--- /dev/null
++++ b/drivers/hwmon/fb_panther_plus.c
+@@ -0,0 +1,722 @@
++/*
++ * fb_panther_plus.c - Driver for Panther+ microserver
++ *
++ * Copyright 2014-present Facebook. All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++//#define DEBUG
++
++#include <linux/delay.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/jiffies.h>
++#include <linux/i2c.h>
++#include <linux/hwmon.h>
++#include <linux/hwmon-sysfs.h>
++#include <linux/err.h>
++#include <linux/mutex.h>
++#include <linux/sysfs.h>
++
++#ifdef DEBUG
++
++#define PP_DEBUG(fmt, ...) do { \
++ printk(KERN_DEBUG "%s:%d " fmt "\n", \
++ __FUNCTION__, __LINE__, ##__VA_ARGS__); \
++} while (0)
++
++#else /* !DEBUG */
++
++#define PP_DEBUG(fmt, ...)
++
++#endif
++
++static const unsigned short normal_i2c[] = {
++ 0x40, I2C_CLIENT_END
++};
++
++/*
++ * Insmod parameters
++ */
++
++I2C_CLIENT_INSMOD_1(panther_plus);
++
++/*
++ * Driver data (common to all clients)
++ */
++
++static const struct i2c_device_id panther_plus_id[] = {
++ { "fb_panther_plus", panther_plus },
++ { },
++};
++MODULE_DEVICE_TABLE(i2c, panther_plus_id);
++
++struct panther_plus_data {
++ struct device *hwmon_dev;
++ struct mutex update_lock;
++};
++
++// Identifies the sysfs attribute panther_plus_show is requesting.
++enum {
++ PANTHER_PLUS_SYSFS_CPU_TEMP,
++ PANTHER_PLUS_SYSFS_DIMM_TEMP,
++ PANTHER_PLUS_SYSFS_GPIO_INPUTS,
++ PANTHER_PLUS_SYSFS_SMS_KCS,
++ PANTHER_PLUS_SYSFS_ALERT_CONTROL,
++ PANTHER_PLUS_SYSFS_ALERT_STATUS,
++ PANTHER_PLUS_SYSFS_DISCOVERY_SPEC_VER,
++ PANTHER_PLUS_SYSFS_DISCOVERY_HW_VER,
++ PANTHER_PLUS_SYSFS_DISCOVERY_MANUFACTURER_ID,
++ PANTHER_PLUS_SYSFS_DISCOVERY_DEVICE_ID,
++ PANTHER_PLUS_SYSFS_DISCOVERY_PRODUCT_ID,
++};
++
++// Function Block ID identifiers.
++enum panther_plus_fbid_en {
++ PANTHER_PLUS_FBID_IPMI_SMS_KCS = 0x0,
++ PANTHER_PLUS_FBID_GPIO_INPUTS = 0xd,
++ PANTHER_PLUS_FBID_READ_REGISTER = 0x10,
++ PANTHER_PLUS_FBID_ALERT_CONTROL = 0xFD,
++ PANTHER_PLUS_FBID_ALERT_STATUS = 0xFE,
++ PANTHER_PLUS_FBID_DISCOVERY = 0xFF,
++};
++
++static inline void panther_plus_make_read(struct i2c_msg *msg,
++ u8 addr,
++ u8 *buf,
++ int len)
++{
++ msg->addr = addr;
++ msg->flags = I2C_M_RD;
++ msg->buf = buf;
++ msg->len = len;
++}
++
++static inline void panther_plus_make_write(struct i2c_msg *msg,
++ u8 addr,
++ u8 *buf,
++ int len)
++{
++ msg->addr = addr;
++ msg->flags = 0;
++ msg->buf = buf;
++ msg->len = len;
++}
++
++static int panther_plus_fbid_io(struct i2c_client *client,
++ enum panther_plus_fbid_en fbid,
++ const u8 *write_buf, u8 write_len,
++ u8 *read_buf, u8 read_len)
++{
++ // The Intel uServer Module Management Interface Spec defines SMBus blocks,
++ // but block sizes exceed the SMBus maximum block sizes
++ // (32, see I2C_SMBUS_BLOCK_MAX). So we basically have to re-implement the
++ // smbus functions with a larger max.
++ struct i2c_msg msg[2];
++ u8 buf[255];
++ u8 buf_len;
++ int rc;
++ u8 num_msgs = 1;
++
++ if (write_len + 1 > sizeof(buf)) {
++ return -EINVAL;
++ }
++
++ /* first, write the FBID, followed by the write_buf if there is one */
++ buf[0] = fbid;
++ buf_len = 1;
++ if (write_buf) {
++ memcpy(&buf[1], write_buf, write_len);
++ buf_len += write_len;
++ }
++ panther_plus_make_write(&msg[0], client->addr, buf, buf_len);
++
++ /* then, read */
++ if (read_buf) {
++ panther_plus_make_read(&msg[1], client->addr, read_buf, read_len);
++ num_msgs = 2;
++ }
++
++ rc = i2c_transfer(client->adapter, msg, num_msgs);
++ if (rc < 0) {
++ PP_DEBUG("Failed to read FBID: %d, error=%d", fbid, rc);
++ return rc;
++ }
++
++ if (rc != num_msgs) { /* expect 2 */
++ PP_DEBUG("Unexpected rc (%d != %d) when reading FBID: %d", rc, num_msgs, fbid);
++ return -EIO;
++ }
++
++ /* the first byte read should match fbid */
++
++ if (read_buf && read_buf[0] != fbid) {
++ PP_DEBUG("Unexpected FBID returned (%d != %d)", read_buf[0], fbid);
++ return -EIO;
++ }
++
++ return 0;
++}
++
++#define PP_GPIO_POWER_ON 0x1
++#define PP_GPIO_PWRGD_P1V35 (0x1 << 1)
++#define PP_GPIO_RST_EAGE_N (0x1 << 2)
++#define PP_GPIO_FM_BIOS_POST_CMPLT_N (0x1 << 3)
++#define PP_GPIO_IERR_FPGA (0x1 << 4)
++#define PP_GPIO_AVN_PLD_PROCHOT_N (0x1 << 5)
++#define PP_GPIO_BUS1_ERROR (0x1 << 6)
++#define PP_GPIO_AVN_PLD_THERMTRIP_N (0x1 << 7)
++#define PP_GPIO_MCERR_FPGA (0x1 << 8)
++#define PP_GPIO_ERROR_AVN_2 (0x1 << 9)
++#define PP_GPIO_ERROR_AVN_1 (0x1 << 10)
++#define PP_GPIO_ERROR_AVN_0 (0x1 << 11)
++#define PP_GPIO_H_MEMHOT_CO_N (0x1 << 12)
++#define PP_GPIO_SLP_S45_N (0x1 << 13)
++#define PP_GPIO_PLTRST_FPGA_N (0x1 << 14)
++#define PP_GPIO_FPGA_GPI_PWD_FAIL (0x1 << 15)
++#define PP_GPIO_FPGA_GPI_NMI (0x1 << 16)
++#define PP_GPIO_GPI_VCCP_VRHOT_N (0x1 << 17)
++#define PP_GPIO_FPGA_GPI_TMP75_ALERT (0x1 << 18)
++#define PP_GPIO_LPC_CLKRUN_N (0x1 << 19)
++
++static int panther_plus_read_gpio_inputs_value(
++ struct i2c_client *client, u32 *val)
++{
++ int rc;
++ u8 read_buf[5];
++
++ rc = panther_plus_fbid_io(client, PANTHER_PLUS_FBID_GPIO_INPUTS,
++ NULL, 0, read_buf, sizeof(read_buf));
++ if (rc < 0) {
++ return rc;
++ }
++
++ /*
++ * expect receiving 5 bytes as:
++ * 0xd 0x3 <gpio0-7> <gpio8-15> <gpio9-23>
++ */
++ if (read_buf[1] != 0x3) {
++ PP_DEBUG("Unexpected length %d != 3", read_buf[1]);
++ return -EIO;
++ }
++
++ *val = read_buf[2] | (read_buf[3] << 8) | (read_buf[4] << 16);
++
++ return 0;
++}
++
++static int panther_plus_is_in_post(struct i2c_client *client)
++{
++ u32 val;
++ int rc;
++
++ rc = panther_plus_read_gpio_inputs_value(client, &val);
++ if (rc < 0) {
++ /* failed to read gpio, treat it as in post */
++ return 1;
++ }
++
++ /* if PP_GPIO_FM_BIOS_POST_CMPLT_N is set, post is _not_ done yet */
++ return (val & PP_GPIO_FM_BIOS_POST_CMPLT_N);
++}
++
++static int panther_plus_read_register(struct i2c_client *client,
++ u8 reg_idx, u32 *reg_val)
++{
++ u8 write_buf[2];
++ u8 read_buf[8];
++ int rc;
++
++ /* need to send the register index for the reading */
++ write_buf[0] = 0x1; /* one byte */
++ write_buf[1] = reg_idx;
++
++ rc = panther_plus_fbid_io(client, PANTHER_PLUS_FBID_READ_REGISTER,
++ write_buf, sizeof(write_buf),
++ read_buf, sizeof(read_buf));
++ if (rc < 0) {
++ return -EIO;
++ }
++
++ /*
++ * expect receiving 8 bytes as:
++ * 0x10 0x6 <reg_idx> LSB LSB+1 LSB+2 LSB+3 valid
++ */
++ if (read_buf[1] != 0x6
++ || read_buf[2] != reg_idx
++ || read_buf[7] != 0) {
++ return -EIO;
++ }
++
++ *reg_val = read_buf[3] | (read_buf[4] << 8)
++ | (read_buf[5] << 16) | (read_buf[6] << 24);
++
++ PP_DEBUG("Read register %d: 0x%x", reg_idx, *reg_val);
++
++ return 0;
++}
++
++#define PANTHER_PLUS_REG_SOC_TJMAX 0
++#define PANTHER_PLUS_REG_SOC_RUNTIME 1
++#define PANTHER_PLUS_REG_SOC_THERMAL_MARGIN 2
++#define PANTHER_PLUS_REG_SOC_DIMM0_A_TEMP 3
++#define PANTHER_PLUS_REG_SOC_DIMM0_B_TEMP 4
++#define PANTHER_PLUS_REG_SOC_POWER_UNIT 5
++#define PANTHER_PLUS_REG_SOC_POWER_CONSUMPTION 6
++#define PANTHER_PLUS_REG_SOC_POWER_CALC 7
++#define PANTHER_PLUS_REG_SOC_DIMM1_A_TEMP 8
++#define PANTHER_PLUS_REG_SOC_DIMM1_B_TEMP 9
++
++static int panther_plus_read_cpu_temp(struct i2c_client *client, char *ret)
++{
++ int rc;
++ u32 tjmax;
++ u32 tmargin;
++ int val;
++ int temp;
++
++ /*
++ * make sure POST is done, accessing CPU temperature during POST phase could
++ * confusing POST and make it hang
++ */
++ if (panther_plus_is_in_post(client)) {
++ return -EBUSY;
++ }
++
++ mdelay(10);
++
++ /* first read Tjmax: register 0, bit[16-23] */
++ rc = panther_plus_read_register(client, PANTHER_PLUS_REG_SOC_TJMAX, &tjmax);
++ if (rc < 0) {
++ return rc;
++ }
++
++ mdelay(10);
++
++ /* then, read the thermal margin */
++ rc = panther_plus_read_register(client, PANTHER_PLUS_REG_SOC_THERMAL_MARGIN,
++ &tmargin);
++ if (rc < 0) {
++ return rc;
++ }
++ /*
++ * thermal margin is 16b 2's complement value representing a number of 1/64
++ * degress centigrade.
++ */
++ tmargin &= 0xFFFF;
++ if ((tmargin & 0x8000)) {
++ /* signed */
++ val = -((tmargin - 1) ^ 0xFFFF);
++ } else {
++ val = tmargin;
++ }
++
++ /*
++ * now val holds the margin (a number of 1/64), add it to the Tjmax.
++ * Times 1000 for lm-sensors.
++ */
++ temp = ((tjmax >> 16) & 0xFF) * 1000 + val * 1000 / 64;
++
++ return sprintf(ret, "%d\n", temp);
++}
++
++static int panther_plus_read_dimm_temp(struct i2c_client *client,
++ int dimm, char *ret)
++{
++ int rc;
++ u32 val;
++ int temp;
++
++ /*
++ * make sure POST is done, accessing DIMM temperature will fail anyway if
++ * POST is not done.
++ */
++ if (panther_plus_is_in_post(client)) {
++ return -EBUSY;
++ }
++
++ mdelay(10);
++
++ rc = panther_plus_read_register(client, dimm, &val);
++ if (rc < 0) {
++ return rc;
++ }
++
++ /*
++ * DIMM temperature is encoded in 16b as the following:
++ * b15-b12: TCRIT HIGH LOW SIGN
++ * b11-b08: 128 64 32 16
++ * b07-b04: 8 4 2 1
++ * b03-b00: 0.5 0.25 0.125 0.0625
++ */
++ /* For now, only care about those 12 data bits and SIGN */
++ val &= 0x1FFF;
++ if ((val & 0x1000)) {
++ /* signed */
++ val = -((val - 1) ^ 0x1FFF);
++ }
++
++ /*
++ * now val holds the value as a number of 1/16, times 1000 for lm-sensors */
++ temp = val * 1000 / 16;
++
++ return sprintf(ret, "%d\n", temp);
++}
++
++static int panther_plus_read_gpio_inputs(struct i2c_client *client, char *ret)
++{
++ u32 val;
++ int rc;
++
++ rc = panther_plus_read_gpio_inputs_value(client, &val);
++ if (rc < 0) {
++ return rc;
++ }
++ return sprintf(ret, "0x%x\n", val);
++}
++
++static int panther_plus_read_sms_kcs(struct i2c_client *client, char *ret)
++{
++ int rc;
++ u8 read_buf[255] = {0x0};
++
++ rc = panther_plus_fbid_io(client, PANTHER_PLUS_FBID_IPMI_SMS_KCS,
++ NULL, 0, read_buf, sizeof(read_buf));
++ if (rc < 0) {
++ return rc;
++ }
++
++ memcpy(ret, read_buf, read_buf[1]+2);
++
++ return (read_buf[1]+2);
++}
++
++static int panther_plus_write_sms_kcs(struct i2c_client *client, const char *buf, u8 count)
++{
++ int rc;
++
++ rc = panther_plus_fbid_io(client, PANTHER_PLUS_FBID_IPMI_SMS_KCS,
++ buf, count, NULL, 0);
++ if (rc < 0) {
++ return rc;
++ }
++
++ return count;
++}
++
++static int panther_plus_read_alert_status(struct i2c_client *client, char *ret)
++{
++ int rc;
++ u8 rbuf[5] = {0};
++
++ rc = panther_plus_fbid_io(client, PANTHER_PLUS_FBID_ALERT_STATUS,
++ NULL, 0, rbuf, sizeof(rbuf));
++ if (rc < 0) {
++ return rc;
++ }
++
++ memcpy(ret, rbuf, rbuf[1]+2);
++
++ return (rbuf[1]+2);
++}
++
++static int panther_plus_read_alert_control(struct i2c_client *client, char *ret)
++{
++ int rc;
++ u8 rbuf[5] = {0};
++
++ rc = panther_plus_fbid_io(client, PANTHER_PLUS_FBID_ALERT_CONTROL,
++ NULL, 0, rbuf, sizeof(rbuf));
++ if (rc < 0) {
++ return rc;
++ }
++
++ memcpy(ret, rbuf, rbuf[1]+2);
++
++ return (rbuf[1]+2);
++}
++
++static int panther_plus_read_discovery(struct i2c_client *client, char *ret,
++ int which_attribute)
++{
++ int rc;
++ u8 datalen;
++#define DISCOVERY_DATA_SIZE 10
++ u8 rbuf[DISCOVERY_DATA_SIZE+2] = {0};
++ rc = panther_plus_fbid_io(client, PANTHER_PLUS_FBID_DISCOVERY,
++ NULL, 0, rbuf, sizeof(rbuf));
++ if (rc < 0) {
++ return rc;
++ }
++ datalen = rbuf[1];
++ if (datalen < DISCOVERY_DATA_SIZE) {
++ return -EINVAL;
++ }
++ switch (which_attribute) {
++ case PANTHER_PLUS_SYSFS_DISCOVERY_SPEC_VER:
++ return scnprintf(ret, PAGE_SIZE, "%u.%u\n", rbuf[2], rbuf[3]);
++ case PANTHER_PLUS_SYSFS_DISCOVERY_HW_VER:
++ return scnprintf(ret, PAGE_SIZE, "%u.%u\n", rbuf[4], rbuf[5]);
++ case PANTHER_PLUS_SYSFS_DISCOVERY_MANUFACTURER_ID:
++ return scnprintf(ret, PAGE_SIZE, "0x%02X%02X%02X\n", rbuf[8], rbuf[7],
++ rbuf[6]);
++ case PANTHER_PLUS_SYSFS_DISCOVERY_DEVICE_ID:
++ return scnprintf(ret, PAGE_SIZE, "0x%02X\n", rbuf[9]);
++ case PANTHER_PLUS_SYSFS_DISCOVERY_PRODUCT_ID:
++ return scnprintf(ret, PAGE_SIZE, "0x%02X%02X\n", rbuf[11], rbuf[10]);
++ default:
++ return -EINVAL;
++ }
++ return -EINVAL;
++}
++
++static int panther_plus_write_alert_control(struct i2c_client *client, const char *buf, u8 count)
++{
++ int rc;
++
++ rc = panther_plus_fbid_io(client, PANTHER_PLUS_FBID_ALERT_CONTROL,
++ buf, count, NULL, 0);
++ if (rc < 0) {
++ return rc;
++ }
++
++ return count;
++}
++
++static ssize_t panther_plus_show(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct panther_plus_data *data = i2c_get_clientdata(client);
++ struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
++ int which = sensor_attr->index;
++ int rc = -EIO;
++
++ mutex_lock(&data->update_lock);
++ switch (which) {
++ case PANTHER_PLUS_SYSFS_CPU_TEMP:
++ rc = panther_plus_read_cpu_temp(client, buf);
++ break;
++ case PANTHER_PLUS_SYSFS_DIMM_TEMP:
++ rc = panther_plus_read_dimm_temp(client, sensor_attr->nr, buf);
++ break;
++ case PANTHER_PLUS_SYSFS_GPIO_INPUTS:
++ rc = panther_plus_read_gpio_inputs(client, buf);
++ break;
++ case PANTHER_PLUS_SYSFS_SMS_KCS:
++ rc = panther_plus_read_sms_kcs(client, buf);
++ break;
++ case PANTHER_PLUS_SYSFS_ALERT_STATUS:
++ rc = panther_plus_read_alert_status(client, buf);
++ break;
++ case PANTHER_PLUS_SYSFS_ALERT_CONTROL:
++ rc = panther_plus_read_alert_control(client, buf);
++ break;
++ case PANTHER_PLUS_SYSFS_DISCOVERY_SPEC_VER:
++ case PANTHER_PLUS_SYSFS_DISCOVERY_HW_VER:
++ case PANTHER_PLUS_SYSFS_DISCOVERY_MANUFACTURER_ID:
++ case PANTHER_PLUS_SYSFS_DISCOVERY_DEVICE_ID:
++ case PANTHER_PLUS_SYSFS_DISCOVERY_PRODUCT_ID:
++ rc = panther_plus_read_discovery(client, buf, which);
++ default:
++ break;
++ }
++
++ /*
++ * With the current i2c driver, the bus/kernel could hang if accessing the
++ * FPGA too fast. Adding some delay here until we fix the i2c driver bug
++ */
++ mdelay(10);
++
++ mutex_unlock(&data->update_lock);
++
++ return rc;
++}
++
++static ssize_t panther_plus_set(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct panther_plus_data *data = i2c_get_clientdata(client);
++ struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
++ int which = sensor_attr->index;
++
++ int rc = -EIO;
++ mutex_lock(&data->update_lock);
++ switch (which) {
++ case PANTHER_PLUS_SYSFS_SMS_KCS:
++ rc = panther_plus_write_sms_kcs(client, buf, count);
++ break;
++ case PANTHER_PLUS_SYSFS_ALERT_CONTROL:
++ rc = panther_plus_write_alert_control(client, buf, count);
++ break;
++ default:
++ break;
++ }
++
++ mdelay(10);
++
++ mutex_unlock(&data->update_lock);
++
++ return rc;
++}
++
++static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, panther_plus_show, NULL,
++ 0, PANTHER_PLUS_SYSFS_CPU_TEMP);
++static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, panther_plus_show, NULL,
++ PANTHER_PLUS_REG_SOC_DIMM0_A_TEMP,
++ PANTHER_PLUS_SYSFS_DIMM_TEMP);
++static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, panther_plus_show, NULL,
++ PANTHER_PLUS_REG_SOC_DIMM0_B_TEMP,
++ PANTHER_PLUS_SYSFS_DIMM_TEMP);
++static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, panther_plus_show, NULL,
++ PANTHER_PLUS_REG_SOC_DIMM1_A_TEMP,
++ PANTHER_PLUS_SYSFS_DIMM_TEMP);
++static SENSOR_DEVICE_ATTR_2(temp5_input, S_IRUGO, panther_plus_show, NULL,
++ PANTHER_PLUS_REG_SOC_DIMM1_B_TEMP,
++ PANTHER_PLUS_SYSFS_DIMM_TEMP);
++static SENSOR_DEVICE_ATTR_2(gpio_inputs, S_IRUGO, panther_plus_show, NULL,
++ 0, PANTHER_PLUS_SYSFS_GPIO_INPUTS);
++static SENSOR_DEVICE_ATTR_2(sms_kcs, S_IWUSR | S_IRUGO, panther_plus_show, panther_plus_set,
++ 0, PANTHER_PLUS_SYSFS_SMS_KCS);
++static SENSOR_DEVICE_ATTR_2(alert_status, S_IRUGO, panther_plus_show, NULL,
++ 0, PANTHER_PLUS_SYSFS_ALERT_STATUS);
++static SENSOR_DEVICE_ATTR_2(alert_control, S_IWUSR | S_IRUGO, panther_plus_show, panther_plus_set,
++ 0, PANTHER_PLUS_SYSFS_ALERT_CONTROL);
++static SENSOR_DEVICE_ATTR_2(spec_ver, S_IRUGO, panther_plus_show, NULL,
++ 0, PANTHER_PLUS_SYSFS_DISCOVERY_SPEC_VER);
++static SENSOR_DEVICE_ATTR_2(hw_ver, S_IRUGO, panther_plus_show, NULL,
++ 0, PANTHER_PLUS_SYSFS_DISCOVERY_HW_VER);
++static SENSOR_DEVICE_ATTR_2(manufacturer_id, S_IRUGO, panther_plus_show, NULL,
++ 0, PANTHER_PLUS_SYSFS_DISCOVERY_MANUFACTURER_ID);
++static SENSOR_DEVICE_ATTR_2(device_id, S_IRUGO, panther_plus_show, NULL,
++ 0, PANTHER_PLUS_SYSFS_DISCOVERY_DEVICE_ID);
++static SENSOR_DEVICE_ATTR_2(product_id, S_IRUGO, panther_plus_show, NULL,
++ 0, PANTHER_PLUS_SYSFS_DISCOVERY_PRODUCT_ID);
++
++static struct attribute *panther_plus_attributes[] = {
++ &sensor_dev_attr_temp1_input.dev_attr.attr,
++ &sensor_dev_attr_temp2_input.dev_attr.attr,
++ &sensor_dev_attr_temp3_input.dev_attr.attr,
++ &sensor_dev_attr_temp4_input.dev_attr.attr,
++ &sensor_dev_attr_temp5_input.dev_attr.attr,
++ &sensor_dev_attr_gpio_inputs.dev_attr.attr,
++ &sensor_dev_attr_sms_kcs.dev_attr.attr,
++ &sensor_dev_attr_alert_status.dev_attr.attr,
++ &sensor_dev_attr_alert_control.dev_attr.attr,
++ &sensor_dev_attr_spec_ver.dev_attr.attr,
++ &sensor_dev_attr_hw_ver.dev_attr.attr,
++ &sensor_dev_attr_manufacturer_id.dev_attr.attr,
++ &sensor_dev_attr_device_id.dev_attr.attr,
++ &sensor_dev_attr_product_id.dev_attr.attr,
++ NULL
++};
++
++static const struct attribute_group panther_plus_group = {
++ .attrs = panther_plus_attributes,
++};
++
++/* Return 0 if detection is successful, -ENODEV otherwise */
++static int panther_plus_detect(struct i2c_client *client, int kind,
++ struct i2c_board_info *info)
++{
++ /*
++ * We don't currently do any detection of the Panther+, although
++ * presumably we could try to query FBID 0xFF for HW ID.
++ */
++ strlcpy(info->type, "panther_plus", I2C_NAME_SIZE);
++ return 0;
++}
++
++static int panther_plus_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ struct panther_plus_data *data;
++ int err;
++
++ data = kzalloc(sizeof(struct panther_plus_data), GFP_KERNEL);
++ if (!data) {
++ err = -ENOMEM;
++ goto exit;
++ }
++
++ i2c_set_clientdata(client, data);
++ mutex_init(&data->update_lock);
++
++ /* Register sysfs hooks */
++ if ((err = sysfs_create_group(&client->dev.kobj, &panther_plus_group)))
++ goto exit_free;
++
++ data->hwmon_dev = hwmon_device_register(&client->dev);
++ if (IS_ERR(data->hwmon_dev)) {
++ err = PTR_ERR(data->hwmon_dev);
++ goto exit_remove_files;
++ }
++
++ printk(KERN_INFO "Panther+ driver successfully loaded.\n");
++
++ return 0;
++
++ exit_remove_files:
++ sysfs_remove_group(&client->dev.kobj, &panther_plus_group);
++ exit_free:
++ kfree(data);
++ exit:
++ return err;
++}
++
++static int panther_plus_remove(struct i2c_client *client)
++{
++ struct panther_plus_data *data = i2c_get_clientdata(client);
++
++ hwmon_device_unregister(data->hwmon_dev);
++ sysfs_remove_group(&client->dev.kobj, &panther_plus_group);
++
++ kfree(data);
++ return 0;
++}
++
++static struct i2c_driver panther_plus_driver = {
++ .class = I2C_CLASS_HWMON,
++ .driver = {
++ .name = "panther_plus",
++ },
++ .probe = panther_plus_probe,
++ .remove = panther_plus_remove,
++ .id_table = panther_plus_id,
++ .detect = panther_plus_detect,
++ .address_data = &addr_data,
++};
++
++static int __init sensors_panther_plus_init(void)
++{
++ return i2c_add_driver(&panther_plus_driver);
++}
++
++static void __exit sensors_panther_plus_exit(void)
++{
++ i2c_del_driver(&panther_plus_driver);
++}
++
++MODULE_AUTHOR("Tian Fang <tfang@fb.com>");
++MODULE_DESCRIPTION("Panther+ Driver");
++MODULE_LICENSE("GPL");
++
++module_init(sensors_panther_plus_init);
++module_exit(sensors_panther_plus_exit);
+diff --git a/drivers/hwmon/max127.c b/drivers/hwmon/max127.c
+new file mode 100644
+index 0000000..a223f94
+--- /dev/null
++++ b/drivers/hwmon/max127.c
+@@ -0,0 +1,312 @@
++/*
++ * max127.c - Part of lm_sensors, Linux kernel modules for hardware
++ * monitoring
++ * Copyright 2004-present Facebook. All Rights Reserved.
++ * Copyright (C) 2003-2004 Alexey Fisher <fishor@mail.ru>
++ * Jean Delvare <khali@linux-fr.org>
++ *
++ * Based on the max1619 driver, which was based on the lm90 driver.
++ * The MAX127 is a voltage sensor chip made by Maxim. It reports
++ * up to eight voltages, with a choice of maximums * of 5V or 10V.
++ * In addition, it can read either only positive voltages,
++ * or negative voltages as well, for a maximum range of -10V to +10V.
++ *
++ * Complete datasheet can be obtained from Maxim's website at:
++ * http://datasheets.maximintegrated.com/en/ds/MAX127-MAX128B.pdf
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/jiffies.h>
++#include <linux/i2c.h>
++#include <linux/hwmon.h>
++#include <linux/hwmon-sysfs.h>
++#include <linux/err.h>
++#include <linux/mutex.h>
++#include <linux/sysfs.h>
++
++static const unsigned short normal_i2c[] = {
++ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
++
++/*
++ * Insmod parameters
++ */
++
++I2C_CLIENT_INSMOD_1(max127);
++
++static int scaling;
++module_param(scaling, int, 0);
++MODULE_PARM_DESC(scaling, "Fixed-point scaling factor (* 10000), ie 24414");
++
++
++/*
++ * The MAX127 I2C messages
++ */
++
++/* We send a single query byte to the device, setting the following bits: */
++
++#define MAX127_REG_R_START 0x80 /* Top bit must be set */
++#define MAX127_REG_R_SEL_MASK 0x70 /* Which of 8 inputs to get */
++#define MAX127_REG_R_SEL_SHIFT 4
++#define MAX127_REG_R_RNG 0x08 /* 10v (otherwise 5v) */
++#define MAX127_REG_R_BIP 0x04 /* show negative voltage */
++#define MAX127_REG_R_PD1 0x02 /* power saving controls */
++#define MAX127_REG_R_PD0 0x01
++
++/* Must shift return value to get a 12-bit value */
++#define MAX127_RESULT_SHIFT 4
++
++#define MAX127_CHANNELS 8
++
++/*
++ * Functions declaration
++ */
++
++static int max127_probe(struct i2c_client *client,
++ const struct i2c_device_id *id);
++static int max127_detect(struct i2c_client *client, int kind,
++ struct i2c_board_info *info);
++static int max127_remove(struct i2c_client *client);
++static void max127_update_device(struct device *dev, int which);
++
++/*
++ * Driver data (common to all clients)
++ */
++
++static const struct i2c_device_id max127_id[] = {
++ { "max127", max127 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, max127_id);
++
++static struct i2c_driver max127_driver = {
++ .class = I2C_CLASS_HWMON,
++ .driver = {
++ .name = "max127",
++ },
++ .probe = max127_probe,
++ .remove = max127_remove,
++ .id_table = max127_id,
++ .detect = max127_detect,
++ .address_data = &addr_data,
++};
++
++/*
++ * Client data (each client gets its own)
++ */
++
++struct max127_data {
++ struct device *hwmon_dev;
++ struct mutex update_lock;
++ u16 valid; /* zero until following fields are valid */
++
++ u16 voltage;
++};
++
++/*
++ * Sysfs stuff
++ */
++
++static ssize_t show_in(struct device *dev, struct device_attribute *attr,
++ char *buf)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct max127_data *data = i2c_get_clientdata(client);
++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
++ int which = sensor_attr->index;
++ int valid;
++ unsigned voltage;
++
++ mutex_lock(&data->update_lock);
++ max127_update_device(dev, which);
++ valid = data->valid;
++ voltage = data->voltage;
++ mutex_unlock(&data->update_lock);
++
++ if (scaling)
++ voltage = voltage * scaling / 10000;
++
++ if (!valid)
++ return -EIO;
++ return sprintf(buf, "%u\n", voltage);
++}
++
++
++static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_in, NULL, 0);
++static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in, NULL, 1);
++static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_in, NULL, 2);
++static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_in, NULL, 3);
++static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_in, NULL, 4);
++static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_in, NULL, 5);
++static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_in, NULL, 6);
++static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_in, NULL, 7);
++
++static struct attribute *max127_attributes[] = {
++ &sensor_dev_attr_in0_input.dev_attr.attr,
++ &sensor_dev_attr_in1_input.dev_attr.attr,
++ &sensor_dev_attr_in2_input.dev_attr.attr,
++ &sensor_dev_attr_in3_input.dev_attr.attr,
++ &sensor_dev_attr_in4_input.dev_attr.attr,
++ &sensor_dev_attr_in5_input.dev_attr.attr,
++ &sensor_dev_attr_in6_input.dev_attr.attr,
++ &sensor_dev_attr_in7_input.dev_attr.attr,
++ NULL
++};
++
++static const struct attribute_group max127_group = {
++ .attrs = max127_attributes,
++};
++
++/*
++ * Real code
++ */
++
++/* Return 0 if detection is successful, -ENODEV otherwise */
++static int max127_detect(struct i2c_client *new_client, int kind,
++ struct i2c_board_info *info)
++{
++ struct i2c_adapter *adapter = new_client->adapter;
++
++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
++ I2C_FUNC_SMBUS_WORD_DATA))
++ return -EIO;
++
++ /*
++ * We don't currently do any detection of the MAX127, although
++ * presumably we could try setting and unsetting the top
++ * bit in a query to see whether it does conversions or fails.
++ */
++
++ strlcpy(info->type, "max127", I2C_NAME_SIZE);
++
++ return 0;
++}
++
++static int max127_probe(struct i2c_client *new_client,
++ const struct i2c_device_id *id)
++{
++ struct max127_data *data;
++ int err;
++
++ data = kzalloc(sizeof(struct max127_data), GFP_KERNEL);
++ if (!data) {
++ err = -ENOMEM;
++ goto exit;
++ }
++
++ i2c_set_clientdata(new_client, data);
++ data->valid = 0;
++ mutex_init(&data->update_lock);
++
++ /* Register sysfs hooks */
++ if ((err = sysfs_create_group(&new_client->dev.kobj, &max127_group)))
++ goto exit_free;
++
++ data->hwmon_dev = hwmon_device_register(&new_client->dev);
++ if (IS_ERR(data->hwmon_dev)) {
++ err = PTR_ERR(data->hwmon_dev);
++ goto exit_remove_files;
++ }
++
++ return 0;
++
++exit_remove_files:
++ sysfs_remove_group(&new_client->dev.kobj, &max127_group);
++exit_free:
++ kfree(data);
++exit:
++ return err;
++}
++
++static int max127_remove(struct i2c_client *client)
++{
++ struct max127_data *data = i2c_get_clientdata(client);
++
++ hwmon_device_unregister(data->hwmon_dev);
++ sysfs_remove_group(&client->dev.kobj, &max127_group);
++
++ kfree(data);
++ return 0;
++}
++
++static void max127_update_device(struct device *dev, int which)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct max127_data *data = i2c_get_clientdata(client);
++ struct i2c_msg msg;
++ int status;
++ u8 buf[2];
++
++ /*
++ * The MAX127 doesn't use standard SMBus queries; it needs a
++ * write to specify what conversion to make, followed by an i2c
++ * STOP. It can then be read for the two-byte voltage value.
++ * Perhaps the idea is that a query can be started, then
++ * checked at an arbitrarily later time. We don't support
++ * that -- we just get a result immediately.
++ *
++ * We have to use i2c_transfer to do the second read without
++ * writing to any registers, rather than using the i2c_smbus_xxxxxx
++ * queries that most of the other hwmon drivers do.
++ */
++
++ dev_dbg(&client->dev, "Updating max127 data for probe %d.\n", which);
++ data->valid = 0;
++
++ buf[0] = MAX127_REG_R_START | (which << MAX127_REG_R_SEL_SHIFT) |
++ MAX127_REG_R_RNG;
++ msg.addr = client->addr;
++ msg.flags = 0;
++ msg.buf = buf;
++ msg.len = 1;
++ status = i2c_transfer(client->adapter, &msg, 1);
++
++ if (status != 1) {
++ return;
++ }
++
++ msg.addr = client->addr;
++ msg.flags = I2C_M_RD;
++ msg.buf = buf;
++ msg.len = 2;
++ status = i2c_transfer(client->adapter, &msg, 1);
++
++ data->voltage = (buf[0] << 8) | buf[1];
++ data->voltage >>= MAX127_RESULT_SHIFT;
++
++ if (status == 1)
++ data->valid = 1;
++}
++
++static int __init sensors_max127_init(void)
++{
++ return i2c_add_driver(&max127_driver);
++}
++
++static void __exit sensors_max127_exit(void)
++{
++ i2c_del_driver(&max127_driver);
++}
++
++MODULE_AUTHOR("Kevin Lahey <klahey@fb.com>");
++MODULE_DESCRIPTION("MAX127 sensor driver");
++MODULE_LICENSE("GPL");
++
++module_init(sensors_max127_init);
++module_exit(sensors_max127_exit);
+diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
+new file mode 100644
+index 0000000..52a3c7e
+--- /dev/null
++++ b/drivers/hwmon/pmbus/Kconfig
+@@ -0,0 +1,144 @@
++#
++# PMBus chip drivers configuration
++#
++
++menuconfig PMBUS
++ tristate "PMBus support"
++ depends on I2C
++ default n
++ help
++ Say yes here if you want to enable PMBus support.
++
++ This driver can also be built as a module. If so, the module will
++ be called pmbus_core.
++
++if PMBUS
++
++config SENSORS_PMBUS
++ tristate "Generic PMBus devices"
++ default y
++ help
++ If you say yes here you get hardware monitoring support for generic
++ PMBus devices, including but not limited to ADP4000, BMR453, BMR454,
++ MDT040, NCP4200, NCP4208, PDT003, PDT006, PDT012, UDT020, TPS40400,
++ and TPS40422.
++
++ This driver can also be built as a module. If so, the module will
++ be called pmbus.
++
++config SENSORS_ADM1275
++ tristate "Analog Devices ADM1275 and compatibles"
++ default n
++ help
++ If you say yes here you get hardware monitoring support for Analog
++ Devices ADM1075, ADM1275, and ADM1276 Hot-Swap Controller and Digital
++ Power Monitors.
++
++ This driver can also be built as a module. If so, the module will
++ be called adm1275.
++
++config SENSORS_LM25066
++ tristate "National Semiconductor LM25066 and compatibles"
++ default n
++ help
++ If you say yes here you get hardware monitoring support for National
++ Semiconductor LM25056, LM25066, LM5064, and LM5066.
++
++ This driver can also be built as a module. If so, the module will
++ be called lm25066.
++
++config SENSORS_LTC2978
++ tristate "Linear Technologies LTC2974, LTC2978, LTC3880, and LTC3883"
++ default n
++ help
++ If you say yes here you get hardware monitoring support for Linear
++ Technology LTC2974, LTC2978, LTC3880, and LTC3883.
++
++ This driver can also be built as a module. If so, the module will
++ be called ltc2978.
++
++config SENSORS_MAX16064
++ tristate "Maxim MAX16064"
++ default n
++ help
++ If you say yes here you get hardware monitoring support for Maxim
++ MAX16064.
++
++ This driver can also be built as a module. If so, the module will
++ be called max16064.
++
++config SENSORS_MAX34440
++ tristate "Maxim MAX34440 and compatibles"
++ default n
++ help
++ If you say yes here you get hardware monitoring support for Maxim
++ MAX34440, MAX34441, MAX34446, MAX34460, and MAX34461.
++
++ This driver can also be built as a module. If so, the module will
++ be called max34440.
++
++config SENSORS_MAX8688
++ tristate "Maxim MAX8688"
++ default n
++ help
++ If you say yes here you get hardware monitoring support for Maxim
++ MAX8688.
++
++ This driver can also be built as a module. If so, the module will
++ be called max8688.
++
++config SENSORS_PFE1100
++ tristate "Power One PFE1100"
++ default n
++ help
++ If you say yes here you get hardware monitoring support for
++ Power One PFE1100 devices.
++
++ This driver can also be built as a module. If so, the module will
++ be called pfe1100.
++
++config SENSORS_PFE3000
++ tristate "Power One PFE3000"
++ default n
++ help
++ If you say yes here you get hardware monitoring support for
++ Power One PFE3000 devices.
++
++ This driver can also be built as a module. If so, the module will
++ be called pfe3000.
++
++config SENSORS_UCD9000
++ tristate "TI UCD90120, UCD90124, UCD9090, UCD90910"
++ default n
++ help
++ If you say yes here you get hardware monitoring support for TI
++ UCD90120, UCD90124, UCD9090, UCD90910 Sequencer and System Health
++ Controllers.
++
++ This driver can also be built as a module. If so, the module will
++ be called ucd9000.
++
++config SENSORS_UCD9200
++ tristate "TI UCD9220, UCD9222, UCD9224, UCD9240, UCD9244, UCD9246, UCD9248"
++ default n
++ help
++ If you say yes here you get hardware monitoring support for TI
++ UCD9220, UCD9222, UCD9224, UCD9240, UCD9244, UCD9246, and UCD9248
++ Digital PWM System Controllers.
++
++ This driver can also be built as a module. If so, the module will
++ be called ucd9200.
++
++config SENSORS_ZL6100
++ tristate "Intersil ZL6100 and compatibles"
++ default n
++ help
++ If you say yes here you get hardware monitoring support for Intersil
++ ZL2004, ZL2005, ZL2006, ZL2008, ZL2105, ZL2106, ZL6100, ZL6105,
++ ZL9101M, and ZL9117M Digital DC/DC Controllers, as well as for
++ Ericsson BMR450, BMR451, BMR462, BMR463, and BMR464.
++
++ This driver can also be built as a module. If so, the module will
++ be called zl6100.
++
++endif # PMBUS
+diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
+new file mode 100644
+index 0000000..6cb3f6d
+--- /dev/null
++++ b/drivers/hwmon/pmbus/Makefile
+@@ -0,0 +1,17 @@
++#
++# Makefile for PMBus chip drivers.
++#
++
++obj-$(CONFIG_PMBUS) += pmbus_core.o
++obj-$(CONFIG_SENSORS_PMBUS) += pmbus.o
++obj-$(CONFIG_SENSORS_ADM1275) += adm1275.o
++obj-$(CONFIG_SENSORS_LM25066) += lm25066.o
++obj-$(CONFIG_SENSORS_LTC2978) += ltc2978.o
++obj-$(CONFIG_SENSORS_MAX16064) += max16064.o
++obj-$(CONFIG_SENSORS_MAX34440) += max34440.o
++obj-$(CONFIG_SENSORS_MAX8688) += max8688.o
++obj-$(CONFIG_SENSORS_PFE1100) += pfe1100.o
++obj-$(CONFIG_SENSORS_PFE3000) += pfe3000.o
++obj-$(CONFIG_SENSORS_UCD9000) += ucd9000.o
++obj-$(CONFIG_SENSORS_UCD9200) += ucd9200.o
++obj-$(CONFIG_SENSORS_ZL6100) += zl6100.o
+diff --git a/drivers/hwmon/pmbus/adm1275.c b/drivers/hwmon/pmbus/adm1275.c
+new file mode 100644
+index 0000000..d29f604
+--- /dev/null
++++ b/drivers/hwmon/pmbus/adm1275.c
+@@ -0,0 +1,457 @@
++/*
++ * Hardware monitoring driver for Analog Devices ADM1275 Hot-Swap Controller
++ * and Digital Power Monitor
++ *
++ * Copyright (c) 2011 Ericsson AB.
++ *
++ * 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.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/err.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include "pmbus.h"
++
++enum chips { adm1075, adm1275, adm1276, adm1278 };
++
++#define ADM1275_PEAK_IOUT 0xd0
++#define ADM1275_PEAK_VIN 0xd1
++#define ADM1275_PEAK_VOUT 0xd2
++#define ADM1278_PMON_CONTROL 0xd3
++#define ADM1275_PMON_CONFIG 0xd4
++
++#define ADM1278_CFG_TSFLT (1 << 15)
++#define ADM1278_CFG_SIMULTANEOUS (1 << 14)
++#define ADM1278_CFG_PMON_MODE (1 << 4)
++#define ADM1278_CFG_TEMP1_EN (1 << 3)
++#define ADM1278_CFG_VIN_EN (1 << 2)
++#define ADM1278_CFG_VOUT_EN (1 << 1)
++
++#define ADM1275_VIN_VOUT_SELECT (1 << 6)
++#define ADM1275_VRANGE (1 << 5)
++#define ADM1075_IRANGE_50 (1 << 4)
++#define ADM1075_IRANGE_25 (1 << 3)
++#define ADM1075_IRANGE_MASK ((1 << 3) | (1 << 4))
++
++#define ADM1275_IOUT_WARN2_LIMIT 0xd7
++#define ADM1275_DEVICE_CONFIG 0xd8
++
++#define ADM1275_IOUT_WARN2_SELECT (1 << 4)
++
++#define ADM1276_PEAK_PIN 0xda
++
++#define ADM1275_MFR_STATUS_IOUT_WARN2 (1 << 0)
++
++#define ADM1075_READ_VAUX 0xdd
++#define ADM1075_VAUX_OV_WARN_LIMIT 0xde
++#define ADM1075_VAUX_UV_WARN_LIMIT 0xdf
++#define ADM1075_VAUX_STATUS 0xf6
++
++#define ADM1075_VAUX_OV_WARN (1<<7)
++#define ADM1075_VAUX_UV_WARN (1<<6)
++
++struct adm1275_data {
++ int id;
++ bool have_oc_fault;
++ struct pmbus_driver_info info;
++};
++
++#define to_adm1275_data(x) container_of(x, struct adm1275_data, info)
++
++#define ADM1278_R_SENSE 500 /* R_sense resistor value in microohms */
++
++static int r_sense = ADM1278_R_SENSE;
++module_param(r_sense, int, 0644);
++MODULE_PARM_DESC(r_sense, "Rsense resistor value in microohms");
++
++
++static int adm1275_read_word_data(struct i2c_client *client, int page, int reg)
++{
++ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
++ const struct adm1275_data *data = to_adm1275_data(info);
++ int ret = 0;
++
++ if (page)
++ return -ENXIO;
++
++ switch (reg) {
++ case PMBUS_IOUT_UC_FAULT_LIMIT:
++ if (data->have_oc_fault) {
++ ret = -ENXIO;
++ break;
++ }
++ ret = pmbus_read_word_data(client, 0, ADM1275_IOUT_WARN2_LIMIT);
++ break;
++ case PMBUS_IOUT_OC_FAULT_LIMIT:
++ if (!data->have_oc_fault) {
++ ret = -ENXIO;
++ break;
++ }
++ ret = pmbus_read_word_data(client, 0, ADM1275_IOUT_WARN2_LIMIT);
++ break;
++ case PMBUS_VOUT_OV_WARN_LIMIT:
++ if (data->id != adm1075) {
++ ret = -ENODATA;
++ break;
++ }
++ ret = pmbus_read_word_data(client, 0,
++ ADM1075_VAUX_OV_WARN_LIMIT);
++ break;
++ case PMBUS_VOUT_UV_WARN_LIMIT:
++ if (data->id != adm1075) {
++ ret = -ENODATA;
++ break;
++ }
++ ret = pmbus_read_word_data(client, 0,
++ ADM1075_VAUX_UV_WARN_LIMIT);
++ break;
++ case PMBUS_READ_VOUT:
++ if (data->id != adm1075) {
++ ret = -ENODATA;
++ break;
++ }
++ ret = pmbus_read_word_data(client, 0, ADM1075_READ_VAUX);
++ break;
++ case PMBUS_VIRT_READ_IOUT_MAX:
++ ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_IOUT);
++ break;
++ case PMBUS_VIRT_READ_VOUT_MAX:
++ ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_VOUT);
++ break;
++ case PMBUS_VIRT_READ_VIN_MAX:
++ ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_VIN);
++ break;
++ case PMBUS_VIRT_READ_PIN_MAX:
++ if (data->id == adm1275) {
++ ret = -ENXIO;
++ break;
++ }
++ ret = pmbus_read_word_data(client, 0, ADM1276_PEAK_PIN);
++ break;
++ case PMBUS_VIRT_RESET_IOUT_HISTORY:
++ case PMBUS_VIRT_RESET_VOUT_HISTORY:
++ case PMBUS_VIRT_RESET_VIN_HISTORY:
++ break;
++ case PMBUS_VIRT_RESET_PIN_HISTORY:
++ if (data->id == adm1275)
++ ret = -ENXIO;
++ break;
++ default:
++ ret = -ENODATA;
++ break;
++ }
++ return ret;
++}
++
++static int adm1275_write_word_data(struct i2c_client *client, int page, int reg,
++ u16 word)
++{
++ int ret;
++
++ if (page)
++ return -ENXIO;
++
++ switch (reg) {
++ case PMBUS_IOUT_UC_FAULT_LIMIT:
++ case PMBUS_IOUT_OC_FAULT_LIMIT:
++ ret = pmbus_write_word_data(client, 0, ADM1275_IOUT_WARN2_LIMIT,
++ word);
++ break;
++ case PMBUS_VIRT_RESET_IOUT_HISTORY:
++ ret = pmbus_write_word_data(client, 0, ADM1275_PEAK_IOUT, 0);
++ break;
++ case PMBUS_VIRT_RESET_VOUT_HISTORY:
++ ret = pmbus_write_word_data(client, 0, ADM1275_PEAK_VOUT, 0);
++ break;
++ case PMBUS_VIRT_RESET_VIN_HISTORY:
++ ret = pmbus_write_word_data(client, 0, ADM1275_PEAK_VIN, 0);
++ break;
++ case PMBUS_VIRT_RESET_PIN_HISTORY:
++ ret = pmbus_write_word_data(client, 0, ADM1276_PEAK_PIN, 0);
++ break;
++ default:
++ ret = -ENODATA;
++ break;
++ }
++ return ret;
++}
++
++static int adm1275_read_byte_data(struct i2c_client *client, int page, int reg)
++{
++ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
++ const struct adm1275_data *data = to_adm1275_data(info);
++ int mfr_status, ret;
++
++ if (page > 0)
++ return -ENXIO;
++
++ switch (reg) {
++ case PMBUS_STATUS_IOUT:
++ ret = pmbus_read_byte_data(client, page, PMBUS_STATUS_IOUT);
++ if (ret < 0)
++ break;
++ mfr_status = pmbus_read_byte_data(client, page,
++ PMBUS_STATUS_MFR_SPECIFIC);
++ if (mfr_status < 0) {
++ ret = mfr_status;
++ break;
++ }
++ if (mfr_status & ADM1275_MFR_STATUS_IOUT_WARN2) {
++ ret |= data->have_oc_fault ?
++ PB_IOUT_OC_FAULT : PB_IOUT_UC_FAULT;
++ }
++ break;
++ case PMBUS_STATUS_VOUT:
++ if (data->id != adm1075) {
++ ret = -ENODATA;
++ break;
++ }
++ ret = 0;
++ mfr_status = pmbus_read_byte_data(client, 0,
++ ADM1075_VAUX_STATUS);
++ if (mfr_status & ADM1075_VAUX_OV_WARN)
++ ret |= PB_VOLTAGE_OV_WARNING;
++ if (mfr_status & ADM1075_VAUX_UV_WARN)
++ ret |= PB_VOLTAGE_UV_WARNING;
++ break;
++ default:
++ ret = -ENODATA;
++ break;
++ }
++ return ret;
++}
++
++static const struct i2c_device_id adm1275_id[] = {
++ { "adm1075", adm1075 },
++ { "adm1275", adm1275 },
++ { "adm1276", adm1276 },
++ { "adm1278", adm1278 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, adm1275_id);
++
++static int adm1275_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1];
++ int config, device_config;
++ int ret;
++ struct pmbus_driver_info *info;
++ struct adm1275_data *data;
++ const struct i2c_device_id *mid;
++
++ if (!i2c_check_functionality(client->adapter,
++ I2C_FUNC_SMBUS_READ_BYTE_DATA
++ | I2C_FUNC_SMBUS_BLOCK_DATA))
++ return -ENODEV;
++
++ ret = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, block_buffer);
++ if (ret < 0) {
++ dev_err(&client->dev, "Failed to read Manufacturer ID\n");
++ return ret;
++ }
++ if (ret != 3 || strncmp(block_buffer, "ADI", 3)) {
++ dev_err(&client->dev, "Unsupported Manufacturer ID\n");
++ return -ENODEV;
++ }
++
++ ret = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, block_buffer);
++ if (ret < 0) {
++ dev_err(&client->dev, "Failed to read Manufacturer Model\n");
++ return ret;
++ }
++ for (mid = adm1275_id; mid->name[0]; mid++) {
++ if (!strncasecmp(mid->name, block_buffer, strlen(mid->name)))
++ break;
++ }
++ if (!mid->name[0]) {
++ dev_err(&client->dev, "Unsupported device\n");
++ return -ENODEV;
++ }
++
++ if (id->driver_data != mid->driver_data)
++ dev_notice(&client->dev,
++ "Device mismatch: Configured %s, detected %s\n",
++ id->name, mid->name);
++
++ config = i2c_smbus_read_byte_data(client, ADM1275_PMON_CONFIG);
++ if (config < 0)
++ return config;
++
++ device_config = i2c_smbus_read_byte_data(client, ADM1275_DEVICE_CONFIG);
++ if (device_config < 0)
++ return device_config;
++
++ data = devm_kzalloc(&client->dev, sizeof(struct adm1275_data),
++ GFP_KERNEL);
++ if (!data)
++ return -ENOMEM;
++
++ data->id = mid->driver_data;
++
++ info = &data->info;
++
++ info->pages = 1;
++ info->format[PSC_VOLTAGE_IN] = direct;
++ info->format[PSC_VOLTAGE_OUT] = direct;
++ info->format[PSC_CURRENT_OUT] = direct;
++ if (data->id == adm1278)
++ info->m[PSC_CURRENT_OUT] = 807 * r_sense / 1000;
++ else
++ info->m[PSC_CURRENT_OUT] = 807;
++ info->b[PSC_CURRENT_OUT] = 20475;
++ info->R[PSC_CURRENT_OUT] = -1;
++ info->func[0] = PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT;
++
++ if (data->id == adm1278) {
++ /* Configure monitoring */
++ ret = i2c_smbus_write_byte_data(client,
++ ADM1278_PMON_CONTROL, 0);
++ if (ret < 0)
++ return ret;
++ ret = i2c_smbus_read_word_data(client, ADM1275_PMON_CONFIG);
++ ret = i2c_smbus_write_word_data(client, ADM1275_PMON_CONFIG,
++ ADM1278_CFG_PMON_MODE |
++ ADM1278_CFG_TEMP1_EN |
++ ADM1278_CFG_VIN_EN |
++ ADM1278_CFG_VOUT_EN);
++ if (ret < 0)
++ return ret;
++ ret = i2c_smbus_read_word_data(client, ADM1275_PMON_CONFIG);
++ ret = i2c_smbus_write_byte_data(client, ADM1278_PMON_CONTROL, 1);
++ if (ret < 0)
++ return ret;
++ } else {
++ /* TODO klahey -- there might be adm1278 issues here, too. */
++ info->read_word_data = adm1275_read_word_data;
++ info->read_byte_data = adm1275_read_byte_data;
++ info->write_word_data = adm1275_write_word_data;
++ }
++
++ if (data->id == adm1278) {
++ info->m[PSC_VOLTAGE_IN] = 19599;
++ info->b[PSC_VOLTAGE_IN] = 0;
++ info->R[PSC_VOLTAGE_IN] = -2;
++ info->m[PSC_VOLTAGE_OUT] = 19599;
++ info->b[PSC_VOLTAGE_OUT] = 0;
++ info->R[PSC_VOLTAGE_OUT] = -2;
++ } else if (data->id == adm1075) {
++ info->m[PSC_VOLTAGE_IN] = 27169;
++ info->b[PSC_VOLTAGE_IN] = 0;
++ info->R[PSC_VOLTAGE_IN] = -1;
++ info->m[PSC_VOLTAGE_OUT] = 27169;
++ info->b[PSC_VOLTAGE_OUT] = 0;
++ info->R[PSC_VOLTAGE_OUT] = -1;
++ } else if (config & ADM1275_VRANGE) {
++ info->m[PSC_VOLTAGE_IN] = 19199;
++ info->b[PSC_VOLTAGE_IN] = 0;
++ info->R[PSC_VOLTAGE_IN] = -2;
++ info->m[PSC_VOLTAGE_OUT] = 19199;
++ info->b[PSC_VOLTAGE_OUT] = 0;
++ info->R[PSC_VOLTAGE_OUT] = -2;
++ } else {
++ info->m[PSC_VOLTAGE_IN] = 6720;
++ info->b[PSC_VOLTAGE_IN] = 0;
++ info->R[PSC_VOLTAGE_IN] = -1;
++ info->m[PSC_VOLTAGE_OUT] = 6720;
++ info->b[PSC_VOLTAGE_OUT] = 0;
++ info->R[PSC_VOLTAGE_OUT] = -1;
++ }
++
++ if (device_config & ADM1275_IOUT_WARN2_SELECT)
++ data->have_oc_fault = true;
++
++ switch (data->id) {
++ case adm1075:
++ info->format[PSC_POWER] = direct;
++ info->b[PSC_POWER] = 0;
++ info->R[PSC_POWER] = -1;
++ switch (config & ADM1075_IRANGE_MASK) {
++ case ADM1075_IRANGE_25:
++ info->m[PSC_POWER] = 8549;
++ info->m[PSC_CURRENT_OUT] = 806;
++ break;
++ case ADM1075_IRANGE_50:
++ info->m[PSC_POWER] = 4279;
++ info->m[PSC_CURRENT_OUT] = 404;
++ break;
++ default:
++ dev_err(&client->dev, "Invalid input current range");
++ info->m[PSC_POWER] = 0;
++ info->m[PSC_CURRENT_OUT] = 0;
++ break;
++ }
++ info->func[0] |= PMBUS_HAVE_VIN | PMBUS_HAVE_PIN
++ | PMBUS_HAVE_STATUS_INPUT;
++ if (config & ADM1275_VIN_VOUT_SELECT)
++ info->func[0] |=
++ PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
++ break;
++ case adm1275:
++ if (config & ADM1275_VIN_VOUT_SELECT)
++ info->func[0] |=
++ PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
++ else
++ info->func[0] |=
++ PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT;
++ break;
++ case adm1276:
++ info->format[PSC_POWER] = direct;
++ info->func[0] |= PMBUS_HAVE_VIN | PMBUS_HAVE_PIN
++ | PMBUS_HAVE_STATUS_INPUT;
++ if (config & ADM1275_VIN_VOUT_SELECT)
++ info->func[0] |=
++ PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
++ if (config & ADM1275_VRANGE) {
++ info->m[PSC_POWER] = 6043;
++ info->b[PSC_POWER] = 0;
++ info->R[PSC_POWER] = -2;
++ } else {
++ info->m[PSC_POWER] = 2115;
++ info->b[PSC_POWER] = 0;
++ info->R[PSC_POWER] = -1;
++ }
++ break;
++ case adm1278:
++ info->format[PSC_POWER] = direct;
++ info->format[PSC_TEMPERATURE] = direct;
++ info->func[0] |= PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT
++ | PMBUS_HAVE_STATUS_INPUT
++ | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
++ info->m[PSC_POWER] = 6123 * r_sense / 1000;
++ info->b[PSC_POWER] = 0;
++ info->R[PSC_POWER] = -2;
++ info->m[PSC_TEMPERATURE] = 42;
++ info->b[PSC_TEMPERATURE] = 31880;
++ info->R[PSC_TEMPERATURE] = -1;
++ break;
++ }
++
++ return pmbus_do_probe(client, id, info);
++}
++
++static struct i2c_driver adm1275_driver = {
++ .driver = {
++ .name = "adm1275",
++ },
++ .probe = adm1275_probe,
++ .remove = pmbus_do_remove,
++ .id_table = adm1275_id,
++};
++
++module_i2c_driver(adm1275_driver);
++
++MODULE_AUTHOR("Guenter Roeck");
++MODULE_DESCRIPTION("PMBus driver for Analog Devices ADM1275 and compatibles");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/hwmon/pmbus/lm25066.c b/drivers/hwmon/pmbus/lm25066.c
+new file mode 100644
+index 0000000..6a9d6ed
+--- /dev/null
++++ b/drivers/hwmon/pmbus/lm25066.c
+@@ -0,0 +1,457 @@
++/*
++ * Hardware monitoring driver for LM25056 / LM25066 / LM5064 / LM5066
++ *
++ * Copyright (c) 2011 Ericsson AB.
++ * Copyright (c) 2013 Guenter Roeck
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/err.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include "pmbus.h"
++
++enum chips { lm25056, lm25066, lm5064, lm5066 };
++
++#define LM25066_READ_VAUX 0xd0
++#define LM25066_MFR_READ_IIN 0xd1
++#define LM25066_MFR_READ_PIN 0xd2
++#define LM25066_MFR_IIN_OC_WARN_LIMIT 0xd3
++#define LM25066_MFR_PIN_OP_WARN_LIMIT 0xd4
++#define LM25066_READ_PIN_PEAK 0xd5
++#define LM25066_CLEAR_PIN_PEAK 0xd6
++#define LM25066_DEVICE_SETUP 0xd9
++#define LM25066_READ_AVG_VIN 0xdc
++#define LM25066_READ_AVG_VOUT 0xdd
++#define LM25066_READ_AVG_IIN 0xde
++#define LM25066_READ_AVG_PIN 0xdf
++
++#define LM25066_DEV_SETUP_CL (1 << 4) /* Current limit */
++
++/* LM25056 only */
++
++#define LM25056_VAUX_OV_WARN_LIMIT 0xe3
++#define LM25056_VAUX_UV_WARN_LIMIT 0xe4
++
++#define LM25056_MFR_STS_VAUX_OV_WARN (1 << 1)
++#define LM25056_MFR_STS_VAUX_UV_WARN (1 << 0)
++
++struct __coeff {
++ short m, b, R;
++};
++
++#define PSC_CURRENT_IN_L (PSC_NUM_CLASSES)
++#define PSC_POWER_L (PSC_NUM_CLASSES + 1)
++
++static struct __coeff lm25066_coeff[4][PSC_NUM_CLASSES + 2] = {
++ [lm25056] = {
++ [PSC_VOLTAGE_IN] = {
++ .m = 16296,
++ .R = -2,
++ },
++ [PSC_CURRENT_IN] = {
++ .m = 13797,
++ .R = -2,
++ },
++ [PSC_CURRENT_IN_L] = {
++ .m = 6726,
++ .R = -2,
++ },
++ [PSC_POWER] = {
++ .m = 5501,
++ .R = -3,
++ },
++ [PSC_POWER_L] = {
++ .m = 26882,
++ .R = -4,
++ },
++ [PSC_TEMPERATURE] = {
++ .m = 1580,
++ .b = -14500,
++ .R = -2,
++ },
++ },
++ [lm25066] = {
++ [PSC_VOLTAGE_IN] = {
++ .m = 22070,
++ .R = -2,
++ },
++ [PSC_VOLTAGE_OUT] = {
++ .m = 22070,
++ .R = -2,
++ },
++ [PSC_CURRENT_IN] = {
++ .m = 13661,
++ .R = -2,
++ },
++ [PSC_CURRENT_IN_L] = {
++ .m = 6852,
++ .R = -2,
++ },
++ [PSC_POWER] = {
++ .m = 736,
++ .R = -2,
++ },
++ [PSC_POWER_L] = {
++ .m = 369,
++ .R = -2,
++ },
++ [PSC_TEMPERATURE] = {
++ .m = 16,
++ },
++ },
++ [lm5064] = {
++ [PSC_VOLTAGE_IN] = {
++ .m = 4611,
++ .R = -2,
++ },
++ [PSC_VOLTAGE_OUT] = {
++ .m = 4621,
++ .R = -2,
++ },
++ [PSC_CURRENT_IN] = {
++ .m = 10742,
++ .R = -2,
++ },
++ [PSC_CURRENT_IN_L] = {
++ .m = 5456,
++ .R = -2,
++ },
++ [PSC_POWER] = {
++ .m = 1204,
++ .R = -3,
++ },
++ [PSC_POWER_L] = {
++ .m = 612,
++ .R = -3,
++ },
++ [PSC_TEMPERATURE] = {
++ .m = 16,
++ },
++ },
++ [lm5066] = {
++ [PSC_VOLTAGE_IN] = {
++ .m = 4587,
++ .R = -2,
++ },
++ [PSC_VOLTAGE_OUT] = {
++ .m = 4587,
++ .R = -2,
++ },
++ [PSC_CURRENT_IN] = {
++ .m = 10753,
++ .R = -2,
++ },
++ [PSC_CURRENT_IN_L] = {
++ .m = 5405,
++ .R = -2,
++ },
++ [PSC_POWER] = {
++ .m = 1204,
++ .R = -3,
++ },
++ [PSC_POWER_L] = {
++ .m = 605,
++ .R = -3,
++ },
++ [PSC_TEMPERATURE] = {
++ .m = 16,
++ },
++ },
++};
++
++struct lm25066_data {
++ int id;
++ struct pmbus_driver_info info;
++};
++
++#define to_lm25066_data(x) container_of(x, struct lm25066_data, info)
++
++static int lm25066_read_word_data(struct i2c_client *client, int page, int reg)
++{
++ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
++ const struct lm25066_data *data = to_lm25066_data(info);
++ int ret;
++
++ switch (reg) {
++ case PMBUS_VIRT_READ_VMON:
++ ret = pmbus_read_word_data(client, 0, LM25066_READ_VAUX);
++ if (ret < 0)
++ break;
++ /* Adjust returned value to match VIN coefficients */
++ switch (data->id) {
++ case lm25056:
++ /* VIN: 6.14 mV VAUX: 293 uV LSB */
++ ret = DIV_ROUND_CLOSEST(ret * 293, 6140);
++ break;
++ case lm25066:
++ /* VIN: 4.54 mV VAUX: 283.2 uV LSB */
++ ret = DIV_ROUND_CLOSEST(ret * 2832, 45400);
++ break;
++ case lm5064:
++ /* VIN: 4.53 mV VAUX: 700 uV LSB */
++ ret = DIV_ROUND_CLOSEST(ret * 70, 453);
++ break;
++ case lm5066:
++ /* VIN: 2.18 mV VAUX: 725 uV LSB */
++ ret = DIV_ROUND_CLOSEST(ret * 725, 2180);
++ break;
++ }
++ break;
++ case PMBUS_READ_IIN:
++ ret = pmbus_read_word_data(client, 0, LM25066_MFR_READ_IIN);
++ break;
++ case PMBUS_READ_PIN:
++ ret = pmbus_read_word_data(client, 0, LM25066_MFR_READ_PIN);
++ break;
++ case PMBUS_IIN_OC_WARN_LIMIT:
++ ret = pmbus_read_word_data(client, 0,
++ LM25066_MFR_IIN_OC_WARN_LIMIT);
++ break;
++ case PMBUS_PIN_OP_WARN_LIMIT:
++ ret = pmbus_read_word_data(client, 0,
++ LM25066_MFR_PIN_OP_WARN_LIMIT);
++ break;
++ case PMBUS_VIRT_READ_VIN_AVG:
++ ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_VIN);
++ break;
++ case PMBUS_VIRT_READ_VOUT_AVG:
++ ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_VOUT);
++ break;
++ case PMBUS_VIRT_READ_IIN_AVG:
++ ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_IIN);
++ break;
++ case PMBUS_VIRT_READ_PIN_AVG:
++ ret = pmbus_read_word_data(client, 0, LM25066_READ_AVG_PIN);
++ break;
++ case PMBUS_VIRT_READ_PIN_MAX:
++ ret = pmbus_read_word_data(client, 0, LM25066_READ_PIN_PEAK);
++ break;
++ case PMBUS_VIRT_RESET_PIN_HISTORY:
++ ret = 0;
++ break;
++ default:
++ ret = -ENODATA;
++ break;
++ }
++ return ret;
++}
++
++static int lm25056_read_word_data(struct i2c_client *client, int page, int reg)
++{
++ int ret;
++
++ switch (reg) {
++ case PMBUS_VIRT_VMON_UV_WARN_LIMIT:
++ ret = pmbus_read_word_data(client, 0,
++ LM25056_VAUX_UV_WARN_LIMIT);
++ if (ret < 0)
++ break;
++ /* Adjust returned value to match VIN coefficients */
++ ret = DIV_ROUND_CLOSEST(ret * 293, 6140);
++ break;
++ case PMBUS_VIRT_VMON_OV_WARN_LIMIT:
++ ret = pmbus_read_word_data(client, 0,
++ LM25056_VAUX_OV_WARN_LIMIT);
++ if (ret < 0)
++ break;
++ /* Adjust returned value to match VIN coefficients */
++ ret = DIV_ROUND_CLOSEST(ret * 293, 6140);
++ break;
++ default:
++ ret = lm25066_read_word_data(client, page, reg);
++ break;
++ }
++ return ret;
++}
++
++static int lm25056_read_byte_data(struct i2c_client *client, int page, int reg)
++{
++ int ret, s;
++
++ switch (reg) {
++ case PMBUS_VIRT_STATUS_VMON:
++ ret = pmbus_read_byte_data(client, 0,
++ PMBUS_STATUS_MFR_SPECIFIC);
++ if (ret < 0)
++ break;
++ s = 0;
++ if (ret & LM25056_MFR_STS_VAUX_UV_WARN)
++ s |= PB_VOLTAGE_UV_WARNING;
++ if (ret & LM25056_MFR_STS_VAUX_OV_WARN)
++ s |= PB_VOLTAGE_OV_WARNING;
++ ret = s;
++ break;
++ default:
++ ret = -ENODATA;
++ break;
++ }
++ return ret;
++}
++
++static int lm25066_write_word_data(struct i2c_client *client, int page, int reg,
++ u16 word)
++{
++ int ret;
++
++ switch (reg) {
++ case PMBUS_VOUT_UV_WARN_LIMIT:
++ case PMBUS_OT_FAULT_LIMIT:
++ case PMBUS_OT_WARN_LIMIT:
++ case PMBUS_VIN_UV_WARN_LIMIT:
++ case PMBUS_VIN_OV_WARN_LIMIT:
++ word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff);
++ ret = pmbus_write_word_data(client, 0, reg, word);
++ pmbus_clear_cache(client);
++ break;
++ case PMBUS_IIN_OC_WARN_LIMIT:
++ word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff);
++ ret = pmbus_write_word_data(client, 0,
++ LM25066_MFR_IIN_OC_WARN_LIMIT,
++ word);
++ pmbus_clear_cache(client);
++ break;
++ case PMBUS_PIN_OP_WARN_LIMIT:
++ word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff);
++ ret = pmbus_write_word_data(client, 0,
++ LM25066_MFR_PIN_OP_WARN_LIMIT,
++ word);
++ pmbus_clear_cache(client);
++ break;
++ case PMBUS_VIRT_VMON_UV_WARN_LIMIT:
++ /* Adjust from VIN coefficients (for LM25056) */
++ word = DIV_ROUND_CLOSEST((int)word * 6140, 293);
++ word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff);
++ ret = pmbus_write_word_data(client, 0,
++ LM25056_VAUX_UV_WARN_LIMIT, word);
++ pmbus_clear_cache(client);
++ break;
++ case PMBUS_VIRT_VMON_OV_WARN_LIMIT:
++ /* Adjust from VIN coefficients (for LM25056) */
++ word = DIV_ROUND_CLOSEST((int)word * 6140, 293);
++ word = ((s16)word < 0) ? 0 : clamp_val(word, 0, 0x0fff);
++ ret = pmbus_write_word_data(client, 0,
++ LM25056_VAUX_OV_WARN_LIMIT, word);
++ pmbus_clear_cache(client);
++ break;
++ case PMBUS_VIRT_RESET_PIN_HISTORY:
++ ret = pmbus_write_byte(client, 0, LM25066_CLEAR_PIN_PEAK);
++ break;
++ default:
++ ret = -ENODATA;
++ break;
++ }
++ return ret;
++}
++
++static int lm25066_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ int config;
++ struct lm25066_data *data;
++ struct pmbus_driver_info *info;
++ struct __coeff *coeff;
++
++ if (!i2c_check_functionality(client->adapter,
++ I2C_FUNC_SMBUS_READ_BYTE_DATA))
++ return -ENODEV;
++
++ data = devm_kzalloc(&client->dev, sizeof(struct lm25066_data),
++ GFP_KERNEL);
++ if (!data)
++ return -ENOMEM;
++
++ config = i2c_smbus_read_byte_data(client, LM25066_DEVICE_SETUP);
++ if (config < 0)
++ return config;
++
++ data->id = id->driver_data;
++ info = &data->info;
++
++ info->pages = 1;
++ info->format[PSC_VOLTAGE_IN] = direct;
++ info->format[PSC_VOLTAGE_OUT] = direct;
++ info->format[PSC_CURRENT_IN] = direct;
++ info->format[PSC_TEMPERATURE] = direct;
++ info->format[PSC_POWER] = direct;
++
++ info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VMON
++ | PMBUS_HAVE_PIN | PMBUS_HAVE_IIN | PMBUS_HAVE_STATUS_INPUT
++ | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
++
++ if (data->id == lm25056) {
++ info->func[0] |= PMBUS_HAVE_STATUS_VMON;
++ info->read_word_data = lm25056_read_word_data;
++ info->read_byte_data = lm25056_read_byte_data;
++ } else {
++ info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
++ info->read_word_data = lm25066_read_word_data;
++ }
++ info->write_word_data = lm25066_write_word_data;
++
++ coeff = &lm25066_coeff[data->id][0];
++ info->m[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].m;
++ info->b[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].b;
++ info->R[PSC_TEMPERATURE] = coeff[PSC_TEMPERATURE].R;
++ info->m[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].m;
++ info->b[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].b;
++ info->R[PSC_VOLTAGE_IN] = coeff[PSC_VOLTAGE_IN].R;
++ info->m[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].m;
++ info->b[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].b;
++ info->R[PSC_VOLTAGE_OUT] = coeff[PSC_VOLTAGE_OUT].R;
++ info->b[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].b;
++ info->R[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].R;
++ info->b[PSC_POWER] = coeff[PSC_POWER].b;
++ info->R[PSC_POWER] = coeff[PSC_POWER].R;
++ if (config & LM25066_DEV_SETUP_CL) {
++ info->m[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN_L].m;
++ info->m[PSC_POWER] = coeff[PSC_POWER_L].m;
++ } else {
++ info->m[PSC_CURRENT_IN] = coeff[PSC_CURRENT_IN].m;
++ info->m[PSC_POWER] = coeff[PSC_POWER].m;
++ }
++
++ return pmbus_do_probe(client, id, info);
++}
++
++static const struct i2c_device_id lm25066_id[] = {
++ {"lm25056", lm25056},
++ {"lm25066", lm25066},
++ {"lm5064", lm5064},
++ {"lm5066", lm5066},
++ { }
++};
++
++MODULE_DEVICE_TABLE(i2c, lm25066_id);
++
++/* This is the driver that will be inserted */
++static struct i2c_driver lm25066_driver = {
++ .driver = {
++ .name = "lm25066",
++ },
++ .probe = lm25066_probe,
++ .remove = pmbus_do_remove,
++ .id_table = lm25066_id,
++};
++
++module_i2c_driver(lm25066_driver);
++
++MODULE_AUTHOR("Guenter Roeck");
++MODULE_DESCRIPTION("PMBus driver for LM25056/LM25066/LM5064/LM5066");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/hwmon/pmbus/ltc2978.c b/drivers/hwmon/pmbus/ltc2978.c
+new file mode 100644
+index 0000000..586a89e
+--- /dev/null
++++ b/drivers/hwmon/pmbus/ltc2978.c
+@@ -0,0 +1,496 @@
++/*
++ * Hardware monitoring driver for LTC2974, LTC2978, LTC3880, and LTC3883
++ *
++ * Copyright (c) 2011 Ericsson AB.
++ * Copyright (c) 2013 Guenter Roeck
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/err.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include "pmbus.h"
++
++enum chips { ltc2974, ltc2978, ltc3880, ltc3883 };
++
++/* Common for all chips */
++#define LTC2978_MFR_VOUT_PEAK 0xdd
++#define LTC2978_MFR_VIN_PEAK 0xde
++#define LTC2978_MFR_TEMPERATURE_PEAK 0xdf
++#define LTC2978_MFR_SPECIAL_ID 0xe7
++
++/* LTC2974 and LTC2978 */
++#define LTC2978_MFR_VOUT_MIN 0xfb
++#define LTC2978_MFR_VIN_MIN 0xfc
++#define LTC2978_MFR_TEMPERATURE_MIN 0xfd
++
++/* LTC2974 only */
++#define LTC2974_MFR_IOUT_PEAK 0xd7
++#define LTC2974_MFR_IOUT_MIN 0xd8
++
++/* LTC3880 and LTC3883 */
++#define LTC3880_MFR_IOUT_PEAK 0xd7
++#define LTC3880_MFR_CLEAR_PEAKS 0xe3
++#define LTC3880_MFR_TEMPERATURE2_PEAK 0xf4
++
++/* LTC3883 only */
++#define LTC3883_MFR_IIN_PEAK 0xe1
++
++#define LTC2974_ID 0x0212
++#define LTC2978_ID_REV1 0x0121
++#define LTC2978_ID_REV2 0x0122
++#define LTC3880_ID 0x4000
++#define LTC3880_ID_MASK 0xff00
++#define LTC3883_ID 0x4300
++#define LTC3883_ID_MASK 0xff00
++
++#define LTC2974_NUM_PAGES 4
++#define LTC2978_NUM_PAGES 8
++#define LTC3880_NUM_PAGES 2
++#define LTC3883_NUM_PAGES 1
++
++/*
++ * LTC2978 clears peak data whenever the CLEAR_FAULTS command is executed, which
++ * happens pretty much each time chip data is updated. Raw peak data therefore
++ * does not provide much value. To be able to provide useful peak data, keep an
++ * internal cache of measured peak data, which is only cleared if an explicit
++ * "clear peak" command is executed for the sensor in question.
++ */
++
++struct ltc2978_data {
++ enum chips id;
++ u16 vin_min, vin_max;
++ u16 temp_min[LTC2974_NUM_PAGES], temp_max[LTC2974_NUM_PAGES];
++ u16 vout_min[LTC2978_NUM_PAGES], vout_max[LTC2978_NUM_PAGES];
++ u16 iout_min[LTC2974_NUM_PAGES], iout_max[LTC2974_NUM_PAGES];
++ u16 iin_max;
++ u16 temp2_max;
++ struct pmbus_driver_info info;
++};
++
++#define to_ltc2978_data(x) container_of(x, struct ltc2978_data, info)
++
++static inline int lin11_to_val(int data)
++{
++ s16 e = ((s16)data) >> 11;
++ s32 m = (((s16)(data << 5)) >> 5);
++
++ /*
++ * mantissa is 10 bit + sign, exponent adds up to 15 bit.
++ * Add 6 bit to exponent for maximum accuracy (10 + 15 + 6 = 31).
++ */
++ e += 6;
++ return (e < 0 ? m >> -e : m << e);
++}
++
++static int ltc2978_read_word_data_common(struct i2c_client *client, int page,
++ int reg)
++{
++ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
++ struct ltc2978_data *data = to_ltc2978_data(info);
++ int ret;
++
++ switch (reg) {
++ case PMBUS_VIRT_READ_VIN_MAX:
++ ret = pmbus_read_word_data(client, page, LTC2978_MFR_VIN_PEAK);
++ if (ret >= 0) {
++ if (lin11_to_val(ret) > lin11_to_val(data->vin_max))
++ data->vin_max = ret;
++ ret = data->vin_max;
++ }
++ break;
++ case PMBUS_VIRT_READ_VOUT_MAX:
++ ret = pmbus_read_word_data(client, page, LTC2978_MFR_VOUT_PEAK);
++ if (ret >= 0) {
++ /*
++ * VOUT is 16 bit unsigned with fixed exponent,
++ * so we can compare it directly
++ */
++ if (ret > data->vout_max[page])
++ data->vout_max[page] = ret;
++ ret = data->vout_max[page];
++ }
++ break;
++ case PMBUS_VIRT_READ_TEMP_MAX:
++ ret = pmbus_read_word_data(client, page,
++ LTC2978_MFR_TEMPERATURE_PEAK);
++ if (ret >= 0) {
++ if (lin11_to_val(ret)
++ > lin11_to_val(data->temp_max[page]))
++ data->temp_max[page] = ret;
++ ret = data->temp_max[page];
++ }
++ break;
++ case PMBUS_VIRT_RESET_VOUT_HISTORY:
++ case PMBUS_VIRT_RESET_VIN_HISTORY:
++ case PMBUS_VIRT_RESET_TEMP_HISTORY:
++ ret = 0;
++ break;
++ default:
++ ret = -ENODATA;
++ break;
++ }
++ return ret;
++}
++
++static int ltc2978_read_word_data(struct i2c_client *client, int page, int reg)
++{
++ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
++ struct ltc2978_data *data = to_ltc2978_data(info);
++ int ret;
++
++ switch (reg) {
++ case PMBUS_VIRT_READ_VIN_MIN:
++ ret = pmbus_read_word_data(client, page, LTC2978_MFR_VIN_MIN);
++ if (ret >= 0) {
++ if (lin11_to_val(ret) < lin11_to_val(data->vin_min))
++ data->vin_min = ret;
++ ret = data->vin_min;
++ }
++ break;
++ case PMBUS_VIRT_READ_VOUT_MIN:
++ ret = pmbus_read_word_data(client, page, LTC2978_MFR_VOUT_MIN);
++ if (ret >= 0) {
++ /*
++ * VOUT_MIN is known to not be supported on some lots
++ * of LTC2978 revision 1, and will return the maximum
++ * possible voltage if read. If VOUT_MAX is valid and
++ * lower than the reading of VOUT_MIN, use it instead.
++ */
++ if (data->vout_max[page] && ret > data->vout_max[page])
++ ret = data->vout_max[page];
++ if (ret < data->vout_min[page])
++ data->vout_min[page] = ret;
++ ret = data->vout_min[page];
++ }
++ break;
++ case PMBUS_VIRT_READ_TEMP_MIN:
++ ret = pmbus_read_word_data(client, page,
++ LTC2978_MFR_TEMPERATURE_MIN);
++ if (ret >= 0) {
++ if (lin11_to_val(ret)
++ < lin11_to_val(data->temp_min[page]))
++ data->temp_min[page] = ret;
++ ret = data->temp_min[page];
++ }
++ break;
++ case PMBUS_VIRT_READ_IOUT_MAX:
++ case PMBUS_VIRT_RESET_IOUT_HISTORY:
++ case PMBUS_VIRT_READ_TEMP2_MAX:
++ case PMBUS_VIRT_RESET_TEMP2_HISTORY:
++ ret = -ENXIO;
++ break;
++ default:
++ ret = ltc2978_read_word_data_common(client, page, reg);
++ break;
++ }
++ return ret;
++}
++
++static int ltc2974_read_word_data(struct i2c_client *client, int page, int reg)
++{
++ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
++ struct ltc2978_data *data = to_ltc2978_data(info);
++ int ret;
++
++ switch (reg) {
++ case PMBUS_VIRT_READ_IOUT_MAX:
++ ret = pmbus_read_word_data(client, page, LTC2974_MFR_IOUT_PEAK);
++ if (ret >= 0) {
++ if (lin11_to_val(ret)
++ > lin11_to_val(data->iout_max[page]))
++ data->iout_max[page] = ret;
++ ret = data->iout_max[page];
++ }
++ break;
++ case PMBUS_VIRT_READ_IOUT_MIN:
++ ret = pmbus_read_word_data(client, page, LTC2974_MFR_IOUT_MIN);
++ if (ret >= 0) {
++ if (lin11_to_val(ret)
++ < lin11_to_val(data->iout_min[page]))
++ data->iout_min[page] = ret;
++ ret = data->iout_min[page];
++ }
++ break;
++ case PMBUS_VIRT_RESET_IOUT_HISTORY:
++ ret = 0;
++ break;
++ default:
++ ret = ltc2978_read_word_data(client, page, reg);
++ break;
++ }
++ return ret;
++}
++
++static int ltc3880_read_word_data(struct i2c_client *client, int page, int reg)
++{
++ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
++ struct ltc2978_data *data = to_ltc2978_data(info);
++ int ret;
++
++ switch (reg) {
++ case PMBUS_VIRT_READ_IOUT_MAX:
++ ret = pmbus_read_word_data(client, page, LTC3880_MFR_IOUT_PEAK);
++ if (ret >= 0) {
++ if (lin11_to_val(ret)
++ > lin11_to_val(data->iout_max[page]))
++ data->iout_max[page] = ret;
++ ret = data->iout_max[page];
++ }
++ break;
++ case PMBUS_VIRT_READ_TEMP2_MAX:
++ ret = pmbus_read_word_data(client, page,
++ LTC3880_MFR_TEMPERATURE2_PEAK);
++ if (ret >= 0) {
++ if (lin11_to_val(ret) > lin11_to_val(data->temp2_max))
++ data->temp2_max = ret;
++ ret = data->temp2_max;
++ }
++ break;
++ case PMBUS_VIRT_READ_VIN_MIN:
++ case PMBUS_VIRT_READ_VOUT_MIN:
++ case PMBUS_VIRT_READ_TEMP_MIN:
++ ret = -ENXIO;
++ break;
++ case PMBUS_VIRT_RESET_IOUT_HISTORY:
++ case PMBUS_VIRT_RESET_TEMP2_HISTORY:
++ ret = 0;
++ break;
++ default:
++ ret = ltc2978_read_word_data_common(client, page, reg);
++ break;
++ }
++ return ret;
++}
++
++static int ltc3883_read_word_data(struct i2c_client *client, int page, int reg)
++{
++ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
++ struct ltc2978_data *data = to_ltc2978_data(info);
++ int ret;
++
++ switch (reg) {
++ case PMBUS_VIRT_READ_IIN_MAX:
++ ret = pmbus_read_word_data(client, page, LTC3883_MFR_IIN_PEAK);
++ if (ret >= 0) {
++ if (lin11_to_val(ret)
++ > lin11_to_val(data->iin_max))
++ data->iin_max = ret;
++ ret = data->iin_max;
++ }
++ break;
++ case PMBUS_VIRT_RESET_IIN_HISTORY:
++ ret = 0;
++ break;
++ default:
++ ret = ltc3880_read_word_data(client, page, reg);
++ break;
++ }
++ return ret;
++}
++
++static int ltc2978_clear_peaks(struct i2c_client *client, int page,
++ enum chips id)
++{
++ int ret;
++
++ if (id == ltc3880 || id == ltc3883)
++ ret = pmbus_write_byte(client, 0, LTC3880_MFR_CLEAR_PEAKS);
++ else
++ ret = pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS);
++
++ return ret;
++}
++
++static int ltc2978_write_word_data(struct i2c_client *client, int page,
++ int reg, u16 word)
++{
++ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
++ struct ltc2978_data *data = to_ltc2978_data(info);
++ int ret;
++
++ switch (reg) {
++ case PMBUS_VIRT_RESET_IIN_HISTORY:
++ data->iin_max = 0x7c00;
++ ret = ltc2978_clear_peaks(client, page, data->id);
++ break;
++ case PMBUS_VIRT_RESET_IOUT_HISTORY:
++ data->iout_max[page] = 0x7c00;
++ data->iout_min[page] = 0xfbff;
++ ret = ltc2978_clear_peaks(client, page, data->id);
++ break;
++ case PMBUS_VIRT_RESET_TEMP2_HISTORY:
++ data->temp2_max = 0x7c00;
++ ret = ltc2978_clear_peaks(client, page, data->id);
++ break;
++ case PMBUS_VIRT_RESET_VOUT_HISTORY:
++ data->vout_min[page] = 0xffff;
++ data->vout_max[page] = 0;
++ ret = ltc2978_clear_peaks(client, page, data->id);
++ break;
++ case PMBUS_VIRT_RESET_VIN_HISTORY:
++ data->vin_min = 0x7bff;
++ data->vin_max = 0x7c00;
++ ret = ltc2978_clear_peaks(client, page, data->id);
++ break;
++ case PMBUS_VIRT_RESET_TEMP_HISTORY:
++ data->temp_min[page] = 0x7bff;
++ data->temp_max[page] = 0x7c00;
++ ret = ltc2978_clear_peaks(client, page, data->id);
++ break;
++ default:
++ ret = -ENODATA;
++ break;
++ }
++ return ret;
++}
++
++static const struct i2c_device_id ltc2978_id[] = {
++ {"ltc2974", ltc2974},
++ {"ltc2978", ltc2978},
++ {"ltc3880", ltc3880},
++ {"ltc3883", ltc3883},
++ {}
++};
++MODULE_DEVICE_TABLE(i2c, ltc2978_id);
++
++static int ltc2978_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ int chip_id, i;
++ struct ltc2978_data *data;
++ struct pmbus_driver_info *info;
++
++ if (!i2c_check_functionality(client->adapter,
++ I2C_FUNC_SMBUS_READ_WORD_DATA))
++ return -ENODEV;
++
++ data = devm_kzalloc(&client->dev, sizeof(struct ltc2978_data),
++ GFP_KERNEL);
++ if (!data)
++ return -ENOMEM;
++
++ chip_id = i2c_smbus_read_word_data(client, LTC2978_MFR_SPECIAL_ID);
++ if (chip_id < 0)
++ return chip_id;
++
++ if (chip_id == LTC2974_ID) {
++ data->id = ltc2974;
++ } else if (chip_id == LTC2978_ID_REV1 || chip_id == LTC2978_ID_REV2) {
++ data->id = ltc2978;
++ } else if ((chip_id & LTC3880_ID_MASK) == LTC3880_ID) {
++ data->id = ltc3880;
++ } else if ((chip_id & LTC3883_ID_MASK) == LTC3883_ID) {
++ data->id = ltc3883;
++ } else {
++ dev_err(&client->dev, "Unsupported chip ID 0x%x\n", chip_id);
++ return -ENODEV;
++ }
++ if (data->id != id->driver_data)
++ dev_warn(&client->dev,
++ "Device mismatch: Configured %s, detected %s\n",
++ id->name,
++ ltc2978_id[data->id].name);
++
++ info = &data->info;
++ info->write_word_data = ltc2978_write_word_data;
++
++ data->vin_min = 0x7bff;
++ data->vin_max = 0x7c00;
++ for (i = 0; i < ARRAY_SIZE(data->vout_min); i++)
++ data->vout_min[i] = 0xffff;
++ for (i = 0; i < ARRAY_SIZE(data->iout_min); i++)
++ data->iout_min[i] = 0xfbff;
++ for (i = 0; i < ARRAY_SIZE(data->iout_max); i++)
++ data->iout_max[i] = 0x7c00;
++ for (i = 0; i < ARRAY_SIZE(data->temp_min); i++)
++ data->temp_min[i] = 0x7bff;
++ for (i = 0; i < ARRAY_SIZE(data->temp_max); i++)
++ data->temp_max[i] = 0x7c00;
++ data->temp2_max = 0x7c00;
++
++ switch (data->id) {
++ case ltc2974:
++ info->read_word_data = ltc2974_read_word_data;
++ info->pages = LTC2974_NUM_PAGES;
++ info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT
++ | PMBUS_HAVE_TEMP2;
++ for (i = 0; i < info->pages; i++) {
++ info->func[i] |= PMBUS_HAVE_VOUT
++ | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_POUT
++ | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP
++ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT;
++ }
++ break;
++ case ltc2978:
++ info->read_word_data = ltc2978_read_word_data;
++ info->pages = LTC2978_NUM_PAGES;
++ info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT
++ | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
++ | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
++ for (i = 1; i < LTC2978_NUM_PAGES; i++) {
++ info->func[i] = PMBUS_HAVE_VOUT
++ | PMBUS_HAVE_STATUS_VOUT;
++ }
++ break;
++ case ltc3880:
++ info->read_word_data = ltc3880_read_word_data;
++ info->pages = LTC3880_NUM_PAGES;
++ info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN
++ | PMBUS_HAVE_STATUS_INPUT
++ | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
++ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
++ | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP
++ | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP;
++ info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
++ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
++ | PMBUS_HAVE_POUT
++ | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
++ break;
++ case ltc3883:
++ info->read_word_data = ltc3883_read_word_data;
++ info->pages = LTC3883_NUM_PAGES;
++ info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN
++ | PMBUS_HAVE_STATUS_INPUT
++ | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
++ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
++ | PMBUS_HAVE_PIN | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP
++ | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP;
++ break;
++ default:
++ return -ENODEV;
++ }
++ return pmbus_do_probe(client, id, info);
++}
++
++/* This is the driver that will be inserted */
++static struct i2c_driver ltc2978_driver = {
++ .driver = {
++ .name = "ltc2978",
++ },
++ .probe = ltc2978_probe,
++ .remove = pmbus_do_remove,
++ .id_table = ltc2978_id,
++};
++
++module_i2c_driver(ltc2978_driver);
++
++MODULE_AUTHOR("Guenter Roeck");
++MODULE_DESCRIPTION("PMBus driver for LTC2974, LTC2978, LTC3880, and LTC3883");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/hwmon/pmbus/max16064.c b/drivers/hwmon/pmbus/max16064.c
+new file mode 100644
+index 0000000..fa237a3
+--- /dev/null
++++ b/drivers/hwmon/pmbus/max16064.c
+@@ -0,0 +1,127 @@
++/*
++ * Hardware monitoring driver for Maxim MAX16064
++ *
++ * Copyright (c) 2011 Ericsson AB.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/err.h>
++#include <linux/i2c.h>
++#include "pmbus.h"
++
++#define MAX16064_MFR_VOUT_PEAK 0xd4
++#define MAX16064_MFR_TEMPERATURE_PEAK 0xd6
++
++static int max16064_read_word_data(struct i2c_client *client, int page, int reg)
++{
++ int ret;
++
++ switch (reg) {
++ case PMBUS_VIRT_READ_VOUT_MAX:
++ ret = pmbus_read_word_data(client, page,
++ MAX16064_MFR_VOUT_PEAK);
++ break;
++ case PMBUS_VIRT_READ_TEMP_MAX:
++ ret = pmbus_read_word_data(client, page,
++ MAX16064_MFR_TEMPERATURE_PEAK);
++ break;
++ case PMBUS_VIRT_RESET_VOUT_HISTORY:
++ case PMBUS_VIRT_RESET_TEMP_HISTORY:
++ ret = 0;
++ break;
++ default:
++ ret = -ENODATA;
++ break;
++ }
++ return ret;
++}
++
++static int max16064_write_word_data(struct i2c_client *client, int page,
++ int reg, u16 word)
++{
++ int ret;
++
++ switch (reg) {
++ case PMBUS_VIRT_RESET_VOUT_HISTORY:
++ ret = pmbus_write_word_data(client, page,
++ MAX16064_MFR_VOUT_PEAK, 0);
++ break;
++ case PMBUS_VIRT_RESET_TEMP_HISTORY:
++ ret = pmbus_write_word_data(client, page,
++ MAX16064_MFR_TEMPERATURE_PEAK,
++ 0xffff);
++ break;
++ default:
++ ret = -ENODATA;
++ break;
++ }
++ return ret;
++}
++
++static struct pmbus_driver_info max16064_info = {
++ .pages = 4,
++ .format[PSC_VOLTAGE_IN] = direct,
++ .format[PSC_VOLTAGE_OUT] = direct,
++ .format[PSC_TEMPERATURE] = direct,
++ .m[PSC_VOLTAGE_IN] = 19995,
++ .b[PSC_VOLTAGE_IN] = 0,
++ .R[PSC_VOLTAGE_IN] = -1,
++ .m[PSC_VOLTAGE_OUT] = 19995,
++ .b[PSC_VOLTAGE_OUT] = 0,
++ .R[PSC_VOLTAGE_OUT] = -1,
++ .m[PSC_TEMPERATURE] = -7612,
++ .b[PSC_TEMPERATURE] = 335,
++ .R[PSC_TEMPERATURE] = -3,
++ .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_TEMP
++ | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_TEMP,
++ .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .read_word_data = max16064_read_word_data,
++ .write_word_data = max16064_write_word_data,
++};
++
++static int max16064_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ return pmbus_do_probe(client, id, &max16064_info);
++}
++
++static const struct i2c_device_id max16064_id[] = {
++ {"max16064", 0},
++ {}
++};
++
++MODULE_DEVICE_TABLE(i2c, max16064_id);
++
++/* This is the driver that will be inserted */
++static struct i2c_driver max16064_driver = {
++ .driver = {
++ .name = "max16064",
++ },
++ .probe = max16064_probe,
++ .remove = pmbus_do_remove,
++ .id_table = max16064_id,
++};
++
++module_i2c_driver(max16064_driver);
++
++MODULE_AUTHOR("Guenter Roeck");
++MODULE_DESCRIPTION("PMBus driver for Maxim MAX16064");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/hwmon/pmbus/max34440.c b/drivers/hwmon/pmbus/max34440.c
+new file mode 100644
+index 0000000..7e930c3
+--- /dev/null
++++ b/drivers/hwmon/pmbus/max34440.c
+@@ -0,0 +1,435 @@
++/*
++ * Hardware monitoring driver for Maxim MAX34440/MAX34441
++ *
++ * Copyright (c) 2011 Ericsson AB.
++ * Copyright (c) 2012 Guenter Roeck
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/err.h>
++#include <linux/i2c.h>
++#include "pmbus.h"
++
++enum chips { max34440, max34441, max34446, max34460, max34461 };
++
++#define MAX34440_MFR_VOUT_PEAK 0xd4
++#define MAX34440_MFR_IOUT_PEAK 0xd5
++#define MAX34440_MFR_TEMPERATURE_PEAK 0xd6
++#define MAX34440_MFR_VOUT_MIN 0xd7
++
++#define MAX34446_MFR_POUT_PEAK 0xe0
++#define MAX34446_MFR_POUT_AVG 0xe1
++#define MAX34446_MFR_IOUT_AVG 0xe2
++#define MAX34446_MFR_TEMPERATURE_AVG 0xe3
++
++#define MAX34440_STATUS_OC_WARN (1 << 0)
++#define MAX34440_STATUS_OC_FAULT (1 << 1)
++#define MAX34440_STATUS_OT_FAULT (1 << 5)
++#define MAX34440_STATUS_OT_WARN (1 << 6)
++
++struct max34440_data {
++ int id;
++ struct pmbus_driver_info info;
++};
++
++#define to_max34440_data(x) container_of(x, struct max34440_data, info)
++
++static int max34440_read_word_data(struct i2c_client *client, int page, int reg)
++{
++ int ret;
++ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
++ const struct max34440_data *data = to_max34440_data(info);
++
++ switch (reg) {
++ case PMBUS_VIRT_READ_VOUT_MIN:
++ ret = pmbus_read_word_data(client, page,
++ MAX34440_MFR_VOUT_MIN);
++ break;
++ case PMBUS_VIRT_READ_VOUT_MAX:
++ ret = pmbus_read_word_data(client, page,
++ MAX34440_MFR_VOUT_PEAK);
++ break;
++ case PMBUS_VIRT_READ_IOUT_AVG:
++ if (data->id != max34446)
++ return -ENXIO;
++ ret = pmbus_read_word_data(client, page,
++ MAX34446_MFR_IOUT_AVG);
++ break;
++ case PMBUS_VIRT_READ_IOUT_MAX:
++ ret = pmbus_read_word_data(client, page,
++ MAX34440_MFR_IOUT_PEAK);
++ break;
++ case PMBUS_VIRT_READ_POUT_AVG:
++ if (data->id != max34446)
++ return -ENXIO;
++ ret = pmbus_read_word_data(client, page,
++ MAX34446_MFR_POUT_AVG);
++ break;
++ case PMBUS_VIRT_READ_POUT_MAX:
++ if (data->id != max34446)
++ return -ENXIO;
++ ret = pmbus_read_word_data(client, page,
++ MAX34446_MFR_POUT_PEAK);
++ break;
++ case PMBUS_VIRT_READ_TEMP_AVG:
++ if (data->id != max34446 && data->id != max34460 &&
++ data->id != max34461)
++ return -ENXIO;
++ ret = pmbus_read_word_data(client, page,
++ MAX34446_MFR_TEMPERATURE_AVG);
++ break;
++ case PMBUS_VIRT_READ_TEMP_MAX:
++ ret = pmbus_read_word_data(client, page,
++ MAX34440_MFR_TEMPERATURE_PEAK);
++ break;
++ case PMBUS_VIRT_RESET_POUT_HISTORY:
++ if (data->id != max34446)
++ return -ENXIO;
++ ret = 0;
++ break;
++ case PMBUS_VIRT_RESET_VOUT_HISTORY:
++ case PMBUS_VIRT_RESET_IOUT_HISTORY:
++ case PMBUS_VIRT_RESET_TEMP_HISTORY:
++ ret = 0;
++ break;
++ default:
++ ret = -ENODATA;
++ break;
++ }
++ return ret;
++}
++
++static int max34440_write_word_data(struct i2c_client *client, int page,
++ int reg, u16 word)
++{
++ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
++ const struct max34440_data *data = to_max34440_data(info);
++ int ret;
++
++ switch (reg) {
++ case PMBUS_VIRT_RESET_POUT_HISTORY:
++ ret = pmbus_write_word_data(client, page,
++ MAX34446_MFR_POUT_PEAK, 0);
++ if (ret)
++ break;
++ ret = pmbus_write_word_data(client, page,
++ MAX34446_MFR_POUT_AVG, 0);
++ break;
++ case PMBUS_VIRT_RESET_VOUT_HISTORY:
++ ret = pmbus_write_word_data(client, page,
++ MAX34440_MFR_VOUT_MIN, 0x7fff);
++ if (ret)
++ break;
++ ret = pmbus_write_word_data(client, page,
++ MAX34440_MFR_VOUT_PEAK, 0);
++ break;
++ case PMBUS_VIRT_RESET_IOUT_HISTORY:
++ ret = pmbus_write_word_data(client, page,
++ MAX34440_MFR_IOUT_PEAK, 0);
++ if (!ret && data->id == max34446)
++ ret = pmbus_write_word_data(client, page,
++ MAX34446_MFR_IOUT_AVG, 0);
++
++ break;
++ case PMBUS_VIRT_RESET_TEMP_HISTORY:
++ ret = pmbus_write_word_data(client, page,
++ MAX34440_MFR_TEMPERATURE_PEAK,
++ 0x8000);
++ if (!ret && data->id == max34446)
++ ret = pmbus_write_word_data(client, page,
++ MAX34446_MFR_TEMPERATURE_AVG, 0);
++ break;
++ default:
++ ret = -ENODATA;
++ break;
++ }
++ return ret;
++}
++
++static int max34440_read_byte_data(struct i2c_client *client, int page, int reg)
++{
++ int ret = 0;
++ int mfg_status;
++
++ if (page >= 0) {
++ ret = pmbus_set_page(client, page);
++ if (ret < 0)
++ return ret;
++ }
++
++ switch (reg) {
++ case PMBUS_STATUS_IOUT:
++ mfg_status = pmbus_read_word_data(client, 0,
++ PMBUS_STATUS_MFR_SPECIFIC);
++ if (mfg_status < 0)
++ return mfg_status;
++ if (mfg_status & MAX34440_STATUS_OC_WARN)
++ ret |= PB_IOUT_OC_WARNING;
++ if (mfg_status & MAX34440_STATUS_OC_FAULT)
++ ret |= PB_IOUT_OC_FAULT;
++ break;
++ case PMBUS_STATUS_TEMPERATURE:
++ mfg_status = pmbus_read_word_data(client, 0,
++ PMBUS_STATUS_MFR_SPECIFIC);
++ if (mfg_status < 0)
++ return mfg_status;
++ if (mfg_status & MAX34440_STATUS_OT_WARN)
++ ret |= PB_TEMP_OT_WARNING;
++ if (mfg_status & MAX34440_STATUS_OT_FAULT)
++ ret |= PB_TEMP_OT_FAULT;
++ break;
++ default:
++ ret = -ENODATA;
++ break;
++ }
++ return ret;
++}
++
++static struct pmbus_driver_info max34440_info[] = {
++ [max34440] = {
++ .pages = 14,
++ .format[PSC_VOLTAGE_IN] = direct,
++ .format[PSC_VOLTAGE_OUT] = direct,
++ .format[PSC_TEMPERATURE] = direct,
++ .format[PSC_CURRENT_OUT] = direct,
++ .m[PSC_VOLTAGE_IN] = 1,
++ .b[PSC_VOLTAGE_IN] = 0,
++ .R[PSC_VOLTAGE_IN] = 3, /* R = 0 in datasheet reflects mV */
++ .m[PSC_VOLTAGE_OUT] = 1,
++ .b[PSC_VOLTAGE_OUT] = 0,
++ .R[PSC_VOLTAGE_OUT] = 3, /* R = 0 in datasheet reflects mV */
++ .m[PSC_CURRENT_OUT] = 1,
++ .b[PSC_CURRENT_OUT] = 0,
++ .R[PSC_CURRENT_OUT] = 3, /* R = 0 in datasheet reflects mA */
++ .m[PSC_TEMPERATURE] = 1,
++ .b[PSC_TEMPERATURE] = 0,
++ .R[PSC_TEMPERATURE] = 2,
++ .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
++ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
++ .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
++ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
++ .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
++ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
++ .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
++ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
++ .func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
++ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
++ .func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
++ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
++ .func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .func[7] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .func[8] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .func[9] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .func[10] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .func[12] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .func[13] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .read_byte_data = max34440_read_byte_data,
++ .read_word_data = max34440_read_word_data,
++ .write_word_data = max34440_write_word_data,
++ },
++ [max34441] = {
++ .pages = 12,
++ .format[PSC_VOLTAGE_IN] = direct,
++ .format[PSC_VOLTAGE_OUT] = direct,
++ .format[PSC_TEMPERATURE] = direct,
++ .format[PSC_CURRENT_OUT] = direct,
++ .format[PSC_FAN] = direct,
++ .m[PSC_VOLTAGE_IN] = 1,
++ .b[PSC_VOLTAGE_IN] = 0,
++ .R[PSC_VOLTAGE_IN] = 3,
++ .m[PSC_VOLTAGE_OUT] = 1,
++ .b[PSC_VOLTAGE_OUT] = 0,
++ .R[PSC_VOLTAGE_OUT] = 3,
++ .m[PSC_CURRENT_OUT] = 1,
++ .b[PSC_CURRENT_OUT] = 0,
++ .R[PSC_CURRENT_OUT] = 3,
++ .m[PSC_TEMPERATURE] = 1,
++ .b[PSC_TEMPERATURE] = 0,
++ .R[PSC_TEMPERATURE] = 2,
++ .m[PSC_FAN] = 1,
++ .b[PSC_FAN] = 0,
++ .R[PSC_FAN] = 0,
++ .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
++ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
++ .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
++ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
++ .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
++ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
++ .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
++ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
++ .func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
++ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
++ .func[5] = PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12,
++ .func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .func[7] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .func[8] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .func[9] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .func[10] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .read_byte_data = max34440_read_byte_data,
++ .read_word_data = max34440_read_word_data,
++ .write_word_data = max34440_write_word_data,
++ },
++ [max34446] = {
++ .pages = 7,
++ .format[PSC_VOLTAGE_IN] = direct,
++ .format[PSC_VOLTAGE_OUT] = direct,
++ .format[PSC_TEMPERATURE] = direct,
++ .format[PSC_CURRENT_OUT] = direct,
++ .format[PSC_POWER] = direct,
++ .m[PSC_VOLTAGE_IN] = 1,
++ .b[PSC_VOLTAGE_IN] = 0,
++ .R[PSC_VOLTAGE_IN] = 3,
++ .m[PSC_VOLTAGE_OUT] = 1,
++ .b[PSC_VOLTAGE_OUT] = 0,
++ .R[PSC_VOLTAGE_OUT] = 3,
++ .m[PSC_CURRENT_OUT] = 1,
++ .b[PSC_CURRENT_OUT] = 0,
++ .R[PSC_CURRENT_OUT] = 3,
++ .m[PSC_POWER] = 1,
++ .b[PSC_POWER] = 0,
++ .R[PSC_POWER] = 3,
++ .m[PSC_TEMPERATURE] = 1,
++ .b[PSC_TEMPERATURE] = 0,
++ .R[PSC_TEMPERATURE] = 2,
++ .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
++ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
++ .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
++ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
++ .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
++ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
++ .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
++ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
++ .func[4] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .func[5] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .read_byte_data = max34440_read_byte_data,
++ .read_word_data = max34440_read_word_data,
++ .write_word_data = max34440_write_word_data,
++ },
++ [max34460] = {
++ .pages = 18,
++ .format[PSC_VOLTAGE_OUT] = direct,
++ .format[PSC_TEMPERATURE] = direct,
++ .m[PSC_VOLTAGE_OUT] = 1,
++ .b[PSC_VOLTAGE_OUT] = 0,
++ .R[PSC_VOLTAGE_OUT] = 3,
++ .m[PSC_TEMPERATURE] = 1,
++ .b[PSC_TEMPERATURE] = 0,
++ .R[PSC_TEMPERATURE] = 2,
++ .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[6] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[7] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[8] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[9] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[10] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[11] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[13] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .func[14] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .func[15] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .func[16] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .read_byte_data = max34440_read_byte_data,
++ .read_word_data = max34440_read_word_data,
++ .write_word_data = max34440_write_word_data,
++ },
++ [max34461] = {
++ .pages = 23,
++ .format[PSC_VOLTAGE_OUT] = direct,
++ .format[PSC_TEMPERATURE] = direct,
++ .m[PSC_VOLTAGE_OUT] = 1,
++ .b[PSC_VOLTAGE_OUT] = 0,
++ .R[PSC_VOLTAGE_OUT] = 3,
++ .m[PSC_TEMPERATURE] = 1,
++ .b[PSC_TEMPERATURE] = 0,
++ .R[PSC_TEMPERATURE] = 2,
++ .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[6] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[7] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[8] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[9] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[10] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[11] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[12] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[13] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[14] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ .func[15] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
++ /* page 16 is reserved */
++ .func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .func[18] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .func[19] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .func[20] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .func[21] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
++ .read_byte_data = max34440_read_byte_data,
++ .read_word_data = max34440_read_word_data,
++ .write_word_data = max34440_write_word_data,
++ },
++};
++
++static int max34440_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ struct max34440_data *data;
++
++ data = devm_kzalloc(&client->dev, sizeof(struct max34440_data),
++ GFP_KERNEL);
++ if (!data)
++ return -ENOMEM;
++ data->id = id->driver_data;
++ data->info = max34440_info[id->driver_data];
++
++ return pmbus_do_probe(client, id, &data->info);
++}
++
++static const struct i2c_device_id max34440_id[] = {
++ {"max34440", max34440},
++ {"max34441", max34441},
++ {"max34446", max34446},
++ {"max34460", max34460},
++ {"max34461", max34461},
++ {}
++};
++MODULE_DEVICE_TABLE(i2c, max34440_id);
++
++/* This is the driver that will be inserted */
++static struct i2c_driver max34440_driver = {
++ .driver = {
++ .name = "max34440",
++ },
++ .probe = max34440_probe,
++ .remove = pmbus_do_remove,
++ .id_table = max34440_id,
++};
++
++module_i2c_driver(max34440_driver);
++
++MODULE_AUTHOR("Guenter Roeck");
++MODULE_DESCRIPTION("PMBus driver for Maxim MAX34440/MAX34441");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/hwmon/pmbus/max8688.c b/drivers/hwmon/pmbus/max8688.c
+new file mode 100644
+index 0000000..f04454a
+--- /dev/null
++++ b/drivers/hwmon/pmbus/max8688.c
+@@ -0,0 +1,204 @@
++/*
++ * Hardware monitoring driver for Maxim MAX8688
++ *
++ * Copyright (c) 2011 Ericsson AB.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/err.h>
++#include <linux/i2c.h>
++#include "pmbus.h"
++
++#define MAX8688_MFR_VOUT_PEAK 0xd4
++#define MAX8688_MFR_IOUT_PEAK 0xd5
++#define MAX8688_MFR_TEMPERATURE_PEAK 0xd6
++#define MAX8688_MFG_STATUS 0xd8
++
++#define MAX8688_STATUS_OC_FAULT (1 << 4)
++#define MAX8688_STATUS_OV_FAULT (1 << 5)
++#define MAX8688_STATUS_OV_WARNING (1 << 8)
++#define MAX8688_STATUS_UV_FAULT (1 << 9)
++#define MAX8688_STATUS_UV_WARNING (1 << 10)
++#define MAX8688_STATUS_UC_FAULT (1 << 11)
++#define MAX8688_STATUS_OC_WARNING (1 << 12)
++#define MAX8688_STATUS_OT_FAULT (1 << 13)
++#define MAX8688_STATUS_OT_WARNING (1 << 14)
++
++static int max8688_read_word_data(struct i2c_client *client, int page, int reg)
++{
++ int ret;
++
++ if (page)
++ return -ENXIO;
++
++ switch (reg) {
++ case PMBUS_VIRT_READ_VOUT_MAX:
++ ret = pmbus_read_word_data(client, 0, MAX8688_MFR_VOUT_PEAK);
++ break;
++ case PMBUS_VIRT_READ_IOUT_MAX:
++ ret = pmbus_read_word_data(client, 0, MAX8688_MFR_IOUT_PEAK);
++ break;
++ case PMBUS_VIRT_READ_TEMP_MAX:
++ ret = pmbus_read_word_data(client, 0,
++ MAX8688_MFR_TEMPERATURE_PEAK);
++ break;
++ case PMBUS_VIRT_RESET_VOUT_HISTORY:
++ case PMBUS_VIRT_RESET_IOUT_HISTORY:
++ case PMBUS_VIRT_RESET_TEMP_HISTORY:
++ ret = 0;
++ break;
++ default:
++ ret = -ENODATA;
++ break;
++ }
++ return ret;
++}
++
++static int max8688_write_word_data(struct i2c_client *client, int page, int reg,
++ u16 word)
++{
++ int ret;
++
++ switch (reg) {
++ case PMBUS_VIRT_RESET_VOUT_HISTORY:
++ ret = pmbus_write_word_data(client, 0, MAX8688_MFR_VOUT_PEAK,
++ 0);
++ break;
++ case PMBUS_VIRT_RESET_IOUT_HISTORY:
++ ret = pmbus_write_word_data(client, 0, MAX8688_MFR_IOUT_PEAK,
++ 0);
++ break;
++ case PMBUS_VIRT_RESET_TEMP_HISTORY:
++ ret = pmbus_write_word_data(client, 0,
++ MAX8688_MFR_TEMPERATURE_PEAK,
++ 0xffff);
++ break;
++ default:
++ ret = -ENODATA;
++ break;
++ }
++ return ret;
++}
++
++static int max8688_read_byte_data(struct i2c_client *client, int page, int reg)
++{
++ int ret = 0;
++ int mfg_status;
++
++ if (page > 0)
++ return -ENXIO;
++
++ switch (reg) {
++ case PMBUS_STATUS_VOUT:
++ mfg_status = pmbus_read_word_data(client, 0,
++ MAX8688_MFG_STATUS);
++ if (mfg_status < 0)
++ return mfg_status;
++ if (mfg_status & MAX8688_STATUS_UV_WARNING)
++ ret |= PB_VOLTAGE_UV_WARNING;
++ if (mfg_status & MAX8688_STATUS_UV_FAULT)
++ ret |= PB_VOLTAGE_UV_FAULT;
++ if (mfg_status & MAX8688_STATUS_OV_WARNING)
++ ret |= PB_VOLTAGE_OV_WARNING;
++ if (mfg_status & MAX8688_STATUS_OV_FAULT)
++ ret |= PB_VOLTAGE_OV_FAULT;
++ break;
++ case PMBUS_STATUS_IOUT:
++ mfg_status = pmbus_read_word_data(client, 0,
++ MAX8688_MFG_STATUS);
++ if (mfg_status < 0)
++ return mfg_status;
++ if (mfg_status & MAX8688_STATUS_UC_FAULT)
++ ret |= PB_IOUT_UC_FAULT;
++ if (mfg_status & MAX8688_STATUS_OC_WARNING)
++ ret |= PB_IOUT_OC_WARNING;
++ if (mfg_status & MAX8688_STATUS_OC_FAULT)
++ ret |= PB_IOUT_OC_FAULT;
++ break;
++ case PMBUS_STATUS_TEMPERATURE:
++ mfg_status = pmbus_read_word_data(client, 0,
++ MAX8688_MFG_STATUS);
++ if (mfg_status < 0)
++ return mfg_status;
++ if (mfg_status & MAX8688_STATUS_OT_WARNING)
++ ret |= PB_TEMP_OT_WARNING;
++ if (mfg_status & MAX8688_STATUS_OT_FAULT)
++ ret |= PB_TEMP_OT_FAULT;
++ break;
++ default:
++ ret = -ENODATA;
++ break;
++ }
++ return ret;
++}
++
++static struct pmbus_driver_info max8688_info = {
++ .pages = 1,
++ .format[PSC_VOLTAGE_IN] = direct,
++ .format[PSC_VOLTAGE_OUT] = direct,
++ .format[PSC_TEMPERATURE] = direct,
++ .format[PSC_CURRENT_OUT] = direct,
++ .m[PSC_VOLTAGE_IN] = 19995,
++ .b[PSC_VOLTAGE_IN] = 0,
++ .R[PSC_VOLTAGE_IN] = -1,
++ .m[PSC_VOLTAGE_OUT] = 19995,
++ .b[PSC_VOLTAGE_OUT] = 0,
++ .R[PSC_VOLTAGE_OUT] = -1,
++ .m[PSC_CURRENT_OUT] = 23109,
++ .b[PSC_CURRENT_OUT] = 0,
++ .R[PSC_CURRENT_OUT] = -2,
++ .m[PSC_TEMPERATURE] = -7612,
++ .b[PSC_TEMPERATURE] = 335,
++ .R[PSC_TEMPERATURE] = -3,
++ .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | PMBUS_HAVE_TEMP
++ | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT
++ | PMBUS_HAVE_STATUS_TEMP,
++ .read_byte_data = max8688_read_byte_data,
++ .read_word_data = max8688_read_word_data,
++ .write_word_data = max8688_write_word_data,
++};
++
++static int max8688_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ return pmbus_do_probe(client, id, &max8688_info);
++}
++
++static const struct i2c_device_id max8688_id[] = {
++ {"max8688", 0},
++ { }
++};
++
++MODULE_DEVICE_TABLE(i2c, max8688_id);
++
++/* This is the driver that will be inserted */
++static struct i2c_driver max8688_driver = {
++ .driver = {
++ .name = "max8688",
++ },
++ .probe = max8688_probe,
++ .remove = pmbus_do_remove,
++ .id_table = max8688_id,
++};
++
++module_i2c_driver(max8688_driver);
++
++MODULE_AUTHOR("Guenter Roeck");
++MODULE_DESCRIPTION("PMBus driver for Maxim MAX8688");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/hwmon/pmbus/pfe1100.c b/drivers/hwmon/pmbus/pfe1100.c
+new file mode 100644
+index 0000000..3731fa0
+--- /dev/null
++++ b/drivers/hwmon/pmbus/pfe1100.c
+@@ -0,0 +1,249 @@
++/*
++ * Hardware monitoring driver for PFE1100 and compatibles
++ * Based on the zl6100 driver with the following copyright:
++ *
++ * Copyright (c) 2011 Ericsson AB.
++ * Copyright (c) 2012 Guenter Roeck
++ * Copyright 2004-present Facebook. All Rights Reserved.
++ *
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/err.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include <linux/ktime.h>
++#include <linux/delay.h>
++#include "pmbus.h"
++
++enum chips { SPDFCBK_15G, SPAFCBK_14G };
++
++struct pfe1100_data {
++ int id;
++ struct pmbus_driver_info info;
++};
++
++#define to_pfe1100_data(x) container_of(x, struct pfe1100_data, info)
++
++
++#define PFE1100_WAIT_TIME 5000 /* uS */
++
++static ushort delay = PFE1100_WAIT_TIME;
++module_param(delay, ushort, 0644);
++MODULE_PARM_DESC(delay, "Delay between chip accesses in uS");
++
++static const struct i2c_device_id pfe1100_id[] = {
++ {"pfe1100dc", SPDFCBK_15G},
++ {"pfe1100ac", SPAFCBK_14G},
++ {"pfe1100", 0},
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, pfe1100_id);
++
++static int pfe1100_read_word_data(struct i2c_client *client, int page, int reg)
++{
++ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
++ struct pfe1100_data *data = to_pfe1100_data(info);
++ int ret;
++
++ if (data->id != SPAFCBK_14G && page > 0)
++ return -ENXIO;
++
++ if (reg >= PMBUS_VIRT_BASE)
++ return -ENXIO;
++
++ switch (reg) {
++ case PMBUS_FAN_COMMAND_1:
++ case PMBUS_STATUS_WORD:
++ case PMBUS_READ_VIN:
++ case PMBUS_READ_IIN:
++ case PMBUS_READ_VOUT:
++ case PMBUS_READ_IOUT:
++ case PMBUS_READ_TEMPERATURE_1:
++ case PMBUS_READ_TEMPERATURE_2:
++ case PMBUS_READ_TEMPERATURE_3:
++ case PMBUS_READ_FAN_SPEED_1:
++ case PMBUS_READ_POUT:
++ case PMBUS_READ_PIN:
++ case PMBUS_MFR_LOCATION:
++ ret = pmbus_read_word_data(client, page, reg);
++ return ret;
++ default:
++ return -ENXIO;
++ }
++}
++
++static int pfe1100_read_byte_data(struct i2c_client *client, int page, int reg)
++{
++ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
++ struct pfe1100_data *data = to_pfe1100_data(info);
++ int ret;
++
++ if (data->id != SPAFCBK_14G && page > 0)
++ return -ENXIO;
++
++ switch (reg) {
++ case PMBUS_PAGE:
++ case PMBUS_OPERATION:
++ case PMBUS_CLEAR_FAULTS:
++ case PMBUS_CAPABILITY:
++ case PMBUS_VOUT_MODE:
++ case PMBUS_FAN_CONFIG_12:
++ case PMBUS_STATUS_BYTE:
++ case PMBUS_STATUS_VOUT:
++ case PMBUS_STATUS_IOUT:
++ case PMBUS_STATUS_INPUT:
++ case PMBUS_STATUS_TEMPERATURE:
++ case PMBUS_STATUS_CML:
++ case PMBUS_STATUS_OTHER:
++ case PMBUS_STATUS_MFR_SPECIFIC:
++ case PMBUS_STATUS_FAN_12:
++ ret = pmbus_read_byte_data(client, page, reg);
++ return ret;
++ default:
++ return -ENXIO;
++ }
++}
++
++static int pfe1100_write_word_data(struct i2c_client *client, int page, int reg,
++ u16 word)
++{
++ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
++ struct pfe1100_data *data = to_pfe1100_data(info);
++ int ret;
++
++ if (data->id != SPAFCBK_14G && page > 0)
++ return -ENXIO;
++
++ if (reg >= PMBUS_VIRT_BASE)
++ return -ENXIO;
++
++ if (reg == PMBUS_FAN_COMMAND_1)
++ ret = pmbus_write_word_data(client, page, reg, word);
++ else
++ ret = -ENXIO;
++
++ return ret;
++}
++
++static int pfe1100_write_byte(struct i2c_client *client, int page, u8 value)
++{
++ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
++ struct pfe1100_data *data = to_pfe1100_data(info);
++ int ret;
++
++ if (data->id != SPAFCBK_14G && page > 0)
++ return -ENXIO;
++
++ switch (value) {
++ case PMBUS_PAGE:
++ case PMBUS_OPERATION:
++ case PMBUS_CLEAR_FAULTS:
++ ret = pmbus_write_byte(client, page, value);
++ return ret;
++ default:
++ return -ENXIO;
++ }
++}
++
++static int pfe1100_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ int ret;
++ int kind;
++ struct pfe1100_data *data;
++ struct pmbus_driver_info *info;
++ u8 device_id[I2C_SMBUS_BLOCK_MAX + 1];
++
++ if (!i2c_check_functionality(client->adapter,
++ I2C_FUNC_SMBUS_READ_WORD_DATA
++ | I2C_FUNC_SMBUS_READ_BLOCK_DATA))
++ return -ENODEV;
++
++ ret = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, device_id);
++ if (ret < 0) {
++ dev_err(&client->dev, "Failed to read Manufacturer ID\n");
++ kind = SPDFCBK_15G;
++ } else {
++ device_id[ret] = 0;
++ if (strncmp(device_id, "SPAFCBK-14G", ret))
++ kind = SPDFCBK_15G;
++ else
++ kind = SPAFCBK_14G;
++ dev_notice(&client->dev, "MFR_ID is [%s]\n", device_id);
++ }
++
++ data = devm_kzalloc(&client->dev, sizeof(struct pfe1100_data),
++ GFP_KERNEL);
++ if (!data)
++ return -ENOMEM;
++
++ data->id = kind;
++
++ info = &data->info;
++ info->delay = delay;
++ if (kind == SPAFCBK_14G)
++ info->pages = 2;
++ else
++ info->pages = 1;
++
++ /*
++ * It seems reasonable to just scan the device for supported
++ * values, but most drivers just seem to jam these values in
++ * there, so that's what we'll do.
++ */
++
++ info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_IIN |
++ PMBUS_HAVE_IOUT | PMBUS_HAVE_PIN | PMBUS_HAVE_POUT |
++ PMBUS_HAVE_FAN12 | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 |
++ PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT |
++ PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_STATUS_TEMP |
++ PMBUS_HAVE_STATUS_FAN12 | PMBUS_HAVE_MFRDATA;
++
++ /* AC units have a third temperature sensor, and data from 3V input: */
++
++ if (kind == SPAFCBK_14G) {
++ info->func[0] |= PMBUS_HAVE_TEMP3;
++ info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT |
++ PMBUS_HAVE_POUT | PMBUS_HAVE_STATUS_VOUT |
++ PMBUS_HAVE_STATUS_IOUT;
++ }
++
++ info->read_word_data = pfe1100_read_word_data;
++ info->read_byte_data = pfe1100_read_byte_data;
++ info->write_word_data = pfe1100_write_word_data;
++ info->write_byte = pfe1100_write_byte;
++
++ return pmbus_do_probe(client, id, info);
++}
++
++static struct i2c_driver pfe1100_driver = {
++ .driver = {
++ .name = "pfe1100",
++ },
++ .probe = pfe1100_probe,
++ .remove = pmbus_do_remove,
++ .id_table = pfe1100_id,
++};
++
++module_i2c_driver(pfe1100_driver);
++
++MODULE_AUTHOR("Kevin Lahey, based on work by Guenter Roeck");
++MODULE_DESCRIPTION("PMBus driver for PFE1100");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/hwmon/pmbus/pfe3000.c b/drivers/hwmon/pmbus/pfe3000.c
+new file mode 100644
+index 0000000..0ee2453
+--- /dev/null
++++ b/drivers/hwmon/pmbus/pfe3000.c
+@@ -0,0 +1,133 @@
++/*
++ * Hardware monitoring driver for PFE3000 and compatibles
++ * Based on the zl6100 driver with the following copyright:
++ *
++ * Copyright (c) 2011 Ericsson AB.
++ * Copyright (c) 2012 Guenter Roeck
++ * Copyright 2004-present Facebook. All Rights Reserved.
++ *
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/err.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include <linux/ktime.h>
++#include <linux/delay.h>
++#include <linux/i2c/pmbus.h>
++#include "pmbus.h"
++
++enum chips { PFE3000 };
++
++struct pfe3000_data {
++ struct pmbus_driver_info info;
++};
++
++#define to_pfe3000_data(x) container_of(x, struct pfe3000_data, info)
++
++/*
++ * Other PowerOne device require a wait time; this is included in case
++ * it is necessary for future debugging.
++ */
++
++#define PFE3000_WAIT_TIME 0 /* uS */
++
++static ushort delay = PFE3000_WAIT_TIME;
++module_param(delay, ushort, 0644);
++MODULE_PARM_DESC(delay, "Delay between chip accesses in uS");
++
++
++static const struct i2c_device_id pfe3000_id[] = {
++ {"pfe3000", PFE3000 },
++ {"pfe3000", 0},
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, pfe3000_id);
++
++static struct pmbus_platform_data platform_data = {
++ .flags = PMBUS_SKIP_STATUS_CHECK
++};
++
++static int pfe3000_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ struct device *dev = &client->dev;
++ struct pfe3000_data *data;
++ struct pmbus_driver_info *info;
++
++ data = devm_kzalloc(&client->dev, sizeof(struct pfe3000_data),
++ GFP_KERNEL);
++ if (!data)
++ return -ENOMEM;
++
++ info = &data->info;
++ info->pages = 7;
++ info->delay = delay;
++
++ /*
++ * Skip extra status checks; this is required to read the
++ * VOUT_MODE register to determine the exponent to apply
++ * to the VOUT values.
++ */
++ dev->platform_data = &platform_data;
++
++ /* Make sure that the page isn't pointing elsewhere! */
++
++ i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0);
++
++ /*
++ * It seems reasonable to just scan the device for supported
++ * values, but most drivers seem to jam these values in
++ * there, so that's what we'll do.
++ */
++
++ info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_IIN |
++ PMBUS_HAVE_IOUT | PMBUS_HAVE_PIN | PMBUS_HAVE_POUT |
++ PMBUS_HAVE_FAN12 | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 |
++ PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_VOUT |
++ PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_STATUS_INPUT |
++ PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_STATUS_FAN12 |
++ PMBUS_HAVE_MFRDATA;
++ info->func[1] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_IIN |
++ PMBUS_HAVE_IOUT | PMBUS_HAVE_PIN | PMBUS_HAVE_POUT |
++ PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT |
++ PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_STATUS_FAN12 |
++ PMBUS_HAVE_STATUS_INPUT;
++ info->func[2] = PMBUS_HAVE_VOUT;
++ info->func[4] = PMBUS_HAVE_VOUT;
++ info->func[5] = PMBUS_HAVE_VOUT;
++ info->func[6] = PMBUS_HAVE_VOUT;
++
++ return pmbus_do_probe(client, id, info);
++}
++
++static struct i2c_driver pfe3000_driver = {
++ .driver = {
++ .name = "pfe3000",
++ },
++ .probe = pfe3000_probe,
++ .remove = pmbus_do_remove,
++ .id_table = pfe3000_id,
++};
++
++module_i2c_driver(pfe3000_driver);
++
++MODULE_AUTHOR("Kevin Lahey, based on work by Guenter Roeck");
++MODULE_DESCRIPTION("PMBus driver for PFE1100");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/hwmon/pmbus/pmbus.c b/drivers/hwmon/pmbus/pmbus.c
+new file mode 100644
+index 0000000..7e91700
+--- /dev/null
++++ b/drivers/hwmon/pmbus/pmbus.c
+@@ -0,0 +1,217 @@
++/*
++ * Hardware monitoring driver for PMBus devices
++ *
++ * Copyright (c) 2010, 2011 Ericsson AB.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/err.h>
++#include <linux/slab.h>
++#include <linux/mutex.h>
++#include <linux/i2c.h>
++#include "pmbus.h"
++
++/*
++ * Find sensor groups and status registers on each page.
++ */
++static void pmbus_find_sensor_groups(struct i2c_client *client,
++ struct pmbus_driver_info *info)
++{
++ int page;
++
++ /* Sensors detected on page 0 only */
++ if (pmbus_check_word_register(client, 0, PMBUS_READ_VIN))
++ info->func[0] |= PMBUS_HAVE_VIN;
++ if (pmbus_check_word_register(client, 0, PMBUS_READ_VCAP))
++ info->func[0] |= PMBUS_HAVE_VCAP;
++ if (pmbus_check_word_register(client, 0, PMBUS_READ_IIN))
++ info->func[0] |= PMBUS_HAVE_IIN;
++ if (pmbus_check_word_register(client, 0, PMBUS_READ_PIN))
++ info->func[0] |= PMBUS_HAVE_PIN;
++ if (info->func[0]
++ && pmbus_check_byte_register(client, 0, PMBUS_STATUS_INPUT))
++ info->func[0] |= PMBUS_HAVE_STATUS_INPUT;
++ if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_12) &&
++ pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) {
++ info->func[0] |= PMBUS_HAVE_FAN12;
++ if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_12))
++ info->func[0] |= PMBUS_HAVE_STATUS_FAN12;
++ }
++ if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_34) &&
++ pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_3)) {
++ info->func[0] |= PMBUS_HAVE_FAN34;
++ if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_34))
++ info->func[0] |= PMBUS_HAVE_STATUS_FAN34;
++ }
++ if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1))
++ info->func[0] |= PMBUS_HAVE_TEMP;
++ if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_2))
++ info->func[0] |= PMBUS_HAVE_TEMP2;
++ if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_3))
++ info->func[0] |= PMBUS_HAVE_TEMP3;
++ if (info->func[0] & (PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2
++ | PMBUS_HAVE_TEMP3)
++ && pmbus_check_byte_register(client, 0,
++ PMBUS_STATUS_TEMPERATURE))
++ info->func[0] |= PMBUS_HAVE_STATUS_TEMP;
++
++ /* Sensors detected on all pages */
++ for (page = 0; page < info->pages; page++) {
++ if (pmbus_check_word_register(client, page, PMBUS_READ_VOUT)) {
++ info->func[page] |= PMBUS_HAVE_VOUT;
++ if (pmbus_check_byte_register(client, page,
++ PMBUS_STATUS_VOUT))
++ info->func[page] |= PMBUS_HAVE_STATUS_VOUT;
++ }
++ if (pmbus_check_word_register(client, page, PMBUS_READ_IOUT)) {
++ info->func[page] |= PMBUS_HAVE_IOUT;
++ if (pmbus_check_byte_register(client, 0,
++ PMBUS_STATUS_IOUT))
++ info->func[page] |= PMBUS_HAVE_STATUS_IOUT;
++ }
++ if (pmbus_check_word_register(client, page, PMBUS_READ_POUT))
++ info->func[page] |= PMBUS_HAVE_POUT;
++ }
++}
++
++/*
++ * Identify chip parameters.
++ */
++static int pmbus_identify(struct i2c_client *client,
++ struct pmbus_driver_info *info)
++{
++ int ret = 0;
++
++ if (!info->pages) {
++ /*
++ * Check if the PAGE command is supported. If it is,
++ * keep setting the page number until it fails or until the
++ * maximum number of pages has been reached. Assume that
++ * this is the number of pages supported by the chip.
++ */
++ if (pmbus_check_byte_register(client, 0, PMBUS_PAGE)) {
++ int page;
++
++ for (page = 1; page < PMBUS_PAGES; page++) {
++ if (pmbus_set_page(client, page) < 0)
++ break;
++ }
++ pmbus_set_page(client, 0);
++ info->pages = page;
++ } else {
++ info->pages = 1;
++ }
++ }
++
++ if (pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) {
++ int vout_mode;
++
++ vout_mode = pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE);
++ if (vout_mode >= 0 && vout_mode != 0xff) {
++ switch (vout_mode >> 5) {
++ case 0:
++ break;
++ case 1:
++ info->format[PSC_VOLTAGE_OUT] = vid;
++ break;
++ case 2:
++ info->format[PSC_VOLTAGE_OUT] = direct;
++ break;
++ default:
++ ret = -ENODEV;
++ goto abort;
++ }
++ }
++ }
++
++ /*
++ * We should check if the COEFFICIENTS register is supported.
++ * If it is, and the chip is configured for direct mode, we can read
++ * the coefficients from the chip, one set per group of sensor
++ * registers.
++ *
++ * To do this, we will need access to a chip which actually supports the
++ * COEFFICIENTS command, since the command is too complex to implement
++ * without testing it. Until then, abort if a chip configured for direct
++ * mode was detected.
++ */
++ if (info->format[PSC_VOLTAGE_OUT] == direct) {
++ ret = -ENODEV;
++ goto abort;
++ }
++
++ /* Try to find sensor groups */
++ pmbus_find_sensor_groups(client, info);
++abort:
++ return ret;
++}
++
++static int pmbus_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ struct pmbus_driver_info *info;
++
++ info = devm_kzalloc(&client->dev, sizeof(struct pmbus_driver_info),
++ GFP_KERNEL);
++ if (!info)
++ return -ENOMEM;
++
++ info->pages = id->driver_data;
++ info->identify = pmbus_identify;
++
++ return pmbus_do_probe(client, id, info);
++}
++
++/*
++ * Use driver_data to set the number of pages supported by the chip.
++ */
++static const struct i2c_device_id pmbus_id[] = {
++ {"adp4000", 1},
++ {"bmr453", 1},
++ {"bmr454", 1},
++ {"mdt040", 1},
++ {"ncp4200", 1},
++ {"ncp4208", 1},
++ {"pdt003", 1},
++ {"pdt006", 1},
++ {"pdt012", 1},
++ {"pmbus", 0},
++ {"tps40400", 1},
++ {"tps40422", 2},
++ {"udt020", 1},
++ {}
++};
++
++MODULE_DEVICE_TABLE(i2c, pmbus_id);
++
++/* This is the driver that will be inserted */
++static struct i2c_driver pmbus_driver = {
++ .driver = {
++ .name = "pmbus",
++ },
++ .probe = pmbus_probe,
++ .remove = pmbus_do_remove,
++ .id_table = pmbus_id,
++};
++
++module_i2c_driver(pmbus_driver);
++
++MODULE_AUTHOR("Guenter Roeck");
++MODULE_DESCRIPTION("Generic PMBus driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h
+new file mode 100644
+index 0000000..a6b5fba
+--- /dev/null
++++ b/drivers/hwmon/pmbus/pmbus.h
+@@ -0,0 +1,413 @@
++/*
++ * pmbus.h - Common defines and structures for PMBus devices
++ *
++ * Copyright (c) 2010, 2011 Ericsson AB.
++ * Copyright (c) 2012 Guenter Roeck
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifndef PMBUS_H
++#define PMBUS_H
++
++/* KML: Hacks to make this work on 2.6.28. Ugh. */
++
++#define DIV_ROUND_CLOSEST(x, divisor)( \
++{ \
++ typeof(x) __x = x; \
++ typeof(divisor) __d = divisor; \
++ (((typeof(x))-1) > 0 || \
++ ((typeof(divisor))-1) > 0 || (__x) > 0) ? \
++ (((__x) + ((__d) / 2)) / (__d)) : \
++ (((__x) - ((__d) / 2)) / (__d)); \
++} \
++)
++
++
++#define module_i2c_driver(__i2c_driver) \
++ static int __init __i2c_driver##_init(void) {return i2c_add_driver(&__i2c_driver);} \
++ static void __exit __i2c_driver##_exit(void) {i2c_del_driver(&__i2c_driver);} \
++module_init(__i2c_driver##_init); \
++module_exit(__i2c_driver##_exit);
++
++/* KML: Those are all the hacks needed, surprisingly. */
++
++/*
++ * Registers
++ */
++#define PMBUS_PAGE 0x00
++#define PMBUS_OPERATION 0x01
++#define PMBUS_ON_OFF_CONFIG 0x02
++#define PMBUS_CLEAR_FAULTS 0x03
++#define PMBUS_PHASE 0x04
++
++#define PMBUS_CAPABILITY 0x19
++#define PMBUS_QUERY 0x1A
++
++#define PMBUS_VOUT_MODE 0x20
++#define PMBUS_VOUT_COMMAND 0x21
++#define PMBUS_VOUT_TRIM 0x22
++#define PMBUS_VOUT_CAL_OFFSET 0x23
++#define PMBUS_VOUT_MAX 0x24
++#define PMBUS_VOUT_MARGIN_HIGH 0x25
++#define PMBUS_VOUT_MARGIN_LOW 0x26
++#define PMBUS_VOUT_TRANSITION_RATE 0x27
++#define PMBUS_VOUT_DROOP 0x28
++#define PMBUS_VOUT_SCALE_LOOP 0x29
++#define PMBUS_VOUT_SCALE_MONITOR 0x2A
++
++#define PMBUS_COEFFICIENTS 0x30
++#define PMBUS_POUT_MAX 0x31
++
++#define PMBUS_FAN_CONFIG_12 0x3A
++#define PMBUS_FAN_COMMAND_1 0x3B
++#define PMBUS_FAN_COMMAND_2 0x3C
++#define PMBUS_FAN_CONFIG_34 0x3D
++#define PMBUS_FAN_COMMAND_3 0x3E
++#define PMBUS_FAN_COMMAND_4 0x3F
++
++#define PMBUS_VOUT_OV_FAULT_LIMIT 0x40
++#define PMBUS_VOUT_OV_FAULT_RESPONSE 0x41
++#define PMBUS_VOUT_OV_WARN_LIMIT 0x42
++#define PMBUS_VOUT_UV_WARN_LIMIT 0x43
++#define PMBUS_VOUT_UV_FAULT_LIMIT 0x44
++#define PMBUS_VOUT_UV_FAULT_RESPONSE 0x45
++#define PMBUS_IOUT_OC_FAULT_LIMIT 0x46
++#define PMBUS_IOUT_OC_FAULT_RESPONSE 0x47
++#define PMBUS_IOUT_OC_LV_FAULT_LIMIT 0x48
++#define PMBUS_IOUT_OC_LV_FAULT_RESPONSE 0x49
++#define PMBUS_IOUT_OC_WARN_LIMIT 0x4A
++#define PMBUS_IOUT_UC_FAULT_LIMIT 0x4B
++#define PMBUS_IOUT_UC_FAULT_RESPONSE 0x4C
++
++#define PMBUS_OT_FAULT_LIMIT 0x4F
++#define PMBUS_OT_FAULT_RESPONSE 0x50
++#define PMBUS_OT_WARN_LIMIT 0x51
++#define PMBUS_UT_WARN_LIMIT 0x52
++#define PMBUS_UT_FAULT_LIMIT 0x53
++#define PMBUS_UT_FAULT_RESPONSE 0x54
++#define PMBUS_VIN_OV_FAULT_LIMIT 0x55
++#define PMBUS_VIN_OV_FAULT_RESPONSE 0x56
++#define PMBUS_VIN_OV_WARN_LIMIT 0x57
++#define PMBUS_VIN_UV_WARN_LIMIT 0x58
++#define PMBUS_VIN_UV_FAULT_LIMIT 0x59
++
++#define PMBUS_IIN_OC_FAULT_LIMIT 0x5B
++#define PMBUS_IIN_OC_WARN_LIMIT 0x5D
++
++#define PMBUS_POUT_OP_FAULT_LIMIT 0x68
++#define PMBUS_POUT_OP_WARN_LIMIT 0x6A
++#define PMBUS_PIN_OP_WARN_LIMIT 0x6B
++
++#define PMBUS_STATUS_BYTE 0x78
++#define PMBUS_STATUS_WORD 0x79
++#define PMBUS_STATUS_VOUT 0x7A
++#define PMBUS_STATUS_IOUT 0x7B
++#define PMBUS_STATUS_INPUT 0x7C
++#define PMBUS_STATUS_TEMPERATURE 0x7D
++#define PMBUS_STATUS_CML 0x7E
++#define PMBUS_STATUS_OTHER 0x7F
++#define PMBUS_STATUS_MFR_SPECIFIC 0x80
++#define PMBUS_STATUS_FAN_12 0x81
++#define PMBUS_STATUS_FAN_34 0x82
++
++#define PMBUS_READ_VIN 0x88
++#define PMBUS_READ_IIN 0x89
++#define PMBUS_READ_VCAP 0x8A
++#define PMBUS_READ_VOUT 0x8B
++#define PMBUS_READ_IOUT 0x8C
++#define PMBUS_READ_TEMPERATURE_1 0x8D
++#define PMBUS_READ_TEMPERATURE_2 0x8E
++#define PMBUS_READ_TEMPERATURE_3 0x8F
++#define PMBUS_READ_FAN_SPEED_1 0x90
++#define PMBUS_READ_FAN_SPEED_2 0x91
++#define PMBUS_READ_FAN_SPEED_3 0x92
++#define PMBUS_READ_FAN_SPEED_4 0x93
++#define PMBUS_READ_DUTY_CYCLE 0x94
++#define PMBUS_READ_FREQUENCY 0x95
++#define PMBUS_READ_POUT 0x96
++#define PMBUS_READ_PIN 0x97
++
++#define PMBUS_REVISION 0x98
++#define PMBUS_MFR_ID 0x99
++#define PMBUS_MFR_MODEL 0x9A
++#define PMBUS_MFR_REVISION 0x9B
++#define PMBUS_MFR_LOCATION 0x9C
++#define PMBUS_MFR_DATE 0x9D
++#define PMBUS_MFR_SERIAL 0x9E
++
++/*
++ * Virtual registers.
++ * Useful to support attributes which are not supported by standard PMBus
++ * registers but exist as manufacturer specific registers on individual chips.
++ * Must be mapped to real registers in device specific code.
++ *
++ * Semantics:
++ * Virtual registers are all word size.
++ * READ registers are read-only; writes are either ignored or return an error.
++ * RESET registers are read/write. Reading reset registers returns zero
++ * (used for detection), writing any value causes the associated history to be
++ * reset.
++ * Virtual registers have to be handled in device specific driver code. Chip
++ * driver code returns non-negative register values if a virtual register is
++ * supported, or a negative error code if not. The chip driver may return
++ * -ENODATA or any other error code in this case, though an error code other
++ * than -ENODATA is handled more efficiently and thus preferred. Either case,
++ * the calling PMBus core code will abort if the chip driver returns an error
++ * code when reading or writing virtual registers.
++ */
++#define PMBUS_VIRT_BASE 0x100
++#define PMBUS_VIRT_READ_TEMP_AVG (PMBUS_VIRT_BASE + 0)
++#define PMBUS_VIRT_READ_TEMP_MIN (PMBUS_VIRT_BASE + 1)
++#define PMBUS_VIRT_READ_TEMP_MAX (PMBUS_VIRT_BASE + 2)
++#define PMBUS_VIRT_RESET_TEMP_HISTORY (PMBUS_VIRT_BASE + 3)
++#define PMBUS_VIRT_READ_VIN_AVG (PMBUS_VIRT_BASE + 4)
++#define PMBUS_VIRT_READ_VIN_MIN (PMBUS_VIRT_BASE + 5)
++#define PMBUS_VIRT_READ_VIN_MAX (PMBUS_VIRT_BASE + 6)
++#define PMBUS_VIRT_RESET_VIN_HISTORY (PMBUS_VIRT_BASE + 7)
++#define PMBUS_VIRT_READ_IIN_AVG (PMBUS_VIRT_BASE + 8)
++#define PMBUS_VIRT_READ_IIN_MIN (PMBUS_VIRT_BASE + 9)
++#define PMBUS_VIRT_READ_IIN_MAX (PMBUS_VIRT_BASE + 10)
++#define PMBUS_VIRT_RESET_IIN_HISTORY (PMBUS_VIRT_BASE + 11)
++#define PMBUS_VIRT_READ_PIN_AVG (PMBUS_VIRT_BASE + 12)
++#define PMBUS_VIRT_READ_PIN_MAX (PMBUS_VIRT_BASE + 13)
++#define PMBUS_VIRT_RESET_PIN_HISTORY (PMBUS_VIRT_BASE + 14)
++#define PMBUS_VIRT_READ_POUT_AVG (PMBUS_VIRT_BASE + 15)
++#define PMBUS_VIRT_READ_POUT_MAX (PMBUS_VIRT_BASE + 16)
++#define PMBUS_VIRT_RESET_POUT_HISTORY (PMBUS_VIRT_BASE + 17)
++#define PMBUS_VIRT_READ_VOUT_AVG (PMBUS_VIRT_BASE + 18)
++#define PMBUS_VIRT_READ_VOUT_MIN (PMBUS_VIRT_BASE + 19)
++#define PMBUS_VIRT_READ_VOUT_MAX (PMBUS_VIRT_BASE + 20)
++#define PMBUS_VIRT_RESET_VOUT_HISTORY (PMBUS_VIRT_BASE + 21)
++#define PMBUS_VIRT_READ_IOUT_AVG (PMBUS_VIRT_BASE + 22)
++#define PMBUS_VIRT_READ_IOUT_MIN (PMBUS_VIRT_BASE + 23)
++#define PMBUS_VIRT_READ_IOUT_MAX (PMBUS_VIRT_BASE + 24)
++#define PMBUS_VIRT_RESET_IOUT_HISTORY (PMBUS_VIRT_BASE + 25)
++#define PMBUS_VIRT_READ_TEMP2_AVG (PMBUS_VIRT_BASE + 26)
++#define PMBUS_VIRT_READ_TEMP2_MIN (PMBUS_VIRT_BASE + 27)
++#define PMBUS_VIRT_READ_TEMP2_MAX (PMBUS_VIRT_BASE + 28)
++#define PMBUS_VIRT_RESET_TEMP2_HISTORY (PMBUS_VIRT_BASE + 29)
++
++#define PMBUS_VIRT_READ_VMON (PMBUS_VIRT_BASE + 30)
++#define PMBUS_VIRT_VMON_UV_WARN_LIMIT (PMBUS_VIRT_BASE + 31)
++#define PMBUS_VIRT_VMON_OV_WARN_LIMIT (PMBUS_VIRT_BASE + 32)
++#define PMBUS_VIRT_VMON_UV_FAULT_LIMIT (PMBUS_VIRT_BASE + 33)
++#define PMBUS_VIRT_VMON_OV_FAULT_LIMIT (PMBUS_VIRT_BASE + 34)
++#define PMBUS_VIRT_STATUS_VMON (PMBUS_VIRT_BASE + 35)
++
++/*
++ * CAPABILITY
++ */
++#define PB_CAPABILITY_SMBALERT (1<<4)
++#define PB_CAPABILITY_ERROR_CHECK (1<<7)
++
++/*
++ * VOUT_MODE
++ */
++#define PB_VOUT_MODE_MODE_MASK 0xe0
++#define PB_VOUT_MODE_PARAM_MASK 0x1f
++
++#define PB_VOUT_MODE_LINEAR 0x00
++#define PB_VOUT_MODE_VID 0x20
++#define PB_VOUT_MODE_DIRECT 0x40
++
++/*
++ * Fan configuration
++ */
++#define PB_FAN_2_PULSE_MASK ((1 << 0) | (1 << 1))
++#define PB_FAN_2_RPM (1 << 2)
++#define PB_FAN_2_INSTALLED (1 << 3)
++#define PB_FAN_1_PULSE_MASK ((1 << 4) | (1 << 5))
++#define PB_FAN_1_RPM (1 << 6)
++#define PB_FAN_1_INSTALLED (1 << 7)
++
++/*
++ * STATUS_BYTE, STATUS_WORD (lower)
++ */
++#define PB_STATUS_NONE_ABOVE (1<<0)
++#define PB_STATUS_CML (1<<1)
++#define PB_STATUS_TEMPERATURE (1<<2)
++#define PB_STATUS_VIN_UV (1<<3)
++#define PB_STATUS_IOUT_OC (1<<4)
++#define PB_STATUS_VOUT_OV (1<<5)
++#define PB_STATUS_OFF (1<<6)
++#define PB_STATUS_BUSY (1<<7)
++
++/*
++ * STATUS_WORD (upper)
++ */
++#define PB_STATUS_UNKNOWN (1<<8)
++#define PB_STATUS_OTHER (1<<9)
++#define PB_STATUS_FANS (1<<10)
++#define PB_STATUS_POWER_GOOD_N (1<<11)
++#define PB_STATUS_WORD_MFR (1<<12)
++#define PB_STATUS_INPUT (1<<13)
++#define PB_STATUS_IOUT_POUT (1<<14)
++#define PB_STATUS_VOUT (1<<15)
++
++/*
++ * STATUS_IOUT
++ */
++#define PB_POUT_OP_WARNING (1<<0)
++#define PB_POUT_OP_FAULT (1<<1)
++#define PB_POWER_LIMITING (1<<2)
++#define PB_CURRENT_SHARE_FAULT (1<<3)
++#define PB_IOUT_UC_FAULT (1<<4)
++#define PB_IOUT_OC_WARNING (1<<5)
++#define PB_IOUT_OC_LV_FAULT (1<<6)
++#define PB_IOUT_OC_FAULT (1<<7)
++
++/*
++ * STATUS_VOUT, STATUS_INPUT
++ */
++#define PB_VOLTAGE_UV_FAULT (1<<4)
++#define PB_VOLTAGE_UV_WARNING (1<<5)
++#define PB_VOLTAGE_OV_WARNING (1<<6)
++#define PB_VOLTAGE_OV_FAULT (1<<7)
++
++/*
++ * STATUS_INPUT
++ */
++#define PB_PIN_OP_WARNING (1<<0)
++#define PB_IIN_OC_WARNING (1<<1)
++#define PB_IIN_OC_FAULT (1<<2)
++
++/*
++ * STATUS_TEMPERATURE
++ */
++#define PB_TEMP_UT_FAULT (1<<4)
++#define PB_TEMP_UT_WARNING (1<<5)
++#define PB_TEMP_OT_WARNING (1<<6)
++#define PB_TEMP_OT_FAULT (1<<7)
++
++/*
++ * STATUS_FAN
++ */
++#define PB_FAN_AIRFLOW_WARNING (1<<0)
++#define PB_FAN_AIRFLOW_FAULT (1<<1)
++#define PB_FAN_FAN2_SPEED_OVERRIDE (1<<2)
++#define PB_FAN_FAN1_SPEED_OVERRIDE (1<<3)
++#define PB_FAN_FAN2_WARNING (1<<4)
++#define PB_FAN_FAN1_WARNING (1<<5)
++#define PB_FAN_FAN2_FAULT (1<<6)
++#define PB_FAN_FAN1_FAULT (1<<7)
++
++/*
++ * CML_FAULT_STATUS
++ */
++#define PB_CML_FAULT_OTHER_MEM_LOGIC (1<<0)
++#define PB_CML_FAULT_OTHER_COMM (1<<1)
++#define PB_CML_FAULT_PROCESSOR (1<<3)
++#define PB_CML_FAULT_MEMORY (1<<4)
++#define PB_CML_FAULT_PACKET_ERROR (1<<5)
++#define PB_CML_FAULT_INVALID_DATA (1<<6)
++#define PB_CML_FAULT_INVALID_COMMAND (1<<7)
++
++enum pmbus_sensor_classes {
++ PSC_VOLTAGE_IN = 0,
++ PSC_VOLTAGE_OUT,
++ PSC_CURRENT_IN,
++ PSC_CURRENT_OUT,
++ PSC_POWER,
++ PSC_TEMPERATURE,
++ PSC_FAN,
++ PSC_NUM_CLASSES /* Number of power sensor classes */
++};
++
++#define PMBUS_PAGES 32 /* Per PMBus specification */
++
++/* Functionality bit mask */
++#define PMBUS_HAVE_VIN (1 << 0)
++#define PMBUS_HAVE_VCAP (1 << 1)
++#define PMBUS_HAVE_VOUT (1 << 2)
++#define PMBUS_HAVE_IIN (1 << 3)
++#define PMBUS_HAVE_IOUT (1 << 4)
++#define PMBUS_HAVE_PIN (1 << 5)
++#define PMBUS_HAVE_POUT (1 << 6)
++#define PMBUS_HAVE_FAN12 (1 << 7)
++#define PMBUS_HAVE_FAN34 (1 << 8)
++#define PMBUS_HAVE_TEMP (1 << 9)
++#define PMBUS_HAVE_TEMP2 (1 << 10)
++#define PMBUS_HAVE_TEMP3 (1 << 11)
++#define PMBUS_HAVE_STATUS_VOUT (1 << 12)
++#define PMBUS_HAVE_STATUS_IOUT (1 << 13)
++#define PMBUS_HAVE_STATUS_INPUT (1 << 14)
++#define PMBUS_HAVE_STATUS_TEMP (1 << 15)
++#define PMBUS_HAVE_STATUS_FAN12 (1 << 16)
++#define PMBUS_HAVE_STATUS_FAN34 (1 << 17)
++#define PMBUS_HAVE_VMON (1 << 18)
++#define PMBUS_HAVE_STATUS_VMON (1 << 19)
++#define PMBUS_HAVE_MFRDATA (1 << 20)
++
++enum pmbus_data_format { linear = 0, direct, vid };
++
++struct pmbus_driver_info {
++ int pages; /* Total number of pages */
++ ushort delay;
++ enum pmbus_data_format format[PSC_NUM_CLASSES];
++ /*
++ * Support one set of coefficients for each sensor type
++ * Used for chips providing data in direct mode.
++ */
++ int m[PSC_NUM_CLASSES]; /* mantissa for direct data format */
++ int b[PSC_NUM_CLASSES]; /* offset */
++ int R[PSC_NUM_CLASSES]; /* exponent */
++
++ u32 func[PMBUS_PAGES]; /* Functionality, per page */
++ /*
++ * The following functions map manufacturing specific register values
++ * to PMBus standard register values. Specify only if mapping is
++ * necessary.
++ * Functions return the register value (read) or zero (write) if
++ * successful. A return value of -ENODATA indicates that there is no
++ * manufacturer specific register, but that a standard PMBus register
++ * may exist. Any other negative return value indicates that the
++ * register does not exist, and that no attempt should be made to read
++ * the standard register.
++ */
++ int (*read_byte_data)(struct i2c_client *client, int page, int reg);
++ int (*read_word_data)(struct i2c_client *client, int page, int reg);
++ int (*write_word_data)(struct i2c_client *client, int page, int reg,
++ u16 word);
++ int (*write_byte)(struct i2c_client *client, int page, u8 value);
++ /*
++ * The identify function determines supported PMBus functionality.
++ * This function is only necessary if a chip driver supports multiple
++ * chips, and the chip functionality is not pre-determined.
++ */
++ int (*identify)(struct i2c_client *client,
++ struct pmbus_driver_info *info);
++};
++
++/* Function declarations */
++
++void pmbus_wait(struct i2c_client *client);
++void pmbus_update_wait(struct i2c_client *client);
++void pmbus_clear_cache(struct i2c_client *client);
++int pmbus_set_page(struct i2c_client *client, u8 page);
++int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg);
++int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word);
++int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg);
++int pmbus_write_byte(struct i2c_client *client, int page, u8 value);
++void pmbus_clear_faults(struct i2c_client *client);
++bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg);
++bool pmbus_check_word_register(struct i2c_client *client, int page, int reg);
++int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id,
++ struct pmbus_driver_info *info);
++int pmbus_do_remove(struct i2c_client *client);
++const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client
++ *client);
++
++#endif /* PMBUS_H */
+diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
+new file mode 100644
+index 0000000..d547fc8
+--- /dev/null
++++ b/drivers/hwmon/pmbus/pmbus_core.c
+@@ -0,0 +1,1940 @@
++/*
++ * Hardware monitoring driver for PMBus devices
++ *
++ * Copyright (c) 2010, 2011 Ericsson AB.
++ * Copyright (c) 2012 Guenter Roeck
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/err.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include <linux/hwmon.h>
++#include <linux/hwmon-sysfs.h>
++#include <linux/jiffies.h>
++#include <linux/delay.h>
++#include <linux/i2c/pmbus.h>
++#include "pmbus.h"
++
++/*
++ * Number of additional attribute pointers to allocate
++ * with each call to krealloc
++ */
++#define PMBUS_ATTR_ALLOC_SIZE 32
++
++/*
++ * Index into status register array, per status register group
++ */
++#define PB_STATUS_BASE 0
++#define PB_STATUS_VOUT_BASE (PB_STATUS_BASE + PMBUS_PAGES)
++#define PB_STATUS_IOUT_BASE (PB_STATUS_VOUT_BASE + PMBUS_PAGES)
++#define PB_STATUS_FAN_BASE (PB_STATUS_IOUT_BASE + PMBUS_PAGES)
++#define PB_STATUS_FAN34_BASE (PB_STATUS_FAN_BASE + PMBUS_PAGES)
++#define PB_STATUS_TEMP_BASE (PB_STATUS_FAN34_BASE + PMBUS_PAGES)
++#define PB_STATUS_INPUT_BASE (PB_STATUS_TEMP_BASE + PMBUS_PAGES)
++#define PB_STATUS_VMON_BASE (PB_STATUS_INPUT_BASE + 1)
++
++#define PB_NUM_STATUS_REG (PB_STATUS_VMON_BASE + 1)
++
++#define PMBUS_NAME_SIZE 24
++
++struct pmbus_sensor {
++ struct pmbus_sensor *next;
++ char name[PMBUS_NAME_SIZE]; /* sysfs sensor name */
++ struct device_attribute attribute;
++ u8 page; /* page number */
++ u16 reg; /* register */
++ enum pmbus_sensor_classes class; /* sensor class */
++ bool update; /* runtime sensor update needed */
++ int data; /* Sensor data.
++ Negative if there was a read error */
++};
++#define to_pmbus_sensor(_attr) \
++ container_of(_attr, struct pmbus_sensor, attribute)
++
++struct pmbus_boolean {
++ char name[PMBUS_NAME_SIZE]; /* sysfs boolean name */
++ struct sensor_device_attribute attribute;
++ struct pmbus_sensor *s1;
++ struct pmbus_sensor *s2;
++};
++#define to_pmbus_boolean(_attr) \
++ container_of(_attr, struct pmbus_boolean, attribute)
++
++struct pmbus_label {
++ char name[PMBUS_NAME_SIZE]; /* sysfs label name */
++ struct device_attribute attribute;
++ char label[PMBUS_NAME_SIZE]; /* label */
++};
++#define to_pmbus_label(_attr) \
++ container_of(_attr, struct pmbus_label, attribute)
++
++struct pmbus_data {
++ struct device *dev;
++ struct device *hwmon_dev;
++
++ u32 flags; /* from platform data */
++
++ int exponent; /* linear mode: exponent for output voltages */
++
++ const struct pmbus_driver_info *info;
++
++ int max_attributes;
++ int num_attributes;
++ struct attribute_group group;
++
++ struct pmbus_sensor *sensors;
++
++ struct mutex update_lock;
++ bool valid;
++ unsigned long last_updated; /* in jiffies */
++
++ ktime_t access;
++
++ /*
++ * A single status register covers multiple attributes,
++ * so we keep them all together.
++ */
++ u8 status[PB_NUM_STATUS_REG];
++ u8 status_register;
++
++ u8 currpage;
++};
++
++/* Some chips need a delay between accesses */
++void pmbus_wait(struct i2c_client *client)
++{
++ struct pmbus_data *data = i2c_get_clientdata(client);
++ const struct pmbus_driver_info *info = data->info;
++
++ if (info->delay) {
++ s64 delta = ktime_us_delta(ktime_get(), data->access);
++ if (delta < info->delay)
++ /*
++ * Note that udelay is busy waiting. msleep is
++ * quite a bit slower (it actually takes a
++ * minimum of 20ms), but doesn't busy wait. Hmmm.
++ */
++ udelay(info->delay - delta);
++ }
++}
++EXPORT_SYMBOL_GPL(pmbus_wait);
++
++void pmbus_update_wait(struct i2c_client *client)
++{
++ struct pmbus_data *data = i2c_get_clientdata(client);
++ const struct pmbus_driver_info *info = data->info;
++
++ if (info->delay)
++ data->access = ktime_get();
++}
++EXPORT_SYMBOL_GPL(pmbus_update_wait);
++
++void pmbus_clear_cache(struct i2c_client *client)
++{
++ struct pmbus_data *data = i2c_get_clientdata(client);
++
++ data->valid = false;
++}
++EXPORT_SYMBOL_GPL(pmbus_clear_cache);
++
++int pmbus_set_page(struct i2c_client *client, u8 page)
++{
++ struct pmbus_data *data = i2c_get_clientdata(client);
++ int rv = 0;
++ int newpage;
++
++ if (page != data->currpage) {
++ pmbus_wait(client);
++ rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page);
++ pmbus_update_wait(client);
++ pmbus_wait(client);
++ newpage = i2c_smbus_read_byte_data(client, PMBUS_PAGE);
++ pmbus_update_wait(client);
++ if (newpage != page)
++ rv = -EIO;
++ else
++ data->currpage = page;
++ }
++ return rv;
++}
++EXPORT_SYMBOL_GPL(pmbus_set_page);
++
++int pmbus_write_byte(struct i2c_client *client, int page, u8 value)
++{
++ int rv;
++
++ if (page >= 0) {
++ rv = pmbus_set_page(client, page);
++ if (rv < 0)
++ return rv;
++ }
++
++ pmbus_wait(client);
++ rv = i2c_smbus_write_byte(client, value);
++ pmbus_update_wait(client);
++ return rv;
++}
++EXPORT_SYMBOL_GPL(pmbus_write_byte);
++
++/*
++ * _pmbus_write_byte() is similar to pmbus_write_byte(), but checks if
++ * a device specific mapping funcion exists and calls it if necessary.
++ */
++static int _pmbus_write_byte(struct i2c_client *client, int page, u8 value)
++{
++ struct pmbus_data *data = i2c_get_clientdata(client);
++ const struct pmbus_driver_info *info = data->info;
++ int status;
++
++ if (info->write_byte) {
++ status = info->write_byte(client, page, value);
++ if (status != -ENODATA)
++ return status;
++ }
++ return pmbus_write_byte(client, page, value);
++}
++
++int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word)
++{
++ int rv;
++
++ rv = pmbus_set_page(client, page);
++ if (rv < 0)
++ return rv;
++
++ pmbus_wait(client);
++ rv = i2c_smbus_write_word_data(client, reg, word);
++ pmbus_update_wait(client);
++ return rv;
++}
++EXPORT_SYMBOL_GPL(pmbus_write_word_data);
++
++/*
++ * _pmbus_write_word_data() is similar to pmbus_write_word_data(), but checks if
++ * a device specific mapping function exists and calls it if necessary.
++ */
++static int _pmbus_write_word_data(struct i2c_client *client, int page, int reg,
++ u16 word)
++{
++ struct pmbus_data *data = i2c_get_clientdata(client);
++ const struct pmbus_driver_info *info = data->info;
++ int status;
++
++ if (info->write_word_data) {
++ status = info->write_word_data(client, page, reg, word);
++ if (status != -ENODATA)
++ return status;
++ }
++ if (reg >= PMBUS_VIRT_BASE)
++ return -ENXIO;
++ return pmbus_write_word_data(client, page, reg, word);
++}
++
++int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg)
++{
++ int rv;
++
++ rv = pmbus_set_page(client, page);
++ if (rv < 0)
++ return rv;
++
++ pmbus_wait(client);
++ rv = i2c_smbus_read_word_data(client, reg);
++ pmbus_update_wait(client);
++ return rv;
++}
++EXPORT_SYMBOL_GPL(pmbus_read_word_data);
++
++/*
++ * _pmbus_read_word_data() is similar to pmbus_read_word_data(), but checks if
++ * a device specific mapping function exists and calls it if necessary.
++ */
++static int _pmbus_read_word_data(struct i2c_client *client, int page, int reg)
++{
++ struct pmbus_data *data = i2c_get_clientdata(client);
++ const struct pmbus_driver_info *info = data->info;
++ int status;
++
++ if (info->read_word_data) {
++ status = info->read_word_data(client, page, reg);
++ if (status != -ENODATA)
++ return status;
++ }
++ if (reg >= PMBUS_VIRT_BASE)
++ return -ENXIO;
++ return pmbus_read_word_data(client, page, reg);
++}
++
++int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg)
++{
++ int rv;
++
++ if (page >= 0) {
++ rv = pmbus_set_page(client, page);
++ if (rv < 0)
++ return rv;
++ }
++
++ pmbus_wait(client);
++ rv = i2c_smbus_read_byte_data(client, reg);
++ pmbus_update_wait(client);
++ return rv;
++}
++EXPORT_SYMBOL_GPL(pmbus_read_byte_data);
++
++/*
++ * _pmbus_read_byte_data() is similar to pmbus_read_byte_data(), but checks if
++ * a device specific mapping function exists and calls it if necessary.
++ */
++static int _pmbus_read_byte_data(struct i2c_client *client, int page, int reg)
++{
++ struct pmbus_data *data = i2c_get_clientdata(client);
++ const struct pmbus_driver_info *info = data->info;
++ int status;
++
++ if (info->read_byte_data) {
++ status = info->read_byte_data(client, page, reg);
++ if (status != -ENODATA)
++ return status;
++ }
++ return pmbus_read_byte_data(client, page, reg);
++}
++
++static void pmbus_clear_fault_page(struct i2c_client *client, int page)
++{
++ _pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS);
++}
++
++void pmbus_clear_faults(struct i2c_client *client)
++{
++ struct pmbus_data *data = i2c_get_clientdata(client);
++ int i;
++
++ for (i = 0; i < data->info->pages; i++)
++ pmbus_clear_fault_page(client, i);
++}
++EXPORT_SYMBOL_GPL(pmbus_clear_faults);
++
++static int pmbus_check_status_cml(struct i2c_client *client)
++{
++ struct pmbus_data *data = i2c_get_clientdata(client);
++ int status, status2;
++
++ status = _pmbus_read_byte_data(client, -1, data->status_register);
++ if (status < 0 || (status & PB_STATUS_CML)) {
++ status2 = _pmbus_read_byte_data(client, -1, PMBUS_STATUS_CML);
++ if (status2 < 0 || (status2 & PB_CML_FAULT_INVALID_COMMAND))
++ return -EIO;
++ }
++ return 0;
++}
++
++static bool pmbus_check_register(struct i2c_client *client,
++ int (*func)(struct i2c_client *client,
++ int page, int reg),
++ int page, int reg)
++{
++ int rv;
++ struct pmbus_data *data = i2c_get_clientdata(client);
++
++ rv = func(client, page, reg);
++ if (rv >= 0 && !(data->flags & PMBUS_SKIP_STATUS_CHECK))
++ rv = pmbus_check_status_cml(client);
++ pmbus_clear_fault_page(client, -1);
++ return rv >= 0;
++}
++
++bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg)
++{
++ return pmbus_check_register(client, _pmbus_read_byte_data, page, reg);
++}
++EXPORT_SYMBOL_GPL(pmbus_check_byte_register);
++
++bool pmbus_check_word_register(struct i2c_client *client, int page, int reg)
++{
++ return pmbus_check_register(client, _pmbus_read_word_data, page, reg);
++}
++EXPORT_SYMBOL_GPL(pmbus_check_word_register);
++
++const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client *client)
++{
++ struct pmbus_data *data = i2c_get_clientdata(client);
++
++ return data->info;
++}
++EXPORT_SYMBOL_GPL(pmbus_get_driver_info);
++
++static struct _pmbus_status {
++ u32 func;
++ u16 base;
++ u16 reg;
++} pmbus_status[] = {
++ { PMBUS_HAVE_STATUS_VOUT, PB_STATUS_VOUT_BASE, PMBUS_STATUS_VOUT },
++ { PMBUS_HAVE_STATUS_IOUT, PB_STATUS_IOUT_BASE, PMBUS_STATUS_IOUT },
++ { PMBUS_HAVE_STATUS_TEMP, PB_STATUS_TEMP_BASE,
++ PMBUS_STATUS_TEMPERATURE },
++ { PMBUS_HAVE_STATUS_FAN12, PB_STATUS_FAN_BASE, PMBUS_STATUS_FAN_12 },
++ { PMBUS_HAVE_STATUS_FAN34, PB_STATUS_FAN34_BASE, PMBUS_STATUS_FAN_34 },
++};
++
++static struct pmbus_data *pmbus_update_device(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct pmbus_data *data = i2c_get_clientdata(client);
++ const struct pmbus_driver_info *info = data->info;
++ struct pmbus_sensor *sensor;
++
++ mutex_lock(&data->update_lock);
++ if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
++ int i, j;
++
++ for (i = 0; i < info->pages; i++) {
++ data->status[PB_STATUS_BASE + i]
++ = _pmbus_read_byte_data(client, i,
++ data->status_register);
++ for (j = 0; j < ARRAY_SIZE(pmbus_status); j++) {
++ struct _pmbus_status *s = &pmbus_status[j];
++
++ if (!(info->func[i] & s->func))
++ continue;
++ data->status[s->base + i]
++ = _pmbus_read_byte_data(client, i,
++ s->reg);
++ }
++ }
++
++ if (info->func[0] & PMBUS_HAVE_STATUS_INPUT)
++ data->status[PB_STATUS_INPUT_BASE]
++ = _pmbus_read_byte_data(client, 0,
++ PMBUS_STATUS_INPUT);
++
++ if (info->func[0] & PMBUS_HAVE_STATUS_VMON)
++ data->status[PB_STATUS_VMON_BASE]
++ = _pmbus_read_byte_data(client, 0,
++ PMBUS_VIRT_STATUS_VMON);
++
++ for (sensor = data->sensors; sensor; sensor = sensor->next) {
++ if (!data->valid || sensor->update)
++ sensor->data
++ = _pmbus_read_word_data(client,
++ sensor->page,
++ sensor->reg);
++ }
++ pmbus_clear_faults(client);
++ data->last_updated = jiffies;
++ data->valid = 1;
++ }
++ mutex_unlock(&data->update_lock);
++ return data;
++}
++
++/*
++ * Convert linear sensor values to milli- or micro-units
++ * depending on sensor type.
++ */
++static long pmbus_reg2data_linear(struct pmbus_data *data,
++ struct pmbus_sensor *sensor)
++{
++ s16 exponent;
++ s32 mantissa;
++ long val;
++
++ if (sensor->class == PSC_VOLTAGE_OUT) { /* LINEAR16 */
++ exponent = data->exponent;
++ mantissa = (u16) sensor->data;
++ } else { /* LINEAR11 */
++ exponent = ((s16)sensor->data) >> 11;
++ mantissa = ((s16)((sensor->data & 0x7ff) << 5)) >> 5;
++ }
++
++ val = mantissa;
++
++ /* scale result to milli-units for all sensors except fans */
++ if (sensor->class != PSC_FAN)
++ val = val * 1000L;
++
++ /* scale result to micro-units for power sensors */
++ if (sensor->class == PSC_POWER)
++ val = val * 1000L;
++
++ if (exponent >= 0)
++ val <<= exponent;
++ else
++ val >>= -exponent;
++
++ return val;
++}
++
++/*
++ * Convert direct sensor values to milli- or micro-units
++ * depending on sensor type.
++ */
++static long pmbus_reg2data_direct(struct pmbus_data *data,
++ struct pmbus_sensor *sensor)
++{
++ long val = (s16) sensor->data;
++ long m, b, R;
++
++ m = data->info->m[sensor->class];
++ b = data->info->b[sensor->class];
++ R = data->info->R[sensor->class];
++
++ if (m == 0)
++ return 0;
++
++ /* X = 1/m * (Y * 10^-R - b) */
++ R = -R;
++ /* scale result to milli-units for everything but fans */
++ if (sensor->class != PSC_FAN) {
++ R += 3;
++ b *= 1000;
++ }
++
++ /* scale result to micro-units for power sensors */
++ if (sensor->class == PSC_POWER) {
++ R += 3;
++ b *= 1000;
++ }
++
++ while (R > 0) {
++ val *= 10;
++ R--;
++ }
++ while (R < 0) {
++ val = DIV_ROUND_CLOSEST(val, 10);
++ R++;
++ }
++
++ return (val - b) / m;
++}
++
++/*
++ * Convert VID sensor values to milli- or micro-units
++ * depending on sensor type.
++ * We currently only support VR11.
++ */
++static long pmbus_reg2data_vid(struct pmbus_data *data,
++ struct pmbus_sensor *sensor)
++{
++ long val = sensor->data;
++
++ if (val < 0x02 || val > 0xb2)
++ return 0;
++ return DIV_ROUND_CLOSEST(160000 - (val - 2) * 625, 100);
++}
++
++static long pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor)
++{
++ long val;
++
++ switch (data->info->format[sensor->class]) {
++ case direct:
++ val = pmbus_reg2data_direct(data, sensor);
++ break;
++ case vid:
++ val = pmbus_reg2data_vid(data, sensor);
++ break;
++ case linear:
++ default:
++ val = pmbus_reg2data_linear(data, sensor);
++ break;
++ }
++ return val;
++}
++
++#define MAX_MANTISSA (1023 * 1000)
++#define MIN_MANTISSA (511 * 1000)
++
++static u16 pmbus_data2reg_linear(struct pmbus_data *data,
++ enum pmbus_sensor_classes class, long val)
++{
++ s16 exponent = 0, mantissa;
++ bool negative = false;
++
++ /* simple case */
++ if (val == 0)
++ return 0;
++
++ if (class == PSC_VOLTAGE_OUT) {
++ /* LINEAR16 does not support negative voltages */
++ if (val < 0)
++ return 0;
++
++ /*
++ * For a static exponents, we don't have a choice
++ * but to adjust the value to it.
++ */
++ if (data->exponent < 0)
++ val <<= -data->exponent;
++ else
++ val >>= data->exponent;
++ val = DIV_ROUND_CLOSEST(val, 1000);
++ return val & 0xffff;
++ }
++
++ if (val < 0) {
++ negative = true;
++ val = -val;
++ }
++
++ /* Power is in uW. Convert to mW before converting. */
++ if (class == PSC_POWER)
++ val = DIV_ROUND_CLOSEST(val, 1000L);
++
++ /*
++ * For simplicity, convert fan data to milli-units
++ * before calculating the exponent.
++ */
++ if (class == PSC_FAN)
++ val = val * 1000;
++
++ /* Reduce large mantissa until it fits into 10 bit */
++ while (val >= MAX_MANTISSA && exponent < 15) {
++ exponent++;
++ val >>= 1;
++ }
++ /* Increase small mantissa to improve precision */
++ while (val < MIN_MANTISSA && exponent > -15) {
++ exponent--;
++ val <<= 1;
++ }
++
++ /* Convert mantissa from milli-units to units */
++ mantissa = DIV_ROUND_CLOSEST(val, 1000);
++
++ /* Ensure that resulting number is within range */
++ if (mantissa > 0x3ff)
++ mantissa = 0x3ff;
++
++ /* restore sign */
++ if (negative)
++ mantissa = -mantissa;
++
++ /* Convert to 5 bit exponent, 11 bit mantissa */
++ return (mantissa & 0x7ff) | ((exponent << 11) & 0xf800);
++}
++
++static u16 pmbus_data2reg_direct(struct pmbus_data *data,
++ enum pmbus_sensor_classes class, long val)
++{
++ long m, b, R;
++
++ m = data->info->m[class];
++ b = data->info->b[class];
++ R = data->info->R[class];
++
++ /* Power is in uW. Adjust R and b. */
++ if (class == PSC_POWER) {
++ R -= 3;
++ b *= 1000;
++ }
++
++ /* Calculate Y = (m * X + b) * 10^R */
++ if (class != PSC_FAN) {
++ R -= 3; /* Adjust R and b for data in milli-units */
++ b *= 1000;
++ }
++ val = val * m + b;
++
++ while (R > 0) {
++ val *= 10;
++ R--;
++ }
++ while (R < 0) {
++ val = DIV_ROUND_CLOSEST(val, 10);
++ R++;
++ }
++
++ return val;
++}
++
++static u16 pmbus_data2reg_vid(struct pmbus_data *data,
++ enum pmbus_sensor_classes class, long val)
++{
++ val = clamp_val(val, 500, 1600);
++
++ return 2 + DIV_ROUND_CLOSEST((1600 - val) * 100, 625);
++}
++
++static u16 pmbus_data2reg(struct pmbus_data *data,
++ enum pmbus_sensor_classes class, long val)
++{
++ u16 regval;
++
++ switch (data->info->format[class]) {
++ case direct:
++ regval = pmbus_data2reg_direct(data, class, val);
++ break;
++ case vid:
++ regval = pmbus_data2reg_vid(data, class, val);
++ break;
++ case linear:
++ default:
++ regval = pmbus_data2reg_linear(data, class, val);
++ break;
++ }
++ return regval;
++}
++
++/*
++ * Return boolean calculated from converted data.
++ * <index> defines a status register index and mask.
++ * The mask is in the lower 8 bits, the register index is in bits 8..23.
++ *
++ * The associated pmbus_boolean structure contains optional pointers to two
++ * sensor attributes. If specified, those attributes are compared against each
++ * other to determine if a limit has been exceeded.
++ *
++ * If the sensor attribute pointers are NULL, the function returns true if
++ * (status[reg] & mask) is true.
++ *
++ * If sensor attribute pointers are provided, a comparison against a specified
++ * limit has to be performed to determine the boolean result.
++ * In this case, the function returns true if v1 >= v2 (where v1 and v2 are
++ * sensor values referenced by sensor attribute pointers s1 and s2).
++ *
++ * To determine if an object exceeds upper limits, specify <s1,s2> = <v,limit>.
++ * To determine if an object exceeds lower limits, specify <s1,s2> = <limit,v>.
++ *
++ * If a negative value is stored in any of the referenced registers, this value
++ * reflects an error code which will be returned.
++ */
++static int pmbus_get_boolean(struct pmbus_data *data, struct pmbus_boolean *b,
++ int index)
++{
++ struct pmbus_sensor *s1 = b->s1;
++ struct pmbus_sensor *s2 = b->s2;
++ u16 reg = (index >> 8) & 0xffff;
++ u8 mask = index & 0xff;
++ int ret, status;
++ u8 regval;
++
++ status = data->status[reg];
++ if (status < 0)
++ return status;
++
++ regval = status & mask;
++ if (!s1 && !s2) {
++ ret = !!regval;
++ } else if (!s1 || !s2) {
++ BUG();
++ return 0;
++ } else {
++ long v1, v2;
++
++ if (s1->data < 0)
++ return s1->data;
++ if (s2->data < 0)
++ return s2->data;
++
++ v1 = pmbus_reg2data(data, s1);
++ v2 = pmbus_reg2data(data, s2);
++ ret = !!(regval && v1 >= v2);
++ }
++ return ret;
++}
++
++static ssize_t pmbus_show_boolean(struct device *dev,
++ struct device_attribute *da, char *buf)
++{
++ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
++ struct pmbus_boolean *boolean = to_pmbus_boolean(attr);
++ struct pmbus_data *data = pmbus_update_device(dev);
++ int val;
++
++ val = pmbus_get_boolean(data, boolean, attr->index);
++ if (val < 0)
++ return val;
++ if (val == 0xff)
++ return 0;
++ return snprintf(buf, PAGE_SIZE, "%d\n", val);
++}
++
++static ssize_t pmbus_show_sensor(struct device *dev,
++ struct device_attribute *devattr, char *buf)
++{
++ struct pmbus_data *data = pmbus_update_device(dev);
++ struct pmbus_sensor *sensor = to_pmbus_sensor(devattr);
++
++ if (sensor->data < 0)
++ return sensor->data;
++ if (sensor->data == 0xffff)
++ return 0;
++
++ return snprintf(buf, PAGE_SIZE, "%ld\n", pmbus_reg2data(data, sensor));
++}
++
++static ssize_t pmbus_set_sensor(struct device *dev,
++ struct device_attribute *devattr,
++ const char *buf, size_t count)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct pmbus_data *data = i2c_get_clientdata(client);
++ struct pmbus_sensor *sensor = to_pmbus_sensor(devattr);
++ ssize_t rv = count;
++ long val = 0;
++ int ret;
++ u16 regval;
++
++ if ((val = simple_strtol(buf, NULL, 10)) < 0)
++ return -EINVAL;
++
++ mutex_lock(&data->update_lock);
++ regval = pmbus_data2reg(data, sensor->class, val);
++ ret = _pmbus_write_word_data(client, sensor->page, sensor->reg, regval);
++ if (ret < 0)
++ rv = ret;
++ else
++ sensor->data = regval;
++ mutex_unlock(&data->update_lock);
++ return rv;
++}
++
++static ssize_t pmbus_show_label(struct device *dev,
++ struct device_attribute *da, char *buf)
++{
++ struct pmbus_label *label = to_pmbus_label(da);
++
++ return snprintf(buf, PAGE_SIZE, "%s\n", label->label);
++}
++
++static int pmbus_add_attribute(struct pmbus_data *data, struct attribute *attr)
++{
++ if (data->num_attributes >= data->max_attributes - 1) {
++ int new_max_attrs = data->max_attributes + PMBUS_ATTR_ALLOC_SIZE;
++ void *new_attrs = krealloc(data->group.attrs,
++ new_max_attrs * sizeof(void *),
++ GFP_KERNEL);
++ if (!new_attrs)
++ return -ENOMEM;
++ data->group.attrs = new_attrs;
++ data->max_attributes = new_max_attrs;
++ }
++
++ data->group.attrs[data->num_attributes++] = attr;
++ data->group.attrs[data->num_attributes] = NULL;
++ return 0;
++}
++
++static void pmbus_dev_attr_init(struct device_attribute *dev_attr,
++ const char *name,
++ umode_t mode,
++ ssize_t (*show)(struct device *dev,
++ struct device_attribute *attr,
++ char *buf),
++ ssize_t (*store)(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count))
++{
++ // KML: Unnecessary in 2.6.28:
++ //sysfs_attr_init(&dev_attr->attr);
++ dev_attr->attr.name = name;
++ dev_attr->attr.mode = mode;
++ dev_attr->show = show;
++ dev_attr->store = store;
++}
++
++static void pmbus_attr_init(struct sensor_device_attribute *a,
++ const char *name,
++ umode_t mode,
++ ssize_t (*show)(struct device *dev,
++ struct device_attribute *attr,
++ char *buf),
++ ssize_t (*store)(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count),
++ int idx)
++{
++ pmbus_dev_attr_init(&a->dev_attr, name, mode, show, store);
++ a->index = idx;
++}
++
++static int pmbus_add_boolean(struct pmbus_data *data,
++ const char *name, const char *type, int seq,
++ struct pmbus_sensor *s1,
++ struct pmbus_sensor *s2,
++ u16 reg, u8 mask)
++{
++ struct pmbus_boolean *boolean;
++ struct sensor_device_attribute *a;
++
++ boolean = devm_kzalloc(data->dev, sizeof(*boolean), GFP_KERNEL);
++ if (!boolean)
++ return -ENOMEM;
++
++ a = &boolean->attribute;
++
++ snprintf(boolean->name, sizeof(boolean->name), "%s%d_%s",
++ name, seq, type);
++ boolean->s1 = s1;
++ boolean->s2 = s2;
++ pmbus_attr_init(a, boolean->name, S_IRUGO, pmbus_show_boolean, NULL,
++ (reg << 8) | mask);
++
++ return pmbus_add_attribute(data, &a->dev_attr.attr);
++}
++
++static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data,
++ const char *name, const char *type,
++ int seq, int page, int reg,
++ enum pmbus_sensor_classes class,
++ bool update, bool readonly)
++{
++ struct pmbus_sensor *sensor;
++ struct device_attribute *a;
++
++ sensor = devm_kzalloc(data->dev, sizeof(*sensor), GFP_KERNEL);
++ if (!sensor)
++ return NULL;
++ a = &sensor->attribute;
++
++ snprintf(sensor->name, sizeof(sensor->name), "%s%d_%s",
++ name, seq, type);
++ sensor->page = page;
++ sensor->reg = reg;
++ sensor->class = class;
++ sensor->update = update;
++ pmbus_dev_attr_init(a, sensor->name,
++ readonly ? S_IRUGO : S_IRUGO | S_IWUSR,
++ pmbus_show_sensor, pmbus_set_sensor);
++
++ if (pmbus_add_attribute(data, &a->attr))
++ return NULL;
++
++ sensor->next = data->sensors;
++ data->sensors = sensor;
++
++ return sensor;
++}
++
++static int pmbus_add_label(struct pmbus_data *data,
++ const char *name, int seq,
++ const char *lstring, int index)
++{
++ struct pmbus_label *label;
++ struct device_attribute *a;
++
++ label = devm_kzalloc(data->dev, sizeof(*label), GFP_KERNEL);
++ if (!label)
++ return -ENOMEM;
++
++ a = &label->attribute;
++
++ if (seq == -1)
++ snprintf(label->name, sizeof(label->name), "%s_label", name);
++ else
++ snprintf(label->name, sizeof(label->name), "%s%d_label",
++ name, seq);
++ if (!index)
++ strncpy(label->label, lstring, sizeof(label->label) - 1);
++ else
++ snprintf(label->label, sizeof(label->label), "%s%d", lstring,
++ index);
++
++ pmbus_dev_attr_init(a, label->name, S_IRUGO, pmbus_show_label, NULL);
++ return pmbus_add_attribute(data, &a->attr);
++}
++
++/*
++ * Search for attributes. Allocate sensors, booleans, and labels as needed.
++ */
++
++/*
++ * The pmbus_limit_attr structure describes a single limit attribute
++ * and its associated alarm attribute.
++ */
++struct pmbus_limit_attr {
++ u16 reg; /* Limit register */
++ u16 sbit; /* Alarm attribute status bit */
++ bool update; /* True if register needs updates */
++ bool low; /* True if low limit; for limits with compare
++ functions only */
++ const char *attr; /* Attribute name */
++ const char *alarm; /* Alarm attribute name */
++};
++
++/*
++ * The pmbus_sensor_attr structure describes one sensor attribute. This
++ * description includes a reference to the associated limit attributes.
++ */
++struct pmbus_sensor_attr {
++ u16 reg; /* sensor register */
++ u8 gbit; /* generic status bit */
++ u8 nlimit; /* # of limit registers */
++ enum pmbus_sensor_classes class;/* sensor class */
++ const char *label; /* sensor label */
++ bool paged; /* true if paged sensor */
++ bool update; /* true if update needed */
++ bool compare; /* true if compare function needed */
++ u32 func; /* sensor mask */
++ u32 sfunc; /* sensor status mask */
++ int sbase; /* status base register */
++ const struct pmbus_limit_attr *limit;/* limit registers */
++};
++
++/*
++ * Add a set of limit attributes and, if supported, the associated
++ * alarm attributes.
++ * returns 0 if no alarm register found, 1 if an alarm register was found,
++ * < 0 on errors.
++ */
++static int pmbus_add_limit_attrs(struct i2c_client *client,
++ struct pmbus_data *data,
++ const struct pmbus_driver_info *info,
++ const char *name, int index, int page,
++ struct pmbus_sensor *base,
++ const struct pmbus_sensor_attr *attr)
++{
++ const struct pmbus_limit_attr *l = attr->limit;
++ int nlimit = attr->nlimit;
++ int have_alarm = 0;
++ int i, ret;
++ struct pmbus_sensor *curr;
++
++ for (i = 0; i < nlimit; i++) {
++ if (pmbus_check_word_register(client, page, l->reg)) {
++ curr = pmbus_add_sensor(data, name, l->attr, index,
++ page, l->reg, attr->class,
++ attr->update || l->update,
++ false);
++ if (!curr)
++ return -ENOMEM;
++ if (l->sbit && (info->func[page] & attr->sfunc)) {
++ ret = pmbus_add_boolean(data, name,
++ l->alarm, index,
++ attr->compare ? l->low ? curr : base
++ : NULL,
++ attr->compare ? l->low ? base : curr
++ : NULL,
++ attr->sbase + page, l->sbit);
++ if (ret)
++ return ret;
++ have_alarm = 1;
++ }
++ }
++ l++;
++ }
++ return have_alarm;
++}
++
++static int pmbus_add_sensor_attrs_one(struct i2c_client *client,
++ struct pmbus_data *data,
++ const struct pmbus_driver_info *info,
++ const char *name,
++ int index, int page,
++ const struct pmbus_sensor_attr *attr)
++{
++ struct pmbus_sensor *base;
++ int ret;
++
++ if (attr->label) {
++ ret = pmbus_add_label(data, name, index, attr->label,
++ attr->paged ? page + 1 : 0);
++ if (ret)
++ return ret;
++ }
++ base = pmbus_add_sensor(data, name, "input", index, page, attr->reg,
++ attr->class, true, true);
++ if (!base)
++ return -ENOMEM;
++ if (attr->sfunc) {
++ ret = pmbus_add_limit_attrs(client, data, info, name,
++ index, page, base, attr);
++ if (ret < 0)
++ return ret;
++ /*
++ * Add generic alarm attribute only if there are no individual
++ * alarm attributes, if there is a global alarm bit, and if
++ * the generic status register for this page is accessible.
++ */
++ if (!ret && attr->gbit &&
++ pmbus_check_byte_register(client, page,
++ data->status_register)) {
++ ret = pmbus_add_boolean(data, name, "alarm", index,
++ NULL, NULL,
++ PB_STATUS_BASE + page,
++ attr->gbit);
++ if (ret)
++ return ret;
++ }
++ }
++ return 0;
++}
++
++static int pmbus_add_sensor_attrs(struct i2c_client *client,
++ struct pmbus_data *data,
++ const char *name,
++ const struct pmbus_sensor_attr *attrs,
++ int nattrs)
++{
++ const struct pmbus_driver_info *info = data->info;
++ int index, i;
++ int ret;
++
++ index = 1;
++ for (i = 0; i < nattrs; i++) {
++ int page, pages;
++
++ pages = attrs->paged ? info->pages : 1;
++ for (page = 0; page < pages; page++) {
++ if (!(info->func[page] & attrs->func))
++ continue;
++ ret = pmbus_add_sensor_attrs_one(client, data, info,
++ name, index, page,
++ attrs);
++ if (ret)
++ return ret;
++ index++;
++ }
++ attrs++;
++ }
++ return 0;
++}
++
++static const struct pmbus_limit_attr vin_limit_attrs[] = {
++ {
++ .reg = PMBUS_VIN_UV_WARN_LIMIT,
++ .attr = "min",
++ .alarm = "min_alarm",
++ .sbit = PB_VOLTAGE_UV_WARNING,
++ }, {
++ .reg = PMBUS_VIN_UV_FAULT_LIMIT,
++ .attr = "lcrit",
++ .alarm = "lcrit_alarm",
++ .sbit = PB_VOLTAGE_UV_FAULT,
++ }, {
++ .reg = PMBUS_VIN_OV_WARN_LIMIT,
++ .attr = "max",
++ .alarm = "max_alarm",
++ .sbit = PB_VOLTAGE_OV_WARNING,
++ }, {
++ .reg = PMBUS_VIN_OV_FAULT_LIMIT,
++ .attr = "crit",
++ .alarm = "crit_alarm",
++ .sbit = PB_VOLTAGE_OV_FAULT,
++ }, {
++ .reg = PMBUS_VIRT_READ_VIN_AVG,
++ .update = true,
++ .attr = "average",
++ }, {
++ .reg = PMBUS_VIRT_READ_VIN_MIN,
++ .update = true,
++ .attr = "lowest",
++ }, {
++ .reg = PMBUS_VIRT_READ_VIN_MAX,
++ .update = true,
++ .attr = "highest",
++ }, {
++ .reg = PMBUS_VIRT_RESET_VIN_HISTORY,
++ .attr = "reset_history",
++ },
++};
++
++static const struct pmbus_limit_attr vmon_limit_attrs[] = {
++ {
++ .reg = PMBUS_VIRT_VMON_UV_WARN_LIMIT,
++ .attr = "min",
++ .alarm = "min_alarm",
++ .sbit = PB_VOLTAGE_UV_WARNING,
++ }, {
++ .reg = PMBUS_VIRT_VMON_UV_FAULT_LIMIT,
++ .attr = "lcrit",
++ .alarm = "lcrit_alarm",
++ .sbit = PB_VOLTAGE_UV_FAULT,
++ }, {
++ .reg = PMBUS_VIRT_VMON_OV_WARN_LIMIT,
++ .attr = "max",
++ .alarm = "max_alarm",
++ .sbit = PB_VOLTAGE_OV_WARNING,
++ }, {
++ .reg = PMBUS_VIRT_VMON_OV_FAULT_LIMIT,
++ .attr = "crit",
++ .alarm = "crit_alarm",
++ .sbit = PB_VOLTAGE_OV_FAULT,
++ }
++};
++
++static const struct pmbus_limit_attr vout_limit_attrs[] = {
++ {
++ .reg = PMBUS_VOUT_UV_WARN_LIMIT,
++ .attr = "min",
++ .alarm = "min_alarm",
++ .sbit = PB_VOLTAGE_UV_WARNING,
++ }, {
++ .reg = PMBUS_VOUT_UV_FAULT_LIMIT,
++ .attr = "lcrit",
++ .alarm = "lcrit_alarm",
++ .sbit = PB_VOLTAGE_UV_FAULT,
++ }, {
++ .reg = PMBUS_VOUT_OV_WARN_LIMIT,
++ .attr = "max",
++ .alarm = "max_alarm",
++ .sbit = PB_VOLTAGE_OV_WARNING,
++ }, {
++ .reg = PMBUS_VOUT_OV_FAULT_LIMIT,
++ .attr = "crit",
++ .alarm = "crit_alarm",
++ .sbit = PB_VOLTAGE_OV_FAULT,
++ }, {
++ .reg = PMBUS_VIRT_READ_VOUT_AVG,
++ .update = true,
++ .attr = "average",
++ }, {
++ .reg = PMBUS_VIRT_READ_VOUT_MIN,
++ .update = true,
++ .attr = "lowest",
++ }, {
++ .reg = PMBUS_VIRT_READ_VOUT_MAX,
++ .update = true,
++ .attr = "highest",
++ }, {
++ .reg = PMBUS_VIRT_RESET_VOUT_HISTORY,
++ .attr = "reset_history",
++ }
++};
++
++static const struct pmbus_sensor_attr voltage_attributes[] = {
++ {
++ .reg = PMBUS_READ_VIN,
++ .class = PSC_VOLTAGE_IN,
++ .label = "vin",
++ .func = PMBUS_HAVE_VIN,
++ .sfunc = PMBUS_HAVE_STATUS_INPUT,
++ .sbase = PB_STATUS_INPUT_BASE,
++ .gbit = PB_STATUS_VIN_UV,
++ .limit = vin_limit_attrs,
++ .nlimit = ARRAY_SIZE(vin_limit_attrs),
++ }, {
++ .reg = PMBUS_VIRT_READ_VMON,
++ .class = PSC_VOLTAGE_IN,
++ .label = "vmon",
++ .func = PMBUS_HAVE_VMON,
++ .sfunc = PMBUS_HAVE_STATUS_VMON,
++ .sbase = PB_STATUS_VMON_BASE,
++ .limit = vmon_limit_attrs,
++ .nlimit = ARRAY_SIZE(vmon_limit_attrs),
++ }, {
++ .reg = PMBUS_READ_VCAP,
++ .class = PSC_VOLTAGE_IN,
++ .label = "vcap",
++ .func = PMBUS_HAVE_VCAP,
++ }, {
++ .reg = PMBUS_READ_VOUT,
++ .class = PSC_VOLTAGE_OUT,
++ .label = "vout",
++ .paged = true,
++ .func = PMBUS_HAVE_VOUT,
++ .sfunc = PMBUS_HAVE_STATUS_VOUT,
++ .sbase = PB_STATUS_VOUT_BASE,
++ .gbit = PB_STATUS_VOUT_OV,
++ .limit = vout_limit_attrs,
++ .nlimit = ARRAY_SIZE(vout_limit_attrs),
++ }
++};
++
++/* Current attributes */
++
++static const struct pmbus_limit_attr iin_limit_attrs[] = {
++ {
++ .reg = PMBUS_IIN_OC_WARN_LIMIT,
++ .attr = "max",
++ .alarm = "max_alarm",
++ .sbit = PB_IIN_OC_WARNING,
++ }, {
++ .reg = PMBUS_IIN_OC_FAULT_LIMIT,
++ .attr = "crit",
++ .alarm = "crit_alarm",
++ .sbit = PB_IIN_OC_FAULT,
++ }, {
++ .reg = PMBUS_VIRT_READ_IIN_AVG,
++ .update = true,
++ .attr = "average",
++ }, {
++ .reg = PMBUS_VIRT_READ_IIN_MIN,
++ .update = true,
++ .attr = "lowest",
++ }, {
++ .reg = PMBUS_VIRT_READ_IIN_MAX,
++ .update = true,
++ .attr = "highest",
++ }, {
++ .reg = PMBUS_VIRT_RESET_IIN_HISTORY,
++ .attr = "reset_history",
++ }
++};
++
++static const struct pmbus_limit_attr iout_limit_attrs[] = {
++ {
++ .reg = PMBUS_IOUT_OC_WARN_LIMIT,
++ .attr = "max",
++ .alarm = "max_alarm",
++ .sbit = PB_IOUT_OC_WARNING,
++ }, {
++ .reg = PMBUS_IOUT_UC_FAULT_LIMIT,
++ .attr = "lcrit",
++ .alarm = "lcrit_alarm",
++ .sbit = PB_IOUT_UC_FAULT,
++ }, {
++ .reg = PMBUS_IOUT_OC_FAULT_LIMIT,
++ .attr = "crit",
++ .alarm = "crit_alarm",
++ .sbit = PB_IOUT_OC_FAULT,
++ }, {
++ .reg = PMBUS_VIRT_READ_IOUT_AVG,
++ .update = true,
++ .attr = "average",
++ }, {
++ .reg = PMBUS_VIRT_READ_IOUT_MIN,
++ .update = true,
++ .attr = "lowest",
++ }, {
++ .reg = PMBUS_VIRT_READ_IOUT_MAX,
++ .update = true,
++ .attr = "highest",
++ }, {
++ .reg = PMBUS_VIRT_RESET_IOUT_HISTORY,
++ .attr = "reset_history",
++ }
++};
++
++static const struct pmbus_sensor_attr current_attributes[] = {
++ {
++ .reg = PMBUS_READ_IIN,
++ .class = PSC_CURRENT_IN,
++ .label = "iin",
++ .func = PMBUS_HAVE_IIN,
++ .sfunc = PMBUS_HAVE_STATUS_INPUT,
++ .sbase = PB_STATUS_INPUT_BASE,
++ .limit = iin_limit_attrs,
++ .nlimit = ARRAY_SIZE(iin_limit_attrs),
++ }, {
++ .reg = PMBUS_READ_IOUT,
++ .class = PSC_CURRENT_OUT,
++ .label = "iout",
++ .paged = true,
++ .func = PMBUS_HAVE_IOUT,
++ .sfunc = PMBUS_HAVE_STATUS_IOUT,
++ .sbase = PB_STATUS_IOUT_BASE,
++ .gbit = PB_STATUS_IOUT_OC,
++ .limit = iout_limit_attrs,
++ .nlimit = ARRAY_SIZE(iout_limit_attrs),
++ }
++};
++
++/* Power attributes */
++
++static const struct pmbus_limit_attr pin_limit_attrs[] = {
++ {
++ .reg = PMBUS_PIN_OP_WARN_LIMIT,
++ .attr = "max",
++ .alarm = "alarm",
++ .sbit = PB_PIN_OP_WARNING,
++ }, {
++ .reg = PMBUS_VIRT_READ_PIN_AVG,
++ .update = true,
++ .attr = "average",
++ }, {
++ .reg = PMBUS_VIRT_READ_PIN_MAX,
++ .update = true,
++ .attr = "input_highest",
++ }, {
++ .reg = PMBUS_VIRT_RESET_PIN_HISTORY,
++ .attr = "reset_history",
++ }
++};
++
++static const struct pmbus_limit_attr pout_limit_attrs[] = {
++ {
++ .reg = PMBUS_POUT_MAX,
++ .attr = "cap",
++ .alarm = "cap_alarm",
++ .sbit = PB_POWER_LIMITING,
++ }, {
++ .reg = PMBUS_POUT_OP_WARN_LIMIT,
++ .attr = "max",
++ .alarm = "max_alarm",
++ .sbit = PB_POUT_OP_WARNING,
++ }, {
++ .reg = PMBUS_POUT_OP_FAULT_LIMIT,
++ .attr = "crit",
++ .alarm = "crit_alarm",
++ .sbit = PB_POUT_OP_FAULT,
++ }, {
++ .reg = PMBUS_VIRT_READ_POUT_AVG,
++ .update = true,
++ .attr = "average",
++ }, {
++ .reg = PMBUS_VIRT_READ_POUT_MAX,
++ .update = true,
++ .attr = "input_highest",
++ }, {
++ .reg = PMBUS_VIRT_RESET_POUT_HISTORY,
++ .attr = "reset_history",
++ }
++};
++
++static const struct pmbus_sensor_attr power_attributes[] = {
++ {
++ .reg = PMBUS_READ_PIN,
++ .class = PSC_POWER,
++ .label = "pin",
++ .func = PMBUS_HAVE_PIN,
++ .sfunc = PMBUS_HAVE_STATUS_INPUT,
++ .sbase = PB_STATUS_INPUT_BASE,
++ .limit = pin_limit_attrs,
++ .nlimit = ARRAY_SIZE(pin_limit_attrs),
++ }, {
++ .reg = PMBUS_READ_POUT,
++ .class = PSC_POWER,
++ .label = "pout",
++ .paged = true,
++ .func = PMBUS_HAVE_POUT,
++ .sfunc = PMBUS_HAVE_STATUS_IOUT,
++ .sbase = PB_STATUS_IOUT_BASE,
++ .limit = pout_limit_attrs,
++ .nlimit = ARRAY_SIZE(pout_limit_attrs),
++ }
++};
++
++/* Temperature atributes */
++
++static const struct pmbus_limit_attr temp_limit_attrs[] = {
++ {
++ .reg = PMBUS_UT_WARN_LIMIT,
++ .low = true,
++ .attr = "min",
++ .alarm = "min_alarm",
++ .sbit = PB_TEMP_UT_WARNING,
++ }, {
++ .reg = PMBUS_UT_FAULT_LIMIT,
++ .low = true,
++ .attr = "lcrit",
++ .alarm = "lcrit_alarm",
++ .sbit = PB_TEMP_UT_FAULT,
++ }, {
++ .reg = PMBUS_OT_WARN_LIMIT,
++ .attr = "max",
++ .alarm = "max_alarm",
++ .sbit = PB_TEMP_OT_WARNING,
++ }, {
++ .reg = PMBUS_OT_FAULT_LIMIT,
++ .attr = "crit",
++ .alarm = "crit_alarm",
++ .sbit = PB_TEMP_OT_FAULT,
++ }, {
++ .reg = PMBUS_VIRT_READ_TEMP_MIN,
++ .attr = "lowest",
++ }, {
++ .reg = PMBUS_VIRT_READ_TEMP_AVG,
++ .attr = "average",
++ }, {
++ .reg = PMBUS_VIRT_READ_TEMP_MAX,
++ .attr = "highest",
++ }, {
++ .reg = PMBUS_VIRT_RESET_TEMP_HISTORY,
++ .attr = "reset_history",
++ }
++};
++
++static const struct pmbus_limit_attr temp_limit_attrs2[] = {
++ {
++ .reg = PMBUS_UT_WARN_LIMIT,
++ .low = true,
++ .attr = "min",
++ .alarm = "min_alarm",
++ .sbit = PB_TEMP_UT_WARNING,
++ }, {
++ .reg = PMBUS_UT_FAULT_LIMIT,
++ .low = true,
++ .attr = "lcrit",
++ .alarm = "lcrit_alarm",
++ .sbit = PB_TEMP_UT_FAULT,
++ }, {
++ .reg = PMBUS_OT_WARN_LIMIT,
++ .attr = "max",
++ .alarm = "max_alarm",
++ .sbit = PB_TEMP_OT_WARNING,
++ }, {
++ .reg = PMBUS_OT_FAULT_LIMIT,
++ .attr = "crit",
++ .alarm = "crit_alarm",
++ .sbit = PB_TEMP_OT_FAULT,
++ }, {
++ .reg = PMBUS_VIRT_READ_TEMP2_MIN,
++ .attr = "lowest",
++ }, {
++ .reg = PMBUS_VIRT_READ_TEMP2_AVG,
++ .attr = "average",
++ }, {
++ .reg = PMBUS_VIRT_READ_TEMP2_MAX,
++ .attr = "highest",
++ }, {
++ .reg = PMBUS_VIRT_RESET_TEMP2_HISTORY,
++ .attr = "reset_history",
++ }
++};
++
++static const struct pmbus_limit_attr temp_limit_attrs3[] = {
++ {
++ .reg = PMBUS_UT_WARN_LIMIT,
++ .low = true,
++ .attr = "min",
++ .alarm = "min_alarm",
++ .sbit = PB_TEMP_UT_WARNING,
++ }, {
++ .reg = PMBUS_UT_FAULT_LIMIT,
++ .low = true,
++ .attr = "lcrit",
++ .alarm = "lcrit_alarm",
++ .sbit = PB_TEMP_UT_FAULT,
++ }, {
++ .reg = PMBUS_OT_WARN_LIMIT,
++ .attr = "max",
++ .alarm = "max_alarm",
++ .sbit = PB_TEMP_OT_WARNING,
++ }, {
++ .reg = PMBUS_OT_FAULT_LIMIT,
++ .attr = "crit",
++ .alarm = "crit_alarm",
++ .sbit = PB_TEMP_OT_FAULT,
++ }
++};
++
++static const struct pmbus_sensor_attr temp_attributes[] = {
++ {
++ .reg = PMBUS_READ_TEMPERATURE_1,
++ .class = PSC_TEMPERATURE,
++ .paged = true,
++ .update = true,
++ .compare = true,
++ .func = PMBUS_HAVE_TEMP,
++ .sfunc = PMBUS_HAVE_STATUS_TEMP,
++ .sbase = PB_STATUS_TEMP_BASE,
++ .gbit = PB_STATUS_TEMPERATURE,
++ .limit = temp_limit_attrs,
++ .nlimit = ARRAY_SIZE(temp_limit_attrs),
++ }, {
++ .reg = PMBUS_READ_TEMPERATURE_2,
++ .class = PSC_TEMPERATURE,
++ .paged = true,
++ .update = true,
++ .compare = true,
++ .func = PMBUS_HAVE_TEMP2,
++ .sfunc = PMBUS_HAVE_STATUS_TEMP,
++ .sbase = PB_STATUS_TEMP_BASE,
++ .gbit = PB_STATUS_TEMPERATURE,
++ .limit = temp_limit_attrs2,
++ .nlimit = ARRAY_SIZE(temp_limit_attrs2),
++ }, {
++ .reg = PMBUS_READ_TEMPERATURE_3,
++ .class = PSC_TEMPERATURE,
++ .paged = true,
++ .update = true,
++ .compare = true,
++ .func = PMBUS_HAVE_TEMP3,
++ .sfunc = PMBUS_HAVE_STATUS_TEMP,
++ .sbase = PB_STATUS_TEMP_BASE,
++ .gbit = PB_STATUS_TEMPERATURE,
++ .limit = temp_limit_attrs3,
++ .nlimit = ARRAY_SIZE(temp_limit_attrs3),
++ }
++};
++
++static const int pmbus_fan_registers[] = {
++ PMBUS_READ_FAN_SPEED_1,
++ PMBUS_READ_FAN_SPEED_2,
++ PMBUS_READ_FAN_SPEED_3,
++ PMBUS_READ_FAN_SPEED_4
++};
++
++static const int pmbus_fan_config_registers[] = {
++ PMBUS_FAN_CONFIG_12,
++ PMBUS_FAN_CONFIG_12,
++ PMBUS_FAN_CONFIG_34,
++ PMBUS_FAN_CONFIG_34
++};
++
++static const int pmbus_fan_status_registers[] = {
++ PMBUS_STATUS_FAN_12,
++ PMBUS_STATUS_FAN_12,
++ PMBUS_STATUS_FAN_34,
++ PMBUS_STATUS_FAN_34
++};
++
++static const u32 pmbus_fan_flags[] = {
++ PMBUS_HAVE_FAN12,
++ PMBUS_HAVE_FAN12,
++ PMBUS_HAVE_FAN34,
++ PMBUS_HAVE_FAN34
++};
++
++static const u32 pmbus_fan_status_flags[] = {
++ PMBUS_HAVE_STATUS_FAN12,
++ PMBUS_HAVE_STATUS_FAN12,
++ PMBUS_HAVE_STATUS_FAN34,
++ PMBUS_HAVE_STATUS_FAN34
++};
++
++/* Fans */
++static int pmbus_add_fan_attributes(struct i2c_client *client,
++ struct pmbus_data *data)
++{
++ const struct pmbus_driver_info *info = data->info;
++ int index = 1;
++ int page;
++ int ret;
++
++ for (page = 0; page < info->pages; page++) {
++ int f;
++
++ for (f = 0; f < ARRAY_SIZE(pmbus_fan_registers); f++) {
++ int regval;
++
++ if (!(info->func[page] & pmbus_fan_flags[f]))
++ break;
++
++ if (!pmbus_check_word_register(client, page,
++ pmbus_fan_registers[f]))
++ break;
++
++ /*
++ * Skip fan if not installed.
++ * Each fan configuration register covers multiple fans,
++ * so we have to do some magic.
++ */
++ regval = _pmbus_read_byte_data(client, page,
++ pmbus_fan_config_registers[f]);
++ if (regval < 0 ||
++ (!(regval & (PB_FAN_1_INSTALLED >> ((f & 1) * 4)))))
++ continue;
++
++ if (pmbus_add_sensor(data, "fan", "input", index,
++ page, pmbus_fan_registers[f],
++ PSC_FAN, true, true) == NULL)
++ return -ENOMEM;
++
++ /*
++ * Each fan status register covers multiple fans,
++ * so we have to do some magic.
++ */
++ if ((info->func[page] & pmbus_fan_status_flags[f]) &&
++ pmbus_check_byte_register(client,
++ page, pmbus_fan_status_registers[f])) {
++ int base;
++
++ if (f > 1) /* fan 3, 4 */
++ base = PB_STATUS_FAN34_BASE + page;
++ else
++ base = PB_STATUS_FAN_BASE + page;
++ ret = pmbus_add_boolean(data, "fan",
++ "alarm", index, NULL, NULL, base,
++ PB_FAN_FAN1_WARNING >> (f & 1));
++ if (ret)
++ return ret;
++ ret = pmbus_add_boolean(data, "fan",
++ "fault", index, NULL, NULL, base,
++ PB_FAN_FAN1_FAULT >> (f & 1));
++ if (ret)
++ return ret;
++ }
++ index++;
++ }
++ }
++ return 0;
++}
++
++static const u32 pmbus_mfr_registers[] = {
++ PMBUS_MFR_ID,
++ PMBUS_MFR_MODEL,
++ PMBUS_MFR_REVISION,
++ /*
++ * PMBUS_MFR_LOCATION is not implemented according to spec
++ * in the pfe1100; rather than showing up as a block read,
++ * it's a word read. Even worse, our block read implementation
++ * will get the first byte, 'A', and stomp all over our buffer,
++ * rather than politely declining to read 65 bytes, as it should.
++ *
++ * Clearly, we should fix the implementation rather than hack it
++ * in here, but we want to get this out the door. With more
++ * experience, hopefully we can come up with a more general
++ * implmentation of the MFR register reads.
++ */
++ PMBUS_MFR_DATE,
++ PMBUS_MFR_SERIAL,
++};
++
++static const char *pmbus_mfr_names[] = {
++ "mfr_id",
++ "mfr_model",
++ "mfr_revision",
++ /* "mfr_location", as mentioned above, is not readable */
++ "mfr_date",
++ "mfr_serial",
++};
++
++/* MFR info */
++static int pmbus_add_mfr_attributes(struct i2c_client *client,
++ struct pmbus_data *data)
++{
++ int f;
++ char buf[I2C_SMBUS_BLOCK_MAX + 1];
++
++ if ((data->info->func[0] & PMBUS_HAVE_MFRDATA) == 0 ||
++ !i2c_check_functionality(client->adapter,
++ I2C_FUNC_SMBUS_READ_BLOCK_DATA))
++ return 0;
++
++ for (f = 0; f < ARRAY_SIZE(pmbus_mfr_registers); f++) {
++ int ret;
++
++ pmbus_wait(client);
++ ret = i2c_smbus_read_block_data(client, pmbus_mfr_registers[f],
++ buf);
++ pmbus_update_wait(client);
++ if (ret <= 0)
++ continue;
++
++ buf[ret] = 0;
++ if (!(data->flags & PMBUS_SKIP_STATUS_CHECK)) {
++ ret = pmbus_check_status_cml(client);
++ pmbus_clear_fault_page(client, -1);
++ if (ret < 0)
++ continue;
++ }
++
++ /* Note that the label code truncates to PMBUS_NAME_SIZE */
++
++ ret = pmbus_add_label(data, pmbus_mfr_names[f], -1, buf, 0);
++ if (ret)
++ return ret;
++ }
++ return 0;
++}
++
++static int pmbus_find_attributes(struct i2c_client *client,
++ struct pmbus_data *data)
++{
++ int ret;
++
++ /* Voltage sensors */
++ ret = pmbus_add_sensor_attrs(client, data, "in", voltage_attributes,
++ ARRAY_SIZE(voltage_attributes));
++ if (ret)
++ return ret;
++
++ /* Current sensors */
++ ret = pmbus_add_sensor_attrs(client, data, "curr", current_attributes,
++ ARRAY_SIZE(current_attributes));
++ if (ret)
++ return ret;
++
++ /* Power sensors */
++ ret = pmbus_add_sensor_attrs(client, data, "power", power_attributes,
++ ARRAY_SIZE(power_attributes));
++ if (ret)
++ return ret;
++
++ /* Temperature sensors */
++ ret = pmbus_add_sensor_attrs(client, data, "temp", temp_attributes,
++ ARRAY_SIZE(temp_attributes));
++ if (ret)
++ return ret;
++
++ /* Fans */
++ ret = pmbus_add_fan_attributes(client, data);
++ if (ret)
++ return ret;
++
++ /* Manufacturer strings */
++ ret = pmbus_add_mfr_attributes(client, data);
++ return ret;
++}
++
++/*
++ * Identify chip parameters.
++ * This function is called for all chips.
++ */
++static int pmbus_identify_common(struct i2c_client *client,
++ struct pmbus_data *data)
++{
++ int vout_mode = -1;
++
++ if (pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE))
++ vout_mode = _pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE);
++ if (vout_mode >= 0 && vout_mode != 0xff) {
++ /*
++ * Not all chips support the VOUT_MODE command,
++ * so a failure to read it is not an error.
++ */
++ switch (vout_mode >> 5) {
++ case 0: /* linear mode */
++ if (data->info->format[PSC_VOLTAGE_OUT] != linear)
++ return -ENODEV;
++
++ data->exponent = ((s8)(vout_mode << 3)) >> 3;
++ break;
++ case 1: /* VID mode */
++ if (data->info->format[PSC_VOLTAGE_OUT] != vid)
++ return -ENODEV;
++ break;
++ case 2: /* direct mode */
++ if (data->info->format[PSC_VOLTAGE_OUT] != direct)
++ return -ENODEV;
++ break;
++ default:
++ return -ENODEV;
++ }
++ }
++
++ pmbus_clear_fault_page(client, 0);
++ return 0;
++}
++
++static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data,
++ struct pmbus_driver_info *info)
++{
++ struct device *dev = &client->dev;
++ int ret;
++
++ /*
++ * Some PMBus chips don't support PMBUS_STATUS_BYTE, so try
++ * to use PMBUS_STATUS_WORD instead if that is the case.
++ * Bail out if both registers are not supported.
++ */
++ data->status_register = PMBUS_STATUS_WORD;
++ pmbus_wait(client);
++ ret = i2c_smbus_read_word_data(client, PMBUS_STATUS_WORD);
++ pmbus_update_wait(client);
++ if (ret < 0 || ret == 0xffff) {
++ data->status_register = PMBUS_STATUS_BYTE;
++ pmbus_wait(client);
++ ret = i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE);
++ pmbus_update_wait(client);
++ if (ret < 0 || ret == 0xff) {
++ dev_err(dev, "PMBus status register not found\n");
++ return -ENODEV;
++ }
++ }
++
++ pmbus_clear_faults(client);
++
++ if (info->identify) {
++ ret = (*info->identify)(client, info);
++ if (ret < 0) {
++ dev_err(dev, "Chip identification failed\n");
++ return ret;
++ }
++ }
++
++ if (info->pages <= 0 || info->pages > PMBUS_PAGES) {
++ dev_err(dev, "Bad number of PMBus pages: %d\n", info->pages);
++ return -ENODEV;
++ }
++
++ ret = pmbus_identify_common(client, data);
++ if (ret < 0) {
++ dev_err(dev, "Failed to identify chip capabilities\n");
++ return ret;
++ }
++ return 0;
++}
++
++int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id,
++ struct pmbus_driver_info *info)
++{
++ struct device *dev = &client->dev;
++ const struct pmbus_platform_data *pdata = dev->platform_data;
++ struct pmbus_data *data;
++ int ret;
++
++ if (!info)
++ return -ENODEV;
++
++ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE
++ | I2C_FUNC_SMBUS_BYTE_DATA
++ | I2C_FUNC_SMBUS_WORD_DATA))
++ return -ENODEV;
++
++ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
++ if (!data)
++ return -ENOMEM;
++
++ i2c_set_clientdata(client, data);
++ mutex_init(&data->update_lock);
++ data->dev = dev;
++
++ if (pdata)
++ data->flags = pdata->flags;
++ data->info = info;
++ pmbus_update_wait(client); /* Set time of access if info->delay */
++
++ ret = pmbus_init_common(client, data, info);
++ if (ret < 0)
++ return ret;
++
++ ret = pmbus_find_attributes(client, data);
++ if (ret)
++ goto out_kfree;
++
++ /*
++ * If there are no attributes, something is wrong.
++ * Bail out instead of trying to register nothing.
++ */
++ if (!data->num_attributes) {
++ dev_err(dev, "No attributes found\n");
++ ret = -ENODEV;
++ goto out_kfree;
++ }
++
++ /* Register sysfs hooks */
++ ret = sysfs_create_group(&dev->kobj, &data->group);
++ if (ret) {
++ dev_err(dev, "Failed to create sysfs entries\n");
++ goto out_kfree;
++ }
++ data->hwmon_dev = hwmon_device_register(dev);
++ if (IS_ERR(data->hwmon_dev)) {
++ ret = PTR_ERR(data->hwmon_dev);
++ dev_err(dev, "Failed to register hwmon device\n");
++ goto out_hwmon_device_register;
++ }
++ return 0;
++
++out_hwmon_device_register:
++ sysfs_remove_group(&dev->kobj, &data->group);
++out_kfree:
++ kfree(data->group.attrs);
++ return ret;
++}
++EXPORT_SYMBOL_GPL(pmbus_do_probe);
++
++int pmbus_do_remove(struct i2c_client *client)
++{
++ struct pmbus_data *data = i2c_get_clientdata(client);
++ hwmon_device_unregister(data->hwmon_dev);
++ sysfs_remove_group(&client->dev.kobj, &data->group);
++ kfree(data->group.attrs);
++ return 0;
++}
++EXPORT_SYMBOL_GPL(pmbus_do_remove);
++
++MODULE_AUTHOR("Guenter Roeck");
++MODULE_DESCRIPTION("PMBus core driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/hwmon/pmbus/ucd9000.c b/drivers/hwmon/pmbus/ucd9000.c
+new file mode 100644
+index 0000000..fbb1479
+--- /dev/null
++++ b/drivers/hwmon/pmbus/ucd9000.c
+@@ -0,0 +1,246 @@
++/*
++ * Hardware monitoring driver for UCD90xxx Sequencer and System Health
++ * Controller series
++ *
++ * Copyright (C) 2011 Ericsson AB.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/err.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include <linux/i2c/pmbus.h>
++#include "pmbus.h"
++
++enum chips { ucd9000, ucd90120, ucd90124, ucd9090, ucd90910 };
++
++#define UCD9000_MONITOR_CONFIG 0xd5
++#define UCD9000_NUM_PAGES 0xd6
++#define UCD9000_FAN_CONFIG_INDEX 0xe7
++#define UCD9000_FAN_CONFIG 0xe8
++#define UCD9000_DEVICE_ID 0xfd
++
++#define UCD9000_MON_TYPE(x) (((x) >> 5) & 0x07)
++#define UCD9000_MON_PAGE(x) ((x) & 0x0f)
++
++#define UCD9000_MON_VOLTAGE 1
++#define UCD9000_MON_TEMPERATURE 2
++#define UCD9000_MON_CURRENT 3
++#define UCD9000_MON_VOLTAGE_HW 4
++
++#define UCD9000_NUM_FAN 4
++
++struct ucd9000_data {
++ u8 fan_data[UCD9000_NUM_FAN][I2C_SMBUS_BLOCK_MAX];
++ struct pmbus_driver_info info;
++};
++#define to_ucd9000_data(_info) container_of(_info, struct ucd9000_data, info)
++
++static int ucd9000_get_fan_config(struct i2c_client *client, int fan)
++{
++ int fan_config = 0;
++ struct ucd9000_data *data
++ = to_ucd9000_data(pmbus_get_driver_info(client));
++
++ if (data->fan_data[fan][3] & 1)
++ fan_config |= PB_FAN_2_INSTALLED; /* Use lower bit position */
++
++ /* Pulses/revolution */
++ fan_config |= (data->fan_data[fan][3] & 0x06) >> 1;
++
++ return fan_config;
++}
++
++static int ucd9000_read_byte_data(struct i2c_client *client, int page, int reg)
++{
++ int ret = 0;
++ int fan_config;
++
++ switch (reg) {
++ case PMBUS_FAN_CONFIG_12:
++ if (page > 0)
++ return -ENXIO;
++
++ ret = ucd9000_get_fan_config(client, 0);
++ if (ret < 0)
++ return ret;
++ fan_config = ret << 4;
++ ret = ucd9000_get_fan_config(client, 1);
++ if (ret < 0)
++ return ret;
++ fan_config |= ret;
++ ret = fan_config;
++ break;
++ case PMBUS_FAN_CONFIG_34:
++ if (page > 0)
++ return -ENXIO;
++
++ ret = ucd9000_get_fan_config(client, 2);
++ if (ret < 0)
++ return ret;
++ fan_config = ret << 4;
++ ret = ucd9000_get_fan_config(client, 3);
++ if (ret < 0)
++ return ret;
++ fan_config |= ret;
++ ret = fan_config;
++ break;
++ default:
++ ret = -ENODATA;
++ break;
++ }
++ return ret;
++}
++
++static const struct i2c_device_id ucd9000_id[] = {
++ {"ucd9000", ucd9000},
++ {"ucd90120", ucd90120},
++ {"ucd90124", ucd90124},
++ {"ucd9090", ucd9090},
++ {"ucd90910", ucd90910},
++ {}
++};
++MODULE_DEVICE_TABLE(i2c, ucd9000_id);
++
++static int ucd9000_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1];
++ struct ucd9000_data *data;
++ struct pmbus_driver_info *info;
++ const struct i2c_device_id *mid;
++ int i, ret;
++
++ if (!i2c_check_functionality(client->adapter,
++ I2C_FUNC_SMBUS_BYTE_DATA |
++ I2C_FUNC_SMBUS_BLOCK_DATA))
++ return -ENODEV;
++
++ ret = i2c_smbus_read_block_data(client, UCD9000_DEVICE_ID,
++ block_buffer);
++ if (ret < 0) {
++ dev_err(&client->dev, "Failed to read device ID\n");
++ return ret;
++ }
++ block_buffer[ret] = '\0';
++ dev_info(&client->dev, "Device ID %s\n", block_buffer);
++
++ for (mid = ucd9000_id; mid->name[0]; mid++) {
++ if (!strncasecmp(mid->name, block_buffer, strlen(mid->name)))
++ break;
++ }
++ if (!mid->name[0]) {
++ dev_err(&client->dev, "Unsupported device\n");
++ return -ENODEV;
++ }
++
++ if (id->driver_data != ucd9000 && id->driver_data != mid->driver_data)
++ dev_notice(&client->dev,
++ "Device mismatch: Configured %s, detected %s\n",
++ id->name, mid->name);
++
++ data = devm_kzalloc(&client->dev, sizeof(struct ucd9000_data),
++ GFP_KERNEL);
++ if (!data)
++ return -ENOMEM;
++ info = &data->info;
++
++ ret = i2c_smbus_read_byte_data(client, UCD9000_NUM_PAGES);
++ if (ret < 0) {
++ dev_err(&client->dev,
++ "Failed to read number of active pages\n");
++ return ret;
++ }
++ info->pages = ret;
++ if (!info->pages) {
++ dev_err(&client->dev, "No pages configured\n");
++ return -ENODEV;
++ }
++
++ /* The internal temperature sensor is always active */
++ info->func[0] = PMBUS_HAVE_TEMP;
++
++ /* Everything else is configurable */
++ ret = i2c_smbus_read_block_data(client, UCD9000_MONITOR_CONFIG,
++ block_buffer);
++ if (ret <= 0) {
++ dev_err(&client->dev, "Failed to read configuration data\n");
++ return -ENODEV;
++ }
++ for (i = 0; i < ret; i++) {
++ int page = UCD9000_MON_PAGE(block_buffer[i]);
++
++ if (page >= info->pages)
++ continue;
++
++ switch (UCD9000_MON_TYPE(block_buffer[i])) {
++ case UCD9000_MON_VOLTAGE:
++ case UCD9000_MON_VOLTAGE_HW:
++ info->func[page] |= PMBUS_HAVE_VOUT
++ | PMBUS_HAVE_STATUS_VOUT;
++ break;
++ case UCD9000_MON_TEMPERATURE:
++ info->func[page] |= PMBUS_HAVE_TEMP2
++ | PMBUS_HAVE_STATUS_TEMP;
++ break;
++ case UCD9000_MON_CURRENT:
++ info->func[page] |= PMBUS_HAVE_IOUT
++ | PMBUS_HAVE_STATUS_IOUT;
++ break;
++ default:
++ break;
++ }
++ }
++
++ /* Fan configuration */
++ if (mid->driver_data == ucd90124) {
++ for (i = 0; i < UCD9000_NUM_FAN; i++) {
++ i2c_smbus_write_byte_data(client,
++ UCD9000_FAN_CONFIG_INDEX, i);
++ ret = i2c_smbus_read_block_data(client,
++ UCD9000_FAN_CONFIG,
++ data->fan_data[i]);
++ if (ret < 0)
++ return ret;
++ }
++ i2c_smbus_write_byte_data(client, UCD9000_FAN_CONFIG_INDEX, 0);
++
++ info->read_byte_data = ucd9000_read_byte_data;
++ info->func[0] |= PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12
++ | PMBUS_HAVE_FAN34 | PMBUS_HAVE_STATUS_FAN34;
++ }
++
++ return pmbus_do_probe(client, mid, info);
++}
++
++/* This is the driver that will be inserted */
++static struct i2c_driver ucd9000_driver = {
++ .driver = {
++ .name = "ucd9000",
++ },
++ .probe = ucd9000_probe,
++ .remove = pmbus_do_remove,
++ .id_table = ucd9000_id,
++};
++
++module_i2c_driver(ucd9000_driver);
++
++MODULE_AUTHOR("Guenter Roeck");
++MODULE_DESCRIPTION("PMBus driver for TI UCD90xxx");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/hwmon/pmbus/ucd9200.c b/drivers/hwmon/pmbus/ucd9200.c
+new file mode 100644
+index 0000000..033d6ac
+--- /dev/null
++++ b/drivers/hwmon/pmbus/ucd9200.c
+@@ -0,0 +1,180 @@
++/*
++ * Hardware monitoring driver for ucd9200 series Digital PWM System Controllers
++ *
++ * Copyright (C) 2011 Ericsson AB.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/err.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include <linux/i2c/pmbus.h>
++#include "pmbus.h"
++
++#define UCD9200_PHASE_INFO 0xd2
++#define UCD9200_DEVICE_ID 0xfd
++
++enum chips { ucd9200, ucd9220, ucd9222, ucd9224, ucd9240, ucd9244, ucd9246,
++ ucd9248 };
++
++static const struct i2c_device_id ucd9200_id[] = {
++ {"ucd9200", ucd9200},
++ {"ucd9220", ucd9220},
++ {"ucd9222", ucd9222},
++ {"ucd9224", ucd9224},
++ {"ucd9240", ucd9240},
++ {"ucd9244", ucd9244},
++ {"ucd9246", ucd9246},
++ {"ucd9248", ucd9248},
++ {}
++};
++MODULE_DEVICE_TABLE(i2c, ucd9200_id);
++
++static int ucd9200_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1];
++ struct pmbus_driver_info *info;
++ const struct i2c_device_id *mid;
++ int i, j, ret;
++
++ if (!i2c_check_functionality(client->adapter,
++ I2C_FUNC_SMBUS_BYTE_DATA |
++ I2C_FUNC_SMBUS_BLOCK_DATA))
++ return -ENODEV;
++
++ ret = i2c_smbus_read_block_data(client, UCD9200_DEVICE_ID,
++ block_buffer);
++ if (ret < 0) {
++ dev_err(&client->dev, "Failed to read device ID\n");
++ return ret;
++ }
++ block_buffer[ret] = '\0';
++ dev_info(&client->dev, "Device ID %s\n", block_buffer);
++
++ for (mid = ucd9200_id; mid->name[0]; mid++) {
++ if (!strncasecmp(mid->name, block_buffer, strlen(mid->name)))
++ break;
++ }
++ if (!mid->name[0]) {
++ dev_err(&client->dev, "Unsupported device\n");
++ return -ENODEV;
++ }
++ if (id->driver_data != ucd9200 && id->driver_data != mid->driver_data)
++ dev_notice(&client->dev,
++ "Device mismatch: Configured %s, detected %s\n",
++ id->name, mid->name);
++
++ info = devm_kzalloc(&client->dev, sizeof(struct pmbus_driver_info),
++ GFP_KERNEL);
++ if (!info)
++ return -ENOMEM;
++
++ ret = i2c_smbus_read_block_data(client, UCD9200_PHASE_INFO,
++ block_buffer);
++ if (ret < 0) {
++ dev_err(&client->dev, "Failed to read phase information\n");
++ return ret;
++ }
++
++ /*
++ * Calculate number of configured pages (rails) from PHASE_INFO
++ * register.
++ * Rails have to be sequential, so we can abort after finding
++ * the first unconfigured rail.
++ */
++ info->pages = 0;
++ for (i = 0; i < ret; i++) {
++ if (!block_buffer[i])
++ break;
++ info->pages++;
++ }
++ if (!info->pages) {
++ dev_err(&client->dev, "No rails configured\n");
++ return -ENODEV;
++ }
++ dev_info(&client->dev, "%d rails configured\n", info->pages);
++
++ /*
++ * Set PHASE registers on all pages to 0xff to ensure that phase
++ * specific commands will apply to all phases of a given page (rail).
++ * This only affects the READ_IOUT and READ_TEMPERATURE2 registers.
++ * READ_IOUT will return the sum of currents of all phases of a rail,
++ * and READ_TEMPERATURE2 will return the maximum temperature detected
++ * for the the phases of the rail.
++ */
++ for (i = 0; i < info->pages; i++) {
++ /*
++ * Setting PAGE & PHASE fails once in a while for no obvious
++ * reason, so we need to retry a couple of times.
++ */
++ for (j = 0; j < 3; j++) {
++ ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, i);
++ if (ret < 0)
++ continue;
++ ret = i2c_smbus_write_byte_data(client, PMBUS_PHASE,
++ 0xff);
++ if (ret < 0)
++ continue;
++ break;
++ }
++ if (ret < 0) {
++ dev_err(&client->dev,
++ "Failed to initialize PHASE registers\n");
++ return ret;
++ }
++ }
++ if (info->pages > 1)
++ i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0);
++
++ info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT |
++ PMBUS_HAVE_IIN | PMBUS_HAVE_PIN |
++ PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
++ PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
++ PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP |
++ PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP;
++
++ for (i = 1; i < info->pages; i++)
++ info->func[i] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
++ PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
++ PMBUS_HAVE_POUT |
++ PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP;
++
++ /* ucd9240 supports a single fan */
++ if (mid->driver_data == ucd9240)
++ info->func[0] |= PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12;
++
++ return pmbus_do_probe(client, mid, info);
++}
++
++/* This is the driver that will be inserted */
++static struct i2c_driver ucd9200_driver = {
++ .driver = {
++ .name = "ucd9200",
++ },
++ .probe = ucd9200_probe,
++ .remove = pmbus_do_remove,
++ .id_table = ucd9200_id,
++};
++
++module_i2c_driver(ucd9200_driver);
++
++MODULE_AUTHOR("Guenter Roeck");
++MODULE_DESCRIPTION("PMBus driver for TI UCD922x, UCD924x");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/hwmon/pmbus/zl6100.c b/drivers/hwmon/pmbus/zl6100.c
+new file mode 100644
+index 0000000..8196441
+--- /dev/null
++++ b/drivers/hwmon/pmbus/zl6100.c
+@@ -0,0 +1,419 @@
++/*
++ * Hardware monitoring driver for ZL6100 and compatibles
++ *
++ * Copyright (c) 2011 Ericsson AB.
++ * Copyright (c) 2012 Guenter Roeck
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/err.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include <linux/ktime.h>
++#include <linux/delay.h>
++#include "pmbus.h"
++
++enum chips { zl2004, zl2005, zl2006, zl2008, zl2105, zl2106, zl6100, zl6105,
++ zl9101, zl9117 };
++
++struct zl6100_data {
++ int id;
++ ktime_t access; /* chip access time */
++ int delay; /* Delay between chip accesses in uS */
++ struct pmbus_driver_info info;
++};
++
++#define to_zl6100_data(x) container_of(x, struct zl6100_data, info)
++
++#define ZL6100_MFR_CONFIG 0xd0
++#define ZL6100_DEVICE_ID 0xe4
++
++#define ZL6100_MFR_XTEMP_ENABLE (1 << 7)
++
++#define MFR_VMON_OV_FAULT_LIMIT 0xf5
++#define MFR_VMON_UV_FAULT_LIMIT 0xf6
++#define MFR_READ_VMON 0xf7
++
++#define VMON_UV_WARNING (1 << 5)
++#define VMON_OV_WARNING (1 << 4)
++#define VMON_UV_FAULT (1 << 1)
++#define VMON_OV_FAULT (1 << 0)
++
++#define ZL6100_WAIT_TIME 1000 /* uS */
++
++static ushort delay = ZL6100_WAIT_TIME;
++module_param(delay, ushort, 0644);
++MODULE_PARM_DESC(delay, "Delay between chip accesses in uS");
++
++/* Convert linear sensor value to milli-units */
++static long zl6100_l2d(s16 l)
++{
++ s16 exponent;
++ s32 mantissa;
++ long val;
++
++ exponent = l >> 11;
++ mantissa = ((s16)((l & 0x7ff) << 5)) >> 5;
++
++ val = mantissa;
++
++ /* scale result to milli-units */
++ val = val * 1000L;
++
++ if (exponent >= 0)
++ val <<= exponent;
++ else
++ val >>= -exponent;
++
++ return val;
++}
++
++#define MAX_MANTISSA (1023 * 1000)
++#define MIN_MANTISSA (511 * 1000)
++
++static u16 zl6100_d2l(long val)
++{
++ s16 exponent = 0, mantissa;
++ bool negative = false;
++
++ /* simple case */
++ if (val == 0)
++ return 0;
++
++ if (val < 0) {
++ negative = true;
++ val = -val;
++ }
++
++ /* Reduce large mantissa until it fits into 10 bit */
++ while (val >= MAX_MANTISSA && exponent < 15) {
++ exponent++;
++ val >>= 1;
++ }
++ /* Increase small mantissa to improve precision */
++ while (val < MIN_MANTISSA && exponent > -15) {
++ exponent--;
++ val <<= 1;
++ }
++
++ /* Convert mantissa from milli-units to units */
++ mantissa = DIV_ROUND_CLOSEST(val, 1000);
++
++ /* Ensure that resulting number is within range */
++ if (mantissa > 0x3ff)
++ mantissa = 0x3ff;
++
++ /* restore sign */
++ if (negative)
++ mantissa = -mantissa;
++
++ /* Convert to 5 bit exponent, 11 bit mantissa */
++ return (mantissa & 0x7ff) | ((exponent << 11) & 0xf800);
++}
++
++/* Some chips need a delay between accesses */
++static inline void zl6100_wait(const struct zl6100_data *data)
++{
++ if (data->delay) {
++ s64 delta = ktime_us_delta(ktime_get(), data->access);
++ if (delta < data->delay)
++ udelay(data->delay - delta);
++ }
++}
++
++static int zl6100_read_word_data(struct i2c_client *client, int page, int reg)
++{
++ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
++ struct zl6100_data *data = to_zl6100_data(info);
++ int ret, vreg;
++
++ if (page > 0)
++ return -ENXIO;
++
++ if (data->id == zl2005) {
++ /*
++ * Limit register detection is not reliable on ZL2005.
++ * Make sure registers are not erroneously detected.
++ */
++ switch (reg) {
++ case PMBUS_VOUT_OV_WARN_LIMIT:
++ case PMBUS_VOUT_UV_WARN_LIMIT:
++ case PMBUS_IOUT_OC_WARN_LIMIT:
++ return -ENXIO;
++ }
++ }
++
++ switch (reg) {
++ case PMBUS_VIRT_READ_VMON:
++ vreg = MFR_READ_VMON;
++ break;
++ case PMBUS_VIRT_VMON_OV_WARN_LIMIT:
++ case PMBUS_VIRT_VMON_OV_FAULT_LIMIT:
++ vreg = MFR_VMON_OV_FAULT_LIMIT;
++ break;
++ case PMBUS_VIRT_VMON_UV_WARN_LIMIT:
++ case PMBUS_VIRT_VMON_UV_FAULT_LIMIT:
++ vreg = MFR_VMON_UV_FAULT_LIMIT;
++ break;
++ default:
++ if (reg >= PMBUS_VIRT_BASE)
++ return -ENXIO;
++ vreg = reg;
++ break;
++ }
++
++ zl6100_wait(data);
++ ret = pmbus_read_word_data(client, page, vreg);
++ data->access = ktime_get();
++ if (ret < 0)
++ return ret;
++
++ switch (reg) {
++ case PMBUS_VIRT_VMON_OV_WARN_LIMIT:
++ ret = zl6100_d2l(DIV_ROUND_CLOSEST(zl6100_l2d(ret) * 9, 10));
++ break;
++ case PMBUS_VIRT_VMON_UV_WARN_LIMIT:
++ ret = zl6100_d2l(DIV_ROUND_CLOSEST(zl6100_l2d(ret) * 11, 10));
++ break;
++ }
++
++ return ret;
++}
++
++static int zl6100_read_byte_data(struct i2c_client *client, int page, int reg)
++{
++ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
++ struct zl6100_data *data = to_zl6100_data(info);
++ int ret, status;
++
++ if (page > 0)
++ return -ENXIO;
++
++ zl6100_wait(data);
++
++ switch (reg) {
++ case PMBUS_VIRT_STATUS_VMON:
++ ret = pmbus_read_byte_data(client, 0,
++ PMBUS_STATUS_MFR_SPECIFIC);
++ if (ret < 0)
++ break;
++
++ status = 0;
++ if (ret & VMON_UV_WARNING)
++ status |= PB_VOLTAGE_UV_WARNING;
++ if (ret & VMON_OV_WARNING)
++ status |= PB_VOLTAGE_OV_WARNING;
++ if (ret & VMON_UV_FAULT)
++ status |= PB_VOLTAGE_UV_FAULT;
++ if (ret & VMON_OV_FAULT)
++ status |= PB_VOLTAGE_OV_FAULT;
++ ret = status;
++ break;
++ default:
++ ret = pmbus_read_byte_data(client, page, reg);
++ break;
++ }
++ data->access = ktime_get();
++
++ return ret;
++}
++
++static int zl6100_write_word_data(struct i2c_client *client, int page, int reg,
++ u16 word)
++{
++ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
++ struct zl6100_data *data = to_zl6100_data(info);
++ int ret, vreg;
++
++ if (page > 0)
++ return -ENXIO;
++
++ switch (reg) {
++ case PMBUS_VIRT_VMON_OV_WARN_LIMIT:
++ word = zl6100_d2l(DIV_ROUND_CLOSEST(zl6100_l2d(word) * 10, 9));
++ vreg = MFR_VMON_OV_FAULT_LIMIT;
++ pmbus_clear_cache(client);
++ break;
++ case PMBUS_VIRT_VMON_OV_FAULT_LIMIT:
++ vreg = MFR_VMON_OV_FAULT_LIMIT;
++ pmbus_clear_cache(client);
++ break;
++ case PMBUS_VIRT_VMON_UV_WARN_LIMIT:
++ word = zl6100_d2l(DIV_ROUND_CLOSEST(zl6100_l2d(word) * 10, 11));
++ vreg = MFR_VMON_UV_FAULT_LIMIT;
++ pmbus_clear_cache(client);
++ break;
++ case PMBUS_VIRT_VMON_UV_FAULT_LIMIT:
++ vreg = MFR_VMON_UV_FAULT_LIMIT;
++ pmbus_clear_cache(client);
++ break;
++ default:
++ if (reg >= PMBUS_VIRT_BASE)
++ return -ENXIO;
++ vreg = reg;
++ }
++
++ zl6100_wait(data);
++ ret = pmbus_write_word_data(client, page, vreg, word);
++ data->access = ktime_get();
++
++ return ret;
++}
++
++static int zl6100_write_byte(struct i2c_client *client, int page, u8 value)
++{
++ const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
++ struct zl6100_data *data = to_zl6100_data(info);
++ int ret;
++
++ if (page > 0)
++ return -ENXIO;
++
++ zl6100_wait(data);
++ ret = pmbus_write_byte(client, page, value);
++ data->access = ktime_get();
++
++ return ret;
++}
++
++static const struct i2c_device_id zl6100_id[] = {
++ {"bmr450", zl2005},
++ {"bmr451", zl2005},
++ {"bmr462", zl2008},
++ {"bmr463", zl2008},
++ {"bmr464", zl2008},
++ {"zl2004", zl2004},
++ {"zl2005", zl2005},
++ {"zl2006", zl2006},
++ {"zl2008", zl2008},
++ {"zl2105", zl2105},
++ {"zl2106", zl2106},
++ {"zl6100", zl6100},
++ {"zl6105", zl6105},
++ {"zl9101", zl9101},
++ {"zl9117", zl9117},
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, zl6100_id);
++
++static int zl6100_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ int ret;
++ struct zl6100_data *data;
++ struct pmbus_driver_info *info;
++ u8 device_id[I2C_SMBUS_BLOCK_MAX + 1];
++ const struct i2c_device_id *mid;
++
++ if (!i2c_check_functionality(client->adapter,
++ I2C_FUNC_SMBUS_READ_WORD_DATA
++ | I2C_FUNC_SMBUS_READ_BLOCK_DATA))
++ return -ENODEV;
++
++ ret = i2c_smbus_read_block_data(client, ZL6100_DEVICE_ID,
++ device_id);
++ if (ret < 0) {
++ dev_err(&client->dev, "Failed to read device ID\n");
++ return ret;
++ }
++ device_id[ret] = '\0';
++ dev_info(&client->dev, "Device ID %s\n", device_id);
++
++ mid = NULL;
++ for (mid = zl6100_id; mid->name[0]; mid++) {
++ if (!strncasecmp(mid->name, device_id, strlen(mid->name)))
++ break;
++ }
++ if (!mid->name[0]) {
++ dev_err(&client->dev, "Unsupported device\n");
++ return -ENODEV;
++ }
++ if (id->driver_data != mid->driver_data)
++ dev_notice(&client->dev,
++ "Device mismatch: Configured %s, detected %s\n",
++ id->name, mid->name);
++
++ data = devm_kzalloc(&client->dev, sizeof(struct zl6100_data),
++ GFP_KERNEL);
++ if (!data)
++ return -ENOMEM;
++
++ data->id = mid->driver_data;
++
++ /*
++ * According to information from the chip vendor, all currently
++ * supported chips are known to require a wait time between I2C
++ * accesses.
++ */
++ data->delay = delay;
++
++ /*
++ * Since there was a direct I2C device access above, wait before
++ * accessing the chip again.
++ */
++ data->access = ktime_get();
++ zl6100_wait(data);
++
++ info = &data->info;
++
++ info->pages = 1;
++ info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT
++ | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
++ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
++ | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
++
++ /*
++ * ZL2004, ZL9101M, and ZL9117M support monitoring an extra voltage
++ * (VMON for ZL2004, VDRV for ZL9101M and ZL9117M). Report it as vmon.
++ */
++ if (data->id == zl2004 || data->id == zl9101 || data->id == zl9117)
++ info->func[0] |= PMBUS_HAVE_VMON | PMBUS_HAVE_STATUS_VMON;
++
++ ret = i2c_smbus_read_word_data(client, ZL6100_MFR_CONFIG);
++ if (ret < 0)
++ return ret;
++
++ if (ret & ZL6100_MFR_XTEMP_ENABLE)
++ info->func[0] |= PMBUS_HAVE_TEMP2;
++
++ data->access = ktime_get();
++ zl6100_wait(data);
++
++ info->read_word_data = zl6100_read_word_data;
++ info->read_byte_data = zl6100_read_byte_data;
++ info->write_word_data = zl6100_write_word_data;
++ info->write_byte = zl6100_write_byte;
++
++ return pmbus_do_probe(client, mid, info);
++}
++
++static struct i2c_driver zl6100_driver = {
++ .driver = {
++ .name = "zl6100",
++ },
++ .probe = zl6100_probe,
++ .remove = pmbus_do_remove,
++ .id_table = zl6100_id,
++};
++
++module_i2c_driver(zl6100_driver);
++
++MODULE_AUTHOR("Guenter Roeck");
++MODULE_DESCRIPTION("PMBus driver for ZL6100 and compatibles");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/i2c/busses/i2c-ast.c b/drivers/i2c/busses/i2c-ast.c
+index bccf5a3..7a083de 100644
+--- a/drivers/i2c/busses/i2c-ast.c
++++ b/drivers/i2c/busses/i2c-ast.c
+@@ -88,8 +88,10 @@ struct ast_i2c_dev {
+
+ struct i2c_msg slave_rx_msg[I2C_S_RX_BUF_NUM + 1];
+ struct i2c_msg slave_tx_msg;
++static spinlock_t slave_rx_lock = SPIN_LOCK_UNLOCKED;
+ #endif
+
++static spinlock_t g_master_lock = SPIN_LOCK_UNLOCKED;
+
+ static inline void
+ ast_i2c_write(struct ast_i2c_dev *i2c_dev, u32 val, u32 reg)
+@@ -243,8 +245,9 @@ static void ast_i2c_slave_buff_init(struct ast_i2c_dev *i2c_dev)
+ static void ast_i2c_slave_rdwr_xfer(struct ast_i2c_dev *i2c_dev)
+ {
+ int i;
+- spinlock_t lock;
+- spin_lock(&lock);
++ unsigned long flags;
++
++ spin_lock_irqsave(&slave_rx_lock, flags);
+
+ switch(i2c_dev->slave_event) {
+ case I2C_SLAVE_EVENT_START_WRITE:
+@@ -291,7 +294,7 @@ static void ast_i2c_slave_rdwr_xfer(struct ast_i2c_dev *i2c_dev)
+ i2c_dev->slave_msgs = &slave_tx_msg;
+ break;
+ }
+- spin_unlock(&lock);
++ spin_unlock_irqrestore(&slave_rx_lock, flags);
+
+ }
+
+@@ -299,11 +302,14 @@ static int ast_i2c_slave_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs)
+ {
+ struct ast_i2c_dev *i2c_dev = adap->algo_data;
+ int ret=0, i;
++ unsigned long flags;
+
+ switch(msgs->flags) {
+ case 0:
+ // printk("slave read \n");
+ //cur_msg = get_free_msg;
++ spin_lock_irqsave(&slave_rx_lock, flags);
++
+ for(i=0; i<I2C_S_RX_BUF_NUM; i++) {
+ if((slave_rx_msg[i].addr == 0) && (slave_rx_msg[i].flags == BUFF_FULL)) {
+ memcpy(msgs->buf, slave_rx_msg[i].buf, slave_rx_msg[i].len);
+@@ -313,6 +319,7 @@ static int ast_i2c_slave_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs)
+ break;
+ }
+ }
++ spin_unlock_irqrestore(&slave_rx_lock, flags);
+
+ if(i == I2C_S_RX_BUF_NUM) {
+ printk("No buffer ........ \n");
+@@ -378,13 +385,15 @@ ast_i2c_bus_error_recover(struct ast_i2c_dev *i2c_dev)
+ dev_dbg(i2c_dev->dev, "I2C's master is locking the bus, try to stop it.\n");
+ //
+ init_completion(&i2c_dev->cmd_complete);
++ i2c_dev->cmd_err = 0;
+
+ ast_i2c_write(i2c_dev, AST_I2CD_M_STOP_CMD, I2C_CMD_REG);
+
+ r = wait_for_completion_interruptible_timeout(&i2c_dev->cmd_complete,
+ i2c_dev->adap.timeout*HZ);
+
+- if(i2c_dev->cmd_err) {
++ if(i2c_dev->cmd_err &&
++ i2c_dev->cmd_err != AST_I2CD_INTR_STS_NORMAL_STOP) {
+ dev_dbg(i2c_dev->dev, "recovery error \n");
+ return -1;
+ }
+@@ -411,7 +420,8 @@ ast_i2c_bus_error_recover(struct ast_i2c_dev *i2c_dev)
+
+ r = wait_for_completion_interruptible_timeout(&i2c_dev->cmd_complete,
+ i2c_dev->adap.timeout*HZ);
+- if (i2c_dev->cmd_err != 0) {
++ if (i2c_dev->cmd_err != 0 &&
++ i2c_dev->cmd_err != AST_I2CD_INTR_STS_NORMAL_STOP) {
+ dev_dbg(i2c_dev->dev, "ERROR!! Failed to do recovery command(0x%08x)\n", i2c_dev->cmd_err);
+ return -1;
+ }
+@@ -621,7 +631,9 @@ static void ast_i2c_do_dma_xfer(struct ast_i2c_dev *i2c_dev)
+ }else {
+ //should send next msg
+ if(i2c_dev->master_xfer_cnt != i2c_dev->master_msgs->len)
+- printk("complete rx ... ERROR \n");
++ printk("complete rx ... bus=%d addr=0x%x (%d vs. %d) ERROR\n",
++ i2c_dev->bus_id, i2c_dev->master_msgs->addr,
++ i2c_dev->master_xfer_cnt, i2c_dev->master_msgs->len);
+
+ dev_dbg(i2c_dev->dev, "ast_i2c_do_byte_xfer complete \n");
+ i2c_dev->cmd_err = 0;
+@@ -812,7 +824,9 @@ static void ast_i2c_do_pool_xfer(struct ast_i2c_dev *i2c_dev)
+ } else {
+ //should send next msg
+ if(i2c_dev->master_xfer_cnt != i2c_dev->master_msgs->len)
+- printk("complete rx ... ERROR \n");
++ printk("complete rx ... bus=%d addr=0x%x (%d vs. %d) ERROR\n",
++ i2c_dev->bus_id, i2c_dev->master_msgs->addr,
++ i2c_dev->master_xfer_cnt, i2c_dev->master_msgs->len);
+
+ dev_dbg(i2c_dev->dev, "ast_i2c_do_byte_xfer complete \n");
+ i2c_dev->cmd_err = 0;
+@@ -909,7 +923,9 @@ static void ast_i2c_do_byte_xfer(struct ast_i2c_dev *i2c_dev)
+ } else {
+ //should send next msg
+ if(i2c_dev->master_xfer_cnt != i2c_dev->master_msgs->len)
+- printk("CNT ERROR \n");
++ printk("CNT ERROR bus=%d addr=0x%x (%d vs. %d)\n",
++ i2c_dev->bus_id, i2c_dev->master_msgs->addr,
++ i2c_dev->master_xfer_cnt, i2c_dev->master_msgs->len);
+
+ dev_dbg(i2c_dev->dev, "ast_i2c_do_byte_xfer complete \n");
+ i2c_dev->cmd_err = 0;
+@@ -1039,6 +1055,18 @@ static void ast_i2c_master_xfer_done(struct ast_i2c_dev *i2c_dev)
+ u32 xfer_len;
+ int i;
+ u8 *pool_buf;
++ unsigned long flags;
++
++ spin_lock_irqsave(&g_master_lock, flags);
++
++ /*
++ * This function shall be involked during interrupt handling.
++ * Since the interrupt could be fired at anytime, we will need to make sure
++ * we have the buffer (i2c_dev->master_msgs) to handle the results.
++ */
++ if (!i2c_dev->master_msgs) {
++ goto unlock_out;
++ }
+
+ dev_dbg(i2c_dev->dev, "ast_i2c_master_xfer_done mode[%d]\n",i2c_dev->master_xfer_mode);
+
+@@ -1118,7 +1146,9 @@ next_xfer:
+
+ if(xfer_len !=i2c_dev->master_xfer_len) {
+ //TODO..
+- printk(" ** xfer error \n");
++ printk(" ** xfer error bus=%d addr=0x%x (%d vs. %d)\n",
++ i2c_dev->bus_id, i2c_dev->master_msgs->addr,
++ xfer_len, i2c_dev->master_xfer_len);
+ //should goto stop....
+ i2c_dev->cmd_err = 1;
+ goto done_out;
+@@ -1142,6 +1172,9 @@ done_out:
+ dev_dbg(i2c_dev->dev,"msgs complete \n");
+ complete(&i2c_dev->cmd_complete);
+ }
++
++unlock_out:
++ spin_unlock_irqrestore(&g_master_lock, flags);
+ }
+
+ static void ast_i2c_slave_addr_match(struct ast_i2c_dev *i2c_dev)
+@@ -1214,6 +1247,18 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ sts &= ~AST_I2CD_SMBUS_ALT_INTR_EN;
+ }
+
++ if(AST_I2CD_INTR_STS_ABNORMAL & sts) {
++ i2c_dev->cmd_err |= AST_I2CD_INTR_STS_ABNORMAL;
++ // Turn off interrupts for further abnormal
++ // conditions until we fix this one.
++ ast_i2c_write(i2c_dev,
++ ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
++ ~AST_I2CD_ABNORMAL_INTR_EN,
++ I2C_INTR_CTRL_REG);
++ complete(&i2c_dev->cmd_complete);
++ sts &= ~AST_I2CD_INTR_STS_ABNORMAL;
++ }
++
+ switch(sts) {
+ case AST_I2CD_INTR_STS_TX_ACK:
+ if(i2c_dev->slave_operation == 1) {
+@@ -1251,12 +1296,12 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ } else {
+ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_TX_NAK = %x\n",sts);
+ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_NAK, I2C_INTR_STS_REG);
+- if(i2c_dev->master_msgs->flags == I2C_M_IGNORE_NAK) {
++ if (i2c_dev->master_msgs
++ && i2c_dev->master_msgs->flags & I2C_M_IGNORE_NAK) {
+ dev_dbg(i2c_dev->dev, "I2C_M_IGNORE_NAK next send\n");
+- i2c_dev->cmd_err = 0;
+ } else {
+ dev_dbg(i2c_dev->dev, "NAK error\n");
+- i2c_dev->cmd_err = AST_I2CD_INTR_STS_TX_NAK;
++ i2c_dev->cmd_err |= AST_I2CD_INTR_STS_TX_NAK;
+ }
+ complete(&i2c_dev->cmd_complete);
+ }
+@@ -1270,7 +1315,7 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_TX_NAK| AST_I2CD_INTR_STS_NORMAL_STOP = %x\n",sts);
+ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_NAK | AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);
+ dev_dbg(i2c_dev->dev, "M TX NAK | NORMAL STOP \n");
+- i2c_dev->cmd_err = AST_I2CD_INTR_STS_TX_NAK | AST_I2CD_INTR_STS_NORMAL_STOP;
++ i2c_dev->cmd_err |= AST_I2CD_INTR_STS_TX_NAK | AST_I2CD_INTR_STS_NORMAL_STOP;
+ complete(&i2c_dev->cmd_complete);
+ }
+ break;
+@@ -1316,39 +1361,34 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ } else {
+ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_NORMAL_STOP = %x\n",sts);
+ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);
+- i2c_dev->cmd_err = 0;
++ i2c_dev->cmd_err |= AST_I2CD_INTR_STS_NORMAL_STOP;
+ complete(&i2c_dev->cmd_complete);
+ }
+ break;
+ case (AST_I2CD_INTR_STS_RX_DOWN | AST_I2CD_INTR_STS_NORMAL_STOP):
+- if((i2c_dev->xfer_last == 1) && (i2c_dev->slave_operation == 0)) {
++ /* Whether or not we're done, the hardware thinks we're done, so bail. */
++ if(i2c_dev->slave_operation == 0) {
+ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_RX_DOWN | AST_I2CD_INTR_STS_NORMAL_STOP = %x\n",sts);
+ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_RX_DOWN | AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);
+ //take care
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+ AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+ ast_i2c_master_xfer_done(i2c_dev);
+- } else {
+- printk("TODO .. .. ..\n");
+ }
+ break;
+ case AST_I2CD_INTR_STS_ARBIT_LOSS:
+ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_ARBIT_LOSS = %x\n",sts);
+ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_ARBIT_LOSS, I2C_INTR_STS_REG);
+- i2c_dev->cmd_err = AST_I2CD_INTR_STS_ARBIT_LOSS;
+- complete(&i2c_dev->cmd_complete);
+- break;
+- case AST_I2CD_INTR_STS_ABNORMAL:
+- i2c_dev->cmd_err = AST_I2CD_INTR_STS_ABNORMAL;
++ i2c_dev->cmd_err |= AST_I2CD_INTR_STS_ARBIT_LOSS;
+ complete(&i2c_dev->cmd_complete);
+ break;
+ case AST_I2CD_INTR_STS_SCL_TO:
+- i2c_dev->cmd_err = AST_I2CD_INTR_STS_SCL_TO;
++ i2c_dev->cmd_err |= AST_I2CD_INTR_STS_SCL_TO;
+ complete(&i2c_dev->cmd_complete);
+
+ break;
+ case AST_I2CD_INTR_STS_GCALL_ADDR:
+- i2c_dev->cmd_err = AST_I2CD_INTR_STS_GCALL_ADDR;
++ i2c_dev->cmd_err |= AST_I2CD_INTR_STS_GCALL_ADDR;
+ complete(&i2c_dev->cmd_complete);
+
+ break;
+@@ -1365,7 +1405,6 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ case AST_I2CD_INTR_STS_BUS_RECOVER:
+ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_BUS_RECOVER= %x\n",sts);
+ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_BUS_RECOVER, I2C_INTR_STS_REG);
+- i2c_dev->cmd_err = 0;
+ complete(&i2c_dev->cmd_complete);
+ break;
+ default:
+@@ -1382,6 +1421,9 @@ static int ast_i2c_do_msgs_xfer(struct ast_i2c_dev *i2c_dev, struct i2c_msg *msg
+ {
+ int i;
+ int ret = 1;
++ unsigned long flags;
++
++ spin_lock_irqsave(&g_master_lock, flags);
+
+ //request
+ if(i2c_dev->ast_i2c_data->master_dma == BYTE_MODE)
+@@ -1407,6 +1449,7 @@ static int ast_i2c_do_msgs_xfer(struct ast_i2c_dev *i2c_dev, struct i2c_msg *msg
+
+ i2c_dev->blk_r_flag = 0;
+ init_completion(&i2c_dev->cmd_complete);
++ i2c_dev->cmd_err = 0;
+
+ if(i2c_dev->master_msgs->flags & I2C_M_NOSTART)
+ i2c_dev->master_xfer_cnt = 0;
+@@ -1415,31 +1458,43 @@ static int ast_i2c_do_msgs_xfer(struct ast_i2c_dev *i2c_dev, struct i2c_msg *msg
+
+ i2c_dev->do_master_xfer(i2c_dev);
+
++ spin_unlock_irqrestore(&g_master_lock, flags);
++
+ ret = wait_for_completion_interruptible_timeout(&i2c_dev->cmd_complete,
+ i2c_dev->adap.timeout*HZ);
+
++ spin_lock_irqsave(&g_master_lock, flags);
++ i2c_dev->master_msgs = NULL;
++
+ if (ret == 0) {
+ dev_dbg(i2c_dev->dev, "controller timed out\n");
+ i2c_dev->state = (ast_i2c_read(i2c_dev,I2C_CMD_REG) >> 19) & 0xf;
+ // printk("sts [%x], isr sts [%x] \n",i2c_dev->state, ast_i2c_read(i2c_dev,I2C_INTR_STS_REG));
+ ret = -ETIMEDOUT;
++ spin_unlock_irqrestore(&g_master_lock, flags);
+ goto stop;
+ }
+
+- if(i2c_dev->cmd_err != 0) {
++ if(i2c_dev->cmd_err != 0 &&
++ i2c_dev->cmd_err != AST_I2CD_INTR_STS_NORMAL_STOP) {
+ ret = -EAGAIN;
++ spin_unlock_irqrestore(&g_master_lock, flags);
+ goto stop;
+ }
+-
+ }
+
+- if(i2c_dev->cmd_err == 0) {
++ spin_unlock_irqrestore(&g_master_lock, flags);
++
++ if(i2c_dev->cmd_err == 0 ||
++ i2c_dev->cmd_err == AST_I2CD_INTR_STS_NORMAL_STOP) {
+ ret = num;
+ goto out;
+
+ }
+ stop:
+ init_completion(&i2c_dev->cmd_complete);
++ if(i2c_dev->cmd_err & AST_I2CD_INTR_STS_NORMAL_STOP)
++ goto out;
+ ast_i2c_write(i2c_dev, AST_I2CD_M_STOP_CMD, I2C_CMD_REG);
+ wait_for_completion_interruptible_timeout(&i2c_dev->cmd_complete,
+ i2c_dev->adap.timeout*HZ);
+@@ -1610,6 +1665,8 @@ static int ast_i2c_probe(struct platform_device *pdev)
+ i2c_dev->blk_r_flag = 0;
+ i2c_dev->adap.algo = &i2c_ast_algorithm;
+
++ ast_i2c_dev_init(i2c_dev);
++
+ ret = request_irq(i2c_dev->irq, i2c_ast_handler, IRQF_SHARED,
+ i2c_dev->adap.name, i2c_dev);
+ if (ret) {
+@@ -1617,8 +1674,6 @@ static int ast_i2c_probe(struct platform_device *pdev)
+ goto ereqirq;
+ }
+
+- ast_i2c_dev_init(i2c_dev);
+-
+ #ifdef CONFIG_AST_I2C_SLAVE_RDWR
+ ast_i2c_slave_buff_init(i2c_dev);
+ #endif
+diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
+index 5ced92c..c8e3cf6 100644
+--- a/drivers/i2c/i2c-core.c
++++ b/drivers/i2c/i2c-core.c
+@@ -1842,8 +1842,8 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
+ need to use only one message; when reading, we need two. We initialize
+ most things with sane defaults, to keep the code below somewhat
+ simpler. */
+- unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3];
+- unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2];
++ unsigned char msgbuf0[I2C_SMBUS_BLOCK_LARGE_MAX+3];
++ unsigned char msgbuf1[I2C_SMBUS_BLOCK_LARGE_MAX+2];
+ int num = read_write == I2C_SMBUS_READ?2:1;
+ struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 },
+ { addr, flags | I2C_M_RD, 0, msgbuf1 }
+@@ -1910,6 +1910,23 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
+ msgbuf0[i] = data->block[i-1];
+ }
+ break;
++ case I2C_SMBUS_BLOCK_LARGE_DATA:
++ if (read_write == I2C_SMBUS_READ) {
++ msg[1].flags |= I2C_M_RECV_LEN;
++ msg[1].len = 1; /* block length will be added by
++ the underlying bus driver */
++ } else {
++ msg[0].len = data->block[0] + 2;
++ if (msg[0].len > I2C_SMBUS_BLOCK_LARGE_MAX + 2) {
++ dev_err(&adapter->dev,
++ "Invalid large block write size %d\n",
++ data->block[0]);
++ return -EINVAL;
++ }
++ for (i = 1; i < msg[0].len; i++)
++ msgbuf0[i] = data->block[i-1];
++ }
++ break;
+ case I2C_SMBUS_BLOCK_PROC_CALL:
+ num = 2; /* Another special case */
+ read_write = I2C_SMBUS_READ;
+@@ -1989,6 +2006,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
+ data->block[i+1] = msgbuf1[i];
+ break;
+ case I2C_SMBUS_BLOCK_DATA:
++ case I2C_SMBUS_BLOCK_LARGE_DATA:
+ case I2C_SMBUS_BLOCK_PROC_CALL:
+ for (i = 0; i < msgbuf1[0] + 1; i++)
+ data->block[i] = msgbuf1[i];
+diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
+index 7d1f7e9..07f393d 100644
+--- a/drivers/i2c/i2c-dev.c
++++ b/drivers/i2c/i2c-dev.c
+@@ -245,8 +245,7 @@ static noinline int i2cdev_ioctl_rdrw(struct i2c_client *client,
+ for (i = 0; i < rdwr_arg.nmsgs; i++) {
+ /* Limit the size of the message to a sane amount;
+ * and don't let length change either. */
+- if ((rdwr_pa[i].len > 8192) ||
+- (rdwr_pa[i].flags & I2C_M_RECV_LEN)) {
++ if (rdwr_pa[i].len > 8192) {
+ res = -EINVAL;
+ break;
+ }
+@@ -262,6 +261,31 @@ static noinline int i2cdev_ioctl_rdrw(struct i2c_client *client,
+ res = -EFAULT;
+ break;
+ }
++
++ /* From Linux 3.5: */
++ /*
++ * If the message length is received from the slave (similar
++ * to SMBus block read), we must ensure that the buffer will
++ * be large enough to cope with a message length of
++ * I2C_SMBUS_BLOCK_MAX as this is the maximum underlying bus
++ * drivers allow. The first byte in the buffer must be
++ * pre-filled with the number of extra bytes, which must be
++ * at least one to hold the message length, but can be
++ * greater (for example to account for a checksum byte at
++ * the end of the message.)
++ */
++ if (rdwr_pa[i].flags & I2C_M_RECV_LEN) {
++ if (!(rdwr_pa[i].flags & I2C_M_RD) ||
++ rdwr_pa[i].buf[0] < 1 ||
++ rdwr_pa[i].len < rdwr_pa[i].buf[0] +
++ I2C_SMBUS_BLOCK_MAX) {
++ res = -EINVAL;
++ break;
++ }
++
++ rdwr_pa[i].len = rdwr_pa[i].buf[0];
++ }
++
+ }
+ if (res < 0) {
+ int j;
+@@ -290,7 +314,7 @@ static noinline int i2cdev_ioctl_smbus(struct i2c_client *client,
+ unsigned long arg)
+ {
+ struct i2c_smbus_ioctl_data data_arg;
+- union i2c_smbus_data temp;
++ union i2c_smbus_large_data temp;
+ int datasize, res;
+
+ if (copy_from_user(&data_arg,
+@@ -303,6 +327,7 @@ static noinline int i2cdev_ioctl_smbus(struct i2c_client *client,
+ (data_arg.size != I2C_SMBUS_WORD_DATA) &&
+ (data_arg.size != I2C_SMBUS_PROC_CALL) &&
+ (data_arg.size != I2C_SMBUS_BLOCK_DATA) &&
++ (data_arg.size != I2C_SMBUS_BLOCK_LARGE_DATA) &&
+ (data_arg.size != I2C_SMBUS_I2C_BLOCK_BROKEN) &&
+ (data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA) &&
+ (data_arg.size != I2C_SMBUS_BLOCK_PROC_CALL)) {
+@@ -343,6 +368,8 @@ static noinline int i2cdev_ioctl_smbus(struct i2c_client *client,
+ else if ((data_arg.size == I2C_SMBUS_WORD_DATA) ||
+ (data_arg.size == I2C_SMBUS_PROC_CALL))
+ datasize = sizeof(data_arg.data->word);
++ else if (data_arg.size == I2C_SMBUS_BLOCK_LARGE_DATA)
++ datasize = sizeof(union i2c_smbus_large_data);
+ else /* size == smbus block, i2c block, or block proc. call */
+ datasize = sizeof(data_arg.data->block);
+
+diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
+index 45cb05a..10450cd 100644
+--- a/drivers/mtd/devices/m25p80.c
++++ b/drivers/mtd/devices/m25p80.c
+@@ -503,15 +503,6 @@ static struct flash_info __devinitdata m25p_data [] = {
+ { "at26df161a", 0x1f4601, 0, 64 * 1024, 32, SECT_4K, },
+ { "at26df321", 0x1f4701, 0, 64 * 1024, 64, SECT_4K, },
+
+- /* Macronix */
+- { "mx25l4005a", 0xc22013, 0, 64 * 1024, 8, SECT_4K },
+- { "mx25l3205d", 0xc22016, 0, 64 * 1024, 64, 0 },
+- { "mx25l6405d", 0xc22017, 0, 64 * 1024, 128, 0 },
+- { "mx25l12805d", 0xc22018, 0, 64 * 1024, 256, 0 },
+-
+- { "mx25l12855e", 0xc22618, 0, 64 * 1024, 256, 0 },
+- { "mx25l25635e", 0xc22019, 0, 64 * 1024, 512, 0 },
+-
+ /* Spansion -- single (large) sector size only, at least
+ * for the chips listed here (without boot sectors).
+ */
+@@ -637,7 +628,12 @@ static int __devinit m25p_probe(struct spi_device *spi)
+ dev_warn(&spi->dev, "found %s, expected %s\n",
+ chip ? chip->name : "UNKNOWN",
+ info->name);
+- info = NULL;
++ if (chip) {
++ dev_warn(&spi->dev, "Use %s instead\n", chip->name);
++ info = chip;
++ } else {
++ dev_warn(&spi->dev, "Force to use %s\n", info->name);
++ }
+ }
+ }
+ } else
+diff --git a/drivers/net/ftgmac100_26.c b/drivers/net/ftgmac100_26.c
+index 8575293..fdc77fc 100644
+--- a/drivers/net/ftgmac100_26.c
++++ b/drivers/net/ftgmac100_26.c
+@@ -120,6 +120,8 @@
+ #err "Not define include for GMAC"
+ #endif
+
++#define PHY_DEFAULT_ADDR 0x1F
++
+ /*------------------------------------------------------------------------
+ .
+ . Configuration options, for the experienced user to change.
+@@ -269,9 +271,11 @@ no_phy_access:
+ if (out->miiPhyId == 0xFFFF) { //Realtek PHY at address 1
+ out->phyAddr = 1;
+ }
++#if 0
+ if (out->miiPhyId == 0x0362) {
+ out->phyAddr = 1;
+ }
++#endif
+ out->miiPhyId = ftgmac100_read_phy_register(dev->base_addr, out->phyAddr, 0x02);
+ out->miiPhyId = (out->miiPhyId & 0xffff) << 16;
+ out->miiPhyId |= ftgmac100_read_phy_register(dev->base_addr, out->phyAddr, 0x03) & 0xffff;
+@@ -280,7 +284,7 @@ no_phy_access:
+ case 0x0040: // Broadcom
+ case 0x0141: // Marvell
+ case 0x001c: // Realtek
+- case 0x0362: // BCM54612
++ case 0x0362: // BCM54612, BCM54616
+ break;
+
+ default:
+@@ -334,7 +338,8 @@ static void ftgmac100_reset( struct net_device* dev )
+ speed = (tmp & PHY_SPEED_mask)>>14;
+ netif_carrier_on(dev);
+ }
+- else if (priv->ids.miiPhyId == PHYID_BCM54612E) {
++ else if (priv->ids.miiPhyId == PHYID_BCM54612E
++ || priv->ids.miiPhyId == PHYID_BCM54616S) {
+ // Get link status
+ // First Switch shadow register selector
+ ftgmac100_write_phy_register(dev->base_addr, priv->ids.phyAddr, 0x1C, 0x2000);
+@@ -558,7 +563,8 @@ Re_Get_Link_Status:
+ ,dev->base_addr + IER_REG
+ );
+ }
+- else if (priv->ids.miiPhyId == PHYID_BCM54612E) {
++ else if (priv->ids.miiPhyId == PHYID_BCM54612E
++ || priv->ids.miiPhyId == PHYID_BCM54616S) {
+ outl(
+ // no link PHY link status pin PHYSTS_CHG_bit |
+ AHB_ERR_bit |
+@@ -612,7 +618,8 @@ static void aspeed_mac_timer(unsigned long data)
+ duplex = (tmp & PHY_DUPLEX_mask)>>13;
+ speed = (tmp & PHY_SPEED_mask)>>14;
+ }
+- else if (priv->ids.miiPhyId == PHYID_BCM54612E) {
++ else if (priv->ids.miiPhyId == PHYID_BCM54612E
++ || priv->ids.miiPhyId == PHYID_BCM54616S) {
+ // Get link status
+ // First Switch shadow register selector
+ ftgmac100_write_phy_register(dev->base_addr, priv->ids.phyAddr, 0x1C, 0x2000);
+@@ -913,6 +920,7 @@ static void ftgmac100_phy_configure(struct net_device* dev)
+ case PHYID_VENDOR_BROADCOM:
+ switch (priv->ids.miiPhyId) {
+ case PHYID_BCM54612E:
++ case PHYID_BCM54616S:
+ ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x1C, 0x8C00); // Disable GTXCLK Clock Delay Enable
+ ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x18, 0xF0E7); // Disable RGMII RXD to RXC Skew
+ break;
+@@ -1303,7 +1311,8 @@ static irqreturn_t ftgmac100_interrupt(int irq, void * dev_id, struct pt_regs *
+ // Bits [3:1] are {duplex, speed, link} change interrupts.
+ tmp &= 0x000e;
+ }
+- else if (priv->ids.miiPhyId == PHYID_BCM54612E) {
++ else if (priv->ids.miiPhyId == PHYID_BCM54612E
++ || priv->ids.miiPhyId == PHYID_BCM54616S) {
+ tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x1A);
+ PRINTK("%s: PHY interrupt status, read_phy_reg(0x1A) = 0x%04x\n",
+ dev->name, tmp);
+@@ -1644,7 +1653,8 @@ static int ftgmac100_open(struct net_device *netdev)
+
+ if (((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_BROADCOM) ||
+ ((priv->ids.miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8201EL) ||
+- (priv->ids.miiPhyId == PHYID_BCM54612E)) {
++ (priv->ids.miiPhyId == PHYID_BCM54612E) ||
++ (priv->ids.miiPhyId == PHYID_BCM54616S)) {
+
+ init_timer(&priv->timer);
+ priv->timer.data = (unsigned long)netdev;
+diff --git a/drivers/net/ftgmac100_26.h b/drivers/net/ftgmac100_26.h
+index f145b05..0d47024 100644
+--- a/drivers/net/ftgmac100_26.h
++++ b/drivers/net/ftgmac100_26.h
+@@ -62,7 +62,7 @@
+
+
+ // --------------------------------------------------------------------
+-// ISR_REG ¤Î IMR_REG
++// ISR_REG / IMR_REG
+ // --------------------------------------------------------------------
+ #define HPTXBUF_UNAVA_bit (1UL<<10)
+ #define PHYSTS_CHG_bit (1UL<<9)
+@@ -473,6 +473,7 @@ typedef struct
+ #define PHYID_RTL8211 0x001cc910
+ #define PHYID_RTL8211E 0x001cc915
+ #define PHYID_BCM54612E 0x03625E6A
++#define PHYID_BCM54616S 0x03625D12
+
+
+ /* store this information for the driver.. */
+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
+index dd4cd5a..6c7fe6b 100644
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -419,6 +419,18 @@ config USB_GOKU
+ default USB_GADGET
+ select USB_GADGET_SELECTED
+
++config USB_GADGET_ASPEED_AST
++ boolean "ASPEED AST Virtual Hub"
++ select USB_GADGET_DUALSPEED
++ depends on ARCH_ASPEED
++ help
++ USB device controller for ASPEED AST
++
++config USB_ASPEED_AST
++ tristate
++ depends on USB_GADGET_ASPEED_AST
++ default USB_GADGET
++ select USB_GADGET_SELECTED
+
+ #
+ # LAST -- dummy/emulated controller
+diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
+index bd4041b..a061332 100644
+--- a/drivers/usb/gadget/Makefile
++++ b/drivers/usb/gadget/Makefile
+@@ -19,6 +19,7 @@ obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o
+ obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o
+ obj-$(CONFIG_USB_M66592) += m66592-udc.o
+ obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o
++obj-$(CONFIG_USB_ASPEED_AST) += aspeed_udc.o
+
+ #
+ # USB gadget drivers
+diff --git a/drivers/usb/gadget/aspeed_udc.c b/drivers/usb/gadget/aspeed_udc.c
+new file mode 100644
+index 0000000..a65e52a
+--- /dev/null
++++ b/drivers/usb/gadget/aspeed_udc.c
+@@ -0,0 +1,1043 @@
++/*
++ * aspeed_udc - Driver for Aspeed virtual hub (usb gadget)
++ *
++ * Copyright 2014-present Facebook. All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++//#define DEBUG
++//#define VERBOSE_DEBUG
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/delay.h>
++#include <linux/ioport.h>
++#include <linux/slab.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/interrupt.h>
++#include <linux/proc_fs.h>
++#include <linux/clk.h>
++#include <linux/usb/ch9.h>
++#include <linux/usb/gadget.h>
++#include <linux/dmapool.h>
++#include <linux/dma-mapping.h>
++
++#include <asm/byteorder.h>
++#include <mach/hardware.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/system.h>
++#include <asm/cacheflush.h>
++
++#include "aspeed_udc.h"
++
++#define NUM_ENDPOINTS 14
++#define AST_UDC_EP0_MAXPACKET 64
++
++struct ast_ep *eps;
++static const struct usb_ep_ops ast_ep_ops;
++static int ast_ep_queue(struct usb_ep* _ep, struct usb_request *_rq, gfp_t gfp_flags);
++static void ep_dequeue_all(struct ast_ep* ep, int status);
++static void ep_txrx_check_done(struct ast_ep* ep);
++static void enable_upstream_port(void);
++static void disable_upstream_port(void);
++static int ast_udc_pullup(struct usb_gadget* gadget, int on);
++
++static inline const char* ast_udc_dir2str(u8 dir) {
++ return (dir & USB_DIR_IN) ? "IN" : "OUT";
++}
++
++static int ast_udc_get_frame(struct usb_gadget* gadget) {
++ return -EOPNOTSUPP;
++}
++
++static struct usb_gadget_ops ast_gadget_ops = {
++ .get_frame = ast_udc_get_frame,
++ .pullup = ast_udc_pullup,
++};
++
++static void norelease(struct device *dev) {
++}
++
++static struct aspeed_udc udc = {
++ .gadget = {
++ .ops = &ast_gadget_ops,
++ .ep_list = LIST_HEAD_INIT(udc.gadget.ep_list),
++ .is_dualspeed = 1,
++ .name = "aspeed_udc",
++ .dev = {
++ .bus_id = "gadget",
++ .release = norelease,
++ },
++ },
++ .pullup_on = 1,
++ .ep0_stage = EP0_STAGE_SETUP,
++ .ep0_dir = USB_DIR_IN,
++};
++
++static inline struct ast_usb_request *to_ast_req(struct usb_request* rq)
++{
++ return container_of(rq, struct ast_usb_request, req);
++}
++
++static inline struct ast_ep *to_ast_ep(struct usb_ep* ep)
++{
++ return container_of(ep, struct ast_ep, ep);
++}
++
++static void* ast_alloc_dma_memory(int sz, enum dma_data_direction dir,
++ dma_addr_t *phys)
++{
++ void* mem;
++ mem = kmalloc(sz, GFP_KERNEL | GFP_DMA);
++ if (!mem) {
++ return NULL;
++ }
++
++ *phys = dma_map_single(udc.gadget.dev.parent, mem, sz, dir);
++ return mem;
++}
++
++static void ast_free_dma_memory(int sz, enum dma_data_direction dir,
++ void *mem, dma_addr_t phys)
++{
++ if (phys) {
++ dma_unmap_single(udc.gadget.dev.parent, phys, sz, dir);
++ }
++ if (mem) {
++ kfree(mem);
++ }
++}
++
++static int ast_udc_pullup(struct usb_gadget* gadget, int on) {
++ if(on) {
++ enable_upstream_port();
++ } else {
++ disable_upstream_port();
++ }
++ udc.pullup_on = on;
++ return 0;
++}
++
++static struct ast_ep ep0_ep = {
++ .ep_regs = NULL,
++ .ep = {
++ .name = "ep0",
++ .ops = &ast_ep_ops,
++ .maxpacket = AST_UDC_EP0_MAXPACKET,
++ },
++ .queue = LIST_HEAD_INIT(ep0_ep.queue),
++ .lock = SPIN_LOCK_UNLOCKED,
++ .dma_busy = 0,
++};
++
++static void clear_isr(u32 flag) {
++ ast_hwritel(&udc, ISR, flag);
++}
++
++static void ep0_stall_ready(void) {
++ ast_hwritel(&udc, EP0_STATUS, AST_EP0_STALL);
++}
++
++static void ep0_out_ready(void) {
++ ast_hwritel(&udc, EP0_STATUS, AST_EP0_OUT_READY);
++}
++
++static void ep0_in_ready(size_t size) {
++ ast_hwritel(&udc, EP0_STATUS, (size << 8));
++ ast_hwritel(&udc, EP0_STATUS, (size << 8) | AST_EP0_IN_READY);
++}
++
++static void enable_upstream_port(void) {
++ ast_hwritel(&udc, STATUS, ast_hreadl(&udc, STATUS) | 0x5);
++}
++
++static void disable_upstream_port(void) {
++ ast_hwritel(&udc, STATUS, ast_hreadl(&udc, STATUS) &~ 0x5);
++}
++
++struct ast_usb_request empty_rq = {
++ .req = {
++ .buf = "",
++ .length = 0,
++ },
++ .queue = LIST_HEAD_INIT(empty_rq.queue),
++ .in_transit = 0,
++};
++
++struct ast_ep* ep_by_addr(int addr) {
++ unsigned long flags;
++ int i;
++ struct ast_ep* ep = NULL;
++ for(i = 0; i < NUM_ENDPOINTS && ep == NULL; i++) {
++ struct ast_ep* test = &eps[i];
++ spin_lock_irqsave(&test->lock, flags);
++ if(test->active && test->addr == addr) {
++ ep = test;
++ }
++ spin_unlock_irqrestore(&test->lock, flags);
++ }
++ return ep;
++}
++
++static inline void ep0_init_stage(void)
++{
++ /* expect SETUP after */
++ udc.ep0_stage = EP0_STAGE_SETUP;
++ udc.ep0_dir = USB_DIR_IN;
++}
++
++static void ep0_stall(void) {
++ pr_debug("Prepare for EP0 stall, Reset EP0 stage to SETUP\n");
++ /* reply stall on next pkt */
++ ep0_stall_ready();
++ ep0_init_stage();
++}
++
++static void ep0_next_stage(int has_data_phase, u8 data_dir) {
++#ifdef DEBUG
++ int prev_stage = udc.ep0_stage;
++ int prev_dir = udc.ep0_dir;
++#endif
++
++ switch (udc.ep0_stage) {
++ case EP0_STAGE_SETUP:
++ if (has_data_phase) {
++ udc.ep0_stage = EP0_STAGE_DATA;
++ udc.ep0_dir = (data_dir == USB_DIR_IN) ? USB_DIR_IN : USB_DIR_OUT;
++ } else {
++ udc.ep0_stage = EP0_STAGE_STATUS;
++ udc.ep0_dir = USB_DIR_IN;
++ }
++ break;
++ case EP0_STAGE_DATA:
++ udc.ep0_stage = EP0_STAGE_STATUS;
++ udc.ep0_dir = (udc.ep0_dir == USB_DIR_IN) ? USB_DIR_OUT : USB_DIR_IN;
++ break;
++ case EP0_STAGE_STATUS:
++ udc.ep0_stage = EP0_STAGE_SETUP;
++ udc.ep0_dir = USB_DIR_IN;
++ break;
++ default:
++ pr_err("Wrong EP0 stage %d\n", udc.ep0_stage);
++ break;
++ }
++
++#ifdef DEBUG
++ pr_debug("EP0 stage is changed from %d (%s) to %d (%s)\n",
++ prev_stage, ast_udc_dir2str(prev_dir),
++ udc.ep0_stage, ast_udc_dir2str(udc.ep0_dir));
++#endif
++}
++
++static void ep0_queue_run(void) {
++ struct ast_ep *ep = &ep0_ep;
++
++ /* if ep0 is still doing DMA or no request pending, nothing to do */
++ if (ep->dma_busy || list_empty(&ep->queue)) {
++ return;
++ }
++
++ if (udc.ep0_dir == USB_DIR_OUT) {
++ /* just tell HW we are ready for OUT */
++ ep0_out_ready();
++ } else {
++ size_t sendable;
++ struct ast_usb_request *req;
++
++ req = list_entry(ep->queue.next, struct ast_usb_request, queue);
++ sendable = req->req.length - req->req.actual;
++ if (sendable > AST_UDC_EP0_MAXPACKET) {
++ sendable = AST_UDC_EP0_MAXPACKET;
++ }
++ if (sendable) {
++ memcpy(udc.ep0_dma_virt, req->req.buf + req->req.actual, sendable);
++ }
++ dma_sync_single_for_device(udc.gadget.dev.parent, udc.ep0_dma_phys,
++ AST_UDC_EP0_MAXPACKET, DMA_TO_DEVICE);
++ ep0_in_ready(sendable);
++ req->lastpacket = sendable;
++ }
++ ep->dma_busy = 1;
++}
++
++static int ep0_enqueue(struct usb_ep* _ep, struct usb_request *_rq,
++ gfp_t gfp_flags) {
++ struct ast_usb_request *req = to_ast_req(_rq);
++ struct ast_ep *ep = to_ast_ep(_ep);
++ unsigned long flags;
++ int rc = 0;
++
++ _rq->status = -EINPROGRESS;
++ req->req.actual = 0;
++
++ pr_debug("EP0 enqueue %d bytes at stage %d, %s\n",
++ req->req.length, udc.ep0_stage, ast_udc_dir2str(udc.ep0_dir));
++
++ spin_lock_irqsave(&ep->lock, flags);
++
++ /* shall only happen when in data or status stage */
++ if (udc.ep0_stage != EP0_STAGE_DATA && udc.ep0_stage != EP0_STAGE_STATUS) {
++ pr_err("EP0 enqueue happens at wrong stage %d\n", udc.ep0_stage);
++ rc = -EINPROGRESS;
++ goto out;
++ }
++
++ /* ep0 shall only have one pending request a time */
++ if (!list_empty(&ep->queue)) {
++ pr_err("EP0 enqueue happens with an existing entry on queue\n");
++ } else {
++ list_add_tail(&req->queue, &ep->queue);
++ ep0_queue_run();
++ }
++
++ out:
++ if (rc < 0) {
++ ep0_stall();
++ }
++ spin_unlock_irqrestore(&ep->lock, flags);
++ return rc;
++}
++
++static void ep0_cancel_current(void)
++{
++ struct ast_ep *ep = &ep0_ep;
++ unsigned long flags;
++ ep_dequeue_all(ep, -ECONNRESET);
++ spin_lock_irqsave(&ep->lock, flags);
++ ep0_init_stage();
++ spin_unlock_irqrestore(&ep->lock, flags);
++}
++
++static int ep0_handle_setup(void) {
++ struct ast_ep *ep = &ep0_ep;
++ struct usb_ctrlrequest crq;
++ int rc = 0;
++ u16 val, idx, len;
++ unsigned long flags;
++
++ /* make sure we are expecting setup packet */
++ if (udc.ep0_stage != EP0_STAGE_SETUP) {
++ /*
++ * with g_cdc, we are seeing this message pretty often. could be an
++ * issue on g_cdc. make the log message as debug now
++ */
++ pr_debug("Received SETUP pkt on wrong stage %d. Cancelling "
++ "the current SETUP\n", udc.ep0_stage);
++ ep0_cancel_current();
++ }
++
++ memcpy_fromio(&crq, udc.regs + AST_HUB_ROOT_SETUP_BUFFER, sizeof(crq));
++ val = le16_to_cpu(crq.wValue);
++ idx = le16_to_cpu(crq.wIndex);
++ len = le16_to_cpu(crq.wLength);
++
++ pr_debug("request=%d, reqType=0x%x val=0x%x idx=%d len=%d %s\n",
++ crq.bRequest, crq.bRequestType, val, idx, len,
++ ast_udc_dir2str(crq.bRequestType));
++
++ spin_lock_irqsave(&ep->lock, flags);
++ ep0_next_stage(
++ len, (crq.bRequestType & USB_DIR_IN) ? USB_DIR_IN : USB_DIR_OUT);
++ spin_unlock_irqrestore(&ep->lock, flags);
++
++ switch (crq.bRequest) {
++ case USB_REQ_SET_ADDRESS:
++ udc.hub_address = val;
++ ast_hwritel(&udc, ROOT_CONFIG, udc.hub_address);
++ // reply with an empty pkt for STATUS
++ ep0_enqueue(&ep0_ep.ep, &empty_rq.req, GFP_KERNEL);
++ break;
++
++ case USB_REQ_CLEAR_FEATURE:
++ case USB_REQ_SET_FEATURE:
++ if ((crq.bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD)
++ break;
++ if ((crq.bRequestType & USB_RECIP_MASK) == USB_RECIP_ENDPOINT) {
++ int epaddr = idx & USB_ENDPOINT_NUMBER_MASK;
++ struct ast_ep *ep2;
++ if(val != 0 || len != 0 || epaddr > 15) {
++ ep0_stall();
++ break;
++ }
++ ep2 = ep_by_addr(epaddr);
++ if (ep2) {
++ if(crq.bRequest == USB_REQ_SET_FEATURE) {
++ usb_ep_set_halt(&ep2->ep);
++ } else {
++ usb_ep_clear_halt(&ep2->ep);
++ }
++ }
++ }
++ // reply with an empty pkt for STATUS
++ ep0_enqueue(&ep0_ep.ep, &empty_rq.req, GFP_KERNEL);
++ break;
++
++ default:
++ rc = udc.driver->setup(&udc.gadget, &crq);
++ if (rc < 0) {
++ printk("req %02x, %02x; fail: %d\n", crq.bRequestType,
++ crq.bRequest, rc);
++ ep0_stall();
++ }
++ break;
++ }
++
++ return rc;
++}
++
++static void ep0_handle_ack(void) {
++ struct ast_usb_request *req;
++ struct ast_ep *ep = &ep0_ep;
++ unsigned long status;
++ unsigned long flags;
++ int done = 0;
++
++ spin_lock_irqsave(&ep->lock, flags);
++
++ if (!ep->dma_busy) {
++ goto out;
++ }
++
++ status = ast_hreadl(&udc, EP0_STATUS);
++
++ pr_debug("Check done with status 0x%lx: stage=%d %s\n", status,
++ udc.ep0_stage, ast_udc_dir2str((udc.ep0_dir)));
++
++ if (list_empty(&ep->queue)) {
++ /* we requested DMA but no request */
++ ep->dma_busy = 0;
++ pr_debug("Empty request queue with ep0 status: 0x%lx\n", status);
++ goto out;
++ }
++
++ if ((udc.ep0_dir == USB_DIR_IN && (!(status & AST_EP0_IN_READY)))
++ || (udc.ep0_dir == USB_DIR_OUT && (!(status & AST_EP0_OUT_READY)))) {
++ /* something is ready */
++ ep->dma_busy = 0;
++ req = container_of(ep->queue.next, struct ast_usb_request, queue);
++ req->in_transit = 0;
++ if (udc.ep0_dir == USB_DIR_OUT) {
++ req->lastpacket = (status >> 16) & 0x3F;
++ __cpuc_flush_kern_all();
++ if (req->lastpacket) {
++ memcpy(req->req.buf + req->req.actual, udc.ep0_dma_virt,
++ req->lastpacket);
++ }
++ }
++ req->req.actual += req->lastpacket;
++ pr_debug("EP0 req actual=%d length=%d lastpacket=%d\n",
++ req->req.actual, req->req.length, req->lastpacket);
++ if (req->req.actual >= req->req.length
++ || req->lastpacket < AST_UDC_EP0_MAXPACKET) {
++ list_del_init(&req->queue);
++ done = 1;
++ ep0_next_stage(0, 0);
++ } else {
++ /* the request is not done yet, restart the queue */
++ ep0_queue_run();
++ }
++ }
++
++ out:
++
++ spin_unlock_irqrestore(&ep->lock, flags);
++
++ if (done) {
++ req->req.status = 0;
++ if (req->req.complete) {
++ req->req.complete(&ep->ep, &req->req);
++ }
++ }
++}
++
++static void ep0_handle_status(void) {
++ struct ast_ep *ep = &ep0_ep;
++ unsigned long flags;
++
++ spin_lock_irqsave(&ep->lock, flags);
++
++ /*
++ * If we expect a STATUS from host (OUT), enqueue a reqeust to get it going.
++ * For STATUS to host (IN), the SETUP packet handler needs to enqueue a
++ * STATUS message, therefore, no need to handle it here.
++ */
++ if (udc.ep0_stage == EP0_STAGE_STATUS && udc.ep0_dir == USB_DIR_OUT) {
++ // request with an empty pkt for STATUS from host
++ ep0_enqueue(&ep0_ep.ep, &empty_rq.req, GFP_KERNEL);
++ }
++
++ spin_unlock_irqrestore(&ep->lock, flags);
++}
++
++static struct usb_request *ast_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) {
++ struct ast_usb_request *req;
++ (void) ep;
++ req = kzalloc(sizeof(*req), gfp_flags);
++ INIT_LIST_HEAD(&req->queue);
++ if(!req)
++ return NULL;
++
++ return &req->req;
++}
++
++static void ast_free_request(struct usb_ep *ep, struct usb_request *_req) {
++ struct ast_usb_request *req = to_ast_req(_req);
++ (void) ep;
++ kfree(req);
++}
++
++static int ast_ep_enable(struct usb_ep* _ep, const struct usb_endpoint_descriptor *desc) {
++ struct ast_ep *ep = to_ast_ep(_ep);
++ size_t maxpacket = le16_to_cpu(desc->wMaxPacketSize);
++ int eptype = 0;
++ if(ep->active) {
++ pr_err("Enable an already enabled ep: %s\n", ep->ep.name);
++ return -EBUSY;
++ }
++ ep->ep.maxpacket = maxpacket;
++ pr_debug("Enabling endpoint %s (%p), maxpacket %d: ",
++ ep->ep.name, ep->ep_regs, ep->ep.maxpacket);
++ if (desc->bEndpointAddress & USB_DIR_IN) {
++ ep->to_host = 1;
++ switch (desc->bmAttributes) {
++ case USB_ENDPOINT_XFER_BULK:
++ pr_debug("bulk to host\n");
++ eptype = AST_EP_TYPE_BULK_IN;
++ break;
++ case USB_ENDPOINT_XFER_INT:
++ pr_debug("int to host\n");
++ eptype = AST_EP_TYPE_BULK_IN;
++ break;
++ case USB_ENDPOINT_XFER_ISOC:
++ pr_debug("isoc to host\n");
++ eptype = AST_EP_TYPE_ISO_IN;
++ break;
++ }
++ } else {
++ ep->to_host = 0;
++ switch (desc->bmAttributes) {
++ case USB_ENDPOINT_XFER_BULK:
++ pr_debug("bulk from host\n");
++ eptype = AST_EP_TYPE_BULK_OUT;
++ break;
++ case USB_ENDPOINT_XFER_INT:
++ pr_debug("int from host\n");
++ eptype = AST_EP_TYPE_INT_OUT;
++ break;
++ case USB_ENDPOINT_XFER_ISOC:
++ pr_debug("isoc from host\n");
++ eptype = AST_EP_TYPE_ISO_OUT;
++ break;
++ }
++ }
++
++ ep_hwritel(ep, DMA_CONTROL, AST_EP_DL_RESET);
++ ep_hwritel(ep, DMA_CONTROL, AST_EP_SINGLE_STAGE);
++
++ ep->txbuf = ast_alloc_dma_memory(
++ ep->ep.maxpacket, ep->to_host ? DMA_TO_DEVICE : DMA_FROM_DEVICE,
++ &ep->txbuf_phys);
++
++ if (maxpacket == 1024)
++ maxpacket = 0;
++ ep_hwritel(ep, CONFIG, (maxpacket << 16) | (ep->addr << 8) | (eptype << 4) | AST_EP_ENABLED);
++
++ ep_hwritel(ep, DESC_BASE, ep->txbuf_phys);
++ ep_hwritel(ep, DESC_STATUS, 0);
++
++ ast_hwritel(&udc, EP_ACK_INT_ENABLE, 0x7fff);
++ ep->active = 1;
++ return 0;
++}
++
++static void ep_dequeue_locked(struct ast_ep* ep, struct ast_usb_request *req) {
++ // Cancel in-progress transfer
++ req->req.status = -ECONNRESET;
++ if(req->in_transit) {
++ req->in_transit = 0;
++ ep->dma_busy = 0;
++ ep_hwritel(ep, DESC_STATUS, 0);
++ }
++ list_del_init(&req->queue);
++}
++
++static void ep_dequeue_all(struct ast_ep* ep, int status) {
++ struct ast_usb_request *req;
++ struct ast_usb_request *n;
++ unsigned long flags;
++ spin_lock_irqsave(&ep->lock, flags);
++ list_for_each_entry_safe(req, n, &ep->queue, queue) {
++ ep_dequeue_locked(ep, req);
++ req->req.status = status;
++ if(req->req.complete) {
++ spin_unlock_irqrestore(&ep->lock, flags);
++ req->req.complete(&ep->ep, &req->req);
++ spin_lock_irqsave(&ep->lock, flags);
++ }
++ }
++ spin_unlock_irqrestore(&ep->lock, flags);
++}
++
++static int ast_ep_dequeue(struct usb_ep* _ep, struct usb_request *_rq) {
++ struct ast_usb_request *req = to_ast_req(_rq);
++ struct ast_ep *ep = to_ast_ep(_ep);
++ unsigned long flags;
++ pr_debug("Dequeue a request (%d bytes) from %s\n",
++ req->req.length, ep->ep.name);
++ spin_lock_irqsave(&ep->lock, flags);
++ ep_dequeue_locked(ep, req);
++ if(req->req.complete) {
++ req->req.complete(&ep->ep, &req->req);
++ }
++ spin_unlock_irqrestore(&ep->lock, flags);
++ return 0;
++}
++
++static int ast_ep_disable(struct usb_ep* _ep) {
++ struct ast_ep *ep = to_ast_ep(_ep);
++ unsigned long flags;
++ pr_debug("Disable %s\n", ep->ep.name);
++ if (!ep->active)
++ return 0;
++ ep_dequeue_all(ep, -ESHUTDOWN);
++ spin_lock_irqsave(&ep->lock, flags);
++ ast_free_dma_memory(ep->ep.maxpacket,
++ ep->to_host ? DMA_TO_DEVICE : DMA_FROM_DEVICE,
++ ep->txbuf, ep->txbuf_phys);
++ ep->txbuf_phys = 0;
++ ep->txbuf = NULL;
++ ep->active = 0;
++ ep->ep.maxpacket = 1024;
++ ep_hwritel(ep, CONFIG, 0);
++ spin_unlock_irqrestore(&ep->lock, flags);
++ return 0;
++}
++
++static void disable_all_endpoints(void) {
++ int i;
++ for(i = 0; i < NUM_ENDPOINTS; i++) {
++ if(eps[i].active) {
++ ast_ep_disable(&eps[i].ep);
++ }
++ }
++}
++
++static void ep_txrx(struct ast_ep* ep, void* buf, size_t len) {
++ if(ep->to_host) {
++ memcpy(ep->txbuf, buf, len);
++ }
++ ep_hwritel(ep, DESC_STATUS, len << 16);
++ ep_hwritel(ep, DESC_STATUS, (len << 16) | 1);
++}
++
++static void ep_txrx_check_done(struct ast_ep* ep) {
++ struct ast_usb_request *req;
++ unsigned long flags;
++ u32 status;
++ spin_lock_irqsave(&ep->lock, flags);
++ status = ep_hreadl(ep, DESC_STATUS);
++ // if txrx complete;
++ if(!(status & 0xff) &&
++ !list_empty(&ep->queue)) {
++ req = list_entry(ep->queue.next, struct ast_usb_request, queue);
++ if(!req->in_transit) {
++ spin_unlock_irqrestore(&ep->lock, flags);
++ return;
++ }
++ //head rq completed
++ req->in_transit = 0;
++ ep->dma_busy = 0;
++ if(!ep->to_host) {
++ req->lastpacket = (status >> 16) & 0x3ff;
++ __cpuc_flush_kern_all();
++ memcpy(req->req.buf + req->req.actual, ep->txbuf, req->lastpacket);
++ //print_hex_dump(KERN_DEBUG, "epXrx: ", DUMP_PREFIX_OFFSET, 16, 1, ep->txbuf, req->lastpacket, 0);
++ }
++ req->req.actual += req->lastpacket;
++ if(req->req.actual == req->req.length ||
++ req->lastpacket < ep->ep.maxpacket) {
++ list_del_init(&req->queue);
++ spin_unlock_irqrestore(&ep->lock, flags);
++ //printk("rq done ep%d\n", ep->addr);
++ req->req.status = 0;
++ if(req->req.complete) {
++ req->req.complete(&ep->ep, &req->req);
++ }
++ } else {
++ //printk("rq partial ep%d %d/%d\n", ep->addr, req->req.actual, req->req.length);
++ spin_unlock_irqrestore(&ep->lock, flags);
++ }
++ }
++}
++
++static int ast_ep_queue_run(struct ast_ep* ep) {
++ struct ast_usb_request *req;
++ unsigned long flags;
++ spin_lock_irqsave(&ep->lock, flags);
++ if(ep->active && !ep->dma_busy) {
++ //ep isn't busy..
++ if(list_empty(&ep->queue)) {
++ // nothing
++ } else {
++ req = list_entry(ep->queue.next, struct ast_usb_request, queue);
++ req->lastpacket = req->req.length - req->req.actual;
++ if (req->lastpacket > ep->ep.maxpacket) {
++ req->lastpacket = ep->ep.maxpacket;
++ }
++ //printk("ep%d%sx:%d-%d/%d\n",
++ // ep->addr,
++ // ep->to_host ? "t" : "r",
++ // req->req.actual,
++ // req->req.actual + req->lastpacket,
++ // req->req.length);
++ ep_txrx(ep, req->req.buf + req->req.actual, req->lastpacket);
++ req->in_transit = 1;
++ ep->dma_busy = 1;
++ }
++ }
++ spin_unlock_irqrestore(&ep->lock, flags);
++ return 0;
++}
++
++static void run_all_ep_queues(unsigned long data) {
++ int i;
++ unsigned long flags;
++ spin_lock_irqsave(&udc.lock, flags);
++
++ for(i = 0; i < NUM_ENDPOINTS; i++) {
++ if(eps[i].active) {
++ ep_txrx_check_done(&eps[i]);
++ ast_ep_queue_run(&eps[i]);
++ }
++ }
++
++ spin_unlock_irqrestore(&udc.lock, flags);
++}
++
++DECLARE_TASKLET(check_ep_queues, run_all_ep_queues, 0);
++
++static int ast_ep_queue(struct usb_ep* _ep, struct usb_request *_rq, gfp_t gfp_flags) {
++ struct ast_usb_request *req = to_ast_req(_rq);
++ struct ast_ep *ep = to_ast_ep(_ep);
++ unsigned long flags;
++
++ if (ep == &ep0_ep) {
++ return ep0_enqueue(_ep, _rq, gfp_flags);
++ }
++
++ _rq->status = -EINPROGRESS;
++ spin_lock_irqsave(&ep->lock, flags);
++ list_add_tail(&req->queue, &ep->queue);
++ req->req.actual = 0;
++ spin_unlock_irqrestore(&ep->lock, flags);
++ ast_ep_queue_run(ep);
++
++ return 0;
++}
++
++static int ast_ep_set_halt(struct usb_ep* _ep, int value) {
++ struct ast_ep *ep = to_ast_ep(_ep);
++ unsigned long flags;
++ if (ep == &ep0_ep) {
++ /* cannot halt ep0, just return */
++ return 0;
++ }
++ spin_lock_irqsave(&ep->lock, flags);
++ if(value) {
++ ep_hwritel(ep, CONFIG, ep_hreadl(ep, CONFIG) | AST_EP_STALL_ENABLED);
++ } else {
++ ep_hwritel(ep, CONFIG, ep_hreadl(ep, CONFIG) &~ AST_EP_STALL_ENABLED);
++ }
++ spin_unlock_irqrestore(&ep->lock, flags);
++ return 0;
++}
++
++static const struct usb_ep_ops ast_ep_ops = {
++ .enable = ast_ep_enable,
++ .disable = ast_ep_disable,
++ .queue = ast_ep_queue,
++ .dequeue = ast_ep_dequeue,
++ .set_halt = ast_ep_set_halt,
++ .alloc_request = ast_alloc_request,
++ .free_request = ast_free_request,
++};
++
++static irqreturn_t ast_vhub_udc_irq(int irq, void* devid) {
++ irqreturn_t status = IRQ_NONE;
++ u32 istatus;
++ (void) devid;
++
++ istatus = ast_hreadl(&udc, ISR);
++
++ /*
++ * Must handle IN/OUT ACK first.
++ * For example, in the case of SETUP request DATA IN, after we send out data,
++ * we enqueue a request for STATUS ack from host, and stage will be
++ * STATUS(IN). When host receives the data, it sends out the STATUS msg
++ * and then a new SETUP. In this case, if we process the SETUP first,
++ * that will confuse the stage state machine, as it expects STATUS msg
++ * for now.
++ */
++ if(istatus & AST_IRQ_EP0_OUT_ACK) {
++ clear_isr(AST_IRQ_EP0_OUT_ACK);
++ ep0_handle_ack();
++ status = IRQ_HANDLED;
++ }
++
++ if(istatus & AST_IRQ_EP0_IN_ACK) {
++ clear_isr(AST_IRQ_EP0_IN_ACK);
++ ep0_handle_ack();
++ status = IRQ_HANDLED;
++ }
++
++ if(istatus & AST_IRQ_EP0_SETUP) {
++ clear_isr(AST_IRQ_EP0_SETUP);
++ ep0_handle_setup();
++ status = IRQ_HANDLED;
++ }
++
++ if(istatus & AST_IRQ_EP_POOL_ACK) {
++ u32 acked = ast_hreadl(&udc, EP_ACK_ISR);
++ ast_hwritel(&udc, EP_ACK_ISR, acked);
++ clear_isr(AST_IRQ_EP_POOL_ACK);
++ status = IRQ_HANDLED;
++ tasklet_schedule(&check_ep_queues);
++ }
++
++ if(istatus & AST_IRQ_EP_POOL_NAK) {
++ clear_isr(AST_IRQ_EP_POOL_NAK);
++ printk("Got NAK on the EP pool");
++ status = IRQ_HANDLED;
++ }
++
++ if (status != IRQ_HANDLED) {
++ printk("vhub: unhandled interrupts! ISR: %08x\n", istatus);
++ } else {
++ ep0_handle_status();
++ }
++
++ return status;
++}
++
++int usb_gadget_register_driver(struct usb_gadget_driver *driver) {
++ int err = 0;
++ unsigned long flags;
++ printk("gadget register driver: %s\n", driver->driver.name);
++ if(!udc.pdev)
++ return -ENODEV;
++
++ spin_lock_irqsave(&udc.lock, flags);
++ udc.pullup_on = 1;
++ if (udc.driver) {
++ err = -EBUSY;
++ goto err;
++ }
++ udc.driver = driver;
++ udc.gadget.dev.driver = &driver->driver;
++err:
++ spin_unlock_irqrestore(&udc.lock, flags);
++ if(err == 0) {
++ //ok so far
++ err = driver->bind(&udc.gadget);
++ }
++ if(err == 0) {
++ if(udc.pullup_on) {
++ enable_upstream_port();
++ }
++ printk("vhub: driver registered, port on!\n");
++ } else {
++ printk("vhub: driver failed to register: %d\n", err);
++ spin_lock_irqsave(&udc.lock, flags);
++ udc.driver = NULL;
++ udc.gadget.dev.driver = NULL;
++ spin_unlock_irqrestore(&udc.lock, flags);
++ }
++ return err;
++}
++EXPORT_SYMBOL(usb_gadget_register_driver);
++
++int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) {
++ int err = 0;
++ unsigned long flags;
++ if(!udc.pdev)
++ return -ENODEV;
++ if(driver != udc.driver || !driver->unbind) {
++ return -EINVAL;
++ }
++
++ spin_lock_irqsave(&udc.lock, flags);
++
++ // disappear from the host
++ ast_udc_pullup(&udc.gadget, 0);
++ if(udc.driver->disconnect) {
++ udc.driver->disconnect(&udc.gadget);
++ }
++
++ driver->unbind(&udc.gadget);
++ // turn off the EPs
++ disable_all_endpoints();
++
++ udc.gadget.dev.driver = NULL;
++ udc.driver = NULL;
++
++ spin_unlock_irqrestore(&udc.lock, flags);
++ return err;
++}
++EXPORT_SYMBOL(usb_gadget_unregister_driver);
++
++static int __init ast_vhub_udc_probe(struct platform_device *pdev) {
++ struct resource *res;
++ int err = -ENODEV;
++ int irq;
++ int i;
++
++ udc.regs = NULL;
++ irq = platform_get_irq(pdev, 0);
++ if(irq < 0)
++ return irq;
++ udc.irq = irq;
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++
++ spin_lock_init(&udc.lock);
++ err = -ENOMEM;
++ udc.regs = ioremap(res->start, res->end - res->start + 1);
++ if(!udc.regs) {
++ dev_err(&pdev->dev, "Couldn't map I/O memory!\n");
++ goto error;
++ }
++
++ dev_info(&pdev->dev, "aspeed_udc at 0x%08lx mapped at %p\n",
++ (unsigned long)res->start, udc.regs);
++ platform_set_drvdata(pdev, &udc);
++ device_initialize(&udc.gadget.dev);
++
++ udc.gadget.dev.parent = &pdev->dev;
++ udc.gadget.dev.dma_mask = pdev->dev.dma_mask;
++
++ /* disable all interrupts first */
++ ast_hwritel(&udc, INTERRUPT_ENABLE, 0);
++
++ ast_hwritel(&udc, ISR, 0x1ffff);
++ err = request_irq(irq, ast_vhub_udc_irq, 0, "aspeed_udc", &udc);
++
++ if(err) {
++ dev_err(&pdev->dev, "failed to get irq %d: %d\n", irq, err);
++ goto error;
++ }
++
++ udc.ep0_dma_virt = ast_alloc_dma_memory(
++ AST_UDC_EP0_MAXPACKET, DMA_BIDIRECTIONAL, &udc.ep0_dma_phys);
++ if (!udc.ep0_dma_virt) {
++ printk("vhub fatal: Couldn't get DMA memory!\n");
++ goto error;
++ }
++ ast_hwritel(&udc, EP0_DMA_ADDR, udc.ep0_dma_phys);
++
++ printk("virthub init...\n");
++ ast_hwritel(&udc, SOFTRESET_ENABLE, 0x33f);
++ ast_hwritel(&udc, SOFTRESET_ENABLE, 0x0);
++ ast_hwritel(&udc, ISR, 0x1ffff);
++ ast_hwritel(&udc, EP_ACK_ISR, 0xffffffff);
++ ast_hwritel(&udc, EP_NAK_ISR, 0xffffffff);
++
++ ast_hwritel(&udc, EP1_STATUS, 0x1);
++ ast_hwritel(&udc, STATUS, AST_HUB_RESET_DISABLE);
++
++ udc.pdev = pdev;
++
++ INIT_LIST_HEAD(&ep0_ep.ep.ep_list);
++ udc.gadget.ep0 = &ep0_ep.ep;
++
++ eps = kzalloc(sizeof(struct ast_ep) * 14, GFP_KERNEL);
++ if(!eps) {
++ goto error;
++ }
++
++ for (i = 0; i < NUM_ENDPOINTS; i++) {
++ struct ast_ep* ep = &eps[i];
++ ep->ep_regs = udc.regs + 0x200 + (i * 0x10);
++ INIT_LIST_HEAD(&ep->queue);
++ ep->ep.ops = &ast_ep_ops;
++ ep->index = i;
++ // i+2, Can't use EP1 as the 'virtual hub' has it built in
++ // when using the root device.
++ ep->addr = i+2;
++ snprintf(ep->epname, 7, "ep%d", ep->addr);
++ ep->ep.name = ep->epname;
++ ep->ep.maxpacket = 1024;
++ spin_lock_init(&ep->lock);
++ list_add_tail(&ep->ep.ep_list, &udc.gadget.ep_list);
++ }
++
++ /* enable interrupts */
++ ast_hwritel(&udc, INTERRUPT_ENABLE,
++ AST_INT_EP_POOL_ACK
++ | AST_INT_EP0_IN_ACK
++ | AST_INT_EP0_OUT_ACK
++ | AST_INT_EP0_SETUP_ACK);
++
++ err = device_add(&udc.gadget.dev);
++ if(err) {
++ dev_dbg(&pdev->dev, "Could not add gadget: %d\n", err);
++ goto error;
++ }
++ return 0;
++error:
++ if(udc.regs)
++ iounmap(udc.regs);
++ platform_set_drvdata(pdev, NULL);
++ return err;
++}
++
++static int ast_vhub_udc_remove(struct platform_device *pdev) {
++ if(udc.regs)
++ iounmap(udc.regs);
++ if(udc.irq)
++ free_irq(udc.irq, &udc);
++ platform_set_drvdata(pdev, NULL);
++ return 0;
++}
++
++static struct platform_driver ast_vhub_udc_driver = {
++ .probe = ast_vhub_udc_probe,
++ .remove = ast_vhub_udc_remove,
++ .driver = {
++ .name = "aspeed_udc",
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init ast_udc_init(void) {
++ return platform_driver_probe(&ast_vhub_udc_driver, ast_vhub_udc_probe);
++}
++module_init(ast_udc_init);
++
++static void __exit ast_udc_exit(void) {
++ ast_free_dma_memory(AST_UDC_EP0_MAXPACKET, DMA_BIDIRECTIONAL,
++ udc.ep0_dma_virt, udc.ep0_dma_phys);
++ platform_driver_unregister(&ast_vhub_udc_driver);
++}
++module_exit(ast_udc_exit);
++
++MODULE_DESCRIPTION("AST2400/1250 USB UDC Driver");
++MODULE_AUTHOR("");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:aspeed_udc");
+diff --git a/drivers/usb/gadget/aspeed_udc.h b/drivers/usb/gadget/aspeed_udc.h
+new file mode 100644
+index 0000000..5494afd
+--- /dev/null
++++ b/drivers/usb/gadget/aspeed_udc.h
+@@ -0,0 +1,161 @@
++/*
++ * Copyright 2014-present Facebook. All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifndef __LINUX_USB_GADGET_ASPEED_UDC_H
++#define __LINUX_USB_GADGET_ASPEED_UDC_H
++
++#define AST_INT_EP_POOL_NAK (1 << 17)
++#define AST_INT_EP_POOL_ACK (1 << 16)
++#define AST_INT_DEV5_CONTROLLER (1 << 13)
++#define AST_INT_DEV4_CONTROLLER (1 << 12)
++#define AST_INT_DEV3_CONTROLLER (1 << 11)
++#define AST_INT_DEV2_CONTROLLER (1 << 10)
++#define AST_INT_DEV1_CONTROLLER (1 << 9)
++
++/* Interrupt control bits */
++#define AST_INT_EP1_IN_ACK (1 << 5)
++#define AST_INT_EP0_IN_NAK (1 << 4)
++#define AST_INT_EP0_IN_ACK (1 << 3)
++#define AST_INT_EP0_OUT_NAK (1 << 2)
++#define AST_INT_EP0_OUT_ACK (1 << 1)
++#define AST_INT_EP0_SETUP_ACK (1 << 0)
++
++/* Interrupt status bits */
++#define AST_IRQ_EP_POOL_NAK (1 << 17)
++#define AST_IRQ_EP_POOL_ACK (1 << 16)
++#define AST_IRQ_EP0_SETUP (1 << 0)
++#define AST_IRQ_EP0_OUT_ACK (1 << 1)
++#define AST_IRQ_EP0_OUT_NAK (1 << 2)
++#define AST_IRQ_EP0_IN_ACK (1 << 3)
++#define AST_IRQ_EP0_IN_NAK (1 << 4)
++#define AST_IRQ_EP1_IN_ACK (1 << 5)
++
++#define AST_HUB_RESET_DISABLE (1 << 11)
++
++#define AST_HUB_BASE_ADDR 0x1e6a0000
++#define AST_HUB_STATUS 0x00
++#define AST_HUB_ISR 0x0c
++#define AST_HUB_EP_ACK_ISR 0x18
++#define AST_HUB_EP_NAK_ISR 0x1C
++#define AST_HUB_SOFTRESET_ENABLE 0x20
++#define AST_HUB_INTERRUPT_ENABLE 0x08
++#define AST_HUB_EP0_STATUS 0x30
++#define AST_HUB_EP1_STATUS 0x38
++#define AST_HUB_EP0_DMA_ADDR 0x34
++#define AST_HUB_ROOT_CONFIG 0x04
++#define AST_HUB_EP_ACK_INT_ENABLE 0x10
++#define AST_HUB_EP_NAK_INT_ENABLE 0x14
++
++#define AST_HUB_ROOT_SETUP_BUFFER 0x80
++
++#define AST_EP0_OUT_READY (1 << 2)
++#define AST_EP0_IN_READY (1 << 1)
++#define AST_EP0_STALL (1 << 0)
++
++#define AST_EP_REG_SIZE 0x10
++#define AST_EP_BASE(i) (0x200 + (i) * 0x10)
++
++#define AST_EP_CONFIG 0x00
++#define AST_EP_DMA_CONTROL 0x04
++#define AST_EP_DESC_BASE 0x08
++#define AST_EP_DESC_STATUS 0x0C
++
++#define AST_EP_DL_RESET (1 << 2)
++#define AST_EP_SINGLE_STAGE (1 << 1)
++#define AST_EP_STALL_ENABLED (1 << 12)
++
++#define AST_EP_TYPE_DISABLED 0
++#define AST_EP_TYPE_BULK_IN 2
++#define AST_EP_TYPE_BULK_OUT 3
++#define AST_EP_TYPE_INT_IN 4
++#define AST_EP_TYPE_INT_OUT 5
++#define AST_EP_TYPE_ISO_IN 6
++#define AST_EP_TYPE_ISO_OUT 7
++
++#define AST_EP_ENABLED 1
++
++#define ep_set_type(type, config) \
++ (config | (AST_EP_TYPE_##type << 4))
++
++#define ast_hreadl(udcp, reg) \
++ ioread32((udcp)->regs + AST_HUB_##reg)
++
++#define ast_hwritel(udcp, reg, value) \
++ iowrite32(value, (udcp)->regs + AST_HUB_##reg)
++
++#define ep_hreadl(ep, reg) \
++ ioread32((ep)->ep_regs + AST_EP_##reg)
++
++#define ep_hwritel(ep, reg, value) \
++ iowrite32(value, (ep)->ep_regs + AST_EP_##reg)
++
++
++struct aspeed_udc {
++ spinlock_t lock;
++
++ void __iomem *regs;
++ struct usb_gadget gadget;
++ struct usb_gadget_driver *driver;
++ struct platform_device *pdev;
++
++ struct dma_pool *pool;
++
++ void* ep0_dma_virt;
++ dma_addr_t ep0_dma_phys;
++
++ u16 hub_address;
++ int irq;
++ unsigned int pullup_on;
++
++ enum {
++ EP0_STAGE_SETUP,
++ EP0_STAGE_DATA,
++ EP0_STAGE_STATUS,
++ } ep0_stage;
++ /* either USB_DIR_OUT or USB_DIR_IN, valid if it is in data or status stage */
++ u8 ep0_dir;
++};
++
++struct ast_usb_request {
++ struct usb_request req;
++ struct list_head queue;
++ size_t lastpacket;
++
++ unsigned int in_transit:1;
++};
++
++struct ast_ep {
++ struct usb_ep ep;
++ u8 addr;
++ u8 index;
++ char epname[7];
++ void __iomem *ep_regs;
++
++ spinlock_t lock;
++ struct list_head queue;
++ void *txbuf;
++ dma_addr_t txbuf_phys;
++
++ unsigned int dma_busy:1;
++ unsigned int to_host:1;
++ unsigned int active:1;
++ // const struct usb_endpoint_descriptor *desc;
++};
++
++
++#endif /* __LINUX_USB_GADGET_ASPEED_UDC_H */
+diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
+index 9462e30..b631931 100644
+--- a/drivers/usb/gadget/epautoconf.c
++++ b/drivers/usb/gadget/epautoconf.c
+@@ -182,6 +182,9 @@ ep_matches (
+ /* min() doesn't work on bitfields with gcc-3.5 */
+ if (size > 64)
+ size = 64;
++ if (gadget->is_dualspeed) {
++ size = 512;
++ }
+ desc->wMaxPacketSize = cpu_to_le16(size);
+ }
+ return 1;
+diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
+index 4e3107d..1f05142 100644
+--- a/drivers/usb/gadget/gadget_chips.h
++++ b/drivers/usb/gadget/gadget_chips.h
+@@ -158,6 +158,13 @@
+ #define gadget_is_fsl_qe(g) 0
+ #endif
+
++/* ASPEED BMC Support */
++#ifdef CONFIG_USB_GADGET_ASPEED_AST
++#define gadget_is_aspeed(g) !strcmp("aspeed_udc", (g)->name)
++#else
++#define gadget_is_aspeed(g) 0
++#endif
++
+
+ // CONFIG_USB_GADGET_SX2
+ // CONFIG_USB_GADGET_AU1X00
+@@ -225,6 +232,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
+ return 0x21;
+ else if (gadget_is_fsl_qe(gadget))
+ return 0x22;
++ else if (gadget_is_aspeed(gadget))
++ return 0x23;
+ return -ENOENT;
+ }
+
+diff --git a/drivers/watchdog/ast_wdt.c b/drivers/watchdog/ast_wdt.c
+index 845f1db..9e7e84f 100644
+--- a/drivers/watchdog/ast_wdt.c
++++ b/drivers/watchdog/ast_wdt.c
+@@ -78,6 +78,17 @@ typedef unsigned char bool_T;
+ #define WDT_Clr (WDT_BASE_VA+0x14)
+ #define WDT_RstWd (WDT_BASE_VA+0x18)
+
++#define WDT_CTRL_B_SECOND_BOOT (0x1 << 7)
++#define WDT_CTRL_B_RESET_SOC (0x00 << 5) /* yes, 0x00 */
++#define WDT_CTRL_B_RESET_FULL (0x01 << 5)
++#define WDT_CTRL_B_RESET_ARM (0x2 << 5)
++#define WDT_CTRL_B_RESET_MASK (0x3 << 5)
++#define WDT_CTRL_B_1MCLK (0x1 << 4)
++#define WDT_CTRL_B_EXT (0x1 << 3)
++#define WDT_CTRL_B_INTR (0x1 << 2)
++#define WDT_CTRL_B_CLEAR_AFTER (0x1 << 1)
++#define WDT_CTRL_B_ENABLE (0x1 << 0)
++
+
+ #define AST_READ_REG(r) (*((volatile unsigned int *) (r)))
+ #define AST_WRITE_REG(r,v) (*((volatile unsigned int *) (r)) = ((unsigned int) (v)))
+@@ -87,17 +98,24 @@ typedef unsigned char bool_T;
+ #define WDT_CLK_SRC_PCLK 1
+
+ //Global Variables
+-#define WD_TIMO 6 /* Default heartbeat = 6 seconds */
++#define WDT_TIMO 30 /* Default heartbeat = 30 seconds */
++
++#define WDT_INITIAL_TIMO (8*60) /* Initial timeout, 8m */
++#define WDT_TIMO2TICKS(t) (TICKS_PER_uSEC * 1000000 * (t))
+
+-static int heartbeat = WD_TIMO;
++static int heartbeat = WDT_TIMO;
+ module_param(heartbeat, int, 0);
+-MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WD_TIMO) ")");
++MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WDT_TIMO) ")");
+
+ static int nowayout = WATCHDOG_NOWAYOUT;
+ module_param(nowayout, int, 0);
+ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+
+-static unsigned long wdt_is_open;
++static int force_disable = 0; // setting this to 1 will disable the wdt timer
++module_param(force_disable, int, 0);
++MODULE_PARM_DESC(force_disable, "Disable watchdog by default "
++ "(default=0, enable watchdog)");
++
+ static char expect_close;
+
+ //Function Declaration
+@@ -117,7 +135,7 @@ void wdt_disable(void)
+
+ /* reset WDT_Ctrl[0] as 0 */
+ regVal = AST_READ_REG(WDT_Ctrl);
+- regVal &= 0xFFFFFFFE;
++ regVal &= ~(WDT_CTRL_B_ENABLE);
+ AST_WRITE_REG(WDT_Ctrl, regVal);
+ }
+
+@@ -129,17 +147,18 @@ void wdt_sel_clk_src(unsigned char sourceClk)
+ if (sourceClk == WDT_CLK_SRC_PCLK)
+ {
+ /* reset WDT_Ctrl[4] as 0 */
+- regVal &= 0xFFFFFFEF;
++ regVal &= ~(WDT_CTRL_B_1MCLK);
+ }
+ else
+ {
+ /* set WDT_Ctrl[4] as 1 */
+- regVal |= 0x00000010;
++ regVal |= WDT_CTRL_B_1MCLK;
+ }
+ AST_WRITE_REG(WDT_Ctrl, regVal);
+ }
+
+-void wdt_set_timeout_action(bool_T bResetOut, bool_T bIntrSys, bool_T bResetSys)
++void wdt_set_timeout_action(bool_T bResetOut, bool_T bIntrSys,
++ bool_T bClrAfter, bool_T bResetARMOnly)
+ {
+ register unsigned int regVal;
+
+@@ -148,70 +167,102 @@ void wdt_set_timeout_action(bool_T bResetOut, bool_T bIntrSys, bool_T bResetSys)
+ if (bResetOut)
+ {
+ /* set WDT_Ctrl[3] = 1 */
+- regVal |= 0x00000008;
++ regVal |= WDT_CTRL_B_EXT;
+ }
+ else
+ {
+ /* reset WDT_Ctrl[3] = 0 */
+- regVal &= 0xFFFFFFF7;
++ regVal &= ~WDT_CTRL_B_EXT;
+ }
+
+ if (bIntrSys)
+ {
+ /* set WDT_Ctrl[2] = 1 */
+- regVal |= 0x00000004;
++ regVal |= WDT_CTRL_B_INTR;
+ }
+ else
+ {
+ /* reset WDT_Ctrl[2] = 0 */
+- regVal &= 0xFFFFFFFB;
++ regVal &= ~WDT_CTRL_B_INTR;
+ }
+
+- if (bResetSys)
++ if (bClrAfter)
+ {
+ /* set WDT_Ctrl[1] = 1 */
+- regVal |= 0x00000002;
++ regVal |= WDT_CTRL_B_CLEAR_AFTER;
+ }
+ else
+ {
+ /* reset WDT_Ctrl[1] = 0 */
+- regVal &= 0xFFFFFFFD;
++ regVal &= ~WDT_CTRL_B_CLEAR_AFTER;
++ }
++
++ if (bResetARMOnly)
++ {
++ /* set WDT_Ctrl[6..5] = 10 ie, reset ARM only */
++ regVal &= ~WDT_CTRL_B_RESET_MASK;
++ regVal |= WDT_CTRL_B_RESET_ARM;
++ }
++ else
++ {
++ /* reset WDT_CTrl[6..5] = 01, full chip */
++ regVal &= ~WDT_CTRL_B_RESET_MASK;
++ regVal |= WDT_CTRL_B_RESET_FULL;
+ }
++
+
+ AST_WRITE_REG(WDT_Ctrl, regVal);
+ }
+
+ void wdt_enable(void)
+ {
+- register unsigned int regVal;
++ if (!force_disable) {
++ register unsigned int regVal;
++
++ /* set WDT_Ctrl[0] as 1 */
++ regVal = AST_READ_REG(WDT_Ctrl);
++ regVal |= WDT_CTRL_B_ENABLE;
++ AST_WRITE_REG(WDT_Ctrl, regVal);
++ }
++}
+
+- /* set WDT_Ctrl[0] as 1 */
+- regVal = AST_READ_REG(WDT_Ctrl);
+- regVal |= 1;
+- AST_WRITE_REG(WDT_Ctrl, regVal);
++bool_T wdt_is_enabled(void)
++{
++ unsigned int reg;
++ reg = AST_READ_REG(WDT_Ctrl);
++ return reg & WDT_CTRL_B_ENABLE;
+ }
+
+-void wdt_restart_new(unsigned int nPeriod, int sourceClk, bool_T bResetOut, bool_T bIntrSys, bool_T bResetSys, bool_T bUpdated)
++
++void wdt_restart_new(unsigned int nPeriod, int sourceClk, bool_T bResetOut,
++ bool_T bIntrSys, bool_T bClrAfter, bool_T bResetARMOnly)
+ {
+- wdt_disable();
++ bool_T enabled = wdt_is_enabled();
++
++ if (enabled) {
++ wdt_disable();
++ }
+
+ AST_WRITE_REG(WDT_Reload, nPeriod);
+
+ wdt_sel_clk_src(sourceClk);
+
+- wdt_set_timeout_action(bResetOut, bIntrSys, bResetSys);
++ wdt_set_timeout_action(bResetOut, bIntrSys, bClrAfter, bResetARMOnly);
+
+ AST_WRITE_REG(WDT_Restart, 0x4755); /* reload! */
+
+- if (!bUpdated)
++ if (enabled) {
+ wdt_enable();
++ }
+ }
+
+ void wdt_restart(void)
+ {
+- wdt_disable();
+- AST_WRITE_REG(WDT_Restart, 0x4755); /* reload! */
+- wdt_enable();
++ if (!force_disable) {
++ wdt_disable();
++ AST_WRITE_REG(WDT_Restart, 0x4755); /* reload! */
++ wdt_enable();
++ }
+ }
+
+
+@@ -230,7 +281,9 @@ static int wdt_set_heartbeat(int t)
+
+ heartbeat=t;
+
+- wdt_restart_new(TICKS_PER_uSEC*1000000*t, WDT_CLK_SRC_EXT, FALSE, TRUE, FALSE, FALSE);
++ wdt_restart_new(WDT_TIMO2TICKS(t), WDT_CLK_SRC_EXT,
++ /* No Ext, No intr, Self clear, Full chip reset */
++ FALSE, FALSE, TRUE, FALSE);
+ return 0;
+ }
+
+@@ -245,8 +298,11 @@ static int wdt_set_heartbeat(int t)
+ * @count: count of bytes
+ * @ppos: pointer to the position to write. No seeks allowed
+ *
+- * A write to a watchdog device is defined as a keepalive signal. Any
+- * write of data will do, as we we don't define content meaning.
++ * A write to a watchdog device is defined as a keepalive signal.
++ * Any data will do, except for the reserved letters 'V' (to enable
++ * magic close), the letter 'X' (to override the current watchdog
++ * settings and disable it), or the letter 'x' (to turn off override
++ * and restore its old settings).
+ */
+
+ static ssize_t ast_wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
+@@ -265,8 +321,20 @@ static int wdt_set_heartbeat(int t)
+ char c;
+ if (get_user(c, buf + i))
+ return -EFAULT;
+- if (c == 'V')
+- expect_close = 42;
++ switch(c) {
++ case 'V':
++ expect_close = 42;
++ break;
++ case 'X':
++ force_disable = 1;
++ wdt_disable();
++ break;
++ case 'x':
++ force_disable = 0;
++ break;
++ default:
++ break;
++ }
+ }
+ }
+ wdt_restart();
+@@ -338,8 +406,6 @@ static int ast_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cm
+
+ static int ast_wdt_open(struct inode *inode, struct file *file)
+ {
+- if(test_and_set_bit(0, &wdt_is_open))
+- return -EBUSY;
+ /*
+ * Activate
+ */
+@@ -362,14 +428,23 @@ static int ast_wdt_open(struct inode *inode, struct file *file)
+
+ static int ast_wdt_release(struct inode *inode, struct file *file)
+ {
+- if (expect_close == 42 || !nowayout)
++ if (expect_close != 42 || !nowayout)
+ {
++ /* handles the case where the device is closed without the "magic
++ * close" character (anything that is not 'V' qualifies -- see the
++ * original Linux watchdog spec for more about this). closing the
++ * device in this case must disable the timer too, so automatic
++ * restarts are inhibited.
++ */
++
+ wdt_disable();
+- clear_bit(0, &wdt_is_open);
+ }
+ else
+ {
+- printk(KERN_CRIT "wdt: WDT device closed unexpectedly. WDT will not stop!\n");
++ /* handles the case where the kernel is compiled with nowayout, or
++ * if the user specifies that the watchdog should continue ticking
++ * after device closure (by writing a 'V' before closing the device)
++ */
+ wdt_restart();
+ }
+ expect_close = 0;
+@@ -398,14 +473,23 @@ static int ast_wdt_notify_sys(struct notifier_block *this, unsigned long code, v
+ return NOTIFY_DONE;
+ }
+
+-extern void ast_soc_wdt_reset(void)
++extern void ast_soc_reset_soc(void)
+ {
+- writel(0x10 , WDT_BASE_VA+0x04);
+- writel(0x4755, WDT_BASE_VA+0x08);
+- writel(0x3, WDT_BASE_VA+0x0c);
++ writel(0x10 , WDT_Reload);
++ writel(0x4755, WDT_Restart);
++ writel(WDT_CTRL_B_RESET_SOC|WDT_CTRL_B_CLEAR_AFTER|WDT_CTRL_B_ENABLE,
++ WDT_Ctrl);
+ }
++EXPORT_SYMBOL(ast_soc_reset_soc);
+
+-EXPORT_SYMBOL(ast_soc_wdt_reset);
++extern void ast_wdt_reset_full(void)
++{
++ writel(0x10 , WDT_Reload);
++ writel(0x4755, WDT_Restart);
++ writel(WDT_CTRL_B_RESET_FULL|WDT_CTRL_B_CLEAR_AFTER|WDT_CTRL_B_ENABLE,
++ WDT_Ctrl);
++}
++EXPORT_SYMBOL(ast_wdt_reset_full);
+
+ static struct file_operations ast_wdt_fops =
+ {
+@@ -433,10 +517,6 @@ static int ast_wdt_probe(struct platform_device *pdev)
+ {
+ int ret;
+
+- wdt_disable();
+- wdt_sel_clk_src(WDT_CLK_SRC_EXT);
+- wdt_set_timeout_action(FALSE, FALSE, FALSE);
+-
+ /* register ISR */
+ if (request_irq(IRQ_WDT, (void *)wdt_isr, IRQF_DISABLED, "WDT", NULL))
+ {
+@@ -463,9 +543,22 @@ static int ast_wdt_probe(struct platform_device *pdev)
+ }
+
+ /* interrupt the system while WDT timeout */
+- wdt_restart_new(TICKS_PER_uSEC*1000000*heartbeat, WDT_CLK_SRC_EXT, FALSE, TRUE, FALSE, TRUE);
++ wdt_restart_new(WDT_TIMO2TICKS(WDT_INITIAL_TIMO), WDT_CLK_SRC_EXT,
++ /* No Ext, No intr, Self clear, Full chip reset */
++ FALSE, FALSE, TRUE, FALSE);
+
+- printk(KERN_INFO "AST WDT is installed.(irq = %d, heartbeat = %d secs, nowayout = %d)\n",IRQ_WDT,heartbeat,nowayout);
++ /* enable it by default */
++ if (!force_disable) {
++ wdt_enable();
++ }
++
++ /* change the reload value back to regular */
++ AST_WRITE_REG(WDT_Reload, WDT_TIMO2TICKS(heartbeat));
++
++ printk(KERN_INFO "UMVP2500 WDT is installed. (irq:%d, initial timeout:%ds, "
++ "timeout:%ds nowayout:%d enabled:%s)\n",
++ IRQ_WDT, WDT_INITIAL_TIMO, heartbeat, nowayout,
++ wdt_is_enabled() ? "yes" : "no");
+
+ return (0);
+ }
+diff --git a/include/linux/i2c.h b/include/linux/i2c.h
+index 33a5992..59167e2 100644
+--- a/include/linux/i2c.h
++++ b/include/linux/i2c.h
+@@ -576,6 +576,17 @@ union i2c_smbus_data {
+ /* and one more for user-space compatibility */
+ };
+
++/*
++ * Large SMBus block data io, which is not defined in the SMBus standard,
++ * but used by some NIC (i.e. Intel I354) sideband SMBus interface.
++ */
++#define I2C_SMBUS_BLOCK_LARGE_MAX 240 /* extra large block size */
++union i2c_smbus_large_data {
++ union i2c_smbus_data data;
++ __u8 block[I2C_SMBUS_BLOCK_LARGE_MAX + 2]; /* block[0] is used for length */
++ /* and one more for PEC */
++};
++
+ /* i2c_smbus_xfer read or write markers */
+ #define I2C_SMBUS_READ 1
+ #define I2C_SMBUS_WRITE 0
+@@ -591,6 +602,7 @@ union i2c_smbus_data {
+ #define I2C_SMBUS_I2C_BLOCK_BROKEN 6
+ #define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */
+ #define I2C_SMBUS_I2C_BLOCK_DATA 8
++#define I2C_SMBUS_BLOCK_LARGE_DATA 9
+
+
+ #ifdef __KERNEL__
+diff --git a/include/linux/i2c/pmbus.h b/include/linux/i2c/pmbus.h
+new file mode 100644
+index 0000000..69280db
+--- /dev/null
++++ b/include/linux/i2c/pmbus.h
+@@ -0,0 +1,45 @@
++/*
++ * Hardware monitoring driver for PMBus devices
++ *
++ * Copyright (c) 2010, 2011 Ericsson AB.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifndef _PMBUS_H_
++#define _PMBUS_H_
++
++/* flags */
++
++/*
++ * PMBUS_SKIP_STATUS_CHECK
++ *
++ * During register detection, skip checking the status register for
++ * communication or command errors.
++ *
++ * Some PMBus chips respond with valid data when trying to read an unsupported
++ * register. For such chips, checking the status register is mandatory when
++ * trying to determine if a chip register exists or not.
++ * Other PMBus chips don't support the STATUS_CML register, or report
++ * communication errors for no explicable reason. For such chips, checking
++ * the status register must be disabled.
++ */
++#define PMBUS_SKIP_STATUS_CHECK (1 << 0)
++
++struct pmbus_platform_data {
++ u32 flags; /* Device specific flags */
++};
++
++#endif /* _PMBUS_H_ */
+diff --git a/tools/.gitignore b/tools/.gitignore
+new file mode 100644
+index 0000000..e4e5f6c
+--- /dev/null
++++ b/tools/.gitignore
+@@ -0,0 +1 @@
++*~
+\ No newline at end of file
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0001-MTD-fix-m25p80-64-bit-divisions.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0001-MTD-fix-m25p80-64-bit-divisions.patch
new file mode 100644
index 0000000..c7f3d4e
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0001-MTD-fix-m25p80-64-bit-divisions.patch
@@ -0,0 +1,129 @@
+From d85316ac459f1cdd14ea1828eebeac1f1028e167 Mon Sep 17 00:00:00 2001
+From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
+Date: Thu, 18 Dec 2008 14:10:05 +0200
+Subject: [PATCH 001/130] [MTD] fix m25p80 64-bit divisions
+
+MTD has recently been upgraded for 64-bit support, see commit
+number 69423d99fc182a81f3c5db3eb5c140acc6fc64be in the
+mtd-2.6.git tree (git://git.infradead.org/mtd-2.6.git)
+or see this URL:
+http://git.infradead.org/mtd-2.6.git?a=commit;h=69423d99fc182a81f3c5db3eb5c140acc6fc64be
+
+Some variables in MTD data structures which were 32-bit
+became 64-bit. Namely, the 'size' field in 'struct mtd_info'
+and the 'addr'/'len' fields in 'struct erase_info'. This
+means we have to use 'do_div' to divide them.
+
+This patch fixes the following linking error:
+ERROR: "__umoddi3" [drivers/mtd/devices/m25p80.ko] undefined!
+
+This patch changes divisions of 64-bit variable so that they use
+'do_div'. This patch also change some print placeholders to
+get rid of gcc warnings.
+
+Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
+Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
+---
+ drivers/mtd/devices/m25p80.c | 37 +++++++++++++++++++------------------
+ 1 file changed, 19 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
+index 6659b22..9be0229 100644
+--- a/drivers/mtd/devices/m25p80.c
++++ b/drivers/mtd/devices/m25p80.c
+@@ -20,6 +20,7 @@
+ #include <linux/device.h>
+ #include <linux/interrupt.h>
+ #include <linux/mutex.h>
++#include <linux/math64.h>
+
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
+@@ -169,9 +170,9 @@ static int wait_till_ready(struct m25p *flash)
+ */
+ static int erase_chip(struct m25p *flash)
+ {
+- DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %dKiB\n",
++ DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %lldKiB\n",
+ flash->spi->dev.bus_id, __func__,
+- flash->mtd.size / 1024);
++ (long long)(flash->mtd.size >> 10));
+
+ /* Wait until finished previous write command. */
+ if (wait_till_ready(flash))
+@@ -232,18 +233,18 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
+ {
+ struct m25p *flash = mtd_to_m25p(mtd);
+ u32 addr,len;
++ uint32_t rem;
+
+- DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %d\n",
++ DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%llx, len %lld\n",
+ flash->spi->dev.bus_id, __func__, "at",
+- (u32)instr->addr, instr->len);
++ (long long)instr->addr, (long long)instr->len);
+
+ /* sanity checks */
+ if (instr->addr + instr->len > flash->mtd.size)
+ return -EINVAL;
+- if ((instr->addr % mtd->erasesize) != 0
+- || (instr->len % mtd->erasesize) != 0) {
++ div_u64_rem(instr->len, mtd->erasesize, &rem);
++ if (rem)
+ return -EINVAL;
+- }
+
+ addr = instr->addr;
+ len = instr->len;
+@@ -677,24 +678,24 @@ static int __devinit m25p_probe(struct spi_device *spi)
+ flash->mtd.erasesize = info->sector_size;
+ }
+
+- dev_info(&spi->dev, "%s (%d Kbytes)\n", info->name,
+- flash->mtd.size / 1024);
++ dev_info(&spi->dev, "%s (%lld Kbytes)\n", info->name,
++ (long long)flash->mtd.size >> 10);
+
+ DEBUG(MTD_DEBUG_LEVEL2,
+- "mtd .name = %s, .size = 0x%.8x (%uMiB) "
++ "mtd .name = %s, .size = 0x%llx (%lldMiB) "
+ ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
+ flash->mtd.name,
+- flash->mtd.size, flash->mtd.size / (1024*1024),
++ (long long)flash->mtd.size, (long long)(flash->mtd.size >> 20),
+ flash->mtd.erasesize, flash->mtd.erasesize / 1024,
+ flash->mtd.numeraseregions);
+
+ if (flash->mtd.numeraseregions)
+ for (i = 0; i < flash->mtd.numeraseregions; i++)
+ DEBUG(MTD_DEBUG_LEVEL2,
+- "mtd.eraseregions[%d] = { .offset = 0x%.8x, "
++ "mtd.eraseregions[%d] = { .offset = 0x%llx, "
+ ".erasesize = 0x%.8x (%uKiB), "
+ ".numblocks = %d }\n",
+- i, flash->mtd.eraseregions[i].offset,
++ i, (long long)flash->mtd.eraseregions[i].offset,
+ flash->mtd.eraseregions[i].erasesize,
+ flash->mtd.eraseregions[i].erasesize / 1024,
+ flash->mtd.eraseregions[i].numblocks);
+@@ -722,12 +723,12 @@ static int __devinit m25p_probe(struct spi_device *spi)
+ if (nr_parts > 0) {
+ for (i = 0; i < nr_parts; i++) {
+ DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = "
+- "{.name = %s, .offset = 0x%.8x, "
+- ".size = 0x%.8x (%uKiB) }\n",
++ "{.name = %s, .offset = 0x%llx, "
++ ".size = 0x%llx (%lldKiB) }\n",
+ i, parts[i].name,
+- parts[i].offset,
+- parts[i].size,
+- parts[i].size / 1024);
++ (long long)parts[i].offset,
++ (long long)parts[i].size,
++ (long long)(parts[i].size >> 10));
+ }
+ flash->partitioned = 1;
+ return add_mtd_partitions(&flash->mtd, parts, nr_parts);
+--
+1.8.1
+
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0001-bzip2-lzma-library-support-for-gzip-bzip2-and-lzma-d.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0001-bzip2-lzma-library-support-for-gzip-bzip2-and-lzma-d.patch
new file mode 100644
index 0000000..ffe1082
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0001-bzip2-lzma-library-support-for-gzip-bzip2-and-lzma-d.patch
@@ -0,0 +1,1876 @@
+From 8b368d36bf46357a115da164ffe0e12d881b3503 Mon Sep 17 00:00:00 2001
+From: Alain Knaff <alain@knaff.lu>
+Date: Sun, 4 Jan 2009 22:46:16 +0100
+Subject: bzip2/lzma: library support for gzip, bzip2 and lzma decompression
+
+Impact: Replaces inflate.c with a wrapper around zlib_inflate; new library code
+
+This is the first part of the bzip2/lzma patch
+
+The bzip patch is based on an idea by Christian Ludwig, includes support for
+compressing the kernel with bzip2 or lzma rather than gzip. Both
+compressors give smaller sizes than gzip. Lzma's decompresses faster
+than bzip2.
+
+It also supports ramdisks and initramfs' compressed using these two
+compressors.
+
+The functionality has been successfully used for a couple of years by
+the udpcast project
+
+This version applies to "tip" kernel 2.6.28
+
+This part contains:
+- changed inflate.c to accomodate rest of patch
+- implementation of bzip2 compression (not used at this stage yet)
+- implementation of lzma compression (not used at this stage yet)
+- Makefile routines to support bzip2 and lzma kernel compression
+
+Signed-off-by: Alain Knaff <alain@knaff.lu>
+Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+---
+ .../include/linux/decompress/bunzip2.h | 10 +
+ .../include/linux/decompress/generic.h | 30 +
+ .../include/linux/decompress/inflate.h | 13 +
+ .../include/linux/decompress/mm.h | 87 +++
+ .../include/linux/decompress/unlzma.h | 12 +
+ .../linux-aspeed-2.6.28.9/lib/decompress_bunzip2.c | 735 +++++++++++++++++++++
+ .../linux-aspeed-2.6.28.9/lib/decompress_inflate.c | 167 +++++
+ .../linux-aspeed-2.6.28.9/lib/decompress_unlzma.c | 647 ++++++++++++++++++
+ .../lib/zlib_inflate/inflate.h | 4 +
+ .../lib/zlib_inflate/inftrees.h | 4 +
+ .../linux-aspeed-2.6.28.9/scripts/Makefile.lib | 14 +
+ .../files/linux-aspeed-2.6.28.9/scripts/bin_size | 10 +
+ 12 files changed, 1733 insertions(+)
+ create mode 100644 include/linux/decompress/bunzip2.h
+ create mode 100644 include/linux/decompress/generic.h
+ create mode 100644 include/linux/decompress/inflate.h
+ create mode 100644 include/linux/decompress/mm.h
+ create mode 100644 include/linux/decompress/unlzma.h
+ create mode 100644 lib/decompress_bunzip2.c
+ create mode 100644 lib/decompress_inflate.c
+ create mode 100644 lib/decompress_unlzma.c
+ create mode 100644 scripts/bin_size
+
+diff --git a/include/linux/decompress/bunzip2.h
+new file mode 100644
+index 0000000..1152721
+--- /dev/null
++++ b/include/linux/decompress/bunzip2.h
+@@ -0,0 +1,10 @@
++#ifndef DECOMPRESS_BUNZIP2_H
++#define DECOMPRESS_BUNZIP2_H
++
++int bunzip2(unsigned char *inbuf, int len,
++ int(*fill)(void*, unsigned int),
++ int(*flush)(void*, unsigned int),
++ unsigned char *output,
++ int *pos,
++ void(*error)(char *x));
++#endif
+diff --git a/include/linux/decompress/generic.h
+new file mode 100644
+index 0000000..f847f51
+--- /dev/null
++++ b/include/linux/decompress/generic.h
+@@ -0,0 +1,30 @@
++#ifndef DECOMPRESS_GENERIC_H
++#define DECOMPRESS_GENERIC_H
++
++/* Minimal chunksize to be read.
++ *Bzip2 prefers at least 4096
++ *Lzma prefers 0x10000 */
++#define COMPR_IOBUF_SIZE 4096
++
++typedef int (*decompress_fn) (unsigned char *inbuf, int len,
++ int(*fill)(void*, unsigned int),
++ int(*writebb)(void*, unsigned int),
++ unsigned char *output,
++ int *posp,
++ void(*error)(char *x));
++
++/* inbuf - input buffer
++ *len - len of pre-read data in inbuf
++ *fill - function to fill inbuf if empty
++ *writebb - function to write out outbug
++ *posp - if non-null, input position (number of bytes read) will be
++ * returned here
++ *
++ *If len != 0, the inbuf is initialized (with as much data), and fill
++ *should not be called
++ *If len = 0, the inbuf is allocated, but empty. Its size is IOBUF_SIZE
++ *fill should be called (repeatedly...) to read data, at most IOBUF_SIZE
++ */
++
++
++#endif
+diff --git a/include/linux/decompress/inflate.h
+new file mode 100644
+index 0000000..f9b06cc
+--- /dev/null
++++ b/include/linux/decompress/inflate.h
+@@ -0,0 +1,13 @@
++#ifndef INFLATE_H
++#define INFLATE_H
++
++/* Other housekeeping constants */
++#define INBUFSIZ 4096
++
++int gunzip(unsigned char *inbuf, int len,
++ int(*fill)(void*, unsigned int),
++ int(*flush)(void*, unsigned int),
++ unsigned char *output,
++ int *pos,
++ void(*error_fn)(char *x));
++#endif
+diff --git a/include/linux/decompress/mm.h
+new file mode 100644
+index 0000000..12ff8c3
+--- /dev/null
++++ b/include/linux/decompress/mm.h
+@@ -0,0 +1,87 @@
++/*
++ * linux/compr_mm.h
++ *
++ * Memory management for pre-boot and ramdisk uncompressors
++ *
++ * Authors: Alain Knaff <alain@knaff.lu>
++ *
++ */
++
++#ifndef DECOMPR_MM_H
++#define DECOMPR_MM_H
++
++#ifdef STATIC
++
++/* Code active when included from pre-boot environment: */
++
++/* A trivial malloc implementation, adapted from
++ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
++ */
++static unsigned long malloc_ptr;
++static int malloc_count;
++
++static void *malloc(int size)
++{
++ void *p;
++
++ if (size < 0)
++ error("Malloc error");
++ if (!malloc_ptr)
++ malloc_ptr = free_mem_ptr;
++
++ malloc_ptr = (malloc_ptr + 3) & ~3; /* Align */
++
++ p = (void *)malloc_ptr;
++ malloc_ptr += size;
++
++ if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr)
++ error("Out of memory");
++
++ malloc_count++;
++ return p;
++}
++
++static void free(void *where)
++{
++ malloc_count--;
++ if (!malloc_count)
++ malloc_ptr = free_mem_ptr;
++}
++
++#define large_malloc(a) malloc(a)
++#define large_free(a) free(a)
++
++#define set_error_fn(x)
++
++#define INIT
++
++#else /* STATIC */
++
++/* Code active when compiled standalone for use when loading ramdisk: */
++
++#include <linux/kernel.h>
++#include <linux/fs.h>
++#include <linux/string.h>
++#include <linux/vmalloc.h>
++
++/* Use defines rather than static inline in order to avoid spurious
++ * warnings when not needed (indeed large_malloc / large_free are not
++ * needed by inflate */
++
++#define malloc(a) kmalloc(a, GFP_KERNEL)
++#define free(a) kfree(a)
++
++#define large_malloc(a) vmalloc(a)
++#define large_free(a) vfree(a)
++
++static void(*error)(char *m);
++#define set_error_fn(x) error = x;
++
++#define INIT __init
++#define STATIC
++
++#include <linux/init.h>
++
++#endif /* STATIC */
++
++#endif /* DECOMPR_MM_H */
+diff --git a/include/linux/decompress/unlzma.h
+new file mode 100644
+index 0000000..7796538
+--- /dev/null
++++ b/include/linux/decompress/unlzma.h
+@@ -0,0 +1,12 @@
++#ifndef DECOMPRESS_UNLZMA_H
++#define DECOMPRESS_UNLZMA_H
++
++int unlzma(unsigned char *, int,
++ int(*fill)(void*, unsigned int),
++ int(*flush)(void*, unsigned int),
++ unsigned char *output,
++ int *posp,
++ void(*error)(char *x)
++ );
++
++#endif
+diff --git a/lib/decompress_bunzip2.c
+new file mode 100644
+index 0000000..5d3ddb5
+--- /dev/null
++++ b/lib/decompress_bunzip2.c
+@@ -0,0 +1,735 @@
++/* vi: set sw = 4 ts = 4: */
++/* Small bzip2 deflate implementation, by Rob Landley (rob@landley.net).
++
++ Based on bzip2 decompression code by Julian R Seward (jseward@acm.org),
++ which also acknowledges contributions by Mike Burrows, David Wheeler,
++ Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten,
++ Robert Sedgewick, and Jon L. Bentley.
++
++ This code is licensed under the LGPLv2:
++ LGPL (http://www.gnu.org/copyleft/lgpl.html
++*/
++
++/*
++ Size and speed optimizations by Manuel Novoa III (mjn3@codepoet.org).
++
++ More efficient reading of Huffman codes, a streamlined read_bunzip()
++ function, and various other tweaks. In (limited) tests, approximately
++ 20% faster than bzcat on x86 and about 10% faster on arm.
++
++ Note that about 2/3 of the time is spent in read_unzip() reversing
++ the Burrows-Wheeler transformation. Much of that time is delay
++ resulting from cache misses.
++
++ I would ask that anyone benefiting from this work, especially those
++ using it in commercial products, consider making a donation to my local
++ non-profit hospice organization in the name of the woman I loved, who
++ passed away Feb. 12, 2003.
++
++ In memory of Toni W. Hagan
++
++ Hospice of Acadiana, Inc.
++ 2600 Johnston St., Suite 200
++ Lafayette, LA 70503-3240
++
++ Phone (337) 232-1234 or 1-800-738-2226
++ Fax (337) 232-1297
++
++ http://www.hospiceacadiana.com/
++
++ Manuel
++ */
++
++/*
++ Made it fit for running in Linux Kernel by Alain Knaff (alain@knaff.lu)
++*/
++
++
++#ifndef STATIC
++#include <linux/decompress/bunzip2.h>
++#endif /* !STATIC */
++
++#include <linux/decompress/mm.h>
++
++#ifndef INT_MAX
++#define INT_MAX 0x7fffffff
++#endif
++
++/* Constants for Huffman coding */
++#define MAX_GROUPS 6
++#define GROUP_SIZE 50 /* 64 would have been more efficient */
++#define MAX_HUFCODE_BITS 20 /* Longest Huffman code allowed */
++#define MAX_SYMBOLS 258 /* 256 literals + RUNA + RUNB */
++#define SYMBOL_RUNA 0
++#define SYMBOL_RUNB 1
++
++/* Status return values */
++#define RETVAL_OK 0
++#define RETVAL_LAST_BLOCK (-1)
++#define RETVAL_NOT_BZIP_DATA (-2)
++#define RETVAL_UNEXPECTED_INPUT_EOF (-3)
++#define RETVAL_UNEXPECTED_OUTPUT_EOF (-4)
++#define RETVAL_DATA_ERROR (-5)
++#define RETVAL_OUT_OF_MEMORY (-6)
++#define RETVAL_OBSOLETE_INPUT (-7)
++
++/* Other housekeeping constants */
++#define BZIP2_IOBUF_SIZE 4096
++
++/* This is what we know about each Huffman coding group */
++struct group_data {
++ /* We have an extra slot at the end of limit[] for a sentinal value. */
++ int limit[MAX_HUFCODE_BITS+1];
++ int base[MAX_HUFCODE_BITS];
++ int permute[MAX_SYMBOLS];
++ int minLen, maxLen;
++};
++
++/* Structure holding all the housekeeping data, including IO buffers and
++ memory that persists between calls to bunzip */
++struct bunzip_data {
++ /* State for interrupting output loop */
++ int writeCopies, writePos, writeRunCountdown, writeCount, writeCurrent;
++ /* I/O tracking data (file handles, buffers, positions, etc.) */
++ int (*fill)(void*, unsigned int);
++ int inbufCount, inbufPos /*, outbufPos*/;
++ unsigned char *inbuf /*,*outbuf*/;
++ unsigned int inbufBitCount, inbufBits;
++ /* The CRC values stored in the block header and calculated from the
++ data */
++ unsigned int crc32Table[256], headerCRC, totalCRC, writeCRC;
++ /* Intermediate buffer and its size (in bytes) */
++ unsigned int *dbuf, dbufSize;
++ /* These things are a bit too big to go on the stack */
++ unsigned char selectors[32768]; /* nSelectors = 15 bits */
++ struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */
++ int io_error; /* non-zero if we have IO error */
++};
++
++
++/* Return the next nnn bits of input. All reads from the compressed input
++ are done through this function. All reads are big endian */
++static unsigned int INIT get_bits(struct bunzip_data *bd, char bits_wanted)
++{
++ unsigned int bits = 0;
++
++ /* If we need to get more data from the byte buffer, do so.
++ (Loop getting one byte at a time to enforce endianness and avoid
++ unaligned access.) */
++ while (bd->inbufBitCount < bits_wanted) {
++ /* If we need to read more data from file into byte buffer, do
++ so */
++ if (bd->inbufPos == bd->inbufCount) {
++ if (bd->io_error)
++ return 0;
++ bd->inbufCount = bd->fill(bd->inbuf, BZIP2_IOBUF_SIZE);
++ if (bd->inbufCount <= 0) {
++ bd->io_error = RETVAL_UNEXPECTED_INPUT_EOF;
++ return 0;
++ }
++ bd->inbufPos = 0;
++ }
++ /* Avoid 32-bit overflow (dump bit buffer to top of output) */
++ if (bd->inbufBitCount >= 24) {
++ bits = bd->inbufBits&((1 << bd->inbufBitCount)-1);
++ bits_wanted -= bd->inbufBitCount;
++ bits <<= bits_wanted;
++ bd->inbufBitCount = 0;
++ }
++ /* Grab next 8 bits of input from buffer. */
++ bd->inbufBits = (bd->inbufBits << 8)|bd->inbuf[bd->inbufPos++];
++ bd->inbufBitCount += 8;
++ }
++ /* Calculate result */
++ bd->inbufBitCount -= bits_wanted;
++ bits |= (bd->inbufBits >> bd->inbufBitCount)&((1 << bits_wanted)-1);
++
++ return bits;
++}
++
++/* Unpacks the next block and sets up for the inverse burrows-wheeler step. */
++
++static int INIT get_next_block(struct bunzip_data *bd)
++{
++ struct group_data *hufGroup = NULL;
++ int *base = NULL;
++ int *limit = NULL;
++ int dbufCount, nextSym, dbufSize, groupCount, selector,
++ i, j, k, t, runPos, symCount, symTotal, nSelectors,
++ byteCount[256];
++ unsigned char uc, symToByte[256], mtfSymbol[256], *selectors;
++ unsigned int *dbuf, origPtr;
++
++ dbuf = bd->dbuf;
++ dbufSize = bd->dbufSize;
++ selectors = bd->selectors;
++
++ /* Read in header signature and CRC, then validate signature.
++ (last block signature means CRC is for whole file, return now) */
++ i = get_bits(bd, 24);
++ j = get_bits(bd, 24);
++ bd->headerCRC = get_bits(bd, 32);
++ if ((i == 0x177245) && (j == 0x385090))
++ return RETVAL_LAST_BLOCK;
++ if ((i != 0x314159) || (j != 0x265359))
++ return RETVAL_NOT_BZIP_DATA;
++ /* We can add support for blockRandomised if anybody complains.
++ There was some code for this in busybox 1.0.0-pre3, but nobody ever
++ noticed that it didn't actually work. */
++ if (get_bits(bd, 1))
++ return RETVAL_OBSOLETE_INPUT;
++ origPtr = get_bits(bd, 24);
++ if (origPtr > dbufSize)
++ return RETVAL_DATA_ERROR;
++ /* mapping table: if some byte values are never used (encoding things
++ like ascii text), the compression code removes the gaps to have fewer
++ symbols to deal with, and writes a sparse bitfield indicating which
++ values were present. We make a translation table to convert the
++ symbols back to the corresponding bytes. */
++ t = get_bits(bd, 16);
++ symTotal = 0;
++ for (i = 0; i < 16; i++) {
++ if (t&(1 << (15-i))) {
++ k = get_bits(bd, 16);
++ for (j = 0; j < 16; j++)
++ if (k&(1 << (15-j)))
++ symToByte[symTotal++] = (16*i)+j;
++ }
++ }
++ /* How many different Huffman coding groups does this block use? */
++ groupCount = get_bits(bd, 3);
++ if (groupCount < 2 || groupCount > MAX_GROUPS)
++ return RETVAL_DATA_ERROR;
++ /* nSelectors: Every GROUP_SIZE many symbols we select a new
++ Huffman coding group. Read in the group selector list,
++ which is stored as MTF encoded bit runs. (MTF = Move To
++ Front, as each value is used it's moved to the start of the
++ list.) */
++ nSelectors = get_bits(bd, 15);
++ if (!nSelectors)
++ return RETVAL_DATA_ERROR;
++ for (i = 0; i < groupCount; i++)
++ mtfSymbol[i] = i;
++ for (i = 0; i < nSelectors; i++) {
++ /* Get next value */
++ for (j = 0; get_bits(bd, 1); j++)
++ if (j >= groupCount)
++ return RETVAL_DATA_ERROR;
++ /* Decode MTF to get the next selector */
++ uc = mtfSymbol[j];
++ for (; j; j--)
++ mtfSymbol[j] = mtfSymbol[j-1];
++ mtfSymbol[0] = selectors[i] = uc;
++ }
++ /* Read the Huffman coding tables for each group, which code
++ for symTotal literal symbols, plus two run symbols (RUNA,
++ RUNB) */
++ symCount = symTotal+2;
++ for (j = 0; j < groupCount; j++) {
++ unsigned char length[MAX_SYMBOLS], temp[MAX_HUFCODE_BITS+1];
++ int minLen, maxLen, pp;
++ /* Read Huffman code lengths for each symbol. They're
++ stored in a way similar to mtf; record a starting
++ value for the first symbol, and an offset from the
++ previous value for everys symbol after that.
++ (Subtracting 1 before the loop and then adding it
++ back at the end is an optimization that makes the
++ test inside the loop simpler: symbol length 0
++ becomes negative, so an unsigned inequality catches
++ it.) */
++ t = get_bits(bd, 5)-1;
++ for (i = 0; i < symCount; i++) {
++ for (;;) {
++ if (((unsigned)t) > (MAX_HUFCODE_BITS-1))
++ return RETVAL_DATA_ERROR;
++
++ /* If first bit is 0, stop. Else
++ second bit indicates whether to
++ increment or decrement the value.
++ Optimization: grab 2 bits and unget
++ the second if the first was 0. */
++
++ k = get_bits(bd, 2);
++ if (k < 2) {
++ bd->inbufBitCount++;
++ break;
++ }
++ /* Add one if second bit 1, else
++ * subtract 1. Avoids if/else */
++ t += (((k+1)&2)-1);
++ }
++ /* Correct for the initial -1, to get the
++ * final symbol length */
++ length[i] = t+1;
++ }
++ /* Find largest and smallest lengths in this group */
++ minLen = maxLen = length[0];
++
++ for (i = 1; i < symCount; i++) {
++ if (length[i] > maxLen)
++ maxLen = length[i];
++ else if (length[i] < minLen)
++ minLen = length[i];
++ }
++
++ /* Calculate permute[], base[], and limit[] tables from
++ * length[].
++ *
++ * permute[] is the lookup table for converting
++ * Huffman coded symbols into decoded symbols. base[]
++ * is the amount to subtract from the value of a
++ * Huffman symbol of a given length when using
++ * permute[].
++ *
++ * limit[] indicates the largest numerical value a
++ * symbol with a given number of bits can have. This
++ * is how the Huffman codes can vary in length: each
++ * code with a value > limit[length] needs another
++ * bit.
++ */
++ hufGroup = bd->groups+j;
++ hufGroup->minLen = minLen;
++ hufGroup->maxLen = maxLen;
++ /* Note that minLen can't be smaller than 1, so we
++ adjust the base and limit array pointers so we're
++ not always wasting the first entry. We do this
++ again when using them (during symbol decoding).*/
++ base = hufGroup->base-1;
++ limit = hufGroup->limit-1;
++ /* Calculate permute[]. Concurently, initialize
++ * temp[] and limit[]. */
++ pp = 0;
++ for (i = minLen; i <= maxLen; i++) {
++ temp[i] = limit[i] = 0;
++ for (t = 0; t < symCount; t++)
++ if (length[t] == i)
++ hufGroup->permute[pp++] = t;
++ }
++ /* Count symbols coded for at each bit length */
++ for (i = 0; i < symCount; i++)
++ temp[length[i]]++;
++ /* Calculate limit[] (the largest symbol-coding value
++ *at each bit length, which is (previous limit <<
++ *1)+symbols at this level), and base[] (number of
++ *symbols to ignore at each bit length, which is limit
++ *minus the cumulative count of symbols coded for
++ *already). */
++ pp = t = 0;
++ for (i = minLen; i < maxLen; i++) {
++ pp += temp[i];
++ /* We read the largest possible symbol size
++ and then unget bits after determining how
++ many we need, and those extra bits could be
++ set to anything. (They're noise from
++ future symbols.) At each level we're
++ really only interested in the first few
++ bits, so here we set all the trailing
++ to-be-ignored bits to 1 so they don't
++ affect the value > limit[length]
++ comparison. */
++ limit[i] = (pp << (maxLen - i)) - 1;
++ pp <<= 1;
++ base[i+1] = pp-(t += temp[i]);
++ }
++ limit[maxLen+1] = INT_MAX; /* Sentinal value for
++ * reading next sym. */
++ limit[maxLen] = pp+temp[maxLen]-1;
++ base[minLen] = 0;
++ }
++ /* We've finished reading and digesting the block header. Now
++ read this block's Huffman coded symbols from the file and
++ undo the Huffman coding and run length encoding, saving the
++ result into dbuf[dbufCount++] = uc */
++
++ /* Initialize symbol occurrence counters and symbol Move To
++ * Front table */
++ for (i = 0; i < 256; i++) {
++ byteCount[i] = 0;
++ mtfSymbol[i] = (unsigned char)i;
++ }
++ /* Loop through compressed symbols. */
++ runPos = dbufCount = symCount = selector = 0;
++ for (;;) {
++ /* Determine which Huffman coding group to use. */
++ if (!(symCount--)) {
++ symCount = GROUP_SIZE-1;
++ if (selector >= nSelectors)
++ return RETVAL_DATA_ERROR;
++ hufGroup = bd->groups+selectors[selector++];
++ base = hufGroup->base-1;
++ limit = hufGroup->limit-1;
++ }
++ /* Read next Huffman-coded symbol. */
++ /* Note: It is far cheaper to read maxLen bits and
++ back up than it is to read minLen bits and then an
++ additional bit at a time, testing as we go.
++ Because there is a trailing last block (with file
++ CRC), there is no danger of the overread causing an
++ unexpected EOF for a valid compressed file. As a
++ further optimization, we do the read inline
++ (falling back to a call to get_bits if the buffer
++ runs dry). The following (up to got_huff_bits:) is
++ equivalent to j = get_bits(bd, hufGroup->maxLen);
++ */
++ while (bd->inbufBitCount < hufGroup->maxLen) {
++ if (bd->inbufPos == bd->inbufCount) {
++ j = get_bits(bd, hufGroup->maxLen);
++ goto got_huff_bits;
++ }
++ bd->inbufBits =
++ (bd->inbufBits << 8)|bd->inbuf[bd->inbufPos++];
++ bd->inbufBitCount += 8;
++ };
++ bd->inbufBitCount -= hufGroup->maxLen;
++ j = (bd->inbufBits >> bd->inbufBitCount)&
++ ((1 << hufGroup->maxLen)-1);
++got_huff_bits:
++ /* Figure how how many bits are in next symbol and
++ * unget extras */
++ i = hufGroup->minLen;
++ while (j > limit[i])
++ ++i;
++ bd->inbufBitCount += (hufGroup->maxLen - i);
++ /* Huffman decode value to get nextSym (with bounds checking) */
++ if ((i > hufGroup->maxLen)
++ || (((unsigned)(j = (j>>(hufGroup->maxLen-i))-base[i]))
++ >= MAX_SYMBOLS))
++ return RETVAL_DATA_ERROR;
++ nextSym = hufGroup->permute[j];
++ /* We have now decoded the symbol, which indicates
++ either a new literal byte, or a repeated run of the
++ most recent literal byte. First, check if nextSym
++ indicates a repeated run, and if so loop collecting
++ how many times to repeat the last literal. */
++ if (((unsigned)nextSym) <= SYMBOL_RUNB) { /* RUNA or RUNB */
++ /* If this is the start of a new run, zero out
++ * counter */
++ if (!runPos) {
++ runPos = 1;
++ t = 0;
++ }
++ /* Neat trick that saves 1 symbol: instead of
++ or-ing 0 or 1 at each bit position, add 1
++ or 2 instead. For example, 1011 is 1 << 0
++ + 1 << 1 + 2 << 2. 1010 is 2 << 0 + 2 << 1
++ + 1 << 2. You can make any bit pattern
++ that way using 1 less symbol than the basic
++ or 0/1 method (except all bits 0, which
++ would use no symbols, but a run of length 0
++ doesn't mean anything in this context).
++ Thus space is saved. */
++ t += (runPos << nextSym);
++ /* +runPos if RUNA; +2*runPos if RUNB */
++
++ runPos <<= 1;
++ continue;
++ }
++ /* When we hit the first non-run symbol after a run,
++ we now know how many times to repeat the last
++ literal, so append that many copies to our buffer
++ of decoded symbols (dbuf) now. (The last literal
++ used is the one at the head of the mtfSymbol
++ array.) */
++ if (runPos) {
++ runPos = 0;
++ if (dbufCount+t >= dbufSize)
++ return RETVAL_DATA_ERROR;
++
++ uc = symToByte[mtfSymbol[0]];
++ byteCount[uc] += t;
++ while (t--)
++ dbuf[dbufCount++] = uc;
++ }
++ /* Is this the terminating symbol? */
++ if (nextSym > symTotal)
++ break;
++ /* At this point, nextSym indicates a new literal
++ character. Subtract one to get the position in the
++ MTF array at which this literal is currently to be
++ found. (Note that the result can't be -1 or 0,
++ because 0 and 1 are RUNA and RUNB. But another
++ instance of the first symbol in the mtf array,
++ position 0, would have been handled as part of a
++ run above. Therefore 1 unused mtf position minus 2
++ non-literal nextSym values equals -1.) */
++ if (dbufCount >= dbufSize)
++ return RETVAL_DATA_ERROR;
++ i = nextSym - 1;
++ uc = mtfSymbol[i];
++ /* Adjust the MTF array. Since we typically expect to
++ *move only a small number of symbols, and are bound
++ *by 256 in any case, using memmove here would
++ *typically be bigger and slower due to function call
++ *overhead and other assorted setup costs. */
++ do {
++ mtfSymbol[i] = mtfSymbol[i-1];
++ } while (--i);
++ mtfSymbol[0] = uc;
++ uc = symToByte[uc];
++ /* We have our literal byte. Save it into dbuf. */
++ byteCount[uc]++;
++ dbuf[dbufCount++] = (unsigned int)uc;
++ }
++ /* At this point, we've read all the Huffman-coded symbols
++ (and repeated runs) for this block from the input stream,
++ and decoded them into the intermediate buffer. There are
++ dbufCount many decoded bytes in dbuf[]. Now undo the
++ Burrows-Wheeler transform on dbuf. See
++ http://dogma.net/markn/articles/bwt/bwt.htm
++ */
++ /* Turn byteCount into cumulative occurrence counts of 0 to n-1. */
++ j = 0;
++ for (i = 0; i < 256; i++) {
++ k = j+byteCount[i];
++ byteCount[i] = j;
++ j = k;
++ }
++ /* Figure out what order dbuf would be in if we sorted it. */
++ for (i = 0; i < dbufCount; i++) {
++ uc = (unsigned char)(dbuf[i] & 0xff);
++ dbuf[byteCount[uc]] |= (i << 8);
++ byteCount[uc]++;
++ }
++ /* Decode first byte by hand to initialize "previous" byte.
++ Note that it doesn't get output, and if the first three
++ characters are identical it doesn't qualify as a run (hence
++ writeRunCountdown = 5). */
++ if (dbufCount) {
++ if (origPtr >= dbufCount)
++ return RETVAL_DATA_ERROR;
++ bd->writePos = dbuf[origPtr];
++ bd->writeCurrent = (unsigned char)(bd->writePos&0xff);
++ bd->writePos >>= 8;
++ bd->writeRunCountdown = 5;
++ }
++ bd->writeCount = dbufCount;
++
++ return RETVAL_OK;
++}
++
++/* Undo burrows-wheeler transform on intermediate buffer to produce output.
++ If start_bunzip was initialized with out_fd =-1, then up to len bytes of
++ data are written to outbuf. Return value is number of bytes written or
++ error (all errors are negative numbers). If out_fd!=-1, outbuf and len
++ are ignored, data is written to out_fd and return is RETVAL_OK or error.
++*/
++
++static int INIT read_bunzip(struct bunzip_data *bd, char *outbuf, int len)
++{
++ const unsigned int *dbuf;
++ int pos, xcurrent, previous, gotcount;
++
++ /* If last read was short due to end of file, return last block now */
++ if (bd->writeCount < 0)
++ return bd->writeCount;
++
++ gotcount = 0;
++ dbuf = bd->dbuf;
++ pos = bd->writePos;
++ xcurrent = bd->writeCurrent;
++
++ /* We will always have pending decoded data to write into the output
++ buffer unless this is the very first call (in which case we haven't
++ Huffman-decoded a block into the intermediate buffer yet). */
++
++ if (bd->writeCopies) {
++ /* Inside the loop, writeCopies means extra copies (beyond 1) */
++ --bd->writeCopies;
++ /* Loop outputting bytes */
++ for (;;) {
++ /* If the output buffer is full, snapshot
++ * state and return */
++ if (gotcount >= len) {
++ bd->writePos = pos;
++ bd->writeCurrent = xcurrent;
++ bd->writeCopies++;
++ return len;
++ }
++ /* Write next byte into output buffer, updating CRC */
++ outbuf[gotcount++] = xcurrent;
++ bd->writeCRC = (((bd->writeCRC) << 8)
++ ^bd->crc32Table[((bd->writeCRC) >> 24)
++ ^xcurrent]);
++ /* Loop now if we're outputting multiple
++ * copies of this byte */
++ if (bd->writeCopies) {
++ --bd->writeCopies;
++ continue;
++ }
++decode_next_byte:
++ if (!bd->writeCount--)
++ break;
++ /* Follow sequence vector to undo
++ * Burrows-Wheeler transform */
++ previous = xcurrent;
++ pos = dbuf[pos];
++ xcurrent = pos&0xff;
++ pos >>= 8;
++ /* After 3 consecutive copies of the same
++ byte, the 4th is a repeat count. We count
++ down from 4 instead *of counting up because
++ testing for non-zero is faster */
++ if (--bd->writeRunCountdown) {
++ if (xcurrent != previous)
++ bd->writeRunCountdown = 4;
++ } else {
++ /* We have a repeated run, this byte
++ * indicates the count */
++ bd->writeCopies = xcurrent;
++ xcurrent = previous;
++ bd->writeRunCountdown = 5;
++ /* Sometimes there are just 3 bytes
++ * (run length 0) */
++ if (!bd->writeCopies)
++ goto decode_next_byte;
++ /* Subtract the 1 copy we'd output
++ * anyway to get extras */
++ --bd->writeCopies;
++ }
++ }
++ /* Decompression of this block completed successfully */
++ bd->writeCRC = ~bd->writeCRC;
++ bd->totalCRC = ((bd->totalCRC << 1) |
++ (bd->totalCRC >> 31)) ^ bd->writeCRC;
++ /* If this block had a CRC error, force file level CRC error. */
++ if (bd->writeCRC != bd->headerCRC) {
++ bd->totalCRC = bd->headerCRC+1;
++ return RETVAL_LAST_BLOCK;
++ }
++ }
++
++ /* Refill the intermediate buffer by Huffman-decoding next
++ * block of input */
++ /* (previous is just a convenient unused temp variable here) */
++ previous = get_next_block(bd);
++ if (previous) {
++ bd->writeCount = previous;
++ return (previous != RETVAL_LAST_BLOCK) ? previous : gotcount;
++ }
++ bd->writeCRC = 0xffffffffUL;
++ pos = bd->writePos;
++ xcurrent = bd->writeCurrent;
++ goto decode_next_byte;
++}
++
++static int INIT nofill(void *buf, unsigned int len)
++{
++ return -1;
++}
++
++/* Allocate the structure, read file header. If in_fd ==-1, inbuf must contain
++ a complete bunzip file (len bytes long). If in_fd!=-1, inbuf and len are
++ ignored, and data is read from file handle into temporary buffer. */
++static int INIT start_bunzip(struct bunzip_data **bdp, void *inbuf, int len,
++ int (*fill)(void*, unsigned int))
++{
++ struct bunzip_data *bd;
++ unsigned int i, j, c;
++ const unsigned int BZh0 =
++ (((unsigned int)'B') << 24)+(((unsigned int)'Z') << 16)
++ +(((unsigned int)'h') << 8)+(unsigned int)'0';
++
++ /* Figure out how much data to allocate */
++ i = sizeof(struct bunzip_data);
++
++ /* Allocate bunzip_data. Most fields initialize to zero. */
++ bd = *bdp = malloc(i);
++ memset(bd, 0, sizeof(struct bunzip_data));
++ /* Setup input buffer */
++ bd->inbuf = inbuf;
++ bd->inbufCount = len;
++ if (fill != NULL)
++ bd->fill = fill;
++ else
++ bd->fill = nofill;
++
++ /* Init the CRC32 table (big endian) */
++ for (i = 0; i < 256; i++) {
++ c = i << 24;
++ for (j = 8; j; j--)
++ c = c&0x80000000 ? (c << 1)^0x04c11db7 : (c << 1);
++ bd->crc32Table[i] = c;
++ }
++
++ /* Ensure that file starts with "BZh['1'-'9']." */
++ i = get_bits(bd, 32);
++ if (((unsigned int)(i-BZh0-1)) >= 9)
++ return RETVAL_NOT_BZIP_DATA;
++
++ /* Fourth byte (ascii '1'-'9'), indicates block size in units of 100k of
++ uncompressed data. Allocate intermediate buffer for block. */
++ bd->dbufSize = 100000*(i-BZh0);
++
++ bd->dbuf = large_malloc(bd->dbufSize * sizeof(int));
++ return RETVAL_OK;
++}
++
++/* Example usage: decompress src_fd to dst_fd. (Stops at end of bzip2 data,
++ not end of file.) */
++STATIC int INIT bunzip2(unsigned char *buf, int len,
++ int(*fill)(void*, unsigned int),
++ int(*flush)(void*, unsigned int),
++ unsigned char *outbuf,
++ int *pos,
++ void(*error_fn)(char *x))
++{
++ struct bunzip_data *bd;
++ int i = -1;
++ unsigned char *inbuf;
++
++ set_error_fn(error_fn);
++ if (flush)
++ outbuf = malloc(BZIP2_IOBUF_SIZE);
++ else
++ len -= 4; /* Uncompressed size hack active in pre-boot
++ environment */
++ if (!outbuf) {
++ error("Could not allocate output bufer");
++ return -1;
++ }
++ if (buf)
++ inbuf = buf;
++ else
++ inbuf = malloc(BZIP2_IOBUF_SIZE);
++ if (!inbuf) {
++ error("Could not allocate input bufer");
++ goto exit_0;
++ }
++ i = start_bunzip(&bd, inbuf, len, fill);
++ if (!i) {
++ for (;;) {
++ i = read_bunzip(bd, outbuf, BZIP2_IOBUF_SIZE);
++ if (i <= 0)
++ break;
++ if (!flush)
++ outbuf += i;
++ else
++ if (i != flush(outbuf, i)) {
++ i = RETVAL_UNEXPECTED_OUTPUT_EOF;
++ break;
++ }
++ }
++ }
++ /* Check CRC and release memory */
++ if (i == RETVAL_LAST_BLOCK) {
++ if (bd->headerCRC != bd->totalCRC)
++ error("Data integrity error when decompressing.");
++ else
++ i = RETVAL_OK;
++ } else if (i == RETVAL_UNEXPECTED_OUTPUT_EOF) {
++ error("Compressed file ends unexpectedly");
++ }
++ if (bd->dbuf)
++ large_free(bd->dbuf);
++ if (pos)
++ *pos = bd->inbufPos;
++ free(bd);
++ if (!buf)
++ free(inbuf);
++exit_0:
++ if (flush)
++ free(outbuf);
++ return i;
++}
++
++#define decompress bunzip2
+diff --git a/lib/decompress_inflate.c
+new file mode 100644
+index 0000000..163e66a
+--- /dev/null
++++ b/lib/decompress_inflate.c
+@@ -0,0 +1,167 @@
++#ifdef STATIC
++/* Pre-boot environment: included */
++
++/* prevent inclusion of _LINUX_KERNEL_H in pre-boot environment: lots
++ * errors about console_printk etc... on ARM */
++#define _LINUX_KERNEL_H
++
++#include "zlib_inflate/inftrees.c"
++#include "zlib_inflate/inffast.c"
++#include "zlib_inflate/inflate.c"
++
++#else /* STATIC */
++/* initramfs et al: linked */
++
++#include <linux/zutil.h>
++
++#include "zlib_inflate/inftrees.h"
++#include "zlib_inflate/inffast.h"
++#include "zlib_inflate/inflate.h"
++
++#include "zlib_inflate/infutil.h"
++
++#endif /* STATIC */
++
++#include <linux/decompress/mm.h>
++
++#define INBUF_LEN (16*1024)
++
++/* Included from initramfs et al code */
++STATIC int INIT gunzip(unsigned char *buf, int len,
++ int(*fill)(void*, unsigned int),
++ int(*flush)(void*, unsigned int),
++ unsigned char *out_buf,
++ int *pos,
++ void(*error_fn)(char *x)) {
++ u8 *zbuf;
++ struct z_stream_s *strm;
++ int rc;
++ size_t out_len;
++
++ set_error_fn(error_fn);
++ rc = -1;
++ if (flush) {
++ out_len = 0x8100; /* 32 K */
++ out_buf = malloc(out_len);
++ } else {
++ out_len = 0x7fffffff; /* no limit */
++ }
++ if (!out_buf) {
++ error("Out of memory while allocating output buffer");
++ goto gunzip_nomem1;
++ }
++
++ if (buf)
++ zbuf = buf;
++ else {
++ zbuf = malloc(INBUF_LEN);
++ len = 0;
++ }
++ if (!zbuf) {
++ error("Out of memory while allocating input buffer");
++ goto gunzip_nomem2;
++ }
++
++ strm = malloc(sizeof(*strm));
++ if (strm == NULL) {
++ error("Out of memory while allocating z_stream");
++ goto gunzip_nomem3;
++ }
++
++ strm->workspace = malloc(flush ? zlib_inflate_workspacesize() :
++ sizeof(struct inflate_state));
++ if (strm->workspace == NULL) {
++ error("Out of memory while allocating workspace");
++ goto gunzip_nomem4;
++ }
++
++ if (len == 0)
++ len = fill(zbuf, INBUF_LEN);
++
++ /* verify the gzip header */
++ if (len < 10 ||
++ zbuf[0] != 0x1f || zbuf[1] != 0x8b || zbuf[2] != 0x08) {
++ if (pos)
++ *pos = 0;
++ error("Not a gzip file");
++ goto gunzip_5;
++ }
++
++ /* skip over gzip header (1f,8b,08... 10 bytes total +
++ * possible asciz filename)
++ */
++ strm->next_in = zbuf + 10;
++ /* skip over asciz filename */
++ if (zbuf[3] & 0x8) {
++ while (strm->next_in[0])
++ strm->next_in++;
++ strm->next_in++;
++ }
++ strm->avail_in = len - 10;
++
++ strm->next_out = out_buf;
++ strm->avail_out = out_len;
++
++ rc = zlib_inflateInit2(strm, -MAX_WBITS);
++
++ if (!flush) {
++ WS(strm)->inflate_state.wsize = 0;
++ WS(strm)->inflate_state.window = NULL;
++ }
++
++ while (rc == Z_OK) {
++ if (strm->avail_in == 0) {
++ /* TODO: handle case where both pos and fill are set */
++ len = fill(zbuf, INBUF_LEN);
++ if (len < 0) {
++ rc = -1;
++ error("read error");
++ break;
++ }
++ strm->next_in = zbuf;
++ strm->avail_in = len;
++ }
++ rc = zlib_inflate(strm, 0);
++
++ /* Write any data generated */
++ if (flush && strm->next_out > out_buf) {
++ int l = strm->next_out - out_buf;
++ if (l != flush(out_buf, l)) {
++ rc = -1;
++ error("write error");
++ break;
++ }
++ strm->next_out = out_buf;
++ strm->avail_out = out_len;
++ }
++
++ /* after Z_FINISH, only Z_STREAM_END is "we unpacked it all" */
++ if (rc == Z_STREAM_END) {
++ rc = 0;
++ break;
++ } else if (rc != Z_OK) {
++ error("uncompression error");
++ rc = -1;
++ }
++ }
++
++ zlib_inflateEnd(strm);
++ if (pos)
++ /* add + 8 to skip over trailer */
++ *pos = strm->next_in - zbuf+8;
++
++gunzip_5:
++ free(strm->workspace);
++gunzip_nomem4:
++ free(strm);
++gunzip_nomem3:
++ if (!buf)
++ free(zbuf);
++gunzip_nomem2:
++ if (flush)
++ free(out_buf);
++gunzip_nomem1:
++ return rc; /* returns Z_OK (0) if successful */
++}
++
++#define decompress gunzip
+diff --git a/lib/decompress_unlzma.c
+new file mode 100644
+index 0000000..546f2f4
+--- /dev/null
++++ b/lib/decompress_unlzma.c
+@@ -0,0 +1,647 @@
++/* Lzma decompressor for Linux kernel. Shamelessly snarfed
++ *from busybox 1.1.1
++ *
++ *Linux kernel adaptation
++ *Copyright (C) 2006 Alain < alain@knaff.lu >
++ *
++ *Based on small lzma deflate implementation/Small range coder
++ *implementation for lzma.
++ *Copyright (C) 2006 Aurelien Jacobs < aurel@gnuage.org >
++ *
++ *Based on LzmaDecode.c from the LZMA SDK 4.22 (http://www.7-zip.org/)
++ *Copyright (C) 1999-2005 Igor Pavlov
++ *
++ *Copyrights of the parts, see headers below.
++ *
++ *
++ *This program is free software; you can redistribute it and/or
++ *modify it under the terms of the GNU Lesser General Public
++ *License as published by the Free Software Foundation; either
++ *version 2.1 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
++ *Lesser General Public License for more details.
++ *
++ *You should have received a copy of the GNU Lesser General Public
++ *License along with this library; if not, write to the Free Software
++ *Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#ifndef STATIC
++#include <linux/decompress/unlzma.h>
++#endif /* STATIC */
++
++#include <linux/decompress/mm.h>
++
++#define MIN(a, b) (((a) < (b)) ? (a) : (b))
++
++static long long INIT read_int(unsigned char *ptr, int size)
++{
++ int i;
++ long long ret = 0;
++
++ for (i = 0; i < size; i++)
++ ret = (ret << 8) | ptr[size-i-1];
++ return ret;
++}
++
++#define ENDIAN_CONVERT(x) \
++ x = (typeof(x))read_int((unsigned char *)&x, sizeof(x))
++
++
++/* Small range coder implementation for lzma.
++ *Copyright (C) 2006 Aurelien Jacobs < aurel@gnuage.org >
++ *
++ *Based on LzmaDecode.c from the LZMA SDK 4.22 (http://www.7-zip.org/)
++ *Copyright (c) 1999-2005 Igor Pavlov
++ */
++
++#include <linux/compiler.h>
++
++#define LZMA_IOBUF_SIZE 0x10000
++
++struct rc {
++ int (*fill)(void*, unsigned int);
++ uint8_t *ptr;
++ uint8_t *buffer;
++ uint8_t *buffer_end;
++ int buffer_size;
++ uint32_t code;
++ uint32_t range;
++ uint32_t bound;
++};
++
++
++#define RC_TOP_BITS 24
++#define RC_MOVE_BITS 5
++#define RC_MODEL_TOTAL_BITS 11
++
++
++/* Called twice: once at startup and once in rc_normalize() */
++static void INIT rc_read(struct rc *rc)
++{
++ rc->buffer_size = rc->fill((char *)rc->buffer, LZMA_IOBUF_SIZE);
++ if (rc->buffer_size <= 0)
++ error("unexpected EOF");
++ rc->ptr = rc->buffer;
++ rc->buffer_end = rc->buffer + rc->buffer_size;
++}
++
++/* Called once */
++static inline void INIT rc_init(struct rc *rc,
++ int (*fill)(void*, unsigned int),
++ char *buffer, int buffer_size)
++{
++ rc->fill = fill;
++ rc->buffer = (uint8_t *)buffer;
++ rc->buffer_size = buffer_size;
++ rc->buffer_end = rc->buffer + rc->buffer_size;
++ rc->ptr = rc->buffer;
++
++ rc->code = 0;
++ rc->range = 0xFFFFFFFF;
++}
++
++static inline void INIT rc_init_code(struct rc *rc)
++{
++ int i;
++
++ for (i = 0; i < 5; i++) {
++ if (rc->ptr >= rc->buffer_end)
++ rc_read(rc);
++ rc->code = (rc->code << 8) | *rc->ptr++;
++ }
++}
++
++
++/* Called once. TODO: bb_maybe_free() */
++static inline void INIT rc_free(struct rc *rc)
++{
++ free(rc->buffer);
++}
++
++/* Called twice, but one callsite is in inline'd rc_is_bit_0_helper() */
++static void INIT rc_do_normalize(struct rc *rc)
++{
++ if (rc->ptr >= rc->buffer_end)
++ rc_read(rc);
++ rc->range <<= 8;
++ rc->code = (rc->code << 8) | *rc->ptr++;
++}
++static inline void INIT rc_normalize(struct rc *rc)
++{
++ if (rc->range < (1 << RC_TOP_BITS))
++ rc_do_normalize(rc);
++}
++
++/* Called 9 times */
++/* Why rc_is_bit_0_helper exists?
++ *Because we want to always expose (rc->code < rc->bound) to optimizer
++ */
++static inline uint32_t INIT rc_is_bit_0_helper(struct rc *rc, uint16_t *p)
++{
++ rc_normalize(rc);
++ rc->bound = *p * (rc->range >> RC_MODEL_TOTAL_BITS);
++ return rc->bound;
++}
++static inline int INIT rc_is_bit_0(struct rc *rc, uint16_t *p)
++{
++ uint32_t t = rc_is_bit_0_helper(rc, p);
++ return rc->code < t;
++}
++
++/* Called ~10 times, but very small, thus inlined */
++static inline void INIT rc_update_bit_0(struct rc *rc, uint16_t *p)
++{
++ rc->range = rc->bound;
++ *p += ((1 << RC_MODEL_TOTAL_BITS) - *p) >> RC_MOVE_BITS;
++}
++static inline void rc_update_bit_1(struct rc *rc, uint16_t *p)
++{
++ rc->range -= rc->bound;
++ rc->code -= rc->bound;
++ *p -= *p >> RC_MOVE_BITS;
++}
++
++/* Called 4 times in unlzma loop */
++static int INIT rc_get_bit(struct rc *rc, uint16_t *p, int *symbol)
++{
++ if (rc_is_bit_0(rc, p)) {
++ rc_update_bit_0(rc, p);
++ *symbol *= 2;
++ return 0;
++ } else {
++ rc_update_bit_1(rc, p);
++ *symbol = *symbol * 2 + 1;
++ return 1;
++ }
++}
++
++/* Called once */
++static inline int INIT rc_direct_bit(struct rc *rc)
++{
++ rc_normalize(rc);
++ rc->range >>= 1;
++ if (rc->code >= rc->range) {
++ rc->code -= rc->range;
++ return 1;
++ }
++ return 0;
++}
++
++/* Called twice */
++static inline void INIT
++rc_bit_tree_decode(struct rc *rc, uint16_t *p, int num_levels, int *symbol)
++{
++ int i = num_levels;
++
++ *symbol = 1;
++ while (i--)
++ rc_get_bit(rc, p + *symbol, symbol);
++ *symbol -= 1 << num_levels;
++}
++
++
++/*
++ * Small lzma deflate implementation.
++ * Copyright (C) 2006 Aurelien Jacobs < aurel@gnuage.org >
++ *
++ * Based on LzmaDecode.c from the LZMA SDK 4.22 (http://www.7-zip.org/)
++ * Copyright (C) 1999-2005 Igor Pavlov
++ */
++
++
++struct lzma_header {
++ uint8_t pos;
++ uint32_t dict_size;
++ uint64_t dst_size;
++} __attribute__ ((packed)) ;
++
++
++#define LZMA_BASE_SIZE 1846
++#define LZMA_LIT_SIZE 768
++
++#define LZMA_NUM_POS_BITS_MAX 4
++
++#define LZMA_LEN_NUM_LOW_BITS 3
++#define LZMA_LEN_NUM_MID_BITS 3
++#define LZMA_LEN_NUM_HIGH_BITS 8
++
++#define LZMA_LEN_CHOICE 0
++#define LZMA_LEN_CHOICE_2 (LZMA_LEN_CHOICE + 1)
++#define LZMA_LEN_LOW (LZMA_LEN_CHOICE_2 + 1)
++#define LZMA_LEN_MID (LZMA_LEN_LOW \
++ + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_LOW_BITS)))
++#define LZMA_LEN_HIGH (LZMA_LEN_MID \
++ +(1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_MID_BITS)))
++#define LZMA_NUM_LEN_PROBS (LZMA_LEN_HIGH + (1 << LZMA_LEN_NUM_HIGH_BITS))
++
++#define LZMA_NUM_STATES 12
++#define LZMA_NUM_LIT_STATES 7
++
++#define LZMA_START_POS_MODEL_INDEX 4
++#define LZMA_END_POS_MODEL_INDEX 14
++#define LZMA_NUM_FULL_DISTANCES (1 << (LZMA_END_POS_MODEL_INDEX >> 1))
++
++#define LZMA_NUM_POS_SLOT_BITS 6
++#define LZMA_NUM_LEN_TO_POS_STATES 4
++
++#define LZMA_NUM_ALIGN_BITS 4
++
++#define LZMA_MATCH_MIN_LEN 2
++
++#define LZMA_IS_MATCH 0
++#define LZMA_IS_REP (LZMA_IS_MATCH + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX))
++#define LZMA_IS_REP_G0 (LZMA_IS_REP + LZMA_NUM_STATES)
++#define LZMA_IS_REP_G1 (LZMA_IS_REP_G0 + LZMA_NUM_STATES)
++#define LZMA_IS_REP_G2 (LZMA_IS_REP_G1 + LZMA_NUM_STATES)
++#define LZMA_IS_REP_0_LONG (LZMA_IS_REP_G2 + LZMA_NUM_STATES)
++#define LZMA_POS_SLOT (LZMA_IS_REP_0_LONG \
++ + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX))
++#define LZMA_SPEC_POS (LZMA_POS_SLOT \
++ +(LZMA_NUM_LEN_TO_POS_STATES << LZMA_NUM_POS_SLOT_BITS))
++#define LZMA_ALIGN (LZMA_SPEC_POS \
++ + LZMA_NUM_FULL_DISTANCES - LZMA_END_POS_MODEL_INDEX)
++#define LZMA_LEN_CODER (LZMA_ALIGN + (1 << LZMA_NUM_ALIGN_BITS))
++#define LZMA_REP_LEN_CODER (LZMA_LEN_CODER + LZMA_NUM_LEN_PROBS)
++#define LZMA_LITERAL (LZMA_REP_LEN_CODER + LZMA_NUM_LEN_PROBS)
++
++
++struct writer {
++ uint8_t *buffer;
++ uint8_t previous_byte;
++ size_t buffer_pos;
++ int bufsize;
++ size_t global_pos;
++ int(*flush)(void*, unsigned int);
++ struct lzma_header *header;
++};
++
++struct cstate {
++ int state;
++ uint32_t rep0, rep1, rep2, rep3;
++};
++
++static inline size_t INIT get_pos(struct writer *wr)
++{
++ return
++ wr->global_pos + wr->buffer_pos;
++}
++
++static inline uint8_t INIT peek_old_byte(struct writer *wr,
++ uint32_t offs)
++{
++ if (!wr->flush) {
++ int32_t pos;
++ while (offs > wr->header->dict_size)
++ offs -= wr->header->dict_size;
++ pos = wr->buffer_pos - offs;
++ return wr->buffer[pos];
++ } else {
++ uint32_t pos = wr->buffer_pos - offs;
++ while (pos >= wr->header->dict_size)
++ pos += wr->header->dict_size;
++ return wr->buffer[pos];
++ }
++
++}
++
++static inline void INIT write_byte(struct writer *wr, uint8_t byte)
++{
++ wr->buffer[wr->buffer_pos++] = wr->previous_byte = byte;
++ if (wr->flush && wr->buffer_pos == wr->header->dict_size) {
++ wr->buffer_pos = 0;
++ wr->global_pos += wr->header->dict_size;
++ wr->flush((char *)wr->buffer, wr->header->dict_size);
++ }
++}
++
++
++static inline void INIT copy_byte(struct writer *wr, uint32_t offs)
++{
++ write_byte(wr, peek_old_byte(wr, offs));
++}
++
++static inline void INIT copy_bytes(struct writer *wr,
++ uint32_t rep0, int len)
++{
++ do {
++ copy_byte(wr, rep0);
++ len--;
++ } while (len != 0 && wr->buffer_pos < wr->header->dst_size);
++}
++
++static inline void INIT process_bit0(struct writer *wr, struct rc *rc,
++ struct cstate *cst, uint16_t *p,
++ int pos_state, uint16_t *prob,
++ int lc, uint32_t literal_pos_mask) {
++ int mi = 1;
++ rc_update_bit_0(rc, prob);
++ prob = (p + LZMA_LITERAL +
++ (LZMA_LIT_SIZE
++ * (((get_pos(wr) & literal_pos_mask) << lc)
++ + (wr->previous_byte >> (8 - lc))))
++ );
++
++ if (cst->state >= LZMA_NUM_LIT_STATES) {
++ int match_byte = peek_old_byte(wr, cst->rep0);
++ do {
++ int bit;
++ uint16_t *prob_lit;
++
++ match_byte <<= 1;
++ bit = match_byte & 0x100;
++ prob_lit = prob + 0x100 + bit + mi;
++ if (rc_get_bit(rc, prob_lit, &mi)) {
++ if (!bit)
++ break;
++ } else {
++ if (bit)
++ break;
++ }
++ } while (mi < 0x100);
++ }
++ while (mi < 0x100) {
++ uint16_t *prob_lit = prob + mi;
++ rc_get_bit(rc, prob_lit, &mi);
++ }
++ write_byte(wr, mi);
++ if (cst->state < 4)
++ cst->state = 0;
++ else if (cst->state < 10)
++ cst->state -= 3;
++ else
++ cst->state -= 6;
++}
++
++static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
++ struct cstate *cst, uint16_t *p,
++ int pos_state, uint16_t *prob) {
++ int offset;
++ uint16_t *prob_len;
++ int num_bits;
++ int len;
++
++ rc_update_bit_1(rc, prob);
++ prob = p + LZMA_IS_REP + cst->state;
++ if (rc_is_bit_0(rc, prob)) {
++ rc_update_bit_0(rc, prob);
++ cst->rep3 = cst->rep2;
++ cst->rep2 = cst->rep1;
++ cst->rep1 = cst->rep0;
++ cst->state = cst->state < LZMA_NUM_LIT_STATES ? 0 : 3;
++ prob = p + LZMA_LEN_CODER;
++ } else {
++ rc_update_bit_1(rc, prob);
++ prob = p + LZMA_IS_REP_G0 + cst->state;
++ if (rc_is_bit_0(rc, prob)) {
++ rc_update_bit_0(rc, prob);
++ prob = (p + LZMA_IS_REP_0_LONG
++ + (cst->state <<
++ LZMA_NUM_POS_BITS_MAX) +
++ pos_state);
++ if (rc_is_bit_0(rc, prob)) {
++ rc_update_bit_0(rc, prob);
++
++ cst->state = cst->state < LZMA_NUM_LIT_STATES ?
++ 9 : 11;
++ copy_byte(wr, cst->rep0);
++ return;
++ } else {
++ rc_update_bit_1(rc, prob);
++ }
++ } else {
++ uint32_t distance;
++
++ rc_update_bit_1(rc, prob);
++ prob = p + LZMA_IS_REP_G1 + cst->state;
++ if (rc_is_bit_0(rc, prob)) {
++ rc_update_bit_0(rc, prob);
++ distance = cst->rep1;
++ } else {
++ rc_update_bit_1(rc, prob);
++ prob = p + LZMA_IS_REP_G2 + cst->state;
++ if (rc_is_bit_0(rc, prob)) {
++ rc_update_bit_0(rc, prob);
++ distance = cst->rep2;
++ } else {
++ rc_update_bit_1(rc, prob);
++ distance = cst->rep3;
++ cst->rep3 = cst->rep2;
++ }
++ cst->rep2 = cst->rep1;
++ }
++ cst->rep1 = cst->rep0;
++ cst->rep0 = distance;
++ }
++ cst->state = cst->state < LZMA_NUM_LIT_STATES ? 8 : 11;
++ prob = p + LZMA_REP_LEN_CODER;
++ }
++
++ prob_len = prob + LZMA_LEN_CHOICE;
++ if (rc_is_bit_0(rc, prob_len)) {
++ rc_update_bit_0(rc, prob_len);
++ prob_len = (prob + LZMA_LEN_LOW
++ + (pos_state <<
++ LZMA_LEN_NUM_LOW_BITS));
++ offset = 0;
++ num_bits = LZMA_LEN_NUM_LOW_BITS;
++ } else {
++ rc_update_bit_1(rc, prob_len);
++ prob_len = prob + LZMA_LEN_CHOICE_2;
++ if (rc_is_bit_0(rc, prob_len)) {
++ rc_update_bit_0(rc, prob_len);
++ prob_len = (prob + LZMA_LEN_MID
++ + (pos_state <<
++ LZMA_LEN_NUM_MID_BITS));
++ offset = 1 << LZMA_LEN_NUM_LOW_BITS;
++ num_bits = LZMA_LEN_NUM_MID_BITS;
++ } else {
++ rc_update_bit_1(rc, prob_len);
++ prob_len = prob + LZMA_LEN_HIGH;
++ offset = ((1 << LZMA_LEN_NUM_LOW_BITS)
++ + (1 << LZMA_LEN_NUM_MID_BITS));
++ num_bits = LZMA_LEN_NUM_HIGH_BITS;
++ }
++ }
++
++ rc_bit_tree_decode(rc, prob_len, num_bits, &len);
++ len += offset;
++
++ if (cst->state < 4) {
++ int pos_slot;
++
++ cst->state += LZMA_NUM_LIT_STATES;
++ prob =
++ p + LZMA_POS_SLOT +
++ ((len <
++ LZMA_NUM_LEN_TO_POS_STATES ? len :
++ LZMA_NUM_LEN_TO_POS_STATES - 1)
++ << LZMA_NUM_POS_SLOT_BITS);
++ rc_bit_tree_decode(rc, prob,
++ LZMA_NUM_POS_SLOT_BITS,
++ &pos_slot);
++ if (pos_slot >= LZMA_START_POS_MODEL_INDEX) {
++ int i, mi;
++ num_bits = (pos_slot >> 1) - 1;
++ cst->rep0 = 2 | (pos_slot & 1);
++ if (pos_slot < LZMA_END_POS_MODEL_INDEX) {
++ cst->rep0 <<= num_bits;
++ prob = p + LZMA_SPEC_POS +
++ cst->rep0 - pos_slot - 1;
++ } else {
++ num_bits -= LZMA_NUM_ALIGN_BITS;
++ while (num_bits--)
++ cst->rep0 = (cst->rep0 << 1) |
++ rc_direct_bit(rc);
++ prob = p + LZMA_ALIGN;
++ cst->rep0 <<= LZMA_NUM_ALIGN_BITS;
++ num_bits = LZMA_NUM_ALIGN_BITS;
++ }
++ i = 1;
++ mi = 1;
++ while (num_bits--) {
++ if (rc_get_bit(rc, prob + mi, &mi))
++ cst->rep0 |= i;
++ i <<= 1;
++ }
++ } else
++ cst->rep0 = pos_slot;
++ if (++(cst->rep0) == 0)
++ return;
++ }
++
++ len += LZMA_MATCH_MIN_LEN;
++
++ copy_bytes(wr, cst->rep0, len);
++}
++
++
++
++STATIC inline int INIT unlzma(unsigned char *buf, int in_len,
++ int(*fill)(void*, unsigned int),
++ int(*flush)(void*, unsigned int),
++ unsigned char *output,
++ int *posp,
++ void(*error_fn)(char *x)
++ )
++{
++ struct lzma_header header;
++ int lc, pb, lp;
++ uint32_t pos_state_mask;
++ uint32_t literal_pos_mask;
++ uint16_t *p;
++ int num_probs;
++ struct rc rc;
++ int i, mi;
++ struct writer wr;
++ struct cstate cst;
++ unsigned char *inbuf;
++ int ret = -1;
++
++ set_error_fn(error_fn);
++ if (!flush)
++ in_len -= 4; /* Uncompressed size hack active in pre-boot
++ environment */
++ if (buf)
++ inbuf = buf;
++ else
++ inbuf = malloc(LZMA_IOBUF_SIZE);
++ if (!inbuf) {
++ error("Could not allocate input bufer");
++ goto exit_0;
++ }
++
++ cst.state = 0;
++ cst.rep0 = cst.rep1 = cst.rep2 = cst.rep3 = 1;
++
++ wr.header = &header;
++ wr.flush = flush;
++ wr.global_pos = 0;
++ wr.previous_byte = 0;
++ wr.buffer_pos = 0;
++
++ rc_init(&rc, fill, inbuf, in_len);
++
++ for (i = 0; i < sizeof(header); i++) {
++ if (rc.ptr >= rc.buffer_end)
++ rc_read(&rc);
++ ((unsigned char *)&header)[i] = *rc.ptr++;
++ }
++
++ if (header.pos >= (9 * 5 * 5))
++ error("bad header");
++
++ mi = 0;
++ lc = header.pos;
++ while (lc >= 9) {
++ mi++;
++ lc -= 9;
++ }
++ pb = 0;
++ lp = mi;
++ while (lp >= 5) {
++ pb++;
++ lp -= 5;
++ }
++ pos_state_mask = (1 << pb) - 1;
++ literal_pos_mask = (1 << lp) - 1;
++
++ ENDIAN_CONVERT(header.dict_size);
++ ENDIAN_CONVERT(header.dst_size);
++
++ if (header.dict_size == 0)
++ header.dict_size = 1;
++
++ if (output)
++ wr.buffer = output;
++ else {
++ wr.bufsize = MIN(header.dst_size, header.dict_size);
++ wr.buffer = large_malloc(wr.bufsize);
++ }
++ if (wr.buffer == NULL)
++ goto exit_1;
++
++ num_probs = LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp));
++ p = (uint16_t *) large_malloc(num_probs * sizeof(*p));
++ if (p == 0)
++ goto exit_2;
++ num_probs = LZMA_LITERAL + (LZMA_LIT_SIZE << (lc + lp));
++ for (i = 0; i < num_probs; i++)
++ p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1;
++
++ rc_init_code(&rc);
++
++ while (get_pos(&wr) < header.dst_size) {
++ int pos_state = get_pos(&wr) & pos_state_mask;
++ uint16_t *prob = p + LZMA_IS_MATCH +
++ (cst.state << LZMA_NUM_POS_BITS_MAX) + pos_state;
++ if (rc_is_bit_0(&rc, prob))
++ process_bit0(&wr, &rc, &cst, p, pos_state, prob,
++ lc, literal_pos_mask);
++ else {
++ process_bit1(&wr, &rc, &cst, p, pos_state, prob);
++ if (cst.rep0 == 0)
++ break;
++ }
++ }
++
++ if (posp)
++ *posp = rc.ptr-rc.buffer;
++ if (wr.flush)
++ wr.flush(wr.buffer, wr.buffer_pos);
++ ret = 0;
++ large_free(p);
++exit_2:
++ if (!output)
++ large_free(wr.buffer);
++exit_1:
++ if (!buf)
++ free(inbuf);
++exit_0:
++ return ret;
++}
++
++#define decompress unlzma
+diff --git a/lib/zlib_inflate/inflate.h
+index df8a6c9..3d17b3d 100644
+--- a/lib/zlib_inflate/inflate.h
++++ b/lib/zlib_inflate/inflate.h
+@@ -1,3 +1,6 @@
++#ifndef INFLATE_H
++#define INFLATE_H
++
+ /* inflate.h -- internal inflate state definition
+ * Copyright (C) 1995-2004 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+@@ -105,3 +108,4 @@ struct inflate_state {
+ unsigned short work[288]; /* work area for code table building */
+ code codes[ENOUGH]; /* space for code tables */
+ };
++#endif
+diff --git a/lib/zlib_inflate/inftrees.h
+index 5f5219b..b70b473 100644
+--- a/lib/zlib_inflate/inftrees.h
++++ b/lib/zlib_inflate/inftrees.h
+@@ -1,3 +1,6 @@
++#ifndef INFTREES_H
++#define INFTREES_H
++
+ /* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+@@ -53,3 +56,4 @@ typedef enum {
+ extern int zlib_inflate_table (codetype type, unsigned short *lens,
+ unsigned codes, code **table,
+ unsigned *bits, unsigned short *work);
++#endif
+diff --git a/scripts/Makefile.lib
+index b4ca38a..6f6802d 100644
+--- a/scripts/Makefile.lib
++++ b/scripts/Makefile.lib
+@@ -183,3 +183,17 @@ quiet_cmd_gzip = GZIP $@
+ cmd_gzip = gzip -f -9 < $< > $@
+
+
++# Bzip2
++# ---------------------------------------------------------------------------
++
++# Bzip2 does not include size in file... so we have to fake that
++size_append=$(CONFIG_SHELL) $(srctree)/scripts/bin_size
++
++quiet_cmd_bzip2 = BZIP2 $@
++cmd_bzip2 = (bzip2 -9 < $< ; $(size_append) $<) > $@ || (rm -f $@ ; false)
++
++# Lzma
++# ---------------------------------------------------------------------------
++
++quiet_cmd_lzma = LZMA $@
++cmd_lzma = (lzma -9 -c $< ; $(size_append) $<) >$@ || (rm -f $@ ; false)
+diff --git a/scripts/bin_size
+new file mode 100644
+index 0000000..43e1b36
+--- /dev/null
++++ b/scripts/bin_size
+@@ -0,0 +1,10 @@
++#!/bin/sh
++
++if [ $# = 0 ] ; then
++ echo Usage: $0 file
++fi
++
++size_dec=`stat -c "%s" $1`
++size_hex_echo_string=`printf "%08x" $size_dec |
++ sed 's/\(..\)\(..\)\(..\)\(..\)/\\\\x\4\\\\x\3\\\\x\2\\\\x\1/g'`
++/bin/echo -ne $size_hex_echo_string
+--
+1.8.1
+
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0002-bzip2-lzma-config-and-initramfs-support-for-bzip2-lz.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0002-bzip2-lzma-config-and-initramfs-support-for-bzip2-lz.patch
new file mode 100644
index 0000000..1fca71b
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0002-bzip2-lzma-config-and-initramfs-support-for-bzip2-lz.patch
@@ -0,0 +1,585 @@
+From 46b4296ca3e989127c8646e5c115561f9a2f8fa3 Mon Sep 17 00:00:00 2001
+From: Alain Knaff <alain@knaff.lu>
+Date: Sun, 4 Jan 2009 22:46:17 +0100
+Subject: bzip2/lzma: config and initramfs support for bzip2/lzma decompression
+
+Impact: New code for initramfs decompression, new features
+
+This is the second part of the bzip2/lzma patch
+
+The bzip patch is based on an idea by Christian Ludwig, includes support for
+compressing the kernel with bzip2 or lzma rather than gzip. Both
+compressors give smaller sizes than gzip. Lzma's decompresses faster
+than bzip2.
+
+It also supports ramdisks and initramfs' compressed using these two
+compressors.
+
+The functionality has been successfully used for a couple of years by
+the udpcast project
+
+This version applies to "tip" kernel 2.6.28
+
+This part contains:
+- support for new compressions (bzip2 and lzma) in initramfs and
+old-style ramdisk
+- config dialog for kernel compression (but new kernel compressions
+not yet supported)
+
+Signed-off-by: Alain Knaff <alain@knaff.lu>
+Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+---
+ .../linux-aspeed-2.6.28.9/drivers/block/Kconfig | 25 +++
+ .../linux/files/linux-aspeed-2.6.28.9/init/Kconfig | 50 ++++++
+ .../linux-aspeed-2.6.28.9/init/do_mounts_rd.c | 182 ++++++++-------------
+ .../files/linux-aspeed-2.6.28.9/init/initramfs.c | 123 +++++---------
+ .../linux/files/linux-aspeed-2.6.28.9/lib/Makefile | 3 +-
+ 5 files changed, 184 insertions(+), 199 deletions(-)
+
+diff --git a/drivers/block/Kconfig
+index 0344a8a..7955944 100644
+--- a/drivers/block/Kconfig
++++ b/drivers/block/Kconfig
+@@ -358,6 +358,31 @@ config BLK_DEV_XIP
+ will prevent RAM block device backing store memory from being
+ allocated from highmem (only a problem for highmem systems).
+
++config RD_BZIP2
++ bool "Initial ramdisk compressed using bzip2"
++ default n
++ depends on BLK_DEV_INITRD=y
++ help
++ Support loading of a bzip2 encoded initial ramdisk or cpio buffer
++ If unsure, say N.
++
++config RD_LZMA
++ bool "Initial ramdisk compressed using lzma"
++ default n
++ depends on BLK_DEV_INITRD=y
++ help
++ Support loading of a lzma encoded initial ramdisk or cpio buffer
++ If unsure, say N.
++
++config RD_GZIP
++ bool "Initial ramdisk compressed using gzip"
++ default y
++ depends on BLK_DEV_INITRD=y
++ select ZLIB_INFLATE
++ help
++ Support loading of a gzip encoded initial ramdisk or cpio buffer.
++ If unsure, say Y.
++
+ config CDROM_PKTCDVD
+ tristate "Packet writing on CD/DVD media"
+ depends on !UML
+diff --git a/init/Kconfig
+index 83b6905..d7f95fe 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -101,6 +101,56 @@ config LOCALVERSION_AUTO
+
+ which is done within the script "scripts/setlocalversion".)
+
++choice
++ prompt "Kernel compression mode"
++ default KERNEL_GZIP
++ help
++ The linux kernel is a kind of self-extracting executable.
++ Several compression algorithms are available, which differ
++ in efficiency, compression and decompression speed.
++ Compression speed is only relevant when building a kernel.
++ Decompression speed is relevant at each boot.
++
++ If you have any problems with bzip2 or lzma compressed
++ kernels, mail me (Alain Knaff) <alain@knaff.lu>. (An older
++ version of this functionality (bzip2 only), for 2.4, was
++ supplied by Christian Ludwig)
++
++ High compression options are mostly useful for users, who
++ are low on disk space (embedded systems), but for whom ram
++ size matters less.
++
++ If in doubt, select 'gzip'
++
++config KERNEL_GZIP
++ bool "Gzip"
++ help
++ The old and tried gzip compression. Its compression ratio is
++ the poorest among the 3 choices; however its speed (both
++ compression and decompression) is the fastest.
++
++config KERNEL_BZIP2
++ bool "Bzip2"
++ help
++ Its compression ratio and speed is intermediate.
++ Decompression speed is slowest among the 3.
++ The kernel size is about 10 per cent smaller with bzip2,
++ in comparison to gzip.
++ Bzip2 uses a large amount of memory. For modern kernels
++ you will need at least 8MB RAM or more for booting.
++
++config KERNEL_LZMA
++ bool "LZMA"
++ help
++ The most recent compression algorithm.
++ Its ratio is best, decompression speed is between the other
++ 2. Compression is slowest.
++ The kernel size is about 33 per cent smaller with lzma,
++ in comparison to gzip.
++
++endchoice
++
++
+ config SWAP
+ bool "Support for paging of anonymous memory (swap)"
+ depends on MMU && BLOCK
+diff --git a/init/do_mounts_rd.c
+index a7c748f..dcaeb1f 100644
+--- a/init/do_mounts_rd.c
++++ b/init/do_mounts_rd.c
+@@ -10,6 +10,12 @@
+
+ #include "do_mounts.h"
+
++#include <linux/decompress/generic.h>
++
++#include <linux/decompress/bunzip2.h>
++#include <linux/decompress/unlzma.h>
++#include <linux/decompress/inflate.h>
++
+ int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */
+
+ static int __init prompt_ramdisk(char *str)
+@@ -28,7 +34,7 @@ static int __init ramdisk_start_setup(char *str)
+ }
+ __setup("ramdisk_start=", ramdisk_start_setup);
+
+-static int __init crd_load(int in_fd, int out_fd);
++static int __init crd_load(int in_fd, int out_fd, decompress_fn deco);
+
+ /*
+ * This routine tries to find a RAM disk image to load, and returns the
+@@ -44,7 +50,7 @@ static int __init crd_load(int in_fd, int out_fd);
+ * gzip
+ */
+ static int __init
+-identify_ramdisk_image(int fd, int start_block)
++identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor)
+ {
+ const int size = 512;
+ struct minix_super_block *minixsb;
+@@ -70,6 +76,7 @@ identify_ramdisk_image(int fd, int start_block)
+ sys_lseek(fd, start_block * BLOCK_SIZE, 0);
+ sys_read(fd, buf, size);
+
++#ifdef CONFIG_RD_GZIP
+ /*
+ * If it matches the gzip magic numbers, return 0
+ */
+@@ -77,9 +84,39 @@ identify_ramdisk_image(int fd, int start_block)
+ printk(KERN_NOTICE
+ "RAMDISK: Compressed image found at block %d\n",
+ start_block);
++ *decompressor = gunzip;
++ nblocks = 0;
++ goto done;
++ }
++#endif
++
++#ifdef CONFIG_RD_BZIP2
++ /*
++ * If it matches the bzip2 magic numbers, return -1
++ */
++ if (buf[0] == 0x42 && (buf[1] == 0x5a)) {
++ printk(KERN_NOTICE
++ "RAMDISK: Bzipped image found at block %d\n",
++ start_block);
++ *decompressor = bunzip2;
++ nblocks = 0;
++ goto done;
++ }
++#endif
++
++#ifdef CONFIG_RD_LZMA
++ /*
++ * If it matches the lzma magic numbers, return -1
++ */
++ if (buf[0] == 0x5d && (buf[1] == 0x00)) {
++ printk(KERN_NOTICE
++ "RAMDISK: Lzma image found at block %d\n",
++ start_block);
++ *decompressor = unlzma;
+ nblocks = 0;
+ goto done;
+ }
++#endif
+
+ /* romfs is at block zero too */
+ if (romfsb->word0 == ROMSB_WORD0 &&
+@@ -143,6 +180,7 @@ int __init rd_load_image(char *from)
+ int nblocks, i, disk;
+ char *buf = NULL;
+ unsigned short rotate = 0;
++ decompress_fn decompressor = NULL;
+ #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES)
+ char rotator[4] = { '|' , '/' , '-' , '\\' };
+ #endif
+@@ -155,12 +193,12 @@ int __init rd_load_image(char *from)
+ if (in_fd < 0)
+ goto noclose_input;
+
+- nblocks = identify_ramdisk_image(in_fd, rd_image_start);
++ nblocks = identify_ramdisk_image(in_fd, rd_image_start, &decompressor);
+ if (nblocks < 0)
+ goto done;
+
+ if (nblocks == 0) {
+- if (crd_load(in_fd, out_fd) == 0)
++ if (crd_load(in_fd, out_fd, decompressor) == 0)
+ goto successful_load;
+ goto done;
+ }
+@@ -259,138 +297,48 @@ int __init rd_load_disk(int n)
+ return rd_load_image("/dev/root");
+ }
+
+-/*
+- * gzip declarations
+- */
+-
+-#define OF(args) args
+-
+-#ifndef memzero
+-#define memzero(s, n) memset ((s), 0, (n))
+-#endif
+-
+-typedef unsigned char uch;
+-typedef unsigned short ush;
+-typedef unsigned long ulg;
+-
+-#define INBUFSIZ 4096
+-#define WSIZE 0x8000 /* window size--must be a power of two, and */
+- /* at least 32K for zip's deflate method */
+-
+-static uch *inbuf;
+-static uch *window;
+-
+-static unsigned insize; /* valid bytes in inbuf */
+-static unsigned inptr; /* index of next byte to be processed in inbuf */
+-static unsigned outcnt; /* bytes in output buffer */
+ static int exit_code;
+-static int unzip_error;
+-static long bytes_out;
++static int decompress_error;
+ static int crd_infd, crd_outfd;
+
+-#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
+-
+-/* Diagnostic functions (stubbed out) */
+-#define Assert(cond,msg)
+-#define Trace(x)
+-#define Tracev(x)
+-#define Tracevv(x)
+-#define Tracec(c,x)
+-#define Tracecv(c,x)
+-
+-#define STATIC static
+-#define INIT __init
+-
+-static int __init fill_inbuf(void);
+-static void __init flush_window(void);
+-static void __init error(char *m);
+-
+-#define NO_INFLATE_MALLOC
+-
+-#include "../lib/inflate.c"
+-
+-/* ===========================================================================
+- * Fill the input buffer. This is called only when the buffer is empty
+- * and at least one byte is really needed.
+- * Returning -1 does not guarantee that gunzip() will ever return.
+- */
+-static int __init fill_inbuf(void)
++static int __init compr_fill(void *buf, unsigned int len)
+ {
+- if (exit_code) return -1;
+-
+- insize = sys_read(crd_infd, inbuf, INBUFSIZ);
+- if (insize == 0) {
+- error("RAMDISK: ran out of compressed data");
+- return -1;
+- }
+-
+- inptr = 1;
+-
+- return inbuf[0];
++ int r = sys_read(crd_infd, buf, len);
++ if (r < 0)
++ printk(KERN_ERR "RAMDISK: error while reading compressed data");
++ else if (r == 0)
++ printk(KERN_ERR "RAMDISK: EOF while reading compressed data");
++ return r;
+ }
+
+-/* ===========================================================================
+- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+- * (Used for the decompressed data only.)
+- */
+-static void __init flush_window(void)
++static int __init compr_flush(void *window, unsigned int outcnt)
+ {
+- ulg c = crc; /* temporary variable */
+- unsigned n, written;
+- uch *in, ch;
+-
+- written = sys_write(crd_outfd, window, outcnt);
+- if (written != outcnt && unzip_error == 0) {
+- printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n",
+- written, outcnt, bytes_out);
+- unzip_error = 1;
+- }
+- in = window;
+- for (n = 0; n < outcnt; n++) {
+- ch = *in++;
+- c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+- }
+- crc = c;
+- bytes_out += (ulg)outcnt;
+- outcnt = 0;
++ int written = sys_write(crd_outfd, window, outcnt);
++ if (written != outcnt) {
++ if (decompress_error == 0)
++ printk(KERN_ERR
++ "RAMDISK: incomplete write (%d != %d)\n",
++ written, outcnt);
++ decompress_error = 1;
++ return -1;
++ }
++ return outcnt;
+ }
+
+ static void __init error(char *x)
+ {
+ printk(KERN_ERR "%s\n", x);
+ exit_code = 1;
+- unzip_error = 1;
++ decompress_error = 1;
+ }
+
+-static int __init crd_load(int in_fd, int out_fd)
++static int __init crd_load(int in_fd, int out_fd, decompress_fn deco)
+ {
+ int result;
+-
+- insize = 0; /* valid bytes in inbuf */
+- inptr = 0; /* index of next byte to be processed in inbuf */
+- outcnt = 0; /* bytes in output buffer */
+- exit_code = 0;
+- bytes_out = 0;
+- crc = (ulg)0xffffffffL; /* shift register contents */
+-
+ crd_infd = in_fd;
+ crd_outfd = out_fd;
+- inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
+- if (!inbuf) {
+- printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
+- return -1;
+- }
+- window = kmalloc(WSIZE, GFP_KERNEL);
+- if (!window) {
+- printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
+- kfree(inbuf);
+- return -1;
+- }
+- makecrc();
+- result = gunzip();
+- if (unzip_error)
++ result = deco(NULL, 0, compr_fill, compr_flush, NULL, NULL, error);
++ if (decompress_error)
+ result = 1;
+- kfree(inbuf);
+- kfree(window);
+ return result;
+ }
+diff --git a/init/initramfs.c
+index 4f5ba75..40bd4fb 100644
+--- a/init/initramfs.c
++++ b/init/initramfs.c
+@@ -389,11 +389,14 @@ static int __init write_buffer(char *buf, unsigned len)
+ return len - count;
+ }
+
+-static void __init flush_buffer(char *buf, unsigned len)
++
++static int __init flush_buffer(void *bufv, unsigned len)
+ {
++ char *buf = (char *) bufv;
+ int written;
++ int origLen = len;
+ if (message)
+- return;
++ return -1;
+ while ((written = write_buffer(buf, len)) < len && !message) {
+ char c = buf[written];
+ if (c == '0') {
+@@ -407,73 +410,14 @@ static void __init flush_buffer(char *buf, unsigned len)
+ } else
+ error("junk in compressed archive");
+ }
++ return origLen;
+ }
+
+-/*
+- * gzip declarations
+- */
+-
+-#define OF(args) args
+-
+-#ifndef memzero
+-#define memzero(s, n) memset ((s), 0, (n))
+-#endif
+-
+-typedef unsigned char uch;
+-typedef unsigned short ush;
+-typedef unsigned long ulg;
+-
+-#define WSIZE 0x8000 /* window size--must be a power of two, and */
+- /* at least 32K for zip's deflate method */
+-
+-static uch *inbuf;
+-static uch *window;
+-
+-static unsigned insize; /* valid bytes in inbuf */
+-static unsigned inptr; /* index of next byte to be processed in inbuf */
+-static unsigned outcnt; /* bytes in output buffer */
+-static long bytes_out;
+-
+-#define get_byte() (inptr < insize ? inbuf[inptr++] : -1)
+-
+-/* Diagnostic functions (stubbed out) */
+-#define Assert(cond,msg)
+-#define Trace(x)
+-#define Tracev(x)
+-#define Tracevv(x)
+-#define Tracec(c,x)
+-#define Tracecv(c,x)
+-
+-#define STATIC static
+-#define INIT __init
+-
+-static void __init flush_window(void);
+-static void __init error(char *m);
+-
+-#define NO_INFLATE_MALLOC
++static unsigned my_inptr; /* index of next byte to be processed in inbuf */
+
+-#include "../lib/inflate.c"
+-
+-/* ===========================================================================
+- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+- * (Used for the decompressed data only.)
+- */
+-static void __init flush_window(void)
+-{
+- ulg c = crc; /* temporary variable */
+- unsigned n;
+- uch *in, ch;
+-
+- flush_buffer(window, outcnt);
+- in = window;
+- for (n = 0; n < outcnt; n++) {
+- ch = *in++;
+- c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+- }
+- crc = c;
+- bytes_out += (ulg)outcnt;
+- outcnt = 0;
+-}
++#include <linux/decompress/bunzip2.h>
++#include <linux/decompress/unlzma.h>
++#include <linux/decompress/inflate.h>
+
+ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
+ {
+@@ -482,9 +426,10 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
+ header_buf = kmalloc(110, GFP_KERNEL);
+ symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
+ name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL);
+- window = kmalloc(WSIZE, GFP_KERNEL);
+- if (!window || !header_buf || !symlink_buf || !name_buf)
++
++ if (!header_buf || !symlink_buf || !name_buf)
+ panic("can't allocate buffers");
++
+ state = Start;
+ this_header = 0;
+ message = NULL;
+@@ -504,22 +449,38 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
+ continue;
+ }
+ this_header = 0;
+- insize = len;
+- inbuf = buf;
+- inptr = 0;
+- outcnt = 0; /* bytes in output buffer */
+- bytes_out = 0;
+- crc = (ulg)0xffffffffL; /* shift register contents */
+- makecrc();
+- gunzip();
++ if (!gunzip(buf, len, NULL, flush_buffer, NULL,
++ &my_inptr, error) &&
++ message == NULL)
++ goto ok;
++
++#ifdef CONFIG_RD_BZIP2
++ message = NULL; /* Zero out message, or else cpio will
++ think an error has already occured */
++ if (!bunzip2(buf, len, NULL, flush_buffer, NULL,
++ &my_inptr, error) &&
++ message == NULL) {
++ goto ok;
++ }
++#endif
++
++#ifdef CONFIG_RD_LZMA
++ message = NULL; /* Zero out message, or else cpio will
++ think an error has already occured */
++ if (!unlzma(buf, len, NULL, flush_buffer, NULL,
++ &my_inptr, error) &&
++ message == NULL) {
++ goto ok;
++ }
++#endif
++ok:
+ if (state != Reset)
+- error("junk in gzipped archive");
+- this_header = saved_offset + inptr;
+- buf += inptr;
+- len -= inptr;
++ error("junk in compressed archive");
++ this_header = saved_offset + my_inptr;
++ buf += my_inptr;
++ len -= my_inptr;
+ }
+ dir_utime();
+- kfree(window);
+ kfree(name_buf);
+ kfree(symlink_buf);
+ kfree(header_buf);
+diff --git a/lib/Makefile
+index 7cb65d8..867fd9e 100644
+--- a/lib/Makefile
++++ b/lib/Makefile
+@@ -11,7 +11,8 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
+ rbtree.o radix-tree.o dump_stack.o \
+ idr.o int_sqrt.o extable.o prio_tree.o \
+ sha1.o irq_regs.o reciprocal_div.o argv_split.o \
+- proportions.o prio_heap.o ratelimit.o show_mem.o
++ proportions.o prio_heap.o ratelimit.o show_mem.o \
++ decompress_inflate.o decompress_bunzip2.o decompress_unlzma.o
+
+ lib-$(CONFIG_MMU) += ioremap.o
+ lib-$(CONFIG_SMP) += cpumask.o
+--
+1.8.1
+
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0005-mtd-Bug-in-m25p80.c-during-whole-chip-erase.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0005-mtd-Bug-in-m25p80.c-during-whole-chip-erase.patch
new file mode 100644
index 0000000..e8dd925
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0005-mtd-Bug-in-m25p80.c-during-whole-chip-erase.patch
@@ -0,0 +1,53 @@
+From 3f33b0aaac4e208579fe5aa2964857d4e9ba10c5 Mon Sep 17 00:00:00 2001
+From: "Steven A. Falco" <sfalco@harris.com>
+Date: Mon, 27 Apr 2009 17:10:10 -0400
+Subject: [PATCH 05/16] mtd: Bug in m25p80.c during whole-chip erase
+
+There is a logic error in "whole chip erase" for the m25p80 family. If
+the whole device is successfully erased, erase_chip() will return 0, and
+the code will fall through to the "else" clause, and do sector-by-sector
+erase in addition to the whole-chip erase. This patch corrects that.
+
+Also, the MAX_READY_WAIT_COUNT is insufficient for an m25p16 connected
+to a 400 MHz powerpc. Increasing it allows me to successfully program
+the device on my board.
+
+Signed-off-by: Steven A. Falco <sfalco@harris.com>
+Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
+---
+ drivers/mtd/devices/m25p80.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
+index 8185b1f..dfadef8 100644
+--- a/drivers/mtd/devices/m25p80.c
++++ b/drivers/mtd/devices/m25p80.c
+@@ -54,7 +54,7 @@
+ #define SR_SRWD 0x80 /* SR write protect */
+
+ /* Define max times to check status register before we give up. */
+-#define MAX_READY_WAIT_COUNT 100000
++#define MAX_READY_WAIT_COUNT 1000000
+ #define CMD_SIZE 4
+
+ #ifdef CONFIG_M25PXX_USE_FAST_READ
+@@ -246,10 +246,12 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
+ mutex_lock(&flash->lock);
+
+ /* whole-chip erase? */
+- if (len == flash->mtd.size && erase_chip(flash)) {
+- instr->state = MTD_ERASE_FAILED;
+- mutex_unlock(&flash->lock);
+- return -EIO;
++ if (len == flash->mtd.size) {
++ if (erase_chip(flash)) {
++ instr->state = MTD_ERASE_FAILED;
++ mutex_unlock(&flash->lock);
++ return -EIO;
++ }
+
+ /* REVISIT in some cases we could speed up erasing large regions
+ * by using OPCODE_SE instead of OPCODE_BE_4K. We may have set up
+--
+1.8.1
+
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0006-mtd-fix-timeout-in-M25P80-driver.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0006-mtd-fix-timeout-in-M25P80-driver.patch
new file mode 100644
index 0000000..2bfd226
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0006-mtd-fix-timeout-in-M25P80-driver.patch
@@ -0,0 +1,63 @@
+From cd1a6de7d4a492bf3405a6c070075a4cb8c90262 Mon Sep 17 00:00:00 2001
+From: Peter Horton <zero@colonel-panic.org>
+Date: Fri, 8 May 2009 13:51:53 +0100
+Subject: [PATCH 06/16] mtd: fix timeout in M25P80 driver
+
+Extend erase timeout in M25P80 SPI Flash driver.
+
+The M25P80 drivers fails erasing sectors on a M25P128 because the ready
+wait timeout is too short. Change the timeout from a simple loop count to a
+suitable number of seconds.
+
+Signed-off-by: Peter Horton <zero@colonel-panic.org>
+Tested-by: Martin Michlmayr <tbm@cyrius.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
+---
+ drivers/mtd/devices/m25p80.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
+index dfadef8..cc6369e 100644
+--- a/drivers/mtd/devices/m25p80.c
++++ b/drivers/mtd/devices/m25p80.c
+@@ -54,7 +54,7 @@
+ #define SR_SRWD 0x80 /* SR write protect */
+
+ /* Define max times to check status register before we give up. */
+-#define MAX_READY_WAIT_COUNT 1000000
++#define MAX_READY_WAIT_JIFFIES (10 * HZ) /* eg. M25P128 specs 6s max sector erase */
+ #define CMD_SIZE 4
+
+ #ifdef CONFIG_M25PXX_USE_FAST_READ
+@@ -139,20 +139,20 @@ static inline int write_enable(struct m25p *flash)
+ */
+ static int wait_till_ready(struct m25p *flash)
+ {
+- int count;
++ unsigned long deadline;
+ int sr;
+
+- /* one chip guarantees max 5 msec wait here after page writes,
+- * but potentially three seconds (!) after page erase.
+- */
+- for (count = 0; count < MAX_READY_WAIT_COUNT; count++) {
++ deadline = jiffies + MAX_READY_WAIT_JIFFIES;
++
++ do {
+ if ((sr = read_sr(flash)) < 0)
+ break;
+ else if (!(sr & SR_WIP))
+ return 0;
+
+- /* REVISIT sometimes sleeping would be best */
+- }
++ cond_resched();
++
++ } while (!time_after_eq(jiffies, deadline));
+
+ return 1;
+ }
+--
+1.8.1
+
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0009-mtd-m25p80-timeout-too-short-for-worst-case-m25p16-d.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0009-mtd-m25p80-timeout-too-short-for-worst-case-m25p16-d.patch
new file mode 100644
index 0000000..809f839
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0009-mtd-m25p80-timeout-too-short-for-worst-case-m25p16-d.patch
@@ -0,0 +1,31 @@
+From 89bb871e96cdc3d78b7f69f0bacc94b21bbaccfd Mon Sep 17 00:00:00 2001
+From: "Steven A. Falco" <sfalco@harris.com>
+Date: Fri, 26 Jun 2009 12:42:47 -0400
+Subject: [PATCH 09/16] mtd: m25p80 timeout too short for worst-case m25p16
+ devices
+
+The m25p16 data sheet from numonyx lists the worst-case bulk erase time
+(tBE) as 40 seconds.
+
+Signed-off-by: Steven A. Falco <sfalco@harris.com>
+Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
+---
+ drivers/mtd/devices/m25p80.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
+index 59c4612..ae5fe91 100644
+--- a/drivers/mtd/devices/m25p80.c
++++ b/drivers/mtd/devices/m25p80.c
+@@ -54,7 +54,7 @@
+ #define SR_SRWD 0x80 /* SR write protect */
+
+ /* Define max times to check status register before we give up. */
+-#define MAX_READY_WAIT_JIFFIES (10 * HZ) /* eg. M25P128 specs 6s max sector erase */
++#define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */
+ #define CMD_SIZE 4
+
+ #ifdef CONFIG_M25PXX_USE_FAST_READ
+--
+1.8.1
+
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0010-mtd-m25p80-fix-null-pointer-dereference-bug.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0010-mtd-m25p80-fix-null-pointer-dereference-bug.patch
new file mode 100644
index 0000000..7727636
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0010-mtd-m25p80-fix-null-pointer-dereference-bug.patch
@@ -0,0 +1,56 @@
+From edcb3b14863e1a6aa1923eeaa81125a00cf51a80 Mon Sep 17 00:00:00 2001
+From: Anton Vorontsov <avorontsov@ru.mvista.com>
+Date: Thu, 6 Aug 2009 15:18:37 -0700
+Subject: [PATCH 10/16] mtd: m25p80: fix null pointer dereference bug
+
+This patch fixes the following oops, observed with MTD_PARTITIONS=n:
+
+m25p80 spi32766.0: m25p80 (1024 Kbytes)
+Unable to handle kernel paging request for data at address 0x00000008
+Faulting instruction address: 0xc03a54b0
+Oops: Kernel access of bad area, sig: 11 [#1]
+Modules linked in:
+NIP: c03a54b0 LR: c03a5494 CTR: c01e98b8
+REGS: ef82bb60 TRAP: 0300 Not tainted (2.6.31-rc4-00167-g4733fd3)
+MSR: 00029000 <EE,ME,CE> CR: 24022022 XER: 20000000
+DEAR: 00000008, ESR: 00000000
+TASK = ef82c000[1] 'swapper' THREAD: ef82a000
+GPR00: 00000000 ef82bc10 ef82c000 0000002e 00001eb8 ffffffff c01e9824 00000036
+GPR08: c054ed40 c0542a08 00001eb8 00004000 22022022 1001a1a0 3ff8fd00 00000000
+GPR16: 00000000 00000001 00000000 00000000 ef82bddc c0530000 efbef500 ef8356d0
+GPR24: 00000000 ef8356d0 00000000 efbf7a00 c0530ec4 ffffffed efbf5300 c0541f98
+NIP [c03a54b0] m25p_probe+0x22c/0x354
+LR [c03a5494] m25p_probe+0x210/0x354
+Call Trace:
+[ef82bc10] [c03a5494] m25p_probe+0x210/0x354 (unreliable)
+[ef82bca0] [c024e37c] spi_drv_probe+0x2c/0x3c
+[ef82bcb0] [c01f1afc] driver_probe_device+0xa4/0x178
+[ef82bcd0] [c01f06e8] bus_for_each_drv+0x6c/0xa8
+[ef82bd00] [c01f1a34] device_attach+0x84/0xa8
+...
+
+Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
+Cc: David Brownell <david-b@pacbell.net>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
+Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
+---
+ drivers/mtd/devices/m25p80.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
+index ae5fe91..10ed195 100644
+--- a/drivers/mtd/devices/m25p80.c
++++ b/drivers/mtd/devices/m25p80.c
+@@ -736,7 +736,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
+ flash->partitioned = 1;
+ return add_mtd_partitions(&flash->mtd, parts, nr_parts);
+ }
+- } else if (data->nr_parts)
++ } else if (data && data->nr_parts)
+ dev_warn(&spi->dev, "ignoring %d default partitions on %s\n",
+ data->nr_parts, data->name);
+
+--
+1.8.1
+
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0012-mtd-m25p80-add-support-for-AAI-programming-with-SST-.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0012-mtd-m25p80-add-support-for-AAI-programming-with-SST-.patch
new file mode 100644
index 0000000..e726dc7
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0012-mtd-m25p80-add-support-for-AAI-programming-with-SST-.patch
@@ -0,0 +1,179 @@
+From 49aac4aec53c523f16343b4668a5a239b69659f1 Mon Sep 17 00:00:00 2001
+From: Graf Yang <graf.yang@analog.com>
+Date: Mon, 15 Jun 2009 08:23:41 +0000
+Subject: [PATCH 012/130] mtd: m25p80: add support for AAI programming with SST
+ SPI flashes
+
+The SST SPI flashes are a bit non-standard in that they can be programmed
+one byte at a time (including address!), or they can be written two bytes
+at a time with auto address incrementing (AAI). The latter form is
+obviously much better for performance, so let's use it when possible.
+
+Signed-off-by: Graf Yang <graf.yang@analog.com>
+Signed-off-by: Mike Frysinger <vapier@gentoo.org>
+Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
+---
+ drivers/mtd/devices/m25p80.c | 126 ++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 125 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
+index 6d8d265..53de9f0 100644
+--- a/drivers/mtd/devices/m25p80.c
++++ b/drivers/mtd/devices/m25p80.c
+@@ -44,6 +44,11 @@
+ #define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */
+ #define OPCODE_RDID 0x9f /* Read JEDEC ID */
+
++/* Used for SST flashes only. */
++#define OPCODE_BP 0x02 /* Byte program */
++#define OPCODE_WRDI 0x04 /* Write disable */
++#define OPCODE_AAI_WP 0xad /* Auto address increment word program */
++
+ /* Status Register bits. */
+ #define SR_WIP 1 /* Write in progress */
+ #define SR_WEL 2 /* Write enable latch */
+@@ -132,6 +137,15 @@ static inline int write_enable(struct m25p *flash)
+ return spi_write_then_read(flash->spi, &code, 1, NULL, 0);
+ }
+
++/*
++ * Send write disble instruction to the chip.
++ */
++static inline int write_disable(struct m25p *flash)
++{
++ u8 code = OPCODE_WRDI;
++
++ return spi_write_then_read(flash->spi, &code, 1, NULL, 0);
++}
+
+ /*
+ * Service routine to read status register until ready, or timeout occurs.
+@@ -454,6 +468,111 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
+ return 0;
+ }
+
++static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
++ size_t *retlen, const u_char *buf)
++{
++ struct m25p *flash = mtd_to_m25p(mtd);
++ struct spi_transfer t[2];
++ struct spi_message m;
++ size_t actual;
++ int cmd_sz, ret;
++
++ if (retlen)
++ *retlen = 0;
++
++ /* sanity checks */
++ if (!len)
++ return 0;
++
++ if (to + len > flash->mtd.size)
++ return -EINVAL;
++
++ spi_message_init(&m);
++ memset(t, 0, (sizeof t));
++
++ t[0].tx_buf = flash->command;
++ t[0].len = CMD_SIZE;
++ spi_message_add_tail(&t[0], &m);
++
++ t[1].tx_buf = buf;
++ spi_message_add_tail(&t[1], &m);
++
++ mutex_lock(&flash->lock);
++
++ /* Wait until finished previous write command. */
++ ret = wait_till_ready(flash);
++ if (ret)
++ goto time_out;
++
++ write_enable(flash);
++
++ actual = to % 2;
++ /* Start write from odd address. */
++ if (actual) {
++ flash->command[0] = OPCODE_BP;
++ flash->command[1] = to >> 16;
++ flash->command[2] = to >> 8;
++ flash->command[3] = to;
++
++ /* write one byte. */
++ t[1].len = 1;
++ spi_sync(flash->spi, &m);
++ ret = wait_till_ready(flash);
++ if (ret)
++ goto time_out;
++ *retlen += m.actual_length - CMD_SIZE;
++ }
++ to += actual;
++
++ flash->command[0] = OPCODE_AAI_WP;
++ flash->command[1] = to >> 16;
++ flash->command[2] = to >> 8;
++ flash->command[3] = to;
++
++ /* Write out most of the data here. */
++ cmd_sz = CMD_SIZE;
++ for (; actual < len - 1; actual += 2) {
++ t[0].len = cmd_sz;
++ /* write two bytes. */
++ t[1].len = 2;
++ t[1].tx_buf = buf + actual;
++
++ spi_sync(flash->spi, &m);
++ ret = wait_till_ready(flash);
++ if (ret)
++ goto time_out;
++ *retlen += m.actual_length - cmd_sz;
++ cmd_sz = 1;
++ to += 2;
++ }
++ write_disable(flash);
++ ret = wait_till_ready(flash);
++ if (ret)
++ goto time_out;
++
++ /* Write out trailing byte if it exists. */
++ if (actual != len) {
++ write_enable(flash);
++ flash->command[0] = OPCODE_BP;
++ flash->command[1] = to >> 16;
++ flash->command[2] = to >> 8;
++ flash->command[3] = to;
++ t[0].len = CMD_SIZE;
++ t[1].len = 1;
++ t[1].tx_buf = buf + actual;
++
++ spi_sync(flash->spi, &m);
++ ret = wait_till_ready(flash);
++ if (ret)
++ goto time_out;
++ *retlen += m.actual_length - CMD_SIZE;
++ write_disable(flash);
++ }
++
++time_out:
++ mutex_unlock(&flash->lock);
++ return ret;
++}
+
+ /****************************************************************************/
+
+@@ -670,7 +789,12 @@ static int __devinit m25p_probe(struct spi_device *spi)
+ flash->mtd.size = info->sector_size * info->n_sectors;
+ flash->mtd.erase = m25p80_erase;
+ flash->mtd.read = m25p80_read;
+- flash->mtd.write = m25p80_write;
++
++ /* sst flash chips use AAI word program */
++ if (info->jedec_id >> 16 == 0xbf)
++ flash->mtd.write = sst_write;
++ else
++ flash->mtd.write = m25p80_write;
+
+ /* prefer "small sector" erase if possible */
+ if (info->flags & SECT_4K) {
+--
+1.8.1
+
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0020-mtd-m25p80-make-command-buffer-DMA-safe.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0020-mtd-m25p80-make-command-buffer-DMA-safe.patch
new file mode 100644
index 0000000..d5be404
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0020-mtd-m25p80-make-command-buffer-DMA-safe.patch
@@ -0,0 +1,56 @@
+From ca811c5491b0447d917148156785330af2ec9abe Mon Sep 17 00:00:00 2001
+From: Johannes Stezenbach <js@sig21.net>
+Date: Wed, 28 Oct 2009 14:21:37 +0100
+Subject: [PATCH 20/27] mtd: m25p80: make command buffer DMA-safe
+
+spi_write() requires the buffer to be DMA-safe, kmalloc()
+it seperately to ensure this.
+
+Signed-off-by: Johannes Stezenbach <js@sig21.net>
+Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
+Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
+(cherry picked from commit 61c3506c2cabe58bcdfe438d1e57b62994db1616)
+---
+ drivers/mtd/devices/m25p80.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
+index f6b255c..7ca5ab1 100644
+--- a/drivers/mtd/devices/m25p80.c
++++ b/drivers/mtd/devices/m25p80.c
+@@ -84,7 +84,7 @@ struct m25p {
+ struct mtd_info mtd;
+ unsigned partitioned:1;
+ u8 erase_opcode;
+- u8 command[CMD_SIZE + FAST_READ_DUMMY_BYTE];
++ u8 *command;
+ };
+
+ static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
+@@ -762,6 +762,11 @@ static int __devinit m25p_probe(struct spi_device *spi)
+ flash = kzalloc(sizeof *flash, GFP_KERNEL);
+ if (!flash)
+ return -ENOMEM;
++ flash->command = kmalloc(CMD_SIZE + FAST_READ_DUMMY_BYTE, GFP_KERNEL);
++ if (!flash->command) {
++ kfree(flash);
++ return -ENOMEM;
++ }
+
+ flash->spi = spi;
+ mutex_init(&flash->lock);
+@@ -877,8 +882,10 @@ static int __devexit m25p_remove(struct spi_device *spi)
+ status = del_mtd_partitions(&flash->mtd);
+ else
+ status = del_mtd_device(&flash->mtd);
+- if (status == 0)
++ if (status == 0) {
++ kfree(flash->command);
+ kfree(flash);
++ }
+ return 0;
+ }
+
+--
+1.8.1
+
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0021-mtd-m25p80-Add-support-for-CAT25xxx-serial-EEPROMs.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0021-mtd-m25p80-Add-support-for-CAT25xxx-serial-EEPROMs.patch
new file mode 100644
index 0000000..6f9e7be
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0021-mtd-m25p80-Add-support-for-CAT25xxx-serial-EEPROMs.patch
@@ -0,0 +1,327 @@
+From c2de6ee8dd176f1f37f67169230d3e82c020eb6e Mon Sep 17 00:00:00 2001
+From: Anton Vorontsov <avorontsov@ru.mvista.com>
+Date: Mon, 12 Oct 2009 20:24:40 +0400
+Subject: [PATCH 21/27] mtd: m25p80: Add support for CAT25xxx serial EEPROMs
+
+CAT25 chips (as manufactured by On Semiconductor, previously Catalyst
+Semiconductor) are similar to the original M25Px0 chips, except:
+
+- Address width can vary (1-2 bytes, in contrast to 3 bytes in M25P
+ chips). So, implement convenient m25p_addr2cmd() and m25p_cmdsz()
+ calls, and place address width information into flash_info struct;
+
+- Page size can vary, therefore we shouldn't hardcode it, so get rid
+ of FLASH_PAGESIZE definition, and place the page size information
+ into flash_info struct;
+
+- CAT25 EEPROMs don't need to be erased, so add NO_ERASE flag, and
+ propagate it to the mtd subsystem.
+
+[dwmw2: Fix up for conflicts with DMA safety patch]
+Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
+Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
+(cherry picked from commit 837479d25e221ba616de2c734f58e1decd8cdb95)
+
+Conflicts:
+ drivers/mtd/devices/m25p80.c
+---
+ drivers/mtd/devices/m25p80.c | 124 +++++++++++++++++++++++++------------------
+ 1 file changed, 72 insertions(+), 52 deletions(-)
+
+diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
+index 7ca5ab1..4570bc3 100644
+--- a/drivers/mtd/devices/m25p80.c
++++ b/drivers/mtd/devices/m25p80.c
+@@ -28,9 +28,6 @@
+ #include <linux/spi/spi.h>
+ #include <linux/spi/flash.h>
+
+-
+-#define FLASH_PAGESIZE 256
+-
+ /* Flash opcodes. */
+ #define OPCODE_WREN 0x06 /* Write enable */
+ #define OPCODE_RDSR 0x05 /* Read status register */
+@@ -60,7 +57,7 @@
+
+ /* Define max times to check status register before we give up. */
+ #define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */
+-#define CMD_SIZE 4
++#define MAX_CMD_SIZE 4
+
+ #ifdef CONFIG_M25PXX_USE_FAST_READ
+ #define OPCODE_READ OPCODE_FAST_READ
+@@ -83,6 +80,8 @@ struct m25p {
+ struct mutex lock;
+ struct mtd_info mtd;
+ unsigned partitioned:1;
++ u16 page_size;
++ u16 addr_width;
+ u8 erase_opcode;
+ u8 *command;
+ };
+@@ -203,6 +202,19 @@ static int erase_chip(struct m25p *flash)
+ return 0;
+ }
+
++static void m25p_addr2cmd(struct m25p *flash, unsigned int addr, u8 *cmd)
++{
++ /* opcode is in cmd[0] */
++ cmd[1] = addr >> (flash->addr_width * 8 - 8);
++ cmd[2] = addr >> (flash->addr_width * 8 - 16);
++ cmd[3] = addr >> (flash->addr_width * 8 - 24);
++}
++
++static int m25p_cmdsz(struct m25p *flash)
++{
++ return 1 + flash->addr_width;
++}
++
+ /*
+ * Erase one sector of flash memory at offset ``offset'' which is any
+ * address within the sector which should be erased.
+@@ -224,11 +236,9 @@ static int erase_sector(struct m25p *flash, u32 offset)
+
+ /* Set up command buffer. */
+ flash->command[0] = flash->erase_opcode;
+- flash->command[1] = offset >> 16;
+- flash->command[2] = offset >> 8;
+- flash->command[3] = offset;
++ m25p_addr2cmd(flash, offset, flash->command);
+
+- spi_write(flash->spi, flash->command, CMD_SIZE);
++ spi_write(flash->spi, flash->command, m25p_cmdsz(flash));
+
+ return 0;
+ }
+@@ -330,7 +340,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
+ * Should add 1 byte DUMMY_BYTE.
+ */
+ t[0].tx_buf = flash->command;
+- t[0].len = CMD_SIZE + FAST_READ_DUMMY_BYTE;
++ t[0].len = m25p_cmdsz(flash) + FAST_READ_DUMMY_BYTE;
+ spi_message_add_tail(&t[0], &m);
+
+ t[1].rx_buf = buf;
+@@ -357,13 +367,11 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
+
+ /* Set up the write data buffer. */
+ flash->command[0] = OPCODE_READ;
+- flash->command[1] = from >> 16;
+- flash->command[2] = from >> 8;
+- flash->command[3] = from;
++ m25p_addr2cmd(flash, from, flash->command);
+
+ spi_sync(flash->spi, &m);
+
+- *retlen = m.actual_length - CMD_SIZE - FAST_READ_DUMMY_BYTE;
++ *retlen = m.actual_length - m25p_cmdsz(flash) - FAST_READ_DUMMY_BYTE;
+
+ mutex_unlock(&flash->lock);
+
+@@ -401,7 +409,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
+ memset(t, 0, (sizeof t));
+
+ t[0].tx_buf = flash->command;
+- t[0].len = CMD_SIZE;
++ t[0].len = m25p_cmdsz(flash);
+ spi_message_add_tail(&t[0], &m);
+
+ t[1].tx_buf = buf;
+@@ -419,41 +427,36 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
+
+ /* Set up the opcode in the write buffer. */
+ flash->command[0] = OPCODE_PP;
+- flash->command[1] = to >> 16;
+- flash->command[2] = to >> 8;
+- flash->command[3] = to;
++ m25p_addr2cmd(flash, to, flash->command);
+
+- /* what page do we start with? */
+- page_offset = to % FLASH_PAGESIZE;
++ page_offset = to & (flash->page_size - 1);
+
+ /* do all the bytes fit onto one page? */
+- if (page_offset + len <= FLASH_PAGESIZE) {
++ if (page_offset + len <= flash->page_size) {
+ t[1].len = len;
+
+ spi_sync(flash->spi, &m);
+
+- *retlen = m.actual_length - CMD_SIZE;
++ *retlen = m.actual_length - m25p_cmdsz(flash);
+ } else {
+ u32 i;
+
+ /* the size of data remaining on the first page */
+- page_size = FLASH_PAGESIZE - page_offset;
++ page_size = flash->page_size - page_offset;
+
+ t[1].len = page_size;
+ spi_sync(flash->spi, &m);
+
+- *retlen = m.actual_length - CMD_SIZE;
++ *retlen = m.actual_length - m25p_cmdsz(flash);
+
+- /* write everything in PAGESIZE chunks */
++ /* write everything in flash->page_size chunks */
+ for (i = page_size; i < len; i += page_size) {
+ page_size = len - i;
+- if (page_size > FLASH_PAGESIZE)
+- page_size = FLASH_PAGESIZE;
++ if (page_size > flash->page_size)
++ page_size = flash->page_size;
+
+ /* write the next page to flash */
+- flash->command[1] = (to + i) >> 16;
+- flash->command[2] = (to + i) >> 8;
+- flash->command[3] = (to + i);
++ m25p_addr2cmd(flash, to + i, flash->command);
+
+ t[1].tx_buf = buf + i;
+ t[1].len = page_size;
+@@ -465,7 +468,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
+ spi_sync(flash->spi, &m);
+
+ if (retlen)
+- *retlen += m.actual_length - CMD_SIZE;
++ *retlen += m.actual_length - m25p_cmdsz(flash);
+ }
+ }
+
+@@ -497,7 +500,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
+ memset(t, 0, (sizeof t));
+
+ t[0].tx_buf = flash->command;
+- t[0].len = CMD_SIZE;
++ t[0].len = m25p_cmdsz(flash);
+ spi_message_add_tail(&t[0], &m);
+
+ t[1].tx_buf = buf;
+@@ -516,9 +519,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
+ /* Start write from odd address. */
+ if (actual) {
+ flash->command[0] = OPCODE_BP;
+- flash->command[1] = to >> 16;
+- flash->command[2] = to >> 8;
+- flash->command[3] = to;
++ m25p_addr2cmd(flash, to, flash->command);
+
+ /* write one byte. */
+ t[1].len = 1;
+@@ -526,17 +527,15 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
+ ret = wait_till_ready(flash);
+ if (ret)
+ goto time_out;
+- *retlen += m.actual_length - CMD_SIZE;
++ *retlen += m.actual_length - m25p_cmdsz(flash);
+ }
+ to += actual;
+
+ flash->command[0] = OPCODE_AAI_WP;
+- flash->command[1] = to >> 16;
+- flash->command[2] = to >> 8;
+- flash->command[3] = to;
++ m25p_addr2cmd(flash, to, flash->command);
+
+ /* Write out most of the data here. */
+- cmd_sz = CMD_SIZE;
++ cmd_sz = m25p_cmdsz(flash);
+ for (; actual < len - 1; actual += 2) {
+ t[0].len = cmd_sz;
+ /* write two bytes. */
+@@ -560,10 +559,8 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
+ if (actual != len) {
+ write_enable(flash);
+ flash->command[0] = OPCODE_BP;
+- flash->command[1] = to >> 16;
+- flash->command[2] = to >> 8;
+- flash->command[3] = to;
+- t[0].len = CMD_SIZE;
++ m25p_addr2cmd(flash, to, flash->command);
++ t[0].len = m25p_cmdsz(flash);
+ t[1].len = 1;
+ t[1].tx_buf = buf + actual;
+
+@@ -571,7 +568,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
+ ret = wait_till_ready(flash);
+ if (ret)
+ goto time_out;
+- *retlen += m.actual_length - CMD_SIZE;
++ *retlen += m.actual_length - m25p_cmdsz(flash);
+ write_disable(flash);
+ }
+
+@@ -602,10 +599,19 @@ struct flash_info {
+ unsigned sector_size;
+ u16 n_sectors;
+
++ u16 page_size;
++ u16 addr_width;
++
+ u16 flags;
+ #define SECT_4K 0x01 /* OPCODE_BE_4K works uniformly */
++#define M25P_NO_ERASE 0x02 /* No erase command needed */
+ };
+
++#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \
++ _jedec_id, _ext_id, _sector_size, _n_sectors, 256, 3, _flags
++
++#define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width) \
++ 0, 0, _sector_size, _n_sectors, _page_size, _addr_width, M25P_NO_ERASE
+
+ /* NOTE: double check command sets and memory organization when you add
+ * more flash chips. This current list focusses on newer chips, which
+@@ -660,13 +666,20 @@ static struct flash_info __devinitdata m25p_data [] = {
+ { "m25pe16", 0x208015, 0, 64 * 1024, 32, SECT_4K, },
+
+ /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
+- { "w25x10", 0xef3011, 0, 64 * 1024, 2, SECT_4K, },
+- { "w25x20", 0xef3012, 0, 64 * 1024, 4, SECT_4K, },
+- { "w25x40", 0xef3013, 0, 64 * 1024, 8, SECT_4K, },
+- { "w25x80", 0xef3014, 0, 64 * 1024, 16, SECT_4K, },
+- { "w25x16", 0xef3015, 0, 64 * 1024, 32, SECT_4K, },
+- { "w25x32", 0xef3016, 0, 64 * 1024, 64, SECT_4K, },
+- { "w25x64", 0xef3017, 0, 64 * 1024, 128, SECT_4K, },
++ { "w25x10", INFO(0xef3011, 0, 64 * 1024, 2, SECT_4K) },
++ { "w25x20", INFO(0xef3012, 0, 64 * 1024, 4, SECT_4K) },
++ { "w25x40", INFO(0xef3013, 0, 64 * 1024, 8, SECT_4K) },
++ { "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) },
++ { "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) },
++ { "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) },
++ { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
++
++ /* Catalyst / On Semiconductor -- non-JEDEC */
++ { "cat25c11", CAT25_INFO( 16, 8, 16, 1) },
++ { "cat25c03", CAT25_INFO( 32, 8, 16, 2) },
++ { "cat25c09", CAT25_INFO( 128, 8, 32, 2) },
++ { "cat25c17", CAT25_INFO( 256, 8, 32, 2) },
++ { "cat25128", CAT25_INFO(2048, 8, 64, 2) },
+ };
+
+ static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
+@@ -762,7 +776,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
+ flash = kzalloc(sizeof *flash, GFP_KERNEL);
+ if (!flash)
+ return -ENOMEM;
+- flash->command = kmalloc(CMD_SIZE + FAST_READ_DUMMY_BYTE, GFP_KERNEL);
++ flash->command = kmalloc(MAX_CMD_SIZE + FAST_READ_DUMMY_BYTE, GFP_KERNEL);
+ if (!flash->command) {
+ kfree(flash);
+ return -ENOMEM;
+@@ -809,6 +823,12 @@ static int __devinit m25p_probe(struct spi_device *spi)
+ flash->mtd.erasesize = info->sector_size;
+ }
+
++ if (info->flags & M25P_NO_ERASE)
++ flash->mtd.flags |= MTD_NO_ERASE;
++
++ flash->page_size = info->page_size;
++ flash->addr_width = info->addr_width;
++
+ dev_info(&spi->dev, "%s (%lld Kbytes)\n", info->name,
+ (long long)flash->mtd.size >> 10);
+
+--
+1.8.1
+
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0022-mtd-m25p80-Add-support-for-Macronix-MX25L25635E.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0022-mtd-m25p80-Add-support-for-Macronix-MX25L25635E.patch
new file mode 100644
index 0000000..cafc35a
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0022-mtd-m25p80-Add-support-for-Macronix-MX25L25635E.patch
@@ -0,0 +1,99 @@
+From a67b440516ccdfac57df3a79f1a89234cd5e9948 Mon Sep 17 00:00:00 2001
+From: Kevin Cernekee <cernekee@gmail.com>
+Date: Sat, 30 Oct 2010 21:11:03 -0700
+Subject: [PATCH 22/27] mtd: m25p80: Add support for Macronix MX25L25635E
+
+This is a 256Mbit (32MiB) part so minor changes were made to support
+4-byte addressing.
+
+Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
+Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
+Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
+(cherry picked from commit 4b7f7422b0331e802f8b7c593e058ccee981cff5)
+
+Conflicts:
+ drivers/mtd/devices/m25p80.c
+---
+ drivers/mtd/devices/m25p80.c | 31 ++++++++++++++++++++++++++++---
+ 1 file changed, 28 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
+index 4570bc3..a6a28fc 100644
+--- a/drivers/mtd/devices/m25p80.c
++++ b/drivers/mtd/devices/m25p80.c
+@@ -46,6 +46,10 @@
+ #define OPCODE_WRDI 0x04 /* Write disable */
+ #define OPCODE_AAI_WP 0xad /* Auto address increment word program */
+
++/* Used for Macronix flashes only. */
++#define OPCODE_EN4B 0xb7 /* Enter 4-byte mode */
++#define OPCODE_EX4B 0xe9 /* Exit 4-byte mode */
++
+ /* Status Register bits. */
+ #define SR_WIP 1 /* Write in progress */
+ #define SR_WEL 2 /* Write enable latch */
+@@ -57,7 +61,7 @@
+
+ /* Define max times to check status register before we give up. */
+ #define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */
+-#define MAX_CMD_SIZE 4
++#define MAX_CMD_SIZE 5
+
+ #ifdef CONFIG_M25PXX_USE_FAST_READ
+ #define OPCODE_READ OPCODE_FAST_READ
+@@ -153,6 +157,16 @@ static inline int write_disable(struct m25p *flash)
+ }
+
+ /*
++ * Enable/disable 4-byte addressing mode.
++ */
++static inline int set_4byte(struct m25p *flash, int enable)
++{
++ u8 code = enable ? OPCODE_EN4B : OPCODE_EX4B;
++
++ return spi_write_then_read(flash->spi, &code, 1, NULL, 0);
++}
++
++/*
+ * Service routine to read status register until ready, or timeout occurs.
+ * Returns non-zero if error.
+ */
+@@ -208,6 +222,7 @@ static void m25p_addr2cmd(struct m25p *flash, unsigned int addr, u8 *cmd)
+ cmd[1] = addr >> (flash->addr_width * 8 - 8);
+ cmd[2] = addr >> (flash->addr_width * 8 - 16);
+ cmd[3] = addr >> (flash->addr_width * 8 - 24);
++ cmd[4] = addr >> (flash->addr_width * 8 - 32);
+ }
+
+ static int m25p_cmdsz(struct m25p *flash)
+@@ -608,7 +623,7 @@ struct flash_info {
+ };
+
+ #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \
+- _jedec_id, _ext_id, _sector_size, _n_sectors, 256, 3, _flags
++ _jedec_id, _ext_id, _sector_size, _n_sectors, 256, _flags
+
+ #define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width) \
+ 0, 0, _sector_size, _n_sectors, _page_size, _addr_width, M25P_NO_ERASE
+@@ -827,7 +842,17 @@ static int __devinit m25p_probe(struct spi_device *spi)
+ flash->mtd.flags |= MTD_NO_ERASE;
+
+ flash->page_size = info->page_size;
+- flash->addr_width = info->addr_width;
++
++ if (info->addr_width)
++ flash->addr_width = info->addr_width;
++ else {
++ /* enable 4-byte addressing if the device exceeds 16MiB */
++ if (flash->mtd.size > 0x1000000) {
++ flash->addr_width = 4;
++ set_4byte(flash, 1);
++ } else
++ flash->addr_width = 3;
++ }
+
+ dev_info(&spi->dev, "%s (%lld Kbytes)\n", info->name,
+ (long long)flash->mtd.size >> 10);
+--
+1.8.1
+
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0023-mtd-m25p80-Add-support-for-Macronix-MX25L25655E.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0023-mtd-m25p80-Add-support-for-Macronix-MX25L25655E.patch
new file mode 100644
index 0000000..31aa2bb
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0023-mtd-m25p80-Add-support-for-Macronix-MX25L25655E.patch
@@ -0,0 +1,72 @@
+From 382791c9efc03015575bc1f5552ebb7004f1610f Mon Sep 17 00:00:00 2001
+From: Kevin Cernekee <cernekee@gmail.com>
+Date: Sat, 30 Oct 2010 21:11:04 -0700
+Subject: [PATCH 23/27] mtd: m25p80: Add support for Macronix MX25L25655E
+
+Untested, but expected to be compatible with MX25L25635E which I did
+test.
+
+Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
+Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
+Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
+(cherry picked from commit ac622f583dccb025250becd2d4e60badaf571713)
+
+Conflicts:
+ drivers/mtd/devices/m25p80.c
+---
+ drivers/mtd/devices/m25p80.c | 39 +++++++++++++++++++++++++++++----------
+ 1 file changed, 29 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
+index a6a28fc..4d8519e 100644
+--- a/drivers/mtd/devices/m25p80.c
++++ b/drivers/mtd/devices/m25p80.c
+@@ -635,16 +635,35 @@ struct flash_info {
+ static struct flash_info __devinitdata m25p_data [] = {
+
+ /* Atmel -- some are (confusingly) marketed as "DataFlash" */
+- { "at25fs010", 0x1f6601, 0, 32 * 1024, 4, SECT_4K, },
+- { "at25fs040", 0x1f6604, 0, 64 * 1024, 8, SECT_4K, },
+-
+- { "at25df041a", 0x1f4401, 0, 64 * 1024, 8, SECT_4K, },
+- { "at25df641", 0x1f4800, 0, 64 * 1024, 128, SECT_4K, },
+-
+- { "at26f004", 0x1f0400, 0, 64 * 1024, 8, SECT_4K, },
+- { "at26df081a", 0x1f4501, 0, 64 * 1024, 16, SECT_4K, },
+- { "at26df161a", 0x1f4601, 0, 64 * 1024, 32, SECT_4K, },
+- { "at26df321", 0x1f4701, 0, 64 * 1024, 64, SECT_4K, },
++ { "at25fs010", INFO(0x1f6601, 0, 32 * 1024, 4, SECT_4K) },
++ { "at25fs040", INFO(0x1f6604, 0, 64 * 1024, 8, SECT_4K) },
++
++ { "at25df041a", INFO(0x1f4401, 0, 64 * 1024, 8, SECT_4K) },
++ { "at25df641", INFO(0x1f4800, 0, 64 * 1024, 128, SECT_4K) },
++
++ { "at26f004", INFO(0x1f0400, 0, 64 * 1024, 8, SECT_4K) },
++ { "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16, SECT_4K) },
++ { "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) },
++ { "at26df321", INFO(0x1f4701, 0, 64 * 1024, 64, SECT_4K) },
++
++ /* EON -- en25pxx */
++ { "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) },
++ { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) },
++
++ /* Intel/Numonyx -- xxxs33b */
++ { "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) },
++ { "320s33b", INFO(0x898912, 0, 64 * 1024, 64, 0) },
++ { "640s33b", INFO(0x898913, 0, 64 * 1024, 128, 0) },
++
++ /* Macronix */
++ { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) },
++ { "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) },
++ { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, 0) },
++ { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, 0) },
++ { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
++ { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
++ { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
++ { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
+
+ /* Spansion -- single (large) sector size only, at least
+ * for the chips listed here (without boot sectors).
+--
+1.8.1
+
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0024-mtd-m25p80-add-support-for-Micron-N25Q256A.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0024-mtd-m25p80-add-support-for-Micron-N25Q256A.patch
new file mode 100644
index 0000000..903c70e
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0024-mtd-m25p80-add-support-for-Micron-N25Q256A.patch
@@ -0,0 +1,35 @@
+From 53700b905d75a021dae896a592aac834ef403b40 Mon Sep 17 00:00:00 2001
+From: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
+Date: Tue, 14 Aug 2012 15:24:07 -0400
+Subject: [PATCH 24/27] mtd: m25p80: add support for Micron N25Q256A
+
+The manufacturer datasheet can be found on the Micron website,
+under the name n25q_256mb_3v_65nm.pdf:
+
+http://www.micron.com/search?source=ps&q=n25q_256mb_3v_65nm
+
+Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
+Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
+Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
+(cherry picked from commit 8da28681eb1430fb6715c7aef67001acfbbbcba5)
+---
+ drivers/mtd/devices/m25p80.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
+index 4d8519e..caacfb7 100644
+--- a/drivers/mtd/devices/m25p80.c
++++ b/drivers/mtd/devices/m25p80.c
+@@ -665,6 +665,9 @@ static struct flash_info __devinitdata m25p_data [] = {
+ { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
+ { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
+
++ /* Micron */
++ { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) },
++
+ /* Spansion -- single (large) sector size only, at least
+ * for the chips listed here (without boot sectors).
+ */
+--
+1.8.1
+
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0025-mtd-m25p80-add-support-for-Micron-N25Q128.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0025-mtd-m25p80-add-support-for-Micron-N25Q128.patch
new file mode 100644
index 0000000..dd09ad3
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0025-mtd-m25p80-add-support-for-Micron-N25Q128.patch
@@ -0,0 +1,28 @@
+From ba11b987123391b8d74c6e640df22248f3404cb5 Mon Sep 17 00:00:00 2001
+From: Jan Luebbe <jlu@pengutronix.de>
+Date: Fri, 24 Aug 2012 18:23:50 +0200
+Subject: [PATCH 25/27] mtd: m25p80: add support for Micron N25Q128
+
+Signed-off-by: Jan Luebbe <jlu@pengutronix.de>
+Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
+Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
+(cherry picked from commit 3105875f6b8902628caee2fd7821af43707c6bde)
+---
+ drivers/mtd/devices/m25p80.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
+index caacfb7..380c368 100644
+--- a/drivers/mtd/devices/m25p80.c
++++ b/drivers/mtd/devices/m25p80.c
+@@ -666,6 +666,7 @@ static struct flash_info __devinitdata m25p_data [] = {
+ { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
+
+ /* Micron */
++ { "n25q128", INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
+ { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) },
+
+ /* Spansion -- single (large) sector size only, at least
+--
+1.8.1
+
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0026-mtd-m25p80-modify-info-for-Micron-N25Q128.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0026-mtd-m25p80-modify-info-for-Micron-N25Q128.patch
new file mode 100644
index 0000000..5b204dc
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0026-mtd-m25p80-modify-info-for-Micron-N25Q128.patch
@@ -0,0 +1,39 @@
+From c1fdbfe2f6ee26651b626603d47a1499c0fd87e8 Mon Sep 17 00:00:00 2001
+From: Liming Wang <walimisdev@gmail.com>
+Date: Thu, 22 Nov 2012 14:58:09 +0800
+Subject: [PATCH 26/27] mtd: m25p80: modify info for Micron N25Q128
+
+Micron N25Q128 has two types of flash:
+
+ - One is for 1.8v supply voltage, prefixed with "n25q128a11" and the jedec
+ code is 0x20bb18.
+
+ - Another is for 3v supply voltage, prefixed with "n25q128a13" and the jedec
+ code is 0x20ba18.
+
+So modify the original type info and add another type for Micron N25Q128.
+
+Signed-off-by: Liming Wang <walimisdev@gmail.com>
+Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
+(cherry picked from commit 98a9e2450667e497246449f96eab06eb3fb4d24b)
+---
+ drivers/mtd/devices/m25p80.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
+index 380c368..19a4325 100644
+--- a/drivers/mtd/devices/m25p80.c
++++ b/drivers/mtd/devices/m25p80.c
+@@ -666,7 +666,8 @@ static struct flash_info __devinitdata m25p_data [] = {
+ { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
+
+ /* Micron */
+- { "n25q128", INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
++ { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, 0) },
++ { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
+ { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) },
+
+ /* Spansion -- single (large) sector size only, at least
+--
+1.8.1
+
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0027-mtd-m25p80-n25q064-is-Micron-not-Intel-Numonyx.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0027-mtd-m25p80-n25q064-is-Micron-not-Intel-Numonyx.patch
new file mode 100644
index 0000000..66ab70b
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0027-mtd-m25p80-n25q064-is-Micron-not-Intel-Numonyx.patch
@@ -0,0 +1,29 @@
+From 865453236765126bc0751c35c0c0e5ea5b56f668 Mon Sep 17 00:00:00 2001
+From: Brian Norris <computersforpeace@gmail.com>
+Date: Fri, 22 Feb 2013 14:07:22 -0800
+Subject: [PATCH 27/27] mtd: m25p80: n25q064 is Micron, not Intel/Numonyx
+
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+Acked-by: Peter Korsgaard <jacmet@sunsite.dk>
+Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
+Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
+(cherry picked from commit e66e280c36e09e4573089862e7dc2ade9e680088)
+---
+ drivers/mtd/devices/m25p80.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
+index 19a4325..5659b62 100644
+--- a/drivers/mtd/devices/m25p80.c
++++ b/drivers/mtd/devices/m25p80.c
+@@ -666,6 +666,7 @@ static struct flash_info __devinitdata m25p_data [] = {
+ { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
+
+ /* Micron */
++ { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, 0) },
+ { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, 0) },
+ { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
+ { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) },
+--
+1.8.1
+
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0028-ipv6-Plug-sk_buff-leak-in-ipv6_rcv-net-ipv6-ip6_inpu.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0028-ipv6-Plug-sk_buff-leak-in-ipv6_rcv-net-ipv6-ip6_inpu.patch
new file mode 100644
index 0000000..2ab10b6
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0028-ipv6-Plug-sk_buff-leak-in-ipv6_rcv-net-ipv6-ip6_inpu.patch
@@ -0,0 +1,52 @@
+From 71f6f6dfdf7c7a67462386d9ea05c1095a89c555 Mon Sep 17 00:00:00 2001
+From: Jesper Nilsson <jesper.nilsson@axis.com>
+Date: Fri, 27 Mar 2009 00:17:45 -0700
+Subject: [PATCH] ipv6: Plug sk_buff leak in ipv6_rcv (net/ipv6/ip6_input.c)
+
+Commit 778d80be52699596bf70e0eb0761cf5e1e46088d
+(ipv6: Add disable_ipv6 sysctl to disable IPv6 operaion on specific interface)
+seems to have introduced a leak of sk_buff's for ipv6 traffic,
+at least in some configurations where idev is NULL, or when ipv6
+is disabled via sysctl.
+
+The problem is that if the first condition of the if-statement
+returns non-NULL, it returns an skb with only one reference,
+and when the other conditions apply, execution jumps to the "out"
+label, which does not call kfree_skb for it.
+
+To plug this leak, change to use the "drop" label instead.
+(this relies on it being ok to call kfree_skb on NULL)
+This also allows us to avoid calling rcu_read_unlock here,
+and removes the only user of the "out" label.
+
+Signed-off-by: Jesper Nilsson <jesper.nilsson@axis.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ net/ipv6/ip6_input.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
+index f171e8d..8f04bd9 100644
+--- a/net/ipv6/ip6_input.c
++++ b/net/ipv6/ip6_input.c
+@@ -75,8 +75,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
+ if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL ||
+ !idev || unlikely(idev->cnf.disable_ipv6)) {
+ IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INDISCARDS);
+- rcu_read_unlock();
+- goto out;
++ goto drop;
+ }
+
+ memset(IP6CB(skb), 0, sizeof(struct inet6_skb_parm));
+@@ -147,7 +146,6 @@ err:
+ drop:
+ rcu_read_unlock();
+ kfree_skb(skb);
+-out:
+ return 0;
+ }
+
+--
+1.8.1
+
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/README b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/README
new file mode 100644
index 0000000..b237814
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/README
@@ -0,0 +1 @@
+Patches cherry picked from 2.6.32.41, mostly for the erase timeout issue.
diff --git a/meta-aspeed/recipes-kernel/linux/linux-aspeed.inc b/meta-aspeed/recipes-kernel/linux/linux-aspeed.inc
new file mode 100644
index 0000000..a66c7e1
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/linux-aspeed.inc
@@ -0,0 +1,31 @@
+
+DESCRIPTION = "Linux Kernel for Aspeed"
+SECTION = "kernel"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://COPYING;md5=d7810fab7487fb0aad327b76f1be7cd7"
+
+COMPATIBLE_MACHINE = "aspeed"
+
+do_compile[depends] = "libgcc:do_populate_sysroot"
+
+inherit kernel
+
+# auto load the following modules
+module_autoload_tun = "tun"
+module_autoload_at24 = "at24"
+module_autoload_ads7828 = "ads7828"
+module_autoload_pcf8574 = "pcf8574"
+module_autoload_max127 = "max127"
+module_conf_max127 = "options max127 scaling=24414"
+module_autoload_pmbus_core = "pmbus_core"
+module_autoload_pfe1100 = "pfe1100"
+module_autoload_fb_panther_plus = "fb_panther_plus"
+module_autoload_adm1275 = "adm1275"
+
+# Do not install kernel in rootfs
+do_install[postfuncs] += "remove_kernel_image_from_rootfs"
+remove_kernel_image_from_rootfs() {
+ rm -rf ${D}/boot/uImage*
+}
+pkg_postinst_kernel-image() {
+}
diff --git a/meta-aspeed/recipes-kernel/linux/linux-aspeed_2.6.28.9.bb b/meta-aspeed/recipes-kernel/linux/linux-aspeed_2.6.28.9.bb
new file mode 100644
index 0000000..077e21b
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/linux-aspeed_2.6.28.9.bb
@@ -0,0 +1,39 @@
+
+# This revision corresponds to the tag "v2.6.28.9"
+# We use the revision in order to avoid having to fetch it from the repo during parse
+SRCREV = "1e85856853e24e9013d142adaad38c2adc7e48ac"
+
+PV = "2.6.28.9"
+
+SRC_URI = "git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git;protocol=https;branch=linux-2.6.28.y \
+ file://patch-2.6.28.9/0000-linux-aspeed-064.patch \
+ file://patch-2.6.28.9/0000-linux-openbmc.patch \
+ file://patch-2.6.28.9/0001-MTD-fix-m25p80-64-bit-divisions.patch \
+ file://patch-2.6.28.9/0005-mtd-Bug-in-m25p80.c-during-whole-chip-erase.patch \
+ file://patch-2.6.28.9/0006-mtd-fix-timeout-in-M25P80-driver.patch \
+ file://patch-2.6.28.9/0009-mtd-m25p80-timeout-too-short-for-worst-case-m25p16-d.patch \
+ file://patch-2.6.28.9/0010-mtd-m25p80-fix-null-pointer-dereference-bug.patch \
+ file://patch-2.6.28.9/0012-mtd-m25p80-add-support-for-AAI-programming-with-SST-.patch \
+ file://patch-2.6.28.9/0020-mtd-m25p80-make-command-buffer-DMA-safe.patch \
+ file://patch-2.6.28.9/0021-mtd-m25p80-Add-support-for-CAT25xxx-serial-EEPROMs.patch \
+ file://patch-2.6.28.9/0022-mtd-m25p80-Add-support-for-Macronix-MX25L25635E.patch \
+ file://patch-2.6.28.9/0023-mtd-m25p80-Add-support-for-Macronix-MX25L25655E.patch \
+ file://patch-2.6.28.9/0024-mtd-m25p80-add-support-for-Micron-N25Q256A.patch \
+ file://patch-2.6.28.9/0025-mtd-m25p80-add-support-for-Micron-N25Q128.patch \
+ file://patch-2.6.28.9/0026-mtd-m25p80-modify-info-for-Micron-N25Q128.patch \
+ file://patch-2.6.28.9/0027-mtd-m25p80-n25q064-is-Micron-not-Intel-Numonyx.patch \
+ file://patch-2.6.28.9/0028-ipv6-Plug-sk_buff-leak-in-ipv6_rcv-net-ipv6-ip6_inpu.patch \
+ file://patch-2.6.28.9/0001-bzip2-lzma-library-support-for-gzip-bzip2-and-lzma-d.patch \
+ file://patch-2.6.28.9/0002-bzip2-lzma-config-and-initramfs-support-for-bzip2-lz.patch \
+ "
+
+S = "${WORKDIR}/git"
+
+LINUX_VERSION = "2.6.28.9"
+LINUX_VERSION_EXTENSION ?= "-aspeed"
+
+PR = "r1"
+
+KERNEL_CONFIG_COMMAND = "oe_runmake wedge_defconfig && oe_runmake oldconfig"
+
+include linux-aspeed.inc
OpenPOWER on IntegriCloud