From 2a51b7c1c2165ddb188c511e192b75f0aa0fbead Mon Sep 17 00:00:00 2001 From: Tian Fang Date: Mon, 9 Mar 2015 22:53:57 -0700 Subject: Initial open source release of OpenBMC --- meta-aspeed/classes/aspeed_uboot_image.bbclass | 63 + meta-aspeed/conf/layer.conf | 10 + meta-aspeed/conf/machine/include/ast1250.inc | 28 + meta-aspeed/conf/machine/include/ast2400.inc | 7 + meta-aspeed/recipes-bsp/u-boot/files/fw_env.config | 22 + .../patch-2013.07/0000-u-boot-aspeed-064.patch | 44658 ++++++++++++++++ .../files/patch-2013.07/0001-u-boot-openbmc.patch | 1580 + .../u-boot/u-boot-fw-utils_2013.07%.bbappend | 5 + .../recipes-bsp/u-boot/u-boot_2013.07%.bbappend | 12 + meta-aspeed/recipes-core/images/aspeed-dev.inc | 5 + .../recipes-core/images/files/aspeed_device_table | 41 + .../patch-2.6.28.9/0000-linux-aspeed-064.patch | 50917 +++++++++++++++++++ .../files/patch-2.6.28.9/0000-linux-openbmc.patch | 13400 +++++ .../0001-MTD-fix-m25p80-64-bit-divisions.patch | 129 + ...library-support-for-gzip-bzip2-and-lzma-d.patch | 1876 + ...config-and-initramfs-support-for-bzip2-lz.patch | 585 + ...d-Bug-in-m25p80.c-during-whole-chip-erase.patch | 53 + .../0006-mtd-fix-timeout-in-M25P80-driver.patch | 63 + ...timeout-too-short-for-worst-case-m25p16-d.patch | 31 + ...d-m25p80-fix-null-pointer-dereference-bug.patch | 56 + ...add-support-for-AAI-programming-with-SST-.patch | 179 + ...0-mtd-m25p80-make-command-buffer-DMA-safe.patch | 56 + ...0-Add-support-for-CAT25xxx-serial-EEPROMs.patch | 327 + ...5p80-Add-support-for-Macronix-MX25L25635E.patch | 99 + ...5p80-Add-support-for-Macronix-MX25L25655E.patch | 72 + ...td-m25p80-add-support-for-Micron-N25Q256A.patch | 35 + ...mtd-m25p80-add-support-for-Micron-N25Q128.patch | 28 + ...mtd-m25p80-modify-info-for-Micron-N25Q128.patch | 39 + ...25p80-n25q064-is-Micron-not-Intel-Numonyx.patch | 29 + ...k_buff-leak-in-ipv6_rcv-net-ipv6-ip6_inpu.patch | 52 + .../linux/files/patch-2.6.28.9/README | 1 + meta-aspeed/recipes-kernel/linux/linux-aspeed.inc | 31 + .../recipes-kernel/linux/linux-aspeed_2.6.28.9.bb | 39 + 33 files changed, 114528 insertions(+) create mode 100644 meta-aspeed/classes/aspeed_uboot_image.bbclass create mode 100644 meta-aspeed/conf/layer.conf create mode 100644 meta-aspeed/conf/machine/include/ast1250.inc create mode 100644 meta-aspeed/conf/machine/include/ast2400.inc create mode 100644 meta-aspeed/recipes-bsp/u-boot/files/fw_env.config create mode 100644 meta-aspeed/recipes-bsp/u-boot/files/patch-2013.07/0000-u-boot-aspeed-064.patch create mode 100644 meta-aspeed/recipes-bsp/u-boot/files/patch-2013.07/0001-u-boot-openbmc.patch create mode 100644 meta-aspeed/recipes-bsp/u-boot/u-boot-fw-utils_2013.07%.bbappend create mode 100644 meta-aspeed/recipes-bsp/u-boot/u-boot_2013.07%.bbappend create mode 100644 meta-aspeed/recipes-core/images/aspeed-dev.inc create mode 100644 meta-aspeed/recipes-core/images/files/aspeed_device_table create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0000-linux-aspeed-064.patch create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0000-linux-openbmc.patch create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0001-MTD-fix-m25p80-64-bit-divisions.patch create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0001-bzip2-lzma-library-support-for-gzip-bzip2-and-lzma-d.patch create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0002-bzip2-lzma-config-and-initramfs-support-for-bzip2-lz.patch create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0005-mtd-Bug-in-m25p80.c-during-whole-chip-erase.patch create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0006-mtd-fix-timeout-in-M25P80-driver.patch create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0009-mtd-m25p80-timeout-too-short-for-worst-case-m25p16-d.patch create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0010-mtd-m25p80-fix-null-pointer-dereference-bug.patch create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0012-mtd-m25p80-add-support-for-AAI-programming-with-SST-.patch create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0020-mtd-m25p80-make-command-buffer-DMA-safe.patch create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0021-mtd-m25p80-Add-support-for-CAT25xxx-serial-EEPROMs.patch create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0022-mtd-m25p80-Add-support-for-Macronix-MX25L25635E.patch create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0023-mtd-m25p80-Add-support-for-Macronix-MX25L25655E.patch create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0024-mtd-m25p80-add-support-for-Micron-N25Q256A.patch create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0025-mtd-m25p80-add-support-for-Micron-N25Q128.patch create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0026-mtd-m25p80-modify-info-for-Micron-N25Q128.patch create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0027-mtd-m25p80-n25q064-is-Micron-not-Intel-Numonyx.patch create mode 100644 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 create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/README create mode 100644 meta-aspeed/recipes-kernel/linux/linux-aspeed.inc create mode 100644 meta-aspeed/recipes-kernel/linux/linux-aspeed_2.6.28.9.bb (limited to 'meta-aspeed') 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 ++ #include ++ #include // 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 ++#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 ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++#endif ++#ifdef SLT_UBOOT ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++#endif ++#ifdef SLT_DOS ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #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 ++ #include ++ #include ++#endif ++ ++#ifdef SLT_DOS ++ #include "COMMINF.H" ++ #include ++ #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< 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 ++ #include ++#endif ++#ifdef SLT_DOS ++#include ++#include ++#include ++#include ++#include ++#include ++#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, ®s, ®s) ; ++ ++ 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, ®s, ®s); ++ 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, ®s, ®s); // int386(0x31, ®s, ®s); ++ 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, ®s, ®s); ++ ++ 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 ++ #include ++ #include ++ #define SPI_CS 1 ++#endif ++// ( USE_P2A | USE_LPC ) ++ ++#if defined(LinuxAP) ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++#endif ++#ifdef SLT_UBOOT ++ #include ++ #include ++#endif ++#ifdef SLT_DOS ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++#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 ++ #include ++ #include ++ #include "STDUBOOT.H" ++#endif ++#ifdef SLT_DOS ++ #include ++ #include ++ #include ++ #include ++ #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(×tart)); ++ 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 ++ #include ++ #include ++ #include ++ #include ++#endif ++#ifdef SLT_DOS ++ #include ++ #include ++ #include ++ #include ++ #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 ++ #include ++#endif ++#ifdef SLT_DOS ++ #include ++ #include ++ #include ++ #include ++ #include ++#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 ++ #include ++ #include ++ #include "STDUBOOT.H" ++#endif ++#ifdef SLT_DOS ++ #include ++ #include ++ #include ++ #include ++ #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 ++#include ++#include ++#include ++#include ++ ++/* ++ * 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 ++#include ++#include ++#include ++#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 ++ ++/* ++ * 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 ++#include ++ ++#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 ++#include ++#include ++ ++#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 ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++#else ++ #include ++ #include ++ #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(×tart); ++ #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 \n\n"); ++ else ++ printf ("\nNCSITEST.exe run_mode \n\n"); ++ PrintMode (); ++ PrintPakNUm(); ++ PrintChlNUm(); ++ PrintTest (); ++ if (AST2300) ++ PrintIOTimingBund (); ++ } ++ else { ++ if (AST2300) ++ printf ("\nMACTEST.exe run_mode \n\n"); ++ else ++ printf ("\nMACTEST.exe run_mode \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 ++#include ++ ++#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 ++#include ++ ++#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 ++#include ++#include ++ ++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 ++#include ++#include ++#include ++ ++#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 ++#include ++ ++#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 ++#include ++#include ++#include ++#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 ++#include ++#include ++#include ++#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; jspecificspi == 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 ++#include ++#include ++#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; inr) ++ { ++ 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 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; iaes_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; iplaintext[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 ++#include ++#include ++#include ++#include ++#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 ++#include ++#include ++#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> 12; ++ pjsum = (unsigned char *)(m16byteAlignment((unsigned long) chksumbuf)); ++ ++ /* start test */ ++ for (i=0; i 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 ++#include ++ ++#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, ++ * ++ * 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 ++#include ++/****************************************************************************** ++ 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] ++ /* 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 ++#include ++#include ++#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 ++#include ++#include ++#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 ++#include ++#include ++#include ++ ++#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 i) ++ { ++ printf("[VIDEO] Decoder Pointer cannot move!!! /n"); ++ //ExitVideoTest(); ++ return VIDEO_DECODE_FAIL; ++ } ++ ++ //8*8 YUVA block ++ for (i=24; i> 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> 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 ++#include ++#include ++ ++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 ++#include ++#include ++#include ++ ++#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 ++#include ++ ++#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 ++#include ++#include ++#include ++#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 ++#include ++#include ++#include ++#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; jspecificspi == 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 ++#include ++#include ++#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; inr) ++ { ++ 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 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; iaes_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; iplaintext[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 ++#include ++#include ++#include ++#include ++#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 ++#include ++#include ++#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> 12; ++ pjsum = (unsigned char *)(m16byteAlignment((unsigned long) chksumbuf)); ++ ++ /* start test */ ++ for (i=0; i 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 ++#include ++ ++#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, ++ * ++ * 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 ++#include ++/****************************************************************************** ++ 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] ++ /* 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 ++#include ++#include ++#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 ++#include ++#include ++#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, ++ * ++ * 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 ++#include ++#include ++#include ++ ++#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 i) ++ { ++ printf("[VIDEO] Decoder Pointer cannot move!!! /n"); ++ //ExitVideoTest(); ++ return VIDEO_DECODE_FAIL; ++ } ++ ++ //8*8 YUVA block ++ for (i=24; i> 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 ++#include ++#include ++ ++#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 ++ ++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 ++#include ++ ++#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 ++ ++#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) && defined(CONFIG_ASPEEDNIC) ++ ++#include ++#include ++#include ++ ++ ++/* ++ 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 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public 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 ++ ++#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 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public 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 ++ ++#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 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public 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 ++ ++#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 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public 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 ++ ++#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 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public 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 ++ ++#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 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public 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 ++ ++#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 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public 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 ++ ++#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 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public 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 ++ ++#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 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public 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 ++ ++#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 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public 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 ++ ++#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 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public 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 ++ ++#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 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public 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 ++ ++#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 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public 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 ++ ++#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 + #include + #include +- #include ++ #include "COMMINF.H" + #endif + #ifdef SLT_DOS + #include +@@ -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 +- #include +- #include ++ #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 + #include +- #include ++ #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 + #include +- #include +- #include +- #include ++ #include "COMMINF.H" ++ #include "NCSI.H" ++ #include "IO.H" + #endif + #ifdef SLT_DOS + #include +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 + #include +- #include ++ #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 +-#include +-#include +-#include +-#include ++#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 +-#include ++#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 +-#include +-#include ++#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 + #include + #include +- #include +- #include +- #include ++ #include "COMMINF.H" ++ #include "STDUBOOT.H" ++ #include "IO.H" + #else + #include + #include +@@ -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 +-#include ++ ++#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 ++#include + #include + #include + +@@ -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 + #include +@@ -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, +- * +- * 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 + #include + + 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 + #include + #include ++#include + + + /* +@@ -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 ++ ++#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 @@ +# +#/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 + #include + #include ++#include + + #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 ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++#include ++#ifdef CONFIG_ARCH_AST1070 ++#include ++#include ++#include ++#include ++#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;ibus_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 ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++#include ++#ifdef CONFIG_ARCH_AST1070 ++#include ++#include ++#include ++#include ++#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;ibus_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 ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++//#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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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 ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++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 ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++ ++#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 ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++//#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< 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< 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<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 ++#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 ++ ++//# 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 ++#include ++ ++ .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 +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 ++#include ++#include ++#include ++ ++ .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 ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public 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 ++#include ++#include ++ ++/*************************************************************/ ++#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 /* 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 ++ ++/* ++ * 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 ++#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 ++ ++#if defined(CONFIG_ARCH_AST1010) ++#include ++#elif defined(CONFIG_ARCH_AST1510) ++#include ++#elif defined(CONFIG_ARCH_AST1520) ++#include ++#elif defined(CONFIG_ARCH_AST2000) ++#include ++#elif defined(CONFIG_ARCH_AST2100) ++#include ++#elif defined(CONFIG_ARCH_AST2200) ++#include ++#elif defined(CONFIG_ARCH_AST2300) ++#include ++#elif defined(CONFIG_ARCH_AST2400) ++#include ++#elif defined(CONFIG_ARCH_AST2500) ++#include ++#elif defined(CONFIG_ARCH_AST3100) ++#include ++#elif defined(CONFIG_ARCH_AST3200) ++#include ++#else ++#err "no define for irqs.h" ++#endif ++ ++#include ++//#include ++ ++/*********************************************************************************/ ++//CVIC ++#if defined(CONFIG_ARCH_AST1070) ++//Companion chip irq ++#include ++#endif ++ ++#if defined(CONFIG_AST2400_BMC) ++#include ++#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 ++#include ++ ++#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 ++#elif defined(CONFIG_ARCH_AST2000) ++#include ++#elif defined(CONFIG_ARCH_AST2100) ++#include ++#elif defined(CONFIG_ARCH_AST2200) ++#include ++#elif defined(CONFIG_ARCH_AST2300) ++#include ++#elif defined(CONFIG_ARCH_AST2400) ++#include ++#elif defined(CONFIG_ARCH_AST2500) ++#include ++#elif defined(CONFIG_ARCH_AST3200) ++#include ++#else ++#err "No define for platform.h" ++#endif ++/*********************************************************************************/ ++/* Companion Base Address */ ++#if defined(CONFIG_ARCH_AST1070) ++#include ++#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 ++#include ++#include ++ ++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 ++#include ++#include ++ ++/* ++ * 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 ++#include ++ ++#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 ++#include ++#include ++ ++#include ++#include ++ ++#include ++ ++#include ++#include ++ ++//#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 ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++ ++//#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 ++#include ++#include ++ ++#include ++#include ++ ++#include ++ ++#include ++#include ++ ++#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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++//#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 ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++ ++#include ++ ++#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; ichip->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; ichip->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 ++#include ++#include ++ ++#if defined(CONFIG_COLDFIRE) ++#include ++ ++#include ++#include ++#include ++#include ++#else ++#include ++#include ++#include ++#include ++#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 ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++/* -------------------------------------------------------------------- ++ * 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 ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++ ++/* -------------------------------------------------------------------- ++ * 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 ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++/* -------------------------------------------------------------------- ++ * 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 ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++ ++/* -------------------------------------------------------------------- ++ * 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 ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++ ++/* -------------------------------------------------------------------- ++ * 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 ++#include ++ ++#include ++#include ++ ++#include ++#include ++ ++#include ++ ++/* -------------------------------------------------------------------- ++ * 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 ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++/* -------------------------------------------------------------------- ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* -------------------------------------------------------------------- ++ * 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;iflag = 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;iflag = 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 ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++/* -------------------------------------------------------------------- ++ * 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 ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++ ++/* -------------------------------------------------------------------- ++ * 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 ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++/* -------------------------------------------------------------------- ++ * 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 ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++ ++ ++ ++/* -------------------------------------------------------------------- ++ * 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 ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++/* -------------------------------------------------------------------- ++ * 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 ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++ ++/* -------------------------------------------------------------------- ++ * 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 ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* -------------------------------------------------------------------- ++ * 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 ++#include ++ ++#include ++#include ++ ++#include ++ ++ ++/* -------------------------------------------------------------------- ++ * 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 ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++ ++/* -------------------------------------------------------------------- ++ * 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 ++#include ++#include ++ ++#include ++#include ++//#include ++ ++#include ++ ++/* -------------------------------------------------------------------- ++ * 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 ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++/* -------------------------------------------------------------------- ++ * 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 ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++ ++#include ++#if defined(CONFIG_COLDFIRE) ++#include ++#include ++#include ++#include ++#include ++#include ++#else ++#include ++#include ++#include ++#include ++#include ++#include ++#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 ++#include ++#include ++#include ++#include ++#include ++ ++#if defined(CONFIG_COLDFIRE) ++#include ++#include ++#include ++#include ++#else ++#include ++#include ++#include ++#include ++#include ++#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 ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++/* -------------------------------------------------------------------- ++ * 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 ++#include ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++/* -------------------------------------------------------------------- ++ * 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 ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++ ++#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 ++#include ++ ++#include ++#include ++ ++#include ++ ++/* -------------------------------------------------------------------- ++ * 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 ++#include ++#include ++ ++#include ++ ++#include ++ ++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 ++#if defined(CONFIG_COLDFIRE) ++#include ++#else ++#include ++#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 ++#include ++#include ++ ++ ++/* ++ * 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. ++ * 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. ++ * 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 ++#include ++#include ++ ++/* ++ * 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. ++ * 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. ++ * 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. ++ * 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<> 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<> 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<> 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<> 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<> 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<> 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< ++ * 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 ++#endif ++//============== INTERRUPT======================================== ++#include ++#include ++#include ++ ++/* ++ * 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. ++ * 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. ++ * 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. ++ * 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. ++ * 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. ++ * 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<>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. ++ * 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. ++ * 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. ++ * 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. ++ * 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 ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#ifdef CONFIG_COLDFIRE ++#include ++#else ++#include ++#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 "); ++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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++ ++ ++#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; idev.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 "); ++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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++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 "); ++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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#ifdef CONFIG_COLDFIRE ++#include ++#include ++#else ++#include ++#include ++#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<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 "); ++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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++ ++#if defined(CONFIG_COLDFIRE) ++#include ++#include ++#else ++#include ++#include ++#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; islave_event) { ++ case I2C_SLAVE_EVENT_START_WRITE: ++ for(i=0; islave_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; islave_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; ibuf, 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; islave_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;islave_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;islave_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;imaster_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 "); ++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 + #include + ++#ifdef CONFIG_AST_I2C_SLAVE_RDWR ++#include ++#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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++ ++#include ++ ++ ++#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 & 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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "ftgmac100_26.h" ++ ++#if defined(CONFIG_ARM) ++#include ++#include ++ ++#elif defined(CONFIG_COLDFIRE) ++#include ++ ++#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; irx_descs[i].RXPKT_RDY = RX_OWNBY_FTGMAC100; // owned by FTMAC100 ++ ++ priv->rx_idx = 0; ++ ++ for (i=0; itx_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<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; irx_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_cntrx_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<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<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<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; irx_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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "8250.h" ++#include ++#include ++#include ++#include ++ ++//#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 ++ ++ ++#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;ibuf[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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#if defined(CONFIG_SERIAL_ASPEED_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) ++#define SUPPORT_SYSRQ ++#endif ++ ++#include ++ ++#if defined(CONFIG_COLDFIRE) ++#include ++#include ++#define UART_NR 1 ++ ++#elif defined(CONFIG_ARM) ++#include ++#include ++#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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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;ilen;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;ilen;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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++//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;ilen;i++) ++ printk("%x ",tx_buf[i]); ++ } ++ printk("\n"); ++#endif ++ for(i=0;ilen;i++) { ++ writeb(tx_buf[i], host->buff); ++ } ++ } ++ //Issue need clarify ++ udelay(1); ++ if(rx_buf != 0) { ++ for(i=0;ilen;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;ilen;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 . ++ ++ 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 ++#include ++#include ++#include ++ ++#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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++#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 ++#include ++ ++#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 : ++ */ ++#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 : (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 ++ * ++ * is (td_status(td) & 0xF60000), a.k.a. ++ * uhci_status_bits(td_status(td)). ++ * Note: does not include the TD_CTRL_NAK bit. ++ * 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 ++#include ++#include ++ ++#include ++ ++ ++/* 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#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; ipixclock) { ++ 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;idev, &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 ++#include ++#include ++#include ++ ++#include ++#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;imodedb_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;imodedb_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 "); ++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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#ifdef CONFIG_COLDFIRE ++#include ++#include ++#include ++#else ++#include ++#include ++#include ++#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 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 ++ ++ ++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 , register . ++ may be -1, which means "current page". ++ ++ int (*read_word_data)(struct i2c_client *client, int page, int reg); ++ ++ Read word from page , register . ++ ++ int (*write_word_data)(struct i2c_client *client, int page, int reg, ++ u16 word); ++ ++ Write word to page , register . ++ ++ int (*write_byte)(struct i2c_client *client, int page, u8 value); ++ ++ Write byte to page , register . ++ 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 for subsequent commands. ++ ++ int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg); ++ ++ Read word data from , . 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 , . 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 , . Similar to i2c_smbus_read_byte_data(), but ++ selects page first. may be -1, which means "current page". ++ ++ int pmbus_write_byte(struct i2c_client *client, int page, u8 value); ++ ++ Write byte data to , . Similar to i2c_smbus_write_byte(), but ++ selects page first. 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 + #include + #include +-#include + + #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 + #include + +-#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); + } + + 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;iflag = 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 + #include + ++#include + #include + #include + #include + #include ++#include + +- +- +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +- ++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 ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++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 ++#include ++#include + #include +-#include + #include +-#include +-#include + #include +-#include +- + #include +-#include +-#include +-#include +-#include + #include + #include + +@@ -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 + + +-#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; idev.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 + #endif + ++#include ++ + //#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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++ */ ++ 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 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 "); ++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 ++ * Jean Delvare ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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 "); ++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 ++#include ++#include ++#include ++#include ++#include ++#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 ++#include ++#include ++#include ++#include ++#include ++#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 ++#include ++#include ++#include ++#include ++#include ++#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 ++#include ++#include ++#include ++#include ++#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 ++#include ++#include ++#include ++#include ++#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 ++#include ++#include ++#include ++#include ++#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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#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 ++#include ++#include ++#include ++#include ++#include ++#include ++#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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#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. ++ * 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 = . ++ * To determine if an object exceeds lower limits, specify = . ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#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 ++#include ++#include ++#include ++#include ++#include ++#include ++#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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#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; ibuf, 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 +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 +Signed-off-by: David Woodhouse +--- + 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 + #include + #include ++#include + + #include + #include +@@ -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 +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 +Signed-off-by: H. Peter Anvin +--- + .../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 ++ * ++ */ ++ ++#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 ++#include ++#include ++#include ++ ++/* 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 ++ ++#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 ++#endif /* !STATIC */ ++ ++#include ++ ++#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 ++ ++#include "zlib_inflate/inftrees.h" ++#include "zlib_inflate/inffast.h" ++#include "zlib_inflate/inflate.h" ++ ++#include "zlib_inflate/infutil.h" ++ ++#endif /* STATIC */ ++ ++#include ++ ++#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 ++#endif /* STATIC */ ++ ++#include ++ ++#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 ++ ++#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 +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 +Signed-off-by: H. Peter Anvin +--- + .../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) . (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 ++ ++#include ++#include ++#include ++ + 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 ++#include ++#include + + 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" +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 +Signed-off-by: David Woodhouse +--- + 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 +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 +Tested-by: Martin Michlmayr +Signed-off-by: Andrew Morton +Signed-off-by: David Woodhouse +--- + 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" +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 +Signed-off-by: David Woodhouse +--- + 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 +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 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 +Cc: David Brownell +Signed-off-by: Andrew Morton +Signed-off-by: Artem Bityutskiy +Signed-off-by: David Woodhouse +--- + 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 +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 +Signed-off-by: Mike Frysinger +Signed-off-by: David Woodhouse +--- + 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 +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 +Signed-off-by: Artem Bityutskiy +Signed-off-by: David Woodhouse +(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 +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 +Signed-off-by: David Woodhouse +(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 + #include + +- +-#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 +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 +Signed-off-by: Artem Bityutskiy +Signed-off-by: David Woodhouse +(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 +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 +Signed-off-by: Artem Bityutskiy +Signed-off-by: David Woodhouse +(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 +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 +Signed-off-by: Artem Bityutskiy +Signed-off-by: David Woodhouse +(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 +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 +Signed-off-by: Artem Bityutskiy +Signed-off-by: David Woodhouse +(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 +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 +Signed-off-by: Artem Bityutskiy +(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 +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 +Acked-by: Peter Korsgaard +Signed-off-by: Artem Bityutskiy +Signed-off-by: David Woodhouse +(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 +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 +Signed-off-by: David S. Miller +--- + 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 -- cgit v1.1