diff --git a/package/boot/arm-trusted-firmware-rockchip/Makefile b/package/boot/arm-trusted-firmware-rockchip/Makefile index a1c9e120e..b712a3530 100644 --- a/package/boot/arm-trusted-firmware-rockchip/Makefile +++ b/package/boot/arm-trusted-firmware-rockchip/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=arm-trusted-firmware-rockchip -PKG_VERSION:=2.3-rc0 +PKG_VERSION:=2.3 PKG_RELEASE:=1 PKG_SOURCE:=atf-v$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://github.com/atf-builds/atf/releases/download/v$(PKG_VERSION)/atf-v$(PKG_VERSION).tar.gz? -PKG_HASH:=8d0a2bd18adf54f9cf6fe923d10f21c1d21f42a15067757333ff8989b25f100a +PKG_HASH:=bf352298743aed594cf2958dd588e06ab6713fc514bb6f809bf55a85a87134c1 PKG_LICENSE:=BSD-3-Clause PKG_LICENSE_FILES:=license.md @@ -40,7 +40,7 @@ endef define Build/InstallDev $(INSTALL_DIR) -p $(STAGING_DIR_IMAGE) - $(CP) $(PKG_BUILD_DIR)/rk3399_bl31.elf $(STAGING_DIR_IMAGE)/bl31.elf + $(CP) $(PKG_BUILD_DIR)/rk*.elf $(STAGING_DIR_IMAGE)/ endef define Package/arm-trusted-firmware-rockchip/install diff --git a/package/boot/uboot-rockchip/Makefile b/package/boot/uboot-rockchip/Makefile index b99d051fc..1de1562f4 100644 --- a/package/boot/uboot-rockchip/Makefile +++ b/package/boot/uboot-rockchip/Makefile @@ -13,6 +13,7 @@ PKG_MAINTAINER:=Tobias Maedel include $(INCLUDE_DIR)/u-boot.mk include $(INCLUDE_DIR)/package.mk +PKG_BUILD_DEPENDS:=arm-trusted-firmware-rockchip define U-Boot/Default BUILD_TARGET:=rockchip @@ -20,27 +21,43 @@ define U-Boot/Default HIDDEN:=1 endef +define U-Boot/nanopi-r2s-rk3328 + BUILD_SUBTARGET:=armv8 + NAME:=NanoPi R2S + BUILD_DEVICES:= \ + friendlyarm_nanopi-r2s + BL31=$(STAGING_DIR_IMAGE)/rk3328_bl31.elf +endef + +define U-Boot/rock-pi-e-rk3328 + BUILD_SUBTARGET:=armv8 + NAME:=Rock Pi E + BUILD_DEVICES:= \ + radxa_rock-pi-e + BL31=$(STAGING_DIR_IMAGE)/rk3328_bl31.elf +endef + define U-Boot/rockpro64-rk3399 BUILD_SUBTARGET:=armv8 NAME:=RockPro64 BUILD_DEVICES:= \ pine64_rockpro64 - DEPENDS:=+PACKAGE_u-boot-rockpro64-rk3399:arm-trusted-firmware-rockchip - PKG_BUILD_DEPENDS:=arm-trusted-firmware-rockchip + BL31=$(STAGING_DIR_IMAGE)/rk3399_bl31.elf endef UBOOT_TARGETS := \ + nanopi-r2s-rk3328 \ + rock-pi-e-rk3328 \ rockpro64-rk3399 UBOOT_CONFIGURE_VARS += USE_PRIVATE_LIBGCC=yes UBOOT_MAKE_FLAGS += \ - BL31=$(STAGING_DIR_IMAGE)/bl31.elf + BL31=$(BL31) define Build/Configure - $(SED) s/subdir.*pylibfdt//g $(PKG_BUILD_DIR)/scripts/dtc/Makefile + echo CONFIG_CMD_SETEXPR=y >> $(PKG_BUILD_DIR)/configs/$(UBOOT_CONFIG)_defconfig $(call Build/Configure/U-Boot) - $(SED) 's#CONFIG_MKIMAGE_DTC_PATH=.*#CONFIG_MKIMAGE_DTC_PATH="$(PKG_BUILD_DIR)/scripts/dtc/dtc"#g' $(PKG_BUILD_DIR)/.config echo 'CONFIG_IDENT_STRING=" OpenWrt"' >> $(PKG_BUILD_DIR)/.config endef diff --git a/package/boot/uboot-rockchip/patches/001-rockchip-Avoid-using-libfdt-with-of-platdata.diff b/package/boot/uboot-rockchip/patches/001-rockchip-Avoid-using-libfdt-with-of-platdata.diff new file mode 100644 index 000000000..21e820253 --- /dev/null +++ b/package/boot/uboot-rockchip/patches/001-rockchip-Avoid-using-libfdt-with-of-platdata.diff @@ -0,0 +1,65 @@ +diff --git a/drivers/clk/rockchip/clk_rk3328.c b/drivers/clk/rockchip/clk_rk3328.c +index a89e2ecc4a..e86c17e6d6 100644 +--- a/drivers/clk/rockchip/clk_rk3328.c ++++ b/drivers/clk/rockchip/clk_rk3328.c +@@ -672,6 +672,10 @@ static int rk3328_gmac2io_set_parent(struct clk *clk, struct clk *parent) + return 0; + } + ++ /* FIXME: Device tree should be read in ofdata_to_platdata() */ ++ if (CONFIG_IS_ENABLED(OF_PLATDATA)) ++ return -EDEADLK; ++ + /* + * Otherwise, we need to check the clock-output-names of the + * requested parent to see if the requested id is "gmac_clkin". +@@ -709,6 +713,10 @@ static int rk3328_gmac2io_ext_set_parent(struct clk *clk, struct clk *parent) + return 0; + } + ++ /* FIXME: Device tree should be read in ofdata_to_platdata() */ ++ if (CONFIG_IS_ENABLED(OF_PLATDATA)) ++ return -EDEADLK; ++ + /* + * Otherwise, we need to check the clock-output-names of the + * requested parent to see if the requested id is "gmac_clkin". +@@ -765,9 +773,11 @@ static int rk3328_clk_probe(struct udevice *dev) + + static int rk3328_clk_ofdata_to_platdata(struct udevice *dev) + { +- struct rk3328_clk_priv *priv = dev_get_priv(dev); ++ if (!CONFIG_IS_ENABLED(OF_PLATDATA)) { ++ struct rk3328_clk_priv *priv = dev_get_priv(dev); + +- priv->cru = dev_read_addr_ptr(dev); ++ priv->cru = dev_read_addr_ptr(dev); ++ } + + return 0; + } +diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c +index 80dc431d20..dccc54e95f 100644 +--- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c ++++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c +@@ -383,8 +383,8 @@ static int rockchip_pinconf_prop_name_to_param(const char *property, + return -EPERM; + } + +-static int rockchip_pinctrl_set_state(struct udevice *dev, +- struct udevice *config) ++static int __maybe_unused rockchip_pinctrl_set_state(struct udevice *dev, ++ struct udevice *config) + { + struct rockchip_pinctrl_priv *priv = dev_get_priv(dev); + struct rockchip_pin_ctrl *ctrl = priv->ctrl; +@@ -474,7 +474,9 @@ static int rockchip_pinctrl_set_state(struct udevice *dev, + } + + const struct pinctrl_ops rockchip_pinctrl_ops = { ++#if !CONFIG_IS_ENABLED(PLATDATA) + .set_state = rockchip_pinctrl_set_state, ++#endif + .get_gpio_mux = rockchip_pinctrl_get_gpio_mux, + }; + diff --git a/package/boot/uboot-rockchip/patches/002-dm-core-Don-t-include-ofnode-functions-with-of-platdata.diff b/package/boot/uboot-rockchip/patches/002-dm-core-Don-t-include-ofnode-functions-with-of-platdata.diff new file mode 100644 index 000000000..c25b320e8 --- /dev/null +++ b/package/boot/uboot-rockchip/patches/002-dm-core-Don-t-include-ofnode-functions-with-of-platdata.diff @@ -0,0 +1,41 @@ +diff --git a/drivers/core/Makefile b/drivers/core/Makefile +index bce7467da1..b9e4a2aab1 100644 +--- a/drivers/core/Makefile ++++ b/drivers/core/Makefile +@@ -13,6 +13,8 @@ obj-$(CONFIG_OF_LIVE) += of_access.o of_addr.o + ifndef CONFIG_DM_DEV_READ_INLINE + obj-$(CONFIG_OF_CONTROL) += read.o + endif +-obj-$(CONFIG_OF_CONTROL) += of_extra.o ofnode.o read_extra.o ++ifdef CONFIG_$(SPL_TPL_)OF_LIBFDT ++obj-$(CONFIG_$(SPL_TPL_)OF_CONTROL) += of_extra.o ofnode.o read_extra.o ++endif + + ccflags-$(CONFIG_DM_DEBUG) += -DDEBUG +diff --git a/include/dm/read.h b/include/dm/read.h +index d37fcb504d..4f02d07d00 100644 +--- a/include/dm/read.h ++++ b/include/dm/read.h +@@ -43,8 +43,7 @@ static inline bool dev_of_valid(struct udevice *dev) + return ofnode_valid(dev_ofnode(dev)); + } + +-#ifndef CONFIG_DM_DEV_READ_INLINE +- ++#if !defined(CONFIG_DM_DEV_READ_INLINE) || CONFIG_IS_ENABLED(OF_PLATDATA) + /** + * dev_read_u32() - read a 32-bit integer from a device's DT property + * +diff --git a/net/eth-uclass.c b/net/eth-uclass.c +index 3bd98b01ad..e3bfcdb6cc 100644 +--- a/net/eth-uclass.c ++++ b/net/eth-uclass.c +@@ -467,7 +467,7 @@ static int eth_pre_unbind(struct udevice *dev) + + static bool eth_dev_get_mac_address(struct udevice *dev, u8 mac[ARP_HLEN]) + { +-#if IS_ENABLED(CONFIG_OF_CONTROL) ++#if CONFIG_IS_ENABLED(OF_CONTROL) + const uint8_t *p; + + p = dev_read_u8_array_ptr(dev, "mac-address", ARP_HLEN); diff --git a/package/boot/uboot-rockchip/patches/003-spl-Allow-SPL-TPL-to-use-of-platdata-without-libfdt.diff b/package/boot/uboot-rockchip/patches/003-spl-Allow-SPL-TPL-to-use-of-platdata-without-libfdt.diff new file mode 100644 index 000000000..144657b9a --- /dev/null +++ b/package/boot/uboot-rockchip/patches/003-spl-Allow-SPL-TPL-to-use-of-platdata-without-libfdt.diff @@ -0,0 +1,22 @@ +diff --git a/lib/Kconfig b/lib/Kconfig +index b8a8509d72..1cae2d5cc8 100644 +--- a/lib/Kconfig ++++ b/lib/Kconfig +@@ -496,7 +496,7 @@ config OF_LIBFDT_OVERLAY + + config SPL_OF_LIBFDT + bool "Enable the FDT library for SPL" +- default y if SPL_OF_CONTROL ++ default y if SPL_OF_CONTROL && !SPL_OF_PLATDATA + help + This enables the FDT library (libfdt). It provides functions for + accessing binary device tree images in memory, such as adding and +@@ -517,7 +517,7 @@ config SPL_OF_LIBFDT_ASSUME_MASK + + config TPL_OF_LIBFDT + bool "Enable the FDT library for TPL" +- default y if TPL_OF_CONTROL ++ default y if TPL_OF_CONTROL && !TPL_OF_PLATDATA + help + This enables the FDT library (libfdt). It provides functions for + accessing binary device tree images in memory, such as adding and diff --git a/package/boot/uboot-rockchip/patches/005-add-rock-pi-e-support-dts.patch b/package/boot/uboot-rockchip/patches/005-add-rock-pi-e-support-dts.patch new file mode 100644 index 000000000..621ac58c7 --- /dev/null +++ b/package/boot/uboot-rockchip/patches/005-add-rock-pi-e-support-dts.patch @@ -0,0 +1,325 @@ +diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile +index c6af87cf5e..61afe94a05 100644 +--- a/arch/arm/dts/Makefile ++++ b/arch/arm/dts/Makefile +@@ -107,6 +107,7 @@ dtb-$(CONFIG_ROCKCHIP_RK3308) += \ + dtb-$(CONFIG_ROCKCHIP_RK3328) += \ + rk3328-evb.dtb \ +- rk3328-rock64.dtb ++ rk3328-rock64.dtb \ ++ rk3328-rock-pi-e.dtb + + dtb-$(CONFIG_ROCKCHIP_RK3368) += \ + rk3368-lion.dtb \ +diff --git a/arch/arm/dts/rk3328-rock-pi-e-u-boot.dtsi b/arch/arm/dts/rk3328-rock-pi-e-u-boot.dtsi +new file mode 100644 +index 0000000000..bf5b1f3adc +--- /dev/null ++++ b/arch/arm/dts/rk3328-rock-pi-e-u-boot.dtsi +@@ -0,0 +1,33 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * (C) Copyright 2020 Radxa ++ */ ++ ++#include "rk3328-u-boot.dtsi" ++#include "rk3328-sdram-ddr3-666.dtsi" ++ ++&gpio0 { ++ u-boot,dm-spl; ++}; ++ ++&pinctrl { ++ u-boot,dm-spl; ++}; ++ ++&sdmmc0m1_gpio { ++ u-boot,dm-spl; ++}; ++ ++&pcfg_pull_up_4ma { ++ u-boot,dm-spl; ++}; ++ ++&usb_host0_xhci { ++ vbus-supply = <&vcc5v0_host_xhci>; ++ status = "okay"; ++}; ++ ++/* Need this and all the pinctrl/gpio stuff above to set pinmux */ ++&vcc_sd { ++ u-boot,dm-spl; ++}; +diff --git a/arch/arm/dts/rk3328-rock-pi-e.dts b/arch/arm/dts/rk3328-rock-pi-e.dts +new file mode 100644 +index 0000000000..4b9f9a8248 +--- /dev/null ++++ b/arch/arm/dts/rk3328-rock-pi-e.dts +@@ -0,0 +1,267 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * (C) Copyright 2020 Radxa ++ */ ++ ++/dts-v1/; ++#include "rk3328.dtsi" ++ ++/ { ++ model = "Radxa Rock Pi E"; ++ compatible = "radxa,rock-pi-e", "rockchip,rk3328"; ++ ++ chosen { ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ gmac_clkin: external-gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ clock-output-names = "gmac_clkin"; ++ #clock-cells = <0>; ++ }; ++ ++ vcc_sd: sdmmc-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0m1_gpio>; ++ regulator-name = "vcc_sd"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc_io>; ++ }; ++ ++ vcc5v0_host_xhci: vcc5v0-host-xhci-drv { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ regulator-name = "vcc5v0_host_xhci"; ++ gpio = <&gpio3 RK_PA7 GPIO_ACTIVE_HIGH>; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ vcc_sys: vcc-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_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>; ++}; ++ ++&emmc { ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ mmc-hs200-1_8v; ++ supports-emmc; ++ disable-wp; ++ non-removable; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; ++ vmmc-supply = <&vcc_io>; ++ vqmmc-supply = <&vcc18_emmc>; ++ status = "okay"; ++}; ++ ++&gmac2io { ++ assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; ++ assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>; ++ clock_in_out = "input"; ++ phy-supply = <&vcc_io>; ++ phy-mode = "rgmii"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rgmiim1_pins>; ++ snps,force_thresh_dma_mode; ++ snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; ++ snps,reset-active-low; ++ snps,reset-delays-us = <0 10000 50000>; ++ tx_delay = <0x26>; ++ rx_delay = <0x11>; ++ status = "okay"; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ ++ rk805: rk805@18 { ++ compatible = "rockchip,rk805"; ++ status = "okay"; ++ reg = <0x18>; ++ interrupt-parent = <&gpio2>; ++ interrupts = <6 IRQ_TYPE_LEVEL_LOW>; ++ #clock-cells = <1>; ++ clock-output-names = "xin32k", "rk805-clkout2"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ ++ vcc1-supply = <&vcc_sys>; ++ vcc2-supply = <&vcc_sys>; ++ vcc3-supply = <&vcc_sys>; ++ vcc4-supply = <&vcc_sys>; ++ vcc5-supply = <&vcc_io>; ++ vcc6-supply = <&vcc_sys>; ++ ++ regulators { ++ vdd_logic: DCDC_REG1 { ++ regulator-name = "vdd_logic"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-ramp-delay = <12500>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vdd_arm: DCDC_REG2 { ++ regulator-name = "vdd_arm"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-ramp-delay = <12500>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-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_io: DCDC_REG4 { ++ regulator-name = "vcc_io"; ++ 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_18: LDO_REG1 { ++ regulator-name = "vcc_18"; ++ 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>; ++ }; ++ }; ++ ++ vcc18_emmc: LDO_REG2 { ++ regulator-name = "vcc18_emmc"; ++ 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_10: LDO_REG3 { ++ regulator-name = "vdd_10"; ++ 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>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&io_domains { ++ status = "okay"; ++ ++ vccio1-supply = <&vcc_io>; ++ vccio2-supply = <&vcc18_emmc>; ++ vccio3-supply = <&vcc_io>; ++ vccio4-supply = <&vcc_io>; ++ vccio5-supply = <&vcc_io>; ++ vccio6-supply = <&vcc_io>; ++ pmuio-supply = <&vcc_io>; ++}; ++ ++&pinctrl { ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ card-detect-delay = <200>; ++ disable-wp; ++ max-frequency = <150000000>; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; ++ supports-sd; ++ vmmc-supply = <&vcc_sd>; ++ status = "okay"; ++}; ++ ++&saradc { ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&usb20_otg { ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; diff --git a/package/boot/uboot-rockchip/patches/005-add-support-nanopi-r2s.patch b/package/boot/uboot-rockchip/patches/005-add-support-nanopi-r2s.patch new file mode 100644 index 000000000..2bc93378a --- /dev/null +++ b/package/boot/uboot-rockchip/patches/005-add-support-nanopi-r2s.patch @@ -0,0 +1,792 @@ +diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile +index 0127a91a..c5beaa85 100644 +--- a/arch/arm/dts/Makefile ++++ b/arch/arm/dts/Makefile +@@ -104,7 +104,8 @@ dtb-$(CONFIG_ROCKCHIP_RK3308) += \ + + dtb-$(CONFIG_ROCKCHIP_RK3328) += \ + rk3328-evb.dtb \ ++ rk3328-nanopi-r2s.dtb \ + rk3328-rock64.dtb \ + rk3328-rock-pi-e.dtb + + dtb-$(CONFIG_ROCKCHIP_RK3368) += \ +diff --git a/arch/arm/dts/rk3328-nanopi-r2-common.dtsi b/arch/arm/dts/rk3328-nanopi-r2-common.dtsi +new file mode 100644 +index 00000000..bc924346 +--- /dev/null ++++ b/arch/arm/dts/rk3328-nanopi-r2-common.dtsi +@@ -0,0 +1,614 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2018 FriendlyElec Computer Tech. Co., Ltd. ++ * (http://www.friendlyarm.com) ++ * ++ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd ++ */ ++ ++/dts-v1/; ++/*#include "rk3328-dram-default-timing.dtsi"*/ ++#include "rk3328.dtsi" ++ ++/ { ++ model = "FriendlyARM boards based on Rockchip RK3328"; ++ compatible = "friendlyarm,nanopi-r2", "rockchip,rk3328"; ++ ++ aliases { ++/* ethernet1 = &r8153;*/ ++ }; ++ ++ chosen { ++ bootargs = "swiotlb=1 coherent_pool=1m consoleblank=0"; ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ gmac_clkin: external-gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ clock-output-names = "gmac_clkin"; ++ #clock-cells = <0>; ++ }; ++ ++ leds: gpio-leds { ++ compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ pinctrl-0 =<&leds_gpio>; ++ status = "disabled"; ++ ++ status { ++ gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; ++ label = "nanopi:red:status"; ++ linux,default-trigger = "heartbeat"; ++ linux,default-trigger-delay-ms = <0>; ++ }; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ clocks = <&rk805 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 = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; ++ }; ++ ++/* sdmmc_ext: dwmmc@ff5f0000 { ++ compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; ++ reg = <0x0 0xff5f0000 0x0 0x4000>; ++ clock-freq-min-max = <400000 150000000>; ++ clocks = <&cru HCLK_SDMMC_EXT>, <&cru SCLK_SDMMC_EXT>, ++ <&cru SCLK_SDMMC_EXT_DRV>, <&cru SCLK_SDMMC_EXT_SAMPLE>; ++ clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; ++ fifo-depth = <0x100>; ++ interrupts = ; ++ status = "disabled"; ++ };*/ ++ ++ vcc_sd: sdmmc-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio0 30 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0m1_gpio>; ++ regulator-name = "vcc_sd"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc_io>; ++ }; ++ ++ vccio_sd: sdmmcio-regulator { ++ compatible = "regulator-gpio"; ++ gpios = <&gpio1 RK_PD4 GPIO_ACTIVE_HIGH>; ++ states = <1800000 0x1 ++ 3300000 0x0>; ++ regulator-name = "vccio_sd"; ++ regulator-type = "voltage"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ vin-supply = <&vcc_io>; ++ startup-delay-us = <2000>; ++ regulator-settling-time-us = <5000>; ++ enable-active-high; ++ status = "disabled"; ++ }; ++ ++ vcc_sys: vcc-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ vcc_phy: vcc-phy-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_phy"; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vcc_host_vbus: host-vbus-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_host_vbus"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ dfi: dfi@ff790000 { ++ reg = <0x00 0xff790000 0x00 0x400>; ++ compatible = "rockchip,rk3328-dfi"; ++ rockchip,grf = <&grf>; ++ status = "disabled"; ++ }; ++ ++/* dmc: dmc { ++ compatible = "rockchip,rk3328-dmc"; ++ 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>; ++ auto-min-freq = <786000>; ++ auto-freq-en = <0>; ++ #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,leakage-voltage-sel = < ++ 1 10 0 ++ 11 254 1 ++ >; ++ nvmem-cells = <&logic_leakage>; ++ nvmem-cell-names = "ddr_leakage"; ++ ++ opp-786000000 { ++ opp-hz = /bits/ 64 <786000000>; ++ opp-microvolt = <1075000>; ++ opp-microvolt-L0 = <1075000>; ++ opp-microvolt-L1 = <1050000>; ++ }; ++ opp-798000000 { ++ opp-hz = /bits/ 64 <798000000>; ++ opp-microvolt = <1075000>; ++ opp-microvolt-L0 = <1075000>; ++ opp-microvolt-L1 = <1050000>; ++ }; ++ opp-840000000 { ++ opp-hz = /bits/ 64 <840000000>; ++ opp-microvolt = <1075000>; ++ opp-microvolt-L0 = <1075000>; ++ opp-microvolt-L1 = <1050000>; ++ }; ++ opp-924000000 { ++ opp-hz = /bits/ 64 <924000000>; ++ opp-microvolt = <1100000>; ++ opp-microvolt-L0 = <1100000>; ++ opp-microvolt-L1 = <1075000>; ++ }; ++ opp-1056000000 { ++ opp-hz = /bits/ 64 <1056000000>; ++ opp-microvolt = <1175000>; ++ opp-microvolt-L0 = <1175000>; ++ opp-microvolt-L1 = <1150000>; ++ }; ++ }; ++*/}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&dfi { ++ status = "okay"; ++}; ++ ++/*&dmc { ++ center-supply = <&vdd_logic>; ++ status = "okay"; ++};*/ ++ ++&emmc { ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ max-frequency = <150000000>; ++ mmc-hs200-1_8v; ++ no-sd; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; ++ vmmc-supply = <&vcc_io>; ++ vqmmc-supply = <&vcc18_emmc>; ++ status = "okay"; ++}; ++ ++&gmac2phy { ++ phy-supply = <&vcc_phy>; ++ clock_in_out = "output"; ++ assigned-clocks = <&cru SCLK_MAC2PHY_SRC>; ++ assigned-clock-rate = <50000000>; ++ assigned-clocks = <&cru SCLK_MAC2PHY>; ++ assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; ++ status = "disabled"; ++}; ++ ++&gmac2io { ++ assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; ++ assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>; ++ clock_in_out = "input"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rgmiim1_pins>; ++ phy-handle = <&rtl8211e>; ++ phy-mode = "rgmii"; ++ phy-supply = <&vcc_phy>; ++ snps,reset-active-low; ++ snps,reset-delays-us = <0 10000 30000>; ++ snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; ++ snps,aal; ++ snps,rxpbl = <0x4>; ++ snps,txpbl = <0x4>; ++ tx_delay = <0x24>; ++ rx_delay = <0x18>; ++ status = "okay"; ++ ++ mdio { ++ compatible = "snps,dwmac-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ rtl8211e: phy@0 { ++ reg = <0>; ++ reset-assert-us = <10000>; ++ reset-deassert-us = <30000>; ++ /* reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; */ ++ }; ++ }; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ ++ rk805: rk805@18 { ++ compatible = "rockchip,rk805"; ++ reg = <0x18>; ++ interrupt-parent = <&gpio2>; ++ interrupts = <6 IRQ_TYPE_LEVEL_LOW>; ++ #clock-cells = <1>; ++ clock-output-names = "xin32k", "rk805-clkout2"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ ++ vcc1-supply = <&vcc_sys>; ++ vcc2-supply = <&vcc_sys>; ++ vcc3-supply = <&vcc_sys>; ++ vcc4-supply = <&vcc_sys>; ++ vcc5-supply = <&vcc_io>; ++ vcc6-supply = <&vcc_io>; ++ ++ regulators { ++ vdd_logic: DCDC_REG1 { ++ regulator-name = "vdd_logic"; ++ regulator-init-microvolt = <1075000>; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vdd_arm: DCDC_REG2 { ++ regulator-name = "vdd_arm"; ++ regulator-init-microvolt = <1225000>; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-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_io: DCDC_REG4 { ++ regulator-name = "vcc_io"; ++ 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_18: LDO_REG1 { ++ regulator-name = "vcc_18"; ++ 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>; ++ }; ++ }; ++ ++ vcc18_emmc: LDO_REG2 { ++ regulator-name = "vcc18_emmc"; ++ 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_10: LDO_REG3 { ++ regulator-name = "vdd_10"; ++ 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>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&io_domains { ++ status = "okay"; ++ ++ vccio1-supply = <&vcc_io>; ++ vccio2-supply = <&vcc18_emmc>; ++ vccio3-supply = <&vcc_io>; ++ vccio4-supply = <&vcc_io>; ++ vccio5-supply = <&vcc_io>; ++ vccio6-supply = <&vcc_18>; ++ pmuio-supply = <&vcc_io>; ++}; ++ ++&pinctrl { ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ sdmmc0 { ++ sdmmc0_clk: sdmmc0-clk { ++ rockchip,pins = <1 RK_PA6 1 &pcfg_pull_none_4ma>; ++ }; ++ ++ sdmmc0_cmd: sdmmc0-cmd { ++ rockchip,pins = <1 RK_PA4 1 &pcfg_pull_up_4ma>; ++ }; ++ ++ sdmmc0_dectn: sdmmc0-dectn { ++ rockchip,pins = <1 RK_PA5 1 &pcfg_pull_up_4ma>; ++ }; ++ ++ sdmmc0_bus4: sdmmc0-bus4 { ++ rockchip,pins = ++ <1 RK_PA0 1 &pcfg_pull_up_4ma>, ++ <1 RK_PA1 1 &pcfg_pull_up_4ma>, ++ <1 RK_PA2 1 &pcfg_pull_up_4ma>, ++ <1 RK_PA3 1 &pcfg_pull_up_4ma>; ++ }; ++ }; ++ ++ sdmmc0ext { ++ sdmmc0ext_clk: sdmmc0ext-clk { ++ rockchip,pins = <3 RK_PA2 3 &pcfg_pull_none_2ma>; ++ }; ++ ++ sdmmc0ext_cmd: sdmmc0ext-cmd { ++ rockchip,pins = <3 RK_PA0 3 &pcfg_pull_up_2ma>; ++ }; ++ ++ sdmmc0ext_bus4: sdmmc0ext-bus4 { ++ rockchip,pins = ++ <3 RK_PA4 3 &pcfg_pull_up_2ma>, ++ <3 RK_PA5 3 &pcfg_pull_up_2ma>, ++ <3 RK_PA6 3 &pcfg_pull_up_2ma>, ++ <3 RK_PA7 3 &pcfg_pull_up_2ma>; ++ }; ++ }; ++ ++ gmac-1 { ++ rgmiim1_pins: rgmiim1-pins { ++ rockchip,pins = ++ /* mac_txclk */ ++ <1 RK_PB4 2 &pcfg_pull_none_4ma>, ++ /* mac_rxclk */ ++ <1 RK_PB5 2 &pcfg_pull_none>, ++ /* mac_mdio */ ++ <1 RK_PC3 2 &pcfg_pull_none_2ma>, ++ /* mac_txen */ ++ <1 RK_PD1 2 &pcfg_pull_none_4ma>, ++ /* mac_clk */ ++ <1 RK_PC5 2 &pcfg_pull_none_2ma>, ++ /* mac_rxdv */ ++ <1 RK_PC6 2 &pcfg_pull_none>, ++ /* mac_mdc */ ++ <1 RK_PC7 2 &pcfg_pull_none_2ma>, ++ /* mac_rxd1 */ ++ <1 RK_PB2 2 &pcfg_pull_none>, ++ /* mac_rxd0 */ ++ <1 RK_PB3 2 &pcfg_pull_none>, ++ /* mac_txd1 */ ++ <1 RK_PB0 2 &pcfg_pull_none_4ma>, ++ /* mac_txd0 */ ++ <1 RK_PB1 2 &pcfg_pull_none_4ma>, ++ /* mac_rxd3 */ ++ <1 RK_PB6 2 &pcfg_pull_none>, ++ /* mac_rxd2 */ ++ <1 RK_PB7 2 &pcfg_pull_none>, ++ /* mac_txd3 */ ++ <1 RK_PC0 2 &pcfg_pull_none_4ma>, ++ /* mac_txd2 */ ++ <1 RK_PC1 2 &pcfg_pull_none_4ma>, ++ ++ /* mac_txclk */ ++ <0 RK_PB0 1 &pcfg_pull_none>, ++ /* mac_txen */ ++ <0 RK_PB4 1 &pcfg_pull_none>, ++ /* mac_clk */ ++ <0 RK_PD0 1 &pcfg_pull_none>, ++ /* mac_txd1 */ ++ <0 RK_PC0 1 &pcfg_pull_none>, ++ /* mac_txd0 */ ++ <0 RK_PC1 1 &pcfg_pull_none>, ++ /* mac_txd3 */ ++ <0 RK_PC7 1 &pcfg_pull_none>, ++ /* mac_txd2 */ ++ <0 RK_PC6 1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb { ++ host_vbus_drv: host-vbus-drv { ++ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ otg_vbus_drv: otg-vbus-drv { ++ rockchip,pins = <3 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ gpio-leds { ++ leds_gpio: leds-gpio { ++ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ disable-wp; ++ max-frequency = <150000000>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; ++ vmmc-supply = <&vcc_sd>; ++ status = "okay"; ++}; ++ ++/*&sdmmc_ext { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cap-sdio-irq; ++ disable-wp; ++ keep-power-in-suspend; ++ max-frequency = <100000000>; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ non-removable; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0ext_clk &sdmmc0ext_cmd &sdmmc0ext_bus4>; ++ rockchip,default-sample-phase = <120>; ++ supports-sdio; ++ sd-uhs-sdr104; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ brcmf: bcrmf@1 { ++ reg = <1>; ++ compatible = "brcm,bcm4329-fmac"; ++ interrupt-parent = <&gpio1>; ++ interrupts = ; ++ interrupt-names = "host-wake"; ++ }; ++};*/ ++ ++/*&tsadc { ++ status = "okay"; ++};*/ ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++/*&u2phy { ++ status = "okay"; ++}; ++ ++&u2phy_host { ++ status = "okay"; ++}; ++ ++&u2phy_otg { ++ status = "okay"; ++}; ++ ++&u3phy { ++ vbus-supply = <&vcc_host_vbus>; ++ status = "okay"; ++}; ++ ++&u3phy_utmi { ++ status = "okay"; ++}; ++ ++&u3phy_pipe { ++ status = "okay"; ++}; ++ ++&usb20_otg { ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usbdrd3 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3 { ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ r8153: device@2 { ++ compatible = "usbbda:8153"; ++ reg = <2>; ++ local-mac-address = [00 00 00 00 00 00]; ++ }; ++};*/ +diff --git a/arch/arm/dts/rk3328-nanopi-r2s.dts b/arch/arm/dts/rk3328-nanopi-r2s.dts +new file mode 100644 +index 00000000..c3313bdc +--- /dev/null ++++ b/arch/arm/dts/rk3328-nanopi-r2s.dts +@@ -0,0 +1,140 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2019 FriendlyElec Computer Tech. Co., Ltd. ++ * (http://www.friendlyarm.com) ++ */ ++ ++/dts-v1/; ++#include ++#include "rk3328-nanopi-r2-common.dtsi" ++ ++/ { ++ model = "FriendlyARM NanoPi R2S"; ++ compatible = "friendlyarm,nanopi-r2s", "rockchip,rk3328"; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ autorepeat; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gpio_key1>; ++ ++ reset { ++ gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>; ++ label = "reset"; ++ linux,code = ; ++ linux,input-type = <1>; ++ gpio-key,wakeup = <1>; ++ debounce-interval = <100>; ++ }; ++ }; ++ ++ vcc_rtl8153: vcc-rtl8153-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb30_en_drv>; ++ regulator-always-on; ++ regulator-name = "vcc_rtl8153"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ off-on-delay-us = <5000>; ++ enable-active-high; ++ }; ++}; ++ ++&emmc { ++ status = "disabled"; ++}; ++ ++&i2c0 { ++ status = "okay"; ++}; ++ ++&leds { ++ status = "okay"; ++ ++ lan { ++ gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>; ++ label = "nanopi:green:lan"; ++ }; ++ ++ wan { ++ gpios = <&gpio2 RK_PC2 GPIO_ACTIVE_HIGH>; ++ label = "nanopi:green:wan"; ++ }; ++}; ++ ++&leds_gpio { ++ rockchip,pins = ++ <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>, ++ <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>, ++ <2 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; ++}; ++ ++/*&pwm2 { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-1 = <&pwm2_sleep_pin>; ++ status = "okay"; ++};*/ ++ ++&rk805 { ++ interrupt-parent = <&gpio1>; ++ interrupts = ; ++}; ++ ++&vccio_sd { ++ status = "okay"; ++}; ++ ++&io_domains { ++ vccio3-supply = <&vccio_sd>; ++}; ++ ++&sdmmc { ++ vqmmc-supply = <&vccio_sd>; ++ max-frequency = <150000000>; ++ sd-uhs-sdr50; ++ sd-uhs-sdr104; ++ status = "okay"; ++}; ++ ++/*&sdmmc_ext { ++ status = "disabled"; ++};*/ ++ ++&sdio_pwrseq { ++ status = "disabled"; ++}; ++ ++&pinctrl { ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ pwm { ++ pwm2_sleep_pin: pwm2-sleep-pin { ++ rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_output_low>; ++ }; ++ }; ++ ++ rockchip-key { ++ gpio_key1: gpio-key1 { ++ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb { ++ otg_vbus_drv: otg-vbus-drv { ++ rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ usb30_en_drv: usb30-en-drv { ++ rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/rk3328.dtsi b/arch/arm/dts/rk3328.dtsi +index 060c84e6..eac257b0 100644 +--- a/arch/arm/dts/rk3328.dtsi ++++ b/arch/arm/dts/rk3328.dtsi +@@ -1386,7 +1386,7 @@ + }; + }; + +- gmac2phy { ++ gmac2phy: gmac2phy { + fephyled_speed100: fephyled-speed100 { + rockchip,pins = + <0 31 RK_FUNC_1 &pcfg_pull_none>; diff --git a/package/boot/uboot-rockchip/patches/006-add-rock-pi-e-defconfig.patch b/package/boot/uboot-rockchip/patches/006-add-rock-pi-e-defconfig.patch new file mode 100644 index 000000000..e9d99158a --- /dev/null +++ b/package/boot/uboot-rockchip/patches/006-add-rock-pi-e-defconfig.patch @@ -0,0 +1,110 @@ +diff --git a/configs/rock-pi-e-rk3328_defconfig b/configs/rock-pi-e-rk3328_defconfig +new file mode 100644 +index 0000000000..759838775f +--- /dev/null ++++ b/configs/rock-pi-e-rk3328_defconfig +@@ -0,0 +1,104 @@ ++CONFIG_ARM=y ++CONFIG_ARCH_ROCKCHIP=y ++CONFIG_SYS_TEXT_BASE=0x00200000 ++CONFIG_SPL_GPIO_SUPPORT=y ++CONFIG_ENV_OFFSET=0x3F8000 ++CONFIG_ROCKCHIP_RK3328=y ++CONFIG_TPL_ROCKCHIP_COMMON_BOARD=y ++CONFIG_TPL_LIBCOMMON_SUPPORT=y ++CONFIG_TPL_LIBGENERIC_SUPPORT=y ++CONFIG_SPL_DRIVERS_MISC_SUPPORT=y ++CONFIG_SPL_STACK_R_ADDR=0x4000000 ++CONFIG_SPL_SYS_MALLOC_F_LEN=0x4000 ++CONFIG_NR_DRAM_BANKS=1 ++CONFIG_DEBUG_UART_BASE=0xFF130000 ++CONFIG_DEBUG_UART_CLOCK=24000000 ++CONFIG_SMBIOS_PRODUCT_NAME="rock-pi-e_rk3328" ++CONFIG_DEBUG_UART=y ++CONFIG_TPL_SYS_MALLOC_F_LEN=0x800 ++# CONFIG_ANDROID_BOOT_IMAGE is not set ++CONFIG_FIT=y ++CONFIG_FIT_VERBOSE=y ++CONFIG_SPL_LOAD_FIT=y ++CONFIG_DEFAULT_FDT_FILE="rockchip/rk3328-rock-pi-e.dtb" ++CONFIG_MISC_INIT_R=y ++# CONFIG_DISPLAY_CPUINFO is not set ++CONFIG_DISPLAY_BOARDINFO_LATE=y ++# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set ++CONFIG_TPL_SYS_MALLOC_SIMPLE=y ++CONFIG_SPL_STACK_R=y ++CONFIG_SPL_I2C_SUPPORT=y ++CONFIG_SPL_POWER_SUPPORT=y ++CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x10000 ++CONFIG_SPL_ATF=y ++CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y ++CONFIG_TPL_DRIVERS_MISC_SUPPORT=y ++CONFIG_CMD_BOOTZ=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_USB=y ++CONFIG_CMD_TIME=y ++CONFIG_SPL_OF_CONTROL=y ++CONFIG_TPL_OF_CONTROL=y ++CONFIG_DEFAULT_DEVICE_TREE="rk3328-rock-pi-e" ++CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" ++CONFIG_TPL_OF_PLATDATA=y ++CONFIG_ENV_IS_IN_MMC=y ++CONFIG_SYS_RELOC_GD_ENV_ADDR=y ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_TPL_DM=y ++CONFIG_REGMAP=y ++CONFIG_SPL_REGMAP=y ++CONFIG_TPL_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_SPL_SYSCON=y ++CONFIG_TPL_SYSCON=y ++CONFIG_CLK=y ++CONFIG_SPL_CLK=y ++CONFIG_FASTBOOT_BUF_ADDR=0x800800 ++CONFIG_FASTBOOT_CMD_OEM_FORMAT=y ++CONFIG_ROCKCHIP_GPIO=y ++CONFIG_SYS_I2C_ROCKCHIP=y ++CONFIG_MMC_DW=y ++CONFIG_MMC_DW_ROCKCHIP=y ++CONFIG_SF_DEFAULT_SPEED=20000000 ++CONFIG_DM_ETH=y ++CONFIG_ETH_DESIGNWARE=y ++CONFIG_GMAC_ROCKCHIP=y ++CONFIG_PHY=y ++CONFIG_PINCTRL=y ++CONFIG_SPL_PINCTRL=y ++CONFIG_DM_PMIC=y ++CONFIG_PMIC_RK8XX=y ++CONFIG_SPL_DM_REGULATOR=y ++CONFIG_REGULATOR_PWM=y ++CONFIG_SPL_DM_REGULATOR_FIXED=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_REGULATOR_RK8XX=y ++CONFIG_PWM_ROCKCHIP=y ++CONFIG_RAM=y ++CONFIG_SPL_RAM=y ++CONFIG_TPL_RAM=y ++CONFIG_DM_RESET=y ++CONFIG_BAUDRATE=1500000 ++CONFIG_DEBUG_UART_SHIFT=2 ++CONFIG_DEBUG_UART_ANNOUNCE=y ++CONFIG_DEBUG_UART_SKIP_INIT=y ++CONFIG_SYSRESET=y ++# CONFIG_TPL_SYSRESET is not set ++CONFIG_USB=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_DWC3=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_GENERIC=y ++CONFIG_USB_OHCI_HCD=y ++CONFIG_USB_OHCI_GENERIC=y ++CONFIG_USB_DWC2=y ++CONFIG_USB_DWC3=y ++# CONFIG_USB_DWC3_GADGET is not set ++CONFIG_USB_GADGET=y ++CONFIG_USB_GADGET_DWC2_OTG=y ++CONFIG_SPL_TINY_MEMSET=y ++CONFIG_TPL_TINY_MEMSET=y ++CONFIG_ERRNO_STR=y ++CONFIG_SMBIOS_MANUFACTURER="radxa" diff --git a/package/boot/uboot-rockchip/patches/006-add-support-nanopi-r2s-defconfig.patch b/package/boot/uboot-rockchip/patches/006-add-support-nanopi-r2s-defconfig.patch new file mode 100644 index 000000000..44503ba61 --- /dev/null +++ b/package/boot/uboot-rockchip/patches/006-add-support-nanopi-r2s-defconfig.patch @@ -0,0 +1,149 @@ +diff --git a/arch/arm/dts/rk3328-nanopi-r2s-u-boot.dtsi b/arch/arm/dts/rk3328-nanopi-r2s-u-boot.dtsi +new file mode 100644 +index 00000000..cf3452ea +--- /dev/null ++++ b/arch/arm/dts/rk3328-nanopi-r2s-u-boot.dtsi +@@ -0,0 +1,37 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * (C) Copyright 2018-2019 Rockchip Electronics Co., Ltd ++ */ ++ ++#include "rk3328-u-boot.dtsi" ++#include "rk3328-sdram-ddr4-666.dtsi" ++/ { ++ chosen { ++ u-boot,spl-boot-order = "same-as-spl", &sdmmc, &emmc; ++ }; ++}; ++ ++&gpio0 { ++ u-boot,dm-spl; ++}; ++ ++&pinctrl { ++ u-boot,dm-spl; ++}; ++ ++&sdmmc0m1_gpio { ++ u-boot,dm-spl; ++}; ++ ++&pcfg_pull_up_4ma { ++ u-boot,dm-spl; ++}; ++ ++&usb_host0_xhci { ++ status = "okay"; ++}; ++ ++/* Need this and all the pinctrl/gpio stuff above to set pinmux */ ++&vcc_sd { ++ u-boot,dm-spl; ++}; +diff --git a/configs/nanopi-r2s-rk3328_defconfig b/configs/nanopi-r2s-rk3328_defconfig +new file mode 100644 +index 00000000..720b5e04 +--- /dev/null ++++ b/configs/nanopi-r2s-rk3328_defconfig +@@ -0,0 +1,100 @@ ++CONFIG_ARM=y ++CONFIG_ARCH_ROCKCHIP=y ++CONFIG_SYS_TEXT_BASE=0x00200000 ++CONFIG_SPL_GPIO_SUPPORT=y ++CONFIG_ROCKCHIP_RK3328=y ++CONFIG_TPL_ROCKCHIP_COMMON_BOARD=y ++CONFIG_TPL_LIBCOMMON_SUPPORT=y ++CONFIG_TPL_LIBGENERIC_SUPPORT=y ++CONFIG_SPL_DRIVERS_MISC_SUPPORT=y ++CONFIG_ENV_OFFSET=0x3F8000 ++CONFIG_SPL_STACK_R_ADDR=0x600000 ++CONFIG_NR_DRAM_BANKS=1 ++CONFIG_DEBUG_UART_BASE=0xFF130000 ++CONFIG_DEBUG_UART_CLOCK=24000000 ++CONFIG_SMBIOS_PRODUCT_NAME="nanopi-r2s_rk3328" ++CONFIG_DEBUG_UART=y ++CONFIG_TPL_SYS_MALLOC_F_LEN=0x800 ++# CONFIG_ANDROID_BOOT_IMAGE is not set ++CONFIG_FIT=y ++CONFIG_FIT_VERBOSE=y ++CONFIG_SPL_LOAD_FIT=y ++CONFIG_DEFAULT_FDT_FILE="rockchip/rk3328-nanopi-r2s.dtb" ++CONFIG_MISC_INIT_R=y ++# CONFIG_DISPLAY_CPUINFO is not set ++CONFIG_DISPLAY_BOARDINFO_LATE=y ++# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set ++CONFIG_TPL_SYS_MALLOC_SIMPLE=y ++CONFIG_SPL_STACK_R=y ++CONFIG_SPL_I2C_SUPPORT=y ++CONFIG_SPL_POWER_SUPPORT=y ++CONFIG_SPL_ATF=y ++CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y ++CONFIG_CMD_BOOTZ=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_USB=y ++# CONFIG_CMD_SETEXPR is not set ++CONFIG_CMD_TIME=y ++CONFIG_SPL_OF_CONTROL=y ++CONFIG_TPL_OF_CONTROL=y ++CONFIG_DEFAULT_DEVICE_TREE="rk3328-nanopi-r2s" ++CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" ++CONFIG_TPL_OF_PLATDATA=y ++CONFIG_ENV_IS_IN_MMC=y ++CONFIG_SYS_RELOC_GD_ENV_ADDR=y ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_TPL_DM=y ++CONFIG_REGMAP=y ++CONFIG_SPL_REGMAP=y ++CONFIG_TPL_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_SPL_SYSCON=y ++CONFIG_TPL_SYSCON=y ++CONFIG_CLK=y ++CONFIG_SPL_CLK=y ++CONFIG_FASTBOOT_BUF_ADDR=0x800800 ++CONFIG_FASTBOOT_CMD_OEM_FORMAT=y ++CONFIG_ROCKCHIP_GPIO=y ++CONFIG_SYS_I2C_ROCKCHIP=y ++CONFIG_MMC_DW=y ++CONFIG_MMC_DW_ROCKCHIP=y ++CONFIG_SF_DEFAULT_SPEED=20000000 ++CONFIG_DM_ETH=y ++CONFIG_ETH_DESIGNWARE=y ++CONFIG_GMAC_ROCKCHIP=y ++CONFIG_PHY=y ++CONFIG_PINCTRL=y ++CONFIG_SPL_PINCTRL=y ++CONFIG_DM_PMIC=y ++CONFIG_PMIC_RK8XX=y ++CONFIG_SPL_DM_REGULATOR=y ++CONFIG_REGULATOR_PWM=y ++CONFIG_SPL_DM_REGULATOR_FIXED=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_REGULATOR_RK8XX=y ++CONFIG_PWM_ROCKCHIP=y ++CONFIG_RAM=y ++CONFIG_SPL_RAM=y ++CONFIG_TPL_RAM=y ++CONFIG_DM_RESET=y ++CONFIG_BAUDRATE=1500000 ++CONFIG_DEBUG_UART_SHIFT=2 ++CONFIG_SYSRESET=y ++# CONFIG_TPL_SYSRESET is not set ++CONFIG_USB=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_DWC3=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_GENERIC=y ++CONFIG_USB_OHCI_HCD=y ++CONFIG_USB_OHCI_GENERIC=y ++CONFIG_USB_DWC2=y ++CONFIG_USB_DWC3=y ++# CONFIG_USB_DWC3_GADGET is not set ++CONFIG_USB_GADGET=y ++CONFIG_USB_GADGET_DWC2_OTG=y ++CONFIG_SPL_TINY_MEMSET=y ++CONFIG_TPL_TINY_MEMSET=y ++CONFIG_ERRNO_STR=y ++CONFIG_SMBIOS_MANUFACTURER="friendlyarm" diff --git a/package/boot/uboot-rockchip/patches/007-sdmmc-fifo-mode-in-spl.patch b/package/boot/uboot-rockchip/patches/007-sdmmc-fifo-mode-in-spl.patch new file mode 100644 index 000000000..9b7354f97 --- /dev/null +++ b/package/boot/uboot-rockchip/patches/007-sdmmc-fifo-mode-in-spl.patch @@ -0,0 +1,22 @@ +From b0693aeb9ceab57ffc9d9f4ceca610bd82d5ca07 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Kamil=20Trzci=C5=84ski?= +Date: Mon, 21 May 2018 02:00:19 +0200 +Subject: [PATCH] ayufan: rock64: for SPL build always use fifo-mode + +Change-Id: I9ac012ce4aaf03a151f7c5c818829d631efdd7ed +diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c +index fc0f0fad76..d1f26e41fe 100644 +--- a/drivers/mmc/rockchip_dw_mmc.c ++++ b/drivers/mmc/rockchip_dw_mmc.c +@@ -70,7 +70,11 @@ static int rockchip_dwmmc_ofdata_to_platdata(struct udevice *dev) + + if (priv->fifo_depth < 0) + return -EINVAL; ++#ifdef CONFIG_SPL_BUILD ++ priv->fifo_mode = true; // always force fifo mode ++#else + priv->fifo_mode = dev_read_bool(dev, "fifo-mode"); ++#endif + + /* + * 'clock-freq-min-max' is deprecated diff --git a/package/boot/uboot-rockchip/patches/008-set-sdmmc-priority.patch b/package/boot/uboot-rockchip/patches/008-set-sdmmc-priority.patch new file mode 100644 index 000000000..b71d4a211 --- /dev/null +++ b/package/boot/uboot-rockchip/patches/008-set-sdmmc-priority.patch @@ -0,0 +1,15 @@ +diff --git a/include/configs/rockchip-common.h b/include/configs/rockchip-common.h +index 68e1105a..906c22ed 100644 +--- a/include/configs/rockchip-common.h ++++ b/include/configs/rockchip-common.h +@@ -14,8 +14,8 @@ + /* First try to boot from SD (index 0), then eMMC (index 1) */ + #if CONFIG_IS_ENABLED(CMD_MMC) + #define BOOT_TARGET_MMC(func) \ +- func(MMC, mmc, 0) \ +- func(MMC, mmc, 1) ++ func(MMC, mmc, 1) \ ++ func(MMC, mmc, 0) + #else + #define BOOT_TARGET_MMC(func) + #endif diff --git a/package/boot/uboot-rockchip/patches/009-add-set-eth1-addr.patch b/package/boot/uboot-rockchip/patches/009-add-set-eth1-addr.patch new file mode 100644 index 000000000..422cbc3f9 --- /dev/null +++ b/package/boot/uboot-rockchip/patches/009-add-set-eth1-addr.patch @@ -0,0 +1,16 @@ +diff --git a/arch/arm/mach-rockchip/misc.c b/arch/arm/mach-rockchip/misc.c +index 6dbb9bde..89f3a918 100644 +--- a/arch/arm/mach-rockchip/misc.c ++++ b/arch/arm/mach-rockchip/misc.c +@@ -50,6 +50,11 @@ int rockchip_setup_macaddr(void) + mac_addr[0] &= 0xfe; /* clear multicast bit */ + mac_addr[0] |= 0x02; /* set local assignment bit (IEEE802) */ + eth_env_set_enetaddr("ethaddr", mac_addr); ++ ++ /* Make a valid MAC address for eth1 too */ ++ mac_addr[5] += 0x20; ++ mac_addr[5] &= 0xff; ++ eth_env_set_enetaddr("eth1addr", mac_addr); + #endif + return 0; + } diff --git a/target/linux/rockchip/armv8/base-files/etc/board.d/01_leds b/target/linux/rockchip/armv8/base-files/etc/board.d/01_leds new file mode 100755 index 000000000..2b75aab53 --- /dev/null +++ b/target/linux/rockchip/armv8/base-files/etc/board.d/01_leds @@ -0,0 +1,18 @@ +#!/bin/sh +# +# Copyright © 2017 OpenWrt.org +# + +. /lib/functions/uci-defaults.sh + +board_config_update + +case "$(board_name)" in +friendlyarm,nanopi-r2s) + ucidef_set_led_netdev "wan" "WAN" "nanopi:green:wan" "eth0" + ucidef_set_led_netdev "lan" "LAN" "nanopi:green:lan" "eth1" + ;; +esac +board_config_flush + +exit 0 diff --git a/target/linux/rockchip/armv8/base-files/etc/board.d/02_network b/target/linux/rockchip/armv8/base-files/etc/board.d/02_network index c5adda170..eac8233b9 100755 --- a/target/linux/rockchip/armv8/base-files/etc/board.d/02_network +++ b/target/linux/rockchip/armv8/base-files/etc/board.d/02_network @@ -5,6 +5,12 @@ board_config_update case "$(board_name)" in +friendlyarm,nanopi-r2s) + ucidef_set_interfaces_lan_wan "eth0" "eth1" + ;; +radxa,rock-pi-e) + ucidef_set_interfaces_lan_wan "eth1" "eth0" + ;; *) ucidef_set_interface_lan 'eth0' ;; diff --git a/target/linux/rockchip/armv8/base-files/etc/inittab b/target/linux/rockchip/armv8/base-files/etc/inittab new file mode 100644 index 000000000..df4782712 --- /dev/null +++ b/target/linux/rockchip/armv8/base-files/etc/inittab @@ -0,0 +1,6 @@ +::sysinit:/etc/init.d/rcS S boot +::shutdown:/etc/init.d/rcS K shutdown +::askconsole:/usr/libexec/login.sh +tts/0::askfirst:/usr/libexec/login.sh +ttyS0::askfirst:/usr/libexec/login.sh +tty1::askfirst:/usr/libexec/login.sh diff --git a/target/linux/rockchip/armv8/config-5.4 b/target/linux/rockchip/armv8/config-5.4 index 48b05b432..0e4090bfc 100644 --- a/target/linux/rockchip/armv8/config-5.4 +++ b/target/linux/rockchip/armv8/config-5.4 @@ -9,6 +9,7 @@ CONFIG_ARCH_ROCKCHIP=y CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y CONFIG_ARC_EMAC_CORE=y CONFIG_ARM64_CNP=y +CONFIG_ARM64_CRYPTO=y # CONFIG_ARM64_ERRATUM_1165522 is not set # CONFIG_ARM64_ERRATUM_1286807 is not set # CONFIG_ARM64_ERRATUM_1418040 is not set @@ -38,7 +39,9 @@ CONFIG_ARM_CPUIDLE=y CONFIG_ARM_GIC_V2M=y CONFIG_ARM_GIC_V3_ITS_PCI=y CONFIG_ARM_MHU=y +CONFIG_ARM_PMU=y CONFIG_ARM_PSCI_CPUIDLE=y +CONFIG_ARM_RK3328_DMC_DEVFREQ=y # CONFIG_ARM_RK3399_DMC_DEVFREQ is not set # CONFIG_ARM_SCMI_PROTOCOL is not set CONFIG_ARM_SCPI_CPUFREQ=y @@ -50,6 +53,7 @@ CONFIG_ARM_SMMU_V3=y CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_BACKLIGHT_GPIO=y CONFIG_BACKLIGHT_PWM=y +# CONFIG_BLK_CGROUP is not set CONFIG_BLK_DEV_BSG=y CONFIG_BLK_DEV_BSGLIB=y # CONFIG_BLK_DEV_INITRD is not set @@ -66,6 +70,15 @@ CONFIG_BRCMSTB_GISB_ARB=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y # CONFIG_CAVIUM_TX2_ERRATUM_219 is not set +CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y +# CONFIG_CFS_BANDWIDTH is not set +CONFIG_CGROUPS=y +# CONFIG_CGROUP_CPUACCT is not set +# CONFIG_CGROUP_DEVICE is not set +# CONFIG_CGROUP_FREEZER is not set +# CONFIG_CGROUP_PERF is not set +# CONFIG_CGROUP_PIDS is not set +CONFIG_CGROUP_SCHED=y CONFIG_CHARGER_GPIO=y CONFIG_CLKSRC_MMIO=y CONFIG_CMA=y @@ -73,7 +86,7 @@ CONFIG_CMA_ALIGNMENT=8 CONFIG_CMA_AREAS=7 # CONFIG_CMA_DEBUG is not set # CONFIG_CMA_DEBUGFS is not set -CONFIG_CMA_SIZE_MBYTES=5 +CONFIG_CMA_SIZE_MBYTES=16 # CONFIG_CMA_SIZE_SEL_MAX is not set CONFIG_CMA_SIZE_SEL_MBYTES=y # CONFIG_CMA_SIZE_SEL_MIN is not set @@ -90,6 +103,7 @@ CONFIG_CONSOLE_TRANSLATIONS=y CONFIG_CONTIG_ALLOC=y CONFIG_CPUFREQ_DT=y CONFIG_CPUFREQ_DT_PLATDEV=y +# CONFIG_CPUSETS is not set CONFIG_CPU_FREQ=y # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y @@ -115,15 +129,79 @@ CONFIG_CRC16=y CONFIG_CRC32_SLICEBY8=y CONFIG_CRC_T10DIF=y CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_CRYPTO_ACOMP2=y +CONFIG_CRYPTO_AES_ARM64=y +CONFIG_CRYPTO_AES_ARM64_BS=y +CONFIG_CRYPTO_AES_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y +CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CHACHA20=y +CONFIG_CRYPTO_CHACHA20POLY1305=y +CONFIG_CRYPTO_CHACHA20_NEON=y +CONFIG_CRYPTO_CMAC=y CONFIG_CRYPTO_CRC32C=y CONFIG_CRYPTO_CRCT10DIF=y +CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=y +CONFIG_CRYPTO_CRYPTD=y +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_DEV_ROCKCHIP=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_GCM=y +CONFIG_CRYPTO_GF128MUL=y +CONFIG_CRYPTO_GHASH=y +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_LIB_DES=y +CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_LZ4=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_NHPOLY1305=y +CONFIG_CRYPTO_NHPOLY1305_NEON=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_POLY1305=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_SEQIV=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA256_ARM64=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +CONFIG_CRYPTO_SHA3=y +CONFIG_CRYPTO_SHA3_ARM64=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_SHA512_ARM64=y +CONFIG_CRYPTO_SHA512_ARM64_CE=y +CONFIG_CRYPTO_SIMD=y +CONFIG_CRYPTO_SM3=y +CONFIG_CRYPTO_SM3_ARM64_CE=y +CONFIG_CRYPTO_SM4=y +CONFIG_CRYPTO_SM4_ARM64_CE=y +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_TWOFISH_COMMON=y +CONFIG_CRYPTO_USER_API=y +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_USER_API_RNG=y +CONFIG_CRYPTO_USER_API_SKCIPHER=y +CONFIG_CRYPTO_ZSTD=y CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI=y # CONFIG_DEVFREQ_GOV_PASSIVE is not set CONFIG_DEVFREQ_GOV_PERFORMANCE=y CONFIG_DEVFREQ_GOV_POWERSAVE=y CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y CONFIG_DEVFREQ_GOV_USERSPACE=y -# CONFIG_DEVFREQ_THERMAL is not set +CONFIG_DEVFREQ_THERMAL=y CONFIG_DEVMEM=y # CONFIG_DEVPORT is not set CONFIG_DEVTMPFS=y @@ -134,6 +212,11 @@ CONFIG_DMA_ENGINE=y CONFIG_DMA_OF=y CONFIG_DMA_SHARED_BUFFER=y CONFIG_DNOTIFY=y +# CONFIG_DP83640_PHY is not set +CONFIG_DRM=y +CONFIG_DRM_BRIDGE=y +CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y +# CONFIG_DRM_ROCKCHIP is not set CONFIG_DT_IDLE_STATES=y CONFIG_DUMMY_CONSOLE=y CONFIG_DWMAC_DWC_QOS_ETH=y @@ -145,7 +228,10 @@ CONFIG_ENERGY_MODEL=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXTCON=y +CONFIG_FAIR_GROUP_SCHED=y CONFIG_FANOTIFY=y +CONFIG_FB=y +CONFIG_FB_CMDLINE=y CONFIG_FHANDLE=y CONFIG_FIXED_PHY=y # CONFIG_FLATMEM_MANUAL is not set @@ -163,13 +249,26 @@ CONFIG_GPIOLIB=y CONFIG_GPIO_DWAPB=y CONFIG_GPIO_GENERIC=y CONFIG_GPIO_GENERIC_PLATFORM=y +CONFIG_GPIO_SYSCON=y +CONFIG_GPIO_SYSFS=y # CONFIG_HARDENED_USERCOPY is not set CONFIG_HAS_IOPORT_MAP=y CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_KVM_ARCH_TLB_FLUSH_ALL=y +CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=y +CONFIG_HAVE_KVM_EVENTFD=y +CONFIG_HAVE_KVM_IRQCHIP=y +CONFIG_HAVE_KVM_IRQFD=y +CONFIG_HAVE_KVM_IRQ_BYPASS=y +CONFIG_HAVE_KVM_IRQ_ROUTING=y +CONFIG_HAVE_KVM_MSI=y +CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE=y CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_HAVE_MOD_ARCH_SPECIFIC=y CONFIG_HAVE_SCHED_AVG_IRQ=y CONFIG_HAVE_UID16=y +CONFIG_HDMI=y CONFIG_HID=y CONFIG_HID_GENERIC=y CONFIG_HOTPLUG_CPU=y @@ -188,9 +287,18 @@ CONFIG_I2C_ALGOBIT=y CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_COMPAT=y +CONFIG_I2C_DESIGNWARE_CORE=y +CONFIG_I2C_DESIGNWARE_PLATFORM=y +# CONFIG_I2C_DESIGNWARE_SLAVE is not set CONFIG_I2C_GPIO=y CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_MUX=y +CONFIG_I2C_MUX_PCA954x=y CONFIG_I2C_RK3X=y +CONFIG_I2C_SLAVE=y +# CONFIG_I2C_SLAVE_EEPROM is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y CONFIG_INDIRECT_PIO=y CONFIG_INPUT=y CONFIG_INPUT_EVDEV=y @@ -198,7 +306,7 @@ CONFIG_INPUT_FF_MEMLESS=y CONFIG_INPUT_KEYBOARD=y CONFIG_INPUT_LEDS=y CONFIG_INPUT_MATRIXKMAP=y -# CONFIG_INPUT_MISC is not set +CONFIG_INPUT_RK805_PWRKEY=y CONFIG_IOMMU_API=y # CONFIG_IOMMU_DEBUGFS is not set # CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set @@ -212,6 +320,8 @@ CONFIG_IOMMU_SUPPORT=y # CONFIG_IONIC is not set # CONFIG_IO_STRICT_DEVMEM is not set CONFIG_IO_URING=y +# CONFIG_IPMB_DEVICE_INTERFACE is not set +CONFIG_IRQ_BYPASS_MANAGER=y CONFIG_IRQ_MSI_IOMMU=y CONFIG_IRQ_TIME_ACCOUNTING=y CONFIG_JBD2=y @@ -223,11 +333,19 @@ CONFIG_KEXEC_FILE=y # CONFIG_KEXEC_SIG is not set CONFIG_KEYBOARD_GPIO=y CONFIG_KSM=y +CONFIG_KVM=y +CONFIG_KVM_ARM_HOST=y +CONFIG_KVM_ARM_PMU=y +CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT=y +CONFIG_KVM_INDIRECT_VECTORS=y +CONFIG_KVM_MMIO=y +CONFIG_KVM_VFIO=y # CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set CONFIG_LEDS_GPIO=y CONFIG_LEDS_PWM=y CONFIG_LEDS_SYSCON=y CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_GPIO=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_PANIC=y # CONFIG_LEDS_TRIGGER_TIMER is not set @@ -236,6 +354,10 @@ CONFIG_LEGACY_PTY_COUNT=16 CONFIG_LIBCRC32C=y CONFIG_LOCALVERSION_AUTO=y CONFIG_LOG_BUF_SHIFT=19 +CONFIG_LZ4_COMPRESS=y +CONFIG_LZ4_DECOMPRESS=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y CONFIG_MAGIC_SYSRQ=y CONFIG_MAGIC_SYSRQ_SERIAL=y CONFIG_MAILBOX=y @@ -248,6 +370,8 @@ CONFIG_MDIO_BUS_MUX_GPIO=y CONFIG_MDIO_BUS_MUX_MMIOREG=y CONFIG_MDIO_DEVICE=y CONFIG_MDIO_GPIO=y +CONFIG_MEDIA_SUPPORT=y +# CONFIG_MEMCG is not set CONFIG_MEMORY_ISOLATION=y CONFIG_MFD_CORE=y CONFIG_MFD_RK808=y @@ -270,6 +394,8 @@ CONFIG_MMC_SDHCI_OF_DWCMSHC=y # CONFIG_MMC_SDHCI_PCI is not set CONFIG_MMC_SDHCI_PLTFM=y # CONFIG_MMC_TIFM_SD is not set +CONFIG_MMU_NOTIFIER=y +CONFIG_MODULES_TREE_LOOKUP=y CONFIG_MQ_IOSCHED_DEADLINE=y # CONFIG_MTD_CFI is not set CONFIG_MTD_CMDLINE_PARTS=y @@ -277,6 +403,9 @@ CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_SPI_NOR=y CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y CONFIG_MTD_SPLIT_FIRMWARE=y +CONFIG_NETWORK_PHY_TIMESTAMPING=y +# CONFIG_NET_CLS_CGROUP is not set +CONFIG_NET_PTP_CLASSIFY=y CONFIG_NLS_ISO8859_1=y CONFIG_NOP_USB_XCEIV=y CONFIG_NO_HZ_COMMON=y @@ -318,41 +447,49 @@ CONFIG_PCI_DOMAINS_GENERIC=y CONFIG_PCI_MSI=y CONFIG_PCI_MSI_IRQ_DOMAIN=y CONFIG_PCI_STUB=y +CONFIG_PERF_EVENTS=y CONFIG_PGTABLE_LEVELS=4 CONFIG_PHYLIB=y CONFIG_PHYLINK=y -CONFIG_PHY_ROCKCHIP_DP=y +# CONFIG_PHY_ROCKCHIP_DP is not set CONFIG_PHY_ROCKCHIP_EMMC=y # CONFIG_PHY_ROCKCHIP_INNO_HDMI is not set CONFIG_PHY_ROCKCHIP_INNO_USB2=y +CONFIG_PHY_ROCKCHIP_INNO_USB3=y CONFIG_PHY_ROCKCHIP_PCIE=y CONFIG_PHY_ROCKCHIP_TYPEC=y CONFIG_PHY_ROCKCHIP_USB=y CONFIG_PINCTRL=y -# CONFIG_PINCTRL_RK805 is not set +CONFIG_PINCTRL_RK805=y CONFIG_PINCTRL_ROCKCHIP=y # CONFIG_PINCTRL_SINGLE is not set CONFIG_PL330_DMA=y CONFIG_PLATFORM_MHU=y +CONFIG_PLUGIN_HOSTCC="" CONFIG_PM=y CONFIG_PM_CLK=y CONFIG_PM_DEVFREQ=y -# CONFIG_PM_DEVFREQ_EVENT is not set +CONFIG_PM_DEVFREQ_EVENT=y CONFIG_PM_GENERIC_DOMAINS=y CONFIG_PM_GENERIC_DOMAINS_OF=y CONFIG_PM_OPP=y CONFIG_POWER_AVS=y CONFIG_POWER_SUPPLY_HWMON=y +CONFIG_PPS=y +CONFIG_PPS_CLIENT_GPIO=y +CONFIG_PPS_CLIENT_KTIMER=y CONFIG_PREEMPT=y CONFIG_PREEMPTION=y CONFIG_PREEMPT_COUNT=y # CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_NOTIFIERS=y CONFIG_PREEMPT_RCU=y CONFIG_PRINTK_TIME=y # CONFIG_PRINT_QUOTA_WARNING is not set CONFIG_PROC_PAGE_MONITOR=y # CONFIG_PROC_STRIPPED is not set CONFIG_PROC_VMCORE=y +CONFIG_PTP_1588_CLOCK=y CONFIG_PWM=y CONFIG_PWM_ROCKCHIP=y CONFIG_PWM_SYSFS=y @@ -370,6 +507,7 @@ CONFIG_RCU_CPU_STALL_TIMEOUT=21 # CONFIG_RCU_EXPERT is not set CONFIG_RCU_TRACE=y # CONFIG_READ_ONLY_THP_FOR_FS is not set +CONFIG_REALTEK_PHY=y CONFIG_REGMAP=y CONFIG_REGMAP_I2C=y CONFIG_REGMAP_IRQ=y @@ -377,6 +515,7 @@ CONFIG_REGMAP_MMIO=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FAN53555=y CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_GPIO=y CONFIG_REGULATOR_PWM=y CONFIG_REGULATOR_RK808=y CONFIG_RELOCATABLE=y @@ -388,15 +527,18 @@ CONFIG_ROCKCHIP_IOMMU=y CONFIG_ROCKCHIP_MBOX=y CONFIG_ROCKCHIP_PHY=y CONFIG_ROCKCHIP_PM_DOMAINS=y -# CONFIG_ROCKCHIP_THERMAL is not set +CONFIG_ROCKCHIP_THERMAL=y CONFIG_ROCKCHIP_TIMER=y CONFIG_RSEQ=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_RK808=y CONFIG_RTC_I2C_AND_SPI=y CONFIG_RTC_NVMEM=y +# CONFIG_RT_GROUP_SCHED is not set # CONFIG_RUNTIME_TESTING_MENU is not set +CONFIG_SCHED_AUTOGROUP=y CONFIG_SCHED_MC=y +CONFIG_SCHED_SMT=y CONFIG_SCSI=y # CONFIG_SCSI_LOWLEVEL is not set # CONFIG_SCSI_PROC_FS is not set @@ -423,6 +565,7 @@ CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIO=y CONFIG_SERIO_AMBAKMI=y CONFIG_SERIO_LIBPS2=y +CONFIG_SGL_ALLOC=y CONFIG_SG_POOL=y CONFIG_SIMPLE_PM_BUS=y CONFIG_SLUB_DEBUG=y @@ -443,6 +586,7 @@ CONFIG_SQUASHFS_FILE_CACHE=y # CONFIG_SQUASHFS_FILE_DIRECT is not set CONFIG_SRAM=y CONFIG_STACKPROTECTOR=y +CONFIG_STACKPROTECTOR_PER_TASK=y CONFIG_STACKPROTECTOR_STRONG=y # CONFIG_STAGING is not set CONFIG_STMMAC_ETH=y @@ -483,6 +627,8 @@ CONFIG_TYPEC_TCPM=y CONFIG_UNINLINE_SPIN_UNLOCK=y CONFIG_USB=y CONFIG_USB_COMMON=y +CONFIG_USB_DWC2=y +CONFIG_USB_DWC2_HOST=y CONFIG_USB_DWC3=y CONFIG_USB_DWC3_HOST=y CONFIG_USB_DWC3_OF_SIMPLE=y @@ -504,6 +650,7 @@ CONFIG_USB_XHCI_PLATFORM=y # CONFIG_USERIO is not set # CONFIG_VFIO is not set # CONFIG_VIRTIO_MENU is not set +CONFIG_VIRTUALIZATION=y CONFIG_VM_EVENT_COUNTERS=y CONFIG_VT=y CONFIG_VT_CONSOLE=y @@ -516,3 +663,5 @@ CONFIG_XZ_DEC_ARMTHUMB=y CONFIG_XZ_DEC_BCJ=y CONFIG_ZLIB_DEFLATE=y CONFIG_ZLIB_INFLATE=y +CONFIG_ZSTD_COMPRESS=y +CONFIG_ZSTD_DECOMPRESS=y diff --git a/target/linux/rockchip/image/Makefile b/target/linux/rockchip/image/Makefile index 22854d9d0..143f3ab82 100644 --- a/target/linux/rockchip/image/Makefile +++ b/target/linux/rockchip/image/Makefile @@ -24,10 +24,10 @@ endef define Build/boot-script # Make an U-boot image and copy it to the boot partition - mkimage -A arm -O linux -T script -C none -a 0 -e 0 -d mmc.bootscript $@.boot/boot.scr + mkimage -A arm -O linux -T script -C lzma -a 0 -e 0 -d mmc.bootscript $@.boot/boot.scr endef -define Build/pine64-img +define Build/sdcard-img # Creates the final SD/eMMC images, # combining boot partition, root partition as well as the u-boot bootloader @@ -50,7 +50,7 @@ endef ### Devices ### define Device/Default PROFILES := Default - KERNEL := kernel-bin + KERNEL := kernel-bin | lzma IMAGES := sysupgrade.img.gz SUPPORTED_DEVICES := $(subst _,$(comma),$(1)) DEVICE_DTS = rockchip/$$(SOC)-$(lastword $(subst _, ,$(1))) diff --git a/target/linux/rockchip/image/armv8.mk b/target/linux/rockchip/image/armv8.mk index 737c6e4f9..5c6381b41 100644 --- a/target/linux/rockchip/image/armv8.mk +++ b/target/linux/rockchip/image/armv8.mk @@ -4,11 +4,31 @@ # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. # +define Device/friendlyarm_nanopi-r2s + DEVICE_VENDOR := FriendlyARM + DEVICE_MODEL := NanoPi R2S + SOC := rk3328 + UBOOT_DEVICE_NAME := nanopi-r2s-rk3328 + IMAGE/sysupgrade.img.gz := boot-common | boot-script | sdcard-img | gzip | append-metadata + DEVICE_PACKAGES += kmod-phy-realtek kmod-usb-net kmod-usb-net-rtl8152 kmod-macvlan +endef +TARGET_DEVICES += friendlyarm_nanopi-r2s + +define Device/radxa_rock-pi-e + DEVICE_VENDOR := Radxa + DEVICE_MODEL := Rock Pi E + SOC := rk3328 + UBOOT_DEVICE_NAME := rock-pi-e-rk3328 + IMAGE/sysupgrade.img.gz := boot-common | boot-script | sdcard-img | gzip | append-metadata + DEVICE_PACKAGES += kmod-phy-realtek +endef +TARGET_DEVICES += radxa_rock-pi-e + define Device/pine64_rockpro64 DEVICE_VENDOR := Pine64 DEVICE_MODEL := RockPro64 SOC := rk3399 UBOOT_DEVICE_NAME := rockpro64-rk3399 - IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata + IMAGE/sysupgrade.img.gz := boot-common | boot-script | sdcard-img | gzip | append-metadata endef TARGET_DEVICES += pine64_rockpro64 diff --git a/target/linux/rockchip/image/mmc.bootscript b/target/linux/rockchip/image/mmc.bootscript index b70a62c4c..13a55d3ac 100644 --- a/target/linux/rockchip/image/mmc.bootscript +++ b/target/linux/rockchip/image/mmc.bootscript @@ -1,8 +1,18 @@ part uuid mmc ${devnum}:2 uuid -setenv bootargs "console=ttyS2,1500000 console=tty1 earlycon=uart8250,mmio32,0xff1a0000 root=PARTUUID=${uuid} rw rootwait" +if test $stdout = 'serial@ff1a0000' ; +then serial_addr=',0xff1a0000'; +elif test $stdout = 'serial@ff130000' ; +then serial_addr=',0xff130000'; +fi; + +setenv bootargs "console=ttyS2,1500000 console=tty1 earlycon=uart8250,mmio32${serial_addr} swiotlb=1 root=PARTUUID=${uuid} rw rootwait loglevel=9"; load mmc ${devnum}:1 ${fdt_addr_r} rockchip.dtb load mmc ${devnum}:1 ${kernel_addr_r} kernel.img -booti ${kernel_addr_r} - ${fdt_addr_r} +echo "Uncompress lzma kernel into memmory.." +setexpr kernel_addr_dec ${filesize} + ${kernel_addr_r} || kernel_addr_dec=0x03000000 +lzmadec ${kernel_addr_r} ${kernel_addr_dec} + +booti ${kernel_addr_dec} - ${fdt_addr_r} diff --git a/target/linux/rockchip/patches-5.4/001-add-rk3328-dmc-driver.patch b/target/linux/rockchip/patches-5.4/001-add-rk3328-dmc-driver.patch new file mode 100644 index 000000000..761429289 --- /dev/null +++ b/target/linux/rockchip/patches-5.4/001-add-rk3328-dmc-driver.patch @@ -0,0 +1,1796 @@ +From fcd9629c05f373771e85920e1c1d0ab252617878 Mon Sep 17 00:00:00 2001 +From: hmz007 +Date: Tue, 19 Nov 2019 13:53:25 +0800 +Subject: [PATCH] PM / devfreq: rockchip: add devfreq driver for rk3328 dmc + +Signed-off-by: hmz007 +--- + drivers/devfreq/Kconfig | 18 +- + drivers/devfreq/Makefile | 1 + + drivers/devfreq/rk3328_dmc.c | 846 +++++++++++++++++++++++++++++++++++ + 3 files changed, 862 insertions(+), 3 deletions(-) + create mode 100644 drivers/devfreq/rk3328_dmc.c + +diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig +index defe1d438710..5ae0832f046b 100644 +--- a/drivers/devfreq/Kconfig ++++ b/drivers/devfreq/Kconfig +@@ -115,6 +115,18 @@ config ARM_TEGRA20_DEVFREQ + It reads Memory Controller counters and adjusts the operating + frequencies and voltages with OPP support. + ++config ARM_RK3328_DMC_DEVFREQ ++ tristate "ARM RK3328 DMC DEVFREQ Driver" ++ depends on ARCH_ROCKCHIP ++ select DEVFREQ_EVENT_ROCKCHIP_DFI ++ select DEVFREQ_GOV_SIMPLE_ONDEMAND ++ select PM_DEVFREQ_EVENT ++ select PM_OPP ++ help ++ This adds the DEVFREQ driver for the RK3328 DMC(Dynamic Memory Controller). ++ It sets the frequency for the memory controller and reads the usage counts ++ from hardware. ++ + config ARM_RK3399_DMC_DEVFREQ + tristate "ARM RK3399 DMC DEVFREQ Driver" + depends on ARCH_ROCKCHIP +@@ -123,9 +135,9 @@ config ARM_RK3399_DMC_DEVFREQ + select PM_DEVFREQ_EVENT + select PM_OPP + help +- This adds the DEVFREQ driver for the RK3399 DMC(Dynamic Memory Controller). +- It sets the frequency for the memory controller and reads the usage counts +- from hardware. ++ This adds the DEVFREQ driver for the RK3399 DMC(Dynamic Memory Controller). ++ It sets the frequency for the memory controller and reads the usage counts ++ from hardware. + + source "drivers/devfreq/event/Kconfig" + +diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile +index 338ae8440db6..ec568406ef50 100644 +--- a/drivers/devfreq/Makefile ++++ b/drivers/devfreq/Makefile +@@ -10,6 +10,7 @@ obj-$(CONFIG_DEVFREQ_GOV_PASSIVE) += governor_passive.o + # DEVFREQ Drivers + obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ) += exynos-bus.o + obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ) += rk3399_dmc.o ++obj-$(CONFIG_ARM_RK3328_DMC_DEVFREQ) += rk3328_dmc.o + obj-$(CONFIG_ARM_TEGRA_DEVFREQ) += tegra30-devfreq.o + obj-$(CONFIG_ARM_TEGRA20_DEVFREQ) += tegra20-devfreq.o + +diff --git a/drivers/devfreq/rk3328_dmc.c b/drivers/devfreq/rk3328_dmc.c +new file mode 100644 +index 000000000000..9e3c87019ada +--- /dev/null ++++ b/drivers/devfreq/rk3328_dmc.c +@@ -0,0 +1,846 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd. ++ * Author: Lin Huang ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define DTS_PAR_OFFSET (4096) ++ ++struct share_params { ++ u32 hz; ++ u32 lcdc_type; ++ u32 vop; ++ u32 vop_dclk_mode; ++ u32 sr_idle_en; ++ u32 addr_mcu_el3; ++ /* ++ * 1: need to wait flag1 ++ * 0: never wait flag1 ++ */ ++ u32 wait_flag1; ++ /* ++ * 1: need to wait flag1 ++ * 0: never wait flag1 ++ */ ++ u32 wait_flag0; ++ u32 complt_hwirq; ++ /* if need, add parameter after */ ++}; ++ ++static struct share_params *ddr_psci_param; ++ ++/* hope this define can adapt all future platform */ ++static const char * const rk3328_dts_timing[] = { ++ "ddr3_speed_bin", ++ "ddr4_speed_bin", ++ "pd_idle", ++ "sr_idle", ++ "sr_mc_gate_idle", ++ "srpd_lite_idle", ++ "standby_idle", ++ ++ "auto_pd_dis_freq", ++ "auto_sr_dis_freq", ++ "ddr3_dll_dis_freq", ++ "ddr4_dll_dis_freq", ++ "phy_dll_dis_freq", ++ ++ "ddr3_odt_dis_freq", ++ "phy_ddr3_odt_dis_freq", ++ "ddr3_drv", ++ "ddr3_odt", ++ "phy_ddr3_ca_drv", ++ "phy_ddr3_ck_drv", ++ "phy_ddr3_dq_drv", ++ "phy_ddr3_odt", ++ ++ "lpddr3_odt_dis_freq", ++ "phy_lpddr3_odt_dis_freq", ++ "lpddr3_drv", ++ "lpddr3_odt", ++ "phy_lpddr3_ca_drv", ++ "phy_lpddr3_ck_drv", ++ "phy_lpddr3_dq_drv", ++ "phy_lpddr3_odt", ++ ++ "lpddr4_odt_dis_freq", ++ "phy_lpddr4_odt_dis_freq", ++ "lpddr4_drv", ++ "lpddr4_dq_odt", ++ "lpddr4_ca_odt", ++ "phy_lpddr4_ca_drv", ++ "phy_lpddr4_ck_cs_drv", ++ "phy_lpddr4_dq_drv", ++ "phy_lpddr4_odt", ++ ++ "ddr4_odt_dis_freq", ++ "phy_ddr4_odt_dis_freq", ++ "ddr4_drv", ++ "ddr4_odt", ++ "phy_ddr4_ca_drv", ++ "phy_ddr4_ck_drv", ++ "phy_ddr4_dq_drv", ++ "phy_ddr4_odt", ++}; ++ ++static const char * const rk3328_dts_ca_timing[] = { ++ "ddr3a1_ddr4a9_de-skew", ++ "ddr3a0_ddr4a10_de-skew", ++ "ddr3a3_ddr4a6_de-skew", ++ "ddr3a2_ddr4a4_de-skew", ++ "ddr3a5_ddr4a8_de-skew", ++ "ddr3a4_ddr4a5_de-skew", ++ "ddr3a7_ddr4a11_de-skew", ++ "ddr3a6_ddr4a7_de-skew", ++ "ddr3a9_ddr4a0_de-skew", ++ "ddr3a8_ddr4a13_de-skew", ++ "ddr3a11_ddr4a3_de-skew", ++ "ddr3a10_ddr4cs0_de-skew", ++ "ddr3a13_ddr4a2_de-skew", ++ "ddr3a12_ddr4ba1_de-skew", ++ "ddr3a15_ddr4odt0_de-skew", ++ "ddr3a14_ddr4a1_de-skew", ++ "ddr3ba1_ddr4a15_de-skew", ++ "ddr3ba0_ddr4bg0_de-skew", ++ "ddr3ras_ddr4cke_de-skew", ++ "ddr3ba2_ddr4ba0_de-skew", ++ "ddr3we_ddr4bg1_de-skew", ++ "ddr3cas_ddr4a12_de-skew", ++ "ddr3ckn_ddr4ckn_de-skew", ++ "ddr3ckp_ddr4ckp_de-skew", ++ "ddr3cke_ddr4a16_de-skew", ++ "ddr3odt0_ddr4a14_de-skew", ++ "ddr3cs0_ddr4act_de-skew", ++ "ddr3reset_ddr4reset_de-skew", ++ "ddr3cs1_ddr4cs1_de-skew", ++ "ddr3odt1_ddr4odt1_de-skew", ++}; ++ ++static const char * const rk3328_dts_cs0_timing[] = { ++ "cs0_dm0_rx_de-skew", ++ "cs0_dm0_tx_de-skew", ++ "cs0_dq0_rx_de-skew", ++ "cs0_dq0_tx_de-skew", ++ "cs0_dq1_rx_de-skew", ++ "cs0_dq1_tx_de-skew", ++ "cs0_dq2_rx_de-skew", ++ "cs0_dq2_tx_de-skew", ++ "cs0_dq3_rx_de-skew", ++ "cs0_dq3_tx_de-skew", ++ "cs0_dq4_rx_de-skew", ++ "cs0_dq4_tx_de-skew", ++ "cs0_dq5_rx_de-skew", ++ "cs0_dq5_tx_de-skew", ++ "cs0_dq6_rx_de-skew", ++ "cs0_dq6_tx_de-skew", ++ "cs0_dq7_rx_de-skew", ++ "cs0_dq7_tx_de-skew", ++ "cs0_dqs0_rx_de-skew", ++ "cs0_dqs0p_tx_de-skew", ++ "cs0_dqs0n_tx_de-skew", ++ ++ "cs0_dm1_rx_de-skew", ++ "cs0_dm1_tx_de-skew", ++ "cs0_dq8_rx_de-skew", ++ "cs0_dq8_tx_de-skew", ++ "cs0_dq9_rx_de-skew", ++ "cs0_dq9_tx_de-skew", ++ "cs0_dq10_rx_de-skew", ++ "cs0_dq10_tx_de-skew", ++ "cs0_dq11_rx_de-skew", ++ "cs0_dq11_tx_de-skew", ++ "cs0_dq12_rx_de-skew", ++ "cs0_dq12_tx_de-skew", ++ "cs0_dq13_rx_de-skew", ++ "cs0_dq13_tx_de-skew", ++ "cs0_dq14_rx_de-skew", ++ "cs0_dq14_tx_de-skew", ++ "cs0_dq15_rx_de-skew", ++ "cs0_dq15_tx_de-skew", ++ "cs0_dqs1_rx_de-skew", ++ "cs0_dqs1p_tx_de-skew", ++ "cs0_dqs1n_tx_de-skew", ++ ++ "cs0_dm2_rx_de-skew", ++ "cs0_dm2_tx_de-skew", ++ "cs0_dq16_rx_de-skew", ++ "cs0_dq16_tx_de-skew", ++ "cs0_dq17_rx_de-skew", ++ "cs0_dq17_tx_de-skew", ++ "cs0_dq18_rx_de-skew", ++ "cs0_dq18_tx_de-skew", ++ "cs0_dq19_rx_de-skew", ++ "cs0_dq19_tx_de-skew", ++ "cs0_dq20_rx_de-skew", ++ "cs0_dq20_tx_de-skew", ++ "cs0_dq21_rx_de-skew", ++ "cs0_dq21_tx_de-skew", ++ "cs0_dq22_rx_de-skew", ++ "cs0_dq22_tx_de-skew", ++ "cs0_dq23_rx_de-skew", ++ "cs0_dq23_tx_de-skew", ++ "cs0_dqs2_rx_de-skew", ++ "cs0_dqs2p_tx_de-skew", ++ "cs0_dqs2n_tx_de-skew", ++ ++ "cs0_dm3_rx_de-skew", ++ "cs0_dm3_tx_de-skew", ++ "cs0_dq24_rx_de-skew", ++ "cs0_dq24_tx_de-skew", ++ "cs0_dq25_rx_de-skew", ++ "cs0_dq25_tx_de-skew", ++ "cs0_dq26_rx_de-skew", ++ "cs0_dq26_tx_de-skew", ++ "cs0_dq27_rx_de-skew", ++ "cs0_dq27_tx_de-skew", ++ "cs0_dq28_rx_de-skew", ++ "cs0_dq28_tx_de-skew", ++ "cs0_dq29_rx_de-skew", ++ "cs0_dq29_tx_de-skew", ++ "cs0_dq30_rx_de-skew", ++ "cs0_dq30_tx_de-skew", ++ "cs0_dq31_rx_de-skew", ++ "cs0_dq31_tx_de-skew", ++ "cs0_dqs3_rx_de-skew", ++ "cs0_dqs3p_tx_de-skew", ++ "cs0_dqs3n_tx_de-skew", ++}; ++ ++static const char * const rk3328_dts_cs1_timing[] = { ++ "cs1_dm0_rx_de-skew", ++ "cs1_dm0_tx_de-skew", ++ "cs1_dq0_rx_de-skew", ++ "cs1_dq0_tx_de-skew", ++ "cs1_dq1_rx_de-skew", ++ "cs1_dq1_tx_de-skew", ++ "cs1_dq2_rx_de-skew", ++ "cs1_dq2_tx_de-skew", ++ "cs1_dq3_rx_de-skew", ++ "cs1_dq3_tx_de-skew", ++ "cs1_dq4_rx_de-skew", ++ "cs1_dq4_tx_de-skew", ++ "cs1_dq5_rx_de-skew", ++ "cs1_dq5_tx_de-skew", ++ "cs1_dq6_rx_de-skew", ++ "cs1_dq6_tx_de-skew", ++ "cs1_dq7_rx_de-skew", ++ "cs1_dq7_tx_de-skew", ++ "cs1_dqs0_rx_de-skew", ++ "cs1_dqs0p_tx_de-skew", ++ "cs1_dqs0n_tx_de-skew", ++ ++ "cs1_dm1_rx_de-skew", ++ "cs1_dm1_tx_de-skew", ++ "cs1_dq8_rx_de-skew", ++ "cs1_dq8_tx_de-skew", ++ "cs1_dq9_rx_de-skew", ++ "cs1_dq9_tx_de-skew", ++ "cs1_dq10_rx_de-skew", ++ "cs1_dq10_tx_de-skew", ++ "cs1_dq11_rx_de-skew", ++ "cs1_dq11_tx_de-skew", ++ "cs1_dq12_rx_de-skew", ++ "cs1_dq12_tx_de-skew", ++ "cs1_dq13_rx_de-skew", ++ "cs1_dq13_tx_de-skew", ++ "cs1_dq14_rx_de-skew", ++ "cs1_dq14_tx_de-skew", ++ "cs1_dq15_rx_de-skew", ++ "cs1_dq15_tx_de-skew", ++ "cs1_dqs1_rx_de-skew", ++ "cs1_dqs1p_tx_de-skew", ++ "cs1_dqs1n_tx_de-skew", ++ ++ "cs1_dm2_rx_de-skew", ++ "cs1_dm2_tx_de-skew", ++ "cs1_dq16_rx_de-skew", ++ "cs1_dq16_tx_de-skew", ++ "cs1_dq17_rx_de-skew", ++ "cs1_dq17_tx_de-skew", ++ "cs1_dq18_rx_de-skew", ++ "cs1_dq18_tx_de-skew", ++ "cs1_dq19_rx_de-skew", ++ "cs1_dq19_tx_de-skew", ++ "cs1_dq20_rx_de-skew", ++ "cs1_dq20_tx_de-skew", ++ "cs1_dq21_rx_de-skew", ++ "cs1_dq21_tx_de-skew", ++ "cs1_dq22_rx_de-skew", ++ "cs1_dq22_tx_de-skew", ++ "cs1_dq23_rx_de-skew", ++ "cs1_dq23_tx_de-skew", ++ "cs1_dqs2_rx_de-skew", ++ "cs1_dqs2p_tx_de-skew", ++ "cs1_dqs2n_tx_de-skew", ++ ++ "cs1_dm3_rx_de-skew", ++ "cs1_dm3_tx_de-skew", ++ "cs1_dq24_rx_de-skew", ++ "cs1_dq24_tx_de-skew", ++ "cs1_dq25_rx_de-skew", ++ "cs1_dq25_tx_de-skew", ++ "cs1_dq26_rx_de-skew", ++ "cs1_dq26_tx_de-skew", ++ "cs1_dq27_rx_de-skew", ++ "cs1_dq27_tx_de-skew", ++ "cs1_dq28_rx_de-skew", ++ "cs1_dq28_tx_de-skew", ++ "cs1_dq29_rx_de-skew", ++ "cs1_dq29_tx_de-skew", ++ "cs1_dq30_rx_de-skew", ++ "cs1_dq30_tx_de-skew", ++ "cs1_dq31_rx_de-skew", ++ "cs1_dq31_tx_de-skew", ++ "cs1_dqs3_rx_de-skew", ++ "cs1_dqs3p_tx_de-skew", ++ "cs1_dqs3n_tx_de-skew", ++}; ++ ++struct rk3328_ddr_dts_config_timing { ++ unsigned int ddr3_speed_bin; ++ unsigned int ddr4_speed_bin; ++ unsigned int pd_idle; ++ unsigned int sr_idle; ++ unsigned int sr_mc_gate_idle; ++ unsigned int srpd_lite_idle; ++ unsigned int standby_idle; ++ ++ unsigned int auto_pd_dis_freq; ++ unsigned int auto_sr_dis_freq; ++ /* for ddr3 only */ ++ unsigned int ddr3_dll_dis_freq; ++ /* for ddr4 only */ ++ unsigned int ddr4_dll_dis_freq; ++ unsigned int phy_dll_dis_freq; ++ ++ unsigned int ddr3_odt_dis_freq; ++ unsigned int phy_ddr3_odt_dis_freq; ++ unsigned int ddr3_drv; ++ unsigned int ddr3_odt; ++ unsigned int phy_ddr3_ca_drv; ++ unsigned int phy_ddr3_ck_drv; ++ unsigned int phy_ddr3_dq_drv; ++ unsigned int phy_ddr3_odt; ++ ++ unsigned int lpddr3_odt_dis_freq; ++ unsigned int phy_lpddr3_odt_dis_freq; ++ unsigned int lpddr3_drv; ++ unsigned int lpddr3_odt; ++ unsigned int phy_lpddr3_ca_drv; ++ unsigned int phy_lpddr3_ck_drv; ++ unsigned int phy_lpddr3_dq_drv; ++ unsigned int phy_lpddr3_odt; ++ ++ unsigned int lpddr4_odt_dis_freq; ++ unsigned int phy_lpddr4_odt_dis_freq; ++ unsigned int lpddr4_drv; ++ unsigned int lpddr4_dq_odt; ++ unsigned int lpddr4_ca_odt; ++ unsigned int phy_lpddr4_ca_drv; ++ unsigned int phy_lpddr4_ck_cs_drv; ++ unsigned int phy_lpddr4_dq_drv; ++ unsigned int phy_lpddr4_odt; ++ ++ unsigned int ddr4_odt_dis_freq; ++ unsigned int phy_ddr4_odt_dis_freq; ++ unsigned int ddr4_drv; ++ unsigned int ddr4_odt; ++ unsigned int phy_ddr4_ca_drv; ++ unsigned int phy_ddr4_ck_drv; ++ unsigned int phy_ddr4_dq_drv; ++ unsigned int phy_ddr4_odt; ++ ++ unsigned int ca_skew[15]; ++ unsigned int cs0_skew[44]; ++ unsigned int cs1_skew[44]; ++ ++ unsigned int available; ++}; ++ ++struct rk3328_ddr_de_skew_setting { ++ unsigned int ca_de_skew[30]; ++ unsigned int cs0_de_skew[84]; ++ unsigned int cs1_de_skew[84]; ++}; ++ ++struct rk3328_dmcfreq { ++ struct device *dev; ++ struct devfreq *devfreq; ++ struct devfreq_simple_ondemand_data ondemand_data; ++ struct clk *dmc_clk; ++ struct devfreq_event_dev *edev; ++ struct mutex lock; ++ struct regulator *vdd_center; ++ unsigned long rate, target_rate; ++ unsigned long volt, target_volt; ++ ++ int (*set_auto_self_refresh)(u32 en); ++}; ++ ++static void ++rk3328_de_skew_setting_2_register(struct rk3328_ddr_de_skew_setting *de_skew, ++ struct rk3328_ddr_dts_config_timing *tim) ++{ ++ u32 n; ++ u32 offset; ++ u32 shift; ++ ++ memset_io(tim->ca_skew, 0, sizeof(tim->ca_skew)); ++ memset_io(tim->cs0_skew, 0, sizeof(tim->cs0_skew)); ++ memset_io(tim->cs1_skew, 0, sizeof(tim->cs1_skew)); ++ ++ /* CA de-skew */ ++ for (n = 0; n < ARRAY_SIZE(de_skew->ca_de_skew); n++) { ++ offset = n / 2; ++ shift = n % 2; ++ /* 0 => 4; 1 => 0 */ ++ shift = (shift == 0) ? 4 : 0; ++ tim->ca_skew[offset] &= ~(0xf << shift); ++ tim->ca_skew[offset] |= (de_skew->ca_de_skew[n] << shift); ++ } ++ ++ /* CS0 data de-skew */ ++ for (n = 0; n < ARRAY_SIZE(de_skew->cs0_de_skew); n++) { ++ offset = ((n / 21) * 11) + ((n % 21) / 2); ++ shift = ((n % 21) % 2); ++ if ((n % 21) == 20) ++ shift = 0; ++ else ++ /* 0 => 4; 1 => 0 */ ++ shift = (shift == 0) ? 4 : 0; ++ tim->cs0_skew[offset] &= ~(0xf << shift); ++ tim->cs0_skew[offset] |= (de_skew->cs0_de_skew[n] << shift); ++ } ++ ++ /* CS1 data de-skew */ ++ for (n = 0; n < ARRAY_SIZE(de_skew->cs1_de_skew); n++) { ++ offset = ((n / 21) * 11) + ((n % 21) / 2); ++ shift = ((n % 21) % 2); ++ if ((n % 21) == 20) ++ shift = 0; ++ else ++ /* 0 => 4; 1 => 0 */ ++ shift = (shift == 0) ? 4 : 0; ++ tim->cs1_skew[offset] &= ~(0xf << shift); ++ tim->cs1_skew[offset] |= (de_skew->cs1_de_skew[n] << shift); ++ } ++} ++ ++static void of_get_rk3328_timings(struct device *dev, ++ struct device_node *np, uint32_t *timing) ++{ ++ struct device_node *np_tim; ++ u32 *p; ++ struct rk3328_ddr_dts_config_timing *dts_timing; ++ struct rk3328_ddr_de_skew_setting *de_skew; ++ int ret = 0; ++ u32 i; ++ ++ dts_timing = ++ (struct rk3328_ddr_dts_config_timing *)(timing + ++ DTS_PAR_OFFSET / 4); ++ ++ np_tim = of_parse_phandle(np, "ddr_timing", 0); ++ if (!np_tim) { ++ ret = -EINVAL; ++ goto end; ++ } ++ de_skew = kmalloc(sizeof(*de_skew), GFP_KERNEL); ++ if (!de_skew) { ++ ret = -ENOMEM; ++ goto end; ++ } ++ ++ p = (u32 *)dts_timing; ++ for (i = 0; i < ARRAY_SIZE(rk3328_dts_timing); i++) { ++ ret |= of_property_read_u32(np_tim, rk3328_dts_timing[i], ++ p + i); ++ } ++ p = (u32 *)de_skew->ca_de_skew; ++ for (i = 0; i < ARRAY_SIZE(rk3328_dts_ca_timing); i++) { ++ ret |= of_property_read_u32(np_tim, rk3328_dts_ca_timing[i], ++ p + i); ++ } ++ p = (u32 *)de_skew->cs0_de_skew; ++ for (i = 0; i < ARRAY_SIZE(rk3328_dts_cs0_timing); i++) { ++ ret |= of_property_read_u32(np_tim, rk3328_dts_cs0_timing[i], ++ p + i); ++ } ++ p = (u32 *)de_skew->cs1_de_skew; ++ for (i = 0; i < ARRAY_SIZE(rk3328_dts_cs1_timing); i++) { ++ ret |= of_property_read_u32(np_tim, rk3328_dts_cs1_timing[i], ++ p + i); ++ } ++ if (!ret) ++ rk3328_de_skew_setting_2_register(de_skew, dts_timing); ++ ++ kfree(de_skew); ++end: ++ if (!ret) { ++ dts_timing->available = 1; ++ } else { ++ dts_timing->available = 0; ++ dev_err(dev, "of_get_ddr_timings: fail\n"); ++ } ++ ++ of_node_put(np_tim); ++} ++ ++static int rockchip_ddr_set_auto_self_refresh(uint32_t en) ++{ ++ struct arm_smccc_res res; ++ ++ ddr_psci_param->sr_idle_en = en; ++ ++ arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, ++ SHARE_PAGE_TYPE_DDR, 0, ROCKCHIP_SIP_CONFIG_DRAM_SET_AT_SR, ++ 0, 0, 0, 0, &res); ++ ++ return res.a0; ++} ++ ++static int rk3328_dmc_init(struct platform_device *pdev, ++ struct rk3328_dmcfreq *dmcfreq) ++{ ++ struct arm_smccc_res res; ++ u32 size, page_num; ++ ++ arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, ++ 0, 0, ROCKCHIP_SIP_CONFIG_DRAM_GET_VERSION, ++ 0, 0, 0, 0, &res); ++ if (res.a0 || (res.a1 < 0x101)) { ++ dev_err(&pdev->dev, ++ "trusted firmware need to update or is invalid\n"); ++ return -ENXIO; ++ } ++ ++ dev_notice(&pdev->dev, "current ATF version 0x%lx\n", res.a1); ++ ++ /* ++ * first 4KB is used for interface parameters ++ * after 4KB * N is dts parameters ++ */ ++ size = sizeof(struct rk3328_ddr_dts_config_timing); ++ page_num = DIV_ROUND_UP(size, 4096) + 1; ++ ++ arm_smccc_smc(ROCKCHIP_SIP_SHARE_MEM, ++ page_num, SHARE_PAGE_TYPE_DDR, 0, ++ 0, 0, 0, 0, &res); ++ if (res.a0 != 0) { ++ dev_err(&pdev->dev, "no ATF memory for init\n"); ++ return -ENOMEM; ++ } ++ ++ ddr_psci_param = ioremap(res.a1, page_num << 12); ++ of_get_rk3328_timings(&pdev->dev, pdev->dev.of_node, ++ (uint32_t *)ddr_psci_param); ++ ++ arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, ++ SHARE_PAGE_TYPE_DDR, 0, ROCKCHIP_SIP_CONFIG_DRAM_INIT, ++ 0, 0, 0, 0, &res); ++ if (res.a0) { ++ dev_err(&pdev->dev, "Rockchip dram init error %lx\n", res.a0); ++ return -ENOMEM; ++ } ++ ++ dmcfreq->set_auto_self_refresh = rockchip_ddr_set_auto_self_refresh; ++ ++ return 0; ++} ++ ++static int rk3328_dmcfreq_target(struct device *dev, unsigned long *freq, ++ u32 flags) ++{ ++ struct rk3328_dmcfreq *dmcfreq = dev_get_drvdata(dev); ++ struct dev_pm_opp *opp; ++ unsigned long old_clk_rate = dmcfreq->rate; ++ unsigned long target_volt, target_rate; ++ int err; ++ ++ opp = devfreq_recommended_opp(dev, freq, flags); ++ if (IS_ERR(opp)) ++ return PTR_ERR(opp); ++ ++ target_rate = dev_pm_opp_get_freq(opp); ++ target_volt = dev_pm_opp_get_voltage(opp); ++ dev_pm_opp_put(opp); ++ ++ if (dmcfreq->rate == target_rate) ++ return 0; ++ ++ mutex_lock(&dmcfreq->lock); ++ ++ /* ++ * If frequency scaling from low to high, adjust voltage first. ++ * If frequency scaling from high to low, adjust frequency first. ++ */ ++ if (old_clk_rate < target_rate) { ++ err = regulator_set_voltage(dmcfreq->vdd_center, target_volt, ++ target_volt); ++ if (err) { ++ dev_err(dev, "Cannot set voltage %lu uV\n", ++ target_volt); ++ goto out; ++ } ++ } ++ ++ err = clk_set_rate(dmcfreq->dmc_clk, target_rate); ++ if (err) { ++ dev_err(dev, "Cannot set frequency %lu (%d)\n", target_rate, ++ err); ++ regulator_set_voltage(dmcfreq->vdd_center, dmcfreq->volt, ++ dmcfreq->volt); ++ goto out; ++ } ++ ++ /* ++ * Check the dpll rate, ++ * There only two result we will get, ++ * 1. Ddr frequency scaling fail, we still get the old rate. ++ * 2. Ddr frequency scaling sucessful, we get the rate we set. ++ */ ++ dmcfreq->rate = clk_get_rate(dmcfreq->dmc_clk); ++ ++ /* If get the incorrect rate, set voltage to old value. */ ++ if (dmcfreq->rate != target_rate) { ++ dev_err(dev, "Got wrong frequency, Request %lu, Current %lu\n", ++ target_rate, dmcfreq->rate); ++ regulator_set_voltage(dmcfreq->vdd_center, dmcfreq->volt, ++ dmcfreq->volt); ++ goto out; ++ } else if (old_clk_rate > target_rate) ++ err = regulator_set_voltage(dmcfreq->vdd_center, target_volt, ++ target_volt); ++ if (err) ++ dev_err(dev, "Cannot set voltage %lu uV\n", target_volt); ++ ++ dmcfreq->rate = target_rate; ++ dmcfreq->volt = target_volt; ++ ++out: ++ mutex_unlock(&dmcfreq->lock); ++ return err; ++} ++ ++static int rk3328_dmcfreq_get_dev_status(struct device *dev, ++ struct devfreq_dev_status *stat) ++{ ++ struct rk3328_dmcfreq *dmcfreq = dev_get_drvdata(dev); ++ struct devfreq_event_data edata; ++ int ret = 0; ++ ++ ret = devfreq_event_get_event(dmcfreq->edev, &edata); ++ if (ret < 0) ++ return ret; ++ ++ stat->current_frequency = dmcfreq->rate; ++ stat->busy_time = edata.load_count; ++ stat->total_time = edata.total_count; ++ ++ return ret; ++} ++ ++static int rk3328_dmcfreq_get_cur_freq(struct device *dev, unsigned long *freq) ++{ ++ struct rk3328_dmcfreq *dmcfreq = dev_get_drvdata(dev); ++ ++ *freq = dmcfreq->rate; ++ ++ return 0; ++} ++ ++static struct devfreq_dev_profile rk3328_devfreq_dmc_profile = { ++ .polling_ms = 200, ++ .target = rk3328_dmcfreq_target, ++ .get_dev_status = rk3328_dmcfreq_get_dev_status, ++ .get_cur_freq = rk3328_dmcfreq_get_cur_freq, ++}; ++ ++static __maybe_unused int rk3328_dmcfreq_suspend(struct device *dev) ++{ ++ struct rk3328_dmcfreq *dmcfreq = dev_get_drvdata(dev); ++ int ret = 0; ++ ++ ret = devfreq_event_disable_edev(dmcfreq->edev); ++ if (ret < 0) { ++ dev_err(dev, "failed to disable the devfreq-event devices\n"); ++ return ret; ++ } ++ ++ ret = devfreq_suspend_device(dmcfreq->devfreq); ++ if (ret < 0) { ++ dev_err(dev, "failed to suspend the devfreq devices\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static __maybe_unused int rk3328_dmcfreq_resume(struct device *dev) ++{ ++ struct rk3328_dmcfreq *dmcfreq = dev_get_drvdata(dev); ++ int ret = 0; ++ ++ ret = devfreq_event_enable_edev(dmcfreq->edev); ++ if (ret < 0) { ++ dev_err(dev, "failed to enable the devfreq-event devices\n"); ++ return ret; ++ } ++ ++ ret = devfreq_resume_device(dmcfreq->devfreq); ++ if (ret < 0) { ++ dev_err(dev, "failed to resume the devfreq devices\n"); ++ return ret; ++ } ++ return ret; ++} ++ ++static SIMPLE_DEV_PM_OPS(rk3328_dmcfreq_pm, rk3328_dmcfreq_suspend, ++ rk3328_dmcfreq_resume); ++ ++static int rk3328_dmcfreq_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *np = pdev->dev.of_node; ++ struct rk3328_dmcfreq *data; ++ struct dev_pm_opp *opp; ++ int ret; ++ ++ data = devm_kzalloc(dev, sizeof(struct rk3328_dmcfreq), GFP_KERNEL); ++ if (!data) ++ return -ENOMEM; ++ ++ mutex_init(&data->lock); ++ ++ data->vdd_center = devm_regulator_get(dev, "center"); ++ if (IS_ERR(data->vdd_center)) { ++ if (PTR_ERR(data->vdd_center) == -EPROBE_DEFER) ++ return -EPROBE_DEFER; ++ ++ dev_err(dev, "Cannot get the regulator \"center\"\n"); ++ return PTR_ERR(data->vdd_center); ++ } ++ ++ data->dmc_clk = devm_clk_get(dev, "dmc_clk"); ++ if (IS_ERR(data->dmc_clk)) { ++ if (PTR_ERR(data->dmc_clk) == -EPROBE_DEFER) ++ return -EPROBE_DEFER; ++ ++ dev_err(dev, "Cannot get the clk dmc_clk\n"); ++ return PTR_ERR(data->dmc_clk); ++ } ++ ++ data->edev = devfreq_event_get_edev_by_phandle(dev, 0); ++ if (IS_ERR(data->edev)) ++ return -EPROBE_DEFER; ++ ++ ret = devfreq_event_enable_edev(data->edev); ++ if (ret < 0) { ++ dev_err(dev, "failed to enable devfreq-event devices\n"); ++ return ret; ++ } ++ ++ ret = rk3328_dmc_init(pdev, data); ++ if (ret) ++ return ret; ++ ++ /* ++ * We add a devfreq driver to our parent since it has a device tree node ++ * with operating points. ++ */ ++ if (dev_pm_opp_of_add_table(dev)) { ++ dev_err(dev, "Invalid operating-points in device tree.\n"); ++ return -EINVAL; ++ } ++ ++ of_property_read_u32(np, "upthreshold", ++ &data->ondemand_data.upthreshold); ++ of_property_read_u32(np, "downdifferential", ++ &data->ondemand_data.downdifferential); ++ ++ data->rate = clk_get_rate(data->dmc_clk); ++ ++ opp = devfreq_recommended_opp(dev, &data->rate, 0); ++ if (IS_ERR(opp)) { ++ ret = PTR_ERR(opp); ++ goto err_free_opp; ++ } ++ ++ data->rate = dev_pm_opp_get_freq(opp); ++ data->volt = dev_pm_opp_get_voltage(opp); ++ dev_pm_opp_put(opp); ++ ++ rk3328_devfreq_dmc_profile.initial_freq = data->rate; ++ ++ data->devfreq = devm_devfreq_add_device(dev, ++ &rk3328_devfreq_dmc_profile, ++ DEVFREQ_GOV_SIMPLE_ONDEMAND, ++ &data->ondemand_data); ++ if (IS_ERR(data->devfreq)) { ++ ret = PTR_ERR(data->devfreq); ++ goto err_free_opp; ++ } ++ ++ devm_devfreq_register_opp_notifier(dev, data->devfreq); ++ ++ data->dev = dev; ++ platform_set_drvdata(pdev, data); ++ ++ return 0; ++ ++err_free_opp: ++ dev_pm_opp_of_remove_table(&pdev->dev); ++ return ret; ++} ++ ++static int rk3328_dmcfreq_remove(struct platform_device *pdev) ++{ ++ struct rk3328_dmcfreq *dmcfreq = dev_get_drvdata(&pdev->dev); ++ ++ /* ++ * Before remove the opp table we need to unregister the opp notifier. ++ */ ++ devm_devfreq_unregister_opp_notifier(dmcfreq->dev, dmcfreq->devfreq); ++ dev_pm_opp_of_remove_table(dmcfreq->dev); ++ ++ return 0; ++} ++ ++static const struct of_device_id rk3328dmc_devfreq_of_match[] = { ++ { .compatible = "rockchip,rk3328-dmc" }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(of, rk3328dmc_devfreq_of_match); ++ ++static struct platform_driver rk3328_dmcfreq_driver = { ++ .probe = rk3328_dmcfreq_probe, ++ .remove = rk3328_dmcfreq_remove, ++ .driver = { ++ .name = "rk3328-dmc-freq", ++ .pm = &rk3328_dmcfreq_pm, ++ .of_match_table = rk3328dmc_devfreq_of_match, ++ }, ++}; ++module_platform_driver(rk3328_dmcfreq_driver); ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_AUTHOR("Lin Huang "); ++MODULE_DESCRIPTION("RK3328 dmcfreq driver with devfreq framework"); +From ce6d3614888e6358466f0e84e248177a6bca5258 Mon Sep 17 00:00:00 2001 +From: Tang Yun ping +Date: Thu, 4 May 2017 20:49:58 +0800 +Subject: [PATCH] clk: rockchip: support setting ddr clock via SIP Version 2 + APIs + +commit 764e893ee82321938fc6f4349e9e7caf06a04410 rockchip. + +Signed-off-by: Tang Yun ping +Signed-off-by: hmz007 +--- + drivers/clk/rockchip/clk-ddr.c | 130 ++++++++++++++++++++++++++++ + drivers/clk/rockchip/clk-rk3328.c | 7 +- + drivers/clk/rockchip/clk.h | 3 +- + include/soc/rockchip/rockchip_sip.h | 11 +++ + 4 files changed, 147 insertions(+), 4 deletions(-) + +diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c +index 9273bce4d7b6..555aaf4e758d 100644 +--- a/drivers/clk/rockchip/clk-ddr.c ++++ b/drivers/clk/rockchip/clk-ddr.c +@@ -87,6 +87,133 @@ static const struct clk_ops rockchip_ddrclk_sip_ops = { + .get_parent = rockchip_ddrclk_get_parent, + }; + ++/* See v4.4/include/dt-bindings/display/rk_fb.h */ ++#define SCREEN_NULL 0 ++#define SCREEN_HDMI 6 ++ ++static inline int rk_drm_get_lcdc_type(void) ++{ ++ return SCREEN_NULL; ++} ++ ++struct share_params { ++ u32 hz; ++ u32 lcdc_type; ++ u32 vop; ++ u32 vop_dclk_mode; ++ u32 sr_idle_en; ++ u32 addr_mcu_el3; ++ /* ++ * 1: need to wait flag1 ++ * 0: never wait flag1 ++ */ ++ u32 wait_flag1; ++ /* ++ * 1: need to wait flag1 ++ * 0: never wait flag1 ++ */ ++ u32 wait_flag0; ++ u32 complt_hwirq; ++ /* if need, add parameter after */ ++}; ++ ++struct rockchip_ddrclk_data { ++ u32 inited_flag; ++ void __iomem *share_memory; ++}; ++ ++static struct rockchip_ddrclk_data ddr_data; ++ ++static void rockchip_ddrclk_data_init(void) ++{ ++ struct arm_smccc_res res; ++ ++ arm_smccc_smc(ROCKCHIP_SIP_SHARE_MEM, ++ 1, SHARE_PAGE_TYPE_DDR, 0, ++ 0, 0, 0, 0, &res); ++ ++ if (!res.a0) { ++ ddr_data.share_memory = (void __iomem *)ioremap(res.a1, 1<<12); ++ ddr_data.inited_flag = 1; ++ } ++} ++ ++static int rockchip_ddrclk_sip_set_rate_v2(struct clk_hw *hw, ++ unsigned long drate, ++ unsigned long prate) ++{ ++ struct share_params *p; ++ struct arm_smccc_res res; ++ ++ if (!ddr_data.inited_flag) ++ rockchip_ddrclk_data_init(); ++ ++ p = (struct share_params *)ddr_data.share_memory; ++ ++ p->hz = drate; ++ p->lcdc_type = rk_drm_get_lcdc_type(); ++ p->wait_flag1 = 1; ++ p->wait_flag0 = 1; ++ ++ arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, ++ SHARE_PAGE_TYPE_DDR, 0, ++ ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE, ++ 0, 0, 0, 0, &res); ++ ++ if ((int)res.a1 == -6) { ++ pr_err("%s: timeout, drate = %lumhz\n", __func__, drate/1000000); ++ /* TODO: rockchip_dmcfreq_wait_complete(); */ ++ } ++ ++ return res.a0; ++} ++ ++static unsigned long rockchip_ddrclk_sip_recalc_rate_v2 ++ (struct clk_hw *hw, unsigned long parent_rate) ++{ ++ struct arm_smccc_res res; ++ ++ arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, ++ SHARE_PAGE_TYPE_DDR, 0, ++ ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE, ++ 0, 0, 0, 0, &res); ++ if (!res.a0) ++ return res.a1; ++ else ++ return 0; ++} ++ ++static long rockchip_ddrclk_sip_round_rate_v2(struct clk_hw *hw, ++ unsigned long rate, ++ unsigned long *prate) ++{ ++ struct share_params *p; ++ struct arm_smccc_res res; ++ ++ if (!ddr_data.inited_flag) ++ rockchip_ddrclk_data_init(); ++ ++ p = (struct share_params *)ddr_data.share_memory; ++ ++ p->hz = rate; ++ ++ arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, ++ SHARE_PAGE_TYPE_DDR, 0, ++ ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE, ++ 0, 0, 0, 0, &res); ++ if (!res.a0) ++ return res.a1; ++ else ++ return 0; ++} ++ ++static const struct clk_ops rockchip_ddrclk_sip_ops_v2 = { ++ .recalc_rate = rockchip_ddrclk_sip_recalc_rate_v2, ++ .set_rate = rockchip_ddrclk_sip_set_rate_v2, ++ .round_rate = rockchip_ddrclk_sip_round_rate_v2, ++ .get_parent = rockchip_ddrclk_get_parent, ++}; ++ + struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, + const char *const *parent_names, + u8 num_parents, int mux_offset, +@@ -114,6 +241,9 @@ struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, + case ROCKCHIP_DDRCLK_SIP: + init.ops = &rockchip_ddrclk_sip_ops; + break; ++ case ROCKCHIP_DDRCLK_SIP_V2: ++ init.ops = &rockchip_ddrclk_sip_ops_v2; ++ break; + default: + pr_err("%s: unsupported ddrclk type %d\n", __func__, ddr_flag); + kfree(ddrclk); +diff --git a/drivers/clk/rockchip/clk-rk3328.c b/drivers/clk/rockchip/clk-rk3328.c +index c186a1985bf4..ac6e6163a232 100644 +--- a/drivers/clk/rockchip/clk-rk3328.c ++++ b/drivers/clk/rockchip/clk-rk3328.c +@@ -314,9 +314,10 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = { + RK3328_CLKGATE_CON(14), 1, GFLAGS), + + /* PD_DDR */ +- COMPOSITE(0, "clk_ddr", mux_ddrphy_p, CLK_IGNORE_UNUSED, +- RK3328_CLKSEL_CON(3), 8, 2, MFLAGS, 0, 3, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, +- RK3328_CLKGATE_CON(0), 4, GFLAGS), ++ COMPOSITE_DDRCLK(SCLK_DDRCLK, "sclk_ddrc", mux_ddrphy_p, 0, ++ RK3328_CLKSEL_CON(3), 8, 2, 0, 3, ++ ROCKCHIP_DDRCLK_SIP_V2), ++ + GATE(0, "clk_ddrmsch", "clk_ddr", CLK_IGNORE_UNUSED, + RK3328_CLKGATE_CON(18), 6, GFLAGS), + GATE(0, "clk_ddrupctl", "clk_ddr", CLK_IGNORE_UNUSED, +diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h +index 2271a84124b0..7405aaf965ec 100644 +--- a/drivers/clk/rockchip/clk.h ++++ b/drivers/clk/rockchip/clk.h +@@ -362,7 +362,8 @@ struct clk *rockchip_clk_register_mmc(const char *name, + * DDRCLK flags, including method of setting the rate + * ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate. + */ +-#define ROCKCHIP_DDRCLK_SIP BIT(0) ++#define ROCKCHIP_DDRCLK_SIP 0x01 ++#define ROCKCHIP_DDRCLK_SIP_V2 0x03 + + struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, + const char *const *parent_names, +diff --git a/include/soc/rockchip/rockchip_sip.h b/include/soc/rockchip/rockchip_sip.h +index c46a9ae2a2ab..fa7e0a2d72cc 100644 +--- a/include/soc/rockchip/rockchip_sip.h ++++ b/include/soc/rockchip/rockchip_sip.h +@@ -16,5 +16,16 @@ + #define ROCKCHIP_SIP_CONFIG_DRAM_CLR_IRQ 0x06 + #define ROCKCHIP_SIP_CONFIG_DRAM_SET_PARAM 0x07 + #define ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD 0x08 ++#define ROCKCHIP_SIP_CONFIG_DRAM_GET_VERSION 0x08 ++ ++#define ROCKCHIP_SIP_SHARE_MEM 0x82000009 ++ ++/* Share mem page types */ ++typedef enum { ++ SHARE_PAGE_TYPE_INVALID = 0, ++ SHARE_PAGE_TYPE_UARTDBG, ++ SHARE_PAGE_TYPE_DDR, ++ SHARE_PAGE_TYPE_MAX, ++} share_page_type_t; + + #endif +From 4db93c6dad0c71750b86163df2fdb21c35f00d9a Mon Sep 17 00:00:00 2001 +From: hmz007 +Date: Tue, 19 Nov 2019 12:49:48 +0800 +Subject: [PATCH] PM / devfreq: rockchip-dfi: add more soc support + +Signed-off-by: hmz007 +--- + drivers/devfreq/event/rockchip-dfi.c | 554 ++++++++++++++++++++++++--- + 1 file changed, 505 insertions(+), 49 deletions(-) + +diff --git a/drivers/devfreq/event/rockchip-dfi.c b/drivers/devfreq/event/rockchip-dfi.c +index 5d1042188727..80be0efdfb9b 100644 +--- a/drivers/devfreq/event/rockchip-dfi.c ++++ b/drivers/devfreq/event/rockchip-dfi.c +@@ -18,25 +18,66 @@ + #include + #include + +-#include +- +-#define RK3399_DMC_NUM_CH 2 +- ++#define PX30_PMUGRF_OS_REG2 0x208 ++ ++#define RK3128_GRF_SOC_CON0 0x140 ++#define RK3128_GRF_OS_REG1 0x1cc ++#define RK3128_GRF_DFI_WRNUM 0x220 ++#define RK3128_GRF_DFI_RDNUM 0x224 ++#define RK3128_GRF_DFI_TIMERVAL 0x22c ++#define RK3128_DDR_MONITOR_EN ((1 << (16 + 6)) + (1 << 6)) ++#define RK3128_DDR_MONITOR_DISB ((1 << (16 + 6)) + (0 << 6)) ++ ++#define RK3288_PMU_SYS_REG2 0x9c ++#define RK3288_GRF_SOC_CON4 0x254 ++#define RK3288_GRF_SOC_STATUS(n) (0x280 + (n) * 4) ++#define RK3288_DFI_EN (0x30003 << 14) ++#define RK3288_DFI_DIS (0x30000 << 14) ++#define RK3288_LPDDR_SEL (0x10001 << 13) ++#define RK3288_DDR3_SEL (0x10000 << 13) ++ ++#define RK3328_GRF_OS_REG2 0x5d0 ++ ++#define RK3368_GRF_DDRC0_CON0 0x600 ++#define RK3368_GRF_SOC_STATUS5 0x494 ++#define RK3368_GRF_SOC_STATUS6 0x498 ++#define RK3368_GRF_SOC_STATUS8 0x4a0 ++#define RK3368_GRF_SOC_STATUS9 0x4a4 ++#define RK3368_GRF_SOC_STATUS10 0x4a8 ++#define RK3368_DFI_EN (0x30003 << 5) ++#define RK3368_DFI_DIS (0x30000 << 5) ++ ++#define MAX_DMC_NUM_CH 2 ++#define READ_DRAMTYPE_INFO(n) (((n) >> 13) & 0x7) ++#define READ_CH_INFO(n) (((n) >> 28) & 0x3) + /* DDRMON_CTRL */ +-#define DDRMON_CTRL 0x04 +-#define CLR_DDRMON_CTRL (0x1f0000 << 0) +-#define LPDDR4_EN (0x10001 << 4) +-#define HARDWARE_EN (0x10001 << 3) +-#define LPDDR3_EN (0x10001 << 2) +-#define SOFTWARE_EN (0x10001 << 1) +-#define SOFTWARE_DIS (0x10000 << 1) +-#define TIME_CNT_EN (0x10001 << 0) ++#define DDRMON_CTRL 0x04 ++#define CLR_DDRMON_CTRL (0x3f0000 << 0) ++#define DDR4_EN (0x10001 << 5) ++#define LPDDR4_EN (0x10001 << 4) ++#define HARDWARE_EN (0x10001 << 3) ++#define LPDDR2_3_EN (0x10001 << 2) ++#define SOFTWARE_EN (0x10001 << 1) ++#define SOFTWARE_DIS (0x10000 << 1) ++#define TIME_CNT_EN (0x10001 << 0) + + #define DDRMON_CH0_COUNT_NUM 0x28 + #define DDRMON_CH0_DFI_ACCESS_NUM 0x2c + #define DDRMON_CH1_COUNT_NUM 0x3c + #define DDRMON_CH1_DFI_ACCESS_NUM 0x40 + ++/* pmu grf */ ++#define PMUGRF_OS_REG2 0x308 ++ ++enum { ++ DDR4 = 0, ++ DDR3 = 3, ++ LPDDR2 = 5, ++ LPDDR3 = 6, ++ LPDDR4 = 7, ++ UNUSED = 0xFF ++}; ++ + struct dmc_usage { + u32 access; + u32 total; +@@ -50,33 +91,261 @@ struct dmc_usage { + struct rockchip_dfi { + struct devfreq_event_dev *edev; + struct devfreq_event_desc *desc; +- struct dmc_usage ch_usage[RK3399_DMC_NUM_CH]; ++ struct dmc_usage ch_usage[MAX_DMC_NUM_CH]; + struct device *dev; + void __iomem *regs; + struct regmap *regmap_pmu; ++ struct regmap *regmap_grf; ++ struct regmap *regmap_pmugrf; + struct clk *clk; ++ u32 dram_type; ++ /* ++ * available mask, 1: available, 0: not available ++ * each bit represent a channel ++ */ ++ u32 ch_msk; ++}; ++ ++static void rk3128_dfi_start_hardware_counter(struct devfreq_event_dev *edev) ++{ ++ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); ++ ++ regmap_write(info->regmap_grf, ++ RK3128_GRF_SOC_CON0, ++ RK3128_DDR_MONITOR_EN); ++} ++ ++static void rk3128_dfi_stop_hardware_counter(struct devfreq_event_dev *edev) ++{ ++ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); ++ ++ regmap_write(info->regmap_grf, ++ RK3128_GRF_SOC_CON0, ++ RK3128_DDR_MONITOR_DISB); ++} ++ ++static int rk3128_dfi_disable(struct devfreq_event_dev *edev) ++{ ++ rk3128_dfi_stop_hardware_counter(edev); ++ ++ return 0; ++} ++ ++static int rk3128_dfi_enable(struct devfreq_event_dev *edev) ++{ ++ rk3128_dfi_start_hardware_counter(edev); ++ ++ return 0; ++} ++ ++static int rk3128_dfi_set_event(struct devfreq_event_dev *edev) ++{ ++ return 0; ++} ++ ++static int rk3128_dfi_get_event(struct devfreq_event_dev *edev, ++ struct devfreq_event_data *edata) ++{ ++ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); ++ unsigned long flags; ++ u32 dfi_wr, dfi_rd, dfi_timer; ++ ++ local_irq_save(flags); ++ ++ rk3128_dfi_stop_hardware_counter(edev); ++ ++ regmap_read(info->regmap_grf, RK3128_GRF_DFI_WRNUM, &dfi_wr); ++ regmap_read(info->regmap_grf, RK3128_GRF_DFI_RDNUM, &dfi_rd); ++ regmap_read(info->regmap_grf, RK3128_GRF_DFI_TIMERVAL, &dfi_timer); ++ ++ edata->load_count = (dfi_wr + dfi_rd) * 4; ++ edata->total_count = dfi_timer; ++ ++ rk3128_dfi_start_hardware_counter(edev); ++ ++ local_irq_restore(flags); ++ ++ return 0; ++} ++ ++static const struct devfreq_event_ops rk3128_dfi_ops = { ++ .disable = rk3128_dfi_disable, ++ .enable = rk3128_dfi_enable, ++ .get_event = rk3128_dfi_get_event, ++ .set_event = rk3128_dfi_set_event, ++}; ++ ++static void rk3288_dfi_start_hardware_counter(struct devfreq_event_dev *edev) ++{ ++ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); ++ ++ regmap_write(info->regmap_grf, RK3288_GRF_SOC_CON4, RK3288_DFI_EN); ++} ++ ++static void rk3288_dfi_stop_hardware_counter(struct devfreq_event_dev *edev) ++{ ++ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); ++ ++ regmap_write(info->regmap_grf, RK3288_GRF_SOC_CON4, RK3288_DFI_DIS); ++} ++ ++static int rk3288_dfi_disable(struct devfreq_event_dev *edev) ++{ ++ rk3288_dfi_stop_hardware_counter(edev); ++ ++ return 0; ++} ++ ++static int rk3288_dfi_enable(struct devfreq_event_dev *edev) ++{ ++ rk3288_dfi_start_hardware_counter(edev); ++ ++ return 0; ++} ++ ++static int rk3288_dfi_set_event(struct devfreq_event_dev *edev) ++{ ++ return 0; ++} ++ ++static int rk3288_dfi_get_busier_ch(struct devfreq_event_dev *edev) ++{ ++ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); ++ u32 tmp, max = 0; ++ u32 i, busier_ch = 0; ++ u32 rd_count, wr_count, total_count; ++ ++ rk3288_dfi_stop_hardware_counter(edev); ++ ++ /* Find out which channel is busier */ ++ for (i = 0; i < MAX_DMC_NUM_CH; i++) { ++ if (!(info->ch_msk & BIT(i))) ++ continue; ++ regmap_read(info->regmap_grf, ++ RK3288_GRF_SOC_STATUS(11 + i * 4), &wr_count); ++ regmap_read(info->regmap_grf, ++ RK3288_GRF_SOC_STATUS(12 + i * 4), &rd_count); ++ regmap_read(info->regmap_grf, ++ RK3288_GRF_SOC_STATUS(14 + i * 4), &total_count); ++ info->ch_usage[i].access = (wr_count + rd_count) * 4; ++ info->ch_usage[i].total = total_count; ++ tmp = info->ch_usage[i].access; ++ if (tmp > max) { ++ busier_ch = i; ++ max = tmp; ++ } ++ } ++ rk3288_dfi_start_hardware_counter(edev); ++ ++ return busier_ch; ++} ++ ++static int rk3288_dfi_get_event(struct devfreq_event_dev *edev, ++ struct devfreq_event_data *edata) ++{ ++ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); ++ int busier_ch; ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ busier_ch = rk3288_dfi_get_busier_ch(edev); ++ local_irq_restore(flags); ++ ++ edata->load_count = info->ch_usage[busier_ch].access; ++ edata->total_count = info->ch_usage[busier_ch].total; ++ ++ return 0; ++} ++ ++static const struct devfreq_event_ops rk3288_dfi_ops = { ++ .disable = rk3288_dfi_disable, ++ .enable = rk3288_dfi_enable, ++ .get_event = rk3288_dfi_get_event, ++ .set_event = rk3288_dfi_set_event, ++}; ++ ++static void rk3368_dfi_start_hardware_counter(struct devfreq_event_dev *edev) ++{ ++ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); ++ ++ regmap_write(info->regmap_grf, RK3368_GRF_DDRC0_CON0, RK3368_DFI_EN); ++} ++ ++static void rk3368_dfi_stop_hardware_counter(struct devfreq_event_dev *edev) ++{ ++ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); ++ ++ regmap_write(info->regmap_grf, RK3368_GRF_DDRC0_CON0, RK3368_DFI_DIS); ++} ++ ++static int rk3368_dfi_disable(struct devfreq_event_dev *edev) ++{ ++ rk3368_dfi_stop_hardware_counter(edev); ++ ++ return 0; ++} ++ ++static int rk3368_dfi_enable(struct devfreq_event_dev *edev) ++{ ++ rk3368_dfi_start_hardware_counter(edev); ++ ++ return 0; ++} ++ ++static int rk3368_dfi_set_event(struct devfreq_event_dev *edev) ++{ ++ return 0; ++} ++ ++static int rk3368_dfi_get_event(struct devfreq_event_dev *edev, ++ struct devfreq_event_data *edata) ++{ ++ struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); ++ unsigned long flags; ++ u32 dfi0_wr, dfi0_rd, dfi1_wr, dfi1_rd, dfi_timer; ++ ++ local_irq_save(flags); ++ ++ rk3368_dfi_stop_hardware_counter(edev); ++ ++ regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS5, &dfi0_wr); ++ regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS6, &dfi0_rd); ++ regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS9, &dfi1_wr); ++ regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS10, &dfi1_rd); ++ regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS8, &dfi_timer); ++ ++ edata->load_count = (dfi0_wr + dfi0_rd + dfi1_wr + dfi1_rd) * 2; ++ edata->total_count = dfi_timer; ++ ++ rk3368_dfi_start_hardware_counter(edev); ++ ++ local_irq_restore(flags); ++ ++ return 0; ++} ++ ++static const struct devfreq_event_ops rk3368_dfi_ops = { ++ .disable = rk3368_dfi_disable, ++ .enable = rk3368_dfi_enable, ++ .get_event = rk3368_dfi_get_event, ++ .set_event = rk3368_dfi_set_event, + }; + + static void rockchip_dfi_start_hardware_counter(struct devfreq_event_dev *edev) + { + struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); + void __iomem *dfi_regs = info->regs; +- u32 val; +- u32 ddr_type; +- +- /* get ddr type */ +- regmap_read(info->regmap_pmu, RK3399_PMUGRF_OS_REG2, &val); +- ddr_type = (val >> RK3399_PMUGRF_DDRTYPE_SHIFT) & +- RK3399_PMUGRF_DDRTYPE_MASK; + + /* clear DDRMON_CTRL setting */ + writel_relaxed(CLR_DDRMON_CTRL, dfi_regs + DDRMON_CTRL); + + /* set ddr type to dfi */ +- if (ddr_type == RK3399_PMUGRF_DDRTYPE_LPDDR3) +- writel_relaxed(LPDDR3_EN, dfi_regs + DDRMON_CTRL); +- else if (ddr_type == RK3399_PMUGRF_DDRTYPE_LPDDR4) ++ if (info->dram_type == LPDDR3 || info->dram_type == LPDDR2) ++ writel_relaxed(LPDDR2_3_EN, dfi_regs + DDRMON_CTRL); ++ else if (info->dram_type == LPDDR4) + writel_relaxed(LPDDR4_EN, dfi_regs + DDRMON_CTRL); ++ else if (info->dram_type == DDR4) ++ writel_relaxed(DDR4_EN, dfi_regs + DDRMON_CTRL); + + /* enable count, use software mode */ + writel_relaxed(SOFTWARE_EN, dfi_regs + DDRMON_CTRL); +@@ -100,12 +369,22 @@ static int rockchip_dfi_get_busier_ch(struct devfreq_event_dev *edev) + rockchip_dfi_stop_hardware_counter(edev); + + /* Find out which channel is busier */ +- for (i = 0; i < RK3399_DMC_NUM_CH; i++) { +- info->ch_usage[i].access = readl_relaxed(dfi_regs + +- DDRMON_CH0_DFI_ACCESS_NUM + i * 20) * 4; ++ for (i = 0; i < MAX_DMC_NUM_CH; i++) { ++ if (!(info->ch_msk & BIT(i))) ++ continue; ++ + info->ch_usage[i].total = readl_relaxed(dfi_regs + + DDRMON_CH0_COUNT_NUM + i * 20); +- tmp = info->ch_usage[i].access; ++ ++ /* LPDDR4 BL = 16,other DDR type BL = 8 */ ++ tmp = readl_relaxed(dfi_regs + ++ DDRMON_CH0_DFI_ACCESS_NUM + i * 20); ++ if (info->dram_type == LPDDR4) ++ tmp *= 8; ++ else ++ tmp *= 4; ++ info->ch_usage[i].access = tmp; ++ + if (tmp > max) { + busier_ch = i; + max = tmp; +@@ -121,7 +400,8 @@ static int rockchip_dfi_disable(struct devfreq_event_dev *edev) + struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); + + rockchip_dfi_stop_hardware_counter(edev); +- clk_disable_unprepare(info->clk); ++ if (info->clk) ++ clk_disable_unprepare(info->clk); + + return 0; + } +@@ -131,10 +411,13 @@ static int rockchip_dfi_enable(struct devfreq_event_dev *edev) + struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); + int ret; + +- ret = clk_prepare_enable(info->clk); +- if (ret) { +- dev_err(&edev->dev, "failed to enable dfi clk: %d\n", ret); +- return ret; ++ if (info->clk) { ++ ret = clk_prepare_enable(info->clk); ++ if (ret) { ++ dev_err(&edev->dev, "failed to enable dfi clk: %d\n", ++ ret); ++ return ret; ++ } + } + + rockchip_dfi_start_hardware_counter(edev); +@@ -151,8 +434,11 @@ static int rockchip_dfi_get_event(struct devfreq_event_dev *edev, + { + struct rockchip_dfi *info = devfreq_event_get_drvdata(edev); + int busier_ch; ++ unsigned long flags; + ++ local_irq_save(flags); + busier_ch = rockchip_dfi_get_busier_ch(edev); ++ local_irq_restore(flags); + + edata->load_count = info->ch_usage[busier_ch].access; + edata->total_count = info->ch_usage[busier_ch].total; +@@ -167,23 +453,117 @@ static const struct devfreq_event_ops rockchip_dfi_ops = { + .set_event = rockchip_dfi_set_event, + }; + +-static const struct of_device_id rockchip_dfi_id_match[] = { +- { .compatible = "rockchip,rk3399-dfi" }, +- { }, +-}; +-MODULE_DEVICE_TABLE(of, rockchip_dfi_id_match); ++static __init int px30_dfi_init(struct platform_device *pdev, ++ struct rockchip_dfi *data, ++ struct devfreq_event_desc *desc) ++{ ++ struct device_node *np = pdev->dev.of_node, *node; ++ struct resource *res; ++ u32 val; + +-static int rockchip_dfi_probe(struct platform_device *pdev) ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ data->regs = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(data->regs)) ++ return PTR_ERR(data->regs); ++ ++ node = of_parse_phandle(np, "rockchip,pmugrf", 0); ++ if (node) { ++ data->regmap_pmugrf = syscon_node_to_regmap(node); ++ if (IS_ERR(data->regmap_pmugrf)) ++ return PTR_ERR(data->regmap_pmugrf); ++ } ++ ++ regmap_read(data->regmap_pmugrf, PX30_PMUGRF_OS_REG2, &val); ++ data->dram_type = READ_DRAMTYPE_INFO(val); ++ data->ch_msk = 1; ++ data->clk = NULL; ++ ++ desc->ops = &rockchip_dfi_ops; ++ ++ return 0; ++} ++ ++static __init int rk3128_dfi_init(struct platform_device *pdev, ++ struct rockchip_dfi *data, ++ struct devfreq_event_desc *desc) ++{ ++ struct device_node *np = pdev->dev.of_node, *node; ++ ++ node = of_parse_phandle(np, "rockchip,grf", 0); ++ if (node) { ++ data->regmap_grf = syscon_node_to_regmap(node); ++ if (IS_ERR(data->regmap_grf)) ++ return PTR_ERR(data->regmap_grf); ++ } ++ ++ desc->ops = &rk3128_dfi_ops; ++ ++ return 0; ++} ++ ++static __init int rk3288_dfi_init(struct platform_device *pdev, ++ struct rockchip_dfi *data, ++ struct devfreq_event_desc *desc) ++{ ++ struct device_node *np = pdev->dev.of_node, *node; ++ u32 val; ++ ++ node = of_parse_phandle(np, "rockchip,pmu", 0); ++ if (node) { ++ data->regmap_pmu = syscon_node_to_regmap(node); ++ if (IS_ERR(data->regmap_pmu)) ++ return PTR_ERR(data->regmap_pmu); ++ } ++ ++ node = of_parse_phandle(np, "rockchip,grf", 0); ++ if (node) { ++ data->regmap_grf = syscon_node_to_regmap(node); ++ if (IS_ERR(data->regmap_grf)) ++ return PTR_ERR(data->regmap_grf); ++ } ++ ++ regmap_read(data->regmap_pmu, RK3288_PMU_SYS_REG2, &val); ++ data->dram_type = READ_DRAMTYPE_INFO(val); ++ data->ch_msk = READ_CH_INFO(val); ++ ++ if (data->dram_type == DDR3) ++ regmap_write(data->regmap_grf, RK3288_GRF_SOC_CON4, ++ RK3288_DDR3_SEL); ++ else ++ regmap_write(data->regmap_grf, RK3288_GRF_SOC_CON4, ++ RK3288_LPDDR_SEL); ++ ++ desc->ops = &rk3288_dfi_ops; ++ ++ return 0; ++} ++ ++static __init int rk3368_dfi_init(struct platform_device *pdev, ++ struct rockchip_dfi *data, ++ struct devfreq_event_desc *desc) ++{ ++ struct device *dev = &pdev->dev; ++ ++ if (!dev->parent || !dev->parent->of_node) ++ return -EINVAL; ++ ++ data->regmap_grf = syscon_node_to_regmap(dev->parent->of_node); ++ if (IS_ERR(data->regmap_grf)) ++ return PTR_ERR(data->regmap_grf); ++ ++ desc->ops = &rk3368_dfi_ops; ++ ++ return 0; ++} ++ ++static __init int rockchip_dfi_init(struct platform_device *pdev, ++ struct rockchip_dfi *data, ++ struct devfreq_event_desc *desc) + { + struct device *dev = &pdev->dev; +- struct rockchip_dfi *data; + struct resource *res; +- struct devfreq_event_desc *desc; + struct device_node *np = pdev->dev.of_node, *node; +- +- data = devm_kzalloc(dev, sizeof(struct rockchip_dfi), GFP_KERNEL); +- if (!data) +- return -ENOMEM; ++ u32 val; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + data->regs = devm_ioremap_resource(&pdev->dev, res); +@@ -203,21 +583,97 @@ static int rockchip_dfi_probe(struct platform_device *pdev) + if (IS_ERR(data->regmap_pmu)) + return PTR_ERR(data->regmap_pmu); + } +- data->dev = dev; ++ ++ regmap_read(data->regmap_pmu, PMUGRF_OS_REG2, &val); ++ data->dram_type = READ_DRAMTYPE_INFO(val); ++ data->ch_msk = READ_CH_INFO(val); ++ ++ desc->ops = &rockchip_dfi_ops; ++ ++ return 0; ++} ++ ++static __init int rk3328_dfi_init(struct platform_device *pdev, ++ struct rockchip_dfi *data, ++ struct devfreq_event_desc *desc) ++{ ++ struct device_node *np = pdev->dev.of_node, *node; ++ struct resource *res; ++ u32 val; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ data->regs = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(data->regs)) ++ return PTR_ERR(data->regs); ++ ++ node = of_parse_phandle(np, "rockchip,grf", 0); ++ if (node) { ++ data->regmap_grf = syscon_node_to_regmap(node); ++ if (IS_ERR(data->regmap_grf)) ++ return PTR_ERR(data->regmap_grf); ++ } ++ ++ regmap_read(data->regmap_grf, RK3328_GRF_OS_REG2, &val); ++ data->dram_type = READ_DRAMTYPE_INFO(val); ++ data->ch_msk = 1; ++ data->clk = NULL; ++ ++ desc->ops = &rockchip_dfi_ops; ++ ++ return 0; ++} ++ ++static const struct of_device_id rockchip_dfi_id_match[] = { ++ { .compatible = "rockchip,px30-dfi", .data = px30_dfi_init }, ++ { .compatible = "rockchip,rk1808-dfi", .data = px30_dfi_init }, ++ { .compatible = "rockchip,rk3128-dfi", .data = rk3128_dfi_init }, ++ { .compatible = "rockchip,rk3288-dfi", .data = rk3288_dfi_init }, ++ { .compatible = "rockchip,rk3328-dfi", .data = rk3328_dfi_init }, ++ { .compatible = "rockchip,rk3368-dfi", .data = rk3368_dfi_init }, ++ { .compatible = "rockchip,rk3399-dfi", .data = rockchip_dfi_init }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(of, rockchip_dfi_id_match); ++ ++static int rockchip_dfi_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct rockchip_dfi *data; ++ struct devfreq_event_desc *desc; ++ struct device_node *np = pdev->dev.of_node; ++ const struct of_device_id *match; ++ int (*init)(struct platform_device *pdev, struct rockchip_dfi *data, ++ struct devfreq_event_desc *desc); ++ ++ data = devm_kzalloc(dev, sizeof(struct rockchip_dfi), GFP_KERNEL); ++ if (!data) ++ return -ENOMEM; + + desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); + if (!desc) + return -ENOMEM; + +- desc->ops = &rockchip_dfi_ops; ++ match = of_match_node(rockchip_dfi_id_match, pdev->dev.of_node); ++ if (match) { ++ init = match->data; ++ if (init) { ++ if (init(pdev, data, desc)) ++ return -EINVAL; ++ } else { ++ return 0; ++ } ++ } else { ++ return 0; ++ } ++ + desc->driver_data = data; + desc->name = np->name; + data->desc = desc; ++ data->dev = dev; + +- data->edev = devm_devfreq_event_add_edev(&pdev->dev, desc); ++ data->edev = devm_devfreq_event_add_edev(dev, desc); + if (IS_ERR(data->edev)) { +- dev_err(&pdev->dev, +- "failed to add devfreq-event device\n"); ++ dev_err(dev, "failed to add devfreq-event device\n"); + return PTR_ERR(data->edev); + } diff --git a/target/linux/rockchip/patches-5.4/001-rk3328_fix_wrong_mmc_shift.patch b/target/linux/rockchip/patches-5.4/001-rk3328_fix_wrong_mmc_shift.patch new file mode 100644 index 000000000..de7a86671 --- /dev/null +++ b/target/linux/rockchip/patches-5.4/001-rk3328_fix_wrong_mmc_shift.patch @@ -0,0 +1,48 @@ +From 6376a1b0e30a1d30c4269083fb5b9a146a944ada Mon Sep 17 00:00:00 2001 +From: Ziyuan Xu +Date: Wed, 28 Nov 2018 17:39:50 +0800 +Subject: [PATCH] Revert "clk: rockchip: fix wrong mmc phase shift for rk3328" + +This reverts commit 4ef244988993afc8a6447e990a4ccb4a223d3f20. + +The description for CRU_EMMC/SDMMC/SDIO_CON[0/1] is jumble on +chapters, make it clear that the correct shift is 1 that from +IC engineer. + +Change-Id: I48dce293ec6ef82a5c78db38efc083227776ea99 +Signed-off-by: Ziyuan Xu +--- + drivers/clk/rockchip/clk-rk3328.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/clk/rockchip/clk-rk3328.c b/drivers/clk/rockchip/clk-rk3328.c +index ac6e6163a232..d77925271198 100644 +--- a/drivers/clk/rockchip/clk-rk3328.c ++++ b/drivers/clk/rockchip/clk-rk3328.c +@@ -808,22 +808,22 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = { + MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "clk_sdmmc", + RK3328_SDMMC_CON0, 1), + MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "clk_sdmmc", +- RK3328_SDMMC_CON1, 0), ++ RK3328_SDMMC_CON1, 1), + + MMC(SCLK_SDIO_DRV, "sdio_drv", "clk_sdio", + RK3328_SDIO_CON0, 1), + MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "clk_sdio", +- RK3328_SDIO_CON1, 0), ++ RK3328_SDIO_CON1, 1), + + MMC(SCLK_EMMC_DRV, "emmc_drv", "clk_emmc", + RK3328_EMMC_CON0, 1), + MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "clk_emmc", +- RK3328_EMMC_CON1, 0), ++ RK3328_EMMC_CON1, 1), + + MMC(SCLK_SDMMC_EXT_DRV, "sdmmc_ext_drv", "clk_sdmmc_ext", + RK3328_SDMMC_EXT_CON0, 1), + MMC(SCLK_SDMMC_EXT_SAMPLE, "sdmmc_ext_sample", "clk_sdmmc_ext", +- RK3328_SDMMC_EXT_CON1, 0), ++ RK3328_SDMMC_EXT_CON1, 1), + }; + + static const char *const rk3328_critical_clocks[] __initconst = { diff --git a/target/linux/rockchip/patches-5.4/002-add-rk3328-usb3-driver.patch b/target/linux/rockchip/patches-5.4/002-add-rk3328-usb3-driver.patch new file mode 100644 index 000000000..6a15af240 --- /dev/null +++ b/target/linux/rockchip/patches-5.4/002-add-rk3328-usb3-driver.patch @@ -0,0 +1,1424 @@ +Add the rockchip innosilicon usb3 phy driver, supporting devices such as the rk3328. +Pulled from: +https://github.com/FireflyTeam/kernel/blob/roc-rk3328-cc/drivers/phy/rockchip/phy-rockchip-inno-usb3.c + +Signed-off-by: Peter Geis +--- + drivers/phy/rockchip/Kconfig | 9 + + drivers/phy/rockchip/Makefile | 1 + + drivers/phy/rockchip/phy-rockchip-inno-usb3.c | 1107 +++++++++++++++++ + 3 files changed, 1117 insertions(+) + create mode 100644 drivers/phy/rockchip/phy-rockchip-inno-usb3.c + +diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig +index c454c90cd99e..766407939d4a 100644 +--- a/drivers/phy/rockchip/Kconfig ++++ b/drivers/phy/rockchip/Kconfig +@@ -35,6 +35,15 @@ config PHY_ROCKCHIP_INNO_USB2 + help + Support for Rockchip USB2.0 PHY with Innosilicon IP block. + ++config PHY_ROCKCHIP_INNO_USB3 ++ tristate "Rockchip INNO USB 3.0 PHY Driver" ++ depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF ++ depends on USB_SUPPORT ++ select GENERIC_PHY ++ select USB_PHY ++ help ++ Support for Rockchip USB 3.0 PHY with Innosilicon IP block. ++ + config PHY_ROCKCHIP_PCIE + tristate "Rockchip PCIe PHY Driver" + depends on (ARCH_ROCKCHIP && OF) || COMPILE_TEST +diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile +index fd21cbaf40dd..d7b3d16c19ae 100644 +--- a/drivers/phy/rockchip/Makefile ++++ b/drivers/phy/rockchip/Makefile +@@ -3,6 +3,7 @@ obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o + obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o + obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI) += phy-rockchip-inno-hdmi.o + obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o ++obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB3) += phy-rockchip-inno-usb3.o + obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o + obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o + obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o +diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb3.c b/drivers/phy/rockchip/phy-rockchip-inno-usb3.c +new file mode 100644 +index 000000000000..31fee8f3a705 +--- /dev/null ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb3.c +@@ -0,0 +1,1107 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * Rockchip USB 3.0 PHY with Innosilicon IP block driver ++ * ++ * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define U3PHY_PORT_NUM 2 ++#define BIT_WRITEABLE_SHIFT 16 ++#define SCHEDULE_DELAY (60 * HZ) ++ ++#define U3PHY_APB_RST BIT(0) ++#define U3PHY_POR_RST BIT(1) ++#define U3PHY_MAC_RST BIT(2) ++ ++struct rockchip_u3phy; ++struct rockchip_u3phy_port; ++ ++enum rockchip_u3phy_type { ++ U3PHY_TYPE_PIPE, ++ U3PHY_TYPE_UTMI, ++}; ++ ++enum rockchip_u3phy_pipe_pwr { ++ PIPE_PWR_P0 = 0, ++ PIPE_PWR_P1 = 1, ++ PIPE_PWR_P2 = 2, ++ PIPE_PWR_P3 = 3, ++ PIPE_PWR_MAX = 4, ++}; ++ ++enum rockchip_u3phy_rest_req { ++ U3_POR_RSTN = 0, ++ U2_POR_RSTN = 1, ++ PIPE_MAC_RSTN = 2, ++ UTMI_MAC_RSTN = 3, ++ PIPE_APB_RSTN = 4, ++ UTMI_APB_RSTN = 5, ++ U3PHY_RESET_MAX = 6, ++}; ++ ++enum rockchip_u3phy_utmi_state { ++ PHY_UTMI_HS_ONLINE = 0, ++ PHY_UTMI_DISCONNECT = 1, ++ PHY_UTMI_CONNECT = 2, ++ PHY_UTMI_FS_LS_ONLINE = 4, ++}; ++ ++/* ++ * @rvalue: reset value ++ * @dvalue: desired value ++ */ ++struct u3phy_reg { ++ unsigned int offset; ++ unsigned int bitend; ++ unsigned int bitstart; ++ unsigned int rvalue; ++ unsigned int dvalue; ++}; ++ ++struct rockchip_u3phy_grfcfg { ++ struct u3phy_reg um_suspend; ++ struct u3phy_reg ls_det_en; ++ struct u3phy_reg ls_det_st; ++ struct u3phy_reg um_ls; ++ struct u3phy_reg um_hstdct; ++ struct u3phy_reg u2_only_ctrl; ++ struct u3phy_reg u3_disable; ++ struct u3phy_reg pp_pwr_st; ++ struct u3phy_reg pp_pwr_en[PIPE_PWR_MAX]; ++}; ++ ++/** ++ * struct rockchip_u3phy_apbcfg: usb3-phy apb configuration. ++ * @u2_pre_emp: usb2-phy pre-emphasis tuning. ++ * @u2_pre_emp_sth: usb2-phy pre-emphasis strength tuning. ++ * @u2_odt_tuning: usb2-phy odt 45ohm tuning. ++ */ ++struct rockchip_u3phy_apbcfg { ++ unsigned int u2_pre_emp; ++ unsigned int u2_pre_emp_sth; ++ unsigned int u2_odt_tuning; ++}; ++ ++struct rockchip_u3phy_cfg { ++ unsigned int reg; ++ const struct rockchip_u3phy_grfcfg grfcfg; ++ ++ int (*phy_pipe_power)(struct rockchip_u3phy *u3phy, ++ struct rockchip_u3phy_port *u3phy_port, ++ bool on); ++ int (*phy_tuning)(struct rockchip_u3phy *u3phy, ++ struct rockchip_u3phy_port *u3phy_port, ++ struct device_node *child_np); ++}; ++ ++struct rockchip_u3phy_port { ++ struct phy *phy; ++ void __iomem *base; ++ unsigned int index; ++ unsigned char type; ++ bool suspended; ++ bool refclk_25m_quirk; ++ struct mutex mutex; /* mutex for updating register */ ++ struct delayed_work um_sm_work; ++}; ++ ++struct rockchip_u3phy { ++ struct device *dev; ++ struct regmap *u3phy_grf; ++ struct regmap *grf; ++ int um_ls_irq; ++ struct clk **clks; ++ int num_clocks; ++ struct dentry *root; ++ struct gpio_desc *vbus_drv_gpio; ++ struct reset_control *rsts[U3PHY_RESET_MAX]; ++ struct rockchip_u3phy_apbcfg apbcfg; ++ const struct rockchip_u3phy_cfg *cfgs; ++ struct rockchip_u3phy_port ports[U3PHY_PORT_NUM]; ++ struct usb_phy usb_phy; ++}; ++ ++static inline int param_write(void __iomem *base, ++ const struct u3phy_reg *reg, bool desired) ++{ ++ unsigned int val, mask; ++ unsigned int tmp = desired ? reg->dvalue : reg->rvalue; ++ int ret = 0; ++ ++ mask = GENMASK(reg->bitend, reg->bitstart); ++ val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT); ++ ret = regmap_write(base, reg->offset, val); ++ ++ return ret; ++} ++ ++static inline bool param_exped(void __iomem *base, ++ const struct u3phy_reg *reg, ++ unsigned int value) ++{ ++ int ret; ++ unsigned int tmp, orig; ++ unsigned int mask = GENMASK(reg->bitend, reg->bitstart); ++ ++ ret = regmap_read(base, reg->offset, &orig); ++ if (ret) ++ return false; ++ ++ tmp = (orig & mask) >> reg->bitstart; ++ return tmp == value; ++} ++ ++static int rockchip_u3phy_usb2_only_show(struct seq_file *s, void *unused) ++{ ++ struct rockchip_u3phy *u3phy = s->private; ++ ++ if (param_exped(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.u2_only_ctrl, 1)) ++ dev_info(u3phy->dev, "u2\n"); ++ else ++ dev_info(u3phy->dev, "u3\n"); ++ ++ return 0; ++} ++ ++static int rockchip_u3phy_usb2_only_open(struct inode *inode, ++ struct file *file) ++{ ++ return single_open(file, rockchip_u3phy_usb2_only_show, ++ inode->i_private); ++} ++ ++static ssize_t rockchip_u3phy_usb2_only_write(struct file *file, ++ const char __user *ubuf, ++ size_t count, loff_t *ppos) ++{ ++ struct seq_file *s = file->private_data; ++ struct rockchip_u3phy *u3phy = s->private; ++ struct rockchip_u3phy_port *u3phy_port; ++ char buf[32]; ++ u8 index; ++ ++ if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) ++ return -EFAULT; ++ ++ if (!strncmp(buf, "u3", 2) && ++ param_exped(u3phy->u3phy_grf, ++ &u3phy->cfgs->grfcfg.u2_only_ctrl, 1)) { ++ dev_info(u3phy->dev, "Set usb3.0 and usb2.0 mode successfully\n"); ++ ++ gpiod_set_value_cansleep(u3phy->vbus_drv_gpio, 0); ++ ++ param_write(u3phy->grf, ++ &u3phy->cfgs->grfcfg.u3_disable, false); ++ param_write(u3phy->u3phy_grf, ++ &u3phy->cfgs->grfcfg.u2_only_ctrl, false); ++ ++ for (index = 0; index < U3PHY_PORT_NUM; index++) { ++ u3phy_port = &u3phy->ports[index]; ++ /* enable u3 rx termimation */ ++ if (u3phy_port->type == U3PHY_TYPE_PIPE) ++ writel(0x30, u3phy_port->base + 0xd8); ++ } ++ ++ atomic_notifier_call_chain(&u3phy->usb_phy.notifier, 0, NULL); ++ ++ gpiod_set_value_cansleep(u3phy->vbus_drv_gpio, 1); ++ } else if (!strncmp(buf, "u2", 2) && ++ param_exped(u3phy->u3phy_grf, ++ &u3phy->cfgs->grfcfg.u2_only_ctrl, 0)) { ++ dev_info(u3phy->dev, "Set usb2.0 only mode successfully\n"); ++ ++ gpiod_set_value_cansleep(u3phy->vbus_drv_gpio, 0); ++ ++ param_write(u3phy->grf, ++ &u3phy->cfgs->grfcfg.u3_disable, true); ++ param_write(u3phy->u3phy_grf, ++ &u3phy->cfgs->grfcfg.u2_only_ctrl, true); ++ ++ for (index = 0; index < U3PHY_PORT_NUM; index++) { ++ u3phy_port = &u3phy->ports[index]; ++ /* disable u3 rx termimation */ ++ if (u3phy_port->type == U3PHY_TYPE_PIPE) ++ writel(0x20, u3phy_port->base + 0xd8); ++ } ++ ++ atomic_notifier_call_chain(&u3phy->usb_phy.notifier, 0, NULL); ++ ++ gpiod_set_value_cansleep(u3phy->vbus_drv_gpio, 1); ++ } else { ++ dev_info(u3phy->dev, "Same or illegal mode\n"); ++ } ++ ++ return count; ++} ++ ++static const struct file_operations rockchip_u3phy_usb2_only_fops = { ++ .open = rockchip_u3phy_usb2_only_open, ++ .write = rockchip_u3phy_usb2_only_write, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++int rockchip_u3phy_debugfs_init(struct rockchip_u3phy *u3phy) ++{ ++ struct dentry *root; ++ struct dentry *file; ++ int ret; ++ ++ root = debugfs_create_dir(dev_name(u3phy->dev), NULL); ++ if (!root) { ++ ret = -ENOMEM; ++ goto err0; ++ } ++ ++ u3phy->root = root; ++ ++ file = debugfs_create_file("u3phy_mode", 0644, root, ++ u3phy, &rockchip_u3phy_usb2_only_fops); ++ if (!file) { ++ ret = -ENOMEM; ++ goto err1; ++ } ++ return 0; ++ ++err1: ++ debugfs_remove_recursive(root); ++err0: ++ return ret; ++} ++ ++static const char *get_rest_name(enum rockchip_u3phy_rest_req rst) ++{ ++ switch (rst) { ++ case U2_POR_RSTN: ++ return "u3phy-u2-por"; ++ case U3_POR_RSTN: ++ return "u3phy-u3-por"; ++ case PIPE_MAC_RSTN: ++ return "u3phy-pipe-mac"; ++ case UTMI_MAC_RSTN: ++ return "u3phy-utmi-mac"; ++ case UTMI_APB_RSTN: ++ return "u3phy-utmi-apb"; ++ case PIPE_APB_RSTN: ++ return "u3phy-pipe-apb"; ++ default: ++ return "invalid"; ++ } ++} ++ ++static void rockchip_u3phy_rest_deassert(struct rockchip_u3phy *u3phy, ++ unsigned int flag) ++{ ++ int rst; ++ ++ if (flag & U3PHY_APB_RST) { ++ dev_dbg(u3phy->dev, "deassert APB bus interface reset\n"); ++ for (rst = PIPE_APB_RSTN; rst <= UTMI_APB_RSTN; rst++) { ++ if (u3phy->rsts[rst]) ++ reset_control_deassert(u3phy->rsts[rst]); ++ } ++ } ++ ++ if (flag & U3PHY_POR_RST) { ++ usleep_range(12, 15); ++ dev_dbg(u3phy->dev, "deassert u2 and u3 phy power on reset\n"); ++ for (rst = U3_POR_RSTN; rst <= U2_POR_RSTN; rst++) { ++ if (u3phy->rsts[rst]) ++ reset_control_deassert(u3phy->rsts[rst]); ++ } ++ } ++ ++ if (flag & U3PHY_MAC_RST) { ++ usleep_range(1200, 1500); ++ dev_dbg(u3phy->dev, "deassert pipe and utmi MAC reset\n"); ++ for (rst = PIPE_MAC_RSTN; rst <= UTMI_MAC_RSTN; rst++) ++ if (u3phy->rsts[rst]) ++ reset_control_deassert(u3phy->rsts[rst]); ++ } ++} ++ ++static void rockchip_u3phy_rest_assert(struct rockchip_u3phy *u3phy) ++{ ++ int rst; ++ ++ dev_dbg(u3phy->dev, "assert u3phy reset\n"); ++ for (rst = 0; rst < U3PHY_RESET_MAX; rst++) ++ if (u3phy->rsts[rst]) ++ reset_control_assert(u3phy->rsts[rst]); ++} ++ ++static int rockchip_u3phy_clk_enable(struct rockchip_u3phy *u3phy) ++{ ++ int ret, clk; ++ ++ for (clk = 0; clk < u3phy->num_clocks && u3phy->clks[clk]; clk++) { ++ ret = clk_prepare_enable(u3phy->clks[clk]); ++ if (ret) ++ goto err_disable_clks; ++ } ++ return 0; ++ ++err_disable_clks: ++ while (--clk >= 0) ++ clk_disable_unprepare(u3phy->clks[clk]); ++ return ret; ++} ++ ++static void rockchip_u3phy_clk_disable(struct rockchip_u3phy *u3phy) ++{ ++ int clk; ++ ++ for (clk = u3phy->num_clocks - 1; clk >= 0; clk--) ++ if (u3phy->clks[clk]) ++ clk_disable_unprepare(u3phy->clks[clk]); ++} ++ ++static int rockchip_u3phy_init(struct phy *phy) ++{ ++ return 0; ++} ++ ++static int rockchip_u3phy_exit(struct phy *phy) ++{ ++ return 0; ++} ++ ++static int rockchip_u3phy_power_on(struct phy *phy) ++{ ++ struct rockchip_u3phy_port *u3phy_port = phy_get_drvdata(phy); ++ struct rockchip_u3phy *u3phy = dev_get_drvdata(phy->dev.parent); ++ int ret; ++ ++ dev_info(&u3phy_port->phy->dev, "u3phy %s power on\n", ++ (u3phy_port->type == U3PHY_TYPE_UTMI) ? "u2" : "u3"); ++ ++ if (!u3phy_port->suspended) ++ return 0; ++ ++ ret = rockchip_u3phy_clk_enable(u3phy); ++ if (ret) ++ return ret; ++ ++ if (u3phy_port->type == U3PHY_TYPE_UTMI) { ++ param_write(u3phy->u3phy_grf, ++ &u3phy->cfgs->grfcfg.um_suspend, false); ++ } else { ++ /* current in p2 ? */ ++ if (param_exped(u3phy->u3phy_grf, ++ &u3phy->cfgs->grfcfg.pp_pwr_st, PIPE_PWR_P2)) ++ goto done; ++ ++ if (u3phy->cfgs->phy_pipe_power) { ++ dev_dbg(u3phy->dev, "do pipe power up\n"); ++ u3phy->cfgs->phy_pipe_power(u3phy, u3phy_port, true); ++ } ++ ++ /* exit to p0 */ ++ param_write(u3phy->u3phy_grf, ++ &u3phy->cfgs->grfcfg.pp_pwr_en[PIPE_PWR_P0], true); ++ usleep_range(90, 100); ++ ++ /* enter to p2 from p0 */ ++ param_write(u3phy->u3phy_grf, ++ &u3phy->cfgs->grfcfg.pp_pwr_en[PIPE_PWR_P2], ++ false); ++ udelay(3); ++ } ++ ++done: ++ u3phy_port->suspended = false; ++ return 0; ++} ++ ++static int rockchip_u3phy_power_off(struct phy *phy) ++{ ++ struct rockchip_u3phy_port *u3phy_port = phy_get_drvdata(phy); ++ struct rockchip_u3phy *u3phy = dev_get_drvdata(phy->dev.parent); ++ ++ dev_info(&u3phy_port->phy->dev, "u3phy %s power off\n", ++ (u3phy_port->type == U3PHY_TYPE_UTMI) ? "u2" : "u3"); ++ ++ if (u3phy_port->suspended) ++ return 0; ++ ++ if (u3phy_port->type == U3PHY_TYPE_UTMI) { ++ param_write(u3phy->u3phy_grf, ++ &u3phy->cfgs->grfcfg.um_suspend, true); ++ } else { ++ /* current in p3 ? */ ++ if (param_exped(u3phy->u3phy_grf, ++ &u3phy->cfgs->grfcfg.pp_pwr_st, PIPE_PWR_P3)) ++ goto done; ++ ++ /* exit to p0 */ ++ param_write(u3phy->u3phy_grf, ++ &u3phy->cfgs->grfcfg.pp_pwr_en[PIPE_PWR_P0], true); ++ udelay(2); ++ ++ /* enter to p3 from p0 */ ++ param_write(u3phy->u3phy_grf, ++ &u3phy->cfgs->grfcfg.pp_pwr_en[PIPE_PWR_P3], true); ++ udelay(6); ++ ++ if (u3phy->cfgs->phy_pipe_power) { ++ dev_dbg(u3phy->dev, "do pipe power down\n"); ++ u3phy->cfgs->phy_pipe_power(u3phy, u3phy_port, false); ++ } ++ } ++ ++done: ++ rockchip_u3phy_clk_disable(u3phy); ++ u3phy_port->suspended = true; ++ return 0; ++} ++ ++static __maybe_unused ++struct phy *rockchip_u3phy_xlate(struct device *dev, ++ struct of_phandle_args *args) ++{ ++ struct rockchip_u3phy *u3phy = dev_get_drvdata(dev); ++ struct rockchip_u3phy_port *u3phy_port = NULL; ++ struct device_node *phy_np = args->np; ++ int index; ++ ++ if (args->args_count != 1) { ++ dev_err(dev, "invalid number of cells in 'phy' property\n"); ++ return ERR_PTR(-EINVAL); ++ } ++ ++ for (index = 0; index < U3PHY_PORT_NUM; index++) { ++ if (phy_np == u3phy->ports[index].phy->dev.of_node) { ++ u3phy_port = &u3phy->ports[index]; ++ break; ++ } ++ } ++ ++ if (!u3phy_port) { ++ dev_err(dev, "failed to find appropriate phy\n"); ++ return ERR_PTR(-EINVAL); ++ } ++ ++ return u3phy_port->phy; ++} ++ ++static struct phy_ops rockchip_u3phy_ops = { ++ .init = rockchip_u3phy_init, ++ .exit = rockchip_u3phy_exit, ++ .power_on = rockchip_u3phy_power_on, ++ .power_off = rockchip_u3phy_power_off, ++ .owner = THIS_MODULE, ++}; ++ ++/* ++ * The function manage host-phy port state and suspend/resume phy port ++ * to save power automatically. ++ * ++ * we rely on utmi_linestate and utmi_hostdisconnect to identify whether ++ * devices is disconnect or not. Besides, we do not need care it is FS/LS ++ * disconnected or HS disconnected, actually, we just only need get the ++ * device is disconnected at last through rearm the delayed work, ++ * to suspend the phy port in _PHY_STATE_DISCONNECT_ case. ++ */ ++static void rockchip_u3phy_um_sm_work(struct work_struct *work) ++{ ++ struct rockchip_u3phy_port *u3phy_port = ++ container_of(work, struct rockchip_u3phy_port, um_sm_work.work); ++ struct rockchip_u3phy *u3phy = ++ dev_get_drvdata(u3phy_port->phy->dev.parent); ++ unsigned int sh = u3phy->cfgs->grfcfg.um_hstdct.bitend - ++ u3phy->cfgs->grfcfg.um_hstdct.bitstart + 1; ++ unsigned int ul, uhd, state; ++ unsigned int ul_mask, uhd_mask; ++ int ret; ++ ++ mutex_lock(&u3phy_port->mutex); ++ ++ ret = regmap_read(u3phy->u3phy_grf, ++ u3phy->cfgs->grfcfg.um_ls.offset, &ul); ++ if (ret < 0) ++ goto next_schedule; ++ ++ ret = regmap_read(u3phy->u3phy_grf, ++ u3phy->cfgs->grfcfg.um_hstdct.offset, &uhd); ++ if (ret < 0) ++ goto next_schedule; ++ ++ uhd_mask = GENMASK(u3phy->cfgs->grfcfg.um_hstdct.bitend, ++ u3phy->cfgs->grfcfg.um_hstdct.bitstart); ++ ul_mask = GENMASK(u3phy->cfgs->grfcfg.um_ls.bitend, ++ u3phy->cfgs->grfcfg.um_ls.bitstart); ++ ++ /* stitch on um_ls and um_hstdct as phy state */ ++ state = ((uhd & uhd_mask) >> u3phy->cfgs->grfcfg.um_hstdct.bitstart) | ++ (((ul & ul_mask) >> u3phy->cfgs->grfcfg.um_ls.bitstart) << sh); ++ ++ switch (state) { ++ case PHY_UTMI_HS_ONLINE: ++ dev_dbg(&u3phy_port->phy->dev, "HS online\n"); ++ break; ++ case PHY_UTMI_FS_LS_ONLINE: ++ /* ++ * For FS/LS device, the online state share with connect state ++ * from um_ls and um_hstdct register, so we distinguish ++ * them via suspended flag. ++ * ++ * Plus, there are two cases, one is D- Line pull-up, and D+ ++ * line pull-down, the state is 4; another is D+ line pull-up, ++ * and D- line pull-down, the state is 2. ++ */ ++ if (!u3phy_port->suspended) { ++ /* D- line pull-up, D+ line pull-down */ ++ dev_dbg(&u3phy_port->phy->dev, "FS/LS online\n"); ++ break; ++ } ++ /* fall through */ ++ case PHY_UTMI_CONNECT: ++ if (u3phy_port->suspended) { ++ dev_dbg(&u3phy_port->phy->dev, "Connected\n"); ++ rockchip_u3phy_power_on(u3phy_port->phy); ++ u3phy_port->suspended = false; ++ } else { ++ /* D+ line pull-up, D- line pull-down */ ++ dev_dbg(&u3phy_port->phy->dev, "FS/LS online\n"); ++ } ++ break; ++ case PHY_UTMI_DISCONNECT: ++ if (!u3phy_port->suspended) { ++ dev_dbg(&u3phy_port->phy->dev, "Disconnected\n"); ++ rockchip_u3phy_power_off(u3phy_port->phy); ++ u3phy_port->suspended = true; ++ } ++ ++ /* ++ * activate the linestate detection to get the next device ++ * plug-in irq. ++ */ ++ param_write(u3phy->u3phy_grf, ++ &u3phy->cfgs->grfcfg.ls_det_st, true); ++ param_write(u3phy->u3phy_grf, ++ &u3phy->cfgs->grfcfg.ls_det_en, true); ++ ++ /* ++ * we don't need to rearm the delayed work when the phy port ++ * is suspended. ++ */ ++ mutex_unlock(&u3phy_port->mutex); ++ return; ++ default: ++ dev_dbg(&u3phy_port->phy->dev, "unknown phy state\n"); ++ break; ++ } ++ ++next_schedule: ++ mutex_unlock(&u3phy_port->mutex); ++ schedule_delayed_work(&u3phy_port->um_sm_work, SCHEDULE_DELAY); ++} ++ ++static irqreturn_t rockchip_u3phy_um_ls_irq(int irq, void *data) ++{ ++ struct rockchip_u3phy_port *u3phy_port = data; ++ struct rockchip_u3phy *u3phy = ++ dev_get_drvdata(u3phy_port->phy->dev.parent); ++ ++ if (!param_exped(u3phy->u3phy_grf, ++ &u3phy->cfgs->grfcfg.ls_det_st, ++ u3phy->cfgs->grfcfg.ls_det_st.dvalue)) ++ return IRQ_NONE; ++ ++ dev_dbg(u3phy->dev, "utmi linestate interrupt\n"); ++ mutex_lock(&u3phy_port->mutex); ++ ++ /* disable linestate detect irq and clear its status */ ++ param_write(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.ls_det_en, false); ++ param_write(u3phy->u3phy_grf, &u3phy->cfgs->grfcfg.ls_det_st, true); ++ ++ mutex_unlock(&u3phy_port->mutex); ++ ++ /* ++ * In this case for host phy, a new device is plugged in, meanwhile, ++ * if the phy port is suspended, we need rearm the work to resume it ++ * and mange its states; otherwise, we just return irq handled. ++ */ ++ if (u3phy_port->suspended) { ++ dev_dbg(u3phy->dev, "schedule utmi sm work\n"); ++ rockchip_u3phy_um_sm_work(&u3phy_port->um_sm_work.work); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static int rockchip_u3phy_parse_dt(struct rockchip_u3phy *u3phy, ++ struct platform_device *pdev) ++ ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node; ++ int ret, i, clk; ++ ++ u3phy->um_ls_irq = platform_get_irq_byname(pdev, "linestate"); ++ if (u3phy->um_ls_irq < 0) { ++ dev_err(dev, "get utmi linestate irq failed\n"); ++ return -ENXIO; ++ } ++ ++ u3phy->vbus_drv_gpio = devm_gpiod_get_optional(dev, "vbus-drv", ++ GPIOD_OUT_HIGH); ++ ++ if (!u3phy->vbus_drv_gpio) { ++ dev_warn(&pdev->dev, "vbus_drv is not assigned\n"); ++ } else if (IS_ERR(u3phy->vbus_drv_gpio)) { ++ dev_err(&pdev->dev, "failed to get vbus_drv\n"); ++ return PTR_ERR(u3phy->vbus_drv_gpio); ++ } ++ ++ u3phy->num_clocks = of_clk_get_parent_count(np); ++ if (u3phy->num_clocks == 0) ++ dev_warn(&pdev->dev, "no clks found in dt\n"); ++ ++ u3phy->clks = devm_kcalloc(dev, u3phy->num_clocks, ++ sizeof(struct clk *), GFP_KERNEL); ++ ++ for (clk = 0; clk < u3phy->num_clocks; clk++) { ++ u3phy->clks[clk] = of_clk_get(np, clk); ++ if (IS_ERR(u3phy->clks[clk])) { ++ ret = PTR_ERR(u3phy->clks[clk]); ++ if (ret == -EPROBE_DEFER) ++ goto err_put_clks; ++ dev_err(&pdev->dev, "failed to get clks, %i\n", ++ ret); ++ u3phy->clks[clk] = NULL; ++ break; ++ } ++ } ++ ++ for (i = 0; i < U3PHY_RESET_MAX; i++) { ++ u3phy->rsts[i] = devm_reset_control_get(dev, get_rest_name(i)); ++ if (IS_ERR(u3phy->rsts[i])) { ++ dev_info(dev, "no %s reset control specified\n", ++ get_rest_name(i)); ++ u3phy->rsts[i] = NULL; ++ } ++ } ++ ++ return 0; ++ ++err_put_clks: ++ while (--clk >= 0) ++ clk_put(u3phy->clks[clk]); ++ return ret; ++} ++ ++static int rockchip_u3phy_port_init(struct rockchip_u3phy *u3phy, ++ struct rockchip_u3phy_port *u3phy_port, ++ struct device_node *child_np) ++{ ++ struct resource res; ++ struct phy *phy; ++ int ret; ++ ++ dev_dbg(u3phy->dev, "u3phy port initialize\n"); ++ ++ mutex_init(&u3phy_port->mutex); ++ u3phy_port->suspended = true; /* initial status */ ++ ++ phy = devm_phy_create(u3phy->dev, child_np, &rockchip_u3phy_ops); ++ if (IS_ERR(phy)) { ++ dev_err(u3phy->dev, "failed to create phy\n"); ++ return PTR_ERR(phy); ++ } ++ ++ u3phy_port->phy = phy; ++ ++ ret = of_address_to_resource(child_np, 0, &res); ++ if (ret) { ++ dev_err(u3phy->dev, "failed to get address resource(np-%s)\n", ++ child_np->name); ++ return ret; ++ } ++ ++ u3phy_port->base = devm_ioremap_resource(&u3phy_port->phy->dev, &res); ++ if (IS_ERR(u3phy_port->base)) { ++ dev_err(u3phy->dev, "failed to remap phy regs\n"); ++ return PTR_ERR(u3phy_port->base); ++ } ++ ++ if (!of_node_cmp(child_np->name, "pipe")) { ++ u3phy_port->type = U3PHY_TYPE_PIPE; ++ u3phy_port->refclk_25m_quirk = ++ of_property_read_bool(child_np, ++ "rockchip,refclk-25m-quirk"); ++ } else { ++ u3phy_port->type = U3PHY_TYPE_UTMI; ++ INIT_DELAYED_WORK(&u3phy_port->um_sm_work, ++ rockchip_u3phy_um_sm_work); ++ ++ ret = devm_request_threaded_irq(u3phy->dev, u3phy->um_ls_irq, ++ NULL, rockchip_u3phy_um_ls_irq, ++ IRQF_ONESHOT, "rockchip_u3phy", ++ u3phy_port); ++ if (ret) { ++ dev_err(u3phy->dev, "failed to request utmi linestate irq handle\n"); ++ return ret; ++ } ++ } ++ ++ if (u3phy->cfgs->phy_tuning) { ++ dev_dbg(u3phy->dev, "do u3phy tuning\n"); ++ ret = u3phy->cfgs->phy_tuning(u3phy, u3phy_port, child_np); ++ if (ret) ++ return ret; ++ } ++ ++ phy_set_drvdata(u3phy_port->phy, u3phy_port); ++ return 0; ++} ++ ++static int rockchip_u3phy_on_init(struct usb_phy *usb_phy) ++{ ++ struct rockchip_u3phy *u3phy = ++ container_of(usb_phy, struct rockchip_u3phy, usb_phy); ++ ++ rockchip_u3phy_rest_deassert(u3phy, U3PHY_POR_RST | U3PHY_MAC_RST); ++ return 0; ++} ++ ++static void rockchip_u3phy_on_shutdown(struct usb_phy *usb_phy) ++{ ++ struct rockchip_u3phy *u3phy = ++ container_of(usb_phy, struct rockchip_u3phy, usb_phy); ++ int rst; ++ ++ for (rst = 0; rst < U3PHY_RESET_MAX; rst++) ++ if (u3phy->rsts[rst] && rst != UTMI_APB_RSTN && ++ rst != PIPE_APB_RSTN) ++ reset_control_assert(u3phy->rsts[rst]); ++ udelay(1); ++} ++ ++static int rockchip_u3phy_on_disconnect(struct usb_phy *usb_phy, ++ enum usb_device_speed speed) ++{ ++ struct rockchip_u3phy *u3phy = ++ container_of(usb_phy, struct rockchip_u3phy, usb_phy); ++ ++ dev_info(u3phy->dev, "%s device has disconnected\n", ++ (speed == USB_SPEED_SUPER) ? "U3" : "UW/U2/U1.1/U1"); ++ ++ if (speed == USB_SPEED_SUPER) ++ atomic_notifier_call_chain(&usb_phy->notifier, 0, NULL); ++ ++ return 0; ++} ++ ++static int rockchip_u3phy_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node; ++ struct device_node *child_np; ++ struct phy_provider *provider; ++ struct rockchip_u3phy *u3phy; ++ const struct rockchip_u3phy_cfg *phy_cfgs; ++ const struct of_device_id *match; ++ unsigned int reg[2]; ++ int index, ret; ++ ++ match = of_match_device(dev->driver->of_match_table, dev); ++ if (!match || !match->data) { ++ dev_err(dev, "phy-cfgs are not assigned!\n"); ++ return -EINVAL; ++ } ++ ++ u3phy = devm_kzalloc(dev, sizeof(*u3phy), GFP_KERNEL); ++ if (!u3phy) ++ return -ENOMEM; ++ ++ u3phy->u3phy_grf = ++ syscon_regmap_lookup_by_phandle(np, "rockchip,u3phygrf"); ++ if (IS_ERR(u3phy->u3phy_grf)) ++ return PTR_ERR(u3phy->u3phy_grf); ++ ++ u3phy->grf = ++ syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); ++ if (IS_ERR(u3phy->grf)) { ++ dev_err(dev, "Missing rockchip,grf property\n"); ++ return PTR_ERR(u3phy->grf); ++ } ++ ++ if (of_property_read_u32_array(np, "reg", reg, 2)) { ++ dev_err(dev, "the reg property is not assigned in %s node\n", ++ np->name); ++ return -EINVAL; ++ } ++ ++ u3phy->dev = dev; ++ phy_cfgs = match->data; ++ platform_set_drvdata(pdev, u3phy); ++ ++ /* find out a proper config which can be matched with dt. */ ++ index = 0; ++ while (phy_cfgs[index].reg) { ++ if (phy_cfgs[index].reg == reg[1]) { ++ u3phy->cfgs = &phy_cfgs[index]; ++ break; ++ } ++ ++ ++index; ++ } ++ ++ if (!u3phy->cfgs) { ++ dev_err(dev, "no phy-cfgs can be matched with %s node\n", ++ np->name); ++ return -EINVAL; ++ } ++ ++ ret = rockchip_u3phy_parse_dt(u3phy, pdev); ++ if (ret) { ++ dev_err(dev, "parse dt failed, ret(%d)\n", ret); ++ return ret; ++ } ++ ++ ret = rockchip_u3phy_clk_enable(u3phy); ++ if (ret) { ++ dev_err(dev, "clk enable failed, ret(%d)\n", ret); ++ return ret; ++ } ++ ++ rockchip_u3phy_rest_assert(u3phy); ++ rockchip_u3phy_rest_deassert(u3phy, U3PHY_APB_RST | U3PHY_POR_RST); ++ ++ index = 0; ++ for_each_available_child_of_node(np, child_np) { ++ struct rockchip_u3phy_port *u3phy_port = &u3phy->ports[index]; ++ ++ u3phy_port->index = index; ++ ret = rockchip_u3phy_port_init(u3phy, u3phy_port, child_np); ++ if (ret) { ++ dev_err(dev, "u3phy port init failed,ret(%d)\n", ret); ++ goto put_child; ++ } ++ ++ /* to prevent out of boundary */ ++ if (++index >= U3PHY_PORT_NUM) ++ break; ++ } ++ ++ provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); ++ if (IS_ERR_OR_NULL(provider)) ++ goto put_child; ++ ++ rockchip_u3phy_rest_deassert(u3phy, U3PHY_MAC_RST); ++ rockchip_u3phy_clk_disable(u3phy); ++ ++ u3phy->usb_phy.dev = dev; ++ u3phy->usb_phy.init = rockchip_u3phy_on_init; ++ u3phy->usb_phy.shutdown = rockchip_u3phy_on_shutdown; ++ u3phy->usb_phy.notify_disconnect = rockchip_u3phy_on_disconnect; ++ usb_add_phy(&u3phy->usb_phy, USB_PHY_TYPE_USB3); ++ ATOMIC_INIT_NOTIFIER_HEAD(&u3phy->usb_phy.notifier); ++ ++ rockchip_u3phy_debugfs_init(u3phy); ++ ++ dev_info(dev, "Rockchip u3phy initialized successfully\n"); ++ return 0; ++ ++put_child: ++ of_node_put(child_np); ++ return ret; ++} ++ ++static int rk3328_u3phy_pipe_power(struct rockchip_u3phy *u3phy, ++ struct rockchip_u3phy_port *u3phy_port, ++ bool on) ++{ ++ unsigned int reg; ++ ++ if (on) { ++ reg = readl(u3phy_port->base + 0x1a8); ++ reg &= ~BIT(4); /* ldo power up */ ++ writel(reg, u3phy_port->base + 0x1a8); ++ ++ reg = readl(u3phy_port->base + 0x044); ++ reg &= ~BIT(4); /* bg power on */ ++ writel(reg, u3phy_port->base + 0x044); ++ ++ reg = readl(u3phy_port->base + 0x150); ++ reg |= BIT(6); /* tx bias enable */ ++ writel(reg, u3phy_port->base + 0x150); ++ ++ reg = readl(u3phy_port->base + 0x080); ++ reg &= ~BIT(2); /* tx cm power up */ ++ writel(reg, u3phy_port->base + 0x080); ++ ++ reg = readl(u3phy_port->base + 0x0c0); ++ /* tx obs enable and rx cm enable */ ++ reg |= (BIT(3) | BIT(4)); ++ writel(reg, u3phy_port->base + 0x0c0); ++ ++ udelay(1); ++ } else { ++ reg = readl(u3phy_port->base + 0x1a8); ++ reg |= BIT(4); /* ldo power down */ ++ writel(reg, u3phy_port->base + 0x1a8); ++ ++ reg = readl(u3phy_port->base + 0x044); ++ reg |= BIT(4); /* bg power down */ ++ writel(reg, u3phy_port->base + 0x044); ++ ++ reg = readl(u3phy_port->base + 0x150); ++ reg &= ~BIT(6); /* tx bias disable */ ++ writel(reg, u3phy_port->base + 0x150); ++ ++ reg = readl(u3phy_port->base + 0x080); ++ reg |= BIT(2); /* tx cm power down */ ++ writel(reg, u3phy_port->base + 0x080); ++ ++ reg = readl(u3phy_port->base + 0x0c0); ++ /* tx obs disable and rx cm disable */ ++ reg &= ~(BIT(3) | BIT(4)); ++ writel(reg, u3phy_port->base + 0x0c0); ++ } ++ ++ return 0; ++} ++ ++static int rk3328_u3phy_tuning(struct rockchip_u3phy *u3phy, ++ struct rockchip_u3phy_port *u3phy_port, ++ struct device_node *child_np) ++{ ++ if (u3phy_port->type == U3PHY_TYPE_UTMI) { ++ /* ++ * For rk3328 SoC, pre-emphasis and pre-emphasis strength must ++ * be written as one fixed value as below. ++ * ++ * Dissimilarly, the odt 45ohm value should be flexibly tuninged ++ * for the different boards to adjust HS eye height, so its ++ * value can be assigned in DT in code design. ++ */ ++ ++ /* {bits[2:0]=111}: always enable pre-emphasis */ ++ u3phy->apbcfg.u2_pre_emp = 0x0f; ++ ++ /* {bits[5:3]=000}: pre-emphasis strength as the weakest */ ++ u3phy->apbcfg.u2_pre_emp_sth = 0x41; ++ ++ /* {bits[4:0]=10101}: odt 45ohm tuning */ ++ u3phy->apbcfg.u2_odt_tuning = 0xb5; ++ /* optional override of the odt 45ohm tuning */ ++ of_property_read_u32(child_np, "rockchip,odt-val-tuning", ++ &u3phy->apbcfg.u2_odt_tuning); ++ ++ writel(u3phy->apbcfg.u2_pre_emp, u3phy_port->base + 0x030); ++ writel(u3phy->apbcfg.u2_pre_emp_sth, u3phy_port->base + 0x040); ++ writel(u3phy->apbcfg.u2_odt_tuning, u3phy_port->base + 0x11c); ++ } else if (u3phy_port->type == U3PHY_TYPE_PIPE) { ++ if (u3phy_port->refclk_25m_quirk) { ++ dev_dbg(u3phy->dev, "switch to 25m refclk\n"); ++ /* ref clk switch to 25M */ ++ writel(0x64, u3phy_port->base + 0x11c); ++ writel(0x64, u3phy_port->base + 0x028); ++ writel(0x01, u3phy_port->base + 0x020); ++ writel(0x21, u3phy_port->base + 0x030); ++ writel(0x06, u3phy_port->base + 0x108); ++ writel(0x00, u3phy_port->base + 0x118); ++ } else { ++ /* configure for 24M ref clk */ ++ writel(0x80, u3phy_port->base + 0x10c); ++ writel(0x01, u3phy_port->base + 0x118); ++ writel(0x38, u3phy_port->base + 0x11c); ++ writel(0x83, u3phy_port->base + 0x020); ++ writel(0x02, u3phy_port->base + 0x108); ++ } ++ ++ /* Enable SSC */ ++ udelay(3); ++ writel(0x08, u3phy_port->base + 0x000); ++ writel(0x0c, u3phy_port->base + 0x120); ++ ++ /* Tuning Rx for compliance RJTL test */ ++ writel(0x70, u3phy_port->base + 0x150); ++ writel(0x12, u3phy_port->base + 0x0c8); ++ writel(0x05, u3phy_port->base + 0x148); ++ writel(0x08, u3phy_port->base + 0x068); ++ writel(0xf0, u3phy_port->base + 0x1c4); ++ writel(0xff, u3phy_port->base + 0x070); ++ writel(0x0f, u3phy_port->base + 0x06c); ++ writel(0xe0, u3phy_port->base + 0x060); ++ ++ /* ++ * Tuning Tx to increase the bias current ++ * used in TX driver and RX EQ, it can ++ * also increase the voltage of LFPS. ++ */ ++ writel(0x08, u3phy_port->base + 0x180); ++ } else { ++ dev_err(u3phy->dev, "invalid u3phy port type\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static const struct rockchip_u3phy_cfg rk3328_u3phy_cfgs[] = { ++ { ++ .reg = 0xff470000, ++ .grfcfg = { ++ .um_suspend = { 0x0004, 15, 0, 0x1452, 0x15d1 }, ++ .u2_only_ctrl = { 0x0020, 15, 15, 0, 1 }, ++ .um_ls = { 0x0030, 5, 4, 0, 1 }, ++ .um_hstdct = { 0x0030, 7, 7, 0, 1 }, ++ .ls_det_en = { 0x0040, 0, 0, 0, 1 }, ++ .ls_det_st = { 0x0044, 0, 0, 0, 1 }, ++ .pp_pwr_st = { 0x0034, 14, 13, 0, 0}, ++ .pp_pwr_en = { {0x0020, 14, 0, 0x0014, 0x0005}, ++ {0x0020, 14, 0, 0x0014, 0x000d}, ++ {0x0020, 14, 0, 0x0014, 0x0015}, ++ {0x0020, 14, 0, 0x0014, 0x001d} }, ++ .u3_disable = { 0x04c4, 15, 0, 0x1100, 0x101}, ++ }, ++ .phy_pipe_power = rk3328_u3phy_pipe_power, ++ .phy_tuning = rk3328_u3phy_tuning, ++ }, ++ { /* sentinel */ } ++}; ++ ++static const struct of_device_id rockchip_u3phy_dt_match[] = { ++ { .compatible = "rockchip,rk3328-u3phy", .data = &rk3328_u3phy_cfgs }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, rockchip_u3phy_dt_match); ++ ++static struct platform_driver rockchip_u3phy_driver = { ++ .probe = rockchip_u3phy_probe, ++ .driver = { ++ .name = "rockchip-u3phy", ++ .of_match_table = rockchip_u3phy_dt_match, ++ }, ++}; ++module_platform_driver(rockchip_u3phy_driver); ++ ++MODULE_AUTHOR("Frank Wang "); ++MODULE_AUTHOR("William Wu "); ++MODULE_DESCRIPTION("Rockchip USB 3.0 PHY driver"); ++MODULE_LICENSE("GPL v2"); + +diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb3.yaml b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb3.yaml +new file mode 100644 +index 000000000000..f4f28625173a +--- /dev/null ++++ b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb3.yaml +@@ -0,0 +1,157 @@ ++# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: "http://devicetree.org/schemas/phy/phy-rockchip-inno-usb3.yaml#" ++$schema: "http://devicetree.org/meta-schemas/core.yaml#" ++ ++title: ROCKCHIP USB 3.0 PHY WITH INNO IP BLOCK ++ ++maintainers: ++ ++properties: ++ compatible: ++ enum: ++ - rockchip,rk3328-u3phy ++ ++ reg: ++ - description: the base address of the USB 3.0 PHY ++ ++ interrupts: ++ maxItems: 1 ++ ++ interrupt-names: ++ items: ++ - const: linestate ++ description: host/otg linestate interrupt ++ ++ clocks: ++ maxItems: 2 ++ ++ clock-names: ++ items: ++ - const: u3phy-otg ++ description: USB 3.0 PHY UTMI ++ - const: u3phy-pipe ++ description: USB 3.0 PHY Pipe ++ ++ resets: ++ maxItems: 6 ++ ++ reset-names: ++ items: ++ - const: u3phy-u2-por ++ description: USB 2.0 logic of USB 3.0 PHY ++ - const: u3phy-u3-por ++ description: USB 3.0 logic of USB 3.0 PHY ++ - const: u3phy-pipe-mac ++ description: USB 3.0 PHY pipe MAC ++ - const: u3phy-utmi-mac ++ description: USB 3.0 PHY utmi MAC ++ - const: u3phy-utmi-apb ++ description: USB 3.0 PHY utmi apb ++ - const: u3phy-pipe-apb ++ description: USB 3.0 PHY pipe apb ++ ++ "#phy-cells": ++ const: 1 ++ ++ rockchip,u3phygrf: ++ $ref: /schemas/types.yaml#/definitions/phandle-array ++ type: array ++ - description: phandle to the syscon managing the ++ "USB 3.0 PHY general register files". ++ ++ vbus-drv-gpios: ++ $ref: /schemas/types.yaml#/definitions/phandle-array ++ type: array ++ - description: phandle for gpio vbus supply ++ ++required: ++ - compatible ++ - reg ++ - interrupts ++ - interrupt-names ++ - clocks ++ - clock-names ++ - resets ++ - reset-names ++ - "#phy-cells" ++ - rockchip,u3phygrf ++ ++patternProperties: ++ "^u3phy_utmi@[0-9a-f]+$": ++ type: object ++ ++ properties: ++ - description: USB 2.0 utmi phy. ++ ++ rockchip,odt-val-tuning: ++ type: boolean ++ - description: specify 45ohm ODT tuning value. ++ ++ "phy-cells": ++ const: 0 ++ ++ required: ++ - reg ++ - "#phy-cells" ++ ++patternProperties: ++ "^u3phy_pipe@[0-9a-f]+$": ++ type: object ++ ++ properties: ++ - description: USB 3.0 pipe phy. ++ ++ rockchip,refclk-25m-quirk : ++ ++ - description: phy reference clock changed to 25m quirk. ++ ++ "phy-cells": ++ const: 0 ++ ++ required: ++ - reg ++ - "#phy-cells" ++ ++examples: ++ ++usb3phy_grf: syscon@ff460000 { ++ compatible = "rockchip,usb3phy-grf", "syscon"; ++ reg = <0x0 0xff460000 0x0 0x1000>; ++}; ++ ++... ++ ++u3phy: usb3-phy@ff470000 { ++ compatible = "rockchip,rk3328-u3phy"; ++ reg = <0x0 0xff470000 0x0 0x0>; ++ rockchip,u3phygrf = <&usb3phy_grf>; ++ interrupts = ; ++ interrupt-names = "linestate"; ++ clocks = <&cru PCLK_USB3PHY_OTG>, <&cru PCLK_USB3PHY_PIPE>; ++ clock-names = "u3phy-otg", "u3phy-pipe"; ++ resets = <&cru SRST_USB3PHY_U2>, ++ <&cru SRST_USB3PHY_U3>, ++ <&cru SRST_USB3PHY_PIPE>, ++ <&cru SRST_USB3OTG_UTMI>, ++ <&cru SRST_USB3PHY_OTG_P>, ++ <&cru SRST_USB3PHY_PIPE_P>; ++ reset-names = "u3phy-u2-por", "u3phy-u3-por", ++ "u3phy-pipe-mac", "u3phy-utmi-mac", ++ "u3phy-utmi-apb", "u3phy-pipe-apb"; ++ vbus-drv-gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ ++ u3phy_utmi: utmi@ff470000 { ++ reg = <0x0 0xff470000 0x0 0x8000>; ++ #phy-cells = <0>; ++ }; ++ ++ u3phy_pipe: pipe@ff478000 { ++ reg = <0x0 0xff478000 0x0 0x8000>; ++ #phy-cells = <0>; ++ }; ++}; +diff --git a/Documentation/devicetree/bindings/soc/rockchip/grf.txt b/Documentation/devicetree/bindings/soc/rockchip/grf.txt +index ada5435ce2c3..5f2f19344cc7 100644 +--- a/Documentation/devicetree/bindings/soc/rockchip/grf.txt ++++ b/Documentation/devicetree/bindings/soc/rockchip/grf.txt +@@ -34,6 +34,8 @@ Required Properties: + - "rockchip,rk3328-usb2phy-grf", "syscon": for rk3328 + - compatible: USBGRF should be one of the following: + - "rockchip,rv1108-usbgrf", "syscon": for rv1108 ++- compatible: USB3PHYGRF should be one of the following: ++ - "rockchip,u3phy-grf", "syscon" + - reg: physical base address of the controller and length of memory mapped + region. + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index 31cc1541f1f5..072e988ad655 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -805,6 +805,47 @@ + }; + }; + ++ usb3phy_grf: syscon@ff460000 { ++ compatible = "rockchip,usb3phy-grf", "syscon"; ++ reg = <0x0 0xff460000 0x0 0x1000>; ++ }; ++ ++ u3phy: usb3-phy@ff470000 { ++ compatible = "rockchip,rk3328-u3phy"; ++ reg = <0x0 0xff470000 0x0 0x0>; ++ rockchip,u3phygrf = <&usb3phy_grf>; ++ rockchip,grf = <&grf>; ++ interrupts = ; ++ interrupt-names = "linestate"; ++ clocks = <&cru PCLK_USB3PHY_OTG>, <&cru PCLK_USB3PHY_PIPE>; ++ clock-names = "u3phy-otg", "u3phy-pipe"; ++ resets = <&cru SRST_USB3PHY_U2>, ++ <&cru SRST_USB3PHY_U3>, ++ <&cru SRST_USB3PHY_PIPE>, ++ <&cru SRST_USB3OTG_UTMI>, ++ <&cru SRST_USB3PHY_OTG_P>, ++ <&cru SRST_USB3PHY_PIPE_P>; ++ reset-names = "u3phy-u2-por", "u3phy-u3-por", ++ "u3phy-pipe-mac", "u3phy-utmi-mac", ++ "u3phy-utmi-apb", "u3phy-pipe-apb"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ status = "disabled"; ++ ++ u3phy_utmi: utmi@ff470000 { ++ reg = <0x0 0xff470000 0x0 0x8000>; ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ u3phy_pipe: pipe@ff478000 { ++ reg = <0x0 0xff478000 0x0 0x8000>; ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ }; ++ + sdmmc: dwmmc@ff500000 { + compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xff500000 0x0 0x4000>; +@@ -936,6 +977,37 @@ + status = "disabled"; + }; + ++ usbdrd3: usb@ff600000 { ++ compatible = "rockchip,rk3328-dwc3", "rockchip,rk3399-dwc3"; ++ clocks = <&cru SCLK_USB3OTG_REF>, <&cru ACLK_USB3OTG>, ++ <&cru SCLK_USB3OTG_SUSPEND>; ++ clock-names = "ref", "bus_early", ++ "suspend"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ clock-ranges; ++ status = "disabled"; ++ ++ usbdrd_dwc3: dwc3@ff600000 { ++ compatible = "snps,dwc3"; ++ reg = <0x0 0xff600000 0x0 0x100000>; ++ interrupts = ; ++ dr_mode = "otg"; ++ phys = <&u3phy_utmi>, <&u3phy_pipe>; ++ phy-names = "usb2-phy", "usb3-phy"; ++ phy_type = "utmi_wide"; ++ snps,dis_enblslpm_quirk; ++ snps,dis-u2-freeclk-exists-quirk; ++ snps,dis_u2_susphy_quirk; ++ snps,dis_u3_susphy_quirk; ++ snps,dis-del-phy-power-chg-quirk; ++ snps,dis-tx-ipgap-linecheck-quirk; ++ snps,xhci-trb-ent-quirk; ++ status = "disabled"; ++ }; ++ }; ++ + gic: interrupt-controller@ff811000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; diff --git a/target/linux/rockchip/patches-5.4/003-add-nanopi-r2s-support.patch b/target/linux/rockchip/patches-5.4/003-add-nanopi-r2s-support.patch new file mode 100644 index 000000000..3463df5c2 --- /dev/null +++ b/target/linux/rockchip/patches-5.4/003-add-nanopi-r2s-support.patch @@ -0,0 +1,780 @@ +diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile +index 92d796a33..24a6c304f 100644 +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -1,6 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-evb.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2s.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-roc-cc.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-evb-act8846.dtb +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2-common.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2-common.dtsi +new file mode 100644 +index 000000000..36890bb7f +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2-common.dtsi +@@ -0,0 +1,614 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2018 FriendlyElec Computer Tech. Co., Ltd. ++ * (http://www.friendlyarm.com) ++ * ++ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd ++ */ ++ ++/dts-v1/; ++#include "rk3328-dram-default-timing.dtsi" ++#include "rk3328.dtsi" ++ ++/ { ++ model = "FriendlyARM boards based on Rockchip RK3328"; ++ compatible = "friendlyarm,nanopi-r2s", "rockchip,rk3328"; ++ ++ aliases { ++ ethernet1 = &r8153; ++ }; ++ ++ chosen { ++ bootargs = "swiotlb=1 coherent_pool=1m consoleblank=0"; ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ gmac_clkin: external-gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ clock-output-names = "gmac_clkin"; ++ #clock-cells = <0>; ++ }; ++ ++ leds: gpio-leds { ++ compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ pinctrl-0 =<&leds_gpio>; ++ status = "disabled"; ++ ++ status { ++ gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; ++ label = "nanopi:red:status"; ++ linux,default-trigger = "heartbeat"; ++ linux,default-trigger-delay-ms = <0>; ++ }; ++ }; ++ ++ sdio_pwrseq: sdio-pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ clocks = <&rk805 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 = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>; ++ }; ++ ++ vcc_sd: sdmmc-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0m1_gpio>; ++ regulator-name = "vcc_sd"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc_io>; ++ }; ++ ++ vccio_sd: sdmmcio-regulator { ++ compatible = "regulator-gpio"; ++ gpios = <&gpio1 RK_PD4 GPIO_ACTIVE_HIGH>; ++ states = <1800000 0x1 ++ 3300000 0x0>; ++ regulator-name = "vccio_sd"; ++ regulator-type = "voltage"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ vin-supply = <&vcc_io>; ++ startup-delay-us = <2000>; ++ regulator-settling-time-us = <5000>; ++ enable-active-high; ++ status = "disabled"; ++ }; ++ ++ vcc_sys: vcc-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ vcc_phy: vcc-phy-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_phy"; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vcc_host_vbus: host-vbus-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_host_vbus"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ dfi: dfi@ff790000 { ++ reg = <0x00 0xff790000 0x00 0x400>; ++ compatible = "rockchip,rk3328-dfi"; ++ rockchip,grf = <&grf>; ++ status = "disabled"; ++ }; ++ ++ dmc: dmc { ++ compatible = "rockchip,rk3328-dmc"; ++ 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>; ++ auto-min-freq = <786000>; ++ auto-freq-en = <0>; ++ #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,leakage-voltage-sel = < ++ 1 10 0 ++ 11 254 1 ++ >; ++ nvmem-cells = <&logic_leakage>; ++ nvmem-cell-names = "ddr_leakage"; ++ ++ opp-786000000 { ++ opp-hz = /bits/ 64 <786000000>; ++ opp-microvolt = <1075000>; ++ opp-microvolt-L0 = <1075000>; ++ opp-microvolt-L1 = <1050000>; ++ }; ++ opp-798000000 { ++ opp-hz = /bits/ 64 <798000000>; ++ opp-microvolt = <1075000>; ++ opp-microvolt-L0 = <1075000>; ++ opp-microvolt-L1 = <1050000>; ++ }; ++ opp-840000000 { ++ opp-hz = /bits/ 64 <840000000>; ++ opp-microvolt = <1075000>; ++ opp-microvolt-L0 = <1075000>; ++ opp-microvolt-L1 = <1050000>; ++ }; ++ opp-924000000 { ++ opp-hz = /bits/ 64 <924000000>; ++ opp-microvolt = <1100000>; ++ opp-microvolt-L0 = <1100000>; ++ opp-microvolt-L1 = <1075000>; ++ }; ++ opp-1056000000 { ++ opp-hz = /bits/ 64 <1056000000>; ++ opp-microvolt = <1175000>; ++ opp-microvolt-L0 = <1175000>; ++ opp-microvolt-L1 = <1150000>; ++ }; ++ }; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu2 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu3 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&dfi { ++ status = "okay"; ++}; ++ ++&dmc { ++ center-supply = <&vdd_logic>; ++ status = "okay"; ++}; ++ ++&emmc { ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ max-frequency = <150000000>; ++ mmc-hs200-1_8v; ++ no-sd; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; ++ vmmc-supply = <&vcc_io>; ++ vqmmc-supply = <&vcc18_emmc>; ++ status = "okay"; ++}; ++ ++&gmac2phy { ++ phy-supply = <&vcc_phy>; ++ clock_in_out = "output"; ++ assigned-clocks = <&cru SCLK_MAC2PHY_SRC>; ++ assigned-clock-rate = <50000000>; ++ assigned-clocks = <&cru SCLK_MAC2PHY>; ++ assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; ++ status = "disabled"; ++}; ++ ++&gmac2io { ++ assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; ++ assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>; ++ clock_in_out = "input"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rgmiim1_pins>; ++ phy-handle = <&rtl8211e>; ++ phy-mode = "rgmii"; ++ phy-supply = <&vcc_phy>; ++ snps,reset-active-low; ++ snps,reset-delays-us = <0 10000 30000>; ++ snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; ++ snps,aal; ++ snps,rxpbl = <0x4>; ++ snps,txpbl = <0x4>; ++ tx_delay = <0x24>; ++ rx_delay = <0x18>; ++ status = "okay"; ++ ++ mdio { ++ compatible = "snps,dwmac-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ rtl8211e: phy@0 { ++ reg = <0>; ++ reset-assert-us = <10000>; ++ reset-deassert-us = <30000>; ++ /* reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; */ ++ }; ++ }; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ ++ rk805: rk805@18 { ++ compatible = "rockchip,rk805"; ++ reg = <0x18>; ++ interrupt-parent = <&gpio2>; ++ interrupts = <6 IRQ_TYPE_LEVEL_LOW>; ++ #clock-cells = <1>; ++ clock-output-names = "xin32k", "rk805-clkout2"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ ++ vcc1-supply = <&vcc_sys>; ++ vcc2-supply = <&vcc_sys>; ++ vcc3-supply = <&vcc_sys>; ++ vcc4-supply = <&vcc_sys>; ++ vcc5-supply = <&vcc_io>; ++ vcc6-supply = <&vcc_io>; ++ ++ regulators { ++ vdd_logic: DCDC_REG1 { ++ regulator-name = "vdd_logic"; ++ regulator-init-microvolt = <1075000>; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vdd_arm: DCDC_REG2 { ++ regulator-name = "vdd_arm"; ++ regulator-init-microvolt = <1225000>; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-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_io: DCDC_REG4 { ++ regulator-name = "vcc_io"; ++ 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_18: LDO_REG1 { ++ regulator-name = "vcc_18"; ++ 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>; ++ }; ++ }; ++ ++ vcc18_emmc: LDO_REG2 { ++ regulator-name = "vcc18_emmc"; ++ 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_10: LDO_REG3 { ++ regulator-name = "vdd_10"; ++ 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>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&io_domains { ++ status = "okay"; ++ ++ vccio1-supply = <&vcc_io>; ++ vccio2-supply = <&vcc18_emmc>; ++ vccio3-supply = <&vcc_io>; ++ vccio4-supply = <&vcc_io>; ++ vccio5-supply = <&vcc_io>; ++ vccio6-supply = <&vcc_18>; ++ pmuio-supply = <&vcc_io>; ++}; ++ ++&pinctrl { ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ sdio-pwrseq { ++ wifi_enable_h: wifi-enable-h { ++ rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ sdmmc0 { ++ sdmmc0_clk: sdmmc0-clk { ++ rockchip,pins = <1 RK_PA6 1 &pcfg_pull_none_4ma>; ++ }; ++ ++ sdmmc0_cmd: sdmmc0-cmd { ++ rockchip,pins = <1 RK_PA4 1 &pcfg_pull_up_4ma>; ++ }; ++ ++ sdmmc0_dectn: sdmmc0-dectn { ++ rockchip,pins = <1 RK_PA5 1 &pcfg_pull_up_4ma>; ++ }; ++ ++ sdmmc0_bus4: sdmmc0-bus4 { ++ rockchip,pins = ++ <1 RK_PA0 1 &pcfg_pull_up_4ma>, ++ <1 RK_PA1 1 &pcfg_pull_up_4ma>, ++ <1 RK_PA2 1 &pcfg_pull_up_4ma>, ++ <1 RK_PA3 1 &pcfg_pull_up_4ma>; ++ }; ++ }; ++ ++ sdmmc0ext { ++ sdmmc0ext_clk: sdmmc0ext-clk { ++ rockchip,pins = <3 RK_PA2 3 &pcfg_pull_none_2ma>; ++ }; ++ ++ sdmmc0ext_cmd: sdmmc0ext-cmd { ++ rockchip,pins = <3 RK_PA0 3 &pcfg_pull_up_2ma>; ++ }; ++ ++ sdmmc0ext_bus4: sdmmc0ext-bus4 { ++ rockchip,pins = ++ <3 RK_PA4 3 &pcfg_pull_up_2ma>, ++ <3 RK_PA5 3 &pcfg_pull_up_2ma>, ++ <3 RK_PA6 3 &pcfg_pull_up_2ma>, ++ <3 RK_PA7 3 &pcfg_pull_up_2ma>; ++ }; ++ }; ++ ++ gmac-1 { ++ rgmiim1_pins: rgmiim1-pins { ++ rockchip,pins = ++ /* mac_txclk */ ++ <1 RK_PB4 2 &pcfg_pull_none_4ma>, ++ /* mac_rxclk */ ++ <1 RK_PB5 2 &pcfg_pull_none>, ++ /* mac_mdio */ ++ <1 RK_PC3 2 &pcfg_pull_none_2ma>, ++ /* mac_txen */ ++ <1 RK_PD1 2 &pcfg_pull_none_4ma>, ++ /* mac_clk */ ++ <1 RK_PC5 2 &pcfg_pull_none_2ma>, ++ /* mac_rxdv */ ++ <1 RK_PC6 2 &pcfg_pull_none>, ++ /* mac_mdc */ ++ <1 RK_PC7 2 &pcfg_pull_none_2ma>, ++ /* mac_rxd1 */ ++ <1 RK_PB2 2 &pcfg_pull_none>, ++ /* mac_rxd0 */ ++ <1 RK_PB3 2 &pcfg_pull_none>, ++ /* mac_txd1 */ ++ <1 RK_PB0 2 &pcfg_pull_none_4ma>, ++ /* mac_txd0 */ ++ <1 RK_PB1 2 &pcfg_pull_none_4ma>, ++ /* mac_rxd3 */ ++ <1 RK_PB6 2 &pcfg_pull_none>, ++ /* mac_rxd2 */ ++ <1 RK_PB7 2 &pcfg_pull_none>, ++ /* mac_txd3 */ ++ <1 RK_PC0 2 &pcfg_pull_none_4ma>, ++ /* mac_txd2 */ ++ <1 RK_PC1 2 &pcfg_pull_none_4ma>, ++ ++ /* mac_txclk */ ++ <0 RK_PB0 1 &pcfg_pull_none>, ++ /* mac_txen */ ++ <0 RK_PB4 1 &pcfg_pull_none>, ++ /* mac_clk */ ++ <0 RK_PD0 1 &pcfg_pull_none>, ++ /* mac_txd1 */ ++ <0 RK_PC0 1 &pcfg_pull_none>, ++ /* mac_txd0 */ ++ <0 RK_PC1 1 &pcfg_pull_none>, ++ /* mac_txd3 */ ++ <0 RK_PC7 1 &pcfg_pull_none>, ++ /* mac_txd2 */ ++ <0 RK_PC6 1 &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb { ++ host_vbus_drv: host-vbus-drv { ++ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ otg_vbus_drv: otg-vbus-drv { ++ rockchip,pins = <3 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ gpio-leds { ++ leds_gpio: leds-gpio { ++ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ disable-wp; ++ max-frequency = <150000000>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; ++ vmmc-supply = <&vcc_sd>; ++ status = "okay"; ++}; ++ ++&sdmmc_ext { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ cap-sdio-irq; ++ disable-wp; ++ keep-power-in-suspend; ++ max-frequency = <100000000>; ++ mmc-pwrseq = <&sdio_pwrseq>; ++ non-removable; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0ext_clk &sdmmc0ext_cmd &sdmmc0ext_bus4>; ++ rockchip,default-sample-phase = <120>; ++ supports-sdio; ++ sd-uhs-sdr104; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ brcmf: bcrmf@1 { ++ reg = <1>; ++ compatible = "brcm,bcm4329-fmac"; ++ interrupt-parent = <&gpio1>; ++ interrupts = ; ++ interrupt-names = "host-wake"; ++ }; ++}; ++ ++&tsadc { ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&u2phy { ++ status = "okay"; ++}; ++ ++&u2phy_host { ++ status = "okay"; ++}; ++ ++&u2phy_otg { ++ status = "okay"; ++}; ++ ++&u3phy { ++ vbus-supply = <&vcc_host_vbus>; ++ status = "okay"; ++}; ++ ++&u3phy_utmi { ++ status = "okay"; ++}; ++ ++&u3phy_pipe { ++ status = "okay"; ++}; ++ ++&usb20_otg { ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&usbdrd3 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3 { ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ r8153: device@2 { ++ compatible = "usbbda:8153"; ++ reg = <2>; ++ local-mac-address = [00 00 00 00 00 00]; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts +new file mode 100644 +index 000000000..971397659 +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts +@@ -0,0 +1,142 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2019 FriendlyElec Computer Tech. Co., Ltd. ++ * (http://www.friendlyarm.com) ++ */ ++ ++/dts-v1/; ++#include ++#include "rk3328-nanopi-r2-common.dtsi" ++ ++/ { ++ model = "FriendlyARM NanoPi R2S"; ++ compatible = "friendlyarm,nanopi-r2s", "rockchip,rk3328"; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ autorepeat; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&gpio_key1>; ++ ++ reset { ++ gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>; ++ label = "reset"; ++ linux,code = ; ++ linux,input-type = <1>; ++ gpio-key,wakeup = <1>; ++ debounce-interval = <100>; ++ }; ++ }; ++ ++ vcc_rtl8153: vcc-rtl8153-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&usb30_en_drv>; ++ regulator-always-on; ++ regulator-name = "vcc_rtl8153"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ off-on-delay-us = <5000>; ++ enable-active-high; ++ }; ++}; ++ ++&emmc { ++ status = "disabled"; ++}; ++ ++&i2c0 { ++ status = "okay"; ++}; ++ ++&leds { ++ status = "okay"; ++ ++ lan { ++ gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>; ++ label = "nanopi:green:lan"; ++ }; ++ ++ wan { ++ gpios = <&gpio2 RK_PC2 GPIO_ACTIVE_HIGH>; ++ label = "nanopi:green:wan"; ++ }; ++}; ++ ++&leds_gpio { ++ rockchip,pins = ++ <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>, ++ <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>, ++ <2 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; ++}; ++ ++&pwm2 { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-1 = <&pwm2_sleep_pin>; ++ status = "okay"; ++}; ++ ++&rk805 { ++ interrupt-parent = <&gpio1>; ++ interrupts = ; ++}; ++ ++&vccio_sd { ++ status = "okay"; ++}; ++ ++&io_domains { ++ vccio3-supply = <&vccio_sd>; ++}; ++ ++&sdmmc { ++ vqmmc-supply = <&vccio_sd>; ++ max-frequency = <150000000>; ++ sd-uhs-sdr12; ++ sd-uhs-sdr25; ++ sd-uhs-sdr50; ++ sd-uhs-sdr104; ++ status = "okay"; ++}; ++ ++&sdmmc_ext { ++ status = "disabled"; ++}; ++ ++&sdio_pwrseq { ++ status = "disabled"; ++}; ++ ++&pinctrl { ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++ ++ pwm { ++ pwm2_sleep_pin: pwm2-sleep-pin { ++ rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_output_low>; ++ }; ++ }; ++ ++ rockchip-key { ++ gpio_key1: gpio-key1 { ++ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ usb { ++ otg_vbus_drv: otg-vbus-drv { ++ rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ ++ usb30_en_drv: usb30-en-drv { ++ rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++}; diff --git a/target/linux/rockchip/patches-5.4/003-add-rk3328-rock-pi-e-support.patch b/target/linux/rockchip/patches-5.4/003-add-rk3328-rock-pi-e-support.patch new file mode 100644 index 000000000..d4e24be55 --- /dev/null +++ b/target/linux/rockchip/patches-5.4/003-add-rk3328-rock-pi-e-support.patch @@ -0,0 +1,420 @@ +diff -ruN a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile +--- a/arch/arm64/boot/dts/rockchip/Makefile 2020-05-27 15:46:53.000000000 +0000 ++++ b/arch/arm64/boot/dts/rockchip/Makefile 2020-06-07 16:32:59.590211585 +0000 +@@ -3,6 +3,7 @@ + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-roc-cc.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock-pi-e.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-evb-act8846.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-geekbox.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-lion-haikou.dtb +diff -ruN a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts +--- a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts 1970-01-01 00:00:00.000000000 +0000 ++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts 2020-06-07 16:32:43.789930837 +0000 +@@ -0,0 +1,405 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2016 Fuzhou Rockchip Electronics Co., Ltd ++ */ ++ ++/dts-v1/; ++#include "rk3328.dtsi" ++#include ++ ++/ { ++ model = "Radxa Rock Pi E"; ++ compatible = "radxa,rock-pi-e", "rockchip,rk3328"; ++ ++ chosen { ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ fiq_debugger: fiq-debugger { ++ compatible = "rockchip,fiq-debugger"; ++ rockchip,serial-id = <2>; ++ rockchip,signal-irq = <159>; ++ rockchip,wake-irq = <0>; ++ /* If enable uart uses irq instead of fiq */ ++ rockchip,irq-mode-enable = <0>; ++ rockchip,baudrate = <1500000>; /* Only 115200 and 1500000 */ ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gmac_clkin: external-gmac-clock { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ clock-output-names = "gmac_clkin"; ++ #clock-cells = <0>; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ status = "okay"; ++ ++ user { ++ label = "rockpi:green:user"; ++ gpios = <&gpio3 RK_PA5 GPIO_ACTIVE_LOW>; ++ linux,default-trigger = "heartbeat"; ++ default-state = "on"; ++ }; ++ }; ++ ++ vcc5v0_host_xhci: vcc5v0-host-xhci-drv { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio3 RK_PA7 GPIO_ACTIVE_HIGH>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&host_vbus_drv>; ++ regulator-name = "vcc5v0_host_xhci"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ enable-active-high; ++ }; ++ ++ vcc_phy: vcc-phy-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_phy"; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ vcc_sd: sdmmc-regulator { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0m1_gpio>; ++ regulator-name = "vcc_sd"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc_io>; ++ }; ++ ++ vcc_sys: vcc-sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_sys"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ }; ++ ++ xin32k: xin32k { ++ compatible = "fixed-clock"; ++ clock-frequency = <32768>; ++ clock-output-names = "xin32k"; ++ #clock-cells = <0>; ++ }; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu2 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&cpu3 { ++ cpu-supply = <&vdd_arm>; ++}; ++ ++&emmc { ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ max-frequency = <150000000>; ++ mmc-ddr-1_8v; ++ mmc-hs200-1_8v; ++ supports-emmc; ++ disable-wp; ++ non-removable; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; ++ vmmc-supply = <&vcc_io>; ++ vqmmc-supply = <&vcc18_emmc>; ++ status = "okay"; ++}; ++ ++&gmac2io { ++ phy-supply = <&vcc_io>; ++ phy-mode = "rgmii"; ++ clock_in_out = "input"; ++ snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; ++ snps,reset-active-low; ++ snps,reset-delays-us = <0 10000 50000>; ++ assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; ++ assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rgmiim1_pins>; ++ snps,txpbl = <0x4>; ++ tx_delay = <0x26>; ++ rx_delay = <0x11>; ++ status = "okay"; ++}; ++ ++&gmac2phy { ++ phy-supply = <&vcc_phy>; ++ clock_in_out = "output"; ++ assigned-clocks = <&cru SCLK_MAC2PHY_SRC>; ++ assigned-clock-rate = <50000000>; ++ assigned-clocks = <&cru SCLK_MAC2PHY>; ++ assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; ++ snps,txpbl = <0x4>; ++ status = "okay"; ++}; ++ ++&i2c1 { ++ status = "okay"; ++ ++ rk805: rk805@18 { ++ compatible = "rockchip,rk805"; ++ status = "okay"; ++ reg = <0x18>; ++ interrupt-parent = <&gpio2>; ++ interrupts = <6 IRQ_TYPE_LEVEL_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_int_l>; ++ rockchip,system-power-controller; ++ wakeup-source; ++ gpio-controller; ++ #gpio-cells = <2>; ++ #clock-cells = <1>; ++ clock-output-names = "xin32k", "rk805-clkout2"; ++ ++ vcc1-supply = <&vcc_sys>; ++ vcc2-supply = <&vcc_sys>; ++ vcc3-supply = <&vcc_sys>; ++ vcc4-supply = <&vcc_sys>; ++ vcc5-supply = <&vcc_io>; ++ vcc6-supply = <&vcc_sys>; ++ ++ rtc { ++ status = "okay"; ++ }; ++ ++ pwrkey { ++ status = "disabled"; ++ }; ++ ++ gpio { ++ status = "okay"; ++ }; ++ ++ regulators { ++ vdd_logic: DCDC_REG1 { ++ regulator-name = "vdd_logic"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-initial-mode = <0x1>; ++ regulator-ramp-delay = <12500>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vdd_arm: DCDC_REG2 { ++ regulator-name = "vdd_arm"; ++ regulator-min-microvolt = <712500>; ++ regulator-max-microvolt = <1450000>; ++ regulator-initial-mode = <0x1>; ++ regulator-ramp-delay = <12500>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <950000>; ++ }; ++ }; ++ ++ vcc_ddr: DCDC_REG3 { ++ regulator-name = "vcc_ddr"; ++ regulator-initial-mode = <0x1>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vcc_io: DCDC_REG4 { ++ regulator-name = "vcc_io"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-initial-mode = <0x1>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-mode = <0x2>; ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vdd_18: LDO_REG1 { ++ regulator-name = "vdd_18"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vcc18_emmc: LDO_REG2 { ++ regulator-name = "vcc18_emmc"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ vdd_10: LDO_REG3 { ++ regulator-name = "vdd_10"; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1000000>; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&io_domains { ++ status = "okay"; ++ ++ vccio1-supply = <&vcc_io>; ++ vccio2-supply = <&vcc18_emmc>; ++ vccio3-supply = <&vcc_io>; ++ vccio4-supply = <&vcc_io>; ++ vccio5-supply = <&vcc_io>; ++ vccio6-supply = <&vcc_io>; ++ pmuio-supply = <&vcc_io>; ++}; ++ ++&pinctrl { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&wifi_enable>; ++ ++ pmic { ++ pmic_int_l: pmic-int-l { ++ rockchip,pins = ++ <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; /* gpio2_a6 */ ++ }; ++ }; ++ ++ usb { ++ host_vbus_drv: host-vbus-drv { ++ rockchip,pins = ++ <3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>; ++ }; ++ }; ++ ++ wifi { ++ wifi_enable: wifi-enable { ++ rockchip,pins = ++ <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>; ++ }; ++ }; ++}; ++ ++&saradc { ++ status = "okay"; ++ vref-supply = <&vdd_18>; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-sd-highspeed; ++ card-detect-delay = <200>; ++ disable-wp; ++ max-frequency = <150000000>; ++ num-slots = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; ++ supports-sd; ++ vmmc-supply = <&vcc_sd>; ++ status = "okay"; ++}; ++ ++&tsadc { ++ status = "okay"; ++ rockchip,hw-tshut-mode = <1>; /* tshut mode 0:CRU 1:GPIO */ ++ rockchip,hw-tshut-polarity = <1>; /* tshut polarity 0:LOW 1:HIGH */ ++}; ++ ++&u2phy { ++ status = "okay"; ++}; ++ ++&u2phy_host { ++ status = "okay"; ++}; ++ ++&u2phy_otg { ++ status = "okay"; ++}; ++ ++&u3phy { ++ status = "okay"; ++}; ++ ++&u3phy_pipe { ++ status = "okay"; ++}; ++ ++&u3phy_utmi { ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; ++ ++&usb20_otg { ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usbdrd3 { ++ status = "okay"; ++}; ++ ++&usbdrd_dwc3 { ++ status = "okay"; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; ++ ++&usb_host0_ohci { ++ status = "okay"; ++}; ++ ++&wdt { ++ status = "okay"; ++}; diff --git a/target/linux/rockchip/patches-5.4/003-nanopi-r2s-kernel-patches.patch b/target/linux/rockchip/patches-5.4/003-nanopi-r2s-kernel-patches.patch new file mode 100644 index 000000000..f98717ecf --- /dev/null +++ b/target/linux/rockchip/patches-5.4/003-nanopi-r2s-kernel-patches.patch @@ -0,0 +1,551 @@ +diff --git a/arch/arm64/boot/dts/rockchip/rk3328-dram-default-timing.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-dram-default-timing.dtsi +new file mode 100644 +index 000000000..a3f5ff4bd +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3328-dram-default-timing.dtsi +@@ -0,0 +1,311 @@ ++/* ++ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd ++ * ++ * This file is dual-licensed: you can use it either under the terms ++ * of the GPL or the X11 license, at your option. Note that this dual ++ * licensing only applies to this file, and not this project as a ++ * whole. ++ * ++ * a) This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Or, alternatively, ++ * ++ * b) Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, ++ * copy, modify, merge, publish, distribute, sublicense, and/or ++ * sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following ++ * conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++#include ++#include ++ ++/ { ++ ddr_timing: ddr_timing { ++ compatible = "rockchip,ddr-timing"; ++ ddr3_speed_bin = ; ++ ddr4_speed_bin = ; ++ pd_idle = <0>; ++ sr_idle = <0>; ++ sr_mc_gate_idle = <0>; ++ srpd_lite_idle = <0>; ++ standby_idle = <0>; ++ ++ auto_pd_dis_freq = <1066>; ++ auto_sr_dis_freq = <800>; ++ ddr3_dll_dis_freq = <300>; ++ ddr4_dll_dis_freq = <625>; ++ phy_dll_dis_freq = <400>; ++ ++ ddr3_odt_dis_freq = <100>; ++ phy_ddr3_odt_dis_freq = <100>; ++ ddr3_drv = ; ++ ddr3_odt = ; ++ phy_ddr3_ca_drv = ; ++ phy_ddr3_ck_drv = ; ++ phy_ddr3_dq_drv = ; ++ phy_ddr3_odt = ; ++ ++ lpddr3_odt_dis_freq = <666>; ++ phy_lpddr3_odt_dis_freq = <666>; ++ lpddr3_drv = ; ++ lpddr3_odt = ; ++ phy_lpddr3_ca_drv = ; ++ phy_lpddr3_ck_drv = ; ++ phy_lpddr3_dq_drv = ; ++ phy_lpddr3_odt = ; ++ ++ lpddr4_odt_dis_freq = <800>; ++ phy_lpddr4_odt_dis_freq = <800>; ++ lpddr4_drv = ; ++ lpddr4_dq_odt = ; ++ lpddr4_ca_odt = ; ++ phy_lpddr4_ca_drv = ; ++ phy_lpddr4_ck_cs_drv = ; ++ phy_lpddr4_dq_drv = ; ++ phy_lpddr4_odt = ; ++ ++ ddr4_odt_dis_freq = <666>; ++ phy_ddr4_odt_dis_freq = <666>; ++ ddr4_drv = ; ++ ddr4_odt = ; ++ phy_ddr4_ca_drv = ; ++ phy_ddr4_ck_drv = ; ++ phy_ddr4_dq_drv = ; ++ phy_ddr4_odt = ; ++ ++ /* CA de-skew, one step is 47.8ps, range 0-15 */ ++ ddr3a1_ddr4a9_de-skew = <7>; ++ ddr3a0_ddr4a10_de-skew = <7>; ++ ddr3a3_ddr4a6_de-skew = <8>; ++ ddr3a2_ddr4a4_de-skew = <8>; ++ ddr3a5_ddr4a8_de-skew = <7>; ++ ddr3a4_ddr4a5_de-skew = <9>; ++ ddr3a7_ddr4a11_de-skew = <7>; ++ ddr3a6_ddr4a7_de-skew = <9>; ++ ddr3a9_ddr4a0_de-skew = <8>; ++ ddr3a8_ddr4a13_de-skew = <7>; ++ ddr3a11_ddr4a3_de-skew = <9>; ++ ddr3a10_ddr4cs0_de-skew = <7>; ++ ddr3a13_ddr4a2_de-skew = <8>; ++ ddr3a12_ddr4ba1_de-skew = <7>; ++ ddr3a15_ddr4odt0_de-skew = <7>; ++ ddr3a14_ddr4a1_de-skew = <8>; ++ ddr3ba1_ddr4a15_de-skew = <7>; ++ ddr3ba0_ddr4bg0_de-skew = <7>; ++ ddr3ras_ddr4cke_de-skew = <7>; ++ ddr3ba2_ddr4ba0_de-skew = <8>; ++ ddr3we_ddr4bg1_de-skew = <8>; ++ ddr3cas_ddr4a12_de-skew = <7>; ++ ddr3ckn_ddr4ckn_de-skew = <8>; ++ ddr3ckp_ddr4ckp_de-skew = <8>; ++ ddr3cke_ddr4a16_de-skew = <8>; ++ ddr3odt0_ddr4a14_de-skew = <7>; ++ ddr3cs0_ddr4act_de-skew = <8>; ++ ddr3reset_ddr4reset_de-skew = <7>; ++ ddr3cs1_ddr4cs1_de-skew = <7>; ++ ddr3odt1_ddr4odt1_de-skew = <7>; ++ ++ /* DATA de-skew ++ * RX one step is 25.1ps, range 0-15 ++ * TX one step is 47.8ps, range 0-15 ++ */ ++ cs0_dm0_rx_de-skew = <7>; ++ cs0_dm0_tx_de-skew = <8>; ++ cs0_dq0_rx_de-skew = <7>; ++ cs0_dq0_tx_de-skew = <8>; ++ cs0_dq1_rx_de-skew = <7>; ++ cs0_dq1_tx_de-skew = <8>; ++ cs0_dq2_rx_de-skew = <7>; ++ cs0_dq2_tx_de-skew = <8>; ++ cs0_dq3_rx_de-skew = <7>; ++ cs0_dq3_tx_de-skew = <8>; ++ cs0_dq4_rx_de-skew = <7>; ++ cs0_dq4_tx_de-skew = <8>; ++ cs0_dq5_rx_de-skew = <7>; ++ cs0_dq5_tx_de-skew = <8>; ++ cs0_dq6_rx_de-skew = <7>; ++ cs0_dq6_tx_de-skew = <8>; ++ cs0_dq7_rx_de-skew = <7>; ++ cs0_dq7_tx_de-skew = <8>; ++ cs0_dqs0_rx_de-skew = <6>; ++ cs0_dqs0p_tx_de-skew = <9>; ++ cs0_dqs0n_tx_de-skew = <9>; ++ ++ cs0_dm1_rx_de-skew = <7>; ++ cs0_dm1_tx_de-skew = <7>; ++ cs0_dq8_rx_de-skew = <7>; ++ cs0_dq8_tx_de-skew = <8>; ++ cs0_dq9_rx_de-skew = <7>; ++ cs0_dq9_tx_de-skew = <7>; ++ cs0_dq10_rx_de-skew = <7>; ++ cs0_dq10_tx_de-skew = <8>; ++ cs0_dq11_rx_de-skew = <7>; ++ cs0_dq11_tx_de-skew = <7>; ++ cs0_dq12_rx_de-skew = <7>; ++ cs0_dq12_tx_de-skew = <8>; ++ cs0_dq13_rx_de-skew = <7>; ++ cs0_dq13_tx_de-skew = <7>; ++ cs0_dq14_rx_de-skew = <7>; ++ cs0_dq14_tx_de-skew = <8>; ++ cs0_dq15_rx_de-skew = <7>; ++ cs0_dq15_tx_de-skew = <7>; ++ cs0_dqs1_rx_de-skew = <7>; ++ cs0_dqs1p_tx_de-skew = <9>; ++ cs0_dqs1n_tx_de-skew = <9>; ++ ++ cs0_dm2_rx_de-skew = <7>; ++ cs0_dm2_tx_de-skew = <8>; ++ cs0_dq16_rx_de-skew = <7>; ++ cs0_dq16_tx_de-skew = <8>; ++ cs0_dq17_rx_de-skew = <7>; ++ cs0_dq17_tx_de-skew = <8>; ++ cs0_dq18_rx_de-skew = <7>; ++ cs0_dq18_tx_de-skew = <8>; ++ cs0_dq19_rx_de-skew = <7>; ++ cs0_dq19_tx_de-skew = <8>; ++ cs0_dq20_rx_de-skew = <7>; ++ cs0_dq20_tx_de-skew = <8>; ++ cs0_dq21_rx_de-skew = <7>; ++ cs0_dq21_tx_de-skew = <8>; ++ cs0_dq22_rx_de-skew = <7>; ++ cs0_dq22_tx_de-skew = <8>; ++ cs0_dq23_rx_de-skew = <7>; ++ cs0_dq23_tx_de-skew = <8>; ++ cs0_dqs2_rx_de-skew = <6>; ++ cs0_dqs2p_tx_de-skew = <9>; ++ cs0_dqs2n_tx_de-skew = <9>; ++ ++ cs0_dm3_rx_de-skew = <7>; ++ cs0_dm3_tx_de-skew = <7>; ++ cs0_dq24_rx_de-skew = <7>; ++ cs0_dq24_tx_de-skew = <8>; ++ cs0_dq25_rx_de-skew = <7>; ++ cs0_dq25_tx_de-skew = <7>; ++ cs0_dq26_rx_de-skew = <7>; ++ cs0_dq26_tx_de-skew = <7>; ++ cs0_dq27_rx_de-skew = <7>; ++ cs0_dq27_tx_de-skew = <7>; ++ cs0_dq28_rx_de-skew = <7>; ++ cs0_dq28_tx_de-skew = <7>; ++ cs0_dq29_rx_de-skew = <7>; ++ cs0_dq29_tx_de-skew = <7>; ++ cs0_dq30_rx_de-skew = <7>; ++ cs0_dq30_tx_de-skew = <7>; ++ cs0_dq31_rx_de-skew = <7>; ++ cs0_dq31_tx_de-skew = <7>; ++ cs0_dqs3_rx_de-skew = <7>; ++ cs0_dqs3p_tx_de-skew = <9>; ++ cs0_dqs3n_tx_de-skew = <9>; ++ ++ cs1_dm0_rx_de-skew = <7>; ++ cs1_dm0_tx_de-skew = <8>; ++ cs1_dq0_rx_de-skew = <7>; ++ cs1_dq0_tx_de-skew = <8>; ++ cs1_dq1_rx_de-skew = <7>; ++ cs1_dq1_tx_de-skew = <8>; ++ cs1_dq2_rx_de-skew = <7>; ++ cs1_dq2_tx_de-skew = <8>; ++ cs1_dq3_rx_de-skew = <7>; ++ cs1_dq3_tx_de-skew = <8>; ++ cs1_dq4_rx_de-skew = <7>; ++ cs1_dq4_tx_de-skew = <8>; ++ cs1_dq5_rx_de-skew = <7>; ++ cs1_dq5_tx_de-skew = <8>; ++ cs1_dq6_rx_de-skew = <7>; ++ cs1_dq6_tx_de-skew = <8>; ++ cs1_dq7_rx_de-skew = <7>; ++ cs1_dq7_tx_de-skew = <8>; ++ cs1_dqs0_rx_de-skew = <6>; ++ cs1_dqs0p_tx_de-skew = <9>; ++ cs1_dqs0n_tx_de-skew = <9>; ++ ++ cs1_dm1_rx_de-skew = <7>; ++ cs1_dm1_tx_de-skew = <7>; ++ cs1_dq8_rx_de-skew = <7>; ++ cs1_dq8_tx_de-skew = <8>; ++ cs1_dq9_rx_de-skew = <7>; ++ cs1_dq9_tx_de-skew = <7>; ++ cs1_dq10_rx_de-skew = <7>; ++ cs1_dq10_tx_de-skew = <8>; ++ cs1_dq11_rx_de-skew = <7>; ++ cs1_dq11_tx_de-skew = <7>; ++ cs1_dq12_rx_de-skew = <7>; ++ cs1_dq12_tx_de-skew = <8>; ++ cs1_dq13_rx_de-skew = <7>; ++ cs1_dq13_tx_de-skew = <7>; ++ cs1_dq14_rx_de-skew = <7>; ++ cs1_dq14_tx_de-skew = <8>; ++ cs1_dq15_rx_de-skew = <7>; ++ cs1_dq15_tx_de-skew = <7>; ++ cs1_dqs1_rx_de-skew = <7>; ++ cs1_dqs1p_tx_de-skew = <9>; ++ cs1_dqs1n_tx_de-skew = <9>; ++ ++ cs1_dm2_rx_de-skew = <7>; ++ cs1_dm2_tx_de-skew = <8>; ++ cs1_dq16_rx_de-skew = <7>; ++ cs1_dq16_tx_de-skew = <8>; ++ cs1_dq17_rx_de-skew = <7>; ++ cs1_dq17_tx_de-skew = <8>; ++ cs1_dq18_rx_de-skew = <7>; ++ cs1_dq18_tx_de-skew = <8>; ++ cs1_dq19_rx_de-skew = <7>; ++ cs1_dq19_tx_de-skew = <8>; ++ cs1_dq20_rx_de-skew = <7>; ++ cs1_dq20_tx_de-skew = <8>; ++ cs1_dq21_rx_de-skew = <7>; ++ cs1_dq21_tx_de-skew = <8>; ++ cs1_dq22_rx_de-skew = <7>; ++ cs1_dq22_tx_de-skew = <8>; ++ cs1_dq23_rx_de-skew = <7>; ++ cs1_dq23_tx_de-skew = <8>; ++ cs1_dqs2_rx_de-skew = <6>; ++ cs1_dqs2p_tx_de-skew = <9>; ++ cs1_dqs2n_tx_de-skew = <9>; ++ ++ cs1_dm3_rx_de-skew = <7>; ++ cs1_dm3_tx_de-skew = <7>; ++ cs1_dq24_rx_de-skew = <7>; ++ cs1_dq24_tx_de-skew = <8>; ++ cs1_dq25_rx_de-skew = <7>; ++ cs1_dq25_tx_de-skew = <7>; ++ cs1_dq26_rx_de-skew = <7>; ++ cs1_dq26_tx_de-skew = <7>; ++ cs1_dq27_rx_de-skew = <7>; ++ cs1_dq27_tx_de-skew = <7>; ++ cs1_dq28_rx_de-skew = <7>; ++ cs1_dq28_tx_de-skew = <7>; ++ cs1_dq29_rx_de-skew = <7>; ++ cs1_dq29_tx_de-skew = <7>; ++ cs1_dq30_rx_de-skew = <7>; ++ cs1_dq30_tx_de-skew = <7>; ++ cs1_dq31_rx_de-skew = <7>; ++ cs1_dq31_tx_de-skew = <7>; ++ cs1_dqs3_rx_de-skew = <7>; ++ cs1_dqs3p_tx_de-skew = <9>; ++ cs1_dqs3n_tx_de-skew = <9>; ++ }; ++}; +diff --git a/include/dt-bindings/clock/rockchip-ddr.h b/include/dt-bindings/clock/rockchip-ddr.h +new file mode 100644 +index 000000000..b065432e7 +--- /dev/null ++++ b/include/dt-bindings/clock/rockchip-ddr.h +@@ -0,0 +1,63 @@ ++/* ++ * ++ * Copyright (C) 2017 ROCKCHIP, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _DT_BINDINGS_CLOCK_ROCKCHIP_DDR_H ++#define _DT_BINDINGS_CLOCK_ROCKCHIP_DDR_H ++ ++#define DDR2_DEFAULT (0) ++ ++#define DDR3_800D (0) /* 5-5-5 */ ++#define DDR3_800E (1) /* 6-6-6 */ ++#define DDR3_1066E (2) /* 6-6-6 */ ++#define DDR3_1066F (3) /* 7-7-7 */ ++#define DDR3_1066G (4) /* 8-8-8 */ ++#define DDR3_1333F (5) /* 7-7-7 */ ++#define DDR3_1333G (6) /* 8-8-8 */ ++#define DDR3_1333H (7) /* 9-9-9 */ ++#define DDR3_1333J (8) /* 10-10-10 */ ++#define DDR3_1600G (9) /* 8-8-8 */ ++#define DDR3_1600H (10) /* 9-9-9 */ ++#define DDR3_1600J (11) /* 10-10-10 */ ++#define DDR3_1600K (12) /* 11-11-11 */ ++#define DDR3_1866J (13) /* 10-10-10 */ ++#define DDR3_1866K (14) /* 11-11-11 */ ++#define DDR3_1866L (15) /* 12-12-12 */ ++#define DDR3_1866M (16) /* 13-13-13 */ ++#define DDR3_2133K (17) /* 11-11-11 */ ++#define DDR3_2133L (18) /* 12-12-12 */ ++#define DDR3_2133M (19) /* 13-13-13 */ ++#define DDR3_2133N (20) /* 14-14-14 */ ++#define DDR3_DEFAULT (21) ++#define DDR_DDR2 (22) ++#define DDR_LPDDR (23) ++#define DDR_LPDDR2 (24) ++ ++#define DDR4_1600J (0) /* 10-10-10 */ ++#define DDR4_1600K (1) /* 11-11-11 */ ++#define DDR4_1600L (2) /* 12-12-12 */ ++#define DDR4_1866L (3) /* 12-12-12 */ ++#define DDR4_1866M (4) /* 13-13-13 */ ++#define DDR4_1866N (5) /* 14-14-14 */ ++#define DDR4_2133N (6) /* 14-14-14 */ ++#define DDR4_2133P (7) /* 15-15-15 */ ++#define DDR4_2133R (8) /* 16-16-16 */ ++#define DDR4_2400P (9) /* 15-15-15 */ ++#define DDR4_2400R (10) /* 16-16-16 */ ++#define DDR4_2400U (11) /* 18-18-18 */ ++#define DDR4_DEFAULT (12) ++ ++#define PAUSE_CPU_STACK_SIZE 16 ++ ++#endif +diff --git a/include/dt-bindings/memory/rk3328-dram.h b/include/dt-bindings/memory/rk3328-dram.h +new file mode 100644 +index 000000000..171f41c25 +--- /dev/null ++++ b/include/dt-bindings/memory/rk3328-dram.h +@@ -0,0 +1,159 @@ ++/* ++ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd ++ * ++ * This file is dual-licensed: you can use it either under the terms ++ * of the GPL or the X11 license, at your option. Note that this dual ++ * licensing only applies to this file, and not this project as a ++ * whole. ++ * ++ * a) This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Or, alternatively, ++ * ++ * b) Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, ++ * copy, modify, merge, publish, distribute, sublicense, and/or ++ * sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following ++ * conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT ++ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++#ifndef _DT_BINDINGS_DRAM_ROCKCHIP_RK3328_H ++#define _DT_BINDINGS_DRAM_ROCKCHIP_RK3328_H ++ ++#define DDR3_DS_34ohm (34) ++#define DDR3_DS_40ohm (40) ++ ++#define DDR3_ODT_DIS (0) ++#define DDR3_ODT_40ohm (40) ++#define DDR3_ODT_60ohm (60) ++#define DDR3_ODT_120ohm (120) ++ ++#define LP2_DS_34ohm (34) ++#define LP2_DS_40ohm (40) ++#define LP2_DS_48ohm (48) ++#define LP2_DS_60ohm (60) ++#define LP2_DS_68_6ohm (68) /* optional */ ++#define LP2_DS_80ohm (80) ++#define LP2_DS_120ohm (120) /* optional */ ++ ++#define LP3_DS_34ohm (34) ++#define LP3_DS_40ohm (40) ++#define LP3_DS_48ohm (48) ++#define LP3_DS_60ohm (60) ++#define LP3_DS_80ohm (80) ++#define LP3_DS_34D_40U (3440) ++#define LP3_DS_40D_48U (4048) ++#define LP3_DS_34D_48U (3448) ++ ++#define LP3_ODT_DIS (0) ++#define LP3_ODT_60ohm (60) ++#define LP3_ODT_120ohm (120) ++#define LP3_ODT_240ohm (240) ++ ++#define LP4_PDDS_40ohm (40) ++#define LP4_PDDS_48ohm (48) ++#define LP4_PDDS_60ohm (60) ++#define LP4_PDDS_80ohm (80) ++#define LP4_PDDS_120ohm (120) ++#define LP4_PDDS_240ohm (240) ++ ++#define LP4_DQ_ODT_40ohm (40) ++#define LP4_DQ_ODT_48ohm (48) ++#define LP4_DQ_ODT_60ohm (60) ++#define LP4_DQ_ODT_80ohm (80) ++#define LP4_DQ_ODT_120ohm (120) ++#define LP4_DQ_ODT_240ohm (240) ++#define LP4_DQ_ODT_DIS (0) ++ ++#define LP4_CA_ODT_40ohm (40) ++#define LP4_CA_ODT_48ohm (48) ++#define LP4_CA_ODT_60ohm (60) ++#define LP4_CA_ODT_80ohm (80) ++#define LP4_CA_ODT_120ohm (120) ++#define LP4_CA_ODT_240ohm (240) ++#define LP4_CA_ODT_DIS (0) ++ ++#define DDR4_DS_34ohm (34) ++#define DDR4_DS_48ohm (48) ++#define DDR4_RTT_NOM_DIS (0) ++#define DDR4_RTT_NOM_60ohm (60) ++#define DDR4_RTT_NOM_120ohm (120) ++#define DDR4_RTT_NOM_40ohm (40) ++#define DDR4_RTT_NOM_240ohm (240) ++#define DDR4_RTT_NOM_48ohm (48) ++#define DDR4_RTT_NOM_80ohm (80) ++#define DDR4_RTT_NOM_34ohm (34) ++ ++#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) ++ ++#endif /*_DT_BINDINGS_DRAM_ROCKCHIP_RK3328_H*/ diff --git a/target/linux/rockchip/patches-5.4/004-rk3328_add_idle_state.patch b/target/linux/rockchip/patches-5.4/004-rk3328_add_idle_state.patch new file mode 100644 index 000000000..1a62e29e1 --- /dev/null +++ b/target/linux/rockchip/patches-5.4/004-rk3328_add_idle_state.patch @@ -0,0 +1,71 @@ +From 4f279f9fbca54464173240f7e73b145a136dfa1e Mon Sep 17 00:00:00 2001 +From: Robin Murphy +Date: Sun, 29 Dec 2019 20:16:17 +0000 +Subject: [PATCH] arm64: dts: rockchip: Add RK3328 idle state + +Downstream RK3328 DTBs describe a CPU idle state matching that present +on other SoCs like RK3399. This works with upstream Trusted Firmware-A +too, so let's add it here. + +Signed-off-by: Robin Murphy +Link: https://lore.kernel.org/r/a8c83e705d387446ea8121516d410e38b2d9c57b.1577640736.git.robin.murphy@arm.com +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index 91306ebed4da..c9ff1188bd7b 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -41,6 +41,7 @@ + reg = <0x0 0x0>; + clocks = <&cru ARMCLK>; + #cooling-cells = <2>; ++ cpu-idle-states = <&CPU_SLEEP>; + dynamic-power-coefficient = <120>; + enable-method = "psci"; + next-level-cache = <&l2>; +@@ -53,6 +54,7 @@ + reg = <0x0 0x1>; + clocks = <&cru ARMCLK>; + #cooling-cells = <2>; ++ cpu-idle-states = <&CPU_SLEEP>; + dynamic-power-coefficient = <120>; + enable-method = "psci"; + next-level-cache = <&l2>; +@@ -65,6 +67,7 @@ + reg = <0x0 0x2>; + clocks = <&cru ARMCLK>; + #cooling-cells = <2>; ++ cpu-idle-states = <&CPU_SLEEP>; + dynamic-power-coefficient = <120>; + enable-method = "psci"; + next-level-cache = <&l2>; +@@ -77,12 +80,26 @@ + reg = <0x0 0x3>; + clocks = <&cru ARMCLK>; + #cooling-cells = <2>; ++ cpu-idle-states = <&CPU_SLEEP>; + dynamic-power-coefficient = <120>; + enable-method = "psci"; + next-level-cache = <&l2>; + 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>; ++ }; ++ }; ++ + l2: l2-cache0 { + compatible = "cache"; + }; diff --git a/target/linux/rockchip/patches-5.4/004-unlock-1512mhz-rk3328.patch b/target/linux/rockchip/patches-5.4/004-unlock-1512mhz-rk3328.patch new file mode 100644 index 000000000..7d67233d6 --- /dev/null +++ b/target/linux/rockchip/patches-5.4/004-unlock-1512mhz-rk3328.patch @@ -0,0 +1,16 @@ +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index 8dabc6e29..d58c893a6 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -125,6 +125,11 @@ + opp-microvolt = <1300000>; + clock-latency-ns = <40000>; + }; ++ opp-1512000000 { ++ opp-hz = /bits/ 64 <1512000000>; ++ opp-microvolt = <1450000>; ++ clock-latency-ns = <40000>; ++ }; + }; + + amba { diff --git a/target/linux/rockchip/patches-5.4/005-add_hwmon_support.patch b/target/linux/rockchip/patches-5.4/005-add_hwmon_support.patch new file mode 100644 index 000000000..5d95ea66a --- /dev/null +++ b/target/linux/rockchip/patches-5.4/005-add_hwmon_support.patch @@ -0,0 +1,92 @@ +From f895f1f4de0b7252f29e7e5779727b303df9e58d Mon Sep 17 00:00:00 2001 +From: schaecsn +Date: Sun, 17 Nov 2019 21:24:13 -0800 +Subject: [PATCH] thermal: rockchip: enable hwmon + +Enable hwmon for the soc and gpu temperature sensors. + +Signed-off-by: Stefan Schaeckeler +--- + drivers/thermal/rockchip_thermal.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c +index 343c2f5c5a25..e47c60010259 100644 +--- a/drivers/thermal/rockchip_thermal.c ++++ b/drivers/thermal/rockchip_thermal.c +@@ -19,6 +19,8 @@ + #include + #include + ++#include "thermal_hwmon.h" ++ + /** + * If the temperature over a period of time High, + * the resulting TSHUT gave CRU module,let it reset the entire chip, +@@ -1321,8 +1323,15 @@ static int rockchip_thermal_probe(struct platform_device *pdev) + + thermal->chip->control(thermal->regs, true); + +- for (i = 0; i < thermal->chip->chn_num; i++) ++ for (i = 0; i < thermal->chip->chn_num; i++) { + rockchip_thermal_toggle_sensor(&thermal->sensors[i], true); ++ thermal->sensors[i].tzd->tzp->no_hwmon = false; ++ error = thermal_add_hwmon_sysfs(thermal->sensors[i].tzd); ++ if (error) ++ dev_warn(&pdev->dev, ++ "failed to register sensor %d with hwmon: %d\n", ++ i, error); ++ } + + platform_set_drvdata(pdev, thermal); + +@@ -1344,6 +1353,7 @@ static int rockchip_thermal_remove(struct platform_device *pdev) + for (i = 0; i < thermal->chip->chn_num; i++) { + struct rockchip_thermal_sensor *sensor = &thermal->sensors[i]; + ++ thermal_remove_hwmon_sysfs(sensor->tzd); + rockchip_thermal_toggle_sensor(sensor, false); + } + + +From b5bcb54fe763aa9f40bae7af7e0629a3a6b93a52 Mon Sep 17 00:00:00 2001 +From: Robin Murphy +Date: Thu, 28 Nov 2019 20:59:27 +0000 +Subject: [PATCH] arm64: dts: rockchip: Add GPU cooling device for RK3399 + +As for RK3288, now that we have a binding for the GPU we can +hook up the missing cooling device for the thermal zone. + +Signed-off-by: Robin Murphy +--- + arch/arm64/boot/dts/rockchip/rk3399.dtsi | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +index e62ea0e2b657..aa0838adb224 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi +@@ -827,6 +827,14 @@ + type = "critical"; + }; + }; ++ ++ cooling-maps { ++ map0 { ++ trip = <&gpu_alert0>; ++ cooling-device = ++ <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ }; ++ }; + }; + }; + +@@ -1886,6 +1894,7 @@ + ; + interrupt-names = "gpu", "job", "mmu"; + clocks = <&cru ACLK_GPU>; ++ #cooling-cells = <2>; + power-domains = <&power RK3399_PD_GPU>; + status = "disabled"; + }; + diff --git a/target/linux/rockchip/patches-5.4/006-rk3328_add_mmc_reset.patch b/target/linux/rockchip/patches-5.4/006-rk3328_add_mmc_reset.patch new file mode 100644 index 000000000..c66fbfbba --- /dev/null +++ b/target/linux/rockchip/patches-5.4/006-rk3328_add_mmc_reset.patch @@ -0,0 +1,40 @@ +From 764e6cf1c0ffcfdbac7a259bc3ce4a7c4f221f75 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 29 Dec 2019 22:13:22 +0000 +Subject: [PATCH] arm64: dts: rockchip: add mmc reset on rk3328 + +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index 635f68fdc85c..3c50c11c2e5b 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -831,6 +831,8 @@ + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + max-frequency = <150000000>; ++ resets = <&cru SRST_MMC0>; ++ reset-names = "reset"; + status = "disabled"; + }; + +@@ -843,6 +845,8 @@ + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + max-frequency = <150000000>; ++ resets = <&cru SRST_SDIO>; ++ reset-names = "reset"; + status = "disabled"; + }; + +@@ -855,6 +859,8 @@ + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + max-frequency = <150000000>; ++ resets = <&cru SRST_EMMC>; ++ reset-names = "reset"; + status = "disabled"; + }; + diff --git a/target/linux/rockchip/patches-5.4/007-add_mmc_poweroff.patch b/target/linux/rockchip/patches-5.4/007-add_mmc_poweroff.patch new file mode 100644 index 000000000..ed0078c5a --- /dev/null +++ b/target/linux/rockchip/patches-5.4/007-add_mmc_poweroff.patch @@ -0,0 +1,94 @@ +From 1049f9202ff060e16121c74fb712daea48979e42 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 11 Oct 2019 08:01:37 +0000 +Subject: [PATCH] mmc: dw_mmc: add power_off callback + +Signed-off-by: Jonas Karlman +--- + drivers/mmc/host/dw_mmc.c | 3 +++ + drivers/mmc/host/dw_mmc.h | 1 + + 2 files changed, 4 insertions(+) + +diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c +index 79c55c7b4afd..84557cdecf2a 100644 +--- a/drivers/mmc/host/dw_mmc.c ++++ b/drivers/mmc/host/dw_mmc.c +@@ -1493,6 +1493,9 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) + regulator_disable(mmc->supply.vqmmc); + slot->host->vqmmc_enabled = false; + ++ if (drv_data && drv_data->power_off) ++ drv_data->power_off(slot->host); ++ + regs = mci_readl(slot->host, PWREN); + regs &= ~(1 << slot->id); + mci_writel(slot->host, PWREN, regs); +diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h +index da5923a92e60..0b5c880364c5 100644 +--- a/drivers/mmc/host/dw_mmc.h ++++ b/drivers/mmc/host/dw_mmc.h +@@ -563,5 +563,6 @@ struct dw_mci_drv_data { + struct mmc_ios *ios); + int (*switch_voltage)(struct mmc_host *mmc, + struct mmc_ios *ios); ++ void (*power_off)(struct dw_mci *host); + }; + #endif /* _DW_MMC_H_ */ + +From 7f34988c4b1477568018aefdab4554f722985c29 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Fri, 11 Oct 2019 08:01:37 +0000 +Subject: [PATCH] mmc: dw_mmc-rockchip: try set vqmmc regulator to 3.3V on + power_off + +Signed-off-by: Jonas Karlman +--- + drivers/mmc/host/dw_mmc-rockchip.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c +index d4d02134848c..05410f90ddd3 100644 +--- a/drivers/mmc/host/dw_mmc-rockchip.c ++++ b/drivers/mmc/host/dw_mmc-rockchip.c +@@ -24,6 +24,32 @@ struct dw_mci_rockchip_priv_data { + int num_phases; + }; + ++static void dw_mci_rk3288_power_off(struct dw_mci *host) ++{ ++ struct mmc_host *mmc = host->slot->mmc; ++ struct mmc_ios *ios = &mmc->ios; ++ int old_signal_voltage; ++ ++ if (IS_ERR(mmc->supply.vqmmc)) ++ return; ++ ++ if (mmc_host_is_spi(mmc)) ++ return; ++ ++ if (ios->vdd != 0 || ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) ++ return; ++ ++ old_signal_voltage = ios->signal_voltage; ++ ++ ios->signal_voltage = MMC_SIGNAL_VOLTAGE_330; ++ ios->vdd = fls(mmc->ocr_avail) - 1; ++ ++ if (mmc_regulator_set_vqmmc(mmc, ios)) ++ ios->signal_voltage = old_signal_voltage; ++ ++ ios->vdd = 0; ++} ++ + static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios) + { + struct dw_mci_rockchip_priv_data *priv = host->priv; +@@ -319,6 +345,7 @@ static const struct dw_mci_drv_data rk3288_drv_data = { + .execute_tuning = dw_mci_rk3288_execute_tuning, + .parse_dt = dw_mci_rk3288_parse_dt, + .init = dw_mci_rockchip_init, ++ .power_off = dw_mci_rk3288_power_off, + }; + + static const struct of_device_id dw_mci_rockchip_match[] = { + diff --git a/target/linux/rockchip/patches-5.4/008-mmc_rename.patch b/target/linux/rockchip/patches-5.4/008-mmc_rename.patch new file mode 100644 index 000000000..f1ecd8e0b --- /dev/null +++ b/target/linux/rockchip/patches-5.4/008-mmc_rename.patch @@ -0,0 +1,56 @@ +From 3ef7c2558f31745588473b75a655894b37e62116 Mon Sep 17 00:00:00 2001 +From: Johan Jonker +Date: Wed, 15 Jan 2020 19:52:44 +0100 +Subject: arm64: dts: rockchip: rename dwmmc node names to mmc + +Current dts files with 'dwmmc' nodes are manually verified. +In order to automate this process rockchip-dw-mshc.txt +has to be converted to yaml. In the new setup +rockchip-dw-mshc.yaml will inherit properties from +mmc-controller.yaml and synopsys-dw-mshc-common.yaml. +'dwmmc' will no longer be a valid name for a node, +so change them all to 'mmc' + +Signed-off-by: Johan Jonker +Link: https://lore.kernel.org/r/20200115185244.18149-2-jbx6244@gmail.com +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +(limited to 'arch/arm64/boot/dts/rockchip/rk3328.dtsi') + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index c9ff1188bd7b..1f53ead52c7f 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -822,7 +822,7 @@ + }; + }; + +- sdmmc: dwmmc@ff500000 { ++ sdmmc: mmc@ff500000 { + compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xff500000 0x0 0x4000>; + interrupts = ; +@@ -836,7 +836,7 @@ + status = "disabled"; + }; + +- sdio: dwmmc@ff510000 { ++ sdio: mmc@ff510000 { + compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xff510000 0x0 0x4000>; + interrupts = ; +@@ -850,7 +850,7 @@ + status = "disabled"; + }; + +- emmc: dwmmc@ff520000 { ++ emmc: mmc@ff520000 { + compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xff520000 0x0 0x4000>; + interrupts = ; +-- +cgit 1.2-0.3.lf.el7 + diff --git a/target/linux/rockchip/patches-5.4/009-rk3328_add_sdmmc_ext_node.patch b/target/linux/rockchip/patches-5.4/009-rk3328_add_sdmmc_ext_node.patch new file mode 100644 index 000000000..829ff9014 --- /dev/null +++ b/target/linux/rockchip/patches-5.4/009-rk3328_add_sdmmc_ext_node.patch @@ -0,0 +1,34 @@ +From 480b56effc7d96a1f87ee50e055ba2936fdad1f8 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Sun, 29 Dec 2019 22:14:02 +0000 +Subject: [PATCH] arm64: dts: rockchip: add sdmmc_ext node on rk3328 + +--- + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +index 3c50c11c2e5b..1c8057c7bcd3 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi +@@ -987,6 +987,20 @@ + }; + }; + ++ sdmmc_ext: mmc@ff5f0000 { ++ compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; ++ reg = <0x0 0xff5f0000 0x0 0x4000>; ++ interrupts = ; ++ clocks = <&cru HCLK_SDMMC_EXT>, <&cru SCLK_SDMMC_EXT>, ++ <&cru SCLK_SDMMC_EXT_DRV>, <&cru SCLK_SDMMC_EXT_SAMPLE>; ++ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; ++ fifo-depth = <0x100>; ++ max-frequency = <150000000>; ++ resets = <&cru SRST_SDMMCEXT>; ++ reset-names = "reset"; ++ status = "disabled"; ++ }; ++ + gic: interrupt-controller@ff811000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; diff --git a/target/linux/rockchip/patches-5.4/010-nanopi-r2s-rtl8152-leds.patch b/target/linux/rockchip/patches-5.4/010-nanopi-r2s-rtl8152-leds.patch new file mode 100644 index 000000000..eea0c9763 --- /dev/null +++ b/target/linux/rockchip/patches-5.4/010-nanopi-r2s-rtl8152-leds.patch @@ -0,0 +1,36 @@ +From 2d4f786f94b331904682c24a792462726d474007 Mon Sep 17 00:00:00 2001 +From: hmz007 +Date: Mon, 23 Dec 2019 13:10:06 +0800 +Subject: [PATCH] r8152: Add module param for customized LEDs + +Signed-off-by: hmz007 +--- + drivers/net/usb/r8152.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c +index eb78f6d9390c..ec737fffcded 100644 +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -37,6 +37,11 @@ + #define DRIVER_DESC "Realtek RTL8152/RTL8153 Based USB Ethernet Adapters" + #define MODULENAME "r8152" + ++/* LED0: Activity, LED1: Link */ ++static int ledsel = 0x78; ++module_param(ledsel, int, 0); ++MODULE_PARM_DESC(ledsel, "Override default LED configuration"); ++ + #define R8152_PHY_ID 32 + + #define PLA_IDR 0xc000 +@@ -4545,6 +4550,9 @@ static void r8153b_init(struct r8152 *tp) + ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); + ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); + ++ /* set customized led */ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_LEDSEL, ledsel); ++ + rtl_tally_reset(tp); + + tp->coalesce = 15000; /* 15 us */ diff --git a/target/linux/rockchip/patches-5.4/011-nanopi-r2s-mac-frfom-dt.patch b/target/linux/rockchip/patches-5.4/011-nanopi-r2s-mac-frfom-dt.patch new file mode 100644 index 000000000..4040e88f0 --- /dev/null +++ b/target/linux/rockchip/patches-5.4/011-nanopi-r2s-mac-frfom-dt.patch @@ -0,0 +1,40 @@ +From 27dfe6f4347e883fd618d5a37500c7f6d3652fb9 Mon Sep 17 00:00:00 2001 +From: hmz007 +Date: Fri, 22 Nov 2019 19:03:00 +0800 +Subject: [PATCH] r8152: support to get MAC address from device tree + +Signed-off-by: hmz007 +--- + drivers/net/usb/r8152.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c +index b2507c59ba8b..eb78f6d9390c 100644 +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1298,6 +1299,17 @@ static int determine_ethernet_addr(struct r8152 *tp, struct sockaddr *sa) + if (ret < 0) { + netif_err(tp, probe, dev, "Get ether addr fail\n"); + } else if (!is_valid_ether_addr(sa->sa_data)) { ++ /* try to get MAC address from DT */ ++ if (tp->udev->dev.of_node) { ++ const u8 *mac = of_get_mac_address(tp->udev->dev.of_node); ++ if (!IS_ERR(mac) && is_valid_ether_addr(mac)) { ++ ether_addr_copy(sa->sa_data, mac); ++ netif_info(tp, probe, dev, "DT mac addr %pM\n", ++ sa->sa_data); ++ return 0; ++ } ++ } ++ + netif_err(tp, probe, dev, "Invalid ether addr %pM\n", + sa->sa_data); + eth_hw_addr_random(dev);