summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml187
-rw-r--r--Documentation/devicetree/bindings/net/micrel-ksz90x1.txt41
-rw-r--r--arch/arm/configs/apalis_imx6_android_defconfig17
-rw-r--r--arch/arm/configs/colibri-imx6ull_defconfig3
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c37
-rw-r--r--drivers/net/phy/micrel.c169
-rw-r--r--include/linux/micrel_phy.h1
7 files changed, 379 insertions, 76 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 6a8826b5166a..3e43a2df5cae 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,89 +1,136 @@
-image: $CI_IMAGE
-
variables:
-# uncomment for the pipeline debug purpose
+# uncomment for the pipeline debug purpose
# CI_DEBUG_TRACE: "true"
- CI_IMAGE: gitlab.int.toradex.com:4567/yuiry.erofeev/linux-toradex/ci-kernel-builder
DOCKER_HOST: tcp://docker:2375
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
-
-# Kernel Configuration Section
-# Supplementary Tool Section
- # Artifacts configuring section
- KERNEL_CONFIG_BUILD_LOG_FILE_NAME: build_config.log
- KERNEL_BUILD_LOG_FILE_NAME: build.log
- KERNEL_CONFIGURATION_FILE: .config
- # Defining temporary build folder to do outside of the box builds. Absolute path
- TEMP_BUILD_FOLDER: /builds/temp-builds
+
stages:
- - build-product
+ - build-kernel
-.build_base:
- stage: build-product
+apalis-imx6-kernel:
+ stage: build-kernel
+ image: gitlab.int.toradex.com:4567/rd/linux-bsp/ci-toolchain-container:linux-toradex_aarch32_arm_builder-bb6f84e
variables:
- GIT_STRATEGY: fetch
-# To run just on merge request
-# only:
-# - merge_requests
-# when: manual
- script: |
- #set -o xtrace
- cd $CI_PROJECT_DIR
- echo -e "Compiler used to build binaries is"
+ DEFCONFIG: apalis_imx6_defconfig
+ GIT_STRATEGY: fetch
+ GIT_DEPTH: "1"
+ script: |
+ echo "GCC used to build binaries is"
which ${CROSS_COMPILE}gcc
${CROSS_COMPILE}gcc --version
echo -e "Arch is \e[36m$ARCH\e[39m"
- mkdir -p $TEMP_BUILD_FOLDER
- make O=$TEMP_BUILD_FOLDER $DEFCONFIG | tee $KERNEL_CONFIG_BUILD_LOG_FILE_NAME
- make O=$TEMP_BUILD_FOLDER -j3 2>&1 | tee $KERNEL_BUILD_LOG_FILE_NAME
- # Artifacts should be uploaded from the CI folder, so we should to copy it
- cp $TEMP_BUILD_FOLDER/$KERNEL_CONFIGURATION_FILE $CI_PROJECT_DIR
- #find / -name ".config" -print
- artifacts:
- when: always
- name: "$CI_COMMIT_REF_NAME"
- paths:
- - $KERNEL_CONFIG_BUILD_LOG_FILE_NAME
- - $KERNEL_BUILD_LOG_FILE_NAME
- - $KERNEL_CONFIGURATION_FILE
-# To allow single steps failing without failing the whole pipeline
- # allow_failure: true
- after_script:
- - set -o xtrace
- - rm -rf $TEMP_BUILD_FOLDER
-
-# If you need additional products build just copy-paste build_******_product section with new config name
-build_apalis_product_imx6 :
- extends: .build_base
- variables:
- DEFCONFIG: apalis_imx6_defconfig
- stage: build-product
-
+ echo "Current directory: ${PWD}"
+ THREADS=$(grep processor /proc/cpuinfo -c)
+ echo "building with $THREADS parallel threads"
+ DEVICETREES=$(find arch/arm/boot/dts/ -regextype posix-extended -regex "^.*\/imx.*(apalis|colibri|verdin).*\.dts" | sed 's/arch\/arm\/boot\/dts\///' | sed 's/\.dts/\.dtb/')
+ make $DEFCONFIG
+ echo -e "building: \n$DEVICETREES"
+ make -j$THREADS $DEVICETREES
+ make -j$THREADS
-build_apalis_product_imx6_android :
- extends: .build_base
+apalis-imx6-android_kernel:
+ stage: build-kernel
+ image: gitlab.int.toradex.com:4567/rd/linux-bsp/ci-toolchain-container:linux-toradex_aarch32_arm_builder-bb6f84e
variables:
DEFCONFIG: apalis_imx6_android_defconfig
-# This only stage is set to manual mode because android config is not in the scope of the overall build
- when: manual
- stage: build-product
+ GIT_STRATEGY: fetch
+ GIT_DEPTH: "1"
+ script: |
+ echo "GCC used to build binaries is"
+ which ${CROSS_COMPILE}gcc
+ ${CROSS_COMPILE}gcc --version
+ echo -e "Arch is \e[36m$ARCH\e[39m"
+ echo "Current directory: ${PWD}"
+ THREADS=$(grep processor /proc/cpuinfo -c)
+ echo "building with $THREADS parallel threads"
+ DEVICETREES=$(find arch/arm/boot/dts/ -regextype posix-extended -regex "^.*\/imx.*(apalis|colibri|verdin).*\.dts" | sed 's/arch\/arm\/boot\/dts\///' | sed 's/\.dts/\.dtb/')
+ make $DEFCONFIG
+ echo -e "building: \n$DEVICETREES"
+ make -j$THREADS $DEVICETREES
+ make -j$THREADS
-
-build_colibri_product_imx6 :
- extends: .build_base
+colibri-imx6-kernel:
+ stage: build-kernel
+ image: gitlab.int.toradex.com:4567/rd/linux-bsp/ci-toolchain-container:linux-toradex_aarch32_arm_builder-bb6f84e
variables:
DEFCONFIG: colibri_imx6_defconfig
- stage: build-product
-
-build_colibri_product_imx7 :
- extends: .build_base
+ GIT_STRATEGY: fetch
+ GIT_DEPTH: "1"
+ # Choose max kernel size that `ubinfo /dev/ubi0_0` reports
+ MAX_KERNEL_SIZE_B: 8507392
+ script: |
+ echo "GCC used to build binaries is"
+ which ${CROSS_COMPILE}gcc
+ ${CROSS_COMPILE}gcc --version
+ echo -e "Arch is \e[36m$ARCH\e[39m"
+ echo "Current directory: ${PWD}"
+ THREADS=$(grep processor /proc/cpuinfo -c)
+ echo "building with $THREADS parallel threads"
+ DEVICETREES=$(find arch/arm/boot/dts/ -regextype posix-extended -regex "^.*\/imx.*(apalis|colibri|verdin).*\.dts" | sed 's/arch\/arm\/boot\/dts\///' | sed 's/\.dts/\.dtb/')
+ make $DEFCONFIG
+ echo -e "building: \n$DEVICETREES"
+ make -j$THREADS $DEVICETREES
+ make -j$THREADS
+
+
+colibri-imx6ull-kernel:
+ stage: build-kernel
+ image: gitlab.int.toradex.com:4567/rd/linux-bsp/ci-toolchain-container:linux-toradex_aarch32_arm_builder-bb6f84e
variables:
- DEFCONFIG: colibri_imx7_defconfig
- stage: build-product
-
-build_colibri_product_imx6ull :
- extends: .build_base
+ DEFCONFIG: colibri-imx6ull_defconfig
+ GIT_STRATEGY: fetch
+ GIT_DEPTH: "1"
+ # Choose max kernel size that `ubinfo /dev/ubi0_0` reports
+ MAX_KERNEL_SIZE_B: 8507392
+ script: |
+ echo "GCC used to build binaries is"
+ which ${CROSS_COMPILE}gcc
+ ${CROSS_COMPILE}gcc --version
+ echo -e "Arch is \e[36m$ARCH\e[39m"
+ echo "Current directory: ${PWD}"
+ THREADS=$(grep processor /proc/cpuinfo -c)
+ echo "building with $THREADS parallel threads"
+ DEVICETREES=$(find arch/arm/boot/dts/ -regextype posix-extended -regex "^.*\/imx.*(apalis|colibri|verdin).*\.dts" | sed 's/arch\/arm\/boot\/dts\///' | sed 's/\.dts/\.dtb/')
+ make $DEFCONFIG
+ echo -e "building: \n$DEVICETREES"
+ make -j$THREADS $DEVICETREES
+ make -j$THREADS
+ KERNEL_SIZE=$(ls -la arch/arm/boot/zImage | awk '{print $5}')
+ echo "Kernel size is ${KERNEL_SIZE} bytes"
+ if [ $KERNEL_SIZE -ge $MAX_KERNEL_SIZE_B ];
+ then
+ echo "❌ Kernel exceeds the max size of ${MAX_KERNEL_SIZE_B}, failing CI pipeline";
+ exit 1
+ fi
+
+colibri-imx7-kernel:
+ stage: build-kernel
+ image: gitlab.int.toradex.com:4567/rd/linux-bsp/ci-toolchain-container:linux-toradex_aarch32_arm_builder-bb6f84e
variables:
- DEFCONFIG: colibri-imx6ull_defconfig
- stage: build-product
+ DEFCONFIG: colibri_imx7_defconfig
+ GIT_STRATEGY: fetch
+ GIT_DEPTH: "1"
+ # Choose max kernel size that `ubinfo /dev/ubi0_0` reports
+ MAX_KERNEL_SIZE_B: 8507392
+ script: |
+ echo "GCC used to build binaries is"
+ which ${CROSS_COMPILE}gcc
+ ${CROSS_COMPILE}gcc --version
+ echo -e "Arch is \e[36m$ARCH\e[39m"
+ echo "Current directory: ${PWD}"
+ THREADS=$(grep processor /proc/cpuinfo -c)
+ echo "building with $THREADS parallel threads"
+ DEVICETREES=$(find arch/arm/boot/dts/ -regextype posix-extended -regex "^.*\/imx.*(apalis|colibri|verdin).*\.dts" | sed 's/arch\/arm\/boot\/dts\///' | sed 's/\.dts/\.dtb/')
+ make $DEFCONFIG
+ echo -e "building: \n$DEVICETREES"
+ make -j$THREADS $DEVICETREES
+ make -j$THREADS
+ KERNEL_SIZE=$(ls -la arch/arm/boot/zImage | awk '{print $5}')
+ echo "Kernel size is ${KERNEL_SIZE} bytes"
+ if [ $KERNEL_SIZE -ge $MAX_KERNEL_SIZE_B ];
+ then
+ echo "❌ Kernel exceeds the max size of ${MAX_KERNEL_SIZE_B}, failing CI pipeline";
+ exit 1
+ fi
+
diff --git a/Documentation/devicetree/bindings/net/micrel-ksz90x1.txt b/Documentation/devicetree/bindings/net/micrel-ksz90x1.txt
index c35b5b428a7f..83ae77116c37 100644
--- a/Documentation/devicetree/bindings/net/micrel-ksz90x1.txt
+++ b/Documentation/devicetree/bindings/net/micrel-ksz90x1.txt
@@ -1,4 +1,4 @@
-Micrel KSZ9021/KSZ9031 Gigabit Ethernet PHY
+Micrel KSZ9021/KSZ9031/KSZ9131 Gigabit Ethernet PHY
Some boards require special tuning values, particularly when it comes
to clock delays. You can specify clock delay values in the PHY OF
@@ -57,6 +57,45 @@ KSZ9031:
- txd2-skew-ps : Skew control of TX data 2 pad
- txd3-skew-ps : Skew control of TX data 3 pad
+KSZ9131:
+
+ All skew control options are specified in picoseconds. The increment
+ step is 100ps. Unlike KSZ9031, the values represent picoseccond delays.
+ A negative value can be assigned as rxc-skew-psec = <(-100)>;.
+
+ The KSZ9131 provides additional 2ns delay register for RXC and TXC signals
+ with the RX DLL and TX DLL Control Register. This is a self adjusting delay
+ locked loop that maintains 2ns of delay for either RXC or TXC register.
+
+ Optional properties:
+
+ - rxc-dll-2ns : 1 to enable 2ns dll controlled delay on RXC
+ 0 to disable this delay.
+ If omitted, register will not be touched. The
+ delay is enabled by default by hardware.
+ - txc-dll-2ns : 1 to enable 2ns dll controlled delay on TXC
+ 0 to disable this delay.
+ If omitted, register will not be touched. The
+ delay is disabled by default by hardware.
+
+ Range of the value -700 to 2400, default value 0:
+
+ - rxc-skew-psec : Skew control of RX clock pad
+ - txc-skew-psec : Skew control of TX clock pad
+
+ Range of the value -700 to 800, default value 0:
+
+ - rxdv-skew-psec : Skew control of RX CTL pad
+ - txen-skew-psec : Skew control of TX CTL pad
+ - rxd0-skew-psec : Skew control of RX data 0 pad
+ - rxd1-skew-psec : Skew control of RX data 1 pad
+ - rxd2-skew-psec : Skew control of RX data 2 pad
+ - rxd3-skew-psec : Skew control of RX data 3 pad
+ - txd0-skew-psec : Skew control of TX data 0 pad
+ - txd1-skew-psec : Skew control of TX data 1 pad
+ - txd2-skew-psec : Skew control of TX data 2 pad
+ - txd3-skew-psec : Skew control of TX data 3 pad
+
Examples:
mdio {
diff --git a/arch/arm/configs/apalis_imx6_android_defconfig b/arch/arm/configs/apalis_imx6_android_defconfig
index a0769007aed2..74b32c18dd33 100644
--- a/arch/arm/configs/apalis_imx6_android_defconfig
+++ b/arch/arm/configs/apalis_imx6_android_defconfig
@@ -329,7 +329,7 @@ CONFIG_HAVE_IMX_SRC=y
#
# CONFIG_SOC_IMX53 is not set
CONFIG_SOC_IMX6Q=y
-CONFIG_SOC_IMX6SL=y
+# CONFIG_SOC_IMX6SL is not set
# CONFIG_SOC_VF610 is not set
# CONFIG_ARCH_OMAP2PLUS is not set
# CONFIG_ARCH_SOCFPGA is not set
@@ -419,8 +419,8 @@ CONFIG_PCIE_DW=y
CONFIG_PCI_IMX6=y
CONFIG_PCI_FORCE_GEN1=y
# CONFIG_EP_MODE_IN_EP_RC_SYS is not set
-CONFIG_RC_MODE_IN_EP_RC_SYS=y
-CONFIG_PCI_IMX_EP_DRV=y
+# CONFIG_RC_MODE_IN_EP_RC_SYS is not set
+# CONFIG_PCI_IMX_EP_DRV is not set
# CONFIG_PCCARD is not set
#
@@ -2074,7 +2074,7 @@ CONFIG_PINCONF=y
# CONFIG_DEBUG_PINCTRL is not set
CONFIG_PINCTRL_IMX=y
CONFIG_PINCTRL_IMX6Q=y
-CONFIG_PINCTRL_IMX6SL=y
+# CONFIG_PINCTRL_IMX6SL is not set
# CONFIG_PINCTRL_SINGLE is not set
# CONFIG_PINCTRL_EXYNOS is not set
# CONFIG_PINCTRL_EXYNOS5440 is not set
@@ -3490,6 +3490,15 @@ CONFIG_DMA_OF=y
# CONFIG_VIRT_DRIVERS is not set
#
+# DMABUF options
+#
+CONFIG_SYNC_FILE=y
+# CONFIG_SW_SYNC is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_VIRT_DRIVERS is not set
+
+#
# Virtio drivers
#
# CONFIG_VIRTIO_PCI is not set
diff --git a/arch/arm/configs/colibri-imx6ull_defconfig b/arch/arm/configs/colibri-imx6ull_defconfig
index 898c03f6a736..ecb8d20ac48d 100644
--- a/arch/arm/configs/colibri-imx6ull_defconfig
+++ b/arch/arm/configs/colibri-imx6ull_defconfig
@@ -103,8 +103,11 @@ CONFIG_BT_BNEP=m
CONFIG_BT_BNEP_MC_FILTER=y
CONFIG_BT_BNEP_PROTO_FILTER=y
CONFIG_BT_HIDP=m
+CONFIG_BT_HCIBTSDIO=m
CONFIG_BT_HCIUART=m
CONFIG_BT_HCIUART_LL=y
+CONFIG_BT_MRVL=m
+CONFIG_BT_MRVL_SDIO=m
CONFIG_WIRELESS_EXT=y
CONFIG_WEXT_PRIV=y
CONFIG_RFKILL=y
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index c0e3928d5f73..2eb8ac385e73 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -101,6 +101,14 @@ static void mmd_write_reg(struct phy_device *dev, int device, int reg, int val)
phy_write(dev, 0x0e, val);
}
+static int mmd_read_reg(struct phy_device *dev, int device, int reg)
+{
+ phy_write(dev, 0x0d, device);
+ phy_write(dev, 0x0e, reg);
+ phy_write(dev, 0x0d, (1 << 14) | device);
+ return phy_read(dev, 0x0e);
+}
+
static int ksz9031rn_phy_fixup(struct phy_device *dev)
{
/*
@@ -114,6 +122,33 @@ static int ksz9031rn_phy_fixup(struct phy_device *dev)
return 0;
}
+#define KSZ9131_RXTXDLL_BYPASS 12
+
+static int ksz9131rn_phy_fixup(struct phy_device *dev)
+{
+ int tmp;
+
+ tmp = mmd_read_reg(dev, 2, 0x4c);
+ /* disable rxdll bypass (enable 2ns skew delay on RXC) */
+ tmp &= ~(1 << KSZ9131_RXTXDLL_BYPASS);
+ mmd_write_reg(dev, 2, 0x4c, tmp);
+
+ tmp = mmd_read_reg(dev, 2, 0x4d);
+ /* disable txdll bypass (enable 2ns skew delay on TXC) */
+ tmp &= ~(1 << KSZ9131_RXTXDLL_BYPASS);
+ mmd_write_reg(dev, 2, 0x4d, tmp);
+
+ /*
+ * Subtract ~0.6ns from txdll = ~1.4ns delay.
+ * leave RXC path untouched
+ */
+ mmd_write_reg(dev, 2, 4, 0x007d);
+ mmd_write_reg(dev, 2, 6, 0xdddd);
+ mmd_write_reg(dev, 2, 8, 0x0007);
+
+ return 0;
+}
+
/*
* fixup for PLX PEX8909 bridge to configure GPIO1-7 as output High
* as they are used for slots1-7 PERST#
@@ -219,6 +254,8 @@ static void __init imx6q_enet_phy_init(void)
ksz9021rn_phy_fixup);
phy_register_fixup_for_uid(PHY_ID_KSZ9031, MICREL_PHY_ID_MASK,
ksz9031rn_phy_fixup);
+ phy_register_fixup_for_uid(PHY_ID_KSZ9131, MICREL_PHY_ID_MASK,
+ ksz9131rn_phy_fixup);
phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffef,
ar8031_phy_fixup);
phy_register_fixup_for_uid(PHY_ID_AR8035, 0xffffffef,
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index fe03a3a2c4c2..5d89437b7e0d 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -14,7 +14,7 @@
* option) any later version.
*
* Support : Micrel Phys:
- * Giga phys: ksz9021, ksz9031
+ * Giga phys: ksz9021, ksz9031, ksz9131
* 100/10 Phys : ksz8001, ksz8721, ksz8737, ksz8041
* ksz8021, ksz8031, ksz8051,
* ksz8081, ksz8091,
@@ -592,6 +592,154 @@ static int ksz9031_config_init(struct phy_device *phydev)
return ksz9031_center_flp_timing(phydev);
}
+#define KSZ9131_SKEW_5BIT_MAX 2400
+#define KSZ9131_SKEW_4BIT_MAX 800
+#define KSZ9131_OFFSET 700
+#define KSZ9131_STEP 100
+
+static int ksz9131_of_load_skew_values(struct phy_device *phydev,
+ struct device_node *of_node,
+ u16 reg, size_t field_sz,
+ char *field[], u8 numfields)
+{
+ int val[4] = {-(1 + KSZ9131_OFFSET), -(2 + KSZ9131_OFFSET),
+ -(3 + KSZ9131_OFFSET), -(4 + KSZ9131_OFFSET)};
+ int skewval, skewmax = 0;
+ int matches = 0;
+ u16 maxval;
+ u16 newval;
+ u16 mask;
+ int i;
+
+ /* psec properties in dts should mean x pico seconds */
+ if (field_sz == 5)
+ skewmax = KSZ9131_SKEW_5BIT_MAX;
+ else
+ skewmax = KSZ9131_SKEW_4BIT_MAX;
+
+ for (i = 0; i < numfields; i++)
+ if (!of_property_read_s32(of_node, field[i], &skewval)) {
+ if (skewval < -KSZ9131_OFFSET)
+ skewval = -KSZ9131_OFFSET;
+ else if (skewval > skewmax)
+ skewval = skewmax;
+
+ val[i] = skewval + KSZ9131_OFFSET;
+ matches++;
+ }
+
+ if (!matches)
+ return 0;
+
+ if (matches < numfields)
+ newval = ksz9031_extended_read(phydev, OP_DATA, 2, reg);
+ else
+ newval = 0;
+
+ maxval = (field_sz == 4) ? 0xf : 0x1f;
+ for (i = 0; i < numfields; i++)
+ if (val[i] != -(i + 1 + KSZ9131_OFFSET)) {
+ mask = 0xffff;
+ mask ^= maxval << (field_sz * i);
+ newval = (newval & mask) |
+ (((val[i] / KSZ9131_STEP) & maxval)
+ << (field_sz * i));
+ }
+
+ return ksz9031_extended_write(phydev, OP_DATA, 2, reg, newval);
+}
+
+#define KSZ9131_RX_DLL_CTRL 0x4c
+#define KSZ9131_TX_DLL_CTRL 0x4d
+#define KSZ9131_DLL_CTRL_BYPASS BIT(12)
+
+static int ksz9131_of_load_dll_skew(struct phy_device *phydev,
+ struct device_node *of_node)
+{
+ int ret;
+ u16 tmp;
+ u32 val;
+
+ if (!of_property_read_u32(of_node, "rxc-dll-2ns", &val)) {
+ tmp = phy_read_mmd(phydev, 2, KSZ9131_RX_DLL_CTRL);
+ if (val == 0)
+ tmp |= KSZ9131_DLL_CTRL_BYPASS;
+ if (val == 1)
+ tmp &= ~KSZ9131_DLL_CTRL_BYPASS;
+ ret = phy_write_mmd(phydev, 2, KSZ9131_RX_DLL_CTRL, tmp);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (!of_property_read_u32(of_node, "txc-dll-2ns", &val)) {
+ tmp = phy_read_mmd(phydev, 2, KSZ9131_TX_DLL_CTRL);
+ if (val == 0)
+ tmp |= KSZ9131_DLL_CTRL_BYPASS;
+ if (val == 1)
+ tmp &= ~KSZ9131_DLL_CTRL_BYPASS;
+ ret = phy_write_mmd(phydev, 2, KSZ9131_TX_DLL_CTRL, tmp);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ksz9131_config_init(struct phy_device *phydev)
+{
+ const struct device *dev = &phydev->mdio.dev;
+ struct device_node *of_node = dev->of_node;
+ char *clk_skews[2] = {"rxc-skew-psec", "txc-skew-psec"};
+ char *rx_data_skews[4] = {
+ "rxd0-skew-psec", "rxd1-skew-psec",
+ "rxd2-skew-psec", "rxd3-skew-psec"
+ };
+ char *tx_data_skews[4] = {
+ "txd0-skew-psec", "txd1-skew-psec",
+ "txd2-skew-psec", "txd3-skew-psec"
+ };
+ char *control_skews[2] = {"txen-skew-psec", "rxdv-skew-psec"};
+ const struct device *dev_walker;
+ int ret;
+
+ dev_walker = &phydev->mdio.dev;
+ do {
+ of_node = dev_walker->of_node;
+ dev_walker = dev_walker->parent;
+ } while (!of_node && dev_walker);
+
+ if (!of_node)
+ return 0;
+
+ ksz9131_of_load_dll_skew(phydev, of_node);
+
+ ret = ksz9131_of_load_skew_values(phydev, of_node,
+ MII_KSZ9031RN_CLK_PAD_SKEW, 5,
+ clk_skews, 2);
+ if (ret < 0)
+ return ret;
+
+ ret = ksz9131_of_load_skew_values(phydev, of_node,
+ MII_KSZ9031RN_CONTROL_PAD_SKEW, 4,
+ control_skews, 2);
+ if (ret < 0)
+ return ret;
+
+ ret = ksz9131_of_load_skew_values(phydev, of_node,
+ MII_KSZ9031RN_RX_DATA_PAD_SKEW, 4,
+ rx_data_skews, 4);
+ if (ret < 0)
+ return ret;
+
+ ret = ksz9131_of_load_skew_values(phydev, of_node,
+ MII_KSZ9031RN_TX_DATA_PAD_SKEW, 4,
+ tx_data_skews, 4);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
#define KSZ8873MLL_GLOBAL_CONTROL_4 0x06
#define KSZ8873MLL_GLOBAL_CONTROL_4_DUPLEX BIT(6)
#define KSZ8873MLL_GLOBAL_CONTROL_4_SPEED BIT(4)
@@ -1020,6 +1168,24 @@ static struct phy_driver ksphy_driver[] = {
.suspend = genphy_suspend,
.resume = kszphy_resume,
}, {
+ .phy_id = PHY_ID_KSZ9131,
+ .phy_id_mask = MICREL_PHY_ID_MASK,
+ .name = "Microchip KSZ9131 Gigabit PHY",
+ .features = PHY_GBIT_FEATURES,
+ .flags = PHY_HAS_INTERRUPT,
+ .driver_data = &ksz9021_type,
+ .probe = kszphy_probe,
+ .config_init = ksz9131_config_init,
+ .config_aneg = genphy_config_aneg,
+ .read_status = ksz9031_read_status,
+ .ack_interrupt = kszphy_ack_interrupt,
+ .config_intr = kszphy_config_intr,
+ .get_sset_count = kszphy_get_sset_count,
+ .get_strings = kszphy_get_strings,
+ .get_stats = kszphy_get_stats,
+ .suspend = genphy_suspend,
+ .resume = kszphy_resume,
+}, {
.phy_id = PHY_ID_KSZ8873MLL,
.phy_id_mask = MICREL_PHY_ID_MASK,
.name = "Micrel KSZ8873MLL Switch",
@@ -1063,6 +1229,7 @@ MODULE_LICENSE("GPL");
static struct mdio_device_id __maybe_unused micrel_tbl[] = {
{ PHY_ID_KSZ9021, 0x000ffffe },
{ PHY_ID_KSZ9031, MICREL_PHY_ID_MASK },
+ { PHY_ID_KSZ9131, MICREL_PHY_ID_MASK },
{ PHY_ID_KSZ8001, 0x00fffffc },
{ PHY_ID_KS8737, MICREL_PHY_ID_MASK },
{ PHY_ID_KSZ8021, 0x00ffffff },
diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h
index f541da68d1e7..f6c0c32852f4 100644
--- a/include/linux/micrel_phy.h
+++ b/include/linux/micrel_phy.h
@@ -31,6 +31,7 @@
#define PHY_ID_KSZ8081 0x00221560
#define PHY_ID_KSZ8061 0x00221570
#define PHY_ID_KSZ9031 0x00221620
+#define PHY_ID_KSZ9131 0x00221640
#define PHY_ID_KSZ886X 0x00221430
#define PHY_ID_KSZ8863 0x00221435