From 01042589afb7c917cab8e568e98727801dfd47ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=A8=E5=9B=9B=E6=B0=B4?= <78152109+ZMuSiShui@users.noreply.github.com> Date: Wed, 22 Dec 2021 23:29:37 +0800 Subject: [PATCH] Add Support For OrangePi R1 Plus LTS (#8498) --- package/boot/uboot-rockchip/Makefile | 15 +- ...Add-support-for-Orangepi-R1-Plus-LTS.patch | 144 ++ .../orangepi-r1-plus-lts-rk3328/dt-decl.h | 23 + .../orangepi-r1-plus-lts-rk3328/dt-plat.c | 154 ++ .../dt-structs-gen.h | 51 + .../armv8/base-files/etc/board.d/01_leds | 3 +- .../armv8/base-files/etc/board.d/02_network | 6 +- .../etc/hotplug.d/net/40-net-smp-affinity | 3 +- target/linux/rockchip/image/armv8.mk | 10 + ...Add-support-for-OrangePi-R1-Plus-LTS.patch | 101 + ...Add-support-for-OrangePi-R1-Plus-LTS.patch | 101 + ...Add-driver-for-Motorcomm-YT85xx-PHYs.patch | 1981 ++++++++++++++++- 12 files changed, 2522 insertions(+), 70 deletions(-) create mode 100644 package/boot/uboot-rockchip/patches/202-rockchip-rk3328-Add-support-for-Orangepi-R1-Plus-LTS.patch create mode 100644 package/boot/uboot-rockchip/src/of-platdata/orangepi-r1-plus-lts-rk3328/dt-decl.h create mode 100644 package/boot/uboot-rockchip/src/of-platdata/orangepi-r1-plus-lts-rk3328/dt-plat.c create mode 100644 package/boot/uboot-rockchip/src/of-platdata/orangepi-r1-plus-lts-rk3328/dt-structs-gen.h create mode 100644 target/linux/rockchip/patches-5.10/206-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus-LTS.patch create mode 100644 target/linux/rockchip/patches-5.4/206-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus-LTS.patch diff --git a/package/boot/uboot-rockchip/Makefile b/package/boot/uboot-rockchip/Makefile index d7cd4a009..9bdb9a58d 100644 --- a/package/boot/uboot-rockchip/Makefile +++ b/package/boot/uboot-rockchip/Makefile @@ -60,6 +60,18 @@ define U-Boot/orangepi-r1-plus-rk3328 USE_RKBIN:=1 endef +define U-Boot/orangepi-r1-plus-lts-rk3328 + BUILD_SUBTARGET:=armv8 + NAME:=Orange Pi R1 Plus LTS + BUILD_DEVICES:= \ + xunlong_orangepi-r1-plus-lts + DEPENDS:=+PACKAGE_u-boot-orangepi-r1-plus-lts-rk3328:arm-trusted-firmware-rk3328 + PKG_BUILD_DEPENDS:=arm-trusted-firmware-rockchip-vendor + ATF:=rk322xh_bl31_v1.46.elf + OF_PLATDATA:=$(1) + USE_RKBIN:=1 +endef + define U-Boot/doornet1-rk3328 BUILD_SUBTARGET:=armv8 NAME:=DoorNet1 @@ -135,7 +147,8 @@ UBOOT_TARGETS := \ doornet1-rk3328 \ nanopi-r2c-rk3328 \ nanopi-r2s-rk3328 \ - orangepi-r1-plus-rk3328 + orangepi-r1-plus-rk3328 \ + orangepi-r1-plus-lts-rk3328 UBOOT_CONFIGURE_VARS += USE_PRIVATE_LIBGCC=yes diff --git a/package/boot/uboot-rockchip/patches/202-rockchip-rk3328-Add-support-for-Orangepi-R1-Plus-LTS.patch b/package/boot/uboot-rockchip/patches/202-rockchip-rk3328-Add-support-for-Orangepi-R1-Plus-LTS.patch new file mode 100644 index 000000000..f897446f8 --- /dev/null +++ b/package/boot/uboot-rockchip/patches/202-rockchip-rk3328-Add-support-for-Orangepi-R1-Plus-LTS.patch @@ -0,0 +1,144 @@ +From 68836b81f7d6328a1a5a6cce5a00bf4010f742e5 Mon Sep 17 00:00:00 2001 +From: baiywt +Date: Wed, 24 Nov 2021 19:59:38 +0800 +Subject: [PATCH] Add support for Orangepi R1 Plus LTS + +--- + arch/arm/dts/Makefile | 1 + + arch/arm/dts/rk3328-orangepi-r1-plus-lts.dts | 7 ++ + configs/orangepi-r1-plus-lts-rk3328_defconfig | 98 +++++++++++++++++++ + 3 files changed, 106 insertions(+) + create mode 100644 arch/arm/dts/rk3328-orangepi-r1-plus-lts.dts + create mode 100644 configs/orangepi-r1-plus-lts-rk3328_defconfig + +diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile +index adfe6c3f..3d4e0f59 100644 +--- a/arch/arm/dts/Makefile ++++ b/arch/arm/dts/Makefile +@@ -110,6 +110,7 @@ dtb-$(CONFIG_ROCKCHIP_RK3328) += \ + rk3328-evb.dtb \ + rk3328-nanopi-r2s.dtb \ + rk3328-orangepi-r1-plus.dtb \ ++ rk3328-orangepi-r1-plus-lts.dtb \ + rk3328-roc-cc.dtb \ + rk3328-rock64.dtb \ + rk3328-rock-pi-e.dtb +diff --git a/arch/arm/dts/rk3328-orangepi-r1-plus-lts.dts b/arch/arm/dts/rk3328-orangepi-r1-plus-lts.dts +new file mode 100644 +index 00000000..e6225b0c +--- /dev/null ++++ b/arch/arm/dts/rk3328-orangepi-r1-plus-lts.dts +@@ -0,0 +1,7 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++#include "rk3328-orangepi-r1-plus.dts" ++ ++/ { ++ model = "Xunlong Orange Pi R1 Plus LTS"; ++ compatible = "xunlong,orangepi-r1-plus-lts", "rockchip,rk3328"; ++}; +diff --git a/configs/orangepi-r1-plus-lts-rk3328_defconfig b/configs/orangepi-r1-plus-lts-rk3328_defconfig +new file mode 100644 +index 00000000..3cb3b5c3 +--- /dev/null ++++ b/configs/orangepi-r1-plus-lts-rk3328_defconfig +@@ -0,0 +1,98 @@ ++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=0x600000 ++CONFIG_NR_DRAM_BANKS=1 ++CONFIG_DEBUG_UART_BASE=0xFF130000 ++CONFIG_DEBUG_UART_CLOCK=24000000 ++CONFIG_SYSINFO=y ++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-orangepi-r1-plus-lts.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-orangepi-r1-plus-lts" ++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_PINCTRL=y ++CONFIG_SPL_PINCTRL=y ++CONFIG_DM_PMIC=y ++CONFIG_PMIC_RK8XX=y ++CONFIG_SPL_DM_REGULATOR=y ++CONFIG_REGULATOR_PWM=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_SPL_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 +-- +2.25.1 diff --git a/package/boot/uboot-rockchip/src/of-platdata/orangepi-r1-plus-lts-rk3328/dt-decl.h b/package/boot/uboot-rockchip/src/of-platdata/orangepi-r1-plus-lts-rk3328/dt-decl.h new file mode 100644 index 000000000..06889b0b4 --- /dev/null +++ b/package/boot/uboot-rockchip/src/of-platdata/orangepi-r1-plus-lts-rk3328/dt-decl.h @@ -0,0 +1,23 @@ +/* + * DO NOT MODIFY + * + * Declares externs for all device/uclass instances. + * This was generated by dtoc from a .dtb (device tree binary) file. + */ + +#include +#include + +/* driver declarations - these allow DM_DRIVER_GET() to be used */ +extern U_BOOT_DRIVER(rockchip_rk3328_cru); +extern U_BOOT_DRIVER(rockchip_rk3328_dmc); +extern U_BOOT_DRIVER(rockchip_rk3288_dw_mshc); +extern U_BOOT_DRIVER(ns16550_serial); +extern U_BOOT_DRIVER(rockchip_rk3328_grf); + +/* uclass driver declarations - needed for DM_UCLASS_DRIVER_REF() */ +extern UCLASS_DRIVER(clk); +extern UCLASS_DRIVER(mmc); +extern UCLASS_DRIVER(ram); +extern UCLASS_DRIVER(serial); +extern UCLASS_DRIVER(syscon); \ No newline at end of file diff --git a/package/boot/uboot-rockchip/src/of-platdata/orangepi-r1-plus-lts-rk3328/dt-plat.c b/package/boot/uboot-rockchip/src/of-platdata/orangepi-r1-plus-lts-rk3328/dt-plat.c new file mode 100644 index 000000000..42468f38a --- /dev/null +++ b/package/boot/uboot-rockchip/src/of-platdata/orangepi-r1-plus-lts-rk3328/dt-plat.c @@ -0,0 +1,154 @@ +/* + * DO NOT MODIFY + * + * Declares the U_BOOT_DRIVER() records and platform data. + * This was generated by dtoc from a .dtb (device tree binary) file. + */ + +/* Allow use of U_BOOT_DRVINFO() in this file */ +#define DT_PLAT_C + +#include +#include +#include + +/* + * driver_info declarations, ordered by 'struct driver_info' linker_list idx: + * + * idx driver_info driver + * --- -------------------- -------------------- + * 0: clock_controller_at_ff440000 rockchip_rk3328_cru + * 1: dmc rockchip_rk3328_dmc + * 2: mmc_at_ff500000 rockchip_rk3288_dw_mshc + * 3: serial_at_ff130000 ns16550_serial + * 4: syscon_at_ff100000 rockchip_rk3328_grf + * --- -------------------- -------------------- + */ + +/* + * Node /clock-controller@ff440000 index 0 + * driver rockchip_rk3328_cru parent None + */ +static struct dtd_rockchip_rk3328_cru dtv_clock_controller_at_ff440000 = { + .reg = {0xff440000, 0x1000}, + .rockchip_grf = 0x3a, +}; +U_BOOT_DRVINFO(clock_controller_at_ff440000) = { + .name = "rockchip_rk3328_cru", + .plat = &dtv_clock_controller_at_ff440000, + .plat_size = sizeof(dtv_clock_controller_at_ff440000), + .parent_idx = -1, +}; + +/* + * Node /dmc index 1 + * driver rockchip_rk3328_dmc parent None + */ +static struct dtd_rockchip_rk3328_dmc dtv_dmc = { + .reg = {0xff400000, 0x1000, 0xff780000, 0x3000, 0xff100000, 0x1000, 0xff440000, 0x1000, + 0xff720000, 0x1000, 0xff798000, 0x1000}, + .rockchip_sdram_params = {0x1, 0xa, 0x2, 0x1, 0x0, 0x0, 0x11, 0x0, + 0x11, 0x0, 0x0, 0x94291288, 0x0, 0x27, 0x462, 0x15, + 0x242, 0xff, 0x14d, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x43049010, 0x64, 0x28003b, 0xd0, 0x20053, 0xd4, 0x220000, 0xd8, + 0x100, 0xdc, 0x40000, 0xe0, 0x0, 0xe4, 0x110000, 0xe8, + 0x420, 0xec, 0x400, 0xf4, 0xf011f, 0x100, 0x9060b06, 0x104, + 0x20209, 0x108, 0x505040a, 0x10c, 0x40400c, 0x110, 0x5030206, 0x114, + 0x3030202, 0x120, 0x3030b03, 0x124, 0x20208, 0x180, 0x1000040, 0x184, + 0x0, 0x190, 0x7030003, 0x198, 0x5001100, 0x1a0, 0xc0400003, 0x240, + 0x6000604, 0x244, 0x201, 0x250, 0xf00, 0x490, 0x1, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0x4, 0xc, 0x28, 0xa, 0x2c, + 0x0, 0x30, 0x9, 0xffffffff, 0xffffffff, 0x77, 0x88, 0x79, + 0x79, 0x87, 0x97, 0x87, 0x78, 0x77, 0x78, 0x87, + 0x88, 0x87, 0x87, 0x77, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x69, 0x9, 0x77, + 0x78, 0x77, 0x78, 0x77, 0x78, 0x77, 0x78, 0x77, + 0x79, 0x9, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x69, 0x9, 0x77, 0x78, 0x77, + 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x79, 0x9, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0x78, 0x69, 0x9, 0x77, 0x78, 0x77, 0x78, 0x77, + 0x78, 0x77, 0x78, 0x77, 0x79, 0x9, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x69, + 0x9, 0x77, 0x78, 0x77, 0x77, 0x77, 0x77, 0x77, + 0x77, 0x77, 0x79, 0x9}, +}; +U_BOOT_DRVINFO(dmc) = { + .name = "rockchip_rk3328_dmc", + .plat = &dtv_dmc, + .plat_size = sizeof(dtv_dmc), + .parent_idx = -1, +}; + +/* + * Node /mmc@ff500000 index 2 + * driver rockchip_rk3288_dw_mshc parent None + */ +static struct dtd_rockchip_rk3288_dw_mshc dtv_mmc_at_ff500000 = { + .bus_width = 0x4, + .cap_sd_highspeed = true, + .clocks = { + {0, {317}}, + {0, {33}}, + {0, {74}}, + {0, {78}},}, + .disable_wp = true, + .fifo_depth = 0x100, + .interrupts = {0x0, 0xc, 0x4}, + .max_frequency = 0x8f0d180, + .pinctrl_0 = {0x47, 0x48, 0x49, 0x4a}, + .pinctrl_names = "default", + .reg = {0xff500000, 0x4000}, + .sd_uhs_sdr104 = true, + .sd_uhs_sdr12 = true, + .sd_uhs_sdr25 = true, + .sd_uhs_sdr50 = true, + .u_boot_spl_fifo_mode = true, + .vmmc_supply = 0x4b, + .vqmmc_supply = 0x1e, +}; +U_BOOT_DRVINFO(mmc_at_ff500000) = { + .name = "rockchip_rk3288_dw_mshc", + .plat = &dtv_mmc_at_ff500000, + .plat_size = sizeof(dtv_mmc_at_ff500000), + .parent_idx = -1, +}; + +/* + * Node /serial@ff130000 index 3 + * driver ns16550_serial parent None + */ +static struct dtd_ns16550_serial dtv_serial_at_ff130000 = { + .clock_frequency = 0x16e3600, + .clocks = { + {0, {40}}, + {0, {212}},}, + .dma_names = {"tx", "rx"}, + .dmas = {0x10, 0x6, 0x10, 0x7}, + .interrupts = {0x0, 0x39, 0x4}, + .pinctrl_0 = 0x26, + .pinctrl_names = "default", + .reg = {0xff130000, 0x100}, + .reg_io_width = 0x4, + .reg_shift = 0x2, +}; +U_BOOT_DRVINFO(serial_at_ff130000) = { + .name = "ns16550_serial", + .plat = &dtv_serial_at_ff130000, + .plat_size = sizeof(dtv_serial_at_ff130000), + .parent_idx = -1, +}; + +/* + * Node /syscon@ff100000 index 4 + * driver rockchip_rk3328_grf parent None + */ +static struct dtd_rockchip_rk3328_grf dtv_syscon_at_ff100000 = { + .reg = {0xff100000, 0x1000}, +}; +U_BOOT_DRVINFO(syscon_at_ff100000) = { + .name = "rockchip_rk3328_grf", + .plat = &dtv_syscon_at_ff100000, + .plat_size = sizeof(dtv_syscon_at_ff100000), + .parent_idx = -1, +}; diff --git a/package/boot/uboot-rockchip/src/of-platdata/orangepi-r1-plus-lts-rk3328/dt-structs-gen.h b/package/boot/uboot-rockchip/src/of-platdata/orangepi-r1-plus-lts-rk3328/dt-structs-gen.h new file mode 100644 index 000000000..364d416f7 --- /dev/null +++ b/package/boot/uboot-rockchip/src/of-platdata/orangepi-r1-plus-lts-rk3328/dt-structs-gen.h @@ -0,0 +1,51 @@ +/* + * DO NOT MODIFY + * + * Defines the structs used to hold devicetree data. + * This was generated by dtoc from a .dtb (device tree binary) file. + */ + +#include +#include +struct dtd_ns16550_serial { + fdt32_t clock_frequency; + struct phandle_1_arg clocks[2]; + const char * dma_names[2]; + fdt32_t dmas[4]; + fdt32_t interrupts[3]; + fdt32_t pinctrl_0; + const char * pinctrl_names; + fdt64_t reg[2]; + fdt32_t reg_io_width; + fdt32_t reg_shift; +}; +struct dtd_rockchip_rk3288_dw_mshc { + fdt32_t bus_width; + bool cap_sd_highspeed; + struct phandle_1_arg clocks[4]; + bool disable_wp; + fdt32_t fifo_depth; + fdt32_t interrupts[3]; + fdt32_t max_frequency; + fdt32_t pinctrl_0[4]; + const char * pinctrl_names; + fdt64_t reg[2]; + bool sd_uhs_sdr104; + bool sd_uhs_sdr12; + bool sd_uhs_sdr25; + bool sd_uhs_sdr50; + bool u_boot_spl_fifo_mode; + fdt32_t vmmc_supply; + fdt32_t vqmmc_supply; +}; +struct dtd_rockchip_rk3328_cru { + fdt64_t reg[2]; + fdt32_t rockchip_grf; +}; +struct dtd_rockchip_rk3328_dmc { + fdt64_t reg[12]; + fdt32_t rockchip_sdram_params[196]; +}; +struct dtd_rockchip_rk3328_grf { + fdt64_t reg[2]; +}; \ No newline at end of file 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 index 30c8d81cf..ee9f1fd18 100755 --- a/target/linux/rockchip/armv8/base-files/etc/board.d/01_leds +++ b/target/linux/rockchip/armv8/base-files/etc/board.d/01_leds @@ -12,7 +12,8 @@ case $board in embedfire,doornet1|\ friendlyarm,nanopi-r2c|\ friendlyarm,nanopi-r2s|\ -xunlong,orangepi-r1-plus) +xunlong,orangepi-r1-plus|\ +xunlong,orangepi-r1-plus-lts) ucidef_set_led_netdev "wan" "WAN" "$boardname:green:wan" "eth0" ucidef_set_led_netdev "lan" "LAN" "$boardname:green:lan" "eth1" ;; 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 abb0e6c55..44eb3b4f1 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 @@ -14,7 +14,8 @@ rockchip_setup_interfaces() friendlyarm,nanopi-r2s|\ friendlyarm,nanopi-r4s|\ sharevdi,guangmiao-g4c|\ - xunlong,orangepi-r1-plus) + xunlong,orangepi-r1-plus|\ + xunlong,orangepi-r1-plus-lts) ucidef_set_interfaces_lan_wan 'eth1' 'eth0' ;; *) @@ -50,7 +51,8 @@ rockchip_setup_macs() wan_mac=$(get_mac_binary "/sys/bus/i2c/devices/2-0051/eeprom" 0xfa) lan_mac=$(macaddr_setbit_la "$wan_mac") ;; - xunlong,orangepi-r1-plus) + xunlong,orangepi-r1-plus|\ + xunlong,orangepi-r1-plus-lts) lan_mac=$(cat /sys/class/net/eth1/address) wan_mac=$(macaddr_add "$lan_mac" -1) ;; diff --git a/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity b/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity index ccb146931..2822e4890 100644 --- a/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity +++ b/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity @@ -31,7 +31,8 @@ case "$(board_name)" in embedfire,doornet1|\ friendlyarm,nanopi-r2c|\ friendlyarm,nanopi-r2s|\ -xunlong,orangepi-r1-plus) +xunlong,orangepi-r1-plus|\ +xunlong,orangepi-r1-plus-lts) set_interface_core 2 "eth0" set_interface_core 4 "eth1" "xhci-hcd:usb3" ;; diff --git a/target/linux/rockchip/image/armv8.mk b/target/linux/rockchip/image/armv8.mk index f3c24b203..30d186fa9 100644 --- a/target/linux/rockchip/image/armv8.mk +++ b/target/linux/rockchip/image/armv8.mk @@ -92,3 +92,13 @@ define Device/xunlong_orangepi-r1-plus DEVICE_PACKAGES := kmod-usb-net-rtl8152 endef TARGET_DEVICES += xunlong_orangepi-r1-plus + +define Device/xunlong_orangepi-r1-plus-lts + DEVICE_VENDOR := Xunlong + DEVICE_MODEL := Orange Pi R1 Plus LTS + SOC := rk3328 + UBOOT_DEVICE_NAME := orangepi-r1-plus-lts-rk3328 + IMAGE/sysupgrade.img.gz := boot-common | boot-script nanopi-r2s | pine64-bin | gzip | append-metadata + DEVICE_PACKAGES := kmod-usb-net-rtl8152 +endef +TARGET_DEVICES += xunlong_orangepi-r1-plus-lts diff --git a/target/linux/rockchip/patches-5.10/206-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus-LTS.patch b/target/linux/rockchip/patches-5.10/206-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus-LTS.patch new file mode 100644 index 000000000..eabd5bb3b --- /dev/null +++ b/target/linux/rockchip/patches-5.10/206-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus-LTS.patch @@ -0,0 +1,101 @@ +From 9f0bfe430a5a67b34bc2274a898b4375a321810b Mon Sep 17 00:00:00 2001 +From: baiywt +Date: Mon, 15 Nov 2021 16:51:43 +0800 +Subject: [PATCH] Add support for OrangePi R1 Plus LTS + +--- + arch/arm64/boot/dts/rockchip/Makefile | 1 + + .../rockchip/rk3328-orangepi-r1-plus-lts.dts | 44 +++++++++++++++++++ + 2 files changed, 45 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts + +diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile +index 23373c752..552d97555 100644 +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -5,6 +5,7 @@ + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2c.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2s.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus-lts.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-orangepi-r1-plus-lts.dts b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts +new file mode 100644 +index 000000000..c65f7c417 +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts +@@ -0,0 +1,70 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++#include "rk3328-orangepi-r1-plus.dts" ++ ++/ { ++ model = "Xunlong Orange Pi R1 Plus LTS"; ++ compatible = "xunlong,orangepi-r1-plus-lts", "rockchip,rk3328"; ++}; ++ ++/delete-node/ &rtl8211e; ++&gmac2io { ++ phy-handle = <ðphy3>; ++ snps,reset-delays-us = <0 15000 50000>; ++ tx_delay = <0x19>; ++ rx_delay = <0x05>; ++ status = "okay"; ++ ++ mdio { ++ compatible = "snps,dwmac-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ethphy3: ethernet-phy@0 { ++ reg = <0x0>; ++ keep-clkout-on; ++ reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ disable-wp; ++ pinctrl-0 = <&sdmmc0_clk>, <&sdmmc0_cmd>, <&sdmmc0_dectn>, <&sdmmc0_bus4>; ++ pinctrl-names = "default"; ++ sd-uhs-sdr12; ++ sd-uhs-sdr25; ++ sd-uhs-sdr50; ++ sd-uhs-sdr104; ++ vmmc-supply = <&vcc_sd>; ++ vqmmc-supply = <&vcc_io_sdio>; ++ status = "okay"; ++}; ++ ++&dmc_opp_table { ++ opp-1056000000 { ++ status = "disabled"; ++ }; ++ opp-924000000 { ++ status = "disabled"; ++ }; ++ opp-840000000 { ++ status = "disabled"; ++ }; ++ opp-798000000 { ++ status = "disabled"; ++ }; ++}; ++ ++&sys_led { ++ label = "orangepi-r1-plus-lts:red:sys"; ++}; ++ ++&wan_led { ++ label = "orangepi-r1-plus-lts:green:wan"; ++}; ++ ++&lan_led { ++ label = "orangepi-r1-plus-lts:green:lan"; ++}; +-- +2.25.1 diff --git a/target/linux/rockchip/patches-5.4/206-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus-LTS.patch b/target/linux/rockchip/patches-5.4/206-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus-LTS.patch new file mode 100644 index 000000000..eabd5bb3b --- /dev/null +++ b/target/linux/rockchip/patches-5.4/206-rockchip-rk3328-Add-support-for-OrangePi-R1-Plus-LTS.patch @@ -0,0 +1,101 @@ +From 9f0bfe430a5a67b34bc2274a898b4375a321810b Mon Sep 17 00:00:00 2001 +From: baiywt +Date: Mon, 15 Nov 2021 16:51:43 +0800 +Subject: [PATCH] Add support for OrangePi R1 Plus LTS + +--- + arch/arm64/boot/dts/rockchip/Makefile | 1 + + .../rockchip/rk3328-orangepi-r1-plus-lts.dts | 44 +++++++++++++++++++ + 2 files changed, 45 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts + +diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile +index 23373c752..552d97555 100644 +--- a/arch/arm64/boot/dts/rockchip/Makefile ++++ b/arch/arm64/boot/dts/rockchip/Makefile +@@ -5,6 +5,7 @@ + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2c.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2s.dtb + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus.dtb ++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus-lts.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-orangepi-r1-plus-lts.dts b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts +new file mode 100644 +index 000000000..c65f7c417 +--- /dev/null ++++ b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts +@@ -0,0 +1,70 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++#include "rk3328-orangepi-r1-plus.dts" ++ ++/ { ++ model = "Xunlong Orange Pi R1 Plus LTS"; ++ compatible = "xunlong,orangepi-r1-plus-lts", "rockchip,rk3328"; ++}; ++ ++/delete-node/ &rtl8211e; ++&gmac2io { ++ phy-handle = <ðphy3>; ++ snps,reset-delays-us = <0 15000 50000>; ++ tx_delay = <0x19>; ++ rx_delay = <0x05>; ++ status = "okay"; ++ ++ mdio { ++ compatible = "snps,dwmac-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ethphy3: ethernet-phy@0 { ++ reg = <0x0>; ++ keep-clkout-on; ++ reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ disable-wp; ++ pinctrl-0 = <&sdmmc0_clk>, <&sdmmc0_cmd>, <&sdmmc0_dectn>, <&sdmmc0_bus4>; ++ pinctrl-names = "default"; ++ sd-uhs-sdr12; ++ sd-uhs-sdr25; ++ sd-uhs-sdr50; ++ sd-uhs-sdr104; ++ vmmc-supply = <&vcc_sd>; ++ vqmmc-supply = <&vcc_io_sdio>; ++ status = "okay"; ++}; ++ ++&dmc_opp_table { ++ opp-1056000000 { ++ status = "disabled"; ++ }; ++ opp-924000000 { ++ status = "disabled"; ++ }; ++ opp-840000000 { ++ status = "disabled"; ++ }; ++ opp-798000000 { ++ status = "disabled"; ++ }; ++}; ++ ++&sys_led { ++ label = "orangepi-r1-plus-lts:red:sys"; ++}; ++ ++&wan_led { ++ label = "orangepi-r1-plus-lts:green:wan"; ++}; ++ ++&lan_led { ++ label = "orangepi-r1-plus-lts:green:lan"; ++}; +-- +2.25.1 diff --git a/target/linux/rockchip/patches-5.4/600-net-phy-Add-driver-for-Motorcomm-YT85xx-PHYs.patch b/target/linux/rockchip/patches-5.4/600-net-phy-Add-driver-for-Motorcomm-YT85xx-PHYs.patch index 2271308b1..c47dcf309 100644 --- a/target/linux/rockchip/patches-5.4/600-net-phy-Add-driver-for-Motorcomm-YT85xx-PHYs.patch +++ b/target/linux/rockchip/patches-5.4/600-net-phy-Add-driver-for-Motorcomm-YT85xx-PHYs.patch @@ -1,18 +1,121 @@ -From 5d6862cc5eac1679d7a4ef388f7c9bbc70e76770 Mon Sep 17 00:00:00 2001 -From: hmz007 -Date: Mon, 5 Jul 2021 17:03:00 +0800 -Subject: [PATCH] net: phy: Add driver for Motorcomm YT85xx PHYs +From acf039521685d9a1d272e8e577c1328c6a5bcca8 Mon Sep 17 00:00:00 2001 +From: baiywt +Date: Thu, 11 Nov 2021 19:53:31 +0800 +Subject: [PATCH 3/3] Add yt8531c support -Signed-off-by: hmz007 --- - drivers/net/phy/Kconfig | 5 + - drivers/net/phy/Makefile | 1 + - drivers/net/phy/motorcomm.c | 346 ++++++++++++++++++++++++++++++++++ - include/linux/motorcomm_phy.h | 68 +++++++ - 4 files changed, 420 insertions(+) + .../net/ethernet/stmicro/stmmac/stmmac_main.c | 77 + + drivers/net/phy/Kconfig | 5 + + drivers/net/phy/Makefile | 1 + + drivers/net/phy/motorcomm.c | 1514 +++++++++++++++++ + drivers/net/phy/phy_device.c | 15 + + drivers/net/phy/yt8614-phy.h | 491 ++++++ + include/linux/motorcomm_phy.h | 119 ++ + 7 files changed, 2222 insertions(+) create mode 100644 drivers/net/phy/motorcomm.c + create mode 100644 drivers/net/phy/yt8614-phy.h create mode 100644 include/linux/motorcomm_phy.h +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -112,6 +112,10 @@ + + #define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x)) + ++#define RTL_8211E_PHY_ID 0x001cc915 ++#define RTL_8211F_PHY_ID 0x001cc916 ++#define RTL_YT8531_PHY_ID 0x4f51e91b ++ + /** + * stmmac_verify_args - verify the driver parameters. + * Description: it checks the driver parameters and set a default in case of +@@ -4431,6 +4435,68 @@ + return 0; + } + ++static int phy_rtl8211e_led_fixup(struct phy_device *phydev) ++{ ++ //int val; ++ ++ printk("%s in\n", __func__); ++ ++ /*switch to extension page44*/ ++ phy_write(phydev, 31, 0x07); ++ phy_write(phydev, 30, 0x2c); ++ ++ /*set led1(yellow) act ++ val = phy_read(phydev, 26); ++ val &= (~(1<<4));// bit4=0 ++ val |= (1<<5);// bit5=1 ++ val &= (~(1<<6));// bit6=0*/ ++ phy_write(phydev, 26, 0x20); ++ ++ /*set led0(green) link ++ val = phy_read(phydev, 28); ++ val |= (7<<0);// bit0,1,2=1 ++ val &= (~(7<<4));// bit4,5,6=0 ++ val &= (~(7<<8));// bit8,9,10=0*/ ++ phy_write(phydev, 28, 0x07); ++ ++ /*switch back to page0*/ ++ phy_write(phydev,31,0x00); ++ ++ return 0; ++} ++ ++static int phy_rtl8211f_led_fixup(struct phy_device *phydev) ++{ ++ printk("%s in\n", __func__); ++ ++ /*switch to extension page44*/ ++ phy_write(phydev, 31, 0xd04); ++ ++ /*set led1(yellow) act */ ++ /*set led2(green) link*/ ++ phy_write(phydev, 16, 0xae00); ++ ++ /*switch back to page0*/ ++ phy_write(phydev,31,0x00); ++ ++ return 0; ++} ++ ++static int phy_yt8531_led_fixup(struct phy_device *phydev) ++{ ++ printk("%s in\n", __func__); ++ phy_write(phydev, 0x1e, 0xa00d); ++ phy_write(phydev, 0x1f, 0x670); ++ ++ phy_write(phydev, 0x1e, 0xa00e); ++ phy_write(phydev, 0x1f, 0x2070); ++ ++ phy_write(phydev, 0x1e, 0xa00f); ++ phy_write(phydev, 0x1f, 0x7e); ++ ++ return 0; ++} ++ + /** + * stmmac_dvr_probe + * @device: device pointer +@@ -4656,6 +4722,17 @@ + goto error_phy_setup; + } + ++ ret = phy_register_fixup_for_uid(RTL_8211E_PHY_ID, 0xffffffff, phy_rtl8211e_led_fixup); ++ if (ret) ++ pr_warn("Cannot register PHY board fixup.\n"); ++ ret = phy_register_fixup_for_uid(RTL_8211F_PHY_ID, 0xffffffff, phy_rtl8211f_led_fixup); ++ if (ret) ++ pr_warn("Cannot register PHY board fixup.\n"); ++ ret = phy_register_fixup_for_uid(RTL_YT8531_PHY_ID, 0xffffffff, phy_yt8531_led_fixup); ++ if (ret) ++ pr_warn("Cannot register PHY board fixup.\n"); ++ ++ + ret = register_netdev(ndev); + if (ret) { + dev_err(priv->device, "%s: ERROR %i registering the device\n", --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -519,6 +519,11 @@ config MICROSEMI_PHY @@ -39,7 +142,7 @@ Signed-off-by: hmz007 obj-$(CONFIG_QSEMI_PHY) += qsemi.o --- /dev/null +++ b/drivers/net/phy/motorcomm.c -@@ -0,0 +1,345 @@ +@@ -0,0 +1,1514 @@ +/* + * drivers/net/phy/motorcomm.c + * @@ -67,6 +170,79 @@ Signed-off-by: hmz007 +#include +#include +#include ++#include ++#ifndef LINUX_VERSION_CODE ++#include ++#else ++#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) ++#endif ++/*for wol, 20210604*/ ++#include ++ ++#include "yt8614-phy.h" ++ ++/**** configuration section begin ***********/ ++ ++/* if system depends on ethernet packet to restore from sleep, please define this macro to 1 ++ * otherwise, define it to 0. ++ */ ++#define SYS_WAKEUP_BASED_ON_ETH_PKT 1 ++ ++/* to enable system WOL of phy, please define this macro to 1 ++ * otherwise, define it to 0. ++ */ ++#define YTPHY_ENABLE_WOL 0 ++ ++/* some GMAC need clock input from PHY, for eg., 125M, please enable this macro ++ * by degault, it is set to 0 ++ * NOTE: this macro will need macro SYS_WAKEUP_BASED_ON_ETH_PKT to set to 1 ++ */ ++#define GMAC_CLOCK_INPUT_NEEDED 1 ++ ++ ++#define YT8521_PHY_MODE_FIBER 1 //fiber mode only ++#define YT8521_PHY_MODE_UTP 2 //utp mode only ++#define YT8521_PHY_MODE_POLL 3 //fiber and utp, poll mode ++ ++/* please make choice according to system design ++ * for Fiber only system, please define YT8521_PHY_MODE_CURR 1 ++ * for UTP only system, please define YT8521_PHY_MODE_CURR 2 ++ * for combo system, please define YT8521_PHY_MODE_CURR 3 ++ */ ++#define YT8521_PHY_MODE_CURR 3 ++ ++/**** configuration section end ***********/ ++ ++ ++/* no need to change below */ ++ ++#if (YTPHY_ENABLE_WOL) ++#undef SYS_WAKEUP_BASED_ON_ETH_PKT ++#define SYS_WAKEUP_BASED_ON_ETH_PKT 1 ++#endif ++ ++/* workaround for 8521 fiber 100m mode */ ++static int link_mode_8521 = 0; //0: no link; 1: utp; 32: fiber. traced that 1000m fiber uses 32. ++static int link_mode_8614[4] = {0}; //0: no link; 1: utp; 32: fiber. traced that 1000m fiber uses 32. ++ ++/* for multiple port phy, base phy address */ ++static unsigned int yt_mport_base_phy_addr = 0xff; //0xff: invalid; for 8618 ++static unsigned int yt_mport_base_phy_addr_8614 = 0xff; //0xff: invalid; ++ ++#if ( LINUX_VERSION_CODE > KERNEL_VERSION(5,0,0) ) ++int genphy_config_init(struct phy_device *phydev) ++{ ++ printk(KERN_ERR"csy: genphy_config_init\n"); ++ return genphy_read_abilities(phydev); ++} ++#endif ++ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++static int ytphy_config_init(struct phy_device *phydev) ++{ ++ return 0; ++} ++#endif + +static int ytphy_read_ext(struct phy_device *phydev, u32 regnum) +{ @@ -175,6 +351,13 @@ Signed-off-by: hmz007 +{ + int ret; + int val; ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ ret = ytphy_config_init(phydev); ++#else ++ ret = genphy_config_init(phydev); ++#endif ++ if (ret < 0) ++ return ret; + + ret = yt8512_clk_init(phydev); + if (ret < 0) @@ -222,7 +405,11 @@ Signed-off-by: hmz007 + case 2: + case 3: + default: ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ speed = -1; ++#else + speed = SPEED_UNKNOWN; ++#endif + break; + } + @@ -231,109 +418,1032 @@ Signed-off-by: hmz007 + + return 0; +} ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++#else ++#if 0 ++int yt8521_soft_reset(struct phy_device *phydev) ++{ ++ int ret; ++ ++ ytphy_write_ext(phydev, 0xa000, 0); ++ ret = genphy_soft_reset(phydev); ++ if (ret < 0) ++ return ret; ++ ++ ytphy_write_ext(phydev, 0xa000, 2); ++ ret = genphy_soft_reset(phydev); ++ if (ret < 0) { ++ ytphy_write_ext(phydev, 0xa000, 0); ++ return ret; ++ } ++ ++ return 0; ++} ++#else ++/* qingsong feedback 2 genphy_soft_reset will cause problem. ++ * and this is the reduction version ++ */ ++int yt8521_soft_reset(struct phy_device *phydev) ++{ ++ int ret, val; ++ ++ val = ytphy_read_ext(phydev, 0xa001); ++ ytphy_write_ext(phydev, 0xa001, (val & ~0x8000)); ++ ++ ret = genphy_soft_reset(phydev); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++#endif ++ ++#endif ++ ++#if GMAC_CLOCK_INPUT_NEEDED ++static int ytphy_mii_rd_ext(struct mii_bus *bus, int phy_id, u32 regnum) ++{ ++ int ret; ++ int val; ++ ++ ret = bus->write(bus, phy_id, REG_DEBUG_ADDR_OFFSET, regnum); ++ if (ret < 0) ++ return ret; ++ ++ val = bus->read(bus, phy_id, REG_DEBUG_DATA); ++ ++ return val; ++} ++ ++static int ytphy_mii_wr_ext(struct mii_bus *bus, int phy_id, u32 regnum, u16 val) ++{ ++ int ret; ++ ++ ret = bus->write(bus, phy_id, REG_DEBUG_ADDR_OFFSET, regnum); ++ if (ret < 0) ++ return ret; ++ ++ ret = bus->write(bus, phy_id, REG_DEBUG_DATA, val); ++ ++ return ret; ++} ++ ++int yt8511_config_dis_txdelay(struct mii_bus *bus, int phy_id) ++{ ++ int ret; ++ int val; ++ ++ /* disable auto sleep */ ++ val = ytphy_mii_rd_ext(bus, phy_id, 0x27); ++ if (val < 0) ++ return val; ++ ++ val &= (~BIT(15)); ++ ++ ret = ytphy_mii_wr_ext(bus, phy_id, 0x27, val); ++ if (ret < 0) ++ return ret; ++ ++ /* enable RXC clock when no wire plug */ ++ val = ytphy_mii_rd_ext(bus, phy_id, 0xc); ++ if (val < 0) ++ return val; ++ ++ /* ext reg 0xc b[7:4] ++ Tx Delay time = 150ps * N - 250ps ++ */ ++ val &= ~(0xf << 4); ++ ret = ytphy_mii_wr_ext(bus, phy_id, 0xc, val); ++ printk("yt8511_config_dis_txdelay..phy txdelay, val=%#08x\n",val); ++ ++ return ret; ++} ++ ++ ++int yt8511_config_out_125m(struct mii_bus *bus, int phy_id) ++{ ++ int ret; ++ int val; ++ ++ ret = ytphy_mii_wr_ext(bus, phy_id, 0xa012, 0xd0); ++ mdelay(100); ++ val = ytphy_mii_rd_ext(bus, phy_id, 0xa012); ++ ++ if(val != 0xd0) ++ { ++ printk("yt8511_config_out_125m error\n"); ++ return -1; ++ } ++ ++ /* disable auto sleep */ ++ val = ytphy_mii_rd_ext(bus, phy_id, 0x27); ++ if (val < 0) ++ return val; ++ ++ val &= (~BIT(15)); ++ ++ ret = ytphy_mii_wr_ext(bus, phy_id, 0x27, val); ++ if (ret < 0) ++ return ret; ++ ++ /* enable RXC clock when no wire plug */ ++ val = ytphy_mii_rd_ext(bus, phy_id, 0xc); ++ if (val < 0) ++ return val; ++ ++ /* ext reg 0xc.b[2:1] ++ 00-----25M from pll; ++ 01---- 25M from xtl;(default) ++ 10-----62.5M from pll; ++ 11----125M from pll(here set to this value) ++ */ ++ val |= (3 << 1); ++ ret = ytphy_mii_wr_ext(bus, phy_id, 0xc, val); ++ printk("yt8511_config_out_125m, phy clk out, val=%#08x\n",val); ++ ++ //ret = ytphy_mii_wr_ext(bus, phy_id, 0xa012, 0x70); ++ ++#if 0 ++ /* for customer, please enable it based on demand. ++ * configure to master ++ */ ++ val = bus->read(bus, phy_id, 0x9/*master/slave config reg*/); ++ val |= (0x3<<11); //to be manual config and force to be master ++ ret = bus->write(bus, phy_id, 0x9, val); //take effect until phy soft reset ++ if (ret < 0) ++ return ret; ++ ++ printk("yt8511_config_out_125m, phy to be master, val=%#08x\n",val); ++#endif ++ ++ return ret; ++} ++ ++EXPORT_SYMBOL(yt8511_config_out_125m); ++ ++static int yt8511_config_init(struct phy_device *phydev) ++{ ++ int ret; ++ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ ret = ytphy_config_init(phydev); ++#else ++ ret = genphy_config_init(phydev); ++#endif ++ ++ return ret; ++} ++#endif /*GMAC_CLOCK_INPUT_NEEDED*/ ++ ++#if (YTPHY_ENABLE_WOL) ++static int ytphy_switch_reg_space(struct phy_device *phydev, int space) ++{ ++ int ret; ++ ++ if (space == YTPHY_REG_SPACE_UTP){ ++ ret = ytphy_write_ext(phydev, 0xa000, 0); ++ }else{ ++ ret = ytphy_write_ext(phydev, 0xa000, 2); ++ } ++ ++ return ret; ++} ++ ++static int ytphy_wol_en_cfg(struct phy_device *phydev, ytphy_wol_cfg_t wol_cfg) ++{ ++ int ret=0; ++ int val=0; ++ ++ val = ytphy_read_ext(phydev, YTPHY_WOL_CFG_REG); ++ if (val < 0) ++ return val; ++ ++ if(wol_cfg.enable) { ++ val |= YTPHY_WOL_CFG_EN; ++ ++ if(wol_cfg.type == YTPHY_WOL_TYPE_LEVEL) { ++ val &= ~YTPHY_WOL_CFG_TYPE; ++ val &= ~YTPHY_WOL_CFG_INTR_SEL; ++ } else if(wol_cfg.type == YTPHY_WOL_TYPE_PULSE) { ++ val |= YTPHY_WOL_CFG_TYPE; ++ val |= YTPHY_WOL_CFG_INTR_SEL; ++ ++ if(wol_cfg.width == YTPHY_WOL_WIDTH_84MS) { ++ val &= ~YTPHY_WOL_CFG_WIDTH1; ++ val &= ~YTPHY_WOL_CFG_WIDTH2; ++ } else if(wol_cfg.width == YTPHY_WOL_WIDTH_168MS) { ++ val |= YTPHY_WOL_CFG_WIDTH1; ++ val &= ~YTPHY_WOL_CFG_WIDTH2; ++ } else if(wol_cfg.width == YTPHY_WOL_WIDTH_336MS) { ++ val &= ~YTPHY_WOL_CFG_WIDTH1; ++ val |= YTPHY_WOL_CFG_WIDTH2; ++ } else if(wol_cfg.width == YTPHY_WOL_WIDTH_672MS) { ++ val |= YTPHY_WOL_CFG_WIDTH1; ++ val |= YTPHY_WOL_CFG_WIDTH2; ++ } ++ } ++ } else { ++ val &= ~YTPHY_WOL_CFG_EN; ++ val &= ~YTPHY_WOL_CFG_INTR_SEL; ++ } ++ ++ ret = ytphy_write_ext(phydev, YTPHY_WOL_CFG_REG, val); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ ++static void ytphy_get_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol) ++{ ++ int val = 0; ++ ++ wol->supported = WAKE_MAGIC; ++ wol->wolopts = 0; ++ ++ val = ytphy_read_ext(phydev, YTPHY_WOL_CFG_REG); ++ if (val < 0) ++ return; ++ ++ if (val & YTPHY_WOL_CFG_EN) ++ wol->wolopts |= WAKE_MAGIC; ++ ++ return; ++} ++ ++static int ytphy_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol) ++{ ++ int ret, pre_page, val; ++ ytphy_wol_cfg_t wol_cfg; ++ struct net_device *p_attached_dev = phydev->attached_dev; ++ ++ memset(&wol_cfg,0,sizeof(ytphy_wol_cfg_t)); ++ pre_page = ytphy_read_ext(phydev, 0xa000); ++ if (pre_page < 0) ++ return pre_page; ++ ++ /* Switch to phy UTP page */ ++ ret = ytphy_switch_reg_space(phydev, YTPHY_REG_SPACE_UTP); ++ if (ret < 0) ++ return ret; ++ ++ if (wol->wolopts & WAKE_MAGIC) { ++ ++ /* Enable the WOL interrupt */ ++ val = phy_read(phydev, YTPHY_UTP_INTR_REG); ++ val |= YTPHY_WOL_INTR; ++ ret = phy_write(phydev, YTPHY_UTP_INTR_REG, val); ++ if (ret < 0) ++ return ret; ++ ++ /* Set the WOL config */ ++ wol_cfg.enable = 1; //enable ++ wol_cfg.type= YTPHY_WOL_TYPE_PULSE; ++ wol_cfg.width= YTPHY_WOL_WIDTH_672MS; ++ ret = ytphy_wol_en_cfg(phydev, wol_cfg); ++ if (ret < 0) ++ return ret; ++ ++ /* Store the device address for the magic packet */ ++ ret = ytphy_write_ext(phydev, YTPHY_MAGIC_PACKET_MAC_ADDR2, ++ ((p_attached_dev->dev_addr[0] << 8) | ++ p_attached_dev->dev_addr[1])); ++ if (ret < 0) ++ return ret; ++ ret = ytphy_write_ext(phydev, YTPHY_MAGIC_PACKET_MAC_ADDR1, ++ ((p_attached_dev->dev_addr[2] << 8) | ++ p_attached_dev->dev_addr[3])); ++ if (ret < 0) ++ return ret; ++ ret = ytphy_write_ext(phydev, YTPHY_MAGIC_PACKET_MAC_ADDR0, ++ ((p_attached_dev->dev_addr[4] << 8) | ++ p_attached_dev->dev_addr[5])); ++ if (ret < 0) ++ return ret; ++ } else { ++ wol_cfg.enable = 0; //disable ++ wol_cfg.type= YTPHY_WOL_TYPE_MAX; ++ wol_cfg.width= YTPHY_WOL_WIDTH_MAX; ++ ret = ytphy_wol_en_cfg(phydev, wol_cfg); ++ if (ret < 0) ++ return ret; ++ } ++ ++ /* Recover to previous register space page */ ++ ret = ytphy_switch_reg_space(phydev, pre_page); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ ++#endif /*(YTPHY_ENABLE_WOL)*/ + +static int yt8521_config_init(struct phy_device *phydev) +{ + int ret; + int val; + ++ phydev->irq = PHY_POLL; ++ ++ ytphy_write_ext(phydev, 0xa000, 0); ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ ret = ytphy_config_init(phydev); ++#else ++ ret = genphy_config_init(phydev); ++#endif ++ if (ret < 0) ++ return ret; ++ + /* disable auto sleep */ + val = ytphy_read_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1); + if (val < 0) + return val; + + val &= (~BIT(YT8521_EN_SLEEP_SW_BIT)); ++ + ret = ytphy_write_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1, val); + if (ret < 0) + return ret; + -+ /* switch to access UTP */ ++ /* enable RXC clock when no wire plug */ + ret = ytphy_write_ext(phydev, 0xa000, 0); + if (ret < 0) + return ret; + -+ /* enable RXC clock when no wire plug */ + val = ytphy_read_ext(phydev, 0xc); + if (val < 0) + return val; -+ + val &= ~(1 << 12); + ret = ytphy_write_ext(phydev, 0xc, val); + if (ret < 0) + return ret; + -+ /* output SyncE clock (125mhz) even link is down */ -+ ret = ytphy_write_ext(phydev, 0xa012, 0x38); -+ if (ret < 0) -+ return ret; ++ printk (KERN_INFO "yt8521_config_init, 8521 init call out.\n"); ++ return ret; ++} + -+ /* disable rgmii clk 2ns delay */ -+ val = ytphy_read_ext(phydev, 0xa001); -+ if (val < 0) -+ return val; ++/* ++ * for fiber mode, there is no 10M speed mode and ++ * this function is for this purpose. ++ */ ++static int yt8521_adjust_status(struct phy_device *phydev, int val, int is_utp) ++{ ++ int speed_mode, duplex; ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ int speed = -1; ++#else ++ int speed = SPEED_UNKNOWN; ++#endif + -+ val &= ~(1 << 8); -+ ret = ytphy_write_ext(phydev, 0xa001, val); -+ if (ret < 0) -+ return ret; ++ duplex = (val & YT8512_DUPLEX) >> YT8521_DUPLEX_BIT; ++ speed_mode = (val & YT8521_SPEED_MODE) >> YT8521_SPEED_MODE_BIT; ++ switch (speed_mode) { ++ case 0: ++ if (is_utp) ++ speed = SPEED_10; ++ break; ++ case 1: ++ speed = SPEED_100; ++ break; ++ case 2: ++ speed = SPEED_1000; ++ break; ++ case 3: ++ break; ++ default: ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ speed = -1; ++#else ++ speed = SPEED_UNKNOWN; ++#endif ++ break; ++ } + -+ /* setup delay */ -+ val = (1 << 10) | (0xf << 4) | 5; -+ ret = ytphy_write_ext(phydev, 0xa003, val); -+ if (ret < 0) -+ return ret; -+ -+ /* LED0: Unused/Off, LED1: Link, LED2: Activity, 8Hz */ -+ ytphy_write_ext(phydev, 0xa00b, 0xe004); -+ ytphy_write_ext(phydev, 0xa00c, 0); -+ ytphy_write_ext(phydev, 0xa00d, 0x2600); -+ ytphy_write_ext(phydev, 0xa00e, 0x0070); -+ ytphy_write_ext(phydev, 0xa00f, 0x000a); ++ phydev->speed = speed; ++ phydev->duplex = duplex; ++ //printk (KERN_INFO "yt8521_adjust_status call out,regval=0x%04x,mode=%s,speed=%dm...\n", val,is_utp?"utp":"fiber", phydev->speed); + + return 0; +} + -+static int yt8521_config_intr(struct phy_device *phydev) ++/* ++ * for fiber mode, when speed is 100M, there is no definition for autonegotiation, and ++ * this function handles this case and return 1 per linux kernel's polling. ++ */ ++int yt8521_aneg_done (struct phy_device *phydev) +{ -+ int val; + -+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) -+ val = BIT(14) | BIT(13) | BIT(11) | BIT(10); -+ else -+ val = 0; ++ //printk("yt8521_aneg_done callin,speed=%dm,linkmoded=%d\n", phydev->speed,link_mode_8521); + -+ return phy_write(phydev, REG_INT_MASK, val); ++ if((32 == link_mode_8521) && (SPEED_100 == phydev->speed)) ++ { ++ return 1/*link_mode_8521*/; ++ } ++ ++#if ( LINUX_VERSION_CODE > KERNEL_VERSION(3,11,0) ) ++ return genphy_aneg_done(phydev); ++#else ++ return 1; ++#endif +} + -+static int yt8521_ack_interrupt(struct phy_device *phydev) ++static int yt8521_read_status(struct phy_device *phydev) +{ ++ int ret; ++ volatile int val, yt8521_fiber_latch_val, yt8521_fiber_curr_val; ++ volatile int link; ++ int link_utp = 0, link_fiber = 0; ++ ++#if (YT8521_PHY_MODE_CURR != YT8521_PHY_MODE_FIBER) ++ /* reading UTP */ ++ ret = ytphy_write_ext(phydev, 0xa000, 0); ++ if (ret < 0) ++ return ret; ++ ++ val = phy_read(phydev, REG_PHY_SPEC_STATUS); ++ if (val < 0) ++ return val; ++ ++ link = val & (BIT(YT8521_LINK_STATUS_BIT)); ++ if (link) { ++ link_utp = 1; ++ link_mode_8521 = 1; ++ yt8521_adjust_status(phydev, val, 1); ++ } else { ++ link_utp = 0; ++ } ++#endif //(YT8521_PHY_MODE_CURR != YT8521_PHY_MODE_FIBER) ++ ++#if (YT8521_PHY_MODE_CURR != YT8521_PHY_MODE_UTP) ++ /* reading Fiber */ ++ ret = ytphy_write_ext(phydev, 0xa000, 2); ++ if (ret < 0) ++ return ret; ++ ++ val = phy_read(phydev, REG_PHY_SPEC_STATUS); ++ if (val < 0) ++ return val; ++ ++ //note: below debug information is used to check multiple PHy ports. ++ //printk (KERN_INFO "yt8521_read_status, fiber status=%04x,macbase=0x%08lx\n", val,(unsigned long)phydev->attached_dev); ++ ++ /* for fiber, from 1000m to 100m, there is not link down from 0x11, and check reg 1 to identify such case ++ * this is important for Linux kernel for that, missing linkdown event will cause problem. ++ */ ++ yt8521_fiber_latch_val = phy_read(phydev, MII_BMSR); ++ yt8521_fiber_curr_val = phy_read(phydev, MII_BMSR); ++ link = val & (BIT(YT8521_LINK_STATUS_BIT)); ++ if((link) && (yt8521_fiber_latch_val != yt8521_fiber_curr_val)) ++ { ++ link = 0; ++ printk (KERN_INFO "yt8521_read_status, fiber link down detect,latch=%04x,curr=%04x\n", yt8521_fiber_latch_val,yt8521_fiber_curr_val); ++ } ++ ++ if (link) { ++ link_fiber = 1; ++ yt8521_adjust_status(phydev, val, 0); ++ link_mode_8521 = 32; //fiber mode ++ ++ ++ } else { ++ link_fiber = 0; ++ } ++#endif //(YT8521_PHY_MODE_CURR != YT8521_PHY_MODE_UTP) ++ ++ if (link_utp || link_fiber) { ++ phydev->link = 1; ++ } else { ++ phydev->link = 0; ++ link_mode_8521 = 0; ++ } ++ ++#if (YT8521_PHY_MODE_CURR != YT8521_PHY_MODE_FIBER) ++ if (link_utp) { ++ ytphy_write_ext(phydev, 0xa000, 0); ++ } ++#endif ++ ++ //printk (KERN_INFO "yzhang..8521 read status call out,link=%d,linkmode=%d\n", phydev->link, link_mode_8521 ); ++ return 0; ++} ++ ++int yt8521_suspend(struct phy_device *phydev) ++{ ++#if !(SYS_WAKEUP_BASED_ON_ETH_PKT) ++ int value; ++ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ mutex_lock(&phydev->lock); ++#else ++ /* no need lock in 4.19 */ ++#endif ++ ++ ytphy_write_ext(phydev, 0xa000, 0); ++ value = phy_read(phydev, MII_BMCR); ++ phy_write(phydev, MII_BMCR, value | BMCR_PDOWN); ++ ++ ytphy_write_ext(phydev, 0xa000, 2); ++ value = phy_read(phydev, MII_BMCR); ++ phy_write(phydev, MII_BMCR, value | BMCR_PDOWN); ++ ++ ytphy_write_ext(phydev, 0xa000, 0); ++ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ mutex_unlock(&phydev->lock); ++#else ++ /* no need lock/unlock in 4.19 */ ++#endif ++#endif /*!(SYS_WAKEUP_BASED_ON_ETH_PKT)*/ ++ ++ return 0; ++} ++ ++int yt8521_resume(struct phy_device *phydev) ++{ ++#if !(SYS_WAKEUP_BASED_ON_ETH_PKT) ++ int value; ++ int ret; ++ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ mutex_lock(&phydev->lock); ++#else ++ /* no need lock/unlock in 4.19 */ ++#endif ++ ++ ytphy_write_ext(phydev, 0xa000, 0); ++ value = phy_read(phydev, MII_BMCR); ++ phy_write(phydev, MII_BMCR, value & ~BMCR_PDOWN); ++ ++ /* disable auto sleep */ ++ value = ytphy_read_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1); ++ if (value < 0) ++ return value; ++ ++ value &= (~BIT(YT8521_EN_SLEEP_SW_BIT)); ++ ret = ytphy_write_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1, value); ++ if (ret < 0) ++ return ret; ++ ++ /* enable RXC clock when no wire plug */ ++ value = ytphy_read_ext(phydev, 0xc); ++ if (value < 0) ++ return value; ++ value &= ~(1 << 12); ++ ret = ytphy_write_ext(phydev, 0xc, value); ++ if (ret < 0) ++ return ret; ++ ++ ytphy_write_ext(phydev, 0xa000, 2); ++ value = phy_read(phydev, MII_BMCR); ++ phy_write(phydev, MII_BMCR, value & ~BMCR_PDOWN); ++ ++#if (YT8521_PHY_MODE_CURR != YT8521_PHY_MODE_FIBER) ++ ytphy_write_ext(phydev, 0xa000, 0); ++#endif ++ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ mutex_unlock(&phydev->lock); ++#else ++ /* no need lock/unlock in 4.19 */ ++#endif ++#endif /*!(SYS_WAKEUP_BASED_ON_ETH_PKT)*/ ++ ++ return 0; ++} ++ ++ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++#else ++int yt8618_soft_reset(struct phy_device *phydev) ++{ ++ int ret; ++ ++ ytphy_write_ext(phydev, 0xa000, 0); ++ ret = genphy_soft_reset(phydev); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ ++int yt8614_soft_reset(struct phy_device *phydev) ++{ ++ int ret; ++ ++ /* utp */ ++ ytphy_write_ext(phydev, 0xa000, 0); ++ ret = genphy_soft_reset(phydev); ++ if (ret < 0) ++ return ret; ++ ++ /* qsgmii */ ++ ytphy_write_ext(phydev, 0xa000, 2); ++ ret = genphy_soft_reset(phydev); ++ if (ret < 0) { ++ ytphy_write_ext(phydev, 0xa000, 0); //back to utp mode ++ return ret; ++ } ++ ++ /* sgmii */ ++ ytphy_write_ext(phydev, 0xa000, 3); ++ ret = genphy_soft_reset(phydev); ++ if (ret < 0) { ++ ytphy_write_ext(phydev, 0xa000, 0); //back to utp mode ++ return ret; ++ } ++ ++ return 0; ++} ++ ++#endif ++ ++static int yt8618_config_init(struct phy_device *phydev) ++{ ++ int ret; + int val; + -+ val = phy_read(phydev, REG_INT_STATUS); -+ phydev_dbg(phydev, "intr status 0x04%x\n", val); ++ phydev->irq = PHY_POLL; + -+ return (val < 0) ? val : 0; ++ if(0xff == yt_mport_base_phy_addr) ++ /* by default, we think the first phy should be the base phy addr. for mul */ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ { ++ yt_mport_base_phy_addr = phydev->addr; ++ }else if (yt_mport_base_phy_addr > phydev->addr) { ++ printk (KERN_INFO "yzhang..8618 init, phy address mismatch, base=%d, cur=%d\n", yt_mport_base_phy_addr, phydev->addr); ++ } ++#else ++ { ++ yt_mport_base_phy_addr = phydev->mdio.addr; ++ }else if (yt_mport_base_phy_addr > phydev->mdio.addr) { ++ printk (KERN_INFO "yzhang..8618 init, phy address mismatch, base=%d, cur=%d\n", yt_mport_base_phy_addr, phydev->mdio.addr); ++ } ++#endif ++ ++ ytphy_write_ext(phydev, 0xa000, 0); ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ ret = ytphy_config_init(phydev); ++#else ++ ret = genphy_config_init(phydev); ++#endif ++ if (ret < 0) ++ return ret; ++ ++ /* for utp to optimize signal */ ++ ret = ytphy_write_ext(phydev, 0x41, 0x33); ++ if (ret < 0) ++ return ret; ++ ret = ytphy_write_ext(phydev, 0x42, 0x66); ++ if (ret < 0) ++ return ret; ++ ret = ytphy_write_ext(phydev, 0x43, 0xaa); ++ if (ret < 0) ++ return ret; ++ ret = ytphy_write_ext(phydev, 0x44, 0xd0d); ++ if (ret < 0) ++ return ret; ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ if((phydev->addr > yt_mport_base_phy_addr) && ((2 == phydev->addr - yt_mport_base_phy_addr) || (5 == phydev->addr - yt_mport_base_phy_addr))) ++#else ++ if((phydev->mdio.addr > yt_mport_base_phy_addr) && ((2 == phydev->mdio.addr - yt_mport_base_phy_addr) || (5 == phydev->mdio.addr - yt_mport_base_phy_addr))) ++#endif ++ { ++ ret = ytphy_write_ext(phydev, 0x44, 0x2929); ++ if (ret < 0) ++ return ret; ++ } ++ ++ val = phy_read(phydev, MII_BMCR); ++ phy_write(phydev, MII_BMCR, val | BMCR_RESET); ++ ++ printk (KERN_INFO "yt8618_config_init call out.\n"); ++ return ret; +} + ++static int yt8614_config_init(struct phy_device *phydev) ++{ ++ int ret = 0; ++ ++ phydev->irq = PHY_POLL; ++ ++ if(0xff == yt_mport_base_phy_addr_8614) ++ /* by default, we think the first phy should be the base phy addr. for mul */ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ { ++ yt_mport_base_phy_addr_8614 = (unsigned int)phydev->addr; ++ }else if (yt_mport_base_phy_addr_8614 > (unsigned int)phydev->addr) { ++ printk (KERN_INFO "yzhang..8618 init, phy address mismatch, base=%u, cur=%d\n", yt_mport_base_phy_addr_8614, phydev->addr); ++ } ++#else ++ { ++ yt_mport_base_phy_addr_8614 = (unsigned int)phydev->mdio.addr; ++ }else if (yt_mport_base_phy_addr_8614 > (unsigned int)phydev->mdio.addr) { ++ printk (KERN_INFO "yzhang..8618 init, phy address mismatch, base=%u, cur=%d\n", yt_mport_base_phy_addr_8614, phydev->mdio.addr); ++ } ++#endif ++ return ret; ++} ++ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++#define yt8614_get_port_from_phydev(phydev) ((0xff == yt_mport_base_phy_addr_8614) && (yt_mport_base_phy_addr_8614 <= (phydev)->addr) ? 0 : (unsigned int)((phydev)->addr) - yt_mport_base_phy_addr_8614) ++#else ++#define yt8614_get_port_from_phydev(phydev) ((0xff == yt_mport_base_phy_addr_8614) && (yt_mport_base_phy_addr_8614 <= (phydev)->mdio.addr) ? 0 : (unsigned int)((phydev)->mdio.addr) - yt_mport_base_phy_addr_8614) ++#endif ++ ++int yt8618_aneg_done (struct phy_device *phydev) ++{ ++ ++ return genphy_aneg_done(phydev); ++} ++ ++int yt8614_aneg_done (struct phy_device *phydev) ++{ ++ int port = yt8614_get_port_from_phydev(phydev); ++ ++ /*it should be used for 8614 fiber*/ ++ if((32 == link_mode_8614[port]) && (SPEED_100 == phydev->speed)) ++ { ++ return 1; ++ } ++ ++ return genphy_aneg_done(phydev); ++} ++ ++static int yt8614_read_status(struct phy_device *phydev) ++{ ++ //int i; ++ int ret; ++ volatile int val, yt8614_fiber_latch_val, yt8614_fiber_curr_val; ++ volatile int link; ++ int link_utp = 0, link_fiber = 0; ++ int port = yt8614_get_port_from_phydev(phydev); ++ ++#if (YT8614_PHY_MODE_CURR != YT8521_PHY_MODE_FIBER) ++ /* switch to utp and reading regs */ ++ ret = ytphy_write_ext(phydev, 0xa000, 0); ++ if (ret < 0) ++ return ret; ++ ++ val = phy_read(phydev, REG_PHY_SPEC_STATUS); ++ if (val < 0) ++ return val; ++ ++ link = val & (BIT(YT8521_LINK_STATUS_BIT)); ++ if (link) { ++ link_utp = 1; ++ // here is same as 8521 and re-use the function; ++ yt8521_adjust_status(phydev, val, 1); ++ } else { ++ link_utp = 0; ++ } ++#endif //(YT8614_PHY_MODE_CURR != YT8521_PHY_MODE_FIBER) ++ ++#if (YT8614_PHY_MODE_CURR != YT8521_PHY_MODE_UTP) ++ /* reading Fiber/sgmii */ ++ ret = ytphy_write_ext(phydev, 0xa000, 3); ++ if (ret < 0) ++ return ret; ++ ++ val = phy_read(phydev, REG_PHY_SPEC_STATUS); ++ if (val < 0) ++ return val; ++ ++ //printk (KERN_INFO "yzhang..8614 read fiber status=%04x,macbase=0x%08lx\n", val,(unsigned long)phydev->attached_dev); ++ ++ /* for fiber, from 1000m to 100m, there is not link down from 0x11, and check reg 1 to identify such case */ ++ yt8614_fiber_latch_val = phy_read(phydev, MII_BMSR); ++ yt8614_fiber_curr_val = phy_read(phydev, MII_BMSR); ++ link = val & (BIT(YT8521_LINK_STATUS_BIT)); ++ if((link) && (yt8614_fiber_latch_val != yt8614_fiber_curr_val)) ++ { ++ link = 0; ++ printk (KERN_INFO "yt8614_read_status, fiber link down detect,latch=%04x,curr=%04x\n", yt8614_fiber_latch_val,yt8614_fiber_curr_val); ++ } ++ ++ if (link) { ++ link_fiber = 1; ++ yt8521_adjust_status(phydev, val, 0); ++ link_mode_8614[port] = 32; //fiber mode ++ ++ ++ } else { ++ link_fiber = 0; ++ } ++#endif //(YT8521_PHY_MODE_CURR != YT8521_PHY_MODE_UTP) ++ ++ if (link_utp || link_fiber) { ++ phydev->link = 1; ++ } else { ++ phydev->link = 0; ++ link_mode_8614[port] = 0; ++ } ++ ++#if (YT8614_PHY_MODE_CURR != YT8521_PHY_MODE_FIBER) ++ if (link_utp) { ++ ytphy_write_ext(phydev, 0xa000, 0); ++ } ++#endif ++ //printk (KERN_INFO "yt8614_read_status call out,link=%d,linkmode=%d\n", phydev->link, link_mode_8614[port] ); ++ ++ return 0; ++} ++ ++static int yt8618_read_status(struct phy_device *phydev) ++{ ++ int ret; ++ volatile int val; //maybe for 8614 yt8521_fiber_latch_val, yt8521_fiber_curr_val; ++ volatile int link; ++ int link_utp = 0, link_fiber = 0; ++ ++ /* switch to utp and reading regs */ ++ ret = ytphy_write_ext(phydev, 0xa000, 0); ++ if (ret < 0) ++ return ret; ++ ++ val = phy_read(phydev, REG_PHY_SPEC_STATUS); ++ if (val < 0) ++ return val; ++ ++ link = val & (BIT(YT8521_LINK_STATUS_BIT)); ++ if (link) { ++ link_utp = 1; ++ yt8521_adjust_status(phydev, val, 1); ++ } else { ++ link_utp = 0; ++ } ++ ++ if (link_utp || link_fiber) { ++ phydev->link = 1; ++ } else { ++ phydev->link = 0; ++ } ++ ++ return 0; ++} ++ ++int yt8618_suspend(struct phy_device *phydev) ++{ ++#if !(SYS_WAKEUP_BASED_ON_ETH_PKT) ++ int value; ++ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ mutex_lock(&phydev->lock); ++#else ++ /* no need lock in 4.19 */ ++#endif ++ ++ ytphy_write_ext(phydev, 0xa000, 0); ++ value = phy_read(phydev, MII_BMCR); ++ phy_write(phydev, MII_BMCR, value | BMCR_PDOWN); ++ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ mutex_unlock(&phydev->lock); ++#else ++ /* no need lock/unlock in 4.19 */ ++#endif ++#endif /*!(SYS_WAKEUP_BASED_ON_ETH_PKT)*/ ++ ++ return 0; ++} ++ ++int yt8618_resume(struct phy_device *phydev) ++{ ++#if !(SYS_WAKEUP_BASED_ON_ETH_PKT) ++ int value; ++ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ mutex_lock(&phydev->lock); ++#else ++ /* no need lock/unlock in 4.19 */ ++#endif ++ ++ ytphy_write_ext(phydev, 0xa000, 0); ++ value = phy_read(phydev, MII_BMCR); ++ phy_write(phydev, MII_BMCR, value & ~BMCR_PDOWN); ++ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ mutex_unlock(&phydev->lock); ++#else ++ /* no need lock/unlock in 4.19 */ ++#endif ++#endif /*!(SYS_WAKEUP_BASED_ON_ETH_PKT)*/ ++ ++ return 0; ++} ++ ++int yt8614_suspend(struct phy_device *phydev) ++{ ++#if !(SYS_WAKEUP_BASED_ON_ETH_PKT) ++ int value; ++ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ mutex_lock(&phydev->lock); ++#else ++ /* no need lock in 4.19 */ ++#endif ++ ++ ytphy_write_ext(phydev, 0xa000, 0); ++ value = phy_read(phydev, MII_BMCR); ++ phy_write(phydev, MII_BMCR, value | BMCR_PDOWN); ++ ++ ytphy_write_ext(phydev, 0xa000, 3); ++ value = phy_read(phydev, MII_BMCR); ++ phy_write(phydev, MII_BMCR, value | BMCR_PDOWN); ++ ++ ytphy_write_ext(phydev, 0xa000, 0); ++ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ mutex_unlock(&phydev->lock); ++#else ++ /* no need lock/unlock in 4.19 */ ++#endif ++#endif /*!(SYS_WAKEUP_BASED_ON_ETH_PKT)*/ ++ ++ return 0; ++} ++ ++int yt8614_resume(struct phy_device *phydev) ++{ ++#if !(SYS_WAKEUP_BASED_ON_ETH_PKT) ++ int value; ++ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ mutex_lock(&phydev->lock); ++#else ++ /* no need lock/unlock in 4.19 */ ++#endif ++ ++ ytphy_write_ext(phydev, 0xa000, 0); ++ value = phy_read(phydev, MII_BMCR); ++ phy_write(phydev, MII_BMCR, value & ~BMCR_PDOWN); ++ ++ ytphy_write_ext(phydev, 0xa000, 3); ++ value = phy_read(phydev, MII_BMCR); ++ phy_write(phydev, MII_BMCR, value & ~BMCR_PDOWN); ++ ++ ytphy_write_ext(phydev, 0xa000, 0); ++ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ mutex_unlock(&phydev->lock); ++#else ++ /* no need lock/unlock in 4.19 */ ++#endif ++#endif /*!(SYS_WAKEUP_BASED_ON_ETH_PKT)*/ ++ ++ return 0; ++} ++ ++ +static struct phy_driver ytphy_drvs[] = { + { -+ .phy_id = PHY_ID_YT8010, -+ .name = "YT8010 Automotive Ethernet", -+ .phy_id_mask = MOTORCOMM_PHY_ID_MASK, -+ .features = PHY_BASIC_FEATURES, -+ .config_aneg = yt8010_config_aneg, -+ .read_status = genphy_read_status, ++ .phy_id = PHY_ID_YT8010, ++ .name = "YT8010 Automotive Ethernet", ++ .phy_id_mask = MOTORCOMM_PHY_ID_MASK, ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ) ++ .features = PHY_BASIC_FEATURES, ++ .flags = PHY_HAS_INTERRUPT, ++#endif ++ .config_aneg = yt8010_config_aneg, ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ .config_init = ytphy_config_init, ++#else ++ .config_init = genphy_config_init, ++#endif ++ .read_status = genphy_read_status, + }, { + .phy_id = PHY_ID_YT8510, + .name = "YT8510 100/10Mb Ethernet", + .phy_id_mask = MOTORCOMM_PHY_ID_MASK, ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ) + .features = PHY_BASIC_FEATURES, ++ .flags = PHY_HAS_INTERRUPT, ++#endif ++ .config_aneg = genphy_config_aneg, ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ .config_init = ytphy_config_init, ++#else ++ .config_init = genphy_config_init, ++#endif + .read_status = genphy_read_status, + }, { + .phy_id = PHY_ID_YT8511, + .name = "YT8511 Gigabit Ethernet", + .phy_id_mask = MOTORCOMM_PHY_ID_MASK, ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ) + .features = PHY_GBIT_FEATURES, ++ .flags = PHY_HAS_INTERRUPT, ++#endif ++ .config_aneg = genphy_config_aneg, ++#if GMAC_CLOCK_INPUT_NEEDED ++ .config_init = yt8511_config_init, ++#else ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ .config_init = ytphy_config_init, ++#else ++ .config_init = genphy_config_init, ++#endif ++#endif + .read_status = genphy_read_status, + .suspend = genphy_suspend, + .resume = genphy_resume, @@ -341,7 +1451,11 @@ Signed-off-by: hmz007 + .phy_id = PHY_ID_YT8512, + .name = "YT8512 Ethernet", + .phy_id_mask = MOTORCOMM_PHY_ID_MASK, ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ) + .features = PHY_BASIC_FEATURES, ++ .flags = PHY_HAS_INTERRUPT, ++#endif ++ .config_aneg = genphy_config_aneg, + .config_init = yt8512_config_init, + .read_status = yt8512_read_status, + .suspend = genphy_suspend, @@ -350,25 +1464,177 @@ Signed-off-by: hmz007 + .phy_id = PHY_ID_YT8512B, + .name = "YT8512B Ethernet", + .phy_id_mask = MOTORCOMM_PHY_ID_MASK, ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ) + .features = PHY_BASIC_FEATURES, ++ .flags = PHY_HAS_INTERRUPT, ++#endif ++ .config_aneg = genphy_config_aneg, + .config_init = yt8512_config_init, + .read_status = yt8512_read_status, + .suspend = genphy_suspend, + .resume = genphy_resume, + }, { -+ .phy_id = PHY_ID_YT8521, -+ .name = "YT8521 Ethernet", ++ .phy_id = PHY_ID_YT8521, ++ .name = "YT8521 Ethernet", ++ .phy_id_mask = MOTORCOMM_PHY_ID_MASK, ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ) ++ .features = PHY_BASIC_FEATURES | PHY_GBIT_FEATURES, ++#endif ++ .flags = PHY_POLL, ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++#else ++ .soft_reset = yt8521_soft_reset, ++#endif ++ .config_aneg = genphy_config_aneg, ++#if ( LINUX_VERSION_CODE > KERNEL_VERSION(3,11,0) ) ++ .aneg_done = yt8521_aneg_done, ++#endif ++ .config_init = yt8521_config_init, ++ .read_status = yt8521_read_status, ++ .suspend = yt8521_suspend, ++ .resume = yt8521_resume, ++#if (YTPHY_ENABLE_WOL) ++ .get_wol = &ytphy_get_wol, ++ .set_wol = &ytphy_set_wol, ++#endif ++ },{ ++ /* same as 8521 */ ++ .phy_id = PHY_ID_YT8531S, ++ .name = "YT8531S Ethernet", ++ .phy_id_mask = MOTORCOMM_PHY_ID_MASK, ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ) ++ .features = PHY_BASIC_FEATURES | PHY_GBIT_FEATURES, ++#endif ++ .flags = PHY_POLL, ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++#else ++ .soft_reset = yt8521_soft_reset, ++#endif ++ .config_aneg = genphy_config_aneg, ++#if ( LINUX_VERSION_CODE > KERNEL_VERSION(3,11,0) ) ++ .aneg_done = yt8521_aneg_done, ++#endif ++ .config_init = yt8521_config_init, ++ .read_status = yt8521_read_status, ++ .suspend = yt8521_suspend, ++ .resume = yt8521_resume, ++#if (YTPHY_ENABLE_WOL) ++ .get_wol = &ytphy_get_wol, ++ .set_wol = &ytphy_set_wol, ++#endif ++ }, { ++ /* same as 8511 */ ++ .phy_id = PHY_ID_YT8531, ++ .name = "YT8531 Gigabit Ethernet", + .phy_id_mask = MOTORCOMM_PHY_ID_MASK, -+ /* PHY_GBIT_FEATURES */ -+ .config_init = yt8521_config_init, -+ .ack_interrupt = yt8521_ack_interrupt, -+ .config_intr = yt8521_config_intr, ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ) ++ .features = PHY_BASIC_FEATURES | PHY_GBIT_FEATURES, ++ .flags = PHY_HAS_INTERRUPT, ++#endif ++ .config_aneg = genphy_config_aneg, ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++ .config_init = ytphy_config_init, ++#else ++ .config_init = genphy_config_init, ++#endif ++ .read_status = genphy_read_status, + .suspend = genphy_suspend, + .resume = genphy_resume, -+ }, ++#if (YTPHY_ENABLE_WOL) ++ .get_wol = &ytphy_get_wol, ++ .set_wol = &ytphy_set_wol, ++#endif ++ }, { ++ .phy_id = PHY_ID_YT8618, ++ .name = "YT8618 Ethernet", ++ .phy_id_mask = MOTORCOMM_MPHY_ID_MASK, ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ) ++ .features = PHY_BASIC_FEATURES | PHY_GBIT_FEATURES, ++#endif ++ .flags = PHY_POLL, ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++#else ++ .soft_reset = yt8618_soft_reset, ++#endif ++ .config_aneg = genphy_config_aneg, ++#if ( LINUX_VERSION_CODE > KERNEL_VERSION(3,11,0) ) ++ .aneg_done = yt8618_aneg_done, ++#endif ++ .config_init = yt8618_config_init, ++ .read_status = yt8618_read_status, ++ .suspend = yt8618_suspend, ++ .resume = yt8618_resume, ++ }, { ++ .phy_id = PHY_ID_YT8614, ++ .name = "YT8614 Ethernet", ++ .phy_id_mask = MOTORCOMM_MPHY_ID_MASK_8614, ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) ) ++ .features = PHY_BASIC_FEATURES | PHY_GBIT_FEATURES, ++#endif ++ .flags = PHY_POLL, ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++#else ++ .soft_reset = yt8614_soft_reset, ++#endif ++ .config_aneg = genphy_config_aneg, ++#if ( LINUX_VERSION_CODE > KERNEL_VERSION(3,11,0) ) ++ .aneg_done = yt8614_aneg_done, ++#endif ++ .config_init = yt8614_config_init, ++ .read_status = yt8614_read_status, ++ .suspend = yt8614_suspend, ++ .resume = yt8614_resume, ++ }, +}; + ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) ) ++static int ytphy_drivers_register(struct phy_driver* phy_drvs, int size) ++{ ++ int i, j; ++ int ret; ++ ++ for (i = 0; i < size; i++) { ++ ret = phy_driver_register(&phy_drvs[i]); ++ if (ret) ++ goto err; ++ } ++ ++ return 0; ++ ++err: ++ for (j = 0; j < i; j++) ++ phy_driver_unregister(&phy_drvs[j]); ++ ++ return ret; ++} ++ ++static void ytphy_drivers_unregister(struct phy_driver* phy_drvs, int size) ++{ ++ int i; ++ ++ for (i = 0; i < size; i++) { ++ phy_driver_unregister(&phy_drvs[i]); ++ } ++} ++ ++static int __init ytphy_init(void) ++{ ++ printk("motorcomm phy register\n"); ++ return ytphy_drivers_register(ytphy_drvs, ARRAY_SIZE(ytphy_drvs)); ++} ++ ++static void __exit ytphy_exit(void) ++{ ++ printk("motorcomm phy unregister\n"); ++ ytphy_drivers_unregister(ytphy_drvs, ARRAY_SIZE(ytphy_drvs)); ++} ++ ++module_init(ytphy_init); ++module_exit(ytphy_exit); ++#else ++/* for linux 4.x */ +module_phy_driver(ytphy_drvs); ++#endif + +MODULE_DESCRIPTION("Motorcomm PHY driver"); +MODULE_AUTHOR("Leilei Zhao"); @@ -381,13 +1647,544 @@ Signed-off-by: hmz007 + { PHY_ID_YT8512, MOTORCOMM_PHY_ID_MASK }, + { PHY_ID_YT8512B, MOTORCOMM_PHY_ID_MASK }, + { PHY_ID_YT8521, MOTORCOMM_PHY_ID_MASK }, ++ { PHY_ID_YT8531S, MOTORCOMM_PHY_ID_8531_MASK }, ++ { PHY_ID_YT8531, MOTORCOMM_PHY_ID_8531_MASK }, ++ { PHY_ID_YT8618, MOTORCOMM_MPHY_ID_MASK }, ++ { PHY_ID_YT8614, MOTORCOMM_MPHY_ID_MASK_8614 }, + { } +}; + +MODULE_DEVICE_TABLE(mdio, motorcomm_tbl); ++ ++ +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -808,6 +808,8 @@ + return 0; + } + ++int yt8511_config_out_125m(struct mii_bus *bus, int phy_id); ++ + /** + * get_phy_device - reads the specified PHY device and returns its @phy_device + * struct +@@ -835,6 +837,19 @@ + if ((phy_id & 0x1fffffff) == 0x1fffffff) + return ERR_PTR(-ENODEV); + ++ printk (KERN_INFO "yzhang..read phyaddr=%d, phyid=%08x\n",addr, phy_id); ++ ++ if(phy_id == 0x4f51e91b) ++ { ++ printk (KERN_INFO "yzhang..get YT8511, abt to set 125m clk out, phyaddr=%d, phyid=%08x\n",addr, phy_id); ++ r = yt8511_config_out_125m(bus, addr); ++ printk (KERN_INFO "yzhang..8511 set 125m clk out, reg=%#04x\n",bus->read(bus,addr,0x1f)/*double check as delay*/); ++ if (r<0) ++ { ++ printk (KERN_INFO "yzhang..failed to set 125m clk out, ret=%d\n",r); ++ } ++ } ++ + return phy_device_create(bus, addr, phy_id, is_c45, &c45_ids); + } + EXPORT_SYMBOL(get_phy_device); +--- /dev/null ++++ b/drivers/net/phy/yt8614-phy.h +@@ -0,0 +1,491 @@ ++#ifndef _PHY_H_ ++#define _PHY_H_ ++ ++ ++/* configuration for driver */ ++ ++#define YT8614_MAX_LPORT_ID 3 ++ ++#define YT8614_PHY_MODE_FIBER 1 //fiber mode only ++#define YT8614_PHY_MODE_UTP 2 //utp mode only ++#define YT8614_PHY_MODE_POLL 3 //fiber and utp, poll mode ++ ++/* please make choice according to system design ++ * for Fiber only system, please define YT8614_PHY_MODE_CURR 1 ++ * for UTP only system, please define YT8614_PHY_MODE_CURR 2 ++ * for combo system, please define YT8614_PHY_MODE_CURR 3 ++ */ ++#define YT8614_PHY_MODE_CURR 3 ++ ++ ++ ++/* pls dont modify below lines */ ++ ++#define PHY_ID_YT8614 0x4F51E899 //serdes ++#define MOTORCOMM_MPHY_ID_MASK_8614 0xffffffff ++ ++#ifndef BOOL ++#define BOOL unsigned int ++#endif ++ ++#ifndef FALSE ++#define FALSE 0 ++#endif ++ ++#ifndef TRUE ++#define TRUE 1 ++#endif ++ ++#ifndef SPEED_1000M ++#define SPEED_1000M 2 ++#endif ++#ifndef SPEED_100M ++#define SPEED_100M 1 ++#endif ++#ifndef SPEED_10M ++#define SPEED_10M 0 ++#endif ++ ++#ifndef SPEED_UNKNOWN ++#define SPEED_UNKNOWN 0xffff ++#endif ++ ++#ifndef DUPLEX_FULL ++#define DUPLEX_FULL 1 ++#endif ++#ifndef DUPLEX_HALF ++#define DUPLEX_HALF 0 ++#endif ++ ++#ifndef BIT ++#define BIT(n) (0x1<<(n)) ++#endif ++#ifndef s32 ++typedef int s32; ++typedef unsigned int u32; ++typedef unsigned short u16; ++typedef unsigned char u8; ++#endif ++ ++#ifndef REG_PHY_SPEC_STATUS ++#define REG_PHY_SPEC_STATUS 0x11 ++#define REG_DEBUG_ADDR_OFFSET 0x1e ++#define REG_DEBUG_DATA 0x1f ++#endif ++ ++/**********YT8614************************************************/ ++ ++#define YT8614_SMI_SEL_PHY 0x0 ++#define YT8614_SMI_SEL_SDS_QSGMII 0x02 ++#define YT8614_SMI_SEL_SDS_SGMII 0x03 ++ ++/* yt8614 register type */ ++#define YT8614_TYPE_COMMON 0x01 ++#define YT8614_TYPE_UTP_MII 0x02 ++#define YT8614_TYPE_UTP_EXT 0x03 ++#define YT8614_TYPE_LDS_MII 0x04 ++#define YT8614_TYPE_UTP_MMD 0x05 ++#define YT8614_TYPE_SDS_QSGMII_MII 0x06 ++#define YT8614_TYPE_SDS_SGMII_MII 0x07 ++#define YT8614_TYPE_SDS_QSGMII_EXT 0x08 ++#define YT8614_TYPE_SDS_SGMII_EXT 0x09 ++ ++/* YT8614 extended common register */ ++#define YT8614_REG_COM_SMI_MUX 0xA000 ++#define YT8614_REG_COM_SLED_CFG0 0xA001 ++#define YT8614_REG_COM_PHY_ID 0xA002 ++#define YT8614_REG_COM_CHIP_VER 0xA003 ++#define YT8614_REG_COM_SLED_CFG 0xA004 ++#define YT8614_REG_COM_MODE_CHG_RESET 0xA005 ++#define YT8614_REG_COM_SYNCE0_CFG 0xA006 ++#define YT8614_REG_COM_CHIP_MODE 0xA007 ++ ++#define YT8614_REG_COM_HIDE_SPEED 0xA009 ++ ++#define YT8614_REG_COM_SYNCE1_CFG 0xA00E ++ ++#define YT8614_REG_COM_HIDE_FIBER_MODE 0xA019 ++ ++ ++#define YT8614_REG_COM_HIDE_SEL1 0xA054 ++#define YT8614_REG_COM_HIDE_LED_CFG2 0xB8 ++#define YT8614_REG_COM_HIDE_LED_CFG3 0xB9 ++#define YT8614_REG_COM_HIDE_LED_CFG5 0xBB ++ ++#define YT8614_REG_COM_HIDE_LED_CFG4 0xBA //not used currently ++ ++#if 0 ++#define YT8614_REG_COM_HIDE_LED12_CFG 0xA060 //not used currently ++#define YT8614_REG_COM_HIDE_LED13_CFG 0xA061 ++#define YT8614_REG_COM_HIDE_LED14_CFG 0xA062 ++#define YT8614_REG_COM_HIDE_LED15_CFG 0xA063 ++#define YT8614_REG_COM_HIDE_LED16_CFG 0xA064 ++#define YT8614_REG_COM_HIDE_LED17_CFG 0xA065 ++#define YT8614_REG_COM_HIDE_LED18_CFG 0xA066 ++#define YT8614_REG_COM_HIDE_LED19_CFG 0xA067 ++#define YT8614_REG_COM_HIDE_LED20_CFG 0xA068 ++#define YT8614_REG_COM_HIDE_LED21_CFG 0xA069 ++#define YT8614_REG_COM_HIDE_LED22_CFG 0xA06A ++#define YT8614_REG_COM_HIDE_LED23_CFG 0xA06B ++#define YT8614_REG_COM_HIDE_LED24_CFG 0xA06C ++#define YT8614_REG_COM_HIDE_LED25_CFG 0xA06D ++#define YT8614_REG_COM_HIDE_LED26_CFG 0xA06E ++#define YT8614_REG_COM_HIDE_LED27_CFG 0xA06F ++#endif ++ ++#define YT8614_REG_COM_HIDE_LED28_CFG 0xA070 ++#define YT8614_REG_COM_HIDE_LED29_CFG 0xA071 ++#define YT8614_REG_COM_HIDE_LED30_CFG 0xA072 ++#define YT8614_REG_COM_HIDE_LED31_CFG 0xA073 ++#define YT8614_REG_COM_HIDE_LED32_CFG 0xA074 ++#define YT8614_REG_COM_HIDE_LED33_CFG 0xA075 ++#define YT8614_REG_COM_HIDE_LED34_CFG 0xA076 ++#define YT8614_REG_COM_HIDE_LED35_CFG 0xA077 ++ ++#define YT8614_REG_COM_PKG_CFG0 0xA0A0 ++#define YT8614_REG_COM_PKG_CFG1 0xA0A1 ++#define YT8614_REG_COM_PKG_CFG2 0xA0A2 ++#define YT8614_REG_COM_PKG_RX_VALID0 0xA0A3 ++#define YT8614_REG_COM_PKG_RX_VALID1 0xA0A4 ++#define YT8614_REG_COM_PKG_RX_OS0 0xA0A5 ++#define YT8614_REG_COM_PKG_RX_OS1 0xA0A6 ++#define YT8614_REG_COM_PKG_RX_US0 0xA0A7 ++#define YT8614_REG_COM_PKG_RX_US1 0xA0A8 ++#define YT8614_REG_COM_PKG_RX_ERR 0xA0A9 ++#define YT8614_REG_COM_PKG_RX_OS_BAD 0xA0AA ++#define YT8614_REG_COM_PKG_RX_FRAG 0xA0AB ++#define YT8614_REG_COM_PKG_RX_NOSFD 0xA0AC ++#define YT8614_REG_COM_PKG_TX_VALID0 0xA0AD ++#define YT8614_REG_COM_PKG_TX_VALID1 0xA0AE ++#define YT8614_REG_COM_PKG_TX_OS0 0xA0AF ++ ++#define YT8614_REG_COM_PKG_TX_OS1 0xA0B0 ++#define YT8614_REG_COM_PKG_TX_US0 0xA0B1 ++#define YT8614_REG_COM_PKG_TX_US1 0xA0B2 ++#define YT8614_REG_COM_PKG_TX_ERR 0xA0B3 ++#define YT8614_REG_COM_PKG_TX_OS_BAD 0xA0B4 ++#define YT8614_REG_COM_PKG_TX_FRAG 0xA0B5 ++#define YT8614_REG_COM_PKG_TX_NOSFD 0xA0B6 ++#define YT8614_REG_COM_PKG_CFG3 0xA0B7 ++#define YT8614_REG_COM_PKG_AZ_CFG 0xA0B8 ++#define YT8614_REG_COM_PKG_DA_SA_CFG3 0xA0B9 ++ ++#define YT8614_REG_COM_MANU_HW_RESET 0xA0C0 ++ ++/* YT8614 UTP MII register: same as generic phy register definitions */ ++#define REG_MII_BMCR 0x00 /* Basic mode control register */ ++#define REG_MII_BMSR 0x01 /* Basic mode status register */ ++#define REG_MII_PHYSID1 0x02 /* PHYS ID 1 */ ++#define REG_MII_PHYSID2 0x03 /* PHYS ID 2 */ ++#define REG_MII_ADVERTISE 0x04 /* Advertisement control reg */ ++#define REG_MII_LPA 0x05 /* Link partner ability reg */ ++#define REG_MII_EXPANSION 0x06 /* Expansion register */ ++#define REG_MII_NEXT_PAGE 0x07 /* Next page register */ ++#define REG_MII_LPR_NEXT_PAGE 0x08 /* LPR next page register */ ++#define REG_MII_CTRL1000 0x09 /* 1000BASE-T control */ ++#define REG_MII_STAT1000 0x0A /* 1000BASE-T status */ ++ ++#define REG_MII_MMD_CTRL 0x0D /* MMD access control register */ ++#define REG_MII_MMD_DATA 0x0E /* MMD access data register */ ++ ++#define REG_MII_ESTATUS 0x0F /* Extended Status */ ++#define REG_MII_SPEC_CTRL 0x10 /* PHY specific func control */ ++#define REG_MII_SPEC_STATUS 0x11 /* PHY specific status */ ++#define REG_MII_INT_MASK 0x12 /* Interrupt mask register */ ++#define REG_MII_INT_STATUS 0x13 /* Interrupt status register */ ++#define REG_MII_DOWNG_CTRL 0x14 /* Speed auto downgrade control*/ ++#define REG_MII_RERRCOUNTER 0x15 /* Receive error counter */ ++ ++#define REG_MII_EXT_ADDR 0x1E /* Extended reg's address */ ++#define REG_MII_EXT_DATA 0x1F /* Extended reg's date */ ++ ++#ifndef MII_BMSR ++#define MII_BMSR REG_MII_BMSR ++#endif ++ ++#ifndef YT8614_SPEED_MODE_BIT ++#define YT8614_SPEED_MODE 0xc000 ++#define YT8614_DUPLEX 0x2000 ++#define YT8614_SPEED_MODE_BIT 14 ++#define YT8614_DUPLEX_BIT 13 ++#define YT8614_LINK_STATUS_BIT 10 ++ ++#endif ++ ++#define YT8614_REG_COM_HIDE_SPEED_CMB_PRI 0x2000 ++ ++/* YT8614 UTP MMD register */ ++#define YT8614_REG_UTP_MMD_CTRL1 0x00 /* PCS control 1 register */ ++#define YT8614_REG_UTP_MMD_STATUS1 0x01 /* PCS status 1 register */ ++#define YT8614_REG_UTP_MMD_EEE_CTRL 0x14 /* EEE control and capability */ ++#define YT8614_REG_UTP_MMD_EEE_WK_ERR_CNT 0x16 /* EEE wake error counter */ ++#define YT8614_REG_UTP_MMD_EEE_LOCAL_ABI 0x3C /* local device EEE ability */ ++#define YT8614_REG_UTP_MMD_EEE_LP_ABI 0x3D /* link partner EEE ability */ ++#define YT8614_REG_UTP_MMD_EEE_AUTONEG_RES 0x8000 /* autoneg result of EEE */ ++ ++/* YT8614 UTP EXT register */ ++#define YT8614_REG_UTP_EXT_LPBK 0x0A ++#define YT8614_REG_UTP_EXT_SLEEP_CTRL1 0x27 ++#define YT8614_REG_UTP_EXT_DEBUG_MON1 0x5A ++#define YT8614_REG_UTP_EXT_DEBUG_MON2 0x5B ++#define YT8614_REG_UTP_EXT_DEBUG_MON3 0x5C ++#define YT8614_REG_UTP_EXT_DEBUG_MON4 0x5D ++ ++/* YT8614 SDS(1.25G/5G) MII register: same as YT8521S */ ++#define REG_SDS_BMCR 0x00 /* Basic mode control register */ ++#define REG_SDS_BMSR 0x01 /* Basic mode status register */ ++#define REG_SDS_PHYSID1 0x02 /* PHYS ID 1 */ ++#define REG_SDS_PHYSID2 0x03 /* PHYS ID 2 */ ++#define REG_SDS_ADVERTISE 0x04 /* Advertisement control reg */ ++#define REG_SDS_LPA 0x05 /* Link partner ability reg */ ++#define REG_SDS_EXPANSION 0x06 /* Expansion register */ ++#define REG_SDS_NEXT_PAGE 0x07 /* Next page register */ ++#define REG_SDS_LPR_NEXT_PAGE 0x08 /* LPR next page register */ ++ ++#define REG_SDS_ESTATUS 0x0F /* Extended Status */ ++#define REG_SDS_SPEC_STATUS 0x11 /* SDS specific status */ ++ ++#define REG_SDS_100FX_CFG 0x14 /* 100fx cfg */ ++#define REG_SDS_RERRCOUNTER 0x15 /* Receive error counter */ ++#define REG_SDS_LINT_FAIL_CNT 0x16 /* Lint fail counter mon */ ++ ++/* YT8614 SDS(5G) EXT register */ ++#define YT8614_REG_QSGMII_EXT_ANA_DIG_CFG 0x02 /* sds analog digital interface cfg */ ++#define YT8614_REG_QSGMII_EXT_PRBS_CFG1 0x05 /* sds prbs cfg1 */ ++#define YT8614_REG_QSGMII_EXT_PRBS_CFG2_1 0x06 /* sds prbs cfg2 */ ++#define YT8614_REG_QSGMII_EXT_PRBS_CFG2_2 0x07 /* sds prbs cfg2 */ ++#define YT8614_REG_QSGMII_EXT_PRBS_MON1 0x08 /* sds prbs mon1 */ ++#define YT8614_REG_QSGMII_EXT_PRBS_MON2 0x09 /* sds prbs mon2 */ ++#define YT8614_REG_QSGMII_EXT_PRBS_MON3 0x0A /* sds prbs mon3 */ ++#define YT8614_REG_QSGMII_EXT_PRBS_MON4 0x0B /* sds prbs mon4 */ ++#define YT8614_REG_QSGMII_EXT_PRBS_MON5 0x0C /* sds prbs mon5 */ ++#define YT8614_REG_QSGMII_EXT_ANA_CFG2 0xA1 /* Analog cfg2 */ ++ ++/* YT8614 SDS(1.25G) EXT register */ ++#define YT8614_REG_SGMII_EXT_PRBS_CFG1 0x05 /* sds prbs cfg1 */ ++#define YT8614_REG_SGMII_EXT_PRBS_CFG2 0x06 /* sds prbs cfg2 */ ++#define YT8614_REG_SGMII_EXT_PRBS_MON1 0x08 /* sds prbs mon1 */ ++#define YT8614_REG_SGMII_EXT_PRBS_MON2 0x09 /* sds prbs mon2 */ ++#define YT8614_REG_SGMII_EXT_PRBS_MON3 0x0A /* sds prbs mon3 */ ++#define YT8614_REG_SGMII_EXT_PRBS_MON4 0x0B /* sds prbs mon4 */ ++#define YT8614_REG_SGMII_EXT_PRBS_MON5 0x0C /* sds prbs mon5 */ ++#define YT8614_REG_SGMII_EXT_ANA_CFG2 0xA1 /* Analog cfg2 */ ++#define YT8614_REG_SGMII_EXT_HIDE_AUTO_SEN 0xA5 /* Fiber auto sensing */ ++ ++//////////////////////////////////////////////////////////////////// ++#define YT8614_MMD_DEV_ADDR1 0x1 ++#define YT8614_MMD_DEV_ADDR3 0x3 ++#define YT8614_MMD_DEV_ADDR7 0x7 ++#define YT8614_MMD_DEV_ADDR_NONE 0xFF ++ ++/**********YT8521S************************************************/ ++/* Basic mode control register(0x00) */ ++#define BMCR_RESV 0x003f /* Unused... */ ++#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */ ++#define BMCR_CTST 0x0080 /* Collision test */ ++#define BMCR_FULLDPLX 0x0100 /* Full duplex */ ++#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */ ++#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */ ++#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */ ++#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */ ++#define BMCR_SPEED100 0x2000 /* Select 100Mbps */ ++#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */ ++#define BMCR_RESET 0x8000 /* Reset the DP83840 */ ++ ++/* Basic mode status register(0x01) */ ++#define BMSR_ERCAP 0x0001 /* Ext-reg capability */ ++#define BMSR_JCD 0x0002 /* Jabber detected */ ++#define BMSR_LSTATUS 0x0004 /* Link status */ ++#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */ ++#define BMSR_RFAULT 0x0010 /* Remote fault detected */ ++#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */ ++#define BMSR_RESV 0x00c0 /* Unused... */ ++#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */ ++#define BMSR_100HALF2 0x0200 /* Can do 100BASE-T2 HDX */ ++#define BMSR_100FULL2 0x0400 /* Can do 100BASE-T2 FDX */ ++#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */ ++#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */ ++#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */ ++#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */ ++#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */ ++ ++/* Advertisement control register(0x04) */ ++#define ADVERTISE_SLCT 0x001f /* Selector bits */ ++#define ADVERTISE_CSMA 0x0001 /* Only selector supported */ ++#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */ ++#define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */ ++#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */ ++#define ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */ ++#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */ ++#define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */ ++#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */ ++#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */ ++#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */ ++#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */ ++#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */ ++#define ADVERTISE_RESV 0x1000 /* Unused... */ ++#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */ ++#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */ ++#define ADVERTISE_NPAGE 0x8000 /* Next page bit */ ++ ++#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | ADVERTISE_CSMA) ++#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \ ++ ADVERTISE_100HALF | ADVERTISE_100FULL) ++ ++/* Link partner ability register(0x05) */ ++#define LPA_SLCT 0x001f /* Same as advertise selector */ ++#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */ ++#define LPA_1000XFULL 0x0020 /* Can do 1000BASE-X full-duplex */ ++#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */ ++#define LPA_1000XHALF 0x0040 /* Can do 1000BASE-X half-duplex */ ++#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */ ++#define LPA_1000XPAUSE 0x0080 /* Can do 1000BASE-X pause */ ++#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */ ++#define LPA_1000XPAUSE_ASYM 0x0100 /* Can do 1000BASE-X pause asym */ ++#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */ ++#define LPA_PAUSE_CAP 0x0400 /* Can pause */ ++#define LPA_PAUSE_ASYM 0x0800 /* Can pause asymetrically */ ++#define LPA_RESV 0x1000 /* Unused... */ ++#define LPA_RFAULT 0x2000 /* Link partner faulted */ ++#define LPA_LPACK 0x4000 /* Link partner acked us */ ++#define LPA_NPAGE 0x8000 /* Next page bit */ ++ ++/* 1000BASE-T Control register(0x09) */ ++#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */ ++#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */ ++#define CTL1000_AS_MASTER 0x0800 ++#define CTL1000_ENABLE_MASTER 0x1000 ++ ++/* 1000BASE-T Status register(0x0A) */ ++#define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */ ++#define LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */ ++#define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */ ++#define LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */ ++ ++/**********YT8614************************************************/ ++/* Basic mode control register(0x00) */ ++#define FIBER_BMCR_RESV 0x001f /* b[4:0] Unused... */ ++#define FIBER_BMCR_EN_UNIDIR 0x0020 /* b[5] Valid when bit 0.12 is zero and bit 0.8 is one */ ++#define FIBER_BMCR_SPEED1000 0x0040 /* b[6] MSB of Speed (1000) */ ++#define FIBER_BMCR_CTST 0x0080 /* b[7] Collision test */ ++#define FIBER_BMCR_DUPLEX_MODE 0x0100 /* b[8] Duplex mode */ ++#define FIBER_BMCR_ANRESTART 0x0200 /* b[9] Auto negotiation restart */ ++#define FIBER_BMCR_ISOLATE 0x0400 /* b[10] Isolate phy from RGMII/SGMII/FIBER */ ++#define FIBER_BMCR_PDOWN 0x0800 /* b[11] 1: Power down */ ++#define FIBER_BMCR_ANENABLE 0x1000 /* b[12] Enable auto negotiation */ ++#define FIBER_BMCR_SPEED100 0x2000 /* b[13] LSB of Speed (100) */ ++#define FIBER_BMCR_LOOPBACK 0x4000 /* b[14] Internal loopback control */ ++#define FIBER_BMCR_RESET 0x8000 /* b[15] PHY Software Reset(self-clear) */ ++ ++/* Sds specific status register(0x11) */ ++#define FIBER_SSR_ERCAP 0x0001 /* b[0] realtime syncstatus */ ++#define FIBER_SSR_XMIT 0x000E /* b[3:1] realtime transmit statemachine. ++ 001: Xmit Idle; ++ 010: Xmit Config; ++ 100: Xmit Data. */ ++#define FIBER_SSR_SER_MODE_CFG 0x0030 /* b[5:4] realtime serdes working mode. ++ 00: SG_MAC; ++ 01: SG_PHY; ++ 10: FIB_1000; ++ 11: FIB_100. */ ++#define FIBER_SSR_EN_FLOWCTRL_TX 0x0040 /* b[6] realtime en_flowctrl_tx */ ++#define FIBER_SSR_EN_FLOWCTRL_RX 0x0080 /* b[7] realtime en_flowctrl_rx */ ++#define FIBER_SSR_DUPLEX_ERROR 0x0100 /* b[8] realtime deplex error */ ++#define FIBER_SSR_RX_LPI_ACTIVE 0x0200 /* b[9] rx lpi is active */ ++#define FIBER_SSR_LSTATUS 0x0400 /* b[10] Link status real-time */ ++#define FIBER_SSR_PAUSE 0x1800 /* b[12:11] Pause to mac */ ++#define FIBER_SSR_DUPLEX 0x2000 /* b[13] This status bit is valid only when bit10 is 1. ++ 1: full duplex ++ 0: half duplex */ ++#define FIBER_SSR_SPEED_MODE 0xC000 /* b[15:14] These status bits are valid only when bit10 is 1. ++ 10---1000M ++ 01---100M */ ++ ++/* SLED cfg0 (ext 0xA001) */ ++#define FIBER_SLED_CFG0_EN_CTRL 0x00FF /* b[7:0] Control to enable the eight ports' SLED */ ++#define FIBER_SLED_CFG0_BIT_MASK 0x0700 /* b[10:8] 1: enable the pin output */ ++#define FIBER_SLED_CFG0_ACT_LOW 0x0800 /* b[11] control SLED's polarity. 1: active low; 0: active high */ ++#define FIBER_SLED_CFG0_MANU_ST 0x7000 /* b[14:12] SLEDs' manul status, corresponding to each port's 3 SLEDs */ ++#define FIBER_SLED_CFG0_MANU_EN 0x8000 /* b[15] to control serial LEDs status manually */ ++ ++/**********YT8614************************************************/ ++/* Fiber auto sensing(sgmii ext 0xA5) */ ++#define FIBER_AUTO_SEN_ENABLE 0x8000 /* b[15] Enable fiber auto sensing */ ++ ++/* Fiber force speed(common ext 0xA009) */ ++#define FIBER_FORCE_1000M 0x0001 /* b[0] 1:1000BX 0:100FX */ ++ ++#ifndef NULL ++#define NULL 0 ++#endif ++ ++/* errno */ ++enum ytphy_8614_errno_e ++{ ++ SYS_E_NONE, ++ SYS_E_PARAM, ++ SYS_E_MAX ++}; ++ ++/* errno */ ++enum ytphy_8614_combo_speed_e ++{ ++ YT8614_COMBO_FIBER_1000M, ++ YT8614_COMBO_FIBER_100M, ++ YT8614_COMBO_UTP_ONLY, ++ YT8614_COMBO_SPEED_MAX ++}; ++ ++/* definition for porting */ ++/* phy registers access */ ++typedef struct ++{ ++ u16 reg; /* the offset of the phy internal address */ ++ u16 val; /* the value of the register */ ++ u8 regType; /* register type */ ++} phy_data_s; ++ ++/* for porting use. ++ * pls over-write member function read/write for mdio access ++ */ ++typedef struct phy_info_str ++{ ++#if 0 ++ struct phy_device *phydev; ++ int mdio_base; ++#endif ++ unsigned int lport; ++ unsigned int bus_id; ++ unsigned int phy_addr; ++ ++ s32 (*read)(struct phy_info_str *info, phy_data_s *param); ++ s32 (*write)(struct phy_info_str *info, phy_data_s *param); ++}phy_info_s; ++ ++/* get phy access method */ ++s32 yt8614_read_reg(struct phy_info_str *info, phy_data_s *param); ++s32 yt8614_write_reg(struct phy_info_str *info, phy_data_s *param); ++s32 yt8614_phy_soft_reset(u32 lport); ++s32 yt8614_phy_init(u32 lport); ++s32 yt8614_fiber_enable(u32 lport, BOOL enable); ++s32 yt8614_utp_enable(u32 lport, BOOL enable); ++s32 yt8614_fiber_unidirection_set(u32 lport, int speed, BOOL enable); ++s32 yt8614_fiber_autosensing_set(u32 lport, BOOL enable); ++s32 yt8614_fiber_speed_set(u32 lport, int fiber_speed); ++s32 yt8614_qsgmii_autoneg_set(u32 lport, BOOL enable); ++s32 yt8614_sgmii_autoneg_set(u32 lport, BOOL enable); ++s32 yt8614_qsgmii_sgmii_link_status_get(u32 lport, BOOL *enable, BOOL if_qsgmii); ++int yt8614_combo_media_priority_set (u32 lport, int fiber); ++int yt8614_combo_media_priority_get (u32 lport, int *fiber); ++s32 yt8614_utp_autoneg_set(u32 lport, BOOL enable); ++s32 yt8614_utp_autoneg_get(u32 lport, BOOL *enable); ++s32 yt8614_utp_autoneg_ability_set(u32 lport, unsigned int cap_mask); ++s32 yt8614_utp_autoneg_ability_get(u32 lport, unsigned int *cap_mask); ++s32 yt8614_utp_force_duplex_set(u32 lport, BOOL full); ++s32 yt8614_utp_force_duplex_get(u32 lport, BOOL *full); ++s32 yt8614_utp_force_speed_set(u32 lport, unsigned int speed); ++s32 yt8614_utp_force_speed_get(u32 lport, unsigned int *speed); ++int yt8614_autoneg_done_get (u32 lport, int speed, int *aneg); ++int yt8614_media_status_get(u32 lport, int* speed, int* duplex, int* ret_link, int *media); ++ ++#endif --- /dev/null +++ b/include/linux/motorcomm_phy.h -@@ -0,0 +1,67 @@ +@@ -0,0 +1,119 @@ +/* + * include/linux/motorcomm_phy.h + * @@ -404,6 +2201,8 @@ Signed-off-by: hmz007 +#define _MOTORCOMM_PHY_H + +#define MOTORCOMM_PHY_ID_MASK 0x00000fff ++#define MOTORCOMM_PHY_ID_8531_MASK 0xffffffff ++#define MOTORCOMM_MPHY_ID_MASK 0x0000ffff + +#define PHY_ID_YT8010 0x00000309 +#define PHY_ID_YT8510 0x00000109 @@ -411,10 +2210,12 @@ Signed-off-by: hmz007 +#define PHY_ID_YT8512 0x00000118 +#define PHY_ID_YT8512B 0x00000128 +#define PHY_ID_YT8521 0x0000011a ++#define PHY_ID_YT8531S 0x4f51e91a ++#define PHY_ID_YT8531 0x4f51e91b ++//#define PHY_ID_YT8614 0x0000e899 ++#define PHY_ID_YT8618 0x0000e889 + +#define REG_PHY_SPEC_STATUS 0x11 -+#define REG_INT_MASK 0x12 -+#define REG_INT_STATUS 0x13 +#define REG_DEBUG_ADDR_OFFSET 0x1e +#define REG_DEBUG_DATA 0x1f + @@ -454,4 +2255,54 @@ Signed-off-by: hmz007 +#define YT8521_DUPLEX_BIT 13 +#define YT8521_LINK_STATUS_BIT 10 + ++/* based on yt8521 wol config register */ ++#define YTPHY_UTP_INTR_REG 0x12 ++/* WOL Event Interrupt Enable */ ++#define YTPHY_WOL_INTR BIT(6) ++ ++/* Magic Packet MAC address registers */ ++#define YTPHY_MAGIC_PACKET_MAC_ADDR2 0xa007 ++#define YTPHY_MAGIC_PACKET_MAC_ADDR1 0xa008 ++#define YTPHY_MAGIC_PACKET_MAC_ADDR0 0xa009 ++ ++#define YTPHY_WOL_CFG_REG 0xa00a ++#define YTPHY_WOL_CFG_TYPE BIT(0) /* WOL TYPE */ ++#define YTPHY_WOL_CFG_EN BIT(3) /* WOL Enable */ ++#define YTPHY_WOL_CFG_INTR_SEL BIT(6) /* WOL Event Interrupt Enable */ ++#define YTPHY_WOL_CFG_WIDTH1 BIT(1) /* WOL Pulse Width */ ++#define YTPHY_WOL_CFG_WIDTH2 BIT(2) ++ ++#define YTPHY_REG_SPACE_UTP 0 ++#define YTPHY_REG_SPACE_FIBER 2 ++ ++enum ytphy_wol_type_e ++{ ++ YTPHY_WOL_TYPE_LEVEL, ++ YTPHY_WOL_TYPE_PULSE, ++ YTPHY_WOL_TYPE_MAX ++}; ++typedef enum ytphy_wol_type_e ytphy_wol_type_t; ++ ++enum ytphy_wol_width_e ++{ ++ YTPHY_WOL_WIDTH_84MS, ++ YTPHY_WOL_WIDTH_168MS, ++ YTPHY_WOL_WIDTH_336MS, ++ YTPHY_WOL_WIDTH_672MS, ++ YTPHY_WOL_WIDTH_MAX ++}; ++typedef enum ytphy_wol_width_e ytphy_wol_width_t; ++ ++struct ytphy_wol_cfg_s ++{ ++ int enable; ++ int type; ++ int width; ++}; ++typedef struct ytphy_wol_cfg_s ytphy_wol_cfg_t; ++ +#endif /* _MOTORCOMM_PHY_H */ ++ ++ +-- +2.25.1