diff --git a/layers/meta-balena b/layers/meta-balena index f2295d2b9..9d7e6d1d6 160000 --- a/layers/meta-balena +++ b/layers/meta-balena @@ -1 +1 @@ -Subproject commit f2295d2b9fc9b8993b7264a5144a7051184ee61c +Subproject commit 9d7e6d1d64ab2b1c5a9aef0d721534688d00191c diff --git a/layers/meta-balena-nanopc-t4/conf/layer.conf b/layers/meta-balena-nanopc-t4/conf/layer.conf index 959450cd5..c54181f76 100644 --- a/layers/meta-balena-nanopc-t4/conf/layer.conf +++ b/layers/meta-balena-nanopc-t4/conf/layer.conf @@ -7,4 +7,6 @@ BBFILE_COLLECTIONS += "balena-nanopc-t4" BBFILE_PATTERN_balena-nanopc-t4 := "^${LAYERDIR}/" BBFILE_PRIORITY_balena-nanopc-t4 = "1337" +BBMASK += "/meta-nanopc-t4/recipes-bsp/u-boot/u-boot-rockchip.bb" + LAYERSERIES_COMPAT_balena-nanopc-t4 = "thud" diff --git a/layers/meta-balena-nanopc-t4/conf/machine/lec-px30.conf b/layers/meta-balena-nanopc-t4/conf/machine/lec-px30.conf new file mode 100644 index 000000000..8fa59b769 --- /dev/null +++ b/layers/meta-balena-nanopc-t4/conf/machine/lec-px30.conf @@ -0,0 +1,24 @@ +#@TYPE: Machine +#@NAME: ADLINK LEC-PX30 +#@SOC: Rockchip PX30 +#@DESCRIPTION: Machine configuration for ADLINK LEC-PX30 + +require conf/machine/include/arm/arch-armv8.inc +require conf/machine/include/soc-family.inc +# require conf/machine/include/px30.inc + +PREFERRED_PROVIDER_virtual/bootloader = "u-boot-rockchip" +PREFERRED_PROVIDER_virtual/kernel = "linux-rockchip" +PREFERRED_VERSION_linux-rockchip = "4.4.185%" + +UBOOT_MACHINE = "evb-px30_defconfig" + +KERNEL_IMAGETYPE = "Image" + +SERIAL_CONSOLES = "1500000;ttyFIQ0" + +#KBUILD_DEFCONFIG = "lec-px30_config" + +KERNEL_DEVICETREE = "rockchip/px30-evb-ddr3-v10-linux.dtb" + +MACHINE_ESSENTIAL_EXTRA_RDEPENDS += "kernel-devicetree rkbin-wifi" diff --git a/layers/meta-balena-nanopc-t4/conf/machine/smarc-px30.conf b/layers/meta-balena-nanopc-t4/conf/machine/smarc-px30.conf new file mode 100644 index 000000000..eefdbeb81 --- /dev/null +++ b/layers/meta-balena-nanopc-t4/conf/machine/smarc-px30.conf @@ -0,0 +1,6 @@ +#@TYPE: Machine +##@NAME: smarc-px30 +##@DESCRIPTION: Machine configuration for the I-Pi SMARC PX30 + +MACHINEOVERRIDES = "lec-px30:${MACHINE}" +include conf/machine/lec-px30.conf diff --git a/layers/meta-balena-nanopc-t4/conf/samples/local.conf.sample b/layers/meta-balena-nanopc-t4/conf/samples/local.conf.sample index fca7f601e..779b08283 100644 --- a/layers/meta-balena-nanopc-t4/conf/samples/local.conf.sample +++ b/layers/meta-balena-nanopc-t4/conf/samples/local.conf.sample @@ -1,6 +1,6 @@ # Supported machines #MACHINE ?= "nanopc-t4" - +#MACHINE ?= "lec-px30" BALENA_STORAGE = "overlay2" # More info meta-resin/README.md diff --git a/layers/meta-balena-nanopc-t4/recipes-bsp/rkbin/files/PX30TRUST.ini b/layers/meta-balena-nanopc-t4/recipes-bsp/rkbin/files/PX30TRUST.ini new file mode 100644 index 000000000..f6cfc2ec1 --- /dev/null +++ b/layers/meta-balena-nanopc-t4/recipes-bsp/rkbin/files/PX30TRUST.ini @@ -0,0 +1,15 @@ +[VERSION] +MAJOR=1 +MINOR=0 +[BL30_OPTION] +SEC=0 +[BL31_OPTION] +SEC=1 +PATH=rk33/px30_bl31_v1.14.elf +ADDR=0x00040000 +[BL32_OPTION] +SEC=0 +[BL33_OPTION] +SEC=0 +[OUTPUT] +PATH=trust.img diff --git a/layers/meta-balena-nanopc-t4/recipes-bsp/rkbin/rkbin_git.bbappend b/layers/meta-balena-nanopc-t4/recipes-bsp/rkbin/rkbin_git.bbappend new file mode 100644 index 000000000..ac6d69d57 --- /dev/null +++ b/layers/meta-balena-nanopc-t4/recipes-bsp/rkbin/rkbin_git.bbappend @@ -0,0 +1,15 @@ +FILESEXTRAPATHS_append := ":${THISDIR}/files" + +SRC_URI_append_lec-px30 = " \ + file://PX30TRUST.ini \ +" + +do_compile_lec-px30() { + cp ${WORKDIR}/PX30TRUST.ini . + tools/trust_merger PX30TRUST.ini +} + +do_deploy_append_lec-px30 () { + install -m 755 ${S}/rk33/px30_ddr_333MHz_v1.10.bin ${DEPLOYDIR}/rkbin + install -m 755 ${S}/rk33/px30_miniloader_v1.15.bin ${DEPLOYDIR}/rkbin +} diff --git a/layers/meta-balena-nanopc-t4/recipes-bsp/u-boot/files/0000-rockchip-add-support-for-px30.patch b/layers/meta-balena-nanopc-t4/recipes-bsp/u-boot/files/0000-rockchip-add-support-for-px30.patch new file mode 100644 index 000000000..4624da2e0 --- /dev/null +++ b/layers/meta-balena-nanopc-t4/recipes-bsp/u-boot/files/0000-rockchip-add-support-for-px30.patch @@ -0,0 +1,10395 @@ +From patchwork Thu Oct 24 23:27:52 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: =?utf-8?q?Heiko_St=C3=BCbner?= <heiko@sntech.de> +X-Patchwork-Id: 1183652 +X-Patchwork-Delegate: ykai007@gmail.com +Return-Path: <u-boot-bounces@lists.denx.de> +X-Original-To: incoming@patchwork.ozlabs.org +Delivered-To: patchwork-incoming@bilbo.ozlabs.org +Authentication-Results: ozlabs.org; + spf=none (no SPF record) smtp.mailfrom=lists.denx.de + (client-ip=81.169.180.215; helo=lists.denx.de; + envelope-from=u-boot-bounces@lists.denx.de; + receiver=<UNKNOWN>) +Authentication-Results: ozlabs.org; + dmarc=none (p=none dis=none) header.from=sntech.de +Received: from lists.denx.de (dione.denx.de [81.169.180.215]) + by ozlabs.org (Postfix) with ESMTP id 46zk2Q1bSKz9sPL + for <incoming@patchwork.ozlabs.org>; + Fri, 25 Oct 2019 10:28:28 +1100 (AEDT) +Received: by lists.denx.de (Postfix, from userid 105) + id 14E82C21E47; Thu, 24 Oct 2019 23:28:20 +0000 (UTC) +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de +X-Spam-Level: +X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable + autolearn_force=no version=3.4.0 +Received: from lists.denx.de (localhost [IPv6:::1]) + by lists.denx.de (Postfix) with ESMTP id B39C3C21DA1; + Thu, 24 Oct 2019 23:28:18 +0000 (UTC) +Received: by lists.denx.de (Postfix, from userid 105) + id C2FBCC21DB5; Thu, 24 Oct 2019 23:28:17 +0000 (UTC) +Received: from gloria.sntech.de (gloria.sntech.de [185.11.138.130]) + by lists.denx.de (Postfix) with ESMTPS id 659DAC21D9A + for <u-boot@lists.denx.de>; Thu, 24 Oct 2019 23:28:17 +0000 (UTC) +Received: from ip5f5a6266.dynamic.kabel-deutschland.de ([95.90.98.102] + helo=phil.fritz.box) by gloria.sntech.de with esmtpsa + (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) + (Exim 4.89) (envelope-from <heiko@sntech.de>) + id 1iNmWd-0002cR-9G; Fri, 25 Oct 2019 01:28:15 +0200 +From: Heiko Stuebner <heiko@sntech.de> +To: u-boot@lists.denx.de +Date: Fri, 25 Oct 2019 01:27:52 +0200 +Message-Id: <20191024232803.10338-2-heiko@sntech.de> +X-Mailer: git-send-email 2.23.0 +In-Reply-To: <20191024232803.10338-1-heiko@sntech.de> +References: <20191024232803.10338-1-heiko@sntech.de> +MIME-Version: 1.0 +Cc: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>, + joe.hershberger@ni.com, christoph.muellner@theobroma-systems.com +Subject: [U-Boot] [PATCH 01/12] spl: separate SPL_FRAMEWORK config for spl + and tpl +X-BeenThere: u-boot@lists.denx.de +X-Mailman-Version: 2.1.18 +Precedence: list +List-Id: U-Boot discussion <u-boot.lists.denx.de> +List-Unsubscribe: <https://lists.denx.de/options/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=unsubscribe> +List-Archive: <http://lists.denx.de/pipermail/u-boot/> +List-Post: <mailto:u-boot@lists.denx.de> +List-Help: <mailto:u-boot-request@lists.denx.de?subject=help> +List-Subscribe: <https://lists.denx.de/listinfo/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=subscribe> +Errors-To: u-boot-bounces@lists.denx.de +Sender: "U-Boot" <u-boot-bounces@lists.denx.de> + +From: Heiko Stuebner <heiko.stuebner@theobroma-systems.com> + +Right now enabling SPL_FRAMEWORK will also enable it for the TPL in all +cases, making the TPL bigger. There may be cases where the TPL is really +size constrained due to its underlying ram size. + +Therefore introduce a new TPL_FRAMEWORK option and make the relevant +conditionals check for both. The default is set to "y if SPL_FRAMEWORK" +to mimic the previous behaviour where the TPL would always get the +SPL framework if it was enabled in SPL. + +Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com> +--- + arch/arm/lib/Makefile | 2 +- + arch/arm/lib/crt0.S | 2 +- + arch/arm/lib/crt0_64.S | 2 ++ + arch/powerpc/lib/Makefile | 2 +- + common/spl/Kconfig | 8 ++++++++ + common/spl/Makefile | 2 +- + scripts/Makefile.spl | 4 ++++ + 7 files changed, 18 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile +index 48ee6c3c60..9de9a9acee 100644 +--- a/arch/arm/lib/Makefile ++++ b/arch/arm/lib/Makefile +@@ -35,7 +35,7 @@ obj-$(CONFIG_CMD_BOOTM) += bootm.o + obj-$(CONFIG_CMD_BOOTZ) += bootm.o zimage.o + obj-$(CONFIG_SYS_L2_PL310) += cache-pl310.o + else +-obj-$(CONFIG_SPL_FRAMEWORK) += spl.o ++obj-$(CONFIG_$(SPL_TPL_)FRAMEWORK) += spl.o + obj-$(CONFIG_SPL_FRAMEWORK) += zimage.o + obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o + endif +diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S +index c74641dcd9..fb6c37cf51 100644 +--- a/arch/arm/lib/crt0.S ++++ b/arch/arm/lib/crt0.S +@@ -149,7 +149,7 @@ here: + + bl c_runtime_cpu_setup /* we still call old routine here */ + #endif +-#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK) ++#if !defined(CONFIG_SPL_BUILD) || CONFIG_IS_ENABLED(FRAMEWORK) + + #if !defined(CONFIG_SPL_EARLY_BSS) + SPL_CLEAR_BSS +diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S +index e76b25a03e..04afa518ac 100644 +--- a/arch/arm/lib/crt0_64.S ++++ b/arch/arm/lib/crt0_64.S +@@ -120,6 +120,7 @@ relocation_return: + */ + bl c_runtime_cpu_setup /* still call old routine */ + #endif /* !CONFIG_SPL_BUILD */ ++#if !defined(CONFIG_SPL_BUILD) || CONFIG_IS_ENABLED(FRAMEWORK) + #if defined(CONFIG_SPL_BUILD) + bl spl_relocate_stack_gd /* may return NULL */ + /* set up gd here, outside any C code, if new stack is returned */ +@@ -152,5 +153,6 @@ clear_loop: + b board_init_r /* PC relative jump */ + + /* NOTREACHED - board_init_r() does not return */ ++#endif + + ENDPROC(_main) +diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile +index 8ac49bdd06..01c9dd51be 100644 +--- a/arch/powerpc/lib/Makefile ++++ b/arch/powerpc/lib/Makefile +@@ -41,5 +41,5 @@ obj-y += time.o + endif # not minimal + + ifdef CONFIG_SPL_BUILD +-obj-$(CONFIG_SPL_FRAMEWORK) += spl.o ++obj-$(CONFIG_$(SPL_TPL)_FRAMEWORK) += spl.o + endif +diff --git a/common/spl/Kconfig b/common/spl/Kconfig +index f467eca2be..4d5c4ddc46 100644 +--- a/common/spl/Kconfig ++++ b/common/spl/Kconfig +@@ -1183,6 +1183,14 @@ config TPL + + if TPL + ++config TPL_FRAMEWORK ++ bool "Support TPL based upon the common SPL framework" ++ default y if SPL_FRAMEWORK ++ help ++ Enable the SPL framework under common/spl/ for TPL builds. ++ This framework supports MMC, NAND and YMODEM and other methods ++ loading of U-Boot's SPL stage. If unsure, say Y. ++ + config TPL_HANDOFF + bool "Pass hand-off information from TPL to SPL and U-Boot proper" + depends on HANDOFF +diff --git a/common/spl/Makefile b/common/spl/Makefile +index 5ce6f4ae48..eaa57f5ce5 100644 +--- a/common/spl/Makefile ++++ b/common/spl/Makefile +@@ -7,7 +7,7 @@ + # + + ifdef CONFIG_SPL_BUILD +-obj-$(CONFIG_SPL_FRAMEWORK) += spl.o ++obj-$(CONFIG_$(SPL_TPL_)FRAMEWORK) += spl.o + obj-$(CONFIG_$(SPL_TPL_)BOOTROM_SUPPORT) += spl_bootrom.o + obj-$(CONFIG_$(SPL_TPL_)LOAD_FIT) += spl_fit.o + obj-$(CONFIG_$(SPL_TPL_)NOR_SUPPORT) += spl_nor.o +diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl +index 7af6b120b6..090c831710 100644 +--- a/scripts/Makefile.spl ++++ b/scripts/Makefile.spl +@@ -71,7 +71,11 @@ HAVE_VENDOR_COMMON_LIB = $(if $(wildcard $(srctree)/board/$(VENDOR)/common/Makef + libs-y += $(if $(BOARDDIR),board/$(BOARDDIR)/) + libs-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/ + ++ifeq ($(CONFIG_TPL_BUILD),y) ++libs-$(CONFIG_TPL_FRAMEWORK) += common/spl/ ++else + libs-$(CONFIG_SPL_FRAMEWORK) += common/spl/ ++endif + libs-y += common/init/ + + # Special handling for a few options which support SPL/TPL + +From patchwork Thu Oct 24 23:27:53 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: =?utf-8?q?Heiko_St=C3=BCbner?= <heiko@sntech.de> +X-Patchwork-Id: 1183654 +X-Patchwork-Delegate: ykai007@gmail.com +Return-Path: <u-boot-bounces@lists.denx.de> +X-Original-To: incoming@patchwork.ozlabs.org +Delivered-To: patchwork-incoming@bilbo.ozlabs.org +Authentication-Results: ozlabs.org; + spf=none (no SPF record) smtp.mailfrom=lists.denx.de + (client-ip=81.169.180.215; helo=lists.denx.de; + envelope-from=u-boot-bounces@lists.denx.de; + receiver=<UNKNOWN>) +Authentication-Results: ozlabs.org; + dmarc=none (p=none dis=none) header.from=sntech.de +Received: from lists.denx.de (dione.denx.de [81.169.180.215]) + by ozlabs.org (Postfix) with ESMTP id 46zk3w75Tkz9sPL + for <incoming@patchwork.ozlabs.org>; + Fri, 25 Oct 2019 10:29:48 +1100 (AEDT) +Received: by lists.denx.de (Postfix, from userid 105) + id 9D54FC21DE8; Thu, 24 Oct 2019 23:29:18 +0000 (UTC) +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de +X-Spam-Level: +X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable + autolearn_force=no version=3.4.0 +Received: from lists.denx.de (localhost [IPv6:::1]) + by lists.denx.de (Postfix) with ESMTP id 0186FC21E34; + Thu, 24 Oct 2019 23:28:21 +0000 (UTC) +Received: by lists.denx.de (Postfix, from userid 105) + id 290B6C21C6A; Thu, 24 Oct 2019 23:28:17 +0000 (UTC) +Received: from gloria.sntech.de (gloria.sntech.de [185.11.138.130]) + by lists.denx.de (Postfix) with ESMTPS id 629A5C21D8A + for <u-boot@lists.denx.de>; Thu, 24 Oct 2019 23:28:17 +0000 (UTC) +Received: from ip5f5a6266.dynamic.kabel-deutschland.de ([95.90.98.102] + helo=phil.fritz.box) by gloria.sntech.de with esmtpsa + (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) + (Exim 4.89) (envelope-from <heiko@sntech.de>) + id 1iNmWd-0002cR-MF; Fri, 25 Oct 2019 01:28:15 +0200 +From: Heiko Stuebner <heiko@sntech.de> +To: u-boot@lists.denx.de +Date: Fri, 25 Oct 2019 01:27:53 +0200 +Message-Id: <20191024232803.10338-3-heiko@sntech.de> +X-Mailer: git-send-email 2.23.0 +In-Reply-To: <20191024232803.10338-1-heiko@sntech.de> +References: <20191024232803.10338-1-heiko@sntech.de> +MIME-Version: 1.0 +Cc: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>, + joe.hershberger@ni.com, christoph.muellner@theobroma-systems.com +Subject: [U-Boot] [PATCH 02/12] rockchip: add core px30 headers +X-BeenThere: u-boot@lists.denx.de +X-Mailman-Version: 2.1.18 +Precedence: list +List-Id: U-Boot discussion <u-boot.lists.denx.de> +List-Unsubscribe: <https://lists.denx.de/options/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=unsubscribe> +List-Archive: <http://lists.denx.de/pipermail/u-boot/> +List-Post: <mailto:u-boot@lists.denx.de> +List-Help: <mailto:u-boot-request@lists.denx.de?subject=help> +List-Subscribe: <https://lists.denx.de/listinfo/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=subscribe> +Errors-To: u-boot-bounces@lists.denx.de +Sender: "U-Boot" <u-boot-bounces@lists.denx.de> + +Add headers needed by the upcoming px30 support, including two +new dt-binding headers taken from the Linux kernel. + +Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com> +--- + arch/arm/include/asm/arch-rockchip/grf_px30.h | 144 ++++++++++++++++++ + include/configs/px30_common.h | 62 ++++++++ + include/dt-bindings/power/px30-power.h | 27 ++++ + include/dt-bindings/soc/rockchip,boot-mode.h | 16 ++ + 4 files changed, 249 insertions(+) + create mode 100644 arch/arm/include/asm/arch-rockchip/grf_px30.h + create mode 100644 include/configs/px30_common.h + create mode 100644 include/dt-bindings/power/px30-power.h + create mode 100644 include/dt-bindings/soc/rockchip,boot-mode.h + +diff --git a/arch/arm/include/asm/arch-rockchip/grf_px30.h b/arch/arm/include/asm/arch-rockchip/grf_px30.h +new file mode 100644 +index 0000000000..c167bb42fa +--- /dev/null ++++ b/arch/arm/include/asm/arch-rockchip/grf_px30.h +@@ -0,0 +1,144 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * (C) Copyright 2017 Rockchip Electronics Co., Ltd. ++ */ ++#ifndef _ASM_ARCH_GRF_px30_H ++#define _ASM_ARCH_GRF_px30_H ++ ++#include <common.h> ++ ++struct px30_grf { ++ unsigned int gpio1al_iomux; ++ unsigned int gpio1ah_iomux; ++ unsigned int gpio1bl_iomux; ++ unsigned int gpio1bh_iomux; ++ unsigned int gpio1cl_iomux; ++ unsigned int gpio1ch_iomux; ++ unsigned int gpio1dl_iomux; ++ unsigned int gpio1dh_iomux; ++ ++ unsigned int gpio2al_iomux; ++ unsigned int gpio2ah_iomux; ++ unsigned int gpio2bl_iomux; ++ unsigned int gpio2bh_iomux; ++ unsigned int gpio2cl_iomux; ++ unsigned int gpio2ch_iomux; ++ unsigned int gpio2dl_iomux; ++ unsigned int gpio2dh_iomux; ++ ++ unsigned int gpio3al_iomux; ++ unsigned int gpio3ah_iomux; ++ unsigned int gpio3bl_iomux; ++ unsigned int gpio3bh_iomux; ++ unsigned int gpio3cl_iomux; ++ unsigned int gpio3ch_iomux; ++ unsigned int gpio3dl_iomux; ++ unsigned int gpio3dh_iomux; ++ ++ unsigned int gpio1a_p; ++ unsigned int gpio1b_p; ++ unsigned int gpio1c_p; ++ unsigned int gpio1d_p; ++ unsigned int gpio2a_p; ++ unsigned int gpio2b_p; ++ unsigned int gpio2c_p; ++ unsigned int gpio2d_p; ++ unsigned int gpio3a_p; ++ unsigned int gpio3b_p; ++ unsigned int gpio3c_p; ++ unsigned int gpio3d_p; ++ unsigned int gpio1a_sr; ++ unsigned int gpio1b_sr; ++ unsigned int gpio1c_sr; ++ unsigned int gpio1d_sr; ++ unsigned int gpio2a_sr; ++ unsigned int gpio2b_sr; ++ unsigned int gpio2c_sr; ++ unsigned int gpio2d_sr; ++ unsigned int gpio3a_sr; ++ unsigned int gpio3b_sr; ++ unsigned int gpio3c_sr; ++ unsigned int gpio3d_sr; ++ unsigned int gpio1a_smt; ++ unsigned int gpio1b_smt; ++ unsigned int gpio1c_smt; ++ unsigned int gpio1d_smt; ++ unsigned int gpio2a_smt; ++ unsigned int gpio2b_smt; ++ unsigned int gpio2c_smt; ++ unsigned int gpio2d_smt; ++ unsigned int gpio3a_smt; ++ unsigned int gpio3b_smt; ++ unsigned int gpio3c_smt; ++ unsigned int gpio3d_smt; ++ unsigned int gpio1a_e; ++ unsigned int gpio1b_e; ++ unsigned int gpio1c_e; ++ unsigned int gpio1d_e; ++ unsigned int gpio2a_e; ++ unsigned int gpio2b_e; ++ unsigned int gpio2c_e; ++ unsigned int gpio2d_e; ++ unsigned int gpio3a_e; ++ unsigned int gpio3b_e; ++ unsigned int gpio3c_e; ++ unsigned int gpio3d_e; ++ ++ unsigned int reserved0[(0x180 - 0x11C) / 4 - 1]; ++ unsigned int io_vsel; ++ unsigned int iofunc_con0; ++ unsigned int reserved1[(0x400 - 0x184) / 4 - 1]; ++ unsigned int soc_con[6]; ++ unsigned int reserved2[(0x480 - 0x414) / 4 - 1]; ++ unsigned int soc_status0; ++ unsigned int reserved3[(0x500 - 0x480) / 4 - 1]; ++ unsigned int cpu_con[3]; ++ unsigned int reserved4[5]; ++ unsigned int cpu_status[2]; ++ unsigned int reserved5[2]; ++ unsigned int soc_noc_con[2]; ++ unsigned int reserved6[6]; ++ unsigned int ddr_bankhash[4]; ++ unsigned int reserved7[(0x700 - 0x55c) / 4 - 1]; ++ unsigned int host0_con[2]; ++ unsigned int reserved8[(0x880 - 0x704) / 4 - 1]; ++ unsigned int otg_con3; ++ unsigned int reserved9[3]; ++ unsigned int host0_status4; ++ unsigned int reserved10[(0x904 - 0x890) / 4 - 1]; ++ unsigned int mac_con1; ++}; ++ ++check_member(px30_grf, mac_con1, 0x904); ++ ++struct px30_pmugrf { ++ unsigned int gpio0a_e; ++ unsigned int gpio0b_e; ++ unsigned int gpio0c_e; ++ unsigned int gpio0d_e; ++ unsigned int gpio0a_p; ++ unsigned int gpio0b_p; ++ unsigned int gpio0c_p; ++ unsigned int gpio0d_p; ++ unsigned int gpio0al_iomux; ++ unsigned int gpio0bl_iomux; ++ unsigned int gpio0cl_iomux; ++ unsigned int gpio0dl_iomux; ++ unsigned int gpio0l_sr; ++ unsigned int gpio0h_sr; ++ unsigned int gpio0l_smt; ++ unsigned int gpio0h_smt; ++ unsigned int reserved1[(0x100 - 0x3c) / 4 - 1]; ++ unsigned int soc_con[4]; ++ unsigned int reserved2[(0x180 - 0x10c) / 4 - 1]; ++ unsigned int pvtm_con[2]; ++ unsigned int reserved3[2]; ++ unsigned int pvtm_status[2]; ++ unsigned int reserved4[(0x200 - 0x194) / 4 - 1]; ++ unsigned int os_reg[12]; ++ unsigned int reset_function_status; ++}; ++ ++check_member(px30_pmugrf, reset_function_status, 0x230); ++ ++#endif +diff --git a/include/configs/px30_common.h b/include/configs/px30_common.h +new file mode 100644 +index 0000000000..d6c70601dd +--- /dev/null ++++ b/include/configs/px30_common.h +@@ -0,0 +1,62 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * (C) Copyright 2017 Rockchip Electronics Co., Ltd ++ */ ++ ++#ifndef __CONFIG_PX30_COMMON_H ++#define __CONFIG_PX30_COMMON_H ++ ++#include "rockchip-common.h" ++ ++#define CONFIG_SYS_CBSIZE 1024 ++#define CONFIG_SKIP_LOWLEVEL_INIT ++ ++#define CONFIG_SYS_NS16550_MEM32 ++ ++#define CONFIG_ROCKCHIP_STIMER_BASE 0xff220020 ++#define COUNTER_FREQUENCY 24000000 ++ ++/* FIXME: ff020000 is pmu_mem (10k), while ff0e0000 is regular int_mem */ ++#define CONFIG_IRAM_BASE 0xff020000 ++ ++#define CONFIG_SYS_INIT_SP_ADDR 0x00400000 ++#define CONFIG_SYS_LOAD_ADDR 0x00800800 ++#define CONFIG_SPL_STACK 0x00400000 ++#define CONFIG_SPL_MAX_SIZE 0x20000 ++#define CONFIG_SPL_BSS_START_ADDR 0x4000000 ++#define CONFIG_SPL_BSS_MAX_SIZE 0x4000 ++#define CONFIG_SYS_BOOTM_LEN (64 << 20) /* 64M */ ++ ++#define GICD_BASE 0xff131000 ++#define GICC_BASE 0xff132000 ++ ++#define CONFIG_SYS_BOOTM_LEN (64 << 20) /* 64M */ ++ ++/* MMC/SD IP block */ ++//#define CONFIG_BOUNCE_BUFFER ++ ++#define CONFIG_SYS_SDRAM_BASE 0 ++#define SDRAM_MAX_SIZE 0xff000000 ++#define SDRAM_BANK_SIZE (2UL << 30) ++ ++#ifndef CONFIG_SPL_BUILD ++ ++#define ENV_MEM_LAYOUT_SETTINGS \ ++ "scriptaddr=0x00500000\0" \ ++ "pxefile_addr_r=0x00600000\0" \ ++ "fdt_addr_r=0x08300000\0" \ ++ "kernel_addr_r=0x00280000\0" \ ++ "kernel_addr_c=0x03e80000\0" \ ++ "ramdisk_addr_r=0x0a200000\0" ++ ++#include <config_distro_bootcmd.h> ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ ENV_MEM_LAYOUT_SETTINGS \ ++ "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \ ++ "partitions=" PARTS_DEFAULT \ ++ ROCKCHIP_DEVICE_SETTINGS \ ++ BOOTENV ++ ++#endif ++ ++#endif +diff --git a/include/dt-bindings/power/px30-power.h b/include/dt-bindings/power/px30-power.h +new file mode 100644 +index 0000000000..30917a99ad +--- /dev/null ++++ b/include/dt-bindings/power/px30-power.h +@@ -0,0 +1,27 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#ifndef __DT_BINDINGS_POWER_PX30_POWER_H__ ++#define __DT_BINDINGS_POWER_PX30_POWER_H__ ++ ++/* VD_CORE */ ++#define PX30_PD_A35_0 0 ++#define PX30_PD_A35_1 1 ++#define PX30_PD_A35_2 2 ++#define PX30_PD_A35_3 3 ++#define PX30_PD_SCU 4 ++ ++/* VD_LOGIC */ ++#define PX30_PD_USB 5 ++#define PX30_PD_DDR 6 ++#define PX30_PD_SDCARD 7 ++#define PX30_PD_CRYPTO 8 ++#define PX30_PD_GMAC 9 ++#define PX30_PD_MMC_NAND 10 ++#define PX30_PD_VPU 11 ++#define PX30_PD_VO 12 ++#define PX30_PD_VI 13 ++#define PX30_PD_GPU 14 ++ ++/* VD_PMU */ ++#define PX30_PD_PMU 15 ++ ++#endif +diff --git a/include/dt-bindings/soc/rockchip,boot-mode.h b/include/dt-bindings/soc/rockchip,boot-mode.h +new file mode 100644 +index 0000000000..4b0914c098 +--- /dev/null ++++ b/include/dt-bindings/soc/rockchip,boot-mode.h +@@ -0,0 +1,16 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#ifndef __ROCKCHIP_BOOT_MODE_H ++#define __ROCKCHIP_BOOT_MODE_H ++ ++/*high 24 bits is tag, low 8 bits is type*/ ++#define REBOOT_FLAG 0x5242C300 ++/* normal boot */ ++#define BOOT_NORMAL (REBOOT_FLAG + 0) ++/* enter bootloader rockusb mode */ ++#define BOOT_BL_DOWNLOAD (REBOOT_FLAG + 1) ++/* enter recovery */ ++#define BOOT_RECOVERY (REBOOT_FLAG + 3) ++ /* enter fastboot mode */ ++#define BOOT_FASTBOOT (REBOOT_FLAG + 9) ++ ++#endif + +From patchwork Thu Oct 24 23:27:54 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: =?utf-8?q?Heiko_St=C3=BCbner?= <heiko@sntech.de> +X-Patchwork-Id: 1183653 +X-Patchwork-Delegate: ykai007@gmail.com +Return-Path: <u-boot-bounces@lists.denx.de> +X-Original-To: incoming@patchwork.ozlabs.org +Delivered-To: patchwork-incoming@bilbo.ozlabs.org +Authentication-Results: ozlabs.org; + spf=none (no SPF record) smtp.mailfrom=lists.denx.de + (client-ip=81.169.180.215; helo=lists.denx.de; + envelope-from=u-boot-bounces@lists.denx.de; + receiver=<UNKNOWN>) +Authentication-Results: ozlabs.org; + dmarc=none (p=none dis=none) header.from=sntech.de +Received: from lists.denx.de (dione.denx.de [81.169.180.215]) + by ozlabs.org (Postfix) with ESMTP id 46zk3J4RTSz9sQm + for <incoming@patchwork.ozlabs.org>; + Fri, 25 Oct 2019 10:29:16 +1100 (AEDT) +Received: by lists.denx.de (Postfix, from userid 105) + id 4016FC21D8A; Thu, 24 Oct 2019 23:28:39 +0000 (UTC) +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de +X-Spam-Level: +X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable + autolearn_force=no version=3.4.0 +Received: from lists.denx.de (localhost [IPv6:::1]) + by lists.denx.de (Postfix) with ESMTP id 507BDC21DD9; + Thu, 24 Oct 2019 23:28:19 +0000 (UTC) +Received: by lists.denx.de (Postfix, from userid 105) + id CBEBDC21C6A; Thu, 24 Oct 2019 23:28:17 +0000 (UTC) +Received: from gloria.sntech.de (gloria.sntech.de [185.11.138.130]) + by lists.denx.de (Postfix) with ESMTPS id 61B44C21C6A + for <u-boot@lists.denx.de>; Thu, 24 Oct 2019 23:28:17 +0000 (UTC) +Received: from ip5f5a6266.dynamic.kabel-deutschland.de ([95.90.98.102] + helo=phil.fritz.box) by gloria.sntech.de with esmtpsa + (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) + (Exim 4.89) (envelope-from <heiko@sntech.de>) + id 1iNmWe-0002cR-38; Fri, 25 Oct 2019 01:28:16 +0200 +From: Heiko Stuebner <heiko@sntech.de> +To: u-boot@lists.denx.de +Date: Fri, 25 Oct 2019 01:27:54 +0200 +Message-Id: <20191024232803.10338-4-heiko@sntech.de> +X-Mailer: git-send-email 2.23.0 +In-Reply-To: <20191024232803.10338-1-heiko@sntech.de> +References: <20191024232803.10338-1-heiko@sntech.de> +MIME-Version: 1.0 +Cc: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>, + joe.hershberger@ni.com, David Wu <david.wu@rock-chips.com>, + christoph.muellner@theobroma-systems.com +Subject: [U-Boot] [PATCH 03/12] pinctrl: rockchip: add px30 pinctrl driver +X-BeenThere: u-boot@lists.denx.de +X-Mailman-Version: 2.1.18 +Precedence: list +List-Id: U-Boot discussion <u-boot.lists.denx.de> +List-Unsubscribe: <https://lists.denx.de/options/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=unsubscribe> +List-Archive: <http://lists.denx.de/pipermail/u-boot/> +List-Post: <mailto:u-boot@lists.denx.de> +List-Help: <mailto:u-boot-request@lists.denx.de?subject=help> +List-Subscribe: <https://lists.denx.de/listinfo/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=subscribe> +Errors-To: u-boot-bounces@lists.denx.de +Sender: "U-Boot" <u-boot-bounces@lists.denx.de> + +From: David Wu <david.wu@rock-chips.com> + +Add the necessary glue code to allow pinctrl setting on px30 socs. + +Signed-off-by: David Wu <david.wu@rock-chips.com> +Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com> +Reviewed-by: Kever Yang<kever.yang@rock-chips.com> +--- + drivers/pinctrl/rockchip/Makefile | 1 + + drivers/pinctrl/rockchip/pinctrl-px30.c | 368 ++++++++++++++++++++++++ + 2 files changed, 369 insertions(+) + create mode 100644 drivers/pinctrl/rockchip/pinctrl-px30.c + +diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile +index a616d8587f..83913f668f 100644 +--- a/drivers/pinctrl/rockchip/Makefile ++++ b/drivers/pinctrl/rockchip/Makefile +@@ -3,6 +3,7 @@ + # Copyright (c) 2017 Rockchip Electronics Co., Ltd + + obj-y += pinctrl-rockchip-core.o ++obj-$(CONFIG_ROCKCHIP_PX30) += pinctrl-px30.o + obj-$(CONFIG_ROCKCHIP_RK3036) += pinctrl-rk3036.o + obj-$(CONFIG_ROCKCHIP_RK3128) += pinctrl-rk3128.o + obj-$(CONFIG_ROCKCHIP_RK3188) += pinctrl-rk3188.o +diff --git a/drivers/pinctrl/rockchip/pinctrl-px30.c b/drivers/pinctrl/rockchip/pinctrl-px30.c +new file mode 100644 +index 0000000000..bb56ae9fb3 +--- /dev/null ++++ b/drivers/pinctrl/rockchip/pinctrl-px30.c +@@ -0,0 +1,368 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * (C) Copyright 2019 Rockchip Electronics Co., Ltd ++ */ ++ ++#include <common.h> ++#include <dm.h> ++#include <dm/pinctrl.h> ++#include <regmap.h> ++#include <syscon.h> ++ ++#include "pinctrl-rockchip.h" ++ ++static struct rockchip_mux_route_data px30_mux_route_data[] = { ++ { ++ /* cif-d2m0 */ ++ .bank_num = 2, ++ .pin = 0, ++ .func = 1, ++ .route_offset = 0x184, ++ .route_val = BIT(16 + 7), ++ }, { ++ /* cif-d2m1 */ ++ .bank_num = 3, ++ .pin = 3, ++ .func = 3, ++ .route_offset = 0x184, ++ .route_val = BIT(16 + 7) | BIT(7), ++ }, { ++ /* pdm-m0 */ ++ .bank_num = 3, ++ .pin = 22, ++ .func = 2, ++ .route_offset = 0x184, ++ .route_val = BIT(16 + 8), ++ }, { ++ /* pdm-m1 */ ++ .bank_num = 2, ++ .pin = 22, ++ .func = 1, ++ .route_offset = 0x184, ++ .route_val = BIT(16 + 8) | BIT(8), ++ }, { ++ /* uart2-rxm0 */ ++ .bank_num = 1, ++ .pin = 27, ++ .func = 2, ++ .route_offset = 0x184, ++ .route_val = BIT(16 + 10), ++ }, { ++ /* uart2-rxm1 */ ++ .bank_num = 2, ++ .pin = 14, ++ .func = 2, ++ .route_offset = 0x184, ++ .route_val = BIT(16 + 10) | BIT(10), ++ }, { ++ /* uart3-rxm0 */ ++ .bank_num = 0, ++ .pin = 17, ++ .func = 2, ++ .route_offset = 0x184, ++ .route_val = BIT(16 + 9), ++ }, { ++ /* uart3-rxm1 */ ++ .bank_num = 1, ++ .pin = 15, ++ .func = 2, ++ .route_offset = 0x184, ++ .route_val = BIT(16 + 9) | BIT(9), ++ }, ++}; ++ ++static int px30_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) ++{ ++ struct rockchip_pinctrl_priv *priv = bank->priv; ++ int iomux_num = (pin / 8); ++ struct regmap *regmap; ++ int reg, ret, mask, mux_type; ++ u8 bit; ++ u32 data, route_reg, route_val; ++ ++ regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) ++ ? priv->regmap_pmu : priv->regmap_base; ++ ++ /* get basic quadrupel of mux registers and the correct reg inside */ ++ mux_type = bank->iomux[iomux_num].type; ++ reg = bank->iomux[iomux_num].offset; ++ reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask); ++ ++ if (bank->route_mask & BIT(pin)) { ++ if (rockchip_get_mux_route(bank, pin, mux, &route_reg, ++ &route_val)) { ++ ret = regmap_write(regmap, route_reg, route_val); ++ if (ret) ++ return ret; ++ } ++ } ++ ++ data = (mask << (bit + 16)); ++ data |= (mux & mask) << bit; ++ ret = regmap_write(regmap, reg, data); ++ ++ return ret; ++} ++ ++#define PX30_PULL_PMU_OFFSET 0x10 ++#define PX30_PULL_GRF_OFFSET 0x60 ++#define PX30_PULL_BITS_PER_PIN 2 ++#define PX30_PULL_PINS_PER_REG 8 ++#define PX30_PULL_BANK_STRIDE 16 ++ ++static void px30_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, ++ int pin_num, struct regmap **regmap, ++ int *reg, u8 *bit) ++{ ++ struct rockchip_pinctrl_priv *priv = bank->priv; ++ ++ /* The first 32 pins of the first bank are located in PMU */ ++ if (bank->bank_num == 0) { ++ *regmap = priv->regmap_pmu; ++ *reg = PX30_PULL_PMU_OFFSET; ++ } else { ++ *regmap = priv->regmap_base; ++ *reg = PX30_PULL_GRF_OFFSET; ++ ++ /* correct the offset, as we're starting with the 2nd bank */ ++ *reg -= 0x10; ++ *reg += bank->bank_num * PX30_PULL_BANK_STRIDE; ++ } ++ ++ *reg += ((pin_num / PX30_PULL_PINS_PER_REG) * 4); ++ *bit = (pin_num % PX30_PULL_PINS_PER_REG); ++ *bit *= PX30_PULL_BITS_PER_PIN; ++} ++ ++static int px30_set_pull(struct rockchip_pin_bank *bank, ++ int pin_num, int pull) ++{ ++ struct regmap *regmap; ++ int reg, ret; ++ u8 bit, type; ++ u32 data; ++ ++ if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) ++ return -ENOTSUPP; ++ ++ px30_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); ++ type = bank->pull_type[pin_num / 8]; ++ ret = rockchip_translate_pull_value(type, pull); ++ if (ret < 0) { ++ debug("unsupported pull setting %d\n", pull); ++ return ret; ++ } ++ ++ /* enable the write to the equivalent lower bits */ ++ data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); ++ data |= (ret << bit); ++ ret = regmap_write(regmap, reg, data); ++ ++ return ret; ++} ++ ++#define PX30_DRV_PMU_OFFSET 0x20 ++#define PX30_DRV_GRF_OFFSET 0xf0 ++#define PX30_DRV_BITS_PER_PIN 2 ++#define PX30_DRV_PINS_PER_REG 8 ++#define PX30_DRV_BANK_STRIDE 16 ++ ++static void px30_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, ++ int pin_num, struct regmap **regmap, ++ int *reg, u8 *bit) ++{ ++ struct rockchip_pinctrl_priv *priv = bank->priv; ++ ++ /* The first 32 pins of the first bank are located in PMU */ ++ if (bank->bank_num == 0) { ++ *regmap = priv->regmap_pmu; ++ *reg = PX30_DRV_PMU_OFFSET; ++ } else { ++ *regmap = priv->regmap_base; ++ *reg = PX30_DRV_GRF_OFFSET; ++ ++ /* correct the offset, as we're starting with the 2nd bank */ ++ *reg -= 0x10; ++ *reg += bank->bank_num * PX30_DRV_BANK_STRIDE; ++ } ++ ++ *reg += ((pin_num / PX30_DRV_PINS_PER_REG) * 4); ++ *bit = (pin_num % PX30_DRV_PINS_PER_REG); ++ *bit *= PX30_DRV_BITS_PER_PIN; ++} ++ ++static int px30_set_drive(struct rockchip_pin_bank *bank, ++ int pin_num, int strength) ++{ ++ struct regmap *regmap; ++ int reg, ret; ++ u32 data, rmask_bits, temp; ++ u8 bit; ++ int drv_type = bank->drv[pin_num / 8].drv_type; ++ ++ px30_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); ++ ret = rockchip_translate_drive_value(drv_type, strength); ++ if (ret < 0) { ++ debug("unsupported driver strength %d\n", strength); ++ return ret; ++ } ++ ++ switch (drv_type) { ++ case DRV_TYPE_IO_1V8_3V0_AUTO: ++ case DRV_TYPE_IO_3V3_ONLY: ++ rmask_bits = ROCKCHIP_DRV_3BITS_PER_PIN; ++ switch (bit) { ++ case 0 ... 12: ++ /* regular case, nothing to do */ ++ break; ++ case 15: ++ /* ++ * drive-strength offset is special, as it is spread ++ * over 2 registers, the bit data[15] contains bit 0 ++ * of the value while temp[1:0] contains bits 2 and 1 ++ */ ++ data = (ret & 0x1) << 15; ++ temp = (ret >> 0x1) & 0x3; ++ ++ data |= BIT(31); ++ ret = regmap_write(regmap, reg, data); ++ if (ret) ++ return ret; ++ ++ temp |= (0x3 << 16); ++ reg += 0x4; ++ ret = regmap_write(regmap, reg, temp); ++ ++ return ret; ++ case 18 ... 21: ++ /* setting fully enclosed in the second register */ ++ reg += 4; ++ bit -= 16; ++ break; ++ default: ++ debug("unsupported bit: %d for pinctrl drive type: %d\n", ++ bit, drv_type); ++ return -EINVAL; ++ } ++ break; ++ case DRV_TYPE_IO_DEFAULT: ++ case DRV_TYPE_IO_1V8_OR_3V0: ++ case DRV_TYPE_IO_1V8_ONLY: ++ rmask_bits = ROCKCHIP_DRV_BITS_PER_PIN; ++ break; ++ default: ++ debug("unsupported pinctrl drive type: %d\n", ++ drv_type); ++ return -EINVAL; ++ } ++ ++ /* enable the write to the equivalent lower bits */ ++ data = ((1 << rmask_bits) - 1) << (bit + 16); ++ data |= (ret << bit); ++ ret = regmap_write(regmap, reg, data); ++ ++ return ret; ++} ++ ++#define PX30_SCHMITT_PMU_OFFSET 0x38 ++#define PX30_SCHMITT_GRF_OFFSET 0xc0 ++#define PX30_SCHMITT_PINS_PER_PMU_REG 16 ++#define PX30_SCHMITT_BANK_STRIDE 16 ++#define PX30_SCHMITT_PINS_PER_GRF_REG 8 ++ ++static int px30_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, ++ int pin_num, ++ struct regmap **regmap, ++ int *reg, u8 *bit) ++{ ++ struct rockchip_pinctrl_priv *priv = bank->priv; ++ int pins_per_reg; ++ ++ if (bank->bank_num == 0) { ++ *regmap = priv->regmap_pmu; ++ *reg = PX30_SCHMITT_PMU_OFFSET; ++ pins_per_reg = PX30_SCHMITT_PINS_PER_PMU_REG; ++ } else { ++ *regmap = priv->regmap_base; ++ *reg = PX30_SCHMITT_GRF_OFFSET; ++ pins_per_reg = PX30_SCHMITT_PINS_PER_GRF_REG; ++ *reg += (bank->bank_num - 1) * PX30_SCHMITT_BANK_STRIDE; ++ } ++ *reg += ((pin_num / pins_per_reg) * 4); ++ *bit = pin_num % pins_per_reg; ++ ++ return 0; ++} ++ ++static int px30_set_schmitt(struct rockchip_pin_bank *bank, ++ int pin_num, int enable) ++{ ++ struct regmap *regmap; ++ int reg; ++ u8 bit; ++ u32 data; ++ ++ px30_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit); ++ /* enable the write to the equivalent lower bits */ ++ data = BIT(bit + 16) | (enable << bit); ++ ++ return regmap_write(regmap, reg, data); ++} ++ ++static struct rockchip_pin_bank px30_pin_banks[] = { ++ PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, ++ IOMUX_SOURCE_PMU, ++ IOMUX_SOURCE_PMU, ++ IOMUX_SOURCE_PMU ++ ), ++ PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT ++ ), ++ PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT ++ ), ++ PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT ++ ), ++}; ++ ++static struct rockchip_pin_ctrl px30_pin_ctrl = { ++ .pin_banks = px30_pin_banks, ++ .nr_banks = ARRAY_SIZE(px30_pin_banks), ++ .grf_mux_offset = 0x0, ++ .pmu_mux_offset = 0x0, ++ .grf_drv_offset = 0xf0, ++ .pmu_drv_offset = 0x20, ++ .iomux_routes = px30_mux_route_data, ++ .niomux_routes = ARRAY_SIZE(px30_mux_route_data), ++ .set_mux = px30_set_mux, ++ .set_pull = px30_set_pull, ++ .set_drive = px30_set_drive, ++ .set_schmitt = px30_set_schmitt, ++}; ++ ++static const struct udevice_id px30_pinctrl_ids[] = { ++ { ++ .compatible = "rockchip,px30-pinctrl", ++ .data = (ulong)&px30_pin_ctrl ++ }, ++ { } ++}; ++ ++U_BOOT_DRIVER(pinctrl_px30) = { ++ .name = "rockchip_px30_pinctrl", ++ .id = UCLASS_PINCTRL, ++ .of_match = px30_pinctrl_ids, ++ .priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv), ++ .ops = &rockchip_pinctrl_ops, ++#if !CONFIG_IS_ENABLED(OF_PLATDATA) ++ .bind = dm_scan_fdt_dev, ++#endif ++ .probe = rockchip_pinctrl_probe, ++}; + +From patchwork Thu Oct 24 23:27:55 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: =?utf-8?q?Heiko_St=C3=BCbner?= <heiko@sntech.de> +X-Patchwork-Id: 1183659 +X-Patchwork-Delegate: ykai007@gmail.com +Return-Path: <u-boot-bounces@lists.denx.de> +X-Original-To: incoming@patchwork.ozlabs.org +Delivered-To: patchwork-incoming@bilbo.ozlabs.org +Authentication-Results: ozlabs.org; + spf=none (no SPF record) smtp.mailfrom=lists.denx.de + (client-ip=81.169.180.215; helo=lists.denx.de; + envelope-from=u-boot-bounces@lists.denx.de; + receiver=<UNKNOWN>) +Authentication-Results: ozlabs.org; + dmarc=none (p=none dis=none) header.from=sntech.de +Received: from lists.denx.de (dione.denx.de [81.169.180.215]) + by ozlabs.org (Postfix) with ESMTP id 46zk730ZxBz9sPL + for <incoming@patchwork.ozlabs.org>; + Fri, 25 Oct 2019 10:32:31 +1100 (AEDT) +Received: by lists.denx.de (Postfix, from userid 105) + id C00E2C21E12; Thu, 24 Oct 2019 23:30:13 +0000 (UTC) +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de +X-Spam-Level: +X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable + autolearn_force=no version=3.4.0 +Received: from lists.denx.de (localhost [IPv6:::1]) + by lists.denx.de (Postfix) with ESMTP id F0E2EC21E62; + Thu, 24 Oct 2019 23:28:22 +0000 (UTC) +Received: by lists.denx.de (Postfix, from userid 105) + id 9226BC21D74; Thu, 24 Oct 2019 23:28:18 +0000 (UTC) +Received: from gloria.sntech.de (gloria.sntech.de [185.11.138.130]) + by lists.denx.de (Postfix) with ESMTPS id 66177C21DA1 + for <u-boot@lists.denx.de>; Thu, 24 Oct 2019 23:28:17 +0000 (UTC) +Received: from ip5f5a6266.dynamic.kabel-deutschland.de ([95.90.98.102] + helo=phil.fritz.box) by gloria.sntech.de with esmtpsa + (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) + (Exim 4.89) (envelope-from <heiko@sntech.de>) + id 1iNmWe-0002cR-FK; Fri, 25 Oct 2019 01:28:16 +0200 +From: Heiko Stuebner <heiko@sntech.de> +To: u-boot@lists.denx.de +Date: Fri, 25 Oct 2019 01:27:55 +0200 +Message-Id: <20191024232803.10338-5-heiko@sntech.de> +X-Mailer: git-send-email 2.23.0 +In-Reply-To: <20191024232803.10338-1-heiko@sntech.de> +References: <20191024232803.10338-1-heiko@sntech.de> +MIME-Version: 1.0 +Cc: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>, + joe.hershberger@ni.com, christoph.muellner@theobroma-systems.com +Subject: [U-Boot] [PATCH 04/12] rockchip: clk: add px30 clock driver +X-BeenThere: u-boot@lists.denx.de +X-Mailman-Version: 2.1.18 +Precedence: list +List-Id: U-Boot discussion <u-boot.lists.denx.de> +List-Unsubscribe: <https://lists.denx.de/options/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=unsubscribe> +List-Archive: <http://lists.denx.de/pipermail/u-boot/> +List-Post: <mailto:u-boot@lists.denx.de> +List-Help: <mailto:u-boot-request@lists.denx.de?subject=help> +List-Subscribe: <https://lists.denx.de/listinfo/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=subscribe> +Errors-To: u-boot-bounces@lists.denx.de +Sender: "U-Boot" <u-boot-bounces@lists.denx.de> + +From: Kever Yang <kever.yang@rock-chips.com> + +The px30 contains 2 separate clock controllers, pmucru and cru. +Add drivers for them. + +Signed-off-by: Kever Yang <kever.yang@rock-chips.com> +Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com> +--- + arch/arm/include/asm/arch-rockchip/cru_px30.h | 432 +++++ + drivers/clk/rockchip/Makefile | 1 + + drivers/clk/rockchip/clk_px30.c | 1630 +++++++++++++++++ + include/dt-bindings/clock/px30-cru.h | 389 ++++ + 4 files changed, 2452 insertions(+) + create mode 100644 arch/arm/include/asm/arch-rockchip/cru_px30.h + create mode 100644 drivers/clk/rockchip/clk_px30.c + create mode 100644 include/dt-bindings/clock/px30-cru.h + +diff --git a/arch/arm/include/asm/arch-rockchip/cru_px30.h b/arch/arm/include/asm/arch-rockchip/cru_px30.h +new file mode 100644 +index 0000000000..7d9fd181ac +--- /dev/null ++++ b/arch/arm/include/asm/arch-rockchip/cru_px30.h +@@ -0,0 +1,432 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * (C) Copyright 2017 Rockchip Electronics Co., Ltd. ++ */ ++#ifndef _ASM_ARCH_CRU_PX30_H ++#define _ASM_ARCH_CRU_PX30_H ++ ++#include <common.h> ++ ++#define MHz 1000000 ++#define KHz 1000 ++#define OSC_HZ (24 * MHz) ++ ++#define APLL_HZ (600 * MHz) ++#define GPLL_HZ (1200 * MHz) ++#define NPLL_HZ (1188 * MHz) ++#define ACLK_BUS_HZ (200 * MHz) ++#define HCLK_BUS_HZ (150 * MHz) ++#define PCLK_BUS_HZ (100 * MHz) ++#define ACLK_PERI_HZ (200 * MHz) ++#define HCLK_PERI_HZ (150 * MHz) ++#define PCLK_PMU_HZ (100 * MHz) ++ ++/* PX30 pll id */ ++enum px30_pll_id { ++ APLL, ++ DPLL, ++ CPLL, ++ NPLL, ++ GPLL, ++ PLL_COUNT, ++}; ++ ++struct px30_clk_priv { ++ struct px30_cru *cru; ++ ulong gpll_hz; ++}; ++ ++struct px30_pmuclk_priv { ++ struct px30_pmucru *pmucru; ++ ulong gpll_hz; ++}; ++ ++struct px30_pll { ++ unsigned int con0; ++ unsigned int con1; ++ unsigned int con2; ++ unsigned int con3; ++ unsigned int con4; ++ unsigned int reserved0[3]; ++}; ++ ++struct px30_cru { ++ struct px30_pll pll[4]; ++ unsigned int reserved1[8]; ++ unsigned int mode; ++ unsigned int misc; ++ unsigned int reserved2[2]; ++ unsigned int glb_cnt_th; ++ unsigned int glb_rst_st; ++ unsigned int glb_srst_fst; ++ unsigned int glb_srst_snd; ++ unsigned int glb_rst_con; ++ unsigned int reserved3[7]; ++ unsigned int hwffc_con0; ++ unsigned int reserved4; ++ unsigned int hwffc_th; ++ unsigned int hwffc_intst; ++ unsigned int apll_con0_s; ++ unsigned int apll_con1_s; ++ unsigned int clksel_con0_s; ++ unsigned int reserved5; ++ unsigned int clksel_con[60]; ++ unsigned int reserved6[4]; ++ unsigned int clkgate_con[18]; ++ unsigned int reserved7[(0x280 - 0x244) / 4 - 1]; ++ unsigned int ssgtbl[32]; ++ unsigned int softrst_con[12]; ++ unsigned int reserved8[(0x380 - 0x32c) / 4 - 1]; ++ unsigned int sdmmc_con[2]; ++ unsigned int sdio_con[2]; ++ unsigned int emmc_con[2]; ++ unsigned int reserved9[(0x400 - 0x394) / 4 - 1]; ++ unsigned int autocs_con[8]; ++}; ++ ++check_member(px30_cru, autocs_con[7], 0x41c); ++ ++struct px30_pmucru { ++ struct px30_pll pll; ++ unsigned int pmu_mode; ++ unsigned int reserved1[7]; ++ unsigned int pmu_clksel_con[6]; ++ unsigned int reserved2[10]; ++ unsigned int pmu_clkgate_con[2]; ++ unsigned int reserved3[14]; ++ unsigned int pmu_autocs_con[2]; ++}; ++ ++check_member(px30_pmucru, pmu_autocs_con[1], 0xc4); ++ ++struct pll_rate_table { ++ unsigned long rate; ++ unsigned int fbdiv; ++ unsigned int postdiv1; ++ unsigned int refdiv; ++ unsigned int postdiv2; ++ unsigned int dsmpd; ++ unsigned int frac; ++}; ++ ++struct cpu_rate_table { ++ unsigned long rate; ++ unsigned int aclk_div; ++ unsigned int pclk_div; ++}; ++ ++enum { ++ /* PLLCON0*/ ++ PLL_BP_SHIFT = 15, ++ PLL_POSTDIV1_SHIFT = 12, ++ PLL_POSTDIV1_MASK = 7 << PLL_POSTDIV1_SHIFT, ++ PLL_FBDIV_SHIFT = 0, ++ PLL_FBDIV_MASK = 0xfff, ++ ++ /* PLLCON1 */ ++ PLL_PDSEL_SHIFT = 15, ++ PLL_PD1_SHIFT = 14, ++ PLL_PD_SHIFT = 13, ++ PLL_PD_MASK = 1 << PLL_PD_SHIFT, ++ PLL_DSMPD_SHIFT = 12, ++ PLL_DSMPD_MASK = 1 << PLL_DSMPD_SHIFT, ++ PLL_LOCK_STATUS_SHIFT = 10, ++ PLL_LOCK_STATUS_MASK = 1 << PLL_LOCK_STATUS_SHIFT, ++ PLL_POSTDIV2_SHIFT = 6, ++ PLL_POSTDIV2_MASK = 7 << PLL_POSTDIV2_SHIFT, ++ PLL_REFDIV_SHIFT = 0, ++ PLL_REFDIV_MASK = 0x3f, ++ ++ /* PLLCON2 */ ++ PLL_FOUT4PHASEPD_SHIFT = 27, ++ PLL_FOUTVCOPD_SHIFT = 26, ++ PLL_FOUTPOSTDIVPD_SHIFT = 25, ++ PLL_DACPD_SHIFT = 24, ++ PLL_FRAC_DIV = 0xffffff, ++ ++ /* CRU_MODE */ ++ PLLMUX_FROM_XIN24M = 0, ++ PLLMUX_FROM_PLL, ++ PLLMUX_FROM_RTC32K, ++ USBPHY480M_MODE_SHIFT = 8, ++ USBPHY480M_MODE_MASK = 3 << USBPHY480M_MODE_SHIFT, ++ NPLL_MODE_SHIFT = 6, ++ NPLL_MODE_MASK = 3 << NPLL_MODE_SHIFT, ++ DPLL_MODE_SHIFT = 4, ++ DPLL_MODE_MASK = 3 << DPLL_MODE_SHIFT, ++ CPLL_MODE_SHIFT = 2, ++ CPLL_MODE_MASK = 3 << CPLL_MODE_SHIFT, ++ APLL_MODE_SHIFT = 0, ++ APLL_MODE_MASK = 3 << APLL_MODE_SHIFT, ++ ++ /* CRU_CLK_SEL0_CON */ ++ CORE_ACLK_DIV_SHIFT = 12, ++ CORE_ACLK_DIV_MASK = 0x07 << CORE_ACLK_DIV_SHIFT, ++ CORE_DBG_DIV_SHIFT = 8, ++ CORE_DBG_DIV_MASK = 0x03 << CORE_DBG_DIV_SHIFT, ++ CORE_CLK_PLL_SEL_SHIFT = 7, ++ CORE_CLK_PLL_SEL_MASK = 1 << CORE_CLK_PLL_SEL_SHIFT, ++ CORE_CLK_PLL_SEL_APLL = 0, ++ CORE_CLK_PLL_SEL_GPLL, ++ CORE_DIV_CON_SHIFT = 0, ++ CORE_DIV_CON_MASK = 0x0f << CORE_DIV_CON_SHIFT, ++ ++ /* CRU_CLK_SEL3_CON */ ++ ACLK_VO_PLL_SHIFT = 6, ++ ACLK_VO_PLL_MASK = 0x3 << ACLK_VO_PLL_SHIFT, ++ ACLK_VO_SEL_GPLL = 0, ++ ACLK_VO_SEL_CPLL, ++ ACLK_VO_SEL_NPLL, ++ ACLK_VO_DIV_SHIFT = 0, ++ ACLK_VO_DIV_MASK = 0x1f << ACLK_VO_DIV_SHIFT, ++ ++ /* CRU_CLK_SEL5_CON */ ++ DCLK_VOPB_SEL_SHIFT = 14, ++ DCLK_VOPB_SEL_MASK = 0x3 << DCLK_VOPB_SEL_SHIFT, ++ DCLK_VOPB_SEL_DIVOUT = 0, ++ DCLK_VOPB_SEL_FRACOUT, ++ DCLK_VOPB_SEL_24M, ++ DCLK_VOPB_PLL_SEL_SHIFT = 11, ++ DCLK_VOPB_PLL_SEL_MASK = 0x1 << DCLK_VOPB_PLL_SEL_SHIFT, ++ DCLK_VOPB_PLL_SEL_CPLL = 0, ++ DCLK_VOPB_PLL_SEL_NPLL, ++ DCLK_VOPB_DIV_SHIFT = 0, ++ DCLK_VOPB_DIV_MASK = 0xff, ++ ++ /* CRU_CLK_SEL8_CON */ ++ DCLK_VOPL_SEL_SHIFT = 14, ++ DCLK_VOPL_SEL_MASK = 0x3 << DCLK_VOPL_SEL_SHIFT, ++ DCLK_VOPL_SEL_DIVOUT = 0, ++ DCLK_VOPL_SEL_FRACOUT, ++ DCLK_VOPL_SEL_24M, ++ DCLK_VOPL_PLL_SEL_SHIFT = 11, ++ DCLK_VOPL_PLL_SEL_MASK = 0x1 << DCLK_VOPL_PLL_SEL_SHIFT, ++ DCLK_VOPL_PLL_SEL_NPLL = 0, ++ DCLK_VOPL_PLL_SEL_CPLL, ++ DCLK_VOPL_DIV_SHIFT = 0, ++ DCLK_VOPL_DIV_MASK = 0xff, ++ ++ /* CRU_CLK_SEL14_CON */ ++ PERI_PLL_SEL_SHIFT = 15, ++ PERI_PLL_SEL_MASK = 3 << PERI_PLL_SEL_SHIFT, ++ PERI_PLL_GPLL = 0, ++ PERI_PLL_CPLL, ++ PERI_HCLK_DIV_SHIFT = 8, ++ PERI_HCLK_DIV_MASK = 0x1f << PERI_HCLK_DIV_SHIFT, ++ PERI_ACLK_DIV_SHIFT = 0, ++ PERI_ACLK_DIV_MASK = 0x1f << PERI_ACLK_DIV_SHIFT, ++ ++ /* CRU_CLKSEL15_CON */ ++ NANDC_CLK_SEL_SHIFT = 15, ++ NANDC_CLK_SEL_MASK = 0x1 << NANDC_CLK_SEL_SHIFT, ++ NANDC_CLK_SEL_NANDC = 0, ++ NANDC_CLK_SEL_NANDC_DIV50, ++ NANDC_DIV50_SHIFT = 8, ++ NANDC_DIV50_MASK = 0x1f << NANDC_DIV50_SHIFT, ++ NANDC_PLL_SHIFT = 6, ++ NANDC_PLL_MASK = 0x3 << NANDC_PLL_SHIFT, ++ NANDC_SEL_GPLL = 0, ++ NANDC_SEL_CPLL, ++ NANDC_SEL_NPLL, ++ NANDC_DIV_SHIFT = 0, ++ NANDC_DIV_MASK = 0x1f << NANDC_DIV_SHIFT, ++ ++ /* CRU_CLKSEL20_CON */ ++ EMMC_PLL_SHIFT = 14, ++ EMMC_PLL_MASK = 3 << EMMC_PLL_SHIFT, ++ EMMC_SEL_GPLL = 0, ++ EMMC_SEL_CPLL, ++ EMMC_SEL_NPLL, ++ EMMC_SEL_24M, ++ EMMC_DIV_SHIFT = 0, ++ EMMC_DIV_MASK = 0xff << EMMC_DIV_SHIFT, ++ ++ /* CRU_CLKSEL21_CON */ ++ EMMC_CLK_SEL_SHIFT = 15, ++ EMMC_CLK_SEL_MASK = 1 << EMMC_CLK_SEL_SHIFT, ++ EMMC_CLK_SEL_EMMC = 0, ++ EMMC_CLK_SEL_EMMC_DIV50, ++ EMMC_DIV50_SHIFT = 0, ++ EMMC_DIV50_MASK = 0xff << EMMC_DIV_SHIFT, ++ ++ /* CRU_CLKSEL22_CON */ ++ GMAC_PLL_SEL_SHIFT = 14, ++ GMAC_PLL_SEL_MASK = 3 << GMAC_PLL_SEL_SHIFT, ++ GMAC_PLL_SEL_GPLL = 0, ++ GMAC_PLL_SEL_CPLL, ++ GMAC_PLL_SEL_NPLL, ++ CLK_GMAC_DIV_SHIFT = 8, ++ CLK_GMAC_DIV_MASK = 0x1f << CLK_GMAC_DIV_SHIFT, ++ SFC_PLL_SEL_SHIFT = 7, ++ SFC_PLL_SEL_MASK = 1 << SFC_PLL_SEL_SHIFT, ++ SFC_DIV_CON_SHIFT = 0, ++ SFC_DIV_CON_MASK = 0x7f, ++ ++ /* CRU_CLK_SEL23_CON */ ++ BUS_PLL_SEL_SHIFT = 15, ++ BUS_PLL_SEL_MASK = 1 << BUS_PLL_SEL_SHIFT, ++ BUS_PLL_SEL_GPLL = 0, ++ BUS_PLL_SEL_CPLL, ++ BUS_ACLK_DIV_SHIFT = 8, ++ BUS_ACLK_DIV_MASK = 0x1f << BUS_ACLK_DIV_SHIFT, ++ RMII_CLK_SEL_SHIFT = 7, ++ RMII_CLK_SEL_MASK = 1 << RMII_CLK_SEL_SHIFT, ++ RMII_CLK_SEL_10M = 0, ++ RMII_CLK_SEL_100M, ++ RMII_EXTCLK_SEL_SHIFT = 6, ++ RMII_EXTCLK_SEL_MASK = 1 << RMII_EXTCLK_SEL_SHIFT, ++ RMII_EXTCLK_SEL_INT = 0, ++ RMII_EXTCLK_SEL_EXT, ++ PCLK_GMAC_DIV_SHIFT = 0, ++ PCLK_GMAC_DIV_MASK = 0x0f << PCLK_GMAC_DIV_SHIFT, ++ ++ /* CRU_CLK_SEL24_CON */ ++ BUS_PCLK_DIV_SHIFT = 8, ++ BUS_PCLK_DIV_MASK = 3 << BUS_PCLK_DIV_SHIFT, ++ BUS_HCLK_DIV_SHIFT = 0, ++ BUS_HCLK_DIV_MASK = 0x1f << BUS_HCLK_DIV_SHIFT, ++ ++ /* CRU_CLK_SEL25_CON */ ++ CRYPTO_APK_SEL_SHIFT = 14, ++ CRYPTO_APK_PLL_SEL_MASK = 3 << CRYPTO_APK_SEL_SHIFT, ++ CRYPTO_PLL_SEL_GPLL = 0, ++ CRYPTO_PLL_SEL_CPLL, ++ CRYPTO_PLL_SEL_NPLL = 0, ++ CRYPTO_APK_DIV_SHIFT = 8, ++ CRYPTO_APK_DIV_MASK = 0x1f << CRYPTO_APK_DIV_SHIFT, ++ CRYPTO_PLL_SEL_SHIFT = 6, ++ CRYPTO_PLL_SEL_MASK = 3 << CRYPTO_PLL_SEL_SHIFT, ++ CRYPTO_DIV_SHIFT = 0, ++ CRYPTO_DIV_MASK = 0x1f << CRYPTO_DIV_SHIFT, ++ ++ /* CRU_CLK_SEL30_CON */ ++ CLK_I2S1_DIV_CON_MASK = 0x7f, ++ CLK_I2S1_PLL_SEL_MASK = 0X1 << 8, ++ CLK_I2S1_PLL_SEL_GPLL = 0X0 << 8, ++ CLK_I2S1_PLL_SEL_NPLL = 0X1 << 8, ++ CLK_I2S1_SEL_MASK = 0x3 << 10, ++ CLK_I2S1_SEL_I2S1 = 0x0 << 10, ++ CLK_I2S1_SEL_FRAC = 0x1 << 10, ++ CLK_I2S1_SEL_MCLK_IN = 0x2 << 10, ++ CLK_I2S1_SEL_OSC = 0x3 << 10, ++ CLK_I2S1_OUT_SEL_MASK = 0x1 << 15, ++ CLK_I2S1_OUT_SEL_I2S1 = 0x0 << 15, ++ CLK_I2S1_OUT_SEL_OSC = 0x1 << 15, ++ ++ /* CRU_CLK_SEL31_CON */ ++ CLK_I2S1_FRAC_NUMERATOR_SHIFT = 16, ++ CLK_I2S1_FRAC_NUMERATOR_MASK = 0xffff << 16, ++ CLK_I2S1_FRAC_DENOMINATOR_SHIFT = 0, ++ CLK_I2S1_FRAC_DENOMINATOR_MASK = 0xffff, ++ ++ /* CRU_CLK_SEL34_CON */ ++ UART1_PLL_SEL_SHIFT = 14, ++ UART1_PLL_SEL_MASK = 3 << UART1_PLL_SEL_SHIFT, ++ UART1_PLL_SEL_GPLL = 0, ++ UART1_PLL_SEL_24M, ++ UART1_PLL_SEL_480M, ++ UART1_PLL_SEL_NPLL, ++ UART1_DIV_CON_SHIFT = 0, ++ UART1_DIV_CON_MASK = 0x1f << UART1_DIV_CON_SHIFT, ++ ++ /* CRU_CLK_SEL35_CON */ ++ UART1_CLK_SEL_SHIFT = 14, ++ UART1_CLK_SEL_MASK = 3 << UART1_PLL_SEL_SHIFT, ++ UART1_CLK_SEL_UART1 = 0, ++ UART1_CLK_SEL_UART1_NP5, ++ UART1_CLK_SEL_UART1_FRAC, ++ UART1_DIVNP5_SHIFT = 0, ++ UART1_DIVNP5_MASK = 0x1f << UART1_DIVNP5_SHIFT, ++ ++ /* CRU_CLK_SEL37_CON */ ++ UART2_PLL_SEL_SHIFT = 14, ++ UART2_PLL_SEL_MASK = 3 << UART2_PLL_SEL_SHIFT, ++ UART2_PLL_SEL_GPLL = 0, ++ UART2_PLL_SEL_24M, ++ UART2_PLL_SEL_480M, ++ UART2_PLL_SEL_NPLL, ++ UART2_DIV_CON_SHIFT = 0, ++ UART2_DIV_CON_MASK = 0x1f << UART2_DIV_CON_SHIFT, ++ ++ /* CRU_CLK_SEL38_CON */ ++ UART2_CLK_SEL_SHIFT = 14, ++ UART2_CLK_SEL_MASK = 3 << UART2_PLL_SEL_SHIFT, ++ UART2_CLK_SEL_UART2 = 0, ++ UART2_CLK_SEL_UART2_NP5, ++ UART2_CLK_SEL_UART2_FRAC, ++ UART2_DIVNP5_SHIFT = 0, ++ UART2_DIVNP5_MASK = 0x1f << UART2_DIVNP5_SHIFT, ++ ++ /* CRU_CLK_SEL46_CON */ ++ UART5_PLL_SEL_SHIFT = 14, ++ UART5_PLL_SEL_MASK = 3 << UART5_PLL_SEL_SHIFT, ++ UART5_PLL_SEL_GPLL = 0, ++ UART5_PLL_SEL_24M, ++ UART5_PLL_SEL_480M, ++ UART5_PLL_SEL_NPLL, ++ UART5_DIV_CON_SHIFT = 0, ++ UART5_DIV_CON_MASK = 0x1f << UART5_DIV_CON_SHIFT, ++ ++ /* CRU_CLK_SEL47_CON */ ++ UART5_CLK_SEL_SHIFT = 14, ++ UART5_CLK_SEL_MASK = 3 << UART5_PLL_SEL_SHIFT, ++ UART5_CLK_SEL_UART5 = 0, ++ UART5_CLK_SEL_UART5_NP5, ++ UART5_CLK_SEL_UART5_FRAC, ++ UART5_DIVNP5_SHIFT = 0, ++ UART5_DIVNP5_MASK = 0x1f << UART5_DIVNP5_SHIFT, ++ ++ /* CRU_CLK_SEL49_CON */ ++ CLK_I2C_PLL_SEL_GPLL = 0, ++ CLK_I2C_PLL_SEL_24M, ++ CLK_I2C_DIV_CON_MASK = 0x7f, ++ CLK_I2C_PLL_SEL_MASK = 1, ++ CLK_I2C1_PLL_SEL_SHIFT = 15, ++ CLK_I2C1_DIV_CON_SHIFT = 8, ++ CLK_I2C0_PLL_SEL_SHIFT = 7, ++ CLK_I2C0_DIV_CON_SHIFT = 0, ++ ++ /* CRU_CLK_SEL50_CON */ ++ CLK_I2C3_PLL_SEL_SHIFT = 15, ++ CLK_I2C3_DIV_CON_SHIFT = 8, ++ CLK_I2C2_PLL_SEL_SHIFT = 7, ++ CLK_I2C2_DIV_CON_SHIFT = 0, ++ ++ /* CRU_CLK_SEL52_CON */ ++ CLK_PWM_PLL_SEL_GPLL = 0, ++ CLK_PWM_PLL_SEL_24M, ++ CLK_PWM_DIV_CON_MASK = 0x7f, ++ CLK_PWM_PLL_SEL_MASK = 1, ++ CLK_PWM1_PLL_SEL_SHIFT = 15, ++ CLK_PWM1_DIV_CON_SHIFT = 8, ++ CLK_PWM0_PLL_SEL_SHIFT = 7, ++ CLK_PWM0_DIV_CON_SHIFT = 0, ++ ++ /* CRU_CLK_SEL53_CON */ ++ CLK_SPI_PLL_SEL_GPLL = 0, ++ CLK_SPI_PLL_SEL_24M, ++ CLK_SPI_DIV_CON_MASK = 0x7f, ++ CLK_SPI_PLL_SEL_MASK = 1, ++ CLK_SPI1_PLL_SEL_SHIFT = 15, ++ CLK_SPI1_DIV_CON_SHIFT = 8, ++ CLK_SPI0_PLL_SEL_SHIFT = 7, ++ CLK_SPI0_DIV_CON_SHIFT = 0, ++ ++ /* CRU_CLK_SEL55_CON */ ++ CLK_SARADC_DIV_CON_SHIFT = 0, ++ CLK_SARADC_DIV_CON_MASK = 0x7ff, ++ ++ /* CRU_CLK_GATE10_CON */ ++ CLK_I2S1_OUT_MCLK_PAD_MASK = 0x1 << 9, ++ CLK_I2S1_OUT_MCLK_PAD_ENABLE = 0x1 << 9, ++ CLK_I2S1_OUT_MCLK_PAD_DISABLE = 0x0 << 9, ++ ++ /* CRU_PMU_MODE */ ++ GPLL_MODE_SHIFT = 0, ++ GPLL_MODE_MASK = 3 << GPLL_MODE_SHIFT, ++ ++ /* CRU_PMU_CLK_SEL0_CON */ ++ CLK_PMU_PCLK_DIV_SHIFT = 0, ++ CLK_PMU_PCLK_DIV_MASK = 0x1f << CLK_PMU_PCLK_DIV_SHIFT, ++}; ++#endif +diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile +index 41cfb7ad3f..f9134fd51f 100644 +--- a/drivers/clk/rockchip/Makefile ++++ b/drivers/clk/rockchip/Makefile +@@ -3,6 +3,7 @@ + # Copyright (c) 2017 Rockchip Electronics Co., Ltd + # + ++obj-$(CONFIG_ROCKCHIP_PX30) += clk_px30.o + obj-$(CONFIG_ROCKCHIP_RK3036) += clk_rk3036.o + obj-$(CONFIG_ROCKCHIP_RK3128) += clk_rk3128.o + obj-$(CONFIG_ROCKCHIP_RK3188) += clk_rk3188.o +diff --git a/drivers/clk/rockchip/clk_px30.c b/drivers/clk/rockchip/clk_px30.c +new file mode 100644 +index 0000000000..36764c128b +--- /dev/null ++++ b/drivers/clk/rockchip/clk_px30.c +@@ -0,0 +1,1630 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * (C) Copyright 2017 Rockchip Electronics Co., Ltd ++ */ ++ ++#include <common.h> ++#include <bitfield.h> ++#include <clk-uclass.h> ++#include <dm.h> ++#include <errno.h> ++#include <syscon.h> ++#include <asm/arch-rockchip/clock.h> ++#include <asm/arch-rockchip/cru_px30.h> ++#include <asm/arch-rockchip/hardware.h> ++#include <asm/io.h> ++#include <dm/lists.h> ++#include <dt-bindings/clock/px30-cru.h> ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++enum { ++ VCO_MAX_HZ = 3200U * 1000000, ++ VCO_MIN_HZ = 800 * 1000000, ++ OUTPUT_MAX_HZ = 3200U * 1000000, ++ OUTPUT_MIN_HZ = 24 * 1000000, ++}; ++ ++#define PX30_VOP_PLL_LIMIT 600000000 ++ ++#define PX30_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1, \ ++ _postdiv2, _dsmpd, _frac) \ ++{ \ ++ .rate = _rate##U, \ ++ .fbdiv = _fbdiv, \ ++ .postdiv1 = _postdiv1, \ ++ .refdiv = _refdiv, \ ++ .postdiv2 = _postdiv2, \ ++ .dsmpd = _dsmpd, \ ++ .frac = _frac, \ ++} ++ ++#define PX30_CPUCLK_RATE(_rate, _aclk_div, _pclk_div) \ ++{ \ ++ .rate = _rate##U, \ ++ .aclk_div = _aclk_div, \ ++ .pclk_div = _pclk_div, \ ++} ++ ++#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) ++ ++#define PX30_CLK_DUMP(_id, _name, _iscru) \ ++{ \ ++ .id = _id, \ ++ .name = _name, \ ++ .is_cru = _iscru, \ ++} ++ ++static struct pll_rate_table px30_pll_rates[] = { ++ /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ ++ PX30_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0), ++ PX30_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0), ++ PX30_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0), ++ PX30_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0), ++ PX30_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0), ++ PX30_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0), ++ PX30_PLL_RATE(600000000, 1, 75, 3, 1, 1, 0), ++}; ++ ++static struct cpu_rate_table px30_cpu_rates[] = { ++ PX30_CPUCLK_RATE(1200000000, 1, 5), ++ PX30_CPUCLK_RATE(1008000000, 1, 5), ++ PX30_CPUCLK_RATE(816000000, 1, 3), ++ PX30_CPUCLK_RATE(600000000, 1, 3), ++ PX30_CPUCLK_RATE(408000000, 1, 1), ++}; ++ ++static u8 pll_mode_shift[PLL_COUNT] = { ++ APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT, ++ NPLL_MODE_SHIFT, GPLL_MODE_SHIFT ++}; ++ ++static u32 pll_mode_mask[PLL_COUNT] = { ++ APLL_MODE_MASK, DPLL_MODE_MASK, CPLL_MODE_MASK, ++ NPLL_MODE_MASK, GPLL_MODE_MASK ++}; ++ ++static struct pll_rate_table auto_table; ++ ++static ulong px30_clk_get_pll_rate(struct px30_clk_priv *priv, ++ enum px30_pll_id pll_id); ++ ++static struct pll_rate_table *pll_clk_set_by_auto(u32 drate) ++{ ++ struct pll_rate_table *rate = &auto_table; ++ u32 ref_khz = OSC_HZ / KHz, refdiv, fbdiv = 0; ++ u32 postdiv1, postdiv2 = 1; ++ u32 fref_khz; ++ u32 diff_khz, best_diff_khz; ++ const u32 max_refdiv = 63, max_fbdiv = 3200, min_fbdiv = 16; ++ const u32 max_postdiv1 = 7, max_postdiv2 = 7; ++ u32 vco_khz; ++ u32 rate_khz = drate / KHz; ++ ++ if (!drate) { ++ printf("%s: the frequency can't be 0 Hz\n", __func__); ++ return NULL; ++ } ++ ++ postdiv1 = DIV_ROUND_UP(VCO_MIN_HZ / 1000, rate_khz); ++ if (postdiv1 > max_postdiv1) { ++ postdiv2 = DIV_ROUND_UP(postdiv1, max_postdiv1); ++ postdiv1 = DIV_ROUND_UP(postdiv1, postdiv2); ++ } ++ ++ vco_khz = rate_khz * postdiv1 * postdiv2; ++ ++ if (vco_khz < (VCO_MIN_HZ / KHz) || vco_khz > (VCO_MAX_HZ / KHz) || ++ postdiv2 > max_postdiv2) { ++ printf("%s: Cannot find out a supported VCO for Freq (%uHz)\n", ++ __func__, rate_khz); ++ return NULL; ++ } ++ ++ rate->postdiv1 = postdiv1; ++ rate->postdiv2 = postdiv2; ++ ++ best_diff_khz = vco_khz; ++ for (refdiv = 1; refdiv < max_refdiv && best_diff_khz; refdiv++) { ++ fref_khz = ref_khz / refdiv; ++ ++ fbdiv = vco_khz / fref_khz; ++ if (fbdiv >= max_fbdiv || fbdiv <= min_fbdiv) ++ continue; ++ ++ diff_khz = vco_khz - fbdiv * fref_khz; ++ if (fbdiv + 1 < max_fbdiv && diff_khz > fref_khz / 2) { ++ fbdiv++; ++ diff_khz = fref_khz - diff_khz; ++ } ++ ++ if (diff_khz >= best_diff_khz) ++ continue; ++ ++ best_diff_khz = diff_khz; ++ rate->refdiv = refdiv; ++ rate->fbdiv = fbdiv; ++ } ++ ++ if (best_diff_khz > 4 * (MHz / KHz)) { ++ printf("%s: Failed to match output frequency %u bestis %u Hz\n", ++ __func__, rate_khz, ++ best_diff_khz * KHz); ++ return NULL; ++ } ++ ++ return rate; ++} ++ ++static const struct pll_rate_table *get_pll_settings(unsigned long rate) ++{ ++ unsigned int rate_count = ARRAY_SIZE(px30_pll_rates); ++ int i; ++ ++ for (i = 0; i < rate_count; i++) { ++ if (rate == px30_pll_rates[i].rate) ++ return &px30_pll_rates[i]; ++ } ++ ++ return pll_clk_set_by_auto(rate); ++} ++ ++static const struct cpu_rate_table *get_cpu_settings(unsigned long rate) ++{ ++ unsigned int rate_count = ARRAY_SIZE(px30_cpu_rates); ++ int i; ++ ++ for (i = 0; i < rate_count; i++) { ++ if (rate == px30_cpu_rates[i].rate) ++ return &px30_cpu_rates[i]; ++ } ++ ++ return NULL; ++} ++ ++/* ++ * How to calculate the PLL(from TRM V0.3 Part 1 Page 63): ++ * Formulas also embedded within the Fractional PLL Verilog model: ++ * If DSMPD = 1 (DSM is disabled, "integer mode") ++ * FOUTVCO = FREF / REFDIV * FBDIV ++ * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2 ++ * Where: ++ * FOUTVCO = Fractional PLL non-divided output frequency ++ * FOUTPOSTDIV = Fractional PLL divided output frequency ++ * (output of second post divider) ++ * FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input) ++ * REFDIV = Fractional PLL input reference clock divider ++ * FBDIV = Integer value programmed into feedback divide ++ * ++ */ ++static int rkclk_set_pll(struct px30_pll *pll, unsigned int *mode, ++ enum px30_pll_id pll_id, ++ unsigned long drate) ++{ ++ const struct pll_rate_table *rate; ++ uint vco_hz, output_hz; ++ ++ rate = get_pll_settings(drate); ++ if (!rate) { ++ printf("%s unsupport rate\n", __func__); ++ return -EINVAL; ++ } ++ ++ /* All PLLs have same VCO and output frequency range restrictions. */ ++ vco_hz = OSC_HZ / 1000 * rate->fbdiv / rate->refdiv * 1000; ++ output_hz = vco_hz / rate->postdiv1 / rate->postdiv2; ++ ++ debug("PLL at %p: fb=%d, ref=%d, pst1=%d, pst2=%d, vco=%u Hz, output=%u Hz\n", ++ pll, rate->fbdiv, rate->refdiv, rate->postdiv1, ++ rate->postdiv2, vco_hz, output_hz); ++ assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ && ++ output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ); ++ ++ /* ++ * When power on or changing PLL setting, ++ * we must force PLL into slow mode to ensure output stable clock. ++ */ ++ rk_clrsetreg(mode, pll_mode_mask[pll_id], ++ PLLMUX_FROM_XIN24M << pll_mode_shift[pll_id]); ++ ++ /* use integer mode */ ++ rk_setreg(&pll->con1, 1 << PLL_DSMPD_SHIFT); ++ /* Power down */ ++ rk_setreg(&pll->con1, 1 << PLL_PD_SHIFT); ++ ++ rk_clrsetreg(&pll->con0, ++ PLL_POSTDIV1_MASK | PLL_FBDIV_MASK, ++ (rate->postdiv1 << PLL_POSTDIV1_SHIFT) | rate->fbdiv); ++ rk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK | PLL_REFDIV_MASK, ++ (rate->postdiv2 << PLL_POSTDIV2_SHIFT | ++ rate->refdiv << PLL_REFDIV_SHIFT)); ++ ++ /* Power Up */ ++ rk_clrreg(&pll->con1, 1 << PLL_PD_SHIFT); ++ ++ /* waiting for pll lock */ ++ while (!(readl(&pll->con1) & (1 << PLL_LOCK_STATUS_SHIFT))) ++ udelay(1); ++ ++ rk_clrsetreg(mode, pll_mode_mask[pll_id], ++ PLLMUX_FROM_PLL << pll_mode_shift[pll_id]); ++ ++ return 0; ++} ++ ++static uint32_t rkclk_pll_get_rate(struct px30_pll *pll, unsigned int *mode, ++ enum px30_pll_id pll_id) ++{ ++ u32 refdiv, fbdiv, postdiv1, postdiv2; ++ u32 con, shift, mask; ++ ++ con = readl(mode); ++ shift = pll_mode_shift[pll_id]; ++ mask = pll_mode_mask[pll_id]; ++ ++ switch ((con & mask) >> shift) { ++ case PLLMUX_FROM_XIN24M: ++ return OSC_HZ; ++ case PLLMUX_FROM_PLL: ++ /* normal mode */ ++ con = readl(&pll->con0); ++ postdiv1 = (con & PLL_POSTDIV1_MASK) >> PLL_POSTDIV1_SHIFT; ++ fbdiv = (con & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT; ++ con = readl(&pll->con1); ++ postdiv2 = (con & PLL_POSTDIV2_MASK) >> PLL_POSTDIV2_SHIFT; ++ refdiv = (con & PLL_REFDIV_MASK) >> PLL_REFDIV_SHIFT; ++ return (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000; ++ case PLLMUX_FROM_RTC32K: ++ default: ++ return 32768; ++ } ++} ++ ++static ulong px30_i2c_get_clk(struct px30_clk_priv *priv, ulong clk_id) ++{ ++ struct px30_cru *cru = priv->cru; ++ u32 div, con; ++ ++ switch (clk_id) { ++ case SCLK_I2C0: ++ con = readl(&cru->clksel_con[49]); ++ div = con >> CLK_I2C0_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; ++ break; ++ case SCLK_I2C1: ++ con = readl(&cru->clksel_con[49]); ++ div = con >> CLK_I2C1_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; ++ break; ++ case SCLK_I2C2: ++ con = readl(&cru->clksel_con[50]); ++ div = con >> CLK_I2C2_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; ++ break; ++ case SCLK_I2C3: ++ con = readl(&cru->clksel_con[50]); ++ div = con >> CLK_I2C3_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; ++ break; ++ default: ++ printf("do not support this i2c bus\n"); ++ return -EINVAL; ++ } ++ ++ return DIV_TO_RATE(priv->gpll_hz, div); ++} ++ ++static ulong px30_i2c_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz) ++{ ++ struct px30_cru *cru = priv->cru; ++ int src_clk_div; ++ ++ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); ++ assert(src_clk_div - 1 <= 127); ++ ++ switch (clk_id) { ++ case SCLK_I2C0: ++ rk_clrsetreg(&cru->clksel_con[49], ++ CLK_I2C_DIV_CON_MASK << CLK_I2C0_DIV_CON_SHIFT | ++ CLK_I2C_PLL_SEL_MASK << CLK_I2C0_PLL_SEL_SHIFT, ++ (src_clk_div - 1) << CLK_I2C0_DIV_CON_SHIFT | ++ CLK_I2C_PLL_SEL_GPLL << CLK_I2C0_PLL_SEL_SHIFT); ++ break; ++ case SCLK_I2C1: ++ rk_clrsetreg(&cru->clksel_con[49], ++ CLK_I2C_DIV_CON_MASK << CLK_I2C1_DIV_CON_SHIFT | ++ CLK_I2C_PLL_SEL_MASK << CLK_I2C1_PLL_SEL_SHIFT, ++ (src_clk_div - 1) << CLK_I2C1_DIV_CON_SHIFT | ++ CLK_I2C_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT); ++ break; ++ case SCLK_I2C2: ++ rk_clrsetreg(&cru->clksel_con[50], ++ CLK_I2C_DIV_CON_MASK << CLK_I2C2_DIV_CON_SHIFT | ++ CLK_I2C_PLL_SEL_MASK << CLK_I2C2_PLL_SEL_SHIFT, ++ (src_clk_div - 1) << CLK_I2C2_DIV_CON_SHIFT | ++ CLK_I2C_PLL_SEL_GPLL << CLK_I2C2_PLL_SEL_SHIFT); ++ break; ++ case SCLK_I2C3: ++ rk_clrsetreg(&cru->clksel_con[50], ++ CLK_I2C_DIV_CON_MASK << CLK_I2C3_DIV_CON_SHIFT | ++ CLK_I2C_PLL_SEL_MASK << CLK_I2C3_PLL_SEL_SHIFT, ++ (src_clk_div - 1) << CLK_I2C3_DIV_CON_SHIFT | ++ CLK_I2C_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT); ++ break; ++ default: ++ printf("do not support this i2c bus\n"); ++ return -EINVAL; ++ } ++ ++ return px30_i2c_get_clk(priv, clk_id); ++} ++ ++/* ++ * calculate best rational approximation for a given fraction ++ * taking into account restricted register size, e.g. to find ++ * appropriate values for a pll with 5 bit denominator and ++ * 8 bit numerator register fields, trying to set up with a ++ * frequency ratio of 3.1415, one would say: ++ * ++ * rational_best_approximation(31415, 10000, ++ * (1 << 8) - 1, (1 << 5) - 1, &n, &d); ++ * ++ * you may look at given_numerator as a fixed point number, ++ * with the fractional part size described in given_denominator. ++ * ++ * for theoretical background, see: ++ * http://en.wikipedia.org/wiki/Continued_fraction ++ */ ++static void rational_best_approximation(unsigned long given_numerator, ++ unsigned long given_denominator, ++ unsigned long max_numerator, ++ unsigned long max_denominator, ++ unsigned long *best_numerator, ++ unsigned long *best_denominator) ++{ ++ unsigned long n, d, n0, d0, n1, d1; ++ ++ n = given_numerator; ++ d = given_denominator; ++ n0 = 0; ++ d1 = 0; ++ n1 = 1; ++ d0 = 1; ++ for (;;) { ++ unsigned long t, a; ++ ++ if (n1 > max_numerator || d1 > max_denominator) { ++ n1 = n0; ++ d1 = d0; ++ break; ++ } ++ if (d == 0) ++ break; ++ t = d; ++ a = n / d; ++ d = n % d; ++ n = t; ++ t = n0 + a * n1; ++ n0 = n1; ++ n1 = t; ++ t = d0 + a * d1; ++ d0 = d1; ++ d1 = t; ++ } ++ *best_numerator = n1; ++ *best_denominator = d1; ++} ++ ++static ulong px30_i2s_get_clk(struct px30_clk_priv *priv, ulong clk_id) ++{ ++ u32 con, fracdiv, gate; ++ u32 clk_src = priv->gpll_hz / 2; ++ unsigned long m, n; ++ struct px30_cru *cru = priv->cru; ++ ++ switch (clk_id) { ++ case SCLK_I2S1: ++ con = readl(&cru->clksel_con[30]); ++ fracdiv = readl(&cru->clksel_con[31]); ++ gate = readl(&cru->clkgate_con[10]); ++ m = fracdiv & CLK_I2S1_FRAC_NUMERATOR_MASK; ++ m >>= CLK_I2S1_FRAC_NUMERATOR_SHIFT; ++ n = fracdiv & CLK_I2S1_FRAC_DENOMINATOR_MASK; ++ n >>= CLK_I2S1_FRAC_DENOMINATOR_SHIFT; ++ debug("con30: 0x%x, gate: 0x%x, frac: 0x%x\n", ++ con, gate, fracdiv); ++ break; ++ default: ++ printf("do not support this i2s bus\n"); ++ return -EINVAL; ++ } ++ ++ return clk_src * n / m; ++} ++ ++static ulong px30_i2s_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz) ++{ ++ u32 clk_src; ++ unsigned long m, n, val; ++ struct px30_cru *cru = priv->cru; ++ ++ clk_src = priv->gpll_hz / 2; ++ rational_best_approximation(hz, clk_src, ++ GENMASK(16 - 1, 0), ++ GENMASK(16 - 1, 0), ++ &m, &n); ++ switch (clk_id) { ++ case SCLK_I2S1: ++ rk_clrsetreg(&cru->clksel_con[30], ++ CLK_I2S1_PLL_SEL_MASK, CLK_I2S1_PLL_SEL_GPLL); ++ rk_clrsetreg(&cru->clksel_con[30], ++ CLK_I2S1_DIV_CON_MASK, 0x1); ++ rk_clrsetreg(&cru->clksel_con[30], ++ CLK_I2S1_SEL_MASK, CLK_I2S1_SEL_FRAC); ++ val = m << CLK_I2S1_FRAC_NUMERATOR_SHIFT | n; ++ writel(val, &cru->clksel_con[31]); ++ rk_clrsetreg(&cru->clkgate_con[10], ++ CLK_I2S1_OUT_MCLK_PAD_MASK, ++ CLK_I2S1_OUT_MCLK_PAD_ENABLE); ++ break; ++ default: ++ printf("do not support this i2s bus\n"); ++ return -EINVAL; ++ } ++ ++ return px30_i2s_get_clk(priv, clk_id); ++} ++ ++static ulong px30_nandc_get_clk(struct px30_clk_priv *priv) ++{ ++ struct px30_cru *cru = priv->cru; ++ u32 div, con; ++ ++ con = readl(&cru->clksel_con[15]); ++ div = (con & NANDC_DIV_MASK) >> NANDC_DIV_SHIFT; ++ ++ return DIV_TO_RATE(priv->gpll_hz, div); ++} ++ ++static ulong px30_nandc_set_clk(struct px30_clk_priv *priv, ++ ulong set_rate) ++{ ++ struct px30_cru *cru = priv->cru; ++ int src_clk_div; ++ ++ /* Select nandc source from GPLL by default */ ++ /* nandc clock defaulg div 2 internal, need provide double in cru */ ++ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, set_rate); ++ assert(src_clk_div - 1 <= 31); ++ ++ rk_clrsetreg(&cru->clksel_con[15], ++ NANDC_CLK_SEL_MASK | NANDC_PLL_MASK | ++ NANDC_DIV_MASK, ++ NANDC_CLK_SEL_NANDC << NANDC_CLK_SEL_SHIFT | ++ NANDC_SEL_GPLL << NANDC_PLL_SHIFT | ++ (src_clk_div - 1) << NANDC_DIV_SHIFT); ++ ++ return px30_nandc_get_clk(priv); ++} ++ ++static ulong px30_mmc_get_clk(struct px30_clk_priv *priv, uint clk_id) ++{ ++ struct px30_cru *cru = priv->cru; ++ u32 div, con, con_id; ++ ++ switch (clk_id) { ++ case HCLK_SDMMC: ++ case SCLK_SDMMC: ++ con_id = 16; ++ break; ++ case HCLK_EMMC: ++ case SCLK_EMMC: ++ case SCLK_EMMC_SAMPLE: ++ con_id = 20; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ con = readl(&cru->clksel_con[con_id]); ++ div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT; ++ ++ if ((con & EMMC_PLL_MASK) >> EMMC_PLL_SHIFT ++ == EMMC_SEL_24M) ++ return DIV_TO_RATE(OSC_HZ, div) / 2; ++ else ++ return DIV_TO_RATE(priv->gpll_hz, div) / 2; ++} ++ ++static ulong px30_mmc_set_clk(struct px30_clk_priv *priv, ++ ulong clk_id, ulong set_rate) ++{ ++ struct px30_cru *cru = priv->cru; ++ int src_clk_div; ++ u32 con_id; ++ ++ switch (clk_id) { ++ case HCLK_SDMMC: ++ case SCLK_SDMMC: ++ con_id = 16; ++ break; ++ case HCLK_EMMC: ++ case SCLK_EMMC: ++ con_id = 20; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ /* Select clk_sdmmc/emmc source from GPLL by default */ ++ /* mmc clock defaulg div 2 internal, need provide double in cru */ ++ src_clk_div = DIV_ROUND_UP(priv->gpll_hz / 2, set_rate); ++ ++ if (src_clk_div > 127) { ++ /* use 24MHz source for 400KHz clock */ ++ src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate); ++ rk_clrsetreg(&cru->clksel_con[con_id], ++ EMMC_PLL_MASK | EMMC_DIV_MASK, ++ EMMC_SEL_24M << EMMC_PLL_SHIFT | ++ (src_clk_div - 1) << EMMC_DIV_SHIFT); ++ } else { ++ rk_clrsetreg(&cru->clksel_con[con_id], ++ EMMC_PLL_MASK | EMMC_DIV_MASK, ++ EMMC_SEL_GPLL << EMMC_PLL_SHIFT | ++ (src_clk_div - 1) << EMMC_DIV_SHIFT); ++ } ++ rk_clrsetreg(&cru->clksel_con[con_id + 1], EMMC_CLK_SEL_MASK, ++ EMMC_CLK_SEL_EMMC); ++ ++ return px30_mmc_get_clk(priv, clk_id); ++} ++ ++static ulong px30_pwm_get_clk(struct px30_clk_priv *priv, ulong clk_id) ++{ ++ struct px30_cru *cru = priv->cru; ++ u32 div, con; ++ ++ switch (clk_id) { ++ case SCLK_PWM0: ++ con = readl(&cru->clksel_con[52]); ++ div = con >> CLK_PWM0_DIV_CON_SHIFT & CLK_PWM_DIV_CON_MASK; ++ break; ++ case SCLK_PWM1: ++ con = readl(&cru->clksel_con[52]); ++ div = con >> CLK_PWM1_DIV_CON_SHIFT & CLK_PWM_DIV_CON_MASK; ++ break; ++ default: ++ printf("do not support this pwm bus\n"); ++ return -EINVAL; ++ } ++ ++ return DIV_TO_RATE(priv->gpll_hz, div); ++} ++ ++static ulong px30_pwm_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz) ++{ ++ struct px30_cru *cru = priv->cru; ++ int src_clk_div; ++ ++ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); ++ assert(src_clk_div - 1 <= 127); ++ ++ switch (clk_id) { ++ case SCLK_PWM0: ++ rk_clrsetreg(&cru->clksel_con[52], ++ CLK_PWM_DIV_CON_MASK << CLK_PWM0_DIV_CON_SHIFT | ++ CLK_PWM_PLL_SEL_MASK << CLK_PWM0_PLL_SEL_SHIFT, ++ (src_clk_div - 1) << CLK_PWM0_DIV_CON_SHIFT | ++ CLK_PWM_PLL_SEL_GPLL << CLK_PWM0_PLL_SEL_SHIFT); ++ break; ++ case SCLK_PWM1: ++ rk_clrsetreg(&cru->clksel_con[52], ++ CLK_PWM_DIV_CON_MASK << CLK_PWM1_DIV_CON_SHIFT | ++ CLK_PWM_PLL_SEL_MASK << CLK_PWM1_PLL_SEL_SHIFT, ++ (src_clk_div - 1) << CLK_PWM1_DIV_CON_SHIFT | ++ CLK_PWM_PLL_SEL_GPLL << CLK_PWM1_PLL_SEL_SHIFT); ++ break; ++ default: ++ printf("do not support this pwm bus\n"); ++ return -EINVAL; ++ } ++ ++ return px30_pwm_get_clk(priv, clk_id); ++} ++ ++static ulong px30_saradc_get_clk(struct px30_clk_priv *priv) ++{ ++ struct px30_cru *cru = priv->cru; ++ u32 div, con; ++ ++ con = readl(&cru->clksel_con[55]); ++ div = con >> CLK_SARADC_DIV_CON_SHIFT & CLK_SARADC_DIV_CON_MASK; ++ ++ return DIV_TO_RATE(OSC_HZ, div); ++} ++ ++static ulong px30_saradc_set_clk(struct px30_clk_priv *priv, uint hz) ++{ ++ struct px30_cru *cru = priv->cru; ++ int src_clk_div; ++ ++ src_clk_div = DIV_ROUND_UP(OSC_HZ, hz); ++ assert(src_clk_div - 1 <= 2047); ++ ++ rk_clrsetreg(&cru->clksel_con[55], ++ CLK_SARADC_DIV_CON_MASK, ++ (src_clk_div - 1) << CLK_SARADC_DIV_CON_SHIFT); ++ ++ return px30_saradc_get_clk(priv); ++} ++ ++static ulong px30_tsadc_get_clk(struct px30_clk_priv *priv) ++{ ++ struct px30_cru *cru = priv->cru; ++ u32 div, con; ++ ++ con = readl(&cru->clksel_con[54]); ++ div = con >> CLK_SARADC_DIV_CON_SHIFT & CLK_SARADC_DIV_CON_MASK; ++ ++ return DIV_TO_RATE(OSC_HZ, div); ++} ++ ++static ulong px30_tsadc_set_clk(struct px30_clk_priv *priv, uint hz) ++{ ++ struct px30_cru *cru = priv->cru; ++ int src_clk_div; ++ ++ src_clk_div = DIV_ROUND_UP(OSC_HZ, hz); ++ assert(src_clk_div - 1 <= 2047); ++ ++ rk_clrsetreg(&cru->clksel_con[54], ++ CLK_SARADC_DIV_CON_MASK, ++ (src_clk_div - 1) << CLK_SARADC_DIV_CON_SHIFT); ++ ++ return px30_tsadc_get_clk(priv); ++} ++ ++static ulong px30_spi_get_clk(struct px30_clk_priv *priv, ulong clk_id) ++{ ++ struct px30_cru *cru = priv->cru; ++ u32 div, con; ++ ++ switch (clk_id) { ++ case SCLK_SPI0: ++ con = readl(&cru->clksel_con[53]); ++ div = con >> CLK_SPI0_DIV_CON_SHIFT & CLK_SPI_DIV_CON_MASK; ++ break; ++ case SCLK_SPI1: ++ con = readl(&cru->clksel_con[53]); ++ div = con >> CLK_SPI1_DIV_CON_SHIFT & CLK_SPI_DIV_CON_MASK; ++ break; ++ default: ++ printf("do not support this pwm bus\n"); ++ return -EINVAL; ++ } ++ ++ return DIV_TO_RATE(priv->gpll_hz, div); ++} ++ ++static ulong px30_spi_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz) ++{ ++ struct px30_cru *cru = priv->cru; ++ int src_clk_div; ++ ++ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); ++ assert(src_clk_div - 1 <= 127); ++ ++ switch (clk_id) { ++ case SCLK_SPI0: ++ rk_clrsetreg(&cru->clksel_con[53], ++ CLK_SPI_DIV_CON_MASK << CLK_SPI0_DIV_CON_SHIFT | ++ CLK_SPI_PLL_SEL_MASK << CLK_SPI0_PLL_SEL_SHIFT, ++ (src_clk_div - 1) << CLK_SPI0_DIV_CON_SHIFT | ++ CLK_SPI_PLL_SEL_GPLL << CLK_SPI0_PLL_SEL_SHIFT); ++ break; ++ case SCLK_SPI1: ++ rk_clrsetreg(&cru->clksel_con[53], ++ CLK_SPI_DIV_CON_MASK << CLK_SPI1_DIV_CON_SHIFT | ++ CLK_SPI_PLL_SEL_MASK << CLK_SPI1_PLL_SEL_SHIFT, ++ (src_clk_div - 1) << CLK_SPI1_DIV_CON_SHIFT | ++ CLK_SPI_PLL_SEL_GPLL << CLK_SPI1_PLL_SEL_SHIFT); ++ break; ++ default: ++ printf("do not support this pwm bus\n"); ++ return -EINVAL; ++ } ++ ++ return px30_spi_get_clk(priv, clk_id); ++} ++ ++static ulong px30_vop_get_clk(struct px30_clk_priv *priv, ulong clk_id) ++{ ++ struct px30_cru *cru = priv->cru; ++ u32 div, con, parent; ++ ++ switch (clk_id) { ++ case ACLK_VOPB: ++ case ACLK_VOPL: ++ con = readl(&cru->clksel_con[3]); ++ div = con & ACLK_VO_DIV_MASK; ++ parent = priv->gpll_hz; ++ break; ++ case DCLK_VOPB: ++ con = readl(&cru->clksel_con[5]); ++ div = con & DCLK_VOPB_DIV_MASK; ++ parent = rkclk_pll_get_rate(&cru->pll[CPLL], &cru->mode, CPLL); ++ break; ++ case DCLK_VOPL: ++ con = readl(&cru->clksel_con[8]); ++ div = con & DCLK_VOPL_DIV_MASK; ++ parent = rkclk_pll_get_rate(&cru->pll[NPLL], &cru->mode, NPLL); ++ break; ++ default: ++ return -ENOENT; ++ } ++ ++ return DIV_TO_RATE(parent, div); ++} ++ ++static ulong px30_vop_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz) ++{ ++ struct px30_cru *cru = priv->cru; ++ ulong npll_hz; ++ int src_clk_div; ++ ++ switch (clk_id) { ++ case ACLK_VOPB: ++ case ACLK_VOPL: ++ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); ++ assert(src_clk_div - 1 <= 31); ++ rk_clrsetreg(&cru->clksel_con[3], ++ ACLK_VO_PLL_MASK | ACLK_VO_DIV_MASK, ++ ACLK_VO_SEL_GPLL << ACLK_VO_PLL_SHIFT | ++ (src_clk_div - 1) << ACLK_VO_DIV_SHIFT); ++ break; ++ case DCLK_VOPB: ++ if (hz < PX30_VOP_PLL_LIMIT) { ++ src_clk_div = DIV_ROUND_UP(PX30_VOP_PLL_LIMIT, hz); ++ if (src_clk_div % 2) ++ src_clk_div = src_clk_div - 1; ++ } else { ++ src_clk_div = 1; ++ } ++ assert(src_clk_div - 1 <= 255); ++ rkclk_set_pll(&cru->pll[CPLL], &cru->mode, ++ CPLL, hz * src_clk_div); ++ rk_clrsetreg(&cru->clksel_con[5], ++ DCLK_VOPB_SEL_MASK | DCLK_VOPB_PLL_SEL_MASK | ++ DCLK_VOPB_DIV_MASK, ++ DCLK_VOPB_SEL_DIVOUT << DCLK_VOPB_SEL_SHIFT | ++ DCLK_VOPB_PLL_SEL_CPLL << DCLK_VOPB_PLL_SEL_SHIFT | ++ (src_clk_div - 1) << DCLK_VOPB_DIV_SHIFT); ++ break; ++ case DCLK_VOPL: ++ npll_hz = px30_clk_get_pll_rate(priv, NPLL); ++ if (npll_hz >= PX30_VOP_PLL_LIMIT && npll_hz >= hz && ++ npll_hz % hz == 0) { ++ src_clk_div = npll_hz / hz; ++ assert(src_clk_div - 1 <= 255); ++ } else { ++ if (hz < PX30_VOP_PLL_LIMIT) { ++ src_clk_div = DIV_ROUND_UP(PX30_VOP_PLL_LIMIT, ++ hz); ++ if (src_clk_div % 2) ++ src_clk_div = src_clk_div - 1; ++ } else { ++ src_clk_div = 1; ++ } ++ assert(src_clk_div - 1 <= 255); ++ rkclk_set_pll(&cru->pll[NPLL], &cru->mode, NPLL, ++ hz * src_clk_div); ++ } ++ rk_clrsetreg(&cru->clksel_con[8], ++ DCLK_VOPL_SEL_MASK | DCLK_VOPL_PLL_SEL_MASK | ++ DCLK_VOPL_DIV_MASK, ++ DCLK_VOPL_SEL_DIVOUT << DCLK_VOPL_SEL_SHIFT | ++ DCLK_VOPL_PLL_SEL_NPLL << DCLK_VOPL_PLL_SEL_SHIFT | ++ (src_clk_div - 1) << DCLK_VOPL_DIV_SHIFT); ++ break; ++ default: ++ printf("do not support this vop freq\n"); ++ return -EINVAL; ++ } ++ ++ return px30_vop_get_clk(priv, clk_id); ++} ++ ++static ulong px30_bus_get_clk(struct px30_clk_priv *priv, ulong clk_id) ++{ ++ struct px30_cru *cru = priv->cru; ++ u32 div, con, parent; ++ ++ switch (clk_id) { ++ case ACLK_BUS_PRE: ++ con = readl(&cru->clksel_con[23]); ++ div = (con & BUS_ACLK_DIV_MASK) >> BUS_ACLK_DIV_SHIFT; ++ parent = priv->gpll_hz; ++ break; ++ case HCLK_BUS_PRE: ++ con = readl(&cru->clksel_con[24]); ++ div = (con & BUS_HCLK_DIV_MASK) >> BUS_HCLK_DIV_SHIFT; ++ parent = priv->gpll_hz; ++ break; ++ case PCLK_BUS_PRE: ++ case PCLK_WDT_NS: ++ parent = px30_bus_get_clk(priv, ACLK_BUS_PRE); ++ con = readl(&cru->clksel_con[24]); ++ div = (con & BUS_PCLK_DIV_MASK) >> BUS_PCLK_DIV_SHIFT; ++ break; ++ default: ++ return -ENOENT; ++ } ++ ++ return DIV_TO_RATE(parent, div); ++} ++ ++static ulong px30_bus_set_clk(struct px30_clk_priv *priv, ulong clk_id, ++ ulong hz) ++{ ++ struct px30_cru *cru = priv->cru; ++ int src_clk_div; ++ ++ /* ++ * select gpll as pd_bus bus clock source and ++ * set up dependent divisors for PCLK/HCLK and ACLK clocks. ++ */ ++ switch (clk_id) { ++ case ACLK_BUS_PRE: ++ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); ++ assert(src_clk_div - 1 <= 31); ++ rk_clrsetreg(&cru->clksel_con[23], ++ BUS_PLL_SEL_MASK | BUS_ACLK_DIV_MASK, ++ BUS_PLL_SEL_GPLL << BUS_PLL_SEL_SHIFT | ++ (src_clk_div - 1) << BUS_ACLK_DIV_SHIFT); ++ break; ++ case HCLK_BUS_PRE: ++ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); ++ assert(src_clk_div - 1 <= 31); ++ rk_clrsetreg(&cru->clksel_con[24], ++ BUS_PLL_SEL_MASK | BUS_HCLK_DIV_MASK, ++ BUS_PLL_SEL_GPLL << BUS_PLL_SEL_SHIFT | ++ (src_clk_div - 1) << BUS_HCLK_DIV_SHIFT); ++ break; ++ case PCLK_BUS_PRE: ++ src_clk_div = ++ DIV_ROUND_UP(px30_bus_get_clk(priv, ACLK_BUS_PRE), hz); ++ assert(src_clk_div - 1 <= 3); ++ rk_clrsetreg(&cru->clksel_con[24], ++ BUS_PCLK_DIV_MASK, ++ (src_clk_div - 1) << BUS_PCLK_DIV_SHIFT); ++ break; ++ default: ++ printf("do not support this bus freq\n"); ++ return -EINVAL; ++ } ++ ++ return px30_bus_get_clk(priv, clk_id); ++} ++ ++static ulong px30_peri_get_clk(struct px30_clk_priv *priv, ulong clk_id) ++{ ++ struct px30_cru *cru = priv->cru; ++ u32 div, con, parent; ++ ++ switch (clk_id) { ++ case ACLK_PERI_PRE: ++ con = readl(&cru->clksel_con[14]); ++ div = (con & PERI_ACLK_DIV_MASK) >> PERI_ACLK_DIV_SHIFT; ++ parent = priv->gpll_hz; ++ break; ++ case HCLK_PERI_PRE: ++ con = readl(&cru->clksel_con[14]); ++ div = (con & PERI_HCLK_DIV_MASK) >> PERI_HCLK_DIV_SHIFT; ++ parent = priv->gpll_hz; ++ break; ++ default: ++ return -ENOENT; ++ } ++ ++ return DIV_TO_RATE(parent, div); ++} ++ ++static ulong px30_peri_set_clk(struct px30_clk_priv *priv, ulong clk_id, ++ ulong hz) ++{ ++ struct px30_cru *cru = priv->cru; ++ int src_clk_div; ++ ++ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); ++ assert(src_clk_div - 1 <= 31); ++ ++ /* ++ * select gpll as pd_peri bus clock source and ++ * set up dependent divisors for HCLK and ACLK clocks. ++ */ ++ switch (clk_id) { ++ case ACLK_PERI_PRE: ++ rk_clrsetreg(&cru->clksel_con[14], ++ PERI_PLL_SEL_MASK | PERI_ACLK_DIV_MASK, ++ PERI_PLL_GPLL << PERI_PLL_SEL_SHIFT | ++ (src_clk_div - 1) << PERI_ACLK_DIV_SHIFT); ++ break; ++ case HCLK_PERI_PRE: ++ rk_clrsetreg(&cru->clksel_con[14], ++ PERI_PLL_SEL_MASK | PERI_HCLK_DIV_MASK, ++ PERI_PLL_GPLL << PERI_PLL_SEL_SHIFT | ++ (src_clk_div - 1) << PERI_HCLK_DIV_SHIFT); ++ break; ++ default: ++ printf("do not support this peri freq\n"); ++ return -EINVAL; ++ } ++ ++ return px30_peri_get_clk(priv, clk_id); ++} ++ ++#ifndef CONFIG_SPL_BUILD ++static ulong px30_crypto_get_clk(struct px30_clk_priv *priv, ulong clk_id) ++{ ++ struct px30_cru *cru = priv->cru; ++ u32 div, con, parent; ++ ++ switch (clk_id) { ++ case SCLK_CRYPTO: ++ con = readl(&cru->clksel_con[25]); ++ div = (con & CRYPTO_DIV_MASK) >> CRYPTO_DIV_SHIFT; ++ parent = priv->gpll_hz; ++ break; ++ case SCLK_CRYPTO_APK: ++ con = readl(&cru->clksel_con[25]); ++ div = (con & CRYPTO_APK_DIV_MASK) >> CRYPTO_APK_DIV_SHIFT; ++ parent = priv->gpll_hz; ++ break; ++ default: ++ return -ENOENT; ++ } ++ ++ return DIV_TO_RATE(parent, div); ++} ++ ++static ulong px30_crypto_set_clk(struct px30_clk_priv *priv, ulong clk_id, ++ ulong hz) ++{ ++ struct px30_cru *cru = priv->cru; ++ int src_clk_div; ++ ++ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); ++ assert(src_clk_div - 1 <= 31); ++ ++ /* ++ * select gpll as crypto clock source and ++ * set up dependent divisors for crypto clocks. ++ */ ++ switch (clk_id) { ++ case SCLK_CRYPTO: ++ rk_clrsetreg(&cru->clksel_con[25], ++ CRYPTO_PLL_SEL_MASK | CRYPTO_DIV_MASK, ++ CRYPTO_PLL_SEL_GPLL << CRYPTO_PLL_SEL_SHIFT | ++ (src_clk_div - 1) << CRYPTO_DIV_SHIFT); ++ break; ++ case SCLK_CRYPTO_APK: ++ rk_clrsetreg(&cru->clksel_con[25], ++ CRYPTO_APK_PLL_SEL_MASK | CRYPTO_APK_DIV_MASK, ++ CRYPTO_PLL_SEL_GPLL << CRYPTO_APK_SEL_SHIFT | ++ (src_clk_div - 1) << CRYPTO_APK_DIV_SHIFT); ++ break; ++ default: ++ printf("do not support this peri freq\n"); ++ return -EINVAL; ++ } ++ ++ return px30_crypto_get_clk(priv, clk_id); ++} ++ ++static ulong px30_i2s1_mclk_get_clk(struct px30_clk_priv *priv, ulong clk_id) ++{ ++ struct px30_cru *cru = priv->cru; ++ u32 con; ++ ++ con = readl(&cru->clksel_con[30]); ++ ++ if (!(con & CLK_I2S1_OUT_SEL_MASK)) ++ return -ENOENT; ++ ++ return 12000000; ++} ++ ++static ulong px30_i2s1_mclk_set_clk(struct px30_clk_priv *priv, ulong clk_id, ++ ulong hz) ++{ ++ struct px30_cru *cru = priv->cru; ++ ++ if (hz != 12000000) { ++ printf("do not support this i2s1_mclk freq\n"); ++ return -EINVAL; ++ } ++ ++ rk_clrsetreg(&cru->clksel_con[30], CLK_I2S1_OUT_SEL_MASK, ++ CLK_I2S1_OUT_SEL_OSC); ++ rk_clrsetreg(&cru->clkgate_con[10], CLK_I2S1_OUT_MCLK_PAD_MASK, ++ CLK_I2S1_OUT_MCLK_PAD_ENABLE); ++ ++ return px30_i2s1_mclk_get_clk(priv, clk_id); ++} ++ ++static ulong px30_mac_set_clk(struct px30_clk_priv *priv, uint hz) ++{ ++ struct px30_cru *cru = priv->cru; ++ u32 con = readl(&cru->clksel_con[22]); ++ ulong pll_rate; ++ u8 div; ++ ++ if ((con >> GMAC_PLL_SEL_SHIFT) & GMAC_PLL_SEL_CPLL) ++ pll_rate = px30_clk_get_pll_rate(priv, CPLL); ++ else if ((con >> GMAC_PLL_SEL_SHIFT) & GMAC_PLL_SEL_NPLL) ++ pll_rate = px30_clk_get_pll_rate(priv, NPLL); ++ else ++ pll_rate = priv->gpll_hz; ++ ++ /*default set 50MHZ for gmac*/ ++ if (!hz) ++ hz = 50000000; ++ ++ div = DIV_ROUND_UP(pll_rate, hz) - 1; ++ assert(div < 32); ++ rk_clrsetreg(&cru->clksel_con[22], CLK_GMAC_DIV_MASK, ++ div << CLK_GMAC_DIV_SHIFT); ++ ++ return DIV_TO_RATE(pll_rate, div); ++} ++ ++static int px30_mac_set_speed_clk(struct px30_clk_priv *priv, uint hz) ++{ ++ struct px30_cru *cru = priv->cru; ++ ++ if (hz != 2500000 && hz != 25000000) { ++ debug("Unsupported mac speed:%d\n", hz); ++ return -EINVAL; ++ } ++ ++ rk_clrsetreg(&cru->clksel_con[23], RMII_CLK_SEL_MASK, ++ ((hz == 2500000) ? 0 : 1) << RMII_CLK_SEL_SHIFT); ++ ++ return 0; ++} ++ ++#endif ++ ++static ulong px30_clk_get_pll_rate(struct px30_clk_priv *priv, ++ enum px30_pll_id pll_id) ++{ ++ struct px30_cru *cru = priv->cru; ++ ++ return rkclk_pll_get_rate(&cru->pll[pll_id], &cru->mode, pll_id); ++} ++ ++static ulong px30_clk_set_pll_rate(struct px30_clk_priv *priv, ++ enum px30_pll_id pll_id, ulong hz) ++{ ++ struct px30_cru *cru = priv->cru; ++ ++ if (rkclk_set_pll(&cru->pll[pll_id], &cru->mode, pll_id, hz)) ++ return -EINVAL; ++ return rkclk_pll_get_rate(&cru->pll[pll_id], &cru->mode, pll_id); ++} ++ ++static ulong px30_armclk_set_clk(struct px30_clk_priv *priv, ulong hz) ++{ ++ struct px30_cru *cru = priv->cru; ++ const struct cpu_rate_table *rate; ++ ulong old_rate; ++ ++ rate = get_cpu_settings(hz); ++ if (!rate) { ++ printf("%s unsupport rate\n", __func__); ++ return -EINVAL; ++ } ++ ++ /* ++ * select apll as cpu/core clock pll source and ++ * set up dependent divisors for PERI and ACLK clocks. ++ * core hz : apll = 1:1 ++ */ ++ old_rate = px30_clk_get_pll_rate(priv, APLL); ++ if (old_rate > hz) { ++ if (rkclk_set_pll(&cru->pll[APLL], &cru->mode, APLL, hz)) ++ return -EINVAL; ++ rk_clrsetreg(&cru->clksel_con[0], ++ CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK | ++ CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK, ++ rate->aclk_div << CORE_ACLK_DIV_SHIFT | ++ rate->pclk_div << CORE_DBG_DIV_SHIFT | ++ CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT | ++ 0 << CORE_DIV_CON_SHIFT); ++ } else if (old_rate < hz) { ++ rk_clrsetreg(&cru->clksel_con[0], ++ CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK | ++ CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK, ++ rate->aclk_div << CORE_ACLK_DIV_SHIFT | ++ rate->pclk_div << CORE_DBG_DIV_SHIFT | ++ CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT | ++ 0 << CORE_DIV_CON_SHIFT); ++ if (rkclk_set_pll(&cru->pll[APLL], &cru->mode, APLL, hz)) ++ return -EINVAL; ++ } ++ ++ return px30_clk_get_pll_rate(priv, APLL); ++} ++ ++static ulong px30_clk_get_rate(struct clk *clk) ++{ ++ struct px30_clk_priv *priv = dev_get_priv(clk->dev); ++ ulong rate = 0; ++ ++ if (!priv->gpll_hz && clk->id > ARMCLK) { ++ printf("%s gpll=%lu\n", __func__, priv->gpll_hz); ++ return -ENOENT; ++ } ++ ++ debug("%s %ld\n", __func__, clk->id); ++ switch (clk->id) { ++ case PLL_APLL: ++ rate = px30_clk_get_pll_rate(priv, APLL); ++ break; ++ case PLL_DPLL: ++ rate = px30_clk_get_pll_rate(priv, DPLL); ++ break; ++ case PLL_CPLL: ++ rate = px30_clk_get_pll_rate(priv, CPLL); ++ break; ++ case PLL_NPLL: ++ rate = px30_clk_get_pll_rate(priv, NPLL); ++ break; ++ case ARMCLK: ++ rate = px30_clk_get_pll_rate(priv, APLL); ++ break; ++ case HCLK_SDMMC: ++ case HCLK_EMMC: ++ case SCLK_SDMMC: ++ case SCLK_EMMC: ++ case SCLK_EMMC_SAMPLE: ++ rate = px30_mmc_get_clk(priv, clk->id); ++ break; ++ case SCLK_I2C0: ++ case SCLK_I2C1: ++ case SCLK_I2C2: ++ case SCLK_I2C3: ++ rate = px30_i2c_get_clk(priv, clk->id); ++ break; ++ case SCLK_I2S1: ++ rate = px30_i2s_get_clk(priv, clk->id); ++ break; ++ case SCLK_NANDC: ++ rate = px30_nandc_get_clk(priv); ++ break; ++ case SCLK_PWM0: ++ case SCLK_PWM1: ++ rate = px30_pwm_get_clk(priv, clk->id); ++ break; ++ case SCLK_SARADC: ++ rate = px30_saradc_get_clk(priv); ++ break; ++ case SCLK_TSADC: ++ rate = px30_tsadc_get_clk(priv); ++ break; ++ case SCLK_SPI0: ++ case SCLK_SPI1: ++ rate = px30_spi_get_clk(priv, clk->id); ++ break; ++ case ACLK_VOPB: ++ case ACLK_VOPL: ++ case DCLK_VOPB: ++ case DCLK_VOPL: ++ rate = px30_vop_get_clk(priv, clk->id); ++ break; ++ case ACLK_BUS_PRE: ++ case HCLK_BUS_PRE: ++ case PCLK_BUS_PRE: ++ case PCLK_WDT_NS: ++ rate = px30_bus_get_clk(priv, clk->id); ++ break; ++ case ACLK_PERI_PRE: ++ case HCLK_PERI_PRE: ++ rate = px30_peri_get_clk(priv, clk->id); ++ break; ++#ifndef CONFIG_SPL_BUILD ++ case SCLK_CRYPTO: ++ case SCLK_CRYPTO_APK: ++ rate = px30_crypto_get_clk(priv, clk->id); ++ break; ++#endif ++ default: ++ return -ENOENT; ++ } ++ ++ return rate; ++} ++ ++static ulong px30_clk_set_rate(struct clk *clk, ulong rate) ++{ ++ struct px30_clk_priv *priv = dev_get_priv(clk->dev); ++ ulong ret = 0; ++ ++ if (!priv->gpll_hz && clk->id > ARMCLK) { ++ printf("%s gpll=%lu\n", __func__, priv->gpll_hz); ++ return -ENOENT; ++ } ++ ++ debug("%s %ld %ld\n", __func__, clk->id, rate); ++ switch (clk->id) { ++ case PLL_NPLL: ++ ret = px30_clk_set_pll_rate(priv, NPLL, rate); ++ break; ++ case ARMCLK: ++ ret = px30_armclk_set_clk(priv, rate); ++ break; ++ case HCLK_SDMMC: ++ case HCLK_EMMC: ++ case SCLK_SDMMC: ++ case SCLK_EMMC: ++ ret = px30_mmc_set_clk(priv, clk->id, rate); ++ break; ++ case SCLK_I2C0: ++ case SCLK_I2C1: ++ case SCLK_I2C2: ++ case SCLK_I2C3: ++ ret = px30_i2c_set_clk(priv, clk->id, rate); ++ break; ++ case SCLK_I2S1: ++ ret = px30_i2s_set_clk(priv, clk->id, rate); ++ break; ++ case SCLK_NANDC: ++ ret = px30_nandc_set_clk(priv, rate); ++ break; ++ case SCLK_PWM0: ++ case SCLK_PWM1: ++ ret = px30_pwm_set_clk(priv, clk->id, rate); ++ break; ++ case SCLK_SARADC: ++ ret = px30_saradc_set_clk(priv, rate); ++ break; ++ case SCLK_TSADC: ++ ret = px30_tsadc_set_clk(priv, rate); ++ break; ++ case SCLK_SPI0: ++ case SCLK_SPI1: ++ ret = px30_spi_set_clk(priv, clk->id, rate); ++ break; ++ case ACLK_VOPB: ++ case ACLK_VOPL: ++ case DCLK_VOPB: ++ case DCLK_VOPL: ++ ret = px30_vop_set_clk(priv, clk->id, rate); ++ break; ++ case ACLK_BUS_PRE: ++ case HCLK_BUS_PRE: ++ case PCLK_BUS_PRE: ++ ret = px30_bus_set_clk(priv, clk->id, rate); ++ break; ++ case ACLK_PERI_PRE: ++ case HCLK_PERI_PRE: ++ ret = px30_peri_set_clk(priv, clk->id, rate); ++ break; ++#ifndef CONFIG_SPL_BUILD ++ case SCLK_CRYPTO: ++ case SCLK_CRYPTO_APK: ++ ret = px30_crypto_set_clk(priv, clk->id, rate); ++ break; ++ case SCLK_I2S1_OUT: ++ ret = px30_i2s1_mclk_set_clk(priv, clk->id, rate); ++ break; ++ case SCLK_GMAC: ++ case SCLK_GMAC_SRC: ++ ret = px30_mac_set_clk(priv, rate); ++ break; ++ case SCLK_GMAC_RMII: ++ ret = px30_mac_set_speed_clk(priv, rate); ++ break; ++#endif ++ default: ++ return -ENOENT; ++ } ++ ++ return ret; ++} ++ ++#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) ++static int px30_gmac_set_parent(struct clk *clk, struct clk *parent) ++{ ++ struct px30_clk_priv *priv = dev_get_priv(clk->dev); ++ struct px30_cru *cru = priv->cru; ++ ++ if (parent->id == SCLK_GMAC_SRC) { ++ debug("%s: switching GAMC to SCLK_GMAC_SRC\n", __func__); ++ rk_clrsetreg(&cru->clksel_con[23], RMII_EXTCLK_SEL_MASK, ++ RMII_EXTCLK_SEL_INT << RMII_EXTCLK_SEL_SHIFT); ++ } else { ++ debug("%s: switching GMAC to external clock\n", __func__); ++ rk_clrsetreg(&cru->clksel_con[23], RMII_EXTCLK_SEL_MASK, ++ RMII_EXTCLK_SEL_EXT << RMII_EXTCLK_SEL_SHIFT); ++ } ++ return 0; ++} ++ ++static int px30_clk_set_parent(struct clk *clk, struct clk *parent) ++{ ++ switch (clk->id) { ++ case SCLK_GMAC: ++ return px30_gmac_set_parent(clk, parent); ++ default: ++ return -ENOENT; ++ } ++} ++#endif ++ ++static int px30_clk_enable(struct clk *clk) ++{ ++ switch (clk->id) { ++ case HCLK_HOST: ++ case SCLK_GMAC: ++ case SCLK_GMAC_RX_TX: ++ case SCLK_MAC_REF: ++ case SCLK_MAC_REFOUT: ++ case ACLK_GMAC: ++ case PCLK_GMAC: ++ case SCLK_GMAC_RMII: ++ /* Required to successfully probe the Designware GMAC driver */ ++ return 0; ++ } ++ ++ debug("%s: unsupported clk %ld\n", __func__, clk->id); ++ return -ENOENT; ++} ++ ++static struct clk_ops px30_clk_ops = { ++ .get_rate = px30_clk_get_rate, ++ .set_rate = px30_clk_set_rate, ++#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) ++ .set_parent = px30_clk_set_parent, ++#endif ++ .enable = px30_clk_enable, ++}; ++ ++static void px30_clk_init(struct px30_clk_priv *priv) ++{ ++ ulong npll_hz; ++ int ret; ++ ++ npll_hz = px30_clk_get_pll_rate(priv, NPLL); ++ if (npll_hz != NPLL_HZ) { ++ ret = px30_clk_set_pll_rate(priv, NPLL, NPLL_HZ); ++ if (ret < 0) ++ printf("%s failed to set npll rate\n", __func__); ++ } ++ ++ px30_bus_set_clk(priv, ACLK_BUS_PRE, ACLK_BUS_HZ); ++ px30_bus_set_clk(priv, HCLK_BUS_PRE, HCLK_BUS_HZ); ++ px30_bus_set_clk(priv, PCLK_BUS_PRE, PCLK_BUS_HZ); ++ px30_peri_set_clk(priv, ACLK_PERI_PRE, ACLK_PERI_HZ); ++ px30_peri_set_clk(priv, HCLK_PERI_PRE, HCLK_PERI_HZ); ++} ++ ++static int px30_clk_probe(struct udevice *dev) ++{ ++ struct px30_clk_priv *priv = dev_get_priv(dev); ++ struct clk clk_gpll; ++ int ret; ++ ++ if (px30_clk_get_pll_rate(priv, APLL) != APLL_HZ) ++ px30_armclk_set_clk(priv, APLL_HZ); ++ ++ /* get the GPLL rate from the pmucru */ ++ ret = clk_get_by_name(dev, "gpll", &clk_gpll); ++ if (ret) { ++ printf("%s: failed to get gpll clk from pmucru\n", __func__); ++ return ret; ++ } ++ ++ priv->gpll_hz = clk_get_rate(&clk_gpll); ++ ++ px30_clk_init(priv); ++ ++ return 0; ++} ++ ++static int px30_clk_ofdata_to_platdata(struct udevice *dev) ++{ ++ struct px30_clk_priv *priv = dev_get_priv(dev); ++ ++ priv->cru = dev_read_addr_ptr(dev); ++ ++ return 0; ++} ++ ++static int px30_clk_bind(struct udevice *dev) ++{ ++ int ret; ++ struct udevice *sys_child; ++ struct sysreset_reg *priv; ++ ++ /* The reset driver does not have a device node, so bind it here */ ++ ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", ++ &sys_child); ++ if (ret) { ++ debug("Warning: No sysreset driver: ret=%d\n", ret); ++ } else { ++ priv = malloc(sizeof(struct sysreset_reg)); ++ priv->glb_srst_fst_value = offsetof(struct px30_cru, ++ glb_srst_fst); ++ priv->glb_srst_snd_value = offsetof(struct px30_cru, ++ glb_srst_snd); ++ sys_child->priv = priv; ++ } ++ ++#if CONFIG_IS_ENABLED(RESET_ROCKCHIP) ++ ret = offsetof(struct px30_cru, softrst_con[0]); ++ ret = rockchip_reset_bind(dev, ret, 12); ++ if (ret) ++ debug("Warning: software reset driver bind faile\n"); ++#endif ++ ++ return 0; ++} ++ ++static const struct udevice_id px30_clk_ids[] = { ++ { .compatible = "rockchip,px30-cru" }, ++ { } ++}; ++ ++U_BOOT_DRIVER(rockchip_px30_cru) = { ++ .name = "rockchip_px30_cru", ++ .id = UCLASS_CLK, ++ .of_match = px30_clk_ids, ++ .priv_auto_alloc_size = sizeof(struct px30_clk_priv), ++ .ofdata_to_platdata = px30_clk_ofdata_to_platdata, ++ .ops = &px30_clk_ops, ++ .bind = px30_clk_bind, ++ .probe = px30_clk_probe, ++}; ++ ++static ulong px30_pclk_pmu_get_pmuclk(struct px30_pmuclk_priv *priv) ++{ ++ struct px30_pmucru *pmucru = priv->pmucru; ++ u32 div, con; ++ ++ con = readl(&pmucru->pmu_clksel_con[0]); ++ div = (con & CLK_PMU_PCLK_DIV_MASK) >> CLK_PMU_PCLK_DIV_SHIFT; ++ ++ return DIV_TO_RATE(priv->gpll_hz, div); ++} ++ ++static ulong px30_pclk_pmu_set_pmuclk(struct px30_pmuclk_priv *priv, ulong hz) ++{ ++ struct px30_pmucru *pmucru = priv->pmucru; ++ int src_clk_div; ++ ++ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz); ++ assert(src_clk_div - 1 <= 31); ++ ++ rk_clrsetreg(&pmucru->pmu_clksel_con[0], ++ CLK_PMU_PCLK_DIV_MASK, ++ (src_clk_div - 1) << CLK_PMU_PCLK_DIV_SHIFT); ++ ++ return px30_pclk_pmu_get_pmuclk(priv); ++} ++ ++static ulong px30_pmuclk_get_gpll_rate(struct px30_pmuclk_priv *priv) ++{ ++ struct px30_pmucru *pmucru = priv->pmucru; ++ ++ return rkclk_pll_get_rate(&pmucru->pll, &pmucru->pmu_mode, GPLL); ++} ++ ++static ulong px30_pmuclk_set_gpll_rate(struct px30_pmuclk_priv *priv, ulong hz) ++{ ++ struct px30_pmucru *pmucru = priv->pmucru; ++ ulong pclk_pmu_rate; ++ u32 div; ++ ++ if (priv->gpll_hz == hz) ++ return priv->gpll_hz; ++ ++ div = DIV_ROUND_UP(hz, priv->gpll_hz); ++ ++ /* save clock rate */ ++ pclk_pmu_rate = px30_pclk_pmu_get_pmuclk(priv); ++ ++ /* avoid rate too large, reduce rate first */ ++ px30_pclk_pmu_set_pmuclk(priv, pclk_pmu_rate / div); ++ ++ /* change gpll rate */ ++ rkclk_set_pll(&pmucru->pll, &pmucru->pmu_mode, GPLL, hz); ++ priv->gpll_hz = px30_pmuclk_get_gpll_rate(priv); ++ ++ /* restore clock rate */ ++ px30_pclk_pmu_set_pmuclk(priv, pclk_pmu_rate); ++ ++ return priv->gpll_hz; ++} ++ ++static ulong px30_pmuclk_get_rate(struct clk *clk) ++{ ++ struct px30_pmuclk_priv *priv = dev_get_priv(clk->dev); ++ ulong rate = 0; ++ ++ debug("%s %ld\n", __func__, clk->id); ++ switch (clk->id) { ++ case PLL_GPLL: ++ rate = px30_pmuclk_get_gpll_rate(priv); ++ break; ++ case PCLK_PMU_PRE: ++ rate = px30_pclk_pmu_get_pmuclk(priv); ++ break; ++ default: ++ return -ENOENT; ++ } ++ ++ return rate; ++} ++ ++static ulong px30_pmuclk_set_rate(struct clk *clk, ulong rate) ++{ ++ struct px30_pmuclk_priv *priv = dev_get_priv(clk->dev); ++ ulong ret = 0; ++ ++ debug("%s %ld %ld\n", __func__, clk->id, rate); ++ switch (clk->id) { ++ case PLL_GPLL: ++ ret = px30_pmuclk_set_gpll_rate(priv, rate); ++ break; ++ case PCLK_PMU_PRE: ++ ret = px30_pclk_pmu_set_pmuclk(priv, rate); ++ break; ++ default: ++ return -ENOENT; ++ } ++ ++ return ret; ++} ++ ++static struct clk_ops px30_pmuclk_ops = { ++ .get_rate = px30_pmuclk_get_rate, ++ .set_rate = px30_pmuclk_set_rate, ++}; ++ ++static void px30_pmuclk_init(struct px30_pmuclk_priv *priv) ++{ ++ priv->gpll_hz = px30_pmuclk_get_gpll_rate(priv); ++ px30_pmuclk_set_gpll_rate(priv, GPLL_HZ); ++ ++ px30_pclk_pmu_set_pmuclk(priv, PCLK_PMU_HZ); ++} ++ ++static int px30_pmuclk_probe(struct udevice *dev) ++{ ++ struct px30_pmuclk_priv *priv = dev_get_priv(dev); ++ ++ px30_pmuclk_init(priv); ++ ++ return 0; ++} ++ ++static int px30_pmuclk_ofdata_to_platdata(struct udevice *dev) ++{ ++ struct px30_pmuclk_priv *priv = dev_get_priv(dev); ++ ++ priv->pmucru = dev_read_addr_ptr(dev); ++ ++ return 0; ++} ++ ++static const struct udevice_id px30_pmuclk_ids[] = { ++ { .compatible = "rockchip,px30-pmucru" }, ++ { } ++}; ++ ++U_BOOT_DRIVER(rockchip_px30_pmucru) = { ++ .name = "rockchip_px30_pmucru", ++ .id = UCLASS_CLK, ++ .of_match = px30_pmuclk_ids, ++ .priv_auto_alloc_size = sizeof(struct px30_pmuclk_priv), ++ .ofdata_to_platdata = px30_pmuclk_ofdata_to_platdata, ++ .ops = &px30_pmuclk_ops, ++ .probe = px30_pmuclk_probe, ++}; +diff --git a/include/dt-bindings/clock/px30-cru.h b/include/dt-bindings/clock/px30-cru.h +new file mode 100644 +index 0000000000..e5e59690b5 +--- /dev/null ++++ b/include/dt-bindings/clock/px30-cru.h +@@ -0,0 +1,389 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Copyright (c) 2017 Rockchip Electronics Co. Ltd. ++ * Author: Elaine <zhangqing@rock-chips.com> ++ */ ++ ++#ifndef _DT_BINDINGS_CLK_ROCKCHIP_PX30_H ++#define _DT_BINDINGS_CLK_ROCKCHIP_PX30_H ++ ++/* core clocks */ ++#define PLL_APLL 1 ++#define PLL_DPLL 2 ++#define PLL_CPLL 3 ++#define PLL_NPLL 4 ++#define APLL_BOOST_H 5 ++#define APLL_BOOST_L 6 ++#define ARMCLK 7 ++ ++/* sclk gates (special clocks) */ ++#define USB480M 14 ++#define SCLK_PDM 15 ++#define SCLK_I2S0_TX 16 ++#define SCLK_I2S0_TX_OUT 17 ++#define SCLK_I2S0_RX 18 ++#define SCLK_I2S0_RX_OUT 19 ++#define SCLK_I2S1 20 ++#define SCLK_I2S1_OUT 21 ++#define SCLK_I2S2 22 ++#define SCLK_I2S2_OUT 23 ++#define SCLK_UART1 24 ++#define SCLK_UART2 25 ++#define SCLK_UART3 26 ++#define SCLK_UART4 27 ++#define SCLK_UART5 28 ++#define SCLK_I2C0 29 ++#define SCLK_I2C1 30 ++#define SCLK_I2C2 31 ++#define SCLK_I2C3 32 ++#define SCLK_I2C4 33 ++#define SCLK_PWM0 34 ++#define SCLK_PWM1 35 ++#define SCLK_SPI0 36 ++#define SCLK_SPI1 37 ++#define SCLK_TIMER0 38 ++#define SCLK_TIMER1 39 ++#define SCLK_TIMER2 40 ++#define SCLK_TIMER3 41 ++#define SCLK_TIMER4 42 ++#define SCLK_TIMER5 43 ++#define SCLK_TSADC 44 ++#define SCLK_SARADC 45 ++#define SCLK_OTP 46 ++#define SCLK_OTP_USR 47 ++#define SCLK_CRYPTO 48 ++#define SCLK_CRYPTO_APK 49 ++#define SCLK_DDRC 50 ++#define SCLK_ISP 51 ++#define SCLK_CIF_OUT 52 ++#define SCLK_RGA_CORE 53 ++#define SCLK_VOPB_PWM 54 ++#define SCLK_NANDC 55 ++#define SCLK_SDIO 56 ++#define SCLK_EMMC 57 ++#define SCLK_SFC 58 ++#define SCLK_SDMMC 59 ++#define SCLK_OTG_ADP 60 ++#define SCLK_GMAC_SRC 61 ++#define SCLK_GMAC 62 ++#define SCLK_GMAC_RX_TX 63 ++#define SCLK_MAC_REF 64 ++#define SCLK_MAC_REFOUT 65 ++#define SCLK_MAC_OUT 66 ++#define SCLK_SDMMC_DRV 67 ++#define SCLK_SDMMC_SAMPLE 68 ++#define SCLK_SDIO_DRV 69 ++#define SCLK_SDIO_SAMPLE 70 ++#define SCLK_EMMC_DRV 71 ++#define SCLK_EMMC_SAMPLE 72 ++#define SCLK_GPU 73 ++#define SCLK_PVTM 74 ++#define SCLK_CORE_VPU 75 ++#define SCLK_GMAC_RMII 76 ++#define SCLK_UART2_SRC 77 ++#define SCLK_NANDC_DIV 78 ++#define SCLK_NANDC_DIV50 79 ++#define SCLK_SDIO_DIV 80 ++#define SCLK_SDIO_DIV50 81 ++#define SCLK_EMMC_DIV 82 ++#define SCLK_EMMC_DIV50 83 ++ ++/* dclk gates */ ++#define DCLK_VOPB 150 ++#define DCLK_VOPL 151 ++ ++/* aclk gates */ ++#define ACLK_GPU 170 ++#define ACLK_BUS_PRE 171 ++#define ACLK_CRYPTO 172 ++#define ACLK_VI_PRE 173 ++#define ACLK_VO_PRE 174 ++#define ACLK_VPU 175 ++#define ACLK_PERI_PRE 176 ++#define ACLK_GMAC 178 ++#define ACLK_CIF 179 ++#define ACLK_ISP 180 ++#define ACLK_VOPB 181 ++#define ACLK_VOPL 182 ++#define ACLK_RGA 183 ++#define ACLK_GIC 184 ++#define ACLK_DCF 186 ++#define ACLK_DMAC 187 ++ ++/* hclk gates */ ++#define HCLK_BUS_PRE 240 ++#define HCLK_CRYPTO 241 ++#define HCLK_VI_PRE 242 ++#define HCLK_VO_PRE 243 ++#define HCLK_VPU 244 ++#define HCLK_PERI_PRE 245 ++#define HCLK_MMC_NAND 246 ++#define HCLK_SDMMC 247 ++#define HCLK_USB 248 ++#define HCLK_CIF 249 ++#define HCLK_ISP 250 ++#define HCLK_VOPB 251 ++#define HCLK_VOPL 252 ++#define HCLK_RGA 253 ++#define HCLK_NANDC 254 ++#define HCLK_SDIO 255 ++#define HCLK_EMMC 256 ++#define HCLK_SFC 257 ++#define HCLK_OTG 258 ++#define HCLK_HOST 259 ++#define HCLK_HOST_ARB 260 ++#define HCLK_PDM 261 ++#define HCLK_I2S0 262 ++#define HCLK_I2S1 263 ++#define HCLK_I2S2 264 ++ ++/* pclk gates */ ++#define PCLK_BUS_PRE 320 ++#define PCLK_DDR 321 ++#define PCLK_VO_PRE 322 ++#define PCLK_GMAC 323 ++#define PCLK_MIPI_DSI 324 ++#define PCLK_MIPIDSIPHY 325 ++#define PCLK_MIPICSIPHY 326 ++#define PCLK_USB_GRF 327 ++#define PCLK_DCF 328 ++#define PCLK_UART1 329 ++#define PCLK_UART2 330 ++#define PCLK_UART3 331 ++#define PCLK_UART4 332 ++#define PCLK_UART5 333 ++#define PCLK_I2C0 334 ++#define PCLK_I2C1 335 ++#define PCLK_I2C2 336 ++#define PCLK_I2C3 337 ++#define PCLK_I2C4 338 ++#define PCLK_PWM0 339 ++#define PCLK_PWM1 340 ++#define PCLK_SPI0 341 ++#define PCLK_SPI1 342 ++#define PCLK_SARADC 343 ++#define PCLK_TSADC 344 ++#define PCLK_TIMER 345 ++#define PCLK_OTP_NS 346 ++#define PCLK_WDT_NS 347 ++#define PCLK_GPIO1 348 ++#define PCLK_GPIO2 349 ++#define PCLK_GPIO3 350 ++#define PCLK_ISP 351 ++#define PCLK_CIF 352 ++#define PCLK_OTP_PHY 353 ++ ++#define CLK_NR_CLKS (PCLK_OTP_PHY + 1) ++ ++/* pmu-clocks indices */ ++ ++#define PLL_GPLL 1 ++ ++#define SCLK_RTC32K_PMU 4 ++#define SCLK_WIFI_PMU 5 ++#define SCLK_UART0_PMU 6 ++#define SCLK_PVTM_PMU 7 ++#define PCLK_PMU_PRE 8 ++#define SCLK_REF24M_PMU 9 ++#define SCLK_USBPHY_REF 10 ++#define SCLK_MIPIDSIPHY_REF 11 ++ ++#define XIN24M_DIV 12 ++ ++#define PCLK_GPIO0_PMU 20 ++#define PCLK_UART0_PMU 21 ++ ++#define CLKPMU_NR_CLKS (PCLK_UART0_PMU + 1) ++ ++/* soft-reset indices */ ++#define SRST_CORE0_PO 0 ++#define SRST_CORE1_PO 1 ++#define SRST_CORE2_PO 2 ++#define SRST_CORE3_PO 3 ++#define SRST_CORE0 4 ++#define SRST_CORE1 5 ++#define SRST_CORE2 6 ++#define SRST_CORE3 7 ++#define SRST_CORE0_DBG 8 ++#define SRST_CORE1_DBG 9 ++#define SRST_CORE2_DBG 10 ++#define SRST_CORE3_DBG 11 ++#define SRST_TOPDBG 12 ++#define SRST_CORE_NOC 13 ++#define SRST_STRC_A 14 ++#define SRST_L2C 15 ++ ++#define SRST_DAP 16 ++#define SRST_CORE_PVTM 17 ++#define SRST_GPU 18 ++#define SRST_GPU_NIU 19 ++#define SRST_UPCTL2 20 ++#define SRST_UPCTL2_A 21 ++#define SRST_UPCTL2_P 22 ++#define SRST_MSCH 23 ++#define SRST_MSCH_P 24 ++#define SRST_DDRMON_P 25 ++#define SRST_DDRSTDBY_P 26 ++#define SRST_DDRSTDBY 27 ++#define SRST_DDRGRF_p 28 ++#define SRST_AXI_SPLIT_A 29 ++#define SRST_AXI_CMD_A 30 ++#define SRST_AXI_CMD_P 31 ++ ++#define SRST_DDRPHY 32 ++#define SRST_DDRPHYDIV 33 ++#define SRST_DDRPHY_P 34 ++#define SRST_VPU_A 36 ++#define SRST_VPU_NIU_A 37 ++#define SRST_VPU_H 38 ++#define SRST_VPU_NIU_H 39 ++#define SRST_VI_NIU_A 40 ++#define SRST_VI_NIU_H 41 ++#define SRST_ISP_H 42 ++#define SRST_ISP 43 ++#define SRST_CIF_A 44 ++#define SRST_CIF_H 45 ++#define SRST_CIF_PCLKIN 46 ++#define SRST_MIPICSIPHY_P 47 ++ ++#define SRST_VO_NIU_A 48 ++#define SRST_VO_NIU_H 49 ++#define SRST_VO_NIU_P 50 ++#define SRST_VOPB_A 51 ++#define SRST_VOPB_H 52 ++#define SRST_VOPB 53 ++#define SRST_PWM_VOPB 54 ++#define SRST_VOPL_A 55 ++#define SRST_VOPL_H 56 ++#define SRST_VOPL 57 ++#define SRST_RGA_A 58 ++#define SRST_RGA_H 59 ++#define SRST_RGA 60 ++#define SRST_MIPIDSI_HOST_P 61 ++#define SRST_MIPIDSIPHY_P 62 ++#define SRST_VPU_CORE 63 ++ ++#define SRST_PERI_NIU_A 64 ++#define SRST_USB_NIU_H 65 ++#define SRST_USB2OTG_H 66 ++#define SRST_USB2OTG 67 ++#define SRST_USB2OTG_ADP 68 ++#define SRST_USB2HOST_H 69 ++#define SRST_USB2HOST_ARB_H 70 ++#define SRST_USB2HOST_AUX_H 71 ++#define SRST_USB2HOST_EHCI 72 ++#define SRST_USB2HOST 73 ++#define SRST_USBPHYPOR 74 ++#define SRST_USBPHY_OTG_PORT 75 ++#define SRST_USBPHY_HOST_PORT 76 ++#define SRST_USBPHY_GRF 77 ++#define SRST_CPU_BOOST_P 78 ++#define SRST_CPU_BOOST 79 ++ ++#define SRST_MMC_NAND_NIU_H 80 ++#define SRST_SDIO_H 81 ++#define SRST_EMMC_H 82 ++#define SRST_SFC_H 83 ++#define SRST_SFC 84 ++#define SRST_SDCARD_NIU_H 85 ++#define SRST_SDMMC_H 86 ++#define SRST_NANDC_H 89 ++#define SRST_NANDC 90 ++#define SRST_GMAC_NIU_A 92 ++#define SRST_GMAC_NIU_P 93 ++#define SRST_GMAC_A 94 ++ ++#define SRST_PMU_NIU_P 96 ++#define SRST_PMU_SGRF_P 97 ++#define SRST_PMU_GRF_P 98 ++#define SRST_PMU 99 ++#define SRST_PMU_MEM_P 100 ++#define SRST_PMU_GPIO0_P 101 ++#define SRST_PMU_UART0_P 102 ++#define SRST_PMU_CRU_P 103 ++#define SRST_PMU_PVTM 104 ++#define SRST_PMU_UART 105 ++#define SRST_PMU_NIU_H 106 ++#define SRST_PMU_DDR_FAIL_SAVE 107 ++#define SRST_PMU_CORE_PERF_A 108 ++#define SRST_PMU_CORE_GRF_P 109 ++#define SRST_PMU_GPU_PERF_A 110 ++#define SRST_PMU_GPU_GRF_P 111 ++ ++#define SRST_CRYPTO_NIU_A 112 ++#define SRST_CRYPTO_NIU_H 113 ++#define SRST_CRYPTO_A 114 ++#define SRST_CRYPTO_H 115 ++#define SRST_CRYPTO 116 ++#define SRST_CRYPTO_APK 117 ++#define SRST_BUS_NIU_H 120 ++#define SRST_USB_NIU_P 121 ++#define SRST_BUS_TOP_NIU_P 122 ++#define SRST_INTMEM_A 123 ++#define SRST_GIC_A 124 ++#define SRST_ROM_H 126 ++#define SRST_DCF_A 127 ++ ++#define SRST_DCF_P 128 ++#define SRST_PDM_H 129 ++#define SRST_PDM 130 ++#define SRST_I2S0_H 131 ++#define SRST_I2S0_TX 132 ++#define SRST_I2S1_H 133 ++#define SRST_I2S1 134 ++#define SRST_I2S2_H 135 ++#define SRST_I2S2 136 ++#define SRST_UART1_P 137 ++#define SRST_UART1 138 ++#define SRST_UART2_P 139 ++#define SRST_UART2 140 ++#define SRST_UART3_P 141 ++#define SRST_UART3 142 ++#define SRST_UART4_P 143 ++ ++#define SRST_UART4 144 ++#define SRST_UART5_P 145 ++#define SRST_UART5 146 ++#define SRST_I2C0_P 147 ++#define SRST_I2C0 148 ++#define SRST_I2C1_P 149 ++#define SRST_I2C1 150 ++#define SRST_I2C2_P 151 ++#define SRST_I2C2 152 ++#define SRST_I2C3_P 153 ++#define SRST_I2C3 154 ++#define SRST_PWM0_P 157 ++#define SRST_PWM0 158 ++#define SRST_PWM1_P 159 ++ ++#define SRST_PWM1 160 ++#define SRST_SPI0_P 161 ++#define SRST_SPI0 162 ++#define SRST_SPI1_P 163 ++#define SRST_SPI1 164 ++#define SRST_SARADC_P 165 ++#define SRST_SARADC 166 ++#define SRST_TSADC_P 167 ++#define SRST_TSADC 168 ++#define SRST_TIMER_P 169 ++#define SRST_TIMER0 170 ++#define SRST_TIMER1 171 ++#define SRST_TIMER2 172 ++#define SRST_TIMER3 173 ++#define SRST_TIMER4 174 ++#define SRST_TIMER5 175 ++ ++#define SRST_OTP_NS_P 176 ++#define SRST_OTP_NS_SBPI 177 ++#define SRST_OTP_NS_USR 178 ++#define SRST_OTP_PHY_P 179 ++#define SRST_OTP_PHY 180 ++#define SRST_WDT_NS_P 181 ++#define SRST_GPIO1_P 182 ++#define SRST_GPIO2_P 183 ++#define SRST_GPIO3_P 184 ++#define SRST_SGRF_P 185 ++#define SRST_GRF_P 186 ++#define SRST_I2S0_RX 191 ++ ++#endif + +From patchwork Thu Oct 24 23:27:56 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: =?utf-8?q?Heiko_St=C3=BCbner?= <heiko@sntech.de> +X-Patchwork-Id: 1183656 +X-Patchwork-Delegate: ykai007@gmail.com +Return-Path: <u-boot-bounces@lists.denx.de> +X-Original-To: incoming@patchwork.ozlabs.org +Delivered-To: patchwork-incoming@bilbo.ozlabs.org +Authentication-Results: ozlabs.org; + spf=none (no SPF record) smtp.mailfrom=lists.denx.de + (client-ip=81.169.180.215; helo=lists.denx.de; + envelope-from=u-boot-bounces@lists.denx.de; + receiver=<UNKNOWN>) +Authentication-Results: ozlabs.org; + dmarc=none (p=none dis=none) header.from=sntech.de +Received: from lists.denx.de (dione.denx.de [81.169.180.215]) + by ozlabs.org (Postfix) with ESMTP id 46zk4y0XzPz9sPL + for <incoming@patchwork.ozlabs.org>; + Fri, 25 Oct 2019 10:30:42 +1100 (AEDT) +Received: by lists.denx.de (Postfix, from userid 105) + id BAF13C21E1B; Thu, 24 Oct 2019 23:28:58 +0000 (UTC) +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de +X-Spam-Level: +X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable + autolearn_force=no version=3.4.0 +Received: from lists.denx.de (localhost [IPv6:::1]) + by lists.denx.de (Postfix) with ESMTP id D7FFAC21E0F; + Thu, 24 Oct 2019 23:28:19 +0000 (UTC) +Received: by lists.denx.de (Postfix, from userid 105) + id EEFA9C21D74; Thu, 24 Oct 2019 23:28:17 +0000 (UTC) +Received: from gloria.sntech.de (gloria.sntech.de [185.11.138.130]) + by lists.denx.de (Postfix) with ESMTPS id 668F7C21DA6 + for <u-boot@lists.denx.de>; Thu, 24 Oct 2019 23:28:17 +0000 (UTC) +Received: from ip5f5a6266.dynamic.kabel-deutschland.de ([95.90.98.102] + helo=phil.fritz.box) by gloria.sntech.de with esmtpsa + (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) + (Exim 4.89) (envelope-from <heiko@sntech.de>) + id 1iNmWe-0002cR-VL; Fri, 25 Oct 2019 01:28:17 +0200 +From: Heiko Stuebner <heiko@sntech.de> +To: u-boot@lists.denx.de +Date: Fri, 25 Oct 2019 01:27:56 +0200 +Message-Id: <20191024232803.10338-6-heiko@sntech.de> +X-Mailer: git-send-email 2.23.0 +In-Reply-To: <20191024232803.10338-1-heiko@sntech.de> +References: <20191024232803.10338-1-heiko@sntech.de> +MIME-Version: 1.0 +Cc: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>, + joe.hershberger@ni.com, christoph.muellner@theobroma-systems.com +Subject: [U-Boot] [PATCH 05/12] net: gmac_rockchip: add support for px30 +X-BeenThere: u-boot@lists.denx.de +X-Mailman-Version: 2.1.18 +Precedence: list +List-Id: U-Boot discussion <u-boot.lists.denx.de> +List-Unsubscribe: <https://lists.denx.de/options/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=unsubscribe> +List-Archive: <http://lists.denx.de/pipermail/u-boot/> +List-Post: <mailto:u-boot@lists.denx.de> +List-Help: <mailto:u-boot-request@lists.denx.de?subject=help> +List-Subscribe: <https://lists.denx.de/listinfo/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=subscribe> +Errors-To: u-boot-bounces@lists.denx.de +Sender: "U-Boot" <u-boot-bounces@lists.denx.de> + +Add the glue code to allow the px30 variant of the Rockchip gmac +to provide network functionality. + +Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com> +Reviewed-by: Kever Yang<kever.yang@rock-chips.com> +--- + drivers/net/gmac_rockchip.c | 69 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 69 insertions(+) + +diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c +index 26a6121175..3f3e38a2c6 100644 +--- a/drivers/net/gmac_rockchip.c ++++ b/drivers/net/gmac_rockchip.c +@@ -14,6 +14,7 @@ + #include <asm/arch-rockchip/periph.h> + #include <asm/arch-rockchip/clock.h> + #include <asm/arch-rockchip/hardware.h> ++#include <asm/arch-rockchip/grf_px30.h> + #include <asm/arch-rockchip/grf_rk322x.h> + #include <asm/arch-rockchip/grf_rk3288.h> + #include <asm/arch-rockchip/grf_rk3328.h> +@@ -72,6 +73,47 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) + return designware_eth_ofdata_to_platdata(dev); + } + ++static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++{ ++ struct px30_grf *grf; ++ struct clk clk_speed; ++ int speed, ret; ++ enum { ++ PX30_GMAC_SPEED_SHIFT = 0x2, ++ PX30_GMAC_SPEED_MASK = BIT(2), ++ PX30_GMAC_SPEED_10M = 0, ++ PX30_GMAC_SPEED_100M = BIT(2), ++ }; ++ ++ ret = clk_get_by_name(priv->phydev->dev, "clk_mac_speed", ++ &clk_speed); ++ if (ret) ++ return ret; ++ ++ switch (priv->phydev->speed) { ++ case 10: ++ speed = PX30_GMAC_SPEED_10M; ++ ret = clk_set_rate(&clk_speed, 2500000); ++ if (ret) ++ return ret; ++ break; ++ case 100: ++ speed = PX30_GMAC_SPEED_100M; ++ ret = clk_set_rate(&clk_speed, 25000000); ++ if (ret) ++ return ret; ++ break; ++ default: ++ debug("Unknown phy speed: %d\n", priv->phydev->speed); ++ return -EINVAL; ++ } ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(&grf->mac_con1, PX30_GMAC_SPEED_MASK, speed); ++ ++ return 0; ++} ++ + static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv) + { + struct rk322x_grf *grf; +@@ -257,6 +299,22 @@ static int rv1108_set_rmii_speed(struct dw_eth_dev *priv) + return 0; + } + ++static void px30_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata) ++{ ++ struct px30_grf *grf; ++ enum { ++ PX30_GMAC_PHY_INTF_SEL_SHIFT = 4, ++ PX30_GMAC_PHY_INTF_SEL_MASK = GENMASK(4, 6), ++ PX30_GMAC_PHY_INTF_SEL_RMII = BIT(6), ++ }; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ ++ rk_clrsetreg(&grf->mac_con1, ++ PX30_GMAC_PHY_INTF_SEL_MASK, ++ PX30_GMAC_PHY_INTF_SEL_RMII); ++} ++ + static void rk3228_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) + { + struct rk322x_grf *grf; +@@ -445,6 +503,10 @@ static int gmac_rockchip_probe(struct udevice *dev) + ulong rate; + int ret; + ++ ret = clk_set_defaults(dev); ++ if (ret) ++ debug("%s clk_set_defaults failed %d\n", __func__, ret); ++ + ret = clk_get_by_index(dev, 0, &clk); + if (ret) + return ret; +@@ -569,6 +631,11 @@ const struct eth_ops gmac_rockchip_eth_ops = { + .write_hwaddr = designware_eth_write_hwaddr, + }; + ++const struct rk_gmac_ops px30_gmac_ops = { ++ .fix_mac_speed = px30_gmac_fix_mac_speed, ++ .set_to_rmii = px30_gmac_set_to_rmii, ++}; ++ + const struct rk_gmac_ops rk3228_gmac_ops = { + .fix_mac_speed = rk3228_gmac_fix_mac_speed, + .set_to_rgmii = rk3228_gmac_set_to_rgmii, +@@ -600,6 +667,8 @@ const struct rk_gmac_ops rv1108_gmac_ops = { + }; + + static const struct udevice_id rockchip_gmac_ids[] = { ++ { .compatible = "rockchip,px30-gmac", ++ .data = (ulong)&px30_gmac_ops }, + { .compatible = "rockchip,rk3228-gmac", + .data = (ulong)&rk3228_gmac_ops }, + { .compatible = "rockchip,rk3288-gmac", + +From patchwork Thu Oct 24 23:27:57 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: =?utf-8?q?Heiko_St=C3=BCbner?= <heiko@sntech.de> +X-Patchwork-Id: 1183655 +X-Patchwork-Delegate: ykai007@gmail.com +Return-Path: <u-boot-bounces@lists.denx.de> +X-Original-To: incoming@patchwork.ozlabs.org +Delivered-To: patchwork-incoming@bilbo.ozlabs.org +Authentication-Results: ozlabs.org; + spf=none (no SPF record) smtp.mailfrom=lists.denx.de + (client-ip=81.169.180.215; helo=lists.denx.de; + envelope-from=u-boot-bounces@lists.denx.de; + receiver=<UNKNOWN>) +Authentication-Results: ozlabs.org; + dmarc=none (p=none dis=none) header.from=sntech.de +Received: from lists.denx.de (dione.denx.de [81.169.180.215]) + by ozlabs.org (Postfix) with ESMTP id 46zk4t73sdz9sPL + for <incoming@patchwork.ozlabs.org>; + Fri, 25 Oct 2019 10:30:38 +1100 (AEDT) +Received: by lists.denx.de (Postfix, from userid 105) + id B8310C21DC1; Thu, 24 Oct 2019 23:29:09 +0000 (UTC) +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de +X-Spam-Level: +X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable + autolearn_force=no version=3.4.0 +Received: from lists.denx.de (localhost [IPv6:::1]) + by lists.denx.de (Postfix) with ESMTP id 7CDCBC21E1B; + Thu, 24 Oct 2019 23:28:20 +0000 (UTC) +Received: by lists.denx.de (Postfix, from userid 105) + id 10669C21D8A; Thu, 24 Oct 2019 23:28:17 +0000 (UTC) +Received: from gloria.sntech.de (gloria.sntech.de [185.11.138.130]) + by lists.denx.de (Postfix) with ESMTPS id A1DB1C21DB3 + for <u-boot@lists.denx.de>; Thu, 24 Oct 2019 23:28:17 +0000 (UTC) +Received: from ip5f5a6266.dynamic.kabel-deutschland.de ([95.90.98.102] + helo=phil.fritz.box) by gloria.sntech.de with esmtpsa + (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) + (Exim 4.89) (envelope-from <heiko@sntech.de>) + id 1iNmWf-0002cR-B0; Fri, 25 Oct 2019 01:28:17 +0200 +From: Heiko Stuebner <heiko@sntech.de> +To: u-boot@lists.denx.de +Date: Fri, 25 Oct 2019 01:27:57 +0200 +Message-Id: <20191024232803.10338-7-heiko@sntech.de> +X-Mailer: git-send-email 2.23.0 +In-Reply-To: <20191024232803.10338-1-heiko@sntech.de> +References: <20191024232803.10338-1-heiko@sntech.de> +MIME-Version: 1.0 +Cc: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>, + joe.hershberger@ni.com, christoph.muellner@theobroma-systems.com +Subject: [U-Boot] [PATCH 06/12] rockchip: mkimage: add support for px30 +X-BeenThere: u-boot@lists.denx.de +X-Mailman-Version: 2.1.18 +Precedence: list +List-Id: U-Boot discussion <u-boot.lists.denx.de> +List-Unsubscribe: <https://lists.denx.de/options/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=unsubscribe> +List-Archive: <http://lists.denx.de/pipermail/u-boot/> +List-Post: <mailto:u-boot@lists.denx.de> +List-Help: <mailto:u-boot-request@lists.denx.de?subject=help> +List-Subscribe: <https://lists.denx.de/listinfo/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=subscribe> +Errors-To: u-boot-bounces@lists.denx.de +Sender: "U-Boot" <u-boot-bounces@lists.denx.de> + +From: Kever Yang <kever.yang@rock-chips.com> + +Add the table entry for px30 socs. +The px30 has 10K of sram available. + +Signed-off-by: Kever Yang <kever.yang@rock-chips.com> +Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com> +Reviewed-by: Kever Yang<kever.yang@rock-chips.com> +--- + tools/rkcommon.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/rkcommon.c b/tools/rkcommon.c +index 831c2ad820..83df82e4b0 100644 +--- a/tools/rkcommon.c ++++ b/tools/rkcommon.c +@@ -67,6 +67,7 @@ struct spl_info { + }; + + static struct spl_info spl_infos[] = { ++ { "px30", "RK33", 0x2800, false }, + { "rk3036", "RK30", 0x1000, false }, + { "rk3128", "RK31", 0x1800, false }, + { "rk3188", "RK31", 0x8000 - 0x800, true }, + +From patchwork Thu Oct 24 23:27:58 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: =?utf-8?q?Heiko_St=C3=BCbner?= <heiko@sntech.de> +X-Patchwork-Id: 1183658 +X-Patchwork-Delegate: ykai007@gmail.com +Return-Path: <u-boot-bounces@lists.denx.de> +X-Original-To: incoming@patchwork.ozlabs.org +Delivered-To: patchwork-incoming@bilbo.ozlabs.org +Authentication-Results: ozlabs.org; + spf=none (no SPF record) smtp.mailfrom=lists.denx.de + (client-ip=81.169.180.215; helo=lists.denx.de; + envelope-from=u-boot-bounces@lists.denx.de; + receiver=<UNKNOWN>) +Authentication-Results: ozlabs.org; + dmarc=none (p=none dis=none) header.from=sntech.de +Received: from lists.denx.de (dione.denx.de [81.169.180.215]) + by ozlabs.org (Postfix) with ESMTP id 46zk5k66Vpz9sPL + for <incoming@patchwork.ozlabs.org>; + Fri, 25 Oct 2019 10:31:22 +1100 (AEDT) +Received: by lists.denx.de (Postfix, from userid 105) + id 8E320C21E13; Thu, 24 Oct 2019 23:29:48 +0000 (UTC) +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de +X-Spam-Level: +X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable + autolearn_force=no version=3.4.0 +Received: from lists.denx.de (localhost [IPv6:::1]) + by lists.denx.de (Postfix) with ESMTP id 45147C21E5B; + Thu, 24 Oct 2019 23:28:22 +0000 (UTC) +Received: by lists.denx.de (Postfix, from userid 105) + id 526D9C21DA6; Thu, 24 Oct 2019 23:28:18 +0000 (UTC) +Received: from gloria.sntech.de (gloria.sntech.de [185.11.138.130]) + by lists.denx.de (Postfix) with ESMTPS id 191A0C21D9A + for <u-boot@lists.denx.de>; Thu, 24 Oct 2019 23:28:18 +0000 (UTC) +Received: from ip5f5a6266.dynamic.kabel-deutschland.de ([95.90.98.102] + helo=phil.fritz.box) by gloria.sntech.de with esmtpsa + (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) + (Exim 4.89) (envelope-from <heiko@sntech.de>) + id 1iNmWf-0002cR-P0; Fri, 25 Oct 2019 01:28:17 +0200 +From: Heiko Stuebner <heiko@sntech.de> +To: u-boot@lists.denx.de +Date: Fri, 25 Oct 2019 01:27:58 +0200 +Message-Id: <20191024232803.10338-8-heiko@sntech.de> +X-Mailer: git-send-email 2.23.0 +In-Reply-To: <20191024232803.10338-1-heiko@sntech.de> +References: <20191024232803.10338-1-heiko@sntech.de> +MIME-Version: 1.0 +Cc: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>, + joe.hershberger@ni.com, Finley Xiao <finley.xiao@rock-chips.com>, + christoph.muellner@theobroma-systems.com +Subject: [U-Boot] [PATCH 07/12] misc: add driver for the Rockchip otp + controller +X-BeenThere: u-boot@lists.denx.de +X-Mailman-Version: 2.1.18 +Precedence: list +List-Id: U-Boot discussion <u-boot.lists.denx.de> +List-Unsubscribe: <https://lists.denx.de/options/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=unsubscribe> +List-Archive: <http://lists.denx.de/pipermail/u-boot/> +List-Post: <mailto:u-boot@lists.denx.de> +List-Help: <mailto:u-boot-request@lists.denx.de?subject=help> +List-Subscribe: <https://lists.denx.de/listinfo/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=subscribe> +Errors-To: u-boot-bounces@lists.denx.de +Sender: "U-Boot" <u-boot-bounces@lists.denx.de> + +From: Finley Xiao <finley.xiao@rock-chips.com> + +Newer Rockchip socs like the px30 use a different ip block to handle +one-time-programmable memory, so add a misc driver for it as well. + +Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com> +Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com> +Reviewed-by: Kever Yang<kever.yang@rock-chips.com> +--- + drivers/misc/Kconfig | 9 ++ + drivers/misc/Makefile | 1 + + drivers/misc/rockchip-otp.c | 176 ++++++++++++++++++++++++++++++++++++ + 3 files changed, 186 insertions(+) + create mode 100644 drivers/misc/rockchip-otp.c + +diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig +index 8037b6ee2d..d68b24e6ec 100644 +--- a/drivers/misc/Kconfig ++++ b/drivers/misc/Kconfig +@@ -59,6 +59,15 @@ config ROCKCHIP_EFUSE + extended (by porting the read function from the Linux kernel sources) + to support other recent Rockchip devices. + ++config ROCKCHIP_OTP ++ bool "Rockchip OTP Support" ++ depends on MISC ++ help ++ Enable (read-only) access for the one-time-programmable memory block ++ found in Rockchip SoCs: accesses can either be made using byte ++ addressing and a length or through child-nodes that are generated ++ based on the e-fuse map retrieved from the DTS. ++ + config VEXPRESS_CONFIG + bool "Enable support for Arm Versatile Express config bus" + depends on MISC +diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile +index 509c588582..b172567297 100644 +--- a/drivers/misc/Makefile ++++ b/drivers/misc/Makefile +@@ -52,6 +52,7 @@ obj-$(CONFIG_PCA9551_LED) += pca9551_led.o + obj-$(CONFIG_$(SPL_)PWRSEQ) += pwrseq-uclass.o + obj-$(CONFIG_QFW) += qfw.o + obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o ++obj-$(CONFIG_ROCKCHIP_OTP) += rockchip-otp.o + obj-$(CONFIG_SANDBOX) += swap_case.o + obj-$(CONFIG_SANDBOX) += syscon_sandbox.o misc_sandbox.o + obj-$(CONFIG_SMSC_LPC47M) += smsc_lpc47m.o +diff --git a/drivers/misc/rockchip-otp.c b/drivers/misc/rockchip-otp.c +new file mode 100644 +index 0000000000..bdd443b3db +--- /dev/null ++++ b/drivers/misc/rockchip-otp.c +@@ -0,0 +1,176 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <command.h> ++#include <dm.h> ++#include <linux/bitops.h> ++#include <linux/delay.h> ++#include <misc.h> ++ ++/* OTP Register Offsets */ ++#define OTPC_SBPI_CTRL 0x0020 ++#define OTPC_SBPI_CMD_VALID_PRE 0x0024 ++#define OTPC_SBPI_CS_VALID_PRE 0x0028 ++#define OTPC_SBPI_STATUS 0x002C ++#define OTPC_USER_CTRL 0x0100 ++#define OTPC_USER_ADDR 0x0104 ++#define OTPC_USER_ENABLE 0x0108 ++#define OTPC_USER_QP 0x0120 ++#define OTPC_USER_Q 0x0124 ++#define OTPC_INT_STATUS 0x0304 ++#define OTPC_SBPI_CMD0_OFFSET 0x1000 ++#define OTPC_SBPI_CMD1_OFFSET 0x1004 ++ ++/* OTP Register bits and masks */ ++#define OTPC_USER_ADDR_MASK GENMASK(31, 16) ++#define OTPC_USE_USER BIT(0) ++#define OTPC_USE_USER_MASK GENMASK(16, 16) ++#define OTPC_USER_FSM_ENABLE BIT(0) ++#define OTPC_USER_FSM_ENABLE_MASK GENMASK(16, 16) ++#define OTPC_SBPI_DONE BIT(1) ++#define OTPC_USER_DONE BIT(2) ++ ++#define SBPI_DAP_ADDR 0x02 ++#define SBPI_DAP_ADDR_SHIFT 8 ++#define SBPI_DAP_ADDR_MASK GENMASK(31, 24) ++#define SBPI_CMD_VALID_MASK GENMASK(31, 16) ++#define SBPI_DAP_CMD_WRF 0xC0 ++#define SBPI_DAP_REG_ECC 0x3A ++#define SBPI_ECC_ENABLE 0x00 ++#define SBPI_ECC_DISABLE 0x09 ++#define SBPI_ENABLE BIT(0) ++#define SBPI_ENABLE_MASK GENMASK(16, 16) ++ ++#define OTPC_TIMEOUT 10000 ++ ++struct rockchip_otp_platdata { ++ void __iomem *base; ++ unsigned long secure_conf_base; ++ unsigned long otp_mask_base; ++}; ++ ++static int rockchip_otp_wait_status(struct rockchip_otp_platdata *otp, ++ u32 flag) ++{ ++ int delay = OTPC_TIMEOUT; ++ ++ while (!(readl(otp->base + OTPC_INT_STATUS) & flag)) { ++ udelay(1); ++ delay--; ++ if (delay <= 0) { ++ printf("%s: wait init status timeout\n", __func__); ++ return -ETIMEDOUT; ++ } ++ } ++ ++ /* clean int status */ ++ writel(flag, otp->base + OTPC_INT_STATUS); ++ ++ return 0; ++} ++ ++static int rockchip_otp_ecc_enable(struct rockchip_otp_platdata *otp, ++ bool enable) ++{ ++ int ret = 0; ++ ++ writel(SBPI_DAP_ADDR_MASK | (SBPI_DAP_ADDR << SBPI_DAP_ADDR_SHIFT), ++ otp->base + OTPC_SBPI_CTRL); ++ ++ writel(SBPI_CMD_VALID_MASK | 0x1, otp->base + OTPC_SBPI_CMD_VALID_PRE); ++ writel(SBPI_DAP_CMD_WRF | SBPI_DAP_REG_ECC, ++ otp->base + OTPC_SBPI_CMD0_OFFSET); ++ ++ if (enable) ++ writel(SBPI_ECC_ENABLE, otp->base + OTPC_SBPI_CMD1_OFFSET); ++ else ++ writel(SBPI_ECC_DISABLE, otp->base + OTPC_SBPI_CMD1_OFFSET); ++ ++ writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL); ++ ++ ret = rockchip_otp_wait_status(otp, OTPC_SBPI_DONE); ++ if (ret < 0) ++ printf("%s timeout during ecc_enable\n", __func__); ++ ++ return ret; ++} ++ ++static int rockchip_px30_otp_read(struct udevice *dev, int offset, ++ void *buf, int size) ++{ ++ struct rockchip_otp_platdata *otp = dev_get_platdata(dev); ++ u8 *buffer = buf; ++ int ret = 0; ++ ++ ret = rockchip_otp_ecc_enable(otp, false); ++ if (ret < 0) { ++ printf("%s rockchip_otp_ecc_enable err\n", __func__); ++ return ret; ++ } ++ ++ writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); ++ udelay(5); ++ while (size--) { ++ writel(offset++ | OTPC_USER_ADDR_MASK, ++ otp->base + OTPC_USER_ADDR); ++ writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK, ++ otp->base + OTPC_USER_ENABLE); ++ ++ ret = rockchip_otp_wait_status(otp, OTPC_USER_DONE); ++ if (ret < 0) { ++ printf("%s timeout during read setup\n", __func__); ++ goto read_end; ++ } ++ ++ *buffer++ = readb(otp->base + OTPC_USER_Q); ++ } ++ ++read_end: ++ writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); ++ ++ return ret; ++} ++ ++static int rockchip_otp_read(struct udevice *dev, int offset, ++ void *buf, int size) ++{ ++ return rockchip_px30_otp_read(dev, offset, buf, size); ++} ++ ++static const struct misc_ops rockchip_otp_ops = { ++ .read = rockchip_otp_read, ++}; ++ ++static int rockchip_otp_ofdata_to_platdata(struct udevice *dev) ++{ ++ struct rockchip_otp_platdata *otp = dev_get_platdata(dev); ++ ++ otp->base = dev_read_addr_ptr(dev); ++ ++ return 0; ++} ++ ++static const struct udevice_id rockchip_otp_ids[] = { ++ { ++ .compatible = "rockchip,px30-otp", ++ .data = (ulong)&rockchip_px30_otp_read, ++ }, ++ { ++ .compatible = "rockchip,rk3308-otp", ++ .data = (ulong)&rockchip_px30_otp_read, ++ }, ++ {} ++}; ++ ++U_BOOT_DRIVER(rockchip_otp) = { ++ .name = "rockchip_otp", ++ .id = UCLASS_MISC, ++ .of_match = rockchip_otp_ids, ++ .ops = &rockchip_otp_ops, ++ .ofdata_to_platdata = rockchip_otp_ofdata_to_platdata, ++ .platdata_auto_alloc_size = sizeof(struct rockchip_otp_platdata), ++}; + +From patchwork Thu Oct 24 23:27:59 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: =?utf-8?q?Heiko_St=C3=BCbner?= <heiko@sntech.de> +X-Patchwork-Id: 1183660 +X-Patchwork-Delegate: ykai007@gmail.com +Return-Path: <u-boot-bounces@lists.denx.de> +X-Original-To: incoming@patchwork.ozlabs.org +Delivered-To: patchwork-incoming@bilbo.ozlabs.org +Authentication-Results: ozlabs.org; + spf=none (no SPF record) smtp.mailfrom=lists.denx.de + (client-ip=81.169.180.215; helo=lists.denx.de; + envelope-from=u-boot-bounces@lists.denx.de; + receiver=<UNKNOWN>) +Authentication-Results: ozlabs.org; + dmarc=none (p=none dis=none) header.from=sntech.de +Received: from lists.denx.de (dione.denx.de [81.169.180.215]) + by ozlabs.org (Postfix) with ESMTP id 46zk7M11qTz9sPL + for <incoming@patchwork.ozlabs.org>; + Fri, 25 Oct 2019 10:32:47 +1100 (AEDT) +Received: by lists.denx.de (Postfix, from userid 105) + id CDB04C21DB3; Thu, 24 Oct 2019 23:31:26 +0000 (UTC) +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de +X-Spam-Level: +X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable + autolearn_force=no version=3.4.0 +Received: from lists.denx.de (localhost [IPv6:::1]) + by lists.denx.de (Postfix) with ESMTP id 74184C21E73; + Thu, 24 Oct 2019 23:28:23 +0000 (UTC) +Received: by lists.denx.de (Postfix, from userid 105) + id A4C7DC21D9A; Thu, 24 Oct 2019 23:28:18 +0000 (UTC) +Received: from gloria.sntech.de (gloria.sntech.de [185.11.138.130]) + by lists.denx.de (Postfix) with ESMTPS id 74C64C21C6A + for <u-boot@lists.denx.de>; Thu, 24 Oct 2019 23:28:18 +0000 (UTC) +Received: from ip5f5a6266.dynamic.kabel-deutschland.de ([95.90.98.102] + helo=phil.fritz.box) by gloria.sntech.de with esmtpsa + (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) + (Exim 4.89) (envelope-from <heiko@sntech.de>) + id 1iNmWg-0002cR-5C; Fri, 25 Oct 2019 01:28:18 +0200 +From: Heiko Stuebner <heiko@sntech.de> +To: u-boot@lists.denx.de +Date: Fri, 25 Oct 2019 01:27:59 +0200 +Message-Id: <20191024232803.10338-9-heiko@sntech.de> +X-Mailer: git-send-email 2.23.0 +In-Reply-To: <20191024232803.10338-1-heiko@sntech.de> +References: <20191024232803.10338-1-heiko@sntech.de> +MIME-Version: 1.0 +Cc: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>, + joe.hershberger@ni.com, christoph.muellner@theobroma-systems.com +Subject: [U-Boot] [PATCH 08/12] rockchip: misc: read cpuid either from efuse + or otp +X-BeenThere: u-boot@lists.denx.de +X-Mailman-Version: 2.1.18 +Precedence: list +List-Id: U-Boot discussion <u-boot.lists.denx.de> +List-Unsubscribe: <https://lists.denx.de/options/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=unsubscribe> +List-Archive: <http://lists.denx.de/pipermail/u-boot/> +List-Post: <mailto:u-boot@lists.denx.de> +List-Help: <mailto:u-boot-request@lists.denx.de?subject=help> +List-Subscribe: <https://lists.denx.de/listinfo/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=subscribe> +Errors-To: u-boot-bounces@lists.denx.de +Sender: "U-Boot" <u-boot-bounces@lists.denx.de> + +From: Heiko Stuebner <heiko.stuebner@theobroma-systems.com> + +Newer Rockchip socs use a different ip block to handle one-time- +programmable memory, so depending on what got enabled get the cpuid +from either source. + +Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com> +Reviewed-by: Kever Yang<kever.yang@rock-chips.com> +--- + arch/arm/mach-rockchip/misc.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/mach-rockchip/misc.c b/arch/arm/mach-rockchip/misc.c +index c0e4fdbc00..bed4317f7e 100644 +--- a/arch/arm/mach-rockchip/misc.c ++++ b/arch/arm/mach-rockchip/misc.c +@@ -57,13 +57,18 @@ int rockchip_cpuid_from_efuse(const u32 cpuid_offset, + const u32 cpuid_length, + u8 *cpuid) + { +-#if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE) ++#if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE) || CONFIG_IS_ENABLED(ROCKCHIP_OTP) + struct udevice *dev; + int ret; + + /* retrieve the device */ ++#if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE) + ret = uclass_get_device_by_driver(UCLASS_MISC, + DM_GET_DRIVER(rockchip_efuse), &dev); ++#elif CONFIG_IS_ENABLED(ROCKCHIP_OTP) ++ ret = uclass_get_device_by_driver(UCLASS_MISC, ++ DM_GET_DRIVER(rockchip_otp), &dev); ++#endif + if (ret) { + debug("%s: could not find efuse device\n", __func__); + return -1; + +From patchwork Thu Oct 24 23:28:00 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: =?utf-8?q?Heiko_St=C3=BCbner?= <heiko@sntech.de> +X-Patchwork-Id: 1183661 +X-Patchwork-Delegate: ykai007@gmail.com +Return-Path: <u-boot-bounces@lists.denx.de> +X-Original-To: incoming@patchwork.ozlabs.org +Delivered-To: patchwork-incoming@bilbo.ozlabs.org +Authentication-Results: ozlabs.org; + spf=none (no SPF record) smtp.mailfrom=lists.denx.de + (client-ip=81.169.180.215; helo=lists.denx.de; + envelope-from=u-boot-bounces@lists.denx.de; + receiver=<UNKNOWN>) +Authentication-Results: ozlabs.org; + dmarc=none (p=none dis=none) header.from=sntech.de +Received: from lists.denx.de (dione.denx.de [81.169.180.215]) + by ozlabs.org (Postfix) with ESMTP id 46zk7g4c2rz9sPL + for <incoming@patchwork.ozlabs.org>; + Fri, 25 Oct 2019 10:33:03 +1100 (AEDT) +Received: by lists.denx.de (Postfix, from userid 105) + id 4B5BCC21E47; Thu, 24 Oct 2019 23:31:35 +0000 (UTC) +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de +X-Spam-Level: +X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable + autolearn_force=no version=3.4.0 +Received: from lists.denx.de (localhost [IPv6:::1]) + by lists.denx.de (Postfix) with ESMTP id 05287C21E7F; + Thu, 24 Oct 2019 23:28:29 +0000 (UTC) +Received: by lists.denx.de (Postfix, from userid 105) + id 12715C21DF3; Thu, 24 Oct 2019 23:28:20 +0000 (UTC) +Received: from gloria.sntech.de (gloria.sntech.de [185.11.138.130]) + by lists.denx.de (Postfix) with ESMTPS id CF8A3C21DA6 + for <u-boot@lists.denx.de>; Thu, 24 Oct 2019 23:28:18 +0000 (UTC) +Received: from ip5f5a6266.dynamic.kabel-deutschland.de ([95.90.98.102] + helo=phil.fritz.box) by gloria.sntech.de with esmtpsa + (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) + (Exim 4.89) (envelope-from <heiko@sntech.de>) + id 1iNmWg-0002cR-Ha; Fri, 25 Oct 2019 01:28:18 +0200 +From: Heiko Stuebner <heiko@sntech.de> +To: u-boot@lists.denx.de +Date: Fri, 25 Oct 2019 01:28:00 +0200 +Message-Id: <20191024232803.10338-10-heiko@sntech.de> +X-Mailer: git-send-email 2.23.0 +In-Reply-To: <20191024232803.10338-1-heiko@sntech.de> +References: <20191024232803.10338-1-heiko@sntech.de> +MIME-Version: 1.0 +Cc: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>, + joe.hershberger@ni.com, christoph.muellner@theobroma-systems.com +Subject: [U-Boot] [PATCH 09/12] rockchip: ram: add dm-based sdram driver +X-BeenThere: u-boot@lists.denx.de +X-Mailman-Version: 2.1.18 +Precedence: list +List-Id: U-Boot discussion <u-boot.lists.denx.de> +List-Unsubscribe: <https://lists.denx.de/options/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=unsubscribe> +List-Archive: <http://lists.denx.de/pipermail/u-boot/> +List-Post: <mailto:u-boot@lists.denx.de> +List-Help: <mailto:u-boot-request@lists.denx.de?subject=help> +List-Subscribe: <https://lists.denx.de/listinfo/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=subscribe> +Errors-To: u-boot-bounces@lists.denx.de +Sender: "U-Boot" <u-boot-bounces@lists.denx.de> + +From: Heiko Stuebner <heiko.stuebner@theobroma-systems.com> + +sdram configuration happens outside of dm-infrastructure in special +tpl-code, so the sdram driver itself has just the function to read +back the sdram configuration and allow main uboot to handle dram sizes. + +Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com> +--- + drivers/ram/rockchip/Makefile | 1 + + drivers/ram/rockchip/sdram_px30.c | 57 +++++++++++++++++++++++++++++++ + 2 files changed, 58 insertions(+) + create mode 100644 drivers/ram/rockchip/sdram_px30.c + +diff --git a/drivers/ram/rockchip/Makefile b/drivers/ram/rockchip/Makefile +index feb1f82d00..a51df57411 100644 +--- a/drivers/ram/rockchip/Makefile ++++ b/drivers/ram/rockchip/Makefile +@@ -5,6 +5,7 @@ + + obj-$(CONFIG_RAM_ROCKCHIP_DEBUG) += sdram_debug.o + obj-$(CONFIG_ROCKCHIP_RK3368) = dmc-rk3368.o ++obj-$(CONFIG_ROCKCHIP_PX30) = sdram_px30.o + obj-$(CONFIG_ROCKCHIP_RK3128) = sdram_rk3128.o + obj-$(CONFIG_ROCKCHIP_RK3188) = sdram_rk3188.o + obj-$(CONFIG_ROCKCHIP_RK322X) = sdram_rk322x.o +diff --git a/drivers/ram/rockchip/sdram_px30.c b/drivers/ram/rockchip/sdram_px30.c +new file mode 100644 +index 0000000000..bdb97f2b5c +--- /dev/null ++++ b/drivers/ram/rockchip/sdram_px30.c +@@ -0,0 +1,57 @@ ++// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++/* ++ * (C) Copyright 2017 Rockchip Electronics Co., Ltd. ++ */ ++ ++#include <common.h> ++#include <dm.h> ++#include <ram.h> ++#include <syscon.h> ++#include <asm/arch-rockchip/clock.h> ++#include <asm/arch-rockchip/grf_px30.h> ++#include <asm/arch-rockchip/sdram_common.h> ++ ++struct dram_info { ++ struct ram_info info; ++ struct px30_pmugrf *pmugrf; ++}; ++ ++static int px30_dmc_probe(struct udevice *dev) ++{ ++ struct dram_info *priv = dev_get_priv(dev); ++ ++ priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF); ++ debug("%s: grf=%p\n", __func__, priv->pmugrf); ++ priv->info.base = CONFIG_SYS_SDRAM_BASE; ++ priv->info.size = ++ rockchip_sdram_size((phys_addr_t)&priv->pmugrf->os_reg[2]); ++ ++ return 0; ++} ++ ++static int px30_dmc_get_info(struct udevice *dev, struct ram_info *info) ++{ ++ struct dram_info *priv = dev_get_priv(dev); ++ ++ *info = priv->info; ++ ++ return 0; ++} ++ ++static struct ram_ops px30_dmc_ops = { ++ .get_info = px30_dmc_get_info, ++}; ++ ++static const struct udevice_id px30_dmc_ids[] = { ++ { .compatible = "rockchip,px30-dmc" }, ++ { } ++}; ++ ++U_BOOT_DRIVER(dmc_px30) = { ++ .name = "rockchip_px30_dmc", ++ .id = UCLASS_RAM, ++ .of_match = px30_dmc_ids, ++ .ops = &px30_dmc_ops, ++ .probe = px30_dmc_probe, ++ .priv_auto_alloc_size = sizeof(struct dram_info), ++}; + +From patchwork Thu Oct 24 23:28:01 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: =?utf-8?q?Heiko_St=C3=BCbner?= <heiko@sntech.de> +X-Patchwork-Id: 1183665 +X-Patchwork-Delegate: ykai007@gmail.com +Return-Path: <u-boot-bounces@lists.denx.de> +X-Original-To: incoming@patchwork.ozlabs.org +Delivered-To: patchwork-incoming@bilbo.ozlabs.org +Authentication-Results: ozlabs.org; + spf=none (no SPF record) smtp.mailfrom=lists.denx.de + (client-ip=81.169.180.215; helo=lists.denx.de; + envelope-from=u-boot-bounces@lists.denx.de; + receiver=<UNKNOWN>) +Authentication-Results: ozlabs.org; + dmarc=none (p=none dis=none) header.from=sntech.de +Received: from lists.denx.de (dione.denx.de [81.169.180.215]) + by ozlabs.org (Postfix) with ESMTP id 46zkWL1XGLz9sQm + for <incoming@patchwork.ozlabs.org>; + Fri, 25 Oct 2019 10:50:06 +1100 (AEDT) +Received: by lists.denx.de (Postfix, from userid 105) + id CF9C2C21DA1; Thu, 24 Oct 2019 23:49:56 +0000 (UTC) +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de +X-Spam-Level: +X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable + autolearn_force=no version=3.4.0 +Received: from lists.denx.de (localhost [IPv6:::1]) + by lists.denx.de (Postfix) with ESMTP id 25EB1C21E12; + Thu, 24 Oct 2019 23:48:26 +0000 (UTC) +Received: by lists.denx.de (Postfix, from userid 105) + id 9613FC21E12; Thu, 24 Oct 2019 23:48:24 +0000 (UTC) +Received: from gloria.sntech.de (gloria.sntech.de [185.11.138.130]) + by lists.denx.de (Postfix) with ESMTPS id B4FA4C21E13 + for <u-boot@lists.denx.de>; Thu, 24 Oct 2019 23:47:59 +0000 (UTC) +Received: from ip5f5a6266.dynamic.kabel-deutschland.de ([95.90.98.102] + helo=phil.fritz.box) by gloria.sntech.de with esmtpsa + (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) + (Exim 4.89) (envelope-from <heiko@sntech.de>) + id 1iNmWg-0002cR-Ty; Fri, 25 Oct 2019 01:28:19 +0200 +From: Heiko Stuebner <heiko@sntech.de> +To: u-boot@lists.denx.de +Date: Fri, 25 Oct 2019 01:28:01 +0200 +Message-Id: <20191024232803.10338-11-heiko@sntech.de> +X-Mailer: git-send-email 2.23.0 +In-Reply-To: <20191024232803.10338-1-heiko@sntech.de> +References: <20191024232803.10338-1-heiko@sntech.de> +MIME-Version: 1.0 +Cc: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>, + joe.hershberger@ni.com, christoph.muellner@theobroma-systems.com +Subject: [U-Boot] [PATCH 10/12] rockchip: add px30 devicetrees +X-BeenThere: u-boot@lists.denx.de +X-Mailman-Version: 2.1.18 +Precedence: list +List-Id: U-Boot discussion <u-boot.lists.denx.de> +List-Unsubscribe: <https://lists.denx.de/options/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=unsubscribe> +List-Archive: <http://lists.denx.de/pipermail/u-boot/> +List-Post: <mailto:u-boot@lists.denx.de> +List-Help: <mailto:u-boot-request@lists.denx.de?subject=help> +List-Subscribe: <https://lists.denx.de/listinfo/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=subscribe> +Errors-To: u-boot-bounces@lists.denx.de +Sender: "U-Boot" <u-boot-bounces@lists.denx.de> + +From: Heiko Stuebner <heiko.stuebner@theobroma-systems.com> + +Add px30 related devicetrees synced from the Linux kernel. + +Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com> +--- + arch/arm/dts/Makefile | 3 + + arch/arm/dts/px30-evb-u-boot.dtsi | 81 ++ + arch/arm/dts/px30-evb.dts | 527 ++++++++ + arch/arm/dts/px30.dtsi | 2068 +++++++++++++++++++++++++++++ + 4 files changed, 2679 insertions(+) + create mode 100644 arch/arm/dts/px30-evb-u-boot.dtsi + create mode 100644 arch/arm/dts/px30-evb.dts + create mode 100644 arch/arm/dts/px30.dtsi + +diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile +index dbb062edda..04ddbfb11f 100644 +--- a/arch/arm/dts/Makefile ++++ b/arch/arm/dts/Makefile +@@ -67,6 +67,9 @@ dtb-$(CONFIG_KIRKWOOD) += \ + dtb-$(CONFIG_ARCH_OWL) += \ + bubblegum_96.dtb + ++dtb-$(CONFIG_ROCKCHIP_PX30) += \ ++ px30-evb.dtb ++ + dtb-$(CONFIG_ROCKCHIP_RK3036) += \ + rk3036-sdk.dtb + +diff --git a/arch/arm/dts/px30-evb-u-boot.dtsi b/arch/arm/dts/px30-evb-u-boot.dtsi +new file mode 100644 +index 0000000000..3de9c7068e +--- /dev/null ++++ b/arch/arm/dts/px30-evb-u-boot.dtsi +@@ -0,0 +1,81 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * (C) Copyright 2017 Rockchip Electronics Co., Ltd ++ */ ++ ++/ { ++ aliases { ++ mmc0 = &emmc; ++ mmc1 = &sdmmc; ++ }; ++ ++ chosen { ++ u-boot,spl-boot-order = &emmc, &sdmmc; ++ }; ++}; ++ ++&dmc { ++ u-boot,dm-pre-reloc; ++}; ++ ++&uart2 { ++ clock-frequency = <24000000>; ++ u-boot,dm-pre-reloc; ++}; ++ ++&uart5 { ++ clock-frequency = <24000000>; ++ u-boot,dm-pre-reloc; ++}; ++ ++&sdmmc { ++ u-boot,dm-pre-reloc; ++ ++ /* temporary till I find out why dma mode doesn't work */ ++ fifo-mode; ++}; ++ ++&emmc { ++ u-boot,dm-pre-reloc; ++}; ++ ++&grf { ++ u-boot,dm-pre-reloc; ++}; ++ ++&pmugrf { ++ u-boot,dm-pre-reloc; ++}; ++ ++&xin24m { ++ u-boot,dm-pre-reloc; ++}; ++ ++&cru { ++ u-boot,dm-pre-reloc; ++}; ++ ++&pmucru { ++ u-boot,dm-pre-reloc; ++}; ++ ++&saradc { ++ u-boot,dm-pre-reloc; ++ status = "okay"; ++}; ++ ++&gpio0 { ++ u-boot,dm-pre-reloc; ++}; ++ ++&gpio1 { ++ u-boot,dm-pre-reloc; ++}; ++ ++&gpio2 { ++ u-boot,dm-pre-reloc; ++}; ++ ++&gpio3 { ++ u-boot,dm-pre-reloc; ++}; +diff --git a/arch/arm/dts/px30-evb.dts b/arch/arm/dts/px30-evb.dts +new file mode 100644 +index 0000000000..089a7ade4e +--- /dev/null ++++ b/arch/arm/dts/px30-evb.dts +@@ -0,0 +1,527 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd ++ */ ++ ++/dts-v1/; ++#include <dt-bindings/gpio/gpio.h> ++#include <dt-bindings/input/input.h> ++#include <dt-bindings/pinctrl/rockchip.h> ++#include "px30.dtsi" ++#include "px30-evb-u-boot.dtsi" ++ ++/ { ++ model = "Rockchip PX30 EVB"; ++ compatible = "rockchip,px30-evb", "rockchip,px30"; ++ ++ chosen { ++ stdout-path = "serial5:115200n8"; ++ }; ++ ++ adc-keys { ++ compatible = "adc-keys"; ++ io-channels = <&saradc 2>; ++ io-channel-names = "buttons"; ++ keyup-threshold-microvolt = <1800000>; ++ poll-interval = <100>; ++ ++ esc-key { ++ label = "esc"; ++ linux,code = <KEY_ESC>; ++ press-threshold-microvolt = <1310000>; ++ }; ++ ++ home-key { ++ label = "home"; ++ linux,code = <KEY_HOME>; ++ press-threshold-microvolt = <624000>; ++ }; ++ ++ menu-key { ++ label = "menu"; ++ linux,code = <KEY_MENU>; ++ press-threshold-microvolt = <987000>; ++ }; ++ ++ vol-down-key { ++ label = "volume down"; ++ linux,code = <KEY_VOLUMEDOWN>; ++ press-threshold-microvolt = <300000>; ++ }; ++ ++ vol-up-key { ++ label = "volume up"; ++ linux,code = <KEY_VOLUMEUP>; ++ press-threshold-microvolt = <17000>; ++ }; ++ }; ++ ++ backlight: backlight { ++ compatible = "pwm-backlight"; ++ pwms = <&pwm1 0 25000 0>; ++ power-supply = <&vcc3v3_lcd>; ++ }; ++ ++ emmc_pwrseq: emmc-pwrseq { ++ compatible = "mmc-pwrseq-emmc"; ++ pinctrl-0 = <&emmc_reset>; ++ pinctrl-names = "default"; ++ reset-gpios = <&gpio1 RK_PB3 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable_h>; ++ ++ /* ++ * On the module itself this is one of these (depending ++ * on the actual card populated): ++ * - SDIO_RESET_L_WL_REG_ON ++ * - PDN (power down when low) ++ */ ++ reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; /* GPIO3_A4 */ ++ }; ++ ++ vcc5v0_sys: vccsys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc5v0_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu2 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu3 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&display_subsystem { ++ status = "okay"; ++}; ++ ++&dsi { ++ status = "okay"; ++ ++ ports { ++ mipi_out: port@1 { ++ reg = <1>; ++ ++ mipi_out_panel: endpoint { ++ remote-endpoint = <&mipi_in_panel>; ++ }; ++ }; ++ }; ++ ++ panel@0 { ++ compatible = "sitronix,st7703"; ++ reg = <0>; ++ backlight = <&backlight>; ++ iovcc-supply = <&vcc_1v8>; ++ vci-supply = <&vcc3v3_lcd>; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ ++ mipi_in_panel: endpoint { ++ remote-endpoint = <&mipi_out_panel>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&dsi_dphy { ++ status = "okay"; ++}; ++ ++&emmc { ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ mmc-hs200-1_8v; ++ non-removable; ++ mmc-pwrseq = <&emmc_pwrseq>; ++ vmmc-supply = <&vcc_3v0>; ++ vqmmc-supply = <&vccio_flash>; ++ status = "okay"; ++}; ++ ++&gmac { ++ clock_in_out = "output"; ++ phy-supply = <&vcc_rmii>; ++ snps,reset-gpio = <&gpio2 13 GPIO_ACTIVE_LOW>; ++ snps,reset-active-low; ++ snps,reset-delays-us = <0 50000 50000>; ++ status = "okay"; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ ++ rk809: pmic@20 { ++ compatible = "rockchip,rk809"; ++ reg = <0x20>; ++ interrupt-parent = <&gpio0>; ++ interrupts = <7 IRQ_TYPE_LEVEL_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ #clock-cells = <0>; ++ clock-output-names = "xin32k"; ++ ++ vcc1-supply = <&vcc5v0_sys>; ++ vcc2-supply = <&vcc5v0_sys>; ++ vcc3-supply = <&vcc5v0_sys>; ++ vcc4-supply = <&vcc5v0_sys>; ++ vcc5-supply = <&vcc3v3_sys>; ++ vcc6-supply = <&vcc3v3_sys>; ++ vcc7-supply = <&vcc3v3_sys>; ++ vcc8-supply = <&vcc3v3_sys>; ++ vcc9-supply = <&vcc5v0_sys>; ++ ++ regulators { ++ vdd_log: DCDC_REG1 { ++ regulator-name = "vdd_log"; ++ regulator-min-microvolt = <950000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <950000>; ++ }; ++ }; ++ ++ vdd_arm: DCDC_REG2 { ++ regulator-name = "vdd_arm"; ++ regulator-min-microvolt = <950000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-ramp-delay = <6001>; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ regulator-suspend-microvolt = <950000>; ++ }; ++ }; ++ ++ vcc_ddr: DCDC_REG3 { ++ regulator-name = "vcc_ddr"; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_3v0: vcc_rmii: DCDC_REG4 { ++ regulator-name = "vcc_3v0"; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3000000>; ++ }; ++ }; ++ ++ vcc3v3_sys: DCDC_REG5 { ++ regulator-name = "vcc3v3_sys"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcc_1v0: LDO_REG1 { ++ regulator-name = "vcc_1v0"; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1000000>; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vcc_1v8: vccio_flash: vccio_sdio: LDO_REG2 { ++ regulator-name = "vcc_1v8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdd_1v0: LDO_REG3 { ++ regulator-name = "vdd_1v0"; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1000000>; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vcc3v0_pmu: LDO_REG4 { ++ regulator-name = "vcc3v0_pmu"; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3000000>; ++ }; ++ }; ++ ++ vccio_sd: LDO_REG5 { ++ regulator-name = "vccio_sd"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcc_sd: LDO_REG6 { ++ regulator-name = "vcc_sd"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcc2v8_dvp: LDO_REG7 { ++ regulator-name = "vcc2v8_dvp"; ++ regulator-min-microvolt = <2800000>; ++ regulator-max-microvolt = <2800000>; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ regulator-suspend-microvolt = <2800000>; ++ }; ++ }; ++ ++ vcc1v8_dvp: LDO_REG8 { ++ regulator-name = "vcc1v8_dvp"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc1v5_dvp: LDO_REG9 { ++ regulator-name = "vcc1v5_dvp"; ++ regulator-min-microvolt = <1500000>; ++ regulator-max-microvolt = <1500000>; ++ regulator-boot-on; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ regulator-suspend-microvolt = <1500000>; ++ }; ++ }; ++ ++ vcc3v3_lcd: SWITCH_REG1 { ++ regulator-name = "vcc3v3_lcd"; ++ regulator-boot-on; ++ }; ++ ++ vcc5v0_host: SWITCH_REG2 { ++ regulator-name = "vcc5v0_host"; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ }; ++ }; ++}; ++ ++&i2s1_2ch { ++ status = "okay"; ++}; ++ ++&io_domains { ++ status = "okay"; ++ ++ vccio1-supply = <&vccio_sdio>; ++ vccio2-supply = <&vccio_sd>; ++ vccio3-supply = <&vcc_3v0>; ++ vccio4-supply = <&vcc3v0_pmu>; ++ vccio5-supply = <&vcc_3v0>; ++ vccio6-supply = <&vccio_flash>; ++}; ++ ++&pinctrl { ++ headphone { ++ hp_det: hp-det { ++ rockchip,pins = ++ <2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++ ++ emmc { ++ emmc_reset: emmc-reset { ++ rockchip,pins = <1 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ pmic { ++ pmic_int: pmic_int { ++ rockchip,pins = ++ <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ soc_slppin_gpio: soc_slppin_gpio { ++ rockchip,pins = ++ <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>; ++ }; ++ ++ soc_slppin_slp: soc_slppin_slp { ++ rockchip,pins = ++ <0 RK_PA4 1 &pcfg_pull_none>; ++ }; ++ ++ soc_slppin_rst: soc_slppin_rst { ++ rockchip,pins = ++ <0 RK_PA4 2 &pcfg_pull_none>; ++ }; ++ }; ++ ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = ++ <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&pmu_io_domains { ++ status = "okay"; ++ ++ pmuio1-supply = <&vcc3v0_pmu>; ++ pmuio2-supply = <&vcc3v0_pmu>; ++}; ++ ++&pwm1 { ++ status = "okay"; ++}; ++ ++&saradc { ++ vref-supply = <&vcc_1v8>; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ card-detect-delay = <800>; ++ sd-uhs-sdr12; ++ sd-uhs-sdr25; ++ sd-uhs-sdr50; ++ sd-uhs-sdr104; ++ vmmc-supply = <&vcc_sd>; ++ vqmmc-supply = <&vccio_sd>; ++ status = "okay"; ++}; ++ ++&sdio { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ keep-power-in-suspend; ++ non-removable; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ sd-uhs-sdr104; ++ status = "okay"; ++}; ++ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_xfer &uart1_cts>; ++ status = "okay"; ++}; ++ ++&uart5 { ++ status = "okay"; ++}; ++ ++&usb20_otg { ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&vopb { ++ status = "okay"; ++}; ++ ++&vopb_mmu { ++ status = "okay"; ++}; ++ ++&vopl { ++ status = "okay"; ++}; ++ ++&vopl_mmu { ++ status = "okay"; ++}; +diff --git a/arch/arm/dts/px30.dtsi b/arch/arm/dts/px30.dtsi +new file mode 100644 +index 0000000000..0d2325a77f +--- /dev/null ++++ b/arch/arm/dts/px30.dtsi +@@ -0,0 +1,2068 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd ++ */ ++ ++#include <dt-bindings/clock/px30-cru.h> ++#include <dt-bindings/gpio/gpio.h> ++#include <dt-bindings/interrupt-controller/arm-gic.h> ++#include <dt-bindings/interrupt-controller/irq.h> ++#include <dt-bindings/pinctrl/rockchip.h> ++#include <dt-bindings/power/px30-power.h> ++#include <dt-bindings/soc/rockchip,boot-mode.h> ++ ++/ { ++ compatible = "rockchip,px30"; ++ ++ interrupt-parent = <&gic>; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ++ aliases { ++ ethernet0 = &gmac; ++ i2c0 = &i2c0; ++ i2c1 = &i2c1; ++ i2c2 = &i2c2; ++ i2c3 = &i2c3; ++ serial0 = &uart0; ++ serial1 = &uart1; ++ serial2 = &uart2; ++ serial3 = &uart3; ++ serial4 = &uart4; ++ serial5 = &uart5; ++ spi0 = &spi0; ++ spi1 = &spi1; ++ }; ++ ++ cpus { ++ #address-cells = <2>; ++ #size-cells = <0>; ++ ++ cpu0: cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a35"; ++ reg = <0x0 0x0>; ++ enable-method = "psci"; ++ clocks = <&cru ARMCLK>; ++ #cooling-cells = <2>; ++ cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; ++ dynamic-power-coefficient = <90>; ++ operating-points-v2 = <&cpu0_opp_table>; ++ }; ++ ++ cpu1: cpu@1 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a35"; ++ reg = <0x0 0x1>; ++ enable-method = "psci"; ++ clocks = <&cru ARMCLK>; ++ #cooling-cells = <2>; ++ cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; ++ dynamic-power-coefficient = <90>; ++ operating-points-v2 = <&cpu0_opp_table>; ++ }; ++ ++ cpu2: cpu@2 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a35"; ++ reg = <0x0 0x2>; ++ enable-method = "psci"; ++ clocks = <&cru ARMCLK>; ++ #cooling-cells = <2>; ++ cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; ++ dynamic-power-coefficient = <90>; ++ operating-points-v2 = <&cpu0_opp_table>; ++ }; ++ ++ cpu3: cpu@3 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a35"; ++ reg = <0x0 0x3>; ++ enable-method = "psci"; ++ clocks = <&cru ARMCLK>; ++ #cooling-cells = <2>; ++ cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; ++ dynamic-power-coefficient = <90>; ++ operating-points-v2 = <&cpu0_opp_table>; ++ }; ++ ++ idle-states { ++ entry-method = "psci"; ++ ++ CPU_SLEEP: cpu-sleep { ++ compatible = "arm,idle-state"; ++ local-timer-stop; ++ arm,psci-suspend-param = <0x0010000>; ++ entry-latency-us = <120>; ++ exit-latency-us = <250>; ++ min-residency-us = <900>; ++ }; ++ ++ CLUSTER_SLEEP: cluster-sleep { ++ compatible = "arm,idle-state"; ++ local-timer-stop; ++ arm,psci-suspend-param = <0x1010000>; ++ entry-latency-us = <400>; ++ exit-latency-us = <500>; ++ min-residency-us = <2000>; ++ }; ++ }; ++ }; ++ ++ cpu0_opp_table: cpu0-opp-table { ++ compatible = "operating-points-v2"; ++ opp-shared; ++ ++ opp-408000000 { ++ opp-hz = /bits/ 64 <408000000>; ++ opp-microvolt = <950000 950000 1350000>; ++ clock-latency-ns = <40000>; ++ opp-suspend; ++ }; ++ opp-600000000 { ++ opp-hz = /bits/ 64 <600000000>; ++ opp-microvolt = <950000 950000 1350000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-816000000 { ++ opp-hz = /bits/ 64 <816000000>; ++ opp-microvolt = <1050000 1050000 1350000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1008000000 { ++ opp-hz = /bits/ 64 <1008000000>; ++ opp-microvolt = <1175000 1175000 1350000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1200000000 { ++ opp-hz = /bits/ 64 <1200000000>; ++ opp-microvolt = <1300000 1300000 1350000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1296000000 { ++ opp-hz = /bits/ 64 <1296000000>; ++ opp-microvolt = <1350000 1350000 1350000>; ++ clock-latency-ns = <40000>; ++ }; ++ }; ++ ++ arm-pmu { ++ compatible = "arm,cortex-a53-pmu"; ++ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; ++ }; ++ ++ dmc: dmc { ++ compatible = "rockchip,px30-dmc", "syscon"; ++ reg = <0x0 0xff2a0000 0x0 0x1000>; ++ }; ++ ++ display_subsystem: display-subsystem { ++ compatible = "rockchip,display-subsystem"; ++ ports = <&vopb_out>, <&vopl_out>; ++ status = "disabled"; ++ }; ++ ++ gmac_clkin: external-gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <50000000>; ++ clock-output-names = "gmac_clkin"; ++ #clock-cells = <0>; ++ }; ++ ++ psci { ++ compatible = "arm,psci-1.0"; ++ method = "smc"; ++ }; ++ ++ timer { ++ compatible = "arm,armv8-timer"; ++ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, ++ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, ++ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, ++ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; ++ }; ++ ++ xin24m: xin24m { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <24000000>; ++ clock-output-names = "xin24m"; ++ }; ++ ++ pmu: power-management@ff000000 { ++ compatible = "rockchip,px30-pmu", "syscon", "simple-mfd"; ++ reg = <0x0 0xff000000 0x0 0x1000>; ++ ++ power: power-controller { ++ compatible = "rockchip,px30-power-controller"; ++ #power-domain-cells = <1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ /* These power domains are grouped by VD_LOGIC */ ++ pd_usb@PX30_PD_USB { ++ reg = <PX30_PD_USB>; ++ clocks = <&cru HCLK_HOST>, ++ <&cru HCLK_OTG>, ++ <&cru SCLK_OTG_ADP>; ++ pm_qos = <&qos_usb_host>, <&qos_usb_otg>; ++ }; ++ pd_sdcard@PX30_PD_SDCARD { ++ reg = <PX30_PD_SDCARD>; ++ clocks = <&cru HCLK_SDMMC>, ++ <&cru SCLK_SDMMC>; ++ pm_qos = <&qos_sdmmc>; ++ }; ++ pd_gmac@PX30_PD_GMAC { ++ reg = <PX30_PD_GMAC>; ++ clocks = <&cru ACLK_GMAC>, ++ <&cru PCLK_GMAC>, ++ <&cru SCLK_MAC_REF>, ++ <&cru SCLK_GMAC_RX_TX>; ++ pm_qos = <&qos_gmac>; ++ }; ++ pd_mmc_nand@PX30_PD_MMC_NAND { ++ reg = <PX30_PD_MMC_NAND>; ++ clocks = <&cru HCLK_NANDC>, ++ <&cru HCLK_EMMC>, ++ <&cru HCLK_SDIO>, ++ <&cru HCLK_SFC>, ++ <&cru SCLK_EMMC>, ++ <&cru SCLK_NANDC>, ++ <&cru SCLK_SDIO>, ++ <&cru SCLK_SFC>; ++ pm_qos = <&qos_emmc>, <&qos_nand>, ++ <&qos_sdio>, <&qos_sfc>; ++ }; ++ pd_vpu@PX30_PD_VPU { ++ reg = <PX30_PD_VPU>; ++ clocks = <&cru ACLK_VPU>, ++ <&cru HCLK_VPU>, ++ <&cru SCLK_CORE_VPU>; ++ pm_qos = <&qos_vpu>, <&qos_vpu_r128>; ++ }; ++ pd_vo@PX30_PD_VO { ++ reg = <PX30_PD_VO>; ++ clocks = <&cru ACLK_RGA>, ++ <&cru ACLK_VOPB>, ++ <&cru ACLK_VOPL>, ++ <&cru DCLK_VOPB>, ++ <&cru DCLK_VOPL>, ++ <&cru HCLK_RGA>, ++ <&cru HCLK_VOPB>, ++ <&cru HCLK_VOPL>, ++ <&cru PCLK_MIPI_DSI>, ++ <&cru SCLK_RGA_CORE>, ++ <&cru SCLK_VOPB_PWM>; ++ pm_qos = <&qos_rga_rd>, <&qos_rga_wr>, ++ <&qos_vop_m0>, <&qos_vop_m1>; ++ }; ++ pd_vi@PX30_PD_VI { ++ reg = <PX30_PD_VI>; ++ clocks = <&cru ACLK_CIF>, ++ <&cru ACLK_ISP>, ++ <&cru HCLK_CIF>, ++ <&cru HCLK_ISP>, ++ <&cru SCLK_ISP>; ++ pm_qos = <&qos_isp_128>, <&qos_isp_rd>, ++ <&qos_isp_wr>, <&qos_isp_m1>, ++ <&qos_vip>; ++ }; ++ pd_gpu@PX30_PD_GPU { ++ reg = <PX30_PD_GPU>; ++ clocks = <&cru SCLK_GPU>; ++ pm_qos = <&qos_gpu>; ++ }; ++ }; ++ }; ++ ++ pmugrf: syscon@ff010000 { ++ compatible = "rockchip,px30-pmugrf", "syscon", "simple-mfd"; ++ reg = <0x0 0xff010000 0x0 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ pmu_io_domains: io-domains { ++ compatible = "rockchip,px30-pmu-io-voltage-domain"; ++ status = "disabled"; ++ }; ++ ++ reboot-mode { ++ compatible = "syscon-reboot-mode"; ++ offset = <0x200>; ++ mode-bootloader = <BOOT_BL_DOWNLOAD>; ++ mode-fastboot = <BOOT_FASTBOOT>; ++ mode-loader = <BOOT_BL_DOWNLOAD>; ++ mode-normal = <BOOT_NORMAL>; ++ mode-recovery = <BOOT_RECOVERY>; ++ }; ++ }; ++ ++ uart0: serial@ff030000 { ++ compatible = "rockchip,px30-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xff030000 0x0 0x100>; ++ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&pmucru SCLK_UART0_PMU>, <&pmucru PCLK_UART0_PMU>; ++ clock-names = "baudclk", "apb_pclk"; ++ dmas = <&dmac 0>, <&dmac 1>; ++ dma-names = "tx", "rx"; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; ++ status = "disabled"; ++ }; ++ ++ i2s1_2ch: i2s@ff070000 { ++ compatible = "rockchip,px30-i2s", "rockchip,rk3066-i2s"; ++ reg = <0x0 0xff070000 0x0 0x1000>; ++ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_I2S1>, <&cru HCLK_I2S1>; ++ clock-names = "i2s_clk", "i2s_hclk"; ++ dmas = <&dmac 18>, <&dmac 19>; ++ dma-names = "tx", "rx"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s1_2ch_sclk &i2s1_2ch_lrck ++ &i2s1_2ch_sdi &i2s1_2ch_sdo>; ++ #sound-dai-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ i2s2_2ch: i2s@ff080000 { ++ compatible = "rockchip,px30-i2s", "rockchip,rk3066-i2s"; ++ reg = <0x0 0xff080000 0x0 0x1000>; ++ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_I2S2>, <&cru HCLK_I2S2>; ++ clock-names = "i2s_clk", "i2s_hclk"; ++ dmas = <&dmac 20>, <&dmac 21>; ++ dma-names = "tx", "rx"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s2_2ch_sclk &i2s2_2ch_lrck ++ &i2s2_2ch_sdi &i2s2_2ch_sdo>; ++ #sound-dai-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ gic: interrupt-controller@ff131000 { ++ compatible = "arm,gic-400"; ++ #interrupt-cells = <3>; ++ #address-cells = <0>; ++ interrupt-controller; ++ reg = <0x0 0xff131000 0 0x1000>, ++ <0x0 0xff132000 0 0x2000>, ++ <0x0 0xff134000 0 0x2000>, ++ <0x0 0xff136000 0 0x2000>; ++ interrupts = <GIC_PPI 9 ++ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; ++ }; ++ ++ grf: syscon@ff140000 { ++ compatible = "rockchip,px30-grf", "syscon", "simple-mfd"; ++ reg = <0x0 0xff140000 0x0 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ io_domains: io-domains { ++ compatible = "rockchip,px30-io-voltage-domain"; ++ status = "disabled"; ++ }; ++ }; ++ ++ uart1: serial@ff158000 { ++ compatible = "rockchip,px30-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xff158000 0x0 0x100>; ++ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>; ++ clock-names = "baudclk", "apb_pclk"; ++ dmas = <&dmac 2>, <&dmac 3>; ++ dma-names = "tx", "rx"; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_xfer &uart1_cts &uart1_rts>; ++ status = "disabled"; ++ }; ++ ++ uart2: serial@ff160000 { ++ compatible = "rockchip,px30-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xff160000 0x0 0x100>; ++ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>; ++ clock-names = "baudclk", "apb_pclk"; ++ dmas = <&dmac 4>, <&dmac 5>; ++ dma-names = "tx", "rx"; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2m0_xfer>; ++ status = "disabled"; ++ }; ++ ++ uart3: serial@ff168000 { ++ compatible = "rockchip,px30-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xff168000 0x0 0x100>; ++ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>; ++ clock-names = "baudclk", "apb_pclk"; ++ dmas = <&dmac 6>, <&dmac 7>; ++ dma-names = "tx", "rx"; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart3m1_xfer &uart3m1_cts &uart3m1_rts>; ++ status = "disabled"; ++ }; ++ ++ uart4: serial@ff170000 { ++ compatible = "rockchip,px30-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xff170000 0x0 0x100>; ++ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>; ++ clock-names = "baudclk", "apb_pclk"; ++ dmas = <&dmac 8>, <&dmac 9>; ++ dma-names = "tx", "rx"; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart4_xfer &uart4_cts &uart4_rts>; ++ status = "disabled"; ++ }; ++ ++ uart5: serial@ff178000 { ++ compatible = "rockchip,px30-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xff178000 0x0 0x100>; ++ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_UART5>, <&cru PCLK_UART5>; ++ clock-names = "baudclk", "apb_pclk"; ++ dmas = <&dmac 10>, <&dmac 11>; ++ dma-names = "tx", "rx"; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart5_xfer &uart5_cts &uart5_rts>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@ff180000 { ++ compatible = "rockchip,px30-i2c", "rockchip,rk3399-i2c"; ++ reg = <0x0 0xff180000 0x0 0x1000>; ++ clocks = <&cru SCLK_I2C0>, <&cru PCLK_I2C0>; ++ clock-names = "i2c", "pclk"; ++ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_xfer>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ i2c1: i2c@ff190000 { ++ compatible = "rockchip,px30-i2c", "rockchip,rk3399-i2c"; ++ reg = <0x0 0xff190000 0x0 0x1000>; ++ clocks = <&cru SCLK_I2C1>, <&cru PCLK_I2C1>; ++ clock-names = "i2c", "pclk"; ++ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_xfer>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ i2c2: i2c@ff1a0000 { ++ compatible = "rockchip,px30-i2c", "rockchip,rk3399-i2c"; ++ reg = <0x0 0xff1a0000 0x0 0x1000>; ++ clocks = <&cru SCLK_I2C2>, <&cru PCLK_I2C2>; ++ clock-names = "i2c", "pclk"; ++ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c2_xfer>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ i2c3: i2c@ff1b0000 { ++ compatible = "rockchip,px30-i2c", "rockchip,rk3399-i2c"; ++ reg = <0x0 0xff1b0000 0x0 0x1000>; ++ clocks = <&cru SCLK_I2C3>, <&cru PCLK_I2C3>; ++ clock-names = "i2c", "pclk"; ++ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c3_xfer>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ spi0: spi@ff1d0000 { ++ compatible = "rockchip,px30-spi", "rockchip,rk3066-spi"; ++ reg = <0x0 0xff1d0000 0x0 0x1000>; ++ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>; ++ clock-names = "spiclk", "apb_pclk"; ++ dmas = <&dmac 12>, <&dmac 13>; ++ dma-names = "tx", "rx"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_clk &spi0_csn &spi0_miso &spi0_mosi>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ spi1: spi@ff1d8000 { ++ compatible = "rockchip,px30-spi", "rockchip,rk3066-spi"; ++ reg = <0x0 0xff1d8000 0x0 0x1000>; ++ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>; ++ clock-names = "spiclk", "apb_pclk"; ++ dmas = <&dmac 14>, <&dmac 15>; ++ dma-names = "tx", "rx"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi1_clk &spi1_csn0 &spi1_csn1 &spi1_miso &spi1_mosi>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ wdt: watchdog@ff1e0000 { ++ compatible = "snps,dw-wdt"; ++ reg = <0x0 0xff1e0000 0x0 0x100>; ++ clocks = <&cru PCLK_WDT_NS>; ++ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; ++ status = "disabled"; ++ }; ++ ++ pwm0: pwm@ff200000 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff200000 0x0 0x10>; ++ clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>; ++ clock-names = "pwm", "pclk"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm0_pin>; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ pwm1: pwm@ff200010 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff200010 0x0 0x10>; ++ clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>; ++ clock-names = "pwm", "pclk"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm1_pin>; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ pwm2: pwm@ff200020 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff200020 0x0 0x10>; ++ clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>; ++ clock-names = "pwm", "pclk"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm2_pin>; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ pwm3: pwm@ff200030 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff200030 0x0 0x10>; ++ clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>; ++ clock-names = "pwm", "pclk"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm3_pin>; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ pwm4: pwm@ff208000 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff208000 0x0 0x10>; ++ clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>; ++ clock-names = "pwm", "pclk"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm4_pin>; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ pwm5: pwm@ff208010 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff208010 0x0 0x10>; ++ clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>; ++ clock-names = "pwm", "pclk"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm5_pin>; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ pwm6: pwm@ff208020 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff208020 0x0 0x10>; ++ clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>; ++ clock-names = "pwm", "pclk"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm6_pin>; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ pwm7: pwm@ff208030 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff208030 0x0 0x10>; ++ clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>; ++ clock-names = "pwm", "pclk"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm7_pin>; ++ #pwm-cells = <3>; ++ status = "disabled"; ++ }; ++ ++ rktimer: timer@ff210000 { ++ compatible = "rockchip,px30-timer", "rockchip,rk3288-timer"; ++ reg = <0x0 0xff210000 0x0 0x1000>; ++ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru PCLK_TIMER>, <&cru SCLK_TIMER0>; ++ clock-names = "pclk", "timer"; ++ }; ++ ++ amba { ++ compatible = "simple-bus"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ ++ dmac: dmac@ff240000 { ++ compatible = "arm,pl330", "arm,primecell"; ++ reg = <0x0 0xff240000 0x0 0x4000>; ++ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru ACLK_DMAC>; ++ clock-names = "apb_pclk"; ++ #dma-cells = <1>; ++ }; ++ }; ++ ++ saradc: saradc@ff288000 { ++ compatible = "rockchip,px30-saradc", "rockchip,rk3399-saradc"; ++ reg = <0x0 0xff288000 0x0 0x100>; ++ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>; ++ #io-channel-cells = <1>; ++ clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>; ++ clock-names = "saradc", "apb_pclk"; ++ resets = <&cru SRST_SARADC_P>; ++ reset-names = "saradc-apb"; ++ status = "disabled"; ++ }; ++ ++ otp: nvmem@ff290000 { ++ compatible = "rockchip,px30-otp"; ++ reg = <0x0 0xff290000 0x0 0x4000>; ++ clocks = <&cru SCLK_OTP_USR>, <&cru PCLK_OTP_NS>, ++ <&cru PCLK_OTP_PHY>; ++ clock-names = "otp", "apb_pclk", "phy"; ++ resets = <&cru SRST_OTP_PHY>; ++ reset-names = "phy"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ /* Data cells */ ++ cpu_id: id@7 { ++ reg = <0x07 0x10>; ++ }; ++ cpu_leakage: cpu-leakage@17 { ++ reg = <0x17 0x1>; ++ }; ++ performance: performance@1e { ++ reg = <0x1e 0x1>; ++ bits = <4 3>; ++ }; ++ }; ++ ++ cru: clock-controller@ff2b0000 { ++ compatible = "rockchip,px30-cru"; ++ reg = <0x0 0xff2b0000 0x0 0x1000>; ++ clocks = <&xin24m>, <&pmucru PLL_GPLL>; ++ clock-names = "xin24m", "gpll"; ++ rockchip,grf = <&grf>; ++ #clock-cells = <1>; ++ #reset-cells = <1>; ++ }; ++ ++ pmucru: clock-controller@ff2bc000 { ++ compatible = "rockchip,px30-pmucru"; ++ reg = <0x0 0xff2bc000 0x0 0x1000>; ++ clocks = <&xin24m>; ++ clock-names = "xin24m"; ++ rockchip,grf = <&grf>; ++ #clock-cells = <1>; ++ #reset-cells = <1>; ++ }; ++ ++ dsi_dphy: phy@ff2e0000 { ++ compatible = "rockchip,px30-dsi-dphy"; ++ reg = <0x0 0xff2e0000 0x0 0x10000>; ++ clocks = <&pmucru SCLK_MIPIDSIPHY_REF>, <&cru PCLK_MIPIDSIPHY>; ++ clock-names = "ref", "pclk"; ++ #clock-cells = <0>; ++ resets = <&cru SRST_MIPIDSIPHY_P>; ++ reset-names = "apb"; ++ #phy-cells = <0>; ++ power-domains = <&power PX30_PD_VO>; ++ status = "disabled"; ++ }; ++ ++ usb20_otg: usb@ff300000 { ++ compatible = "rockchip,px30-usb", "rockchip,rk3066-usb", ++ "snps,dwc2"; ++ reg = <0x0 0xff300000 0x0 0x40000>; ++ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru HCLK_OTG>; ++ clock-names = "otg"; ++ dr_mode = "otg"; ++ g-np-tx-fifo-size = <16>; ++ g-rx-fifo-size = <280>; ++ g-tx-fifo-size = <256 128 128 64 32 16>; ++ g-use-dma; ++ power-domains = <&power PX30_PD_USB>; ++ status = "disabled"; ++ }; ++ ++ usb_host0_ehci: usb@ff340000 { ++ compatible = "generic-ehci"; ++ reg = <0x0 0xff340000 0x0 0x10000>; ++ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru HCLK_HOST>; ++ clock-names = "usbhost"; ++ power-domains = <&power PX30_PD_USB>; ++ status = "disabled"; ++ }; ++ ++ usb_host0_ohci: usb@ff350000 { ++ compatible = "generic-ohci"; ++ reg = <0x0 0xff350000 0x0 0x10000>; ++ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru HCLK_HOST>; ++ clock-names = "usbhost"; ++ power-domains = <&power PX30_PD_USB>; ++ status = "disabled"; ++ }; ++ ++ gmac: ethernet@ff360000 { ++ compatible = "rockchip,px30-gmac"; ++ reg = <0x0 0xff360000 0x0 0x10000>; ++ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "macirq"; ++ clocks = <&cru SCLK_GMAC>, <&cru SCLK_GMAC_RX_TX>, ++ <&cru SCLK_GMAC_RX_TX>, <&cru SCLK_MAC_REF>, ++ <&cru SCLK_MAC_REFOUT>, <&cru ACLK_GMAC>, ++ <&cru PCLK_GMAC>, <&cru SCLK_GMAC_RMII>; ++ clock-names = "stmmaceth", "mac_clk_rx", ++ "mac_clk_tx", "clk_mac_ref", ++ "clk_mac_refout", "aclk_mac", ++ "pclk_mac", "clk_mac_speed"; ++ rockchip,grf = <&grf>; ++ phy-mode = "rmii"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rmii_pins &mac_refclk_12ma>; ++ power-domains = <&power PX30_PD_GMAC>; ++ resets = <&cru SRST_GMAC_A>; ++ reset-names = "stmmaceth"; ++ status = "disabled"; ++ }; ++ ++ sdmmc: dwmmc@ff370000 { ++ compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc"; ++ reg = <0x0 0xff370000 0x0 0x4000>; ++ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, ++ <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; ++ clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; ++ fifo-depth = <0x100>; ++ max-frequency = <150000000>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>; ++ power-domains = <&power PX30_PD_SDCARD>; ++ status = "disabled"; ++ }; ++ ++ sdio: dwmmc@ff380000 { ++ compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc"; ++ reg = <0x0 0xff380000 0x0 0x4000>; ++ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>, ++ <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>; ++ clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; ++ fifo-depth = <0x100>; ++ max-frequency = <150000000>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdio_bus4 &sdio_cmd &sdio_clk>; ++ power-domains = <&power PX30_PD_MMC_NAND>; ++ status = "disabled"; ++ }; ++ ++ emmc: dwmmc@ff390000 { ++ compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc"; ++ reg = <0x0 0xff390000 0x0 0x4000>; ++ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>, ++ <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; ++ clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; ++ fifo-depth = <0x100>; ++ max-frequency = <150000000>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; ++ power-domains = <&power PX30_PD_MMC_NAND>; ++ status = "disabled"; ++ }; ++ ++ dsi: dsi@ff450000 { ++ compatible = "rockchip,px30-mipi-dsi"; ++ reg = <0x0 0xff450000 0x0 0x10000>; ++ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru PCLK_MIPI_DSI>, <&dsi_dphy>; ++ clock-names = "pclk", "pll"; ++ resets = <&cru SRST_MIPIDSI_HOST_P>; ++ reset-names = "apb"; ++ phys = <&dsi_dphy>; ++ phy-names = "dphy"; ++ power-domains = <&power PX30_PD_VO>; ++ rockchip,grf = <&grf>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ dsi_in_vopb: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&vopb_out_dsi>; ++ }; ++ ++ dsi_in_vopl: endpoint@1 { ++ reg = <1>; ++ remote-endpoint = <&vopl_out_dsi>; ++ }; ++ }; ++ }; ++ }; ++ ++ vopb: vop@ff460000 { ++ compatible = "rockchip,px30-vop-big"; ++ reg = <0x0 0xff460000 0x0 0xefc>; ++ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru ACLK_VOPB>, <&cru DCLK_VOPB>, ++ <&cru HCLK_VOPB>; ++ clock-names = "aclk_vop", "dclk_vop", "hclk_vop"; ++ resets = <&cru SRST_VOPB_A>, <&cru SRST_VOPB_H>, <&cru SRST_VOPB>; ++ reset-names = "axi", "ahb", "dclk"; ++ iommus = <&vopb_mmu>; ++ power-domains = <&power PX30_PD_VO>; ++ rockchip,grf = <&grf>; ++ status = "disabled"; ++ ++ vopb_out: port { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ vopb_out_dsi: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&dsi_in_vopb>; ++ }; ++ }; ++ }; ++ ++ vopb_mmu: iommu@ff460f00 { ++ compatible = "rockchip,iommu"; ++ reg = <0x0 0xff460f00 0x0 0x100>; ++ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "vopb_mmu"; ++ clocks = <&cru ACLK_VOPB>, <&cru HCLK_VOPB>; ++ clock-names = "aclk", "iface"; ++ power-domains = <&power PX30_PD_VO>; ++ #iommu-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ vopl: vop@ff470000 { ++ compatible = "rockchip,px30-vop-lit"; ++ reg = <0x0 0xff470000 0x0 0xefc>; ++ interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru ACLK_VOPL>, <&cru DCLK_VOPL>, ++ <&cru HCLK_VOPL>; ++ clock-names = "aclk_vop", "dclk_vop", "hclk_vop"; ++ resets = <&cru SRST_VOPL_A>, <&cru SRST_VOPL_H>, <&cru SRST_VOPL>; ++ reset-names = "axi", "ahb", "dclk"; ++ iommus = <&vopl_mmu>; ++ power-domains = <&power PX30_PD_VO>; ++ rockchip,grf = <&grf>; ++ status = "disabled"; ++ ++ vopl_out: port { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ vopl_out_dsi: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&dsi_in_vopl>; ++ }; ++ }; ++ }; ++ ++ vopl_mmu: iommu@ff470f00 { ++ compatible = "rockchip,iommu"; ++ reg = <0x0 0xff470f00 0x0 0x100>; ++ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "vopl_mmu"; ++ clocks = <&cru ACLK_VOPL>, <&cru HCLK_VOPL>; ++ clock-names = "aclk", "iface"; ++ power-domains = <&power PX30_PD_VO>; ++ #iommu-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ qos_gmac: qos@ff518000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff518000 0x0 0x20>; ++ }; ++ ++ qos_gpu: qos@ff520000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff520000 0x0 0x20>; ++ }; ++ ++ qos_sdmmc: qos@ff52c000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff52c000 0x0 0x20>; ++ }; ++ ++ qos_emmc: qos@ff538000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff538000 0x0 0x20>; ++ }; ++ ++ qos_nand: qos@ff538080 { ++ compatible = "syscon"; ++ reg = <0x0 0xff538080 0x0 0x20>; ++ }; ++ ++ qos_sdio: qos@ff538100 { ++ compatible = "syscon"; ++ reg = <0x0 0xff538100 0x0 0x20>; ++ }; ++ ++ qos_sfc: qos@ff538180 { ++ compatible = "syscon"; ++ reg = <0x0 0xff538180 0x0 0x20>; ++ }; ++ ++ qos_usb_host: qos@ff540000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff540000 0x0 0x20>; ++ }; ++ ++ qos_usb_otg: qos@ff540080 { ++ compatible = "syscon"; ++ reg = <0x0 0xff540080 0x0 0x20>; ++ }; ++ ++ qos_isp_128: qos@ff548000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff548000 0x0 0x20>; ++ }; ++ ++ qos_isp_rd: qos@ff548080 { ++ compatible = "syscon"; ++ reg = <0x0 0xff548080 0x0 0x20>; ++ }; ++ ++ qos_isp_wr: qos@ff548100 { ++ compatible = "syscon"; ++ reg = <0x0 0xff548100 0x0 0x20>; ++ }; ++ ++ qos_isp_m1: qos@ff548180 { ++ compatible = "syscon"; ++ reg = <0x0 0xff548180 0x0 0x20>; ++ }; ++ ++ qos_vip: qos@ff548200 { ++ compatible = "syscon"; ++ reg = <0x0 0xff548200 0x0 0x20>; ++ }; ++ ++ qos_rga_rd: qos@ff550000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff550000 0x0 0x20>; ++ }; ++ ++ qos_rga_wr: qos@ff550080 { ++ compatible = "syscon"; ++ reg = <0x0 0xff550080 0x0 0x20>; ++ }; ++ ++ qos_vop_m0: qos@ff550100 { ++ compatible = "syscon"; ++ reg = <0x0 0xff550100 0x0 0x20>; ++ }; ++ ++ qos_vop_m1: qos@ff550180 { ++ compatible = "syscon"; ++ reg = <0x0 0xff550180 0x0 0x20>; ++ }; ++ ++ qos_vpu: qos@ff558000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff558000 0x0 0x20>; ++ }; ++ ++ qos_vpu_r128: qos@ff558080 { ++ compatible = "syscon"; ++ reg = <0x0 0xff558080 0x0 0x20>; ++ }; ++ ++ pinctrl: pinctrl { ++ compatible = "rockchip,px30-pinctrl"; ++ rockchip,grf = <&grf>; ++ rockchip,pmu = <&pmugrf>; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ ++ gpio0: gpio0@ff040000 { ++ compatible = "rockchip,gpio-bank"; ++ reg = <0x0 0xff040000 0x0 0x100>; ++ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&pmucru PCLK_GPIO0_PMU>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ gpio1: gpio1@ff250000 { ++ compatible = "rockchip,gpio-bank"; ++ reg = <0x0 0xff250000 0x0 0x100>; ++ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru PCLK_GPIO1>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ gpio2: gpio2@ff260000 { ++ compatible = "rockchip,gpio-bank"; ++ reg = <0x0 0xff260000 0x0 0x100>; ++ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru PCLK_GPIO2>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ gpio3: gpio3@ff270000 { ++ compatible = "rockchip,gpio-bank"; ++ reg = <0x0 0xff270000 0x0 0x100>; ++ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru PCLK_GPIO3>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ pcfg_pull_up: pcfg-pull-up { ++ bias-pull-up; ++ }; ++ ++ pcfg_pull_down: pcfg-pull-down { ++ bias-pull-down; ++ }; ++ ++ pcfg_pull_none: pcfg-pull-none { ++ bias-disable; ++ }; ++ ++ pcfg_pull_none_2ma: pcfg-pull-none-2ma { ++ bias-disable; ++ drive-strength = <2>; ++ }; ++ ++ pcfg_pull_up_2ma: pcfg-pull-up-2ma { ++ bias-pull-up; ++ drive-strength = <2>; ++ }; ++ ++ pcfg_pull_up_4ma: pcfg-pull-up-4ma { ++ bias-pull-up; ++ drive-strength = <4>; ++ }; ++ ++ pcfg_pull_none_4ma: pcfg-pull-none-4ma { ++ bias-disable; ++ drive-strength = <4>; ++ }; ++ ++ pcfg_pull_down_4ma: pcfg-pull-down-4ma { ++ bias-pull-down; ++ drive-strength = <4>; ++ }; ++ ++ pcfg_pull_none_8ma: pcfg-pull-none-8ma { ++ bias-disable; ++ drive-strength = <8>; ++ }; ++ ++ pcfg_pull_up_8ma: pcfg-pull-up-8ma { ++ bias-pull-up; ++ drive-strength = <8>; ++ }; ++ ++ pcfg_pull_none_12ma: pcfg-pull-none-12ma { ++ bias-disable; ++ drive-strength = <12>; ++ }; ++ ++ pcfg_pull_up_12ma: pcfg-pull-up-12ma { ++ bias-pull-up; ++ drive-strength = <12>; ++ }; ++ ++ pcfg_pull_none_smt: pcfg-pull-none-smt { ++ bias-disable; ++ input-schmitt-enable; ++ }; ++ ++ pcfg_output_high: pcfg-output-high { ++ output-high; ++ }; ++ ++ pcfg_output_low: pcfg-output-low { ++ output-low; ++ }; ++ ++ pcfg_input_high: pcfg-input-high { ++ bias-pull-up; ++ input-enable; ++ }; ++ ++ pcfg_input: pcfg-input { ++ input-enable; ++ }; ++ ++ i2c0 { ++ i2c0_xfer: i2c0-xfer { ++ rockchip,pins = ++ <0 RK_PB0 1 &pcfg_pull_none_smt>, ++ <0 RK_PB1 1 &pcfg_pull_none_smt>; ++ }; ++ }; ++ ++ i2c1 { ++ i2c1_xfer: i2c1-xfer { ++ rockchip,pins = ++ <0 RK_PC2 1 &pcfg_pull_none_smt>, ++ <0 RK_PC3 1 &pcfg_pull_none_smt>; ++ }; ++ }; ++ ++ i2c2 { ++ i2c2_xfer: i2c2-xfer { ++ rockchip,pins = ++ <2 RK_PB7 2 &pcfg_pull_none_smt>, ++ <2 RK_PC0 2 &pcfg_pull_none_smt>; ++ }; ++ }; ++ ++ i2c3 { ++ i2c3_xfer: i2c3-xfer { ++ rockchip,pins = ++ <1 RK_PB4 4 &pcfg_pull_none_smt>, ++ <1 RK_PB5 4 &pcfg_pull_none_smt>; ++ }; ++ }; ++ ++ tsadc { ++ tsadc_otp_gpio: tsadc-otp-gpio { ++ rockchip,pins = ++ <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ tsadc_otp_out: tsadc-otp-out { ++ rockchip,pins = ++ <0 RK_PA6 1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ uart0 { ++ uart0_xfer: uart0-xfer { ++ rockchip,pins = ++ <0 RK_PB2 1 &pcfg_pull_up>, ++ <0 RK_PB3 1 &pcfg_pull_up>; ++ }; ++ ++ uart0_cts: uart0-cts { ++ rockchip,pins = ++ <0 RK_PB4 1 &pcfg_pull_none>; ++ }; ++ ++ uart0_rts: uart0-rts { ++ rockchip,pins = ++ <0 RK_PB5 1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ uart1 { ++ uart1_xfer: uart1-xfer { ++ rockchip,pins = ++ <1 RK_PC1 1 &pcfg_pull_up>, ++ <1 RK_PC0 1 &pcfg_pull_up>; ++ }; ++ ++ uart1_cts: uart1-cts { ++ rockchip,pins = ++ <1 RK_PC2 1 &pcfg_pull_none>; ++ }; ++ ++ uart1_rts: uart1-rts { ++ rockchip,pins = ++ <1 RK_PC3 1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ uart2-m0 { ++ uart2m0_xfer: uart2m0-xfer { ++ rockchip,pins = ++ <1 RK_PD2 2 &pcfg_pull_up>, ++ <1 RK_PD3 2 &pcfg_pull_up>; ++ }; ++ }; ++ ++ uart2-m1 { ++ uart2m1_xfer: uart2m1-xfer { ++ rockchip,pins = ++ <2 RK_PB4 2 &pcfg_pull_up>, ++ <2 RK_PB6 2 &pcfg_pull_up>; ++ }; ++ }; ++ ++ uart3-m0 { ++ uart3m0_xfer: uart3m0-xfer { ++ rockchip,pins = ++ <0 RK_PC0 2 &pcfg_pull_up>, ++ <0 RK_PC1 2 &pcfg_pull_up>; ++ }; ++ ++ uart3m0_cts: uart3m0-cts { ++ rockchip,pins = ++ <0 RK_PC2 2 &pcfg_pull_none>; ++ }; ++ ++ uart3m0_rts: uart3m0-rts { ++ rockchip,pins = ++ <0 RK_PC3 2 &pcfg_pull_none>; ++ }; ++ }; ++ ++ uart3-m1 { ++ uart3m1_xfer: uart3m1-xfer { ++ rockchip,pins = ++ <1 RK_PB6 2 &pcfg_pull_up>, ++ <1 RK_PB7 2 &pcfg_pull_up>; ++ }; ++ ++ uart3m1_cts: uart3m1-cts { ++ rockchip,pins = ++ <1 RK_PB4 2 &pcfg_pull_none>; ++ }; ++ ++ uart3m1_rts: uart3m1-rts { ++ rockchip,pins = ++ <1 RK_PB5 2 &pcfg_pull_none>; ++ }; ++ }; ++ ++ uart4 { ++ uart4_xfer: uart4-xfer { ++ rockchip,pins = ++ <1 RK_PD4 2 &pcfg_pull_up>, ++ <1 RK_PD5 2 &pcfg_pull_up>; ++ }; ++ ++ uart4_cts: uart4-cts { ++ rockchip,pins = ++ <1 RK_PD6 2 &pcfg_pull_none>; ++ }; ++ ++ uart4_rts: uart4-rts { ++ rockchip,pins = ++ <1 RK_PD7 2 &pcfg_pull_none>; ++ }; ++ }; ++ ++ uart5 { ++ uart5_xfer: uart5-xfer { ++ rockchip,pins = ++ <3 RK_PA2 4 &pcfg_pull_up>, ++ <3 RK_PA1 4 &pcfg_pull_up>; ++ }; ++ ++ uart5_cts: uart5-cts { ++ rockchip,pins = ++ <3 RK_PA3 4 &pcfg_pull_none>; ++ }; ++ ++ uart5_rts: uart5-rts { ++ rockchip,pins = ++ <3 RK_PA5 4 &pcfg_pull_none>; ++ }; ++ }; ++ ++ spi0 { ++ spi0_clk: spi0-clk { ++ rockchip,pins = ++ <1 RK_PB7 3 &pcfg_pull_up_4ma>; ++ }; ++ ++ spi0_csn: spi0-csn { ++ rockchip,pins = ++ <1 RK_PB6 3 &pcfg_pull_up_4ma>; ++ }; ++ ++ spi0_miso: spi0-miso { ++ rockchip,pins = ++ <1 RK_PB5 3 &pcfg_pull_up_4ma>; ++ }; ++ ++ spi0_mosi: spi0-mosi { ++ rockchip,pins = ++ <1 RK_PB4 3 &pcfg_pull_up_4ma>; ++ }; ++ ++ spi0_clk_hs: spi0-clk-hs { ++ rockchip,pins = ++ <1 RK_PB7 3 &pcfg_pull_up_8ma>; ++ }; ++ ++ spi0_miso_hs: spi0-miso-hs { ++ rockchip,pins = ++ <1 RK_PB5 3 &pcfg_pull_up_8ma>; ++ }; ++ ++ spi0_mosi_hs: spi0-mosi-hs { ++ rockchip,pins = ++ <1 RK_PB4 3 &pcfg_pull_up_8ma>; ++ }; ++ }; ++ ++ spi1 { ++ spi1_clk: spi1-clk { ++ rockchip,pins = ++ <3 RK_PB7 4 &pcfg_pull_up_4ma>; ++ }; ++ ++ spi1_csn0: spi1-csn0 { ++ rockchip,pins = ++ <3 RK_PB1 4 &pcfg_pull_up_4ma>; ++ }; ++ ++ spi1_csn1: spi1-csn1 { ++ rockchip,pins = ++ <3 RK_PB2 2 &pcfg_pull_up_4ma>; ++ }; ++ ++ spi1_miso: spi1-miso { ++ rockchip,pins = ++ <3 RK_PB6 4 &pcfg_pull_up_4ma>; ++ }; ++ ++ spi1_mosi: spi1-mosi { ++ rockchip,pins = ++ <3 RK_PB4 4 &pcfg_pull_up_4ma>; ++ }; ++ ++ spi1_clk_hs: spi1-clk-hs { ++ rockchip,pins = ++ <3 RK_PB7 4 &pcfg_pull_up_8ma>; ++ }; ++ ++ spi1_miso_hs: spi1-miso-hs { ++ rockchip,pins = ++ <3 RK_PB6 4 &pcfg_pull_up_8ma>; ++ }; ++ ++ spi1_mosi_hs: spi1-mosi-hs { ++ rockchip,pins = ++ <3 RK_PB4 4 &pcfg_pull_up_8ma>; ++ }; ++ }; ++ ++ pdm { ++ pdm_clk0m0: pdm-clk0m0 { ++ rockchip,pins = ++ <3 RK_PC6 2 &pcfg_pull_none>; ++ }; ++ ++ pdm_clk0m1: pdm-clk0m1 { ++ rockchip,pins = ++ <2 RK_PC6 1 &pcfg_pull_none>; ++ }; ++ ++ pdm_clk1: pdm-clk1 { ++ rockchip,pins = ++ <3 RK_PC7 2 &pcfg_pull_none>; ++ }; ++ ++ pdm_sdi0m0: pdm-sdi0m0 { ++ rockchip,pins = ++ <3 RK_PD3 2 &pcfg_pull_none>; ++ }; ++ ++ pdm_sdi0m1: pdm-sdi0m1 { ++ rockchip,pins = ++ <2 RK_PC5 2 &pcfg_pull_none>; ++ }; ++ ++ pdm_sdi1: pdm-sdi1 { ++ rockchip,pins = ++ <3 RK_PD0 2 &pcfg_pull_none>; ++ }; ++ ++ pdm_sdi2: pdm-sdi2 { ++ rockchip,pins = ++ <3 RK_PD1 2 &pcfg_pull_none>; ++ }; ++ ++ pdm_sdi3: pdm-sdi3 { ++ rockchip,pins = ++ <3 RK_PD2 2 &pcfg_pull_none>; ++ }; ++ ++ pdm_clk0m0_sleep: pdm-clk0m0-sleep { ++ rockchip,pins = ++ <3 RK_PC6 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ ++ pdm_clk0m_sleep1: pdm-clk0m1-sleep { ++ rockchip,pins = ++ <2 RK_PC6 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ ++ pdm_clk1_sleep: pdm-clk1-sleep { ++ rockchip,pins = ++ <3 RK_PC7 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ ++ pdm_sdi0m0_sleep: pdm-sdi0m0-sleep { ++ rockchip,pins = ++ <3 RK_PD3 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ ++ pdm_sdi0m1_sleep: pdm-sdi0m1-sleep { ++ rockchip,pins = ++ <2 RK_PC5 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ ++ pdm_sdi1_sleep: pdm-sdi1-sleep { ++ rockchip,pins = ++ <3 RK_PD0 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ ++ pdm_sdi2_sleep: pdm-sdi2-sleep { ++ rockchip,pins = ++ <3 RK_PD1 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ ++ pdm_sdi3_sleep: pdm-sdi3-sleep { ++ rockchip,pins = ++ <3 RK_PD2 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ }; ++ ++ i2s0 { ++ i2s0_8ch_mclk: i2s0-8ch-mclk { ++ rockchip,pins = ++ <3 RK_PC1 2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sclktx: i2s0-8ch-sclktx { ++ rockchip,pins = ++ <3 RK_PC3 2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sclkrx: i2s0-8ch-sclkrx { ++ rockchip,pins = ++ <3 RK_PB4 2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_lrcktx: i2s0-8ch-lrcktx { ++ rockchip,pins = ++ <3 RK_PC2 2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_lrckrx: i2s0-8ch-lrckrx { ++ rockchip,pins = ++ <3 RK_PB5 2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdo0: i2s0-8ch-sdo0 { ++ rockchip,pins = ++ <3 RK_PC4 2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdo1: i2s0-8ch-sdo1 { ++ rockchip,pins = ++ <3 RK_PC0 2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdo2: i2s0-8ch-sdo2 { ++ rockchip,pins = ++ <3 RK_PB7 2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdo3: i2s0-8ch-sdo3 { ++ rockchip,pins = ++ <3 RK_PB6 2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdi0: i2s0-8ch-sdi0 { ++ rockchip,pins = ++ <3 RK_PC5 2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdi1: i2s0-8ch-sdi1 { ++ rockchip,pins = ++ <3 RK_PB3 2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdi2: i2s0-8ch-sdi2 { ++ rockchip,pins = ++ <3 RK_PB1 2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdi3: i2s0-8ch-sdi3 { ++ rockchip,pins = ++ <3 RK_PB0 2 &pcfg_pull_none>; ++ }; ++ }; ++ ++ i2s1 { ++ i2s1_2ch_mclk: i2s1-2ch-mclk { ++ rockchip,pins = ++ <2 RK_PC3 1 &pcfg_pull_none>; ++ }; ++ ++ i2s1_2ch_sclk: i2s1-2ch-sclk { ++ rockchip,pins = ++ <2 RK_PC2 1 &pcfg_pull_none>; ++ }; ++ ++ i2s1_2ch_lrck: i2s1-2ch-lrck { ++ rockchip,pins = ++ <2 RK_PC1 1 &pcfg_pull_none>; ++ }; ++ ++ i2s1_2ch_sdi: i2s1-2ch-sdi { ++ rockchip,pins = ++ <2 RK_PC5 1 &pcfg_pull_none>; ++ }; ++ ++ i2s1_2ch_sdo: i2s1-2ch-sdo { ++ rockchip,pins = ++ <2 RK_PC4 1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ i2s2 { ++ i2s2_2ch_mclk: i2s2-2ch-mclk { ++ rockchip,pins = ++ <3 RK_PA1 2 &pcfg_pull_none>; ++ }; ++ ++ i2s2_2ch_sclk: i2s2-2ch-sclk { ++ rockchip,pins = ++ <3 RK_PA2 2 &pcfg_pull_none>; ++ }; ++ ++ i2s2_2ch_lrck: i2s2-2ch-lrck { ++ rockchip,pins = ++ <3 RK_PA3 2 &pcfg_pull_none>; ++ }; ++ ++ i2s2_2ch_sdi: i2s2-2ch-sdi { ++ rockchip,pins = ++ <3 RK_PA5 2 &pcfg_pull_none>; ++ }; ++ ++ i2s2_2ch_sdo: i2s2-2ch-sdo { ++ rockchip,pins = ++ <3 RK_PA7 2 &pcfg_pull_none>; ++ }; ++ }; ++ ++ sdmmc { ++ sdmmc_clk: sdmmc-clk { ++ rockchip,pins = ++ <1 RK_PD6 1 &pcfg_pull_none_8ma>; ++ }; ++ ++ sdmmc_cmd: sdmmc-cmd { ++ rockchip,pins = ++ <1 RK_PD7 1 &pcfg_pull_up_8ma>; ++ }; ++ ++ sdmmc_det: sdmmc-det { ++ rockchip,pins = ++ <0 RK_PA3 1 &pcfg_pull_up_8ma>; ++ }; ++ ++ sdmmc_bus1: sdmmc-bus1 { ++ rockchip,pins = ++ <1 RK_PD2 1 &pcfg_pull_up_8ma>; ++ }; ++ ++ sdmmc_bus4: sdmmc-bus4 { ++ rockchip,pins = ++ <1 RK_PD2 1 &pcfg_pull_up_8ma>, ++ <1 RK_PD3 1 &pcfg_pull_up_8ma>, ++ <1 RK_PD4 1 &pcfg_pull_up_8ma>, ++ <1 RK_PD5 1 &pcfg_pull_up_8ma>; ++ }; ++ }; ++ ++ sdio { ++ sdio_clk: sdio-clk { ++ rockchip,pins = ++ <1 RK_PC5 1 &pcfg_pull_none>; ++ }; ++ ++ sdio_cmd: sdio-cmd { ++ rockchip,pins = ++ <1 RK_PC4 1 &pcfg_pull_up>; ++ }; ++ ++ sdio_bus4: sdio-bus4 { ++ rockchip,pins = ++ <1 RK_PC6 1 &pcfg_pull_up>, ++ <1 RK_PC7 1 &pcfg_pull_up>, ++ <1 RK_PD0 1 &pcfg_pull_up>, ++ <1 RK_PD1 1 &pcfg_pull_up>; ++ }; ++ }; ++ ++ emmc { ++ emmc_clk: emmc-clk { ++ rockchip,pins = ++ <1 RK_PB1 2 &pcfg_pull_none_8ma>; ++ }; ++ ++ emmc_cmd: emmc-cmd { ++ rockchip,pins = ++ <1 RK_PB2 2 &pcfg_pull_up_8ma>; ++ }; ++ ++ emmc_rstnout: emmc-rstnout { ++ rockchip,pins = ++ <1 RK_PB3 2 &pcfg_pull_none>; ++ }; ++ ++ emmc_bus1: emmc-bus1 { ++ rockchip,pins = ++ <1 RK_PA0 2 &pcfg_pull_up_8ma>; ++ }; ++ ++ emmc_bus4: emmc-bus4 { ++ rockchip,pins = ++ <1 RK_PA0 2 &pcfg_pull_up_8ma>, ++ <1 RK_PA1 2 &pcfg_pull_up_8ma>, ++ <1 RK_PA2 2 &pcfg_pull_up_8ma>, ++ <1 RK_PA3 2 &pcfg_pull_up_8ma>; ++ }; ++ ++ emmc_bus8: emmc-bus8 { ++ rockchip,pins = ++ <1 RK_PA0 2 &pcfg_pull_up_8ma>, ++ <1 RK_PA1 2 &pcfg_pull_up_8ma>, ++ <1 RK_PA2 2 &pcfg_pull_up_8ma>, ++ <1 RK_PA3 2 &pcfg_pull_up_8ma>, ++ <1 RK_PA4 2 &pcfg_pull_up_8ma>, ++ <1 RK_PA5 2 &pcfg_pull_up_8ma>, ++ <1 RK_PA6 2 &pcfg_pull_up_8ma>, ++ <1 RK_PA7 2 &pcfg_pull_up_8ma>; ++ }; ++ }; ++ ++ flash { ++ flash_cs0: flash-cs0 { ++ rockchip,pins = ++ <1 RK_PB0 1 &pcfg_pull_none>; ++ }; ++ ++ flash_rdy: flash-rdy { ++ rockchip,pins = ++ <1 RK_PB1 1 &pcfg_pull_none>; ++ }; ++ ++ flash_dqs: flash-dqs { ++ rockchip,pins = ++ <1 RK_PB2 1 &pcfg_pull_none>; ++ }; ++ ++ flash_ale: flash-ale { ++ rockchip,pins = ++ <1 RK_PB3 1 &pcfg_pull_none>; ++ }; ++ ++ flash_cle: flash-cle { ++ rockchip,pins = ++ <1 RK_PB4 1 &pcfg_pull_none>; ++ }; ++ ++ flash_wrn: flash-wrn { ++ rockchip,pins = ++ <1 RK_PB5 1 &pcfg_pull_none>; ++ }; ++ ++ flash_csl: flash-csl { ++ rockchip,pins = ++ <1 RK_PB6 1 &pcfg_pull_none>; ++ }; ++ ++ flash_rdn: flash-rdn { ++ rockchip,pins = ++ <1 RK_PB7 1 &pcfg_pull_none>; ++ }; ++ ++ flash_bus8: flash-bus8 { ++ rockchip,pins = ++ <1 RK_PA0 1 &pcfg_pull_up_12ma>, ++ <1 RK_PA1 1 &pcfg_pull_up_12ma>, ++ <1 RK_PA2 1 &pcfg_pull_up_12ma>, ++ <1 RK_PA3 1 &pcfg_pull_up_12ma>, ++ <1 RK_PA4 1 &pcfg_pull_up_12ma>, ++ <1 RK_PA5 1 &pcfg_pull_up_12ma>, ++ <1 RK_PA6 1 &pcfg_pull_up_12ma>, ++ <1 RK_PA7 1 &pcfg_pull_up_12ma>; ++ }; ++ }; ++ ++ lcdc { ++ lcdc_rgb_dclk_pin: lcdc-rgb-dclk-pin { ++ rockchip,pins = ++ <3 RK_PA0 1 &pcfg_pull_none_12ma>; ++ }; ++ ++ lcdc_rgb_m0_hsync_pin: lcdc-rgb-m0-hsync-pin { ++ rockchip,pins = ++ <3 RK_PA1 1 &pcfg_pull_none_12ma>; ++ }; ++ ++ lcdc_rgb_m0_vsync_pin: lcdc-rgb-m0-vsync-pin { ++ rockchip,pins = ++ <3 RK_PA2 1 &pcfg_pull_none_12ma>; ++ }; ++ ++ lcdc_rgb_m0_den_pin: lcdc-rgb-m0-den-pin { ++ rockchip,pins = ++ <3 RK_PA3 1 &pcfg_pull_none_12ma>; ++ }; ++ ++ lcdc_rgb888_m0_data_pins: lcdc-rgb888-m0-data-pins { ++ rockchip,pins = ++ <3 RK_PA7 1 &pcfg_pull_none_8ma>, /* lcdc_d3 */ ++ <3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */ ++ <3 RK_PA5 1 &pcfg_pull_none_8ma>, /* lcdc_d1 */ ++ <3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */ ++ <3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */ ++ <3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */ ++ <3 RK_PB1 1 &pcfg_pull_none_8ma>, /* lcdc_d5 */ ++ <3 RK_PB0 1 &pcfg_pull_none_8ma>, /* lcdc_d4 */ ++ <3 RK_PB7 1 &pcfg_pull_none_8ma>, /* lcdc_d11 */ ++ <3 RK_PB6 1 &pcfg_pull_none_8ma>, /* lcdc_d10 */ ++ <3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */ ++ <3 RK_PB4 1 &pcfg_pull_none_8ma>, /* lcdc_d8 */ ++ <3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */ ++ <3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */ ++ <3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */ ++ <3 RK_PC0 1 &pcfg_pull_none_8ma>, /* lcdc_d12 */ ++ <3 RK_PC7 1 &pcfg_pull_none_8ma>, /* lcdc_d19 */ ++ <3 RK_PC6 1 &pcfg_pull_none_8ma>, /* lcdc_d18 */ ++ <3 RK_PC5 1 &pcfg_pull_none_8ma>, /* lcdc_d17 */ ++ <3 RK_PC4 1 &pcfg_pull_none_8ma>, /* lcdc_d16 */ ++ <3 RK_PD3 1 &pcfg_pull_none_8ma>, /* lcdc_d23 */ ++ <3 RK_PD2 1 &pcfg_pull_none_8ma>, /* lcdc_d22 */ ++ <3 RK_PD1 1 &pcfg_pull_none_8ma>, /* lcdc_d21 */ ++ <3 RK_PD0 1 &pcfg_pull_none_8ma>; /* lcdc_d20 */ ++ }; ++ ++ lcdc_rgb666_m0_data_pins: lcdc-rgb666-m0-data-pins { ++ rockchip,pins = ++ <3 RK_PA7 1 &pcfg_pull_none_8ma>, /* lcdc_d3 */ ++ <3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */ ++ <3 RK_PA5 1 &pcfg_pull_none_8ma>, /* lcdc_d1 */ ++ <3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */ ++ <3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */ ++ <3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */ ++ <3 RK_PB1 1 &pcfg_pull_none_8ma>, /* lcdc_d5 */ ++ <3 RK_PB0 1 &pcfg_pull_none_8ma>, /* lcdc_d4 */ ++ <3 RK_PB7 1 &pcfg_pull_none_8ma>, /* lcdc_d11 */ ++ <3 RK_PB6 1 &pcfg_pull_none_8ma>, /* lcdc_d10 */ ++ <3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */ ++ <3 RK_PB4 1 &pcfg_pull_none_8ma>, /* lcdc_d8 */ ++ <3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */ ++ <3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */ ++ <3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */ ++ <3 RK_PC0 1 &pcfg_pull_none_8ma>, /* lcdc_d12 */ ++ <3 RK_PC5 1 &pcfg_pull_none_8ma>, /* lcdc_d17 */ ++ <3 RK_PC4 1 &pcfg_pull_none_8ma>; /* lcdc_d16 */ ++ }; ++ ++ lcdc_rgb565_m0_data_pins: lcdc-rgb565-m0-data-pins { ++ rockchip,pins = ++ <3 RK_PA7 1 &pcfg_pull_none_8ma>, /* lcdc_d3 */ ++ <3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */ ++ <3 RK_PA5 1 &pcfg_pull_none_8ma>, /* lcdc_d1 */ ++ <3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */ ++ <3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */ ++ <3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */ ++ <3 RK_PB1 1 &pcfg_pull_none_8ma>, /* lcdc_d5 */ ++ <3 RK_PB0 1 &pcfg_pull_none_8ma>, /* lcdc_d4 */ ++ <3 RK_PB7 1 &pcfg_pull_none_8ma>, /* lcdc_d11 */ ++ <3 RK_PB6 1 &pcfg_pull_none_8ma>, /* lcdc_d10 */ ++ <3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */ ++ <3 RK_PB4 1 &pcfg_pull_none_8ma>, /* lcdc_d8 */ ++ <3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */ ++ <3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */ ++ <3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */ ++ <3 RK_PC0 1 &pcfg_pull_none_8ma>; /* lcdc_d12 */ ++ }; ++ ++ lcdc_rgb888_m1_data_pins: lcdc-rgb888-m1-data-pins { ++ rockchip,pins = ++ <3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */ ++ <3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */ ++ <3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */ ++ <3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */ ++ <3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */ ++ <3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */ ++ <3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */ ++ <3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */ ++ <3 RK_PC0 1 &pcfg_pull_none_8ma>, /* lcdc_d12 */ ++ <3 RK_PC7 1 &pcfg_pull_none_8ma>, /* lcdc_d19 */ ++ <3 RK_PC6 1 &pcfg_pull_none_8ma>, /* lcdc_d18 */ ++ <3 RK_PC5 1 &pcfg_pull_none_8ma>, /* lcdc_d17 */ ++ <3 RK_PC4 1 &pcfg_pull_none_8ma>, /* lcdc_d16 */ ++ <3 RK_PD3 1 &pcfg_pull_none_8ma>, /* lcdc_d23 */ ++ <3 RK_PD2 1 &pcfg_pull_none_8ma>, /* lcdc_d22 */ ++ <3 RK_PD1 1 &pcfg_pull_none_8ma>, /* lcdc_d21 */ ++ <3 RK_PD0 1 &pcfg_pull_none_8ma>; /* lcdc_d20 */ ++ }; ++ ++ lcdc_rgb666_m1_data_pins: lcdc-rgb666-m1-data-pins { ++ rockchip,pins = ++ <3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */ ++ <3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */ ++ <3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */ ++ <3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */ ++ <3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */ ++ <3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */ ++ <3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */ ++ <3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */ ++ <3 RK_PC0 1 &pcfg_pull_none_8ma>, /* lcdc_d12 */ ++ <3 RK_PC5 1 &pcfg_pull_none_8ma>, /* lcdc_d17 */ ++ <3 RK_PC4 1 &pcfg_pull_none_8ma>; /* lcdc_d16 */ ++ }; ++ ++ lcdc_rgb565_m1_data_pins: lcdc-rgb565-m1-data-pins { ++ rockchip,pins = ++ <3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */ ++ <3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */ ++ <3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */ ++ <3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */ ++ <3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */ ++ <3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */ ++ <3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */ ++ <3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */ ++ <3 RK_PC0 1 &pcfg_pull_none_8ma>; /* lcdc_d12 */ ++ }; ++ }; ++ ++ pwm0 { ++ pwm0_pin: pwm0-pin { ++ rockchip,pins = ++ <0 RK_PB7 1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ pwm1 { ++ pwm1_pin: pwm1-pin { ++ rockchip,pins = ++ <0 RK_PC0 1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ pwm2 { ++ pwm2_pin: pwm2-pin { ++ rockchip,pins = ++ <2 RK_PB5 1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ pwm3 { ++ pwm3_pin: pwm3-pin { ++ rockchip,pins = ++ <0 RK_PC1 1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ pwm4 { ++ pwm4_pin: pwm4-pin { ++ rockchip,pins = ++ <3 RK_PC2 3 &pcfg_pull_none>; ++ }; ++ }; ++ ++ pwm5 { ++ pwm5_pin: pwm5-pin { ++ rockchip,pins = ++ <3 RK_PC3 3 &pcfg_pull_none>; ++ }; ++ }; ++ ++ pwm6 { ++ pwm6_pin: pwm6-pin { ++ rockchip,pins = ++ <3 RK_PC4 3 &pcfg_pull_none>; ++ }; ++ }; ++ ++ pwm7 { ++ pwm7_pin: pwm7-pin { ++ rockchip,pins = ++ <3 RK_PC5 3 &pcfg_pull_none>; ++ }; ++ }; ++ ++ gmac { ++ rmii_pins: rmii-pins { ++ rockchip,pins = ++ <2 RK_PA0 2 &pcfg_pull_none_12ma>, /* mac_txen */ ++ <2 RK_PA1 2 &pcfg_pull_none_12ma>, /* mac_txd1 */ ++ <2 RK_PA2 2 &pcfg_pull_none_12ma>, /* mac_txd0 */ ++ <2 RK_PA3 2 &pcfg_pull_none>, /* mac_rxd0 */ ++ <2 RK_PA4 2 &pcfg_pull_none>, /* mac_rxd1 */ ++ <2 RK_PA5 2 &pcfg_pull_none>, /* mac_rxer */ ++ <2 RK_PA6 2 &pcfg_pull_none>, /* mac_rxdv */ ++ <2 RK_PA7 2 &pcfg_pull_none>, /* mac_mdio */ ++ <2 RK_PB1 2 &pcfg_pull_none>; /* mac_mdc */ ++ }; ++ ++ mac_refclk_12ma: mac-refclk-12ma { ++ rockchip,pins = ++ <2 RK_PB2 2 &pcfg_pull_none_12ma>; ++ }; ++ ++ mac_refclk: mac-refclk { ++ rockchip,pins = ++ <2 RK_PB2 2 &pcfg_pull_none>; ++ }; ++ }; ++ ++ cif-m0 { ++ cif_clkout_m0: cif-clkout-m0 { ++ rockchip,pins = ++ <2 RK_PB3 1 &pcfg_pull_none>; ++ }; ++ ++ dvp_d2d9_m0: dvp-d2d9-m0 { ++ rockchip,pins = ++ <2 RK_PA0 1 &pcfg_pull_none>, /* cif_data2 */ ++ <2 RK_PA1 1 &pcfg_pull_none>, /* cif_data3 */ ++ <2 RK_PA2 1 &pcfg_pull_none>, /* cif_data4 */ ++ <2 RK_PA3 1 &pcfg_pull_none>, /* cif_data5 */ ++ <2 RK_PA4 1 &pcfg_pull_none>, /* cif_data6 */ ++ <2 RK_PA5 1 &pcfg_pull_none>, /* cif_data7 */ ++ <2 RK_PA6 1 &pcfg_pull_none>, /* cif_data8 */ ++ <2 RK_PA7 1 &pcfg_pull_none>, /* cif_data9 */ ++ <2 RK_PB0 1 &pcfg_pull_none>, /* cif_sync */ ++ <2 RK_PB1 1 &pcfg_pull_none>, /* cif_href */ ++ <2 RK_PB2 1 &pcfg_pull_none>, /* cif_clkin */ ++ <2 RK_PB3 1 &pcfg_pull_none>; /* cif_clkout */ ++ }; ++ ++ dvp_d0d1_m0: dvp-d0d1-m0 { ++ rockchip,pins = ++ <2 RK_PB4 1 &pcfg_pull_none>, /* cif_data0 */ ++ <2 RK_PB6 1 &pcfg_pull_none>; /* cif_data1 */ ++ }; ++ ++ dvp_d10d11_m0:d10-d11-m0 { ++ rockchip,pins = ++ <2 RK_PB7 1 &pcfg_pull_none>, /* cif_data10 */ ++ <2 RK_PC0 1 &pcfg_pull_none>; /* cif_data11 */ ++ }; ++ }; ++ ++ cif-m1 { ++ cif_clkout_m1: cif-clkout-m1 { ++ rockchip,pins = ++ <3 RK_PD0 3 &pcfg_pull_none>; ++ }; ++ ++ dvp_d2d9_m1: dvp-d2d9-m1 { ++ rockchip,pins = ++ <3 RK_PA3 3 &pcfg_pull_none>, /* cif_data2 */ ++ <3 RK_PA5 3 &pcfg_pull_none>, /* cif_data3 */ ++ <3 RK_PA7 3 &pcfg_pull_none>, /* cif_data4 */ ++ <3 RK_PB0 3 &pcfg_pull_none>, /* cif_data5 */ ++ <3 RK_PB1 3 &pcfg_pull_none>, /* cif_data6 */ ++ <3 RK_PB4 3 &pcfg_pull_none>, /* cif_data7 */ ++ <3 RK_PB6 3 &pcfg_pull_none>, /* cif_data8 */ ++ <3 RK_PB7 3 &pcfg_pull_none>, /* cif_data9 */ ++ <3 RK_PD1 3 &pcfg_pull_none>, /* cif_sync */ ++ <3 RK_PD2 3 &pcfg_pull_none>, /* cif_href */ ++ <3 RK_PD3 3 &pcfg_pull_none>, /* cif_clkin */ ++ <3 RK_PD0 3 &pcfg_pull_none>; /* cif_clkout */ ++ }; ++ ++ dvp_d0d1_m1: dvp-d0d1-m1 { ++ rockchip,pins = ++ <3 RK_PA1 3 &pcfg_pull_none>, /* cif_data0 */ ++ <3 RK_PA2 3 &pcfg_pull_none>; /* cif_data1 */ ++ }; ++ ++ dvp_d10d11_m1:d10-d11-m1 { ++ rockchip,pins = ++ <3 RK_PC6 3 &pcfg_pull_none>, /* cif_data10 */ ++ <3 RK_PC7 3 &pcfg_pull_none>; /* cif_data11 */ ++ }; ++ }; ++ ++ isp { ++ isp_prelight: isp-prelight { ++ rockchip,pins = ++ <3 RK_PD1 4 &pcfg_pull_none>; ++ }; ++ }; ++ }; ++}; + +From patchwork Thu Oct 24 23:28:02 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: =?utf-8?q?Heiko_St=C3=BCbner?= <heiko@sntech.de> +X-Patchwork-Id: 1183663 +X-Patchwork-Delegate: ykai007@gmail.com +Return-Path: <u-boot-bounces@lists.denx.de> +X-Original-To: incoming@patchwork.ozlabs.org +Delivered-To: patchwork-incoming@bilbo.ozlabs.org +Authentication-Results: ozlabs.org; + spf=none (no SPF record) smtp.mailfrom=lists.denx.de + (client-ip=81.169.180.215; helo=lists.denx.de; + envelope-from=u-boot-bounces@lists.denx.de; + receiver=<UNKNOWN>) +Authentication-Results: ozlabs.org; + dmarc=none (p=none dis=none) header.from=sntech.de +Received: from lists.denx.de (dione.denx.de [81.169.180.215]) + by ozlabs.org (Postfix) with ESMTP id 46zkT344zwz9sPk + for <incoming@patchwork.ozlabs.org>; + Fri, 25 Oct 2019 10:48:07 +1100 (AEDT) +Received: by lists.denx.de (Postfix, from userid 105) + id 43CE0C21DCA; Thu, 24 Oct 2019 23:48:06 +0000 (UTC) +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de +X-Spam-Level: +X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable + autolearn_force=no version=3.4.0 +Received: from lists.denx.de (localhost [IPv6:::1]) + by lists.denx.de (Postfix) with ESMTP id 677B0C21D8A; + Thu, 24 Oct 2019 23:47:48 +0000 (UTC) +Received: by lists.denx.de (Postfix, from userid 105) + id 7F9B4C21D8A; Thu, 24 Oct 2019 23:47:47 +0000 (UTC) +Received: from gloria.sntech.de (gloria.sntech.de [185.11.138.130]) + by lists.denx.de (Postfix) with ESMTPS id 62563C21C6A + for <u-boot@lists.denx.de>; Thu, 24 Oct 2019 23:47:46 +0000 (UTC) +Received: from ip5f5a6266.dynamic.kabel-deutschland.de ([95.90.98.102] + helo=phil.fritz.box) by gloria.sntech.de with esmtpsa + (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) + (Exim 4.89) (envelope-from <heiko@sntech.de>) + id 1iNmWh-0002cR-Cg; Fri, 25 Oct 2019 01:28:19 +0200 +From: Heiko Stuebner <heiko@sntech.de> +To: u-boot@lists.denx.de +Date: Fri, 25 Oct 2019 01:28:02 +0200 +Message-Id: <20191024232803.10338-12-heiko@sntech.de> +X-Mailer: git-send-email 2.23.0 +In-Reply-To: <20191024232803.10338-1-heiko@sntech.de> +References: <20191024232803.10338-1-heiko@sntech.de> +MIME-Version: 1.0 +Cc: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>, + joe.hershberger@ni.com, christoph.muellner@theobroma-systems.com +Subject: [U-Boot] [PATCH 11/12] rockchip: add px30 architecture core +X-BeenThere: u-boot@lists.denx.de +X-Mailman-Version: 2.1.18 +Precedence: list +List-Id: U-Boot discussion <u-boot.lists.denx.de> +List-Unsubscribe: <https://lists.denx.de/options/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=unsubscribe> +List-Archive: <http://lists.denx.de/pipermail/u-boot/> +List-Post: <mailto:u-boot@lists.denx.de> +List-Help: <mailto:u-boot-request@lists.denx.de?subject=help> +List-Subscribe: <https://lists.denx.de/listinfo/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=subscribe> +Errors-To: u-boot-bounces@lists.denx.de +Sender: "U-Boot" <u-boot-bounces@lists.denx.de> + +From: Kever Yang <kever.yang@rock-chips.com> + +Add core architecture code to support the px30 soc. +This includes a separate tpl board file due to very limited +sram size as well as a non-dm sdram driver, as this also has +to fit into the tiny sram. + +Signed-off-by: Kever Yang <kever.yang@rock-chips.com> +Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com> +--- + arch/arm/include/asm/arch-px30/boot0.h | 11 + + arch/arm/include/asm/arch-px30/gpio.h | 11 + + .../include/asm/arch-rockchip/sdram_px30.h | 359 +++++ + arch/arm/mach-rockchip/Kconfig | 23 + + arch/arm/mach-rockchip/Makefile | 2 + + arch/arm/mach-rockchip/px30-board-tpl.c | 59 + + arch/arm/mach-rockchip/px30/Kconfig | 48 + + arch/arm/mach-rockchip/px30/Makefile | 14 + + arch/arm/mach-rockchip/px30/clk_px30.c | 31 + + arch/arm/mach-rockchip/px30/px30.c | 248 +++ + .../px30/sdram-px30-ddr3-detect-333.inc | 70 + + .../px30/sdram-px30-ddr4-detect-333.inc | 73 + + .../px30/sdram-px30-ddr_skew.inc | 121 ++ + .../px30/sdram-px30-lpddr2-detect-333.inc | 71 + + .../px30/sdram-px30-lpddr3-detect-333.inc | 72 + + arch/arm/mach-rockchip/px30/sdram_px30.c | 1405 +++++++++++++++++ + arch/arm/mach-rockchip/px30/syscon_px30.c | 53 + + 17 files changed, 2671 insertions(+) + create mode 100644 arch/arm/include/asm/arch-px30/boot0.h + create mode 100644 arch/arm/include/asm/arch-px30/gpio.h + create mode 100644 arch/arm/include/asm/arch-rockchip/sdram_px30.h + create mode 100644 arch/arm/mach-rockchip/px30-board-tpl.c + create mode 100644 arch/arm/mach-rockchip/px30/Kconfig + create mode 100644 arch/arm/mach-rockchip/px30/Makefile + create mode 100644 arch/arm/mach-rockchip/px30/clk_px30.c + create mode 100644 arch/arm/mach-rockchip/px30/px30.c + create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-ddr3-detect-333.inc + create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-ddr4-detect-333.inc + create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-ddr_skew.inc + create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-lpddr2-detect-333.inc + create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-lpddr3-detect-333.inc + create mode 100644 arch/arm/mach-rockchip/px30/sdram_px30.c + create mode 100644 arch/arm/mach-rockchip/px30/syscon_px30.c + +diff --git a/arch/arm/include/asm/arch-px30/boot0.h b/arch/arm/include/asm/arch-px30/boot0.h +new file mode 100644 +index 0000000000..2e78b074ad +--- /dev/null ++++ b/arch/arm/include/asm/arch-px30/boot0.h +@@ -0,0 +1,11 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * (C) Copyright 2019 Rockchip Electronics Co., Ltd ++ */ ++ ++#ifndef __ASM_ARCH_BOOT0_H__ ++#define __ASM_ARCH_BOOT0_H__ ++ ++#include <asm/arch-rockchip/boot0.h> ++ ++#endif +diff --git a/arch/arm/include/asm/arch-px30/gpio.h b/arch/arm/include/asm/arch-px30/gpio.h +new file mode 100644 +index 0000000000..eca79d5159 +--- /dev/null ++++ b/arch/arm/include/asm/arch-px30/gpio.h +@@ -0,0 +1,11 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * (C) Copyright 2019 Rockchip Electronics Co., Ltd ++ */ ++ ++#ifndef __ASM_ARCH_GPIO_H__ ++#define __ASM_ARCH_GPIO_H__ ++ ++#include <asm/arch-rockchip/gpio.h> ++ ++#endif +diff --git a/arch/arm/include/asm/arch-rockchip/sdram_px30.h b/arch/arm/include/asm/arch-rockchip/sdram_px30.h +new file mode 100644 +index 0000000000..e10eb97b89 +--- /dev/null ++++ b/arch/arm/include/asm/arch-rockchip/sdram_px30.h +@@ -0,0 +1,359 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * Copyright (C) 2018 Rockchip Electronics Co., Ltd ++ */ ++ ++#ifndef _ASM_ARCH_SDRAM_PX30_H ++#define _ASM_ARCH_SDRAM_PX30_H ++ ++struct ddr_pctl_regs { ++ u32 pctl[30][2]; ++}; ++ ++/* ddr pctl registers define */ ++#define DDR_PCTL2_MSTR 0x0 ++#define DDR_PCTL2_STAT 0x4 ++#define DDR_PCTL2_MSTR1 0x8 ++#define DDR_PCTL2_MRCTRL0 0x10 ++#define DDR_PCTL2_MRCTRL1 0x14 ++#define DDR_PCTL2_MRSTAT 0x18 ++#define DDR_PCTL2_MRCTRL2 0x1c ++#define DDR_PCTL2_DERATEEN 0x20 ++#define DDR_PCTL2_DERATEINT 0x24 ++#define DDR_PCTL2_PWRCTL 0x30 ++#define DDR_PCTL2_PWRTMG 0x34 ++#define DDR_PCTL2_HWLPCTL 0x38 ++#define DDR_PCTL2_RFSHCTL0 0x50 ++#define DDR_PCTL2_RFSHCTL1 0x54 ++#define DDR_PCTL2_RFSHCTL2 0x58 ++#define DDR_PCTL2_RFSHCTL4 0x5c ++#define DDR_PCTL2_RFSHCTL3 0x60 ++#define DDR_PCTL2_RFSHTMG 0x64 ++#define DDR_PCTL2_RFSHTMG1 0x68 ++#define DDR_PCTL2_RFSHCTL5 0x6c ++#define DDR_PCTL2_INIT0 0xd0 ++#define DDR_PCTL2_INIT1 0xd4 ++#define DDR_PCTL2_INIT2 0xd8 ++#define DDR_PCTL2_INIT3 0xdc ++#define DDR_PCTL2_INIT4 0xe0 ++#define DDR_PCTL2_INIT5 0xe4 ++#define DDR_PCTL2_INIT6 0xe8 ++#define DDR_PCTL2_INIT7 0xec ++#define DDR_PCTL2_DIMMCTL 0xf0 ++#define DDR_PCTL2_RANKCTL 0xf4 ++#define DDR_PCTL2_CHCTL 0xfc ++#define DDR_PCTL2_DRAMTMG0 0x100 ++#define DDR_PCTL2_DRAMTMG1 0x104 ++#define DDR_PCTL2_DRAMTMG2 0x108 ++#define DDR_PCTL2_DRAMTMG3 0x10c ++#define DDR_PCTL2_DRAMTMG4 0x110 ++#define DDR_PCTL2_DRAMTMG5 0x114 ++#define DDR_PCTL2_DRAMTMG6 0x118 ++#define DDR_PCTL2_DRAMTMG7 0x11c ++#define DDR_PCTL2_DRAMTMG8 0x120 ++#define DDR_PCTL2_DRAMTMG9 0x124 ++#define DDR_PCTL2_DRAMTMG10 0x128 ++#define DDR_PCTL2_DRAMTMG11 0x12c ++#define DDR_PCTL2_DRAMTMG12 0x130 ++#define DDR_PCTL2_DRAMTMG13 0x134 ++#define DDR_PCTL2_DRAMTMG14 0x138 ++#define DDR_PCTL2_DRAMTMG15 0x13c ++#define DDR_PCTL2_DRAMTMG16 0x140 ++#define DDR_PCTL2_ZQCTL0 0x180 ++#define DDR_PCTL2_ZQCTL1 0x184 ++#define DDR_PCTL2_ZQCTL2 0x188 ++#define DDR_PCTL2_ZQSTAT 0x18c ++#define DDR_PCTL2_DFITMG0 0x190 ++#define DDR_PCTL2_DFITMG1 0x194 ++#define DDR_PCTL2_DFILPCFG0 0x198 ++#define DDR_PCTL2_DFILPCFG1 0x19c ++#define DDR_PCTL2_DFIUPD0 0x1a0 ++#define DDR_PCTL2_DFIUPD1 0x1a4 ++#define DDR_PCTL2_DFIUPD2 0x1a8 ++#define DDR_PCTL2_DFIMISC 0x1b0 ++#define DDR_PCTL2_DFITMG2 0x1b4 ++#define DDR_PCTL2_DFITMG3 0x1b8 ++#define DDR_PCTL2_DFISTAT 0x1bc ++#define DDR_PCTL2_DBICTL 0x1c0 ++#define DDR_PCTL2_ADDRMAP0 0x200 ++#define DDR_PCTL2_ADDRMAP1 0x204 ++#define DDR_PCTL2_ADDRMAP2 0x208 ++#define DDR_PCTL2_ADDRMAP3 0x20c ++#define DDR_PCTL2_ADDRMAP4 0x210 ++#define DDR_PCTL2_ADDRMAP5 0x214 ++#define DDR_PCTL2_ADDRMAP6 0x218 ++#define DDR_PCTL2_ADDRMAP7 0x21c ++#define DDR_PCTL2_ADDRMAP8 0x220 ++#define DDR_PCTL2_ADDRMAP9 0x224 ++#define DDR_PCTL2_ADDRMAP10 0x228 ++#define DDR_PCTL2_ADDRMAP11 0x22c ++#define DDR_PCTL2_ODTCFG 0x240 ++#define DDR_PCTL2_ODTMAP 0x244 ++#define DDR_PCTL2_SCHED 0x250 ++#define DDR_PCTL2_SCHED1 0x254 ++#define DDR_PCTL2_PERFHPR1 0x25c ++#define DDR_PCTL2_PERFLPR1 0x264 ++#define DDR_PCTL2_PERFWR1 0x26c ++#define DDR_PCTL2_DQMAP0 0x280 ++#define DDR_PCTL2_DQMAP1 0x284 ++#define DDR_PCTL2_DQMAP2 0x288 ++#define DDR_PCTL2_DQMAP3 0x28c ++#define DDR_PCTL2_DQMAP4 0x290 ++#define DDR_PCTL2_DQMAP5 0x294 ++#define DDR_PCTL2_DBG0 0x300 ++#define DDR_PCTL2_DBG1 0x304 ++#define DDR_PCTL2_DBGCAM 0x308 ++#define DDR_PCTL2_DBGCMD 0x30c ++#define DDR_PCTL2_DBGSTAT 0x310 ++#define DDR_PCTL2_SWCTL 0x320 ++#define DDR_PCTL2_SWSTAT 0x324 ++#define DDR_PCTL2_POISONCFG 0x36c ++#define DDR_PCTL2_POISONSTAT 0x370 ++#define DDR_PCTL2_ADVECCINDEX 0x374 ++#define DDR_PCTL2_ADVECCSTAT 0x378 ++#define DDR_PCTL2_PSTAT 0x3fc ++#define DDR_PCTL2_PCCFG 0x400 ++#define DDR_PCTL2_PCFGR_n 0x404 ++#define DDR_PCTL2_PCFGW_n 0x408 ++#define DDR_PCTL2_PCTRL_n 0x490 ++ ++/* PCTL2_MRSTAT */ ++#define MR_WR_BUSY BIT(0) ++ ++#define PHY_DDR3_RON_RTT_DISABLE (0) ++#define PHY_DDR3_RON_RTT_451ohm (1) ++#define PHY_DDR3_RON_RTT_225ohm (2) ++#define PHY_DDR3_RON_RTT_150ohm (3) ++#define PHY_DDR3_RON_RTT_112ohm (4) ++#define PHY_DDR3_RON_RTT_90ohm (5) ++#define PHY_DDR3_RON_RTT_75ohm (6) ++#define PHY_DDR3_RON_RTT_64ohm (7) ++#define PHY_DDR3_RON_RTT_56ohm (16) ++#define PHY_DDR3_RON_RTT_50ohm (17) ++#define PHY_DDR3_RON_RTT_45ohm (18) ++#define PHY_DDR3_RON_RTT_41ohm (19) ++#define PHY_DDR3_RON_RTT_37ohm (20) ++#define PHY_DDR3_RON_RTT_34ohm (21) ++#define PHY_DDR3_RON_RTT_33ohm (22) ++#define PHY_DDR3_RON_RTT_30ohm (23) ++#define PHY_DDR3_RON_RTT_28ohm (24) ++#define PHY_DDR3_RON_RTT_26ohm (25) ++#define PHY_DDR3_RON_RTT_25ohm (26) ++#define PHY_DDR3_RON_RTT_23ohm (27) ++#define PHY_DDR3_RON_RTT_22ohm (28) ++#define PHY_DDR3_RON_RTT_21ohm (29) ++#define PHY_DDR3_RON_RTT_20ohm (30) ++#define PHY_DDR3_RON_RTT_19ohm (31) ++ ++#define PHY_DDR4_LPDDR3_RON_RTT_DISABLE (0) ++#define PHY_DDR4_LPDDR3_RON_RTT_480ohm (1) ++#define PHY_DDR4_LPDDR3_RON_RTT_240ohm (2) ++#define PHY_DDR4_LPDDR3_RON_RTT_160ohm (3) ++#define PHY_DDR4_LPDDR3_RON_RTT_120ohm (4) ++#define PHY_DDR4_LPDDR3_RON_RTT_96ohm (5) ++#define PHY_DDR4_LPDDR3_RON_RTT_80ohm (6) ++#define PHY_DDR4_LPDDR3_RON_RTT_68ohm (7) ++#define PHY_DDR4_LPDDR3_RON_RTT_60ohm (16) ++#define PHY_DDR4_LPDDR3_RON_RTT_53ohm (17) ++#define PHY_DDR4_LPDDR3_RON_RTT_48ohm (18) ++#define PHY_DDR4_LPDDR3_RON_RTT_43ohm (19) ++#define PHY_DDR4_LPDDR3_RON_RTT_40ohm (20) ++#define PHY_DDR4_LPDDR3_RON_RTT_37ohm (21) ++#define PHY_DDR4_LPDDR3_RON_RTT_34ohm (22) ++#define PHY_DDR4_LPDDR3_RON_RTT_32ohm (23) ++#define PHY_DDR4_LPDDR3_RON_RTT_30ohm (24) ++#define PHY_DDR4_LPDDR3_RON_RTT_28ohm (25) ++#define PHY_DDR4_LPDDR3_RON_RTT_26ohm (26) ++#define PHY_DDR4_LPDDR3_RON_RTT_25ohm (27) ++#define PHY_DDR4_LPDDR3_RON_RTT_24ohm (28) ++#define PHY_DDR4_LPDDR3_RON_RTT_22ohm (29) ++#define PHY_DDR4_LPDDR3_RON_RTT_21ohm (30) ++#define PHY_DDR4_LPDDR3_RON_RTT_20ohm (31) ++ ++struct ddr_phy_regs { ++ u32 phy[5][2]; ++}; ++ ++#define PHY_REG(base, n) ((base) + 4 * (n)) ++ ++/* PHY_REG0 */ ++#define DIGITAL_DERESET BIT(3) ++#define ANALOG_DERESET BIT(2) ++#define DIGITAL_RESET (0 << 3) ++#define ANALOG_RESET (0 << 2) ++ ++/* PHY_REG1 */ ++#define PHY_DDR2 (0) ++#define PHY_LPDDR2 (1) ++#define PHY_DDR3 (2) ++#define PHY_LPDDR3 (3) ++#define PHY_DDR4 (4) ++#define PHY_BL_4 (0 << 2) ++#define PHY_BL_8 BIT(2) ++ ++/* PHY_REG2 */ ++#define PHY_DTT_EN BIT(0) ++#define PHY_DTT_DISB (0 << 0) ++#define PHY_WRITE_LEVELING_EN BIT(2) ++#define PHY_WRITE_LEVELING_DISB (0 << 2) ++#define PHY_SELECT_CS0 (2) ++#define PHY_SELECT_CS1 (1) ++#define PHY_SELECT_CS0_1 (0) ++#define PHY_WRITE_LEVELING_SELECTCS(n) ((n) << 6) ++#define PHY_DATA_TRAINING_SELECTCS(n) ((n) << 4) ++ ++struct ddr_phy_skew { ++ u32 a0_a1_skew[15]; ++ u32 cs0_dm0_skew[11]; ++ u32 cs0_dm1_skew[11]; ++ u32 cs0_dm2_skew[11]; ++ u32 cs0_dm3_skew[11]; ++ u32 cs1_dm0_skew[11]; ++ u32 cs1_dm1_skew[11]; ++ u32 cs1_dm2_skew[11]; ++ u32 cs1_dm3_skew[11]; ++}; ++ ++#define SR_IDLE 93 ++#define PD_IDLE 13 ++ ++/* PMUGRF */ ++#define PMUGRF_OS_REG0 (0x200) ++#define PMUGRF_OS_REG(n) (PMUGRF_OS_REG0 + (n) * 4) ++ ++/* DDR GRF */ ++#define DDR_GRF_CON(n) (0 + (n) * 4) ++#define DDR_GRF_STATUS_BASE (0X100) ++#define DDR_GRF_STATUS(n) (DDR_GRF_STATUS_BASE + (n) * 4) ++#define DDR_GRF_LP_CON (0x20) ++ ++#define SPLIT_MODE_32_L16_VALID (0) ++#define SPLIT_MODE_32_H16_VALID (1) ++#define SPLIT_MODE_16_L8_VALID (2) ++#define SPLIT_MODE_16_H8_VALID (3) ++ ++#define DDR_GRF_SPLIT_CON (0x8) ++#define SPLIT_MODE_MASK (0x3) ++#define SPLIT_MODE_OFFSET (9) ++#define SPLIT_BYPASS_MASK (1) ++#define SPLIT_BYPASS_OFFSET (8) ++#define SPLIT_SIZE_MASK (0xff) ++#define SPLIT_SIZE_OFFSET (0) ++ ++/* CRU define */ ++/* CRU_PLL_CON0 */ ++#define PB(n) ((0x1 << (15 + 16)) | ((n) << 15)) ++#define POSTDIV1(n) ((0x7 << (12 + 16)) | ((n) << 12)) ++#define FBDIV(n) ((0xFFF << 16) | (n)) ++ ++/* CRU_PLL_CON1 */ ++#define RSTMODE(n) ((0x1 << (15 + 16)) | ((n) << 15)) ++#define RST(n) ((0x1 << (14 + 16)) | ((n) << 14)) ++#define PD(n) ((0x1 << (13 + 16)) | ((n) << 13)) ++#define DSMPD(n) ((0x1 << (12 + 16)) | ((n) << 12)) ++#define LOCK(n) (((n) >> 10) & 0x1) ++#define POSTDIV2(n) ((0x7 << (6 + 16)) | ((n) << 6)) ++#define REFDIV(n) ((0x3F << 16) | (n)) ++ ++/* CRU_MODE */ ++#define CLOCK_FROM_XIN_OSC (0) ++#define CLOCK_FROM_PLL (1) ++#define CLOCK_FROM_RTC_32K (2) ++#define DPLL_MODE(n) ((0x3 << (4 + 16)) | ((n) << 4)) ++ ++/* CRU_SOFTRESET_CON1 */ ++#define upctl2_psrstn_req(n) (((0x1 << 6) << 16) | ((n) << 6)) ++#define upctl2_asrstn_req(n) (((0x1 << 5) << 16) | ((n) << 5)) ++#define upctl2_srstn_req(n) (((0x1 << 4) << 16) | ((n) << 4)) ++ ++/* CRU_SOFTRESET_CON2 */ ++#define ddrphy_psrstn_req(n) (((0x1 << 2) << 16) | ((n) << 2)) ++#define ddrphy_srstn_req(n) (((0x1 << 0) << 16) | ((n) << 0)) ++ ++/* CRU register */ ++#define CRU_PLL_CON(pll_id, n) ((pll_id) * 0x20 + (n) * 4) ++#define CRU_MODE (0xa0) ++#define CRU_GLB_CNT_TH (0xb0) ++#define CRU_CLKSEL_CON_BASE 0x100 ++#define CRU_CLKSELS_CON(i) (CRU_CLKSEL_CON_BASE + ((i) * 4)) ++#define CRU_CLKGATE_CON_BASE 0x200 ++#define CRU_CLKGATE_CON(i) (CRU_CLKGATE_CON_BASE + ((i) * 4)) ++#define CRU_CLKSFTRST_CON_BASE 0x300 ++#define CRU_CLKSFTRST_CON(i) (CRU_CLKSFTRST_CON_BASE + ((i) * 4)) ++ ++struct px30_ddr_grf_regs { ++ u32 ddr_grf_con[4]; ++ u32 reserved1[(0x20 - 0x10) / 4]; ++ u32 ddr_grf_lp_con; ++ u32 reserved2[(0x100 - 0x24) / 4]; ++ u32 ddr_grf_status[11]; ++}; ++ ++struct px30_msch_timings { ++ u32 ddrtiminga0; ++ u32 ddrtimingb0; ++ u32 ddrtimingc0; ++ u32 devtodev0; ++ u32 ddrmode; ++ u32 ddr4timing; ++ u32 agingx0; ++}; ++ ++struct px30_sdram_channel { ++ unsigned int rank; ++ unsigned int col; ++ /* 3:8bank, 2:4bank */ ++ unsigned int bk; ++ /* channel buswidth, 2:32bit, 1:16bit, 0:8bit */ ++ unsigned int bw; ++ /* die buswidth, 2:32bit, 1:16bit, 0:8bit */ ++ unsigned int dbw; ++ unsigned int row_3_4; ++ unsigned int cs0_row; ++ unsigned int cs1_row; ++ unsigned int cs0_high16bit_row; ++ unsigned int cs1_high16bit_row; ++ unsigned int ddrconfig; ++ struct px30_msch_timings noc_timings; ++}; ++ ++struct px30_base_params { ++ unsigned int ddr_freq; ++ unsigned int dramtype; ++ unsigned int num_channels; ++ unsigned int stride; ++ unsigned int odt; ++}; ++ ++struct px30_sdram_params { ++ struct px30_sdram_channel ch; ++ struct px30_base_params base; ++ struct ddr_pctl_regs pctl_regs; ++ struct ddr_phy_regs phy_regs; ++ struct ddr_phy_skew *skew; ++}; ++ ++struct px30_msch_regs { ++ u32 coreid; ++ u32 revisionid; ++ u32 deviceconf; ++ u32 devicesize; ++ u32 ddrtiminga0; ++ u32 ddrtimingb0; ++ u32 ddrtimingc0; ++ u32 devtodev0; ++ u32 reserved1[(0x110 - 0x20) / 4]; ++ u32 ddrmode; ++ u32 ddr4timing; ++ u32 reserved2[(0x1000 - 0x118) / 4]; ++ u32 agingx0; ++ u32 reserved3[(0x1040 - 0x1004) / 4]; ++ u32 aging0; ++ u32 aging1; ++ u32 aging2; ++ u32 aging3; ++}; ++ ++int sdram_init(void); ++ ++#endif +diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig +index f5a80b4f0c..116b40a3c5 100644 +--- a/arch/arm/mach-rockchip/Kconfig ++++ b/arch/arm/mach-rockchip/Kconfig +@@ -1,5 +1,27 @@ + if ARCH_ROCKCHIP + ++config ROCKCHIP_PX30 ++ bool "Support Rockchip PX30" ++ select ARM64 ++ select SUPPORT_SPL ++ select SUPPORT_TPL ++ select SPL ++ select TPL ++ select TPL_TINY_FRAMEWORK if TPL ++ select TPL_NEEDS_SEPARATE_TEXT_BASE if SPL ++ select TPL_NEEDS_SEPARATE_STACK if TPL ++ imply SPL_SEPARATE_BSS ++ select SPL_SERIAL_SUPPORT ++ select TPL_SERIAL_SUPPORT ++ select DEBUG_UART_BOARD_INIT ++ imply ROCKCHIP_COMMON_BOARD ++ imply SPL_ROCKCHIP_COMMON_BOARD ++ help ++ The Rockchip PX30 is a ARM-based SoC with a quad-core Cortex-A35 ++ including NEON and GPU, Mali-400 graphics, several DDR3 options ++ and video codec support. Peripherals include Gigabit Ethernet, ++ USB2 host and OTG, SDIO, I2S, UART, SPI, I2C and PWMs. ++ + config ROCKCHIP_RK3036 + bool "Support Rockchip RK3036" + select CPU_V7A +@@ -315,6 +337,7 @@ config TPL_ROCKCHIP_EARLYRETURN_TO_BROM + config SPL_MMC_SUPPORT + default y if !SPL_ROCKCHIP_BACK_TO_BROM + ++source "arch/arm/mach-rockchip/px30/Kconfig" + source "arch/arm/mach-rockchip/rk3036/Kconfig" + source "arch/arm/mach-rockchip/rk3128/Kconfig" + source "arch/arm/mach-rockchip/rk3188/Kconfig" +diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile +index 45d9b06233..ddff566dee 100644 +--- a/arch/arm/mach-rockchip/Makefile ++++ b/arch/arm/mach-rockchip/Makefile +@@ -11,6 +11,7 @@ obj-spl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o + obj-spl-$(CONFIG_SPL_ROCKCHIP_COMMON_BOARD) += spl.o spl-boot-order.o + obj-tpl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o + obj-tpl-$(CONFIG_TPL_ROCKCHIP_COMMON_BOARD) += tpl.o ++obj-tpl-$(CONFIG_ROCKCHIP_PX30) += px30-board-tpl.o + + obj-spl-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board-spl.o + +@@ -27,6 +28,7 @@ endif + + obj-$(CONFIG_$(SPL_TPL_)RAM) += sdram_common.o + ++obj-$(CONFIG_ROCKCHIP_PX30) += px30/ + obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036/ + obj-$(CONFIG_ROCKCHIP_RK3128) += rk3128/ + obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188/ +diff --git a/arch/arm/mach-rockchip/px30-board-tpl.c b/arch/arm/mach-rockchip/px30-board-tpl.c +new file mode 100644 +index 0000000000..8c8976f61c +--- /dev/null ++++ b/arch/arm/mach-rockchip/px30-board-tpl.c +@@ -0,0 +1,59 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * (C) Copyright 2019 Rockchip Electronics Co., Ltd ++ */ ++ ++#include <common.h> ++#include <debug_uart.h> ++#include <dm.h> ++#include <ram.h> ++#include <spl.h> ++#include <version.h> ++#include <asm/io.h> ++#include <asm/arch-rockchip/bootrom.h> ++#include <asm/arch-rockchip/sdram_px30.h> ++ ++#define TIMER_LOAD_COUNT0 0x00 ++#define TIMER_LOAD_COUNT1 0x04 ++#define TIMER_CUR_VALUE0 0x08 ++#define TIMER_CUR_VALUE1 0x0c ++#define TIMER_CONTROL_REG 0x10 ++ ++#define TIMER_EN 0x1 ++#define TIMER_FMODE (0 << 1) ++#define TIMER_RMODE (1 << 1) ++ ++void secure_timer_init(void) ++{ ++ writel(0, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG); ++ writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_LOAD_COUNT0); ++ writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_LOAD_COUNT1); ++ writel(TIMER_EN | TIMER_FMODE, ++ CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG); ++} ++ ++void board_init_f(ulong dummy) ++{ ++ int ret; ++ ++#ifdef CONFIG_DEBUG_UART ++ debug_uart_init(); ++ /* ++ * Debug UART can be used from here if required: ++ * ++ * debug_uart_init(); ++ * printch('a'); ++ * printhex8(0x1234); ++ * printascii("string"); ++ */ ++ printascii("U-Boot TPL board init\n"); ++#endif ++ ++ secure_timer_init(); ++ ret = sdram_init(); ++ if (ret) ++ printascii("sdram_init failed\n"); ++ ++ /* return to maskrom */ ++ back_to_bootrom(BROM_BOOT_NEXTSTAGE); ++} +diff --git a/arch/arm/mach-rockchip/px30/Kconfig b/arch/arm/mach-rockchip/px30/Kconfig +new file mode 100644 +index 0000000000..ef04afca8d +--- /dev/null ++++ b/arch/arm/mach-rockchip/px30/Kconfig +@@ -0,0 +1,48 @@ ++if ROCKCHIP_PX30 ++ ++config TARGET_EVB_PX30 ++ bool "EVB_PX30" ++ ++config ROCKCHIP_BOOT_MODE_REG ++ default 0xff010200 ++ ++config SYS_SOC ++ default "px30" ++ ++config SYS_MALLOC_F_LEN ++ default 0x400 ++ ++config SPL_SERIAL_SUPPORT ++ default y ++ ++config TPL_LDSCRIPT ++ default "arch/arm/mach-rockchip/u-boot-tpl-v8.lds" ++ ++config TPL_TEXT_BASE ++ default 0xff0e1000 ++ ++config TPL_MAX_SIZE ++ default 10240 ++ ++config TPL_STACK ++ default 0xff0e4fff ++ ++config ROCKCHIP_RK3326 ++ bool "Support Rockchip RK3326 " ++ help ++ RK3326 can use most code from PX30, but at some situations we have ++ to distinguish between RK3326 and PX30, so this macro gives help. ++ It is usually selected in rk3326 board defconfig. ++ ++config DEBUG_UART2_CHANNEL ++ int "Mux channel to use for debug UART2" ++ depends on DEBUG_UART_BOARD_INIT ++ default 0 ++ help ++ UART2 can use two different set of pins to route the output. ++ For using the UART for early debugging the route to use needs ++ to be declared (0 or 1). ++ ++source "board/rockchip/evb_px30/Kconfig" ++ ++endif +diff --git a/arch/arm/mach-rockchip/px30/Makefile b/arch/arm/mach-rockchip/px30/Makefile +new file mode 100644 +index 0000000000..6d0742bcab +--- /dev/null ++++ b/arch/arm/mach-rockchip/px30/Makefile +@@ -0,0 +1,14 @@ ++# ++# (C) Copyright 2017 Rockchip Electronics Co., Ltd. ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++obj-y += clk_px30.o ++ ++ifndef CONFIG_TPL_BUILD ++obj-y += syscon_px30.o ++endif ++ ++obj-y += px30.o ++obj-y += sdram_px30.o +diff --git a/arch/arm/mach-rockchip/px30/clk_px30.c b/arch/arm/mach-rockchip/px30/clk_px30.c +new file mode 100644 +index 0000000000..0bd6b471da +--- /dev/null ++++ b/arch/arm/mach-rockchip/px30/clk_px30.c +@@ -0,0 +1,31 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * (C) Copyright 2017 Rockchip Electronics Co., Ltd. ++ */ ++ ++#include <common.h> ++#include <dm.h> ++#include <syscon.h> ++#include <asm/arch-rockchip/clock.h> ++#include <asm/arch-rockchip/cru_px30.h> ++ ++int rockchip_get_clk(struct udevice **devp) ++{ ++ return uclass_get_device_by_driver(UCLASS_CLK, ++ DM_GET_DRIVER(rockchip_px30_cru), devp); ++} ++ ++void *rockchip_get_cru(void) ++{ ++ struct px30_clk_priv *priv; ++ struct udevice *dev; ++ int ret; ++ ++ ret = rockchip_get_clk(&dev); ++ if (ret) ++ return ERR_PTR(ret); ++ ++ priv = dev_get_priv(dev); ++ ++ return priv->cru; ++} +diff --git a/arch/arm/mach-rockchip/px30/px30.c b/arch/arm/mach-rockchip/px30/px30.c +new file mode 100644 +index 0000000000..7cd2292fe2 +--- /dev/null ++++ b/arch/arm/mach-rockchip/px30/px30.c +@@ -0,0 +1,248 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2017 Rockchip Electronics Co., Ltd ++ */ ++#include <common.h> ++#include <clk.h> ++#include <dm.h> ++#include <asm/armv8/mmu.h> ++#include <asm/io.h> ++#include <asm/arch-rockchip/grf_px30.h> ++#include <asm/arch-rockchip/hardware.h> ++#include <asm/arch-rockchip/uart.h> ++#include <asm/arch-rockchip/clock.h> ++#include <asm/arch-rockchip/cru_px30.h> ++#include <dt-bindings/clock/px30-cru.h> ++ ++static struct mm_region px30_mem_map[] = { ++ { ++ .virt = 0x0UL, ++ .phys = 0x0UL, ++ .size = 0xff000000UL, ++ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | ++ PTE_BLOCK_INNER_SHARE ++ }, { ++ .virt = 0xff000000UL, ++ .phys = 0xff000000UL, ++ .size = 0x01000000UL, ++ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | ++ PTE_BLOCK_NON_SHARE | ++ PTE_BLOCK_PXN | PTE_BLOCK_UXN ++ }, { ++ /* List terminator */ ++ 0, ++ } ++}; ++ ++struct mm_region *mem_map = px30_mem_map; ++ ++#define PMU_PWRDN_CON 0xff000018 ++#define GRF_BASE 0xff140000 ++#define CRU_BASE 0xff2b0000 ++#define VIDEO_PHY_BASE 0xff2e0000 ++#define SERVICE_CORE_ADDR 0xff508000 ++#define DDR_FW_BASE 0xff534000 ++ ++#define FW_DDR_CON 0x40 ++ ++#define QOS_PRIORITY 0x08 ++ ++#define QOS_PRIORITY_LEVEL(h, l) ((((h) & 3) << 8) | ((l) & 3)) ++ ++/* GRF_GPIO1CL_IOMUX */ ++enum { ++ GPIO1C1_SHIFT = 4, ++ GPIO1C1_MASK = 0xf << GPIO1C1_SHIFT, ++ GPIO1C1_GPIO = 0, ++ GPIO1C1_UART1_TX, ++ ++ GPIO1C0_SHIFT = 0, ++ GPIO1C0_MASK = 0xf << GPIO1C0_SHIFT, ++ GPIO1C0_GPIO = 0, ++ GPIO1C0_UART1_RX, ++}; ++ ++/* GRF_GPIO1DL_IOMUX */ ++enum { ++ GPIO1D3_SHIFT = 12, ++ GPIO1D3_MASK = 0xf << GPIO1D3_SHIFT, ++ GPIO1D3_GPIO = 0, ++ GPIO1D3_SDMMC_D1, ++ GPIO1D3_UART2_RXM0, ++ ++ GPIO1D2_SHIFT = 8, ++ GPIO1D2_MASK = 0xf << GPIO1D2_SHIFT, ++ GPIO1D2_GPIO = 0, ++ GPIO1D2_SDMMC_D0, ++ GPIO1D2_UART2_TXM0, ++}; ++ ++/* GRF_GPIO1DH_IOMUX */ ++enum { ++ GPIO1D7_SHIFT = 12, ++ GPIO1D7_MASK = 0xf << GPIO1D7_SHIFT, ++ GPIO1D7_GPIO = 0, ++ GPIO1D7_SDMMC_CMD, ++ ++ GPIO1D6_SHIFT = 8, ++ GPIO1D6_MASK = 0xf << GPIO1D6_SHIFT, ++ GPIO1D6_GPIO = 0, ++ GPIO1D6_SDMMC_CLK, ++ ++ GPIO1D5_SHIFT = 4, ++ GPIO1D5_MASK = 0xf << GPIO1D5_SHIFT, ++ GPIO1D5_GPIO = 0, ++ GPIO1D5_SDMMC_D3, ++ ++ GPIO1D4_SHIFT = 0, ++ GPIO1D4_MASK = 0xf << GPIO1D4_SHIFT, ++ GPIO1D4_GPIO = 0, ++ GPIO1D4_SDMMC_D2, ++}; ++ ++/* GRF_GPIO2BH_IOMUX */ ++enum { ++ GPIO2B6_SHIFT = 8, ++ GPIO2B6_MASK = 0xf << GPIO2B6_SHIFT, ++ GPIO2B6_GPIO = 0, ++ GPIO2B6_CIF_D1M0, ++ GPIO2B6_UART2_RXM1, ++ ++ GPIO2B4_SHIFT = 0, ++ GPIO2B4_MASK = 0xf << GPIO2B4_SHIFT, ++ GPIO2B4_GPIO = 0, ++ GPIO2B4_CIF_D0M0, ++ GPIO2B4_UART2_TXM1, ++}; ++ ++/* GRF_GPIO3AL_IOMUX */ ++enum { ++ GPIO3A2_SHIFT = 8, ++ GPIO3A2_MASK = 0xf << GPIO3A2_SHIFT, ++ GPIO3A2_GPIO = 0, ++ GPIO3A2_UART5_TX = 4, ++ ++ GPIO3A1_SHIFT = 4, ++ GPIO3A1_MASK = 0xf << GPIO3A1_SHIFT, ++ GPIO3A1_GPIO = 0, ++ GPIO3A1_UART5_RX = 4, ++}; ++ ++int arch_cpu_init(void) ++{ ++ static struct px30_grf * const grf = (void *)GRF_BASE; ++ u32 __maybe_unused val; ++ ++#ifdef CONFIG_SPL_BUILD ++ /* We do some SoC one time setting here. */ ++ /* Disable the ddr secure region setting to make it non-secure */ ++ writel(0x0, DDR_FW_BASE + FW_DDR_CON); ++ ++ /* Set cpu qos priority */ ++ writel(QOS_PRIORITY_LEVEL(1, 1), SERVICE_CORE_ADDR + QOS_PRIORITY); ++ ++#if !defined(CONFIG_DEBUG_UART_BOARD_INIT) || \ ++ (CONFIG_DEBUG_UART_BASE != 0xff160000) || \ ++ (CONFIG_DEBUG_UART_CHANNEL != 0) ++ /* fix sdmmc pinmux if not using uart2-channel0 as debug uart */ ++ rk_clrsetreg(&grf->gpio1dl_iomux, ++ GPIO1D3_MASK | GPIO1D2_MASK, ++ GPIO1D3_SDMMC_D1 << GPIO1D3_SHIFT | ++ GPIO1D2_SDMMC_D0 << GPIO1D2_SHIFT); ++ rk_clrsetreg(&grf->gpio1dh_iomux, ++ GPIO1D7_MASK | GPIO1D6_MASK | GPIO1D5_MASK | GPIO1D4_MASK, ++ GPIO1D7_SDMMC_CMD << GPIO1D7_SHIFT | ++ GPIO1D6_SDMMC_CLK << GPIO1D6_SHIFT | ++ GPIO1D5_SDMMC_D3 << GPIO1D5_SHIFT | ++ GPIO1D4_SDMMC_D2 << GPIO1D4_SHIFT); ++#endif ++ ++#endif ++ ++ /* Enable PD_VO (default disable at reset) */ ++ rk_clrreg(PMU_PWRDN_CON, 1 << 13); ++ ++ /* Disable video phy bandgap by default */ ++ writel(0x82, VIDEO_PHY_BASE + 0x0000); ++ writel(0x05, VIDEO_PHY_BASE + 0x03ac); ++ ++ /* Clear the force_jtag */ ++ rk_clrreg(&grf->cpu_con[1], 1 << 7); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_DEBUG_UART_BOARD_INIT ++void board_debug_uart_init(void) ++{ ++ static struct px30_grf * const grf = (void *)GRF_BASE; ++ static struct px30_cru * const cru = (void *)CRU_BASE; ++ ++#if defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xff158000) ++ /* uart_sel_clk default select 24MHz */ ++ rk_clrsetreg(&cru->clksel_con[34], ++ UART1_PLL_SEL_MASK | UART1_DIV_CON_MASK, ++ UART1_PLL_SEL_24M << UART1_PLL_SEL_SHIFT | 0); ++ rk_clrsetreg(&cru->clksel_con[35], ++ UART1_CLK_SEL_MASK, ++ UART1_CLK_SEL_UART1 << UART1_CLK_SEL_SHIFT); ++ ++ rk_clrsetreg(&grf->gpio1cl_iomux, ++ GPIO1C1_MASK | GPIO1C0_MASK, ++ GPIO1C1_UART1_TX << GPIO1C1_SHIFT | ++ GPIO1C0_UART1_RX << GPIO1C0_SHIFT); ++#elif defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xff178000) ++ /* uart_sel_clk default select 24MHz */ ++ rk_clrsetreg(&cru->clksel_con[46], ++ UART5_PLL_SEL_MASK | UART5_DIV_CON_MASK, ++ UART5_PLL_SEL_24M << UART5_PLL_SEL_SHIFT | 0); ++ rk_clrsetreg(&cru->clksel_con[47], ++ UART5_CLK_SEL_MASK, ++ UART5_CLK_SEL_UART5 << UART5_CLK_SEL_SHIFT); ++ ++ rk_clrsetreg(&grf->gpio3al_iomux, ++ GPIO3A2_MASK | GPIO3A1_MASK, ++ GPIO3A2_UART5_TX << GPIO3A2_SHIFT | ++ GPIO3A1_UART5_RX << GPIO3A1_SHIFT); ++#else ++ /* GRF_IOFUNC_CON0 */ ++ enum { ++ CON_IOMUX_UART2SEL_SHIFT = 10, ++ CON_IOMUX_UART2SEL_MASK = 3 << CON_IOMUX_UART2SEL_SHIFT, ++ CON_IOMUX_UART2SEL_M0 = 0, ++ CON_IOMUX_UART2SEL_M1, ++ CON_IOMUX_UART2SEL_USBPHY, ++ }; ++ ++ /* uart_sel_clk default select 24MHz */ ++ rk_clrsetreg(&cru->clksel_con[37], ++ UART2_PLL_SEL_MASK | UART2_DIV_CON_MASK, ++ UART2_PLL_SEL_24M << UART2_PLL_SEL_SHIFT | 0); ++ rk_clrsetreg(&cru->clksel_con[38], ++ UART2_CLK_SEL_MASK, ++ UART2_CLK_SEL_UART2 << UART2_CLK_SEL_SHIFT); ++ ++#if (CONFIG_DEBUG_UART2_CHANNEL == 1) ++ /* Enable early UART2 */ ++ rk_clrsetreg(&grf->iofunc_con0, ++ CON_IOMUX_UART2SEL_MASK, ++ CON_IOMUX_UART2SEL_M1 << CON_IOMUX_UART2SEL_SHIFT); ++ ++ rk_clrsetreg(&grf->gpio2bh_iomux, ++ GPIO2B6_MASK | GPIO2B4_MASK, ++ GPIO2B6_UART2_RXM1 << GPIO2B6_SHIFT | ++ GPIO2B4_UART2_TXM1 << GPIO2B4_SHIFT); ++#else ++ rk_clrsetreg(&grf->iofunc_con0, ++ CON_IOMUX_UART2SEL_MASK, ++ CON_IOMUX_UART2SEL_M0 << CON_IOMUX_UART2SEL_SHIFT); ++ ++ rk_clrsetreg(&grf->gpio1dl_iomux, ++ GPIO1D3_MASK | GPIO1D2_MASK, ++ GPIO1D3_UART2_RXM0 << GPIO1D3_SHIFT | ++ GPIO1D2_UART2_TXM0 << GPIO1D2_SHIFT); ++#endif /* CONFIG_DEBUG_UART2_CHANNEL == 1 */ ++ ++#endif /* CONFIG_DEBUG_UART_BASE && CONFIG_DEBUG_UART_BASE == ... */ ++} ++#endif /* CONFIG_DEBUG_UART_BOARD_INIT */ +diff --git a/arch/arm/mach-rockchip/px30/sdram-px30-ddr3-detect-333.inc b/arch/arm/mach-rockchip/px30/sdram-px30-ddr3-detect-333.inc +new file mode 100644 +index 0000000000..e17b2ed86c +--- /dev/null ++++ b/arch/arm/mach-rockchip/px30/sdram-px30-ddr3-detect-333.inc +@@ -0,0 +1,70 @@ ++{ ++ { ++ .rank = 0x1, ++ .col = 0xC, ++ .bk = 0x3, ++ .bw = 0x1, ++ .dbw = 0x0, ++ .row_3_4 = 0x0, ++ .cs0_row = 0x10, ++ .cs1_row = 0x10, ++ .cs0_high16bit_row = 0x10, ++ .cs1_high16bit_row = 0x10, ++ .ddrconfig = 0, ++ { ++ 0x290b0609, ++ 0x08020401, ++ 0x00000002, ++ 0x00001111, ++ 0x0000000c, ++ 0x00000222, ++ 0x000000ff ++ } ++ }, ++ { ++ .ddr_freq = 333, ++ .dramtype = DDR3, ++ .num_channels = 1, ++ .stride = 0, ++ .odt = 0, ++ }, ++ { ++ { ++ {0x00000000, 0x43041001}, /* MSTR */ ++ {0x00000064, 0x0028003b}, /* RFSHTMG */ ++ {0x000000d0, 0x00020053}, /* INIT0 */ ++ {0x000000d4, 0x00020000}, /* INIT1 */ ++ {0x000000d8, 0x00000100}, /* INIT2 */ ++ {0x000000dc, 0x03200000}, /* INIT3 */ ++ {0x000000e0, 0x00000000}, /* INIT4 */ ++ {0x000000e4, 0x00090000}, /* INIT5 */ ++ {0x000000f4, 0x000f012f}, /* RANKCTL */ ++ {0x00000100, 0x07090b06}, /* DRAMTMG0 */ ++ {0x00000104, 0x00050209}, /* DRAMTMG1 */ ++ {0x00000108, 0x03030407}, /* DRAMTMG2 */ ++ {0x0000010c, 0x00202006}, /* DRAMTMG3 */ ++ {0x00000110, 0x03020204}, /* DRAMTMG4 */ ++ {0x00000114, 0x03030202}, /* DRAMTMG5 */ ++ {0x00000120, 0x00000903}, /* DRAMTMG8 */ ++ {0x00000180, 0x00800020}, /* ZQCTL0 */ ++ {0x00000184, 0x00000000}, /* ZQCTL1 */ ++ {0x00000190, 0x07010001}, /* DFITMG0 */ ++ {0x00000198, 0x07000101}, /* DFILPCFG0 */ ++ {0x000001a0, 0xc0400003}, /* DFIUPD0 */ ++ {0x00000240, 0x06000604}, /* ODTCFG */ ++ {0x00000244, 0x00000201}, /* ODTMAP */ ++ {0x00000250, 0x00001f00}, /* SCHED */ ++ {0x00000490, 0x00000001}, /* PCTRL_0 */ ++ {0xffffffff, 0xffffffff} ++ } ++ }, ++ { ++ { ++ {0x00000004, 0x0000000a}, /* PHYREG01 */ ++ {0x00000028, 0x00000006}, /* PHYREG0A */ ++ {0x0000002c, 0x00000000}, /* PHYREG0B */ ++ {0x00000030, 0x00000005}, /* PHYREG0C */ ++ {0xffffffff, 0xffffffff} ++ } ++ } ++}, +diff --git a/arch/arm/mach-rockchip/px30/sdram-px30-ddr4-detect-333.inc b/arch/arm/mach-rockchip/px30/sdram-px30-ddr4-detect-333.inc +new file mode 100644 +index 0000000000..cdc417405a +--- /dev/null ++++ b/arch/arm/mach-rockchip/px30/sdram-px30-ddr4-detect-333.inc +@@ -0,0 +1,73 @@ ++{ ++ { ++ .rank = 0x1, ++ .col = 0xA, ++ .bk = 0x2, ++ .bw = 0x1, ++ .dbw = 0x0, ++ .row_3_4 = 0x0, ++ .cs0_row = 0x11, ++ .cs1_row = 0x0, ++ .cs0_high16bit_row = 0x11, ++ .cs1_high16bit_row = 0x0, ++ .ddrconfig = 0, ++ { ++ 0x4d110a08, ++ 0x06020501, ++ 0x00000002, ++ 0x00001111, ++ 0x0000000c, ++ 0x0000022a, ++ 0x000000ff ++ } ++ }, ++ { ++ .ddr_freq = 333, ++ .dramtype = DDR4, ++ .num_channels = 1, ++ .stride = 0, ++ .odt = 0, ++ }, ++ { ++ { ++ {0x00000000, 0x43049010}, /* MSTR */ ++ {0x00000064, 0x0028003b}, /* RFSHTMG */ ++ {0x000000d0, 0x00020053}, /* INIT0 */ ++ {0x000000d4, 0x00220000}, /* INIT1 */ ++ {0x000000d8, 0x00000100}, /* INIT2 */ ++ {0x000000dc, 0x00040000}, /* INIT3 */ ++ {0x000000e0, 0x00000000}, /* INIT4 */ ++ {0x000000e4, 0x00110000}, /* INIT5 */ ++ {0x000000e8, 0x00000420}, /* INIT6 */ ++ {0x000000ec, 0x00000400}, /* INIT7 */ ++ {0x000000f4, 0x000f012f}, /* RANKCTL */ ++ {0x00000100, 0x09060b06}, /* DRAMTMG0 */ ++ {0x00000104, 0x00020209}, /* DRAMTMG1 */ ++ {0x00000108, 0x0505040a}, /* DRAMTMG2 */ ++ {0x0000010c, 0x0040400c}, /* DRAMTMG3 */ ++ {0x00000110, 0x05030206}, /* DRAMTMG4 */ ++ {0x00000114, 0x03030202}, /* DRAMTMG5 */ ++ {0x00000120, 0x03030b03}, /* DRAMTMG8 */ ++ {0x00000124, 0x00020208}, /* DRAMTMG9 */ ++ {0x00000180, 0x01000040}, /* ZQCTL0 */ ++ {0x00000184, 0x00000000}, /* ZQCTL1 */ ++ {0x00000190, 0x07030003}, /* DFITMG0 */ ++ {0x00000198, 0x07000101}, /* DFILPCFG0 */ ++ {0x000001a0, 0xc0400003}, /* DFIUPD0 */ ++ {0x00000240, 0x06000604}, /* ODTCFG */ ++ {0x00000244, 0x00000201}, /* ODTMAP */ ++ {0x00000250, 0x00001f00}, /* SCHED */ ++ {0x00000490, 0x00000001}, /* PCTRL_0 */ ++ {0xffffffff, 0xffffffff} ++ } ++ }, ++ { ++ { ++ {0x00000004, 0x0000000c}, /* PHYREG01 */ ++ {0x00000028, 0x0000000a}, /* PHYREG0A */ ++ {0x0000002c, 0x00000000}, /* PHYREG0B */ ++ {0x00000030, 0x00000009}, /* PHYREG0C */ ++ {0xffffffff, 0xffffffff} ++ } ++ } ++}, +\ No newline at end of file +diff --git a/arch/arm/mach-rockchip/px30/sdram-px30-ddr_skew.inc b/arch/arm/mach-rockchip/px30/sdram-px30-ddr_skew.inc +new file mode 100644 +index 0000000000..f24343dda1 +--- /dev/null ++++ b/arch/arm/mach-rockchip/px30/sdram-px30-ddr_skew.inc +@@ -0,0 +1,121 @@ ++ { ++ 0x77, ++ 0x88, ++ 0x79, ++ 0x79, ++ 0x87, ++ 0x97, ++ 0x87, ++ 0x78, ++ 0x77, ++ 0x78, ++ 0x87, ++ 0x88, ++ 0x87, ++ 0x87, ++ 0x77 ++ }, ++ { ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x69, ++ 0x9, ++ }, ++ { ++ 0x77, ++ 0x78, ++ 0x77, ++ 0x78, ++ 0x77, ++ 0x78, ++ 0x77, ++ 0x78, ++ 0x77, ++ 0x79, ++ 0x9, ++ }, ++ { ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x69, ++ 0x9, ++ }, ++ { ++ 0x77, ++ 0x78, ++ 0x77, ++ 0x77, ++ 0x77, ++ 0x77, ++ 0x77, ++ 0x77, ++ 0x77, ++ 0x79, ++ 0x9, ++ }, ++ { ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x69, ++ 0x9, ++ }, ++ { ++ 0x77, ++ 0x78, ++ 0x77, ++ 0x78, ++ 0x77, ++ 0x78, ++ 0x77, ++ 0x78, ++ 0x77, ++ 0x79, ++ 0x9, ++ }, ++ { ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x78, ++ 0x69, ++ 0x9, ++ }, ++ { ++ 0x77, ++ 0x78, ++ 0x77, ++ 0x77, ++ 0x77, ++ 0x77, ++ 0x77, ++ 0x77, ++ 0x77, ++ 0x79, ++ 0x9, ++ } +diff --git a/arch/arm/mach-rockchip/px30/sdram-px30-lpddr2-detect-333.inc b/arch/arm/mach-rockchip/px30/sdram-px30-lpddr2-detect-333.inc +new file mode 100644 +index 0000000000..3bde062d62 +--- /dev/null ++++ b/arch/arm/mach-rockchip/px30/sdram-px30-lpddr2-detect-333.inc +@@ -0,0 +1,71 @@ ++{ ++ { ++ .rank = 0x1, ++ .col = 0xC, ++ .bk = 0x3, ++ .bw = 0x1, ++ .dbw = 0x0, ++ .row_3_4 = 0x0, ++ .cs0_row = 0xF, ++ .cs1_row = 0xF, ++ .cs0_high16bit_row = 0xF, ++ .cs1_high16bit_row = 0xF, ++ .ddrconfig = 0, ++ { ++ 0x2b0c070a, ++ 0x08020303, ++ 0x00000002, ++ 0x00001111, ++ 0x0000000c, ++ 0x00000219, ++ 0x000000ff ++ } ++ }, ++ { ++ .ddr_freq = 333, ++ .dramtype = LPDDR2, ++ .num_channels = 1, ++ .stride = 0, ++ .odt = 0, ++ }, ++ { ++ { ++ {0x00000000, 0x41041004}, /* MSTR */ ++ {0x00000064, 0x00140023}, /* RFSHTMG */ ++ {0x000000d0, 0x00220002}, /* INIT0 */ ++ {0x000000d4, 0x00010000}, /* INIT1 */ ++ {0x000000d8, 0x00000703}, /* INIT2 */ ++ {0x000000dc, 0x00630005}, /* INIT3 */ ++ {0x000000e0, 0x00010000}, /* INIT4 */ ++ {0x000000e4, 0x00070003}, /* INIT5 */ ++ {0x000000f4, 0x000f012f}, /* RANKCTL */ ++ {0x00000100, 0x07090b07}, /* DRAMTMG0 */ ++ {0x00000104, 0x0002010b}, /* DRAMTMG1 */ ++ {0x00000108, 0x02040506}, /* DRAMTMG2 */ ++ {0x0000010c, 0x00303000}, /* DRAMTMG3 */ ++ {0x00000110, 0x04010204}, /* DRAMTMG4 */ ++ {0x00000114, 0x01010303}, /* DRAMTMG5 */ ++ {0x00000118, 0x02020003}, /* DRAMTMG6 */ ++ {0x00000120, 0x00000303}, /* DRAMTMG8 */ ++ {0x00000138, 0x00000025}, /* DRAMTMG14 */ ++ {0x00000180, 0x003c000f}, /* ZQCTL0 */ ++ {0x00000184, 0x00900000}, /* ZQCTL1 */ ++ {0x00000190, 0x07020001}, /* DFITMG0 */ ++ {0x00000198, 0x07000101}, /* DFILPCFG0 */ ++ {0x000001a0, 0xc0400003}, /* DFIUPD0 */ ++ {0x00000240, 0x07030718}, /* ODTCFG */ ++ {0x00000250, 0x00001f00}, /* SCHED */ ++ {0x00000490, 0x00000001}, /* PCTRL_0 */ ++ {0xffffffff, 0xffffffff} ++ } ++ }, ++ { ++ { ++ {0x00000004, 0x00000009}, /* PHYREG01 */ ++ {0x00000028, 0x00000007}, /* PHYREG0A */ ++ {0x0000002c, 0x00000000}, /* PHYREG0B */ ++ {0x00000030, 0x00000004}, /* PHYREG0C */ ++ {0xffffffff, 0xffffffff} ++ } ++ } ++}, +diff --git a/arch/arm/mach-rockchip/px30/sdram-px30-lpddr3-detect-333.inc b/arch/arm/mach-rockchip/px30/sdram-px30-lpddr3-detect-333.inc +new file mode 100644 +index 0000000000..a205fc9332 +--- /dev/null ++++ b/arch/arm/mach-rockchip/px30/sdram-px30-lpddr3-detect-333.inc +@@ -0,0 +1,72 @@ ++{ ++ { ++ .rank = 0x1, ++ .col = 0xC, ++ .bk = 0x3, ++ .bw = 0x1, ++ .dbw = 0x0, ++ .row_3_4 = 0x0, ++ .cs0_row = 0x10, ++ .cs1_row = 0x10, ++ .cs0_high16bit_row = 0x10, ++ .cs1_high16bit_row = 0x10, ++ .ddrconfig = 0, ++ { ++ 0x290a060a, ++ 0x08020303, ++ 0x00000002, ++ 0x00001111, ++ 0x0000000c, ++ 0x0000021a, ++ 0x000000ff ++ } ++ }, ++ { ++ .ddr_freq = 333, ++ .dramtype = LPDDR3, ++ .num_channels = 1, ++ .stride = 0, ++ .odt = 0, ++ }, ++ { ++ { ++ {0x00000000, 0x43041008}, /* MSTR */ ++ {0x00000064, 0x00140023}, /* RFSHTMG */ ++ {0x000000d0, 0x00220002}, /* INIT0 */ ++ {0x000000d4, 0x00010000}, /* INIT1 */ ++ {0x000000d8, 0x00000703}, /* INIT2 */ ++ {0x000000dc, 0x00830004}, /* INIT3 */ ++ {0x000000e0, 0x00010000}, /* INIT4 */ ++ {0x000000e4, 0x00070003}, /* INIT5 */ ++ {0x000000f4, 0x000f012f}, /* RANKCTL */ ++ {0x00000100, 0x06090b07}, /* DRAMTMG0 */ ++ {0x00000104, 0x0002020b}, /* DRAMTMG1 */ ++ {0x00000108, 0x02030506}, /* DRAMTMG2 */ ++ {0x0000010c, 0x00505000}, /* DRAMTMG3 */ ++ {0x00000110, 0x03020204}, /* DRAMTMG4 */ ++ {0x00000114, 0x01010303}, /* DRAMTMG5 */ ++ {0x00000118, 0x02020003}, /* DRAMTMG6 */ ++ {0x00000120, 0x00000303}, /* DRAMTMG8 */ ++ {0x00000138, 0x00000025}, /* DRAMTMG14 */ ++ {0x00000180, 0x003c000f}, /* ZQCTL0 */ ++ {0x00000184, 0x00900000}, /* ZQCTL1 */ ++ {0x00000190, 0x07020000}, /* DFITMG0 */ ++ {0x00000198, 0x07000101}, /* DFILPCFG0 */ ++ {0x000001a0, 0xc0400003}, /* DFIUPD0 */ ++ {0x00000240, 0x0900090c}, /* ODTCFG */ ++ {0x00000244, 0x00000101}, /* ODTMAP */ ++ {0x00000250, 0x00001f00}, /* SCHED */ ++ {0x00000490, 0x00000001}, /* PCTRL_0 */ ++ {0xffffffff, 0xffffffff} ++ } ++ }, ++ { ++ { ++ {0x00000004, 0x0000000b}, /* PHYREG01 */ ++ {0x00000028, 0x00000006}, /* PHYREG0A */ ++ {0x0000002c, 0x00000000}, /* PHYREG0B */ ++ {0x00000030, 0x00000003}, /* PHYREG0C */ ++ {0xffffffff, 0xffffffff} ++ } ++ } ++}, +diff --git a/arch/arm/mach-rockchip/px30/sdram_px30.c b/arch/arm/mach-rockchip/px30/sdram_px30.c +new file mode 100644 +index 0000000000..2590d9366e +--- /dev/null ++++ b/arch/arm/mach-rockchip/px30/sdram_px30.c +@@ -0,0 +1,1405 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * (C) Copyright 2018 Rockchip Electronics Co., Ltd. ++ */ ++ ++#include <common.h> ++#include <debug_uart.h> ++#include <dm.h> ++#include <ram.h> ++#include <syscon.h> ++#include <asm/io.h> ++#include <asm/arch-rockchip/clock.h> ++#include <asm/arch-rockchip/cru_px30.h> ++#include <asm/arch-rockchip/grf_px30.h> ++#include <asm/arch-rockchip/hardware.h> ++#include <asm/arch-rockchip/sdram_common.h> ++#include <asm/arch-rockchip/sdram_px30.h> ++ ++#define TIMER_CUR_VALUE0 0x08 ++#define TIMER_CUR_VALUE1 0x0c ++ ++static u64 rockchip_get_ticks(void) ++{ ++ u64 timebase_h, timebase_l; ++ ++ timebase_l = readl(CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CUR_VALUE0); ++ timebase_h = readl(CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CUR_VALUE1); ++ ++ return timebase_h << 32 | timebase_l; ++} ++ ++void rockchip_udelay(unsigned int usec) ++{ ++ u64 tmp; ++ ++ /* get timestamp */ ++ tmp = rockchip_get_ticks() + usec_to_tick(usec); ++ ++ /* loop till event */ ++ while (rockchip_get_ticks() < tmp + 1) ++ ; ++} ++ ++u8 ddr_cfg_2_rbc[] = { ++ /* ++ * [6:4] max row: 13+n ++ * [3] bank(0:4bank,1:8bank) ++ * [2:0] col(10+n) ++ */ ++ ((5 << 4) | (1 << 3) | 0), /* 0 */ ++ ((5 << 4) | (1 << 3) | 1), /* 1 */ ++ ((4 << 4) | (1 << 3) | 2), /* 2 */ ++ ((3 << 4) | (1 << 3) | 3), /* 3 */ ++ ((2 << 4) | (1 << 3) | 4), /* 4 */ ++ ((5 << 4) | (0 << 3) | 2), /* 5 */ ++ ((4 << 4) | (1 << 3) | 2), /* 6 */ ++}; ++ ++#ifdef CONFIG_TPL_BUILD ++ ++/* ++ * for ddr4 if ddrconfig=7, upctl should set 7 and noc should ++ * set to 1 for more efficient. ++ * noc ddrconf, upctl addrmap ++ * 1 7 ++ * 2 8 ++ * 3 9 ++ * 12 10 ++ * 5 11 ++ */ ++static u8 d4_rbc_2_d3_rbc[] = { ++ 1, /* 7 */ ++ 2, /* 8 */ ++ 3, /* 9 */ ++ 12, /* 10 */ ++ 5, /* 11 */ ++}; ++ ++/* ++ * row higher than cs should be disabled by set to 0xf ++ * rank addrmap calculate by real cap. ++ */ ++static u32 addrmap[][8] = { ++ /* map0 map1, map2, map3, map4, map5 ++ * map6, map7, map8 ++ * ------------------------------------------------------- ++ * bk2-0 col 5-2 col 9-6 col 11-10 row 11-0 ++ * row 15-12 row 17-16 bg1,0 ++ * ------------------------------------------------------- ++ * 4,3,2 5-2 9-6 6 ++ * 3,2 ++ */ ++ {0x00060606, 0x00000000, 0x1f1f0000, 0x00001f1f, 0x05050505, ++ 0x05050505, 0x00000505, 0x3f3f}, /* 0 */ ++ {0x00070707, 0x00000000, 0x1f000000, 0x00001f1f, 0x06060606, ++ 0x06060606, 0x06060606, 0x3f3f}, /* 1 */ ++ {0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707, ++ 0x07070707, 0x00000f07, 0x3f3f}, /* 2 */ ++ {0x00090909, 0x00000000, 0x00000000, 0x00001f00, 0x08080808, ++ 0x08080808, 0x00000f0f, 0x3f3f}, /* 3 */ ++ {0x000a0a0a, 0x00000000, 0x00000000, 0x00000000, 0x09090909, ++ 0x0f090909, 0x00000f0f, 0x3f3f}, /* 4 */ ++ {0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x06060606, ++ 0x06060606, 0x00000606, 0x3f3f}, /* 5 */ ++ {0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707, ++ 0x07070707, 0x00000f0f, 0x3f3f}, /* 6 */ ++ {0x003f0808, 0x00000006, 0x1f1f0000, 0x00001f1f, 0x06060606, ++ 0x06060606, 0x00000606, 0x0600}, /* 7 */ ++ {0x003f0909, 0x00000007, 0x1f000000, 0x00001f1f, 0x07070707, ++ 0x07070707, 0x00000f07, 0x0700}, /* 8 */ ++ {0x003f0a0a, 0x01010100, 0x01010101, 0x00001f1f, 0x08080808, ++ 0x08080808, 0x00000f0f, 0x0801}, /* 9 */ ++ {0x003f0909, 0x01010100, 0x01010101, 0x00001f1f, 0x07070707, ++ 0x07070707, 0x00000f07, 0x3f01}, /* 10 */ ++ {0x003f0808, 0x00000007, 0x1f000000, 0x00001f1f, 0x06060606, ++ 0x06060606, 0x00000606, 0x3f00}, /* 11 */ ++ /* when ddr4 12 map to 10, when ddr3 12 unused */ ++ {0x003f0909, 0x01010100, 0x01010101, 0x00001f1f, 0x07070707, ++ 0x07070707, 0x00000f07, 0x3f01}, /* 10 */ ++ {0x00070706, 0x00000000, 0x1f010000, 0x00001f1f, 0x06060606, ++ 0x06060606, 0x00000606, 0x3f3f}, /* 13 */ ++}; ++ ++DECLARE_GLOBAL_DATA_PTR; ++struct dram_info { ++ struct ddr_pctl_regs *pctl; ++ struct ddr_phy_regs *phy; ++ struct px30_cru *cru; ++ struct px30_msch_regs *msch; ++ struct px30_ddr_grf_regs *ddr_grf; ++ struct px30_grf *grf; ++ struct ram_info info; ++ struct px30_pmugrf *pmugrf; ++}; ++ ++#define PMUGRF_BASE_ADDR 0xFF010000 ++#define CRU_BASE_ADDR 0xFF2B0000 ++#define GRF_BASE_ADDR 0xFF140000 ++#define DDRC_BASE_ADDR 0xFF600000 ++#define DDR_PHY_BASE_ADDR 0xFF2A0000 ++#define SERVER_MSCH0_BASE_ADDR 0xFF530000 ++#define DDR_GRF_BASE_ADDR 0xff630000 ++ ++struct dram_info dram_info; ++ ++struct px30_sdram_params sdram_configs[] = { ++#include "sdram-px30-ddr3-detect-333.inc" ++}; ++ ++struct ddr_phy_skew skew = { ++#include "sdram-px30-ddr_skew.inc" ++}; ++ ++#define PATTERN (0x5aa5f00f) ++ ++/* ++ * cs: 0:cs0 ++ * 1:cs1 ++ * else cs0+cs1 ++ * note: it didn't consider about row_3_4 ++ */ ++u64 sdram_get_cs_cap(struct px30_sdram_channel *cap_info, u32 cs, u32 dram_type) ++{ ++ u32 bg; ++ u64 cap[2]; ++ ++ if (dram_type == DDR4) ++ /* DDR4 8bit dram BG = 2(4bank groups), ++ * 16bit dram BG = 1 (2 bank groups) ++ */ ++ bg = (cap_info->dbw == 0) ? 2 : 1; ++ else ++ bg = 0; ++ cap[0] = 1llu << (cap_info->bw + cap_info->col + ++ bg + cap_info->bk + cap_info->cs0_row); ++ ++ if (cap_info->rank == 2) ++ cap[1] = 1llu << (cap_info->bw + cap_info->col + ++ bg + cap_info->bk + cap_info->cs1_row); ++ else ++ cap[1] = 0; ++ ++ if (cs == 0) ++ return cap[0]; ++ else if (cs == 1) ++ return cap[1]; ++ else ++ return (cap[0] + cap[1]); ++} ++ ++/* n: Unit bytes */ ++void sdram_copy_to_reg(u32 *dest, const u32 *src, u32 n) ++{ ++ int i; ++ ++ for (i = 0; i < n / sizeof(u32); i++) { ++ writel(*src, dest); ++ src++; ++ dest++; ++ } ++} ++ ++static void sdram_phy_dll_bypass_set(void __iomem *phy_base, u32 freq) ++{ ++ u32 tmp; ++ u32 i, j; ++ ++ setbits_le32(PHY_REG(phy_base, 0x13), 1 << 4); ++ clrbits_le32(PHY_REG(phy_base, 0x14), 1 << 3); ++ for (i = 0; i < 4; i++) { ++ j = 0x26 + i * 0x10; ++ setbits_le32(PHY_REG(phy_base, j), 1 << 4); ++ clrbits_le32(PHY_REG(phy_base, j + 0x1), 1 << 3); ++ } ++ ++ if (freq <= (400000000)) ++ /* DLL bypass */ ++ setbits_le32(PHY_REG(phy_base, 0xa4), 0x1f); ++ else ++ clrbits_le32(PHY_REG(phy_base, 0xa4), 0x1f); ++ ++ if (freq <= (801000000)) ++ tmp = 2; ++ else ++ tmp = 1; ++ ++ for (i = 0; i < 4; i++) { ++ j = 0x28 + i * 0x10; ++ writel(tmp, PHY_REG(phy_base, j)); ++ } ++} ++ ++static void sdram_phy_set_ds_odt(void __iomem *phy_base, ++ u32 dram_type) ++{ ++ u32 cmd_drv, clk_drv, dqs_drv, dqs_odt; ++ u32 i, j; ++ ++ if (dram_type == DDR3) { ++ cmd_drv = PHY_DDR3_RON_RTT_34ohm; ++ clk_drv = PHY_DDR3_RON_RTT_45ohm; ++ dqs_drv = PHY_DDR3_RON_RTT_34ohm; ++ dqs_odt = PHY_DDR3_RON_RTT_225ohm; ++ } else { ++ cmd_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm; ++ clk_drv = PHY_DDR4_LPDDR3_RON_RTT_43ohm; ++ dqs_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm; ++ if (dram_type == LPDDR2) ++ dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_DISABLE; ++ else ++ dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_240ohm; ++ } ++ /* DS */ ++ writel(cmd_drv, PHY_REG(phy_base, 0x11)); ++ clrsetbits_le32(PHY_REG(phy_base, 0x12), 0x1f << 3, cmd_drv << 3); ++ writel(clk_drv, PHY_REG(phy_base, 0x16)); ++ writel(clk_drv, PHY_REG(phy_base, 0x18)); ++ ++ for (i = 0; i < 4; i++) { ++ j = 0x20 + i * 0x10; ++ writel(dqs_drv, PHY_REG(phy_base, j)); ++ writel(dqs_drv, PHY_REG(phy_base, j + 0xf)); ++ /* ODT */ ++ writel(dqs_odt, PHY_REG(phy_base, j + 0x1)); ++ writel(dqs_odt, PHY_REG(phy_base, j + 0xe)); ++ } ++} ++ ++static void phy_soft_reset(void __iomem *phy_base) ++{ ++ clrbits_le32(PHY_REG(phy_base, 0), 0x3 << 2); ++ udelay(1); ++ setbits_le32(PHY_REG(phy_base, 0), ANALOG_DERESET); ++ udelay(5); ++ setbits_le32(PHY_REG(phy_base, 0), DIGITAL_DERESET); ++ udelay(1); ++} ++ ++static void phy_dram_set_bw(void __iomem *phy_base, u32 bw) ++{ ++ if (bw == 2) { ++ clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4); ++ setbits_le32(PHY_REG(phy_base, 0x46), 1 << 3); ++ setbits_le32(PHY_REG(phy_base, 0x56), 1 << 3); ++ } else if (bw == 1) { ++ clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4); ++ clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3); ++ clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3); ++ } else if (bw == 0) { ++ clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 1 << 4); ++ clrbits_le32(PHY_REG(phy_base, 0x36), 1 << 3); ++ clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3); ++ clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3); ++ } ++ ++ phy_soft_reset(phy_base); ++} ++ ++static int phy_data_training(void __iomem *phy_base, u32 cs, u32 dramtype) ++{ ++ u32 ret; ++ u32 odt_val; ++ u32 i, j; ++ ++ odt_val = readl(PHY_REG(phy_base, 0x2e)); ++ ++ for (i = 0; i < 4; i++) { ++ j = 0x20 + i * 0x10; ++ writel(PHY_DDR3_RON_RTT_225ohm, PHY_REG(phy_base, j + 0x1)); ++ writel(0, PHY_REG(phy_base, j + 0xe)); ++ } ++ ++ if (dramtype == DDR4) { ++ clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0); ++ clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0); ++ clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0); ++ clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0); ++ } ++ /* choose training cs */ ++ clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs)); ++ /* enable gate training */ ++ clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 1); ++ udelay(50); ++ ret = readl(PHY_REG(phy_base, 0xff)); ++ /* disable gate training */ ++ clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 0); ++ clrbits_le32(PHY_REG(phy_base, 2), 0x30); ++ ++ if (dramtype == DDR4) { ++ clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0x2); ++ clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0x2); ++ clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0x2); ++ clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0x2); ++ } ++ ++ if (ret & 0x10) { ++ ret = -1; ++ } else { ++ ret = (ret & 0xf) ^ (readl(PHY_REG(phy_base, 0)) >> 4); ++ ret = (ret == 0) ? 0 : -1; ++ } ++ ++ for (i = 0; i < 4; i++) { ++ j = 0x20 + i * 0x10; ++ writel(odt_val, PHY_REG(phy_base, j + 0x1)); ++ writel(odt_val, PHY_REG(phy_base, j + 0xe)); ++ } ++ ++ return ret; ++} ++ ++static void phy_cfg(void __iomem *phy_base, ++ struct ddr_phy_regs *phy_regs, struct ddr_phy_skew *skew, ++ struct px30_base_params *base, u32 bw) ++{ ++ u32 i; ++ ++ sdram_phy_dll_bypass_set(phy_base, base->ddr_freq); ++ for (i = 0; phy_regs->phy[i][0] != 0xFFFFFFFF; i++) { ++ writel(phy_regs->phy[i][1], ++ phy_base + phy_regs->phy[i][0]); ++ } ++ if (bw == 2) { ++ clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4); ++ } else if (bw == 1) { ++ clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4); ++ /* disable DQS2,DQS3 tx dll for saving power */ ++ clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3); ++ clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3); ++ } else { ++ clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 1 << 4); ++ /* disable DQS2,DQS3 tx dll for saving power */ ++ clrbits_le32(PHY_REG(phy_base, 0x36), 1 << 3); ++ clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3); ++ clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3); ++ } ++ sdram_phy_set_ds_odt(phy_base, base->dramtype); ++ ++ /* deskew */ ++ setbits_le32(PHY_REG(phy_base, 2), 8); ++ sdram_copy_to_reg(PHY_REG(phy_base, 0xb0), ++ &skew->a0_a1_skew[0], 15 * 4); ++ sdram_copy_to_reg(PHY_REG(phy_base, 0x70), ++ &skew->cs0_dm0_skew[0], 44 * 4); ++ sdram_copy_to_reg(PHY_REG(phy_base, 0xc0), ++ &skew->cs1_dm0_skew[0], 44 * 4); ++} ++ ++void sdram_org_config(struct px30_sdram_channel *info, ++ struct px30_base_params *base, ++ u32 *p_os_reg2, u32 *p_os_reg3, u32 channel) ++{ ++ *p_os_reg2 |= base->dramtype << SYS_REG_DDRTYPE_SHIFT; ++ *p_os_reg2 |= (base->num_channels - 1) << SYS_REG_NUM_CH_SHIFT; ++ *p_os_reg2 |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(channel); ++ *p_os_reg2 |= 1 << SYS_REG_CHINFO_SHIFT(channel); ++ *p_os_reg2 |= (info->rank - 1) << SYS_REG_RANK_SHIFT(channel); ++ *p_os_reg2 |= (info->col - 9) << SYS_REG_COL_SHIFT(channel); ++ *p_os_reg2 |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(channel); ++ *p_os_reg2 |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(channel); ++ if (info->cs1_row >= 13) ++ *p_os_reg2 |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(channel); ++ *p_os_reg2 |= (2 >> info->bw) << SYS_REG_BW_SHIFT(channel); ++ *p_os_reg2 |= (2 >> info->dbw) << SYS_REG_DBW_SHIFT(channel); ++} ++ ++void sdram_msch_config(struct px30_msch_regs *msch, ++ struct px30_msch_timings *noc_timings, ++ struct px30_sdram_channel *cap_info, ++ struct px30_base_params *base) ++{ ++ u64 cs_cap[2]; ++ ++ cs_cap[0] = sdram_get_cs_cap(cap_info, 0, base->dramtype); ++ cs_cap[1] = sdram_get_cs_cap(cap_info, 1, base->dramtype); ++ writel(((((cs_cap[1] >> 20) / 64) & 0xff) << 8) | ++ (((cs_cap[0] >> 20) / 64) & 0xff), ++ &msch->devicesize); ++ ++ writel(noc_timings->ddrtiminga0, &msch->ddrtiminga0); ++ writel(noc_timings->ddrtimingb0, &msch->ddrtimingb0); ++ writel(noc_timings->ddrtimingc0, &msch->ddrtimingc0); ++ writel(noc_timings->devtodev0, &msch->devtodev0); ++ writel(noc_timings->ddrmode, &msch->ddrmode); ++ writel(noc_timings->ddr4timing, &msch->ddr4timing); ++ writel(noc_timings->agingx0, &msch->agingx0); ++ writel(noc_timings->agingx0, &msch->aging0); ++ writel(noc_timings->agingx0, &msch->aging1); ++ writel(noc_timings->agingx0, &msch->aging2); ++ writel(noc_timings->agingx0, &msch->aging3); ++} ++ ++int sdram_detect_bw(struct px30_sdram_channel *cap_info) ++{ ++ return 0; ++} ++ ++int sdram_detect_cs(struct px30_sdram_channel *cap_info) ++{ ++ return 0; ++} ++ ++int sdram_detect_col(struct px30_sdram_channel *cap_info, ++ u32 coltmp) ++{ ++ void __iomem *test_addr; ++ u32 col; ++ u32 bw = cap_info->bw; ++ ++ for (col = coltmp; col >= 9; col -= 1) { ++ writel(0, CONFIG_SYS_SDRAM_BASE); ++ test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE + ++ (1ul << (col + bw - 1ul))); ++ writel(PATTERN, test_addr); ++ if ((readl(test_addr) == PATTERN) && ++ (readl(CONFIG_SYS_SDRAM_BASE) == 0)) ++ break; ++ } ++ if (col == 8) { ++ printascii("col error\n"); ++ return -1; ++ } ++ ++ cap_info->col = col; ++ ++ return 0; ++} ++ ++int sdram_detect_bank(struct px30_sdram_channel *cap_info, ++ u32 coltmp, u32 bktmp) ++{ ++ void __iomem *test_addr; ++ u32 bk; ++ u32 bw = cap_info->bw; ++ ++ test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE + ++ (1ul << (coltmp + bktmp + bw - 1ul))); ++ writel(0, CONFIG_SYS_SDRAM_BASE); ++ writel(PATTERN, test_addr); ++ if ((readl(test_addr) == PATTERN) && ++ (readl(CONFIG_SYS_SDRAM_BASE) == 0)) ++ bk = 3; ++ else ++ bk = 2; ++ ++ cap_info->bk = bk; ++ ++ return 0; ++} ++ ++/* detect bg for ddr4 */ ++int sdram_detect_bg(struct px30_sdram_channel *cap_info, ++ u32 coltmp) ++{ ++ void __iomem *test_addr; ++ u32 dbw; ++ u32 bw = cap_info->bw; ++ ++ test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE + ++ (1ul << (coltmp + bw + 1ul))); ++ writel(0, CONFIG_SYS_SDRAM_BASE); ++ writel(PATTERN, test_addr); ++ if ((readl(test_addr) == PATTERN) && ++ (readl(CONFIG_SYS_SDRAM_BASE) == 0)) ++ dbw = 0; ++ else ++ dbw = 1; ++ ++ cap_info->dbw = dbw; ++ ++ return 0; ++} ++ ++/* detect dbw for ddr3,lpddr2,lpddr3,lpddr4 */ ++int sdram_detect_dbw(struct px30_sdram_channel *cap_info, u32 dram_type) ++{ ++ u32 row, col, bk, bw, cs_cap, cs; ++ u32 die_bw_0 = 0, die_bw_1 = 0; ++ ++ if (dram_type == DDR3 || dram_type == LPDDR4) { ++ cap_info->dbw = 1; ++ } else if (dram_type == LPDDR3 || dram_type == LPDDR2) { ++ row = cap_info->cs0_row; ++ col = cap_info->col; ++ bk = cap_info->bk; ++ cs = cap_info->rank; ++ bw = cap_info->bw; ++ cs_cap = (1 << (row + col + bk + bw - 20)); ++ if (bw == 2) { ++ if (cs_cap <= 0x2000000) /* 256Mb */ ++ die_bw_0 = (col < 9) ? 2 : 1; ++ else if (cs_cap <= 0x10000000) /* 2Gb */ ++ die_bw_0 = (col < 10) ? 2 : 1; ++ else if (cs_cap <= 0x40000000) /* 8Gb */ ++ die_bw_0 = (col < 11) ? 2 : 1; ++ else ++ die_bw_0 = (col < 12) ? 2 : 1; ++ if (cs > 1) { ++ row = cap_info->cs1_row; ++ cs_cap = (1 << (row + col + bk + bw - 20)); ++ if (cs_cap <= 0x2000000) /* 256Mb */ ++ die_bw_0 = (col < 9) ? 2 : 1; ++ else if (cs_cap <= 0x10000000) /* 2Gb */ ++ die_bw_0 = (col < 10) ? 2 : 1; ++ else if (cs_cap <= 0x40000000) /* 8Gb */ ++ die_bw_0 = (col < 11) ? 2 : 1; ++ else ++ die_bw_0 = (col < 12) ? 2 : 1; ++ } ++ } else { ++ die_bw_1 = 1; ++ die_bw_0 = 1; ++ } ++ cap_info->dbw = (die_bw_0 > die_bw_1) ? die_bw_0 : die_bw_1; ++ } ++ ++ return 0; ++} ++ ++int sdram_detect_row(struct px30_sdram_channel *cap_info, ++ u32 coltmp, u32 bktmp, u32 rowtmp) ++{ ++ u32 row; ++ u32 bw = cap_info->bw; ++ void __iomem *test_addr; ++ ++ for (row = rowtmp; row > 12; row--) { ++ writel(0, CONFIG_SYS_SDRAM_BASE); ++ test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE + ++ (1ul << (row + bktmp + coltmp + bw - 1ul))); ++ writel(PATTERN, test_addr); ++ if ((readl(test_addr) == PATTERN) && ++ (readl(CONFIG_SYS_SDRAM_BASE) == 0)) ++ break; ++ } ++ if (row == 12) { ++ printascii("row error"); ++ return -1; ++ } ++ ++ cap_info->cs0_row = row; ++ ++ return 0; ++} ++ ++int sdram_detect_row_3_4(struct px30_sdram_channel *cap_info, ++ u32 coltmp, u32 bktmp) ++{ ++ u32 row_3_4; ++ u32 bw = cap_info->bw; ++ u32 row = cap_info->cs0_row; ++ void __iomem *test_addr, *test_addr1; ++ ++ test_addr = CONFIG_SYS_SDRAM_BASE; ++ test_addr1 = (void __iomem *)(CONFIG_SYS_SDRAM_BASE + ++ (0x3ul << (row + bktmp + coltmp + bw - 1ul - 1ul))); ++ ++ writel(0, test_addr); ++ writel(PATTERN, test_addr1); ++ if ((readl(test_addr) == 0) && (readl(test_addr1) == PATTERN)) ++ row_3_4 = 0; ++ else ++ row_3_4 = 1; ++ ++ cap_info->row_3_4 = row_3_4; ++ ++ return 0; ++} ++ ++int sdram_detect_high_row(struct px30_sdram_channel *cap_info) ++{ ++ cap_info->cs0_high16bit_row = cap_info->cs0_row; ++ cap_info->cs1_high16bit_row = cap_info->cs1_row; ++ ++ return 0; ++} ++ ++int sdram_detect_cs1_row(struct px30_sdram_channel *cap_info, u32 dram_type) ++{ ++ void __iomem *test_addr; ++ u32 row = 0, bktmp, coltmp, bw; ++ ulong cs0_cap; ++ u32 byte_mask; ++ ++ if (cap_info->rank == 2) { ++ cs0_cap = sdram_get_cs_cap(cap_info, 0, dram_type); ++ ++ if (dram_type == DDR4) { ++ if (cap_info->dbw == 0) ++ bktmp = cap_info->bk + 2; ++ else ++ bktmp = cap_info->bk + 1; ++ } else { ++ bktmp = cap_info->bk; ++ } ++ bw = cap_info->bw; ++ coltmp = cap_info->col; ++ ++ /* ++ * because px30 support axi split,min bandwidth ++ * is 8bit. if cs0 is 32bit, cs1 may 32bit or 16bit ++ * so we check low 16bit data when detect cs1 row. ++ * if cs0 is 16bit/8bit, we check low 8bit data. ++ */ ++ if (bw == 2) ++ byte_mask = 0xFFFF; ++ else ++ byte_mask = 0xFF; ++ ++ /* detect cs1 row */ ++ for (row = cap_info->cs0_row; row > 12; row--) { ++ test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE + ++ cs0_cap + ++ (1ul << (row + bktmp + coltmp + bw - 1ul))); ++ writel(0, CONFIG_SYS_SDRAM_BASE + cs0_cap); ++ writel(PATTERN, test_addr); ++ ++ if (((readl(test_addr) & byte_mask) == ++ (PATTERN & byte_mask)) && ++ ((readl(CONFIG_SYS_SDRAM_BASE + cs0_cap) & ++ byte_mask) == 0)) { ++ break; ++ } ++ } ++ } ++ ++ cap_info->cs1_row = row; ++ ++ return 0; ++} ++ ++static void rkclk_ddr_reset(struct dram_info *dram, ++ u32 ctl_srstn, u32 ctl_psrstn, ++ u32 phy_srstn, u32 phy_psrstn) ++{ ++ writel(upctl2_srstn_req(ctl_srstn) | upctl2_psrstn_req(ctl_psrstn) | ++ upctl2_asrstn_req(ctl_srstn), ++ &dram->cru->softrst_con[1]); ++ writel(ddrphy_srstn_req(phy_srstn) | ddrphy_psrstn_req(phy_psrstn), ++ &dram->cru->softrst_con[2]); ++} ++ ++static void rkclk_set_dpll(struct dram_info *dram, unsigned int hz) ++{ ++ unsigned int refdiv, postdiv1, postdiv2, fbdiv; ++ int delay = 1000; ++ u32 mhz = hz / MHz; ++ ++ refdiv = 1; ++ if (mhz <= 300) { ++ postdiv1 = 4; ++ postdiv2 = 2; ++ } else if (mhz <= 400) { ++ postdiv1 = 6; ++ postdiv2 = 1; ++ } else if (mhz <= 600) { ++ postdiv1 = 4; ++ postdiv2 = 1; ++ } else if (mhz <= 800) { ++ postdiv1 = 3; ++ postdiv2 = 1; ++ } else if (mhz <= 1600) { ++ postdiv1 = 2; ++ postdiv2 = 1; ++ } else { ++ postdiv1 = 1; ++ postdiv2 = 1; ++ } ++ fbdiv = (mhz * refdiv * postdiv1 * postdiv2) / 24; ++ ++ writel(DPLL_MODE(CLOCK_FROM_XIN_OSC), &dram->cru->mode); ++ ++ writel(POSTDIV1(postdiv1) | FBDIV(fbdiv), &dram->cru->pll[1].con0); ++ writel(DSMPD(1) | POSTDIV2(postdiv2) | REFDIV(refdiv), ++ &dram->cru->pll[1].con1); ++ ++ while (delay > 0) { ++ rockchip_udelay(1); ++ if (LOCK(readl(&dram->cru->pll[1].con1))) ++ break; ++ delay--; ++ } ++ ++ writel(DPLL_MODE(CLOCK_FROM_PLL), &dram->cru->mode); ++} ++ ++static void rkclk_configure_ddr(struct dram_info *dram, ++ struct px30_sdram_params *sdram_params) ++{ ++ /* for inno ddr phy need 2*freq */ ++ rkclk_set_dpll(dram, sdram_params->base.ddr_freq * MHz * 2); ++} ++ ++/* return ddrconfig value ++ * (-1), find ddrconfig fail ++ * other, the ddrconfig value ++ * only support cs0_row >= cs1_row ++ */ ++static unsigned int calculate_ddrconfig(struct px30_sdram_params *sdram_params) ++{ ++ struct px30_sdram_channel *cap_info = &sdram_params->ch; ++ u32 bw, die_bw, col, bank; ++ u32 i, tmp; ++ u32 ddrconf = -1; ++ ++ bw = cap_info->bw; ++ die_bw = cap_info->dbw; ++ col = cap_info->col; ++ bank = cap_info->bk; ++ ++ if (sdram_params->base.dramtype == DDR4) { ++ if (die_bw == 0) ++ ddrconf = 7 + bw; ++ else ++ ddrconf = 12 - bw; ++ ddrconf = d4_rbc_2_d3_rbc[ddrconf - 7]; ++ } else { ++ tmp = ((bank - 2) << 3) | (col + bw - 10); ++ for (i = 0; i < 7; i++) ++ if ((ddr_cfg_2_rbc[i] & 0xf) == tmp) { ++ ddrconf = i; ++ break; ++ } ++ if (i > 6) ++ printascii("calculate ddrconfig error\n"); ++ } ++ ++ return ddrconf; ++} ++ ++/* ++ * rank = 1: cs0 ++ * rank = 2: cs1 ++ */ ++static void pctl_read_mr(void __iomem *pctl_base, u32 rank, u32 mr_num) ++{ ++ writel((rank << 4) | (1 << 0), pctl_base + DDR_PCTL2_MRCTRL0); ++ writel((mr_num << 8), pctl_base + DDR_PCTL2_MRCTRL1); ++ setbits_le32(pctl_base + DDR_PCTL2_MRCTRL0, 1u << 31); ++ while (readl(pctl_base + DDR_PCTL2_MRCTRL0) & (1u << 31)) ++ continue; ++ while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY) ++ continue; ++} ++ ++/* rank = 1: cs0 ++ * rank = 2: cs1 ++ * rank = 3: cs0 & cs1 ++ * note: be careful of keep mr original val ++ */ ++static int pctl_write_mr(void __iomem *pctl_base, u32 rank, u32 mr_num, u32 arg, ++ u32 dramtype) ++{ ++ while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY) ++ continue; ++ if (dramtype == DDR3 || dramtype == DDR4) { ++ writel((mr_num << 12) | (rank << 4) | (0 << 0), ++ pctl_base + DDR_PCTL2_MRCTRL0); ++ writel(arg, pctl_base + DDR_PCTL2_MRCTRL1); ++ } else { ++ writel((rank << 4) | (0 << 0), ++ pctl_base + DDR_PCTL2_MRCTRL0); ++ writel((mr_num << 8) | (arg & 0xff), ++ pctl_base + DDR_PCTL2_MRCTRL1); ++ } ++ ++ setbits_le32(pctl_base + DDR_PCTL2_MRCTRL0, 1u << 31); ++ while (readl(pctl_base + DDR_PCTL2_MRCTRL0) & (1u << 31)) ++ continue; ++ while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY) ++ continue; ++ ++ return 0; ++} ++ ++static int upctl2_update_ref_reg(void __iomem *pctl_base) ++{ ++ u32 ret; ++ ++ ret = readl(pctl_base + DDR_PCTL2_RFSHCTL3) ^ (1 << 1); ++ writel(ret, pctl_base + DDR_PCTL2_RFSHCTL3); ++ ++ return 0; ++} ++ ++static u32 pctl_dis_zqcs_aref(void __iomem *pctl_base) ++{ ++ u32 dis_auto_zq = 0; ++ ++ /* disable zqcs */ ++ if (!(readl(pctl_base + DDR_PCTL2_ZQCTL0) & ++ (1ul << 31))) { ++ dis_auto_zq = 1; ++ setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31); ++ } ++ ++ /* disable auto refresh */ ++ setbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1); ++ ++ upctl2_update_ref_reg(pctl_base); ++ ++ return dis_auto_zq; ++} ++ ++static void pctl_rest_zqcs_aref(void __iomem *pctl_base, u32 dis_auto_zq) ++{ ++ /* restore zqcs */ ++ if (dis_auto_zq) ++ clrbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31); ++ ++ /* restore auto refresh */ ++ clrbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1); ++ ++ upctl2_update_ref_reg(pctl_base); ++} ++ ++/* ++ * rank : 1:cs0, 2:cs1, 3:cs0&cs1 ++ * vrefrate: 4500: 45%, ++ */ ++static int pctl_write_vrefdq(void __iomem *pctl_base, u32 rank, u32 vrefrate, ++ u32 dramtype) ++{ ++ u32 tccd_l, value; ++ u32 dis_auto_zq = 0; ++ ++ if (dramtype != DDR4 || vrefrate < 4500 || ++ vrefrate > 9200) ++ return (-1); ++ ++ tccd_l = (readl(pctl_base + DDR_PCTL2_DRAMTMG4) >> 16) & 0xf; ++ tccd_l = (tccd_l - 4) << 10; ++ ++ if (vrefrate > 7500) { ++ /* range 1 */ ++ value = ((vrefrate - 6000) / 65) | tccd_l; ++ } else { ++ /* range 2 */ ++ value = ((vrefrate - 4500) / 65) | tccd_l | (1 << 6); ++ } ++ ++ dis_auto_zq = pctl_dis_zqcs_aref(pctl_base); ++ ++ /* enable vrefdq calibratin */ ++ pctl_write_mr(pctl_base, rank, 6, value | (1 << 7), dramtype); ++ udelay(1);/* tvrefdqe */ ++ /* write vrefdq value */ ++ pctl_write_mr(pctl_base, rank, 6, value | (1 << 7), dramtype); ++ udelay(1);/* tvref_time */ ++ pctl_write_mr(pctl_base, rank, 6, value | (0 << 7), dramtype); ++ udelay(1);/* tvrefdqx */ ++ ++ pctl_rest_zqcs_aref(pctl_base, dis_auto_zq); ++ ++ return 0; ++} ++ ++static u32 pctl_remodify_sdram_params(struct ddr_pctl_regs *pctl_regs, ++ struct px30_sdram_channel *cap_info, ++ u32 dram_type) ++{ ++ u32 tmp = 0, tmp_adr = 0, i; ++ ++ for (i = 0; pctl_regs->pctl[i][0] != 0xFFFFFFFF; i++) { ++ if (pctl_regs->pctl[i][0] == 0) { ++ tmp = pctl_regs->pctl[i][1];/* MSTR */ ++ tmp_adr = i; ++ } ++ } ++ ++ tmp &= ~((3ul << 30) | (3ul << 24) | (3ul << 12)); ++ ++ switch (cap_info->dbw) { ++ case 2: ++ tmp |= (3ul << 30); ++ break; ++ case 1: ++ tmp |= (2ul << 30); ++ break; ++ case 0: ++ default: ++ tmp |= (1ul << 30); ++ break; ++ } ++ ++ /* ++ * If DDR3 or DDR4 MSTR.active_ranks=1, ++ * it will gate memory clock when enter power down. ++ * Force set active_ranks to 3 to workaround it. ++ */ ++ if (cap_info->rank == 2 || dram_type == DDR3 || ++ dram_type == DDR4) ++ tmp |= 3 << 24; ++ else ++ tmp |= 1 << 24; ++ ++ tmp |= (2 - cap_info->bw) << 12; ++ ++ pctl_regs->pctl[tmp_adr][1] = tmp; ++ ++ return 0; ++} ++ ++static int pctl_cfg(void __iomem *pctl_base, struct ddr_pctl_regs *pctl_regs, ++ u32 sr_idle, u32 pd_idle) ++{ ++ u32 i; ++ ++ for (i = 0; pctl_regs->pctl[i][0] != 0xFFFFFFFF; i++) { ++ writel(pctl_regs->pctl[i][1], ++ pctl_base + pctl_regs->pctl[i][0]); ++ } ++ clrsetbits_le32(pctl_base + DDR_PCTL2_PWRTMG, ++ (0xff << 16) | 0x1f, ++ ((sr_idle & 0xff) << 16) | (pd_idle & 0x1f)); ++ ++ clrsetbits_le32(pctl_base + DDR_PCTL2_HWLPCTL, ++ 0xfff << 16, ++ 5 << 16); ++ /* disable zqcs */ ++ setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1u << 31); ++ ++ return 0; ++} ++ ++/* ++ * calculate controller dram address map, and setting to register. ++ * argument sdram_params->ch.ddrconf must be right value before ++ * call this function. ++ */ ++static void set_ctl_address_map(struct dram_info *dram, ++ struct px30_sdram_params *sdram_params) ++{ ++ struct px30_sdram_channel *cap_info = &sdram_params->ch; ++ void __iomem *pctl_base = dram->pctl; ++ u32 cs_pst, bg, max_row, ddrconf; ++ u32 i; ++ ++ if (sdram_params->base.dramtype == DDR4) ++ /* ++ * DDR4 8bit dram BG = 2(4bank groups), ++ * 16bit dram BG = 1 (2 bank groups) ++ */ ++ bg = (cap_info->dbw == 0) ? 2 : 1; ++ else ++ bg = 0; ++ ++ cs_pst = cap_info->bw + cap_info->col + ++ bg + cap_info->bk + cap_info->cs0_row; ++ if (cs_pst >= 32 || cap_info->rank == 1) ++ writel(0x1f, pctl_base + DDR_PCTL2_ADDRMAP0); ++ else ++ writel(cs_pst - 8, pctl_base + DDR_PCTL2_ADDRMAP0); ++ ++ ddrconf = cap_info->ddrconfig; ++ if (sdram_params->base.dramtype == DDR4) { ++ for (i = 0; i < ARRAY_SIZE(d4_rbc_2_d3_rbc); i++) { ++ if (d4_rbc_2_d3_rbc[i] == ddrconf) { ++ ddrconf = 7 + i; ++ break; ++ } ++ } ++ } ++ ++ sdram_copy_to_reg((u32 *)(pctl_base + DDR_PCTL2_ADDRMAP1), ++ &addrmap[ddrconf][0], 8 * 4); ++ max_row = cs_pst - 1 - 8 - (addrmap[ddrconf][5] & 0xf); ++ ++ if (max_row < 12) ++ printascii("set addrmap fail\n"); ++ /* need to disable row ahead of rank by set to 0xf */ ++ for (i = 17; i > max_row; i--) ++ clrsetbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6 + ++ ((i - 12) * 8 / 32) * 4, ++ 0xf << ((i - 12) * 8 % 32), ++ 0xf << ((i - 12) * 8 % 32)); ++ ++ if ((sdram_params->base.dramtype == LPDDR3 || ++ sdram_params->base.dramtype == LPDDR2) && ++ cap_info->row_3_4) ++ setbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6, 1 << 31); ++ if (sdram_params->base.dramtype == DDR4 && cap_info->bw != 0x2) ++ setbits_le32(pctl_base + DDR_PCTL2_PCCFG, 1 << 8); ++} ++ ++/* ++ * rank = 1: cs0 ++ * rank = 2: cs1 ++ */ ++int read_mr(struct dram_info *dram, u32 rank, u32 mr_num) ++{ ++ void __iomem *ddr_grf_base = dram->ddr_grf; ++ ++ pctl_read_mr(dram->pctl, rank, mr_num); ++ ++ return (readl(ddr_grf_base + DDR_GRF_STATUS(0)) & 0xff); ++} ++ ++#define MIN(a, b) (((a) > (b)) ? (b) : (a)) ++#define MAX(a, b) (((a) > (b)) ? (a) : (b)) ++static u32 check_rd_gate(struct dram_info *dram) ++{ ++ void __iomem *phy_base = dram->phy; ++ ++ u32 max_val = 0; ++ u32 min_val = 0xff; ++ u32 gate[4]; ++ u32 i, bw; ++ ++ bw = (readl(PHY_REG(phy_base, 0x0)) >> 4) & 0xf; ++ switch (bw) { ++ case 0x1: ++ bw = 1; ++ break; ++ case 0x3: ++ bw = 2; ++ break; ++ case 0xf: ++ default: ++ bw = 4; ++ break; ++ } ++ ++ for (i = 0; i < bw; i++) { ++ gate[i] = readl(PHY_REG(phy_base, 0xfb + i)); ++ max_val = MAX(max_val, gate[i]); ++ min_val = MIN(min_val, gate[i]); ++ } ++ ++ if (max_val > 0x80 || min_val < 0x20) ++ return -1; ++ else ++ return 0; ++} ++ ++static int data_training(struct dram_info *dram, u32 cs, u32 dramtype) ++{ ++ void __iomem *pctl_base = dram->pctl; ++ u32 dis_auto_zq = 0; ++ u32 pwrctl; ++ u32 ret; ++ ++ /* disable auto low-power */ ++ pwrctl = readl(pctl_base + DDR_PCTL2_PWRCTL); ++ writel(0, pctl_base + DDR_PCTL2_PWRCTL); ++ ++ dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl); ++ ++ ret = phy_data_training(dram->phy, cs, dramtype); ++ ++ pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq); ++ ++ /* restore auto low-power */ ++ writel(pwrctl, pctl_base + DDR_PCTL2_PWRCTL); ++ ++ return ret; ++} ++ ++static void dram_set_bw(struct dram_info *dram, u32 bw) ++{ ++ phy_dram_set_bw(dram->phy, bw); ++} ++ ++static void set_ddrconfig(struct dram_info *dram, u32 ddrconfig) ++{ ++ writel(ddrconfig | (ddrconfig << 8), &dram->msch->deviceconf); ++ rk_clrsetreg(&dram->grf->soc_noc_con[1], 0x3 << 14, 0 << 14); ++} ++ ++static void dram_all_config(struct dram_info *dram, ++ struct px30_sdram_params *sdram_params) ++{ ++ struct px30_sdram_channel *cap_info = &sdram_params->ch; ++ u32 sys_reg2 = 0; ++ u32 sys_reg3 = 0; ++ ++ set_ddrconfig(dram, cap_info->ddrconfig); ++ sdram_org_config(cap_info, &sdram_params->base, &sys_reg2, ++ &sys_reg3, 0); ++ writel(sys_reg2, &dram->pmugrf->os_reg[2]); ++ writel(sys_reg3, &dram->pmugrf->os_reg[3]); ++ sdram_msch_config(dram->msch, &sdram_params->ch.noc_timings, cap_info, ++ &sdram_params->base); ++} ++ ++static void enable_low_power(struct dram_info *dram, ++ struct px30_sdram_params *sdram_params) ++{ ++ void __iomem *pctl_base = dram->pctl; ++ void __iomem *phy_base = dram->phy; ++ void __iomem *ddr_grf_base = dram->ddr_grf; ++ u32 grf_lp_con; ++ ++ /* ++ * bit0: grf_upctl_axi_cg_en = 1 enable upctl2 axi clk auto gating ++ * bit1: grf_upctl_apb_cg_en = 1 ungated axi,core clk for apb access ++ * bit2: grf_upctl_core_cg_en = 1 enable upctl2 core clk auto gating ++ * bit3: grf_selfref_type2_en = 0 disable core clk gating when type2 sr ++ * bit4: grf_upctl_syscreq_cg_en = 1 ++ * ungating coreclk when c_sysreq assert ++ * bit8-11: grf_auto_sr_dly = 6 ++ */ ++ writel(0x1f1f0617, &dram->ddr_grf->ddr_grf_con[1]); ++ ++ if (sdram_params->base.dramtype == DDR4) ++ grf_lp_con = (0x7 << 16) | (1 << 1); ++ else if (sdram_params->base.dramtype == DDR3) ++ grf_lp_con = (0x7 << 16) | (1 << 0); ++ else ++ grf_lp_con = (0x7 << 16) | (1 << 2); ++ ++ /* en lpckdis_en */ ++ grf_lp_con = grf_lp_con | (0x1 << (9 + 16)) | (0x1 << 9); ++ writel(grf_lp_con, ddr_grf_base + DDR_GRF_LP_CON); ++ ++ /* off digit module clock when enter power down */ ++ setbits_le32(PHY_REG(phy_base, 7), 1 << 7); ++ ++ /* enable sr, pd */ ++ if (PD_IDLE == 0) ++ clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 1)); ++ else ++ setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 1)); ++ if (SR_IDLE == 0) ++ clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, 1); ++ else ++ setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, 1); ++ setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 3)); ++} ++ ++/* ++ * pre_init: 0: pre init for dram cap detect ++ * 1: detect correct cap(except cs1 row)info, than reinit ++ * 2: after reinit, we detect cs1_row, if cs1_row not equal ++ * to cs0_row and cs is in middle on ddrconf map, we need ++ * to reinit dram, than set the correct ddrconf. ++ */ ++static int sdram_init_(struct dram_info *dram, ++ struct px30_sdram_params *sdram_params, u32 pre_init) ++{ ++ struct px30_sdram_channel *cap_info = &sdram_params->ch; ++ void __iomem *pctl_base = dram->pctl; ++ ++ rkclk_ddr_reset(dram, 1, 1, 1, 1); ++ rockchip_udelay(10); ++ /* ++ * dereset ddr phy psrstn to config pll, ++ * if using phy pll psrstn must be dereset ++ * before config pll ++ */ ++ rkclk_ddr_reset(dram, 1, 1, 1, 0); ++ rkclk_configure_ddr(dram, sdram_params); ++ ++ /* release phy srst to provide clk to ctrl */ ++ rkclk_ddr_reset(dram, 1, 1, 0, 0); ++ rockchip_udelay(10); ++ phy_soft_reset(dram->phy); ++ ++ /* release ctrl presetn, and config ctl registers */ ++ rkclk_ddr_reset(dram, 1, 0, 0, 0); ++ pctl_cfg(dram->pctl, &sdram_params->pctl_regs, SR_IDLE, PD_IDLE); ++ cap_info->ddrconfig = calculate_ddrconfig(sdram_params); ++ set_ctl_address_map(dram, sdram_params); ++ phy_cfg(dram->phy, &sdram_params->phy_regs, sdram_params->skew, ++ &sdram_params->base, cap_info->bw); ++ ++ /* enable dfi_init_start to init phy after ctl srstn deassert */ ++ setbits_le32(pctl_base + DDR_PCTL2_DFIMISC, (1 << 5) | (1 << 4)); ++ ++ rkclk_ddr_reset(dram, 0, 0, 0, 0); ++ /* wait for dfi_init_done and dram init complete */ ++ while ((readl(pctl_base + DDR_PCTL2_STAT) & 0x7) == 0) ++ continue; ++ ++ if (sdram_params->base.dramtype == LPDDR3) ++ pctl_write_mr(dram->pctl, 3, 11, 3, LPDDR3); ++ ++ /* do ddr gate training */ ++redo_cs0_training: ++ if (data_training(dram, 0, sdram_params->base.dramtype) != 0) { ++ if (pre_init != 0) ++ printascii("DTT cs0 error\n"); ++ return -1; ++ } ++ if (check_rd_gate(dram)) { ++ printascii("re training cs0"); ++ goto redo_cs0_training; ++ } ++ ++ if (sdram_params->base.dramtype == LPDDR3) { ++ if ((read_mr(dram, 1, 8) & 0x3) != 0x3) ++ return -1; ++ } else if (sdram_params->base.dramtype == LPDDR2) { ++ if ((read_mr(dram, 1, 8) & 0x3) != 0x0) ++ return -1; ++ } ++ ++ /* for px30: when 2cs, both 2 cs should be training */ ++ if (pre_init != 0 && cap_info->rank == 2) { ++redo_cs1_training: ++ if (data_training(dram, 1, sdram_params->base.dramtype) != 0) { ++ printascii("DTT cs1 error\n"); ++ return -1; ++ } ++ if (check_rd_gate(dram)) { ++ printascii("re training cs1"); ++ goto redo_cs1_training; ++ } ++ } ++ ++ if (sdram_params->base.dramtype == DDR4) ++ pctl_write_vrefdq(dram->pctl, 0x3, 5670, ++ sdram_params->base.dramtype); ++ ++ dram_all_config(dram, sdram_params); ++ enable_low_power(dram, sdram_params); ++ ++ return 0; ++} ++ ++static int dram_detect_cap(struct dram_info *dram, ++ struct px30_sdram_params *sdram_params, ++ unsigned char channel) ++{ ++ struct px30_sdram_channel *cap_info = &sdram_params->ch; ++ ++ /* ++ * for ddr3: ddrconf = 3 ++ * for ddr4: ddrconf = 12 ++ * for lpddr3: ddrconf = 3 ++ * default bw = 1 ++ */ ++ u32 bk, bktmp; ++ u32 col, coltmp; ++ u32 rowtmp; ++ u32 cs; ++ u32 bw = 1; ++ u32 dram_type = sdram_params->base.dramtype; ++ ++ if (dram_type != DDR4) { ++ /* detect col and bk for ddr3/lpddr3 */ ++ coltmp = 12; ++ bktmp = 3; ++ if (dram_type == LPDDR2) ++ rowtmp = 15; ++ else ++ rowtmp = 16; ++ ++ if (sdram_detect_col(cap_info, coltmp) != 0) ++ goto cap_err; ++ sdram_detect_bank(cap_info, coltmp, bktmp); ++ sdram_detect_dbw(cap_info, dram_type); ++ } else { ++ /* detect bg for ddr4 */ ++ coltmp = 10; ++ bktmp = 4; ++ rowtmp = 17; ++ ++ col = 10; ++ bk = 2; ++ cap_info->col = col; ++ cap_info->bk = bk; ++ sdram_detect_bg(cap_info, coltmp); ++ } ++ ++ /* detect row */ ++ if (sdram_detect_row(cap_info, coltmp, bktmp, rowtmp) != 0) ++ goto cap_err; ++ ++ /* detect row_3_4 */ ++ sdram_detect_row_3_4(cap_info, coltmp, bktmp); ++ ++ /* bw and cs detect using data training */ ++ if (data_training(dram, 1, dram_type) == 0) ++ cs = 1; ++ else ++ cs = 0; ++ cap_info->rank = cs + 1; ++ ++ dram_set_bw(dram, 2); ++ if (data_training(dram, 0, dram_type) == 0) ++ bw = 2; ++ else ++ bw = 1; ++ cap_info->bw = bw; ++ ++ cap_info->cs0_high16bit_row = cap_info->cs0_row; ++ if (cs) { ++ cap_info->cs1_row = cap_info->cs0_row; ++ cap_info->cs1_high16bit_row = cap_info->cs0_row; ++ } else { ++ cap_info->cs1_row = 0; ++ cap_info->cs1_high16bit_row = 0; ++ } ++ ++ return 0; ++cap_err: ++ return -1; ++} ++ ++static int sdram_init_detect(struct dram_info *dram, ++ struct px30_sdram_params *sdram_params) ++{ ++ struct px30_sdram_channel *cap_info = &sdram_params->ch; ++ u32 ret; ++ u32 sys_reg = 0; ++ u32 sys_reg3 = 0; ++ ++ if (sdram_init_(dram, sdram_params, 0) != 0) ++ return -1; ++ ++ if (dram_detect_cap(dram, sdram_params, 0) != 0) ++ return -1; ++ ++ /* modify bw, cs related timing */ ++ pctl_remodify_sdram_params(&sdram_params->pctl_regs, cap_info, ++ sdram_params->base.dramtype); ++ /* reinit sdram by real dram cap */ ++ ret = sdram_init_(dram, sdram_params, 1); ++ if (ret != 0) ++ goto out; ++ ++ /* redetect cs1 row */ ++ sdram_detect_cs1_row(cap_info, sdram_params->base.dramtype); ++ if (cap_info->cs1_row) { ++ sys_reg = readl(&dram->pmugrf->os_reg[2]); ++ sys_reg3 = readl(&dram->pmugrf->os_reg[3]); ++ writel(sys_reg, &dram->pmugrf->os_reg[2]); ++ writel(sys_reg3, &dram->pmugrf->os_reg[3]); ++ } ++ ++ ret = sdram_detect_high_row(cap_info); ++ ++out: ++ return ret; ++} ++ ++struct px30_sdram_params *get_default_sdram_config(void) ++{ ++ sdram_configs[0].skew = &skew; ++ ++ return &sdram_configs[0]; ++} ++ ++int sdram_init(void) ++{ ++ struct px30_sdram_params *sdram_params; ++ int ret = 0; ++ ++ dram_info.phy = (void *)DDR_PHY_BASE_ADDR; ++ dram_info.pctl = (void *)DDRC_BASE_ADDR; ++ dram_info.grf = (void *)GRF_BASE_ADDR; ++ dram_info.cru = (void *)CRU_BASE_ADDR; ++ dram_info.msch = (void *)SERVER_MSCH0_BASE_ADDR; ++ dram_info.ddr_grf = (void *)DDR_GRF_BASE_ADDR; ++ dram_info.pmugrf = (void *)PMUGRF_BASE_ADDR; ++ ++ sdram_params = get_default_sdram_config(); ++ ret = sdram_init_detect(&dram_info, sdram_params); ++ if (ret) ++ return ret; ++ ++ return ret; ++} ++#endif /* CONFIG_TPL_BUILD */ +diff --git a/arch/arm/mach-rockchip/px30/syscon_px30.c b/arch/arm/mach-rockchip/px30/syscon_px30.c +new file mode 100644 +index 0000000000..0331491b40 +--- /dev/null ++++ b/arch/arm/mach-rockchip/px30/syscon_px30.c +@@ -0,0 +1,53 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * (C) Copyright 2017 Rockchip Electronics Co., Ltd ++ */ ++ ++#include <common.h> ++#include <dm.h> ++#include <syscon.h> ++#include <asm/arch-rockchip/clock.h> ++ ++static const struct udevice_id px30_syscon_ids[] = { ++ { .compatible = "rockchip,px30-pmu", .data = ROCKCHIP_SYSCON_PMU }, ++ { .compatible = "rockchip,px30-pmugrf", .data = ROCKCHIP_SYSCON_PMUGRF }, ++ { .compatible = "rockchip,px30-grf", .data = ROCKCHIP_SYSCON_GRF }, ++ { } ++}; ++ ++U_BOOT_DRIVER(syscon_px30) = { ++ .id = UCLASS_SYSCON, ++ .name = "px30_syscon", ++ .of_match = px30_syscon_ids, ++}; ++ ++#if CONFIG_IS_ENABLED(OF_PLATDATA) ++static int px30_syscon_bind_of_platdata(struct udevice *dev) ++{ ++ dev->driver_data = dev->driver->of_match->data; ++ debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data); ++ ++ return 0; ++} ++ ++U_BOOT_DRIVER(rockchip_px30_pmu) = { ++ .name = "rockchip_px30_pmu", ++ .id = UCLASS_SYSCON, ++ .of_match = px30_syscon_ids, ++ .bind = px30_syscon_bind_of_platdata, ++}; ++ ++U_BOOT_DRIVER(rockchip_px30_pmugrf) = { ++ .name = "rockchip_px30_pmugrf", ++ .id = UCLASS_SYSCON, ++ .of_match = px30_syscon_ids + 1, ++ .bind = px30_syscon_bind_of_platdata, ++}; ++ ++U_BOOT_DRIVER(rockchip_px30_grf) = { ++ .name = "rockchip_px30_grf", ++ .id = UCLASS_SYSCON, ++ .of_match = px30_syscon_ids + 2, ++ .bind = px30_syscon_bind_of_platdata, ++}; ++#endif + +From patchwork Thu Oct 24 23:28:03 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: =?utf-8?q?Heiko_St=C3=BCbner?= <heiko@sntech.de> +X-Patchwork-Id: 1183664 +X-Patchwork-Delegate: ykai007@gmail.com +Return-Path: <u-boot-bounces@lists.denx.de> +X-Original-To: incoming@patchwork.ozlabs.org +Delivered-To: patchwork-incoming@bilbo.ozlabs.org +Authentication-Results: ozlabs.org; + spf=none (no SPF record) smtp.mailfrom=lists.denx.de + (client-ip=81.169.180.215; helo=lists.denx.de; + envelope-from=u-boot-bounces@lists.denx.de; + receiver=<UNKNOWN>) +Authentication-Results: ozlabs.org; + dmarc=none (p=none dis=none) header.from=sntech.de +Received: from lists.denx.de (dione.denx.de [81.169.180.215]) + by ozlabs.org (Postfix) with ESMTP id 46zkVl3sCMz9sQm + for <incoming@patchwork.ozlabs.org>; + Fri, 25 Oct 2019 10:49:35 +1100 (AEDT) +Received: by lists.denx.de (Postfix, from userid 105) + id 3FFE4C21DD7; Thu, 24 Oct 2019 23:49:31 +0000 (UTC) +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de +X-Spam-Level: +X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable + autolearn_force=no version=3.4.0 +Received: from lists.denx.de (localhost [IPv6:::1]) + by lists.denx.de (Postfix) with ESMTP id C5CA9C21E1A; + Thu, 24 Oct 2019 23:48:20 +0000 (UTC) +Received: by lists.denx.de (Postfix, from userid 105) + id 1C9F3C21E16; Thu, 24 Oct 2019 23:48:19 +0000 (UTC) +Received: from gloria.sntech.de (gloria.sntech.de [185.11.138.130]) + by lists.denx.de (Postfix) with ESMTPS id 4A74FC21DD9 + for <u-boot@lists.denx.de>; Thu, 24 Oct 2019 23:47:55 +0000 (UTC) +Received: from ip5f5a6266.dynamic.kabel-deutschland.de ([95.90.98.102] + helo=phil.fritz.box) by gloria.sntech.de with esmtpsa + (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) + (Exim 4.89) (envelope-from <heiko@sntech.de>) + id 1iNmWh-0002cR-Qb; Fri, 25 Oct 2019 01:28:19 +0200 +From: Heiko Stuebner <heiko@sntech.de> +To: u-boot@lists.denx.de +Date: Fri, 25 Oct 2019 01:28:03 +0200 +Message-Id: <20191024232803.10338-13-heiko@sntech.de> +X-Mailer: git-send-email 2.23.0 +In-Reply-To: <20191024232803.10338-1-heiko@sntech.de> +References: <20191024232803.10338-1-heiko@sntech.de> +MIME-Version: 1.0 +Cc: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>, + joe.hershberger@ni.com, christoph.muellner@theobroma-systems.com +Subject: [U-Boot] [PATCH 12/12] rockchip: add px30-evb board +X-BeenThere: u-boot@lists.denx.de +X-Mailman-Version: 2.1.18 +Precedence: list +List-Id: U-Boot discussion <u-boot.lists.denx.de> +List-Unsubscribe: <https://lists.denx.de/options/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=unsubscribe> +List-Archive: <http://lists.denx.de/pipermail/u-boot/> +List-Post: <mailto:u-boot@lists.denx.de> +List-Help: <mailto:u-boot-request@lists.denx.de?subject=help> +List-Subscribe: <https://lists.denx.de/listinfo/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=subscribe> +Errors-To: u-boot-bounces@lists.denx.de +Sender: "U-Boot" <u-boot-bounces@lists.denx.de> + +From: Heiko Stuebner <heiko.stuebner@theobroma-systems.com> + +The px30 evb is an evaluation board for the px30 together with a dsi- +connected display. This adds board and config files for it. + +Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com> +Reviewed-by: Kever Yang<kever.yang@rock-chips.com> +--- + board/rockchip/evb_px30/Kconfig | 15 ++++ + board/rockchip/evb_px30/MAINTAINERS | 6 ++ + board/rockchip/evb_px30/Makefile | 7 ++ + board/rockchip/evb_px30/evb_px30.c | 4 + + configs/evb-px30_defconfig | 113 ++++++++++++++++++++++++++++ + include/configs/evb_px30.h | 19 +++++ + 6 files changed, 164 insertions(+) + create mode 100644 board/rockchip/evb_px30/Kconfig + create mode 100644 board/rockchip/evb_px30/MAINTAINERS + create mode 100644 board/rockchip/evb_px30/Makefile + create mode 100644 board/rockchip/evb_px30/evb_px30.c + create mode 100644 configs/evb-px30_defconfig + create mode 100644 include/configs/evb_px30.h + +diff --git a/board/rockchip/evb_px30/Kconfig b/board/rockchip/evb_px30/Kconfig +new file mode 100644 +index 0000000000..0042c8e4db +--- /dev/null ++++ b/board/rockchip/evb_px30/Kconfig +@@ -0,0 +1,15 @@ ++if TARGET_EVB_PX30 ++ ++config SYS_BOARD ++ default "evb_px30" ++ ++config SYS_VENDOR ++ default "rockchip" ++ ++config SYS_CONFIG_NAME ++ default "evb_px30" ++ ++config BOARD_SPECIFIC_OPTIONS # dummy ++ def_bool y ++ ++endif +diff --git a/board/rockchip/evb_px30/MAINTAINERS b/board/rockchip/evb_px30/MAINTAINERS +new file mode 100644 +index 0000000000..cf13f2419e +--- /dev/null ++++ b/board/rockchip/evb_px30/MAINTAINERS +@@ -0,0 +1,6 @@ ++EVB-PX30 ++M: Kever Yang <kever.yang@rock-chips.com> ++S: Maintained ++F: board/rockchip/evb_px30 ++F: include/configs/evb_px30.h ++F: configs/evb-px30_defconfig +diff --git a/board/rockchip/evb_px30/Makefile b/board/rockchip/evb_px30/Makefile +new file mode 100644 +index 0000000000..74b0b9f44f +--- /dev/null ++++ b/board/rockchip/evb_px30/Makefile +@@ -0,0 +1,7 @@ ++# ++# (C) Copyright 2017 Rockchip Electronics Co., Ltd ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++obj-y += evb_px30.o +diff --git a/board/rockchip/evb_px30/evb_px30.c b/board/rockchip/evb_px30/evb_px30.c +new file mode 100644 +index 0000000000..29464ae63e +--- /dev/null ++++ b/board/rockchip/evb_px30/evb_px30.c +@@ -0,0 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * (C) Copyright 2019 Rockchip Electronics Co., Ltd ++ */ +diff --git a/configs/evb-px30_defconfig b/configs/evb-px30_defconfig +new file mode 100644 +index 0000000000..d1cc1788c9 +--- /dev/null ++++ b/configs/evb-px30_defconfig +@@ -0,0 +1,113 @@ ++CONFIG_ARM=y ++CONFIG_ARCH_ROCKCHIP=y ++CONFIG_SYS_TEXT_BASE=0x00200000 ++CONFIG_SPL_LIBCOMMON_SUPPORT=y ++CONFIG_SPL_LIBGENERIC_SUPPORT=y ++CONFIG_SYS_MALLOC_F_LEN=0x2000 ++CONFIG_ROCKCHIP_PX30=y ++CONFIG_TARGET_EVB_PX30=y ++CONFIG_TPL_LIBGENERIC_SUPPORT=y ++CONFIG_SPL_DRIVERS_MISC_SUPPORT=y ++CONFIG_NR_DRAM_BANKS=1 ++CONFIG_SPL_STACK_R_ADDR=0x600000 ++CONFIG_DEBUG_UART_BASE=0xFF178000 ++CONFIG_DEBUG_UART_CLOCK=24000000 ++CONFIG_DEBUG_UART=y ++CONFIG_TPL_SYS_MALLOC_F_LEN=0x600 ++# CONFIG_ANDROID_BOOT_IMAGE is not set ++CONFIG_FIT=y ++CONFIG_FIT_VERBOSE=y ++CONFIG_SPL_LOAD_FIT=y ++# CONFIG_CONSOLE_MUX is not set ++CONFIG_DEFAULT_FDT_FILE="rockchip/px30-evb.dtb" ++CONFIG_MISC_INIT_R=y ++# CONFIG_DISPLAY_CPUINFO is not set ++CONFIG_DISPLAY_BOARDINFO_LATE=y ++CONFIG_SPL_BOUNCE_BUFFER_STATIC=y ++CONFIG_SPL_TEXT_BASE=0x00000000 ++# CONFIG_SPL_BOARD_INIT is not set ++CONFIG_SPL_BOOTROM_SUPPORT=y ++# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set ++# CONFIG_SPL_LEGACY_IMAGE_SUPPORT is not set ++CONFIG_SPL_STACK_R=y ++# CONFIG_TPL_BANNER_PRINT is not set ++CONFIG_SPL_CRC32_SUPPORT=y ++CONFIG_SPL_ATF=y ++# CONFIG_TPL_FRAMEWORK is not set ++# CONFIG_CMD_BOOTD is not set ++# CONFIG_CMD_ELF is not set ++# CONFIG_CMD_IMI is not set ++# CONFIG_CMD_XIMG is not set ++# CONFIG_CMD_LZMADEC is not set ++# CONFIG_CMD_UNZIP is not set ++# CONFIG_CMD_FLASH is not set ++CONFIG_CMD_GPT=y ++# CONFIG_CMD_LOADB is not set ++# CONFIG_CMD_LOADS is not set ++CONFIG_CMD_MMC=y ++CONFIG_CMD_USB=y ++CONFIG_CMD_USB_MASS_STORAGE=y ++# CONFIG_CMD_ITEST is not set ++# CONFIG_CMD_SETEXPR is not set ++# CONFIG_CMD_MISC is not set ++# CONFIG_SPL_DOS_PARTITION is not set ++# CONFIG_ISO_PARTITION is not set ++CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64 ++CONFIG_SPL_OF_CONTROL=y ++CONFIG_OF_LIVE=y ++CONFIG_DEFAULT_DEVICE_TREE="px30-evb" ++CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" ++CONFIG_ENV_IS_IN_MMC=y ++CONFIG_REGMAP=y ++CONFIG_SPL_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_SPL_SYSCON=y ++CONFIG_CLK=y ++CONFIG_SPL_CLK=y ++CONFIG_FASTBOOT_BUF_ADDR=0x800800 ++CONFIG_FASTBOOT_BUF_SIZE=0x04000000 ++CONFIG_FASTBOOT_FLASH=y ++CONFIG_FASTBOOT_FLASH_MMC_DEV=0 ++CONFIG_ROCKCHIP_GPIO=y ++CONFIG_SYS_I2C_ROCKCHIP=y ++CONFIG_MISC=y ++CONFIG_ROCKCHIP_OTP=y ++CONFIG_MMC_DW=y ++CONFIG_MMC_DW_ROCKCHIP=y ++CONFIG_DM_ETH=y ++CONFIG_ETH_DESIGNWARE=y ++CONFIG_GMAC_ROCKCHIP=y ++CONFIG_PHY_REALTEK=y ++CONFIG_PINCTRL=y ++CONFIG_DM_PMIC=y ++CONFIG_PMIC_RK8XX=y ++CONFIG_REGULATOR_PWM=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_REGULATOR_RK8XX=y ++CONFIG_PWM_ROCKCHIP=y ++CONFIG_RAM=y ++CONFIG_SPL_RAM=y ++CONFIG_DM_RESET=y ++# CONFIG_SPECIFY_CONSOLE_INDEX is not set ++# CONFIG_TPL_DM_SERIAL is not set ++CONFIG_DEBUG_UART_SHIFT=2 ++CONFIG_DEBUG_UART_SKIP_INIT=y ++CONFIG_SOUND=y ++CONFIG_SYSRESET=y ++CONFIG_OPTEE=y ++CONFIG_DM_THERMAL=y ++CONFIG_USB=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_GENERIC=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_GADGET_DWC2_OTG=y ++CONFIG_DM_VIDEO=y ++CONFIG_DISPLAY=y ++CONFIG_LCD=y ++CONFIG_USE_TINY_PRINTF=y ++CONFIG_SPL_TINY_MEMSET=y ++CONFIG_TPL_TINY_MEMSET=y ++CONFIG_LZ4=y ++CONFIG_LZO=y ++CONFIG_ERRNO_STR=y ++# CONFIG_EFI_LOADER is not set +diff --git a/include/configs/evb_px30.h b/include/configs/evb_px30.h +new file mode 100644 +index 0000000000..e761c7c519 +--- /dev/null ++++ b/include/configs/evb_px30.h +@@ -0,0 +1,19 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * (C) Copyright 2017 Rockchip Electronics Co., Ltd ++ */ ++ ++#ifndef __EVB_PX30_H ++#define __EVB_PX30_H ++ ++#include <configs/px30_common.h> ++ ++#define CONFIG_SYS_MMC_ENV_DEV 0 ++ ++#define ROCKCHIP_DEVICE_SETTINGS \ ++ "stdout=serial,vidconsole\0" \ ++ "stderr=serial,vidconsole\0" ++ ++#define CONFIG_SUPPORT_EMMC_RPMB ++ ++#endif + diff --git a/layers/meta-balena-nanopc-t4/recipes-bsp/u-boot/files/0001-lec-px30.patch b/layers/meta-balena-nanopc-t4/recipes-bsp/u-boot/files/0001-lec-px30.patch new file mode 100644 index 000000000..def3234da --- /dev/null +++ b/layers/meta-balena-nanopc-t4/recipes-bsp/u-boot/files/0001-lec-px30.patch @@ -0,0 +1,2310 @@ +From 7f97b6f09036cadff3055010b631b01b3b6caea2 Mon Sep 17 00:00:00 2001 +From: Alexandru Costache <alexandru@balena.io> +Date: Mon, 18 Jan 2021 09:37:18 +0100 +Subject: [PATCH] Add lec-px30 support + +Upstream-status: Inappropriate[backport] +Signed-off-by: David Tischler +--- + arch/arm/dts/lec-px30.dtsi | 2275 ++++++++++++++++++++++++++++++++++++ + configs/evb-px30_defconfig | 5 + + 2 files changed, 2280 insertions(+) + create mode 100644 arch/arm/dts/lec-px30.dtsi + +diff --git a/arch/arm/dts/lec-px30.dtsi b/arch/arm/dts/lec-px30.dtsi +new file mode 100644 +index 0000000000..5b830093d1 +--- /dev/null ++++ b/arch/arm/dts/lec-px30.dtsi +@@ -0,0 +1,2275 @@ ++/* ++ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd ++ * ++ * SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ */ ++ ++#include <dt-bindings/clock/px30-cru.h> ++#include <dt-bindings/gpio/gpio.h> ++#include <dt-bindings/interrupt-controller/arm-gic.h> ++#include <dt-bindings/interrupt-controller/irq.h> ++#include <dt-bindings/pinctrl/rockchip.h> ++#include <dt-bindings/power/px30-power.h> ++#include <dt-bindings/soc/rockchip,boot-mode.h> ++ ++/ { ++ compatible = "rockchip,lec-px30"; ++ ++ interrupt-parent = <&gic>; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ serial2 = &uart2; ++ i2c0 = &i2c0; ++ i2c1 = &i2c1; ++ i2c2 = &i2c2; ++ i2c3 = &i2c3; ++ }; ++ ++ cpus { ++ #address-cells = <2>; ++ #size-cells = <0>; ++ ++ cpu0: cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a35", "arm,armv8"; ++ reg = <0x0 0x0>; ++ enable-method = "psci"; ++ }; ++ ++ cpu1: cpu@1 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a35", "arm,armv8"; ++ reg = <0x0 0x1>; ++ enable-method = "psci"; ++ }; ++ cpu2: cpu@2 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a35", "arm,armv8"; ++ reg = <0x0 0x2>; ++ enable-method = "psci"; ++ }; ++ cpu3: cpu@3 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a35", "arm,armv8"; ++ reg = <0x0 0x3>; ++ enable-method = "psci"; ++ }; ++ }; ++ ++ arm-pmu { ++ compatible = "arm,cortex-a53-pmu"; ++ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; ++ }; ++ ++ dmc: dmc { ++ compatible = "rockchip,px30-dmc", "syscon"; ++ reg = <0x0 0xff2a0000 0x0 0x1000>; ++ }; ++ ++ display_subsystem: display-subsystem { ++ compatible = "rockchip,display-subsystem"; ++ ports = <&vopb_out>, <&vopl_out>; ++ status = "disabled"; ++ }; ++ ++ firmware { ++ optee { ++ compatible = "linaro,optee-tz"; ++ method = "smc"; ++ }; ++ }; ++ ++ gmac_clkin: external-gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <50000000>; ++ clock-output-names = "gmac_clkin"; ++ #clock-cells = <0>; ++ }; ++ ++ psci { ++ compatible = "arm,psci-1.0"; ++ method = "smc"; ++ }; ++ ++ timer { ++ compatible = "arm,armv8-timer"; ++ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, ++ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, ++ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, ++ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; ++ }; ++ ++ xin24m: xin24m { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <24000000>; ++ clock-output-names = "xin24m"; ++ }; ++ ++ pmu: power-management@ff000000 { ++ compatible = "rockchip,px30-pmu", "syscon", "simple-mfd"; ++ reg = <0x0 0xff000000 0x0 0x1000>; ++ ++ power: power-controller { ++ compatible = "rockchip,px30-power-controller"; ++ #power-domain-cells = <1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ ++ /* These power domains are grouped by VD_LOGIC */ ++ pd_usb@PX30_PD_USB { ++ reg = <PX30_PD_USB>; ++ clocks = <&cru HCLK_HOST>, ++ <&cru HCLK_OTG>, ++ <&cru SCLK_OTG_ADP>; ++ }; ++ pd_sdcard@PX30_PD_SDCARD { ++ reg = <PX30_PD_SDCARD>; ++ clocks = <&cru HCLK_SDMMC>, ++ <&cru SCLK_SDMMC>; ++ }; ++ pd_gmac@PX30_PD_GMAC { ++ reg = <PX30_PD_GMAC>; ++ clocks = <&cru ACLK_GMAC>, ++ <&cru PCLK_GMAC>, ++ <&cru SCLK_MAC_REF>, ++ <&cru SCLK_GMAC_RX_TX>; ++ }; ++ pd_mmc_nand@PX30_PD_MMC_NAND { ++ reg = <PX30_PD_MMC_NAND>; ++ clocks = <&cru HCLK_NANDC>, ++ <&cru HCLK_EMMC>, ++ <&cru HCLK_SDIO>, ++ <&cru HCLK_SFC>, ++ <&cru SCLK_EMMC>, ++ <&cru SCLK_NANDC>, ++ <&cru SCLK_SDIO>, ++ <&cru SCLK_SFC>; ++ }; ++ pd_vpu@PX30_PD_VPU { ++ reg = <PX30_PD_VPU>; ++ clocks = <&cru ACLK_VPU>, ++ <&cru HCLK_VPU>, ++ <&cru SCLK_CORE_VPU>; ++ }; ++ pd_vo@PX30_PD_VO { ++ reg = <PX30_PD_VO>; ++ clocks = <&cru ACLK_RGA>, ++ <&cru ACLK_VOPB>, ++ <&cru ACLK_VOPL>, ++ <&cru DCLK_VOPB>, ++ <&cru DCLK_VOPL>, ++ <&cru HCLK_RGA>, ++ <&cru HCLK_VOPB>, ++ <&cru HCLK_VOPL>, ++ <&cru PCLK_MIPI_DSI>, ++ <&cru SCLK_RGA_CORE>, ++ <&cru SCLK_VOPB_PWM>; ++ }; ++ pd_vi@PX30_PD_VI { ++ reg = <PX30_PD_VI>; ++ clocks = <&cru ACLK_CIF>, ++ <&cru ACLK_ISP>, ++ <&cru HCLK_CIF>, ++ <&cru HCLK_ISP>, ++ <&cru SCLK_ISP>; ++ }; ++ pd_gpu@PX30_PD_GPU { ++ reg = <PX30_PD_GPU>; ++ clocks = <&cru ACLK_GPU>; ++ }; ++ }; ++ }; ++ ++ pmugrf: syscon@ff010000 { ++ compatible = "rockchip,px30-pmugrf", "syscon", "simple-mfd"; ++ reg = <0x0 0xff010000 0x0 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ pmu_io_domains: io-domains { ++ compatible = "rockchip,px30-pmu-io-voltage-domain"; ++ status = "disabled"; ++ }; ++ ++ reboot-mode { ++ compatible = "syscon-reboot-mode"; ++ offset = <0x200>; ++ mode-bootloader = <BOOT_BL_DOWNLOAD>; ++ mode-charge = <BOOT_CHARGING>; ++ mode-fastboot = <BOOT_FASTBOOT>; ++ mode-loader = <BOOT_BL_DOWNLOAD>; ++ mode-normal = <BOOT_NORMAL>; ++ mode-recovery = <BOOT_RECOVERY>; ++ mode-ums = <BOOT_UMS>; ++ }; ++ ++ pmu_pvtm: pmu-pvtm { ++ compatible = "rockchip,px30-pmu-pvtm"; ++ clocks = <&pmucru SCLK_PVTM_PMU>; ++ clock-names = "pmu"; ++ status = "disabled"; ++ }; ++ }; ++ ++ uart0: serial@ff030000 { ++ compatible = "rockchip,px30-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xff030000 0x0 0x100>; ++ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_UART0_PMU>, <&cru PCLK_UART0_PMU>; ++ clock-names = "baudclk", "apb_pclk"; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ dmas = <&dmac 0>, <&dmac 1>; ++ #dma-cells = <2>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; ++ status = "disabled"; ++ }; ++ ++ i2s0_8ch: i2s@ff060000 { ++ compatible = "rockchip,px30-i2s", "rockchip,rk3066-i2s"; ++ reg = <0x0 0xff060000 0x0 0x1000>; ++ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_I2S0_TX>, <&cru HCLK_I2S0>; ++ clock-names = "i2s_clk", "i2s_hclk"; ++ dmas = <&dmac 16>, <&dmac 17>; ++ dma-names = "tx", "rx"; ++ status = "disabled"; ++ }; ++ ++ i2s1_2ch: i2s@ff070000 { ++ compatible = "rockchip,px30-i2s", "rockchip,rk3066-i2s"; ++ reg = <0x0 0xff070000 0x0 0x1000>; ++ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_I2S1>, <&cru HCLK_I2S1>; ++ clock-names = "i2s_clk", "i2s_hclk"; ++ dmas = <&dmac 18>, <&dmac 19>; ++ dma-names = "tx", "rx"; ++ status = "disabled"; ++ }; ++ ++ i2s2_2ch: i2s@ff080000 { ++ compatible = "rockchip,px30-i2s", "rockchip,rk3066-i2s"; ++ reg = <0x0 0xff080000 0x0 0x1000>; ++ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_I2S2>, <&cru HCLK_I2S2>; ++ clock-names = "i2s_clk", "i2s_hclk"; ++ dmas = <&dmac 20>, <&dmac 21>; ++ dma-names = "tx", "rx"; ++ status = "disabled"; ++ }; ++ ++ pdm: pdm@ff0a0000 { ++ compatible = "rockchip,pdm"; ++ reg = <0x0 0xff0a0000 0x0 0x1000>; ++ clocks = <&cru SCLK_PDM>, <&cru HCLK_PDM>; ++ clock-names = "pdm_clk", "pdm_hclk"; ++ dmas = <&dmac 24>; ++ dma-names = "rx"; ++ status = "disabled"; ++ }; ++ ++ gic: interrupt-controller@ff131000 { ++ compatible = "arm,gic-400"; ++ #interrupt-cells = <3>; ++ #address-cells = <0>; ++ interrupt-controller; ++ reg = <0x0 0xff131000 0 0x1000>, ++ <0x0 0xff132000 0 0x2000>, ++ <0x0 0xff134000 0 0x2000>, ++ <0x0 0xff136000 0 0x2000>; ++ interrupts = <GIC_PPI 9 ++ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; ++ }; ++ ++ grf: syscon@ff140000 { ++ compatible = "rockchip,px30-grf", "syscon", "simple-mfd"; ++ reg = <0x0 0xff140000 0x0 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ io_domains: io-domains { ++ compatible = "rockchip,px30-io-voltage-domain"; ++ status = "disabled"; ++ }; ++ }; ++ ++ core_grf: syscon@ff148000 { ++ compatible = "syscon", "simple-mfd"; ++ reg = <0x0 0xff148000 0x0 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ pvtm: pvtm { ++ compatible = "rockchip,px30-pvtm"; ++ clocks = <&cru SCLK_PVTM>; ++ clock-names = "core"; ++ status = "disabled"; ++ }; ++ }; ++ ++ uart1: serial@ff158000 { ++ compatible = "rockchip,px30-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xff158000 0x0 0x100>; ++ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>; ++ clock-names = "sclk_uart", "pclk_uart"; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ dmas = <&dmac 2>, <&dmac 3>; ++ #dma-cells = <2>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_xfer &uart1_cts &uart1_rts>; ++ status = "disabled"; ++ }; ++ ++ uart2: serial@ff160000 { ++ compatible = "rockchip,px30-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xff160000 0x0 0x100>; ++ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>; ++ clock-names = "baudclk", "apb_pclk"; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ dmas = <&dmac 4>, <&dmac 5>; ++ #dma-cells = <2>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2m0_xfer>; ++ status = "disabled"; ++ }; ++ ++ uart3: serial@ff168000 { ++ compatible = "rockchip,px30-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xff168000 0x0 0x100>; ++ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>; ++ clock-names = "baudclk", "apb_pclk"; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ dmas = <&dmac 6>, <&dmac 7>; ++ #dma-cells = <2>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart3m1_xfer &uart3m1_cts &uart3m1_rts>; ++ status = "disabled"; ++ }; ++ ++ uart4: serial@ff170000 { ++ compatible = "rockchip,px30-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xff170000 0x0 0x100>; ++ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>; ++ clock-names = "baudclk", "apb_pclk"; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ dmas = <&dmac 8>, <&dmac 9>; ++ #dma-cells = <2>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart4_xfer &uart4_cts &uart4_rts>; ++ status = "disabled"; ++ }; ++ ++ uart5: serial@ff178000 { ++ compatible = "rockchip,px30-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xff178000 0x0 0x100>; ++ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_UART5>, <&cru PCLK_UART5>; ++ clock-names = "baudclk", "apb_pclk"; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ dmas = <&dmac 10>, <&dmac 11>; ++ #dma-cells = <2>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart5_xfer &uart5_cts &uart5_rts>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@ff180000 { ++ compatible = "rockchip,rk3399-i2c"; ++ reg = <0x0 0xff180000 0x0 0x1000>; ++ clocks = <&cru SCLK_I2C0>, <&cru PCLK_I2C0>; ++ clock-names = "i2c", "pclk"; ++ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_xfer>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ i2c1: i2c@ff190000 { ++ compatible = "rockchip,rk3399-i2c"; ++ reg = <0x0 0xff190000 0x0 0x1000>; ++ clocks = <&cru SCLK_I2C1>, <&cru PCLK_I2C1>; ++ clock-names = "i2c", "pclk"; ++ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_xfer>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ i2c2: i2c@ff1a0000 { ++ compatible = "rockchip,rk3399-i2c"; ++ reg = <0x0 0xff1a0000 0x0 0x1000>; ++ clocks = <&cru SCLK_I2C2>, <&cru PCLK_I2C2>; ++ clock-names = "i2c", "pclk"; ++ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c2_xfer>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ i2c3: i2c@ff1b0000 { ++ compatible = "rockchip,rk3399-i2c"; ++ reg = <0x0 0xff1b0000 0x0 0x1000>; ++ clocks = <&cru SCLK_I2C3>, <&cru PCLK_I2C3>; ++ clock-names = "i2c", "pclk"; ++ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c3_xfer>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ spi0: spi@ff1d0000 { ++ compatible = "rockchip,px30-spi", "rockchip,rk3066-spi"; ++ reg = <0x0 0xff1d0000 0x0 0x1000>; ++ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>; ++ clock-names = "spiclk", "apb_pclk"; ++ dmas = <&dmac 12>, <&dmac 13>; ++ #dma-cells = <2>; ++ dma-names = "tx", "rx"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_clk &spi0_csn &spi0_miso &spi0_mosi>; ++ status = "disabled"; ++ }; ++ ++ spi1: spi@ff1d8000 { ++ compatible = "rockchip,px30-spi", "rockchip,rk3066-spi"; ++ reg = <0x0 0xff1d8000 0x0 0x1000>; ++ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>; ++ clock-names = "spiclk", "apb_pclk"; ++ dmas = <&dmac 14>, <&dmac 15>; ++ #dma-cells = <2>; ++ dma-names = "tx", "rx"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi1_clk &spi1_csn &spi1_miso &spi1_mosi>; ++ status = "disabled"; ++ }; ++ ++ wdt: watchdog@ff1e0000 { ++ compatible = "snps,dw-wdt"; ++ reg = <0x0 0xff1e0000 0x0 0x100>; ++ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; ++ status = "disabled"; ++ }; ++ ++ pwm0: pwm@ff200000 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff200000 0x0 0x10>; ++ #pwm-cells = <3>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm0_pin>; ++ clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>; ++ clock-names = "pwm", "pclk"; ++ status = "disabled"; ++ }; ++ ++ pwm1: pwm@ff200010 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff200010 0x0 0x10>; ++ #pwm-cells = <3>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm1_pin>; ++ clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>; ++ clock-names = "pwm", "pclk"; ++ status = "disabled"; ++ }; ++ ++ pwm2: pwm@ff200020 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff200020 0x0 0x10>; ++ #pwm-cells = <3>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm2_pin>; ++ clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>; ++ clock-names = "pwm", "pclk"; ++ status = "disabled"; ++ }; ++ ++ pwm3: pwm@ff200030 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff200030 0x0 0x10>; ++ #pwm-cells = <3>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm3_pin>; ++ clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>; ++ clock-names = "pwm", "pclk"; ++ status = "disabled"; ++ }; ++ ++ pwm4: pwm@ff208000 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff208000 0x0 0x10>; ++ #pwm-cells = <3>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm4_pin>; ++ clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>; ++ clock-names = "pwm", "pclk"; ++ status = "disabled"; ++ }; ++ ++ pwm5: pwm@ff208010 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff208010 0x0 0x10>; ++ #pwm-cells = <3>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm5_pin>; ++ clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>; ++ clock-names = "pwm", "pclk"; ++ status = "disabled"; ++ }; ++ ++ pwm6: pwm@ff208020 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff208020 0x0 0x10>; ++ #pwm-cells = <3>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm6_pin>; ++ clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>; ++ clock-names = "pwm", "pclk"; ++ status = "disabled"; ++ }; ++ ++ pwm7: pwm@ff208030 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff208030 0x0 0x10>; ++ #pwm-cells = <3>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm7_pin>; ++ clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>; ++ clock-names = "pwm", "pclk"; ++ status = "disabled"; ++ }; ++ ++ amba { ++ compatible = "simple-bus"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ ++ dmac: dmac@ff240000 { ++ compatible = "arm,pl330", "arm,primecell"; ++ reg = <0x0 0xff240000 0x0 0x4000>; ++ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru ACLK_DMAC>; ++ clock-names = "apb_pclk"; ++ #dma-cells = <1>; ++ peripherals-req-type-burst; ++ }; ++ }; ++ ++ tsadc: tsadc@ff280000 { ++ compatible = "rockchip,px30-tsadc"; ++ reg = <0x0 0xff280000 0x0 0x100>; ++ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>; ++ rockchip,grf = <&grf>; ++ clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>; ++ clock-names = "tsadc", "apb_pclk"; ++ assigned-clocks = <&cru SCLK_TSADC>; ++ assigned-clock-rates = <50000>; ++ resets = <&cru SRST_TSADC_P>; ++ reset-names = "tsadc-apb"; ++ pinctrl-names = "init", "default", "sleep"; ++ pinctrl-0 = <&tsadc_otp_gpio>; ++ pinctrl-1 = <&tsadc_otp_out>; ++ pinctrl-2 = <&tsadc_otp_gpio>; ++ #thermal-sensor-cells = <1>; ++ rockchip,hw-tshut-temp = <100000>; ++ status = "disabled"; ++ }; ++ ++ saradc: saradc@ff288000 { ++ compatible = "rockchip,px30-saradc", "rockchip,rk3399-saradc"; ++ reg = <0x0 0xff288000 0x0 0x100>; ++ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>; ++ #io-channel-cells = <1>; ++ clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>; ++ clock-names = "saradc", "apb_pclk"; ++ resets = <&cru SRST_SARADC_P>; ++ reset-names = "saradc-apb"; ++ status = "disabled"; ++ }; ++ ++ cru: clock-controller@ff2b0000 { ++ compatible = "rockchip,px30-cru"; ++ reg = <0x0 0xff2b0000 0x0 0x9000>; ++ rockchip,grf = <&grf>; ++ #clock-cells = <1>; ++ #reset-cells = <1>; ++ ++ assigned-clocks = ++ <&cru APLL_BOOST_H>, <&cru APLL_BOOST_L>, ++ <&cru PLL_NPLL>, <&cru PLL_CPLL>, ++ <&cru ARMCLK>; ++ assigned-clock-rates = ++ <1608000000>, <1416000000>, ++ <1188000000>, <1188000000>, ++ <816000000>; ++ }; ++ ++ pmucru: pmu-clock-controller@ff2bc000 { ++ compatible = "rockchip,px30-pmucru"; ++ reg = <0x0 0xff2bc000 0x0 0x1000>; ++ rockchip,grf = <&grf>; ++ #clock-cells = <1>; ++ #reset-cells = <1>; ++ ++ assigned-clocks = ++ <&pmucru PLL_GPLL>, <&pmucru PCLK_PMU_PRE>, ++ <&pmucru SCLK_WIFI_PMU>, <&cru ACLK_BUS_PRE>, ++ <&cru ACLK_PERI_PRE>, <&cru HCLK_BUS_PRE>, ++ <&cru HCLK_PERI_PRE>, <&cru PCLK_BUS_PRE>; ++ assigned-clock-rates = ++ <1200000000>, <100000000>, ++ <26000000>, <300000000>, ++ <300000000>, <150000000>, ++ <150000000>, <75000000>; ++ }; ++ ++ usb2phy_grf: syscon@ff2c0000 { ++ compatible = "rockchip,px30-usb2phy-grf", "syscon", ++ "simple-mfd"; ++ reg = <0x0 0xff2c0000 0x0 0x10000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ u2phy: usb2-phy@100 { ++ compatible = "rockchip,px30-usb2phy", ++ "rockchip,rk3328-usb2phy"; ++ reg = <0x100 0x10>; ++ clocks = <&pmucru SCLK_USBPHY_REF>; ++ clock-names = "phyclk"; ++ #clock-cells = <0>; ++ assigned-clocks = <&cru USB480M>; ++ assigned-clock-parents = <&u2phy>; ++ clock-output-names = "usb480m_phy"; ++ status = "disabled"; ++ ++ u2phy_host: host-port { ++ #phy-cells = <0>; ++ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "linestate"; ++ status = "disabled"; ++ }; ++ ++ u2phy_otg: otg-port { ++ #phy-cells = <0>; ++ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "otg-bvalid", "otg-id", ++ "linestate"; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ mipi_dphy: mipi-dphy@ff2e0000 { ++ compatible = "rockchip,px30-mipi-dphy"; ++ reg = <0x0 0xff2e0000 0x0 0x10000>; ++ clocks = <&cru SCLK_MIPIDSIPHY_REF>, <&cru PCLK_MIPIDSIPHY>; ++ clock-names = "ref", "pclk"; ++ clock-output-names = "mipi_dphy_pll"; ++ #clock-cells = <0>; ++ resets = <&cru SRST_MIPIDSIPHY_P>; ++ reset-names = "apb"; ++ power-domains = <&power PX30_PD_VO>; ++ #phy-cells = <0>; ++ rockchip,grf = <&grf>; ++ status = "disabled"; ++ }; ++ ++ lvds: lvds@ff2e0000 { ++ compatible = "rockchip,px30-lvds"; ++ reg = <0x0 0xff2e0000 0x0 0x100>, <0x0 0xff2e0100 0x0 0x100>; ++ reg-names = "mipi_lvds_phy", "mipi_lvds_ctl"; ++ clocks = <&cru PCLK_MIPIDSIPHY>, <&cru PCLK_MIPI_DSI>; ++ clock-names = "pclk_lvds", "pclk_lvds_ctl"; ++ power-domains = <&power PX30_PD_VO>; ++ rockchip,grf = <&grf>; ++ status = "disabled"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ lvds_in_vopl: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&vopl_out_lvds>; ++ }; ++ ++ lvds_in_vopb: endpoint@1 { ++ reg = <1>; ++ remote-endpoint = <&vopb_out_lvds>; ++ }; ++ }; ++ }; ++ }; ++ ++ usb20_otg: usb@ff300000 { ++ compatible = "rockchip,px30-usb", "rockchip,rk3066-usb", ++ "snps,dwc2"; ++ reg = <0x0 0xff300000 0x0 0x40000>; ++ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru HCLK_OTG>; ++ clock-names = "otg"; ++ dr_mode = "otg"; ++ g-np-tx-fifo-size = <16>; ++ g-rx-fifo-size = <275>; ++ g-tx-fifo-size = <256 128 128 64 64 32>; ++ g-use-dma; ++ phys = <&u2phy_otg>; ++ phy-names = "usb2-phy"; ++ status = "disabled"; ++ }; ++ ++ usb_host0_ehci: usb@ff340000 { ++ compatible = "generic-ehci"; ++ reg = <0x0 0xff340000 0x0 0x10000>; ++ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru HCLK_HOST>, <&cru HCLK_HOST_ARB>, ++ <&u2phy>; ++ clock-names = "usbhost", "arbiter", "utmi"; ++ phys = <&u2phy_host>; ++ phy-names = "usb"; ++ status = "disabled"; ++ }; ++ ++ usb_host0_ohci: usb@ff350000 { ++ compatible = "generic-ohci"; ++ reg = <0x0 0xff350000 0x0 0x10000>; ++ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru HCLK_HOST>, <&cru HCLK_HOST_ARB>, ++ <&u2phy>; ++ clock-names = "usbhost", "arbiter", "utmi"; ++ phys = <&u2phy_host>; ++ phy-names = "usb"; ++ }; ++ ++ gmac: ethernet@ff360000 { ++ compatible = "rockchip,px30-gmac"; ++ reg = <0x0 0xff360000 0x0 0x10000>; ++ rockchip,grf = <&grf>; ++ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "macirq"; ++ clocks = <&cru SCLK_GMAC>, <&cru SCLK_GMAC_RX_TX>, ++ <&cru SCLK_GMAC_RX_TX>, <&cru SCLK_MAC_REF>, ++ <&cru SCLK_MAC_REFOUT>, <&cru ACLK_GMAC>, ++ <&cru PCLK_GMAC>, <&cru SCLK_GMAC_RMII>; ++ clock-names = "stmmaceth", "mac_clk_rx", ++ "mac_clk_tx", "clk_mac_ref", ++ "clk_mac_refout", "aclk_mac", ++ "pclk_mac", "clk_mac_speed"; ++ phy-mode = "rmii"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rmii_pins &mac_refclk_12ma>; ++ resets = <&cru SRST_GMAC_A>; ++ reset-names = "stmmaceth"; ++ power-domains = <&power PX30_PD_GMAC>; ++ status = "disabled"; ++ }; ++ ++ sdmmc: dwmmc@ff370000 { ++ compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc"; ++ reg = <0x0 0xff370000 0x0 0x4000>; ++ max-frequency = <150000000>; ++ clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, ++ <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; ++ clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; ++ fifo-depth = <0x100>; ++ cd-gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_HIGH>; ++ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>; ++ status = "disabled"; ++ }; ++ ++ sdio: dwmmc@ff380000 { ++ compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc"; ++ reg = <0x0 0xff380000 0x0 0x4000>; ++ max-frequency = <150000000>; ++ clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>, ++ <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>; ++ clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; ++ fifo-depth = <0x100>; ++ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>; ++ status = "disabled"; ++ }; ++ ++ emmc: dwmmc@ff390000 { ++ compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc"; ++ reg = <0x0 0xff390000 0x0 0x4000>; ++ max-frequency = <150000000>; ++ clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>, ++ <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; ++ clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; ++ fifo-depth = <0x100>; ++ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; ++ status = "disabled"; ++ }; ++ ++ nandc0: nandc@ff3b0000 { ++ compatible = "rockchip,rk-nandc"; ++ reg = <0x0 0xff3b0000 0x0 0x4000>; ++ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>; ++ nandc_id = <0>; ++ clocks = <&cru SCLK_NANDC>, <&cru HCLK_NANDC>; ++ clock-names = "clk_nandc", "hclk_nandc"; ++ status = "disabled"; ++ }; ++ ++ gpu: gpu@ff400000 { ++ compatible = "arm,malit602", "arm,malit60x", "arm,malit6xx", "arm,mali-midgard"; ++ reg = <0x0 0xff400000 0x0 0x4000>; ++ ++ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "GPU", "MMU", "JOB"; ++ ++ clocks = <&cru ACLK_GPU>; ++ clock-names = "clk_mali"; ++ ++ status = "disabled"; ++ }; ++ ++ hevc: hevc_service@ff440000 { ++ compatible = "rockchip,hevc_sub"; ++ iommu_enabled = <1>; ++ reg = <0x0 0xff440000 0x0 0x400>; ++ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "irq_dec"; ++ dev_mode = <1>; ++ iommus = <&hevc_mmu>; ++ name = "hevc_service"; ++ allocator = <1>; ++ }; ++ ++ vpu: vpu_service@ff442000 { ++ compatible = "rockchip,vpu_sub"; ++ iommu_enabled = <1>; ++ reg = <0x0 0xff442000 0x0 0x800>; ++ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "irq_enc", "irq_dec"; ++ dev_mode = <0>; ++ iommus = <&vpu_mmu>; ++ name = "vpu_service"; ++ allocator = <1>; ++ }; ++ ++ vpu_combo: vpu_combo { ++ compatible = "rockchip,vpu_combo"; ++ subcnt = <2>; ++ rockchip,grf = <&grf>; ++ rockchip,sub = <&vpu>, <&hevc>; ++ clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>, <&cru SCLK_CORE_VPU>; ++ clock-names = "aclk_vcodec", "hclk_vcodec", "clk_core"; ++ resets = <&cru SRST_VPU_A>, <&cru SRST_VPU_H>, ++ <&cru SRST_VPU_NIU_A>, <&cru SRST_VPU_NIU_H>, ++ <&cru SRST_VPU_CORE>; ++ reset-names = "video_a", "video_h", "niu_a", "niu_h", ++ "video_core"; ++ mode_bit = <15>; ++ mode_ctrl = <0x410>; ++ name = "vpu_combo"; ++ status = "disabled"; ++ }; ++ ++ hevc_mmu: iommu@ff440440 { ++ compatible = "rockchip,iommu"; ++ reg = <0x0 0xff440440 0x0 0x40>, <0x0 0xff440480 0x0 0x40>; ++ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "hevc_mmu"; ++ clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>; ++ clock-names = "aclk", "hclk"; ++ #iommu-cells = <0>; ++ }; ++ ++ vpu_mmu: iommu@ff442800 { ++ compatible = "rockchip,iommu"; ++ reg = <0x0 0xff442800 0x0 0x100>; ++ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "vpu_mmu"; ++ clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>; ++ clock-names = "aclk", "hclk"; ++ #iommu-cells = <0>; ++ }; ++ ++ dsi: dsi@ff450000 { ++ compatible = "rockchip,px30-mipi-dsi"; ++ reg = <0x0 0xff450000 0x0 0x10000>; ++ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru PCLK_MIPI_DSI>, <&mipi_dphy>; ++ clock-names = "pclk", "hs_clk"; ++ resets = <&cru SRST_MIPIDSI_HOST_P>; ++ reset-names = "apb"; ++ phys = <&mipi_dphy>; ++ phy-names = "mipi_dphy"; ++ power-domains = <&power PX30_PD_VO>; ++ rockchip,grf = <&grf>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ ++ ports { ++ port { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ dsi_in_vopl: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&vopl_out_dsi>; ++ }; ++ ++ dsi_in_vopb: endpoint@1 { ++ reg = <1>; ++ remote-endpoint = <&vopb_out_dsi>; ++ }; ++ }; ++ }; ++ }; ++ ++ vopb: vop@ff460000 { ++ compatible = "rockchip,px30-vop-big"; ++ reg = <0x0 0xff460000 0x0 0x1fc>, <0x0 0xff460a00 0x0 0x400>; ++ reg-names = "regs", "gamma_lut"; ++ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru ACLK_VOPB>, <&cru DCLK_VOPB>, ++ <&cru HCLK_VOPB>; ++ clock-names = "aclk_vop", "dclk_vop", "hclk_vop"; ++ iommus = <&vopb_mmu>; ++ status = "disabled"; ++ ++ vopb_out: port { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ vopb_out_lvds: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&lvds_in_vopb>; ++ }; ++ ++ vopb_out_dsi: endpoint@1 { ++ reg = <1>; ++ remote-endpoint = <&dsi_in_vopb>; ++ }; ++ }; ++ }; ++ ++ vopb_mmu: iommu@ff460f00 { ++ compatible = "rockchip,iommu"; ++ reg = <0x0 0xff460f00 0x0 0x100>; ++ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "vopb_mmu"; ++ clocks = <&cru ACLK_VOPB>, <&cru HCLK_VOPB>; ++ clock-names = "aclk", "hclk"; ++ #iommu-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ vopl: vop@ff470000 { ++ compatible = "rockchip,px30-vop-lit"; ++ reg = <0x0 0xff470000 0x0 0x1fc>, <0x0 0xff470a00 0x0 0x400>; ++ reg-names = "regs", "gamma_lut"; ++ interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru ACLK_VOPL>, <&cru DCLK_VOPL>, ++ <&cru HCLK_VOPL>; ++ clock-names = "aclk_vop", "dclk_vop", "hclk_vop"; ++ iommus = <&vopl_mmu>; ++ status = "disabled"; ++ ++ vopl_out: port { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ vopl_out_lvds: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&lvds_in_vopl>; ++ }; ++ ++ vopl_out_dsi: endpoint@1 { ++ reg = <1>; ++ remote-endpoint = <&dsi_in_vopl>; ++ }; ++ }; ++ }; ++ ++ vopl_mmu: iommu@ff470f00 { ++ compatible = "rockchip,iommu"; ++ reg = <0x0 0xff470f00 0x0 0x100>; ++ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "vopl_mmu"; ++ clocks = <&cru ACLK_VOPL>, <&cru HCLK_VOPL>; ++ clock-names = "aclk", "hclk"; ++ #iommu-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ rk_rga: rk_rga@ff480000 { ++ compatible = "rockchip,rga2"; ++ //dev_mode = <1>; ++ reg = <0x0 0xff480000 0x0 0x1000>; ++ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru ACLK_RGA>, <&cru HCLK_RGA>; ++ clock-names = "aclk_rga", "hclk_rga"; ++ dma-coherent; ++ status = "disabled"; ++ }; ++ ++ cif: cif@ff490000 { ++ compatible = "rockchip,cif"; ++ reg = <0x0 0xff490000 0x0 0x200>; ++ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru ACLK_CIF>, <&cru HCLK_CIF>, <&cru PCLK_CIF>, <&cru SCLK_CIF_OUT>; ++ clock-names = "aclk_cif0", "hclk_cif0", "pclk_cif", "cif0_out"; ++ resets = <&cru SRST_CIF_A>, <&cru SRST_CIF_H>, <&cru SRST_CIF_PCLKIN>; ++ reset-names = "rst_cif_a", "rst_cif_h", "rst_cif_pclkin"; ++ pinctrl-names = "cif_pin_all"; ++ pinctrl-0 = <&dvp_d2d9_m0>; ++ status = "disabled"; ++ }; ++ ++ vip_mmu: iommu@ff490800{ ++ compatible = "rockchip,iommu"; ++ reg = <0x0 0xff490800 0x0 0x100>; ++ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "vip_mmu"; ++ clocks = <&cru ACLK_CIF>, <&cru HCLK_CIF>; ++ clock-names = "aclk", "hclk"; ++ rk_iommu,disable_reset_quirk; ++ #iommu-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ rk_isp: rk_isp@ff4a0000 { ++ compatible = "rockchip,px30-isp", "rockchip,isp"; ++ reg = <0x0 0xff4a0000 0x0 0x4000>; ++ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru ACLK_ISP>, <&cru HCLK_ISP>, <&cru SCLK_ISP>, <&cru SCLK_ISP>, ++ <&cru PCLK_ISP>, <&cru SCLK_CIF_OUT>, <&cru SCLK_CIF_OUT>, <&cru PCLK_MIPICSIPHY>; ++ clock-names = "aclk_isp", "hclk_isp", "clk_isp", "clk_isp_jpe", ++ "pclkin_isp", "clk_cif_pll", "clk_cif_out", "pclk_dphyrx"; ++ resets = <&cru SRST_ISP>, <&cru SRST_MIPICSIPHY_P>; ++ reset-names = "rst_isp", "rst_mipicsiphy"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cif_clkout_m0>; ++ rockchip,isp,mipiphy = <0>; ++ rockchip,isp,csiphy,reg = <0xff2f0000 0x4000>; ++ rockchip,grf = <&grf>; ++ rockchip,cru = <&cru>; ++ rockchip,isp,iommu-enable = <1>; ++ iommus = <&isp_mmu>; ++ status = "disabled"; ++ }; ++ ++ isp_mmu: iommu@ff4a8000 { ++ compatible = "rockchip,iommu"; ++ reg = <0x0 0xff4a8000 0x0 0x100>; ++ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "isp_mmu"; ++ clocks = <&cru ACLK_ISP>, <&cru HCLK_ISP>; ++ clock-names = "aclk", "hclk"; ++ rk_iommu,disable_reset_quirk; ++ #iommu-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ qos_gmac: qos@ff518000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff518000 0x0 0x20>; ++ }; ++ ++ qos_gpu: qos@ff520000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff520000 0x0 0x20>; ++ }; ++ ++ qos_sdmmc: qos@ff52c000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff52c000 0x0 0x20>; ++ }; ++ ++ qos_emmc: qos@ff538000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff538000 0x0 0x20>; ++ }; ++ ++ qos_nand: qos@ff538080 { ++ compatible = "syscon"; ++ reg = <0x0 0xff538080 0x0 0x20>; ++ }; ++ ++ qos_sdio: qos@ff538100 { ++ compatible = "syscon"; ++ reg = <0x0 0xff538100 0x0 0x20>; ++ }; ++ ++ qos_sfc: qos@ff538180 { ++ compatible = "syscon"; ++ reg = <0x0 0xff538180 0x0 0x20>; ++ }; ++ ++ qos_usb_host: qos@ff540000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff540000 0x0 0x20>; ++ }; ++ ++ qos_usb_otg: qos@ff540080 { ++ compatible = "syscon"; ++ reg = <0x0 0xff540080 0x0 0x20>; ++ }; ++ ++ qos_isp_128: qos@ff548000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff548000 0x0 0x20>; ++ }; ++ ++ qos_isp_rd: qos@ff548080 { ++ compatible = "syscon"; ++ reg = <0x0 0xff548080 0x0 0x20>; ++ }; ++ ++ qos_isp_wr: qos@ff548100 { ++ compatible = "syscon"; ++ reg = <0x0 0xff548100 0x0 0x20>; ++ }; ++ ++ qos_isp_m1: qos@ff548180 { ++ compatible = "syscon"; ++ reg = <0x0 0xff548180 0x0 0x20>; ++ }; ++ ++ qos_vip: qos@ff548200 { ++ compatible = "syscon"; ++ reg = <0x0 0xff548200 0x0 0x20>; ++ }; ++ ++ qos_rga_rd: qos@ff550000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff550000 0x0 0x20>; ++ }; ++ ++ qos_rga_wr: qos@ff550080 { ++ compatible = "syscon"; ++ reg = <0x0 0xff550080 0x0 0x20>; ++ }; ++ ++ qos_vop_m0: qos@ff550100 { ++ compatible = "syscon"; ++ reg = <0x0 0xff550100 0x0 0x20>; ++ }; ++ ++ qos_vop_m1: qos@ff550180 { ++ compatible = "syscon"; ++ reg = <0x0 0xff550180 0x0 0x20>; ++ }; ++ ++ qos_vpu: qos@ff558000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff558000 0x0 0x20>; ++ }; ++ ++ qos_vpu_r128: qos@ff558080 { ++ compatible = "syscon"; ++ reg = <0x0 0xff558080 0x0 0x20>; ++ }; ++ ++ pinctrl: pinctrl { ++ compatible = "rockchip,px30-pinctrl"; ++ rockchip,grf = <&grf>; ++ rockchip,pmu = <&pmugrf>; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ ++ gpio0: gpio0@ff040000 { ++ compatible = "rockchip,gpio-bank"; ++ reg = <0x0 0xff040000 0x0 0x100>; ++ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru PCLK_GPIO0_PMU>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ gpio1: gpio1@ff250000 { ++ compatible = "rockchip,gpio-bank"; ++ reg = <0x0 0xff250000 0x0 0x100>; ++ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru PCLK_GPIO1>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ gpio2: gpio2@ff260000 { ++ compatible = "rockchip,gpio-bank"; ++ reg = <0x0 0xff260000 0x0 0x100>; ++ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru PCLK_GPIO2>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ gpio3: gpio3@ff270000 { ++ compatible = "rockchip,gpio-bank"; ++ reg = <0x0 0xff270000 0x0 0x100>; ++ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru PCLK_GPIO3>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ pcfg_pull_up: pcfg-pull-up { ++ bias-pull-up; ++ }; ++ ++ pcfg_pull_down: pcfg-pull-down { ++ bias-pull-down; ++ }; ++ ++ pcfg_pull_none: pcfg-pull-none { ++ bias-disable; ++ }; ++ ++ pcfg_pull_none_2ma: pcfg-pull-none-2ma { ++ bias-disable; ++ drive-strength = <2>; ++ }; ++ ++ pcfg_pull_up_2ma: pcfg-pull-up-2ma { ++ bias-pull-up; ++ drive-strength = <2>; ++ }; ++ ++ pcfg_pull_up_4ma: pcfg-pull-up-4ma { ++ bias-pull-up; ++ drive-strength = <4>; ++ }; ++ ++ pcfg_pull_none_4ma: pcfg-pull-none-4ma { ++ bias-disable; ++ drive-strength = <4>; ++ }; ++ ++ pcfg_pull_down_4ma: pcfg-pull-down-4ma { ++ bias-pull-down; ++ drive-strength = <4>; ++ }; ++ ++ pcfg_pull_none_8ma: pcfg-pull-none-8ma { ++ bias-disable; ++ drive-strength = <8>; ++ }; ++ ++ pcfg_pull_up_8ma: pcfg-pull-up-8ma { ++ bias-pull-up; ++ drive-strength = <8>; ++ }; ++ ++ pcfg_pull_none_12ma: pcfg-pull-none-12ma { ++ bias-disable; ++ drive-strength = <12>; ++ }; ++ ++ pcfg_pull_up_12ma: pcfg-pull-up-12ma { ++ bias-pull-up; ++ drive-strength = <12>; ++ }; ++ ++ pcfg_pull_none_smt: pcfg-pull-none-smt { ++ bias-disable; ++ input-schmitt-enable; ++ }; ++ ++ pcfg_output_high: pcfg-output-high { ++ output-high; ++ }; ++ ++ pcfg_output_low: pcfg-output-low { ++ output-low; ++ }; ++ ++ pcfg_input_high: pcfg-input-high { ++ bias-pull-up; ++ input-enable; ++ }; ++ ++ pcfg_input: pcfg-input { ++ input-enable; ++ }; ++ ++ i2c0 { ++ i2c0_xfer: i2c0-xfer { ++ rockchip,pins = ++ <0 RK_PB0 RK_FUNC_1 &pcfg_pull_none_smt>, ++ <0 RK_PB1 RK_FUNC_1 &pcfg_pull_none_smt>; ++ }; ++ }; ++ ++ i2c1 { ++ i2c1_xfer: i2c1-xfer { ++ rockchip,pins = ++ <0 RK_PC2 RK_FUNC_1 &pcfg_pull_none_smt>, ++ <0 RK_PC3 RK_FUNC_1 &pcfg_pull_none_smt>; ++ }; ++ }; ++ ++ i2c2 { ++ i2c2_xfer: i2c2-xfer { ++ rockchip,pins = ++ <2 RK_PB7 RK_FUNC_2 &pcfg_pull_none_smt>, ++ <2 RK_PC0 RK_FUNC_2 &pcfg_pull_none_smt>; ++ }; ++ }; ++ ++ i2c3 { ++ i2c3_xfer: i2c3-xfer { ++ rockchip,pins = ++ <1 RK_PB4 RK_FUNC_4 &pcfg_pull_none_smt>, ++ <1 RK_PB5 RK_FUNC_4 &pcfg_pull_none_smt>; ++ }; ++ }; ++ ++ tsadc { ++ tsadc_otp_gpio: tsadc-otp-gpio { ++ rockchip,pins = ++ <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ tsadc_otp_out: tsadc-otp-out { ++ rockchip,pins = ++ <0 RK_PA6 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ uart0 { ++ uart0_xfer: uart0-xfer { ++ rockchip,pins = ++ <0 RK_PB2 RK_FUNC_1 &pcfg_pull_up>, ++ <0 RK_PB3 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ uart0_cts: uart0-cts { ++ rockchip,pins = ++ <0 RK_PB4 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ uart0_rts: uart0-rts { ++ rockchip,pins = ++ <0 RK_PB5 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ uart0_rts_gpio: uart0-rts-gpio { ++ rockchip,pins = ++ <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ uart1 { ++ uart1_xfer: uart1-xfer { ++ rockchip,pins = ++ <1 RK_PC1 RK_FUNC_1 &pcfg_pull_up>, ++ <1 RK_PC0 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ uart1_cts: uart1-cts { ++ rockchip,pins = ++ <1 RK_PC2 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ uart1_rts: uart1-rts { ++ rockchip,pins = ++ <1 RK_PC3 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ uart1_rts_gpio: uart1-rts-gpio { ++ rockchip,pins = ++ <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ uart2-m0 { ++ uart2m0_xfer: uart2m0-xfer { ++ rockchip,pins = ++ <1 RK_PD2 RK_FUNC_2 &pcfg_pull_up>, ++ <1 RK_PD3 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ }; ++ ++ uart2-m1 { ++ uart2m1_xfer: uart2m1-xfer { ++ rockchip,pins = ++ <2 RK_PB4 RK_FUNC_2 &pcfg_pull_up>, ++ <2 RK_PB6 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ }; ++ ++ uart3-m0 { ++ uart3m0_xfer: uart3m0-xfer { ++ rockchip,pins = ++ <0 RK_PC0 RK_FUNC_2 &pcfg_pull_up>, ++ <0 RK_PC1 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ uart3m0_cts: uart3m0-cts { ++ rockchip,pins = ++ <0 RK_PC2 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ uart3m0_rts: uart3m0-rts { ++ rockchip,pins = ++ <0 RK_PC3 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ uart3m0_rts_gpio: uart3m0-rts-gpio { ++ rockchip,pins = ++ <0 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ uart3-m1 { ++ uart3m1_xfer: uart3m1-xfer { ++ rockchip,pins = ++ <1 RK_PB6 RK_FUNC_2 &pcfg_pull_up>, ++ <1 RK_PB7 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ uart3m1_cts: uart3m1-cts { ++ rockchip,pins = ++ <1 RK_PB4 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ uart3m1_rts: uart3m1-rts { ++ rockchip,pins = ++ <1 RK_PB5 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ uart3m1_rts_gpio: uart3m1-rts-gpio { ++ rockchip,pins = ++ <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ uart4 { ++ ++ uart4_xfer: uart4-xfer { ++ rockchip,pins = ++ <1 RK_PD4 RK_FUNC_2 &pcfg_pull_up>, ++ <1 RK_PD5 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ uart4_cts: uart4-cts { ++ rockchip,pins = ++ <1 RK_PD6 RK_FUNC_2 &pcfg_pull_none>; ++ ++ }; ++ ++ uart4_rts: uart4-rts { ++ rockchip,pins = ++ <1 RK_PD7 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ }; ++ ++ uart5 { ++ ++ uart5_xfer: uart5-xfer { ++ rockchip,pins = ++ <3 RK_PA2 RK_FUNC_4 &pcfg_pull_up>, ++ <3 RK_PA1 RK_FUNC_4 &pcfg_pull_none>; ++ }; ++ ++ uart5_cts: uart5-cts { ++ rockchip,pins = ++ <3 RK_PA3 RK_FUNC_4 &pcfg_pull_none>; ++ ++ }; ++ ++ uart5_rts: uart5-rts { ++ rockchip,pins = ++ <3 RK_PA5 RK_FUNC_4 &pcfg_pull_none>; ++ }; ++ }; ++ ++ spi0 { ++ spi0_clk: spi0-clk { ++ rockchip,pins = ++ <1 RK_PB7 RK_FUNC_3 &pcfg_pull_up>; ++ }; ++ ++ spi0_csn: spi0-csn { ++ rockchip,pins = ++ <1 RK_PB6 RK_FUNC_3 &pcfg_pull_up>; ++ }; ++ ++ spi0_miso: spi0-miso { ++ rockchip,pins = ++ <1 RK_PB5 RK_FUNC_3 &pcfg_pull_up>; ++ }; ++ ++ spi0_mosi: spi0-mosi { ++ rockchip,pins = ++ <1 RK_PB4 RK_FUNC_3 &pcfg_pull_up>; ++ }; ++ }; ++ ++ spi1 { ++ spi1_clk: spi1-clk { ++ rockchip,pins = ++ <3 RK_PB7 RK_FUNC_4 &pcfg_pull_up>; ++ }; ++ ++ spi1_csn: spi1-csn { ++ rockchip,pins = ++ <3 RK_PB1 RK_FUNC_4 &pcfg_pull_up>; ++ }; ++ ++ spi1_miso: spi1-miso { ++ rockchip,pins = ++ <3 RK_PB6 RK_FUNC_4 &pcfg_pull_up>; ++ }; ++ ++ spi1_mosi: spi1-mosi { ++ rockchip,pins = ++ <3 RK_PB4 RK_FUNC_4 &pcfg_pull_up>; ++ }; ++ }; ++ ++ pdm { ++ pdm_clk0m0: pdm-clk0m0 { ++ rockchip,pins = ++ <3 RK_PC6 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ pdm_clk0m1: pdm-clk0m1 { ++ rockchip,pins = ++ <2 RK_PC6 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ pdm_clk1: pdm-clk1 { ++ rockchip,pins = ++ <3 RK_PC7 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ pdm_sdi0m0: pdm-sdi0m0 { ++ rockchip,pins = ++ <3 RK_PD3 RK_FUNC_4 &pcfg_pull_none>; ++ }; ++ ++ pdm_sdi0m1: pdm-sdi0m1 { ++ rockchip,pins = ++ <2 RK_PC5 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ pdm_sdi1: pdm-sdi1 { ++ rockchip,pins = ++ <3 RK_PD0 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ pdm_sdi2: pdm-sdi2 { ++ rockchip,pins = ++ <3 RK_PD1 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ pdm_sdi3: pdm-sdi3 { ++ rockchip,pins = ++ <3 RK_PD2 RK_FUNC_4 &pcfg_pull_none>; ++ }; ++ ++ pdm_clk0m0_sleep: pdm-clk0m0-sleep { ++ rockchip,pins = ++ <3 RK_PC6 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ ++ pdm_clk0m_sleep1: pdm-clk0m1-sleep { ++ rockchip,pins = ++ <2 RK_PC6 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ ++ pdm_clk1_sleep: pdm-clk1-sleep { ++ rockchip,pins = ++ <3 RK_PC7 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ ++ pdm_sdi0m0_sleep: pdm-sdi0m0-sleep { ++ rockchip,pins = ++ <3 RK_PD3 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ ++ pdm_sdi0m1_sleep: pdm-sdi0m1-sleep { ++ rockchip,pins = ++ <2 RK_PC5 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ ++ pdm_sdi1_sleep: pdm-sdi1-sleep { ++ rockchip,pins = ++ <3 RK_PD0 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ ++ pdm_sdi2_sleep: pdm-sdi2-sleep { ++ rockchip,pins = ++ <3 RK_PD1 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ ++ pdm_sdi3_sleep: pdm-sdi3-sleep { ++ rockchip,pins = ++ <3 RK_PD2 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ }; ++ ++ i2s0 { ++ i2s0_8ch_mclk: i2s0-8ch-mclk { ++ rockchip,pins = ++ <3 RK_PC1 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sclktx: i2s0-8ch-sclktx { ++ rockchip,pins = ++ <3 RK_PC3 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sclkrx: i2s0-8ch-sclkrx { ++ rockchip,pins = ++ <3 RK_PB4 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_lrcktx: i2s0-8ch-lrcktx { ++ rockchip,pins = ++ <3 RK_PC2 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_lrckrx: i2s0-8ch-lrckrx { ++ rockchip,pins = ++ <3 RK_PB5 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdo: i2s0-8ch-sdo { ++ rockchip,pins = ++ <3 RK_PD2 RK_FUNC_3 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdo0: i2s0-8ch-sdo0 { ++ rockchip,pins = ++ <3 RK_PC4 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdo1: i2s0-8ch-sdo1 { ++ rockchip,pins = ++ <3 RK_PC0 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdo2: i2s0-8ch-sdo2 { ++ rockchip,pins = ++ <3 RK_PB7 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdo3: i2s0-8ch-sdo3 { ++ rockchip,pins = ++ <3 RK_PB6 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdi: i2s0-8ch-sdi { ++ rockchip,pins = ++ <3 RK_PD3 RK_FUNC_3 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdi0: i2s0-8ch-sdi0 { ++ rockchip,pins = ++ <3 RK_PC5 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdi1: i2s0-8ch-sdi1 { ++ rockchip,pins = ++ <3 RK_PB3 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdi2: i2s0-8ch-sdi2 { ++ rockchip,pins = ++ <3 RK_PB1 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdi3: i2s0-8ch-sdi3 { ++ rockchip,pins = ++ <3 RK_PB0 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ }; ++ ++ i2s1 { ++ i2s1_2ch_mclk: i2s1-2ch-mclk { ++ rockchip,pins = ++ <2 RK_PC3 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ i2s1_2ch_sclk: i2s1-2ch-sclk { ++ rockchip,pins = ++ <2 RK_PC2 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ i2s1_2ch_lrck: i2s1-2ch-lrck { ++ rockchip,pins = ++ <2 RK_PC1 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ i2s1_2ch_sdi: i2s1-2ch-sdi { ++ rockchip,pins = ++ <2 RK_PC5 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ i2s1_2ch_sdo: i2s1-2ch-sdo { ++ rockchip,pins = ++ <2 RK_PC4 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ i2s2 { ++ i2s2_2ch_mclk: i2s2-2ch-mclk { ++ rockchip,pins = ++ <3 RK_PA1 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s2_2ch_sclk: i2s2-2ch-sclk { ++ rockchip,pins = ++ <3 RK_PA2 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s2_2ch_lrck: i2s2-2ch-lrck { ++ rockchip,pins = ++ <3 RK_PA3 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s2_2ch_sdi: i2s2-2ch-sdi { ++ rockchip,pins = ++ <3 RK_PA5 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s2_2ch_sdo: i2s2-2ch-sdo { ++ rockchip,pins = ++ <3 RK_PA7 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ }; ++ ++ sdmmc { ++ sdmmc_clk: sdmmc-clk { ++ rockchip,pins = ++ <1 RK_PD6 RK_FUNC_1 &pcfg_pull_none_8ma>; ++ }; ++ ++ sdmmc_cmd: sdmmc-cmd { ++ rockchip,pins = ++ <1 RK_PD7 RK_FUNC_1 &pcfg_pull_up_8ma>; ++ }; ++ ++ sdmmc_det: sdmmc-det { ++ rockchip,pins = ++ <0 RK_PA3 RK_FUNC_1 &pcfg_pull_up_8ma>; ++ }; ++ ++ sdmmc_bus1: sdmmc-bus1 { ++ rockchip,pins = ++ <1 RK_PD2 RK_FUNC_1 &pcfg_pull_up_8ma>; ++ }; ++ ++ sdmmc_bus4: sdmmc-bus4 { ++ rockchip,pins = ++ <1 RK_PD2 RK_FUNC_1 &pcfg_pull_up_8ma>, ++ <1 RK_PD3 RK_FUNC_1 &pcfg_pull_up_8ma>, ++ <1 RK_PD4 RK_FUNC_1 &pcfg_pull_up_8ma>, ++ <1 RK_PD5 RK_FUNC_1 &pcfg_pull_up_8ma>; ++ }; ++ ++ sdmmc_gpio: sdmmc-gpio { ++ rockchip,pins = ++ <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up_4ma>, ++ <1 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up_4ma>, ++ <1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up_4ma>, ++ <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_up_4ma>, ++ <1 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up_4ma>, ++ <1 RK_PD7 RK_FUNC_GPIO &pcfg_pull_up_4ma>; ++ }; ++ }; ++ ++ sdio { ++ sdio_clk: sdio-clk { ++ rockchip,pins = ++ <1 RK_PC5 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ sdio_cmd: sdio-cmd { ++ rockchip,pins = ++ <1 RK_PC4 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ ++ sdio_bus4: sdio-bus4 { ++ rockchip,pins = ++ <1 RK_PC6 RK_FUNC_1 &pcfg_pull_up>, ++ <1 RK_PC7 RK_FUNC_1 &pcfg_pull_up>, ++ <1 RK_PD0 RK_FUNC_1 &pcfg_pull_up>, ++ <1 RK_PD1 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ ++ sdio_gpio: sdio-gpio { ++ rockchip,pins = ++ <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PC7 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ emmc { ++ emmc_clk: emmc-clk { ++ rockchip,pins = ++ <1 RK_PB1 RK_FUNC_2 &pcfg_pull_none_8ma>; ++ }; ++ ++ emmc_cmd: emmc-cmd { ++ rockchip,pins = ++ <1 RK_PB2 RK_FUNC_2 &pcfg_pull_up_8ma>; ++ }; ++ ++ emmc_pwren: emmc-pwren { ++ rockchip,pins = ++ <1 RK_PB0 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ emmc_rstnout: emmc-rstnout { ++ rockchip,pins = ++ <1 RK_PB3 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ emmc_bus1: emmc-bus1 { ++ rockchip,pins = ++ <1 RK_PA0 RK_FUNC_2 &pcfg_pull_up_8ma>; ++ }; ++ ++ emmc_bus4: emmc-bus4 { ++ rockchip,pins = ++ <1 RK_PA0 RK_FUNC_2 &pcfg_pull_up_8ma>, ++ <1 RK_PA1 RK_FUNC_2 &pcfg_pull_up_8ma>, ++ <1 RK_PA2 RK_FUNC_2 &pcfg_pull_up_8ma>, ++ <1 RK_PA3 RK_FUNC_2 &pcfg_pull_up_8ma>; ++ }; ++ ++ emmc_bus8: emmc-bus8 { ++ rockchip,pins = ++ <1 RK_PA0 RK_FUNC_2 &pcfg_pull_up_8ma>, ++ <1 RK_PA1 RK_FUNC_2 &pcfg_pull_up_8ma>, ++ <1 RK_PA2 RK_FUNC_2 &pcfg_pull_up_8ma>, ++ <1 RK_PA3 RK_FUNC_2 &pcfg_pull_up_8ma>, ++ <1 RK_PA4 RK_FUNC_2 &pcfg_pull_up_8ma>, ++ <1 RK_PA5 RK_FUNC_2 &pcfg_pull_up_8ma>, ++ <1 RK_PA6 RK_FUNC_2 &pcfg_pull_up_8ma>, ++ <1 RK_PA7 RK_FUNC_2 &pcfg_pull_up_8ma>; ++ }; ++ }; ++ ++ flash { ++ flash_cs0: flash-cs0 { ++ rockchip,pins = ++ <1 RK_PB0 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ flash_rdy: flash-rdy { ++ rockchip,pins = ++ <1 RK_PB1 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ flash_dqs: flash-dqs { ++ rockchip,pins = ++ <1 RK_PB2 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ flash_ale: flash-ale { ++ rockchip,pins = ++ <1 RK_PB3 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ flash_cle: flash-cle { ++ rockchip,pins = ++ <1 RK_PB4 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ flash_wrn: flash-wrn { ++ rockchip,pins = ++ <1 RK_PB5 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ flash_csl: flash-csl { ++ rockchip,pins = ++ <1 RK_PB6 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ flash_rdn: flash-rdn { ++ rockchip,pins = ++ <1 RK_PB7 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ flash_bus8: flash-bus8 { ++ rockchip,pins = ++ <1 RK_PA0 RK_FUNC_1 &pcfg_pull_up_12ma>, ++ <1 RK_PA1 RK_FUNC_1 &pcfg_pull_up_12ma>, ++ <1 RK_PA2 RK_FUNC_1 &pcfg_pull_up_12ma>, ++ <1 RK_PA3 RK_FUNC_1 &pcfg_pull_up_12ma>, ++ <1 RK_PA4 RK_FUNC_1 &pcfg_pull_up_12ma>, ++ <1 RK_PA5 RK_FUNC_1 &pcfg_pull_up_12ma>, ++ <1 RK_PA6 RK_FUNC_1 &pcfg_pull_up_12ma>, ++ <1 RK_PA7 RK_FUNC_1 &pcfg_pull_up_12ma>; ++ }; ++ }; ++ ++ lcdc { ++ lcdc_rgb_dclk_pin: lcdc-rgb-dclk-pin { ++ rockchip,pins = ++ <3 RK_PA0 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ lcdc_rgb_m0_hsync_pin: lcdc-rgb-m0-hsync-pin { ++ rockchip,pins = ++ <3 RK_PA1 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ lcdc_rgb_m0_vsync_pin: lcdc-rgb-m0-vsync-pin { ++ rockchip,pins = ++ <3 RK_PA2 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ lcdc_rgb_m0_den_pin: lcdc-rgb-m0-den-pin { ++ rockchip,pins = ++ <3 RK_PA3 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ lcdc_rgb888_m0_data_pins: lcdc-rgb888-m0-data-pins { ++ rockchip,pins = ++ <3 RK_PA7 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d3 */ ++ <3 RK_PA6 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d2 */ ++ <3 RK_PA5 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d1 */ ++ <3 RK_PA4 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d0 */ ++ <3 RK_PB3 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d7 */ ++ <3 RK_PB2 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d6 */ ++ <3 RK_PB1 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d5 */ ++ <3 RK_PB0 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d4 */ ++ <3 RK_PB7 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d11 */ ++ <3 RK_PB6 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d10 */ ++ <3 RK_PB5 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d9 */ ++ <3 RK_PB4 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d8 */ ++ <3 RK_PC3 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d15 */ ++ <3 RK_PC2 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d14 */ ++ <3 RK_PC1 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d13 */ ++ <3 RK_PC0 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d12 */ ++ <3 RK_PC7 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d19 */ ++ <3 RK_PC6 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d18 */ ++ <3 RK_PC5 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d17 */ ++ <3 RK_PC4 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d16 */ ++ <3 RK_PD3 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d23 */ ++ <3 RK_PD2 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d22 */ ++ <3 RK_PD1 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d21 */ ++ <3 RK_PD0 RK_FUNC_1 &pcfg_pull_none>; /* lcdc_d20 */ ++ }; ++ ++ lcdc_rgb666_m0_data_pins: lcdc-rgb666-m0-data-pins { ++ rockchip,pins = ++ <3 RK_PA7 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d3 */ ++ <3 RK_PA6 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d2 */ ++ <3 RK_PA5 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d1 */ ++ <3 RK_PA4 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d0 */ ++ <3 RK_PB3 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d7 */ ++ <3 RK_PB2 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d6 */ ++ <3 RK_PB1 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d5 */ ++ <3 RK_PB0 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d4 */ ++ <3 RK_PB7 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d11 */ ++ <3 RK_PB6 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d10 */ ++ <3 RK_PB5 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d9 */ ++ <3 RK_PB4 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d8 */ ++ <3 RK_PC3 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d15 */ ++ <3 RK_PC2 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d14 */ ++ <3 RK_PC1 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d13 */ ++ <3 RK_PC0 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d12 */ ++ <3 RK_PC5 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d17 */ ++ <3 RK_PC4 RK_FUNC_1 &pcfg_pull_none>; /* lcdc_d16 */ ++ }; ++ ++ lcdc_rgb565_m0_data_pins: lcdc-rgb565-m0-data-pins { ++ rockchip,pins = ++ <3 RK_PA7 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d3 */ ++ <3 RK_PA6 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d2 */ ++ <3 RK_PA5 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d1 */ ++ <3 RK_PA4 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d0 */ ++ <3 RK_PB3 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d7 */ ++ <3 RK_PB2 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d6 */ ++ <3 RK_PB1 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d5 */ ++ <3 RK_PB0 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d4 */ ++ <3 RK_PB7 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d11 */ ++ <3 RK_PB6 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d10 */ ++ <3 RK_PB5 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d9 */ ++ <3 RK_PB4 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d8 */ ++ <3 RK_PC3 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d15 */ ++ <3 RK_PC2 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d14 */ ++ <3 RK_PC1 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d13 */ ++ <3 RK_PC0 RK_FUNC_1 &pcfg_pull_none>; /* lcdc_d12 */ ++ }; ++ ++ lcdc_rgb888_m1_data_pins: lcdc-rgb888-m1-data-pins { ++ rockchip,pins = ++ <3 RK_PA6 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d2 */ ++ <3 RK_PA4 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d0 */ ++ <3 RK_PB3 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d7 */ ++ <3 RK_PB2 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d6 */ ++ <3 RK_PB5 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d9 */ ++ <3 RK_PC3 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d15 */ ++ <3 RK_PC2 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d14 */ ++ <3 RK_PC1 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d13 */ ++ <3 RK_PC0 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d12 */ ++ <3 RK_PC7 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d19 */ ++ <3 RK_PC6 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d18 */ ++ <3 RK_PC5 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d17 */ ++ <3 RK_PC4 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d16 */ ++ <3 RK_PD3 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d23 */ ++ <3 RK_PD2 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d22 */ ++ <3 RK_PD1 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d21 */ ++ <3 RK_PD0 RK_FUNC_1 &pcfg_pull_none>; /* lcdc_d20 */ ++ }; ++ ++ lcdc_rgb666_m1_data_pins: lcdc-rgb666-m1-data-pins { ++ rockchip,pins = ++ <3 RK_PA6 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d2 */ ++ <3 RK_PA4 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d0 */ ++ <3 RK_PB3 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d7 */ ++ <3 RK_PB2 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d6 */ ++ <3 RK_PB5 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d9 */ ++ <3 RK_PC3 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d15 */ ++ <3 RK_PC2 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d14 */ ++ <3 RK_PC1 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d13 */ ++ <3 RK_PC0 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d12 */ ++ <3 RK_PC5 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d17 */ ++ <3 RK_PC4 RK_FUNC_1 &pcfg_pull_none>; /* lcdc_d16 */ ++ }; ++ ++ lcdc_rgb565_m1_data_pins: lcdc-rgb565-m1-data-pins { ++ rockchip,pins = ++ <3 RK_PA6 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d2 */ ++ <3 RK_PA4 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d0 */ ++ <3 RK_PB3 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d7 */ ++ <3 RK_PB2 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d6 */ ++ <3 RK_PB5 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d9 */ ++ <3 RK_PC3 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d15 */ ++ <3 RK_PC2 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d14 */ ++ <3 RK_PC1 RK_FUNC_1 &pcfg_pull_none>, /* lcdc_d13 */ ++ <3 RK_PC0 RK_FUNC_1 &pcfg_pull_none>; /* lcdc_d12 */ ++ }; ++ }; ++ ++ pwm0 { ++ pwm0_pin: pwm0-pin { ++ rockchip,pins = ++ <0 RK_PB7 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ pwm1 { ++ pwm1_pin: pwm1-pin { ++ rockchip,pins = ++ <0 RK_PC0 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ pwm2 { ++ pwm2_pin: pwm2-pin { ++ rockchip,pins = ++ <2 RK_PB5 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ pwm3 { ++ pwm3_pin: pwm3-pin { ++ rockchip,pins = ++ <0 RK_PC1 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ pwm4 { ++ pwm4_pin: pwm4-pin { ++ rockchip,pins = ++ <3 RK_PC2 RK_FUNC_3 &pcfg_pull_none>; ++ }; ++ }; ++ ++ pwm5 { ++ pwm5_pin: pwm5-pin { ++ rockchip,pins = ++ <3 RK_PC3 RK_FUNC_3 &pcfg_pull_none>; ++ }; ++ }; ++ ++ pwm6 { ++ pwm6_pin: pwm6-pin { ++ rockchip,pins = ++ <3 RK_PC4 RK_FUNC_3 &pcfg_pull_none>; ++ }; ++ }; ++ ++ pwm7 { ++ pwm7_pin: pwm7-pin { ++ rockchip,pins = ++ <3 RK_PC5 RK_FUNC_3 &pcfg_pull_none>; ++ }; ++ }; ++ ++ gmac { ++ rmii_pins: rmii-pins { ++ rockchip,pins = ++ /* mac_txen */ ++ <2 RK_PA0 RK_FUNC_2 &pcfg_pull_none_12ma>, ++ /* mac_txd1 */ ++ <2 RK_PA1 RK_FUNC_2 &pcfg_pull_none_12ma>, ++ /* mac_txd0 */ ++ <2 RK_PA2 RK_FUNC_2 &pcfg_pull_none_12ma>, ++ /* mac_rxd0 */ ++ <2 RK_PA3 RK_FUNC_2 &pcfg_pull_none>, ++ /* mac_rxd1 */ ++ <2 RK_PA4 RK_FUNC_2 &pcfg_pull_none>, ++ /* mac_rxer */ ++ <2 RK_PA5 RK_FUNC_2 &pcfg_pull_none>, ++ /* mac_rxdv */ ++ <2 RK_PA6 RK_FUNC_2 &pcfg_pull_none>, ++ /* mac_mdio */ ++ <2 RK_PA7 RK_FUNC_2 &pcfg_pull_none>, ++ /* mac_mdc */ ++ <2 RK_PB1 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ mac_refclk_12ma: mac-refclk-12ma { ++ rockchip,pins = ++ <2 RK_PB2 RK_FUNC_2 &pcfg_pull_none_12ma>; ++ }; ++ ++ mac_refclk: mac-refclk { ++ rockchip,pins = ++ <2 RK_PB2 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ }; ++ ++ cif-m0 { ++ cif_clkout_m0: cif-clkout-m0 { ++ rockchip,pins = <2 RK_PB3 RK_FUNC_1 &pcfg_pull_none>;/* cif_clkout */ ++ }; ++ ++ dvp_d2d9_m0: dvp-d2d9-m0 { ++ rockchip,pins = ++ <2 RK_PA0 RK_FUNC_1 &pcfg_pull_none>,/* cif_data2 */ ++ <2 RK_PA1 RK_FUNC_1 &pcfg_pull_none>,/* cif_data3 */ ++ <2 RK_PA2 RK_FUNC_1 &pcfg_pull_none>,/* cif_data4 */ ++ <2 RK_PA3 RK_FUNC_1 &pcfg_pull_none>,/* cif_data5 */ ++ <2 RK_PA4 RK_FUNC_1 &pcfg_pull_none>,/* cif_data6 */ ++ <2 RK_PA5 RK_FUNC_1 &pcfg_pull_none>,/* cif_data7 */ ++ <2 RK_PA6 RK_FUNC_1 &pcfg_pull_none>,/* cif_data8 */ ++ <2 RK_PA7 RK_FUNC_1 &pcfg_pull_none>,/* cif_data9 */ ++ <2 RK_PB0 RK_FUNC_1 &pcfg_pull_none>,/* cif_sync */ ++ <2 RK_PB1 RK_FUNC_1 &pcfg_pull_none>,/* cif_href */ ++ <2 RK_PB2 RK_FUNC_1 &pcfg_pull_none>,/* cif_clkin */ ++ <2 RK_PB3 RK_FUNC_1 &pcfg_pull_none>;/* cif_clkout */ ++ }; ++ ++ dvp_d0d1_m0: dvp-d0d1-m0 { ++ rockchip,pins = ++ <2 RK_PB4 RK_FUNC_1 &pcfg_pull_none>,/* cif_data0 */ ++ <2 RK_PB6 RK_FUNC_1 &pcfg_pull_none>;/* cif_data1 */ ++ }; ++ ++ dvp_d10d11_m0:d10-d11-m0 { ++ rockchip,pins = ++ <2 RK_PB7 RK_FUNC_1 &pcfg_pull_none>,/* cif_data10 */ ++ <2 RK_PC0 RK_FUNC_1 &pcfg_pull_none>;/* cif_data11 */ ++ }; ++ }; ++ ++ cif-m1 { ++ cif_clkout_m1: cif-clkout-m1 { ++ rockchip,pins = <3 RK_PD0 RK_FUNC_3 &pcfg_pull_none>;/* cif_clkout */ ++ }; ++ ++ dvp_d2d9_m1: dvp-d2d9-m1 { ++ rockchip,pins = ++ <3 RK_PA3 RK_FUNC_1 &pcfg_pull_none>,/* cif_data2 */ ++ <3 RK_PA5 RK_FUNC_1 &pcfg_pull_none>,/* cif_data3 */ ++ <3 RK_PA7 RK_FUNC_1 &pcfg_pull_none>,/* cif_data4 */ ++ <3 RK_PB0 RK_FUNC_1 &pcfg_pull_none>,/* cif_data5 */ ++ <3 RK_PB1 RK_FUNC_1 &pcfg_pull_none>,/* cif_data6 */ ++ <3 RK_PB4 RK_FUNC_1 &pcfg_pull_none>,/* cif_data7 */ ++ <3 RK_PB6 RK_FUNC_1 &pcfg_pull_none>,/* cif_data8 */ ++ <3 RK_PB7 RK_FUNC_1 &pcfg_pull_none>,/* cif_data9 */ ++ <3 RK_PD1 RK_FUNC_3 &pcfg_pull_none>,/* cif_sync */ ++ <3 RK_PD2 RK_FUNC_2 &pcfg_pull_none>,/* cif_href */ ++ <3 RK_PD3 RK_FUNC_2 &pcfg_pull_none>,/* cif_clkin */ ++ <3 RK_PD0 RK_FUNC_3 &pcfg_pull_none>;/* cif_clkout */ ++ }; ++ ++ dvp_d0d1_m1: dvp-d0d1-m1 { ++ rockchip,pins = ++ <3 RK_PA1 RK_FUNC_3 &pcfg_pull_none>,/* cif_data0 */ ++ <3 RK_PA2 RK_FUNC_3 &pcfg_pull_none>;/* cif_data1 */ ++ }; ++ ++ dvp_d10d11_m1:d10-d11-m1 { ++ rockchip,pins = ++ <3 RK_PC6 RK_FUNC_3 &pcfg_pull_none>,/* cif_data10 */ ++ <3 RK_PC7 RK_FUNC_3 &pcfg_pull_none>;/* cif_data11 */ ++ }; ++ }; ++ ++ isp { ++ isp_prelight: isp-prelight { ++ rockchip,pins = <3 RK_PD1 RK_FUNC_4 &pcfg_pull_none>;/* ISP_PRELIGHTTRIG */ ++ }; ++ }; ++ }; ++}; +diff --git a/configs/evb-px30_defconfig b/configs/evb-px30_defconfig +index d1cc1788c9..4a35f3f887 100644 +--- a/configs/evb-px30_defconfig ++++ b/configs/evb-px30_defconfig +@@ -111,3 +111,8 @@ CONFIG_LZ4=y + CONFIG_LZO=y + CONFIG_ERRNO_STR=y + # CONFIG_EFI_LOADER is not set ++CONFIG_BOOTCOMMAND="setenv resin_kernel_load_addr ${kernel_addr_r}; run resin_set_kernel_root; run set_os_cmdline; setenv bootargs ${resin_kernel_root} rootwait console=ttyFIQ0,1500000 console=tty1 ${os_cmdline} panic=10 loglevel=7; load mmc ${resin_dev_index}:${resin_root_part} ${kernel_addr_r} /boot/Image; load mmc ${resin_dev_index}:${resin_root_part} ${fdt_addr_r} /boot/px30-evb-ddr3-v10-linux.dtb; booti ${kernel_addr_r} - ${fdt_addr_r}" ++CONFIG_CMD_FS_UUID=y ++CONFIG_CMD_EXPORTENV=y ++CONFIG_CMD_IMPORTENV=y ++CONFIG_CMD_SETEXPR=y +-- +2.17.1 + diff --git a/layers/meta-balena-nanopc-t4/recipes-bsp/u-boot/files/0001-resin-specific-env-integration-kconfig_REWORKED-lec-px30.patch b/layers/meta-balena-nanopc-t4/recipes-bsp/u-boot/files/0001-resin-specific-env-integration-kconfig_REWORKED-lec-px30.patch new file mode 100644 index 000000000..d5b1c257e --- /dev/null +++ b/layers/meta-balena-nanopc-t4/recipes-bsp/u-boot/files/0001-resin-specific-env-integration-kconfig_REWORKED-lec-px30.patch @@ -0,0 +1,19 @@ +--- a/include/env_default.h ++++ b/include/env_default.h +@@ -8,7 +8,7 @@ + */ + + #include <env_callback.h> +- ++#include <env_resin.h> + #ifdef DEFAULT_ENV_INSTANCE_EMBEDDED + env_t embedded_environment __UBOOT_ENV_SECTION__(environment) = { + ENV_CRC, /* CRC Sum */ +@@ -21,6 +21,7 @@ + #else + const uchar default_environment[] = { + #endif ++ RESIN_ENV + #ifndef CONFIG_USE_DEFAULT_ENV_FILE + #ifdef CONFIG_ENV_CALLBACK_LIST_DEFAULT + ENV_CALLBACK_VAR "=" CONFIG_ENV_CALLBACK_LIST_DEFAULT "\0" diff --git a/layers/meta-balena-nanopc-t4/recipes-bsp/u-boot/u-boot-rockchip.bb b/layers/meta-balena-nanopc-t4/recipes-bsp/u-boot/u-boot-rockchip.bb new file mode 100644 index 000000000..aa939a3de --- /dev/null +++ b/layers/meta-balena-nanopc-t4/recipes-bsp/u-boot/u-boot-rockchip.bb @@ -0,0 +1,23 @@ +DESCRIPTION = "FriendlyElec NanoPC-T4 U-Boot" +LICENSE = "GPLv2+" +LIC_FILES_CHKSUM = "file://Licenses/README;md5=30503fd321432fc713238f582193b78e" + +require recipes-bsp/u-boot/u-boot.inc + +DEPENDS_append = " bison-native rkbin " + +SRC_URI = " \ + git://github.com/u-boot/u-boot \ +" + +S = "${WORKDIR}/git" + +do_install_append() { + install -d ${D}/boot + install -c -m 0644 ${B}/idbloader.bin ${B}/uboot.img ${D}/boot +} + +do_deploy_append() { + install ${B}/idbloader.bin ${DEPLOYDIR} + install ${B}/uboot.img ${DEPLOYDIR} +} diff --git a/layers/meta-balena-nanopc-t4/recipes-bsp/u-boot/u-boot-rockchip.bbappend b/layers/meta-balena-nanopc-t4/recipes-bsp/u-boot/u-boot-rockchip.bbappend index 3c287526b..3478b3fb7 100644 --- a/layers/meta-balena-nanopc-t4/recipes-bsp/u-boot/u-boot-rockchip.bbappend +++ b/layers/meta-balena-nanopc-t4/recipes-bsp/u-boot/u-boot-rockchip.bbappend @@ -5,7 +5,29 @@ FILESEXTRAPATHS_append := ":${THISDIR}/files" # rework meta-resin patch whose context is different now in u-boot v2019.4 SRC_URI_remove = "file://resin-specific-env-integration-kconfig.patch" -SRC_URI += " \ + +SRC_URI_append_lec-px30 = " \ + file://0001-resin-specific-env-integration-kconfig_REWORKED-lec-px30.patch \ + file://0000-rockchip-add-support-for-px30.patch \ + file://0001-lec-px30.patch \ +" + +SRC_URI_append_nanopc-t4= " \ file://0001-resin-specific-env-integration-kconfig_REWORKED.patch \ - file://0002-NanoPC-T4-machine-specific-integration-of-resin-envi.patch \ + file://nanopc-t4.patch \ " + +SRCREV_nanopc-t4 = "v2019.04" +SRCREV_lec-px30 = "v2019.10" + +do_compile_append_nanopc-t4() { + tools/mkimage -n rk3399 -T rksd -d ${DEPLOY_DIR_IMAGE}/rkbin/rk3399_ddr_800MHz_v1.14.bin idbloader.bin + cat ${DEPLOY_DIR_IMAGE}/rkbin/rk3399_miniloader_v1.15.bin >> idbloader.bin + ${DEPLOY_DIR_IMAGE}/rkbin/tools/loaderimage --pack --uboot ./u-boot-dtb.bin uboot.img 0x200000 +} + +do_compile_append_lec-px30() { + tools/mkimage -n px30 -T rksd -d ${DEPLOY_DIR_IMAGE}/rkbin/px30_ddr_333MHz_v1.10.bin idbloader.bin + cat ${DEPLOY_DIR_IMAGE}/rkbin/px30_miniloader_v1.15.bin >> idbloader.bin + ${DEPLOY_DIR_IMAGE}/rkbin/tools/loaderimage --pack --uboot ./u-boot-dtb.bin uboot.img 0x200000 +} diff --git a/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0001-Device-tree-for-LEC-PX30-A2.patch b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0001-Device-tree-for-LEC-PX30-A2.patch new file mode 100644 index 000000000..a35046d11 --- /dev/null +++ b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0001-Device-tree-for-LEC-PX30-A2.patch @@ -0,0 +1,8638 @@ +From 673ce6623c876e1a8a7b91ee251d9a95baf2f374 Mon Sep 17 00:00:00 2001 +From: Katha Ashok <katha.ashok@adlinktech.com> +Date: Thu, 19 Dec 2019 20:47:38 +0530 +Subject: [PATCH] Device tree for LEC-PX30 A2 + +--- + arch/arm64/boot/dts/rockchip/dsi2hdmi_lt9611.dtsi | 48 + + arch/arm64/boot/dts/rockchip/lec-px30.dtsi | 2920 +++++++++++++ + .../boot/dts/rockchip/px30-evb-ddr3-v10-linux.dts | 845 +++- + .../arm64/boot/dts/rockchip/px30-evb-ddr3-v10.dtsi | 4 +- + arch/arm64/boot/dts/rockchip/rk3326-linux.dtsi | 8 +- + arch/arm64/configs/adlink-px30_config | 4410 ++++++++++++++++++++ + 6 files changed, 8147 insertions(+), 88 deletions(-) + create mode 100644 arch/arm64/boot/dts/rockchip/dsi2hdmi_lt9611.dtsi + create mode 100644 arch/arm64/boot/dts/rockchip/lec-px30.dtsi + create mode 100644 arch/arm64/configs/adlink-px30_config + +diff --git a/arch/arm64/boot/dts/rockchip/dsi2hdmi_lt9611.dtsi b/arch/arm64/boot/dts/rockchip/dsi2hdmi_lt9611.dtsi +new file mode 100644 +index 0000000..bb00587 +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/dsi2hdmi_lt9611.dtsi +@@ -0,0 +1,48 @@ ++&dsi { ++ status = "okay"; ++ rockchip,lane-rate = <891>; ++ ++ panel@0 { ++ compatible = "simple-panel-dsi"; ++ reg = <0>; ++ power-supply = <&vcc3v3_lcd>; ++ backlight = <&backlight>; ++ prepare-delay-ms = <2>; ++ reset-delay-ms = <1>; ++ init-delay-ms = <20>; ++ enable-delay-ms = <120>; ++ disable-delay-ms = <50>; ++ unprepare-delay-ms = <20>; ++ ++ width-mm = <68>; ++ height-mm = <121>; ++ ++ dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | ++ MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>; ++ dsi,format = <MIPI_DSI_FMT_RGB888>; ++ /* dsi,lanes = <2>;*/ ++ dsi,lanes = <4>; ++ ++ display-timings { ++ native-mode = <&timing0>; ++ ++ timing0: timing0 { ++ /*clock-frequency = <74250000>;*/ ++ clock-frequency=<148500000>; ++ hactive = <1920>; ++ vactive = <1080>; ++ hfront-porch = <88>; ++ hsync-len = <44>; ++ hback-porch = <148>; ++ vfront-porch = <4>; ++ vsync-len = <5>; ++ vback-porch = <36>; ++ hsync-active = <0>; ++ vsync-active = <0>; ++ de-active = <0>; ++ pixelclk-active = <0>; ++ }; ++ }; ++ }; ++}; ++ +diff --git a/arch/arm64/boot/dts/rockchip/lec-px30.dtsi b/arch/arm64/boot/dts/rockchip/lec-px30.dtsi +new file mode 100644 +index 0000000..708bc9c +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/lec-px30.dtsi +@@ -0,0 +1,2920 @@ ++/* ++ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd ++ * ++ * SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ */ ++ ++#include <dt-bindings/clock/px30-cru.h> ++#include <dt-bindings/display/media-bus-format.h> ++#include <dt-bindings/gpio/gpio.h> ++#include <dt-bindings/interrupt-controller/arm-gic.h> ++#include <dt-bindings/interrupt-controller/irq.h> ++#include <dt-bindings/pinctrl/rockchip.h> ++#include <dt-bindings/power/px30-power.h> ++#include <dt-bindings/soc/rockchip,boot-mode.h> ++#include <dt-bindings/soc/rockchip-system-status.h> ++#include <dt-bindings/suspend/rockchip-px30.h> ++#include <dt-bindings/thermal/thermal.h> ++#include "px30-dram-default-timing.dtsi" ++ ++/ { ++ compatible = "rockchip,lec-px30"; ++ ++ interrupt-parent = <&gic>; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ++ aliases { ++ ethernet0 = &gmac; ++ i2c0 = &i2c0; ++ i2c1 = &i2c1; ++ i2c2 = &i2c2; ++ i2c3 = &i2c3; ++ serial0 = &uart0; ++ serial1 = &uart1; ++ serial2 = &uart2; ++ serial3 = &uart3; ++ serial4 = &uart4; ++ serial5 = &uart5; ++ spi0 = &spi0; ++ spi1 = &spi1; ++ }; ++ ++ cpus { ++ #address-cells = <2>; ++ #size-cells = <0>; ++ ++ cpu0: cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a35", "arm,armv8"; ++ reg = <0x0 0x0>; ++ enable-method = "psci"; ++ clocks = <&cru ARMCLK>; ++ #cooling-cells = <2>; ++ dynamic-power-coefficient = <90>; ++ operating-points-v2 = <&cpu0_opp_table>; ++ cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; ++ }; ++ ++ cpu1: cpu@1 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a35", "arm,armv8"; ++ reg = <0x0 0x1>; ++ enable-method = "psci"; ++ operating-points-v2 = <&cpu0_opp_table>; ++ cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; ++ }; ++ cpu2: cpu@2 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a35", "arm,armv8"; ++ reg = <0x0 0x2>; ++ enable-method = "psci"; ++ operating-points-v2 = <&cpu0_opp_table>; ++ cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; ++ }; ++ cpu3: cpu@3 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a35", "arm,armv8"; ++ reg = <0x0 0x3>; ++ enable-method = "psci"; ++ operating-points-v2 = <&cpu0_opp_table>; ++ cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; ++ }; ++ ++ idle-states { ++ entry-method = "psci"; ++ ++ CPU_SLEEP: cpu-sleep { ++ compatible = "arm,idle-state"; ++ local-timer-stop; ++ arm,psci-suspend-param = <0x0010000>; ++ entry-latency-us = <120>; ++ exit-latency-us = <250>; ++ min-residency-us = <900>; ++ }; ++ ++ CLUSTER_SLEEP: cluster-sleep { ++ compatible = "arm,idle-state"; ++ local-timer-stop; ++ arm,psci-suspend-param = <0x1010000>; ++ entry-latency-us = <400>; ++ exit-latency-us = <500>; ++ min-residency-us = <2000>; ++ }; ++ }; ++ }; ++ ++ cpu0_opp_table: cpu0-opp-table { ++ compatible = "operating-points-v2"; ++ opp-shared; ++ ++ rockchip,temp-hysteresis = <5000>; ++ rockchip,low-temp = <0>; ++ rockchip,low-temp-min-volt = <1000000>; ++ rockchip,low-temp-adjust-volt = < ++ /* MHz MHz uV */ ++ 0 1512 50000 ++ >; ++ ++ clocks = <&cru PLL_APLL>; ++ rockchip,avs-scale = <4>; ++ rockchip,max-volt = <1350000>; ++ rockchip,evb-irdrop = <25000>; ++ nvmem-cells = <&cpu_leakage>, <&performance>; ++ nvmem-cell-names = "cpu_leakage", "performance"; ++ rockchip,bin-scaling-sel = < ++ 0 13 ++ 1 15 ++ >; ++ ++ rockchip,pvtm-voltage-sel = < ++ 0 50000 0 ++ 50001 54000 1 ++ 54001 60000 2 ++ 60001 99999 3 ++ >; ++ rockchip,pvtm-freq = <408000>; ++ rockchip,pvtm-volt = <1000000>; ++ rockchip,pvtm-ch = <0 0>; ++ rockchip,pvtm-sample-time = <1000>; ++ rockchip,pvtm-number = <10>; ++ rockchip,pvtm-error = <1000>; ++ rockchip,pvtm-ref-temp = <40>; ++ rockchip,pvtm-temp-prop = <(-56) (-56)>; ++ rockchip,thermal-zone = "soc-thermal"; ++ ++ opp-408000000 { ++ opp-hz = /bits/ 64 <408000000>; ++ opp-microvolt = <950000 950000 1350000>; ++ opp-microvolt-L0 = <950000 950000 1350000>; ++ opp-microvolt-L1 = <950000 950000 1350000>; ++ opp-microvolt-L2 = <950000 950000 1350000>; ++ opp-microvolt-L3 = <950000 950000 1350000>; ++ clock-latency-ns = <40000>; ++ opp-suspend; ++ }; ++ opp-600000000 { ++ opp-hz = /bits/ 64 <600000000>; ++ opp-microvolt = <950000 950000 1350000>; ++ opp-microvolt-L0 = <950000 950000 1350000>; ++ opp-microvolt-L1 = <950000 950000 1350000>; ++ opp-microvolt-L2 = <950000 950000 1350000>; ++ opp-microvolt-L3 = <950000 950000 1350000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-816000000 { ++ opp-hz = /bits/ 64 <816000000>; ++ opp-microvolt = <1050000 1050000 1350000>; ++ opp-microvolt-L0 = <1050000 1050000 1350000>; ++ opp-microvolt-L1 = <1000000 1000000 1350000>; ++ opp-microvolt-L2 = <1000000 1000000 1350000>; ++ opp-microvolt-L3 = <950000 950000 1350000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1008000000 { ++ opp-hz = /bits/ 64 <1008000000>; ++ opp-microvolt = <1175000 1175000 1350000>; ++ opp-microvolt-L0 = <1175000 1175000 1350000>; ++ opp-microvolt-L1 = <1125000 1125000 1350000>; ++ opp-microvolt-L2 = <1125000 1125000 1350000>; ++ opp-microvolt-L3 = <1050000 1050000 1350000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1200000000 { ++ opp-hz = /bits/ 64 <1200000000>; ++ opp-microvolt = <1300000 1300000 1350000>; ++ opp-microvolt-L0 = <1300000 1300000 1350000>; ++ opp-microvolt-L1 = <1275000 1275000 1350000>; ++ opp-microvolt-L2 = <1250000 1250000 1350000>; ++ opp-microvolt-L3 = <1200000 1200000 1350000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1248000000 { ++ opp-hz = /bits/ 64 <1248000000>; ++ opp-microvolt = <1350000 1350000 1350000>; ++ opp-microvolt-L0 = <1350000 1350000 1350000>; ++ opp-microvolt-L1 = <1300000 1300000 1350000>; ++ opp-microvolt-L2 = <1275000 1275000 1350000>; ++ opp-microvolt-L3 = <1225000 1225000 1350000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1296000000 { ++ opp-hz = /bits/ 64 <1296000000>; ++ opp-microvolt = <1350000 1350000 1350000>; ++ opp-microvolt-L0 = <1350000 1350000 1350000>; ++ opp-microvolt-L1 = <1350000 1350000 1350000>; ++ opp-microvolt-L2 = <1300000 1300000 1350000>; ++ opp-microvolt-L3 = <1250000 1250000 1350000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1416000000 { ++ opp-hz = /bits/ 64 <1416000000>; ++ opp-microvolt = <1350000 1350000 1350000>; ++ opp-microvolt-L0 = <1350000 1350000 1350000>; ++ opp-microvolt-L1 = <1350000 1350000 1350000>; ++ opp-microvolt-L2 = <1300000 1300000 1350000>; ++ opp-microvolt-L3 = <1250000 1250000 1350000>; ++ clock-latency-ns = <40000>; ++ }; ++ opp-1512000000 { ++ opp-hz = /bits/ 64 <1512000000>; ++ opp-microvolt = <1350000 1350000 1350000>; ++ opp-microvolt-L0 = <1350000 1350000 1350000>; ++ opp-microvolt-L1 = <1350000 1350000 1350000>; ++ opp-microvolt-L2 = <1300000 1300000 1350000>; ++ opp-microvolt-L3 = <1250000 1250000 1350000>; ++ clock-latency-ns = <40000>; ++ }; ++ }; ++ ++ arm-pmu { ++ compatible = "arm,cortex-a53-pmu"; ++ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; ++ }; ++ ++ bus_soc: bus-soc { ++ compatible = "rockchip,px30-bus"; ++ rockchip,busfreq-policy = "autocs"; ++ soc-bus0 { ++ bus-id = <0>; ++ timer-us = <20>; ++ enable-msk = <0x40f7>; ++ status = "disabled"; ++ }; ++ soc-bus1 { ++ bus-id = <1>; ++ timer-us = <200>; ++ enable-msk = <0x40bf>; ++ status = "disabled"; ++ }; ++ soc-bus2 { ++ bus-id = <2>; ++ timer-us = <200>; ++ enable-msk = <0x4007>; ++ status = "disabled"; ++ }; ++ }; ++ ++ bus_apll: bus-apll { ++ compatible = "rockchip,px30-bus"; ++ rockchip,busfreq-policy = "clkfreq"; ++ clocks = <&cru PLL_APLL>; ++ clock-names = "bus"; ++ operating-points-v2 = <&bus_apll_opp_table>; ++ status = "disabled"; ++ }; ++ ++ bus_apll_opp_table: bus-apll-opp-table { ++ compatible = "operating-points-v2"; ++ opp-shared; ++ ++ opp-1512000000 { ++ opp-hz = /bits/ 64 <1512000000>; ++ opp-microvolt = <1000000>; ++ }; ++ opp-1008000000 { ++ opp-hz = /bits/ 64 <1008000000>; ++ opp-microvolt = <950000>; ++ }; ++ }; ++ ++ cpuinfo { ++ compatible = "rockchip,cpuinfo"; ++ nvmem-cells = <&otp_id>; ++ nvmem-cell-names = "id"; ++ }; ++ ++ display_subsystem: display-subsystem { ++ compatible = "rockchip,display-subsystem"; ++ ports = <&vopb_out>, <&vopl_out>; ++ status = "disabled"; ++ }; ++ ++ firmware { ++ optee { ++ compatible = "linaro,optee-tz"; ++ method = "smc"; ++ }; ++ }; ++ ++ gmac_clkin: external-gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <50000000>; ++ clock-output-names = "gmac_clkin"; ++ #clock-cells = <0>; ++ }; ++ ++ psci { ++ compatible = "arm,psci-1.0"; ++ method = "smc"; ++ }; ++ ++ rockchip_suspend: rockchip-suspend { ++ compatible = "rockchip,pm-px30"; ++ status = "disabled"; ++ rockchip,sleep-debug-en = <0>; ++ rockchip,sleep-mode-config = < ++ (0 ++ | RKPM_SLP_ARMOFF ++ | RKPM_SLP_PMU_HW_PLLS_PD ++ | RKPM_SLP_PMU_PMUALIVE_32K ++ | RKPM_SLP_PMU_DIS_OSC ++ | RKPM_SLP_PMIC_LP ++ ) ++ >; ++ rockchip,wakeup-config = < ++ (0 ++ | RKPM_CLUSTER_WKUP_EN ++ | RKPM_GPIO_WKUP_EN ++ | RKPM_USB_WKUP_EN ++ ) ++ >; ++ }; ++ ++ timer { ++ compatible = "arm,armv8-timer"; ++ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, ++ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, ++ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, ++ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; ++ }; ++ ++ xin24m: xin24m { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <24000000>; ++ clock-output-names = "xin24m"; ++ }; ++ ++ xin32k: xin32k { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <32768>; ++ clock-output-names = "xin32k"; ++ }; ++ ++ pmu: power-management@ff000000 { ++ compatible = "rockchip,px30-pmu", "syscon", "simple-mfd"; ++ reg = <0x0 0xff000000 0x0 0x1000>; ++ ++ power: power-controller { ++ compatible = "rockchip,px30-power-controller"; ++ #power-domain-cells = <1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ /* These power domains are grouped by VD_LOGIC */ ++ pd_usb@PX30_PD_USB { ++ reg = <PX30_PD_USB>; ++ clocks = <&cru HCLK_HOST>, ++ <&cru HCLK_OTG>, ++ <&cru SCLK_OTG_ADP>; ++ pm_qos = <&qos_usb_host>, <&qos_usb_otg>; ++ }; ++ pd_sdcard@PX30_PD_SDCARD { ++ reg = <PX30_PD_SDCARD>; ++ clocks = <&cru HCLK_SDMMC>, ++ <&cru SCLK_SDMMC>; ++ pm_qos = <&qos_sdmmc>; ++ }; ++ pd_gmac@PX30_PD_GMAC { ++ reg = <PX30_PD_GMAC>; ++ clocks = <&cru ACLK_GMAC>, ++ <&cru PCLK_GMAC>, ++ <&cru SCLK_MAC_REF>, ++ <&cru SCLK_GMAC_RX_TX>; ++ pm_qos = <&qos_gmac>; ++ }; ++ pd_mmc_nand@PX30_PD_MMC_NAND { ++ reg = <PX30_PD_MMC_NAND>; ++ clocks = <&cru HCLK_NANDC>, ++ <&cru HCLK_EMMC>, ++ <&cru HCLK_SDIO>, ++ <&cru HCLK_SFC>, ++ <&cru SCLK_EMMC>, ++ <&cru SCLK_NANDC>, ++ <&cru SCLK_SDIO>, ++ <&cru SCLK_SFC>; ++ pm_qos = <&qos_emmc>, <&qos_nand>, ++ <&qos_sdio>, <&qos_sfc>; ++ }; ++ pd_vpu@PX30_PD_VPU { ++ reg = <PX30_PD_VPU>; ++ clocks = <&cru ACLK_VPU>, ++ <&cru HCLK_VPU>, ++ <&cru SCLK_CORE_VPU>; ++ pm_qos = <&qos_vpu>, <&qos_vpu_r128>; ++ }; ++ pd_vo@PX30_PD_VO { ++ reg = <PX30_PD_VO>; ++ clocks = <&cru ACLK_RGA>, ++ <&cru ACLK_VOPB>, ++ <&cru ACLK_VOPL>, ++ <&cru DCLK_VOPB>, ++ <&cru DCLK_VOPL>, ++ <&cru HCLK_RGA>, ++ <&cru HCLK_VOPB>, ++ <&cru HCLK_VOPL>, ++ <&cru PCLK_MIPI_DSI>, ++ <&cru SCLK_RGA_CORE>, ++ <&cru SCLK_VOPB_PWM>; ++ pm_qos = <&qos_rga_rd>, <&qos_rga_wr>, ++ <&qos_vop_m0>, <&qos_vop_m1>; ++ }; ++ pd_vi@PX30_PD_VI { ++ reg = <PX30_PD_VI>; ++ clocks = <&cru ACLK_CIF>, ++ <&cru ACLK_ISP>, ++ <&cru HCLK_CIF>, ++ <&cru HCLK_ISP>, ++ <&cru SCLK_ISP>; ++ pm_qos = <&qos_isp_128>, <&qos_isp_rd>, ++ <&qos_isp_wr>, <&qos_isp_m1>, ++ <&qos_vip>; ++ }; ++ pd_gpu@PX30_PD_GPU { ++ reg = <PX30_PD_GPU>; ++ clocks = <&cru SCLK_GPU>; ++ pm_qos = <&qos_gpu>; ++ }; ++ }; ++ }; ++ ++ pmugrf: syscon@ff010000 { ++ compatible = "rockchip,px30-pmugrf", "syscon", "simple-mfd"; ++ reg = <0x0 0xff010000 0x0 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ pmu_io_domains: io-domains { ++ compatible = "rockchip,px30-pmu-io-voltage-domain"; ++ status = "disabled"; ++ }; ++ ++ reboot-mode { ++ compatible = "syscon-reboot-mode"; ++ offset = <0x200>; ++ mode-bootloader = <BOOT_BL_DOWNLOAD>; ++ mode-charge = <BOOT_CHARGING>; ++ mode-fastboot = <BOOT_FASTBOOT>; ++ mode-loader = <BOOT_BL_DOWNLOAD>; ++ mode-normal = <BOOT_NORMAL>; ++ mode-recovery = <BOOT_RECOVERY>; ++ mode-ums = <BOOT_UMS>; ++ }; ++ ++ pmu_pvtm: pmu-pvtm { ++ compatible = "rockchip,px30-pmu-pvtm"; ++ clocks = <&pmucru SCLK_PVTM_PMU>; ++ clock-names = "pmu"; ++ status = "okay"; ++ }; ++ }; ++ ++ uart0: serial@ff030000 { ++ compatible = "rockchip,px30-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xff030000 0x0 0x100>; ++ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&pmucru SCLK_UART0_PMU>, <&pmucru PCLK_UART0_PMU>; ++ clock-names = "baudclk", "apb_pclk"; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ dmas = <&dmac 0>, <&dmac 1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; ++ status = "disabled"; ++ }; ++ ++ i2s0_8ch: i2s@ff060000 { ++ compatible = "rockchip,px30-i2s-tdm"; ++ reg = <0x0 0xff060000 0x0 0x1000>; ++ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_I2S0_TX>, <&cru SCLK_I2S0_RX>, <&cru HCLK_I2S0>; ++ clock-names = "mclk_tx", "mclk_rx", "hclk"; ++ dmas = <&dmac 16>, <&dmac 17>; ++ dma-names = "tx", "rx"; ++ resets = <&cru SRST_I2S0_TX>, <&cru SRST_I2S0_RX>; ++ reset-names = "tx-m", "rx-m"; ++ rockchip,cru = <&cru>; ++ rockchip,grf = <&grf>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s0_8ch_sclktx ++ &i2s0_8ch_sclkrx ++ &i2s0_8ch_lrcktx ++ &i2s0_8ch_lrckrx ++ &i2s0_8ch_sdi0 ++ &i2s0_8ch_sdi1 ++ &i2s0_8ch_sdi2 ++ &i2s0_8ch_sdi3 ++ &i2s0_8ch_sdo0 ++ &i2s0_8ch_sdo1 ++ &i2s0_8ch_sdo2 ++ &i2s0_8ch_sdo3>; ++ status = "disabled"; ++ }; ++ ++ i2s1_2ch: i2s@ff070000 { ++ compatible = "rockchip,px30-i2s", "rockchip,rk3066-i2s"; ++ reg = <0x0 0xff070000 0x0 0x1000>; ++ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_I2S1>, <&cru HCLK_I2S1>; ++ clock-names = "i2s_clk", "i2s_hclk"; ++ dmas = <&dmac 18>, <&dmac 19>; ++ dma-names = "tx", "rx"; ++ resets = <&cru SRST_I2S1>, <&cru SRST_I2S1_H>; ++ reset-names = "reset-m", "reset-h"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s1_2ch_sclk ++ &i2s1_2ch_lrck ++ &i2s1_2ch_sdi ++ &i2s1_2ch_sdo>; ++ status = "disabled"; ++ }; ++ ++ i2s2_2ch: i2s@ff080000 { ++ compatible = "rockchip,px30-i2s", "rockchip,rk3066-i2s"; ++ reg = <0x0 0xff080000 0x0 0x1000>; ++ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_I2S2>, <&cru HCLK_I2S2>; ++ clock-names = "i2s_clk", "i2s_hclk"; ++ dmas = <&dmac 20>, <&dmac 21>; ++ dma-names = "tx", "rx"; ++ resets = <&cru SRST_I2S2>, <&cru SRST_I2S2_H>; ++ reset-names = "reset-m", "reset-h"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s2_2ch_sclk ++ &i2s2_2ch_lrck ++ &i2s2_2ch_sdi ++ &i2s2_2ch_sdo>; ++ status = "disabled"; ++ }; ++ ++ pdm: pdm@ff0a0000 { ++ compatible = "rockchip,px30-pdm", "rockchip,pdm"; ++ reg = <0x0 0xff0a0000 0x0 0x1000>; ++ clocks = <&cru SCLK_PDM>, <&cru HCLK_PDM>; ++ clock-names = "pdm_clk", "pdm_hclk"; ++ dmas = <&dmac 24>; ++ dma-names = "rx"; ++ resets = <&cru SRST_PDM>; ++ reset-names = "pdm-m"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pdm_clk0m0 ++ &pdm_clk1 ++ &pdm_sdi0m0 ++ &pdm_sdi1 ++ &pdm_sdi2 ++ &pdm_sdi3>; ++ status = "disabled"; ++ }; ++ ++ gic: interrupt-controller@ff131000 { ++ compatible = "arm,gic-400"; ++ #interrupt-cells = <3>; ++ #address-cells = <0>; ++ interrupt-controller; ++ reg = <0x0 0xff131000 0 0x1000>, ++ <0x0 0xff132000 0 0x2000>, ++ <0x0 0xff134000 0 0x2000>, ++ <0x0 0xff136000 0 0x2000>; ++ interrupts = <GIC_PPI 9 ++ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; ++ }; ++ ++ grf: syscon@ff140000 { ++ compatible = "rockchip,px30-grf", "syscon", "simple-mfd"; ++ reg = <0x0 0xff140000 0x0 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ io_domains: io-domains { ++ compatible = "rockchip,px30-io-voltage-domain"; ++ status = "disabled"; ++ }; ++ ++ lvds: lvds { ++ compatible = "rockchip,px30-lvds"; ++ phys = <&video_phy>; ++ phy-names = "phy"; ++ status = "disabled"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ lvds_in_vopb: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&vopb_out_lvds>; ++ }; ++ ++ lvds_in_vopl: endpoint@1 { ++ reg = <1>; ++ remote-endpoint = <&vopl_out_lvds>; ++ }; ++ }; ++ }; ++ }; ++ ++ rgb: rgb { ++ compatible = "rockchip,px30-rgb"; ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&lcdc_m0_rgb_pins>; ++ pinctrl-1 = <&lcdc_m0_sleep_pins>; ++ status = "disabled"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ rgb_in_vopb: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&vopb_out_rgb>; ++ }; ++ ++ rgb_in_vopl: endpoint@1 { ++ reg = <1>; ++ remote-endpoint = <&vopl_out_rgb>; ++ }; ++ }; ++ }; ++ }; ++ }; ++ ++ core_grf: syscon@ff148000 { ++ compatible = "syscon", "simple-mfd"; ++ reg = <0x0 0xff148000 0x0 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ pvtm: pvtm { ++ compatible = "rockchip,px30-pvtm"; ++ clocks = <&cru SCLK_PVTM>; ++ clock-names = "core"; ++ status = "okay"; ++ }; ++ }; ++ ++ uart1: serial@ff158000 { ++ compatible = "rockchip,px30-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xff158000 0x0 0x100>; ++ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>; ++ clock-names = "baudclk", "apb_pclk"; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ dmas = <&dmac 2>, <&dmac 3>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_xfer &uart1_cts &uart1_rts>; ++ status = "disabled"; ++ }; ++ ++ uart2: serial@ff160000 { ++ compatible = "rockchip,px30-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xff160000 0x0 0x100>; ++ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>; ++ clock-names = "baudclk", "apb_pclk"; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ dmas = <&dmac 4>, <&dmac 5>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2m0_xfer>; ++ status = "disabled"; ++ }; ++ ++ uart3: serial@ff168000 { ++ compatible = "rockchip,px30-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xff168000 0x0 0x100>; ++ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>; ++ clock-names = "baudclk", "apb_pclk"; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ dmas = <&dmac 6>, <&dmac 7>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart3m1_xfer &uart3m1_cts &uart3m1_rts>; ++ status = "disabled"; ++ }; ++ ++ uart4: serial@ff170000 { ++ compatible = "rockchip,px30-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xff170000 0x0 0x100>; ++ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>; ++ clock-names = "baudclk", "apb_pclk"; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ dmas = <&dmac 8>, <&dmac 9>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart4_xfer &uart4_cts &uart4_rts>; ++ status = "disabled"; ++ }; ++ ++ uart5: serial@ff178000 { ++ compatible = "rockchip,px30-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xff178000 0x0 0x100>; ++ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru SCLK_UART5>, <&cru PCLK_UART5>; ++ clock-names = "baudclk", "apb_pclk"; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ dmas = <&dmac 10>, <&dmac 11>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart5_xfer &uart5_cts &uart5_rts>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@ff180000 { ++ compatible = "rockchip,rk3399-i2c"; ++ reg = <0x0 0xff180000 0x0 0x1000>; ++ clocks = <&cru SCLK_I2C0>, <&cru PCLK_I2C0>; ++ clock-names = "i2c", "pclk"; ++ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_xfer>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ i2c1: i2c@ff190000 { ++ compatible = "rockchip,rk3399-i2c"; ++ reg = <0x0 0xff190000 0x0 0x1000>; ++ clocks = <&cru SCLK_I2C1>, <&cru PCLK_I2C1>; ++ clock-names = "i2c", "pclk"; ++ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_xfer>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ i2c2: i2c@ff1a0000 { ++ compatible = "rockchip,rk3399-i2c"; ++ reg = <0x0 0xff1a0000 0x0 0x1000>; ++ clocks = <&cru SCLK_I2C2>, <&cru PCLK_I2C2>; ++ clock-names = "i2c", "pclk"; ++ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c2_xfer>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ i2c3: i2c@ff1b0000 { ++ compatible = "rockchip,rk3399-i2c"; ++ reg = <0x0 0xff1b0000 0x0 0x1000>; ++ clocks = <&cru SCLK_I2C3>, <&cru PCLK_I2C3>; ++ clock-names = "i2c", "pclk"; ++ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c3_xfer>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ spi0: spi@ff1d0000 { ++ compatible = "rockchip,px30-spi", "rockchip,rk3066-spi"; ++ reg = <0x0 0xff1d0000 0x0 0x1000>; ++ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>; ++ clock-names = "spiclk", "apb_pclk"; ++ dmas = <&dmac 12>, <&dmac 13>; ++ dma-names = "tx", "rx"; ++ /*cs-gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>;*/ ++ pinctrl-names = "default", "high_speed"; ++ pinctrl-0 = <&spi0_clk /*&spi0_csn*/ &spi0_miso &spi0_mosi>; ++ pinctrl-1 = <&spi0_clk_hs /*&spi0_csn*/ &spi0_miso_hs &spi0_mosi_hs>; ++ status = "disabled"; ++ }; ++ ++ spi1: spi@ff1d8000 { ++ compatible = "rockchip,px30-spi", "rockchip,rk3066-spi"; ++ reg = <0x0 0xff1d8000 0x0 0x1000>; ++ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>; ++ clock-names = "spiclk", "apb_pclk"; ++ dmas = <&dmac 14>, <&dmac 15>; ++ dma-names = "tx", "rx"; ++ pinctrl-names = "default", "high_speed"; ++ pinctrl-0 = <&spi1_clk &spi1_csn0 &spi1_csn1 &spi1_miso &spi1_mosi>; ++ pinctrl-1 = <&spi1_clk_hs &spi1_csn0 &spi1_csn1 &spi1_miso_hs &spi1_mosi_hs>; ++ status = "disabled"; ++ }; ++ ++ wdt: watchdog@ff1e0000 { ++ compatible = "snps,dw-wdt"; ++ reg = <0x0 0xff1e0000 0x0 0x100>; ++ clocks = <&cru PCLK_WDT_NS>; ++ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; ++ resets = <&cru SRST_WDT_NS_P>; ++ reset-names = "reset"; ++ status = "disabled"; ++ }; ++ ++ pwm0: pwm@ff200000 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff200000 0x0 0x10>; ++ #pwm-cells = <3>; ++ pinctrl-names = "active"; ++ pinctrl-0 = <&pwm0_pin>; ++ clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>; ++ clock-names = "pwm", "pclk"; ++ status = "disabled"; ++ }; ++ ++ pwm1: pwm@ff200010 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff200010 0x0 0x10>; ++ #pwm-cells = <3>; ++ pinctrl-names = "active"; ++ pinctrl-0 = <&pwm1_pin>; ++ clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>; ++ clock-names = "pwm", "pclk"; ++ status = "disabled"; ++ }; ++ ++ pwm2: pwm@ff200020 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff200020 0x0 0x10>; ++ #pwm-cells = <3>; ++ pinctrl-names = "active"; ++ pinctrl-0 = <&pwm2_pin>; ++ clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>; ++ clock-names = "pwm", "pclk"; ++ status = "disabled"; ++ }; ++ ++ pwm3: pwm@ff200030 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff200030 0x0 0x10>; ++ #pwm-cells = <3>; ++ pinctrl-names = "active"; ++ pinctrl-0 = <&pwm3_pin>; ++ clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>; ++ clock-names = "pwm", "pclk"; ++ status = "disabled"; ++ }; ++ ++ pwm4: pwm@ff208000 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff208000 0x0 0x10>; ++ #pwm-cells = <3>; ++ pinctrl-names = "active"; ++ pinctrl-0 = <&pwm4_pin>; ++ clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>; ++ clock-names = "pwm", "pclk"; ++ status = "disabled"; ++ }; ++ ++ pwm5: pwm@ff208010 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff208010 0x0 0x10>; ++ #pwm-cells = <3>; ++ pinctrl-names = "active"; ++ pinctrl-0 = <&pwm5_pin>; ++ clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>; ++ clock-names = "pwm", "pclk"; ++ status = "disabled"; ++ }; ++ ++ pwm6: pwm@ff208020 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff208020 0x0 0x10>; ++ #pwm-cells = <3>; ++ pinctrl-names = "active"; ++ pinctrl-0 = <&pwm6_pin>; ++ clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>; ++ clock-names = "pwm", "pclk"; ++ status = "disabled"; ++ }; ++ ++ pwm7: pwm@ff208030 { ++ compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; ++ reg = <0x0 0xff208030 0x0 0x10>; ++ #pwm-cells = <3>; ++ pinctrl-names = "active"; ++ pinctrl-0 = <&pwm7_pin>; ++ clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>; ++ clock-names = "pwm", "pclk"; ++ status = "disabled"; ++ }; ++ ++ rktimer: rktimer@ff210000 { ++ compatible = "rockchip,rk3288-timer"; ++ reg = <0x0 0xff210000 0x0 0x1000>; ++ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru PCLK_TIMER>, <&cru SCLK_TIMER0>; ++ clock-names = "pclk", "timer"; ++ }; ++ ++ amba { ++ compatible = "simple-bus"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ ++ dmac: dmac@ff240000 { ++ compatible = "arm,pl330", "arm,primecell"; ++ reg = <0x0 0xff240000 0x0 0x4000>; ++ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru ACLK_DMAC>; ++ clock-names = "apb_pclk"; ++ #dma-cells = <1>; ++ peripherals-req-type-burst; ++ }; ++ }; ++ ++ thermal_zones: thermal-zones { ++ ++ soc_thermal: soc-thermal { ++ polling-delay-passive = <20>; ++ polling-delay = <1000>; ++ sustainable-power = <750>; ++ ++ thermal-sensors = <&tsadc 0>; ++ ++ trips { ++ threshold: trip-point-0 { ++ temperature = <70000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ target: trip-point-1 { ++ temperature = <85000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ soc_crit: soc-crit { ++ temperature = <115000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ }; ++ ++ cooling-maps { ++ map0 { ++ trip = <&target>; ++ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ contribution = <4096>; ++ }; ++ map1 { ++ trip = <&target>; ++ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ contribution = <4096>; ++ }; ++ }; ++ }; ++ ++ gpu_thermal: gpu-thermal { ++ polling-delay-passive = <100>; /* milliseconds */ ++ polling-delay = <1000>; /* milliseconds */ ++ ++ thermal-sensors = <&tsadc 1>; ++ }; ++ }; ++ ++ tsadc: tsadc@ff280000 { ++ compatible = "rockchip,px30-tsadc"; ++ reg = <0x0 0xff280000 0x0 0x100>; ++ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>; ++ rockchip,grf = <&grf>; ++ clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>; ++ clock-names = "tsadc", "apb_pclk"; ++ assigned-clocks = <&cru SCLK_TSADC>; ++ assigned-clock-rates = <50000>; ++ resets = <&cru SRST_TSADC>; ++ reset-names = "tsadc-apb"; ++ #thermal-sensor-cells = <1>; ++ rockchip,hw-tshut-temp = <120000>; ++ status = "disabled"; ++ }; ++ ++ saradc: saradc@ff288000 { ++ compatible = "rockchip,px30-saradc", "rockchip,rk3399-saradc"; ++ reg = <0x0 0xff288000 0x0 0x100>; ++ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>; ++ #io-channel-cells = <1>; ++ clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>; ++ clock-names = "saradc", "apb_pclk"; ++ resets = <&cru SRST_SARADC_P>; ++ reset-names = "saradc-apb"; ++ status = "disabled"; ++ }; ++ ++ otp: otp@ff290000 { ++ compatible = "rockchip,px30-otp"; ++ reg = <0x0 0xff290000 0x0 0x4000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ clocks = <&cru SCLK_OTP_USR>, <&cru PCLK_OTP_NS>, ++ <&cru PCLK_OTP_PHY>; ++ clock-names = "clk_otp", "pclk_otp", "pclk_otp_phy"; ++ resets = <&cru SRST_OTP_PHY>; ++ reset-names = "otp_phy"; ++ ++ /* Data cells */ ++ otp_id: id@7 { ++ reg = <0x07 0x10>; ++ }; ++ cpu_leakage: cpu-leakage@17 { ++ reg = <0x17 0x1>; ++ }; ++ performance: performance@1e { ++ reg = <0x1e 0x1>; ++ bits = <4 3>; ++ }; ++ }; ++ ++ cru: clock-controller@ff2b0000 { ++ compatible = "rockchip,px30-cru"; ++ reg = <0x0 0xff2b0000 0x0 0x1000>; ++ rockchip,grf = <&grf>; ++ rockchip,boost = <&cpu_boost>; ++ #clock-cells = <1>; ++ #reset-cells = <1>; ++ }; ++ ++ cpu_boost: cpu-boost@ff2b8000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff2b8000 0x0 0x1000>; ++ rockchip,boost-low-con0 = <0x1032>; ++ rockchip,boost-low-con1 = <0x1441>; ++ rockchip,boost-high-con0 = <0x1036>; ++ rockchip,boost-high-con1 = <0x1441>; ++ rockchip,boost-backup-pll = <1>; ++ rockchip,boost-backup-pll-usage = <0>; ++ rockchip,boost-switch-threshold = <0x249f00>; ++ rockchip,boost-statis-threshold = <0x100>; ++ rockchip,boost-statis-enable = <0>; ++ rockchip,boost-enable = <0>; ++ }; ++ ++ pmucru: pmu-clock-controller@ff2bc000 { ++ compatible = "rockchip,px30-pmucru"; ++ reg = <0x0 0xff2bc000 0x0 0x1000>; ++ rockchip,grf = <&grf>; ++ #clock-cells = <1>; ++ #reset-cells = <1>; ++ ++ assigned-clocks = ++ <&pmucru PLL_GPLL>, <&pmucru PCLK_PMU_PRE>, ++ <&pmucru SCLK_WIFI_PMU>, <&cru ARMCLK>, ++ <&cru ACLK_BUS_PRE>, <&cru ACLK_PERI_PRE>, ++ <&cru HCLK_BUS_PRE>, <&cru HCLK_PERI_PRE>, ++ <&cru PCLK_BUS_PRE>, <&cru SCLK_GPU>; ++ assigned-clock-rates = ++ <1200000000>, <100000000>, ++ <26000000>, <600000000>, ++ <200000000>, <200000000>, ++ <150000000>, <150000000>, ++ <100000000>, <200000000>; ++ }; ++ ++ usb2phy_grf: syscon@ff2c0000 { ++ compatible = "rockchip,px30-usb2phy-grf", "syscon", ++ "simple-mfd"; ++ reg = <0x0 0xff2c0000 0x0 0x10000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ u2phy: usb2-phy@100 { ++ compatible = "rockchip,px30-usb2phy", ++ "rockchip,rk3328-usb2phy"; ++ reg = <0x100 0x10>; ++ clocks = <&pmucru SCLK_USBPHY_REF>; ++ clock-names = "phyclk"; ++ #clock-cells = <0>; ++ assigned-clocks = <&cru USB480M>, <&cru SCLK_UART1_SRC>; ++ assigned-clock-parents = <&u2phy>, <&cru USB480M>; ++ clock-output-names = "usb480m_phy"; ++ status = "disabled"; ++ ++ u2phy_host: host-port { ++ #phy-cells = <0>; ++ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "linestate"; ++ status = "disabled"; ++ }; ++ ++ u2phy_otg: otg-port { ++ #phy-cells = <0>; ++ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "otg-bvalid", "otg-id", ++ "linestate"; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ video_phy: video-phy@ff2e0000 { ++ compatible = "rockchip,px30-video-phy"; ++ reg = <0x0 0xff2e0000 0x0 0x10000>, ++ <0x0 0xff450000 0x0 0x10000>; ++ clocks = <&pmucru SCLK_MIPIDSIPHY_REF>, ++ <&cru PCLK_MIPIDSIPHY>, <&cru PCLK_MIPI_DSI>; ++ clock-names = "ref", "pclk_phy", "pclk_host"; ++ #clock-cells = <0>; ++ resets = <&cru SRST_MIPIDSIPHY_P>; ++ reset-names = "rst"; ++ power-domains = <&power PX30_PD_VO>; ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ mipi_dphy_rx0: mipi-dphy-rx0@ff2f0000 { ++ compatible = "rockchip,rk3326-mipi-dphy"; ++ reg = <0x0 0xff2f0000 0x0 0x4000>; ++ clocks = <&cru PCLK_MIPICSIPHY>; ++ clock-names = "dphy-ref"; ++ power-domains = <&power PX30_PD_VI>; ++ rockchip,grf = <&grf>; ++ status = "disabled"; ++ }; ++ ++ usb20_otg: usb@ff300000 { ++ compatible = "rockchip,px30-usb", "rockchip,rk3066-usb", ++ "snps,dwc2"; ++ reg = <0x0 0xff300000 0x0 0x40000>; ++ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru HCLK_OTG>; ++ clock-names = "otg"; ++ power-domains = <&power PX30_PD_USB>; ++ dr_mode = "otg"; ++ g-np-tx-fifo-size = <16>; ++ g-rx-fifo-size = <280>; ++ g-tx-fifo-size = <256 128 128 64 32 16>; ++ g-use-dma; ++ phys = <&u2phy_otg>; ++ phy-names = "usb2-phy"; ++ status = "disabled"; ++ }; ++ ++ usb_host0_ehci: usb@ff340000 { ++ compatible = "generic-ehci"; ++ reg = <0x0 0xff340000 0x0 0x10000>; ++ interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru HCLK_HOST>, <&u2phy>; ++ clock-names = "usbhost", "utmi"; ++ power-domains = <&power PX30_PD_USB>; ++ phys = <&u2phy_host>; ++ phy-names = "usb"; ++ status = "disabled"; ++ }; ++ ++ usb_host0_ohci: usb@ff350000 { ++ compatible = "generic-ohci"; ++ reg = <0x0 0xff350000 0x0 0x10000>; ++ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru HCLK_HOST>, <&u2phy>; ++ clock-names = "usbhost", "utmi"; ++ power-domains = <&power PX30_PD_USB>; ++ phys = <&u2phy_host>; ++ phy-names = "usb"; ++ status = "disabled"; ++ }; ++ ++ gmac: ethernet@ff360000 { ++ compatible = "rockchip,px30-gmac"; ++ reg = <0x0 0xff360000 0x0 0x10000>; ++ rockchip,grf = <&grf>; ++ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "macirq"; ++ clocks = <&cru SCLK_GMAC>, <&cru SCLK_GMAC_RX_TX>, ++ <&cru SCLK_GMAC_RX_TX>, <&cru SCLK_MAC_REF>, ++ <&cru SCLK_MAC_REFOUT>, <&cru ACLK_GMAC>, ++ <&cru PCLK_GMAC>, <&cru SCLK_GMAC_RMII>; ++ clock-names = "stmmaceth", "mac_clk_rx", ++ "mac_clk_tx", "clk_mac_ref", ++ "clk_mac_refout", "aclk_mac", ++ "pclk_mac", "clk_mac_speed"; ++ phy-mode = "rmii"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rmii_pins &mac_refclk_12ma>; ++ resets = <&cru SRST_GMAC_A>; ++ reset-names = "stmmaceth"; ++ power-domains = <&power PX30_PD_GMAC>; ++ status = "disabled"; ++ }; ++ ++ sdmmc: dwmmc@ff370000 { ++ compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc"; ++ reg = <0x0 0xff370000 0x0 0x4000>; ++ max-frequency = <150000000>; ++ clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, ++ <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; ++ clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; ++ assigned-clocks = <&cru SCLK_SDMMC>; ++ assigned-clock-parents = <&cru SCLK_SDMMC_DIV50>; ++ power-domains = <&power PX30_PD_SDCARD>; ++ fifo-depth = <0x100>; ++ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>; ++ /*pinctrl-0 = <&sdmmc_clk_4ma &sdmmc_cmd_4ma &sdmmc_det_4ma &sdmmc_bus4_4ma>;*/ ++ status = "disabled"; ++ }; ++ ++ sdio: dwmmc@ff380000 { ++ compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc"; ++ reg = <0x0 0xff380000 0x0 0x4000>; ++ max-frequency = <150000000>; ++ clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>, ++ <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>; ++ clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; ++ assigned-clocks = <&cru SCLK_SDIO>; ++ assigned-clock-parents = <&cru SCLK_SDIO_DIV50>; ++ power-domains = <&power PX30_PD_MMC_NAND>; ++ fifo-depth = <0x100>; ++ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdio_bus4 &sdio_cmd &sdio_clk>; ++ status = "disabled"; ++ }; ++ ++ emmc: dwmmc@ff390000 { ++ compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc"; ++ reg = <0x0 0xff390000 0x0 0x4000>; ++ max-frequency = <150000000>; ++ clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>, ++ <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; ++ clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; ++ assigned-clocks = <&cru SCLK_EMMC>; ++ assigned-clock-parents = <&cru SCLK_EMMC_DIV50>; ++ power-domains = <&power PX30_PD_MMC_NAND>; ++ fifo-depth = <0x100>; ++ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; ++ status = "disabled"; ++ }; ++ ++ nandc0: nandc@ff3b0000 { ++ compatible = "rockchip,rk-nandc"; ++ reg = <0x0 0xff3b0000 0x0 0x4000>; ++ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>; ++ nandc_id = <0>; ++ clocks = <&cru SCLK_NANDC>, <&cru HCLK_NANDC>; ++ clock-names = "clk_nandc", "hclk_nandc"; ++ assigned-clocks = <&cru SCLK_NANDC>; ++ assigned-clock-parents = <&cru SCLK_NANDC_DIV50>; ++ power-domains = <&power PX30_PD_MMC_NAND>; ++ status = "disabled"; ++ }; ++ ++ gpu: gpu@ff400000 { ++ compatible = "arm,malit602", "arm,malit60x", "arm,malit6xx", "arm,mali-midgard"; ++ reg = <0x0 0xff400000 0x0 0x4000>; ++ ++ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "GPU", "MMU", "JOB"; ++ ++ clocks = <&cru SCLK_GPU>; ++ clock-names = "clk_mali"; ++ power-domains = <&power PX30_PD_GPU>; ++ #cooling-cells = <2>; ++ operating-points-v2 = <&gpu_opp_table>; ++ ++ status = "disabled"; ++ power_model { ++ compatible = "arm,mali-simple-power-model"; ++ static-coefficient = <411000>; ++ dynamic-coefficient = <733>; ++ ts = <32000 4700 (-80) 2>; ++ thermal-zone = "gpu-thermal"; ++ }; ++ ++ }; ++ ++ gpu_opp_table: gpu-opp-table { ++ compatible = "operating-points-v2"; ++ ++ rockchip,thermal-zone = "soc-thermal"; ++ rockchip,temp-hysteresis = <5000>; ++ rockchip,low-temp = <0>; ++ rockchip,low-temp-min-volt = <1000000>; ++ rockchip,low-temp-adjust-volt = < ++ /* MHz MHz uV */ ++ 0 480 50000 ++ >; ++ ++ rockchip,max-volt = <1175000>; ++ rockchip,evb-irdrop = <25000>; ++ ++ rockchip,pvtm-voltage-sel = < ++ 0 50000 0 ++ 50001 54000 1 ++ 54001 60000 2 ++ 60001 99999 3 ++ >; ++ rockchip,pvtm-ch = <0 0>; ++ ++ opp-200000000 { ++ opp-hz = /bits/ 64 <200000000>; ++ opp-microvolt = <950000>; ++ opp-microvolt-L0 = <950000>; ++ opp-microvolt-L1 = <950000>; ++ opp-microvolt-L2 = <950000>; ++ opp-microvolt-L3 = <950000>; ++ }; ++ opp-300000000 { ++ opp-hz = /bits/ 64 <300000000>; ++ opp-microvolt = <975000>; ++ opp-microvolt-L0 = <975000>; ++ opp-microvolt-L1 = <950000>; ++ opp-microvolt-L2 = <950000>; ++ opp-microvolt-L3 = <950000>; ++ }; ++ opp-400000000 { ++ opp-hz = /bits/ 64 <400000000>; ++ opp-microvolt = <1050000>; ++ opp-microvolt-L0 = <1050000>; ++ opp-microvolt-L1 = <1025000>; ++ opp-microvolt-L2 = <975000>; ++ opp-microvolt-L3 = <950000>; ++ }; ++ opp-480000000 { ++ opp-hz = /bits/ 64 <480000000>; ++ opp-microvolt = <1125000>; ++ opp-microvolt-L0 = <1125000>; ++ opp-microvolt-L1 = <1100000>; ++ opp-microvolt-L2 = <1050000>; ++ opp-microvolt-L3 = <1000000>; ++ }; ++ }; ++ ++ hevc: hevc_service@ff440000 { ++ compatible = "rockchip,hevc_sub"; ++ iommu_enabled = <1>; ++ reg = <0x0 0xff440000 0x0 0x400>; ++ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "irq_dec"; ++ dev_mode = <1>; ++ iommus = <&hevc_mmu>; ++ name = "hevc_service"; ++ allocator = <1>; ++ }; ++ ++ vpu: vpu_service@ff442000 { ++ compatible = "rockchip,vpu_sub"; ++ iommu_enabled = <1>; ++ reg = <0x0 0xff442000 0x0 0x800>; ++ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "irq_enc", "irq_dec"; ++ dev_mode = <0>; ++ iommus = <&vpu_mmu>; ++ name = "vpu_service"; ++ allocator = <1>; ++ }; ++ ++ vpu_combo: vpu_combo { ++ compatible = "rockchip,vpu_combo"; ++ subcnt = <2>; ++ rockchip,grf = <&grf>; ++ rockchip,sub = <&vpu>, <&hevc>; ++ clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>, <&cru SCLK_CORE_VPU>; ++ clock-names = "aclk_vcodec", "hclk_vcodec", "clk_core"; ++ resets = <&cru SRST_VPU_A>, <&cru SRST_VPU_H>, ++ <&cru SRST_VPU_NIU_A>, <&cru SRST_VPU_NIU_H>, ++ <&cru SRST_VPU_CORE>; ++ reset-names = "video_a", "video_h", "niu_a", "niu_h", ++ "video_core"; ++ power-domains = <&power PX30_PD_VPU>; ++ mode_bit = <15>; ++ mode_ctrl = <0x410>; ++ name = "vpu_combo"; ++ status = "disabled"; ++ }; ++ ++ hevc_mmu: iommu@ff440440 { ++ compatible = "rockchip,iommu"; ++ reg = <0x0 0xff440440 0x0 0x40>, <0x0 0xff440480 0x0 0x40>; ++ interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "hevc_mmu"; ++ clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>; ++ clock-names = "aclk", "hclk"; ++ power-domains = <&power PX30_PD_VPU>; ++ #iommu-cells = <0>; ++ }; ++ ++ vpu_mmu: iommu@ff442800 { ++ compatible = "rockchip,iommu"; ++ reg = <0x0 0xff442800 0x0 0x100>; ++ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "vpu_mmu"; ++ clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>; ++ clock-names = "aclk", "hclk"; ++ power-domains = <&power PX30_PD_VPU>; ++ #iommu-cells = <0>; ++ }; ++ ++ dsi: dsi@ff450000 { ++ compatible = "rockchip,px30-mipi-dsi"; ++ reg = <0x0 0xff450000 0x0 0x10000>; ++ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru PCLK_MIPI_DSI>, <&video_phy>; ++ clock-names = "pclk", "hs_clk"; ++ resets = <&cru SRST_MIPIDSI_HOST_P>; ++ reset-names = "apb"; ++ phys = <&video_phy>; ++ phy-names = "mipi_dphy"; ++ power-domains = <&power PX30_PD_VO>; ++ rockchip,grf = <&grf>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ dsi_in_vopb: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&vopb_out_dsi>; ++ }; ++ ++ dsi_in_vopl: endpoint@1 { ++ reg = <1>; ++ remote-endpoint = <&vopl_out_dsi>; ++ }; ++ }; ++ }; ++ }; ++ ++ vopb: vop@ff460000 { ++ compatible = "rockchip,px30-vop-big"; ++ reg = <0x0 0xff460000 0x0 0x1fc>, <0x0 0xff460a00 0x0 0x400>; ++ rockchip,grf = <&grf>; ++ reg-names = "regs", "gamma_lut"; ++ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru ACLK_VOPB>, <&cru DCLK_VOPB>, ++ <&cru HCLK_VOPB>; ++ clock-names = "aclk_vop", "dclk_vop", "hclk_vop"; ++ power-domains = <&power PX30_PD_VO>; ++ iommus = <&vopb_mmu>; ++ status = "disabled"; ++ ++ vopb_out: port { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ vopb_out_lvds: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&lvds_in_vopb>; ++ }; ++ ++ vopb_out_dsi: endpoint@1 { ++ reg = <1>; ++ remote-endpoint = <&dsi_in_vopb>; ++ }; ++ ++ vopb_out_rgb: endpoint@2 { ++ reg = <2>; ++ remote-endpoint = <&rgb_in_vopb>; ++ }; ++ }; ++ }; ++ ++ vopb_mmu: iommu@ff460f00 { ++ compatible = "rockchip,iommu"; ++ reg = <0x0 0xff460f00 0x0 0x100>; ++ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "vopb_mmu"; ++ clocks = <&cru ACLK_VOPB>, <&cru HCLK_VOPB>; ++ clock-names = "aclk", "hclk"; ++ power-domains = <&power PX30_PD_VO>; ++ #iommu-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ vopl: vop@ff470000 { ++ compatible = "rockchip,px30-vop-lit"; ++ reg = <0x0 0xff470000 0x0 0x1fc>, <0x0 0xff470a00 0x0 0x400>; ++ rockchip,grf = <&grf>; ++ reg-names = "regs", "gamma_lut"; ++ interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru ACLK_VOPL>, <&cru DCLK_VOPL>, ++ <&cru HCLK_VOPL>; ++ clock-names = "aclk_vop", "dclk_vop", "hclk_vop"; ++ power-domains = <&power PX30_PD_VO>; ++ iommus = <&vopl_mmu>; ++ status = "disabled"; ++ ++ vopl_out: port { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ vopl_out_lvds: endpoint@0 { ++ reg = <0>; ++ remote-endpoint = <&lvds_in_vopl>; ++ }; ++ ++ vopl_out_dsi: endpoint@1 { ++ reg = <1>; ++ remote-endpoint = <&dsi_in_vopl>; ++ }; ++ ++ vopl_out_rgb: endpoint@2 { ++ reg = <2>; ++ remote-endpoint = <&rgb_in_vopl>; ++ }; ++ }; ++ }; ++ ++ vopl_mmu: iommu@ff470f00 { ++ compatible = "rockchip,iommu"; ++ reg = <0x0 0xff470f00 0x0 0x100>; ++ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "vopl_mmu"; ++ clocks = <&cru ACLK_VOPL>, <&cru HCLK_VOPL>; ++ clock-names = "aclk", "hclk"; ++ power-domains = <&power PX30_PD_VO>; ++ #iommu-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ rk_rga: rk_rga@ff480000 { ++ compatible = "rockchip,rga2"; ++ //dev_mode = <1>; ++ reg = <0x0 0xff480000 0x0 0x1000>; ++ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru ACLK_RGA>, <&cru HCLK_RGA>, <&cru SCLK_RGA_CORE>; ++ clock-names = "aclk_rga", "hclk_rga", "clk_rga"; ++ power-domains = <&power PX30_PD_VO>; ++ dma-coherent; ++ status = "disabled"; ++ }; ++ ++ cif: cif@ff490000 { ++ compatible = "rockchip,cif"; ++ reg = <0x0 0xff490000 0x0 0x200>; ++ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru ACLK_CIF>, <&cru HCLK_CIF>, <&cru PCLK_CIF>, <&cru SCLK_CIF_OUT>; ++ clock-names = "aclk_cif0", "hclk_cif0", "pclk_cif", "cif0_out"; ++ resets = <&cru SRST_CIF_A>, <&cru SRST_CIF_H>, <&cru SRST_CIF_PCLKIN>; ++ reset-names = "rst_cif_a", "rst_cif_h", "rst_cif_pclkin"; ++ power-domains = <&power PX30_PD_VI>; ++ pinctrl-names = "cif_pin_all"; ++ pinctrl-0 = <&dvp_d2d9_m0>; ++ iommus = <&vip_mmu>; ++ status = "disabled"; ++ }; ++ ++ cif_new: cif-new@ff490000 { ++ compatible = "rockchip,px30-cif"; ++ reg = <0x0 0xff490000 0x0 0x200>; ++ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru ACLK_CIF>, <&cru HCLK_CIF>, <&cru PCLK_CIF>, <&cru SCLK_CIF_OUT>; ++ clock-names = "aclk_cif", "hclk_cif", "pclk_cif", "cif_out"; ++ resets = <&cru SRST_CIF_A>, <&cru SRST_CIF_H>, <&cru SRST_CIF_PCLKIN>; ++ reset-names = "rst_cif_a", "rst_cif_h", "rst_cif_pclkin"; ++ power-domains = <&power PX30_PD_VI>; ++ iommus = <&vip_mmu>; ++ status = "disabled"; ++ }; ++ ++ vip_mmu: iommu@ff490800{ ++ compatible = "rockchip,iommu"; ++ reg = <0x0 0xff490800 0x0 0x100>; ++ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "vip_mmu"; ++ clocks = <&cru ACLK_CIF>, <&cru HCLK_CIF>; ++ clock-names = "aclk", "hclk"; ++ power-domains = <&power PX30_PD_VI>; ++ rk_iommu,disable_reset_quirk; ++ #iommu-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ rk_isp: rk_isp@ff4a0000 { ++ compatible = "rockchip,px30-isp", "rockchip,isp"; ++ reg = <0x0 0xff4a0000 0x0 0x8000>; ++ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru ACLK_ISP>, <&cru HCLK_ISP>, <&cru SCLK_ISP>, <&cru SCLK_ISP>, ++ <&cru PCLK_ISP>, <&cru SCLK_CIF_OUT>, <&cru SCLK_CIF_OUT>, <&cru PCLK_MIPICSIPHY>; ++ clock-names = "aclk_isp", "hclk_isp", "clk_isp", "clk_isp_jpe", ++ "pclkin_isp", "clk_cif_pll", "clk_cif_out", "pclk_dphyrx"; ++ resets = <&cru SRST_ISP>, <&cru SRST_MIPICSIPHY_P>; ++ reset-names = "rst_isp", "rst_mipicsiphy"; ++ power-domains = <&power PX30_PD_VI>; ++ pinctrl-names = "default", "isp_dvp8bit2", "isp_dvp10bit", "isp_dvp12bit"; ++ pinctrl-0 = <&cif_clkout_m0>; ++ pinctrl-1 = <&dvp_d2d9_m0>; ++ pinctrl-2 = <&dvp_d2d9_m0 &dvp_d10d11_m0>; ++ pinctrl-3 = <&dvp_d0d1_m0 &dvp_d2d9_m0 &dvp_d10d11_m0>; ++ rockchip,isp,mipiphy = <1>; ++ rockchip,isp,csiphy,reg = <0xff2f0000 0x4000>; ++ rockchip,grf = <&grf>; ++ rockchip,cru = <&cru>; ++ rockchip,isp,iommu-enable = <1>; ++ iommus = <&isp_mmu>; ++ status = "disabled"; ++ }; ++ ++ rkisp1: rkisp1@ff4a0000 { ++ compatible = "rockchip,rk3326-rkisp1"; ++ reg = <0x0 0xff4a0000 0x0 0x8000>; ++ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "isp_irq", "mi_irq", "mipi_irq"; ++ clocks = <&cru ACLK_ISP>, <&cru HCLK_ISP>, ++ <&cru SCLK_ISP>, <&cru PCLK_ISP>; ++ clock-names = "aclk_isp", "hclk_isp", ++ "clk_isp", "pclk_isp"; ++ devfreq = <&dmc>; ++ power-domains = <&power PX30_PD_VI>; ++ iommus = <&isp_mmu>; ++ rockchip,grf = <&grf>; ++ status = "disabled"; ++ }; ++ ++ isp_mmu: iommu@ff4a8000 { ++ compatible = "rockchip,iommu"; ++ reg = <0x0 0xff4a8000 0x0 0x100>; ++ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "isp_mmu"; ++ clocks = <&cru ACLK_ISP>, <&cru HCLK_ISP>; ++ clock-names = "aclk", "hclk"; ++ power-domains = <&power PX30_PD_VI>; ++ rk_iommu,disable_reset_quirk; ++ #iommu-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ qos_gmac: qos@ff518000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff518000 0x0 0x20>; ++ }; ++ ++ qos_gpu: qos@ff520000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff520000 0x0 0x20>; ++ }; ++ ++ qos_sdmmc: qos@ff52c000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff52c000 0x0 0x20>; ++ }; ++ ++ qos_emmc: qos@ff538000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff538000 0x0 0x20>; ++ }; ++ ++ qos_nand: qos@ff538080 { ++ compatible = "syscon"; ++ reg = <0x0 0xff538080 0x0 0x20>; ++ }; ++ ++ qos_sdio: qos@ff538100 { ++ compatible = "syscon"; ++ reg = <0x0 0xff538100 0x0 0x20>; ++ }; ++ ++ qos_sfc: qos@ff538180 { ++ compatible = "syscon"; ++ reg = <0x0 0xff538180 0x0 0x20>; ++ }; ++ ++ qos_usb_host: qos@ff540000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff540000 0x0 0x20>; ++ }; ++ ++ qos_usb_otg: qos@ff540080 { ++ compatible = "syscon"; ++ reg = <0x0 0xff540080 0x0 0x20>; ++ }; ++ ++ qos_isp_128: qos@ff548000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff548000 0x0 0x20>; ++ }; ++ ++ qos_isp_rd: qos@ff548080 { ++ compatible = "syscon"; ++ reg = <0x0 0xff548080 0x0 0x20>; ++ }; ++ ++ qos_isp_wr: qos@ff548100 { ++ compatible = "syscon"; ++ reg = <0x0 0xff548100 0x0 0x20>; ++ }; ++ ++ qos_isp_m1: qos@ff548180 { ++ compatible = "syscon"; ++ reg = <0x0 0xff548180 0x0 0x20>; ++ }; ++ ++ qos_vip: qos@ff548200 { ++ compatible = "syscon"; ++ reg = <0x0 0xff548200 0x0 0x20>; ++ }; ++ ++ qos_rga_rd: qos@ff550000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff550000 0x0 0x20>; ++ }; ++ ++ qos_rga_wr: qos@ff550080 { ++ compatible = "syscon"; ++ reg = <0x0 0xff550080 0x0 0x20>; ++ }; ++ ++ qos_vop_m0: qos@ff550100 { ++ compatible = "syscon"; ++ reg = <0x0 0xff550100 0x0 0x20>; ++ }; ++ ++ qos_vop_m1: qos@ff550180 { ++ compatible = "syscon"; ++ reg = <0x0 0xff550180 0x0 0x20>; ++ }; ++ ++ qos_vpu: qos@ff558000 { ++ compatible = "syscon"; ++ reg = <0x0 0xff558000 0x0 0x20>; ++ }; ++ ++ qos_vpu_r128: qos@ff558080 { ++ compatible = "syscon"; ++ reg = <0x0 0xff558080 0x0 0x20>; ++ }; ++ ++ dfi: dfi@ff610000 { ++ reg = <0x00 0xff610000 0x00 0x400>; ++ compatible = "rockchip,px30-dfi"; ++ rockchip,pmugrf = <&pmugrf>; ++ status = "disabled"; ++ }; ++ ++ dmc: dmc { ++ compatible = "rockchip,px30-dmc"; ++ interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "complete_irq"; ++ devfreq-events = <&dfi>; ++ clocks = <&cru SCLK_DDRCLK>; ++ clock-names = "dmc_clk"; ++ operating-points-v2 = <&dmc_opp_table>; ++ ddr_timing = <&ddr_timing>; ++ upthreshold = <40>; ++ downdifferential = <20>; ++ system-status-freq = < ++ /*system status freq(KHz)*/ ++ SYS_STATUS_NORMAL 528000 ++ SYS_STATUS_REBOOT 450000 ++ SYS_STATUS_SUSPEND 194000 ++ SYS_STATUS_VIDEO_1080P 450000 ++ SYS_STATUS_BOOST 528000 ++ SYS_STATUS_ISP 666000 ++ SYS_STATUS_PERFORMANCE 666000 ++ >; ++ auto-min-freq = <328000>; ++ auto-freq-en = <1>; ++ #cooling-cells = <2>; ++ status = "disabled"; ++ ++ ddr_power_model: ddr_power_model { ++ compatible = "ddr_power_model"; ++ dynamic-power-coefficient = <120>; ++ static-power-coefficient = <200>; ++ ts = <32000 4700 (-80) 2>; ++ thermal-zone = "soc-thermal"; ++ }; ++ }; ++ ++ dmc_opp_table: dmc-opp-table { ++ compatible = "operating-points-v2"; ++ ++ rockchip,max-volt = <1150000>; ++ rockchip,evb-irdrop = <25000>; ++ ++ rockchip,pvtm-voltage-sel = < ++ 0 50000 0 ++ 50001 54000 1 ++ 54001 60000 2 ++ 60001 99999 3 ++ >; ++ rockchip,pvtm-ch = <0 0>; ++ ++ opp-194000000 { ++ opp-hz = /bits/ 64 <194000000>; ++ opp-microvolt = <950000>; ++ opp-microvolt-L0 = <950000>; ++ opp-microvolt-L1 = <950000>; ++ opp-microvolt-L2 = <950000>; ++ opp-microvolt-L3 = <950000>; ++ }; ++ opp-328000000 { ++ opp-hz = /bits/ 64 <328000000>; ++ opp-microvolt = <950000>; ++ opp-microvolt-L0 = <950000>; ++ opp-microvolt-L1 = <950000>; ++ opp-microvolt-L2 = <950000>; ++ opp-microvolt-L3 = <950000>; ++ }; ++ opp-450000000 { ++ opp-hz = /bits/ 64 <450000000>; ++ opp-microvolt = <950000>; ++ opp-microvolt-L0 = <950000>; ++ opp-microvolt-L1 = <950000>; ++ opp-microvolt-L2 = <950000>; ++ opp-microvolt-L3 = <950000>; ++ }; ++ opp-528000000 { ++ opp-hz = /bits/ 64 <528000000>; ++ opp-microvolt = <975000>; ++ opp-microvolt-L0 = <975000>; ++ opp-microvolt-L1 = <975000>; ++ opp-microvolt-L2 = <950000>; ++ opp-microvolt-L3 = <950000>; ++ }; ++ opp-666000000 { ++ opp-hz = /bits/ 64 <666000000>; ++ opp-microvolt = <1050000>; ++ opp-microvolt-L0 = <1050000>; ++ opp-microvolt-L1 = <1000000>; ++ opp-microvolt-L2 = <975000>; ++ opp-microvolt-L3 = <950000>; ++ }; ++ opp-786000000 { ++ opp-hz = /bits/ 64 <786000000>; ++ opp-microvolt = <1100000>; ++ opp-microvolt-L0 = <1100000>; ++ opp-microvolt-L1 = <1050000>; ++ opp-microvolt-L2 = <1025000>; ++ opp-microvolt-L3 = <1000000>; ++ status = "disabled"; ++ }; ++ }; ++ ++ pinctrl: pinctrl { ++ compatible = "rockchip,px30-pinctrl"; ++ rockchip,grf = <&grf>; ++ rockchip,pmu = <&pmugrf>; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ ++ gpio0: gpio0@ff040000 { ++ compatible = "rockchip,gpio-bank"; ++ reg = <0x0 0xff040000 0x0 0x100>; ++ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&pmucru PCLK_GPIO0_PMU>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ gpio1: gpio1@ff250000 { ++ compatible = "rockchip,gpio-bank"; ++ reg = <0x0 0xff250000 0x0 0x100>; ++ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru PCLK_GPIO1>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ gpio2: gpio2@ff260000 { ++ compatible = "rockchip,gpio-bank"; ++ reg = <0x0 0xff260000 0x0 0x100>; ++ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru PCLK_GPIO2>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ gpio3: gpio3@ff270000 { ++ compatible = "rockchip,gpio-bank"; ++ reg = <0x0 0xff270000 0x0 0x100>; ++ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&cru PCLK_GPIO3>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ pcfg_pull_up: pcfg-pull-up { ++ bias-pull-up; ++ }; ++ ++ pcfg_pull_down: pcfg-pull-down { ++ bias-pull-down; ++ }; ++ ++ pcfg_pull_none: pcfg-pull-none { ++ bias-disable; ++ }; ++ ++ pcfg_pull_none_2ma: pcfg-pull-none-2ma { ++ bias-disable; ++ drive-strength = <2>; ++ }; ++ ++ pcfg_pull_up_2ma: pcfg-pull-up-2ma { ++ bias-pull-up; ++ drive-strength = <2>; ++ }; ++ ++ pcfg_pull_up_4ma: pcfg-pull-up-4ma { ++ bias-pull-up; ++ drive-strength = <4>; ++ }; ++ ++ pcfg_pull_none_4ma: pcfg-pull-none-4ma { ++ bias-disable; ++ drive-strength = <4>; ++ }; ++ ++ pcfg_pull_down_4ma: pcfg-pull-down-4ma { ++ bias-pull-down; ++ drive-strength = <4>; ++ }; ++ ++ pcfg_pull_none_8ma: pcfg-pull-none-8ma { ++ bias-disable; ++ drive-strength = <8>; ++ }; ++ ++ pcfg_pull_up_8ma: pcfg-pull-up-8ma { ++ bias-pull-up; ++ drive-strength = <8>; ++ }; ++ ++ pcfg_pull_none_12ma: pcfg-pull-none-12ma { ++ bias-disable; ++ drive-strength = <12>; ++ }; ++ ++ pcfg_pull_up_12ma: pcfg-pull-up-12ma { ++ bias-pull-up; ++ drive-strength = <12>; ++ }; ++ ++ pcfg_pull_none_smt: pcfg-pull-none-smt { ++ bias-disable; ++ input-schmitt-enable; ++ }; ++ ++ pcfg_output_high: pcfg-output-high { ++ output-high; ++ }; ++ ++ pcfg_output_low: pcfg-output-low { ++ output-low; ++ }; ++ ++ pcfg_input_high: pcfg-input-high { ++ bias-pull-up; ++ input-enable; ++ }; ++ ++ pcfg_input: pcfg-input { ++ input-enable; ++ }; ++ ++ i2c0 { ++ i2c0_xfer: i2c0-xfer { ++ rockchip,pins = ++ <0 RK_PB0 RK_FUNC_1 &pcfg_pull_none_smt>, ++ <0 RK_PB1 RK_FUNC_1 &pcfg_pull_none_smt>; ++ }; ++ }; ++ ++ i2c1 { ++ i2c1_xfer: i2c1-xfer { ++ rockchip,pins = ++ <0 RK_PC2 RK_FUNC_1 &pcfg_pull_none_smt>, ++ <0 RK_PC3 RK_FUNC_1 &pcfg_pull_none_smt>; ++ }; ++ }; ++ ++ i2c2 { ++ i2c2_xfer: i2c2-xfer { ++ rockchip,pins = ++ <2 RK_PB7 RK_FUNC_2 &pcfg_pull_none_smt>, ++ <2 RK_PC0 RK_FUNC_2 &pcfg_pull_none_smt>; ++ }; ++ }; ++ ++ i2c3 { ++ i2c3_xfer: i2c3-xfer { ++ rockchip,pins = ++ <1 RK_PB4 RK_FUNC_4 &pcfg_pull_none_smt>, ++ <1 RK_PB5 RK_FUNC_4 &pcfg_pull_none_smt>; ++ }; ++ }; ++ ++ tsadc { ++ tsadc_otp_gpio: tsadc-otp-gpio { ++ rockchip,pins = ++ <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ tsadc_otp_out: tsadc-otp-out { ++ rockchip,pins = ++ <0 RK_PA6 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ uart0 { ++ uart0_xfer: uart0-xfer { ++ rockchip,pins = ++ <0 RK_PB2 RK_FUNC_1 &pcfg_pull_up>, ++ <0 RK_PB3 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ ++ uart0_cts: uart0-cts { ++ rockchip,pins = ++ <0 RK_PB4 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ uart0_rts: uart0-rts { ++ rockchip,pins = ++ <0 RK_PB5 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ uart0_rts_gpio: uart0-rts-gpio { ++ rockchip,pins = ++ <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ uart1 { ++ uart1_xfer: uart1-xfer { ++ rockchip,pins = ++ <1 RK_PC1 RK_FUNC_1 &pcfg_pull_up>, ++ <1 RK_PC0 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ ++ uart1_cts: uart1-cts { ++ rockchip,pins = ++ <1 RK_PC2 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ uart1_rts: uart1-rts { ++ rockchip,pins = ++ <1 RK_PC3 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ uart1_rts_gpio: uart1-rts-gpio { ++ rockchip,pins = ++ <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ uart2-m0 { ++ uart2m0_xfer: uart2m0-xfer { ++ rockchip,pins = ++ <1 RK_PD2 RK_FUNC_2 &pcfg_pull_up>, ++ <1 RK_PD3 RK_FUNC_2 &pcfg_pull_up>; ++ }; ++ }; ++ ++ uart2-m1 { ++ uart2m1_xfer: uart2m1-xfer { ++ rockchip,pins = ++ <2 RK_PB4 RK_FUNC_2 &pcfg_pull_up>, ++ <2 RK_PB6 RK_FUNC_2 &pcfg_pull_up>; ++ }; ++ }; ++ ++ uart3-m0 { ++ uart3m0_xfer: uart3m0-xfer { ++ rockchip,pins = ++ <0 RK_PC0 RK_FUNC_2 &pcfg_pull_up>, ++ <0 RK_PC1 RK_FUNC_2 &pcfg_pull_up>; ++ }; ++ ++ uart3m0_cts: uart3m0-cts { ++ rockchip,pins = ++ <0 RK_PC2 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ uart3m0_rts: uart3m0-rts { ++ rockchip,pins = ++ <0 RK_PC3 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ uart3m0_rts_gpio: uart3m0-rts-gpio { ++ rockchip,pins = ++ <0 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ uart3-m1 { ++ uart3m1_xfer: uart3m1-xfer { ++ rockchip,pins = ++ <1 RK_PB6 RK_FUNC_2 &pcfg_pull_up>, ++ <1 RK_PB7 RK_FUNC_2 &pcfg_pull_up>; ++ }; ++ ++ uart3m1_cts: uart3m1-cts { ++ rockchip,pins = ++ <1 RK_PB4 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ uart3m1_rts: uart3m1-rts { ++ rockchip,pins = ++ <1 RK_PB5 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ uart3m1_rts_gpio: uart3m1-rts-gpio { ++ rockchip,pins = ++ <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ uart4 { ++ ++ uart4_xfer: uart4-xfer { ++ rockchip,pins = ++ <1 RK_PD4 RK_FUNC_2 &pcfg_pull_up>, ++ <1 RK_PD5 RK_FUNC_2 &pcfg_pull_up>; ++ }; ++ ++ uart4_cts: uart4-cts { ++ rockchip,pins = ++ <1 RK_PD6 RK_FUNC_2 &pcfg_pull_none>; ++ ++ }; ++ ++ uart4_rts: uart4-rts { ++ rockchip,pins = ++ <1 RK_PD7 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ }; ++ ++ uart5 { ++ ++ uart5_xfer: uart5-xfer { ++ rockchip,pins = ++ <3 RK_PA2 RK_FUNC_4 &pcfg_pull_up>, ++ <3 RK_PA1 RK_FUNC_4 &pcfg_pull_up>; ++ }; ++ ++ uart5_cts: uart5-cts { ++ rockchip,pins = ++ <3 RK_PA3 RK_FUNC_4 &pcfg_pull_none>; ++ ++ }; ++ ++ uart5_rts: uart5-rts { ++ rockchip,pins = ++ <3 RK_PA5 RK_FUNC_4 &pcfg_pull_none>; ++ }; ++ }; ++ ++ spi0 { ++ spi0_clk: spi0-clk { ++ rockchip,pins = ++ <1 RK_PB7 RK_FUNC_3 &pcfg_pull_up_4ma>; ++ }; ++ ++ spi0_csn: spi0-csn { ++ rockchip,pins = ++ <1 RK_PB6 RK_FUNC_3 &pcfg_pull_up_4ma>; ++ }; ++ ++ spi0_miso: spi0-miso { ++ rockchip,pins = ++ <1 RK_PB5 RK_FUNC_3 &pcfg_pull_up_4ma>; ++ }; ++ ++ spi0_mosi: spi0-mosi { ++ rockchip,pins = ++ <1 RK_PB4 RK_FUNC_3 &pcfg_pull_up_4ma>; ++ }; ++ ++ spi0_clk_hs: spi0-clk-hs { ++ rockchip,pins = ++ <1 RK_PB7 RK_FUNC_3 &pcfg_pull_up_8ma>; ++ }; ++ ++ spi0_miso_hs: spi0-miso-hs { ++ rockchip,pins = ++ <1 RK_PB5 RK_FUNC_3 &pcfg_pull_up_8ma>; ++ }; ++ ++ spi0_mosi_hs: spi0-mosi-hs { ++ rockchip,pins = ++ <1 RK_PB4 RK_FUNC_3 &pcfg_pull_up_8ma>; ++ }; ++ }; ++ ++ spi1 { ++ spi1_clk: spi1-clk { ++ rockchip,pins = ++ <3 RK_PB7 RK_FUNC_4 &pcfg_pull_up_4ma>; ++ }; ++ ++ spi1_csn0: spi1-csn0 { ++ rockchip,pins = ++ <3 RK_PB1 RK_FUNC_4 &pcfg_pull_up_4ma>; ++ }; ++ ++ spi1_csn1: spi1-csn1 { ++ rockchip,pins = ++ <3 RK_PB2 RK_FUNC_2 &pcfg_pull_up_4ma>; ++ }; ++ ++ spi1_miso: spi1-miso { ++ rockchip,pins = ++ <3 RK_PB6 RK_FUNC_4 &pcfg_pull_up_4ma>; ++ }; ++ ++ spi1_mosi: spi1-mosi { ++ rockchip,pins = ++ <3 RK_PB4 RK_FUNC_4 &pcfg_pull_up_4ma>; ++ }; ++ ++ spi1_clk_hs: spi1-clk-hs { ++ rockchip,pins = ++ <3 RK_PB7 RK_FUNC_4 &pcfg_pull_up_8ma>; ++ }; ++ ++ spi1_miso_hs: spi1-miso-hs { ++ rockchip,pins = ++ <3 RK_PB6 RK_FUNC_4 &pcfg_pull_up_8ma>; ++ }; ++ ++ spi1_mosi_hs: spi1-mosi-hs { ++ rockchip,pins = ++ <3 RK_PB4 RK_FUNC_4 &pcfg_pull_up_8ma>; ++ }; ++ }; ++ ++ pdm { ++ pdm_clk0m0: pdm-clk0m0 { ++ rockchip,pins = ++ <3 RK_PC6 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ pdm_clk0m1: pdm-clk0m1 { ++ rockchip,pins = ++ <2 RK_PC6 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ pdm_clk1: pdm-clk1 { ++ rockchip,pins = ++ <3 RK_PC7 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ pdm_sdi0m0: pdm-sdi0m0 { ++ rockchip,pins = ++ <3 RK_PD3 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ pdm_sdi0m1: pdm-sdi0m1 { ++ rockchip,pins = ++ <2 RK_PC5 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ pdm_sdi1: pdm-sdi1 { ++ rockchip,pins = ++ <3 RK_PD0 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ pdm_sdi2: pdm-sdi2 { ++ rockchip,pins = ++ <3 RK_PD1 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ pdm_sdi3: pdm-sdi3 { ++ rockchip,pins = ++ <3 RK_PD2 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ pdm_clk0m0_sleep: pdm-clk0m0-sleep { ++ rockchip,pins = ++ <3 RK_PC6 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ ++ pdm_clk0m_sleep1: pdm-clk0m1-sleep { ++ rockchip,pins = ++ <2 RK_PC6 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ ++ pdm_clk1_sleep: pdm-clk1-sleep { ++ rockchip,pins = ++ <3 RK_PC7 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ ++ pdm_sdi0m0_sleep: pdm-sdi0m0-sleep { ++ rockchip,pins = ++ <3 RK_PD3 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ ++ pdm_sdi0m1_sleep: pdm-sdi0m1-sleep { ++ rockchip,pins = ++ <2 RK_PC5 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ ++ pdm_sdi1_sleep: pdm-sdi1-sleep { ++ rockchip,pins = ++ <3 RK_PD0 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ ++ pdm_sdi2_sleep: pdm-sdi2-sleep { ++ rockchip,pins = ++ <3 RK_PD1 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ ++ pdm_sdi3_sleep: pdm-sdi3-sleep { ++ rockchip,pins = ++ <3 RK_PD2 RK_FUNC_GPIO &pcfg_input_high>; ++ }; ++ }; ++ ++ i2s0 { ++ i2s0_8ch_mclk: i2s0-8ch-mclk { ++ rockchip,pins = ++ <3 RK_PC1 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sclktx: i2s0-8ch-sclktx { ++ rockchip,pins = ++ <3 RK_PC3 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sclkrx: i2s0-8ch-sclkrx { ++ rockchip,pins = ++ <3 RK_PB4 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_lrcktx: i2s0-8ch-lrcktx { ++ rockchip,pins = ++ <3 RK_PC2 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_lrckrx: i2s0-8ch-lrckrx { ++ rockchip,pins = ++ <3 RK_PB5 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdo0: i2s0-8ch-sdo0 { ++ rockchip,pins = ++ <3 RK_PC4 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdo1: i2s0-8ch-sdo1 { ++ rockchip,pins = ++ <3 RK_PC0 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdo2: i2s0-8ch-sdo2 { ++ rockchip,pins = ++ <3 RK_PB7 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdo3: i2s0-8ch-sdo3 { ++ rockchip,pins = ++ <3 RK_PB6 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdi0: i2s0-8ch-sdi0 { ++ rockchip,pins = ++ <3 RK_PC5 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdi1: i2s0-8ch-sdi1 { ++ rockchip,pins = ++ <3 RK_PB3 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdi2: i2s0-8ch-sdi2 { ++ rockchip,pins = ++ <3 RK_PB1 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s0_8ch_sdi3: i2s0-8ch-sdi3 { ++ rockchip,pins = ++ <3 RK_PB0 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ }; ++ ++ i2s1 { ++ i2s1_2ch_mclk: i2s1-2ch-mclk { ++ rockchip,pins = ++ <2 RK_PC3 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ i2s1_2ch_sclk: i2s1-2ch-sclk { ++ rockchip,pins = ++ <2 RK_PC2 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ i2s1_2ch_lrck: i2s1-2ch-lrck { ++ rockchip,pins = ++ <2 RK_PC1 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ i2s1_2ch_sdi: i2s1-2ch-sdi { ++ rockchip,pins = ++ <2 RK_PC5 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ i2s1_2ch_sdo: i2s1-2ch-sdo { ++ rockchip,pins = ++ <2 RK_PC4 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ i2s2 { ++ i2s2_2ch_mclk: i2s2-2ch-mclk { ++ rockchip,pins = ++ <3 RK_PA1 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s2_2ch_sclk: i2s2-2ch-sclk { ++ rockchip,pins = ++ <3 RK_PA2 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s2_2ch_lrck: i2s2-2ch-lrck { ++ rockchip,pins = ++ <3 RK_PA3 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s2_2ch_sdi: i2s2-2ch-sdi { ++ rockchip,pins = ++ <3 RK_PA5 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ i2s2_2ch_sdo: i2s2-2ch-sdo { ++ rockchip,pins = ++ <3 RK_PA7 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ }; ++ ++ sdmmc { ++ sdmmc_clk: sdmmc-clk { ++ rockchip,pins = ++ <1 RK_PD6 RK_FUNC_1 &pcfg_pull_none_8ma>; ++ }; ++ ++ sdmmc_cmd: sdmmc-cmd { ++ rockchip,pins = ++ <1 RK_PD7 RK_FUNC_1 &pcfg_pull_up_8ma>; ++ }; ++ ++ sdmmc_det: sdmmc-det { ++ rockchip,pins = ++ <0 RK_PA3 RK_FUNC_1 &pcfg_pull_up_8ma>; ++ }; ++ ++ sdmmc_bus1: sdmmc-bus1 { ++ rockchip,pins = ++ <1 RK_PD2 RK_FUNC_1 &pcfg_pull_up_8ma>; ++ }; ++ ++ sdmmc_bus4: sdmmc-bus4 { ++ rockchip,pins = ++ <1 RK_PD2 RK_FUNC_1 &pcfg_pull_up_8ma>, ++ <1 RK_PD3 RK_FUNC_1 &pcfg_pull_up_8ma>, ++ <1 RK_PD4 RK_FUNC_1 &pcfg_pull_up_8ma>, ++ <1 RK_PD5 RK_FUNC_1 &pcfg_pull_up_8ma>; ++ }; ++ ++ sdmmc_clk_4ma: sdmmc-clk-4ma { ++ rockchip,pins = ++ <1 RK_PD6 RK_FUNC_1 &pcfg_pull_none_4ma>; ++ }; ++ ++ sdmmc_cmd_4ma: sdmmc-cmd-4ma { ++ rockchip,pins = ++ <1 RK_PD7 RK_FUNC_1 &pcfg_pull_up_4ma>; ++ }; ++ ++ sdmmc_det_4ma: sdmmc-det-4ma { ++ rockchip,pins = ++ <0 RK_PA3 RK_FUNC_1 &pcfg_pull_up_4ma>; ++ }; ++ ++ sdmmc_bus1_4ma: sdmmc-bus1-4ma { ++ rockchip,pins = ++ <1 RK_PD2 RK_FUNC_1 &pcfg_pull_up_4ma>; ++ }; ++ ++ sdmmc_bus4_4ma: sdmmc-bus4-4ma { ++ rockchip,pins = ++ <1 RK_PD2 RK_FUNC_1 &pcfg_pull_up_4ma>, ++ <1 RK_PD3 RK_FUNC_1 &pcfg_pull_up_4ma>, ++ <1 RK_PD4 RK_FUNC_1 &pcfg_pull_up_4ma>, ++ <1 RK_PD5 RK_FUNC_1 &pcfg_pull_up_4ma>; ++ }; ++ ++ sdmmc_gpio: sdmmc-gpio { ++ rockchip,pins = ++ <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up_4ma>, ++ <1 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up_4ma>, ++ <1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up_4ma>, ++ <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_up_4ma>, ++ <1 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up_4ma>, ++ <1 RK_PD7 RK_FUNC_GPIO &pcfg_pull_up_4ma>; ++ }; ++ }; ++ ++ sdio { ++ sdio_clk: sdio-clk { ++ rockchip,pins = ++ <1 RK_PC5 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ sdio_cmd: sdio-cmd { ++ rockchip,pins = ++ <1 RK_PC4 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ ++ sdio_bus4: sdio-bus4 { ++ rockchip,pins = ++ <1 RK_PC6 RK_FUNC_1 &pcfg_pull_up>, ++ <1 RK_PC7 RK_FUNC_1 &pcfg_pull_up>, ++ <1 RK_PD0 RK_FUNC_1 &pcfg_pull_up>, ++ <1 RK_PD1 RK_FUNC_1 &pcfg_pull_up>; ++ }; ++ ++ sdio_gpio: sdio-gpio { ++ rockchip,pins = ++ <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PC7 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_up>, ++ <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ emmc { ++ emmc_clk: emmc-clk { ++ rockchip,pins = ++ <1 RK_PB1 RK_FUNC_2 &pcfg_pull_none_8ma>; ++ }; ++ ++ emmc_cmd: emmc-cmd { ++ rockchip,pins = ++ <1 RK_PB2 RK_FUNC_2 &pcfg_pull_up_8ma>; ++ }; ++ ++ emmc_pwren: emmc-pwren { ++ rockchip,pins = ++ <1 RK_PB0 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ emmc_rstnout: emmc-rstnout { ++ rockchip,pins = ++ <1 RK_PB3 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ emmc_bus1: emmc-bus1 { ++ rockchip,pins = ++ <1 RK_PA0 RK_FUNC_2 &pcfg_pull_up_8ma>; ++ }; ++ ++ emmc_bus4: emmc-bus4 { ++ rockchip,pins = ++ <1 RK_PA0 RK_FUNC_2 &pcfg_pull_up_8ma>, ++ <1 RK_PA1 RK_FUNC_2 &pcfg_pull_up_8ma>, ++ <1 RK_PA2 RK_FUNC_2 &pcfg_pull_up_8ma>, ++ <1 RK_PA3 RK_FUNC_2 &pcfg_pull_up_8ma>; ++ }; ++ ++ emmc_bus8: emmc-bus8 { ++ rockchip,pins = ++ <1 RK_PA0 RK_FUNC_2 &pcfg_pull_up_8ma>, ++ <1 RK_PA1 RK_FUNC_2 &pcfg_pull_up_8ma>, ++ <1 RK_PA2 RK_FUNC_2 &pcfg_pull_up_8ma>, ++ <1 RK_PA3 RK_FUNC_2 &pcfg_pull_up_8ma>, ++ <1 RK_PA4 RK_FUNC_2 &pcfg_pull_up_8ma>, ++ <1 RK_PA5 RK_FUNC_2 &pcfg_pull_up_8ma>, ++ <1 RK_PA6 RK_FUNC_2 &pcfg_pull_up_8ma>, ++ <1 RK_PA7 RK_FUNC_2 &pcfg_pull_up_8ma>; ++ }; ++ }; ++ ++ flash { ++ flash_cs0: flash-cs0 { ++ rockchip,pins = ++ <1 RK_PB0 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ flash_rdy: flash-rdy { ++ rockchip,pins = ++ <1 RK_PB1 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ flash_dqs: flash-dqs { ++ rockchip,pins = ++ <1 RK_PB2 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ flash_ale: flash-ale { ++ rockchip,pins = ++ <1 RK_PB3 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ flash_cle: flash-cle { ++ rockchip,pins = ++ <1 RK_PB4 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ flash_wrn: flash-wrn { ++ rockchip,pins = ++ <1 RK_PB5 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ flash_csl: flash-csl { ++ rockchip,pins = ++ <1 RK_PB6 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ flash_rdn: flash-rdn { ++ rockchip,pins = ++ <1 RK_PB7 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ ++ flash_bus8: flash-bus8 { ++ rockchip,pins = ++ <1 RK_PA0 RK_FUNC_1 &pcfg_pull_up_12ma>, ++ <1 RK_PA1 RK_FUNC_1 &pcfg_pull_up_12ma>, ++ <1 RK_PA2 RK_FUNC_1 &pcfg_pull_up_12ma>, ++ <1 RK_PA3 RK_FUNC_1 &pcfg_pull_up_12ma>, ++ <1 RK_PA4 RK_FUNC_1 &pcfg_pull_up_12ma>, ++ <1 RK_PA5 RK_FUNC_1 &pcfg_pull_up_12ma>, ++ <1 RK_PA6 RK_FUNC_1 &pcfg_pull_up_12ma>, ++ <1 RK_PA7 RK_FUNC_1 &pcfg_pull_up_12ma>; ++ }; ++ }; ++ ++ lcdc { ++ lcdc_m0_rgb_pins: lcdc-m0-rgb-pins { ++ rockchip,pins = ++ <3 RK_PA0 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_DCLK */ ++ <3 RK_PA1 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_HSYNC */ ++ <3 RK_PA2 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_VSYNC */ ++ <3 RK_PA3 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_DEN */ ++ <3 RK_PA4 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_D0 */ ++ <3 RK_PA5 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_D1 */ ++ <3 RK_PA6 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_D2 */ ++ <3 RK_PA7 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_D3 */ ++ <3 RK_PB0 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_D4 */ ++ <3 RK_PB1 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_D5 */ ++ <3 RK_PB2 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_D6 */ ++ <3 RK_PB3 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_D7 */ ++ <3 RK_PB4 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_D8 */ ++ <3 RK_PB5 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_D9 */ ++ <3 RK_PB6 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_D10 */ ++ <3 RK_PB7 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_D11 */ ++ <3 RK_PC0 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_D12 */ ++ <3 RK_PC1 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_D13 */ ++ <3 RK_PC2 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_D14 */ ++ <3 RK_PC3 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_D15 */ ++ <3 RK_PC4 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_D16 */ ++ <3 RK_PC5 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_D17 */ ++ <3 RK_PC6 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_D18 */ ++ <3 RK_PC7 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_D19 */ ++ <3 RK_PD0 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_D20 */ ++ <3 RK_PD1 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_D21 */ ++ <3 RK_PD2 RK_FUNC_1 &pcfg_pull_none_8ma>, /* LCDC_D22 */ ++ <3 RK_PD3 RK_FUNC_1 &pcfg_pull_none_8ma>; /* LCDC_D23 */ ++ }; ++ ++ lcdc_m0_sleep_pins: lcdc-m0-sleep-pins { ++ rockchip,pins = ++ <3 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_DCLK */ ++ <3 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_HSYNC */ ++ <3 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_VSYNC */ ++ <3 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_DEN */ ++ <3 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_D0 */ ++ <3 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_D1 */ ++ <3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_D2 */ ++ <3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_D3 */ ++ <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_D4 */ ++ <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_D5 */ ++ <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_D6 */ ++ <3 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_D7 */ ++ <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_D8 */ ++ <3 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_D9 */ ++ <3 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_D10 */ ++ <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_D11 */ ++ <3 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_D12 */ ++ <3 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_D13 */ ++ <3 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_D14 */ ++ <3 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_D15 */ ++ <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_D16 */ ++ <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_D17 */ ++ <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_D18 */ ++ <3 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_D19 */ ++ <3 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_D20 */ ++ <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_D21 */ ++ <3 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>, /* LCDC_D22 */ ++ <3 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>; /* LCDC_D23 */ ++ }; ++ }; ++ ++ pwm0 { ++ pwm0_pin: pwm0-pin { ++ rockchip,pins = ++ <0 RK_PB7 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ pwm1 { ++ pwm1_pin: pwm1-pin { ++ rockchip,pins = ++ <0 RK_PC0 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ pwm2 { ++ pwm2_pin: pwm2-pin { ++ rockchip,pins = ++ <2 RK_PB5 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ pwm3 { ++ pwm3_pin: pwm3-pin { ++ rockchip,pins = ++ <0 RK_PC1 RK_FUNC_1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ pwm4 { ++ pwm4_pin: pwm4-pin { ++ rockchip,pins = ++ <3 RK_PC2 RK_FUNC_3 &pcfg_pull_none>; ++ }; ++ }; ++ ++ pwm5 { ++ pwm5_pin: pwm5-pin { ++ rockchip,pins = ++ <3 RK_PC3 RK_FUNC_3 &pcfg_pull_none>; ++ }; ++ }; ++ ++ pwm6 { ++ pwm6_pin: pwm6-pin { ++ rockchip,pins = ++ <3 RK_PC4 RK_FUNC_3 &pcfg_pull_none>; ++ }; ++ }; ++ ++ pwm7 { ++ pwm7_pin: pwm7-pin { ++ rockchip,pins = ++ <3 RK_PC5 RK_FUNC_3 &pcfg_pull_none>; ++ }; ++ }; ++ ++ gmac { ++ rmii_pins: rmii-pins { ++ rockchip,pins = ++ /* mac_txen */ ++ <2 RK_PA0 RK_FUNC_2 &pcfg_pull_none_12ma>, ++ /* mac_txd1 */ ++ <2 RK_PA1 RK_FUNC_2 &pcfg_pull_none_12ma>, ++ /* mac_txd0 */ ++ <2 RK_PA2 RK_FUNC_2 &pcfg_pull_none_12ma>, ++ /* mac_rxd0 */ ++ <2 RK_PA3 RK_FUNC_2 &pcfg_pull_none>, ++ /* mac_rxd1 */ ++ <2 RK_PA4 RK_FUNC_2 &pcfg_pull_none>, ++ /* mac_rxer */ ++ <2 RK_PA5 RK_FUNC_2 &pcfg_pull_none>, ++ /* mac_rxdv */ ++ <2 RK_PA6 RK_FUNC_2 &pcfg_pull_none>, ++ /* mac_mdio */ ++ <2 RK_PA7 RK_FUNC_2 &pcfg_pull_none>, ++ /* mac_mdc */ ++ <2 RK_PB1 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ ++ mac_refclk_12ma: mac-refclk-12ma { ++ rockchip,pins = ++ <2 RK_PB2 RK_FUNC_2 &pcfg_pull_none_12ma>; ++ }; ++ ++ mac_refclk: mac-refclk { ++ rockchip,pins = ++ <2 RK_PB2 RK_FUNC_2 &pcfg_pull_none>; ++ }; ++ }; ++ ++ cif-m0 { ++ cif_clkout_m0: cif-clkout-m0 { ++ rockchip,pins = <2 RK_PB3 RK_FUNC_1 &pcfg_pull_none_12ma>;/* cif_clkout */ ++ }; ++ ++ dvp_d2d9_m0: dvp-d2d9-m0 { ++ rockchip,pins = ++ <2 RK_PA0 RK_FUNC_1 &pcfg_pull_none>,/* cif_data2 */ ++ <2 RK_PA1 RK_FUNC_1 &pcfg_pull_none>,/* cif_data3 */ ++ <2 RK_PA2 RK_FUNC_1 &pcfg_pull_none>,/* cif_data4 */ ++ <2 RK_PA3 RK_FUNC_1 &pcfg_pull_none>,/* cif_data5 */ ++ <2 RK_PA4 RK_FUNC_1 &pcfg_pull_none>,/* cif_data6 */ ++ <2 RK_PA5 RK_FUNC_1 &pcfg_pull_none>,/* cif_data7 */ ++ <2 RK_PA6 RK_FUNC_1 &pcfg_pull_none>,/* cif_data8 */ ++ <2 RK_PA7 RK_FUNC_1 &pcfg_pull_none>,/* cif_data9 */ ++ <2 RK_PB0 RK_FUNC_1 &pcfg_pull_none>,/* cif_sync */ ++ <2 RK_PB1 RK_FUNC_1 &pcfg_pull_none>,/* cif_href */ ++ <2 RK_PB2 RK_FUNC_1 &pcfg_pull_none>,/* cif_clkin */ ++ <2 RK_PB3 RK_FUNC_1 &pcfg_pull_none>;/* cif_clkout */ ++ }; ++ ++ dvp_d0d1_m0: dvp-d0d1-m0 { ++ rockchip,pins = ++ <2 RK_PB4 RK_FUNC_1 &pcfg_pull_none>,/* cif_data0 */ ++ <2 RK_PB6 RK_FUNC_1 &pcfg_pull_none>;/* cif_data1 */ ++ }; ++ ++ dvp_d10d11_m0:d10-d11-m0 { ++ rockchip,pins = ++ <2 RK_PB7 RK_FUNC_1 &pcfg_pull_none>,/* cif_data10 */ ++ <2 RK_PC0 RK_FUNC_1 &pcfg_pull_none>;/* cif_data11 */ ++ }; ++ }; ++ ++ cif-m1 { ++ cif_clkout_m1: cif-clkout-m1 { ++ rockchip,pins = <3 RK_PD0 RK_FUNC_3 &pcfg_pull_none>;/* cif_clkout */ ++ }; ++ ++ dvp_d2d9_m1: dvp-d2d9-m1 { ++ rockchip,pins = ++ <3 RK_PA3 RK_FUNC_3 &pcfg_pull_none>,/* cif_data2 */ ++ <3 RK_PA5 RK_FUNC_3 &pcfg_pull_none>,/* cif_data3 */ ++ <3 RK_PA7 RK_FUNC_3 &pcfg_pull_none>,/* cif_data4 */ ++ <3 RK_PB0 RK_FUNC_3 &pcfg_pull_none>,/* cif_data5 */ ++ <3 RK_PB1 RK_FUNC_3 &pcfg_pull_none>,/* cif_data6 */ ++ <3 RK_PB4 RK_FUNC_3 &pcfg_pull_none>,/* cif_data7 */ ++ <3 RK_PB6 RK_FUNC_3 &pcfg_pull_none>,/* cif_data8 */ ++ <3 RK_PB7 RK_FUNC_3 &pcfg_pull_none>,/* cif_data9 */ ++ <3 RK_PD1 RK_FUNC_3 &pcfg_pull_none>,/* cif_sync */ ++ <3 RK_PD2 RK_FUNC_3 &pcfg_pull_none>,/* cif_href */ ++ <3 RK_PD3 RK_FUNC_3 &pcfg_pull_none>,/* cif_clkin */ ++ <3 RK_PD0 RK_FUNC_3 &pcfg_pull_none>;/* cif_clkout */ ++ }; ++ ++ dvp_d0d1_m1: dvp-d0d1-m1 { ++ rockchip,pins = ++ <3 RK_PA1 RK_FUNC_3 &pcfg_pull_none>,/* cif_data0 */ ++ <3 RK_PA2 RK_FUNC_3 &pcfg_pull_none>;/* cif_data1 */ ++ }; ++ ++ dvp_d10d11_m1:d10-d11-m1 { ++ rockchip,pins = ++ <3 RK_PC6 RK_FUNC_3 &pcfg_pull_none>,/* cif_data10 */ ++ <3 RK_PC7 RK_FUNC_3 &pcfg_pull_none>;/* cif_data11 */ ++ }; ++ }; ++ ++ isp { ++ isp_prelight: isp-prelight { ++ rockchip,pins = <3 RK_PD1 RK_FUNC_4 &pcfg_pull_none>;/* ISP_PRELIGHTTRIG */ ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10-linux.dts b/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10-linux.dts +index f943c7f..653e560 100644 +--- a/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10-linux.dts ++++ b/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10-linux.dts +@@ -3,18 +3,32 @@ + * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd + */ + ++/* 1 => ADV7535, 2 => IT9611 */ ++#define DSI2HDMI_BRIDGE 2 ++ + /dts-v1/; + #include <dt-bindings/gpio/gpio.h> + #include <dt-bindings/pinctrl/rockchip.h> + #include <dt-bindings/input/input.h> + #include <dt-bindings/display/drm_mipi_dsi.h> + #include <dt-bindings/sensor-dev.h> +-#include "px30.dtsi" ++#include "lec-px30.dtsi" + #include "rk3326-linux.dtsi" ++//#include "lcd_1024x600_mipi.dtsi" ++//#include "lcd_1920x1200_mipi.dtsi" ++//#include "lcd_720x1280_mipi.dtsi" ++//#include "lcd_1280x800_lvds.dtsi" ++#if DSI2HDMI_BRIDGE == 1 ++#include "lcd_1920x1080_mipi.dtsi" ++#endif ++#if DSI2HDMI_BRIDGE == 2 ++#include "dsi2hdmi_lt9611.dtsi" ++#endif + + / { +- model = "Rockchip linux PX30 evb ddr3 board"; +- compatible = "rockchip,px30-evb-ddr3-v10-linux", "rockchip,px30"; ++ ++ model = "ADLINK ARM, LEC-PX30"; ++ compatible = "adlink,lec-px30"; + + adc-keys { + compatible = "adc-keys"; +@@ -54,6 +68,11 @@ + }; + }; + ++ adc_test{ ++ compatible = "rockchip,adc_test"; ++ io-channels = <&saradc 0>; ++ }; ++ + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pwm1 0 25000 0>; +@@ -91,6 +110,7 @@ + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255>; + default-brightness-level = <200>; ++ /*enable-gpios=<&gpio0 15 GPIO_ACTIVE_HIGH>*/ + }; + + charge-animation { +@@ -101,7 +121,7 @@ + rockchip,screen-on-voltage = <3600>; + status = "okay"; + }; +- ++#if 0 + rk809-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; +@@ -122,37 +142,168 @@ + sound-dai = <&rk809_codec>; + }; + }; +- +- rk_headset { ++#endif ++ ++#if 0 ++ tlv320-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,name = "rockchip,tlv320-codec"; ++ simple-audio-card,mclk-fs = <256>; ++ simple-audio-card,widgets = ++ "Microphone", "Mic Jack", ++ "Line", "Line In", ++ "Line", "Line Out", ++ "Speaker", "Speaker", ++ "Headphone", "Headphone Jack"; ++ simple-audio-card,routing = ++ "Line Out", "LLOUT", ++ "Line Out", "RLOUT", ++ "Headphone Jack", "HPLOUT", ++ "Headphone Jack", "HPROUT", ++ "MIC3L", "Mic Jack", ++ "MIC3R", "Mic Jack", ++ "Mic Jack", "Mic Bias", ++ "LINE1L", "Line In", ++ "LINE1R", "Line In"; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&i2s2_2ch>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&tlv320_codec>; ++ }; ++ }; ++ ++#endif ++ rt5640-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,name = "rockchip,rt5640-codec"; ++ simple-audio-card,mclk-fs = <256>; ++ simple-audio-card,widgets = ++ "Microphone", "Mic Jack", ++ "Headphone", "Headphone Jack"; ++ simple-audio-card,routing = ++ "Mic Jack", "MICBIAS1", ++ "IN1P", "Mic Jack", ++ "Headphone Jack", "HPOL", ++ "Headphone Jack", "HPOR"; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s1_2ch>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&rt5640>; ++ }; ++ }; ++ ++ ++ px30_lanxus_gpioset { ++ compatible = "lanxus-px30,gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&lanxus_gpioset>; ++ REBOOT_GPIO=<&gpio3 6 GPIO_ACTIVE_HIGH>;/*change to GPIO3_A6*/ ++ /*PHY_PWR = <&gpio2 8 GPIO_ACTIVE_LOW>;*/ ++ status = "okay"; ++ }; ++ /* ++ sgtl5000-sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,name = "rockchip,sgtl5000-codec"; ++ simple-audio-card,mclk-fs = <256>; ++ simple-audio-card,widgets = ++ "Microphone", "Mic Jack", ++ "Line", "Line In", ++ "Line", "Line Out", ++ "Headphone", "Headphone Jack"; ++ simple-audio-card,routing = ++ "MIC_IN", "Mic Jack", ++ "Mic Jack", "Mic Bias", ++ "Headphone Jack", "HP_OUT"; ++ simple-audio-card,cpu { ++ sound-dai = <&i2s2_2ch>; ++ }; ++ simple-audio-card,codec { ++ sound-dai = <&sgtl5000_codec>; ++ }; ++ }; ++ */ ++ ++ /*rk_headset { + compatible = "rockchip_headset"; + headset_gpio = <&gpio2 RK_PB0 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&hp_det>; + io-channels = <&saradc 1>; +- }; ++ };*/ + +- sdio_pwrseq: sdio-pwrseq { ++/* sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; +- /*clocks = <&rk809 1>;*/ +- /*clock-names = "ext_clock";*/ ++ clocks = <&rk809 1>; ++ clock-names = "ext_clock"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h>; +- ++*/ + /* + * On the module itself this is one of these (depending + * on the actual card populated): + * - SDIO_RESET_L_WL_REG_ON + * - PDN (power down when low) + */ +- reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; /* GPIO3_A4 */ +- }; ++/* reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; ++ };*/ ++ ++ ++ clk20m: clk20m { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <20000000>; ++ }; + + vcc_phy: vcc-phy-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_phy"; ++ /*gpio = <&gpio2 8 GPIO_ACTIVE_HIGH>; ++ pinctrl-name="default"; ++ pinctrl-0=<ð_phy_pwr>;*/ + regulator-always-on; + regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ }; ++ ++ // ++ vcc_sd_pwr: sdmmc-regulator { ++ compatible = "regulator-fixed"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc_pwr>; ++ /*gpio = <&gpio0 2 GPIO_ACTIVE_HIGH>;*/ ++ regulator-name = "vcc_sd_pwr"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ /*startup-delay-us = <100000>;*/ ++ }; ++ ++ ++ ++ sound_1v8: sound_1v8 { ++ compatible = "regulator-fixed"; ++ regulator-name = "sound_1v8"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; + }; ++ ++ sound_3v3: sound_3v3 { ++ compatible = "regulator-fixed"; ++ regulator-name = "sound_3v3"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ }; + + vcc5v0_sys: vccsys { + compatible = "regulator-fixed"; +@@ -165,12 +316,12 @@ + + wireless-wlan { + compatible = "wlan-platdata"; +- wifi_chip_type = "AP6210"; +- WIFI,host_wake_irq = <&gpio0 RK_PB2 GPIO_ACTIVE_HIGH>; ++ wifi_chip_type = "rtl8723bu"; ++ /*WIFI,host_wake_irq = <&gpio0 RK_PB2 GPIO_ACTIVE_HIGH>;*/ + status = "okay"; + }; + +- wireless-bluetooth { ++/* wireless-bluetooth { + compatible = "bluetooth-platdata"; + clocks = <&rk809 1>; + clock-names = "ext_clock"; +@@ -178,17 +329,17 @@ + pinctrl-names = "default","rts_gpio"; + pinctrl-0 = <&uart1_rts>; + pinctrl-1 = <&uart1_rts_gpio>; +- BT,reset_gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; +- BT,wake_gpio = <&gpio2 RK_PB0 GPIO_ACTIVE_HIGH>; ++ BT,reset_gpio = <&gpio2 RK_PB0 GPIO_ACTIVE_HIGH>; ++ BT,wake_gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; + BT,wake_host_irq = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>; +- status = "okay"; +- }; ++ status = "disabled"; ++ };*/ + }; + + &display_subsystem { + status = "okay"; + }; +- ++/* moved lcd_1920x1200_mipi.dtsi + &dsi { + status = "okay"; + +@@ -211,8 +362,8 @@ + MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>; + dsi,format = <MIPI_DSI_FMT_RGB888>; + dsi,lanes = <4>; +- +- panel-init-sequence = [ ++*/ ++ /*panel-init-sequence = [ + 05 fa 01 11 + 39 00 04 b9 f1 12 83 + 39 00 1c ba 33 81 05 f9 0e 0e 00 00 00 +@@ -258,21 +409,21 @@ + panel-exit-sequence = [ + 05 00 01 28 + 05 00 01 10 +- ]; ++ ];*/ + +- display-timings { ++/* display-timings { + native-mode = <&timing0>; + + timing0: timing0 { +- clock-frequency = <64000000>; +- hactive = <720>; +- vactive = <1280>; +- hfront-porch = <40>; +- hsync-len = <10>; +- hback-porch = <40>; +- vfront-porch = <22>; +- vsync-len = <4>; +- vback-porch = <11>; ++ clock-frequency = <60000000>; ++ hactive = <1024>; ++ vactive = <600>; ++ hfront-porch = <150>; ++ hsync-len = <20>; ++ hback-porch = <150>; ++ vfront-porch = <8>; ++ vsync-len = <3>; ++ vback-porch = <24>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; +@@ -281,20 +432,7 @@ + }; + }; + }; +- +-&dsi_in_vopb { +- status = "okay"; +-}; +- +-&dsi_in_vopl { +- status = "disabled"; +-}; +- +-&route_dsi { +- connect = <&vopb_out_dsi>; +- status = "okay"; +-}; +- ++*/ + &bus_apll { + bus-supply = <&vdd_logic>; + status = "okay"; +@@ -304,6 +442,11 @@ + cpu-supply = <&vdd_arm>; + }; + ++/* move to moved lcd_1920x1200_mipi.dtsi ++&dsi_in_vopl { ++ status = "disabled"; ++}; ++*/ + &dfi { + status = "okay"; + }; +@@ -326,10 +469,16 @@ + + &gmac { + phy-supply = <&vcc_phy>; +- clock_in_out = "output"; ++ clock_in_out = "input"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rmii_pins &mac_refclk_12ma ð_phy_pwr>; ++ snps,power-gpio= <&gpio2 8 GPIO_ACTIVE_HIGH>; + snps,reset-gpio = <&gpio2 13 GPIO_ACTIVE_LOW>; + snps,reset-active-low; +- snps,reset-delays-us = <0 50000 50000>; ++ snps,reset-delays-us = <0 100000 100000>; ++ max-speed=<100>; ++/* tx_delay = <0x0>; ++ rx_delay=<0x0>; */ + status = "okay"; + }; + +@@ -338,6 +487,66 @@ + status = "okay"; + }; + ++&spi0 { ++ status = "okay"; ++ max-freq = <48000000>; ++ spi_dev@0 { ++ status = "okay"; ++ compatible = "rockchip,spidev"; ++ reg = <0>; ++ spi-max-frequency = <48000000>; ++ spi-lsb-first; ++ spi-gpio-cs= <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; ++ }; ++ ++ /* spidemo@00 { ++ compatible = "lanxus,px30-spi"; ++ reg = <0x00>; ++ spi-max-frequency = <48000000>; ++ spi-gpio-cs= <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; ++ };*/ ++ ++}; ++ ++ ++&spi1 { ++ status = "okay"; ++ max-freq = <50000000>; ++ ++ can0: can@0 { ++ compatible = "microchip,mcp2517fd"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&can_int>; ++ reg = <0>; ++ clocks = <&clk20m>; ++ spi-max-frequency = <10000000>; ++ interrupt-parent = <&gpio0>; ++ interrupts = <17 IRQ_TYPE_LEVEL_LOW>; ++ ++ }; ++ ++ /*spidev@01 { ++ status = "okay"; ++ compatible = "rockchip,spidev"; ++ reg = <1>; ++ spi-max-frequency = <24000000>; ++ };*/ ++/* can2: can@2 { ++ compatible = "microchip,mcp2517fd"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&can_int>; ++ reg = <1>; ++ clocks = <&clk20m>; ++ spi-max-frequency = <10000000>; ++ interrupt-parent = <&gpio0>; ++ interrupts = <17 IRQ_TYPE_LEVEL_LOW>; ++ ++ };*/ ++ ++ ++}; ++ ++ + &i2c0 { + status = "okay"; + +@@ -507,7 +716,7 @@ + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; +- regulator-max-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>;/*old 3300000*/ + + regulator-name = "vccio_sd"; + regulator-state-mem { +@@ -520,7 +729,7 @@ + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; +- ++ regulator-always-on;/*add for test*/ + regulator-name = "vcc_sd"; + regulator-state-mem { + regulator-on-in-suspend; +@@ -530,6 +739,7 @@ + }; + + vcc2v8_dvp: LDO_REG7 { ++ regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; +@@ -542,6 +752,7 @@ + }; + + vcc1v8_dvp: LDO_REG8 { ++ regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; +@@ -554,6 +765,7 @@ + }; + + vdd1v5_dvp: LDO_REG9 { ++ regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; +@@ -588,7 +800,7 @@ + regulator-name = "vcc5v0_host"; + }; + }; +- ++#if 0 + rk809_codec: codec { + #sound-dai-cells = <0>; + compatible = "rockchip,rk809-codec", "rockchip,rk817-codec"; +@@ -600,14 +812,70 @@ + spk-volume = <3>; + status = "okay"; + }; ++ ++#endif + }; ++ ++#if 0 ++ tlv320_codec: codec@18 { ++ #sound-dai-cells = <0>; ++ compatible = "ti,tlv320aic3x"; ++ reg = <0x18>; ++ clocks = <&cru SCLK_I2S2_OUT>; ++ clock-names = "mclk"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s2_2ch_mclk>; ++ ai31xx-micbias-vg=<2>; ++ gpio-reset=<&gpio3 23 GPIO_ACTIVE_LOW>; ++ /*clock-frequency = <12000000>;*/ ++ AVDD-supply = <&sound_3v3>; ++ IOVDD-supply = <&sound_1v8>; ++ DRVDD-supply = <&sound_3v3>; ++ DVDD-supply = <&sound_1v8>; ++ status = "okay"; ++ }; ++#endif ++ /*sgtl5000_codec: codec@0a { ++ compatible = "fsl,sgtl5000"; ++ //#sound-dai-cells = <0>; ++ reg = <0x0a>; ++ clocks = <&cru SCLK_I2S2_OUT>; ++ clock-names = "mclk"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s2_2ch_mclk>; ++ VDDA-supply = <&sound_3v3>; ++ VDDIO-supply = <&sound_1v8>; ++ VDDD-supply = <&sound_1v8>; ++ };*/ ++ ++ ++ /*atecc608a@01 { ++ status = "okay"; ++ compatible = "atmel,atecc508a"; ++ reg = <1>; ++ clock-frequency = <1000000>; ++ };*/ ++ ++ ++ + }; + + &i2c1 { + status = "okay"; ++#if 0 ++ gslx680@40 { ++ status = "disabled"; ++ compatible = "9tripod,gslx680"; ++ reg = <0x40>; ++ power-supply = <&vcc3v3_lcd>; ++ touch-gpio = <&gpio0 5 IRQ_TYPE_EDGE_RISING>; ++ reset-gpio = <&gpio0 12 GPIO_ACTIVE_LOW>; ++ max-x = <1024>; ++ max-y = <600>; ++ }; + + sensor@f { +- status = "okay"; ++ status = "disabled"; + compatible = "ak8963"; + reg = <0x0f>; + type = <SENSOR_TYPE_COMPASS>; +@@ -618,6 +886,7 @@ + }; + + gt1x: gt1x@14 { ++ status = "disabled"; + compatible = "goodix,gt1x"; + reg = <0x14>; + power-supply = <&vcc3v3_lcd>; +@@ -626,7 +895,7 @@ + }; + + sensor@4c { +- status = "okay"; ++ status = "disabled"; + compatible = "gs_mma7660"; + reg = <0x4c>; + type = <SENSOR_TYPE_ACCEL>; +@@ -636,35 +905,220 @@ + layout = <2>; + reprobe_en = <1>; + }; ++#endif ++ ++ /*rtc pcf8563 i2c0-->i2c1*/ ++ rtc@51 { ++ compatible = "nxp,pcf8563"; ++ reg = <0x51>; ++ }; ++ ++ /*atecc608a i2c0->i2c1*/ ++ ++ /*i2c1->stm32 BMC: PB7,PB8*/ ++ ++ i2c_gpio_expander@3e{ ++ #gpio-cells = <2>; ++ #interrupt-cells = <2>; ++ compatible = "semtech,sx1509q"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sx1509_int>; ++ reg = <0x3e>; ++ interrupt-parent = <&gpio3>;/*gpio3_c2*/ ++ interrupts = <23 0>; ++ gpio-controller; ++ interrupt-controller; ++ /*oscio_is_gpo; ++ reset_during_probe;*/ ++ pullup_ena = <0xffff>; ++ pulldn_ena = <0x0>; ++ open_drain_ena = <0x0>; ++ polarity = <0x0>; ++ }; ++ ++ ads1115@48{ ++ compatible = "ti,ads1115"; ++ reg = <0x48>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ channel@0 { ++ reg = <0>; ++ ti,gain = <0>; ++ ti,datarate = <6>; ++ }; ++ ++ channel@1 { ++ reg = <1>; ++ ti,gain = <0>; ++ ti,datarate = <6>; ++ }; ++ channel@2 { ++ reg = <2>; ++ ti,gain = <0>; ++ ti,datarate = <6>; ++ }; ++ channel@3 { ++ reg = <3>; ++ ti,gain = <0>; ++ ti,datarate = <6>; ++ }; ++ channel@4 { ++ reg = <4>; ++ ti,gain = <0>; ++ ti,datarate = <6>; ++ }; ++ channel@5 { ++ reg = <5>; ++ ti,gain = <0>; ++ ti,datarate = <6>; ++ }; ++ channel@6 { ++ reg = <6>; ++ ti,gain = <0>; ++ ti,datarate = <6>; ++ }; ++ channel@7 { ++ reg = <7>; ++ ti,gain = <0>; ++ ti,datarate = <6>; ++ }; ++ }; ++ ++ ++/* tlv320_codec: codec@18 { ++ #sound-dai-cells = <0>; ++ compatible = "ti,tlv320aic3x"; ++ reg = <0x18>; ++ clocks = <&cru SCLK_I2S2_OUT>; ++ clock-names = "mclk"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s2_2ch_mclk>; ++ ai31xx-micbias-vg=<2>; ++ gpio-reset=<&gpio3 23 GPIO_ACTIVE_LOW>; ++ AVDD-supply = <&sound_3v3>; ++ IOVDD-supply = <&sound_1v8>; ++ DRVDD-supply = <&sound_3v3>; ++ DVDD-supply = <&sound_1v8>; ++ status = "okay"; ++ }; ++ ++*/ ++ rt5640: rt5640@1c { ++ #sound-dai-cells = <0>; ++ compatible = "realtek,rt5640"; ++ reg = <0x1c>; ++ clocks = <&cru SCLK_I2S1_OUT>; ++ clock-names = "mclk"; ++ //realtek,in1-differential; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s1_2ch_mclk>; ++ //hp-con-gpio = <&gpio4 21 GPIO_ACTIVE_HIGH>; ++ //hp-det-gpio = <&gpio4 28 GPIO_ACTIVE_LOW>; ++ //io-channels = <&saradc 4>; ++ //hp-det-adc-value = <500>; ++ ++ }; ++ ++ //ads1115 ++/* ++-channel: ++ 0: Voltage over AIN0 and AIN1. ++ 1: Voltage over AIN0 and AIN3. ++ 2: Voltage over AIN1 and AIN3. ++ 3: Voltage over AIN2 and AIN3. ++ 4: Voltage over AIN0 and GND. ++ 5: Voltage over AIN1 and GND. ++ 6: Voltage over AIN2 and GND. ++ 7: Voltage over AIN3 and GND. ++-gain: ++ 0: +/- 6.144 V ++ 1: +/- 4.096 V ++ 2: +/- 2.048 V (default) ++ 3: +/- 1.024 V ++ 4: +/- 0.512 V ++ 5: +/- 0.256 V ++ - data_rate in samples per second ++ 0: 128 ++ 1: 250 ++ 2: 490 ++ 3: 920 ++ 4: 1600 (default) ++ 5: 2400 ++ 6: 3300 ++*/ ++ /*/sys/devices/platform/ff190000.i2c/i2c-1/1-0048/in0_input*/ ++/* ++ ads1115@48 { ++ compatible = "ti,ads1115"; ++ reg = <0x48>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ channel@0 { ++ reg = <0>; ++ ti,gain = <3>; ++ ti,datarate = <5>; ++ }; ++ channel@1 { ++ reg = <1>; ++ ti,gain = <3>; ++ ti,datarate = <5>; ++ }; ++ channel@2 { ++ reg = <2>; ++ ti,gain = <3>; ++ ti,datarate = <5>; ++ }; ++ channel@3 { ++ reg = <3>; ++ ti,gain = <3>; ++ ti,datarate = <5>; ++ }; ++ channel@4 { ++ reg = <4>; ++ ti,gain = <3>; ++ ti,datarate = <5>; ++ }; ++ channel@5 { ++ reg = <5>; ++ ti,gain = <3>; ++ ti,datarate = <5>; ++ }; ++ channel@6 { ++ reg = <6>; ++ ti,gain = <3>; ++ ti,datarate = <5>; ++ }; ++ ++ channel@7 { ++ reg = <7>; ++ ti,gain = <3>; ++ ti,datarate = <5>; ++ }; ++ ++ }; ++*/ ++ + }; + + &i2c2 { + status = "okay"; + +- clock-frequency = <100000>; ++ /*clock-frequency = <100000>;*/ + + /* These are relatively safe rise/fall times; TODO: measure */ +- i2c-scl-falling-time-ns = <50>; +- i2c-scl-rising-time-ns = <300>; ++ /*i2c-scl-falling-time-ns = <50>; ++ i2c-scl-rising-time-ns = <300>;*/ + +- ov5695: ov5695@36 { ++/* ov5695: ov5695@36 { + compatible = "ovti,ov5695"; + reg = <0x36>; + clocks = <&cru SCLK_CIF_OUT>; + clock-names = "xvclk"; +- +- avdd-supply = <&vcc2v8_dvp>; +- dovdd-supply = <&vcc1v8_dvp>; +- dvdd-supply = <&vdd1v5_dvp>; +- +- /*reset-gpios = <&gpio2 14 GPIO_ACTIVE_HIGH>;*/ ++ //reset-gpios = <&gpio2 14 GPIO_ACTIVE_HIGH>; + pwdn-gpios = <&gpio2 14 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&cif_clkout_m0>; +- rockchip,camera-module-index = <0>; +- rockchip,camera-module-facing = "back"; +- rockchip,camera-module-name = "TongJu"; +- rockchip,camera-module-lens-name = "CHT842-MD"; + port { + ucam_out: endpoint { + remote-endpoint = <&mipi_in_ucam>; +@@ -672,6 +1126,127 @@ + }; + }; + }; ++*/ ++ ++ /*vm149c: vm149c@0c { ++ compatible = "silicon touch,vm149c"; ++ status = "okay"; ++ reg = <0x0c>; ++ rockchip,camera-module-index = <0>; ++ rockchip,camera-module-facing = "back"; ++ };*/ ++#if 0 ++ gt1x: gt1x@5d { ++ status = "okay"; ++ compatible = "goodix,gt1x"; ++ reg = <0x5d>; ++ power-supply = <&vcc3v3_lcd>; ++ //goodix,rst-gpio = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>; ++ //goodix,irq-gpio = <&gpio0 RK_PA5 IRQ_TYPE_LEVEL_LOW>; ++ }; ++#endif ++ ++#if 0 ++ ov13850: ov13850@10 { ++ compatible = "ovti,ov13850"; ++ status = "okay"; ++ reg = <0x10>; ++ clocks = <&cru SCLK_CIF_OUT>; ++ clock-names = "xvclk"; ++ /* avdd-supply = <>; */ ++ /* dvdd-supply = <>; */ ++ /* dovdd-supply = <>; */ ++ /* reset-gpios = <>; */ ++ reset-gpios = <&gpio3 RK_PC3 GPIO_ACTIVE_HIGH>; ++ pwdn-gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cif_clkout_m0 &cam_rst &cam_pwr>; ++ rockchip,camera-module-index = <0>; ++ rockchip,camera-module-facing = "back"; ++ rockchip,camera-module-name = "TongJu"; ++ rockchip,camera-module-lens-name = "CHT842-MD"; ++ /*lens-focus = <&vm149c>;*/ ++ port { ++ ucam_out: endpoint { ++ remote-endpoint = <&mipi_in_ucam>; ++ data-lanes = <1 2>; ++ }; ++ }; ++ }; ++#endif ++ imx219: imx219@10 { ++ compatible = "sony,imx219"; ++ reg = <0x10>; ++ clocks = <&cru SCLK_CIF_OUT>; ++ clock-names = "xvclk"; ++ /*avdd-supply = <&vcc2v8_dvp>; ++ dovdd-supply = <&vdd1v5_dvp>; ++ dvdd-supply = <&vcc1v8_dvp>;*/ ++ reset-gpios = <&gpio3 RK_PC3 GPIO_ACTIVE_HIGH>; ++ pwdn-gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cif_clkout_m0 &cam_rst &cam_pwr>; ++ rockchip,camera-module-index = <0>; ++ rockchip,camera-module-facing = "back"; ++ rockchip,camera-module-name = "TongJu"; ++ rockchip,camera-module-lens-name = "CHT842-MD"; ++ port { ++ ucam_out: endpoint { ++ remote-endpoint = <&mipi_in_ucam>; ++ data-lanes = <1 2>; ++ }; ++ }; ++ }; ++ ++#if DSI2HDMI_BRIDGE == 2 ++ lt9611@3b { ++ compatible = "firefly,lt9611"; ++ reg = <0x3b>; ++ reset-gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_LOW>; ++ irq-gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_LOW>; ++ }; ++#endif ++#if DSI2HDMI_BRIDGE == 1 ++ adv7535: adv7535@39 { ++ compatible = "lanxus_i2c_adv7535"; ++ reg = <0x39>; ++ }; ++#endif ++ ++#if DSI2HDMI_BRIDGE == 1 ++ adv_bridge: adv7535@3d { ++ compatible = "adi,adv7533"; ++ // ok, marked by johnson to test ++ //reg = <0x39>; ++ //adi,addr-cec = <0x3c>; ++ // end of marked ++ ++ reg = <0x39>; ++ ++ adi,addr-cec = <0x3c>; ++ adi,dsi-channel = <1>; ++ adi,dsi-lanes = <4>; ++ pinctrl-0 = <&pinctrl_7535>; ++ interrupt-parent = <&gpio3>; ++ interrupts = <16 IRQ_TYPE_LEVEL_LOW>; ++ ++ status = "okay"; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg=<0>; ++ ++ adv7535_bridge_out: endpoint { ++ remote-endpoint = <&adv7535_panel_in>; ++ }; ++ }; ++ }; ++ }; ++#endif ++ + }; + + &i2s1_2ch { +@@ -679,20 +1254,30 @@ + #sound-dai-cells = <0>; + }; + ++#if 0 ++&i2s2_2ch { ++ status = "okay"; ++// rockchip,bclk-fs = <64>; ++ #sound-dai-cells = <0>; ++}; ++#endif ++ + &io_domains { + status = "okay"; + +- vccio1-supply = <&vcc_3v0>; ++ vccio1-supply = <&vcc1v8_soc>; + vccio2-supply = <&vccio_sd>; + vccio3-supply = <&vcc_3v0>; +- vccio4-supply = <&vcc3v0_pmu>; +- vccio5-supply = <&vcc_3v0>; ++ vccio4-supply = <&vcc1v8_dvp>; /*<&vcc3v0_pmu>;*/ ++ vccio5-supply = <&vcc1v8_soc>; /*vcc_3v0*/ ++ + }; + + &isp_mmu { + status = "okay"; + }; + ++ + &mipi_dphy_rx0 { + status = "okay"; + +@@ -733,13 +1318,14 @@ + status = "okay"; + + pmuio1-supply = <&vcc3v0_pmu>; +- pmuio2-supply = <&vcc3v0_pmu>; ++ pmuio2-supply = <&vcc1v8_soc>; /* <&vcc3v0_pmu>;*/ + }; + + &pwm1 { + status = "okay"; + }; + ++ + &rk_rga { + status = "okay"; + }; +@@ -769,6 +1355,8 @@ + }; + + &sdmmc { ++/* clock-frequency = <37500000>; ++ max-frequency = <37500000>;*/ + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; +@@ -781,35 +1369,61 @@ + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <&vccio_sd>; +- vmmc-supply = <&vcc_sd>; ++ vmmc-supply = <&vcc_sd_pwr>; + status = "okay"; + }; + ++&emmc { ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ mmc-hs200-1_8v; ++ supports-emmc; ++ disable-wp; ++ non-removable; ++ num-slots = <1>; ++ status = "okay"; ++}; ++ ++ + &sdio { +- bus-width = <4>; ++/* bus-width = <4>; + cap-sd-highspeed; + supports-sdio; + ignore-pm-notify; + keep-power-in-suspend; + non-removable; + mmc-pwrseq = <&sdio_pwrseq>; +- sd-uhs-sdr104; +- status = "okay"; ++ sd-uhs-sdr104;*/ ++ status = "disabled"; + }; + + &tsadc { +- pinctrl-names = "gpio", "otpout"; ++ pinctrl-names = "init", "default"; + pinctrl-0 = <&tsadc_otp_gpio>; + pinctrl-1 = <&tsadc_otp_out>; + status = "okay"; + }; + ++/*change to uart0 debug*/ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_xfer /*&uart0_cts &uart0_rts*/>; ++ status = "okay"; ++}; ++ + &uart1 { + pinctrl-names = "default"; +- pinctrl-0 = <&uart1_xfer &uart1_cts>; ++ pinctrl-0 = <&uart1_xfer /*&uart1_cts &uart1_rts*/>; + status = "okay"; + }; + ++/*uart2 debug change to uart2m1*/ ++&uart2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2m1_xfer>; ++ status = "disabled"; ++}; ++ + &u2phy { + status = "okay"; + +@@ -855,11 +1469,11 @@ + }; + + &pinctrl { +- headphone { ++ /*headphone { + hp_det: hp-det { + rockchip,pins = <2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_down>; + }; +- }; ++ };*/ + + pmic { + pmic_int: pmic_int { +@@ -883,11 +1497,76 @@ + }; + }; + +- sdio-pwrseq { ++ can { ++ can_int: can_int { ++ rockchip,pins = ++ <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ }; ++ eth_phy { ++ eth_phy_pwr: eth_phy_pwr { ++ rockchip,pins = ++ <2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ }; ++ ++ sdmmc_pwr { ++ sdmmc_pwr: sdmmc_pwr { ++ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_output_high>; ++ }; ++ }; ++ ++ ov13850 { ++ ++ cam_rst: cam_rst { ++ rockchip,pins = ++ <3 RK_PC3 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ cam_pwr: cam_pwr { ++ rockchip,pins = ++ <3 RK_PC1 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ ++ ++ }; ++ ++ i2c_gpio { ++ sx1509_int: sx1509_int{ ++ rockchip,pins = ++ <3 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ lcd_vdd_gpio { ++ lcd_vdd_gpio_en: lcd_vdd_gpio_en { ++ rockchip,pins = ++ <3 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ ++ px30_lanxus_gpioset{ ++ lanxus_gpioset: lanxus-gpioset { ++ rockchip,pins = <3 RK_PA6 RK_FUNC_GPIO &pcfg_output_high>; ++ }; ++ }; ++ ++ ++ adv7535-int { ++ pinctrl_7535: pinctrl-7535 { ++ rockchip,pins = <3 RK_PC0 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ ++ /*sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; +- }; ++ };*/ + }; + + /* DON'T PUT ANYTHING BELOW HERE. PUT IT ABOVE PINCTRL */ +diff --git a/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10.dtsi b/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10.dtsi +index f1ff3ff..55444b8 100644 +--- a/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10.dtsi ++++ b/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10.dtsi +@@ -576,13 +576,13 @@ + }; + }; + +- vcc5v0_host: SWITCH_REG2 { ++ vcc5v0_host: SWITCH_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vcc5v0_host"; + }; + +- vcc3v3_lcd: SWITCH_REG1 { ++ vcc3v3_lcd: SWITCH_REG2 { + regulator-boot-on; + regulator-name = "vcc3v3_lcd"; + }; +diff --git a/arch/arm64/boot/dts/rockchip/rk3326-linux.dtsi b/arch/arm64/boot/dts/rockchip/rk3326-linux.dtsi +index 3672ce7..9fbb720 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3326-linux.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3326-linux.dtsi +@@ -44,7 +44,9 @@ + compatible = "rockchip,linux", "rockchip,rk3326"; + + chosen { +- bootargs = "earlycon=uart8250,mmio32,0xff160000 swiotlb=1 console=ttyFIQ0 rw root=PARTUUID=614e0000-0000 rootwait"; ++ //bootargs = "earlycon=uart8250,mmio32,0xff160000 swiotlb=1 console=ttyFIQ0 rw root=PARTUUID=614e0000-0000 rootwait"; ++ bootargs = "earlycon=uart8250,mmio32,0xff160000 swiotlb=1 console=ttyFIQ0 rw root=/dev/mmcblk1p4 rootwait"; ++ /* bootargs = "console=tty1 rw root=PARTUUID=614e0000-0000 rootwait";*/ + }; + + fiq-debugger { +@@ -53,10 +55,10 @@ + rockchip,wake-irq = <0>; + /* If enable uart uses irq instead of fiq */ + rockchip,irq-mode-enable = <0>; +- rockchip,baudrate = <1500000>; /* Only 115200 and 1500000 */ ++ rockchip,baudrate = <115200>; /* Only 115200 and 1500000 */ + interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; +- pinctrl-0 = <&uart2m0_xfer>; ++ pinctrl-0 = <&uart2m1_xfer>;/*change to uart2m1*/ + status = "okay"; + }; + +diff --git a/arch/arm64/configs/adlink-px30_config b/arch/arm64/configs/adlink-px30_config +new file mode 100644 +index 0000000..091482f +--- /dev/null ++++ b/arch/arm64/configs/adlink-px30_config +@@ -0,0 +1,4410 @@ ++# ++# Automatically generated file; DO NOT EDIT. ++# Linux/arm64 4.4.185 Kernel Configuration ++# ++CONFIG_ARM64=y ++CONFIG_64BIT=y ++CONFIG_ARCH_PHYS_ADDR_T_64BIT=y ++CONFIG_MMU=y ++CONFIG_ARCH_MMAP_RND_BITS_MIN=18 ++CONFIG_ARCH_MMAP_RND_BITS_MAX=24 ++CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 ++CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 ++CONFIG_ARM64_PAGE_SHIFT=12 ++CONFIG_ARM64_CONT_SHIFT=4 ++CONFIG_NO_IOPORT_MAP=y ++CONFIG_STACKTRACE_SUPPORT=y ++CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 ++CONFIG_LOCKDEP_SUPPORT=y ++CONFIG_TRACE_IRQFLAGS_SUPPORT=y ++CONFIG_RWSEM_XCHGADD_ALGORITHM=y ++CONFIG_GENERIC_BUG=y ++CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y ++CONFIG_GENERIC_HWEIGHT=y ++CONFIG_GENERIC_CSUM=y ++CONFIG_GENERIC_CALIBRATE_DELAY=y ++CONFIG_ZONE_DMA=y ++CONFIG_HAVE_GENERIC_RCU_GUP=y ++CONFIG_ARCH_DMA_ADDR_T_64BIT=y ++CONFIG_NEED_DMA_MAP_STATE=y ++CONFIG_NEED_SG_DMA_LENGTH=y ++CONFIG_SMP=y ++CONFIG_SWIOTLB=y ++CONFIG_IOMMU_HELPER=y ++CONFIG_KERNEL_MODE_NEON=y ++CONFIG_FIX_EARLYCON_MEM=y ++CONFIG_PGTABLE_LEVELS=3 ++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" ++CONFIG_IRQ_WORK=y ++CONFIG_BUILDTIME_EXTABLE_SORT=y ++CONFIG_THREAD_INFO_IN_TASK=y ++ ++# ++# General setup ++# ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++CONFIG_CROSS_COMPILE="" ++# CONFIG_COMPILE_TEST is not set ++CONFIG_LOCALVERSION="-rockchip-standard" ++CONFIG_LOCALVERSION_AUTO=y ++CONFIG_DEFAULT_HOSTNAME="localhost" ++CONFIG_SWAP=y ++CONFIG_SYSVIPC=y ++CONFIG_SYSVIPC_SYSCTL=y ++# CONFIG_POSIX_MQUEUE is not set ++CONFIG_CROSS_MEMORY_ATTACH=y ++CONFIG_FHANDLE=y ++CONFIG_USELIB=y ++# CONFIG_AUDIT is not set ++CONFIG_HAVE_ARCH_AUDITSYSCALL=y ++ ++# ++# IRQ subsystem ++# ++CONFIG_GENERIC_IRQ_PROBE=y ++CONFIG_GENERIC_IRQ_SHOW=y ++CONFIG_GENERIC_IRQ_SHOW_LEVEL=y ++CONFIG_GENERIC_IRQ_MIGRATION=y ++CONFIG_HARDIRQS_SW_RESEND=y ++CONFIG_GENERIC_IRQ_CHIP=y ++CONFIG_IRQ_DOMAIN=y ++CONFIG_IRQ_DOMAIN_HIERARCHY=y ++CONFIG_HANDLE_DOMAIN_IRQ=y ++# CONFIG_IRQ_DOMAIN_DEBUG is not set ++CONFIG_IRQ_FORCED_THREADING=y ++CONFIG_SPARSE_IRQ=y ++CONFIG_GENERIC_TIME_VSYSCALL=y ++CONFIG_GENERIC_CLOCKEVENTS=y ++CONFIG_ARCH_HAS_TICK_BROADCAST=y ++CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y ++ ++# ++# Timers subsystem ++# ++CONFIG_TICK_ONESHOT=y ++CONFIG_NO_HZ_COMMON=y ++# CONFIG_HZ_PERIODIC is not set ++CONFIG_NO_HZ_IDLE=y ++# CONFIG_NO_HZ_FULL is not set ++CONFIG_NO_HZ=y ++CONFIG_HIGH_RES_TIMERS=y ++ ++# ++# CPU/Task time and stats accounting ++# ++CONFIG_TICK_CPU_ACCOUNTING=y ++# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set ++# CONFIG_IRQ_TIME_ACCOUNTING is not set ++# CONFIG_SCHED_WALT is not set ++# CONFIG_BSD_PROCESS_ACCT is not set ++# CONFIG_TASKSTATS is not set ++ ++# ++# RCU Subsystem ++# ++CONFIG_TREE_RCU=y ++# CONFIG_RCU_EXPERT is not set ++CONFIG_SRCU=y ++# CONFIG_TASKS_RCU is not set ++CONFIG_RCU_STALL_COMMON=y ++# CONFIG_TREE_RCU_TRACE is not set ++# CONFIG_RCU_EXPEDITE_BOOT is not set ++# CONFIG_BUILD_BIN2C is not set ++# CONFIG_IKCONFIG is not set ++CONFIG_LOG_BUF_SHIFT=18 ++CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 ++CONFIG_GENERIC_SCHED_CLOCK=y ++CONFIG_CGROUPS=y ++# CONFIG_CGROUP_DEBUG is not set ++CONFIG_CGROUP_FREEZER=y ++# CONFIG_CGROUP_PIDS is not set ++CONFIG_CGROUP_DEVICE=y ++CONFIG_CPUSETS=y ++CONFIG_PROC_PID_CPUSET=y ++CONFIG_CGROUP_CPUACCT=y ++# CONFIG_MEMCG is not set ++# CONFIG_CGROUP_PERF is not set ++CONFIG_CGROUP_SCHED=y ++CONFIG_FAIR_GROUP_SCHED=y ++CONFIG_CFS_BANDWIDTH=y ++# CONFIG_RT_GROUP_SCHED is not set ++# CONFIG_BLK_CGROUP is not set ++# CONFIG_CHECKPOINT_RESTORE is not set ++CONFIG_NAMESPACES=y ++CONFIG_UTS_NS=y ++CONFIG_IPC_NS=y ++CONFIG_USER_NS=y ++CONFIG_PID_NS=y ++CONFIG_NET_NS=y ++# CONFIG_SCHED_AUTOGROUP is not set ++# CONFIG_SCHED_TUNE is not set ++CONFIG_DEFAULT_USE_ENERGY_AWARE=y ++# CONFIG_SYSFS_DEPRECATED is not set ++CONFIG_RELAY=y ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_INITRAMFS_SOURCE="" ++CONFIG_RD_GZIP=y ++CONFIG_RD_BZIP2=y ++CONFIG_RD_LZMA=y ++CONFIG_RD_XZ=y ++CONFIG_RD_LZO=y ++CONFIG_RD_LZ4=y ++# CONFIG_INITRD_ASYNC is not set ++# CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE is not set ++CONFIG_CC_OPTIMIZE_FOR_SIZE=y ++CONFIG_SYSCTL=y ++CONFIG_ANON_INODES=y ++CONFIG_HAVE_UID16=y ++CONFIG_SYSCTL_EXCEPTION_TRACE=y ++CONFIG_BPF=y ++CONFIG_EXPERT=y ++CONFIG_UID16=y ++CONFIG_MULTIUSER=y ++# CONFIG_SGETMASK_SYSCALL is not set ++CONFIG_SYSFS_SYSCALL=y ++# CONFIG_SYSCTL_SYSCALL is not set ++CONFIG_KALLSYMS=y ++# CONFIG_KALLSYMS_ALL is not set ++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_BPF_SYSCALL is not set ++CONFIG_SHMEM=y ++CONFIG_AIO=y ++CONFIG_ADVISE_SYSCALLS=y ++# CONFIG_USERFAULTFD is not set ++CONFIG_MEMBARRIER=y ++CONFIG_EMBEDDED=y ++CONFIG_HAVE_PERF_EVENTS=y ++CONFIG_PERF_USE_VMALLOC=y ++ ++# ++# Kernel Performance Events And Counters ++# ++CONFIG_PERF_EVENTS=y ++# CONFIG_DEBUG_PERF_USE_VMALLOC is not set ++CONFIG_VM_EVENT_COUNTERS=y ++CONFIG_SLUB_DEBUG=y ++# CONFIG_COMPAT_BRK is not set ++# CONFIG_SLAB is not set ++CONFIG_SLUB=y ++# CONFIG_SLOB is not set ++CONFIG_SLUB_CPU_PARTIAL=y ++# CONFIG_SYSTEM_DATA_VERIFICATION is not set ++CONFIG_PROFILING=y ++CONFIG_TRACEPOINTS=y ++# CONFIG_KPROBES is not set ++# CONFIG_JUMP_LABEL is not set ++# CONFIG_UPROBES is not set ++# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set ++CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y ++CONFIG_HAVE_KPROBES=y ++CONFIG_HAVE_KRETPROBES=y ++CONFIG_HAVE_ARCH_TRACEHOOK=y ++CONFIG_HAVE_DMA_ATTRS=y ++CONFIG_HAVE_DMA_CONTIGUOUS=y ++CONFIG_GENERIC_SMP_IDLE_THREAD=y ++CONFIG_GENERIC_IDLE_POLL_SETUP=y ++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y ++CONFIG_HAVE_CLK=y ++CONFIG_HAVE_DMA_API_DEBUG=y ++CONFIG_HAVE_HW_BREAKPOINT=y ++CONFIG_HAVE_PERF_REGS=y ++CONFIG_HAVE_PERF_USER_STACK_DUMP=y ++CONFIG_HAVE_ARCH_JUMP_LABEL=y ++CONFIG_HAVE_RCU_TABLE_FREE=y ++CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y ++CONFIG_HAVE_CMPXCHG_LOCAL=y ++CONFIG_HAVE_CMPXCHG_DOUBLE=y ++CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y ++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y ++CONFIG_SECCOMP_FILTER=y ++CONFIG_HAVE_CC_STACKPROTECTOR=y ++# CONFIG_CC_STACKPROTECTOR is not set ++CONFIG_CC_STACKPROTECTOR_NONE=y ++# CONFIG_CC_STACKPROTECTOR_REGULAR is not set ++# CONFIG_CC_STACKPROTECTOR_STRONG is not set ++CONFIG_HAVE_CONTEXT_TRACKING=y ++CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y ++CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y ++CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y ++CONFIG_HAVE_ARCH_HUGE_VMAP=y ++CONFIG_MODULES_USE_ELF_RELA=y ++CONFIG_ARCH_HAS_ELF_RANDOMIZE=y ++CONFIG_HAVE_ARCH_MMAP_RND_BITS=y ++CONFIG_ARCH_MMAP_RND_BITS=18 ++CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS=y ++CONFIG_ARCH_MMAP_RND_COMPAT_BITS=11 ++CONFIG_CLONE_BACKWARDS=y ++CONFIG_OLD_SIGSUSPEND3=y ++CONFIG_COMPAT_OLD_SIGACTION=y ++ ++# ++# GCOV-based kernel profiling ++# ++# CONFIG_GCOV_KERNEL is not set ++CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y ++CONFIG_HAVE_GENERIC_DMA_COHERENT=y ++CONFIG_SLABINFO=y ++CONFIG_RT_MUTEXES=y ++CONFIG_BASE_SMALL=0 ++CONFIG_MODULES=y ++CONFIG_MODULE_FORCE_LOAD=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODULE_FORCE_UNLOAD=y ++# CONFIG_MODVERSIONS is not set ++# CONFIG_MODULE_SRCVERSION_ALL is not set ++# CONFIG_MODULE_SIG is not set ++# CONFIG_MODULE_COMPRESS is not set ++CONFIG_MODULES_TREE_LOOKUP=y ++CONFIG_BLOCK=y ++CONFIG_BLK_DEV_BSG=y ++# CONFIG_BLK_DEV_BSGLIB is not set ++# CONFIG_BLK_DEV_INTEGRITY is not set ++# CONFIG_BLK_CMDLINE_PARSER is not set ++ ++# ++# Partition Types ++# ++CONFIG_PARTITION_ADVANCED=y ++# CONFIG_ACORN_PARTITION is not set ++# CONFIG_AIX_PARTITION is not set ++# CONFIG_OSF_PARTITION is not set ++# CONFIG_AMIGA_PARTITION is not set ++# CONFIG_ATARI_PARTITION is not set ++# CONFIG_MAC_PARTITION is not set ++CONFIG_MSDOS_PARTITION=y ++# CONFIG_BSD_DISKLABEL is not set ++# CONFIG_MINIX_SUBPARTITION is not set ++# CONFIG_SOLARIS_X86_PARTITION is not set ++# CONFIG_UNIXWARE_DISKLABEL is not set ++# CONFIG_LDM_PARTITION is not set ++# CONFIG_SGI_PARTITION is not set ++# CONFIG_ULTRIX_PARTITION is not set ++# CONFIG_SUN_PARTITION is not set ++# CONFIG_KARMA_PARTITION is not set ++CONFIG_EFI_PARTITION=y ++# CONFIG_SYSV68_PARTITION is not set ++CONFIG_RK_PARTITION=y ++# CONFIG_CMDLINE_PARTITION is not set ++CONFIG_BLOCK_COMPAT=y ++ ++# ++# IO Schedulers ++# ++CONFIG_IOSCHED_NOOP=y ++CONFIG_IOSCHED_DEADLINE=y ++CONFIG_IOSCHED_CFQ=y ++# CONFIG_DEFAULT_DEADLINE is not set ++CONFIG_DEFAULT_CFQ=y ++# CONFIG_DEFAULT_NOOP is not set ++CONFIG_DEFAULT_IOSCHED="cfq" ++CONFIG_ASN1=y ++CONFIG_UNINLINE_SPIN_UNLOCK=y ++CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y ++CONFIG_MUTEX_SPIN_ON_OWNER=y ++CONFIG_RWSEM_SPIN_ON_OWNER=y ++CONFIG_LOCK_SPIN_ON_OWNER=y ++CONFIG_FREEZER=y ++ ++# ++# Platform selection ++# ++# CONFIG_ARCH_BCM_IPROC is not set ++# CONFIG_ARCH_BERLIN is not set ++# CONFIG_ARCH_EXYNOS7 is not set ++# CONFIG_ARCH_LAYERSCAPE is not set ++# CONFIG_ARCH_HISI is not set ++# CONFIG_ARCH_MEDIATEK is not set ++# CONFIG_ARCH_QCOM is not set ++CONFIG_ARCH_ROCKCHIP=y ++# CONFIG_ARCH_SEATTLE is not set ++# CONFIG_ARCH_STRATIX10 is not set ++# CONFIG_ARCH_TEGRA is not set ++# CONFIG_ARCH_SPRD is not set ++# CONFIG_ARCH_THUNDER is not set ++# CONFIG_ARCH_VEXPRESS is not set ++# CONFIG_ARCH_XGENE is not set ++# CONFIG_ARCH_ZYNQMP is not set ++ ++# ++# Bus support ++# ++# CONFIG_PCI is not set ++# CONFIG_PCI_DOMAINS is not set ++# CONFIG_PCI_DOMAINS_GENERIC is not set ++# CONFIG_PCI_SYSCALL is not set ++ ++# ++# Kernel Features ++# ++ ++# ++# ARM errata workarounds via the alternatives framework ++# ++# CONFIG_ARM64_ERRATUM_826319 is not set ++# CONFIG_ARM64_ERRATUM_827319 is not set ++# CONFIG_ARM64_ERRATUM_824069 is not set ++# CONFIG_ARM64_ERRATUM_819472 is not set ++# CONFIG_ARM64_ERRATUM_832075 is not set ++CONFIG_ARM64_ERRATUM_845719=y ++CONFIG_ARM64_ERRATUM_843419=y ++# CONFIG_ARM64_ERRATUM_1024718 is not set ++# CONFIG_CAVIUM_ERRATUM_22375 is not set ++# CONFIG_CAVIUM_ERRATUM_23154 is not set ++CONFIG_CAVIUM_ERRATUM_27456=y ++CONFIG_ARM64_4K_PAGES=y ++# CONFIG_ARM64_16K_PAGES is not set ++# CONFIG_ARM64_64K_PAGES is not set ++CONFIG_ARM64_VA_BITS_39=y ++# CONFIG_ARM64_VA_BITS_48 is not set ++CONFIG_ARM64_VA_BITS=39 ++# CONFIG_CPU_BIG_ENDIAN is not set ++CONFIG_SCHED_MC=y ++# CONFIG_SCHED_SMT is not set ++CONFIG_NR_CPUS=8 ++CONFIG_HOTPLUG_CPU=y ++# CONFIG_PREEMPT_NONE is not set ++CONFIG_PREEMPT_VOLUNTARY=y ++# CONFIG_PREEMPT is not set ++# CONFIG_HZ_100 is not set ++# CONFIG_HZ_250 is not set ++# CONFIG_HZ_300 is not set ++CONFIG_HZ_1000=y ++CONFIG_HZ=1000 ++CONFIG_SCHED_HRTICK=y ++CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y ++CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y ++CONFIG_ARCH_SPARSEMEM_ENABLE=y ++CONFIG_ARCH_SPARSEMEM_DEFAULT=y ++CONFIG_ARCH_SELECT_MEMORY_MODEL=y ++CONFIG_HAVE_ARCH_PFN_VALID=y ++CONFIG_HW_PERF_EVENTS=y ++CONFIG_SYS_SUPPORTS_HUGETLBFS=y ++CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y ++CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y ++CONFIG_SELECT_MEMORY_MODEL=y ++CONFIG_SPARSEMEM_MANUAL=y ++CONFIG_SPARSEMEM=y ++CONFIG_HAVE_MEMORY_PRESENT=y ++CONFIG_SPARSEMEM_EXTREME=y ++CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y ++CONFIG_SPARSEMEM_VMEMMAP=y ++CONFIG_HAVE_MEMBLOCK=y ++CONFIG_NO_BOOTMEM=y ++# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set ++CONFIG_SPLIT_PTLOCK_CPUS=4 ++# CONFIG_COMPACTION is not set ++CONFIG_PHYS_ADDR_T_64BIT=y ++CONFIG_ZONE_DMA_FLAG=1 ++CONFIG_BOUNCE=y ++# CONFIG_KSM is not set ++CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 ++# CONFIG_TRANSPARENT_HUGEPAGE is not set ++# CONFIG_CLEANCACHE is not set ++# CONFIG_FRONTSWAP is not set ++# CONFIG_CMA is not set ++# CONFIG_ZPOOL is not set ++# CONFIG_ZBUD is not set ++CONFIG_ZSMALLOC=y ++# CONFIG_PGTABLE_MAPPING is not set ++# CONFIG_ZSMALLOC_STAT is not set ++CONFIG_GENERIC_EARLY_IOREMAP=y ++# CONFIG_IDLE_PAGE_TRACKING is not set ++CONFIG_FRAME_VECTOR=y ++CONFIG_SECCOMP=y ++# CONFIG_KEXEC is not set ++# CONFIG_CRASH_DUMP is not set ++# CONFIG_XEN is not set ++CONFIG_FORCE_MAX_ZONEORDER=11 ++CONFIG_UNMAP_KERNEL_AT_EL0=y ++CONFIG_ARMV8_DEPRECATED=y ++CONFIG_SWP_EMULATION=y ++CONFIG_CP15_BARRIER_EMULATION=y ++CONFIG_SETEND_EMULATION=y ++# CONFIG_ARM64_SW_TTBR0_PAN is not set ++ ++# ++# ARMv8.1 architectural features ++# ++CONFIG_ARM64_HW_AFDBM=y ++CONFIG_ARM64_PAN=y ++# CONFIG_ARM64_LSE_ATOMICS is not set ++CONFIG_ARM64_UAO=y ++CONFIG_ARM64_MODULE_CMODEL_LARGE=y ++# CONFIG_RANDOMIZE_BASE is not set ++ ++# ++# Boot options ++# ++CONFIG_CMDLINE="" ++# CONFIG_EFI is not set ++# CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE is not set ++ ++# ++# Userspace binary formats ++# ++CONFIG_BINFMT_ELF=y ++CONFIG_COMPAT_BINFMT_ELF=y ++CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y ++CONFIG_BINFMT_SCRIPT=y ++# CONFIG_HAVE_AOUT is not set ++# CONFIG_BINFMT_MISC is not set ++CONFIG_COREDUMP=y ++CONFIG_COMPAT=y ++CONFIG_SYSVIPC_COMPAT=y ++CONFIG_KEYS_COMPAT=y ++ ++# ++# Power management options ++# ++CONFIG_SUSPEND=y ++CONFIG_SUSPEND_FREEZER=y ++# CONFIG_SUSPEND_SKIP_SYNC is not set ++CONFIG_HAS_WAKELOCK=y ++CONFIG_WAKELOCK=y ++# CONFIG_HIBERNATION is not set ++CONFIG_PM_SLEEP=y ++CONFIG_PM_SLEEP_SMP=y ++# CONFIG_PM_AUTOSLEEP is not set ++# CONFIG_PM_WAKELOCKS is not set ++CONFIG_PM=y ++CONFIG_PM_DEBUG=y ++CONFIG_PM_ADVANCED_DEBUG=y ++# CONFIG_PM_TEST_SUSPEND is not set ++CONFIG_PM_SLEEP_DEBUG=y ++CONFIG_PM_OPP=y ++CONFIG_PM_CLK=y ++CONFIG_PM_GENERIC_DOMAINS=y ++CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y ++CONFIG_PM_GENERIC_DOMAINS_SLEEP=y ++CONFIG_PM_GENERIC_DOMAINS_OF=y ++CONFIG_CPU_PM=y ++CONFIG_ARCH_HIBERNATION_POSSIBLE=y ++CONFIG_ARCH_SUSPEND_POSSIBLE=y ++ ++# ++# CPU Power Management ++# ++ ++# ++# CPU Idle ++# ++CONFIG_CPU_IDLE=y ++CONFIG_CPU_IDLE_GOV_LADDER=y ++CONFIG_CPU_IDLE_GOV_MENU=y ++CONFIG_DT_IDLE_STATES=y ++ ++# ++# ARM CPU Idle Drivers ++# ++CONFIG_ARM_CPUIDLE=y ++# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set ++ ++# ++# CPU Frequency scaling ++# ++CONFIG_CPU_FREQ=y ++CONFIG_CPU_FREQ_GOV_COMMON=y ++CONFIG_CPU_FREQ_STAT=y ++# CONFIG_CPU_FREQ_STAT_DETAILS is not set ++CONFIG_CPU_FREQ_TIMES=y ++# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set ++# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set ++# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set ++# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set ++# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set ++CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y ++# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set ++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y ++CONFIG_CPU_FREQ_GOV_POWERSAVE=y ++CONFIG_CPU_FREQ_GOV_USERSPACE=y ++CONFIG_CPU_FREQ_GOV_ONDEMAND=y ++CONFIG_CPU_FREQ_GOV_INTERACTIVE=y ++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y ++# CONFIG_CPU_FREQ_GOV_SCHEDUTIL is not set ++ ++# ++# CPU frequency scaling drivers ++# ++CONFIG_CPUFREQ_DT=y ++# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set ++# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set ++CONFIG_ARM_ROCKCHIP_CPUFREQ=y ++CONFIG_NET=y ++CONFIG_COMPAT_NETLINK_MESSAGES=y ++ ++# ++# Networking options ++# ++CONFIG_PACKET=y ++# CONFIG_PACKET_DIAG is not set ++CONFIG_UNIX=y ++# CONFIG_UNIX_DIAG is not set ++CONFIG_XFRM=y ++CONFIG_XFRM_ALGO=y ++CONFIG_XFRM_USER=y ++# CONFIG_XFRM_SUB_POLICY is not set ++# CONFIG_XFRM_MIGRATE is not set ++# CONFIG_XFRM_STATISTICS is not set ++CONFIG_NET_KEY=y ++# CONFIG_NET_KEY_MIGRATE is not set ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++# CONFIG_IP_FIB_TRIE_STATS is not set ++# CONFIG_IP_MULTIPLE_TABLES is not set ++# CONFIG_IP_ROUTE_MULTIPATH is not set ++# CONFIG_IP_ROUTE_VERBOSE is not set ++# CONFIG_IP_PNP is not set ++# CONFIG_NET_IPIP is not set ++# CONFIG_NET_IPGRE_DEMUX is not set ++# CONFIG_NET_IP_TUNNEL is not set ++CONFIG_IP_MROUTE=y ++# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set ++# CONFIG_IP_PIMSM_V1 is not set ++# CONFIG_IP_PIMSM_V2 is not set ++CONFIG_SYN_COOKIES=y ++# CONFIG_NET_UDP_TUNNEL is not set ++# CONFIG_NET_FOU 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 is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_LRO is not set ++# CONFIG_INET_DIAG is not set ++# 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=y ++# 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_IPV6_ILA is not set ++# CONFIG_INET6_XFRM_TUNNEL is not set ++# CONFIG_INET6_TUNNEL is not set ++# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET6_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET6_XFRM_MODE_BEET is not set ++# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set ++# CONFIG_IPV6_SIT is not set ++# CONFIG_IPV6_TUNNEL is not set ++# CONFIG_IPV6_GRE is not set ++# CONFIG_IPV6_MULTIPLE_TABLES is not set ++# CONFIG_IPV6_MROUTE is not set ++# CONFIG_ANDROID_PARANOID_NETWORK is not set ++# CONFIG_NETWORK_SECMARK is not set ++CONFIG_NET_PTP_CLASSIFY=y ++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set ++# CONFIG_NETFILTER is not set ++# CONFIG_IP_DCCP is not set ++# CONFIG_IP_SCTP is not set ++# CONFIG_RDS is not set ++# CONFIG_TIPC is not set ++# CONFIG_ATM is not set ++# CONFIG_L2TP is not set ++# CONFIG_BRIDGE is not set ++CONFIG_HAVE_NET_DSA=y ++# 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_PHONET is not set ++# CONFIG_6LOWPAN is not set ++# CONFIG_IEEE802154 is not set ++# CONFIG_NET_SCHED is not set ++# CONFIG_DCB is not set ++CONFIG_DNS_RESOLVER=y ++# CONFIG_BATMAN_ADV is not set ++# CONFIG_OPENVSWITCH is not set ++# CONFIG_VSOCKETS is not set ++# CONFIG_NETLINK_DIAG is not set ++# CONFIG_MPLS is not set ++# CONFIG_HSR is not set ++# CONFIG_NET_SWITCHDEV is not set ++# CONFIG_NET_L3_MASTER_DEV is not set ++CONFIG_RPS=y ++CONFIG_RFS_ACCEL=y ++CONFIG_XPS=y ++# CONFIG_CGROUP_NET_PRIO is not set ++# CONFIG_CGROUP_NET_CLASSID is not set ++CONFIG_NET_RX_BUSY_POLL=y ++CONFIG_BQL=y ++# CONFIG_BPF_JIT is not set ++CONFIG_NET_FLOW_LIMIT=y ++ ++# ++# Network testing ++# ++# CONFIG_NET_PKTGEN is not set ++# CONFIG_NET_DROP_MONITOR is not set ++# CONFIG_HAMRADIO is not set ++CONFIG_CAN=y ++CONFIG_CAN_RAW=y ++CONFIG_CAN_BCM=y ++CONFIG_CAN_GW=y ++ ++# ++# CAN Device Drivers ++# ++# CONFIG_CAN_VCAN is not set ++# CONFIG_CAN_SLCAN is not set ++CONFIG_CAN_DEV=y ++CONFIG_CAN_CALC_BITTIMING=y ++# CONFIG_CAN_LEDS is not set ++# CONFIG_CAN_GRCAN is not set ++# CONFIG_CAN_XILINXCAN is not set ++# CONFIG_CAN_SJA1000 is not set ++# CONFIG_CAN_C_CAN is not set ++# CONFIG_CAN_M_CAN is not set ++# CONFIG_CAN_CC770 is not set ++ ++# ++# CAN SPI interfaces ++# ++# CONFIG_CAN_MCP251X is not set ++CONFIG_CAN_MCP25XXFD=m ++ ++# ++# CAN USB interfaces ++# ++# CONFIG_CAN_EMS_USB is not set ++# CONFIG_CAN_ESD_USB2 is not set ++# CONFIG_CAN_GS_USB is not set ++# CONFIG_CAN_KVASER_USB is not set ++# CONFIG_CAN_PEAK_USB is not set ++# CONFIG_CAN_8DEV_USB is not set ++# CONFIG_CAN_SOFTING is not set ++# CONFIG_CAN_DEBUG_DEVICES is not set ++# CONFIG_IRDA is not set ++CONFIG_BT=y ++CONFIG_BT_BREDR=y ++CONFIG_BT_RFCOMM=y ++# CONFIG_BT_RFCOMM_TTY is not set ++# CONFIG_BT_BNEP is not set ++CONFIG_BT_HIDP=y ++CONFIG_BT_HS=y ++CONFIG_BT_LE=y ++# CONFIG_BT_SELFTEST is not set ++CONFIG_BT_DEBUGFS=y ++ ++# ++# Bluetooth device drivers ++# ++CONFIG_BT_INTEL=y ++CONFIG_BT_BCM=y ++CONFIG_BT_RTL=y ++# CONFIG_BT_RTKBTUSB is not set ++CONFIG_BT_HCIBTUSB=y ++CONFIG_BT_HCIBTUSB_BCM=y ++CONFIG_BT_HCIBTUSB_RTL=y ++# CONFIG_BT_HCIBTSDIO is not set ++CONFIG_BT_HCIUART=y ++CONFIG_BT_HCIUART_H4=y ++# CONFIG_BT_HCIUART_BCSP is not set ++CONFIG_BT_HCIUART_ATH3K=y ++CONFIG_BT_HCIUART_LL=y ++# CONFIG_BT_HCIUART_3WIRE is not set ++# CONFIG_BT_HCIUART_INTEL is not set ++# CONFIG_BT_HCIUART_BCM is not set ++# CONFIG_BT_HCIUART_QCA is not set ++# CONFIG_BT_HCIBCM203X is not set ++# CONFIG_BT_HCIBPA10X is not set ++CONFIG_BT_HCIBFUSB=y ++CONFIG_BT_HCIVHCI=y ++CONFIG_BT_MRVL=y ++CONFIG_BT_MRVL_SDIO=y ++# CONFIG_BT_ATH3K is not set ++# CONFIG_AF_RXRPC is not set ++CONFIG_WIRELESS=y ++CONFIG_WIRELESS_EXT=y ++CONFIG_WEXT_CORE=y ++CONFIG_WEXT_PROC=y ++CONFIG_WEXT_PRIV=y ++CONFIG_CFG80211=y ++CONFIG_NL80211_TESTMODE=y ++# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set ++# CONFIG_CFG80211_REG_DEBUG is not set ++# CONFIG_CFG80211_CERTIFICATION_ONUS is not set ++CONFIG_CFG80211_DEFAULT_PS=y ++CONFIG_CFG80211_DEBUGFS=y ++# CONFIG_CFG80211_INTERNAL_REGDB is not set ++CONFIG_CFG80211_CRDA_SUPPORT=y ++CONFIG_CFG80211_WEXT=y ++# CONFIG_LIB80211 is not set ++CONFIG_MAC80211=y ++CONFIG_MAC80211_HAS_RC=y ++CONFIG_MAC80211_RC_MINSTREL=y ++CONFIG_MAC80211_RC_MINSTREL_HT=y ++# CONFIG_MAC80211_RC_MINSTREL_VHT is not set ++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y ++CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" ++# CONFIG_MAC80211_MESH is not set ++CONFIG_MAC80211_LEDS=y ++CONFIG_MAC80211_DEBUGFS=y ++# CONFIG_MAC80211_MESSAGE_TRACING is not set ++CONFIG_MAC80211_DEBUG_MENU=y ++# CONFIG_MAC80211_NOINLINE is not set ++CONFIG_MAC80211_VERBOSE_DEBUG=y ++# CONFIG_MAC80211_MLME_DEBUG is not set ++# CONFIG_MAC80211_STA_DEBUG is not set ++# CONFIG_MAC80211_HT_DEBUG is not set ++# CONFIG_MAC80211_OCB_DEBUG is not set ++# CONFIG_MAC80211_IBSS_DEBUG is not set ++# CONFIG_MAC80211_PS_DEBUG is not set ++# CONFIG_MAC80211_TDLS_DEBUG is not set ++# CONFIG_MAC80211_DEBUG_COUNTERS is not set ++CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 ++# CONFIG_WIMAX is not set ++CONFIG_RFKILL=y ++CONFIG_RFKILL_PM=y ++CONFIG_RFKILL_LEDS=y ++# CONFIG_RFKILL_INPUT is not set ++# CONFIG_RFKILL_REGULATOR is not set ++# CONFIG_RFKILL_GPIO is not set ++# CONFIG_NET_9P is not set ++# CONFIG_CAIF is not set ++# CONFIG_CEPH_LIB is not set ++# CONFIG_NFC is not set ++# CONFIG_LWTUNNEL is not set ++# CONFIG_DST_CACHE is not set ++CONFIG_HAVE_BPF_JIT=y ++CONFIG_HAVE_EBPF_JIT=y ++ ++# ++# Device Drivers ++# ++CONFIG_ARM_AMBA=y ++# CONFIG_TEGRA_AHB is not set ++ ++# ++# Generic Driver Options ++# ++CONFIG_UEVENT_HELPER=y ++CONFIG_UEVENT_HELPER_PATH="" ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_STANDALONE=y ++CONFIG_PREVENT_FIRMWARE_BUILD=y ++CONFIG_FW_LOADER=y ++CONFIG_FIRMWARE_IN_KERNEL=y ++CONFIG_EXTRA_FIRMWARE="" ++# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set ++CONFIG_WANT_DEV_COREDUMP=y ++CONFIG_ALLOW_DEV_COREDUMP=y ++CONFIG_DEV_COREDUMP=y ++# CONFIG_DEBUG_DRIVER is not set ++CONFIG_DEBUG_DEVRES=y ++# CONFIG_SYS_HYPERVISOR is not set ++# CONFIG_GENERIC_CPU_DEVICES is not set ++CONFIG_GENERIC_CPU_AUTOPROBE=y ++CONFIG_REGMAP=y ++CONFIG_REGMAP_I2C=y ++CONFIG_REGMAP_SPI=y ++CONFIG_REGMAP_MMIO=y ++CONFIG_REGMAP_IRQ=y ++CONFIG_DMA_SHARED_BUFFER=y ++# CONFIG_FENCE_TRACE is not set ++ ++# ++# Bus devices ++# ++# CONFIG_ARM_CCI400_PMU is not set ++# CONFIG_ARM_CCI500_PMU is not set ++# CONFIG_ARM_CCN is not set ++# CONFIG_VEXPRESS_CONFIG is not set ++CONFIG_CONNECTOR=y ++CONFIG_PROC_EVENTS=y ++# CONFIG_MTD is not set ++CONFIG_DTC=y ++CONFIG_OF=y ++# CONFIG_OF_UNITTEST is not set ++CONFIG_OF_FLATTREE=y ++CONFIG_OF_EARLY_FLATTREE=y ++CONFIG_OF_ADDRESS=y ++CONFIG_OF_IRQ=y ++CONFIG_OF_NET=y ++CONFIG_OF_MDIO=y ++CONFIG_OF_RESERVED_MEM=y ++# CONFIG_OF_OVERLAY is not set ++# CONFIG_PARPORT is not set ++CONFIG_BLK_DEV=y ++# CONFIG_BLK_DEV_NULL_BLK is not set ++CONFIG_ZRAM=y ++# CONFIG_ZRAM_WRITEBACK is not set ++# CONFIG_ZRAM_MEMORY_TRACKING is not set ++# CONFIG_BLK_DEV_COW_COMMON is not set ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 ++# CONFIG_BLK_DEV_CRYPTOLOOP is not set ++# CONFIG_BLK_DEV_DRBD is not set ++# CONFIG_BLK_DEV_NBD is not set ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_COUNT=1 ++CONFIG_BLK_DEV_RAM_SIZE=4096 ++# CONFIG_CDROM_PKTCDVD is not set ++# CONFIG_ATA_OVER_ETH is not set ++# CONFIG_BLK_DEV_RBD is not set ++ ++# ++# Misc devices ++# ++# CONFIG_ROCKCHIP_SCR is not set ++# CONFIG_SENSORS_LIS3LV02D is not set ++# CONFIG_AD525X_DPOT is not set ++# CONFIG_DUMMY_IRQ is not set ++# CONFIG_ICS932S401 is not set ++# CONFIG_ENCLOSURE_SERVICES is not set ++# CONFIG_APDS9802ALS is not set ++# CONFIG_ISL29003 is not set ++# CONFIG_ISL29020 is not set ++# CONFIG_SENSORS_TSL2550 is not set ++# CONFIG_SENSORS_BH1780 is not set ++# CONFIG_SENSORS_BH1770 is not set ++# CONFIG_SENSORS_APDS990X is not set ++# CONFIG_HMC6352 is not set ++# CONFIG_DS1682 is not set ++# CONFIG_TI_DAC7512 is not set ++# CONFIG_BMP085_I2C is not set ++# CONFIG_BMP085_SPI is not set ++# CONFIG_USB_SWITCH_FSA9480 is not set ++# CONFIG_LATTICE_ECP3_CONFIG is not set ++# CONFIG_SRAM is not set ++# CONFIG_MEMORY_STATE_TIME is not set ++# CONFIG_USB_CAM_GPIO is not set ++# CONFIG_GPIO_DET is not set ++# CONFIG_C2PORT is not set ++ ++# ++# EEPROM support ++# ++# CONFIG_EEPROM_AT24 is not set ++# CONFIG_EEPROM_AT25 is not set ++# CONFIG_EEPROM_LEGACY is not set ++# CONFIG_EEPROM_MAX6875 is not set ++# CONFIG_EEPROM_93CX6 is not set ++# CONFIG_EEPROM_93XX46 is not set ++ ++# ++# Texas Instruments shared transport line discipline ++# ++# CONFIG_TI_ST is not set ++# CONFIG_SENSORS_LIS3_SPI is not set ++# CONFIG_SENSORS_LIS3_I2C is not set ++ ++# ++# Altera FPGA firmware download module ++# ++# CONFIG_ALTERA_STAPL is not set ++ ++# ++# Intel MIC Bus Driver ++# ++ ++# ++# SCIF Bus Driver ++# ++ ++# ++# Intel MIC Host Driver ++# ++ ++# ++# Intel MIC Card Driver ++# ++ ++# ++# SCIF Driver ++# ++ ++# ++# Intel MIC Coprocessor State Management (COSM) Drivers ++# ++# CONFIG_ECHO is not set ++# CONFIG_CXL_BASE is not set ++# CONFIG_CXL_KERNEL_API is not set ++# CONFIG_CXL_EEH is not set ++ ++# ++# SCSI device support ++# ++CONFIG_SCSI_MOD=y ++# CONFIG_RAID_ATTRS is not set ++CONFIG_SCSI=y ++CONFIG_SCSI_DMA=y ++# CONFIG_SCSI_NETLINK is not set ++# CONFIG_SCSI_MQ_DEFAULT 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=y ++# CONFIG_BLK_DEV_SR_VENDOR is not set ++# CONFIG_CHR_DEV_SG is not set ++# CONFIG_CHR_DEV_SCH is not set ++# CONFIG_SCSI_CONSTANTS is not set ++# CONFIG_SCSI_LOGGING is not set ++CONFIG_SCSI_SCAN_ASYNC=y ++ ++# ++# SCSI Transports ++# ++CONFIG_SCSI_SPI_ATTRS=y ++# CONFIG_SCSI_FC_ATTRS is not set ++# CONFIG_SCSI_ISCSI_ATTRS is not set ++# CONFIG_SCSI_SAS_ATTRS is not set ++# CONFIG_SCSI_SAS_LIBSAS is not set ++# CONFIG_SCSI_SRP_ATTRS is not set ++CONFIG_SCSI_LOWLEVEL=y ++# CONFIG_ISCSI_TCP is not set ++# CONFIG_ISCSI_BOOT_SYSFS is not set ++# CONFIG_SCSI_UFSHCD is not set ++# CONFIG_SCSI_DEBUG is not set ++# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set ++# CONFIG_SCSI_DH is not set ++# CONFIG_SCSI_OSD_INITIATOR is not set ++CONFIG_HAVE_PATA_PLATFORM=y ++# CONFIG_ATA is not set ++# CONFIG_MD is not set ++# CONFIG_TARGET_CORE is not set ++CONFIG_NETDEVICES=y ++CONFIG_MII=y ++CONFIG_NET_CORE=y ++# CONFIG_BONDING is not set ++# CONFIG_DUMMY is not set ++# CONFIG_EQUALIZER is not set ++# CONFIG_NET_TEAM is not set ++# CONFIG_MACVLAN is not set ++# CONFIG_IPVLAN is not set ++# CONFIG_VXLAN is not set ++# CONFIG_NETCONSOLE is not set ++# CONFIG_NETPOLL is not set ++# CONFIG_NET_POLL_CONTROLLER is not set ++# CONFIG_TUN is not set ++# CONFIG_TUN_VNET_CROSS_LE is not set ++# CONFIG_VETH is not set ++# CONFIG_NLMON is not set ++ ++# ++# CAIF transport drivers ++# ++ ++# ++# Distributed Switch Architecture drivers ++# ++# CONFIG_NET_DSA_MV88E6XXX is not set ++# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set ++CONFIG_ETHERNET=y ++# CONFIG_ALTERA_TSE is not set ++# CONFIG_NET_VENDOR_AMD is not set ++# CONFIG_NET_VENDOR_ARC is not set ++# CONFIG_NET_VENDOR_AURORA is not set ++# CONFIG_NET_CADENCE is not set ++# CONFIG_NET_VENDOR_BROADCOM is not set ++# CONFIG_DNET is not set ++# CONFIG_NET_VENDOR_EZCHIP is not set ++# CONFIG_NET_VENDOR_HISILICON is not set ++# CONFIG_NET_VENDOR_INTEL is not set ++# CONFIG_NET_VENDOR_MARVELL is not set ++# CONFIG_NET_VENDOR_MICREL is not set ++# CONFIG_NET_VENDOR_MICROCHIP is not set ++# CONFIG_NET_VENDOR_NATSEMI is not set ++# CONFIG_ETHOC is not set ++# CONFIG_NET_VENDOR_QUALCOMM is not set ++# CONFIG_NET_VENDOR_RENESAS is not set ++# CONFIG_NET_VENDOR_ROCKER is not set ++# CONFIG_NET_VENDOR_SAMSUNG is not set ++# CONFIG_NET_VENDOR_SEEQ is not set ++# CONFIG_NET_VENDOR_SMSC is not set ++CONFIG_NET_VENDOR_SMSC9514=y ++CONFIG_SMSC9500=m ++CONFIG_SMSCUSBNET=m ++CONFIG_NET_VENDOR_STMICRO=y ++CONFIG_STMMAC_ETH=y ++CONFIG_STMMAC_PLATFORM=y ++# CONFIG_DWMAC_GENERIC is not set ++# CONFIG_DWMAC_IPQ806X is not set ++# CONFIG_DWMAC_LPC18XX is not set ++# CONFIG_DWMAC_MESON is not set ++CONFIG_DWMAC_ROCKCHIP=y ++# CONFIG_DWMAC_SOCFPGA is not set ++# CONFIG_DWMAC_STI is not set ++# CONFIG_DWMAC_SUNXI is not set ++# CONFIG_NET_VENDOR_SYNOPSYS is not set ++# CONFIG_NET_VENDOR_VIA is not set ++# CONFIG_NET_VENDOR_WIZNET is not set ++CONFIG_PHYLIB=y ++ ++# ++# MII PHY device drivers ++# ++# CONFIG_AQUANTIA_PHY is not set ++# CONFIG_AT803X_PHY is not set ++# CONFIG_AMD_PHY is not set ++# CONFIG_MARVELL_PHY is not set ++# CONFIG_DAVICOM_PHY is not set ++# CONFIG_QSEMI_PHY is not set ++# CONFIG_LXT_PHY is not set ++# CONFIG_CICADA_PHY is not set ++# CONFIG_VITESSE_PHY is not set ++# CONFIG_TERANETICS_PHY is not set ++CONFIG_ROCKCHIP_PHY=y ++# CONFIG_SMSC_PHY is not set ++# CONFIG_BROADCOM_PHY is not set ++# CONFIG_BCM7XXX_PHY is not set ++# CONFIG_BCM87XX_PHY is not set ++# CONFIG_ICPLUS_PHY is not set ++# CONFIG_REALTEK_PHY is not set ++# CONFIG_NATIONAL_PHY is not set ++# CONFIG_STE10XP is not set ++# CONFIG_LSI_ET1011C_PHY is not set ++# CONFIG_MICREL_PHY is not set ++# CONFIG_DP83848_PHY is not set ++# CONFIG_DP83867_PHY is not set ++# CONFIG_MICROCHIP_PHY is not set ++# CONFIG_FIXED_PHY is not set ++# CONFIG_MDIO_BITBANG is not set ++# CONFIG_MDIO_OCTEON is not set ++# CONFIG_MDIO_BUS_MUX_GPIO is not set ++# CONFIG_MDIO_BUS_MUX_MMIOREG is not set ++# CONFIG_MDIO_BCM_UNIMAC is not set ++# CONFIG_MICREL_KS8995MA is not set ++# CONFIG_PPP is not set ++# CONFIG_SLIP is not set ++CONFIG_USB_NET_DRIVERS=y ++# CONFIG_USB_CATC is not set ++# CONFIG_USB_KAWETH is not set ++# CONFIG_USB_PEGASUS is not set ++CONFIG_USB_RTL8150=y ++CONFIG_USB_RTL8152=y ++# CONFIG_USB_LAN78XX is not set ++CONFIG_USB_USBNET=y ++CONFIG_USB_NET_AX8817X=y ++CONFIG_USB_NET_AX88179_178A=y ++CONFIG_USB_NET_CDCETHER=y ++# CONFIG_USB_NET_CDC_EEM is not set ++CONFIG_USB_NET_CDC_NCM=y ++# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set ++CONFIG_USB_NET_CDC_MBIM=y ++# CONFIG_USB_NET_DM9601 is not set ++# CONFIG_USB_NET_SR9700 is not set ++# CONFIG_USB_NET_SR9800 is not set ++# CONFIG_USB_NET_SMSC75XX is not set ++CONFIG_USB_NET_SMSC95XX=y ++# CONFIG_USB_NET_GL620A is not set ++# CONFIG_USB_NET_NET1080 is not set ++# CONFIG_USB_NET_PLUSB is not set ++# CONFIG_USB_NET_MCS7830 is not set ++CONFIG_USB_NET_RNDIS_HOST=y ++# CONFIG_USB_NET_CDC_SUBSET is not set ++# CONFIG_USB_NET_ZAURUS is not set ++# CONFIG_USB_NET_CX82310_ETH is not set ++# CONFIG_USB_NET_KALMIA is not set ++# CONFIG_USB_NET_QMI_WWAN is not set ++# CONFIG_USB_HSO is not set ++# CONFIG_USB_NET_INT51X1 is not set ++# CONFIG_USB_IPHETH is not set ++# CONFIG_USB_SIERRA_NET is not set ++# CONFIG_USB_VL600 is not set ++# CONFIG_USB_NET_CH9200 is not set ++CONFIG_WLAN=y ++CONFIG_LIBERTAS_THINFIRM=y ++# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set ++# CONFIG_LIBERTAS_THINFIRM_USB is not set ++# CONFIG_AT76C50X_USB is not set ++# CONFIG_USB_ZD1201 is not set ++CONFIG_USB_NET_RNDIS_WLAN=y ++# CONFIG_RTL8187 is not set ++# CONFIG_MAC80211_HWSIM is not set ++# CONFIG_VIRT_WIFI is not set ++# CONFIG_ATH_CARDS is not set ++# CONFIG_B43 is not set ++# CONFIG_B43LEGACY is not set ++# CONFIG_BRCMSMAC is not set ++# CONFIG_BRCMFMAC is not set ++# CONFIG_HOSTAP is not set ++# CONFIG_LIBERTAS is not set ++# CONFIG_P54_COMMON is not set ++# CONFIG_RT2X00 is not set ++# CONFIG_WL_MEDIATEK is not set ++CONFIG_RTL_CARDS=y ++# CONFIG_RTL8192CU is not set ++# CONFIG_RTL8XXXU is not set ++CONFIG_WL_ROCKCHIP=y ++CONFIG_WIFI_BUILD_MODULE=y ++# CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP is not set ++# CONFIG_WIFI_GENERATE_RANDOM_MAC_ADDR is not set ++CONFIG_AP6XXX=m ++# CONFIG_CYW_BCMDHD is not set ++CONFIG_RTL_WIRELESS_SOLUTION=y ++CONFIG_RTL8188EU=m ++# CONFIG_RTL8188FU is not set ++# CONFIG_RTL8189ES is not set ++# CONFIG_RTL8189FS is not set ++# CONFIG_RTL8723BS is not set ++# CONFIG_RTL8723BU is not set ++# CONFIG_RTL8723CS is not set ++# CONFIG_RTL8723DS is not set ++# CONFIG_MVL88W8977 is not set ++ ++# ++# SouthSV 6XXX WLAN support ++# ++# CONFIG_SSV6051 is not set ++# CONFIG_WL_TI is not set ++# CONFIG_ZD1211RW is not set ++CONFIG_MWIFIEX=y ++CONFIG_MWIFIEX_SDIO=y ++# CONFIG_MWIFIEX_USB is not set ++# CONFIG_CW1200 is not set ++# CONFIG_RSI_91X is not set ++ ++# ++# Enable WiMAX (Networking options) to see the WiMAX drivers ++# ++# CONFIG_WAN is not set ++# CONFIG_ISDN is not set ++# CONFIG_NVM is not set ++ ++# ++# Input device support ++# ++CONFIG_INPUT=y ++CONFIG_INPUT_LEDS=y ++CONFIG_INPUT_FF_MEMLESS=y ++CONFIG_INPUT_POLLDEV=y ++# CONFIG_INPUT_SPARSEKMAP is not set ++CONFIG_INPUT_MATRIXKMAP=y ++ ++# ++# Userland interfaces ++# ++# CONFIG_INPUT_MOUSEDEV is not set ++# CONFIG_INPUT_JOYDEV is not set ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_EVBUG is not set ++# CONFIG_INPUT_KEYRESET is not set ++# CONFIG_INPUT_KEYCOMBO is not set ++ ++# ++# Input Device Drivers ++# ++CONFIG_INPUT_KEYBOARD=y ++CONFIG_KEYBOARD_ADC=y ++# CONFIG_KEYBOARD_ADP5588 is not set ++# CONFIG_KEYBOARD_ADP5589 is not set ++# CONFIG_KEYBOARD_ATKBD is not set ++# CONFIG_KEYBOARD_QT1070 is not set ++# CONFIG_KEYBOARD_QT2160 is not set ++# CONFIG_KEYBOARD_LKKBD is not set ++CONFIG_KEYBOARD_GPIO=y ++CONFIG_KEYBOARD_GPIO_POLLED=y ++# CONFIG_KEYBOARD_TCA6416 is not set ++# CONFIG_KEYBOARD_TCA8418 is not set ++# CONFIG_KEYBOARD_MATRIX is not set ++# CONFIG_KEYBOARD_LM8323 is not set ++# CONFIG_KEYBOARD_LM8333 is not set ++# CONFIG_KEYBOARD_MAX7359 is not set ++# CONFIG_KEYBOARD_MCS is not set ++# CONFIG_KEYBOARD_MPR121 is not set ++# CONFIG_KEYBOARD_NEWTON is not set ++# CONFIG_KEYBOARD_OPENCORES is not set ++# CONFIG_KEYBOARD_SAMSUNG is not set ++# CONFIG_KEYBOARD_STOWAWAY is not set ++# CONFIG_KEYBOARD_SUNKBD is not set ++# CONFIG_KEYBOARD_OMAP4 is not set ++CONFIG_KEYBOARD_ROCKCHIP=y ++# CONFIG_KEYBOARD_XTKBD is not set ++# CONFIG_KEYBOARD_CAP11XX is not set ++# CONFIG_KEYBOARD_BCM is not set ++CONFIG_INPUT_MOUSE=y ++# CONFIG_MOUSE_PS2 is not set ++# CONFIG_MOUSE_SERIAL is not set ++# CONFIG_MOUSE_APPLETOUCH is not set ++# CONFIG_MOUSE_BCM5974 is not set ++CONFIG_MOUSE_CYAPA=y ++CONFIG_MOUSE_ELAN_I2C=y ++CONFIG_MOUSE_ELAN_I2C_I2C=y ++# CONFIG_MOUSE_ELAN_I2C_SMBUS is not set ++# CONFIG_MOUSE_VSXXXAA is not set ++# CONFIG_MOUSE_GPIO is not set ++# CONFIG_MOUSE_SYNAPTICS_I2C is not set ++# CONFIG_MOUSE_SYNAPTICS_USB is not set ++# CONFIG_INPUT_JOYSTICK is not set ++# CONFIG_INPUT_TABLET is not set ++CONFIG_INPUT_TOUCHSCREEN=y ++CONFIG_TOUCHSCREEN_PROPERTIES=y ++# CONFIG_TOUCHSCREEN_ADS7846 is not set ++# CONFIG_TOUCHSCREEN_AD7877 is not set ++# CONFIG_TOUCHSCREEN_AD7879 is not set ++# CONFIG_TOUCHSCREEN_AR1021_I2C is not set ++CONFIG_TOUCHSCREEN_ATMEL_MXT=y ++# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set ++# CONFIG_TOUCHSCREEN_BU21013 is not set ++# CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set ++# CONFIG_TOUCHSCREEN_CY8C40XX is not set ++# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set ++# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set ++# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set ++# CONFIG_TOUCHSCREEN_DYNAPRO is not set ++# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set ++# CONFIG_TOUCHSCREEN_EETI is not set ++# CONFIG_TOUCHSCREEN_EGALAX is not set ++# CONFIG_TOUCHSCREEN_FT6236 is not set ++# CONFIG_TOUCHSCREEN_FUJITSU is not set ++# CONFIG_TOUCHSCREEN_GOODIX is not set ++# CONFIG_TOUCHSCREEN_GSLX680A is not set ++# CONFIG_TOUCHSCREEN_GSLX680_D708 is not set ++# CONFIG_TOUCHSCREEN_GSLX680_PAD is not set ++CONFIG_TOUCHSCREEN_GSLX680_VR=y ++# CONFIG_TOUCHSCREEN_GSLX680_FIREFLY is not set ++CONFIG_TOUCHSCREEN_GSL3673=y ++# CONFIG_TOUCHSCREEN_GSL3673_800X1280 is not set ++CONFIG_TOUCHSCREEN_GT9XX=y ++# CONFIG_TOUCHSCREEN_ILI210X is not set ++# CONFIG_TOUCHSCREEN_GUNZE is not set ++CONFIG_TOUCHSCREEN_ELAN=y ++# CONFIG_TOUCHSCREEN_ELO is not set ++# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set ++# CONFIG_TOUCHSCREEN_WACOM_I2C is not set ++# CONFIG_TOUCHSCREEN_MAX11801 is not set ++# CONFIG_TOUCHSCREEN_MCS5000 is not set ++# CONFIG_TOUCHSCREEN_MMS114 is not set ++# CONFIG_TOUCHSCREEN_MTOUCH is not set ++# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set ++# CONFIG_TOUCHSCREEN_INEXIO is not set ++# CONFIG_TOUCHSCREEN_MK712 is not set ++# CONFIG_TOUCHSCREEN_PENMOUNT is not set ++# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set ++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set ++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set ++# CONFIG_TOUCHSCREEN_PIXCIR is not set ++# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set ++CONFIG_TOUCHSCREEN_USB_COMPOSITE=y ++CONFIG_TOUCHSCREEN_USB_EGALAX=y ++CONFIG_TOUCHSCREEN_USB_PANJIT=y ++CONFIG_TOUCHSCREEN_USB_3M=y ++CONFIG_TOUCHSCREEN_USB_ITM=y ++CONFIG_TOUCHSCREEN_USB_ETURBO=y ++CONFIG_TOUCHSCREEN_USB_GUNZE=y ++CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y ++CONFIG_TOUCHSCREEN_USB_IRTOUCH=y ++CONFIG_TOUCHSCREEN_USB_IDEALTEK=y ++CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y ++CONFIG_TOUCHSCREEN_USB_GOTOP=y ++CONFIG_TOUCHSCREEN_USB_JASTEC=y ++CONFIG_TOUCHSCREEN_USB_ELO=y ++CONFIG_TOUCHSCREEN_USB_E2I=y ++CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y ++CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y ++CONFIG_TOUCHSCREEN_USB_NEXIO=y ++CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y ++# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set ++# CONFIG_TOUCHSCREEN_TSC_SERIO is not set ++# CONFIG_TOUCHSCREEN_TSC2004 is not set ++# CONFIG_TOUCHSCREEN_TSC2005 is not set ++# CONFIG_TOUCHSCREEN_TSC2007 is not set ++# CONFIG_TOUCHSCREEN_ST1232 is not set ++# CONFIG_TOUCHSCREEN_SUR40 is not set ++# CONFIG_TOUCHSCREEN_SX8654 is not set ++# CONFIG_TOUCHSCREEN_TPS6507X is not set ++# CONFIG_TOUCHSCREEN_ZFORCE is not set ++# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set ++# CONFIG_TOUCHSCREEN_VTL_CT36X is not set ++CONFIG_TOUCHSCREEN_GT1X=y ++CONFIG_ROCKCHIP_REMOTECTL=y ++CONFIG_ROCKCHIP_REMOTECTL_PWM=y ++ ++# ++# handle all sensors ++# ++# CONFIG_SENSOR_DEVICE is not set ++CONFIG_INPUT_MISC=y ++# CONFIG_INPUT_AD714X is not set ++# CONFIG_INPUT_BMA150 is not set ++# CONFIG_INPUT_E3X0_BUTTON is not set ++# CONFIG_INPUT_MMA8450 is not set ++# CONFIG_INPUT_MPU3050 is not set ++# CONFIG_INPUT_GP2A is not set ++# CONFIG_INPUT_GPIO_BEEPER is not set ++# CONFIG_INPUT_GPIO_TILT_POLLED is not set ++# CONFIG_INPUT_ATI_REMOTE2 is not set ++# CONFIG_INPUT_KEYCHORD is not set ++# CONFIG_INPUT_KEYSPAN_REMOTE is not set ++# CONFIG_INPUT_KXTJ9 is not set ++# CONFIG_INPUT_POWERMATE is not set ++# CONFIG_INPUT_YEALINK is not set ++# CONFIG_INPUT_CM109 is not set ++# CONFIG_INPUT_REGULATOR_HAPTIC is not set ++CONFIG_INPUT_RK8XX_PWRKEY=y ++CONFIG_INPUT_UINPUT=y ++CONFIG_INPUT_GPIO=y ++# CONFIG_INPUT_PCF8574 is not set ++# CONFIG_INPUT_PWM_BEEPER is not set ++# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set ++# CONFIG_INPUT_ADXL34X is not set ++# CONFIG_INPUT_IMS_PCU is not set ++# CONFIG_INPUT_CMA3000 is not set ++# CONFIG_INPUT_SOC_BUTTON_ARRAY is not set ++# CONFIG_INPUT_DRV260X_HAPTICS is not set ++# CONFIG_INPUT_DRV2665_HAPTICS is not set ++# CONFIG_INPUT_DRV2667_HAPTICS is not set ++ ++# ++# Hardware I/O ports ++# ++# CONFIG_SERIO is not set ++# CONFIG_GAMEPORT is not set ++ ++# ++# Character devices ++# ++CONFIG_TTY=y ++CONFIG_VT=y ++CONFIG_CONSOLE_TRANSLATIONS=y ++CONFIG_VT_CONSOLE=y ++CONFIG_VT_CONSOLE_SLEEP=y ++CONFIG_HW_CONSOLE=y ++CONFIG_VT_HW_CONSOLE_BINDING=y ++CONFIG_UNIX98_PTYS=y ++CONFIG_DEVPTS_MULTIPLE_INSTANCES=y ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_SERIAL_NONSTANDARD is not set ++# CONFIG_N_GSM is not set ++# CONFIG_TRACE_SINK is not set ++CONFIG_LDISC_AUTOLOAD=y ++CONFIG_DEVMEM=y ++# CONFIG_DEVKMEM is not set ++ ++# ++# Serial drivers ++# ++CONFIG_SERIAL_EARLYCON=y ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_DMA=y ++CONFIG_SERIAL_8250_NR_UARTS=5 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=5 ++# CONFIG_SERIAL_8250_EXTENDED is not set ++CONFIG_SERIAL_8250_FSL=y ++CONFIG_SERIAL_8250_DW=y ++# CONFIG_SERIAL_8250_RT288X is not set ++# CONFIG_SERIAL_8250_INGENIC is not set ++ ++# ++# Non-8250 serial port support ++# ++# CONFIG_SERIAL_AMBA_PL010 is not set ++# CONFIG_SERIAL_AMBA_PL011 is not set ++# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set ++# CONFIG_SERIAL_MAX3100 is not set ++# CONFIG_SERIAL_MAX310X is not set ++# CONFIG_SERIAL_UARTLITE is not set ++CONFIG_SERIAL_CORE=y ++CONFIG_SERIAL_CORE_CONSOLE=y ++CONFIG_SERIAL_OF_PLATFORM=y ++# CONFIG_SERIAL_SCCNXP is not set ++# CONFIG_SERIAL_SC16IS7XX is not set ++# CONFIG_SERIAL_ALTERA_JTAGUART is not set ++# CONFIG_SERIAL_ALTERA_UART is not set ++# CONFIG_SERIAL_IFX6X60 is not set ++# CONFIG_SERIAL_XILINX_PS_UART is not set ++# CONFIG_SERIAL_ARC is not set ++# CONFIG_SERIAL_FSL_LPUART is not set ++# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set ++# CONFIG_TTY_PRINTK is not set ++# CONFIG_HVC_DCC is not set ++# CONFIG_IPMI_HANDLER is not set ++CONFIG_HW_RANDOM=y ++# CONFIG_HW_RANDOM_TIMERIOMEM is not set ++CONFIG_HW_RANDOM_TPM=y ++CONFIG_HW_RANDOM_ROCKCHIP=y ++ ++# ++# PCMCIA character devices ++# ++# CONFIG_RAW_DRIVER is not set ++CONFIG_TCG_TPM=y ++# CONFIG_TCG_TIS_I2C_ATMEL is not set ++CONFIG_TCG_TIS_I2C_INFINEON=y ++# CONFIG_TCG_TIS_I2C_NUVOTON is not set ++# CONFIG_TCG_TIS_ST33ZP24 is not set ++# CONFIG_XILLYBUS is not set ++ ++# ++# I2C support ++# ++CONFIG_I2C=y ++CONFIG_I2C_BOARDINFO=y ++CONFIG_I2C_COMPAT=y ++CONFIG_I2C_CHARDEV=y ++CONFIG_I2C_MUX=y ++ ++# ++# Multiplexer I2C Chip support ++# ++# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set ++# CONFIG_I2C_MUX_GPIO is not set ++# CONFIG_I2C_MUX_PCA9541 is not set ++# CONFIG_I2C_MUX_PCA954x is not set ++# CONFIG_I2C_MUX_PINCTRL is not set ++# CONFIG_I2C_MUX_REG is not set ++CONFIG_I2C_HELPER_AUTO=y ++CONFIG_I2C_ALGOBIT=y ++ ++# ++# I2C Hardware Bus support ++# ++ ++# ++# I2C system bus drivers (mostly embedded / system-on-chip) ++# ++# CONFIG_I2C_CADENCE is not set ++# CONFIG_I2C_CBUS_GPIO is not set ++# CONFIG_I2C_DESIGNWARE_PLATFORM is not set ++# CONFIG_I2C_EMEV2 is not set ++# CONFIG_I2C_GPIO is not set ++# CONFIG_I2C_NOMADIK is not set ++# CONFIG_I2C_OCORES is not set ++# CONFIG_I2C_PCA_PLATFORM is not set ++# CONFIG_I2C_PXA_PCI is not set ++CONFIG_I2C_RK3X=y ++# CONFIG_I2C_SIMTEC is not set ++# CONFIG_I2C_XILINX is not set ++ ++# ++# External I2C/SMBus adapter drivers ++# ++# CONFIG_I2C_DIOLAN_U2C is not set ++# CONFIG_I2C_PARPORT_LIGHT is not set ++# CONFIG_I2C_ROBOTFUZZ_OSIF is not set ++# CONFIG_I2C_TAOS_EVM is not set ++# CONFIG_I2C_TINY_USB is not set ++ ++# ++# Other I2C/SMBus bus drivers ++# ++# CONFIG_I2C_STUB is not set ++# CONFIG_I2C_SLAVE 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_SPI=y ++# CONFIG_SPI_DEBUG is not set ++CONFIG_SPI_MASTER=y ++ ++# ++# SPI Master Controller Drivers ++# ++# CONFIG_SPI_ALTERA is not set ++CONFIG_SPI_BITBANG=y ++# CONFIG_SPI_CADENCE is not set ++# CONFIG_SPI_GPIO is not set ++# CONFIG_SPI_FSL_SPI is not set ++# CONFIG_SPI_OC_TINY is not set ++# CONFIG_SPI_PL022 is not set ++# CONFIG_SPI_PXA2XX_PCI is not set ++CONFIG_SPI_ROCKCHIP=y ++# CONFIG_SPI_SC18IS602 is not set ++# CONFIG_SPI_XCOMM is not set ++# CONFIG_SPI_XILINX is not set ++# CONFIG_SPI_ZYNQMP_GQSPI is not set ++# CONFIG_SPI_DESIGNWARE is not set ++ ++# ++# SPI Protocol Masters ++# ++CONFIG_SPI_SPIDEV=y ++# CONFIG_SPI_TLE62X0 is not set ++# CONFIG_SPMI is not set ++# CONFIG_HSI is not set ++ ++# ++# PPS support ++# ++CONFIG_PPS=y ++# CONFIG_PPS_DEBUG is not set ++ ++# ++# PPS clients support ++# ++# CONFIG_PPS_CLIENT_KTIMER is not set ++# CONFIG_PPS_CLIENT_LDISC is not set ++# CONFIG_PPS_CLIENT_GPIO is not set ++ ++# ++# PPS generators support ++# ++ ++# ++# PTP clock support ++# ++CONFIG_PTP_1588_CLOCK=y ++ ++# ++# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. ++# ++CONFIG_PINCTRL=y ++ ++# ++# Pin controllers ++# ++CONFIG_PINMUX=y ++CONFIG_PINCONF=y ++CONFIG_GENERIC_PINCONF=y ++# CONFIG_DEBUG_PINCTRL is not set ++# CONFIG_PINCTRL_AMD is not set ++CONFIG_PINCTRL_ROCKCHIP=y ++# CONFIG_PINCTRL_SINGLE is not set ++CONFIG_PINCTRL_RK805=y ++CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y ++CONFIG_ARCH_REQUIRE_GPIOLIB=y ++CONFIG_GPIOLIB=y ++CONFIG_GPIO_DEVRES=y ++CONFIG_OF_GPIO=y ++CONFIG_DEBUG_GPIO=y ++CONFIG_GPIO_SYSFS=y ++CONFIG_GPIO_GENERIC=y ++ ++# ++# Memory mapped GPIO drivers ++# ++# CONFIG_GPIO_74XX_MMIO is not set ++# CONFIG_GPIO_ALTERA is not set ++# CONFIG_GPIO_DWAPB is not set ++CONFIG_GPIO_GENERIC_PLATFORM=y ++# CONFIG_GPIO_GRGPIO is not set ++# CONFIG_GPIO_PL061 is not set ++# CONFIG_GPIO_SYSCON is not set ++# CONFIG_GPIO_XGENE is not set ++# CONFIG_GPIO_XILINX is not set ++# CONFIG_GPIO_ZX is not set ++ ++# ++# I2C GPIO expanders ++# ++# CONFIG_GPIO_ADP5588 is not set ++# CONFIG_GPIO_ADNP is not set ++# CONFIG_GPIO_MAX7300 is not set ++# CONFIG_GPIO_MAX732X is not set ++# CONFIG_GPIO_PCA953X is not set ++# CONFIG_GPIO_PCF857X is not set ++# CONFIG_GPIO_SX150X is not set ++ ++# ++# MFD GPIO expanders ++# ++CONFIG_GPIO_RK8XX=y ++ ++# ++# SPI GPIO expanders ++# ++# CONFIG_GPIO_74X164 is not set ++# CONFIG_GPIO_MAX7301 is not set ++# CONFIG_GPIO_MC33880 is not set ++ ++# ++# SPI or I2C GPIO expanders ++# ++# CONFIG_GPIO_MCP23S08 is not set ++ ++# ++# USB GPIO expanders ++# ++# CONFIG_W1 is not set ++CONFIG_POWER_SUPPLY=y ++# CONFIG_POWER_SUPPLY_DEBUG is not set ++# CONFIG_PDA_POWER is not set ++# CONFIG_GENERIC_ADC_BATTERY is not set ++# CONFIG_TEST_POWER is not set ++# CONFIG_BATTERY_DS2780 is not set ++# CONFIG_BATTERY_DS2781 is not set ++# CONFIG_BATTERY_DS2782 is not set ++# CONFIG_BATTERY_SBS is not set ++# CONFIG_BATTERY_BQ27XXX is not set ++# CONFIG_BATTERY_MAX17040 is not set ++# CONFIG_BATTERY_MAX17042 is not set ++# CONFIG_CHARGER_MAX8903 is not set ++# CONFIG_CHARGER_LP8727 is not set ++CONFIG_CHARGER_GPIO=y ++# CONFIG_CHARGER_MANAGER is not set ++# CONFIG_CHARGER_BQ2415X is not set ++# CONFIG_CHARGER_BQ24190 is not set ++# CONFIG_CHARGER_BQ24257 is not set ++# CONFIG_CHARGER_BQ24735 is not set ++# CONFIG_CHARGER_BQ25700 is not set ++# CONFIG_CHARGER_BQ25890 is not set ++# CONFIG_CHARGER_SMB347 is not set ++# CONFIG_CHARGER_SY6982C is not set ++# CONFIG_CHARGER_UNIVERSAL is not set ++# CONFIG_BATTERY_GAUGE_LTC2941 is not set ++# CONFIG_BATTERY_EC is not set ++# CONFIG_BATTERY_CW2015 is not set ++# CONFIG_BATTERY_RK816 is not set ++CONFIG_BATTERY_RK817=y ++CONFIG_CHARGER_RK817=y ++# CONFIG_BATTERY_RK818 is not set ++# CONFIG_CHARGER_RK818 is not set ++# CONFIG_CHARGER_RT9455 is not set ++CONFIG_POWER_RESET=y ++CONFIG_POWER_RESET_GPIO=y ++CONFIG_POWER_RESET_GPIO_RESTART=y ++# CONFIG_POWER_RESET_LTC2952 is not set ++# CONFIG_POWER_RESET_RESTART is not set ++# CONFIG_POWER_RESET_XGENE is not set ++# CONFIG_POWER_RESET_SYSCON is not set ++# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set ++CONFIG_REBOOT_MODE=y ++CONFIG_SYSCON_REBOOT_MODE=y ++CONFIG_POWER_AVS=y ++CONFIG_ROCKCHIP_IODOMAIN=y ++CONFIG_HWMON=y ++# CONFIG_HWMON_VID is not set ++# CONFIG_HWMON_DEBUG_CHIP is not set ++ ++# ++# Native drivers ++# ++# CONFIG_SENSORS_AD7314 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_ADT7310 is not set ++# CONFIG_SENSORS_ADT7410 is not set ++# CONFIG_SENSORS_ADT7411 is not set ++# CONFIG_SENSORS_ADT7462 is not set ++# CONFIG_SENSORS_ADT7470 is not set ++# CONFIG_SENSORS_ADT7475 is not set ++# CONFIG_SENSORS_ASC7621 is not set ++# CONFIG_SENSORS_ATXP1 is not set ++# CONFIG_SENSORS_DS620 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_G760A is not set ++# CONFIG_SENSORS_G762 is not set ++# CONFIG_SENSORS_GPIO_FAN is not set ++# CONFIG_SENSORS_HIH6130 is not set ++# CONFIG_SENSORS_IIO_HWMON is not set ++# CONFIG_SENSORS_IT87 is not set ++# CONFIG_SENSORS_JC42 is not set ++# CONFIG_SENSORS_POWR1220 is not set ++# CONFIG_SENSORS_LINEAGE is not set ++# CONFIG_SENSORS_LTC2945 is not set ++# CONFIG_SENSORS_LTC4151 is not set ++# CONFIG_SENSORS_LTC4215 is not set ++# CONFIG_SENSORS_LTC4222 is not set ++# CONFIG_SENSORS_LTC4245 is not set ++# CONFIG_SENSORS_LTC4260 is not set ++# CONFIG_SENSORS_LTC4261 is not set ++# CONFIG_SENSORS_MAX1111 is not set ++# CONFIG_SENSORS_MAX16065 is not set ++# CONFIG_SENSORS_MAX1619 is not set ++# CONFIG_SENSORS_MAX1668 is not set ++# CONFIG_SENSORS_MAX197 is not set ++# CONFIG_SENSORS_MAX6639 is not set ++# CONFIG_SENSORS_MAX6642 is not set ++# CONFIG_SENSORS_MAX6650 is not set ++# CONFIG_SENSORS_MAX6697 is not set ++# CONFIG_SENSORS_MAX31790 is not set ++# CONFIG_SENSORS_HTU21 is not set ++# CONFIG_SENSORS_MCP3021 is not set ++# CONFIG_SENSORS_ADCXX is not set ++# CONFIG_SENSORS_LM63 is not set ++# CONFIG_SENSORS_LM70 is not set ++# CONFIG_SENSORS_LM73 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_LM95234 is not set ++# CONFIG_SENSORS_LM95241 is not set ++# CONFIG_SENSORS_LM95245 is not set ++# CONFIG_SENSORS_PC87360 is not set ++# CONFIG_SENSORS_PC87427 is not set ++# CONFIG_SENSORS_NTC_THERMISTOR is not set ++# CONFIG_SENSORS_NCT6683 is not set ++# CONFIG_SENSORS_NCT6775 is not set ++# CONFIG_SENSORS_NCT7802 is not set ++# CONFIG_SENSORS_NCT7904 is not set ++# CONFIG_SENSORS_PCF8591 is not set ++# CONFIG_PMBUS is not set ++# CONFIG_SENSORS_PWM_FAN is not set ++# CONFIG_SENSORS_SHT15 is not set ++# CONFIG_SENSORS_SHT21 is not set ++# CONFIG_SENSORS_SHTC1 is not set ++# CONFIG_SENSORS_DME1737 is not set ++# CONFIG_SENSORS_EMC1403 is not set ++# CONFIG_SENSORS_EMC2103 is not set ++# CONFIG_SENSORS_EMC6W201 is not set ++# CONFIG_SENSORS_SMSC47M1 is not set ++# CONFIG_SENSORS_SMSC47M192 is not set ++# CONFIG_SENSORS_SMSC47B397 is not set ++# CONFIG_SENSORS_SCH56XX_COMMON is not set ++# CONFIG_SENSORS_SCH5627 is not set ++# CONFIG_SENSORS_SCH5636 is not set ++# CONFIG_SENSORS_SMM665 is not set ++# CONFIG_SENSORS_ADC128D818 is not set ++CONFIG_SENSORS_ADS1015=y ++# CONFIG_SENSORS_ADS7828 is not set ++# CONFIG_SENSORS_ADS7871 is not set ++# CONFIG_SENSORS_AMC6821 is not set ++# CONFIG_SENSORS_INA209 is not set ++# CONFIG_SENSORS_INA2XX is not set ++# CONFIG_SENSORS_TC74 is not set ++# CONFIG_SENSORS_THMC50 is not set ++# CONFIG_SENSORS_TMP102 is not set ++# CONFIG_SENSORS_TMP103 is not set ++# CONFIG_SENSORS_TMP401 is not set ++# CONFIG_SENSORS_TMP421 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_W83795 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_THERMAL=y ++CONFIG_THERMAL_HWMON=y ++CONFIG_THERMAL_OF=y ++CONFIG_THERMAL_WRITABLE_TRIPS=y ++# CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE is not set ++# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set ++# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set ++CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR=y ++CONFIG_THERMAL_GOV_FAIR_SHARE=y ++CONFIG_THERMAL_GOV_STEP_WISE=y ++# CONFIG_THERMAL_GOV_BANG_BANG is not set ++# CONFIG_THERMAL_GOV_USER_SPACE is not set ++CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y ++CONFIG_CPU_THERMAL=y ++# CONFIG_CLOCK_THERMAL is not set ++CONFIG_DEVFREQ_THERMAL=y ++# CONFIG_THERMAL_EMULATION is not set ++# CONFIG_IMX_THERMAL is not set ++CONFIG_ROCKCHIP_THERMAL=y ++# CONFIG_RK_VIRTUAL_THERMAL is not set ++# CONFIG_RK3368_THERMAL is not set ++CONFIG_WATCHDOG=y ++# CONFIG_WATCHDOG_CORE is not set ++# CONFIG_WATCHDOG_NOWAYOUT is not set ++ ++# ++# Watchdog Device Drivers ++# ++# CONFIG_SOFT_WATCHDOG is not set ++# CONFIG_GPIO_WATCHDOG is not set ++# CONFIG_XILINX_WATCHDOG is not set ++# CONFIG_ARM_SP805_WATCHDOG is not set ++# CONFIG_CADENCE_WATCHDOG is not set ++CONFIG_DW_WATCHDOG=y ++# CONFIG_MAX63XX_WATCHDOG is not set ++# CONFIG_BCM7038_WDT is not set ++# CONFIG_MEN_A21_WDT is not set ++ ++# ++# USB-based Watchdog Cards ++# ++# CONFIG_USBPCWATCHDOG is not set ++CONFIG_SSB_POSSIBLE=y ++ ++# ++# Sonics Silicon Backplane ++# ++# CONFIG_SSB is not set ++CONFIG_BCMA_POSSIBLE=y ++ ++# ++# Broadcom specific AMBA ++# ++# CONFIG_BCMA is not set ++ ++# ++# Multifunction device drivers ++# ++CONFIG_MFD_CORE=y ++# CONFIG_MFD_AS3711 is not set ++# CONFIG_MFD_AS3722 is not set ++# CONFIG_PMIC_ADP5520 is not set ++# CONFIG_MFD_AAT2870_CORE is not set ++# CONFIG_MFD_ATMEL_FLEXCOM is not set ++# CONFIG_MFD_ATMEL_HLCDC is not set ++# CONFIG_MFD_BCM590XX is not set ++# CONFIG_MFD_AXP20X is not set ++# CONFIG_MFD_CROS_EC is not set ++# CONFIG_PMIC_DA903X is not set ++# CONFIG_MFD_DA9052_SPI is not set ++# CONFIG_MFD_DA9052_I2C is not set ++# CONFIG_MFD_DA9055 is not set ++# CONFIG_MFD_DA9062 is not set ++# CONFIG_MFD_DA9063 is not set ++# CONFIG_MFD_DA9150 is not set ++# CONFIG_MFD_DLN2 is not set ++# CONFIG_MFD_MC13XXX_SPI is not set ++# CONFIG_MFD_MC13XXX_I2C is not set ++# CONFIG_MFD_HI6421_PMIC is not set ++# CONFIG_HTC_PASIC3 is not set ++# CONFIG_HTC_I2CPLD is not set ++# CONFIG_INTEL_SOC_PMIC is not set ++# CONFIG_MFD_KEMPLD is not set ++# CONFIG_MFD_88PM800 is not set ++# CONFIG_MFD_88PM805 is not set ++# CONFIG_MFD_88PM860X is not set ++# CONFIG_MFD_MAX14577 is not set ++# CONFIG_MFD_MAX77686 is not set ++# CONFIG_MFD_MAX77693 is not set ++# CONFIG_MFD_MAX77843 is not set ++# CONFIG_MFD_MAX8907 is not set ++# CONFIG_MFD_MAX8925 is not set ++# CONFIG_MFD_MAX8997 is not set ++# CONFIG_MFD_MAX8998 is not set ++# CONFIG_MFD_MT6397 is not set ++# CONFIG_MFD_MENF21BMC is not set ++# CONFIG_EZX_PCAP is not set ++# CONFIG_MFD_VIPERBOARD is not set ++# CONFIG_MFD_RETU is not set ++# CONFIG_MFD_PCF50633 is not set ++# CONFIG_MFD_RT5033 is not set ++# CONFIG_MFD_RTSX_USB is not set ++# CONFIG_MFD_RC5T583 is not set ++# CONFIG_MFD_RK618 is not set ++CONFIG_MFD_RK808=y ++# CONFIG_MFD_RN5T618 is not set ++# CONFIG_MFD_SEC_CORE is not set ++# CONFIG_MFD_SI476X_CORE is not set ++# CONFIG_MFD_SM501 is not set ++# CONFIG_MFD_SKY81452 is not set ++# CONFIG_MFD_SMSC is not set ++# CONFIG_ABX500_CORE is not set ++# CONFIG_MFD_STMPE is not set ++CONFIG_MFD_SYSCON=y ++# CONFIG_MFD_TI_AM335X_TSCADC is not set ++# CONFIG_MFD_LP3943 is not set ++# CONFIG_MFD_LP8788 is not set ++# CONFIG_MFD_PALMAS is not set ++# CONFIG_TPS6105X is not set ++# CONFIG_TPS65010 is not set ++# CONFIG_TPS6507X is not set ++# CONFIG_MFD_TPS65090 is not set ++# CONFIG_MFD_TPS65217 is not set ++# CONFIG_MFD_TPS65218 is not set ++# CONFIG_MFD_TPS6586X is not set ++# CONFIG_MFD_TPS65910 is not set ++# CONFIG_MFD_TPS65912 is not set ++# CONFIG_MFD_TPS65912_I2C is not set ++# CONFIG_MFD_TPS65912_SPI is not set ++# CONFIG_MFD_TPS80031 is not set ++# CONFIG_TWL4030_CORE is not set ++# CONFIG_TWL6040_CORE is not set ++# CONFIG_MFD_WL1273_CORE is not set ++# CONFIG_MFD_LM3533 is not set ++# CONFIG_MFD_TC3589X is not set ++# CONFIG_MFD_TMIO is not set ++# CONFIG_MFD_ARIZONA_I2C is not set ++# CONFIG_MFD_ARIZONA_SPI is not set ++# CONFIG_MFD_WM8400 is not set ++# CONFIG_MFD_WM831X_I2C is not set ++# CONFIG_MFD_WM831X_SPI is not set ++# CONFIG_MFD_RK1000 is not set ++# CONFIG_MFD_WM8350_I2C is not set ++# CONFIG_MFD_WM8994 is not set ++CONFIG_FUSB_30X=y ++CONFIG_REGULATOR=y ++CONFIG_REGULATOR_DEBUG=y ++CONFIG_REGULATOR_FIXED_VOLTAGE=y ++# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set ++# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set ++# CONFIG_REGULATOR_ACT8865 is not set ++# CONFIG_REGULATOR_AD5398 is not set ++# CONFIG_REGULATOR_ANATOP is not set ++# CONFIG_REGULATOR_DA9210 is not set ++# CONFIG_REGULATOR_DA9211 is not set ++CONFIG_REGULATOR_FAN53555=y ++CONFIG_REGULATOR_GPIO=y ++# CONFIG_REGULATOR_ISL9305 is not set ++# CONFIG_REGULATOR_ISL6271A is not set ++# CONFIG_REGULATOR_LP3971 is not set ++# CONFIG_REGULATOR_LP3972 is not set ++# CONFIG_REGULATOR_LP872X is not set ++# CONFIG_REGULATOR_LP8752 is not set ++# CONFIG_REGULATOR_LP8755 is not set ++# CONFIG_REGULATOR_LTC3589 is not set ++# CONFIG_REGULATOR_MAX1586 is not set ++# CONFIG_REGULATOR_MAX8649 is not set ++# CONFIG_REGULATOR_MAX8660 is not set ++# CONFIG_REGULATOR_MAX8952 is not set ++# CONFIG_REGULATOR_MAX8973 is not set ++# CONFIG_REGULATOR_MP8865 is not set ++# CONFIG_REGULATOR_MT6311 is not set ++# CONFIG_REGULATOR_PFUZE100 is not set ++CONFIG_REGULATOR_PWM=y ++CONFIG_REGULATOR_RK808=y ++CONFIG_REGULATOR_RK818=y ++# CONFIG_REGULATOR_SYR82X is not set ++# CONFIG_REGULATOR_TPS51632 is not set ++# CONFIG_REGULATOR_TPS549B22 is not set ++# CONFIG_REGULATOR_TPS62360 is not set ++# CONFIG_REGULATOR_TPS65023 is not set ++# CONFIG_REGULATOR_TPS6507X is not set ++# CONFIG_REGULATOR_TPS65132 is not set ++# CONFIG_REGULATOR_TPS6524X is not set ++# CONFIG_REGULATOR_XZ3216 is not set ++CONFIG_MEDIA_SUPPORT=y ++ ++# ++# Multimedia core support ++# ++CONFIG_MEDIA_CAMERA_SUPPORT=y ++# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set ++# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set ++# CONFIG_MEDIA_RADIO_SUPPORT is not set ++# CONFIG_MEDIA_SDR_SUPPORT is not set ++CONFIG_MEDIA_RC_SUPPORT=y ++# CONFIG_MEDIA_CEC_SUPPORT is not set ++CONFIG_MEDIA_CONTROLLER=y ++CONFIG_VIDEO_DEV=y ++CONFIG_VIDEO_V4L2_SUBDEV_API=y ++CONFIG_VIDEO_V4L2=y ++# CONFIG_VIDEO_ADV_DEBUG is not set ++# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set ++CONFIG_V4L2_MEM2MEM_DEV=y ++CONFIG_V4L2_FWNODE=y ++CONFIG_VIDEOBUF_GEN=y ++CONFIG_VIDEOBUF2_CORE=y ++CONFIG_VIDEOBUF2_MEMOPS=y ++CONFIG_VIDEOBUF2_DMA_CONTIG=y ++CONFIG_VIDEOBUF2_VMALLOC=y ++CONFIG_VIDEOBUF2_DMA_SG=y ++# CONFIG_TTPCI_EEPROM is not set ++ ++# ++# Media drivers ++# ++CONFIG_RC_CORE=y ++CONFIG_RC_MAP=y ++# CONFIG_LIRC is not set ++CONFIG_RC_DECODERS=y ++CONFIG_IR_NEC_DECODER=y ++# CONFIG_IR_RC5_DECODER is not set ++# CONFIG_IR_RC6_DECODER is not set ++# CONFIG_IR_JVC_DECODER is not set ++# CONFIG_IR_SONY_DECODER is not set ++# CONFIG_IR_SANYO_DECODER is not set ++# CONFIG_IR_SHARP_DECODER is not set ++# CONFIG_IR_MCE_KBD_DECODER is not set ++# CONFIG_IR_XMP_DECODER is not set ++# CONFIG_IR_IMON_DECODER is not set ++# CONFIG_RC_DEVICES is not set ++CONFIG_MEDIA_USB_SUPPORT=y ++ ++# ++# Webcam devices ++# ++CONFIG_USB_VIDEO_CLASS=y ++# CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV is not set ++# CONFIG_USB_GSPCA is not set ++# CONFIG_USB_PWC is not set ++# CONFIG_VIDEO_CPIA2 is not set ++# CONFIG_USB_ZR364XX is not set ++# CONFIG_USB_STKWEBCAM is not set ++# CONFIG_USB_S2255 is not set ++# CONFIG_VIDEO_USBTV is not set ++# CONFIG_NPU_USB_ACM is not set ++ ++# ++# Webcam, TV (analog/digital) USB devices ++# ++# CONFIG_VIDEO_EM28XX is not set ++CONFIG_V4L_PLATFORM_DRIVERS=y ++CONFIG_SOC_CAMERA=y ++# CONFIG_SOC_CAMERA_PLATFORM is not set ++# CONFIG_VIDEO_XILINX is not set ++# CONFIG_VIDEO_RK_CIF_ISP10 is not set ++# CONFIG_VIDEO_ROCKCHIP_CIF is not set ++CONFIG_VIDEO_ROCKCHIP_ISP1=y ++CONFIG_V4L_MEM2MEM_DRIVERS=y ++# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set ++# CONFIG_VIDEO_SH_VEU is not set ++CONFIG_VIDEO_ROCKCHIP_RGA=y ++# CONFIG_VIDEO_ROCKCHIP_VPU is not set ++# CONFIG_V4L_TEST_DRIVERS is not set ++# CONFIG_ROCKCHIP_TSP is not set ++ ++# ++# Supported MMC/SDIO adapters ++# ++# CONFIG_CYPRESS_FIRMWARE is not set ++ ++# ++# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) ++# ++# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set ++# CONFIG_VIDEO_IR_I2C is not set ++ ++# ++# I2C Encoders, decoders, sensors and other helper chips ++# ++ ++# ++# Audio decoders, processors and mixers ++# ++# CONFIG_VIDEO_TVAUDIO is not set ++# CONFIG_VIDEO_TDA7432 is not set ++# CONFIG_VIDEO_TDA9840 is not set ++# CONFIG_VIDEO_TEA6415C is not set ++# CONFIG_VIDEO_TEA6420 is not set ++# CONFIG_VIDEO_MSP3400 is not set ++# CONFIG_VIDEO_CS5345 is not set ++# CONFIG_VIDEO_CS53L32A is not set ++# CONFIG_VIDEO_TLV320AIC23B is not set ++# CONFIG_VIDEO_UDA1342 is not set ++# CONFIG_VIDEO_WM8775 is not set ++# CONFIG_VIDEO_WM8739 is not set ++# CONFIG_VIDEO_VP27SMPX is not set ++# CONFIG_VIDEO_SONY_BTF_MPX is not set ++ ++# ++# RDS decoders ++# ++# CONFIG_VIDEO_SAA6588 is not set ++ ++# ++# Video decoders ++# ++# CONFIG_VIDEO_ADV7180 is not set ++# CONFIG_VIDEO_ADV7181D is not set ++# CONFIG_VIDEO_ADV7183 is not set ++# CONFIG_VIDEO_ADV7604 is not set ++# CONFIG_VIDEO_ADV7842 is not set ++# CONFIG_VIDEO_BT819 is not set ++# CONFIG_VIDEO_BT856 is not set ++# CONFIG_VIDEO_BT866 is not set ++# CONFIG_VIDEO_KS0127 is not set ++# CONFIG_VIDEO_ML86V7667 is not set ++# CONFIG_VIDEO_SAA7110 is not set ++# CONFIG_VIDEO_SAA711X is not set ++# CONFIG_VIDEO_TC35874X is not set ++# CONFIG_VIDEO_TVP514X is not set ++# CONFIG_VIDEO_TVP5150 is not set ++# CONFIG_VIDEO_TVP7002 is not set ++# CONFIG_VIDEO_TW2804 is not set ++# CONFIG_VIDEO_TW9903 is not set ++# CONFIG_VIDEO_TW9906 is not set ++# CONFIG_VIDEO_VPX3220 is not set ++ ++# ++# Video and audio decoders ++# ++# CONFIG_VIDEO_SAA717X is not set ++# CONFIG_VIDEO_CX25840 is not set ++ ++# ++# Video encoders ++# ++# CONFIG_VIDEO_SAA7127 is not set ++# CONFIG_VIDEO_SAA7185 is not set ++# CONFIG_VIDEO_ADV7170 is not set ++# CONFIG_VIDEO_ADV7175 is not set ++# CONFIG_VIDEO_ADV7343 is not set ++# CONFIG_VIDEO_ADV7393 is not set ++# CONFIG_VIDEO_ADV7511 is not set ++# CONFIG_VIDEO_AD9389B is not set ++# CONFIG_VIDEO_AK881X is not set ++# CONFIG_VIDEO_THS8200 is not set ++ ++# ++# Camera sensor devices ++# ++# CONFIG_VIDEO_IMX219 is not set ++# CONFIG_VIDEO_IMX258 is not set ++# CONFIG_VIDEO_IMX317 is not set ++# CONFIG_VIDEO_IMX323 is not set ++# CONFIG_VIDEO_IMX327 is not set ++# CONFIG_VIDEO_VIRT_CAMERA is not set ++# CONFIG_VIDEO_OV2659 is not set ++# CONFIG_VIDEO_OV2680 is not set ++# CONFIG_VIDEO_OV2685 is not set ++# CONFIG_VIDEO_OV2718 is not set ++# CONFIG_VIDEO_OV2735 is not set ++# CONFIG_VIDEO_OV4689 is not set ++# CONFIG_VIDEO_OV5647 is not set ++# CONFIG_VIDEO_OV5648 is not set ++CONFIG_VIDEO_OV5695=y ++# CONFIG_VIDEO_OV7251 is not set ++# CONFIG_VIDEO_OV7640 is not set ++# CONFIG_VIDEO_OV7670 is not set ++# CONFIG_VIDEO_OV7725 is not set ++# CONFIG_VIDEO_OV7750 is not set ++# CONFIG_VIDEO_OV8858 is not set ++# CONFIG_VIDEO_OV9281 is not set ++# CONFIG_VIDEO_OV9650 is not set ++# CONFIG_VIDEO_OV13850 is not set ++# CONFIG_VIDEO_VS6624 is not set ++# CONFIG_VIDEO_MT9M032 is not set ++# CONFIG_VIDEO_MT9P031 is not set ++# CONFIG_VIDEO_MT9T001 is not set ++# CONFIG_VIDEO_MT9V011 is not set ++# CONFIG_VIDEO_MT9V032 is not set ++# CONFIG_VIDEO_AR0230 is not set ++# CONFIG_VIDEO_SR030PC30 is not set ++# CONFIG_VIDEO_NOON010PC30 is not set ++# CONFIG_VIDEO_M5MOLS is not set ++# CONFIG_VIDEO_S5K6AA is not set ++# CONFIG_VIDEO_S5K6A3 is not set ++# CONFIG_VIDEO_S5K4ECGX is not set ++# CONFIG_VIDEO_S5K5BAF is not set ++# CONFIG_VIDEO_SMIAPP is not set ++# CONFIG_VIDEO_S5C73M3 is not set ++# CONFIG_VIDEO_GC2155 is not set ++# CONFIG_VIDEO_GC0312 is not set ++# CONFIG_VIDEO_GC2145 is not set ++CONFIG_VIDEO_GC2355=y ++# CONFIG_VIDEO_GC2385 is not set ++# CONFIG_VIDEO_GC5025 is not set ++# CONFIG_VIDEO_GC8034 is not set ++CONFIG_VIDEO_SC031GS=y ++# CONFIG_VIDEO_SC132GS is not set ++# CONFIG_VIDEO_GC0329 is not set ++# CONFIG_VIDEO_GC2035 is not set ++# CONFIG_VIDEO_BF3925 is not set ++# CONFIG_VIDEO_JX_H65 is not set ++CONFIG_VIDEO_PREISP_DUMMY_SENSOR=y ++ ++# ++# Flash devices ++# ++# CONFIG_VIDEO_ADP1653 is not set ++# CONFIG_VIDEO_AS3645A is not set ++# CONFIG_VIDEO_LM3560 is not set ++# CONFIG_VIDEO_LM3646 is not set ++# CONFIG_VIDEO_SGM3784 is not set ++ ++# ++# Video improvement chips ++# ++# CONFIG_VIDEO_UPD64031A is not set ++# CONFIG_VIDEO_UPD64083 is not set ++ ++# ++# Camera lens devices ++# ++# CONFIG_VIDEO_VM149C is not set ++# CONFIG_VIDEO_DW9714 is not set ++# CONFIG_VIDEO_FP5510 is not set ++ ++# ++# Audio/Video compression chips ++# ++# CONFIG_VIDEO_SAA6752HS is not set ++ ++# ++# Miscellaneous helper chips ++# ++# CONFIG_VIDEO_THS7303 is not set ++# CONFIG_VIDEO_M52790 is not set ++# CONFIG_VIDEO_NVP6324 is not set ++ ++# ++# Sensors used on soc_camera driver ++# ++ ++# ++# soc_camera sensor drivers ++# ++# CONFIG_SOC_CAMERA_IMX074 is not set ++# CONFIG_SOC_CAMERA_MT9M001 is not set ++# CONFIG_SOC_CAMERA_MT9M111 is not set ++# CONFIG_SOC_CAMERA_MT9T031 is not set ++# CONFIG_SOC_CAMERA_MT9T112 is not set ++# CONFIG_SOC_CAMERA_MT9V022 is not set ++# CONFIG_SOC_CAMERA_OV2640 is not set ++# CONFIG_SOC_CAMERA_OV5642 is not set ++# CONFIG_SOC_CAMERA_OV6650 is not set ++# CONFIG_SOC_CAMERA_OV772X is not set ++# CONFIG_SOC_CAMERA_OV9640 is not set ++# CONFIG_SOC_CAMERA_OV9740 is not set ++# CONFIG_SOC_CAMERA_RJ54N1 is not set ++# CONFIG_SOC_CAMERA_TW9910 is not set ++ ++# ++# SPI helper chips ++# ++# CONFIG_VIDEO_GS1662 is not set ++CONFIG_VIDEO_ROCKCHIP_PREISP=y ++ ++# ++# Customise DVB Frontends ++# ++# CONFIG_DVB_AU8522_V4L is not set ++# CONFIG_DVB_TUNER_DIB0070 is not set ++# CONFIG_DVB_TUNER_DIB0090 is not set ++ ++# ++# Tools to develop new frontends ++# ++# CONFIG_DVB_DUMMY_FE is not set ++# CONFIG_CAMSYS_DRV is not set ++# CONFIG_ROCK_CHIP_SOC_CAMERA is not set ++ ++# ++# Graphics support ++# ++CONFIG_DRM=y ++CONFIG_DRM_IGNORE_IOTCL_PERMIT=y ++CONFIG_DRM_MIPI_DSI=y ++CONFIG_DRM_KMS_HELPER=y ++CONFIG_DRM_KMS_FB_HELPER=y ++CONFIG_DRM_FBDEV_EMULATION=y ++CONFIG_DRM_LOAD_EDID_FIRMWARE=y ++# CONFIG_DRM_DP_CEC is not set ++# CONFIG_DRM_SCDC_HELPER is not set ++CONFIG_DRM_DMA_SYNC=y ++ ++# ++# I2C encoder or helper chips ++# ++# CONFIG_DRM_I2C_ADV7511 is not set ++# CONFIG_DRM_I2C_CH7006 is not set ++# CONFIG_DRM_I2C_SIL164 is not set ++# CONFIG_DRM_I2C_NXP_TDA998X is not set ++# CONFIG_DRM_VGEM is not set ++CONFIG_DRM_ROCKCHIP=y ++# CONFIG_ROCKCHIP_DRM_DEBUG is not set ++# CONFIG_ROCKCHIP_DW_HDMI is not set ++CONFIG_ROCKCHIP_DW_MIPI_DSI=y ++# CONFIG_ROCKCHIP_MIPI_CSI_TX is not set ++CONFIG_ROCKCHIP_ANALOGIX_DP=y ++# CONFIG_ROCKCHIP_INNO_HDMI is not set ++CONFIG_ROCKCHIP_LVDS=y ++CONFIG_ROCKCHIP_DRM_TVE=y ++# CONFIG_ROCKCHIP_RGB is not set ++# CONFIG_ROCKCHIP_DRM_BACKLIGHT is not set ++# CONFIG_ROCKCHIP_RK3066_HDMI is not set ++# CONFIG_DRM_UDL is not set ++CONFIG_DRM_PANEL=y ++ ++# ++# Display Panels ++# ++CONFIG_DRM_PANEL_SIMPLE=y ++# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set ++# CONFIG_DRM_PANEL_LG_LG4573 is not set ++# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set ++# CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set ++CONFIG_DRM_BRIDGE=y ++ ++# ++# Display Interface Bridges ++# ++# CONFIG_DRM_NXP_PTN3460 is not set ++# CONFIG_DRM_PARADE_PS8622 is not set ++# CONFIG_DRM_RK1000 is not set ++# CONFIG_DRM_DUMB_VGA_DAC is not set ++# CONFIG_DRM_LONTIUM_LT8912 is not set ++CONFIG_DRM_LONTIUM_LT9611_I2C=y ++# CONFIG_DRM_CHIPONE_ICN6211 is not set ++CONFIG_DRM_ANALOGIX_DP=y ++# CONFIG_DRM_ANALOGIX_ANX78XX is not set ++# CONFIG_DRM_ANALOGIX_ANX6345 is not set ++# CONFIG_POWERVR_ROGUE_M is not set ++# CONFIG_MALI400 is not set ++CONFIG_MALI_MIDGARD_FOR_ANDROID=y ++# CONFIG_MALI_MIDGARD_FOR_LINUX is not set ++# CONFIG_MALI_MIDGARD is not set ++# CONFIG_MALI_CORESTACK is not set ++CONFIG_MALI_PWRSOFT_765=y ++# CONFIG_MALI_KUTF is not set ++# CONFIG_MALI_BIFROST_FOR_ANDROID is not set ++CONFIG_MALI_BIFROST_FOR_LINUX=y ++CONFIG_MALI_BIFROST=y ++# CONFIG_MALI_BIFROST_GATOR_SUPPORT is not set ++# CONFIG_MALI_BIFROST_ENABLE_TRACE is not set ++CONFIG_MALI_BIFROST_DEVFREQ=y ++# CONFIG_MALI_BIFROST_DMA_FENCE is not set ++CONFIG_MALI_PLATFORM_NAME="rk" ++CONFIG_MALI_BIFROST_EXPERT=y ++# CONFIG_MALI_BIFROST_PRFCNT_SET_SECONDARY is not set ++CONFIG_MALI_BIFROST_DEBUG=y ++# CONFIG_MALI_BIFROST_NO_MALI is not set ++# CONFIG_MALI_BIFROST_TRACE_TIMELINE is not set ++# CONFIG_MALI_BIFROST_SYSTEM_TRACE is not set ++# CONFIG_MALI_JOB_DUMP is not set ++# CONFIG_MALI_2MB_ALLOC is not set ++ ++# ++# Frame buffer Devices ++# ++CONFIG_FB=y ++# CONFIG_FIRMWARE_EDID is not set ++CONFIG_FB_CMDLINE=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=y ++CONFIG_FB_SYS_COPYAREA=y ++CONFIG_FB_SYS_IMAGEBLIT=y ++# CONFIG_FB_FOREIGN_ENDIAN is not set ++CONFIG_FB_SYS_FOPS=y ++# CONFIG_FB_SVGALIB is not set ++# CONFIG_FB_MACMODES is not set ++# CONFIG_FB_BACKLIGHT is not set ++# CONFIG_FB_MODE_HELPERS is not set ++# CONFIG_FB_TILEBLITTING is not set ++ ++# ++# Frame buffer hardware drivers ++# ++# CONFIG_FB_ARMCLCD is not set ++# CONFIG_FB_UVESA is not set ++# CONFIG_FB_OPENCORES is not set ++# CONFIG_FB_S1D13XXX is not set ++# CONFIG_FB_SMSCUFX is not set ++# CONFIG_FB_UDL is not set ++# CONFIG_FB_IBM_GXT4500 is not set ++# CONFIG_FB_VIRTUAL is not set ++# CONFIG_FB_METRONOME is not set ++# CONFIG_FB_BROADSHEET is not set ++# CONFIG_FB_AUO_K190X is not set ++# CONFIG_FB_SIMPLE is not set ++# CONFIG_FB_SSD1307 is not set ++CONFIG_BACKLIGHT_LCD_SUPPORT=y ++# CONFIG_LCD_CLASS_DEVICE is not set ++CONFIG_BACKLIGHT_CLASS_DEVICE=y ++CONFIG_BACKLIGHT_GENERIC=y ++CONFIG_BACKLIGHT_PWM=y ++# CONFIG_BACKLIGHT_PM8941_WLED is not set ++# CONFIG_BACKLIGHT_ADP8860 is not set ++# CONFIG_BACKLIGHT_ADP8870 is not set ++# CONFIG_BACKLIGHT_LM3630A is not set ++# CONFIG_BACKLIGHT_LM3639 is not set ++# CONFIG_BACKLIGHT_LP855X is not set ++# CONFIG_BACKLIGHT_GPIO is not set ++# CONFIG_BACKLIGHT_LV5207LP is not set ++# CONFIG_BACKLIGHT_BD6107 is not set ++ ++# ++# Rockchip Misc Video driver ++# ++# CONFIG_FB_ROCKCHIP is not set ++# CONFIG_LCDC_RK3368 is not set ++CONFIG_LCD_GENERAL=y ++# CONFIG_LCD_MIPI is not set ++# CONFIG_RK_TRSM is not set ++# CONFIG_RK_HDMI is not set ++ ++# ++# RGA ++# ++# CONFIG_ROCKCHIP_RGA is not set ++ ++# ++# RGA2 ++# ++# CONFIG_ROCKCHIP_RGA2 is not set ++ ++# ++# VCODEC ++# ++CONFIG_RK_VCODEC=y ++ ++# ++# IEP ++# ++# CONFIG_IEP is not set ++# CONFIG_IEP_MMU is not set ++ ++# ++# DP ++# ++ ++# ++# ROCKCHIP_MPP ++# ++CONFIG_ROCKCHIP_MPP_SERVICE=y ++CONFIG_ROCKCHIP_MPP_DEVICE=y ++# CONFIG_VGASTATE is not set ++CONFIG_VIDEOMODE_HELPERS=y ++CONFIG_HDMI=y ++ ++# ++# Console display driver support ++# ++CONFIG_DUMMY_CONSOLE=y ++CONFIG_DUMMY_CONSOLE_COLUMNS=80 ++CONFIG_DUMMY_CONSOLE_ROWS=25 ++# CONFIG_FRAMEBUFFER_CONSOLE is not set ++# CONFIG_LOGO is not set ++CONFIG_SOUND=y ++# CONFIG_SOUND_OSS_CORE is not set ++CONFIG_SND=y ++CONFIG_SND_TIMER=y ++CONFIG_SND_PCM=y ++CONFIG_SND_DMAENGINE_PCM=y ++CONFIG_SND_HWDEP=y ++CONFIG_SND_RAWMIDI=y ++CONFIG_SND_JACK=y ++CONFIG_SND_SEQUENCER=y ++CONFIG_SND_SEQ_DUMMY=y ++# CONFIG_SND_MIXER_OSS is not set ++# CONFIG_SND_PCM_OSS is not set ++CONFIG_SND_PCM_TIMER=y ++# CONFIG_SND_SEQUENCER_OSS is not set ++CONFIG_SND_HRTIMER=y ++CONFIG_SND_SEQ_HRTIMER_DEFAULT=y ++CONFIG_SND_DYNAMIC_MINORS=y ++CONFIG_SND_MAX_CARDS=32 ++# CONFIG_SND_SUPPORT_OLD_API is not set ++CONFIG_SND_PROC_FS=y ++CONFIG_SND_VERBOSE_PROCFS=y ++# CONFIG_SND_VERBOSE_PRINTK is not set ++# CONFIG_SND_DEBUG is not set ++CONFIG_SND_RAWMIDI_SEQ=y ++# CONFIG_SND_OPL3_LIB_SEQ is not set ++# CONFIG_SND_OPL4_LIB_SEQ is not set ++# CONFIG_SND_SBAWE_SEQ is not set ++# CONFIG_SND_EMU10K1_SEQ is not set ++CONFIG_SND_DRIVERS=y ++# CONFIG_SND_DUMMY is not set ++# CONFIG_SND_ALOOP is not set ++# CONFIG_SND_VIRMIDI is not set ++# CONFIG_SND_MTPAV is not set ++# CONFIG_SND_SERIAL_U16550 is not set ++# CONFIG_SND_MPU401 is not set ++ ++# ++# HD-Audio ++# ++CONFIG_SND_HDA_PREALLOC_SIZE=64 ++# CONFIG_SND_SPI is not set ++CONFIG_SND_USB=y ++CONFIG_SND_USB_AUDIO=y ++# CONFIG_SND_USB_UA101 is not set ++# CONFIG_SND_USB_CAIAQ is not set ++# CONFIG_SND_USB_6FIRE is not set ++# CONFIG_SND_USB_HIFACE is not set ++# CONFIG_SND_BCD2000 is not set ++# CONFIG_SND_USB_POD is not set ++# CONFIG_SND_USB_PODHD is not set ++# CONFIG_SND_USB_TONEPORT is not set ++# CONFIG_SND_USB_VARIAX is not set ++CONFIG_SND_SOC=y ++CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y ++# CONFIG_SND_ATMEL_SOC is not set ++# CONFIG_SND_DESIGNWARE_I2S is not set ++ ++# ++# SoC Audio for Freescale CPUs ++# ++ ++# ++# Common SoC Audio options for Freescale CPUs: ++# ++# CONFIG_SND_SOC_FSL_ASRC is not set ++# CONFIG_SND_SOC_FSL_SAI is not set ++# CONFIG_SND_SOC_FSL_SSI is not set ++# CONFIG_SND_SOC_FSL_SPDIF is not set ++# CONFIG_SND_SOC_FSL_ESAI is not set ++# CONFIG_SND_SOC_IMX_AUDMUX is not set ++CONFIG_SND_SOC_ROCKCHIP=y ++# CONFIG_SND_SOC_ROCKCHIP_FORCE_SRAM is not set ++CONFIG_SND_SOC_ROCKCHIP_I2S=y ++# CONFIG_SND_SOC_ROCKCHIP_I2S_TDM is not set ++# CONFIG_SND_SOC_ROCKCHIP_MULTI_DAIS is not set ++# CONFIG_SND_SOC_ROCKCHIP_PDM is not set ++# CONFIG_SND_SOC_ROCKCHIP_SPDIF is not set ++# CONFIG_SND_SOC_ROCKCHIP_SPDIFRX is not set ++# CONFIG_SND_SOC_ROCKCHIP_VAD is not set ++# CONFIG_SND_SOC_ROCKCHIP_DA7219 is not set ++# CONFIG_SND_SOC_ROCKCHIP_HDMI_ANALOG is not set ++# CONFIG_SND_SOC_ROCKCHIP_MAX98090 is not set ++# CONFIG_SND_SOC_ROCKCHIP_MULTICODECS is not set ++# CONFIG_SND_SOC_ROCKCHIP_RT5645 is not set ++# CONFIG_SND_SOC_ROCKCHIP_RT5651_TC358749 is not set ++# CONFIG_SND_SOC_ROCKCHIP_CDNDP is not set ++ ++# ++# Allwinner SoC Audio support ++# ++# CONFIG_SND_SUN4I_CODEC is not set ++# CONFIG_SND_SOC_XTFPGA_I2S is not set ++CONFIG_SND_SOC_I2C_AND_SPI=y ++ ++# ++# CODEC drivers ++# ++# CONFIG_SND_SOC_AC97_CODEC is not set ++# CONFIG_SND_SOC_ADAU1701 is not set ++# CONFIG_SND_SOC_AK4104 is not set ++# CONFIG_SND_SOC_AK4554 is not set ++# CONFIG_SND_SOC_AK4613 is not set ++# CONFIG_SND_SOC_AK4642 is not set ++# CONFIG_SND_SOC_AK5386 is not set ++# CONFIG_SND_SOC_ALC5623 is not set ++# CONFIG_SND_SOC_CS35L32 is not set ++# CONFIG_SND_SOC_CS42L51_I2C is not set ++# CONFIG_SND_SOC_CS42L52 is not set ++# CONFIG_SND_SOC_CS42L56 is not set ++# CONFIG_SND_SOC_CS42L73 is not set ++# CONFIG_SND_SOC_CS4265 is not set ++# CONFIG_SND_SOC_CS4270 is not set ++# CONFIG_SND_SOC_CS4271_I2C is not set ++# CONFIG_SND_SOC_CS4271_SPI is not set ++# CONFIG_SND_SOC_CS42XX8_I2C is not set ++# CONFIG_SND_SOC_CS4349 is not set ++# CONFIG_SND_SOC_CX2072X is not set ++# CONFIG_SND_SOC_CX20810 is not set ++# CONFIG_SND_SOC_DUMMY_CODEC is not set ++# CONFIG_SND_SOC_BT_SCO is not set ++# CONFIG_SND_SOC_ES8316 is not set ++# CONFIG_SND_SOC_ES8323 is not set ++# CONFIG_SND_SOC_ES8328 is not set ++# CONFIG_SND_SOC_ES8328_I2C is not set ++# CONFIG_SND_SOC_ES8396 is not set ++# CONFIG_SND_SOC_GTM601 is not set ++# CONFIG_SND_SOC_GVA_CODEC is not set ++# CONFIG_SND_SOC_FM1288 is not set ++# CONFIG_SND_SOC_PCM1681 is not set ++# CONFIG_SND_SOC_PCM1792A is not set ++# CONFIG_SND_SOC_PCM512x_I2C is not set ++# CONFIG_SND_SOC_PCM512x_SPI is not set ++# CONFIG_SND_SOC_RK312X is not set ++# CONFIG_SND_SOC_RK3228 is not set ++# CONFIG_SND_SOC_RK3308 is not set ++# CONFIG_SND_SOC_RK3328 is not set ++CONFIG_SND_SOC_RK817=y ++CONFIG_SND_SOC_RL6231=y ++# CONFIG_SND_SOC_RT5616 is not set ++# CONFIG_SND_SOC_RT5631 is not set ++CONFIG_SND_SOC_RT5640=y ++# CONFIG_SND_SOC_RT5651 is not set ++# CONFIG_SND_SOC_RT5677_SPI is not set ++# CONFIG_SND_SOC_SGTL5000 is not set ++# CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set ++# CONFIG_SND_SOC_SPDIF is not set ++# CONFIG_SND_SOC_SSM2602_SPI is not set ++# CONFIG_SND_SOC_SSM2602_I2C is not set ++# CONFIG_SND_SOC_SSM4567 is not set ++# CONFIG_SND_SOC_STA32X is not set ++# CONFIG_SND_SOC_STA350 is not set ++# CONFIG_SND_SOC_STI_SAS is not set ++# CONFIG_SND_SOC_TAS2552 is not set ++# CONFIG_SND_SOC_TAS5086 is not set ++# CONFIG_SND_SOC_TAS571X is not set ++# CONFIG_SND_SOC_TC358749X is not set ++# CONFIG_SND_SOC_TFA9879 is not set ++# CONFIG_SND_SOC_TLV320AIC23_I2C is not set ++# CONFIG_SND_SOC_TLV320AIC23_SPI is not set ++# CONFIG_SND_SOC_TLV320AIC31XX is not set ++# CONFIG_SND_SOC_TLV320AIC3X is not set ++# CONFIG_SND_SOC_TS3A227E is not set ++# CONFIG_SND_SOC_WM8510 is not set ++# CONFIG_SND_SOC_WM8523 is not set ++# CONFIG_SND_SOC_WM8580 is not set ++# CONFIG_SND_SOC_WM8711 is not set ++# CONFIG_SND_SOC_WM8728 is not set ++# CONFIG_SND_SOC_WM8731 is not set ++# CONFIG_SND_SOC_WM8737 is not set ++# CONFIG_SND_SOC_WM8741 is not set ++# CONFIG_SND_SOC_WM8750 is not set ++# CONFIG_SND_SOC_WM8753 is not set ++# CONFIG_SND_SOC_WM8770 is not set ++# CONFIG_SND_SOC_WM8776 is not set ++# CONFIG_SND_SOC_WM8804_I2C is not set ++# CONFIG_SND_SOC_WM8804_SPI is not set ++# CONFIG_SND_SOC_WM8903 is not set ++# CONFIG_SND_SOC_WM8962 is not set ++# CONFIG_SND_SOC_WM8978 is not set ++# CONFIG_SND_SOC_TPA6130A2 is not set ++CONFIG_SND_SIMPLE_CARD=y ++# CONFIG_SOUND_PRIME is not set ++ ++# ++# HID support ++# ++CONFIG_HID=y ++CONFIG_HID_BATTERY_STRENGTH=y ++CONFIG_HIDRAW=y ++CONFIG_UHID=y ++CONFIG_HID_GENERIC=y ++ ++# ++# Special HID drivers ++# ++# CONFIG_HID_A4TECH is not set ++# CONFIG_HID_ACRUX is not set ++# CONFIG_HID_APPLE is not set ++# CONFIG_HID_APPLEIR is not set ++# CONFIG_HID_AUREAL is not set ++# CONFIG_HID_BELKIN is not set ++# CONFIG_HID_BETOP_FF is not set ++# CONFIG_HID_CHERRY is not set ++# CONFIG_HID_CHICONY is not set ++# CONFIG_HID_CORSAIR is not set ++# CONFIG_HID_PRODIKEYS is not set ++# CONFIG_HID_CP2112 is not set ++# CONFIG_HID_CYPRESS is not set ++# CONFIG_HID_DRAGONRISE is not set ++# CONFIG_HID_EMS_FF is not set ++# CONFIG_HID_ELECOM is not set ++# CONFIG_HID_ELO is not set ++# CONFIG_HID_EZKEY is not set ++# CONFIG_HID_GEMBIRD is not set ++# CONFIG_HID_GFRM is not set ++# CONFIG_HID_HOLTEK is not set ++# CONFIG_HID_GT683R is not set ++# CONFIG_HID_KEYTOUCH is not set ++# CONFIG_HID_KYE is not set ++# CONFIG_HID_UCLOGIC is not set ++# CONFIG_HID_WALTOP is not set ++# CONFIG_HID_GYRATION is not set ++# CONFIG_HID_ICADE is not set ++# CONFIG_HID_TWINHAN is not set ++CONFIG_HID_KENSINGTON=y ++# CONFIG_HID_LCPOWER is not set ++# CONFIG_HID_LENOVO is not set ++# CONFIG_HID_LOGITECH is not set ++# CONFIG_HID_MAGICMOUSE is not set ++# CONFIG_HID_MICROSOFT is not set ++# CONFIG_HID_MONTEREY is not set ++CONFIG_HID_MULTITOUCH=y ++# CONFIG_HID_NTRIG is not set ++# CONFIG_HID_ORTEK is not set ++# CONFIG_HID_PANTHERLORD is not set ++# CONFIG_HID_PENMOUNT is not set ++# CONFIG_HID_PETALYNX is not set ++# CONFIG_HID_PICOLCD is not set ++# CONFIG_HID_PLANTRONICS is not set ++# CONFIG_HID_PRIMAX is not set ++# CONFIG_HID_ROCCAT is not set ++# CONFIG_HID_SAITEK is not set ++# CONFIG_HID_SAMSUNG is not set ++# CONFIG_HID_SONY is not set ++# CONFIG_HID_SPEEDLINK is not set ++# CONFIG_HID_STEELSERIES is not set ++# CONFIG_HID_SUNPLUS is not set ++# CONFIG_HID_RMI is not set ++# CONFIG_HID_GREENASIA is not set ++# CONFIG_HID_SMARTJOYPLUS is not set ++# CONFIG_HID_TIVO is not set ++# CONFIG_HID_TOPSEED is not set ++# CONFIG_HID_THINGM is not set ++# CONFIG_HID_THRUSTMASTER is not set ++# CONFIG_HID_WACOM is not set ++# CONFIG_HID_WIIMOTE is not set ++# CONFIG_HID_XINMO is not set ++# CONFIG_HID_ZEROPLUS is not set ++# CONFIG_HID_ZYDACRON is not set ++# CONFIG_HID_SENSOR_HUB is not set ++# CONFIG_HID_RKVR is not set ++# CONFIG_HID_ALPS is not set ++ ++# ++# USB HID support ++# ++CONFIG_USB_HID=y ++# CONFIG_HID_PID is not set ++CONFIG_USB_HIDDEV=y ++ ++# ++# I2C HID support ++# ++CONFIG_I2C_HID=y ++CONFIG_USB_OHCI_LITTLE_ENDIAN=y ++CONFIG_USB_SUPPORT=y ++CONFIG_USB_COMMON=y ++CONFIG_USB_ARCH_HAS_HCD=y ++CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++ ++# ++# Miscellaneous USB options ++# ++# CONFIG_USB_DEFAULT_PERSIST is not set ++# CONFIG_USB_DYNAMIC_MINORS is not set ++CONFIG_USB_OTG=y ++# CONFIG_USB_OTG_WHITELIST is not set ++# CONFIG_USB_OTG_BLACKLIST_HUB is not set ++# CONFIG_USB_OTG_FSM is not set ++# CONFIG_USB_ULPI_BUS is not set ++CONFIG_USB_MON=y ++# CONFIG_USB_WUSB_CBAF is not set ++ ++# ++# USB Host Controller Drivers ++# ++# CONFIG_USB_C67X00_HCD is not set ++# CONFIG_USB_XHCI_HCD is not set ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_ROOT_HUB_TT=y ++CONFIG_USB_EHCI_TT_NEWSCHED=y ++CONFIG_USB_EHCI_HCD_PLATFORM=y ++# CONFIG_USB_OXU210HP_HCD is not set ++# CONFIG_USB_ISP116X_HCD is not set ++# CONFIG_USB_ISP1362_HCD is not set ++# CONFIG_USB_FOTG210_HCD is not set ++# CONFIG_USB_MAX3421_HCD is not set ++CONFIG_USB_OHCI_HCD=y ++CONFIG_USB_OHCI_HCD_PLATFORM=y ++# CONFIG_USB_SL811_HCD is not set ++# CONFIG_USB_R8A66597_HCD is not set ++# CONFIG_USB_HCD_TEST_MODE is not set ++ ++# ++# USB Device Class drivers ++# ++CONFIG_USB_ACM=y ++# CONFIG_USB_PRINTER is not set ++CONFIG_USB_WDM=y ++# 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 info ++# ++CONFIG_USB_STORAGE=y ++# CONFIG_USB_STORAGE_DEBUG is not set ++# CONFIG_USB_STORAGE_REALTEK 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_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_STORAGE_ENE_UB6250 is not set ++CONFIG_USB_UAS=y ++ ++# ++# USB Imaging devices ++# ++# CONFIG_USB_MDC800 is not set ++# CONFIG_USB_MICROTEK is not set ++# CONFIG_USBIP_CORE is not set ++# CONFIG_USB_MUSB_HDRC is not set ++# CONFIG_USB_DWC3 is not set ++CONFIG_USB_DWC2=y ++# CONFIG_USB_DWC2_HOST is not set ++ ++# ++# Gadget/Dual-role mode requires USB Gadget support to be enabled ++# ++# CONFIG_USB_DWC2_PERIPHERAL is not set ++CONFIG_USB_DWC2_DUAL_ROLE=y ++# CONFIG_USB_DWC2_DEBUG is not set ++# CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set ++# CONFIG_USB_CHIPIDEA is not set ++# CONFIG_USB_ISP1760 is not set ++ ++# ++# USB port drivers ++# ++CONFIG_USB_SERIAL=y ++# CONFIG_USB_SERIAL_CONSOLE is not set ++CONFIG_USB_SERIAL_GENERIC=y ++# CONFIG_USB_SERIAL_SIMPLE is not set ++# CONFIG_USB_SERIAL_AIRCABLE is not set ++# CONFIG_USB_SERIAL_ARK3116 is not set ++# CONFIG_USB_SERIAL_BELKIN is not set ++# CONFIG_USB_SERIAL_CH341 is not set ++# CONFIG_USB_SERIAL_WHITEHEAT is not set ++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set ++CONFIG_USB_SERIAL_CP210X=y ++# CONFIG_USB_SERIAL_CYPRESS_M8 is not set ++# CONFIG_USB_SERIAL_EMPEG is not set ++CONFIG_USB_SERIAL_FTDI_SIO=y ++# CONFIG_USB_SERIAL_VISOR is not set ++# CONFIG_USB_SERIAL_IPAQ is not set ++# CONFIG_USB_SERIAL_IR is not set ++# CONFIG_USB_SERIAL_EDGEPORT is not set ++# CONFIG_USB_SERIAL_EDGEPORT_TI is not set ++# CONFIG_USB_SERIAL_F81232 is not set ++# CONFIG_USB_SERIAL_GARMIN is not set ++# CONFIG_USB_SERIAL_IPW is not set ++# CONFIG_USB_SERIAL_IUU is not set ++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set ++CONFIG_USB_SERIAL_KEYSPAN=y ++# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set ++# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set ++# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set ++# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set ++# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set ++# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set ++# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set ++# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set ++# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set ++# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set ++# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set ++# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set ++# CONFIG_USB_SERIAL_KLSI is not set ++# CONFIG_USB_SERIAL_KOBIL_SCT is not set ++# CONFIG_USB_SERIAL_MCT_U232 is not set ++# CONFIG_USB_SERIAL_METRO is not set ++# CONFIG_USB_SERIAL_MOS7720 is not set ++# CONFIG_USB_SERIAL_MOS7840 is not set ++# CONFIG_USB_SERIAL_MXUPORT is not set ++# CONFIG_USB_SERIAL_NAVMAN is not set ++CONFIG_USB_SERIAL_PL2303=y ++CONFIG_USB_SERIAL_OTI6858=y ++# CONFIG_USB_SERIAL_QCAUX is not set ++CONFIG_USB_SERIAL_QUALCOMM=y ++# CONFIG_USB_SERIAL_SPCP8X5 is not set ++# CONFIG_USB_SERIAL_SAFE is not set ++CONFIG_USB_SERIAL_SIERRAWIRELESS=y ++# CONFIG_USB_SERIAL_SYMBOL is not set ++# CONFIG_USB_SERIAL_TI is not set ++# CONFIG_USB_SERIAL_CYBERJACK is not set ++# CONFIG_USB_SERIAL_XIRCOM is not set ++CONFIG_USB_SERIAL_WWAN=y ++CONFIG_USB_SERIAL_OPTION=y ++# CONFIG_USB_SERIAL_OMNINET is not set ++# CONFIG_USB_SERIAL_OPTICON is not set ++# CONFIG_USB_SERIAL_XSENS_MT is not set ++# CONFIG_USB_SERIAL_WISHBONE is not set ++# CONFIG_USB_SERIAL_SSU100 is not set ++# CONFIG_USB_SERIAL_QT2 is not set ++# CONFIG_USB_SERIAL_DEBUG 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_LED is not set ++# CONFIG_USB_CYPRESS_CY7C63 is not set ++# CONFIG_USB_CYTHERM 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_EHSET_TEST_FIXTURE is not set ++# CONFIG_USB_ISIGHTFW is not set ++# CONFIG_USB_YUREX is not set ++CONFIG_USB_EZUSB_FX2=y ++# CONFIG_USB_HSIC_USB3503 is not set ++# CONFIG_USB_LINK_LAYER_TEST is not set ++# CONFIG_USB_CHAOSKEY is not set ++ ++# ++# USB Physical Layer drivers ++# ++# CONFIG_USB_PHY is not set ++# CONFIG_USB_OTG_WAKELOCK is not set ++# CONFIG_NOP_USB_XCEIV is not set ++# CONFIG_USB_GPIO_VBUS is not set ++# CONFIG_USB_ISP1301 is not set ++# CONFIG_USB_ULPI is not set ++CONFIG_USB_GADGET=y ++# CONFIG_USB_GADGET_DEBUG is not set ++CONFIG_USB_GADGET_DEBUG_FILES=y ++# CONFIG_USB_GADGET_DEBUG_FS is not set ++CONFIG_USB_GADGET_VBUS_DRAW=500 ++CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 ++ ++# ++# USB Peripheral Controller ++# ++# CONFIG_USB_FOTG210_UDC is not set ++# CONFIG_USB_GR_UDC is not set ++# CONFIG_USB_R8A66597 is not set ++# CONFIG_USB_PXA27X is not set ++# CONFIG_USB_MV_UDC is not set ++# CONFIG_USB_MV_U3D is not set ++# CONFIG_USB_M66592 is not set ++# CONFIG_USB_BDC_UDC is not set ++# CONFIG_USB_NET2272 is not set ++# CONFIG_USB_GADGET_XILINX is not set ++# CONFIG_USB_DUMMY_HCD is not set ++CONFIG_USB_LIBCOMPOSITE=y ++CONFIG_USB_F_ACM=y ++CONFIG_USB_U_SERIAL=y ++CONFIG_USB_F_SERIAL=y ++CONFIG_USB_F_OBEX=y ++# CONFIG_USB_CONFIGFS is not set ++# CONFIG_USB_ZERO is not set ++# CONFIG_USB_AUDIO is not set ++# CONFIG_USB_ETH is not set ++# CONFIG_USB_G_NCM is not set ++# CONFIG_USB_GADGETFS is not set ++# CONFIG_USB_FUNCTIONFS is not set ++# CONFIG_USB_MASS_STORAGE is not set ++CONFIG_USB_G_SERIAL=y ++# CONFIG_USB_MIDI_GADGET is not set ++# CONFIG_USB_G_PRINTER is not set ++# CONFIG_USB_CDC_COMPOSITE is not set ++# CONFIG_USB_G_ACM_MS is not set ++# CONFIG_USB_G_MULTI is not set ++# CONFIG_USB_G_HID is not set ++# CONFIG_USB_G_DBGP is not set ++# CONFIG_USB_G_WEBCAM is not set ++ ++# ++# ROCKCHIP USB Support ++# ++# CONFIG_USB20_HOST is not set ++# CONFIG_USB20_OTG is not set ++# CONFIG_USB_LED_TRIG is not set ++# CONFIG_UWB is not set ++CONFIG_MMC=y ++# CONFIG_MMC_DEBUG is not set ++# CONFIG_MMC_EMBEDDED_SDIO is not set ++# CONFIG_MMC_PARANOID_SD_INIT is not set ++ ++# ++# MMC/SD/SDIO Card Drivers ++# ++CONFIG_MMC_BLOCK=y ++CONFIG_MMC_BLOCK_MINORS=32 ++CONFIG_MMC_BLOCK_BOUNCE=y ++# CONFIG_SDIO_UART is not set ++CONFIG_MMC_TEST=y ++# CONFIG_MMC_SIMULATE_MAX_SPEED is not set ++ ++# ++# MMC/SD/SDIO Host Controller Drivers ++# ++# CONFIG_MMC_ARMMMCI is not set ++# CONFIG_MMC_SDHCI is not set ++# CONFIG_MMC_SPI is not set ++CONFIG_MMC_DW=y ++CONFIG_MMC_DW_PLTFM=y ++# CONFIG_MMC_DW_EXYNOS is not set ++# CONFIG_MMC_DW_K3 is not set ++CONFIG_MMC_DW_ROCKCHIP=y ++# CONFIG_MMC_VUB300 is not set ++# CONFIG_MMC_USHC is not set ++# CONFIG_MMC_USDHI6ROL0 is not set ++# CONFIG_MMC_MTK is not set ++# CONFIG_MEMSTICK is not set ++CONFIG_NEW_LEDS=y ++CONFIG_LEDS_CLASS=y ++# CONFIG_LEDS_CLASS_FLASH is not set ++ ++# ++# LED drivers ++# ++# CONFIG_LEDS_BCM6328 is not set ++# CONFIG_LEDS_BCM6358 is not set ++# CONFIG_LEDS_LM3530 is not set ++# CONFIG_LEDS_LM3642 is not set ++# CONFIG_LEDS_PCA9532 is not set ++CONFIG_LEDS_GPIO=y ++# CONFIG_LEDS_LP3944 is not set ++# CONFIG_LEDS_LP5521 is not set ++# CONFIG_LEDS_LP5523 is not set ++# CONFIG_LEDS_LP5562 is not set ++# CONFIG_LEDS_LP8501 is not set ++# CONFIG_LEDS_LP8860 is not set ++# CONFIG_LEDS_PCA955X is not set ++# CONFIG_LEDS_PCA963X is not set ++# CONFIG_LEDS_DAC124S085 is not set ++# CONFIG_LEDS_PWM is not set ++# CONFIG_LEDS_REGULATOR is not set ++# CONFIG_LEDS_BD2802 is not set ++# CONFIG_LEDS_LT3593 is not set ++# CONFIG_LEDS_TCA6507 is not set ++# CONFIG_LEDS_TLC591XX is not set ++# CONFIG_LEDS_LM355x is not set ++CONFIG_LEDS_IS31FL32XX=y ++ ++# ++# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) ++# ++# CONFIG_LEDS_BLINKM is not set ++# CONFIG_LEDS_SYSCON is not set ++ ++# ++# LED Triggers ++# ++CONFIG_LEDS_TRIGGERS=y ++# CONFIG_LEDS_TRIGGER_TIMER is not set ++# CONFIG_LEDS_TRIGGER_ONESHOT is not set ++# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set ++# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set ++# CONFIG_LEDS_TRIGGER_CPU is not set ++# CONFIG_LEDS_TRIGGER_GPIO is not set ++# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set ++ ++# ++# iptables trigger is under Netfilter config (LED target) ++# ++# CONFIG_LEDS_TRIGGER_TRANSIENT is not set ++# CONFIG_LEDS_TRIGGER_CAMERA is not set ++# CONFIG_SWITCH is not set ++# CONFIG_ACCESSIBILITY is not set ++CONFIG_EDAC_SUPPORT=y ++# CONFIG_EDAC is not set ++CONFIG_RTC_LIB=y ++CONFIG_RTC_CLASS=y ++CONFIG_RTC_HCTOSYS=y ++CONFIG_RTC_HCTOSYS_DEVICE="rtc0" ++CONFIG_RTC_SYSTOHC=y ++CONFIG_RTC_SYSTOHC_DEVICE="rtc0" ++# 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_ABB5ZES3 is not set ++# CONFIG_RTC_DRV_ABX80X is not set ++# CONFIG_RTC_DRV_DS1307 is not set ++# CONFIG_RTC_DRV_DS1374 is not set ++# CONFIG_RTC_DRV_DS1672 is not set ++# CONFIG_RTC_DRV_DS3232 is not set ++# CONFIG_RTC_DRV_FAKE is not set ++# CONFIG_RTC_DRV_HYM8563 is not set ++# CONFIG_RTC_DRV_MAX6900 is not set ++CONFIG_RTC_DRV_RK808=y ++# CONFIG_RTC_DRV_RK_TIMER is not set ++# CONFIG_RTC_DRV_RS5C372 is not set ++# CONFIG_RTC_DRV_ISL1208 is not set ++# CONFIG_RTC_DRV_ISL12022 is not set ++# CONFIG_RTC_DRV_ISL12057 is not set ++# CONFIG_RTC_DRV_X1205 is not set ++# CONFIG_RTC_DRV_PCF2127 is not set ++# CONFIG_RTC_DRV_PCF8523 is not set ++# CONFIG_RTC_DRV_PCF8563 is not set ++# CONFIG_RTC_DRV_PCF85063 is not set ++# CONFIG_RTC_DRV_PCF8583 is not set ++# CONFIG_RTC_DRV_M41T80 is not set ++# CONFIG_RTC_DRV_BQ32K is not set ++# CONFIG_RTC_DRV_S35390A is not set ++# CONFIG_RTC_DRV_FM3130 is not set ++# CONFIG_RTC_DRV_RX8581 is not set ++# CONFIG_RTC_DRV_RX8025 is not set ++# CONFIG_RTC_DRV_EM3027 is not set ++# CONFIG_RTC_DRV_RV3029C2 is not set ++# CONFIG_RTC_DRV_RV8803 is not set ++ ++# ++# SPI RTC drivers ++# ++# CONFIG_RTC_DRV_M41T93 is not set ++# CONFIG_RTC_DRV_M41T94 is not set ++# CONFIG_RTC_DRV_DS1305 is not set ++# CONFIG_RTC_DRV_DS1343 is not set ++# CONFIG_RTC_DRV_DS1347 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 ++# CONFIG_RTC_DRV_PCF2123 is not set ++# CONFIG_RTC_DRV_RX4581 is not set ++# CONFIG_RTC_DRV_MCP795 is not set ++ ++# ++# Platform RTC drivers ++# ++# CONFIG_RTC_DRV_DS1286 is not set ++# CONFIG_RTC_DRV_DS1511 is not set ++# CONFIG_RTC_DRV_DS1553 is not set ++# CONFIG_RTC_DRV_DS1685_FAMILY is not set ++# CONFIG_RTC_DRV_DS1742 is not set ++# CONFIG_RTC_DRV_DS2404 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_MSM6242 is not set ++# CONFIG_RTC_DRV_BQ4802 is not set ++# CONFIG_RTC_DRV_RP5C01 is not set ++# CONFIG_RTC_DRV_V3020 is not set ++# CONFIG_RTC_DRV_ZYNQMP is not set ++ ++# ++# on-CPU RTC drivers ++# ++# CONFIG_RTC_DRV_PL030 is not set ++# CONFIG_RTC_DRV_PL031 is not set ++# CONFIG_RTC_DRV_SNVS is not set ++ ++# ++# HID Sensor RTC drivers ++# ++# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set ++CONFIG_DMADEVICES=y ++# CONFIG_DMADEVICES_DEBUG is not set ++ ++# ++# DMA Devices ++# ++CONFIG_DMA_ENGINE=y ++CONFIG_DMA_OF=y ++# CONFIG_AMBA_PL08X is not set ++# CONFIG_FSL_EDMA is not set ++# CONFIG_INTEL_IDMA64 is not set ++CONFIG_PL330_DMA=y ++# CONFIG_DW_DMAC is not set ++ ++# ++# DMA Clients ++# ++# CONFIG_ASYNC_TX_DMA is not set ++# CONFIG_DMATEST is not set ++# CONFIG_AUXDISPLAY is not set ++# CONFIG_UIO is not set ++# CONFIG_VFIO is not set ++# CONFIG_VIRT_DRIVERS is not set ++ ++# ++# Virtio drivers ++# ++# CONFIG_VIRTIO_MMIO is not set ++ ++# ++# Microsoft Hyper-V guest support ++# ++CONFIG_STAGING=y ++# CONFIG_PRISM2_USB is not set ++# CONFIG_COMEDI is not set ++# CONFIG_RTLLIB is not set ++# CONFIG_R8712U is not set ++# CONFIG_R8188EU is not set ++# CONFIG_R8723AU is not set ++# CONFIG_VT6656 is not set ++ ++# ++# IIO staging drivers ++# ++ ++# ++# Accelerometers ++# ++# CONFIG_ADIS16201 is not set ++# CONFIG_ADIS16203 is not set ++# CONFIG_ADIS16204 is not set ++# CONFIG_ADIS16209 is not set ++# CONFIG_ADIS16220 is not set ++# CONFIG_ADIS16240 is not set ++# CONFIG_LIS3L02DQ is not set ++# CONFIG_SCA3000 is not set ++ ++# ++# Analog to digital converters ++# ++# CONFIG_AD7606 is not set ++# CONFIG_AD7780 is not set ++# CONFIG_AD7816 is not set ++# CONFIG_AD7192 is not set ++# CONFIG_AD7280 is not set ++ ++# ++# Analog digital bi-direction converters ++# ++# CONFIG_ADT7316 is not set ++ ++# ++# Capacitance to digital converters ++# ++# CONFIG_AD7150 is not set ++# CONFIG_AD7152 is not set ++# CONFIG_AD7746 is not set ++ ++# ++# Direct Digital Synthesis ++# ++# CONFIG_AD9832 is not set ++# CONFIG_AD9834 is not set ++ ++# ++# Digital gyroscope sensors ++# ++# CONFIG_ADIS16060 is not set ++ ++# ++# Network Analyzer, Impedance Converters ++# ++# CONFIG_AD5933 is not set ++# CONFIG_INV_MPU_IIO is not set ++ ++# ++# Light sensors ++# ++CONFIG_SENSORS_ISL29018=y ++# CONFIG_SENSORS_ISL29028 is not set ++CONFIG_TSL2583=y ++# CONFIG_TSL2x7x is not set ++ ++# ++# Magnetometer sensors ++# ++# CONFIG_SENSORS_HMC5843_I2C is not set ++# CONFIG_SENSORS_HMC5843_SPI is not set ++ ++# ++# Active energy metering IC ++# ++# CONFIG_ADE7753 is not set ++# CONFIG_ADE7754 is not set ++# CONFIG_ADE7758 is not set ++# CONFIG_ADE7759 is not set ++# CONFIG_ADE7854 is not set ++ ++# ++# Resolver to digital converters ++# ++# CONFIG_AD2S90 is not set ++# CONFIG_AD2S1200 is not set ++# CONFIG_AD2S1210 is not set ++ ++# ++# Triggers - standalone ++# ++# CONFIG_IIO_PERIODIC_RTC_TRIGGER is not set ++# CONFIG_IIO_SIMPLE_DUMMY is not set ++ ++# ++# Speakup console speech ++# ++# CONFIG_SPEAKUP is not set ++# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set ++# CONFIG_STAGING_MEDIA is not set ++ ++# ++# Android ++# ++# CONFIG_ASHMEM is not set ++# CONFIG_ANDROID_TIMED_OUTPUT is not set ++# CONFIG_ANDROID_LOW_MEMORY_KILLER is not set ++# CONFIG_SYNC is not set ++# CONFIG_ION is not set ++CONFIG_FIQ_DEBUGGER=y ++CONFIG_FIQ_DEBUGGER_NO_SLEEP=y ++# CONFIG_FIQ_DEBUGGER_WAKEUP_IRQ_ALWAYS_ON is not set ++CONFIG_FIQ_DEBUGGER_CONSOLE=y ++CONFIG_FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE=y ++# CONFIG_FIQ_DEBUGGER_TRUST_ZONE is not set ++# CONFIG_FIQ_DEBUGGER_UART_OVERLAY is not set ++# CONFIG_FIQ_WATCHDOG is not set ++# CONFIG_RK_CONSOLE_THREAD is not set ++# CONFIG_STAGING_BOARD is not set ++# CONFIG_WIMAX_GDM72XX is not set ++# CONFIG_LTE_GDM724X is not set ++# CONFIG_LUSTRE_FS is not set ++# CONFIG_DGAP is not set ++# CONFIG_GS_FPGABOOT is not set ++# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set ++# CONFIG_FB_TFT is not set ++# CONFIG_FSL_MC_BUS is not set ++# CONFIG_WILC1000_DRIVER is not set ++# CONFIG_MOST is not set ++# CONFIG_POWERVR_ROGUE_N is not set ++# CONFIG_GOLDFISH is not set ++# CONFIG_CHROME_PLATFORMS is not set ++CONFIG_CLKDEV_LOOKUP=y ++CONFIG_HAVE_CLK_PREPARE=y ++CONFIG_COMMON_CLK=y ++ ++# ++# Common Clock Framework ++# ++# CONFIG_COMMON_CLK_VERSATILE is not set ++CONFIG_COMMON_CLK_RK808=y ++# CONFIG_COMMON_CLK_SI5351 is not set ++# CONFIG_COMMON_CLK_SI514 is not set ++# CONFIG_COMMON_CLK_SI570 is not set ++# CONFIG_COMMON_CLK_CDCE925 is not set ++# CONFIG_CLK_QORIQ is not set ++# CONFIG_COMMON_CLK_XGENE is not set ++# CONFIG_COMMON_CLK_PWM is not set ++# CONFIG_COMMON_CLK_PXA is not set ++# CONFIG_COMMON_CLK_CDCE706 is not set ++ ++# ++# Hardware Spinlock drivers ++# ++# CONFIG_HWSPINLOCK_ROCKCHIP is not set ++ ++# ++# Clock Source drivers ++# ++CONFIG_CLKSRC_OF=y ++CONFIG_CLKSRC_PROBE=y ++CONFIG_ROCKCHIP_TIMER=y ++CONFIG_ARM_ARCH_TIMER=y ++CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y ++# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set ++# CONFIG_ARM_TIMER_SP804 is not set ++# CONFIG_ATMEL_PIT is not set ++# CONFIG_SH_TIMER_CMT is not set ++# CONFIG_SH_TIMER_MTU2 is not set ++# CONFIG_SH_TIMER_TMU is not set ++# CONFIG_EM_TIMER_STI is not set ++# CONFIG_MAILBOX is not set ++CONFIG_IOMMU_API=y ++CONFIG_IOMMU_SUPPORT=y ++ ++# ++# Generic IOMMU Pagetable Support ++# ++# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set ++CONFIG_IOMMU_IOVA=y ++CONFIG_OF_IOMMU=y ++CONFIG_IOMMU_DMA=y ++CONFIG_ROCKCHIP_IOMMU=y ++# CONFIG_RK_IOMMU is not set ++# CONFIG_ARM_SMMU is not set ++ ++# ++# Remoteproc drivers ++# ++# CONFIG_STE_MODEM_RPROC is not set ++ ++# ++# Rpmsg drivers ++# ++ ++# ++# SOC (System On Chip) specific Drivers ++# ++ ++# ++# Rockchip CPU selection ++# ++CONFIG_CPU_PX30=y ++# CONFIG_CPU_RK1808 is not set ++# CONFIG_CPU_RK3308 is not set ++CONFIG_CPU_RK3328=y ++# CONFIG_CPU_RK3366 is not set ++CONFIG_CPU_RK3368=y ++CONFIG_CPU_RK3399=y ++CONFIG_ANDROID_VERSION=0x07010000 ++CONFIG_ROCKCHIP_CPUINFO=y ++# CONFIG_ROCKCHIP_DEVICEINFO is not set ++CONFIG_ROCKCHIP_IPA=y ++CONFIG_ROCKCHIP_OPP=y ++# CONFIG_ROCKCHIP_PM_TEST is not set ++CONFIG_ROCKCHIP_GRF=y ++CONFIG_ROCKCHIP_PM_DOMAINS=y ++CONFIG_ROCKCHIP_PVTM=y ++CONFIG_ROCKCHIP_SUSPEND_MODE=y ++CONFIG_ROCKCHIP_SYSTEM_MONITOR=y ++# CONFIG_ROCKCHIP_VENDOR_STORAGE_UPDATE_LOADER is not set ++# CONFIG_SUNXI_SRAM is not set ++# CONFIG_SOC_TI is not set ++CONFIG_PM_DEVFREQ=y ++ ++# ++# DEVFREQ Governors ++# ++CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y ++CONFIG_DEVFREQ_GOV_PERFORMANCE=y ++CONFIG_DEVFREQ_GOV_POWERSAVE=y ++CONFIG_DEVFREQ_GOV_USERSPACE=y ++ ++# ++# DEVFREQ Drivers ++# ++# CONFIG_ARM_ROCKCHIP_BUS_DEVFREQ is not set ++CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ=y ++CONFIG_PM_DEVFREQ_EVENT=y ++CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI=y ++# CONFIG_DEVFREQ_EVENT_ROCKCHIP_NOCP is not set ++CONFIG_EXTCON=y ++ ++# ++# Extcon Device Drivers ++# ++# CONFIG_EXTCON_ADC_JACK is not set ++# CONFIG_EXTCON_GPIO is not set ++# CONFIG_EXTCON_RT8973A is not set ++# CONFIG_EXTCON_SM5502 is not set ++# CONFIG_EXTCON_USB_GPIO is not set ++CONFIG_MEMORY=y ++# CONFIG_ARM_PL172_MPMC is not set ++CONFIG_IIO=y ++CONFIG_IIO_BUFFER=y ++# CONFIG_IIO_BUFFER_CB is not set ++CONFIG_IIO_KFIFO_BUF=y ++CONFIG_IIO_TRIGGER=y ++CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 ++ ++# ++# Accelerometers ++# ++# CONFIG_BMA180 is not set ++# CONFIG_BMC150_ACCEL is not set ++# CONFIG_IIO_ST_ACCEL_3AXIS is not set ++# CONFIG_KXSD9 is not set ++# CONFIG_KXCJK1013 is not set ++# CONFIG_MMA8452 is not set ++# CONFIG_MMA9551 is not set ++# CONFIG_MMA9553 is not set ++# CONFIG_MXC4005 is not set ++# CONFIG_STK8312 is not set ++# CONFIG_STK8BA50 is not set ++ ++# ++# Analog to digital converters ++# ++# CONFIG_AD7266 is not set ++# CONFIG_AD7291 is not set ++# CONFIG_AD7298 is not set ++# CONFIG_AD7476 is not set ++# CONFIG_AD7791 is not set ++# CONFIG_AD7793 is not set ++# CONFIG_AD7887 is not set ++# CONFIG_AD7923 is not set ++# CONFIG_AD799X is not set ++# CONFIG_CC10001_ADC is not set ++# CONFIG_GPIO_MUXADC is not set ++# CONFIG_HI8435 is not set ++# CONFIG_MAX1027 is not set ++# CONFIG_MAX1363 is not set ++# CONFIG_MCP320X is not set ++# CONFIG_MCP3422 is not set ++# CONFIG_NAU7802 is not set ++CONFIG_ROCKCHIP_SARADC=y ++# CONFIG_TI_ADC081C is not set ++# CONFIG_TI_ADC128S052 is not set ++# CONFIG_VF610_ADC is not set ++ ++# ++# Amplifiers ++# ++# CONFIG_AD8366 is not set ++ ++# ++# Chemical Sensors ++# ++# CONFIG_VZ89X is not set ++ ++# ++# Hid Sensor IIO Common ++# ++ ++# ++# SSP Sensor Common ++# ++# CONFIG_IIO_SSP_SENSORHUB is not set ++ ++# ++# Digital to analog converters ++# ++# CONFIG_AD5064 is not set ++# CONFIG_AD5360 is not set ++# CONFIG_AD5380 is not set ++# CONFIG_AD5421 is not set ++# CONFIG_AD5446 is not set ++# CONFIG_AD5449 is not set ++# CONFIG_AD5504 is not set ++# CONFIG_AD5624R_SPI is not set ++# CONFIG_AD5686 is not set ++# CONFIG_AD5755 is not set ++# CONFIG_AD5764 is not set ++# CONFIG_AD5791 is not set ++# CONFIG_AD7303 is not set ++# CONFIG_M62332 is not set ++# CONFIG_MAX517 is not set ++# CONFIG_MAX5821 is not set ++# CONFIG_MCP4725 is not set ++# CONFIG_MCP4922 is not set ++ ++# ++# Frequency Synthesizers DDS/PLL ++# ++ ++# ++# Clock Generator/Distribution ++# ++# CONFIG_AD9523 is not set ++ ++# ++# Phase-Locked Loop (PLL) frequency synthesizers ++# ++# CONFIG_ADF4350 is not set ++ ++# ++# Digital gyroscope sensors ++# ++# CONFIG_ADIS16080 is not set ++# CONFIG_ADIS16130 is not set ++# CONFIG_ADIS16136 is not set ++# CONFIG_ADIS16260 is not set ++# CONFIG_ADXRS450 is not set ++# CONFIG_BMG160 is not set ++# CONFIG_IIO_ST_GYRO_3AXIS is not set ++# CONFIG_ITG3200 is not set ++ ++# ++# Humidity sensors ++# ++# CONFIG_DHT11 is not set ++# CONFIG_HDC100X is not set ++# CONFIG_HTU21 is not set ++# CONFIG_SI7005 is not set ++# CONFIG_SI7020 is not set ++ ++# ++# Inertial measurement units ++# ++# CONFIG_ADIS16400 is not set ++# CONFIG_ADIS16480 is not set ++# CONFIG_KMX61 is not set ++# CONFIG_INV_MPU6050_IIO is not set ++ ++# ++# Light sensors ++# ++# CONFIG_ADJD_S311 is not set ++# CONFIG_AL3320A is not set ++# CONFIG_APDS9300 is not set ++# CONFIG_APDS9960 is not set ++# CONFIG_BH1750 is not set ++# CONFIG_CM32181 is not set ++# CONFIG_CM3232 is not set ++# CONFIG_CM3323 is not set ++# CONFIG_CM36651 is not set ++# CONFIG_GP2AP020A00F is not set ++# CONFIG_ISL29125 is not set ++# CONFIG_JSA1212 is not set ++# CONFIG_RPR0521 is not set ++# CONFIG_LTR501 is not set ++# CONFIG_OPT3001 is not set ++# CONFIG_PA12203001 is not set ++# CONFIG_STK3310 is not set ++# CONFIG_TCS3414 is not set ++# CONFIG_TCS3472 is not set ++CONFIG_SENSORS_TSL2563=y ++# CONFIG_TSL4531 is not set ++# CONFIG_US5182D is not set ++# CONFIG_VCNL4000 is not set ++# CONFIG_VL6180 is not set ++ ++# ++# Magnetometer sensors ++# ++# CONFIG_AK8975 is not set ++# CONFIG_AK09911 is not set ++# CONFIG_BMC150_MAGN is not set ++# CONFIG_MAG3110 is not set ++# CONFIG_MMC35240 is not set ++# CONFIG_IIO_ST_MAGN_3AXIS is not set ++ ++# ++# Inclinometer sensors ++# ++ ++# ++# Triggers - standalone ++# ++# CONFIG_IIO_INTERRUPT_TRIGGER is not set ++CONFIG_IIO_SYSFS_TRIGGER=y ++ ++# ++# Digital potentiometers ++# ++# CONFIG_MCP4531 is not set ++ ++# ++# Pressure sensors ++# ++# CONFIG_BMP280 is not set ++# CONFIG_MPL115 is not set ++# CONFIG_MPL3115 is not set ++# CONFIG_MS5611 is not set ++# CONFIG_MS5637 is not set ++# CONFIG_IIO_ST_PRESS is not set ++# CONFIG_T5403 is not set ++ ++# ++# Lightning sensors ++# ++# CONFIG_AS3935 is not set ++ ++# ++# Proximity sensors ++# ++# CONFIG_LIDAR_LITE_V2 is not set ++# CONFIG_SRF04 is not set ++# CONFIG_SX9500 is not set ++ ++# ++# Temperature sensors ++# ++# CONFIG_MLX90614 is not set ++# CONFIG_TMP006 is not set ++# CONFIG_TSYS01 is not set ++# CONFIG_TSYS02D is not set ++CONFIG_PWM=y ++CONFIG_PWM_SYSFS=y ++# CONFIG_PWM_FSL_FTM is not set ++# CONFIG_PWM_GPIO is not set ++# CONFIG_PWM_PCA9685 is not set ++CONFIG_PWM_ROCKCHIP=y ++# CONFIG_PWM_ROCKCHIP_I2S is not set ++CONFIG_IRQCHIP=y ++CONFIG_ARM_GIC=y ++CONFIG_ARM_GIC_V3=y ++CONFIG_PARTITION_PERCPU=y ++# CONFIG_IPACK_BUS is not set ++CONFIG_ARCH_HAS_RESET_CONTROLLER=y ++CONFIG_RESET_CONTROLLER=y ++# CONFIG_FMC is not set ++ ++# ++# PHY Subsystem ++# ++CONFIG_GENERIC_PHY=y ++# CONFIG_PHY_PXA_28NM_HSIC is not set ++# CONFIG_PHY_PXA_28NM_USB2 is not set ++# CONFIG_BCM_KONA_USB2_PHY is not set ++# CONFIG_PHY_SAMSUNG_USB2 is not set ++# CONFIG_PHY_XGENE is not set ++# CONFIG_PHY_ROCKCHIP_USB is not set ++# CONFIG_PHY_ROCKCHIP_INNO_COMBPHY is not set ++CONFIG_PHY_ROCKCHIP_INNO_USB2=y ++# CONFIG_PHY_ROCKCHIP_INNO_USB3 is not set ++# CONFIG_PHY_ROCKCHIP_EMMC is not set ++# CONFIG_PHY_ROCKCHIP_DP is not set ++CONFIG_PHY_ROCKCHIP_MIPI_RX=y ++# CONFIG_PHY_ROCKCHIP_INNO_MIPI_DPHY is not set ++# CONFIG_PHY_ROCKCHIP_INNO_HDMI_PHY is not set ++# CONFIG_PHY_ROCKCHIP_INNO_VIDEO_PHY is not set ++CONFIG_PHY_ROCKCHIP_INNO_VIDEO_COMBO_PHY=y ++# CONFIG_PHY_ROCKCHIP_TYPEC is not set ++# CONFIG_PHY_ROCKCHIP_PCIE is not set ++# CONFIG_POWERCAP is not set ++# CONFIG_MCB is not set ++ ++# ++# Performance monitor support ++# ++CONFIG_ARM_PMU=y ++CONFIG_RAS=y ++ ++# ++# Android ++# ++CONFIG_ANDROID=y ++# CONFIG_ANDROID_BINDER_IPC is not set ++# CONFIG_LIBNVDIMM is not set ++CONFIG_NVMEM=y ++# CONFIG_ROCKCHIP_EFUSE is not set ++CONFIG_ROCKCHIP_OTP=y ++# CONFIG_STM is not set ++# CONFIG_INTEL_TH is not set ++ ++# ++# FPGA Configuration Support ++# ++# CONFIG_FPGA is not set ++# CONFIG_TEE is not set ++# CONFIG_RK_FLASH is not set ++# CONFIG_RK_NAND is not set ++ ++# ++# Headset device support ++# ++# CONFIG_RK_HEADSET is not set ++ ++# ++# Firmware Drivers ++# ++CONFIG_ARM_PSCI_FW=y ++# CONFIG_FIRMWARE_MEMMAP is not set ++CONFIG_HAVE_ARM_SMCCC=y ++CONFIG_ROCKCHIP_SIP=y ++ ++# ++# File systems ++# ++CONFIG_DCACHE_WORD_ACCESS=y ++# CONFIG_EXT2_FS is not set ++# CONFIG_EXT3_FS is not set ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_USE_FOR_EXT2=y ++CONFIG_EXT4_FS_POSIX_ACL=y ++CONFIG_EXT4_FS_SECURITY=y ++# CONFIG_EXT4_ENCRYPTION is not set ++# CONFIG_EXT4_DEBUG is not set ++CONFIG_JBD2=y ++# CONFIG_JBD2_DEBUG is not set ++CONFIG_FS_MBCACHE=y ++# CONFIG_REISERFS_FS is not set ++# CONFIG_JFS_FS is not set ++CONFIG_XFS_FS=y ++# CONFIG_XFS_QUOTA is not set ++# CONFIG_XFS_POSIX_ACL is not set ++# CONFIG_XFS_RT is not set ++# CONFIG_XFS_WARN is not set ++# CONFIG_XFS_DEBUG is not set ++# CONFIG_GFS2_FS is not set ++# CONFIG_OCFS2_FS is not set ++# CONFIG_BTRFS_FS is not set ++# CONFIG_NILFS2_FS is not set ++# CONFIG_F2FS_FS is not set ++# CONFIG_FS_DAX is not set ++CONFIG_FS_POSIX_ACL=y ++CONFIG_EXPORTFS=y ++CONFIG_FILE_LOCKING=y ++# CONFIG_FS_ENCRYPTION is not set ++CONFIG_FSNOTIFY=y ++# CONFIG_DNOTIFY is not set ++CONFIG_INOTIFY_USER=y ++# CONFIG_FANOTIFY is not set ++# CONFIG_QUOTA is not set ++# CONFIG_QUOTACTL is not set ++# CONFIG_AUTOFS4_FS is not set ++CONFIG_FUSE_FS=y ++# CONFIG_CUSE is not set ++# CONFIG_OVERLAY_FS is not set ++ ++# ++# Caches ++# ++# CONFIG_FSCACHE is not set ++ ++# ++# CD-ROM/DVD Filesystems ++# ++CONFIG_ISO9660_FS=y ++CONFIG_JOLIET=y ++CONFIG_ZISOFS=y ++# CONFIG_UDF_FS is not set ++ ++# ++# DOS/FAT/NT Filesystems ++# ++CONFIG_FAT_FS=y ++# CONFIG_MSDOS_FS is not set ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_CODEPAGE=936 ++CONFIG_FAT_DEFAULT_IOCHARSET="utf8" ++# CONFIG_NTFS_FS is not set ++ ++# ++# Pseudo filesystems ++# ++CONFIG_PROC_FS=y ++# CONFIG_PROC_KCORE is not set ++CONFIG_PROC_SYSCTL=y ++CONFIG_PROC_PAGE_MONITOR=y ++# CONFIG_PROC_CHILDREN is not set ++CONFIG_PROC_UID=y ++CONFIG_KERNFS=y ++CONFIG_SYSFS=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_TMPFS_XATTR=y ++# CONFIG_HUGETLBFS is not set ++# CONFIG_HUGETLB_PAGE is not set ++CONFIG_CONFIGFS_FS=y ++CONFIG_MISC_FILESYSTEMS=y ++# CONFIG_ADFS_FS is not set ++# CONFIG_AFFS_FS is not set ++# CONFIG_ECRYPT_FS is not set ++# CONFIG_SDCARD_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_LOGFS is not set ++# CONFIG_CRAMFS is not set ++CONFIG_SQUASHFS=y ++CONFIG_SQUASHFS_DECOMP_SINGLE=y ++# CONFIG_SQUASHFS_DECOMP_MULTI is not set ++# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set ++# CONFIG_SQUASHFS_XATTR is not set ++CONFIG_SQUASHFS_ZLIB=y ++# CONFIG_SQUASHFS_LZ4 is not set ++# CONFIG_SQUASHFS_LZO is not set ++# CONFIG_SQUASHFS_XZ is not set ++# CONFIG_SQUASHFS_ZSTD is not set ++# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set ++# CONFIG_SQUASHFS_EMBEDDED is not set ++CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 ++# 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_QNX6FS_FS is not set ++# CONFIG_ROMFS_FS is not set ++# CONFIG_PSTORE 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_V2=y ++CONFIG_NFS_V3=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_SWAP=y ++# CONFIG_NFS_V4_1 is not set ++# CONFIG_NFS_USE_LEGACY_DNS is not set ++CONFIG_NFS_USE_KERNEL_DNS=y ++# CONFIG_NFSD is not set ++CONFIG_GRACE_PERIOD=y ++CONFIG_LOCKD=y ++CONFIG_LOCKD_V4=y ++CONFIG_NFS_ACL_SUPPORT=y ++CONFIG_NFS_COMMON=y ++CONFIG_SUNRPC=y ++CONFIG_SUNRPC_GSS=y ++CONFIG_SUNRPC_SWAP=y ++# CONFIG_SUNRPC_DEBUG is not set ++# CONFIG_CEPH_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 ++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 is not set ++# CONFIG_NLS_CODEPAGE_932 is not set ++# 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_MAC_ROMAN is not set ++# CONFIG_NLS_MAC_CELTIC is not set ++# CONFIG_NLS_MAC_CENTEURO is not set ++# CONFIG_NLS_MAC_CROATIAN is not set ++# CONFIG_NLS_MAC_CYRILLIC is not set ++# CONFIG_NLS_MAC_GAELIC is not set ++# CONFIG_NLS_MAC_GREEK is not set ++# CONFIG_NLS_MAC_ICELAND is not set ++# CONFIG_NLS_MAC_INUIT is not set ++# CONFIG_NLS_MAC_ROMANIAN is not set ++# CONFIG_NLS_MAC_TURKISH is not set ++CONFIG_NLS_UTF8=y ++# CONFIG_DLM is not set ++# CONFIG_VIRTUALIZATION is not set ++ ++# ++# Kernel hacking ++# ++ ++# ++# printk and dmesg options ++# ++CONFIG_PRINTK_TIME=y ++# CONFIG_PRINTK_PROCESS is not set ++CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 ++# CONFIG_BOOT_PRINTK_DELAY is not set ++CONFIG_DYNAMIC_DEBUG=y ++ ++# ++# Compile-time checks and compiler options ++# ++CONFIG_DEBUG_INFO=y ++# CONFIG_DEBUG_INFO_REDUCED is not set ++# CONFIG_DEBUG_INFO_SPLIT is not set ++# CONFIG_DEBUG_INFO_DWARF4 is not set ++# CONFIG_GDB_SCRIPTS is not set ++CONFIG_ENABLE_WARN_DEPRECATED=y ++CONFIG_ENABLE_MUST_CHECK=y ++CONFIG_FRAME_WARN=2048 ++# CONFIG_STRIP_ASM_SYMS is not set ++# CONFIG_READABLE_ASM is not set ++# CONFIG_UNUSED_SYMBOLS is not set ++# CONFIG_PAGE_OWNER is not set ++CONFIG_DEBUG_FS=y ++# CONFIG_HEADERS_CHECK is not set ++# CONFIG_DEBUG_SECTION_MISMATCH is not set ++CONFIG_SECTION_MISMATCH_WARN_ONLY=y ++CONFIG_ARCH_WANT_FRAME_POINTERS=y ++CONFIG_FRAME_POINTER=y ++# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set ++CONFIG_MAGIC_SYSRQ=y ++CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0 ++CONFIG_DEBUG_KERNEL=y ++ ++# ++# Memory Debugging ++# ++# CONFIG_PAGE_EXTENSION is not set ++# CONFIG_DEBUG_PAGEALLOC is not set ++# CONFIG_DEBUG_OBJECTS is not set ++# CONFIG_SLUB_DEBUG_ON is not set ++# CONFIG_SLUB_STATS is not set ++CONFIG_HAVE_DEBUG_KMEMLEAK=y ++# CONFIG_DEBUG_KMEMLEAK is not set ++# CONFIG_DEBUG_STACK_USAGE is not set ++# CONFIG_DEBUG_VM is not set ++# CONFIG_DEBUG_MEMORY_INIT is not set ++# CONFIG_DEBUG_PER_CPU_MAPS is not set ++CONFIG_HAVE_ARCH_KASAN=y ++# CONFIG_KASAN is not set ++# CONFIG_DEBUG_SHIRQ is not set ++ ++# ++# Debug Lockups and Hangs ++# ++CONFIG_LOCKUP_DETECTOR=y ++CONFIG_HARDLOCKUP_DETECTOR_OTHER_CPU=y ++CONFIG_HARDLOCKUP_DETECTOR=y ++# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set ++CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0 ++CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y ++CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1 ++CONFIG_DETECT_HUNG_TASK=y ++CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 ++CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y ++CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=1 ++# CONFIG_PANIC_ON_OOPS is not set ++CONFIG_PANIC_ON_OOPS_VALUE=0 ++CONFIG_PANIC_TIMEOUT=0 ++CONFIG_SCHED_DEBUG=y ++CONFIG_SCHED_INFO=y ++# CONFIG_PANIC_ON_RT_THROTTLING is not set ++CONFIG_SCHEDSTATS=y ++# CONFIG_SCHED_STACK_END_CHECK is not set ++# CONFIG_DEBUG_TIMEKEEPING is not set ++CONFIG_TIMER_STATS=y ++ ++# ++# Lock Debugging (spinlocks, mutexes, etc...) ++# ++# CONFIG_DEBUG_RT_MUTEXES is not set ++CONFIG_DEBUG_SPINLOCK=y ++# CONFIG_DEBUG_MUTEXES is not set ++# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set ++# CONFIG_DEBUG_LOCK_ALLOC is not set ++# CONFIG_PROVE_LOCKING is not set ++# CONFIG_LOCK_STAT is not set ++# CONFIG_DEBUG_ATOMIC_SLEEP is not set ++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set ++# CONFIG_LOCK_TORTURE_TEST is not set ++CONFIG_STACKTRACE=y ++# CONFIG_DEBUG_KOBJECT is not set ++CONFIG_HAVE_DEBUG_BUGVERBOSE=y ++CONFIG_DEBUG_BUGVERBOSE=y ++# CONFIG_DEBUG_LIST is not set ++# CONFIG_DEBUG_PI_LIST is not set ++# CONFIG_DEBUG_SG is not set ++# CONFIG_DEBUG_NOTIFIERS is not set ++CONFIG_DEBUG_CREDENTIALS=y ++ ++# ++# RCU Debugging ++# ++# CONFIG_PROVE_RCU is not set ++# CONFIG_SPARSE_RCU_POINTER is not set ++# CONFIG_TORTURE_TEST is not set ++# CONFIG_RCU_TORTURE_TEST is not set ++CONFIG_RCU_CPU_STALL_TIMEOUT=60 ++# CONFIG_RCU_TRACE is not set ++# CONFIG_RCU_EQS_DEBUG is not set ++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set ++# CONFIG_NOTIFIER_ERROR_INJECTION is not set ++# CONFIG_FAULT_INJECTION is not set ++CONFIG_NOP_TRACER=y ++CONFIG_HAVE_FUNCTION_TRACER=y ++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y ++CONFIG_HAVE_DYNAMIC_FTRACE=y ++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y ++CONFIG_HAVE_SYSCALL_TRACEPOINTS=y ++CONFIG_HAVE_C_RECORDMCOUNT=y ++CONFIG_TRACE_CLOCK=y ++CONFIG_RING_BUFFER=y ++CONFIG_EVENT_TRACING=y ++CONFIG_GPU_TRACEPOINTS=y ++CONFIG_CONTEXT_SWITCH_TRACER=y ++CONFIG_TRACING=y ++CONFIG_GENERIC_TRACER=y ++CONFIG_TRACING_SUPPORT=y ++CONFIG_FTRACE=y ++CONFIG_FUNCTION_TRACER=y ++CONFIG_FUNCTION_GRAPH_TRACER=y ++# CONFIG_PREEMPTIRQ_EVENTS is not set ++# CONFIG_IRQSOFF_TRACER is not set ++# CONFIG_SCHED_TRACER is not set ++# CONFIG_FTRACE_SYSCALLS is not set ++# CONFIG_TRACER_SNAPSHOT is not set ++CONFIG_BRANCH_PROFILE_NONE=y ++# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set ++# CONFIG_PROFILE_ALL_BRANCHES is not set ++# CONFIG_STACK_TRACER is not set ++CONFIG_BLK_DEV_IO_TRACE=y ++# CONFIG_PROBE_EVENTS is not set ++CONFIG_DYNAMIC_FTRACE=y ++# CONFIG_FUNCTION_PROFILER is not set ++CONFIG_FTRACE_MCOUNT_RECORD=y ++# CONFIG_FTRACE_STARTUP_TEST is not set ++# CONFIG_TRACEPOINT_BENCHMARK is not set ++# CONFIG_RING_BUFFER_BENCHMARK is not set ++# CONFIG_RING_BUFFER_STARTUP_TEST is not set ++# CONFIG_TRACE_ENUM_MAP_FILE is not set ++CONFIG_TRACING_EVENTS_GPIO=y ++ ++# ++# Runtime Testing ++# ++CONFIG_LKDTM=y ++# CONFIG_TEST_LIST_SORT is not set ++# CONFIG_BACKTRACE_SELF_TEST is not set ++# CONFIG_RBTREE_TEST is not set ++# CONFIG_INTERVAL_TREE_TEST is not set ++# CONFIG_PERCPU_TEST is not set ++# CONFIG_ATOMIC64_SELFTEST is not set ++# CONFIG_TEST_HEXDUMP is not set ++# CONFIG_TEST_STRING_HELPERS is not set ++# CONFIG_TEST_KSTRTOX is not set ++# CONFIG_TEST_PRINTF is not set ++# CONFIG_TEST_RHASHTABLE is not set ++# CONFIG_DMA_API_DEBUG is not set ++# CONFIG_TEST_LKM is not set ++# CONFIG_TEST_USER_COPY is not set ++# CONFIG_TEST_BPF is not set ++# CONFIG_TEST_FIRMWARE is not set ++# CONFIG_TEST_UDELAY is not set ++# CONFIG_MEMTEST is not set ++# CONFIG_TEST_STATIC_KEYS is not set ++# CONFIG_BUG_ON_DATA_CORRUPTION is not set ++# CONFIG_SAMPLES is not set ++CONFIG_HAVE_ARCH_KGDB=y ++# CONFIG_KGDB is not set ++# CONFIG_ARM64_PTDUMP is not set ++CONFIG_STRICT_DEVMEM=y ++# CONFIG_PID_IN_CONTEXTIDR is not set ++# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set ++CONFIG_DEBUG_SET_MODULE_RONX=y ++CONFIG_DEBUG_RODATA=y ++# CONFIG_DEBUG_ALIGN_RODATA is not set ++# CONFIG_CORESIGHT is not set ++ ++# ++# Security options ++# ++CONFIG_KEYS=y ++# CONFIG_PERSISTENT_KEYRINGS is not set ++# CONFIG_BIG_KEYS is not set ++# CONFIG_TRUSTED_KEYS is not set ++# CONFIG_ENCRYPTED_KEYS is not set ++# CONFIG_SECURITY_DMESG_RESTRICT is not set ++# CONFIG_SECURITY_PERF_EVENTS_RESTRICT is not set ++# CONFIG_SECURITY is not set ++CONFIG_SECURITYFS=y ++CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y ++CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y ++# CONFIG_HARDENED_USERCOPY is not set ++# CONFIG_TEE_SUPPORT is not set ++CONFIG_DEFAULT_SECURITY_DAC=y ++CONFIG_DEFAULT_SECURITY="" ++CONFIG_CRYPTO=y ++ ++# ++# Crypto core or helper ++# ++CONFIG_CRYPTO_ALGAPI=y ++CONFIG_CRYPTO_ALGAPI2=y ++CONFIG_CRYPTO_AEAD=y ++CONFIG_CRYPTO_AEAD2=y ++CONFIG_CRYPTO_BLKCIPHER=y ++CONFIG_CRYPTO_BLKCIPHER2=y ++CONFIG_CRYPTO_HASH=y ++CONFIG_CRYPTO_HASH2=y ++CONFIG_CRYPTO_RNG=y ++CONFIG_CRYPTO_RNG2=y ++CONFIG_CRYPTO_RNG_DEFAULT=y ++CONFIG_CRYPTO_PCOMP2=y ++CONFIG_CRYPTO_AKCIPHER2=y ++CONFIG_CRYPTO_AKCIPHER=y ++# CONFIG_CRYPTO_RSA is not set ++CONFIG_CRYPTO_MANAGER=y ++CONFIG_CRYPTO_MANAGER2=y ++# CONFIG_CRYPTO_USER is not set ++CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y ++CONFIG_CRYPTO_GF128MUL=y ++CONFIG_CRYPTO_NULL=y ++CONFIG_CRYPTO_NULL2=y ++# CONFIG_CRYPTO_PCRYPT is not set ++CONFIG_CRYPTO_WORKQUEUE=y ++CONFIG_CRYPTO_CRYPTD=y ++# CONFIG_CRYPTO_MCRYPTD is not set ++# CONFIG_CRYPTO_AUTHENC is not set ++# CONFIG_CRYPTO_TEST is not set ++CONFIG_CRYPTO_ABLK_HELPER=y ++ ++# ++# Authenticated Encryption with Associated Data ++# ++CONFIG_CRYPTO_CCM=y ++CONFIG_CRYPTO_GCM=y ++# CONFIG_CRYPTO_CHACHA20POLY1305 is not set ++CONFIG_CRYPTO_SEQIV=y ++# CONFIG_CRYPTO_ECHAINIV is not set ++ ++# ++# Block modes ++# ++# CONFIG_CRYPTO_CBC is not set ++# CONFIG_CRYPTO_HEH is not set ++CONFIG_CRYPTO_CTR=y ++# CONFIG_CRYPTO_CTS is not set ++CONFIG_CRYPTO_ECB=y ++# CONFIG_CRYPTO_LRW is not set ++# CONFIG_CRYPTO_PCBC is not set ++# CONFIG_CRYPTO_XTS is not set ++# CONFIG_CRYPTO_KEYWRAP is not set ++ ++# ++# Hash modes ++# ++CONFIG_CRYPTO_CMAC=y ++CONFIG_CRYPTO_HMAC=y ++# CONFIG_CRYPTO_XCBC is not set ++# CONFIG_CRYPTO_VMAC is not set ++ ++# ++# Digest ++# ++CONFIG_CRYPTO_CRC32C=y ++# CONFIG_CRYPTO_CRC32 is not set ++CONFIG_CRYPTO_CRCT10DIF=y ++CONFIG_CRYPTO_GHASH=y ++# CONFIG_CRYPTO_POLY1305 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=y ++CONFIG_CRYPTO_SHA512=y ++# CONFIG_CRYPTO_TGR192 is not set ++# CONFIG_CRYPTO_WP512 is not set ++ ++# ++# Ciphers ++# ++CONFIG_CRYPTO_AES=y ++# CONFIG_CRYPTO_ANUBIS is not set ++CONFIG_CRYPTO_ARC4=y ++# 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 is not set ++# CONFIG_CRYPTO_FCRYPT is not set ++# CONFIG_CRYPTO_KHAZAD is not set ++# CONFIG_CRYPTO_SALSA20 is not set ++# CONFIG_CRYPTO_CHACHA20 is not set ++# CONFIG_CRYPTO_SEED is not set ++# CONFIG_CRYPTO_SERPENT is not set ++# CONFIG_CRYPTO_TEA is not set ++CONFIG_CRYPTO_TWOFISH=y ++CONFIG_CRYPTO_TWOFISH_COMMON=y ++ ++# ++# Compression ++# ++# CONFIG_CRYPTO_DEFLATE is not set ++# CONFIG_CRYPTO_ZLIB is not set ++CONFIG_CRYPTO_LZO=y ++# CONFIG_CRYPTO_842 is not set ++# CONFIG_CRYPTO_LZ4 is not set ++# CONFIG_CRYPTO_LZ4HC is not set ++# CONFIG_CRYPTO_ZSTD is not set ++ ++# ++# Random Number Generation ++# ++CONFIG_CRYPTO_ANSI_CPRNG=y ++CONFIG_CRYPTO_DRBG_MENU=y ++CONFIG_CRYPTO_DRBG_HMAC=y ++# CONFIG_CRYPTO_DRBG_HASH is not set ++# CONFIG_CRYPTO_DRBG_CTR is not set ++CONFIG_CRYPTO_DRBG=y ++CONFIG_CRYPTO_JITTERENTROPY=y ++CONFIG_CRYPTO_USER_API=y ++CONFIG_CRYPTO_USER_API_HASH=y ++CONFIG_CRYPTO_USER_API_SKCIPHER=y ++# CONFIG_CRYPTO_USER_API_RNG is not set ++# CONFIG_CRYPTO_USER_API_AEAD is not set ++CONFIG_CRYPTO_HASH_INFO=y ++CONFIG_CRYPTO_HW=y ++# CONFIG_CRYPTO_DEV_CCP is not set ++# CONFIG_CRYPTO_DEV_ROCKCHIP_V1 is not set ++# CONFIG_CRYPTO_DEV_ROCKCHIP_V2 is not set ++CONFIG_ASYMMETRIC_KEY_TYPE=y ++CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y ++CONFIG_PUBLIC_KEY_ALGO_RSA=y ++CONFIG_X509_CERTIFICATE_PARSER=y ++CONFIG_PKCS7_MESSAGE_PARSER=y ++# CONFIG_PKCS7_TEST_KEY is not set ++# CONFIG_SIGNED_PE_FILE_VERIFICATION is not set ++ ++# ++# Certificates for signature checking ++# ++CONFIG_SYSTEM_TRUSTED_KEYRING=y ++CONFIG_SYSTEM_TRUSTED_KEYS="" ++CONFIG_ARM64_CRYPTO=y ++CONFIG_CRYPTO_SHA1_ARM64_CE=y ++CONFIG_CRYPTO_SHA2_ARM64_CE=y ++CONFIG_CRYPTO_GHASH_ARM64_CE=y ++# CONFIG_CRYPTO_POLY_HASH_ARM64_CE is not set ++CONFIG_CRYPTO_AES_ARM64_CE=y ++CONFIG_CRYPTO_AES_ARM64_CE_CCM=y ++CONFIG_CRYPTO_AES_ARM64_CE_BLK=y ++# CONFIG_CRYPTO_AES_ARM64_NEON_BLK is not set ++# CONFIG_CRYPTO_CRC32_ARM64 is not set ++CONFIG_BINARY_PRINTF=y ++ ++# ++# Library routines ++# ++CONFIG_BITREVERSE=y ++CONFIG_HAVE_ARCH_BITREVERSE=y ++CONFIG_RATIONAL=y ++CONFIG_GENERIC_STRNCPY_FROM_USER=y ++CONFIG_GENERIC_STRNLEN_USER=y ++CONFIG_GENERIC_NET_UTILS=y ++CONFIG_GENERIC_PCI_IOMAP=y ++CONFIG_GENERIC_IO=y ++CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y ++CONFIG_CRC_CCITT=y ++CONFIG_CRC16=y ++CONFIG_CRC_T10DIF=y ++CONFIG_CRC_ITU_T=y ++CONFIG_CRC32=y ++# CONFIG_CRC32_SELFTEST is not set ++CONFIG_CRC32_SLICEBY8=y ++# CONFIG_CRC32_SLICEBY4 is not set ++# CONFIG_CRC32_SARWATE is not set ++# CONFIG_CRC32_BIT is not set ++CONFIG_CRC7=y ++CONFIG_LIBCRC32C=y ++# CONFIG_CRC8 is not set ++CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y ++# CONFIG_RANDOM32_SELFTEST is not set ++CONFIG_ZLIB_INFLATE=y ++CONFIG_LZO_COMPRESS=y ++CONFIG_LZO_DECOMPRESS=y ++CONFIG_LZ4_DECOMPRESS=y ++CONFIG_XZ_DEC=y ++# CONFIG_XZ_DEC_X86 is not set ++# CONFIG_XZ_DEC_POWERPC is not set ++# CONFIG_XZ_DEC_IA64 is not set ++CONFIG_XZ_DEC_ARM=y ++CONFIG_XZ_DEC_ARMTHUMB=y ++# CONFIG_XZ_DEC_SPARC is not set ++CONFIG_XZ_DEC_BCJ=y ++# CONFIG_XZ_DEC_TEST is not set ++CONFIG_DECOMPRESS_GZIP=y ++CONFIG_DECOMPRESS_BZIP2=y ++CONFIG_DECOMPRESS_LZMA=y ++CONFIG_DECOMPRESS_XZ=y ++CONFIG_DECOMPRESS_LZO=y ++CONFIG_DECOMPRESS_LZ4=y ++CONFIG_GENERIC_ALLOCATOR=y ++CONFIG_ASSOCIATIVE_ARRAY=y ++CONFIG_HAS_IOMEM=y ++CONFIG_HAS_DMA=y ++CONFIG_CPU_RMAP=y ++CONFIG_DQL=y ++CONFIG_NLATTR=y ++CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y ++CONFIG_CLZ_TAB=y ++# CONFIG_CORDIC is not set ++# CONFIG_DDR is not set ++CONFIG_MPILIB=y ++CONFIG_LIBFDT=y ++CONFIG_OID_REGISTRY=y ++# CONFIG_SG_SPLIT is not set ++CONFIG_ARCH_HAS_SG_CHAIN=y +-- +2.7.4 + + diff --git a/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0002-Added-ethernet-driver-support-for-LEC-PX30-A2.patch b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0002-Added-ethernet-driver-support-for-LEC-PX30-A2.patch new file mode 100644 index 000000000..e8f221db4 --- /dev/null +++ b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0002-Added-ethernet-driver-support-for-LEC-PX30-A2.patch @@ -0,0 +1,9584 @@ +From 67ca8500e5934cd7dfd1f837b3f38631aba8a67b Mon Sep 17 00:00:00 2001 +From: Katha Ashok <katha.ashok@adlinktech.com> +Date: Tue, 5 Nov 2019 11:33:29 +0530 +Subject: [PATCH 2/2] Added ethernet driver support for LEC-PX30 A2 + +--- + drivers/net/ethernet/Kconfig | 1 + + drivers/net/ethernet/Makefile | 1 + + drivers/net/ethernet/smsc9514/Kconfig | 25 + + drivers/net/ethernet/smsc9514/Makefile | 9 + + drivers/net/ethernet/smsc9514/ioctl_9500.h | 160 + + drivers/net/ethernet/smsc9514/smsc9500.c | 5918 ++++++++++++++++++++++++++++ + drivers/net/ethernet/smsc9514/smsc9500.h | 859 ++++ + drivers/net/ethernet/smsc9514/smscusbnet.c | 2157 ++++++++++ + drivers/net/ethernet/smsc9514/smscusbnet.h | 328 ++ + drivers/net/ethernet/smsc9514/version.h | 6 + + include/linux/usb.h | 2 + + 11 files changed, 9466 insertions(+) + create mode 100644 drivers/net/ethernet/smsc9514/Kconfig + create mode 100755 drivers/net/ethernet/smsc9514/Makefile + create mode 100755 drivers/net/ethernet/smsc9514/ioctl_9500.h + create mode 100755 drivers/net/ethernet/smsc9514/smsc9500.c + create mode 100755 drivers/net/ethernet/smsc9514/smsc9500.h + create mode 100755 drivers/net/ethernet/smsc9514/smscusbnet.c + create mode 100755 drivers/net/ethernet/smsc9514/smscusbnet.h + create mode 100755 drivers/net/ethernet/smsc9514/version.h + +diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig +index 31c5e47..b417916 100644 +--- a/drivers/net/ethernet/Kconfig ++++ b/drivers/net/ethernet/Kconfig +@@ -165,6 +165,7 @@ source "drivers/net/ethernet/sis/Kconfig" + source "drivers/net/ethernet/sfc/Kconfig" + source "drivers/net/ethernet/sgi/Kconfig" + source "drivers/net/ethernet/smsc/Kconfig" ++source "drivers/net/ethernet/smsc9514/Kconfig" + source "drivers/net/ethernet/stmicro/Kconfig" + source "drivers/net/ethernet/sun/Kconfig" + source "drivers/net/ethernet/synopsys/Kconfig" +diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile +index 071f84e..60701cd 100644 +--- a/drivers/net/ethernet/Makefile ++++ b/drivers/net/ethernet/Makefile +@@ -75,6 +75,7 @@ obj-$(CONFIG_NET_VENDOR_SIS) += sis/ + obj-$(CONFIG_SFC) += sfc/ + obj-$(CONFIG_NET_VENDOR_SGI) += sgi/ + obj-$(CONFIG_NET_VENDOR_SMSC) += smsc/ ++obj-$(CONFIG_NET_VENDOR_SMSC9514) += smsc9514/ + obj-$(CONFIG_NET_VENDOR_STMICRO) += stmicro/ + obj-$(CONFIG_NET_VENDOR_SUN) += sun/ + obj-$(CONFIG_NET_VENDOR_SYNOPSYS) += synopsys/ +diff --git a/drivers/net/ethernet/smsc9514/Kconfig b/drivers/net/ethernet/smsc9514/Kconfig +new file mode 100644 +index 0000000..2d8b513 +--- /dev/null ++++ b/drivers/net/ethernet/smsc9514/Kconfig +@@ -0,0 +1,25 @@ ++# ++# SMSC95XX USB to Ethernet controller device configuration ++# ++ ++menuconfig NET_VENDOR_SMSC9514 ++ tristate 'LAN 9514 driver configuration' ++ help ++ This enables SMSC95XX USB to Ethernet controller board specific character ++ devices. ++ ++if NET_VENDOR_SMSC9514 ++ ++config SMSC9500 ++ tristate "SMSC 9500 module" ++ help ++ This driver is required for smsc9500 module. ++ ++config SMSCUSBNET ++ tristate "SMSCUSBNET module" ++ help ++ This driver is required for smsc usb net module. ++ ++endif # NET_VENDOR_SMSC9514 ++ ++ +diff --git a/drivers/net/ethernet/smsc9514/Makefile b/drivers/net/ethernet/smsc9514/Makefile +new file mode 100755 +index 0000000..80e9fb5 +--- /dev/null ++++ b/drivers/net/ethernet/smsc9514/Makefile +@@ -0,0 +1,9 @@ ++obj-$(CONFIG_SMSC9500) += smsc9500.o ++obj-$(CONFIG_SMSCUSBNET) += smscusbnet.o ++ ++ ++ ++ ++ ++ ++ +diff --git a/drivers/net/ethernet/smsc9514/ioctl_9500.h b/drivers/net/ethernet/smsc9514/ioctl_9500.h +new file mode 100755 +index 0000000..9b293c4 +--- /dev/null ++++ b/drivers/net/ethernet/smsc9514/ioctl_9500.h +@@ -0,0 +1,160 @@ ++#ifndef IOCTL_9500_H_ ++#define IOCTL_9500_H_ ++ ++/*************************************************************************** ++ * ++ * Copyright (C) 2008-2009 SMSC ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ *************************************************************************** ++ * File: ioctl_500.h ++ */ ++ ++#define SMSC9500_DRIVER_SIGNATURE (0x82745BACUL+DRIVER_VERSION) ++#define SMSC9500_APP_SIGNATURE (0x987BEF28UL+DRIVER_VERSION) ++ ++#define SMSC9500_IOCTL (SIOCDEVPRIVATE + 0xB) ++#define MAX_EEPROM_SIZE 512 ++ ++enum { ++ COMMAND_BASE = 0x974FB832UL, ++ COMMAND_GET_SIGNATURE, ++ COMMAND_LAN_GET_REG, ++ COMMAND_LAN_SET_REG, ++ COMMAND_MAC_GET_REG, ++ COMMAND_MAC_SET_REG, ++ COMMAND_PHY_GET_REG, ++ COMMAND_PHY_SET_REG, ++ COMMAND_DUMP_LAN_REGS, ++ COMMAND_DUMP_MAC_REGS, ++ COMMAND_DUMP_PHY_REGS, ++ COMMAND_DUMP_EEPROM, ++ COMMAND_GET_MAC_ADDRESS, ++ COMMAND_SET_MAC_ADDRESS, ++ COMMAND_LOAD_MAC_ADDRESS, ++ COMMAND_SAVE_MAC_ADDRESS, ++ COMMAND_SET_DEBUG_MODE, ++ COMMAND_SET_POWER_MODE, ++ COMMAND_GET_POWER_MODE, ++ COMMAND_SET_LINK_MODE, ++ COMMAND_GET_LINK_MODE, ++ COMMAND_SET_LINK_STATUS, ++ COMMAND_GET_LINK_STATUS, ++ COMMAND_GET_CONFIGURATION, ++ COMMAND_DUMP_TEMP, ++ COMMAND_READ_BYTE, ++ COMMAND_READ_WORD, ++ COMMAND_READ_DWORD, ++ COMMAND_WRITE_BYTE, ++ COMMAND_WRITE_WORD, ++ COMMAND_WRITE_DWORD, ++ COMMAND_CHECK_LINK, ++ COMMAND_GET_ERRORS, ++ COMMAND_SET_EEPROM, ++ COMMAND_GET_EEPROM, ++ COMMAND_WRITE_EEPROM_FROM_FILE, ++ COMMAND_WRITE_EEPROM_TO_FILE, ++ COMMAND_VERIFY_EEPROM_WITH_FILE, ++ ++ /*The following codes are intended for cmd9500 only ++ They are not intended to have any use in the driver */ ++ ++ COMMAND_RUN_SERVER, ++ COMMAND_RUN_TUNER, ++ COMMAND_GET_FLOW_PARAMS, ++ COMMAND_SET_FLOW_PARAMS, ++ COMMAND_SET_AMDIX_STS, ++ COMMAND_GET_AMDIX_STS, ++ COMMAND_SET_EEPROM_BUFFER ++}; ++ ++enum { ++ LAN_REG_ID_REV, ++ LAN_REG_FPGA_REV, ++ LAN_REG_INT_STS, ++ LAN_REG_RX_CFG, ++ LAN_REG_TX_CFG, ++ LAN_REG_HW_CFG, ++ LAN_REG_RX_FIFO_INF, ++ LAN_REG_TX_FIFO_INF, ++ LAN_REG_PMT_CTRL, ++ LAN_REG_LED_GPIO_CFG, ++ LAN_REG_GPIO_CFG, ++ LAN_REG_AFC_CFG, ++ LAN_REG_E2P_CMD, ++ LAN_REG_E2P_DATA, ++ LAN_REG_BURST_CAP, ++ LAN_REG_STRAP_DBG, ++ LAN_REG_DP_SEL, ++ LAN_REG_DP_CMD, ++ LAN_REG_DP_ADDR, ++ LAN_REG_DP_DATA0, ++ LAN_REG_DP_DATA1, ++ LAN_REG_GPIO_WAKE, ++ LAN_REG_INT_EP_CTL, ++ LAN_REG_BULK_IN_DLY, ++ MAX_LAN_REG_NUM ++}; ++ ++enum { ++ MAC_REG_MAC_CR, ++ MAC_REG_ADDRH, ++ MAC_REG_ADDRL, ++ MAC_REG_HASHH, ++ MAC_REG_HASHL, ++ MAC_REG_MII_ADDR, ++ MAC_REG_MII_DATA, ++ MAC_REG_FLOW, ++ MAC_REG_VLAN1, ++ MAC_REG_VLAN2, ++ MAC_REG_WUFF, ++ MAC_REG_WUCSR, ++ MAC_REG_COE_CR, ++ MAX_MAC_REG_NUM ++}; ++ ++enum { ++ PHY_REG_BCR, ++ PHY_REG_BSR, ++ PHY_REG_ID1, ++ PHY_REG_ID2, ++ PHY_REG_ANEG_ADV, ++ PHY_REG_ANEG_LPA, ++ PHY_REG_ANEG_ER, ++ PHY_REG_SILICON_REV, ++ PHY_REG_MODE_CTRL_STS, ++ PHY_REG_SPECIAL_MODES, ++ PHY_REG_TSTCNTL, ++ PHY_REG_TSTREAD1, ++ PHY_REG_TSTREAD2, ++ PHY_REG_TSTWRITE, ++ PHY_REG_SPECIAL_CTRL_STS, ++ PHY_REG_SITC, ++ PHY_REG_INT_SRC, ++ PHY_REG_INT_MASK, ++ PHY_REG_SPECIAL, ++ MAX_PHY_REG_NUM ++}; ++ ++typedef struct _SMSC9500_IOCTL_DATA { ++ unsigned long dwSignature; ++ unsigned long dwCommand; ++ unsigned long Data[526]; ++ char Strng1[30]; ++ char Strng2[10]; ++} SMSC9500_IOCTL_DATA, *PSMSC9500_IOCTL_DATA; ++ ++#endif /*IOCTL_9500_H_*/ +diff --git a/drivers/net/ethernet/smsc9514/smsc9500.c b/drivers/net/ethernet/smsc9514/smsc9500.c +new file mode 100755 +index 0000000..3e17b83 +--- /dev/null ++++ b/drivers/net/ethernet/smsc9514/smsc9500.c +@@ -0,0 +1,5918 @@ ++ /* ++ * Copyright (C) 2007-2008 SMSC ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ *************************************************************************** ++ * File: smsc9500.c ++ ***************************************************************************/ ++ ++#ifndef __KERNEL__ ++#define __KERNEL__ ++#endif ++ ++#include <linux/version.h> ++#include <linux/module.h> ++#include <linux/moduleparam.h> ++#include <linux/module.h> ++#include <linux/kmod.h> ++#include <linux/sched.h> ++#include <linux/init.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/ethtool.h> ++#include <linux/workqueue.h> ++#include <linux/mii.h> ++#include <linux/usb.h> ++#include <linux/crc32.h> ++#include <linux/ioport.h> ++#include <asm/io.h> ++#include <linux/mm.h> ++#include "version.h" ++#include "smscusbnet.h" ++#include "smsc9500.h" ++#include "ioctl_9500.h" ++ ++//#define PME_EEPROMLESS ++ ++#ifndef bool ++#define bool int ++#endif ++ ++#define CHECK_RETURN_STATUS(A) \ ++ { \ ++ if((A) < 0) \ ++ { \ ++ SMSC_WARNING("Failure in %s(), line: %d\n", __FUNCTION__,__LINE__); \ ++ goto DONE; \ ++ } \ ++ } ++ ++unsigned int debug_mode = DBG_WARNING | DBG_LINK_CHANGE; ++module_param(debug_mode, uint, 0); ++MODULE_PARM_DESC(debug_mode,"bit 0 enables trace points, bit 1 enables warning points, bit 2 enables eth gpios, bit 3 enables gen gpios"); ++ ++u32 link_mode=0x7fUL; ++module_param(link_mode, uint, 0); ++MODULE_PARM_DESC(link_mode,"Set Link speed and Duplex, 1=10HD,2=10FD,4=100HD,8=100FD,default=0x7F"); ++ ++u32 auto_mdix=0x2U;//0x3U ++module_param(auto_mdix, uint, 0); ++MODULE_PARM_DESC(auto_mdix,"Set Auto-MDIX state, 0=StraightCable,1=CrossOver,2=Enable AMDIX,3=controlled by Strap"); ++ ++u32 mac_addr_hi16=0xFFFFFFFFUL; ++module_param(mac_addr_hi16, uint, 0); ++MODULE_PARM_DESC(mac_addr_hi16,"Specifies the high 16 bits of the mac address"); ++ ++u32 mac_addr_lo32=0xFFFFFFFFUL; ++module_param(mac_addr_lo32, uint, 0); ++MODULE_PARM_DESC(mac_addr_lo32,"Specifies the low 32 bits of the mac address"); ++ ++u32 phy_addr=0xFFFFFFFFUL; ++module_param(phy_addr, uint, 0); ++MODULE_PARM_DESC(phy_addr,"phy_addr, only valid if it is external phy set by strap; 0-31=external phy with specified address, else autodetect external phy addr"); ++ ++bool tx_Csum=FALSE; ++module_param(tx_Csum,bool, 0); ++MODULE_PARM_DESC(tx_Csum,"Enable Tx Hardware Checksum Offload"); ++ ++bool rx_Csum=FALSE; ++module_param(rx_Csum,bool, 0); ++MODULE_PARM_DESC(tx_Csum,"Enable Rx Hardware Checksum Offload"); ++ ++u32 bulkin_delay=DEFAULT_BULK_IN_DELAY; ++module_param(bulkin_delay,uint, 0); ++MODULE_PARM_DESC(bulkin_delay,"16 bit value in units of 16ns to delay UTX sending data"); ++ ++bool LinkActLedCfg=TRUE; ++module_param(LinkActLedCfg,bool, 0); ++MODULE_PARM_DESC(LinkActLedCfg,"Enables separate Link and Activity LEDs in LAN9500A"); ++ ++u32 LinkLedOnGpio=11; ++module_param(LinkLedOnGpio, uint, 0); ++MODULE_PARM_DESC(LinkLedOnGpio,"Enable separate Link and Activity LEDs in LAN9500 and specifies gpio port for link status"); ++ ++u32 LinkLedBufType=0; ++module_param(LinkLedBufType, uint, 0); ++MODULE_PARM_DESC(LinkLedBufType,"Specifies gpio buffer type for link led"); ++ ++u32 LinkLedPolarity = 0; ++module_param(LinkLedPolarity, uint, 0); ++MODULE_PARM_DESC(LinkLedPolarity,"Specifies active level on gpio port"); ++ ++/* ++ linkdownsuspend = 0----> Disabled ++ linkdownsuspend = 1----> Enabled, wake up on auto-negotiation complete, device is in suspend0. ++ linkdownsuspend = 2----> Enabled, wake up on energy detection, device is in suspend1. ++*/ ++static uint linkdownsuspend=0; ++module_param(linkdownsuspend, uint, 0); ++MODULE_PARM_DESC(linkdownsuspend,"Suspend device when link is down"); ++ ++static u32 dynamicsuspend=0; ++module_param(dynamicsuspend,uint, 0); ++MODULE_PARM_DESC(dynamicsuspend,"Enable dynamic autosuspend mode"); ++ ++static u32 netdetach=0; ++module_param(netdetach,uint, 0); ++MODULE_PARM_DESC(netdetach,"Enable net detach mode, for LAN9500A only"); ++ ++u32 EDPDConfig=EDPD_CFG_DEFAULT; ++module_param(EDPDConfig, uint, 0); ++MODULE_PARM_DESC(EDPDConfig,"Set EDPD Config"); ++ ++u32 tx_skb_clone=TRUE; ++module_param(tx_skb_clone, uint, 0); ++MODULE_PARM_DESC(tx_skb_clone,"Set tx_skb_clone"); ++ ++u32 EnableEEE=0; ++module_param(EnableEEE, uint, 0); ++MODULE_PARM_DESC(EnableEEE,"Enable EEE"); ++ ++/* ++ MdioDisable: ++ bit 0: when set disables all internal access to phy ++ bit 1: when set disables IOCTL access to phy ++ when MdioDisable is set the auto-neg need to be disabled. ++ for 100FD, set link_mode=0x08UL; ++*/ ++u32 MdioDisable=0; ++module_param(MdioDisable, uint, 0); ++MODULE_PARM_DESC(MdioDisable,"MDIO Access control"); ++ ++/* MdioDefaultLinkStatus: (applicable only when MdioDisable bit 0 is set) ++ bit 0: When set report link down after initilization ++ When clear (default) report link up after initialization ++*/ ++u32 MdioDefaultLinkStatus=1; ++module_param(MdioDefaultLinkStatus, uint, 0); ++MODULE_PARM_DESC(MdioDefaultLinkStatus,"Default link status reporting when MdioDisable bit 0 is set"); ++ ++static int smsc9500_reset(struct usbnet *dev); ++static int smsc9500_get_stats(struct usbnet *dev, char *data); ++static int smsc9500_private_ioctl(PADAPTER_DATA privateData, struct usbnet *dev, PSMSC9500_IOCTL_DATA ioctlData); ++static int smsc9500_device_recovery(struct usbnet *dev); ++static int SetGpo(struct usbnet * dev, u32 Gpo, u32 State); ++static int Smsc9500_suspend (struct usb_interface *intf, pm_message_t state); ++static int Smsc9500SystemSuspend (struct usb_interface *intf, pm_message_t state); ++static int Smsc9500AutoSuspend (struct usb_interface *intf, pm_message_t state); ++static int Smsc9500SystemResume(struct usb_interface *intf); ++static u16 CalculateCrc16(const BYTE * bpData,const u32 dwLen, const BOOLEAN fBitReverse); ++static int SetLinkDownWakeupEvents(struct usbnet *dev, int wakeUpMode); ++static int ResetLinkDownWakeupEvents(struct usbnet *dev); ++static int Smsc9500AutoResume(struct usb_interface *intf); ++static int EnablePHYWakeupInterrupt(struct usbnet *dev, u32 interrupt); ++static int DisablePHYWakeupInterrupt(struct usbnet *dev, u32 interrupt); ++static int smsc9500_eth_mac_addr(struct net_device *netdev, void *p); ++static int smsc9500_eth_phy_boost(struct usbnet *dev, int mode); ++#ifdef PME_EEPROMLESS ++static int EepromLessPMESetting(struct usbnet *dev); ++#endif ++ ++static u32 LanRegMap[MAX_LAN_REG_NUM]; ++static u32 MacRegMap[MAX_MAC_REG_NUM]; ++static u32 PhyRegMap[MAX_PHY_REG_NUM]; ++ ++enum{ ++ SMSC9500_FAIL = -1, ++ SMSC9500_SUCCESS = 0 ++}; ++ ++static int smsc9500_read_reg(struct usbnet *dev, u32 index, u32 *data) ++{ ++ int ret = 0; ++ u32 *buf = NULL; ++ u16 retry_count = 0; ++ ++ BUG_ON(!dev); ++ ++ /* The heap buffer should be used for usb_control_msg, because the stack might not be DMA-mappable ++ Control message is very slow so it really isn't big deal to dynamically allocate the data ++ */ ++ buf = kmalloc (sizeof(u32), GFP_KERNEL | GFP_DMA); ++ if(buf == NULL) { ++ return SMSC9500_FAIL; ++ } ++ ++ do { ++ if (dev->disconnected) { ++ ret = -1; ++ break; ++ } ++ ++ ret = usb_control_msg( ++ dev->udev, ++ usb_rcvctrlpipe(dev->udev, 0), ++ USB_VENDOR_REQUEST_READ_REGISTER, ++ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, ++ 00, ++ index, ++ (void*)buf, ++ sizeof(u32), ++ USB_CTRL_GET_TIMEOUT); ++ } while((ret < 0) && (retry_count++ < 3)); ++ ++ if (ret < 0) { ++ SMSC_WARNING("Failed to read register index 0x%08x\n", index); ++ } else { ++ le32_to_cpus(buf); ++ *data = *buf; ++ } ++ kfree(buf); ++ return ret; ++} ++ ++static int smsc9500_write_reg(struct usbnet *dev, u32 index, u32 data) ++{ ++ int ret = 0; ++ u32* buf = NULL; ++ u16 retry_count = 0; ++ ++ BUG_ON(!dev); ++ ++ /* The heap buffer should be used for usb_control_msg, because the stack might not be DMA-mappable ++ Control message is very slow so it really isn't big deal to dynamically allocate the data ++ */ ++ buf = kmalloc (sizeof(u32), GFP_KERNEL | GFP_DMA); ++ if(buf == NULL) { ++ return SMSC9500_FAIL; ++ } ++ *buf = data; ++ ++ cpu_to_le32s(buf); ++ ++ do{ ++ if (dev->disconnected) { ++ ret = -1; ++ break; ++ } ++ ret = usb_control_msg( ++ dev->udev, ++ usb_sndctrlpipe(dev->udev, 0), ++ USB_VENDOR_REQUEST_WRITE_REGISTER, ++ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, ++ 00, ++ index, ++ buf, ++ sizeof(u32), ++ USB_CTRL_SET_TIMEOUT); ++ } while((ret < 0) && (retry_count++ < 3)); ++ ++ if (ret < 0) { ++ SMSC_WARNING("Failed to write register index 0x%08x\n", index); ++ } ++ kfree(buf); ++ return ret; ++} ++ ++static int smsc9500_set_feature(struct usbnet *dev, u32 feature) ++{ ++ BUG_ON(!dev); ++ ++ cpu_to_le32s((u32*)&feature); ++ ++ return usb_control_msg( ++ dev->udev, ++ usb_sndctrlpipe(dev->udev, 0), ++ USB_REQ_SET_FEATURE, ++ USB_RECIP_DEVICE, ++ feature, ++ 0, ++ NULL, ++ 0, ++ USB_CTRL_SET_TIMEOUT); ++} ++ ++static int smsc9500_clear_feature(struct usbnet *dev, u32 feature) ++{ ++ BUG_ON(!dev); ++ ++ cpu_to_le32s((u32*)&feature); ++ ++ return usb_control_msg( ++ dev->udev, ++ usb_sndctrlpipe(dev->udev, 0), ++ USB_REQ_CLEAR_FEATURE, ++ USB_RECIP_DEVICE, ++ feature, ++ 0, ++ NULL, ++ 0, ++ USB_CTRL_SET_TIMEOUT); ++} ++ ++static int smsc9500_read_phy(struct usbnet *dev, u32 Register, u32 *pValue32) ++{ ++ int ret = SMSC9500_FAIL; ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ u32 dwValue,dwAddr; ++ int Count; ++ ++ BUG_ON(!dev); ++ ++ if (MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS) { ++ SMSC_WARNING ("smsc9500_read_phy: Phy (mdio) access disabled\n"); ++ return ret; ++ } ++ ++ if (down_interruptible(&adapterData->phy_mutex)) { ++ return -EINTR; ++ } ++ ++ /* confirm MII not busy */ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, MII_ADDR, &dwValue)); ++ ++ if ((dwValue & MII_BUSY_) != 0UL){ ++ SMSC_WARNING("MII is busy in smsc9500_read_phy\n"); ++ goto DONE; ++ } ++ ++ /* set the address, index & direction (read from PHY) */ ++ dwAddr = ((adapterData->dwPhyAddress & 0x1FUL) << 11) | ((Register & 0x1FUL) << 6)| MII_READ_ | MII_BUSY_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, MII_ADDR, dwAddr)); ++ ++ /* Loop until the read is completed w/timeout */ ++ for(Count = 1; Count < 100; Count++) { ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, MII_ADDR, &dwValue)); ++ if (!(dwValue & MII_BUSY_)) ++ break; ++ udelay(1); ++ } ++ ++ if (Count < 100) { ++ ret = smsc9500_read_reg(dev, MII_DATA, pValue32); ++ } else { ++ SMSC_WARNING("Timed out reading MII register %08X\n",Register & 0x1f); ++ } ++DONE: ++ up(&adapterData->phy_mutex); ++ return ret; ++} ++ ++static int smsc9500_read_phy_address(struct usbnet *dev, u32 dwPhyAddress, u32 Register, u32 *pValue32) ++{ ++ int ret = SMSC9500_FAIL; ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ u32 dwValue,dwAddr; ++ int Count; ++ ++ BUG_ON(!dev); ++ ++ if (down_interruptible(&adapterData->phy_mutex)) { ++ return -EINTR; ++ } ++ ++ /* confirm MII not busy */ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, MII_ADDR, &dwValue)); ++ ++ if ((dwValue & MII_BUSY_) != 0UL) { ++ SMSC_WARNING("MII is busy in smsc9500_read_phy\n"); ++ goto DONE; ++ } ++ ++ /* set the address, index & direction (read from PHY) */ ++ dwAddr = ((dwPhyAddress & 0x1FUL) << 11) | ((Register & 0x1FUL) << 6)| MII_READ_ | MII_BUSY_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, MII_ADDR, dwAddr)); ++ ++ /* Loop until the read is completed w/timeout */ ++ for(Count = 1; Count < 100; Count++) { ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, MII_ADDR, &dwValue)); ++ if (!(dwValue & MII_BUSY_)) ++ break; ++ udelay(1); ++ } ++ ++ if (Count < 100) { ++ ret = smsc9500_read_reg(dev, MII_DATA, pValue32); ++ } else { ++ SMSC_WARNING ("Timed out reading MII register %08X\n",Register & 0x1f); ++ } ++DONE: ++ up(&adapterData->phy_mutex); ++ return ret; ++} ++ ++static int smsc9500_write_phy(struct usbnet *dev, u32 Register, u32 pValue32) ++{ ++ int Count; ++ u32 dwValue,dwAddr; ++ int ret = SMSC9500_FAIL; ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ BUG_ON(!dev); ++ ++ if (MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS) { ++ SMSC_WARNING ("smsc9500_write_phy: Phy (mdio) access disabled\n"); ++ return ret; ++ } ++ ++ if (down_interruptible(&adapterData->phy_mutex)) { ++ return -EINTR; ++ } ++ ++ if (Register == 0) { ++ if (((LOWORD(pValue32))&0x1200)==0x1200) { ++ adapterData->wLastADVatRestart = adapterData->wLastADV; ++ } ++ } ++ if (Register == 4) { ++ adapterData->wLastADV = LOWORD(pValue32); ++ } ++ ++ /* confirm MII not busy */ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, MII_ADDR, &dwValue)); ++ ++ if ((dwValue & MII_BUSY_) != 0UL) { ++ SMSC_WARNING ("MII is busy in smsc9500_read_phy\n"); ++ goto DONE; ++ } ++ ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, MII_DATA, pValue32)); ++ ++ /* set the address, index & direction (read from PHY) */ ++ dwAddr = ((adapterData->dwPhyAddress & 0x1FUL) << 11) | ((Register & 0x1FUL) << 6)| MII_WRITE_ | MII_BUSY_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, MII_ADDR, dwAddr)); ++ ++ /* Loop until the read is completed w/timeout */ ++ for(Count = 1; Count < 100; Count++) { ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, MII_ADDR, &dwValue)); ++ if(!(dwValue & MII_BUSY_)) ++ break; ++ udelay(1); ++ } ++ ++ if (Count < 100) { ++ ret = 0; ++ } else { ++ SMSC_WARNING("Timed out writing MII register %08X\n",Register & 0x1f); ++ } ++DONE: ++ up(&adapterData->phy_mutex); ++ return ret; ++} ++ ++static int smsc9500_write_phy_address(struct usbnet *dev, u32 dwPhyAddress, u32 Register, u32 pValue32) ++{ ++ int Count; ++ u32 dwValue,dwAddr; ++ int ret = SMSC9500_FAIL; ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ BUG_ON(!dev); ++ ++ if (down_interruptible(&adapterData->phy_mutex)) { ++ return -EINTR; ++ } ++ ++ if (Register == 0){ ++ if (((LOWORD(pValue32)) & 0x1200) == 0x1200) { ++ adapterData->wLastADVatRestart = adapterData->wLastADV; ++ } ++ } ++ if (Register == 4) { ++ adapterData->wLastADV = LOWORD(pValue32); ++ } ++ ++ /* confirm MII not busy */ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, MII_ADDR, &dwValue)); ++ ++ if ((dwValue & MII_BUSY_) != 0UL) { ++ SMSC_WARNING ("MII is busy in smsc9500_read_phy\n"); ++ goto DONE; ++ } ++ ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, MII_DATA, pValue32)); ++ ++ /* set the address, index & direction (read from PHY) */ ++ dwAddr = ((dwPhyAddress & 0x1FUL) << 11) | ((Register & 0x1FUL) << 6)| MII_WRITE_ | MII_BUSY_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, MII_ADDR, dwAddr)); ++ ++ /* Loop until the read is completed w/timeout */ ++ for(Count = 1; Count <100; Count++) { ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, MII_ADDR, &dwValue)); ++ if (!(dwValue & MII_BUSY_)) ++ break; ++ udelay(1); ++ } ++ ++ if (Count < 100) { ++ ret = 0; ++ } else { ++ SMSC_WARNING("Timed out writing MII register %08X\n",Register & 0x1f); ++ } ++DONE: ++ up(&adapterData->phy_mutex); ++ return ret; ++} ++ ++static int smsc9500_eeprom_IsBusy(struct usbnet *dev) ++{ ++ int Count, retVal = 0; ++ u32 dwValue; ++ ++ BUG_ON(!dev); ++ ++ for(Count = 0; Count < 1000; Count++) { ++ if(smsc9500_read_reg(dev, E2P_CMD, &dwValue) < 0) { ++ return SMSC9500_FAIL; ++ } ++ if (!(dwValue & E2P_CMD_BUSY_) || (dwValue & E2P_CMD_TIMEOUT_)) { ++ break; ++ } ++ udelay(60); ++ } ++ ++ if ((dwValue & E2P_CMD_TIMEOUT_) || (dwValue & E2P_CMD_BUSY_)) { ++ SMSC_WARNING("EEPROM read operation timeout"); ++ retVal = SMSC9500_FAIL; ++ } ++ ++ return retVal; ++} ++ ++/* Read EEPROM data ++ */ ++static int smsc9500_read_eeprom(struct usbnet *dev, u32 dwOffset, u32 dwLength, BYTE* pbValue) ++{ ++ int i, ret = SMSC9500_FAIL; ++ u32 dwValue,dwAddr; ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ BUG_ON(!dev); ++ BUG_ON(!pbValue); ++ ++ if(down_interruptible(&adapterData->eeprom_mutex)) { ++ return -EINTR; ++ } ++ ++ /* confirm eeprom not busy */ ++ CHECK_RETURN_STATUS(smsc9500_eeprom_IsBusy(dev)); ++ ++ dwAddr = dwOffset; ++ for(i = 0; i < dwLength; i++) { ++ /* Isuue command */ ++ dwValue = E2P_CMD_BUSY_ | E2P_CMD_READ_ | (dwAddr & E2P_CMD_ADDR_); ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, E2P_CMD, dwValue)); ++ CHECK_RETURN_STATUS(smsc9500_eeprom_IsBusy(dev)); ++ ++ /* Read data when ready */ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, E2P_DATA, &dwValue)); ++ ++ pbValue[i] = dwValue & 0xFF; ++ dwAddr++; ++ } ++ ret = SMSC9500_SUCCESS; ++DONE: ++ up(&adapterData->eeprom_mutex); ++ return ret; ++ ++} ++ ++static int smsc9500_do_write_eeprom(struct usbnet *dev, u32 dwOffset, u32 dwLength, BYTE* pbValue) ++{ ++ int i, ret = SMSC9500_FAIL; ++ u32 dwValue,dwAddr; ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ BUG_ON(!dev); ++ BUG_ON(!pbValue); ++ ++ if (down_interruptible(&adapterData->eeprom_mutex)) { ++ return -EINTR; ++ } ++ ++ /* confirm eeprom not busy */ ++ CHECK_RETURN_STATUS(smsc9500_eeprom_IsBusy(dev)); ++ ++ /* Iuuse write/erase enable command */ ++ dwValue = E2P_CMD_BUSY_ | E2P_CMD_EWEN_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, E2P_CMD, dwValue)); ++ CHECK_RETURN_STATUS(smsc9500_eeprom_IsBusy(dev)); ++ ++ dwAddr = dwOffset; ++ for(i = 0; i < dwLength; i++) { ++ /* Fill data register */ ++ dwValue = pbValue[i]; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, E2P_DATA, dwValue)); ++ ++ /* Send "write" command */ ++ dwValue = E2P_CMD_BUSY_ | E2P_CMD_WRITE_ | (dwAddr & E2P_CMD_ADDR_); ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, E2P_CMD, dwValue)); ++ CHECK_RETURN_STATUS(smsc9500_eeprom_IsBusy(dev)); ++ dwAddr++; ++ } ++ ret = SMSC9500_SUCCESS; ++DONE: ++ up(&adapterData->eeprom_mutex); ++ return ret; ++ ++} ++ ++static int smsc9500_write_eeprom(struct usbnet *dev, u32 dwOffset, u32 dwLength, BYTE* pbValue) ++{ ++ u32 dwValue; ++ int i, retries = 10; ++ ++ for (i = 0; i < retries; i++) { ++ if (smsc9500_do_write_eeprom(dev, dwOffset, dwLength, pbValue) == SMSC9500_SUCCESS) ++ return SMSC9500_SUCCESS; ++ } ++ mdelay(100); ++ if ((smsc9500_eeprom_IsBusy(dev) != 0) && (smsc9500_read_reg(dev,ID_REV, &dwValue)== 0)) ++ set_bit (EVENT_DEV_RECOVERY, &dev->flags); ++ return SMSC9500_FAIL; ++} ++ ++static int IsDataPortReady(struct usbnet *dev) ++{ ++ u32 dwValue; ++ int count = 0; ++ int ret = FALSE; ++ ++ /* confirm data port is not busy */ ++ for(count=0; count<100; count++){ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, DP_SEL, &dwValue)); ++ if (dwValue & DP_SEL_DPRDY) { ++ ret = TRUE; ++ break; ++ } ++ udelay(40); ++ } ++ ++ if (ret == FALSE) { ++ SMSC_WARNING("Data port is busy "); ++ } ++DONE: ++ return ret; ++} ++ ++/** Read data from internal RAM ++ */ ++static int ReadDataPort(struct usbnet *dev, int ramSel, u32 startAddr, u32 length, u32 *valLow, u32 *valHigh) ++{ ++ int i; ++ u32 dwValue; ++ int ret = SMSC9500_FAIL; ++ PADAPTER_DATA adapterData; ++ ++ BUG_ON(!dev); ++ adapterData = (PADAPTER_DATA)(dev->data[0]); ++ BUG_ON(!adapterData); ++ ++ if (down_interruptible(&adapterData->internal_ram_mutex)) { ++ return -EINTR; ++ } ++ ++ /* confirm data port not busy */ ++ if (!IsDataPortReady(dev)) ++ goto DONE; ++ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, DP_SEL, &dwValue)); ++ dwValue &= ~DP_SEL_RSEL; ++ switch(ramSel) { ++ case RAMSEL_FCT: ++ dwValue |= DP_SEL_RSEL_FCT; break; ++ case RAMSEL_EEPROM: ++ dwValue |= DP_SEL_RSEL_EEPROM; break; ++ case RAMSEL_TXTLI: ++ dwValue |= DP_SEL_RSEL_TXTLI; break; ++ case RAMSEL_RXTLI: ++ dwValue |= DP_SEL_RSEL_RXTLI; break; ++ } ++ dwValue |= DP_SEL_TESTEN; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, DP_SEL, dwValue)); ++ ++ for(i = 0; i < length; i++) { ++ /* Set device ram address */ ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, DP_ADDR, startAddr + i)); ++ /* Enable reading */ ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, DP_CMD, DP_CMD_READ)); ++ ++ if(!IsDataPortReady(dev)) ++ goto DONE; ++ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, DP_DATA0, valLow + i)); ++ if (valHigh) { ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, DP_DATA1, valHigh + i)); ++ } ++ } ++ ++ ret = SMSC9500_SUCCESS; ++DONE: ++ smsc9500_read_reg(dev, DP_SEL, &dwValue); ++ dwValue &= ~DP_SEL_TESTEN; ++ smsc9500_write_reg(dev, DP_SEL, dwValue); ++ ++ up(&adapterData->internal_ram_mutex); ++ return ret; ++} ++ ++/** ++ * smsc9500_is_zero_ether_addr - Determine if give Ethernet address is all zeros. ++ * @addr: Pointer to a six-byte array containing the Ethernet address ++ * ++ * Return true if the address is all zeroes. ++ */ ++static int smsc9500_is_zero_ether_addr(const u8 *addr) ++{ ++ return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]); ++} ++ ++/** ++ * smsc9500_is_multicast_ether_addr - Determine if the Ethernet address is a multicast. ++ * @addr: Pointer to a six-byte array containing the Ethernet address ++ * ++ * Return true if the address is a multicast address. ++ * By definition the broadcast address is also a multicast address. ++ */ ++static int smsc9500_is_multicast_ether_addr(const u8 *addr) ++{ ++ return (0x01 & addr[0]); ++} ++ ++/** ++ * smsc9500_is_valid_ether_addr - Determine if the given Ethernet address is valid ++ * @addr: Pointer to a six-byte array containing the Ethernet address ++ * ++ * Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not ++ * a multicast address, and is not FF:FF:FF:FF:FF:FF. ++ * ++ * Return true if the address is valid. ++ */ ++ ++static int smsc9500_is_valid_ether_addr(const u8 *addr) ++{ ++ /* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to ++ * explicitly check for it here. */ ++ return !smsc9500_is_multicast_ether_addr(addr) && !smsc9500_is_zero_ether_addr(addr); ++} ++ ++static void smsc9500_status(struct usbnet *dev, struct urb *urb) ++{ ++ int hasFrame; ++ struct smsc9500_int_data *event; ++ ++ BUG_ON(!dev); ++ BUG_ON(!urb); ++ ++ SMSC_TRACE(DBG_INTR, "smsc9500_status"); ++ ++ if (urb->actual_length < 4) { ++ SMSC_WARNING("urb->actual_length = %d", urb->actual_length); ++ return; ++ } ++ event = urb->transfer_buffer; ++ ++ le32_to_cpus((u32*)&event->IntEndPoint); ++ ++ SMSC_TRACE(DBG_INTR, "event->IntEndPoint = 0x%08x", event->IntEndPoint); ++ hasFrame = event->IntEndPoint &INT_END_RXFIFO_HAS_FRAME_; ++ ++ if (hasFrame) { ++ dev->StopSummitUrb=0; ++ tasklet_schedule (&dev->bh); ++ } ++} ++ ++ ++static int smsc9500_get_stats(struct usbnet *dev, char *data) ++{ ++ void* buf; ++ int ret = 0; ++ u16 retry_count = 0; ++ u16 RxStatSize = 0; ++ u16 TxStatSize = 0; ++ ++ BUG_ON(!dev); ++ BUG_ON(!data); ++ ++ SMSC_TRACE(DBG_RX, "smsc9500_get_stats"); ++ ++ buf = kmalloc (sizeof(SMSC9500_RX_STATS) + sizeof(SMSC9500_TX_STATS), GFP_KERNEL | GFP_DMA); ++ if (buf == NULL) { ++ return SMSC9500_FAIL; ++ } ++ ++ if (dev->chipDependFeatures[FEATURE_EEE]) { ++ RxStatSize = sizeof(SMSC9500_RX_STATS); ++ TxStatSize = sizeof(SMSC9500_TX_STATS); ++ }else{ ++ /* 20h for RX statistics. 28h for TX statistics */ ++ RxStatSize = sizeof(SMSC9500_RX_STATS) - 8; ++ TxStatSize = sizeof(SMSC9500_TX_STATS) - 8; ++ } ++ ++ do { ++ ret = usb_control_msg( ++ dev->udev, ++ usb_rcvctrlpipe(dev->udev, 0), ++ USB_VENDOR_REQUEST_GET_STATS, ++ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, ++ 00, ++ 0, ++ buf, ++ RxStatSize, ++ USB_CTRL_SET_TIMEOUT); ++ } while((ret < 0) && (retry_count++ < 3)); ++ ++ if (ret < 0) { ++ SMSC_WARNING("Failed to get Rx status\n"); ++ goto Done; ++ } ++ ++ retry_count = 0; ++ ++ do { ++ ret = usb_control_msg( ++ dev->udev, ++ usb_rcvctrlpipe(dev->udev, 0), ++ USB_VENDOR_REQUEST_GET_STATS, ++ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, ++ 00, ++ 1, ++ buf+sizeof(SMSC9500_RX_STATS), ++ TxStatSize, ++ USB_CTRL_SET_TIMEOUT); ++ } while((ret < 0) && (retry_count++ < 3)); ++ ++ if (ret < 0) { ++ SMSC_WARNING("Failed to get Tx status\n"); ++ } else { ++ memcpy(data, buf, (sizeof(SMSC9500_TX_STATS)+sizeof(SMSC9500_RX_STATS))); ++ } ++Done: ++ kfree(buf); ++ return ret; ++} ++ ++void UpdateStatCounters(struct usbnet *dev, char * pStats) ++{ ++ int i = 0; ++ u32 * pValue32 = (u32 *)pStats; ++ pSMSC9500_RX_STATS pRxStats; ++ pSMSC9500_TX_STATS pTxStats; ++ PADAPTER_DATA pAdapter = (PADAPTER_DATA)(dev->data[0]); ++ ++ for (i = 0; i < ((sizeof(SMSC9500_RX_STATS) + sizeof(SMSC9500_RX_STATS)) / 4); i++) { ++ le32_to_cpus((u32*)&pValue32[i]); ++ if ((i != 0)|| (i != 8) || (i != 9) || (i != 10) || (i != 20) || (i != 21)) ++ pValue32[i] &= 0xFFFFF; //This counter has 20 bits. ++ } ++ ++ pRxStats = (pSMSC9500_RX_STATS) pStats; ++ pTxStats = (pSMSC9500_TX_STATS) (pStats + sizeof(SMSC9500_RX_STATS)); ++ ++ if (dev->chipDependFeatures[FEATURE_NEWSTATIS_CNT]) { ++ // Good Tx (32Bit Counter) ++ if (pTxStats->TxGoodFrames >= pAdapter->tx_statistics.TxGoodFrames) ++ pAdapter->TxGoodFrames += (u64)(pTxStats->TxGoodFrames - pAdapter->tx_statistics.TxGoodFrames); ++ else ++ pAdapter->TxGoodFrames += (u64)(pTxStats->TxGoodFrames + (0xFFFFFFFFUL - pAdapter->tx_statistics.TxGoodFrames) + 1UL); ++ ++ pAdapter->tx_statistics.TxGoodFrames = pTxStats->TxGoodFrames; ++ ++ // Tx Excess Collisions (20Bit Counter) ++ if (pTxStats->TxExcessiveCollisionErrors >= pAdapter->tx_statistics.TxExcessiveCollisionErrors) ++ pAdapter->TxExcessiveCollisionErrors += (pTxStats->TxExcessiveCollisionErrors - pAdapter->tx_statistics.TxExcessiveCollisionErrors); ++ else ++ pAdapter->TxExcessiveCollisionErrors += (pTxStats->TxExcessiveCollisionErrors + (0xFFFFFUL - pAdapter->tx_statistics.TxExcessiveCollisionErrors) + 1UL); ++ ++ pAdapter->tx_statistics.TxExcessiveCollisionErrors = pTxStats->TxExcessiveCollisionErrors; ++ ++ // Tx Late Collisions (20Bit Counter) ++ if (pTxStats->TxLateCollisionErrors >= pAdapter->tx_statistics.TxLateCollisionErrors) ++ pAdapter->TxLateCollisionErrors += (pTxStats->TxLateCollisionErrors - pAdapter->tx_statistics.TxLateCollisionErrors); ++ else ++ pAdapter->TxLateCollisionErrors += (pTxStats->TxLateCollisionErrors + (0xFFFFFUL - pAdapter->tx_statistics.TxLateCollisionErrors) + 1UL); ++ ++ pAdapter->tx_statistics.TxLateCollisionErrors = pTxStats->TxLateCollisionErrors; ++ ++ // Tx Underrun (20Bit Counter) ++ if (pTxStats->TxBufferUnderrunErrors >= pAdapter->tx_statistics.TxBufferUnderrunErrors) ++ pAdapter->TxBufferUnderrunErrors += (pTxStats->TxBufferUnderrunErrors - pAdapter->tx_statistics.TxBufferUnderrunErrors); ++ else ++ pAdapter->TxBufferUnderrunErrors += (pTxStats->TxBufferUnderrunErrors + (0xFFFFFUL - pAdapter->tx_statistics.TxBufferUnderrunErrors) + 1UL); ++ ++ pAdapter->tx_statistics.TxBufferUnderrunErrors = pTxStats->TxBufferUnderrunErrors; ++ ++ // Tx Carrier Errors (20Bit Counter) ++ if (pTxStats->TxCarrierErrors >= pAdapter->tx_statistics.TxCarrierErrors) ++ pAdapter->TxCarrierErrors += (pTxStats->TxCarrierErrors - pAdapter->tx_statistics.TxCarrierErrors); ++ else ++ pAdapter->TxCarrierErrors += (pTxStats->TxCarrierErrors + (0xFFFFFUL - pAdapter->tx_statistics.TxCarrierErrors) + 1UL); ++ ++ pAdapter->tx_statistics.TxCarrierErrors = pTxStats->TxCarrierErrors; ++ ++ // Tx Single Collision (20Bit Counter) ++ if (pTxStats->TxSingleCollisions >= pAdapter->tx_statistics.TxSingleCollisions) ++ pAdapter->TxSingleCollisions += (pTxStats->TxSingleCollisions - pAdapter->tx_statistics.TxSingleCollisions); ++ else ++ pAdapter->TxSingleCollisions += (pTxStats->TxSingleCollisions + (0xFFFFFUL - pAdapter->tx_statistics.TxSingleCollisions) + 1UL); ++ ++ pAdapter->tx_statistics.TxSingleCollisions = pTxStats->TxSingleCollisions; ++ ++ // Tx Multiple Collision (20Bit Counter) ++ if (pTxStats->TxMultipleCollisions >= pAdapter->tx_statistics.TxMultipleCollisions) ++ pAdapter->TxMultipleCollisions += (pTxStats->TxMultipleCollisions - pAdapter->tx_statistics.TxMultipleCollisions); ++ else ++ pAdapter->TxMultipleCollisions += (pTxStats->TxMultipleCollisions + (0xFFFFFUL - pAdapter->tx_statistics.TxMultipleCollisions) + 1UL); ++ ++ pAdapter->tx_statistics.TxMultipleCollisions = pTxStats->TxMultipleCollisions; ++ ++ // Tx Excessive Deferral (20Bit Counter) ++ if (pTxStats->TxExcessiveDeferralErrors >= pAdapter->tx_statistics.TxExcessiveDeferralErrors) ++ pAdapter->TxExcessiveDeferralErrors += (pTxStats->TxExcessiveDeferralErrors - pAdapter->tx_statistics.TxExcessiveDeferralErrors); ++ else ++ pAdapter->TxExcessiveDeferralErrors += (pTxStats->TxExcessiveDeferralErrors + (0xFFFFFUL - pAdapter->tx_statistics.TxExcessiveDeferralErrors) + 1UL); ++ ++ pAdapter->tx_statistics.TxExcessiveDeferralErrors = pTxStats->TxExcessiveDeferralErrors; ++ ++ // Tx Pause (20Bit Counter) ++ if (pTxStats->TxPauseFrames >= pAdapter->tx_statistics.TxPauseFrames) ++ pAdapter->TxPauseFrames += (pTxStats->TxPauseFrames - pAdapter->tx_statistics.TxPauseFrames); ++ else ++ pAdapter->TxPauseFrames += (pTxStats->TxPauseFrames + (0xFFFFFUL - pAdapter->tx_statistics.TxPauseFrames) + 1UL); ++ ++ pAdapter->tx_statistics.TxPauseFrames = pTxStats->TxPauseFrames; ++ ++ // Tx Bad (20Bit Counter) ++ if (pTxStats->TxBadFrames >= pAdapter->tx_statistics.TxBadFrames) ++ pAdapter->TxBadFrames += (pTxStats->TxBadFrames - pAdapter->tx_statistics.TxBadFrames); ++ else ++ pAdapter->TxBadFrames += (pTxStats->TxBadFrames + (0xFFFFFUL - pAdapter->tx_statistics.TxBadFrames) + 1UL); ++ ++ pAdapter->tx_statistics.TxPauseFrames = pTxStats->TxPauseFrames; ++ ++ // Good Rx (32Bit Counter) ++ if (pRxStats->RxGoodFrames >= pAdapter->rx_statistics.RxGoodFrames) ++ pAdapter->RxGoodFrames += (u64)(pRxStats->RxGoodFrames - pAdapter->rx_statistics.RxGoodFrames); ++ else ++ pAdapter->RxGoodFrames += (u64)(pRxStats->RxGoodFrames + (0xFFFFFFFFUL - pAdapter->rx_statistics.RxGoodFrames) + 1UL); ++ ++ pAdapter->rx_statistics.RxGoodFrames = pRxStats->RxGoodFrames; ++ ++ // Rx Crc (20Bit Counter) ++ if (pRxStats->RxCrcErrors >= pAdapter->rx_statistics.RxCrcErrors) ++ pAdapter->RxCrcErrors += (pRxStats->RxCrcErrors - pAdapter->rx_statistics.RxCrcErrors); ++ else ++ pAdapter->RxCrcErrors += (pRxStats->RxCrcErrors + (0xFFFFFUL - pAdapter->rx_statistics.RxCrcErrors) + 1UL); ++ ++ pAdapter->rx_statistics.RxCrcErrors = pRxStats->RxCrcErrors; ++ ++ // Rx Alignment (20Bit Counter) ++ if (pRxStats->RxAlignmentErrors >= pAdapter->rx_statistics.RxAlignmentErrors) ++ pAdapter->RxAlignmentErrors += (pRxStats->RxAlignmentErrors - pAdapter->rx_statistics.RxAlignmentErrors); ++ else ++ pAdapter->RxAlignmentErrors += (pRxStats->RxAlignmentErrors + (0xFFFFFUL - pAdapter->rx_statistics.RxAlignmentErrors) + 1UL); ++ ++ pAdapter->rx_statistics.RxAlignmentErrors = pRxStats->RxAlignmentErrors; ++ ++ // Rx Resources (20Bit Counter) ++ if (pRxStats->RxFifoDroppedFrames >= pAdapter->rx_statistics.RxFifoDroppedFrames) ++ pAdapter->RxFifoDroppedFrames += (pRxStats->RxFifoDroppedFrames - pAdapter->rx_statistics.RxFifoDroppedFrames); ++ else ++ pAdapter->RxFifoDroppedFrames += (pRxStats->RxFifoDroppedFrames + (0xFFFFFUL - pAdapter->rx_statistics.RxFifoDroppedFrames) + 1UL); ++ ++ pAdapter->rx_statistics.RxFifoDroppedFrames = pRxStats->RxFifoDroppedFrames; ++ ++ // Rx Runts (20Bit Counter) ++ if (pRxStats->RxRuntFrameErrors >= pAdapter->rx_statistics.RxRuntFrameErrors) ++ pAdapter->RxRuntFrameErrors += (pRxStats->RxRuntFrameErrors - pAdapter->rx_statistics.RxRuntFrameErrors); ++ else ++ pAdapter->RxRuntFrameErrors += (pRxStats->RxRuntFrameErrors + (0xFFFFFUL - pAdapter->rx_statistics.RxRuntFrameErrors) + 1UL); ++ ++ pAdapter->rx_statistics.RxRuntFrameErrors = pRxStats->RxRuntFrameErrors; ++ ++ // Rx TooLong (20Bit Counter) ++ if (pRxStats->RxFrameTooLongError >= pAdapter->rx_statistics.RxFrameTooLongError) ++ pAdapter->RxFrameTooLongError += (pRxStats->RxFrameTooLongError - pAdapter->rx_statistics.RxFrameTooLongError); ++ else ++ pAdapter->RxFrameTooLongError += (pRxStats->RxFrameTooLongError + (0xFFFFFUL - pAdapter->rx_statistics.RxFrameTooLongError) + 1UL); ++ ++ pAdapter->rx_statistics.RxFrameTooLongError = pRxStats->RxFrameTooLongError; ++ ++ // Rx Late Collisions (20Bit Counter) ++ if (pRxStats->RxLaterCollisionError >= pAdapter->rx_statistics.RxLaterCollisionError) ++ pAdapter->RxLaterCollisionError += (pRxStats->RxLaterCollisionError - pAdapter->rx_statistics.RxLaterCollisionError); ++ else ++ pAdapter->RxLaterCollisionError += (pRxStats->RxLaterCollisionError + (0xFFFFFUL - pAdapter->rx_statistics.RxLaterCollisionError) + 1UL); ++ ++ pAdapter->rx_statistics.RxLaterCollisionError = pRxStats->RxLaterCollisionError; ++ ++ // Rx Bad (20Bit Counter) ++ if (pRxStats->RxBadFrames >= pAdapter->rx_statistics.RxBadFrames) ++ pAdapter->RxBadFrames += (pRxStats->RxBadFrames - pAdapter->rx_statistics.RxBadFrames); ++ else ++ pAdapter->RxBadFrames += (pRxStats->RxBadFrames + (0xFFFFFUL - pAdapter->rx_statistics.RxBadFrames) + 1UL); ++ ++ pAdapter->rx_statistics.RxBadFrames = pRxStats->RxBadFrames; ++ ++ if (dev->chipDependFeatures[FEATURE_EEE]) { ++ // EEE Tx LPI Transitions (32 bit) ++ if (pTxStats->EeeTxLpiTransitions >= pAdapter->tx_statistics.EeeTxLpiTransitions) { ++ pAdapter->EeeTxLpiTransitions += ++ (u64)(pTxStats->EeeTxLpiTransitions - pAdapter->tx_statistics.EeeTxLpiTransitions); ++ } else { ++ pAdapter->EeeTxLpiTransitions += ++ (u64)(pTxStats->EeeTxLpiTransitions + (0xFFFFFFFFUL - pAdapter->tx_statistics.EeeTxLpiTransitions) + 1UL); ++ } ++ ++ // EEE Tx LPI Time (32 bit) ++ if (pTxStats->EeeTxLpiTime >= pAdapter->tx_statistics.EeeTxLpiTime) { ++ pAdapter->EeeTxLpiTime += ++ (u64)(pTxStats->EeeTxLpiTime - pAdapter->tx_statistics.EeeTxLpiTime); ++ } else { ++ pAdapter->EeeTxLpiTime += ++ (u64)(pTxStats->EeeTxLpiTime + (0xFFFFFFFFUL - pAdapter->tx_statistics.EeeTxLpiTime) + 1UL); ++ } ++ ++ //EEE Rx LPI Transitions (32 bit) ++ if (pRxStats->EeeRxLpiTransitions >= pAdapter->rx_statistics.EeeRxLpiTransitions) { ++ pAdapter->EeeRxLpiTransitions += ++ (u64)(pRxStats->EeeRxLpiTransitions - pAdapter->rx_statistics.EeeRxLpiTransitions); ++ } else { ++ pAdapter->EeeRxLpiTransitions += ++ (u64)(pRxStats->EeeRxLpiTransitions + (0xFFFFFFFFUL - pAdapter->rx_statistics.EeeRxLpiTransitions) + 1UL); ++ } ++ ++ //EEE Rx LPI Time (32 bit) ++ if (pRxStats->EeeRxLpiTime >= pAdapter->rx_statistics.EeeRxLpiTime) { ++ pAdapter->EeeRxLpiTime += (u64)(pRxStats->EeeRxLpiTime - pAdapter->rx_statistics.EeeRxLpiTime); ++ } else { ++ pAdapter->EeeRxLpiTime += ++ (u64)(pRxStats->EeeRxLpiTime + (0xFFFFFFFFUL - pAdapter->rx_statistics.EeeRxLpiTime) + 1UL); ++ } ++ } ++ } else { ++ // Good Tx (32Bit Counter) ++ pAdapter->TxGoodFrames += (u64)pTxStats->TxGoodFrames; ++ ++ // Tx Excess Collisions (20Bit Counter) ++ pAdapter->TxExcessiveCollisionErrors += pTxStats->TxExcessiveCollisionErrors; ++ ++ // Tx Late Collisions (20Bit Counter) ++ pAdapter->TxLateCollisionErrors += pTxStats->TxLateCollisionErrors; ++ ++ // Tx Underrun (20Bit Counter) ++ pAdapter->TxBufferUnderrunErrors += pTxStats->TxBufferUnderrunErrors; ++ ++ // Tx Carrier Errors (20Bit Counter) ++ pAdapter->TxCarrierErrors += pTxStats->TxCarrierErrors; ++ ++ // Tx Single Collision (20Bit Counter) ++ pAdapter->TxSingleCollisions += pTxStats->TxSingleCollisions; ++ ++ // Tx Multiple Collision (20Bit Counter) ++ pAdapter->TxMultipleCollisions += pTxStats->TxMultipleCollisions; ++ ++ // Tx Excessive Deferral (20Bit Counter) ++ pAdapter->TxExcessiveDeferralErrors += pTxStats->TxExcessiveDeferralErrors; ++ ++ // Tx Pause (20Bit Counter) ++ pAdapter->TxPauseFrames += pTxStats->TxPauseFrames; ++ ++ // Tx Bad (20Bit Counter) ++ pAdapter->TxBadFrames += pTxStats->TxBadFrames; ++ ++ // Good Rx (32Bit Counter) ++ pAdapter->RxGoodFrames += (u64)pRxStats->RxGoodFrames; ++ ++ // Rx Crc (20Bit Counter) ++ pAdapter->RxCrcErrors += pRxStats->RxCrcErrors; ++ ++ // Rx Alignment (20Bit Counter) ++ pAdapter->RxAlignmentErrors += pRxStats->RxAlignmentErrors; ++ ++ // Rx Resources (20Bit Counter) ++ pAdapter->RxFifoDroppedFrames += pRxStats->RxFifoDroppedFrames; ++ ++ // Rx Runts (20Bit Counter) ++ pAdapter->RxRuntFrameErrors += pRxStats->RxRuntFrameErrors; ++ ++ // Rx TooLong (20Bit Counter) ++ pAdapter->RxFrameTooLongError += pRxStats->RxFrameTooLongError; ++ ++ // Rx Late Collisions (20Bit Counter) ++ pAdapter->RxLaterCollisionError += pRxStats->RxLaterCollisionError; ++ ++ // Rx Bad (20Bit Counter) ++ pAdapter->RxBadFrames += pRxStats->RxBadFrames; ++ } ++} ++ ++ ++static void smsc9500_async_cmd_callback(struct urb *urb, struct pt_regs *regs) ++{ ++ struct USB_CONTEXT *usb_context = (struct USB_CONTEXT *)urb->context; ++ ++ if (urb->status < 0) ++ SMSC_WARNING("smsc9500_async_cmd_callback() failed with %d\n",urb->status); ++ ++ complete((struct completion *)&usb_context->notify); ++ ++ kfree(&usb_context->req); ++ usb_free_urb(urb); ++} ++ ++static int ++smsc9500_read_reg_async(struct usbnet *dev, u32 index, void *data, int wait) ++{ ++ int status; ++ u32 size = 4; ++ struct urb *urb; ++ int ret = ASYNC_RW_SUCCESS; ++ struct USB_CONTEXT *usb_context; ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)) ++ int expire; ++#endif ++ ++ BUG_ON(!dev); ++ BUG_ON(!data); ++ ++ if ((urb = usb_alloc_urb(0, GFP_ATOMIC)) == NULL) { ++ SMSC_WARNING("Error allocating URB in write_cmd_async!"); ++ return ASYNC_RW_FAIL; ++ } ++ ++ if ((usb_context = kmalloc(sizeof(struct USB_CONTEXT), GFP_ATOMIC)) == NULL) { ++ SMSC_WARNING("Failed to allocate memory for control request"); ++ usb_free_urb(urb); ++ return ASYNC_RW_FAIL; ++ } ++ ++ usb_context->req.bRequestType = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE; ++ usb_context->req.bRequest = USB_VENDOR_REQUEST_READ_REGISTER; ++ usb_context->req.wValue = 00; ++ usb_context->req.wIndex = cpu_to_le32(index); ++ usb_context->req.wLength = cpu_to_le32(size); ++ init_completion(&usb_context->notify); ++ ++ usb_fill_control_urb(urb, dev->udev, ++ usb_rcvctrlpipe(dev->udev, 0), ++ (void *)&usb_context->req, data, size, ++ (usb_complete_t)smsc9500_async_cmd_callback, (void*)usb_context); ++ ++ if ((status = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { ++ SMSC_WARNING( "Error submitting the control message: status=%d", status); ++ kfree(usb_context); ++ usb_free_urb(urb); ++ return ASYNC_RW_FAIL; ++ } ++ ++ if (wait) { ++ /* wait_for_completion_timeout only implemented in 2.6.11 and higher kernel version */ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)) ++ expire = msecs_to_jiffies(USB_CTRL_SET_TIMEOUT); ++ if (!wait_for_completion_timeout(&usb_context->notify, expire)) { ++ ret = ASYNC_RW_TIMEOUT; ++ SMSC_TRACE(DBG_WARNING, "urb timeout"); ++ kfree(usb_context); ++ usb_free_urb(urb); ++ return ASYNC_RW_FAIL; ++ } ++#endif ++ } ++ return ret; ++} ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) ++extern void *page_address(struct page *); ++static void CalculateTxChecksumOffset( struct sk_buff *skb, int *csum_start_offset) ++{ ++ int i; ++ u32 offset; ++ unsigned int skbFragCnt; ++ ++ skbFragCnt = skb_shinfo(skb)->nr_frags + 1; ++ ++ /* Initialize csum offset locations as if it was single frag */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) ++ SMSC_ASSERT(skb->h.raw); ++#else ++ /* Should never happen for a CHECKSUM_HW packet */ ++ SMSC_ASSERT(skb->transport_header); ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) ++ *csum_start_offset = skb->h.raw - skb->data; ++#else ++ *csum_start_offset = (unsigned long)skb->transport_header - (unsigned long)skb->data; ++#endif ++ ++ offset = (skbFragCnt == 1) ? skb->len : (skb->len - skb->data_len); ++ ++ /* Process all fragments */ ++ for(i = 0; i < (skbFragCnt-1); i++) { ++ skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; ++ unsigned char *frag_addr = (unsigned char *) page_address(frag->page) + frag->page_offset; ++ ++ /* Find if transport header start belongs to this fragment ++ and if so calculate offset from start of packet */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) ++ if((frag_addr <= skb->h.raw) && ((frag_addr + frag->size) >=skb->h.raw)) { ++ *csum_start_offset = offset + ((u32)skb->h.raw) - ((u32)frag_addr); ++ } ++#else ++ if((frag_addr <= (unsigned char *)((unsigned long)skb->transport_header)) && ++ ((frag_addr + frag->size) >= (unsigned char *)((unsigned long)skb->transport_header))) { ++ *csum_start_offset = offset + ((unsigned long)skb->transport_header) - ((unsigned long)frag_addr); ++ } ++#endif ++ ++ SMSC_ASSERT((offset + frag->size) <= skb->len); ++ ++ offset += frag->size; ++ } ++ ++} ++#endif ++ ++static void Tx_StopQueue( ++ struct usbnet *dev,u32 dwSource) ++{ ++ unsigned long intFlags = 0; ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ spin_lock_irqsave(&(adapterData->TxQueueLock), intFlags); ++ if(adapterData->dwTxQueueDisableMask == 0) { ++ netif_stop_queue(dev->net); ++ } ++ adapterData->dwTxQueueDisableMask |= dwSource; ++ spin_unlock_irqrestore(&(adapterData->TxQueueLock), intFlags); ++} ++ ++static void Tx_WakeQueue( ++ struct usbnet *dev,u32 dwSource) ++{ ++ unsigned long intFlags = 0; ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ spin_lock_irqsave(&(adapterData->TxQueueLock), intFlags); ++ adapterData->dwTxQueueDisableMask&=(~dwSource); ++ if(adapterData->dwTxQueueDisableMask == 0) { ++ netif_wake_queue(dev->net); ++ } ++ spin_unlock_irqrestore(&(adapterData->TxQueueLock), intFlags); ++} ++ ++ ++int NICStartRxPath(struct usbnet *dev) ++{ ++ u32 Value32; ++ int Status = -1; ++ ++ /* Enable the receiver at the Mac */ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, MAC_CR, &Value32)); ++ Value32 |= MAC_CR_RXEN_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, MAC_CR, Value32)); ++ Status = 0; ++DONE: ++ return (Status); ++} ++ ++ ++ ++int NICStopRxPath(struct usbnet *dev) ++{ ++ int Status = -1; ++ u32 Value32, dwValue, Count = 0; ++ ++ /* Clr the Rx Stop bit if not already */ ++ dwValue = INT_STS_RX_STOP_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, INT_STS, dwValue)); ++ ++ /* Disable the receiver at the Mac */ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, MAC_CR, &Value32)); ++ Value32 &= (~MAC_CR_RXEN_); ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, MAC_CR, Value32)); ++ ++ ++ // The Rx Stop bit should assert as soon as the packet "in flight" makes ++ // it into the Mac, worst case is 10 Mbps HD. This will be ~2ms tops ++ // Assuming one register read per (micro)frame the case of high speed USB ++ // - 125us register read cycle time - is the worse and would need up to ++ // 16 reads. Let's just round up to 20. ++ do { ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, INT_STS, &Value32)); ++ // Let it try to do the 20 reads even if the reg reads are failing ++ // If the previous write did go thru at least this way we have a better ++ // chance of making sure the receiver did stop. ++ } while ((++Count<20) && ((Value32 & INT_STS_RX_STOP_) == 0)); ++ ++DONE: ++ return (Status); ++} ++ ++int NICStopAndFlushRxPath(struct usbnet *dev) ++{ ++ int Status = -1; ++ u32 Value32, dwValue; ++ ++ Status = NICStopRxPath(dev); ++ ++ dwValue = RX_FIFO_FLUSH_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, RX_CFG, dwValue)); ++ ++ /* Should self clear way before the read */ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, RX_CFG, &Value32)); ++ ++ if (Value32 & RX_FIFO_FLUSH_) { ++ // Flush did not self clear! ++ Status = -1; ++ } else { ++ Status = 0; ++ } ++DONE: ++ return (Status); ++} ++ ++ ++/* Returns hash bit number for given MAC address ++example: ++ 01 00 5E 00 00 01 -> returns bit number 31 ++*/ ++static u32 Rx_Hash(BYTE addr[6]) ++{ ++ int i; ++ u32 result = 0; ++ u32 crc = 0xFFFFFFFFUL; ++ u32 poly = 0xEDB88320UL; ++ for(i = 0; i < 6; i++) { ++ int bit; ++ u32 data = ((u32)addr[i]); ++ for(bit=0;bit<8;bit++) { ++ u32 p = (crc^((u32)data))&1UL; ++ crc >>= 1; ++ if(p != 0) crc ^= poly; ++ data >>= 1; ++ } ++ } ++ result=((crc&0x01UL)<<5)| ++ ((crc&0x02UL)<<3)| ++ ((crc&0x04UL)<<1)| ++ ((crc&0x08UL)>>1)| ++ ((crc&0x10UL)>>3)| ++ ((crc&0x20UL)>>5); ++ return result; ++} ++ ++static int smsc9500_rx_setmulticastlist(struct usbnet *dev) ++{ ++ u32 ret = SMSC9500_FAIL; ++ u32 local_MACCR, dwHashHi,dwHashLo; ++ ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ if ((dev->suspendFlag) || (dev->netDetachDone)) { ++ return 0; ++ } ++ ++ if (down_interruptible(&adapterData->RxFilterLock)) { ++ return -EINTR; ++ } ++ ++ SMSC_TRACE(DBG_MCAST, "smsc9500_set_multicast"); ++ ++ if (dev->net->flags & IFF_PROMISC) { ++ SMSC_TRACE(DBG_MCAST, "Promiscuous Mode Enabled"); ++ adapterData->set_bits_mask = MAC_CR_PRMS_; ++ adapterData->clear_bits_mask = (MAC_CR_MCPAS_ | MAC_CR_HPFILT_); ++ ++ adapterData->HashHi = 0UL; ++ adapterData->HashLo = 0UL; ++ goto PREPARE; ++ } ++ ++ if (dev->net->flags & IFF_ALLMULTI) { ++ SMSC_TRACE(DBG_MCAST, "Receive all Multicast Enabled"); ++ adapterData->set_bits_mask = MAC_CR_MCPAS_; ++ adapterData->clear_bits_mask = (MAC_CR_PRMS_ | MAC_CR_HPFILT_); ++ ++ adapterData->HashHi = 0UL; ++ adapterData->HashLo = 0UL; ++ goto PREPARE; ++ } ++ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)) ++ if (dev->net->mc_count > 0) { ++ u32 dwHashH = 0; ++ u32 dwHashL = 0; ++ u32 dwCount = 0; ++ struct dev_mc_list *mc_list = dev->net->mc_list; ++ ++ adapterData->set_bits_mask = MAC_CR_HPFILT_; ++ adapterData->clear_bits_mask = (MAC_CR_PRMS_ | MAC_CR_MCPAS_); ++ ++ while (mc_list != NULL) { ++ dwCount++; ++ if((mc_list->dmi_addrlen) == 6) { ++ u32 dwMask = 0x01UL; ++ u32 dwBitNum = Rx_Hash(mc_list->dmi_addr); ++ ++ dwMask <<= (dwBitNum&0x1FUL); ++ if (dwBitNum & 0x20UL) { ++ dwHashH |= dwMask; ++ } else { ++ dwHashL |= dwMask; ++ } ++ } else { ++ SMSC_WARNING("dmi_addrlen!=6"); ++ } ++ mc_list = mc_list->next; ++ } ++ if (dwCount != ((u32)(dev->net->mc_count))) { ++ SMSC_WARNING("dwCount != dev->net->mc_count"); ++ } ++ SMSC_TRACE(DBG_MCAST, "Multicast: HASHH = 0x%08X,HASHL = 0x%08X", dwHashH, dwHashL); ++ adapterData->HashHi = dwHashH; ++ adapterData->HashLo = dwHashL; ++ } ++#else ++ if( netdev_mc_count(dev->net)>0) { ++ u32 dwHashH = 0; ++ u32 dwHashL = 0; ++ u32 dwCount = 0; ++ struct netdev_hw_addr *ha; ++ ++ adapterData->set_bits_mask = MAC_CR_HPFILT_; ++ adapterData->clear_bits_mask = (MAC_CR_PRMS_ | MAC_CR_MCPAS_); ++ ++ netdev_for_each_mc_addr(ha, dev->net) { ++ u32 dwMask = 0x01UL; ++ u32 dwBitNum = Rx_Hash(ha->addr); ++ dwCount++; ++ ++ dwMask <<= (dwBitNum&0x1FUL); ++ if(dwBitNum & 0x20UL) { ++ dwHashH |= dwMask; ++ } else { ++ dwHashL |= dwMask; ++ } ++ } ++ if (dwCount != ((u32)netdev_mc_count(dev->net))) { ++ SMSC_WARNING("dwCount != netdev_mc_count(dev->net)"); ++ } ++ SMSC_TRACE(DBG_MCAST, "Multicast: HASHH = 0x%08X,HASHL = 0x%08X", dwHashH, dwHashL); ++ adapterData->HashHi = dwHashH; ++ adapterData->HashLo = dwHashL; ++ } ++#endif ++ else { ++ adapterData->set_bits_mask = 0L; ++ adapterData->clear_bits_mask = (MAC_CR_PRMS_ | MAC_CR_MCPAS_ | MAC_CR_HPFILT_); ++ ++ SMSC_TRACE(DBG_MCAST, "Receive own packets only"); ++ adapterData->HashHi = 0UL; ++ adapterData->HashLo = 0UL; ++ } ++ ++ ++PREPARE: ++ up(&adapterData->RxFilterLock); ++ ++ dwHashHi = adapterData->HashHi; ++ dwHashLo = adapterData->HashLo; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, HASHH, dwHashHi)); ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, HASHL, dwHashLo)); ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, MAC_CR, &local_MACCR)); ++ ++ local_MACCR |= adapterData->set_bits_mask; ++ local_MACCR &= ~(adapterData->clear_bits_mask); ++ ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, MAC_CR, local_MACCR)); ++ ++ SMSC_TRACE(DBG_MCAST, "smsc9500_set_multicast"); ++ ret = 0; ++DONE: ++ return ret; ++} ++ ++static void smsc9500_set_multicast(struct net_device *netdev) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ smscusbnet_defer_myevent(dev, EVENT_SET_MULTICAST); ++} ++ ++static int Phy_GetLinkMode(struct usbnet *dev) ++{ ++ u16 wRegBcr = 0; ++ int ret = SMSC9500_FAIL; ++ u16 wRegBSR, wRegLPA, WSpeedIndication; ++ u32 dwTemp, dwValue, result = LINK_OFF; ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ SMSC_TRACE(DBG_LINK, "Phy_GetLinkMode"); ++ ++ /* if mdio access disable return the initialized link speed */ ++ if (MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS) { ++ if (adapterData->DefaultLinkStatus & MDIO_DEFAULT_LINK_INIT_MASK) { ++ result = link_mode & (LINK_SPEED_10HD | LINK_SPEED_10FD | LINK_SPEED_100HD | LINK_SPEED_100FD); ++ adapterData->dwLinkSpeed = adapterData->dwLinkSettings = result; ++ } else { ++ adapterData->dwLinkSpeed = adapterData->dwLinkSettings = LINK_OFF; ++ } ++ return 0; ++ } ++ ++ /* Read PHY_BSR twice: link status bit is LL */ ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_BSR, &dwTemp)); ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_BSR, &dwTemp)); ++ ++ wRegBSR = LOWORD(dwTemp); ++ ++ adapterData->dwLinkSettings = LINK_OFF; ++ ++ if (wRegBSR&PHY_BSR_LINK_STATUS_) { ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_BCR, &dwValue)); ++ wRegBcr = LOWORD(dwValue); ++ ++ if (wRegBcr & PHY_BCR_AUTO_NEG_ENABLE_) { ++ u32 linkSettings = LINK_AUTO_NEGOTIATE; ++ u16 wRegADV = adapterData->wLastADVatRestart; ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_ANEG_LPA, &dwTemp)); ++ wRegLPA = LOWORD(dwTemp); ++ ++ if (wRegADV & PHY_ANEG_ADV_ASYMP_) { ++ linkSettings |= LINK_ASYMMETRIC_PAUSE; ++ } ++ if (wRegADV & PHY_ANEG_ADV_SYMP_) { ++ linkSettings |= LINK_SYMMETRIC_PAUSE; ++ } ++ if (wRegADV & PHY_ANEG_LPA_100FDX_) { ++ linkSettings |= LINK_SPEED_100FD; ++ } ++ if (wRegADV & PHY_ANEG_LPA_100HDX_) { ++ linkSettings |= LINK_SPEED_100HD; ++ } ++ if (wRegADV & PHY_ANEG_LPA_10FDX_) { ++ linkSettings |= LINK_SPEED_10FD; ++ } ++ if (wRegADV & PHY_ANEG_LPA_10HDX_) { ++ linkSettings |= LINK_SPEED_10HD; ++ } ++ adapterData->dwLinkSettings = linkSettings; ++ ++ wRegLPA &= wRegADV; ++ if(wRegLPA & PHY_ANEG_LPA_100FDX_) { ++ result = LINK_SPEED_100FD; ++ } else if(wRegLPA & PHY_ANEG_LPA_100HDX_) { ++ result = LINK_SPEED_100HD; ++ } else if(wRegLPA & PHY_ANEG_LPA_10FDX_) { ++ result = LINK_SPEED_10FD; ++ } else if(wRegLPA & PHY_ANEG_LPA_10HDX_) { ++ result = LINK_SPEED_10HD; ++ } ++ if (result == LINK_OFF) { ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_SPECIAL, &dwTemp)); ++ WSpeedIndication = LOWORD(dwTemp); ++ if ((WSpeedIndication & PHY_SPECIAL_SPD_)== PHY_SPECIAL_SPD_10HALF_) { ++ result = LINK_SPEED_10HD; ++ } else if ((WSpeedIndication & PHY_SPECIAL_SPD_)== PHY_SPECIAL_SPD_10FULL_) { ++ result = LINK_SPEED_10FD; ++ } else if ((WSpeedIndication & PHY_SPECIAL_SPD_)== PHY_SPECIAL_SPD_100HALF_) { ++ result = LINK_SPEED_100HD; ++ } else if ((WSpeedIndication & PHY_SPECIAL_SPD_)== PHY_SPECIAL_SPD_100FULL_) { ++ result = LINK_SPEED_100FD; ++ } ++ } ++ } else { ++ if (wRegBcr & PHY_BCR_SPEED_SELECT_) { ++ if (wRegBcr & PHY_BCR_DUPLEX_MODE_) { ++ adapterData->dwLinkSettings = result = LINK_SPEED_100FD; ++ } else { ++ adapterData->dwLinkSettings = result = LINK_SPEED_100HD; ++ } ++ } else { ++ if(wRegBcr & PHY_BCR_DUPLEX_MODE_) { ++ adapterData->dwLinkSettings = result = LINK_SPEED_10FD; ++ } else { ++ adapterData->dwLinkSettings = result = LINK_SPEED_10HD; ++ } ++ } ++ } ++ } ++ adapterData->dwLinkSpeed = result; ++ ret = 0; ++DONE: ++ return ret; ++} ++ ++static int Phy_UpdateLinkMode(struct usbnet *dev) ++{ ++ u32 dwTemp,dwValue; ++ int ret = SMSC9500_FAIL; ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ u32 dwOldLinkSpeed = adapterData->dwLinkSpeed; ++ ++ SMSC_TRACE(DBG_LINK, "Phy_UpdateLinkMode"); ++ ++ Phy_GetLinkMode(dev); ++ ++ if (dwOldLinkSpeed != (adapterData->dwLinkSpeed)) { ++ if (adapterData->dwLinkSpeed != LINK_OFF) { ++ u32 dwRegVal=0; ++ ++ /* Ethernet output boost */ ++ smsc9500_eth_phy_boost(dev, 1); ++ ++ switch(adapterData->dwLinkSpeed) { ++ case LINK_SPEED_10HD: ++ SMSC_TRACE(DBG_LINK_CHANGE, "Link is now UP at 10Mbps HD"); ++ break; ++ case LINK_SPEED_10FD: ++ SMSC_TRACE(DBG_LINK_CHANGE, "Link is now UP at 10Mbps FD"); ++ break; ++ case LINK_SPEED_100HD: ++ SMSC_TRACE(DBG_LINK_CHANGE, "Link is now UP at 100Mbps HD"); ++ break; ++ case LINK_SPEED_100FD: ++ SMSC_TRACE(DBG_LINK_CHANGE, "Link is now UP at 100Mbps FD"); ++ break; ++ default: ++ SMSC_TRACE(DBG_LINK_CHANGE, "Link is now UP at Unknown Link Speed, dwLinkSpeed=0x%08X", ++ adapterData->dwLinkSpeed); ++ break; ++ } ++ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, MAC_CR, &dwRegVal)); ++ dwRegVal &= ~(MAC_CR_FDPX_ | MAC_CR_RCVOWN_); ++ switch (adapterData->dwLinkSpeed) { ++ case LINK_SPEED_10HD: ++ case LINK_SPEED_100HD: ++ dwRegVal |= MAC_CR_RCVOWN_; ++ break; ++ case LINK_SPEED_10FD: ++ case LINK_SPEED_100FD: ++ dwRegVal |= MAC_CR_FDPX_; ++ break; ++ default: ++ break; ++ } ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, MAC_CR, dwRegVal)); ++ ++ if (adapterData->dwLinkSettings & LINK_AUTO_NEGOTIATE) { ++ u16 linkPartner = 0; ++ u16 localLink = 0; ++ ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_ANEG_ADV, &dwTemp)); ++ localLink = LOWORD(dwTemp); ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_ANEG_LPA, &dwTemp)); ++ linkPartner = LOWORD(dwTemp); ++ switch(adapterData->dwLinkSpeed) { ++ case LINK_SPEED_10FD: ++ case LINK_SPEED_100FD: ++ if (((localLink&linkPartner) & ((u16)PHY_ANEG_ADV_SYMP_)) != ((u16)0U)) { ++ /* Enable PAUSE receive and transmit */ ++ dwTemp = 0xFFFF0002UL; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, FLOW, dwTemp)); ++ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, AFC_CFG, &dwValue)); ++ dwValue = dwValue | 0x0000000FUL; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, AFC_CFG, dwValue)); ++ ++ } else if(((localLink & ((u16)0x0C00U)) == ((u16)0x0C00U)) && ++ ((linkPartner & ((u16)0x0C00U)) == ((u16)0x0800U))) { ++ /* Enable PAUSE receive, disable PAUSE transmit */ ++ dwTemp = 0xFFFF0002UL; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, FLOW, dwTemp)); ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, AFC_CFG, &dwValue)); ++ dwValue = dwValue&(~0x0000000FUL); ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, AFC_CFG, dwValue)); ++ ++ } else if(((localLink & ((u16)0x0C00U)) == ((u16)0x0800U)) && ++ ((linkPartner & ((u16)0x0C00U)) == ((u16)0x0C00U))) { ++ /* Enable PAUSE transmit, disable PAUSE receive */ ++ dwTemp = 0x0UL; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, FLOW, dwTemp)); ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, AFC_CFG, &dwValue)); ++ dwValue = dwValue | 0x0000000FUL; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, AFC_CFG, dwValue)); ++ ++ } else { ++ /* Disable PAUSE receive and transmit */ ++ dwTemp = 0x0UL; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, FLOW, dwTemp)); ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, AFC_CFG,&dwValue)); ++ dwValue = dwValue&(~0x0000000FUL); ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, AFC_CFG, dwValue)); ++ } ++ break; ++ case LINK_SPEED_10HD: ++ case LINK_SPEED_100HD: ++ dwTemp = 0x0UL; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, FLOW, dwTemp)); ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, AFC_CFG,&dwValue)); ++ dwValue = dwValue | 0x0000000FUL; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, AFC_CFG, dwValue)); ++ break; ++ default: ++ break; ++ } ++ SMSC_TRACE(DBG_LINK_CHANGE, "LAN9500: %s,%s,%s,%s,%s,%s", ++ (localLink&PHY_ANEG_ADV_ASYMP_)?"ASYMP":" ", ++ (localLink&PHY_ANEG_ADV_SYMP_)?"SYMP ":" ", ++ (localLink&PHY_ANEG_ADV_100F_)?"100FD":" ", ++ (localLink&PHY_ANEG_ADV_100H_)?"100HD":" ", ++ (localLink&PHY_ANEG_ADV_10F_)?"10FD ":" ", ++ (localLink&PHY_ANEG_ADV_10H_)?"10HD ":" "); ++ ++ SMSC_TRACE(DBG_LINK_CHANGE, "Partner: %s,%s,%s,%s,%s,%s", ++ (linkPartner&PHY_ANEG_LPA_ASYMP_)?"ASYMP":" ", ++ (linkPartner&PHY_ANEG_LPA_SYMP_)?"SYMP ":" ", ++ (linkPartner&PHY_ANEG_LPA_100FDX_)?"100FD":" ", ++ (linkPartner&PHY_ANEG_LPA_100HDX_)?"100HD":" ", ++ (linkPartner&PHY_ANEG_LPA_10FDX_)?"10FD ":" ", ++ (linkPartner&PHY_ANEG_LPA_10HDX_)?"10HD ":" "); ++ } else { ++ switch(adapterData->dwLinkSpeed) { ++ case LINK_SPEED_10HD: ++ case LINK_SPEED_100HD: ++ dwTemp = 0x0UL; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, FLOW, dwTemp)); ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, AFC_CFG, &dwValue)); ++ dwValue = dwValue | 0x0000000FUL; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, AFC_CFG, dwValue)); ++ break; ++ default: ++ dwTemp = 0x0UL; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, FLOW, dwTemp)); ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, AFC_CFG, &dwValue)); ++ dwValue = dwValue & (~0x0000000FUL); ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, AFC_CFG, dwValue)); ++ break; ++ } ++ } ++ netif_carrier_on(dev->net); ++ Tx_WakeQueue(dev,0x01); ++ SetGpo(dev, adapterData->LinkLedOnGpio, !adapterData->LinkLedOnGpioPolarity); ++ NICStartRxPath(dev); ++ set_bit(EVENT_LINK_UP, &dev->flags); ++ ++ } else { ++ SMSC_TRACE(DBG_LINK_CHANGE,"Link is now DOWN"); ++ Tx_StopQueue(dev,0x01); ++ netif_carrier_off(dev->net); ++ SetGpo(dev, adapterData->LinkLedOnGpio, adapterData->LinkLedOnGpioPolarity); ++ NICStopAndFlushRxPath(dev); ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, FLOW, 0)); ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, AFC_CFG, &dwValue)); ++ dwValue = dwValue & (~0x0000000FUL); ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, AFC_CFG, dwValue)); ++ set_bit(EVENT_LINK_DOWN, &dev->flags); ++ } ++ } ++ ret = 0; ++DONE: ++ return ret; ++} ++ ++static int Phy_CheckLink(void * ptr) ++{ ++ u32 dwValue; ++ struct usbnet *dev = ptr; ++ int ret = SMSC9500_FAIL; ++ char statistics[sizeof(SMSC9500_RX_STATS) + sizeof(SMSC9500_TX_STATS)]; ++ ++ BUG_ON(!dev); ++ ++ SMSC_TRACE(DBG_LINK, "Phy_CheckLink"); ++ ++ if (Phy_UpdateLinkMode(dev) < 0) ++ return ret; ++ ++ /* verify whether ethernet boost is set */ ++ smsc9500_eth_phy_boost(dev, 0); ++ ++ if (dev->suspendFlag & AUTOSUSPEND_DETACH) { ++ if(!netif_carrier_ok(dev->net)) { ++ /* Link is down, detach device*/ ++ /* Set wakeup event */ ++ SetLinkDownWakeupEvents(dev, WAKEPHY_ENERGY); ++ ++ /* Enable net detach */ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, HW_CFG, &dwValue)); ++ dwValue |= HW_CFG_SMDET_EN; ++ /* Not checking return status here. Failure or ++ success smsc9500_write_reg() return negetive */ ++ smsc9500_write_reg(dev, HW_CFG, dwValue); ++ dev->suspendFlag &= ~AUTOSUSPEND_DETACH; ++ dev->netDetachDone = TRUE; ++ ret = SMSC9500_SUCCESS; ++ goto DONE; ++ } ++ } ++ ++ if (smsc9500_get_stats(dev, statistics) > 0){ ++ UpdateStatCounters(dev,statistics); ++ } ++ ++ if ((!(dev->StopLinkPolling)) && (!timer_pending(&dev->LinkPollingTimer))) { ++ dev->LinkPollingTimer.expires = jiffies+HZ; ++ add_timer(&(dev->LinkPollingTimer)); ++ } ++ ret = SMSC9500_SUCCESS; ++DONE: ++ return ret; ++} ++ ++ ++static int phy_SetLink(struct usbnet *dev, u32 dwLinkRequest) ++{ ++ u32 dwValue; ++ u16 wTemp = 0; ++ int ret = SMSC9500_FAIL; ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ SMSC_TRACE(DBG_LINK, "phy_SetLink"); ++ ++ /* If mdio access is disabled return */ ++ if (MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS) { ++ return 0; ++ } ++ ++ if(dwLinkRequest&LINK_AUTO_NEGOTIATE) { ++ ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_ANEG_ADV,&dwValue)); ++ wTemp=LOWORD(dwValue); ++ wTemp&=~PHY_ANEG_ADV_PAUSE_; ++ if(dwLinkRequest&LINK_ASYMMETRIC_PAUSE) { ++ wTemp|=PHY_ANEG_ADV_ASYMP_; ++ } ++ if(dwLinkRequest&LINK_SYMMETRIC_PAUSE) { ++ wTemp|=PHY_ANEG_ADV_SYMP_; ++ } ++ wTemp&=~PHY_ANEG_ADV_SPEED_; ++ if(dwLinkRequest&LINK_SPEED_10HD) { ++ wTemp|=PHY_ANEG_ADV_10H_; ++ } ++ if(dwLinkRequest&LINK_SPEED_10FD) { ++ wTemp|=PHY_ANEG_ADV_10F_; ++ } ++ ++ if((dwLinkRequest&LINK_SPEED_100HD) && (dev->udev->speed == USB_SPEED_HIGH)) { ++ wTemp|=PHY_ANEG_ADV_100H_; ++ } ++ if((dwLinkRequest&LINK_SPEED_100FD) && (dev->udev->speed == USB_SPEED_HIGH)) { ++ wTemp|=PHY_ANEG_ADV_100F_; ++ } ++ ++ dwValue=(u32)(wTemp) &0x0000FFFFUL; ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev,PHY_ANEG_ADV, dwValue)); ++ ++ // begin to establish link ++ wTemp=PHY_BCR_AUTO_NEG_ENABLE_|PHY_BCR_RESTART_AUTO_NEG_; ++ dwValue=(u32)(wTemp) &0x0000FFFFUL; ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev,PHY_BCR, dwValue)); ++ } else { ++ ++ /* Automdix fix when force mode */ ++ if (adapterData->internalPhy == TRUE) { ++ if ((auto_mdix >= AMDIX_ENABLE) && (dev->chipDependFeatures[FEATURE_MDIX_MODE] == TRUE)) { ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_SILICON_REV, &dwValue)); ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_SILICON_REV, dwValue | PHY_SILICON_REV_AMDIX_XTD_)); ++ } else { ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_SPECIAL_CTRL_STS, &dwValue)); ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_SPECIAL_CTRL_STS, (dwValue & 0x1FFF)|0x8000)); ++ } ++ } ++ ++ if(dwLinkRequest&(LINK_SPEED_100FD)) { ++ dwLinkRequest=LINK_SPEED_100FD; ++ } else if(dwLinkRequest&(LINK_SPEED_100HD)) { ++ dwLinkRequest=LINK_SPEED_100HD; ++ } else if(dwLinkRequest&(LINK_SPEED_10FD)) { ++ dwLinkRequest=LINK_SPEED_10FD; ++ } else if(dwLinkRequest&(LINK_SPEED_10HD)) { ++ dwLinkRequest=LINK_SPEED_10HD; ++ } ++ if(dwLinkRequest&(LINK_SPEED_10FD|LINK_SPEED_100FD)) { ++ wTemp|=PHY_BCR_DUPLEX_MODE_; ++ } ++ if(dwLinkRequest&(LINK_SPEED_100HD|LINK_SPEED_100FD)) { ++ wTemp|=PHY_BCR_SPEED_SELECT_; ++ } ++ dwValue=(u32)(wTemp) &0x0000FFFFUL; ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev,PHY_BCR, dwValue)); ++ } ++ ++ /* Ethernet output boost */ ++ smsc9500_eth_phy_boost(dev, 1); ++ ++ ret = 0; ++DONE: ++ return ret; ++} ++ ++static int Phy_SetAutoMdix( struct usbnet *dev, u16 wAutoMdix) ++{ ++ u32 SpecialCtrlSts = 0U; ++ int ret = SMSC9500_FAIL; ++ ++ /* If mdio access is disabled return */ ++ if (MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS) { ++ return 0; ++ } ++ ++ if (wAutoMdix > AMDIX_ENABLE) { ++ SMSC_TRACE(DBG_INIT, "LAN9500 Auto MDIX feature controlled by hardware strap"); ++ } else { ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_SPECIAL_CTRL_STS, &SpecialCtrlSts)); ++ if (wAutoMdix == AMDIX_DISABLE_CROSSOVER) { ++ SpecialCtrlSts |= (SPECIAL_CTRL_STS_OVRRD_AMDIX_ | SPECIAL_CTRL_STS_AMDIX_STATE_); ++ SpecialCtrlSts &= ~SPECIAL_CTRL_STS_AMDIX_ENABLE_; ++ SMSC_WARNING("LAN9500 Auto MDIX hardware strap was overiden by driver. " ++ "AutoMdix is disabled, use crossover cable."); ++ } else if (wAutoMdix == AMDIX_DISABLE_STRAIGHT) { ++ SpecialCtrlSts |= SPECIAL_CTRL_STS_OVRRD_AMDIX_; ++ SpecialCtrlSts &= ~(SPECIAL_CTRL_STS_AMDIX_ENABLE_ | SPECIAL_CTRL_STS_AMDIX_STATE_); ++ SMSC_WARNING("LAN9500 Auto MDIX hardware strap was overiden by driver. " ++ "AutoMdix is disabled, use straight cable."); ++ } else { ++ SpecialCtrlSts |= (SPECIAL_CTRL_STS_OVRRD_AMDIX_ | SPECIAL_CTRL_STS_AMDIX_ENABLE_); ++ SMSC_WARNING("LAN9500 Auto MDIX hardware strap was overiden by driver. AutoMdix is enabled"); ++ } ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_SPECIAL_CTRL_STS, SpecialCtrlSts)); ++ } ++ ret = 0; ++DONE: ++ return ret; ++} ++ ++static BOOLEAN Phy_Initialize( struct usbnet *dev, u32 dwPhyAddr, u32 dwLinkRequest) ++{ ++ u32 dwPhyBcr; ++ u32 dwLoopCount = 0; ++ u32 phy_id_1, phy_id_2; ++ BOOLEAN result = FALSE, bConfigureAutoMdix = FALSE; ++ u32 dwTemp = 0,dwValue, address, Value32, Temp32; ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ SMSC_TRACE(DBG_INIT, "Phy_Initialize"); ++ ++ SMSC_ASSERT(dwLinkRequest <= 0x7FUL); ++ ++ adapterData->internalPhy = TRUE; ++ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, HW_CFG, &dwValue)); ++ if (dwValue & HW_CFG_PSEL_) { ++ if (dwPhyAddr <= 31) { ++ /* We know the phy address. Use it. */ ++ adapterData->dwPhyAddress = dwPhyAddr; ++ } else if ((dwPhyAddr > 31) && (MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS)) { ++ /* When phy access is disabled, phy address do ++ not matter. Assign 0 */ ++ adapterData->dwPhyAddress = 0; ++ } else { /* Auto detect PHY */ ++ phy_id_1 = 0xFFFFU; ++ phy_id_2 = 0xFFFFU; ++ for (address = 0; address <= 31; address++) { ++ adapterData->dwPhyAddress = address; ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_ID_1, &phy_id_1)); ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_ID_2, &phy_id_2)); ++ if((phy_id_1 != 0x7FFFU) && (phy_id_1 != 0xFFFFU) && (phy_id_1 != 0x0000U)){ ++ SMSC_TRACE(DBG_INIT, "Deteced Phy at address = 0x%02X", address); ++ break; ++ } ++ } ++ } ++ SMSC_TRACE(DBG_INIT, "Using external PHY "); ++ adapterData->internalPhy = FALSE; ++ ++ } else { /* Use Internal Phy */ ++ SMSC_TRACE(DBG_INIT, "Using internal PHY "); ++ adapterData->dwPhyAddress = 1; ++ bConfigureAutoMdix = TRUE; ++ } ++ ++ adapterData->dwLinkSpeed = LINK_INIT; ++ adapterData->dwLinkSettings = LINK_INIT; ++ ++ if (!(MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS)) { ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_ID_2, &dwTemp)); ++ adapterData->bPhyRev = ((BYTE)(dwTemp & (0x0FUL))); ++ adapterData->bPhyModel = ((BYTE)((dwTemp >> 4) & (0x3FUL))); ++ adapterData->dwPhyId = ((dwTemp & (0xFC00UL)) << 8); ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_ID_1, &dwTemp)); ++ adapterData->dwPhyId |= ((dwTemp & (0x0000FFFFUL)) << 2); ++ ++ SMSC_TRACE(DBG_INIT, "PhyId: 0x%08X, PhyModel: 0x%02X, PhyRev: 0x%02X", ++ adapterData->dwPhyId, adapterData->bPhyModel, adapterData->bPhyRev); ++ ++ /* Reset the PHY */ ++ dwPhyBcr = (u32)PHY_BCR_RESET_ ; ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev,PHY_BCR, dwPhyBcr)); ++ ++ dwLoopCount = 20; ++ do { ++ mdelay(100); ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev,PHY_BCR,&dwPhyBcr)); ++ ++ dwLoopCount--; ++ } while((dwLoopCount>0) && ((u16)dwPhyBcr&PHY_BCR_RESET_)); ++ ++ if((u16)dwPhyBcr&PHY_BCR_RESET_) { ++ SMSC_WARNING("PHY reset failed to complete"); ++ goto DONE; ++ } ++ else { ++ SMSC_TRACE(DBG_INIT, "PHY reset!"); ++ } ++ ++ if (bConfigureAutoMdix) { ++ Phy_SetAutoMdix(dev, (u16)auto_mdix); ++ } ++ ++ phy_SetLink(dev,dwLinkRequest); ++ ++ /* set EDPD settings */ ++ if ((EDPDConfig != 0) && (adapterData->internalPhy) && ++ ((dev->chipID == PID_LAN9500A) || (dev->chipID == PID_LAN9530) || ++ (dev->chipID == PID_LAN9730) || (dev->chipID == PID_LAN89530))) { ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_SILICON_REV, &dwTemp)); ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_SILICON_REV, ++ (dwTemp & 0x03FF) | EDPDConfig)); ++ } ++ ++ /* Set EEE (for external or internal phy) if enabled and supported */ ++ if (((dev->chipID == PID_LAN9730) || (dev->chipID == PID_LAN9530) ++ || (dev->chipID == PID_LAN89530)) && (EnableEEE < 2)) ++ { ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev,MAC_CR,&Value32)); ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_SILICON_REV, &Temp32)); ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_ANEG_ADV, &dwTemp)); ++ ++ if (EnableEEE == 0) { ++ Value32 &= ~MAC_CR_ENABLE_EEE; ++ Temp32 &= ~PHY_SILICON_REV_EEE_ENABLE; ++ dwTemp &= ~PHY_ANEG_NEXT_PAGE; ++ } else if (EnableEEE == 1) { ++ Value32 |= MAC_CR_ENABLE_EEE; ++ Temp32 |= PHY_SILICON_REV_EEE_ENABLE; ++ dwTemp |= PHY_ANEG_NEXT_PAGE; ++ } ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev,PHY_ANEG_ADV, dwTemp)); ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_SILICON_REV, Temp32)); ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, MAC_CR, Value32)) ; ++ } ++ } ++ ++ result = TRUE; ++DONE: ++ return result; ++} ++ ++ ++ ++static int smsc9500_get_settings(struct net_device *net, struct ethtool_cmd *cmd) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ cmd->supported = SUPPORTED_10baseT_Half | ++ SUPPORTED_10baseT_Full | ++ SUPPORTED_100baseT_Half | ++ SUPPORTED_100baseT_Full | ++ SUPPORTED_Autoneg | ++ SUPPORTED_MII; ++ cmd->advertising = ADVERTISED_MII; ++ ++ if (adapterData->dwLinkSettings & LINK_SPEED_10HD) ++ cmd->advertising |= ADVERTISED_10baseT_Half; ++ if (adapterData->dwLinkSettings & LINK_SPEED_10FD) ++ cmd->advertising |= ADVERTISED_10baseT_Full; ++ if (adapterData->dwLinkSettings & LINK_SPEED_100HD) ++ cmd->advertising |= ADVERTISED_100baseT_Half; ++ if (adapterData->dwLinkSettings & LINK_SPEED_100FD) ++ cmd->advertising |= ADVERTISED_100baseT_Full; ++ if (adapterData->dwLinkSettings & LINK_AUTO_NEGOTIATE) { ++ cmd->advertising |= ADVERTISED_Autoneg; ++ cmd->autoneg = AUTONEG_ENABLE; ++ } else { ++ cmd->autoneg = AUTONEG_DISABLE; ++ } ++ if (adapterData->dwLinkSpeed & (LINK_SPEED_100HD | LINK_SPEED_100FD)) { ++ cmd->speed = SPEED_100; ++ } else { ++ cmd->speed = SPEED_10; ++ } ++ if (adapterData->dwLinkSpeed & (LINK_SPEED_10FD | LINK_SPEED_100FD)) { ++ cmd->duplex=DUPLEX_FULL; ++ } else { ++ cmd->duplex=DUPLEX_HALF; ++ } ++ cmd->port = PORT_MII; ++ cmd->phy_address = (u8)adapterData->dwPhyAddress; ++ cmd->transceiver = XCVR_INTERNAL; ++ cmd->maxtxpkt = 0; ++ cmd->maxrxpkt = 0; ++ ++ return 0; ++} ++ ++static int smsc9500_set_settings(struct net_device *net, struct ethtool_cmd *cmd) ++{ ++ int result = -EFAULT; ++ u32 linkRequest = 0; ++ struct usbnet *dev = netdev_priv(net); ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ if (cmd->autoneg == AUTONEG_ENABLE) { ++ u32 mask = (ADVERTISED_100baseT_Half | ++ ADVERTISED_100baseT_Full | ++ ADVERTISED_10baseT_Half | ++ ADVERTISED_10baseT_Full); ++ ++ if (cmd->advertising & ~mask) ++ return -EINVAL; ++ if (cmd->advertising & ADVERTISED_100baseT_Full) ++ linkRequest |= LINK_SPEED_100FD; ++ if (cmd->advertising & ADVERTISED_100baseT_Half) ++ linkRequest |= LINK_SPEED_100HD; ++ if (cmd->advertising & ADVERTISED_10baseT_Full) ++ linkRequest |= LINK_SPEED_10FD; ++ if (cmd->advertising & ADVERTISED_10baseT_Half) ++ linkRequest |= LINK_SPEED_10HD; ++ linkRequest |= LINK_AUTO_NEGOTIATE; ++ } else { ++ ++ if (!((cmd->speed == SPEED_10) || (cmd->speed == SPEED_100))) ++ return -EOPNOTSUPP; ++ ++ if (cmd->speed == SPEED_100) { ++ if (cmd->duplex == DUPLEX_FULL) { ++ linkRequest |= LINK_SPEED_100FD; ++ } else { ++ linkRequest |= LINK_SPEED_100HD; ++ } ++ } else { ++ if (cmd->duplex == DUPLEX_FULL) { ++ linkRequest |= LINK_SPEED_10FD; ++ } else { ++ linkRequest |= LINK_SPEED_10HD; ++ } ++ } ++ } ++ ++ /* keep the flow control settings */ ++ linkRequest |= adapterData->dwLinkSettings & (LINK_SYMMETRIC_PAUSE | LINK_ASYMMETRIC_PAUSE); ++ adapterData->dwLinkSettings = linkRequest; ++ adapterData->dwSavedLinkSettings = linkRequest; ++ ++ if (phy_SetLink(dev, adapterData->dwLinkSettings) == SMSC9500_SUCCESS) { ++ result = 0; ++ } ++ ++ return result; ++} ++ ++void smsc9500_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ strcpy(info->driver, "Smsc9500"); ++ memset(&info->version, 0, sizeof(info->version)); ++ sprintf(info->version, "%lX.%02lX.%02lX", ++ (DRIVER_VERSION >> 16),(DRIVER_VERSION >> 8) & 0xFF, (DRIVER_VERSION & 0xFFUL)); ++ memset(&info->fw_version, 0, sizeof(info->fw_version)); ++ sprintf(info->fw_version, "%lu", (adapterData->dwIdRev) & 0xFFFFUL); ++ memset(&info->bus_info, 0, sizeof(info->bus_info)); ++/* ++ * kernel 4.x does not have reserved1 in ethtool.h drvinfo. ++ */ ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,19,8)) ++ memset(&info->reserved1, 0, sizeof(info->reserved1)); ++#endif ++ memset(&info->reserved2, 0, sizeof(info->reserved2)); ++ info->n_stats = 0; ++ info->testinfo_len = 0; ++ info->eedump_len = 0; ++ info->regdump_len = 0; ++} ++ ++ ++static int smsc9500_regs_len(struct net_device *dev) ++{ ++ /* all smsc9500 registers plus all phy registers */ ++ return 0x200 + (32 * sizeof(u32)); ++} ++ ++ ++static void smsc9500_get_regs(struct net_device *net, struct ethtool_regs *regs, void *buf) ++{ ++ u32 *data = buf; ++ unsigned int i, j = 0; ++ struct usbnet *dev = netdev_priv(net); ++ ++ smsc9500_read_reg(dev, ID_REV,®s->version); ++ for (i = 0; i < 0x200; i += (sizeof(u32))) ++ smsc9500_read_reg(dev, i,&data[j++]); ++ ++ if (MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS) { ++ SMSC_WARNING("Phy Mdio internal access disabled\n"); ++ return; ++ } ++ ++ for (i = 0; i <= 31; i++) ++ smsc9500_read_phy(dev, i,&data[j++]); ++} ++ ++ ++int smsc9500_nway_restart(struct usbnet *dev) ++{ ++ uint bmcr; ++ int ret = -EINVAL; ++ ++ if (MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS) { ++ SMSC_WARNING("Phy Mdio internal access disabled\n"); ++ return ret; ++ } ++ ++ /* if autoneg is off, it's an error */ ++ smsc9500_read_phy(dev, PHY_BCR, &bmcr); ++ ++ if (bmcr & PHY_BCR_AUTO_NEG_ENABLE_) { ++ bmcr |= PHY_BCR_RESTART_AUTO_NEG_; ++ smsc9500_write_phy(dev, PHY_BCR, bmcr); ++ ret = 0; ++ } ++ ++ return ret; ++} ++ ++int smsc9500_nway_reset(struct net_device *net) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ ++ return smsc9500_nway_restart(dev); ++} ++ ++static u32 smsc9500_get_link (struct net_device *net) ++{ ++ u32 wRegBSR; ++ struct usbnet *dev = netdev_priv(net); ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ if (MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS) { ++ /* No phy access, report link up */ ++ return (adapterData->DefaultLinkStatus & MDIO_DEFAULT_LINK_INIT_MASK); ++ } ++ ++ /* read PHY_BSR twice: link status bit is LL */ ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_BSR, &wRegBSR)); ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_BSR, &wRegBSR)); ++ if(!(wRegBSR & PHY_BSR_LINK_STATUS_)) { ++ return 0; ++ } else { ++ return 1; ++ } ++DONE: ++ return 0; ++} ++ ++static u32 smsc9500_get_msglevel (struct net_device *net) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ ++ return dev->msg_enable; ++} ++ ++ ++static void smsc9500_set_msglevel (struct net_device *net, u32 level) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ ++ dev->msg_enable = level; ++} ++ ++ ++static void smsc9500_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ wolinfo->supported = (WAKE_PHY | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST | WAKE_ARP | WAKE_MAGIC); ++ wolinfo->wolopts = adapterData->WolWakeupOpts; ++} ++ ++static int smsc9500_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) ++{ ++ int result = -EFAULT; ++ struct usbnet *dev = netdev_priv(net); ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ adapterData->WolWakeupOpts = wolinfo->wolopts; ++ result = 0; ++ ++ return result; ++} ++ ++ ++static BOOLEAN IsEepromContentValid(struct usbnet *dev) ++{ ++ u32 tmp, strapVal, idRev; ++ BOOLEAN validContent = FALSE; ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, ID_REV, &idRev)); ++ idRev = idRev >> 16; ++ ++ if((idRev == PID_LAN9500) || (idRev == PID_LAN9500A)) { ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, STRAP_DBG, &strapVal)); ++ if (strapVal & EEPROM_DISABLE) { ++ SMSC_WARNING("EEPROM disable strap is set\n"); ++ adapterData->eepromContentValid = FALSE; ++ return FALSE; ++ } ++ } ++ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, E2P_CMD, &tmp)); ++ if (tmp & E2P_CMD_LOADED_) { ++ validContent = TRUE; ++ } else { ++ SMSC_TRACE(DBG_INIT, "EEPROM content not valid, not loaded"); ++ validContent = FALSE; ++ } ++DONE: ++ adapterData->eepromContentValid = validContent; ++ return validContent; ++} ++ ++static int smsc9500_eeprom_size(struct usbnet *dev) ++{ ++ int size = 0; ++ u32 start, end; ++ u32 tmp, strapVal, idRev; ++ BOOLEAN validContent = FALSE; ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, ID_REV, &idRev)); ++ idRev = idRev >> 16; ++ ++ if((idRev == PID_LAN9500) || (idRev == PID_LAN9500A)) { ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, STRAP_DBG, &strapVal)); ++ if (strapVal & EEPROM_DISABLE) { ++ SMSC_WARNING("EEPROM disable strap is set\n"); ++ size = 0; ++ adapterData->eepromContentValid = FALSE; ++ return size; ++ } else if (!(strapVal & EEPROM_SIZE)) { ++ size = 128; ++ goto CheckValid; ++ } ++ } ++ ++ if(smsc9500_read_eeprom(dev, 0, sizeof(u32), (BYTE*)&start) < 0) { ++ goto DONE; ++ } ++ if(smsc9500_read_eeprom(dev, 256, sizeof(u32), (BYTE*)&end) < 0) { ++ goto DONE; ++ } ++ /* write to 256 the inverse value of start */ ++ tmp = ~start; ++ if(smsc9500_write_eeprom(dev, 256, sizeof(u32), (BYTE*)&tmp) < 0) { ++ goto DONE; ++ } ++ /* read the location 0 again */ ++ if(smsc9500_read_eeprom(dev, 0, sizeof(u32), (BYTE*)&tmp) < 0) { ++ goto DONE; ++ } ++ if (tmp != start) { ++ /* restore the value of location 0 */ ++ if(smsc9500_write_eeprom(dev, 0, sizeof(u32), (BYTE*)&start) < 0) { ++ goto DONE; ++ } ++ /* 256 byte eeprom */ ++ size = 256; ++ } else { ++ /* restore the value of location 0 */ ++ if(smsc9500_write_eeprom(dev, 256, sizeof(u32), (BYTE*)&end) < 0) { ++ goto DONE; ++ } ++ /* 512 byte eeprom */ ++ size = 512; ++ } ++ ++CheckValid: ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, E2P_CMD, &tmp)); ++ if (tmp & E2P_CMD_LOADED_) { ++ validContent = TRUE; ++ } else { ++ validContent = FALSE; ++ } ++DONE: ++ adapterData->eepromContentValid = validContent; ++ return size; ++ ++} ++ ++static int smsc9500_get_eeprom_len(struct net_device *net) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ return adapterData->eepromSize = smsc9500_eeprom_size(dev); ++} ++ ++static int smsc9500_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *ee, u8 *data) ++{ ++ int result = 0; ++ int len = ee->len; ++ int offset = ee->offset; ++ struct usbnet *dev = netdev_priv(netdev); ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ ee->magic = LAN9500_EEPROM_MAGIC; ++ ++ adapterData->eepromSize = smsc9500_eeprom_size(dev); ++ ++ if (len == 0) { ++ return 0; ++ } ++ ++ if (offset + len > adapterData->eepromSize) { ++ SMSC_WARNING("EEPROM address is out of range"); ++ result = -EINVAL; ++ } else { ++ if (smsc9500_read_eeprom(dev, offset, len, data) < 0) { ++ result = -EFAULT; ++ } ++ } ++ ++ return result; ++} ++ ++static int smsc9500_set_eeprom(struct net_device *netdev, struct ethtool_eeprom *ee, u8 *data) ++{ ++ int result = 0; ++ int len = ee->len; ++ int offset = ee->offset; ++ struct usbnet *dev = netdev_priv(netdev); ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ adapterData->eepromSize = smsc9500_eeprom_size(dev); ++ ++ if (len == 0) { ++ return 0; ++ } ++ ++ if (offset + len > adapterData->eepromSize) { ++ SMSC_WARNING("EEPROM address is out of range"); ++ result = -EINVAL; ++ return result; ++ } ++ ++ if (ee->magic != LAN9500_EEPROM_MAGIC) { ++ SMSC_WARNING("EEPROM: magic value mismatch, writing fail, magic = 0x%x", ee->magic); ++ result = -EFAULT; ++ return result; ++ } ++ ++ if (smsc9500_write_eeprom(dev, offset, len, data) < 0) { ++ result = -EFAULT; ++ } ++ ++ return result; ++} ++ ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,2,31)) ++static u32 smsc9500_ethtool_get_tx_csum(struct net_device *netdev) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ return adapterData->UseTxCsum; ++} ++ ++static u32 smsc9500_ethtool_get_rx_csum(struct net_device *netdev) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ return adapterData->UseRxCsum; ++} ++ ++/* Enable or disable Tx & Rx checksum offload engines */ ++static int smsc9500_set_csums(struct usbnet *dev) ++{ ++ u32 read_buf; ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ int ret = smsc9500_read_reg(dev, COE_CR, &read_buf); ++ if (ret < 0) { ++ SMSC_WARNING("Failed to read COE_CR: %d\n", ret); ++ return ret; ++ } ++ ++ if (adapterData->UseTxCsum) ++ read_buf |= Tx_COE_EN_; ++ else ++ read_buf &= ~Tx_COE_EN_; ++ ++ if (adapterData->UseRxCsum) ++ read_buf |= Rx_COE_EN_; ++ else ++ read_buf &= ~Rx_COE_EN_; ++ ++ ret = smsc9500_write_reg(dev, COE_CR, read_buf); ++ if (ret < 0) { ++ SMSC_WARNING("Failed to write COE_CR: %d\n", ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int smsc9500_ethtool_set_tx_csum(struct net_device *netdev, u32 val) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ adapterData->UseTxCsum = !!val; ++ ++ if (adapterData->UseTxCsum) ++ netdev->features |= NETIF_F_HW_CSUM; ++ else ++ netdev->features &= ~NETIF_F_HW_CSUM; ++ ++ return smsc9500_set_csums(dev); ++} ++ ++ ++static int smsc9500_ethtool_set_rx_csum(struct net_device *netdev, u32 val) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ adapterData->UseRxCsum = !!val; ++ ++ return smsc9500_set_csums(dev); ++} ++#endif ++ ++static void smsc9500_get_ethtool_stats(struct net_device *netdev,struct ethtool_stats *stats, u64 *data) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ char statistics[sizeof(SMSC9500_RX_STATS) + sizeof(SMSC9500_TX_STATS)]; ++ ++ ++ /* Get statistics counters */ ++ if (smsc9500_get_stats(dev, statistics) > 0) { ++ UpdateStatCounters(dev,statistics); ++ } ++ ++ data[0] = dev->stats.rx_packets; ++ data[1] = dev->stats.tx_packets; ++ data[2] = dev->stats.rx_bytes; ++ data[3] = dev->stats.tx_bytes; ++ data[4] = dev->stats.rx_errors; ++ data[5] = dev->stats.tx_errors; ++ data[6] = dev->stats.tx_dropped; ++ data[7] = dev->stats.rx_dropped; ++ data[8] = dev->stats.rx_length_errors; ++ data[9] = dev->stats.rx_over_errors; ++ data[10] =dev->stats.rx_crc_errors; ++ data[11] = dev->stats.rx_frame_errors; ++ data[12] = adapterData->RxGoodFrames; ++ data[13] = adapterData->RxCrcErrors; ++ data[14] = adapterData->RxRuntFrameErrors; ++ data[15] = adapterData->RxAlignmentErrors; ++ data[16] = adapterData->RxFrameTooLongError; ++ data[17] = adapterData->RxLaterCollisionError; ++ data[18] = adapterData->RxBadFrames; ++ data[19] = adapterData->RxFifoDroppedFrames; ++ data[20] = adapterData->TxGoodFrames; ++ data[21] = adapterData->TxPauseFrames; ++ data[22] = adapterData->TxSingleCollisions; ++ data[23] = adapterData->TxMultipleCollisions; ++ data[24] = adapterData->TxExcessiveCollisionErrors; ++ data[25] = adapterData->TxLateCollisionErrors; ++ data[26] = adapterData->TxBufferUnderrunErrors; ++ data[27] = adapterData->TxExcessiveDeferralErrors; ++ data[28] = adapterData->TxCarrierErrors; ++ data[29] = adapterData->TxBadFrames; ++} ++ ++static void smsc9500_get_strings(struct net_device *netdev, u32 stringset,u8 *data) ++{ ++ memcpy(data, ethtool_stats_keys, sizeof(ethtool_stats_keys)); ++} ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) ++static int smsc9500_get_sset_count(struct net_device *netdev) ++{ ++ return ARRAY_SIZE(ethtool_stats_keys); ++} ++#else ++static int smsc9500_get_sset_count(struct net_device *netdev, int sset) ++ ++{ ++ switch (sset) { ++ case ETH_SS_STATS: ++ return ARRAY_SIZE(ethtool_stats_keys); ++ ++ default: ++ return -EOPNOTSUPP; ++ } ++} ++#endif ++ ++/* We need to override some ethtool_ops so we require our ++ own structure so we don't interfere with other usbnet ++ devices that may be connected at the same time. */ ++static struct ethtool_ops smsc9500_ethtool_ops = { ++ .get_settings = smsc9500_get_settings, ++ .set_settings = smsc9500_set_settings, ++ .get_drvinfo = smsc9500_get_drvinfo, ++ .get_regs_len = smsc9500_regs_len, ++ .get_regs = smsc9500_get_regs, ++ .get_wol = smsc9500_get_wol, ++ .set_wol = smsc9500_set_wol, ++ .get_msglevel = smsc9500_get_msglevel, ++ .set_msglevel = smsc9500_set_msglevel, ++ .nway_reset = smsc9500_nway_reset, ++ .get_link = smsc9500_get_link, ++ .get_eeprom_len = smsc9500_get_eeprom_len, ++ .get_eeprom = smsc9500_get_eeprom, ++ .set_eeprom = smsc9500_set_eeprom, ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,2,31)) ++ .get_tx_csum = smsc9500_ethtool_get_tx_csum, ++ .set_tx_csum = smsc9500_ethtool_set_tx_csum, ++ .get_rx_csum = smsc9500_ethtool_get_rx_csum, ++ .set_rx_csum = smsc9500_ethtool_set_rx_csum, ++#endif ++ .get_strings = smsc9500_get_strings, ++ .get_ethtool_stats = smsc9500_get_ethtool_stats, ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) ++ .get_stats_count = smsc9500_get_sset_count, ++#else ++ .get_sset_count = smsc9500_get_sset_count, ++#endif ++}; ++ ++static int Smsc9500_do_ioctl( struct net_device *netdev, struct ifreq *ifr, int cmd) ++{ ++ u32 dwValue; ++ int result = 0; ++ void __user *userAddr = NULL; ++ struct usbnet *dev = netdev_priv(netdev); ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ SMSC_TRACE(DBG_IOCTL, "Smsc9500_do_ioctl"); ++ ++ if (netdev == NULL) { ++ SMSC_WARNING("netdev == NULL"); ++ result = -EFAULT; ++ goto DONE; ++ } ++ ++ if(ifr == NULL) { ++ SMSC_WARNING("ifr == NULL"); ++ result = -EFAULT; ++ goto DONE; ++ } ++ userAddr = ifr->ifr_data; ++ ++ switch(cmd) { ++ case SIOCGMIIPHY: ++ case SIOCDEVPRIVATE: ++ SMSC_TRACE(DBG_IOCTL, "SIOCGMIIPHY"); ++ if (adapterData->LanInitialized) { ++ struct mii_ioctl_data *miiData = ++ (struct mii_ioctl_data *) & (ifr->ifr_data); ++ miiData->phy_id = 1; ++ } ++ break; ++ case SIOCGMIIREG: ++ case SIOCDEVPRIVATE+1: ++ SMSC_TRACE(DBG_IOCTL, "SIOCGMIIREG"); ++ if (MdioDisable & MDIO_DISABLE_IOCTL_ACCESS) { ++ SMSC_WARNING("Phy Mdio ioctl access disabled\n"); ++ result = -EFAULT; ++ break; ++ } ++ if (adapterData->LanInitialized) { ++ struct mii_ioctl_data *miiData = ++ (struct mii_ioctl_data *) & (ifr->ifr_data); ++ if (smsc9500_read_phy(dev, miiData->reg_num, &dwValue) < 0) { ++ result = -EFAULT; ++ } ++ miiData->val_out = (u16)dwValue; ++ } ++ break; ++ case SIOCSMIIREG: ++ case SIOCDEVPRIVATE+2: ++ SMSC_TRACE(DBG_IOCTL, "SIOCSMIIREG"); ++ if (MdioDisable & MDIO_DISABLE_IOCTL_ACCESS) { ++ SMSC_WARNING("Phy Mdio ioctl access disabled\n"); ++ result = -EFAULT; ++ break; ++ } ++ if (adapterData->LanInitialized) { ++ struct mii_ioctl_data *miiData = ++ (struct mii_ioctl_data *) & (ifr->ifr_data); ++ dwValue = miiData->val_in; ++ if (smsc9500_write_phy(dev, miiData->reg_num, dwValue) < 0) { ++ result = -EFAULT; ++ } ++ } ++ break; ++ case SMSC9500_IOCTL: ++ result = smsc9500_private_ioctl(adapterData, dev, (PSMSC9500_IOCTL_DATA)userAddr); ++ break; ++ ++ default: ++ result = -EOPNOTSUPP; ++ break; ++ } ++DONE: ++ return result; ++} ++ ++static int smsc9500_private_ioctl(PADAPTER_DATA privateData, struct usbnet *dev, PSMSC9500_IOCTL_DATA ioctlData) ++{ ++ int i; ++ BYTE cBuf; ++ BYTE *dataBuf; ++ u32 dwBuf, offset, len, phyAddr; ++ BOOLEAN success = FALSE; ++ ++ if (ioctlData == NULL) { ++ return SMSC9500_FAIL; ++ } ++ ++ if(ioctlData->dwSignature != SMSC9500_APP_SIGNATURE) { ++ goto DONE; ++ } ++ ++ switch (ioctlData->dwCommand) { ++ case COMMAND_GET_SIGNATURE: ++ success = TRUE; ++ break; ++ case COMMAND_GET_CONFIGURATION: ++ privateData->eepromSize = smsc9500_eeprom_size(dev); ++ ioctlData->Data[0] = DRIVER_VERSION; ++ ioctlData->Data[1] = link_mode; ++ ioctlData->Data[2] = privateData->macAddrHi16; ++ ioctlData->Data[3] = privateData->MmacAddrLo32; ++ ioctlData->Data[4] = debug_mode; ++ ioctlData->Data[5] = privateData->dwIdRev; ++ ioctlData->Data[6] = privateData->dwFpgaRev; ++ ioctlData->Data[7] = 1; ++ ioctlData->Data[8] = privateData->dwPhyId; ++ ioctlData->Data[9] = privateData->bPhyModel; ++ ioctlData->Data[10] = privateData->bPhyRev; ++ ioctlData->Data[11] = privateData->dwLinkSpeed; ++ ioctlData->Data[12] = privateData->eepromSize / 128; //Unit is 128B ++ success = TRUE; ++ break; ++ case COMMAND_LAN_GET_REG: ++ offset = ioctlData->Data[0]; ++ if ((ioctlData->Data[0] <= LAN_REGISTER_RANGE) && ((ioctlData->Data[0]&0x3UL)==0)) ++ { ++ if (smsc9500_read_reg(dev, offset, &dwBuf) >= 0) { ++ ioctlData->Data[1] = dwBuf; ++ success=TRUE; ++ } ++ } else { ++ SMSC_WARNING("Reading LAN9500 Mem Map Failed"); ++ goto MEM_MAP_ACCESS_FAILED; ++ } ++ break; ++ case COMMAND_LAN_SET_REG: ++ if((ioctlData->Data[0] <= LAN_REGISTER_RANGE) && ((ioctlData->Data[0]&0x3UL)==0)) { ++ offset = ioctlData->Data[0]; ++ dwBuf = ioctlData->Data[1]; ++ if(smsc9500_write_reg(dev, offset, dwBuf) >= 0) { ++ success = TRUE; ++ } ++ } else { ++ SMSC_WARNING("Writing LAN9500 Mem Map Failed"); ++MEM_MAP_ACCESS_FAILED: ++ SMSC_WARNING(" Invalid offset == 0x%08lX",ioctlData->Data[0]); ++ if(ioctlData->Data[0] > LAN_REGISTER_RANGE) { ++ SMSC_WARNING(" Out of range"); ++ } ++ if(ioctlData->Data[0]&0x3UL) { ++ SMSC_WARNING(" Not u32 aligned"); ++ } ++ } ++ break; ++ case COMMAND_MAC_GET_REG: ++ if ((ioctlData->Data[0] >= MAC_REGISTER_RANGE_MIN) && ++ (ioctlData->Data[0] <= MAC_REGISTER_RANGE_MAX) && ++ ((ioctlData->Data[0]&0x3UL)==0)) { ++ offset = ioctlData->Data[0]; ++ if (smsc9500_read_reg(dev, offset, &dwBuf) >= 0) { ++ ioctlData->Data[1] = dwBuf; ++ success = TRUE; ++ } ++ } else { ++ SMSC_WARNING("Reading Mac Register Failed"); ++ goto MAC_ACCESS_FAILURE; ++ } ++ break; ++ case COMMAND_MAC_SET_REG: ++ if ((ioctlData->Data[0] >= MAC_REGISTER_RANGE_MIN) && ++ (ioctlData->Data[0] <= MAC_REGISTER_RANGE_MAX) && ++ ((ioctlData->Data[0]&0x3UL)==0)) { ++ offset = ioctlData->Data[0]; ++ dwBuf = ioctlData->Data[1]; ++ if (smsc9500_write_reg(dev, offset, dwBuf) >= 0) { ++ ioctlData->Data[1] = dwBuf; ++ success = TRUE; ++ } ++ } else { ++ SMSC_WARNING("Writing Mac Register Failed"); ++MAC_ACCESS_FAILURE: ++ if (!(privateData->LanInitialized)) { ++ SMSC_WARNING(" LAN Not Initialized,"); ++ SMSC_WARNING(" Use ifconfig to bring interface UP"); ++ } ++ if (!((ioctlData->Data[0] >= MAC_REGISTER_RANGE_MIN)&& ++ (ioctlData->Data[0] <= MAC_REGISTER_RANGE_MAX))) { ++ SMSC_WARNING(" Invalid index = 0x%08lX",ioctlData->Data[0]); ++ } ++ } ++ break; ++ case COMMAND_PHY_GET_REG: ++ if (MdioDisable & MDIO_DISABLE_IOCTL_ACCESS) { ++ SMSC_WARNING("Phy Mdio ioctl access disabled\n"); ++ success = FALSE; ++ break; ++ } ++ if ((ioctlData->Data[0] < 32) && (privateData->LanInitialized)) { ++ offset = ioctlData->Data[0]; ++ phyAddr = ioctlData->Data[1]; ++ if (smsc9500_read_phy_address(dev, phyAddr, offset, &dwBuf) >= 0) { ++ ioctlData->Data[1] = dwBuf; ++ success = TRUE; ++ } ++ } else { ++ SMSC_WARNING("Reading Phy Register Failed"); ++ if (!(privateData->LanInitialized)) { ++ SMSC_WARNING(" Lan Not Initialized,"); ++ SMSC_WARNING(" Use ifconfig to bring interface UP"); ++ } ++ if (!(ioctlData->Data[0] < 32)) { ++ SMSC_WARNING(" Invalid index == 0x%ld",ioctlData->Data[0]); ++ } ++ } ++ break; ++ case COMMAND_PHY_SET_REG: ++ if (MdioDisable & MDIO_DISABLE_IOCTL_ACCESS) { ++ SMSC_WARNING("Phy Mdio ioctl access disabled\n"); ++ success = FALSE; ++ break; ++ } ++ if ((ioctlData->Data[0]<32) && (privateData->LanInitialized)) { ++ offset = ioctlData->Data[0]; ++ dwBuf = ioctlData->Data[1]; ++ phyAddr = ioctlData->Data[2]; ++ if (smsc9500_write_phy_address(dev, phyAddr, offset, dwBuf) >= 0) { ++ success = TRUE; ++ } ++ } else { ++ SMSC_WARNING("Writing Phy Register Failed"); ++ if (!(privateData->LanInitialized)) { ++ SMSC_WARNING(" Lan Not Initialized,"); ++ SMSC_WARNING(" Use ifconfig to bring interface UP"); ++ } ++ if (!(ioctlData->Data[0] < 32)) { ++ SMSC_WARNING(" Invalid index = 0x%ld",ioctlData->Data[0]); ++ } ++ } ++ break; ++ case COMMAND_GET_EEPROM: ++ offset = ioctlData->Data[0]; ++ privateData->eepromSize = smsc9500_eeprom_size(dev); ++ if(offset < privateData->eepromSize) { ++ if(smsc9500_read_eeprom(dev, offset, 1, &cBuf) >= 0){ ++ success = TRUE; ++ ioctlData->Data[1] = cBuf; ++ } ++ } else { ++ SMSC_WARNING("Reading EEPROM Failed"); ++ } ++ break; ++ case COMMAND_SET_EEPROM: ++ offset = ioctlData->Data[0]; ++ cBuf = (BYTE)ioctlData->Data[1]; ++ privateData->eepromSize = smsc9500_eeprom_size(dev); ++ if(offset < privateData->eepromSize) { ++ if (smsc9500_write_eeprom(dev, offset, 1, &cBuf) >= 0) { ++ success = TRUE; ++ } ++ } else { ++ SMSC_WARNING("Writing EEPROM Failed"); ++ if (!(offset < privateData->eepromSize)) { ++ SMSC_WARNING(" Invalid eeprom offset == 0x%d",offset); ++ } ++ } ++ break; ++ case COMMAND_SET_EEPROM_BUFFER: ++ offset = ioctlData->Data[0]; ++ len = ioctlData->Data[1]; ++ dataBuf = (BYTE *)&ioctlData->Data[2]; ++ privateData->eepromSize = smsc9500_eeprom_size(dev); ++ if (offset < privateData->eepromSize) { ++ if (smsc9500_write_eeprom(dev, offset, len, dataBuf) >= 0) { ++ success = TRUE; ++ } ++ } else { ++ SMSC_WARNING("Writing EEPROM Failed"); ++ if (!(offset < privateData->eepromSize)) { ++ SMSC_WARNING(" Invalid eeprom offset == 0x%d",offset); ++ } ++ } ++ break; ++ case COMMAND_DUMP_LAN_REGS: ++ success = TRUE; ++ for(i = 0; i < MAX_LAN_REG_NUM; i++){ ++ if (smsc9500_read_reg(dev, LanRegMap[i], &dwBuf) < 0) { ++ SMSC_WARNING("Failed to read LAN reg 0x%x", (unsigned int)LanRegMap[i]); ++ success = FALSE; ++ } else { ++ ioctlData->Data[i] = dwBuf; ++ } ++ } ++ break; ++ case COMMAND_DUMP_MAC_REGS: ++ if (privateData->LanInitialized) { ++ success=TRUE; ++ for(i=0; i<MAX_MAC_REG_NUM; i++){ ++ if (smsc9500_read_reg(dev, MacRegMap[i], &dwBuf) < 0) { ++ SMSC_WARNING("Failed to read MAC reg 0x%x", (unsigned int)MacRegMap[i]); ++ success = FALSE; ++ } else { ++ ioctlData->Data[i] = dwBuf; ++ } ++ } ++ } else { ++ SMSC_WARNING("Mac Not Initialized,"); ++ SMSC_WARNING(" Use ifconfig to bring interface UP"); ++ } ++ break; ++ case COMMAND_DUMP_PHY_REGS: ++ if (MdioDisable & MDIO_DISABLE_IOCTL_ACCESS) { ++ SMSC_WARNING("Phy Mdio ioctl access disabled\n"); ++ success = FALSE; ++ break; ++ } ++ if (privateData->LanInitialized) { ++ success = TRUE; ++ for(i=0; i<MAX_PHY_REG_NUM; i++) { ++ if (smsc9500_read_phy(dev, PhyRegMap[i], &dwBuf) < 0){ ++ SMSC_WARNING("Failed to read PHY reg 0x%x", (unsigned int)PhyRegMap[i]); ++ success = FALSE; ++ } else { ++ ioctlData->Data[i] = dwBuf; ++ } ++ } ++ } else { ++ SMSC_WARNING("Phy Not Initialized,"); ++ SMSC_WARNING(" Use ifconfig to bring interface UP"); ++ } ++ break; ++ case COMMAND_DUMP_EEPROM: ++ success = TRUE; ++ privateData->eepromSize = smsc9500_eeprom_size(dev); ++ if(smsc9500_read_eeprom(dev, 0, privateData->eepromSize, (BYTE*)ioctlData->Data) < 0) { ++ success = FALSE; ++ } ++ break; ++ case COMMAND_GET_MAC_ADDRESS: ++ if (privateData->LanInitialized) { ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, ADDRH, &dwBuf)); ++ ioctlData->Data[0] = dwBuf; ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, ADDRL, &dwBuf)); ++ ioctlData->Data[1] = dwBuf; ++ success = TRUE; ++ } else { ++ SMSC_WARNING("Lan Not Initialized,"); ++ SMSC_WARNING(" Use ifconfig to bring interface UP"); ++ } ++ break; ++ case COMMAND_SET_MAC_ADDRESS: ++ if(privateData->LanInitialized) { ++ u32 dwLow32 = ioctlData->Data[1]; ++ u32 dwHigh16 = ioctlData->Data[0]; ++ ++ if ((((dwHigh16 & 0xFFFF) == 0x0UL) && (dwLow32 == 0x0UL)) ++ || (0x01 & LOBYTE(LOWORD(dwLow32)))) { ++ SMSC_WARNING("Not a Valid MAC Address"); ++ } else { ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, ADDRH, dwHigh16)); ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, ADDRL, dwLow32)); ++ dev->net->dev_addr[0]=LOBYTE(LOWORD(dwLow32)); ++ dev->net->dev_addr[1]=HIBYTE(LOWORD(dwLow32)); ++ dev->net->dev_addr[2]=LOBYTE(HIWORD(dwLow32)); ++ dev->net->dev_addr[3]=HIBYTE(HIWORD(dwLow32)); ++ dev->net->dev_addr[4]=LOBYTE(LOWORD(dwHigh16)); ++ dev->net->dev_addr[5]=HIBYTE(LOWORD(dwHigh16)); ++ success = TRUE; ++ } ++ } else { ++ SMSC_WARNING("Lan Not Initialized,"); ++ SMSC_WARNING("Use ifconfig to bring interface UP"); ++ } ++ break; ++ case COMMAND_LOAD_MAC_ADDRESS: ++ if (privateData->LanInitialized) { ++ if (privateData->eepromContentValid == TRUE) { ++ if(smsc9500_read_eeprom(dev, EEPROM_MAC_OFFSET, 6, dev->net->dev_addr) == 0) { ++ dwBuf = dev->net->dev_addr[0] | dev->net->dev_addr[1] << 8 | ++ dev->net->dev_addr[2] << 16 | dev->net->dev_addr[3] << 24; ++ ioctlData->Data[1] = dwBuf; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, ADDRL, ioctlData->Data[1])); ++ dwBuf = dev->net->dev_addr[4] | dev->net->dev_addr[5] << 8; ++ ioctlData->Data[0] = dwBuf; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, ADDRH, ioctlData->Data[0])); ++ success = TRUE; ++ } else { ++ SMSC_WARNING("Failed to Load Mac Address"); ++ } ++ } else { ++ SMSC_WARNING("EEPROM contents not valid"); ++ } ++ } else { ++ SMSC_WARNING("Lan Not Initialized"); ++ SMSC_WARNING("Use ifconfig to bring interface UP"); ++ } ++ break; ++ case COMMAND_SAVE_MAC_ADDRESS: ++ if (privateData->LanInitialized) { ++ if (privateData->eepromContentValid == TRUE) { ++ u32 dwLow32 = ioctlData->Data[1]; ++ u32 dwHigh16 = ioctlData->Data[0]; ++ ++ cpu_to_le32s((u32*)&dwLow32); ++ cpu_to_le32s((u32*)&dwHigh16); ++ ++ if ((smsc9500_write_eeprom(dev, EEPROM_MAC_OFFSET, 4, (BYTE*)&dwLow32) == 0) && ++ (smsc9500_write_eeprom(dev, EEPROM_MAC_OFFSET+4, 2, (BYTE*)&dwHigh16) == 0)) { ++ success = TRUE; ++ } ++ } else { ++ SMSC_WARNING("EEPROM contents not valid"); ++ } ++ } else { ++ SMSC_WARNING("Lan Not Initialized,"); ++ SMSC_WARNING("Use ifconfig to bring interface UP"); ++ } ++ break; ++ case COMMAND_SET_DEBUG_MODE: ++ debug_mode = ioctlData->Data[0]; ++ if (debug_mode & 0x04UL) { ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, GPIO_CFG, 0x00670700UL)); ++ success = TRUE; ++ } else { ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, GPIO_CFG, 0x70070000)); ++ success = TRUE; ++ } ++ success = TRUE; ++ break; ++ case COMMAND_SET_LINK_MODE: ++ link_mode = (ioctlData->Data[0] & 0x7FUL); ++ if (privateData->LanInitialized) { ++ phy_SetLink(dev, link_mode); ++ } ++ success = TRUE; ++ break; ++ case COMMAND_GET_LINK_MODE: ++ ioctlData->Data[0] = link_mode; ++ success = TRUE; ++ break; ++ case COMMAND_CHECK_LINK: ++ Phy_UpdateLinkMode(dev); ++ success = TRUE; ++ break; ++ case COMMAND_SET_LINK_STATUS: ++ if (!(MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS)) { ++ SMSC_WARNING("This ioctl available only when Phy Mdio internal access disabled\n"); ++ success = FALSE; ++ break; ++ } ++ /* Assign the link status from user, link check will ++ set the link */ ++ privateData->DefaultLinkStatus = (ioctlData->Data[0] & 0x1UL); ++ success = TRUE; ++ break; ++ case COMMAND_GET_LINK_STATUS: ++ if (!(MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS)) { ++ SMSC_WARNING("This ioctl available only when Phy Mdio internal access disabled\n"); ++ success = FALSE; ++ break; ++ } ++ ioctlData->Data[0] = privateData->DefaultLinkStatus & MDIO_DEFAULT_LINK_INIT_MASK; ++ success = TRUE; ++ break; ++ case COMMAND_GET_ERRORS: ++ ioctlData->Data[0] = dev->extra_error_cnts.tx_epipe; ++ ioctlData->Data[1] = dev->extra_error_cnts.tx_eproto; ++ ioctlData->Data[2] = dev->extra_error_cnts.tx_etimeout; ++ ioctlData->Data[3] = dev->extra_error_cnts.tx_eilseq; ++ ++ ioctlData->Data[4] = dev->extra_error_cnts.rx_epipe; ++ ioctlData->Data[5] = dev->extra_error_cnts.rx_eproto; ++ ioctlData->Data[6] = dev->extra_error_cnts.rx_etimeout; ++ ioctlData->Data[7] = dev->extra_error_cnts.rx_eilseq; ++ ioctlData->Data[8] = dev->extra_error_cnts.rx_eoverflow; ++ success = TRUE; ++ break; ++ case COMMAND_READ_BYTE: ++ ioctlData->Data[1] = (*((volatile BYTE *)(ioctlData->Data[0]))); ++ success = TRUE; ++ break; ++ case COMMAND_READ_WORD: ++ ioctlData->Data[1] = (*((volatile u16 *)(ioctlData->Data[0]))); ++ success = TRUE; ++ break; ++ case COMMAND_READ_DWORD: ++ ioctlData->Data[1] = (*((volatile u32 *)(ioctlData->Data[0]))); ++ success = TRUE; ++ break; ++ case COMMAND_WRITE_BYTE: ++ (*((volatile BYTE *)(ioctlData->Data[0])))= ((BYTE)(ioctlData->Data[1])); ++ success = TRUE; ++ break; ++ case COMMAND_WRITE_WORD: ++ (*((volatile u16 *)(ioctlData->Data[0])))= ((u16)(ioctlData->Data[1])); ++ success = TRUE; ++ break; ++ case COMMAND_WRITE_DWORD: ++ (*((volatile u32 *)(ioctlData->Data[0])))= ((u32)(ioctlData->Data[1])); ++ success = TRUE; ++ break; ++ case COMMAND_SET_AMDIX_STS: ++ auto_mdix = (ioctlData->Data[0]); ++ if (privateData->LanInitialized) { ++ Phy_SetAutoMdix(dev, (u16)auto_mdix); ++ } ++ success = TRUE; ++ break; ++ case COMMAND_GET_AMDIX_STS: ++ ioctlData->Data[0] = auto_mdix; ++ success = TRUE; ++ break; ++ ++ default: ++ break; ++ } ++ ++DONE: ++ if ((success) && (ioctlData!=NULL)) { ++ ioctlData->dwSignature = SMSC9500_DRIVER_SIGNATURE; ++ return SMSC9500_SUCCESS; ++ } ++ return SMSC9500_FAIL; ++} ++ ++static int smsc9500_eth_mac_addr(struct net_device *netdev, void *p) ++{ ++ struct sockaddr *addr = p; ++ struct usbnet *dev = netdev_priv(netdev); ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ if (netif_running(netdev)) ++ return -EBUSY; ++ if (!is_valid_ether_addr((u8 *)addr->sa_data)) ++ return -EADDRNOTAVAIL; ++ memcpy(dev->net->dev_addr, addr->sa_data, ETH_ALEN); ++ ++ adapterData->MmacAddrLo32 = dev->net->dev_addr[0] | dev->net->dev_addr[1] << 8 | ++ dev->net->dev_addr[2] << 16 | dev->net->dev_addr[3] << 24; ++ adapterData->macAddrHi16 = dev->net->dev_addr[4] | dev->net->dev_addr[5] << 8; ++ ++ return 0; ++} ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) ++static const struct net_device_ops smsc95xx_netdev_ops = ++{ ++ .ndo_open = smscusbnet_open, ++ .ndo_stop = smscusbnet_stop, ++ .ndo_start_xmit = smscusbnet_start_xmit, ++ .ndo_tx_timeout = smscusbnet_tx_timeout, ++ .ndo_change_mtu = smscusbnet_change_mtu, ++ .ndo_set_mac_address = smsc9500_eth_mac_addr, ++ .ndo_validate_addr = eth_validate_addr, ++ .ndo_do_ioctl = Smsc9500_do_ioctl, ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,1,10)) ++ .ndo_set_multicast_list = smsc9500_set_multicast, ++#else ++ .ndo_set_rx_mode=smsc9500_set_multicast, ++#endif ++ .ndo_get_stats = smscusbnet_get_stats, ++}; ++#endif //linux 2.6.29 ++ ++static int smsc9500_bind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ u32 dwBuf; ++ int ret = 0; ++ PADAPTER_DATA adapterData = NULL; ++ char version[15]; ++ ++ SMSC_TRACE(DBG_INIT, "smsc9500_bind"); ++ ++ /* Init system control and status regsiter map */ ++ LanRegMap[LAN_REG_ID_REV] = ID_REV; ++ LanRegMap[LAN_REG_FPGA_REV] = FPGA_REV; ++ LanRegMap[LAN_REG_INT_STS] = INT_STS; ++ LanRegMap[LAN_REG_RX_CFG] = RX_CFG; ++ LanRegMap[LAN_REG_TX_CFG] = TX_CFG; ++ LanRegMap[LAN_REG_HW_CFG] = HW_CFG; ++ LanRegMap[LAN_REG_RX_FIFO_INF] = RX_FIFO_INF; ++ LanRegMap[LAN_REG_TX_FIFO_INF] = TX_FIFO_INF; ++ LanRegMap[LAN_REG_PMT_CTRL] = PM_CTRL; ++ LanRegMap[LAN_REG_LED_GPIO_CFG] = LED_GPIO_CFG; ++ LanRegMap[LAN_REG_GPIO_CFG] = GPIO_CFG; ++ LanRegMap[LAN_REG_AFC_CFG] = AFC_CFG; ++ LanRegMap[LAN_REG_E2P_CMD] = E2P_CMD; ++ LanRegMap[LAN_REG_E2P_DATA] = E2P_DATA; ++ LanRegMap[LAN_REG_BURST_CAP] = BURST_CAP; ++ LanRegMap[LAN_REG_STRAP_DBG] = STRAP_DBG; ++ LanRegMap[LAN_REG_DP_SEL] = DP_SEL; ++ LanRegMap[LAN_REG_DP_CMD] = DP_CMD; ++ LanRegMap[LAN_REG_DP_ADDR] = DP_ADDR; ++ LanRegMap[LAN_REG_DP_DATA0] = DP_DATA0; ++ LanRegMap[LAN_REG_DP_DATA1] = DP_DATA1; ++ LanRegMap[LAN_REG_GPIO_WAKE] = GPIO_WAKE; ++ LanRegMap[LAN_REG_INT_EP_CTL] = INT_EP_CTL; ++ LanRegMap[LAN_REG_BULK_IN_DLY] = BULK_IN_DLY; ++ ++ /* Init MAC register map */ ++ MacRegMap[MAC_REG_MAC_CR] = MAC_CR; ++ MacRegMap[MAC_REG_ADDRH] = ADDRH; ++ MacRegMap[MAC_REG_ADDRL] = ADDRL; ++ MacRegMap[MAC_REG_HASHH] = HASHH; ++ MacRegMap[MAC_REG_HASHL] = HASHL; ++ MacRegMap[MAC_REG_MII_ADDR] = MII_ADDR; ++ MacRegMap[MAC_REG_MII_DATA] = MII_DATA; ++ MacRegMap[MAC_REG_FLOW] = FLOW; ++ MacRegMap[MAC_REG_VLAN1] = VLAN1; ++ MacRegMap[MAC_REG_VLAN2] = VLAN2; ++ MacRegMap[MAC_REG_WUFF] = WUFF; ++ MacRegMap[MAC_REG_WUCSR] = WUCSR; ++ MacRegMap[MAC_REG_COE_CR] = COE_CR; ++ ++ /* Init PHY map */ ++ PhyRegMap[PHY_REG_BCR] = PHY_BCR; ++ PhyRegMap[PHY_REG_BSR] = PHY_BSR; ++ PhyRegMap[PHY_REG_ID1] = PHY_ID_1; ++ PhyRegMap[PHY_REG_ID2] = PHY_ID_2; ++ PhyRegMap[PHY_REG_ANEG_ADV] = PHY_ANEG_ADV; ++ PhyRegMap[PHY_REG_ANEG_LPA] = PHY_ANEG_LPA; ++ PhyRegMap[PHY_REG_ANEG_ER] = PHY_ANEG_REG; ++ PhyRegMap[PHY_REG_SILICON_REV] = PHY_SILICON_REV; ++ PhyRegMap[PHY_REG_MODE_CTRL_STS] = PHY_MODE_CTRL_STS; ++ PhyRegMap[PHY_REG_SPECIAL_MODES] = PHY_SPECIAL_MODES; ++ PhyRegMap[PHY_REG_TSTCNTL] = PHY_TSTCNTL; ++ PhyRegMap[PHY_REG_TSTREAD1] = PHY_TSTREAD1; ++ PhyRegMap[PHY_REG_TSTREAD2] = PHY_TSTREAD2; ++ PhyRegMap[PHY_REG_TSTWRITE] = PHY_TSTWRITE; ++ PhyRegMap[PHY_REG_SPECIAL_CTRL_STS] = PHY_SPECIAL_CTRL_STS; ++ PhyRegMap[PHY_REG_SITC] = PHY_SITC; ++ PhyRegMap[PHY_REG_INT_SRC] = PHY_INT_SRC; ++ PhyRegMap[PHY_REG_INT_MASK] = PHY_INT_MASK; ++ PhyRegMap[PHY_REG_SPECIAL] = PHY_SPECIAL; ++ ++ sprintf(version,"%lX.%02lX.%02lX", ++ (DRIVER_VERSION >> 16),(DRIVER_VERSION >> 8)&0xFF,(DRIVER_VERSION&0xFFUL)); ++ SMSC_TRACE(DBG_INIT, "Driver smsc9500.ko verison %s",version); ++ ++ ret = smscusbnet_get_endpoints(dev,intf); ++ if (ret < 0) ++ goto out1; ++ ++ dev->data[0] = (unsigned long) kmalloc(sizeof(ADAPTER_DATA),GFP_KERNEL); ++ ++ if ((PADAPTER_DATA)dev->data[0] == NULL) { ++ SMSC_WARNING("Unable to allocate ADAPTER_DATA"); ++ ret = -ENOMEM; ++ goto out1; ++ } ++ memset((PADAPTER_DATA)dev->data[0],0,sizeof(ADAPTER_DATA)); ++ adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ sema_init(&adapterData->phy_mutex, 1); ++ sema_init(&adapterData->eeprom_mutex, 1); ++ sema_init(&adapterData->internal_ram_mutex, 1); ++ sema_init(&adapterData->RxFilterLock, 1); ++ ++ if ((ret = smsc9500_read_reg(dev,HW_CFG,&dwBuf)< 0)) { ++ SMSC_WARNING("Failed to read HW_CFG: %d", ret); ++ return ret; ++ } ++ if (dwBuf & HW_CFG_SMDET_STS) { ++ SMSC_TRACE(DBG_INIT, "Come back from net detach"); ++ } ++ ++ adapterData->macAddrHi16 = mac_addr_hi16; ++ adapterData->MmacAddrLo32 = mac_addr_lo32; ++ ++ /* set initial value for eeprom related variables */ ++ adapterData->eepromContentValid = IsEepromContentValid(dev); ++ ++ adapterData->LinkActLedCfg = LinkActLedCfg; ++ adapterData->LinkLedOnGpio = LinkLedOnGpio; ++ adapterData->LinkLedOnGpioBufType = LinkLedBufType; ++ adapterData->LinkLedOnGpioPolarity = LinkLedPolarity; ++ ++ adapterData->eepromSize = smsc9500_eeprom_size(dev); ++ ++ /* Reset and Init all registers */ ++ ret = smsc9500_reset(dev); ++ if (ret < 0) ++ goto out1; ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) ++ dev->net->do_ioctl = Smsc9500_do_ioctl; ++ dev->net->set_multicast_list = smsc9500_set_multicast; ++ dev->net->set_mac_address = smsc9500_eth_mac_addr; ++#else ++ dev->net->netdev_ops = &smsc95xx_netdev_ops; ++#endif ++ dev->net->ethtool_ops = &smsc9500_ethtool_ops; ++ dev->net->flags |= IFF_MULTICAST; ++ dev->linkDownSuspend = linkdownsuspend; ++ dev->dynamicSuspend = dynamicsuspend; ++ ++ if (dev->udev->config->desc.bmAttributes & USB_CONFIG_ATT_WAKEUP) { ++ SMSC_TRACE(DBG_INIT, "The device is configed to support remote wakes"); ++ } else { ++ SMSC_WARNING("The device not configed to support remote wakes, " ++ "Over write to disable linkdownsuspend and dynamicsuspend"); ++ if (dev->dynamicSuspend || dev->linkDownSuspend) { ++ dev->dynamicSuspend = dev->linkDownSuspend = 0; ++ } ++ } ++ if (dev->linkDownSuspend && (MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS)) { ++ SMSC_WARNING("linkdownsuspend cannot be supported when mdio access is disabled, " ++ "Over write to disable linkdownsuspend\n"); ++ dev->linkDownSuspend = 0; ++ } ++ ++#ifndef CONFIG_PM ++ if (dev->dynamicSuspend || dev->linkDownSuspend) { ++ SMSC_WARNING("Power management has to be enabled in the kernel configuration " ++ "to support dynamicsuspend and linkdownsuspend"); ++ dev->dynamicSuspend = dev->linkDownSuspend = 0; ++ } ++#endif //CONFIG_PM ++ if (dev->chipDependFeatures[FEATURE_SMARTDETACH]) { ++ dev->netDetach = netdetach; ++ /* If net detach is enabled, link down suspend should be disabled */ ++ if (dev->netDetach) ++ dev->linkDownSuspend = 0; ++ } ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) && defined(CONFIG_PM) ++ if (dev->dynamicSuspend || dev->linkDownSuspend) { ++#if ((LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))) ++ if (dev->udev->autosuspend_disabled) { ++#endif ++ SMSC_WARNING("Autosuspend should be enabled by " ++ "shell cmd \"echo auto > /sys/bus/usb/devices/X-XX/power/level\""); ++#if ((LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))) ++ } ++#endif ++ } ++#endif ++ adapterData->UseTxCsum = tx_Csum; ++ adapterData->UseRxCsum = rx_Csum; ++ if (tx_Csum) ++ SMSC_TRACE(DBG_INIT, "Tx HW Checksum"); ++ if (rx_Csum) ++ SMSC_TRACE(DBG_INIT, "Rx HW Checksum"); ++ ++ if (adapterData->UseTxCsum) ++ dev->net->features = (NETIF_F_HW_CSUM); ++ else ++ dev->net->features = 0; ++ ++ adapterData->dwTxQueueDisableMask = 0; ++ spin_lock_init(&(adapterData->TxQueueLock)); ++ adapterData->TxInitialized = TRUE; ++ adapterData->WolWakeupOpts = WAKE_PHY; ++ adapterData->LanInitialized = TRUE; ++ ++ /* Indicate carrier off explicitly. Link check will indicate if link is up */ ++ netif_carrier_off(dev->net); ++ /* Get the default link status for MDIO-less operation */ ++ adapterData->DefaultLinkStatus = MdioDefaultLinkStatus; ++ ++ SMSC_TRACE(DBG_INIT, "smsc9500_bind, return 0"); ++ return 0; ++out1: ++ if (adapterData != NULL){ ++ kfree(adapterData); ++ adapterData = NULL; ++ } ++ SMSC_TRACE(DBG_INIT, "smsc9500_bind, return %x", ret); ++ return ret; ++} ++ ++ ++static void smsc9500_unbind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ SMSC_TRACE(DBG_CLOSE, "smsc9500_unbind"); ++ ++ if (adapterData != NULL) { ++ SMSC_TRACE(DBG_CLOSE, "free adapterData"); ++ kfree(adapterData); ++ adapterData = NULL; ++ } ++} ++ ++static int smsc9500_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ++{ ++ u16 size; ++ char *packet; ++ struct sk_buff *ax_skb; ++ u32 header, AlignCount = 0; ++ int ret = RX_FIXUP_VALID_SKB; ++ u16 *vlan_tag; ++ ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ SMSC_TRACE(DBG_RX, "smsc9500_rx_fixup"); ++ ++ while (skb->len > 0) { ++ memcpy(&header, skb->data, sizeof(header)); ++ le32_to_cpus(&header); ++ skb_pull(skb, 4 + RX_OFFSET); ++ packet = (char *)skb->data; ++ ++ /* get the packet length */ ++ size = (u16) ((header & RX_STS_FL_) >> 16); ++ AlignCount = (STATUS_WORD_LEN - ((size + RX_OFFSET) % STATUS_WORD_LEN)) % STATUS_WORD_LEN; ++ ++ if (header & RX_STS_ES_) { ++ dev->stats.rx_errors++; ++ if (header & RX_STS_CRC_) { ++ dev->stats.rx_crc_errors++; ++ } else { ++ if (header & (RX_STS_TL_ | RX_STS_RF_)) { ++ dev->stats.rx_frame_errors++; ++ } ++ if (((header & RX_STS_LE_) != 0L) && ((header & RX_STS_FT_) == 0L)) { ++ dev->stats.rx_length_errors++; ++ } ++ } ++ /* last packet */ ++ if (size == skb->len) { ++ return RX_FIXUP_INVALID_SKB; ++ } else { ++ skb_pull(skb, size + AlignCount); ++ if (skb->len == 0) { ++ return RX_FIXUP_INVALID_SKB; ++ } ++ continue; ++ } ++ } ++ ++ if ((size == skb->len)) { ++ if (adapterData->UseRxCsum) { ++ u16 wHwCsum; ++#ifdef NET_SKBUFF_DATA_USES_OFFSET ++ wHwCsum = *(u16*)(skb_tail_pointer(skb) - 2); ++#else ++ wHwCsum = *(u16*)(skb->tail - 2); ++#endif ++ skb->csum = wHwCsum; ++ } ++ ++ if (adapterData->UseRxCsum) { ++ skb->ip_summed = CHECKSUM_COMPLETE; ++ } else { ++ skb->ip_summed = CHECKSUM_NONE; ++ } ++ ++ if (adapterData->UseRxCsum) { ++ skb_trim(skb, size - 2 - 4); ++ ++ } else { ++ skb_trim(skb, size - 4); ++ } ++ ++ if (dev->rx_skb_copy) { ++ if (dev->turbo_mode) { ++ ax_skb = alloc_skb(skb->len + dev->net_ip_align, GFP_ATOMIC); ++ skb_reserve(ax_skb, dev->net_ip_align); ++ skb_put(ax_skb, skb->len); ++ memcpy(ax_skb->data, skb->data, skb->len); ++ ++ vlan_tag = (u16*)&ax_skb->cb[0]; ++ *vlan_tag = VLAN_DUMMY; //Reserved value ++ smscusbnet_skb_return(dev, ax_skb); ++ ret = RX_FIXUP_INVALID_SKB; ++ } else { ++ if (dev->rx_use_prealloc_buffs) { ++ ax_skb = alloc_skb(skb->len + dev->net_ip_align, GFP_ATOMIC); ++ skb_reserve(ax_skb, dev->net_ip_align); ++ skb_put(ax_skb, skb->len); ++ memcpy(ax_skb->data, skb->data, skb->len); ++ ++ vlan_tag = (u16*)&ax_skb->cb[0]; ++ *vlan_tag = VLAN_DUMMY; //Reserved value ++ smscusbnet_skb_return(dev, ax_skb); ++ ret = RX_FIXUP_INVALID_SKB; ++ } else { ++ ret = RX_FIXUP_VALID_SKB; ++ vlan_tag = (u16*)&skb->cb[0]; ++ *vlan_tag = VLAN_DUMMY; //Reserved value ++ } ++ } ++ } else { ++ /* FIXME: We are not supposed to change truesize, ++ but this is the easy way to cheat kernel without ++ memory copy */ ++ skb->truesize = skb->len + sizeof(struct sk_buff); ++ vlan_tag = (u16*)&skb->cb[0]; ++ *vlan_tag = VLAN_DUMMY; //Reserved value ++ } ++ return ret; ++ } ++ ++ if (size > (ETH_FRAME_LEN+12)) {// ETH_FRAME_LEN+4(CRC)+2(COE)+4(Vlan) ++ SMSC_TRACE(DBG_RX, "size > (ETH_FRAME_LEN+12), hearder = 0x%08x", header); ++ return RX_FIXUP_ERROR; ++ } ++ ++ if (dev->rx_skb_copy) { ++ ax_skb = alloc_skb(size + dev->net_ip_align, GFP_ATOMIC); ++ skb_reserve(ax_skb, dev->net_ip_align); ++ } else { ++ ax_skb = skb_clone(skb, GFP_ATOMIC); ++ } ++ ++ if (ax_skb) { ++ if (dev->rx_skb_copy) { ++ skb_put(ax_skb, size); ++ memcpy(ax_skb->data, packet, size); ++ } else { ++ ax_skb->len = size; ++ ax_skb->data = (u8 *)packet; ++ skb_trim(ax_skb, 0); ++ skb_put(ax_skb, size); ++ } ++ ++ if (adapterData->UseRxCsum) { ++ u16 wHwCsum; ++#ifdef NET_SKBUFF_DATA_USES_OFFSET ++ wHwCsum = *(u16*)(skb_tail_pointer(ax_skb) - 2); ++#else ++ wHwCsum = *(u16*)(ax_skb->tail - 2); ++#endif ++ ax_skb->csum = wHwCsum; ++ } ++ ++ if (adapterData->UseRxCsum) { ++ ax_skb->ip_summed = CHECKSUM_COMPLETE; ++ } else { ++ ax_skb->ip_summed = CHECKSUM_NONE; ++ } ++ ++ if (adapterData->UseRxCsum) { ++ skb_trim(ax_skb, size-2-4); ++ ++ } else { ++ skb_trim(ax_skb, size-4); ++ } ++ ++ if (!dev->rx_skb_copy) { ++ /* FIXME: We are not supposed to change truesize, ++ but this is the easy way to cheat kernel without ++ memory copy */ ++ ax_skb->truesize = ax_skb->len + sizeof(struct sk_buff); ++ } ++ ++ vlan_tag = (u16*)&ax_skb->cb[0]; ++ *vlan_tag = VLAN_DUMMY; //Reserved value ++ smscusbnet_skb_return(dev, ax_skb); ++ } else { ++ SMSC_TRACE(DBG_RX, "no ax_skb"); ++ return RX_FIXUP_ERROR; ++ } ++ ++ skb_pull(skb, size + AlignCount); ++ ++ if (skb->len == 0) { ++ SMSC_TRACE(DBG_RX, "skb->len == 0 left"); ++ break; ++ } ++ } ++ ++ if (skb->len < 0) { ++ SMSC_WARNING("invalid rx length < 0 %d", skb->len); ++ return RX_FIXUP_ERROR; ++ } ++ ++ return ret; ++} ++ ++static struct sk_buff *smsc9500_tx_fixup(struct usbnet *dev, struct sk_buff *skb, int flags) ++{ ++ int i; ++ u8 * prt; ++ u32 TxCommandA,TxCommandB; ++ int headroom = skb_headroom(skb); ++ int tailroom = skb_tailroom(skb); ++ int SkbSize, CopySize, AlignmentSize; ++ unsigned skbFragCnt = skb_shinfo(skb)->nr_frags + 1; ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ SMSC_TRACE(DBG_TX, "smsc9500_tx_fixup"); ++ ++ if (adapterData->UseTxCsum) { ++ u32 dwTxCsumPreamble = 0; ++ if (skb->ip_summed == CHECKSUM_PARTIAL) { ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) ++ int Chsum_start_offset = 0; ++ CalculateTxChecksumOffset( skb, &Chsum_start_offset); ++ ++ /* tx checksum problem workaround */ ++ if (skb->len <= 45) { ++ u32 csum; ++ csum = csum_partial(skb->data + Chsum_start_offset, ++ skb->len - (skb->data + Chsum_start_offset - skb->data), 0); ++ *((u16 *)(skb->data + Chsum_start_offset + skb->csum)) = csum_fold(csum); ++ goto Non_CheckSumOffLoad; ++ } ++ dwTxCsumPreamble = (((u16) (Chsum_start_offset + skb->csum)) << 16) | ((u16) Chsum_start_offset); ++#else ++ /* tx checksum problem workaround */ ++ if (skb->len <= 45) { ++ u32 csum; ++ csum = csum_partial(skb->head + skb->csum_start, skb->len - ++ (skb->head + skb->csum_start - skb->data), 0); ++ *((u16 *)(skb->head + (skb->csum_start + skb->csum_offset))) = csum_fold(csum); ++ goto Non_CheckSumOffLoad; ++ } ++ dwTxCsumPreamble = (((u16) (skb->csum_offset+skb->csum_start-(skb->data - skb->head))) << 16) ++ | ((u16) (skb->csum_start-(skb->data - skb->head))); ++#endif ++ } ++ if(skb->ip_summed == CHECKSUM_PARTIAL) { ++ if (skbFragCnt == 1) { ++ /* ip_summed, one Fragament */ ++ SMSC_TRACE(DBG_TX, "ip_summed, Onefrag"); ++ ++ AlignmentSize = skb->len % STATUS_WORD_LEN; ++ if(AlignmentSize)AlignmentSize = STATUS_WORD_LEN - AlignmentSize; ++ if (tx_skb_clone && (!skb_cloned(skb)) ++ && ((headroom + tailroom) >= (12 + AlignmentSize))) { ++ if( (headroom < 12 ) || (tailroom < AlignmentSize) ){ ++ skb->data = memmove(skb->head +12, skb->data, skb->len); ++ SkbSize = skb->len; ++ skb_trim(skb, 0); ++ skb_put(skb, SkbSize); ++ } ++ } else { ++ struct sk_buff *skb2; ++ skb2 = skb_copy_expand(skb, 12, AlignmentSize, flags); ++ dev_kfree_skb_any(skb); ++ skb = skb2; ++ if (!skb) ++ return NULL; ++ } ++ ++ skb_push(skb, STATUS_WORD_LEN); ++ memcpy(skb->data, &dwTxCsumPreamble, STATUS_WORD_LEN); ++ ++ skb_push(skb, STATUS_WORD_LEN); ++ TxCommandB = (u32)(skb->len-STATUS_WORD_LEN)|TX_CMD_B_CSUM_ENABLE; ++ cpu_to_le32s((u32*)&TxCommandB); ++ memcpy(skb->data, &TxCommandB, STATUS_WORD_LEN); ++ skb_push(skb, STATUS_WORD_LEN); ++ TxCommandA = TX_CMD_A_FIRST_SEG_ | TX_CMD_A_LAST_SEG_ | (u32)(skb->len-8); ++ cpu_to_le32s((u32*)&TxCommandA); ++ memcpy(skb->data, &TxCommandA, STATUS_WORD_LEN); ++ skb_put(skb, AlignmentSize); ++ return skb; ++ } else { ++ /* ip_summed, Multi Fragament */ ++ struct sk_buff *skb2; ++ SkbSize = skb->len+4*4*(skbFragCnt+1); ++ skb2 = dev_alloc_skb(SkbSize); ++ ++ SMSC_TRACE(DBG_TX, "ip_summed, Multifrags"); ++ ++ if (!skb2) ++ return NULL; ++ ++ skb_put(skb2, SkbSize); ++ { ++ TxCommandA = TX_CMD_A_FIRST_SEG_ |((u32)sizeof(u32)); ++ ++ TxCommandB = TX_CMD_B_CSUM_ENABLE |((u32)(skb->len+STATUS_WORD_LEN)) ; ++ cpu_to_le32s((u32*)&TxCommandA); ++ cpu_to_le32s((u32*)&TxCommandB); ++ ++ memcpy(skb2->data, &TxCommandA, STATUS_WORD_LEN); ++ memcpy(skb2->data + STATUS_WORD_LEN, &TxCommandB, STATUS_WORD_LEN); ++ memcpy(skb2->data + 8, &dwTxCsumPreamble, STATUS_WORD_LEN); ++ } ++ { ++ TxCommandA = ++ ((((unsigned long)(skb->data))&0x03UL)<<16) | //u32 alignment adjustment ++ ((u32)((skb->len)-(skb->data_len))); ++ TxCommandB = ((u32)(skb->len+STATUS_WORD_LEN)); ++ cpu_to_le32s((u32*)&TxCommandA); ++ cpu_to_le32s((u32*)&TxCommandB); ++ CopySize = ((((u32)(skb->len - skb->data_len))+3+(((unsigned long)(skb->data))&0x03UL))>>2)*4; ++ memcpy(skb2->data + 12, &TxCommandA, STATUS_WORD_LEN); ++ memcpy(skb2->data + 12 + STATUS_WORD_LEN, &TxCommandB, STATUS_WORD_LEN); ++ memcpy(skb2->data + 12 + STATUS_WORD_LEN * 2, (u32 *)(((unsigned long)(skb->data))&0xFFFFFFFCUL),CopySize); ++ } ++ ++ prt = (u8 *)skb2->data+20+CopySize; ++ ++ for(i = 1; i < skbFragCnt;i++) { ++ skb_frag_t *frag = &skb_shinfo(skb)->frags[i - 1]; ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0)) ++ void *frag_addr = ((unsigned char *) page_address(frag->page) + frag->page_offset); ++#else ++ void *frag_addr = (void *)skb_frag_address(frag); ++#endif ++ ++ TxCommandA = ((((unsigned long)(frag_addr))&0x03UL)<<16) | //alignment adjustment ++ ((u32)(frag->size)); ++ ++ if (i == (skbFragCnt-1)) { ++ TxCommandA |= TX_CMD_A_LAST_SEG_ ; ++ } ++ ++ TxCommandB = ((u32)(skb->len+STATUS_WORD_LEN)); ++ cpu_to_le32s((u32*)&TxCommandA); ++ cpu_to_le32s((u32*)&TxCommandB); ++ memcpy(prt, &TxCommandA, STATUS_WORD_LEN); ++ prt = prt + STATUS_WORD_LEN; ++ memcpy(prt, &TxCommandB, STATUS_WORD_LEN); ++ prt = prt + STATUS_WORD_LEN; ++ CopySize = ((((unsigned long)(frag->size)) + 3 + ++ (((unsigned long)(frag_addr))&0x03UL)) >> 2) * 4; ++ memcpy(prt, (u32 *)(((unsigned long)(frag_addr)) & 0xFFFFFFFCUL), CopySize); ++ prt = prt+CopySize; ++ } ++ ++ skb_trim(skb2,prt-skb2->data); ++ dev_kfree_skb_any(skb); ++ return skb2; ++ } ++ ++ } else { ++ if (skbFragCnt > 1) { ++ /* Non ip_summed, Multifrags */ ++ ++ struct sk_buff *skb2; ++ SkbSize = skb->len+4*4*skbFragCnt; ++ skb2 = dev_alloc_skb(SkbSize); ++ SMSC_TRACE(DBG_TX, "Non ip_summed, Multifrags"); ++ ++ if (!skb2) ++ return NULL; ++ ++ skb_put(skb2, SkbSize); ++ { ++ TxCommandA =((((unsigned long)(skb->data)) & 0x03UL) << 16) | //u32 alignment adjustment ++ TX_CMD_A_FIRST_SEG_ | (u32)((skb->len) - (skb->data_len)); ++ ++ TxCommandB = TX_CMD_B_CSUM_ENABLE |((u32)(skb->len)); ++ cpu_to_le32s((u32*)&TxCommandA); ++ cpu_to_le32s((u32*)&TxCommandB); ++ SMSC_TRACE(DBG_TX, "first frag."); ++ CopySize = ((((unsigned long)((skb->len) - (skb->data_len))) + 3 + ++ (((unsigned long)(skb->data))&0x03UL)) >> 2)*4; ++ memcpy(skb2->data, &TxCommandA, STATUS_WORD_LEN); ++ memcpy(skb2->data + STATUS_WORD_LEN, &TxCommandB, STATUS_WORD_LEN); ++ memcpy(skb2->data + STATUS_WORD_LEN * 2, ++ (void *)(((unsigned long)(skb->data)) & 0xFFFFFFFCUL),CopySize); ++ } ++ ++ prt = (u8 *)skb2->data+8+CopySize; ++ for(i = 1; i < skbFragCnt; i++) { ++ skb_frag_t *frag = &skb_shinfo(skb)->frags[i - 1]; ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0)) ++ ++ void *frag_addr = ((unsigned char *)page_address(frag->page) + frag->page_offset); ++#else ++ void *frag_addr = (void *)skb_frag_address(frag); ++#endif ++ TxCommandA = ((((unsigned long)(frag_addr))&0x03UL)<<16) | //u32 alignment adjustment ++ ((u32)(frag->size)); ++ ++ if (i == (skbFragCnt - 1)) { ++ TxCommandA |= TX_CMD_A_LAST_SEG_ ; ++ } ++ ++ TxCommandB = ((u32)(skb->len)); ++ cpu_to_le32s((u32*)&TxCommandA); ++ cpu_to_le32s((u32*)&TxCommandB); ++ memcpy(prt, &TxCommandA, STATUS_WORD_LEN); ++ prt = prt + STATUS_WORD_LEN; ++ memcpy(prt, &TxCommandB, STATUS_WORD_LEN); ++ prt = prt + STATUS_WORD_LEN; ++ ++ CopySize = ((((unsigned long)(frag->size)) + 3 + ++ (((unsigned long)(frag_addr)) & 0x03UL)) >> 2) * 4; ++ memcpy(prt, (void *)(((unsigned long)(frag_addr)) & 0xFFFFFFFCUL), CopySize); ++ prt = prt+CopySize; ++ } ++ ++ skb_trim(skb2,prt-skb2->data); ++ dev_kfree_skb_any(skb); ++ SMSC_TRACE(DBG_TX, "return from Nonip_summed, Multifrags"); ++ return skb2; ++ } else { ++ goto Non_CheckSumOffLoad; ++ } ++ } ++ } else { ++Non_CheckSumOffLoad: ++ /* Non ip_summed, onefrag */ ++ SMSC_TRACE(DBG_TX, "Non ip_summed, onefrag"); ++ AlignmentSize = skb->len % STATUS_WORD_LEN; ++ if (AlignmentSize) ++ AlignmentSize = STATUS_WORD_LEN - AlignmentSize; ++ ++ if (tx_skb_clone && (!skb_cloned(skb)) ++ && ((headroom + tailroom) >= (2*STATUS_WORD_LEN + AlignmentSize))) { ++ if ((headroom < (2*STATUS_WORD_LEN)) || (tailroom < AlignmentSize)){ ++ skb->data = memmove(skb->head + 2 * STATUS_WORD_LEN, skb->data, skb->len); ++ SkbSize = skb->len; ++ skb_trim(skb, 0); ++ skb_put(skb, SkbSize); ++ } ++ } else { ++ struct sk_buff *skb2; ++ skb2 = skb_copy_expand(skb, 2*STATUS_WORD_LEN, AlignmentSize, flags); ++ dev_kfree_skb_any(skb); ++ skb = skb2; ++ if (!skb) ++ return NULL; ++ } ++ ++ skb_push(skb, STATUS_WORD_LEN); ++ TxCommandB = (u32)(skb->len - STATUS_WORD_LEN); ++ cpu_to_le32s((u32*)&TxCommandB); ++ ++ memcpy(skb->data, &TxCommandB, STATUS_WORD_LEN); ++ skb_push(skb, STATUS_WORD_LEN); ++ TxCommandA = TX_CMD_A_FIRST_SEG_ | TX_CMD_A_LAST_SEG_ | (u32)(skb->len - 2*STATUS_WORD_LEN); ++ cpu_to_le32s((u32*)&TxCommandA); ++ memcpy(skb->data, &TxCommandA, STATUS_WORD_LEN); ++ ++ skb_put(skb, AlignmentSize); ++ return skb; ++ } ++} ++ ++static int smsc9500_reset(struct usbnet *dev) ++{ ++ int ret=0, Timeout; ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ u32 dwReadBuf, dwAddrH, dwAddrL, dwWriteBuf,dwMacCr,DwTemp, dwBurstCap; ++ ++ u32 dwLedGpioCfg; ++ ++ SMSC_TRACE(DBG_INIT, "smsc9500_reset"); ++ ++ if ((ret = smsc9500_read_reg(dev,HW_CFG,&dwReadBuf)< 0)) { ++ SMSC_WARNING("Failed to read HW_CFG: %d", ret); ++ return ret; ++ } ++ dwReadBuf |= HW_CFG_LRST_; ++ if ((ret = smsc9500_write_reg(dev, HW_CFG, dwReadBuf)) < 0) { ++ SMSC_WARNING("Failed to write HW_CFG_LRST_ bit in HW_CFG register, ret = %d",ret); ++ return ret; ++ } ++ ++ Timeout = 0; ++ do { ++ if ((ret = smsc9500_read_reg(dev, HW_CFG, &dwReadBuf)< 0)) { ++ SMSC_WARNING("Failed to read HW_CFG: %d", ret); ++ return ret; ++ } ++ /* wait for 100 */ ++ msleep(100); ++ Timeout++; ++ } while ((dwReadBuf & HW_CFG_LRST_) && (Timeout < 100)); ++ ++ if(Timeout >= 100) { ++ SMSC_WARNING("Timeout waiting for completion of Lite Reset"); ++ return SMSC9500_FAIL; ++ } ++ ++ if((ret = smsc9500_read_reg(dev, ID_REV, &dev->chipID)) < 0) { ++ SMSC_WARNING("Failed to read GPIO_CFG: %d", ret); ++ return ret; ++ } ++ dev->chipID = dev->chipID >> 16; ++ ++ /* Enable chip specific features */ ++ if (dev->chipID == PID_LAN9512) { ++ dev->chipDependFeatures[FEATURE_WUFF_8] = TRUE; ++ } else if (dev->chipID == PID_LAN9500A) { ++ int i; ++ for(i = 0; i < FEATURE_MAX_NO; i++) ++ dev->chipDependFeatures[i] = TRUE; ++ dev->chipDependFeatures[FEATURE_EEE] = FALSE; ++ } else if ((dev->chipID == PID_LAN9530) || (dev->chipID == PID_LAN9730) || (dev->chipID == PID_LAN89530)) { ++ int i; ++ for(i = 0; i < FEATURE_MAX_NO; i++) ++ dev->chipDependFeatures[i] = TRUE; ++ } ++ ++ if ((ret = smsc9500_read_reg(dev, PM_CTRL, &DwTemp) < 0)) { ++ SMSC_WARNING("Failed to read PM_CTRL: %d", ret); ++ return ret; ++ } ++ ++ if ((ret = smsc9500_write_reg(dev, PM_CTRL, (DwTemp | PM_CTL_PHY_RST_)) < 0)) { ++ SMSC_WARNING("Failed to write PM_CTRL: %d", ret); ++ return ret; ++ } ++ ++ Timeout = 0; ++ do { ++ if ((ret = smsc9500_read_reg(dev, PM_CTRL, &dwReadBuf) < 0)) { ++ SMSC_WARNING("Failed to read PM_CTRL: %d", ret); ++ return ret; ++ } ++ msleep(100); ++ Timeout++; ++ } while ((dwReadBuf & PM_CTL_PHY_RST_) && (Timeout < 100)); ++ ++ if (Timeout >= 100) { ++ SMSC_WARNING("Timeout waiting for PHY Reset"); ++ return SMSC9500_FAIL; ++ } ++ dwAddrH = 0x0000FFFFUL; ++ dwAddrL = 0xFFFFFFFF; ++ ++ ++ if (adapterData->macAddrHi16 != 0xFFFFFFFF || adapterData->MmacAddrLo32 != 0xFFFFFFFF) { ++ dwAddrH = adapterData->macAddrHi16 & 0xFFFF; ++ dwAddrL = adapterData->MmacAddrLo32; ++ } else { ++ //add by lm ++ if (dev->chipID == PID_LAN9512) ++ adapterData->eepromContentValid=TRUE; ++ //end ++ ++ if ((adapterData->eepromContentValid == TRUE) && ++ (smsc9500_read_eeprom(dev, EEPROM_MAC_OFFSET, 6, dev->net->dev_addr) == 0)) { ++ ++ if (smsc9500_is_valid_ether_addr(dev->net->dev_addr)) { ++ dwAddrL = dev->net->dev_addr[0] | dev->net->dev_addr[1] << 8 | ++ dev->net->dev_addr[2] << 16 | dev->net->dev_addr[3] << 24; ++ dwAddrH = dev->net->dev_addr[4] | dev->net->dev_addr[5] << 8; ++ } ++ } else { ++ /* LAN9500's descriptor RAM may provide Mac address */ ++ MAC_ADDR_IN_RAM macRam; ++ if (ReadDataPort(dev, RAMSEL_EEPROM, 0, sizeof(MAC_ADDR_IN_RAM) / 4, ++ (u32*)&macRam, NULL) == SMSC9500_SUCCESS) { ++ cpu_to_le32s(&macRam.signature); ++ cpu_to_le32s(&macRam.MacAddrL); ++ cpu_to_le32s(&macRam.MacAddrH); ++ cpu_to_le16s(&macRam.crc); ++ cpu_to_le16s(&macRam.crcComplement); ++ if(macRam.signature == 0x736D7363){ /* Signature "smsc" */ ++ u16 crc = CalculateCrc16((BYTE *)&macRam, 12, FALSE); ++ if((crc == macRam.crc) && (crc == (u16)~macRam.crcComplement)) { ++ dwAddrL = macRam.MacAddrL; ++ dwAddrH = macRam.MacAddrH; ++ } ++ } ++ } ++ } ++ } ++ ++ /* Mac address could be initialized by system firmware. Lan9500A ++ will implement this way */ ++ if ((dwAddrH==0x0000FFFFUL)&&(dwAddrL==0xFFFFFFFF)) { ++ if ((ret = smsc9500_read_reg(dev,ADDRL, &dwAddrL) < 0)) { ++ SMSC_WARNING("Failed to read ADDRL: %d", ret); ++ return ret; ++ } ++ if ((ret = smsc9500_read_reg(dev,ADDRH, &dwAddrH) < 0)) { ++ SMSC_WARNING("Failed to read ADDRH: %d", ret); ++ return ret; ++ } ++ } ++ ++ if ((((dwAddrH & 0xFFFF) == 0x0000FFFFUL) && (dwAddrL == 0xFFFFFFFF)) || ++ (((dwAddrH & 0xFFFF) == 0x0UL) && (dwAddrL == 0x0UL)) || ++ (0x01 & LOBYTE(LOWORD(dwAddrL)))) { ++ dwAddrH=0x00000070UL; ++ dwAddrL=0x110F8000UL; ++ SMSC_TRACE(DBG_INIT, "Mac Address is set by default to 0x%04X%08X", dwAddrH, dwAddrL); ++ } ++ adapterData->macAddrHi16 = dwAddrH; ++ adapterData->MmacAddrLo32 = dwAddrL; ++ ++ if ((ret = smsc9500_write_reg(dev, ADDRL, dwAddrL) < 0)) { ++ SMSC_WARNING("Failed to write ADDRL: %d", ret); ++ return ret; ++ } ++ if ((ret = smsc9500_write_reg(dev, ADDRH, dwAddrH) < 0)) { ++ SMSC_WARNING("Failed to write ADDRH: %d", ret); ++ return ret; ++ } ++ ++ dev->net->dev_addr[0] = LOBYTE(LOWORD(dwAddrL)); ++ dev->net->dev_addr[1] = HIBYTE(LOWORD(dwAddrL)); ++ dev->net->dev_addr[2] = LOBYTE(HIWORD(dwAddrL)); ++ dev->net->dev_addr[3] = HIBYTE(HIWORD(dwAddrL)); ++ dev->net->dev_addr[4] = LOBYTE(LOWORD(dwAddrH)); ++ dev->net->dev_addr[5] = HIBYTE(LOWORD(dwAddrH)); ++ ++ SMSC_TRACE(DBG_INIT, "dev->net->dev_addr %02x:%02x:%02x:%02x:%02x:%02x", ++ dev->net->dev_addr [0], dev->net->dev_addr [1], ++ dev->net->dev_addr [2], dev->net->dev_addr [3], ++ dev->net->dev_addr [4], dev->net->dev_addr [5]); ++ ++#ifdef PME_EEPROMLESS ++ if ((ret=EepromLessPMESetting(dev))<0) ++ return ret; ++#endif ++ if (!(smscusbnet_IsOperationalMode(dev))) { ++ if ((ret = smsc9500_read_reg(dev, HW_CFG, &dwReadBuf) < 0)) { ++ SMSC_WARNING("Failed to read HW_CFG: %d", ret); ++ return ret; ++ } ++ ++ dwReadBuf |= HW_CFG_BIR_; ++ if ((ret = smsc9500_write_reg(dev, HW_CFG, dwReadBuf)) < 0) { ++ SMSC_WARNING("Failed to write HW_CFG_BIR_ bit in HW_CFG register, ret = %d ",ret); ++ return ret; ++ } ++ ++ if ((ret = smsc9500_read_reg(dev, HW_CFG, &dwReadBuf) < 0)) { ++ SMSC_WARNING("Failed to read HW_CFG: %d", ret); ++ return ret; ++ } ++ } ++ ++ if (dev->turbo_mode) { ++ if(dev->udev->speed == USB_SPEED_HIGH) ++ dwBurstCap = dev->rx_urb_size / HS_USB_PKT_SIZE; ++ else ++ dwBurstCap = dev->rx_urb_size / FS_USB_PKT_SIZE; ++ } else { ++ dwBurstCap = 0; ++ } ++ ++ if ((ret = smsc9500_write_reg(dev, BURST_CAP, dwBurstCap)) < 0) { ++ SMSC_WARNING("Failed to write BURST_CAP"); ++ return ret; ++ } ++ if ((ret = smsc9500_read_reg(dev, BURST_CAP, &dwReadBuf) < 0)) { ++ SMSC_WARNING("Failed to read BURST_CAP: %d", ret); ++ return ret; ++ } ++ SMSC_TRACE(DBG_INIT, "BURST_CAP after writing: 0x%08x", dwReadBuf); ++ ++ if ((ret = smsc9500_write_reg(dev, BULK_IN_DLY, bulkin_delay)) < 0) { ++ SMSC_WARNING("Failed to write BULK_IN_DLY"); ++ return ret; ++ } ++ if ((ret = smsc9500_read_reg(dev, BULK_IN_DLY, &dwReadBuf)< 0)) { ++ SMSC_WARNING("Failed to read BULK_IN_DLY: %d", ret); ++ return ret; ++ } ++ SMSC_TRACE(DBG_INIT, "BULK_IN_DLY: 0x%08x", dwReadBuf); ++ ++ if ((ret = smsc9500_read_reg(dev, HW_CFG, &dwReadBuf) < 0)) { ++ SMSC_WARNING("Failed to read HW_CFG: %d", ret); ++ return ret; ++ } ++ ++ if (dev->turbo_mode) { ++ dwReadBuf |= (HW_CFG_MEF_|HW_CFG_BCE_); ++ } ++ ++ dwReadBuf &= ~HW_CFG_RXDOFF_; ++ dwReadBuf |= RX_OFFSET << 9; //set Rx data offset=2, Make IP header aligns on word boundary. ++ ++ if ((ret = smsc9500_write_reg(dev, HW_CFG, dwReadBuf)) < 0) { ++ SMSC_WARNING("Failed to write HW_CFG_BIR_ bit in HW_CFG register, ret = %d \n",ret); ++ return ret; ++ } ++ ++ if ((ret = smsc9500_read_reg(dev, HW_CFG, &dwReadBuf) < 0)) { ++ SMSC_WARNING("Failed to read HW_CFG: %d", ret); ++ return ret; ++ } ++ SMSC_TRACE(DBG_INIT, "HW_CFG: 0x%08x", dwReadBuf); ++ ++ if ((ret = smsc9500_write_reg(dev, INT_STS, 0xFFFFFFFFUL))<0) { ++ SMSC_WARNING("Failed to write INT_STS register, ret = %d",ret); ++ return ret; ++ } ++ ++ ++ if ((ret = smsc9500_read_reg(dev, ID_REV, &dwReadBuf) < 0)) { ++ SMSC_WARNING("Failed to read ID_REV: %d", ret); ++ return ret; ++ } ++ adapterData->dwIdRev = dwReadBuf; ++ SMSC_TRACE(DBG_INIT, "ID_REV = 0x%08x", dwReadBuf); ++ ++ ++ if ((ret = smsc9500_read_reg(dev, FPGA_REV, &dwReadBuf) < 0)) { ++ SMSC_WARNING("Failed to read FPGA_REV: %d", ret); ++ return ret; ++ } ++ adapterData->dwFpgaRev = dwReadBuf; ++ ++ if (smscusbnet_IsOperationalMode(dev)) { ++ ++ if ((ret = smsc9500_read_reg(dev, INT_EP_CTL, &dwReadBuf) < 0)) { ++ SMSC_WARNING("Failed to read INT_EP_CTL: %d", ret); ++ return ret; ++ } ++ SMSC_TRACE(DBG_INIT, "INT_EP_CTL: 0x%08x", dwReadBuf); ++ ++ dwReadBuf |= INT_EP_CTL_RX_FIFO_EN_; ++ if ((ret = smsc9500_write_reg(dev, INT_EP_CTL, dwReadBuf)) < 0) { ++ SMSC_WARNING("Failed to write INT_EP_CTL register,ret = %d",ret); ++ return ret; ++ } ++ ++ if ((ret = smsc9500_read_reg(dev, INT_EP_CTL, &dwReadBuf) < 0)) { ++ SMSC_WARNING("Failed to read INT_EP_CTL: %d", ret); ++ return ret; ++ } ++ SMSC_TRACE(DBG_INIT, "INT_EP_CTL: 0x%08x", dwReadBuf); ++ } ++ ++ /* Set TX COE */ ++ if(adapterData->UseTxCsum) { ++ if ((ret = smsc9500_read_reg(dev, COE_CR, &dwReadBuf) < 0)) { ++ SMSC_WARNING("Failed to read COE_CR: %d", ret); ++ return ret; ++ } ++ dwReadBuf |= Tx_COE_EN_; ++ ++ if ((ret = smsc9500_write_reg(dev, COE_CR, dwReadBuf) < 0)) { ++ SMSC_WARNING("Failed to write COE_CR: %d", ret); ++ return ret; ++ } ++ ++ if ((ret = smsc9500_read_reg(dev, COE_CR, &DwTemp) < 0)) { ++ SMSC_WARNING("Failed to read COE_CR: %d", ret); ++ return ret; ++ } ++ SMSC_TRACE(DBG_INIT, "COE_CR = 0x%08x", DwTemp); ++ } ++ ++ if ((ret = smsc9500_write_reg(dev, FLOW, 0x0UL) < 0)) { ++ SMSC_WARNING("Failed to write FLOW: %d", ret); ++ return ret; ++ } ++ ++ if ((ret = smsc9500_write_reg(dev, AFC_CFG, AFC_CFG_DEFAULT) < 0)) { ++ SMSC_WARNING("Failed to write AFC_CFG: %d", ret); ++ return ret; ++ } ++ ++ if ((ret = smsc9500_read_reg(dev, MAC_CR, &dwMacCr) < 0)) { ++ SMSC_WARNING("Failed to read MAC_CR: %d", ret); ++ return ret; ++ } ++ dwMacCr |= (MAC_CR_TXEN_); ++ if ((ret = smsc9500_write_reg(dev, MAC_CR, dwMacCr) < 0)) { ++ SMSC_WARNING("Failed to read MAC_CR: %d", ret); ++ return ret; ++ } ++ dwWriteBuf = TX_CFG_ON_; ++ if ((ret = smsc9500_write_reg(dev, TX_CFG, dwWriteBuf) < 0)) { ++ SMSC_WARNING("Failed to write TX_CFG: %d", ret); ++ return ret; ++ } ++ ++ /* Set Vlan */ ++ dwWriteBuf = (u32)ETH_P_8021Q; ++ if ((ret = smsc9500_write_reg(dev, VLAN1, dwWriteBuf) < 0)) { ++ SMSC_WARNING("Failed to write VAN1: %d", ret); ++ return ret; ++ } ++ ++ /* Set Rx COE */ ++ if (adapterData->UseRxCsum) { ++ if ((ret = smsc9500_read_reg(dev, COE_CR, &dwReadBuf) < 0)) { ++ SMSC_WARNING("Failed to read COE_CR: %d", ret); ++ return ret; ++ } ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)) ++ dwReadBuf |= (Rx_COE_EN_ | Rx_COE_MODE_); ++#else ++ dwReadBuf |= Rx_COE_EN_; ++#endif ++ if ((ret = smsc9500_write_reg(dev, COE_CR, dwReadBuf) < 0)) { ++ SMSC_WARNING("Failed to write COE_CR: %d", ret); ++ return ret; ++ } ++ ++ if ((ret = smsc9500_read_reg(dev, COE_CR, &DwTemp) < 0)) { ++ SMSC_WARNING("Failed to read COE_CR: %d", ret); ++ return ret; ++ } ++ SMSC_TRACE(DBG_INIT, "COE_CR = 0x%08x", DwTemp); ++ ++ } ++ ++ if ((ret = smsc9500_read_reg(dev, MAC_CR, &dwMacCr) < 0)) { ++ SMSC_WARNING("Failed to read MAC_CR: %d", ret); ++ return ret; ++ } ++ ++ dwMacCr |= MAC_CR_RXEN_; ++ ++ if ((ret = smsc9500_write_reg(dev, MAC_CR, dwMacCr) < 0)) { ++ SMSC_WARNING("Failed to read MAC_CR: %d", ret); ++ return ret; ++ } ++ ++ /* Enable the LEDs by default */ ++ if ((ret = smsc9500_read_reg(dev, LED_GPIO_CFG, &DwTemp) < 0)) { ++ SMSC_WARNING("Failed to read LED_GPIO_CFG: %d", ret); ++ return ret; ++ } ++ DwTemp &= (~LED_GPIO_CFG_GPCTL_10_ | ~LED_GPIO_CFG_GPCTL_09_ | ~LED_GPIO_CFG_GPCTL_08_); ++ ++ if ((ret = smsc9500_write_reg( dev, LED_GPIO_CFG, ++ (LED_GPIO_CFG_GPCTL_LED_ << LED_GPIO_CFG_GPCTL_10_SH) | ++ (LED_GPIO_CFG_GPCTL_LED_ << LED_GPIO_CFG_GPCTL_09_SH) | ++ (LED_GPIO_CFG_GPCTL_LED_ << LED_GPIO_CFG_GPCTL_08_SH))) < 0) { ++ SMSC_WARNING("Failed to write LED_GPIO_CFG: %d", ret); ++ return ret; ++ } ++ ++ //adapterData->LinkActLedCfg=TRUE; ++ if (adapterData->LinkActLedCfg) { ++ /* Driver parameter enables separate Link and Activity ++ LEDs for supported devices */ ++ if (1/*dev->chipDependFeatures[FEATURE_SEP_LEDS]*/) { ++ dwLedGpioCfg = (LED_GPIO_CFG_GPCTL_LED_ << LED_GPIO_CFG_GPCTL_10_SH) | ++ (LED_GPIO_CFG_GPCTL_LED_ << LED_GPIO_CFG_GPCTL_09_SH) | ++ (LED_GPIO_CFG_GPCTL_LED_ << LED_GPIO_CFG_GPCTL_08_SH); ++ ++ /* Enable separate Link/Act LEDs */ ++ dwLedGpioCfg |= LED_GPIO_CFG_LED_SEL_; ++ ++ /* Set LED GPIO Config */ ++ if((ret = smsc9500_write_reg(dev, LED_GPIO_CFG, dwLedGpioCfg)) < 0) { ++ SMSC_WARNING("Failed to write LED_GPIO_CFG: %d", ret); ++ return ret; ++ } ++ } else { ++ /* Reset to default value */ ++ adapterData->LinkActLedCfg = 0; ++ /* Disable Software control LinkLed GPIO in case it is set */ ++ adapterData->LinkLedOnGpio = 11; ++ } ++ } else if (adapterData->LinkLedOnGpio <= 10) { ++ /* Software control LinkLed GPIO is enable. ++ If selected GPIO is GPIO0-GPIO7, make sure external PHY is not enable. ++ GPIO0-GPIO7 pins are multiplexed with MII signals */ ++ if (adapterData->LinkLedOnGpio < 8) { ++ /* Check PHY Strap */ ++ if((ret = smsc9500_read_reg(dev, HW_CFG, &DwTemp)) < 0){ ++ SMSC_WARNING("Failed to read HW_CFG: %d", ret); ++ return ret; ++ } ++ if (DwTemp & HW_CFG_PSEL_) { ++ /* External PHY is enable */ ++ SMSC_WARNING("External PHY Enable::GPIO%d can not be set as Link Up/Down Led\n", adapterData->LinkLedOnGpio); ++ /* Disable Software control LinkLed GPIO */ ++ adapterData->LinkLedOnGpio = 11; ++ } else { ++ u32 dwGpioCfg; ++ if((ret = smsc9500_read_reg(dev, GPIO_CFG, &dwGpioCfg)) < 0){ ++ SMSC_WARNING("Failed to read GPIO_CFG: %d", ret); ++ return ret; ++ } ++ ++ dwGpioCfg &= ~(GPIO_CFG_GPO0_EN_ << adapterData->LinkLedOnGpio); ++ dwGpioCfg |= GPIO_CFG_GPO0_DIR_ << adapterData->LinkLedOnGpio; ++ ++ /* Check GPIO buffer type */ ++ if (!adapterData->LinkLedOnGpioBufType) {// Push-Pull output ++ dwGpioCfg |= GPIO_CFG_GPO0_TYPE_ << adapterData->LinkLedOnGpio; ++ } ++ ++ /* Check GPIO Polarity */ ++ if (adapterData->LinkLedOnGpioPolarity) { // Active low ++ dwGpioCfg |= GPIO_CFG_GPO0_DATA_ << adapterData->LinkLedOnGpio; ++ } ++ ++ /* Set GPIO Config register */ ++ if((ret = smsc9500_write_reg(dev, GPIO_CFG, dwGpioCfg)) < 0) { ++ SMSC_WARNING("Failed to write GPIO_CFG: %d", ret); ++ return ret; ++ } ++ } ++ } else { ++ u32 dwLedGpioCfg = (LED_GPIO_CFG_GPCTL_LED_ << LED_GPIO_CFG_GPCTL_10_SH) | ++ (LED_GPIO_CFG_GPCTL_LED_ << LED_GPIO_CFG_GPCTL_09_SH) | ++ (LED_GPIO_CFG_GPCTL_LED_ << LED_GPIO_CFG_GPCTL_08_SH); ++ switch (adapterData->LinkLedOnGpio) { ++ case 8: ++ /* Enable GPIO 8 */ ++ dwLedGpioCfg &= (~(LED_GPIO_CFG_GPCTL_LED_ << LED_GPIO_CFG_GPCTL_08_SH)); ++ /* Set Output Direction */ ++ dwLedGpioCfg |= LED_GPIO_CFG_GPDIR_08_; ++ /* Set Buffer Type */ ++ if (!adapterData->LinkLedOnGpioBufType) {// Push-Pull Output ++ dwLedGpioCfg |= LED_GPIO_CFG_GPBUF_08_; ++ } ++ /* Check GPIO Polarity */ ++ if (adapterData->LinkLedOnGpioPolarity) { // Active low ++ dwLedGpioCfg |= LED_GPIO_CFG_GPDATA_08_; ++ } ++ break; ++ case 9: ++ /* Enable GPIO 9 */ ++ dwLedGpioCfg &= (~(LED_GPIO_CFG_GPCTL_LED_ << LED_GPIO_CFG_GPCTL_09_SH)); ++ /* Set Output Direction */ ++ dwLedGpioCfg |= LED_GPIO_CFG_GPDIR_09_; ++ /* Set Buffer Type */ ++ if (!adapterData->LinkLedOnGpioBufType) { // Push-Pull Output ++ dwLedGpioCfg |= LED_GPIO_CFG_GPBUF_09_; ++ } ++ /* Check GPIO Polarity */ ++ if (adapterData->LinkLedOnGpioPolarity) { // Active low ++ dwLedGpioCfg |= LED_GPIO_CFG_GPDATA_09_; ++ } ++ break; ++ case 10: ++ /* Enable GPIO 10 */ ++ dwLedGpioCfg &= (~(LED_GPIO_CFG_GPCTL_LED_ << LED_GPIO_CFG_GPCTL_10_SH)); ++ /* Set Output Direction */ ++ dwLedGpioCfg |= LED_GPIO_CFG_GPDIR_10_; ++ /* Set Buffer Type */ ++ if (!adapterData->LinkLedOnGpioBufType) {// Push-Pull Output ++ dwLedGpioCfg |= LED_GPIO_CFG_GPBUF_10_; ++ } ++ /* Check GPIO Polarity */ ++ if (adapterData->LinkLedOnGpioPolarity) {// Active low ++ dwLedGpioCfg |= LED_GPIO_CFG_GPDATA_10_; ++ } ++ break; ++ } ++ /* Set LED GPIO Config */ ++ if((ret = smsc9500_write_reg( dev, LED_GPIO_CFG, dwLedGpioCfg)) < 0) { ++ SMSC_WARNING("Failed to write LED_GPIO_CFG: %d", ret); ++ return ret; ++ } ++ } ++ } ++ smsc9500_rx_setmulticastlist(dev); ++ ++ adapterData->dwSavedLinkSettings = link_mode; ++ if (!Phy_Initialize(dev, phy_addr, link_mode)) ++ return SMSC9500_FAIL; ++ ++ return 0; ++} ++ ++static int smsc9500_link_reset(struct usbnet *dev) ++{ ++ int ret = 0; ++ ++ SMSC_TRACE(DBG_LINK, "smsc9500_link_reset"); ++ ++ ret = Phy_CheckLink(dev); ++ ++ if (dev->StopLinkPolling) { ++ clear_bit (EVENT_DEV_RECOVERY, &dev->flags); ++ } ++ ++ if (test_bit (EVENT_DEV_RECOVERY, &dev->flags)) { ++ ret = smsc9500_device_recovery(dev); ++ clear_bit (EVENT_DEV_RECOVERY, &dev->flags); ++ } ++ return ret; ++} ++ ++ ++static int smsc9500_stopTxPath(struct usbnet * dev) ++{ ++ u32 Value32; ++ int ret = SMSC9500_FAIL; ++ int Count = 0; ++ ++ SMSC_TRACE(DBG_TX, "smsc9500_stopTxPath"); ++ ++ /* Stop the Transmit path at SCSRs */ ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, TX_CFG, TX_CFG_STOP_)); ++ /* The bit should self clear as soon as the packet makes it out ++ of the Mac, worst case is 10 Mbps HD and frame deferred to the ++ maximum. This will be ~100ms tops. Assuming one register read per ++ (micro)frame the case of high speed USB - 125us register read ++ cycle time - is the worse and ++ would need up to 800 reads. Let's just round up to 1000 */ ++ do ++ { ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, TX_CFG, &Value32)); ++ /* Let it try to do the 1000 reads even if the reg reads ++ are failing If the previous write did go thru at least ++ this way we have a better chance of making sure the ++ transmit path did stop. */ ++ } while ( (++Count<1000) && ((Value32 & (TX_CFG_STOP_ | TX_CFG_ON_)) != 0) ); ++ ++ /* Disable Mac TX */ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, MAC_CR, &Value32)); ++ Value32 &= ~MAC_CR_TXEN_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, MAC_CR, Value32 )); ++ ++ ret = SMSC9500_SUCCESS; ++DONE: ++ return ret; ++} ++ ++static int smsc9500_stopAndFlushTxPath(struct usbnet *dev) ++{ ++ u32 Value32; ++ int ret = SMSC9500_FAIL; ++ ++ SMSC_TRACE(DBG_TX, "smsc9500_stopAndFlushTxPath"); ++ if(smsc9500_stopTxPath(dev) < 0)return ret; ++ ++ /* Flush the transmit path */ ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, TX_CFG, TX_CFG_FIFO_FLUSH_)); ++ ++ /* Should self clear way before the read. */ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, TX_CFG, &Value32)); ++ ++ if (Value32 & TX_CFG_FIFO_FLUSH_) { ++ /* Flush did not self clear! */ ++ goto DONE; ++ } ++ ret = SMSC9500_SUCCESS; ++DONE: ++ return ret; ++} ++ ++ ++static int smsc9500_stopRxPath(struct usbnet * dev) ++{ ++ u32 Value32; ++ int Count = 0; ++ int ret = SMSC9500_FAIL; ++ ++ SMSC_TRACE(DBG_RX, "smsc9500_stopRxPath"); ++ ++ /* Clr the Rx Stop bit if not already */ ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, INT_STS, INT_STS_RX_STOP_)); ++ ++ /* Disable the receiver at the Mac */ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, MAC_CR, &Value32)); ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, MAC_CR, Value32 & (~MAC_CR_RXEN_))); ++ ++ /* The Rx Stop bit should assert as soon as the packet "in ++ flight" makes it into the Mac, worst case is 10 Mbps HD. This ++ will be ~2ms tops Assuming one register read per (micro)frame ++ the case of high speed USB - 125us register read cycle time - ++ is the worse and would need up to ++ 16 reads. Let's just round up to 20. */ ++ do { ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, INT_STS, &Value32)); ++ /* Let it try to do the 20 reads even if the reg reads ++ are failing If the previous write did go thru at least ++ this way we have a better chance of making sure the ++ receiver did stop */ ++ } while ( (++Count<20) && ((Value32 & INT_STS_RX_STOP_) == 0) ); ++ ++ /* Disable Mac RX */ ++ //CHECK_RETURN_STATUS(smsc9500_read_reg(dev, MAC_CR, &Value32)); ++ //Value32 &= ~MAC_CR_RXEN_; ++ //CHECK_RETURN_STATUS(smsc9500_write_reg(dev, MAC_CR, Value32)); ++ ++ ret = SMSC9500_SUCCESS; ++DONE: ++ return ret; ++} ++ ++static int smsc9500_stopAndFlushRxPath(struct usbnet *dev) ++{ ++ u32 Value32; ++ int ret = SMSC9500_FAIL; ++ ++ SMSC_TRACE(DBG_RX, "smsc9500_stopAndFlushRxPath"); ++ ++ if (smsc9500_stopRxPath(dev) < 0) ++ goto DONE; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, RX_CFG, RX_FIFO_FLUSH_)); ++ ++ /* Should self clear way before the read */ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, RX_CFG, &Value32)); ++ ++ if (Value32 & RX_FIFO_FLUSH_) { ++ /* Flush did not self clear! */ ++ goto DONE; ++ } ++ ret = SMSC9500_SUCCESS; ++DONE: ++ return ret; ++} ++ ++ ++#ifdef PME_EEPROMLESS ++static int EepromLessPMESetting(struct usbnet *dev) ++{ ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ u32 dwReadBuf, dwAddrH, dwAddrL, dwWrite,dwRead; ++ int ret; ++ ++ //API for customer to provide MAC address ++/* ++ GetMacAddr(&dev->net->dev_addr); ++ ++ dwAddrL = dev->net->dev_addr[0] | dev->net->dev_addr[1] << 8 | dev->net->dev_addr[2] << 16 | dev->net->dev_addr[3] << 24; ++ dwAddrH = dev->net->dev_addr[4] | dev->net->dev_addr[5] << 8; ++ ++ if ((ret = smsc9500_write_reg(dev,ADDRL, dwAddrL)< 0)) { ++ SMSC_WARNING("Failed to write ADDRL: %d", ret); ++ return ret; ++ } ++ if ((ret = smsc9500_write_reg(dev,ADDRH, dwAddrH)< 0)) { ++ SMSC_WARNING("Failed to write ADDRH: %d", ret); ++ return ret; ++ } ++*/ ++ if ((ret = smsc9500_read_reg(dev,FLAG_ATTR, &dwRead)< 0)) { ++ SMSC_WARNING("Failed to read FLAG_ATTR: %d", ret); ++ return ret; ++ } ++ ++ //define your PME configuration here by setting theses values: ++ //FLAG_ATTR_PME_ENABLE The device supports GPIO PME signaling. ++ //FLAG_ATTR_PME_CFG_PULSE GPIO PME is signaled via a pulse,otherwise it's signal via a level ++ // FLAG_ATTR_PME_LEN_150MS GPIO PME pulse length is 150 mS, otherwisw it's 1.5mS ++ //FLAG_ATTR_PME_POL GPIO PME signaling polarity is high ++ //FLAG_ATTR_PME_BUFF_TYPE Push-Pull driver, otherwise Open drain driver ++ //FLAG_ATTR_PME_WAKE_PHY PHY linkup wakeup supported, otherwise Magic packet wakeup supported ++ //FLAG_ATTR_PME_GPIO10_HIGH Active-high detection for GPIO10 ++ dwRead |= FLAG_ATTR_PME_ENABLE | FLAG_ATTR_PME_POL; ++ ++ if ((ret = smsc9500_write_reg(dev,FLAG_ATTR, dwRead)< 0)) { ++ SMSC_WARNING("Failed to write FLAG_ATTR: %d", ret); ++ return ret; ++ } ++ if ((ret = smsc9500_read_reg(dev,HW_CFG, &dwRead)< 0)) { ++ SMSC_WARNING("Failed to read HW_CFG: %d", ret); ++ return ret; ++ } ++ ++ dwRead |= HW_CFG_EEM|HW_CFG_RST_PROTECT; ++ if ((ret = smsc9500_write_reg(dev,HW_CFG, dwRead)< 0)) { ++ SMSC_WARNING("Failed to write HW_CFG: %d", ret); ++ return ret; ++ } ++ return ret; ++ } ++#endif /* PME_EEPROMLESS */ ++ ++ ++static u16 CalculateCrc16(const BYTE * bpData,const u32 dwLen, const BOOLEAN fBitReverse) ++{ ++ const u16 wCrc16Poly = 0x8005U; // s/b international standard for CRC-16 ++ // x^16 + x^15 + x^2 + 1 ++ //u16 wCrc16Poly = 0xA001; // reverse ++ u16 wMsb; ++ u16 i, j, bit; ++ u16 wCrcOut=0; ++ u16 wCrc = 0xFFFFU; ++ BYTE bCurrentByte; ++ u16 wNumOfBits = 16U; ++ ++ wNumOfBits = wNumOfBits; // to avoid lint warning ++ ++ for (i = 0; i < (u16)dwLen; i++) { ++ bCurrentByte = *bpData++; ++ ++ for (bit = (u16)0U; bit < (u16)8U; bit++) { ++ wMsb = wCrc >> 15; ++ wCrc <<= 1; ++ ++ if (wMsb ^ (u16)(bCurrentByte & 1)) { ++ wCrc ^= wCrc16Poly; ++ wCrc |= (u16)0x0001U; ++ } ++ bCurrentByte >>= 1; ++ } ++ } ++ /* bit reverse if needed ++ so far we do not need this for 117 ++ but the standard CRC-16 seems to require this */ ++ if (fBitReverse) { ++ j = 1; ++ for (i=(u16)(1<<(wNumOfBits-(u16)1U)); i; i = i>>1) { ++ if (wCrc & i) { ++ wCrcOut |= j; ++ } ++ j <<= 1; ++ } ++ wCrc = wCrcOut; ++ } ++ return wCrc; ++} ++ ++/* ++ ++Routine Description: ++ ++ This routine set/reset General Purpose Output. ++ ++Arguments: ++ ++ Adapter - pointer to our Adapter ++ Gpo - Gpo [0:10] ++ State - 1 = ON or 0 = OFF ++ ++Return Value: ++*/ ++ ++static int SetGpo(struct usbnet * dev, u32 Gpo, u32 State) ++{ ++ u32 Value32, Status; ++ int ret = SMSC9500_FAIL; ++ ++ if ((Gpo > 10) || (State > 1)) { ++ if (State > 1) { ++ SMSC_WARNING("Gpo%d state (%d) is out of range [0:1] in NICSetGpo\n", Gpo, State); ++ } ++ goto Exit_NICSetGpo; ++ } ++ ++ if (Gpo < 8) { ++ if (smsc9500_read_reg( dev, GPIO_CFG, &Value32 ) < 0) { ++ SMSC_WARNING("Failed to read GPIO_CFG\n"); ++ goto Exit_NICSetGpo; ++ } ++ Value32 &= (~(GPIO_CFG_GPO0_DATA_ << Gpo)); ++ Value32 |= (State << Gpo); ++ ++ Status = smsc9500_write_reg(dev, GPIO_CFG, Value32); ++ if (Status < 0) ++ goto Exit_NICSetGpo; ++ } else { ++ Status = smsc9500_read_reg(dev, LED_GPIO_CFG, &Value32 ); ++ if (Status < 0) ++ goto Exit_NICSetGpo; ++ ++ Value32 &= (~(LED_GPIO_CFG_GPDATA_08_ << (Gpo-8))); ++ Value32 |= (State << (Gpo-8)); ++ ++ Status = smsc9500_write_reg(dev, LED_GPIO_CFG, Value32 ); ++ if (Status < 0) ++ goto Exit_NICSetGpo; ++ } ++ ++ ret = SMSC9500_SUCCESS; ++Exit_NICSetGpo: ++ return ret; ++} ++ ++/* ++Routine Description: ++ ++ This routine set device at suspend3 state ++ ++Arguments: ++ ++ netdev - pointer to our device ++ ++Return Value: ++ ++*/ ++static int SetWakeupOnSuspend3(struct net_device *netdev) ++{ ++ u32 Value32; ++ int ret = SMSC9500_FAIL; ++ struct usbnet *dev = netdev_priv(netdev); ++ ++ BUG_ON(!dev); ++ ++ SMSC_TRACE(DBG_PWR, "Setting Suspend3 mode"); ++ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, RX_FIFO_INF, &Value32)); ++ ++ if ((Value32 & 0xFFFF) != 0) { ++ SMSC_TRACE(DBG_PWR, "Rx FIFO is not empty"); ++ Value32 = RX_FIFO_FLUSH_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, RX_CFG, Value32)); ++ } else { ++ SMSC_TRACE(DBG_PWR, "Rx FIFO is empty, continue suspend"); ++ } ++ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, PM_CTRL, &Value32)); ++ Value32 &= (~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_)); ++ Value32 |= PM_CTL_SUS_MODE_3 | PM_CTL_RES_CLR_WKP_STS; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, PM_CTRL, Value32)); ++ Value32 &= ~PM_CTL_WUPS_; ++ Value32 |= PM_CTL_WUPS_WOL_; //Clear wol status ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, PM_CTRL, Value32)); ++ ++ CHECK_RETURN_STATUS(smsc9500_set_feature(dev,USB_DEVICE_REMOTE_WAKEUP)); ++ ++ ret = SMSC9500_SUCCESS; ++DONE: ++ return ret; ++} ++ ++static int SetWakeupEvents(struct net_device *netdev) ++{ ++ u16 wValue; ++ WAKEUP_FILTER sFilter; ++ u32 dwValue, dwTemp, Value32; ++ int i = 0, ret = SMSC9500_FAIL; ++ int filterMaskCnt = 0, filterCmdCnt = 0, filterOffsetCnt = 0, filterCrcCnt = 0; ++ struct usbnet *dev = netdev_priv(netdev); ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ u32 opts = adapterData->WolWakeupOpts; ++ BYTE bBcast[BCAST_LEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; ++ BYTE bMcast[MCAST_LEN] = {0x01, 0x00, 0x5E}; ++ BYTE bArp[ARP_LEN] = {0x08, 0x06}; ++ ++ BUG_ON(!netdev); ++ ++ SMSC_TRACE(DBG_PWR, "SetWakeupEvents"); ++ ++ if(opts & (WAKE_PHY | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST | WAKE_ARP | WAKE_MAGIC)) { ++ if ((!(MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS)) && (opts & WAKE_PHY)) { ++ /* Clear any pending Phy interrupt and enable the mask for it */ ++ adapterData->systemSuspendPHYEvent = PHY_INT_MASK_LINK_DOWN_; ++ if (adapterData->dwLinkSettings&LINK_AUTO_NEGOTIATE) ++ adapterData->systemSuspendPHYEvent |= PHY_INT_MASK_ANEG_COMP_; ++ ++ EnablePHYWakeupInterrupt(dev, adapterData->systemSuspendPHYEvent); ++ ++ /* If there's currently no link we can use Suspend1 */ ++ /* read PHY_BSR twice: link status bit is LL */ ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_BSR, &Value32)); ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_BSR, &Value32)); ++ wValue = (u16)Value32; ++ if (!(wValue & PHY_BSR_LINK_STATUS_)) { ++ SMSC_TRACE(DBG_PWR, "Setting PHY in PD/ED Mode"); ++ ++ /* If we are in force mode, set the NWAY */ ++ if ((adapterData->dwSavedLinkSettings&LINK_AUTO_NEGOTIATE) == 0) { ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_BCR, &Value32)); ++ Value32 |= PHY_BCR_AUTO_NEG_ENABLE_; ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_BCR, Value32)); ++ } ++ ++ /* Enable the energy detect power-down mode */ ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_MODE_CTRL_STS, &dwValue)); ++ wValue = (u16)dwValue; ++ wValue |= MODE_CTRL_STS_EDPWRDOWN_; ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_MODE_CTRL_STS, wValue)); ++ ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_INT_SRC, &dwTemp)); //Read to clear ++ /* Enable ENERGYON interrupt source */ ++ ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_INT_MASK, &dwValue)); ++ wValue = (u16)dwValue; ++ wValue |= PHY_INT_MASK_ENERGY_ON_; ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_INT_MASK, wValue)); ++ ++ /* Put Lan9500 in Suspend1 */ ++ SMSC_TRACE(DBG_PWR, "Setting Suspend1 mode"); ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, PM_CTRL, &Value32)); ++ Value32 &= (~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_)); ++ Value32 |= PM_CTL_SUS_MODE_1; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, PM_CTRL, Value32)); ++ Value32 &= ~PM_CTL_WUPS_; ++ /* Clear wol status, enable energy detection */ ++ Value32 |= (PM_CTL_WUPS_ED_ | PM_CTL_ED_EN_); ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, PM_CTRL, Value32)); ++ ++ CHECK_RETURN_STATUS(smsc9500_set_feature(dev, USB_DEVICE_REMOTE_WAKEUP)); ++ } else { ++ /* Put Lan9500 in Suspend0 */ ++ SMSC_TRACE(DBG_PWR, "Setting Suspend0 mode"); ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, PM_CTRL, &Value32)); ++ Value32 &= (~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_)); ++ Value32 |= PM_CTL_SUS_MODE_0; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, PM_CTRL, Value32)); ++ Value32 &= ~PM_CTL_WUPS_; ++ /* Clear wol status */ ++ Value32 |= PM_CTL_WUPS_ED_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, PM_CTRL, Value32)); ++ CHECK_RETURN_STATUS(smsc9500_set_feature(dev, USB_DEVICE_REMOTE_WAKEUP)); ++ } ++ } else if (!(MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS)) { ++ /* Clear any pending Phy interrupt and disable ++ the mask for it */ ++ Value32 = PHY_INT_MASK_LINK_DOWN_; ++ if(adapterData->dwLinkSettings&LINK_AUTO_NEGOTIATE) ++ Value32 |= PHY_INT_MASK_ANEG_COMP_; ++ DisablePHYWakeupInterrupt(dev, Value32); ++ } ++ ++ if (opts & (WAKE_BCAST | WAKE_MCAST | WAKE_ARP | WAKE_UCAST| WAKE_MAGIC)) { ++ if (opts & (WAKE_BCAST | WAKE_MCAST | WAKE_ARP | WAKE_UCAST)) { ++ int filter = 0; ++ ++ memset(&sFilter,0,sizeof(sFilter)); ++ ++ if (opts & WAKE_BCAST) { ++ SMSC_TRACE(DBG_PWR, "Set broadicast detection"); ++ sFilter.dwFilterMask[filter * 4] = 0x003F; ++ sFilter.dwFilterMask[filter * 4 + 1] = 0x00; ++ sFilter.dwFilterMask[filter * 4 + 2] = 0x00; ++ sFilter.dwFilterMask[filter * 4 + 3] = 0x00; ++ sFilter.dwCommad[filter/4] |= 0x05UL << ((filter % 4) * 8); //set command ++ sFilter.dwOffset[filter/4] |= 0x00 << ((filter % 4) * 8); ++ sFilter.dwCRC[filter/2] |= CalculateCrc16(bBcast, BCAST_LEN, FALSE) << ((filter % 2) * 16); ++ filter++; ++ } ++ if (opts & WAKE_MCAST) { ++ SMSC_TRACE(DBG_PWR, "Set multicast detection"); ++ sFilter.dwFilterMask[filter * 4] = 0x0007; ++ sFilter.dwFilterMask[filter * 4 + 1] = 0x00; ++ sFilter.dwFilterMask[filter * 4 + 2] = 0x00; ++ sFilter.dwFilterMask[filter * 4 + 3] = 0x00; ++ sFilter.dwCommad[filter/4] |= 0x09UL << ((filter % 4) * 8); //set command ++ sFilter.dwOffset[filter/4] |= 0x00 << ((filter % 4) * 8); ++ sFilter.dwCRC[filter/2] |= (CalculateCrc16(bMcast, MCAST_LEN, FALSE) << ((filter % 2) * 16)); ++ filter++; ++ } ++ if (opts & WAKE_ARP) { ++ SMSC_TRACE(DBG_PWR, "Set ARP detection"); ++ sFilter.dwFilterMask[filter * 4] = 0x0003; //Check two bytes for ARP ++ sFilter.dwFilterMask[filter * 4 + 1] = 0x00; ++ sFilter.dwFilterMask[filter * 4 + 2] = 0x00; ++ sFilter.dwFilterMask[filter * 4 + 3] = 0x00; ++ sFilter.dwCommad[filter/4] |= 0x05UL << ((filter % 4) * 8); //set command ++ sFilter.dwOffset[filter/4] |= 0x0C << ((filter % 4) * 8); ++ sFilter.dwCRC[filter/2]= CalculateCrc16(bArp, ARP_LEN, FALSE) << ((filter % 2) * 16); //This is ARP type ++ filter++; ++ } ++ if (opts & WAKE_UCAST) { ++ SMSC_TRACE(DBG_PWR, "Set UCAST detection"); ++ sFilter.dwFilterMask[filter * 4] = 0x003F; //Check nothing ++ sFilter.dwFilterMask[filter * 4 + 1] = 0x00; ++ sFilter.dwFilterMask[filter * 4 + 2] = 0x00; ++ sFilter.dwFilterMask[filter * 4 + 3] = 0x00; ++ sFilter.dwCommad[filter/4] |= 0x01UL << ((filter % 4) * 8); //set command ++ sFilter.dwOffset[filter/4] |= 0x00 << ((filter % 4) * 8); ++ sFilter.dwCRC[filter/2] |= CalculateCrc16(&netdev->dev_addr[0], 6, FALSE) << ((filter % 2) * 16); ++ filter++; ++ } ++ ++ if (!dev->chipDependFeatures[FEATURE_WUFF_8]) { ++ filterMaskCnt = LAN9500_WUFF_NUM * 4; ++ filterCmdCnt = LAN9500_WUFF_NUM / 4; ++ filterOffsetCnt = LAN9500_WUFF_NUM / 4; ++ filterCrcCnt = LAN9500_WUFF_NUM / 2; ++ } else { ++ filterMaskCnt = LAN9500A_WUFF_NUM * 4; ++ filterCmdCnt = LAN9500A_WUFF_NUM / 4; ++ filterOffsetCnt = LAN9500A_WUFF_NUM / 4; ++ filterCrcCnt = LAN9500A_WUFF_NUM / 2; ++ } ++ ++ for(i = 0; i < filterMaskCnt; i++) { ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, WUFF, sFilter.dwFilterMask[i])); ++ } ++ for(i = 0; i < filterCmdCnt; i++) { ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, WUFF, sFilter.dwCommad[i])); ++ } ++ for(i = 0; i < filterOffsetCnt; i++) { ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, WUFF, sFilter.dwOffset[i])); ++ } ++ for(i = 0; i < filterCrcCnt; i++) { ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, WUFF, sFilter.dwCRC[i])); ++ } ++ ++ /* Clear any pending pattern match packet status */ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, WUCSR, &Value32)); ++ Value32 |= WUCSR_WUFR_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, WUCSR, Value32)); ++ ++ /* Enable pattern match packet wake */ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, WUCSR, &Value32)); ++ Value32 |= WUCSR_WAKE_EN_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, WUCSR, Value32)); ++ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, PM_CTRL, &Value32)); ++ Value32 |= PM_CTL_WOL_EN_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, PM_CTRL, Value32)); ++ ++ } else { ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, WUCSR, &Value32)); ++ Value32 &= (~WUCSR_WAKE_EN_); ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, WUCSR, Value32)); ++ } ++ ++ if (opts & WAKE_MAGIC) { ++ SMSC_TRACE(DBG_PWR, "Setting magic packet detection"); ++ /* Clear any pending magic packet status */ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, WUCSR, &Value32)); ++ Value32 |= WUCSR_MPR_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, WUCSR, Value32)); ++ ++ /* Enable MP wake */ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, WUCSR, &Value32)); ++ Value32 |= WUCSR_MPEN_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, WUCSR, Value32)); ++ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, PM_CTRL, &Value32)); ++ Value32 |= PM_CTL_WOL_EN_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, PM_CTRL, Value32 )); ++ } else { ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, WUCSR, &Value32)); ++ Value32 &= (~WUCSR_MPEN_); ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, WUCSR, Value32)); ++ } ++ ++ /* Enable recevier */ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, MAC_CR, &dwValue)); ++ dwValue |= MAC_CR_RXEN_; ++ if(opts & WAKE_MCAST) { ++ dwValue |= MAC_CR_MCPAS_; ++ } ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev,MAC_CR, dwValue)); ++ ++ SMSC_TRACE(DBG_PWR, "Setting Suspend0 mode"); ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, PM_CTRL, &Value32)); ++ Value32 &= (~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_)); ++ Value32 |= PM_CTL_SUS_MODE_0; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, PM_CTRL, Value32)); ++ Value32 &= ~PM_CTL_WUPS_; ++ /* Clear wol status, should not change suspned_mode while clearing WUPS_sts[1] */ ++ Value32 |= PM_CTL_WUPS_WOL_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, PM_CTRL, Value32)); ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, PM_CTRL, &Value32)); ++ CHECK_RETURN_STATUS(smsc9500_set_feature(dev, USB_DEVICE_REMOTE_WAKEUP)); ++ } ++ } else { ++ SMSC_TRACE(DBG_PWR, "Disabling Wake events in ESS Regs"); ++ ++ /* Disable Energy detect (Link up) & Wake up events to do USB wake */ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, WUCSR, &Value32)); ++ Value32 |=~(WUCSR_MPEN_ | WUCSR_WAKE_EN_ ); ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, WUCSR, Value32)); ++ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, PM_CTRL, &Value32)); ++ Value32 &= ~(PM_CTL_ED_EN_ | PM_CTL_WOL_EN_); ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, PM_CTRL, Value32)); ++ ++ /* Put Lan9500 in Suspend2 */ ++ SMSC_TRACE(DBG_PWR, "Setting Suspend2 mode"); ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, PM_CTRL, &Value32)); ++ Value32 &= (~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_)); ++ Value32 |= PM_CTL_SUS_MODE_2; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, PM_CTRL, Value32)); ++ } ++ ++ ret = 0; ++DONE: ++ return ret; ++} ++ ++static int ResetWakeupEvents(struct net_device *netdev) ++{ ++ u32 dwValue; ++ u16 wValue; ++ int ret = SMSC9500_FAIL; ++ struct usbnet *dev = netdev_priv(netdev); ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ BUG_ON(!adapterData); ++ SMSC_TRACE(DBG_PWR, "ResetWakeupEvents"); ++ ++ if (!(adapterData->WolWakeupOpts & ++ (WAKE_PHY | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST | WAKE_ARP | WAKE_MAGIC))) { ++ return ret; ++ } ++ ++ smsc9500_clear_feature(dev,USB_DEVICE_REMOTE_WAKEUP); ++ if ((adapterData->WolWakeupOpts & WAKE_PHY) && (!(MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS))) { ++ //Disable the energy detect power-down mode ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_MODE_CTRL_STS, &dwValue)); ++ wValue = (u16)dwValue; ++ wValue &= ~MODE_CTRL_STS_EDPWRDOWN_; ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_MODE_CTRL_STS, wValue)); ++ ++ //Disable energy-detect wake-up ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, PM_CTRL, &dwValue)); ++ dwValue &= ~PM_CTL_PHY_RST_; ++ dwValue |= PM_CTL_WUPS_; //Clear wake-up status ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, PM_CTRL, dwValue)); ++ ++ if (!(MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS)) { ++ DisablePHYWakeupInterrupt(dev, adapterData->systemSuspendPHYEvent); ++ } ++ ++ smsc9500_eth_phy_boost(dev, 1); ++ } ++ ++ if (adapterData->WolWakeupOpts & (WAKE_BCAST | WAKE_MCAST | WAKE_ARP | WAKE_UCAST)) { ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, WUCSR, &dwValue)); ++ dwValue &= ~WUCSR_WAKE_EN_; //Disable Wake-up frame detection ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, WUCSR, dwValue)); ++ ++ } ++ ++ if (adapterData->WolWakeupOpts & WAKE_MAGIC) { ++ //Set Magic packet detection ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, WUCSR, &dwValue)); ++ dwValue &= ~WUCSR_MPEN_; //Disable magic frame detection ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, WUCSR, dwValue)); ++ } ++ ++ //Disable wake-up frame interrupt ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, PM_CTRL, &dwValue)); ++ dwValue &= ~PM_CTL_WOL_EN_; ++ dwValue |= PM_CTL_WUPS_; //Clear wake-up status ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, PM_CTRL, dwValue)); ++ ++ ret = 0; ++DONE: ++ return ret; ++} ++ ++static int SetLinkDownWakeupEvents(struct usbnet *dev, int wakeUpMode) ++{ ++ u32 dwValue; ++ u16 wValue; ++ int ret = SMSC9500_FAIL; ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ BUG_ON(!dev); ++ ++ SMSC_TRACE(DBG_PWR, "SetLinkDownWakeupEvents"); ++ ++ if (MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS) { ++ return ret; ++ } ++ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, PM_CTRL, &dwValue)); ++ dwValue |= PM_CTL_ED_EN_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, PM_CTRL, dwValue)); ++ ++ SMSC_TRACE(DBG_PWR, "Setting PHY in PD/ED Mode"); ++ ++ if (wakeUpMode == WAKEPHY_ENERGY) { ++ ++ /* If we are in force mode, set the NWAY */ ++ if ((adapterData->dwSavedLinkSettings&LINK_AUTO_NEGOTIATE) == 0) { ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_BCR, &dwValue)); ++ dwValue |= PHY_BCR_AUTO_NEG_ENABLE_; ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_BCR, dwValue)); ++ } ++ ++ /* Enable the energy detect power-down mode */ ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_MODE_CTRL_STS, &dwValue)); ++ wValue = (u16)dwValue; ++ wValue |= MODE_CTRL_STS_EDPWRDOWN_; ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_MODE_CTRL_STS, wValue)); ++ ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_INT_SRC, &dwValue)); //Read to clear ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_INT_SRC, &dwValue)); //Read two times ++ ++ /* Enable interrupt source */ ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_INT_MASK, &dwValue)); ++ wValue |= (PHY_INT_MASK_ENERGY_ON_ | PHY_INT_MASK_ANEG_COMP_); ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_INT_MASK, wValue)); ++ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, PM_CTRL, &dwValue)); ++ dwValue &= (~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_)); ++ dwValue |= PM_CTL_SUS_MODE_1; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, PM_CTRL, dwValue)); ++ ++ CHECK_RETURN_STATUS(smsc9500_set_feature(dev, USB_DEVICE_REMOTE_WAKEUP)); ++ ++ SMSC_TRACE(DBG_PWR, "Setting Suspend1 mode"); ++ ++ } else if (wakeUpMode == WAKEPHY_NEGO_COMPLETE) { ++ /* Disable the energy detect power-down mode */ ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_MODE_CTRL_STS, &dwValue)); ++ dwValue &= ~MODE_CTRL_STS_EDPWRDOWN_; ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_MODE_CTRL_STS, dwValue)); ++ ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_INT_SRC, &dwValue)); //Read to clear ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_INT_SRC, &dwValue)); //Read two times ++ /* Enable interrupt source */ ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_INT_MASK, &dwValue)); ++ dwValue |= PHY_INT_MASK_ANEG_COMP_; ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_INT_MASK, dwValue)); ++ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, PM_CTRL, &dwValue)); ++ dwValue &= (~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_)); ++ dwValue |= PM_CTL_SUS_MODE_0; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, PM_CTRL, dwValue)); ++ ++ CHECK_RETURN_STATUS(smsc9500_set_feature(dev, USB_DEVICE_REMOTE_WAKEUP)); ++ ++ SMSC_TRACE(DBG_PWR, "Setting Suspend0 mode"); ++ } ++ ret = 0; ++DONE: ++ return ret; ++} ++ ++static int ResetLinkDownWakeupEvents(struct usbnet *dev) ++{ ++ u32 dwValue; ++ u16 wValue; ++ int ret = SMSC9500_FAIL; ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ SMSC_TRACE(DBG_PWR, "ResetLinkDownWakeupEvents"); ++ ++ smsc9500_clear_feature(dev, USB_DEVICE_REMOTE_WAKEUP); ++ ++ /* Disable the energy detect power-down mode */ ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_MODE_CTRL_STS, &dwValue)); ++ wValue = (u16)dwValue; ++ wValue &= ~MODE_CTRL_STS_EDPWRDOWN_; ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_MODE_CTRL_STS, wValue)); ++ ++ //Disable ENERGYON interrupt source ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_INT_MASK, &dwValue)); ++ wValue = (u16)dwValue; ++ wValue &= ~PHY_INT_MASK_ENERGY_ON_; ++ if (dev->linkDownSuspend == WAKEPHY_ENERGY) { ++ wValue &= ~(PHY_INT_MASK_ENERGY_ON_ | PHY_INT_MASK_ANEG_COMP_); ++ } else if (dev->linkDownSuspend == WAKEPHY_NEGO_COMPLETE) { ++ wValue &= ~PHY_INT_MASK_ANEG_COMP_; ++ } ++ ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_INT_MASK, wValue)); ++ ++ /* Disable energy-detect wake-up */ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, PM_CTRL, &dwValue)); ++ dwValue &= ~PM_CTL_ED_EN_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, PM_CTRL, dwValue)); ++ ++ smsc9500_eth_phy_boost(dev, 1); ++ ++ /* If we are in force mode, re-set the NWAY */ ++ if((adapterData->dwSavedLinkSettings&LINK_AUTO_NEGOTIATE) == 0) { ++ phy_SetLink(dev, adapterData->dwSavedLinkSettings); ++ } ++ ret = 0; ++DONE: ++ return ret; ++} ++ ++/*++ ++ ++Routine Description: ++ ++ This routine enables PHY interrupt ++ ++Arguments: ++ interrupt: Bit mask for PHY interrupt ++Return Value: ++ ++--*/ ++ ++static int EnablePHYWakeupInterrupt(struct usbnet *dev, u32 interrupt) ++{ ++ u32 dwValue; ++ int ret = SMSC9500_FAIL; ++ ++ BUG_ON(!dev); ++ ++ SMSC_TRACE(DBG_PWR, "EnablePHYWakeupInterrupt"); ++ ++ if (MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS) { ++ /* Return Success here. During dynamic suspend, mac ++ will be configured to wake and pretend (no phy access) ++ phy is configured.*/ ++ return SMSC9500_SUCCESS; ++ } ++ ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_INT_SRC, &dwValue)); //Read to clear ++ ++ /* Enable interrupt source */ ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_INT_MASK, &dwValue)); ++ dwValue |= interrupt; ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_INT_MASK, dwValue)); ++ ++ if (dwValue) { ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, PM_CTRL, &dwValue)); ++ dwValue &= ~PM_CTL_PHY_RST_; ++ dwValue |= PM_CTL_ED_EN_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, PM_CTRL, dwValue)); ++ } ++ ++ ret = SMSC9500_SUCCESS; ++DONE: ++ return ret; ++} ++ ++/*++ ++ ++Routine Description: ++ ++ This routine Disables linkdown interrupt in the PHY ++ ++Arguments: ++ ++Return Value: ++ ++--*/ ++ ++static int DisablePHYWakeupInterrupt(struct usbnet *dev, u32 interrupt) ++{ ++ u32 dwValue; ++ int ret = SMSC9500_FAIL; ++ ++ BUG_ON(!dev); ++ ++ SMSC_TRACE(DBG_PWR, "DisablePHYWakeupInterrupt"); ++ ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_INT_SRC, &dwValue)); //Read to clear ++ ++ if (MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS) { ++ /* Return Success here. During dynamic suspend resume, ++ mac wake disabled and pretend (no phy access) phy wake ++ disabled. */ ++ return SMSC9500_SUCCESS; ++ } ++ ++ /* Disable interrupt source */ ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_INT_MASK, &dwValue)); ++ dwValue &= PHY_INT_MASK_ALL; ++ dwValue &= ~interrupt; ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_INT_MASK, dwValue)); ++ ++ if (dwValue == 0) { ++ /* All interrupt sources are disabled */ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, PM_CTRL, &dwValue)); ++ dwValue &= ~(PM_CTL_PHY_RST_ | PM_CTL_ED_EN_); ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, PM_CTRL, dwValue)); ++ } ++ ++ ret = SMSC9500_SUCCESS; ++ ++DONE: ++ return ret; ++} ++ ++/* ++Routine Description: ++ ++ This routine Starts the Tx path at the MAC and sets the flag to accept ++ bulk out requests ++ ++*/ ++static int StartTxPath(struct usbnet * dev ) ++{ ++ u32 Value32; ++ int ret = SMSC9500_FAIL; ++ ++ /* Enable Tx at MAC */ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, MAC_CR, &Value32)); ++ Value32 |= MAC_CR_TXEN_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, MAC_CR, Value32)); ++ ++ /* Enable Tx at SCSRs */ ++ Value32 = TX_CFG_ON_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, TX_CFG, Value32)); ++ ++ ret = 0; ++DONE: ++ return ret; ++} ++ ++/* ++Routine Description: ++ ++ Starts the Receive path. ++ ++ Note that if we are operating in USB bandwidth friendly mode we defer ++ starting the bulk in requests for now (will start when operational mode pipe signals ++ receive data available). ++ ++*/ ++static int StartRxPath(struct usbnet *dev ) ++{ ++ u32 Value32; ++ int ret = SMSC9500_FAIL; ++ ++ CHECK_RETURN_STATUS(smsc9500_read_reg(dev, MAC_CR, &Value32)); ++ Value32 |= MAC_CR_RXEN_; ++ CHECK_RETURN_STATUS(smsc9500_write_reg(dev, MAC_CR, Value32)); ++ ++ ret = 0; ++DONE: ++ return ret; ++} ++ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)) ++static int Smsc9500_suspend (struct usb_interface *intf, u32 state) ++#else ++static int Smsc9500_suspend (struct usb_interface *intf, pm_message_t state) ++#endif ++{ ++ u32 dwValue; ++ int ret = SMSC9500_SUCCESS; ++ struct usbnet *dev = usb_get_intfdata(intf); ++ ++ SMSC_TRACE(DBG_PWR, "Smsc9500_suspend"); ++ ++ BUG_ON(!dev); ++ BUG_ON(!dev->udev); ++ ++ smsc9500_read_reg(dev,WUCSR,&dwValue); ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) ++#ifdef CONFIG_PM ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) ++ if(dev->udev->auto_pm) //Internal pm event, autosuspend ++#else ++ if (state.event & PM_EVENT_AUTO) ++#endif ++#else ++ if(0) ++#endif //CONFIG_PM ++#else ++ if(0) ++#endif ++ { ++ /* Auto suspend */ ++ ret = Smsc9500AutoSuspend(intf, state); ++ } else { ++ /* It is system suspend */ ++ ret = Smsc9500SystemSuspend(intf, state); ++ } ++ ++ return ret; ++} ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)) ++static int Smsc9500AutoSuspend (struct usb_interface *intf, u32 state) ++#else ++static int Smsc9500AutoSuspend (struct usb_interface *intf, pm_message_t state) ++#endif ++{ ++ u32 Value32; ++ bool LinkUp = FALSE; ++ int ret = SMSC9500_SUCCESS; ++ struct usbnet *dev = usb_get_intfdata(intf); ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ int suspendFlag = dev->suspendFlag; ++ ++ SMSC_TRACE(DBG_PWR, "Smsc9500AutoSuspend, suspendFlag = 0x%x", suspendFlag); ++ ++ dev->suspendFlag = 0; ++ ++ if (netif_running (dev->net)) { ++ adapterData->wakeupOptsBackup = adapterData->WolWakeupOpts; ++ ++ if (MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS) { ++ if (adapterData->DefaultLinkStatus & MDIO_DEFAULT_LINK_INIT_MASK) { ++ LinkUp = TRUE; ++ } else { ++ LinkUp = FALSE; ++ } ++ } else { ++ /* last minute link check */ ++ /* read PHY_BSR twice: link status bit is LL */ ++ smsc9500_read_phy(dev, PHY_BSR, &Value32); ++ if (smsc9500_read_phy(dev, PHY_BSR, &Value32) < 0) { ++ return SMSC9500_FAIL; ++ } ++ if (Value32 & PHY_BSR_LINK_STATUS_) { ++ LinkUp = TRUE; ++ } else { ++ LinkUp = FALSE; ++ } ++ } ++ ++ if (LinkUp == FALSE) { ++ /* Link is down */ ++ if (dev->netDetach) { ++ /* NetDetach highest priority */ ++ if (!dev->pmLock) { ++ /* Resume immediately, then detach device from USB bus */ ++ smscusbnet_defer_myevent(dev, EVENT_IDLE_RESUME); ++ } ++ ret = SMSC9500_FAIL; ++ goto _SUSPEND_EXIT; ++ } else if (dev->linkDownSuspend || (suspendFlag & AUTOSUSPEND_LINKDOWN)) { ++ dev->suspendFlag |= AUTOSUSPEND_LINKDOWN; ++ if (!(MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS)) { ++ ret = SetLinkDownWakeupEvents(dev, dev->linkDownSuspend); ++ } ++ } else if (suspendFlag & AUTOSUSPEND_DYNAMIC) { ++ dev->suspendFlag |= AUTOSUSPEND_DYNAMIC; ++ adapterData->WolWakeupOpts = (WAKE_UCAST | WAKE_BCAST | WAKE_MCAST | WAKE_ARP); ++ ret = SetWakeupEvents(dev->net); ++ if (!(MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS)) { ++ /* Save PHY interrupt event, so we can clear it after waking up */ ++ adapterData->dynamicSuspendPHYEvent = PHY_INT_MASK_ENERGY_ON_ | ++ PHY_INT_MASK_ANEG_COMP_; ++ ret = EnablePHYWakeupInterrupt(dev, adapterData->dynamicSuspendPHYEvent); ++ } ++ } else if (suspendFlag & AUTOSUSPEND_DYNAMIC_S3) { ++ /* LAN9500A on wards supports suspend3 */ ++ dev->suspendFlag |= AUTOSUSPEND_DYNAMIC_S3; ++ ret = SetWakeupOnSuspend3(dev->net); ++ if ((ret != SMSC9500_FAIL) && (!(MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS))) { ++ /* Save PHY interrupt event, so we can clear it after waking up */ ++ adapterData->dynamicSuspendPHYEvent = PHY_INT_MASK_ENERGY_ON_ | ++ PHY_INT_MASK_ANEG_COMP_; ++ ret = EnablePHYWakeupInterrupt(dev, adapterData->dynamicSuspendPHYEvent); ++ } ++ } else { ++ SMSC_WARNING("auto suspend event is null\n"); ++ ret = SMSC9500_FAIL; ++ } ++ } else { ++ /* Link Up */ ++ if (suspendFlag & AUTOSUSPEND_DYNAMIC) { ++ dev->suspendFlag |= AUTOSUSPEND_DYNAMIC; ++ adapterData->WolWakeupOpts = (WAKE_UCAST | WAKE_BCAST | WAKE_MCAST | WAKE_ARP); ++ ret = SetWakeupEvents(dev->net); ++ if (!(MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS)) { ++ /* Save PHY interrupt event, so we can clear it after waking up */ ++ adapterData->dynamicSuspendPHYEvent = PHY_INT_MASK_LINK_DOWN_; ++ ret = EnablePHYWakeupInterrupt(dev, adapterData->dynamicSuspendPHYEvent); ++ } ++ } else if(suspendFlag & AUTOSUSPEND_DYNAMIC_S3) { ++ dev->suspendFlag |= AUTOSUSPEND_DYNAMIC_S3; ++ ret = SetWakeupOnSuspend3(dev->net); ++ if ((ret != SMSC9500_FAIL) && (!(MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS))) { ++ /* Save PHY interrupt event, so we can clear it after waking up */ ++ adapterData->dynamicSuspendPHYEvent = PHY_INT_MASK_LINK_DOWN_; ++ ret = EnablePHYWakeupInterrupt(dev, adapterData->dynamicSuspendPHYEvent); ++ } ++ } else { ++ /* if(suspendFlag & AUTOSUSPEND_LINKDOWN) Resume immediately */ ++ ret = SMSC9500_FAIL; ++ } ++ } ++ ++ if (ret != SMSC9500_SUCCESS) { ++ SMSC_WARNING("Failed to suspend device\n"); ++ dev->suspendFlag = 0; ++ if (!dev->pmLock) { ++ /* Resume immediately */ ++ smscusbnet_defer_myevent(dev, EVENT_IDLE_RESUME); ++ } ++ goto _SUSPEND_EXIT; ++ } else { ++ smscusbnet_FreeQueue(dev); ++ del_timer_sync(&dev->LinkPollingTimer); ++ } ++ } else { ++ /* Interface down */ ++ u32 Value32; ++ SMSC_TRACE(DBG_PWR, "Interface is down, set suspend2 mode"); ++ smsc9500_read_reg(dev, PM_CTRL, &Value32); ++ Value32 &= (~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_)); ++ Value32 |= PM_CTL_SUS_MODE_2; ++ smsc9500_write_reg(dev, PM_CTRL, Value32); ++ dev->suspendFlag |= AUTOSUSPEND_INTFDOWN; ++ } ++_SUSPEND_EXIT: ++ return ret; ++} ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)) ++static int Smsc9500SystemSuspend (struct usb_interface *intf, u32 state) ++#else ++static int Smsc9500SystemSuspend (struct usb_interface *intf, pm_message_t state) ++#endif ++{ ++ struct usbnet *dev = usb_get_intfdata(intf); ++ ++ SMSC_TRACE(DBG_PWR, "Smsc9500SystemSuspend"); ++ ++ dev->idleCount = 0; ++ dev->suspendFlag = 0; ++ ++ if (dev->net && netif_running (dev->net) && netif_device_present (dev->net)) { ++ netif_device_detach (dev->net); ++ smscusbnet_FreeQueue(dev); ++ ++ dev->StopLinkPolling = TRUE; ++ del_timer_sync(&dev->LinkPollingTimer); ++ ++ Tx_StopQueue(dev,0x04UL); ++ smsc9500_stopAndFlushTxPath(dev); ++ smsc9500_stopAndFlushRxPath(dev); ++ ++ SetWakeupEvents(dev->net); ++ } else { ++ /* Put device to Suspend2 */ ++ u32 Value32; ++ SMSC_TRACE(DBG_PWR, "Setting Suspend2 mode"); ++ smsc9500_read_reg(dev, PM_CTRL, &Value32); ++ Value32 &= (~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_)); ++ Value32 |= PM_CTL_SUS_MODE_2; ++ smsc9500_write_reg(dev, PM_CTRL, Value32); ++ dev->suspendFlag |= AUTOSUSPEND_INTFDOWN; ++ } ++ ++ return SMSC9500_SUCCESS; ++} ++ ++static int Smsc9500_resume(struct usb_interface *intf) ++{ ++ int ret = SMSC9500_SUCCESS; ++ struct usbnet *dev = usb_get_intfdata(intf); ++ ++ SMSC_TRACE(DBG_PWR, "Smsc9500_resume"); ++ ++ BUG_ON(!dev); ++ BUG_ON(!dev->udev); ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) ++ /* autoresume */ ++ if(dev->suspendFlag) ++#else ++ if(0) ++#endif ++ { ++ ret = Smsc9500AutoResume(intf); ++ } else { ++ ret = Smsc9500SystemResume(intf); ++ } ++ return ret; ++} ++ ++static int Smsc9500AutoResume(struct usb_interface *intf) ++{ ++ u32 dwValue; ++ struct usbnet *dev = usb_get_intfdata(intf); ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ SMSC_TRACE(DBG_PWR, "Smsc9500AutoResume"); ++ ++ clear_bit(EVENT_DEV_RECOVERY, &dev->flags); ++ ++ if (dev->suspendFlag & AUTOSUSPEND_INTFDOWN) { ++ SMSC_TRACE(DBG_PWR, "Resume from interface down"); ++ goto _EXIT_AUTORESUME; ++ } ++ ++ if (!dev->pmLock) { ++ smscusbnet_defer_myevent(dev, EVENT_IDLE_RESUME); ++ } ++ ++ if (dev->suspendFlag & AUTOSUSPEND_LINKDOWN) { ++ if (!(MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS)) { ++ ResetLinkDownWakeupEvents(dev); ++ } ++ } else if(dev->suspendFlag & AUTOSUSPEND_DYNAMIC) { ++ if (!(MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS)) { ++ DisablePHYWakeupInterrupt(dev, adapterData->dynamicSuspendPHYEvent); ++ } ++ ResetWakeupEvents(dev->net); ++ } else if(dev->suspendFlag & AUTOSUSPEND_DYNAMIC_S3) { ++ /* Resume from suspend3 */ ++ smsc9500_clear_feature(dev,USB_DEVICE_REMOTE_WAKEUP); ++ ++ if (!(MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS)) { ++ DisablePHYWakeupInterrupt(dev, adapterData->dynamicSuspendPHYEvent); ++ } ++ ++ if (smsc9500_read_reg(dev, PM_CTRL, &dwValue) < 0) { ++ SMSC_WARNING("Failed to read PM_CTRL"); ++ } ++ dwValue &= (~(PM_CTL_SUS_MODE_ | PM_CTL_PHY_RST_)); ++ dwValue |= PM_CTL_SUS_MODE_2; ++ ++ if (smsc9500_write_reg(dev, PM_CTRL, dwValue) < 0) { ++ SMSC_WARNING("Failed to write PM_CTRL"); ++ } ++ dwValue &= ~PM_CTL_WUPS_; ++ dwValue |= PM_CTL_WUPS_WOL_; ++ ++ /* Should not change suspend_mode while clearing WUPS_sts[1] */ ++ if (smsc9500_write_reg(dev, PM_CTRL, dwValue) < 0) { ++ SMSC_WARNING("Failed to write PM_CTRL"); ++ } ++ } ++ //if(dev->delay.function)(dev->delay.function)((unsigned long)dev); ++ tasklet_schedule(&dev->bh); ++ ++ if (adapterData->wakeupOptsBackup) { ++ adapterData->WolWakeupOpts = adapterData->wakeupOptsBackup; ++ adapterData->wakeupOptsBackup = 0; ++ } ++ ++ Tx_WakeQueue(dev,0x04UL); ++ ++_EXIT_AUTORESUME: ++ dev->idleCount = 0; ++ dev->suspendFlag = 0; ++ ++ return SMSC9500_SUCCESS; ++} ++ ++static int Smsc9500SystemResume(struct usb_interface *intf) ++{ ++ int ret = 0; ++ u32 dwValue; ++ struct usbnet *dev = usb_get_intfdata(intf); ++ ++ SMSC_TRACE(DBG_PWR, "Smsc9500SystemResume\n"); ++ ++ if (netif_running(dev->net) && !netif_device_present (dev->net)) { ++ netif_device_attach(dev->net); ++ } ++ ++ /* Test if hcd is still alive */ ++ if (smsc9500_read_reg_async(dev, MAC_CR, &dwValue, TRUE) == ASYNC_RW_SUCCESS) { ++ SMSC_TRACE(DBG_PWR, "hcd is alive"); ++ ret = smsc9500_reset(dev); ++ if (ret < 0) ++ return ret; ++ StartTxPath(dev); ++ StartRxPath(dev); ++ ResetWakeupEvents(dev->net); ++ } else { ++ /* This will happen on suspend-to-disk, if we access usb bus, ++ will hang on usb_kill_urb */ ++ SMSC_TRACE(DBG_PWR, "no hcd"); ++ } ++ ++ Tx_WakeQueue(dev,0x04UL); ++ ++ init_timer(&(dev->LinkPollingTimer)); ++ dev->StopLinkPolling = FALSE; ++ dev->LinkPollingTimer.function = smscusbnet_linkpolling; ++ dev->LinkPollingTimer.data = (unsigned long) dev; ++ dev->LinkPollingTimer.expires = jiffies+HZ; ++ add_timer(&(dev->LinkPollingTimer)); ++ tasklet_schedule (&dev->bh); ++ ++ dev->idleCount = 0; ++ ++ return SMSC9500_SUCCESS; ++} ++ ++static int smsc9500_device_recovery(struct usbnet *dev) ++{ ++ u32 dwReadBuf; ++ ++ BUG_ON(!dev); ++ ++ if (dev->net && netif_device_present (dev->net)) { ++ SMSC_WARNING("Device recovery is in progress\n"); ++ ++ if (smsc9500_read_reg(dev,INT_STS,&dwReadBuf) < 0) ++ return SMSC9500_FAIL; ++ ++ smscusbnet_FreeQueue(dev); ++ ++ dev->StopLinkPolling = TRUE; ++ del_timer_sync(&dev->LinkPollingTimer); ++ ++ Tx_StopQueue(dev,0x04UL); ++ ++ if (smsc9500_stopAndFlushTxPath(dev) < 0) ++ return SMSC9500_FAIL; ++ if (smsc9500_stopAndFlushRxPath(dev) < 0) ++ return SMSC9500_FAIL; ++ ++ if (dwReadBuf & INT_STS_TXE_) { ++ /* reset only when TXE */ ++ if (smsc9500_reset(dev) < 0) ++ return SMSC9500_FAIL; ++ } ++ ++ if(StartTxPath(dev) < 0) ++ return SMSC9500_FAIL; ++ if(StartRxPath(dev) < 0) ++ return SMSC9500_FAIL; ++ ++ Tx_WakeQueue(dev,0x04UL); ++ ++ init_timer(&(dev->LinkPollingTimer)); ++ dev->StopLinkPolling = FALSE; ++ dev->LinkPollingTimer.function = smscusbnet_linkpolling; ++ dev->LinkPollingTimer.data = (unsigned long) dev; ++ dev->LinkPollingTimer.expires = jiffies+HZ; ++ add_timer(&(dev->LinkPollingTimer)); ++ ++ tasklet_schedule (&dev->bh); ++ ++ SMSC_WARNING("Device recovery is done\n"); ++ } ++ ++ return SMSC9500_SUCCESS; ++} ++ ++static int smsc9500_eth_phy_boost(struct usbnet *dev, int mode) ++{ ++ u32 dwTemp; ++ int Count; ++ PADAPTER_DATA adapterData = (PADAPTER_DATA)(dev->data[0]); ++ ++ /* If mdio access is disabled return */ ++ if (MdioDisable & MDIO_DISABLE_INTERNAL_ACCESS) { ++ return 0; ++ } ++ if ((adapterData->internalPhy) && ((dev->chipID == PID_LAN9730) || ++ (dev->chipID == PID_LAN9530) || (dev->chipID == PID_LAN89530))) { ++ if (mode == 1) { ++ /* set boost */ ++ dwTemp = PHY_TSTCNTL_TEST_MODE; ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_TSTCNTL, dwTemp)); ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_TSTCNTL, 0 )); ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_TSTCNTL, dwTemp)); ++ ++ dwTemp = 0x85E8; ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_TSTWRITE, dwTemp)); ++ /* dwTemp = 0x4416; */ ++ dwTemp = (PHY_TSTCNTL_WRITE | PHY_TSTCNTL_TEST_MODE | 0x16); ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_TSTCNTL, dwTemp)); ++ /* Loop until write is completed w/timeout */ ++ for(Count = 1; Count < 100; Count++) { ++ dwTemp = 0; ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_TSTCNTL, &dwTemp)); ++ if(!(dwTemp & PHY_TSTCNTL_WRITE)) ++ break; ++ udelay(1); ++ } ++ ++ if (Count == 100) { ++ SMSC_WARNING("Timed out writing PHY_TSTWRITE\n"); ++ } ++ ++ #if 0 ++ /* read and verify the value */ ++ /* dwTemp = 0x86C0 */ ++ dwTemp = (PHY_TSTCNTL_READ | PHY_TSTCNTL_TEST_MODE | 0xC0); ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_TSTCNTL, dwTemp)); ++ /* Loop until read is completed w/timeout */ ++ for(Count = 1; Count < 100; Count++) { ++ dwTemp = 0; ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_TSTCNTL, &dwTemp)); ++ if(!(dwTemp & PHY_TSTCNTL_READ)) ++ break; ++ udelay(1); ++ } ++ ++ if (Count < 100) { ++ dwTemp = 0; ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_TSTREAD1, &dwTemp)); ++ if (dwTemp != 0x85E8) { ++ SMSC_WARNING("Failed to set Ethernet Boost: 0x%x", dwTemp); ++ } else{ ++ SMSC_TRACE(DBG_INIT, "Ethernet Boost: 0x%x", dwTemp); ++ } ++ ++ } else { ++ SMSC_WARNING("Timed out reading PHY_TSTREAD1 register\n"); ++ return 1; ++ } ++ #endif ++ ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_TSTCNTL, 0 )); ++ } else { ++ #if 0 ++ dwTemp = PHY_TSTCNTL_TEST_MODE; ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_TSTCNTL, dwTemp)); ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_TSTCNTL, 0 )); ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_TSTCNTL, dwTemp)); ++ ++ /* read and verify the value */ ++ /* dwTemp = 0x86C0; */ ++ dwTemp = (PHY_TSTCNTL_READ | PHY_TSTCNTL_TEST_MODE | 0xC0); ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_TSTCNTL, dwTemp)); ++ /* Loop until read is completed w/timeout */ ++ for(Count= 1; Count < 100; Count++) { ++ dwTemp = 0; ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_TSTCNTL, &dwTemp)); ++ if (!(dwTemp & PHY_TSTCNTL_READ)) ++ break; ++ udelay(1); ++ } ++ ++ if (Count < 100) { ++ dwTemp = 0; ++ CHECK_RETURN_STATUS(smsc9500_read_phy(dev, PHY_TSTREAD1, &dwTemp)); ++ if (dwTemp != 0x85E8) { ++ SMSC_WARNING("Failed to set Ethernet Boost: 0x%x", dwTemp); ++ } else { ++ SMSC_TRACE(DBG_INIT, "Ethernet Boost: 0x%x", dwTemp); ++ } ++ ++ } else { ++ SMSC_WARNING("Timed out reading PHY_TSTREAD1 register"); ++ return 1; ++ } ++ ++ CHECK_RETURN_STATUS(smsc9500_write_phy(dev, PHY_TSTCNTL, 0 )); ++ #endif ++ } ++ } ++ return 0; ++DONE: ++ return 1; ++} ++ ++ ++static const struct driver_info smsc9500_info = { ++ .description = "smsc9500 USB 2.0 Ethernet", ++ .bind = smsc9500_bind, ++ .unbind=smsc9500_unbind, ++ .status = smsc9500_status, ++ .link_reset = smsc9500_link_reset, ++ .reset = smsc9500_reset, ++ .flags = FLAG_ETHER, ++ .rx_fixup = smsc9500_rx_fixup, ++ .tx_fixup = smsc9500_tx_fixup, ++ .rx_setmulticastlist=smsc9500_rx_setmulticastlist, ++}; ++ ++static const struct usb_device_id products [] = { ++ { ++ /* SMSC9500 USB Ethernet Device */ ++ USB_DEVICE (0x0424, PID_LAN9500), ++ .driver_info = (unsigned long) &smsc9500_info, ++ }, ++ { ++ /* SMSC9512/9514 USB hub with Ethernet Device */ ++ USB_DEVICE (0x0424, PID_LAN9512), ++ .driver_info = (unsigned long) &smsc9500_info, ++ }, ++ { ++ /* SMSC9500A USB Ethernet Device */ ++ USB_DEVICE (0x0424, PID_LAN9500A), ++ .driver_info = (unsigned long) &smsc9500_info, ++ }, ++ { ++ /* LAN9530 USB Ethernet Device */ ++ USB_DEVICE (0x0424, PID_LAN9530 ), ++ .driver_info = (unsigned long) &smsc9500_info, ++ }, ++ { ++ /* LAN9730 USB Ethernet Device */ ++ USB_DEVICE (0x0424, PID_LAN9730), ++ .driver_info = (unsigned long) &smsc9500_info, ++ }, ++ { ++ /* LAN89530 USB Ethernet Device */ ++ USB_DEVICE (0x0424, PID_LAN89530), ++ .driver_info = (unsigned long) &smsc9500_info, ++ }, ++ { }, /* END */ ++}; ++ ++MODULE_DEVICE_TABLE(usb, products); ++ ++static struct usb_driver smsc9500_driver = { ++ .name = "smsc9500", ++ .id_table = products, ++ .probe = smscusbnet_probe, ++ .suspend = Smsc9500_suspend, ++ .resume = Smsc9500_resume, ++ .disconnect = smscusbnet_disconnect, ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) ++ .reset_resume = Smsc9500SystemResume, ++#endif ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) ++ .supports_autosuspend = 1, ++#endif ++}; ++ ++static int __init smsc9500_init(void) ++{ ++ return usb_register(&smsc9500_driver); ++} ++module_init(smsc9500_init); ++ ++static void __exit smsc9500_exit(void) ++{ ++ usb_deregister(&smsc9500_driver); ++} ++module_exit(smsc9500_exit); ++ ++MODULE_AUTHOR("Nancy Lin and Sean(Xiang) Chen"); ++MODULE_DESCRIPTION("SMSC9500 USB 2.0 Ethernet Devices"); ++MODULE_LICENSE("GPL"); ++ +diff --git a/drivers/net/ethernet/smsc9514/smsc9500.h b/drivers/net/ethernet/smsc9514/smsc9500.h +new file mode 100755 +index 0000000..09f8093 +--- /dev/null ++++ b/drivers/net/ethernet/smsc9514/smsc9500.h +@@ -0,0 +1,859 @@ ++/*************************************************************************** ++ * ++ * Copyright (C) 2007-2008 SMSC ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ *************************************************************************** ++ * File: smsc9500.h ++ *****************************************************************************/ ++ ++#ifndef _LAN9500_H ++#define _LAN9500_H ++ ++typedef unsigned char BYTE; ++ ++#define STATUS_WORD_LEN 4 ++ ++#define LAN_REGISTER_RANGE 0xFF ++#define MAC_REGISTER_RANGE_MIN 0x100 ++#define MAC_REGISTER_RANGE_MAX 0x130 ++ ++/* product id definition */ ++#define PID_LAN9500 0x9500 ++#define PID_LAN9500A 0x9E00 ++#define PID_LAN9512 0xEC00 ++#define PID_LAN9530 0x9530 ++#define PID_LAN9535 0x9535 ++#define PID_LAN9730 0x9730 ++#define PID_LAN9735 0x9735 ++#define PID_LAN89530 0x9E08 ++ ++/* Tx MAT Cmds */ ++#define TX_CMD_A_DATA_OFFSET_ (0x001F0000UL) ++#define TX_CMD_A_FIRST_SEG_ (0x00002000UL) ++#define TX_CMD_A_LAST_SEG_ (0x00001000UL) ++#define TX_CMD_A_BUF_SIZE_ (0x000007FFUL) ++ ++#define TX_CMD_B_CSUM_ENABLE (0x00004000UL) ++#define TX_CMD_B_ADD_CRC_DISABLE_ (0x00002000UL) ++#define TX_CMD_B_DISABLE_PADDING_ (0x00001000UL) ++#define TX_CMD_B_PKT_BYTE_LENGTH_ (0x000007FFUL) ++ ++/* Rx sts Wd */ ++#define RX_STS_FF_ 0x40000000UL // Filter Fail ++#define RX_STS_FL_ 0x3FFF0000UL // Frame Length ++#define RX_STS_DL_SHIFT_ 16UL ++#define RX_STS_ES_ 0x00008000UL // Error Summary ++#define RX_STS_BF_ 0x00002000UL // Broadcast Frame ++#define RX_STS_LE_ 0x00001000UL // Length Error ++#define RX_STS_RF_ 0x00000800UL // Runt Frame ++#define RX_STS_MF_ 0x00000400UL // Multicast Frame ++#define RX_STS_TL_ 0x00000080UL // Frame too long ++#define RX_STS_CS_ 0x00000040UL // Collision Seen ++#define RX_STS_FT_ 0x00000020UL // Frame Type ++#define RX_STS_RW_ 0x00000010UL // Receive Watchdog ++#define RX_STS_ME_ 0x00000008UL // Mii Error ++#define RX_STS_DB_ 0x00000004UL // Dribbling ++#define RX_STS_CRC_ 0x00000002UL // CRC Error ++#define RX_STS_ERR_MASK_ 0x000088DEUL ++ ++ ++/* SCSRs */ ++#define ID_REV (0x00UL) ++ #define ID_REV_CHIP_ID_MASK_ (0xffff0000UL) ++ #define ID_REV_CHIP_REV_MASK_ (0x0000ffffUL) ++ #define ID_REV_CHIP_ID_9500_ (0x9500UL) ++ #define GetChipIdFromID_REV(dwReg) ((dwReg & ID_REV_CHIP_ID_MASK_) >> 16) ++ #define GetChiprevFromID_REV(dwReg) (dwReg & ID_REV_CHIP_REV_MASK_) ++ ++#define FPGA_REV (0x04UL) ++ ++#define INT_STS (0x08UL) ++ #define INT_STS_TX_STOP_ (0x00020000UL) ++ #define INT_STS_RX_STOP_ (0x00010000UL) ++ #define INT_STS_PHY_INT_ (0x00008000UL) ++ #define INT_STS_TXE_ (0x00004000UL) ++ #define INT_STS_TDFU_ (0x00002000UL) ++ #define INT_STS_TDFO_ (0x00001000UL) ++ #define INT_STS_RXDF_ (0x00000800UL) ++ #define INT_STS_GPIOS_ (0x000007FFUL) ++ ++#define RX_CFG (0x0CUL) ++ #define RX_FIFO_FLUSH_ (0x00000001UL) ++ ++#define TX_CFG (0x10UL) ++ #define TX_CFG_ON_ (0x00000004UL) ++ #define TX_CFG_STOP_ (0x00000002UL) ++ #define TX_CFG_FIFO_FLUSH_ (0x00000001UL) ++ ++#define HW_CFG (0x14UL) ++ #define HW_CFG_SMDET_STS (0x00040000UL) ++ #define HW_CFG_SMDET_EN (0x00020000UL) ++ #define HW_CFG_EEM (0x00010000UL) ++ #define HW_CFG_RST_PROTECT (0x00008000UL) ++ #define HW_CFG_PHY_BOOST (0x00006000UL) ++ #define HW_CFG_PHY_BOOST_NORMAL (0x00000000UL) ++ #define HW_CFG_PHY_BOOST_4 (0x00002000UL) ++ #define HW_CFG_PHY_BOOST_8 (0x00004000UL) ++ #define HW_CFG_PHY_BOOST_12 (0x00006000UL) ++ #define HW_CFG_BIR_ (0x00001000UL) ++ #define HW_CFG_LEDB_ (0x00000800UL) ++ #define HW_CFG_RXDOFF_ (0x00000600UL) ++ #define HW_CFG_RXDOFF_2_ (0x00000400UL) ++ #define HW_CFG_SBP_ (0x00000100UL) ++ #define HW_CFG_IME_ (0x00000080UL) ++ #define HW_CFG_DRP_ (0x00000040UL) ++ #define HW_CFG_MEF_ (0x00000020UL) ++ #define HW_CFG_ETC_ (0x00000010UL) ++ #define HW_CFG_LRST_ (0x00000008UL) ++ #define HW_CFG_PSEL_ (0x00000004UL) ++ #define HW_CFG_BCE_ (0x00000002UL) ++ #define HW_CFG_SRST_ (0x00000001UL) ++ ++#define RX_FIFO_INF (0x18UL) ++ ++#define TX_FIFO_INF (0x1CUL) ++ ++#define PM_CTRL (0x20UL) ++ #define PM_CTL_RES_CLR_WKP_STS (0x00000200UL) ++ #define PM_CTL_RES_CLR_WKP_EN (0x00000100UL) ++ #define PM_CTL_DEV_RDY_ (0x00000080UL) ++ #define PM_CTL_SUS_MODE_ (0x00000060UL) ++ #define PM_CTL_SUS_MODE_0 (0x00000000UL) ++ #define PM_CTL_SUS_MODE_1 (0x00000020UL) ++ #define PM_CTL_SUS_MODE_2 (0x00000040UL) ++ #define PM_CTL_SUS_MODE_3 (0x00000060UL) ++ #define PM_CTL_PHY_RST_ (0x00000010UL) ++ #define PM_CTL_WOL_EN_ (0x00000008UL) ++ #define PM_CTL_ED_EN_ (0x00000004UL) ++ #define PM_CTL_WUPS_ (0x00000003UL) ++ #define PM_CTL_WUPS_NO_ (0x00000000UL) ++ #define PM_CTL_WUPS_ED_ (0x00000001UL) ++ #define PM_CTL_WUPS_WOL_ (0x00000002UL) ++ #define PM_CTL_WUPS_MULTI_ (0x00000003UL) ++ ++#define LED_GPIO_CFG (0x24UL) ++ #define LED_GPIO_CFG_LED_SEL_ (0x80000000UL) ++ #define LED_GPIO_CFG_GPCTL_10_ (0x03000000UL) ++ #define LED_GPIO_CFG_GPCTL_10_SH 24 ++ #define LED_GPIO_CFG_GPCTL_09_ (0x00300000UL) ++ #define LED_GPIO_CFG_GPCTL_09_SH 20 ++ #define LED_GPIO_CFG_GPCTL_08_ (0x00030000UL) ++ #define LED_GPIO_CFG_GPCTL_08_SH 16 ++ ++ #define LED_GPIO_CFG_GPCTL_DIAG2_ (0x3UL) ++ #define LED_GPIO_CFG_GPCTL_DIAG1_ (0x2UL) ++ #define LED_GPIO_CFG_GPCTL_LED_ (0x1UL) ++ #define LED_GPIO_CFG_GPCTL_GPIO_ (0x0UL) ++ ++ #define LED_GPIO_CFG_GPBUF_ (0x00000700UL) ++ #define LED_GPIO_CFG_GPBUF_10_ (0x00000400UL) ++ #define LED_GPIO_CFG_GPBUF_09_ (0x00000200UL) ++ #define LED_GPIO_CFG_GPBUF_08_ (0x00000100UL) ++ #define LED_GPIO_CFG_GPDIR_ (0x00000070UL) ++ #define LED_GPIO_CFG_GPDIR_10_ (0x00000040UL) ++ #define LED_GPIO_CFG_GPDIR_09_ (0x00000020UL) ++ #define LED_GPIO_CFG_GPDIR_08_ (0x00000010UL) ++ #define LED_GPIO_CFG_GPDATA_ (0x00000007UL) ++ #define LED_GPIO_CFG_GPDATA_10_ (0x00000004UL) ++ #define LED_GPIO_CFG_GPDATA_09_ (0x00000002UL) ++ #define LED_GPIO_CFG_GPDATA_08_ (0x00000001UL) ++ ++#define GPIO_CFG (0x28UL) ++ #define GPIO_CFG_GPEN_ (0xFF000000UL) ++ #define GPIO_CFG_GPO0_EN_ (0x01000000UL) ++ #define GPIO_CFG_GPTYPE_ (0x00FF0000UL) ++ #define GPIO_CFG_GPO0_TYPE_ (0x00010000UL) ++ #define GPIO_CFG_GPDIR_ (0x0000FF00UL) ++ #define GPIO_CFG_GPO0_DIR_ (0x00000100UL) ++ #define GPIO_CFG_GPDATA_ (0x000000FFUL) ++ #define GPIO_CFG_GPO0_DATA_ (0x00000001UL) ++ ++#define AFC_CFG (0x2CUL) ++ #define AFC_CFG_DEFAULT (0x00f830A1UL) // Hi watermark = 15.5Kb (~10 mtu pkts) ++ // low watermark = 3k (~2 mtu pkts) ++ // backpressure duration = ~ 350us ++ // Apply FC on any frame. ++#define E2P_CMD (0x30UL) ++ #define E2P_CMD_BUSY_ 0x80000000UL ++ #define E2P_CMD_MASK_ 0x70000000UL ++ #define E2P_CMD_READ_ 0x00000000UL ++ #define E2P_CMD_EWDS_ 0x10000000UL ++ #define E2P_CMD_EWEN_ 0x20000000UL ++ #define E2P_CMD_WRITE_ 0x30000000UL ++ #define E2P_CMD_WRAL_ 0x40000000UL ++ #define E2P_CMD_ERASE_ 0x50000000UL ++ #define E2P_CMD_ERAL_ 0x60000000UL ++ #define E2P_CMD_RELOAD_ 0x70000000UL ++ #define E2P_CMD_TIMEOUT_ 0x00000400UL ++ #define E2P_CMD_LOADED_ 0x00000200UL ++ #define E2P_CMD_ADDR_ 0x000001FFUL ++#define E2P_DATA (0x34UL) ++ #define E2P_DATA_MASK_ 0x000000FFUL ++ ++#define BURST_CAP (0x38UL) ++#define STRAP_DBG (0x3CUL) ++ #define EEPROM_DISABLE (0x1) ++ #define EEPROM_SIZE (0x4) ++#define DP_SEL (0x40UL) ++ #define DP_SEL_DPRDY (0x80000000UL) ++ #define DP_SEL_RSEL (0x00000006UL) ++ #define DP_SEL_RSEL_FCT (0x00000000UL) ++ #define DP_SEL_RSEL_EEPROM (0x00000002UL) ++ #define DP_SEL_RSEL_TXTLI (0x00000004UL) ++ #define DP_SEL_RSEL_RXTLI (0x00000006UL) ++ #define DP_SEL_TESTEN (0x00000001UL) ++#define DP_CMD (0x44UL) ++ #define DP_CMD_READ (0x0) ++ #define DP_CMD_WRITE (0x1) ++#define DP_ADDR (0x48UL) ++#define DP_DATA0 (0x4CUL) ++#define DP_DATA1 (0x50UL) ++#define RAM_BIST0 (0x54UL) ++#define RAM_BIST1 (0x58UL) ++#define RAM_BIST2 (0x5CUL) ++#define RAM_BIST3 (0x60UL) ++#define GPIO_WAKE (0x64UL) ++#define BULK_IN_DLY (0x6CUL) ++ ++#define INT_EP_CTL (0x68UL) ++ #define INT_EP_CTL_INTEP_ (0x80000000UL) ++ #define INT_EP_CTL_MACRTO_ (0x00080000UL) ++ #define INT_EP_CTL_RX_FIFO_EN_ (0x00040000UL) ++ #define INT_EP_CTL_TX_STOP_ (0x00020000UL) ++ #define INT_EP_CTL_RX_STOP_ (0x00010000UL) ++ #define INT_EP_CTL_PHY_INT_ (0x00008000UL) ++ #define INT_EP_CTL_TXE_ (0x00004000UL) ++ #define INT_EP_CTL_TDFU_ (0x00002000UL) ++ #define INT_EP_CTL_TDFO_ (0x00001000UL) ++ #define INT_EP_CTL_RXDF_ (0x00000800UL) ++ #define INT_EP_CTL_GPIOS_ (0x000007FFUL) ++ ++#define FLAG_ATTR (0xB0UL) ++ #define FLAG_ATTR_RMT_WKP (0x20000UL) ++ #define FLAG_ATTR_SELF_PWR (0x10000UL) ++ #define FLAG_ATTR_PME_ENABLE (0x80UL) ++ #define FLAG_ATTR_PME_CFG_PULSE (0x40UL) ++ #define FLAG_ATTR_PME_LEN_150MS (0x20UL) ++ #define FLAG_ATTR_PME_POL (0x10UL) ++ #define FLAG_ATTR_PME_BUFF_TYPE (0x8UL) ++ #define FLAG_ATTR_PME_WAKE_PHY (0x4UL) ++ #define FLAG_ATTR_PME_GPIO10_HIGH (0x2UL) ++ ++#define MAC_CR (0x100UL) ++ #define MAC_CR_RXALL_ 0x80000000UL ++ #define MAC_CR_ENABLE_EEE 0x02000000UL ++ #define MAC_CR_RCVOWN_ 0x00800000UL ++ #define MAC_CR_LOOPBK_ 0x00200000UL ++ #define MAC_CR_FDPX_ 0x00100000UL ++ #define MAC_CR_MCPAS_ 0x00080000UL ++ #define MAC_CR_PRMS_ 0x00040000UL ++ #define MAC_CR_INVFILT_ 0x00020000UL ++ #define MAC_CR_PASSBAD_ 0x00010000UL ++ #define MAC_CR_HFILT_ 0x00008000UL ++ #define MAC_CR_HPFILT_ 0x00002000UL ++ #define MAC_CR_LCOLL_ 0x00001000UL ++ #define MAC_CR_BCAST_ 0x00000800UL ++ #define MAC_CR_DISRTY_ 0x00000400UL ++ #define MAC_CR_PADSTR_ 0x00000100UL ++ #define MAC_CR_BOLMT_MASK 0x000000C0UL ++ #define MAC_CR_DFCHK_ 0x00000020UL ++ #define MAC_CR_TXEN_ 0x00000008UL ++ #define MAC_CR_RXEN_ 0x00000004UL ++#define ADDRH (0x104UL) ++#define ADDRL (0x108UL) ++#define HASHH (0x10CUL) ++#define HASHL (0x110UL) ++ ++#define MII_ADDR (0x114UL) ++ #define MII_WRITE_ (0x02UL) ++ #define MII_BUSY_ (0x01UL) ++ #define MII_READ_ (0x00UL) // ~of MII Write bit ++#define MII_DATA (0x118UL) ++#define FLOW (0x11CUL) ++ #define FLOW_FCPT_ (0xFFFF0000UL) ++ #define FLOW_FCPASS_ (0x00000004UL) ++ #define FLOW_FCEN_ (0x00000002UL) ++ #define FLOW_FCBSY_ (0x00000001UL) ++ ++#define VLAN1 (0x120UL) ++#define VLAN2 (0x124UL) ++#define WUFF (0x128UL) ++#define WUCSR (0x12CUL) ++ #define WUCSR_GUE_ (0x00000200UL) ++ #define WUCSR_WUFR_ (0x00000040UL) ++ #define WUCSR_MPR_ (0x00000020UL) ++ #define WUCSR_WAKE_EN_ (0x00000004UL) ++ #define WUCSR_MPEN_ (0x00000002UL) ++ ++#define COE_CR (0x130UL) ++ #define Tx_COE_EN_ (0x00010000UL) ++ #define Rx_COE_MODE_ (0x00000002UL) ++ #define Rx_COE_EN_ (0x00000001UL) ++ ++/* PHY Definitions */ ++#define LAN_PHY_ADDR (1UL) ++ ++#define PHY_BCR ((u32)0U) ++ #define PHY_BCR_RESET_ ((u16)0x8000U) ++ #define PHY_BCR_LOOPBACK_ ((u16)0x4000U) ++ #define PHY_BCR_SPEED_SELECT_ ((u16)0x2000U) ++ #define PHY_BCR_AUTO_NEG_ENABLE_ ((u16)0x1000U) ++ #define PHY_BCR_POWER_DOWN ((u16)0x0800U) ++ #define PHY_BCR_ISOLATE ((u16)0x0400U) ++ #define PHY_BCR_RESTART_AUTO_NEG_ ((u16)0x0200U) ++ #define PHY_BCR_DUPLEX_MODE_ ((u16)0x0100U) ++ ++#define PHY_BSR ((u32)1U) ++ #define PHY_BSR_AUTO_NEG_COMP_ ((u16)0x0020U) ++ #define PHY_BSR_REMOTE_FAULT_ ((u16)0x0010U) ++ #define PHY_BSR_LINK_STATUS_ ((u16)0x0004U) ++ ++#define PHY_ID_1 ((u32)2U) ++#define PHY_ID_2 ((u32)3U) ++ ++#define PHY_ANEG_ADV ((u32)4U) ++ #define PHY_ANEG_NEXT_PAGE ((u16)0x8000) ++ #define PHY_ANEG_ADV_PAUSE_ ((u16)0x0C00) ++ #define PHY_ANEG_ADV_ASYMP_ ((u16)0x0800) ++ #define PHY_ANEG_ADV_SYMP_ ((u16)0x0400) ++ #define PHY_ANEG_ADV_SPEED_ ((u16)0x1E0) ++ #define PHY_ANEG_ADV_100F_ ((u16)0x100) ++ #define PHY_ANEG_ADV_100H_ ((u16)0x80) ++ #define PHY_ANEG_ADV_10F_ ((u16)0x40) ++ #define PHY_ANEG_ADV_10H_ ((u16)0x20) ++ ++#define PHY_ANEG_LPA ((u32)5U) ++#define PHY_ANEG_LPA_ASYMP_ ((u16)0x0800) ++#define PHY_ANEG_LPA_SYMP_ ((u16)0x0400) ++#define PHY_ANEG_LPA_T4_ ((u16)0x0200) ++#define PHY_ANEG_LPA_100FDX_ ((u16)0x0100) ++#define PHY_ANEG_LPA_100HDX_ ((u16)0x0080) ++#define PHY_ANEG_LPA_10FDX_ ((u16)0x0040) ++#define PHY_ANEG_LPA_10HDX_ ((u16)0x0020) ++ ++#define PHY_ANEG_REG ((u32)6U) ++ #define PHY_LP_AN_ABLE ((u16)0x0001) ++ ++#define PHY_SILICON_REV ((u32)16U) ++ #define PHY_SILICON_REV_TX_NLP_EN_ BIT_15 ++ #define PHY_SILICON_REV_TX_NLP_I_MSK_ (BIT_14 | BIT13) ++ #define PHY_SILICON_REV_TX_NLP_I_256_ (BIT_14 | BIT13) ++ #define PHY_SILICON_REV_TX_NLP_I_512_ BIT_14 ++ #define PHY_SILICON_REV_TX_NLP_I_768_ BIT_13 ++ #define PHY_SILICON_REV_TX_NLP_I_1S_ 0 ++ #define PHY_SILICON_REV_RX_1_NLP_ BIT_12 ++ #define PHY_SILICON_REV_EEE_ENABLE BIT_2 ++ #define PHY_SILICON_REV_EDPD_XTD_XOVR BIT_1 ++ #define PHY_SILICON_REV_AMDIX_XTD_ BIT_0 ++ #define EDPD_CFG_DEFAULT (PHY_SILICON_REV_TX_NLP_EN_ | \ ++ PHY_SILICON_REV_TX_NLP_I_768_ | PHY_SILICON_REV_RX_1_NLP_) ++ ++#define PHY_MODE_CTRL_STS ((u32)17) ++ #define MODE_CTRL_STS_FASTRIP_ ((u16)0x4000U) ++ #define MODE_CTRL_STS_EDPWRDOWN_ ((u16)0x2000U) ++ #define MODE_CTRL_STS_LOWSQEN_ ((u16)0x0800U) ++ #define MODE_CTRL_STS_MDPREBP_ ((u16)0x0400U) ++ #define MODE_CTRL_STS_FARLOOPBACK_ ((u16)0x0200U) ++ #define MODE_CTRL_STS_FASTEST_ ((u16)0x0100U) ++ #define MODE_CTRL_STS_REFCLKEN_ ((u16)0x0010U) ++ #define MODE_CTRL_STS_PHYADBP_ ((u16)0x0008U) ++ #define MODE_CTRL_STS_FORCE_G_LINK_ ((u16)0x0004U) ++ #define MODE_CTRL_STS_ENERGYON_ ((u16)0x0002U) ++ ++#define PHY_SPECIAL_MODES ((u32)18) ++ ++#define PHY_TSTCNTL ((u32)20) ++ #define PHY_TSTCNTL_READ ((u16)0x8000U) ++ #define PHY_TSTCNTL_WRITE ((u16)0x4000U) ++ #define PHY_TSTCNTL_TEST_MODE ((u16)0x0400U) ++ #define PHY_TSTCNTL_READ_MASK ((u16)0x02E0U) ++ #define PHY_TSTCNTL_WRITE_MASK ((u16)0x001FU) ++ ++#define PHY_TSTREAD1 ((u32)21) // Testability data Read for LSB ++#define PHY_TSTREAD2 ((u32)22) // Testability data Read for MSB ++#define PHY_TSTWRITE ((u32)23) // Testability/Configuration data Write ++ ++#define PHY_SPECIAL_CTRL_STS ((u32)27) ++ #define SPECIAL_CTRL_STS_OVRRD_AMDIX_ ((u16)0x8000U) ++ #define SPECIAL_CTRL_STS_AMDIX_ENABLE_ ((u16)0x4000U) ++ #define SPECIAL_CTRL_STS_AMDIX_STATE_ ((u16)0x2000U) ++ ++#define PHY_SITC ((u32)28) ++ ++#define PHY_INT_SRC ((u32)29) ++ #define PHY_INT_SRC_ENERGY_ON_ ((u16)0x0080U) ++ #define PHY_INT_SRC_ANEG_COMP_ ((u16)0x0040U) ++ #define PHY_INT_SRC_REMOTE_FAULT_ ((u16)0x0020U) ++ #define PHY_INT_SRC_LINK_DOWN_ ((u16)0x0010U) ++ ++#define PHY_INT_MASK ((u32)30) ++ #define PHY_INT_MASK_ALL ((u16)0x00FFU) ++ #define PHY_INT_MASK_ENERGY_ON_ ((u16)0x0080U) ++ #define PHY_INT_MASK_ANEG_COMP_ ((u16)0x0040U) ++ #define PHY_INT_MASK_REMOTE_FAULT_ ((u16)0x0020U) ++ #define PHY_INT_MASK_LINK_DOWN_ ((u16)0x0010U) ++ ++#define PHY_SPECIAL ((u32)31) ++ #define PHY_SPECIAL_SPD_ ((u16)0x001CU) ++ #define PHY_SPECIAL_SPD_10HALF_ ((u16)0x0004U) ++ #define PHY_SPECIAL_SPD_10FULL_ ((u16)0x0014U) ++ #define PHY_SPECIAL_SPD_100HALF_ ((u16)0x0008U) ++ #define PHY_SPECIAL_SPD_100FULL_ ((u16)0x0018U) ++ ++#define AMDIX_DISABLE_STRAIGHT ((u16)0x0U) ++#define AMDIX_DISABLE_CROSSOVER ((u16)0x01U) ++#define AMDIX_ENABLE ((u16)0x02U) ++ ++#define PHY_LAN83C180_INT_ACK_REG 0x15 ++#define PHY_LAN83C180_OPTIONS 0x18 ++ ++#define PHY_LAN83C183_STATUS_OUTPUT 0x12 ++#define PHY_LAN83C183_INT_MASK 0x13 ++#define PHY_LAN83C183_MASK_BASE 0xFFC0 ++#define PHY_LAN83C183_MASK_INT ~0x8000 ++#define PHY_LAN83C183_MASK_LINK ~0x4000 ++ ++#define PHY_FOX_INT_SOURCE 0x1D ++#define PHY_FOX_INT_ENERGY_ON BIT_7 ++#define PHY_FOX_INT_NWAY_DONE BIT_6 ++#define PHY_FOX_INT_REMOTE_FAULT BIT_5 ++#define PHY_FOX_INT_LINK_DOWN BIT_4 ++#define PHY_FOX_INT_NWAY_LP_ACK BIT_3 ++#define PHY_FOX_INT_PARALLEL_DET BIT_2 ++#define PHY_FOX_INT_NWAY_PAGE_RX BIT_1 ++#define PHY_FOX_INT_RESERVED BIT_0 ++ ++#define PHY_FOX_INT_MASK 0x1E ++ ++#define PHY_QSI_INT_SOURCE_REG 0x1D ++#define PHY_QSI_AN_COMPLETE_INT BIT_6 ++#define PHY_QSI_REM_FAULT_INT BIT_5 ++#define PHY_QSI_LINK_DOWN_INT BIT_4 ++#define PHY_QSI_AN_LP_ACK_INT BIT_3 ++#define PHY_QSI_PAR_DET_INT BIT_2 ++#define PHY_QSI_AN_PAGE_RCVD_INT BIT_1 ++#define PHY_QSI_RCV_ERR_CNT_INT BIT_0 ++#define PHY_QSI_INT_MASK_REG 0x1E ++#define PHY_QSI_INT_MODE BIT_15 ++ ++/* Bit Mask definitions */ ++#define BIT_NONE 0x00000000 ++#define BIT_0 0x0001 ++#define BIT_1 0x0002 ++#define BIT_2 0x0004 ++#define BIT_3 0x0008 ++#define BIT_4 0x0010 ++#define BIT_5 0x0020 ++#define BIT_6 0x0040 ++#define BIT_7 0x0080 ++#define BIT_8 0x0100 ++#define BIT_9 0x0200 ++#define BIT_10 0x0400 ++#define BIT_11 0x0800 ++#define BIT_12 0x1000 ++#define BIT_13 0x2000 ++#define BIT_14 0x4000 ++#define BIT_15 0x8000 ++#define BIT_16 0x10000 ++#define BIT_17 0x20000 ++#define BIT_18 0x40000 ++#define BIT_19 0x80000 ++#define BIT_20 0x100000 ++#define BIT_21 0x200000 ++#define BIT_22 0x400000 ++#define BIT_23 0x800000 ++#define BIT_24 0x1000000 ++#define BIT_25 0x2000000 ++#define BIT_26 0x4000000 ++#define BIT_27 0x8000000 ++#define BIT_28 0x10000000 ++#define BIT_29 0x20000000 ++#define BIT_30 0x40000000 ++#define BIT_31 0x80000000 ++ ++/* Vendor Requests */ ++#define USB_VENDOR_REQUEST_WRITE_REGISTER 0xA0 ++#define USB_VENDOR_REQUEST_READ_REGISTER 0xA1 ++#define USB_VENDOR_REQUEST_GET_STATS 0xA2 ++ ++#define MDIO_DISABLE_INTERNAL_ACCESS BIT_0 ++#define MDIO_DISABLE_IOCTL_ACCESS BIT_1 ++#define MDIO_DEFAULT_LINK_INIT_MASK BIT_0 ++ ++#define rx_stat_count 8 ++#define tx_stat_count 10 ++ ++/* Stats block structures */ ++typedef struct _SMSC9500_RX_STATS { ++ u32 RxGoodFrames; ++ u32 RxCrcErrors; ++ u32 RxRuntFrameErrors; ++ u32 RxAlignmentErrors; ++ u32 RxFrameTooLongError; ++ u32 RxLaterCollisionError; ++ u32 RxBadFrames; ++ u32 RxFifoDroppedFrames; ++ u32 EeeRxLpiTransitions; ++ u32 EeeRxLpiTime; ++} SMSC9500_RX_STATS, *pSMSC9500_RX_STATS; ++ ++typedef struct _SMSC9500_TX_STATS { ++ u32 TxGoodFrames; ++ u32 TxPauseFrames; ++ u32 TxSingleCollisions; ++ u32 TxMultipleCollisions; ++ u32 TxExcessiveCollisionErrors; ++ u32 TxLateCollisionErrors; ++ u32 TxBufferUnderrunErrors; ++ u32 TxExcessiveDeferralErrors; ++ u32 TxCarrierErrors; ++ u32 TxBadFrames; ++ u32 EeeTxLpiTransitions; ++ u32 EeeTxLpiTime; ++} SMSC9500_TX_STATS, *pSMSC9500_TX_STATS; ++ ++/* Interrupt Endpoint status word bitfields */ ++#define INT_ENP_RFHF_ (0x00040000UL) ++#define INT_ENP_TX_STOP_ ETH_INT_STS_TX_STOP_ ++#define INT_ENP_RX_STOP_ ETH_INT_STS_RX_STOP_ ++#define INT_ENP_PHY_INT_ ETH_INT_STS_PHY_INT_ ++#define INT_ENP_TXE_ ETH_INT_STS_TXE_ ++#define INT_ENP_TDFU_ ETH_INT_STS_TDFU_ ++#define INT_ENP_TDFO_ ETH_INT_STS_TDFO_ ++#define INT_ENP_RXDF_ ETH_INT_STS_RXDF_ ++#define INT_ENP_GPIOS_ ETH_INT_STS_GPIOS_ ++ ++struct USB_CONTEXT{ ++ struct usb_ctrlrequest req; ++ struct completion notify; ++}; ++ ++enum{ ++ ASYNC_RW_SUCCESS, ++ ASYNC_RW_FAIL, ++ ASYNC_RW_TIMEOUT, ++}; ++ ++#define USE_DEBUG ++#ifdef USE_DEBUG ++#define USE_WARNING ++#define USE_TRACE ++#define USE_ASSERT ++#endif //USE_DEBUG ++ ++#define HIBYTE(word) ((BYTE)(((u16)(word))>>8)) ++#define LOBYTE(word) ((BYTE)(((u16)(word))&0x00FFU)) ++#define HIWORD(dWord) ((u16)(((u32)(dWord))>>16)) ++#define LOWORD(dWord) ((u16)(((u32)(dWord))&0x0000FFFFUL)) ++ ++/******************************************************* ++* Macro: SMSC_TRACE ++* Description: ++* This macro is used like printf. ++* It can be used anywhere you want to display information ++* For any release version it should not be left in ++* performance sensitive Tx and Rx code paths. ++* To use this macro define USE_TRACE and set bit 0 of debug_mode ++*******************************************************/ ++#ifdef USING_LINT ++extern void SMSC_TRACE(unsigned long dbgBit, const char * a, ...); ++#else //not USING_LINT ++#ifdef USE_TRACE ++extern u32 debug_mode; ++#ifndef USE_WARNING ++#define USE_WARNING ++#endif ++# define SMSC_TRACE(dbgBit,msg,args...) \ ++ if(debug_mode&dbgBit) { \ ++ printk("SMSC_9500: " msg "\n", ## args); \ ++ } ++#else ++# define SMSC_TRACE(dbgBit,msg,args...) ++#endif ++#endif //end of not USING_LINT ++ ++/* ++* Macro: SMSC_WARNING ++* Description: ++* This macro is used like printf. ++* It can be used anywhere you want to display warning information ++* For any release version it should not be left in ++* performance sensitive Tx and Rx code paths. ++* To use this macro define USE_TRACE or ++* USE_WARNING and set bit 1 of debug_mode ++*/ ++#ifdef USING_LINT ++extern void SMSC_WARNING(const char * a, ...); ++#else //not USING_LINT ++#ifdef USE_WARNING ++extern u32 debug_mode; ++#ifndef USE_ASSERT ++#define USE_ASSERT ++#endif ++# define SMSC_WARNING(msg, args...) \ ++ if(debug_mode&DBG_WARNING) { \ ++ printk("SMSC_9500_WARNING: ");\ ++ printk(__FUNCTION__);\ ++ printk(": " msg "\n",## args);\ ++ } ++#else ++#define SMSC_WARNING(msg, args...) ++#endif ++#endif //end of not USING_LINT ++ ++/* ++* Macro: SMSC_ASSERT ++* Description: ++* This macro is used to test assumptions made when coding. ++* It can be used anywhere, but is intended only for situations ++* where a failure is fatal. ++* If code execution where allowed to continue it is assumed that ++* only further unrecoverable errors would occur and so this macro ++* includes an infinite loop to prevent further corruption. ++* Assertions are only intended for use during developement to ++* insure consistency of logic through out the driver. ++* A driver should not be released if assertion failures are ++* still occuring. ++* To use this macro define USE_TRACE or USE_WARNING or ++* USE_ASSERT ++*/ ++#ifdef USING_LINT ++extern void SMSC_ASSERT(BOOLEAN condition); ++#else //not USING_LINT ++#ifdef USE_ASSERT ++ #define SMSC_ASSERT(condition) \ ++ if(!(condition)) { \ ++ printk("SMSC_9500_ASSERTION_FAILURE: \n"); \ ++ printk(" Condition = " #condition "\n"); \ ++ printk(" Function = ");printk(__FUNCTION__);printk("\n"); \ ++ printk(" File = " __FILE__ "\n"); \ ++ printk(" Line = %d\n",__LINE__); \ ++ while(1); \ ++ } ++#else ++#define SMSC_ASSERT(condition) ++#endif ++#endif //end of not USING_LINT ++ ++#define LINK_INIT (0xFFFF) ++#define LINK_OFF (0x00UL) ++#define LINK_SPEED_10HD (0x01UL) ++#define LINK_SPEED_10FD (0x02UL) ++#define LINK_SPEED_100HD (0x04UL) ++#define LINK_SPEED_100FD (0x08UL) ++#define LINK_SYMMETRIC_PAUSE (0x10UL) ++#define LINK_ASYMMETRIC_PAUSE (0x20UL) ++#define LINK_AUTO_NEGOTIATE (0x40UL) ++ ++#define INT_END_MACRTO_INT_ (0x00080000UL) ++#define INT_END_RXFIFO_HAS_FRAME_ (0x00040000UL) ++#define INT_END_TXSTOP_INT_ (0x00020000UL) ++#define INT_END_RXSTOP_INT_ (0x00010000UL) ++#define INT_END_PHY_INT_ (0x00008000UL) ++#define INT_END_TXE_ (0x00004000UL) ++#define INT_END_TDFU_ (0x00002000UL) ++#define INT_END_TDFO_ (0x00001000UL) ++#define INT_END_RXDF_INT_ (0x00000800UL) ++#define INT_END_GPIO_INT_ (0x000007FFUL) ++ ++#define DBG_TRACE (0x01UL) ++#define DBG_WARNING (0x02UL) ++#define DBG_INIT (0x80000000UL) ++#define DBG_CLOSE (0x40000000UL) ++#define DBG_INTR (0x20000000UL) ++#define DBG_PWR (0x10000000UL) ++#define DBG_IOCTL (0x08000000UL) ++#define DBG_LINK (0x04000000UL) ++#define DBG_RX (0x02000000UL) ++#define DBG_TX (0x01000000UL) ++#define DBG_MCAST (0x00800000UL) ++#define DBG_HOST (0x00400000UL) ++#define DBG_LINK_CHANGE (0x00200000UL) ++ ++#define DEFAULT_BULK_IN_DELAY (0x00002000UL) ++#define ETH_HEADER_SIZE 14 ++#define ETH_MAX_DATA_SIZE 1500 ++#define ETH_MAX_PACKET_SIZE (ETH_MAX_DATA_SIZE + ETH_HEADER_SIZE) ++#define LAN9500_EEPROM_MAGIC 0x9500UL ++#define EEPROM_MAC_OFFSET 0x01 ++ ++struct smsc9500_int_data { ++ u32 IntEndPoint; ++} __attribute__ ((packed)); ++ ++#define MAX_WUFF_NUM 8 ++#define LAN9500_WUFF_NUM 4 ++#define LAN9500A_WUFF_NUM 8 ++ ++typedef struct _WAKEUP_FILTER { ++ u32 dwFilterMask[MAX_WUFF_NUM*4]; ++ u32 dwCommad[MAX_WUFF_NUM/4]; ++ u32 dwOffset[MAX_WUFF_NUM/4]; ++ u32 dwCRC[MAX_WUFF_NUM/2]; ++} WAKEUP_FILTER, *PWAKEUP_FILTER; ++ ++static struct { ++ const char str[ETH_GSTRING_LEN]; ++} ethtool_stats_keys[] = { ++ { "rx_packets"}, ++ { "tx_packets"}, ++ { "rx_bytes"}, ++ { "tx_bytes"}, ++ { "rx_errors"}, ++ { "tx_errors"}, ++ { "tx_dropped"}, ++ { "rx_no_buffer_count"}, ++ { "rx_length_errors"}, ++ { "rx_over_errors"}, ++ { "rx_crc_errors"}, ++ { "rx_frame_errors"}, ++ { "RxGoodFrames"}, ++ { "RxCrcErrors"}, ++ { "RxRuntFrameErrors"}, ++ { "RxAlignmentErrors"}, ++ { "RxFrameTooLongError"}, ++ { "RxLaterCollisionError"}, ++ { "RxBadFrames"}, ++ { "RxFifoDroppedFrames"}, ++ { "TxGoodFrames"}, ++ { "TxPauseFrames"}, ++ { "TxSingleCollisions"}, ++ { "TxMultipleCollisions"}, ++ { "TxExcessiveCollisionErrors"}, ++ { "TxLateCollisionErrors"}, ++ { "TxBufferUnderrunErrors"}, ++ { "TxExcessiveDeferralErrors"}, ++ { "TxCarrierErrors"}, ++ { "TxBadFrames"}, ++}; ++ ++typedef struct _ADAPTER_DATA { ++ u32 dwIdRev; ++ u32 dwPhyAddress; ++ u32 dwPhyId; ++ u32 dwFpgaRev; ++ u32 macAddrHi16; //Mac address high 16 bits ++ u32 MmacAddrLo32; //Mac address Low 32 bits ++ BOOLEAN internalPhy; ++ ++ BOOLEAN UseTxCsum; ++ BOOLEAN UseRxCsum; ++ ++ BOOLEAN LanInitialized; ++ BYTE bPhyModel; ++ BYTE bPhyRev; ++ u32 dwLinkSpeed; ++ u32 dwLinkSettings; ++ u32 dwSavedLinkSettings; ++ u32 DefaultLinkStatus; ++ struct semaphore phy_mutex; // Mutex for PHY access ++ struct semaphore eeprom_mutex; //Mutex for eeprom access ++ struct semaphore internal_ram_mutex; //Mutex for internal ram operation ++ struct semaphore RxFilterLock; ++ ++ u16 wLastADV; ++ u16 wLastADVatRestart; ++ ++ spinlock_t TxQueueLock; ++ BOOLEAN TxInitialized; ++ u32 dwTxQueueDisableMask; ++ BOOLEAN TxQueueDisabled; ++ ++ u32 WolWakeupOpts; ++ u32 wakeupOptsBackup; ++ u32 dwWUFF[20]; ++ ++ /* for Rx Multicast work around */ ++ volatile u32 HashLo; ++ volatile u32 HashHi; ++ volatile BOOLEAN MulticastUpdatePending; ++ volatile u32 set_bits_mask; ++ volatile u32 clear_bits_mask; ++ ++ u32 LinkLedOnGpio; //Gpio port number for link led ++ u32 LinkLedOnGpioPolarity; //Gpio Output polarity ++ u32 LinkActLedCfg; ++ u32 LinkLedOnGpioBufType; ++ ++ u32 dynamicSuspendPHYEvent; //Store PHY interrupt source for dynamic suspend ++ u32 systemSuspendPHYEvent; //Store PHY interrupt source for system suspend ++ ++ u16 eepromSize; ++ BOOLEAN eepromContentValid; ++ ++ /* Count of transmit errors & other stats */ ++ u64 TxGoodFrames; ++ u32 TxPauseFrames; ++ u32 TxSingleCollisions; ++ u32 TxMultipleCollisions; ++ u32 TxExcessiveCollisionErrors; ++ u32 TxLateCollisionErrors; ++ u32 TxBufferUnderrunErrors; ++ u32 TxExcessiveDeferralErrors; ++ u32 TxCarrierErrors; ++ u32 TxBadFrames; ++ u32 EeeTxLpiTransitions; ++ u32 EeeTxLpiTime; ++ ++ /* Count of receive errors */ ++ u64 RxGoodFrames; ++ u32 RxCrcErrors; ++ u32 RxRuntFrameErrors; ++ u32 RxAlignmentErrors; ++ u32 RxFrameTooLongError; ++ u32 RxLaterCollisionError; ++ u32 RxBadFrames; ++ u32 RxFifoDroppedFrames; ++ u32 EeeRxLpiTransitions; ++ u32 EeeRxLpiTime; ++ ++ SMSC9500_RX_STATS rx_statistics; ++ SMSC9500_TX_STATS tx_statistics; ++ ++} ADAPTER_DATA, *PADAPTER_DATA; ++ ++typedef struct _MAC_ADDR_IN_RAM { ++ u32 signature; ++ u32 MacAddrL; ++ u32 MacAddrH; ++ u16 crc; ++ u16 crcComplement; ++} MAC_ADDR_IN_RAM; ++ ++enum { ++ RAMSEL_FCT, ++ RAMSEL_EEPROM, ++ RAMSEL_TXTLI, ++ RAMSEL_RXTLI ++}; ++ ++#ifndef min ++#define min(_a, _b) (((_a) < (_b)) ? (_a) : (_b)) ++#endif ++ ++#ifndef max ++#define max(_a, _b) (((_a) > (_b)) ? (_a) : (_b)) ++#endif ++ ++#define BCAST_LEN 6 ++#define MCAST_LEN 3 ++#define ARP_LEN 2 ++ ++#endif /* _LAN9500_H */ ++ ++ ++ +diff --git a/drivers/net/ethernet/smsc9514/smscusbnet.c b/drivers/net/ethernet/smsc9514/smscusbnet.c +new file mode 100755 +index 0000000..ede03de +--- /dev/null ++++ b/drivers/net/ethernet/smsc9514/smscusbnet.c +@@ -0,0 +1,2157 @@ ++/* ++ * USB Network driver infrastructure ++ * Copyright (C) 2000-2005 by David Brownell ++ * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++/* ++ * This is a generic "USB networking" framework that works with several ++ * kinds of full and high speed networking devices: host-to-host cables, ++ * smart usb peripherals, and actual Ethernet adapters. ++ * ++ * These devices usually differ in terms of control protocols (if they ++ * even have one!) and sometimes they define new framing to wrap or batch ++ * Ethernet packets. Otherwise, they talk to USB pretty much the same, ++ * so interface (un)binding, endpoint I/O queues, fault handling, and other ++ * issues can usefully be addressed by this framework. ++ */ ++ ++#include <linux/version.h> ++#include <linux/module.h> ++#include <linux/moduleparam.h> ++#include <linux/module.h> ++#include <linux/sched.h> ++#include <linux/init.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/ethtool.h> ++#include <linux/workqueue.h> ++#include <linux/mii.h> ++#include <linux/usb.h> ++#include <linux/if_vlan.h> ++#include "smscusbnet.h" ++#include "version.h" ++ ++/* ++ * Nineteen USB 1.1 max size bulk transactions per frame (ms), max. ++ * Several dozen bytes of IPv4 data can fit in two such transactions. ++ * One maximum size Ethernet packet takes twenty four of them. ++ * For high speed, each frame comfortably fits almost 36 max size ++ * Ethernet packets (so queues should be bigger). ++ * ++ * REVISIT qlens should be members of 'struct usbnet'; the goal is to ++ * let the USB host controller be busy for 5msec or more before an irq ++ * is required, under load. Jumbograms change the equation. ++ */ ++#define RX_QLEN(dev) ((dev)->rx_qlen) ++#define TX_QLEN(dev) ((dev)->tx_qlen) ++ ++// reawaken network queue this soon after stopping; else watchdog barks ++#define TX_TIMEOUT_JIFFIES (5*HZ) ++ ++#define Link_Check_Delay (1*HZ) ++ ++// throttle rx/tx briefly after some faults, so khubd might disconnect() ++// us (it polls at HZ/4 usually) before we report too many false errors. ++#define THROTTLE_JIFFIES (HZ/8) ++ ++// between wakeups ++#define UNLINK_TIMEOUT_MS 3 ++ ++// randomly generated ethernet address ++static u8 node_id [ETH_ALEN]; ++ ++static const char driver_name [] = "smscusbnet"; ++ ++/* use ethtool to change the level for any given device */ ++static int msg_level = -1; ++module_param (msg_level, int, 0); ++MODULE_PARM_DESC (msg_level, "Override default message level"); ++ ++/* ++operational_mode = 0 (low latency) ++operational_mode = 1 (low power) ++*/ ++static int operational_mode = 0; ++module_param(operational_mode,int, 0); ++MODULE_PARM_DESC(operational_mode,"Enable operational mode"); ++ ++bool TurboMode = TRUE; ++module_param(TurboMode,bool, 0); ++MODULE_PARM_DESC(TurboMode,"Enable Turbo Mode"); ++ ++static unsigned long rx_queue_size = 6UL; ++module_param(rx_queue_size, ulong, 0); ++MODULE_PARM_DESC(rx_queue_size,"Specifies the size of the rx queue lenght"); ++ ++static unsigned long tx_queue_size = 6UL; ++module_param(tx_queue_size, ulong, 0); ++MODULE_PARM_DESC(tx_queue_size,"Specifies the size of the tx queue lenght"); ++ ++int tx_hold_on_completion = TRUE; ++module_param(tx_hold_on_completion, int, 0); ++MODULE_PARM_DESC(tx_hold_on_completion,"Hold tx until USB completion, must be true when tx_use_prealloc_buffers is true"); ++ ++int tx_use_prealloc_buffers = TRUE; ++module_param(tx_use_prealloc_buffers, int, 0); ++MODULE_PARM_DESC(tx_use_prealloc_buffers,"Uses pre allocated buffers for usb tx (tx_hold_on_completion must me true)"); ++ ++int rx_use_prealloc_buffers = TRUE; ++module_param(rx_use_prealloc_buffers, int, 0); ++MODULE_PARM_DESC(rx_use_prealloc_buffers,"Uses pre allocated buffers for usb rx. rx_skb_copy must be set to 1"); ++ ++int rx_urb_buf_alignment = 0; ++module_param(rx_urb_buf_alignment, int, 0); ++MODULE_PARM_DESC(rx_urb_buf_alignment,"rx urb buffer alignment in bytes. 0 - default alignment from skb_alloc"); ++ ++int tx_urb_buf_alignment = 0; ++module_param(tx_urb_buf_alignment, int, 0); ++MODULE_PARM_DESC(tx_urb_buf_alignment,"tx urb buffer alignment in bytes. 0 - default alignment from skb_alloc"); ++ ++int rx_skb_copy = 1; ++module_param(rx_skb_copy, int, 0); ++MODULE_PARM_DESC(rx_skb_copy,"default 1 - use skb_alloc for received packets, 0 - use skb_clone, for pre allocated buffers set this to 1"); ++ ++int net_ip_align = 0; ++module_param(net_ip_align, int, 0); ++MODULE_PARM_DESC(net_ip_align,"ip alignment for Rx packets, default 0 = NET_IP_ALIGN"); ++ ++static int smscusbnet_xmit (struct sk_buff *skb, struct net_device *net); ++static int smscusbnet_bundle_skb_ximt(struct usbnet *dev, struct sk_buff_head *q); ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) ++static struct net_device_stats *smscusbnet_get_stats (struct net_device *net); ++static int smscusbnet_stop (struct net_device *net); ++static int smscusbnet_open (struct net_device *net); ++static int smscusbnet_start_xmit (struct sk_buff *skb, struct net_device *net); ++static void smscusbnet_tx_timeout (struct net_device *net); ++static int smscusbnet_change_mtu (struct net_device *net, int new_mtu); ++#endif ++static void intr_complete (struct urb *urb); ++static void rx_complete (struct urb *urb); ++ ++static int smscusbnet_alloc_rx_pool(struct usbnet *dev, int size) ++{ ++ struct sk_buff *skb; ++ int i; ++ ++ for (i = 0; i < dev->rx_qlen; i++) { ++ skb = alloc_skb(size + dev->rx_urb_buf_alignment, GFP_ATOMIC); ++ if (!skb) ++ return 1; ++ if (dev->rx_urb_buf_alignment) { ++ skb->data = (unsigned char *)(((ulong)skb->head + dev->rx_urb_buf_alignment - 1) & ++ ~(dev->rx_urb_buf_alignment - 1)); ++ skb_reset_tail_pointer(skb); ++ } ++ __skb_queue_tail(&dev->rx_pool_queue, skb); ++ } ++ return 0; ++} ++ ++static inline void smscusbnet_free_rx_pool(struct usbnet *dev) ++{ ++ if (!skb_queue_empty(&dev->rx_pool_queue)) ++ skb_queue_purge(&dev->rx_pool_queue); ++} ++ ++static inline struct sk_buff *smscusbnet_get_rx_buffer(struct usbnet *dev) ++{ ++ if (!skb_queue_empty(&dev->rx_pool_queue)) ++ return(skb_dequeue(&dev->rx_pool_queue)); ++ else ++ return NULL; ++} ++ ++static inline void smscusbnet_return_rx_buffer(struct usbnet *dev, struct sk_buff *skb) ++{ ++ unsigned long lockflags; ++ ++ if (dev->rx_urb_buf_alignment) { ++ skb->data = (unsigned char *)(((ulong)skb->head + dev->rx_urb_buf_alignment - 1) & ++ ~(dev->rx_urb_buf_alignment - 1)); ++ } else { ++ skb->data = skb->head; ++ } ++ skb_reset_tail_pointer(skb); ++ skb->len = 0; ++ skb->data_len = 0; ++ spin_lock_irqsave(&dev->rx_pool_queue.lock, lockflags); ++ __skb_queue_tail(&dev->rx_pool_queue, skb); ++ spin_unlock_irqrestore(&dev->rx_pool_queue.lock, lockflags); ++} ++ ++static int smscusbnet_alloc_tx_pool(struct usbnet *dev, int size) ++{ ++ struct sk_buff *skb; ++ int i; ++ ++ for (i = 0; i < dev->tx_qlen; i++) { ++ skb = alloc_skb(size, GFP_ATOMIC); ++ if (!skb) ++ return 1; ++ if (dev->tx_urb_buf_alignment) { ++ skb->data = (unsigned char *)(((ulong)skb->head + dev->tx_urb_buf_alignment - 1) & ++ ~(dev->tx_urb_buf_alignment - 1)); ++ skb_reset_tail_pointer(skb); ++ } ++ __skb_queue_tail(&dev->tx_pool_queue, skb); ++ } ++ return 0; ++} ++ ++static inline void smscusbnet_free_tx_pool(struct usbnet *dev) ++{ ++ if (!skb_queue_empty(&dev->tx_pool_queue)) ++ skb_queue_purge(&dev->tx_pool_queue); ++} ++ ++static inline struct sk_buff *smscusbnet_get_tx_buffer(struct usbnet *dev) ++{ ++ if (!skb_queue_empty(&dev->tx_pool_queue)) ++ return(skb_dequeue(&dev->tx_pool_queue)); ++ else ++ return NULL; ++} ++ ++static inline void smscusbnet_return_tx_buffer(struct usbnet *dev, struct sk_buff *skb) ++{ ++ unsigned long lockflags; ++ ++ if (dev->tx_urb_buf_alignment) { ++ skb->data = (unsigned char *)(((ulong)skb->head + dev->tx_urb_buf_alignment - 1) & ++ ~(dev->tx_urb_buf_alignment - 1)); ++ skb_reset_tail_pointer(skb); ++ } else { ++ skb->data = skb->head; ++ } ++ skb_reset_tail_pointer(skb); ++ skb->len = 0; ++ skb->data_len = 0; ++ spin_lock_irqsave(&dev->tx_pool_queue.lock, lockflags); ++ __skb_queue_tail(&dev->tx_pool_queue, skb); ++ spin_unlock_irqrestore(&dev->tx_pool_queue.lock, lockflags); ++} ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) ++static const struct net_device_ops smscusbnet_netdev_ops = ++{ ++ .ndo_open = smscusbnet_open, ++ .ndo_stop = smscusbnet_stop, ++ .ndo_start_xmit = smscusbnet_start_xmit, ++ .ndo_tx_timeout = smscusbnet_tx_timeout, ++ .ndo_change_mtu = smscusbnet_change_mtu, ++ .ndo_get_stats = smscusbnet_get_stats, ++ .ndo_validate_addr = eth_validate_addr, ++}; ++#endif ++ ++int smscusbnet_IsOperationalMode(struct usbnet *dev) ++{ ++ return operational_mode; ++} ++ ++/* handles CDC Ethernet and many other network "bulk data" interfaces */ ++int smscusbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf) ++{ ++ int tmp; ++ struct usb_host_interface *alt = NULL; ++ struct usb_host_endpoint *in = NULL, *out = NULL; ++ struct usb_host_endpoint *status = NULL; ++ ++ for (tmp = 0; tmp < intf->num_altsetting; tmp++) { ++ unsigned ep; ++ ++ in = out = status = NULL; ++ alt = intf->altsetting + tmp; ++ ++ /* take the first altsetting with in-bulk + out-bulk; ++ * remember any status endpoint, just in case; ++ * ignore other endpoints and altsetttings. ++ */ ++ for (ep = 0; ep < alt->desc.bNumEndpoints; ep++) { ++ struct usb_host_endpoint *e; ++ int intr = 0; ++ ++ e = alt->endpoint + ep; ++ switch (e->desc.bmAttributes) { ++ case USB_ENDPOINT_XFER_INT: ++ if (!(e->desc.bEndpointAddress & USB_DIR_IN)) ++ continue; ++ intr = 1; ++ /* FALLTHROUGH */ ++ case USB_ENDPOINT_XFER_BULK: ++ break; ++ default: ++ continue; ++ } ++ if (e->desc.bEndpointAddress & USB_DIR_IN) { ++ if (!intr && !in) ++ in = e; ++ else if (intr && !status) ++ status = e; ++ } else { ++ if (!out) ++ out = e; ++ } ++ } ++ if (in && out) ++ break; ++ } ++ if (!alt || !in || !out) ++ { ++ devdbg (dev, "return EINVAL = %d", EINVAL); ++ ++ return -EINVAL; ++ } ++ if (alt->desc.bAlternateSetting != 0 ++ || !(dev->driver_info->flags & FLAG_NO_SETINT)) { ++ tmp = usb_set_interface (dev->udev, alt->desc.bInterfaceNumber, ++ alt->desc.bAlternateSetting); ++ if (tmp < 0) ++ { ++ devdbg (dev, "return tmp = %d", tmp); ++ return tmp; ++ ++ } ++ } ++ ++ dev->in = usb_rcvbulkpipe (dev->udev, ++ in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); ++ dev->out = usb_sndbulkpipe (dev->udev, ++ out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); ++ dev->status = status; ++ ++ return 0; ++} ++ ++static int init_status (struct usbnet *dev, struct usb_interface *intf) ++{ ++ unsigned pipe = 0; ++ unsigned maxp; ++ unsigned period; ++ ++ if (!dev->driver_info->status) ++ return 0; ++ ++ pipe = usb_rcvintpipe (dev->udev, ++ dev->status->desc.bEndpointAddress ++ & USB_ENDPOINT_NUMBER_MASK); ++ maxp = usb_maxpacket (dev->udev, pipe, 0); ++ ++ period = dev->status->desc.bInterval; ++ dev->interrupt_urb_buffer = NULL; ++ ++ if(operational_mode){ ++ dev->interrupt_urb_buffer = kmalloc (maxp, GFP_KERNEL); ++ if (dev->interrupt_urb_buffer) { ++ dev->interrupt = usb_alloc_urb (0, GFP_KERNEL); ++ if (!dev->interrupt) { ++ devdbg (dev, "failed to alloc interrupt urb\n!!!"); ++ kfree (dev->interrupt_urb_buffer); ++ dev->interrupt_urb_buffer = NULL; ++ return -ENOMEM; ++ } else { ++ usb_fill_int_urb(dev->interrupt, dev->udev, pipe, ++ dev->interrupt_urb_buffer, maxp, intr_complete, dev, period); ++ devdbg (dev,"status ep%din, %d bytes period %d\n", ++ usb_pipeendpoint(pipe), maxp, period); ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++/* Passes this packet up the stack, updating its accounting. ++ * Some link protocols batch packets, so their rx_fixup paths ++ * can return clones as well as just modify the original skb. ++ */ ++void smscusbnet_skb_return(struct usbnet *dev, struct sk_buff *skb) ++{ ++ int status; ++ u16 vlan_tag = *((u16 *)&skb->cb[0]); ++ ++ skb->dev = dev->net; ++ skb->protocol = eth_type_trans (skb, dev->net); ++ ++ if (netif_msg_rx_status (dev)) ++ devdbg (dev, "< rx, len %zu, type 0x%x", skb->len + sizeof (struct ethhdr), skb->protocol); ++ memset (skb->cb, 0, sizeof (struct skb_data)); ++ ++ if (vlan_tag == VLAN_DUMMY) { ++ /* No vlan tag acceleration */ ++ status = netif_rx (skb); ++ } else { ++ /* Vlan tag acceleration */ ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,0,31)) ++ status = vlan_hwaccel_rx(skb, dev->vlgrp, vlan_tag); ++#else ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)) ++ __vlan_hwaccel_put_tag(skb, vlan_tag); ++#else ++ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tag); ++#endif ++ status = netif_rx(skb); ++#endif ++ } ++ ++ if (status == NET_RX_DROP) { ++ dev->stats.rx_dropped++; ++ } else { ++ dev->stats.rx_packets++; ++ dev->stats.rx_bytes += skb->len; ++ } ++ ++ if (status != NET_RX_SUCCESS && netif_msg_rx_err (dev)) ++ devdbg (dev, "netif_rx status %d", status); ++} ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) ++static ++#endif ++int smscusbnet_change_mtu (struct net_device *net, int new_mtu) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ int ll_mtu = new_mtu + net->hard_header_len; ++ ++#ifdef JUMBO_FRAME ++ if (new_mtu <= 0) ++ return -EINVAL; ++ // no second zero-length packet read wanted after mtu-sized packets ++ if ((ll_mtu % dev->maxpacket) == 0) ++ return -EDOM; ++ if(dev->driver_info->set_max_frame_size(dev, net->hard_header_len + new_mtu - EXTRA_HEADER_LEN) < 0){ ++ return -EINVAL; ++ } ++ net->mtu = new_mtu; ++ dev->hard_mtu = net->mtu + net->hard_header_len; ++#else ++ if (new_mtu <= 0 || ll_mtu > dev->hard_mtu) ++ return -EINVAL; ++ // no second zero-length packet read wanted after mtu-sized packets ++ if ((ll_mtu % dev->maxpacket) == 0) ++ return -EDOM; ++ net->mtu = new_mtu; ++#endif ++ return 0; ++} ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) ++static ++#endif ++struct net_device_stats *smscusbnet_get_stats (struct net_device *net) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ return &dev->stats; ++} ++ ++ ++/* some LK 2.4 HCDs oopsed if we freed or resubmitted urbs from ++ * completion callbacks. 2.5 should have fixed those bugs... ++ */ ++static void defer_bh(struct usbnet *dev, struct sk_buff *skb, struct sk_buff_head *list) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&list->lock, flags); ++ __skb_unlink(skb, list); ++ spin_unlock(&list->lock); ++ spin_lock(&dev->done.lock); ++ __skb_queue_tail(&dev->done, skb); ++ if (dev->done.qlen == 1) ++ tasklet_schedule(&dev->bh); ++ spin_unlock_irqrestore(&dev->done.lock, flags); ++} ++ ++/* some work can't be done in tasklets, so we use keventd ++ * ++ * NOTE: annoying asymmetry: if it's active, schedule_work() fails, ++ * but tasklet_schedule() doesn't. hope the failure is rare. ++ */ ++void smscusbnet_defer_kevent (struct usbnet *dev, int work) ++{ ++ set_bit (work, &dev->flags); ++ if (!schedule_work (&dev->kevent)){ ++ devdbg (dev, "kevent %d may have been dropped", work); ++ } ++ //else ++ //devdbg (dev, "kevent %d scheduled", work); ++} ++ ++/* some work can't be done in tasklets, so we use keventd ++ * ++ * We use myevent to schedule Rx Bulk in ++ * ++ */ ++void smscusbnet_defer_myevent (struct usbnet *dev, int work) ++{ ++ set_bit (work, &dev->flags); ++ if (!queue_work(dev->MyWorkQueue,&dev->myevent)){ ++ //deverr (dev, "myevent %d may have been dropped", work); ++ } ++ //else ++ //devdbg (dev,"myevent %d scheduled", work); ++} ++ ++void smscusbnet_linkpolling(unsigned long ptr) ++{ ++ struct usbnet * dev = (struct usbnet *) ptr; ++ ++ if (dev == NULL) ++ return; ++ smscusbnet_defer_myevent(dev, EVENT_LINK_RESET); ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) && defined(CONFIG_PM) ++ if (dev->dynamicSuspend) { ++ smscusbnet_defer_myevent(dev, EVENT_IDLE_CHECK); ++ } ++#endif ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) && defined(CONFIG_PM) ++ if (dev->linkDownSuspend || dev->netDetach) { ++#else ++ if (dev->netDetach) { ++#endif ++ /* Check 2 times in case of conflict with resume */ ++ if (!netif_carrier_ok(dev->net) && dev->linkcheck++ > 2) { ++ smscusbnet_defer_myevent(dev, EVENT_LINK_DOWN_DETACH); ++ dev->linkcheck = 0; ++ } ++ } ++} ++ ++static inline struct sk_buff *smscusbnet_allocate_rx_skb_buffer(struct usbnet *dev, int flags) ++{ ++ struct sk_buff *skb = NULL; ++ size_t size = dev->rx_urb_size; ++ ++ if (dev->rx_use_prealloc_buffs) { ++ skb = smscusbnet_get_rx_buffer(dev); ++ } else { ++ skb = alloc_skb(size + dev->net_ip_align + dev->rx_urb_buf_alignment, flags); ++ /* This skb will be submitted to usb host for receive, ++ align skb->data to rx_urb_buf_alignment. */ ++ if (skb && dev->rx_urb_buf_alignment) { ++ skb->data = (unsigned char *)(((ulong)skb->head + dev->rx_urb_buf_alignment - 1) & ++ ~(dev->rx_urb_buf_alignment - 1)); ++ skb_reset_tail_pointer(skb); ++ } ++ } ++ ++ return skb; ++} ++ ++static int rx_submit(struct usbnet *dev, struct urb *urb, int flags) ++{ ++ struct sk_buff *skb; ++ struct skb_data *entry; ++ int retval = 0; ++ unsigned long lockflags; ++ size_t size = dev->rx_urb_size; ++ ++ skb = smscusbnet_allocate_rx_skb_buffer(dev, flags); ++ if (!skb) { ++ if (netif_msg_rx_err (dev)) ++ devdbg (dev,"no rx skb\n"); ++ /* When using pre allocated memory, no rx skb means all ++ are submitted. rx_complete should resubmit */ ++ if (!dev->rx_use_prealloc_buffs) ++ smscusbnet_defer_kevent(dev, EVENT_RX_MEMORY); ++ usb_free_urb(urb); ++ return -ENOMEM; ++ } ++ ++ entry = (struct skb_data *) skb->cb; ++ entry->urb = urb; ++ entry->dev = dev; ++ entry->state = rx_start; ++ entry->length = 0; ++ ++ usb_fill_bulk_urb (urb, dev->udev, dev->in, ++ skb->data, size, rx_complete, skb); ++ ++ spin_lock_irqsave (&dev->rxq.lock, lockflags); ++ ++ if (netif_running (dev->net) ++ && netif_device_present (dev->net) ++ && !test_bit (EVENT_RX_HALT, &dev->flags) ++ && netif_carrier_ok(dev->net)) { ++ switch (retval = usb_submit_urb (urb, GFP_ATOMIC)) { ++ case -EPIPE: ++ smscusbnet_defer_kevent (dev, EVENT_RX_HALT); ++ break; ++ case -ENOMEM: ++ smscusbnet_defer_kevent (dev, EVENT_RX_MEMORY); ++ break; ++ case -ENODEV: ++ if (netif_msg_ifdown (dev)) ++ devdbg (dev, "device gone"); ++ netif_device_detach (dev->net); ++ break; ++ default: ++ if (netif_msg_rx_err (dev)) ++ devdbg (dev, "rx submit, %d", retval); ++ tasklet_schedule (&dev->bh); ++ break; ++ case 0: ++ __skb_queue_tail (&dev->rxq, skb); ++ } ++ } else { ++ if (netif_msg_ifdown (dev)) ++ devdbg (dev, "rx: stopped"); ++ retval = -ENOLINK; ++ } ++ spin_unlock_irqrestore (&dev->rxq.lock, lockflags); ++ if (retval) { ++ dev_kfree_skb_any (skb); ++ usb_free_urb(urb); ++ } ++ return retval; ++} ++ ++static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) ++{ ++ int ret; ++ ++ if (!dev->driver_info->rx_fixup) ++ return; ++ ++ ret = dev->driver_info->rx_fixup(dev, skb); ++ if (ret == RX_FIXUP_INVALID_SKB) { ++ skb_queue_tail(&dev->done, skb); ++ } else if (ret == RX_FIXUP_ERROR) { ++ dev->stats.rx_errors++; ++ skb_queue_tail(&dev->done, skb); ++ } else { ++ if (skb->len) { ++ smscusbnet_skb_return(dev, skb); ++ } else { ++ if (netif_msg_rx_err(dev)) ++ devdbg(dev, "drop"); ++ dev->stats.rx_errors++; ++ skb_queue_tail(&dev->done, skb); ++ } ++ } ++} ++ ++static void rx_complete (struct urb *urb) ++{ ++ struct sk_buff *skb = (struct sk_buff *) urb->context; ++ struct skb_data *entry = (struct skb_data *) skb->cb; ++ struct usbnet *dev = entry->dev; ++ int urb_status = urb->status; ++ ++ dev->idleCount = 0; ++ ++ skb_put(skb, urb->actual_length); ++ entry->state = rx_done; ++ entry->urb = NULL; ++ ++ switch (urb_status) { ++ /* success */ ++ case 0: ++ if (operational_mode) { ++ if ((skb->len < dev->net->hard_header_len) && (skb->len != 0)) { ++ entry->state = rx_cleanup; ++ dev->stats.rx_errors++; ++ dev->stats.rx_length_errors++; ++ if (netif_msg_rx_err (dev)) ++ devdbg (dev, "rx length %d", skb->len); ++ } ++ ++ if (skb->len == 0) { ++ entry->state = rx_cleanup; ++ dev->StopSummitUrb = 1; ++ } else { ++ dev->StopSummitUrb = 0; ++ } ++ } else { ++ if (skb->len < dev->net->hard_header_len) { ++ entry->state = rx_cleanup; ++ dev->stats.rx_errors++; ++ dev->stats.rx_length_errors++; ++ if (netif_msg_rx_err (dev)) ++ devdbg (dev, "rx length %d", skb->len); ++ } ++ } ++ break; ++ ++ // stalls need manual reset. this is rare ... except that ++ // when going through USB 2.0 TTs, unplug appears this way. ++ // we avoid the highspeed version of the ETIMEOUT/EILSEQ ++ // storm, recovering as needed. ++ case -EPIPE: ++ dev->extra_error_cnts.rx_epipe++; ++ dev->stats.rx_errors++; ++ devdbg (dev,"in rx_complete,case -EPIPE, dev->stats.rx_errors=0x%08lx\n", dev->stats.rx_errors); ++ smscusbnet_defer_kevent (dev, EVENT_RX_HALT); ++ // FALLTHROUGH ++ // software-driven interface shutdown ++ case -ECONNRESET: // async unlink ++ case -ESHUTDOWN: // hardware gone ++ if (netif_msg_ifdown (dev)) ++ devdbg (dev, "rx shutdown, code %d", urb_status); ++ goto block; ++ ++ // we get controller i/o faults during khubd disconnect() delays. ++ // throttle down resubmits, to avoid log floods; just temporarily, ++ // so we still recover when the fault isn't a khubd delay. ++ case -EPROTO: // ehci ++ dev->extra_error_cnts.rx_eproto++; ++ goto _HANDLE; ++ case -ETIMEDOUT: // ohci ++ case -ETIME: // ohci ++ dev->extra_error_cnts.rx_etimeout++; ++ goto _HANDLE; ++ case -EILSEQ: // uhci ++ dev->extra_error_cnts.rx_eilseq++; ++_HANDLE: ++ dev->stats.rx_errors++; ++ devdbg (dev,"in rx_complete,case -EPROTO, dev->stats.rx_errors=0x%08lx\n", dev->stats.rx_errors); ++ if (!timer_pending (&dev->delay)) { ++ mod_timer (&dev->delay, jiffies + THROTTLE_JIFFIES); ++ if (netif_msg_link (dev)) ++ devdbg (dev, "rx throttle %d", urb_status); ++ } ++ //Set recovery flag ++ set_bit (EVENT_DEV_RECOVERY, &dev->flags); ++block: ++ entry->state = rx_cleanup; ++ entry->urb = urb; ++ urb = NULL; ++ break; ++ // data overrun ... flush fifo? ++ case -EOVERFLOW: ++ dev->extra_error_cnts.rx_eoverflow++; ++ dev->stats.rx_over_errors++; ++ // FALLTHROUGH ++ /* Set recovery flag */ ++ set_bit (EVENT_DEV_RECOVERY, &dev->flags); ++ default: ++ entry->state = rx_cleanup; ++ dev->stats.rx_errors++; ++ devdbg (dev,"in rx_complete,case default dev->stats.rx_errors=0x%08lx\n", dev->stats.rx_errors); ++ if (netif_msg_rx_err (dev)) ++ devdbg (dev, "rx status %d", urb_status); ++ break; ++ } ++ ++ defer_bh(dev, skb, &dev->rxq); ++ ++ if (urb) { ++ if (operational_mode) { ++ if (netif_running (dev->net) ++ && !test_bit (EVENT_RX_HALT, &dev->flags) ++ && !dev->StopSummitUrb) { ++ rx_submit (dev, urb, GFP_ATOMIC); ++ return; ++ } ++ ++ } else { ++ ++ if (netif_running (dev->net) ++ && !test_bit (EVENT_RX_HALT, &dev->flags)) { ++ rx_submit(dev, urb, GFP_ATOMIC); ++ return; ++ } ++ } ++ usb_free_urb(urb); ++ } ++ if (netif_msg_rx_err (dev)) ++ devdbg (dev, "no read resubmitted"); ++} ++ ++static void intr_complete (struct urb *urb) ++{ ++ int status = urb->status; ++ struct usbnet *dev = urb->context; ++ ++ switch (status) { ++ /* success */ ++ case 0: ++ dev->driver_info->status(dev, urb); ++ break; ++ ++ /* software-driven interface shutdown */ ++ case -ENOENT: // urb killed ++ case -ESHUTDOWN: // hardware gone ++ if (netif_msg_ifdown (dev)) ++ devdbg (dev,"intr shutdown, code %d", status); ++ return; ++ ++ // we get controller i/o faults during khubd disconnect() delays. ++ // throttle down resubmits, to avoid log floods; just temporarily, ++ // so we still recover when the fault isn't a khubd delay. ++ /* We need throttling here like RX/TX, because flood events occur on slow ppc platform ++ * when the device is being disconnected. ++ */ ++ case -EPROTO: // ehci ++ case -ETIMEDOUT: // ohci ++ case -ETIME: // ohci ++ case -EILSEQ: // uhci ++ ++ devdbg (dev,"in intr_complete,case -EPROTO\n"); ++ if (!timer_pending (&dev->delay)) { ++ mod_timer (&dev->delay, jiffies + THROTTLE_JIFFIES); ++ if (netif_msg_link (dev)) ++ devdbg (dev, "intr throttle %d", status); ++ } ++ dev->intr_urb_delay_submit = TRUE; ++ return; ++ ++ default: ++ devdbg (dev,"intr status %d", status); ++ break; ++ } ++ ++ if (!netif_running (dev->net)){ ++ return; ++ } ++ ++ memset(urb->transfer_buffer, 0, urb->transfer_buffer_length); ++ status = usb_submit_urb (urb, GFP_ATOMIC); ++ if (status != 0 && netif_msg_timer (dev)) ++ deverr(dev, "intr resubmit --> %d", status); ++} ++ ++// unlink pending rx/tx; completion handlers do all other cleanup ++ ++static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q) ++{ ++ unsigned long flags; ++ struct sk_buff *skb, *skbnext; ++ int count = 0; ++ ++ spin_lock_irqsave (&q->lock, flags); ++ for (skb = q->next; skb != (struct sk_buff *) q; skb = skbnext) { ++ struct skb_data *entry; ++ struct urb *urb; ++ int retval; ++ ++ entry = (struct skb_data *) skb->cb; ++ urb = entry->urb; ++ skbnext = skb->next; ++ ++ /* Get reference count of the URB to avoid it to be ++ * freed during usb_unlink_urb, which may trigger ++ * use-after-free problem inside usb_unlink_urb since ++ * usb_unlink_urb is always racing with .complete ++ * handler(include defer_bh). ++ */ ++ usb_get_urb(urb); ++ spin_unlock_irqrestore (&q->lock, flags); ++ ++ // during some PM-driven resume scenarios, ++ // these (async) unlinks complete immediately ++ retval = usb_unlink_urb (urb); ++ if (retval != -EINPROGRESS && retval != 0) ++ devdbg (dev, "unlink urb err, %d", retval); ++ else ++ count++; ++ ++ usb_put_urb(urb); ++ spin_lock_irqsave (&q->lock, flags); ++ } ++ spin_unlock_irqrestore (&q->lock, flags); ++ return count; ++} ++ ++static void smscusbnet_free_rx_buffer(struct usbnet *dev, struct sk_buff *skb) ++{ ++ if (dev->rx_use_prealloc_buffs) { ++ smscusbnet_return_rx_buffer(dev, skb); ++ } else { ++ dev_kfree_skb(skb); ++ } ++} ++static void smscusbnet_free_tx_buffer(struct usbnet *dev, struct sk_buff *skb) ++{ ++ if (dev->tx_use_prealloc_buffs) { ++ smscusbnet_return_tx_buffer(dev, skb); ++ } else { ++ dev_kfree_skb(skb); ++ } ++} ++ ++/* tasklet (work deferred from completions, in_irq) or timer */ ++static void smscusbnet_bh(unsigned long param) ++{ ++ int ret = 0; ++ unsigned long flags; ++ struct sk_buff *skb = NULL; ++ struct skb_data *entry = NULL; ++ struct usbnet *dev = (struct usbnet *) param; ++ ++ if (dev == NULL) ++ return; ++ ++ while ((skb = skb_dequeue(&dev->done))) { ++ entry = (struct skb_data *) skb->cb; ++ switch (entry->state) { ++ case rx_done: ++ entry->state = rx_cleanup; ++ rx_process(dev, skb); ++ continue; ++ case tx_done: ++ usb_free_urb(entry->urb); ++ smscusbnet_free_tx_buffer(dev, skb); ++ spin_lock_irqsave(&dev->txq.lock, flags); ++ if (!dev->txq.qlen) ++ smscusbnet_bundle_skb_ximt(dev, &dev->tx_pending_q); ++ spin_unlock_irqrestore(&dev->txq.lock, flags); ++ continue; ++ case rx_cleanup: ++ if (entry->urb) ++ usb_free_urb(entry->urb); ++ smscusbnet_free_rx_buffer(dev, skb); ++ continue; ++ default: ++ devdbg (dev, "bogus skb state %d", entry->state); ++ } ++ } ++ ++ if (netif_running(dev->net) && netif_device_present(dev->net) && !timer_pending(&dev->delay)) { ++ /* submit delayed interrupt urb */ ++ if (operational_mode && dev->interrupt && dev->intr_urb_delay_submit) { ++ int status = usb_submit_urb(dev->interrupt, GFP_ATOMIC); ++ dev->intr_urb_delay_submit = FALSE; ++ if (status != 0 && netif_msg_timer (dev)) ++ deverr(dev, "intr resubmit --> %d", status); ++ } ++ } ++ ++ /* waiting for all pending urbs to complete? */ ++ if (dev->wait) { ++ if ((dev->txq.qlen + dev->rxq.qlen + dev->done.qlen) == 0) { ++ wake_up(dev->wait); ++ } ++ /* or are we maybe short a few urbs? */ ++ } else if (netif_running(dev->net) ++ && netif_device_present(dev->net) ++ && !timer_pending(&dev->delay) ++ && !test_bit(EVENT_RX_HALT, &dev->flags) ++ && netif_carrier_ok(dev->net)) { ++ ++ if (((operational_mode) && (!dev->StopSummitUrb)) ||(!(operational_mode) )) { ++ int temp = dev->rxq.qlen; ++ int qlen = RX_QLEN(dev); ++ ++ if (temp < qlen) { ++ struct urb *urb; ++ int i; ++ ++ /* don't refill the queue all at once */ ++ for (i = 0; i < 5 && dev->rxq.qlen < qlen; i++) { ++ urb = usb_alloc_urb(0,GFP_ATOMIC); ++ if (urb != NULL) { ++ ret = rx_submit(dev, urb, GFP_ATOMIC); ++ if (ret) ++ break; ++ } ++ } ++ if (dev->rxq.qlen < qlen) ++ tasklet_schedule(&dev->bh); ++ } ++ ++ } ++ if (!dev->tx_hold_on_completion) { ++ if (dev->txq.qlen < TX_QLEN(dev)) ++ netif_wake_queue(dev->net); ++ } ++ } ++} ++ ++// precondition: never called in_interrupt ++int smscusbnet_stop (struct net_device *net) ++{ ++ int temp; ++ struct usbnet *dev = netdev_priv(net); ++ ++ DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup); ++ DECLARE_WAITQUEUE (wait, current); ++ ++ netif_stop_queue (net); ++ if (netif_msg_ifdown (dev)) ++ devinfo (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld", ++ ++ dev->stats.rx_packets, dev->stats.tx_packets, ++ dev->stats.rx_errors, dev->stats.tx_errors ++ ); ++ if(!skb_queue_empty(&dev->tx_pending_q)){ ++ skb_queue_purge(&dev->tx_pending_q); ++ } ++ // ensure there are no more active urbs ++ add_wait_queue (&unlink_wakeup, &wait); ++ dev->wait = &unlink_wakeup; ++ temp = unlink_urbs (dev, &dev->txq) + unlink_urbs (dev, &dev->rxq); ++ // maybe wait for deletions to finish. ++ while (!skb_queue_empty(&dev->rxq) && ++ !skb_queue_empty(&dev->txq) && ++ !skb_queue_empty(&dev->done)) { ++ msleep(UNLINK_TIMEOUT_MS); ++ if (netif_msg_ifdown (dev)) ++ devdbg (dev, "waited for %d urb completions", temp); ++ } ++ dev->wait = NULL; ++ remove_wait_queue (&unlink_wakeup, &wait); ++ if(operational_mode){ ++ usb_kill_urb(dev->interrupt); ++ } ++ ++ /* deferred work (task, timer, softirq) must also stop. ++ * can't flush_scheduled_work() until we drop rtnl (later), ++ * else workers could deadlock; so make workers a NOP. ++ */ ++ dev->flags = 0; ++ //Clean up the counters ++ memset(&dev->stats, 0, sizeof(dev->stats)); ++ memset(&dev->extra_error_cnts, 0, sizeof(dev->extra_error_cnts)); ++ ++ dev->StopLinkPolling=TRUE; ++ tasklet_kill (&dev->bh); ++ netif_carrier_off(dev->net); ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) ++ /* if device is in suspend0 status already, resume it first. So ++ we can set suspend2 in Smsc9500_suspend(); */ ++ down(&dev->pm_mutex); ++ if (!dev->pmLock){ ++ dev->pmLock = TRUE; ++ usb_autopm_get_interface(dev->uintf); ++ } ++ up(&dev->pm_mutex); ++ ++ msleep(100); ++ ++ down(&dev->pm_mutex); ++ if (dev->pmLock) { ++ usb_autopm_put_interface(dev->uintf); ++ } ++ dev->pmLock = FALSE; ++ up(&dev->pm_mutex); ++#endif ++ ++ return 0; ++} ++ ++// posts reads, and enables write queuing ++ ++// precondition: never called in_interrupt ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) ++static ++#endif ++int smscusbnet_open (struct net_device *net) ++{ ++ int retval = 0; ++ struct usbnet *dev = netdev_priv(net); ++ struct driver_info *info = dev->driver_info; ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) ++ down(&dev->pm_mutex); ++ dev->pmLock = TRUE; ++ usb_autopm_get_interface(dev->uintf); ++ up(&dev->pm_mutex); ++#endif ++ ++ dev->suspendFlag = 0; ++ dev->netDetachDone = FALSE; ++ ++ // put into "known safe" state ++ if (info->reset && (retval = info->reset (dev)) < 0) { ++ devdbg (dev,"info->reset && (retval = info->reset (dev)) \n"); ++ if (netif_msg_ifup (dev)) ++ devinfo (dev, ++ "open reset fail (%d) usbnet usb-%s-%s, %s", ++ retval, ++ dev->udev->bus->bus_name, dev->udev->devpath, ++ info->description); ++ goto done; ++ } ++ ++ dev->intr_urb_delay_submit = FALSE; ++ ++ // insist peer be connected ++ if (info->check_connect && (retval = info->check_connect (dev)) < 0) { ++ if (netif_msg_ifup (dev)) ++ devdbg (dev, "can't open; %d", retval); ++ goto done; ++ } ++ ++ /* start any status interrupt transfer */ ++ if(operational_mode){ ++ if (dev->interrupt) { ++ devdbg (dev,"dev->interrupt \n"); ++ retval = usb_submit_urb(dev->interrupt, GFP_KERNEL); ++ if (retval < 0) { ++ if (netif_msg_ifup (dev)) ++ deverr (dev, "intr submit %d", retval); ++ goto done; ++ } ++ } ++ } ++ ++ netif_start_queue(net); ++ if (netif_msg_ifup(dev)) { ++ char *framing; ++ devdbg (dev,"netif_msg_ifup \n"); ++ if (dev->driver_info->flags & FLAG_FRAMING_NC) ++ framing = "NetChip"; ++ else if (dev->driver_info->flags & FLAG_FRAMING_GL) ++ framing = "GeneSys"; ++ else if (dev->driver_info->flags & FLAG_FRAMING_Z) ++ framing = "Zaurus"; ++ else if (dev->driver_info->flags & FLAG_FRAMING_RN) ++ framing = "RNDIS"; ++ else if (dev->driver_info->flags & FLAG_FRAMING_AX) ++ framing = "ASIX"; ++ else ++ framing = "simple"; ++ ++ devinfo(dev, "open: enable queueing " ++ "(rx %lx, tx %lx) mtu %d %s framing", ++ RX_QLEN (dev), TX_QLEN (dev), dev->net->mtu, ++ framing); ++ } ++ ++ // delay posting reads until we're fully open ++ tasklet_schedule(&dev->bh); ++ dev->StopLinkPolling = FALSE; ++ if ((!(dev->StopLinkPolling)) && (!timer_pending(&dev->LinkPollingTimer))) { ++ dev->LinkPollingTimer.expires = jiffies+HZ; ++ add_timer(&(dev->LinkPollingTimer)); ++ } ++done: ++ return retval; ++} ++ ++/* work that cannot be done in interrupt context uses keventd. ++ * ++ * NOTE: with 2.5 we could do more of this using completion callbacks, ++ * especially now that control transfers can be queued. ++ */ ++ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) ++static void kevent (void *data) ++{ ++ struct usbnet *dev = data; ++#else ++static void kevent(struct work_struct *work) ++{ ++ struct usbnet *dev = container_of(work,struct usbnet,kevent); ++#endif ++ ++ int status; ++ ++ if (dev == NULL) ++ return; ++ ++ /* usb_clear_halt() needs a thread context */ ++ if (test_bit(EVENT_TX_HALT, &dev->flags)) { ++ unlink_urbs(dev, &dev->txq); ++ status = usb_clear_halt (dev->udev, dev->out); ++ ++ /* Set recovery flag, the device will be reset in the smsc9500.c */ ++ set_bit(EVENT_DEV_RECOVERY, &dev->flags); ++ ++ if (status < 0 && status != -EPIPE && status != -ESHUTDOWN) { ++ if (netif_msg_tx_err(dev)) ++ deverr(dev, "can't clear tx halt, status %d", status); ++ } else { ++ clear_bit(EVENT_TX_HALT, &dev->flags); ++ if (status != -ESHUTDOWN){ ++ netif_wake_queue(dev->net); ++ } ++ } ++ } ++ if (test_bit(EVENT_RX_HALT, &dev->flags)) { ++ unlink_urbs(dev, &dev->rxq); ++ status = usb_clear_halt(dev->udev, dev->in); ++ ++ /* Set recovery flag */ ++ set_bit(EVENT_DEV_RECOVERY, &dev->flags); ++ ++ if (status < 0 && status != -EPIPE && status != -ESHUTDOWN) { ++ if (netif_msg_rx_err (dev)) ++ deverr(dev, "can't clear rx halt, status %d", ++ status); ++ } else { ++ clear_bit(EVENT_RX_HALT, &dev->flags); ++ tasklet_schedule(&dev->bh); ++ } ++ } ++ ++ /* tasklet could resubmit itself forever if memory is tight */ ++ if (test_bit(EVENT_RX_MEMORY, &dev->flags)) { ++ struct urb *urb = NULL; ++ ++ if (netif_running (dev->net)) ++ urb = usb_alloc_urb(0,GFP_KERNEL); ++ else ++ clear_bit(EVENT_RX_MEMORY, &dev->flags); ++ if (urb != NULL) { ++ clear_bit(EVENT_RX_MEMORY, &dev->flags); ++ rx_submit(dev, urb, GFP_KERNEL); ++ tasklet_schedule(&dev->bh); ++ } ++ } ++ ++ //if (dev->flags) ++ //devdbg (dev, "kevent done, flags = 0x%lx \n", dev->flags); ++} ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) ++/*-------------------------------------------------------------------------*/ ++ ++/* Stop all traffic so kernel will suspend our device. ++ * ++ */ ++#ifdef CONFIG_PM ++static int suspendDevice(struct usbnet *dev) ++{ ++ if(operational_mode){ ++ usb_kill_urb(dev->interrupt); //stop interrupt urb ++ }else{ ++ DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup); ++ DECLARE_WAITQUEUE (wait, current); ++ ++ add_wait_queue (&unlink_wakeup, &wait); ++ dev->wait = &unlink_wakeup; ++ unlink_urbs (dev, &dev->txq); ++ unlink_urbs (dev, &dev->rxq); ++ // maybe wait for deletions to finish. ++ while (!skb_queue_empty(&dev->rxq) && ++ !skb_queue_empty(&dev->txq) && ++ !skb_queue_empty(&dev->done)) { ++ msleep(UNLINK_TIMEOUT_MS); ++ } ++ dev->wait = NULL; ++ remove_wait_queue (&unlink_wakeup, &wait); ++ } ++ ++ dev->StopLinkPolling = TRUE; //stop accessing registers ++ down(&dev->pm_mutex); ++ if(dev->pmLock){ ++ dev->pmLock = FALSE; ++ usb_autopm_put_interface(dev->uintf); ++ } ++ up(&dev->pm_mutex); ++ ++ return 0; ++} ++#endif //CONFIG_PM ++#endif ++ ++/* work that cannot be done in interrupt context uses keventd. ++ * ++ * NOTE: with 2.5 we could do more of this using completion callbacks, ++ * especially now that control transfers can be queued. ++ */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) ++static void myevent(void *data) ++{ ++ struct usbnet *dev = data; ++#else ++static void myevent(struct work_struct *work) ++{ ++ struct usbnet *dev = container_of(work,struct usbnet,myevent); ++#endif ++ ++ if (dev == NULL) ++ return; ++ ++ if (dev->disconnected) { ++ printk("myevent: Disconnected\n"); ++ return; ++ } ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) && defined(CONFIG_PM) ++ if (test_bit (EVENT_IDLE_CHECK, &dev->flags)) { ++ clear_bit (EVENT_IDLE_CHECK, &dev->flags); ++ //autosuspend_disabled should be enabled by shell cmd "echo auto > /sys/bus/usb/devices/X-XX/power/level" ++ if(dev->dynamicSuspend ++#if ((LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))) ++ && !dev->udev->autosuspend_disabled ++#endif ++ ){ ++ if((dev->idleCount >= PM_IDLE_DELAY) && ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,31)) ++ (atomic_read(&dev->uintf->pm_usage_cnt) > 0)){ ++#else ++ (dev->uintf->pm_usage_cnt > 0)){ ++#endif ++ ++ if(dev->chipDependFeatures[FEATURE_SUSPEND3]){ ++ dev->suspendFlag |= AUTOSUSPEND_DYNAMIC_S3; ++ }else{ ++ dev->suspendFlag |= AUTOSUSPEND_DYNAMIC; ++ } ++ ++ suspendDevice(dev); ++ } ++ if(dev->idleCount < PM_IDLE_DELAY)dev->idleCount++; ++ } ++ } ++#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) && defined(CONFIG_PM) ++ if (test_bit (EVENT_LINK_DOWN_DETACH, &dev->flags)) { ++ clear_bit (EVENT_LINK_DOWN_DETACH, &dev->flags); ++ if(dev->netDetach){ ++ dev->suspendFlag |= AUTOSUSPEND_DETACH; ++ } ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) && defined(CONFIG_PM) ++ else if(dev->linkDownSuspend ++#if ((LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))) ++ && !dev->udev->autosuspend_disabled ++#endif ++ ){ ++ dev->suspendFlag |= AUTOSUSPEND_LINKDOWN; ++ suspendDevice(dev); ++ } ++#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) && defined(CONFIG_PM) ++ } ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) && defined(CONFIG_PM) ++ if (test_bit (EVENT_IDLE_RESUME, &dev->flags)) { ++ clear_bit (EVENT_IDLE_RESUME, &dev->flags); ++ ++ if (dev->dynamicSuspend || dev->linkDownSuspend) { ++ down(&dev->pm_mutex); ++ if (!dev->pmLock) { ++ dev->pmLock = TRUE; ++ usb_autopm_get_interface(dev->uintf); ++ } ++ up(&dev->pm_mutex); ++ ++ if (operational_mode) { ++ if (dev->interrupt) { ++ if (usb_submit_urb(dev->interrupt, GFP_KERNEL) < 0) { ++ deverr(dev, "intr submit "); ++ } ++ } ++ } ++ if( (!timer_pending(&dev->LinkPollingTimer))) { ++ dev->LinkPollingTimer.expires = jiffies+HZ; ++ add_timer(&(dev->LinkPollingTimer)); ++ } ++ dev->StopLinkPolling = FALSE; ++ netif_wake_queue(dev->net); ++ } ++ } ++ ++#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) && defined(CONFIG_PM) ++ if (test_bit (EVENT_LINK_RESET, &dev->flags)) { ++ struct driver_info *info = dev->driver_info; ++ int retval = 0; ++ ++ clear_bit (EVENT_LINK_RESET, &dev->flags); ++ ++ if(info->link_reset && (retval = info->link_reset(dev)) < 0) { ++ devinfo(dev, "link reset failed (%d) usbnet usb-%s-%s, %s", ++ retval, ++ dev->udev->bus->bus_name, dev->udev->devpath, ++ info->description); ++ } ++ ++ if (test_bit (EVENT_LINK_UP, &dev->flags)) { ++ clear_bit (EVENT_LINK_UP, &dev->flags); ++ tasklet_schedule (&dev->bh); ++ ++ } ++ if (test_bit (EVENT_LINK_DOWN, &dev->flags)) { ++ clear_bit (EVENT_LINK_DOWN, &dev->flags); ++ unlink_urbs (dev, &dev->rxq); ++ ++ } ++ } ++ ++ if (test_bit (EVENT_SET_MULTICAST, &dev->flags)) { ++ struct driver_info *info = dev->driver_info; ++ int retval = 0; ++ ++ clear_bit (EVENT_SET_MULTICAST, &dev->flags); ++ if(info->rx_setmulticastlist&& (retval = info->rx_setmulticastlist(dev)) < 0) { ++ devinfo(dev, "Set Multicast failed (%d) usbnet usb-%s-%s, %s", ++ retval, ++ dev->udev->bus->bus_name, dev->udev->devpath, ++ info->description); ++ } ++ } ++ ++ //if (dev->flags) ++ //devdbg (dev, "myevent done, flags = 0x%lx", dev->flags); ++} ++ ++static void tx_complete(struct urb *urb) ++{ ++ struct sk_buff *skb = (struct sk_buff *)urb->context; ++ struct skb_data *entry = (struct skb_data *)skb->cb; ++ struct usbnet *dev = entry->dev; ++ ++ dev->idleCount = 0; ++ ++ if (urb->status == 0) { ++ if (dev->tx_hold_on_completion) { ++ if (dev->tx_pending_q.qlen < (TX_QLEN(dev) / 2)) ++ netif_wake_queue(dev->net); ++ ++ dev->stats.tx_packets += entry->pkt_cnt; ++ } else { ++ dev->stats.tx_packets++; ++ } ++ dev->stats.tx_bytes += entry->length; ++ } else { ++ dev->stats.tx_errors++; ++ ++ switch (urb->status) { ++ case -EPIPE: ++ smscusbnet_defer_kevent(dev, EVENT_TX_HALT); ++ dev->extra_error_cnts.tx_epipe++; ++ break; ++ ++ /* software-driven interface shutdown */ ++ case -ECONNRESET: // async unlink ++ case -ESHUTDOWN: // hardware gone ++ break; ++ ++ /* like rx, tx gets controller i/o faults during khubd delays ++ and so it uses the same throttling mechanism */ ++ case -EPROTO: // ehci ++ dev->extra_error_cnts.tx_eproto++; ++ goto _HANDLE; ++ case -ETIMEDOUT: // ohci ++ case -ETIME: // ohci ++ dev->extra_error_cnts.tx_etimeout++; ++ goto _HANDLE; ++ case -EILSEQ: // uhci ++ dev->extra_error_cnts.tx_eilseq++; ++_HANDLE: ++ if (!timer_pending(&dev->delay)) { ++ mod_timer(&dev->delay, ++ jiffies + THROTTLE_JIFFIES); ++ if (netif_msg_link (dev)) ++ devdbg(dev, "tx throttle %d", ++ urb->status); ++ } ++ netif_stop_queue(dev->net); ++ /* Set recovery flag */ ++ set_bit (EVENT_DEV_RECOVERY, &dev->flags); ++ ++ break; ++ default: ++ if (netif_msg_tx_err(dev)) ++ devdbg(dev, "tx err %d", entry->urb->status); ++ break; ++ } ++ } ++ ++ urb->dev = NULL; ++ entry->state = tx_done; ++ defer_bh(dev, skb, &dev->txq); ++} ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) ++static ++#endif ++void smscusbnet_tx_timeout (struct net_device *net) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ ++ unlink_urbs (dev, &dev->txq); ++ tasklet_schedule (&dev->bh); ++ ++ // FIXME: device recovery -- reset? ++} ++ ++/*txq.lock will be acquired by caller*/ ++static int smscusbnet_bundle_skb_ximt(struct usbnet *dev, struct sk_buff_head *q) ++{ ++ unsigned long flags; ++ struct sk_buff *skb = NULL, *skbnext = NULL; ++ int count = 0, pkt_cnt = 0; ++ int SkbSize = 0; ++ struct skb_data *entry; ++ int retval = NET_XMIT_SUCCESS; ++ struct urb *urb = NULL; ++ ++ if ((struct sk_buff *)q == q->next) ++ return retval; ++ ++ if (dev->tx_use_prealloc_buffs) { ++ spin_lock_irqsave(&q->lock, flags); ++ ++ if (!q->qlen) { ++ spin_unlock_irqrestore(&q->lock, flags); ++ return retval; ++ } ++ ++ skb = smscusbnet_get_tx_buffer(dev); ++ if (!skb) { ++ devdbg (dev, "smscusbnet_bundle_skb_ximt(): no tx buffer available\n"); ++ spin_unlock_irqrestore(&q->lock, flags); ++ return retval; ++ } ++ count = 0; ++ while((skbnext = __skb_dequeue(q)) != NULL) { ++ if ((count + skbnext->len) < dev->tx_urb_size) { ++ memcpy(skb->data + count, skbnext->data, skbnext->len); ++ count += skbnext->len; ++ pkt_cnt++; ++ skb_put(skb, skbnext->len); ++ kfree_skb(skbnext); ++ } else { ++ __skb_queue_head(q, skbnext); ++ break; ++ } ++ } ++ SkbSize = count; ++ ++ spin_unlock_irqrestore(&q->lock, flags); ++ ++ } else { ++ spin_lock_irqsave(&q->lock, flags); ++ ++ for(skbnext = q->next; skbnext != (struct sk_buff *) q; skbnext = skbnext->next) { ++ SkbSize += skbnext->len; ++ pkt_cnt++; ++ } ++ if(SkbSize == 0) { ++ spin_unlock_irqrestore(&q->lock, flags); ++ return retval; ++ } ++ ++ if(pkt_cnt > 1) { ++ skb = dev_alloc_skb(SkbSize); ++ if (!skb){ ++ devdbg (dev, "smscusbnet_merge_skb, skb is NULL, CX_SkbSize = %d", SkbSize); ++ spin_unlock_irqrestore(&q->lock, flags); ++ return retval; ++ } ++ if (dev->tx_urb_buf_alignment) { ++ skb->data = (unsigned char *)(((ulong)skb->head + dev->tx_urb_buf_alignment - 1) & ++ ~(dev->tx_urb_buf_alignment - 1)); ++ skb_reset_tail_pointer(skb); ++ } ++ skb_put(skb, SkbSize); ++ count = 0; ++ ++ for(skbnext = q->next; skbnext != (struct sk_buff *) q; skbnext = skbnext->next) { ++ memcpy(skb->data + count, skbnext->data, skbnext->len); ++ count += skbnext->len; ++ } ++ while((skbnext = __skb_dequeue(q)) != NULL){ ++ kfree_skb(skbnext); ++ } ++ ++ } else { //one packet ++ skb = __skb_dequeue(q); ++ } ++ spin_unlock_irqrestore(&q->lock, flags); ++ } ++ ++ netif_wake_queue(dev->net); ++ ++ if (!(urb = usb_alloc_urb(0, GFP_ATOMIC))) { ++ if (netif_msg_tx_err(dev)) ++ devdbg(dev, "no urb"); ++ retval = NET_XMIT_SUCCESS; ++ dev->stats.tx_dropped += pkt_cnt; ++ if (skb){ ++ dev_kfree_skb_any(skb); ++ skb = NULL; ++ } ++ ++ goto drop; ++ } else { ++ entry = (struct skb_data *) skb->cb; ++ entry->urb = urb; ++ entry->dev = dev; ++ entry->state = tx_start; ++ entry->length = SkbSize; ++ entry->pkt_cnt = pkt_cnt; ++ ++ usb_fill_bulk_urb(urb, dev->udev, dev->out, ++ skb->data, skb->len, tx_complete, skb); ++ } ++ ++ switch ((retval = usb_submit_urb(urb, GFP_ATOMIC))) { ++ case -EPIPE: ++ devdbg(dev," in smscusbnet_bundle_skb_ximt,-EPIPE\n"); ++ netif_stop_queue(dev->net); ++ smscusbnet_defer_kevent(dev, EVENT_TX_HALT); ++ break; ++ default: ++ if (netif_msg_tx_err(dev)) ++ devdbg(dev, "tx: submit urb err %d", retval); ++ break; ++ case 0: ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,7,10)) ++ dev->net->trans_start = jiffies; ++#else ++ netif_trans_update(dev->net); ++#endif ++ __skb_queue_tail(&dev->txq, skb); ++ ++ if (dev->txq.qlen >= TX_QLEN(dev)) ++ netif_stop_queue(dev->net); ++ } ++ ++ if (retval) { ++ if (netif_msg_tx_err(dev)) ++ devdbg(dev, "drop, code %d", retval); ++drop: ++ retval = NET_XMIT_SUCCESS; ++ ++ dev->stats.tx_dropped += pkt_cnt; ++ if (skb) ++ dev_kfree_skb_any(skb); ++ usb_free_urb (urb); ++ } else if (netif_msg_tx_queued(dev)) { ++ devdbg(dev, "> tx, len %d, type 0x%x", ++ SkbSize, skb->protocol); ++ } ++ ++ return retval; ++} ++ ++/*-------------------------------------------------------------------------*/ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) ++static ++#endif ++int smscusbnet_start_xmit (struct sk_buff *skb, struct net_device *net) ++{ ++ int retval = NET_XMIT_SUCCESS; ++ struct usbnet *dev = netdev_priv(net); ++ struct driver_info *info = dev->driver_info; ++ ++#if defined(CONFIG_PM) ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,31)) ++ if (atomic_read(&dev->uintf->pm_usage_cnt) <= 0) { ++#else ++ if(dev->uintf->pm_usage_cnt <= 0) { ++#endif ++ netif_stop_queue (net); ++ smscusbnet_defer_myevent(dev, EVENT_IDLE_RESUME); ++ return NET_XMIT_DROP; ++ } ++#endif //CONFIG_PM ++ ++ /* We do not advertise SG, so skbs should be already linearized */ ++ BUG_ON(skb_shinfo(skb)->nr_frags); ++ ++ /* some devices want funky USB-level framing, for win32 driver ++ (usually) and/or hardware quirks */ ++ if (info->tx_fixup) { ++ skb = info->tx_fixup(dev, skb, GFP_ATOMIC); ++ if (!skb) { ++ if (netif_msg_tx_err (dev)) ++ devdbg (dev, "can't tx_fixup skb"); ++ retval = NET_XMIT_SUCCESS; ++ dev->stats.tx_dropped++; ++ return NET_XMIT_DROP; ++ } ++ } ++ ++ if (dev->tx_hold_on_completion) { ++ unsigned long flags; ++ ++ skb_queue_tail(&dev->tx_pending_q, skb); ++ spin_lock_irqsave (&dev->txq.lock, flags); ++ if (dev->txq.qlen != 0) { ++ if (dev->tx_pending_q.qlen >= (TX_QLEN(dev) / 2)) { ++ netif_stop_queue (net); ++ } ++ } else { ++ retval = smscusbnet_bundle_skb_ximt(dev, &dev->tx_pending_q); ++ } ++ spin_unlock_irqrestore(&dev->txq.lock, flags); ++ } else { ++ retval = smscusbnet_xmit(skb, net); ++ } ++ return retval; ++} ++ ++static int smscusbnet_xmit(struct sk_buff *skb, struct net_device *net) ++{ ++ int retval = NET_XMIT_SUCCESS; ++ struct usbnet *dev = netdev_priv(net); ++ struct urb *urb = NULL; ++ struct skb_data *entry; ++ unsigned long flags; ++ ++ if (!(urb = usb_alloc_urb(0, GFP_ATOMIC))) { ++ if (netif_msg_tx_err(dev)) ++ devdbg(dev, "no urb"); ++ goto drop; ++ } ++ ++ entry = (struct skb_data *) skb->cb; ++ entry->urb = urb; ++ entry->dev = dev; ++ entry->state = tx_start; ++ entry->length = skb->len; ++ ++ usb_fill_bulk_urb(urb, dev->udev, dev->out, ++ skb->data, skb->len, tx_complete, skb); ++ ++ /* don't assume the hardware handles USB_ZERO_PACKET ++ * NOTE: strictly conforming cdc-ether devices should expect ++ * the ZLP here, but ignore the one-byte packet. ++ * ++ * FIXME zero that byte, if it doesn't require a new skb. ++ */ ++ if ((skb->len % dev->maxpacket) == 0) { ++ urb->transfer_buffer_length++; ++ if (skb_tailroom(skb)) { ++ skb->data[skb->len] = 0; ++ __skb_put(skb, 1); ++ } ++ } ++ spin_lock_irqsave(&dev->txq.lock, flags); ++ ++ switch ((retval = usb_submit_urb(urb, GFP_ATOMIC))) { ++ case -EPIPE: ++ devdbg (dev," in tx_fixup,-EPIPE\n"); ++ netif_stop_queue (net); ++ smscusbnet_defer_kevent(dev, EVENT_TX_HALT); ++ break; ++ default: ++ if (netif_msg_tx_err(dev)) ++ devdbg(dev, "tx: submit urb err %d", retval); ++ break; ++ case 0: ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,7,10)) ++ dev->net->trans_start = jiffies; ++#else ++ netif_trans_update(dev->net); ++#endif ++ __skb_queue_tail(&dev->txq, skb); ++ ++ if (dev->txq.qlen >= TX_QLEN(dev)) ++ netif_stop_queue(net); ++ } ++ spin_unlock_irqrestore(&dev->txq.lock, flags); ++ ++ if (retval) { ++ devdbg (dev," in tx_fixup,drop\n"); ++ if (netif_msg_tx_err(dev)) ++ devdbg (dev, "drop, code %d", retval); ++drop: ++ retval = NET_XMIT_SUCCESS; ++ dev->stats.tx_dropped++; ++ if (skb) ++ dev_kfree_skb_any(skb); ++ usb_free_urb (urb); ++ } else if (netif_msg_tx_queued(dev)) { ++ devdbg(dev, "> tx, len %d, type 0x%x", ++ skb->len, skb->protocol); ++ } ++ ++ return retval; ++} ++ ++/*------------------------------------------------------------------------- ++ * ++ * USB Device Driver support ++ * ++ *-------------------------------------------------------------------------*/ ++ ++// precondition: never called in_interrupt ++ ++void smscusbnet_disconnect (struct usb_interface *intf) ++{ ++ struct usbnet *dev = NULL; ++ struct usb_device *xdev = NULL; ++ struct net_device *net = NULL; ++ ++ dev = usb_get_intfdata(intf); ++ usb_set_intfdata(intf, NULL); ++ if (!dev) ++ return; ++ ++ dev->disconnected = TRUE; ++ xdev = interface_to_usbdev (intf); ++ ++ if (netif_msg_probe (dev)) ++ devinfo (dev, "unregister '%s' usb-%s-%s, %s", ++ intf->dev.driver->name, ++ xdev->bus->bus_name, xdev->devpath, ++ dev->driver_info->description); ++ ++ net = dev->net; ++ unregister_netdev (net); ++ ++ if(operational_mode && dev->interrupt){ ++ usb_free_urb(dev->interrupt); ++ } ++ if(dev->interrupt_urb_buffer){ ++ kfree(dev->interrupt_urb_buffer); ++ dev->interrupt_urb_buffer = NULL; ++ } ++ ++ if (dev->driver_info->unbind) { ++ dev->driver_info->unbind (dev, intf); ++ } ++ ++ /* we don't hold rtnl here ... */ ++ flush_scheduled_work (); ++ flush_workqueue(dev->MyWorkQueue); ++ destroy_workqueue(dev->MyWorkQueue); ++ ++ del_timer_sync (&dev->LinkPollingTimer); ++ del_timer_sync (&dev->delay); ++ ++ if (dev->rx_use_prealloc_buffs) ++ smscusbnet_free_rx_pool(dev); ++ if (dev->tx_use_prealloc_buffs) ++ smscusbnet_free_tx_pool(dev); ++ ++ free_netdev(net); ++ usb_put_dev (xdev); ++ ++} ++ ++// precondition: never called in_interrupt ++int ++smscusbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) ++{ ++ struct usbnet *dev = NULL; ++ struct net_device *net = NULL; ++ struct usb_host_interface *interface = NULL; ++ struct driver_info *info = NULL; ++ struct usb_device *xdev = NULL; ++ int status = 0; ++ char version[15]; ++ ++ info = (struct driver_info *) prod->driver_info; ++ if (!info) { ++ return -ENODEV; ++ } ++ xdev = interface_to_usbdev (udev); ++ interface = udev->cur_altsetting; ++ ++ usb_get_dev (xdev); ++ ++ sprintf(version,"%lX.%02lX.%02lX", (DRIVER_VERSION>>16),(DRIVER_VERSION>>8)&0xFF,(DRIVER_VERSION&0xFFUL)); ++ printk("Driver smscusbnet.ko verison %s\n",version); ++ ++ // set up our own records ++ net = alloc_etherdev(sizeof(*dev)); ++ if (!net) { ++ goto out; ++ } ++ dev = netdev_priv(net); ++ ++ sema_init(&dev->pm_mutex, 1); ++ ++ dev->udev = xdev; ++ dev->uintf = udev; ++ dev->driver_info = info; ++ dev->msg_enable = netif_msg_init (msg_level, NETIF_MSG_DRV ++ | NETIF_MSG_PROBE | NETIF_MSG_LINK); ++ skb_queue_head_init (&dev->rxq); ++ skb_queue_head_init (&dev->txq); ++ skb_queue_head_init (&dev->tx_pending_q); ++ skb_queue_head_init (&dev->done); ++ dev->bh.func = smscusbnet_bh; ++ dev->bh.data = (unsigned long) dev; ++ ++ dev->idVendor = prod->idVendor; ++ dev->idProduct = prod->idProduct; ++ dev->disconnected = FALSE; ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) ++ INIT_WORK (&dev->kevent, kevent,dev); ++#else ++ INIT_WORK (&dev->kevent, kevent); ++#endif ++ ++ if (operational_mode) ++ devdbg (dev,"Operational mode enabled\n"); ++ ++ dev->MyWorkQueue=create_singlethread_workqueue("intr_work"); ++ if (!dev->MyWorkQueue) { ++ devdbg (dev,"can't create MyWorkQueue!\n"); ++ goto out1; ++ } ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) ++ INIT_WORK (&dev->myevent, myevent,dev); ++#else ++ INIT_WORK (&dev->myevent, myevent); ++#endif ++ dev->delay.function = smscusbnet_bh; ++ dev->delay.data = (unsigned long) dev; ++ init_timer (&dev->delay); ++ ++ dev->tx_qlen = tx_queue_size; ++ dev->rx_qlen = rx_queue_size; ++ dev->turbo_mode = TurboMode; ++ ++ if (TurboMode) { ++ if(dev->udev->speed == USB_SPEED_HIGH) ++ dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE; ++ else ++ dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE; ++ }else{ ++ dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE; ++ } ++ ++ dev->tx_hold_on_completion = tx_hold_on_completion; ++ dev->tx_urb_buf_alignment = tx_urb_buf_alignment; ++ dev->rx_urb_buf_alignment = rx_urb_buf_alignment; ++ if (net_ip_align) { ++ dev->net_ip_align = net_ip_align; ++ } else { ++ dev->net_ip_align = NET_IP_ALIGN; ++ } ++ dev->rx_skb_copy = rx_skb_copy; ++ ++ dev->rx_use_prealloc_buffs = rx_use_prealloc_buffers; ++ skb_queue_head_init(&dev->rx_pool_queue); ++ /* allocate rx usb buffers if enabled */ ++ if (dev->rx_use_prealloc_buffs) { ++ status = smscusbnet_alloc_rx_pool(dev, dev->rx_urb_size); ++ if (status) { ++ smscusbnet_free_rx_pool(dev); ++ status = ENOMEM; ++ goto out1; ++ } ++ } ++ ++ dev->tx_use_prealloc_buffs = tx_use_prealloc_buffers; ++ dev->tx_urb_size = DEFAULT_TX_BUFFER_SIZE; ++ skb_queue_head_init(&dev->tx_pool_queue); ++ /* allocate tx usb buffers if enabled */ ++ if (dev->tx_use_prealloc_buffs) { ++ status = smscusbnet_alloc_tx_pool(dev, dev->tx_urb_size); ++ if (status) { ++ smscusbnet_free_tx_pool(dev); ++ status = ENOMEM; ++ goto out1; ++ } ++ } ++ ++ dev->StopLinkPolling = FALSE; ++ dev->LinkPollingTimer.function = smscusbnet_linkpolling; ++ dev->LinkPollingTimer.data = (unsigned long) dev; ++ init_timer(&(dev->LinkPollingTimer)); ++ ++ dev->net = net; ++ strcpy (net->name, "eth%d"); ++ memcpy (net->dev_addr, node_id, sizeof node_id); ++ ++ /* rx and tx sides can use different message sizes; ++ * bind() should set rx_urb_size in that case. ++ */ ++ /* Reserve extra 8 bytes for control word to eliminate memcpy ++ in tx_fixup() */ ++ net->hard_header_len += EXTRA_HEADER_LEN; ++ dev->hard_mtu = net->mtu + net->hard_header_len; ++#if 0 ++ /* dma_supported() is deeply broken on almost all architectures ++ possible with some EHCI controllers */ ++ if (dma_supported (&udev->dev, DMA_64BIT_MASK)) ++ net->features |= NETIF_F_HIGHDMA; ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) ++ net->change_mtu = smscusbnet_change_mtu; ++ net->get_stats = smscusbnet_get_stats; ++ net->hard_start_xmit = smscusbnet_start_xmit; ++ net->open = smscusbnet_open; ++ net->stop = smscusbnet_stop; ++ net->tx_timeout = smscusbnet_tx_timeout; ++#else ++ net->netdev_ops = &smscusbnet_netdev_ops; ++#endif //linux 2.6.29 ++ net->watchdog_timeo = TX_TIMEOUT_JIFFIES; ++ ++ /* allow device-specific bind/init procedures ++ NOTE net->name still not usable */ ++ if (info->bind) { ++ status = info->bind(dev, udev); ++ if (status < 0) { ++ devdbg(dev,"info->bind,status<0 \n"); ++ goto out2; ++ } ++ /* heuristic: "usb%d" for links we know are two-host, ++ else "eth%d" when there's reasonable doubt. userspace ++ can rename the link if it knows better */ ++ if ((dev->driver_info->flags & FLAG_ETHER) != 0 ++ && (net->dev_addr [0] & 0x02) == 0) { ++ strcpy (net->name, "eth%d"); ++ } ++ ++ /* maybe the remote can't receive an Ethernet MTU */ ++ if (net->mtu > (dev->hard_mtu - net->hard_header_len)) ++ net->mtu = dev->hard_mtu - net->hard_header_len; ++ } else if (!info->in || !info->out) { ++ status = smscusbnet_get_endpoints(dev, udev); ++ } else { ++ dev->in = usb_rcvbulkpipe(xdev, info->in); ++ dev->out = usb_sndbulkpipe(xdev, info->out); ++ if (!(info->flags & FLAG_NO_SETINT)) ++ status = usb_set_interface (xdev, ++ interface->desc.bInterfaceNumber, ++ interface->desc.bAlternateSetting); ++ else ++ status = 0; ++ } ++ if (status >= 0 && dev->status) { ++ status = init_status (dev, udev); ++ } ++ if (status < 0) { ++ devdbg(dev,"status<0 \n"); ++ goto out3; ++ } ++ ++ if (!dev->rx_urb_size) ++ dev->rx_urb_size = dev->hard_mtu; ++ ++ dev->StopSummitUrb = 1; ++ ++ dev->maxpacket = usb_maxpacket(dev->udev, dev->out, 1); ++ SET_NETDEV_DEV(net, &udev->dev); ++ status = register_netdev(net); ++ ++ if (status) { ++ goto out3; ++ } ++ if (netif_msg_probe(dev)) ++ devinfo(dev, "register '%s' at usb-%s-%s, %s, " ++ "%02x:%02x:%02x:%02x:%02x:%02x", ++ udev->dev.driver->name, ++ xdev->bus->bus_name, xdev->devpath, ++ dev->driver_info->description, ++ net->dev_addr [0], net->dev_addr [1], ++ net->dev_addr [2], net->dev_addr [3], ++ net->dev_addr [4], net->dev_addr [5]); ++ ++ /* ok, it's ready to go */ ++ usb_set_intfdata(udev, dev); ++ ++ /* start as if the link is up */ ++ netif_device_attach(net); ++ ++ return 0; ++out3: ++ if (info->unbind) ++ info->unbind(dev, udev); ++out2: ++ if (dev->MyWorkQueue) { ++ destroy_workqueue(dev->MyWorkQueue); ++ } ++out1: ++ free_netdev(net); ++out: ++ usb_put_dev(xdev); ++ return status; ++} ++ ++ ++/* FIXME these suspend/resume methods assume non-CDC style ++ * devices, with only one interface. ++ */ ++ ++int smscusbnet_FreeQueue (struct usbnet *dev) ++{ ++ DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup); ++ DECLARE_WAITQUEUE (wait, current); ++ ++ /* accelerate emptying of the rx and queues, to avoid ++ * having everything error out. ++ */ ++ /* ensure there are no more active urbs */ ++ add_wait_queue (&unlink_wakeup, &wait); ++ dev->wait = &unlink_wakeup; ++ (void) unlink_urbs (dev, &dev->rxq); ++ (void) unlink_urbs (dev, &dev->txq); ++ ++ /* maybe wait for deletions to finish. */ ++ while (!skb_queue_empty(&dev->rxq) && ++ !skb_queue_empty(&dev->txq) && ++ !skb_queue_empty(&dev->done)) { ++ msleep(UNLINK_TIMEOUT_MS); ++ } ++ dev->wait = NULL; ++ remove_wait_queue (&unlink_wakeup, &wait); ++ ++ return 0; ++} ++ ++/* FIXME these suspend/resume methods assume non-CDC style ++ * devices, with only one interface. ++ */ ++ #ifndef pm_message_t ++#define pm_message_t u32 ++#endif ++int smscusbnet_suspend (struct usb_interface *intf, pm_message_t state) ++{ ++ struct usbnet *dev = usb_get_intfdata(intf); ++ ++ /* accelerate emptying of the rx and queues, to avoid ++ * having everything error out. ++ */ ++ netif_device_detach (dev->net); ++ ++ (void) unlink_urbs (dev, &dev->txq); ++ (void) unlink_urbs (dev, &dev->rxq); ++ ++ return 0; ++} ++ ++int smscusbnet_resume (struct usb_interface *intf) ++{ ++ struct usbnet *dev = usb_get_intfdata(intf); ++ netif_device_attach (dev->net); ++ tasklet_schedule (&dev->bh); ++ return 0; ++} ++ ++EXPORT_SYMBOL_GPL(smscusbnet_IsOperationalMode); ++EXPORT_SYMBOL_GPL(smscusbnet_get_endpoints); ++EXPORT_SYMBOL_GPL(smscusbnet_skb_return); ++EXPORT_SYMBOL_GPL(smscusbnet_defer_kevent); ++EXPORT_SYMBOL_GPL(smscusbnet_defer_myevent); ++EXPORT_SYMBOL_GPL(smscusbnet_disconnect); ++EXPORT_SYMBOL_GPL(smscusbnet_probe); ++EXPORT_SYMBOL_GPL(smscusbnet_FreeQueue); ++EXPORT_SYMBOL_GPL(smscusbnet_linkpolling); ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) ++EXPORT_SYMBOL(smscusbnet_stop); ++EXPORT_SYMBOL(smscusbnet_get_stats); ++EXPORT_SYMBOL(smscusbnet_open); ++EXPORT_SYMBOL(smscusbnet_start_xmit); ++EXPORT_SYMBOL(smscusbnet_tx_timeout); ++EXPORT_SYMBOL(smscusbnet_change_mtu); ++#endif ++ ++static int __init smscusbnet_init(void) ++{ ++ /* compiler should optimize this out */ ++ BUG_ON (sizeof (((struct sk_buff *)0)->cb) ++ < sizeof (struct skb_data)); ++ ++ random_ether_addr(node_id); ++ return 0; ++} ++module_init(smscusbnet_init); ++ ++static void __exit smscusbnet_exit(void) ++{ ++} ++module_exit(smscusbnet_exit); ++ ++MODULE_AUTHOR("David Brownell"); ++MODULE_DESCRIPTION("USB network driver framework"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/net/ethernet/smsc9514/smscusbnet.h b/drivers/net/ethernet/smsc9514/smscusbnet.h +new file mode 100755 +index 0000000..00d30f4 +--- /dev/null ++++ b/drivers/net/ethernet/smsc9514/smscusbnet.h +@@ -0,0 +1,328 @@ ++/* ++ * USB Networking Link Interface ++ * ++ * Copyright (C) 2000-2005 by David Brownell <dbrownell@users.sourceforge.net> ++ * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#ifndef __SMSCUSBNET_H ++#define __SMSCUSBNET_H ++ ++#ifndef DEBUG ++#define DEBUG ++#endif ++ ++typedef unsigned char BOOLEAN; ++#define TRUE ((BOOLEAN)1) ++#define FALSE ((BOOLEAN)0) ++ ++#define HS_USB_PKT_SIZE 512 ++#define FS_USB_PKT_SIZE 64 ++ ++#define RX_OFFSET 2 /* default NET_IP_ALIGN value */ ++ ++#define MAX_SINGLE_PACKET_SIZE 2048 ++#define DEFAULT_HS_BURST_CAP_SIZE (16 *1024 + 5 * HS_USB_PKT_SIZE) ++#define DEFAULT_FS_BURST_CAP_SIZE (6 *1024 + 33 * FS_USB_PKT_SIZE) ++#define DEFAULT_TX_BUFFER_SIZE (7 * 1024) ++ ++#define EXTRA_HEADER_LEN 8 ++#define VLAN_DUMMY 0xFFFF ++ ++enum{ ++ RX_FIXUP_VALID_SKB, ++ RX_FIXUP_INVALID_SKB, ++ RX_FIXUP_ERROR, ++}; ++ ++struct ExtraErrorCounter ++{ ++ u32 tx_epipe; ++ u32 tx_eproto; ++ u32 tx_etimeout; ++ u32 tx_eilseq; ++ u32 tx_eoverflow; ++ ++ u32 rx_epipe; ++ u32 rx_eproto; ++ u32 rx_etimeout; ++ u32 rx_eilseq; ++ u32 rx_eoverflow; ++ ++}; ++ ++#define AUTOSUSPEND_DYNAMIC 0x01 //Suspend on s0, work for lan9500 and lan9500a ++#define AUTOSUSPEND_DYNAMIC_S3 0x02 //Suspend on s3, only for lan9500a ++#define AUTOSUSPEND_LINKDOWN 0x04 //Suspend when link is down ++#define AUTOSUSPEND_INTFDOWN 0x08 //Suspend when interface is down ++#define AUTOSUSPEND_DETACH 0x10 //Enable net detach ++ ++enum{ ++ FEATURE_SUSPEND3, ++ FEATURE_SMARTDETACH, ++ FEATURE_NEWSTATIS_CNT, ++ FEATURE_SEP_LEDS, ++ FEATURE_WUFF_8, ++ FEATURE_MDIX_MODE, ++ FEATURE_EEE, ++ FEATURE_MAX_NO ++}; ++ ++enum{ ++ EVENT_TX_HALT, ++ EVENT_RX_HALT, ++ EVENT_RX_MEMORY, ++ EVENT_STS_SPLIT, ++ EVENT_LINK_RESET, ++ EVENT_SET_MULTICAST, ++ EVENT_HAS_FRAME, ++ EVENT_DEV_RECOVERY, ++ EVENT_IDLE_CHECK, ++ EVENT_IDLE_RESUME, ++ EVENT_LINK_DOWN_DETACH, ++ EVENT_LINK_UP, ++ EVENT_LINK_DOWN, ++}; ++ ++/* interface from usbnet core to each USB networking link we handle */ ++struct usbnet { ++ /* housekeeping */ ++ struct usb_device *udev; ++ struct usb_interface *uintf; ++ struct driver_info *driver_info; ++ wait_queue_head_t *wait; ++ int StopSummitUrb; ++ ++ /* i/o info: pipes etc */ ++ unsigned in, out; ++ struct usb_host_endpoint *status; ++ unsigned maxpacket; ++ struct timer_list delay; ++ struct timer_list LinkPollingTimer; ++ BOOLEAN StopLinkPolling; ++ u16 idProduct; //Product id from device descriptor ++ u16 idVendor; //Vendor id from device descriptor ++ u32 linkDownSuspend; //1. auto-negotiation complete; 2. energy detection; ++ u32 dynamicSuspend; //Enable dynamic suspend when there are no traffic ++ u32 netDetach; //Enable net detach, only for LAN9500A ++ ++ /* protocol/interface state */ ++ struct net_device *net; ++ struct net_device_stats stats; ++ struct ExtraErrorCounter extra_error_cnts; ++ int msg_enable; ++ unsigned long data [5]; ++ u32 xid; ++ u32 hard_mtu; /* count any extra framing */ ++ size_t rx_urb_size; /* size for rx urbs */ ++ size_t tx_urb_size; /* size for tx urbs, for bundling */ ++ struct mii_if_info mii; ++ ++ /* various kinds of pending driver work */ ++ struct sk_buff_head rxq; ++ struct sk_buff_head txq; ++ struct sk_buff_head tx_pending_q; ++ struct sk_buff_head done; ++ ++ struct urb *tx_urb; ++ ++ struct urb *interrupt; ++ void *interrupt_urb_buffer; ++ struct tasklet_struct bh; ++ ++ struct work_struct kevent; ++ struct work_struct myevent; ++ struct workqueue_struct * MyWorkQueue; ++ unsigned long flags; ++ BOOLEAN intr_urb_delay_submit; ++ ++ int idleCount; ++ int linkcheck; ++ BOOLEAN pmLock; ++ struct semaphore pm_mutex; ++ int suspendFlag; //Flag indicates link down suspend and select suspend ++ BOOLEAN netDetachDone; ++ BOOLEAN disconnected; ++ u32 chipID; ++ u32 preRxFifoDroppedFrame; //Previous counter value ++ ++ int chipDependFeatures[FEATURE_MAX_NO]; //Flag for chip-depend feratures ++ struct vlan_group *vlgrp; //vlan support ++ ++ int turbo_mode; ++ int tx_hold_on_completion; ++ unsigned long tx_qlen; ++ unsigned long rx_qlen; ++ struct sk_buff_head rx_pool_queue; ++ int rx_use_prealloc_buffs; ++ struct sk_buff_head tx_pool_queue; ++ int tx_use_prealloc_buffs; ++ ++ int tx_urb_buf_alignment; ++ int rx_urb_buf_alignment; ++ int net_ip_align; ++ int rx_skb_copy; ++}; ++#define PM_IDLE_DELAY 3 //Time before auto-suspend ++enum{ ++ WAKEPHY_OFF, ++ WAKEPHY_NEGO_COMPLETE, ++ WAKEPHY_ENERGY ++}; ++ ++static inline struct usb_driver *driver_of(struct usb_interface *intf) ++{ ++ return to_usb_driver(intf->dev.driver); ++} ++/* interface from the device/framing level "minidriver" to core */ ++struct driver_info { ++ char *description; ++ ++ int flags; ++/* framing is CDC Ethernet, not writing ZLPs (hw issues), or optionally: */ ++#define FLAG_FRAMING_NC 0x0001 /* guard against device dropouts */ ++#define FLAG_FRAMING_GL 0x0002 /* genelink batches packets */ ++#define FLAG_FRAMING_Z 0x0004 /* zaurus adds a trailer */ ++#define FLAG_FRAMING_RN 0x0008 /* RNDIS batches, plus huge header */ ++ ++#define FLAG_NO_SETINT 0x0010 /* device can't set_interface() */ ++#define FLAG_ETHER 0x0020 /* maybe use "eth%d" names */ ++ ++#define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */ ++ ++ /* init device ... can sleep, or cause probe() failure */ ++ int (*bind)(struct usbnet *, struct usb_interface *); ++ ++ /* cleanup device ... can sleep, but can't fail */ ++ void (*unbind)(struct usbnet *, struct usb_interface *); ++ ++ /* reset device ... can sleep */ ++ int (*reset)(struct usbnet *); ++ ++ /* see if peer is connected ... can sleep */ ++ int (*check_connect)(struct usbnet *); ++ ++ /* for status polling */ ++ void (*status)(struct usbnet *, struct urb *); ++ /* Set max frame size*/ ++ int (*set_max_frame_size)(struct usbnet *, int size); ++ /* link reset handling, called from defer_kevent */ ++ int (*link_reset)(struct usbnet *); ++ ++ /* fixup rx packet (strip framing) */ ++ int (*rx_fixup)(struct usbnet *dev, struct sk_buff *skb); ++ ++ /*set multicast list */ ++ int (*rx_setmulticastlist) (struct usbnet *dev); ++ ++ /* fixup tx packet (add framing) */ ++ struct sk_buff *(*tx_fixup)(struct usbnet *dev, ++ struct sk_buff *skb, int flags); ++ ++ /* for new devices, use the descriptor-reading code instead */ ++ int in; /* rx endpoint */ ++ int out; /* tx endpoint */ ++ ++ unsigned long data; /* Misc driver specific data */ ++ ++}; ++ ++/* Minidrivers are just drivers using the "usbnet" core as a powerful ++ * network-specific subroutine library ... that happens to do pretty ++ * much everything except custom framing and chip-specific stuff. ++ */ ++extern int smscusbnet_probe(struct usb_interface *, const struct usb_device_id *); ++extern void smscusbnet_disconnect(struct usb_interface *); ++extern void smscusbnet_linkpolling(unsigned long ptr); ++ ++/* Drivers that reuse some of the standard USB CDC infrastructure ++ * (notably, using multiple interfaces according to the the CDC ++ * union descriptor) get some helper code. ++ */ ++struct cdc_state { ++ struct usb_cdc_header_desc *header; ++ struct usb_cdc_union_desc *u; ++ struct usb_cdc_ether_desc *ether; ++ struct usb_interface *control; ++ struct usb_interface *data; ++}; ++ ++extern int usbnet_generic_cdc_bind (struct usbnet *, struct usb_interface *); ++extern void usbnet_cdc_unbind (struct usbnet *, struct usb_interface *); ++ ++/* CDC and RNDIS support the same host-chosen packet filters for IN transfers */ ++#define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \ ++ |USB_CDC_PACKET_TYPE_ALL_MULTICAST \ ++ |USB_CDC_PACKET_TYPE_PROMISCUOUS \ ++ |USB_CDC_PACKET_TYPE_DIRECTED) ++ ++ ++/* we record the state for each of our queued skbs */ ++enum skb_state { ++ illegal = 0, ++ tx_start, tx_done, ++ rx_start, rx_done, rx_cleanup ++}; ++ ++struct skb_data { /* skb->cb is one of these */ ++ struct urb *urb; ++ struct usbnet *dev; ++ enum skb_state state; ++ size_t length; ++ size_t pkt_cnt; ++}; ++ ++extern int smscusbnet_IsOperationalMode(struct usbnet *); ++extern int smscusbnet_get_endpoints(struct usbnet *, struct usb_interface *); ++extern void smscusbnet_defer_kevent (struct usbnet *, int); ++extern void smscusbnet_defer_myevent (struct usbnet *, int); ++extern void smscusbnet_skb_return (struct usbnet *, struct sk_buff *); ++extern int summit_IntrUrb (struct usbnet *dev); ++ ++extern u32 smscusbnet_get_msglevel (struct net_device *); ++extern void smscusbnet_set_msglevel (struct net_device *, u32); ++extern void smscusbnet_get_drvinfo (struct net_device *, struct ethtool_drvinfo *); ++extern int smscusbnet_FreeQueue (struct usbnet *dev); ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) ++extern int smscusbnet_stop (struct net_device *net); ++extern struct net_device_stats *smscusbnet_get_stats (struct net_device *net); ++extern int smscusbnet_open (struct net_device *net); ++extern int smscusbnet_start_xmit (struct sk_buff *skb, struct net_device *net); ++extern int smscusbnet_change_mtu (struct net_device *net, int new_mtu); ++extern void smscusbnet_tx_timeout (struct net_device *net); ++#endif ++/* messaging support includes the interface name, so it must not be ++ * used before it has one ... notably, in minidriver bind() calls. ++ */ ++#ifdef DEBUG ++#define devdbg(usbnet, fmt, arg...) \ ++ printk(KERN_DEBUG "%s: " fmt "\n" , (usbnet)->net->name , ## arg) ++#else ++#define devdbg(usbnet, fmt, arg...) do {} while(0) ++#endif ++ ++#define deverr(usbnet, fmt, arg...) \ ++ printk(KERN_ERR "%s: " fmt "\n" , (usbnet)->net->name , ## arg) ++#define devwarn(usbnet, fmt, arg...) \ ++ printk(KERN_WARNING "%s: " fmt "\n" , (usbnet)->net->name , ## arg) ++ ++#define devinfo(usbnet, fmt, arg...) \ ++ printk(KERN_INFO "%s: " fmt "\n" , (usbnet)->net->name , ## arg); \ ++ ++ ++#endif /* __smscusbnet_H */ +diff --git a/drivers/net/ethernet/smsc9514/version.h b/drivers/net/ethernet/smsc9514/version.h +new file mode 100755 +index 0000000..29426ce +--- /dev/null ++++ b/drivers/net/ethernet/smsc9514/version.h +@@ -0,0 +1,6 @@ ++#ifndef SMSC9500_VERSION_H_ ++#define SMSC9500_VERSION_H_ ++ ++#define DRIVER_VERSION (0x00010205UL) ++ ++#endif /*SMSC9500_VERSION_H_*/ +diff --git a/include/linux/usb.h b/include/linux/usb.h +index 02bffcc..6621dd1 100644 +--- a/include/linux/usb.h ++++ b/include/linux/usb.h +@@ -127,6 +127,7 @@ enum usb_interface_condition { + * @dev: driver model's view of this device + * @usb_dev: if an interface is bound to the USB major, this will point + * to the sysfs representation for that device. ++ * @pm_usage_cnt: PM usage counter for this interface + * @reset_ws: Used for scheduling resets from atomic context. + * @resetting_device: USB core reset the device, so use alt setting 0 as + * current; needs bandwidth alloc after reset. +@@ -183,6 +184,7 @@ struct usb_interface { + + struct device dev; /* interface specific device info */ + struct device *usb_dev; ++ atomic_t pm_usage_cnt; /* usage counter for autosuspend */ + struct work_struct reset_ws; /* for resets in atomic context */ + }; + #define to_usb_interface(d) container_of(d, struct usb_interface, dev) +-- +2.7.4 + diff --git a/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0003-Added-mcp25xxfd-driver-support-for-LEC-PX30-A2.patch b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0003-Added-mcp25xxfd-driver-support-for-LEC-PX30-A2.patch new file mode 100644 index 000000000..978eebdcc --- /dev/null +++ b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0003-Added-mcp25xxfd-driver-support-for-LEC-PX30-A2.patch @@ -0,0 +1,4567 @@ +From cd4f6ab6020301a3373c8e7df00b262eec0c6faf Mon Sep 17 00:00:00 2001 +From: Dineshkumar V <dineshkumar.varadarajan@adlinktech.com> +Date: Wed, 13 Nov 2019 15:25:51 +0530 +Subject: [PATCH 3/3] Added mcp25xxfd driver support for LEC-PX30 A2 + +--- + drivers/net/can/spi/Kconfig | 6 + + drivers/net/can/spi/Makefile | 1 + + drivers/net/can/spi/mcp25xxfd.c | 4522 +++++++++++++++++++++++++++++++++++++++ + 3 files changed, 4529 insertions(+) + create mode 100755 drivers/net/can/spi/mcp25xxfd.c + +diff --git a/drivers/net/can/spi/Kconfig b/drivers/net/can/spi/Kconfig +index 148cae5..7fbfbd3 100644 +--- a/drivers/net/can/spi/Kconfig ++++ b/drivers/net/can/spi/Kconfig +@@ -7,4 +7,10 @@ config CAN_MCP251X + ---help--- + Driver for the Microchip MCP251x SPI CAN controllers. + ++config CAN_MCP25XXFD ++ tristate "Microchip MCP2517FD SPI CAN controllers" ++ depends on HAS_DMA ++ ---help--- ++ Driver for the Microchip MCP25XXFD SPI CAN controllers. ++ + endmenu +diff --git a/drivers/net/can/spi/Makefile b/drivers/net/can/spi/Makefile +index 0e86040..e0724f6 100644 +--- a/drivers/net/can/spi/Makefile ++++ b/drivers/net/can/spi/Makefile +@@ -4,3 +4,4 @@ + + + obj-$(CONFIG_CAN_MCP251X) += mcp251x.o ++obj-$(CONFIG_CAN_MCP25XXFD) += mcp25xxfd.o +diff --git a/drivers/net/can/spi/mcp25xxfd.c b/drivers/net/can/spi/mcp25xxfd.c +new file mode 100755 +index 0000000..91d69da +--- /dev/null ++++ b/drivers/net/can/spi/mcp25xxfd.c +@@ -0,0 +1,4522 @@ ++/* ++ * CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface ++ * ++ * Copyright 2017 Martin Sperl <kernel@xxxxxxxxxxxxxxxx> ++ * ++ * SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note ++ * ++ * Based on Microchip MCP251x CAN controller driver written by ++ * David Vrabel, Copyright 2006 Arcom Control Systems Ltd. ++ * ++ */ ++ ++#include <linux/can/core.h> ++#include <linux/can/dev.h> ++#include <linux/can/led.h> ++#include <linux/clk.h> ++#include <linux/completion.h> ++#include <linux/debugfs.h> ++#include <linux/delay.h> ++#include <linux/device.h> ++#include <linux/dma-mapping.h> ++#include <linux/freezer.h> ++#include <linux/gpio/driver.h> ++#include <linux/interrupt.h> ++#include <linux/io.h> ++#include <linux/jiffies.h> ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/netdevice.h> ++#include <linux/of.h> ++#include <linux/of_device.h> ++#include <linux/platform_device.h> ++#include <linux/slab.h> ++#include <linux/sort.h> ++#include <linux/spi/spi.h> ++#include <linux/uaccess.h> ++#include <linux/regulator/consumer.h> ++ ++#define DEVICE_NAME "mcp25xxfd" ++ ++/* device description and rational: ++ * ++ * the mcp25xxfd is a CanFD controller that also supports can2.0 only ++ * modes. ++ * It is connected via spi to the host and requires at minimum a single ++ * irq line in addition to the SPI lines - it is not mentioned explicitly ++ * in the documentation but in principle SPI 3-wire should be possible. ++ * ++ * The clock connected is typically 4MHz, 20MHz or 40MHz. ++ * For the 4MHz clock the controller contains 10x PLL circuitry. ++ * ++ * The controller itself has 2KB or ECC-SRAM for data. ++ * It also has 32 FIFOs (of up to 32 CAN-frames). ++ * There are 4 Fifo types which can get configured: ++ * * TEF - Transmission Event Fifo - which consumes FIFO 0 ++ * even if it is not configured ++ * * Tansmission Queue - for up to 32 Frames. ++ * this queue reorders CAN frames to get transmitted following the ++ * typical CAN dominant/recessive rules on the can bus itself. ++ * This FIFO is optional. ++ * * TX FIFO: generic TX fifos that can contain arbitrary data ++ * and which come with a configurable priority for transmission ++ * It is also possible to have the Controller automatically trigger ++ * a transfer when a Filter Rule for a RTR frame matches. ++ * Each of these fifos in principle can get configured for distinct ++ * dlc sizes (8 thru 64 bytes) ++ * * RX FIFO: generic RX fifo which is filled via filter-rules. ++ * Each of these fifos in principle can get configured for distinct ++ * dlc sizes (8 thru 64 bytes) ++ * Unfortunately there is no filter rule that would allow triggering ++ * on different frame sizes, so for all practical purposes the ++ * RX fifos have to be of the same size (unless one wants to experience ++ * lost data). ++ * When a Can Frame is transmitted fromthe TX Queue or an individual ++ * TX FIFO then a small TEF Frame can get added to the TEF FIFO queue ++ * to log the Transmission of the frame - this includes ID, Flags ++ * (including a custom identifier/index) . ++ * ++ * The controller provides an optional free running counter with a divider ++ * for timestamping of RX frames as well as for TEF entries. ++ * ++ * Driver Implementation details and rational: ++ * * The whole driver has been designed to give best performance ++ * and as little packet loss as possible with 1MHZ Can frames with DLC=0 ++ * on small/slow devices like the Raspberry Pi 1 ++ * * This means that some optimizations for full duplex communication ++ * have been implemented to avoid CPU introduced latencies ++ * (especially for spi_write_then_read cases) - this only applies to ++ * 4 wire SPI busses. ++ * * Due to the fact that the TXQ does reorder Can-Frames we do not make ++ * use of it to avoid unexpected behaviour (say when running a ++ * firmware upgrade via Can) ++ * * this means we use individual TX-fifos with a given priority and ++ * we have to wait until all the TX fifos have been transmitted before ++ * we can restart the networking queue to avoid reordering the frames on ++ * the Can bus itself. ++ * Still we can transmit a transmit only Duty-cycle of 66% to 90% on the ++ * Can bus (at 1MHz). ++ * The scaling factors here are: ++ * * Can bus speed - lower Speeds increase Duty-cycle ++ * * SPI Clock Rate - higher speeds increase duty-cycle ++ * * CPU speed + SPI implementation - reduces latencies between transfers ++ * * There is a module parameter that allows the modification of the ++ * number of tx_fifos, which is by default 7. ++ * * The driver offers some module parameters that allow to control the use ++ * of some optimizations (prefer reading more data than necessary instead ++ * of multiple SPI transfers - the idea here is that this way we may ++ * allow the SPI-controller to use DMA instead of programmed IO to ++ * limit latencies/number of interrupts) ++ * When we have to read multiple RX frames in CanFD mode: ++ * * we allow reading all 64 bytes of payload even if DLC <=8 ++ * this mode is used in Can2.0 only mode by default and can not get ++ * disabled (SRAM Reads have to be a multiple of 4 bytes anyway) ++ * * Releasing/freeing the RX queue requires writing of 1 byte per fifo. ++ * unfortunately these 32-bit registers are not ajacent to each other, ++ * so that for 2 consecutive RX Frames instead of writing 1 byte per ++ * fifo (with protocol overhead of 2 bytes - so a total of 6 bytes in ++ * 2 transfers) we transmit 13 bytes (with a protocol overhead of 2 - ++ * so a total of 15 bytes) ++ * This optimization is only enabled by a module parameter. ++ * * we use TEF + time stamping to record the transmitted frames ++ * including their timestamp - we use this to order TX and RX frames ++ * when submitting them to the network stack. ++ * * due to the inability to "filter" based on DLC sizes we have to use ++ * a common FIFO size. This is 8 bytes for Can2.0 and 64 bytes for CanFD. ++ * * the driver tries to detect the Controller only by reading registers, ++ * but there are circumstances (e.g. after a crashed driver) where we ++ * have to "blindly" configure the clock rate to get the controller to ++ * respond correctly. ++ * * There is one situation where the controller will require a full POR ++ * (total power off) to recover from a bad Clock configuration. ++ * This happens when the wrong clock is configured in the device tree ++ * (say 4MHz are configured, while 20 or 40MHz are used) ++ * in such a situation the driver tries to enable the PLL, which will ++ * never synchronize and the controller becomes unresponsive to further ++ * spi requests until a POR. ++ */ ++ ++#define MCP25XXFD_OST_DELAY_MS 3 ++#define MCP25XXFD_MIN_CLOCK_FREQUENCY 1000000 ++#define MCP25XXFD_MAX_CLOCK_FREQUENCY 40000000 ++#define MCP25XXFD_PLL_MULTIPLIER 10 ++#define MCP25XXFD_AUTO_PLL_MAX_CLOCK_FREQUENCY \ ++ (MCP25XXFD_MAX_CLOCK_FREQUENCY / MCP25XXFD_PLL_MULTIPLIER) ++#define MCP25XXFD_SCLK_DIVIDER 2 ++ ++#define MCP25XXFD_OSC_POLLING_JIFFIES (HZ / 2) ++ ++#define TX_ECHO_SKB_MAX 32 ++ ++#define INSTRUCTION_RESET 0x0000 ++#define INSTRUCTION_READ 0x3000 ++#define INSTRUCTION_WRITE 0x2000 ++#define INSTRUCTION_READ_CRC 0xB000 ++#define INSTRUCTION_WRITE_CRC 0xA000 ++#define INSTRUCTION_WRITE_SAVE 0xC000 ++ ++#define ADDRESS_MASK 0x0fff ++ ++#define MCP25XXFD_SFR_BASE(x) (0xE00 + (x)) ++#define MCP25XXFD_OSC MCP25XXFD_SFR_BASE(0x00) ++# define MCP25XXFD_OSC_PLLEN BIT(0) ++# define MCP25XXFD_OSC_OSCDIS BIT(2) ++# define MCP25XXFD_OSC_SCLKDIV BIT(4) ++# define MCP25XXFD_OSC_CLKODIV_BITS 2 ++# define MCP25XXFD_OSC_CLKODIV_SHIFT 5 ++# define MCP25XXFD_OSC_CLKODIV_MASK \ ++ GENMASK(MCP25XXFD_OSC_CLKODIV_SHIFT \ ++ + MCP25XXFD_OSC_CLKODIV_BITS - 1, \ ++ MCP25XXFD_OSC_CLKODIV_SHIFT) ++# define MCP25XXFD_OSC_CLKODIV_10 3 ++# define MCP25XXFD_OSC_CLKODIV_4 2 ++# define MCP25XXFD_OSC_CLKODIV_2 1 ++# define MCP25XXFD_OSC_CLKODIV_1 0 ++# define MCP25XXFD_OSC_PLLRDY BIT(8) ++# define MCP25XXFD_OSC_OSCRDY BIT(10) ++# define MCP25XXFD_OSC_SCLKRDY BIT(12) ++#define MCP25XXFD_IOCON MCP25XXFD_SFR_BASE(0x04) ++# define MCP25XXFD_IOCON_TRIS0 BIT(0) ++# define MCP25XXFD_IOCON_TRIS1 BIT(1) ++# define MCP25XXFD_IOCON_XSTBYEN BIT(6) ++# define MCP25XXFD_IOCON_LAT0 BIT(8) ++# define MCP25XXFD_IOCON_LAT1 BIT(9) ++# define MCP25XXFD_IOCON_GPIO0 BIT(16) ++# define MCP25XXFD_IOCON_GPIO1 BIT(17) ++# define MCP25XXFD_IOCON_PM0 BIT(24) ++# define MCP25XXFD_IOCON_PM1 BIT(25) ++# define MCP25XXFD_IOCON_TXCANOD BIT(28) ++# define MCP25XXFD_IOCON_SOF BIT(29) ++# define MCP25XXFD_IOCON_INTOD BIT(29) ++#define MCP25XXFD_CRC MCP25XXFD_SFR_BASE(0x08) ++# define MCP25XXFD_CRC_MASK GENMASK(15, 0) ++# define MCP25XXFD_CRC_CRCERRIE BIT(16) ++# define MCP25XXFD_CRC_FERRIE BIT(17) ++# define MCP25XXFD_CRC_CRCERRIF BIT(24) ++# define MCP25XXFD_CRC_FERRIF BIT(25) ++#define MCP25XXFD_ECCCON MCP25XXFD_SFR_BASE(0x0C) ++# define MCP25XXFD_ECCCON_ECCEN BIT(0) ++# define MCP25XXFD_ECCCON_SECIE BIT(1) ++# define MCP25XXFD_ECCCON_DEDIE BIT(2) ++# define MCP25XXFD_ECCCON_PARITY_BITS 6 ++# define MCP25XXFD_ECCCON_PARITY_SHIFT 8 ++# define MCP25XXFD_ECCCON_PARITY_MASK \ ++ GENMASK(MCP25XXFD_ECCCON_PARITY_SHIFT \ ++ + MCP25XXFD_ECCCON_PARITY_BITS - 1, \ ++ MCP25XXFD_ECCCON_PARITY_SHIFT) ++#define MCP25XXFD_ECCSTAT MCP25XXFD_SFR_BASE(0x10) ++# define MCP25XXFD_ECCSTAT_SECIF BIT(1) ++# define MCP25XXFD_ECCSTAT_DEDIF BIT(2) ++# define MCP25XXFD_ECCSTAT_ERRADDR_SHIFT 8 ++# define MCP25XXFD_ECCSTAT_ERRADDR_MASK \ ++ GENMASK(MCP25XXFD_ECCSTAT_ERRADDR_SHIFT + 11, \ ++ MCP25XXFD_ECCSTAT_ERRADDR_SHIFT) ++ ++#define CAN_SFR_BASE(x) (0x000 + (x)) ++#define CAN_CON CAN_SFR_BASE(0x00) ++# define CAN_CON_DNCNT_BITS 5 ++# define CAN_CON_DNCNT_SHIFT 0 ++# define CAN_CON_DNCNT_MASK \ ++ GENMASK(CAN_CON_DNCNT_SHIFT + CAN_CON_DNCNT_BITS - 1, \ ++ CAN_CON_DNCNT_SHIFT) ++# define CAN_CON_ISOCRCEN BIT(5) ++# define CAN_CON_PXEDIS BIT(6) ++# define CAN_CON_WAKFIL BIT(8) ++# define CAN_CON_WFT_BITS 2 ++# define CAN_CON_WFT_SHIFT 9 ++# define CAN_CON_WFT_MASK \ ++ GENMASK(CAN_CON_WFT_SHIFT + CAN_CON_WFT_BITS - 1, \ ++ CAN_CON_WFT_SHIFT) ++# define CAN_CON_BUSY BIT(11) ++# define CAN_CON_BRSDIS BIT(12) ++# define CAN_CON_RTXAT BIT(16) ++# define CAN_CON_ESIGM BIT(17) ++# define CAN_CON_SERR2LOM BIT(18) ++# define CAN_CON_STEF BIT(19) ++# define CAN_CON_TXQEN BIT(20) ++# define CAN_CON_OPMODE_BITS 3 ++# define CAN_CON_OPMOD_SHIFT 21 ++# define CAN_CON_OPMOD_MASK \ ++ GENMASK(CAN_CON_OPMOD_SHIFT + CAN_CON_OPMODE_BITS - 1, \ ++ CAN_CON_OPMOD_SHIFT) ++# define CAN_CON_REQOP_BITS 3 ++# define CAN_CON_REQOP_SHIFT 24 ++# define CAN_CON_REQOP_MASK \ ++ GENMASK(CAN_CON_REQOP_SHIFT + CAN_CON_REQOP_BITS - 1, \ ++ CAN_CON_REQOP_SHIFT) ++# define CAN_CON_MODE_MIXED 0 ++# define CAN_CON_MODE_SLEEP 1 ++# define CAN_CON_MODE_INTERNAL_LOOPBACK 2 ++# define CAN_CON_MODE_LISTENONLY 3 ++# define CAN_CON_MODE_CONFIG 4 ++# define CAN_CON_MODE_EXTERNAL_LOOPBACK 5 ++# define CAN_CON_MODE_CAN2_0 6 ++# define CAN_CON_MODE_RESTRICTED 7 ++# define CAN_CON_ABAT BIT(27) ++# define CAN_CON_TXBWS_BITS 3 ++# define CAN_CON_TXBWS_SHIFT 28 ++# define CAN_CON_TXBWS_MASK \ ++ GENMASK(CAN_CON_TXBWS_SHIFT + CAN_CON_TXBWS_BITS - 1, \ ++ CAN_CON_TXBWS_SHIFT) ++# define CAN_CON_DEFAULT \ ++ (CAN_CON_ISOCRCEN | \ ++ CAN_CON_PXEDIS | \ ++ CAN_CON_WAKFIL | \ ++ (3 << CAN_CON_WFT_SHIFT) | \ ++ CAN_CON_STEF | \ ++ CAN_CON_TXQEN | \ ++ (CAN_CON_MODE_CONFIG << CAN_CON_OPMOD_SHIFT) | \ ++ (CAN_CON_MODE_CONFIG << CAN_CON_REQOP_SHIFT)) ++# define CAN_CON_DEFAULT_MASK \ ++ (CAN_CON_DNCNT_MASK | \ ++ CAN_CON_ISOCRCEN | \ ++ CAN_CON_PXEDIS | \ ++ CAN_CON_WAKFIL | \ ++ CAN_CON_WFT_MASK | \ ++ CAN_CON_BRSDIS | \ ++ CAN_CON_RTXAT | \ ++ CAN_CON_ESIGM | \ ++ CAN_CON_SERR2LOM | \ ++ CAN_CON_STEF | \ ++ CAN_CON_TXQEN | \ ++ CAN_CON_OPMOD_MASK | \ ++ CAN_CON_REQOP_MASK | \ ++ CAN_CON_ABAT | \ ++ CAN_CON_TXBWS_MASK) ++#define CAN_NBTCFG CAN_SFR_BASE(0x04) ++# define CAN_NBTCFG_SJW_BITS 7 ++# define CAN_NBTCFG_SJW_SHIFT 0 ++# define CAN_NBTCFG_SJW_MASK \ ++ GENMASK(CAN_NBTCFG_SJW_SHIFT + CAN_NBTCFG_SJW_BITS - 1, \ ++ CAN_NBTCFG_SJW_SHIFT) ++# define CAN_NBTCFG_TSEG2_BITS 7 ++# define CAN_NBTCFG_TSEG2_SHIFT 8 ++# define CAN_NBTCFG_TSEG2_MASK \ ++ GENMASK(CAN_NBTCFG_TSEG2_SHIFT + CAN_NBTCFG_TSEG2_BITS - 1, \ ++ CAN_NBTCFG_TSEG2_SHIFT) ++# define CAN_NBTCFG_TSEG1_BITS 8 ++# define CAN_NBTCFG_TSEG1_SHIFT 16 ++# define CAN_NBTCFG_TSEG1_MASK \ ++ GENMASK(CAN_NBTCFG_TSEG1_SHIFT + CAN_NBTCFG_TSEG1_BITS - 1, \ ++ CAN_NBTCFG_TSEG1_SHIFT) ++# define CAN_NBTCFG_BRP_BITS 8 ++# define CAN_NBTCFG_BRP_SHIFT 24 ++# define CAN_NBTCFG_BRP_MASK \ ++ GENMASK(CAN_NBTCFG_BRP_SHIFT + CAN_NBTCFG_BRP_BITS - 1, \ ++ CAN_NBTCFG_BRP_SHIFT) ++#define CAN_DBTCFG CAN_SFR_BASE(0x08) ++# define CAN_DBTCFG_SJW_BITS 4 ++# define CAN_DBTCFG_SJW_SHIFT 0 ++# define CAN_DBTCFG_SJW_MASK \ ++ GENMASK(CAN_DBTCFG_SJW_SHIFT + CAN_DBTCFG_SJW_BITS - 1, \ ++ CAN_DBTCFG_SJW_SHIFT) ++# define CAN_DBTCFG_TSEG2_BITS 4 ++# define CAN_DBTCFG_TSEG2_SHIFT 8 ++# define CAN_DBTCFG_TSEG2_MASK \ ++ GENMASK(CAN_DBTCFG_TSEG2_SHIFT + CAN_DBTCFG_TSEG2_BITS - 1, \ ++ CAN_DBTCFG_TSEG2_SHIFT) ++# define CAN_DBTCFG_TSEG1_BITS 5 ++# define CAN_DBTCFG_TSEG1_SHIFT 16 ++# define CAN_DBTCFG_TSEG1_MASK \ ++ GENMASK(CAN_DBTCFG_TSEG1_SHIFT + CAN_DBTCFG_TSEG1_BITS - 1, \ ++ CAN_DBTCFG_TSEG1_SHIFT) ++# define CAN_DBTCFG_BRP_BITS 8 ++# define CAN_DBTCFG_BRP_SHIFT 24 ++# define CAN_DBTCFG_BRP_MASK \ ++ GENMASK(CAN_DBTCFG_BRP_SHIFT + CAN_DBTCFG_BRP_BITS - 1, \ ++ CAN_DBTCFG_BRP_SHIFT) ++#define CAN_TDC CAN_SFR_BASE(0x0C) ++# define CAN_TDC_TDCV_BITS 5 ++# define CAN_TDC_TDCV_SHIFT 0 ++# define CAN_TDC_TDCV_MASK \ ++ GENMASK(CAN_TDC_TDCV_SHIFT + CAN_TDC_TDCV_BITS - 1, \ ++ CAN_TDC_TDCV_SHIFT) ++# define CAN_TDC_TDCO_BITS 5 ++# define CAN_TDC_TDCO_SHIFT 8 ++# define CAN_TDC_TDCO_MASK \ ++ GENMASK(CAN_TDC_TDCO_SHIFT + CAN_TDC_TDCO_BITS - 1, \ ++ CAN_TDC_TDCO_SHIFT) ++# define CAN_TDC_TDCMOD_BITS 2 ++# define CAN_TDC_TDCMOD_SHIFT 16 ++# define CAN_TDC_TDCMOD_MASK \ ++ GENMASK(CAN_TDC_TDCMOD_SHIFT + CAN_TDC_TDCMOD_BITS - 1, \ ++ CAN_TDC_TDCMOD_SHIFT) ++# define CAN_TDC_TDCMOD_DISABLED 0 ++# define CAN_TDC_TDCMOD_MANUAL 1 ++# define CAN_TDC_TDCMOD_AUTO 2 ++# define CAN_TDC_SID11EN BIT(24) ++# define CAN_TDC_EDGFLTEN BIT(25) ++#define CAN_TBC CAN_SFR_BASE(0x10) ++#define CAN_TSCON CAN_SFR_BASE(0x14) ++# define CAN_TSCON_TBCPRE_BITS 10 ++# define CAN_TSCON_TBCPRE_SHIFT 0 ++# define CAN_TSCON_TBCPRE_MASK \ ++ GENMASK(CAN_TSCON_TBCPRE_SHIFT + CAN_TSCON_TBCPRE_BITS - 1, \ ++ CAN_TSCON_TBCPRE_SHIFT) ++# define CAN_TSCON_TBCEN BIT(16) ++# define CAN_TSCON_TSEOF BIT(17) ++# define CAN_TSCON_TSRES BIT(18) ++#define CAN_VEC CAN_SFR_BASE(0x18) ++# define CAN_VEC_ICODE_BITS 7 ++# define CAN_VEC_ICODE_SHIFT 0 ++# define CAN_VEC_ICODE_MASK \ ++ GENMASK(CAN_VEC_ICODE_SHIFT + CAN_VEC_ICODE_BITS - 1, \ ++ CAN_VEC_ICODE_SHIFT) ++# define CAN_VEC_FILHIT_BITS 5 ++# define CAN_VEC_FILHIT_SHIFT 8 ++# define CAN_VEC_FILHIT_MASK \ ++ GENMASK(CAN_VEC_FILHIT_SHIFT + CAN_VEC_FILHIT_BITS - 1, \ ++ CAN_VEC_FILHIT_SHIFT) ++# define CAN_VEC_TXCODE_BITS 7 ++# define CAN_VEC_TXCODE_SHIFT 16 ++# define CAN_VEC_TXCODE_MASK \ ++ GENMASK(CAN_VEC_TXCODE_SHIFT + CAN_VEC_TXCODE_BITS - 1, \ ++ CAN_VEC_TXCODE_SHIFT) ++# define CAN_VEC_RXCODE_BITS 7 ++# define CAN_VEC_RXCODE_SHIFT 24 ++# define CAN_VEC_RXCODE_MASK \ ++ GENMASK(CAN_VEC_RXCODE_SHIFT + CAN_VEC_RXCODE_BITS - 1, \ ++ CAN_VEC_RXCODE_SHIFT) ++#define CAN_INT CAN_SFR_BASE(0x1C) ++# define CAN_INT_IF_SHIFT 0 ++# define CAN_INT_TXIF BIT(0) ++# define CAN_INT_RXIF BIT(1) ++# define CAN_INT_TBCIF BIT(2) ++# define CAN_INT_MODIF BIT(3) ++# define CAN_INT_TEFIF BIT(4) ++# define CAN_INT_ECCIF BIT(8) ++# define CAN_INT_SPICRCIF BIT(9) ++# define CAN_INT_TXATIF BIT(10) ++# define CAN_INT_RXOVIF BIT(11) ++# define CAN_INT_SERRIF BIT(12) ++# define CAN_INT_CERRIF BIT(13) ++# define CAN_INT_WAKIF BIT(14) ++# define CAN_INT_IVMIF BIT(15) ++# define CAN_INT_IF_MASK \ ++ (CAN_INT_TXIF | \ ++ CAN_INT_RXIF | \ ++ CAN_INT_TBCIF | \ ++ CAN_INT_MODIF | \ ++ CAN_INT_TEFIF | \ ++ CAN_INT_ECCIF | \ ++ CAN_INT_SPICRCIF | \ ++ CAN_INT_TXATIF | \ ++ CAN_INT_RXOVIF | \ ++ CAN_INT_CERRIF | \ ++ CAN_INT_SERRIF | \ ++ CAN_INT_WAKEIF | \ ++ CAN_INT_IVMIF) ++# define CAN_INT_IE_SHIFT 16 ++# define CAN_INT_TXIE (CAN_INT_TXIF << CAN_INT_IE_SHIFT) ++# define CAN_INT_RXIE (CAN_INT_RXIF << CAN_INT_IE_SHIFT) ++# define CAN_INT_TBCIE (CAN_INT_TBCIF << CAN_INT_IE_SHIFT) ++# define CAN_INT_MODIE (CAN_INT_MODIF << CAN_INT_IE_SHIFT) ++# define CAN_INT_TEFIE (CAN_INT_TEFIF << CAN_INT_IE_SHIFT) ++# define CAN_INT_ECCIE (CAN_INT_ECCIF << CAN_INT_IE_SHIFT) ++# define CAN_INT_SPICRCIE \ ++ (CAN_INT_SPICRCIF << CAN_INT_IE_SHIFT) ++# define CAN_INT_TXATIE (CAN_INT_TXATIF << CAN_INT_IE_SHIFT) ++# define CAN_INT_RXOVIE (CAN_INT_RXOVIF << CAN_INT_IE_SHIFT) ++# define CAN_INT_CERRIE (CAN_INT_CERRIF << CAN_INT_IE_SHIFT) ++# define CAN_INT_SERRIE (CAN_INT_SERRIF << CAN_INT_IE_SHIFT) ++# define CAN_INT_WAKIE (CAN_INT_WAKIF << CAN_INT_IE_SHIFT) ++# define CAN_INT_IVMIE (CAN_INT_IVMIF << CAN_INT_IE_SHIFT) ++# define CAN_INT_IE_MASK \ ++ (CAN_INT_TXIE | \ ++ CAN_INT_RXIE | \ ++ CAN_INT_TBCIE | \ ++ CAN_INT_MODIE | \ ++ CAN_INT_TEFIE | \ ++ CAN_INT_ECCIE | \ ++ CAN_INT_SPICRCIE | \ ++ CAN_INT_TXATIE | \ ++ CAN_INT_RXOVIE | \ ++ CAN_INT_CERRIE | \ ++ CAN_INT_SERRIE | \ ++ CAN_INT_WAKEIE | \ ++ CAN_INT_IVMIE) ++#define CAN_RXIF CAN_SFR_BASE(0x20) ++#define CAN_TXIF CAN_SFR_BASE(0x24) ++#define CAN_RXOVIF CAN_SFR_BASE(0x28) ++#define CAN_TXATIF CAN_SFR_BASE(0x2C) ++#define CAN_TXREQ CAN_SFR_BASE(0x30) ++#define CAN_TREC CAN_SFR_BASE(0x34) ++# define CAN_TREC_REC_BITS 8 ++# define CAN_TREC_REC_SHIFT 0 ++# define CAN_TREC_REC_MASK \ ++ GENMASK(CAN_TREC_REC_SHIFT + CAN_TREC_REC_BITS - 1, \ ++ CAN_TREC_REC_SHIFT) ++# define CAN_TREC_TEC_BITS 8 ++# define CAN_TREC_TEC_SHIFT 8 ++# define CAN_TREC_TEC_MASK \ ++ GENMASK(CAN_TREC_TEC_SHIFT + CAN_TREC_TEC_BITS - 1, \ ++ CAN_TREC_TEC_SHIFT) ++# define CAN_TREC_EWARN BIT(16) ++# define CAN_TREC_RXWARN BIT(17) ++# define CAN_TREC_TXWARN BIT(18) ++# define CAN_TREC_RXBP BIT(19) ++# define CAN_TREC_TXBP BIT(20) ++# define CAN_TREC_TXBO BIT(21) ++#define CAN_BDIAG0 CAN_SFR_BASE(0x38) ++# define CAN_BDIAG0_NRERRCNT_BITS 8 ++# define CAN_BDIAG0_NRERRCNT_SHIFT 0 ++# define CAN_BDIAG0_NRERRCNT_MASK \ ++ GENMASK(CAN_BDIAG0_NRERRCNT_SHIFT + CAN_BDIAG0_NRERRCNT_BITS - 1, \ ++ CAN_BDIAG0_NRERRCNT_SHIFT) ++# define CAN_BDIAG0_NTERRCNT_BITS 8 ++# define CAN_BDIAG0_NTERRCNT_SHIFT 8 ++# define CAN_BDIAG0_NTERRCNT_MASK \ ++ GENMASK(CAN_BDIAG0_NTERRCNT_SHIFT + CAN_BDIAG0_NTERRCNT_BITS - 1, \ ++ CAN_BDIAG0_NTERRCNT_SHIFT) ++# define CAN_BDIAG0_DRERRCNT_BITS 8 ++# define CAN_BDIAG0_DRERRCNT_SHIFT 16 ++# define CAN_BDIAG0_DRERRCNT_MASK \ ++ GENMASK(CAN_BDIAG0_DRERRCNT_SHIFT + CAN_BDIAG0_DRERRCNT_BITS - 1, \ ++ CAN_BDIAG0_DRERRCNT_SHIFT) ++# define CAN_BDIAG0_DTERRCNT_BITS 8 ++# define CAN_BDIAG0_DTERRCNT_SHIFT 24 ++# define CAN_BDIAG0_DTERRCNT_MASK \ ++ GENMASK(CAN_BDIAG0_DTERRCNT_SHIFT + CAN_BDIAG0_DTERRCNT_BITS - 1, \ ++ CAN_BDIAG0_DTERRCNT_SHIFT) ++#define CAN_BDIAG1 CAN_SFR_BASE(0x3C) ++# define CAN_BDIAG1_EFMSGCNT_BITS 16 ++# define CAN_BDIAG1_EFMSGCNT_SHIFT 0 ++# define CAN_BDIAG1_EFMSGCNT_MASK \ ++ GENMASK(CAN_BDIAG1_EFMSGCNT_SHIFT + CAN_BDIAG1_EFMSGCNT_BITS - 1, \ ++ CAN_BDIAG1_EFMSGCNT_SHIFT) ++# define CAN_BDIAG1_NBIT0ERR BIT(16) ++# define CAN_BDIAG1_NBIT1ERR BIT(17) ++# define CAN_BDIAG1_NACKERR BIT(18) ++# define CAN_BDIAG1_NSTUFERR BIT(19) ++# define CAN_BDIAG1_NFORMERR BIT(20) ++# define CAN_BDIAG1_NCRCERR BIT(21) ++# define CAN_BDIAG1_TXBOERR BIT(23) ++# define CAN_BDIAG1_DBIT0ERR BIT(24) ++# define CAN_BDIAG1_DBIT1ERR BIT(25) ++# define CAN_BDIAG1_DFORMERR BIT(27) ++# define CAN_BDIAG1_DSTUFERR BIT(28) ++# define CAN_BDIAG1_DCRCERR BIT(29) ++# define CAN_BDIAG1_ESI BIT(30) ++# define CAN_BDIAG1_DLCMM BIT(31) ++#define CAN_TEFCON CAN_SFR_BASE(0x40) ++# define CAN_TEFCON_TEFNEIE BIT(0) ++# define CAN_TEFCON_TEFHIE BIT(1) ++# define CAN_TEFCON_TEFFIE BIT(2) ++# define CAN_TEFCON_TEFOVIE BIT(3) ++# define CAN_TEFCON_TEFTSEN BIT(5) ++# define CAN_TEFCON_UINC BIT(8) ++# define CAN_TEFCON_FRESET BIT(10) ++# define CAN_TEFCON_FSIZE_BITS 5 ++# define CAN_TEFCON_FSIZE_SHIFT 24 ++# define CAN_TEFCON_FSIZE_MASK \ ++ GENMASK(CAN_TEFCON_FSIZE_SHIFT + CAN_TEFCON_FSIZE_BITS - 1, \ ++ CAN_TEFCON_FSIZE_SHIFT) ++#define CAN_TEFSTA CAN_SFR_BASE(0x44) ++# define CAN_TEFSTA_TEFNEIF BIT(0) ++# define CAN_TEFSTA_TEFHIF BIT(1) ++# define CAN_TEFSTA_TEFFIF BIT(2) ++# define CAN_TEFSTA_TEVOVIF BIT(3) ++#define CAN_TEFUA CAN_SFR_BASE(0x48) ++#define CAN_RESERVED CAN_SFR_BASE(0x4C) ++#define CAN_TXQCON CAN_SFR_BASE(0x50) ++# define CAN_TXQCON_TXQNIE BIT(0) ++# define CAN_TXQCON_TXQEIE BIT(2) ++# define CAN_TXQCON_TXATIE BIT(4) ++# define CAN_TXQCON_TXEN BIT(7) ++# define CAN_TXQCON_UINC BIT(8) ++# define CAN_TXQCON_TXREQ BIT(9) ++# define CAN_TXQCON_FRESET BIT(10) ++# define CAN_TXQCON_TXPRI_BITS 5 ++# define CAN_TXQCON_TXPRI_SHIFT 16 ++# define CAN_TXQCON_TXPRI_MASK \ ++ GENMASK(CAN_TXQCON_TXPRI_SHIFT + CAN_TXQCON_TXPRI_BITS - 1, \ ++ CAN_TXQCON_TXPRI_SHIFT) ++# define CAN_TXQCON_TXAT_BITS 2 ++# define CAN_TXQCON_TXAT_SHIFT 21 ++# define CAN_TXQCON_TXAT_MASK \ ++ GENMASK(CAN_TXQCON_TXAT_SHIFT + CAN_TXQCON_TXAT_BITS - 1, \ ++ CAN_TXQCON_TXAT_SHIFT) ++# define CAN_TXQCON_FSIZE_BITS 5 ++# define CAN_TXQCON_FSIZE_SHIFT 24 ++# define CAN_TXQCON_FSIZE_MASK \ ++ GENMASK(CAN_TXQCON_FSIZE_SHIFT + CAN_TXQCON_FSIZE_BITS - 1, \ ++ CAN_TXQCON_FSIZE_SHIFT) ++# define CAN_TXQCON_PLSIZE_BITS 3 ++# define CAN_TXQCON_PLSIZE_SHIFT 29 ++# define CAN_TXQCON_PLSIZE_MASK \ ++ GENMASK(CAN_TXQCON_PLSIZE_SHIFT + CAN_TXQCON_PLSIZE_BITS - 1, \ ++ CAN_TXQCON_PLSIZE_SHIFT) ++# define CAN_TXQCON_PLSIZE_8 0 ++# define CAN_TXQCON_PLSIZE_12 1 ++# define CAN_TXQCON_PLSIZE_16 2 ++# define CAN_TXQCON_PLSIZE_20 3 ++# define CAN_TXQCON_PLSIZE_24 4 ++# define CAN_TXQCON_PLSIZE_32 5 ++# define CAN_TXQCON_PLSIZE_48 6 ++# define CAN_TXQCON_PLSIZE_64 7 ++ ++#define CAN_TXQSTA CAN_SFR_BASE(0x54) ++# define CAN_TXQSTA_TXQNIF BIT(0) ++# define CAN_TXQSTA_TXQEIF BIT(2) ++# define CAN_TXQSTA_TXATIF BIT(4) ++# define CAN_TXQSTA_TXERR BIT(5) ++# define CAN_TXQSTA_TXLARB BIT(6) ++# define CAN_TXQSTA_TXABT BIT(7) ++# define CAN_TXQSTA_TXQCI_BITS 5 ++# define CAN_TXQSTA_TXQCI_SHIFT 8 ++# define CAN_TXQSTA_TXQCI_MASK \ ++ GENMASK(CAN_TXQSTA_TXQCI_SHIFT + CAN_TXQSTA_TXQCI_BITS - 1, \ ++ CAN_TXQSTA_TXQCI_SHIFT) ++ ++#define CAN_TXQUA CAN_SFR_BASE(0x58) ++#define CAN_FIFOCON(x) CAN_SFR_BASE(0x5C + 12 * (x - 1)) ++#define CAN_FIFOCON_TFNRFNIE BIT(0) ++#define CAN_FIFOCON_TFHRFHIE BIT(1) ++#define CAN_FIFOCON_TFERFFIE BIT(2) ++#define CAN_FIFOCON_RXOVIE BIT(3) ++#define CAN_FIFOCON_TXATIE BIT(4) ++#define CAN_FIFOCON_RXTSEN BIT(5) ++#define CAN_FIFOCON_RTREN BIT(6) ++#define CAN_FIFOCON_TXEN BIT(7) ++#define CAN_FIFOCON_UINC BIT(8) ++#define CAN_FIFOCON_TXREQ BIT(9) ++#define CAN_FIFOCON_FRESET BIT(10) ++# define CAN_FIFOCON_TXPRI_BITS 5 ++# define CAN_FIFOCON_TXPRI_SHIFT 16 ++# define CAN_FIFOCON_TXPRI_MASK \ ++ GENMASK(CAN_FIFOCON_TXPRI_SHIFT + CAN_FIFOCON_TXPRI_BITS - 1, \ ++ CAN_FIFOCON_TXPRI_SHIFT) ++# define CAN_FIFOCON_TXAT_BITS 2 ++# define CAN_FIFOCON_TXAT_SHIFT 21 ++# define CAN_FIFOCON_TXAT_MASK \ ++ GENMASK(CAN_FIFOCON_TXAT_SHIFT + CAN_FIFOCON_TXAT_BITS - 1, \ ++ CAN_FIFOCON_TXAT_SHIFT) ++# define CAN_FIFOCON_TXAT_ONE_SHOT 0 ++# define CAN_FIFOCON_TXAT_THREE_SHOT 1 ++# define CAN_FIFOCON_TXAT_UNLIMITED 2 ++# define CAN_FIFOCON_FSIZE_BITS 5 ++# define CAN_FIFOCON_FSIZE_SHIFT 24 ++# define CAN_FIFOCON_FSIZE_MASK \ ++ GENMASK(CAN_FIFOCON_FSIZE_SHIFT + CAN_FIFOCON_FSIZE_BITS - 1, \ ++ CAN_FIFOCON_FSIZE_SHIFT) ++# define CAN_FIFOCON_PLSIZE_BITS 3 ++# define CAN_FIFOCON_PLSIZE_SHIFT 29 ++# define CAN_FIFOCON_PLSIZE_MASK \ ++ GENMASK(CAN_FIFOCON_PLSIZE_SHIFT + CAN_FIFOCON_PLSIZE_BITS - 1, \ ++ CAN_FIFOCON_PLSIZE_SHIFT) ++#define CAN_FIFOSTA(x) CAN_SFR_BASE(0x60 + 12 * (x - 1)) ++# define CAN_FIFOSTA_TFNRFNIF BIT(0) ++# define CAN_FIFOSTA_TFHRFHIF BIT(1) ++# define CAN_FIFOSTA_TFERFFIF BIT(2) ++# define CAN_FIFOSTA_RXOVIF BIT(3) ++# define CAN_FIFOSTA_TXATIF BIT(4) ++# define CAN_FIFOSTA_TXERR BIT(5) ++# define CAN_FIFOSTA_TXLARB BIT(6) ++# define CAN_FIFOSTA_TXABT BIT(7) ++# define CAN_FIFOSTA_FIFOCI_BITS 5 ++# define CAN_FIFOSTA_FIFOCI_SHIFT 8 ++# define CAN_FIFOSTA_FIFOCI_MASK \ ++ GENMASK(CAN_FIFOSTA_FIFOCI_SHIFT + CAN_FIFOSTA_FIFOCI_BITS - 1, \ ++ CAN_FIFOSTA_FIFOCI_SHIFT) ++#define CAN_FIFOUA(x) CAN_SFR_BASE(0x64 + 12 * (x - 1)) ++#define CAN_FLTCON(x) CAN_SFR_BASE(0x1D0 + (x & 0x1c)) ++# define CAN_FILCON_SHIFT(x) ((x & 3) * 8) ++# define CAN_FILCON_BITS(x) CAN_FILCON_BITS_ ++# define CAN_FILCON_BITS_ 4 ++ /* avoid macro reuse warning, so do not use GENMASK as above */ ++# define CAN_FILCON_MASK(x) \ ++ (GENMASK(CAN_FILCON_BITS_ - 1, 0) << CAN_FILCON_SHIFT(x)) ++# define CAN_FIFOCON_FLTEN(x) BIT(7 + CAN_FILCON_SHIFT(x)) ++#define CAN_FLTOBJ(x) CAN_SFR_BASE(0x1F0 + 8 * x) ++# define CAN_FILOBJ_SID_BITS 11 ++# define CAN_FILOBJ_SID_SHIFT 0 ++# define CAN_FILOBJ_SID_MASK \ ++ GENMASK(CAN_FILOBJ_SID_SHIFT + CAN_FILOBJ_SID_BITS - 1, \ ++ CAN_FILOBJ_SID_SHIFT) ++# define CAN_FILOBJ_EID_BITS 18 ++# define CAN_FILOBJ_EID_SHIFT 12 ++# define CAN_FILOBJ_EID_MASK \ ++ GENMASK(CAN_FILOBJ_EID_SHIFT + CAN_FILOBJ_EID_BITS - 1, \ ++ CAN_FILOBJ_EID_SHIFT) ++# define CAN_FILOBJ_SID11 BIT(29) ++# define CAN_FILOBJ_EXIDE BIT(30) ++#define CAN_FLTMASK(x) CAN_SFR_BASE(0x1F4 + 8 * x) ++# define CAN_FILMASK_MSID_BITS 11 ++# define CAN_FILMASK_MSID_SHIFT 0 ++# define CAN_FILMASK_MSID_MASK \ ++ GENMASK(CAN_FILMASK_MSID_SHIFT + CAN_FILMASK_MSID_BITS - 1, \ ++ CAN_FILMASK_MSID_SHIFT) ++# define CAN_FILMASK_MEID_BITS 18 ++# define CAN_FILMASK_MEID_SHIFT 12 ++# define CAN_FILMASK_MEID_MASK \ ++ GENMASK(CAN_FILMASK_MEID_SHIFT + CAN_FILMASK_MEID_BITS - 1, \ ++ CAN_FILMASK_MEID_SHIFT) ++# define CAN_FILMASK_MSID11 BIT(29) ++# define CAN_FILMASK_MIDE BIT(30) ++ ++#define CAN_OBJ_ID_SID_BITS 11 ++#define CAN_OBJ_ID_SID_SHIFT 0 ++#define CAN_OBJ_ID_SID_MASK \ ++ GENMASK(CAN_OBJ_ID_SID_SHIFT + CAN_OBJ_ID_SID_BITS - 1, \ ++ CAN_OBJ_ID_SID_SHIFT) ++#define CAN_OBJ_ID_EID_BITS 18 ++#define CAN_OBJ_ID_EID_SHIFT 11 ++#define CAN_OBJ_ID_EID_MASK \ ++ GENMASK(CAN_OBJ_ID_EID_SHIFT + CAN_OBJ_ID_EID_BITS - 1, \ ++ CAN_OBJ_ID_EID_SHIFT) ++#define CAN_OBJ_ID_SID_BIT11 BIT(29) ++ ++#define CAN_OBJ_FLAGS_DLC_BITS 4 ++#define CAN_OBJ_FLAGS_DLC_SHIFT 0 ++#define CAN_OBJ_FLAGS_DLC_MASK \ ++ GENMASK(CAN_OBJ_FLAGS_DLC_SHIFT + CAN_OBJ_FLAGS_DLC_BITS - 1, \ ++ CAN_OBJ_FLAGS_DLC_SHIFT) ++#define CAN_OBJ_FLAGS_IDE BIT(4) ++#define CAN_OBJ_FLAGS_RTR BIT(5) ++#define CAN_OBJ_FLAGS_BRS BIT(6) ++#define CAN_OBJ_FLAGS_FDF BIT(7) ++#define CAN_OBJ_FLAGS_ESI BIT(8) ++#define CAN_OBJ_FLAGS_SEQ_BITS 7 ++#define CAN_OBJ_FLAGS_SEQ_SHIFT 9 ++#define CAN_OBJ_FLAGS_SEQ_MASK \ ++ GENMASK(CAN_OBJ_FLAGS_SEQ_SHIFT + CAN_OBJ_FLAGS_SEQ_BITS - 1, \ ++ CAN_OBJ_FLAGS_SEQ_SHIFT) ++#define CAN_OBJ_FLAGS_FILHIT_BITS 11 ++#define CAN_OBJ_FLAGS_FILHIT_SHIFT 5 ++#define CAN_OBJ_FLAGS_FILHIT_MASK \ ++ GENMASK(CAN_FLAGS_FILHIT_SHIFT + CAN_FLAGS_FILHIT_BITS - 1, \ ++ CAN_FLAGS_FILHIT_SHIFT) ++ ++#define CAN_OBJ_FLAGS_CUSTOM_ISTEF BIT(31) ++ ++#define MCP25XXFD_BUFFER_TXRX_SIZE 2048 ++ ++static const char * const mcp25xxfd_mode_names[] = { ++ [CAN_CON_MODE_MIXED] = "can2.0+canfd", ++ [CAN_CON_MODE_SLEEP] = "sleep", ++ [CAN_CON_MODE_INTERNAL_LOOPBACK] = "internal loopback", ++ [CAN_CON_MODE_LISTENONLY] = "listen only", ++ [CAN_CON_MODE_CONFIG] = "config", ++ [CAN_CON_MODE_EXTERNAL_LOOPBACK] = "external loopback", ++ [CAN_CON_MODE_CAN2_0] = "can2.0", ++ [CAN_CON_MODE_RESTRICTED] = "restricted" ++}; ++ ++struct mcp25xxfd_obj { ++ u32 id; ++ u32 flags; ++}; ++ ++struct mcp25xxfd_obj_tx { ++ struct mcp25xxfd_obj header; ++ u32 data[]; ++}; ++ ++static void mcp25xxfd_obj_to_le(struct mcp25xxfd_obj *obj) ++{ ++ obj->id = cpu_to_le32(obj->id); ++ obj->flags = cpu_to_le32(obj->flags); ++} ++ ++struct mcp25xxfd_obj_ts { ++ u32 id; ++ u32 flags; ++ u32 ts; ++}; ++ ++struct mcp25xxfd_obj_tef { ++ struct mcp25xxfd_obj_ts header; ++}; ++ ++struct mcp25xxfd_obj_rx { ++ struct mcp25xxfd_obj_ts header; ++ u8 data[]; ++}; ++ ++static void mcp25xxfd_obj_ts_from_le(struct mcp25xxfd_obj_ts *obj) ++{ ++ obj->id = le32_to_cpu(obj->id); ++ obj->flags = le32_to_cpu(obj->flags); ++ obj->ts = le32_to_cpu(obj->ts); ++} ++ ++#define FIFO_DATA(x) (0x400 + (x)) ++#define FIFO_DATA_SIZE 0x800 ++ ++static const struct can_bittiming_const mcp25xxfd_nominal_bittiming_const = { ++ .name = DEVICE_NAME, ++ .tseg1_min = 2, ++ .tseg1_max = BIT(CAN_NBTCFG_TSEG1_BITS), ++ .tseg2_min = 1, ++ .tseg2_max = BIT(CAN_NBTCFG_TSEG2_BITS), ++ .sjw_max = BIT(CAN_NBTCFG_SJW_BITS), ++ .brp_min = 1, ++ .brp_max = BIT(CAN_NBTCFG_BRP_BITS), ++ .brp_inc = 1, ++}; ++ ++static const struct can_bittiming_const mcp25xxfd_data_bittiming_const = { ++ .name = DEVICE_NAME, ++ .tseg1_min = 1, ++ .tseg1_max = BIT(CAN_DBTCFG_TSEG1_BITS), ++ .tseg2_min = 1, ++ .tseg2_max = BIT(CAN_DBTCFG_TSEG2_BITS), ++ .sjw_max = BIT(CAN_DBTCFG_SJW_BITS), ++ .brp_min = 1, ++ .brp_max = BIT(CAN_DBTCFG_BRP_BITS), ++ .brp_inc = 1, ++}; ++ ++enum mcp25xxfd_model { ++ CAN_MCP2517FD = 0x2517, ++}; ++ ++enum mcp25xxfd_gpio_mode { ++ gpio_mode_int = 0, ++ gpio_mode_standby = MCP25XXFD_IOCON_XSTBYEN, ++ gpio_mode_out_low = MCP25XXFD_IOCON_PM0, ++ gpio_mode_out_high = MCP25XXFD_IOCON_PM0 | MCP25XXFD_IOCON_LAT0, ++ gpio_mode_in = MCP25XXFD_IOCON_PM0 | MCP25XXFD_IOCON_TRIS0 ++}; ++ ++struct mcp25xxfd_trigger_tx_message { ++ struct spi_message msg; ++ struct spi_transfer fill_xfer; ++ struct spi_transfer trigger_xfer; ++ int fifo; ++ char fill_cmd[2]; ++ char fill_obj[sizeof(struct mcp25xxfd_obj_tx)]; ++ char fill_data[64]; ++ char trigger_cmd[2]; ++ char trigger_data; ++}; ++ ++struct mcp25xxfd_read_fifo_info { ++ struct mcp25xxfd_obj_ts *rxb[32]; ++ int rx_count; ++}; ++ ++struct mcp25xxfd_priv { ++ struct can_priv can; ++ struct net_device *net; ++ struct spi_device *spi; ++ struct regulator *power; ++ struct regulator *transceiver; ++ struct clk *clk; ++ ++ struct mutex clk_user_lock; /* lock for enabling/disabling the clock */ ++ int clk_user_mask; ++#define MCP25XXFD_CLK_USER_CAN BIT(0) ++#define MCP25XXFD_CLK_USER_GPIO0 BIT(1) ++#define MCP25XXFD_CLK_USER_GPIO1 BIT(2) ++ ++ struct dentry *debugfs_dir; ++ ++#ifdef CONFIG_GPIOLIB ++ struct gpio_chip gpio; ++#endif ++ ++ /* the actual model of the mcp25xxfd */ ++ enum mcp25xxfd_model model; ++ ++ struct { ++ /* clock configuration */ ++ bool clock_pll; ++ bool clock_div2; ++ int clock_odiv; ++ ++ /* GPIO configuration */ ++ bool gpio_opendrain; ++ } config; ++ ++ /* the distinct spi_speeds to use for spi communication */ ++ u32 spi_setup_speed_hz; ++ u32 spi_speed_hz; ++ ++ /* fifo info */ ++ struct { ++ /* define payload size and mode */ ++ int payload_size; ++ u32 payload_mode; ++ ++ /* TEF addresses - start, end and current */ ++ u32 tef_fifos; ++ u32 tef_address_start; ++ u32 tef_address_end; ++ u32 tef_address; ++ ++ /* address in mcp25xxfd-Fifo RAM of each fifo */ ++ u32 fifo_address[32]; ++ ++ /* infos on tx-fifos */ ++ u32 tx_fifos; ++ u32 tx_fifo_start; ++ u32 tx_fifo_mask; /* bitmask of which fifo is a tx fifo */ ++ u32 tx_submitted_mask; ++ u32 tx_pending_mask; ++ u32 tx_pending_mask_in_irq; ++ u32 tx_processed_mask; ++ ++ /* info on rx_fifos */ ++ u32 rx_fifos; ++ u32 rx_fifo_depth; ++ u32 rx_fifo_start; ++ u32 rx_fifo_mask; /* bitmask of which fifo is a rx fifo */ ++ ++ /* memory image of FIFO RAM on mcp25xxfd */ ++ u8 fifo_data[MCP25XXFD_BUFFER_TXRX_SIZE]; ++ ++ } fifos; ++ ++ /* structure with active fifos that need to get fed to the system */ ++ struct mcp25xxfd_read_fifo_info queued_fifos; ++ ++ /* statistics */ ++ struct { ++ /* number of calls to the irq handler */ ++ u64 irq_calls; ++ /* number of loops inside the irq handler */ ++ u64 irq_loops; ++ ++ /* interrupt handler state and statistics */ ++ u32 irq_state; ++#define IRQ_STATE_NEVER_RUN 0 ++#define IRQ_STATE_RUNNING 1 ++#define IRQ_STATE_HANDLED 2 ++ /* stats on number of rx overflows */ ++ u64 rx_overflow; ++ /* statistics of FIFO usage */ ++ u64 fifo_usage[32]; ++ ++ /* message abort counter */ ++ u64 rx_mab; ++ u64 tx_mab; ++ ++ /* message counter fd */ ++ u64 rx_fd_count; ++ u64 tx_fd_count; ++ ++ /* message counter fd bit rate switch */ ++ u64 rx_brs_count; ++ u64 tx_brs_count; ++ ++ /* interrupt counter */ ++ u64 int_ivm_count; ++ u64 int_wake_count; ++ u64 int_cerr_count; ++ u64 int_serr_count; ++ u64 int_rxov_count; ++ u64 int_txat_count; ++ u64 int_spicrc_count; ++ u64 int_ecc_count; ++ u64 int_tef_count; ++ u64 int_mod_count; ++ u64 int_tbc_count; ++ u64 int_rx_count; ++ u64 int_tx_count; ++ ++ /* dlc statistics */ ++ u64 rx_dlc_usage[16]; ++ u64 tx_dlc_usage[16]; ++ } stats; ++ ++ /* the current status of the mcp25xxfd */ ++ struct { ++ u32 intf; ++ /* ASSERT(CAN_INT + 4 == CAN_RXIF) */ ++ u32 rxif; ++ /* ASSERT(CAN_RXIF + 4 == CAN_TXIF) */ ++ u32 txif; ++ /* ASSERT(CAN_TXIF + 4 == CAN_RXOVIF) */ ++ u32 rxovif; ++ /* ASSERT(CAN_RXOVIF + 4 == CAN_TXATIF) */ ++ u32 txatif; ++ /* ASSERT(CAN_TXATIF + 4 == CAN_TXREQ) */ ++ u32 txreq; ++ /* ASSERT(CAN_TXREQ + 4 == CAN_TREC) */ ++ u32 trec; ++ /* ASSERT(CAN_TREC + 4 == CAN_BDIAG0) */ ++ u32 bdiag0; ++ /* ASSERT(CAN_BDIAG0 + 4 == CAN_BDIAG1) */ ++ u32 bdiag1; ++ } status; ++ ++ /* configuration registers */ ++ struct { ++ u32 osc; ++ u32 ecccon; ++ u32 con; ++ u32 iocon; ++ u32 tdc; ++ u32 tscon; ++ u32 tefcon; ++ u32 nbtcfg; ++ u32 dbtcfg; ++ } regs; ++ ++ /* interrupt handler signaling */ ++ int force_quit; ++ int after_suspend; ++#define AFTER_SUSPEND_UP 1 ++#define AFTER_SUSPEND_DOWN 2 ++#define AFTER_SUSPEND_POWER 4 ++#define AFTER_SUSPEND_RESTART 8 ++ int restart_tx; ++ ++ /* interrupt flags during irq handling */ ++ u32 bdiag1_clear_mask; ++ u32 bdiag1_clear_value; ++ ++ /* composit error id and dataduring irq handling */ ++ u32 can_err_id; ++ u32 can_err_data[8]; ++ ++ /* the current mode */ ++ u32 active_can_mode; ++ u32 new_state; ++ ++ /* status of the tx_queue enabled/disabled */ ++ u32 tx_queue_status; ++#define TX_QUEUE_STATUS_INIT 0 ++#define TX_QUEUE_STATUS_RUNNING 1 ++#define TX_QUEUE_STATUS_NEEDS_START 2 ++#define TX_QUEUE_STATUS_STOPPED 3 ++ ++ /* spi-tx/rx buffers for efficient transfers ++ * used during setup and irq ++ */ ++ struct mutex spi_rxtx_lock; ++ u8 spi_tx[MCP25XXFD_BUFFER_TXRX_SIZE]; ++ u8 spi_rx[MCP25XXFD_BUFFER_TXRX_SIZE]; ++ ++ /* structure for transmit fifo spi_messages */ ++ struct mcp25xxfd_trigger_tx_message *spi_transmit_fifos; ++}; ++ ++/* module parameters */ ++bool use_bulk_release_fifos; ++module_param(use_bulk_release_fifos, bool, 0664); ++MODULE_PARM_DESC(use_bulk_release_fifos, ++ "Use code that favours longer spi transfers over multiple transfers"); ++bool use_complete_fdfifo_read; ++module_param(use_complete_fdfifo_read, bool, 0664); ++MODULE_PARM_DESC(use_complete_fdfifo_read, ++ "Use code that favours longer spi transfers over multiple transfers for fd can"); ++unsigned int tx_fifos; ++module_param(tx_fifos, uint, 0664); ++MODULE_PARM_DESC(tx_fifos, ++ "Number of tx-fifos to configure\n"); ++unsigned int bw_sharing_log2bits; ++module_param(bw_sharing_log2bits, uint, 0664); ++MODULE_PARM_DESC(bw_sharing_log2bits, ++ "Delay between 2 transmissions in number of arbitration bit times\n"); ++bool three_shot; ++module_param(three_shot, bool, 0664); ++MODULE_PARM_DESC(three_shot, ++ "Use 3 shots when one-shot is requested"); ++ ++/* spi sync helper */ ++ ++/* wrapper arround spi_sync, that sets speed_hz */ ++static int mcp25xxfd_sync_transfer(struct spi_device *spi, ++ struct spi_transfer *xfer, ++ unsigned int xfers, ++ int speed_hz) ++{ ++ int i; ++ ++ for (i = 0; i < xfers; i++) ++ xfer[i].speed_hz = speed_hz; ++ ++ return spi_sync_transfer(spi, xfer, xfers); ++} ++ ++/* an optimization of spi_write_then_read that merges the transfers */ ++static int mcp25xxfd_write_then_read(struct spi_device *spi, ++ const void *tx_buf, ++ unsigned int tx_len, ++ void *rx_buf, ++ unsigned int rx_len, ++ int speed_hz) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ struct spi_transfer xfer[2]; ++ u8 single_reg_data_tx[6]; ++ u8 single_reg_data_rx[6]; ++ int ret; ++ ++ memset(xfer, 0, sizeof(xfer)); ++ ++ /* when using a halfduplex controller or to big for buffer */ ++ if ((spi->master->flags & SPI_MASTER_HALF_DUPLEX) || ++ (tx_len + rx_len > sizeof(priv->spi_tx))) { ++ xfer[0].tx_buf = tx_buf; ++ xfer[0].len = tx_len; ++ ++ xfer[1].rx_buf = rx_buf; ++ xfer[1].len = rx_len; ++ ++ return mcp25xxfd_sync_transfer(spi, xfer, 2, speed_hz); ++ } ++ ++ /* full duplex optimization */ ++ xfer[0].len = tx_len + rx_len; ++ if (xfer[0].len > sizeof(single_reg_data_tx)) { ++ mutex_lock(&priv->spi_rxtx_lock); ++ xfer[0].tx_buf = priv->spi_tx; ++ xfer[0].rx_buf = priv->spi_rx; ++ } else { ++ xfer[0].tx_buf = single_reg_data_tx; ++ xfer[0].rx_buf = single_reg_data_rx; ++ } ++ ++ /* copy and clean */ ++ memcpy((u8 *)xfer[0].tx_buf, tx_buf, tx_len); ++ memset((u8 *)xfer[0].tx_buf + tx_len, 0, rx_len); ++ ++ ret = mcp25xxfd_sync_transfer(spi, xfer, 1, speed_hz); ++ if (!ret) ++ memcpy(rx_buf, xfer[0].rx_buf + tx_len, rx_len); ++ ++ if (xfer[0].len > sizeof(single_reg_data_tx)) ++ mutex_unlock(&priv->spi_rxtx_lock); ++ ++ return ret; ++} ++ ++/* simple spi_write wrapper with speed_hz */ ++static int mcp25xxfd_write(struct spi_device *spi, ++ const void *tx_buf, ++ unsigned int tx_len, ++ int speed_hz) ++{ ++ struct spi_transfer xfer; ++ ++ memset(&xfer, 0, sizeof(xfer)); ++ xfer.tx_buf = tx_buf; ++ xfer.len = tx_len; ++ ++ return mcp25xxfd_sync_transfer(spi, &xfer, 1, speed_hz); ++} ++ ++/* spi_sync wrapper similar to spi_write_then_read that optimizes transfers */ ++static int mcp25xxfd_write_then_write(struct spi_device *spi, ++ const void *tx_buf, ++ unsigned int tx_len, ++ const void *tx2_buf, ++ unsigned int tx2_len, ++ int speed_hz) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ struct spi_transfer xfer; ++ u8 single_reg_data[6]; ++ int ret; ++ ++ if (tx_len + tx2_len > MCP25XXFD_BUFFER_TXRX_SIZE) ++ return -EINVAL; ++ ++ memset(&xfer, 0, sizeof(xfer)); ++ ++ xfer.len = tx_len + tx2_len; ++ if (xfer.len > sizeof(single_reg_data)) { ++ mutex_lock(&priv->spi_rxtx_lock); ++ xfer.tx_buf = priv->spi_tx; ++ } else { ++ xfer.tx_buf = single_reg_data; ++ } ++ ++ memcpy((u8 *)xfer.tx_buf, tx_buf, tx_len); ++ memcpy((u8 *)xfer.tx_buf + tx_len, tx2_buf, tx2_len); ++ ++ ret = mcp25xxfd_sync_transfer(spi, &xfer, 1, speed_hz); ++ ++ if (xfer.len > sizeof(single_reg_data)) ++ mutex_unlock(&priv->spi_rxtx_lock); ++ ++ return ret; ++} ++ ++/* mcp25xxfd spi command/protocol helper */ ++ ++static void mcp25xxfd_calc_cmd_addr(u16 cmd, u16 addr, u8 *data) ++{ ++ cmd = cmd | (addr & ADDRESS_MASK); ++ ++ data[0] = (cmd >> 8) & 0xff; ++ data[1] = (cmd >> 0) & 0xff; ++} ++ ++static int mcp25xxfd_cmd_reset(struct spi_device *spi, u32 speed_hz) ++{ ++ u8 cmd[2]; ++ ++ mcp25xxfd_calc_cmd_addr(INSTRUCTION_RESET, 0, cmd); ++ ++ /* write the reset command */ ++ return mcp25xxfd_write(spi, cmd, 2, speed_hz); ++} ++ ++/* read multiple bytes, transform some registers */ ++static int mcp25xxfd_cmd_readn(struct spi_device *spi, u32 reg, ++ void *data, int n, u32 speed_hz) ++{ ++ u8 cmd[2]; ++ int ret; ++ ++ mcp25xxfd_calc_cmd_addr(INSTRUCTION_READ, reg, cmd); ++ ++ ret = mcp25xxfd_write_then_read(spi, &cmd, 2, data, n, speed_hz); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static int mcp25xxfd_convert_to_cpu(u32 *data, int n) ++{ ++ int i; ++ ++ for (i = 0; i < n; i++) ++ data[i] = le32_to_cpu(data[i]); ++ ++ return 0; ++} ++ ++static int mcp25xxfd_first_byte(u32 mask) ++{ ++ return (mask & 0x0000ffff) ? ++ ((mask & 0x000000ff) ? 0 : 1) : ++ ((mask & 0x00ff0000) ? 2 : 3); ++} ++ ++static int mcp25xxfd_last_byte(u32 mask) ++{ ++ return (mask & 0xffff0000) ? ++ ((mask & 0xff000000) ? 3 : 2) : ++ ((mask & 0x0000ff00) ? 1 : 0); ++} ++ ++/* read a register, but we are only interrested in a few bytes */ ++static int mcp25xxfd_cmd_read_mask(struct spi_device *spi, u32 reg, ++ u32 *data, u32 mask, u32 speed_hz) ++{ ++ int first_byte, last_byte, len_byte; ++ int ret; ++ ++ /* check that at least one bit is set */ ++ if (!mask) ++ return -EINVAL; ++ ++ /* calculate first and last byte used */ ++ first_byte = mcp25xxfd_first_byte(mask); ++ last_byte = mcp25xxfd_last_byte(mask); ++ len_byte = last_byte - first_byte + 1; ++ ++ /* do a partial read */ ++ *data = 0; ++ ret = mcp25xxfd_cmd_readn(spi, reg + first_byte, ++ ((void *)data + first_byte), len_byte, ++ speed_hz); ++ if (ret) ++ return ret; ++ ++ return mcp25xxfd_convert_to_cpu(data, 1); ++} ++ ++static int mcp25xxfd_cmd_read(struct spi_device *spi, u32 reg, u32 *data, ++ u32 speed_hz) ++{ ++ return mcp25xxfd_cmd_read_mask(spi, reg, data, -1, speed_hz); ++} ++ ++/* read a register, but we are only interrested in a few bytes */ ++static int mcp25xxfd_cmd_write_mask(struct spi_device *spi, u32 reg, ++ u32 data, u32 mask, u32 speed_hz) ++{ ++ int first_byte, last_byte, len_byte; ++ u8 cmd[2]; ++ ++ /* check that at least one bit is set */ ++ if (!mask) ++ return -EINVAL; ++ ++ /* calculate first and last byte used */ ++ first_byte = mcp25xxfd_first_byte(mask); ++ last_byte = mcp25xxfd_last_byte(mask); ++ len_byte = last_byte - first_byte + 1; ++ ++ /* prepare buffer */ ++ mcp25xxfd_calc_cmd_addr(INSTRUCTION_WRITE, reg + first_byte, cmd); ++ data = cpu_to_le32(data); ++ ++ return mcp25xxfd_write_then_write(spi, ++ cmd, sizeof(cmd), ++ ((void *)&data + first_byte), ++ len_byte, ++ speed_hz); ++} ++ ++static int mcp25xxfd_cmd_write(struct spi_device *spi, u32 reg, u32 data, ++ u32 speed_hz) ++{ ++ return mcp25xxfd_cmd_write_mask(spi, reg, data, -1, speed_hz); ++} ++ ++static int mcp25xxfd_cmd_writen(struct spi_device *spi, u32 reg, ++ void *data, int n, u32 speed_hz) ++{ ++ u8 cmd[2]; ++ int ret; ++ ++ mcp25xxfd_calc_cmd_addr(INSTRUCTION_WRITE, reg, cmd); ++ ++ ret = mcp25xxfd_write_then_write(spi, &cmd, 2, data, n, speed_hz); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static int mcp25xxfd_clean_sram(struct spi_device *spi, u32 speed_hz) ++{ ++ u8 buffer[256]; ++ int i; ++ int ret; ++ ++ memset(buffer, 0, sizeof(buffer)); ++ ++ for (i = 0; i < FIFO_DATA_SIZE; i += sizeof(buffer)) { ++ ret = mcp25xxfd_cmd_writen(spi, FIFO_DATA(i), ++ buffer, sizeof(buffer), ++ speed_hz); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++/* mcp25xxfd opmode helper functions */ ++ ++static int mcp25xxfd_get_opmode(struct spi_device *spi, ++ int *mode, ++ int speed_hz) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ int ret; ++ ++ /* read the mode */ ++ ret = mcp25xxfd_cmd_read_mask(spi, ++ CAN_CON, ++ &priv->regs.con, ++ CAN_CON_OPMOD_MASK, ++ speed_hz); ++ if (ret) ++ return ret; ++ /* calculate the mode */ ++ *mode = (priv->regs.con & CAN_CON_OPMOD_MASK) >> ++ CAN_CON_OPMOD_SHIFT; ++ ++ /* and assign to active mode as well */ ++ priv->active_can_mode = *mode; ++ ++ return 0; ++} ++ ++static int mcp25xxfd_set_opmode(struct spi_device *spi, int mode, ++ int speed_hz) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ u32 val = priv->regs.con & ~CAN_CON_REQOP_MASK; ++ ++ /* regs.con also contains the effective register */ ++ priv->regs.con = val | ++ (mode << CAN_CON_REQOP_SHIFT) | ++ (mode << CAN_CON_OPMOD_SHIFT); ++ priv->active_can_mode = mode; ++ ++ /* if the opmode is sleep then the oscilator will be disabled ++ * and also not ready ++ */ ++ if (mode == CAN_CON_MODE_SLEEP) { ++ priv->regs.osc &= ~(MCP25XXFD_OSC_OSCRDY | ++ MCP25XXFD_OSC_PLLRDY | ++ MCP25XXFD_OSC_SCLKRDY); ++ priv->regs.osc |= MCP25XXFD_OSC_OSCDIS; ++ } ++ ++ /* but only write the relevant section */ ++ return mcp25xxfd_cmd_write_mask(spi, CAN_CON, ++ priv->regs.con, ++ CAN_CON_REQOP_MASK, ++ speed_hz); ++} ++ ++static int mcp25xxfd_set_normal_opmode(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ int mode; ++ ++ if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) ++ mode = CAN_CON_MODE_EXTERNAL_LOOPBACK; ++ else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) ++ mode = CAN_CON_MODE_LISTENONLY; ++ else if (priv->can.ctrlmode & CAN_CTRLMODE_FD) ++ mode = CAN_CON_MODE_MIXED; ++ else ++ mode = CAN_CON_MODE_CAN2_0; ++ ++ return mcp25xxfd_set_opmode(spi, mode, priv->spi_setup_speed_hz); ++} ++ ++/* clock helper */ ++static int mcp25xxfd_wake_from_sleep(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ u32 waitfor = MCP25XXFD_OSC_OSCRDY; ++ u32 mask = waitfor | MCP25XXFD_OSC_OSCDIS; ++ unsigned long timeout; ++ int ret; ++ ++ /* write clock with OSCDIS cleared*/ ++ priv->regs.osc &= ~MCP25XXFD_OSC_OSCDIS; ++ ret = mcp25xxfd_cmd_write(spi, MCP25XXFD_OSC, ++ priv->regs.osc, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ ++ /* wait for synced pll/osc/sclk */ ++ timeout = jiffies + MCP25XXFD_OSC_POLLING_JIFFIES; ++ while (time_before_eq(jiffies, timeout)) { ++ ret = mcp25xxfd_cmd_read(spi, MCP25XXFD_OSC, ++ &priv->regs.osc, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ if ((priv->regs.osc & mask) == waitfor) { ++ priv->active_can_mode = CAN_CON_MODE_CONFIG; ++ return 0; ++ } ++ /* wait some time */ ++ mdelay(100); ++ } ++ ++ dev_err(&spi->dev, ++ "Clock did not enable within the timeout period\n"); ++ return -ETIMEDOUT; ++} ++ ++static int mcp25xxfd_hw_check_clock(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ u32 val; ++ int ret; ++ ++ /* read the osc register and check if it matches ++ * what we have on record ++ */ ++ ret = mcp25xxfd_cmd_read(spi, MCP25XXFD_OSC, ++ &val, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ ++ if (val == priv->regs.osc) ++ return 0; ++ ++ /* ignore all those ready bits on second try */ ++ if ((val & 0xff) == (priv->regs.osc & 0xff)) { ++ dev_info(&spi->dev, ++ "The oscillator register value %08x does not match what we expect: %08x - it is still reasonable, but please investigate\n", ++ val, priv->regs.osc); ++ return 0; ++ } ++ ++ dev_err(&spi->dev, ++ "The oscillator register value %08x does not match what we expect: %08x\n", ++ val, priv->regs.osc); ++ ++ return -ENODEV; ++} ++ ++static int mcp25xxfd_start_clock(struct spi_device *spi, int requestor_mask) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ int ret = 0; ++ ++ mutex_lock(&priv->clk_user_lock); ++ ++ priv->clk_user_mask |= requestor_mask; ++ ++ if (priv->clk_user_mask != requestor_mask) ++ goto out; ++ ++ /* check that the controller clock register ++ * is what it is supposed to be ++ */ ++ ret = mcp25xxfd_hw_check_clock(spi); ++ if (ret) { ++ dev_err(&spi->dev, ++ "Controller clock register in unexpected state"); ++ goto out; ++ } ++ ++ /* and we start the clock */ ++ if (!IS_ERR(priv->clk)) ++ ret = clk_prepare_enable(priv->clk); ++ ++ /* we wake from sleep */ ++ if (priv->active_can_mode == CAN_CON_MODE_SLEEP) ++ ret = mcp25xxfd_wake_from_sleep(spi); ++ ++out: ++ mutex_unlock(&priv->clk_user_lock); ++ ++ return ret; ++} ++ ++static int mcp25xxfd_stop_clock(struct spi_device *spi, int requestor_mask) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ ++ mutex_lock(&priv->clk_user_lock); ++ ++ priv->clk_user_mask &= ~requestor_mask; ++ ++ if (!priv->clk_user_mask) ++ goto out; ++ ++ /* put us into sleep mode */ ++ mcp25xxfd_set_opmode(spi, CAN_CON_MODE_SLEEP, ++ priv->spi_setup_speed_hz); ++ ++ /* and we stop the clock */ ++ if (!IS_ERR(priv->clk)) ++ clk_disable_unprepare(priv->clk); ++ ++out: ++ mutex_unlock(&priv->clk_user_lock); ++ ++ return 0; ++} ++ ++/* mcp25xxfd GPIO helper functions */ ++#ifdef CONFIG_GPIOLIB ++ ++enum mcp25xxfd_gpio_pins { ++ MCP25XXFD_GPIO_GPIO0 = 0, ++ MCP25XXFD_GPIO_GPIO1 = 1, ++}; ++ ++static int mcp25xxfd_gpio_request(struct gpio_chip *chip, ++ unsigned int offset) ++{ ++ struct mcp25xxfd_priv *priv = gpiochip_get_data(chip); ++ int clock_requestor = offset ? ++ MCP25XXFD_CLK_USER_GPIO1 : MCP25XXFD_CLK_USER_GPIO0; ++ ++ /* only handle gpio 0/1 */ ++ if (offset > 1) ++ return -EINVAL; ++ ++ mcp25xxfd_start_clock(priv->spi, clock_requestor); ++ ++ return 0; ++} ++ ++static void mcp25xxfd_gpio_free(struct gpio_chip *chip, ++ unsigned int offset) ++{ ++ struct mcp25xxfd_priv *priv = gpiochip_get_data(chip); ++ int clock_requestor = offset ? ++ MCP25XXFD_CLK_USER_GPIO1 : MCP25XXFD_CLK_USER_GPIO0; ++ ++ /* only handle gpio 0/1 */ ++ if (offset > 1) ++ return; ++ ++ mcp25xxfd_stop_clock(priv->spi, clock_requestor); ++} ++ ++static int mcp25xxfd_gpio_get(struct gpio_chip *chip, unsigned int offset) ++{ ++ struct mcp25xxfd_priv *priv = gpiochip_get_data(chip); ++ u32 mask = (offset) ? MCP25XXFD_IOCON_GPIO1 : MCP25XXFD_IOCON_GPIO0; ++ int ret; ++ ++ /* only handle gpio 0/1 */ ++ if (offset > 1) ++ return -EINVAL; ++ ++ /* read the relevant gpio Latch */ ++ ret = mcp25xxfd_cmd_read_mask(priv->spi, MCP25XXFD_IOCON, ++ &priv->regs.iocon, mask, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ ++ /* return the match */ ++ return priv->regs.iocon & mask; ++} ++ ++static void mcp25xxfd_gpio_set(struct gpio_chip *chip, unsigned int offset, ++ int value) ++{ ++ struct mcp25xxfd_priv *priv = gpiochip_get_data(chip); ++ u32 mask = (offset) ? MCP25XXFD_IOCON_LAT1 : MCP25XXFD_IOCON_LAT0; ++ ++ /* only handle gpio 0/1 */ ++ if (offset > 1) ++ return; ++ ++ /* update in memory representation with the corresponding value */ ++ if (value) ++ priv->regs.iocon |= mask; ++ else ++ priv->regs.iocon &= ~mask; ++ ++ mcp25xxfd_cmd_write_mask(priv->spi, MCP25XXFD_IOCON, ++ priv->regs.iocon, mask, ++ priv->spi_setup_speed_hz); ++} ++ ++static int mcp25xxfd_gpio_direction_input(struct gpio_chip *chip, ++ unsigned int offset) ++{ ++ struct mcp25xxfd_priv *priv = gpiochip_get_data(chip); ++ u32 mask_tri = (offset) ? ++ MCP25XXFD_IOCON_TRIS1 : MCP25XXFD_IOCON_TRIS0; ++ u32 mask_stby = (offset) ? ++ 0 : MCP25XXFD_IOCON_XSTBYEN; ++ u32 mask_pm = (offset) ? ++ MCP25XXFD_IOCON_PM1 : MCP25XXFD_IOCON_PM0; ++ ++ /* only handle gpio 0/1 */ ++ if (offset > 1) ++ return -EINVAL; ++ ++ /* set the mask */ ++ priv->regs.iocon |= mask_tri | mask_pm; ++ ++ /* clear stby */ ++ priv->regs.iocon &= ~mask_stby; ++ ++ return mcp25xxfd_cmd_write_mask(priv->spi, MCP25XXFD_IOCON, ++ priv->regs.iocon, ++ mask_tri | mask_stby | mask_pm, ++ priv->spi_setup_speed_hz); ++} ++ ++static int mcp25xxfd_gpio_direction_output(struct gpio_chip *chip, ++ unsigned int offset, int value) ++{ ++ struct mcp25xxfd_priv *priv = gpiochip_get_data(chip); ++ u32 mask_tri = (offset) ? ++ MCP25XXFD_IOCON_TRIS1 : MCP25XXFD_IOCON_TRIS0; ++ u32 mask_lat = (offset) ? ++ MCP25XXFD_IOCON_LAT1 : MCP25XXFD_IOCON_LAT0; ++ u32 mask_pm = (offset) ? ++ MCP25XXFD_IOCON_PM1 : MCP25XXFD_IOCON_PM0; ++ u32 mask_stby = (offset) ? ++ 0 : MCP25XXFD_IOCON_XSTBYEN; ++ ++ /* only handle gpio 0/1 */ ++ if (offset > 1) ++ return -EINVAL; ++ ++ /* clear the tristate bit and also clear stby */ ++ priv->regs.iocon &= ~(mask_tri | mask_stby); ++ ++ /* set GPIO mode */ ++ priv->regs.iocon |= mask_pm; ++ ++ /* set the value */ ++ if (value) ++ priv->regs.iocon |= mask_lat; ++ else ++ priv->regs.iocon &= ~mask_lat; ++ ++ return mcp25xxfd_cmd_write_mask(priv->spi, MCP25XXFD_IOCON, ++ priv->regs.iocon, ++ mask_tri | mask_lat | ++ mask_pm | mask_stby, ++ priv->spi_setup_speed_hz); ++} ++ ++static int mcp25xxfd_gpio_setup(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ ++ /* gpiochip only handles GPIO0 and GPIO1 */ ++ priv->gpio.owner = THIS_MODULE; ++ priv->gpio.parent = &spi->dev; ++ priv->gpio.label = dev_name(&spi->dev); ++ priv->gpio.direction_input = mcp25xxfd_gpio_direction_input; ++ priv->gpio.get = mcp25xxfd_gpio_get; ++ priv->gpio.direction_output = mcp25xxfd_gpio_direction_output; ++ priv->gpio.set = mcp25xxfd_gpio_set; ++ priv->gpio.request = mcp25xxfd_gpio_request; ++ priv->gpio.free = mcp25xxfd_gpio_free; ++ priv->gpio.base = -1; ++ priv->gpio.ngpio = 2; ++ priv->gpio.can_sleep = 1; ++ ++ return devm_gpiochip_add_data(&spi->dev, &priv->gpio, priv); ++} ++ ++#else ++ ++static int mcp25xxfd_gpio_setup(struct spi_device *spi) ++{ ++ return 0; ++} ++ ++#endif ++ ++/* ideally these would be defined in uapi/linux/can.h */ ++#define CAN_EFF_SID_SHIFT (CAN_EFF_ID_BITS - CAN_SFF_ID_BITS) ++#define CAN_EFF_SID_BITS CAN_SFF_ID_BITS ++#define CAN_EFF_SID_MASK \ ++ GENMASK(CAN_EFF_SID_SHIFT + CAN_EFF_SID_BITS - 1, \ ++ CAN_EFF_SID_SHIFT) ++#define CAN_EFF_EID_SHIFT 0 ++#define CAN_EFF_EID_BITS CAN_EFF_SID_SHIFT ++#define CAN_EFF_EID_MASK \ ++ GENMASK(CAN_EFF_EID_SHIFT + CAN_EFF_EID_BITS - 1, \ ++ CAN_EFF_EID_SHIFT) ++ ++static void mcp25xxfd_canid_to_mcpid(u32 can_id, u32 *id, u32 *flags) ++{ ++ if (can_id & CAN_EFF_FLAG) { ++ int sid = (can_id & CAN_EFF_SID_MASK) >> CAN_EFF_SID_SHIFT; ++ int eid = (can_id & CAN_EFF_EID_MASK) >> CAN_EFF_EID_SHIFT; ++ *id = (eid << CAN_OBJ_ID_EID_SHIFT) | ++ (sid << CAN_OBJ_ID_SID_SHIFT); ++ *flags = CAN_OBJ_FLAGS_IDE; ++ } else { ++ *id = can_id & CAN_SFF_MASK; ++ *flags = 0; ++ } ++ ++ *flags |= (can_id & CAN_RTR_FLAG) ? CAN_OBJ_FLAGS_RTR : 0; ++} ++ ++static void mcp25xxfd_mcpid_to_canid(u32 mcpid, u32 mcpflags, u32 *id) ++{ ++ u32 sid = (mcpid & CAN_OBJ_ID_SID_MASK) >> CAN_OBJ_ID_SID_SHIFT; ++ u32 eid = (mcpid & CAN_OBJ_ID_EID_MASK) >> CAN_OBJ_ID_EID_SHIFT; ++ ++ if (mcpflags & CAN_OBJ_FLAGS_IDE) { ++ *id = (eid << CAN_EFF_EID_SHIFT) | ++ (sid << CAN_EFF_SID_SHIFT) | ++ CAN_EFF_FLAG; ++ } else { ++ *id = sid; ++ } ++ ++ *id |= (mcpflags & CAN_OBJ_FLAGS_RTR) ? CAN_RTR_FLAG : 0; ++} ++ ++static void __mcp25xxfd_stop_queue(struct net_device *net, ++ unsigned int id) ++{ ++ struct mcp25xxfd_priv *priv = netdev_priv(net); ++ ++ if (priv->tx_queue_status >= TX_QUEUE_STATUS_STOPPED) ++ dev_warn(&priv->spi->dev, ++ "tx-queue is already stopped by: %i\n", ++ priv->tx_queue_status); ++ ++ priv->tx_queue_status = id ? id : TX_QUEUE_STATUS_STOPPED; ++ netif_stop_queue(priv->net); ++} ++ ++/* helper to identify who is stopping the queue by line number */ ++#define mcp25xxfd_stop_queue(spi) \ ++ __mcp25xxfd_stop_queue(spi, __LINE__) ++ ++static void mcp25xxfd_wake_queue(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ ++ /* nothing should be left pending /in flight now... */ ++ priv->fifos.tx_pending_mask = 0; ++ priv->fifos.tx_submitted_mask = 0; ++ priv->fifos.tx_processed_mask = 0; ++ priv->tx_queue_status = TX_QUEUE_STATUS_RUNNING; ++ ++ /* wake queue now */ ++ netif_wake_queue(priv->net); ++} ++ ++/* CAN transmit related*/ ++ ++static void mcp25xxfd_mark_tx_pending(void *context) ++{ ++ struct mcp25xxfd_trigger_tx_message *txm = context; ++ struct spi_device *spi = txm->msg.spi; ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ ++ /* only here or in the irq handler this value is changed, ++ * so there is no race condition and it does not require locking ++ * serialization happens via spi_pump_message ++ */ ++ priv->fifos.tx_pending_mask |= BIT(txm->fifo); ++} ++ ++static int mcp25xxfd_fill_spi_transmit_fifos(struct mcp25xxfd_priv *priv) ++{ ++ struct mcp25xxfd_trigger_tx_message *txm; ++ int i, fifo; ++ const u32 trigger = CAN_FIFOCON_TXREQ | CAN_FIFOCON_UINC; ++ const int first_byte = mcp25xxfd_first_byte(trigger); ++ u32 fifo_address; ++ ++ priv->spi_transmit_fifos = kcalloc(priv->fifos.tx_fifos, ++ sizeof(*priv->spi_transmit_fifos), ++ GFP_KERNEL | GFP_DMA); ++ if (!priv->spi_transmit_fifos) ++ return -ENOMEM; ++ ++ for (i = 0; i < priv->fifos.tx_fifos; i++) { ++ fifo = priv->fifos.tx_fifo_start + i; ++ txm = &priv->spi_transmit_fifos[i]; ++ fifo_address = priv->fifos.fifo_address[fifo]; ++ /* prepare the message */ ++ spi_message_init(&txm->msg); ++ txm->msg.complete = mcp25xxfd_mark_tx_pending; ++ txm->msg.context = txm; ++ txm->fifo = fifo; ++ /* the payload itself */ ++ txm->fill_xfer.speed_hz = priv->spi_speed_hz; ++ txm->fill_xfer.tx_buf = txm->fill_cmd; ++ txm->fill_xfer.len = 2; ++ txm->fill_xfer.cs_change = true; ++ mcp25xxfd_calc_cmd_addr(INSTRUCTION_WRITE, ++ FIFO_DATA(fifo_address), ++ txm->fill_cmd); ++ spi_message_add_tail(&txm->fill_xfer, &txm->msg); ++ /* the trigger command */ ++ txm->trigger_xfer.speed_hz = priv->spi_speed_hz; ++ txm->trigger_xfer.tx_buf = txm->trigger_cmd; ++ txm->trigger_xfer.len = 3; ++ mcp25xxfd_calc_cmd_addr(INSTRUCTION_WRITE, ++ CAN_FIFOCON(fifo) + first_byte, ++ txm->trigger_cmd); ++ txm->trigger_data = trigger >> (8 * first_byte); ++ spi_message_add_tail(&txm->trigger_xfer, &txm->msg); ++ } ++ ++ return 0; ++} ++ ++static int mcp25xxfd_transmit_message_common(struct spi_device *spi, ++ int fifo, ++ struct mcp25xxfd_obj_tx *obj, ++ int len, ++ u8 *data) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ struct mcp25xxfd_trigger_tx_message *txm = ++ &priv->spi_transmit_fifos[fifo - priv->fifos.tx_fifo_start]; ++ int ret; ++ ++ /* add fifo as seq */ ++ obj->header.flags |= fifo << CAN_OBJ_FLAGS_SEQ_SHIFT; ++ ++ /* transform to le32 */ ++ mcp25xxfd_obj_to_le(&obj->header); ++ ++ /* fill in details */ ++ memcpy(txm->fill_obj, obj, sizeof(struct mcp25xxfd_obj_tx)); ++ memset(txm->fill_data, 0, priv->fifos.payload_size); ++ memcpy(txm->fill_data, data, len); ++ ++ /* transfers to FIFO RAM has to be multiple of 4 */ ++ txm->fill_xfer.len = ++ 2 + sizeof(struct mcp25xxfd_obj_tx) + ALIGN(len, 4); ++ ++ /* and transmit asyncroniously */ ++ ret = spi_async(spi, &txm->msg); ++ if (ret) ++ return NETDEV_TX_BUSY; ++ ++ return NETDEV_TX_OK; ++} ++ ++static int mcp25xxfd_transmit_fdmessage(struct spi_device *spi, int fifo, ++ struct canfd_frame *frame) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ struct mcp25xxfd_obj_tx obj; ++ int dlc = can_len2dlc(frame->len); ++ u32 flags; ++ ++ frame->len = can_dlc2len(dlc); ++ ++ mcp25xxfd_canid_to_mcpid(frame->can_id, &obj.header.id, &flags); ++ ++ flags |= dlc << CAN_OBJ_FLAGS_DLC_SHIFT; ++ flags |= (frame->can_id & CAN_EFF_FLAG) ? CAN_OBJ_FLAGS_IDE : 0; ++ flags |= (frame->can_id & CAN_RTR_FLAG) ? CAN_OBJ_FLAGS_RTR : 0; ++ if (frame->flags & CANFD_BRS) { ++ flags |= CAN_OBJ_FLAGS_BRS; ++ priv->stats.tx_brs_count++; ++ } ++ flags |= (frame->flags & CANFD_ESI) ? CAN_OBJ_FLAGS_ESI : 0; ++ flags |= CAN_OBJ_FLAGS_FDF; ++ ++ priv->stats.tx_fd_count++; ++ priv->stats.tx_dlc_usage[dlc]++; ++ ++ obj.header.flags = flags; ++ ++ return mcp25xxfd_transmit_message_common(spi, fifo, &obj, ++ frame->len, frame->data); ++} ++ ++static int mcp25xxfd_transmit_message(struct spi_device *spi, int fifo, ++ struct can_frame *frame) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ struct mcp25xxfd_obj_tx obj; ++ u32 flags; ++ ++ if (frame->can_dlc > 8) ++ frame->can_dlc = 8; ++ ++ priv->stats.tx_dlc_usage[frame->can_dlc]++; ++ ++ mcp25xxfd_canid_to_mcpid(frame->can_id, &obj.header.id, &flags); ++ ++ flags |= frame->can_dlc << CAN_OBJ_FLAGS_DLC_SHIFT; ++ flags |= (frame->can_id & CAN_EFF_FLAG) ? CAN_OBJ_FLAGS_IDE : 0; ++ flags |= (frame->can_id & CAN_RTR_FLAG) ? CAN_OBJ_FLAGS_RTR : 0; ++ ++ obj.header.flags = flags; ++ ++ return mcp25xxfd_transmit_message_common(spi, fifo, &obj, ++ frame->can_dlc, frame->data); ++} ++ ++static bool mcp25xxfd_is_last_txfifo(struct spi_device *spi, ++ int fifo) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ ++ return (fifo == ++ (priv->fifos.tx_fifo_start + priv->fifos.tx_fifos - 1)); ++} ++ ++static netdev_tx_t mcp25xxfd_start_xmit(struct sk_buff *skb, ++ struct net_device *net) ++{ ++ struct mcp25xxfd_priv *priv = netdev_priv(net); ++ struct spi_device *spi = priv->spi; ++ u32 pending_mask; ++ int fifo; ++ int ret; ++ ++ if (can_dropped_invalid_skb(net, skb)) ++ return NETDEV_TX_OK; ++ ++ if (priv->can.state == CAN_STATE_BUS_OFF) { ++ mcp25xxfd_stop_queue(priv->net); ++ return NETDEV_TX_BUSY; ++ } ++ ++ /* get effective mask */ ++ pending_mask = priv->fifos.tx_pending_mask | ++ priv->fifos.tx_submitted_mask; ++ ++ /* decide on fifo to assign */ ++ if (pending_mask) ++ fifo = fls(pending_mask); ++ else ++ fifo = priv->fifos.tx_fifo_start; ++ ++ /* handle error - this should not happen... */ ++ if (fifo >= priv->fifos.tx_fifo_start + priv->fifos.tx_fifos) { ++ dev_err(&spi->dev, ++ "reached tx-fifo %i, which is not valid\n", ++ fifo); ++ return NETDEV_TX_BUSY; ++ } ++ ++ /* if we are the last one, then stop the queue */ ++ if (mcp25xxfd_is_last_txfifo(spi, fifo)) ++ mcp25xxfd_stop_queue(priv->net); ++ ++ /* mark as submitted */ ++ priv->fifos.tx_submitted_mask |= BIT(fifo); ++ priv->stats.fifo_usage[fifo]++; ++ ++ /* now process it for real */ ++ if (can_is_canfd_skb(skb)) ++ ret = mcp25xxfd_transmit_fdmessage(spi, fifo, ++ (struct canfd_frame *) ++ skb->data); ++ else ++ ret = mcp25xxfd_transmit_message(spi, fifo, ++ (struct can_frame *) ++ skb->data); ++ ++ /* keep it for reference until the message really got transmitted */ ++ if (ret == NETDEV_TX_OK) ++ can_put_echo_skb(skb, priv->net, fifo); ++ ++ return ret; ++} ++ ++/* CAN RX Related */ ++ ++static int mcp25xxfd_can_transform_rx_fd(struct spi_device *spi, ++ struct mcp25xxfd_obj_rx *rx) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ struct canfd_frame *frame; ++ struct sk_buff *skb; ++ u32 flags = rx->header.flags; ++ int dlc; ++ ++ /* allocate the skb buffer */ ++ skb = alloc_canfd_skb(priv->net, &frame); ++ if (!skb) { ++ dev_err(&spi->dev, "cannot allocate RX skb\n"); ++ priv->net->stats.rx_dropped++; ++ return -ENOMEM; ++ } ++ ++ mcp25xxfd_mcpid_to_canid(rx->header.id, flags, &frame->can_id); ++ frame->flags |= (flags & CAN_OBJ_FLAGS_BRS) ? CANFD_BRS : 0; ++ frame->flags |= (flags & CAN_OBJ_FLAGS_ESI) ? CANFD_ESI : 0; ++ ++ dlc = (flags & CAN_OBJ_FLAGS_DLC_MASK) >> CAN_OBJ_FLAGS_DLC_SHIFT; ++ frame->len = can_dlc2len(dlc); ++ ++ memcpy(frame->data, rx->data, frame->len); ++ ++ priv->stats.rx_fd_count++; ++ priv->net->stats.rx_packets++; ++ priv->net->stats.rx_bytes += frame->len; ++ if (rx->header.flags & CAN_OBJ_FLAGS_BRS) ++ priv->stats.rx_brs_count++; ++ priv->stats.rx_dlc_usage[dlc]++; ++ ++ can_led_event(priv->net, CAN_LED_EVENT_RX); ++ ++ netif_rx_ni(skb); ++ ++ return 0; ++} ++ ++static int mcp25xxfd_can_transform_rx_normal(struct spi_device *spi, ++ struct mcp25xxfd_obj_rx *rx) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ struct sk_buff *skb; ++ struct can_frame *frame; ++ u32 flags = rx->header.flags; ++ int len; ++ int dlc; ++ ++ /* allocate the skb buffer */ ++ skb = alloc_can_skb(priv->net, &frame); ++ if (!skb) { ++ dev_err(&spi->dev, "cannot allocate RX skb\n"); ++ priv->net->stats.rx_dropped++; ++ return -ENOMEM; ++ } ++ ++ mcp25xxfd_mcpid_to_canid(rx->header.id, flags, &frame->can_id); ++ ++ dlc = (flags & CAN_OBJ_FLAGS_DLC_MASK) >> CAN_OBJ_FLAGS_DLC_SHIFT; ++ frame->can_dlc = dlc; ++ ++ len = can_dlc2len(frame->can_dlc); ++ ++ memcpy(frame->data, rx->data, len); ++ ++ priv->net->stats.rx_packets++; ++ priv->net->stats.rx_bytes += len; ++ priv->stats.rx_dlc_usage[dlc]++; ++ ++ can_led_event(priv->net, CAN_LED_EVENT_RX); ++ ++ netif_rx_ni(skb); ++ ++ return 0; ++} ++ ++static int mcp25xxfd_process_queued_rx(struct spi_device *spi, ++ struct mcp25xxfd_obj_ts *obj) ++{ ++ struct mcp25xxfd_obj_rx *rx = container_of(obj, ++ struct mcp25xxfd_obj_rx, ++ header); ++ ++ if (obj->flags & CAN_OBJ_FLAGS_FDF) ++ return mcp25xxfd_can_transform_rx_fd(spi, rx); ++ else ++ return mcp25xxfd_can_transform_rx_normal(spi, rx); ++} ++ ++static int mcp25xxfd_normal_release_fifos(struct spi_device *spi, ++ int start, int end) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ int ret; ++ ++ /* release each fifo in a separate transfer */ ++ for (; start < end ; start++) { ++ ret = mcp25xxfd_cmd_write_mask(spi, CAN_FIFOCON(start), ++ CAN_FIFOCON_UINC, ++ CAN_FIFOCON_UINC, ++ priv->spi_speed_hz); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++/* unfortunately the CAN_FIFOCON are not directly consecutive ++ * so the optimization of "clearing all in one spi_transfer" ++ * would produce an overhead of 11 unnecessary bytes/fifo ++ * - transferring 14 (2 cmd + 12 data) bytes ++ * instead of just 3 (2 + 1). ++ * On some slower systems this may still be beneficial, ++ * but it is not good enough for the generic case. ++ * On a Raspberry Pi CM the timings for clearing 3 fifos ++ * (at 12.5MHz SPI clock speed) are: ++ * * normal: ++ * * 3 spi transfers ++ * * 9 bytes total ++ * * 36.74us from first CS low to last CS high ++ * * individual CS: 9.14us, 5.74us and 5.16us ++ * * 77.02us from CS up of fifo transfer to last release CS up ++ * * bulk: ++ * * 1 spi transfer ++ * * 27 bytes total ++ * * 29.06us CS Low ++ * * 78.28us from CS up of fifo transfer to last release CS up ++ * this obviously varies with SPI_clock speed ++ * - the slower the clock the less efficient the optimization. ++ * similarly the faster the CPU (and bigger the code cache) the ++ * less effcient the optimization - the above case is border line. ++ */ ++ ++#define FIFOCON_SPACING (CAN_FIFOCON(1) - CAN_FIFOCON(0)) ++#define FIFOCON_SPACINGW (FIFOCON_SPACING / sizeof(u32)) ++ ++static int mcp25xxfd_bulk_release_fifos(struct spi_device *spi, ++ int start, int end) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ int i; ++ int ret; ++ ++ /* calculate start address and length */ ++ int fifos = end - start; ++ int first_byte = mcp25xxfd_first_byte(CAN_FIFOCON_UINC); ++ int addr = CAN_FIFOCON(start); ++ int len = 1 + (fifos - 1) * FIFOCON_SPACING; ++ ++ /* the worsted case buffer */ ++ u32 buf[32 * FIFOCON_SPACINGW], base; ++ ++ base = (priv->fifos.payload_mode << CAN_FIFOCON_PLSIZE_SHIFT) | ++ ((priv->fifos.rx_fifo_depth - 1) << CAN_FIFOCON_FSIZE_SHIFT) | ++ CAN_FIFOCON_RXTSEN | /* RX timestamps */ ++ CAN_FIFOCON_UINC | ++ CAN_FIFOCON_TFERFFIE | /* FIFO Full */ ++ CAN_FIFOCON_TFHRFHIE | /* FIFO Half Full*/ ++ CAN_FIFOCON_TFNRFNIE; /* FIFO not empty */ ++ ++ memset(buf, 0, sizeof(buf)); ++ for (i = 0; i < end - start ; i++) { ++ if (i == priv->fifos.rx_fifos - 1) ++ base |= CAN_FIFOCON_RXOVIE; ++ buf[FIFOCON_SPACINGW * i] = cpu_to_le32(base); ++ } ++ ++ ret = mcp25xxfd_cmd_writen(spi, addr + first_byte, ++ (u8 *)buf + first_byte, ++ len, ++ priv->spi_speed_hz); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++/* queued FIFO handling for release to system */ ++ ++static void mcp25xxfd_clear_queued_fifos(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ ++ /* prepare rfi - mostly used for sorting */ ++ priv->queued_fifos.rx_count = 0; ++} ++ ++static void mcp25xxfd_addto_queued_fifos(struct spi_device *spi, ++ struct mcp25xxfd_obj_ts *obj) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ struct mcp25xxfd_read_fifo_info *rfi = &priv->queued_fifos; ++ ++ /* timestamps must ignore the highest byte, so we shift it, ++ * so that it still compares correctly ++ */ ++ obj->ts <<= 8; ++ ++ /* add pointer to queued array-list */ ++ rfi->rxb[rfi->rx_count] = obj; ++ rfi->rx_count++; ++} ++ ++static int mcp25xxfd_process_queued_tef(struct spi_device *spi, ++ struct mcp25xxfd_obj_ts *obj) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ struct mcp25xxfd_obj_tef *tef = container_of(obj, ++ struct mcp25xxfd_obj_tef, ++ header); ++ int dlc = (obj->flags & CAN_OBJ_FLAGS_DLC_MASK) ++ >> CAN_OBJ_FLAGS_DLC_SHIFT; ++ int fifo = (tef->header.flags & CAN_OBJ_FLAGS_SEQ_MASK) >> ++ CAN_OBJ_FLAGS_SEQ_SHIFT; ++ ++ /* update counters */ ++ priv->net->stats.tx_packets++; ++ priv->net->stats.tx_bytes += can_dlc2len(dlc); ++ if (obj->flags & CAN_OBJ_FLAGS_FDF) ++ priv->stats.tx_fd_count++; ++ if (obj->flags & CAN_OBJ_FLAGS_BRS) ++ priv->stats.tx_brs_count++; ++ priv->stats.tx_dlc_usage[dlc]++; ++ ++ /* release it */ ++ can_get_echo_skb(priv->net, fifo); ++ ++ can_led_event(priv->net, CAN_LED_EVENT_TX); ++ ++ return 0; ++} ++ ++static int mcp25xxfd_compare_obj_ts(const void *a, const void *b) ++{ ++ const struct mcp25xxfd_obj_ts * const *rxa = a; ++ const struct mcp25xxfd_obj_ts * const *rxb = b; ++ /* using signed here to handle rollover correctly */ ++ s32 ats = (*rxa)->ts; ++ s32 bts = (*rxb)->ts; ++ ++ if (ats < bts) ++ return -1; ++ if (ats > bts) ++ return 1; ++ return 0; ++} ++ ++static int mcp25xxfd_process_queued_fifos(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ struct mcp25xxfd_read_fifo_info *rfi = &priv->queued_fifos; ++ int i; ++ int ret; ++ ++ /* sort the fifos (rx and TEF) by receive timestamp */ ++ sort(rfi->rxb, rfi->rx_count, sizeof(struct mcp25xxfd_obj_ts *), ++ mcp25xxfd_compare_obj_ts, NULL); ++ ++ /* process the recived fifos */ ++ for (i = 0; i < rfi->rx_count ; i++) { ++ if (rfi->rxb[i]->flags & CAN_OBJ_FLAGS_CUSTOM_ISTEF) ++ ret = mcp25xxfd_process_queued_tef(spi, rfi->rxb[i]); ++ else ++ ret = mcp25xxfd_process_queued_rx(spi, rfi->rxb[i]); ++ if (ret) ++ return ret; ++ } ++ ++ /* clear queued fifos */ ++ mcp25xxfd_clear_queued_fifos(spi); ++ ++ return 0; ++} ++ ++static int mcp25xxfd_transform_rx(struct spi_device *spi, ++ struct mcp25xxfd_obj_rx *rx) ++{ ++ int dlc; ++ ++ /* transform the data to system byte order */ ++ mcp25xxfd_obj_ts_from_le(&rx->header); ++ ++ /* add the object to the list */ ++ mcp25xxfd_addto_queued_fifos(spi, &rx->header); ++ ++ /* calc length and return it */ ++ dlc = (rx->header.flags & CAN_OBJ_FLAGS_DLC_MASK) ++ >> CAN_OBJ_FLAGS_DLC_SHIFT; ++ return can_dlc2len(dlc); ++} ++ ++/* read_fifo implementations ++ * ++ * read_fifos is a simple implementation, that: ++ * * loops all fifos ++ * * read header + some data-bytes (8) ++ * * read rest of data-bytes bytes ++ * * release fifo ++ * for 3 can frames dlc<=8 to read here we have: ++ * * 6 spi transfers ++ * * 75 bytes (= 3 * (2 + 12 + 8) bytes + 3 * 3 bytes) ++ * for 3 canfd frames dlc>8 to read here we have: ++ * * 9 spi transfers ++ * * 81 (= 3 * (2 + 12 + 8 + 2) bytes + 3 * 3 bytes) + 3 * extra payload ++ * this only transfers the required size of bytes on the spi bus. ++ * ++ * bulk_read_fifos is an optimization that is most practical for ++ * Can2.0 busses, but may also be practical for CanFD busses that ++ * have a high average payload data size. ++ * ++ * It will read all of the fifo data in a single spi_transfer: ++ * * read all fifos in one go (as long as these are ajacent to each other) ++ * * loop all fifos ++ * * release fifo ++ * for 3 can2.0 frames to read here we have: ++ * * 4 spi transfers ++ * * 71 bytes (= 2 + 3 * (12 + 8) bytes + 3 * 3 bytes) ++ * for 3 canfd frames to read here we have: ++ * * 4 spi transfers ++ * * 230 bytes (= 2 + 3 * (12 + 64) bytes) ++ * obviously this reads way too many bytes for framesizes <=32 bytes, ++ * but it avoids the overhead on the CPU side and may even trigger ++ * DMA transfers due to the high byte count, which release CPU cycles. ++ * ++ * This optimization will also be efficient for cases where a high ++ * percentage of canFD frames has a dlc-size > 8. ++ * This mode is used for Can2.0 configured busses. ++ * ++ * For now this option can get forced for CanFD via a module parameter. ++ * In the future there may be some heuristics that could trigger a usage ++ * of this mode as well in some circumstances. ++ * ++ * Note: there is a second optimization for release fifo as well, ++ * but it is not as efficient as this optimization for the ++ * non-CanFD case - see mcp25xxfd_bulk_release_fifos ++ */ ++ ++static int mcp25xxfd_read_fifos(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ int fifo_header_size = sizeof(struct mcp25xxfd_obj_rx); ++ int fifo_min_payload_size = 8; ++ int fifo_min_size = fifo_header_size + fifo_min_payload_size; ++ int fifo_max_payload_size = ++ ((priv->can.ctrlmode & CAN_CTRLMODE_FD) ? 64 : 8); ++ u32 mask = priv->status.rxif; ++ struct mcp25xxfd_obj_rx *rx; ++ int i, len; ++ int ret; ++ u32 fifo_address; ++ u8 *data; ++ ++ /* read all the "open" segments in big chunks */ ++ for (i = priv->fifos.rx_fifo_start + priv->fifos.rx_fifos - 1; ++ i >= priv->fifos.rx_fifo_start; ++ i--) { ++ if (!(mask & BIT(i))) ++ continue; ++ /* the fifo to fill */ ++ rx = (struct mcp25xxfd_obj_rx *) ++ (priv->fifos.fifo_data + priv->fifos.fifo_address[i]); ++ /* read the minimal payload */ ++ fifo_address = priv->fifos.fifo_address[i]; ++ ret = mcp25xxfd_cmd_readn(spi, ++ FIFO_DATA(fifo_address), ++ rx, ++ fifo_min_size, ++ priv->spi_speed_hz); ++ if (ret) ++ return ret; ++ /* process fifo stats and get length */ ++ len = min_t(int, mcp25xxfd_transform_rx(spi, rx), ++ fifo_max_payload_size); ++ ++ /* read extra payload if needed */ ++ if (len > fifo_min_payload_size) { ++ data = &rx->data[fifo_min_payload_size]; ++ ret = mcp25xxfd_cmd_readn(spi, ++ FIFO_DATA(fifo_address + ++ fifo_min_size), ++ data, ++ len - fifo_min_payload_size, ++ priv->spi_speed_hz); ++ if (ret) ++ return ret; ++ } ++ /* release fifo */ ++ ret = mcp25xxfd_normal_release_fifos(spi, i, i + 1); ++ if (ret) ++ return ret; ++ /* increment fifo_usage */ ++ priv->stats.fifo_usage[i]++; ++ } ++ ++ return 0; ++} ++ ++static int mcp25xxfd_bulk_read_fifo_range(struct spi_device *spi, ++ int start, int end) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ const int fifo_header_size = sizeof(struct mcp25xxfd_obj_rx); ++ const int fifo_max_payload_size = priv->fifos.payload_size; ++ const int fifo_max_size = fifo_header_size + fifo_max_payload_size; ++ struct mcp25xxfd_obj_rx *rx; ++ int i; ++ int ret; ++ ++ /* now we got start and end, so read the range */ ++ ret = mcp25xxfd_cmd_readn(spi, ++ FIFO_DATA(priv->fifos.fifo_address[start]), ++ priv->fifos.fifo_data + ++ priv->fifos.fifo_address[start], ++ (end - start) * fifo_max_size, ++ priv->spi_speed_hz); ++ if (ret) ++ return ret; ++ ++ /* clear all the fifos in range */ ++ if (use_bulk_release_fifos) ++ ret = mcp25xxfd_bulk_release_fifos(spi, start, end); ++ else ++ ret = mcp25xxfd_normal_release_fifos(spi, start, end); ++ if (ret) ++ return ret; ++ ++ /* preprocess data */ ++ for (i = start; i < end ; i++) { ++ /* store the fifo to process */ ++ rx = (struct mcp25xxfd_obj_rx *) ++ (priv->fifos.fifo_data + priv->fifos.fifo_address[i]); ++ /* process fifo stats */ ++ mcp25xxfd_transform_rx(spi, rx); ++ /* increment usage */ ++ priv->stats.fifo_usage[i]++; ++ } ++ ++ return 0; ++} ++ ++static int mcp25xxfd_bulk_read_fifos(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ u32 mask = priv->status.rxif; ++ int i, start, end; ++ int ret; ++ ++ /* find blocks of set bits top down */ ++ for (i = priv->fifos.rx_fifo_start + priv->fifos.rx_fifos - 1; ++ mask && (i >= priv->fifos.rx_fifo_start); ++ i--) { ++ /* if the bit is 0 then continue loop to find a 1 */ ++ if ((mask & BIT(i)) == 0) ++ continue; ++ ++ /* so we found a non-0 bit - this is start and end */ ++ start = i; ++ end = i; ++ ++ /* find the first bit set */ ++ for (; mask & BIT(i); i--) { ++ mask &= ~BIT(i); ++ start = i; ++ } ++ ++ /* now process that range */ ++ ret = mcp25xxfd_bulk_read_fifo_range(spi, start, end + 1); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int mcp25xxfd_can_ist_handle_rxif(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ u32 mask = priv->status.rxif; ++ int ret; ++ ++ if (!mask) ++ return 0; ++ ++ /* read all the fifos - for non-fd case use bulk read optimization */ ++ if (((priv->can.ctrlmode & CAN_CTRLMODE_FD) == 0) || ++ use_complete_fdfifo_read) ++ ret = mcp25xxfd_bulk_read_fifos(spi); ++ else ++ ret = mcp25xxfd_read_fifos(spi); ++ ++ return 0; ++} ++ ++static void mcp25xxfd_mark_tx_processed(struct spi_device *spi, ++ int fifo) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ ++ /* set mask */ ++ priv->fifos.tx_processed_mask |= BIT(fifo); ++ ++ /* check if we should reenable the TX-queue */ ++ if (mcp25xxfd_is_last_txfifo(spi, fifo)) ++ priv->tx_queue_status = TX_QUEUE_STATUS_NEEDS_START; ++} ++ ++static int mcp25xxfd_can_ist_handle_tefif_handle_single(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ struct mcp25xxfd_obj_tef *tef; ++ int fifo; ++ int ret; ++ ++ /* calc address in address space */ ++ tef = (struct mcp25xxfd_obj_tef *)(priv->fifos.fifo_data + ++ priv->fifos.tef_address); ++ ++ /* read all the object data */ ++ ret = mcp25xxfd_cmd_readn(spi, ++ FIFO_DATA(priv->fifos.tef_address), ++ tef, ++ /* we do not read the last byte of the ts ++ * to avoid MAB issiues ++ */ ++ sizeof(*tef) - 1, ++ priv->spi_speed_hz); ++ /* increment the counter to read next */ ++ ret = mcp25xxfd_cmd_write_mask(spi, ++ CAN_TEFCON, ++ CAN_TEFCON_UINC, ++ CAN_TEFCON_UINC, ++ priv->spi_speed_hz); ++ ++ /* transform the data to system byte order */ ++ mcp25xxfd_obj_ts_from_le(&tef->header); ++ ++ fifo = (tef->header.flags & CAN_OBJ_FLAGS_SEQ_MASK) >> ++ CAN_OBJ_FLAGS_SEQ_SHIFT; ++ ++ /* submit to queue */ ++ tef->header.flags |= CAN_OBJ_FLAGS_CUSTOM_ISTEF; ++ mcp25xxfd_addto_queued_fifos(spi, &tef->header); ++ ++ /* increment tef_address with rollover */ ++ priv->fifos.tef_address += sizeof(*tef); ++ if (priv->fifos.tef_address > priv->fifos.tef_address_end) ++ priv->fifos.tef_address = ++ priv->fifos.tef_address_start; ++ ++ /* and mark as processed right now */ ++ mcp25xxfd_mark_tx_processed(spi, fifo); ++ ++ return 0; ++} ++ ++static int mcp25xxfd_can_ist_handle_tefif_conservative(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ u32 val[2]; ++ int ret; ++ ++ while (1) { ++ /* get the current TEFSTA and TEFUA */ ++ ret = mcp25xxfd_cmd_readn(priv->spi, ++ CAN_TEFSTA, ++ val, ++ 8, ++ priv->spi_speed_hz); ++ if (ret) ++ return ret; ++ mcp25xxfd_convert_to_cpu(val, 2); ++ ++ /* check for interrupt flags */ ++ if (!(val[0] & CAN_TEFSTA_TEFNEIF)) ++ return 0; ++ ++ if (priv->fifos.tef_address != val[1]) { ++ dev_err(&spi->dev, ++ "TEF Address mismatch - read: %04x calculated: %04x\n", ++ val[1], priv->fifos.tef_address); ++ priv->fifos.tef_address = val[1]; ++ } ++ ++ ret = mcp25xxfd_can_ist_handle_tefif_handle_single(spi); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int mcp25xxfd_can_ist_handle_tefif_count(struct spi_device *spi, ++ int count) ++{ ++ int i; ++ int ret; ++ ++ /* now clear TEF for each */ ++ /* TODO: optimize for BULK reads, as we (hopefully) know COUNT */ ++ for (i = 0; i < count; i++) { ++ /* handle a single TEF */ ++ ret = mcp25xxfd_can_ist_handle_tefif_handle_single(spi); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int mcp25xxfd_can_ist_handle_tefif(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ u32 pending = priv->fifos.tx_pending_mask_in_irq & ++ (~priv->fifos.tx_processed_mask); ++ int count; ++ ++ /* calculate the number of fifos that have been processed */ ++ count = hweight_long(pending); ++ count -= hweight_long(priv->status.txreq & pending); ++ ++ /* in case of unexpected results handle "safely" */ ++ if (count <= 0) ++ return mcp25xxfd_can_ist_handle_tefif_conservative(spi); ++ ++ return mcp25xxfd_can_ist_handle_tefif_count(spi, count); ++} ++ ++static int mcp25xxfd_can_ist_handle_txatif_fifo(struct spi_device *spi, ++ int fifo) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ u32 val; ++ int ret; ++ ++ /* read fifo status */ ++ ret = mcp25xxfd_cmd_read(spi, ++ CAN_FIFOSTA(fifo), ++ &val, ++ priv->spi_speed_hz); ++ if (ret) ++ return ret; ++ ++ /* clear the relevant interrupt flags */ ++ ret = mcp25xxfd_cmd_write_mask(spi, ++ CAN_FIFOSTA(fifo), ++ 0, ++ CAN_FIFOSTA_TXABT | ++ CAN_FIFOSTA_TXLARB | ++ CAN_FIFOSTA_TXERR | ++ CAN_FIFOSTA_TXATIF, ++ priv->spi_speed_hz); ++ ++ /* for specific cases we could trigger a retransmit ++ * instead of an abort. ++ */ ++ ++ /* and we release it from the echo_skb buffer ++ * NOTE: this is one place where packet delivery will not ++ * be ordered, as we do not have any timing information ++ * when this occurred ++ */ ++ can_get_echo_skb(priv->net, fifo); ++ ++ /* but we need to run a bit of cleanup */ ++ priv->status.txif &= ~BIT(fifo); ++ priv->net->stats.tx_aborted_errors++; ++ ++ /* mark the fifo as processed */ ++ mcp25xxfd_mark_tx_processed(spi, fifo); ++ ++ /* handle all the known cases accordingly - ignoring FIFO full */ ++ val &= CAN_FIFOSTA_TXABT | ++ CAN_FIFOSTA_TXLARB | ++ CAN_FIFOSTA_TXERR; ++ switch (val) { ++ case CAN_FIFOSTA_TXERR: ++ break; ++ default: ++ dev_warn_ratelimited(&spi->dev, ++ "Unknown TX-Fifo abort condition: %08x - stopping tx-queue\n", ++ val); ++ break; ++ } ++ ++ return 0; ++} ++ ++static int mcp25xxfd_can_ist_handle_txatif(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ int i, fifo; ++ int ret; ++ ++ /* process all the fifos with that flag set */ ++ for (i = 0, fifo = priv->fifos.tx_fifo_start; ++ i < priv->fifos.tx_fifos; i++, fifo++) { ++ if (priv->status.txatif & BIT(fifo)) { ++ ret = mcp25xxfd_can_ist_handle_txatif_fifo(spi, fifo); ++ if (ret) ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ ++static void mcp25xxfd_error_skb(struct net_device *net) ++{ ++ struct mcp25xxfd_priv *priv = netdev_priv(net); ++ struct sk_buff *skb; ++ struct can_frame *frame; ++ ++ skb = alloc_can_err_skb(net, &frame); ++ if (skb) { ++ frame->can_id = priv->can_err_id; ++ memcpy(frame->data, priv->can_err_data, 8); ++ netif_rx_ni(skb); ++ } else { ++ netdev_err(net, "cannot allocate error skb\n"); ++ } ++} ++ ++static int mcp25xxfd_can_ist_handle_rxovif(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ u32 mask = priv->status.rxovif; ++ int i; ++ int ret; ++ ++ /* clear all fifos that have an overflow bit set */ ++ for (i = 0; i < 32; i++) { ++ if (mask & BIT(i)) { ++ ret = mcp25xxfd_cmd_write_mask(spi, ++ CAN_FIFOSTA(i), ++ 0, ++ CAN_FIFOSTA_RXOVIF, ++ priv->spi_speed_hz); ++ if (ret) ++ return ret; ++ /* update statistics */ ++ priv->net->stats.rx_over_errors++; ++ priv->net->stats.rx_errors++; ++ priv->stats.rx_overflow++; ++ priv->can_err_id |= CAN_ERR_CRTL; ++ priv->can_err_data[1] |= CAN_ERR_CRTL_RX_OVERFLOW; ++ } ++ } ++ ++ return 0; ++} ++ ++static int mcp25xxfd_can_ist_handle_modif(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ int omode = priv->active_can_mode; ++ int mode; ++ int ret; ++ ++ /* Note that this irq does not get triggered in all situations ++ * for example SERRIF will move to RESTICTED or LISTENONLY ++ * but MODIF will not be raised! ++ */ ++ ++ /* get the mode */ ++ ret = mcp25xxfd_get_opmode(spi, &mode, priv->spi_speed_hz); ++ if (ret) ++ return ret; ++ ++ /* if we are restricted, then return to "normal" mode */ ++ if (mode == CAN_CON_MODE_RESTRICTED) ++ return mcp25xxfd_set_normal_opmode(spi); ++ ++ /* the controller itself will transition to sleep, so we ignore it */ ++ if (mode == CAN_CON_MODE_SLEEP) ++ return 0; ++ ++ /* switches to the same mode as before are also ignored ++ * - this typically happens if the driver is shortly ++ * switching to a different mode and then returning to the ++ * original mode ++ */ ++ if (mode == omode) ++ return 0; ++ ++ /* these we need to handle correctly, so warn and give context */ ++ dev_warn(&spi->dev, ++ "Controller unexpectedly switched from mode %s(%u) to %s(%u)\n", ++ mcp25xxfd_mode_names[omode], omode, ++ mcp25xxfd_mode_names[mode], mode); ++ ++ return 0; ++} ++ ++static int mcp25xxfd_can_ist_handle_cerrif(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ ++ /* in principle we could also delay reading bdiag registers ++ * until we get here - it would add some extra delay in the ++ * error case, but be slightly faster in the "normal" case. ++ * slightly faster would be saving 8 bytes of spi transfer. ++ */ ++ ++ dev_err_ratelimited(&spi->dev, "CAN Bus error\n"); ++ priv->can_err_id |= CAN_ERR_BUSERROR; ++ ++ if (priv->status.bdiag1 & ++ (CAN_BDIAG1_DBIT0ERR | CAN_BDIAG1_NBIT0ERR)) { ++ priv->can_err_id |= CAN_ERR_BUSERROR; ++ priv->can_err_data[2] |= CAN_ERR_PROT_BIT0; ++ priv->bdiag1_clear_mask |= CAN_BDIAG1_DBIT0ERR | ++ CAN_BDIAG1_NBIT0ERR; ++ } ++ if (priv->status.bdiag1 & ++ (CAN_BDIAG1_DBIT1ERR | CAN_BDIAG1_NBIT1ERR)) { ++ priv->can_err_id |= CAN_ERR_BUSERROR; ++ priv->can_err_data[2] |= CAN_ERR_PROT_BIT1; ++ priv->bdiag1_clear_mask |= CAN_BDIAG1_DBIT1ERR | ++ CAN_BDIAG1_NBIT1ERR; ++ } ++ if (priv->status.bdiag1 & ++ (CAN_BDIAG1_DSTUFERR | CAN_BDIAG1_NSTUFERR)) { ++ priv->can_err_id |= CAN_ERR_BUSERROR; ++ priv->can_err_data[2] |= CAN_ERR_PROT_STUFF; ++ priv->bdiag1_clear_mask |= CAN_BDIAG1_DSTUFERR | ++ CAN_BDIAG1_NSTUFERR; ++ } ++ if (priv->status.bdiag1 & ++ (CAN_BDIAG1_DFORMERR | CAN_BDIAG1_NFORMERR)) { ++ priv->can_err_id |= CAN_ERR_BUSERROR; ++ priv->can_err_data[2] |= CAN_ERR_PROT_FORM; ++ priv->bdiag1_clear_mask |= CAN_BDIAG1_DFORMERR | ++ CAN_BDIAG1_NFORMERR; ++ } ++ if (priv->status.bdiag1 & CAN_BDIAG1_NACKERR) { ++ priv->can_err_id |= CAN_ERR_ACK; ++ priv->bdiag1_clear_mask |= CAN_BDIAG1_NACKERR; ++ } ++ ++ return 0; ++} ++ ++static int mcp25xxfd_can_ist_handle_eccif(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ int ret; ++ u32 val; ++ u32 addr; ++ ++ priv->can_err_id |= CAN_ERR_CRTL; ++ priv->can_err_data[1] |= CAN_ERR_CRTL_UNSPEC; ++ ++ /* read ECC status register */ ++ ret = mcp25xxfd_cmd_read(spi, MCP25XXFD_ECCSTAT, &val, ++ priv->spi_speed_hz); ++ if (ret) ++ return ret; ++ ++ addr = (val & MCP25XXFD_ECCSTAT_ERRADDR_MASK) >> ++ MCP25XXFD_ECCSTAT_ERRADDR_SHIFT; ++ ++ dev_err_ratelimited(&spi->dev, ++ "ECC %s bit error at %03x\n", ++ (val & MCP25XXFD_ECCSTAT_DEDIF) ? ++ "double" : "single", ++ addr); ++ ++ return mcp25xxfd_cmd_write(spi, MCP25XXFD_ECCSTAT, 0, ++ priv->spi_speed_hz); ++} ++ ++static int mcp25xxfd_can_ist_handle_serrif_txmab(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ ++ priv->net->stats.tx_fifo_errors++; ++ priv->net->stats.tx_errors++; ++ priv->stats.tx_mab++; ++ ++ return 0; ++} ++ ++static int mcp25xxfd_can_ist_handle_serrif_rxmab(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ ++ priv->net->stats.rx_dropped++; ++ priv->net->stats.rx_errors++; ++ priv->stats.rx_mab++; ++ ++ return 0; ++} ++ ++static int mcp25xxfd_can_ist_handle_serrif(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ u32 clear; ++ int ret; ++ ++ /* clear some interrupts immediately, ++ * so that we get notified if they happen again ++ */ ++ clear = CAN_INT_SERRIF | CAN_INT_MODIF | CAN_INT_IVMIF; ++ ret = mcp25xxfd_cmd_write_mask(spi, CAN_INT, ++ priv->status.intf & (~clear), ++ clear, ++ priv->spi_speed_hz); ++ if (ret) ++ return ret; ++ ++ /* Errors here are: ++ * * Bus Bandwidth Error: when a RX Message Assembly Buffer ++ * is still full when the next message has already arrived ++ * the recived message shall be ignored ++ * * TX MAB Underflow: when a TX Message is invalid ++ * due to ECC errors or TXMAB underflow ++ * in this situatioon the system will transition to ++ * Restricted or Listen Only mode ++ */ ++ ++ priv->can_err_id |= CAN_ERR_CRTL; ++ priv->can_err_data[1] |= CAN_ERR_CRTL_UNSPEC; ++ ++ /* a mode change + invalid message would indicate ++ * TX MAB Underflow ++ */ ++ if ((priv->status.intf & CAN_INT_MODIF) && ++ (priv->status.intf & CAN_INT_IVMIF)) { ++ return mcp25xxfd_can_ist_handle_serrif_txmab(spi); ++ } ++ ++ /* for RX there is only the RXIF an indicator ++ * - surprizingly RX-MAB does not change mode or anything ++ */ ++ if (priv->status.intf & CAN_INT_RXIF) ++ return mcp25xxfd_can_ist_handle_serrif_rxmab(spi); ++ ++ /* the final case */ ++ dev_warn_ratelimited(&spi->dev, ++ "unidentified system error - intf = %08x\n", ++ priv->status.intf); ++ ++ return 0; ++} ++ ++static int mcp25xxfd_can_ist_handle_ivmif(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ ++ /* if we have a systemerror as well, then ignore it */ ++ if (priv->status.intf & CAN_INT_SERRIF) ++ return 0; ++ ++ /* otherwise it is an RX issue, so account for it here */ ++ priv->can_err_id |= CAN_ERR_PROT; ++ priv->can_err_data[2] |= CAN_ERR_PROT_FORM; ++ priv->net->stats.rx_frame_errors++; ++ priv->net->stats.rx_errors++; ++ ++ return 0; ++} ++ ++static int mcp25xxfd_disable_interrupts(struct spi_device *spi, ++ u32 speed_hz) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ ++ priv->status.intf = 0; ++ return mcp25xxfd_cmd_write(spi, CAN_INT, 0, speed_hz); ++} ++ ++static int mcp25xxfd_enable_interrupts(struct spi_device *spi, ++ u32 speed_hz) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ ++ priv->status.intf = CAN_INT_TEFIE | ++ CAN_INT_RXIE | ++ CAN_INT_MODIE | ++ CAN_INT_SERRIE | ++ CAN_INT_IVMIE | ++ CAN_INT_CERRIE | ++ CAN_INT_RXOVIE | ++ CAN_INT_ECCIE; ++ return mcp25xxfd_cmd_write(spi, CAN_INT, ++ priv->status.intf, ++ speed_hz); ++} ++ ++static int mcp25xxfd_hw_wake(struct spi_device *spi) ++{ ++ return mcp25xxfd_start_clock(spi, MCP25XXFD_CLK_USER_CAN); ++} ++ ++static void mcp25xxfd_hw_sleep(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ ++ /* disable interrupts */ ++ mcp25xxfd_disable_interrupts(spi, priv->spi_setup_speed_hz); ++ ++ /* stop the clocks */ ++ mcp25xxfd_stop_clock(spi, MCP25XXFD_CLK_USER_CAN); ++} ++ ++static int mcp25xxfd_can_ist_handle_status(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ const u32 clear_irq = CAN_INT_TBCIF | ++ CAN_INT_MODIF | ++ CAN_INT_SERRIF | ++ CAN_INT_CERRIF | ++ CAN_INT_WAKIF | ++ CAN_INT_IVMIF; ++ int ret; ++ ++ /* clear all the interrupts asap */ ++ ret = mcp25xxfd_cmd_write_mask(spi, CAN_INT, ++ priv->status.intf & (~clear_irq), ++ clear_irq, ++ priv->spi_speed_hz); ++ if (ret) ++ return ret; ++ ++ /* interrupt clearing info */ ++ priv->bdiag1_clear_value = 0; ++ priv->bdiag1_clear_mask = 0; ++ priv->can_err_id = 0; ++ memset(priv->can_err_data, 0, 8); ++ ++ /* state changes */ ++ priv->new_state = priv->can.state; ++ ++ /* clear queued fifos */ ++ mcp25xxfd_clear_queued_fifos(spi); ++ ++ /* system error interrupt needs to get handled first ++ * to get us out of restricted mode ++ */ ++ if (priv->status.intf & CAN_INT_SERRIF) { ++ priv->stats.int_serr_count++; ++ ret = mcp25xxfd_can_ist_handle_serrif(spi); ++ if (ret) ++ return ret; ++ } ++ ++ /* mode change interrupt */ ++ if (priv->status.intf & CAN_INT_MODIF) { ++ priv->stats.int_mod_count++; ++ ret = mcp25xxfd_can_ist_handle_modif(spi); ++ if (ret) ++ return ret; ++ } ++ ++ /* handle the rx */ ++ if (priv->status.intf & CAN_INT_RXIF) { ++ priv->stats.int_rx_count++; ++ ret = mcp25xxfd_can_ist_handle_rxif(spi); ++ if (ret) ++ return ret; ++ } ++ ++ /* handle aborted TX FIFOs */ ++ if (priv->status.txatif) { ++ priv->stats.int_txat_count++; ++ ret = mcp25xxfd_can_ist_handle_txatif(spi); ++ if (ret) ++ return ret; ++ } ++ ++ /* handle the tef */ ++ if (priv->status.intf & CAN_INT_TEFIF) { ++ priv->stats.int_tef_count++; ++ ret = mcp25xxfd_can_ist_handle_tefif(spi); ++ if (ret) ++ return ret; ++ } ++ ++ /* process the queued fifos */ ++ ret = mcp25xxfd_process_queued_fifos(spi); ++ ++ /* handle error interrupt flags */ ++ if (priv->status.rxovif) { ++ priv->stats.int_rxov_count++; ++ ret = mcp25xxfd_can_ist_handle_rxovif(spi); ++ if (ret) ++ return ret; ++ } ++ ++ /* sram ECC error interrupt */ ++ if (priv->status.intf & CAN_INT_ECCIF) { ++ priv->stats.int_ecc_count++; ++ ret = mcp25xxfd_can_ist_handle_eccif(spi); ++ if (ret) ++ return ret; ++ } ++ ++ /* message format interrupt */ ++ if (priv->status.intf & CAN_INT_IVMIF) { ++ priv->stats.int_ivm_count++; ++ ret = mcp25xxfd_can_ist_handle_ivmif(spi); ++ if (ret) ++ return ret; ++ } ++ ++ /* handle bus errors in more detail */ ++ if (priv->status.intf & CAN_INT_CERRIF) { ++ priv->stats.int_cerr_count++; ++ ret = mcp25xxfd_can_ist_handle_cerrif(spi); ++ if (ret) ++ return ret; ++ } ++ ++ /* Error counter handling */ ++ if (priv->status.trec & CAN_TREC_TXWARN) { ++ priv->new_state = CAN_STATE_ERROR_WARNING; ++ priv->can_err_id |= CAN_ERR_CRTL; ++ priv->can_err_data[1] |= CAN_ERR_CRTL_TX_WARNING; ++ } ++ if (priv->status.trec & CAN_TREC_RXWARN) { ++ priv->new_state = CAN_STATE_ERROR_WARNING; ++ priv->can_err_id |= CAN_ERR_CRTL; ++ priv->can_err_data[1] |= CAN_ERR_CRTL_RX_WARNING; ++ } ++ if (priv->status.trec & CAN_TREC_TXBP) { ++ priv->new_state = CAN_STATE_ERROR_PASSIVE; ++ priv->can_err_id |= CAN_ERR_CRTL; ++ priv->can_err_data[1] |= CAN_ERR_CRTL_TX_PASSIVE; ++ } ++ if (priv->status.trec & CAN_TREC_RXBP) { ++ priv->new_state = CAN_STATE_ERROR_PASSIVE; ++ priv->can_err_id |= CAN_ERR_CRTL; ++ priv->can_err_data[1] |= CAN_ERR_CRTL_RX_PASSIVE; ++ } ++ if (priv->status.trec & CAN_TREC_TXBO) { ++ priv->new_state = CAN_STATE_BUS_OFF; ++ priv->can_err_id |= CAN_ERR_BUSOFF; ++ } ++ ++ /* based on the last state state check the new state */ ++ switch (priv->can.state) { ++ case CAN_STATE_ERROR_ACTIVE: ++ if (priv->new_state >= CAN_STATE_ERROR_WARNING && ++ priv->new_state <= CAN_STATE_BUS_OFF) ++ priv->can.can_stats.error_warning++; ++ /* fallthrough */ ++ case CAN_STATE_ERROR_WARNING: ++ if (priv->new_state >= CAN_STATE_ERROR_PASSIVE && ++ priv->new_state <= CAN_STATE_BUS_OFF) ++ priv->can.can_stats.error_passive++; ++ break; ++ default: ++ break; ++ } ++ priv->can.state = priv->new_state; ++ ++ /* and send error packet */ ++ if (priv->can_err_id) ++ mcp25xxfd_error_skb(priv->net); ++ ++ /* handle BUS OFF */ ++ if (priv->can.state == CAN_STATE_BUS_OFF) { ++ if (priv->can.restart_ms == 0) { ++ mcp25xxfd_stop_queue(priv->net); ++ priv->force_quit = 1; ++ priv->can.can_stats.bus_off++; ++ can_bus_off(priv->net); ++ mcp25xxfd_hw_sleep(spi); ++ } ++ } else { ++ /* restart the tx queue if needed */ ++ if (priv->fifos.tx_processed_mask == priv->fifos.tx_fifo_mask) ++ mcp25xxfd_wake_queue(spi); ++ } ++ ++ /* clear bdiag flags */ ++ if (priv->bdiag1_clear_mask) { ++ ret = mcp25xxfd_cmd_write_mask(spi, ++ CAN_BDIAG1, ++ priv->bdiag1_clear_value, ++ priv->bdiag1_clear_mask, ++ priv->spi_speed_hz); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static irqreturn_t mcp25xxfd_can_ist(int irq, void *dev_id) ++{ ++ struct mcp25xxfd_priv *priv = dev_id; ++ struct spi_device *spi = priv->spi; ++ int ret; ++ ++ priv->stats.irq_calls++; ++ priv->stats.irq_state = IRQ_STATE_RUNNING; ++ ++ while (!priv->force_quit) { ++ /* count irq loops */ ++ priv->stats.irq_loops++; ++ ++ /* copy pending to in_irq - any ++ * updates that happen asyncronously ++ * are not taken into account here ++ */ ++ priv->fifos.tx_pending_mask_in_irq = ++ priv->fifos.tx_pending_mask; ++ ++ /* read interrupt status flags */ ++ ret = mcp25xxfd_cmd_readn(spi, CAN_INT, ++ &priv->status, ++ sizeof(priv->status), ++ priv->spi_speed_hz); ++ if (ret) ++ return ret; ++ ++ /* only act if the mask is applied */ ++ if ((priv->status.intf & ++ (priv->status.intf >> CAN_INT_IE_SHIFT)) == 0) ++ break; ++ ++ /* handle the status */ ++ ret = mcp25xxfd_can_ist_handle_status(spi); ++ if (ret) ++ return ret; ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static int mcp25xxfd_get_berr_counter(const struct net_device *net, ++ struct can_berr_counter *bec) ++{ ++ struct mcp25xxfd_priv *priv = netdev_priv(net); ++ ++ bec->txerr = (priv->status.trec & CAN_TREC_TEC_MASK) >> ++ CAN_TREC_TEC_SHIFT; ++ bec->rxerr = (priv->status.trec & CAN_TREC_REC_MASK) >> ++ CAN_TREC_REC_SHIFT; ++ ++ return 0; ++} ++ ++static int mcp25xxfd_power_enable(struct regulator *reg, int enable) ++{ ++ if (IS_ERR_OR_NULL(reg)) ++ return 0; ++ ++ if (enable) ++ return regulator_enable(reg); ++ else ++ return regulator_disable(reg); ++} ++ ++static int mcp25xxfd_do_set_mode(struct net_device *net, enum can_mode mode) ++{ ++ switch (mode) { ++ case CAN_MODE_START: ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ return 0; ++} ++ ++static int mcp25xxfd_do_set_nominal_bittiming(struct net_device *net) ++{ ++ struct mcp25xxfd_priv *priv = netdev_priv(net); ++ struct can_bittiming *bt = &priv->can.bittiming; ++ struct spi_device *spi = priv->spi; ++ ++ int sjw = bt->sjw; ++ int pseg2 = bt->phase_seg2; ++ int pseg1 = bt->phase_seg1; ++ int propseg = bt->prop_seg; ++ int brp = bt->brp; ++ ++ int tseg1 = propseg + pseg1; ++ int tseg2 = pseg2; ++ ++ /* calculate nominal bit timing */ ++ priv->regs.nbtcfg = ((sjw - 1) << CAN_NBTCFG_SJW_SHIFT) | ++ ((tseg2 - 1) << CAN_NBTCFG_TSEG2_SHIFT) | ++ ((tseg1 - 1) << CAN_NBTCFG_TSEG1_SHIFT) | ++ ((brp - 1) << CAN_NBTCFG_BRP_SHIFT); ++ ++ return mcp25xxfd_cmd_write(spi, CAN_NBTCFG, ++ priv->regs.nbtcfg, ++ priv->spi_setup_speed_hz); ++} ++ ++static int mcp25xxfd_do_set_data_bittiming(struct net_device *net) ++{ ++ struct mcp25xxfd_priv *priv = netdev_priv(net); ++ struct can_bittiming *bt = &priv->can.data_bittiming; ++ struct spi_device *spi = priv->spi; ++ ++ int sjw = bt->sjw; ++ int pseg2 = bt->phase_seg2; ++ int pseg1 = bt->phase_seg1; ++ int propseg = bt->prop_seg; ++ int brp = bt->brp; ++ ++ int tseg1 = propseg + pseg1; ++ int tseg2 = pseg2; ++ ++ int ret; ++ ++ /* set up Transmitter delay compensation */ ++ if (!priv->regs.tdc) ++ priv->regs.tdc = CAN_TDC_EDGFLTEN | ++ (CAN_TDC_TDCMOD_AUTO << CAN_TDC_TDCMOD_SHIFT); ++ ret = mcp25xxfd_cmd_write(spi, CAN_TDC, priv->regs.tdc, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ ++ /* calculate nominal bit timing */ ++ priv->regs.dbtcfg = ((sjw - 1) << CAN_DBTCFG_SJW_SHIFT) | ++ ((tseg2 - 1) << CAN_DBTCFG_TSEG2_SHIFT) | ++ ((tseg1 - 1) << CAN_DBTCFG_TSEG1_SHIFT) | ++ ((brp - 1) << CAN_DBTCFG_BRP_SHIFT); ++ ++ return mcp25xxfd_cmd_write(spi, CAN_DBTCFG, ++ priv->regs.dbtcfg, ++ priv->spi_setup_speed_hz); ++} ++ ++static int mcp25xxfd_hw_probe(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ int ret; ++ ++ /* Wait for oscillator startup timer after power up */ ++ mdelay(MCP25XXFD_OST_DELAY_MS); ++ ++ /* send a "blind" reset, hoping we are in Config mode */ ++ mcp25xxfd_cmd_reset(spi, priv->spi_setup_speed_hz); ++ ++ /* Wait for oscillator startup again */ ++ mdelay(MCP25XXFD_OST_DELAY_MS); ++ ++ /* check clock register that the clock is ready or disabled */ ++ ret = mcp25xxfd_cmd_read(spi, MCP25XXFD_OSC, ++ &priv->regs.osc, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ ++ /* there can only be one... */ ++ switch (priv->regs.osc & ++ (MCP25XXFD_OSC_OSCRDY | MCP25XXFD_OSC_OSCDIS)) { ++ case MCP25XXFD_OSC_OSCRDY: /* either the clock is ready */ ++ break; ++ case MCP25XXFD_OSC_OSCDIS: /* or the clock is disabled */ ++ /* wakeup sleeping system */ ++ ret = mcp25xxfd_wake_from_sleep(spi); ++ if (ret) ++ return ret; ++ /* send a reset, hoping we are now in Config mode */ ++ mcp25xxfd_cmd_reset(spi, priv->spi_setup_speed_hz); ++ ++ /* Wait for oscillator startup again */ ++ mdelay(MCP25XXFD_OST_DELAY_MS); ++ break; ++ default: ++ /* otherwise there is no valid device (or in strange state) ++ * ++ * if PLL is enabled but not ready, then there may be ++ * something "fishy" ++ * this happened during driver development ++ * (enabling pll, when when on wrong clock), so best warn ++ * about such a possibility ++ */ ++ if ((priv->regs.osc & ++ (MCP25XXFD_OSC_PLLEN | MCP25XXFD_OSC_PLLRDY)) ++ == MCP25XXFD_OSC_PLLEN) ++ dev_err(&spi->dev, ++ "mcp25xxfd may be in a strange state - a power disconnect may be required\n"); ++ ++ return -ENODEV; ++ } ++ ++ /* check if we are in config mode already*/ ++ ++ /* read CON register and match */ ++ ret = mcp25xxfd_cmd_read(spi, CAN_CON, ++ &priv->regs.con, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ ++ /* apply mask and check */ ++ if ((priv->regs.con & CAN_CON_DEFAULT_MASK) == CAN_CON_DEFAULT) { ++ priv->active_can_mode = CAN_CON_MODE_CONFIG; ++ return 0; ++ } ++ ++ /* as per datasheet a reset only works in Config Mode ++ * so as we have in principle no knowledge of the current ++ * mode that the controller is in we have no safe way ++ * to detect the device correctly ++ * hence we need to "blindly" put the controller into ++ * config mode. ++ * on the "save" side, the OSC reg has to be valid already, ++ * so there is a chance we got the controller... ++ */ ++ ++ /* blindly force it into config mode */ ++ priv->regs.con = CAN_CON_DEFAULT; ++ priv->active_can_mode = CAN_CON_MODE_CONFIG; ++ ret = mcp25xxfd_cmd_write(spi, CAN_CON, CAN_CON_DEFAULT, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ ++ /* delay some time */ ++ mdelay(MCP25XXFD_OST_DELAY_MS); ++ ++ /* reset can controller */ ++ mcp25xxfd_cmd_reset(spi, priv->spi_setup_speed_hz); ++ ++ /* delay some time */ ++ mdelay(MCP25XXFD_OST_DELAY_MS); ++ ++ /* read CON register and match a final time */ ++ ret = mcp25xxfd_cmd_read(spi, CAN_CON, ++ &priv->regs.con, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ ++ /* apply mask and check */ ++ if ((priv->regs.con & CAN_CON_DEFAULT_MASK) != CAN_CON_DEFAULT) ++ return -ENODEV; ++ ++ /* just in case: disable interrupts on controller */ ++ return mcp25xxfd_disable_interrupts(spi, ++ priv->spi_setup_speed_hz); ++} ++ ++static int mcp25xxfd_setup_osc(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ int val = ((priv->config.clock_pll) ? MCP25XXFD_OSC_PLLEN : 0) ++ | ((priv->config.clock_div2) ? MCP25XXFD_OSC_SCLKDIV : 0); ++ int waitfor = ((priv->config.clock_pll) ? MCP25XXFD_OSC_PLLRDY : 0) ++ | ((priv->config.clock_div2) ? MCP25XXFD_OSC_SCLKRDY : 0) ++ | MCP25XXFD_OSC_OSCRDY; ++ int ret; ++ unsigned long timeout; ++ ++ /* manage clock_out divider */ ++ switch (priv->config.clock_odiv) { ++ case 10: ++ val |= (MCP25XXFD_OSC_CLKODIV_10) ++ << MCP25XXFD_OSC_CLKODIV_SHIFT; ++ break; ++ case 4: ++ val |= (MCP25XXFD_OSC_CLKODIV_4) ++ << MCP25XXFD_OSC_CLKODIV_SHIFT; ++ break; ++ case 2: ++ val |= (MCP25XXFD_OSC_CLKODIV_2) ++ << MCP25XXFD_OSC_CLKODIV_SHIFT; ++ break; ++ case 1: ++ val |= (MCP25XXFD_OSC_CLKODIV_1) ++ << MCP25XXFD_OSC_CLKODIV_SHIFT; ++ break; ++ case 0: ++ /* this means implicitly SOF output */ ++ val |= (MCP25XXFD_OSC_CLKODIV_10) ++ << MCP25XXFD_OSC_CLKODIV_SHIFT; ++ break; ++ default: ++ dev_err(&spi->dev, ++ "Unsupported output clock divider %i\n", ++ priv->config.clock_odiv); ++ return -EINVAL; ++ } ++ ++ /* write clock */ ++ ret = mcp25xxfd_cmd_write(spi, MCP25XXFD_OSC, val, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ ++ /* wait for synced pll/osc/sclk */ ++ timeout = jiffies + MCP25XXFD_OSC_POLLING_JIFFIES; ++ while (time_before_eq(jiffies, timeout)) { ++ ret = mcp25xxfd_cmd_read(spi, MCP25XXFD_OSC, ++ &priv->regs.osc, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ if ((priv->regs.osc & waitfor) == waitfor) ++ return 0; ++ } ++ ++ dev_err(&spi->dev, ++ "Clock did not lock within the timeout period\n"); ++ ++ /* we timed out */ ++ return -ENODEV; ++} ++ ++static int mcp25xxfd_setup_fifo(struct net_device *net, ++ struct mcp25xxfd_priv *priv, ++ struct spi_device *spi) ++{ ++ u32 val, available_memory, tx_memory_used; ++ int ret; ++ int i, fifo; ++ ++ /* clear all filter */ ++ for (i = 0; i < 32; i++) { ++ ret = mcp25xxfd_cmd_write(spi, CAN_FLTOBJ(i), 0, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ ret = mcp25xxfd_cmd_write(spi, CAN_FLTMASK(i), 0, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ ret = mcp25xxfd_cmd_write_mask(spi, CAN_FLTCON(i), 0, ++ CAN_FILCON_MASK(i), ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ } ++ ++ /* decide on TEF, tx and rx FIFOS */ ++ switch (net->mtu) { ++ case CAN_MTU: ++ /* note: if we have INT1 connected to a GPIO ++ * then we could handle this differently and more ++ * efficiently ++ */ ++ ++ /* mtu is 8 */ ++ priv->fifos.payload_size = 8; ++ priv->fifos.payload_mode = CAN_TXQCON_PLSIZE_8; ++ ++ /* 7 tx fifos starting at fifo 1 */ ++ priv->fifos.tx_fifos = 7; ++ ++ /* 24 rx fifos with 1 buffers/fifo */ ++ priv->fifos.rx_fifo_depth = 1; ++ ++ break; ++ case CANFD_MTU: ++ /* wish there was a way to have hw filters ++ * that can separate based on length ... ++ */ ++ /* MTU is 64 */ ++ priv->fifos.payload_size = 64; ++ priv->fifos.payload_mode = CAN_TXQCON_PLSIZE_64; ++ ++ /* 7 tx fifos */ ++ priv->fifos.tx_fifos = 7; ++ ++ /* 19 rx fifos with 1 buffer/fifo */ ++ priv->fifos.rx_fifo_depth = 1; ++ ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ /* if defined as a module modify the number of tx_fifos */ ++ if (tx_fifos) { ++ dev_info(&spi->dev, ++ "Using %i tx-fifos as per module parameter\n", ++ tx_fifos); ++ priv->fifos.tx_fifos = tx_fifos; ++ } ++ ++ /* check range - we need 1 RX-fifo and one tef-fifo, hence 30 */ ++ if (priv->fifos.tx_fifos > 30) { ++ dev_err(&spi->dev, ++ "There is an absolute maximum of 30 tx-fifos\n"); ++ return -EINVAL; ++ } ++ ++ tx_memory_used = priv->fifos.tx_fifos * ++ (sizeof(struct mcp25xxfd_obj_tef) + ++ sizeof(struct mcp25xxfd_obj_tx) + ++ priv->fifos.payload_size); ++ /* check that we are not exceeding memory limits with 1 RX buffer */ ++ if (tx_memory_used + (sizeof(struct mcp25xxfd_obj_rx) + ++ priv->fifos.payload_size) > MCP25XXFD_BUFFER_TXRX_SIZE) { ++ dev_err(&spi->dev, ++ "Configured %i tx-fifos exceeds available memory already\n", ++ priv->fifos.tx_fifos); ++ return -EINVAL; ++ } ++ ++ /* calculate possible amount of RX fifos */ ++ available_memory = MCP25XXFD_BUFFER_TXRX_SIZE - tx_memory_used; ++ ++ priv->fifos.rx_fifos = available_memory / ++ (sizeof(struct mcp25xxfd_obj_rx) + ++ priv->fifos.payload_size) / ++ priv->fifos.rx_fifo_depth; ++ ++ /* we only support 31 FIFOS in total (TEF = FIFO0), ++ * so modify rx accordingly ++ */ ++ if (priv->fifos.tx_fifos + priv->fifos.rx_fifos > 31) ++ priv->fifos.rx_fifos = 31 - priv->fifos.tx_fifos; ++ ++ /* calculate effective memory used */ ++ available_memory -= priv->fifos.rx_fifos * ++ (sizeof(struct mcp25xxfd_obj_rx) + ++ priv->fifos.payload_size) * ++ priv->fifos.rx_fifo_depth; ++ ++ /* calcluate tef size */ ++ priv->fifos.tef_fifos = priv->fifos.tx_fifos; ++ fifo = available_memory / sizeof(struct mcp25xxfd_obj_tef); ++ if (fifo > 0) { ++ priv->fifos.tef_fifos += fifo; ++ if (priv->fifos.tef_fifos > 32) ++ priv->fifos.tef_fifos = 32; ++ } ++ ++ /* calculate rx/tx fifo start */ ++ priv->fifos.rx_fifo_start = 1; ++ priv->fifos.tx_fifo_start = ++ priv->fifos.rx_fifo_start + priv->fifos.rx_fifos; ++ ++ /* set up TEF SIZE to the number of tx_fifos and IRQ */ ++ priv->regs.tefcon = CAN_TEFCON_FRESET | ++ CAN_TEFCON_TEFNEIE | ++ CAN_TEFCON_TEFTSEN | ++ ((priv->fifos.tef_fifos - 1) << CAN_TEFCON_FSIZE_SHIFT); ++ ++ ret = mcp25xxfd_cmd_write(spi, CAN_TEFCON, ++ priv->regs.tefcon, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ ++ /* set up tx fifos */ ++ val = CAN_FIFOCON_TXEN | ++ CAN_FIFOCON_TXATIE | /* show up txatie flags in txatif reg */ ++ CAN_FIFOCON_FRESET | /* reset FIFO */ ++ (priv->fifos.payload_mode << CAN_FIFOCON_PLSIZE_SHIFT) | ++ (0 << CAN_FIFOCON_FSIZE_SHIFT); /* 1 FIFO only */ ++ ++ if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT) ++ if (three_shot) ++ val |= CAN_FIFOCON_TXAT_THREE_SHOT << ++ CAN_FIFOCON_TXAT_SHIFT; ++ else ++ val |= CAN_FIFOCON_TXAT_ONE_SHOT << ++ CAN_FIFOCON_TXAT_SHIFT; ++ else ++ val |= CAN_FIFOCON_TXAT_UNLIMITED << ++ CAN_FIFOCON_TXAT_SHIFT; ++ ++ for (i = 0; i < priv->fifos.tx_fifos; i++) { ++ fifo = priv->fifos.tx_fifo_start + i; ++ ret = mcp25xxfd_cmd_write(spi, CAN_FIFOCON(fifo), ++ /* the prioriy needs to be inverted ++ * we need to run from lowest to ++ * highest to avoid MAB errors ++ */ ++ val | ((31 - fifo) << ++ CAN_FIFOCON_TXPRI_SHIFT), ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ priv->fifos.tx_fifo_mask |= BIT(fifo); ++ } ++ ++ /* now set up RX FIFO */ ++ for (i = 0, ++ fifo = priv->fifos.rx_fifo_start + priv->fifos.rx_fifos - 1; ++ i < priv->fifos.rx_fifos; i++, fifo--) { ++ /* prepare the fifo itself */ ++ ret = mcp25xxfd_cmd_write(spi, CAN_FIFOCON(fifo), ++ (priv->fifos.payload_mode << ++ CAN_FIFOCON_PLSIZE_SHIFT) | ++ ((priv->fifos.rx_fifo_depth - 1) << ++ CAN_FIFOCON_FSIZE_SHIFT) | ++ /* RX timestamps: */ ++ CAN_FIFOCON_RXTSEN | ++ /* reset FIFO: */ ++ CAN_FIFOCON_FRESET | ++ /* FIFO Full: */ ++ CAN_FIFOCON_TFERFFIE | ++ /* FIFO Half Full: */ ++ CAN_FIFOCON_TFHRFHIE | ++ /* FIFO not empty: */ ++ CAN_FIFOCON_TFNRFNIE | ++ /* on last fifo add overflow flag: */ ++ ((i == priv->fifos.rx_fifos - 1) ? ++ CAN_FIFOCON_RXOVIE : 0), ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ /* prepare the rx filter config: filter i directs to fifo ++ * FLTMSK and FLTOBJ are 0 already, so they match everything ++ */ ++ ret = mcp25xxfd_cmd_write_mask(spi, CAN_FLTCON(i), ++ CAN_FIFOCON_FLTEN(i) | ++ (fifo << CAN_FILCON_SHIFT(i)), ++ CAN_FIFOCON_FLTEN(i) | ++ CAN_FILCON_MASK(i), ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ ++ priv->fifos.rx_fifo_mask |= BIT(fifo); ++ } ++ ++ /* we need to move out of CONFIG mode shortly to get the addresses */ ++ ret = mcp25xxfd_set_opmode(spi, CAN_CON_MODE_INTERNAL_LOOPBACK, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ ++ /* for the TEF fifo */ ++ ret = mcp25xxfd_cmd_read(spi, CAN_TEFUA, &val, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ priv->fifos.tef_address = val; ++ priv->fifos.tef_address_start = val; ++ priv->fifos.tef_address_end = priv->fifos.tef_address_start + ++ priv->fifos.tef_fifos * sizeof(struct mcp25xxfd_obj_tef) - ++ 1; ++ ++ /* get all the relevant addresses for the transmit fifos */ ++ for (i = 0; i < priv->fifos.tx_fifos; i++) { ++ fifo = priv->fifos.tx_fifo_start + i; ++ ret = mcp25xxfd_cmd_read(spi, CAN_FIFOUA(fifo), ++ &val, priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ priv->fifos.fifo_address[fifo] = val; ++ } ++ ++ /* and prepare the spi_messages */ ++ ret = mcp25xxfd_fill_spi_transmit_fifos(priv); ++ if (ret) ++ return ret; ++ ++ /* get all the relevant addresses for the rx fifos */ ++ for (i = 0; i < priv->fifos.rx_fifos; i++) { ++ fifo = priv->fifos.rx_fifo_start + i; ++ ret = mcp25xxfd_cmd_read(spi, CAN_FIFOUA(fifo), ++ &val, priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ priv->fifos.fifo_address[fifo] = val; ++ } ++ ++ /* now get back into config mode */ ++ ret = mcp25xxfd_set_opmode(spi, CAN_CON_MODE_CONFIG, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static int mcp25xxfd_setup(struct net_device *net, ++ struct mcp25xxfd_priv *priv, ++ struct spi_device *spi) ++{ ++ int ret; ++ ++ /* set up pll/clock if required */ ++ ret = mcp25xxfd_setup_osc(spi); ++ if (ret) ++ return ret; ++ ++ /* set up RAM ECC */ ++ priv->regs.ecccon = MCP25XXFD_ECCCON_ECCEN | ++ MCP25XXFD_ECCCON_SECIE | ++ MCP25XXFD_ECCCON_DEDIE; ++ ret = mcp25xxfd_cmd_write(spi, MCP25XXFD_ECCCON, ++ priv->regs.ecccon, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ ++ /* clean SRAM now that we have ECC enabled ++ * only this case it is clear that all RAM cels have ++ * valid ECC bits ++ */ ++ ret = mcp25xxfd_clean_sram(spi, priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ ++ /* time stamp control register - 1ns resolution, but disabled */ ++ ret = mcp25xxfd_cmd_write(spi, CAN_TBC, 0, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ priv->regs.tscon = CAN_TSCON_TBCEN | ++ ((priv->can.clock.freq / 1000000) ++ << CAN_TSCON_TBCPRE_SHIFT); ++ ret = mcp25xxfd_cmd_write(spi, CAN_TSCON, ++ priv->regs.tscon, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ ++ /* setup value of con_register */ ++ priv->regs.con = CAN_CON_STEF /* enable TEF */; ++ ++ /* transmission bandwidth sharing bits */ ++ if (bw_sharing_log2bits > 12) ++ bw_sharing_log2bits = 12; ++ priv->regs.con |= bw_sharing_log2bits << CAN_CON_TXBWS_SHIFT; ++ /* non iso FD mode */ ++ if (!(priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO)) ++ priv->regs.con |= CAN_CON_ISOCRCEN; ++ /* one shot */ ++ if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT) ++ priv->regs.con |= CAN_CON_RTXAT; ++ ++ /* and put us into default mode = CONFIG */ ++ priv->regs.con |= (CAN_CON_MODE_CONFIG << CAN_CON_REQOP_SHIFT) | ++ (CAN_CON_MODE_CONFIG << CAN_CON_OPMOD_SHIFT); ++ /* apply it now - later we will only switch opsmodes... */ ++ ret = mcp25xxfd_cmd_write(spi, CAN_CON, ++ priv->regs.con, ++ priv->spi_setup_speed_hz); ++ ++ /* setup fifos - this also puts the system into sleep mode */ ++ return mcp25xxfd_setup_fifo(net, priv, spi); ++} ++ ++static int mcp25xxfd_open(struct net_device *net) ++{ ++ struct mcp25xxfd_priv *priv = netdev_priv(net); ++ struct spi_device *spi = priv->spi; ++ int ret; ++ ++ ret = open_candev(net); ++ if (ret) { ++ dev_err(&spi->dev, "unable to set initial baudrate!\n"); ++ return ret; ++ } ++ ++ mcp25xxfd_power_enable(priv->transceiver, 1); ++ ++ priv->force_quit = 0; ++ ++ /* clear those statistics */ ++ memset(&priv->stats, 0, sizeof(priv->stats)); ++ ++ ret = request_threaded_irq(spi->irq, NULL, ++ mcp25xxfd_can_ist, ++ IRQF_ONESHOT | IRQF_TRIGGER_LOW, ++ DEVICE_NAME, priv); ++ if (ret) { ++ dev_err(&spi->dev, "failed to acquire irq %d - %i\n", ++ spi->irq, ret); ++ mcp25xxfd_power_enable(priv->transceiver, 0); ++ close_candev(net); ++ return ret; ++ } ++ ++ /* wake from sleep if necessary */ ++ ret = mcp25xxfd_hw_wake(spi); ++ if (ret) ++ goto open_clean; ++ ++ ret = mcp25xxfd_setup(net, priv, spi); ++ if (ret) ++ goto open_clean; ++ ++ mcp25xxfd_do_set_nominal_bittiming(net); ++ mcp25xxfd_do_set_data_bittiming(net); ++ ++ ret = mcp25xxfd_set_normal_opmode(spi); ++ if (ret) ++ goto open_clean; ++ /* setting up default state */ ++ priv->can.state = CAN_STATE_ERROR_ACTIVE; ++ ++ /* only now enable the interrupt on the controller */ ++ ret = mcp25xxfd_enable_interrupts(spi, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ goto open_clean; ++ ++ can_led_event(net, CAN_LED_EVENT_OPEN); ++ ++ priv->tx_queue_status = TX_QUEUE_STATUS_RUNNING; ++ netif_wake_queue(net); ++ ++ return 0; ++ ++open_clean: ++ mcp25xxfd_disable_interrupts(spi, priv->spi_setup_speed_hz); ++ free_irq(spi->irq, priv); ++ mcp25xxfd_hw_sleep(spi); ++ mcp25xxfd_power_enable(priv->transceiver, 0); ++ close_candev(net); ++ ++ return ret; ++} ++ ++static void mcp25xxfd_clean(struct net_device *net) ++{ ++ struct mcp25xxfd_priv *priv = netdev_priv(net); ++ int i; ++ ++ for (i = 0; i < priv->fifos.tx_fifos; i++) { ++ if (priv->fifos.tx_pending_mask & BIT(i)) { ++ can_free_echo_skb(priv->net, 0); ++ priv->net->stats.tx_errors++; ++ } ++ } ++ ++ priv->fifos.tx_pending_mask = 0; ++} ++ ++static int mcp25xxfd_stop(struct net_device *net) ++{ ++ struct mcp25xxfd_priv *priv = netdev_priv(net); ++ struct spi_device *spi = priv->spi; ++ ++ close_candev(net); ++ ++ kfree(priv->spi_transmit_fifos); ++ priv->spi_transmit_fifos = NULL; ++ ++ priv->force_quit = 1; ++ free_irq(spi->irq, priv); ++ ++ /* Disable and clear pending interrupts */ ++ mcp25xxfd_disable_interrupts(spi, priv->spi_setup_speed_hz); ++ ++ mcp25xxfd_clean(net); ++ ++ mcp25xxfd_hw_sleep(spi); ++ ++ mcp25xxfd_power_enable(priv->transceiver, 0); ++ ++ priv->can.state = CAN_STATE_STOPPED; ++ ++ can_led_event(net, CAN_LED_EVENT_STOP); ++ ++ return 0; ++} ++ ++static const struct net_device_ops mcp25xxfd_netdev_ops = { ++ .ndo_open = mcp25xxfd_open, ++ .ndo_stop = mcp25xxfd_stop, ++ .ndo_start_xmit = mcp25xxfd_start_xmit, ++ .ndo_change_mtu = can_change_mtu, ++}; ++ ++static const struct of_device_id mcp25xxfd_of_match[] = { ++ { ++ .compatible = "microchip,mcp2517fd", ++ .data = (void *)CAN_MCP2517FD, ++ }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, mcp25xxfd_of_match); ++ ++static const struct spi_device_id mcp25xxfd_id_table[] = { ++ { ++ .name = "mcp2517fd", ++ .driver_data = (kernel_ulong_t)CAN_MCP2517FD, ++ }, ++ { } ++}; ++MODULE_DEVICE_TABLE(spi, mcp25xxfd_id_table); ++ ++static int mcp25xxfd_dump_regs(struct seq_file *file, void *offset) ++{ ++ struct spi_device *spi = file->private; ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ u32 data[CAN_TXQUA - CAN_CON + 4]; ++ int i; ++ int count; ++ int ret; ++ ++ count = (CAN_TXQUA - CAN_CON) / 4 + 1; ++ ret = mcp25xxfd_cmd_readn(spi, CAN_CON, data, 4 * count, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ ++ mcp25xxfd_convert_to_cpu((u32 *)data, 4 * count); ++ ++ for (i = 0; i < count; i++) { ++ seq_printf(file, "Reg 0x%03x = 0x%08x\n", ++ CAN_CON + 4 * i, ++ ((u32 *)data)[i]); ++ } ++ ++ count = (MCP25XXFD_ECCSTAT - MCP25XXFD_OSC) / 4 + 1; ++ ret = mcp25xxfd_cmd_readn(spi, MCP25XXFD_OSC, data, 4 * count, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ mcp25xxfd_convert_to_cpu((u32 *)data, 4 * count); ++ ++ for (i = 0; i < count; i++) { ++ seq_printf(file, "Reg 0x%03x = 0x%08x\n", ++ MCP25XXFD_OSC + 4 * i, ++ ((u32 *)data)[i]); ++ } ++ ++ return 0; ++} ++ ++#if defined(CONFIG_DEBUG_FS) ++static void mcp25xxfd_debugfs_add(struct mcp25xxfd_priv *priv) ++{ ++ struct dentry *root, *fifousage, *fifoaddr, *rx, *tx, *status, ++ *regs, *stats, *rxdlc, *txdlc; ++ char name[32]; ++ int i; ++ ++ /* create the net device name */ ++ snprintf(name, sizeof(name), DEVICE_NAME "-%s", priv->net->name); ++ priv->debugfs_dir = debugfs_create_dir(name, NULL); ++ root = priv->debugfs_dir; ++ ++ rx = debugfs_create_dir("rx", root); ++ tx = debugfs_create_dir("tx", root); ++ fifoaddr = debugfs_create_dir("fifo_address", root); ++ status = debugfs_create_dir("status", root); ++ regs = debugfs_create_dir("regs", root); ++ stats = debugfs_create_dir("stats", root); ++ fifousage = debugfs_create_dir("fifo_usage", stats); ++ rxdlc = debugfs_create_dir("rx_dlc_usage", stats); ++ txdlc = debugfs_create_dir("tx_dlc_usage", stats); ++ ++ /* add spi speed info */ ++ debugfs_create_u32("spi_setup_speed_hz", 0444, root, ++ &priv->spi_setup_speed_hz); ++ debugfs_create_u32("spi_speed_hz", 0444, root, ++ &priv->spi_speed_hz); ++ ++ /* add irq state info */ ++ debugfs_create_u32("irq_state", 0444, root, &priv->stats.irq_state); ++ ++ /* for the clock user mask */ ++ debugfs_create_u32("clk_user_mask", 0444, root, &priv->clk_user_mask); ++ ++ /* add fd statistics */ ++ debugfs_create_u64("rx_fd_frames", 0444, stats, ++ &priv->stats.rx_fd_count); ++ debugfs_create_u64("tx_fd_frames", 0444, stats, ++ &priv->stats.tx_fd_count); ++ debugfs_create_u64("rx_brs_frames", 0444, stats, ++ &priv->stats.rx_brs_count); ++ debugfs_create_u64("tx_brs_frames", 0444, stats, ++ &priv->stats.tx_brs_count); ++ ++ /* export the status structure */ ++ debugfs_create_x32("intf", 0444, status, &priv->status.intf); ++ debugfs_create_x32("rx_if", 0444, status, &priv->status.rxif); ++ debugfs_create_x32("tx_if", 0444, status, &priv->status.txif); ++ debugfs_create_x32("rx_ovif", 0444, status, &priv->status.rxovif); ++ debugfs_create_x32("tx_atif", 0444, status, &priv->status.txatif); ++ debugfs_create_x32("tx_req", 0444, status, &priv->status.txreq); ++ debugfs_create_x32("trec", 0444, status, &priv->status.trec); ++ debugfs_create_x32("bdiag0", 0444, status, &priv->status.bdiag0); ++ debugfs_create_x32("bdiag1", 0444, status, &priv->status.bdiag1); ++ ++ /* some configuration registers */ ++ debugfs_create_x32("con", 0444, regs, &priv->regs.con); ++ debugfs_create_x32("ecccon", 0444, regs, &priv->regs.ecccon); ++ debugfs_create_x32("osc", 0444, regs, &priv->regs.osc); ++ debugfs_create_x32("iocon", 0444, regs, &priv->regs.iocon); ++ debugfs_create_x32("tdc", 0774, regs, &priv->regs.tdc); ++ debugfs_create_x32("tscon", 0444, regs, &priv->regs.tscon); ++ debugfs_create_x32("nbtcfg", 0444, regs, &priv->regs.nbtcfg); ++ debugfs_create_x32("dbtcfg", 0444, regs, &priv->regs.dbtcfg); ++ ++ /* information on fifos */ ++ debugfs_create_u32("fifo_start", 0444, rx, ++ &priv->fifos.rx_fifo_start); ++ debugfs_create_u32("fifo_count", 0444, rx, ++ &priv->fifos.rx_fifos); ++ debugfs_create_x32("fifo_mask", 0444, rx, ++ &priv->fifos.rx_fifo_mask); ++ debugfs_create_u64("rx_overflow", 0444, rx, ++ &priv->stats.rx_overflow); ++ debugfs_create_u64("rx_mab", 0444, stats, ++ &priv->stats.rx_mab); ++ ++ debugfs_create_u32("fifo_start", 0444, tx, ++ &priv->fifos.tx_fifo_start); ++ debugfs_create_u32("fifo_count", 0444, tx, ++ &priv->fifos.tx_fifos); ++ debugfs_create_x32("fifo_mask", 0444, tx, ++ &priv->fifos.tx_fifo_mask); ++ debugfs_create_x32("fifo_pending", 0444, tx, ++ &priv->fifos.tx_pending_mask); ++ debugfs_create_x32("fifo_submitted", 0444, tx, ++ &priv->fifos.tx_submitted_mask); ++ debugfs_create_x32("fifo_processed", 0444, tx, ++ &priv->fifos.tx_processed_mask); ++ debugfs_create_u32("queue_status", 0444, tx, ++ &priv->tx_queue_status); ++ debugfs_create_u64("tx_mab", 0444, stats, ++ &priv->stats.tx_mab); ++ ++ debugfs_create_u32("tef_count", 0444, tx, ++ &priv->fifos.tef_fifos); ++ ++ debugfs_create_u32("fifo_max_payload_size", 0444, root, ++ &priv->fifos.payload_size); ++ ++ /* interrupt statistics */ ++ debugfs_create_u64("int", 0444, stats, ++ &priv->stats.irq_calls); ++ debugfs_create_u64("int_loops", 0444, stats, ++ &priv->stats.irq_loops); ++ debugfs_create_u64("int_ivm", 0444, stats, ++ &priv->stats.int_ivm_count); ++ debugfs_create_u64("int_wake", 0444, stats, ++ &priv->stats.int_wake_count); ++ debugfs_create_u64("int_cerr", 0444, stats, ++ &priv->stats.int_cerr_count); ++ debugfs_create_u64("int_serr", 0444, stats, ++ &priv->stats.int_serr_count); ++ debugfs_create_u64("int_rxov", 0444, stats, ++ &priv->stats.int_rxov_count); ++ debugfs_create_u64("int_txat", 0444, stats, ++ &priv->stats.int_txat_count); ++ debugfs_create_u64("int_spicrc", 0444, stats, ++ &priv->stats.int_spicrc_count); ++ debugfs_create_u64("int_ecc", 0444, stats, ++ &priv->stats.int_ecc_count); ++ debugfs_create_u64("int_tef", 0444, stats, ++ &priv->stats.int_tef_count); ++ debugfs_create_u64("int_mod", 0444, stats, ++ &priv->stats.int_mod_count); ++ debugfs_create_u64("int_tbc", 0444, stats, ++ &priv->stats.int_tbc_count); ++ debugfs_create_u64("int_rx", 0444, stats, ++ &priv->stats.int_rx_count); ++ debugfs_create_u64("int_tx", 0444, stats, ++ &priv->stats.int_tx_count); ++ ++ /* dlc statistics */ ++ for (i = 0; i < 16; i++) { ++ snprintf(name, sizeof(name), "%02i", i); ++ debugfs_create_u64(name, 0444, rxdlc, ++ &priv->stats.rx_dlc_usage[i]); ++ debugfs_create_u64(name, 0444, txdlc, ++ &priv->stats.tx_dlc_usage[i]); ++ } ++ ++ /* statistics on fifo buffer usage and address */ ++ for (i = 1; i < 32; i++) { ++ snprintf(name, sizeof(name), "%02i", i); ++ debugfs_create_u64(name, 0444, fifousage, ++ &priv->stats.fifo_usage[i]); ++ debugfs_create_u32(name, 0444, fifoaddr, ++ &priv->fifos.fifo_address[i]); ++ } ++ ++ /* dump the controller registers themselves */ ++ debugfs_create_devm_seqfile(&priv->spi->dev, "reg_dump", ++ root, mcp25xxfd_dump_regs); ++} ++ ++static void mcp25xxfd_debugfs_remove(struct mcp25xxfd_priv *priv) ++{ ++ debugfs_remove_recursive(priv->debugfs_dir); ++} ++ ++#else ++static void mcp25xxfd_debugfs_add(struct mcp25xxfd_priv *priv) ++{ ++ return 0; ++} ++ ++static void mcp25xxfd_debugfs_remove(struct mcp25xxfd_priv *priv) ++{ ++} ++#endif ++ ++#ifdef CONFIG_OF_DYNAMIC ++int mcp25xxfd_of_parse(struct mcp25xxfd_priv *priv) ++{ ++ struct spi_device *spi = priv->spi; ++ const struct device_node *np = spi->dev.of_node; ++ u32 val; ++ int ret; ++ ++ priv->config.clock_div2 = ++ of_property_read_bool(np, "microchip,clock-div2"); ++ ++ ret = of_property_read_u32_index(np, "microchip,clock-out-div", ++ 0, &val); ++ if (!ret) { ++ switch (val) { ++ case 0: ++ case 1: ++ case 2: ++ case 4: ++ case 10: ++ priv->config.clock_odiv = val; ++ break; ++ default: ++ dev_err(&spi->dev, ++ "Invalid value in device tree for microchip,clock_out_div: %u - valid values: 0, 1, 2, 4, 10\n", ++ val); ++ return -EINVAL; ++ } ++ } ++ ++ priv->config.gpio_opendrain = ++ of_property_read_bool(np, "microchip,gpio-open-drain"); ++ ++ return 0; ++} ++#else ++int mcp25xxfd_of_parse(struct mcp25xxfd_priv *priv) ++{ ++ return 0; ++} ++#endif ++ ++static int mcp25xxfd_can_probe(struct spi_device *spi) ++{ ++ const struct of_device_id *of_id = ++ of_match_device(mcp25xxfd_of_match, &spi->dev); ++ struct net_device *net; ++ struct mcp25xxfd_priv *priv; ++ struct clk *clk; ++ int ret, freq; ++ ++ /* as irq_create_fwspec_mapping() can return 0, check for it */ ++ if (spi->irq <= 0) { ++ dev_err(&spi->dev, "no valid irq line defined: irq = %i\n", ++ spi->irq); ++ return -EINVAL; ++ } ++ ++ clk = devm_clk_get(&spi->dev, NULL); ++ if (IS_ERR(clk)) ++ return PTR_ERR(clk); ++ ++ freq = clk_get_rate(clk); ++ if (freq < MCP25XXFD_MIN_CLOCK_FREQUENCY || ++ freq > MCP25XXFD_MAX_CLOCK_FREQUENCY) { ++ dev_err(&spi->dev, ++ "Clock frequency %i is not in range [%i:%i]\n", ++ freq, ++ MCP25XXFD_MIN_CLOCK_FREQUENCY, ++ MCP25XXFD_MAX_CLOCK_FREQUENCY); ++ return -ERANGE; ++ } ++ ++ /* Allocate can/net device */ ++ net = alloc_candev(sizeof(*priv), TX_ECHO_SKB_MAX); ++ if (!net) ++ return -ENOMEM; ++ ++ net->netdev_ops = &mcp25xxfd_netdev_ops; ++ net->flags |= IFF_ECHO; ++ ++ priv = netdev_priv(net); ++ priv->can.bittiming_const = &mcp25xxfd_nominal_bittiming_const; ++ priv->can.do_set_bittiming = &mcp25xxfd_do_set_nominal_bittiming; ++ priv->can.data_bittiming_const = &mcp25xxfd_data_bittiming_const; ++ priv->can.do_set_data_bittiming = &mcp25xxfd_do_set_data_bittiming; ++ priv->can.do_set_mode = mcp25xxfd_do_set_mode; ++ priv->can.do_get_berr_counter = mcp25xxfd_get_berr_counter; ++ ++ priv->can.ctrlmode_supported = ++ CAN_CTRLMODE_FD | ++ CAN_CTRLMODE_LOOPBACK | ++ CAN_CTRLMODE_LISTENONLY | ++ CAN_CTRLMODE_BERR_REPORTING | ++ CAN_CTRLMODE_FD_NON_ISO | ++ CAN_CTRLMODE_ONE_SHOT; ++ ++ if (of_id) ++ priv->model = (enum mcp25xxfd_model)of_id->data; ++ else ++ priv->model = spi_get_device_id(spi)->driver_data; ++ ++ spi_set_drvdata(spi, priv); ++ priv->spi = spi; ++ priv->net = net; ++ priv->clk = clk; ++ ++ priv->clk_user_mask = MCP25XXFD_CLK_USER_CAN; ++ ++ mutex_init(&priv->clk_user_lock); ++ mutex_init(&priv->spi_rxtx_lock); ++ ++ /* enable the clock and mark as enabled */ ++ priv->clk_user_mask = MCP25XXFD_CLK_USER_CAN; ++ ret = clk_prepare_enable(clk); ++ if (ret) ++ goto out_free; ++ ++ /* Setup GPIO controller */ ++ ret = mcp25xxfd_gpio_setup(spi); ++ if (ret) ++ goto out_clk; ++ ++ /* all by default as push/pull */ ++ priv->config.gpio_opendrain = false; ++ ++ /* do not use the SCK clock divider of 2 */ ++ priv->config.clock_div2 = false; ++ ++ /* clock output is divided by 10 */ ++ priv->config.clock_odiv = 10; ++ ++ /* as a first guess we assume we are in CAN_CON_MODE_SLEEP ++ * this is how we leave the controller when removing ourselves ++ */ ++ priv->active_can_mode = CAN_CON_MODE_SLEEP; ++ ++ /* if we have a clock that is smaller then 4MHz, then enable the pll */ ++ priv->config.clock_pll = ++ (freq <= MCP25XXFD_AUTO_PLL_MAX_CLOCK_FREQUENCY); ++ ++ /* check in device tree for overrrides */ ++ ret = mcp25xxfd_of_parse(priv); ++ if (ret) ++ return ret; ++ ++ /* decide on real can clock rate */ ++ priv->can.clock.freq = freq; ++ if (priv->config.clock_pll) { ++ priv->can.clock.freq *= MCP25XXFD_PLL_MULTIPLIER; ++ if (priv->can.clock.freq > MCP25XXFD_MAX_CLOCK_FREQUENCY) { ++ dev_err(&spi->dev, ++ "PLL clock frequency %i would exceed limit\n", ++ priv->can.clock.freq ++ ); ++ return -EINVAL; ++ } ++ } ++ if (priv->config.clock_div2) ++ priv->can.clock.freq /= MCP25XXFD_SCLK_DIVIDER; ++ ++ /* calclculate the clock frequencies to use */ ++ priv->spi_setup_speed_hz = freq / 2; ++ priv->spi_speed_hz = priv->can.clock.freq / 2; ++ if (priv->config.clock_div2) { ++ priv->spi_setup_speed_hz /= MCP25XXFD_SCLK_DIVIDER; ++ priv->spi_speed_hz /= MCP25XXFD_SCLK_DIVIDER; ++ } ++ ++ if (spi->max_speed_hz) { ++ priv->spi_setup_speed_hz = min_t(int, ++ priv->spi_setup_speed_hz, ++ spi->max_speed_hz); ++ priv->spi_speed_hz = min_t(int, ++ priv->spi_speed_hz, ++ spi->max_speed_hz); ++ } ++ ++ /* Configure the SPI bus */ ++ spi->bits_per_word = 8; ++ ret = spi_setup(spi); ++ if (ret) ++ goto out_clk; ++ ++#if 0 //lm removed ++ priv->power = devm_regulator_get_optional(&spi->dev, "vdd"); ++ priv->transceiver = devm_regulator_get_optional(&spi->dev, "xceiver"); ++ if ((PTR_ERR(priv->power) == -EPROBE_DEFER) || ++ (PTR_ERR(priv->transceiver) == -EPROBE_DEFER)) { ++ ret = -EPROBE_DEFER; ++ goto out_clk; ++ } ++#endif ++ ret = mcp25xxfd_power_enable(priv->power, 1); ++ if (ret) ++ goto out_clk; ++ ++ SET_NETDEV_DEV(net, &spi->dev); ++ ++ ret = mcp25xxfd_hw_probe(spi); ++ /* on error retry a second time */ ++ if (ret == -ENODEV) { ++ ret = mcp25xxfd_hw_probe(spi); ++ printk("mcp2517 retry a second time!\n"); ++ ret = mcp25xxfd_hw_probe(spi); ++ if (ret == -ENODEV) { ++ printk("mcp2517 retry the 3 time!\n"); ++ msleep(10); ++ ret = mcp25xxfd_hw_probe(spi); ++ if (ret == -ENODEV) { ++ printk("mcp2517 retry the 4 time!\n"); ++ msleep(10); ++ ret = mcp25xxfd_hw_probe(spi); ++ } ++ } ++ if (!ret) ++ dev_info(&spi->dev, ++ "found device only during retry\n"); ++ } ++ if (ret) { ++ if (ret == -ENODEV) ++ dev_err(&spi->dev, ++ "Cannot initialize MCP%x. Wrong wiring?\n", ++ priv->model); ++ goto error_probe; ++ } ++ ++ /* setting up GPIO+INT as PUSHPULL , TXCAN PUSH/PULL, no Standby */ ++ priv->regs.iocon = 0; ++ ++ /* SOF/CLOCKOUT pin 3 */ ++ if (priv->config.clock_odiv < 1) ++ priv->regs.iocon |= MCP25XXFD_IOCON_SOF; ++ ++ /* INT/GPIO (probably also clockout) as open drain */ ++ if (priv->config.gpio_opendrain) ++ priv->regs.iocon |= MCP25XXFD_IOCON_INTOD; ++ ++ ret = mcp25xxfd_cmd_write(spi, MCP25XXFD_IOCON, priv->regs.iocon, ++ priv->spi_setup_speed_hz); ++ if (ret) ++ return ret; ++ ++ /* and put controller to sleep */ ++ mcp25xxfd_hw_sleep(spi); ++ ++ ret = register_candev(net); ++ if (ret) ++ goto error_probe; ++ ++ /* register debugfs */ ++ mcp25xxfd_debugfs_add(priv); ++ ++ devm_can_led_init(net); ++ ++ netdev_info(net, "MCP%x successfully initialized.\n", priv->model); ++ return 0; ++ ++error_probe: ++ mcp25xxfd_power_enable(priv->power, 0); ++ ++out_clk: ++ mcp25xxfd_stop_clock(spi, MCP25XXFD_CLK_USER_CAN); ++ ++out_free: ++ free_candev(net); ++ dev_err(&spi->dev, "Probe failed, err=%d\n", -ret); ++ return ret; ++} ++ ++static int mcp25xxfd_can_remove(struct spi_device *spi) ++{ ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ struct net_device *net = priv->net; ++ ++ mcp25xxfd_debugfs_remove(priv); ++ ++ unregister_candev(net); ++ ++ mcp25xxfd_power_enable(priv->power, 0); ++ ++ if (!IS_ERR(priv->clk)) ++ clk_disable_unprepare(priv->clk); ++ ++ free_candev(net); ++ ++ return 0; ++} ++ ++static int __maybe_unused mcp25xxfd_can_suspend(struct device *dev) ++{ ++ struct spi_device *spi = to_spi_device(dev); ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ struct net_device *net = priv->net; ++ ++ priv->force_quit = 1; ++ disable_irq(spi->irq); ++ ++ if (netif_running(net)) { ++ netif_device_detach(net); ++ ++ mcp25xxfd_hw_sleep(spi); ++ mcp25xxfd_power_enable(priv->transceiver, 0); ++ priv->after_suspend = AFTER_SUSPEND_UP; ++ } else { ++ priv->after_suspend = AFTER_SUSPEND_DOWN; ++ } ++ ++ if (!IS_ERR_OR_NULL(priv->power)) { ++ regulator_disable(priv->power); ++ priv->after_suspend |= AFTER_SUSPEND_POWER; ++ } ++ ++ return 0; ++} ++ ++static int __maybe_unused mcp25xxfd_can_resume(struct device *dev) ++{ ++ struct spi_device *spi = to_spi_device(dev); ++ struct mcp25xxfd_priv *priv = spi_get_drvdata(spi); ++ ++ if (priv->after_suspend & AFTER_SUSPEND_POWER) ++ mcp25xxfd_power_enable(priv->power, 1); ++ ++ if (priv->after_suspend & AFTER_SUSPEND_UP) ++ mcp25xxfd_power_enable(priv->transceiver, 1); ++ else ++ priv->after_suspend = 0; ++ ++ priv->force_quit = 0; ++ ++ enable_irq(spi->irq); ++ ++ return 0; ++} ++ ++static SIMPLE_DEV_PM_OPS(mcp25xxfd_can_pm_ops, mcp25xxfd_can_suspend, ++ mcp25xxfd_can_resume); ++ ++static struct spi_driver mcp25xxfd_can_driver = { ++ .driver = { ++ .name = DEVICE_NAME, ++ .of_match_table = mcp25xxfd_of_match, ++ .pm = &mcp25xxfd_can_pm_ops, ++ }, ++ .id_table = mcp25xxfd_id_table, ++ .probe = mcp25xxfd_can_probe, ++ .remove = mcp25xxfd_can_remove, ++}; ++module_spi_driver(mcp25xxfd_can_driver); ++ ++MODULE_AUTHOR("Martin Sperl <kernel@xxxxxxxxxxxxxxxx>"); ++MODULE_DESCRIPTION("Microchip 25XXFD CAN driver"); ++MODULE_LICENSE("GPL v2"); +-- +2.7.4 + diff --git a/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0004-Added-LT9611-driver-support-for-LEC-PX30-A2.patch b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0004-Added-LT9611-driver-support-for-LEC-PX30-A2.patch new file mode 100644 index 000000000..e010a7dae --- /dev/null +++ b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0004-Added-LT9611-driver-support-for-LEC-PX30-A2.patch @@ -0,0 +1,1027 @@ +From 9ae6662b0318130c9ecb9b223ecf473e6f335d7d Mon Sep 17 00:00:00 2001 +From: Dineshkumar V <dineshkumar.varadarajan@adlinktech.com> +Date: Wed, 19 Feb 2020 16:43:36 +0530 +Subject: [PATCH 4/4] Added LT9611 driver support for LEC-PX30-A2 + +--- + drivers/gpu/drm/bridge/Kconfig | 7 + + drivers/gpu/drm/bridge/Makefile | 2 +- + drivers/gpu/drm/bridge/lt9611-i2c.c | 976 ++++++++++++++++++++++++++++++++++++ + 3 files changed, 984 insertions(+), 1 deletion(-) + create mode 100644 drivers/gpu/drm/bridge/lt9611-i2c.c + +diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig +index cbb2138..e4a8f47 100644 +--- a/drivers/gpu/drm/bridge/Kconfig ++++ b/drivers/gpu/drm/bridge/Kconfig +@@ -48,6 +48,13 @@ config DRM_LONTIUM_LT8912 + help + Lontium LT8912 MIPI-DSI to LVDS and HDMI/MHL bridge chip driver. + ++config DRM_LONTIUM_LT9611_I2C ++ tristate "Lontium LT9611 MIPI-DSI to HDMI/MHL bridge with i2c" ++ depends on OF ++ select DRM_KMS_HELPER ++ select REGMAP_I2C ++ help ++ Lontium LT9611 MIPI-DSI to HDMI/MHL bridge chip driver with i2c. + config DRM_CHIPONE_ICN6211 + tristate "Chipone ICN6211 MIPI-DSI to RGB bridge" + depends on OF +diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile +index 19db905..effac4a 100644 +--- a/drivers/gpu/drm/bridge/Makefile ++++ b/drivers/gpu/drm/bridge/Makefile +@@ -6,6 +6,6 @@ obj-$(CONFIG_DRM_RK1000) += rk1000.o + obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o + obj-$(CONFIG_DRM_LONTIUM_LT8912) += lt8912.o + obj-$(CONFIG_DRM_CHIPONE_ICN6211) += icn6211.o +- ++obj-$(CONFIG_DRM_LONTIUM_LT9611_I2C) += lt9611-i2c.o + obj-y += analogix/ + obj-y += synopsys/ +diff --git a/drivers/gpu/drm/bridge/lt9611-i2c.c b/drivers/gpu/drm/bridge/lt9611-i2c.c +new file mode 100644 +index 0000000..cdf763d +--- /dev/null ++++ b/drivers/gpu/drm/bridge/lt9611-i2c.c +@@ -0,0 +1,976 @@ ++/* Copyright (c) 2017, The Linux Foundation. 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 version 2 and ++ * only version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. * ++ */ ++ ++ ++/*************************** ++*driver ic: LT9611 ++*version: lt9611_driver_v1.4 ++*release date: 20180816 ++1. implement the adjustment of hdmi sync polarity. ++2. implement pattern picture output. ++3. Add 1280x1024, 1024x768. ++ ++****************************/ ++ ++#include <linux/types.h> ++# include <linux/kernel.h> ++# include <linux/module.h> ++# include <linux/init.h> ++# include <linux/device.h> ++# include <linux/platform_device.h> ++# include <linux/fs.h> ++# include <linux/delay.h> ++# include <linux/i2c.h> ++# include <linux/gpio.h> ++# include <linux/interrupt.h> ++# include <linux/of_gpio.h> ++# include <linux/of_irq.h> ++# include <linux/pm.h> ++# include <linux/pm_runtime.h> ++# include <linux/regulator/consumer.h> ++#include <linux/regmap.h> ++#include <linux/of_platform.h> ++#include <linux/kobject.h> ++ ++#define DBUG 1 ++ ++#ifdef DBUG ++#define DEBUG printk ++#else ++#define DEBUG(fmt, args...) ++#endif ++ ++#define STRING_OFF "off" ++#define STRING_ON "on" ++ ++#define single_port_mipi 1 ++#define dual_port_mipi 2 ++ ++//Do not support 3lane ++#define lane_cnt_1 1 ++#define lane_cnt_2 2 ++#define lane_cnt_4 0 ++ ++#define audio_i2s 0 ++#define audio_spdif 1 ++ ++#define lt9611_dsi 0 ++#define lt9611_csi 1 ++ ++#define Non_Burst_Mode_with_Sync_Events 0x00 ++#define Non_Burst_Mode_with_Sync_Pulses 0x01 ++#define Burst_Mode 0x02 ++ ++#define ac_mode 0 ++#define dc_mode 1 ++ ++#define hdcp_diable 0 ++#define hdcp_enable 1 ++ ++ ++#define Output_RGB888 0 ++#define Output_YCbCr444 1 ++#define Output_YCbCr422_16BIT 2 ++#define Output_YCbCr422_20BIT 3 ++#define Output_YCbCr422_24BIT 4 ++ ++#define Video_Output_Mode Output_RGB888 ++ ++enum video_format ++{ ++ video_640x480_60Hz_vic1, //vic 1 ++ video_720x480_60Hz_vic3, //vic 2 ++ video_1280x720_60Hz_vic4, //vic 3 ++ video_1920x1080_60Hz_vic16, //vic 4 ++ ++ video_1920x1080i_60Hz_169=5, //vic 5 ++ video_720x480i_60Hz_43=6, //vic 6 ++ video_720x480i_60Hz_169=7, //vic 7 ++ video_720x240P_60Hz_43=8, //vic 8 ++ video_720x240P_60Hz_169=9, //vic 9 ++ video_1920x1080_30Hz_vic, ++ video_1280x720_30Hz_vic, ++ ++ video_3840x2160_30Hz_vic, ++ video_3840x1080_60Hz_vic, ++ video_1024x600_60Hz_vic, ++ video_none ++}; ++ ++struct video_timing{ ++int hfp; ++int hs; ++int hbp; ++int hact; ++int htotal; ++int vfp; ++int vs; ++int vbp; ++int vact; ++int vtotal; ++int pclk_khz; ++}; ++ ++struct lontium_ic_mode{ ++int mipi_port_cnt; //1 or 2 ++int mipi_lane_cnt; //1 or 2 or 4 ++bool mipi_mode; //dsi or csi ++int video_mode; //Non-Burst Mode with Sync Pulses; Non-Burst Mode with Sync Events ++bool audio_out; //i2s or spdif ++bool hdmi_coupling_mode;//ac_mode or dc_mode ++bool hdcp_encryption; //hdcp_enable or hdcp_diable ++}; ++ ++ ++ ++struct lontium_ic_mode lt9611_mode= { ++dual_port_mipi, //mipi_port_cnt; //single_port_mipi or dual_port_mipi ++//dual_port_mipi, //mipi_port_cnt; //single_port_mipi or dual_port_mipi ++lane_cnt_4, //mipi_lane_cnt; //1 or 2 or 4 ++lt9611_dsi, //mipi_mode; //lt9611_dsi or lt9611_csi ++Non_Burst_Mode_with_Sync_Events, ++audio_i2s, //audio_out //audio_i2s or audio_spdif ++//dc_mode, //hdmi_coupling_mode;//ac_mode or dc_mode ++ac_mode, //hdmi_coupling_mode;//ac_mode or dc_mode ++hdcp_enable //hdcp_encryption //hdcp_enable or hdcp_diable ++}; ++ // hfp, hs, hbp,hact,htotal,vfp, vs, vbp,vact,vtotal, pclk_khz ++struct video_timing video_640x480_60Hz ={ 8, 96, 40, 640, 800, 33, 2, 10, 480, 525, 25000}; ++struct video_timing video_720x480_60Hz ={16, 62, 60, 720, 858, 9, 6, 30, 480, 525, 27000}; ++struct video_timing video_1280x720_60Hz ={110,40, 220,1280, 1650, 5, 5, 20, 720, 750, 49500}; ++struct video_timing video_1280x720_30Hz ={110,40, 220,1280, 1650, 5, 5, 20, 720, 750, 37125}; ++struct video_timing video_1920x1080_30Hz ={88, 44, 148,1920, 2200, 4, 5, 36, 1080, 1125, 74250}; ++struct video_timing video_1920x1080_60Hz ={88, 44, 148,1920, 2200, 4, 5, 36, 1080, 1125, 148500}; ++struct video_timing video_3840x1080_60Hz ={176,88, 296,3840, 4400, 4, 5, 36, 1080, 1125, 297000}; ++struct video_timing video_3840x2160_30Hz ={176,88, 296,3840, 4400, 8, 10, 72, 2160, 2250, 297000}; ++struct video_timing video_1024x600_60Hz ={60,60, 100,1024, 1154, 2, 5, 10, 600, 617, 34000}; ++ ++struct video_timing *video; ++ ++struct lt9611 { ++ ++ struct gpio_desc *reset_n; ++ struct regmap *regmap; ++ struct video_timing *video; ++ int mipi_lane_cnt; ++ bool is_dual; ++ bool audio_status; ++ int hfp; ++ int hs_width; ++ int hbp; ++ int h_act; ++ int h_tal; ++ int vfp; ++ int vs_width; ++ int vbp; ++ int v_act; ++ int v_tal; ++ int mipi_video_format; ++ enum video_format video_format; ++ int hdmi_vic; ++ int hdmi_y; //0x00:RGB, 0x01:YCbCr422 0x02:YCbCr 444 ++ u8 sink_edid[256]; ++ ++}; ++ ++static void lt9611_power_on(struct lt9611 *lt9611) ++{ ++ DEBUG("ADLINK lt9611_power_on\n"); ++ gpiod_direction_output(lt9611->reset_n, 0); ++ msleep(20); ++ gpiod_direction_output(lt9611->reset_n, 1); ++ msleep(20); ++ gpiod_direction_output(lt9611->reset_n, 0); ++ msleep(20); ++} ++ ++static void lt9611_chip_id(struct lt9611 *lt9611) ++{ ++ int rev[16]; ++ regmap_write(lt9611->regmap, 0xff, 0x80); ++ regmap_write(lt9611->regmap, 0xee, 0x01); ++ regmap_read(lt9611->regmap, 0x00, &rev[0]); ++ regmap_read(lt9611->regmap, 0x01, &rev[1]); ++ regmap_read(lt9611->regmap, 0x02, &rev[2]); ++ DEBUG("ADLINK %s: lt9611 chip id: 0x%x 0x%x 0x%x\n", __func__, rev[0],rev[1],rev[2]); ++ ++} ++ ++static void lt9611_system_init(struct lt9611 *lt9611) ++{ ++ DEBUG("ADLINK %s: lt9611 system init\n", __func__); ++ regmap_write(lt9611->regmap, 0xFF, 0x82); ++ regmap_write(lt9611->regmap, 0x51, 0x01); ++ //Timer for Frequency meter ++ regmap_write(lt9611->regmap, 0xFF, 0x82); ++ regmap_write(lt9611->regmap, 0x1b, 0x69); //Timer 2 ++ regmap_write(lt9611->regmap, 0x1c, 0x78); ++ regmap_write(lt9611->regmap, 0xcb, 0x69); //Timer 1 ++ regmap_write(lt9611->regmap, 0xcc, 0x78); ++ ++ regmap_write(lt9611->regmap, 0xff, 0x80); ++ regmap_write(lt9611->regmap, 0x04, 0xf0); ++ regmap_write(lt9611->regmap, 0x06, 0xf0); ++ regmap_write(lt9611->regmap, 0x0a, 0x80); ++ regmap_write(lt9611->regmap, 0x0b, 0x40); ++ regmap_write(lt9611->regmap, 0x0d, 0xef); ++ regmap_write(lt9611->regmap, 0x11, 0xfa); ++ ++} ++ ++void lt9611_hdmi_out_disable(struct lt9611 *lt9611) //dsren ++{ ++ regmap_write(lt9611->regmap, 0xff,0x81); ++ regmap_write(lt9611->regmap, 0x30,0x00); /* Txphy PD */ ++ regmap_write(lt9611->regmap, 0x23,0x80); /* Txpll PD */ ++} ++ ++static void lt9611_mipi_input_analog(struct lt9611 *lt9611)//xuxi ++{ ++ DEBUG("ADLINK %s\n",__func__); ++ //mipi mode ++ regmap_write(lt9611->regmap, 0xff, 0x81); ++ regmap_write(lt9611->regmap, 0x06, 0x40); //port A rx current ++ regmap_write(lt9611->regmap, 0x0a, 0xfe); //port A ldo voltage set ++ regmap_write(lt9611->regmap, 0x0b, 0xbf); //enable port A lprx ++ regmap_write(lt9611->regmap, 0x11, 0x40); //port B rx current ++ regmap_write(lt9611->regmap, 0x15, 0xfe); //port B ldo voltage set ++ regmap_write(lt9611->regmap, 0x16, 0xbf); //enable port B lprx ++ ++ regmap_write(lt9611->regmap, 0x1c, 0x03); //PortA clk lane no-LP mode. ++ regmap_write(lt9611->regmap, 0x20, 0x03); //PortB clk lane no-LP mode. ++} ++ ++static void lt9611_mipi_input_digtal(struct lt9611 *lt9611) //weiguo ++{ ++ DEBUG("ADLINK %s \n",__func__); ++ regmap_write(lt9611->regmap, 0xff, 0x82); ++ regmap_write(lt9611->regmap, 0x4f, 0x80); //[7] = Select ad_txpll_d_clk. ++ regmap_write(lt9611->regmap, 0x50, 0x10); ++ ++ regmap_write(lt9611->regmap, 0xff, 0x83); ++ regmap_write(lt9611->regmap, 0x00, lt9611->mipi_lane_cnt); ++ regmap_write(lt9611->regmap, 0x02, 0x0a); //settle ++ regmap_write(lt9611->regmap, 0x06, 0x0a); //settle ++ ++ if(0) //dual_port_mipi ++ { ++ DEBUG("ADLINK %s dual port mipi \n",__func__); ++ regmap_write(lt9611->regmap, 0x0a, 0x03); //1=dual_lr, 0=dual_en ++ } ++ else //single_port_mipi ++ { ++ DEBUG("ADLINK %s single port mipi \n",__func__); ++ regmap_write(lt9611->regmap, 0x0a, 0x00); //1=dual_lr, 0=dual_en ++ } ++} ++ ++static int lt9611_htotal_sysclk(struct lt9611 *lt9611) ++{ ++ int reg, temp; ++ regmap_write(lt9611->regmap, 0xff, 0x82); ++ regmap_read(lt9611->regmap, 0x86, ®); ++ regmap_read(lt9611->regmap, 0x87, &temp); ++ reg = reg*256+temp; ++ DEBUG("ADLINK %s: lt9611 htotal sysclk: %d\n", __func__, reg); ++ return reg; ++} ++ ++static void lt9611_video_check(struct lt9611 *lt9611) //dsren ++{ ++ int htotal_sysclk; ++ int temp,temp_l; ++ regmap_write(lt9611->regmap, 0xff, 0x82); // top video check module ++ ++ regmap_read(lt9611->regmap, 0x82, &(lt9611->v_act)); ++ regmap_read(lt9611->regmap, 0x83, &temp); ++ lt9611->v_act = ((lt9611->v_act)<<8) + temp; ++ ++ regmap_read(lt9611->regmap, 0x6c, &(lt9611->v_tal)); ++ regmap_read(lt9611->regmap, 0x6d, &temp); ++ lt9611->v_tal = ((lt9611->v_tal)<<8) + temp; ++ ++ ++ regmap_write(lt9611->regmap, 0xff, 0x83); ++ ++ regmap_read(lt9611->regmap, 0x82, &(lt9611->h_act)); ++ regmap_read(lt9611->regmap, 0x83, &temp); ++ lt9611->h_act = ((lt9611->h_act)<<8) + temp; ++ lt9611->h_act = (lt9611->h_act/3); ++ ++ //if(lt9611.mipi_port_cnt==dual_port_mipi) ++ if(lt9611->is_dual) ++ { ++ regmap_read(lt9611->regmap, 0x86, &temp); ++ regmap_read(lt9611->regmap, 0x87, &temp_l); ++ temp = (temp<<8)+temp_l; ++ temp = (temp/3); ++ lt9611->h_act = lt9611->h_act+temp; ++ ++ } ++ regmap_read(lt9611->regmap, 0x88, &(lt9611->mipi_video_format)); ++ htotal_sysclk = lt9611_htotal_sysclk(lt9611); ++printk("--YYS---111 \n"); ++ if((lt9611->h_act==video_640x480_60Hz.hact)&& ++ (lt9611->h_act == video_640x480_60Hz.vact)&& ++ (lt9611->v_tal==video_640x480_60Hz.vtotal)){ ++ ++ DEBUG("ADLINK %s: Video_Check = video_640x480_60Hz\n", __func__); ++ lt9611->video_format = video_640x480_60Hz_vic1; ++ lt9611->hdmi_vic=1; ++ lt9611->video = &video_640x480_60Hz; ++ ++ ++ } ++ else if((lt9611->h_act == video_720x480_60Hz.hact)&& ++ (lt9611->v_act == video_720x480_60Hz.vact)&& ++ (lt9611->v_tal == video_720x480_60Hz.vtotal)){ ++ ++ DEBUG("ADLINK %s: Video_Check = video_720x480_60Hz\n", __func__); ++ lt9611->video_format = video_720x480_60Hz_vic3; ++ lt9611->video = &video_720x480_60Hz; ++ lt9611->hdmi_vic = 3; ++ } ++ ++ else if((lt9611->h_act == video_1280x720_60Hz.hact)&& ++ (lt9611->v_act == video_1280x720_60Hz.vact)&& ++ (lt9611->v_tal == video_1280x720_60Hz.vtotal)){ ++ ++ DEBUG("ADLINK %s: Video_Check = video_1280x720_60Hz\n", __func__); ++ lt9611->video_format = video_1280x720_60Hz_vic4; ++ lt9611->video = &video_1280x720_60Hz; ++ lt9611->hdmi_vic = 4; ++ } ++ else if((lt9611->h_act == video_1920x1080_60Hz.hact)&& ++ (lt9611->v_act == video_1920x1080_60Hz.vact)){ ++ ++ if(htotal_sysclk > 500){ ++ ++ DEBUG("ADLINK %s: Video_Check = video_1920x1080_30Hz\n", __func__); ++ lt9611->video_format = video_1920x1080_30Hz_vic; ++ lt9611->video = &video_1920x1080_30Hz; ++ lt9611->hdmi_vic = 34; ++ } ++ else{ ++ ++ DEBUG("ADLINK %s: Video_Check = video_1920x1080_60Hz\n", __func__); ++ lt9611->video_format = video_1920x1080_60Hz_vic16; ++ lt9611->video = &video_1920x1080_60Hz; ++ lt9611->hdmi_vic = 16; ++ } ++ }else if((lt9611->h_act == video_3840x2160_30Hz.hact)&& ++ (lt9611->v_act == video_3840x2160_30Hz.vact)){ ++ ++ DEBUG("ADLINK %s: Video_Check = video_3840x2160_30Hz\n", __func__); ++ lt9611->video_format = video_3840x2160_30Hz_vic; ++ lt9611->video = &video_3840x2160_30Hz; ++ lt9611->hdmi_vic = 95; ++ ++ }else if((lt9611->h_act == video_3840x1080_60Hz.hact)&& ++ (lt9611->v_act == video_3840x1080_60Hz.vact)){ ++ ++ DEBUG("ADLINK %s: Video_Check = video_3840x1080_60Hz\n", __func__); ++ lt9611->video_format = video_3840x1080_60Hz_vic; ++ lt9611->video = &video_3840x1080_60Hz; ++ lt9611->hdmi_vic = 0; ++ ++ }else if((lt9611->h_act == video_1024x600_60Hz.hact)&& ++ (lt9611->v_act == video_1024x600_60Hz.vact)){ ++ ++ DEBUG("ADLINK %s: Video_Check = video_1024x600_60Hz\n", __func__); ++ lt9611->video_format = video_1024x600_60Hz_vic; ++ lt9611->video = &video_1024x600_60Hz; ++ lt9611->hdmi_vic = 0; ++ } ++ else{//YYS ++ ++ lt9611->video_format = video_1280x720_60Hz_vic4; ++ lt9611->video = &video_1280x720_60Hz; ++ lt9611->hdmi_vic = 4; ++ ++ lt9611->video_format = video_1920x1080_30Hz_vic; ++ lt9611->video = &video_1920x1080_30Hz; ++ lt9611->hdmi_vic = 34; ++ ++ DEBUG("ADLINK %s:Video_Check = unknown video format\n", __func__); ++ } ++ ++ ++} ++ ++static void lt9611_frequency_meter_byte_clk(struct lt9611 *lt9611) ++{ ++ int temp; ++ int reg = 0x00; ++ ++ /* port A byte clk meter */ ++ regmap_write(lt9611->regmap, 0xff, 0x82); ++ regmap_write(lt9611->regmap, 0xff, 0x83);//PortA ++ msleep(50); ++ regmap_read(lt9611->regmap, 0xcd, &temp); ++ if((temp&0x60) == 0x60) /* clk stable */ ++ { ++ reg = (temp&0x0f) * 65536; ++ regmap_read(lt9611->regmap, 0xce, &temp); ++ reg = reg + temp*256; ++ regmap_read(lt9611->regmap, 0xcf, &temp); ++ reg = reg + temp; ++ DEBUG("ADLINK %s:port A byte clk = %d\n", __func__, reg); ++ ++ } ++ else /* clk unstable */ ++ DEBUG("ADLINK %s:port A byte clk unstable\n", __func__); ++ ++ /* port B byte clk meter */ ++ regmap_write(lt9611->regmap, 0xff, 0x82); ++ regmap_write(lt9611->regmap, 0xc7, 0x04);//PortA ++ msleep(50); ++ regmap_read(lt9611->regmap, 0xcd, &temp); ++ ++ if((temp&0x60) == 0x60) /* clk stable */ ++ { ++ reg = (temp&0x0f) * 65536; ++ regmap_read(lt9611->regmap, 0xce, &temp); ++ reg =reg + temp*256; ++ regmap_read(lt9611->regmap, 0xcf, &temp); ++ reg = reg + temp; ++ ++ DEBUG("ADLINK %s:port B byte clk = %d\n", __func__, reg); ++ ++ } ++ else /* clk unstable */ ++ DEBUG("ADLINK %s:port B byte clk unstable\n", __func__); ++} ++ ++static void lt9611_mipi_video_timing(struct lt9611 *lt9611) //weiguo ++{ ++ struct video_timing *video_format = lt9611->video; ++ regmap_write(lt9611->regmap, 0xff, 0x83); ++ regmap_write(lt9611->regmap, 0x0d, (video_format->vtotal/256)); ++ regmap_write(lt9611->regmap, 0x0e, (video_format->vtotal%256));//vtotal ++ regmap_write(lt9611->regmap, 0x0f, (video_format->vact/256)); ++ regmap_write(lt9611->regmap, 0x10, (video_format->vact%256)); //vactive ++ regmap_write(lt9611->regmap, 0x11, (video_format->htotal/256)); ++ regmap_write(lt9611->regmap, 0x12, (video_format->htotal%256));//htotal ++ regmap_write(lt9611->regmap, 0x13, (video_format->hact/256)); ++ regmap_write(lt9611->regmap, 0x14, (video_format->hact%256)); //hactive ++ regmap_write(lt9611->regmap, 0x15, (video_format->vs%256)); //vsa ++ regmap_write(lt9611->regmap, 0x16, (video_format->hs%256)); //hsa ++ regmap_write(lt9611->regmap, 0x17, (video_format->vfp%256)); //vfp ++ regmap_write(lt9611->regmap, 0x18, ((video_format->vs+video_format->vbp)%256)); //vss ++ regmap_write(lt9611->regmap, 0x19, (video_format->hfp%256)); //hfp ++ regmap_write(lt9611->regmap, 0x1a, ((video_format->hs+video_format->hbp)/256)); ++ regmap_write(lt9611->regmap, 0x1b, ((video_format->hs+video_format->hbp)%256)); //hss ++ ++} ++ ++static void lt9611_mipi_pcr(struct lt9611 *lt9611) //weiguo ++{ ++ regmap_write(lt9611->regmap, 0xff, 0x83); ++ regmap_write(lt9611->regmap, 0x0b, 0x01); //vsync read delay(reference value) ++ regmap_write(lt9611->regmap, 0x0c, 0x10); // ++ ++ regmap_write(lt9611->regmap, 0x48, 0x00); //de mode delay ++ regmap_write(lt9611->regmap, 0x49, 0x81); //=1/4 hact ++ ++ /* stage 1 */ ++ regmap_write(lt9611->regmap, 0x21, 0x4a); //bit[3:0] step[11:8] ++ //regmap_write(lt9611->regmap,0x22,0x40);//step[7:0] ++ ++ regmap_write(lt9611->regmap, 0x24, 0x71); //bit[7:4]v/h/de mode; line for clk stb[11:8] ++ regmap_write(lt9611->regmap, 0x25, 0x50); //line for clk stb[7:0] ++ ++ regmap_write(lt9611->regmap, 0x2a, 0x02); //clk stable in ++ ++ /* stage 2 */ ++ regmap_write(lt9611->regmap, 0x4a, 0x40); //offset //0x10 ++ regmap_write(lt9611->regmap, 0x1d, 0x80); //PCR de mode step setting. ++ //regmap_write(lt9611->regmap,0x23,0x01); // ++ ++ /* MK limit */ ++ regmap_write(lt9611->regmap, 0x2d, 0x38); //M up limit ++ regmap_write(lt9611->regmap, 0x31, 0x08); //M down limit ++ ++ switch(lt9611->video_format) ++ { ++ case video_3840x1080_60Hz_vic: ++ case video_3840x2160_30Hz_vic: ++ ++ regmap_write(lt9611->regmap, 0x0b, 0x03); //vsync mode ++ regmap_write(lt9611->regmap, 0x0c, 0xd0); //=1/4 hact ++ ++ regmap_write(lt9611->regmap, 0x48, 0x03); //de mode delay ++ regmap_write(lt9611->regmap, 0x49, 0xe0); // ++ ++ regmap_write(lt9611->regmap, 0x24, 0x72); //bit[7:4]v/h/de mode; line for clk stb[11:8] ++ regmap_write(lt9611->regmap, 0x25, 0x00); //line for clk stb[7:0] ++ ++ regmap_write(lt9611->regmap, 0x2a, 0x01); //clk stable in ++ ++ regmap_write(lt9611->regmap, 0x4a, 0x10); //offset ++ regmap_write(lt9611->regmap, 0x1d, 0x10); //PCR de mode step setting. ++ ++ regmap_write(lt9611->regmap, 0x26, 0x37); ++ break; ++ ++ case video_1920x1080_60Hz_vic16: ++ regmap_write(lt9611->regmap, 0x26, 0x37); ++ break; ++ ++ case video_1920x1080_30Hz_vic: ++ ++ regmap_write(lt9611->regmap, 0x26, 0x1c); ++ break; ++ ++ case video_1280x720_60Hz_vic4: ++ case video_1280x720_30Hz_vic: ++ regmap_write(lt9611->regmap, 0x26, 0x1c); ++ break; ++ ++ case video_1024x600_60Hz_vic: ++ regmap_write(lt9611->regmap, 0x24, 0x70); //bit[7:4]v/h/de mode; line for clk stb[11:8] ++ regmap_write(lt9611->regmap, 0x25, 0x80); //line for clk stb[7:0] ++ ++ regmap_write(lt9611->regmap, 0x2a, 0x10); //clk stable in ++ ++ /* stage 2 */ ++ //regmap_write(lt9611->regmap,0x23,0x04); //pcr h mode step ++ //regmap_write(lt9611->regmap,0x4a,0x10); //offset //0x10 ++ regmap_write(lt9611->regmap, 0x1d, 0xf0); //PCR de mode step setting. ++ ++ regmap_write(lt9611->regmap,0x26,0x19); //pcr_m ++ ++ break; ++ ++ case video_720x480_60Hz_vic3: ++ case video_640x480_60Hz_vic1: ++ ++ regmap_write(lt9611->regmap, 0x26, 0x14); ++ break; ++ ++ default: break; ++ } ++ ++ lt9611_mipi_video_timing(lt9611); ++ ++ regmap_write(lt9611->regmap, 0xff, 0x80); ++ regmap_write(lt9611->regmap, 0x11, 0x5a); //Pcr reset ++ regmap_write(lt9611->regmap, 0x11, 0xfa); ++ ++} ++ ++static void lt9611_pll(struct lt9611 *lt9611) //zhangzhichun ++{ ++ int pclk; ++ int pll_lock_flag; ++ int i; ++ struct video_timing *video_format = lt9611->video; ++ pclk = video_format->pclk_khz; ++ DEBUG("ADLINK %s:set rx pll = %d\n", __func__, pclk); ++ ++ regmap_write(lt9611->regmap, 0xff, 0x81); ++ regmap_write(lt9611->regmap, 0x23, 0x40); ++ regmap_write(lt9611->regmap, 0x24, 0x64); ++ regmap_write(lt9611->regmap, 0x25, 0x80); //pre-divider ++ regmap_write(lt9611->regmap, 0x26, 0x55); ++ regmap_write(lt9611->regmap, 0x2c, 0x37); ++ ++ regmap_write(lt9611->regmap, 0x2f, 0x01); ++ regmap_write(lt9611->regmap, 0x26, 0x55); ++ regmap_write(lt9611->regmap, 0x27, 0x66); ++ regmap_write(lt9611->regmap, 0x28, 0x88); ++ ++ if(pclk > 150000) ++ regmap_write(lt9611->regmap, 0x2d, 0x88); ++ else if(pclk > 70000) ++ regmap_write(lt9611->regmap, 0x2d, 0x99); ++ else ++ regmap_write(lt9611->regmap, 0x2d, 0xaa); //0xaa ++ ++ pclk = pclk / 2; ++ regmap_write(lt9611->regmap, 0xff, 0x82); //13.5M ++ regmap_write(lt9611->regmap, 0xe3, pclk/65536); ++ pclk = pclk % 65536; ++ regmap_write(lt9611->regmap, 0xe4, pclk/256); ++ regmap_write(lt9611->regmap, 0xe5, pclk%256); ++ ++ regmap_write(lt9611->regmap, 0xde, 0x20); ++ regmap_write(lt9611->regmap, 0xde, 0xe0); ++ ++ regmap_write(lt9611->regmap, 0xff, 0x80); ++ regmap_write(lt9611->regmap, 0x11, 0x5a); /* Pcr clk reset */ ++ regmap_write(lt9611->regmap, 0x11, 0xfa); ++ regmap_write(lt9611->regmap, 0x18, 0xdc); /* pll analog reset */ ++ regmap_write(lt9611->regmap, 0x18, 0xfc); ++ regmap_write(lt9611->regmap, 0x16, 0xf1); ++ regmap_write(lt9611->regmap, 0x16, 0xf3); ++ ++ /* pll lock status */ ++ for(i = 0; i < 6 ; i++) ++ { ++ regmap_write(lt9611->regmap, 0xff, 0x80); ++ regmap_write(lt9611->regmap, 0x16, 0xe3); /* pll lock logic reset */ ++ regmap_write(lt9611->regmap, 0x16, 0xf3); ++ regmap_write(lt9611->regmap, 0xff, 0x82); ++ regmap_read(lt9611->regmap, 0x15, &pll_lock_flag); ++ if(pll_lock_flag & 0x80) ++ { ++ DEBUG("ADLINK %s:HDMI pll locked\n", __func__); ++ break; ++ } ++ else ++ { ++ regmap_write(lt9611->regmap, 0xff, 0x80); ++ regmap_write(lt9611->regmap, 0x11, 0x5a); /* Pcr clk reset */ ++ regmap_write(lt9611->regmap, 0x11, 0xfa); ++ regmap_write(lt9611->regmap, 0x18, 0xdc); /* pll analog reset */ ++ regmap_write(lt9611->regmap, 0x18, 0xfc); ++ regmap_write(lt9611->regmap, 0x16, 0xf1); /* pll cal reset*/ ++ regmap_write(lt9611->regmap,0x16, 0xf3); ++ DEBUG(" ADLINK %sHDMI pll unlocked, reset pll\n", __func__); ++ } ++ } ++} ++ ++static void lt9611_audio_init(struct lt9611 *lt9611) //sujin ++{ ++ #if 1 ++ if(lt9611_mode.audio_out==audio_i2s) ++ { ++ DEBUG("%s:Audio inut = I2S 2ch\n", __func__); ++ regmap_write(lt9611->regmap, 0xff, 0x82); ++ regmap_write(lt9611->regmap, 0xd6, 0x8c); ++ regmap_write(lt9611->regmap, 0xd7, 0x04); //sync polarity ++ ++ regmap_write(lt9611->regmap, 0xff, 0x84); ++ regmap_write(lt9611->regmap, 0x06, 0x08); ++ regmap_write(lt9611->regmap, 0x07, 0x10); ++ ++ regmap_write(lt9611->regmap, 0x34, 0xd4); //CTS_N ++ lt9611->audio_status = 1; ++ } ++ ++ if(lt9611_mode.audio_out==audio_spdif) ++ { ++ DEBUG("%s:Audio inut = SPDIF\n", __func__); ++ regmap_write(lt9611->regmap, 0xff, 0x82); ++ regmap_write(lt9611->regmap, 0xd6, 0x8c); ++ regmap_write(lt9611->regmap, 0xd7, 0x04); //sync polarity ++ ++ regmap_write(lt9611->regmap, 0xff, 0x84); ++ regmap_write(lt9611->regmap, 0x06, 0x0c); ++ regmap_write(lt9611->regmap, 0x07, 0x10); ++ ++ regmap_write(lt9611->regmap, 0x34, 0xd4); //CTS_N ++ } ++ #endif ++} ++ ++ ++static void lt9611_csc(struct lt9611 *lt9611) //dsren ++{ ++ #if (Video_Output_Mode == Output_RGB888) ++ { ++ lt9611->hdmi_y=0; ++ regmap_write(lt9611->regmap,0xff,0x82); ++ regmap_write(lt9611->regmap,0xb9,0x00); //No csc ++ } ++ #elif (Video_Output_Mode == Output_YCbCr444) ++ { ++ lt9611->hdmi_y=1; ++ regmap_write(lt9611->regmap,0xb9,0x00); //RGB to YCbCr ++ } ++ #elif (Video_Output_Mode == Output_YCbCr22) ++ { ++ lt9611->hdmi_y=2; ++ regmap_write(lt9611->regmap,0xb9,0x00); //RGB to YCbCr ++ } ++ #endif ++} ++ ++static void lt9611_hdcp_init(struct lt9611 *lt9611) //luodexing ++{ ++ regmap_write(lt9611->regmap,0xff,0x85); ++ regmap_write(lt9611->regmap,0x07,0x1f); ++ regmap_write(lt9611->regmap,0x13,0xfe);// [7]=force_hpd, [6]=force_rsen, [5]=vsync_pol, [4]=hsync_pol, ++ // [3]=hdmi_mode, [2]=no_accs_when_rdy, [1]=skip_wt_hdmi ++ regmap_write(lt9611->regmap,0x17,0x0f);// [7]=ri_short_read, [3]=sync_pol_mode, [2]=srm_chk_done, ++ // [1]=bksv_srm_pass, [0]=ksv_list_vld ++ regmap_write(lt9611->regmap,0x15,0x05); ++ //regmap_write(lt9611->regmap,0x15,0x65);// [7]=key_ddc_st_sel, [6]=tx_hdcp_en,[5]=tx_auth_en, [4]=tx_re_auth ++} ++ ++static void lt9611_hdmi_tx_digital(struct lt9611 *lt9611) //dsren ++{ ++ //AVI ++ regmap_write(lt9611->regmap,0xff,0x84); ++ regmap_write(lt9611->regmap,0x43,0x56-lt9611->hdmi_vic-((lt9611->hdmi_y<<5)+0x10)); //AVI_PB0 ++ regmap_write(lt9611->regmap,0x44,(lt9611->hdmi_y<<5)+0x10); //AVI_PB1 ++ regmap_write(lt9611->regmap,0x47,lt9611->hdmi_vic); //AVI_PB1 ++} ++ ++static void lt9611_hdmi_tx_phy(struct lt9611 *lt9611) //xyji ++{ ++ regmap_write(lt9611->regmap,0xff,0x81); ++ regmap_write(lt9611->regmap,0x30,0x6a); ++ if(lt9611_mode.hdmi_coupling_mode==ac_mode) ++ { ++ regmap_write(lt9611->regmap,0x31,0x73); //DC: 0x44, AC:0x73 ++ } ++ else //lt9611.hdmi_coupling_mode==dc_mode ++ { ++ regmap_write(lt9611->regmap,0x31,0x44); ++ } ++ regmap_write(lt9611->regmap,0x32,0x4a); ++ regmap_write(lt9611->regmap,0x33,0x0b); ++ regmap_write(lt9611->regmap,0x34,0x00); ++ regmap_write(lt9611->regmap,0x35,0x00); ++ regmap_write(lt9611->regmap,0x36,0x00); ++ regmap_write(lt9611->regmap,0x37,0x44); ++ regmap_write(lt9611->regmap,0x3f,0x0f); ++ regmap_write(lt9611->regmap,0x40,0xa0); ++ regmap_write(lt9611->regmap,0x41,0xa0); ++ regmap_write(lt9611->regmap,0x42,0xa0); ++ regmap_write(lt9611->regmap,0x43,0xa0); ++ regmap_write(lt9611->regmap,0x44,0x0a); ++} ++ ++void lt9611_hdmi_out_enable(struct lt9611 *lt9611) //dsren ++{ ++ regmap_write(lt9611->regmap,0xff,0x81); ++ regmap_write(lt9611->regmap,0x23,0x40); ++ ++ regmap_write(lt9611->regmap,0xff,0x82); ++ regmap_write(lt9611->regmap,0xde,0x20); ++ regmap_write(lt9611->regmap,0xde,0xe0); ++ ++ regmap_write(lt9611->regmap,0xff,0x80); ++ regmap_write(lt9611->regmap,0x18,0xdc); /* txpll sw rst */ ++ regmap_write(lt9611->regmap,0x18,0xfc); ++ regmap_write(lt9611->regmap,0x16,0xf1); /* txpll calibration rest */ ++ regmap_write(lt9611->regmap,0x16,0xf3); ++ ++ regmap_write(lt9611->regmap,0x11,0x5a); //Pcr reset ++ regmap_write(lt9611->regmap,0x11,0xfa); ++ ++ regmap_write(lt9611->regmap,0xff,0x81); ++ regmap_write(lt9611->regmap,0x30,0xea); ++} ++ ++static void lt9611_hdcp_enable(struct lt9611 *lt9611) //luodexing ++{ ++#if 0 ++ regmap_write(lt9611->regmap,0xff,0x80); ++ regmap_write(lt9611->regmap,0x14,0x7f); ++ regmap_write(lt9611->regmap,0x14,0xff); ++ regmap_write(lt9611->regmap,0xff,0x85); ++ regmap_write(lt9611->regmap,0x15,0x01); //disable HDCP ++ regmap_write(lt9611->regmap,0x15,0x71); //enable HDCP ++ regmap_write(lt9611->regmap,0x15,0x65); //enable HDCP ++#endif ++} ++ ++static void lt9611_audio_enable(struct lt9611 *lt9611) //luodexing ++{ ++ regmap_write(lt9611->regmap,0xff,0x84); ++ regmap_write(lt9611->regmap,0x06,0x08); ++} ++ ++static void lt9611_audio_disable(struct lt9611 *lt9611) //luodexing ++{ ++ regmap_write(lt9611->regmap,0xff,0x84); ++ regmap_write(lt9611->regmap,0x06,0x00); ++} ++ ++static const struct regmap_config lt9611_regmap_config = { ++ .reg_bits = 8, ++ .val_bits = 8, ++ .max_register = 0xff, ++}; ++ ++ ++static ssize_t audio_show(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ char *s= buf; ++ int len; ++ struct lt9611 *lt9611 = dev_get_drvdata(dev); ++ if(lt9611->audio_status){ ++ s += sprintf(s, "%s\n", STRING_ON); ++ }else{ ++ s += sprintf(s,"%s\n", STRING_OFF); ++ } ++ ++ if (s != buf) ++ { ++ *(s-1) = '\n'; ++ } ++ ++ len = (s - buf); ++ ++ return len; ++} ++ ++static ssize_t audio_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) ++{ ++ char *p; ++ int len; ++ struct lt9611 *lt9611 = dev_get_drvdata(dev); ++ p = memchr(buf, '\n', count); ++ len = p ? p - buf : count; ++ ++ if(!strncmp(buf, STRING_ON, len )) ++ { ++ lt9611->audio_status = 1; ++ lt9611_audio_enable(lt9611); ++ } ++ else if(!strncmp(buf, STRING_OFF, len )) ++ { ++ lt9611->audio_status = 0; ++ lt9611_audio_disable(lt9611); ++ } ++ ++ return count; ++} ++static DEVICE_ATTR(audio, 0664, audio_show, audio_store); ++ ++static int lt9611_bridge_suspend(struct device *dev) ++{ ++ struct lt9611 *lt9611 = dev_get_drvdata(dev); ++ lt9611_hdmi_out_disable(lt9611); ++ return 0; ++} ++ ++static int lt9611_bridge_resume(struct device *dev) ++{ ++ struct lt9611 *lt9611 = dev_get_drvdata(dev); ++ lt9611_pll(lt9611); ++ lt9611_mipi_pcr(lt9611); ++ lt9611_hdmi_tx_digital(lt9611); ++ lt9611_hdmi_out_enable(lt9611); ++ return 0; ++} ++ ++static SIMPLE_DEV_PM_OPS(lt9611_bridge_pm_ops, ++ lt9611_bridge_suspend, ++ lt9611_bridge_resume); ++ ++static int lt9611_probe(struct i2c_client *client, const struct i2c_device_id *id) ++{ ++ struct device *dev = &client->dev; ++ int ret; ++ struct lt9611 *lt9611; ++ ++ // if(1) return 0; ++ ++ printk("ADLINK ,LT9611 DRIVER \n"); ++ lt9611 = devm_kzalloc(dev, sizeof(*lt9611), GFP_KERNEL); ++ if (!lt9611){ ++ dev_err(dev, "failed to alloc memory\n"); ++ printk("ADLINK :%s failed to alloc memory \n",__func__); ++ return -ENOMEM; ++ } ++ dev_set_drvdata(dev, lt9611); ++ ++ ++ lt9611->reset_n = devm_gpiod_get(dev, "reset", GPIOD_ASIS); ++ if (IS_ERR(lt9611->reset_n)) { ++ ret = PTR_ERR(lt9611->reset_n); ++ printk("ADLINK :%s failed to request reset GPIO \n",__func__); ++ ++ dev_err(dev, "failed to request reset GPIO: %d\n", ret); ++ return ret; ++ } ++ ++ lt9611->regmap = devm_regmap_init_i2c(client, <9611_regmap_config); ++ if (IS_ERR(lt9611->regmap)) { ++ dev_err(dev, "failed to allocate register map\n"); ++ ++ printk("ADLINK :%s failed to allocate register map \n",__func__); ++ ++ return PTR_ERR(lt9611->regmap); ++ } ++ ++ ret = device_create_file(dev, &dev_attr_audio); ++ if(ret < 0){ ++ dev_err(dev, "failed to create attribute file\n"); ++ printk("ADLINK :%s failed to create attribute \n",__func__); ++ ++ return ret; ++ } ++ ++ lt9611_power_on(lt9611); ++ lt9611_hdcp_enable(lt9611); //dummy ++ lt9611_chip_id(lt9611); ++ lt9611_system_init(lt9611); ++ lt9611_mipi_input_analog(lt9611); ++ lt9611_mipi_input_digtal(lt9611); ++ msleep(1000); ++ lt9611_video_check(lt9611); ++ lt9611_frequency_meter_byte_clk(lt9611); ++ lt9611_mipi_pcr(lt9611); ++ lt9611_pll(lt9611); ++ lt9611_audio_init(lt9611); ++ lt9611_csc(lt9611); ++ lt9611_hdcp_init(lt9611); ++ lt9611_hdmi_tx_digital(lt9611); ++ lt9611_hdmi_tx_phy(lt9611); ++ lt9611_hdmi_out_enable(lt9611); ++ return 0; ++} ++static int lt9611_remove(struct i2c_client *client) ++{ ++ return 0; ++} ++ ++static struct i2c_device_id lt9611_id[] = { ++ { "lt9611", 0 }, ++ {} ++}; ++ ++static const struct of_device_id lt9611_match_table[] = { ++ { .compatible = "firefly, lt9611" }, ++ {} ++}; ++ ++MODULE_DEVICE_TABLE(of, lt9611_match_table); ++ ++static struct i2c_driver lt9611_driver = { ++ .driver = { ++ .name = "lt9611", ++ .owner = THIS_MODULE, ++ .of_match_table = lt9611_match_table, ++ .pm = <9611_bridge_pm_ops, ++ }, ++ .probe = lt9611_probe, ++ .remove = lt9611_remove, ++ .id_table = lt9611_id, ++ ++}; ++ ++static int __init lt9611_init(void) ++{ ++ return i2c_add_driver(<9611_driver); ++} ++ ++static void __exit lt9611_exit(void) ++{ ++ i2c_del_driver(<9611_driver); ++} ++ ++module_init(lt9611_init); ++module_exit(lt9611_exit); ++ ++ ++MODULE_AUTHOR("xhguo@lontium.com"); ++MODULE_DESCRIPTION("Lontium bridge IC LT9611 that convert mipi to hdmi)"); ++MODULE_LICENSE("GPL"); ++ +-- +2.7.4 + diff --git a/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0005-Modified-compatible-property-as-per-target-kernel-dt.patch b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0005-Modified-compatible-property-as-per-target-kernel-dt.patch new file mode 100644 index 000000000..d5a3c4470 --- /dev/null +++ b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0005-Modified-compatible-property-as-per-target-kernel-dt.patch @@ -0,0 +1,40 @@ +From 73325c6a311a6e606714a48b2ca5615ea512254f Mon Sep 17 00:00:00 2001 +From: Dineshkumar V <dineshkumar.varadarajan@adlinktech.com> +Date: Thu, 5 Dec 2019 21:45:51 +0530 +Subject: [PATCH 5/5] Modified compatible property as per target kernel dts + file + +--- + drivers/clk/rockchip/clk-px30.c | 2 +- + drivers/cpufreq/rockchip-cpufreq.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/rockchip/clk-px30.c b/drivers/clk/rockchip/clk-px30.c +index 56e78c2..96690f1 100644 +--- a/drivers/clk/rockchip/clk-px30.c ++++ b/drivers/clk/rockchip/clk-px30.c +@@ -1068,7 +1068,7 @@ static void __init px30_clk_init(struct device_node *np) + PX30_GRF_SOC_STATUS0); + rockchip_clk_register_branches(ctx, px30_clk_branches, + ARRAY_SIZE(px30_clk_branches)); +- if (of_machine_is_compatible("rockchip,px30")) ++ if (of_machine_is_compatible("adlink,lec-px30")) + rockchip_clk_register_branches(ctx, px30_gpu_src_clk, + ARRAY_SIZE(px30_gpu_src_clk)); + else +diff --git a/drivers/cpufreq/rockchip-cpufreq.c b/drivers/cpufreq/rockchip-cpufreq.c +index c206b7c..ccb38ab 100644 +--- a/drivers/cpufreq/rockchip-cpufreq.c ++++ b/drivers/cpufreq/rockchip-cpufreq.c +@@ -164,7 +164,7 @@ out: + } + static const struct of_device_id rockchip_cpufreq_of_match[] = { + { +- .compatible = "rockchip,px30", ++ .compatible = "adlink,lec-px30", + .data = (void *)&px30_get_soc_info, + }, + { +-- +2.7.4 + diff --git a/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0006-Added-Sx150x-gpio-expander-suppport-for-LEC-PX30-A2.patch b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0006-Added-Sx150x-gpio-expander-suppport-for-LEC-PX30-A2.patch new file mode 100644 index 000000000..fbc80f9cb --- /dev/null +++ b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0006-Added-Sx150x-gpio-expander-suppport-for-LEC-PX30-A2.patch @@ -0,0 +1,289 @@ +From 1044a22daf998d8ba03001906ecd54cfb223ba35 Mon Sep 17 00:00:00 2001 +From: Dineshkumar V <dineshkumar.varadarajan@adlinktech.com> +Date: Wed, 19 Feb 2020 16:10:40 +0530 +Subject: [PATCH 6/6] Added Sx150x gpio expander suppport for LEC-PX30-A2 + +--- + drivers/gpio/gpio-sx150x.c | 242 ++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 240 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpio/gpio-sx150x.c b/drivers/gpio/gpio-sx150x.c +index c014515..1011aa5 100644 +--- a/drivers/gpio/gpio-sx150x.c ++++ b/drivers/gpio/gpio-sx150x.c +@@ -620,6 +620,224 @@ static int sx150x_install_irq_chip(struct sx150x_chip *chip, + + return err; + } ++static struct sx150x_platform_data *of_sx150x_get_platdata( ++ struct i2c_client *client) ++{ ++ int rc, gpio; ++ struct sx150x_platform_data *pdata; ++ struct device_node *np; ++ u32 value; ++ if (!client->dev.of_node) ++ return NULL; ++ np = client->dev.of_node; ++ pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); ++ if (!pdata) ++ return ERR_PTR(-ENOMEM); ++ gpio = of_get_named_gpio(np, "int-gpios", 0); ++ if (gpio_is_valid(gpio)) { ++ rc = devm_gpio_request_one(&client->dev, gpio, ++ GPIOF_DIR_IN, "sx150x_interrupt"); ++ if (rc) ++ return ERR_PTR(rc); ++ } ++ pdata->irq_summary = irq_of_parse_and_map(np, 0); ++ if (!pdata->irq_summary) ++ return ERR_PTR(-EPROBE_DEFER); ++ pdata->oscio_is_gpo = of_property_read_bool(np, "oscio_is_gpo"); ++ pdata->reset_during_probe =of_property_read_bool(np, "reset_during_probe"); ++ rc = of_property_read_u32(np, "pullup_ena",&value); ++ if (rc) ++ pdata->io_pullup_ena = 0; ++ else ++ pdata->io_pullup_ena = value&0xffff; ++ rc = of_property_read_u32(np, "pulldn_ena",&value); ++ if (rc) ++ pdata->io_pulldn_ena = 0; ++ else ++ pdata->io_pulldn_ena = value&0xffff; ++ rc = of_property_read_u32(np, "open_drain_ena",&value); ++ if (rc) ++ pdata->io_open_drain_ena = 0; ++ else ++ pdata->io_pulldn_ena = value&0xffff; ++ rc = of_property_read_u32(np, "polarity",&value); ++ if (rc) ++ pdata->io_polarity = 0; ++ else ++ pdata->io_polarity = value&0xffff; ++ printk("io_pullup_ena=0x%x,io_pulldn_ena=0x%x,io_open_drain_ena=0x%x,pdata->io_polarity=0x%x\n",pdata->io_pullup_ena,pdata->io_pulldn_ena,pdata->io_open_drain_ena,pdata->io_polarity); ++ pdata->gpio_base = -1; ++ pdata->irq_base = 0; ++ return pdata; ++} ++//test pwd ++#if 0 ++void init(struct i2c_client *client) ++{ ++#define REG_MISC 0x1f ++#define REG_CLOCK 0x1e ++ sx150x_i2c_write(client,REG_MISC,16); ++ sx150x_i2c_write(client,REG_CLOCK,64); ++} ++#define REG_INPUT_DISABLE_B 0x00 // RegInputDisableB Input buffer disable register _ I/O[15_8] (Bank B) 0000 0000 ++#define REG_INPUT_DISABLE_A 0x01 // RegInputDisableA Input buffer disable register _ I/O[7_0] (Bank A) 0000 0000 ++#define REG_LONG_SLEW_B 0x02 // RegLongSlewB Output buffer long slew register _ I/O[15_8] (Bank B) 0000 0000 ++#define REG_LONG_SLEW_A 0x03 // RegLongSlewA Output buffer long slew register _ I/O[7_0] (Bank A) 0000 0000 ++#define REG_LOW_DRIVE_B 0x04 // RegLowDriveB Output buffer low drive register _ I/O[15_8] (Bank B) 0000 0000 ++#define REG_LOW_DRIVE_A 0x05 // RegLowDriveA Output buffer low drive register _ I/O[7_0] (Bank A) 0000 0000 ++#define REG_PULL_UP_B 0x06 // RegPullUpB Pull_up register _ I/O[15_8] (Bank B) 0000 0000 ++#define REG_PULL_UP_A 0x07 // RegPullUpA Pull_up register _ I/O[7_0] (Bank A) 0000 0000 ++#define REG_PULL_DOWN_B 0x08 // RegPullDownB Pull_down register _ I/O[15_8] (Bank B) 0000 0000 ++#define REG_PULL_DOWN_A 0x09 // RegPullDownA Pull_down register _ I/O[7_0] (Bank A) 0000 0000 ++#define REG_OPEN_DRAIN_B 0x0A // RegOpenDrainB Open drain register _ I/O[15_8] (Bank B) 0000 0000 ++#define REG_OPEN_DRAIN_A 0x0B // RegOpenDrainA Open drain register _ I/O[7_0] (Bank A) 0000 0000 ++#define REG_POLARITY_B 0x0C // RegPolarityB Polarity register _ I/O[15_8] (Bank B) 0000 0000 ++#define REG_POLARITY_A 0x0D // RegPolarityA Polarity register _ I/O[7_0] (Bank A) 0000 0000 ++#define REG_DIR_B 0x0E // RegDirB Direction register _ I/O[15_8] (Bank B) 1111 1111 ++#define REG_DIR_A 0x0F // RegDirA Direction register _ I/O[7_0] (Bank A) 1111 1111 ++#define REG_DATA_B 0x10 // RegDataB Data register _ I/O[15_8] (Bank B) 1111 1111* ++#define REG_DATA_A 0x11 // RegDataA Data register _ I/O[7_0] (Bank A) 1111 1111* ++#define REG_INTERRUPT_MASK_B 0x12 // RegInterruptMaskB Interrupt mask register _ I/O[15_8] (Bank B) 1111 1111 ++#define REG_INTERRUPT_MASK_A 0x13 // RegInterruptMaskA Interrupt mask register _ I/O[7_0] (Bank A) 1111 1111 ++#define REG_SENSE_HIGH_B 0x14 // RegSenseHighB Sense register for I/O[15:12] 0000 0000 ++#define REG_SENSE_LOW_B 0x15 // RegSenseLowB Sense register for I/O[11:8] 0000 0000 ++#define REG_SENSE_HIGH_A 0x16 // RegSenseHighA Sense register for I/O[7:4] 0000 0000 ++#define REG_SENSE_LOW_A 0x17 // RegSenseLowA Sense register for I/O[3:0] 0000 0000 ++#define REG_INTERRUPT_SOURCE_B 0x18 // RegInterruptSourceB Interrupt source register _ I/O[15_8] (Bank B) 0000 0000 ++#define REG_INTERRUPT_SOURCE_A 0x19 // RegInterruptSourceA Interrupt source register _ I/O[7_0] (Bank A) 0000 0000 ++#define REG_EVENT_STATUS_B 0x1A // RegEventStatusB Event status register _ I/O[15_8] (Bank B) 0000 0000 ++#define REG_EVENT_STATUS_A 0x1B // RegEventStatusA Event status register _ I/O[7_0] (Bank A) 0000 0000 ++#define REG_LEVEL_SHIFTER_1 0x1C // RegLevelShifter1 Level shifter register 0000 0000 ++#define REG_LEVEL_SHIFTER_2 0x1D // RegLevelShifter2 Level shifter register 0000 0000 ++#define REG_LED_DRIVER_ENABLE_B 0x20 // RegLEDDriverEnableB LED driver enable register _ I/O[15_8] (Bank B) 0000 0000 ++#define REG_LED_DRIVER_ENABLE_A 0x21 // RegLEDDriverEnableA LED driver enable register _ I/O[7_0] (Bank A) 0000 0000 ++#define REG_DEBOUNCE_CONFIG 0x22 // RegDebounceConfig Debounce configuration register 0000 0000 ++#define REG_DEBOUNCE_ENABLE_B 0x23 // RegDebounceEnableB Debounce enable register _ I/O[15_8] (Bank B) 0000 0000 ++#define REG_DEBOUNCE_ENABLE_A 0x24 // RegDebounceEnableA Debounce enable register _ I/O[7_0] (Bank A) 0000 0000 ++#define REG_KEY_CONFIG_1 0x25 // RegKeyConfig1 Key scan configuration register 0000 0000 ++#define REG_KEY_CONFIG_2 0x26 // RegKeyConfig2 Key scan configuration register 0000 0000 ++#define REG_KEY_DATA_1 0x27 // RegKeyData1 Key value (column) 1111 1111 ++#define REG_KEY_DATA_2 0x28 // RegKeyData2 Key value (row) 1111 1111 ++#define REG_T_ON_0 0x29 // RegTOn0 ON time register for I/O[0] 0000 0000 ++#define REG_I_ON_0 0x2A // RegIOn0 ON intensity register for I/O[0] 1111 1111 ++#define REG_OFF_0 0x2B // RegOff0 OFF time/intensity register for I/O[0] 0000 0000 ++#define REG_T_ON_1 0x2C // RegTOn1 ON time register for I/O[1] 0000 0000 ++#define REG_I_ON_1 0x2D // RegIOn1 ON intensity register for I/O[1] 1111 1111 ++#define REG_OFF_1 0x2E // RegOff1 OFF time/intensity register for I/O[1] 0000 0000 ++#define REG_T_ON_2 0x2F // RegTOn2 ON time register for I/O[2] 0000 0000 ++#define REG_I_ON_2 0x30 // RegIOn2 ON intensity register for I/O[2] 1111 1111 ++#define REG_OFF_2 0x31 // RegOff2 OFF time/intensity register for I/O[2] 0000 0000 ++#define REG_T_ON_3 0x32 // RegTOn3 ON time register for I/O[3] 0000 0000 ++#define REG_I_ON_3 0x33 // RegIOn3 ON intensity register for I/O[3] 1111 1111 ++#define REG_OFF_3 0x34 // RegOff3 OFF time/intensity register for I/O[3] 0000 0000 ++#define REG_T_ON_4 0x35 // RegTOn4 ON time register for I/O[4] 0000 0000 ++#define REG_I_ON_4 0x36 // RegIOn4 ON intensity register for I/O[4] 1111 1111 ++#define REG_OFF_4 0x37 // RegOff4 OFF time/intensity register for I/O[4] 0000 0000 ++#define REG_T_RISE_4 0x38 // RegTRise4 Fade in register for I/O[4] 0000 0000 ++#define REG_T_FALL_4 0x39 // RegTFall4 Fade out register for I/O[4] 0000 0000 ++#define REG_T_ON_5 0x3A // RegTOn5 ON time register for I/O[5] 0000 0000 ++#define REG_I_ON_5 0x3B // RegIOn5 ON intensity register for I/O[5] 1111 1111 ++#define REG_OFF_5 0x3C // RegOff5 OFF time/intensity register for I/O[5] 0000 0000 ++#define REG_T_RISE_5 0x3D // RegTRise5 Fade in register for I/O[5] 0000 0000 ++#define REG_T_FALL_5 0x3E // RegTFall5 Fade out register for I/O[5] 0000 0000 ++#define REG_T_ON_6 0x3F // RegTOn6 ON time register for I/O[6] 0000 0000 ++#define REG_I_ON_6 0x40 // RegIOn6 ON intensity register for I/O[6] 1111 1111 ++#define REG_OFF_6 0x41 // RegOff6 OFF time/intensity register for I/O[6] 0000 0000 ++#define REG_T_RISE_6 0x42 // RegTRise6 Fade in register for I/O[6] 0000 0000 ++#define REG_T_FALL_6 0x43 // RegTFall6 Fade out register for I/O[6] 0000 0000 ++#define REG_T_ON_7 0x44 // RegTOn7 ON time register for I/O[7] 0000 0000 ++#define REG_I_ON_7 0x45 // RegIOn7 ON intensity register for I/O[7] 1111 1111 ++#define REG_OFF_7 0x46 // RegOff7 OFF time/intensity register for I/O[7] 0000 0000 ++#define REG_T_RISE_7 0x47 // RegTRise7 Fade in register for I/O[7] 0000 0000 ++#define REG_T_FALL_7 0x48 // RegTFall7 Fade out register for I/O[7] 0000 0000 ++#define REG_T_ON_8 0x49 // RegTOn8 ON time register for I/O[8] 0000 0000 ++#define REG_I_ON_8 0x4A // RegIOn8 ON intensity register for I/O[8] 1111 1111 ++#define REG_OFF_8 0x4B // RegOff8 OFF time/intensity register for I/O[8] 0000 0000 ++#define REG_T_ON_9 0x4C // RegTOn9 ON time register for I/O[9] 0000 0000 ++#define REG_I_ON_9 0x4D // RegIOn9 ON intensity register for I/O[9] 1111 1111 ++#define REG_OFF_9 0x4E // RegOff9 OFF time/intensity register for I/O[9] 0000 0000 ++#define REG_T_ON_10 0x4F // RegTOn10 ON time register for I/O[10] 0000 0000 ++#define REG_I_ON_10 0x50 // RegIOn10 ON intensity register for I/O[10] 1111 1111 ++#define REG_OFF_10 0x51 // RegOff10 OFF time/intensity register for I/O[10] 0000 0000 ++#define REG_T_ON_11 0x52 // RegTOn11 ON time register for I/O[11] 0000 0000 ++#define REG_I_ON_11 0x53 // RegIOn11 ON intensity register for I/O[11] 1111 1111 ++#define REG_OFF_11 0x54 // RegOff11 OFF time/intensity register for I/O[11] 0000 0000 ++#define REG_T_ON_12 0x55 // RegTOn12 ON time register for I/O[12] 0000 0000 ++#define REG_I_ON_12 0x56 // RegIOn12 ON intensity register for I/O[12] 1111 1111 ++#define REG_OFF_12 0x57 // RegOff12 OFF time/intensity register for I/O[12] 0000 0000 ++#define REG_T_RISE_12 0x58 // RegTRise12 Fade in register for I/O[12] 0000 0000 ++#define REG_T_FALL_12 0x59 // RegTFall12 Fade out register for I/O[12] 0000 0000 ++#define REG_T_ON_13 0x5A // RegTOn13 ON time register for I/O[13] 0000 0000 ++#define REG_I_ON_13 0x5B // RegIOn13 ON intensity register for I/O[13] 1111 1111 ++#define REG_OFF_13 0x5C // RegOff13 OFF time/intensity register for I/O[13] 0000 0000 ++#define REG_T_RISE_13 0x5D // RegTRise13 Fade in register for I/O[13] 0000 0000 ++#define REG_T_FALL_13 0x5E // RegTFall13 Fade out register for I/O[13] 0000 0000 ++#define REG_T_ON_14 0x5F // RegTOn14 ON time register for I/O[14] 0000 0000 ++#define REG_I_ON_14 0x60 // RegIOn14 ON intensity register for I/O[14] 1111 1111 ++#define REG_OFF_14 0x61 // RegOff14 OFF time/intensity register for I/O[14] 0000 0000 ++#define REG_T_RISE_14 0x62 // RegTRise14 Fade in register for I/O[14] 0000 0000 ++#define REG_T_FALL_14 0x63 // RegTFall14 Fade out register for I/O[14] 0000 0000 ++#define REG_T_ON_15 0x64 // RegTOn15 ON time register for I/O[15] 0000 0000 ++#define REG_I_ON_15 0x65 // RegIOn15 ON intensity register for I/O[15] 1111 1111 ++#define REG_OFF_15 0x66 // RegOff15 OFF time/intensity register for I/O[15] 0000 0000 ++#define REG_T_RISE_15 0x67 // RegTRise15 Fade in register for I/O[15] 0000 0000 ++#define REG_T_FALL_15 0x68 // RegTFall15 Fade out register for I/O[15] 0000 0000 ++#define REG_HIGH_INPUT_B 0x69 // RegHighInputB High input enable register _ I/O[15_8] (Bank B) 0000 0000 ++#define REG_HIGH_INPUT_A 0x6A // RegHighInputA High input enable register _ I/O[7_0] (Bank A) 0000 0000 ++#define REG_RESET 0x7D // RegReset Software reset register 0000 0000 ++#define REG_TEST_1 0x7E // RegTest1 Test register 0000 0000 ++#define REG_TEST_2 0x7F // RegTest2 Test register 0000 0000 ++uint8_t REG_I_ON[16] = {REG_I_ON_0, REG_I_ON_1, REG_I_ON_2, REG_I_ON_3, ++ REG_I_ON_4, REG_I_ON_5, REG_I_ON_6, REG_I_ON_7, ++ REG_I_ON_8, REG_I_ON_9, REG_I_ON_10, REG_I_ON_11, ++ REG_I_ON_12, REG_I_ON_13, REG_I_ON_14, REG_I_ON_15}; ++void ledDriverInit(struct i2c_client *client, uint8_t pin) ++{ ++ if(pin > 7) ++ { ++ uint8_t pinb = pin-8; ++ uint8_t temp; ++ sx150x_i2c_read(client,REG_INPUT_DISABLE_B,&temp); ++ temp |= (1<<pinb); ++ sx150x_i2c_write(client,REG_INPUT_DISABLE_B,temp); ++ sx150x_i2c_read(client,REG_PULL_UP_B,&temp); ++ temp &= ~(1<<pinb); ++ sx150x_i2c_write(client,REG_PULL_UP_B,temp); ++ sx150x_i2c_read(client,REG_DIR_B,&temp); ++ temp &= ~(1<<pinb); ++ sx150x_i2c_write(client,REG_DIR_B,temp); ++ sx150x_i2c_read(client,REG_LED_DRIVER_ENABLE_B,&temp); ++ temp |= (1<<pinb); ++ sx150x_i2c_write(client,REG_LED_DRIVER_ENABLE_B,temp); ++ sx150x_i2c_read(client,REG_DATA_B,&temp); ++ temp &= ~(1<<pinb); ++ sx150x_i2c_write(client,REG_DATA_B,temp); ++ } ++ else ++ { ++ uint8_t temp; ++ sx150x_i2c_read(client,REG_INPUT_DISABLE_A,&temp); ++ temp |= (1<<pin); ++ sx150x_i2c_write(client,REG_INPUT_DISABLE_A,temp); ++ sx150x_i2c_read(client,REG_PULL_UP_A,&temp); ++ temp &= ~(1<<pin); ++ sx150x_i2c_write(client,REG_PULL_UP_A,temp); ++ sx150x_i2c_read(client,REG_DIR_A,&temp); ++ temp &= ~(1<<pin); ++ sx150x_i2c_write(client,REG_DIR_A,temp); ++ sx150x_i2c_read(client,REG_LED_DRIVER_ENABLE_A,&temp); ++ temp |= (1<<pin); ++ sx150x_i2c_write(client,REG_LED_DRIVER_ENABLE_A,temp); ++ sx150x_i2c_read(client,REG_DATA_A,&temp); ++ temp &= ~(1<<pin); ++ sx150x_i2c_write(client,REG_DATA_A,temp); ++ } ++} ++void analogWrite(struct i2c_client *client,uint8_t pin,uint8_t cycle) ++{ ++ sx150x_i2c_write(client,REG_I_ON[pin], cycle); ++} ++#endif + + static int sx150x_probe(struct i2c_client *client, + const struct i2c_device_id *id) +@@ -629,10 +847,15 @@ static int sx150x_probe(struct i2c_client *client, + struct sx150x_platform_data *pdata; + struct sx150x_chip *chip; + int rc; +- ++ int irq; + pdata = dev_get_platdata(&client->dev); ++ if (!pdata) { ++ pdata = of_sx150x_get_platdata(client); + if (!pdata) + return -EINVAL; ++ else if (IS_ERR(pdata)) ++ return PTR_ERR(pdata); ++ } + + if (!i2c_check_functionality(client->adapter, i2c_funcs)) + return -ENOSYS; +@@ -650,7 +873,7 @@ static int sx150x_probe(struct i2c_client *client, + rc = gpiochip_add(&chip->gpio_chip); + if (rc) + return rc; +- ++ printk("pdata->irq_summary=%d\n",pdata->irq_summary); + if (pdata->irq_summary >= 0) { + rc = sx150x_install_irq_chip(chip, + pdata->irq_summary, +@@ -661,6 +884,21 @@ static int sx150x_probe(struct i2c_client *client, + + i2c_set_clientdata(client, chip); + ++ gpio_direction_input(504);//pin 8 ++ irq=gpio_to_irq(504); ++ printk("sx1509 irq=%d\n",irq); ++ enable_irq(irq); ++ printk("###########probe ok\n"); ++#if 0 ++ printk("sx150x test for pwm\n"); ++ init(client); ++ for(i=0; i < 16; i++) ++ { ++ ledDriverInit(client,i); ++ analogWrite(client,i,127); ++ } ++ printk("sx150xtest for pwm end\n"); ++#endif + return 0; + probe_fail_post_gpiochip_add: + gpiochip_remove(&chip->gpio_chip); +-- +2.7.4 + diff --git a/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0007-Added-SPI-chip-select-enable-disable-support-for-SPI.patch b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0007-Added-SPI-chip-select-enable-disable-support-for-SPI.patch new file mode 100644 index 000000000..d7c8532ae --- /dev/null +++ b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0007-Added-SPI-chip-select-enable-disable-support-for-SPI.patch @@ -0,0 +1,112 @@ +From 2ed09d2c6dabe7ae167b4e1fa585f5e1fbced5b2 Mon Sep 17 00:00:00 2001 +From: Dineshkumar V <dineshkumar.varadarajan@adlinktech.com> +Date: Wed, 26 Feb 2020 18:45:49 +0530 +Subject: [PATCH 7/7] Added SPI chip select enable/disable support for SPI + Read/Write + +--- + drivers/spi/spi-rockchip.c | 14 ++------------ + drivers/spi/spi.c | 18 ++++++++++++++++-- + include/linux/spi/spi.h | 1 + + 3 files changed, 19 insertions(+), 14 deletions(-) + +diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c +index a9a6339..7e44fcf 100644 +--- a/drivers/spi/spi-rockchip.c ++++ b/drivers/spi/spi-rockchip.c +@@ -433,18 +433,9 @@ static void rockchip_spi_dma_txcb(void *data) + spin_unlock_irqrestore(&rs->lock, flags); + } + +-static u32 rockchip_spi_calc_burst_size(u32 data_len) +-{ +- u32 i; + + /* burst size: 1, 2, 4, 8 */ +- for (i = 1; i < 8; i <<= 1) { +- if (data_len & i) +- break; +- } + +- return i; +-} + + static int rockchip_spi_prepare_dma(struct rockchip_spi *rs) + { +@@ -465,7 +456,7 @@ static int rockchip_spi_prepare_dma(struct rockchip_spi *rs) + rxconf.direction = rs->dma_rx.direction; + rxconf.src_addr = rs->dma_rx.addr; + rxconf.src_addr_width = rs->n_bytes; +- rxconf.src_maxburst = rockchip_spi_calc_burst_size(rs->len / rs->n_bytes); ++ rxconf.src_maxburst = 1; + dmaengine_slave_config(rs->dma_rx.ch, &rxconf); + + rxdesc = dmaengine_prep_slave_sg( +@@ -598,8 +589,7 @@ static void rockchip_spi_config(struct rockchip_spi *rs) + writel_relaxed(rs->fifo_len / 2 - 1, rs->regs + ROCKCHIP_SPI_RXFTLR); + + writel_relaxed(rs->fifo_len / 2 - 1, rs->regs + ROCKCHIP_SPI_DMATDLR); +- writel_relaxed(rockchip_spi_calc_burst_size(rs->len / rs->n_bytes) - 1, +- rs->regs + ROCKCHIP_SPI_DMARDLR); ++ writel_relaxed(0, rs->regs + ROCKCHIP_SPI_DMARDLR); + writel_relaxed(dmacr, rs->regs + ROCKCHIP_SPI_DMACR); + + spi_set_clk(rs, div); +diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c +index c132c67..6b94ee4 100644 +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -673,6 +673,10 @@ static void spi_set_cs(struct spi_device *spi, bool enable) + if (spi->mode & SPI_CS_HIGH) + enable = !enable; + ++ if(spi->spi_gpio_cs>0) ++ { ++ gpio_set_value(spi->spi_gpio_cs,!enable); ++ } + if (gpio_is_valid(spi->cs_gpio)) + gpio_set_value(spi->cs_gpio, !enable); + else if (spi->master->set_cs) +@@ -903,8 +907,6 @@ static int spi_map_msg(struct spi_master *master, struct spi_message *msg) + if (max_tx || max_rx) { + list_for_each_entry(xfer, &msg->transfers, + transfer_list) { +- if (!xfer->len) +- continue; + if (!xfer->tx_buf) + xfer->tx_buf = master->dummy_tx; + if (!xfer->rx_buf) +@@ -1521,6 +1523,18 @@ of_register_spi_device(struct spi_master *master, struct device_node *nc) + } + spi->max_speed_hz = value; + ++ spi->spi_gpio_cs=of_get_named_gpio(nc,"spi-gpio-cs",0); ++ if(spi->spi_gpio_cs>0) ++ { ++ printk("spi->spi_gpio_cs=%d\n",spi->spi_gpio_cs); ++ rc = gpio_request(spi->spi_gpio_cs, "spi0_gpio_cs"); ++ if (rc != 0) { ++ gpio_free(spi->spi_gpio_cs); ++ printk("gpio request spi_gpio_cs failed\n"); ++ } ++ else ++ gpio_direction_output(spi->spi_gpio_cs, 1); ++ } + /* Store a pointer to the node in the device structure */ + of_node_get(nc); + spi->dev.of_node = nc; +diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h +index cce80e6..e1b8c04 100644 +--- a/include/linux/spi/spi.h ++++ b/include/linux/spi/spi.h +@@ -158,6 +158,7 @@ struct spi_device { + void *controller_data; + char modalias[SPI_NAME_SIZE]; + int cs_gpio; /* chip select gpio */ ++ int spi_gpio_cs;/*add by lm*/ + + /* the statistics */ + struct spi_statistics statistics; +-- +2.7.4 + diff --git a/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0008-Modified-Boot-Arguments-to-mount-fileystem-from-SD-c.patch b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0008-Modified-Boot-Arguments-to-mount-fileystem-from-SD-c.patch new file mode 100644 index 000000000..f057c7bee --- /dev/null +++ b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/0008-Modified-Boot-Arguments-to-mount-fileystem-from-SD-c.patch @@ -0,0 +1,25 @@ +From 981b285389321d180d4dad2e81cf34f513fa507e Mon Sep 17 00:00:00 2001 +From: Arun Kumar E V <dineshkumar.varadarajan@adlinktech.com> +Date: Tue, 3 Mar 2020 15:21:29 +0530 +Subject: [PATCH 9/9] Modified Boot Arguments to mount fileystem from SD card + +--- + arch/arm64/boot/dts/rockchip/rk3326-linux.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3326-linux.dtsi b/arch/arm64/boot/dts/rockchip/rk3326-linux.dtsi +index 9fbb720..4f2c272 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3326-linux.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3326-linux.dtsi +@@ -45,7 +45,7 @@ + + chosen { + //bootargs = "earlycon=uart8250,mmio32,0xff160000 swiotlb=1 console=ttyFIQ0 rw root=PARTUUID=614e0000-0000 rootwait"; +- bootargs = "earlycon=uart8250,mmio32,0xff160000 swiotlb=1 console=ttyFIQ0 rw root=/dev/mmcblk1p4 rootwait"; ++ bootargs = "earlycon=uart8250,mmio32,0xff160000 swiotlb=1 console=ttyFIQ0 rw root=/dev/mmcblk0p4 rootwait"; + /* bootargs = "console=tty1 rw root=PARTUUID=614e0000-0000 rootwait";*/ + }; + +-- +2.7.4 + diff --git a/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/adjust_wireless_firmware_path.patch b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/adjust_wireless_firmware_path.patch new file mode 100644 index 000000000..c9b6f9fcd --- /dev/null +++ b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/adjust_wireless_firmware_path.patch @@ -0,0 +1,24 @@ +Patch imported from https://github.com/armbian/build.git at revision c55f6ea8bc220bded6695fdae8b0c5bfa891b688 + +Upstream-Status: Inappropriate [not author] +Signed-off-by: Florin Sarbu <florin@balena.io> +--- + drivers/net/wireless/rockchip_wlan/rkwifi/rk_wifi_config.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/rk_wifi_config.c b/drivers/net/wireless/rockchip_wlan/rkwifi/rk_wifi_config.c +index fa07a94..352ea75 100644 +--- a/drivers/net/wireless/rockchip_wlan/rkwifi/rk_wifi_config.c ++++ b/drivers/net/wireless/rockchip_wlan/rkwifi/rk_wifi_config.c +@@ -18,7 +18,7 @@ + */ + + #define VENDOR_ETC_FIRMWARE "/vendor/etc/firmware/" +-#define SYSTEM_ETC_FIRMWARE "/system/etc/firmware/" ++#define SYSTEM_ETC_FIRMWARE "/lib/firmware/rkwifi/" + char ANDROID_FW_PATH[64] = {0}; + + extern int get_wifi_chip_type(void); +-- +2.7.4 + diff --git a/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/defconfig b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/defconfig new file mode 100644 index 000000000..fbe7cebd8 --- /dev/null +++ b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/files/4.4.185/defconfig @@ -0,0 +1,4411 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/arm64 4.4.185 Kernel Configuration +# +CONFIG_ARM64=y +CONFIG_64BIT=y +CONFIG_ARCH_PHYS_ADDR_T_64BIT=y +CONFIG_MMU=y +CONFIG_ARCH_MMAP_RND_BITS_MIN=18 +CONFIG_ARCH_MMAP_RND_BITS_MAX=24 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 +CONFIG_ARM64_PAGE_SHIFT=12 +CONFIG_ARM64_CONT_SHIFT=4 +CONFIG_NO_IOPORT_MAP=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ZONE_DMA=y +CONFIG_HAVE_GENERIC_RCU_GUP=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_SMP=y +CONFIG_SWIOTLB=y +CONFIG_IOMMU_HELPER=y +CONFIG_KERNEL_MODE_NEON=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_PGTABLE_LEVELS=3 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_IRQ_WORK=y +CONFIG_BUILDTIME_EXTABLE_SORT=y +CONFIG_THREAD_INFO_IN_TASK=y + +# +# General setup +# +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +# CONFIG_COMPILE_TEST is not set +CONFIG_LOCALVERSION="-rockchip-standard" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_DEFAULT_HOSTNAME="localhost" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_FHANDLE=y +CONFIG_USELIB=y +# CONFIG_AUDIT is not set +CONFIG_HAVE_ARCH_AUDITSYSCALL=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_IRQ_MIGRATION=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_CHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_HANDLE_DOMAIN_IRQ=y +# CONFIG_IRQ_DOMAIN_DEBUG is not set +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_SPARSE_IRQ=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_ARCH_HAS_TICK_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ_COMMON=y +# CONFIG_HZ_PERIODIC is not set +CONFIG_NO_HZ_IDLE=y +# CONFIG_NO_HZ_FULL is not set +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y + +# +# CPU/Task time and stats accounting +# +CONFIG_TICK_CPU_ACCOUNTING=y +# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set +# CONFIG_IRQ_TIME_ACCOUNTING is not set +# CONFIG_SCHED_WALT is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_RCU_EXPERT is not set +CONFIG_SRCU=y +# CONFIG_TASKS_RCU is not set +CONFIG_RCU_STALL_COMMON=y +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_RCU_EXPEDITE_BOOT is not set +# CONFIG_BUILD_BIN2C is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=18 +CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_CGROUPS=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_FREEZER=y +# CONFIG_CGROUP_PIDS is not set +CONFIG_CGROUP_DEVICE=y +CONFIG_CPUSETS=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_CGROUP_CPUACCT=y +# CONFIG_MEMCG is not set +# CONFIG_CGROUP_PERF is not set +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_CFS_BANDWIDTH=y +# CONFIG_RT_GROUP_SCHED is not set +# CONFIG_BLK_CGROUP is not set +# CONFIG_CHECKPOINT_RESTORE is not set +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_IPC_NS=y +CONFIG_USER_NS=y +CONFIG_PID_NS=y +CONFIG_NET_NS=y +# CONFIG_SCHED_AUTOGROUP is not set +# CONFIG_SCHED_TUNE is not set +CONFIG_DEFAULT_USE_ENERGY_AWARE=y +# CONFIG_SYSFS_DEPRECATED is not set +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +CONFIG_RD_XZ=y +CONFIG_RD_LZO=y +CONFIG_RD_LZ4=y +# CONFIG_INITRD_ASYNC is not set +# CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_HAVE_UID16=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_BPF=y +CONFIG_EXPERT=y +CONFIG_UID16=y +CONFIG_MULTIUSER=y +# CONFIG_SGETMASK_SYSCALL is not set +CONFIG_SYSFS_SYSCALL=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +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_BPF_SYSCALL is not set +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_ADVISE_SYSCALLS=y +# CONFIG_USERFAULTFD is not set +CONFIG_MEMBARRIER=y +CONFIG_EMBEDDED=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_COMPAT_BRK is not set +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_SLUB_CPU_PARTIAL=y +# CONFIG_SYSTEM_DATA_VERIFICATION is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +# CONFIG_KPROBES is not set +# CONFIG_JUMP_LABEL is not set +# CONFIG_UPROBES is not set +# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_RCU_TABLE_FREE=y +CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y +CONFIG_HAVE_CMPXCHG_LOCAL=y +CONFIG_HAVE_CMPXCHG_DOUBLE=y +CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_SECCOMP_FILTER=y +CONFIG_HAVE_CC_STACKPROTECTOR=y +# CONFIG_CC_STACKPROTECTOR is not set +CONFIG_CC_STACKPROTECTOR_NONE=y +# CONFIG_CC_STACKPROTECTOR_REGULAR is not set +# CONFIG_CC_STACKPROTECTOR_STRONG is not set +CONFIG_HAVE_CONTEXT_TRACKING=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y +CONFIG_HAVE_ARCH_HUGE_VMAP=y +CONFIG_MODULES_USE_ELF_RELA=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_HAVE_ARCH_MMAP_RND_BITS=y +CONFIG_ARCH_MMAP_RND_BITS=18 +CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS=y +CONFIG_ARCH_MMAP_RND_COMPAT_BITS=11 +CONFIG_CLONE_BACKWARDS=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_COMPAT_OLD_SIGACTION=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_MODULE_SIG is not set +# CONFIG_MODULE_COMPRESS is not set +CONFIG_MODULES_TREE_LOOKUP=y +CONFIG_BLOCK=y +CONFIG_BLK_DEV_BSG=y +# CONFIG_BLK_DEV_BSGLIB is not set +# CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_CMDLINE_PARSER is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_AIX_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +CONFIG_RK_PARTITION=y +# CONFIG_CMDLINE_PARTITION is not set +CONFIG_BLOCK_COMPAT=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_ASN1=y +CONFIG_UNINLINE_SPIN_UNLOCK=y +CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_FREEZER=y + +# +# Platform selection +# +# CONFIG_ARCH_BCM_IPROC is not set +# CONFIG_ARCH_BERLIN is not set +# CONFIG_ARCH_EXYNOS7 is not set +# CONFIG_ARCH_LAYERSCAPE is not set +# CONFIG_ARCH_HISI is not set +# CONFIG_ARCH_MEDIATEK is not set +# CONFIG_ARCH_QCOM is not set +CONFIG_ARCH_ROCKCHIP=y +# CONFIG_ARCH_SEATTLE is not set +# CONFIG_ARCH_STRATIX10 is not set +# CONFIG_ARCH_TEGRA is not set +# CONFIG_ARCH_SPRD is not set +# CONFIG_ARCH_THUNDER is not set +# CONFIG_ARCH_VEXPRESS is not set +# CONFIG_ARCH_XGENE is not set +# CONFIG_ARCH_ZYNQMP is not set + +# +# Bus support +# +# CONFIG_PCI is not set +# CONFIG_PCI_DOMAINS is not set +# CONFIG_PCI_DOMAINS_GENERIC is not set +# CONFIG_PCI_SYSCALL is not set + +# +# Kernel Features +# + +# +# ARM errata workarounds via the alternatives framework +# +# CONFIG_ARM64_ERRATUM_826319 is not set +# CONFIG_ARM64_ERRATUM_827319 is not set +# CONFIG_ARM64_ERRATUM_824069 is not set +# CONFIG_ARM64_ERRATUM_819472 is not set +# CONFIG_ARM64_ERRATUM_832075 is not set +CONFIG_ARM64_ERRATUM_845719=y +CONFIG_ARM64_ERRATUM_843419=y +# CONFIG_ARM64_ERRATUM_1024718 is not set +# CONFIG_CAVIUM_ERRATUM_22375 is not set +# CONFIG_CAVIUM_ERRATUM_23154 is not set +CONFIG_CAVIUM_ERRATUM_27456=y +CONFIG_ARM64_4K_PAGES=y +# CONFIG_ARM64_16K_PAGES is not set +# CONFIG_ARM64_64K_PAGES is not set +CONFIG_ARM64_VA_BITS_39=y +# CONFIG_ARM64_VA_BITS_48 is not set +CONFIG_ARM64_VA_BITS=39 +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_SCHED_MC=y +# CONFIG_SCHED_SMT is not set +CONFIG_NR_CPUS=8 +CONFIG_HOTPLUG_CPU=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +# CONFIG_HZ_100 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_300 is not set +CONFIG_HZ_1000=y +CONFIG_HZ=1000 +CONFIG_SCHED_HRTICK=y +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y +CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HW_PERF_EVENTS=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y +CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_HAVE_MEMORY_PRESENT=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_NO_BOOTMEM=y +# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_COMPACTION is not set +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 +# CONFIG_TRANSPARENT_HUGEPAGE is not set +# CONFIG_CLEANCACHE is not set +# CONFIG_FRONTSWAP is not set +# CONFIG_CMA is not set +# CONFIG_ZPOOL is not set +# CONFIG_ZBUD is not set +CONFIG_ZSMALLOC=y +# CONFIG_PGTABLE_MAPPING is not set +# CONFIG_ZSMALLOC_STAT is not set +CONFIG_GENERIC_EARLY_IOREMAP=y +# CONFIG_IDLE_PAGE_TRACKING is not set +CONFIG_FRAME_VECTOR=y +CONFIG_SECCOMP=y +# CONFIG_KEXEC is not set +# CONFIG_CRASH_DUMP is not set +# CONFIG_XEN is not set +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_UNMAP_KERNEL_AT_EL0=y +CONFIG_ARMV8_DEPRECATED=y +CONFIG_SWP_EMULATION=y +CONFIG_CP15_BARRIER_EMULATION=y +CONFIG_SETEND_EMULATION=y +# CONFIG_ARM64_SW_TTBR0_PAN is not set + +# +# ARMv8.1 architectural features +# +CONFIG_ARM64_HW_AFDBM=y +CONFIG_ARM64_PAN=y +# CONFIG_ARM64_LSE_ATOMICS is not set +CONFIG_ARM64_UAO=y +CONFIG_ARM64_MODULE_CMODEL_LARGE=y +# CONFIG_RANDOMIZE_BASE is not set + +# +# Boot options +# +CONFIG_CMDLINE="" +# CONFIG_EFI is not set +# CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_COMPAT_BINFMT_ELF=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_BINFMT_SCRIPT=y +# CONFIG_HAVE_AOUT is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_COREDUMP=y +CONFIG_COMPAT=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_KEYS_COMPAT=y + +# +# Power management options +# +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_SUSPEND_SKIP_SYNC is not set +CONFIG_HAS_WAKELOCK=y +CONFIG_WAKELOCK=y +# CONFIG_HIBERNATION is not set +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +# CONFIG_PM_AUTOSLEEP is not set +# CONFIG_PM_WAKELOCKS is not set +CONFIG_PM=y +CONFIG_PM_DEBUG=y +CONFIG_PM_ADVANCED_DEBUG=y +# CONFIG_PM_TEST_SUSPEND is not set +CONFIG_PM_SLEEP_DEBUG=y +CONFIG_PM_OPP=y +CONFIG_PM_CLK=y +CONFIG_PM_GENERIC_DOMAINS=y +CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y +CONFIG_PM_GENERIC_DOMAINS_SLEEP=y +CONFIG_PM_GENERIC_DOMAINS_OF=y +CONFIG_CPU_PM=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y + +# +# CPU Power Management +# + +# +# CPU Idle +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_DT_IDLE_STATES=y + +# +# ARM CPU Idle Drivers +# +CONFIG_ARM_CPUIDLE=y +# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_TIMES=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_INTERACTIVE=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +# CONFIG_CPU_FREQ_GOV_SCHEDUTIL is not set + +# +# CPU frequency scaling drivers +# +CONFIG_CPUFREQ_DT=y +# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set +# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set +CONFIG_ARM_ROCKCHIP_CPUFREQ=y +CONFIG_NET=y +CONFIG_COMPAT_NETLINK_MESSAGES=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_DIAG is not set +CONFIG_UNIX=y +# CONFIG_UNIX_DIAG is not set +CONFIG_XFRM=y +CONFIG_XFRM_ALGO=y +CONFIG_XFRM_USER=y +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +# CONFIG_IP_FIB_TRIE_STATS is not set +# CONFIG_IP_MULTIPLE_TABLES is not set +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE_DEMUX is not set +# CONFIG_NET_IP_TUNNEL is not set +CONFIG_IP_MROUTE=y +# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set +# CONFIG_IP_PIMSM_V1 is not set +# CONFIG_IP_PIMSM_V2 is not set +CONFIG_SYN_COOKIES=y +# CONFIG_NET_UDP_TUNNEL is not set +# CONFIG_NET_FOU 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 is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# 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=y +# 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_IPV6_ILA is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET6_XFRM_MODE_TUNNEL is not set +# CONFIG_INET6_XFRM_MODE_BEET is not set +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +# CONFIG_IPV6_SIT is not set +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_GRE is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_ANDROID_PARANOID_NETWORK is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NET_PTP_CLASSIFY=y +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +# CONFIG_BRIDGE is not set +CONFIG_HAVE_NET_DSA=y +# 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_PHONET is not set +# CONFIG_6LOWPAN is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set +CONFIG_DNS_RESOLVER=y +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +# CONFIG_VSOCKETS is not set +# CONFIG_NETLINK_DIAG is not set +# CONFIG_MPLS is not set +# CONFIG_HSR is not set +# CONFIG_NET_SWITCHDEV is not set +# CONFIG_NET_L3_MASTER_DEV is not set +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_XPS=y +# CONFIG_CGROUP_NET_PRIO is not set +# CONFIG_CGROUP_NET_CLASSID is not set +CONFIG_NET_RX_BUSY_POLL=y +CONFIG_BQL=y +# CONFIG_BPF_JIT is not set +CONFIG_NET_FLOW_LIMIT=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_HAMRADIO is not set +CONFIG_CAN=y +CONFIG_CAN_RAW=y +CONFIG_CAN_BCM=y +CONFIG_CAN_GW=y + +# +# CAN Device Drivers +# +# CONFIG_CAN_VCAN is not set +# CONFIG_CAN_SLCAN is not set +CONFIG_CAN_DEV=y +CONFIG_CAN_CALC_BITTIMING=y +# CONFIG_CAN_LEDS is not set +# CONFIG_CAN_GRCAN is not set +# CONFIG_CAN_XILINXCAN is not set +# CONFIG_CAN_SJA1000 is not set +# CONFIG_CAN_C_CAN is not set +# CONFIG_CAN_M_CAN is not set +# CONFIG_CAN_CC770 is not set + +# +# CAN SPI interfaces +# +# CONFIG_CAN_MCP251X is not set +CONFIG_CAN_MCP25XXFD=m + +# +# CAN USB interfaces +# +# CONFIG_CAN_EMS_USB is not set +# CONFIG_CAN_ESD_USB2 is not set +# CONFIG_CAN_GS_USB is not set +# CONFIG_CAN_KVASER_USB is not set +# CONFIG_CAN_PEAK_USB is not set +# CONFIG_CAN_8DEV_USB is not set +# CONFIG_CAN_SOFTING is not set +# CONFIG_CAN_DEBUG_DEVICES is not set +# CONFIG_IRDA is not set +CONFIG_BT=y +CONFIG_BT_BREDR=y +CONFIG_BT_RFCOMM=y +# CONFIG_BT_RFCOMM_TTY is not set +# CONFIG_BT_BNEP is not set +CONFIG_BT_HIDP=y +CONFIG_BT_HS=y +CONFIG_BT_LE=y +# CONFIG_BT_SELFTEST is not set +CONFIG_BT_DEBUGFS=y + +# +# Bluetooth device drivers +# +CONFIG_BT_INTEL=y +CONFIG_BT_BCM=y +CONFIG_BT_RTL=y +# CONFIG_BT_RTKBTUSB is not set +CONFIG_BT_HCIBTUSB=y +CONFIG_BT_HCIBTUSB_BCM=y +CONFIG_BT_HCIBTUSB_RTL=y +# CONFIG_BT_HCIBTSDIO is not set +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_H4=y +# CONFIG_BT_HCIUART_BCSP is not set +CONFIG_BT_HCIUART_ATH3K=y +CONFIG_BT_HCIUART_LL=y +# CONFIG_BT_HCIUART_3WIRE is not set +# CONFIG_BT_HCIUART_INTEL is not set +# CONFIG_BT_HCIUART_BCM is not set +# CONFIG_BT_HCIUART_QCA is not set +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +CONFIG_BT_HCIBFUSB=y +CONFIG_BT_HCIVHCI=y +CONFIG_BT_MRVL=y +CONFIG_BT_MRVL_SDIO=y +# CONFIG_BT_ATH3K is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_PRIV=y +CONFIG_CFG80211=y +CONFIG_NL80211_TESTMODE=y +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_REG_DEBUG is not set +# CONFIG_CFG80211_CERTIFICATION_ONUS is not set +CONFIG_CFG80211_DEFAULT_PS=y +CONFIG_CFG80211_DEBUGFS=y +# CONFIG_CFG80211_INTERNAL_REGDB is not set +CONFIG_CFG80211_CRDA_SUPPORT=y +CONFIG_CFG80211_WEXT=y +# CONFIG_LIB80211 is not set +CONFIG_MAC80211=y +CONFIG_MAC80211_HAS_RC=y +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_MINSTREL_HT=y +# CONFIG_MAC80211_RC_MINSTREL_VHT is not set +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" +# CONFIG_MAC80211_MESH is not set +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_DEBUGFS=y +# CONFIG_MAC80211_MESSAGE_TRACING is not set +CONFIG_MAC80211_DEBUG_MENU=y +# CONFIG_MAC80211_NOINLINE is not set +CONFIG_MAC80211_VERBOSE_DEBUG=y +# CONFIG_MAC80211_MLME_DEBUG is not set +# CONFIG_MAC80211_STA_DEBUG is not set +# CONFIG_MAC80211_HT_DEBUG is not set +# CONFIG_MAC80211_OCB_DEBUG is not set +# CONFIG_MAC80211_IBSS_DEBUG is not set +# CONFIG_MAC80211_PS_DEBUG is not set +# CONFIG_MAC80211_TDLS_DEBUG is not set +# CONFIG_MAC80211_DEBUG_COUNTERS is not set +CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 +# CONFIG_WIMAX is not set +CONFIG_RFKILL=y +CONFIG_RFKILL_PM=y +CONFIG_RFKILL_LEDS=y +# CONFIG_RFKILL_INPUT is not set +# CONFIG_RFKILL_REGULATOR is not set +# CONFIG_RFKILL_GPIO is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set +# CONFIG_LWTUNNEL is not set +# CONFIG_DST_CACHE is not set +CONFIG_HAVE_BPF_JIT=y +CONFIG_HAVE_EBPF_JIT=y + +# +# Device Drivers +# +CONFIG_ARM_AMBA=y +# CONFIG_TEGRA_AHB is not set + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER=y +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set +CONFIG_WANT_DEV_COREDUMP=y +CONFIG_ALLOW_DEV_COREDUMP=y +CONFIG_DEV_COREDUMP=y +# CONFIG_DEBUG_DRIVER is not set +CONFIG_DEBUG_DEVRES=y +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_GENERIC_CPU_DEVICES is not set +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_SPI=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGMAP_IRQ=y +CONFIG_DMA_SHARED_BUFFER=y +# CONFIG_FENCE_TRACE is not set + +# +# Bus devices +# +# CONFIG_ARM_CCI400_PMU is not set +# CONFIG_ARM_CCI500_PMU is not set +# CONFIG_ARM_CCN is not set +# CONFIG_VEXPRESS_CONFIG is not set +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y +# CONFIG_MTD is not set +CONFIG_DTC=y +CONFIG_OF=y +# CONFIG_OF_UNITTEST is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_IRQ=y +CONFIG_OF_NET=y +CONFIG_OF_MDIO=y +CONFIG_OF_RESERVED_MEM=y +# CONFIG_OF_OVERLAY is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_NULL_BLK is not set +CONFIG_ZRAM=y +# CONFIG_ZRAM_WRITEBACK is not set +# CONFIG_ZRAM_MEMORY_TRACKING is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_DRBD is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=1 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_RBD is not set + +# +# Misc devices +# +# CONFIG_ROCKCHIP_SCR is not set +# CONFIG_SENSORS_LIS3LV02D is not set +# CONFIG_AD525X_DPOT is not set +# CONFIG_DUMMY_IRQ is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1780 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_HMC6352 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set +# CONFIG_BMP085_I2C is not set +# CONFIG_BMP085_SPI is not set +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_LATTICE_ECP3_CONFIG is not set +# CONFIG_SRAM is not set +# CONFIG_MEMORY_STATE_TIME is not set +# CONFIG_USB_CAM_GPIO is not set +# CONFIG_GPIO_DET is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_EEPROM_93XX46 is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set +# CONFIG_SENSORS_LIS3_SPI is not set +# CONFIG_SENSORS_LIS3_I2C is not set + +# +# Altera FPGA firmware download module +# +# CONFIG_ALTERA_STAPL is not set + +# +# Intel MIC Bus Driver +# + +# +# SCIF Bus Driver +# + +# +# Intel MIC Host Driver +# + +# +# Intel MIC Card Driver +# + +# +# SCIF Driver +# + +# +# Intel MIC Coprocessor State Management (COSM) Drivers +# +# CONFIG_ECHO is not set +# CONFIG_CXL_BASE is not set +# CONFIG_CXL_KERNEL_API is not set +# CONFIG_CXL_EEH is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_NETLINK is not set +# CONFIG_SCSI_MQ_DEFAULT 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=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +CONFIG_SCSI_SCAN_ASYNC=y + +# +# SCSI Transports +# +CONFIG_SCSI_SPI_ATTRS=y +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_ISCSI_BOOT_SYSFS is not set +# CONFIG_SCSI_UFSHCD is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +CONFIG_HAVE_PATA_PLATFORM=y +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_TARGET_CORE is not set +CONFIG_NETDEVICES=y +CONFIG_MII=y +CONFIG_NET_CORE=y +# CONFIG_BONDING is not set +# CONFIG_DUMMY is not set +# CONFIG_EQUALIZER is not set +# CONFIG_NET_TEAM is not set +# CONFIG_MACVLAN is not set +# CONFIG_IPVLAN is not set +# CONFIG_VXLAN is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_TUN is not set +# CONFIG_TUN_VNET_CROSS_LE is not set +# CONFIG_VETH is not set +# CONFIG_NLMON is not set + +# +# CAIF transport drivers +# + +# +# Distributed Switch Architecture drivers +# +# CONFIG_NET_DSA_MV88E6XXX is not set +# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set +CONFIG_ETHERNET=y +# CONFIG_ALTERA_TSE is not set +# CONFIG_NET_VENDOR_AMD is not set +# CONFIG_NET_VENDOR_ARC is not set +# CONFIG_NET_VENDOR_AURORA is not set +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_DNET is not set +# CONFIG_NET_VENDOR_EZCHIP is not set +# CONFIG_NET_VENDOR_HISILICON is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_ETHOC is not set +# CONFIG_NET_VENDOR_QUALCOMM is not set +# CONFIG_NET_VENDOR_RENESAS is not set +# CONFIG_NET_VENDOR_ROCKER is not set +# CONFIG_NET_VENDOR_SAMSUNG is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +CONFIG_NET_VENDOR_SMSC9514=y +CONFIG_SMSC9500=m +CONFIG_SMSCUSBNET=m +CONFIG_NET_VENDOR_STMICRO=y +CONFIG_STMMAC_ETH=y +CONFIG_STMMAC_PLATFORM=y +# CONFIG_DWMAC_GENERIC is not set +# CONFIG_DWMAC_IPQ806X is not set +# CONFIG_DWMAC_LPC18XX is not set +# CONFIG_DWMAC_MESON is not set +CONFIG_DWMAC_ROCKCHIP=y +# CONFIG_DWMAC_SOCFPGA is not set +# CONFIG_DWMAC_STI is not set +# CONFIG_DWMAC_SUNXI is not set +# CONFIG_NET_VENDOR_SYNOPSYS is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_AQUANTIA_PHY is not set +# CONFIG_AT803X_PHY is not set +# CONFIG_AMD_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_TERANETICS_PHY is not set +CONFIG_ROCKCHIP_PHY=y +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_BCM7XXX_PHY is not set +# CONFIG_BCM87XX_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_DP83848_PHY is not set +# CONFIG_DP83867_PHY is not set +# CONFIG_MICROCHIP_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MDIO_OCTEON is not set +# CONFIG_MDIO_BUS_MUX_GPIO is not set +# CONFIG_MDIO_BUS_MUX_MMIOREG is not set +# CONFIG_MDIO_BCM_UNIMAC is not set +# CONFIG_MICREL_KS8995MA is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +CONFIG_USB_NET_DRIVERS=y +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +CONFIG_USB_RTL8150=y +CONFIG_USB_RTL8152=y +# CONFIG_USB_LAN78XX is not set +CONFIG_USB_USBNET=y +CONFIG_USB_NET_AX8817X=y +CONFIG_USB_NET_AX88179_178A=y +CONFIG_USB_NET_CDCETHER=y +# CONFIG_USB_NET_CDC_EEM is not set +CONFIG_USB_NET_CDC_NCM=y +# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set +CONFIG_USB_NET_CDC_MBIM=y +# CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_SR9700 is not set +# CONFIG_USB_NET_SR9800 is not set +# CONFIG_USB_NET_SMSC75XX is not set +CONFIG_USB_NET_SMSC95XX=y +# CONFIG_USB_NET_GL620A is not set +# CONFIG_USB_NET_NET1080 is not set +# CONFIG_USB_NET_PLUSB is not set +# CONFIG_USB_NET_MCS7830 is not set +CONFIG_USB_NET_RNDIS_HOST=y +# CONFIG_USB_NET_CDC_SUBSET is not set +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_NET_CX82310_ETH is not set +# CONFIG_USB_NET_KALMIA is not set +# CONFIG_USB_NET_QMI_WWAN is not set +# CONFIG_USB_HSO is not set +# CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_USB_SIERRA_NET is not set +# CONFIG_USB_VL600 is not set +# CONFIG_USB_NET_CH9200 is not set +CONFIG_WLAN=y +CONFIG_LIBERTAS_THINFIRM=y +# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set +# CONFIG_LIBERTAS_THINFIRM_USB is not set +# CONFIG_AT76C50X_USB is not set +# CONFIG_USB_ZD1201 is not set +CONFIG_USB_NET_RNDIS_WLAN=y +# CONFIG_RTL8187 is not set +# CONFIG_MAC80211_HWSIM is not set +# CONFIG_VIRT_WIFI is not set +# CONFIG_ATH_CARDS is not set +# CONFIG_B43 is not set +# CONFIG_B43LEGACY is not set +# CONFIG_BRCMSMAC is not set +# CONFIG_BRCMFMAC is not set +# CONFIG_HOSTAP is not set +# CONFIG_LIBERTAS is not set +# CONFIG_P54_COMMON is not set +# CONFIG_RT2X00 is not set +# CONFIG_WL_MEDIATEK is not set +CONFIG_RTL_CARDS=y +# CONFIG_RTL8192CU is not set +# CONFIG_RTL8XXXU is not set +CONFIG_WL_ROCKCHIP=y +CONFIG_WIFI_BUILD_MODULE=y +# CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP is not set +# CONFIG_WIFI_GENERATE_RANDOM_MAC_ADDR is not set +CONFIG_AP6XXX=m +# CONFIG_CYW_BCMDHD is not set +CONFIG_RTL_WIRELESS_SOLUTION=y +CONFIG_RTL8188EU=m +# CONFIG_RTL8188FU is not set +# CONFIG_RTL8189ES is not set +# CONFIG_RTL8189FS is not set +# CONFIG_RTL8723BS is not set +CONFIG_RTL8723BU=y +# CONFIG_RTL8723CS is not set +# CONFIG_RTL8723DS is not set +# CONFIG_MVL88W8977 is not set + +# +# SouthSV 6XXX WLAN support +# +# CONFIG_SSV6051 is not set +# CONFIG_WL_TI is not set +# CONFIG_ZD1211RW is not set +CONFIG_MWIFIEX=y +CONFIG_MWIFIEX_SDIO=y +# CONFIG_MWIFIEX_USB is not set +# CONFIG_CW1200 is not set +# CONFIG_RSI_91X is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_ISDN is not set +# CONFIG_NVM is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_LEDS=y +CONFIG_INPUT_FF_MEMLESS=y +CONFIG_INPUT_POLLDEV=y +# CONFIG_INPUT_SPARSEKMAP is not set +CONFIG_INPUT_MATRIXKMAP=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set +# CONFIG_INPUT_KEYRESET is not set +# CONFIG_INPUT_KEYCOMBO is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ADC=y +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_GPIO_POLLED=y +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_TCA8418 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_LM8333 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_MCS is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_SAMSUNG is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_OMAP4 is not set +CONFIG_KEYBOARD_ROCKCHIP=y +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_CAP11XX is not set +# CONFIG_KEYBOARD_BCM is not set +CONFIG_INPUT_MOUSE=y +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +CONFIG_MOUSE_CYAPA=y +CONFIG_MOUSE_ELAN_I2C=y +CONFIG_MOUSE_ELAN_I2C_I2C=y +# CONFIG_MOUSE_ELAN_I2C_SMBUS is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MOUSE_GPIO is not set +# CONFIG_MOUSE_SYNAPTICS_I2C is not set +# CONFIG_MOUSE_SYNAPTICS_USB is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_PROPERTIES=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_AR1021_I2C is not set +CONFIG_TOUCHSCREEN_ATMEL_MXT=y +# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set +# CONFIG_TOUCHSCREEN_BU21013 is not set +# CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set +# CONFIG_TOUCHSCREEN_CY8C40XX is not set +# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set +# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set +# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_EGALAX is not set +# CONFIG_TOUCHSCREEN_FT6236 is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GOODIX is not set +# CONFIG_TOUCHSCREEN_GSLX680A is not set +# CONFIG_TOUCHSCREEN_GSLX680_D708 is not set +# CONFIG_TOUCHSCREEN_GSLX680_PAD is not set +CONFIG_TOUCHSCREEN_GSLX680_VR=y +# CONFIG_TOUCHSCREEN_GSLX680_FIREFLY is not set +CONFIG_TOUCHSCREEN_GSL3673=y +# CONFIG_TOUCHSCREEN_GSL3673_800X1280 is not set +CONFIG_TOUCHSCREEN_GT9XX=y +# CONFIG_TOUCHSCREEN_ILI210X is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +CONFIG_TOUCHSCREEN_ELAN=y +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_WACOM_I2C is not set +# CONFIG_TOUCHSCREEN_MAX11801 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MMS114 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_PIXCIR is not set +# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set +CONFIG_TOUCHSCREEN_USB_COMPOSITE=y +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_JASTEC=y +CONFIG_TOUCHSCREEN_USB_ELO=y +CONFIG_TOUCHSCREEN_USB_E2I=y +CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y +CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y +CONFIG_TOUCHSCREEN_USB_NEXIO=y +CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC_SERIO is not set +# CONFIG_TOUCHSCREEN_TSC2004 is not set +# CONFIG_TOUCHSCREEN_TSC2005 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_ST1232 is not set +# CONFIG_TOUCHSCREEN_SUR40 is not set +# CONFIG_TOUCHSCREEN_SX8654 is not set +# CONFIG_TOUCHSCREEN_TPS6507X is not set +# CONFIG_TOUCHSCREEN_ZFORCE is not set +# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set +# CONFIG_TOUCHSCREEN_VTL_CT36X is not set +CONFIG_TOUCHSCREEN_GT1X=y +CONFIG_ROCKCHIP_REMOTECTL=y +CONFIG_ROCKCHIP_REMOTECTL_PWM=y + +# +# handle all sensors +# +# CONFIG_SENSOR_DEVICE is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_BMA150 is not set +# CONFIG_INPUT_E3X0_BUTTON is not set +# CONFIG_INPUT_MMA8450 is not set +# CONFIG_INPUT_MPU3050 is not set +# CONFIG_INPUT_GP2A is not set +# CONFIG_INPUT_GPIO_BEEPER is not set +# CONFIG_INPUT_GPIO_TILT_POLLED is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYCHORD is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_KXTJ9 is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +# CONFIG_INPUT_REGULATOR_HAPTIC is not set +CONFIG_INPUT_RK8XX_PWRKEY=y +CONFIG_INPUT_UINPUT=y +CONFIG_INPUT_GPIO=y +# CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_PWM_BEEPER is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_IMS_PCU is not set +# CONFIG_INPUT_CMA3000 is not set +# CONFIG_INPUT_SOC_BUTTON_ARRAY is not set +# CONFIG_INPUT_DRV260X_HAPTICS is not set +# CONFIG_INPUT_DRV2665_HAPTICS is not set +# CONFIG_INPUT_DRV2667_HAPTICS is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_TTY=y +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_CONSOLE_SLEEP=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_UNIX98_PTYS=y +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set +# CONFIG_TRACE_SINK is not set +CONFIG_LDISC_AUTOLOAD=y +CONFIG_DEVMEM=y +# CONFIG_DEVKMEM is not set + +# +# Serial drivers +# +CONFIG_SERIAL_EARLYCON=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_DMA=y +CONFIG_SERIAL_8250_NR_UARTS=5 +CONFIG_SERIAL_8250_RUNTIME_UARTS=5 +# CONFIG_SERIAL_8250_EXTENDED is not set +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_DW=y +# CONFIG_SERIAL_8250_RT288X is not set +# CONFIG_SERIAL_8250_INGENIC is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX310X is not set +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_SERIAL_SCCNXP is not set +# CONFIG_SERIAL_SC16IS7XX is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_SERIAL_ARC is not set +# CONFIG_SERIAL_FSL_LPUART is not set +# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set +# CONFIG_TTY_PRINTK is not set +# CONFIG_HVC_DCC is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +CONFIG_HW_RANDOM_TPM=y +CONFIG_HW_RANDOM_ROCKCHIP=y + +# +# PCMCIA character devices +# +# CONFIG_RAW_DRIVER is not set +CONFIG_TCG_TPM=y +# CONFIG_TCG_TIS_I2C_ATMEL is not set +CONFIG_TCG_TIS_I2C_INFINEON=y +# CONFIG_TCG_TIS_I2C_NUVOTON is not set +# CONFIG_TCG_TIS_ST33ZP24 is not set +# CONFIG_XILLYBUS is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=y + +# +# Multiplexer I2C Chip support +# +# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set +# CONFIG_I2C_MUX_GPIO is not set +# CONFIG_I2C_MUX_PCA9541 is not set +# CONFIG_I2C_MUX_PCA954x is not set +# CONFIG_I2C_MUX_PINCTRL is not set +# CONFIG_I2C_MUX_REG is not set +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_CADENCE is not set +# CONFIG_I2C_CBUS_GPIO is not set +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set +# CONFIG_I2C_EMEV2 is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_NOMADIK is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PXA_PCI is not set +CONFIG_I2C_RK3X=y +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_ROBOTFUZZ_OSIF is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_SLAVE 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_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +CONFIG_SPI_BITBANG=y +# CONFIG_SPI_CADENCE is not set +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_FSL_SPI is not set +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PL022 is not set +# CONFIG_SPI_PXA2XX_PCI is not set +CONFIG_SPI_ROCKCHIP=y +# CONFIG_SPI_SC18IS602 is not set +# CONFIG_SPI_XCOMM is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_ZYNQMP_GQSPI is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=y +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_SPMI is not set +# CONFIG_HSI is not set + +# +# PPS support +# +CONFIG_PPS=y +# CONFIG_PPS_DEBUG is not set + +# +# PPS clients support +# +# CONFIG_PPS_CLIENT_KTIMER is not set +# CONFIG_PPS_CLIENT_LDISC is not set +# CONFIG_PPS_CLIENT_GPIO is not set + +# +# PPS generators support +# + +# +# PTP clock support +# +CONFIG_PTP_1588_CLOCK=y + +# +# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. +# +CONFIG_PINCTRL=y + +# +# Pin controllers +# +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_GENERIC_PINCONF=y +# CONFIG_DEBUG_PINCTRL is not set +# CONFIG_PINCTRL_AMD is not set +CONFIG_PINCTRL_ROCKCHIP=y +# CONFIG_PINCTRL_SINGLE is not set +# CONFIG_PINCTRL_RK805 is not set +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_DEVRES=y +CONFIG_OF_GPIO=y +CONFIG_GPIOLIB_IRQCHIP=y +CONFIG_DEBUG_GPIO=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_GENERIC=y + +# +# Memory mapped GPIO drivers +# +# CONFIG_GPIO_74XX_MMIO is not set +# CONFIG_GPIO_ALTERA is not set +# CONFIG_GPIO_DWAPB is not set +CONFIG_GPIO_GENERIC_PLATFORM=y +# CONFIG_GPIO_GRGPIO is not set +# CONFIG_GPIO_PL061 is not set +# CONFIG_GPIO_SYSCON is not set +# CONFIG_GPIO_XGENE is not set +# CONFIG_GPIO_XILINX is not set +# CONFIG_GPIO_ZX is not set + +# +# I2C GPIO expanders +# +# CONFIG_GPIO_ADP5588 is not set +# CONFIG_GPIO_ADNP is not set +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +CONFIG_GPIO_SX150X=y + +# +# MFD GPIO expanders +# +CONFIG_GPIO_RK8XX=y + +# +# SPI GPIO expanders +# +# CONFIG_GPIO_74X164 is not set +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# SPI or I2C GPIO expanders +# +# CONFIG_GPIO_MCP23S08 is not set + +# +# USB GPIO expanders +# +# CONFIG_W1 is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_GENERIC_ADC_BATTERY is not set +# CONFIG_TEST_POWER is not set +# CONFIG_BATTERY_DS2780 is not set +# CONFIG_BATTERY_DS2781 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_SBS is not set +# CONFIG_BATTERY_BQ27XXX is not set +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_BATTERY_MAX17042 is not set +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_CHARGER_LP8727 is not set +CONFIG_CHARGER_GPIO=y +# CONFIG_CHARGER_MANAGER is not set +# CONFIG_CHARGER_BQ2415X is not set +# CONFIG_CHARGER_BQ24190 is not set +# CONFIG_CHARGER_BQ24257 is not set +# CONFIG_CHARGER_BQ24735 is not set +# CONFIG_CHARGER_BQ25700 is not set +# CONFIG_CHARGER_BQ25890 is not set +# CONFIG_CHARGER_SMB347 is not set +# CONFIG_CHARGER_SY6982C is not set +# CONFIG_CHARGER_UNIVERSAL is not set +# CONFIG_BATTERY_GAUGE_LTC2941 is not set +# CONFIG_BATTERY_EC is not set +# CONFIG_BATTERY_CW2015 is not set +# CONFIG_BATTERY_RK816 is not set +CONFIG_BATTERY_RK817=y +CONFIG_CHARGER_RK817=y +# CONFIG_BATTERY_RK818 is not set +# CONFIG_CHARGER_RK818 is not set +# CONFIG_CHARGER_RT9455 is not set +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_GPIO=y +CONFIG_POWER_RESET_GPIO_RESTART=y +# CONFIG_POWER_RESET_LTC2952 is not set +# CONFIG_POWER_RESET_RESTART is not set +# CONFIG_POWER_RESET_XGENE is not set +# CONFIG_POWER_RESET_SYSCON is not set +# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set +CONFIG_REBOOT_MODE=y +CONFIG_SYSCON_REBOOT_MODE=y +CONFIG_POWER_AVS=y +CONFIG_ROCKCHIP_IODOMAIN=y +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +# CONFIG_SENSORS_AD7314 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_ADT7310 is not set +# CONFIG_SENSORS_ADT7410 is not set +# CONFIG_SENSORS_ADT7411 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ASC7621 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS620 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_G760A is not set +# CONFIG_SENSORS_G762 is not set +# CONFIG_SENSORS_GPIO_FAN is not set +# CONFIG_SENSORS_HIH6130 is not set +# CONFIG_SENSORS_IIO_HWMON is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_JC42 is not set +# CONFIG_SENSORS_POWR1220 is not set +# CONFIG_SENSORS_LINEAGE is not set +# CONFIG_SENSORS_LTC2945 is not set +# CONFIG_SENSORS_LTC4151 is not set +# CONFIG_SENSORS_LTC4215 is not set +# CONFIG_SENSORS_LTC4222 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_LTC4260 is not set +# CONFIG_SENSORS_LTC4261 is not set +# CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_MAX16065 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX1668 is not set +# CONFIG_SENSORS_MAX197 is not set +# CONFIG_SENSORS_MAX6639 is not set +# CONFIG_SENSORS_MAX6642 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_MAX6697 is not set +# CONFIG_SENSORS_MAX31790 is not set +# CONFIG_SENSORS_HTU21 is not set +# CONFIG_SENSORS_MCP3021 is not set +# CONFIG_SENSORS_ADCXX is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM73 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_LM95234 is not set +# CONFIG_SENSORS_LM95241 is not set +# CONFIG_SENSORS_LM95245 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_NTC_THERMISTOR is not set +# CONFIG_SENSORS_NCT6683 is not set +# CONFIG_SENSORS_NCT6775 is not set +# CONFIG_SENSORS_NCT7802 is not set +# CONFIG_SENSORS_NCT7904 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_PMBUS is not set +# CONFIG_SENSORS_PWM_FAN is not set +# CONFIG_SENSORS_SHT15 is not set +# CONFIG_SENSORS_SHT21 is not set +# CONFIG_SENSORS_SHTC1 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_EMC1403 is not set +# CONFIG_SENSORS_EMC2103 is not set +# CONFIG_SENSORS_EMC6W201 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SCH56XX_COMMON is not set +# CONFIG_SENSORS_SCH5627 is not set +# CONFIG_SENSORS_SCH5636 is not set +# CONFIG_SENSORS_SMM665 is not set +# CONFIG_SENSORS_ADC128D818 is not set +CONFIG_SENSORS_ADS1015=y +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_ADS7871 is not set +# CONFIG_SENSORS_AMC6821 is not set +# CONFIG_SENSORS_INA209 is not set +# CONFIG_SENSORS_INA2XX is not set +# CONFIG_SENSORS_TC74 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TMP102 is not set +# CONFIG_SENSORS_TMP103 is not set +# CONFIG_SENSORS_TMP401 is not set +# CONFIG_SENSORS_TMP421 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_W83795 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_THERMAL=y +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_OF=y +CONFIG_THERMAL_WRITABLE_TRIPS=y +# CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE is not set +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR=y +CONFIG_THERMAL_GOV_FAIR_SHARE=y +CONFIG_THERMAL_GOV_STEP_WISE=y +# CONFIG_THERMAL_GOV_BANG_BANG is not set +# CONFIG_THERMAL_GOV_USER_SPACE is not set +CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y +CONFIG_CPU_THERMAL=y +# CONFIG_CLOCK_THERMAL is not set +CONFIG_DEVFREQ_THERMAL=y +# CONFIG_THERMAL_EMULATION is not set +# CONFIG_IMX_THERMAL is not set +CONFIG_ROCKCHIP_THERMAL=y +# CONFIG_RK_VIRTUAL_THERMAL is not set +# CONFIG_RK3368_THERMAL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_CORE is not set +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_GPIO_WATCHDOG is not set +# CONFIG_XILINX_WATCHDOG is not set +# CONFIG_ARM_SP805_WATCHDOG is not set +# CONFIG_CADENCE_WATCHDOG is not set +CONFIG_DW_WATCHDOG=y +# CONFIG_MAX63XX_WATCHDOG is not set +# CONFIG_BCM7038_WDT is not set +# CONFIG_MEN_A21_WDT is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y + +# +# Broadcom specific AMBA +# +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +CONFIG_MFD_CORE=y +# CONFIG_MFD_AS3711 is not set +# CONFIG_MFD_AS3722 is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_ATMEL_FLEXCOM is not set +# CONFIG_MFD_ATMEL_HLCDC is not set +# CONFIG_MFD_BCM590XX is not set +# CONFIG_MFD_AXP20X is not set +# CONFIG_MFD_CROS_EC is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_MFD_DA9055 is not set +# CONFIG_MFD_DA9062 is not set +# CONFIG_MFD_DA9063 is not set +# CONFIG_MFD_DA9150 is not set +# CONFIG_MFD_DLN2 is not set +# CONFIG_MFD_MC13XXX_SPI is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_MFD_HI6421_PMIC is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_INTEL_SOC_PMIC is not set +# CONFIG_MFD_KEMPLD is not set +# CONFIG_MFD_88PM800 is not set +# CONFIG_MFD_88PM805 is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_MAX14577 is not set +# CONFIG_MFD_MAX77686 is not set +# CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX77843 is not set +# CONFIG_MFD_MAX8907 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_MT6397 is not set +# CONFIG_MFD_MENF21BMC is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_VIPERBOARD is not set +# CONFIG_MFD_RETU is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_RT5033 is not set +# CONFIG_MFD_RTSX_USB is not set +# CONFIG_MFD_RC5T583 is not set +# CONFIG_MFD_RK618 is not set +CONFIG_MFD_RK808=y +# CONFIG_MFD_RN5T618 is not set +# CONFIG_MFD_SEC_CORE is not set +# CONFIG_MFD_SI476X_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SKY81452 is not set +# CONFIG_MFD_SMSC is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_MFD_STMPE is not set +CONFIG_MFD_SYSCON=y +# CONFIG_MFD_TI_AM335X_TSCADC is not set +# CONFIG_MFD_LP3943 is not set +# CONFIG_MFD_LP8788 is not set +# CONFIG_MFD_PALMAS is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TPS65218 is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_MFD_TPS80031 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_LM3533 is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_ARIZONA_I2C is not set +# CONFIG_MFD_ARIZONA_SPI is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_RK1000 is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +CONFIG_FUSB_30X=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_DEBUG=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set +# CONFIG_REGULATOR_ACT8865 is not set +# CONFIG_REGULATOR_AD5398 is not set +# CONFIG_REGULATOR_ANATOP is not set +# CONFIG_REGULATOR_DA9210 is not set +# CONFIG_REGULATOR_DA9211 is not set +CONFIG_REGULATOR_FAN53555=y +CONFIG_REGULATOR_GPIO=y +# CONFIG_REGULATOR_ISL9305 is not set +# CONFIG_REGULATOR_ISL6271A is not set +# CONFIG_REGULATOR_LP3971 is not set +# CONFIG_REGULATOR_LP3972 is not set +# CONFIG_REGULATOR_LP872X is not set +# CONFIG_REGULATOR_LP8752 is not set +# CONFIG_REGULATOR_LP8755 is not set +# CONFIG_REGULATOR_LTC3589 is not set +# CONFIG_REGULATOR_MAX1586 is not set +# CONFIG_REGULATOR_MAX8649 is not set +# CONFIG_REGULATOR_MAX8660 is not set +# CONFIG_REGULATOR_MAX8952 is not set +# CONFIG_REGULATOR_MAX8973 is not set +# CONFIG_REGULATOR_MP8865 is not set +# CONFIG_REGULATOR_MT6311 is not set +# CONFIG_REGULATOR_PFUZE100 is not set +CONFIG_REGULATOR_PWM=y +CONFIG_REGULATOR_RK808=y +CONFIG_REGULATOR_RK818=y +# CONFIG_REGULATOR_SYR82X is not set +# CONFIG_REGULATOR_TPS51632 is not set +# CONFIG_REGULATOR_TPS549B22 is not set +# CONFIG_REGULATOR_TPS62360 is not set +# CONFIG_REGULATOR_TPS65023 is not set +# CONFIG_REGULATOR_TPS6507X is not set +# CONFIG_REGULATOR_TPS65132 is not set +# CONFIG_REGULATOR_TPS6524X is not set +# CONFIG_REGULATOR_XZ3216 is not set +CONFIG_MEDIA_SUPPORT=y + +# +# Multimedia core support +# +CONFIG_MEDIA_CAMERA_SUPPORT=y +# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set +# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set +# CONFIG_MEDIA_RADIO_SUPPORT is not set +# CONFIG_MEDIA_SDR_SUPPORT is not set +CONFIG_MEDIA_RC_SUPPORT=y +# CONFIG_MEDIA_CEC_SUPPORT is not set +CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y +CONFIG_VIDEO_V4L2=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_V4L2_MEM2MEM_DEV=y +CONFIG_V4L2_FWNODE=y +CONFIG_VIDEOBUF_GEN=y +CONFIG_VIDEOBUF2_CORE=y +CONFIG_VIDEOBUF2_MEMOPS=y +CONFIG_VIDEOBUF2_DMA_CONTIG=y +CONFIG_VIDEOBUF2_VMALLOC=y +CONFIG_VIDEOBUF2_DMA_SG=y +# CONFIG_TTPCI_EEPROM is not set + +# +# Media drivers +# +CONFIG_RC_CORE=y +CONFIG_RC_MAP=y +# CONFIG_LIRC is not set +CONFIG_RC_DECODERS=y +CONFIG_IR_NEC_DECODER=y +# CONFIG_IR_RC5_DECODER is not set +# CONFIG_IR_RC6_DECODER is not set +# CONFIG_IR_JVC_DECODER is not set +# CONFIG_IR_SONY_DECODER is not set +# CONFIG_IR_SANYO_DECODER is not set +# CONFIG_IR_SHARP_DECODER is not set +# CONFIG_IR_MCE_KBD_DECODER is not set +# CONFIG_IR_XMP_DECODER is not set +# CONFIG_IR_IMON_DECODER is not set +# CONFIG_RC_DEVICES is not set +CONFIG_MEDIA_USB_SUPPORT=y + +# +# Webcam devices +# +CONFIG_USB_VIDEO_CLASS=y +# CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV is not set +# CONFIG_USB_GSPCA is not set +# CONFIG_USB_PWC is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set +# CONFIG_VIDEO_USBTV is not set +# CONFIG_NPU_USB_ACM is not set + +# +# Webcam, TV (analog/digital) USB devices +# +# CONFIG_VIDEO_EM28XX is not set +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_SOC_CAMERA=y +# CONFIG_SOC_CAMERA_PLATFORM is not set +# CONFIG_VIDEO_XILINX is not set +# CONFIG_VIDEO_RK_CIF_ISP10 is not set +# CONFIG_VIDEO_ROCKCHIP_CIF is not set +CONFIG_VIDEO_ROCKCHIP_ISP1=y +CONFIG_V4L_MEM2MEM_DRIVERS=y +# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set +# CONFIG_VIDEO_SH_VEU is not set +CONFIG_VIDEO_ROCKCHIP_RGA=y +# CONFIG_VIDEO_ROCKCHIP_VPU is not set +# CONFIG_V4L_TEST_DRIVERS is not set +# CONFIG_ROCKCHIP_TSP is not set + +# +# Supported MMC/SDIO adapters +# +# CONFIG_CYPRESS_FIRMWARE is not set + +# +# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) +# +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set +# CONFIG_VIDEO_IR_I2C is not set + +# +# I2C Encoders, decoders, sensors and other helper chips +# + +# +# Audio decoders, processors and mixers +# +# CONFIG_VIDEO_TVAUDIO is not set +# CONFIG_VIDEO_TDA7432 is not set +# CONFIG_VIDEO_TDA9840 is not set +# CONFIG_VIDEO_TEA6415C is not set +# CONFIG_VIDEO_TEA6420 is not set +# CONFIG_VIDEO_MSP3400 is not set +# CONFIG_VIDEO_CS5345 is not set +# CONFIG_VIDEO_CS53L32A is not set +# CONFIG_VIDEO_TLV320AIC23B is not set +# CONFIG_VIDEO_UDA1342 is not set +# CONFIG_VIDEO_WM8775 is not set +# CONFIG_VIDEO_WM8739 is not set +# CONFIG_VIDEO_VP27SMPX is not set +# CONFIG_VIDEO_SONY_BTF_MPX is not set + +# +# RDS decoders +# +# CONFIG_VIDEO_SAA6588 is not set + +# +# Video decoders +# +# CONFIG_VIDEO_ADV7180 is not set +# CONFIG_VIDEO_ADV7181D is not set +# CONFIG_VIDEO_ADV7183 is not set +# CONFIG_VIDEO_ADV7604 is not set +# CONFIG_VIDEO_ADV7842 is not set +# CONFIG_VIDEO_BT819 is not set +# CONFIG_VIDEO_BT856 is not set +# CONFIG_VIDEO_BT866 is not set +# CONFIG_VIDEO_KS0127 is not set +# CONFIG_VIDEO_ML86V7667 is not set +# CONFIG_VIDEO_SAA7110 is not set +# CONFIG_VIDEO_SAA711X is not set +# CONFIG_VIDEO_TC35874X is not set +# CONFIG_VIDEO_TVP514X is not set +# CONFIG_VIDEO_TVP5150 is not set +# CONFIG_VIDEO_TVP7002 is not set +# CONFIG_VIDEO_TW2804 is not set +# CONFIG_VIDEO_TW9903 is not set +# CONFIG_VIDEO_TW9906 is not set +# CONFIG_VIDEO_VPX3220 is not set + +# +# Video and audio decoders +# +# CONFIG_VIDEO_SAA717X is not set +# CONFIG_VIDEO_CX25840 is not set + +# +# Video encoders +# +# CONFIG_VIDEO_SAA7127 is not set +# CONFIG_VIDEO_SAA7185 is not set +# CONFIG_VIDEO_ADV7170 is not set +# CONFIG_VIDEO_ADV7175 is not set +# CONFIG_VIDEO_ADV7343 is not set +# CONFIG_VIDEO_ADV7393 is not set +# CONFIG_VIDEO_ADV7511 is not set +# CONFIG_VIDEO_AD9389B is not set +# CONFIG_VIDEO_AK881X is not set +# CONFIG_VIDEO_THS8200 is not set + +# +# Camera sensor devices +# +# CONFIG_VIDEO_IMX219 is not set +# CONFIG_VIDEO_IMX258 is not set +# CONFIG_VIDEO_IMX317 is not set +# CONFIG_VIDEO_IMX323 is not set +# CONFIG_VIDEO_IMX327 is not set +# CONFIG_VIDEO_VIRT_CAMERA is not set +# CONFIG_VIDEO_OV2659 is not set +# CONFIG_VIDEO_OV2680 is not set +# CONFIG_VIDEO_OV2685 is not set +# CONFIG_VIDEO_OV2718 is not set +# CONFIG_VIDEO_OV2735 is not set +# CONFIG_VIDEO_OV4689 is not set +# CONFIG_VIDEO_OV5647 is not set +# CONFIG_VIDEO_OV5648 is not set +CONFIG_VIDEO_OV5695=y +# CONFIG_VIDEO_OV7251 is not set +# CONFIG_VIDEO_OV7640 is not set +# CONFIG_VIDEO_OV7670 is not set +# CONFIG_VIDEO_OV7725 is not set +# CONFIG_VIDEO_OV7750 is not set +# CONFIG_VIDEO_OV8858 is not set +# CONFIG_VIDEO_OV9281 is not set +# CONFIG_VIDEO_OV9650 is not set +# CONFIG_VIDEO_OV13850 is not set +# CONFIG_VIDEO_VS6624 is not set +# CONFIG_VIDEO_MT9M032 is not set +# CONFIG_VIDEO_MT9P031 is not set +# CONFIG_VIDEO_MT9T001 is not set +# CONFIG_VIDEO_MT9V011 is not set +# CONFIG_VIDEO_MT9V032 is not set +# CONFIG_VIDEO_AR0230 is not set +# CONFIG_VIDEO_SR030PC30 is not set +# CONFIG_VIDEO_NOON010PC30 is not set +# CONFIG_VIDEO_M5MOLS is not set +# CONFIG_VIDEO_S5K6AA is not set +# CONFIG_VIDEO_S5K6A3 is not set +# CONFIG_VIDEO_S5K4ECGX is not set +# CONFIG_VIDEO_S5K5BAF is not set +# CONFIG_VIDEO_SMIAPP is not set +# CONFIG_VIDEO_S5C73M3 is not set +# CONFIG_VIDEO_GC2155 is not set +# CONFIG_VIDEO_GC0312 is not set +# CONFIG_VIDEO_GC2145 is not set +CONFIG_VIDEO_GC2355=y +# CONFIG_VIDEO_GC2385 is not set +# CONFIG_VIDEO_GC5025 is not set +# CONFIG_VIDEO_GC8034 is not set +CONFIG_VIDEO_SC031GS=y +# CONFIG_VIDEO_SC132GS is not set +# CONFIG_VIDEO_GC0329 is not set +# CONFIG_VIDEO_GC2035 is not set +# CONFIG_VIDEO_BF3925 is not set +# CONFIG_VIDEO_JX_H65 is not set +CONFIG_VIDEO_PREISP_DUMMY_SENSOR=y + +# +# Flash devices +# +# CONFIG_VIDEO_ADP1653 is not set +# CONFIG_VIDEO_AS3645A is not set +# CONFIG_VIDEO_LM3560 is not set +# CONFIG_VIDEO_LM3646 is not set +# CONFIG_VIDEO_SGM3784 is not set + +# +# Video improvement chips +# +# CONFIG_VIDEO_UPD64031A is not set +# CONFIG_VIDEO_UPD64083 is not set + +# +# Camera lens devices +# +# CONFIG_VIDEO_VM149C is not set +# CONFIG_VIDEO_DW9714 is not set +# CONFIG_VIDEO_FP5510 is not set + +# +# Audio/Video compression chips +# +# CONFIG_VIDEO_SAA6752HS is not set + +# +# Miscellaneous helper chips +# +# CONFIG_VIDEO_THS7303 is not set +# CONFIG_VIDEO_M52790 is not set +# CONFIG_VIDEO_NVP6324 is not set + +# +# Sensors used on soc_camera driver +# + +# +# soc_camera sensor drivers +# +# CONFIG_SOC_CAMERA_IMX074 is not set +# CONFIG_SOC_CAMERA_MT9M001 is not set +# CONFIG_SOC_CAMERA_MT9M111 is not set +# CONFIG_SOC_CAMERA_MT9T031 is not set +# CONFIG_SOC_CAMERA_MT9T112 is not set +# CONFIG_SOC_CAMERA_MT9V022 is not set +# CONFIG_SOC_CAMERA_OV2640 is not set +# CONFIG_SOC_CAMERA_OV5642 is not set +# CONFIG_SOC_CAMERA_OV6650 is not set +# CONFIG_SOC_CAMERA_OV772X is not set +# CONFIG_SOC_CAMERA_OV9640 is not set +# CONFIG_SOC_CAMERA_OV9740 is not set +# CONFIG_SOC_CAMERA_RJ54N1 is not set +# CONFIG_SOC_CAMERA_TW9910 is not set + +# +# SPI helper chips +# +# CONFIG_VIDEO_GS1662 is not set +CONFIG_VIDEO_ROCKCHIP_PREISP=y + +# +# Customise DVB Frontends +# +# CONFIG_DVB_AU8522_V4L is not set +# CONFIG_DVB_TUNER_DIB0070 is not set +# CONFIG_DVB_TUNER_DIB0090 is not set + +# +# Tools to develop new frontends +# +# CONFIG_DVB_DUMMY_FE is not set +# CONFIG_CAMSYS_DRV is not set +# CONFIG_ROCK_CHIP_SOC_CAMERA is not set + +# +# Graphics support +# +CONFIG_DRM=y +CONFIG_DRM_IGNORE_IOTCL_PERMIT=y +CONFIG_DRM_MIPI_DSI=y +CONFIG_DRM_KMS_HELPER=y +CONFIG_DRM_KMS_FB_HELPER=y +CONFIG_DRM_FBDEV_EMULATION=y +CONFIG_DRM_LOAD_EDID_FIRMWARE=y +# CONFIG_DRM_DP_CEC is not set +# CONFIG_DRM_SCDC_HELPER is not set +CONFIG_DRM_DMA_SYNC=y + +# +# I2C encoder or helper chips +# +# CONFIG_DRM_I2C_ADV7511 is not set +# CONFIG_DRM_I2C_CH7006 is not set +# CONFIG_DRM_I2C_SIL164 is not set +# CONFIG_DRM_I2C_NXP_TDA998X is not set +# CONFIG_DRM_VGEM is not set +CONFIG_DRM_ROCKCHIP=y +# CONFIG_ROCKCHIP_DRM_DEBUG is not set +# CONFIG_ROCKCHIP_DW_HDMI is not set +CONFIG_ROCKCHIP_DW_MIPI_DSI=y +# CONFIG_ROCKCHIP_MIPI_CSI_TX is not set +CONFIG_ROCKCHIP_ANALOGIX_DP=y +# CONFIG_ROCKCHIP_INNO_HDMI is not set +CONFIG_ROCKCHIP_LVDS=y +CONFIG_ROCKCHIP_DRM_TVE=y +# CONFIG_ROCKCHIP_RGB is not set +# CONFIG_ROCKCHIP_DRM_BACKLIGHT is not set +# CONFIG_ROCKCHIP_RK3066_HDMI is not set +# CONFIG_DRM_UDL is not set +CONFIG_DRM_PANEL=y + +# +# Display Panels +# +CONFIG_DRM_PANEL_SIMPLE=y +# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set +# CONFIG_DRM_PANEL_LG_LG4573 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set +# CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set +CONFIG_DRM_BRIDGE=y + +# +# Display Interface Bridges +# +# CONFIG_DRM_NXP_PTN3460 is not set +# CONFIG_DRM_PARADE_PS8622 is not set +# CONFIG_DRM_RK1000 is not set +# CONFIG_DRM_DUMB_VGA_DAC is not set +# CONFIG_DRM_LONTIUM_LT8912 is not set +CONFIG_DRM_LONTIUM_LT9611_I2C=y +# CONFIG_DRM_CHIPONE_ICN6211 is not set +CONFIG_DRM_ANALOGIX_DP=y +# CONFIG_DRM_ANALOGIX_ANX78XX is not set +# CONFIG_DRM_ANALOGIX_ANX6345 is not set +# CONFIG_POWERVR_ROGUE_M is not set +# CONFIG_MALI400 is not set +CONFIG_MALI_MIDGARD_FOR_ANDROID=y +# CONFIG_MALI_MIDGARD_FOR_LINUX is not set +# CONFIG_MALI_MIDGARD is not set +# CONFIG_MALI_CORESTACK is not set +CONFIG_MALI_PWRSOFT_765=y +# CONFIG_MALI_KUTF is not set +# CONFIG_MALI_BIFROST_FOR_ANDROID is not set +CONFIG_MALI_BIFROST_FOR_LINUX=y +CONFIG_MALI_BIFROST=y +# CONFIG_MALI_BIFROST_GATOR_SUPPORT is not set +# CONFIG_MALI_BIFROST_ENABLE_TRACE is not set +CONFIG_MALI_BIFROST_DEVFREQ=y +# CONFIG_MALI_BIFROST_DMA_FENCE is not set +CONFIG_MALI_PLATFORM_NAME="rk" +CONFIG_MALI_BIFROST_EXPERT=y +# CONFIG_MALI_BIFROST_PRFCNT_SET_SECONDARY is not set +CONFIG_MALI_BIFROST_DEBUG=y +# CONFIG_MALI_BIFROST_NO_MALI is not set +# CONFIG_MALI_BIFROST_TRACE_TIMELINE is not set +# CONFIG_MALI_BIFROST_SYSTEM_TRACE is not set +# CONFIG_MALI_JOB_DUMP is not set +# CONFIG_MALI_2MB_ALLOC is not set + +# +# Frame buffer Devices +# +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +CONFIG_FB_CMDLINE=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=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_IMAGEBLIT=y +# CONFIG_FB_FOREIGN_ENDIAN is not set +CONFIG_FB_SYS_FOPS=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_ARMCLCD is not set +# CONFIG_FB_UVESA is not set +# CONFIG_FB_OPENCORES is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_IBM_GXT4500 is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_FB_AUO_K190X is not set +# CONFIG_FB_SIMPLE is not set +# CONFIG_FB_SSD1307 is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GENERIC=y +CONFIG_BACKLIGHT_PWM=y +# CONFIG_BACKLIGHT_PM8941_WLED is not set +# CONFIG_BACKLIGHT_ADP8860 is not set +# CONFIG_BACKLIGHT_ADP8870 is not set +# CONFIG_BACKLIGHT_LM3630A is not set +# CONFIG_BACKLIGHT_LM3639 is not set +# CONFIG_BACKLIGHT_LP855X is not set +# CONFIG_BACKLIGHT_GPIO is not set +# CONFIG_BACKLIGHT_LV5207LP is not set +# CONFIG_BACKLIGHT_BD6107 is not set + +# +# Rockchip Misc Video driver +# +# CONFIG_FB_ROCKCHIP is not set +# CONFIG_LCDC_RK3368 is not set +CONFIG_LCD_GENERAL=y +# CONFIG_LCD_MIPI is not set +# CONFIG_RK_TRSM is not set +# CONFIG_RK_HDMI is not set + +# +# RGA +# +# CONFIG_ROCKCHIP_RGA is not set + +# +# RGA2 +# +# CONFIG_ROCKCHIP_RGA2 is not set + +# +# VCODEC +# +CONFIG_RK_VCODEC=y + +# +# IEP +# +# CONFIG_IEP is not set +# CONFIG_IEP_MMU is not set + +# +# DP +# + +# +# ROCKCHIP_MPP +# +CONFIG_ROCKCHIP_MPP_SERVICE=y +CONFIG_ROCKCHIP_MPP_DEVICE=y +# CONFIG_VGASTATE is not set +CONFIG_VIDEOMODE_HELPERS=y +CONFIG_HDMI=y + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_DUMMY_CONSOLE_COLUMNS=80 +CONFIG_DUMMY_CONSOLE_ROWS=25 +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_LOGO is not set +CONFIG_SOUND=y +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_DMAENGINE_PCM=y +CONFIG_SND_HWDEP=y +CONFIG_SND_RAWMIDI=y +CONFIG_SND_JACK=y +CONFIG_SND_SEQUENCER=y +CONFIG_SND_SEQ_DUMMY=y +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +CONFIG_SND_PCM_TIMER=y +# CONFIG_SND_SEQUENCER_OSS is not set +CONFIG_SND_HRTIMER=y +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_MAX_CARDS=32 +# CONFIG_SND_SUPPORT_OLD_API is not set +CONFIG_SND_PROC_FS=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_RAWMIDI_SEQ=y +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_ALOOP is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# HD-Audio +# +CONFIG_SND_HDA_PREALLOC_SIZE=64 +# CONFIG_SND_SPI is not set +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=y +# CONFIG_SND_USB_UA101 is not set +# CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_USB_6FIRE is not set +# CONFIG_SND_USB_HIFACE is not set +# CONFIG_SND_BCD2000 is not set +# CONFIG_SND_USB_POD is not set +# CONFIG_SND_USB_PODHD is not set +# CONFIG_SND_USB_TONEPORT is not set +# CONFIG_SND_USB_VARIAX is not set +CONFIG_SND_SOC=y +CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y +# CONFIG_SND_ATMEL_SOC is not set +# CONFIG_SND_DESIGNWARE_I2S is not set + +# +# SoC Audio for Freescale CPUs +# + +# +# Common SoC Audio options for Freescale CPUs: +# +# CONFIG_SND_SOC_FSL_ASRC is not set +# CONFIG_SND_SOC_FSL_SAI is not set +# CONFIG_SND_SOC_FSL_SSI is not set +# CONFIG_SND_SOC_FSL_SPDIF is not set +# CONFIG_SND_SOC_FSL_ESAI is not set +# CONFIG_SND_SOC_IMX_AUDMUX is not set +CONFIG_SND_SOC_ROCKCHIP=y +# CONFIG_SND_SOC_ROCKCHIP_FORCE_SRAM is not set +CONFIG_SND_SOC_ROCKCHIP_I2S=y +# CONFIG_SND_SOC_ROCKCHIP_I2S_TDM is not set +# CONFIG_SND_SOC_ROCKCHIP_MULTI_DAIS is not set +# CONFIG_SND_SOC_ROCKCHIP_PDM is not set +# CONFIG_SND_SOC_ROCKCHIP_SPDIF is not set +# CONFIG_SND_SOC_ROCKCHIP_SPDIFRX is not set +# CONFIG_SND_SOC_ROCKCHIP_VAD is not set +# CONFIG_SND_SOC_ROCKCHIP_DA7219 is not set +# CONFIG_SND_SOC_ROCKCHIP_HDMI_ANALOG is not set +# CONFIG_SND_SOC_ROCKCHIP_MAX98090 is not set +# CONFIG_SND_SOC_ROCKCHIP_MULTICODECS is not set +# CONFIG_SND_SOC_ROCKCHIP_RT5645 is not set +# CONFIG_SND_SOC_ROCKCHIP_RT5651_TC358749 is not set +# CONFIG_SND_SOC_ROCKCHIP_CDNDP is not set + +# +# Allwinner SoC Audio support +# +# CONFIG_SND_SUN4I_CODEC is not set +# CONFIG_SND_SOC_XTFPGA_I2S is not set +CONFIG_SND_SOC_I2C_AND_SPI=y + +# +# CODEC drivers +# +# CONFIG_SND_SOC_AC97_CODEC is not set +# CONFIG_SND_SOC_ADAU1701 is not set +# CONFIG_SND_SOC_AK4104 is not set +# CONFIG_SND_SOC_AK4554 is not set +# CONFIG_SND_SOC_AK4613 is not set +# CONFIG_SND_SOC_AK4642 is not set +# CONFIG_SND_SOC_AK5386 is not set +# CONFIG_SND_SOC_ALC5623 is not set +# CONFIG_SND_SOC_CS35L32 is not set +# CONFIG_SND_SOC_CS42L51_I2C is not set +# CONFIG_SND_SOC_CS42L52 is not set +# CONFIG_SND_SOC_CS42L56 is not set +# CONFIG_SND_SOC_CS42L73 is not set +# CONFIG_SND_SOC_CS4265 is not set +# CONFIG_SND_SOC_CS4270 is not set +# CONFIG_SND_SOC_CS4271_I2C is not set +# CONFIG_SND_SOC_CS4271_SPI is not set +# CONFIG_SND_SOC_CS42XX8_I2C is not set +# CONFIG_SND_SOC_CS4349 is not set +# CONFIG_SND_SOC_CX2072X is not set +# CONFIG_SND_SOC_CX20810 is not set +# CONFIG_SND_SOC_DUMMY_CODEC is not set +# CONFIG_SND_SOC_BT_SCO is not set +# CONFIG_SND_SOC_ES8316 is not set +# CONFIG_SND_SOC_ES8323 is not set +# CONFIG_SND_SOC_ES8328 is not set +# CONFIG_SND_SOC_ES8328_I2C is not set +# CONFIG_SND_SOC_ES8396 is not set +# CONFIG_SND_SOC_GTM601 is not set +# CONFIG_SND_SOC_GVA_CODEC is not set +# CONFIG_SND_SOC_FM1288 is not set +# CONFIG_SND_SOC_PCM1681 is not set +# CONFIG_SND_SOC_PCM1792A is not set +# CONFIG_SND_SOC_PCM512x_I2C is not set +# CONFIG_SND_SOC_PCM512x_SPI is not set +# CONFIG_SND_SOC_RK312X is not set +# CONFIG_SND_SOC_RK3228 is not set +# CONFIG_SND_SOC_RK3308 is not set +# CONFIG_SND_SOC_RK3328 is not set +CONFIG_SND_SOC_RK817=y +CONFIG_SND_SOC_RL6231=y +# CONFIG_SND_SOC_RT5616 is not set +# CONFIG_SND_SOC_RT5631 is not set +CONFIG_SND_SOC_RT5640=y +# CONFIG_SND_SOC_RT5651 is not set +# CONFIG_SND_SOC_RT5677_SPI is not set +# CONFIG_SND_SOC_SGTL5000 is not set +# CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set +# CONFIG_SND_SOC_SPDIF is not set +# CONFIG_SND_SOC_SSM2602_SPI is not set +# CONFIG_SND_SOC_SSM2602_I2C is not set +# CONFIG_SND_SOC_SSM4567 is not set +# CONFIG_SND_SOC_STA32X is not set +# CONFIG_SND_SOC_STA350 is not set +# CONFIG_SND_SOC_STI_SAS is not set +# CONFIG_SND_SOC_TAS2552 is not set +# CONFIG_SND_SOC_TAS5086 is not set +# CONFIG_SND_SOC_TAS571X is not set +# CONFIG_SND_SOC_TC358749X is not set +# CONFIG_SND_SOC_TFA9879 is not set +# CONFIG_SND_SOC_TLV320AIC23_I2C is not set +# CONFIG_SND_SOC_TLV320AIC23_SPI is not set +# CONFIG_SND_SOC_TLV320AIC31XX is not set +# CONFIG_SND_SOC_TLV320AIC3X is not set +# CONFIG_SND_SOC_TS3A227E is not set +# CONFIG_SND_SOC_WM8510 is not set +# CONFIG_SND_SOC_WM8523 is not set +# CONFIG_SND_SOC_WM8580 is not set +# CONFIG_SND_SOC_WM8711 is not set +# CONFIG_SND_SOC_WM8728 is not set +# CONFIG_SND_SOC_WM8731 is not set +# CONFIG_SND_SOC_WM8737 is not set +# CONFIG_SND_SOC_WM8741 is not set +# CONFIG_SND_SOC_WM8750 is not set +# CONFIG_SND_SOC_WM8753 is not set +# CONFIG_SND_SOC_WM8770 is not set +# CONFIG_SND_SOC_WM8776 is not set +# CONFIG_SND_SOC_WM8804_I2C is not set +# CONFIG_SND_SOC_WM8804_SPI is not set +# CONFIG_SND_SOC_WM8903 is not set +# CONFIG_SND_SOC_WM8962 is not set +# CONFIG_SND_SOC_WM8978 is not set +# CONFIG_SND_SOC_TPA6130A2 is not set +CONFIG_SND_SIMPLE_CARD=y +# CONFIG_SOUND_PRIME is not set + +# +# HID support +# +CONFIG_HID=y +CONFIG_HID_BATTERY_STRENGTH=y +CONFIG_HIDRAW=y +CONFIG_UHID=y +CONFIG_HID_GENERIC=y + +# +# Special HID drivers +# +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_ACRUX is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_APPLEIR is not set +# CONFIG_HID_AUREAL is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_BETOP_FF is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_CORSAIR is not set +# CONFIG_HID_PRODIKEYS is not set +# CONFIG_HID_CP2112 is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EMS_FF is not set +# CONFIG_HID_ELECOM is not set +# CONFIG_HID_ELO is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_GEMBIRD is not set +# CONFIG_HID_GFRM is not set +# CONFIG_HID_HOLTEK is not set +# CONFIG_HID_GT683R is not set +# CONFIG_HID_KEYTOUCH is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_UCLOGIC is not set +# CONFIG_HID_WALTOP is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_ICADE is not set +# CONFIG_HID_TWINHAN is not set +CONFIG_HID_KENSINGTON=y +# CONFIG_HID_LCPOWER is not set +# CONFIG_HID_LENOVO is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MAGICMOUSE is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MONTEREY is not set +CONFIG_HID_MULTITOUCH=y +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PENMOUNT is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_PLANTRONICS is not set +# CONFIG_HID_PRIMAX is not set +# CONFIG_HID_ROCCAT is not set +# CONFIG_HID_SAITEK is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_SPEEDLINK is not set +# CONFIG_HID_STEELSERIES is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_RMI is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TIVO is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THINGM is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_WACOM is not set +# CONFIG_HID_WIIMOTE is not set +# CONFIG_HID_XINMO is not set +# CONFIG_HID_ZEROPLUS is not set +# CONFIG_HID_ZYDACRON is not set +# CONFIG_HID_SENSOR_HUB is not set +# CONFIG_HID_RKVR is not set +# CONFIG_HID_ALPS is not set + +# +# USB HID support +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +CONFIG_USB_HIDDEV=y + +# +# I2C HID support +# +CONFIG_I2C_HID=y +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEFAULT_PERSIST is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_OTG=y +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_OTG_FSM is not set +# CONFIG_USB_ULPI_BUS is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_XHCI_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_FOTG210_HCD is not set +# CONFIG_USB_MAX3421_HCD is not set +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HCD_TEST_MODE is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=y +# CONFIG_USB_PRINTER is not set +CONFIG_USB_WDM=y +# 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 info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_REALTEK 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_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_STORAGE_ENE_UB6250 is not set +CONFIG_USB_UAS=y + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USBIP_CORE is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_DWC3 is not set +CONFIG_USB_DWC2=y +# CONFIG_USB_DWC2_HOST is not set + +# +# Gadget/Dual-role mode requires USB Gadget support to be enabled +# +# CONFIG_USB_DWC2_PERIPHERAL is not set +CONFIG_USB_DWC2_DUAL_ROLE=y +# CONFIG_USB_DWC2_DEBUG is not set +# CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set +# CONFIG_USB_CHIPIDEA is not set +# CONFIG_USB_ISP1760 is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=y +# CONFIG_USB_SERIAL_CONSOLE is not set +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_SIMPLE is not set +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_CH341 is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +CONFIG_USB_SERIAL_CP210X=y +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +CONFIG_USB_SERIAL_FTDI_SIO=y +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_F81232 is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_IUU is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +CONFIG_USB_SERIAL_KEYSPAN=y +# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_METRO is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MXUPORT is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +CONFIG_USB_SERIAL_PL2303=y +CONFIG_USB_SERIAL_OTI6858=y +# CONFIG_USB_SERIAL_QCAUX is not set +CONFIG_USB_SERIAL_QUALCOMM=y +# CONFIG_USB_SERIAL_SPCP8X5 is not set +# CONFIG_USB_SERIAL_SAFE is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=y +# CONFIG_USB_SERIAL_SYMBOL is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +CONFIG_USB_SERIAL_WWAN=y +CONFIG_USB_SERIAL_OPTION=y +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_XSENS_MT is not set +# CONFIG_USB_SERIAL_WISHBONE is not set +# CONFIG_USB_SERIAL_SSU100 is not set +# CONFIG_USB_SERIAL_QT2 is not set +# CONFIG_USB_SERIAL_DEBUG 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_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM 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_EHSET_TEST_FIXTURE is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set +CONFIG_USB_EZUSB_FX2=y +# CONFIG_USB_HSIC_USB3503 is not set +# CONFIG_USB_LINK_LAYER_TEST is not set +# CONFIG_USB_CHAOSKEY is not set + +# +# USB Physical Layer drivers +# +# CONFIG_USB_PHY is not set +# CONFIG_USB_OTG_WAKELOCK is not set +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ISP1301 is not set +# CONFIG_USB_ULPI is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +CONFIG_USB_GADGET_DEBUG_FILES=y +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=500 +CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 + +# +# USB Peripheral Controller +# +# CONFIG_USB_FOTG210_UDC is not set +# CONFIG_USB_GR_UDC is not set +# CONFIG_USB_R8A66597 is not set +# CONFIG_USB_PXA27X is not set +# CONFIG_USB_MV_UDC is not set +# CONFIG_USB_MV_U3D is not set +# CONFIG_USB_M66592 is not set +# CONFIG_USB_BDC_UDC is not set +# CONFIG_USB_NET2272 is not set +# CONFIG_USB_GADGET_XILINX is not set +# CONFIG_USB_DUMMY_HCD is not set +CONFIG_USB_LIBCOMPOSITE=y +CONFIG_USB_F_ACM=y +CONFIG_USB_U_SERIAL=y +CONFIG_USB_F_SERIAL=y +CONFIG_USB_F_OBEX=y +# CONFIG_USB_CONFIGFS is not set +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_G_NCM is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FUNCTIONFS is not set +# CONFIG_USB_MASS_STORAGE is not set +CONFIG_USB_G_SERIAL=y +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_ACM_MS is not set +# CONFIG_USB_G_MULTI is not set +# CONFIG_USB_G_HID is not set +# CONFIG_USB_G_DBGP is not set +# CONFIG_USB_G_WEBCAM is not set + +# +# ROCKCHIP USB Support +# +# CONFIG_USB20_HOST is not set +# CONFIG_USB20_OTG is not set +# CONFIG_USB_LED_TRIG is not set +# CONFIG_UWB is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_EMBEDDED_SDIO is not set +# CONFIG_MMC_PARANOID_SD_INIT is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +CONFIG_MMC_TEST=y +# CONFIG_MMC_SIMULATE_MAX_SPEED is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_ARMMMCI is not set +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_SPI is not set +CONFIG_MMC_DW=y +CONFIG_MMC_DW_PLTFM=y +# CONFIG_MMC_DW_EXYNOS is not set +# CONFIG_MMC_DW_K3 is not set +CONFIG_MMC_DW_ROCKCHIP=y +# CONFIG_MMC_VUB300 is not set +# CONFIG_MMC_USHC is not set +# CONFIG_MMC_USDHI6ROL0 is not set +# CONFIG_MMC_MTK is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +# CONFIG_LEDS_CLASS_FLASH is not set + +# +# LED drivers +# +# CONFIG_LEDS_BCM6328 is not set +# CONFIG_LEDS_BCM6358 is not set +# CONFIG_LEDS_LM3530 is not set +# CONFIG_LEDS_LM3642 is not set +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_LP5521 is not set +# CONFIG_LEDS_LP5523 is not set +# CONFIG_LEDS_LP5562 is not set +# CONFIG_LEDS_LP8501 is not set +# CONFIG_LEDS_LP8860 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_PCA963X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_PWM is not set +# CONFIG_LEDS_REGULATOR is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +# CONFIG_LEDS_TCA6507 is not set +# CONFIG_LEDS_TLC591XX is not set +# CONFIG_LEDS_LM355x is not set +CONFIG_LEDS_IS31FL32XX=y + +# +# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) +# +# CONFIG_LEDS_BLINKM is not set +# CONFIG_LEDS_SYSCON is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +# CONFIG_LEDS_TRIGGER_TIMER is not set +# CONFIG_LEDS_TRIGGER_ONESHOT is not set +# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_CPU is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_LEDS_TRIGGER_TRANSIENT is not set +# CONFIG_LEDS_TRIGGER_CAMERA is not set +# CONFIG_SWITCH is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_EDAC_SUPPORT=y +# CONFIG_EDAC is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_SYSTOHC=y +CONFIG_RTC_SYSTOHC_DEVICE="rtc0" +# 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_ABB5ZES3 is not set +# CONFIG_RTC_DRV_ABX80X is not set +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS3232 is not set +# CONFIG_RTC_DRV_FAKE is not set +# CONFIG_RTC_DRV_HYM8563 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +CONFIG_RTC_DRV_RK808=y +# CONFIG_RTC_DRV_RK_TIMER is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_ISL12057 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF2127 is not set +# CONFIG_RTC_DRV_PCF8523 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF85063 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_RV3029C2 is not set +# CONFIG_RTC_DRV_RV8803 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T93 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1343 is not set +# CONFIG_RTC_DRV_DS1347 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 +# CONFIG_RTC_DRV_PCF2123 is not set +# CONFIG_RTC_DRV_RX4581 is not set +# CONFIG_RTC_DRV_MCP795 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1685_FAMILY is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_DS2404 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_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set +# CONFIG_RTC_DRV_ZYNQMP is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_PL030 is not set +# CONFIG_RTC_DRV_PL031 is not set +# CONFIG_RTC_DRV_SNVS is not set + +# +# HID Sensor RTC drivers +# +# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +CONFIG_DMA_ENGINE=y +CONFIG_DMA_OF=y +# CONFIG_AMBA_PL08X is not set +# CONFIG_FSL_EDMA is not set +# CONFIG_INTEL_IDMA64 is not set +CONFIG_PL330_DMA=y +# CONFIG_DW_DMAC is not set + +# +# DMA Clients +# +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set +# CONFIG_VFIO is not set +# CONFIG_VIRT_DRIVERS is not set + +# +# Virtio drivers +# +# CONFIG_VIRTIO_MMIO is not set + +# +# Microsoft Hyper-V guest support +# +CONFIG_STAGING=y +# CONFIG_PRISM2_USB is not set +# CONFIG_COMEDI is not set +# CONFIG_RTLLIB is not set +# CONFIG_R8712U is not set +# CONFIG_R8188EU is not set +# CONFIG_R8723AU is not set +# CONFIG_VT6656 is not set + +# +# IIO staging drivers +# + +# +# Accelerometers +# +# CONFIG_ADIS16201 is not set +# CONFIG_ADIS16203 is not set +# CONFIG_ADIS16204 is not set +# CONFIG_ADIS16209 is not set +# CONFIG_ADIS16220 is not set +# CONFIG_ADIS16240 is not set +# CONFIG_LIS3L02DQ is not set +# CONFIG_SCA3000 is not set + +# +# Analog to digital converters +# +# CONFIG_AD7606 is not set +# CONFIG_AD7780 is not set +# CONFIG_AD7816 is not set +# CONFIG_AD7192 is not set +# CONFIG_AD7280 is not set + +# +# Analog digital bi-direction converters +# +# CONFIG_ADT7316 is not set + +# +# Capacitance to digital converters +# +# CONFIG_AD7150 is not set +# CONFIG_AD7152 is not set +# CONFIG_AD7746 is not set + +# +# Direct Digital Synthesis +# +# CONFIG_AD9832 is not set +# CONFIG_AD9834 is not set + +# +# Digital gyroscope sensors +# +# CONFIG_ADIS16060 is not set + +# +# Network Analyzer, Impedance Converters +# +# CONFIG_AD5933 is not set +# CONFIG_INV_MPU_IIO is not set + +# +# Light sensors +# +CONFIG_SENSORS_ISL29018=y +# CONFIG_SENSORS_ISL29028 is not set +CONFIG_TSL2583=y +# CONFIG_TSL2x7x is not set + +# +# Magnetometer sensors +# +# CONFIG_SENSORS_HMC5843_I2C is not set +# CONFIG_SENSORS_HMC5843_SPI is not set + +# +# Active energy metering IC +# +# CONFIG_ADE7753 is not set +# CONFIG_ADE7754 is not set +# CONFIG_ADE7758 is not set +# CONFIG_ADE7759 is not set +# CONFIG_ADE7854 is not set + +# +# Resolver to digital converters +# +# CONFIG_AD2S90 is not set +# CONFIG_AD2S1200 is not set +# CONFIG_AD2S1210 is not set + +# +# Triggers - standalone +# +# CONFIG_IIO_PERIODIC_RTC_TRIGGER is not set +# CONFIG_IIO_SIMPLE_DUMMY is not set + +# +# Speakup console speech +# +# CONFIG_SPEAKUP is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set +# CONFIG_STAGING_MEDIA is not set + +# +# Android +# +# CONFIG_ASHMEM is not set +# CONFIG_ANDROID_TIMED_OUTPUT is not set +# CONFIG_ANDROID_LOW_MEMORY_KILLER is not set +# CONFIG_SYNC is not set +# CONFIG_ION is not set +CONFIG_FIQ_DEBUGGER=y +CONFIG_FIQ_DEBUGGER_NO_SLEEP=y +# CONFIG_FIQ_DEBUGGER_WAKEUP_IRQ_ALWAYS_ON is not set +CONFIG_FIQ_DEBUGGER_CONSOLE=y +CONFIG_FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE=y +# CONFIG_FIQ_DEBUGGER_TRUST_ZONE is not set +# CONFIG_FIQ_DEBUGGER_UART_OVERLAY is not set +# CONFIG_FIQ_WATCHDOG is not set +# CONFIG_RK_CONSOLE_THREAD is not set +# CONFIG_STAGING_BOARD is not set +# CONFIG_WIMAX_GDM72XX is not set +# CONFIG_LTE_GDM724X is not set +# CONFIG_LUSTRE_FS is not set +# CONFIG_DGAP is not set +# CONFIG_GS_FPGABOOT is not set +# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set +# CONFIG_FB_TFT is not set +# CONFIG_FSL_MC_BUS is not set +# CONFIG_WILC1000_DRIVER is not set +# CONFIG_MOST is not set +# CONFIG_POWERVR_ROGUE_N is not set +# CONFIG_GOLDFISH is not set +# CONFIG_CHROME_PLATFORMS is not set +CONFIG_CLKDEV_LOOKUP=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_COMMON_CLK=y + +# +# Common Clock Framework +# +# CONFIG_COMMON_CLK_VERSATILE is not set +CONFIG_COMMON_CLK_RK808=y +# CONFIG_COMMON_CLK_SI5351 is not set +# CONFIG_COMMON_CLK_SI514 is not set +# CONFIG_COMMON_CLK_SI570 is not set +# CONFIG_COMMON_CLK_CDCE925 is not set +# CONFIG_CLK_QORIQ is not set +# CONFIG_COMMON_CLK_XGENE is not set +# CONFIG_COMMON_CLK_PWM is not set +# CONFIG_COMMON_CLK_PXA is not set +# CONFIG_COMMON_CLK_CDCE706 is not set + +# +# Hardware Spinlock drivers +# +# CONFIG_HWSPINLOCK_ROCKCHIP is not set + +# +# Clock Source drivers +# +CONFIG_CLKSRC_OF=y +CONFIG_CLKSRC_PROBE=y +CONFIG_ROCKCHIP_TIMER=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set +# CONFIG_ARM_TIMER_SP804 is not set +# CONFIG_ATMEL_PIT is not set +# CONFIG_SH_TIMER_CMT is not set +# CONFIG_SH_TIMER_MTU2 is not set +# CONFIG_SH_TIMER_TMU is not set +# CONFIG_EM_TIMER_STI is not set +# CONFIG_MAILBOX is not set +CONFIG_IOMMU_API=y +CONFIG_IOMMU_SUPPORT=y + +# +# Generic IOMMU Pagetable Support +# +# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set +CONFIG_IOMMU_IOVA=y +CONFIG_OF_IOMMU=y +CONFIG_IOMMU_DMA=y +CONFIG_ROCKCHIP_IOMMU=y +# CONFIG_RK_IOMMU is not set +# CONFIG_ARM_SMMU is not set + +# +# Remoteproc drivers +# +# CONFIG_STE_MODEM_RPROC is not set + +# +# Rpmsg drivers +# + +# +# SOC (System On Chip) specific Drivers +# + +# +# Rockchip CPU selection +# +CONFIG_CPU_PX30=y +# CONFIG_CPU_RK1808 is not set +# CONFIG_CPU_RK3308 is not set +CONFIG_CPU_RK3328=y +# CONFIG_CPU_RK3366 is not set +CONFIG_CPU_RK3368=y +CONFIG_CPU_RK3399=y +CONFIG_ANDROID_VERSION=0x07010000 +CONFIG_ROCKCHIP_CPUINFO=y +# CONFIG_ROCKCHIP_DEVICEINFO is not set +CONFIG_ROCKCHIP_IPA=y +CONFIG_ROCKCHIP_OPP=y +# CONFIG_ROCKCHIP_PM_TEST is not set +CONFIG_ROCKCHIP_GRF=y +CONFIG_ROCKCHIP_PM_DOMAINS=y +CONFIG_ROCKCHIP_PVTM=y +CONFIG_ROCKCHIP_SUSPEND_MODE=y +CONFIG_ROCKCHIP_SYSTEM_MONITOR=y +# CONFIG_ROCKCHIP_VENDOR_STORAGE_UPDATE_LOADER is not set +# CONFIG_SUNXI_SRAM is not set +# CONFIG_SOC_TI is not set +CONFIG_PM_DEVFREQ=y + +# +# DEVFREQ Governors +# +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y +CONFIG_DEVFREQ_GOV_PERFORMANCE=y +CONFIG_DEVFREQ_GOV_POWERSAVE=y +CONFIG_DEVFREQ_GOV_USERSPACE=y + +# +# DEVFREQ Drivers +# +# CONFIG_ARM_ROCKCHIP_BUS_DEVFREQ is not set +CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ=y +CONFIG_PM_DEVFREQ_EVENT=y +CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI=y +# CONFIG_DEVFREQ_EVENT_ROCKCHIP_NOCP is not set +CONFIG_EXTCON=y + +# +# Extcon Device Drivers +# +# CONFIG_EXTCON_ADC_JACK is not set +# CONFIG_EXTCON_GPIO is not set +# CONFIG_EXTCON_RT8973A is not set +# CONFIG_EXTCON_SM5502 is not set +# CONFIG_EXTCON_USB_GPIO is not set +CONFIG_MEMORY=y +# CONFIG_ARM_PL172_MPMC is not set +CONFIG_IIO=y +CONFIG_IIO_BUFFER=y +# CONFIG_IIO_BUFFER_CB is not set +CONFIG_IIO_KFIFO_BUF=y +CONFIG_IIO_TRIGGER=y +CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 + +# +# Accelerometers +# +# CONFIG_BMA180 is not set +# CONFIG_BMC150_ACCEL is not set +# CONFIG_IIO_ST_ACCEL_3AXIS is not set +# CONFIG_KXSD9 is not set +# CONFIG_KXCJK1013 is not set +# CONFIG_MMA8452 is not set +# CONFIG_MMA9551 is not set +# CONFIG_MMA9553 is not set +# CONFIG_MXC4005 is not set +# CONFIG_STK8312 is not set +# CONFIG_STK8BA50 is not set + +# +# Analog to digital converters +# +# CONFIG_AD7266 is not set +# CONFIG_AD7291 is not set +# CONFIG_AD7298 is not set +# CONFIG_AD7476 is not set +# CONFIG_AD7791 is not set +# CONFIG_AD7793 is not set +# CONFIG_AD7887 is not set +# CONFIG_AD7923 is not set +# CONFIG_AD799X is not set +# CONFIG_CC10001_ADC is not set +# CONFIG_GPIO_MUXADC is not set +# CONFIG_HI8435 is not set +# CONFIG_MAX1027 is not set +# CONFIG_MAX1363 is not set +# CONFIG_MCP320X is not set +# CONFIG_MCP3422 is not set +# CONFIG_NAU7802 is not set +CONFIG_ROCKCHIP_SARADC=y +# CONFIG_TI_ADC081C is not set +# CONFIG_TI_ADC128S052 is not set +# CONFIG_VF610_ADC is not set + +# +# Amplifiers +# +# CONFIG_AD8366 is not set + +# +# Chemical Sensors +# +# CONFIG_VZ89X is not set + +# +# Hid Sensor IIO Common +# + +# +# SSP Sensor Common +# +# CONFIG_IIO_SSP_SENSORHUB is not set + +# +# Digital to analog converters +# +# CONFIG_AD5064 is not set +# CONFIG_AD5360 is not set +# CONFIG_AD5380 is not set +# CONFIG_AD5421 is not set +# CONFIG_AD5446 is not set +# CONFIG_AD5449 is not set +# CONFIG_AD5504 is not set +# CONFIG_AD5624R_SPI is not set +# CONFIG_AD5686 is not set +# CONFIG_AD5755 is not set +# CONFIG_AD5764 is not set +# CONFIG_AD5791 is not set +# CONFIG_AD7303 is not set +# CONFIG_M62332 is not set +# CONFIG_MAX517 is not set +# CONFIG_MAX5821 is not set +# CONFIG_MCP4725 is not set +# CONFIG_MCP4922 is not set + +# +# Frequency Synthesizers DDS/PLL +# + +# +# Clock Generator/Distribution +# +# CONFIG_AD9523 is not set + +# +# Phase-Locked Loop (PLL) frequency synthesizers +# +# CONFIG_ADF4350 is not set + +# +# Digital gyroscope sensors +# +# CONFIG_ADIS16080 is not set +# CONFIG_ADIS16130 is not set +# CONFIG_ADIS16136 is not set +# CONFIG_ADIS16260 is not set +# CONFIG_ADXRS450 is not set +# CONFIG_BMG160 is not set +# CONFIG_IIO_ST_GYRO_3AXIS is not set +# CONFIG_ITG3200 is not set + +# +# Humidity sensors +# +# CONFIG_DHT11 is not set +# CONFIG_HDC100X is not set +# CONFIG_HTU21 is not set +# CONFIG_SI7005 is not set +# CONFIG_SI7020 is not set + +# +# Inertial measurement units +# +# CONFIG_ADIS16400 is not set +# CONFIG_ADIS16480 is not set +# CONFIG_KMX61 is not set +# CONFIG_INV_MPU6050_IIO is not set + +# +# Light sensors +# +# CONFIG_ADJD_S311 is not set +# CONFIG_AL3320A is not set +# CONFIG_APDS9300 is not set +# CONFIG_APDS9960 is not set +# CONFIG_BH1750 is not set +# CONFIG_CM32181 is not set +# CONFIG_CM3232 is not set +# CONFIG_CM3323 is not set +# CONFIG_CM36651 is not set +# CONFIG_GP2AP020A00F is not set +# CONFIG_ISL29125 is not set +# CONFIG_JSA1212 is not set +# CONFIG_RPR0521 is not set +# CONFIG_LTR501 is not set +# CONFIG_OPT3001 is not set +# CONFIG_PA12203001 is not set +# CONFIG_STK3310 is not set +# CONFIG_TCS3414 is not set +# CONFIG_TCS3472 is not set +CONFIG_SENSORS_TSL2563=y +# CONFIG_TSL4531 is not set +# CONFIG_US5182D is not set +# CONFIG_VCNL4000 is not set +# CONFIG_VL6180 is not set + +# +# Magnetometer sensors +# +# CONFIG_AK8975 is not set +# CONFIG_AK09911 is not set +# CONFIG_BMC150_MAGN is not set +# CONFIG_MAG3110 is not set +# CONFIG_MMC35240 is not set +# CONFIG_IIO_ST_MAGN_3AXIS is not set + +# +# Inclinometer sensors +# + +# +# Triggers - standalone +# +# CONFIG_IIO_INTERRUPT_TRIGGER is not set +CONFIG_IIO_SYSFS_TRIGGER=y + +# +# Digital potentiometers +# +# CONFIG_MCP4531 is not set + +# +# Pressure sensors +# +# CONFIG_BMP280 is not set +# CONFIG_MPL115 is not set +# CONFIG_MPL3115 is not set +# CONFIG_MS5611 is not set +# CONFIG_MS5637 is not set +# CONFIG_IIO_ST_PRESS is not set +# CONFIG_T5403 is not set + +# +# Lightning sensors +# +# CONFIG_AS3935 is not set + +# +# Proximity sensors +# +# CONFIG_LIDAR_LITE_V2 is not set +# CONFIG_SRF04 is not set +# CONFIG_SX9500 is not set + +# +# Temperature sensors +# +# CONFIG_MLX90614 is not set +# CONFIG_TMP006 is not set +# CONFIG_TSYS01 is not set +# CONFIG_TSYS02D is not set +CONFIG_PWM=y +CONFIG_PWM_SYSFS=y +# CONFIG_PWM_FSL_FTM is not set +# CONFIG_PWM_GPIO is not set +# CONFIG_PWM_PCA9685 is not set +CONFIG_PWM_ROCKCHIP=y +# CONFIG_PWM_ROCKCHIP_I2S is not set +CONFIG_IRQCHIP=y +CONFIG_ARM_GIC=y +CONFIG_ARM_GIC_V3=y +CONFIG_PARTITION_PERCPU=y +# CONFIG_IPACK_BUS is not set +CONFIG_ARCH_HAS_RESET_CONTROLLER=y +CONFIG_RESET_CONTROLLER=y +# CONFIG_FMC is not set + +# +# PHY Subsystem +# +CONFIG_GENERIC_PHY=y +# CONFIG_PHY_PXA_28NM_HSIC is not set +# CONFIG_PHY_PXA_28NM_USB2 is not set +# CONFIG_BCM_KONA_USB2_PHY is not set +# CONFIG_PHY_SAMSUNG_USB2 is not set +# CONFIG_PHY_XGENE is not set +# CONFIG_PHY_ROCKCHIP_USB is not set +# CONFIG_PHY_ROCKCHIP_INNO_COMBPHY is not set +CONFIG_PHY_ROCKCHIP_INNO_USB2=y +# CONFIG_PHY_ROCKCHIP_INNO_USB3 is not set +# CONFIG_PHY_ROCKCHIP_EMMC is not set +# CONFIG_PHY_ROCKCHIP_DP is not set +CONFIG_PHY_ROCKCHIP_MIPI_RX=y +# CONFIG_PHY_ROCKCHIP_INNO_MIPI_DPHY is not set +# CONFIG_PHY_ROCKCHIP_INNO_HDMI_PHY is not set +# CONFIG_PHY_ROCKCHIP_INNO_VIDEO_PHY is not set +CONFIG_PHY_ROCKCHIP_INNO_VIDEO_COMBO_PHY=y +# CONFIG_PHY_ROCKCHIP_TYPEC is not set +# CONFIG_PHY_ROCKCHIP_PCIE is not set +# CONFIG_POWERCAP is not set +# CONFIG_MCB is not set + +# +# Performance monitor support +# +CONFIG_ARM_PMU=y +CONFIG_RAS=y + +# +# Android +# +CONFIG_ANDROID=y +# CONFIG_ANDROID_BINDER_IPC is not set +# CONFIG_LIBNVDIMM is not set +CONFIG_NVMEM=y +# CONFIG_ROCKCHIP_EFUSE is not set +CONFIG_ROCKCHIP_OTP=y +# CONFIG_STM is not set +# CONFIG_INTEL_TH is not set + +# +# FPGA Configuration Support +# +# CONFIG_FPGA is not set +# CONFIG_TEE is not set +# CONFIG_RK_FLASH is not set +# CONFIG_RK_NAND is not set + +# +# Headset device support +# +# CONFIG_RK_HEADSET is not set + +# +# Firmware Drivers +# +CONFIG_ARM_PSCI_FW=y +# CONFIG_FIRMWARE_MEMMAP is not set +CONFIG_HAVE_ARM_SMCCC=y +CONFIG_ROCKCHIP_SIP=y + +# +# File systems +# +CONFIG_DCACHE_WORD_ACCESS=y +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_USE_FOR_EXT2=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +# CONFIG_EXT4_ENCRYPTION is not set +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_XFS_FS=y +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_WARN is not set +# CONFIG_XFS_DEBUG is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +# CONFIG_F2FS_FS is not set +# CONFIG_FS_DAX is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y +CONFIG_FILE_LOCKING=y +# CONFIG_FS_ENCRYPTION is not set +CONFIG_FSNOTIFY=y +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY_USER=y +# CONFIG_FANOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_QUOTACTL is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_FUSE_FS=y +# CONFIG_CUSE is not set +# CONFIG_OVERLAY_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=936 +CONFIG_FAT_DEFAULT_IOCHARSET="utf8" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +# CONFIG_PROC_CHILDREN is not set +CONFIG_PROC_UID=y +CONFIG_KERNFS=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=y +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_ECRYPT_FS is not set +# CONFIG_SDCARD_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_LOGFS is not set +# CONFIG_CRAMFS is not set +CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_DECOMP_SINGLE=y +# CONFIG_SQUASHFS_DECOMP_MULTI is not set +# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set +# CONFIG_SQUASHFS_XATTR is not set +CONFIG_SQUASHFS_ZLIB=y +# CONFIG_SQUASHFS_LZ4 is not set +# CONFIG_SQUASHFS_LZO is not set +# CONFIG_SQUASHFS_XZ is not set +# CONFIG_SQUASHFS_ZSTD is not set +# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# 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_QNX6FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_PSTORE 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_V2=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y +# CONFIG_NFS_V4_1 is not set +# CONFIG_NFS_USE_LEGACY_DNS is not set +CONFIG_NFS_USE_KERNEL_DNS=y +# CONFIG_NFSD is not set +CONFIG_GRACE_PERIOD=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_SUNRPC_SWAP=y +# CONFIG_SUNRPC_DEBUG is not set +# CONFIG_CEPH_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 +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 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# 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_MAC_ROMAN is not set +# CONFIG_NLS_MAC_CELTIC is not set +# CONFIG_NLS_MAC_CENTEURO is not set +# CONFIG_NLS_MAC_CROATIAN is not set +# CONFIG_NLS_MAC_CYRILLIC is not set +# CONFIG_NLS_MAC_GAELIC is not set +# CONFIG_NLS_MAC_GREEK is not set +# CONFIG_NLS_MAC_ICELAND is not set +# CONFIG_NLS_MAC_INUIT is not set +# CONFIG_NLS_MAC_ROMANIAN is not set +# CONFIG_NLS_MAC_TURKISH is not set +CONFIG_NLS_UTF8=y +# CONFIG_DLM is not set +# CONFIG_VIRTUALIZATION is not set + +# +# Kernel hacking +# + +# +# printk and dmesg options +# +CONFIG_PRINTK_TIME=y +# CONFIG_PRINTK_PROCESS is not set +CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 +# CONFIG_BOOT_PRINTK_DELAY is not set +CONFIG_DYNAMIC_DEBUG=y + +# +# Compile-time checks and compiler options +# +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_INFO_REDUCED is not set +# CONFIG_DEBUG_INFO_SPLIT is not set +# CONFIG_DEBUG_INFO_DWARF4 is not set +# CONFIG_GDB_SCRIPTS is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=2048 +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_READABLE_ASM is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_PAGE_OWNER is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_SECTION_MISMATCH_WARN_ONLY=y +CONFIG_ARCH_WANT_FRAME_POINTERS=y +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0 +CONFIG_DEBUG_KERNEL=y + +# +# Memory Debugging +# +# CONFIG_PAGE_EXTENSION is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +CONFIG_HAVE_DEBUG_KMEMLEAK=y +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +CONFIG_HAVE_ARCH_KASAN=y +# CONFIG_KASAN is not set +# CONFIG_DEBUG_SHIRQ is not set + +# +# Debug Lockups and Hangs +# +CONFIG_LOCKUP_DETECTOR=y +CONFIG_HARDLOCKUP_DETECTOR_OTHER_CPU=y +CONFIG_HARDLOCKUP_DETECTOR=y +# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0 +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1 +CONFIG_DETECT_HUNG_TASK=y +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 +CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=1 +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +CONFIG_PANIC_TIMEOUT=0 +CONFIG_SCHED_DEBUG=y +CONFIG_SCHED_INFO=y +# CONFIG_PANIC_ON_RT_THROTTLING is not set +CONFIG_SCHEDSTATS=y +# CONFIG_SCHED_STACK_END_CHECK is not set +# CONFIG_DEBUG_TIMEKEEPING is not set +CONFIG_TIMER_STATS=y + +# +# Lock Debugging (spinlocks, mutexes, etc...) +# +# CONFIG_DEBUG_RT_MUTEXES is not set +CONFIG_DEBUG_SPINLOCK=y +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_LOCK_TORTURE_TEST is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_HAVE_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_PI_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +CONFIG_DEBUG_CREDENTIALS=y + +# +# RCU Debugging +# +# CONFIG_PROVE_RCU is not set +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_TORTURE_TEST is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +# CONFIG_RCU_TRACE is not set +# CONFIG_RCU_EQS_DEBUG is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_NOTIFIER_ERROR_INJECTION is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACE_CLOCK=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_GPU_TRACEPOINTS=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_TRACING=y +CONFIG_GENERIC_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +CONFIG_FUNCTION_TRACER=y +CONFIG_FUNCTION_GRAPH_TRACER=y +# CONFIG_PREEMPTIRQ_EVENTS is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_FTRACE_SYSCALLS is not set +# CONFIG_TRACER_SNAPSHOT is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_PROBE_EVENTS is not set +CONFIG_DYNAMIC_FTRACE=y +# CONFIG_FUNCTION_PROFILER is not set +CONFIG_FTRACE_MCOUNT_RECORD=y +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_TRACEPOINT_BENCHMARK is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_RING_BUFFER_STARTUP_TEST is not set +# CONFIG_TRACE_ENUM_MAP_FILE is not set +CONFIG_TRACING_EVENTS_GPIO=y + +# +# Runtime Testing +# +CONFIG_LKDTM=y +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_RBTREE_TEST is not set +# CONFIG_INTERVAL_TREE_TEST is not set +# CONFIG_PERCPU_TEST is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_TEST_HEXDUMP is not set +# CONFIG_TEST_STRING_HELPERS is not set +# CONFIG_TEST_KSTRTOX is not set +# CONFIG_TEST_PRINTF is not set +# CONFIG_TEST_RHASHTABLE is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_TEST_LKM is not set +# CONFIG_TEST_USER_COPY is not set +# CONFIG_TEST_BPF is not set +# CONFIG_TEST_FIRMWARE is not set +# CONFIG_TEST_UDELAY is not set +# CONFIG_MEMTEST is not set +# CONFIG_TEST_STATIC_KEYS is not set +# CONFIG_BUG_ON_DATA_CORRUPTION is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_ARM64_PTDUMP is not set +CONFIG_STRICT_DEVMEM=y +# CONFIG_PID_IN_CONTEXTIDR is not set +# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set +CONFIG_DEBUG_SET_MODULE_RONX=y +CONFIG_DEBUG_RODATA=y +# CONFIG_DEBUG_ALIGN_RODATA is not set +# CONFIG_CORESIGHT is not set + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_PERSISTENT_KEYRINGS is not set +# CONFIG_BIG_KEYS is not set +# CONFIG_TRUSTED_KEYS is not set +# CONFIG_ENCRYPTED_KEYS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY_PERF_EVENTS_RESTRICT is not set +# CONFIG_SECURITY is not set +CONFIG_SECURITYFS=y +CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y +CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y +# CONFIG_HARDENED_USERCOPY is not set +# CONFIG_TEE_SUPPORT is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_PCOMP2=y +CONFIG_CRYPTO_AKCIPHER2=y +CONFIG_CRYPTO_AKCIPHER=y +# CONFIG_CRYPTO_RSA is not set +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_USER is not set +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +CONFIG_CRYPTO_GF128MUL=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_NULL2=y +# CONFIG_CRYPTO_PCRYPT is not set +CONFIG_CRYPTO_WORKQUEUE=y +CONFIG_CRYPTO_CRYPTD=y +# CONFIG_CRYPTO_MCRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set +CONFIG_CRYPTO_ABLK_HELPER=y + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=y +CONFIG_CRYPTO_GCM=y +# CONFIG_CRYPTO_CHACHA20POLY1305 is not set +CONFIG_CRYPTO_SEQIV=y +# CONFIG_CRYPTO_ECHAINIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_HEH is not set +CONFIG_CRYPTO_CTR=y +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_KEYWRAP is not set + +# +# Hash modes +# +CONFIG_CRYPTO_CMAC=y +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_CRC32 is not set +CONFIG_CRYPTO_CRCT10DIF=y +CONFIG_CRYPTO_GHASH=y +# CONFIG_CRYPTO_POLY1305 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=y +CONFIG_CRYPTO_SHA512=y +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=y +# 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 is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_CHACHA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_TWOFISH_COMMON=y + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +CONFIG_CRYPTO_LZO=y +# CONFIG_CRYPTO_842 is not set +# CONFIG_CRYPTO_LZ4 is not set +# CONFIG_CRYPTO_LZ4HC is not set +# CONFIG_CRYPTO_ZSTD is not set + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_DRBG_HMAC=y +# CONFIG_CRYPTO_DRBG_HASH is not set +# CONFIG_CRYPTO_DRBG_CTR is not set +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_USER_API=y +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_USER_API_SKCIPHER=y +# CONFIG_CRYPTO_USER_API_RNG is not set +# CONFIG_CRYPTO_USER_API_AEAD is not set +CONFIG_CRYPTO_HASH_INFO=y +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_CCP is not set +# CONFIG_CRYPTO_DEV_ROCKCHIP_V1 is not set +# CONFIG_CRYPTO_DEV_ROCKCHIP_V2 is not set +CONFIG_ASYMMETRIC_KEY_TYPE=y +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y +CONFIG_PUBLIC_KEY_ALGO_RSA=y +CONFIG_X509_CERTIFICATE_PARSER=y +CONFIG_PKCS7_MESSAGE_PARSER=y +# CONFIG_PKCS7_TEST_KEY is not set +# CONFIG_SIGNED_PE_FILE_VERIFICATION is not set + +# +# Certificates for signature checking +# +CONFIG_SYSTEM_TRUSTED_KEYRING=y +CONFIG_SYSTEM_TRUSTED_KEYS="" +CONFIG_ARM64_CRYPTO=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +CONFIG_CRYPTO_GHASH_ARM64_CE=y +# CONFIG_CRYPTO_POLY_HASH_ARM64_CE is not set +CONFIG_CRYPTO_AES_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +# CONFIG_CRYPTO_AES_ARM64_NEON_BLK is not set +# CONFIG_CRYPTO_CRC32_ARM64 is not set +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_HAVE_ARCH_BITREVERSE=y +CONFIG_RATIONAL=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_NET_UTILS=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_IO=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +CONFIG_CRC_CCITT=y +CONFIG_CRC16=y +CONFIG_CRC_T10DIF=y +CONFIG_CRC_ITU_T=y +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +CONFIG_CRC7=y +CONFIG_LIBCRC32C=y +# CONFIG_CRC8 is not set +CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y +# CONFIG_RANDOM32_SELFTEST is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_LZ4_DECOMPRESS=y +CONFIG_XZ_DEC=y +# CONFIG_XZ_DEC_X86 is not set +# CONFIG_XZ_DEC_POWERPC is not set +# CONFIG_XZ_DEC_IA64 is not set +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +# CONFIG_XZ_DEC_SPARC is not set +CONFIG_XZ_DEC_BCJ=y +# CONFIG_XZ_DEC_TEST is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_BZIP2=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_DECOMPRESS_XZ=y +CONFIG_DECOMPRESS_LZO=y +CONFIG_DECOMPRESS_LZ4=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_DMA=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_NLATTR=y +CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y +CONFIG_CLZ_TAB=y +# CONFIG_CORDIC is not set +# CONFIG_DDR is not set +CONFIG_MPILIB=y +CONFIG_LIBFDT=y +CONFIG_OID_REGISTRY=y +# CONFIG_SG_SPLIT is not set +CONFIG_ARCH_HAS_SG_CHAIN=y diff --git a/layers/meta-balena-nanopc-t4/recipes-kernel/linux/linux-rockchip_%.bbappend b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/linux-rockchip_%.bbappend index e65b4cfea..e8fd580cd 100644 --- a/layers/meta-balena-nanopc-t4/recipes-kernel/linux/linux-rockchip_%.bbappend +++ b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/linux-rockchip_%.bbappend @@ -1 +1,8 @@ -inherit kernel-resin +inherit kernel-resin deploy + +# Fix module build on this 4.4 kernel +RESIN_CONFIGS_append_lec-px30 = " ccstackprotector" +RESIN_CONFIGS[ccstackprotector] = " \ + CONFIG_CC_STACKPROTECTOR_NONE=y \ + CONFIG_CC_STACKPROTECTOR_STRONG=n \ +" diff --git a/layers/meta-balena-nanopc-t4/recipes-kernel/linux/linux-rockchip_4.4.185.bb b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/linux-rockchip_4.4.185.bb new file mode 100644 index 000000000..7f35dbc7b --- /dev/null +++ b/layers/meta-balena-nanopc-t4/recipes-kernel/linux/linux-rockchip_4.4.185.bb @@ -0,0 +1,38 @@ +SUMMARY = "LEC-PX30 kernel" +DESCRIPTION = "ADLINK iPi LEC-PX30 kernel" + +FILESEXTRAPATHS_prepend := "${THISDIR}/files/4.4.185:" + +LINUX_VERSION = "4.4.185" + +SRC_URI = " \ + git://github.com/rockchip-linux/kernel.git;branch=develop-4.4 \ + file://adjust_wireless_firmware_path.patch \ +" +SRCREV = "e83084b53d4e02f5fd25aad25b42ffd3108c7f15" + +require recipes-kernel/linux/linux-yocto.inc + +PV = "${LINUX_VERSION}+git${SRCPV}" + +S = "${WORKDIR}/git" + +KCONFIG_MODE="--alldefconfig" + +COMPATIBLE_MACHINE = "(lec-px30)" + +SRC_URI += " \ + file://defconfig \ + file://0001-Device-tree-for-LEC-PX30-A2.patch \ + file://0002-Added-ethernet-driver-support-for-LEC-PX30-A2.patch \ + file://0003-Added-mcp25xxfd-driver-support-for-LEC-PX30-A2.patch \ + file://0004-Added-LT9611-driver-support-for-LEC-PX30-A2.patch \ + file://0005-Modified-compatible-property-as-per-target-kernel-dt.patch \ + file://0006-Added-Sx150x-gpio-expander-suppport-for-LEC-PX30-A2.patch \ + file://0007-Added-SPI-chip-select-enable-disable-support-for-SPI.patch \ +" + +# Comment the below line to mount file system from eMMC +# SRC_URI += "file://0008-Modified-Boot-Arguments-to-mount-fileystem-from-SD-c.patch")" + + diff --git a/smarc-px30.coffee b/smarc-px30.coffee new file mode 100644 index 000000000..42c2be215 --- /dev/null +++ b/smarc-px30.coffee @@ -0,0 +1,35 @@ +deviceTypesCommon = require '@resin.io/device-types/common' +{ networkOptions, commonImg, instructions } = deviceTypesCommon + +module.exports = + version: 1 + slug: 'smarc-px30' + name: 'I-Pi SMARC PX30 SD-CARD' + arch: 'aarch64' + state: 'new' + community: true + + instructions: commonImg.instructions + + gettingStartedLink: + windows: 'https://www.balena.io/docs/learn/getting-started/smarc-px30/nodejs/' + osx: 'https://www.balena.io/docs/learn/getting-started/smarc-px30/nodejs/' + linux: 'https://www.balena.io/docs/learn/getting-started/smarc-px30/nodejs/' + + yocto: + machine: 'smarc-px30' + image: 'resin-image' + fstype: 'resinos-img' + version: 'yocto-thud' + deployArtifact: 'resin-image-smarc-px30.resinos-img' + compressed: true + + options: [ networkOptions.group ] + + configuration: + config: + partition: + primary: 1 + path: '/config.json' + + initialization: commonImg.initialization diff --git a/smarc-px30.svg b/smarc-px30.svg new file mode 100644 index 000000000..1e46babee --- /dev/null +++ b/smarc-px30.svg @@ -0,0 +1 @@ +<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><defs><style>.cls-1{fill:#0091bd;}</style></defs><path class="cls-1" d="M9.3,10.14h2.62V21.37H9.3V20.2a4.3,4.3,0,0,1-3.36,1.51c-3.46,0-5.44-2.88-5.44-6C.5,12.09,3,9.85,6,9.85a4.05,4.05,0,0,1,3.33,1.6ZM3.19,15.81c0,1.93,1.22,3.58,3.11,3.58a3.21,3.21,0,0,0,3.18-3.54c0-2.46-1.51-3.63-3.18-3.63C4.41,12.2,3.19,13.82,3.19,15.81ZM15,10.14h2.62v1a4.58,4.58,0,0,1,1.09-.94,2.94,2.94,0,0,1,1.6-.38,3.88,3.88,0,0,1,2.06.53l-1.07,2.37A2.33,2.33,0,0,0,20,12.34a2.05,2.05,0,0,0-1.63.61,3.57,3.57,0,0,0-.73,2.58v5.84H15Zm9.05,0h2.62v1a3.42,3.42,0,0,1,2.77-1.33,3.29,3.29,0,0,1,2.9,1.64,4,4,0,0,1,3.33-1.64,3.59,3.59,0,0,1,3.2,1.76,5.6,5.6,0,0,1,.59,2.84v6.93H36.88V15.22a4.75,4.75,0,0,0-.25-2,1.48,1.48,0,0,0-1.5-1,1.94,1.94,0,0,0-1.55.82,4.5,4.5,0,0,0-.51,2.56V21.4H30.45V15.22a4.75,4.75,0,0,0-.25-2,1.48,1.48,0,0,0-1.5-1,1.94,1.94,0,0,0-1.55.82,4.5,4.5,0,0,0-.51,2.56V21.4H24.09Z"/><path class="cls-1" d="M14.88,32.17,12.5,24.85h1.7l1,3.47c.12.42.22.82.33,1.18s.21.77.33,1.19h.06c.13-.42.24-.82.33-1.19s.2-.76.31-1.18l1-3.47h1.62L16.8,32.17Z"/><path class="cls-1" d="M23.73,32.34a4.08,4.08,0,0,1-1.24-.18,3,3,0,0,1-1-.49,2.46,2.46,0,0,1-.64-.77,2.08,2.08,0,0,1-.23-1,2,2,0,0,1,.44-1.33,3.59,3.59,0,0,1,1.07-.85v-.06a3.62,3.62,0,0,1-.86-.89A2.12,2.12,0,0,1,21,25.56a2.37,2.37,0,0,1,.21-1,2.07,2.07,0,0,1,.59-.78,2.6,2.6,0,0,1,.9-.49,3.78,3.78,0,0,1,1.14-.17,3.31,3.31,0,0,1,1.11.18,2.37,2.37,0,0,1,.85.49,2.17,2.17,0,0,1,.55.77,2.48,2.48,0,0,1,.19,1,1.88,1.88,0,0,1-.35,1.14,2.93,2.93,0,0,1-.81.8v.06a3.53,3.53,0,0,1,1.09.9,2.16,2.16,0,0,1,.45,1.42,2.11,2.11,0,0,1-.22,1,2.39,2.39,0,0,1-.64.78,3.32,3.32,0,0,1-1,.52A4.08,4.08,0,0,1,23.73,32.34Zm0-1.43a1.34,1.34,0,0,0,.86-.27A1,1,0,0,0,25,29.8a.91.91,0,0,0-.13-.5,1.37,1.37,0,0,0-.38-.38,3.37,3.37,0,0,0-.6-.33l-.76-.34a2.54,2.54,0,0,0-.49.64,1.64,1.64,0,0,0-.2.77,1.12,1.12,0,0,0,.41.92A1.47,1.47,0,0,0,23.77,30.91ZM24.29,27a1.94,1.94,0,0,0,.55-1.3,1.18,1.18,0,0,0-.29-.83,1.12,1.12,0,0,0-1.49-.07,1,1,0,0,0-.3.77,1,1,0,0,0,.42.86A5.17,5.17,0,0,0,24.29,27Z"/></svg> \ No newline at end of file