diff --git a/package/boot/uboot-rockchip/Makefile b/package/boot/uboot-rockchip/Makefile index 25e8ce0be..69ce25dae 100644 --- a/package/boot/uboot-rockchip/Makefile +++ b/package/boot/uboot-rockchip/Makefile @@ -182,6 +182,17 @@ define U-Boot/opc-h68k-rk3568 DDR:=rk3568_ddr_1560MHz_v1.13.bin endef +define U-Boot/photonicat-rk3568 + BUILD_SUBTARGET:=armv8 + NAME:=Ariaboard Photonicat + BUILD_DEVICES:= \ + ariaboard_photonicat + DEPENDS:=+PACKAGE_u-boot-photonicat-rk3568:arm-trusted-firmware-rk3568 + PKG_BUILD_DEPENDS:=arm-trusted-firmware-rockchip-vendor + ATF:=rk3568_bl31_v1.28.elf + DDR:=rk3568_ddr_1560MHz_v1.13.bin +endef + define U-Boot/radxa-e25-rk3568 BUILD_SUBTARGET:=armv8 NAME:=Radxa E25 @@ -230,6 +241,7 @@ endef UBOOT_TARGETS := \ mrkaio-m68s-rk3568 \ opc-h68k-rk3568 \ + photonicat-rk3568 \ radxa-e25-rk3568 \ rock-3a-rk3568 \ r66s-rk3568 \ diff --git a/package/boot/uboot-rockchip/patches/314-rockchip-rk3568-Add-support-for-photonicat.patch b/package/boot/uboot-rockchip/patches/314-rockchip-rk3568-Add-support-for-photonicat.patch new file mode 100644 index 000000000..216186289 --- /dev/null +++ b/package/boot/uboot-rockchip/patches/314-rockchip-rk3568-Add-support-for-photonicat.patch @@ -0,0 +1,208 @@ +--- a/arch/arm/dts/Makefile ++++ b/arch/arm/dts/Makefile +@@ -175,6 +175,7 @@ dtb-$(CONFIG_ROCKCHIP_RK3399) += \ + rk3568-opc-h68k.dtb \ + rk3568-mrkaio-m68s.dtb \ + rk3568-nanopi-r5s.dtb \ ++ rk3568-photonicat.dtb \ + rk3566-quartz64-a.dtb \ + rk3568-rock-3a.dtb \ + rk3568-rock-pi-e25.dtb +--- /dev/null ++++ b/arch/arm/dts/rk3568-photonicat-u-boot.dtsi +@@ -0,0 +1,33 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++#include "rk3568-u-boot.dtsi" ++ ++/ { ++ chosen { ++ stdout-path = &uart2; ++ u-boot,spl-boot-order = "same-as-spl", &sdmmc0, &sdhci; ++ }; ++}; ++ ++&gpio0 { ++ u-boot,dm-spl; ++}; ++ ++&pinctrl { ++ u-boot,dm-spl; ++}; ++ ++&sdmmc0 { ++ bus-width = <4>; ++ u-boot,spl-fifo-mode; ++}; ++ ++&uart2 { ++ u-boot,dm-spl; ++ clock-frequency = <24000000>; ++ status = "okay"; ++}; ++ ++&vcc3v3_sd { ++ u-boot,dm-spl; ++}; +--- /dev/null ++++ b/arch/arm/dts/rk3568-photonicat.dts +@@ -0,0 +1,54 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++/dts-v1/; ++#include ++#include ++#include "rk3568.dtsi" ++ ++/ { ++ model = "Ariaboard Photonicat"; ++ compatible = "ariaboard,photonicat", "rockchip,rk3568"; ++ ++ chosen: chosen { ++ stdout-path = "serial2:1500000n8"; ++ }; ++ ++ vcc3v3_sd: vcc3v3_sd { ++ compatible = "regulator-fixed"; ++ gpio = <&gpio0 RK_PB6 GPIO_ACTIVE_LOW>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&vcc_sd_h>; ++ regulator-boot-on; ++ regulator-name = "vcc3v3_sd"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ }; ++}; ++ ++&pinctrl { ++ vcc_sd { ++ vcc_sd_h: vcc-sd-h { ++ rockchip,pins = <0 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>; ++ }; ++ }; ++}; ++ ++&sdhci { ++ bus-width = <8>; ++ max-frequency = <200000000>; ++ non-removable; ++ status = "okay"; ++}; ++ ++&sdmmc0 { ++ max-frequency = <52000000>; ++ status = "okay"; ++}; ++ ++&sdmmc1 { ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++}; +--- /dev/null ++++ b/configs/photonicat-rk3568_defconfig +@@ -0,0 +1,101 @@ ++CONFIG_ARM=y ++CONFIG_SKIP_LOWLEVEL_INIT=y ++CONFIG_ARCH_ROCKCHIP=y ++CONFIG_SYS_TEXT_BASE=0x00a00000 ++CONFIG_SPL_LIBCOMMON_SUPPORT=y ++CONFIG_SPL_LIBGENERIC_SUPPORT=y ++CONFIG_NR_DRAM_BANKS=2 ++CONFIG_DEFAULT_DEVICE_TREE="rk3568-photonicat" ++CONFIG_ROCKCHIP_RK3568=y ++CONFIG_SPL_ROCKCHIP_BACK_TO_BROM=y ++CONFIG_SPL_ROCKCHIP_COMMON_BOARD=y ++CONFIG_SPL_GPIO=y ++CONFIG_SPL_MMC=y ++CONFIG_SPL_SERIAL=y ++CONFIG_SPL_STACK_R_ADDR=0x600000 ++CONFIG_TARGET_EVB_RK3568=y ++CONFIG_DEBUG_UART_BASE=0xFE660000 ++CONFIG_DEBUG_UART_CLOCK=24000000 ++CONFIG_DEBUG_UART=y ++CONFIG_SYS_LOAD_ADDR=0xc00800 ++CONFIG_API=y ++CONFIG_FIT=y ++CONFIG_FIT_VERBOSE=y ++CONFIG_SPL_LOAD_FIT=y ++CONFIG_OF_SYSTEM_SETUP=y ++CONFIG_DEFAULT_FDT_FILE="rockchip/rk3568-photonicat.dtb" ++# CONFIG_SYS_DEVICE_NULLDEV is not set ++CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS=2 ++# CONFIG_DISPLAY_CPUINFO is not set ++CONFIG_DISPLAY_BOARDINFO_LATE=y ++# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set ++CONFIG_SPL_STACK_R=y ++CONFIG_SPL_SEPARATE_BSS=y ++CONFIG_SPL_ADC=y ++CONFIG_SPL_ATF=y ++CONFIG_SPL_BOARD_INIT=y ++CONFIG_CMD_ADC=y ++CONFIG_CMD_BIND=y ++CONFIG_CMD_CLK=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_I2C=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_USB=y ++# CONFIG_CMD_SETEXPR is not set ++CONFIG_CMD_PMIC=y ++CONFIG_CMD_REGULATOR=y ++# CONFIG_SPL_DOS_PARTITION is not set ++CONFIG_SPL_OF_CONTROL=y ++CONFIG_OF_LIVE=y ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_SPL_DM_WARN=y ++CONFIG_SPL_REGMAP=y ++CONFIG_SPL_SYSCON=y ++CONFIG_SPL_CLK=y ++CONFIG_ROCKCHIP_GPIO=y ++CONFIG_ROCKCHIP_GPIO_V2=y ++CONFIG_SYS_I2C_ROCKCHIP=y ++CONFIG_MISC=y ++CONFIG_MMC_IO_VOLTAGE=y ++CONFIG_SPL_MMC_IO_VOLTAGE=y ++CONFIG_MMC_HS200_SUPPORT=y ++CONFIG_SPL_MMC_HS200_SUPPORT=y ++CONFIG_MMC_DW=y ++CONFIG_MMC_DW_ROCKCHIP=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_SDMA=y ++CONFIG_MMC_SDHCI_ROCKCHIP=y ++CONFIG_DM_ETH=y ++CONFIG_ETH_DESIGNWARE=y ++CONFIG_GMAC_ROCKCHIP=y ++CONFIG_POWER_DOMAIN=y ++CONFIG_DM_PMIC=y ++CONFIG_PMIC_RK8XX=y ++CONFIG_SPL_PMIC_RK8XX=y ++CONFIG_REGULATOR_PWM=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_SPL_DM_REGULATOR_FIXED=y ++CONFIG_DM_REGULATOR_GPIO=y ++CONFIG_REGULATOR_RK8XX=y ++CONFIG_PWM_ROCKCHIP=y ++CONFIG_SPL_RAM=y ++CONFIG_DM_RESET=y ++CONFIG_BAUDRATE=1500000 ++CONFIG_DEBUG_UART_SHIFT=2 ++CONFIG_SYSRESET=y ++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_DWC3=y ++CONFIG_USB_DWC3_GENERIC=y ++CONFIG_ROCKCHIP_USB2_PHY=y ++CONFIG_USB_KEYBOARD=y ++CONFIG_USB_HOST_ETHER=y ++CONFIG_USB_ETHER_LAN75XX=y ++CONFIG_USB_ETHER_LAN78XX=y ++CONFIG_USB_ETHER_SMSC95XX=y ++CONFIG_ERRNO_STR=y diff --git a/package/lean/pcat-manager/Makefile b/package/lean/pcat-manager/Makefile new file mode 100644 index 000000000..2004114db --- /dev/null +++ b/package/lean/pcat-manager/Makefile @@ -0,0 +1,48 @@ +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=pcat-manager +PKG_VERSION:=1.0.16 +PKG_RELEASE:=2 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2022-11-17 +PKG_SOURCE_URL:=https://github.com/photonicat/rockchip_rk3568_pcat_manager +PKG_SOURCE_VERSION:=b35d84e1636bbed8751d15f4b73c911912652435 +PKG_MIRROR_HASH:=f06ef0011ed28bb7c42c308f83b89c1f4b586950bdaf5c562a4b5708789e6746 + +PKG_LICENSE:=GPL-3.0 +PKG_LICENSE_FILES:=LICENSE + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/meson.mk + +define Package/pcat-manager + SECTION:=utils + CATEGORY:=Utilities + TITLE:=photonicat watchdog + URL:=https://photonicat.com + DEPENDS:=+glib2 +libgpiod +libjson-c +libusb-1.0 +endef + +define Package/pcat-manager/description + Photonicat Manager is a system service for + power management and modem controlling. +endef + +define Package/pcat-manager/install + $(INSTALL_DIR) $(1)/etc/ + $(INSTALL_CONF) ./files/pcat-manager.conf $(1)/etc + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/pcat-manager.init $(1)/etc/init.d/pcat-manager + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) \ + $(PKG_INSTALL_DIR)/usr/bin/pcat-manager \ + $(1)/usr/bin/pcat-manager +endef + +$(eval $(call BuildPackage,pcat-manager)) diff --git a/package/lean/pcat-manager/files/pcat-manager.conf b/package/lean/pcat-manager/files/pcat-manager.conf new file mode 100644 index 000000000..0d48d719c --- /dev/null +++ b/package/lean/pcat-manager/files/pcat-manager.conf @@ -0,0 +1,28 @@ +[Hardware] +GPIOModemPowerChip=gpiochip4 +GPIOModemPowerLine=18 +GPIOModemPowerActiveLow=0 +GPIOModemRFKillChip=gpiochip4 +GPIOModemRFKillLine=20 +GPIOModemRFKillActiveLow=1 +GPIOModemResetChip=gpiochip0 +GPIOModemResetLine=8 +GPIOModemResetActiveLow=0 + +[PowerManager] +SerialDevice=/dev/ttyS0 +SerialBaud=115200 +AutoShutdownVoltageGeneral=0 +AutoShutdownVoltageLTE=0 +AutoShutdownVoltage5G=3600 +LEDHighVoltage=0 +LEDMediumVoltage=0 +LEDLowVoltage=0 +LEDWorkLowVoltage=0 +StartupVoltage=0 +ChargerLimitVoltage=0 +ChargerFastVoltage=0 +BatteryFullThreshold=4100 +BatteryDischargeTableNormal=4100;4040;3980;3920;3870;3820;3790;3770;3740;3680;3450 +BatteryDischargeTable5G=4100;4040;3980;3920;3870;3820;3790;3770;3740;3680;3600 +BatteryChargeTable=4100;4060;4020;3980;3940;3900;3860;3820;3780;3740;3700 diff --git a/package/lean/pcat-manager/files/pcat-manager.init b/package/lean/pcat-manager/files/pcat-manager.init new file mode 100644 index 000000000..e6a6b3829 --- /dev/null +++ b/package/lean/pcat-manager/files/pcat-manager.init @@ -0,0 +1,24 @@ +#!/bin/sh /etc/rc.common + +START=45 +STOP=89 + +start() { + service_start /usr/bin/pcat-manager -D +} + +stop() { + service_stop /usr/bin/pcat-manager +} + +restart() { + killall -USR1 pcat-manager + stop + start +} + +shutdown() { + touch /tmp/pcat-manager-shutdown.tmp + stop + rfkill block wwan 2>/dev/null || true +} diff --git a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-photonicat.dts b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-photonicat.dts new file mode 100644 index 000000000..800422f3a --- /dev/null +++ b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3568-photonicat.dts @@ -0,0 +1,592 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +/dts-v1/; +#include +#include +#include +#include +#include "rk3568.dtsi" + +/ { + model = "Ariaboard Photonicat"; + compatible = "ariaboard,photonicat", "rockchip,rk3568"; + + aliases { + ethernet0 = &gmac0; + ethernet1 = &gmac1; + mmc0 = &sdhci; + mmc1 = &sdmmc0; + mmc2 = &sdmmc1; + }; + + chosen: chosen { + stdout-path = "serial2:1500000n8"; + }; + + gmac0_xpcsclk: xpcs-gmac0-clock { + compatible = "fixed-clock"; + clock-frequency = <125000000>; + clock-output-names = "clk_gmac0_xpcs_mii"; + #clock-cells = <0>; + }; + +#ifdef DTS_NO_LEGACY + hdmi-con { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi_out_con>; + }; + }; + }; +#endif + + modem-rfkill { + compatible = "rfkill-gpio"; + name = "modem-rfkill"; + type = "wwan"; + reset-gpios = <&gpio4 RK_PC2 GPIO_ACTIVE_HIGH>; + shutdown-gpios = <&gpio4 RK_PC4 GPIO_ACTIVE_LOW>; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&pmucru CLK_RTC_32K>; + clock-names = "ext_clock"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h &clk32k_out1>; + reset-gpios = <&gpio2 RK_PB1 GPIO_ACTIVE_LOW>; + }; + + vcc_1v8: vcc-1v8 { + compatible = "regulator-fixed"; + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc3v3_sys>; + }; + + vcc_3v3: vcc-3v3 { + compatible = "regulator-fixed"; + regulator-name = "vcc_3v3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc3v3_sys>; + }; + + vcc_sysin: vcc-sysin { + compatible = "regulator-fixed"; + regulator-name = "vcc_sysin"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + vcc_syson: vcc-syson { + compatible = "regulator-fixed"; + regulator-name = "vcc_syson"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc_sysin>; + }; + + vdda_0v9: vdda-0v9 { + compatible = "regulator-fixed"; + regulator-name = "vdda_0v9"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + vin-supply = <&vcc3v3_sys>; + }; + + vcca_1v8: vcca-1v8 { + compatible = "regulator-fixed"; + regulator-name = "vcca_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc3v3_sys>; + }; + + /* pi6c pcie clock generator */ + vcc3v3_pi6c: vcc3v3-pi6c { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie_enable_h>; + regulator-name = "vcc3v3_pi6c"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_syson>; + }; + + /* actually fed by vcc_syson, dependent + * on pi6c clock generator + */ + vcc3v3_pcie: vcc3v3-pcie { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_pcie"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc3v3_pi6c>; + }; + + vcc3v3_ngff: vcc3v3-ngff { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PB0 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&ngffpcie_enable_h>; + regulator-name = "vcc3v3_ngff"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc3v3_sys>; + }; + + vcc3v3_sd: vcc3v3_sd { + compatible = "regulator-fixed"; + gpio = <&gpio0 RK_PB6 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc_sd_h>; + regulator-boot-on; + regulator-name = "vcc3v3_sd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_3v3>; + }; + + vcc3v3_sys: vcc3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_syson>; + }; + + vcc5v0_usb_otg: vcc5v0-usb-otg { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_usb_otg_en>; + regulator-name = "vcc5v0_usb_otg"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc_sysin>; + }; + + vdd_gpu: vdd-gpu { + compatible = "pwm-regulator"; + regulator-name = "vdd_gpu"; + regulator-always-on; + regulator-boot-on; + regulator-init-microvolt = <900000>; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-settling-time-up-us = <250>; + + pwms = <&pwm2 0 5000 1>; + pwm-supply = <&vcc_syson>; + }; + + vdd_logic: vdd-logic { + compatible = "pwm-regulator"; + regulator-name = "vdd_logic"; + regulator-always-on; + regulator-boot-on; + regulator-init-microvolt = <900000>; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-settling-time-up-us = <250>; + + pwms = <&pwm1 0 5000 1>; + pwm-supply = <&vcc_syson>; + }; +}; + +&combphy0 { + status = "okay"; +}; + +&combphy1 { + status = "okay"; +}; + +&combphy2 { + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu1 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu2 { + cpu-supply = <&vdd_cpu>; +}; + +&cpu3 { + cpu-supply = <&vdd_cpu>; +}; + +&gmac0 { + assigned-clocks = <&cru SCLK_GMAC0_RX_TX>; + assigned-clock-parents = <&gmac0_xpcsclk>; + power-domains = <&power RK3568_PD_PIPE>; + phys = <&combphy2 PHY_TYPE_SGMII>; + phy-handle = <&sgmii_phy>; + phy-mode = "sgmii"; + phy-supply = <&vcc_3v3>; + pinctrl-names = "default"; + pinctrl-0 = <&gmac0_miim>; + rockchip,xpcs = <&xpcs>; + snps,reset-gpio = <&gpio3 RK_PC6 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + snps,reset-delays-us = <0 20000 100000>; + tx_delay = <0xff>; + rx_delay = <0xff>; + status = "okay"; +}; + +&gmac1 { + assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>; + assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>; + assigned-clock-rates = <0>, <125000000>; + clock_in_out = "output"; + phy-handle = <&rgmii_phy>; + phy-mode = "rgmii"; + phy-supply = <&vcc_3v3>; + pinctrl-names = "default"; + pinctrl-0 = <&gmac1m1_miim + &gmac1m1_tx_bus2 + &gmac1m1_rx_bus2 + &gmac1m1_rgmii_clk + &gmac1m1_rgmii_bus>; + snps,reset-gpio = <&gpio4 RK_PC0 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + snps,reset-delays-us = <0 20000 100000>; + tx_delay = <0x30>; + rx_delay = <0x10>; + status = "okay"; +}; + +#ifdef DTS_NO_LEGACY +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + +&hdmi { + avdd-0v9-supply = <&vdda_0v9>; + avdd-1v8-supply = <&vcca_1v8>; + status = "okay"; +}; + +&hdmi_in { + hdmi_in_vp0: endpoint { + remote-endpoint = <&vp0_out_hdmi>; + }; +}; + +&hdmi_out { + hdmi_out_con: endpoint { + remote-endpoint = <&hdmi_con_in>; + }; +}; + +&hdmi_sound { + status = "okay"; +}; +#endif + +&i2c0 { + status = "okay"; + + vdd_cpu: regulator@1c { + compatible = "tcs,tcs4525"; + reg = <0x1c>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_cpu"; + regulator-always-on; + regulator-boot-on; + regulator-init-microvolt = <900000>; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1390000>; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc_syson>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; +}; + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2m1_xfer>; + status = "okay"; +}; + +#ifdef DTS_NO_LEGACY +&i2s0_8ch { + status = "okay"; +}; +#endif + +&mdio0 { + sgmii_phy: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0x0>; + }; +}; + +&mdio1 { + rgmii_phy: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0x0>; + }; +}; + +&pcie30phy { + phy-supply = <&vcc3v3_pi6c>; + status = "okay"; +}; + +&pcie3x2 { + reset-gpios = <&gpio0 RK_PC3 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc3v3_pcie>; + status = "okay"; +}; + +&pinctrl { + bt { + bt_enable_h: bt-enable-h { + rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pcie { + pcie_enable_h: pcie-enable-h { + rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <2 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb { + vcc5v0_usb_otg_en: vcc5v0_usb_otg_en { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + ngffpcie_enable_h: ngffpcie-enable-h { + rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + vcc_sd { + vcc_sd_h: vcc-sd-h { + rockchip,pins = <0 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pmu_io_domains { + pmuio1-supply = <&vcc_3v3>; + pmuio2-supply = <&vcc_3v3>; + vccio1-supply = <&vcc_3v3>; + vccio3-supply = <&vcc_3v3>; + vccio4-supply = <&vcc_1v8>; + vccio5-supply = <&vcc_3v3>; + vccio6-supply = <&vcc_3v3>; + vccio7-supply = <&vcc_3v3>; + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; + +&rng { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcca_1v8>; + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + max-frequency = <200000000>; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd>; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&vcc_1v8>; +}; + +&sdmmc0 { + bus-width = <4>; + cap-sd-highspeed; + cd-gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_LOW>; + disable-wp; + no-1-8-v; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd>; + vmmc-supply = <&vcc3v3_sd>; + vqmmc-supply = <&vcc_3v3>; + status = "okay"; +}; + +&sdmmc1 { + bus-width = <4>; + cap-sd-highspeed; + keep-power-in-suspend; + mmc-pwrseq = <&sdio_pwrseq>; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_clk &sdmmc1_cmd>; + sd-uhs-sdr104; + vmmc-supply = <&vcc3v3_sys>; + vqmmc-supply = <&vcc_1v8>; + status = "okay"; + + sdio_wifi@1 { + reg = <1>; + interrupt-parent = <&gpio2>; + interrupts = ; + interrupt-names = "host-wake"; + }; +}; + +&tsadc { + rockchip,hw-tshut-mode = <1>; + rockchip,hw-tshut-polarity = <0>; + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn &uart1m0_rtsn>; + status = "okay"; + uart-has-rtscts; + + bluetooth { + compatible = "qcom,qca9377-bt"; + enable-gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>; + clocks = <&pmucru CLK_RTC_32K>; + clock-names = "lpo"; + pinctrl-names = "default"; + pinctrl-0 = <&bt_enable_h>; + vddio-supply = <&vcc_1v8>; + }; +}; + +&uart2 { + status = "okay"; +}; + +&uart3 { + status = "okay"; +}; + +&uart4 { + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host0_xhci { + extcon = <&usb2phy0>; + status = "okay"; +}; + +&usb_host1_xhci { + status = "okay"; +}; + +&usb2phy0 { + status = "okay"; +}; + +&usb2phy0_host { + phy-supply = <&vcc3v3_ngff>; + status = "okay"; +}; + +&usb2phy0_otg { + phy-supply = <&vcc5v0_usb_otg>; + status = "okay"; +}; + +&usb2phy1 { + status = "okay"; +}; + +&usb2phy1_otg { + phy-supply = <&vcc5v0_usb_otg>; + status = "okay"; +}; + +#ifdef DTS_NO_LEGACY +&vop { + assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>; + assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>; + status = "okay"; +}; + +&vop_mmu { + status = "okay"; +}; + +&vp0 { + vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { + reg = ; + remote-endpoint = <&hdmi_in_vp0>; + }; +}; +#endif + +&xin32k { + pinctrl-names = "default"; + pinctrl-0 = <&clk32k_out1>; +}; + +&xpcs { + status = "okay"; +}; diff --git a/target/linux/rockchip/image/armv8.mk b/target/linux/rockchip/image/armv8.mk index 4b82770a0..f6ba3858c 100644 --- a/target/linux/rockchip/image/armv8.mk +++ b/target/linux/rockchip/image/armv8.mk @@ -2,6 +2,16 @@ # # Copyright (C) 2020 Tobias Maedel +define Device/ariaboard_photonicat + DEVICE_VENDOR := Ariaboard + DEVICE_MODEL := Photonicat + SOC := rk3568 + UBOOT_DEVICE_NAME := photonicat-rk3568 + IMAGE/sysupgrade.img.gz := boot-common | boot-script nanopi-r5s | pine64-img | gzip | append-metadata + DEVICE_PACKAGES := ar3k-firmware pcat-manager +endef +TARGET_DEVICES += ariaboard_photonicat + define Device/ezpro_mrkaio-m68s DEVICE_VENDOR := EZPRO DEVICE_MODEL := Mrkaio M68S diff --git a/target/linux/rockchip/patches-5.15/112-arm64-dts-rockchip-rk3568-Add-xpcs-support.patch b/target/linux/rockchip/patches-5.15/112-arm64-dts-rockchip-rk3568-Add-xpcs-support.patch new file mode 100644 index 000000000..ad137ee48 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/112-arm64-dts-rockchip-rk3568-Add-xpcs-support.patch @@ -0,0 +1,33 @@ +--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi +@@ -173,11 +173,13 @@ gmac0: ethernet@fe2a0000 { + clocks = <&cru SCLK_GMAC0>, <&cru SCLK_GMAC0_RX_TX>, + <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_MAC0_REFOUT>, + <&cru ACLK_GMAC0>, <&cru PCLK_GMAC0>, +- <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_GMAC0_PTP_REF>; ++ <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_GMAC0_PTP_REF>, ++ <&cru PCLK_XPCS>; + clock-names = "stmmaceth", "mac_clk_rx", + "mac_clk_tx", "clk_mac_refout", + "aclk_mac", "pclk_mac", +- "clk_mac_speed", "ptp_ref"; ++ "clk_mac_speed", "ptp_ref", ++ "pclk_xpcs"; + resets = <&cru SRST_A_GMAC0>; + reset-names = "stmmaceth"; + rockchip,grf = <&grf>; +--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +@@ -321,6 +321,12 @@ usb_host1_ohci: usb@fd8c0000 { + status = "disabled"; + }; + ++ xpcs: syscon@fda00000 { ++ compatible = "rockchip,rk3568-xpcs", "syscon"; ++ reg = <0x0 0xfda00000 0x0 0x200000>; ++ status = "disabled"; ++ }; ++ + pmugrf: syscon@fdc20000 { + compatible = "rockchip,rk3568-pmugrf", "syscon", "simple-mfd"; + reg = <0x0 0xfdc20000 0x0 0x10000>; diff --git a/target/linux/rockchip/patches-5.15/113-ethernet-stmicro-stmmac-Add-SGMII-QSGMII-support.patch b/target/linux/rockchip/patches-5.15/113-ethernet-stmicro-stmmac-Add-SGMII-QSGMII-support.patch new file mode 100644 index 000000000..cdbd0db43 --- /dev/null +++ b/target/linux/rockchip/patches-5.15/113-ethernet-stmicro-stmmac-Add-SGMII-QSGMII-support.patch @@ -0,0 +1,343 @@ +From ca89ea7e0760c096c6fd807d321ecb8416f8cd9d Mon Sep 17 00:00:00 2001 +From: David Wu +Date: Thu, 31 Dec 2020 18:32:03 +0800 +Subject: [PATCH] ethernet: stmicro: stmmac: Add SGMII/QSGMII support for + RK3568 + +After the completion of Clause 37 auto-negotiation, xpcs automatically +switches to the negotiated speed for 10/100/1000M. + +Change-Id: Iab9dd6ee61a35bf89fd3a0721f5d398de501a7ec +Signed-off-by: David Wu +--- + .../net/ethernet/stmicro/stmmac/dwmac-rk.c | 228 +++++++++++++++++- + 1 file changed, 217 insertions(+), 11 deletions(-) + +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -30,6 +31,8 @@ struct rk_gmac_ops { + void (*set_to_rgmii)(struct rk_priv_data *bsp_priv, + int tx_delay, int rx_delay); + void (*set_to_rmii)(struct rk_priv_data *bsp_priv); ++ void (*set_to_sgmii)(struct rk_priv_data *bsp_priv); ++ void (*set_to_qsgmii)(struct rk_priv_data *bsp_priv); + void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed); + void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed); + void (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv); +@@ -60,6 +63,7 @@ struct rk_priv_data { + struct clk *clk_mac_speed; + struct clk *aclk_mac; + struct clk *pclk_mac; ++ struct clk *pclk_xpcs; + struct clk *clk_phy; + + struct reset_control *phy_reset; +@@ -69,6 +73,7 @@ struct rk_priv_data { + int rx_delay; + + struct regmap *grf; ++ struct regmap *xpcs; + }; + + #define HIWORD_UPDATE(val, mask, shift) \ +@@ -81,6 +86,128 @@ struct rk_priv_data { + (((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \ + ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE)) + ++/* XPCS */ ++#define XPCS_APB_INCREMENT (0x4) ++#define XPCS_APB_MASK GENMASK_ULL(20, 0) ++ ++#define SR_MII_BASE (0x1F0000) ++#define SR_MII1_BASE (0x1A0000) ++ ++#define VR_MII_DIG_CTRL1 (0x8000) ++#define VR_MII_AN_CTRL (0x8001) ++#define VR_MII_AN_INTR_STS (0x8002) ++#define VR_MII_LINK_TIMER_CTRL (0x800A) ++ ++#define SR_MII_CTRL_AN_ENABLE \ ++ (BMCR_ANENABLE | BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000) ++#define MII_MAC_AUTO_SW (0x0200) ++#define PCS_MODE_OFFSET (0x1) ++#define MII_AN_INTR_EN (0x1) ++#define PCS_SGMII_MODE (0x2 << PCS_MODE_OFFSET) ++#define PCS_QSGMII_MODE (0X3 << PCS_MODE_OFFSET) ++#define VR_MII_CTRL_SGMII_AN_EN (PCS_SGMII_MODE | MII_AN_INTR_EN) ++#define VR_MII_CTRL_QSGMII_AN_EN (PCS_QSGMII_MODE | MII_AN_INTR_EN) ++ ++#define SR_MII_OFFSET(_x) ({ \ ++ typeof(_x) (x) = (_x); \ ++ (((x) == 0) ? SR_MII_BASE : (SR_MII1_BASE + ((x) - 1) * 0x10000)); \ ++}) \ ++ ++static int xpcs_read(void *priv, int reg) ++{ ++ struct rk_priv_data *bsp_priv = (struct rk_priv_data *)priv; ++ int ret, val; ++ ++ ret = regmap_read(bsp_priv->xpcs, ++ (u32)(reg * XPCS_APB_INCREMENT) & XPCS_APB_MASK, ++ &val); ++ if (ret) ++ return ret; ++ ++ return val; ++} ++ ++static int xpcs_write(void *priv, int reg, u16 value) ++{ ++ struct rk_priv_data *bsp_priv = (struct rk_priv_data *)priv; ++ ++ return regmap_write(bsp_priv->xpcs, ++ (reg * XPCS_APB_INCREMENT) & XPCS_APB_MASK, value); ++} ++ ++static int xpcs_poll_reset(struct rk_priv_data *bsp_priv, int dev) ++{ ++ /* Poll until the reset bit clears (50ms per retry == 0.6 sec) */ ++ unsigned int retries = 12; ++ int ret; ++ ++ do { ++ msleep(50); ++ ret = xpcs_read(bsp_priv, SR_MII_OFFSET(dev) + MDIO_CTRL1); ++ if (ret < 0) ++ return ret; ++ } while (ret & MDIO_CTRL1_RESET && --retries); ++ ++ return (ret & MDIO_CTRL1_RESET) ? -ETIMEDOUT : 0; ++} ++ ++static int xpcs_soft_reset(struct rk_priv_data *bsp_priv, int dev) ++{ ++ int ret; ++ ++ ret = xpcs_write(bsp_priv, SR_MII_OFFSET(dev) + MDIO_CTRL1, ++ MDIO_CTRL1_RESET); ++ if (ret < 0) ++ return ret; ++ ++ return xpcs_poll_reset(bsp_priv, dev); ++} ++ ++static int xpcs_setup(struct rk_priv_data *bsp_priv, int mode) ++{ ++ int ret, i, idx = bsp_priv->id; ++ u32 val; ++ ++ if (mode == PHY_INTERFACE_MODE_QSGMII && idx > 0) ++ return 0; ++ ++ ret = xpcs_soft_reset(bsp_priv, idx); ++ if (ret) { ++ dev_err(&bsp_priv->pdev->dev, "xpcs_soft_reset fail %d\n", ret); ++ return ret; ++ } ++ ++ xpcs_write(bsp_priv, SR_MII_OFFSET(0) + VR_MII_AN_INTR_STS, 0x0); ++ xpcs_write(bsp_priv, SR_MII_OFFSET(0) + VR_MII_LINK_TIMER_CTRL, 0x1); ++ ++ if (mode == PHY_INTERFACE_MODE_SGMII) ++ xpcs_write(bsp_priv, SR_MII_OFFSET(0) + VR_MII_AN_CTRL, ++ VR_MII_CTRL_SGMII_AN_EN); ++ else ++ xpcs_write(bsp_priv, SR_MII_OFFSET(0) + VR_MII_AN_CTRL, ++ VR_MII_CTRL_QSGMII_AN_EN); ++ ++ if (mode == PHY_INTERFACE_MODE_QSGMII) { ++ for (i = 0; i < 4; i++) { ++ val = xpcs_read(bsp_priv, ++ SR_MII_OFFSET(i) + VR_MII_DIG_CTRL1); ++ xpcs_write(bsp_priv, ++ SR_MII_OFFSET(i) + VR_MII_DIG_CTRL1, ++ val | MII_MAC_AUTO_SW); ++ xpcs_write(bsp_priv, SR_MII_OFFSET(i) + MII_BMCR, ++ SR_MII_CTRL_AN_ENABLE); ++ } ++ } else { ++ val = xpcs_read(bsp_priv, SR_MII_OFFSET(idx) + VR_MII_DIG_CTRL1); ++ xpcs_write(bsp_priv, SR_MII_OFFSET(idx) + VR_MII_DIG_CTRL1, ++ val | MII_MAC_AUTO_SW); ++ xpcs_write(bsp_priv, SR_MII_OFFSET(idx) + MII_BMCR, ++ SR_MII_CTRL_AN_ENABLE); ++ } ++ ++ return ret; ++} ++ + #define PX30_GRF_GMAC_CON1 0x0904 + + /* PX30_GRF_GMAC_CON1 */ +@@ -1008,6 +1135,7 @@ static const struct rk_gmac_ops rk3399_ops = { + #define RK3568_GRF_GMAC1_CON1 0x038c + + /* RK3568_GRF_GMAC0_CON1 && RK3568_GRF_GMAC1_CON1 */ ++#define RK3568_GMAC_GMII_MODE GRF_BIT(7) + #define RK3568_GMAC_PHY_INTF_SEL_RGMII \ + (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) + #define RK3568_GMAC_PHY_INTF_SEL_RMII \ +@@ -1023,6 +1151,46 @@ static const struct rk_gmac_ops rk3399_ops = { + #define RK3568_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) + #define RK3568_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) + ++#define RK3568_PIPE_GRF_XPCS_CON0 0X0040 ++ ++#define RK3568_PIPE_GRF_XPCS_QGMII_MAC_SEL GRF_BIT(0) ++#define RK3568_PIPE_GRF_XPCS_SGMII_MAC_SEL GRF_BIT(1) ++#define RK3568_PIPE_GRF_XPCS_PHY_READY GRF_BIT(2) ++ ++static void rk3568_set_to_sgmii(struct rk_priv_data *bsp_priv) ++{ ++ struct device *dev = &bsp_priv->pdev->dev; ++ u32 con1; ++ ++ if (IS_ERR(bsp_priv->grf)) { ++ dev_err(dev, "Missing rockchip,grf property\n"); ++ return; ++ } ++ ++ con1 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON1 : ++ RK3568_GRF_GMAC0_CON1; ++ regmap_write(bsp_priv->grf, con1, RK3568_GMAC_GMII_MODE); ++ ++ xpcs_setup(bsp_priv, PHY_INTERFACE_MODE_SGMII); ++} ++ ++static void rk3568_set_to_qsgmii(struct rk_priv_data *bsp_priv) ++{ ++ struct device *dev = &bsp_priv->pdev->dev; ++ u32 con1; ++ ++ if (IS_ERR(bsp_priv->grf)) { ++ dev_err(dev, "Missing rockchip,grf property\n"); ++ return; ++ } ++ ++ con1 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON1 : ++ RK3568_GRF_GMAC0_CON1; ++ regmap_write(bsp_priv->grf, con1, RK3568_GMAC_GMII_MODE); ++ ++ xpcs_setup(bsp_priv, PHY_INTERFACE_MODE_QSGMII); ++} ++ + static void rk3568_set_to_rgmii(struct rk_priv_data *bsp_priv, + int tx_delay, int rx_delay) + { +@@ -1094,6 +1262,8 @@ static void rk3568_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed) + static const struct rk_gmac_ops rk3568_ops = { + .set_to_rgmii = rk3568_set_to_rgmii, + .set_to_rmii = rk3568_set_to_rmii, ++ .set_to_sgmii = rk3568_set_to_sgmii, ++ .set_to_qsgmii = rk3568_set_to_qsgmii, + .set_rgmii_speed = rk3568_set_gmac_speed, + .set_rmii_speed = rk3568_set_gmac_speed, + .regs_valid = true, +@@ -1517,6 +1687,12 @@ static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat) + dev_err(dev, "cannot get clock %s\n", + "clk_mac_refout"); + } ++ } else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_SGMII || ++ bsp_priv->phy_iface == PHY_INTERFACE_MODE_QSGMII) { ++ bsp_priv->pclk_xpcs = devm_clk_get(dev, "pclk_xpcs"); ++ if (IS_ERR(bsp_priv->pclk_xpcs)) ++ dev_err(dev, "cannot get clock %s\n", ++ "pclk_xpcs"); + } + + bsp_priv->clk_mac_speed = devm_clk_get(dev, "clk_mac_speed"); +@@ -1572,6 +1748,9 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable) + if (!IS_ERR(bsp_priv->pclk_mac)) + clk_prepare_enable(bsp_priv->pclk_mac); + ++ if (!IS_ERR(bsp_priv->pclk_xpcs)) ++ clk_prepare_enable(bsp_priv->pclk_xpcs); ++ + if (!IS_ERR(bsp_priv->mac_clk_tx)) + clk_prepare_enable(bsp_priv->mac_clk_tx); + +@@ -1605,6 +1784,8 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable) + + clk_disable_unprepare(bsp_priv->pclk_mac); + ++ clk_disable_unprepare(bsp_priv->pclk_xpcs); ++ + clk_disable_unprepare(bsp_priv->mac_clk_tx); + + clk_disable_unprepare(bsp_priv->clk_mac_speed); +@@ -1623,7 +1804,7 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable) + return 0; + } + +-static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable) ++static int rk_gmac_phy_power_on(struct rk_priv_data *bsp_priv, bool enable) + { + struct regulator *ldo = bsp_priv->regulator; + int ret; +@@ -1728,6 +1909,18 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev, + + bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node, + "rockchip,grf"); ++ bsp_priv->xpcs = syscon_regmap_lookup_by_phandle(dev->of_node, ++ "rockchip,xpcs"); ++ if (!IS_ERR(bsp_priv->xpcs)) { ++ struct phy *comphy; ++ ++ comphy = devm_of_phy_get(&pdev->dev, dev->of_node, NULL); ++ if (IS_ERR(comphy)) ++ dev_err(dev, "devm_of_phy_get error\n"); ++ ret = phy_init(comphy); ++ if (ret) ++ dev_err(dev, "phy_init error\n"); ++ } + + if (plat->phy_node) { + bsp_priv->integrated_phy = of_property_read_bool(plat->phy_node, +@@ -1805,11 +1998,19 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) + dev_info(dev, "init for RMII\n"); + bsp_priv->ops->set_to_rmii(bsp_priv); + break; ++ case PHY_INTERFACE_MODE_SGMII: ++ dev_info(dev, "init for SGMII\n"); ++ bsp_priv->ops->set_to_sgmii(bsp_priv); ++ break; ++ case PHY_INTERFACE_MODE_QSGMII: ++ dev_info(dev, "init for QSGMII\n"); ++ bsp_priv->ops->set_to_qsgmii(bsp_priv); ++ break; + default: + dev_err(dev, "NO interface defined!\n"); + } + +- ret = phy_power_on(bsp_priv, true); ++ ret = rk_gmac_phy_power_on(bsp_priv, true); + if (ret) { + gmac_clk_enable(bsp_priv, false); + return ret; +@@ -1830,7 +2031,7 @@ static void rk_gmac_powerdown(struct rk_priv_data *gmac) + + pm_runtime_put_sync(&gmac->pdev->dev); + +- phy_power_on(gmac, false); ++ rk_gmac_phy_power_on(gmac, false); + gmac_clk_enable(gmac, false); + } + +@@ -1851,6 +2052,9 @@ static void rk_fix_speed(void *priv, unsigned int speed) + if (bsp_priv->ops->set_rmii_speed) + bsp_priv->ops->set_rmii_speed(bsp_priv, speed); + break; ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_QSGMII: ++ break; + default: + dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface); + } diff --git a/target/linux/rockchip/patches-6.1/112-arm64-dts-rockchip-rk3568-Add-xpcs-support.patch b/target/linux/rockchip/patches-6.1/112-arm64-dts-rockchip-rk3568-Add-xpcs-support.patch new file mode 100644 index 000000000..54fd198fe --- /dev/null +++ b/target/linux/rockchip/patches-6.1/112-arm64-dts-rockchip-rk3568-Add-xpcs-support.patch @@ -0,0 +1,33 @@ +--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi +@@ -173,11 +173,13 @@ gmac0: ethernet@fe2a0000 { + clocks = <&cru SCLK_GMAC0>, <&cru SCLK_GMAC0_RX_TX>, + <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_MAC0_REFOUT>, + <&cru ACLK_GMAC0>, <&cru PCLK_GMAC0>, +- <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_GMAC0_PTP_REF>; ++ <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_GMAC0_PTP_REF>, ++ <&cru PCLK_XPCS>; + clock-names = "stmmaceth", "mac_clk_rx", + "mac_clk_tx", "clk_mac_refout", + "aclk_mac", "pclk_mac", +- "clk_mac_speed", "ptp_ref"; ++ "clk_mac_speed", "ptp_ref", ++ "pclk_xpcs"; + resets = <&cru SRST_A_GMAC0>; + reset-names = "stmmaceth"; + rockchip,grf = <&grf>; +--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +@@ -376,6 +376,12 @@ usb_host1_ohci: usb@fd8c0000 { + status = "disabled"; + }; + ++ xpcs: syscon@fda00000 { ++ compatible = "rockchip,rk3568-xpcs", "syscon"; ++ reg = <0x0 0xfda00000 0x0 0x200000>; ++ status = "disabled"; ++ }; ++ + pmugrf: syscon@fdc20000 { + compatible = "rockchip,rk3568-pmugrf", "syscon", "simple-mfd"; + reg = <0x0 0xfdc20000 0x0 0x10000>; diff --git a/target/linux/rockchip/patches-6.1/113-ethernet-stmicro-stmmac-Add-SGMII-QSGMII-support.patch b/target/linux/rockchip/patches-6.1/113-ethernet-stmicro-stmmac-Add-SGMII-QSGMII-support.patch new file mode 100644 index 000000000..4197edac8 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/113-ethernet-stmicro-stmmac-Add-SGMII-QSGMII-support.patch @@ -0,0 +1,343 @@ +From ca89ea7e0760c096c6fd807d321ecb8416f8cd9d Mon Sep 17 00:00:00 2001 +From: David Wu +Date: Thu, 31 Dec 2020 18:32:03 +0800 +Subject: [PATCH] ethernet: stmicro: stmmac: Add SGMII/QSGMII support for + RK3568 + +After the completion of Clause 37 auto-negotiation, xpcs automatically +switches to the negotiated speed for 10/100/1000M. + +Change-Id: Iab9dd6ee61a35bf89fd3a0721f5d398de501a7ec +Signed-off-by: David Wu +--- + .../net/ethernet/stmicro/stmmac/dwmac-rk.c | 228 +++++++++++++++++- + 1 file changed, 217 insertions(+), 11 deletions(-) + +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -30,6 +31,8 @@ struct rk_gmac_ops { + void (*set_to_rgmii)(struct rk_priv_data *bsp_priv, + int tx_delay, int rx_delay); + void (*set_to_rmii)(struct rk_priv_data *bsp_priv); ++ void (*set_to_sgmii)(struct rk_priv_data *bsp_priv); ++ void (*set_to_qsgmii)(struct rk_priv_data *bsp_priv); + void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed); + void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed); + void (*set_clock_selection)(struct rk_priv_data *bsp_priv, bool input, +@@ -60,6 +63,7 @@ struct rk_priv_data { + struct clk *clk_mac_speed; + struct clk *aclk_mac; + struct clk *pclk_mac; ++ struct clk *pclk_xpcs; + struct clk *clk_phy; + + struct reset_control *phy_reset; +@@ -69,6 +73,7 @@ struct rk_priv_data { + + struct regmap *grf; + struct regmap *php_grf; ++ struct regmap *xpcs; + }; + + #define HIWORD_UPDATE(val, mask, shift) \ +@@ -81,6 +86,128 @@ struct rk_priv_data { + (((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \ + ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE)) + ++/* XPCS */ ++#define XPCS_APB_INCREMENT (0x4) ++#define XPCS_APB_MASK GENMASK_ULL(20, 0) ++ ++#define SR_MII_BASE (0x1F0000) ++#define SR_MII1_BASE (0x1A0000) ++ ++#define VR_MII_DIG_CTRL1 (0x8000) ++#define VR_MII_AN_CTRL (0x8001) ++#define VR_MII_AN_INTR_STS (0x8002) ++#define VR_MII_LINK_TIMER_CTRL (0x800A) ++ ++#define SR_MII_CTRL_AN_ENABLE \ ++ (BMCR_ANENABLE | BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000) ++#define MII_MAC_AUTO_SW (0x0200) ++#define PCS_MODE_OFFSET (0x1) ++#define MII_AN_INTR_EN (0x1) ++#define PCS_SGMII_MODE (0x2 << PCS_MODE_OFFSET) ++#define PCS_QSGMII_MODE (0X3 << PCS_MODE_OFFSET) ++#define VR_MII_CTRL_SGMII_AN_EN (PCS_SGMII_MODE | MII_AN_INTR_EN) ++#define VR_MII_CTRL_QSGMII_AN_EN (PCS_QSGMII_MODE | MII_AN_INTR_EN) ++ ++#define SR_MII_OFFSET(_x) ({ \ ++ typeof(_x) (x) = (_x); \ ++ (((x) == 0) ? SR_MII_BASE : (SR_MII1_BASE + ((x) - 1) * 0x10000)); \ ++}) \ ++ ++static int xpcs_read(void *priv, int reg) ++{ ++ struct rk_priv_data *bsp_priv = (struct rk_priv_data *)priv; ++ int ret, val; ++ ++ ret = regmap_read(bsp_priv->xpcs, ++ (u32)(reg * XPCS_APB_INCREMENT) & XPCS_APB_MASK, ++ &val); ++ if (ret) ++ return ret; ++ ++ return val; ++} ++ ++static int xpcs_write(void *priv, int reg, u16 value) ++{ ++ struct rk_priv_data *bsp_priv = (struct rk_priv_data *)priv; ++ ++ return regmap_write(bsp_priv->xpcs, ++ (reg * XPCS_APB_INCREMENT) & XPCS_APB_MASK, value); ++} ++ ++static int xpcs_poll_reset(struct rk_priv_data *bsp_priv, int dev) ++{ ++ /* Poll until the reset bit clears (50ms per retry == 0.6 sec) */ ++ unsigned int retries = 12; ++ int ret; ++ ++ do { ++ msleep(50); ++ ret = xpcs_read(bsp_priv, SR_MII_OFFSET(dev) + MDIO_CTRL1); ++ if (ret < 0) ++ return ret; ++ } while (ret & MDIO_CTRL1_RESET && --retries); ++ ++ return (ret & MDIO_CTRL1_RESET) ? -ETIMEDOUT : 0; ++} ++ ++static int xpcs_soft_reset(struct rk_priv_data *bsp_priv, int dev) ++{ ++ int ret; ++ ++ ret = xpcs_write(bsp_priv, SR_MII_OFFSET(dev) + MDIO_CTRL1, ++ MDIO_CTRL1_RESET); ++ if (ret < 0) ++ return ret; ++ ++ return xpcs_poll_reset(bsp_priv, dev); ++} ++ ++static int xpcs_setup(struct rk_priv_data *bsp_priv, int mode) ++{ ++ int ret, i, idx = bsp_priv->id; ++ u32 val; ++ ++ if (mode == PHY_INTERFACE_MODE_QSGMII && idx > 0) ++ return 0; ++ ++ ret = xpcs_soft_reset(bsp_priv, idx); ++ if (ret) { ++ dev_err(&bsp_priv->pdev->dev, "xpcs_soft_reset fail %d\n", ret); ++ return ret; ++ } ++ ++ xpcs_write(bsp_priv, SR_MII_OFFSET(0) + VR_MII_AN_INTR_STS, 0x0); ++ xpcs_write(bsp_priv, SR_MII_OFFSET(0) + VR_MII_LINK_TIMER_CTRL, 0x1); ++ ++ if (mode == PHY_INTERFACE_MODE_SGMII) ++ xpcs_write(bsp_priv, SR_MII_OFFSET(0) + VR_MII_AN_CTRL, ++ VR_MII_CTRL_SGMII_AN_EN); ++ else ++ xpcs_write(bsp_priv, SR_MII_OFFSET(0) + VR_MII_AN_CTRL, ++ VR_MII_CTRL_QSGMII_AN_EN); ++ ++ if (mode == PHY_INTERFACE_MODE_QSGMII) { ++ for (i = 0; i < 4; i++) { ++ val = xpcs_read(bsp_priv, ++ SR_MII_OFFSET(i) + VR_MII_DIG_CTRL1); ++ xpcs_write(bsp_priv, ++ SR_MII_OFFSET(i) + VR_MII_DIG_CTRL1, ++ val | MII_MAC_AUTO_SW); ++ xpcs_write(bsp_priv, SR_MII_OFFSET(i) + MII_BMCR, ++ SR_MII_CTRL_AN_ENABLE); ++ } ++ } else { ++ val = xpcs_read(bsp_priv, SR_MII_OFFSET(idx) + VR_MII_DIG_CTRL1); ++ xpcs_write(bsp_priv, SR_MII_OFFSET(idx) + VR_MII_DIG_CTRL1, ++ val | MII_MAC_AUTO_SW); ++ xpcs_write(bsp_priv, SR_MII_OFFSET(idx) + MII_BMCR, ++ SR_MII_CTRL_AN_ENABLE); ++ } ++ ++ return ret; ++} ++ + #define PX30_GRF_GMAC_CON1 0x0904 + + /* PX30_GRF_GMAC_CON1 */ +@@ -1008,6 +1135,7 @@ static const struct rk_gmac_ops rk3399_ops = { + #define RK3568_GRF_GMAC1_CON1 0x038c + + /* RK3568_GRF_GMAC0_CON1 && RK3568_GRF_GMAC1_CON1 */ ++#define RK3568_GMAC_GMII_MODE GRF_BIT(7) + #define RK3568_GMAC_PHY_INTF_SEL_RGMII \ + (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) + #define RK3568_GMAC_PHY_INTF_SEL_RMII \ +@@ -1023,6 +1151,46 @@ static const struct rk_gmac_ops rk3399_ops = { + #define RK3568_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) + #define RK3568_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) + ++#define RK3568_PIPE_GRF_XPCS_CON0 0X0040 ++ ++#define RK3568_PIPE_GRF_XPCS_QGMII_MAC_SEL GRF_BIT(0) ++#define RK3568_PIPE_GRF_XPCS_SGMII_MAC_SEL GRF_BIT(1) ++#define RK3568_PIPE_GRF_XPCS_PHY_READY GRF_BIT(2) ++ ++static void rk3568_set_to_sgmii(struct rk_priv_data *bsp_priv) ++{ ++ struct device *dev = &bsp_priv->pdev->dev; ++ u32 con1; ++ ++ if (IS_ERR(bsp_priv->grf)) { ++ dev_err(dev, "Missing rockchip,grf property\n"); ++ return; ++ } ++ ++ con1 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON1 : ++ RK3568_GRF_GMAC0_CON1; ++ regmap_write(bsp_priv->grf, con1, RK3568_GMAC_GMII_MODE); ++ ++ xpcs_setup(bsp_priv, PHY_INTERFACE_MODE_SGMII); ++} ++ ++static void rk3568_set_to_qsgmii(struct rk_priv_data *bsp_priv) ++{ ++ struct device *dev = &bsp_priv->pdev->dev; ++ u32 con1; ++ ++ if (IS_ERR(bsp_priv->grf)) { ++ dev_err(dev, "Missing rockchip,grf property\n"); ++ return; ++ } ++ ++ con1 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON1 : ++ RK3568_GRF_GMAC0_CON1; ++ regmap_write(bsp_priv->grf, con1, RK3568_GMAC_GMII_MODE); ++ ++ xpcs_setup(bsp_priv, PHY_INTERFACE_MODE_QSGMII); ++} ++ + static void rk3568_set_to_rgmii(struct rk_priv_data *bsp_priv, + int tx_delay, int rx_delay) + { +@@ -1094,6 +1262,8 @@ static void rk3568_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed) + static const struct rk_gmac_ops rk3568_ops = { + .set_to_rgmii = rk3568_set_to_rgmii, + .set_to_rmii = rk3568_set_to_rmii, ++ .set_to_sgmii = rk3568_set_to_sgmii, ++ .set_to_qsgmii = rk3568_set_to_qsgmii, + .set_rgmii_speed = rk3568_set_gmac_speed, + .set_rmii_speed = rk3568_set_gmac_speed, + .regs_valid = true, +@@ -1517,6 +1687,12 @@ static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat) + dev_err(dev, "cannot get clock %s\n", + "clk_mac_refout"); + } ++ } else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_SGMII || ++ bsp_priv->phy_iface == PHY_INTERFACE_MODE_QSGMII) { ++ bsp_priv->pclk_xpcs = devm_clk_get(dev, "pclk_xpcs"); ++ if (IS_ERR(bsp_priv->pclk_xpcs)) ++ dev_err(dev, "cannot get clock %s\n", ++ "pclk_xpcs"); + } + + bsp_priv->clk_mac_speed = devm_clk_get(dev, "clk_mac_speed"); +@@ -1572,6 +1748,9 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable) + if (!IS_ERR(bsp_priv->pclk_mac)) + clk_prepare_enable(bsp_priv->pclk_mac); + ++ if (!IS_ERR(bsp_priv->pclk_xpcs)) ++ clk_prepare_enable(bsp_priv->pclk_xpcs); ++ + if (!IS_ERR(bsp_priv->mac_clk_tx)) + clk_prepare_enable(bsp_priv->mac_clk_tx); + +@@ -1605,6 +1784,8 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable) + + clk_disable_unprepare(bsp_priv->pclk_mac); + ++ clk_disable_unprepare(bsp_priv->pclk_xpcs); ++ + clk_disable_unprepare(bsp_priv->mac_clk_tx); + + clk_disable_unprepare(bsp_priv->clk_mac_speed); +@@ -1623,7 +1804,7 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable) + return 0; + } + +-static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable) ++static int rk_gmac_phy_power_on(struct rk_priv_data *bsp_priv, bool enable) + { + struct regulator *ldo = bsp_priv->regulator; + int ret; +@@ -1728,6 +1909,18 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev, + "rockchip,grf"); + bsp_priv->php_grf = syscon_regmap_lookup_by_phandle(dev->of_node, + "rockchip,php-grf"); ++ bsp_priv->xpcs = syscon_regmap_lookup_by_phandle(dev->of_node, ++ "rockchip,xpcs"); ++ if (!IS_ERR(bsp_priv->xpcs)) { ++ struct phy *comphy; ++ ++ comphy = devm_of_phy_get(&pdev->dev, dev->of_node, NULL); ++ if (IS_ERR(comphy)) ++ dev_err(dev, "devm_of_phy_get error\n"); ++ ret = phy_init(comphy); ++ if (ret) ++ dev_err(dev, "phy_init error\n"); ++ } + + if (plat->phy_node) { + bsp_priv->integrated_phy = of_property_read_bool(plat->phy_node, +@@ -1805,11 +1998,19 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) + dev_info(dev, "init for RMII\n"); + bsp_priv->ops->set_to_rmii(bsp_priv); + break; ++ case PHY_INTERFACE_MODE_SGMII: ++ dev_info(dev, "init for SGMII\n"); ++ bsp_priv->ops->set_to_sgmii(bsp_priv); ++ break; ++ case PHY_INTERFACE_MODE_QSGMII: ++ dev_info(dev, "init for QSGMII\n"); ++ bsp_priv->ops->set_to_qsgmii(bsp_priv); ++ break; + default: + dev_err(dev, "NO interface defined!\n"); + } + +- ret = phy_power_on(bsp_priv, true); ++ ret = rk_gmac_phy_power_on(bsp_priv, true); + if (ret) { + gmac_clk_enable(bsp_priv, false); + return ret; +@@ -1830,7 +2031,7 @@ static void rk_gmac_powerdown(struct rk_priv_data *gmac) + + pm_runtime_put_sync(&gmac->pdev->dev); + +- phy_power_on(gmac, false); ++ rk_gmac_phy_power_on(gmac, false); + gmac_clk_enable(gmac, false); + } + +@@ -1851,6 +2052,9 @@ static void rk_fix_speed(void *priv, unsigned int speed) + if (bsp_priv->ops->set_rmii_speed) + bsp_priv->ops->set_rmii_speed(bsp_priv, speed); + break; ++ case PHY_INTERFACE_MODE_SGMII: ++ case PHY_INTERFACE_MODE_QSGMII: ++ break; + default: + dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface); + }