summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-bus-pci-devices-pvpanic4
-rw-r--r--Documentation/ABI/testing/sysfs-driver-xdata49
-rw-r--r--Documentation/devicetree/bindings/fpga/fpga-region.txt187
-rw-r--r--Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt24
-rw-r--r--Documentation/devicetree/bindings/nvmem/brcm,nvram.yaml34
-rw-r--r--Documentation/devicetree/bindings/nvmem/mtk-efuse.txt1
-rw-r--r--Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml1
-rw-r--r--Documentation/devicetree/bindings/phy/bcm-ns-usb2-phy.txt21
-rw-r--r--Documentation/devicetree/bindings/phy/bcm-ns-usb2-phy.yaml59
-rw-r--r--Documentation/devicetree/bindings/phy/bcm-ns-usb3-phy.txt34
-rw-r--r--Documentation/devicetree/bindings/phy/bcm-ns-usb3-phy.yaml62
-rw-r--r--Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml3
-rw-r--r--Documentation/devicetree/bindings/phy/marvell,armada-3700-utmi-phy.yaml57
-rw-r--r--Documentation/devicetree/bindings/phy/marvell,armada-cp110-utmi-phy.yaml109
-rw-r--r--Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml13
-rw-r--r--Documentation/devicetree/bindings/phy/mediatek,hdmi-phy.yaml11
-rw-r--r--Documentation/devicetree/bindings/phy/mediatek,tphy.yaml3
-rw-r--r--Documentation/devicetree/bindings/phy/mediatek,ufs-phy.yaml7
-rw-r--r--Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml100
-rw-r--r--Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml17
-rw-r--r--Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml22
-rw-r--r--Documentation/devicetree/bindings/phy/phy-mvebu-utmi.txt38
-rw-r--r--Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml5
-rw-r--r--Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml2
-rw-r--r--Documentation/devicetree/bindings/phy/qcom,qmp-usb3-dp-phy.yaml3
-rw-r--r--Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml1
-rw-r--r--Documentation/devicetree/bindings/phy/ti,phy-j721e-wiz.yaml4
-rw-r--r--Documentation/devicetree/bindings/soundwire/qcom,sdw.txt20
-rw-r--r--Documentation/fpga/dfl.rst26
-rw-r--r--Documentation/misc-devices/dw-xdata-pcie.rst40
-rw-r--r--MAINTAINERS17
-rw-r--r--drivers/android/binder.c198
-rw-r--r--drivers/android/binder_internal.h18
-rw-r--r--drivers/char/applicom.c2
-rw-r--r--drivers/char/lp.c4
-rw-r--r--drivers/char/mwave/tp3780i.c6
-rw-r--r--drivers/char/mwave/tp3780i.h2
-rw-r--r--drivers/char/virtio_console.c23
-rw-r--r--drivers/firmware/google/gsmi.c14
-rw-r--r--drivers/fpga/Kconfig9
-rw-r--r--drivers/fpga/dfl-afu-error.c10
-rw-r--r--drivers/fpga/dfl-afu-main.c35
-rw-r--r--drivers/fpga/dfl-afu.h2
-rw-r--r--drivers/fpga/dfl-pci.c18
-rw-r--r--drivers/fpga/xilinx-pr-decoupler.c45
-rw-r--r--drivers/fpga/xilinx-spi.c24
-rw-r--r--drivers/greybus/es2.c2
-rw-r--r--drivers/hwtracing/coresight/coresight-core.c2
-rw-r--r--drivers/hwtracing/coresight/coresight-etm-perf.c2
-rw-r--r--drivers/hwtracing/coresight/coresight-etm4x-core.c1
-rw-r--r--drivers/misc/Kconfig19
-rw-r--r--drivers/misc/Makefile3
-rw-r--r--drivers/misc/ad525x_dpot.c3
-rw-r--r--drivers/misc/cxl/context.c2
-rw-r--r--drivers/misc/cxl/fault.c2
-rw-r--r--drivers/misc/dw-xdata-pcie.c420
-rw-r--r--drivers/misc/genwqe/card_ddcb.c10
-rw-r--r--drivers/misc/kgdbts.c74
-rw-r--r--drivers/misc/lis3lv02d/lis3lv02d.c27
-rw-r--r--drivers/misc/pvpanic/Kconfig27
-rw-r--r--drivers/misc/pvpanic/Makefile8
-rw-r--r--drivers/misc/pvpanic/pvpanic-mmio.c (renamed from drivers/misc/pvpanic.c)89
-rw-r--r--drivers/misc/pvpanic/pvpanic-pci.c125
-rw-r--r--drivers/misc/pvpanic/pvpanic.c113
-rw-r--r--drivers/misc/pvpanic/pvpanic.h21
-rw-r--r--drivers/misc/sgi-xp/xp_main.c4
-rw-r--r--drivers/misc/sgi-xp/xpc_main.c2
-rw-r--r--drivers/misc/uacce/uacce.c2
-rw-r--r--drivers/misc/vmw_balloon.c11
-rw-r--r--drivers/misc/vmw_vmci/vmci_doorbell.c2
-rw-r--r--drivers/misc/vmw_vmci/vmci_guest.c2
-rw-r--r--drivers/misc/vmw_vmci/vmci_host.c2
-rw-r--r--drivers/most/most_cdev.c6
-rw-r--r--drivers/mux/gpio.c19
-rw-r--r--drivers/nvmem/Kconfig10
-rw-r--r--drivers/nvmem/Makefile2
-rw-r--r--drivers/nvmem/brcm_nvram.c78
-rw-r--r--drivers/nvmem/core.c95
-rw-r--r--drivers/nvmem/qcom-spmi-sdam.c2
-rw-r--r--drivers/nvmem/qfprom.c44
-rw-r--r--drivers/nvmem/snvs_lpgpr.c2
-rw-r--r--drivers/phy/Kconfig1
-rw-r--r--drivers/phy/Makefile1
-rw-r--r--drivers/phy/broadcom/Kconfig2
-rw-r--r--drivers/phy/cadence/Kconfig2
-rw-r--r--drivers/phy/cadence/phy-cadence-sierra.c419
-rw-r--r--drivers/phy/cadence/phy-cadence-torrent.c475
-rw-r--r--drivers/phy/hisilicon/phy-hi6220-usb.c2
-rw-r--r--drivers/phy/hisilicon/phy-hix5hd2-sata.c2
-rw-r--r--drivers/phy/ingenic/phy-ingenic-usb.c4
-rw-r--r--drivers/phy/intel/phy-intel-lgm-combo.c2
-rw-r--r--drivers/phy/marvell/Kconfig12
-rw-r--r--drivers/phy/marvell/Makefile1
-rw-r--r--drivers/phy/marvell/phy-mvebu-cp110-utmi.c384
-rw-r--r--drivers/phy/microchip/Kconfig13
-rw-r--r--drivers/phy/microchip/Makefile6
-rw-r--r--drivers/phy/microchip/sparx5_serdes.c2513
-rw-r--r--drivers/phy/microchip/sparx5_serdes.h136
-rw-r--r--drivers/phy/microchip/sparx5_serdes_regs.h2695
-rw-r--r--drivers/phy/phy-core.c30
-rw-r--r--drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c4
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp.c528
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp.h77
-rw-r--r--drivers/phy/qualcomm/phy-qcom-usb-hs.c1
-rw-r--r--drivers/phy/ralink/phy-mt7621-pci.c6
-rw-r--r--drivers/phy/rockchip/phy-rockchip-typec.c1
-rw-r--r--drivers/phy/st/Kconfig1
-rw-r--r--drivers/phy/st/phy-stm32-usbphyc.c65
-rw-r--r--drivers/phy/ti/phy-j721e-wiz.c449
-rw-r--r--drivers/phy/ti/phy-tusb1210.c27
-rw-r--r--drivers/phy/xilinx/phy-zynqmp.c58
-rw-r--r--drivers/pps/clients/pps-gpio.c108
-rw-r--r--drivers/soundwire/Makefile2
-rw-r--r--drivers/soundwire/bus.c100
-rw-r--r--drivers/soundwire/bus.h2
-rw-r--r--drivers/soundwire/bus_type.c15
-rw-r--r--drivers/soundwire/cadence_master.c16
-rw-r--r--drivers/soundwire/dmi-quirks.c96
-rw-r--r--drivers/soundwire/generic_bandwidth_allocation.c15
-rw-r--r--drivers/soundwire/intel.c24
-rw-r--r--drivers/soundwire/intel_init.c9
-rw-r--r--drivers/soundwire/qcom.c652
-rw-r--r--drivers/soundwire/slave.c9
-rw-r--r--drivers/soundwire/stream.c28
-rw-r--r--drivers/uio/Kconfig17
-rw-r--r--drivers/uio/Makefile1
-rw-r--r--drivers/uio/uio_dfl.c66
-rw-r--r--drivers/virt/acrn/vm.c2
-rw-r--r--drivers/w1/slaves/w1_ds2780.c2
-rw-r--r--drivers/w1/slaves/w1_ds2781.c2
-rw-r--r--drivers/w1/slaves/w1_therm.c7
-rw-r--r--include/dt-bindings/mux/ti-serdes.h5
-rw-r--r--include/dt-bindings/phy/phy-cadence-torrent.h13
-rw-r--r--include/dt-bindings/phy/phy-cadence.h20
-rw-r--r--include/dt-bindings/phy/phy-ti.h21
-rw-r--r--include/linux/nvmem-consumer.h4
-rw-r--r--include/linux/phy/phy.h26
-rw-r--r--include/linux/pps-gpio.h19
-rw-r--r--include/linux/soundwire/sdw.h36
-rw-r--r--include/uapi/linux/android/binder.h20
-rw-r--r--include/uapi/linux/map_to_7segment.h14
-rwxr-xr-xscripts/spdxcheck.py2
142 files changed, 10822 insertions, 1065 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-pci-devices-pvpanic b/Documentation/ABI/testing/sysfs-bus-pci-devices-pvpanic
index 1936f7324155..4ec03cd36357 100644
--- a/Documentation/ABI/testing/sysfs-bus-pci-devices-pvpanic
+++ b/Documentation/ABI/testing/sysfs-bus-pci-devices-pvpanic
@@ -1,4 +1,5 @@
-What: /sys/devices/pci0000:00/*/QEMU0001:00/capability
+What: /sys/devices/pci0000:00/*/QEMU0001:00/capability for MMIO
+ /sys/bus/pci/drivers/pvpanic-pci/0000:00:0*.0/capability for PCI
Date: Jan 2021
Contact: zhenwei pi <pizhenwei@bytedance.com>
Description:
@@ -12,6 +13,7 @@ Description:
https://git.qemu.org/?p=qemu.git;a=blob_plain;f=docs/specs/pvpanic.txt
What: /sys/devices/pci0000:00/*/QEMU0001:00/events
+ /sys/bus/pci/drivers/pvpanic-pci/0000:00:0*.0/events for PCI
Date: Jan 2021
Contact: zhenwei pi <pizhenwei@bytedance.com>
Description:
diff --git a/Documentation/ABI/testing/sysfs-driver-xdata b/Documentation/ABI/testing/sysfs-driver-xdata
new file mode 100644
index 000000000000..f574e8e6dca2
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-xdata
@@ -0,0 +1,49 @@
+What: /sys/class/misc/drivers/dw-xdata-pcie.<device>/write
+Date: April 2021
+KernelVersion: 5.13
+Contact: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
+Description: Allows the user to enable the PCIe traffic generator which
+ will create write TLPs frames - from the Root Complex to the
+ Endpoint direction or to disable the PCIe traffic generator
+ in all directions.
+
+ Write y/1/on to enable, n/0/off to disable
+
+ Usage e.g.
+ echo 1 > /sys/class/misc/dw-xdata-pcie.<device>/write
+ or
+ echo 0 > /sys/class/misc/dw-xdata-pcie.<device>/write
+
+ The user can read the current PCIe link throughput generated
+ through this generator in MB/s.
+
+ Usage e.g.
+ cat /sys/class/misc/dw-xdata-pcie.<device>/write
+ 204
+
+ The file is read and write.
+
+What: /sys/class/misc/dw-xdata-pcie.<device>/read
+Date: April 2021
+KernelVersion: 5.13
+Contact: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
+Description: Allows the user to enable the PCIe traffic generator which
+ will create read TLPs frames - from the Endpoint to the Root
+ Complex direction or to disable the PCIe traffic generator
+ in all directions.
+
+ Write y/1/on to enable, n/0/off to disable
+
+ Usage e.g.
+ echo 1 > /sys/class/misc/dw-xdata-pcie.<device>/read
+ or
+ echo 0 > /sys/class/misc/dw-xdata-pcie.<device>/read
+
+ The user can read the current PCIe link throughput generated
+ through this generator in MB/s.
+
+ Usage e.g.
+ cat /sys/class/misc/dw-xdata-pcie.<device>/read
+ 199
+
+ The file is read and write.
diff --git a/Documentation/devicetree/bindings/fpga/fpga-region.txt b/Documentation/devicetree/bindings/fpga/fpga-region.txt
index e811cf825019..d787d57491a1 100644
--- a/Documentation/devicetree/bindings/fpga/fpga-region.txt
+++ b/Documentation/devicetree/bindings/fpga/fpga-region.txt
@@ -245,36 +245,31 @@ Base tree contains:
Overlay contains:
-/dts-v1/ /plugin/;
-/ {
- fragment@0 {
- target = <&fpga_region0>;
- #address-cells = <1>;
- #size-cells = <1>;
- __overlay__ {
- #address-cells = <1>;
- #size-cells = <1>;
-
- firmware-name = "soc_system.rbf";
- fpga-bridges = <&fpga_bridge1>;
- ranges = <0x20000 0xff200000 0x100000>,
- <0x0 0xc0000000 0x20000000>;
-
- gpio@10040 {
- compatible = "altr,pio-1.0";
- reg = <0x10040 0x20>;
- altr,ngpio = <4>;
- #gpio-cells = <2>;
- clocks = <2>;
- gpio-controller;
- };
-
- onchip-memory {
- device_type = "memory";
- compatible = "altr,onchipmem-15.1";
- reg = <0x0 0x10000>;
- };
- };
+/dts-v1/;
+/plugin/;
+
+&fpga_region0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ firmware-name = "soc_system.rbf";
+ fpga-bridges = <&fpga_bridge1>;
+ ranges = <0x20000 0xff200000 0x100000>,
+ <0x0 0xc0000000 0x20000000>;
+
+ gpio@10040 {
+ compatible = "altr,pio-1.0";
+ reg = <0x10040 0x20>;
+ altr,ngpio = <4>;
+ #gpio-cells = <2>;
+ clocks = <2>;
+ gpio-controller;
+ };
+
+ onchip-memory {
+ device_type = "memory";
+ compatible = "altr,onchipmem-15.1";
+ reg = <0x0 0x10000>;
};
};
@@ -371,25 +366,22 @@ Live Device Tree contains:
};
DT Overlay contains:
-/dts-v1/ /plugin/;
-/ {
-fragment@0 {
- target = <&fpga_region0>;
+
+/dts-v1/;
+/plugin/;
+
+&fpga_region0 {
#address-cells = <1>;
#size-cells = <1>;
- __overlay__ {
- #address-cells = <1>;
- #size-cells = <1>;
- firmware-name = "zynq-gpio.bin";
+ firmware-name = "zynq-gpio.bin";
- gpio1: gpio@40000000 {
- compatible = "xlnx,xps-gpio-1.00.a";
- reg = <0x40000000 0x10000>;
- gpio-controller;
- #gpio-cells = <0x2>;
- xlnx,gpio-width= <0x6>;
- };
+ gpio1: gpio@40000000 {
+ compatible = "xlnx,xps-gpio-1.00.a";
+ reg = <0x40000000 0x10000>;
+ gpio-controller;
+ #gpio-cells = <0x2>;
+ xlnx,gpio-width= <0x6>;
};
};
@@ -402,41 +394,37 @@ This example programs the FPGA to have two regions that can later be partially
configured. Each region has its own bridge in the FPGA fabric.
DT Overlay contains:
-/dts-v1/ /plugin/;
-/ {
- fragment@0 {
- target = <&fpga_region0>;
- #address-cells = <1>;
- #size-cells = <1>;
- __overlay__ {
- #address-cells = <1>;
- #size-cells = <1>;
-
- firmware-name = "base.rbf";
-
- fpga-bridge@4400 {
- compatible = "altr,freeze-bridge-controller";
- reg = <0x4400 0x10>;
-
- fpga_region1: fpga-region1 {
- compatible = "fpga-region";
- #address-cells = <0x1>;
- #size-cells = <0x1>;
- ranges;
- };
- };
-
- fpga-bridge@4420 {
- compatible = "altr,freeze-bridge-controller";
- reg = <0x4420 0x10>;
-
- fpga_region2: fpga-region2 {
- compatible = "fpga-region";
- #address-cells = <0x1>;
- #size-cells = <0x1>;
- ranges;
- };
- };
+
+/dts-v1/;
+/plugin/;
+
+&fpga_region0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ firmware-name = "base.rbf";
+
+ fpga-bridge@4400 {
+ compatible = "altr,freeze-bridge-controller";
+ reg = <0x4400 0x10>;
+
+ fpga_region1: fpga-region1 {
+ compatible = "fpga-region";
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ ranges;
+ };
+ };
+
+ fpga-bridge@4420 {
+ compatible = "altr,freeze-bridge-controller";
+ reg = <0x4420 0x10>;
+
+ fpga_region2: fpga-region2 {
+ compatible = "fpga-region";
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ ranges;
};
};
};
@@ -451,28 +439,23 @@ differences are that the FPGA is partially reconfigured due to the
"partial-fpga-config" boolean and the only bridge that is controlled during
programming is the FPGA based bridge of fpga_region1.
-/dts-v1/ /plugin/;
-/ {
- fragment@0 {
- target = <&fpga_region1>;
- #address-cells = <1>;
- #size-cells = <1>;
- __overlay__ {
- #address-cells = <1>;
- #size-cells = <1>;
-
- firmware-name = "soc_image2.rbf";
- partial-fpga-config;
-
- gpio@10040 {
- compatible = "altr,pio-1.0";
- reg = <0x10040 0x20>;
- clocks = <0x2>;
- altr,ngpio = <0x4>;
- #gpio-cells = <0x2>;
- gpio-controller;
- };
- };
+/dts-v1/;
+/plugin/;
+
+&fpga_region1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ firmware-name = "soc_image2.rbf";
+ partial-fpga-config;
+
+ gpio@10040 {
+ compatible = "altr,pio-1.0";
+ reg = <0x10040 0x20>;
+ clocks = <0x2>;
+ altr,ngpio = <0x4>;
+ #gpio-cells = <0x2>;
+ gpio-controller;
};
};
diff --git a/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt b/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt
index 4284d293fa61..0acdfa6d62a4 100644
--- a/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt
+++ b/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt
@@ -7,13 +7,24 @@ changes from passing through the bridge. The controller can also
couple / enable the bridges which allows traffic to pass through the
bridge normally.
+Xilinx LogiCORE Dynamic Function eXchange(DFX) AXI shutdown manager
+Softcore is compatible with the Xilinx LogiCORE pr-decoupler.
+
+The Dynamic Function eXchange AXI shutdown manager prevents AXI traffic
+from passing through the bridge. The controller safely handles AXI4MM
+and AXI4-Lite interfaces on a Reconfigurable Partition when it is
+undergoing dynamic reconfiguration, preventing the system deadlock
+that can occur if AXI transactions are interrupted by DFX
+
The Driver supports only MMIO handling. A PR region can have multiple
PR Decouplers which can be handled independently or chained via decouple/
decouple_status signals.
Required properties:
- compatible : Should contain "xlnx,pr-decoupler-1.00" followed by
- "xlnx,pr-decoupler"
+ "xlnx,pr-decoupler" or
+ "xlnx,dfx-axi-shutdown-manager-1.00" followed by
+ "xlnx,dfx-axi-shutdown-manager"
- regs : base address and size for decoupler module
- clocks : input clock to IP
- clock-names : should contain "aclk"
@@ -22,6 +33,7 @@ See Documentation/devicetree/bindings/fpga/fpga-region.txt and
Documentation/devicetree/bindings/fpga/fpga-bridge.txt for generic bindings.
Example:
+Partial Reconfig Decoupler:
fpga-bridge@100000450 {
compatible = "xlnx,pr-decoupler-1.00",
"xlnx-pr-decoupler";
@@ -30,3 +42,13 @@ Example:
clock-names = "aclk";
bridge-enable = <0>;
};
+
+Dynamic Function eXchange AXI shutdown manager:
+ fpga-bridge@100000450 {
+ compatible = "xlnx,dfx-axi-shutdown-manager-1.00",
+ "xlnx,dfx-axi-shutdown-manager";
+ regs = <0x10000045 0x10>;
+ clocks = <&clkc 15>;
+ clock-names = "aclk";
+ bridge-enable = <0>;
+ };
diff --git a/Documentation/devicetree/bindings/nvmem/brcm,nvram.yaml b/Documentation/devicetree/bindings/nvmem/brcm,nvram.yaml
new file mode 100644
index 000000000000..58ff6b0bdb1a
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/brcm,nvram.yaml
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/nvmem/brcm,nvram.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom's NVRAM
+
+description: |
+ Broadcom's NVRAM is a structure containing device specific environment
+ variables. It is used for storing device configuration, booting parameters
+ and calibration data.
+
+ NVRAM can be accessed on Broadcom BCM47xx MIPS and Northstar ARM Cortex-A9
+ devices usiong I/O mapped memory.
+
+maintainers:
+ - Rafał Miłecki <rafal@milecki.pl>
+
+allOf:
+ - $ref: "nvmem.yaml#"
+
+properties:
+ compatible:
+ const: brcm,nvram
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ nvram@1eff0000 {
+ compatible = "brcm,nvram";
+ reg = <0x1eff0000 0x10000>;
+ };
diff --git a/Documentation/devicetree/bindings/nvmem/mtk-efuse.txt b/Documentation/devicetree/bindings/nvmem/mtk-efuse.txt
index ef93c3b95424..2f2895b1f06d 100644
--- a/Documentation/devicetree/bindings/nvmem/mtk-efuse.txt
+++ b/Documentation/devicetree/bindings/nvmem/mtk-efuse.txt
@@ -8,6 +8,7 @@ Required properties:
"mediatek,mt7623-efuse", "mediatek,efuse": for MT7623
"mediatek,mt8173-efuse" or "mediatek,efuse": for MT8173
"mediatek,mt8516-efuse", "mediatek,efuse": for MT8516
+ "mediatek,mt8192-efuse", "mediatek,efuse": for MT8192
- reg: Should contain registers location and length
= Data cells =
diff --git a/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml b/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml
index 992777c90a0b..861b205016b1 100644
--- a/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml
+++ b/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml
@@ -24,6 +24,7 @@ properties:
- qcom,msm8998-qfprom
- qcom,qcs404-qfprom
- qcom,sc7180-qfprom
+ - qcom,sc7280-qfprom
- qcom,sdm845-qfprom
- const: qcom,qfprom
diff --git a/Documentation/devicetree/bindings/phy/bcm-ns-usb2-phy.txt b/Documentation/devicetree/bindings/phy/bcm-ns-usb2-phy.txt
deleted file mode 100644
index a7aee9ea8926..000000000000
--- a/Documentation/devicetree/bindings/phy/bcm-ns-usb2-phy.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-Driver for Broadcom Northstar USB 2.0 PHY
-
-Required properties:
-- compatible: brcm,ns-usb2-phy
-- reg: iomem address range of DMU (Device Management Unit)
-- reg-names: "dmu", the only needed & supported reg right now
-- clocks: USB PHY reference clock
-- clock-names: "phy-ref-clk", the only needed & supported clock right now
-
-To initialize USB 2.0 PHY driver needs to setup PLL correctly. To do this it
-requires passing phandle to the USB PHY reference clock.
-
-Example:
- usb2-phy {
- compatible = "brcm,ns-usb2-phy";
- reg = <0x1800c000 0x1000>;
- reg-names = "dmu";
- #phy-cells = <0>;
- clocks = <&genpll BCM_NSP_GENPLL_USB_PHY_REF_CLK>;
- clock-names = "phy-ref-clk";
- };
diff --git a/Documentation/devicetree/bindings/phy/bcm-ns-usb2-phy.yaml b/Documentation/devicetree/bindings/phy/bcm-ns-usb2-phy.yaml
new file mode 100644
index 000000000000..05b4dcd80019
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/bcm-ns-usb2-phy.yaml
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/bcm-ns-usb2-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom Northstar USB 2.0 PHY
+
+description: >
+ To initialize USB 2.0 PHY driver needs to setup PLL correctly.
+ To do this it requires passing phandle to the USB PHY reference clock.
+
+maintainers:
+ - Rafał Miłecki <rafal@milecki.pl>
+
+properties:
+ compatible:
+ const: brcm,ns-usb2-phy
+
+ reg:
+ items:
+ - description: iomem address range of DMU (Device Management Unit)
+
+ reg-names:
+ items:
+ - const: dmu
+
+ clocks:
+ items:
+ - description: USB PHY reference clock
+
+ clock-names:
+ items:
+ - const: phy-ref-clk
+
+ "#phy-cells":
+ const: 0
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - clocks
+ - clock-names
+ - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/bcm-nsp.h>
+ phy@1800c000 {
+ compatible = "brcm,ns-usb2-phy";
+ reg = <0x1800c000 0x1000>;
+ reg-names = "dmu";
+ clocks = <&genpll BCM_NSP_GENPLL_USB_PHY_REF_CLK>;
+ clock-names = "phy-ref-clk";
+ #phy-cells = <0>;
+ };
diff --git a/Documentation/devicetree/bindings/phy/bcm-ns-usb3-phy.txt b/Documentation/devicetree/bindings/phy/bcm-ns-usb3-phy.txt
deleted file mode 100644
index 32f057260351..000000000000
--- a/Documentation/devicetree/bindings/phy/bcm-ns-usb3-phy.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-Driver for Broadcom Northstar USB 3.0 PHY
-
-Required properties:
-
-- compatible: one of: "brcm,ns-ax-usb3-phy", "brcm,ns-bx-usb3-phy".
-- reg: address of MDIO bus device
-- usb3-dmp-syscon: phandle to syscon with DMP (Device Management Plugin)
- registers
-- #phy-cells: must be 0
-
-Initialization of USB 3.0 PHY depends on Northstar version. There are currently
-three known series: Ax, Bx and Cx.
-Known A0: BCM4707 rev 0
-Known B0: BCM4707 rev 4, BCM53573 rev 2
-Known B1: BCM4707 rev 6
-Known C0: BCM47094 rev 0
-
-Example:
- mdio: mdio@0 {
- reg = <0x0>;
- #size-cells = <1>;
- #address-cells = <0>;
-
- usb3-phy@10 {
- compatible = "brcm,ns-ax-usb3-phy";
- reg = <0x10>;
- usb3-dmp-syscon = <&usb3_dmp>;
- #phy-cells = <0>;
- };
- };
-
- usb3_dmp: syscon@18105000 {
- reg = <0x18105000 0x1000>;
- };
diff --git a/Documentation/devicetree/bindings/phy/bcm-ns-usb3-phy.yaml b/Documentation/devicetree/bindings/phy/bcm-ns-usb3-phy.yaml
new file mode 100644
index 000000000000..7fd419db45d0
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/bcm-ns-usb3-phy.yaml
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/bcm-ns-usb3-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom Northstar USB 3.0 PHY
+
+description: |
+ Initialization of USB 3.0 PHY depends on Northstar version. There are currently
+ three known series: Ax, Bx and Cx.
+ Known A0: BCM4707 rev 0
+ Known B0: BCM4707 rev 4, BCM53573 rev 2
+ Known B1: BCM4707 rev 6
+ Known C0: BCM47094 rev 0
+
+maintainers:
+ - Rafał Miłecki <rafal@milecki.pl>
+
+properties:
+ compatible:
+ enum:
+ - brcm,ns-ax-usb3-phy
+ - brcm,ns-bx-usb3-phy
+
+ reg:
+ description: address of MDIO bus device
+ maxItems: 1
+
+ usb3-dmp-syscon:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description:
+ Phandle to the DMP (Device Management Plugin) syscon
+
+ "#phy-cells":
+ const: 0
+
+required:
+ - compatible
+ - reg
+ - usb3-dmp-syscon
+ - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb3-phy@10 {
+ compatible = "brcm,ns-ax-usb3-phy";
+ reg = <0x10>;
+ usb3-dmp-syscon = <&usb3_dmp>;
+ #phy-cells = <0>;
+ };
+ };
+
+ usb3_dmp: syscon@18105000 {
+ reg = <0x18105000 0x1000>;
+ };
diff --git a/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml b/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml
index 0497368d1fca..5f9e91bfb5ff 100644
--- a/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml
@@ -42,6 +42,9 @@ properties:
- const: usb_mdio
- const: bdc_ec
+ power-domains:
+ maxItems: 1
+
clocks:
minItems: 1
maxItems: 2
diff --git a/Documentation/devicetree/bindings/phy/marvell,armada-3700-utmi-phy.yaml b/Documentation/devicetree/bindings/phy/marvell,armada-3700-utmi-phy.yaml
new file mode 100644
index 000000000000..2437c3683326
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/marvell,armada-3700-utmi-phy.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/phy/marvell,armada-3700-utmi-phy.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Marvell Armada UTMI/UTMI+ PHY
+
+maintainers:
+ - Miquel Raynal <miquel.raynal@bootlin.com>
+
+description:
+ On Armada 3700, there are two USB controllers, one is compatible with
+ the USB2 and USB3 specifications and supports OTG. The other one is USB2
+ compliant and only supports host mode. Both of these controllers come with
+ a slightly different UTMI PHY.
+
+properties:
+ compatible:
+ enum:
+ - marvell,a3700-utmi-host-phy
+ - marvell,a3700-utmi-otg-phy
+ reg:
+ maxItems: 1
+
+ "#phy-cells":
+ const: 0
+
+ marvell,usb-misc-reg:
+ description:
+ Phandle on the "USB miscellaneous registers" shared region
+ covering registers related to both the host controller and
+ the PHY.
+ $ref: /schemas/types.yaml#/definitions/phandle
+
+required:
+ - compatible
+ - reg
+ - "#phy-cells"
+ - marvell,usb-misc-reg
+
+additionalProperties: false
+
+examples:
+ - |
+ usb2_utmi_host_phy: phy@5f000 {
+ compatible = "marvell,armada-3700-utmi-host-phy";
+ reg = <0x5f000 0x800>;
+ marvell,usb-misc-reg = <&usb2_syscon>;
+ #phy-cells = <0>;
+ };
+
+ usb2_syscon: system-controller@5f800 {
+ compatible = "marvell,armada-3700-usb2-host-misc", "syscon";
+ reg = <0x5f800 0x800>;
+ };
diff --git a/Documentation/devicetree/bindings/phy/marvell,armada-cp110-utmi-phy.yaml b/Documentation/devicetree/bindings/phy/marvell,armada-cp110-utmi-phy.yaml
new file mode 100644
index 000000000000..30f3b5f32a95
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/marvell,armada-cp110-utmi-phy.yaml
@@ -0,0 +1,109 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/phy/marvell,armada-cp110-utmi-phy.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Marvell Armada CP110/CP115 UTMI PHY
+
+maintainers:
+ - Konstantin Porotchkin <kostap@marvell.com>
+
+description:
+ On Armada 7k/8k and CN913x, there are two host and one device USB controllers.
+ Each of two exiting UTMI PHYs could be connected to either USB host or USB device
+ controller.
+ The USB device controller can only be connected to a single UTMI PHY port
+ 0.H----- USB HOST0
+ UTMI PHY0 --------/
+ 0.D-----0
+ \------ USB DEVICE
+ 1.D-----1
+ UTMI PHY1 --------\
+ 1.H----- USB HOST1
+
+properties:
+ compatible:
+ const: marvell,cp110-utmi-phy
+
+ reg:
+ maxItems: 1
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 0
+
+ marvell,system-controller:
+ description:
+ Phandle to the system controller node
+ $ref: /schemas/types.yaml#/definitions/phandle
+
+#Required child nodes:
+
+patternProperties:
+ "^usb-phy@[0|1]$":
+ type: object
+ description:
+ Each UTMI PHY port must be represented as a sub-node.
+
+ properties:
+ reg:
+ description: phy port index.
+ maxItems: 1
+
+ "#phy-cells":
+ const: 0
+
+ required:
+ - reg
+ - "#phy-cells"
+
+ additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - "#address-cells"
+ - "#size-cells"
+ - marvell,system-controller
+
+additionalProperties: false
+
+examples:
+ - |
+ cp0_utmi: utmi@580000 {
+ compatible = "marvell,cp110-utmi-phy";
+ reg = <0x580000 0x2000>;
+ marvell,system-controller = <&cp0_syscon0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cp0_utmi0: usb-phy@0 {
+ reg = <0>;
+ #phy-cells = <0>;
+ };
+
+ cp0_utmi1: usb-phy@1 {
+ reg = <1>;
+ #phy-cells = <0>;
+ };
+ };
+
+ cp0_usb3_0 {
+ usb-phy = <&cp0_usb3_0_phy0>;
+ phys = <&cp0_utmi0>;
+ phy-names = "utmi";
+ /* UTMI0 is connected to USB host controller (default mode) */
+ dr_mode = "host";
+ };
+
+ cp0_usb3_1 {
+ usb-phy = <&cp0_usb3_0_phy1>;
+ phys = <&cp0_utmi1>;
+ phy-names = "utmi";
+ /* UTMI1 is connected to USB device controller */
+ dr_mode = "peripheral";
+ };
diff --git a/Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml b/Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml
index 71d4acea1f66..6e4d795f9b02 100644
--- a/Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml
@@ -19,11 +19,14 @@ properties:
pattern: "^dsi-phy@[0-9a-f]+$"
compatible:
- enum:
- - mediatek,mt2701-mipi-tx
- - mediatek,mt7623-mipi-tx
- - mediatek,mt8173-mipi-tx
- - mediatek,mt8183-mipi-tx
+ oneOf:
+ - items:
+ - enum:
+ - mediatek,mt7623-mipi-tx
+ - const: mediatek,mt2701-mipi-tx
+ - const: mediatek,mt2701-mipi-tx
+ - const: mediatek,mt8173-mipi-tx
+ - const: mediatek,mt8183-mipi-tx
reg:
maxItems: 1
diff --git a/Documentation/devicetree/bindings/phy/mediatek,hdmi-phy.yaml b/Documentation/devicetree/bindings/phy/mediatek,hdmi-phy.yaml
index 4752517a1446..0d94950b84ca 100644
--- a/Documentation/devicetree/bindings/phy/mediatek,hdmi-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/mediatek,hdmi-phy.yaml
@@ -21,10 +21,13 @@ properties:
pattern: "^hdmi-phy@[0-9a-f]+$"
compatible:
- enum:
- - mediatek,mt2701-hdmi-phy
- - mediatek,mt7623-hdmi-phy
- - mediatek,mt8173-hdmi-phy
+ oneOf:
+ - items:
+ - enum:
+ - mediatek,mt7623-hdmi-phy
+ - const: mediatek,mt2701-hdmi-phy
+ - const: mediatek,mt2701-hdmi-phy
+ - const: mediatek,mt8173-hdmi-phy
reg:
maxItems: 1
diff --git a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
index 602e6ff45785..b8a7651a3d9a 100644
--- a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
+++ b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
@@ -79,6 +79,7 @@ properties:
- mediatek,mt2712-tphy
- mediatek,mt7629-tphy
- mediatek,mt8183-tphy
+ - mediatek,mt8195-tphy
- const: mediatek,generic-tphy-v2
- const: mediatek,mt2701-u3phy
deprecated: true
@@ -117,7 +118,7 @@ properties:
# Required child node:
patternProperties:
- "^usb-phy@[0-9a-f]+$":
+ "^(usb|pcie|sata)-phy@[0-9a-f]+$":
type: object
description:
A sub-node is required for each port the controller provides.
diff --git a/Documentation/devicetree/bindings/phy/mediatek,ufs-phy.yaml b/Documentation/devicetree/bindings/phy/mediatek,ufs-phy.yaml
index 3a9be82e7f13..74cc32c1d2e8 100644
--- a/Documentation/devicetree/bindings/phy/mediatek,ufs-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/mediatek,ufs-phy.yaml
@@ -22,7 +22,12 @@ properties:
pattern: "^ufs-phy@[0-9a-f]+$"
compatible:
- const: mediatek,mt8183-ufsphy
+ oneOf:
+ - items:
+ - enum:
+ - mediatek,mt8195-ufsphy
+ - const: mediatek,mt8183-ufsphy
+ - const: mediatek,mt8183-ufsphy
reg:
maxItems: 1
diff --git a/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml b/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml
new file mode 100644
index 000000000000..bdbdb3bbddbe
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/microchip,sparx5-serdes.yaml
@@ -0,0 +1,100 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/microchip,sparx5-serdes.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip Sparx5 Serdes controller
+
+maintainers:
+ - Steen Hegelund <steen.hegelund@microchip.com>
+
+description: |
+ The Sparx5 SERDES interfaces share the same basic functionality, but
+ support different operating modes and line rates.
+
+ The following list lists the SERDES features:
+
+ * RX Adaptive Decision Feedback Equalizer (DFE)
+ * Programmable continuous time linear equalizer (CTLE)
+ * Rx variable gain control
+ * Rx built-in fault detector (loss-of-lock/loss-of-signal)
+ * Adjustable tx de-emphasis (FFE)
+ * Tx output amplitude control
+ * Supports rx eye monitor
+ * Multiple loopback modes
+ * Prbs generator and checker
+ * Polarity inversion control
+
+ SERDES6G:
+
+ The SERDES6G is a high-speed SERDES interface, which can operate at
+ the following data rates:
+
+ * 100 Mbps (100BASE-FX)
+ * 1.25 Gbps (SGMII/1000BASE-X/1000BASE-KX)
+ * 3.125 Gbps (2.5GBASE-X/2.5GBASE-KX)
+ * 5.15625 Gbps (5GBASE-KR/5G-USXGMII)
+
+ SERDES10G
+
+ The SERDES10G is a high-speed SERDES interface, which can operate at
+ the following data rates:
+
+ * 100 Mbps (100BASE-FX)
+ * 1.25 Gbps (SGMII/1000BASE-X/1000BASE-KX)
+ * 3.125 Gbps (2.5GBASE-X/2.5GBASE-KX)
+ * 5 Gbps (QSGMII/USGMII)
+ * 5.15625 Gbps (5GBASE-KR/5G-USXGMII)
+ * 10 Gbps (10G-USGMII)
+ * 10.3125 Gbps (10GBASE-R/10GBASE-KR/USXGMII)
+
+ SERDES25G
+
+ The SERDES25G is a high-speed SERDES interface, which can operate at
+ the following data rates:
+
+ * 1.25 Gbps (SGMII/1000BASE-X/1000BASE-KX)
+ * 3.125 Gbps (2.5GBASE-X/2.5GBASE-KX)
+ * 5 Gbps (QSGMII/USGMII)
+ * 5.15625 Gbps (5GBASE-KR/5G-USXGMII)
+ * 10 Gbps (10G-USGMII)
+ * 10.3125 Gbps (10GBASE-R/10GBASE-KR/USXGMII)
+ * 25.78125 Gbps (25GBASE-KR/25GBASE-CR/25GBASE-SR/25GBASE-LR/25GBASE-ER)
+
+properties:
+ $nodename:
+ pattern: "^serdes@[0-9a-f]+$"
+
+ compatible:
+ const: microchip,sparx5-serdes
+
+ reg:
+ minItems: 1
+
+ '#phy-cells':
+ const: 1
+ description: |
+ - The main serdes input port
+
+ clocks:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - '#phy-cells'
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+ serdes: serdes@10808000 {
+ compatible = "microchip,sparx5-serdes";
+ #phy-cells = <1>;
+ clocks = <&sys_clk>;
+ reg = <0x10808000 0x5d0000>;
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml b/Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml
index d210843863df..84383e2e0b34 100644
--- a/Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml
+++ b/Documentation/devicetree/bindings/phy/phy-cadence-sierra.yaml
@@ -26,6 +26,9 @@ properties:
'#size-cells':
const: 0
+ '#clock-cells':
+ const: 1
+
resets:
minItems: 1
maxItems: 2
@@ -49,12 +52,24 @@ properties:
const: serdes
clocks:
- maxItems: 2
+ minItems: 2
+ maxItems: 4
clock-names:
+ minItems: 2
items:
- const: cmn_refclk_dig_div
- const: cmn_refclk1_dig_div
+ - const: pll0_refclk
+ - const: pll1_refclk
+
+ assigned-clocks:
+ minItems: 1
+ maxItems: 2
+
+ assigned-clock-parents:
+ minItems: 1
+ maxItems: 2
cdns,autoconf:
type: boolean
diff --git a/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml b/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
index e266ade53d87..01dcd14e7b2a 100644
--- a/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
+++ b/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
@@ -28,13 +28,27 @@ properties:
'#size-cells':
const: 0
+ '#clock-cells':
+ const: 1
+
clocks:
- maxItems: 1
+ minItems: 1
+ maxItems: 2
description:
- PHY reference clock. Must contain an entry in clock-names.
+ PHY reference clock for 1 item. Must contain an entry in clock-names.
+ Optional Parent to enable output reference clock.
clock-names:
- const: refclk
+ minItems: 1
+ items:
+ - const: refclk
+ - const: phy_en_refclk
+
+ assigned-clocks:
+ maxItems: 3
+
+ assigned-clock-parents:
+ maxItems: 3
reg:
minItems: 1
@@ -170,7 +184,7 @@ examples:
};
- |
#include <dt-bindings/phy/phy.h>
- #include <dt-bindings/phy/phy-cadence-torrent.h>
+ #include <dt-bindings/phy/phy-cadence.h>
bus {
#address-cells = <2>;
diff --git a/Documentation/devicetree/bindings/phy/phy-mvebu-utmi.txt b/Documentation/devicetree/bindings/phy/phy-mvebu-utmi.txt
deleted file mode 100644
index aa99ceec73b0..000000000000
--- a/Documentation/devicetree/bindings/phy/phy-mvebu-utmi.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-MVEBU A3700 UTMI PHY
---------------------
-
-USB2 UTMI+ PHY controllers can be found on the following Marvell MVEBU SoCs:
-* Armada 3700
-
-On Armada 3700, there are two USB controllers, one is compatible with the USB2
-and USB3 specifications and supports OTG. The other one is USB2 compliant and
-only supports host mode. Both of these controllers come with a slightly
-different UTMI PHY.
-
-Required Properties:
-
-- compatible: Should be one of:
- * "marvell,a3700-utmi-host-phy" for the PHY connected to
- the USB2 host-only controller.
- * "marvell,a3700-utmi-otg-phy" for the PHY connected to
- the USB3 and USB2 OTG capable controller.
-- reg: PHY IP register range.
-- marvell,usb-misc-reg: handle on the "USB miscellaneous registers" shared
- region covering registers related to both the host
- controller and the PHY.
-- #phy-cells: Standard property (Documentation: phy-bindings.txt) Should be 0.
-
-
-Example:
-
- usb2_utmi_host_phy: phy@5f000 {
- compatible = "marvell,armada-3700-utmi-host-phy";
- reg = <0x5f000 0x800>;
- marvell,usb-misc-reg = <&usb2_syscon>;
- #phy-cells = <0>;
- };
-
- usb2_syscon: system-controller@5f800 {
- compatible = "marvell,armada-3700-usb2-host-misc", "syscon";
- reg = <0x5f800 0x800>;
- };
diff --git a/Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml b/Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml
index 46df6786727a..018cc1246ee1 100644
--- a/Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml
+++ b/Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml
@@ -51,6 +51,10 @@ properties:
vdda1v8-supply:
description: regulator providing 1V8 power supply to the PLL block
+ '#clock-cells':
+ description: number of clock cells for ck_usbo_48m consumer
+ const: 0
+
#Required child nodes:
patternProperties:
@@ -120,6 +124,7 @@ examples:
vdda1v8-supply = <&reg18>;
#address-cells = <1>;
#size-cells = <0>;
+ #clock-cells = <0>;
usbphyc_port0: usb-phy@0 {
reg = <0>;
diff --git a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
index 626447fee092..7808ec8bc712 100644
--- a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
@@ -25,11 +25,13 @@ properties:
- qcom,msm8998-qmp-pcie-phy
- qcom,msm8998-qmp-ufs-phy
- qcom,msm8998-qmp-usb3-phy
+ - qcom,sc7180-qmp-usb3-phy
- qcom,sc8180x-qmp-ufs-phy
- qcom,sc8180x-qmp-usb3-phy
- qcom,sdm845-qhp-pcie-phy
- qcom,sdm845-qmp-pcie-phy
- qcom,sdm845-qmp-ufs-phy
+ - qcom,sdm845-qmp-usb3-phy
- qcom,sdm845-qmp-usb3-uni-phy
- qcom,sm8150-qmp-ufs-phy
- qcom,sm8150-qmp-usb3-phy
diff --git a/Documentation/devicetree/bindings/phy/qcom,qmp-usb3-dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qmp-usb3-dp-phy.yaml
index 33974ad10afe..217aa6c91893 100644
--- a/Documentation/devicetree/bindings/phy/qcom,qmp-usb3-dp-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,qmp-usb3-dp-phy.yaml
@@ -14,9 +14,8 @@ properties:
compatible:
enum:
- qcom,sc7180-qmp-usb3-dp-phy
- - qcom,sc7180-qmp-usb3-phy
- qcom,sdm845-qmp-usb3-dp-phy
- - qcom,sdm845-qmp-usb3-phy
+ - qcom,sm8250-qmp-usb3-dp-phy
reg:
items:
- description: Address and length of PHY's USB serdes block.
diff --git a/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml b/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml
index ee77c6458326..20203a8a9e41 100644
--- a/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml
@@ -16,6 +16,7 @@ properties:
compatible:
enum:
- qcom,usb-snps-hs-7nm-phy
+ - qcom,sc7280-usb-hs-phy
- qcom,sm8150-usb-hs-phy
- qcom,sm8250-usb-hs-phy
- qcom,sm8350-usb-hs-phy
diff --git a/Documentation/devicetree/bindings/phy/ti,phy-j721e-wiz.yaml b/Documentation/devicetree/bindings/phy/ti,phy-j721e-wiz.yaml
index bbbd85501ada..57e1d013a502 100644
--- a/Documentation/devicetree/bindings/phy/ti,phy-j721e-wiz.yaml
+++ b/Documentation/devicetree/bindings/phy/ti,phy-j721e-wiz.yaml
@@ -15,6 +15,7 @@ properties:
enum:
- ti,j721e-wiz-16g
- ti,j721e-wiz-10g
+ - ti,am64-wiz-10g
power-domains:
maxItems: 1
@@ -42,6 +43,9 @@ properties:
"#reset-cells":
const: 1
+ "#clock-cells":
+ const: 1
+
ranges: true
assigned-clocks:
diff --git a/Documentation/devicetree/bindings/soundwire/qcom,sdw.txt b/Documentation/devicetree/bindings/soundwire/qcom,sdw.txt
index b104be131235..b93a2b3e029d 100644
--- a/Documentation/devicetree/bindings/soundwire/qcom,sdw.txt
+++ b/Documentation/devicetree/bindings/soundwire/qcom,sdw.txt
@@ -54,6 +54,8 @@ board specific bus parameters.
Value type: <prop-encoded-array>
Definition: should specify payload transport window offset1 of each
data port. Out ports followed by In ports.
+ Value of 0xFF indicates that this option is not implemented
+ or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
- qcom,ports-offset2:
@@ -61,6 +63,8 @@ board specific bus parameters.
Value type: <prop-encoded-array>
Definition: should specify payload transport window offset2 of each
data port. Out ports followed by In ports.
+ Value of 0xFF indicates that this option is not implemented
+ or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
- qcom,ports-sinterval-low:
@@ -69,12 +73,16 @@ board specific bus parameters.
Definition: should be sample interval low of each data port.
Out ports followed by In ports. Used for Sample Interval
calculation.
+ Value of 0xFF indicates that this option is not implemented
+ or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
- qcom,ports-word-length:
Usage: optional
Value type: <prop-encoded-array>
Definition: should be size of payload channel sample.
+ Value of 0xFF indicates that this option is not implemented
+ or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
- qcom,ports-block-pack-mode:
@@ -84,6 +92,8 @@ board specific bus parameters.
0 to indicate Blocks are per Channel
1 to indicate Blocks are per Port.
Out ports followed by In ports.
+ Value of 0xFF indicates that this option is not implemented
+ or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
- qcom,ports-block-group-count:
@@ -92,6 +102,8 @@ board specific bus parameters.
Definition: should be in range 1 to 4 to indicate how many sample
intervals are combined into a payload.
Out ports followed by In ports.
+ Value of 0xFF indicates that this option is not implemented
+ or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
- qcom,ports-lane-control:
@@ -100,6 +112,8 @@ board specific bus parameters.
Definition: should be in range 0 to 7 to identify which data lane
the data port uses.
Out ports followed by In ports.
+ Value of 0xFF indicates that this option is not implemented
+ or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
- qcom,ports-hstart:
@@ -109,6 +123,8 @@ board specific bus parameters.
SoundWire Frame, i.e. left edge of the Transport sub-frame
for each port. Values between 0 and 15 are valid.
Out ports followed by In ports.
+ Value of 0xFF indicates that this option is not implemented
+ or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
- qcom,ports-hstop:
@@ -118,6 +134,8 @@ board specific bus parameters.
SoundWire Frame, i.e. the right edge of the Transport
sub-frame for each port. Values between 0 and 15 are valid.
Out ports followed by In ports.
+ Value of 0xFF indicates that this option is not implemented
+ or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
- qcom,dports-type:
@@ -128,6 +146,8 @@ board specific bus parameters.
1 for simple ports
2 for full port
Out ports followed by In ports.
+ Value of 0xFF indicates that this option is not implemented
+ or applicable for the respective data port.
More info in MIPI Alliance SoundWire 1.0 Specifications.
Note:
diff --git a/Documentation/fpga/dfl.rst b/Documentation/fpga/dfl.rst
index c41ac76ffaae..f3a1223f2517 100644
--- a/Documentation/fpga/dfl.rst
+++ b/Documentation/fpga/dfl.rst
@@ -7,6 +7,7 @@ Authors:
- Enno Luebbers <enno.luebbers@intel.com>
- Xiao Guangrong <guangrong.xiao@linux.intel.com>
- Wu Hao <hao.wu@intel.com>
+- Xu Yilun <yilun.xu@intel.com>
The Device Feature List (DFL) FPGA framework (and drivers according to
this framework) hides the very details of low layer hardwares and provides
@@ -530,6 +531,31 @@ Being able to specify more than one DFL per BAR has been considered, but it
was determined the use case did not provide value. Specifying a single DFL
per BAR simplifies the implementation and allows for extra error checking.
+
+Userspace driver support for DFL devices
+========================================
+The purpose of an FPGA is to be reprogrammed with newly developed hardware
+components. New hardware can instantiate a new private feature in the DFL, and
+then present a DFL device in the system. In some cases users may need a
+userspace driver for the DFL device:
+
+* Users may need to run some diagnostic test for their hardware.
+* Users may prototype the kernel driver in user space.
+* Some hardware is designed for specific purposes and does not fit into one of
+ the standard kernel subsystems.
+
+This requires direct access to MMIO space and interrupt handling from
+userspace. The uio_dfl module exposes the UIO device interfaces for this
+purpose.
+
+Currently the uio_dfl driver only supports the Ether Group sub feature, which
+has no irq in hardware. So the interrupt handling is not added in this driver.
+
+UIO_DFL should be selected to enable the uio_dfl module driver. To support a
+new DFL feature via UIO direct access, its feature id should be added to the
+driver's id_table.
+
+
Open discussion
===============
FME driver exports one ioctl (DFL_FPGA_FME_PORT_PR) for partial reconfiguration
diff --git a/Documentation/misc-devices/dw-xdata-pcie.rst b/Documentation/misc-devices/dw-xdata-pcie.rst
new file mode 100644
index 000000000000..fd75c9321f47
--- /dev/null
+++ b/Documentation/misc-devices/dw-xdata-pcie.rst
@@ -0,0 +1,40 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===========================================================================
+Driver for Synopsys DesignWare PCIe traffic generator (also known as xData)
+===========================================================================
+
+This driver should be used as a host-side (Root Complex) driver and Synopsys
+DesignWare prototype that includes this IP.
+
+The "dw-xdata-pcie" driver can be used to enable/disable PCIe traffic
+generator in either direction (mutual exclusion) besides allowing the
+PCIe link performance analysis.
+
+The interaction with this driver is done through the module parameter and
+can be changed in runtime. The driver outputs the requested command state
+information to /var/log/kern.log or dmesg.
+
+Request write TLPs traffic generation - Root Complex to Endpoint direction
+- Command:
+ echo 1 > /sys/class/misc/dw-xdata-pcie/write
+
+Get write TLPs traffic link throughput in MB/s
+- Command:
+ cat /sys/class/misc/dw-xdata-pcie/write
+- Output example:
+ 204
+
+Request read TLPs traffic generation - Endpoint to Root Complex direction:
+- Command:
+ echo 1 > /sys/class/misc/dw-xdata-pcie/read
+
+Get read TLPs traffic link throughput in MB/s
+- Command:
+ cat /sys/class/misc/dw-xdata-pcie/read
+- Output example:
+ 199
+
+Request to stop any current TLP transfer:
+- Command:
+ echo 1 > /sys/class/misc/dw-xdata-pcie/stop
diff --git a/MAINTAINERS b/MAINTAINERS
index c80ad735b384..aa86b4d0bfce 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1764,6 +1764,7 @@ F: Documentation/devicetree/bindings/arm/coresight.txt
F: Documentation/trace/coresight/*
F: drivers/hwtracing/coresight/*
F: include/dt-bindings/arm/coresight-cti-dt.h
+F: include/linux/coresight*
F: tools/perf/arch/arm/util/auxtrace.c
F: tools/perf/arch/arm/util/cs-etm.c
F: tools/perf/arch/arm/util/cs-etm.h
@@ -5099,6 +5100,13 @@ S: Maintained
F: drivers/dma/dw-edma/
F: include/linux/dma/edma.h
+DESIGNWARE XDATA IP DRIVER
+M: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
+L: linux-pci@vger.kernel.org
+S: Maintained
+F: Documentation/misc-devices/dw-xdata-pcie.rst
+F: drivers/misc/dw-xdata-pcie.c
+
DESIGNWARE USB2 DRD IP DRIVER
M: Minas Harutyunyan <hminas@synopsys.com>
L: linux-usb@vger.kernel.org
@@ -6990,6 +6998,7 @@ S: Maintained
F: Documentation/ABI/testing/sysfs-bus-dfl*
F: Documentation/fpga/dfl.rst
F: drivers/fpga/dfl*
+F: drivers/uio/uio_dfl.c
F: include/linux/dfl.h
F: include/uapi/linux/fpga-dfl.h
@@ -7891,6 +7900,11 @@ W: https://linuxtv.org
T: git git://linuxtv.org/media_tree.git
F: drivers/media/usb/hdpvr/
+HEWLETT PACKARD ENTERPRISE ILO CHIF DRIVER
+M: Matt Hsiao <matt.hsiao@hpe.com>
+S: Supported
+F: drivers/misc/hpilo.[ch]
+
HEWLETT PACKARD ENTERPRISE ILO NMI WATCHDOG DRIVER
M: Jerry Hoemann <jerry.hoemann@hpe.com>
S: Supported
@@ -8545,7 +8559,8 @@ S: Supported
F: drivers/scsi/ibmvscsi/ibmvfc*
IBM Power Virtual Management Channel Driver
-M: Steven Royer <seroyer@linux.ibm.com>
+M: Brad Warrum <bwarrum@linux.ibm.com>
+M: Ritu Agarwal <rituagar@linux.ibm.com>
S: Supported
F: drivers/misc/ibmvmc.*
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index c119736ca56a..e1a484ab0366 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -1506,6 +1506,12 @@ static void binder_free_transaction(struct binder_transaction *t)
if (target_proc) {
binder_inner_proc_lock(target_proc);
+ target_proc->outstanding_txns--;
+ if (target_proc->outstanding_txns < 0)
+ pr_warn("%s: Unexpected outstanding_txns %d\n",
+ __func__, target_proc->outstanding_txns);
+ if (!target_proc->outstanding_txns && target_proc->is_frozen)
+ wake_up_interruptible_all(&target_proc->freeze_wait);
if (t->buffer)
t->buffer->transaction = NULL;
binder_inner_proc_unlock(target_proc);
@@ -2331,10 +2337,11 @@ static int binder_fixup_parent(struct binder_transaction *t,
* If the @thread parameter is not NULL, the transaction is always queued
* to the waitlist of that specific thread.
*
- * Return: true if the transactions was successfully queued
- * false if the target process or thread is dead
+ * Return: 0 if the transaction was successfully queued
+ * BR_DEAD_REPLY if the target process or thread is dead
+ * BR_FROZEN_REPLY if the target process or thread is frozen
*/
-static bool binder_proc_transaction(struct binder_transaction *t,
+static int binder_proc_transaction(struct binder_transaction *t,
struct binder_proc *proc,
struct binder_thread *thread)
{
@@ -2353,11 +2360,16 @@ static bool binder_proc_transaction(struct binder_transaction *t,
}
binder_inner_proc_lock(proc);
+ if (proc->is_frozen) {
+ proc->sync_recv |= !oneway;
+ proc->async_recv |= oneway;
+ }
- if (proc->is_dead || (thread && thread->is_dead)) {
+ if ((proc->is_frozen && !oneway) || proc->is_dead ||
+ (thread && thread->is_dead)) {
binder_inner_proc_unlock(proc);
binder_node_unlock(node);
- return false;
+ return proc->is_frozen ? BR_FROZEN_REPLY : BR_DEAD_REPLY;
}
if (!thread && !pending_async)
@@ -2373,10 +2385,11 @@ static bool binder_proc_transaction(struct binder_transaction *t,
if (!pending_async)
binder_wakeup_thread_ilocked(proc, thread, !oneway /* sync */);
+ proc->outstanding_txns++;
binder_inner_proc_unlock(proc);
binder_node_unlock(node);
- return true;
+ return 0;
}
/**
@@ -3013,13 +3026,16 @@ static void binder_transaction(struct binder_proc *proc,
if (reply) {
binder_enqueue_thread_work(thread, tcomplete);
binder_inner_proc_lock(target_proc);
- if (target_thread->is_dead) {
+ if (target_thread->is_dead || target_proc->is_frozen) {
+ return_error = target_thread->is_dead ?
+ BR_DEAD_REPLY : BR_FROZEN_REPLY;
binder_inner_proc_unlock(target_proc);
goto err_dead_proc_or_thread;
}
BUG_ON(t->buffer->async_transaction != 0);
binder_pop_transaction_ilocked(target_thread, in_reply_to);
binder_enqueue_thread_work_ilocked(target_thread, &t->work);
+ target_proc->outstanding_txns++;
binder_inner_proc_unlock(target_proc);
wake_up_interruptible_sync(&target_thread->wait);
binder_free_transaction(in_reply_to);
@@ -3038,7 +3054,9 @@ static void binder_transaction(struct binder_proc *proc,
t->from_parent = thread->transaction_stack;
thread->transaction_stack = t;
binder_inner_proc_unlock(proc);
- if (!binder_proc_transaction(t, target_proc, target_thread)) {
+ return_error = binder_proc_transaction(t,
+ target_proc, target_thread);
+ if (return_error) {
binder_inner_proc_lock(proc);
binder_pop_transaction_ilocked(thread, t);
binder_inner_proc_unlock(proc);
@@ -3048,7 +3066,8 @@ static void binder_transaction(struct binder_proc *proc,
BUG_ON(target_node == NULL);
BUG_ON(t->buffer->async_transaction != 1);
binder_enqueue_thread_work(thread, tcomplete);
- if (!binder_proc_transaction(t, target_proc, NULL))
+ return_error = binder_proc_transaction(t, target_proc, NULL);
+ if (return_error)
goto err_dead_proc_or_thread;
}
if (target_thread)
@@ -3065,7 +3084,6 @@ static void binder_transaction(struct binder_proc *proc,
return;
err_dead_proc_or_thread:
- return_error = BR_DEAD_REPLY;
return_error_line = __LINE__;
binder_dequeue_work(proc, tcomplete);
err_translate_failed:
@@ -3696,7 +3714,7 @@ static int binder_wait_for_work(struct binder_thread *thread,
binder_inner_proc_lock(proc);
list_del_init(&thread->waiting_thread_node);
if (signal_pending(current)) {
- ret = -ERESTARTSYS;
+ ret = -EINTR;
break;
}
}
@@ -4298,6 +4316,9 @@ static void binder_free_proc(struct binder_proc *proc)
BUG_ON(!list_empty(&proc->todo));
BUG_ON(!list_empty(&proc->delivered_death));
+ if (proc->outstanding_txns)
+ pr_warn("%s: Unexpected outstanding_txns %d\n",
+ __func__, proc->outstanding_txns);
device = container_of(proc->context, struct binder_device, context);
if (refcount_dec_and_test(&device->ref)) {
kfree(proc->context->name);
@@ -4359,6 +4380,7 @@ static int binder_thread_release(struct binder_proc *proc,
(t->to_thread == thread) ? "in" : "out");
if (t->to_thread == thread) {
+ thread->proc->outstanding_txns--;
t->to_proc = NULL;
t->to_thread = NULL;
if (t->buffer) {
@@ -4609,6 +4631,76 @@ static int binder_ioctl_get_node_debug_info(struct binder_proc *proc,
return 0;
}
+static int binder_ioctl_freeze(struct binder_freeze_info *info,
+ struct binder_proc *target_proc)
+{
+ int ret = 0;
+
+ if (!info->enable) {
+ binder_inner_proc_lock(target_proc);
+ target_proc->sync_recv = false;
+ target_proc->async_recv = false;
+ target_proc->is_frozen = false;
+ binder_inner_proc_unlock(target_proc);
+ return 0;
+ }
+
+ /*
+ * Freezing the target. Prevent new transactions by
+ * setting frozen state. If timeout specified, wait
+ * for transactions to drain.
+ */
+ binder_inner_proc_lock(target_proc);
+ target_proc->sync_recv = false;
+ target_proc->async_recv = false;
+ target_proc->is_frozen = true;
+ binder_inner_proc_unlock(target_proc);
+
+ if (info->timeout_ms > 0)
+ ret = wait_event_interruptible_timeout(
+ target_proc->freeze_wait,
+ (!target_proc->outstanding_txns),
+ msecs_to_jiffies(info->timeout_ms));
+
+ if (!ret && target_proc->outstanding_txns)
+ ret = -EAGAIN;
+
+ if (ret < 0) {
+ binder_inner_proc_lock(target_proc);
+ target_proc->is_frozen = false;
+ binder_inner_proc_unlock(target_proc);
+ }
+
+ return ret;
+}
+
+static int binder_ioctl_get_freezer_info(
+ struct binder_frozen_status_info *info)
+{
+ struct binder_proc *target_proc;
+ bool found = false;
+
+ info->sync_recv = 0;
+ info->async_recv = 0;
+
+ mutex_lock(&binder_procs_lock);
+ hlist_for_each_entry(target_proc, &binder_procs, proc_node) {
+ if (target_proc->pid == info->pid) {
+ found = true;
+ binder_inner_proc_lock(target_proc);
+ info->sync_recv |= target_proc->sync_recv;
+ info->async_recv |= target_proc->async_recv;
+ binder_inner_proc_unlock(target_proc);
+ }
+ }
+ mutex_unlock(&binder_procs_lock);
+
+ if (!found)
+ return -EINVAL;
+
+ return 0;
+}
+
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
int ret;
@@ -4727,6 +4819,84 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
}
break;
}
+ case BINDER_FREEZE: {
+ struct binder_freeze_info info;
+ struct binder_proc **target_procs = NULL, *target_proc;
+ int target_procs_count = 0, i = 0;
+
+ ret = 0;
+
+ if (copy_from_user(&info, ubuf, sizeof(info))) {
+ ret = -EFAULT;
+ goto err;
+ }
+
+ mutex_lock(&binder_procs_lock);
+ hlist_for_each_entry(target_proc, &binder_procs, proc_node) {
+ if (target_proc->pid == info.pid)
+ target_procs_count++;
+ }
+
+ if (target_procs_count == 0) {
+ mutex_unlock(&binder_procs_lock);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ target_procs = kcalloc(target_procs_count,
+ sizeof(struct binder_proc *),
+ GFP_KERNEL);
+
+ if (!target_procs) {
+ mutex_unlock(&binder_procs_lock);
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ hlist_for_each_entry(target_proc, &binder_procs, proc_node) {
+ if (target_proc->pid != info.pid)
+ continue;
+
+ binder_inner_proc_lock(target_proc);
+ target_proc->tmp_ref++;
+ binder_inner_proc_unlock(target_proc);
+
+ target_procs[i++] = target_proc;
+ }
+ mutex_unlock(&binder_procs_lock);
+
+ for (i = 0; i < target_procs_count; i++) {
+ if (ret >= 0)
+ ret = binder_ioctl_freeze(&info,
+ target_procs[i]);
+
+ binder_proc_dec_tmpref(target_procs[i]);
+ }
+
+ kfree(target_procs);
+
+ if (ret < 0)
+ goto err;
+ break;
+ }
+ case BINDER_GET_FROZEN_INFO: {
+ struct binder_frozen_status_info info;
+
+ if (copy_from_user(&info, ubuf, sizeof(info))) {
+ ret = -EFAULT;
+ goto err;
+ }
+
+ ret = binder_ioctl_get_freezer_info(&info);
+ if (ret < 0)
+ goto err;
+
+ if (copy_to_user(ubuf, &info, sizeof(info))) {
+ ret = -EFAULT;
+ goto err;
+ }
+ break;
+ }
default:
ret = -EINVAL;
goto err;
@@ -4736,7 +4906,7 @@ err:
if (thread)
thread->looper_need_return = false;
wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
- if (ret && ret != -ERESTARTSYS)
+ if (ret && ret != -EINTR)
pr_info("%d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret);
err_unlocked:
trace_binder_ioctl_done(ret);
@@ -4823,6 +4993,7 @@ static int binder_open(struct inode *nodp, struct file *filp)
get_task_struct(current->group_leader);
proc->tsk = current->group_leader;
INIT_LIST_HEAD(&proc->todo);
+ init_waitqueue_head(&proc->freeze_wait);
proc->default_priority = task_nice(current);
/* binderfs stashes devices in i_private */
if (is_binderfs_device(nodp)) {
@@ -5035,6 +5206,9 @@ static void binder_deferred_release(struct binder_proc *proc)
proc->tmp_ref++;
proc->is_dead = true;
+ proc->is_frozen = false;
+ proc->sync_recv = false;
+ proc->async_recv = false;
threads = 0;
active_transactions = 0;
while ((n = rb_first(&proc->threads))) {
diff --git a/drivers/android/binder_internal.h b/drivers/android/binder_internal.h
index 6cd79011e35d..2872a7de68e1 100644
--- a/drivers/android/binder_internal.h
+++ b/drivers/android/binder_internal.h
@@ -367,9 +367,22 @@ struct binder_ref {
* (protected by binder_deferred_lock)
* @deferred_work: bitmap of deferred work to perform
* (protected by binder_deferred_lock)
+ * @outstanding_txns: number of transactions to be transmitted before
+ * processes in freeze_wait are woken up
+ * (protected by @inner_lock)
* @is_dead: process is dead and awaiting free
* when outstanding transactions are cleaned up
* (protected by @inner_lock)
+ * @is_frozen: process is frozen and unable to service
+ * binder transactions
+ * (protected by @inner_lock)
+ * @sync_recv: process received sync transactions since last frozen
+ * (protected by @inner_lock)
+ * @async_recv: process received async transactions since last frozen
+ * (protected by @inner_lock)
+ * @freeze_wait: waitqueue of processes waiting for all outstanding
+ * transactions to be processed
+ * (protected by @inner_lock)
* @todo: list of work for this process
* (protected by @inner_lock)
* @stats: per-process binder statistics
@@ -410,7 +423,12 @@ struct binder_proc {
struct task_struct *tsk;
struct hlist_node deferred_work_node;
int deferred_work;
+ int outstanding_txns;
bool is_dead;
+ bool is_frozen;
+ bool sync_recv;
+ bool async_recv;
+ wait_queue_head_t freeze_wait;
struct list_head todo;
struct binder_stats stats;
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c
index 45ac7ab003ce..deb85a334c93 100644
--- a/drivers/char/applicom.c
+++ b/drivers/char/applicom.c
@@ -836,7 +836,7 @@ static long ac_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
Dummy = readb(apbs[IndexCard].RamIO + VERS);
kfree(adgl);
mutex_unlock(&ac_mutex);
- return 0;
+ return ret;
err:
if (warncount) {
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 862c2fd933c7..0e22e3b0a04e 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -546,7 +546,7 @@ static int lp_open(struct inode *inode, struct file *file)
}
/* Determine if the peripheral supports ECP mode */
lp_claim_parport_or_block(&lp_table[minor]);
- if ( (lp_table[minor].dev->port->modes & PARPORT_MODE_ECP) &&
+ if ((lp_table[minor].dev->port->modes & PARPORT_MODE_ECP) &&
!parport_negotiate(lp_table[minor].dev->port,
IEEE1284_MODE_ECP)) {
printk(KERN_INFO "lp%d: ECP mode\n", minor);
@@ -590,7 +590,7 @@ static int lp_do_ioctl(unsigned int minor, unsigned int cmd,
return -ENODEV;
if ((LP_F(minor) & LP_EXIST) == 0)
return -ENODEV;
- switch ( cmd ) {
+ switch (cmd) {
case LPTIME:
if (arg > UINT_MAX / HZ)
return -EINVAL;
diff --git a/drivers/char/mwave/tp3780i.c b/drivers/char/mwave/tp3780i.c
index 5e1618a76b2a..8588b51202e5 100644
--- a/drivers/char/mwave/tp3780i.c
+++ b/drivers/char/mwave/tp3780i.c
@@ -177,14 +177,10 @@ int tp3780I_InitializeBoardData(THINKPAD_BD_DATA * pBDData)
return retval;
}
-int tp3780I_Cleanup(THINKPAD_BD_DATA * pBDData)
+void tp3780I_Cleanup(THINKPAD_BD_DATA *pBDData)
{
- int retval = 0;
-
PRINTK_2(TRACE_TP3780I,
"tp3780i::tp3780I_Cleanup entry and exit pBDData %p\n", pBDData);
-
- return retval;
}
int tp3780I_CalcResources(THINKPAD_BD_DATA * pBDData)
diff --git a/drivers/char/mwave/tp3780i.h b/drivers/char/mwave/tp3780i.h
index 07685b68538f..8bd976d42fae 100644
--- a/drivers/char/mwave/tp3780i.h
+++ b/drivers/char/mwave/tp3780i.h
@@ -91,7 +91,7 @@ int tp3780I_DisableDSP(THINKPAD_BD_DATA * pBDData);
int tp3780I_ResetDSP(THINKPAD_BD_DATA * pBDData);
int tp3780I_StartDSP(THINKPAD_BD_DATA * pBDData);
int tp3780I_QueryAbilities(THINKPAD_BD_DATA * pBDData, MW_ABILITIES * pAbilities);
-int tp3780I_Cleanup(THINKPAD_BD_DATA * pBDData);
+void tp3780I_Cleanup(THINKPAD_BD_DATA *pBDData);
int tp3780I_ReadWriteDspDStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode,
void __user *pvBuffer, unsigned int uCount,
unsigned long ulDSPAddr);
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 1836cc56e357..59dfd9c421a1 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -1456,18 +1456,15 @@ static int add_port(struct ports_device *portdev, u32 id)
*/
send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1);
- if (pdrvdata.debugfs_dir) {
- /*
- * Finally, create the debugfs file that we can use to
- * inspect a port's state at any time
- */
- snprintf(debugfs_name, sizeof(debugfs_name), "vport%up%u",
- port->portdev->vdev->index, id);
- port->debugfs_file = debugfs_create_file(debugfs_name, 0444,
- pdrvdata.debugfs_dir,
- port,
- &port_debugfs_fops);
- }
+ /*
+ * Finally, create the debugfs file that we can use to
+ * inspect a port's state at any time
+ */
+ snprintf(debugfs_name, sizeof(debugfs_name), "vport%up%u",
+ port->portdev->vdev->index, id);
+ port->debugfs_file = debugfs_create_file(debugfs_name, 0444,
+ pdrvdata.debugfs_dir,
+ port, &port_debugfs_fops);
return 0;
free_inbufs:
@@ -2244,8 +2241,6 @@ static int __init init(void)
}
pdrvdata.debugfs_dir = debugfs_create_dir("virtio-ports", NULL);
- if (!pdrvdata.debugfs_dir)
- pr_warn("Error creating debugfs dir for virtio-ports\n");
INIT_LIST_HEAD(&pdrvdata.consoles);
INIT_LIST_HEAD(&pdrvdata.portdevs);
diff --git a/drivers/firmware/google/gsmi.c b/drivers/firmware/google/gsmi.c
index 3d77f26c1e8c..bb6e77ee3898 100644
--- a/drivers/firmware/google/gsmi.c
+++ b/drivers/firmware/google/gsmi.c
@@ -136,12 +136,16 @@ MODULE_PARM_DESC(spincount,
"The number of loop iterations to use when using the spin handshake.");
/*
- * Platforms might not support S0ix logging in their GSMI handlers. In order to
- * avoid any side-effects of generating an SMI for S0ix logging, use the S0ix
- * related GSMI commands only for those platforms that explicitly enable this
- * option.
+ * Some older platforms with Apollo Lake chipsets do not support S0ix logging
+ * in their GSMI handlers, and behaved poorly when resuming via power button
+ * press if the logging was attempted. Updated firmware with proper behavior
+ * has long since shipped, removing the need for this opt-in parameter. It
+ * now exists as an opt-out parameter for folks defiantly running old
+ * firmware, or unforeseen circumstances. After the change from opt-in to
+ * opt-out has baked sufficiently, this parameter should probably be removed
+ * entirely.
*/
-static bool s0ix_logging_enable;
+static bool s0ix_logging_enable = true;
module_param(s0ix_logging_enable, bool, 0600);
static struct gsmi_buf *gsmi_buf_alloc(void)
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index 5ff9438b7b46..d591dd9b7c60 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -118,10 +118,17 @@ config XILINX_PR_DECOUPLER
depends on FPGA_BRIDGE
depends on HAS_IOMEM
help
- Say Y to enable drivers for Xilinx LogiCORE PR Decoupler.
+ Say Y to enable drivers for Xilinx LogiCORE PR Decoupler
+ or Xilinx Dynamic Function eXchnage AIX Shutdown Manager.
The PR Decoupler exists in the FPGA fabric to isolate one
region of the FPGA from the busses while that region is
being reprogrammed during partial reconfig.
+ The Dynamic Function eXchange AXI shutdown manager prevents
+ AXI traffic from passing through the bridge. The controller
+ safely handles AXI4MM and AXI4-Lite interfaces on a
+ Reconfigurable Partition when it is undergoing dynamic
+ reconfiguration, preventing the system deadlock that can
+ occur if AXI transactions are interrupted by DFX.
config FPGA_REGION
tristate "FPGA Region"
diff --git a/drivers/fpga/dfl-afu-error.c b/drivers/fpga/dfl-afu-error.c
index c4691187cca9..ab7be6217368 100644
--- a/drivers/fpga/dfl-afu-error.c
+++ b/drivers/fpga/dfl-afu-error.c
@@ -52,7 +52,7 @@ static int afu_port_err_clear(struct device *dev, u64 err)
struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
struct platform_device *pdev = to_platform_device(dev);
void __iomem *base_err, *base_hdr;
- int ret = -EBUSY;
+ int enable_ret = 0, ret = -EBUSY;
u64 v;
base_err = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_ERROR);
@@ -96,18 +96,20 @@ static int afu_port_err_clear(struct device *dev, u64 err)
v = readq(base_err + PORT_FIRST_ERROR);
writeq(v, base_err + PORT_FIRST_ERROR);
} else {
+ dev_warn(dev, "%s: received 0x%llx, expected 0x%llx\n",
+ __func__, v, err);
ret = -EINVAL;
}
/* Clear mask */
__afu_port_err_mask(dev, false);
- /* Enable the Port by clear the reset */
- __afu_port_enable(pdev);
+ /* Enable the Port by clearing the reset */
+ enable_ret = __afu_port_enable(pdev);
done:
mutex_unlock(&pdata->lock);
- return ret;
+ return enable_ret ? enable_ret : ret;
}
static ssize_t errors_show(struct device *dev, struct device_attribute *attr,
diff --git a/drivers/fpga/dfl-afu-main.c b/drivers/fpga/dfl-afu-main.c
index 753cda4b2568..7f621e96d3b8 100644
--- a/drivers/fpga/dfl-afu-main.c
+++ b/drivers/fpga/dfl-afu-main.c
@@ -21,6 +21,9 @@
#include "dfl-afu.h"
+#define RST_POLL_INVL 10 /* us */
+#define RST_POLL_TIMEOUT 1000 /* us */
+
/**
* __afu_port_enable - enable a port by clear reset
* @pdev: port platform device.
@@ -32,7 +35,7 @@
*
* The caller needs to hold lock for protection.
*/
-void __afu_port_enable(struct platform_device *pdev)
+int __afu_port_enable(struct platform_device *pdev)
{
struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
void __iomem *base;
@@ -41,7 +44,7 @@ void __afu_port_enable(struct platform_device *pdev)
WARN_ON(!pdata->disable_count);
if (--pdata->disable_count != 0)
- return;
+ return 0;
base = dfl_get_feature_ioaddr_by_id(&pdev->dev, PORT_FEATURE_ID_HEADER);
@@ -49,10 +52,20 @@ void __afu_port_enable(struct platform_device *pdev)
v = readq(base + PORT_HDR_CTRL);
v &= ~PORT_CTRL_SFTRST;
writeq(v, base + PORT_HDR_CTRL);
-}
-#define RST_POLL_INVL 10 /* us */
-#define RST_POLL_TIMEOUT 1000 /* us */
+ /*
+ * HW clears the ack bit to indicate that the port is fully out
+ * of reset.
+ */
+ if (readq_poll_timeout(base + PORT_HDR_CTRL, v,
+ !(v & PORT_CTRL_SFTRST_ACK),
+ RST_POLL_INVL, RST_POLL_TIMEOUT)) {
+ dev_err(&pdev->dev, "timeout, failure to enable device\n");
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
/**
* __afu_port_disable - disable a port by hold reset
@@ -86,7 +99,7 @@ int __afu_port_disable(struct platform_device *pdev)
if (readq_poll_timeout(base + PORT_HDR_CTRL, v,
v & PORT_CTRL_SFTRST_ACK,
RST_POLL_INVL, RST_POLL_TIMEOUT)) {
- dev_err(&pdev->dev, "timeout, fail to reset device\n");
+ dev_err(&pdev->dev, "timeout, failure to disable device\n");
return -ETIMEDOUT;
}
@@ -110,10 +123,10 @@ static int __port_reset(struct platform_device *pdev)
int ret;
ret = __afu_port_disable(pdev);
- if (!ret)
- __afu_port_enable(pdev);
+ if (ret)
+ return ret;
- return ret;
+ return __afu_port_enable(pdev);
}
static int port_reset(struct platform_device *pdev)
@@ -872,11 +885,11 @@ static int afu_dev_destroy(struct platform_device *pdev)
static int port_enable_set(struct platform_device *pdev, bool enable)
{
struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
- int ret = 0;
+ int ret;
mutex_lock(&pdata->lock);
if (enable)
- __afu_port_enable(pdev);
+ ret = __afu_port_enable(pdev);
else
ret = __afu_port_disable(pdev);
mutex_unlock(&pdata->lock);
diff --git a/drivers/fpga/dfl-afu.h b/drivers/fpga/dfl-afu.h
index 576e94960086..e5020e2b1f3d 100644
--- a/drivers/fpga/dfl-afu.h
+++ b/drivers/fpga/dfl-afu.h
@@ -80,7 +80,7 @@ struct dfl_afu {
};
/* hold pdata->lock when call __afu_port_enable/disable */
-void __afu_port_enable(struct platform_device *pdev);
+int __afu_port_enable(struct platform_device *pdev);
int __afu_port_disable(struct platform_device *pdev);
void afu_mmio_region_init(struct dfl_feature_platform_data *pdata);
diff --git a/drivers/fpga/dfl-pci.c b/drivers/fpga/dfl-pci.c
index 04e47e266f26..b44523ea8c91 100644
--- a/drivers/fpga/dfl-pci.c
+++ b/drivers/fpga/dfl-pci.c
@@ -69,14 +69,16 @@ static void cci_pci_free_irq(struct pci_dev *pcidev)
}
/* PCI Device ID */
-#define PCIE_DEVICE_ID_PF_INT_5_X 0xBCBD
-#define PCIE_DEVICE_ID_PF_INT_6_X 0xBCC0
-#define PCIE_DEVICE_ID_PF_DSC_1_X 0x09C4
-#define PCIE_DEVICE_ID_INTEL_PAC_N3000 0x0B30
+#define PCIE_DEVICE_ID_PF_INT_5_X 0xBCBD
+#define PCIE_DEVICE_ID_PF_INT_6_X 0xBCC0
+#define PCIE_DEVICE_ID_PF_DSC_1_X 0x09C4
+#define PCIE_DEVICE_ID_INTEL_PAC_N3000 0x0B30
+#define PCIE_DEVICE_ID_INTEL_PAC_D5005 0x0B2B
/* VF Device */
-#define PCIE_DEVICE_ID_VF_INT_5_X 0xBCBF
-#define PCIE_DEVICE_ID_VF_INT_6_X 0xBCC1
-#define PCIE_DEVICE_ID_VF_DSC_1_X 0x09C5
+#define PCIE_DEVICE_ID_VF_INT_5_X 0xBCBF
+#define PCIE_DEVICE_ID_VF_INT_6_X 0xBCC1
+#define PCIE_DEVICE_ID_VF_DSC_1_X 0x09C5
+#define PCIE_DEVICE_ID_INTEL_PAC_D5005_VF 0x0B2C
static struct pci_device_id cci_pcie_id_tbl[] = {
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_5_X),},
@@ -86,6 +88,8 @@ static struct pci_device_id cci_pcie_id_tbl[] = {
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_DSC_1_X),},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_DSC_1_X),},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_N3000),},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_D5005),},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_D5005_VF),},
{0,}
};
MODULE_DEVICE_TABLE(pci, cci_pcie_id_tbl);
diff --git a/drivers/fpga/xilinx-pr-decoupler.c b/drivers/fpga/xilinx-pr-decoupler.c
index 7d69af230567..ea2bde6e5bc4 100644
--- a/drivers/fpga/xilinx-pr-decoupler.c
+++ b/drivers/fpga/xilinx-pr-decoupler.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017, National Instruments Corp.
- * Copyright (c) 2017, Xilix Inc
+ * Copyright (c) 2017, Xilinx Inc
*
* FPGA Bridge Driver for the Xilinx LogiCORE Partial Reconfiguration
* Decoupler IP Core.
@@ -18,7 +18,12 @@
#define CTRL_CMD_COUPLE 0
#define CTRL_OFFSET 0
+struct xlnx_config_data {
+ const char *name;
+};
+
struct xlnx_pr_decoupler_data {
+ const struct xlnx_config_data *ipconfig;
void __iomem *io_base;
struct clk *clk;
};
@@ -76,15 +81,28 @@ static const struct fpga_bridge_ops xlnx_pr_decoupler_br_ops = {
.enable_show = xlnx_pr_decoupler_enable_show,
};
+static const struct xlnx_config_data decoupler_config = {
+ .name = "Xilinx PR Decoupler",
+};
+
+static const struct xlnx_config_data shutdown_config = {
+ .name = "Xilinx DFX AXI Shutdown Manager",
+};
+
static const struct of_device_id xlnx_pr_decoupler_of_match[] = {
- { .compatible = "xlnx,pr-decoupler-1.00", },
- { .compatible = "xlnx,pr-decoupler", },
+ { .compatible = "xlnx,pr-decoupler-1.00", .data = &decoupler_config },
+ { .compatible = "xlnx,pr-decoupler", .data = &decoupler_config },
+ { .compatible = "xlnx,dfx-axi-shutdown-manager-1.00",
+ .data = &shutdown_config },
+ { .compatible = "xlnx,dfx-axi-shutdown-manager",
+ .data = &shutdown_config },
{},
};
MODULE_DEVICE_TABLE(of, xlnx_pr_decoupler_of_match);
static int xlnx_pr_decoupler_probe(struct platform_device *pdev)
{
+ struct device_node *np = pdev->dev.of_node;
struct xlnx_pr_decoupler_data *priv;
struct fpga_bridge *br;
int err;
@@ -94,17 +112,23 @@ static int xlnx_pr_decoupler_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
+ if (np) {
+ const struct of_device_id *match;
+
+ match = of_match_node(xlnx_pr_decoupler_of_match, np);
+ if (match && match->data)
+ priv->ipconfig = match->data;
+ }
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
priv->io_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(priv->io_base))
return PTR_ERR(priv->io_base);
priv->clk = devm_clk_get(&pdev->dev, "aclk");
- if (IS_ERR(priv->clk)) {
- if (PTR_ERR(priv->clk) != -EPROBE_DEFER)
- dev_err(&pdev->dev, "input clock not found\n");
- return PTR_ERR(priv->clk);
- }
+ if (IS_ERR(priv->clk))
+ return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk),
+ "input clock not found\n");
err = clk_prepare_enable(priv->clk);
if (err) {
@@ -114,7 +138,7 @@ static int xlnx_pr_decoupler_probe(struct platform_device *pdev)
clk_disable(priv->clk);
- br = devm_fpga_bridge_create(&pdev->dev, "Xilinx PR Decoupler",
+ br = devm_fpga_bridge_create(&pdev->dev, priv->ipconfig->name,
&xlnx_pr_decoupler_br_ops, priv);
if (!br) {
err = -ENOMEM;
@@ -125,7 +149,8 @@ static int xlnx_pr_decoupler_probe(struct platform_device *pdev)
err = fpga_bridge_register(br);
if (err) {
- dev_err(&pdev->dev, "unable to register Xilinx PR Decoupler");
+ dev_err(&pdev->dev, "unable to register %s",
+ priv->ipconfig->name);
goto err_clk;
}
diff --git a/drivers/fpga/xilinx-spi.c b/drivers/fpga/xilinx-spi.c
index 27defa98092d..fee4d0abf6bf 100644
--- a/drivers/fpga/xilinx-spi.c
+++ b/drivers/fpga/xilinx-spi.c
@@ -233,25 +233,19 @@ static int xilinx_spi_probe(struct spi_device *spi)
/* PROGRAM_B is active low */
conf->prog_b = devm_gpiod_get(&spi->dev, "prog_b", GPIOD_OUT_LOW);
- if (IS_ERR(conf->prog_b)) {
- dev_err(&spi->dev, "Failed to get PROGRAM_B gpio: %ld\n",
- PTR_ERR(conf->prog_b));
- return PTR_ERR(conf->prog_b);
- }
+ if (IS_ERR(conf->prog_b))
+ return dev_err_probe(&spi->dev, PTR_ERR(conf->prog_b),
+ "Failed to get PROGRAM_B gpio\n");
conf->init_b = devm_gpiod_get_optional(&spi->dev, "init-b", GPIOD_IN);
- if (IS_ERR(conf->init_b)) {
- dev_err(&spi->dev, "Failed to get INIT_B gpio: %ld\n",
- PTR_ERR(conf->init_b));
- return PTR_ERR(conf->init_b);
- }
+ if (IS_ERR(conf->init_b))
+ return dev_err_probe(&spi->dev, PTR_ERR(conf->init_b),
+ "Failed to get INIT_B gpio\n");
conf->done = devm_gpiod_get(&spi->dev, "done", GPIOD_IN);
- if (IS_ERR(conf->done)) {
- dev_err(&spi->dev, "Failed to get DONE gpio: %ld\n",
- PTR_ERR(conf->done));
- return PTR_ERR(conf->done);
- }
+ if (IS_ERR(conf->done))
+ return dev_err_probe(&spi->dev, PTR_ERR(conf->done),
+ "Failed to get DONE gpio\n");
mgr = devm_fpga_mgr_create(&spi->dev,
"Xilinx Slave Serial FPGA Manager",
diff --git a/drivers/greybus/es2.c b/drivers/greybus/es2.c
index 48ad154df3a7..86a7fbc7fe13 100644
--- a/drivers/greybus/es2.c
+++ b/drivers/greybus/es2.c
@@ -1171,7 +1171,7 @@ static ssize_t apb_log_enable_read(struct file *f, char __user *buf,
char tmp_buf[3];
sprintf(tmp_buf, "%d\n", enable);
- return simple_read_from_buffer(buf, count, ppos, tmp_buf, 3);
+ return simple_read_from_buffer(buf, count, ppos, tmp_buf, 2);
}
static ssize_t apb_log_enable_write(struct file *f, const char __user *buf,
diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index 0062c8935653..b57bea167102 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -86,7 +86,7 @@ static int coresight_id_match(struct device *dev, void *data)
i_csdev->type != CORESIGHT_DEV_TYPE_SOURCE)
return 0;
- /* Get the source ID for both compoment */
+ /* Get the source ID for both components */
trace_id = source_ops(csdev)->trace_id(csdev);
i_trace_id = source_ops(i_csdev)->trace_id(i_csdev);
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index 0f603b4094f2..bdbb77334329 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -58,7 +58,7 @@ static ssize_t format_attr_contextid_show(struct device *dev,
return sprintf(page, "config:%d\n", pid_fmt);
}
-struct device_attribute format_attr_contextid =
+static struct device_attribute format_attr_contextid =
__ATTR(contextid, 0444, format_attr_contextid_show, NULL);
static struct attribute *etm_config_formats_attr[] = {
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 15016f757828..a5b13a7779c3 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -1951,6 +1951,7 @@ static const struct amba_id etm4_ids[] = {
CS_AMBA_UCI_ID(0x000bbd05, uci_id_etm4),/* Cortex-A55 */
CS_AMBA_UCI_ID(0x000bbd0a, uci_id_etm4),/* Cortex-A75 */
CS_AMBA_UCI_ID(0x000bbd0c, uci_id_etm4),/* Neoverse N1 */
+ CS_AMBA_UCI_ID(0x000bbd41, uci_id_etm4),/* Cortex-A78 */
CS_AMBA_UCI_ID(0x000f0205, uci_id_etm4),/* Qualcomm Kryo */
CS_AMBA_UCI_ID(0x000f0211, uci_id_etm4),/* Qualcomm Kryo */
CS_AMBA_UCI_ID(0x000bb802, uci_id_etm4),/* Qualcomm Kryo 385 Cortex-A55 */
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index f532c59bb59b..f4fb5c52b863 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -402,6 +402,16 @@ config SRAM
config SRAM_EXEC
bool
+config DW_XDATA_PCIE
+ depends on PCI
+ tristate "Synopsys DesignWare xData PCIe driver"
+ help
+ This driver allows controlling Synopsys DesignWare PCIe traffic
+ generator IP also known as xData, present in Synopsys DesignWare
+ PCIe Endpoint prototype.
+
+ If unsure, say N.
+
config PCI_ENDPOINT_TEST
depends on PCI
select CRC32
@@ -427,14 +437,6 @@ config MISC_RTSX
tristate
default MISC_RTSX_PCI || MISC_RTSX_USB
-config PVPANIC
- tristate "pvpanic device support"
- depends on HAS_IOMEM && (ACPI || OF)
- help
- This driver provides support for the pvpanic device. pvpanic is
- a paravirtualized device provided by QEMU; it lets a virtual machine
- (guest) communicate panic events to the host.
-
config HISI_HIKEY_USB
tristate "USB GPIO Hub on HiSilicon Hikey 960/970 Platform"
depends on (OF && GPIOLIB) || COMPILE_TEST
@@ -461,4 +463,5 @@ source "drivers/misc/bcm-vk/Kconfig"
source "drivers/misc/cardreader/Kconfig"
source "drivers/misc/habanalabs/Kconfig"
source "drivers/misc/uacce/Kconfig"
+source "drivers/misc/pvpanic/Kconfig"
endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 99b6f15a3c70..e92a56d4442f 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -47,11 +47,12 @@ obj-$(CONFIG_SRAM_EXEC) += sram-exec.o
obj-$(CONFIG_GENWQE) += genwqe/
obj-$(CONFIG_ECHO) += echo/
obj-$(CONFIG_CXL_BASE) += cxl/
+obj-$(CONFIG_DW_XDATA_PCIE) += dw-xdata-pcie.o
obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o
obj-$(CONFIG_OCXL) += ocxl/
obj-$(CONFIG_BCM_VK) += bcm-vk/
obj-y += cardreader/
-obj-$(CONFIG_PVPANIC) += pvpanic.o
+obj-$(CONFIG_PVPANIC) += pvpanic/
obj-$(CONFIG_HABANA_AI) += habanalabs/
obj-$(CONFIG_UACCE) += uacce/
obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o
diff --git a/drivers/misc/ad525x_dpot.c b/drivers/misc/ad525x_dpot.c
index 6f164522b028..5d8f3f6a95f2 100644
--- a/drivers/misc/ad525x_dpot.c
+++ b/drivers/misc/ad525x_dpot.c
@@ -139,6 +139,9 @@ static s32 dpot_read_spi(struct dpot_data *dpot, u8 reg)
value = dpot_read_r8d8(dpot,
DPOT_AD5291_READ_RDAC << 2);
+ if (value < 0)
+ return value;
+
if (dpot->uid == DPOT_UID(AD5291_ID))
value = value >> 2;
diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c
index fb2eff69e449..e627b4056623 100644
--- a/drivers/misc/cxl/context.c
+++ b/drivers/misc/cxl/context.c
@@ -52,7 +52,7 @@ int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master)
* can always access it when dereferenced from IDR. For the same
* reason, the segment table is only destroyed after the context is
* removed from the IDR. Access to this in the IOCTL is protected by
- * Linux filesytem symantics (can't IOCTL until open is complete).
+ * Linux filesystem semantics (can't IOCTL until open is complete).
*/
i = cxl_alloc_sst(ctx);
if (i)
diff --git a/drivers/misc/cxl/fault.c b/drivers/misc/cxl/fault.c
index 01153b74334a..60c829113299 100644
--- a/drivers/misc/cxl/fault.c
+++ b/drivers/misc/cxl/fault.c
@@ -200,7 +200,7 @@ static struct mm_struct *get_mem_context(struct cxl_context *ctx)
if (ctx->mm == NULL)
return NULL;
- if (!atomic_inc_not_zero(&ctx->mm->mm_users))
+ if (!mmget_not_zero(ctx->mm))
return NULL;
return ctx->mm;
diff --git a/drivers/misc/dw-xdata-pcie.c b/drivers/misc/dw-xdata-pcie.c
new file mode 100644
index 000000000000..257c25da5199
--- /dev/null
+++ b/drivers/misc/dw-xdata-pcie.c
@@ -0,0 +1,420 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 Synopsys, Inc. and/or its affiliates.
+ * Synopsys DesignWare xData driver
+ *
+ * Author: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
+ */
+
+#include <linux/miscdevice.h>
+#include <linux/bitfield.h>
+#include <linux/pci-epf.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/bitops.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+
+#define DW_XDATA_DRIVER_NAME "dw-xdata-pcie"
+
+#define DW_XDATA_EP_MEM_OFFSET 0x8000000
+
+static DEFINE_IDA(xdata_ida);
+
+#define STATUS_DONE BIT(0)
+
+#define CONTROL_DOORBELL BIT(0)
+#define CONTROL_IS_WRITE BIT(1)
+#define CONTROL_LENGTH(a) FIELD_PREP(GENMASK(13, 2), a)
+#define CONTROL_PATTERN_INC BIT(16)
+#define CONTROL_NO_ADDR_INC BIT(18)
+
+#define XPERF_CONTROL_ENABLE BIT(5)
+
+#define BURST_REPEAT BIT(31)
+#define BURST_VALUE 0x1001
+
+#define PATTERN_VALUE 0x0
+
+struct dw_xdata_regs {
+ u32 addr_lsb; /* 0x000 */
+ u32 addr_msb; /* 0x004 */
+ u32 burst_cnt; /* 0x008 */
+ u32 control; /* 0x00c */
+ u32 pattern; /* 0x010 */
+ u32 status; /* 0x014 */
+ u32 RAM_addr; /* 0x018 */
+ u32 RAM_port; /* 0x01c */
+ u32 _reserved0[14]; /* 0x020..0x054 */
+ u32 perf_control; /* 0x058 */
+ u32 _reserved1[41]; /* 0x05c..0x0fc */
+ u32 wr_cnt_lsb; /* 0x100 */
+ u32 wr_cnt_msb; /* 0x104 */
+ u32 rd_cnt_lsb; /* 0x108 */
+ u32 rd_cnt_msb; /* 0x10c */
+} __packed;
+
+struct dw_xdata_region {
+ phys_addr_t paddr; /* physical address */
+ void __iomem *vaddr; /* virtual address */
+};
+
+struct dw_xdata {
+ struct dw_xdata_region rg_region; /* registers */
+ size_t max_wr_len; /* max wr xfer len */
+ size_t max_rd_len; /* max rd xfer len */
+ struct mutex mutex;
+ struct pci_dev *pdev;
+ struct miscdevice misc_dev;
+};
+
+static inline struct dw_xdata_regs __iomem *__dw_regs(struct dw_xdata *dw)
+{
+ return dw->rg_region.vaddr;
+}
+
+static void dw_xdata_stop(struct dw_xdata *dw)
+{
+ u32 burst;
+
+ mutex_lock(&dw->mutex);
+
+ burst = readl(&(__dw_regs(dw)->burst_cnt));
+
+ if (burst & BURST_REPEAT) {
+ burst &= ~(u32)BURST_REPEAT;
+ writel(burst, &(__dw_regs(dw)->burst_cnt));
+ }
+
+ mutex_unlock(&dw->mutex);
+}
+
+static void dw_xdata_start(struct dw_xdata *dw, bool write)
+{
+ struct device *dev = &dw->pdev->dev;
+ u32 control, status;
+
+ /* Stop first if xfer in progress */
+ dw_xdata_stop(dw);
+
+ mutex_lock(&dw->mutex);
+
+ /* Clear status register */
+ writel(0x0, &(__dw_regs(dw)->status));
+
+ /* Burst count register set for continuous until stopped */
+ writel(BURST_REPEAT | BURST_VALUE, &(__dw_regs(dw)->burst_cnt));
+
+ /* Pattern register */
+ writel(PATTERN_VALUE, &(__dw_regs(dw)->pattern));
+
+ /* Control register */
+ control = CONTROL_DOORBELL | CONTROL_PATTERN_INC | CONTROL_NO_ADDR_INC;
+ if (write) {
+ control |= CONTROL_IS_WRITE;
+ control |= CONTROL_LENGTH(dw->max_wr_len);
+ } else {
+ control |= CONTROL_LENGTH(dw->max_rd_len);
+ }
+ writel(control, &(__dw_regs(dw)->control));
+
+ /*
+ * The xData HW block needs about 100 ms to initiate the traffic
+ * generation according this HW block datasheet.
+ */
+ usleep_range(100, 150);
+
+ status = readl(&(__dw_regs(dw)->status));
+
+ mutex_unlock(&dw->mutex);
+
+ if (!(status & STATUS_DONE))
+ dev_dbg(dev, "xData: started %s direction\n",
+ write ? "write" : "read");
+}
+
+static void dw_xdata_perf_meas(struct dw_xdata *dw, u64 *data, bool write)
+{
+ if (write) {
+ *data = readl(&(__dw_regs(dw)->wr_cnt_msb));
+ *data <<= 32;
+ *data |= readl(&(__dw_regs(dw)->wr_cnt_lsb));
+ } else {
+ *data = readl(&(__dw_regs(dw)->rd_cnt_msb));
+ *data <<= 32;
+ *data |= readl(&(__dw_regs(dw)->rd_cnt_lsb));
+ }
+}
+
+static u64 dw_xdata_perf_diff(u64 *m1, u64 *m2, u64 time)
+{
+ u64 rate = (*m1 - *m2);
+
+ rate *= (1000 * 1000 * 1000);
+ rate >>= 20;
+ rate = DIV_ROUND_CLOSEST_ULL(rate, time);
+
+ return rate;
+}
+
+static void dw_xdata_perf(struct dw_xdata *dw, u64 *rate, bool write)
+{
+ struct device *dev = &dw->pdev->dev;
+ u64 data[2], time[2], diff;
+
+ mutex_lock(&dw->mutex);
+
+ /* First acquisition of current count frames */
+ writel(0x0, &(__dw_regs(dw)->perf_control));
+ dw_xdata_perf_meas(dw, &data[0], write);
+ time[0] = jiffies;
+ writel((u32)XPERF_CONTROL_ENABLE, &(__dw_regs(dw)->perf_control));
+
+ /*
+ * Wait 100ms between the 1st count frame acquisition and the 2nd
+ * count frame acquisition, in order to calculate the speed later
+ */
+ mdelay(100);
+
+ /* Second acquisition of current count frames */
+ writel(0x0, &(__dw_regs(dw)->perf_control));
+ dw_xdata_perf_meas(dw, &data[1], write);
+ time[1] = jiffies;
+ writel((u32)XPERF_CONTROL_ENABLE, &(__dw_regs(dw)->perf_control));
+
+ /*
+ * Speed calculation
+ *
+ * rate = (2nd count frames - 1st count frames) / (time elapsed)
+ */
+ diff = jiffies_to_nsecs(time[1] - time[0]);
+ *rate = dw_xdata_perf_diff(&data[1], &data[0], diff);
+
+ mutex_unlock(&dw->mutex);
+
+ dev_dbg(dev, "xData: time=%llu us, %s=%llu MB/s\n",
+ diff, write ? "write" : "read", *rate);
+}
+
+static struct dw_xdata *misc_dev_to_dw(struct miscdevice *misc_dev)
+{
+ return container_of(misc_dev, struct dw_xdata, misc_dev);
+}
+
+static ssize_t write_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct miscdevice *misc_dev = dev_get_drvdata(dev);
+ struct dw_xdata *dw = misc_dev_to_dw(misc_dev);
+ u64 rate;
+
+ dw_xdata_perf(dw, &rate, true);
+
+ return sysfs_emit(buf, "%llu\n", rate);
+}
+
+static ssize_t write_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct miscdevice *misc_dev = dev_get_drvdata(dev);
+ struct dw_xdata *dw = misc_dev_to_dw(misc_dev);
+ bool enabled;
+ int ret;
+
+ ret = kstrtobool(buf, &enabled);
+ if (ret < 0)
+ return ret;
+
+ if (enabled) {
+ dev_dbg(dev, "xData: requested write transfer\n");
+ dw_xdata_start(dw, true);
+ } else {
+ dev_dbg(dev, "xData: requested stop transfer\n");
+ dw_xdata_stop(dw);
+ }
+
+ return size;
+}
+
+static DEVICE_ATTR_RW(write);
+
+static ssize_t read_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct miscdevice *misc_dev = dev_get_drvdata(dev);
+ struct dw_xdata *dw = misc_dev_to_dw(misc_dev);
+ u64 rate;
+
+ dw_xdata_perf(dw, &rate, false);
+
+ return sysfs_emit(buf, "%llu\n", rate);
+}
+
+static ssize_t read_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct miscdevice *misc_dev = dev_get_drvdata(dev);
+ struct dw_xdata *dw = misc_dev_to_dw(misc_dev);
+ bool enabled;
+ int ret;
+
+ ret = kstrtobool(buf, &enabled);
+ if (ret < 0)
+ return ret;
+
+ if (enabled) {
+ dev_dbg(dev, "xData: requested read transfer\n");
+ dw_xdata_start(dw, false);
+ } else {
+ dev_dbg(dev, "xData: requested stop transfer\n");
+ dw_xdata_stop(dw);
+ }
+
+ return size;
+}
+
+static DEVICE_ATTR_RW(read);
+
+static struct attribute *xdata_attrs[] = {
+ &dev_attr_write.attr,
+ &dev_attr_read.attr,
+ NULL,
+};
+
+ATTRIBUTE_GROUPS(xdata);
+
+static int dw_xdata_pcie_probe(struct pci_dev *pdev,
+ const struct pci_device_id *pid)
+{
+ struct device *dev = &pdev->dev;
+ struct dw_xdata *dw;
+ char name[24];
+ u64 addr;
+ int err;
+ int id;
+
+ /* Enable PCI device */
+ err = pcim_enable_device(pdev);
+ if (err) {
+ dev_err(dev, "enabling device failed\n");
+ return err;
+ }
+
+ /* Mapping PCI BAR regions */
+ err = pcim_iomap_regions(pdev, BIT(BAR_0), pci_name(pdev));
+ if (err) {
+ dev_err(dev, "xData BAR I/O remapping failed\n");
+ return err;
+ }
+
+ pci_set_master(pdev);
+
+ /* Allocate memory */
+ dw = devm_kzalloc(dev, sizeof(*dw), GFP_KERNEL);
+ if (!dw)
+ return -ENOMEM;
+
+ /* Data structure initialization */
+ mutex_init(&dw->mutex);
+
+ dw->rg_region.vaddr = pcim_iomap_table(pdev)[BAR_0];
+ if (!dw->rg_region.vaddr)
+ return -ENOMEM;
+
+ dw->rg_region.paddr = pdev->resource[BAR_0].start;
+
+ dw->max_wr_len = pcie_get_mps(pdev);
+ dw->max_wr_len >>= 2;
+
+ dw->max_rd_len = pcie_get_readrq(pdev);
+ dw->max_rd_len >>= 2;
+
+ dw->pdev = pdev;
+
+ id = ida_simple_get(&xdata_ida, 0, 0, GFP_KERNEL);
+ if (id < 0) {
+ dev_err(dev, "xData: unable to get id\n");
+ return id;
+ }
+
+ snprintf(name, sizeof(name), DW_XDATA_DRIVER_NAME ".%d", id);
+ dw->misc_dev.name = kstrdup(name, GFP_KERNEL);
+ if (!dw->misc_dev.name) {
+ err = -ENOMEM;
+ goto err_ida_remove;
+ }
+
+ dw->misc_dev.minor = MISC_DYNAMIC_MINOR;
+ dw->misc_dev.parent = dev;
+ dw->misc_dev.groups = xdata_groups;
+
+ writel(0x0, &(__dw_regs(dw)->RAM_addr));
+ writel(0x0, &(__dw_regs(dw)->RAM_port));
+
+ addr = dw->rg_region.paddr + DW_XDATA_EP_MEM_OFFSET;
+ writel(lower_32_bits(addr), &(__dw_regs(dw)->addr_lsb));
+ writel(upper_32_bits(addr), &(__dw_regs(dw)->addr_msb));
+ dev_dbg(dev, "xData: target address = 0x%.16llx\n", addr);
+
+ dev_dbg(dev, "xData: wr_len = %zu, rd_len = %zu\n",
+ dw->max_wr_len * 4, dw->max_rd_len * 4);
+
+ /* Saving data structure reference */
+ pci_set_drvdata(pdev, dw);
+
+ /* Register misc device */
+ err = misc_register(&dw->misc_dev);
+ if (err) {
+ dev_err(dev, "xData: failed to register device\n");
+ goto err_kfree_name;
+ }
+
+ return 0;
+
+err_kfree_name:
+ kfree(dw->misc_dev.name);
+
+err_ida_remove:
+ ida_simple_remove(&xdata_ida, id);
+
+ return err;
+}
+
+static void dw_xdata_pcie_remove(struct pci_dev *pdev)
+{
+ struct dw_xdata *dw = pci_get_drvdata(pdev);
+ int id;
+
+ if (sscanf(dw->misc_dev.name, DW_XDATA_DRIVER_NAME ".%d", &id) != 1)
+ return;
+
+ if (id < 0)
+ return;
+
+ dw_xdata_stop(dw);
+ misc_deregister(&dw->misc_dev);
+ kfree(dw->misc_dev.name);
+ ida_simple_remove(&xdata_ida, id);
+}
+
+static const struct pci_device_id dw_xdata_pcie_id_table[] = {
+ { PCI_DEVICE_DATA(SYNOPSYS, EDDA, NULL) },
+ { }
+};
+MODULE_DEVICE_TABLE(pci, dw_xdata_pcie_id_table);
+
+static struct pci_driver dw_xdata_pcie_driver = {
+ .name = DW_XDATA_DRIVER_NAME,
+ .id_table = dw_xdata_pcie_id_table,
+ .probe = dw_xdata_pcie_probe,
+ .remove = dw_xdata_pcie_remove,
+};
+
+module_pci_driver(dw_xdata_pcie_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Synopsys DesignWare xData PCIe driver");
+MODULE_AUTHOR("Gustavo Pimentel <gustavo.pimentel@synopsys.com>");
+
diff --git a/drivers/misc/genwqe/card_ddcb.c b/drivers/misc/genwqe/card_ddcb.c
index 0db4000dedf2..500b1feaf1f6 100644
--- a/drivers/misc/genwqe/card_ddcb.c
+++ b/drivers/misc/genwqe/card_ddcb.c
@@ -316,7 +316,7 @@ static int enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_queue *queue,
/**
* copy_ddcb_results() - Copy output state from real DDCB to request
- * @req: pointer to requsted DDCB parameters
+ * @req: pointer to requested DDCB parameters
* @ddcb_no: pointer to ddcb number being tapped
*
* Copy DDCB ASV to request struct. There is no endian
@@ -356,7 +356,7 @@ static void copy_ddcb_results(struct ddcb_requ *req, int ddcb_no)
}
/**
- * genwqe_check_ddcb_queue() - Checks DDCB queue for completed work equests.
+ * genwqe_check_ddcb_queue() - Checks DDCB queue for completed work requests.
* @cd: pointer to genwqe device descriptor
* @queue: queue to be checked
*
@@ -498,7 +498,7 @@ int __genwqe_wait_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req)
/*
* We need to distinguish 3 cases here:
- * 1. rc == 0 timeout occured
+ * 1. rc == 0 timeout occurred
* 2. rc == -ERESTARTSYS signal received
* 3. rc > 0 remaining jiffies condition is true
*/
@@ -982,7 +982,7 @@ static int genwqe_next_ddcb_ready(struct genwqe_dev *cd)
spin_lock_irqsave(&queue->ddcb_lock, flags);
- if (queue_empty(queue)) { /* emtpy queue */
+ if (queue_empty(queue)) { /* empty queue */
spin_unlock_irqrestore(&queue->ddcb_lock, flags);
return 0;
}
@@ -1002,7 +1002,7 @@ static int genwqe_next_ddcb_ready(struct genwqe_dev *cd)
* @cd: pointer to genwqe device descriptor
*
* Keep track on the number of DDCBs which ware currently in the
- * queue. This is needed for statistics as well as conditon if we want
+ * queue. This is needed for statistics as well as condition if we want
* to wait or better do polling in case of no interrupts available.
*/
int genwqe_ddcbs_in_flight(struct genwqe_dev *cd)
diff --git a/drivers/misc/kgdbts.c b/drivers/misc/kgdbts.c
index 945701bce553..64d33e368509 100644
--- a/drivers/misc/kgdbts.c
+++ b/drivers/misc/kgdbts.c
@@ -92,22 +92,23 @@
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/sched/task.h>
+#include <linux/kallsyms.h>
#include <asm/sections.h>
-#define v1printk(a...) do { \
- if (verbose) \
- printk(KERN_INFO a); \
- } while (0)
-#define v2printk(a...) do { \
- if (verbose > 1) \
- printk(KERN_INFO a); \
- touch_nmi_watchdog(); \
- } while (0)
-#define eprintk(a...) do { \
- printk(KERN_ERR a); \
- WARN_ON(1); \
- } while (0)
+#define v1printk(a...) do { \
+ if (verbose) \
+ printk(KERN_INFO a); \
+} while (0)
+#define v2printk(a...) do { \
+ if (verbose > 1) \
+ printk(KERN_INFO a); \
+ touch_nmi_watchdog(); \
+} while (0)
+#define eprintk(a...) do { \
+ printk(KERN_ERR a); \
+ WARN_ON(1); \
+} while (0)
#define MAX_CONFIG_LEN 40
static struct kgdb_io kgdbts_io_ops;
@@ -200,21 +201,30 @@ static noinline void kgdbts_break_test(void)
v2printk("kgdbts: breakpoint complete\n");
}
-/* Lookup symbol info in the kernel */
+/*
+ * This is a cached wrapper for kallsyms_lookup_name().
+ *
+ * The cache is a big win for several tests. For example it more the doubles
+ * the cycles per second during the sys_open test. This is not theoretic,
+ * the performance improvement shows up at human scale, especially when
+ * testing using emulators.
+ *
+ * Obviously neither re-entrant nor thread-safe but that is OK since it
+ * can only be called from the debug trap (and therefore all other CPUs
+ * are halted).
+ */
static unsigned long lookup_addr(char *arg)
{
- unsigned long addr = 0;
-
- if (!strcmp(arg, "kgdbts_break_test"))
- addr = (unsigned long)kgdbts_break_test;
- else if (!strcmp(arg, "sys_open"))
- addr = (unsigned long)do_sys_open;
- else if (!strcmp(arg, "kernel_clone"))
- addr = (unsigned long)kernel_clone;
- else if (!strcmp(arg, "hw_break_val"))
- addr = (unsigned long)&hw_break_val;
- addr = (unsigned long) dereference_function_descriptor((void *)addr);
- return addr;
+ static char cached_arg[KSYM_NAME_LEN];
+ static unsigned long cached_addr;
+
+ if (strcmp(arg, cached_arg)) {
+ strscpy(cached_arg, arg, KSYM_NAME_LEN);
+ cached_addr = kallsyms_lookup_name(arg);
+ }
+
+ return (unsigned long)dereference_function_descriptor(
+ (void *)cached_addr);
}
static void break_helper(char *bp_type, char *arg, unsigned long vaddr)
@@ -310,7 +320,7 @@ static int check_and_rewind_pc(char *put_str, char *arg)
if (arch_needs_sstep_emulation && sstep_addr &&
ip + offset == sstep_addr &&
- ((!strcmp(arg, "sys_open") || !strcmp(arg, "kernel_clone")))) {
+ ((!strcmp(arg, "do_sys_openat2") || !strcmp(arg, "kernel_clone")))) {
/* This is special case for emulated single step */
v2printk("Emul: rewind hit single step bp\n");
restart_from_top_after_write = 1;
@@ -619,14 +629,14 @@ static struct test_struct do_kernel_clone_test[] = {
*/
static struct test_struct sys_open_test[] = {
{ "?", "S0*" }, /* Clear break points */
- { "sys_open", "OK", sw_break, }, /* set sw breakpoint */
+ { "do_sys_openat2", "OK", sw_break, }, /* set sw breakpoint */
{ "c", "T0*", NULL, get_thread_id_continue }, /* Continue */
- { "sys_open", "OK", sw_rem_break }, /*remove breakpoint */
- { "g", "sys_open", NULL, check_and_rewind_pc }, /* check location */
+ { "do_sys_openat2", "OK", sw_rem_break }, /*remove breakpoint */
+ { "g", "do_sys_openat2", NULL, check_and_rewind_pc }, /* check location */
{ "write", "OK", write_regs, emul_reset }, /* Write registers */
{ "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */
- { "g", "sys_open", NULL, check_single_step },
- { "sys_open", "OK", sw_break, }, /* set sw breakpoint */
+ { "g", "do_sys_openat2", NULL, check_single_step },
+ { "do_sys_openat2", "OK", sw_break, }, /* set sw breakpoint */
{ "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */
{ "D", "OK", NULL, final_ack_set }, /* detach and unregister I/O */
{ "", "", get_cont_catch, put_cont_catch },
diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c
index dd65cedf3b12..70c5bb1e6f49 100644
--- a/drivers/misc/lis3lv02d/lis3lv02d.c
+++ b/drivers/misc/lis3lv02d/lis3lv02d.c
@@ -208,7 +208,7 @@ static int lis3_3dc_rates[16] = {0, 1, 10, 25, 50, 100, 200, 400, 1600, 5000};
static int lis3_3dlh_rates[4] = {50, 100, 400, 1000};
/* ODR is Output Data Rate */
-static int lis3lv02d_get_odr(struct lis3lv02d *lis3)
+static int lis3lv02d_get_odr_index(struct lis3lv02d *lis3)
{
u8 ctrl;
int shift;
@@ -216,15 +216,23 @@ static int lis3lv02d_get_odr(struct lis3lv02d *lis3)
lis3->read(lis3, CTRL_REG1, &ctrl);
ctrl &= lis3->odr_mask;
shift = ffs(lis3->odr_mask) - 1;
- return lis3->odrs[(ctrl >> shift)];
+ return (ctrl >> shift);
}
static int lis3lv02d_get_pwron_wait(struct lis3lv02d *lis3)
{
- int div = lis3lv02d_get_odr(lis3);
+ int odr_idx = lis3lv02d_get_odr_index(lis3);
+ int div = lis3->odrs[odr_idx];
- if (WARN_ONCE(div == 0, "device returned spurious data"))
+ if (div == 0) {
+ if (odr_idx == 0) {
+ /* Power-down mode, not sampling no need to sleep */
+ return 0;
+ }
+
+ dev_err(&lis3->pdev->dev, "Error unknown odrs-index: %d\n", odr_idx);
return -ENXIO;
+ }
/* LIS3 power on delay is quite long */
msleep(lis3->pwron_delay / div);
@@ -816,9 +824,12 @@ static ssize_t lis3lv02d_rate_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct lis3lv02d *lis3 = dev_get_drvdata(dev);
+ int odr_idx;
lis3lv02d_sysfs_poweron(lis3);
- return sprintf(buf, "%d\n", lis3lv02d_get_odr(lis3));
+
+ odr_idx = lis3lv02d_get_odr_index(lis3);
+ return sprintf(buf, "%d\n", lis3->odrs[odr_idx]);
}
static ssize_t lis3lv02d_rate_set(struct device *dev,
@@ -1162,16 +1173,14 @@ int lis3lv02d_init_device(struct lis3lv02d *lis3)
break;
default:
pr_err("unknown sensor type 0x%X\n", lis3->whoami);
- return -EINVAL;
+ return -ENODEV;
}
lis3->reg_cache = kzalloc(max(sizeof(lis3_wai8_regs),
sizeof(lis3_wai12_regs)), GFP_KERNEL);
- if (lis3->reg_cache == NULL) {
- printk(KERN_ERR DRIVER_NAME "out of memory\n");
+ if (lis3->reg_cache == NULL)
return -ENOMEM;
- }
mutex_init(&lis3->mutex);
atomic_set(&lis3->wake_thread, 0);
diff --git a/drivers/misc/pvpanic/Kconfig b/drivers/misc/pvpanic/Kconfig
new file mode 100644
index 000000000000..12d40a21f698
--- /dev/null
+++ b/drivers/misc/pvpanic/Kconfig
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Pvpanic Kconfig
+#
+# Copyright (C) 2021 Oracle.
+#
+
+config PVPANIC
+ bool "pvpanic device support"
+ help
+ This option allows to select a specific pvpanic device driver.
+ pvpanic is a paravirtualized device provided by QEMU; it lets
+ a virtual machine (guest) communicate panic events to the host.
+
+config PVPANIC_MMIO
+ tristate "pvpanic MMIO device support"
+ depends on HAS_IOMEM && (ACPI || OF) && PVPANIC
+ help
+ This driver provides support for the MMIO pvpanic device.
+
+config PVPANIC_PCI
+ tristate "pvpanic PCI device support"
+ depends on PCI && PVPANIC
+ help
+ This driver provides support for the PCI pvpanic device.
+ pvpanic is a paravirtualized device provided by QEMU which
+ forwards the panic events from the guest to the host.
diff --git a/drivers/misc/pvpanic/Makefile b/drivers/misc/pvpanic/Makefile
new file mode 100644
index 000000000000..9471df7d4f9c
--- /dev/null
+++ b/drivers/misc/pvpanic/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Pvpanic Makefile
+#
+# Copyright (C) 2021 Oracle.
+#
+obj-$(CONFIG_PVPANIC_MMIO) += pvpanic.o pvpanic-mmio.o
+obj-$(CONFIG_PVPANIC_PCI) += pvpanic.o pvpanic-pci.o
diff --git a/drivers/misc/pvpanic.c b/drivers/misc/pvpanic/pvpanic-mmio.c
index f1655f5ca016..4c0841776087 100644
--- a/drivers/misc/pvpanic.c
+++ b/drivers/misc/pvpanic/pvpanic-mmio.c
@@ -1,13 +1,12 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Pvpanic Device Support
+ * Pvpanic MMIO Device Support
*
* Copyright (C) 2013 Fujitsu.
* Copyright (C) 2018 ZTE.
+ * Copyright (C) 2021 Oracle.
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/kexec.h>
@@ -15,28 +14,36 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/types.h>
+#include <linux/slab.h>
#include <uapi/misc/pvpanic.h>
-static void __iomem *base;
-static unsigned int capability = PVPANIC_PANICKED | PVPANIC_CRASH_LOADED;
-static unsigned int events;
+#include "pvpanic.h"
+
+MODULE_AUTHOR("Hu Tao <hutao@cn.fujitsu.com>");
+MODULE_DESCRIPTION("pvpanic-mmio device driver");
+MODULE_LICENSE("GPL");
static ssize_t capability_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- return sysfs_emit(buf, "%x\n", capability);
+ struct pvpanic_instance *pi = dev_get_drvdata(dev);
+
+ return sysfs_emit(buf, "%x\n", pi->capability);
}
static DEVICE_ATTR_RO(capability);
static ssize_t events_show(struct device *dev, struct device_attribute *attr, char *buf)
{
- return sysfs_emit(buf, "%x\n", events);
+ struct pvpanic_instance *pi = dev_get_drvdata(dev);
+
+ return sysfs_emit(buf, "%x\n", pi->events);
}
static ssize_t events_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
+ struct pvpanic_instance *pi = dev_get_drvdata(dev);
unsigned int tmp;
int err;
@@ -44,57 +51,28 @@ static ssize_t events_store(struct device *dev, struct device_attribute *attr,
if (err)
return err;
- if ((tmp & capability) != tmp)
+ if ((tmp & pi->capability) != tmp)
return -EINVAL;
- events = tmp;
+ pi->events = tmp;
return count;
-
}
static DEVICE_ATTR_RW(events);
-static struct attribute *pvpanic_dev_attrs[] = {
+static struct attribute *pvpanic_mmio_dev_attrs[] = {
&dev_attr_capability.attr,
&dev_attr_events.attr,
NULL
};
-ATTRIBUTE_GROUPS(pvpanic_dev);
-
-MODULE_AUTHOR("Hu Tao <hutao@cn.fujitsu.com>");
-MODULE_DESCRIPTION("pvpanic device driver");
-MODULE_LICENSE("GPL");
-
-static void
-pvpanic_send_event(unsigned int event)
-{
- if (event & capability & events)
- iowrite8(event, base);
-}
-
-static int
-pvpanic_panic_notify(struct notifier_block *nb, unsigned long code,
- void *unused)
-{
- unsigned int event = PVPANIC_PANICKED;
-
- if (kexec_crash_loaded())
- event = PVPANIC_CRASH_LOADED;
-
- pvpanic_send_event(event);
-
- return NOTIFY_DONE;
-}
-
-static struct notifier_block pvpanic_panic_nb = {
- .notifier_call = pvpanic_panic_notify,
- .priority = 1, /* let this called before broken drm_fb_helper */
-};
+ATTRIBUTE_GROUPS(pvpanic_mmio_dev);
static int pvpanic_mmio_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
+ struct pvpanic_instance *pi;
struct resource *res;
+ void __iomem *base;
res = platform_get_mem_or_io(pdev, 0);
if (!res)
@@ -115,23 +93,28 @@ static int pvpanic_mmio_probe(struct platform_device *pdev)
return -EINVAL;
}
+ pi = kmalloc(sizeof(*pi), GFP_ATOMIC);
+ if (!pi)
+ return -ENOMEM;
+
+ pi->base = base;
+ pi->capability = PVPANIC_PANICKED | PVPANIC_CRASH_LOADED;
+
/* initlize capability by RDPT */
- capability &= ioread8(base);
- events = capability;
+ pi->capability &= ioread8(base);
+ pi->events = pi->capability;
- if (capability)
- atomic_notifier_chain_register(&panic_notifier_list,
- &pvpanic_panic_nb);
+ dev_set_drvdata(dev, pi);
- return 0;
+ return pvpanic_probe(pi);
}
static int pvpanic_mmio_remove(struct platform_device *pdev)
{
+ struct pvpanic_instance *pi = dev_get_drvdata(&pdev->dev);
- if (capability)
- atomic_notifier_chain_unregister(&panic_notifier_list,
- &pvpanic_panic_nb);
+ pvpanic_remove(pi);
+ kfree(pi);
return 0;
}
@@ -153,7 +136,7 @@ static struct platform_driver pvpanic_mmio_driver = {
.name = "pvpanic-mmio",
.of_match_table = pvpanic_mmio_match,
.acpi_match_table = pvpanic_device_ids,
- .dev_groups = pvpanic_dev_groups,
+ .dev_groups = pvpanic_mmio_dev_groups,
},
.probe = pvpanic_mmio_probe,
.remove = pvpanic_mmio_remove,
diff --git a/drivers/misc/pvpanic/pvpanic-pci.c b/drivers/misc/pvpanic/pvpanic-pci.c
new file mode 100644
index 000000000000..9ecc4e8559d5
--- /dev/null
+++ b/drivers/misc/pvpanic/pvpanic-pci.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Pvpanic PCI Device Support
+ *
+ * Copyright (C) 2021 Oracle.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+
+#include <uapi/misc/pvpanic.h>
+
+#include "pvpanic.h"
+
+#define PCI_VENDOR_ID_REDHAT 0x1b36
+#define PCI_DEVICE_ID_REDHAT_PVPANIC 0x0011
+
+MODULE_AUTHOR("Mihai Carabas <mihai.carabas@oracle.com>");
+MODULE_DESCRIPTION("pvpanic device driver ");
+MODULE_LICENSE("GPL");
+
+static const struct pci_device_id pvpanic_pci_id_tbl[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_REDHAT, PCI_DEVICE_ID_REDHAT_PVPANIC)},
+ {}
+};
+
+static ssize_t capability_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct pvpanic_instance *pi = dev_get_drvdata(dev);
+
+ return sysfs_emit(buf, "%x\n", pi->capability);
+}
+static DEVICE_ATTR_RO(capability);
+
+static ssize_t events_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct pvpanic_instance *pi = dev_get_drvdata(dev);
+
+ return sysfs_emit(buf, "%x\n", pi->events);
+}
+
+static ssize_t events_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct pvpanic_instance *pi = dev_get_drvdata(dev);
+ unsigned int tmp;
+ int err;
+
+ err = kstrtouint(buf, 16, &tmp);
+ if (err)
+ return err;
+
+ if ((tmp & pi->capability) != tmp)
+ return -EINVAL;
+
+ pi->events = tmp;
+
+ return count;
+}
+static DEVICE_ATTR_RW(events);
+
+static struct attribute *pvpanic_pci_dev_attrs[] = {
+ &dev_attr_capability.attr,
+ &dev_attr_events.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(pvpanic_pci_dev);
+
+static int pvpanic_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ struct device *dev = &pdev->dev;
+ struct pvpanic_instance *pi;
+ void __iomem *base;
+ int ret;
+
+ ret = pci_enable_device(pdev);
+ if (ret < 0)
+ return ret;
+
+ base = pci_iomap(pdev, 0, 0);
+ if (!base)
+ return -ENOMEM;
+
+ pi = kmalloc(sizeof(*pi), GFP_ATOMIC);
+ if (!pi)
+ return -ENOMEM;
+
+ pi->base = base;
+ pi->capability = PVPANIC_PANICKED | PVPANIC_CRASH_LOADED;
+
+ /* initlize capability by RDPT */
+ pi->capability &= ioread8(base);
+ pi->events = pi->capability;
+
+ dev_set_drvdata(dev, pi);
+
+ return pvpanic_probe(pi);
+}
+
+static void pvpanic_pci_remove(struct pci_dev *pdev)
+{
+ struct pvpanic_instance *pi = dev_get_drvdata(&pdev->dev);
+
+ pvpanic_remove(pi);
+ iounmap(pi->base);
+ kfree(pi);
+ pci_disable_device(pdev);
+}
+
+static struct pci_driver pvpanic_pci_driver = {
+ .name = "pvpanic-pci",
+ .id_table = pvpanic_pci_id_tbl,
+ .probe = pvpanic_pci_probe,
+ .remove = pvpanic_pci_remove,
+ .driver = {
+ .dev_groups = pvpanic_pci_dev_groups,
+ },
+};
+
+module_pci_driver(pvpanic_pci_driver);
diff --git a/drivers/misc/pvpanic/pvpanic.c b/drivers/misc/pvpanic/pvpanic.c
new file mode 100644
index 000000000000..65f70a4da8c0
--- /dev/null
+++ b/drivers/misc/pvpanic/pvpanic.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Pvpanic Device Support
+ *
+ * Copyright (C) 2013 Fujitsu.
+ * Copyright (C) 2018 ZTE.
+ * Copyright (C) 2021 Oracle.
+ */
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/kexec.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/cdev.h>
+#include <linux/list.h>
+
+#include <uapi/misc/pvpanic.h>
+
+#include "pvpanic.h"
+
+MODULE_AUTHOR("Mihai Carabas <mihai.carabas@oracle.com>");
+MODULE_DESCRIPTION("pvpanic device driver ");
+MODULE_LICENSE("GPL");
+
+static struct list_head pvpanic_list;
+static spinlock_t pvpanic_lock;
+
+static void
+pvpanic_send_event(unsigned int event)
+{
+ struct pvpanic_instance *pi_cur;
+
+ spin_lock(&pvpanic_lock);
+ list_for_each_entry(pi_cur, &pvpanic_list, list) {
+ if (event & pi_cur->capability & pi_cur->events)
+ iowrite8(event, pi_cur->base);
+ }
+ spin_unlock(&pvpanic_lock);
+}
+
+static int
+pvpanic_panic_notify(struct notifier_block *nb, unsigned long code,
+ void *unused)
+{
+ unsigned int event = PVPANIC_PANICKED;
+
+ if (kexec_crash_loaded())
+ event = PVPANIC_CRASH_LOADED;
+
+ pvpanic_send_event(event);
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block pvpanic_panic_nb = {
+ .notifier_call = pvpanic_panic_notify,
+ .priority = 1, /* let this called before broken drm_fb_helper */
+};
+
+int pvpanic_probe(struct pvpanic_instance *pi)
+{
+ if (!pi || !pi->base)
+ return -EINVAL;
+
+ spin_lock(&pvpanic_lock);
+ list_add(&pi->list, &pvpanic_list);
+ spin_unlock(&pvpanic_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(pvpanic_probe);
+
+void pvpanic_remove(struct pvpanic_instance *pi)
+{
+ struct pvpanic_instance *pi_cur, *pi_next;
+
+ if (!pi)
+ return;
+
+ spin_lock(&pvpanic_lock);
+ list_for_each_entry_safe(pi_cur, pi_next, &pvpanic_list, list) {
+ if (pi_cur == pi) {
+ list_del(&pi_cur->list);
+ break;
+ }
+ }
+ spin_unlock(&pvpanic_lock);
+}
+EXPORT_SYMBOL_GPL(pvpanic_remove);
+
+static int pvpanic_init(void)
+{
+ INIT_LIST_HEAD(&pvpanic_list);
+ spin_lock_init(&pvpanic_lock);
+
+ atomic_notifier_chain_register(&panic_notifier_list,
+ &pvpanic_panic_nb);
+
+ return 0;
+}
+
+static void pvpanic_exit(void)
+{
+ atomic_notifier_chain_unregister(&panic_notifier_list,
+ &pvpanic_panic_nb);
+
+}
+
+module_init(pvpanic_init);
+module_exit(pvpanic_exit);
diff --git a/drivers/misc/pvpanic/pvpanic.h b/drivers/misc/pvpanic/pvpanic.h
new file mode 100644
index 000000000000..1afccc2e9fec
--- /dev/null
+++ b/drivers/misc/pvpanic/pvpanic.h
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Pvpanic Device Support
+ *
+ * Copyright (C) 2021 Oracle.
+ */
+
+#ifndef PVPANIC_H_
+#define PVPANIC_H_
+
+struct pvpanic_instance {
+ void __iomem *base;
+ unsigned int capability;
+ unsigned int events;
+ struct list_head list;
+};
+
+int pvpanic_probe(struct pvpanic_instance *pi);
+void pvpanic_remove(struct pvpanic_instance *pi);
+
+#endif /* PVPANIC_H_ */
diff --git a/drivers/misc/sgi-xp/xp_main.c b/drivers/misc/sgi-xp/xp_main.c
index cf2965aa5c05..87d156c15f35 100644
--- a/drivers/misc/sgi-xp/xp_main.c
+++ b/drivers/misc/sgi-xp/xp_main.c
@@ -21,11 +21,11 @@
/* define the XP debug device structures to be used with dev_dbg() et al */
-struct device_driver xp_dbg_name = {
+static struct device_driver xp_dbg_name = {
.name = "xp"
};
-struct device xp_dbg_subname = {
+static struct device xp_dbg_subname = {
.init_name = "", /* set to "" */
.driver = &xp_dbg_name
};
diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c
index 84610bbcc131..b2c3c22fc13c 100644
--- a/drivers/misc/sgi-xp/xpc_main.c
+++ b/drivers/misc/sgi-xp/xpc_main.c
@@ -207,7 +207,7 @@ xpc_start_hb_beater(void)
{
xpc_arch_ops.heartbeat_init();
timer_setup(&xpc_hb_timer, xpc_hb_beater, 0);
- xpc_hb_beater(0);
+ xpc_hb_beater(NULL);
}
static void
diff --git a/drivers/misc/uacce/uacce.c b/drivers/misc/uacce/uacce.c
index d07af4edfcac..94843e0e51c6 100644
--- a/drivers/misc/uacce/uacce.c
+++ b/drivers/misc/uacce/uacce.c
@@ -126,7 +126,7 @@ static int uacce_fops_open(struct inode *inode, struct file *filep)
{
struct uacce_device *uacce;
struct uacce_queue *q;
- int ret = 0;
+ int ret;
uacce = xa_load(&uacce_xa, iminor(inode));
if (!uacce)
diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c
index b837e7eba5f7..f1d8ba6d4857 100644
--- a/drivers/misc/vmw_balloon.c
+++ b/drivers/misc/vmw_balloon.c
@@ -346,11 +346,6 @@ struct vmballoon {
/* statistics */
struct vmballoon_stats *stats;
-#ifdef CONFIG_DEBUG_FS
- /* debugfs file exporting statistics */
- struct dentry *dbg_entry;
-#endif
-
/**
* @b_dev_info: balloon device information descriptor.
*/
@@ -1709,14 +1704,14 @@ DEFINE_SHOW_ATTRIBUTE(vmballoon_debug);
static void __init vmballoon_debugfs_init(struct vmballoon *b)
{
- b->dbg_entry = debugfs_create_file("vmmemctl", S_IRUGO, NULL, b,
- &vmballoon_debug_fops);
+ debugfs_create_file("vmmemctl", S_IRUGO, NULL, b,
+ &vmballoon_debug_fops);
}
static void __exit vmballoon_debugfs_exit(struct vmballoon *b)
{
static_key_disable(&balloon_stat_enabled.key);
- debugfs_remove(b->dbg_entry);
+ debugfs_remove(debugfs_lookup("vmmemctl", NULL));
kfree(b->stats);
b->stats = NULL;
}
diff --git a/drivers/misc/vmw_vmci/vmci_doorbell.c b/drivers/misc/vmw_vmci/vmci_doorbell.c
index 345addd9306d..fa8a7fce4481 100644
--- a/drivers/misc/vmw_vmci/vmci_doorbell.c
+++ b/drivers/misc/vmw_vmci/vmci_doorbell.c
@@ -326,7 +326,7 @@ int vmci_dbell_host_context_notify(u32 src_cid, struct vmci_handle handle)
bool vmci_dbell_register_notification_bitmap(u64 bitmap_ppn)
{
int result;
- struct vmci_notify_bm_set_msg bitmap_set_msg;
+ struct vmci_notify_bm_set_msg bitmap_set_msg = { };
bitmap_set_msg.hdr.dst = vmci_make_handle(VMCI_HYPERVISOR_CONTEXT_ID,
VMCI_SET_NOTIFY_BITMAP);
diff --git a/drivers/misc/vmw_vmci/vmci_guest.c b/drivers/misc/vmw_vmci/vmci_guest.c
index cc8eeb361fcd..1018dc77269d 100644
--- a/drivers/misc/vmw_vmci/vmci_guest.c
+++ b/drivers/misc/vmw_vmci/vmci_guest.c
@@ -168,7 +168,7 @@ static int vmci_check_host_caps(struct pci_dev *pdev)
VMCI_UTIL_NUM_RESOURCES * sizeof(u32);
struct vmci_datagram *check_msg;
- check_msg = kmalloc(msg_size, GFP_KERNEL);
+ check_msg = kzalloc(msg_size, GFP_KERNEL);
if (!check_msg) {
dev_err(&pdev->dev, "%s: Insufficient memory\n", __func__);
return -ENOMEM;
diff --git a/drivers/misc/vmw_vmci/vmci_host.c b/drivers/misc/vmw_vmci/vmci_host.c
index 2d8328d928d5..da1e2a773823 100644
--- a/drivers/misc/vmw_vmci/vmci_host.c
+++ b/drivers/misc/vmw_vmci/vmci_host.c
@@ -908,7 +908,7 @@ static long vmci_host_unlocked_ioctl(struct file *filp,
unsigned int iocmd, unsigned long ioarg)
{
#define VMCI_DO_IOCTL(ioctl_name, ioctl_fn) do { \
- char *name = __stringify(IOCTL_VMCI_ ## ioctl_name); \
+ char *name = "IOCTL_VMCI_" # ioctl_name; \
return vmci_host_do_ ## ioctl_fn( \
vmci_host_dev, name, uptr); \
} while (0)
diff --git a/drivers/most/most_cdev.c b/drivers/most/most_cdev.c
index 044880760b58..8908b9363a96 100644
--- a/drivers/most/most_cdev.c
+++ b/drivers/most/most_cdev.c
@@ -44,8 +44,8 @@ struct comp_channel {
};
#define to_channel(d) container_of(d, struct comp_channel, cdev)
-static struct list_head channel_list;
-static spinlock_t ch_list_lock;
+static LIST_HEAD(channel_list);
+static DEFINE_SPINLOCK(ch_list_lock);
static inline bool ch_has_mbo(struct comp_channel *c)
{
@@ -494,8 +494,6 @@ static int __init mod_init(void)
if (IS_ERR(comp.class))
return PTR_ERR(comp.class);
- INIT_LIST_HEAD(&channel_list);
- spin_lock_init(&ch_list_lock);
ida_init(&comp.minor_id);
err = alloc_chrdev_region(&comp.devno, 0, CHRDEV_REGION_SIZE, "cdev");
diff --git a/drivers/mux/gpio.c b/drivers/mux/gpio.c
index 02c1f2c014e8..cc5f2c1861d4 100644
--- a/drivers/mux/gpio.c
+++ b/drivers/mux/gpio.c
@@ -7,11 +7,12 @@
* Author: Peter Rosin <peda@axentia.se>
*/
+#include <linux/bitmap.h>
#include <linux/err.h>
#include <linux/gpio/consumer.h>
+#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/mux/driver.h>
-#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/property.h>
@@ -23,8 +24,9 @@ static int mux_gpio_set(struct mux_control *mux, int state)
{
struct mux_gpio *mux_gpio = mux_chip_priv(mux->chip);
DECLARE_BITMAP(values, BITS_PER_TYPE(state));
+ u32 value = state;
- values[0] = state;
+ bitmap_from_arr32(values, &value, BITS_PER_TYPE(value));
gpiod_set_array_value_cansleep(mux_gpio->gpios->ndescs,
mux_gpio->gpios->desc,
@@ -64,14 +66,11 @@ static int mux_gpio_probe(struct platform_device *pdev)
mux_chip->ops = &mux_gpio_ops;
mux_gpio->gpios = devm_gpiod_get_array(dev, "mux", GPIOD_OUT_LOW);
- if (IS_ERR(mux_gpio->gpios)) {
- ret = PTR_ERR(mux_gpio->gpios);
- if (ret != -EPROBE_DEFER)
- dev_err(dev, "failed to get gpios\n");
- return ret;
- }
+ if (IS_ERR(mux_gpio->gpios))
+ return dev_err_probe(dev, PTR_ERR(mux_gpio->gpios),
+ "failed to get gpios\n");
WARN_ON(pins != mux_gpio->gpios->ndescs);
- mux_chip->mux->states = 1 << pins;
+ mux_chip->mux->states = BIT(pins);
ret = device_property_read_u32(dev, "idle-state", (u32 *)&idle_state);
if (ret >= 0 && idle_state != MUX_IDLE_AS_IS) {
@@ -96,7 +95,7 @@ static int mux_gpio_probe(struct platform_device *pdev)
static struct platform_driver mux_gpio_driver = {
.driver = {
.name = "gpio-mux",
- .of_match_table = of_match_ptr(mux_gpio_dt_ids),
+ .of_match_table = mux_gpio_dt_ids,
},
.probe = mux_gpio_probe,
};
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 75d2594c16e1..dd2019006838 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -272,10 +272,20 @@ config SPRD_EFUSE
config NVMEM_RMEM
tristate "Reserved Memory Based Driver Support"
+ depends on HAS_IOMEM
help
This driver maps reserved memory into an nvmem device. It might be
useful to expose information left by firmware in memory.
This driver can also be built as a module. If so, the module
will be called nvmem-rmem.
+
+config NVMEM_BRCM_NVRAM
+ tristate "Broadcom's NVRAM support"
+ depends on ARCH_BCM_5301X || COMPILE_TEST
+ depends on HAS_IOMEM
+ help
+ This driver provides support for Broadcom's NVRAM that can be accessed
+ using I/O mapping.
+
endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 5376b8e0dae5..bbea1410240a 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -57,3 +57,5 @@ obj-$(CONFIG_SPRD_EFUSE) += nvmem_sprd_efuse.o
nvmem_sprd_efuse-y := sprd-efuse.o
obj-$(CONFIG_NVMEM_RMEM) += nvmem-rmem.o
nvmem-rmem-y := rmem.o
+obj-$(CONFIG_NVMEM_BRCM_NVRAM) += nvmem_brcm_nvram.o
+nvmem_brcm_nvram-y := brcm_nvram.o
diff --git a/drivers/nvmem/brcm_nvram.c b/drivers/nvmem/brcm_nvram.c
new file mode 100644
index 000000000000..bd2ecaaf4585
--- /dev/null
+++ b/drivers/nvmem/brcm_nvram.c
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 Rafał Miłecki <rafal@milecki.pl>
+ */
+
+#include <linux/io.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/platform_device.h>
+
+struct brcm_nvram {
+ struct device *dev;
+ void __iomem *base;
+};
+
+static int brcm_nvram_read(void *context, unsigned int offset, void *val,
+ size_t bytes)
+{
+ struct brcm_nvram *priv = context;
+ u8 *dst = val;
+
+ while (bytes--)
+ *dst++ = readb(priv->base + offset++);
+
+ return 0;
+}
+
+static int brcm_nvram_probe(struct platform_device *pdev)
+{
+ struct nvmem_config config = {
+ .name = "brcm-nvram",
+ .reg_read = brcm_nvram_read,
+ };
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ struct brcm_nvram *priv;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+ priv->dev = dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ priv->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(priv->base))
+ return PTR_ERR(priv->base);
+
+ config.dev = dev;
+ config.priv = priv;
+ config.size = resource_size(res);
+
+ return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
+}
+
+static const struct of_device_id brcm_nvram_of_match_table[] = {
+ { .compatible = "brcm,nvram", },
+ {},
+};
+
+static struct platform_driver brcm_nvram_driver = {
+ .probe = brcm_nvram_probe,
+ .driver = {
+ .name = "brcm_nvram",
+ .of_match_table = brcm_nvram_of_match_table,
+ },
+};
+
+static int __init brcm_nvram_init(void)
+{
+ return platform_driver_register(&brcm_nvram_driver);
+}
+
+subsys_initcall_sync(brcm_nvram_init);
+
+MODULE_AUTHOR("Rafał Miłecki");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(of, brcm_nvram_of_match_table);
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index a5ab1e0c74cf..bca671ff4e54 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -1606,6 +1606,101 @@ int nvmem_cell_read_u64(struct device *dev, const char *cell_id, u64 *val)
}
EXPORT_SYMBOL_GPL(nvmem_cell_read_u64);
+static void *nvmem_cell_read_variable_common(struct device *dev,
+ const char *cell_id,
+ size_t max_len, size_t *len)
+{
+ struct nvmem_cell *cell;
+ int nbits;
+ void *buf;
+
+ cell = nvmem_cell_get(dev, cell_id);
+ if (IS_ERR(cell))
+ return cell;
+
+ nbits = cell->nbits;
+ buf = nvmem_cell_read(cell, len);
+ nvmem_cell_put(cell);
+ if (IS_ERR(buf))
+ return buf;
+
+ /*
+ * If nbits is set then nvmem_cell_read() can significantly exaggerate
+ * the length of the real data. Throw away the extra junk.
+ */
+ if (nbits)
+ *len = DIV_ROUND_UP(nbits, 8);
+
+ if (*len > max_len) {
+ kfree(buf);
+ return ERR_PTR(-ERANGE);
+ }
+
+ return buf;
+}
+
+/**
+ * nvmem_cell_read_variable_le_u32() - Read up to 32-bits of data as a little endian number.
+ *
+ * @dev: Device that requests the nvmem cell.
+ * @cell_id: Name of nvmem cell to read.
+ * @val: pointer to output value.
+ *
+ * Return: 0 on success or negative errno.
+ */
+int nvmem_cell_read_variable_le_u32(struct device *dev, const char *cell_id,
+ u32 *val)
+{
+ size_t len;
+ u8 *buf;
+ int i;
+
+ buf = nvmem_cell_read_variable_common(dev, cell_id, sizeof(*val), &len);
+ if (IS_ERR(buf))
+ return PTR_ERR(buf);
+
+ /* Copy w/ implicit endian conversion */
+ *val = 0;
+ for (i = 0; i < len; i++)
+ *val |= buf[i] << (8 * i);
+
+ kfree(buf);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(nvmem_cell_read_variable_le_u32);
+
+/**
+ * nvmem_cell_read_variable_le_u64() - Read up to 64-bits of data as a little endian number.
+ *
+ * @dev: Device that requests the nvmem cell.
+ * @cell_id: Name of nvmem cell to read.
+ * @val: pointer to output value.
+ *
+ * Return: 0 on success or negative errno.
+ */
+int nvmem_cell_read_variable_le_u64(struct device *dev, const char *cell_id,
+ u64 *val)
+{
+ size_t len;
+ u8 *buf;
+ int i;
+
+ buf = nvmem_cell_read_variable_common(dev, cell_id, sizeof(*val), &len);
+ if (IS_ERR(buf))
+ return PTR_ERR(buf);
+
+ /* Copy w/ implicit endian conversion */
+ *val = 0;
+ for (i = 0; i < len; i++)
+ *val |= (uint64_t)buf[i] << (8 * i);
+
+ kfree(buf);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(nvmem_cell_read_variable_le_u64);
+
/**
* nvmem_device_cell_read() - Read a given nvmem device and cell
*
diff --git a/drivers/nvmem/qcom-spmi-sdam.c b/drivers/nvmem/qcom-spmi-sdam.c
index f6e9f96933ca..4fcb63507ecd 100644
--- a/drivers/nvmem/qcom-spmi-sdam.c
+++ b/drivers/nvmem/qcom-spmi-sdam.c
@@ -141,7 +141,7 @@ static int sdam_probe(struct platform_device *pdev)
sdam->sdam_config.dev = &pdev->dev;
sdam->sdam_config.name = "spmi_sdam";
sdam->sdam_config.id = NVMEM_DEVID_AUTO;
- sdam->sdam_config.owner = THIS_MODULE,
+ sdam->sdam_config.owner = THIS_MODULE;
sdam->sdam_config.stride = 1;
sdam->sdam_config.word_size = 1;
sdam->sdam_config.reg_read = sdam_read;
diff --git a/drivers/nvmem/qfprom.c b/drivers/nvmem/qfprom.c
index 6cace24dfbf7..d6d3f24685a8 100644
--- a/drivers/nvmem/qfprom.c
+++ b/drivers/nvmem/qfprom.c
@@ -45,11 +45,13 @@ MODULE_PARM_DESC(read_raw_data, "Read raw instead of corrected data");
* @qfprom_blow_timer_value: The timer value of qfprom when doing efuse blow.
* @qfprom_blow_set_freq: The frequency required to set when we start the
* fuse blowing.
+ * @qfprom_blow_uV: LDO voltage to be set when doing efuse blow
*/
struct qfprom_soc_data {
u32 accel_value;
u32 qfprom_blow_timer_value;
u32 qfprom_blow_set_freq;
+ int qfprom_blow_uV;
};
/**
@@ -111,6 +113,15 @@ static const struct qfprom_soc_compatible_data sc7180_qfprom = {
.nkeepout = ARRAY_SIZE(sc7180_qfprom_keepout)
};
+static const struct nvmem_keepout sc7280_qfprom_keepout[] = {
+ {.start = 0x128, .end = 0x148},
+ {.start = 0x238, .end = 0x248}
+};
+
+static const struct qfprom_soc_compatible_data sc7280_qfprom = {
+ .keepout = sc7280_qfprom_keepout,
+ .nkeepout = ARRAY_SIZE(sc7280_qfprom_keepout)
+};
/**
* qfprom_disable_fuse_blowing() - Undo enabling of fuse blowing.
* @priv: Our driver data.
@@ -127,6 +138,16 @@ static void qfprom_disable_fuse_blowing(const struct qfprom_priv *priv,
{
int ret;
+ /*
+ * This may be a shared rail and may be able to run at a lower rate
+ * when we're not blowing fuses. At the moment, the regulator framework
+ * applies voltage constraints even on disabled rails, so remove our
+ * constraints and allow the rail to be adjusted by other users.
+ */
+ ret = regulator_set_voltage(priv->vcc, 0, INT_MAX);
+ if (ret)
+ dev_warn(priv->dev, "Failed to set 0 voltage (ignoring)\n");
+
ret = regulator_disable(priv->vcc);
if (ret)
dev_warn(priv->dev, "Failed to disable regulator (ignoring)\n");
@@ -158,6 +179,7 @@ static int qfprom_enable_fuse_blowing(const struct qfprom_priv *priv,
struct qfprom_touched_values *old)
{
int ret;
+ int qfprom_blow_uV = priv->soc_data->qfprom_blow_uV;
ret = clk_prepare_enable(priv->secclk);
if (ret) {
@@ -172,6 +194,17 @@ static int qfprom_enable_fuse_blowing(const struct qfprom_priv *priv,
goto err_clk_prepared;
}
+ /*
+ * Hardware requires 1.8V min for fuse blowing; this may be
+ * a rail shared do don't specify a max--regulator constraints
+ * will handle.
+ */
+ ret = regulator_set_voltage(priv->vcc, qfprom_blow_uV, INT_MAX);
+ if (ret) {
+ dev_err(priv->dev, "Failed to set %duV\n", qfprom_blow_uV);
+ goto err_clk_rate_set;
+ }
+
ret = regulator_enable(priv->vcc);
if (ret) {
dev_err(priv->dev, "Failed to enable regulator\n");
@@ -290,6 +323,14 @@ static const struct qfprom_soc_data qfprom_7_8_data = {
.accel_value = 0xD10,
.qfprom_blow_timer_value = 25,
.qfprom_blow_set_freq = 4800000,
+ .qfprom_blow_uV = 1800000,
+};
+
+static const struct qfprom_soc_data qfprom_7_15_data = {
+ .accel_value = 0xD08,
+ .qfprom_blow_timer_value = 24,
+ .qfprom_blow_set_freq = 4800000,
+ .qfprom_blow_uV = 1900000,
};
static int qfprom_probe(struct platform_device *pdev)
@@ -358,6 +399,8 @@ static int qfprom_probe(struct platform_device *pdev)
if (major_version == 7 && minor_version == 8)
priv->soc_data = &qfprom_7_8_data;
+ if (major_version == 7 && minor_version == 15)
+ priv->soc_data = &qfprom_7_15_data;
priv->vcc = devm_regulator_get(&pdev->dev, "vcc");
if (IS_ERR(priv->vcc))
@@ -384,6 +427,7 @@ static int qfprom_probe(struct platform_device *pdev)
static const struct of_device_id qfprom_of_match[] = {
{ .compatible = "qcom,qfprom",},
{ .compatible = "qcom,sc7180-qfprom", .data = &sc7180_qfprom},
+ { .compatible = "qcom,sc7280-qfprom", .data = &sc7280_qfprom},
{/* sentinel */},
};
MODULE_DEVICE_TABLE(of, qfprom_of_match);
diff --git a/drivers/nvmem/snvs_lpgpr.c b/drivers/nvmem/snvs_lpgpr.c
index c527d26ca6ac..4692aa985bd6 100644
--- a/drivers/nvmem/snvs_lpgpr.c
+++ b/drivers/nvmem/snvs_lpgpr.c
@@ -123,7 +123,7 @@ static int snvs_lpgpr_probe(struct platform_device *pdev)
cfg->dev = dev;
cfg->stride = 4;
cfg->word_size = 4;
- cfg->size = dcfg->size,
+ cfg->size = dcfg->size;
cfg->owner = THIS_MODULE;
cfg->reg_read = snvs_lpgpr_read;
cfg->reg_write = snvs_lpgpr_write;
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 68d9c2f6a5ca..54c1f2f0985f 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -71,6 +71,7 @@ source "drivers/phy/ingenic/Kconfig"
source "drivers/phy/lantiq/Kconfig"
source "drivers/phy/marvell/Kconfig"
source "drivers/phy/mediatek/Kconfig"
+source "drivers/phy/microchip/Kconfig"
source "drivers/phy/motorola/Kconfig"
source "drivers/phy/mscc/Kconfig"
source "drivers/phy/qualcomm/Kconfig"
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 32261e164abd..adac1b1a39d1 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -20,6 +20,7 @@ obj-y += allwinner/ \
lantiq/ \
marvell/ \
mediatek/ \
+ microchip/ \
motorola/ \
mscc/ \
qualcomm/ \
diff --git a/drivers/phy/broadcom/Kconfig b/drivers/phy/broadcom/Kconfig
index 09256339bd04..fd92b73b7109 100644
--- a/drivers/phy/broadcom/Kconfig
+++ b/drivers/phy/broadcom/Kconfig
@@ -94,7 +94,7 @@ config PHY_BRCM_USB
depends on ARCH_BCM4908 || ARCH_BRCMSTB || COMPILE_TEST
depends on OF
select GENERIC_PHY
- select SOC_BRCMSTB
+ select SOC_BRCMSTB if ARCH_BRCMSTB
default ARCH_BCM4908
default ARCH_BRCMSTB
help
diff --git a/drivers/phy/cadence/Kconfig b/drivers/phy/cadence/Kconfig
index 432832bdbd16..a62910ff5591 100644
--- a/drivers/phy/cadence/Kconfig
+++ b/drivers/phy/cadence/Kconfig
@@ -7,6 +7,7 @@ config PHY_CADENCE_TORRENT
tristate "Cadence Torrent PHY driver"
depends on OF
depends on HAS_IOMEM
+ depends on COMMON_CLK
select GENERIC_PHY
help
Support for Cadence Torrent PHY.
@@ -24,6 +25,7 @@ config PHY_CADENCE_DPHY
config PHY_CADENCE_SIERRA
tristate "Cadence Sierra PHY Driver"
depends on OF && HAS_IOMEM && RESET_CONTROLLER
+ depends on COMMON_CLK
select GENERIC_PHY
help
Enable this to support the Cadence Sierra PHY driver
diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c
index 26a0badabe38..5c68e31c5939 100644
--- a/drivers/phy/cadence/phy-cadence-sierra.c
+++ b/drivers/phy/cadence/phy-cadence-sierra.c
@@ -7,6 +7,7 @@
*
*/
#include <linux/clk.h>
+#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/io.h>
@@ -20,10 +21,12 @@
#include <linux/of.h>
#include <linux/of_platform.h>
#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/phy/phy-cadence.h>
/* PHY register offsets */
#define SIERRA_COMMON_CDB_OFFSET 0x0
#define SIERRA_MACRO_ID_REG 0x0
+#define SIERRA_CMN_PLLLC_GEN_PREG 0x42
#define SIERRA_CMN_PLLLC_MODE_PREG 0x48
#define SIERRA_CMN_PLLLC_LF_COEFF_MODE1_PREG 0x49
#define SIERRA_CMN_PLLLC_LF_COEFF_MODE0_PREG 0x4A
@@ -31,6 +34,9 @@
#define SIERRA_CMN_PLLLC_BWCAL_MODE1_PREG 0x4F
#define SIERRA_CMN_PLLLC_BWCAL_MODE0_PREG 0x50
#define SIERRA_CMN_PLLLC_SS_TIME_STEPSIZE_MODE_PREG 0x62
+#define SIERRA_CMN_REFRCV_PREG 0x98
+#define SIERRA_CMN_REFRCV1_PREG 0xB8
+#define SIERRA_CMN_PLLLC1_GEN_PREG 0xC2
#define SIERRA_LANE_CDB_OFFSET(ln, block_offset, reg_offset) \
((0x4000 << (block_offset)) + \
@@ -144,6 +150,19 @@
#define SIERRA_MAX_LANES 16
#define PLL_LOCK_TIME 100000
+#define CDNS_SIERRA_OUTPUT_CLOCKS 2
+#define CDNS_SIERRA_INPUT_CLOCKS 5
+enum cdns_sierra_clock_input {
+ PHY_CLK,
+ CMN_REFCLK_DIG_DIV,
+ CMN_REFCLK1_DIG_DIV,
+ PLL0_REFCLK,
+ PLL1_REFCLK,
+};
+
+#define SIERRA_NUM_CMN_PLLC 2
+#define SIERRA_NUM_CMN_PLLC_PARENTS 2
+
static const struct reg_field macro_id_type =
REG_FIELD(SIERRA_MACRO_ID_REG, 0, 15);
static const struct reg_field phy_pll_cfg_1 =
@@ -151,6 +170,53 @@ static const struct reg_field phy_pll_cfg_1 =
static const struct reg_field pllctrl_lock =
REG_FIELD(SIERRA_PLLCTRL_STATUS_PREG, 0, 0);
+static const char * const clk_names[] = {
+ [CDNS_SIERRA_PLL_CMNLC] = "pll_cmnlc",
+ [CDNS_SIERRA_PLL_CMNLC1] = "pll_cmnlc1",
+};
+
+enum cdns_sierra_cmn_plllc {
+ CMN_PLLLC,
+ CMN_PLLLC1,
+};
+
+struct cdns_sierra_pll_mux_reg_fields {
+ struct reg_field pfdclk_sel_preg;
+ struct reg_field plllc1en_field;
+ struct reg_field termen_field;
+};
+
+static const struct cdns_sierra_pll_mux_reg_fields cmn_plllc_pfdclk1_sel_preg[] = {
+ [CMN_PLLLC] = {
+ .pfdclk_sel_preg = REG_FIELD(SIERRA_CMN_PLLLC_GEN_PREG, 1, 1),
+ .plllc1en_field = REG_FIELD(SIERRA_CMN_REFRCV1_PREG, 8, 8),
+ .termen_field = REG_FIELD(SIERRA_CMN_REFRCV1_PREG, 0, 0),
+ },
+ [CMN_PLLLC1] = {
+ .pfdclk_sel_preg = REG_FIELD(SIERRA_CMN_PLLLC1_GEN_PREG, 1, 1),
+ .plllc1en_field = REG_FIELD(SIERRA_CMN_REFRCV_PREG, 8, 8),
+ .termen_field = REG_FIELD(SIERRA_CMN_REFRCV_PREG, 0, 0),
+ },
+};
+
+struct cdns_sierra_pll_mux {
+ struct clk_hw hw;
+ struct regmap_field *pfdclk_sel_preg;
+ struct regmap_field *plllc1en_field;
+ struct regmap_field *termen_field;
+ struct clk_init_data clk_data;
+};
+
+#define to_cdns_sierra_pll_mux(_hw) \
+ container_of(_hw, struct cdns_sierra_pll_mux, hw)
+
+static const int pll_mux_parent_index[][SIERRA_NUM_CMN_PLLC_PARENTS] = {
+ [CMN_PLLLC] = { PLL0_REFCLK, PLL1_REFCLK },
+ [CMN_PLLLC1] = { PLL1_REFCLK, PLL0_REFCLK },
+};
+
+static u32 cdns_sierra_pll_mux_table[] = { 0, 1 };
+
struct cdns_sierra_inst {
struct phy *phy;
u32 phy_type;
@@ -197,12 +263,15 @@ struct cdns_sierra_phy {
struct regmap_field *macro_id_type;
struct regmap_field *phy_pll_cfg_1;
struct regmap_field *pllctrl_lock[SIERRA_MAX_LANES];
- struct clk *clk;
- struct clk *cmn_refclk_dig_div;
- struct clk *cmn_refclk1_dig_div;
+ struct regmap_field *cmn_refrcv_refclk_plllc1en_preg[SIERRA_NUM_CMN_PLLC];
+ struct regmap_field *cmn_refrcv_refclk_termen_preg[SIERRA_NUM_CMN_PLLC];
+ struct regmap_field *cmn_plllc_pfdclk1_sel_preg[SIERRA_NUM_CMN_PLLC];
+ struct clk *input_clks[CDNS_SIERRA_INPUT_CLOCKS];
int nsubnodes;
u32 num_lanes;
bool autoconf;
+ struct clk_onecell_data clk_data;
+ struct clk *output_clks[CDNS_SIERRA_OUTPUT_CLOCKS];
};
static int cdns_regmap_write(void *context, unsigned int reg, unsigned int val)
@@ -281,8 +350,8 @@ static int cdns_sierra_phy_init(struct phy *gphy)
if (phy->autoconf)
return 0;
- clk_set_rate(phy->cmn_refclk_dig_div, 25000000);
- clk_set_rate(phy->cmn_refclk1_dig_div, 25000000);
+ clk_set_rate(phy->input_clks[CMN_REFCLK_DIG_DIV], 25000000);
+ clk_set_rate(phy->input_clks[CMN_REFCLK1_DIG_DIV], 25000000);
if (ins->phy_type == PHY_TYPE_PCIE) {
num_cmn_regs = phy->init_data->pcie_cmn_regs;
num_ln_regs = phy->init_data->pcie_ln_regs;
@@ -319,6 +388,12 @@ static int cdns_sierra_phy_on(struct phy *gphy)
u32 val;
int ret;
+ ret = reset_control_deassert(sp->phy_rst);
+ if (ret) {
+ dev_err(dev, "Failed to take the PHY out of reset\n");
+ return ret;
+ }
+
/* Take the PHY lane group out of reset */
ret = reset_control_deassert(ins->lnk_rst);
if (ret) {
@@ -358,6 +433,153 @@ static const struct phy_ops ops = {
.owner = THIS_MODULE,
};
+static u8 cdns_sierra_pll_mux_get_parent(struct clk_hw *hw)
+{
+ struct cdns_sierra_pll_mux *mux = to_cdns_sierra_pll_mux(hw);
+ struct regmap_field *field = mux->pfdclk_sel_preg;
+ unsigned int val;
+
+ regmap_field_read(field, &val);
+ return clk_mux_val_to_index(hw, cdns_sierra_pll_mux_table, 0, val);
+}
+
+static int cdns_sierra_pll_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct cdns_sierra_pll_mux *mux = to_cdns_sierra_pll_mux(hw);
+ struct regmap_field *plllc1en_field = mux->plllc1en_field;
+ struct regmap_field *termen_field = mux->termen_field;
+ struct regmap_field *field = mux->pfdclk_sel_preg;
+ int val, ret;
+
+ ret = regmap_field_write(plllc1en_field, 0);
+ ret |= regmap_field_write(termen_field, 0);
+ if (index == 1) {
+ ret |= regmap_field_write(plllc1en_field, 1);
+ ret |= regmap_field_write(termen_field, 1);
+ }
+
+ val = cdns_sierra_pll_mux_table[index];
+ ret |= regmap_field_write(field, val);
+
+ return ret;
+}
+
+static const struct clk_ops cdns_sierra_pll_mux_ops = {
+ .set_parent = cdns_sierra_pll_mux_set_parent,
+ .get_parent = cdns_sierra_pll_mux_get_parent,
+};
+
+static int cdns_sierra_pll_mux_register(struct cdns_sierra_phy *sp,
+ struct regmap_field *pfdclk1_sel_field,
+ struct regmap_field *plllc1en_field,
+ struct regmap_field *termen_field,
+ int clk_index)
+{
+ struct cdns_sierra_pll_mux *mux;
+ struct device *dev = sp->dev;
+ struct clk_init_data *init;
+ const char **parent_names;
+ unsigned int num_parents;
+ char clk_name[100];
+ struct clk *clk;
+ int i;
+
+ mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
+ if (!mux)
+ return -ENOMEM;
+
+ num_parents = SIERRA_NUM_CMN_PLLC_PARENTS;
+ parent_names = devm_kzalloc(dev, (sizeof(char *) * num_parents), GFP_KERNEL);
+ if (!parent_names)
+ return -ENOMEM;
+
+ for (i = 0; i < num_parents; i++) {
+ clk = sp->input_clks[pll_mux_parent_index[clk_index][i]];
+ if (IS_ERR_OR_NULL(clk)) {
+ dev_err(dev, "No parent clock for derived_refclk\n");
+ return PTR_ERR(clk);
+ }
+ parent_names[i] = __clk_get_name(clk);
+ }
+
+ snprintf(clk_name, sizeof(clk_name), "%s_%s", dev_name(dev), clk_names[clk_index]);
+
+ init = &mux->clk_data;
+
+ init->ops = &cdns_sierra_pll_mux_ops;
+ init->flags = CLK_SET_RATE_NO_REPARENT;
+ init->parent_names = parent_names;
+ init->num_parents = num_parents;
+ init->name = clk_name;
+
+ mux->pfdclk_sel_preg = pfdclk1_sel_field;
+ mux->plllc1en_field = plllc1en_field;
+ mux->termen_field = termen_field;
+ mux->hw.init = init;
+
+ clk = devm_clk_register(dev, &mux->hw);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ sp->output_clks[clk_index] = clk;
+
+ return 0;
+}
+
+static int cdns_sierra_phy_register_pll_mux(struct cdns_sierra_phy *sp)
+{
+ struct regmap_field *pfdclk1_sel_field;
+ struct regmap_field *plllc1en_field;
+ struct regmap_field *termen_field;
+ struct device *dev = sp->dev;
+ int ret = 0, i, clk_index;
+
+ clk_index = CDNS_SIERRA_PLL_CMNLC;
+ for (i = 0; i < SIERRA_NUM_CMN_PLLC; i++, clk_index++) {
+ pfdclk1_sel_field = sp->cmn_plllc_pfdclk1_sel_preg[i];
+ plllc1en_field = sp->cmn_refrcv_refclk_plllc1en_preg[i];
+ termen_field = sp->cmn_refrcv_refclk_termen_preg[i];
+
+ ret = cdns_sierra_pll_mux_register(sp, pfdclk1_sel_field, plllc1en_field,
+ termen_field, clk_index);
+ if (ret) {
+ dev_err(dev, "Fail to register cmn plllc mux\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static void cdns_sierra_clk_unregister(struct cdns_sierra_phy *sp)
+{
+ struct device *dev = sp->dev;
+ struct device_node *node = dev->of_node;
+
+ of_clk_del_provider(node);
+}
+
+static int cdns_sierra_clk_register(struct cdns_sierra_phy *sp)
+{
+ struct device *dev = sp->dev;
+ struct device_node *node = dev->of_node;
+ int ret;
+
+ ret = cdns_sierra_phy_register_pll_mux(sp);
+ if (ret) {
+ dev_err(dev, "Failed to pll mux clocks\n");
+ return ret;
+ }
+
+ sp->clk_data.clks = sp->output_clks;
+ sp->clk_data.clk_num = CDNS_SIERRA_OUTPUT_CLOCKS;
+ ret = of_clk_add_provider(node, of_clk_src_onecell_get, &sp->clk_data);
+ if (ret)
+ dev_err(dev, "Failed to add clock provider: %s\n", node->name);
+
+ return ret;
+}
+
static int cdns_sierra_get_optional(struct cdns_sierra_inst *inst,
struct device_node *child)
{
@@ -396,6 +618,7 @@ static int cdns_regfield_init(struct cdns_sierra_phy *sp)
{
struct device *dev = sp->dev;
struct regmap_field *field;
+ struct reg_field reg_field;
struct regmap *regmap;
int i;
@@ -407,6 +630,32 @@ static int cdns_regfield_init(struct cdns_sierra_phy *sp)
}
sp->macro_id_type = field;
+ for (i = 0; i < SIERRA_NUM_CMN_PLLC; i++) {
+ reg_field = cmn_plllc_pfdclk1_sel_preg[i].pfdclk_sel_preg;
+ field = devm_regmap_field_alloc(dev, regmap, reg_field);
+ if (IS_ERR(field)) {
+ dev_err(dev, "PLLLC%d_PFDCLK1_SEL failed\n", i);
+ return PTR_ERR(field);
+ }
+ sp->cmn_plllc_pfdclk1_sel_preg[i] = field;
+
+ reg_field = cmn_plllc_pfdclk1_sel_preg[i].plllc1en_field;
+ field = devm_regmap_field_alloc(dev, regmap, reg_field);
+ if (IS_ERR(field)) {
+ dev_err(dev, "REFRCV%d_REFCLK_PLLLC1EN failed\n", i);
+ return PTR_ERR(field);
+ }
+ sp->cmn_refrcv_refclk_plllc1en_preg[i] = field;
+
+ reg_field = cmn_plllc_pfdclk1_sel_preg[i].termen_field;
+ field = devm_regmap_field_alloc(dev, regmap, reg_field);
+ if (IS_ERR(field)) {
+ dev_err(dev, "REFRCV%d_REFCLK_TERMEN failed\n", i);
+ return PTR_ERR(field);
+ }
+ sp->cmn_refrcv_refclk_termen_preg[i] = field;
+ }
+
regmap = sp->regmap_phy_config_ctrl;
field = devm_regmap_field_alloc(dev, regmap, phy_pll_cfg_1);
if (IS_ERR(field)) {
@@ -471,6 +720,110 @@ static int cdns_regmap_init_blocks(struct cdns_sierra_phy *sp,
return 0;
}
+static int cdns_sierra_phy_get_clocks(struct cdns_sierra_phy *sp,
+ struct device *dev)
+{
+ struct clk *clk;
+ int ret;
+
+ clk = devm_clk_get_optional(dev, "phy_clk");
+ if (IS_ERR(clk)) {
+ dev_err(dev, "failed to get clock phy_clk\n");
+ return PTR_ERR(clk);
+ }
+ sp->input_clks[PHY_CLK] = clk;
+
+ clk = devm_clk_get_optional(dev, "cmn_refclk_dig_div");
+ if (IS_ERR(clk)) {
+ dev_err(dev, "cmn_refclk_dig_div clock not found\n");
+ ret = PTR_ERR(clk);
+ return ret;
+ }
+ sp->input_clks[CMN_REFCLK_DIG_DIV] = clk;
+
+ clk = devm_clk_get_optional(dev, "cmn_refclk1_dig_div");
+ if (IS_ERR(clk)) {
+ dev_err(dev, "cmn_refclk1_dig_div clock not found\n");
+ ret = PTR_ERR(clk);
+ return ret;
+ }
+ sp->input_clks[CMN_REFCLK1_DIG_DIV] = clk;
+
+ clk = devm_clk_get_optional(dev, "pll0_refclk");
+ if (IS_ERR(clk)) {
+ dev_err(dev, "pll0_refclk clock not found\n");
+ ret = PTR_ERR(clk);
+ return ret;
+ }
+ sp->input_clks[PLL0_REFCLK] = clk;
+
+ clk = devm_clk_get_optional(dev, "pll1_refclk");
+ if (IS_ERR(clk)) {
+ dev_err(dev, "pll1_refclk clock not found\n");
+ ret = PTR_ERR(clk);
+ return ret;
+ }
+ sp->input_clks[PLL1_REFCLK] = clk;
+
+ return 0;
+}
+
+static int cdns_sierra_phy_enable_clocks(struct cdns_sierra_phy *sp)
+{
+ int ret;
+
+ ret = clk_prepare_enable(sp->input_clks[PHY_CLK]);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(sp->output_clks[CDNS_SIERRA_PLL_CMNLC]);
+ if (ret)
+ goto err_pll_cmnlc;
+
+ ret = clk_prepare_enable(sp->output_clks[CDNS_SIERRA_PLL_CMNLC1]);
+ if (ret)
+ goto err_pll_cmnlc1;
+
+ return 0;
+
+err_pll_cmnlc1:
+ clk_disable_unprepare(sp->output_clks[CDNS_SIERRA_PLL_CMNLC]);
+
+err_pll_cmnlc:
+ clk_disable_unprepare(sp->input_clks[PHY_CLK]);
+
+ return ret;
+}
+
+static void cdns_sierra_phy_disable_clocks(struct cdns_sierra_phy *sp)
+{
+ clk_disable_unprepare(sp->output_clks[CDNS_SIERRA_PLL_CMNLC1]);
+ clk_disable_unprepare(sp->output_clks[CDNS_SIERRA_PLL_CMNLC]);
+ clk_disable_unprepare(sp->input_clks[PHY_CLK]);
+}
+
+static int cdns_sierra_phy_get_resets(struct cdns_sierra_phy *sp,
+ struct device *dev)
+{
+ struct reset_control *rst;
+
+ rst = devm_reset_control_get_exclusive(dev, "sierra_reset");
+ if (IS_ERR(rst)) {
+ dev_err(dev, "failed to get reset\n");
+ return PTR_ERR(rst);
+ }
+ sp->phy_rst = rst;
+
+ rst = devm_reset_control_get_optional_exclusive(dev, "sierra_apb");
+ if (IS_ERR(rst)) {
+ dev_err(dev, "failed to get apb reset\n");
+ return PTR_ERR(rst);
+ }
+ sp->apb_rst = rst;
+
+ return 0;
+}
+
static int cdns_sierra_phy_probe(struct platform_device *pdev)
{
struct cdns_sierra_phy *sp;
@@ -481,7 +834,6 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
unsigned int id_value;
int i, ret, node = 0;
void __iomem *base;
- struct clk *clk;
struct device_node *dn = dev->of_node, *child;
if (of_get_child_count(dn) == 0)
@@ -518,43 +870,21 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, sp);
- sp->clk = devm_clk_get_optional(dev, "phy_clk");
- if (IS_ERR(sp->clk)) {
- dev_err(dev, "failed to get clock phy_clk\n");
- return PTR_ERR(sp->clk);
- }
-
- sp->phy_rst = devm_reset_control_get(dev, "sierra_reset");
- if (IS_ERR(sp->phy_rst)) {
- dev_err(dev, "failed to get reset\n");
- return PTR_ERR(sp->phy_rst);
- }
-
- sp->apb_rst = devm_reset_control_get_optional(dev, "sierra_apb");
- if (IS_ERR(sp->apb_rst)) {
- dev_err(dev, "failed to get apb reset\n");
- return PTR_ERR(sp->apb_rst);
- }
-
- clk = devm_clk_get_optional(dev, "cmn_refclk_dig_div");
- if (IS_ERR(clk)) {
- dev_err(dev, "cmn_refclk_dig_div clock not found\n");
- ret = PTR_ERR(clk);
+ ret = cdns_sierra_phy_get_clocks(sp, dev);
+ if (ret)
return ret;
- }
- sp->cmn_refclk_dig_div = clk;
- clk = devm_clk_get_optional(dev, "cmn_refclk1_dig_div");
- if (IS_ERR(clk)) {
- dev_err(dev, "cmn_refclk1_dig_div clock not found\n");
- ret = PTR_ERR(clk);
+ ret = cdns_sierra_clk_register(sp);
+ if (ret)
return ret;
- }
- sp->cmn_refclk1_dig_div = clk;
- ret = clk_prepare_enable(sp->clk);
+ ret = cdns_sierra_phy_get_resets(sp, dev);
if (ret)
- return ret;
+ goto unregister_clk;
+
+ ret = cdns_sierra_phy_enable_clocks(sp);
+ if (ret)
+ goto unregister_clk;
/* Enable APB */
reset_control_deassert(sp->apb_rst);
@@ -571,6 +901,10 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
for_each_available_child_of_node(dn, child) {
struct phy *gphy;
+ if (!(of_node_name_eq(child, "phy") ||
+ of_node_name_eq(child, "link")))
+ continue;
+
sp->phys[node].lnk_rst =
of_reset_control_array_get_exclusive(child);
@@ -616,7 +950,6 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
pm_runtime_enable(dev);
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
- reset_control_deassert(sp->phy_rst);
return PTR_ERR_OR_ZERO(phy_provider);
put_child:
@@ -626,8 +959,10 @@ put_child2:
reset_control_put(sp->phys[i].lnk_rst);
of_node_put(child);
clk_disable:
- clk_disable_unprepare(sp->clk);
+ cdns_sierra_phy_disable_clocks(sp);
reset_control_assert(sp->apb_rst);
+unregister_clk:
+ cdns_sierra_clk_unregister(sp);
return ret;
}
@@ -640,6 +975,7 @@ static int cdns_sierra_phy_remove(struct platform_device *pdev)
reset_control_assert(phy->apb_rst);
pm_runtime_disable(&pdev->dev);
+ cdns_sierra_phy_disable_clocks(phy);
/*
* The device level resets will be put automatically.
* Need to put the subnode resets here though.
@@ -648,6 +984,9 @@ static int cdns_sierra_phy_remove(struct platform_device *pdev)
reset_control_assert(phy->phys[i].lnk_rst);
reset_control_put(phy->phys[i].lnk_rst);
}
+
+ cdns_sierra_clk_unregister(phy);
+
return 0;
}
diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c
index 591a15834b48..0477e7beebbf 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -7,7 +7,9 @@
*/
#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/phy/phy-cadence.h>
#include <linux/clk.h>
+#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/io.h>
@@ -84,6 +86,8 @@
#define CMN_PLLSM1_PLLLOCK_TMR 0x0034U
#define CMN_CDIAG_CDB_PWRI_OVRD 0x0041U
#define CMN_CDIAG_XCVRC_PWRI_OVRD 0x0047U
+#define CMN_CDIAG_REFCLK_OVRD 0x004CU
+#define CMN_CDIAG_REFCLK_DRV0_CTRL 0x0050U
#define CMN_BGCAL_INIT_TMR 0x0064U
#define CMN_BGCAL_ITER_TMR 0x0065U
#define CMN_IBCAL_INIT_TMR 0x0074U
@@ -122,6 +126,8 @@
#define CMN_PLL1_FRACDIVH_M0 0x00D2U
#define CMN_PLL1_HIGH_THR_M0 0x00D3U
#define CMN_PLL1_DSM_DIAG_M0 0x00D4U
+#define CMN_PLL1_DSM_FBH_OVRD_M0 0x00D5U
+#define CMN_PLL1_DSM_FBL_OVRD_M0 0x00D6U
#define CMN_PLL1_SS_CTRL1_M0 0x00D8U
#define CMN_PLL1_SS_CTRL2_M0 0x00D9U
#define CMN_PLL1_SS_CTRL3_M0 0x00DAU
@@ -163,10 +169,12 @@
#define TX_TXCC_CPOST_MULT_00 0x004CU
#define TX_TXCC_CPOST_MULT_01 0x004DU
#define TX_TXCC_MGNFS_MULT_000 0x0050U
+#define TX_TXCC_MGNFS_MULT_100 0x0054U
#define DRV_DIAG_TX_DRV 0x00C6U
#define XCVR_DIAG_PLLDRC_CTRL 0x00E5U
#define XCVR_DIAG_HSCLK_SEL 0x00E6U
#define XCVR_DIAG_HSCLK_DIV 0x00E7U
+#define XCVR_DIAG_RXCLK_CTRL 0x00E9U
#define XCVR_DIAG_BIDI_CTRL 0x00EAU
#define XCVR_DIAG_PSC_OVRD 0x00EBU
#define TX_PSC_A0 0x0100U
@@ -206,6 +214,7 @@
#define RX_DIAG_ACYA 0x01FFU
/* PHY PCS common registers */
+#define PHY_PIPE_CMN_CTRL1 0x0000U
#define PHY_PLL_CFG 0x000EU
#define PHY_PIPE_USB3_GEN2_PRE_CFG0 0x0020U
#define PHY_PIPE_USB3_GEN2_POST_CFG0 0x0022U
@@ -216,6 +225,10 @@
#define PHY_PMA_CMN_CTRL2 0x0001U
#define PHY_PMA_PLL_RAW_CTRL 0x0003U
+static const char * const clk_names[] = {
+ [CDNS_TORRENT_REFCLK_DRIVER] = "refclk-driver",
+};
+
static const struct reg_field phy_pll_cfg =
REG_FIELD(PHY_PLL_CFG, 0, 1);
@@ -231,6 +244,26 @@ static const struct reg_field phy_pma_pll_raw_ctrl =
static const struct reg_field phy_reset_ctrl =
REG_FIELD(PHY_RESET, 8, 8);
+static const struct reg_field phy_pipe_cmn_ctrl1_0 = REG_FIELD(PHY_PIPE_CMN_CTRL1, 0, 0);
+
+#define REFCLK_OUT_NUM_CMN_CONFIG 5
+
+enum cdns_torrent_refclk_out_cmn {
+ CMN_CDIAG_REFCLK_OVRD_4,
+ CMN_CDIAG_REFCLK_DRV0_CTRL_1,
+ CMN_CDIAG_REFCLK_DRV0_CTRL_4,
+ CMN_CDIAG_REFCLK_DRV0_CTRL_5,
+ CMN_CDIAG_REFCLK_DRV0_CTRL_6,
+};
+
+static const struct reg_field refclk_out_cmn_cfg[] = {
+ [CMN_CDIAG_REFCLK_OVRD_4] = REG_FIELD(CMN_CDIAG_REFCLK_OVRD, 4, 4),
+ [CMN_CDIAG_REFCLK_DRV0_CTRL_1] = REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 1, 1),
+ [CMN_CDIAG_REFCLK_DRV0_CTRL_4] = REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 4, 4),
+ [CMN_CDIAG_REFCLK_DRV0_CTRL_5] = REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 5, 5),
+ [CMN_CDIAG_REFCLK_DRV0_CTRL_6] = REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 6, 6),
+};
+
enum cdns_torrent_phy_type {
TYPE_NONE,
TYPE_DP,
@@ -279,6 +312,8 @@ struct cdns_torrent_phy {
struct regmap_field *phy_pma_cmn_ctrl_2;
struct regmap_field *phy_pma_pll_raw_ctrl;
struct regmap_field *phy_reset_ctrl;
+ struct clk *clks[CDNS_TORRENT_REFCLK_DRIVER + 1];
+ struct clk_onecell_data clk_data;
};
enum phy_powerstate {
@@ -288,6 +323,16 @@ enum phy_powerstate {
POWERSTATE_A3 = 3,
};
+struct cdns_torrent_derived_refclk {
+ struct clk_hw hw;
+ struct regmap_field *phy_pipe_cmn_ctrl1_0;
+ struct regmap_field *cmn_fields[REFCLK_OUT_NUM_CMN_CONFIG];
+ struct clk_init_data clk_data;
+};
+
+#define to_cdns_torrent_derived_refclk(_hw) \
+ container_of(_hw, struct cdns_torrent_derived_refclk, hw)
+
static int cdns_torrent_phy_init(struct phy *phy);
static int cdns_torrent_dp_init(struct phy *phy);
static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy,
@@ -326,6 +371,19 @@ static const struct phy_ops cdns_torrent_phy_ops = {
.owner = THIS_MODULE,
};
+static int cdns_torrent_noop_phy_on(struct phy *phy)
+{
+ /* Give 5ms to 10ms delay for the PIPE clock to be stable */
+ usleep_range(5000, 10000);
+
+ return 0;
+}
+
+static const struct phy_ops noop_ops = {
+ .power_on = cdns_torrent_noop_phy_on,
+ .owner = THIS_MODULE,
+};
+
struct cdns_reg_pairs {
u32 val;
u32 off;
@@ -1604,6 +1662,108 @@ static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy, u32 num_lanes)
return ret;
}
+static int cdns_torrent_derived_refclk_enable(struct clk_hw *hw)
+{
+ struct cdns_torrent_derived_refclk *derived_refclk = to_cdns_torrent_derived_refclk(hw);
+
+ regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_6], 0);
+ regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_4], 1);
+ regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_5], 1);
+ regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_1], 0);
+ regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_OVRD_4], 1);
+ regmap_field_write(derived_refclk->phy_pipe_cmn_ctrl1_0, 1);
+
+ return 0;
+}
+
+static void cdns_torrent_derived_refclk_disable(struct clk_hw *hw)
+{
+ struct cdns_torrent_derived_refclk *derived_refclk = to_cdns_torrent_derived_refclk(hw);
+
+ regmap_field_write(derived_refclk->phy_pipe_cmn_ctrl1_0, 0);
+}
+
+static int cdns_torrent_derived_refclk_is_enabled(struct clk_hw *hw)
+{
+ struct cdns_torrent_derived_refclk *derived_refclk = to_cdns_torrent_derived_refclk(hw);
+ int val;
+
+ regmap_field_read(derived_refclk->phy_pipe_cmn_ctrl1_0, &val);
+
+ return !!val;
+}
+
+static const struct clk_ops cdns_torrent_derived_refclk_ops = {
+ .enable = cdns_torrent_derived_refclk_enable,
+ .disable = cdns_torrent_derived_refclk_disable,
+ .is_enabled = cdns_torrent_derived_refclk_is_enabled,
+};
+
+static int cdns_torrent_derived_refclk_register(struct cdns_torrent_phy *cdns_phy)
+{
+ struct cdns_torrent_derived_refclk *derived_refclk;
+ struct device *dev = cdns_phy->dev;
+ struct regmap_field *field;
+ struct clk_init_data *init;
+ const char *parent_name;
+ struct regmap *regmap;
+ char clk_name[100];
+ struct clk *clk;
+ int i;
+
+ derived_refclk = devm_kzalloc(dev, sizeof(*derived_refclk), GFP_KERNEL);
+ if (!derived_refclk)
+ return -ENOMEM;
+
+ snprintf(clk_name, sizeof(clk_name), "%s_%s", dev_name(dev),
+ clk_names[CDNS_TORRENT_REFCLK_DRIVER]);
+
+ clk = devm_clk_get_optional(dev, "phy_en_refclk");
+ if (IS_ERR(clk)) {
+ dev_err(dev, "No parent clock for derived_refclk\n");
+ return PTR_ERR(clk);
+ }
+
+ init = &derived_refclk->clk_data;
+
+ if (clk) {
+ parent_name = __clk_get_name(clk);
+ init->parent_names = &parent_name;
+ init->num_parents = 1;
+ }
+ init->ops = &cdns_torrent_derived_refclk_ops;
+ init->flags = 0;
+ init->name = clk_name;
+
+ regmap = cdns_phy->regmap_phy_pcs_common_cdb;
+ field = devm_regmap_field_alloc(dev, regmap, phy_pipe_cmn_ctrl1_0);
+ if (IS_ERR(field)) {
+ dev_err(dev, "phy_pipe_cmn_ctrl1_0 reg field init failed\n");
+ return PTR_ERR(field);
+ }
+ derived_refclk->phy_pipe_cmn_ctrl1_0 = field;
+
+ regmap = cdns_phy->regmap_common_cdb;
+ for (i = 0; i < REFCLK_OUT_NUM_CMN_CONFIG; i++) {
+ field = devm_regmap_field_alloc(dev, regmap, refclk_out_cmn_cfg[i]);
+ if (IS_ERR(field)) {
+ dev_err(dev, "CMN reg field init failed\n");
+ return PTR_ERR(field);
+ }
+ derived_refclk->cmn_fields[i] = field;
+ }
+
+ derived_refclk->hw.init = init;
+
+ clk = devm_clk_register(dev, &derived_refclk->hw);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ cdns_phy->clks[CDNS_TORRENT_REFCLK_DRIVER] = clk;
+
+ return 0;
+}
+
static int cdns_torrent_phy_on(struct phy *phy)
{
struct cdns_torrent_inst *inst = phy_get_drvdata(phy);
@@ -2071,6 +2231,85 @@ int cdns_torrent_phy_configure_multilink(struct cdns_torrent_phy *cdns_phy)
return 0;
}
+static void cdns_torrent_clk_cleanup(struct cdns_torrent_phy *cdns_phy)
+{
+ struct device *dev = cdns_phy->dev;
+
+ of_clk_del_provider(dev->of_node);
+}
+
+static int cdns_torrent_clk_register(struct cdns_torrent_phy *cdns_phy)
+{
+ struct device *dev = cdns_phy->dev;
+ struct device_node *node = dev->of_node;
+ int ret;
+
+ ret = cdns_torrent_derived_refclk_register(cdns_phy);
+ if (ret) {
+ dev_err(dev, "failed to register derived refclk\n");
+ return ret;
+ }
+
+ cdns_phy->clk_data.clks = cdns_phy->clks;
+ cdns_phy->clk_data.clk_num = CDNS_TORRENT_REFCLK_DRIVER + 1;
+
+ ret = of_clk_add_provider(node, of_clk_src_onecell_get, &cdns_phy->clk_data);
+ if (ret) {
+ dev_err(dev, "Failed to add clock provider: %s\n", node->name);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int cdns_torrent_reset(struct cdns_torrent_phy *cdns_phy)
+{
+ struct device *dev = cdns_phy->dev;
+
+ cdns_phy->phy_rst = devm_reset_control_get_exclusive_by_index(dev, 0);
+ if (IS_ERR(cdns_phy->phy_rst)) {
+ dev_err(dev, "%s: failed to get reset\n",
+ dev->of_node->full_name);
+ return PTR_ERR(cdns_phy->phy_rst);
+ }
+
+ cdns_phy->apb_rst = devm_reset_control_get_optional_exclusive(dev, "torrent_apb");
+ if (IS_ERR(cdns_phy->apb_rst)) {
+ dev_err(dev, "%s: failed to get apb reset\n",
+ dev->of_node->full_name);
+ return PTR_ERR(cdns_phy->apb_rst);
+ }
+
+ return 0;
+}
+
+static int cdns_torrent_clk(struct cdns_torrent_phy *cdns_phy)
+{
+ struct device *dev = cdns_phy->dev;
+ int ret;
+
+ cdns_phy->clk = devm_clk_get(dev, "refclk");
+ if (IS_ERR(cdns_phy->clk)) {
+ dev_err(dev, "phy ref clock not found\n");
+ return PTR_ERR(cdns_phy->clk);
+ }
+
+ ret = clk_prepare_enable(cdns_phy->clk);
+ if (ret) {
+ dev_err(cdns_phy->dev, "Failed to prepare ref clock\n");
+ return ret;
+ }
+
+ cdns_phy->ref_clk_rate = clk_get_rate(cdns_phy->clk);
+ if (!(cdns_phy->ref_clk_rate)) {
+ dev_err(cdns_phy->dev, "Failed to get ref clock rate\n");
+ clk_disable_unprepare(cdns_phy->clk);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int cdns_torrent_phy_probe(struct platform_device *pdev)
{
struct cdns_torrent_phy *cdns_phy;
@@ -2080,6 +2319,7 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev)
struct device_node *child;
int ret, subnodes, node = 0, i;
u32 total_num_lanes = 0;
+ int already_configured;
u8 init_dp_regmap = 0;
u32 phy_type;
@@ -2096,26 +2336,6 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev)
cdns_phy->dev = dev;
cdns_phy->init_data = data;
- cdns_phy->phy_rst = devm_reset_control_get_exclusive_by_index(dev, 0);
- if (IS_ERR(cdns_phy->phy_rst)) {
- dev_err(dev, "%s: failed to get reset\n",
- dev->of_node->full_name);
- return PTR_ERR(cdns_phy->phy_rst);
- }
-
- cdns_phy->apb_rst = devm_reset_control_get_optional(dev, "torrent_apb");
- if (IS_ERR(cdns_phy->apb_rst)) {
- dev_err(dev, "%s: failed to get apb reset\n",
- dev->of_node->full_name);
- return PTR_ERR(cdns_phy->apb_rst);
- }
-
- cdns_phy->clk = devm_clk_get(dev, "refclk");
- if (IS_ERR(cdns_phy->clk)) {
- dev_err(dev, "phy ref clock not found\n");
- return PTR_ERR(cdns_phy->clk);
- }
-
cdns_phy->sd_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(cdns_phy->sd_base))
return PTR_ERR(cdns_phy->sd_base);
@@ -2134,21 +2354,24 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev)
if (ret)
return ret;
- ret = clk_prepare_enable(cdns_phy->clk);
- if (ret) {
- dev_err(cdns_phy->dev, "Failed to prepare ref clock\n");
+ ret = cdns_torrent_clk_register(cdns_phy);
+ if (ret)
return ret;
- }
- cdns_phy->ref_clk_rate = clk_get_rate(cdns_phy->clk);
- if (!(cdns_phy->ref_clk_rate)) {
- dev_err(cdns_phy->dev, "Failed to get ref clock rate\n");
- clk_disable_unprepare(cdns_phy->clk);
- return -EINVAL;
- }
+ regmap_field_read(cdns_phy->phy_pma_cmn_ctrl_1, &already_configured);
- /* Enable APB */
- reset_control_deassert(cdns_phy->apb_rst);
+ if (!already_configured) {
+ ret = cdns_torrent_reset(cdns_phy);
+ if (ret)
+ goto clk_cleanup;
+
+ ret = cdns_torrent_clk(cdns_phy);
+ if (ret)
+ goto clk_cleanup;
+
+ /* Enable APB */
+ reset_control_deassert(cdns_phy->apb_rst);
+ }
for_each_available_child_of_node(dev->of_node, child) {
struct phy *gphy;
@@ -2218,7 +2441,10 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev)
of_property_read_u32(child, "cdns,ssc-mode",
&cdns_phy->phys[node].ssc_mode);
- gphy = devm_phy_create(dev, child, &cdns_torrent_phy_ops);
+ if (!already_configured)
+ gphy = devm_phy_create(dev, child, &cdns_torrent_phy_ops);
+ else
+ gphy = devm_phy_create(dev, child, &noop_ops);
if (IS_ERR(gphy)) {
ret = PTR_ERR(gphy);
goto put_child;
@@ -2302,7 +2528,7 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev)
goto put_lnk_rst;
}
- if (cdns_phy->nsubnodes > 1) {
+ if (cdns_phy->nsubnodes > 1 && !already_configured) {
ret = cdns_torrent_phy_configure_multilink(cdns_phy);
if (ret)
goto put_lnk_rst;
@@ -2324,6 +2550,8 @@ put_lnk_rst:
of_node_put(child);
reset_control_assert(cdns_phy->apb_rst);
clk_disable_unprepare(cdns_phy->clk);
+clk_cleanup:
+ cdns_torrent_clk_cleanup(cdns_phy);
return ret;
}
@@ -2340,6 +2568,7 @@ static int cdns_torrent_phy_remove(struct platform_device *pdev)
}
clk_disable_unprepare(cdns_phy->clk);
+ cdns_torrent_clk_cleanup(cdns_phy);
return 0;
}
@@ -2455,8 +2684,6 @@ static struct cdns_reg_pairs usb_100_int_ssc_cmn_regs[] = {
{0x0C5E, CMN_PLL1_VCOCAL_REFTIM_START},
{0x0C56, CMN_PLL0_VCOCAL_PLLCNT_START},
{0x0C56, CMN_PLL1_VCOCAL_PLLCNT_START},
- {0x0003, CMN_PLL0_VCOCAL_TCTRL},
- {0x0003, CMN_PLL1_VCOCAL_TCTRL},
{0x00C7, CMN_PLL0_LOCK_REFCNT_START},
{0x00C7, CMN_PLL1_LOCK_REFCNT_START},
{0x00C7, CMN_PLL0_LOCK_PLLCNT_START},
@@ -2464,7 +2691,9 @@ static struct cdns_reg_pairs usb_100_int_ssc_cmn_regs[] = {
{0x0005, CMN_PLL0_LOCK_PLLCNT_THR},
{0x0005, CMN_PLL1_LOCK_PLLCNT_THR},
{0x8200, CMN_CDIAG_CDB_PWRI_OVRD},
- {0x8200, CMN_CDIAG_XCVRC_PWRI_OVRD}
+ {0x8200, CMN_CDIAG_XCVRC_PWRI_OVRD},
+ {0x007F, CMN_TXPUCAL_TUNE},
+ {0x007F, CMN_TXPDCAL_TUNE}
};
static struct cdns_torrent_vals usb_100_int_ssc_cmn_vals = {
@@ -2507,13 +2736,28 @@ static struct cdns_torrent_vals usb_phy_pcs_cmn_vals = {
};
/* USB 100 MHz Ref clk, no SSC */
-static struct cdns_reg_pairs usb_100_no_ssc_cmn_regs[] = {
+static struct cdns_reg_pairs sl_usb_100_no_ssc_cmn_regs[] = {
+ {0x0028, CMN_PDIAG_PLL1_CP_PADJ_M0},
+ {0x001E, CMN_PLL1_DSM_FBH_OVRD_M0},
+ {0x000C, CMN_PLL1_DSM_FBL_OVRD_M0},
{0x0003, CMN_PLL0_VCOCAL_TCTRL},
{0x0003, CMN_PLL1_VCOCAL_TCTRL},
{0x8200, CMN_CDIAG_CDB_PWRI_OVRD},
{0x8200, CMN_CDIAG_XCVRC_PWRI_OVRD}
};
+static struct cdns_torrent_vals sl_usb_100_no_ssc_cmn_vals = {
+ .reg_pairs = sl_usb_100_no_ssc_cmn_regs,
+ .num_regs = ARRAY_SIZE(sl_usb_100_no_ssc_cmn_regs),
+};
+
+static struct cdns_reg_pairs usb_100_no_ssc_cmn_regs[] = {
+ {0x8200, CMN_CDIAG_CDB_PWRI_OVRD},
+ {0x8200, CMN_CDIAG_XCVRC_PWRI_OVRD},
+ {0x007F, CMN_TXPUCAL_TUNE},
+ {0x007F, CMN_TXPDCAL_TUNE}
+};
+
static struct cdns_reg_pairs usb_100_no_ssc_tx_ln_regs[] = {
{0x02FF, TX_PSC_A0},
{0x06AF, TX_PSC_A1},
@@ -2645,12 +2889,22 @@ static struct cdns_torrent_vals sgmii_pcie_xcvr_diag_ln_vals = {
};
/* SGMII 100 MHz Ref clk, no SSC */
-static struct cdns_reg_pairs sgmii_100_no_ssc_cmn_regs[] = {
+static struct cdns_reg_pairs sl_sgmii_100_no_ssc_cmn_regs[] = {
+ {0x0028, CMN_PDIAG_PLL1_CP_PADJ_M0},
+ {0x001E, CMN_PLL1_DSM_FBH_OVRD_M0},
+ {0x000C, CMN_PLL1_DSM_FBL_OVRD_M0},
{0x0003, CMN_PLL0_VCOCAL_TCTRL},
- {0x0003, CMN_PLL1_VCOCAL_TCTRL},
- {0x3700, CMN_DIAG_BIAS_OVRD1},
- {0x0008, CMN_TXPUCAL_TUNE},
- {0x0008, CMN_TXPDCAL_TUNE}
+ {0x0003, CMN_PLL1_VCOCAL_TCTRL}
+};
+
+static struct cdns_torrent_vals sl_sgmii_100_no_ssc_cmn_vals = {
+ .reg_pairs = sl_sgmii_100_no_ssc_cmn_regs,
+ .num_regs = ARRAY_SIZE(sl_sgmii_100_no_ssc_cmn_regs),
+};
+
+static struct cdns_reg_pairs sgmii_100_no_ssc_cmn_regs[] = {
+ {0x007F, CMN_TXPUCAL_TUNE},
+ {0x007F, CMN_TXPDCAL_TUNE}
};
static struct cdns_reg_pairs sgmii_100_no_ssc_tx_ln_regs[] = {
@@ -2661,6 +2915,15 @@ static struct cdns_reg_pairs sgmii_100_no_ssc_tx_ln_regs[] = {
{0x00B3, DRV_DIAG_TX_DRV}
};
+static struct cdns_reg_pairs ti_sgmii_100_no_ssc_tx_ln_regs[] = {
+ {0x00F3, TX_PSC_A0},
+ {0x04A2, TX_PSC_A2},
+ {0x04A2, TX_PSC_A3},
+ {0x0000, TX_TXCC_CPOST_MULT_00},
+ {0x00B3, DRV_DIAG_TX_DRV},
+ {0x4000, XCVR_DIAG_RXCLK_CTRL},
+};
+
static struct cdns_reg_pairs sgmii_100_no_ssc_rx_ln_regs[] = {
{0x091D, RX_PSC_A0},
{0x0900, RX_PSC_A2},
@@ -2689,6 +2952,11 @@ static struct cdns_torrent_vals sgmii_100_no_ssc_tx_ln_vals = {
.num_regs = ARRAY_SIZE(sgmii_100_no_ssc_tx_ln_regs),
};
+static struct cdns_torrent_vals ti_sgmii_100_no_ssc_tx_ln_vals = {
+ .reg_pairs = ti_sgmii_100_no_ssc_tx_ln_regs,
+ .num_regs = ARRAY_SIZE(ti_sgmii_100_no_ssc_tx_ln_regs),
+};
+
static struct cdns_torrent_vals sgmii_100_no_ssc_rx_ln_vals = {
.reg_pairs = sgmii_100_no_ssc_rx_ln_regs,
.num_regs = ARRAY_SIZE(sgmii_100_no_ssc_rx_ln_regs),
@@ -2736,17 +3004,14 @@ static struct cdns_reg_pairs sgmii_100_int_ssc_cmn_regs[] = {
{0x0C5E, CMN_PLL1_VCOCAL_REFTIM_START},
{0x0C56, CMN_PLL0_VCOCAL_PLLCNT_START},
{0x0C56, CMN_PLL1_VCOCAL_PLLCNT_START},
- {0x0003, CMN_PLL0_VCOCAL_TCTRL},
- {0x0003, CMN_PLL1_VCOCAL_TCTRL},
{0x00C7, CMN_PLL0_LOCK_REFCNT_START},
{0x00C7, CMN_PLL1_LOCK_REFCNT_START},
{0x00C7, CMN_PLL0_LOCK_PLLCNT_START},
{0x00C7, CMN_PLL1_LOCK_PLLCNT_START},
{0x0005, CMN_PLL0_LOCK_PLLCNT_THR},
{0x0005, CMN_PLL1_LOCK_PLLCNT_THR},
- {0x3700, CMN_DIAG_BIAS_OVRD1},
- {0x0008, CMN_TXPUCAL_TUNE},
- {0x0008, CMN_TXPDCAL_TUNE}
+ {0x007F, CMN_TXPUCAL_TUNE},
+ {0x007F, CMN_TXPDCAL_TUNE}
};
static struct cdns_torrent_vals sgmii_100_int_ssc_cmn_vals = {
@@ -2755,19 +3020,43 @@ static struct cdns_torrent_vals sgmii_100_int_ssc_cmn_vals = {
};
/* QSGMII 100 MHz Ref clk, no SSC */
-static struct cdns_reg_pairs qsgmii_100_no_ssc_cmn_regs[] = {
+static struct cdns_reg_pairs sl_qsgmii_100_no_ssc_cmn_regs[] = {
+ {0x0028, CMN_PDIAG_PLL1_CP_PADJ_M0},
+ {0x001E, CMN_PLL1_DSM_FBH_OVRD_M0},
+ {0x000C, CMN_PLL1_DSM_FBL_OVRD_M0},
{0x0003, CMN_PLL0_VCOCAL_TCTRL},
{0x0003, CMN_PLL1_VCOCAL_TCTRL}
};
+static struct cdns_torrent_vals sl_qsgmii_100_no_ssc_cmn_vals = {
+ .reg_pairs = sl_qsgmii_100_no_ssc_cmn_regs,
+ .num_regs = ARRAY_SIZE(sl_qsgmii_100_no_ssc_cmn_regs),
+};
+
+static struct cdns_reg_pairs qsgmii_100_no_ssc_cmn_regs[] = {
+ {0x007F, CMN_TXPUCAL_TUNE},
+ {0x007F, CMN_TXPDCAL_TUNE}
+};
+
static struct cdns_reg_pairs qsgmii_100_no_ssc_tx_ln_regs[] = {
{0x00F3, TX_PSC_A0},
{0x04A2, TX_PSC_A2},
{0x04A2, TX_PSC_A3},
{0x0000, TX_TXCC_CPOST_MULT_00},
+ {0x0011, TX_TXCC_MGNFS_MULT_100},
{0x0003, DRV_DIAG_TX_DRV}
};
+static struct cdns_reg_pairs ti_qsgmii_100_no_ssc_tx_ln_regs[] = {
+ {0x00F3, TX_PSC_A0},
+ {0x04A2, TX_PSC_A2},
+ {0x04A2, TX_PSC_A3},
+ {0x0000, TX_TXCC_CPOST_MULT_00},
+ {0x0011, TX_TXCC_MGNFS_MULT_100},
+ {0x0003, DRV_DIAG_TX_DRV},
+ {0x4000, XCVR_DIAG_RXCLK_CTRL},
+};
+
static struct cdns_reg_pairs qsgmii_100_no_ssc_rx_ln_regs[] = {
{0x091D, RX_PSC_A0},
{0x0900, RX_PSC_A2},
@@ -2796,6 +3085,11 @@ static struct cdns_torrent_vals qsgmii_100_no_ssc_tx_ln_vals = {
.num_regs = ARRAY_SIZE(qsgmii_100_no_ssc_tx_ln_regs),
};
+static struct cdns_torrent_vals ti_qsgmii_100_no_ssc_tx_ln_vals = {
+ .reg_pairs = ti_qsgmii_100_no_ssc_tx_ln_regs,
+ .num_regs = ARRAY_SIZE(ti_qsgmii_100_no_ssc_tx_ln_regs),
+};
+
static struct cdns_torrent_vals qsgmii_100_no_ssc_rx_ln_vals = {
.reg_pairs = qsgmii_100_no_ssc_rx_ln_regs,
.num_regs = ARRAY_SIZE(qsgmii_100_no_ssc_rx_ln_regs),
@@ -2843,14 +3137,14 @@ static struct cdns_reg_pairs qsgmii_100_int_ssc_cmn_regs[] = {
{0x0C5E, CMN_PLL1_VCOCAL_REFTIM_START},
{0x0C56, CMN_PLL0_VCOCAL_PLLCNT_START},
{0x0C56, CMN_PLL1_VCOCAL_PLLCNT_START},
- {0x0003, CMN_PLL0_VCOCAL_TCTRL},
- {0x0003, CMN_PLL1_VCOCAL_TCTRL},
{0x00C7, CMN_PLL0_LOCK_REFCNT_START},
{0x00C7, CMN_PLL1_LOCK_REFCNT_START},
{0x00C7, CMN_PLL0_LOCK_PLLCNT_START},
{0x00C7, CMN_PLL1_LOCK_PLLCNT_START},
{0x0005, CMN_PLL0_LOCK_PLLCNT_THR},
- {0x0005, CMN_PLL1_LOCK_PLLCNT_THR}
+ {0x0005, CMN_PLL1_LOCK_PLLCNT_THR},
+ {0x007F, CMN_TXPUCAL_TUNE},
+ {0x007F, CMN_TXPDCAL_TUNE}
};
static struct cdns_torrent_vals qsgmii_100_int_ssc_cmn_vals = {
@@ -2922,8 +3216,6 @@ static struct cdns_reg_pairs pcie_100_int_ssc_cmn_regs[] = {
{0x0C5E, CMN_PLL1_VCOCAL_REFTIM_START},
{0x0C56, CMN_PLL0_VCOCAL_PLLCNT_START},
{0x0C56, CMN_PLL1_VCOCAL_PLLCNT_START},
- {0x0003, CMN_PLL0_VCOCAL_TCTRL},
- {0x0003, CMN_PLL1_VCOCAL_TCTRL},
{0x00C7, CMN_PLL0_LOCK_REFCNT_START},
{0x00C7, CMN_PLL1_LOCK_REFCNT_START},
{0x00C7, CMN_PLL0_LOCK_PLLCNT_START},
@@ -2979,8 +3271,6 @@ static struct cdns_reg_pairs sl_pcie_100_int_ssc_cmn_regs[] = {
{0x0C5E, CMN_PLL1_VCOCAL_REFTIM_START},
{0x0C56, CMN_PLL0_VCOCAL_PLLCNT_START},
{0x0C56, CMN_PLL1_VCOCAL_PLLCNT_START},
- {0x0003, CMN_PLL0_VCOCAL_TCTRL},
- {0x0003, CMN_PLL1_VCOCAL_TCTRL},
{0x00C7, CMN_PLL0_LOCK_REFCNT_START},
{0x00C7, CMN_PLL1_LOCK_REFCNT_START},
{0x00C7, CMN_PLL0_LOCK_PLLCNT_START},
@@ -2996,8 +3286,9 @@ static struct cdns_torrent_vals sl_pcie_100_int_ssc_cmn_vals = {
/* PCIe, 100 MHz Ref clk, no SSC & external SSC */
static struct cdns_reg_pairs pcie_100_ext_no_ssc_cmn_regs[] = {
- {0x0003, CMN_PLL0_VCOCAL_TCTRL},
- {0x0003, CMN_PLL1_VCOCAL_TCTRL}
+ {0x0028, CMN_PDIAG_PLL1_CP_PADJ_M0},
+ {0x001E, CMN_PLL1_DSM_FBH_OVRD_M0},
+ {0x000C, CMN_PLL1_DSM_FBL_OVRD_M0}
};
static struct cdns_reg_pairs pcie_100_ext_no_ssc_rx_ln_regs[] = {
@@ -3198,8 +3489,8 @@ static const struct cdns_torrent_data cdns_map_torrent = {
.cmn_vals = {
[TYPE_PCIE] = {
[TYPE_NONE] = {
- [NO_SSC] = &pcie_100_no_ssc_cmn_vals,
- [EXTERNAL_SSC] = &pcie_100_no_ssc_cmn_vals,
+ [NO_SSC] = NULL,
+ [EXTERNAL_SSC] = NULL,
[INTERNAL_SSC] = &sl_pcie_100_int_ssc_cmn_vals,
},
[TYPE_SGMII] = {
@@ -3220,7 +3511,7 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
[TYPE_SGMII] = {
[TYPE_NONE] = {
- [NO_SSC] = &sgmii_100_no_ssc_cmn_vals,
+ [NO_SSC] = &sl_sgmii_100_no_ssc_cmn_vals,
},
[TYPE_PCIE] = {
[NO_SSC] = &sgmii_100_no_ssc_cmn_vals,
@@ -3235,7 +3526,7 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
[TYPE_QSGMII] = {
[TYPE_NONE] = {
- [NO_SSC] = &qsgmii_100_no_ssc_cmn_vals,
+ [NO_SSC] = &sl_qsgmii_100_no_ssc_cmn_vals,
},
[TYPE_PCIE] = {
[NO_SSC] = &qsgmii_100_no_ssc_cmn_vals,
@@ -3250,8 +3541,8 @@ static const struct cdns_torrent_data cdns_map_torrent = {
},
[TYPE_USB] = {
[TYPE_NONE] = {
- [NO_SSC] = &usb_100_no_ssc_cmn_vals,
- [EXTERNAL_SSC] = &usb_100_no_ssc_cmn_vals,
+ [NO_SSC] = &sl_usb_100_no_ssc_cmn_vals,
+ [EXTERNAL_SSC] = &sl_usb_100_no_ssc_cmn_vals,
[INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals,
},
[TYPE_PCIE] = {
@@ -3260,13 +3551,13 @@ static const struct cdns_torrent_data cdns_map_torrent = {
[INTERNAL_SSC] = &usb_100_int_ssc_cmn_vals,
},
[TYPE_SGMII] = {
- [NO_SSC] = &usb_100_no_ssc_cmn_vals,
- [EXTERNAL_SSC] = &usb_100_no_ssc_cmn_vals,
+ [NO_SSC] = &sl_usb_100_no_ssc_cmn_vals,
+ [EXTERNAL_SSC] = &sl_usb_100_no_ssc_cmn_vals,
[INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals,
},
[TYPE_QSGMII] = {
- [NO_SSC] = &usb_100_no_ssc_cmn_vals,
- [EXTERNAL_SSC] = &usb_100_no_ssc_cmn_vals,
+ [NO_SSC] = &sl_usb_100_no_ssc_cmn_vals,
+ [EXTERNAL_SSC] = &sl_usb_100_no_ssc_cmn_vals,
[INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals,
},
},
@@ -3607,8 +3898,8 @@ static const struct cdns_torrent_data ti_j721e_map_torrent = {
.cmn_vals = {
[TYPE_PCIE] = {
[TYPE_NONE] = {
- [NO_SSC] = &pcie_100_no_ssc_cmn_vals,
- [EXTERNAL_SSC] = &pcie_100_no_ssc_cmn_vals,
+ [NO_SSC] = NULL,
+ [EXTERNAL_SSC] = NULL,
[INTERNAL_SSC] = &sl_pcie_100_int_ssc_cmn_vals,
},
[TYPE_SGMII] = {
@@ -3629,7 +3920,7 @@ static const struct cdns_torrent_data ti_j721e_map_torrent = {
},
[TYPE_SGMII] = {
[TYPE_NONE] = {
- [NO_SSC] = &sgmii_100_no_ssc_cmn_vals,
+ [NO_SSC] = &sl_sgmii_100_no_ssc_cmn_vals,
},
[TYPE_PCIE] = {
[NO_SSC] = &sgmii_100_no_ssc_cmn_vals,
@@ -3644,7 +3935,7 @@ static const struct cdns_torrent_data ti_j721e_map_torrent = {
},
[TYPE_QSGMII] = {
[TYPE_NONE] = {
- [NO_SSC] = &qsgmii_100_no_ssc_cmn_vals,
+ [NO_SSC] = &sl_qsgmii_100_no_ssc_cmn_vals,
},
[TYPE_PCIE] = {
[NO_SSC] = &qsgmii_100_no_ssc_cmn_vals,
@@ -3659,8 +3950,8 @@ static const struct cdns_torrent_data ti_j721e_map_torrent = {
},
[TYPE_USB] = {
[TYPE_NONE] = {
- [NO_SSC] = &usb_100_no_ssc_cmn_vals,
- [EXTERNAL_SSC] = &usb_100_no_ssc_cmn_vals,
+ [NO_SSC] = &sl_usb_100_no_ssc_cmn_vals,
+ [EXTERNAL_SSC] = &sl_usb_100_no_ssc_cmn_vals,
[INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals,
},
[TYPE_PCIE] = {
@@ -3669,13 +3960,13 @@ static const struct cdns_torrent_data ti_j721e_map_torrent = {
[INTERNAL_SSC] = &usb_100_int_ssc_cmn_vals,
},
[TYPE_SGMII] = {
- [NO_SSC] = &usb_100_no_ssc_cmn_vals,
- [EXTERNAL_SSC] = &usb_100_no_ssc_cmn_vals,
+ [NO_SSC] = &sl_usb_100_no_ssc_cmn_vals,
+ [EXTERNAL_SSC] = &sl_usb_100_no_ssc_cmn_vals,
[INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals,
},
[TYPE_QSGMII] = {
- [NO_SSC] = &usb_100_no_ssc_cmn_vals,
- [EXTERNAL_SSC] = &usb_100_no_ssc_cmn_vals,
+ [NO_SSC] = &sl_usb_100_no_ssc_cmn_vals,
+ [EXTERNAL_SSC] = &sl_usb_100_no_ssc_cmn_vals,
[INTERNAL_SSC] = &sl_usb_100_int_ssc_cmn_vals,
},
},
@@ -3705,32 +3996,32 @@ static const struct cdns_torrent_data ti_j721e_map_torrent = {
},
[TYPE_SGMII] = {
[TYPE_NONE] = {
- [NO_SSC] = &sgmii_100_no_ssc_tx_ln_vals,
+ [NO_SSC] = &ti_sgmii_100_no_ssc_tx_ln_vals,
},
[TYPE_PCIE] = {
- [NO_SSC] = &sgmii_100_no_ssc_tx_ln_vals,
- [EXTERNAL_SSC] = &sgmii_100_no_ssc_tx_ln_vals,
- [INTERNAL_SSC] = &sgmii_100_no_ssc_tx_ln_vals,
+ [NO_SSC] = &ti_sgmii_100_no_ssc_tx_ln_vals,
+ [EXTERNAL_SSC] = &ti_sgmii_100_no_ssc_tx_ln_vals,
+ [INTERNAL_SSC] = &ti_sgmii_100_no_ssc_tx_ln_vals,
},
[TYPE_USB] = {
- [NO_SSC] = &sgmii_100_no_ssc_tx_ln_vals,
- [EXTERNAL_SSC] = &sgmii_100_no_ssc_tx_ln_vals,
- [INTERNAL_SSC] = &sgmii_100_no_ssc_tx_ln_vals,
+ [NO_SSC] = &ti_sgmii_100_no_ssc_tx_ln_vals,
+ [EXTERNAL_SSC] = &ti_sgmii_100_no_ssc_tx_ln_vals,
+ [INTERNAL_SSC] = &ti_sgmii_100_no_ssc_tx_ln_vals,
},
},
[TYPE_QSGMII] = {
[TYPE_NONE] = {
- [NO_SSC] = &qsgmii_100_no_ssc_tx_ln_vals,
+ [NO_SSC] = &ti_qsgmii_100_no_ssc_tx_ln_vals,
},
[TYPE_PCIE] = {
- [NO_SSC] = &qsgmii_100_no_ssc_tx_ln_vals,
- [EXTERNAL_SSC] = &qsgmii_100_no_ssc_tx_ln_vals,
- [INTERNAL_SSC] = &qsgmii_100_no_ssc_tx_ln_vals,
+ [NO_SSC] = &ti_qsgmii_100_no_ssc_tx_ln_vals,
+ [EXTERNAL_SSC] = &ti_qsgmii_100_no_ssc_tx_ln_vals,
+ [INTERNAL_SSC] = &ti_qsgmii_100_no_ssc_tx_ln_vals,
},
[TYPE_USB] = {
- [NO_SSC] = &qsgmii_100_no_ssc_tx_ln_vals,
- [EXTERNAL_SSC] = &qsgmii_100_no_ssc_tx_ln_vals,
- [INTERNAL_SSC] = &qsgmii_100_no_ssc_tx_ln_vals,
+ [NO_SSC] = &ti_qsgmii_100_no_ssc_tx_ln_vals,
+ [EXTERNAL_SSC] = &ti_qsgmii_100_no_ssc_tx_ln_vals,
+ [INTERNAL_SSC] = &ti_qsgmii_100_no_ssc_tx_ln_vals,
},
},
[TYPE_USB] = {
diff --git a/drivers/phy/hisilicon/phy-hi6220-usb.c b/drivers/phy/hisilicon/phy-hi6220-usb.c
index be05292df8b8..e92ba78da4c8 100644
--- a/drivers/phy/hisilicon/phy-hi6220-usb.c
+++ b/drivers/phy/hisilicon/phy-hi6220-usb.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2015 Linaro Ltd.
- * Copyright (c) 2015 Hisilicon Limited.
+ * Copyright (c) 2015 HiSilicon Limited.
*/
#include <linux/mfd/syscon.h>
diff --git a/drivers/phy/hisilicon/phy-hix5hd2-sata.c b/drivers/phy/hisilicon/phy-hix5hd2-sata.c
index c67b78cd2602..b0f99a9ac857 100644
--- a/drivers/phy/hisilicon/phy-hix5hd2-sata.c
+++ b/drivers/phy/hisilicon/phy-hix5hd2-sata.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2014 Linaro Ltd.
- * Copyright (c) 2014 Hisilicon Limited.
+ * Copyright (c) 2014 HiSilicon Limited.
*/
#include <linux/delay.h>
diff --git a/drivers/phy/ingenic/phy-ingenic-usb.c b/drivers/phy/ingenic/phy-ingenic-usb.c
index ea127b177f46..28c28d816484 100644
--- a/drivers/phy/ingenic/phy-ingenic-usb.c
+++ b/drivers/phy/ingenic/phy-ingenic-usb.c
@@ -352,8 +352,8 @@ static int ingenic_usb_phy_probe(struct platform_device *pdev)
}
priv->phy = devm_phy_create(dev, NULL, &ingenic_usb_phy_ops);
- if (IS_ERR(priv))
- return PTR_ERR(priv);
+ if (IS_ERR(priv->phy))
+ return PTR_ERR(priv->phy);
phy_set_drvdata(priv->phy, priv);
diff --git a/drivers/phy/intel/phy-intel-lgm-combo.c b/drivers/phy/intel/phy-intel-lgm-combo.c
index 360b1eb2ebd6..157683d10367 100644
--- a/drivers/phy/intel/phy-intel-lgm-combo.c
+++ b/drivers/phy/intel/phy-intel-lgm-combo.c
@@ -462,7 +462,7 @@ static int intel_cbphy_fwnode_parse(struct intel_combo_phy *cbphy)
/*
* syscfg and hsiocfg variables stores the handle of the registers set
- * in which ComboPhy subsytem specific registers are subset. Using
+ * in which ComboPhy subsystem specific registers are subset. Using
* Register map framework to access the registers set.
*/
ret = fwnode_property_get_reference_args(fwnode, "intel,syscfg", NULL,
diff --git a/drivers/phy/marvell/Kconfig b/drivers/phy/marvell/Kconfig
index 6c96f2bf5266..bdb87c976243 100644
--- a/drivers/phy/marvell/Kconfig
+++ b/drivers/phy/marvell/Kconfig
@@ -3,8 +3,8 @@
# Phy drivers for Marvell platforms
#
config ARMADA375_USBCLUSTER_PHY
- def_bool y
- depends on MACH_ARMADA_375 || COMPILE_TEST
+ bool "Armada 375 USB cluster PHY support" if COMPILE_TEST
+ default y if MACH_ARMADA_375
depends on OF && HAS_IOMEM
select GENERIC_PHY
@@ -67,6 +67,14 @@ config PHY_MVEBU_CP110_COMPHY
lanes can be used by various controllers (Ethernet, sata, usb,
PCIe...).
+config PHY_MVEBU_CP110_UTMI
+ tristate "Marvell CP110 UTMI driver"
+ depends on ARCH_MVEBU || COMPILE_TEST
+ depends on OF && USB_COMMON
+ select GENERIC_PHY
+ help
+ Enable this to support Marvell CP110 UTMI PHY driver.
+
config PHY_MVEBU_SATA
def_bool y
depends on ARCH_DOVE || MACH_DOVE || MACH_KIRKWOOD
diff --git a/drivers/phy/marvell/Makefile b/drivers/phy/marvell/Makefile
index 7f296ef02829..90862c4daa26 100644
--- a/drivers/phy/marvell/Makefile
+++ b/drivers/phy/marvell/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_MVEBU_A3700_COMPHY) += phy-mvebu-a3700-comphy.o
obj-$(CONFIG_PHY_MVEBU_A3700_UTMI) += phy-mvebu-a3700-utmi.o
obj-$(CONFIG_PHY_MVEBU_A38X_COMPHY) += phy-armada38x-comphy.o
obj-$(CONFIG_PHY_MVEBU_CP110_COMPHY) += phy-mvebu-cp110-comphy.o
+obj-$(CONFIG_PHY_MVEBU_CP110_UTMI) += phy-mvebu-cp110-utmi.o
obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o
obj-$(CONFIG_PHY_PXA_28NM_HSIC) += phy-pxa-28nm-hsic.o
obj-$(CONFIG_PHY_PXA_28NM_USB2) += phy-pxa-28nm-usb2.o
diff --git a/drivers/phy/marvell/phy-mvebu-cp110-utmi.c b/drivers/phy/marvell/phy-mvebu-cp110-utmi.c
new file mode 100644
index 000000000000..08d178a4dc13
--- /dev/null
+++ b/drivers/phy/marvell/phy-mvebu-cp110-utmi.c
@@ -0,0 +1,384 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Marvell
+ *
+ * Authors:
+ * Konstantin Porotchkin <kostap@marvell.com>
+ *
+ * Marvell CP110 UTMI PHY driver
+ */
+
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/usb/of.h>
+#include <linux/usb/otg.h>
+
+#define UTMI_PHY_PORTS 2
+
+/* CP110 UTMI register macro definetions */
+#define SYSCON_USB_CFG_REG 0x420
+#define USB_CFG_DEVICE_EN_MASK BIT(0)
+#define USB_CFG_DEVICE_MUX_OFFSET 1
+#define USB_CFG_DEVICE_MUX_MASK BIT(1)
+#define USB_CFG_PLL_MASK BIT(25)
+
+#define SYSCON_UTMI_CFG_REG(id) (0x440 + (id) * 4)
+#define UTMI_PHY_CFG_PU_MASK BIT(5)
+
+#define UTMI_PLL_CTRL_REG 0x0
+#define PLL_REFDIV_OFFSET 0
+#define PLL_REFDIV_MASK GENMASK(6, 0)
+#define PLL_REFDIV_VAL 0x5
+#define PLL_FBDIV_OFFSET 16
+#define PLL_FBDIV_MASK GENMASK(24, 16)
+#define PLL_FBDIV_VAL 0x60
+#define PLL_SEL_LPFR_MASK GENMASK(29, 28)
+#define PLL_RDY BIT(31)
+#define UTMI_CAL_CTRL_REG 0x8
+#define IMPCAL_VTH_OFFSET 8
+#define IMPCAL_VTH_MASK GENMASK(10, 8)
+#define IMPCAL_VTH_VAL 0x7
+#define IMPCAL_DONE BIT(23)
+#define PLLCAL_DONE BIT(31)
+#define UTMI_TX_CH_CTRL_REG 0xC
+#define DRV_EN_LS_OFFSET 12
+#define DRV_EN_LS_MASK GENMASK(15, 12)
+#define IMP_SEL_LS_OFFSET 16
+#define IMP_SEL_LS_MASK GENMASK(19, 16)
+#define TX_AMP_OFFSET 20
+#define TX_AMP_MASK GENMASK(22, 20)
+#define TX_AMP_VAL 0x4
+#define UTMI_RX_CH_CTRL0_REG 0x14
+#define SQ_DET_EN BIT(15)
+#define SQ_ANA_DTC_SEL BIT(28)
+#define UTMI_RX_CH_CTRL1_REG 0x18
+#define SQ_AMP_CAL_OFFSET 0
+#define SQ_AMP_CAL_MASK GENMASK(2, 0)
+#define SQ_AMP_CAL_VAL 1
+#define SQ_AMP_CAL_EN BIT(3)
+#define UTMI_CTRL_STATUS0_REG 0x24
+#define SUSPENDM BIT(22)
+#define TEST_SEL BIT(25)
+#define UTMI_CHGDTC_CTRL_REG 0x38
+#define VDAT_OFFSET 8
+#define VDAT_MASK GENMASK(9, 8)
+#define VDAT_VAL 1
+#define VSRC_OFFSET 10
+#define VSRC_MASK GENMASK(11, 10)
+#define VSRC_VAL 1
+
+#define PLL_LOCK_DELAY_US 10000
+#define PLL_LOCK_TIMEOUT_US 1000000
+
+#define PORT_REGS(p) ((p)->priv->regs + (p)->id * 0x1000)
+
+/**
+ * struct mvebu_cp110_utmi - PHY driver data
+ *
+ * @regs: PHY registers
+ * @syscom: Regmap with system controller registers
+ * @dev: device driver handle
+ * @caps: PHY capabilities
+ */
+struct mvebu_cp110_utmi {
+ void __iomem *regs;
+ struct regmap *syscon;
+ struct device *dev;
+ const struct phy_ops *ops;
+};
+
+/**
+ * struct mvebu_cp110_utmi_port - PHY port data
+ *
+ * @priv: PHY driver data
+ * @id: PHY port ID
+ * @dr_mode: PHY connection: USB_DR_MODE_HOST or USB_DR_MODE_PERIPHERAL
+ */
+struct mvebu_cp110_utmi_port {
+ struct mvebu_cp110_utmi *priv;
+ u32 id;
+ enum usb_dr_mode dr_mode;
+};
+
+static void mvebu_cp110_utmi_port_setup(struct mvebu_cp110_utmi_port *port)
+{
+ u32 reg;
+
+ /*
+ * Setup PLL.
+ * The reference clock is the frequency of quartz resonator
+ * connected to pins REFCLK_XIN and REFCLK_XOUT of the SoC.
+ * Register init values are matching the 40MHz default clock.
+ * The crystal used for all platform boards is now 25MHz.
+ * See the functional specification for details.
+ */
+ reg = readl(PORT_REGS(port) + UTMI_PLL_CTRL_REG);
+ reg &= ~(PLL_REFDIV_MASK | PLL_FBDIV_MASK | PLL_SEL_LPFR_MASK);
+ reg |= (PLL_REFDIV_VAL << PLL_REFDIV_OFFSET) |
+ (PLL_FBDIV_VAL << PLL_FBDIV_OFFSET);
+ writel(reg, PORT_REGS(port) + UTMI_PLL_CTRL_REG);
+
+ /* Impedance Calibration Threshold Setting */
+ reg = readl(PORT_REGS(port) + UTMI_CAL_CTRL_REG);
+ reg &= ~IMPCAL_VTH_MASK;
+ reg |= IMPCAL_VTH_VAL << IMPCAL_VTH_OFFSET;
+ writel(reg, PORT_REGS(port) + UTMI_CAL_CTRL_REG);
+
+ /* Set LS TX driver strength coarse control */
+ reg = readl(PORT_REGS(port) + UTMI_TX_CH_CTRL_REG);
+ reg &= ~TX_AMP_MASK;
+ reg |= TX_AMP_VAL << TX_AMP_OFFSET;
+ writel(reg, PORT_REGS(port) + UTMI_TX_CH_CTRL_REG);
+
+ /* Disable SQ and enable analog squelch detect */
+ reg = readl(PORT_REGS(port) + UTMI_RX_CH_CTRL0_REG);
+ reg &= ~SQ_DET_EN;
+ reg |= SQ_ANA_DTC_SEL;
+ writel(reg, PORT_REGS(port) + UTMI_RX_CH_CTRL0_REG);
+
+ /*
+ * Set External squelch calibration number and
+ * enable the External squelch calibration
+ */
+ reg = readl(PORT_REGS(port) + UTMI_RX_CH_CTRL1_REG);
+ reg &= ~SQ_AMP_CAL_MASK;
+ reg |= (SQ_AMP_CAL_VAL << SQ_AMP_CAL_OFFSET) | SQ_AMP_CAL_EN;
+ writel(reg, PORT_REGS(port) + UTMI_RX_CH_CTRL1_REG);
+
+ /*
+ * Set Control VDAT Reference Voltage - 0.325V and
+ * Control VSRC Reference Voltage - 0.6V
+ */
+ reg = readl(PORT_REGS(port) + UTMI_CHGDTC_CTRL_REG);
+ reg &= ~(VDAT_MASK | VSRC_MASK);
+ reg |= (VDAT_VAL << VDAT_OFFSET) | (VSRC_VAL << VSRC_OFFSET);
+ writel(reg, PORT_REGS(port) + UTMI_CHGDTC_CTRL_REG);
+}
+
+static int mvebu_cp110_utmi_phy_power_off(struct phy *phy)
+{
+ struct mvebu_cp110_utmi_port *port = phy_get_drvdata(phy);
+ struct mvebu_cp110_utmi *utmi = port->priv;
+ int i;
+
+ /* Power down UTMI PHY port */
+ regmap_clear_bits(utmi->syscon, SYSCON_UTMI_CFG_REG(port->id),
+ UTMI_PHY_CFG_PU_MASK);
+
+ for (i = 0; i < UTMI_PHY_PORTS; i++) {
+ int test = regmap_test_bits(utmi->syscon,
+ SYSCON_UTMI_CFG_REG(i),
+ UTMI_PHY_CFG_PU_MASK);
+ /* skip PLL shutdown if there are active UTMI PHY ports */
+ if (test != 0)
+ return 0;
+ }
+
+ /* PLL Power down if all UTMI PHYs are down */
+ regmap_clear_bits(utmi->syscon, SYSCON_USB_CFG_REG, USB_CFG_PLL_MASK);
+
+ return 0;
+}
+
+static int mvebu_cp110_utmi_phy_power_on(struct phy *phy)
+{
+ struct mvebu_cp110_utmi_port *port = phy_get_drvdata(phy);
+ struct mvebu_cp110_utmi *utmi = port->priv;
+ struct device *dev = &phy->dev;
+ int ret;
+ u32 reg;
+
+ /* It is necessary to power off UTMI before configuration */
+ ret = mvebu_cp110_utmi_phy_power_off(phy);
+ if (ret) {
+ dev_err(dev, "UTMI power OFF before power ON failed\n");
+ return ret;
+ }
+
+ /*
+ * If UTMI port is connected to USB Device controller,
+ * configure the USB MUX prior to UTMI PHY initialization.
+ * The single USB device controller can be connected
+ * to UTMI0 or to UTMI1 PHY port, but not to both.
+ */
+ if (port->dr_mode == USB_DR_MODE_PERIPHERAL) {
+ regmap_update_bits(utmi->syscon, SYSCON_USB_CFG_REG,
+ USB_CFG_DEVICE_EN_MASK | USB_CFG_DEVICE_MUX_MASK,
+ USB_CFG_DEVICE_EN_MASK |
+ (port->id << USB_CFG_DEVICE_MUX_OFFSET));
+ }
+
+ /* Set Test suspendm mode and enable Test UTMI select */
+ reg = readl(PORT_REGS(port) + UTMI_CTRL_STATUS0_REG);
+ reg |= SUSPENDM | TEST_SEL;
+ writel(reg, PORT_REGS(port) + UTMI_CTRL_STATUS0_REG);
+
+ /* Wait for UTMI power down */
+ mdelay(1);
+
+ /* PHY port setup first */
+ mvebu_cp110_utmi_port_setup(port);
+
+ /* Power UP UTMI PHY */
+ regmap_set_bits(utmi->syscon, SYSCON_UTMI_CFG_REG(port->id),
+ UTMI_PHY_CFG_PU_MASK);
+
+ /* Disable Test UTMI select */
+ reg = readl(PORT_REGS(port) + UTMI_CTRL_STATUS0_REG);
+ reg &= ~TEST_SEL;
+ writel(reg, PORT_REGS(port) + UTMI_CTRL_STATUS0_REG);
+
+ /* Wait for impedance calibration */
+ ret = readl_poll_timeout(PORT_REGS(port) + UTMI_CAL_CTRL_REG, reg,
+ reg & IMPCAL_DONE,
+ PLL_LOCK_DELAY_US, PLL_LOCK_TIMEOUT_US);
+ if (ret) {
+ dev_err(dev, "Failed to end UTMI impedance calibration\n");
+ return ret;
+ }
+
+ /* Wait for PLL calibration */
+ ret = readl_poll_timeout(PORT_REGS(port) + UTMI_CAL_CTRL_REG, reg,
+ reg & PLLCAL_DONE,
+ PLL_LOCK_DELAY_US, PLL_LOCK_TIMEOUT_US);
+ if (ret) {
+ dev_err(dev, "Failed to end UTMI PLL calibration\n");
+ return ret;
+ }
+
+ /* Wait for PLL ready */
+ ret = readl_poll_timeout(PORT_REGS(port) + UTMI_PLL_CTRL_REG, reg,
+ reg & PLL_RDY,
+ PLL_LOCK_DELAY_US, PLL_LOCK_TIMEOUT_US);
+ if (ret) {
+ dev_err(dev, "PLL is not ready\n");
+ return ret;
+ }
+
+ /* PLL Power up */
+ regmap_set_bits(utmi->syscon, SYSCON_USB_CFG_REG, USB_CFG_PLL_MASK);
+
+ return 0;
+}
+
+static const struct phy_ops mvebu_cp110_utmi_phy_ops = {
+ .power_on = mvebu_cp110_utmi_phy_power_on,
+ .power_off = mvebu_cp110_utmi_phy_power_off,
+ .owner = THIS_MODULE,
+};
+
+static const struct of_device_id mvebu_cp110_utmi_of_match[] = {
+ { .compatible = "marvell,cp110-utmi-phy" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, mvebu_cp110_utmi_of_match);
+
+static int mvebu_cp110_utmi_phy_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct mvebu_cp110_utmi *utmi;
+ struct phy_provider *provider;
+ struct device_node *child;
+ u32 usb_devices = 0;
+
+ utmi = devm_kzalloc(dev, sizeof(*utmi), GFP_KERNEL);
+ if (!utmi)
+ return -ENOMEM;
+
+ utmi->dev = dev;
+
+ /* Get system controller region */
+ utmi->syscon = syscon_regmap_lookup_by_phandle(dev->of_node,
+ "marvell,system-controller");
+ if (IS_ERR(utmi->syscon)) {
+ dev_err(dev, "Missing UTMI system controller\n");
+ return PTR_ERR(utmi->syscon);
+ }
+
+ /* Get UTMI memory region */
+ utmi->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(utmi->regs))
+ return PTR_ERR(utmi->regs);
+
+ for_each_available_child_of_node(dev->of_node, child) {
+ struct mvebu_cp110_utmi_port *port;
+ struct phy *phy;
+ int ret;
+ u32 port_id;
+
+ ret = of_property_read_u32(child, "reg", &port_id);
+ if ((ret < 0) || (port_id >= UTMI_PHY_PORTS)) {
+ dev_err(dev,
+ "invalid 'reg' property on child %pOF\n",
+ child);
+ continue;
+ }
+
+ port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
+ if (!port) {
+ of_node_put(child);
+ return -ENOMEM;
+ }
+
+ port->dr_mode = of_usb_get_dr_mode_by_phy(child, -1);
+ if ((port->dr_mode != USB_DR_MODE_HOST) &&
+ (port->dr_mode != USB_DR_MODE_PERIPHERAL)) {
+ dev_err(&pdev->dev,
+ "Missing dual role setting of the port%d, will use HOST mode\n",
+ port_id);
+ port->dr_mode = USB_DR_MODE_HOST;
+ }
+
+ if (port->dr_mode == USB_DR_MODE_PERIPHERAL) {
+ usb_devices++;
+ if (usb_devices > 1) {
+ dev_err(dev,
+ "Single USB device allowed! Port%d will use HOST mode\n",
+ port_id);
+ port->dr_mode = USB_DR_MODE_HOST;
+ }
+ }
+
+ /* Retrieve PHY capabilities */
+ utmi->ops = &mvebu_cp110_utmi_phy_ops;
+
+ /* Instantiate the PHY */
+ phy = devm_phy_create(dev, child, utmi->ops);
+ if (IS_ERR(phy)) {
+ dev_err(dev, "Failed to create the UTMI PHY\n");
+ of_node_put(child);
+ return PTR_ERR(phy);
+ }
+
+ port->priv = utmi;
+ port->id = port_id;
+ phy_set_drvdata(phy, port);
+
+ /* Ensure the PHY is powered off */
+ mvebu_cp110_utmi_phy_power_off(phy);
+ }
+
+ dev_set_drvdata(dev, utmi);
+ provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+ return PTR_ERR_OR_ZERO(provider);
+}
+
+static struct platform_driver mvebu_cp110_utmi_driver = {
+ .probe = mvebu_cp110_utmi_phy_probe,
+ .driver = {
+ .name = "mvebu-cp110-utmi-phy",
+ .of_match_table = mvebu_cp110_utmi_of_match,
+ },
+};
+module_platform_driver(mvebu_cp110_utmi_driver);
+
+MODULE_AUTHOR("Konstatin Porotchkin <kostap@marvell.com>");
+MODULE_DESCRIPTION("Marvell Armada CP110 UTMI PHY driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/microchip/Kconfig b/drivers/phy/microchip/Kconfig
new file mode 100644
index 000000000000..3728a284bf64
--- /dev/null
+++ b/drivers/phy/microchip/Kconfig
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Phy drivers for Microchip devices
+#
+
+config PHY_SPARX5_SERDES
+ tristate "Microchip Sparx5 SerDes PHY driver"
+ select GENERIC_PHY
+ depends on ARCH_SPARX5 || COMPILE_TEST
+ depends on OF
+ depends on HAS_IOMEM
+ help
+ Enable this for support of the 10G/25G SerDes on Microchip Sparx5.
diff --git a/drivers/phy/microchip/Makefile b/drivers/phy/microchip/Makefile
new file mode 100644
index 000000000000..7b98345712aa
--- /dev/null
+++ b/drivers/phy/microchip/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Makefile for the Microchip phy drivers.
+#
+
+obj-$(CONFIG_PHY_SPARX5_SERDES) := sparx5_serdes.o
diff --git a/drivers/phy/microchip/sparx5_serdes.c b/drivers/phy/microchip/sparx5_serdes.c
new file mode 100644
index 000000000000..c8a7d0927ced
--- /dev/null
+++ b/drivers/phy/microchip/sparx5_serdes.c
@@ -0,0 +1,2513 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* Microchip Sparx5 Switch SerDes driver
+ *
+ * Copyright (c) 2020 Microchip Technology Inc. and its subsidiaries.
+ *
+ * The Sparx5 Chip Register Model can be browsed at this location:
+ * https://github.com/microchip-ung/sparx-5_reginfo
+ * and the datasheet is available here:
+ * https://ww1.microchip.com/downloads/en/DeviceDoc/SparX-5_Family_L2L3_Enterprise_10G_Ethernet_Switches_Datasheet_00003822B.pdf
+ */
+#include <linux/printk.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/netdevice.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/phy.h>
+#include <linux/phy/phy.h>
+
+#include "sparx5_serdes.h"
+
+#define SPX5_CMU_MAX 14
+
+#define SPX5_SERDES_10G_START 13
+#define SPX5_SERDES_25G_START 25
+
+enum sparx5_10g28cmu_mode {
+ SPX5_SD10G28_CMU_MAIN = 0,
+ SPX5_SD10G28_CMU_AUX1 = 1,
+ SPX5_SD10G28_CMU_AUX2 = 3,
+ SPX5_SD10G28_CMU_NONE = 4,
+};
+
+enum sparx5_sd25g28_mode_preset_type {
+ SPX5_SD25G28_MODE_PRESET_25000,
+ SPX5_SD25G28_MODE_PRESET_10000,
+ SPX5_SD25G28_MODE_PRESET_5000,
+ SPX5_SD25G28_MODE_PRESET_SD_2G5,
+ SPX5_SD25G28_MODE_PRESET_1000BASEX,
+};
+
+enum sparx5_sd10g28_mode_preset_type {
+ SPX5_SD10G28_MODE_PRESET_10000,
+ SPX5_SD10G28_MODE_PRESET_SFI_5000_6G,
+ SPX5_SD10G28_MODE_PRESET_SFI_5000_10G,
+ SPX5_SD10G28_MODE_PRESET_QSGMII,
+ SPX5_SD10G28_MODE_PRESET_SD_2G5,
+ SPX5_SD10G28_MODE_PRESET_1000BASEX,
+};
+
+struct sparx5_serdes_io_resource {
+ enum sparx5_serdes_target id;
+ phys_addr_t offset;
+};
+
+struct sparx5_sd25g28_mode_preset {
+ u8 bitwidth;
+ u8 tx_pre_div;
+ u8 fifo_ck_div;
+ u8 pre_divsel;
+ u8 vco_div_mode;
+ u8 sel_div;
+ u8 ck_bitwidth;
+ u8 subrate;
+ u8 com_txcal_en;
+ u8 com_tx_reserve_msb;
+ u8 com_tx_reserve_lsb;
+ u8 cfg_itx_ipcml_base;
+ u8 tx_reserve_lsb;
+ u8 tx_reserve_msb;
+ u8 bw;
+ u8 rxterm;
+ u8 dfe_tap;
+ u8 dfe_enable;
+ bool txmargin;
+ u8 cfg_ctle_rstn;
+ u8 r_dfe_rstn;
+ u8 cfg_pi_bw_3_0;
+ u8 tx_tap_dly;
+ u8 tx_tap_adv;
+};
+
+struct sparx5_sd25g28_media_preset {
+ u8 cfg_eq_c_force_3_0;
+ u8 cfg_vga_ctrl_byp_4_0;
+ u8 cfg_eq_r_force_3_0;
+ u8 cfg_en_adv;
+ u8 cfg_en_main;
+ u8 cfg_en_dly;
+ u8 cfg_tap_adv_3_0;
+ u8 cfg_tap_main;
+ u8 cfg_tap_dly_4_0;
+ u8 cfg_alos_thr_2_0;
+};
+
+struct sparx5_sd25g28_args {
+ u8 if_width; /* UDL if-width: 10/16/20/32/64 */
+ bool skip_cmu_cfg:1; /* Enable/disable CMU cfg */
+ enum sparx5_10g28cmu_mode cmu_sel; /* Device/Mode serdes uses */
+ bool no_pwrcycle:1; /* Omit initial power-cycle */
+ bool txinvert:1; /* Enable inversion of output data */
+ bool rxinvert:1; /* Enable inversion of input data */
+ u16 txswing; /* Set output level */
+ u8 rate; /* Rate of network interface */
+ u8 pi_bw_gen1;
+ u8 duty_cycle; /* Set output level to half/full */
+ bool mute:1; /* Mute Output Buffer */
+ bool reg_rst:1;
+ u8 com_pll_reserve;
+};
+
+struct sparx5_sd25g28_params {
+ u8 reg_rst;
+ u8 cfg_jc_byp;
+ u8 cfg_common_reserve_7_0;
+ u8 r_reg_manual;
+ u8 r_d_width_ctrl_from_hwt;
+ u8 r_d_width_ctrl_2_0;
+ u8 r_txfifo_ck_div_pmad_2_0;
+ u8 r_rxfifo_ck_div_pmad_2_0;
+ u8 cfg_pll_lol_set;
+ u8 cfg_vco_div_mode_1_0;
+ u8 cfg_pre_divsel_1_0;
+ u8 cfg_sel_div_3_0;
+ u8 cfg_vco_start_code_3_0;
+ u8 cfg_pma_tx_ck_bitwidth_2_0;
+ u8 cfg_tx_prediv_1_0;
+ u8 cfg_rxdiv_sel_2_0;
+ u8 cfg_tx_subrate_2_0;
+ u8 cfg_rx_subrate_2_0;
+ u8 r_multi_lane_mode;
+ u8 cfg_cdrck_en;
+ u8 cfg_dfeck_en;
+ u8 cfg_dfe_pd;
+ u8 cfg_dfedmx_pd;
+ u8 cfg_dfetap_en_5_1;
+ u8 cfg_dmux_pd;
+ u8 cfg_dmux_clk_pd;
+ u8 cfg_erramp_pd;
+ u8 cfg_pi_dfe_en;
+ u8 cfg_pi_en;
+ u8 cfg_pd_ctle;
+ u8 cfg_summer_en;
+ u8 cfg_pmad_ck_pd;
+ u8 cfg_pd_clk;
+ u8 cfg_pd_cml;
+ u8 cfg_pd_driver;
+ u8 cfg_rx_reg_pu;
+ u8 cfg_pd_rms_det;
+ u8 cfg_dcdr_pd;
+ u8 cfg_ecdr_pd;
+ u8 cfg_pd_sq;
+ u8 cfg_itx_ipdriver_base_2_0;
+ u8 cfg_tap_dly_4_0;
+ u8 cfg_tap_main;
+ u8 cfg_en_main;
+ u8 cfg_tap_adv_3_0;
+ u8 cfg_en_adv;
+ u8 cfg_en_dly;
+ u8 cfg_iscan_en;
+ u8 l1_pcs_en_fast_iscan;
+ u8 l0_cfg_bw_1_0;
+ u8 l0_cfg_txcal_en;
+ u8 cfg_en_dummy;
+ u8 cfg_pll_reserve_3_0;
+ u8 l0_cfg_tx_reserve_15_8;
+ u8 l0_cfg_tx_reserve_7_0;
+ u8 cfg_tx_reserve_15_8;
+ u8 cfg_tx_reserve_7_0;
+ u8 cfg_bw_1_0;
+ u8 cfg_txcal_man_en;
+ u8 cfg_phase_man_4_0;
+ u8 cfg_quad_man_1_0;
+ u8 cfg_txcal_shift_code_5_0;
+ u8 cfg_txcal_valid_sel_3_0;
+ u8 cfg_txcal_en;
+ u8 cfg_cdr_kf_2_0;
+ u8 cfg_cdr_m_7_0;
+ u8 cfg_pi_bw_3_0;
+ u8 cfg_pi_steps_1_0;
+ u8 cfg_dis_2ndorder;
+ u8 cfg_ctle_rstn;
+ u8 r_dfe_rstn;
+ u8 cfg_alos_thr_2_0;
+ u8 cfg_itx_ipcml_base_1_0;
+ u8 cfg_rx_reserve_7_0;
+ u8 cfg_rx_reserve_15_8;
+ u8 cfg_rxterm_2_0;
+ u8 cfg_fom_selm;
+ u8 cfg_rx_sp_ctle_1_0;
+ u8 cfg_isel_ctle_1_0;
+ u8 cfg_vga_ctrl_byp_4_0;
+ u8 cfg_vga_byp;
+ u8 cfg_agc_adpt_byp;
+ u8 cfg_eqr_byp;
+ u8 cfg_eqr_force_3_0;
+ u8 cfg_eqc_force_3_0;
+ u8 cfg_sum_setcm_en;
+ u8 cfg_init_pos_iscan_6_0;
+ u8 cfg_init_pos_ipi_6_0;
+ u8 cfg_dfedig_m_2_0;
+ u8 cfg_en_dfedig;
+ u8 cfg_pi_DFE_en;
+ u8 cfg_tx2rx_lp_en;
+ u8 cfg_txlb_en;
+ u8 cfg_rx2tx_lp_en;
+ u8 cfg_rxlb_en;
+ u8 r_tx_pol_inv;
+ u8 r_rx_pol_inv;
+};
+
+struct sparx5_sd10g28_media_preset {
+ u8 cfg_en_adv;
+ u8 cfg_en_main;
+ u8 cfg_en_dly;
+ u8 cfg_tap_adv_3_0;
+ u8 cfg_tap_main;
+ u8 cfg_tap_dly_4_0;
+ u8 cfg_vga_ctrl_3_0;
+ u8 cfg_vga_cp_2_0;
+ u8 cfg_eq_res_3_0;
+ u8 cfg_eq_r_byp;
+ u8 cfg_eq_c_force_3_0;
+ u8 cfg_alos_thr_3_0;
+};
+
+struct sparx5_sd10g28_mode_preset {
+ u8 bwidth; /* interface width: 10/16/20/32/64 */
+ enum sparx5_10g28cmu_mode cmu_sel; /* Device/Mode serdes uses */
+ u8 rate; /* Rate of network interface */
+ u8 dfe_tap;
+ u8 dfe_enable;
+ u8 pi_bw_gen1;
+ u8 duty_cycle; /* Set output level to half/full */
+};
+
+struct sparx5_sd10g28_args {
+ bool skip_cmu_cfg:1; /* Enable/disable CMU cfg */
+ bool no_pwrcycle:1; /* Omit initial power-cycle */
+ bool txinvert:1; /* Enable inversion of output data */
+ bool rxinvert:1; /* Enable inversion of input data */
+ bool txmargin:1; /* Set output level to half/full */
+ u16 txswing; /* Set output level */
+ bool mute:1; /* Mute Output Buffer */
+ bool is_6g:1;
+ bool reg_rst:1;
+};
+
+struct sparx5_sd10g28_params {
+ u8 cmu_sel;
+ u8 is_6g;
+ u8 skip_cmu_cfg;
+ u8 cfg_lane_reserve_7_0;
+ u8 cfg_ssc_rtl_clk_sel;
+ u8 cfg_lane_reserve_15_8;
+ u8 cfg_txrate_1_0;
+ u8 cfg_rxrate_1_0;
+ u8 r_d_width_ctrl_2_0;
+ u8 cfg_pma_tx_ck_bitwidth_2_0;
+ u8 cfg_rxdiv_sel_2_0;
+ u8 r_pcs2pma_phymode_4_0;
+ u8 cfg_lane_id_2_0;
+ u8 cfg_cdrck_en;
+ u8 cfg_dfeck_en;
+ u8 cfg_dfe_pd;
+ u8 cfg_dfetap_en_5_1;
+ u8 cfg_erramp_pd;
+ u8 cfg_pi_DFE_en;
+ u8 cfg_pi_en;
+ u8 cfg_pd_ctle;
+ u8 cfg_summer_en;
+ u8 cfg_pd_rx_cktree;
+ u8 cfg_pd_clk;
+ u8 cfg_pd_cml;
+ u8 cfg_pd_driver;
+ u8 cfg_rx_reg_pu;
+ u8 cfg_d_cdr_pd;
+ u8 cfg_pd_sq;
+ u8 cfg_rxdet_en;
+ u8 cfg_rxdet_str;
+ u8 r_multi_lane_mode;
+ u8 cfg_en_adv;
+ u8 cfg_en_main;
+ u8 cfg_en_dly;
+ u8 cfg_tap_adv_3_0;
+ u8 cfg_tap_main;
+ u8 cfg_tap_dly_4_0;
+ u8 cfg_vga_ctrl_3_0;
+ u8 cfg_vga_cp_2_0;
+ u8 cfg_eq_res_3_0;
+ u8 cfg_eq_r_byp;
+ u8 cfg_eq_c_force_3_0;
+ u8 cfg_en_dfedig;
+ u8 cfg_sum_setcm_en;
+ u8 cfg_en_preemph;
+ u8 cfg_itx_ippreemp_base_1_0;
+ u8 cfg_itx_ipdriver_base_2_0;
+ u8 cfg_ibias_tune_reserve_5_0;
+ u8 cfg_txswing_half;
+ u8 cfg_dis_2nd_order;
+ u8 cfg_rx_ssc_lh;
+ u8 cfg_pi_floop_steps_1_0;
+ u8 cfg_pi_ext_dac_23_16;
+ u8 cfg_pi_ext_dac_15_8;
+ u8 cfg_iscan_ext_dac_7_0;
+ u8 cfg_cdr_kf_gen1_2_0;
+ u8 cfg_cdr_kf_gen2_2_0;
+ u8 cfg_cdr_kf_gen3_2_0;
+ u8 cfg_cdr_kf_gen4_2_0;
+ u8 r_cdr_m_gen1_7_0;
+ u8 cfg_pi_bw_gen1_3_0;
+ u8 cfg_pi_bw_gen2;
+ u8 cfg_pi_bw_gen3;
+ u8 cfg_pi_bw_gen4;
+ u8 cfg_pi_ext_dac_7_0;
+ u8 cfg_pi_steps;
+ u8 cfg_mp_max_3_0;
+ u8 cfg_rstn_dfedig;
+ u8 cfg_alos_thr_3_0;
+ u8 cfg_predrv_slewrate_1_0;
+ u8 cfg_itx_ipcml_base_1_0;
+ u8 cfg_ip_pre_base_1_0;
+ u8 r_cdr_m_gen2_7_0;
+ u8 r_cdr_m_gen3_7_0;
+ u8 r_cdr_m_gen4_7_0;
+ u8 r_en_auto_cdr_rstn;
+ u8 cfg_oscal_afe;
+ u8 cfg_pd_osdac_afe;
+ u8 cfg_resetb_oscal_afe[2];
+ u8 cfg_center_spreading;
+ u8 cfg_m_cnt_maxval_4_0;
+ u8 cfg_ncnt_maxval_7_0;
+ u8 cfg_ncnt_maxval_10_8;
+ u8 cfg_ssc_en;
+ u8 cfg_tx2rx_lp_en;
+ u8 cfg_txlb_en;
+ u8 cfg_rx2tx_lp_en;
+ u8 cfg_rxlb_en;
+ u8 r_tx_pol_inv;
+ u8 r_rx_pol_inv;
+ u8 fx_100;
+};
+
+static struct sparx5_sd25g28_media_preset media_presets_25g[] = {
+ { /* ETH_MEDIA_DEFAULT */
+ .cfg_en_adv = 0,
+ .cfg_en_main = 1,
+ .cfg_en_dly = 0,
+ .cfg_tap_adv_3_0 = 0,
+ .cfg_tap_main = 1,
+ .cfg_tap_dly_4_0 = 0,
+ .cfg_eq_c_force_3_0 = 0xf,
+ .cfg_vga_ctrl_byp_4_0 = 4,
+ .cfg_eq_r_force_3_0 = 12,
+ .cfg_alos_thr_2_0 = 7,
+ },
+ { /* ETH_MEDIA_SR */
+ .cfg_en_adv = 1,
+ .cfg_en_main = 1,
+ .cfg_en_dly = 1,
+ .cfg_tap_adv_3_0 = 0,
+ .cfg_tap_main = 1,
+ .cfg_tap_dly_4_0 = 0x10,
+ .cfg_eq_c_force_3_0 = 0xf,
+ .cfg_vga_ctrl_byp_4_0 = 8,
+ .cfg_eq_r_force_3_0 = 4,
+ .cfg_alos_thr_2_0 = 0,
+ },
+ { /* ETH_MEDIA_DAC */
+ .cfg_en_adv = 0,
+ .cfg_en_main = 1,
+ .cfg_en_dly = 0,
+ .cfg_tap_adv_3_0 = 0,
+ .cfg_tap_main = 1,
+ .cfg_tap_dly_4_0 = 0,
+ .cfg_eq_c_force_3_0 = 0xf,
+ .cfg_vga_ctrl_byp_4_0 = 8,
+ .cfg_eq_r_force_3_0 = 0xc,
+ .cfg_alos_thr_2_0 = 0,
+ },
+};
+
+static struct sparx5_sd25g28_mode_preset mode_presets_25g[] = {
+ { /* SPX5_SD25G28_MODE_PRESET_25000 */
+ .bitwidth = 40,
+ .tx_pre_div = 0,
+ .fifo_ck_div = 0,
+ .pre_divsel = 1,
+ .vco_div_mode = 0,
+ .sel_div = 15,
+ .ck_bitwidth = 3,
+ .subrate = 0,
+ .com_txcal_en = 0,
+ .com_tx_reserve_msb = (0x26 << 1),
+ .com_tx_reserve_lsb = 0xf0,
+ .cfg_itx_ipcml_base = 0,
+ .tx_reserve_msb = 0xcc,
+ .tx_reserve_lsb = 0xfe,
+ .bw = 3,
+ .rxterm = 0,
+ .dfe_enable = 1,
+ .dfe_tap = 0x1f,
+ .txmargin = 1,
+ .cfg_ctle_rstn = 1,
+ .r_dfe_rstn = 1,
+ .cfg_pi_bw_3_0 = 0,
+ .tx_tap_dly = 8,
+ .tx_tap_adv = 0xc,
+ },
+ { /* SPX5_SD25G28_MODE_PRESET_10000 */
+ .bitwidth = 64,
+ .tx_pre_div = 0,
+ .fifo_ck_div = 2,
+ .pre_divsel = 0,
+ .vco_div_mode = 1,
+ .sel_div = 9,
+ .ck_bitwidth = 0,
+ .subrate = 0,
+ .com_txcal_en = 1,
+ .com_tx_reserve_msb = (0x20 << 1),
+ .com_tx_reserve_lsb = 0x40,
+ .cfg_itx_ipcml_base = 0,
+ .tx_reserve_msb = 0x4c,
+ .tx_reserve_lsb = 0x44,
+ .bw = 3,
+ .cfg_pi_bw_3_0 = 0,
+ .rxterm = 3,
+ .dfe_enable = 1,
+ .dfe_tap = 0x1f,
+ .txmargin = 0,
+ .cfg_ctle_rstn = 1,
+ .r_dfe_rstn = 1,
+ .tx_tap_dly = 0,
+ .tx_tap_adv = 0,
+ },
+ { /* SPX5_SD25G28_MODE_PRESET_5000 */
+ .bitwidth = 64,
+ .tx_pre_div = 0,
+ .fifo_ck_div = 2,
+ .pre_divsel = 0,
+ .vco_div_mode = 2,
+ .sel_div = 9,
+ .ck_bitwidth = 0,
+ .subrate = 0,
+ .com_txcal_en = 1,
+ .com_tx_reserve_msb = (0x20 << 1),
+ .com_tx_reserve_lsb = 0,
+ .cfg_itx_ipcml_base = 0,
+ .tx_reserve_msb = 0xe,
+ .tx_reserve_lsb = 0x80,
+ .bw = 0,
+ .rxterm = 0,
+ .cfg_pi_bw_3_0 = 6,
+ .dfe_enable = 0,
+ .dfe_tap = 0,
+ .tx_tap_dly = 0,
+ .tx_tap_adv = 0,
+ },
+ { /* SPX5_SD25G28_MODE_PRESET_SD_2G5 */
+ .bitwidth = 10,
+ .tx_pre_div = 0,
+ .fifo_ck_div = 0,
+ .pre_divsel = 0,
+ .vco_div_mode = 1,
+ .sel_div = 6,
+ .ck_bitwidth = 3,
+ .subrate = 2,
+ .com_txcal_en = 1,
+ .com_tx_reserve_msb = (0x26 << 1),
+ .com_tx_reserve_lsb = (0xf << 4),
+ .cfg_itx_ipcml_base = 2,
+ .tx_reserve_msb = 0x8,
+ .tx_reserve_lsb = 0x8a,
+ .bw = 0,
+ .cfg_pi_bw_3_0 = 0,
+ .rxterm = (1 << 2),
+ .dfe_enable = 0,
+ .dfe_tap = 0,
+ .tx_tap_dly = 0,
+ .tx_tap_adv = 0,
+ },
+ { /* SPX5_SD25G28_MODE_PRESET_1000BASEX */
+ .bitwidth = 10,
+ .tx_pre_div = 0,
+ .fifo_ck_div = 1,
+ .pre_divsel = 0,
+ .vco_div_mode = 1,
+ .sel_div = 8,
+ .ck_bitwidth = 3,
+ .subrate = 3,
+ .com_txcal_en = 1,
+ .com_tx_reserve_msb = (0x26 << 1),
+ .com_tx_reserve_lsb = 0xf0,
+ .cfg_itx_ipcml_base = 0,
+ .tx_reserve_msb = 0x8,
+ .tx_reserve_lsb = 0xce,
+ .bw = 0,
+ .rxterm = 0,
+ .cfg_pi_bw_3_0 = 0,
+ .dfe_enable = 0,
+ .dfe_tap = 0,
+ .tx_tap_dly = 0,
+ .tx_tap_adv = 0,
+ },
+};
+
+static struct sparx5_sd10g28_media_preset media_presets_10g[] = {
+ { /* ETH_MEDIA_DEFAULT */
+ .cfg_en_adv = 0,
+ .cfg_en_main = 1,
+ .cfg_en_dly = 0,
+ .cfg_tap_adv_3_0 = 0,
+ .cfg_tap_main = 1,
+ .cfg_tap_dly_4_0 = 0,
+ .cfg_vga_ctrl_3_0 = 5,
+ .cfg_vga_cp_2_0 = 0,
+ .cfg_eq_res_3_0 = 0xa,
+ .cfg_eq_r_byp = 1,
+ .cfg_eq_c_force_3_0 = 0x8,
+ .cfg_alos_thr_3_0 = 0x3,
+ },
+ { /* ETH_MEDIA_SR */
+ .cfg_en_adv = 1,
+ .cfg_en_main = 1,
+ .cfg_en_dly = 1,
+ .cfg_tap_adv_3_0 = 0,
+ .cfg_tap_main = 1,
+ .cfg_tap_dly_4_0 = 0xc,
+ .cfg_vga_ctrl_3_0 = 0xa,
+ .cfg_vga_cp_2_0 = 0x4,
+ .cfg_eq_res_3_0 = 0xa,
+ .cfg_eq_r_byp = 1,
+ .cfg_eq_c_force_3_0 = 0xF,
+ .cfg_alos_thr_3_0 = 0x3,
+ },
+ { /* ETH_MEDIA_DAC */
+ .cfg_en_adv = 1,
+ .cfg_en_main = 1,
+ .cfg_en_dly = 1,
+ .cfg_tap_adv_3_0 = 12,
+ .cfg_tap_main = 1,
+ .cfg_tap_dly_4_0 = 8,
+ .cfg_vga_ctrl_3_0 = 0xa,
+ .cfg_vga_cp_2_0 = 4,
+ .cfg_eq_res_3_0 = 0xa,
+ .cfg_eq_r_byp = 1,
+ .cfg_eq_c_force_3_0 = 0xf,
+ .cfg_alos_thr_3_0 = 0x0,
+ }
+};
+
+static struct sparx5_sd10g28_mode_preset mode_presets_10g[] = {
+ { /* SPX5_SD10G28_MODE_PRESET_10000 */
+ .bwidth = 64,
+ .cmu_sel = SPX5_SD10G28_CMU_MAIN,
+ .rate = 0x0,
+ .dfe_enable = 1,
+ .dfe_tap = 0x1f,
+ .pi_bw_gen1 = 0x0,
+ .duty_cycle = 0x2,
+ },
+ { /* SPX5_SD10G28_MODE_PRESET_SFI_5000_6G */
+ .bwidth = 16,
+ .cmu_sel = SPX5_SD10G28_CMU_MAIN,
+ .rate = 0x1,
+ .dfe_enable = 0,
+ .dfe_tap = 0,
+ .pi_bw_gen1 = 0x5,
+ .duty_cycle = 0x0,
+ },
+ { /* SPX5_SD10G28_MODE_PRESET_SFI_5000_10G */
+ .bwidth = 64,
+ .cmu_sel = SPX5_SD10G28_CMU_MAIN,
+ .rate = 0x1,
+ .dfe_enable = 0,
+ .dfe_tap = 0,
+ .pi_bw_gen1 = 0x5,
+ .duty_cycle = 0x0,
+ },
+ { /* SPX5_SD10G28_MODE_PRESET_QSGMII */
+ .bwidth = 20,
+ .cmu_sel = SPX5_SD10G28_CMU_AUX1,
+ .rate = 0x1,
+ .dfe_enable = 0,
+ .dfe_tap = 0,
+ .pi_bw_gen1 = 0x5,
+ .duty_cycle = 0x0,
+ },
+ { /* SPX5_SD10G28_MODE_PRESET_SD_2G5 */
+ .bwidth = 10,
+ .cmu_sel = SPX5_SD10G28_CMU_AUX2,
+ .rate = 0x2,
+ .dfe_enable = 0,
+ .dfe_tap = 0,
+ .pi_bw_gen1 = 0x7,
+ .duty_cycle = 0x0,
+ },
+ { /* SPX5_SD10G28_MODE_PRESET_1000BASEX */
+ .bwidth = 10,
+ .cmu_sel = SPX5_SD10G28_CMU_AUX1,
+ .rate = 0x3,
+ .dfe_enable = 0,
+ .dfe_tap = 0,
+ .pi_bw_gen1 = 0x7,
+ .duty_cycle = 0x0,
+ },
+};
+
+/* map from SD25G28 interface width to configuration value */
+static u8 sd25g28_get_iw_setting(struct device *dev, const u8 interface_width)
+{
+ switch (interface_width) {
+ case 10: return 0;
+ case 16: return 1;
+ case 32: return 3;
+ case 40: return 4;
+ case 64: return 5;
+ default:
+ dev_err(dev, "%s: Illegal value %d for interface width\n",
+ __func__, interface_width);
+ }
+ return 0;
+}
+
+/* map from SD10G28 interface width to configuration value */
+static u8 sd10g28_get_iw_setting(struct device *dev, const u8 interface_width)
+{
+ switch (interface_width) {
+ case 10: return 0;
+ case 16: return 1;
+ case 20: return 2;
+ case 32: return 3;
+ case 40: return 4;
+ case 64: return 7;
+ default:
+ dev_err(dev, "%s: Illegal value %d for interface width\n", __func__,
+ interface_width);
+ return 0;
+ }
+}
+
+static int sparx5_sd10g25_get_mode_preset(struct sparx5_serdes_macro *macro,
+ struct sparx5_sd25g28_mode_preset *mode)
+{
+ switch (macro->serdesmode) {
+ case SPX5_SD_MODE_SFI:
+ if (macro->speed == SPEED_25000)
+ *mode = mode_presets_25g[SPX5_SD25G28_MODE_PRESET_25000];
+ else if (macro->speed == SPEED_10000)
+ *mode = mode_presets_25g[SPX5_SD25G28_MODE_PRESET_10000];
+ else if (macro->speed == SPEED_5000)
+ *mode = mode_presets_25g[SPX5_SD25G28_MODE_PRESET_5000];
+ break;
+ case SPX5_SD_MODE_2G5:
+ *mode = mode_presets_25g[SPX5_SD25G28_MODE_PRESET_SD_2G5];
+ break;
+ case SPX5_SD_MODE_1000BASEX:
+ *mode = mode_presets_25g[SPX5_SD25G28_MODE_PRESET_1000BASEX];
+ break;
+ case SPX5_SD_MODE_100FX:
+ /* Not supported */
+ return -EINVAL;
+ default:
+ *mode = mode_presets_25g[SPX5_SD25G28_MODE_PRESET_25000];
+ break;
+ }
+ return 0;
+}
+
+static int sparx5_sd10g28_get_mode_preset(struct sparx5_serdes_macro *macro,
+ struct sparx5_sd10g28_mode_preset *mode,
+ struct sparx5_sd10g28_args *args)
+{
+ switch (macro->serdesmode) {
+ case SPX5_SD_MODE_SFI:
+ if (macro->speed == SPEED_10000) {
+ *mode = mode_presets_10g[SPX5_SD10G28_MODE_PRESET_10000];
+ } else if (macro->speed == SPEED_5000) {
+ if (args->is_6g)
+ *mode = mode_presets_10g[SPX5_SD10G28_MODE_PRESET_SFI_5000_6G];
+ else
+ *mode = mode_presets_10g[SPX5_SD10G28_MODE_PRESET_SFI_5000_10G];
+ } else {
+ dev_err(macro->priv->dev, "%s: Illegal speed: %02u, sidx: %02u, mode (%u)",
+ __func__, macro->speed, macro->sidx,
+ macro->serdesmode);
+ return -EINVAL;
+ }
+ break;
+ case SPX5_SD_MODE_QSGMII:
+ *mode = mode_presets_10g[SPX5_SD10G28_MODE_PRESET_QSGMII];
+ break;
+ case SPX5_SD_MODE_2G5:
+ *mode = mode_presets_10g[SPX5_SD10G28_MODE_PRESET_SD_2G5];
+ break;
+ case SPX5_SD_MODE_100FX:
+ case SPX5_SD_MODE_1000BASEX:
+ *mode = mode_presets_10g[SPX5_SD10G28_MODE_PRESET_1000BASEX];
+ break;
+ default:
+ *mode = mode_presets_10g[SPX5_SD10G28_MODE_PRESET_10000];
+ break;
+ }
+ return 0;
+}
+
+static void sparx5_sd25g28_get_params(struct sparx5_serdes_macro *macro,
+ struct sparx5_sd25g28_media_preset *media,
+ struct sparx5_sd25g28_mode_preset *mode,
+ struct sparx5_sd25g28_args *args,
+ struct sparx5_sd25g28_params *params)
+{
+ u8 iw = sd25g28_get_iw_setting(macro->priv->dev, mode->bitwidth);
+ struct sparx5_sd25g28_params init = {
+ .r_d_width_ctrl_2_0 = iw,
+ .r_txfifo_ck_div_pmad_2_0 = mode->fifo_ck_div,
+ .r_rxfifo_ck_div_pmad_2_0 = mode->fifo_ck_div,
+ .cfg_vco_div_mode_1_0 = mode->vco_div_mode,
+ .cfg_pre_divsel_1_0 = mode->pre_divsel,
+ .cfg_sel_div_3_0 = mode->sel_div,
+ .cfg_vco_start_code_3_0 = 0,
+ .cfg_pma_tx_ck_bitwidth_2_0 = mode->ck_bitwidth,
+ .cfg_tx_prediv_1_0 = mode->tx_pre_div,
+ .cfg_rxdiv_sel_2_0 = mode->ck_bitwidth,
+ .cfg_tx_subrate_2_0 = mode->subrate,
+ .cfg_rx_subrate_2_0 = mode->subrate,
+ .r_multi_lane_mode = 0,
+ .cfg_cdrck_en = 1,
+ .cfg_dfeck_en = mode->dfe_enable,
+ .cfg_dfe_pd = mode->dfe_enable == 1 ? 0 : 1,
+ .cfg_dfedmx_pd = 1,
+ .cfg_dfetap_en_5_1 = mode->dfe_tap,
+ .cfg_dmux_pd = 0,
+ .cfg_dmux_clk_pd = 1,
+ .cfg_erramp_pd = mode->dfe_enable == 1 ? 0 : 1,
+ .cfg_pi_DFE_en = mode->dfe_enable,
+ .cfg_pi_en = 1,
+ .cfg_pd_ctle = 0,
+ .cfg_summer_en = 1,
+ .cfg_pmad_ck_pd = 0,
+ .cfg_pd_clk = 0,
+ .cfg_pd_cml = 0,
+ .cfg_pd_driver = 0,
+ .cfg_rx_reg_pu = 1,
+ .cfg_pd_rms_det = 1,
+ .cfg_dcdr_pd = 0,
+ .cfg_ecdr_pd = 1,
+ .cfg_pd_sq = 1,
+ .cfg_itx_ipdriver_base_2_0 = mode->txmargin,
+ .cfg_tap_dly_4_0 = media->cfg_tap_dly_4_0,
+ .cfg_tap_main = media->cfg_tap_main,
+ .cfg_en_main = media->cfg_en_main,
+ .cfg_tap_adv_3_0 = media->cfg_tap_adv_3_0,
+ .cfg_en_adv = media->cfg_en_adv,
+ .cfg_en_dly = media->cfg_en_dly,
+ .cfg_iscan_en = 0,
+ .l1_pcs_en_fast_iscan = 0,
+ .l0_cfg_bw_1_0 = 0,
+ .cfg_en_dummy = 0,
+ .cfg_pll_reserve_3_0 = args->com_pll_reserve,
+ .l0_cfg_txcal_en = mode->com_txcal_en,
+ .l0_cfg_tx_reserve_15_8 = mode->com_tx_reserve_msb,
+ .l0_cfg_tx_reserve_7_0 = mode->com_tx_reserve_lsb,
+ .cfg_tx_reserve_15_8 = mode->tx_reserve_msb,
+ .cfg_tx_reserve_7_0 = mode->tx_reserve_lsb,
+ .cfg_bw_1_0 = mode->bw,
+ .cfg_txcal_man_en = 1,
+ .cfg_phase_man_4_0 = 0,
+ .cfg_quad_man_1_0 = 0,
+ .cfg_txcal_shift_code_5_0 = 2,
+ .cfg_txcal_valid_sel_3_0 = 4,
+ .cfg_txcal_en = 0,
+ .cfg_cdr_kf_2_0 = 1,
+ .cfg_cdr_m_7_0 = 6,
+ .cfg_pi_bw_3_0 = mode->cfg_pi_bw_3_0,
+ .cfg_pi_steps_1_0 = 0,
+ .cfg_dis_2ndorder = 1,
+ .cfg_ctle_rstn = mode->cfg_ctle_rstn,
+ .r_dfe_rstn = mode->r_dfe_rstn,
+ .cfg_alos_thr_2_0 = media->cfg_alos_thr_2_0,
+ .cfg_itx_ipcml_base_1_0 = mode->cfg_itx_ipcml_base,
+ .cfg_rx_reserve_7_0 = 0xbf,
+ .cfg_rx_reserve_15_8 = 0x61,
+ .cfg_rxterm_2_0 = mode->rxterm,
+ .cfg_fom_selm = 0,
+ .cfg_rx_sp_ctle_1_0 = 0,
+ .cfg_isel_ctle_1_0 = 0,
+ .cfg_vga_ctrl_byp_4_0 = media->cfg_vga_ctrl_byp_4_0,
+ .cfg_vga_byp = 1,
+ .cfg_agc_adpt_byp = 1,
+ .cfg_eqr_byp = 1,
+ .cfg_eqr_force_3_0 = media->cfg_eq_r_force_3_0,
+ .cfg_eqc_force_3_0 = media->cfg_eq_c_force_3_0,
+ .cfg_sum_setcm_en = 1,
+ .cfg_pi_dfe_en = 1,
+ .cfg_init_pos_iscan_6_0 = 6,
+ .cfg_init_pos_ipi_6_0 = 9,
+ .cfg_dfedig_m_2_0 = 6,
+ .cfg_en_dfedig = mode->dfe_enable,
+ .r_d_width_ctrl_from_hwt = 0,
+ .r_reg_manual = 1,
+ .reg_rst = args->reg_rst,
+ .cfg_jc_byp = 1,
+ .cfg_common_reserve_7_0 = 1,
+ .cfg_pll_lol_set = 1,
+ .cfg_tx2rx_lp_en = 0,
+ .cfg_txlb_en = 0,
+ .cfg_rx2tx_lp_en = 0,
+ .cfg_rxlb_en = 0,
+ .r_tx_pol_inv = args->txinvert,
+ .r_rx_pol_inv = args->rxinvert,
+ };
+
+ *params = init;
+}
+
+static void sparx5_sd10g28_get_params(struct sparx5_serdes_macro *macro,
+ struct sparx5_sd10g28_media_preset *media,
+ struct sparx5_sd10g28_mode_preset *mode,
+ struct sparx5_sd10g28_args *args,
+ struct sparx5_sd10g28_params *params)
+{
+ u8 iw = sd10g28_get_iw_setting(macro->priv->dev, mode->bwidth);
+ struct sparx5_sd10g28_params init = {
+ .skip_cmu_cfg = args->skip_cmu_cfg,
+ .is_6g = args->is_6g,
+ .cmu_sel = mode->cmu_sel,
+ .cfg_lane_reserve_7_0 = (mode->cmu_sel % 2) << 6,
+ .cfg_ssc_rtl_clk_sel = (mode->cmu_sel / 2),
+ .cfg_lane_reserve_15_8 = mode->duty_cycle,
+ .cfg_txrate_1_0 = mode->rate,
+ .cfg_rxrate_1_0 = mode->rate,
+ .fx_100 = macro->serdesmode == SPX5_SD_MODE_100FX,
+ .r_d_width_ctrl_2_0 = iw,
+ .cfg_pma_tx_ck_bitwidth_2_0 = iw,
+ .cfg_rxdiv_sel_2_0 = iw,
+ .r_pcs2pma_phymode_4_0 = 0,
+ .cfg_lane_id_2_0 = 0,
+ .cfg_cdrck_en = 1,
+ .cfg_dfeck_en = mode->dfe_enable,
+ .cfg_dfe_pd = (mode->dfe_enable == 1) ? 0 : 1,
+ .cfg_dfetap_en_5_1 = mode->dfe_tap,
+ .cfg_erramp_pd = (mode->dfe_enable == 1) ? 0 : 1,
+ .cfg_pi_DFE_en = mode->dfe_enable,
+ .cfg_pi_en = 1,
+ .cfg_pd_ctle = 0,
+ .cfg_summer_en = 1,
+ .cfg_pd_rx_cktree = 0,
+ .cfg_pd_clk = 0,
+ .cfg_pd_cml = 0,
+ .cfg_pd_driver = 0,
+ .cfg_rx_reg_pu = 1,
+ .cfg_d_cdr_pd = 0,
+ .cfg_pd_sq = mode->dfe_enable,
+ .cfg_rxdet_en = 0,
+ .cfg_rxdet_str = 0,
+ .r_multi_lane_mode = 0,
+ .cfg_en_adv = media->cfg_en_adv,
+ .cfg_en_main = 1,
+ .cfg_en_dly = media->cfg_en_dly,
+ .cfg_tap_adv_3_0 = media->cfg_tap_adv_3_0,
+ .cfg_tap_main = media->cfg_tap_main,
+ .cfg_tap_dly_4_0 = media->cfg_tap_dly_4_0,
+ .cfg_vga_ctrl_3_0 = media->cfg_vga_ctrl_3_0,
+ .cfg_vga_cp_2_0 = media->cfg_vga_cp_2_0,
+ .cfg_eq_res_3_0 = media->cfg_eq_res_3_0,
+ .cfg_eq_r_byp = media->cfg_eq_r_byp,
+ .cfg_eq_c_force_3_0 = media->cfg_eq_c_force_3_0,
+ .cfg_en_dfedig = mode->dfe_enable,
+ .cfg_sum_setcm_en = 1,
+ .cfg_en_preemph = 0,
+ .cfg_itx_ippreemp_base_1_0 = 0,
+ .cfg_itx_ipdriver_base_2_0 = (args->txswing >> 6),
+ .cfg_ibias_tune_reserve_5_0 = (args->txswing & 63),
+ .cfg_txswing_half = (args->txmargin),
+ .cfg_dis_2nd_order = 0x1,
+ .cfg_rx_ssc_lh = 0x0,
+ .cfg_pi_floop_steps_1_0 = 0x0,
+ .cfg_pi_ext_dac_23_16 = (1 << 5),
+ .cfg_pi_ext_dac_15_8 = (0 << 6),
+ .cfg_iscan_ext_dac_7_0 = (1 << 7) + 9,
+ .cfg_cdr_kf_gen1_2_0 = 1,
+ .cfg_cdr_kf_gen2_2_0 = 1,
+ .cfg_cdr_kf_gen3_2_0 = 1,
+ .cfg_cdr_kf_gen4_2_0 = 1,
+ .r_cdr_m_gen1_7_0 = 4,
+ .cfg_pi_bw_gen1_3_0 = mode->pi_bw_gen1,
+ .cfg_pi_bw_gen2 = mode->pi_bw_gen1,
+ .cfg_pi_bw_gen3 = mode->pi_bw_gen1,
+ .cfg_pi_bw_gen4 = mode->pi_bw_gen1,
+ .cfg_pi_ext_dac_7_0 = 3,
+ .cfg_pi_steps = 0,
+ .cfg_mp_max_3_0 = 1,
+ .cfg_rstn_dfedig = mode->dfe_enable,
+ .cfg_alos_thr_3_0 = media->cfg_alos_thr_3_0,
+ .cfg_predrv_slewrate_1_0 = 3,
+ .cfg_itx_ipcml_base_1_0 = 0,
+ .cfg_ip_pre_base_1_0 = 0,
+ .r_cdr_m_gen2_7_0 = 2,
+ .r_cdr_m_gen3_7_0 = 2,
+ .r_cdr_m_gen4_7_0 = 2,
+ .r_en_auto_cdr_rstn = 0,
+ .cfg_oscal_afe = 1,
+ .cfg_pd_osdac_afe = 0,
+ .cfg_resetb_oscal_afe[0] = 0,
+ .cfg_resetb_oscal_afe[1] = 1,
+ .cfg_center_spreading = 0,
+ .cfg_m_cnt_maxval_4_0 = 15,
+ .cfg_ncnt_maxval_7_0 = 32,
+ .cfg_ncnt_maxval_10_8 = 6,
+ .cfg_ssc_en = 1,
+ .cfg_tx2rx_lp_en = 0,
+ .cfg_txlb_en = 0,
+ .cfg_rx2tx_lp_en = 0,
+ .cfg_rxlb_en = 0,
+ .r_tx_pol_inv = args->txinvert,
+ .r_rx_pol_inv = args->rxinvert,
+ };
+
+ *params = init;
+}
+
+static void sparx5_sd25g28_reset(void __iomem *regs[],
+ struct sparx5_sd25g28_params *params,
+ u32 sd_index)
+{
+ if (params->reg_rst == 1) {
+ sdx5_rmw_addr(SD_LANE_25G_SD_LANE_CFG_EXT_CFG_RST_SET(1),
+ SD_LANE_25G_SD_LANE_CFG_EXT_CFG_RST,
+ sdx5_addr(regs, SD_LANE_25G_SD_LANE_CFG(sd_index)));
+
+ usleep_range(1000, 2000);
+
+ sdx5_rmw_addr(SD_LANE_25G_SD_LANE_CFG_EXT_CFG_RST_SET(0),
+ SD_LANE_25G_SD_LANE_CFG_EXT_CFG_RST,
+ sdx5_addr(regs, SD_LANE_25G_SD_LANE_CFG(sd_index)));
+ }
+}
+
+static int sparx5_sd25g28_apply_params(struct sparx5_serdes_macro *macro,
+ struct sparx5_sd25g28_params *params)
+{
+ struct sparx5_serdes_private *priv = macro->priv;
+ void __iomem **regs = priv->regs;
+ struct device *dev = priv->dev;
+ u32 sd_index = macro->stpidx;
+ u32 value;
+
+ sdx5_rmw(SD_LANE_25G_SD_LANE_CFG_MACRO_RST_SET(1),
+ SD_LANE_25G_SD_LANE_CFG_MACRO_RST,
+ priv,
+ SD_LANE_25G_SD_LANE_CFG(sd_index));
+
+ sdx5_rmw(SD25G_LANE_CMU_FF_REGISTER_TABLE_INDEX_SET(0xFF),
+ SD25G_LANE_CMU_FF_REGISTER_TABLE_INDEX,
+ priv,
+ SD25G_LANE_CMU_FF(sd_index));
+
+ sdx5_rmw(SD25G_LANE_CMU_1A_R_DWIDTHCTRL_FROM_HWT_SET
+ (params->r_d_width_ctrl_from_hwt) |
+ SD25G_LANE_CMU_1A_R_REG_MANUAL_SET(params->r_reg_manual),
+ SD25G_LANE_CMU_1A_R_DWIDTHCTRL_FROM_HWT |
+ SD25G_LANE_CMU_1A_R_REG_MANUAL,
+ priv,
+ SD25G_LANE_CMU_1A(sd_index));
+
+ sdx5_rmw(SD25G_LANE_CMU_31_CFG_COMMON_RESERVE_7_0_SET
+ (params->cfg_common_reserve_7_0),
+ SD25G_LANE_CMU_31_CFG_COMMON_RESERVE_7_0,
+ priv,
+ SD25G_LANE_CMU_31(sd_index));
+
+ sdx5_rmw(SD25G_LANE_CMU_09_CFG_EN_DUMMY_SET(params->cfg_en_dummy),
+ SD25G_LANE_CMU_09_CFG_EN_DUMMY,
+ priv,
+ SD25G_LANE_CMU_09(sd_index));
+
+ sdx5_rmw(SD25G_LANE_CMU_13_CFG_PLL_RESERVE_3_0_SET
+ (params->cfg_pll_reserve_3_0),
+ SD25G_LANE_CMU_13_CFG_PLL_RESERVE_3_0,
+ priv,
+ SD25G_LANE_CMU_13(sd_index));
+
+ sdx5_rmw(SD25G_LANE_CMU_40_L0_CFG_TXCAL_EN_SET(params->l0_cfg_txcal_en),
+ SD25G_LANE_CMU_40_L0_CFG_TXCAL_EN,
+ priv,
+ SD25G_LANE_CMU_40(sd_index));
+
+ sdx5_rmw(SD25G_LANE_CMU_46_L0_CFG_TX_RESERVE_15_8_SET
+ (params->l0_cfg_tx_reserve_15_8),
+ SD25G_LANE_CMU_46_L0_CFG_TX_RESERVE_15_8,
+ priv,
+ SD25G_LANE_CMU_46(sd_index));
+
+ sdx5_rmw(SD25G_LANE_CMU_45_L0_CFG_TX_RESERVE_7_0_SET
+ (params->l0_cfg_tx_reserve_7_0),
+ SD25G_LANE_CMU_45_L0_CFG_TX_RESERVE_7_0,
+ priv,
+ SD25G_LANE_CMU_45(sd_index));
+
+ sdx5_rmw(SD25G_LANE_CMU_0B_CFG_VCO_CAL_RESETN_SET(0),
+ SD25G_LANE_CMU_0B_CFG_VCO_CAL_RESETN,
+ priv,
+ SD25G_LANE_CMU_0B(sd_index));
+
+ sdx5_rmw(SD25G_LANE_CMU_0B_CFG_VCO_CAL_RESETN_SET(1),
+ SD25G_LANE_CMU_0B_CFG_VCO_CAL_RESETN,
+ priv,
+ SD25G_LANE_CMU_0B(sd_index));
+
+ sdx5_rmw(SD25G_LANE_CMU_19_R_CK_RESETB_SET(0),
+ SD25G_LANE_CMU_19_R_CK_RESETB,
+ priv,
+ SD25G_LANE_CMU_19(sd_index));
+
+ sdx5_rmw(SD25G_LANE_CMU_19_R_CK_RESETB_SET(1),
+ SD25G_LANE_CMU_19_R_CK_RESETB,
+ priv,
+ SD25G_LANE_CMU_19(sd_index));
+
+ sdx5_rmw(SD25G_LANE_CMU_18_R_PLL_RSTN_SET(0),
+ SD25G_LANE_CMU_18_R_PLL_RSTN,
+ priv,
+ SD25G_LANE_CMU_18(sd_index));
+
+ sdx5_rmw(SD25G_LANE_CMU_18_R_PLL_RSTN_SET(1),
+ SD25G_LANE_CMU_18_R_PLL_RSTN,
+ priv,
+ SD25G_LANE_CMU_18(sd_index));
+
+ sdx5_rmw(SD25G_LANE_CMU_1A_R_DWIDTHCTRL_2_0_SET(params->r_d_width_ctrl_2_0),
+ SD25G_LANE_CMU_1A_R_DWIDTHCTRL_2_0,
+ priv,
+ SD25G_LANE_CMU_1A(sd_index));
+
+ sdx5_rmw(SD25G_LANE_CMU_30_R_TXFIFO_CK_DIV_PMAD_2_0_SET
+ (params->r_txfifo_ck_div_pmad_2_0) |
+ SD25G_LANE_CMU_30_R_RXFIFO_CK_DIV_PMAD_2_0_SET
+ (params->r_rxfifo_ck_div_pmad_2_0),
+ SD25G_LANE_CMU_30_R_TXFIFO_CK_DIV_PMAD_2_0 |
+ SD25G_LANE_CMU_30_R_RXFIFO_CK_DIV_PMAD_2_0,
+ priv,
+ SD25G_LANE_CMU_30(sd_index));
+
+ sdx5_rmw(SD25G_LANE_CMU_0C_CFG_PLL_LOL_SET_SET(params->cfg_pll_lol_set) |
+ SD25G_LANE_CMU_0C_CFG_VCO_DIV_MODE_1_0_SET
+ (params->cfg_vco_div_mode_1_0),
+ SD25G_LANE_CMU_0C_CFG_PLL_LOL_SET |
+ SD25G_LANE_CMU_0C_CFG_VCO_DIV_MODE_1_0,
+ priv,
+ SD25G_LANE_CMU_0C(sd_index));
+
+ sdx5_rmw(SD25G_LANE_CMU_0D_CFG_PRE_DIVSEL_1_0_SET
+ (params->cfg_pre_divsel_1_0),
+ SD25G_LANE_CMU_0D_CFG_PRE_DIVSEL_1_0,
+ priv,
+ SD25G_LANE_CMU_0D(sd_index));
+
+ sdx5_rmw(SD25G_LANE_CMU_0E_CFG_SEL_DIV_3_0_SET(params->cfg_sel_div_3_0),
+ SD25G_LANE_CMU_0E_CFG_SEL_DIV_3_0,
+ priv,
+ SD25G_LANE_CMU_0E(sd_index));
+
+ sdx5_rmw(SD25G_LANE_CMU_FF_REGISTER_TABLE_INDEX_SET(0x00),
+ SD25G_LANE_CMU_FF_REGISTER_TABLE_INDEX,
+ priv,
+ SD25G_LANE_CMU_FF(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_0C_LN_CFG_PMA_TX_CK_BITWIDTH_2_0_SET
+ (params->cfg_pma_tx_ck_bitwidth_2_0),
+ SD25G_LANE_LANE_0C_LN_CFG_PMA_TX_CK_BITWIDTH_2_0,
+ priv,
+ SD25G_LANE_LANE_0C(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_01_LN_CFG_TX_PREDIV_1_0_SET
+ (params->cfg_tx_prediv_1_0),
+ SD25G_LANE_LANE_01_LN_CFG_TX_PREDIV_1_0,
+ priv,
+ SD25G_LANE_LANE_01(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_18_LN_CFG_RXDIV_SEL_2_0_SET
+ (params->cfg_rxdiv_sel_2_0),
+ SD25G_LANE_LANE_18_LN_CFG_RXDIV_SEL_2_0,
+ priv,
+ SD25G_LANE_LANE_18(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_2C_LN_CFG_TX_SUBRATE_2_0_SET
+ (params->cfg_tx_subrate_2_0),
+ SD25G_LANE_LANE_2C_LN_CFG_TX_SUBRATE_2_0,
+ priv,
+ SD25G_LANE_LANE_2C(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_28_LN_CFG_RX_SUBRATE_2_0_SET
+ (params->cfg_rx_subrate_2_0),
+ SD25G_LANE_LANE_28_LN_CFG_RX_SUBRATE_2_0,
+ priv,
+ SD25G_LANE_LANE_28(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_18_LN_CFG_CDRCK_EN_SET(params->cfg_cdrck_en),
+ SD25G_LANE_LANE_18_LN_CFG_CDRCK_EN,
+ priv,
+ SD25G_LANE_LANE_18(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_0F_LN_CFG_DFETAP_EN_5_1_SET
+ (params->cfg_dfetap_en_5_1),
+ SD25G_LANE_LANE_0F_LN_CFG_DFETAP_EN_5_1,
+ priv,
+ SD25G_LANE_LANE_0F(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_18_LN_CFG_ERRAMP_PD_SET(params->cfg_erramp_pd),
+ SD25G_LANE_LANE_18_LN_CFG_ERRAMP_PD,
+ priv,
+ SD25G_LANE_LANE_18(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_1D_LN_CFG_PI_DFE_EN_SET(params->cfg_pi_dfe_en),
+ SD25G_LANE_LANE_1D_LN_CFG_PI_DFE_EN,
+ priv,
+ SD25G_LANE_LANE_1D(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_19_LN_CFG_ECDR_PD_SET(params->cfg_ecdr_pd),
+ SD25G_LANE_LANE_19_LN_CFG_ECDR_PD,
+ priv,
+ SD25G_LANE_LANE_19(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_01_LN_CFG_ITX_IPDRIVER_BASE_2_0_SET
+ (params->cfg_itx_ipdriver_base_2_0),
+ SD25G_LANE_LANE_01_LN_CFG_ITX_IPDRIVER_BASE_2_0,
+ priv,
+ SD25G_LANE_LANE_01(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_03_LN_CFG_TAP_DLY_4_0_SET(params->cfg_tap_dly_4_0),
+ SD25G_LANE_LANE_03_LN_CFG_TAP_DLY_4_0,
+ priv,
+ SD25G_LANE_LANE_03(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_06_LN_CFG_TAP_ADV_3_0_SET(params->cfg_tap_adv_3_0),
+ SD25G_LANE_LANE_06_LN_CFG_TAP_ADV_3_0,
+ priv,
+ SD25G_LANE_LANE_06(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_07_LN_CFG_EN_ADV_SET(params->cfg_en_adv) |
+ SD25G_LANE_LANE_07_LN_CFG_EN_DLY_SET(params->cfg_en_dly),
+ SD25G_LANE_LANE_07_LN_CFG_EN_ADV |
+ SD25G_LANE_LANE_07_LN_CFG_EN_DLY,
+ priv,
+ SD25G_LANE_LANE_07(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_43_LN_CFG_TX_RESERVE_15_8_SET
+ (params->cfg_tx_reserve_15_8),
+ SD25G_LANE_LANE_43_LN_CFG_TX_RESERVE_15_8,
+ priv,
+ SD25G_LANE_LANE_43(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_42_LN_CFG_TX_RESERVE_7_0_SET
+ (params->cfg_tx_reserve_7_0),
+ SD25G_LANE_LANE_42_LN_CFG_TX_RESERVE_7_0,
+ priv,
+ SD25G_LANE_LANE_42(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_05_LN_CFG_BW_1_0_SET(params->cfg_bw_1_0),
+ SD25G_LANE_LANE_05_LN_CFG_BW_1_0,
+ priv,
+ SD25G_LANE_LANE_05(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_0B_LN_CFG_TXCAL_MAN_EN_SET
+ (params->cfg_txcal_man_en),
+ SD25G_LANE_LANE_0B_LN_CFG_TXCAL_MAN_EN,
+ priv,
+ SD25G_LANE_LANE_0B(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_0A_LN_CFG_TXCAL_SHIFT_CODE_5_0_SET
+ (params->cfg_txcal_shift_code_5_0),
+ SD25G_LANE_LANE_0A_LN_CFG_TXCAL_SHIFT_CODE_5_0,
+ priv,
+ SD25G_LANE_LANE_0A(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_09_LN_CFG_TXCAL_VALID_SEL_3_0_SET
+ (params->cfg_txcal_valid_sel_3_0),
+ SD25G_LANE_LANE_09_LN_CFG_TXCAL_VALID_SEL_3_0,
+ priv,
+ SD25G_LANE_LANE_09(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_1A_LN_CFG_CDR_KF_2_0_SET(params->cfg_cdr_kf_2_0),
+ SD25G_LANE_LANE_1A_LN_CFG_CDR_KF_2_0,
+ priv,
+ SD25G_LANE_LANE_1A(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_1B_LN_CFG_CDR_M_7_0_SET(params->cfg_cdr_m_7_0),
+ SD25G_LANE_LANE_1B_LN_CFG_CDR_M_7_0,
+ priv,
+ SD25G_LANE_LANE_1B(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_2B_LN_CFG_PI_BW_3_0_SET(params->cfg_pi_bw_3_0),
+ SD25G_LANE_LANE_2B_LN_CFG_PI_BW_3_0,
+ priv,
+ SD25G_LANE_LANE_2B(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_2C_LN_CFG_DIS_2NDORDER_SET
+ (params->cfg_dis_2ndorder),
+ SD25G_LANE_LANE_2C_LN_CFG_DIS_2NDORDER,
+ priv,
+ SD25G_LANE_LANE_2C(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_2E_LN_CFG_CTLE_RSTN_SET(params->cfg_ctle_rstn),
+ SD25G_LANE_LANE_2E_LN_CFG_CTLE_RSTN,
+ priv,
+ SD25G_LANE_LANE_2E(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_00_LN_CFG_ITX_IPCML_BASE_1_0_SET
+ (params->cfg_itx_ipcml_base_1_0),
+ SD25G_LANE_LANE_00_LN_CFG_ITX_IPCML_BASE_1_0,
+ priv,
+ SD25G_LANE_LANE_00(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_44_LN_CFG_RX_RESERVE_7_0_SET
+ (params->cfg_rx_reserve_7_0),
+ SD25G_LANE_LANE_44_LN_CFG_RX_RESERVE_7_0,
+ priv,
+ SD25G_LANE_LANE_44(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_45_LN_CFG_RX_RESERVE_15_8_SET
+ (params->cfg_rx_reserve_15_8),
+ SD25G_LANE_LANE_45_LN_CFG_RX_RESERVE_15_8,
+ priv,
+ SD25G_LANE_LANE_45(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_0D_LN_CFG_DFECK_EN_SET(params->cfg_dfeck_en) |
+ SD25G_LANE_LANE_0D_LN_CFG_RXTERM_2_0_SET(params->cfg_rxterm_2_0),
+ SD25G_LANE_LANE_0D_LN_CFG_DFECK_EN |
+ SD25G_LANE_LANE_0D_LN_CFG_RXTERM_2_0,
+ priv,
+ SD25G_LANE_LANE_0D(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_21_LN_CFG_VGA_CTRL_BYP_4_0_SET
+ (params->cfg_vga_ctrl_byp_4_0),
+ SD25G_LANE_LANE_21_LN_CFG_VGA_CTRL_BYP_4_0,
+ priv,
+ SD25G_LANE_LANE_21(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_22_LN_CFG_EQR_FORCE_3_0_SET
+ (params->cfg_eqr_force_3_0),
+ SD25G_LANE_LANE_22_LN_CFG_EQR_FORCE_3_0,
+ priv,
+ SD25G_LANE_LANE_22(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_1C_LN_CFG_EQC_FORCE_3_0_SET
+ (params->cfg_eqc_force_3_0) |
+ SD25G_LANE_LANE_1C_LN_CFG_DFE_PD_SET(params->cfg_dfe_pd),
+ SD25G_LANE_LANE_1C_LN_CFG_EQC_FORCE_3_0 |
+ SD25G_LANE_LANE_1C_LN_CFG_DFE_PD,
+ priv,
+ SD25G_LANE_LANE_1C(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_1E_LN_CFG_SUM_SETCM_EN_SET
+ (params->cfg_sum_setcm_en),
+ SD25G_LANE_LANE_1E_LN_CFG_SUM_SETCM_EN,
+ priv,
+ SD25G_LANE_LANE_1E(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_25_LN_CFG_INIT_POS_ISCAN_6_0_SET
+ (params->cfg_init_pos_iscan_6_0),
+ SD25G_LANE_LANE_25_LN_CFG_INIT_POS_ISCAN_6_0,
+ priv,
+ SD25G_LANE_LANE_25(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_26_LN_CFG_INIT_POS_IPI_6_0_SET
+ (params->cfg_init_pos_ipi_6_0),
+ SD25G_LANE_LANE_26_LN_CFG_INIT_POS_IPI_6_0,
+ priv,
+ SD25G_LANE_LANE_26(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_18_LN_CFG_ERRAMP_PD_SET(params->cfg_erramp_pd),
+ SD25G_LANE_LANE_18_LN_CFG_ERRAMP_PD,
+ priv,
+ SD25G_LANE_LANE_18(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_0E_LN_CFG_DFEDIG_M_2_0_SET
+ (params->cfg_dfedig_m_2_0),
+ SD25G_LANE_LANE_0E_LN_CFG_DFEDIG_M_2_0,
+ priv,
+ SD25G_LANE_LANE_0E(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_0E_LN_CFG_EN_DFEDIG_SET(params->cfg_en_dfedig),
+ SD25G_LANE_LANE_0E_LN_CFG_EN_DFEDIG,
+ priv,
+ SD25G_LANE_LANE_0E(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_40_LN_R_TX_POL_INV_SET(params->r_tx_pol_inv) |
+ SD25G_LANE_LANE_40_LN_R_RX_POL_INV_SET(params->r_rx_pol_inv),
+ SD25G_LANE_LANE_40_LN_R_TX_POL_INV |
+ SD25G_LANE_LANE_40_LN_R_RX_POL_INV,
+ priv,
+ SD25G_LANE_LANE_40(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_04_LN_CFG_RX2TX_LP_EN_SET(params->cfg_rx2tx_lp_en) |
+ SD25G_LANE_LANE_04_LN_CFG_TX2RX_LP_EN_SET(params->cfg_tx2rx_lp_en),
+ SD25G_LANE_LANE_04_LN_CFG_RX2TX_LP_EN |
+ SD25G_LANE_LANE_04_LN_CFG_TX2RX_LP_EN,
+ priv,
+ SD25G_LANE_LANE_04(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_1E_LN_CFG_RXLB_EN_SET(params->cfg_rxlb_en),
+ SD25G_LANE_LANE_1E_LN_CFG_RXLB_EN,
+ priv,
+ SD25G_LANE_LANE_1E(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_19_LN_CFG_TXLB_EN_SET(params->cfg_txlb_en),
+ SD25G_LANE_LANE_19_LN_CFG_TXLB_EN,
+ priv,
+ SD25G_LANE_LANE_19(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_2E_LN_CFG_RSTN_DFEDIG_SET(0),
+ SD25G_LANE_LANE_2E_LN_CFG_RSTN_DFEDIG,
+ priv,
+ SD25G_LANE_LANE_2E(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_2E_LN_CFG_RSTN_DFEDIG_SET(1),
+ SD25G_LANE_LANE_2E_LN_CFG_RSTN_DFEDIG,
+ priv,
+ SD25G_LANE_LANE_2E(sd_index));
+
+ sdx5_rmw(SD_LANE_25G_SD_LANE_CFG_MACRO_RST_SET(0),
+ SD_LANE_25G_SD_LANE_CFG_MACRO_RST,
+ priv,
+ SD_LANE_25G_SD_LANE_CFG(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_1C_LN_CFG_CDR_RSTN_SET(0),
+ SD25G_LANE_LANE_1C_LN_CFG_CDR_RSTN,
+ priv,
+ SD25G_LANE_LANE_1C(sd_index));
+
+ usleep_range(1000, 2000);
+
+ sdx5_rmw(SD25G_LANE_LANE_1C_LN_CFG_CDR_RSTN_SET(1),
+ SD25G_LANE_LANE_1C_LN_CFG_CDR_RSTN,
+ priv,
+ SD25G_LANE_LANE_1C(sd_index));
+
+ usleep_range(10000, 20000);
+
+ sdx5_rmw(SD25G_LANE_CMU_FF_REGISTER_TABLE_INDEX_SET(0xff),
+ SD25G_LANE_CMU_FF_REGISTER_TABLE_INDEX,
+ priv,
+ SD25G_LANE_CMU_FF(sd_index));
+
+ value = readl(sdx5_addr(regs, SD25G_LANE_CMU_C0(sd_index)));
+ value = SD25G_LANE_CMU_C0_PLL_LOL_UDL_GET(value);
+
+ if (value) {
+ dev_err(dev, "25G PLL Loss of Lock: 0x%x\n", value);
+ return -EINVAL;
+ }
+
+ value = readl(sdx5_addr(regs, SD_LANE_25G_SD_LANE_STAT(sd_index)));
+ value = SD_LANE_25G_SD_LANE_STAT_PMA_RST_DONE_GET(value);
+
+ if (value != 0x1) {
+ dev_err(dev, "25G PMA Reset failed: 0x%x\n", value);
+ return -EINVAL;
+ }
+ sdx5_rmw(SD25G_LANE_CMU_2A_R_DBG_LOL_STATUS_SET(0x1),
+ SD25G_LANE_CMU_2A_R_DBG_LOL_STATUS,
+ priv,
+ SD25G_LANE_CMU_2A(sd_index));
+
+ sdx5_rmw(SD_LANE_25G_SD_SER_RST_SER_RST_SET(0x0),
+ SD_LANE_25G_SD_SER_RST_SER_RST,
+ priv,
+ SD_LANE_25G_SD_SER_RST(sd_index));
+
+ sdx5_rmw(SD_LANE_25G_SD_DES_RST_DES_RST_SET(0x0),
+ SD_LANE_25G_SD_DES_RST_DES_RST,
+ priv,
+ SD_LANE_25G_SD_DES_RST(sd_index));
+
+ sdx5_rmw(SD25G_LANE_CMU_FF_REGISTER_TABLE_INDEX_SET(0),
+ SD25G_LANE_CMU_FF_REGISTER_TABLE_INDEX,
+ priv,
+ SD25G_LANE_CMU_FF(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_2D_LN_CFG_ALOS_THR_2_0_SET
+ (params->cfg_alos_thr_2_0),
+ SD25G_LANE_LANE_2D_LN_CFG_ALOS_THR_2_0,
+ priv,
+ SD25G_LANE_LANE_2D(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_2E_LN_CFG_DIS_SQ_SET(0),
+ SD25G_LANE_LANE_2E_LN_CFG_DIS_SQ,
+ priv,
+ SD25G_LANE_LANE_2E(sd_index));
+
+ sdx5_rmw(SD25G_LANE_LANE_2E_LN_CFG_PD_SQ_SET(0),
+ SD25G_LANE_LANE_2E_LN_CFG_PD_SQ,
+ priv,
+ SD25G_LANE_LANE_2E(sd_index));
+
+ return 0;
+}
+
+static void sparx5_sd10g28_reset(void __iomem *regs[], u32 lane_index)
+{
+ /* Note: SerDes SD10G_LANE_1 is configured in 10G_LAN mode */
+ sdx5_rmw_addr(SD_LANE_SD_LANE_CFG_EXT_CFG_RST_SET(1),
+ SD_LANE_SD_LANE_CFG_EXT_CFG_RST,
+ sdx5_addr(regs, SD_LANE_SD_LANE_CFG(lane_index)));
+
+ usleep_range(1000, 2000);
+
+ sdx5_rmw_addr(SD_LANE_SD_LANE_CFG_EXT_CFG_RST_SET(0),
+ SD_LANE_SD_LANE_CFG_EXT_CFG_RST,
+ sdx5_addr(regs, SD_LANE_SD_LANE_CFG(lane_index)));
+}
+
+static int sparx5_sd10g28_apply_params(struct sparx5_serdes_macro *macro,
+ struct sparx5_sd10g28_params *params)
+{
+ struct sparx5_serdes_private *priv = macro->priv;
+ void __iomem **regs = priv->regs;
+ struct device *dev = priv->dev;
+ u32 lane_index = macro->sidx;
+ u32 sd_index = macro->stpidx;
+ void __iomem *sd_inst;
+ u32 value;
+
+ if (params->is_6g)
+ sd_inst = sdx5_inst_get(priv, TARGET_SD6G_LANE, sd_index);
+ else
+ sd_inst = sdx5_inst_get(priv, TARGET_SD10G_LANE, sd_index);
+
+ sdx5_rmw(SD_LANE_SD_LANE_CFG_MACRO_RST_SET(1),
+ SD_LANE_SD_LANE_CFG_MACRO_RST,
+ priv,
+ SD_LANE_SD_LANE_CFG(lane_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_93_R_DWIDTHCTRL_FROM_HWT_SET(0x0) |
+ SD10G_LANE_LANE_93_R_REG_MANUAL_SET(0x1) |
+ SD10G_LANE_LANE_93_R_AUXCKSEL_FROM_HWT_SET(0x1) |
+ SD10G_LANE_LANE_93_R_LANE_ID_FROM_HWT_SET(0x1) |
+ SD10G_LANE_LANE_93_R_EN_RATECHG_CTRL_SET(0x0),
+ SD10G_LANE_LANE_93_R_DWIDTHCTRL_FROM_HWT |
+ SD10G_LANE_LANE_93_R_REG_MANUAL |
+ SD10G_LANE_LANE_93_R_AUXCKSEL_FROM_HWT |
+ SD10G_LANE_LANE_93_R_LANE_ID_FROM_HWT |
+ SD10G_LANE_LANE_93_R_EN_RATECHG_CTRL,
+ sd_inst,
+ SD10G_LANE_LANE_93(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_94_R_ISCAN_REG_SET(0x1) |
+ SD10G_LANE_LANE_94_R_TXEQ_REG_SET(0x1) |
+ SD10G_LANE_LANE_94_R_MISC_REG_SET(0x1) |
+ SD10G_LANE_LANE_94_R_SWING_REG_SET(0x1),
+ SD10G_LANE_LANE_94_R_ISCAN_REG |
+ SD10G_LANE_LANE_94_R_TXEQ_REG |
+ SD10G_LANE_LANE_94_R_MISC_REG |
+ SD10G_LANE_LANE_94_R_SWING_REG,
+ sd_inst,
+ SD10G_LANE_LANE_94(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_9E_R_RXEQ_REG_SET(0x1),
+ SD10G_LANE_LANE_9E_R_RXEQ_REG,
+ sd_inst,
+ SD10G_LANE_LANE_9E(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_A1_R_SSC_FROM_HWT_SET(0x0) |
+ SD10G_LANE_LANE_A1_R_CDR_FROM_HWT_SET(0x0) |
+ SD10G_LANE_LANE_A1_R_PCLK_GATING_FROM_HWT_SET(0x1),
+ SD10G_LANE_LANE_A1_R_SSC_FROM_HWT |
+ SD10G_LANE_LANE_A1_R_CDR_FROM_HWT |
+ SD10G_LANE_LANE_A1_R_PCLK_GATING_FROM_HWT,
+ sd_inst,
+ SD10G_LANE_LANE_A1(sd_index));
+
+ sdx5_rmw(SD_LANE_SD_LANE_CFG_RX_REF_SEL_SET(params->cmu_sel) |
+ SD_LANE_SD_LANE_CFG_TX_REF_SEL_SET(params->cmu_sel),
+ SD_LANE_SD_LANE_CFG_RX_REF_SEL |
+ SD_LANE_SD_LANE_CFG_TX_REF_SEL,
+ priv,
+ SD_LANE_SD_LANE_CFG(lane_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_40_CFG_LANE_RESERVE_7_0_SET
+ (params->cfg_lane_reserve_7_0),
+ SD10G_LANE_LANE_40_CFG_LANE_RESERVE_7_0,
+ sd_inst,
+ SD10G_LANE_LANE_40(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_50_CFG_SSC_RTL_CLK_SEL_SET
+ (params->cfg_ssc_rtl_clk_sel),
+ SD10G_LANE_LANE_50_CFG_SSC_RTL_CLK_SEL,
+ sd_inst,
+ SD10G_LANE_LANE_50(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_35_CFG_TXRATE_1_0_SET
+ (params->cfg_txrate_1_0) |
+ SD10G_LANE_LANE_35_CFG_RXRATE_1_0_SET
+ (params->cfg_rxrate_1_0),
+ SD10G_LANE_LANE_35_CFG_TXRATE_1_0 |
+ SD10G_LANE_LANE_35_CFG_RXRATE_1_0,
+ sd_inst,
+ SD10G_LANE_LANE_35(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_94_R_DWIDTHCTRL_2_0_SET
+ (params->r_d_width_ctrl_2_0),
+ SD10G_LANE_LANE_94_R_DWIDTHCTRL_2_0,
+ sd_inst,
+ SD10G_LANE_LANE_94(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_01_CFG_PMA_TX_CK_BITWIDTH_2_0_SET
+ (params->cfg_pma_tx_ck_bitwidth_2_0),
+ SD10G_LANE_LANE_01_CFG_PMA_TX_CK_BITWIDTH_2_0,
+ sd_inst,
+ SD10G_LANE_LANE_01(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_30_CFG_RXDIV_SEL_2_0_SET
+ (params->cfg_rxdiv_sel_2_0),
+ SD10G_LANE_LANE_30_CFG_RXDIV_SEL_2_0,
+ sd_inst,
+ SD10G_LANE_LANE_30(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_A2_R_PCS2PMA_PHYMODE_4_0_SET
+ (params->r_pcs2pma_phymode_4_0),
+ SD10G_LANE_LANE_A2_R_PCS2PMA_PHYMODE_4_0,
+ sd_inst,
+ SD10G_LANE_LANE_A2(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_13_CFG_CDRCK_EN_SET(params->cfg_cdrck_en),
+ SD10G_LANE_LANE_13_CFG_CDRCK_EN,
+ sd_inst,
+ SD10G_LANE_LANE_13(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_23_CFG_DFECK_EN_SET
+ (params->cfg_dfeck_en) |
+ SD10G_LANE_LANE_23_CFG_DFE_PD_SET(params->cfg_dfe_pd) |
+ SD10G_LANE_LANE_23_CFG_ERRAMP_PD_SET
+ (params->cfg_erramp_pd),
+ SD10G_LANE_LANE_23_CFG_DFECK_EN |
+ SD10G_LANE_LANE_23_CFG_DFE_PD |
+ SD10G_LANE_LANE_23_CFG_ERRAMP_PD,
+ sd_inst,
+ SD10G_LANE_LANE_23(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_22_CFG_DFETAP_EN_5_1_SET
+ (params->cfg_dfetap_en_5_1),
+ SD10G_LANE_LANE_22_CFG_DFETAP_EN_5_1,
+ sd_inst,
+ SD10G_LANE_LANE_22(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_1A_CFG_PI_DFE_EN_SET
+ (params->cfg_pi_DFE_en),
+ SD10G_LANE_LANE_1A_CFG_PI_DFE_EN,
+ sd_inst,
+ SD10G_LANE_LANE_1A(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_02_CFG_EN_ADV_SET(params->cfg_en_adv) |
+ SD10G_LANE_LANE_02_CFG_EN_MAIN_SET(params->cfg_en_main) |
+ SD10G_LANE_LANE_02_CFG_EN_DLY_SET(params->cfg_en_dly) |
+ SD10G_LANE_LANE_02_CFG_TAP_ADV_3_0_SET
+ (params->cfg_tap_adv_3_0),
+ SD10G_LANE_LANE_02_CFG_EN_ADV |
+ SD10G_LANE_LANE_02_CFG_EN_MAIN |
+ SD10G_LANE_LANE_02_CFG_EN_DLY |
+ SD10G_LANE_LANE_02_CFG_TAP_ADV_3_0,
+ sd_inst,
+ SD10G_LANE_LANE_02(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_03_CFG_TAP_MAIN_SET(params->cfg_tap_main),
+ SD10G_LANE_LANE_03_CFG_TAP_MAIN,
+ sd_inst,
+ SD10G_LANE_LANE_03(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_04_CFG_TAP_DLY_4_0_SET
+ (params->cfg_tap_dly_4_0),
+ SD10G_LANE_LANE_04_CFG_TAP_DLY_4_0,
+ sd_inst,
+ SD10G_LANE_LANE_04(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_2F_CFG_VGA_CTRL_3_0_SET
+ (params->cfg_vga_ctrl_3_0),
+ SD10G_LANE_LANE_2F_CFG_VGA_CTRL_3_0,
+ sd_inst,
+ SD10G_LANE_LANE_2F(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_2F_CFG_VGA_CP_2_0_SET
+ (params->cfg_vga_cp_2_0),
+ SD10G_LANE_LANE_2F_CFG_VGA_CP_2_0,
+ sd_inst,
+ SD10G_LANE_LANE_2F(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_0B_CFG_EQ_RES_3_0_SET
+ (params->cfg_eq_res_3_0),
+ SD10G_LANE_LANE_0B_CFG_EQ_RES_3_0,
+ sd_inst,
+ SD10G_LANE_LANE_0B(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_0D_CFG_EQR_BYP_SET(params->cfg_eq_r_byp),
+ SD10G_LANE_LANE_0D_CFG_EQR_BYP,
+ sd_inst,
+ SD10G_LANE_LANE_0D(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_0E_CFG_EQC_FORCE_3_0_SET
+ (params->cfg_eq_c_force_3_0) |
+ SD10G_LANE_LANE_0E_CFG_SUM_SETCM_EN_SET
+ (params->cfg_sum_setcm_en),
+ SD10G_LANE_LANE_0E_CFG_EQC_FORCE_3_0 |
+ SD10G_LANE_LANE_0E_CFG_SUM_SETCM_EN,
+ sd_inst,
+ SD10G_LANE_LANE_0E(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_23_CFG_EN_DFEDIG_SET
+ (params->cfg_en_dfedig),
+ SD10G_LANE_LANE_23_CFG_EN_DFEDIG,
+ sd_inst,
+ SD10G_LANE_LANE_23(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_06_CFG_EN_PREEMPH_SET
+ (params->cfg_en_preemph),
+ SD10G_LANE_LANE_06_CFG_EN_PREEMPH,
+ sd_inst,
+ SD10G_LANE_LANE_06(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_33_CFG_ITX_IPPREEMP_BASE_1_0_SET
+ (params->cfg_itx_ippreemp_base_1_0) |
+ SD10G_LANE_LANE_33_CFG_ITX_IPDRIVER_BASE_2_0_SET
+ (params->cfg_itx_ipdriver_base_2_0),
+ SD10G_LANE_LANE_33_CFG_ITX_IPPREEMP_BASE_1_0 |
+ SD10G_LANE_LANE_33_CFG_ITX_IPDRIVER_BASE_2_0,
+ sd_inst,
+ SD10G_LANE_LANE_33(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_52_CFG_IBIAS_TUNE_RESERVE_5_0_SET
+ (params->cfg_ibias_tune_reserve_5_0),
+ SD10G_LANE_LANE_52_CFG_IBIAS_TUNE_RESERVE_5_0,
+ sd_inst,
+ SD10G_LANE_LANE_52(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_37_CFG_TXSWING_HALF_SET
+ (params->cfg_txswing_half),
+ SD10G_LANE_LANE_37_CFG_TXSWING_HALF,
+ sd_inst,
+ SD10G_LANE_LANE_37(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_3C_CFG_DIS_2NDORDER_SET
+ (params->cfg_dis_2nd_order),
+ SD10G_LANE_LANE_3C_CFG_DIS_2NDORDER,
+ sd_inst,
+ SD10G_LANE_LANE_3C(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_39_CFG_RX_SSC_LH_SET
+ (params->cfg_rx_ssc_lh),
+ SD10G_LANE_LANE_39_CFG_RX_SSC_LH,
+ sd_inst,
+ SD10G_LANE_LANE_39(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_1A_CFG_PI_FLOOP_STEPS_1_0_SET
+ (params->cfg_pi_floop_steps_1_0),
+ SD10G_LANE_LANE_1A_CFG_PI_FLOOP_STEPS_1_0,
+ sd_inst,
+ SD10G_LANE_LANE_1A(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_16_CFG_PI_EXT_DAC_23_16_SET
+ (params->cfg_pi_ext_dac_23_16),
+ SD10G_LANE_LANE_16_CFG_PI_EXT_DAC_23_16,
+ sd_inst,
+ SD10G_LANE_LANE_16(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_15_CFG_PI_EXT_DAC_15_8_SET
+ (params->cfg_pi_ext_dac_15_8),
+ SD10G_LANE_LANE_15_CFG_PI_EXT_DAC_15_8,
+ sd_inst,
+ SD10G_LANE_LANE_15(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_26_CFG_ISCAN_EXT_DAC_7_0_SET
+ (params->cfg_iscan_ext_dac_7_0),
+ SD10G_LANE_LANE_26_CFG_ISCAN_EXT_DAC_7_0,
+ sd_inst,
+ SD10G_LANE_LANE_26(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_42_CFG_CDR_KF_GEN1_2_0_SET
+ (params->cfg_cdr_kf_gen1_2_0),
+ SD10G_LANE_LANE_42_CFG_CDR_KF_GEN1_2_0,
+ sd_inst,
+ SD10G_LANE_LANE_42(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_0F_R_CDR_M_GEN1_7_0_SET
+ (params->r_cdr_m_gen1_7_0),
+ SD10G_LANE_LANE_0F_R_CDR_M_GEN1_7_0,
+ sd_inst,
+ SD10G_LANE_LANE_0F(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_24_CFG_PI_BW_GEN1_3_0_SET
+ (params->cfg_pi_bw_gen1_3_0),
+ SD10G_LANE_LANE_24_CFG_PI_BW_GEN1_3_0,
+ sd_inst,
+ SD10G_LANE_LANE_24(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_14_CFG_PI_EXT_DAC_7_0_SET
+ (params->cfg_pi_ext_dac_7_0),
+ SD10G_LANE_LANE_14_CFG_PI_EXT_DAC_7_0,
+ sd_inst,
+ SD10G_LANE_LANE_14(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_1A_CFG_PI_STEPS_SET(params->cfg_pi_steps),
+ SD10G_LANE_LANE_1A_CFG_PI_STEPS,
+ sd_inst,
+ SD10G_LANE_LANE_1A(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_3A_CFG_MP_MAX_3_0_SET
+ (params->cfg_mp_max_3_0),
+ SD10G_LANE_LANE_3A_CFG_MP_MAX_3_0,
+ sd_inst,
+ SD10G_LANE_LANE_3A(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_31_CFG_RSTN_DFEDIG_SET
+ (params->cfg_rstn_dfedig),
+ SD10G_LANE_LANE_31_CFG_RSTN_DFEDIG,
+ sd_inst,
+ SD10G_LANE_LANE_31(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_48_CFG_ALOS_THR_3_0_SET
+ (params->cfg_alos_thr_3_0),
+ SD10G_LANE_LANE_48_CFG_ALOS_THR_3_0,
+ sd_inst,
+ SD10G_LANE_LANE_48(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_36_CFG_PREDRV_SLEWRATE_1_0_SET
+ (params->cfg_predrv_slewrate_1_0),
+ SD10G_LANE_LANE_36_CFG_PREDRV_SLEWRATE_1_0,
+ sd_inst,
+ SD10G_LANE_LANE_36(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_32_CFG_ITX_IPCML_BASE_1_0_SET
+ (params->cfg_itx_ipcml_base_1_0),
+ SD10G_LANE_LANE_32_CFG_ITX_IPCML_BASE_1_0,
+ sd_inst,
+ SD10G_LANE_LANE_32(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_37_CFG_IP_PRE_BASE_1_0_SET
+ (params->cfg_ip_pre_base_1_0),
+ SD10G_LANE_LANE_37_CFG_IP_PRE_BASE_1_0,
+ sd_inst,
+ SD10G_LANE_LANE_37(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_41_CFG_LANE_RESERVE_15_8_SET
+ (params->cfg_lane_reserve_15_8),
+ SD10G_LANE_LANE_41_CFG_LANE_RESERVE_15_8,
+ sd_inst,
+ SD10G_LANE_LANE_41(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_9E_R_EN_AUTO_CDR_RSTN_SET
+ (params->r_en_auto_cdr_rstn),
+ SD10G_LANE_LANE_9E_R_EN_AUTO_CDR_RSTN,
+ sd_inst,
+ SD10G_LANE_LANE_9E(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_0C_CFG_OSCAL_AFE_SET
+ (params->cfg_oscal_afe) |
+ SD10G_LANE_LANE_0C_CFG_PD_OSDAC_AFE_SET
+ (params->cfg_pd_osdac_afe),
+ SD10G_LANE_LANE_0C_CFG_OSCAL_AFE |
+ SD10G_LANE_LANE_0C_CFG_PD_OSDAC_AFE,
+ sd_inst,
+ SD10G_LANE_LANE_0C(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_0B_CFG_RESETB_OSCAL_AFE_SET
+ (params->cfg_resetb_oscal_afe[0]),
+ SD10G_LANE_LANE_0B_CFG_RESETB_OSCAL_AFE,
+ sd_inst,
+ SD10G_LANE_LANE_0B(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_0B_CFG_RESETB_OSCAL_AFE_SET
+ (params->cfg_resetb_oscal_afe[1]),
+ SD10G_LANE_LANE_0B_CFG_RESETB_OSCAL_AFE,
+ sd_inst,
+ SD10G_LANE_LANE_0B(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_83_R_TX_POL_INV_SET
+ (params->r_tx_pol_inv) |
+ SD10G_LANE_LANE_83_R_RX_POL_INV_SET
+ (params->r_rx_pol_inv),
+ SD10G_LANE_LANE_83_R_TX_POL_INV |
+ SD10G_LANE_LANE_83_R_RX_POL_INV,
+ sd_inst,
+ SD10G_LANE_LANE_83(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_06_CFG_RX2TX_LP_EN_SET
+ (params->cfg_rx2tx_lp_en) |
+ SD10G_LANE_LANE_06_CFG_TX2RX_LP_EN_SET
+ (params->cfg_tx2rx_lp_en),
+ SD10G_LANE_LANE_06_CFG_RX2TX_LP_EN |
+ SD10G_LANE_LANE_06_CFG_TX2RX_LP_EN,
+ sd_inst,
+ SD10G_LANE_LANE_06(sd_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_0E_CFG_RXLB_EN_SET(params->cfg_rxlb_en) |
+ SD10G_LANE_LANE_0E_CFG_TXLB_EN_SET(params->cfg_txlb_en),
+ SD10G_LANE_LANE_0E_CFG_RXLB_EN |
+ SD10G_LANE_LANE_0E_CFG_TXLB_EN,
+ sd_inst,
+ SD10G_LANE_LANE_0E(sd_index));
+
+ sdx5_rmw(SD_LANE_SD_LANE_CFG_MACRO_RST_SET(0),
+ SD_LANE_SD_LANE_CFG_MACRO_RST,
+ priv,
+ SD_LANE_SD_LANE_CFG(lane_index));
+
+ sdx5_inst_rmw(SD10G_LANE_LANE_50_CFG_SSC_RESETB_SET(1),
+ SD10G_LANE_LANE_50_CFG_SSC_RESETB,
+ sd_inst,
+ SD10G_LANE_LANE_50(sd_index));
+
+ sdx5_rmw(SD10G_LANE_LANE_50_CFG_SSC_RESETB_SET(1),
+ SD10G_LANE_LANE_50_CFG_SSC_RESETB,
+ priv,
+ SD10G_LANE_LANE_50(sd_index));
+
+ sdx5_rmw(SD_LANE_MISC_SD_125_RST_DIS_SET(params->fx_100),
+ SD_LANE_MISC_SD_125_RST_DIS,
+ priv,
+ SD_LANE_MISC(lane_index));
+
+ sdx5_rmw(SD_LANE_MISC_RX_ENA_SET(params->fx_100),
+ SD_LANE_MISC_RX_ENA,
+ priv,
+ SD_LANE_MISC(lane_index));
+
+ sdx5_rmw(SD_LANE_MISC_MUX_ENA_SET(params->fx_100),
+ SD_LANE_MISC_MUX_ENA,
+ priv,
+ SD_LANE_MISC(lane_index));
+
+ usleep_range(3000, 6000);
+
+ value = readl(sdx5_addr(regs, SD_LANE_SD_LANE_STAT(lane_index)));
+ value = SD_LANE_SD_LANE_STAT_PMA_RST_DONE_GET(value);
+ if (value != 1) {
+ dev_err(dev, "10G PMA Reset failed: 0x%x\n", value);
+ return -EINVAL;
+ }
+
+ sdx5_rmw(SD_LANE_SD_SER_RST_SER_RST_SET(0x0),
+ SD_LANE_SD_SER_RST_SER_RST,
+ priv,
+ SD_LANE_SD_SER_RST(lane_index));
+
+ sdx5_rmw(SD_LANE_SD_DES_RST_DES_RST_SET(0x0),
+ SD_LANE_SD_DES_RST_DES_RST,
+ priv,
+ SD_LANE_SD_DES_RST(lane_index));
+
+ return 0;
+}
+
+static int sparx5_sd25g28_config(struct sparx5_serdes_macro *macro, bool reset)
+{
+ struct sparx5_sd25g28_media_preset media = media_presets_25g[macro->media];
+ struct sparx5_sd25g28_mode_preset mode;
+ struct sparx5_sd25g28_args args = {
+ .rxinvert = 1,
+ .txinvert = 0,
+ .txswing = 240,
+ .com_pll_reserve = 0xf,
+ .reg_rst = reset,
+ };
+ struct sparx5_sd25g28_params params;
+ int err;
+
+ err = sparx5_sd10g25_get_mode_preset(macro, &mode);
+ if (err)
+ return err;
+ sparx5_sd25g28_get_params(macro, &media, &mode, &args, &params);
+ sparx5_sd25g28_reset(macro->priv->regs, &params, macro->stpidx);
+ return sparx5_sd25g28_apply_params(macro, &params);
+}
+
+static int sparx5_sd10g28_config(struct sparx5_serdes_macro *macro, bool reset)
+{
+ struct sparx5_sd10g28_media_preset media = media_presets_10g[macro->media];
+ struct sparx5_sd10g28_mode_preset mode;
+ struct sparx5_sd10g28_params params;
+ struct sparx5_sd10g28_args args = {
+ .is_6g = (macro->serdestype == SPX5_SDT_6G),
+ .txinvert = 0,
+ .rxinvert = 1,
+ .txswing = 240,
+ .reg_rst = reset,
+ };
+ int err;
+
+ err = sparx5_sd10g28_get_mode_preset(macro, &mode, &args);
+ if (err)
+ return err;
+ sparx5_sd10g28_get_params(macro, &media, &mode, &args, &params);
+ sparx5_sd10g28_reset(macro->priv->regs, macro->sidx);
+ return sparx5_sd10g28_apply_params(macro, &params);
+}
+
+/* Power down serdes TX driver */
+static int sparx5_serdes_power_save(struct sparx5_serdes_macro *macro, u32 pwdn)
+{
+ struct sparx5_serdes_private *priv = macro->priv;
+ void __iomem *sd_inst;
+
+ if (macro->serdestype == SPX5_SDT_6G)
+ sd_inst = sdx5_inst_get(priv, TARGET_SD6G_LANE, macro->stpidx);
+ else if (macro->serdestype == SPX5_SDT_10G)
+ sd_inst = sdx5_inst_get(priv, TARGET_SD10G_LANE, macro->stpidx);
+ else
+ sd_inst = sdx5_inst_get(priv, TARGET_SD25G_LANE, macro->stpidx);
+
+ if (macro->serdestype == SPX5_SDT_25G) {
+ sdx5_inst_rmw(SD25G_LANE_LANE_04_LN_CFG_PD_DRIVER_SET(pwdn),
+ SD25G_LANE_LANE_04_LN_CFG_PD_DRIVER,
+ sd_inst,
+ SD25G_LANE_LANE_04(0));
+ } else {
+ /* 6G and 10G */
+ sdx5_inst_rmw(SD10G_LANE_LANE_06_CFG_PD_DRIVER_SET(pwdn),
+ SD10G_LANE_LANE_06_CFG_PD_DRIVER,
+ sd_inst,
+ SD10G_LANE_LANE_06(0));
+ }
+ return 0;
+}
+
+static int sparx5_serdes_clock_config(struct sparx5_serdes_macro *macro)
+{
+ struct sparx5_serdes_private *priv = macro->priv;
+
+ if (macro->serdesmode == SPX5_SD_MODE_100FX) {
+ u32 freq = priv->coreclock == 250000000 ? 2 :
+ priv->coreclock == 500000000 ? 1 : 0;
+
+ sdx5_rmw(SD_LANE_MISC_CORE_CLK_FREQ_SET(freq),
+ SD_LANE_MISC_CORE_CLK_FREQ,
+ priv,
+ SD_LANE_MISC(macro->sidx));
+ }
+ return 0;
+}
+
+static int sparx5_cmu_apply_cfg(struct sparx5_serdes_private *priv,
+ u32 cmu_idx,
+ void __iomem *cmu_tgt,
+ void __iomem *cmu_cfg_tgt,
+ u32 spd10g)
+{
+ void __iomem **regs = priv->regs;
+ struct device *dev = priv->dev;
+ int value;
+
+ cmu_tgt = sdx5_inst_get(priv, TARGET_SD_CMU, cmu_idx);
+ cmu_cfg_tgt = sdx5_inst_get(priv, TARGET_SD_CMU_CFG, cmu_idx);
+
+ if (cmu_idx == 1 || cmu_idx == 4 || cmu_idx == 7 ||
+ cmu_idx == 10 || cmu_idx == 13) {
+ spd10g = 0;
+ }
+
+ sdx5_inst_rmw(SD_CMU_CFG_SD_CMU_CFG_EXT_CFG_RST_SET(1),
+ SD_CMU_CFG_SD_CMU_CFG_EXT_CFG_RST,
+ cmu_cfg_tgt,
+ SD_CMU_CFG_SD_CMU_CFG(cmu_idx));
+
+ sdx5_inst_rmw(SD_CMU_CFG_SD_CMU_CFG_EXT_CFG_RST_SET(0),
+ SD_CMU_CFG_SD_CMU_CFG_EXT_CFG_RST,
+ cmu_cfg_tgt,
+ SD_CMU_CFG_SD_CMU_CFG(cmu_idx));
+
+ sdx5_inst_rmw(SD_CMU_CFG_SD_CMU_CFG_CMU_RST_SET(1),
+ SD_CMU_CFG_SD_CMU_CFG_CMU_RST,
+ cmu_cfg_tgt,
+ SD_CMU_CFG_SD_CMU_CFG(cmu_idx));
+
+ sdx5_inst_rmw(SD_CMU_CMU_45_R_DWIDTHCTRL_FROM_HWT_SET(0x1) |
+ SD_CMU_CMU_45_R_REFCK_SSC_EN_FROM_HWT_SET(0x1) |
+ SD_CMU_CMU_45_R_LINK_BUF_EN_FROM_HWT_SET(0x1) |
+ SD_CMU_CMU_45_R_BIAS_EN_FROM_HWT_SET(0x1) |
+ SD_CMU_CMU_45_R_EN_RATECHG_CTRL_SET(0x0),
+ SD_CMU_CMU_45_R_DWIDTHCTRL_FROM_HWT |
+ SD_CMU_CMU_45_R_REFCK_SSC_EN_FROM_HWT |
+ SD_CMU_CMU_45_R_LINK_BUF_EN_FROM_HWT |
+ SD_CMU_CMU_45_R_BIAS_EN_FROM_HWT |
+ SD_CMU_CMU_45_R_EN_RATECHG_CTRL,
+ cmu_tgt,
+ SD_CMU_CMU_45(cmu_idx));
+
+ sdx5_inst_rmw(SD_CMU_CMU_47_R_PCS2PMA_PHYMODE_4_0_SET(0),
+ SD_CMU_CMU_47_R_PCS2PMA_PHYMODE_4_0,
+ cmu_tgt,
+ SD_CMU_CMU_47(cmu_idx));
+
+ sdx5_inst_rmw(SD_CMU_CMU_1B_CFG_RESERVE_7_0_SET(0),
+ SD_CMU_CMU_1B_CFG_RESERVE_7_0,
+ cmu_tgt,
+ SD_CMU_CMU_1B(cmu_idx));
+
+ sdx5_inst_rmw(SD_CMU_CMU_0D_CFG_JC_BYP_SET(0x1),
+ SD_CMU_CMU_0D_CFG_JC_BYP,
+ cmu_tgt,
+ SD_CMU_CMU_0D(cmu_idx));
+
+ sdx5_inst_rmw(SD_CMU_CMU_1F_CFG_VTUNE_SEL_SET(1),
+ SD_CMU_CMU_1F_CFG_VTUNE_SEL,
+ cmu_tgt,
+ SD_CMU_CMU_1F(cmu_idx));
+
+ sdx5_inst_rmw(SD_CMU_CMU_00_CFG_PLL_TP_SEL_1_0_SET(3),
+ SD_CMU_CMU_00_CFG_PLL_TP_SEL_1_0,
+ cmu_tgt,
+ SD_CMU_CMU_00(cmu_idx));
+
+ sdx5_inst_rmw(SD_CMU_CMU_05_CFG_BIAS_TP_SEL_1_0_SET(3),
+ SD_CMU_CMU_05_CFG_BIAS_TP_SEL_1_0,
+ cmu_tgt,
+ SD_CMU_CMU_05(cmu_idx));
+
+ sdx5_inst_rmw(SD_CMU_CMU_30_R_PLL_DLOL_EN_SET(1),
+ SD_CMU_CMU_30_R_PLL_DLOL_EN,
+ cmu_tgt,
+ SD_CMU_CMU_30(cmu_idx));
+
+ sdx5_inst_rmw(SD_CMU_CMU_09_CFG_SW_10G_SET(spd10g),
+ SD_CMU_CMU_09_CFG_SW_10G,
+ cmu_tgt,
+ SD_CMU_CMU_09(cmu_idx));
+
+ sdx5_inst_rmw(SD_CMU_CFG_SD_CMU_CFG_CMU_RST_SET(0),
+ SD_CMU_CFG_SD_CMU_CFG_CMU_RST,
+ cmu_cfg_tgt,
+ SD_CMU_CFG_SD_CMU_CFG(cmu_idx));
+
+ msleep(20);
+
+ sdx5_inst_rmw(SD_CMU_CMU_44_R_PLL_RSTN_SET(0),
+ SD_CMU_CMU_44_R_PLL_RSTN,
+ cmu_tgt,
+ SD_CMU_CMU_44(cmu_idx));
+
+ sdx5_inst_rmw(SD_CMU_CMU_44_R_PLL_RSTN_SET(1),
+ SD_CMU_CMU_44_R_PLL_RSTN,
+ cmu_tgt,
+ SD_CMU_CMU_44(cmu_idx));
+
+ msleep(20);
+
+ value = readl(sdx5_addr(regs, SD_CMU_CMU_E0(cmu_idx)));
+ value = SD_CMU_CMU_E0_PLL_LOL_UDL_GET(value);
+
+ if (value) {
+ dev_err(dev, "CMU PLL Loss of Lock: 0x%x\n", value);
+ return -EINVAL;
+ }
+ sdx5_inst_rmw(SD_CMU_CMU_0D_CFG_PMA_TX_CK_PD_SET(0),
+ SD_CMU_CMU_0D_CFG_PMA_TX_CK_PD,
+ cmu_tgt,
+ SD_CMU_CMU_0D(cmu_idx));
+ return 0;
+}
+
+static int sparx5_cmu_cfg(struct sparx5_serdes_private *priv, u32 cmu_idx)
+{
+ void __iomem *cmu_tgt, *cmu_cfg_tgt;
+ u32 spd10g = 1;
+
+ if (cmu_idx == 1 || cmu_idx == 4 || cmu_idx == 7 ||
+ cmu_idx == 10 || cmu_idx == 13) {
+ spd10g = 0;
+ }
+
+ cmu_tgt = sdx5_inst_get(priv, TARGET_SD_CMU, cmu_idx);
+ cmu_cfg_tgt = sdx5_inst_get(priv, TARGET_SD_CMU_CFG, cmu_idx);
+
+ return sparx5_cmu_apply_cfg(priv, cmu_idx, cmu_tgt, cmu_cfg_tgt, spd10g);
+}
+
+static int sparx5_serdes_cmu_enable(struct sparx5_serdes_private *priv)
+{
+ int idx, err = 0;
+
+ if (!priv->cmu_enabled) {
+ for (idx = 0; idx < SPX5_CMU_MAX; idx++) {
+ err = sparx5_cmu_cfg(priv, idx);
+ if (err) {
+ dev_err(priv->dev, "CMU %u, error: %d\n", idx, err);
+ goto leave;
+ }
+ }
+ priv->cmu_enabled = true;
+ }
+leave:
+ return err;
+}
+
+static int sparx5_serdes_get_serdesmode(phy_interface_t portmode, int speed)
+{
+ switch (portmode) {
+ case PHY_INTERFACE_MODE_1000BASEX:
+ case PHY_INTERFACE_MODE_2500BASEX:
+ if (speed == SPEED_2500)
+ return SPX5_SD_MODE_2G5;
+ if (speed == SPEED_100)
+ return SPX5_SD_MODE_100FX;
+ return SPX5_SD_MODE_1000BASEX;
+ case PHY_INTERFACE_MODE_SGMII:
+ /* The same Serdes mode is used for both SGMII and 1000BaseX */
+ return SPX5_SD_MODE_1000BASEX;
+ case PHY_INTERFACE_MODE_QSGMII:
+ return SPX5_SD_MODE_QSGMII;
+ case PHY_INTERFACE_MODE_10GBASER:
+ return SPX5_SD_MODE_SFI;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int sparx5_serdes_config(struct sparx5_serdes_macro *macro)
+{
+ struct device *dev = macro->priv->dev;
+ int serdesmode;
+ int err;
+
+ err = sparx5_serdes_cmu_enable(macro->priv);
+ if (err)
+ return err;
+
+ serdesmode = sparx5_serdes_get_serdesmode(macro->portmode, macro->speed);
+ if (serdesmode < 0) {
+ dev_err(dev, "SerDes %u, interface not supported: %s\n",
+ macro->sidx,
+ phy_modes(macro->portmode));
+ return serdesmode;
+ }
+ macro->serdesmode = serdesmode;
+
+ sparx5_serdes_clock_config(macro);
+
+ if (macro->serdestype == SPX5_SDT_25G)
+ err = sparx5_sd25g28_config(macro, false);
+ else
+ err = sparx5_sd10g28_config(macro, false);
+ if (err) {
+ dev_err(dev, "SerDes %u, config error: %d\n",
+ macro->sidx, err);
+ }
+ return err;
+}
+
+static int sparx5_serdes_power_on(struct phy *phy)
+{
+ struct sparx5_serdes_macro *macro = phy_get_drvdata(phy);
+
+ return sparx5_serdes_power_save(macro, false);
+}
+
+static int sparx5_serdes_power_off(struct phy *phy)
+{
+ struct sparx5_serdes_macro *macro = phy_get_drvdata(phy);
+
+ return sparx5_serdes_power_save(macro, true);
+}
+
+static int sparx5_serdes_set_mode(struct phy *phy, enum phy_mode mode, int submode)
+{
+ struct sparx5_serdes_macro *macro;
+
+ if (mode != PHY_MODE_ETHERNET)
+ return -EINVAL;
+
+ switch (submode) {
+ case PHY_INTERFACE_MODE_1000BASEX:
+ case PHY_INTERFACE_MODE_2500BASEX:
+ case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_QSGMII:
+ case PHY_INTERFACE_MODE_10GBASER:
+ macro = phy_get_drvdata(phy);
+ macro->portmode = submode;
+ sparx5_serdes_config(macro);
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int sparx5_serdes_set_media(struct phy *phy, enum phy_media media)
+{
+ struct sparx5_serdes_macro *macro = phy_get_drvdata(phy);
+
+ if (media != macro->media) {
+ macro->media = media;
+ if (macro->serdesmode != SPX5_SD_MODE_NONE)
+ sparx5_serdes_config(macro);
+ }
+ return 0;
+}
+
+static int sparx5_serdes_set_speed(struct phy *phy, int speed)
+{
+ struct sparx5_serdes_macro *macro = phy_get_drvdata(phy);
+
+ if (macro->sidx < SPX5_SERDES_10G_START && speed > SPEED_5000)
+ return -EINVAL;
+ if (macro->sidx < SPX5_SERDES_25G_START && speed > SPEED_10000)
+ return -EINVAL;
+ if (speed != macro->speed) {
+ macro->speed = speed;
+ if (macro->serdesmode != SPX5_SD_MODE_NONE)
+ sparx5_serdes_config(macro);
+ }
+ return 0;
+}
+
+static int sparx5_serdes_reset(struct phy *phy)
+{
+ struct sparx5_serdes_macro *macro = phy_get_drvdata(phy);
+ int err;
+
+ err = sparx5_serdes_cmu_enable(macro->priv);
+ if (err)
+ return err;
+ if (macro->serdestype == SPX5_SDT_25G)
+ err = sparx5_sd25g28_config(macro, true);
+ else
+ err = sparx5_sd10g28_config(macro, true);
+ if (err) {
+ dev_err(&phy->dev, "SerDes %u, reset error: %d\n",
+ macro->sidx, err);
+ }
+ return err;
+}
+
+static int sparx5_serdes_validate(struct phy *phy, enum phy_mode mode,
+ int submode,
+ union phy_configure_opts *opts)
+{
+ struct sparx5_serdes_macro *macro = phy_get_drvdata(phy);
+
+ if (mode != PHY_MODE_ETHERNET)
+ return -EINVAL;
+
+ if (macro->speed == 0)
+ return -EINVAL;
+
+ if (macro->sidx < SPX5_SERDES_10G_START && macro->speed > SPEED_5000)
+ return -EINVAL;
+ if (macro->sidx < SPX5_SERDES_25G_START && macro->speed > SPEED_10000)
+ return -EINVAL;
+
+ switch (submode) {
+ case PHY_INTERFACE_MODE_1000BASEX:
+ if (macro->speed != SPEED_100 && /* This is for 100BASE-FX */
+ macro->speed != SPEED_1000)
+ return -EINVAL;
+ break;
+ case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_2500BASEX:
+ case PHY_INTERFACE_MODE_QSGMII:
+ if (macro->speed >= SPEED_5000)
+ return -EINVAL;
+ break;
+ case PHY_INTERFACE_MODE_10GBASER:
+ if (macro->speed < SPEED_5000)
+ return -EINVAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static const struct phy_ops sparx5_serdes_ops = {
+ .power_on = sparx5_serdes_power_on,
+ .power_off = sparx5_serdes_power_off,
+ .set_mode = sparx5_serdes_set_mode,
+ .set_media = sparx5_serdes_set_media,
+ .set_speed = sparx5_serdes_set_speed,
+ .reset = sparx5_serdes_reset,
+ .validate = sparx5_serdes_validate,
+ .owner = THIS_MODULE,
+};
+
+static int sparx5_phy_create(struct sparx5_serdes_private *priv,
+ int idx, struct phy **phy)
+{
+ struct sparx5_serdes_macro *macro;
+
+ *phy = devm_phy_create(priv->dev, NULL, &sparx5_serdes_ops);
+ if (IS_ERR(*phy))
+ return PTR_ERR(*phy);
+
+ macro = devm_kzalloc(priv->dev, sizeof(*macro), GFP_KERNEL);
+ if (!macro)
+ return -ENOMEM;
+
+ macro->sidx = idx;
+ macro->priv = priv;
+ macro->speed = SPEED_UNKNOWN;
+ if (idx < SPX5_SERDES_10G_START) {
+ macro->serdestype = SPX5_SDT_6G;
+ macro->stpidx = macro->sidx;
+ } else if (idx < SPX5_SERDES_25G_START) {
+ macro->serdestype = SPX5_SDT_10G;
+ macro->stpidx = macro->sidx - SPX5_SERDES_10G_START;
+ } else {
+ macro->serdestype = SPX5_SDT_25G;
+ macro->stpidx = macro->sidx - SPX5_SERDES_25G_START;
+ }
+
+ phy_set_drvdata(*phy, macro);
+
+ return 0;
+}
+
+static struct sparx5_serdes_io_resource sparx5_serdes_iomap[] = {
+ { TARGET_SD_CMU, 0x0 }, /* 0x610808000: sd_cmu_0 */
+ { TARGET_SD_CMU + 1, 0x8000 }, /* 0x610810000: sd_cmu_1 */
+ { TARGET_SD_CMU + 2, 0x10000 }, /* 0x610818000: sd_cmu_2 */
+ { TARGET_SD_CMU + 3, 0x18000 }, /* 0x610820000: sd_cmu_3 */
+ { TARGET_SD_CMU + 4, 0x20000 }, /* 0x610828000: sd_cmu_4 */
+ { TARGET_SD_CMU + 5, 0x28000 }, /* 0x610830000: sd_cmu_5 */
+ { TARGET_SD_CMU + 6, 0x30000 }, /* 0x610838000: sd_cmu_6 */
+ { TARGET_SD_CMU + 7, 0x38000 }, /* 0x610840000: sd_cmu_7 */
+ { TARGET_SD_CMU + 8, 0x40000 }, /* 0x610848000: sd_cmu_8 */
+ { TARGET_SD_CMU_CFG, 0x48000 }, /* 0x610850000: sd_cmu_cfg_0 */
+ { TARGET_SD_CMU_CFG + 1, 0x50000 }, /* 0x610858000: sd_cmu_cfg_1 */
+ { TARGET_SD_CMU_CFG + 2, 0x58000 }, /* 0x610860000: sd_cmu_cfg_2 */
+ { TARGET_SD_CMU_CFG + 3, 0x60000 }, /* 0x610868000: sd_cmu_cfg_3 */
+ { TARGET_SD_CMU_CFG + 4, 0x68000 }, /* 0x610870000: sd_cmu_cfg_4 */
+ { TARGET_SD_CMU_CFG + 5, 0x70000 }, /* 0x610878000: sd_cmu_cfg_5 */
+ { TARGET_SD_CMU_CFG + 6, 0x78000 }, /* 0x610880000: sd_cmu_cfg_6 */
+ { TARGET_SD_CMU_CFG + 7, 0x80000 }, /* 0x610888000: sd_cmu_cfg_7 */
+ { TARGET_SD_CMU_CFG + 8, 0x88000 }, /* 0x610890000: sd_cmu_cfg_8 */
+ { TARGET_SD6G_LANE, 0x90000 }, /* 0x610898000: sd6g_lane_0 */
+ { TARGET_SD6G_LANE + 1, 0x98000 }, /* 0x6108a0000: sd6g_lane_1 */
+ { TARGET_SD6G_LANE + 2, 0xa0000 }, /* 0x6108a8000: sd6g_lane_2 */
+ { TARGET_SD6G_LANE + 3, 0xa8000 }, /* 0x6108b0000: sd6g_lane_3 */
+ { TARGET_SD6G_LANE + 4, 0xb0000 }, /* 0x6108b8000: sd6g_lane_4 */
+ { TARGET_SD6G_LANE + 5, 0xb8000 }, /* 0x6108c0000: sd6g_lane_5 */
+ { TARGET_SD6G_LANE + 6, 0xc0000 }, /* 0x6108c8000: sd6g_lane_6 */
+ { TARGET_SD6G_LANE + 7, 0xc8000 }, /* 0x6108d0000: sd6g_lane_7 */
+ { TARGET_SD6G_LANE + 8, 0xd0000 }, /* 0x6108d8000: sd6g_lane_8 */
+ { TARGET_SD6G_LANE + 9, 0xd8000 }, /* 0x6108e0000: sd6g_lane_9 */
+ { TARGET_SD6G_LANE + 10, 0xe0000 }, /* 0x6108e8000: sd6g_lane_10 */
+ { TARGET_SD6G_LANE + 11, 0xe8000 }, /* 0x6108f0000: sd6g_lane_11 */
+ { TARGET_SD6G_LANE + 12, 0xf0000 }, /* 0x6108f8000: sd6g_lane_12 */
+ { TARGET_SD10G_LANE, 0xf8000 }, /* 0x610900000: sd10g_lane_0 */
+ { TARGET_SD10G_LANE + 1, 0x100000 }, /* 0x610908000: sd10g_lane_1 */
+ { TARGET_SD10G_LANE + 2, 0x108000 }, /* 0x610910000: sd10g_lane_2 */
+ { TARGET_SD10G_LANE + 3, 0x110000 }, /* 0x610918000: sd10g_lane_3 */
+ { TARGET_SD_LANE, 0x1a0000 }, /* 0x6109a8000: sd_lane_0 */
+ { TARGET_SD_LANE + 1, 0x1a8000 }, /* 0x6109b0000: sd_lane_1 */
+ { TARGET_SD_LANE + 2, 0x1b0000 }, /* 0x6109b8000: sd_lane_2 */
+ { TARGET_SD_LANE + 3, 0x1b8000 }, /* 0x6109c0000: sd_lane_3 */
+ { TARGET_SD_LANE + 4, 0x1c0000 }, /* 0x6109c8000: sd_lane_4 */
+ { TARGET_SD_LANE + 5, 0x1c8000 }, /* 0x6109d0000: sd_lane_5 */
+ { TARGET_SD_LANE + 6, 0x1d0000 }, /* 0x6109d8000: sd_lane_6 */
+ { TARGET_SD_LANE + 7, 0x1d8000 }, /* 0x6109e0000: sd_lane_7 */
+ { TARGET_SD_LANE + 8, 0x1e0000 }, /* 0x6109e8000: sd_lane_8 */
+ { TARGET_SD_LANE + 9, 0x1e8000 }, /* 0x6109f0000: sd_lane_9 */
+ { TARGET_SD_LANE + 10, 0x1f0000 }, /* 0x6109f8000: sd_lane_10 */
+ { TARGET_SD_LANE + 11, 0x1f8000 }, /* 0x610a00000: sd_lane_11 */
+ { TARGET_SD_LANE + 12, 0x200000 }, /* 0x610a08000: sd_lane_12 */
+ { TARGET_SD_LANE + 13, 0x208000 }, /* 0x610a10000: sd_lane_13 */
+ { TARGET_SD_LANE + 14, 0x210000 }, /* 0x610a18000: sd_lane_14 */
+ { TARGET_SD_LANE + 15, 0x218000 }, /* 0x610a20000: sd_lane_15 */
+ { TARGET_SD_LANE + 16, 0x220000 }, /* 0x610a28000: sd_lane_16 */
+ { TARGET_SD_CMU + 9, 0x400000 }, /* 0x610c08000: sd_cmu_9 */
+ { TARGET_SD_CMU + 10, 0x408000 }, /* 0x610c10000: sd_cmu_10 */
+ { TARGET_SD_CMU + 11, 0x410000 }, /* 0x610c18000: sd_cmu_11 */
+ { TARGET_SD_CMU + 12, 0x418000 }, /* 0x610c20000: sd_cmu_12 */
+ { TARGET_SD_CMU + 13, 0x420000 }, /* 0x610c28000: sd_cmu_13 */
+ { TARGET_SD_CMU_CFG + 9, 0x428000 }, /* 0x610c30000: sd_cmu_cfg_9 */
+ { TARGET_SD_CMU_CFG + 10, 0x430000 }, /* 0x610c38000: sd_cmu_cfg_10 */
+ { TARGET_SD_CMU_CFG + 11, 0x438000 }, /* 0x610c40000: sd_cmu_cfg_11 */
+ { TARGET_SD_CMU_CFG + 12, 0x440000 }, /* 0x610c48000: sd_cmu_cfg_12 */
+ { TARGET_SD_CMU_CFG + 13, 0x448000 }, /* 0x610c50000: sd_cmu_cfg_13 */
+ { TARGET_SD10G_LANE + 4, 0x450000 }, /* 0x610c58000: sd10g_lane_4 */
+ { TARGET_SD10G_LANE + 5, 0x458000 }, /* 0x610c60000: sd10g_lane_5 */
+ { TARGET_SD10G_LANE + 6, 0x460000 }, /* 0x610c68000: sd10g_lane_6 */
+ { TARGET_SD10G_LANE + 7, 0x468000 }, /* 0x610c70000: sd10g_lane_7 */
+ { TARGET_SD10G_LANE + 8, 0x470000 }, /* 0x610c78000: sd10g_lane_8 */
+ { TARGET_SD10G_LANE + 9, 0x478000 }, /* 0x610c80000: sd10g_lane_9 */
+ { TARGET_SD10G_LANE + 10, 0x480000 }, /* 0x610c88000: sd10g_lane_10 */
+ { TARGET_SD10G_LANE + 11, 0x488000 }, /* 0x610c90000: sd10g_lane_11 */
+ { TARGET_SD25G_LANE, 0x490000 }, /* 0x610c98000: sd25g_lane_0 */
+ { TARGET_SD25G_LANE + 1, 0x498000 }, /* 0x610ca0000: sd25g_lane_1 */
+ { TARGET_SD25G_LANE + 2, 0x4a0000 }, /* 0x610ca8000: sd25g_lane_2 */
+ { TARGET_SD25G_LANE + 3, 0x4a8000 }, /* 0x610cb0000: sd25g_lane_3 */
+ { TARGET_SD25G_LANE + 4, 0x4b0000 }, /* 0x610cb8000: sd25g_lane_4 */
+ { TARGET_SD25G_LANE + 5, 0x4b8000 }, /* 0x610cc0000: sd25g_lane_5 */
+ { TARGET_SD25G_LANE + 6, 0x4c0000 }, /* 0x610cc8000: sd25g_lane_6 */
+ { TARGET_SD25G_LANE + 7, 0x4c8000 }, /* 0x610cd0000: sd25g_lane_7 */
+ { TARGET_SD_LANE + 17, 0x550000 }, /* 0x610d58000: sd_lane_17 */
+ { TARGET_SD_LANE + 18, 0x558000 }, /* 0x610d60000: sd_lane_18 */
+ { TARGET_SD_LANE + 19, 0x560000 }, /* 0x610d68000: sd_lane_19 */
+ { TARGET_SD_LANE + 20, 0x568000 }, /* 0x610d70000: sd_lane_20 */
+ { TARGET_SD_LANE + 21, 0x570000 }, /* 0x610d78000: sd_lane_21 */
+ { TARGET_SD_LANE + 22, 0x578000 }, /* 0x610d80000: sd_lane_22 */
+ { TARGET_SD_LANE + 23, 0x580000 }, /* 0x610d88000: sd_lane_23 */
+ { TARGET_SD_LANE + 24, 0x588000 }, /* 0x610d90000: sd_lane_24 */
+ { TARGET_SD_LANE_25G, 0x590000 }, /* 0x610d98000: sd_lane_25g_25 */
+ { TARGET_SD_LANE_25G + 1, 0x598000 }, /* 0x610da0000: sd_lane_25g_26 */
+ { TARGET_SD_LANE_25G + 2, 0x5a0000 }, /* 0x610da8000: sd_lane_25g_27 */
+ { TARGET_SD_LANE_25G + 3, 0x5a8000 }, /* 0x610db0000: sd_lane_25g_28 */
+ { TARGET_SD_LANE_25G + 4, 0x5b0000 }, /* 0x610db8000: sd_lane_25g_29 */
+ { TARGET_SD_LANE_25G + 5, 0x5b8000 }, /* 0x610dc0000: sd_lane_25g_30 */
+ { TARGET_SD_LANE_25G + 6, 0x5c0000 }, /* 0x610dc8000: sd_lane_25g_31 */
+ { TARGET_SD_LANE_25G + 7, 0x5c8000 }, /* 0x610dd0000: sd_lane_25g_32 */
+};
+
+/* Client lookup function, uses serdes index */
+static struct phy *sparx5_serdes_xlate(struct device *dev,
+ struct of_phandle_args *args)
+{
+ struct sparx5_serdes_private *priv = dev_get_drvdata(dev);
+ int idx;
+ unsigned int sidx;
+
+ if (args->args_count != 1)
+ return ERR_PTR(-EINVAL);
+
+ sidx = args->args[0];
+
+ /* Check validity: ERR_PTR(-ENODEV) if not valid */
+ for (idx = 0; idx < SPX5_SERDES_MAX; idx++) {
+ struct sparx5_serdes_macro *macro =
+ phy_get_drvdata(priv->phys[idx]);
+
+ if (sidx != macro->sidx)
+ continue;
+
+ return priv->phys[idx];
+ }
+ return ERR_PTR(-ENODEV);
+}
+
+static int sparx5_serdes_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct sparx5_serdes_private *priv;
+ struct phy_provider *provider;
+ struct resource *iores;
+ void __iomem *iomem;
+ unsigned long clock;
+ struct clk *clk;
+ int idx;
+ int err;
+
+ if (!np && !pdev->dev.platform_data)
+ return -ENODEV;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, priv);
+ priv->dev = &pdev->dev;
+
+ /* Get coreclock */
+ clk = devm_clk_get(priv->dev, NULL);
+ if (IS_ERR(clk)) {
+ dev_err(priv->dev, "Failed to get coreclock\n");
+ return PTR_ERR(clk);
+ }
+ clock = clk_get_rate(clk);
+ if (clock == 0) {
+ dev_err(priv->dev, "Invalid coreclock %lu\n", clock);
+ return -EINVAL;
+ }
+ priv->coreclock = clock;
+
+ iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ iomem = devm_ioremap(priv->dev, iores->start, resource_size(iores));
+ if (IS_ERR(iomem)) {
+ dev_err(priv->dev, "Unable to get serdes registers: %s\n",
+ iores->name);
+ return PTR_ERR(iomem);
+ }
+ for (idx = 0; idx < ARRAY_SIZE(sparx5_serdes_iomap); idx++) {
+ struct sparx5_serdes_io_resource *iomap = &sparx5_serdes_iomap[idx];
+
+ priv->regs[iomap->id] = iomem + iomap->offset;
+ }
+ for (idx = 0; idx < SPX5_SERDES_MAX; idx++) {
+ err = sparx5_phy_create(priv, idx, &priv->phys[idx]);
+ if (err)
+ return err;
+ }
+
+ provider = devm_of_phy_provider_register(priv->dev, sparx5_serdes_xlate);
+
+ return PTR_ERR_OR_ZERO(provider);
+}
+
+static const struct of_device_id sparx5_serdes_match[] = {
+ { .compatible = "microchip,sparx5-serdes" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, sparx5_serdes_match);
+
+static struct platform_driver sparx5_serdes_driver = {
+ .probe = sparx5_serdes_probe,
+ .driver = {
+ .name = "sparx5-serdes",
+ .of_match_table = sparx5_serdes_match,
+ },
+};
+
+module_platform_driver(sparx5_serdes_driver);
+
+MODULE_DESCRIPTION("Microchip Sparx5 switch serdes driver");
+MODULE_AUTHOR("Steen Hegelund <steen.hegelund@microchip.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/microchip/sparx5_serdes.h b/drivers/phy/microchip/sparx5_serdes.h
new file mode 100644
index 000000000000..0a3e496e6210
--- /dev/null
+++ b/drivers/phy/microchip/sparx5_serdes.h
@@ -0,0 +1,136 @@
+/* SPDX-License-Identifier: GPL-2.0+
+ * Microchip Sparx5 SerDes driver
+ *
+ * Copyright (c) 2020 Microchip Technology Inc.
+ */
+
+#ifndef _SPARX5_SERDES_H_
+#define _SPARX5_SERDES_H_
+
+#include "sparx5_serdes_regs.h"
+
+#define SPX5_SERDES_MAX 33
+
+enum sparx5_serdes_type {
+ SPX5_SDT_6G = 6,
+ SPX5_SDT_10G = 10,
+ SPX5_SDT_25G = 25,
+};
+
+enum sparx5_serdes_mode {
+ SPX5_SD_MODE_NONE,
+ SPX5_SD_MODE_2G5,
+ SPX5_SD_MODE_QSGMII,
+ SPX5_SD_MODE_100FX,
+ SPX5_SD_MODE_1000BASEX,
+ SPX5_SD_MODE_SFI,
+};
+
+struct sparx5_serdes_private {
+ struct device *dev;
+ void __iomem *regs[NUM_TARGETS];
+ struct phy *phys[SPX5_SERDES_MAX];
+ bool cmu_enabled;
+ unsigned long coreclock;
+};
+
+struct sparx5_serdes_macro {
+ struct sparx5_serdes_private *priv;
+ u32 sidx;
+ u32 stpidx;
+ enum sparx5_serdes_type serdestype;
+ enum sparx5_serdes_mode serdesmode;
+ phy_interface_t portmode;
+ int speed;
+ enum phy_media media;
+};
+
+/* Read, Write and modify registers content.
+ * The register definition macros start at the id
+ */
+static inline void __iomem *sdx5_addr(void __iomem *base[],
+ int id, int tinst, int tcnt,
+ int gbase, int ginst,
+ int gcnt, int gwidth,
+ int raddr, int rinst,
+ int rcnt, int rwidth)
+{
+ WARN_ON((tinst) >= tcnt);
+ WARN_ON((ginst) >= gcnt);
+ WARN_ON((rinst) >= rcnt);
+ return base[id + (tinst)] +
+ gbase + ((ginst) * gwidth) +
+ raddr + ((rinst) * rwidth);
+}
+
+static inline void __iomem *sdx5_inst_baseaddr(void __iomem *base,
+ int gbase, int ginst,
+ int gcnt, int gwidth,
+ int raddr, int rinst,
+ int rcnt, int rwidth)
+{
+ WARN_ON((ginst) >= gcnt);
+ WARN_ON((rinst) >= rcnt);
+ return base +
+ gbase + ((ginst) * gwidth) +
+ raddr + ((rinst) * rwidth);
+}
+
+static inline void sdx5_rmw(u32 val, u32 mask, struct sparx5_serdes_private *priv,
+ int id, int tinst, int tcnt,
+ int gbase, int ginst, int gcnt, int gwidth,
+ int raddr, int rinst, int rcnt, int rwidth)
+{
+ u32 nval;
+ void __iomem *addr =
+ sdx5_addr(priv->regs, id, tinst, tcnt,
+ gbase, ginst, gcnt, gwidth,
+ raddr, rinst, rcnt, rwidth);
+ nval = readl(addr);
+ nval = (nval & ~mask) | (val & mask);
+ writel(nval, addr);
+}
+
+static inline void sdx5_inst_rmw(u32 val, u32 mask, void __iomem *iomem,
+ int id, int tinst, int tcnt,
+ int gbase, int ginst, int gcnt, int gwidth,
+ int raddr, int rinst, int rcnt, int rwidth)
+{
+ u32 nval;
+ void __iomem *addr =
+ sdx5_inst_baseaddr(iomem,
+ gbase, ginst, gcnt, gwidth,
+ raddr, rinst, rcnt, rwidth);
+ nval = readl(addr);
+ nval = (nval & ~mask) | (val & mask);
+ writel(nval, addr);
+}
+
+static inline void sdx5_rmw_addr(u32 val, u32 mask, void __iomem *addr)
+{
+ u32 nval;
+
+ nval = readl(addr);
+ nval = (nval & ~mask) | (val & mask);
+ writel(nval, addr);
+}
+
+static inline void __iomem *sdx5_inst_get(struct sparx5_serdes_private *priv,
+ int id, int tinst)
+{
+ return priv->regs[id + tinst];
+}
+
+static inline void __iomem *sdx5_inst_addr(void __iomem *iomem,
+ int id, int tinst, int tcnt,
+ int gbase,
+ int ginst, int gcnt, int gwidth,
+ int raddr,
+ int rinst, int rcnt, int rwidth)
+{
+ return sdx5_inst_baseaddr(iomem, gbase, ginst, gcnt, gwidth,
+ raddr, rinst, rcnt, rwidth);
+}
+
+
+#endif /* _SPARX5_SERDES_REGS_H_ */
diff --git a/drivers/phy/microchip/sparx5_serdes_regs.h b/drivers/phy/microchip/sparx5_serdes_regs.h
new file mode 100644
index 000000000000..b96386a4df5a
--- /dev/null
+++ b/drivers/phy/microchip/sparx5_serdes_regs.h
@@ -0,0 +1,2695 @@
+/* SPDX-License-Identifier: GPL-2.0+
+ * Microchip Sparx5 SerDes driver
+ *
+ * Copyright (c) 2020 Microchip Technology Inc.
+ */
+
+/* This file is autogenerated by cml-utils 2020-11-16 13:11:27 +0100.
+ * Commit ID: 13bdf073131d8bf40c54901df6988ae4e9c8f29f
+ */
+
+#ifndef _SPARX5_SERDES_REGS_H_
+#define _SPARX5_SERDES_REGS_H_
+
+#include <linux/bitfield.h>
+#include <linux/types.h>
+#include <linux/bug.h>
+
+enum sparx5_serdes_target {
+ TARGET_SD10G_LANE = 200,
+ TARGET_SD25G_LANE = 212,
+ TARGET_SD6G_LANE = 233,
+ TARGET_SD_CMU = 248,
+ TARGET_SD_CMU_CFG = 262,
+ TARGET_SD_LANE = 276,
+ TARGET_SD_LANE_25G = 301,
+ NUM_TARGETS = 332
+};
+
+#define __REG(...) __VA_ARGS__
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_01 */
+#define SD10G_LANE_LANE_01(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 4, 0, 1, 4)
+
+#define SD10G_LANE_LANE_01_CFG_PMA_TX_CK_BITWIDTH_2_0 GENMASK(2, 0)
+#define SD10G_LANE_LANE_01_CFG_PMA_TX_CK_BITWIDTH_2_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_01_CFG_PMA_TX_CK_BITWIDTH_2_0, x)
+#define SD10G_LANE_LANE_01_CFG_PMA_TX_CK_BITWIDTH_2_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_01_CFG_PMA_TX_CK_BITWIDTH_2_0, x)
+
+#define SD10G_LANE_LANE_01_CFG_RXDET_EN BIT(4)
+#define SD10G_LANE_LANE_01_CFG_RXDET_EN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_01_CFG_RXDET_EN, x)
+#define SD10G_LANE_LANE_01_CFG_RXDET_EN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_01_CFG_RXDET_EN, x)
+
+#define SD10G_LANE_LANE_01_CFG_RXDET_STR BIT(5)
+#define SD10G_LANE_LANE_01_CFG_RXDET_STR_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_01_CFG_RXDET_STR, x)
+#define SD10G_LANE_LANE_01_CFG_RXDET_STR_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_01_CFG_RXDET_STR, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_02 */
+#define SD10G_LANE_LANE_02(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 8, 0, 1, 4)
+
+#define SD10G_LANE_LANE_02_CFG_EN_ADV BIT(0)
+#define SD10G_LANE_LANE_02_CFG_EN_ADV_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_02_CFG_EN_ADV, x)
+#define SD10G_LANE_LANE_02_CFG_EN_ADV_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_02_CFG_EN_ADV, x)
+
+#define SD10G_LANE_LANE_02_CFG_EN_MAIN BIT(1)
+#define SD10G_LANE_LANE_02_CFG_EN_MAIN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_02_CFG_EN_MAIN, x)
+#define SD10G_LANE_LANE_02_CFG_EN_MAIN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_02_CFG_EN_MAIN, x)
+
+#define SD10G_LANE_LANE_02_CFG_EN_DLY BIT(2)
+#define SD10G_LANE_LANE_02_CFG_EN_DLY_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_02_CFG_EN_DLY, x)
+#define SD10G_LANE_LANE_02_CFG_EN_DLY_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_02_CFG_EN_DLY, x)
+
+#define SD10G_LANE_LANE_02_CFG_EN_DLY2 BIT(3)
+#define SD10G_LANE_LANE_02_CFG_EN_DLY2_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_02_CFG_EN_DLY2, x)
+#define SD10G_LANE_LANE_02_CFG_EN_DLY2_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_02_CFG_EN_DLY2, x)
+
+#define SD10G_LANE_LANE_02_CFG_TAP_ADV_3_0 GENMASK(7, 4)
+#define SD10G_LANE_LANE_02_CFG_TAP_ADV_3_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_02_CFG_TAP_ADV_3_0, x)
+#define SD10G_LANE_LANE_02_CFG_TAP_ADV_3_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_02_CFG_TAP_ADV_3_0, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_03 */
+#define SD10G_LANE_LANE_03(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 12, 0, 1, 4)
+
+#define SD10G_LANE_LANE_03_CFG_TAP_MAIN BIT(0)
+#define SD10G_LANE_LANE_03_CFG_TAP_MAIN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_03_CFG_TAP_MAIN, x)
+#define SD10G_LANE_LANE_03_CFG_TAP_MAIN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_03_CFG_TAP_MAIN, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_04 */
+#define SD10G_LANE_LANE_04(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 16, 0, 1, 4)
+
+#define SD10G_LANE_LANE_04_CFG_TAP_DLY_4_0 GENMASK(4, 0)
+#define SD10G_LANE_LANE_04_CFG_TAP_DLY_4_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_04_CFG_TAP_DLY_4_0, x)
+#define SD10G_LANE_LANE_04_CFG_TAP_DLY_4_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_04_CFG_TAP_DLY_4_0, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_06 */
+#define SD10G_LANE_LANE_06(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 24, 0, 1, 4)
+
+#define SD10G_LANE_LANE_06_CFG_PD_DRIVER BIT(0)
+#define SD10G_LANE_LANE_06_CFG_PD_DRIVER_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_06_CFG_PD_DRIVER, x)
+#define SD10G_LANE_LANE_06_CFG_PD_DRIVER_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_06_CFG_PD_DRIVER, x)
+
+#define SD10G_LANE_LANE_06_CFG_PD_CLK BIT(1)
+#define SD10G_LANE_LANE_06_CFG_PD_CLK_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_06_CFG_PD_CLK, x)
+#define SD10G_LANE_LANE_06_CFG_PD_CLK_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_06_CFG_PD_CLK, x)
+
+#define SD10G_LANE_LANE_06_CFG_PD_CML BIT(2)
+#define SD10G_LANE_LANE_06_CFG_PD_CML_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_06_CFG_PD_CML, x)
+#define SD10G_LANE_LANE_06_CFG_PD_CML_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_06_CFG_PD_CML, x)
+
+#define SD10G_LANE_LANE_06_CFG_TX2RX_LP_EN BIT(3)
+#define SD10G_LANE_LANE_06_CFG_TX2RX_LP_EN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_06_CFG_TX2RX_LP_EN, x)
+#define SD10G_LANE_LANE_06_CFG_TX2RX_LP_EN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_06_CFG_TX2RX_LP_EN, x)
+
+#define SD10G_LANE_LANE_06_CFG_RX2TX_LP_EN BIT(4)
+#define SD10G_LANE_LANE_06_CFG_RX2TX_LP_EN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_06_CFG_RX2TX_LP_EN, x)
+#define SD10G_LANE_LANE_06_CFG_RX2TX_LP_EN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_06_CFG_RX2TX_LP_EN, x)
+
+#define SD10G_LANE_LANE_06_CFG_EN_PREEMPH BIT(5)
+#define SD10G_LANE_LANE_06_CFG_EN_PREEMPH_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_06_CFG_EN_PREEMPH, x)
+#define SD10G_LANE_LANE_06_CFG_EN_PREEMPH_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_06_CFG_EN_PREEMPH, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_0B */
+#define SD10G_LANE_LANE_0B(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 44, 0, 1, 4)
+
+#define SD10G_LANE_LANE_0B_CFG_EQ_RES_3_0 GENMASK(3, 0)
+#define SD10G_LANE_LANE_0B_CFG_EQ_RES_3_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_0B_CFG_EQ_RES_3_0, x)
+#define SD10G_LANE_LANE_0B_CFG_EQ_RES_3_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_0B_CFG_EQ_RES_3_0, x)
+
+#define SD10G_LANE_LANE_0B_CFG_PD_CTLE BIT(4)
+#define SD10G_LANE_LANE_0B_CFG_PD_CTLE_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_0B_CFG_PD_CTLE, x)
+#define SD10G_LANE_LANE_0B_CFG_PD_CTLE_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_0B_CFG_PD_CTLE, x)
+
+#define SD10G_LANE_LANE_0B_CFG_CTLE_TP_EN BIT(5)
+#define SD10G_LANE_LANE_0B_CFG_CTLE_TP_EN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_0B_CFG_CTLE_TP_EN, x)
+#define SD10G_LANE_LANE_0B_CFG_CTLE_TP_EN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_0B_CFG_CTLE_TP_EN, x)
+
+#define SD10G_LANE_LANE_0B_CFG_RESETB_OSCAL_AFE BIT(6)
+#define SD10G_LANE_LANE_0B_CFG_RESETB_OSCAL_AFE_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_0B_CFG_RESETB_OSCAL_AFE, x)
+#define SD10G_LANE_LANE_0B_CFG_RESETB_OSCAL_AFE_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_0B_CFG_RESETB_OSCAL_AFE, x)
+
+#define SD10G_LANE_LANE_0B_CFG_RESETB_OSCAL_SQ BIT(7)
+#define SD10G_LANE_LANE_0B_CFG_RESETB_OSCAL_SQ_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_0B_CFG_RESETB_OSCAL_SQ, x)
+#define SD10G_LANE_LANE_0B_CFG_RESETB_OSCAL_SQ_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_0B_CFG_RESETB_OSCAL_SQ, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_0C */
+#define SD10G_LANE_LANE_0C(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 48, 0, 1, 4)
+
+#define SD10G_LANE_LANE_0C_CFG_OSCAL_AFE BIT(0)
+#define SD10G_LANE_LANE_0C_CFG_OSCAL_AFE_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_0C_CFG_OSCAL_AFE, x)
+#define SD10G_LANE_LANE_0C_CFG_OSCAL_AFE_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_0C_CFG_OSCAL_AFE, x)
+
+#define SD10G_LANE_LANE_0C_CFG_OSCAL_SQ BIT(1)
+#define SD10G_LANE_LANE_0C_CFG_OSCAL_SQ_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_0C_CFG_OSCAL_SQ, x)
+#define SD10G_LANE_LANE_0C_CFG_OSCAL_SQ_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_0C_CFG_OSCAL_SQ, x)
+
+#define SD10G_LANE_LANE_0C_CFG_OSDAC_2X_AFE BIT(2)
+#define SD10G_LANE_LANE_0C_CFG_OSDAC_2X_AFE_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_0C_CFG_OSDAC_2X_AFE, x)
+#define SD10G_LANE_LANE_0C_CFG_OSDAC_2X_AFE_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_0C_CFG_OSDAC_2X_AFE, x)
+
+#define SD10G_LANE_LANE_0C_CFG_OSDAC_2X_SQ BIT(3)
+#define SD10G_LANE_LANE_0C_CFG_OSDAC_2X_SQ_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_0C_CFG_OSDAC_2X_SQ, x)
+#define SD10G_LANE_LANE_0C_CFG_OSDAC_2X_SQ_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_0C_CFG_OSDAC_2X_SQ, x)
+
+#define SD10G_LANE_LANE_0C_CFG_PD_OSDAC_AFE BIT(4)
+#define SD10G_LANE_LANE_0C_CFG_PD_OSDAC_AFE_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_0C_CFG_PD_OSDAC_AFE, x)
+#define SD10G_LANE_LANE_0C_CFG_PD_OSDAC_AFE_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_0C_CFG_PD_OSDAC_AFE, x)
+
+#define SD10G_LANE_LANE_0C_CFG_PD_OSDAC_SQ BIT(5)
+#define SD10G_LANE_LANE_0C_CFG_PD_OSDAC_SQ_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_0C_CFG_PD_OSDAC_SQ, x)
+#define SD10G_LANE_LANE_0C_CFG_PD_OSDAC_SQ_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_0C_CFG_PD_OSDAC_SQ, x)
+
+#define SD10G_LANE_LANE_0C_CFG_PD_RX_LS BIT(6)
+#define SD10G_LANE_LANE_0C_CFG_PD_RX_LS_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_0C_CFG_PD_RX_LS, x)
+#define SD10G_LANE_LANE_0C_CFG_PD_RX_LS_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_0C_CFG_PD_RX_LS, x)
+
+#define SD10G_LANE_LANE_0C_CFG_RX_PCIE_GEN12 BIT(7)
+#define SD10G_LANE_LANE_0C_CFG_RX_PCIE_GEN12_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_0C_CFG_RX_PCIE_GEN12, x)
+#define SD10G_LANE_LANE_0C_CFG_RX_PCIE_GEN12_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_0C_CFG_RX_PCIE_GEN12, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_0D */
+#define SD10G_LANE_LANE_0D(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 52, 0, 1, 4)
+
+#define SD10G_LANE_LANE_0D_CFG_CTLE_M_THR_1_0 GENMASK(1, 0)
+#define SD10G_LANE_LANE_0D_CFG_CTLE_M_THR_1_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_0D_CFG_CTLE_M_THR_1_0, x)
+#define SD10G_LANE_LANE_0D_CFG_CTLE_M_THR_1_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_0D_CFG_CTLE_M_THR_1_0, x)
+
+#define SD10G_LANE_LANE_0D_CFG_EQR_BYP BIT(4)
+#define SD10G_LANE_LANE_0D_CFG_EQR_BYP_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_0D_CFG_EQR_BYP, x)
+#define SD10G_LANE_LANE_0D_CFG_EQR_BYP_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_0D_CFG_EQR_BYP, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_0E */
+#define SD10G_LANE_LANE_0E(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 56, 0, 1, 4)
+
+#define SD10G_LANE_LANE_0E_CFG_EQC_FORCE_3_0 GENMASK(3, 0)
+#define SD10G_LANE_LANE_0E_CFG_EQC_FORCE_3_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_0E_CFG_EQC_FORCE_3_0, x)
+#define SD10G_LANE_LANE_0E_CFG_EQC_FORCE_3_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_0E_CFG_EQC_FORCE_3_0, x)
+
+#define SD10G_LANE_LANE_0E_CFG_RXLB_EN BIT(4)
+#define SD10G_LANE_LANE_0E_CFG_RXLB_EN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_0E_CFG_RXLB_EN, x)
+#define SD10G_LANE_LANE_0E_CFG_RXLB_EN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_0E_CFG_RXLB_EN, x)
+
+#define SD10G_LANE_LANE_0E_CFG_TXLB_EN BIT(5)
+#define SD10G_LANE_LANE_0E_CFG_TXLB_EN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_0E_CFG_TXLB_EN, x)
+#define SD10G_LANE_LANE_0E_CFG_TXLB_EN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_0E_CFG_TXLB_EN, x)
+
+#define SD10G_LANE_LANE_0E_CFG_SUM_SETCM_EN BIT(6)
+#define SD10G_LANE_LANE_0E_CFG_SUM_SETCM_EN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_0E_CFG_SUM_SETCM_EN, x)
+#define SD10G_LANE_LANE_0E_CFG_SUM_SETCM_EN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_0E_CFG_SUM_SETCM_EN, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_0F */
+#define SD10G_LANE_LANE_0F(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 60, 0, 1, 4)
+
+#define SD10G_LANE_LANE_0F_R_CDR_M_GEN1_7_0 GENMASK(7, 0)
+#define SD10G_LANE_LANE_0F_R_CDR_M_GEN1_7_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_0F_R_CDR_M_GEN1_7_0, x)
+#define SD10G_LANE_LANE_0F_R_CDR_M_GEN1_7_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_0F_R_CDR_M_GEN1_7_0, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_13 */
+#define SD10G_LANE_LANE_13(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 76, 0, 1, 4)
+
+#define SD10G_LANE_LANE_13_CFG_DCDR_PD BIT(0)
+#define SD10G_LANE_LANE_13_CFG_DCDR_PD_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_13_CFG_DCDR_PD, x)
+#define SD10G_LANE_LANE_13_CFG_DCDR_PD_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_13_CFG_DCDR_PD, x)
+
+#define SD10G_LANE_LANE_13_CFG_PHID_1T BIT(1)
+#define SD10G_LANE_LANE_13_CFG_PHID_1T_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_13_CFG_PHID_1T, x)
+#define SD10G_LANE_LANE_13_CFG_PHID_1T_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_13_CFG_PHID_1T, x)
+
+#define SD10G_LANE_LANE_13_CFG_CDRCK_EN BIT(2)
+#define SD10G_LANE_LANE_13_CFG_CDRCK_EN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_13_CFG_CDRCK_EN, x)
+#define SD10G_LANE_LANE_13_CFG_CDRCK_EN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_13_CFG_CDRCK_EN, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_14 */
+#define SD10G_LANE_LANE_14(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 80, 0, 1, 4)
+
+#define SD10G_LANE_LANE_14_CFG_PI_EXT_DAC_7_0 GENMASK(7, 0)
+#define SD10G_LANE_LANE_14_CFG_PI_EXT_DAC_7_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_14_CFG_PI_EXT_DAC_7_0, x)
+#define SD10G_LANE_LANE_14_CFG_PI_EXT_DAC_7_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_14_CFG_PI_EXT_DAC_7_0, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_15 */
+#define SD10G_LANE_LANE_15(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 84, 0, 1, 4)
+
+#define SD10G_LANE_LANE_15_CFG_PI_EXT_DAC_15_8 GENMASK(7, 0)
+#define SD10G_LANE_LANE_15_CFG_PI_EXT_DAC_15_8_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_15_CFG_PI_EXT_DAC_15_8, x)
+#define SD10G_LANE_LANE_15_CFG_PI_EXT_DAC_15_8_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_15_CFG_PI_EXT_DAC_15_8, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_16 */
+#define SD10G_LANE_LANE_16(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 88, 0, 1, 4)
+
+#define SD10G_LANE_LANE_16_CFG_PI_EXT_DAC_23_16 GENMASK(7, 0)
+#define SD10G_LANE_LANE_16_CFG_PI_EXT_DAC_23_16_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_16_CFG_PI_EXT_DAC_23_16, x)
+#define SD10G_LANE_LANE_16_CFG_PI_EXT_DAC_23_16_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_16_CFG_PI_EXT_DAC_23_16, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_1A */
+#define SD10G_LANE_LANE_1A(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 104, 0, 1, 4)
+
+#define SD10G_LANE_LANE_1A_CFG_PI_R_SCAN_EN BIT(0)
+#define SD10G_LANE_LANE_1A_CFG_PI_R_SCAN_EN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_1A_CFG_PI_R_SCAN_EN, x)
+#define SD10G_LANE_LANE_1A_CFG_PI_R_SCAN_EN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_1A_CFG_PI_R_SCAN_EN, x)
+
+#define SD10G_LANE_LANE_1A_CFG_PI_EN BIT(1)
+#define SD10G_LANE_LANE_1A_CFG_PI_EN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_1A_CFG_PI_EN, x)
+#define SD10G_LANE_LANE_1A_CFG_PI_EN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_1A_CFG_PI_EN, x)
+
+#define SD10G_LANE_LANE_1A_CFG_PI_DFE_EN BIT(2)
+#define SD10G_LANE_LANE_1A_CFG_PI_DFE_EN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_1A_CFG_PI_DFE_EN, x)
+#define SD10G_LANE_LANE_1A_CFG_PI_DFE_EN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_1A_CFG_PI_DFE_EN, x)
+
+#define SD10G_LANE_LANE_1A_CFG_PI_STEPS BIT(3)
+#define SD10G_LANE_LANE_1A_CFG_PI_STEPS_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_1A_CFG_PI_STEPS, x)
+#define SD10G_LANE_LANE_1A_CFG_PI_STEPS_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_1A_CFG_PI_STEPS, x)
+
+#define SD10G_LANE_LANE_1A_CFG_PI_FLOOP_STEPS_1_0 GENMASK(5, 4)
+#define SD10G_LANE_LANE_1A_CFG_PI_FLOOP_STEPS_1_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_1A_CFG_PI_FLOOP_STEPS_1_0, x)
+#define SD10G_LANE_LANE_1A_CFG_PI_FLOOP_STEPS_1_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_1A_CFG_PI_FLOOP_STEPS_1_0, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_22 */
+#define SD10G_LANE_LANE_22(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 136, 0, 1, 4)
+
+#define SD10G_LANE_LANE_22_CFG_DFETAP_EN_5_1 GENMASK(4, 0)
+#define SD10G_LANE_LANE_22_CFG_DFETAP_EN_5_1_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_22_CFG_DFETAP_EN_5_1, x)
+#define SD10G_LANE_LANE_22_CFG_DFETAP_EN_5_1_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_22_CFG_DFETAP_EN_5_1, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_23 */
+#define SD10G_LANE_LANE_23(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 140, 0, 1, 4)
+
+#define SD10G_LANE_LANE_23_CFG_DFE_PD BIT(0)
+#define SD10G_LANE_LANE_23_CFG_DFE_PD_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_23_CFG_DFE_PD, x)
+#define SD10G_LANE_LANE_23_CFG_DFE_PD_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_23_CFG_DFE_PD, x)
+
+#define SD10G_LANE_LANE_23_CFG_EN_DFEDIG BIT(1)
+#define SD10G_LANE_LANE_23_CFG_EN_DFEDIG_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_23_CFG_EN_DFEDIG, x)
+#define SD10G_LANE_LANE_23_CFG_EN_DFEDIG_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_23_CFG_EN_DFEDIG, x)
+
+#define SD10G_LANE_LANE_23_CFG_DFECK_EN BIT(2)
+#define SD10G_LANE_LANE_23_CFG_DFECK_EN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_23_CFG_DFECK_EN, x)
+#define SD10G_LANE_LANE_23_CFG_DFECK_EN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_23_CFG_DFECK_EN, x)
+
+#define SD10G_LANE_LANE_23_CFG_ERRAMP_PD BIT(3)
+#define SD10G_LANE_LANE_23_CFG_ERRAMP_PD_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_23_CFG_ERRAMP_PD, x)
+#define SD10G_LANE_LANE_23_CFG_ERRAMP_PD_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_23_CFG_ERRAMP_PD, x)
+
+#define SD10G_LANE_LANE_23_CFG_DFEDIG_M_2_0 GENMASK(6, 4)
+#define SD10G_LANE_LANE_23_CFG_DFEDIG_M_2_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_23_CFG_DFEDIG_M_2_0, x)
+#define SD10G_LANE_LANE_23_CFG_DFEDIG_M_2_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_23_CFG_DFEDIG_M_2_0, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_24 */
+#define SD10G_LANE_LANE_24(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 144, 0, 1, 4)
+
+#define SD10G_LANE_LANE_24_CFG_PI_BW_GEN1_3_0 GENMASK(3, 0)
+#define SD10G_LANE_LANE_24_CFG_PI_BW_GEN1_3_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_24_CFG_PI_BW_GEN1_3_0, x)
+#define SD10G_LANE_LANE_24_CFG_PI_BW_GEN1_3_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_24_CFG_PI_BW_GEN1_3_0, x)
+
+#define SD10G_LANE_LANE_24_CFG_PI_BW_GEN2_3_0 GENMASK(7, 4)
+#define SD10G_LANE_LANE_24_CFG_PI_BW_GEN2_3_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_24_CFG_PI_BW_GEN2_3_0, x)
+#define SD10G_LANE_LANE_24_CFG_PI_BW_GEN2_3_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_24_CFG_PI_BW_GEN2_3_0, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_26 */
+#define SD10G_LANE_LANE_26(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 152, 0, 1, 4)
+
+#define SD10G_LANE_LANE_26_CFG_ISCAN_EXT_DAC_7_0 GENMASK(7, 0)
+#define SD10G_LANE_LANE_26_CFG_ISCAN_EXT_DAC_7_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_26_CFG_ISCAN_EXT_DAC_7_0, x)
+#define SD10G_LANE_LANE_26_CFG_ISCAN_EXT_DAC_7_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_26_CFG_ISCAN_EXT_DAC_7_0, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_2F */
+#define SD10G_LANE_LANE_2F(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 188, 0, 1, 4)
+
+#define SD10G_LANE_LANE_2F_CFG_VGA_CP_2_0 GENMASK(2, 0)
+#define SD10G_LANE_LANE_2F_CFG_VGA_CP_2_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_2F_CFG_VGA_CP_2_0, x)
+#define SD10G_LANE_LANE_2F_CFG_VGA_CP_2_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_2F_CFG_VGA_CP_2_0, x)
+
+#define SD10G_LANE_LANE_2F_CFG_VGA_CTRL_3_0 GENMASK(7, 4)
+#define SD10G_LANE_LANE_2F_CFG_VGA_CTRL_3_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_2F_CFG_VGA_CTRL_3_0, x)
+#define SD10G_LANE_LANE_2F_CFG_VGA_CTRL_3_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_2F_CFG_VGA_CTRL_3_0, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_30 */
+#define SD10G_LANE_LANE_30(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 192, 0, 1, 4)
+
+#define SD10G_LANE_LANE_30_CFG_SUMMER_EN BIT(0)
+#define SD10G_LANE_LANE_30_CFG_SUMMER_EN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_30_CFG_SUMMER_EN, x)
+#define SD10G_LANE_LANE_30_CFG_SUMMER_EN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_30_CFG_SUMMER_EN, x)
+
+#define SD10G_LANE_LANE_30_CFG_RXDIV_SEL_2_0 GENMASK(6, 4)
+#define SD10G_LANE_LANE_30_CFG_RXDIV_SEL_2_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_30_CFG_RXDIV_SEL_2_0, x)
+#define SD10G_LANE_LANE_30_CFG_RXDIV_SEL_2_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_30_CFG_RXDIV_SEL_2_0, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_31 */
+#define SD10G_LANE_LANE_31(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 196, 0, 1, 4)
+
+#define SD10G_LANE_LANE_31_CFG_PI_RSTN BIT(0)
+#define SD10G_LANE_LANE_31_CFG_PI_RSTN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_31_CFG_PI_RSTN, x)
+#define SD10G_LANE_LANE_31_CFG_PI_RSTN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_31_CFG_PI_RSTN, x)
+
+#define SD10G_LANE_LANE_31_CFG_CDR_RSTN BIT(1)
+#define SD10G_LANE_LANE_31_CFG_CDR_RSTN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_31_CFG_CDR_RSTN, x)
+#define SD10G_LANE_LANE_31_CFG_CDR_RSTN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_31_CFG_CDR_RSTN, x)
+
+#define SD10G_LANE_LANE_31_CFG_RSTN_DFEDIG BIT(2)
+#define SD10G_LANE_LANE_31_CFG_RSTN_DFEDIG_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_31_CFG_RSTN_DFEDIG, x)
+#define SD10G_LANE_LANE_31_CFG_RSTN_DFEDIG_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_31_CFG_RSTN_DFEDIG, x)
+
+#define SD10G_LANE_LANE_31_CFG_CTLE_RSTN BIT(3)
+#define SD10G_LANE_LANE_31_CFG_CTLE_RSTN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_31_CFG_CTLE_RSTN, x)
+#define SD10G_LANE_LANE_31_CFG_CTLE_RSTN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_31_CFG_CTLE_RSTN, x)
+
+#define SD10G_LANE_LANE_31_CFG_RSTN_DIV5_8 BIT(4)
+#define SD10G_LANE_LANE_31_CFG_RSTN_DIV5_8_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_31_CFG_RSTN_DIV5_8, x)
+#define SD10G_LANE_LANE_31_CFG_RSTN_DIV5_8_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_31_CFG_RSTN_DIV5_8, x)
+
+#define SD10G_LANE_LANE_31_CFG_R50_EN BIT(5)
+#define SD10G_LANE_LANE_31_CFG_R50_EN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_31_CFG_R50_EN, x)
+#define SD10G_LANE_LANE_31_CFG_R50_EN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_31_CFG_R50_EN, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_32 */
+#define SD10G_LANE_LANE_32(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 200, 0, 1, 4)
+
+#define SD10G_LANE_LANE_32_CFG_ITX_IPCLK_BASE_1_0 GENMASK(1, 0)
+#define SD10G_LANE_LANE_32_CFG_ITX_IPCLK_BASE_1_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_32_CFG_ITX_IPCLK_BASE_1_0, x)
+#define SD10G_LANE_LANE_32_CFG_ITX_IPCLK_BASE_1_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_32_CFG_ITX_IPCLK_BASE_1_0, x)
+
+#define SD10G_LANE_LANE_32_CFG_ITX_IPCML_BASE_1_0 GENMASK(5, 4)
+#define SD10G_LANE_LANE_32_CFG_ITX_IPCML_BASE_1_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_32_CFG_ITX_IPCML_BASE_1_0, x)
+#define SD10G_LANE_LANE_32_CFG_ITX_IPCML_BASE_1_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_32_CFG_ITX_IPCML_BASE_1_0, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_33 */
+#define SD10G_LANE_LANE_33(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 204, 0, 1, 4)
+
+#define SD10G_LANE_LANE_33_CFG_ITX_IPDRIVER_BASE_2_0 GENMASK(2, 0)
+#define SD10G_LANE_LANE_33_CFG_ITX_IPDRIVER_BASE_2_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_33_CFG_ITX_IPDRIVER_BASE_2_0, x)
+#define SD10G_LANE_LANE_33_CFG_ITX_IPDRIVER_BASE_2_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_33_CFG_ITX_IPDRIVER_BASE_2_0, x)
+
+#define SD10G_LANE_LANE_33_CFG_ITX_IPPREEMP_BASE_1_0 GENMASK(5, 4)
+#define SD10G_LANE_LANE_33_CFG_ITX_IPPREEMP_BASE_1_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_33_CFG_ITX_IPPREEMP_BASE_1_0, x)
+#define SD10G_LANE_LANE_33_CFG_ITX_IPPREEMP_BASE_1_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_33_CFG_ITX_IPPREEMP_BASE_1_0, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_35 */
+#define SD10G_LANE_LANE_35(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 212, 0, 1, 4)
+
+#define SD10G_LANE_LANE_35_CFG_TXRATE_1_0 GENMASK(1, 0)
+#define SD10G_LANE_LANE_35_CFG_TXRATE_1_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_35_CFG_TXRATE_1_0, x)
+#define SD10G_LANE_LANE_35_CFG_TXRATE_1_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_35_CFG_TXRATE_1_0, x)
+
+#define SD10G_LANE_LANE_35_CFG_RXRATE_1_0 GENMASK(5, 4)
+#define SD10G_LANE_LANE_35_CFG_RXRATE_1_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_35_CFG_RXRATE_1_0, x)
+#define SD10G_LANE_LANE_35_CFG_RXRATE_1_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_35_CFG_RXRATE_1_0, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_36 */
+#define SD10G_LANE_LANE_36(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 216, 0, 1, 4)
+
+#define SD10G_LANE_LANE_36_CFG_PREDRV_SLEWRATE_1_0 GENMASK(1, 0)
+#define SD10G_LANE_LANE_36_CFG_PREDRV_SLEWRATE_1_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_36_CFG_PREDRV_SLEWRATE_1_0, x)
+#define SD10G_LANE_LANE_36_CFG_PREDRV_SLEWRATE_1_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_36_CFG_PREDRV_SLEWRATE_1_0, x)
+
+#define SD10G_LANE_LANE_36_CFG_EID_LP BIT(4)
+#define SD10G_LANE_LANE_36_CFG_EID_LP_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_36_CFG_EID_LP, x)
+#define SD10G_LANE_LANE_36_CFG_EID_LP_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_36_CFG_EID_LP, x)
+
+#define SD10G_LANE_LANE_36_CFG_EN_PREDRV_EMPH BIT(5)
+#define SD10G_LANE_LANE_36_CFG_EN_PREDRV_EMPH_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_36_CFG_EN_PREDRV_EMPH, x)
+#define SD10G_LANE_LANE_36_CFG_EN_PREDRV_EMPH_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_36_CFG_EN_PREDRV_EMPH, x)
+
+#define SD10G_LANE_LANE_36_CFG_PRBS_SEL BIT(6)
+#define SD10G_LANE_LANE_36_CFG_PRBS_SEL_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_36_CFG_PRBS_SEL, x)
+#define SD10G_LANE_LANE_36_CFG_PRBS_SEL_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_36_CFG_PRBS_SEL, x)
+
+#define SD10G_LANE_LANE_36_CFG_PRBS_SETB BIT(7)
+#define SD10G_LANE_LANE_36_CFG_PRBS_SETB_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_36_CFG_PRBS_SETB, x)
+#define SD10G_LANE_LANE_36_CFG_PRBS_SETB_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_36_CFG_PRBS_SETB, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_37 */
+#define SD10G_LANE_LANE_37(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 220, 0, 1, 4)
+
+#define SD10G_LANE_LANE_37_CFG_RXDET_COMP_PD BIT(0)
+#define SD10G_LANE_LANE_37_CFG_RXDET_COMP_PD_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_37_CFG_RXDET_COMP_PD, x)
+#define SD10G_LANE_LANE_37_CFG_RXDET_COMP_PD_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_37_CFG_RXDET_COMP_PD, x)
+
+#define SD10G_LANE_LANE_37_CFG_PD_RX_CKTREE BIT(1)
+#define SD10G_LANE_LANE_37_CFG_PD_RX_CKTREE_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_37_CFG_PD_RX_CKTREE, x)
+#define SD10G_LANE_LANE_37_CFG_PD_RX_CKTREE_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_37_CFG_PD_RX_CKTREE, x)
+
+#define SD10G_LANE_LANE_37_CFG_TXSWING_HALF BIT(2)
+#define SD10G_LANE_LANE_37_CFG_TXSWING_HALF_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_37_CFG_TXSWING_HALF, x)
+#define SD10G_LANE_LANE_37_CFG_TXSWING_HALF_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_37_CFG_TXSWING_HALF, x)
+
+#define SD10G_LANE_LANE_37_CFG_IP_PRE_BASE_1_0 GENMASK(5, 4)
+#define SD10G_LANE_LANE_37_CFG_IP_PRE_BASE_1_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_37_CFG_IP_PRE_BASE_1_0, x)
+#define SD10G_LANE_LANE_37_CFG_IP_PRE_BASE_1_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_37_CFG_IP_PRE_BASE_1_0, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_39 */
+#define SD10G_LANE_LANE_39(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 228, 0, 1, 4)
+
+#define SD10G_LANE_LANE_39_CFG_RXFILT_Y_2_0 GENMASK(2, 0)
+#define SD10G_LANE_LANE_39_CFG_RXFILT_Y_2_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_39_CFG_RXFILT_Y_2_0, x)
+#define SD10G_LANE_LANE_39_CFG_RXFILT_Y_2_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_39_CFG_RXFILT_Y_2_0, x)
+
+#define SD10G_LANE_LANE_39_CFG_RX_SSC_LH BIT(4)
+#define SD10G_LANE_LANE_39_CFG_RX_SSC_LH_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_39_CFG_RX_SSC_LH, x)
+#define SD10G_LANE_LANE_39_CFG_RX_SSC_LH_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_39_CFG_RX_SSC_LH, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_3A */
+#define SD10G_LANE_LANE_3A(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 232, 0, 1, 4)
+
+#define SD10G_LANE_LANE_3A_CFG_MP_MIN_3_0 GENMASK(3, 0)
+#define SD10G_LANE_LANE_3A_CFG_MP_MIN_3_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_3A_CFG_MP_MIN_3_0, x)
+#define SD10G_LANE_LANE_3A_CFG_MP_MIN_3_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_3A_CFG_MP_MIN_3_0, x)
+
+#define SD10G_LANE_LANE_3A_CFG_MP_MAX_3_0 GENMASK(7, 4)
+#define SD10G_LANE_LANE_3A_CFG_MP_MAX_3_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_3A_CFG_MP_MAX_3_0, x)
+#define SD10G_LANE_LANE_3A_CFG_MP_MAX_3_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_3A_CFG_MP_MAX_3_0, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_3C */
+#define SD10G_LANE_LANE_3C(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 240, 0, 1, 4)
+
+#define SD10G_LANE_LANE_3C_CFG_DIS_ACC BIT(0)
+#define SD10G_LANE_LANE_3C_CFG_DIS_ACC_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_3C_CFG_DIS_ACC, x)
+#define SD10G_LANE_LANE_3C_CFG_DIS_ACC_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_3C_CFG_DIS_ACC, x)
+
+#define SD10G_LANE_LANE_3C_CFG_DIS_2NDORDER BIT(1)
+#define SD10G_LANE_LANE_3C_CFG_DIS_2NDORDER_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_3C_CFG_DIS_2NDORDER, x)
+#define SD10G_LANE_LANE_3C_CFG_DIS_2NDORDER_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_3C_CFG_DIS_2NDORDER, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_40 */
+#define SD10G_LANE_LANE_40(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 256, 0, 1, 4)
+
+#define SD10G_LANE_LANE_40_CFG_LANE_RESERVE_7_0 GENMASK(7, 0)
+#define SD10G_LANE_LANE_40_CFG_LANE_RESERVE_7_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_40_CFG_LANE_RESERVE_7_0, x)
+#define SD10G_LANE_LANE_40_CFG_LANE_RESERVE_7_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_40_CFG_LANE_RESERVE_7_0, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_41 */
+#define SD10G_LANE_LANE_41(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 260, 0, 1, 4)
+
+#define SD10G_LANE_LANE_41_CFG_LANE_RESERVE_15_8 GENMASK(7, 0)
+#define SD10G_LANE_LANE_41_CFG_LANE_RESERVE_15_8_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_41_CFG_LANE_RESERVE_15_8, x)
+#define SD10G_LANE_LANE_41_CFG_LANE_RESERVE_15_8_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_41_CFG_LANE_RESERVE_15_8, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_0:LANE_42 */
+#define SD10G_LANE_LANE_42(t) __REG(TARGET_SD10G_LANE, t, 12, 0, 0, 1, 288, 264, 0, 1, 4)
+
+#define SD10G_LANE_LANE_42_CFG_CDR_KF_GEN1_2_0 GENMASK(2, 0)
+#define SD10G_LANE_LANE_42_CFG_CDR_KF_GEN1_2_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_42_CFG_CDR_KF_GEN1_2_0, x)
+#define SD10G_LANE_LANE_42_CFG_CDR_KF_GEN1_2_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_42_CFG_CDR_KF_GEN1_2_0, x)
+
+#define SD10G_LANE_LANE_42_CFG_CDR_KF_GEN2_2_0 GENMASK(6, 4)
+#define SD10G_LANE_LANE_42_CFG_CDR_KF_GEN2_2_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_42_CFG_CDR_KF_GEN2_2_0, x)
+#define SD10G_LANE_LANE_42_CFG_CDR_KF_GEN2_2_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_42_CFG_CDR_KF_GEN2_2_0, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_1:LANE_48 */
+#define SD10G_LANE_LANE_48(t) __REG(TARGET_SD10G_LANE, t, 12, 288, 0, 1, 40, 0, 0, 1, 4)
+
+#define SD10G_LANE_LANE_48_CFG_ALOS_THR_3_0 GENMASK(3, 0)
+#define SD10G_LANE_LANE_48_CFG_ALOS_THR_3_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_48_CFG_ALOS_THR_3_0, x)
+#define SD10G_LANE_LANE_48_CFG_ALOS_THR_3_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_48_CFG_ALOS_THR_3_0, x)
+
+#define SD10G_LANE_LANE_48_CFG_AUX_RXCK_SEL BIT(4)
+#define SD10G_LANE_LANE_48_CFG_AUX_RXCK_SEL_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_48_CFG_AUX_RXCK_SEL, x)
+#define SD10G_LANE_LANE_48_CFG_AUX_RXCK_SEL_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_48_CFG_AUX_RXCK_SEL, x)
+
+#define SD10G_LANE_LANE_48_CFG_CLK_ENQ BIT(5)
+#define SD10G_LANE_LANE_48_CFG_CLK_ENQ_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_48_CFG_CLK_ENQ, x)
+#define SD10G_LANE_LANE_48_CFG_CLK_ENQ_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_48_CFG_CLK_ENQ, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_1:LANE_50 */
+#define SD10G_LANE_LANE_50(t) __REG(TARGET_SD10G_LANE, t, 12, 288, 0, 1, 40, 32, 0, 1, 4)
+
+#define SD10G_LANE_LANE_50_CFG_SSC_PI_STEP_1_0 GENMASK(1, 0)
+#define SD10G_LANE_LANE_50_CFG_SSC_PI_STEP_1_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_50_CFG_SSC_PI_STEP_1_0, x)
+#define SD10G_LANE_LANE_50_CFG_SSC_PI_STEP_1_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_50_CFG_SSC_PI_STEP_1_0, x)
+
+#define SD10G_LANE_LANE_50_CFG_SSC_RESETB BIT(4)
+#define SD10G_LANE_LANE_50_CFG_SSC_RESETB_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_50_CFG_SSC_RESETB, x)
+#define SD10G_LANE_LANE_50_CFG_SSC_RESETB_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_50_CFG_SSC_RESETB, x)
+
+#define SD10G_LANE_LANE_50_CFG_SSC_RTL_CLK_SEL BIT(5)
+#define SD10G_LANE_LANE_50_CFG_SSC_RTL_CLK_SEL_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_50_CFG_SSC_RTL_CLK_SEL, x)
+#define SD10G_LANE_LANE_50_CFG_SSC_RTL_CLK_SEL_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_50_CFG_SSC_RTL_CLK_SEL, x)
+
+#define SD10G_LANE_LANE_50_CFG_AUX_TXCK_SEL BIT(6)
+#define SD10G_LANE_LANE_50_CFG_AUX_TXCK_SEL_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_50_CFG_AUX_TXCK_SEL, x)
+#define SD10G_LANE_LANE_50_CFG_AUX_TXCK_SEL_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_50_CFG_AUX_TXCK_SEL, x)
+
+#define SD10G_LANE_LANE_50_CFG_JT_EN BIT(7)
+#define SD10G_LANE_LANE_50_CFG_JT_EN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_50_CFG_JT_EN, x)
+#define SD10G_LANE_LANE_50_CFG_JT_EN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_50_CFG_JT_EN, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_2:LANE_52 */
+#define SD10G_LANE_LANE_52(t) __REG(TARGET_SD10G_LANE, t, 12, 328, 0, 1, 24, 0, 0, 1, 4)
+
+#define SD10G_LANE_LANE_52_CFG_IBIAS_TUNE_RESERVE_5_0 GENMASK(5, 0)
+#define SD10G_LANE_LANE_52_CFG_IBIAS_TUNE_RESERVE_5_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_52_CFG_IBIAS_TUNE_RESERVE_5_0, x)
+#define SD10G_LANE_LANE_52_CFG_IBIAS_TUNE_RESERVE_5_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_52_CFG_IBIAS_TUNE_RESERVE_5_0, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_4:LANE_83 */
+#define SD10G_LANE_LANE_83(t) __REG(TARGET_SD10G_LANE, t, 12, 464, 0, 1, 112, 60, 0, 1, 4)
+
+#define SD10G_LANE_LANE_83_R_TX_BIT_REVERSE BIT(0)
+#define SD10G_LANE_LANE_83_R_TX_BIT_REVERSE_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_83_R_TX_BIT_REVERSE, x)
+#define SD10G_LANE_LANE_83_R_TX_BIT_REVERSE_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_83_R_TX_BIT_REVERSE, x)
+
+#define SD10G_LANE_LANE_83_R_TX_POL_INV BIT(1)
+#define SD10G_LANE_LANE_83_R_TX_POL_INV_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_83_R_TX_POL_INV, x)
+#define SD10G_LANE_LANE_83_R_TX_POL_INV_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_83_R_TX_POL_INV, x)
+
+#define SD10G_LANE_LANE_83_R_RX_BIT_REVERSE BIT(2)
+#define SD10G_LANE_LANE_83_R_RX_BIT_REVERSE_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_83_R_RX_BIT_REVERSE, x)
+#define SD10G_LANE_LANE_83_R_RX_BIT_REVERSE_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_83_R_RX_BIT_REVERSE, x)
+
+#define SD10G_LANE_LANE_83_R_RX_POL_INV BIT(3)
+#define SD10G_LANE_LANE_83_R_RX_POL_INV_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_83_R_RX_POL_INV, x)
+#define SD10G_LANE_LANE_83_R_RX_POL_INV_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_83_R_RX_POL_INV, x)
+
+#define SD10G_LANE_LANE_83_R_DFE_RSTN BIT(4)
+#define SD10G_LANE_LANE_83_R_DFE_RSTN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_83_R_DFE_RSTN, x)
+#define SD10G_LANE_LANE_83_R_DFE_RSTN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_83_R_DFE_RSTN, x)
+
+#define SD10G_LANE_LANE_83_R_CDR_RSTN BIT(5)
+#define SD10G_LANE_LANE_83_R_CDR_RSTN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_83_R_CDR_RSTN, x)
+#define SD10G_LANE_LANE_83_R_CDR_RSTN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_83_R_CDR_RSTN, x)
+
+#define SD10G_LANE_LANE_83_R_CTLE_RSTN BIT(6)
+#define SD10G_LANE_LANE_83_R_CTLE_RSTN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_83_R_CTLE_RSTN, x)
+#define SD10G_LANE_LANE_83_R_CTLE_RSTN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_83_R_CTLE_RSTN, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_5:LANE_93 */
+#define SD10G_LANE_LANE_93(t) __REG(TARGET_SD10G_LANE, t, 12, 576, 0, 1, 64, 12, 0, 1, 4)
+
+#define SD10G_LANE_LANE_93_R_RXEI_FIFO_RST_EN BIT(0)
+#define SD10G_LANE_LANE_93_R_RXEI_FIFO_RST_EN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_93_R_RXEI_FIFO_RST_EN, x)
+#define SD10G_LANE_LANE_93_R_RXEI_FIFO_RST_EN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_93_R_RXEI_FIFO_RST_EN, x)
+
+#define SD10G_LANE_LANE_93_R_DWIDTHCTRL_FROM_HWT BIT(1)
+#define SD10G_LANE_LANE_93_R_DWIDTHCTRL_FROM_HWT_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_93_R_DWIDTHCTRL_FROM_HWT, x)
+#define SD10G_LANE_LANE_93_R_DWIDTHCTRL_FROM_HWT_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_93_R_DWIDTHCTRL_FROM_HWT, x)
+
+#define SD10G_LANE_LANE_93_R_DIS_RESTORE_DFE BIT(2)
+#define SD10G_LANE_LANE_93_R_DIS_RESTORE_DFE_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_93_R_DIS_RESTORE_DFE, x)
+#define SD10G_LANE_LANE_93_R_DIS_RESTORE_DFE_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_93_R_DIS_RESTORE_DFE, x)
+
+#define SD10G_LANE_LANE_93_R_EN_RATECHG_CTRL BIT(3)
+#define SD10G_LANE_LANE_93_R_EN_RATECHG_CTRL_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_93_R_EN_RATECHG_CTRL, x)
+#define SD10G_LANE_LANE_93_R_EN_RATECHG_CTRL_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_93_R_EN_RATECHG_CTRL, x)
+
+#define SD10G_LANE_LANE_93_R_REG_MANUAL BIT(4)
+#define SD10G_LANE_LANE_93_R_REG_MANUAL_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_93_R_REG_MANUAL, x)
+#define SD10G_LANE_LANE_93_R_REG_MANUAL_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_93_R_REG_MANUAL, x)
+
+#define SD10G_LANE_LANE_93_R_AUXCKSEL_FROM_HWT BIT(5)
+#define SD10G_LANE_LANE_93_R_AUXCKSEL_FROM_HWT_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_93_R_AUXCKSEL_FROM_HWT, x)
+#define SD10G_LANE_LANE_93_R_AUXCKSEL_FROM_HWT_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_93_R_AUXCKSEL_FROM_HWT, x)
+
+#define SD10G_LANE_LANE_93_R_LANE_ID_FROM_HWT BIT(6)
+#define SD10G_LANE_LANE_93_R_LANE_ID_FROM_HWT_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_93_R_LANE_ID_FROM_HWT, x)
+#define SD10G_LANE_LANE_93_R_LANE_ID_FROM_HWT_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_93_R_LANE_ID_FROM_HWT, x)
+
+#define SD10G_LANE_LANE_93_R_RX_PCIE_GEN12_FROM_HWT BIT(7)
+#define SD10G_LANE_LANE_93_R_RX_PCIE_GEN12_FROM_HWT_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_93_R_RX_PCIE_GEN12_FROM_HWT, x)
+#define SD10G_LANE_LANE_93_R_RX_PCIE_GEN12_FROM_HWT_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_93_R_RX_PCIE_GEN12_FROM_HWT, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_5:LANE_94 */
+#define SD10G_LANE_LANE_94(t) __REG(TARGET_SD10G_LANE, t, 12, 576, 0, 1, 64, 16, 0, 1, 4)
+
+#define SD10G_LANE_LANE_94_R_DWIDTHCTRL_2_0 GENMASK(2, 0)
+#define SD10G_LANE_LANE_94_R_DWIDTHCTRL_2_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_94_R_DWIDTHCTRL_2_0, x)
+#define SD10G_LANE_LANE_94_R_DWIDTHCTRL_2_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_94_R_DWIDTHCTRL_2_0, x)
+
+#define SD10G_LANE_LANE_94_R_ISCAN_REG BIT(4)
+#define SD10G_LANE_LANE_94_R_ISCAN_REG_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_94_R_ISCAN_REG, x)
+#define SD10G_LANE_LANE_94_R_ISCAN_REG_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_94_R_ISCAN_REG, x)
+
+#define SD10G_LANE_LANE_94_R_TXEQ_REG BIT(5)
+#define SD10G_LANE_LANE_94_R_TXEQ_REG_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_94_R_TXEQ_REG, x)
+#define SD10G_LANE_LANE_94_R_TXEQ_REG_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_94_R_TXEQ_REG, x)
+
+#define SD10G_LANE_LANE_94_R_MISC_REG BIT(6)
+#define SD10G_LANE_LANE_94_R_MISC_REG_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_94_R_MISC_REG, x)
+#define SD10G_LANE_LANE_94_R_MISC_REG_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_94_R_MISC_REG, x)
+
+#define SD10G_LANE_LANE_94_R_SWING_REG BIT(7)
+#define SD10G_LANE_LANE_94_R_SWING_REG_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_94_R_SWING_REG, x)
+#define SD10G_LANE_LANE_94_R_SWING_REG_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_94_R_SWING_REG, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_5:LANE_9E */
+#define SD10G_LANE_LANE_9E(t) __REG(TARGET_SD10G_LANE, t, 12, 576, 0, 1, 64, 56, 0, 1, 4)
+
+#define SD10G_LANE_LANE_9E_R_RXEQ_REG BIT(0)
+#define SD10G_LANE_LANE_9E_R_RXEQ_REG_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_9E_R_RXEQ_REG, x)
+#define SD10G_LANE_LANE_9E_R_RXEQ_REG_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_9E_R_RXEQ_REG, x)
+
+#define SD10G_LANE_LANE_9E_R_AUTO_RST_TREE_PD_MAN BIT(1)
+#define SD10G_LANE_LANE_9E_R_AUTO_RST_TREE_PD_MAN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_9E_R_AUTO_RST_TREE_PD_MAN, x)
+#define SD10G_LANE_LANE_9E_R_AUTO_RST_TREE_PD_MAN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_9E_R_AUTO_RST_TREE_PD_MAN, x)
+
+#define SD10G_LANE_LANE_9E_R_EN_AUTO_CDR_RSTN BIT(2)
+#define SD10G_LANE_LANE_9E_R_EN_AUTO_CDR_RSTN_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_9E_R_EN_AUTO_CDR_RSTN, x)
+#define SD10G_LANE_LANE_9E_R_EN_AUTO_CDR_RSTN_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_9E_R_EN_AUTO_CDR_RSTN, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_6:LANE_A1 */
+#define SD10G_LANE_LANE_A1(t) __REG(TARGET_SD10G_LANE, t, 12, 640, 0, 1, 128, 4, 0, 1, 4)
+
+#define SD10G_LANE_LANE_A1_R_PMA_TXCK_DIV_SEL_1_0 GENMASK(1, 0)
+#define SD10G_LANE_LANE_A1_R_PMA_TXCK_DIV_SEL_1_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_A1_R_PMA_TXCK_DIV_SEL_1_0, x)
+#define SD10G_LANE_LANE_A1_R_PMA_TXCK_DIV_SEL_1_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_A1_R_PMA_TXCK_DIV_SEL_1_0, x)
+
+#define SD10G_LANE_LANE_A1_R_SSC_FROM_HWT BIT(4)
+#define SD10G_LANE_LANE_A1_R_SSC_FROM_HWT_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_A1_R_SSC_FROM_HWT, x)
+#define SD10G_LANE_LANE_A1_R_SSC_FROM_HWT_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_A1_R_SSC_FROM_HWT, x)
+
+#define SD10G_LANE_LANE_A1_R_CDR_FROM_HWT BIT(5)
+#define SD10G_LANE_LANE_A1_R_CDR_FROM_HWT_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_A1_R_CDR_FROM_HWT, x)
+#define SD10G_LANE_LANE_A1_R_CDR_FROM_HWT_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_A1_R_CDR_FROM_HWT, x)
+
+#define SD10G_LANE_LANE_A1_R_PCLK_GATING_FROM_HWT BIT(6)
+#define SD10G_LANE_LANE_A1_R_PCLK_GATING_FROM_HWT_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_A1_R_PCLK_GATING_FROM_HWT, x)
+#define SD10G_LANE_LANE_A1_R_PCLK_GATING_FROM_HWT_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_A1_R_PCLK_GATING_FROM_HWT, x)
+
+#define SD10G_LANE_LANE_A1_R_PCLK_GATING BIT(7)
+#define SD10G_LANE_LANE_A1_R_PCLK_GATING_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_A1_R_PCLK_GATING, x)
+#define SD10G_LANE_LANE_A1_R_PCLK_GATING_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_A1_R_PCLK_GATING, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_6:LANE_A2 */
+#define SD10G_LANE_LANE_A2(t) __REG(TARGET_SD10G_LANE, t, 12, 640, 0, 1, 128, 8, 0, 1, 4)
+
+#define SD10G_LANE_LANE_A2_R_PCS2PMA_PHYMODE_4_0 GENMASK(4, 0)
+#define SD10G_LANE_LANE_A2_R_PCS2PMA_PHYMODE_4_0_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_A2_R_PCS2PMA_PHYMODE_4_0, x)
+#define SD10G_LANE_LANE_A2_R_PCS2PMA_PHYMODE_4_0_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_A2_R_PCS2PMA_PHYMODE_4_0, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_8:LANE_DF */
+#define SD10G_LANE_LANE_DF(t) __REG(TARGET_SD10G_LANE, t, 12, 832, 0, 1, 84, 60, 0, 1, 4)
+
+#define SD10G_LANE_LANE_DF_LOL_UDL BIT(0)
+#define SD10G_LANE_LANE_DF_LOL_UDL_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_DF_LOL_UDL, x)
+#define SD10G_LANE_LANE_DF_LOL_UDL_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_DF_LOL_UDL, x)
+
+#define SD10G_LANE_LANE_DF_LOL BIT(1)
+#define SD10G_LANE_LANE_DF_LOL_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_DF_LOL, x)
+#define SD10G_LANE_LANE_DF_LOL_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_DF_LOL, x)
+
+#define SD10G_LANE_LANE_DF_PMA2PCS_RXEI_FILTERED BIT(2)
+#define SD10G_LANE_LANE_DF_PMA2PCS_RXEI_FILTERED_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_DF_PMA2PCS_RXEI_FILTERED, x)
+#define SD10G_LANE_LANE_DF_PMA2PCS_RXEI_FILTERED_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_DF_PMA2PCS_RXEI_FILTERED, x)
+
+#define SD10G_LANE_LANE_DF_SQUELCH BIT(3)
+#define SD10G_LANE_LANE_DF_SQUELCH_SET(x)\
+ FIELD_PREP(SD10G_LANE_LANE_DF_SQUELCH, x)
+#define SD10G_LANE_LANE_DF_SQUELCH_GET(x)\
+ FIELD_GET(SD10G_LANE_LANE_DF_SQUELCH, x)
+
+/* SD25G_TARGET:CMU_GRP_0:CMU_09 */
+#define SD25G_LANE_CMU_09(t) __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 36, 0, 1, 4)
+
+#define SD25G_LANE_CMU_09_CFG_REFCK_TERM_EN BIT(0)
+#define SD25G_LANE_CMU_09_CFG_REFCK_TERM_EN_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_09_CFG_REFCK_TERM_EN, x)
+#define SD25G_LANE_CMU_09_CFG_REFCK_TERM_EN_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_09_CFG_REFCK_TERM_EN, x)
+
+#define SD25G_LANE_CMU_09_CFG_EN_DUMMY BIT(1)
+#define SD25G_LANE_CMU_09_CFG_EN_DUMMY_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_09_CFG_EN_DUMMY, x)
+#define SD25G_LANE_CMU_09_CFG_EN_DUMMY_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_09_CFG_EN_DUMMY, x)
+
+#define SD25G_LANE_CMU_09_CFG_PLL_LOS_SET BIT(2)
+#define SD25G_LANE_CMU_09_CFG_PLL_LOS_SET_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_09_CFG_PLL_LOS_SET, x)
+#define SD25G_LANE_CMU_09_CFG_PLL_LOS_SET_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_09_CFG_PLL_LOS_SET, x)
+
+#define SD25G_LANE_CMU_09_CFG_CTRL_LOGIC_PD BIT(3)
+#define SD25G_LANE_CMU_09_CFG_CTRL_LOGIC_PD_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_09_CFG_CTRL_LOGIC_PD, x)
+#define SD25G_LANE_CMU_09_CFG_CTRL_LOGIC_PD_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_09_CFG_CTRL_LOGIC_PD, x)
+
+#define SD25G_LANE_CMU_09_CFG_PLL_TP_SEL_1_0 GENMASK(5, 4)
+#define SD25G_LANE_CMU_09_CFG_PLL_TP_SEL_1_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_09_CFG_PLL_TP_SEL_1_0, x)
+#define SD25G_LANE_CMU_09_CFG_PLL_TP_SEL_1_0_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_09_CFG_PLL_TP_SEL_1_0, x)
+
+/* SD25G_TARGET:CMU_GRP_0:CMU_0B */
+#define SD25G_LANE_CMU_0B(t) __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 44, 0, 1, 4)
+
+#define SD25G_LANE_CMU_0B_CFG_FORCE_RX_FILT BIT(0)
+#define SD25G_LANE_CMU_0B_CFG_FORCE_RX_FILT_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_0B_CFG_FORCE_RX_FILT, x)
+#define SD25G_LANE_CMU_0B_CFG_FORCE_RX_FILT_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_0B_CFG_FORCE_RX_FILT, x)
+
+#define SD25G_LANE_CMU_0B_CFG_DISLOL BIT(1)
+#define SD25G_LANE_CMU_0B_CFG_DISLOL_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_0B_CFG_DISLOL, x)
+#define SD25G_LANE_CMU_0B_CFG_DISLOL_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_0B_CFG_DISLOL, x)
+
+#define SD25G_LANE_CMU_0B_CFG_RST_TREE_PD_MAN_EN BIT(2)
+#define SD25G_LANE_CMU_0B_CFG_RST_TREE_PD_MAN_EN_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_0B_CFG_RST_TREE_PD_MAN_EN, x)
+#define SD25G_LANE_CMU_0B_CFG_RST_TREE_PD_MAN_EN_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_0B_CFG_RST_TREE_PD_MAN_EN, x)
+
+#define SD25G_LANE_CMU_0B_CFG_VCO_CAL_RESETN BIT(3)
+#define SD25G_LANE_CMU_0B_CFG_VCO_CAL_RESETN_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_0B_CFG_VCO_CAL_RESETN, x)
+#define SD25G_LANE_CMU_0B_CFG_VCO_CAL_RESETN_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_0B_CFG_VCO_CAL_RESETN, x)
+
+#define SD25G_LANE_CMU_0B_CFG_VFILT2PAD BIT(4)
+#define SD25G_LANE_CMU_0B_CFG_VFILT2PAD_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_0B_CFG_VFILT2PAD, x)
+#define SD25G_LANE_CMU_0B_CFG_VFILT2PAD_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_0B_CFG_VFILT2PAD, x)
+
+#define SD25G_LANE_CMU_0B_CFG_DISLOS BIT(5)
+#define SD25G_LANE_CMU_0B_CFG_DISLOS_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_0B_CFG_DISLOS, x)
+#define SD25G_LANE_CMU_0B_CFG_DISLOS_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_0B_CFG_DISLOS, x)
+
+#define SD25G_LANE_CMU_0B_CFG_DCLOL BIT(6)
+#define SD25G_LANE_CMU_0B_CFG_DCLOL_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_0B_CFG_DCLOL, x)
+#define SD25G_LANE_CMU_0B_CFG_DCLOL_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_0B_CFG_DCLOL, x)
+
+#define SD25G_LANE_CMU_0B_CFG_RST_TREE_PD_MAN BIT(7)
+#define SD25G_LANE_CMU_0B_CFG_RST_TREE_PD_MAN_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_0B_CFG_RST_TREE_PD_MAN, x)
+#define SD25G_LANE_CMU_0B_CFG_RST_TREE_PD_MAN_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_0B_CFG_RST_TREE_PD_MAN, x)
+
+/* SD25G_TARGET:CMU_GRP_0:CMU_0C */
+#define SD25G_LANE_CMU_0C(t) __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 48, 0, 1, 4)
+
+#define SD25G_LANE_CMU_0C_CFG_PLL_LOL_SET BIT(0)
+#define SD25G_LANE_CMU_0C_CFG_PLL_LOL_SET_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_0C_CFG_PLL_LOL_SET, x)
+#define SD25G_LANE_CMU_0C_CFG_PLL_LOL_SET_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_0C_CFG_PLL_LOL_SET, x)
+
+#define SD25G_LANE_CMU_0C_CFG_EN_TX_CK_DN BIT(1)
+#define SD25G_LANE_CMU_0C_CFG_EN_TX_CK_DN_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_0C_CFG_EN_TX_CK_DN, x)
+#define SD25G_LANE_CMU_0C_CFG_EN_TX_CK_DN_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_0C_CFG_EN_TX_CK_DN, x)
+
+#define SD25G_LANE_CMU_0C_CFG_VCO_PD BIT(2)
+#define SD25G_LANE_CMU_0C_CFG_VCO_PD_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_0C_CFG_VCO_PD, x)
+#define SD25G_LANE_CMU_0C_CFG_VCO_PD_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_0C_CFG_VCO_PD, x)
+
+#define SD25G_LANE_CMU_0C_CFG_EN_TX_CK_UP BIT(3)
+#define SD25G_LANE_CMU_0C_CFG_EN_TX_CK_UP_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_0C_CFG_EN_TX_CK_UP, x)
+#define SD25G_LANE_CMU_0C_CFG_EN_TX_CK_UP_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_0C_CFG_EN_TX_CK_UP, x)
+
+#define SD25G_LANE_CMU_0C_CFG_VCO_DIV_MODE_1_0 GENMASK(5, 4)
+#define SD25G_LANE_CMU_0C_CFG_VCO_DIV_MODE_1_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_0C_CFG_VCO_DIV_MODE_1_0, x)
+#define SD25G_LANE_CMU_0C_CFG_VCO_DIV_MODE_1_0_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_0C_CFG_VCO_DIV_MODE_1_0, x)
+
+/* SD25G_TARGET:CMU_GRP_0:CMU_0D */
+#define SD25G_LANE_CMU_0D(t) __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 52, 0, 1, 4)
+
+#define SD25G_LANE_CMU_0D_CFG_CK_TREE_PD BIT(0)
+#define SD25G_LANE_CMU_0D_CFG_CK_TREE_PD_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_0D_CFG_CK_TREE_PD, x)
+#define SD25G_LANE_CMU_0D_CFG_CK_TREE_PD_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_0D_CFG_CK_TREE_PD, x)
+
+#define SD25G_LANE_CMU_0D_CFG_EN_RX_CK_DN BIT(1)
+#define SD25G_LANE_CMU_0D_CFG_EN_RX_CK_DN_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_0D_CFG_EN_RX_CK_DN, x)
+#define SD25G_LANE_CMU_0D_CFG_EN_RX_CK_DN_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_0D_CFG_EN_RX_CK_DN, x)
+
+#define SD25G_LANE_CMU_0D_CFG_EN_RX_CK_UP BIT(2)
+#define SD25G_LANE_CMU_0D_CFG_EN_RX_CK_UP_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_0D_CFG_EN_RX_CK_UP, x)
+#define SD25G_LANE_CMU_0D_CFG_EN_RX_CK_UP_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_0D_CFG_EN_RX_CK_UP, x)
+
+#define SD25G_LANE_CMU_0D_CFG_VCO_CAL_BYP BIT(3)
+#define SD25G_LANE_CMU_0D_CFG_VCO_CAL_BYP_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_0D_CFG_VCO_CAL_BYP, x)
+#define SD25G_LANE_CMU_0D_CFG_VCO_CAL_BYP_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_0D_CFG_VCO_CAL_BYP, x)
+
+#define SD25G_LANE_CMU_0D_CFG_PRE_DIVSEL_1_0 GENMASK(5, 4)
+#define SD25G_LANE_CMU_0D_CFG_PRE_DIVSEL_1_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_0D_CFG_PRE_DIVSEL_1_0, x)
+#define SD25G_LANE_CMU_0D_CFG_PRE_DIVSEL_1_0_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_0D_CFG_PRE_DIVSEL_1_0, x)
+
+/* SD25G_TARGET:CMU_GRP_0:CMU_0E */
+#define SD25G_LANE_CMU_0E(t) __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 56, 0, 1, 4)
+
+#define SD25G_LANE_CMU_0E_CFG_SEL_DIV_3_0 GENMASK(3, 0)
+#define SD25G_LANE_CMU_0E_CFG_SEL_DIV_3_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_0E_CFG_SEL_DIV_3_0, x)
+#define SD25G_LANE_CMU_0E_CFG_SEL_DIV_3_0_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_0E_CFG_SEL_DIV_3_0, x)
+
+#define SD25G_LANE_CMU_0E_CFG_PMAA_CENTR_CK_PD BIT(4)
+#define SD25G_LANE_CMU_0E_CFG_PMAA_CENTR_CK_PD_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_0E_CFG_PMAA_CENTR_CK_PD, x)
+#define SD25G_LANE_CMU_0E_CFG_PMAA_CENTR_CK_PD_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_0E_CFG_PMAA_CENTR_CK_PD, x)
+
+/* SD25G_TARGET:CMU_GRP_0:CMU_13 */
+#define SD25G_LANE_CMU_13(t) __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 76, 0, 1, 4)
+
+#define SD25G_LANE_CMU_13_CFG_PLL_RESERVE_3_0 GENMASK(3, 0)
+#define SD25G_LANE_CMU_13_CFG_PLL_RESERVE_3_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_13_CFG_PLL_RESERVE_3_0, x)
+#define SD25G_LANE_CMU_13_CFG_PLL_RESERVE_3_0_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_13_CFG_PLL_RESERVE_3_0, x)
+
+#define SD25G_LANE_CMU_13_CFG_JT_EN BIT(4)
+#define SD25G_LANE_CMU_13_CFG_JT_EN_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_13_CFG_JT_EN, x)
+#define SD25G_LANE_CMU_13_CFG_JT_EN_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_13_CFG_JT_EN, x)
+
+/* SD25G_TARGET:CMU_GRP_0:CMU_18 */
+#define SD25G_LANE_CMU_18(t) __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 96, 0, 1, 4)
+
+#define SD25G_LANE_CMU_18_R_PLL_RSTN BIT(0)
+#define SD25G_LANE_CMU_18_R_PLL_RSTN_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_18_R_PLL_RSTN, x)
+#define SD25G_LANE_CMU_18_R_PLL_RSTN_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_18_R_PLL_RSTN, x)
+
+#define SD25G_LANE_CMU_18_R_PLL_LOL_SET BIT(1)
+#define SD25G_LANE_CMU_18_R_PLL_LOL_SET_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_18_R_PLL_LOL_SET, x)
+#define SD25G_LANE_CMU_18_R_PLL_LOL_SET_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_18_R_PLL_LOL_SET, x)
+
+#define SD25G_LANE_CMU_18_R_PLL_LOS_SET BIT(2)
+#define SD25G_LANE_CMU_18_R_PLL_LOS_SET_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_18_R_PLL_LOS_SET, x)
+#define SD25G_LANE_CMU_18_R_PLL_LOS_SET_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_18_R_PLL_LOS_SET, x)
+
+#define SD25G_LANE_CMU_18_R_PLL_TP_SEL_1_0 GENMASK(5, 4)
+#define SD25G_LANE_CMU_18_R_PLL_TP_SEL_1_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_18_R_PLL_TP_SEL_1_0, x)
+#define SD25G_LANE_CMU_18_R_PLL_TP_SEL_1_0_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_18_R_PLL_TP_SEL_1_0, x)
+
+/* SD25G_TARGET:CMU_GRP_0:CMU_19 */
+#define SD25G_LANE_CMU_19(t) __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 100, 0, 1, 4)
+
+#define SD25G_LANE_CMU_19_R_CK_RESETB BIT(0)
+#define SD25G_LANE_CMU_19_R_CK_RESETB_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_19_R_CK_RESETB, x)
+#define SD25G_LANE_CMU_19_R_CK_RESETB_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_19_R_CK_RESETB, x)
+
+#define SD25G_LANE_CMU_19_R_PLL_DLOL_EN BIT(1)
+#define SD25G_LANE_CMU_19_R_PLL_DLOL_EN_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_19_R_PLL_DLOL_EN, x)
+#define SD25G_LANE_CMU_19_R_PLL_DLOL_EN_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_19_R_PLL_DLOL_EN, x)
+
+/* SD25G_TARGET:CMU_GRP_0:CMU_1A */
+#define SD25G_LANE_CMU_1A(t) __REG(TARGET_SD25G_LANE, t, 8, 0, 0, 1, 132, 104, 0, 1, 4)
+
+#define SD25G_LANE_CMU_1A_R_DWIDTHCTRL_2_0 GENMASK(2, 0)
+#define SD25G_LANE_CMU_1A_R_DWIDTHCTRL_2_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_1A_R_DWIDTHCTRL_2_0, x)
+#define SD25G_LANE_CMU_1A_R_DWIDTHCTRL_2_0_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_1A_R_DWIDTHCTRL_2_0, x)
+
+#define SD25G_LANE_CMU_1A_R_DWIDTHCTRL_FROM_HWT BIT(4)
+#define SD25G_LANE_CMU_1A_R_DWIDTHCTRL_FROM_HWT_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_1A_R_DWIDTHCTRL_FROM_HWT, x)
+#define SD25G_LANE_CMU_1A_R_DWIDTHCTRL_FROM_HWT_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_1A_R_DWIDTHCTRL_FROM_HWT, x)
+
+#define SD25G_LANE_CMU_1A_R_MASK_EI_SOURCE BIT(5)
+#define SD25G_LANE_CMU_1A_R_MASK_EI_SOURCE_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_1A_R_MASK_EI_SOURCE, x)
+#define SD25G_LANE_CMU_1A_R_MASK_EI_SOURCE_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_1A_R_MASK_EI_SOURCE, x)
+
+#define SD25G_LANE_CMU_1A_R_REG_MANUAL BIT(6)
+#define SD25G_LANE_CMU_1A_R_REG_MANUAL_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_1A_R_REG_MANUAL, x)
+#define SD25G_LANE_CMU_1A_R_REG_MANUAL_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_1A_R_REG_MANUAL, x)
+
+/* SD25G_TARGET:CMU_GRP_1:CMU_2A */
+#define SD25G_LANE_CMU_2A(t) __REG(TARGET_SD25G_LANE, t, 8, 132, 0, 1, 124, 36, 0, 1, 4)
+
+#define SD25G_LANE_CMU_2A_R_DBG_SEL_1_0 GENMASK(1, 0)
+#define SD25G_LANE_CMU_2A_R_DBG_SEL_1_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_2A_R_DBG_SEL_1_0, x)
+#define SD25G_LANE_CMU_2A_R_DBG_SEL_1_0_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_2A_R_DBG_SEL_1_0, x)
+
+#define SD25G_LANE_CMU_2A_R_DBG_LINK_LANE BIT(4)
+#define SD25G_LANE_CMU_2A_R_DBG_LINK_LANE_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_2A_R_DBG_LINK_LANE, x)
+#define SD25G_LANE_CMU_2A_R_DBG_LINK_LANE_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_2A_R_DBG_LINK_LANE, x)
+
+#define SD25G_LANE_CMU_2A_R_DBG_LOL_STATUS BIT(5)
+#define SD25G_LANE_CMU_2A_R_DBG_LOL_STATUS_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_2A_R_DBG_LOL_STATUS, x)
+#define SD25G_LANE_CMU_2A_R_DBG_LOL_STATUS_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_2A_R_DBG_LOL_STATUS, x)
+
+/* SD25G_TARGET:CMU_GRP_1:CMU_30 */
+#define SD25G_LANE_CMU_30(t) __REG(TARGET_SD25G_LANE, t, 8, 132, 0, 1, 124, 60, 0, 1, 4)
+
+#define SD25G_LANE_CMU_30_R_TXFIFO_CK_DIV_PMAD_2_0 GENMASK(2, 0)
+#define SD25G_LANE_CMU_30_R_TXFIFO_CK_DIV_PMAD_2_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_30_R_TXFIFO_CK_DIV_PMAD_2_0, x)
+#define SD25G_LANE_CMU_30_R_TXFIFO_CK_DIV_PMAD_2_0_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_30_R_TXFIFO_CK_DIV_PMAD_2_0, x)
+
+#define SD25G_LANE_CMU_30_R_RXFIFO_CK_DIV_PMAD_2_0 GENMASK(6, 4)
+#define SD25G_LANE_CMU_30_R_RXFIFO_CK_DIV_PMAD_2_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_30_R_RXFIFO_CK_DIV_PMAD_2_0, x)
+#define SD25G_LANE_CMU_30_R_RXFIFO_CK_DIV_PMAD_2_0_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_30_R_RXFIFO_CK_DIV_PMAD_2_0, x)
+
+/* SD25G_TARGET:CMU_GRP_1:CMU_31 */
+#define SD25G_LANE_CMU_31(t) __REG(TARGET_SD25G_LANE, t, 8, 132, 0, 1, 124, 64, 0, 1, 4)
+
+#define SD25G_LANE_CMU_31_CFG_COMMON_RESERVE_7_0 GENMASK(7, 0)
+#define SD25G_LANE_CMU_31_CFG_COMMON_RESERVE_7_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_31_CFG_COMMON_RESERVE_7_0, x)
+#define SD25G_LANE_CMU_31_CFG_COMMON_RESERVE_7_0_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_31_CFG_COMMON_RESERVE_7_0, x)
+
+/* SD25G_TARGET:CMU_GRP_2:CMU_40 */
+#define SD25G_LANE_CMU_40(t) __REG(TARGET_SD25G_LANE, t, 8, 256, 0, 1, 512, 0, 0, 1, 4)
+
+#define SD25G_LANE_CMU_40_L0_CFG_CKSKEW_CTRL BIT(0)
+#define SD25G_LANE_CMU_40_L0_CFG_CKSKEW_CTRL_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_40_L0_CFG_CKSKEW_CTRL, x)
+#define SD25G_LANE_CMU_40_L0_CFG_CKSKEW_CTRL_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_40_L0_CFG_CKSKEW_CTRL, x)
+
+#define SD25G_LANE_CMU_40_L0_CFG_ISCAN_HOLD BIT(1)
+#define SD25G_LANE_CMU_40_L0_CFG_ISCAN_HOLD_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_40_L0_CFG_ISCAN_HOLD, x)
+#define SD25G_LANE_CMU_40_L0_CFG_ISCAN_HOLD_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_40_L0_CFG_ISCAN_HOLD, x)
+
+#define SD25G_LANE_CMU_40_L0_CFG_PD_CLK BIT(2)
+#define SD25G_LANE_CMU_40_L0_CFG_PD_CLK_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_40_L0_CFG_PD_CLK, x)
+#define SD25G_LANE_CMU_40_L0_CFG_PD_CLK_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_40_L0_CFG_PD_CLK, x)
+
+#define SD25G_LANE_CMU_40_L0_CFG_TXCAL_EN BIT(3)
+#define SD25G_LANE_CMU_40_L0_CFG_TXCAL_EN_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_40_L0_CFG_TXCAL_EN, x)
+#define SD25G_LANE_CMU_40_L0_CFG_TXCAL_EN_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_40_L0_CFG_TXCAL_EN, x)
+
+#define SD25G_LANE_CMU_40_L0_CFG_TXCAL_MAN_EN BIT(4)
+#define SD25G_LANE_CMU_40_L0_CFG_TXCAL_MAN_EN_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_40_L0_CFG_TXCAL_MAN_EN, x)
+#define SD25G_LANE_CMU_40_L0_CFG_TXCAL_MAN_EN_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_40_L0_CFG_TXCAL_MAN_EN, x)
+
+#define SD25G_LANE_CMU_40_L0_CFG_TXCAL_RST BIT(5)
+#define SD25G_LANE_CMU_40_L0_CFG_TXCAL_RST_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_40_L0_CFG_TXCAL_RST, x)
+#define SD25G_LANE_CMU_40_L0_CFG_TXCAL_RST_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_40_L0_CFG_TXCAL_RST, x)
+
+/* SD25G_TARGET:CMU_GRP_2:CMU_45 */
+#define SD25G_LANE_CMU_45(t) __REG(TARGET_SD25G_LANE, t, 8, 256, 0, 1, 512, 20, 0, 1, 4)
+
+#define SD25G_LANE_CMU_45_L0_CFG_TX_RESERVE_7_0 GENMASK(7, 0)
+#define SD25G_LANE_CMU_45_L0_CFG_TX_RESERVE_7_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_45_L0_CFG_TX_RESERVE_7_0, x)
+#define SD25G_LANE_CMU_45_L0_CFG_TX_RESERVE_7_0_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_45_L0_CFG_TX_RESERVE_7_0, x)
+
+/* SD25G_TARGET:CMU_GRP_2:CMU_46 */
+#define SD25G_LANE_CMU_46(t) __REG(TARGET_SD25G_LANE, t, 8, 256, 0, 1, 512, 24, 0, 1, 4)
+
+#define SD25G_LANE_CMU_46_L0_CFG_TX_RESERVE_15_8 GENMASK(7, 0)
+#define SD25G_LANE_CMU_46_L0_CFG_TX_RESERVE_15_8_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_46_L0_CFG_TX_RESERVE_15_8, x)
+#define SD25G_LANE_CMU_46_L0_CFG_TX_RESERVE_15_8_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_46_L0_CFG_TX_RESERVE_15_8, x)
+
+/* SD25G_TARGET:CMU_GRP_3:CMU_C0 */
+#define SD25G_LANE_CMU_C0(t) __REG(TARGET_SD25G_LANE, t, 8, 768, 0, 1, 252, 0, 0, 1, 4)
+
+#define SD25G_LANE_CMU_C0_READ_VCO_CTUNE_3_0 GENMASK(3, 0)
+#define SD25G_LANE_CMU_C0_READ_VCO_CTUNE_3_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_C0_READ_VCO_CTUNE_3_0, x)
+#define SD25G_LANE_CMU_C0_READ_VCO_CTUNE_3_0_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_C0_READ_VCO_CTUNE_3_0, x)
+
+#define SD25G_LANE_CMU_C0_PLL_LOL_UDL BIT(4)
+#define SD25G_LANE_CMU_C0_PLL_LOL_UDL_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_C0_PLL_LOL_UDL, x)
+#define SD25G_LANE_CMU_C0_PLL_LOL_UDL_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_C0_PLL_LOL_UDL, x)
+
+/* SD25G_TARGET:CMU_GRP_4:CMU_FF */
+#define SD25G_LANE_CMU_FF(t) __REG(TARGET_SD25G_LANE, t, 8, 1020, 0, 1, 4, 0, 0, 1, 4)
+
+#define SD25G_LANE_CMU_FF_REGISTER_TABLE_INDEX GENMASK(7, 0)
+#define SD25G_LANE_CMU_FF_REGISTER_TABLE_INDEX_SET(x)\
+ FIELD_PREP(SD25G_LANE_CMU_FF_REGISTER_TABLE_INDEX, x)
+#define SD25G_LANE_CMU_FF_REGISTER_TABLE_INDEX_GET(x)\
+ FIELD_GET(SD25G_LANE_CMU_FF_REGISTER_TABLE_INDEX, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_00 */
+#define SD25G_LANE_LANE_00(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 0, 0, 1, 4)
+
+#define SD25G_LANE_LANE_00_LN_CFG_ITX_VC_DRIVER_3_0 GENMASK(3, 0)
+#define SD25G_LANE_LANE_00_LN_CFG_ITX_VC_DRIVER_3_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_00_LN_CFG_ITX_VC_DRIVER_3_0, x)
+#define SD25G_LANE_LANE_00_LN_CFG_ITX_VC_DRIVER_3_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_00_LN_CFG_ITX_VC_DRIVER_3_0, x)
+
+#define SD25G_LANE_LANE_00_LN_CFG_ITX_IPCML_BASE_1_0 GENMASK(5, 4)
+#define SD25G_LANE_LANE_00_LN_CFG_ITX_IPCML_BASE_1_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_00_LN_CFG_ITX_IPCML_BASE_1_0, x)
+#define SD25G_LANE_LANE_00_LN_CFG_ITX_IPCML_BASE_1_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_00_LN_CFG_ITX_IPCML_BASE_1_0, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_01 */
+#define SD25G_LANE_LANE_01(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 4, 0, 1, 4)
+
+#define SD25G_LANE_LANE_01_LN_CFG_ITX_IPDRIVER_BASE_2_0 GENMASK(2, 0)
+#define SD25G_LANE_LANE_01_LN_CFG_ITX_IPDRIVER_BASE_2_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_01_LN_CFG_ITX_IPDRIVER_BASE_2_0, x)
+#define SD25G_LANE_LANE_01_LN_CFG_ITX_IPDRIVER_BASE_2_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_01_LN_CFG_ITX_IPDRIVER_BASE_2_0, x)
+
+#define SD25G_LANE_LANE_01_LN_CFG_TX_PREDIV_1_0 GENMASK(5, 4)
+#define SD25G_LANE_LANE_01_LN_CFG_TX_PREDIV_1_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_01_LN_CFG_TX_PREDIV_1_0, x)
+#define SD25G_LANE_LANE_01_LN_CFG_TX_PREDIV_1_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_01_LN_CFG_TX_PREDIV_1_0, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_03 */
+#define SD25G_LANE_LANE_03(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 12, 0, 1, 4)
+
+#define SD25G_LANE_LANE_03_LN_CFG_TAP_DLY_4_0 GENMASK(4, 0)
+#define SD25G_LANE_LANE_03_LN_CFG_TAP_DLY_4_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_03_LN_CFG_TAP_DLY_4_0, x)
+#define SD25G_LANE_LANE_03_LN_CFG_TAP_DLY_4_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_03_LN_CFG_TAP_DLY_4_0, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_04 */
+#define SD25G_LANE_LANE_04(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 16, 0, 1, 4)
+
+#define SD25G_LANE_LANE_04_LN_CFG_TX2RX_LP_EN BIT(0)
+#define SD25G_LANE_LANE_04_LN_CFG_TX2RX_LP_EN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_04_LN_CFG_TX2RX_LP_EN, x)
+#define SD25G_LANE_LANE_04_LN_CFG_TX2RX_LP_EN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_04_LN_CFG_TX2RX_LP_EN, x)
+
+#define SD25G_LANE_LANE_04_LN_CFG_RX2TX_LP_EN BIT(1)
+#define SD25G_LANE_LANE_04_LN_CFG_RX2TX_LP_EN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_04_LN_CFG_RX2TX_LP_EN, x)
+#define SD25G_LANE_LANE_04_LN_CFG_RX2TX_LP_EN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_04_LN_CFG_RX2TX_LP_EN, x)
+
+#define SD25G_LANE_LANE_04_LN_CFG_PD_CML BIT(2)
+#define SD25G_LANE_LANE_04_LN_CFG_PD_CML_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_04_LN_CFG_PD_CML, x)
+#define SD25G_LANE_LANE_04_LN_CFG_PD_CML_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_04_LN_CFG_PD_CML, x)
+
+#define SD25G_LANE_LANE_04_LN_CFG_PD_CLK BIT(3)
+#define SD25G_LANE_LANE_04_LN_CFG_PD_CLK_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_04_LN_CFG_PD_CLK, x)
+#define SD25G_LANE_LANE_04_LN_CFG_PD_CLK_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_04_LN_CFG_PD_CLK, x)
+
+#define SD25G_LANE_LANE_04_LN_CFG_PD_DRIVER BIT(4)
+#define SD25G_LANE_LANE_04_LN_CFG_PD_DRIVER_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_04_LN_CFG_PD_DRIVER, x)
+#define SD25G_LANE_LANE_04_LN_CFG_PD_DRIVER_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_04_LN_CFG_PD_DRIVER, x)
+
+#define SD25G_LANE_LANE_04_LN_CFG_TAP_MAIN BIT(5)
+#define SD25G_LANE_LANE_04_LN_CFG_TAP_MAIN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_04_LN_CFG_TAP_MAIN, x)
+#define SD25G_LANE_LANE_04_LN_CFG_TAP_MAIN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_04_LN_CFG_TAP_MAIN, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_05 */
+#define SD25G_LANE_LANE_05(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 20, 0, 1, 4)
+
+#define SD25G_LANE_LANE_05_LN_CFG_TAP_DLY2_3_0 GENMASK(3, 0)
+#define SD25G_LANE_LANE_05_LN_CFG_TAP_DLY2_3_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_05_LN_CFG_TAP_DLY2_3_0, x)
+#define SD25G_LANE_LANE_05_LN_CFG_TAP_DLY2_3_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_05_LN_CFG_TAP_DLY2_3_0, x)
+
+#define SD25G_LANE_LANE_05_LN_CFG_BW_1_0 GENMASK(5, 4)
+#define SD25G_LANE_LANE_05_LN_CFG_BW_1_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_05_LN_CFG_BW_1_0, x)
+#define SD25G_LANE_LANE_05_LN_CFG_BW_1_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_05_LN_CFG_BW_1_0, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_06 */
+#define SD25G_LANE_LANE_06(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 24, 0, 1, 4)
+
+#define SD25G_LANE_LANE_06_LN_CFG_EN_MAIN BIT(0)
+#define SD25G_LANE_LANE_06_LN_CFG_EN_MAIN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_06_LN_CFG_EN_MAIN, x)
+#define SD25G_LANE_LANE_06_LN_CFG_EN_MAIN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_06_LN_CFG_EN_MAIN, x)
+
+#define SD25G_LANE_LANE_06_LN_CFG_TAP_ADV_3_0 GENMASK(7, 4)
+#define SD25G_LANE_LANE_06_LN_CFG_TAP_ADV_3_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_06_LN_CFG_TAP_ADV_3_0, x)
+#define SD25G_LANE_LANE_06_LN_CFG_TAP_ADV_3_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_06_LN_CFG_TAP_ADV_3_0, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_07 */
+#define SD25G_LANE_LANE_07(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 28, 0, 1, 4)
+
+#define SD25G_LANE_LANE_07_LN_CFG_EN_ADV BIT(0)
+#define SD25G_LANE_LANE_07_LN_CFG_EN_ADV_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_07_LN_CFG_EN_ADV, x)
+#define SD25G_LANE_LANE_07_LN_CFG_EN_ADV_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_07_LN_CFG_EN_ADV, x)
+
+#define SD25G_LANE_LANE_07_LN_CFG_EN_DLY2 BIT(1)
+#define SD25G_LANE_LANE_07_LN_CFG_EN_DLY2_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_07_LN_CFG_EN_DLY2, x)
+#define SD25G_LANE_LANE_07_LN_CFG_EN_DLY2_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_07_LN_CFG_EN_DLY2, x)
+
+#define SD25G_LANE_LANE_07_LN_CFG_EN_DLY BIT(2)
+#define SD25G_LANE_LANE_07_LN_CFG_EN_DLY_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_07_LN_CFG_EN_DLY, x)
+#define SD25G_LANE_LANE_07_LN_CFG_EN_DLY_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_07_LN_CFG_EN_DLY, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_09 */
+#define SD25G_LANE_LANE_09(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 36, 0, 1, 4)
+
+#define SD25G_LANE_LANE_09_LN_CFG_TXCAL_VALID_SEL_3_0 GENMASK(3, 0)
+#define SD25G_LANE_LANE_09_LN_CFG_TXCAL_VALID_SEL_3_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_09_LN_CFG_TXCAL_VALID_SEL_3_0, x)
+#define SD25G_LANE_LANE_09_LN_CFG_TXCAL_VALID_SEL_3_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_09_LN_CFG_TXCAL_VALID_SEL_3_0, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_0A */
+#define SD25G_LANE_LANE_0A(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 40, 0, 1, 4)
+
+#define SD25G_LANE_LANE_0A_LN_CFG_TXCAL_SHIFT_CODE_5_0 GENMASK(5, 0)
+#define SD25G_LANE_LANE_0A_LN_CFG_TXCAL_SHIFT_CODE_5_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_0A_LN_CFG_TXCAL_SHIFT_CODE_5_0, x)
+#define SD25G_LANE_LANE_0A_LN_CFG_TXCAL_SHIFT_CODE_5_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_0A_LN_CFG_TXCAL_SHIFT_CODE_5_0, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_0B */
+#define SD25G_LANE_LANE_0B(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 44, 0, 1, 4)
+
+#define SD25G_LANE_LANE_0B_LN_CFG_TXCAL_MAN_EN BIT(0)
+#define SD25G_LANE_LANE_0B_LN_CFG_TXCAL_MAN_EN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_0B_LN_CFG_TXCAL_MAN_EN, x)
+#define SD25G_LANE_LANE_0B_LN_CFG_TXCAL_MAN_EN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_0B_LN_CFG_TXCAL_MAN_EN, x)
+
+#define SD25G_LANE_LANE_0B_LN_CFG_TXCAL_RST BIT(1)
+#define SD25G_LANE_LANE_0B_LN_CFG_TXCAL_RST_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_0B_LN_CFG_TXCAL_RST, x)
+#define SD25G_LANE_LANE_0B_LN_CFG_TXCAL_RST_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_0B_LN_CFG_TXCAL_RST, x)
+
+#define SD25G_LANE_LANE_0B_LN_CFG_QUAD_MAN_1_0 GENMASK(5, 4)
+#define SD25G_LANE_LANE_0B_LN_CFG_QUAD_MAN_1_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_0B_LN_CFG_QUAD_MAN_1_0, x)
+#define SD25G_LANE_LANE_0B_LN_CFG_QUAD_MAN_1_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_0B_LN_CFG_QUAD_MAN_1_0, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_0C */
+#define SD25G_LANE_LANE_0C(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 48, 0, 1, 4)
+
+#define SD25G_LANE_LANE_0C_LN_CFG_PMA_TX_CK_BITWIDTH_2_0 GENMASK(2, 0)
+#define SD25G_LANE_LANE_0C_LN_CFG_PMA_TX_CK_BITWIDTH_2_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_0C_LN_CFG_PMA_TX_CK_BITWIDTH_2_0, x)
+#define SD25G_LANE_LANE_0C_LN_CFG_PMA_TX_CK_BITWIDTH_2_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_0C_LN_CFG_PMA_TX_CK_BITWIDTH_2_0, x)
+
+#define SD25G_LANE_LANE_0C_LN_CFG_TXCAL_EN BIT(4)
+#define SD25G_LANE_LANE_0C_LN_CFG_TXCAL_EN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_0C_LN_CFG_TXCAL_EN, x)
+#define SD25G_LANE_LANE_0C_LN_CFG_TXCAL_EN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_0C_LN_CFG_TXCAL_EN, x)
+
+#define SD25G_LANE_LANE_0C_LN_CFG_RXTERM_PD BIT(5)
+#define SD25G_LANE_LANE_0C_LN_CFG_RXTERM_PD_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_0C_LN_CFG_RXTERM_PD, x)
+#define SD25G_LANE_LANE_0C_LN_CFG_RXTERM_PD_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_0C_LN_CFG_RXTERM_PD, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_0D */
+#define SD25G_LANE_LANE_0D(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 52, 0, 1, 4)
+
+#define SD25G_LANE_LANE_0D_LN_CFG_RXTERM_2_0 GENMASK(2, 0)
+#define SD25G_LANE_LANE_0D_LN_CFG_RXTERM_2_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_0D_LN_CFG_RXTERM_2_0, x)
+#define SD25G_LANE_LANE_0D_LN_CFG_RXTERM_2_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_0D_LN_CFG_RXTERM_2_0, x)
+
+#define SD25G_LANE_LANE_0D_LN_CFG_RSTN_DIV5_8 BIT(4)
+#define SD25G_LANE_LANE_0D_LN_CFG_RSTN_DIV5_8_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_0D_LN_CFG_RSTN_DIV5_8, x)
+#define SD25G_LANE_LANE_0D_LN_CFG_RSTN_DIV5_8_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_0D_LN_CFG_RSTN_DIV5_8, x)
+
+#define SD25G_LANE_LANE_0D_LN_CFG_SUMMER_EN BIT(5)
+#define SD25G_LANE_LANE_0D_LN_CFG_SUMMER_EN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_0D_LN_CFG_SUMMER_EN, x)
+#define SD25G_LANE_LANE_0D_LN_CFG_SUMMER_EN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_0D_LN_CFG_SUMMER_EN, x)
+
+#define SD25G_LANE_LANE_0D_LN_CFG_DMUX_PD BIT(6)
+#define SD25G_LANE_LANE_0D_LN_CFG_DMUX_PD_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_0D_LN_CFG_DMUX_PD, x)
+#define SD25G_LANE_LANE_0D_LN_CFG_DMUX_PD_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_0D_LN_CFG_DMUX_PD, x)
+
+#define SD25G_LANE_LANE_0D_LN_CFG_DFECK_EN BIT(7)
+#define SD25G_LANE_LANE_0D_LN_CFG_DFECK_EN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_0D_LN_CFG_DFECK_EN, x)
+#define SD25G_LANE_LANE_0D_LN_CFG_DFECK_EN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_0D_LN_CFG_DFECK_EN, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_0E */
+#define SD25G_LANE_LANE_0E(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 56, 0, 1, 4)
+
+#define SD25G_LANE_LANE_0E_LN_CFG_ISCAN_EN BIT(0)
+#define SD25G_LANE_LANE_0E_LN_CFG_ISCAN_EN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_0E_LN_CFG_ISCAN_EN, x)
+#define SD25G_LANE_LANE_0E_LN_CFG_ISCAN_EN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_0E_LN_CFG_ISCAN_EN, x)
+
+#define SD25G_LANE_LANE_0E_LN_CFG_DMUX_CLK_PD BIT(1)
+#define SD25G_LANE_LANE_0E_LN_CFG_DMUX_CLK_PD_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_0E_LN_CFG_DMUX_CLK_PD, x)
+#define SD25G_LANE_LANE_0E_LN_CFG_DMUX_CLK_PD_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_0E_LN_CFG_DMUX_CLK_PD, x)
+
+#define SD25G_LANE_LANE_0E_LN_CFG_EN_DFEDIG BIT(2)
+#define SD25G_LANE_LANE_0E_LN_CFG_EN_DFEDIG_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_0E_LN_CFG_EN_DFEDIG, x)
+#define SD25G_LANE_LANE_0E_LN_CFG_EN_DFEDIG_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_0E_LN_CFG_EN_DFEDIG, x)
+
+#define SD25G_LANE_LANE_0E_LN_CFG_DFEDIG_M_2_0 GENMASK(6, 4)
+#define SD25G_LANE_LANE_0E_LN_CFG_DFEDIG_M_2_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_0E_LN_CFG_DFEDIG_M_2_0, x)
+#define SD25G_LANE_LANE_0E_LN_CFG_DFEDIG_M_2_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_0E_LN_CFG_DFEDIG_M_2_0, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_0F */
+#define SD25G_LANE_LANE_0F(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 60, 0, 1, 4)
+
+#define SD25G_LANE_LANE_0F_LN_CFG_DFETAP_EN_5_1 GENMASK(4, 0)
+#define SD25G_LANE_LANE_0F_LN_CFG_DFETAP_EN_5_1_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_0F_LN_CFG_DFETAP_EN_5_1, x)
+#define SD25G_LANE_LANE_0F_LN_CFG_DFETAP_EN_5_1_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_0F_LN_CFG_DFETAP_EN_5_1, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_18 */
+#define SD25G_LANE_LANE_18(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 96, 0, 1, 4)
+
+#define SD25G_LANE_LANE_18_LN_CFG_CDRCK_EN BIT(0)
+#define SD25G_LANE_LANE_18_LN_CFG_CDRCK_EN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_18_LN_CFG_CDRCK_EN, x)
+#define SD25G_LANE_LANE_18_LN_CFG_CDRCK_EN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_18_LN_CFG_CDRCK_EN, x)
+
+#define SD25G_LANE_LANE_18_LN_CFG_ADD_VOLT BIT(1)
+#define SD25G_LANE_LANE_18_LN_CFG_ADD_VOLT_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_18_LN_CFG_ADD_VOLT, x)
+#define SD25G_LANE_LANE_18_LN_CFG_ADD_VOLT_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_18_LN_CFG_ADD_VOLT, x)
+
+#define SD25G_LANE_LANE_18_LN_CFG_MAN_VOLT_EN BIT(2)
+#define SD25G_LANE_LANE_18_LN_CFG_MAN_VOLT_EN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_18_LN_CFG_MAN_VOLT_EN, x)
+#define SD25G_LANE_LANE_18_LN_CFG_MAN_VOLT_EN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_18_LN_CFG_MAN_VOLT_EN, x)
+
+#define SD25G_LANE_LANE_18_LN_CFG_ERRAMP_PD BIT(3)
+#define SD25G_LANE_LANE_18_LN_CFG_ERRAMP_PD_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_18_LN_CFG_ERRAMP_PD, x)
+#define SD25G_LANE_LANE_18_LN_CFG_ERRAMP_PD_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_18_LN_CFG_ERRAMP_PD, x)
+
+#define SD25G_LANE_LANE_18_LN_CFG_RXDIV_SEL_2_0 GENMASK(6, 4)
+#define SD25G_LANE_LANE_18_LN_CFG_RXDIV_SEL_2_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_18_LN_CFG_RXDIV_SEL_2_0, x)
+#define SD25G_LANE_LANE_18_LN_CFG_RXDIV_SEL_2_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_18_LN_CFG_RXDIV_SEL_2_0, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_19 */
+#define SD25G_LANE_LANE_19(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 100, 0, 1, 4)
+
+#define SD25G_LANE_LANE_19_LN_CFG_DCDR_PD BIT(0)
+#define SD25G_LANE_LANE_19_LN_CFG_DCDR_PD_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_19_LN_CFG_DCDR_PD, x)
+#define SD25G_LANE_LANE_19_LN_CFG_DCDR_PD_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_19_LN_CFG_DCDR_PD, x)
+
+#define SD25G_LANE_LANE_19_LN_CFG_ECDR_PD BIT(1)
+#define SD25G_LANE_LANE_19_LN_CFG_ECDR_PD_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_19_LN_CFG_ECDR_PD, x)
+#define SD25G_LANE_LANE_19_LN_CFG_ECDR_PD_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_19_LN_CFG_ECDR_PD, x)
+
+#define SD25G_LANE_LANE_19_LN_CFG_ISCAN_SEL BIT(2)
+#define SD25G_LANE_LANE_19_LN_CFG_ISCAN_SEL_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_19_LN_CFG_ISCAN_SEL, x)
+#define SD25G_LANE_LANE_19_LN_CFG_ISCAN_SEL_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_19_LN_CFG_ISCAN_SEL, x)
+
+#define SD25G_LANE_LANE_19_LN_CFG_TXLB_EN BIT(3)
+#define SD25G_LANE_LANE_19_LN_CFG_TXLB_EN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_19_LN_CFG_TXLB_EN, x)
+#define SD25G_LANE_LANE_19_LN_CFG_TXLB_EN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_19_LN_CFG_TXLB_EN, x)
+
+#define SD25G_LANE_LANE_19_LN_CFG_RX_REG_PU BIT(4)
+#define SD25G_LANE_LANE_19_LN_CFG_RX_REG_PU_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_19_LN_CFG_RX_REG_PU, x)
+#define SD25G_LANE_LANE_19_LN_CFG_RX_REG_PU_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_19_LN_CFG_RX_REG_PU, x)
+
+#define SD25G_LANE_LANE_19_LN_CFG_RX_REG_BYP BIT(5)
+#define SD25G_LANE_LANE_19_LN_CFG_RX_REG_BYP_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_19_LN_CFG_RX_REG_BYP, x)
+#define SD25G_LANE_LANE_19_LN_CFG_RX_REG_BYP_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_19_LN_CFG_RX_REG_BYP, x)
+
+#define SD25G_LANE_LANE_19_LN_CFG_PD_RMS_DET BIT(6)
+#define SD25G_LANE_LANE_19_LN_CFG_PD_RMS_DET_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_19_LN_CFG_PD_RMS_DET, x)
+#define SD25G_LANE_LANE_19_LN_CFG_PD_RMS_DET_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_19_LN_CFG_PD_RMS_DET, x)
+
+#define SD25G_LANE_LANE_19_LN_CFG_PD_CTLE BIT(7)
+#define SD25G_LANE_LANE_19_LN_CFG_PD_CTLE_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_19_LN_CFG_PD_CTLE, x)
+#define SD25G_LANE_LANE_19_LN_CFG_PD_CTLE_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_19_LN_CFG_PD_CTLE, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_1A */
+#define SD25G_LANE_LANE_1A(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 104, 0, 1, 4)
+
+#define SD25G_LANE_LANE_1A_LN_CFG_CTLE_TP_EN BIT(0)
+#define SD25G_LANE_LANE_1A_LN_CFG_CTLE_TP_EN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_1A_LN_CFG_CTLE_TP_EN, x)
+#define SD25G_LANE_LANE_1A_LN_CFG_CTLE_TP_EN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_1A_LN_CFG_CTLE_TP_EN, x)
+
+#define SD25G_LANE_LANE_1A_LN_CFG_CDR_KF_2_0 GENMASK(6, 4)
+#define SD25G_LANE_LANE_1A_LN_CFG_CDR_KF_2_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_1A_LN_CFG_CDR_KF_2_0, x)
+#define SD25G_LANE_LANE_1A_LN_CFG_CDR_KF_2_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_1A_LN_CFG_CDR_KF_2_0, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_1B */
+#define SD25G_LANE_LANE_1B(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 108, 0, 1, 4)
+
+#define SD25G_LANE_LANE_1B_LN_CFG_CDR_M_7_0 GENMASK(7, 0)
+#define SD25G_LANE_LANE_1B_LN_CFG_CDR_M_7_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_1B_LN_CFG_CDR_M_7_0, x)
+#define SD25G_LANE_LANE_1B_LN_CFG_CDR_M_7_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_1B_LN_CFG_CDR_M_7_0, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_1C */
+#define SD25G_LANE_LANE_1C(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 112, 0, 1, 4)
+
+#define SD25G_LANE_LANE_1C_LN_CFG_CDR_RSTN BIT(0)
+#define SD25G_LANE_LANE_1C_LN_CFG_CDR_RSTN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_1C_LN_CFG_CDR_RSTN, x)
+#define SD25G_LANE_LANE_1C_LN_CFG_CDR_RSTN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_1C_LN_CFG_CDR_RSTN, x)
+
+#define SD25G_LANE_LANE_1C_LN_CFG_DFE_PD BIT(1)
+#define SD25G_LANE_LANE_1C_LN_CFG_DFE_PD_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_1C_LN_CFG_DFE_PD, x)
+#define SD25G_LANE_LANE_1C_LN_CFG_DFE_PD_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_1C_LN_CFG_DFE_PD, x)
+
+#define SD25G_LANE_LANE_1C_LN_CFG_DFEDMX_PD BIT(2)
+#define SD25G_LANE_LANE_1C_LN_CFG_DFEDMX_PD_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_1C_LN_CFG_DFEDMX_PD, x)
+#define SD25G_LANE_LANE_1C_LN_CFG_DFEDMX_PD_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_1C_LN_CFG_DFEDMX_PD, x)
+
+#define SD25G_LANE_LANE_1C_LN_CFG_EQC_FORCE_3_0 GENMASK(7, 4)
+#define SD25G_LANE_LANE_1C_LN_CFG_EQC_FORCE_3_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_1C_LN_CFG_EQC_FORCE_3_0, x)
+#define SD25G_LANE_LANE_1C_LN_CFG_EQC_FORCE_3_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_1C_LN_CFG_EQC_FORCE_3_0, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_1D */
+#define SD25G_LANE_LANE_1D(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 116, 0, 1, 4)
+
+#define SD25G_LANE_LANE_1D_LN_CFG_ISCAN_EXT_OVR BIT(0)
+#define SD25G_LANE_LANE_1D_LN_CFG_ISCAN_EXT_OVR_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_1D_LN_CFG_ISCAN_EXT_OVR, x)
+#define SD25G_LANE_LANE_1D_LN_CFG_ISCAN_EXT_OVR_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_1D_LN_CFG_ISCAN_EXT_OVR, x)
+
+#define SD25G_LANE_LANE_1D_LN_CFG_ISCAN_HOLD BIT(1)
+#define SD25G_LANE_LANE_1D_LN_CFG_ISCAN_HOLD_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_1D_LN_CFG_ISCAN_HOLD, x)
+#define SD25G_LANE_LANE_1D_LN_CFG_ISCAN_HOLD_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_1D_LN_CFG_ISCAN_HOLD, x)
+
+#define SD25G_LANE_LANE_1D_LN_CFG_ISCAN_RSTN BIT(2)
+#define SD25G_LANE_LANE_1D_LN_CFG_ISCAN_RSTN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_1D_LN_CFG_ISCAN_RSTN, x)
+#define SD25G_LANE_LANE_1D_LN_CFG_ISCAN_RSTN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_1D_LN_CFG_ISCAN_RSTN, x)
+
+#define SD25G_LANE_LANE_1D_LN_CFG_AGC_ADPT_BYP BIT(3)
+#define SD25G_LANE_LANE_1D_LN_CFG_AGC_ADPT_BYP_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_1D_LN_CFG_AGC_ADPT_BYP, x)
+#define SD25G_LANE_LANE_1D_LN_CFG_AGC_ADPT_BYP_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_1D_LN_CFG_AGC_ADPT_BYP, x)
+
+#define SD25G_LANE_LANE_1D_LN_CFG_PHID_1T BIT(4)
+#define SD25G_LANE_LANE_1D_LN_CFG_PHID_1T_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_1D_LN_CFG_PHID_1T, x)
+#define SD25G_LANE_LANE_1D_LN_CFG_PHID_1T_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_1D_LN_CFG_PHID_1T, x)
+
+#define SD25G_LANE_LANE_1D_LN_CFG_PI_DFE_EN BIT(5)
+#define SD25G_LANE_LANE_1D_LN_CFG_PI_DFE_EN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_1D_LN_CFG_PI_DFE_EN, x)
+#define SD25G_LANE_LANE_1D_LN_CFG_PI_DFE_EN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_1D_LN_CFG_PI_DFE_EN, x)
+
+#define SD25G_LANE_LANE_1D_LN_CFG_PI_EXT_OVR BIT(6)
+#define SD25G_LANE_LANE_1D_LN_CFG_PI_EXT_OVR_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_1D_LN_CFG_PI_EXT_OVR, x)
+#define SD25G_LANE_LANE_1D_LN_CFG_PI_EXT_OVR_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_1D_LN_CFG_PI_EXT_OVR, x)
+
+#define SD25G_LANE_LANE_1D_LN_CFG_PI_HOLD BIT(7)
+#define SD25G_LANE_LANE_1D_LN_CFG_PI_HOLD_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_1D_LN_CFG_PI_HOLD, x)
+#define SD25G_LANE_LANE_1D_LN_CFG_PI_HOLD_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_1D_LN_CFG_PI_HOLD, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_1E */
+#define SD25G_LANE_LANE_1E(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 120, 0, 1, 4)
+
+#define SD25G_LANE_LANE_1E_LN_CFG_PI_STEPS_1_0 GENMASK(1, 0)
+#define SD25G_LANE_LANE_1E_LN_CFG_PI_STEPS_1_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_1E_LN_CFG_PI_STEPS_1_0, x)
+#define SD25G_LANE_LANE_1E_LN_CFG_PI_STEPS_1_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_1E_LN_CFG_PI_STEPS_1_0, x)
+
+#define SD25G_LANE_LANE_1E_LN_CFG_RXLB_EN BIT(4)
+#define SD25G_LANE_LANE_1E_LN_CFG_RXLB_EN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_1E_LN_CFG_RXLB_EN, x)
+#define SD25G_LANE_LANE_1E_LN_CFG_RXLB_EN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_1E_LN_CFG_RXLB_EN, x)
+
+#define SD25G_LANE_LANE_1E_LN_CFG_SUM_SETCM_EN BIT(5)
+#define SD25G_LANE_LANE_1E_LN_CFG_SUM_SETCM_EN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_1E_LN_CFG_SUM_SETCM_EN, x)
+#define SD25G_LANE_LANE_1E_LN_CFG_SUM_SETCM_EN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_1E_LN_CFG_SUM_SETCM_EN, x)
+
+#define SD25G_LANE_LANE_1E_LN_CFG_R_OFFSET_DIR BIT(6)
+#define SD25G_LANE_LANE_1E_LN_CFG_R_OFFSET_DIR_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_1E_LN_CFG_R_OFFSET_DIR, x)
+#define SD25G_LANE_LANE_1E_LN_CFG_R_OFFSET_DIR_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_1E_LN_CFG_R_OFFSET_DIR, x)
+
+#define SD25G_LANE_LANE_1E_LN_CFG_PMAD_CK_PD BIT(7)
+#define SD25G_LANE_LANE_1E_LN_CFG_PMAD_CK_PD_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_1E_LN_CFG_PMAD_CK_PD, x)
+#define SD25G_LANE_LANE_1E_LN_CFG_PMAD_CK_PD_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_1E_LN_CFG_PMAD_CK_PD, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_21 */
+#define SD25G_LANE_LANE_21(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 132, 0, 1, 4)
+
+#define SD25G_LANE_LANE_21_LN_CFG_VGA_CTRL_BYP_4_0 GENMASK(4, 0)
+#define SD25G_LANE_LANE_21_LN_CFG_VGA_CTRL_BYP_4_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_21_LN_CFG_VGA_CTRL_BYP_4_0, x)
+#define SD25G_LANE_LANE_21_LN_CFG_VGA_CTRL_BYP_4_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_21_LN_CFG_VGA_CTRL_BYP_4_0, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_22 */
+#define SD25G_LANE_LANE_22(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 136, 0, 1, 4)
+
+#define SD25G_LANE_LANE_22_LN_CFG_EQR_FORCE_3_0 GENMASK(3, 0)
+#define SD25G_LANE_LANE_22_LN_CFG_EQR_FORCE_3_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_22_LN_CFG_EQR_FORCE_3_0, x)
+#define SD25G_LANE_LANE_22_LN_CFG_EQR_FORCE_3_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_22_LN_CFG_EQR_FORCE_3_0, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_25 */
+#define SD25G_LANE_LANE_25(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 148, 0, 1, 4)
+
+#define SD25G_LANE_LANE_25_LN_CFG_INIT_POS_ISCAN_6_0 GENMASK(6, 0)
+#define SD25G_LANE_LANE_25_LN_CFG_INIT_POS_ISCAN_6_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_25_LN_CFG_INIT_POS_ISCAN_6_0, x)
+#define SD25G_LANE_LANE_25_LN_CFG_INIT_POS_ISCAN_6_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_25_LN_CFG_INIT_POS_ISCAN_6_0, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_26 */
+#define SD25G_LANE_LANE_26(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 152, 0, 1, 4)
+
+#define SD25G_LANE_LANE_26_LN_CFG_INIT_POS_IPI_6_0 GENMASK(6, 0)
+#define SD25G_LANE_LANE_26_LN_CFG_INIT_POS_IPI_6_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_26_LN_CFG_INIT_POS_IPI_6_0, x)
+#define SD25G_LANE_LANE_26_LN_CFG_INIT_POS_IPI_6_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_26_LN_CFG_INIT_POS_IPI_6_0, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_28 */
+#define SD25G_LANE_LANE_28(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 160, 0, 1, 4)
+
+#define SD25G_LANE_LANE_28_LN_CFG_ISCAN_MODE_EN BIT(0)
+#define SD25G_LANE_LANE_28_LN_CFG_ISCAN_MODE_EN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_28_LN_CFG_ISCAN_MODE_EN, x)
+#define SD25G_LANE_LANE_28_LN_CFG_ISCAN_MODE_EN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_28_LN_CFG_ISCAN_MODE_EN, x)
+
+#define SD25G_LANE_LANE_28_LN_CFG_RX_SSC_LH BIT(1)
+#define SD25G_LANE_LANE_28_LN_CFG_RX_SSC_LH_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_28_LN_CFG_RX_SSC_LH, x)
+#define SD25G_LANE_LANE_28_LN_CFG_RX_SSC_LH_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_28_LN_CFG_RX_SSC_LH, x)
+
+#define SD25G_LANE_LANE_28_LN_CFG_FIGMERIT_SEL BIT(2)
+#define SD25G_LANE_LANE_28_LN_CFG_FIGMERIT_SEL_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_28_LN_CFG_FIGMERIT_SEL, x)
+#define SD25G_LANE_LANE_28_LN_CFG_FIGMERIT_SEL_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_28_LN_CFG_FIGMERIT_SEL, x)
+
+#define SD25G_LANE_LANE_28_LN_CFG_RX_SUBRATE_2_0 GENMASK(6, 4)
+#define SD25G_LANE_LANE_28_LN_CFG_RX_SUBRATE_2_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_28_LN_CFG_RX_SUBRATE_2_0, x)
+#define SD25G_LANE_LANE_28_LN_CFG_RX_SUBRATE_2_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_28_LN_CFG_RX_SUBRATE_2_0, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_2B */
+#define SD25G_LANE_LANE_2B(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 172, 0, 1, 4)
+
+#define SD25G_LANE_LANE_2B_LN_CFG_PI_BW_3_0 GENMASK(3, 0)
+#define SD25G_LANE_LANE_2B_LN_CFG_PI_BW_3_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_2B_LN_CFG_PI_BW_3_0, x)
+#define SD25G_LANE_LANE_2B_LN_CFG_PI_BW_3_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_2B_LN_CFG_PI_BW_3_0, x)
+
+#define SD25G_LANE_LANE_2B_LN_CFG_RSTN_DMUX_SUBR BIT(4)
+#define SD25G_LANE_LANE_2B_LN_CFG_RSTN_DMUX_SUBR_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_2B_LN_CFG_RSTN_DMUX_SUBR, x)
+#define SD25G_LANE_LANE_2B_LN_CFG_RSTN_DMUX_SUBR_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_2B_LN_CFG_RSTN_DMUX_SUBR, x)
+
+#define SD25G_LANE_LANE_2B_LN_CFG_RSTN_TXDUPU BIT(5)
+#define SD25G_LANE_LANE_2B_LN_CFG_RSTN_TXDUPU_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_2B_LN_CFG_RSTN_TXDUPU, x)
+#define SD25G_LANE_LANE_2B_LN_CFG_RSTN_TXDUPU_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_2B_LN_CFG_RSTN_TXDUPU, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_2C */
+#define SD25G_LANE_LANE_2C(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 176, 0, 1, 4)
+
+#define SD25G_LANE_LANE_2C_LN_CFG_TX_SUBRATE_2_0 GENMASK(2, 0)
+#define SD25G_LANE_LANE_2C_LN_CFG_TX_SUBRATE_2_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_2C_LN_CFG_TX_SUBRATE_2_0, x)
+#define SD25G_LANE_LANE_2C_LN_CFG_TX_SUBRATE_2_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_2C_LN_CFG_TX_SUBRATE_2_0, x)
+
+#define SD25G_LANE_LANE_2C_LN_CFG_DIS_2NDORDER BIT(4)
+#define SD25G_LANE_LANE_2C_LN_CFG_DIS_2NDORDER_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_2C_LN_CFG_DIS_2NDORDER, x)
+#define SD25G_LANE_LANE_2C_LN_CFG_DIS_2NDORDER_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_2C_LN_CFG_DIS_2NDORDER, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_2D */
+#define SD25G_LANE_LANE_2D(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 180, 0, 1, 4)
+
+#define SD25G_LANE_LANE_2D_LN_CFG_ALOS_THR_2_0 GENMASK(2, 0)
+#define SD25G_LANE_LANE_2D_LN_CFG_ALOS_THR_2_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_2D_LN_CFG_ALOS_THR_2_0, x)
+#define SD25G_LANE_LANE_2D_LN_CFG_ALOS_THR_2_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_2D_LN_CFG_ALOS_THR_2_0, x)
+
+#define SD25G_LANE_LANE_2D_LN_CFG_SAT_CNTSEL_2_0 GENMASK(6, 4)
+#define SD25G_LANE_LANE_2D_LN_CFG_SAT_CNTSEL_2_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_2D_LN_CFG_SAT_CNTSEL_2_0, x)
+#define SD25G_LANE_LANE_2D_LN_CFG_SAT_CNTSEL_2_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_2D_LN_CFG_SAT_CNTSEL_2_0, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_2E */
+#define SD25G_LANE_LANE_2E(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 184, 0, 1, 4)
+
+#define SD25G_LANE_LANE_2E_LN_CFG_EN_FAST_ISCAN BIT(0)
+#define SD25G_LANE_LANE_2E_LN_CFG_EN_FAST_ISCAN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_2E_LN_CFG_EN_FAST_ISCAN, x)
+#define SD25G_LANE_LANE_2E_LN_CFG_EN_FAST_ISCAN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_2E_LN_CFG_EN_FAST_ISCAN, x)
+
+#define SD25G_LANE_LANE_2E_LN_CFG_DIS_SQ BIT(1)
+#define SD25G_LANE_LANE_2E_LN_CFG_DIS_SQ_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_2E_LN_CFG_DIS_SQ, x)
+#define SD25G_LANE_LANE_2E_LN_CFG_DIS_SQ_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_2E_LN_CFG_DIS_SQ, x)
+
+#define SD25G_LANE_LANE_2E_LN_CFG_PD_SQ BIT(2)
+#define SD25G_LANE_LANE_2E_LN_CFG_PD_SQ_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_2E_LN_CFG_PD_SQ, x)
+#define SD25G_LANE_LANE_2E_LN_CFG_PD_SQ_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_2E_LN_CFG_PD_SQ, x)
+
+#define SD25G_LANE_LANE_2E_LN_CFG_DIS_ALOS BIT(3)
+#define SD25G_LANE_LANE_2E_LN_CFG_DIS_ALOS_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_2E_LN_CFG_DIS_ALOS, x)
+#define SD25G_LANE_LANE_2E_LN_CFG_DIS_ALOS_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_2E_LN_CFG_DIS_ALOS, x)
+
+#define SD25G_LANE_LANE_2E_LN_CFG_RESETN_AGC BIT(4)
+#define SD25G_LANE_LANE_2E_LN_CFG_RESETN_AGC_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_2E_LN_CFG_RESETN_AGC, x)
+#define SD25G_LANE_LANE_2E_LN_CFG_RESETN_AGC_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_2E_LN_CFG_RESETN_AGC, x)
+
+#define SD25G_LANE_LANE_2E_LN_CFG_RSTN_DFEDIG BIT(5)
+#define SD25G_LANE_LANE_2E_LN_CFG_RSTN_DFEDIG_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_2E_LN_CFG_RSTN_DFEDIG, x)
+#define SD25G_LANE_LANE_2E_LN_CFG_RSTN_DFEDIG_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_2E_LN_CFG_RSTN_DFEDIG, x)
+
+#define SD25G_LANE_LANE_2E_LN_CFG_PI_RSTN BIT(6)
+#define SD25G_LANE_LANE_2E_LN_CFG_PI_RSTN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_2E_LN_CFG_PI_RSTN, x)
+#define SD25G_LANE_LANE_2E_LN_CFG_PI_RSTN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_2E_LN_CFG_PI_RSTN, x)
+
+#define SD25G_LANE_LANE_2E_LN_CFG_CTLE_RSTN BIT(7)
+#define SD25G_LANE_LANE_2E_LN_CFG_CTLE_RSTN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_2E_LN_CFG_CTLE_RSTN, x)
+#define SD25G_LANE_LANE_2E_LN_CFG_CTLE_RSTN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_2E_LN_CFG_CTLE_RSTN, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_40 */
+#define SD25G_LANE_LANE_40(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 256, 0, 1, 4)
+
+#define SD25G_LANE_LANE_40_LN_R_TX_BIT_REVERSE BIT(0)
+#define SD25G_LANE_LANE_40_LN_R_TX_BIT_REVERSE_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_40_LN_R_TX_BIT_REVERSE, x)
+#define SD25G_LANE_LANE_40_LN_R_TX_BIT_REVERSE_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_40_LN_R_TX_BIT_REVERSE, x)
+
+#define SD25G_LANE_LANE_40_LN_R_TX_POL_INV BIT(1)
+#define SD25G_LANE_LANE_40_LN_R_TX_POL_INV_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_40_LN_R_TX_POL_INV, x)
+#define SD25G_LANE_LANE_40_LN_R_TX_POL_INV_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_40_LN_R_TX_POL_INV, x)
+
+#define SD25G_LANE_LANE_40_LN_R_RX_BIT_REVERSE BIT(2)
+#define SD25G_LANE_LANE_40_LN_R_RX_BIT_REVERSE_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_40_LN_R_RX_BIT_REVERSE, x)
+#define SD25G_LANE_LANE_40_LN_R_RX_BIT_REVERSE_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_40_LN_R_RX_BIT_REVERSE, x)
+
+#define SD25G_LANE_LANE_40_LN_R_RX_POL_INV BIT(3)
+#define SD25G_LANE_LANE_40_LN_R_RX_POL_INV_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_40_LN_R_RX_POL_INV, x)
+#define SD25G_LANE_LANE_40_LN_R_RX_POL_INV_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_40_LN_R_RX_POL_INV, x)
+
+#define SD25G_LANE_LANE_40_LN_R_CDR_RSTN BIT(4)
+#define SD25G_LANE_LANE_40_LN_R_CDR_RSTN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_40_LN_R_CDR_RSTN, x)
+#define SD25G_LANE_LANE_40_LN_R_CDR_RSTN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_40_LN_R_CDR_RSTN, x)
+
+#define SD25G_LANE_LANE_40_LN_R_DFE_RSTN BIT(5)
+#define SD25G_LANE_LANE_40_LN_R_DFE_RSTN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_40_LN_R_DFE_RSTN, x)
+#define SD25G_LANE_LANE_40_LN_R_DFE_RSTN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_40_LN_R_DFE_RSTN, x)
+
+#define SD25G_LANE_LANE_40_LN_R_CTLE_RSTN BIT(6)
+#define SD25G_LANE_LANE_40_LN_R_CTLE_RSTN_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_40_LN_R_CTLE_RSTN, x)
+#define SD25G_LANE_LANE_40_LN_R_CTLE_RSTN_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_40_LN_R_CTLE_RSTN, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_42 */
+#define SD25G_LANE_LANE_42(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 264, 0, 1, 4)
+
+#define SD25G_LANE_LANE_42_LN_CFG_TX_RESERVE_7_0 GENMASK(7, 0)
+#define SD25G_LANE_LANE_42_LN_CFG_TX_RESERVE_7_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_42_LN_CFG_TX_RESERVE_7_0, x)
+#define SD25G_LANE_LANE_42_LN_CFG_TX_RESERVE_7_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_42_LN_CFG_TX_RESERVE_7_0, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_43 */
+#define SD25G_LANE_LANE_43(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 268, 0, 1, 4)
+
+#define SD25G_LANE_LANE_43_LN_CFG_TX_RESERVE_15_8 GENMASK(7, 0)
+#define SD25G_LANE_LANE_43_LN_CFG_TX_RESERVE_15_8_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_43_LN_CFG_TX_RESERVE_15_8, x)
+#define SD25G_LANE_LANE_43_LN_CFG_TX_RESERVE_15_8_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_43_LN_CFG_TX_RESERVE_15_8, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_44 */
+#define SD25G_LANE_LANE_44(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 272, 0, 1, 4)
+
+#define SD25G_LANE_LANE_44_LN_CFG_RX_RESERVE_7_0 GENMASK(7, 0)
+#define SD25G_LANE_LANE_44_LN_CFG_RX_RESERVE_7_0_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_44_LN_CFG_RX_RESERVE_7_0, x)
+#define SD25G_LANE_LANE_44_LN_CFG_RX_RESERVE_7_0_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_44_LN_CFG_RX_RESERVE_7_0, x)
+
+/* SD25G_TARGET:LANE_GRP_0:LANE_45 */
+#define SD25G_LANE_LANE_45(t) __REG(TARGET_SD25G_LANE, t, 8, 1024, 0, 1, 768, 276, 0, 1, 4)
+
+#define SD25G_LANE_LANE_45_LN_CFG_RX_RESERVE_15_8 GENMASK(7, 0)
+#define SD25G_LANE_LANE_45_LN_CFG_RX_RESERVE_15_8_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_45_LN_CFG_RX_RESERVE_15_8, x)
+#define SD25G_LANE_LANE_45_LN_CFG_RX_RESERVE_15_8_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_45_LN_CFG_RX_RESERVE_15_8, x)
+
+/* SD25G_TARGET:LANE_GRP_1:LANE_DE */
+#define SD25G_LANE_LANE_DE(t) __REG(TARGET_SD25G_LANE, t, 8, 1792, 0, 1, 128, 120, 0, 1, 4)
+
+#define SD25G_LANE_LANE_DE_LN_LOL_UDL BIT(0)
+#define SD25G_LANE_LANE_DE_LN_LOL_UDL_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_DE_LN_LOL_UDL, x)
+#define SD25G_LANE_LANE_DE_LN_LOL_UDL_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_DE_LN_LOL_UDL, x)
+
+#define SD25G_LANE_LANE_DE_LN_LOL BIT(1)
+#define SD25G_LANE_LANE_DE_LN_LOL_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_DE_LN_LOL, x)
+#define SD25G_LANE_LANE_DE_LN_LOL_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_DE_LN_LOL, x)
+
+#define SD25G_LANE_LANE_DE_LN_PMA2PCS_RXEI_FILTERED BIT(2)
+#define SD25G_LANE_LANE_DE_LN_PMA2PCS_RXEI_FILTERED_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_DE_LN_PMA2PCS_RXEI_FILTERED, x)
+#define SD25G_LANE_LANE_DE_LN_PMA2PCS_RXEI_FILTERED_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_DE_LN_PMA2PCS_RXEI_FILTERED, x)
+
+#define SD25G_LANE_LANE_DE_LN_PMA_RXEI BIT(3)
+#define SD25G_LANE_LANE_DE_LN_PMA_RXEI_SET(x)\
+ FIELD_PREP(SD25G_LANE_LANE_DE_LN_PMA_RXEI, x)
+#define SD25G_LANE_LANE_DE_LN_PMA_RXEI_GET(x)\
+ FIELD_GET(SD25G_LANE_LANE_DE_LN_PMA_RXEI, x)
+
+/* SD10G_LANE_TARGET:LANE_GRP_8:LANE_DF */
+#define SD6G_LANE_LANE_DF(t) __REG(TARGET_SD6G_LANE, t, 13, 832, 0, 1, 84, 60, 0, 1, 4)
+
+#define SD6G_LANE_LANE_DF_LOL_UDL BIT(0)
+#define SD6G_LANE_LANE_DF_LOL_UDL_SET(x)\
+ FIELD_PREP(SD6G_LANE_LANE_DF_LOL_UDL, x)
+#define SD6G_LANE_LANE_DF_LOL_UDL_GET(x)\
+ FIELD_GET(SD6G_LANE_LANE_DF_LOL_UDL, x)
+
+#define SD6G_LANE_LANE_DF_LOL BIT(1)
+#define SD6G_LANE_LANE_DF_LOL_SET(x)\
+ FIELD_PREP(SD6G_LANE_LANE_DF_LOL, x)
+#define SD6G_LANE_LANE_DF_LOL_GET(x)\
+ FIELD_GET(SD6G_LANE_LANE_DF_LOL, x)
+
+#define SD6G_LANE_LANE_DF_PMA2PCS_RXEI_FILTERED BIT(2)
+#define SD6G_LANE_LANE_DF_PMA2PCS_RXEI_FILTERED_SET(x)\
+ FIELD_PREP(SD6G_LANE_LANE_DF_PMA2PCS_RXEI_FILTERED, x)
+#define SD6G_LANE_LANE_DF_PMA2PCS_RXEI_FILTERED_GET(x)\
+ FIELD_GET(SD6G_LANE_LANE_DF_PMA2PCS_RXEI_FILTERED, x)
+
+#define SD6G_LANE_LANE_DF_SQUELCH BIT(3)
+#define SD6G_LANE_LANE_DF_SQUELCH_SET(x)\
+ FIELD_PREP(SD6G_LANE_LANE_DF_SQUELCH, x)
+#define SD6G_LANE_LANE_DF_SQUELCH_GET(x)\
+ FIELD_GET(SD6G_LANE_LANE_DF_SQUELCH, x)
+
+/* SD10G_CMU_TARGET:CMU_GRP_0:CMU_00 */
+#define SD_CMU_CMU_00(t) __REG(TARGET_SD_CMU, t, 14, 0, 0, 1, 20, 0, 0, 1, 4)
+
+#define SD_CMU_CMU_00_R_HWT_SIMULATION_MODE BIT(0)
+#define SD_CMU_CMU_00_R_HWT_SIMULATION_MODE_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_00_R_HWT_SIMULATION_MODE, x)
+#define SD_CMU_CMU_00_R_HWT_SIMULATION_MODE_GET(x)\
+ FIELD_GET(SD_CMU_CMU_00_R_HWT_SIMULATION_MODE, x)
+
+#define SD_CMU_CMU_00_CFG_PLL_LOL_SET BIT(1)
+#define SD_CMU_CMU_00_CFG_PLL_LOL_SET_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_00_CFG_PLL_LOL_SET, x)
+#define SD_CMU_CMU_00_CFG_PLL_LOL_SET_GET(x)\
+ FIELD_GET(SD_CMU_CMU_00_CFG_PLL_LOL_SET, x)
+
+#define SD_CMU_CMU_00_CFG_PLL_LOS_SET BIT(2)
+#define SD_CMU_CMU_00_CFG_PLL_LOS_SET_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_00_CFG_PLL_LOS_SET, x)
+#define SD_CMU_CMU_00_CFG_PLL_LOS_SET_GET(x)\
+ FIELD_GET(SD_CMU_CMU_00_CFG_PLL_LOS_SET, x)
+
+#define SD_CMU_CMU_00_CFG_PLL_TP_SEL_1_0 GENMASK(5, 4)
+#define SD_CMU_CMU_00_CFG_PLL_TP_SEL_1_0_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_00_CFG_PLL_TP_SEL_1_0, x)
+#define SD_CMU_CMU_00_CFG_PLL_TP_SEL_1_0_GET(x)\
+ FIELD_GET(SD_CMU_CMU_00_CFG_PLL_TP_SEL_1_0, x)
+
+/* SD10G_CMU_TARGET:CMU_GRP_1:CMU_05 */
+#define SD_CMU_CMU_05(t) __REG(TARGET_SD_CMU, t, 14, 20, 0, 1, 72, 0, 0, 1, 4)
+
+#define SD_CMU_CMU_05_CFG_REFCK_TERM_EN BIT(0)
+#define SD_CMU_CMU_05_CFG_REFCK_TERM_EN_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_05_CFG_REFCK_TERM_EN, x)
+#define SD_CMU_CMU_05_CFG_REFCK_TERM_EN_GET(x)\
+ FIELD_GET(SD_CMU_CMU_05_CFG_REFCK_TERM_EN, x)
+
+#define SD_CMU_CMU_05_CFG_BIAS_TP_SEL_1_0 GENMASK(5, 4)
+#define SD_CMU_CMU_05_CFG_BIAS_TP_SEL_1_0_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_05_CFG_BIAS_TP_SEL_1_0, x)
+#define SD_CMU_CMU_05_CFG_BIAS_TP_SEL_1_0_GET(x)\
+ FIELD_GET(SD_CMU_CMU_05_CFG_BIAS_TP_SEL_1_0, x)
+
+/* SD10G_CMU_TARGET:CMU_GRP_1:CMU_09 */
+#define SD_CMU_CMU_09(t) __REG(TARGET_SD_CMU, t, 14, 20, 0, 1, 72, 16, 0, 1, 4)
+
+#define SD_CMU_CMU_09_CFG_EN_TX_CK_UP BIT(0)
+#define SD_CMU_CMU_09_CFG_EN_TX_CK_UP_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_09_CFG_EN_TX_CK_UP, x)
+#define SD_CMU_CMU_09_CFG_EN_TX_CK_UP_GET(x)\
+ FIELD_GET(SD_CMU_CMU_09_CFG_EN_TX_CK_UP, x)
+
+#define SD_CMU_CMU_09_CFG_EN_TX_CK_DN BIT(1)
+#define SD_CMU_CMU_09_CFG_EN_TX_CK_DN_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_09_CFG_EN_TX_CK_DN, x)
+#define SD_CMU_CMU_09_CFG_EN_TX_CK_DN_GET(x)\
+ FIELD_GET(SD_CMU_CMU_09_CFG_EN_TX_CK_DN, x)
+
+#define SD_CMU_CMU_09_CFG_SW_8G BIT(4)
+#define SD_CMU_CMU_09_CFG_SW_8G_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_09_CFG_SW_8G, x)
+#define SD_CMU_CMU_09_CFG_SW_8G_GET(x)\
+ FIELD_GET(SD_CMU_CMU_09_CFG_SW_8G, x)
+
+#define SD_CMU_CMU_09_CFG_SW_10G BIT(5)
+#define SD_CMU_CMU_09_CFG_SW_10G_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_09_CFG_SW_10G, x)
+#define SD_CMU_CMU_09_CFG_SW_10G_GET(x)\
+ FIELD_GET(SD_CMU_CMU_09_CFG_SW_10G, x)
+
+/* SD10G_CMU_TARGET:CMU_GRP_1:CMU_0D */
+#define SD_CMU_CMU_0D(t) __REG(TARGET_SD_CMU, t, 14, 20, 0, 1, 72, 32, 0, 1, 4)
+
+#define SD_CMU_CMU_0D_CFG_PD_DIV64 BIT(0)
+#define SD_CMU_CMU_0D_CFG_PD_DIV64_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_0D_CFG_PD_DIV64, x)
+#define SD_CMU_CMU_0D_CFG_PD_DIV64_GET(x)\
+ FIELD_GET(SD_CMU_CMU_0D_CFG_PD_DIV64, x)
+
+#define SD_CMU_CMU_0D_CFG_PD_DIV66 BIT(1)
+#define SD_CMU_CMU_0D_CFG_PD_DIV66_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_0D_CFG_PD_DIV66, x)
+#define SD_CMU_CMU_0D_CFG_PD_DIV66_GET(x)\
+ FIELD_GET(SD_CMU_CMU_0D_CFG_PD_DIV66, x)
+
+#define SD_CMU_CMU_0D_CFG_PMA_TX_CK_PD BIT(2)
+#define SD_CMU_CMU_0D_CFG_PMA_TX_CK_PD_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_0D_CFG_PMA_TX_CK_PD, x)
+#define SD_CMU_CMU_0D_CFG_PMA_TX_CK_PD_GET(x)\
+ FIELD_GET(SD_CMU_CMU_0D_CFG_PMA_TX_CK_PD, x)
+
+#define SD_CMU_CMU_0D_CFG_JC_BYP BIT(3)
+#define SD_CMU_CMU_0D_CFG_JC_BYP_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_0D_CFG_JC_BYP, x)
+#define SD_CMU_CMU_0D_CFG_JC_BYP_GET(x)\
+ FIELD_GET(SD_CMU_CMU_0D_CFG_JC_BYP, x)
+
+#define SD_CMU_CMU_0D_CFG_REFCK_PD BIT(4)
+#define SD_CMU_CMU_0D_CFG_REFCK_PD_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_0D_CFG_REFCK_PD, x)
+#define SD_CMU_CMU_0D_CFG_REFCK_PD_GET(x)\
+ FIELD_GET(SD_CMU_CMU_0D_CFG_REFCK_PD, x)
+
+/* SD10G_CMU_TARGET:CMU_GRP_3:CMU_1B */
+#define SD_CMU_CMU_1B(t) __REG(TARGET_SD_CMU, t, 14, 104, 0, 1, 20, 4, 0, 1, 4)
+
+#define SD_CMU_CMU_1B_CFG_RESERVE_7_0 GENMASK(7, 0)
+#define SD_CMU_CMU_1B_CFG_RESERVE_7_0_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_1B_CFG_RESERVE_7_0, x)
+#define SD_CMU_CMU_1B_CFG_RESERVE_7_0_GET(x)\
+ FIELD_GET(SD_CMU_CMU_1B_CFG_RESERVE_7_0, x)
+
+/* SD10G_CMU_TARGET:CMU_GRP_4:CMU_1F */
+#define SD_CMU_CMU_1F(t) __REG(TARGET_SD_CMU, t, 14, 124, 0, 1, 68, 0, 0, 1, 4)
+
+#define SD_CMU_CMU_1F_CFG_BIAS_DN_EN BIT(0)
+#define SD_CMU_CMU_1F_CFG_BIAS_DN_EN_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_1F_CFG_BIAS_DN_EN, x)
+#define SD_CMU_CMU_1F_CFG_BIAS_DN_EN_GET(x)\
+ FIELD_GET(SD_CMU_CMU_1F_CFG_BIAS_DN_EN, x)
+
+#define SD_CMU_CMU_1F_CFG_BIAS_UP_EN BIT(1)
+#define SD_CMU_CMU_1F_CFG_BIAS_UP_EN_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_1F_CFG_BIAS_UP_EN, x)
+#define SD_CMU_CMU_1F_CFG_BIAS_UP_EN_GET(x)\
+ FIELD_GET(SD_CMU_CMU_1F_CFG_BIAS_UP_EN, x)
+
+#define SD_CMU_CMU_1F_CFG_IC2IP_N BIT(2)
+#define SD_CMU_CMU_1F_CFG_IC2IP_N_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_1F_CFG_IC2IP_N, x)
+#define SD_CMU_CMU_1F_CFG_IC2IP_N_GET(x)\
+ FIELD_GET(SD_CMU_CMU_1F_CFG_IC2IP_N, x)
+
+#define SD_CMU_CMU_1F_CFG_VTUNE_SEL BIT(3)
+#define SD_CMU_CMU_1F_CFG_VTUNE_SEL_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_1F_CFG_VTUNE_SEL, x)
+#define SD_CMU_CMU_1F_CFG_VTUNE_SEL_GET(x)\
+ FIELD_GET(SD_CMU_CMU_1F_CFG_VTUNE_SEL, x)
+
+/* SD10G_CMU_TARGET:CMU_GRP_5:CMU_30 */
+#define SD_CMU_CMU_30(t) __REG(TARGET_SD_CMU, t, 14, 192, 0, 1, 72, 0, 0, 1, 4)
+
+#define SD_CMU_CMU_30_R_PLL_DLOL_EN BIT(0)
+#define SD_CMU_CMU_30_R_PLL_DLOL_EN_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_30_R_PLL_DLOL_EN, x)
+#define SD_CMU_CMU_30_R_PLL_DLOL_EN_GET(x)\
+ FIELD_GET(SD_CMU_CMU_30_R_PLL_DLOL_EN, x)
+
+/* SD10G_CMU_TARGET:CMU_GRP_6:CMU_44 */
+#define SD_CMU_CMU_44(t) __REG(TARGET_SD_CMU, t, 14, 264, 0, 1, 632, 8, 0, 1, 4)
+
+#define SD_CMU_CMU_44_R_PLL_RSTN BIT(0)
+#define SD_CMU_CMU_44_R_PLL_RSTN_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_44_R_PLL_RSTN, x)
+#define SD_CMU_CMU_44_R_PLL_RSTN_GET(x)\
+ FIELD_GET(SD_CMU_CMU_44_R_PLL_RSTN, x)
+
+#define SD_CMU_CMU_44_R_CK_RESETB BIT(1)
+#define SD_CMU_CMU_44_R_CK_RESETB_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_44_R_CK_RESETB, x)
+#define SD_CMU_CMU_44_R_CK_RESETB_GET(x)\
+ FIELD_GET(SD_CMU_CMU_44_R_CK_RESETB, x)
+
+/* SD10G_CMU_TARGET:CMU_GRP_6:CMU_45 */
+#define SD_CMU_CMU_45(t) __REG(TARGET_SD_CMU, t, 14, 264, 0, 1, 632, 12, 0, 1, 4)
+
+#define SD_CMU_CMU_45_R_EN_RATECHG_CTRL BIT(0)
+#define SD_CMU_CMU_45_R_EN_RATECHG_CTRL_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_45_R_EN_RATECHG_CTRL, x)
+#define SD_CMU_CMU_45_R_EN_RATECHG_CTRL_GET(x)\
+ FIELD_GET(SD_CMU_CMU_45_R_EN_RATECHG_CTRL, x)
+
+#define SD_CMU_CMU_45_R_DWIDTHCTRL_FROM_HWT BIT(1)
+#define SD_CMU_CMU_45_R_DWIDTHCTRL_FROM_HWT_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_45_R_DWIDTHCTRL_FROM_HWT, x)
+#define SD_CMU_CMU_45_R_DWIDTHCTRL_FROM_HWT_GET(x)\
+ FIELD_GET(SD_CMU_CMU_45_R_DWIDTHCTRL_FROM_HWT, x)
+
+#define SD_CMU_CMU_45_RESERVED BIT(2)
+#define SD_CMU_CMU_45_RESERVED_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_45_RESERVED, x)
+#define SD_CMU_CMU_45_RESERVED_GET(x)\
+ FIELD_GET(SD_CMU_CMU_45_RESERVED, x)
+
+#define SD_CMU_CMU_45_R_REFCK_SSC_EN_FROM_HWT BIT(3)
+#define SD_CMU_CMU_45_R_REFCK_SSC_EN_FROM_HWT_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_45_R_REFCK_SSC_EN_FROM_HWT, x)
+#define SD_CMU_CMU_45_R_REFCK_SSC_EN_FROM_HWT_GET(x)\
+ FIELD_GET(SD_CMU_CMU_45_R_REFCK_SSC_EN_FROM_HWT, x)
+
+#define SD_CMU_CMU_45_RESERVED_2 BIT(4)
+#define SD_CMU_CMU_45_RESERVED_2_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_45_RESERVED_2, x)
+#define SD_CMU_CMU_45_RESERVED_2_GET(x)\
+ FIELD_GET(SD_CMU_CMU_45_RESERVED_2, x)
+
+#define SD_CMU_CMU_45_R_LINK_BUF_EN_FROM_HWT BIT(5)
+#define SD_CMU_CMU_45_R_LINK_BUF_EN_FROM_HWT_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_45_R_LINK_BUF_EN_FROM_HWT, x)
+#define SD_CMU_CMU_45_R_LINK_BUF_EN_FROM_HWT_GET(x)\
+ FIELD_GET(SD_CMU_CMU_45_R_LINK_BUF_EN_FROM_HWT, x)
+
+#define SD_CMU_CMU_45_R_BIAS_EN_FROM_HWT BIT(6)
+#define SD_CMU_CMU_45_R_BIAS_EN_FROM_HWT_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_45_R_BIAS_EN_FROM_HWT, x)
+#define SD_CMU_CMU_45_R_BIAS_EN_FROM_HWT_GET(x)\
+ FIELD_GET(SD_CMU_CMU_45_R_BIAS_EN_FROM_HWT, x)
+
+#define SD_CMU_CMU_45_R_AUTO_RST_TREE_PD_MAN BIT(7)
+#define SD_CMU_CMU_45_R_AUTO_RST_TREE_PD_MAN_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_45_R_AUTO_RST_TREE_PD_MAN, x)
+#define SD_CMU_CMU_45_R_AUTO_RST_TREE_PD_MAN_GET(x)\
+ FIELD_GET(SD_CMU_CMU_45_R_AUTO_RST_TREE_PD_MAN, x)
+
+/* SD10G_CMU_TARGET:CMU_GRP_6:CMU_47 */
+#define SD_CMU_CMU_47(t) __REG(TARGET_SD_CMU, t, 14, 264, 0, 1, 632, 20, 0, 1, 4)
+
+#define SD_CMU_CMU_47_R_PCS2PMA_PHYMODE_4_0 GENMASK(4, 0)
+#define SD_CMU_CMU_47_R_PCS2PMA_PHYMODE_4_0_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_47_R_PCS2PMA_PHYMODE_4_0, x)
+#define SD_CMU_CMU_47_R_PCS2PMA_PHYMODE_4_0_GET(x)\
+ FIELD_GET(SD_CMU_CMU_47_R_PCS2PMA_PHYMODE_4_0, x)
+
+/* SD10G_CMU_TARGET:CMU_GRP_7:CMU_E0 */
+#define SD_CMU_CMU_E0(t) __REG(TARGET_SD_CMU, t, 14, 896, 0, 1, 8, 0, 0, 1, 4)
+
+#define SD_CMU_CMU_E0_READ_VCO_CTUNE_3_0 GENMASK(3, 0)
+#define SD_CMU_CMU_E0_READ_VCO_CTUNE_3_0_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_E0_READ_VCO_CTUNE_3_0, x)
+#define SD_CMU_CMU_E0_READ_VCO_CTUNE_3_0_GET(x)\
+ FIELD_GET(SD_CMU_CMU_E0_READ_VCO_CTUNE_3_0, x)
+
+#define SD_CMU_CMU_E0_PLL_LOL_UDL BIT(4)
+#define SD_CMU_CMU_E0_PLL_LOL_UDL_SET(x)\
+ FIELD_PREP(SD_CMU_CMU_E0_PLL_LOL_UDL, x)
+#define SD_CMU_CMU_E0_PLL_LOL_UDL_GET(x)\
+ FIELD_GET(SD_CMU_CMU_E0_PLL_LOL_UDL, x)
+
+/* SD_CMU_TARGET:SD_CMU_CFG:SD_CMU_CFG */
+#define SD_CMU_CFG_SD_CMU_CFG(t) __REG(TARGET_SD_CMU_CFG, t, 14, 0, 0, 1, 8, 0, 0, 1, 4)
+
+#define SD_CMU_CFG_SD_CMU_CFG_CMU_RST BIT(0)
+#define SD_CMU_CFG_SD_CMU_CFG_CMU_RST_SET(x)\
+ FIELD_PREP(SD_CMU_CFG_SD_CMU_CFG_CMU_RST, x)
+#define SD_CMU_CFG_SD_CMU_CFG_CMU_RST_GET(x)\
+ FIELD_GET(SD_CMU_CFG_SD_CMU_CFG_CMU_RST, x)
+
+#define SD_CMU_CFG_SD_CMU_CFG_EXT_CFG_RST BIT(1)
+#define SD_CMU_CFG_SD_CMU_CFG_EXT_CFG_RST_SET(x)\
+ FIELD_PREP(SD_CMU_CFG_SD_CMU_CFG_EXT_CFG_RST, x)
+#define SD_CMU_CFG_SD_CMU_CFG_EXT_CFG_RST_GET(x)\
+ FIELD_GET(SD_CMU_CFG_SD_CMU_CFG_EXT_CFG_RST, x)
+
+/* SD_LANE_TARGET:SD_RESET:SD_SER_RST */
+#define SD_LANE_SD_SER_RST(t) __REG(TARGET_SD_LANE, t, 25, 0, 0, 1, 8, 0, 0, 1, 4)
+
+#define SD_LANE_SD_SER_RST_SER_RST BIT(0)
+#define SD_LANE_SD_SER_RST_SER_RST_SET(x)\
+ FIELD_PREP(SD_LANE_SD_SER_RST_SER_RST, x)
+#define SD_LANE_SD_SER_RST_SER_RST_GET(x)\
+ FIELD_GET(SD_LANE_SD_SER_RST_SER_RST, x)
+
+/* SD_LANE_TARGET:SD_RESET:SD_DES_RST */
+#define SD_LANE_SD_DES_RST(t) __REG(TARGET_SD_LANE, t, 25, 0, 0, 1, 8, 4, 0, 1, 4)
+
+#define SD_LANE_SD_DES_RST_DES_RST BIT(0)
+#define SD_LANE_SD_DES_RST_DES_RST_SET(x)\
+ FIELD_PREP(SD_LANE_SD_DES_RST_DES_RST, x)
+#define SD_LANE_SD_DES_RST_DES_RST_GET(x)\
+ FIELD_GET(SD_LANE_SD_DES_RST_DES_RST, x)
+
+/* SD_LANE_TARGET:SD_LANE_CFG_STAT:SD_LANE_CFG */
+#define SD_LANE_SD_LANE_CFG(t) __REG(TARGET_SD_LANE, t, 25, 8, 0, 1, 8, 0, 0, 1, 4)
+
+#define SD_LANE_SD_LANE_CFG_MACRO_RST BIT(0)
+#define SD_LANE_SD_LANE_CFG_MACRO_RST_SET(x)\
+ FIELD_PREP(SD_LANE_SD_LANE_CFG_MACRO_RST, x)
+#define SD_LANE_SD_LANE_CFG_MACRO_RST_GET(x)\
+ FIELD_GET(SD_LANE_SD_LANE_CFG_MACRO_RST, x)
+
+#define SD_LANE_SD_LANE_CFG_EXT_CFG_RST BIT(1)
+#define SD_LANE_SD_LANE_CFG_EXT_CFG_RST_SET(x)\
+ FIELD_PREP(SD_LANE_SD_LANE_CFG_EXT_CFG_RST, x)
+#define SD_LANE_SD_LANE_CFG_EXT_CFG_RST_GET(x)\
+ FIELD_GET(SD_LANE_SD_LANE_CFG_EXT_CFG_RST, x)
+
+#define SD_LANE_SD_LANE_CFG_TX_REF_SEL GENMASK(5, 4)
+#define SD_LANE_SD_LANE_CFG_TX_REF_SEL_SET(x)\
+ FIELD_PREP(SD_LANE_SD_LANE_CFG_TX_REF_SEL, x)
+#define SD_LANE_SD_LANE_CFG_TX_REF_SEL_GET(x)\
+ FIELD_GET(SD_LANE_SD_LANE_CFG_TX_REF_SEL, x)
+
+#define SD_LANE_SD_LANE_CFG_RX_REF_SEL GENMASK(7, 6)
+#define SD_LANE_SD_LANE_CFG_RX_REF_SEL_SET(x)\
+ FIELD_PREP(SD_LANE_SD_LANE_CFG_RX_REF_SEL, x)
+#define SD_LANE_SD_LANE_CFG_RX_REF_SEL_GET(x)\
+ FIELD_GET(SD_LANE_SD_LANE_CFG_RX_REF_SEL, x)
+
+#define SD_LANE_SD_LANE_CFG_LANE_RST BIT(8)
+#define SD_LANE_SD_LANE_CFG_LANE_RST_SET(x)\
+ FIELD_PREP(SD_LANE_SD_LANE_CFG_LANE_RST, x)
+#define SD_LANE_SD_LANE_CFG_LANE_RST_GET(x)\
+ FIELD_GET(SD_LANE_SD_LANE_CFG_LANE_RST, x)
+
+#define SD_LANE_SD_LANE_CFG_LANE_TX_RST BIT(9)
+#define SD_LANE_SD_LANE_CFG_LANE_TX_RST_SET(x)\
+ FIELD_PREP(SD_LANE_SD_LANE_CFG_LANE_TX_RST, x)
+#define SD_LANE_SD_LANE_CFG_LANE_TX_RST_GET(x)\
+ FIELD_GET(SD_LANE_SD_LANE_CFG_LANE_TX_RST, x)
+
+#define SD_LANE_SD_LANE_CFG_LANE_RX_RST BIT(10)
+#define SD_LANE_SD_LANE_CFG_LANE_RX_RST_SET(x)\
+ FIELD_PREP(SD_LANE_SD_LANE_CFG_LANE_RX_RST, x)
+#define SD_LANE_SD_LANE_CFG_LANE_RX_RST_GET(x)\
+ FIELD_GET(SD_LANE_SD_LANE_CFG_LANE_RX_RST, x)
+
+/* SD_LANE_TARGET:SD_LANE_CFG_STAT:SD_LANE_STAT */
+#define SD_LANE_SD_LANE_STAT(t) __REG(TARGET_SD_LANE, t, 25, 8, 0, 1, 8, 4, 0, 1, 4)
+
+#define SD_LANE_SD_LANE_STAT_PMA_RST_DONE BIT(0)
+#define SD_LANE_SD_LANE_STAT_PMA_RST_DONE_SET(x)\
+ FIELD_PREP(SD_LANE_SD_LANE_STAT_PMA_RST_DONE, x)
+#define SD_LANE_SD_LANE_STAT_PMA_RST_DONE_GET(x)\
+ FIELD_GET(SD_LANE_SD_LANE_STAT_PMA_RST_DONE, x)
+
+#define SD_LANE_SD_LANE_STAT_DFE_RST_DONE BIT(1)
+#define SD_LANE_SD_LANE_STAT_DFE_RST_DONE_SET(x)\
+ FIELD_PREP(SD_LANE_SD_LANE_STAT_DFE_RST_DONE, x)
+#define SD_LANE_SD_LANE_STAT_DFE_RST_DONE_GET(x)\
+ FIELD_GET(SD_LANE_SD_LANE_STAT_DFE_RST_DONE, x)
+
+#define SD_LANE_SD_LANE_STAT_DBG_OBS GENMASK(31, 16)
+#define SD_LANE_SD_LANE_STAT_DBG_OBS_SET(x)\
+ FIELD_PREP(SD_LANE_SD_LANE_STAT_DBG_OBS, x)
+#define SD_LANE_SD_LANE_STAT_DBG_OBS_GET(x)\
+ FIELD_GET(SD_LANE_SD_LANE_STAT_DBG_OBS, x)
+
+/* SD_LANE_TARGET:CFG_STAT_FX100:MISC */
+#define SD_LANE_MISC(t) __REG(TARGET_SD_LANE, t, 25, 56, 0, 1, 56, 0, 0, 1, 4)
+
+#define SD_LANE_MISC_SD_125_RST_DIS BIT(0)
+#define SD_LANE_MISC_SD_125_RST_DIS_SET(x)\
+ FIELD_PREP(SD_LANE_MISC_SD_125_RST_DIS, x)
+#define SD_LANE_MISC_SD_125_RST_DIS_GET(x)\
+ FIELD_GET(SD_LANE_MISC_SD_125_RST_DIS, x)
+
+#define SD_LANE_MISC_RX_ENA BIT(1)
+#define SD_LANE_MISC_RX_ENA_SET(x)\
+ FIELD_PREP(SD_LANE_MISC_RX_ENA, x)
+#define SD_LANE_MISC_RX_ENA_GET(x)\
+ FIELD_GET(SD_LANE_MISC_RX_ENA, x)
+
+#define SD_LANE_MISC_MUX_ENA BIT(2)
+#define SD_LANE_MISC_MUX_ENA_SET(x)\
+ FIELD_PREP(SD_LANE_MISC_MUX_ENA, x)
+#define SD_LANE_MISC_MUX_ENA_GET(x)\
+ FIELD_GET(SD_LANE_MISC_MUX_ENA, x)
+
+#define SD_LANE_MISC_CORE_CLK_FREQ GENMASK(5, 4)
+#define SD_LANE_MISC_CORE_CLK_FREQ_SET(x)\
+ FIELD_PREP(SD_LANE_MISC_CORE_CLK_FREQ, x)
+#define SD_LANE_MISC_CORE_CLK_FREQ_GET(x)\
+ FIELD_GET(SD_LANE_MISC_CORE_CLK_FREQ, x)
+
+/* SD_LANE_TARGET:CFG_STAT_FX100:M_STAT_MISC */
+#define SD_LANE_M_STAT_MISC(t) __REG(TARGET_SD_LANE, t, 25, 56, 0, 1, 56, 36, 0, 1, 4)
+
+#define SD_LANE_M_STAT_MISC_M_RIS_EDGE_PTR_ADJ_SUM GENMASK(21, 0)
+#define SD_LANE_M_STAT_MISC_M_RIS_EDGE_PTR_ADJ_SUM_SET(x)\
+ FIELD_PREP(SD_LANE_M_STAT_MISC_M_RIS_EDGE_PTR_ADJ_SUM, x)
+#define SD_LANE_M_STAT_MISC_M_RIS_EDGE_PTR_ADJ_SUM_GET(x)\
+ FIELD_GET(SD_LANE_M_STAT_MISC_M_RIS_EDGE_PTR_ADJ_SUM, x)
+
+#define SD_LANE_M_STAT_MISC_M_LOCK_CNT GENMASK(31, 24)
+#define SD_LANE_M_STAT_MISC_M_LOCK_CNT_SET(x)\
+ FIELD_PREP(SD_LANE_M_STAT_MISC_M_LOCK_CNT, x)
+#define SD_LANE_M_STAT_MISC_M_LOCK_CNT_GET(x)\
+ FIELD_GET(SD_LANE_M_STAT_MISC_M_LOCK_CNT, x)
+
+/* SD25G_CFG_TARGET:SD_RESET:SD_SER_RST */
+#define SD_LANE_25G_SD_SER_RST(t) __REG(TARGET_SD_LANE_25G, t, 8, 0, 0, 1, 8, 0, 0, 1, 4)
+
+#define SD_LANE_25G_SD_SER_RST_SER_RST BIT(0)
+#define SD_LANE_25G_SD_SER_RST_SER_RST_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_SER_RST_SER_RST, x)
+#define SD_LANE_25G_SD_SER_RST_SER_RST_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_SER_RST_SER_RST, x)
+
+/* SD25G_CFG_TARGET:SD_RESET:SD_DES_RST */
+#define SD_LANE_25G_SD_DES_RST(t) __REG(TARGET_SD_LANE_25G, t, 8, 0, 0, 1, 8, 4, 0, 1, 4)
+
+#define SD_LANE_25G_SD_DES_RST_DES_RST BIT(0)
+#define SD_LANE_25G_SD_DES_RST_DES_RST_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_DES_RST_DES_RST, x)
+#define SD_LANE_25G_SD_DES_RST_DES_RST_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_DES_RST_DES_RST, x)
+
+/* SD25G_CFG_TARGET:SD_LANE_CFG_STAT:SD_LANE_CFG */
+#define SD_LANE_25G_SD_LANE_CFG(t) __REG(TARGET_SD_LANE_25G, t, 8, 8, 0, 1, 12, 0, 0, 1, 4)
+
+#define SD_LANE_25G_SD_LANE_CFG_MACRO_RST BIT(0)
+#define SD_LANE_25G_SD_LANE_CFG_MACRO_RST_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG_MACRO_RST, x)
+#define SD_LANE_25G_SD_LANE_CFG_MACRO_RST_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG_MACRO_RST, x)
+
+#define SD_LANE_25G_SD_LANE_CFG_EXT_CFG_RST BIT(1)
+#define SD_LANE_25G_SD_LANE_CFG_EXT_CFG_RST_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG_EXT_CFG_RST, x)
+#define SD_LANE_25G_SD_LANE_CFG_EXT_CFG_RST_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG_EXT_CFG_RST, x)
+
+#define SD_LANE_25G_SD_LANE_CFG_HWT_MULTI_LANE_MODE BIT(4)
+#define SD_LANE_25G_SD_LANE_CFG_HWT_MULTI_LANE_MODE_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG_HWT_MULTI_LANE_MODE, x)
+#define SD_LANE_25G_SD_LANE_CFG_HWT_MULTI_LANE_MODE_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG_HWT_MULTI_LANE_MODE, x)
+
+#define SD_LANE_25G_SD_LANE_CFG_PCS2PMA_PHYMODE GENMASK(7, 5)
+#define SD_LANE_25G_SD_LANE_CFG_PCS2PMA_PHYMODE_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG_PCS2PMA_PHYMODE, x)
+#define SD_LANE_25G_SD_LANE_CFG_PCS2PMA_PHYMODE_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG_PCS2PMA_PHYMODE, x)
+
+#define SD_LANE_25G_SD_LANE_CFG_LANE_RST BIT(8)
+#define SD_LANE_25G_SD_LANE_CFG_LANE_RST_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG_LANE_RST, x)
+#define SD_LANE_25G_SD_LANE_CFG_LANE_RST_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG_LANE_RST, x)
+
+#define SD_LANE_25G_SD_LANE_CFG_PCS_EN_ADV BIT(9)
+#define SD_LANE_25G_SD_LANE_CFG_PCS_EN_ADV_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG_PCS_EN_ADV, x)
+#define SD_LANE_25G_SD_LANE_CFG_PCS_EN_ADV_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG_PCS_EN_ADV, x)
+
+#define SD_LANE_25G_SD_LANE_CFG_PCS_EN_MAIN BIT(10)
+#define SD_LANE_25G_SD_LANE_CFG_PCS_EN_MAIN_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG_PCS_EN_MAIN, x)
+#define SD_LANE_25G_SD_LANE_CFG_PCS_EN_MAIN_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG_PCS_EN_MAIN, x)
+
+#define SD_LANE_25G_SD_LANE_CFG_PCS_EN_DLY BIT(11)
+#define SD_LANE_25G_SD_LANE_CFG_PCS_EN_DLY_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG_PCS_EN_DLY, x)
+#define SD_LANE_25G_SD_LANE_CFG_PCS_EN_DLY_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG_PCS_EN_DLY, x)
+
+#define SD_LANE_25G_SD_LANE_CFG_PCS_TAP_ADV GENMASK(15, 12)
+#define SD_LANE_25G_SD_LANE_CFG_PCS_TAP_ADV_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG_PCS_TAP_ADV, x)
+#define SD_LANE_25G_SD_LANE_CFG_PCS_TAP_ADV_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG_PCS_TAP_ADV, x)
+
+#define SD_LANE_25G_SD_LANE_CFG_PCS_TAP_MAIN BIT(16)
+#define SD_LANE_25G_SD_LANE_CFG_PCS_TAP_MAIN_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG_PCS_TAP_MAIN, x)
+#define SD_LANE_25G_SD_LANE_CFG_PCS_TAP_MAIN_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG_PCS_TAP_MAIN, x)
+
+#define SD_LANE_25G_SD_LANE_CFG_PCS_TAP_DLY GENMASK(21, 17)
+#define SD_LANE_25G_SD_LANE_CFG_PCS_TAP_DLY_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG_PCS_TAP_DLY, x)
+#define SD_LANE_25G_SD_LANE_CFG_PCS_TAP_DLY_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG_PCS_TAP_DLY, x)
+
+#define SD_LANE_25G_SD_LANE_CFG_PCS_ISCAN_EN BIT(22)
+#define SD_LANE_25G_SD_LANE_CFG_PCS_ISCAN_EN_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG_PCS_ISCAN_EN, x)
+#define SD_LANE_25G_SD_LANE_CFG_PCS_ISCAN_EN_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG_PCS_ISCAN_EN, x)
+
+#define SD_LANE_25G_SD_LANE_CFG_PCS_EN_FAST_ISCAN BIT(23)
+#define SD_LANE_25G_SD_LANE_CFG_PCS_EN_FAST_ISCAN_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG_PCS_EN_FAST_ISCAN, x)
+#define SD_LANE_25G_SD_LANE_CFG_PCS_EN_FAST_ISCAN_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG_PCS_EN_FAST_ISCAN, x)
+
+#define SD_LANE_25G_SD_LANE_CFG_PCS2PMA_TXSWING BIT(24)
+#define SD_LANE_25G_SD_LANE_CFG_PCS2PMA_TXSWING_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG_PCS2PMA_TXSWING, x)
+#define SD_LANE_25G_SD_LANE_CFG_PCS2PMA_TXSWING_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG_PCS2PMA_TXSWING, x)
+
+#define SD_LANE_25G_SD_LANE_CFG_PCS2PMA_TXEI BIT(25)
+#define SD_LANE_25G_SD_LANE_CFG_PCS2PMA_TXEI_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG_PCS2PMA_TXEI, x)
+#define SD_LANE_25G_SD_LANE_CFG_PCS2PMA_TXEI_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG_PCS2PMA_TXEI, x)
+
+#define SD_LANE_25G_SD_LANE_CFG_PCS2PMA_TXMARGIN GENMASK(28, 26)
+#define SD_LANE_25G_SD_LANE_CFG_PCS2PMA_TXMARGIN_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG_PCS2PMA_TXMARGIN, x)
+#define SD_LANE_25G_SD_LANE_CFG_PCS2PMA_TXMARGIN_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG_PCS2PMA_TXMARGIN, x)
+
+/* SD25G_CFG_TARGET:SD_LANE_CFG_STAT:SD_LANE_CFG2 */
+#define SD_LANE_25G_SD_LANE_CFG2(t) __REG(TARGET_SD_LANE_25G, t, 8, 8, 0, 1, 12, 4, 0, 1, 4)
+
+#define SD_LANE_25G_SD_LANE_CFG2_DATA_WIDTH_SEL GENMASK(2, 0)
+#define SD_LANE_25G_SD_LANE_CFG2_DATA_WIDTH_SEL_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG2_DATA_WIDTH_SEL, x)
+#define SD_LANE_25G_SD_LANE_CFG2_DATA_WIDTH_SEL_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG2_DATA_WIDTH_SEL, x)
+
+#define SD_LANE_25G_SD_LANE_CFG2_PMA_TXCK_SEL GENMASK(5, 3)
+#define SD_LANE_25G_SD_LANE_CFG2_PMA_TXCK_SEL_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG2_PMA_TXCK_SEL, x)
+#define SD_LANE_25G_SD_LANE_CFG2_PMA_TXCK_SEL_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG2_PMA_TXCK_SEL, x)
+
+#define SD_LANE_25G_SD_LANE_CFG2_PMA_RXDIV_SEL GENMASK(8, 6)
+#define SD_LANE_25G_SD_LANE_CFG2_PMA_RXDIV_SEL_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG2_PMA_RXDIV_SEL, x)
+#define SD_LANE_25G_SD_LANE_CFG2_PMA_RXDIV_SEL_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG2_PMA_RXDIV_SEL, x)
+
+#define SD_LANE_25G_SD_LANE_CFG2_PCS2PMA_TX_SPEED GENMASK(10, 9)
+#define SD_LANE_25G_SD_LANE_CFG2_PCS2PMA_TX_SPEED_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG2_PCS2PMA_TX_SPEED, x)
+#define SD_LANE_25G_SD_LANE_CFG2_PCS2PMA_TX_SPEED_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG2_PCS2PMA_TX_SPEED, x)
+
+#define SD_LANE_25G_SD_LANE_CFG2_TXFIFO_CK_DIV GENMASK(13, 11)
+#define SD_LANE_25G_SD_LANE_CFG2_TXFIFO_CK_DIV_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG2_TXFIFO_CK_DIV, x)
+#define SD_LANE_25G_SD_LANE_CFG2_TXFIFO_CK_DIV_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG2_TXFIFO_CK_DIV, x)
+
+#define SD_LANE_25G_SD_LANE_CFG2_RXFIFO_CK_DIV GENMASK(16, 14)
+#define SD_LANE_25G_SD_LANE_CFG2_RXFIFO_CK_DIV_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG2_RXFIFO_CK_DIV, x)
+#define SD_LANE_25G_SD_LANE_CFG2_RXFIFO_CK_DIV_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG2_RXFIFO_CK_DIV, x)
+
+#define SD_LANE_25G_SD_LANE_CFG2_HWT_VCO_DIV_SEL GENMASK(19, 17)
+#define SD_LANE_25G_SD_LANE_CFG2_HWT_VCO_DIV_SEL_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG2_HWT_VCO_DIV_SEL, x)
+#define SD_LANE_25G_SD_LANE_CFG2_HWT_VCO_DIV_SEL_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG2_HWT_VCO_DIV_SEL, x)
+
+#define SD_LANE_25G_SD_LANE_CFG2_HWT_CFG_SEL_DIV GENMASK(23, 20)
+#define SD_LANE_25G_SD_LANE_CFG2_HWT_CFG_SEL_DIV_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG2_HWT_CFG_SEL_DIV, x)
+#define SD_LANE_25G_SD_LANE_CFG2_HWT_CFG_SEL_DIV_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG2_HWT_CFG_SEL_DIV, x)
+
+#define SD_LANE_25G_SD_LANE_CFG2_HWT_PRE_DIVSEL GENMASK(25, 24)
+#define SD_LANE_25G_SD_LANE_CFG2_HWT_PRE_DIVSEL_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG2_HWT_PRE_DIVSEL, x)
+#define SD_LANE_25G_SD_LANE_CFG2_HWT_PRE_DIVSEL_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG2_HWT_PRE_DIVSEL, x)
+
+#define SD_LANE_25G_SD_LANE_CFG2_TXRATE_SEL GENMASK(28, 26)
+#define SD_LANE_25G_SD_LANE_CFG2_TXRATE_SEL_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG2_TXRATE_SEL, x)
+#define SD_LANE_25G_SD_LANE_CFG2_TXRATE_SEL_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG2_TXRATE_SEL, x)
+
+#define SD_LANE_25G_SD_LANE_CFG2_RXRATE_SEL GENMASK(31, 29)
+#define SD_LANE_25G_SD_LANE_CFG2_RXRATE_SEL_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_CFG2_RXRATE_SEL, x)
+#define SD_LANE_25G_SD_LANE_CFG2_RXRATE_SEL_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_CFG2_RXRATE_SEL, x)
+
+/* SD25G_CFG_TARGET:SD_LANE_CFG_STAT:SD_LANE_STAT */
+#define SD_LANE_25G_SD_LANE_STAT(t) __REG(TARGET_SD_LANE_25G, t, 8, 8, 0, 1, 12, 8, 0, 1, 4)
+
+#define SD_LANE_25G_SD_LANE_STAT_PMA_RST_DONE BIT(0)
+#define SD_LANE_25G_SD_LANE_STAT_PMA_RST_DONE_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_STAT_PMA_RST_DONE, x)
+#define SD_LANE_25G_SD_LANE_STAT_PMA_RST_DONE_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_STAT_PMA_RST_DONE, x)
+
+#define SD_LANE_25G_SD_LANE_STAT_LANE_RST_DONE BIT(1)
+#define SD_LANE_25G_SD_LANE_STAT_LANE_RST_DONE_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_STAT_LANE_RST_DONE, x)
+#define SD_LANE_25G_SD_LANE_STAT_LANE_RST_DONE_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_STAT_LANE_RST_DONE, x)
+
+#define SD_LANE_25G_SD_LANE_STAT_DBG_OBS GENMASK(31, 16)
+#define SD_LANE_25G_SD_LANE_STAT_DBG_OBS_SET(x)\
+ FIELD_PREP(SD_LANE_25G_SD_LANE_STAT_DBG_OBS, x)
+#define SD_LANE_25G_SD_LANE_STAT_DBG_OBS_GET(x)\
+ FIELD_GET(SD_LANE_25G_SD_LANE_STAT_DBG_OBS, x)
+
+#endif /* _SPARX5_SERDES_REGS_H_ */
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index 71cb10826326..ccb575b13777 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -373,6 +373,36 @@ int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode)
}
EXPORT_SYMBOL_GPL(phy_set_mode_ext);
+int phy_set_media(struct phy *phy, enum phy_media media)
+{
+ int ret;
+
+ if (!phy || !phy->ops->set_media)
+ return 0;
+
+ mutex_lock(&phy->mutex);
+ ret = phy->ops->set_media(phy, media);
+ mutex_unlock(&phy->mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(phy_set_media);
+
+int phy_set_speed(struct phy *phy, int speed)
+{
+ int ret;
+
+ if (!phy || !phy->ops->set_speed)
+ return 0;
+
+ mutex_lock(&phy->mutex);
+ ret = phy->ops->set_speed(phy, speed);
+ mutex_unlock(&phy->mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(phy_set_speed);
+
int phy_reset(struct phy *phy)
{
int ret;
diff --git a/drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c b/drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c
index 9061ece7ff6a..bfff0c8c9130 100644
--- a/drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c
+++ b/drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c
@@ -276,8 +276,8 @@ static int qcom_ipq806x_usb_hs_phy_init(struct phy *phy)
val = HSUSB_CTRL_DPSEHV_CLAMP | HSUSB_CTRL_DMSEHV_CLAMP |
HSUSB_CTRL_RETENABLEN | HSUSB_CTRL_COMMONONN |
HSUSB_CTRL_OTGSESSVLD_CLAMP | HSUSB_CTRL_ID_HV_CLAMP |
- HSUSB_CTRL_DPSEHV_CLAMP | HSUSB_CTRL_UTMI_OTG_VBUS_VALID |
- HSUSB_CTRL_UTMI_CLK_EN | HSUSB_CTRL_CLAMP_EN | 0x70;
+ HSUSB_CTRL_UTMI_OTG_VBUS_VALID | HSUSB_CTRL_UTMI_CLK_EN |
+ HSUSB_CTRL_CLAMP_EN | 0x70;
/* use core clock if external reference is not present */
if (!phy_dwc3->xo_clk)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 9cdebe7f26cb..7877f70cf86f 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -1840,6 +1840,86 @@ static const struct qmp_phy_init_tbl sm8250_usb3_uniphy_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
};
+static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SVS_MODE_CLK_SEL, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x3b),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYS_CLK_CTRL, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x30),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_CONFIG, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_BG_TIMER, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE0, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_CTRL, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN, 0x17),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORE_CLK_EN, 0x1f),
+};
+
+static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_rbr[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x69),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x80),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x6f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x04),
+};
+
+static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_hbr[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x69),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x80),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0e),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x08),
+};
+
+static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_hbr2[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x8c),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x1c),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x08),
+};
+
+static const struct qmp_phy_init_tbl qmp_v4_dp_serdes_tbl_hbr3[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x69),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0x80),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x2f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x2a),
+ QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x08),
+};
+
+static const struct qmp_phy_init_tbl qmp_v4_dp_tx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_VMODE_CTRL1, 0x40),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_PRE_STALL_LDO_BOOST_EN, 0x30),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_INTERFACE_SELECT, 0x3b),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_CLKBUF_ENABLE, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_RESET_TSYNC_EN, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_INTERFACE_MODE, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x11),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_BAND, 0x4),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_POL_INV, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_DRV_LVL, 0x2a),
+ QMP_PHY_INIT_CFG(QSERDES_V4_TX_TX_EMP_POST1_LVL, 0x20),
+};
+
static const struct qmp_phy_init_tbl sm8250_qmp_pcie_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08),
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34),
@@ -2268,6 +2348,8 @@ static const struct qmp_phy_init_tbl sm8350_usb3_uniphy_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
};
+struct qmp_phy;
+
/* struct qmp_phy_cfg - per-PHY initialization config */
struct qmp_phy_cfg {
/* phy-type - PCIE/UFS/USB */
@@ -2307,6 +2389,12 @@ struct qmp_phy_cfg {
const struct qmp_phy_init_tbl *serdes_tbl_hbr3;
int serdes_tbl_hbr3_num;
+ /* DP PHY callbacks */
+ int (*configure_dp_phy)(struct qmp_phy *qphy);
+ void (*configure_dp_tx)(struct qmp_phy *qphy);
+ int (*calibrate_dp_phy)(struct qmp_phy *qphy);
+ void (*dp_aux_init)(struct qmp_phy *qphy);
+
/* clock ids to be requested */
const char * const *clk_list;
int num_clks;
@@ -2423,6 +2511,16 @@ struct qcom_qmp {
struct reset_control *ufs_reset;
};
+static void qcom_qmp_v3_phy_dp_aux_init(struct qmp_phy *qphy);
+static void qcom_qmp_v3_phy_configure_dp_tx(struct qmp_phy *qphy);
+static int qcom_qmp_v3_phy_configure_dp_phy(struct qmp_phy *qphy);
+static int qcom_qmp_v3_dp_phy_calibrate(struct qmp_phy *qphy);
+
+static void qcom_qmp_v4_phy_dp_aux_init(struct qmp_phy *qphy);
+static void qcom_qmp_v4_phy_configure_dp_tx(struct qmp_phy *qphy);
+static int qcom_qmp_v4_phy_configure_dp_phy(struct qmp_phy *qphy);
+static int qcom_qmp_v4_dp_phy_calibrate(struct qmp_phy *qphy);
+
static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
{
u32 reg;
@@ -2871,6 +2969,11 @@ static const struct qmp_phy_cfg sc7180_dpphy_cfg = {
.has_phy_dp_com_ctrl = true,
.is_dual_lane_phy = true,
+
+ .dp_aux_init = qcom_qmp_v3_phy_dp_aux_init,
+ .configure_dp_tx = qcom_qmp_v3_phy_configure_dp_tx,
+ .configure_dp_phy = qcom_qmp_v3_phy_configure_dp_phy,
+ .calibrate_dp_phy = qcom_qmp_v3_dp_phy_calibrate,
};
static const struct qmp_phy_combo_cfg sc7180_usb3dpphy_cfg = {
@@ -3123,6 +3226,46 @@ static const struct qmp_phy_cfg sm8250_usb3_uniphy_cfg = {
.pwrdn_delay_max = POWER_DOWN_DELAY_US_MAX,
};
+static const struct qmp_phy_cfg sm8250_dpphy_cfg = {
+ .type = PHY_TYPE_DP,
+ .nlanes = 1,
+
+ .serdes_tbl = qmp_v4_dp_serdes_tbl,
+ .serdes_tbl_num = ARRAY_SIZE(qmp_v4_dp_serdes_tbl),
+ .tx_tbl = qmp_v4_dp_tx_tbl,
+ .tx_tbl_num = ARRAY_SIZE(qmp_v4_dp_tx_tbl),
+
+ .serdes_tbl_rbr = qmp_v4_dp_serdes_tbl_rbr,
+ .serdes_tbl_rbr_num = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_rbr),
+ .serdes_tbl_hbr = qmp_v4_dp_serdes_tbl_hbr,
+ .serdes_tbl_hbr_num = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr),
+ .serdes_tbl_hbr2 = qmp_v4_dp_serdes_tbl_hbr2,
+ .serdes_tbl_hbr2_num = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr2),
+ .serdes_tbl_hbr3 = qmp_v4_dp_serdes_tbl_hbr3,
+ .serdes_tbl_hbr3_num = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr3),
+
+ .clk_list = qmp_v4_phy_clk_l,
+ .num_clks = ARRAY_SIZE(qmp_v4_phy_clk_l),
+ .reset_list = msm8996_usb3phy_reset_l,
+ .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
+ .vreg_list = qmp_phy_vreg_l,
+ .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
+ .regs = qmp_v4_usb3phy_regs_layout,
+
+ .has_phy_dp_com_ctrl = true,
+ .is_dual_lane_phy = true,
+
+ .dp_aux_init = qcom_qmp_v4_phy_dp_aux_init,
+ .configure_dp_tx = qcom_qmp_v4_phy_configure_dp_tx,
+ .configure_dp_phy = qcom_qmp_v4_phy_configure_dp_phy,
+ .calibrate_dp_phy = qcom_qmp_v4_dp_phy_calibrate,
+};
+
+static const struct qmp_phy_combo_cfg sm8250_usb3dpphy_cfg = {
+ .usb_cfg = &sm8250_usb3phy_cfg,
+ .dp_cfg = &sm8250_dpphy_cfg,
+};
+
static const struct qmp_phy_cfg sdx55_usb3_uniphy_cfg = {
.type = PHY_TYPE_USB3,
.nlanes = 1,
@@ -3332,24 +3475,24 @@ static int qcom_qmp_phy_serdes_init(struct qmp_phy *qphy)
return 0;
}
-static void qcom_qmp_phy_dp_aux_init(struct qmp_phy *qphy)
+static void qcom_qmp_v3_phy_dp_aux_init(struct qmp_phy *qphy)
{
writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
- qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL);
+ qphy->pcs + QSERDES_DP_PHY_PD_CTL);
/* Turn on BIAS current for PHY/PLL */
writel(QSERDES_V3_COM_BIAS_EN | QSERDES_V3_COM_BIAS_EN_MUX |
QSERDES_V3_COM_CLKBUF_L_EN | QSERDES_V3_COM_EN_SYSCLK_TX_SEL,
qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN);
- writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL);
+ writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
DP_PHY_PD_CTL_LANE_0_1_PWRDN |
DP_PHY_PD_CTL_LANE_2_3_PWRDN | DP_PHY_PD_CTL_PLL_PWRDN |
DP_PHY_PD_CTL_DP_CLAMP_EN,
- qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL);
+ qphy->pcs + QSERDES_DP_PHY_PD_CTL);
writel(QSERDES_V3_COM_BIAS_EN |
QSERDES_V3_COM_BIAS_EN_MUX | QSERDES_V3_COM_CLKBUF_R_EN |
@@ -3357,16 +3500,16 @@ static void qcom_qmp_phy_dp_aux_init(struct qmp_phy *qphy)
QSERDES_V3_COM_CLKBUF_RX_DRIVE_L,
qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN);
- writel(0x00, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG0);
- writel(0x13, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG1);
- writel(0x24, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG2);
- writel(0x00, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG3);
- writel(0x0a, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG4);
- writel(0x26, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG5);
- writel(0x0a, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG6);
- writel(0x03, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG7);
- writel(0xbb, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG8);
- writel(0x03, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG9);
+ writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG0);
+ writel(0x13, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
+ writel(0x24, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
+ writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG3);
+ writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG4);
+ writel(0x26, qphy->pcs + QSERDES_DP_PHY_AUX_CFG5);
+ writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG6);
+ writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG7);
+ writel(0xbb, qphy->pcs + QSERDES_DP_PHY_AUX_CFG8);
+ writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG9);
qphy->dp_aux_cfg = 0;
writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
@@ -3375,6 +3518,20 @@ static void qcom_qmp_phy_dp_aux_init(struct qmp_phy *qphy)
qphy->pcs + QSERDES_V3_DP_PHY_AUX_INTERRUPT_MASK);
}
+static const u8 qmp_dp_v3_pre_emphasis_hbr3_hbr2[4][4] = {
+ { 0x00, 0x0c, 0x15, 0x1a },
+ { 0x02, 0x0e, 0x16, 0xff },
+ { 0x02, 0x11, 0xff, 0xff },
+ { 0x04, 0xff, 0xff, 0xff }
+};
+
+static const u8 qmp_dp_v3_voltage_swing_hbr3_hbr2[4][4] = {
+ { 0x02, 0x12, 0x16, 0x1a },
+ { 0x09, 0x19, 0x1f, 0xff },
+ { 0x10, 0x1f, 0xff, 0xff },
+ { 0x1f, 0xff, 0xff, 0xff }
+};
+
static const u8 qmp_dp_v3_pre_emphasis_hbr_rbr[4][4] = {
{ 0x00, 0x0c, 0x14, 0x19 },
{ 0x00, 0x0b, 0x12, 0xff },
@@ -3389,11 +3546,11 @@ static const u8 qmp_dp_v3_voltage_swing_hbr_rbr[4][4] = {
{ 0x1f, 0xff, 0xff, 0xff }
};
-static void qcom_qmp_phy_configure_dp_tx(struct qmp_phy *qphy)
+static int qcom_qmp_phy_configure_dp_swing(struct qmp_phy *qphy,
+ unsigned int drv_lvl_reg, unsigned int emp_post_reg)
{
const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
unsigned int v_level = 0, p_level = 0;
- u32 bias_en, drvr_en;
u8 voltage_swing_cfg, pre_emphasis_cfg;
int i;
@@ -3402,56 +3559,58 @@ static void qcom_qmp_phy_configure_dp_tx(struct qmp_phy *qphy)
p_level = max(p_level, dp_opts->pre[i]);
}
- if (dp_opts->lanes == 1) {
- bias_en = 0x3e;
- drvr_en = 0x13;
+ if (dp_opts->link_rate <= 2700) {
+ voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr_rbr[v_level][p_level];
+ pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr_rbr[v_level][p_level];
} else {
- bias_en = 0x3f;
- drvr_en = 0x10;
+ voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr3_hbr2[v_level][p_level];
+ pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr3_hbr2[v_level][p_level];
}
- voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr_rbr[v_level][p_level];
- pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr_rbr[v_level][p_level];
-
/* TODO: Move check to config check */
if (voltage_swing_cfg == 0xFF && pre_emphasis_cfg == 0xFF)
- return;
+ return -EINVAL;
/* Enable MUX to use Cursor values from these registers */
voltage_swing_cfg |= DP_PHY_TXn_TX_DRV_LVL_MUX_EN;
pre_emphasis_cfg |= DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN;
- writel(voltage_swing_cfg, qphy->tx + QSERDES_V3_TX_TX_DRV_LVL);
- writel(pre_emphasis_cfg, qphy->tx + QSERDES_V3_TX_TX_EMP_POST1_LVL);
- writel(voltage_swing_cfg, qphy->tx2 + QSERDES_V3_TX_TX_DRV_LVL);
- writel(pre_emphasis_cfg, qphy->tx2 + QSERDES_V3_TX_TX_EMP_POST1_LVL);
+ writel(voltage_swing_cfg, qphy->tx + drv_lvl_reg);
+ writel(pre_emphasis_cfg, qphy->tx + emp_post_reg);
+ writel(voltage_swing_cfg, qphy->tx2 + drv_lvl_reg);
+ writel(pre_emphasis_cfg, qphy->tx2 + emp_post_reg);
- writel(drvr_en, qphy->tx + QSERDES_V3_TX_HIGHZ_DRVR_EN);
- writel(bias_en, qphy->tx + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
- writel(drvr_en, qphy->tx2 + QSERDES_V3_TX_HIGHZ_DRVR_EN);
- writel(bias_en, qphy->tx2 + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
+ return 0;
}
-static int qcom_qmp_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
+static void qcom_qmp_v3_phy_configure_dp_tx(struct qmp_phy *qphy)
{
- const struct phy_configure_opts_dp *dp_opts = &opts->dp;
- struct qmp_phy *qphy = phy_get_drvdata(phy);
+ const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
+ u32 bias_en, drvr_en;
- memcpy(&qphy->dp_opts, dp_opts, sizeof(*dp_opts));
- if (qphy->dp_opts.set_voltages) {
- qcom_qmp_phy_configure_dp_tx(qphy);
- qphy->dp_opts.set_voltages = 0;
+ if (qcom_qmp_phy_configure_dp_swing(qphy,
+ QSERDES_V3_TX_TX_DRV_LVL,
+ QSERDES_V3_TX_TX_EMP_POST1_LVL) < 0)
+ return;
+
+ if (dp_opts->lanes == 1) {
+ bias_en = 0x3e;
+ drvr_en = 0x13;
+ } else {
+ bias_en = 0x3f;
+ drvr_en = 0x10;
}
- return 0;
+ writel(drvr_en, qphy->tx + QSERDES_V3_TX_HIGHZ_DRVR_EN);
+ writel(bias_en, qphy->tx + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
+ writel(drvr_en, qphy->tx2 + QSERDES_V3_TX_HIGHZ_DRVR_EN);
+ writel(bias_en, qphy->tx2 + QSERDES_V3_TX_TRANSCEIVER_BIAS_EN);
}
-static int qcom_qmp_phy_configure_dp_phy(struct qmp_phy *qphy)
+static bool qcom_qmp_phy_configure_dp_mode(struct qmp_phy *qphy)
{
- const struct qmp_phy_dp_clks *dp_clks = qphy->dp_clks;
- const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
- u32 val, phy_vco_div, status;
- unsigned long pixel_freq;
+ u32 val;
+ bool reverse = false;
val = DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN;
@@ -3471,9 +3630,22 @@ static int qcom_qmp_phy_configure_dp_phy(struct qmp_phy *qphy)
* writel(0x4c, qphy->pcs + QSERDES_V3_DP_PHY_MODE);
*/
val |= DP_PHY_PD_CTL_LANE_2_3_PWRDN;
- writel(val, qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL);
+ writel(val, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
+
+ writel(0x5c, qphy->pcs + QSERDES_DP_PHY_MODE);
+
+ return reverse;
+}
+
+static int qcom_qmp_v3_phy_configure_dp_phy(struct qmp_phy *qphy)
+{
+ const struct qmp_phy_dp_clks *dp_clks = qphy->dp_clks;
+ const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
+ u32 phy_vco_div, status;
+ unsigned long pixel_freq;
+
+ qcom_qmp_phy_configure_dp_mode(qphy);
- writel(0x5c, qphy->pcs + QSERDES_V3_DP_PHY_MODE);
writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL);
writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL);
@@ -3503,11 +3675,11 @@ static int qcom_qmp_phy_configure_dp_phy(struct qmp_phy *qphy)
clk_set_rate(dp_clks->dp_link_hw.clk, dp_opts->link_rate * 100000);
clk_set_rate(dp_clks->dp_pixel_hw.clk, pixel_freq);
- writel(0x04, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG2);
- writel(0x01, qphy->pcs + QSERDES_V3_DP_PHY_CFG);
- writel(0x05, qphy->pcs + QSERDES_V3_DP_PHY_CFG);
- writel(0x01, qphy->pcs + QSERDES_V3_DP_PHY_CFG);
- writel(0x09, qphy->pcs + QSERDES_V3_DP_PHY_CFG);
+ writel(0x04, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
+ writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
+ writel(0x05, qphy->pcs + QSERDES_DP_PHY_CFG);
+ writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
+ writel(0x09, qphy->pcs + QSERDES_DP_PHY_CFG);
writel(0x20, qphy->serdes + QSERDES_V3_COM_RESETSM_CNTRL);
@@ -3518,7 +3690,7 @@ static int qcom_qmp_phy_configure_dp_phy(struct qmp_phy *qphy)
10000))
return -ETIMEDOUT;
- writel(0x19, qphy->pcs + QSERDES_V3_DP_PHY_CFG);
+ writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
if (readl_poll_timeout(qphy->pcs + QSERDES_V3_DP_PHY_STATUS,
status,
@@ -3527,9 +3699,9 @@ static int qcom_qmp_phy_configure_dp_phy(struct qmp_phy *qphy)
10000))
return -ETIMEDOUT;
- writel(0x18, qphy->pcs + QSERDES_V3_DP_PHY_CFG);
+ writel(0x18, qphy->pcs + QSERDES_DP_PHY_CFG);
udelay(2000);
- writel(0x19, qphy->pcs + QSERDES_V3_DP_PHY_CFG);
+ writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
return readl_poll_timeout(qphy->pcs + QSERDES_V3_DP_PHY_STATUS,
status,
@@ -3542,9 +3714,8 @@ static int qcom_qmp_phy_configure_dp_phy(struct qmp_phy *qphy)
* We need to calibrate the aux setting here as many times
* as the caller tries
*/
-static int qcom_qmp_dp_phy_calibrate(struct phy *phy)
+static int qcom_qmp_v3_dp_phy_calibrate(struct qmp_phy *qphy)
{
- struct qmp_phy *qphy = phy_get_drvdata(phy);
static const u8 cfg1_settings[] = { 0x13, 0x23, 0x1d };
u8 val;
@@ -3552,7 +3723,231 @@ static int qcom_qmp_dp_phy_calibrate(struct phy *phy)
qphy->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings);
val = cfg1_settings[qphy->dp_aux_cfg];
- writel(val, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG1);
+ writel(val, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
+
+ return 0;
+}
+
+static void qcom_qmp_v4_phy_dp_aux_init(struct qmp_phy *qphy)
+{
+ writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_PSR_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
+ DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
+ qphy->pcs + QSERDES_DP_PHY_PD_CTL);
+
+ /* Turn on BIAS current for PHY/PLL */
+ writel(0x17, qphy->serdes + QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN);
+
+ writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG0);
+ writel(0x13, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
+ writel(0xa4, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
+ writel(0x00, qphy->pcs + QSERDES_DP_PHY_AUX_CFG3);
+ writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG4);
+ writel(0x26, qphy->pcs + QSERDES_DP_PHY_AUX_CFG5);
+ writel(0x0a, qphy->pcs + QSERDES_DP_PHY_AUX_CFG6);
+ writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG7);
+ writel(0xb7, qphy->pcs + QSERDES_DP_PHY_AUX_CFG8);
+ writel(0x03, qphy->pcs + QSERDES_DP_PHY_AUX_CFG9);
+ qphy->dp_aux_cfg = 0;
+
+ writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
+ PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
+ PHY_AUX_REQ_ERR_MASK,
+ qphy->pcs + QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK);
+}
+
+static void qcom_qmp_v4_phy_configure_dp_tx(struct qmp_phy *qphy)
+{
+ /* Program default values before writing proper values */
+ writel(0x27, qphy->tx + QSERDES_V4_TX_TX_DRV_LVL);
+ writel(0x27, qphy->tx2 + QSERDES_V4_TX_TX_DRV_LVL);
+
+ writel(0x20, qphy->tx + QSERDES_V4_TX_TX_EMP_POST1_LVL);
+ writel(0x20, qphy->tx2 + QSERDES_V4_TX_TX_EMP_POST1_LVL);
+
+ qcom_qmp_phy_configure_dp_swing(qphy,
+ QSERDES_V4_TX_TX_DRV_LVL,
+ QSERDES_V4_TX_TX_EMP_POST1_LVL);
+}
+
+static int qcom_qmp_v4_phy_configure_dp_phy(struct qmp_phy *qphy)
+{
+ const struct qmp_phy_dp_clks *dp_clks = qphy->dp_clks;
+ const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
+ u32 phy_vco_div, status;
+ unsigned long pixel_freq;
+ u32 bias0_en, drvr0_en, bias1_en, drvr1_en;
+ bool reverse;
+
+ writel(0x0f, qphy->pcs + QSERDES_V4_DP_PHY_CFG_1);
+
+ reverse = qcom_qmp_phy_configure_dp_mode(qphy);
+
+ writel(0x13, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
+ writel(0xa4, qphy->pcs + QSERDES_DP_PHY_AUX_CFG2);
+
+ writel(0x05, qphy->pcs + QSERDES_V4_DP_PHY_TX0_TX1_LANE_CTL);
+ writel(0x05, qphy->pcs + QSERDES_V4_DP_PHY_TX2_TX3_LANE_CTL);
+
+ switch (dp_opts->link_rate) {
+ case 1620:
+ phy_vco_div = 0x1;
+ pixel_freq = 1620000000UL / 2;
+ break;
+ case 2700:
+ phy_vco_div = 0x1;
+ pixel_freq = 2700000000UL / 2;
+ break;
+ case 5400:
+ phy_vco_div = 0x2;
+ pixel_freq = 5400000000UL / 4;
+ break;
+ case 8100:
+ phy_vco_div = 0x0;
+ pixel_freq = 8100000000UL / 6;
+ break;
+ default:
+ /* Other link rates aren't supported */
+ return -EINVAL;
+ }
+ writel(phy_vco_div, qphy->pcs + QSERDES_V4_DP_PHY_VCO_DIV);
+
+ clk_set_rate(dp_clks->dp_link_hw.clk, dp_opts->link_rate * 100000);
+ clk_set_rate(dp_clks->dp_pixel_hw.clk, pixel_freq);
+
+ writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
+ writel(0x05, qphy->pcs + QSERDES_DP_PHY_CFG);
+ writel(0x01, qphy->pcs + QSERDES_DP_PHY_CFG);
+ writel(0x09, qphy->pcs + QSERDES_DP_PHY_CFG);
+
+ writel(0x20, qphy->serdes + QSERDES_V4_COM_RESETSM_CNTRL);
+
+ if (readl_poll_timeout(qphy->serdes + QSERDES_V4_COM_C_READY_STATUS,
+ status,
+ ((status & BIT(0)) > 0),
+ 500,
+ 10000))
+ return -ETIMEDOUT;
+
+ if (readl_poll_timeout(qphy->serdes + QSERDES_V4_COM_CMN_STATUS,
+ status,
+ ((status & BIT(0)) > 0),
+ 500,
+ 10000))
+ return -ETIMEDOUT;
+
+ if (readl_poll_timeout(qphy->serdes + QSERDES_V4_COM_CMN_STATUS,
+ status,
+ ((status & BIT(1)) > 0),
+ 500,
+ 10000))
+ return -ETIMEDOUT;
+
+ writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
+
+ if (readl_poll_timeout(qphy->pcs + QSERDES_V4_DP_PHY_STATUS,
+ status,
+ ((status & BIT(0)) > 0),
+ 500,
+ 10000))
+ return -ETIMEDOUT;
+
+ if (readl_poll_timeout(qphy->pcs + QSERDES_V4_DP_PHY_STATUS,
+ status,
+ ((status & BIT(1)) > 0),
+ 500,
+ 10000))
+ return -ETIMEDOUT;
+
+ /*
+ * At least for 7nm DP PHY this has to be done after enabling link
+ * clock.
+ */
+
+ if (dp_opts->lanes == 1) {
+ bias0_en = reverse ? 0x3e : 0x15;
+ bias1_en = reverse ? 0x15 : 0x3e;
+ drvr0_en = reverse ? 0x13 : 0x10;
+ drvr1_en = reverse ? 0x10 : 0x13;
+ } else if (dp_opts->lanes == 2) {
+ bias0_en = reverse ? 0x3f : 0x15;
+ bias1_en = reverse ? 0x15 : 0x3f;
+ drvr0_en = 0x10;
+ drvr1_en = 0x10;
+ } else {
+ bias0_en = 0x3f;
+ bias1_en = 0x3f;
+ drvr0_en = 0x10;
+ drvr1_en = 0x10;
+ }
+
+ writel(drvr0_en, qphy->tx + QSERDES_V4_TX_HIGHZ_DRVR_EN);
+ writel(bias0_en, qphy->tx + QSERDES_V4_TX_TRANSCEIVER_BIAS_EN);
+ writel(drvr1_en, qphy->tx2 + QSERDES_V4_TX_HIGHZ_DRVR_EN);
+ writel(bias1_en, qphy->tx2 + QSERDES_V4_TX_TRANSCEIVER_BIAS_EN);
+
+ writel(0x18, qphy->pcs + QSERDES_DP_PHY_CFG);
+ udelay(2000);
+ writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
+
+ if (readl_poll_timeout(qphy->pcs + QSERDES_V4_DP_PHY_STATUS,
+ status,
+ ((status & BIT(1)) > 0),
+ 500,
+ 10000))
+ return -ETIMEDOUT;
+
+ writel(0x0a, qphy->tx + QSERDES_V4_TX_TX_POL_INV);
+ writel(0x0a, qphy->tx2 + QSERDES_V4_TX_TX_POL_INV);
+
+ writel(0x27, qphy->tx + QSERDES_V4_TX_TX_DRV_LVL);
+ writel(0x27, qphy->tx2 + QSERDES_V4_TX_TX_DRV_LVL);
+
+ writel(0x20, qphy->tx + QSERDES_V4_TX_TX_EMP_POST1_LVL);
+ writel(0x20, qphy->tx2 + QSERDES_V4_TX_TX_EMP_POST1_LVL);
+
+ return 0;
+}
+
+/*
+ * We need to calibrate the aux setting here as many times
+ * as the caller tries
+ */
+static int qcom_qmp_v4_dp_phy_calibrate(struct qmp_phy *qphy)
+{
+ static const u8 cfg1_settings[] = { 0x20, 0x13, 0x23, 0x1d };
+ u8 val;
+
+ qphy->dp_aux_cfg++;
+ qphy->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings);
+ val = cfg1_settings[qphy->dp_aux_cfg];
+
+ writel(val, qphy->pcs + QSERDES_DP_PHY_AUX_CFG1);
+
+ return 0;
+}
+
+static int qcom_qmp_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
+{
+ const struct phy_configure_opts_dp *dp_opts = &opts->dp;
+ struct qmp_phy *qphy = phy_get_drvdata(phy);
+ const struct qmp_phy_cfg *cfg = qphy->cfg;
+
+ memcpy(&qphy->dp_opts, dp_opts, sizeof(*dp_opts));
+ if (qphy->dp_opts.set_voltages) {
+ cfg->configure_dp_tx(qphy);
+ qphy->dp_opts.set_voltages = 0;
+ }
+
+ return 0;
+}
+
+static int qcom_qmp_dp_phy_calibrate(struct phy *phy)
+{
+ struct qmp_phy *qphy = phy_get_drvdata(phy);
+ const struct qmp_phy_cfg *cfg = qphy->cfg;
+
+ if (cfg->calibrate_dp_phy)
+ return cfg->calibrate_dp_phy(qphy);
return 0;
}
@@ -3729,7 +4124,7 @@ static int qcom_qmp_phy_init(struct phy *phy)
return ret;
if (cfg->type == PHY_TYPE_DP)
- qcom_qmp_phy_dp_aux_init(qphy);
+ cfg->dp_aux_init(qphy);
return 0;
}
@@ -3783,7 +4178,7 @@ static int qcom_qmp_phy_power_on(struct phy *phy)
/* Configure special DP tx tunings */
if (cfg->type == PHY_TYPE_DP)
- qcom_qmp_phy_configure_dp_tx(qphy);
+ cfg->configure_dp_tx(qphy);
qcom_qmp_phy_configure_lane(rx, cfg->regs,
cfg->rx_tbl, cfg->rx_tbl_num, 1);
@@ -3802,7 +4197,7 @@ static int qcom_qmp_phy_power_on(struct phy *phy)
/* Configure link rate, swing, etc. */
if (cfg->type == PHY_TYPE_DP) {
- qcom_qmp_phy_configure_dp_phy(qphy);
+ cfg->configure_dp_phy(qphy);
} else {
qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num);
if (cfg->pcs_tbl_sec)
@@ -3874,7 +4269,7 @@ static int qcom_qmp_phy_power_off(struct phy *phy)
if (cfg->type == PHY_TYPE_DP) {
/* Assert DP PHY power down */
- writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL);
+ writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_DP_PHY_PD_CTL);
} else {
/* PHY reset */
if (!cfg->no_pcs_sw_reset)
@@ -4578,6 +4973,9 @@ static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
.compatible = "qcom,sm8250-qmp-usb3-phy",
.data = &sm8250_usb3phy_cfg,
}, {
+ .compatible = "qcom,sm8250-qmp-usb3-dp-phy",
+ /* It's a combo phy */
+ }, {
.compatible = "qcom,sm8250-qmp-usb3-uni-phy",
.data = &sm8250_usb3_uniphy_cfg,
}, {
@@ -4611,6 +5009,10 @@ static const struct of_device_id qcom_qmp_combo_phy_of_match_table[] = {
.compatible = "qcom,sc7180-qmp-usb3-dp-phy",
.data = &sc7180_usb3dpphy_cfg,
},
+ {
+ .compatible = "qcom,sm8250-qmp-usb3-dp-phy",
+ .data = &sm8250_usb3dpphy_cfg,
+ },
{ }
};
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h
index 71ce3aa174ae..67bd2dd0d8c5 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.h
@@ -349,13 +349,13 @@
#define QPHY_V3_PCS_MISC_OSC_DTCT_MODE2_CONFIG4 0x5c
#define QPHY_V3_PCS_MISC_OSC_DTCT_MODE2_CONFIG5 0x60
-/* Only for QMP V3 PHY - DP PHY registers */
-#define QSERDES_V3_DP_PHY_REVISION_ID0 0x000
-#define QSERDES_V3_DP_PHY_REVISION_ID1 0x004
-#define QSERDES_V3_DP_PHY_REVISION_ID2 0x008
-#define QSERDES_V3_DP_PHY_REVISION_ID3 0x00c
-#define QSERDES_V3_DP_PHY_CFG 0x010
-#define QSERDES_V3_DP_PHY_PD_CTL 0x018
+/* QMP PHY - DP PHY registers */
+#define QSERDES_DP_PHY_REVISION_ID0 0x000
+#define QSERDES_DP_PHY_REVISION_ID1 0x004
+#define QSERDES_DP_PHY_REVISION_ID2 0x008
+#define QSERDES_DP_PHY_REVISION_ID3 0x00c
+#define QSERDES_DP_PHY_CFG 0x010
+#define QSERDES_DP_PHY_PD_CTL 0x018
# define DP_PHY_PD_CTL_PWRDN 0x001
# define DP_PHY_PD_CTL_PSR_PWRDN 0x002
# define DP_PHY_PD_CTL_AUX_PWRDN 0x004
@@ -363,18 +363,19 @@
# define DP_PHY_PD_CTL_LANE_2_3_PWRDN 0x010
# define DP_PHY_PD_CTL_PLL_PWRDN 0x020
# define DP_PHY_PD_CTL_DP_CLAMP_EN 0x040
-#define QSERDES_V3_DP_PHY_MODE 0x01c
-#define QSERDES_V3_DP_PHY_AUX_CFG0 0x020
-#define QSERDES_V3_DP_PHY_AUX_CFG1 0x024
-#define QSERDES_V3_DP_PHY_AUX_CFG2 0x028
-#define QSERDES_V3_DP_PHY_AUX_CFG3 0x02c
-#define QSERDES_V3_DP_PHY_AUX_CFG4 0x030
-#define QSERDES_V3_DP_PHY_AUX_CFG5 0x034
-#define QSERDES_V3_DP_PHY_AUX_CFG6 0x038
-#define QSERDES_V3_DP_PHY_AUX_CFG7 0x03c
-#define QSERDES_V3_DP_PHY_AUX_CFG8 0x040
-#define QSERDES_V3_DP_PHY_AUX_CFG9 0x044
+#define QSERDES_DP_PHY_MODE 0x01c
+#define QSERDES_DP_PHY_AUX_CFG0 0x020
+#define QSERDES_DP_PHY_AUX_CFG1 0x024
+#define QSERDES_DP_PHY_AUX_CFG2 0x028
+#define QSERDES_DP_PHY_AUX_CFG3 0x02c
+#define QSERDES_DP_PHY_AUX_CFG4 0x030
+#define QSERDES_DP_PHY_AUX_CFG5 0x034
+#define QSERDES_DP_PHY_AUX_CFG6 0x038
+#define QSERDES_DP_PHY_AUX_CFG7 0x03c
+#define QSERDES_DP_PHY_AUX_CFG8 0x040
+#define QSERDES_DP_PHY_AUX_CFG9 0x044
+/* Only for QMP V3 PHY - DP PHY registers */
#define QSERDES_V3_DP_PHY_AUX_INTERRUPT_MASK 0x048
# define PHY_AUX_STOP_ERR_MASK 0x01
# define PHY_AUX_DEC_ERR_MASK 0x02
@@ -396,6 +397,7 @@
#define QSERDES_V3_DP_PHY_STATUS 0x0c0
/* Only for QMP V4 PHY - QSERDES COM registers */
+#define QSERDES_V4_COM_BG_TIMER 0x00c
#define QSERDES_V4_COM_SSC_EN_CENTER 0x010
#define QSERDES_V4_COM_SSC_PER1 0x01c
#define QSERDES_V4_COM_SSC_PER2 0x020
@@ -403,7 +405,9 @@
#define QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0 0x028
#define QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1 0x030
#define QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1 0x034
+#define QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN 0x044
#define QSERDES_V4_COM_CLK_ENABLE1 0x048
+#define QSERDES_V4_COM_SYS_CLK_CTRL 0x04c
#define QSERDES_V4_COM_SYSCLK_BUF_ENABLE 0x050
#define QSERDES_V4_COM_PLL_IVCO 0x058
#define QSERDES_V4_COM_CMN_IPTRIM 0x060
@@ -414,6 +418,7 @@
#define QSERDES_V4_COM_PLL_CCTRL_MODE0 0x084
#define QSERDES_V4_COM_PLL_CCTRL_MODE1 0x088
#define QSERDES_V4_COM_SYSCLK_EN_SEL 0x094
+#define QSERDES_V4_COM_RESETSM_CNTRL 0x09c
#define QSERDES_V4_COM_LOCK_CMP_EN 0x0a4
#define QSERDES_V4_COM_LOCK_CMP1_MODE0 0x0ac
#define QSERDES_V4_COM_LOCK_CMP2_MODE0 0x0b0
@@ -427,16 +432,24 @@
#define QSERDES_V4_COM_DIV_FRAC_START1_MODE1 0x0d8
#define QSERDES_V4_COM_DIV_FRAC_START2_MODE1 0x0dc
#define QSERDES_V4_COM_DIV_FRAC_START3_MODE1 0x0e0
+#define QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0 0x0ec
+#define QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0 0x0f0
+#define QSERDES_V4_COM_VCO_TUNE_CTRL 0x108
#define QSERDES_V4_COM_VCO_TUNE_MAP 0x10c
#define QSERDES_V4_COM_VCO_TUNE1_MODE0 0x110
#define QSERDES_V4_COM_VCO_TUNE2_MODE0 0x114
#define QSERDES_V4_COM_VCO_TUNE1_MODE1 0x118
#define QSERDES_V4_COM_VCO_TUNE2_MODE1 0x11c
#define QSERDES_V4_COM_VCO_TUNE_INITVAL2 0x124
+#define QSERDES_V4_COM_CMN_STATUS 0x140
#define QSERDES_V4_COM_CLK_SELECT 0x154
#define QSERDES_V4_COM_HSCLK_SEL 0x158
#define QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL 0x15c
+#define QSERDES_V4_COM_CORECLK_DIV_MODE0 0x168
#define QSERDES_V4_COM_CORECLK_DIV_MODE1 0x16c
+#define QSERDES_V4_COM_CORE_CLK_EN 0x174
+#define QSERDES_V4_COM_C_READY_STATUS 0x178
+#define QSERDES_V4_COM_CMN_CONFIG 0x17c
#define QSERDES_V4_COM_SVS_MODE_CLK_SEL 0x184
#define QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0 0x1ac
#define QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0 0x1b0
@@ -445,19 +458,32 @@
#define QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1 0x1b8
/* Only for QMP V4 PHY - TX registers */
+#define QSERDES_V4_TX_CLKBUF_ENABLE 0x08
+#define QSERDES_V4_TX_TX_EMP_POST1_LVL 0x0c
+#define QSERDES_V4_TX_TX_DRV_LVL 0x14
+#define QSERDES_V4_TX_RESET_TSYNC_EN 0x1c
+#define QSERDES_V4_TX_PRE_STALL_LDO_BOOST_EN 0x20
+#define QSERDES_V4_TX_TX_BAND 0x24
+#define QSERDES_V4_TX_INTERFACE_SELECT 0x2c
#define QSERDES_V4_TX_RES_CODE_LANE_TX 0x34
#define QSERDES_V4_TX_RES_CODE_LANE_RX 0x38
#define QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX 0x3c
#define QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX 0x40
+#define QSERDES_V4_TX_TRANSCEIVER_BIAS_EN 0x54
+#define QSERDES_V4_TX_HIGHZ_DRVR_EN 0x58
+#define QSERDES_V4_TX_TX_POL_INV 0x5c
+#define QSERDES_V4_TX_PARRATE_REC_DETECT_IDLE_EN 0x60
#define QSERDES_V4_TX_LANE_MODE_1 0x84
#define QSERDES_V4_TX_LANE_MODE_2 0x88
#define QSERDES_V4_TX_RCV_DETECT_LVL_2 0x9c
+#define QSERDES_V4_TX_TRAN_DRVR_EMP_EN 0xb8
+#define QSERDES_V4_TX_TX_INTERFACE_MODE 0xbc
#define QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1 0xd8
#define QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1 0xdC
#define QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1 0xe0
#define QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1 0xe4
-#define QSERDES_V4_TX_TRAN_DRVR_EMP_EN 0xb8
-#define QSERDES_V4_TX_PI_QEC_CTRL 0x104
+#define QSERDES_V4_TX_VMODE_CTRL1 0xe8
+#define QSERDES_V4_TX_PI_QEC_CTRL 0x104
/* Only for QMP V4 PHY - RX registers */
#define QSERDES_V4_RX_UCDR_FO_GAIN 0x008
@@ -514,6 +540,17 @@
#define QSERDES_V4_RX_DCC_CTRL1 0x1bc
#define QSERDES_V4_RX_VTH_CODE 0x1c4
+/* Only for QMP V4 PHY - DP PHY registers */
+#define QSERDES_V4_DP_PHY_CFG_1 0x014
+#define QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK 0x054
+#define QSERDES_V4_DP_PHY_AUX_INTERRUPT_CLEAR 0x058
+#define QSERDES_V4_DP_PHY_VCO_DIV 0x070
+#define QSERDES_V4_DP_PHY_TX0_TX1_LANE_CTL 0x078
+#define QSERDES_V4_DP_PHY_TX2_TX3_LANE_CTL 0x09c
+#define QSERDES_V4_DP_PHY_SPARE0 0x0c8
+#define QSERDES_V4_DP_PHY_AUX_INTERRUPT_STATUS 0x0d8
+#define QSERDES_V4_DP_PHY_STATUS 0x0dc
+
/* Only for QMP V4 PHY - UFS PCS registers */
#define QPHY_V4_PCS_UFS_PHY_START 0x000
#define QPHY_V4_PCS_UFS_POWER_DOWN_CONTROL 0x004
diff --git a/drivers/phy/qualcomm/phy-qcom-usb-hs.c b/drivers/phy/qualcomm/phy-qcom-usb-hs.c
index 327df1a99f77..5c6c17673396 100644
--- a/drivers/phy/qualcomm/phy-qcom-usb-hs.c
+++ b/drivers/phy/qualcomm/phy-qcom-usb-hs.c
@@ -56,6 +56,7 @@ static int qcom_usb_hs_phy_set_mode(struct phy *phy,
fallthrough;
case PHY_MODE_USB_DEVICE:
val |= ULPI_INT_SESS_VALID;
+ break;
default:
break;
}
diff --git a/drivers/phy/ralink/phy-mt7621-pci.c b/drivers/phy/ralink/phy-mt7621-pci.c
index 9a610b414b1f..753cb5bab930 100644
--- a/drivers/phy/ralink/phy-mt7621-pci.c
+++ b/drivers/phy/ralink/phy-mt7621-pci.c
@@ -62,7 +62,7 @@
#define RG_PE1_FRC_MSTCKDIV BIT(5)
-#define XTAL_MASK GENMASK(7, 6)
+#define XTAL_MASK GENMASK(8, 6)
#define MAX_PHYS 2
@@ -319,9 +319,9 @@ static int mt7621_pci_phy_probe(struct platform_device *pdev)
return PTR_ERR(phy->regmap);
phy->phy = devm_phy_create(dev, dev->of_node, &mt7621_pci_phy_ops);
- if (IS_ERR(phy)) {
+ if (IS_ERR(phy->phy)) {
dev_err(dev, "failed to create phy\n");
- return PTR_ERR(phy);
+ return PTR_ERR(phy->phy);
}
phy_set_drvdata(phy->phy, phy);
diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
index 70a31251b202..d2bbdc96a167 100644
--- a/drivers/phy/rockchip/phy-rockchip-typec.c
+++ b/drivers/phy/rockchip/phy-rockchip-typec.c
@@ -1180,6 +1180,7 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev)
dev_err(dev, "failed to create phy: %pOFn\n",
child_np);
pm_runtime_disable(dev);
+ of_node_put(child_np);
return PTR_ERR(phy);
}
diff --git a/drivers/phy/st/Kconfig b/drivers/phy/st/Kconfig
index b32f44ff9033..3fc3d0781fb8 100644
--- a/drivers/phy/st/Kconfig
+++ b/drivers/phy/st/Kconfig
@@ -36,6 +36,7 @@ config PHY_STIH407_USB
config PHY_STM32_USBPHYC
tristate "STMicroelectronics STM32 USB HS PHY Controller driver"
depends on ARCH_STM32 || COMPILE_TEST
+ depends on COMMON_CLK
select GENERIC_PHY
help
Enable this to support the High-Speed USB transceivers that are part
diff --git a/drivers/phy/st/phy-stm32-usbphyc.c b/drivers/phy/st/phy-stm32-usbphyc.c
index d08fbb180e43..c184f4e34584 100644
--- a/drivers/phy/st/phy-stm32-usbphyc.c
+++ b/drivers/phy/st/phy-stm32-usbphyc.c
@@ -7,6 +7,7 @@
*/
#include <linux/bitfield.h>
#include <linux/clk.h>
+#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
@@ -70,6 +71,7 @@ struct stm32_usbphyc {
struct regulator *vdda1v1;
struct regulator *vdda1v8;
atomic_t n_pll_cons;
+ struct clk_hw clk48_hw;
int switch_setup;
};
@@ -295,6 +297,61 @@ static const struct phy_ops stm32_usbphyc_phy_ops = {
.owner = THIS_MODULE,
};
+static int stm32_usbphyc_clk48_prepare(struct clk_hw *hw)
+{
+ struct stm32_usbphyc *usbphyc = container_of(hw, struct stm32_usbphyc, clk48_hw);
+
+ return stm32_usbphyc_pll_enable(usbphyc);
+}
+
+static void stm32_usbphyc_clk48_unprepare(struct clk_hw *hw)
+{
+ struct stm32_usbphyc *usbphyc = container_of(hw, struct stm32_usbphyc, clk48_hw);
+
+ stm32_usbphyc_pll_disable(usbphyc);
+}
+
+static unsigned long stm32_usbphyc_clk48_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+ return 48000000;
+}
+
+static const struct clk_ops usbphyc_clk48_ops = {
+ .prepare = stm32_usbphyc_clk48_prepare,
+ .unprepare = stm32_usbphyc_clk48_unprepare,
+ .recalc_rate = stm32_usbphyc_clk48_recalc_rate,
+};
+
+static void stm32_usbphyc_clk48_unregister(void *data)
+{
+ struct stm32_usbphyc *usbphyc = data;
+
+ of_clk_del_provider(usbphyc->dev->of_node);
+ clk_hw_unregister(&usbphyc->clk48_hw);
+}
+
+static int stm32_usbphyc_clk48_register(struct stm32_usbphyc *usbphyc)
+{
+ struct device_node *node = usbphyc->dev->of_node;
+ struct clk_init_data init = { };
+ int ret = 0;
+
+ init.name = "ck_usbo_48m";
+ init.ops = &usbphyc_clk48_ops;
+
+ usbphyc->clk48_hw.init = &init;
+
+ ret = clk_hw_register(usbphyc->dev, &usbphyc->clk48_hw);
+ if (ret)
+ return ret;
+
+ ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, &usbphyc->clk48_hw);
+ if (ret)
+ clk_hw_unregister(&usbphyc->clk48_hw);
+
+ return ret;
+}
+
static void stm32_usbphyc_switch_setup(struct stm32_usbphyc *usbphyc,
u32 utmi_switch)
{
@@ -473,6 +530,12 @@ static int stm32_usbphyc_probe(struct platform_device *pdev)
goto clk_disable;
}
+ ret = stm32_usbphyc_clk48_register(usbphyc);
+ if (ret) {
+ dev_err(dev, "failed to register ck_usbo_48m clock: %d\n", ret);
+ goto clk_disable;
+ }
+
version = readl_relaxed(usbphyc->base + STM32_USBPHYC_VERSION);
dev_info(dev, "registered rev:%lu.%lu\n",
FIELD_GET(MAJREV, version), FIELD_GET(MINREV, version));
@@ -497,6 +560,8 @@ static int stm32_usbphyc_remove(struct platform_device *pdev)
if (usbphyc->phys[port]->active)
stm32_usbphyc_phy_exit(usbphyc->phys[port]->phy);
+ stm32_usbphyc_clk48_unregister(usbphyc);
+
clk_disable_unprepare(usbphyc->clk);
return 0;
diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c
index c9cfafe89cbf..2b354680a272 100644
--- a/drivers/phy/ti/phy-j721e-wiz.c
+++ b/drivers/phy/ti/phy-j721e-wiz.c
@@ -7,6 +7,7 @@
*/
#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/phy/phy-ti.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/gpio.h>
@@ -26,6 +27,11 @@
#define WIZ_SERDES_RST 0x40c
#define WIZ_SERDES_TYPEC 0x410
#define WIZ_LANECTL(n) (0x480 + (0x40 * (n)))
+#define WIZ_LANEDIV(n) (0x484 + (0x40 * (n)))
+
+#define WIZ_MAX_INPUT_CLOCKS 4
+/* To include mux clocks, divider clocks and gate clocks */
+#define WIZ_MAX_OUTPUT_CLOCKS 32
#define WIZ_MAX_LANES 4
#define WIZ_MUX_NUM_CLOCKS 3
@@ -52,8 +58,16 @@ enum wiz_refclk_div_sel {
CMN_REFCLK1_DIG_DIV,
};
+enum wiz_clock_input {
+ WIZ_CORE_REFCLK,
+ WIZ_EXT_REFCLK,
+ WIZ_CORE_REFCLK1,
+ WIZ_EXT_REFCLK1,
+};
+
static const struct reg_field por_en = REG_FIELD(WIZ_SERDES_CTRL, 31, 31);
static const struct reg_field phy_reset_n = REG_FIELD(WIZ_SERDES_RST, 31, 31);
+static const struct reg_field phy_en_refclk = REG_FIELD(WIZ_SERDES_RST, 30, 30);
static const struct reg_field pll1_refclk_mux_sel =
REG_FIELD(WIZ_SERDES_RST, 29, 29);
static const struct reg_field pll0_refclk_mux_sel =
@@ -70,6 +84,12 @@ static const struct reg_field pma_cmn_refclk_dig_div =
REG_FIELD(WIZ_SERDES_TOP_CTRL, 26, 27);
static const struct reg_field pma_cmn_refclk1_dig_div =
REG_FIELD(WIZ_SERDES_TOP_CTRL, 24, 25);
+static const char * const output_clk_names[] = {
+ [TI_WIZ_PLL0_REFCLK] = "pll0-refclk",
+ [TI_WIZ_PLL1_REFCLK] = "pll1-refclk",
+ [TI_WIZ_REFCLK_DIG] = "refclk-dig",
+ [TI_WIZ_PHY_EN_REFCLK] = "phy-en-refclk",
+};
static const struct reg_field p_enable[WIZ_MAX_LANES] = {
REG_FIELD(WIZ_LANECTL(0), 30, 31),
@@ -101,13 +121,34 @@ static const struct reg_field p_standard_mode[WIZ_MAX_LANES] = {
REG_FIELD(WIZ_LANECTL(3), 24, 25),
};
+static const struct reg_field p0_fullrt_div[WIZ_MAX_LANES] = {
+ REG_FIELD(WIZ_LANECTL(0), 22, 23),
+ REG_FIELD(WIZ_LANECTL(1), 22, 23),
+ REG_FIELD(WIZ_LANECTL(2), 22, 23),
+ REG_FIELD(WIZ_LANECTL(3), 22, 23),
+};
+
+static const struct reg_field p_mac_div_sel0[WIZ_MAX_LANES] = {
+ REG_FIELD(WIZ_LANEDIV(0), 16, 22),
+ REG_FIELD(WIZ_LANEDIV(1), 16, 22),
+ REG_FIELD(WIZ_LANEDIV(2), 16, 22),
+ REG_FIELD(WIZ_LANEDIV(3), 16, 22),
+};
+
+static const struct reg_field p_mac_div_sel1[WIZ_MAX_LANES] = {
+ REG_FIELD(WIZ_LANEDIV(0), 0, 8),
+ REG_FIELD(WIZ_LANEDIV(1), 0, 8),
+ REG_FIELD(WIZ_LANEDIV(2), 0, 8),
+ REG_FIELD(WIZ_LANEDIV(3), 0, 8),
+};
+
static const struct reg_field typec_ln10_swap =
REG_FIELD(WIZ_SERDES_TYPEC, 30, 30);
struct wiz_clk_mux {
struct clk_hw hw;
struct regmap_field *field;
- u32 *table;
+ const u32 *table;
struct clk_init_data clk_data;
};
@@ -123,18 +164,26 @@ struct wiz_clk_divider {
#define to_wiz_clk_div(_hw) container_of(_hw, struct wiz_clk_divider, hw)
struct wiz_clk_mux_sel {
- struct regmap_field *field;
- u32 table[4];
+ u32 table[WIZ_MAX_INPUT_CLOCKS];
const char *node_name;
+ u32 num_parents;
+ u32 parents[WIZ_MAX_INPUT_CLOCKS];
};
struct wiz_clk_div_sel {
- struct regmap_field *field;
- const struct clk_div_table *table;
+ const struct clk_div_table *table;
const char *node_name;
};
-static struct wiz_clk_mux_sel clk_mux_sel_16g[] = {
+struct wiz_phy_en_refclk {
+ struct clk_hw hw;
+ struct regmap_field *phy_en_refclk;
+ struct clk_init_data clk_data;
+};
+
+#define to_wiz_phy_en_refclk(_hw) container_of(_hw, struct wiz_phy_en_refclk, hw)
+
+static const struct wiz_clk_mux_sel clk_mux_sel_16g[] = {
{
/*
* Mux value to be configured for each of the input clocks
@@ -153,20 +202,26 @@ static struct wiz_clk_mux_sel clk_mux_sel_16g[] = {
},
};
-static struct wiz_clk_mux_sel clk_mux_sel_10g[] = {
+static const struct wiz_clk_mux_sel clk_mux_sel_10g[] = {
{
/*
* Mux value to be configured for each of the input clocks
* in the order populated in device tree
*/
+ .num_parents = 2,
+ .parents = { WIZ_CORE_REFCLK, WIZ_EXT_REFCLK },
.table = { 1, 0 },
.node_name = "pll0-refclk",
},
{
+ .num_parents = 2,
+ .parents = { WIZ_CORE_REFCLK, WIZ_EXT_REFCLK },
.table = { 1, 0 },
.node_name = "pll1-refclk",
},
{
+ .num_parents = 2,
+ .parents = { WIZ_CORE_REFCLK, WIZ_EXT_REFCLK },
.table = { 1, 0 },
.node_name = "refclk-dig",
},
@@ -179,7 +234,7 @@ static const struct clk_div_table clk_div_table[] = {
{ .val = 3, .div = 8, },
};
-static struct wiz_clk_div_sel clk_div_sel[] = {
+static const struct wiz_clk_div_sel clk_div_sel[] = {
{
.table = clk_div_table,
.node_name = "cmn-refclk-dig-div",
@@ -193,6 +248,7 @@ static struct wiz_clk_div_sel clk_div_sel[] = {
enum wiz_type {
J721E_WIZ_16G,
J721E_WIZ_10G,
+ AM64_WIZ_10G,
};
#define WIZ_TYPEC_DIR_DEBOUNCE_MIN 100 /* ms */
@@ -201,19 +257,25 @@ enum wiz_type {
struct wiz {
struct regmap *regmap;
enum wiz_type type;
- struct wiz_clk_mux_sel *clk_mux_sel;
- struct wiz_clk_div_sel *clk_div_sel;
+ const struct wiz_clk_mux_sel *clk_mux_sel;
+ const struct wiz_clk_div_sel *clk_div_sel;
unsigned int clk_div_sel_num;
struct regmap_field *por_en;
struct regmap_field *phy_reset_n;
+ struct regmap_field *phy_en_refclk;
struct regmap_field *p_enable[WIZ_MAX_LANES];
struct regmap_field *p_align[WIZ_MAX_LANES];
struct regmap_field *p_raw_auto_start[WIZ_MAX_LANES];
struct regmap_field *p_standard_mode[WIZ_MAX_LANES];
+ struct regmap_field *p_mac_div_sel0[WIZ_MAX_LANES];
+ struct regmap_field *p_mac_div_sel1[WIZ_MAX_LANES];
+ struct regmap_field *p0_fullrt_div[WIZ_MAX_LANES];
struct regmap_field *pma_cmn_refclk_int_mode;
struct regmap_field *pma_cmn_refclk_mode;
struct regmap_field *pma_cmn_refclk_dig_div;
struct regmap_field *pma_cmn_refclk1_dig_div;
+ struct regmap_field *mux_sel_field[WIZ_MUX_NUM_CLOCKS];
+ struct regmap_field *div_sel_field[WIZ_DIV_NUM_CLOCKS_16G];
struct regmap_field *typec_ln10_swap;
struct device *dev;
@@ -223,6 +285,9 @@ struct wiz {
struct gpio_desc *gpio_typec_dir;
int typec_dir_delay;
u32 lane_phy_type[WIZ_MAX_LANES];
+ struct clk *input_clks[WIZ_MAX_INPUT_CLOCKS];
+ struct clk *output_clks[WIZ_MAX_OUTPUT_CLOCKS];
+ struct clk_onecell_data clk_data;
};
static int wiz_reset(struct wiz *wiz)
@@ -242,6 +307,27 @@ static int wiz_reset(struct wiz *wiz)
return 0;
}
+static int wiz_p_mac_div_sel(struct wiz *wiz)
+{
+ u32 num_lanes = wiz->num_lanes;
+ int ret;
+ int i;
+
+ for (i = 0; i < num_lanes; i++) {
+ if (wiz->lane_phy_type[i] == PHY_TYPE_QSGMII) {
+ ret = regmap_field_write(wiz->p_mac_div_sel0[i], 1);
+ if (ret)
+ return ret;
+
+ ret = regmap_field_write(wiz->p_mac_div_sel1[i], 2);
+ if (ret)
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
static int wiz_mode_select(struct wiz *wiz)
{
u32 num_lanes = wiz->num_lanes;
@@ -252,8 +338,10 @@ static int wiz_mode_select(struct wiz *wiz)
for (i = 0; i < num_lanes; i++) {
if (wiz->lane_phy_type[i] == PHY_TYPE_DP)
mode = LANE_MODE_GEN1;
+ else if (wiz->lane_phy_type[i] == PHY_TYPE_QSGMII)
+ mode = LANE_MODE_GEN2;
else
- mode = LANE_MODE_GEN4;
+ continue;
ret = regmap_field_write(wiz->p_standard_mode[i], mode);
if (ret)
@@ -299,6 +387,12 @@ static int wiz_init(struct wiz *wiz)
return ret;
}
+ ret = wiz_p_mac_div_sel(wiz);
+ if (ret) {
+ dev_err(dev, "Configuring P0 MAC DIV SEL failed\n");
+ return ret;
+ }
+
ret = wiz_init_raw_interface(wiz, true);
if (ret) {
dev_err(dev, "WIZ interface initialization failed\n");
@@ -310,8 +404,6 @@ static int wiz_init(struct wiz *wiz)
static int wiz_regfield_init(struct wiz *wiz)
{
- struct wiz_clk_mux_sel *clk_mux_sel;
- struct wiz_clk_div_sel *clk_div_sel;
struct regmap *regmap = wiz->regmap;
int num_lanes = wiz->num_lanes;
struct device *dev = wiz->dev;
@@ -344,54 +436,49 @@ static int wiz_regfield_init(struct wiz *wiz)
return PTR_ERR(wiz->pma_cmn_refclk_mode);
}
- clk_div_sel = &wiz->clk_div_sel[CMN_REFCLK_DIG_DIV];
- clk_div_sel->field = devm_regmap_field_alloc(dev, regmap,
- pma_cmn_refclk_dig_div);
- if (IS_ERR(clk_div_sel->field)) {
+ wiz->div_sel_field[CMN_REFCLK_DIG_DIV] =
+ devm_regmap_field_alloc(dev, regmap, pma_cmn_refclk_dig_div);
+ if (IS_ERR(wiz->div_sel_field[CMN_REFCLK_DIG_DIV])) {
dev_err(dev, "PMA_CMN_REFCLK_DIG_DIV reg field init failed\n");
- return PTR_ERR(clk_div_sel->field);
+ return PTR_ERR(wiz->div_sel_field[CMN_REFCLK_DIG_DIV]);
}
if (wiz->type == J721E_WIZ_16G) {
- clk_div_sel = &wiz->clk_div_sel[CMN_REFCLK1_DIG_DIV];
- clk_div_sel->field =
+ wiz->div_sel_field[CMN_REFCLK1_DIG_DIV] =
devm_regmap_field_alloc(dev, regmap,
pma_cmn_refclk1_dig_div);
- if (IS_ERR(clk_div_sel->field)) {
+ if (IS_ERR(wiz->div_sel_field[CMN_REFCLK1_DIG_DIV])) {
dev_err(dev, "PMA_CMN_REFCLK1_DIG_DIV reg field init failed\n");
- return PTR_ERR(clk_div_sel->field);
+ return PTR_ERR(wiz->div_sel_field[CMN_REFCLK1_DIG_DIV]);
}
}
- clk_mux_sel = &wiz->clk_mux_sel[PLL0_REFCLK];
- clk_mux_sel->field = devm_regmap_field_alloc(dev, regmap,
- pll0_refclk_mux_sel);
- if (IS_ERR(clk_mux_sel->field)) {
+ wiz->mux_sel_field[PLL0_REFCLK] =
+ devm_regmap_field_alloc(dev, regmap, pll0_refclk_mux_sel);
+ if (IS_ERR(wiz->mux_sel_field[PLL0_REFCLK])) {
dev_err(dev, "PLL0_REFCLK_SEL reg field init failed\n");
- return PTR_ERR(clk_mux_sel->field);
+ return PTR_ERR(wiz->mux_sel_field[PLL0_REFCLK]);
}
- clk_mux_sel = &wiz->clk_mux_sel[PLL1_REFCLK];
- clk_mux_sel->field = devm_regmap_field_alloc(dev, regmap,
- pll1_refclk_mux_sel);
- if (IS_ERR(clk_mux_sel->field)) {
+ wiz->mux_sel_field[PLL1_REFCLK] =
+ devm_regmap_field_alloc(dev, regmap, pll1_refclk_mux_sel);
+ if (IS_ERR(wiz->mux_sel_field[PLL1_REFCLK])) {
dev_err(dev, "PLL1_REFCLK_SEL reg field init failed\n");
- return PTR_ERR(clk_mux_sel->field);
+ return PTR_ERR(wiz->mux_sel_field[PLL1_REFCLK]);
}
- clk_mux_sel = &wiz->clk_mux_sel[REFCLK_DIG];
- if (wiz->type == J721E_WIZ_10G)
- clk_mux_sel->field =
+ if (wiz->type == J721E_WIZ_10G || wiz->type == AM64_WIZ_10G)
+ wiz->mux_sel_field[REFCLK_DIG] =
devm_regmap_field_alloc(dev, regmap,
refclk_dig_sel_10g);
else
- clk_mux_sel->field =
+ wiz->mux_sel_field[REFCLK_DIG] =
devm_regmap_field_alloc(dev, regmap,
refclk_dig_sel_16g);
- if (IS_ERR(clk_mux_sel->field)) {
+ if (IS_ERR(wiz->mux_sel_field[REFCLK_DIG])) {
dev_err(dev, "REFCLK_DIG_SEL reg field init failed\n");
- return PTR_ERR(clk_mux_sel->field);
+ return PTR_ERR(wiz->mux_sel_field[REFCLK_DIG]);
}
for (i = 0; i < num_lanes; i++) {
@@ -424,6 +511,28 @@ static int wiz_regfield_init(struct wiz *wiz)
i);
return PTR_ERR(wiz->p_standard_mode[i]);
}
+
+ wiz->p0_fullrt_div[i] = devm_regmap_field_alloc(dev, regmap, p0_fullrt_div[i]);
+ if (IS_ERR(wiz->p0_fullrt_div[i])) {
+ dev_err(dev, "P%d_FULLRT_DIV reg field init failed\n", i);
+ return PTR_ERR(wiz->p0_fullrt_div[i]);
+ }
+
+ wiz->p_mac_div_sel0[i] =
+ devm_regmap_field_alloc(dev, regmap, p_mac_div_sel0[i]);
+ if (IS_ERR(wiz->p_mac_div_sel0[i])) {
+ dev_err(dev, "P%d_MAC_DIV_SEL0 reg field init fail\n",
+ i);
+ return PTR_ERR(wiz->p_mac_div_sel0[i]);
+ }
+
+ wiz->p_mac_div_sel1[i] =
+ devm_regmap_field_alloc(dev, regmap, p_mac_div_sel1[i]);
+ if (IS_ERR(wiz->p_mac_div_sel1[i])) {
+ dev_err(dev, "P%d_MAC_DIV_SEL1 reg field init fail\n",
+ i);
+ return PTR_ERR(wiz->p_mac_div_sel1[i]);
+ }
}
wiz->typec_ln10_swap = devm_regmap_field_alloc(dev, regmap,
@@ -433,6 +542,76 @@ static int wiz_regfield_init(struct wiz *wiz)
return PTR_ERR(wiz->typec_ln10_swap);
}
+ wiz->phy_en_refclk = devm_regmap_field_alloc(dev, regmap, phy_en_refclk);
+ if (IS_ERR(wiz->phy_en_refclk)) {
+ dev_err(dev, "PHY_EN_REFCLK reg field init failed\n");
+ return PTR_ERR(wiz->phy_en_refclk);
+ }
+
+ return 0;
+}
+
+static int wiz_phy_en_refclk_enable(struct clk_hw *hw)
+{
+ struct wiz_phy_en_refclk *wiz_phy_en_refclk = to_wiz_phy_en_refclk(hw);
+ struct regmap_field *phy_en_refclk = wiz_phy_en_refclk->phy_en_refclk;
+
+ regmap_field_write(phy_en_refclk, 1);
+
+ return 0;
+}
+
+static void wiz_phy_en_refclk_disable(struct clk_hw *hw)
+{
+ struct wiz_phy_en_refclk *wiz_phy_en_refclk = to_wiz_phy_en_refclk(hw);
+ struct regmap_field *phy_en_refclk = wiz_phy_en_refclk->phy_en_refclk;
+
+ regmap_field_write(phy_en_refclk, 0);
+}
+
+static int wiz_phy_en_refclk_is_enabled(struct clk_hw *hw)
+{
+ struct wiz_phy_en_refclk *wiz_phy_en_refclk = to_wiz_phy_en_refclk(hw);
+ struct regmap_field *phy_en_refclk = wiz_phy_en_refclk->phy_en_refclk;
+ int val;
+
+ regmap_field_read(phy_en_refclk, &val);
+
+ return !!val;
+}
+
+static const struct clk_ops wiz_phy_en_refclk_ops = {
+ .enable = wiz_phy_en_refclk_enable,
+ .disable = wiz_phy_en_refclk_disable,
+ .is_enabled = wiz_phy_en_refclk_is_enabled,
+};
+
+static int wiz_phy_en_refclk_register(struct wiz *wiz)
+{
+ struct wiz_phy_en_refclk *wiz_phy_en_refclk;
+ struct device *dev = wiz->dev;
+ struct clk_init_data *init;
+ struct clk *clk;
+
+ wiz_phy_en_refclk = devm_kzalloc(dev, sizeof(*wiz_phy_en_refclk), GFP_KERNEL);
+ if (!wiz_phy_en_refclk)
+ return -ENOMEM;
+
+ init = &wiz_phy_en_refclk->clk_data;
+
+ init->ops = &wiz_phy_en_refclk_ops;
+ init->flags = 0;
+ init->name = output_clk_names[TI_WIZ_PHY_EN_REFCLK];
+
+ wiz_phy_en_refclk->phy_en_refclk = wiz->phy_en_refclk;
+ wiz_phy_en_refclk->hw.init = init;
+
+ clk = devm_clk_register(dev, &wiz_phy_en_refclk->hw);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ wiz->output_clks[TI_WIZ_PHY_EN_REFCLK] = clk;
+
return 0;
}
@@ -443,7 +622,7 @@ static u8 wiz_clk_mux_get_parent(struct clk_hw *hw)
unsigned int val;
regmap_field_read(field, &val);
- return clk_mux_val_to_index(hw, mux->table, 0, val);
+ return clk_mux_val_to_index(hw, (u32 *)mux->table, 0, val);
}
static int wiz_clk_mux_set_parent(struct clk_hw *hw, u8 index)
@@ -461,8 +640,69 @@ static const struct clk_ops wiz_clk_mux_ops = {
.get_parent = wiz_clk_mux_get_parent,
};
-static int wiz_mux_clk_register(struct wiz *wiz, struct device_node *node,
- struct regmap_field *field, u32 *table)
+static int wiz_mux_clk_register(struct wiz *wiz, struct regmap_field *field,
+ const struct wiz_clk_mux_sel *mux_sel, int clk_index)
+{
+ struct device *dev = wiz->dev;
+ struct clk_init_data *init;
+ const char **parent_names;
+ unsigned int num_parents;
+ struct wiz_clk_mux *mux;
+ char clk_name[100];
+ struct clk *clk;
+ int ret = 0, i;
+
+ mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
+ if (!mux)
+ return -ENOMEM;
+
+ num_parents = mux_sel->num_parents;
+
+ parent_names = kzalloc((sizeof(char *) * num_parents), GFP_KERNEL);
+ if (!parent_names)
+ return -ENOMEM;
+
+ for (i = 0; i < num_parents; i++) {
+ clk = wiz->input_clks[mux_sel->parents[i]];
+ if (IS_ERR_OR_NULL(clk)) {
+ dev_err(dev, "Failed to get parent clk for %s\n",
+ output_clk_names[clk_index]);
+ ret = -EINVAL;
+ goto err;
+ }
+ parent_names[i] = __clk_get_name(clk);
+ }
+
+ snprintf(clk_name, sizeof(clk_name), "%s_%s", dev_name(dev), output_clk_names[clk_index]);
+
+ init = &mux->clk_data;
+
+ init->ops = &wiz_clk_mux_ops;
+ init->flags = CLK_SET_RATE_NO_REPARENT;
+ init->parent_names = parent_names;
+ init->num_parents = num_parents;
+ init->name = clk_name;
+
+ mux->field = field;
+ mux->table = mux_sel->table;
+ mux->hw.init = init;
+
+ clk = devm_clk_register(dev, &mux->hw);
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ goto err;
+ }
+
+ wiz->output_clks[clk_index] = clk;
+
+err:
+ kfree(parent_names);
+
+ return ret;
+}
+
+static int wiz_mux_of_clk_register(struct wiz *wiz, struct device_node *node,
+ struct regmap_field *field, const u32 *table)
{
struct device *dev = wiz->dev;
struct clk_init_data *init;
@@ -606,20 +846,70 @@ static int wiz_div_clk_register(struct wiz *wiz, struct device_node *node,
static void wiz_clock_cleanup(struct wiz *wiz, struct device_node *node)
{
- struct wiz_clk_mux_sel *clk_mux_sel = wiz->clk_mux_sel;
+ const struct wiz_clk_mux_sel *clk_mux_sel = wiz->clk_mux_sel;
+ struct device *dev = wiz->dev;
struct device_node *clk_node;
int i;
+ if (wiz->type == AM64_WIZ_10G) {
+ of_clk_del_provider(dev->of_node);
+ return;
+ }
+
for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++) {
clk_node = of_get_child_by_name(node, clk_mux_sel[i].node_name);
of_clk_del_provider(clk_node);
of_node_put(clk_node);
}
+
+ for (i = 0; i < wiz->clk_div_sel_num; i++) {
+ clk_node = of_get_child_by_name(node, clk_div_sel[i].node_name);
+ of_clk_del_provider(clk_node);
+ of_node_put(clk_node);
+ }
+
+ of_clk_del_provider(wiz->dev->of_node);
+}
+
+static int wiz_clock_register(struct wiz *wiz)
+{
+ const struct wiz_clk_mux_sel *clk_mux_sel = wiz->clk_mux_sel;
+ struct device *dev = wiz->dev;
+ struct device_node *node = dev->of_node;
+ int clk_index;
+ int ret;
+ int i;
+
+ if (wiz->type != AM64_WIZ_10G)
+ return 0;
+
+ clk_index = TI_WIZ_PLL0_REFCLK;
+ for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++, clk_index++) {
+ ret = wiz_mux_clk_register(wiz, wiz->mux_sel_field[i], &clk_mux_sel[i], clk_index);
+ if (ret) {
+ dev_err(dev, "Failed to register clk: %s\n", output_clk_names[clk_index]);
+ return ret;
+ }
+ }
+
+ ret = wiz_phy_en_refclk_register(wiz);
+ if (ret) {
+ dev_err(dev, "Failed to add phy-en-refclk\n");
+ return ret;
+ }
+
+ wiz->clk_data.clks = wiz->output_clks;
+ wiz->clk_data.clk_num = WIZ_MAX_OUTPUT_CLOCKS;
+ ret = of_clk_add_provider(node, of_clk_src_onecell_get, &wiz->clk_data);
+ if (ret)
+ dev_err(dev, "Failed to add clock provider: %s\n", node->name);
+
+ return ret;
}
static int wiz_clock_init(struct wiz *wiz, struct device_node *node)
{
- struct wiz_clk_mux_sel *clk_mux_sel = wiz->clk_mux_sel;
+ const struct wiz_clk_mux_sel *clk_mux_sel = wiz->clk_mux_sel;
struct device *dev = wiz->dev;
struct device_node *clk_node;
const char *node_name;
@@ -634,6 +924,7 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node)
ret = PTR_ERR(clk);
return ret;
}
+ wiz->input_clks[WIZ_CORE_REFCLK] = clk;
rate = clk_get_rate(clk);
if (rate >= 100000000)
@@ -647,6 +938,7 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node)
ret = PTR_ERR(clk);
return ret;
}
+ wiz->input_clks[WIZ_EXT_REFCLK] = clk;
rate = clk_get_rate(clk);
if (rate >= 100000000)
@@ -654,6 +946,13 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node)
else
regmap_field_write(wiz->pma_cmn_refclk_mode, 0x2);
+ if (wiz->type == AM64_WIZ_10G) {
+ ret = wiz_clock_register(wiz);
+ if (ret)
+ dev_err(dev, "Failed to register wiz clocks\n");
+ return ret;
+ }
+
for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++) {
node_name = clk_mux_sel[i].node_name;
clk_node = of_get_child_by_name(node, node_name);
@@ -663,8 +962,8 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node)
goto err;
}
- ret = wiz_mux_clk_register(wiz, clk_node, clk_mux_sel[i].field,
- clk_mux_sel[i].table);
+ ret = wiz_mux_of_clk_register(wiz, clk_node, wiz->mux_sel_field[i],
+ clk_mux_sel[i].table);
if (ret) {
dev_err(dev, "Failed to register %s clock\n",
node_name);
@@ -684,7 +983,7 @@ static int wiz_clock_init(struct wiz *wiz, struct device_node *node)
goto err;
}
- ret = wiz_div_clk_register(wiz, clk_node, clk_div_sel[i].field,
+ ret = wiz_div_clk_register(wiz, clk_node, wiz->div_sel_field[i],
clk_div_sel[i].table);
if (ret) {
dev_err(dev, "Failed to register %s clock\n",
@@ -719,6 +1018,17 @@ static int wiz_phy_reset_assert(struct reset_controller_dev *rcdev,
return ret;
}
+static int wiz_phy_fullrt_div(struct wiz *wiz, int lane)
+{
+ if (wiz->type != AM64_WIZ_10G)
+ return 0;
+
+ if (wiz->lane_phy_type[lane] == PHY_TYPE_PCIE)
+ return regmap_field_write(wiz->p0_fullrt_div[lane], 0x1);
+
+ return 0;
+}
+
static int wiz_phy_reset_deassert(struct reset_controller_dev *rcdev,
unsigned long id)
{
@@ -742,6 +1052,10 @@ static int wiz_phy_reset_deassert(struct reset_controller_dev *rcdev,
return ret;
}
+ ret = wiz_phy_fullrt_div(wiz, id - 1);
+ if (ret)
+ return ret;
+
if (wiz->lane_phy_type[id - 1] == PHY_TYPE_DP)
ret = regmap_field_write(wiz->p_enable[id - 1], P_ENABLE);
else
@@ -769,6 +1083,9 @@ static const struct of_device_id wiz_id_table[] = {
{
.compatible = "ti,j721e-wiz-10g", .data = (void *)J721E_WIZ_10G
},
+ {
+ .compatible = "ti,am64-wiz-10g", .data = (void *)AM64_WIZ_10G
+ },
{}
};
MODULE_DEVICE_TABLE(of, wiz_id_table);
@@ -787,11 +1104,17 @@ static int wiz_get_lane_phy_types(struct device *dev, struct wiz *wiz)
u32 reg, num_lanes = 1, phy_type = PHY_NONE;
int ret, i;
+ if (!(of_node_name_eq(subnode, "phy") ||
+ of_node_name_eq(subnode, "link")))
+ continue;
+
ret = of_property_read_u32(subnode, "reg", &reg);
if (ret) {
+ of_node_put(subnode);
dev_err(dev,
"%s: Reading \"reg\" from \"%s\" failed: %d\n",
__func__, subnode->name, ret);
+ of_node_put(subnode);
return ret;
}
of_property_read_u32(subnode, "cdns,num-lanes", &num_lanes);
@@ -813,13 +1136,14 @@ static int wiz_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct device_node *node = dev->of_node;
struct platform_device *serdes_pdev;
+ bool already_configured = false;
struct device_node *child_node;
struct regmap *regmap;
struct resource res;
void __iomem *base;
struct wiz *wiz;
+ int ret, val, i;
u32 num_lanes;
- int ret;
wiz = devm_kzalloc(dev, sizeof(*wiz), GFP_KERNEL);
if (!wiz)
@@ -900,14 +1224,14 @@ static int wiz_probe(struct platform_device *pdev)
wiz->dev = dev;
wiz->regmap = regmap;
wiz->num_lanes = num_lanes;
- if (wiz->type == J721E_WIZ_10G)
+ if (wiz->type == J721E_WIZ_10G || wiz->type == AM64_WIZ_10G)
wiz->clk_mux_sel = clk_mux_sel_10g;
else
wiz->clk_mux_sel = clk_mux_sel_16g;
wiz->clk_div_sel = clk_div_sel;
- if (wiz->type == J721E_WIZ_10G)
+ if (wiz->type == J721E_WIZ_10G || wiz->type == AM64_WIZ_10G)
wiz->clk_div_sel_num = WIZ_DIV_NUM_CLOCKS_10G;
else
wiz->clk_div_sel_num = WIZ_DIV_NUM_CLOCKS_16G;
@@ -947,27 +1271,34 @@ static int wiz_probe(struct platform_device *pdev)
goto err_get_sync;
}
+ for (i = 0; i < wiz->num_lanes; i++) {
+ regmap_field_read(wiz->p_enable[i], &val);
+ if (val & (P_ENABLE | P_ENABLE_FORCE)) {
+ already_configured = true;
+ break;
+ }
+ }
+
+ if (!already_configured) {
+ ret = wiz_init(wiz);
+ if (ret) {
+ dev_err(dev, "WIZ initialization failed\n");
+ goto err_wiz_init;
+ }
+ }
+
serdes_pdev = of_platform_device_create(child_node, NULL, dev);
if (!serdes_pdev) {
dev_WARN(dev, "Unable to create SERDES platform device\n");
ret = -ENOMEM;
- goto err_pdev_create;
- }
- wiz->serdes_pdev = serdes_pdev;
-
- ret = wiz_init(wiz);
- if (ret) {
- dev_err(dev, "WIZ initialization failed\n");
goto err_wiz_init;
}
+ wiz->serdes_pdev = serdes_pdev;
of_node_put(child_node);
return 0;
err_wiz_init:
- of_platform_device_destroy(&serdes_pdev->dev, NULL);
-
-err_pdev_create:
wiz_clock_cleanup(wiz, node);
err_get_sync:
diff --git a/drivers/phy/ti/phy-tusb1210.c b/drivers/phy/ti/phy-tusb1210.c
index d8d0cc11d187..a63213f5972a 100644
--- a/drivers/phy/ti/phy-tusb1210.c
+++ b/drivers/phy/ti/phy-tusb1210.c
@@ -7,15 +7,16 @@
* Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
*/
#include <linux/module.h>
+#include <linux/bitfield.h>
#include <linux/ulpi/driver.h>
#include <linux/ulpi/regs.h>
#include <linux/gpio/consumer.h>
#include <linux/phy/ulpi_phy.h>
#define TUSB1210_VENDOR_SPECIFIC2 0x80
-#define TUSB1210_VENDOR_SPECIFIC2_IHSTX_SHIFT 0
-#define TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_SHIFT 4
-#define TUSB1210_VENDOR_SPECIFIC2_DP_SHIFT 6
+#define TUSB1210_VENDOR_SPECIFIC2_IHSTX_MASK GENMASK(3, 0)
+#define TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_MASK GENMASK(5, 4)
+#define TUSB1210_VENDOR_SPECIFIC2_DP_MASK BIT(6)
struct tusb1210 {
struct ulpi *ulpi;
@@ -118,22 +119,22 @@ static int tusb1210_probe(struct ulpi *ulpi)
* diagram optimization and DP/DM swap.
*/
+ reg = ulpi_read(ulpi, TUSB1210_VENDOR_SPECIFIC2);
+
/* High speed output drive strength configuration */
- device_property_read_u8(&ulpi->dev, "ihstx", &val);
- reg = val << TUSB1210_VENDOR_SPECIFIC2_IHSTX_SHIFT;
+ if (!device_property_read_u8(&ulpi->dev, "ihstx", &val))
+ u8p_replace_bits(&reg, val, (u8)TUSB1210_VENDOR_SPECIFIC2_IHSTX_MASK);
/* High speed output impedance configuration */
- device_property_read_u8(&ulpi->dev, "zhsdrv", &val);
- reg |= val << TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_SHIFT;
+ if (!device_property_read_u8(&ulpi->dev, "zhsdrv", &val))
+ u8p_replace_bits(&reg, val, (u8)TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_MASK);
/* DP/DM swap control */
- device_property_read_u8(&ulpi->dev, "datapolarity", &val);
- reg |= val << TUSB1210_VENDOR_SPECIFIC2_DP_SHIFT;
+ if (!device_property_read_u8(&ulpi->dev, "datapolarity", &val))
+ u8p_replace_bits(&reg, val, (u8)TUSB1210_VENDOR_SPECIFIC2_DP_MASK);
- if (reg) {
- ulpi_write(ulpi, TUSB1210_VENDOR_SPECIFIC2, reg);
- tusb->vendor_specific2 = reg;
- }
+ ulpi_write(ulpi, TUSB1210_VENDOR_SPECIFIC2, reg);
+ tusb->vendor_specific2 = reg;
tusb->phy = ulpi_phy_create(ulpi, &phy_ops);
if (IS_ERR(tusb->phy))
diff --git a/drivers/phy/xilinx/phy-zynqmp.c b/drivers/phy/xilinx/phy-zynqmp.c
index 2b65f84a5f89..35652152ce5d 100644
--- a/drivers/phy/xilinx/phy-zynqmp.c
+++ b/drivers/phy/xilinx/phy-zynqmp.c
@@ -208,6 +208,7 @@ struct xpsgtr_phy {
* @gtr_mutex: mutex for locking
* @phys: PHY lanes
* @refclk_sscs: spread spectrum settings for the reference clocks
+ * @clk: reference clocks
* @tx_term_fix: fix for GT issue
* @saved_icm_cfg0: stored value of ICM CFG0 register
* @saved_icm_cfg1: stored value of ICM CFG1 register
@@ -219,6 +220,7 @@ struct xpsgtr_dev {
struct mutex gtr_mutex; /* mutex for locking */
struct xpsgtr_phy phys[NUM_LANES];
const struct xpsgtr_ssc *refclk_sscs[NUM_LANES];
+ struct clk *clk[NUM_LANES];
bool tx_term_fix;
unsigned int saved_icm_cfg0;
unsigned int saved_icm_cfg1;
@@ -818,11 +820,15 @@ static struct phy *xpsgtr_xlate(struct device *dev,
static int __maybe_unused xpsgtr_suspend(struct device *dev)
{
struct xpsgtr_dev *gtr_dev = dev_get_drvdata(dev);
+ unsigned int i;
/* Save the snapshot ICM_CFG registers. */
gtr_dev->saved_icm_cfg0 = xpsgtr_read(gtr_dev, ICM_CFG0);
gtr_dev->saved_icm_cfg1 = xpsgtr_read(gtr_dev, ICM_CFG1);
+ for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++)
+ clk_disable_unprepare(gtr_dev->clk[i]);
+
return 0;
}
@@ -832,6 +838,13 @@ static int __maybe_unused xpsgtr_resume(struct device *dev)
unsigned int icm_cfg0, icm_cfg1;
unsigned int i;
bool skip_phy_init;
+ int err;
+
+ for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++) {
+ err = clk_prepare_enable(gtr_dev->clk[i]);
+ if (err)
+ goto err_clk_put;
+ }
icm_cfg0 = xpsgtr_read(gtr_dev, ICM_CFG0);
icm_cfg1 = xpsgtr_read(gtr_dev, ICM_CFG1);
@@ -852,6 +865,12 @@ static int __maybe_unused xpsgtr_resume(struct device *dev)
gtr_dev->phys[i].skip_phy_init = skip_phy_init;
return 0;
+
+err_clk_put:
+ while (i--)
+ clk_disable_unprepare(gtr_dev->clk[i]);
+
+ return err;
}
static const struct dev_pm_ops xpsgtr_pm_ops = {
@@ -865,6 +884,7 @@ static const struct dev_pm_ops xpsgtr_pm_ops = {
static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev)
{
unsigned int refclk;
+ int ret;
for (refclk = 0; refclk < ARRAY_SIZE(gtr_dev->refclk_sscs); ++refclk) {
unsigned long rate;
@@ -874,14 +894,22 @@ static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev)
snprintf(name, sizeof(name), "ref%u", refclk);
clk = devm_clk_get_optional(gtr_dev->dev, name);
- if (IS_ERR(clk))
- return dev_err_probe(gtr_dev->dev, PTR_ERR(clk),
- "Failed to get reference clock %u\n",
- refclk);
+ if (IS_ERR(clk)) {
+ ret = dev_err_probe(gtr_dev->dev, PTR_ERR(clk),
+ "Failed to get reference clock %u\n",
+ refclk);
+ goto err_clk_put;
+ }
if (!clk)
continue;
+ ret = clk_prepare_enable(clk);
+ if (ret)
+ goto err_clk_put;
+
+ gtr_dev->clk[refclk] = clk;
+
/*
* Get the spread spectrum (SSC) settings for the reference
* clock rate.
@@ -899,11 +927,18 @@ static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev)
dev_err(gtr_dev->dev,
"Invalid rate %lu for reference clock %u\n",
rate, refclk);
- return -EINVAL;
+ ret = -EINVAL;
+ goto err_clk_put;
}
}
return 0;
+
+err_clk_put:
+ while (refclk--)
+ clk_disable_unprepare(gtr_dev->clk[refclk]);
+
+ return ret;
}
static int xpsgtr_probe(struct platform_device *pdev)
@@ -912,6 +947,7 @@ static int xpsgtr_probe(struct platform_device *pdev)
struct xpsgtr_dev *gtr_dev;
struct phy_provider *provider;
unsigned int port;
+ unsigned int i;
int ret;
gtr_dev = devm_kzalloc(&pdev->dev, sizeof(*gtr_dev), GFP_KERNEL);
@@ -951,7 +987,8 @@ static int xpsgtr_probe(struct platform_device *pdev)
phy = devm_phy_create(&pdev->dev, np, &xpsgtr_phyops);
if (IS_ERR(phy)) {
dev_err(&pdev->dev, "failed to create PHY\n");
- return PTR_ERR(phy);
+ ret = PTR_ERR(phy);
+ goto err_clk_put;
}
gtr_phy->phy = phy;
@@ -962,9 +999,16 @@ static int xpsgtr_probe(struct platform_device *pdev)
provider = devm_of_phy_provider_register(&pdev->dev, xpsgtr_xlate);
if (IS_ERR(provider)) {
dev_err(&pdev->dev, "registering provider failed\n");
- return PTR_ERR(provider);
+ ret = PTR_ERR(provider);
+ goto err_clk_put;
}
return 0;
+
+err_clk_put:
+ for (i = 0; i < ARRAY_SIZE(gtr_dev->clk); i++)
+ clk_disable_unprepare(gtr_dev->clk[i]);
+
+ return ret;
}
static const struct of_device_id xpsgtr_of_match[] = {
diff --git a/drivers/pps/clients/pps-gpio.c b/drivers/pps/clients/pps-gpio.c
index e0de1df2ede0..35799e6401c9 100644
--- a/drivers/pps/clients/pps-gpio.c
+++ b/drivers/pps/clients/pps-gpio.c
@@ -12,15 +12,14 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
+#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/pps_kernel.h>
-#include <linux/pps-gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/list.h>
-#include <linux/of_device.h>
-#include <linux/of_gpio.h>
+#include <linux/property.h>
#include <linux/timer.h>
#include <linux/jiffies.h>
@@ -100,51 +99,42 @@ static void pps_gpio_echo_timer_callback(struct timer_list *t)
gpiod_set_value(info->echo_pin, 0);
}
-static int pps_gpio_setup(struct platform_device *pdev)
+static int pps_gpio_setup(struct device *dev)
{
- struct pps_gpio_device_data *data = platform_get_drvdata(pdev);
- struct device_node *np = pdev->dev.of_node;
+ struct pps_gpio_device_data *data = dev_get_drvdata(dev);
int ret;
u32 value;
- data->gpio_pin = devm_gpiod_get(&pdev->dev,
- NULL, /* request "gpios" */
- GPIOD_IN);
- if (IS_ERR(data->gpio_pin)) {
- dev_err(&pdev->dev,
- "failed to request PPS GPIO\n");
- return PTR_ERR(data->gpio_pin);
+ data->gpio_pin = devm_gpiod_get(dev, NULL, GPIOD_IN);
+ if (IS_ERR(data->gpio_pin))
+ return dev_err_probe(dev, PTR_ERR(data->gpio_pin),
+ "failed to request PPS GPIO\n");
+
+ data->assert_falling_edge =
+ device_property_read_bool(dev, "assert-falling-edge");
+
+ data->echo_pin = devm_gpiod_get_optional(dev, "echo", GPIOD_OUT_LOW);
+ if (IS_ERR(data->echo_pin))
+ return dev_err_probe(dev, PTR_ERR(data->echo_pin),
+ "failed to request ECHO GPIO\n");
+
+ if (!data->echo_pin)
+ return 0;
+
+ ret = device_property_read_u32(dev, "echo-active-ms", &value);
+ if (ret) {
+ dev_err(dev, "failed to get echo-active-ms from FW\n");
+ return ret;
}
- data->echo_pin = devm_gpiod_get_optional(&pdev->dev,
- "echo",
- GPIOD_OUT_LOW);
- if (data->echo_pin) {
- if (IS_ERR(data->echo_pin)) {
- dev_err(&pdev->dev, "failed to request ECHO GPIO\n");
- return PTR_ERR(data->echo_pin);
- }
-
- ret = of_property_read_u32(np,
- "echo-active-ms",
- &value);
- if (ret) {
- dev_err(&pdev->dev,
- "failed to get echo-active-ms from OF\n");
- return ret;
- }
- data->echo_active_ms = value;
- /* sanity check on echo_active_ms */
- if (!data->echo_active_ms || data->echo_active_ms > 999) {
- dev_err(&pdev->dev,
- "echo-active-ms: %u - bad value from OF\n",
- data->echo_active_ms);
- return -EINVAL;
- }
+ /* sanity check on echo_active_ms */
+ if (!value || value > 999) {
+ dev_err(dev, "echo-active-ms: %u - bad value from FW\n", value);
+ return -EINVAL;
}
- if (of_property_read_bool(np, "assert-falling-edge"))
- data->assert_falling_edge = true;
+ data->echo_active_ms = value;
+
return 0;
}
@@ -165,34 +155,26 @@ get_irqf_trigger_flags(const struct pps_gpio_device_data *data)
static int pps_gpio_probe(struct platform_device *pdev)
{
struct pps_gpio_device_data *data;
+ struct device *dev = &pdev->dev;
int ret;
int pps_default_params;
- const struct pps_gpio_platform_data *pdata = pdev->dev.platform_data;
/* allocate space for device info */
- data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
- platform_set_drvdata(pdev, data);
+
+ dev_set_drvdata(dev, data);
/* GPIO setup */
- if (pdata) {
- data->gpio_pin = pdata->gpio_pin;
- data->echo_pin = pdata->echo_pin;
-
- data->assert_falling_edge = pdata->assert_falling_edge;
- data->capture_clear = pdata->capture_clear;
- data->echo_active_ms = pdata->echo_active_ms;
- } else {
- ret = pps_gpio_setup(pdev);
- if (ret)
- return -EINVAL;
- }
+ ret = pps_gpio_setup(dev);
+ if (ret)
+ return -EINVAL;
/* IRQ setup */
ret = gpiod_to_irq(data->gpio_pin);
if (ret < 0) {
- dev_err(&pdev->dev, "failed to map GPIO to IRQ: %d\n", ret);
+ dev_err(dev, "failed to map GPIO to IRQ: %d\n", ret);
return -EINVAL;
}
data->irq = ret;
@@ -218,17 +200,17 @@ static int pps_gpio_probe(struct platform_device *pdev)
pps_default_params |= PPS_CAPTURECLEAR | PPS_OFFSETCLEAR;
data->pps = pps_register_source(&data->info, pps_default_params);
if (IS_ERR(data->pps)) {
- dev_err(&pdev->dev, "failed to register IRQ %d as PPS source\n",
+ dev_err(dev, "failed to register IRQ %d as PPS source\n",
data->irq);
return PTR_ERR(data->pps);
}
/* register IRQ interrupt handler */
- ret = devm_request_irq(&pdev->dev, data->irq, pps_gpio_irq_handler,
+ ret = devm_request_irq(dev, data->irq, pps_gpio_irq_handler,
get_irqf_trigger_flags(data), data->info.name, data);
if (ret) {
pps_unregister_source(data->pps);
- dev_err(&pdev->dev, "failed to acquire IRQ %d\n", data->irq);
+ dev_err(dev, "failed to acquire IRQ %d\n", data->irq);
return -EINVAL;
}
@@ -243,11 +225,9 @@ static int pps_gpio_remove(struct platform_device *pdev)
struct pps_gpio_device_data *data = platform_get_drvdata(pdev);
pps_unregister_source(data->pps);
- if (data->echo_pin) {
- del_timer_sync(&data->echo_timer);
- /* reset echo pin in any case */
- gpiod_set_value(data->echo_pin, 0);
- }
+ del_timer_sync(&data->echo_timer);
+ /* reset echo pin in any case */
+ gpiod_set_value(data->echo_pin, 0);
dev_info(&pdev->dev, "removed IRQ %d as PPS source\n", data->irq);
return 0;
}
diff --git a/drivers/soundwire/Makefile b/drivers/soundwire/Makefile
index bf1e250d50dd..986776787b9e 100644
--- a/drivers/soundwire/Makefile
+++ b/drivers/soundwire/Makefile
@@ -20,7 +20,7 @@ soundwire-cadence-y := cadence_master.o
obj-$(CONFIG_SOUNDWIRE_CADENCE) += soundwire-cadence.o
#Intel driver
-soundwire-intel-y := intel.o intel_init.o
+soundwire-intel-y := intel.o intel_init.o dmi-quirks.o
obj-$(CONFIG_SOUNDWIRE_INTEL) += soundwire-intel.o
#Qualcomm driver
diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
index 46885429928a..a9e0aa72654d 100644
--- a/drivers/soundwire/bus.c
+++ b/drivers/soundwire/bus.c
@@ -44,13 +44,13 @@ int sdw_bus_master_add(struct sdw_bus *bus, struct device *parent,
}
ret = sdw_get_id(bus);
- if (ret) {
+ if (ret < 0) {
dev_err(parent, "Failed to get bus id\n");
return ret;
}
ret = sdw_master_device_add(bus, parent, fwnode);
- if (ret) {
+ if (ret < 0) {
dev_err(parent, "Failed to add master device at link %d\n",
bus->link_id);
return ret;
@@ -121,7 +121,7 @@ int sdw_bus_master_add(struct sdw_bus *bus, struct device *parent,
else
ret = -ENOTSUPP; /* No ACPI/DT so error out */
- if (ret) {
+ if (ret < 0) {
dev_err(bus->dev, "Finding slaves failed:%d\n", ret);
return ret;
}
@@ -422,7 +422,7 @@ sdw_bread_no_pm(struct sdw_bus *bus, u16 dev_num, u32 addr)
ret = sdw_fill_msg(&msg, NULL, addr, 1, dev_num,
SDW_MSG_FLAG_READ, &buf);
- if (ret)
+ if (ret < 0)
return ret;
ret = sdw_transfer(bus, &msg);
@@ -440,7 +440,7 @@ sdw_bwrite_no_pm(struct sdw_bus *bus, u16 dev_num, u32 addr, u8 value)
ret = sdw_fill_msg(&msg, NULL, addr, 1, dev_num,
SDW_MSG_FLAG_WRITE, &value);
- if (ret)
+ if (ret < 0)
return ret;
return sdw_transfer(bus, &msg);
@@ -454,7 +454,7 @@ int sdw_bread_no_pm_unlocked(struct sdw_bus *bus, u16 dev_num, u32 addr)
ret = sdw_fill_msg(&msg, NULL, addr, 1, dev_num,
SDW_MSG_FLAG_READ, &buf);
- if (ret)
+ if (ret < 0)
return ret;
ret = sdw_transfer_unlocked(bus, &msg);
@@ -472,7 +472,7 @@ int sdw_bwrite_no_pm_unlocked(struct sdw_bus *bus, u16 dev_num, u32 addr, u8 val
ret = sdw_fill_msg(&msg, NULL, addr, 1, dev_num,
SDW_MSG_FLAG_WRITE, &value);
- if (ret)
+ if (ret < 0)
return ret;
return sdw_transfer_unlocked(bus, &msg);
@@ -593,7 +593,7 @@ EXPORT_SYMBOL(sdw_write);
/* called with bus_lock held */
static struct sdw_slave *sdw_get_slave(struct sdw_bus *bus, int i)
{
- struct sdw_slave *slave = NULL;
+ struct sdw_slave *slave;
list_for_each_entry(slave, &bus->slaves, node) {
if (slave->dev_num == i)
@@ -603,7 +603,7 @@ static struct sdw_slave *sdw_get_slave(struct sdw_bus *bus, int i)
return NULL;
}
-static int sdw_compare_devid(struct sdw_slave *slave, struct sdw_slave_id id)
+int sdw_compare_devid(struct sdw_slave *slave, struct sdw_slave_id id)
{
if (slave->id.mfg_id != id.mfg_id ||
slave->id.part_id != id.part_id ||
@@ -614,6 +614,7 @@ static int sdw_compare_devid(struct sdw_slave *slave, struct sdw_slave_id id)
return 0;
}
+EXPORT_SYMBOL(sdw_compare_devid);
/* called with bus_lock held */
static int sdw_get_device_num(struct sdw_slave *slave)
@@ -698,6 +699,7 @@ void sdw_extract_slave_id(struct sdw_bus *bus,
"SDW Slave class_id 0x%02x, mfg_id 0x%04x, part_id 0x%04x, unique_id 0x%x, version 0x%x\n",
id->class_id, id->mfg_id, id->part_id, id->unique_id, id->sdw_version);
}
+EXPORT_SYMBOL(sdw_extract_slave_id);
static int sdw_program_device_num(struct sdw_bus *bus)
{
@@ -705,7 +707,7 @@ static int sdw_program_device_num(struct sdw_bus *bus)
struct sdw_slave *slave, *_s;
struct sdw_slave_id id;
struct sdw_msg msg;
- bool found = false;
+ bool found;
int count = 0, ret;
u64 addr;
@@ -737,6 +739,7 @@ static int sdw_program_device_num(struct sdw_bus *bus)
sdw_extract_slave_id(bus, addr, &id);
+ found = false;
/* Now compare with entries */
list_for_each_entry_safe(slave, _s, &bus->slaves, node) {
if (sdw_compare_devid(slave, id) == 0) {
@@ -749,7 +752,7 @@ static int sdw_program_device_num(struct sdw_bus *bus)
* dev_num
*/
ret = sdw_assign_device_num(slave);
- if (ret) {
+ if (ret < 0) {
dev_err(bus->dev,
"Assign dev_num failed:%d\n",
ret);
@@ -875,14 +878,18 @@ static int sdw_slave_clk_stop_prepare(struct sdw_slave *slave,
if (wake_en)
val |= SDW_SCP_SYSTEMCTRL_WAKE_UP_EN;
} else {
- val = sdw_read_no_pm(slave, SDW_SCP_SYSTEMCTRL);
-
+ ret = sdw_read_no_pm(slave, SDW_SCP_SYSTEMCTRL);
+ if (ret < 0) {
+ dev_err(&slave->dev, "SDW_SCP_SYSTEMCTRL read failed:%d\n", ret);
+ return ret;
+ }
+ val = ret;
val &= ~(SDW_SCP_SYSTEMCTRL_CLK_STP_PREP);
}
ret = sdw_write_no_pm(slave, SDW_SCP_SYSTEMCTRL, val);
- if (ret != 0)
+ if (ret < 0)
dev_err(&slave->dev,
"Clock Stop prepare failed for slave: %d", ret);
@@ -895,11 +902,15 @@ static int sdw_bus_wait_for_clk_prep_deprep(struct sdw_bus *bus, u16 dev_num)
int val;
do {
- val = sdw_bread_no_pm(bus, dev_num, SDW_SCP_STAT) &
- SDW_SCP_STAT_CLK_STP_NF;
+ val = sdw_bread_no_pm(bus, dev_num, SDW_SCP_STAT);
+ if (val < 0) {
+ dev_err(bus->dev, "SDW_SCP_STAT bread failed:%d\n", val);
+ return val;
+ }
+ val &= SDW_SCP_STAT_CLK_STP_NF;
if (!val) {
- dev_info(bus->dev, "clock stop prep/de-prep done slave:%d",
- dev_num);
+ dev_dbg(bus->dev, "clock stop prep/de-prep done slave:%d",
+ dev_num);
return 0;
}
@@ -1253,6 +1264,7 @@ static int sdw_slave_set_frequency(struct sdw_slave *slave)
static int sdw_initialize_slave(struct sdw_slave *slave)
{
struct sdw_slave_prop *prop = &slave->prop;
+ int status;
int ret;
u8 val;
@@ -1260,6 +1272,44 @@ static int sdw_initialize_slave(struct sdw_slave *slave)
if (ret < 0)
return ret;
+ if (slave->bus->prop.quirks & SDW_MASTER_QUIRKS_CLEAR_INITIAL_CLASH) {
+ /* Clear bus clash interrupt before enabling interrupt mask */
+ status = sdw_read_no_pm(slave, SDW_SCP_INT1);
+ if (status < 0) {
+ dev_err(&slave->dev,
+ "SDW_SCP_INT1 (BUS_CLASH) read failed:%d\n", status);
+ return status;
+ }
+ if (status & SDW_SCP_INT1_BUS_CLASH) {
+ dev_warn(&slave->dev, "Bus clash detected before INT mask is enabled\n");
+ ret = sdw_write_no_pm(slave, SDW_SCP_INT1, SDW_SCP_INT1_BUS_CLASH);
+ if (ret < 0) {
+ dev_err(&slave->dev,
+ "SDW_SCP_INT1 (BUS_CLASH) write failed:%d\n", ret);
+ return ret;
+ }
+ }
+ }
+ if ((slave->bus->prop.quirks & SDW_MASTER_QUIRKS_CLEAR_INITIAL_PARITY) &&
+ !(slave->prop.quirks & SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY)) {
+ /* Clear parity interrupt before enabling interrupt mask */
+ status = sdw_read_no_pm(slave, SDW_SCP_INT1);
+ if (status < 0) {
+ dev_err(&slave->dev,
+ "SDW_SCP_INT1 (PARITY) read failed:%d\n", status);
+ return status;
+ }
+ if (status & SDW_SCP_INT1_PARITY) {
+ dev_warn(&slave->dev, "PARITY error detected before INT mask is enabled\n");
+ ret = sdw_write_no_pm(slave, SDW_SCP_INT1, SDW_SCP_INT1_PARITY);
+ if (ret < 0) {
+ dev_err(&slave->dev,
+ "SDW_SCP_INT1 (PARITY) write failed:%d\n", ret);
+ return ret;
+ }
+ }
+ }
+
/*
* Set SCP_INT1_MASK register, typically bus clash and
* implementation-defined interrupt mask. The Parity detection
@@ -1589,7 +1639,7 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
ret = sdw_read_no_pm(slave, SDW_SCP_INT1);
if (ret < 0) {
dev_err(&slave->dev,
- "SDW_SCP_INT1 read failed:%d\n", ret);
+ "SDW_SCP_INT1 recheck read failed:%d\n", ret);
goto io_err;
}
_buf = ret;
@@ -1597,7 +1647,7 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
ret = sdw_nread_no_pm(slave, SDW_SCP_INTSTAT2, 2, _buf2);
if (ret < 0) {
dev_err(&slave->dev,
- "SDW_SCP_INT2/3 read failed:%d\n", ret);
+ "SDW_SCP_INT2/3 recheck read failed:%d\n", ret);
goto io_err;
}
@@ -1605,7 +1655,7 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
ret = sdw_read_no_pm(slave, SDW_DP0_INT);
if (ret < 0) {
dev_err(&slave->dev,
- "SDW_DP0_INT read failed:%d\n", ret);
+ "SDW_DP0_INT recheck read failed:%d\n", ret);
goto io_err;
}
sdca_cascade = ret & SDW_DP0_SDCA_CASCADE;
@@ -1701,7 +1751,7 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
if (status[0] == SDW_SLAVE_ATTACHED) {
dev_dbg(bus->dev, "Slave attached, programming device number\n");
ret = sdw_program_device_num(bus);
- if (ret)
+ if (ret < 0)
dev_err(bus->dev, "Slave attach failed: %d\n", ret);
/*
* programming a device number will have side effects,
@@ -1735,7 +1785,7 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
case SDW_SLAVE_ALERT:
ret = sdw_handle_slave_alerts(slave);
- if (ret)
+ if (ret < 0)
dev_err(&slave->dev,
"Slave %d alert handling failed: %d\n",
i, ret);
@@ -1754,7 +1804,7 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
attached_initializing = true;
ret = sdw_initialize_slave(slave);
- if (ret)
+ if (ret < 0)
dev_err(&slave->dev,
"Slave %d initialization failed: %d\n",
i, ret);
@@ -1768,7 +1818,7 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
}
ret = sdw_update_slave_status(slave, status[i]);
- if (ret)
+ if (ret < 0)
dev_err(&slave->dev,
"Update Slave status failed:%d\n", ret);
if (attached_initializing) {
diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
index 2e049d39c6e5..40354469860a 100644
--- a/drivers/soundwire/bus.h
+++ b/drivers/soundwire/bus.h
@@ -7,6 +7,8 @@
#define DEFAULT_BANK_SWITCH_TIMEOUT 3000
#define DEFAULT_PROBE_TIMEOUT 2000
+u64 sdw_dmi_override_adr(struct sdw_bus *bus, u64 addr);
+
#if IS_ENABLED(CONFIG_ACPI)
int sdw_acpi_find_slaves(struct sdw_bus *bus);
#else
diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
index 575b9bad99d5..893296f3fe39 100644
--- a/drivers/soundwire/bus_type.c
+++ b/drivers/soundwire/bus_type.c
@@ -82,6 +82,7 @@ static int sdw_drv_probe(struct device *dev)
struct sdw_slave *slave = dev_to_sdw_dev(dev);
struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
const struct sdw_device_id *id;
+ const char *name;
int ret;
/*
@@ -108,7 +109,10 @@ static int sdw_drv_probe(struct device *dev)
ret = drv->probe(slave, id);
if (ret) {
- dev_err(dev, "Probe of %s failed: %d\n", drv->name, ret);
+ name = drv->name;
+ if (!name)
+ name = drv->driver.name;
+ dev_err(dev, "Probe of %s failed: %d\n", name, ret);
dev_pm_domain_detach(dev, false);
return ret;
}
@@ -174,11 +178,16 @@ static void sdw_drv_shutdown(struct device *dev)
*/
int __sdw_register_driver(struct sdw_driver *drv, struct module *owner)
{
+ const char *name;
+
drv->driver.bus = &sdw_bus_type;
if (!drv->probe) {
- pr_err("driver %s didn't provide SDW probe routine\n",
- drv->name);
+ name = drv->name;
+ if (!name)
+ name = drv->driver.name;
+
+ pr_err("driver %s didn't provide SDW probe routine\n", name);
return -EINVAL;
}
diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index d05442e646a3..192dac10f0c2 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -905,7 +905,7 @@ irqreturn_t sdw_cdns_irq(int irq, void *dev_id)
EXPORT_SYMBOL(sdw_cdns_irq);
/**
- * To update slave status in a work since we will need to handle
+ * cdns_update_slave_status_work - update slave status in a work since we will need to handle
* other interrupts eg. CDNS_MCP_INT_RX_WL during the update slave
* process.
* @work: cdns worker thread
@@ -968,7 +968,7 @@ int sdw_cdns_exit_reset(struct sdw_cdns *cdns)
EXPORT_SYMBOL(sdw_cdns_exit_reset);
/**
- * sdw_cdns_enable_slave_interrupt() - Enable SDW slave interrupts
+ * cdns_enable_slave_interrupts() - Enable SDW slave interrupts
* @cdns: Cadence instance
* @state: boolean for true/false
*/
@@ -1450,10 +1450,12 @@ int sdw_cdns_clock_stop(struct sdw_cdns *cdns, bool block_wake)
}
/* Prepare slaves for clock stop */
- ret = sdw_bus_prep_clk_stop(&cdns->bus);
- if (ret < 0) {
- dev_err(cdns->dev, "prepare clock stop failed %d", ret);
- return ret;
+ if (slave_present) {
+ ret = sdw_bus_prep_clk_stop(&cdns->bus);
+ if (ret < 0 && ret != -ENODATA) {
+ dev_err(cdns->dev, "prepare clock stop failed %d\n", ret);
+ return ret;
+ }
}
/*
@@ -1462,7 +1464,7 @@ int sdw_cdns_clock_stop(struct sdw_cdns *cdns, bool block_wake)
*/
ret = sdw_bus_clk_stop(&cdns->bus);
if (ret < 0 && slave_present && ret != -ENODATA) {
- dev_err(cdns->dev, "bus clock stop failed %d", ret);
+ dev_err(cdns->dev, "bus clock stop failed %d\n", ret);
return ret;
}
diff --git a/drivers/soundwire/dmi-quirks.c b/drivers/soundwire/dmi-quirks.c
new file mode 100644
index 000000000000..82061c1d9835
--- /dev/null
+++ b/drivers/soundwire/dmi-quirks.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
+// Copyright(c) 2021 Intel Corporation.
+
+/*
+ * Soundwire DMI quirks
+ */
+
+#include <linux/device.h>
+#include <linux/dmi.h>
+#include <linux/soundwire/sdw.h>
+#include "bus.h"
+
+struct adr_remap {
+ u64 adr;
+ u64 remapped_adr;
+};
+
+/*
+ * HP Spectre 360 Convertible devices do not expose the correct _ADR
+ * in the DSDT.
+ * Remap the bad _ADR values to the ones reported by hardware
+ */
+static const struct adr_remap hp_spectre_360[] = {
+ {
+ 0x000010025D070100,
+ 0x000020025D071100
+ },
+ {
+ 0x000110025d070100,
+ 0x000120025D130800
+ },
+ {}
+};
+
+/*
+ * The initial version of the Dell SKU 0A3E did not expose the devices
+ * on the correct links.
+ */
+static const struct adr_remap dell_sku_0A3E[] = {
+ /* rt715 on link0 */
+ {
+ 0x00020025d071100,
+ 0x00021025d071500
+ },
+ /* rt711 on link1 */
+ {
+ 0x000120025d130800,
+ 0x000120025d071100,
+ },
+ /* rt1308 on link2 */
+ {
+ 0x000220025d071500,
+ 0x000220025d130800
+ },
+ {}
+};
+
+static const struct dmi_system_id adr_remap_quirk_table[] = {
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Convertible"),
+ },
+ .driver_data = (void *)hp_spectre_360,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A3E")
+ },
+ .driver_data = (void *)dell_sku_0A3E,
+ },
+ {}
+};
+
+u64 sdw_dmi_override_adr(struct sdw_bus *bus, u64 addr)
+{
+ const struct dmi_system_id *dmi_id;
+
+ /* check if any address remap quirk applies */
+ dmi_id = dmi_first_match(adr_remap_quirk_table);
+ if (dmi_id) {
+ struct adr_remap *map = dmi_id->driver_data;
+
+ for (map = dmi_id->driver_data; map->adr; map++) {
+ if (map->adr == addr) {
+ dev_dbg(bus->dev, "remapped _ADR 0x%llx as 0x%llx\n",
+ addr, map->remapped_adr);
+ addr = map->remapped_adr;
+ break;
+ }
+ }
+ }
+
+ return addr;
+}
diff --git a/drivers/soundwire/generic_bandwidth_allocation.c b/drivers/soundwire/generic_bandwidth_allocation.c
index 0bdef38c9a30..84d129587084 100644
--- a/drivers/soundwire/generic_bandwidth_allocation.c
+++ b/drivers/soundwire/generic_bandwidth_allocation.c
@@ -62,7 +62,7 @@ static void sdw_compute_slave_ports(struct sdw_master_runtime *m_rt,
sample_int, port_bo, port_bo >> 8,
t_data->hstart,
t_data->hstop,
- (SDW_BLK_GRP_CNT_1 * ch), 0x0);
+ SDW_BLK_PKG_PER_PORT, 0x0);
sdw_fill_port_params(&p_rt->port_params,
p_rt->num, bps,
@@ -95,7 +95,7 @@ static void sdw_compute_master_ports(struct sdw_master_runtime *m_rt,
struct sdw_bus *bus = m_rt->bus;
struct sdw_bus_params *b_params = &bus->params;
int sample_int, hstart = 0;
- unsigned int rate, bps, ch, no_ch;
+ unsigned int rate, bps, ch;
rate = m_rt->stream->params.rate;
bps = m_rt->stream->params.bps;
@@ -110,12 +110,11 @@ static void sdw_compute_master_ports(struct sdw_master_runtime *m_rt,
t_data.hstart = hstart;
list_for_each_entry(p_rt, &m_rt->port_list, port_node) {
- no_ch = sdw_ch_mask_to_ch(p_rt->ch_mask);
sdw_fill_xport_params(&p_rt->transport_params, p_rt->num,
false, SDW_BLK_GRP_CNT_1, sample_int,
port_bo, port_bo >> 8, hstart, hstop,
- (SDW_BLK_GRP_CNT_1 * no_ch), 0x0);
+ SDW_BLK_PKG_PER_PORT, 0x0);
sdw_fill_port_params(&p_rt->port_params,
p_rt->num, bps,
@@ -143,7 +142,7 @@ static void sdw_compute_master_ports(struct sdw_master_runtime *m_rt,
static void _sdw_compute_port_params(struct sdw_bus *bus,
struct sdw_group_params *params, int count)
{
- struct sdw_master_runtime *m_rt = NULL;
+ struct sdw_master_runtime *m_rt;
int hstop = bus->params.col - 1;
int block_offset, port_bo, i;
@@ -169,7 +168,7 @@ static int sdw_compute_group_params(struct sdw_bus *bus,
struct sdw_group_params *params,
int *rates, int count)
{
- struct sdw_master_runtime *m_rt = NULL;
+ struct sdw_master_runtime *m_rt;
int sel_col = bus->params.col;
unsigned int rate, bps, ch;
int i, column_needed = 0;
@@ -406,14 +405,14 @@ int sdw_compute_params(struct sdw_bus *bus)
/* Computes clock frequency, frame shape and frame frequency */
ret = sdw_compute_bus_params(bus);
if (ret < 0) {
- dev_err(bus->dev, "Compute bus params failed: %d", ret);
+ dev_err(bus->dev, "Compute bus params failed: %d\n", ret);
return ret;
}
/* Compute transport and port params */
ret = sdw_compute_port_params(bus);
if (ret < 0) {
- dev_err(bus->dev, "Compute transport params failed: %d", ret);
+ dev_err(bus->dev, "Compute transport params failed: %d\n", ret);
return ret;
}
diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index a2d5cdaa9998..fd95f94630b1 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -561,8 +561,6 @@ static int intel_link_power_down(struct sdw_intel *sdw)
ret = intel_clear_bit(shim, SDW_SHIM_LCTL, link_control, cpa_mask);
}
- link_control = intel_readl(shim, SDW_SHIM_LCTL);
-
mutex_unlock(sdw->link_res->shim_lock);
if (ret < 0) {
@@ -997,7 +995,7 @@ static int intel_prepare(struct snd_pcm_substream *substream,
dma = snd_soc_dai_get_dma_data(dai, substream);
if (!dma) {
- dev_err(dai->dev, "failed to get dma data in %s",
+ dev_err(dai->dev, "failed to get dma data in %s\n",
__func__);
return -EIO;
}
@@ -1061,7 +1059,7 @@ intel_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
ret = intel_free_stream(sdw, substream, dai, sdw->instance);
if (ret < 0) {
- dev_err(dai->dev, "intel_free_stream: failed %d", ret);
+ dev_err(dai->dev, "intel_free_stream: failed %d\n", ret);
return ret;
}
@@ -1286,6 +1284,9 @@ static int sdw_master_read_intel_prop(struct sdw_bus *bus)
if (quirk_mask & SDW_INTEL_QUIRK_MASK_BUS_DISABLE)
prop->hw_disabled = true;
+ prop->quirks = SDW_MASTER_QUIRKS_CLEAR_INITIAL_CLASH |
+ SDW_MASTER_QUIRKS_CLEAR_INITIAL_PARITY;
+
return 0;
}
@@ -1302,6 +1303,7 @@ static int intel_prop_read(struct sdw_bus *bus)
static struct sdw_master_ops sdw_intel_ops = {
.read_prop = sdw_master_read_prop,
+ .override_adr = sdw_dmi_override_adr,
.xfer_msg = cdns_xfer_msg,
.xfer_msg_defer = cdns_xfer_msg_defer,
.reset_page_addr = cdns_reset_page_addr,
@@ -1630,7 +1632,7 @@ static int __maybe_unused intel_suspend(struct device *dev)
ret = intel_link_power_down(sdw);
if (ret) {
- dev_err(dev, "Link power down failed: %d", ret);
+ dev_err(dev, "Link power down failed: %d\n", ret);
return ret;
}
@@ -1665,7 +1667,7 @@ static int __maybe_unused intel_suspend_runtime(struct device *dev)
ret = intel_link_power_down(sdw);
if (ret) {
- dev_err(dev, "Link power down failed: %d", ret);
+ dev_err(dev, "Link power down failed: %d\n", ret);
return ret;
}
@@ -1689,7 +1691,7 @@ static int __maybe_unused intel_suspend_runtime(struct device *dev)
ret = intel_link_power_down(sdw);
if (ret) {
- dev_err(dev, "Link power down failed: %d", ret);
+ dev_err(dev, "Link power down failed: %d\n", ret);
return ret;
}
@@ -1738,7 +1740,7 @@ static int __maybe_unused intel_resume(struct device *dev)
ret = intel_init(sdw);
if (ret) {
- dev_err(dev, "%s failed: %d", __func__, ret);
+ dev_err(dev, "%s failed: %d\n", __func__, ret);
return ret;
}
@@ -1822,7 +1824,7 @@ static int __maybe_unused intel_resume_runtime(struct device *dev)
if (clock_stop_quirks & SDW_INTEL_CLK_STOP_TEARDOWN) {
ret = intel_init(sdw);
if (ret) {
- dev_err(dev, "%s failed: %d", __func__, ret);
+ dev_err(dev, "%s failed: %d\n", __func__, ret);
return ret;
}
@@ -1867,7 +1869,7 @@ static int __maybe_unused intel_resume_runtime(struct device *dev)
} else if (clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET) {
ret = intel_init(sdw);
if (ret) {
- dev_err(dev, "%s failed: %d", __func__, ret);
+ dev_err(dev, "%s failed: %d\n", __func__, ret);
return ret;
}
@@ -1945,7 +1947,7 @@ static int __maybe_unused intel_resume_runtime(struct device *dev)
ret = intel_init(sdw);
if (ret) {
- dev_err(dev, "%s failed: %d", __func__, ret);
+ dev_err(dev, "%s failed: %d\n", __func__, ret);
return ret;
}
diff --git a/drivers/soundwire/intel_init.c b/drivers/soundwire/intel_init.c
index 05b726cdfebc..30ce95ec2d70 100644
--- a/drivers/soundwire/intel_init.c
+++ b/drivers/soundwire/intel_init.c
@@ -178,6 +178,15 @@ static struct sdw_intel_ctx
link->pdev = pdev;
link->cdns = platform_get_drvdata(pdev);
+ if (!link->cdns) {
+ dev_err(&adev->dev, "failed to get link->cdns\n");
+ /*
+ * 1 will be subtracted from i in the err label, but we need to call
+ * intel_link_dev_unregister for this ldev, so plus 1 now
+ */
+ i++;
+ goto err;
+ }
list_add_tail(&link->list, &ctx->link_list);
bus = &link->cdns->bus;
/* Calculate number of slaves */
diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c
index 6d22df01f354..2827085a323b 100644
--- a/drivers/soundwire/qcom.c
+++ b/drivers/soundwire/qcom.c
@@ -24,28 +24,50 @@
#define SWRM_COMP_CFG_IRQ_LEVEL_OR_PULSE_MSK BIT(1)
#define SWRM_COMP_CFG_ENABLE_MSK BIT(0)
#define SWRM_COMP_PARAMS 0x100
+#define SWRM_COMP_PARAMS_WR_FIFO_DEPTH GENMASK(14, 10)
+#define SWRM_COMP_PARAMS_RD_FIFO_DEPTH GENMASK(19, 15)
#define SWRM_COMP_PARAMS_DOUT_PORTS_MASK GENMASK(4, 0)
#define SWRM_COMP_PARAMS_DIN_PORTS_MASK GENMASK(9, 5)
#define SWRM_INTERRUPT_STATUS 0x200
#define SWRM_INTERRUPT_STATUS_RMSK GENMASK(16, 0)
+#define SWRM_INTERRUPT_STATUS_SLAVE_PEND_IRQ BIT(0)
#define SWRM_INTERRUPT_STATUS_NEW_SLAVE_ATTACHED BIT(1)
#define SWRM_INTERRUPT_STATUS_CHANGE_ENUM_SLAVE_STATUS BIT(2)
+#define SWRM_INTERRUPT_STATUS_MASTER_CLASH_DET BIT(3)
+#define SWRM_INTERRUPT_STATUS_RD_FIFO_OVERFLOW BIT(4)
+#define SWRM_INTERRUPT_STATUS_RD_FIFO_UNDERFLOW BIT(5)
+#define SWRM_INTERRUPT_STATUS_WR_CMD_FIFO_OVERFLOW BIT(6)
#define SWRM_INTERRUPT_STATUS_CMD_ERROR BIT(7)
+#define SWRM_INTERRUPT_STATUS_DOUT_PORT_COLLISION BIT(8)
+#define SWRM_INTERRUPT_STATUS_READ_EN_RD_VALID_MISMATCH BIT(9)
#define SWRM_INTERRUPT_STATUS_SPECIAL_CMD_ID_FINISHED BIT(10)
+#define SWRM_INTERRUPT_STATUS_BUS_RESET_FINISHED_V2 BIT(13)
+#define SWRM_INTERRUPT_STATUS_CLK_STOP_FINISHED_V2 BIT(14)
+#define SWRM_INTERRUPT_STATUS_EXT_CLK_STOP_WAKEUP BIT(16)
+#define SWRM_INTERRUPT_MAX 17
#define SWRM_INTERRUPT_MASK_ADDR 0x204
#define SWRM_INTERRUPT_CLEAR 0x208
#define SWRM_INTERRUPT_CPU_EN 0x210
#define SWRM_CMD_FIFO_WR_CMD 0x300
#define SWRM_CMD_FIFO_RD_CMD 0x304
#define SWRM_CMD_FIFO_CMD 0x308
+#define SWRM_CMD_FIFO_FLUSH 0x1
#define SWRM_CMD_FIFO_STATUS 0x30C
+#define SWRM_RD_CMD_FIFO_CNT_MASK GENMASK(20, 16)
+#define SWRM_WR_CMD_FIFO_CNT_MASK GENMASK(12, 8)
#define SWRM_CMD_FIFO_CFG_ADDR 0x314
+#define SWRM_CONTINUE_EXEC_ON_CMD_IGNORE BIT(31)
#define SWRM_RD_WR_CMD_RETRIES 0x7
#define SWRM_CMD_FIFO_RD_FIFO_ADDR 0x318
+#define SWRM_RD_FIFO_CMD_ID_MASK GENMASK(11, 8)
#define SWRM_ENUMERATOR_CFG_ADDR 0x500
+#define SWRM_ENUMERATOR_SLAVE_DEV_ID_1(m) (0x530 + 0x8 * (m))
+#define SWRM_ENUMERATOR_SLAVE_DEV_ID_2(m) (0x534 + 0x8 * (m))
#define SWRM_MCP_FRAME_CTRL_BANK_ADDR(m) (0x101C + 0x40 * (m))
#define SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_BMSK GENMASK(2, 0)
#define SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_BMSK GENMASK(7, 3)
+#define SWRM_MCP_BUS_CTRL 0x1044
+#define SWRM_MCP_BUS_CLK_START BIT(1)
#define SWRM_MCP_CFG_ADDR 0x1048
#define SWRM_MCP_CFG_MAX_NUM_OF_CMD_NO_PINGS_BMSK GENMASK(21, 17)
#define SWRM_DEF_CMD_NO_PINGS 0x1f
@@ -53,8 +75,15 @@
#define SWRM_MCP_STATUS_BANK_NUM_MASK BIT(0)
#define SWRM_MCP_SLV_STATUS 0x1090
#define SWRM_MCP_SLV_STATUS_MASK GENMASK(1, 0)
+#define SWRM_MCP_SLV_STATUS_SZ 2
#define SWRM_DP_PORT_CTRL_BANK(n, m) (0x1124 + 0x100 * (n - 1) + 0x40 * m)
+#define SWRM_DP_PORT_CTRL_2_BANK(n, m) (0x1128 + 0x100 * (n - 1) + 0x40 * m)
+#define SWRM_DP_BLOCK_CTRL_1(n) (0x112C + 0x100 * (n - 1))
+#define SWRM_DP_BLOCK_CTRL2_BANK(n, m) (0x1130 + 0x100 * (n - 1) + 0x40 * m)
+#define SWRM_DP_PORT_HCTRL_BANK(n, m) (0x1134 + 0x100 * (n - 1) + 0x40 * m)
#define SWRM_DP_BLOCK_CTRL3_BANK(n, m) (0x1138 + 0x100 * (n - 1) + 0x40 * m)
+#define SWRM_DIN_DPn_PCM_PORT_CTRL(n) (0x1054 + 0x100 * (n - 1))
+
#define SWRM_DP_PORT_CTRL_EN_CHAN_SHFT 0x18
#define SWRM_DP_PORT_CTRL_OFFSET2_SHFT 0x10
#define SWRM_DP_PORT_CTRL_OFFSET1_SHFT 0x08
@@ -69,16 +98,28 @@
#define SWRM_SPECIAL_CMD_ID 0xF
#define MAX_FREQ_NUM 1
#define TIMEOUT_MS (2 * HZ)
-#define QCOM_SWRM_MAX_RD_LEN 0xf
+#define QCOM_SWRM_MAX_RD_LEN 0x1
#define QCOM_SDW_MAX_PORTS 14
#define DEFAULT_CLK_FREQ 9600000
#define SWRM_MAX_DAIS 0xF
+#define SWR_INVALID_PARAM 0xFF
+#define SWR_HSTOP_MAX_VAL 0xF
+#define SWR_HSTART_MIN_VAL 0x0
+#define SWR_BROADCAST_CMD_ID 0x0F
+#define SWR_MAX_CMD_ID 14
+#define MAX_FIFO_RD_RETRY 3
+#define SWR_OVERFLOW_RETRY_COUNT 30
struct qcom_swrm_port_config {
u8 si;
u8 off1;
u8 off2;
u8 bp_mode;
+ u8 hstart;
+ u8 hstop;
+ u8 word_length;
+ u8 blk_group_count;
+ u8 lane_control;
};
struct qcom_swrm_ctrl {
@@ -86,10 +127,9 @@ struct qcom_swrm_ctrl {
struct device *dev;
struct regmap *regmap;
void __iomem *mmio;
- struct completion *comp;
+ struct completion broadcast;
+ struct completion enumeration;
struct work_struct slave_work;
- /* read/write lock */
- spinlock_t comp_lock;
/* Port alloc/free lock */
struct mutex port_lock;
struct clk *hclk;
@@ -103,11 +143,17 @@ struct qcom_swrm_ctrl {
int rows_index;
unsigned long dout_port_mask;
unsigned long din_port_mask;
+ u32 intr_mask;
+ u8 rcmd_id;
+ u8 wcmd_id;
struct qcom_swrm_port_config pconfig[QCOM_SDW_MAX_PORTS];
struct sdw_stream_runtime *sruntime[SWRM_MAX_DAIS];
enum sdw_slave_status status[SDW_MAX_DEVICES];
int (*reg_read)(struct qcom_swrm_ctrl *ctrl, int reg, u32 *val);
int (*reg_write)(struct qcom_swrm_ctrl *ctrl, int reg, int val);
+ u32 slave_status;
+ u32 wr_fifo_depth;
+ u32 rd_fifo_depth;
};
struct qcom_swrm_data {
@@ -181,77 +227,180 @@ static int qcom_swrm_cpu_reg_write(struct qcom_swrm_ctrl *ctrl, int reg,
return SDW_CMD_OK;
}
-static int qcom_swrm_cmd_fifo_wr_cmd(struct qcom_swrm_ctrl *ctrl, u8 cmd_data,
+static u32 swrm_get_packed_reg_val(u8 *cmd_id, u8 cmd_data,
+ u8 dev_addr, u16 reg_addr)
+{
+ u32 val;
+ u8 id = *cmd_id;
+
+ if (id != SWR_BROADCAST_CMD_ID) {
+ if (id < SWR_MAX_CMD_ID)
+ id += 1;
+ else
+ id = 0;
+ *cmd_id = id;
+ }
+ val = SWRM_REG_VAL_PACK(cmd_data, dev_addr, id, reg_addr);
+
+ return val;
+}
+
+static int swrm_wait_for_rd_fifo_avail(struct qcom_swrm_ctrl *swrm)
+{
+ u32 fifo_outstanding_data, value;
+ int fifo_retry_count = SWR_OVERFLOW_RETRY_COUNT;
+
+ do {
+ /* Check for fifo underflow during read */
+ swrm->reg_read(swrm, SWRM_CMD_FIFO_STATUS, &value);
+ fifo_outstanding_data = FIELD_GET(SWRM_RD_CMD_FIFO_CNT_MASK, value);
+
+ /* Check if read data is available in read fifo */
+ if (fifo_outstanding_data > 0)
+ return 0;
+
+ usleep_range(500, 510);
+ } while (fifo_retry_count--);
+
+ if (fifo_outstanding_data == 0) {
+ dev_err_ratelimited(swrm->dev, "%s err read underflow\n", __func__);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int swrm_wait_for_wr_fifo_avail(struct qcom_swrm_ctrl *swrm)
+{
+ u32 fifo_outstanding_cmds, value;
+ int fifo_retry_count = SWR_OVERFLOW_RETRY_COUNT;
+
+ do {
+ /* Check for fifo overflow during write */
+ swrm->reg_read(swrm, SWRM_CMD_FIFO_STATUS, &value);
+ fifo_outstanding_cmds = FIELD_GET(SWRM_WR_CMD_FIFO_CNT_MASK, value);
+
+ /* Check for space in write fifo before writing */
+ if (fifo_outstanding_cmds < swrm->wr_fifo_depth)
+ return 0;
+
+ usleep_range(500, 510);
+ } while (fifo_retry_count--);
+
+ if (fifo_outstanding_cmds == swrm->wr_fifo_depth) {
+ dev_err_ratelimited(swrm->dev, "%s err write overflow\n", __func__);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int qcom_swrm_cmd_fifo_wr_cmd(struct qcom_swrm_ctrl *swrm, u8 cmd_data,
u8 dev_addr, u16 reg_addr)
{
- DECLARE_COMPLETION_ONSTACK(comp);
- unsigned long flags;
+
u32 val;
- int ret;
+ int ret = 0;
+ u8 cmd_id = 0x0;
- spin_lock_irqsave(&ctrl->comp_lock, flags);
- ctrl->comp = &comp;
- spin_unlock_irqrestore(&ctrl->comp_lock, flags);
- val = SWRM_REG_VAL_PACK(cmd_data, dev_addr,
- SWRM_SPECIAL_CMD_ID, reg_addr);
- ret = ctrl->reg_write(ctrl, SWRM_CMD_FIFO_WR_CMD, val);
- if (ret)
- goto err;
+ if (dev_addr == SDW_BROADCAST_DEV_NUM) {
+ cmd_id = SWR_BROADCAST_CMD_ID;
+ val = swrm_get_packed_reg_val(&cmd_id, cmd_data,
+ dev_addr, reg_addr);
+ } else {
+ val = swrm_get_packed_reg_val(&swrm->wcmd_id, cmd_data,
+ dev_addr, reg_addr);
+ }
- ret = wait_for_completion_timeout(ctrl->comp,
- msecs_to_jiffies(TIMEOUT_MS));
+ if (swrm_wait_for_wr_fifo_avail(swrm))
+ return SDW_CMD_FAIL_OTHER;
+
+ /* Its assumed that write is okay as we do not get any status back */
+ swrm->reg_write(swrm, SWRM_CMD_FIFO_WR_CMD, val);
+
+ /* version 1.3 or less */
+ if (swrm->version <= 0x01030000)
+ usleep_range(150, 155);
+
+ if (cmd_id == SWR_BROADCAST_CMD_ID) {
+ /*
+ * sleep for 10ms for MSM soundwire variant to allow broadcast
+ * command to complete.
+ */
+ ret = wait_for_completion_timeout(&swrm->broadcast,
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret)
+ ret = SDW_CMD_IGNORED;
+ else
+ ret = SDW_CMD_OK;
- if (!ret)
- ret = SDW_CMD_IGNORED;
- else
+ } else {
ret = SDW_CMD_OK;
-err:
- spin_lock_irqsave(&ctrl->comp_lock, flags);
- ctrl->comp = NULL;
- spin_unlock_irqrestore(&ctrl->comp_lock, flags);
-
+ }
return ret;
}
-static int qcom_swrm_cmd_fifo_rd_cmd(struct qcom_swrm_ctrl *ctrl,
+static int qcom_swrm_cmd_fifo_rd_cmd(struct qcom_swrm_ctrl *swrm,
u8 dev_addr, u16 reg_addr,
u32 len, u8 *rval)
{
- int i, ret;
- u32 val;
- DECLARE_COMPLETION_ONSTACK(comp);
- unsigned long flags;
+ u32 cmd_data, cmd_id, val, retry_attempt = 0;
+
+ val = swrm_get_packed_reg_val(&swrm->rcmd_id, len, dev_addr, reg_addr);
+
+ /* wait for FIFO RD to complete to avoid overflow */
+ usleep_range(100, 105);
+ swrm->reg_write(swrm, SWRM_CMD_FIFO_RD_CMD, val);
+ /* wait for FIFO RD CMD complete to avoid overflow */
+ usleep_range(250, 255);
+
+ if (swrm_wait_for_rd_fifo_avail(swrm))
+ return SDW_CMD_FAIL_OTHER;
+
+ do {
+ swrm->reg_read(swrm, SWRM_CMD_FIFO_RD_FIFO_ADDR, &cmd_data);
+ rval[0] = cmd_data & 0xFF;
+ cmd_id = FIELD_GET(SWRM_RD_FIFO_CMD_ID_MASK, cmd_data);
+
+ if (cmd_id != swrm->rcmd_id) {
+ if (retry_attempt < (MAX_FIFO_RD_RETRY - 1)) {
+ /* wait 500 us before retry on fifo read failure */
+ usleep_range(500, 505);
+ swrm->reg_write(swrm, SWRM_CMD_FIFO_CMD,
+ SWRM_CMD_FIFO_FLUSH);
+ swrm->reg_write(swrm, SWRM_CMD_FIFO_RD_CMD, val);
+ }
+ retry_attempt++;
+ } else {
+ return SDW_CMD_OK;
+ }
- spin_lock_irqsave(&ctrl->comp_lock, flags);
- ctrl->comp = &comp;
- spin_unlock_irqrestore(&ctrl->comp_lock, flags);
+ } while (retry_attempt < MAX_FIFO_RD_RETRY);
- val = SWRM_REG_VAL_PACK(len, dev_addr, SWRM_SPECIAL_CMD_ID, reg_addr);
- ret = ctrl->reg_write(ctrl, SWRM_CMD_FIFO_RD_CMD, val);
- if (ret)
- goto err;
+ dev_err(swrm->dev, "failed to read fifo: reg: 0x%x, rcmd_id: 0x%x,\
+ dev_num: 0x%x, cmd_data: 0x%x\n",
+ reg_addr, swrm->rcmd_id, dev_addr, cmd_data);
- ret = wait_for_completion_timeout(ctrl->comp,
- msecs_to_jiffies(TIMEOUT_MS));
+ return SDW_CMD_IGNORED;
+}
- if (!ret) {
- ret = SDW_CMD_IGNORED;
- goto err;
- } else {
- ret = SDW_CMD_OK;
- }
+static int qcom_swrm_get_alert_slave_dev_num(struct qcom_swrm_ctrl *ctrl)
+{
+ u32 val, status;
+ int dev_num;
- for (i = 0; i < len; i++) {
- ctrl->reg_read(ctrl, SWRM_CMD_FIFO_RD_FIFO_ADDR, &val);
- rval[i] = val & 0xFF;
- }
+ ctrl->reg_read(ctrl, SWRM_MCP_SLV_STATUS, &val);
-err:
- spin_lock_irqsave(&ctrl->comp_lock, flags);
- ctrl->comp = NULL;
- spin_unlock_irqrestore(&ctrl->comp_lock, flags);
+ for (dev_num = 0; dev_num < SDW_MAX_DEVICES; dev_num++) {
+ status = (val >> (dev_num * SWRM_MCP_SLV_STATUS_SZ));
- return ret;
+ if ((status & SWRM_MCP_SLV_STATUS_MASK) == SDW_SLAVE_ALERT) {
+ ctrl->status[dev_num] = status;
+ return dev_num;
+ }
+ }
+
+ return -EINVAL;
}
static void qcom_swrm_get_device_status(struct qcom_swrm_ctrl *ctrl)
@@ -260,6 +409,7 @@ static void qcom_swrm_get_device_status(struct qcom_swrm_ctrl *ctrl)
int i;
ctrl->reg_read(ctrl, SWRM_MCP_SLV_STATUS, &val);
+ ctrl->slave_status = val;
for (i = 0; i < SDW_MAX_DEVICES; i++) {
u32 s;
@@ -270,42 +420,188 @@ static void qcom_swrm_get_device_status(struct qcom_swrm_ctrl *ctrl)
}
}
-static irqreturn_t qcom_swrm_irq_handler(int irq, void *dev_id)
+static void qcom_swrm_set_slave_dev_num(struct sdw_bus *bus,
+ struct sdw_slave *slave, int devnum)
{
- struct qcom_swrm_ctrl *ctrl = dev_id;
- u32 sts, value;
- unsigned long flags;
+ struct qcom_swrm_ctrl *ctrl = to_qcom_sdw(bus);
+ u32 status;
+
+ ctrl->reg_read(ctrl, SWRM_MCP_SLV_STATUS, &status);
+ status = (status >> (devnum * SWRM_MCP_SLV_STATUS_SZ));
+ status &= SWRM_MCP_SLV_STATUS_MASK;
+
+ if (status == SDW_SLAVE_ATTACHED) {
+ if (slave)
+ slave->dev_num = devnum;
+ mutex_lock(&bus->bus_lock);
+ set_bit(devnum, bus->assigned);
+ mutex_unlock(&bus->bus_lock);
+ }
+}
- ctrl->reg_read(ctrl, SWRM_INTERRUPT_STATUS, &sts);
+static int qcom_swrm_enumerate(struct sdw_bus *bus)
+{
+ struct qcom_swrm_ctrl *ctrl = to_qcom_sdw(bus);
+ struct sdw_slave *slave, *_s;
+ struct sdw_slave_id id;
+ u32 val1, val2;
+ bool found;
+ u64 addr;
+ int i;
+ char *buf1 = (char *)&val1, *buf2 = (char *)&val2;
+
+ for (i = 1; i <= SDW_MAX_DEVICES; i++) {
+ /*SCP_Devid5 - Devid 4*/
+ ctrl->reg_read(ctrl, SWRM_ENUMERATOR_SLAVE_DEV_ID_1(i), &val1);
+
+ /*SCP_Devid3 - DevId 2 Devid 1 Devid 0*/
+ ctrl->reg_read(ctrl, SWRM_ENUMERATOR_SLAVE_DEV_ID_2(i), &val2);
+
+ if (!val1 && !val2)
+ break;
+
+ addr = buf2[1] | (buf2[0] << 8) | (buf1[3] << 16) |
+ ((u64)buf1[2] << 24) | ((u64)buf1[1] << 32) |
+ ((u64)buf1[0] << 40);
+
+ sdw_extract_slave_id(bus, addr, &id);
+ found = false;
+ /* Now compare with entries */
+ list_for_each_entry_safe(slave, _s, &bus->slaves, node) {
+ if (sdw_compare_devid(slave, id) == 0) {
+ qcom_swrm_set_slave_dev_num(bus, slave, i);
+ found = true;
+ break;
+ }
+ }
- if (sts & SWRM_INTERRUPT_STATUS_CMD_ERROR) {
- ctrl->reg_read(ctrl, SWRM_CMD_FIFO_STATUS, &value);
- dev_err_ratelimited(ctrl->dev,
- "CMD error, fifo status 0x%x\n",
- value);
- ctrl->reg_write(ctrl, SWRM_CMD_FIFO_CMD, 0x1);
+ if (!found) {
+ qcom_swrm_set_slave_dev_num(bus, NULL, i);
+ sdw_slave_add(bus, &id, NULL);
+ }
}
- if ((sts & SWRM_INTERRUPT_STATUS_NEW_SLAVE_ATTACHED) ||
- sts & SWRM_INTERRUPT_STATUS_CHANGE_ENUM_SLAVE_STATUS)
- schedule_work(&ctrl->slave_work);
-
- /**
- * clear the interrupt before complete() is called, as complete can
- * schedule new read/writes which require interrupts, clearing the
- * interrupt would avoid missing interrupts in such cases.
- */
- ctrl->reg_write(ctrl, SWRM_INTERRUPT_CLEAR, sts);
-
- if (sts & SWRM_INTERRUPT_STATUS_SPECIAL_CMD_ID_FINISHED) {
- spin_lock_irqsave(&ctrl->comp_lock, flags);
- if (ctrl->comp)
- complete(ctrl->comp);
- spin_unlock_irqrestore(&ctrl->comp_lock, flags);
- }
+ complete(&ctrl->enumeration);
+ return 0;
+}
+
+static irqreturn_t qcom_swrm_irq_handler(int irq, void *dev_id)
+{
+ struct qcom_swrm_ctrl *swrm = dev_id;
+ u32 value, intr_sts, intr_sts_masked, slave_status;
+ u32 i;
+ int devnum;
+ int ret = IRQ_HANDLED;
+
+ swrm->reg_read(swrm, SWRM_INTERRUPT_STATUS, &intr_sts);
+ intr_sts_masked = intr_sts & swrm->intr_mask;
+
+ do {
+ for (i = 0; i < SWRM_INTERRUPT_MAX; i++) {
+ value = intr_sts_masked & BIT(i);
+ if (!value)
+ continue;
+
+ switch (value) {
+ case SWRM_INTERRUPT_STATUS_SLAVE_PEND_IRQ:
+ devnum = qcom_swrm_get_alert_slave_dev_num(swrm);
+ if (devnum < 0) {
+ dev_err_ratelimited(swrm->dev,
+ "no slave alert found.spurious interrupt\n");
+ } else {
+ sdw_handle_slave_status(&swrm->bus, swrm->status);
+ }
- return IRQ_HANDLED;
+ break;
+ case SWRM_INTERRUPT_STATUS_NEW_SLAVE_ATTACHED:
+ case SWRM_INTERRUPT_STATUS_CHANGE_ENUM_SLAVE_STATUS:
+ dev_err_ratelimited(swrm->dev, "%s: SWR new slave attached\n",
+ __func__);
+ swrm->reg_read(swrm, SWRM_MCP_SLV_STATUS, &slave_status);
+ if (swrm->slave_status == slave_status) {
+ dev_err(swrm->dev, "Slave status not changed %x\n",
+ slave_status);
+ } else {
+ qcom_swrm_get_device_status(swrm);
+ qcom_swrm_enumerate(&swrm->bus);
+ sdw_handle_slave_status(&swrm->bus, swrm->status);
+ }
+ break;
+ case SWRM_INTERRUPT_STATUS_MASTER_CLASH_DET:
+ dev_err_ratelimited(swrm->dev,
+ "%s: SWR bus clsh detected\n",
+ __func__);
+ swrm->intr_mask &= ~SWRM_INTERRUPT_STATUS_MASTER_CLASH_DET;
+ swrm->reg_write(swrm, SWRM_INTERRUPT_CPU_EN, swrm->intr_mask);
+ break;
+ case SWRM_INTERRUPT_STATUS_RD_FIFO_OVERFLOW:
+ swrm->reg_read(swrm, SWRM_CMD_FIFO_STATUS, &value);
+ dev_err_ratelimited(swrm->dev,
+ "%s: SWR read FIFO overflow fifo status 0x%x\n",
+ __func__, value);
+ break;
+ case SWRM_INTERRUPT_STATUS_RD_FIFO_UNDERFLOW:
+ swrm->reg_read(swrm, SWRM_CMD_FIFO_STATUS, &value);
+ dev_err_ratelimited(swrm->dev,
+ "%s: SWR read FIFO underflow fifo status 0x%x\n",
+ __func__, value);
+ break;
+ case SWRM_INTERRUPT_STATUS_WR_CMD_FIFO_OVERFLOW:
+ swrm->reg_read(swrm, SWRM_CMD_FIFO_STATUS, &value);
+ dev_err(swrm->dev,
+ "%s: SWR write FIFO overflow fifo status %x\n",
+ __func__, value);
+ swrm->reg_write(swrm, SWRM_CMD_FIFO_CMD, 0x1);
+ break;
+ case SWRM_INTERRUPT_STATUS_CMD_ERROR:
+ swrm->reg_read(swrm, SWRM_CMD_FIFO_STATUS, &value);
+ dev_err_ratelimited(swrm->dev,
+ "%s: SWR CMD error, fifo status 0x%x, flushing fifo\n",
+ __func__, value);
+ swrm->reg_write(swrm, SWRM_CMD_FIFO_CMD, 0x1);
+ break;
+ case SWRM_INTERRUPT_STATUS_DOUT_PORT_COLLISION:
+ dev_err_ratelimited(swrm->dev,
+ "%s: SWR Port collision detected\n",
+ __func__);
+ swrm->intr_mask &= ~SWRM_INTERRUPT_STATUS_DOUT_PORT_COLLISION;
+ swrm->reg_write(swrm,
+ SWRM_INTERRUPT_CPU_EN, swrm->intr_mask);
+ break;
+ case SWRM_INTERRUPT_STATUS_READ_EN_RD_VALID_MISMATCH:
+ dev_err_ratelimited(swrm->dev,
+ "%s: SWR read enable valid mismatch\n",
+ __func__);
+ swrm->intr_mask &=
+ ~SWRM_INTERRUPT_STATUS_READ_EN_RD_VALID_MISMATCH;
+ swrm->reg_write(swrm,
+ SWRM_INTERRUPT_CPU_EN, swrm->intr_mask);
+ break;
+ case SWRM_INTERRUPT_STATUS_SPECIAL_CMD_ID_FINISHED:
+ complete(&swrm->broadcast);
+ break;
+ case SWRM_INTERRUPT_STATUS_BUS_RESET_FINISHED_V2:
+ break;
+ case SWRM_INTERRUPT_STATUS_CLK_STOP_FINISHED_V2:
+ break;
+ case SWRM_INTERRUPT_STATUS_EXT_CLK_STOP_WAKEUP:
+ break;
+ default:
+ dev_err_ratelimited(swrm->dev,
+ "%s: SWR unknown interrupt value: %d\n",
+ __func__, value);
+ ret = IRQ_NONE;
+ break;
+ }
+ }
+ swrm->reg_write(swrm, SWRM_INTERRUPT_CLEAR, intr_sts);
+ swrm->reg_read(swrm, SWRM_INTERRUPT_STATUS, &intr_sts);
+ intr_sts_masked = intr_sts & swrm->intr_mask;
+ } while (intr_sts_masked);
+
+ return ret;
}
+
static int qcom_swrm_init(struct qcom_swrm_ctrl *ctrl)
{
u32 val;
@@ -316,9 +612,10 @@ static int qcom_swrm_init(struct qcom_swrm_ctrl *ctrl)
ctrl->reg_write(ctrl, SWRM_MCP_FRAME_CTRL_BANK_ADDR(0), val);
- /* Disable Auto enumeration */
- ctrl->reg_write(ctrl, SWRM_ENUMERATOR_CFG_ADDR, 0);
+ /* Enable Auto enumeration */
+ ctrl->reg_write(ctrl, SWRM_ENUMERATOR_CFG_ADDR, 1);
+ ctrl->intr_mask = SWRM_INTERRUPT_STATUS_RMSK;
/* Mask soundwire interrupts */
ctrl->reg_write(ctrl, SWRM_INTERRUPT_MASK_ADDR,
SWRM_INTERRUPT_STATUS_RMSK);
@@ -328,8 +625,17 @@ static int qcom_swrm_init(struct qcom_swrm_ctrl *ctrl)
u32p_replace_bits(&val, SWRM_DEF_CMD_NO_PINGS, SWRM_MCP_CFG_MAX_NUM_OF_CMD_NO_PINGS_BMSK);
ctrl->reg_write(ctrl, SWRM_MCP_CFG_ADDR, val);
+ ctrl->reg_write(ctrl, SWRM_MCP_BUS_CTRL, SWRM_MCP_BUS_CLK_START);
/* Configure number of retries of a read/write cmd */
- ctrl->reg_write(ctrl, SWRM_CMD_FIFO_CFG_ADDR, SWRM_RD_WR_CMD_RETRIES);
+ if (ctrl->version > 0x01050001) {
+ /* Only for versions >= 1.5.1 */
+ ctrl->reg_write(ctrl, SWRM_CMD_FIFO_CFG_ADDR,
+ SWRM_RD_WR_CMD_RETRIES |
+ SWRM_CONTINUE_EXEC_ON_CMD_IGNORE);
+ } else {
+ ctrl->reg_write(ctrl, SWRM_CMD_FIFO_CFG_ADDR,
+ SWRM_RD_WR_CMD_RETRIES);
+ }
/* Set IRQ to PULSE */
ctrl->reg_write(ctrl, SWRM_COMP_CFG_ADDR,
@@ -341,6 +647,11 @@ static int qcom_swrm_init(struct qcom_swrm_ctrl *ctrl)
ctrl->reg_write(ctrl, SWRM_INTERRUPT_CPU_EN,
SWRM_INTERRUPT_STATUS_RMSK);
}
+ ctrl->slave_status = 0;
+ ctrl->reg_read(ctrl, SWRM_COMP_PARAMS, &val);
+ ctrl->rd_fifo_depth = FIELD_GET(SWRM_COMP_PARAMS_RD_FIFO_DEPTH, val);
+ ctrl->wr_fifo_depth = FIELD_GET(SWRM_COMP_PARAMS_WR_FIFO_DEPTH, val);
+
return 0;
}
@@ -396,8 +707,11 @@ static int qcom_swrm_port_params(struct sdw_bus *bus,
struct sdw_port_params *p_params,
unsigned int bank)
{
- /* TBD */
- return 0;
+ struct qcom_swrm_ctrl *ctrl = to_qcom_sdw(bus);
+
+ return ctrl->reg_write(ctrl, SWRM_DP_BLOCK_CTRL_1(p_params->num),
+ p_params->bps - 1);
+
}
static int qcom_swrm_transport_params(struct sdw_bus *bus,
@@ -405,22 +719,57 @@ static int qcom_swrm_transport_params(struct sdw_bus *bus,
enum sdw_reg_bank bank)
{
struct qcom_swrm_ctrl *ctrl = to_qcom_sdw(bus);
+ struct qcom_swrm_port_config *pcfg;
u32 value;
int reg = SWRM_DP_PORT_CTRL_BANK((params->port_num), bank);
int ret;
- value = params->offset1 << SWRM_DP_PORT_CTRL_OFFSET1_SHFT;
- value |= params->offset2 << SWRM_DP_PORT_CTRL_OFFSET2_SHFT;
- value |= params->sample_interval - 1;
+ pcfg = &ctrl->pconfig[params->port_num];
+
+ value = pcfg->off1 << SWRM_DP_PORT_CTRL_OFFSET1_SHFT;
+ value |= pcfg->off2 << SWRM_DP_PORT_CTRL_OFFSET2_SHFT;
+ value |= pcfg->si;
ret = ctrl->reg_write(ctrl, reg, value);
+ if (ret)
+ goto err;
- if (!ret && params->blk_pkg_mode) {
- reg = SWRM_DP_BLOCK_CTRL3_BANK(params->port_num, bank);
+ if (pcfg->lane_control != SWR_INVALID_PARAM) {
+ reg = SWRM_DP_PORT_CTRL_2_BANK(params->port_num, bank);
+ value = pcfg->lane_control;
+ ret = ctrl->reg_write(ctrl, reg, value);
+ if (ret)
+ goto err;
+ }
+
+ if (pcfg->blk_group_count != SWR_INVALID_PARAM) {
+ reg = SWRM_DP_BLOCK_CTRL2_BANK(params->port_num, bank);
+ value = pcfg->blk_group_count;
+ ret = ctrl->reg_write(ctrl, reg, value);
+ if (ret)
+ goto err;
+ }
+
+ if (pcfg->hstart != SWR_INVALID_PARAM
+ && pcfg->hstop != SWR_INVALID_PARAM) {
+ reg = SWRM_DP_PORT_HCTRL_BANK(params->port_num, bank);
+ value = (pcfg->hstop << 4) | pcfg->hstart;
+ ret = ctrl->reg_write(ctrl, reg, value);
+ } else {
+ reg = SWRM_DP_PORT_HCTRL_BANK(params->port_num, bank);
+ value = (SWR_HSTOP_MAX_VAL << 4) | SWR_HSTART_MIN_VAL;
+ ret = ctrl->reg_write(ctrl, reg, value);
+ }
+
+ if (ret)
+ goto err;
- ret = ctrl->reg_write(ctrl, reg, 1);
+ if (pcfg->bp_mode != SWR_INVALID_PARAM) {
+ reg = SWRM_DP_BLOCK_CTRL3_BANK(params->port_num, bank);
+ ret = ctrl->reg_write(ctrl, reg, pcfg->bp_mode);
}
+err:
return ret;
}
@@ -460,27 +809,50 @@ static int qcom_swrm_compute_params(struct sdw_bus *bus)
struct sdw_slave_runtime *s_rt;
struct sdw_port_runtime *p_rt;
struct qcom_swrm_port_config *pcfg;
- int i = 0;
+ struct sdw_slave *slave;
+ unsigned int m_port;
+ int i = 1;
list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
list_for_each_entry(p_rt, &m_rt->port_list, port_node) {
- pcfg = &ctrl->pconfig[p_rt->num - 1];
+ pcfg = &ctrl->pconfig[p_rt->num];
p_rt->transport_params.port_num = p_rt->num;
- p_rt->transport_params.sample_interval = pcfg->si + 1;
- p_rt->transport_params.offset1 = pcfg->off1;
- p_rt->transport_params.offset2 = pcfg->off2;
- p_rt->transport_params.blk_pkg_mode = pcfg->bp_mode;
+ if (pcfg->word_length != SWR_INVALID_PARAM) {
+ sdw_fill_port_params(&p_rt->port_params,
+ p_rt->num, pcfg->word_length + 1,
+ SDW_PORT_FLOW_MODE_ISOCH,
+ SDW_PORT_DATA_MODE_NORMAL);
+ }
+
}
list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) {
+ slave = s_rt->slave;
list_for_each_entry(p_rt, &s_rt->port_list, port_node) {
- pcfg = &ctrl->pconfig[i];
+ m_port = slave->m_port_map[p_rt->num];
+ /* port config starts at offset 0 so -1 from actual port number */
+ if (m_port)
+ pcfg = &ctrl->pconfig[m_port];
+ else
+ pcfg = &ctrl->pconfig[i];
p_rt->transport_params.port_num = p_rt->num;
p_rt->transport_params.sample_interval =
pcfg->si + 1;
p_rt->transport_params.offset1 = pcfg->off1;
p_rt->transport_params.offset2 = pcfg->off2;
p_rt->transport_params.blk_pkg_mode = pcfg->bp_mode;
+ p_rt->transport_params.blk_grp_ctrl = pcfg->blk_group_count;
+
+ p_rt->transport_params.hstart = pcfg->hstart;
+ p_rt->transport_params.hstop = pcfg->hstop;
+ p_rt->transport_params.lane_ctrl = pcfg->lane_control;
+ if (pcfg->word_length != SWR_INVALID_PARAM) {
+ sdw_fill_port_params(&p_rt->port_params,
+ p_rt->num,
+ pcfg->word_length + 1,
+ SDW_PORT_FLOW_MODE_ISOCH,
+ SDW_PORT_DATA_MODE_NORMAL);
+ }
i++;
}
}
@@ -493,16 +865,6 @@ static u32 qcom_swrm_freq_tbl[MAX_FREQ_NUM] = {
DEFAULT_CLK_FREQ,
};
-static void qcom_swrm_slave_wq(struct work_struct *work)
-{
- struct qcom_swrm_ctrl *ctrl =
- container_of(work, struct qcom_swrm_ctrl, slave_work);
-
- qcom_swrm_get_device_status(ctrl);
- sdw_handle_slave_status(&ctrl->bus, ctrl->status);
-}
-
-
static void qcom_swrm_stream_free_ports(struct qcom_swrm_ctrl *ctrl,
struct sdw_stream_runtime *stream)
{
@@ -519,7 +881,7 @@ static void qcom_swrm_stream_free_ports(struct qcom_swrm_ctrl *ctrl,
port_mask = &ctrl->din_port_mask;
list_for_each_entry(p_rt, &m_rt->port_list, port_node)
- clear_bit(p_rt->num - 1, port_mask);
+ clear_bit(p_rt->num, port_mask);
}
mutex_unlock(&ctrl->port_lock);
@@ -535,8 +897,10 @@ static int qcom_swrm_stream_alloc_ports(struct qcom_swrm_ctrl *ctrl,
struct sdw_master_runtime *m_rt;
struct sdw_slave_runtime *s_rt;
struct sdw_port_runtime *p_rt;
+ struct sdw_slave *slave;
unsigned long *port_mask;
int i, maxport, pn, nports = 0, ret = 0;
+ unsigned int m_port;
mutex_lock(&ctrl->port_lock);
list_for_each_entry(m_rt, &stream->master_list, stream_node) {
@@ -549,16 +913,22 @@ static int qcom_swrm_stream_alloc_ports(struct qcom_swrm_ctrl *ctrl,
}
list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) {
+ slave = s_rt->slave;
list_for_each_entry(p_rt, &s_rt->port_list, port_node) {
+ m_port = slave->m_port_map[p_rt->num];
/* Port numbers start from 1 - 14*/
- pn = find_first_zero_bit(port_mask, maxport);
- if (pn > (maxport - 1)) {
+ if (m_port)
+ pn = m_port;
+ else
+ pn = find_first_zero_bit(port_mask, maxport);
+
+ if (pn > maxport) {
dev_err(ctrl->dev, "All ports busy\n");
ret = -EBUSY;
goto err;
}
set_bit(pn, port_mask);
- pconfig[nports].num = pn + 1;
+ pconfig[nports].num = pn;
pconfig[nports].ch_mask = p_rt->ch_mask;
nports++;
}
@@ -580,7 +950,7 @@ static int qcom_swrm_stream_alloc_ports(struct qcom_swrm_ctrl *ctrl,
err:
if (ret) {
for (i = 0; i < nports; i++)
- clear_bit(pconfig[i].num - 1, port_mask);
+ clear_bit(pconfig[i].num, port_mask);
}
mutex_unlock(&ctrl->port_lock);
@@ -652,7 +1022,7 @@ static int qcom_swrm_startup(struct snd_pcm_substream *substream,
ret = snd_soc_dai_set_sdw_stream(codec_dai, sruntime,
substream->stream);
if (ret < 0 && ret != -ENOTSUPP) {
- dev_err(dai->dev, "Failed to set sdw stream on %s",
+ dev_err(dai->dev, "Failed to set sdw stream on %s\n",
codec_dai->name);
sdw_release_stream(sruntime);
return ret;
@@ -728,6 +1098,11 @@ static int qcom_swrm_get_port_config(struct qcom_swrm_ctrl *ctrl)
u8 off2[QCOM_SDW_MAX_PORTS];
u8 si[QCOM_SDW_MAX_PORTS];
u8 bp_mode[QCOM_SDW_MAX_PORTS] = { 0, };
+ u8 hstart[QCOM_SDW_MAX_PORTS];
+ u8 hstop[QCOM_SDW_MAX_PORTS];
+ u8 word_length[QCOM_SDW_MAX_PORTS];
+ u8 blk_group_count[QCOM_SDW_MAX_PORTS];
+ u8 lane_control[QCOM_SDW_MAX_PORTS];
int i, ret, nports, val;
ctrl->reg_read(ctrl, SWRM_COMP_PARAMS, &val);
@@ -754,6 +1129,9 @@ static int qcom_swrm_get_port_config(struct qcom_swrm_ctrl *ctrl)
ctrl->num_dout_ports = val;
nports = ctrl->num_dout_ports + ctrl->num_din_ports;
+ /* Valid port numbers are from 1-14, so mask out port 0 explicitly */
+ set_bit(0, &ctrl->dout_port_mask);
+ set_bit(0, &ctrl->din_port_mask);
ret = of_property_read_u8_array(np, "qcom,ports-offset1",
off1, nports);
@@ -772,11 +1150,35 @@ static int qcom_swrm_get_port_config(struct qcom_swrm_ctrl *ctrl)
ret = of_property_read_u8_array(np, "qcom,ports-block-pack-mode",
bp_mode, nports);
+ if (ret)
+ return ret;
+
+ memset(hstart, SWR_INVALID_PARAM, QCOM_SDW_MAX_PORTS);
+ of_property_read_u8_array(np, "qcom,ports-hstart", hstart, nports);
+
+ memset(hstop, SWR_INVALID_PARAM, QCOM_SDW_MAX_PORTS);
+ of_property_read_u8_array(np, "qcom,ports-hstop", hstop, nports);
+
+ memset(word_length, SWR_INVALID_PARAM, QCOM_SDW_MAX_PORTS);
+ of_property_read_u8_array(np, "qcom,ports-word-length", word_length, nports);
+
+ memset(blk_group_count, SWR_INVALID_PARAM, QCOM_SDW_MAX_PORTS);
+ of_property_read_u8_array(np, "qcom,ports-block-group-count", blk_group_count, nports);
+
+ memset(lane_control, SWR_INVALID_PARAM, QCOM_SDW_MAX_PORTS);
+ of_property_read_u8_array(np, "qcom,ports-lane-control", lane_control, nports);
+
for (i = 0; i < nports; i++) {
- ctrl->pconfig[i].si = si[i];
- ctrl->pconfig[i].off1 = off1[i];
- ctrl->pconfig[i].off2 = off2[i];
- ctrl->pconfig[i].bp_mode = bp_mode[i];
+ /* Valid port number range is from 1-14 */
+ ctrl->pconfig[i + 1].si = si[i];
+ ctrl->pconfig[i + 1].off1 = off1[i];
+ ctrl->pconfig[i + 1].off2 = off2[i];
+ ctrl->pconfig[i + 1].bp_mode = bp_mode[i];
+ ctrl->pconfig[i + 1].hstart = hstart[i];
+ ctrl->pconfig[i + 1].hstop = hstop[i];
+ ctrl->pconfig[i + 1].word_length = word_length[i];
+ ctrl->pconfig[i + 1].blk_group_count = blk_group_count[i];
+ ctrl->pconfig[i + 1].lane_control = lane_control[i];
}
return 0;
@@ -833,9 +1235,9 @@ static int qcom_swrm_probe(struct platform_device *pdev)
ctrl->dev = dev;
dev_set_drvdata(&pdev->dev, ctrl);
- spin_lock_init(&ctrl->comp_lock);
mutex_init(&ctrl->port_lock);
- INIT_WORK(&ctrl->slave_work, qcom_swrm_slave_wq);
+ init_completion(&ctrl->broadcast);
+ init_completion(&ctrl->enumeration);
ctrl->bus.ops = &qcom_swrm_ops;
ctrl->bus.port_ops = &qcom_swrm_port_ops;
@@ -882,6 +1284,8 @@ static int qcom_swrm_probe(struct platform_device *pdev)
}
qcom_swrm_init(ctrl);
+ wait_for_completion_timeout(&ctrl->enumeration,
+ msecs_to_jiffies(TIMEOUT_MS));
ret = qcom_swrm_register_dais(ctrl);
if (ret)
goto err_master_add;
diff --git a/drivers/soundwire/slave.c b/drivers/soundwire/slave.c
index 180f38bd003b..0eed38a79c6d 100644
--- a/drivers/soundwire/slave.c
+++ b/drivers/soundwire/slave.c
@@ -88,6 +88,7 @@ int sdw_slave_add(struct sdw_bus *bus,
return ret;
}
+EXPORT_SYMBOL(sdw_slave_add);
#if IS_ENABLED(CONFIG_ACPI)
@@ -95,7 +96,7 @@ static bool find_slave(struct sdw_bus *bus,
struct acpi_device *adev,
struct sdw_slave_id *id)
{
- unsigned long long addr;
+ u64 addr;
unsigned int link_id;
acpi_status status;
@@ -108,6 +109,12 @@ static bool find_slave(struct sdw_bus *bus,
return false;
}
+ if (bus->ops->override_adr)
+ addr = bus->ops->override_adr(bus, addr);
+
+ if (!addr)
+ return false;
+
/* Extract link id from ADR, Bit 51 to 48 (included) */
link_id = SDW_DISCO_LINK_ID(addr);
diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
index 1099b5d1262b..1eaedaaba094 100644
--- a/drivers/soundwire/stream.c
+++ b/drivers/soundwire/stream.c
@@ -261,7 +261,7 @@ static int sdw_program_master_port_params(struct sdw_bus *bus,
*/
static int sdw_program_port_params(struct sdw_master_runtime *m_rt)
{
- struct sdw_slave_runtime *s_rt = NULL;
+ struct sdw_slave_runtime *s_rt;
struct sdw_bus *bus = m_rt->bus;
struct sdw_port_runtime *p_rt;
int ret = 0;
@@ -1375,8 +1375,16 @@ int sdw_stream_add_slave(struct sdw_slave *slave,
}
ret = sdw_config_stream(&slave->dev, stream, stream_config, true);
- if (ret)
+ if (ret) {
+ /*
+ * sdw_release_master_stream will release s_rt in slave_rt_list in
+ * stream_error case, but s_rt is only added to slave_rt_list
+ * when sdw_config_stream is successful, so free s_rt explicitly
+ * when sdw_config_stream is failed.
+ */
+ kfree(s_rt);
goto stream_error;
+ }
list_add_tail(&s_rt->m_rt_node, &m_rt->slave_rt_list);
@@ -1449,7 +1457,7 @@ struct sdw_dpn_prop *sdw_get_slave_dpn_prop(struct sdw_slave *slave,
static void sdw_acquire_bus_lock(struct sdw_stream_runtime *stream)
{
struct sdw_master_runtime *m_rt;
- struct sdw_bus *bus = NULL;
+ struct sdw_bus *bus;
/* Iterate for all Master(s) in Master list */
list_for_each_entry(m_rt, &stream->master_list, stream_node) {
@@ -1470,8 +1478,8 @@ static void sdw_acquire_bus_lock(struct sdw_stream_runtime *stream)
*/
static void sdw_release_bus_lock(struct sdw_stream_runtime *stream)
{
- struct sdw_master_runtime *m_rt = NULL;
- struct sdw_bus *bus = NULL;
+ struct sdw_master_runtime *m_rt;
+ struct sdw_bus *bus;
/* Iterate for all Master(s) in Master list */
list_for_each_entry_reverse(m_rt, &stream->master_list, stream_node) {
@@ -1513,7 +1521,7 @@ static int _sdw_prepare_stream(struct sdw_stream_runtime *stream,
if (bus->compute_params) {
ret = bus->compute_params(bus);
if (ret < 0) {
- dev_err(bus->dev, "Compute params failed: %d",
+ dev_err(bus->dev, "Compute params failed: %d\n",
ret);
return ret;
}
@@ -1791,7 +1799,7 @@ static int _sdw_deprepare_stream(struct sdw_stream_runtime *stream)
if (bus->compute_params) {
ret = bus->compute_params(bus);
if (ret < 0) {
- dev_err(bus->dev, "Compute params failed: %d",
+ dev_err(bus->dev, "Compute params failed: %d\n",
ret);
return ret;
}
@@ -1855,7 +1863,7 @@ static int set_stream(struct snd_pcm_substream *substream,
for_each_rtd_dais(rtd, i, dai) {
ret = snd_soc_dai_set_sdw_stream(dai, sdw_stream, substream->stream);
if (ret < 0) {
- dev_err(rtd->dev, "failed to set stream pointer on dai %s", dai->name);
+ dev_err(rtd->dev, "failed to set stream pointer on dai %s\n", dai->name);
break;
}
}
@@ -1888,7 +1896,7 @@ int sdw_startup_stream(void *sdw_substream)
sdw_stream = sdw_alloc_stream(name);
if (!sdw_stream) {
- dev_err(rtd->dev, "alloc stream failed for substream DAI %s", substream->name);
+ dev_err(rtd->dev, "alloc stream failed for substream DAI %s\n", substream->name);
ret = -ENOMEM;
goto error;
}
@@ -1927,7 +1935,7 @@ void sdw_shutdown_stream(void *sdw_substream)
sdw_stream = snd_soc_dai_get_sdw_stream(dai, substream->stream);
if (IS_ERR(sdw_stream)) {
- dev_err(rtd->dev, "no stream found for DAI %s", dai->name);
+ dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name);
return;
}
diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
index 202ee81cfc2b..5531f3afeb21 100644
--- a/drivers/uio/Kconfig
+++ b/drivers/uio/Kconfig
@@ -165,4 +165,21 @@ config UIO_HV_GENERIC
to network and storage devices from userspace.
If you compile this as a module, it will be called uio_hv_generic.
+
+config UIO_DFL
+ tristate "Generic driver for DFL (Device Feature List) bus"
+ depends on FPGA_DFL
+ help
+ Generic DFL (Device Feature List) driver for Userspace I/O devices.
+ It is useful to provide direct access to DFL devices from userspace.
+ A sample userspace application using this driver is available for
+ download in a git repository:
+
+ git clone https://github.com/OPAE/opae-sdk.git
+
+ It could be found at:
+
+ opae-sdk/tools/libopaeuio/
+
+ If you compile this as a module, it will be called uio_dfl.
endif
diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile
index c285dd2a4539..f2f416a14228 100644
--- a/drivers/uio/Makefile
+++ b/drivers/uio/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_UIO_PRUSS) += uio_pruss.o
obj-$(CONFIG_UIO_MF624) += uio_mf624.o
obj-$(CONFIG_UIO_FSL_ELBC_GPCM) += uio_fsl_elbc_gpcm.o
obj-$(CONFIG_UIO_HV_GENERIC) += uio_hv_generic.o
+obj-$(CONFIG_UIO_DFL) += uio_dfl.o
diff --git a/drivers/uio/uio_dfl.c b/drivers/uio/uio_dfl.c
new file mode 100644
index 000000000000..89c0fc7b0cbc
--- /dev/null
+++ b/drivers/uio/uio_dfl.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Generic DFL driver for Userspace I/O devicess
+ *
+ * Copyright (C) 2021 Intel Corporation, Inc.
+ */
+#include <linux/dfl.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/uio_driver.h>
+
+#define DRIVER_NAME "uio_dfl"
+
+static int uio_dfl_probe(struct dfl_device *ddev)
+{
+ struct resource *r = &ddev->mmio_res;
+ struct device *dev = &ddev->dev;
+ struct uio_info *uioinfo;
+ struct uio_mem *uiomem;
+ int ret;
+
+ uioinfo = devm_kzalloc(dev, sizeof(struct uio_info), GFP_KERNEL);
+ if (!uioinfo)
+ return -ENOMEM;
+
+ uioinfo->name = DRIVER_NAME;
+ uioinfo->version = "0";
+
+ uiomem = &uioinfo->mem[0];
+ uiomem->memtype = UIO_MEM_PHYS;
+ uiomem->addr = r->start & PAGE_MASK;
+ uiomem->offs = r->start & ~PAGE_MASK;
+ uiomem->size = (uiomem->offs + resource_size(r)
+ + PAGE_SIZE - 1) & PAGE_MASK;
+ uiomem->name = r->name;
+
+ /* Irq is yet to be supported */
+ uioinfo->irq = UIO_IRQ_NONE;
+
+ ret = devm_uio_register_device(dev, uioinfo);
+ if (ret)
+ dev_err(dev, "unable to register uio device\n");
+
+ return ret;
+}
+
+#define FME_FEATURE_ID_ETH_GROUP 0x10
+
+static const struct dfl_device_id uio_dfl_ids[] = {
+ { FME_ID, FME_FEATURE_ID_ETH_GROUP },
+ { }
+};
+MODULE_DEVICE_TABLE(dfl, uio_dfl_ids);
+
+static struct dfl_driver uio_dfl_driver = {
+ .drv = {
+ .name = DRIVER_NAME,
+ },
+ .id_table = uio_dfl_ids,
+ .probe = uio_dfl_probe,
+};
+module_dfl_driver(uio_dfl_driver);
+
+MODULE_DESCRIPTION("Generic DFL driver for Userspace I/O devices");
+MODULE_AUTHOR("Intel Corporation");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/virt/acrn/vm.c b/drivers/virt/acrn/vm.c
index 7804a2492ad7..0d002a355a93 100644
--- a/drivers/virt/acrn/vm.c
+++ b/drivers/virt/acrn/vm.c
@@ -94,7 +94,7 @@ int acrn_vm_destroy(struct acrn_vm *vm)
}
/**
- * acrn_inject_msi() - Inject a MSI interrupt into a User VM
+ * acrn_msi_inject() - Inject a MSI interrupt into a User VM
* @vm: User VM
* @msi_addr: The MSI address
* @msi_data: The MSI data
diff --git a/drivers/w1/slaves/w1_ds2780.c b/drivers/w1/slaves/w1_ds2780.c
index c281fe5ed688..9dcb5a54f7fc 100644
--- a/drivers/w1/slaves/w1_ds2780.c
+++ b/drivers/w1/slaves/w1_ds2780.c
@@ -90,7 +90,7 @@ static ssize_t w1_slave_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
- struct device *dev = container_of(kobj, struct device, kobj);
+ struct device *dev = kobj_to_dev(kobj);
return w1_ds2780_io(dev, buf, off, count, 0);
}
diff --git a/drivers/w1/slaves/w1_ds2781.c b/drivers/w1/slaves/w1_ds2781.c
index f0d393ae070b..2cb7c020b607 100644
--- a/drivers/w1/slaves/w1_ds2781.c
+++ b/drivers/w1/slaves/w1_ds2781.c
@@ -87,7 +87,7 @@ static ssize_t w1_slave_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
- struct device *dev = container_of(kobj, struct device, kobj);
+ struct device *dev = kobj_to_dev(kobj);
return w1_ds2781_io(dev, buf, off, count, 0);
}
diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c
index 976eea28f268..9d08a1c9c445 100644
--- a/drivers/w1/slaves/w1_therm.c
+++ b/drivers/w1/slaves/w1_therm.c
@@ -63,8 +63,8 @@ static u16 bulk_read_device_counter; /* =0 as per C standard */
#define EEPROM_CMD_READ "restore" /* cmd for read eeprom sysfs */
#define BULK_TRIGGER_CMD "trigger" /* cmd to trigger a bulk read */
-#define MIN_TEMP -55 /* min temperature that can be mesured */
-#define MAX_TEMP 125 /* max temperature that can be mesured */
+#define MIN_TEMP -55 /* min temperature that can be measured */
+#define MAX_TEMP 125 /* max temperature that can be measured */
/* Allowed values for sysfs conv_time attribute */
#define CONV_TIME_DEFAULT 0
@@ -906,8 +906,7 @@ static inline int temperature_from_RAM(struct w1_slave *sl, u8 rom[9])
static inline s8 int_to_short(int i)
{
/* Prepare to cast to short by eliminating out of range values */
- i = i > MAX_TEMP ? MAX_TEMP : i;
- i = i < MIN_TEMP ? MIN_TEMP : i;
+ i = clamp(i, MIN_TEMP, MAX_TEMP);
return (s8) i;
}
diff --git a/include/dt-bindings/mux/ti-serdes.h b/include/dt-bindings/mux/ti-serdes.h
index 9047ec6bd3cf..d417b9268b16 100644
--- a/include/dt-bindings/mux/ti-serdes.h
+++ b/include/dt-bindings/mux/ti-serdes.h
@@ -90,4 +90,9 @@
#define J7200_SERDES0_LANE3_USB 0x2
#define J7200_SERDES0_LANE3_IP4_UNUSED 0x3
+/* AM64 */
+
+#define AM64_SERDES0_LANE0_PCIE0 0x0
+#define AM64_SERDES0_LANE0_USB 0x1
+
#endif /* _DT_BINDINGS_MUX_TI_SERDES */
diff --git a/include/dt-bindings/phy/phy-cadence-torrent.h b/include/dt-bindings/phy/phy-cadence-torrent.h
deleted file mode 100644
index e387b6a95741..000000000000
--- a/include/dt-bindings/phy/phy-cadence-torrent.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * This header provides constants for Cadence Torrent SERDES.
- */
-
-#ifndef _DT_BINDINGS_TORRENT_SERDES_H
-#define _DT_BINDINGS_TORRENT_SERDES_H
-
-#define TORRENT_SERDES_NO_SSC 0
-#define TORRENT_SERDES_EXTERNAL_SSC 1
-#define TORRENT_SERDES_INTERNAL_SSC 2
-
-#endif /* _DT_BINDINGS_TORRENT_SERDES_H */
diff --git a/include/dt-bindings/phy/phy-cadence.h b/include/dt-bindings/phy/phy-cadence.h
new file mode 100644
index 000000000000..4652bcb86265
--- /dev/null
+++ b/include/dt-bindings/phy/phy-cadence.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * This header provides constants for Cadence SERDES.
+ */
+
+#ifndef _DT_BINDINGS_CADENCE_SERDES_H
+#define _DT_BINDINGS_CADENCE_SERDES_H
+
+/* Torrent */
+#define TORRENT_SERDES_NO_SSC 0
+#define TORRENT_SERDES_EXTERNAL_SSC 1
+#define TORRENT_SERDES_INTERNAL_SSC 2
+
+#define CDNS_TORRENT_REFCLK_DRIVER 0
+
+/* Sierra */
+#define CDNS_SIERRA_PLL_CMNLC 0
+#define CDNS_SIERRA_PLL_CMNLC1 1
+
+#endif /* _DT_BINDINGS_CADENCE_SERDES_H */
diff --git a/include/dt-bindings/phy/phy-ti.h b/include/dt-bindings/phy/phy-ti.h
new file mode 100644
index 000000000000..ad955d3a56b4
--- /dev/null
+++ b/include/dt-bindings/phy/phy-ti.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * This header provides constants for TI SERDES.
+ */
+
+#ifndef _DT_BINDINGS_TI_SERDES
+#define _DT_BINDINGS_TI_SERDES
+
+/* Clock index for output clocks from WIZ */
+
+/* MUX Clocks */
+#define TI_WIZ_PLL0_REFCLK 0
+#define TI_WIZ_PLL1_REFCLK 1
+#define TI_WIZ_REFCLK_DIG 2
+
+/* Reserve index here for future additions */
+
+/* MISC Clocks */
+#define TI_WIZ_PHY_EN_REFCLK 16
+
+#endif /* _DT_BINDINGS_TI_SERDES */
diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
index 052293f4cbdb..923dada24eb4 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -65,6 +65,10 @@ int nvmem_cell_read_u8(struct device *dev, const char *cell_id, u8 *val);
int nvmem_cell_read_u16(struct device *dev, const char *cell_id, u16 *val);
int nvmem_cell_read_u32(struct device *dev, const char *cell_id, u32 *val);
int nvmem_cell_read_u64(struct device *dev, const char *cell_id, u64 *val);
+int nvmem_cell_read_variable_le_u32(struct device *dev, const char *cell_id,
+ u32 *val);
+int nvmem_cell_read_variable_le_u64(struct device *dev, const char *cell_id,
+ u64 *val);
/* direct nvmem device read/write interface */
struct nvmem_device *nvmem_device_get(struct device *dev, const char *name);
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index e435bdb0bab3..0ed434d02196 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -44,6 +44,12 @@ enum phy_mode {
PHY_MODE_DP
};
+enum phy_media {
+ PHY_MEDIA_DEFAULT,
+ PHY_MEDIA_SR,
+ PHY_MEDIA_DAC,
+};
+
/**
* union phy_configure_opts - Opaque generic phy configuration
*
@@ -64,6 +70,8 @@ union phy_configure_opts {
* @power_on: powering on the phy
* @power_off: powering off the phy
* @set_mode: set the mode of the phy
+ * @set_media: set the media type of the phy (optional)
+ * @set_speed: set the speed of the phy (optional)
* @reset: resetting the phy
* @calibrate: calibrate the phy
* @release: ops to be performed while the consumer relinquishes the PHY
@@ -75,6 +83,8 @@ struct phy_ops {
int (*power_on)(struct phy *phy);
int (*power_off)(struct phy *phy);
int (*set_mode)(struct phy *phy, enum phy_mode mode, int submode);
+ int (*set_media)(struct phy *phy, enum phy_media media);
+ int (*set_speed)(struct phy *phy, int speed);
/**
* @configure:
@@ -215,6 +225,8 @@ int phy_power_off(struct phy *phy);
int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode);
#define phy_set_mode(phy, mode) \
phy_set_mode_ext(phy, mode, 0)
+int phy_set_media(struct phy *phy, enum phy_media media);
+int phy_set_speed(struct phy *phy, int speed);
int phy_configure(struct phy *phy, union phy_configure_opts *opts);
int phy_validate(struct phy *phy, enum phy_mode mode, int submode,
union phy_configure_opts *opts);
@@ -344,6 +356,20 @@ static inline int phy_set_mode_ext(struct phy *phy, enum phy_mode mode,
#define phy_set_mode(phy, mode) \
phy_set_mode_ext(phy, mode, 0)
+static inline int phy_set_media(struct phy *phy, enum phy_media media)
+{
+ if (!phy)
+ return 0;
+ return -ENODEV;
+}
+
+static inline int phy_set_speed(struct phy *phy, int speed)
+{
+ if (!phy)
+ return 0;
+ return -ENODEV;
+}
+
static inline enum phy_mode phy_get_mode(struct phy *phy)
{
return PHY_MODE_INVALID;
diff --git a/include/linux/pps-gpio.h b/include/linux/pps-gpio.h
deleted file mode 100644
index 7bf49908be06..000000000000
--- a/include/linux/pps-gpio.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * pps-gpio.h -- PPS client for GPIOs
- *
- * Copyright (C) 2011 James Nuss <jamesnuss@nanometrics.ca>
- */
-
-#ifndef _PPS_GPIO_H
-#define _PPS_GPIO_H
-
-struct pps_gpio_platform_data {
- struct gpio_desc *gpio_pin;
- struct gpio_desc *echo_pin;
- bool assert_falling_edge;
- bool capture_clear;
- unsigned int echo_active_ms;
-};
-
-#endif /* _PPS_GPIO_H */
diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
index d08039d65825..ced07f8fde87 100644
--- a/include/linux/soundwire/sdw.h
+++ b/include/linux/soundwire/sdw.h
@@ -125,6 +125,12 @@ enum sdw_dpn_grouping {
SDW_BLK_GRP_CNT_4 = 3,
};
+/* block packing mode enum */
+enum sdw_dpn_pkg_mode {
+ SDW_BLK_PKG_PER_PORT = 0,
+ SDW_BLK_PKG_PER_CHANNEL = 1
+};
+
/**
* enum sdw_stream_type: data stream type
*
@@ -405,6 +411,7 @@ struct sdw_slave_prop {
* command
* @mclk_freq: clock reference passed to SoundWire Master, in Hz.
* @hw_disabled: if true, the Master is not functional, typically due to pin-mux
+ * @quirks: bitmask identifying optional behavior beyond the scope of the MIPI specification
*/
struct sdw_master_prop {
u32 revision;
@@ -421,8 +428,29 @@ struct sdw_master_prop {
u32 err_threshold;
u32 mclk_freq;
bool hw_disabled;
+ u64 quirks;
};
+/* Definitions for Master quirks */
+
+/*
+ * In a number of platforms bus clashes are reported after a hardware
+ * reset but without any explanations or evidence of a real problem.
+ * The following quirk will discard all initial bus clash interrupts
+ * but will leave the detection on should real bus clashes happen
+ */
+#define SDW_MASTER_QUIRKS_CLEAR_INITIAL_CLASH BIT(0)
+
+/*
+ * Some Slave devices have known issues with incorrect parity errors
+ * reported after a hardware reset. However during integration unexplained
+ * parity errors can be reported by Slave devices, possibly due to electrical
+ * issues at the Master level.
+ * The following quirk will discard all initial parity errors but will leave
+ * the detection on should real parity errors happen.
+ */
+#define SDW_MASTER_QUIRKS_CLEAR_INITIAL_PARITY BIT(1)
+
int sdw_master_read_prop(struct sdw_bus *bus);
int sdw_slave_read_prop(struct sdw_slave *slave);
@@ -614,6 +642,7 @@ struct sdw_slave_ops {
* @debugfs: Slave debugfs
* @node: node for bus list
* @port_ready: Port ready completion flag for each Slave port
+ * @m_port_map: static Master port map for each Slave port
* @dev_num: Current Device Number, values can be 0 or dev_num_sticky
* @dev_num_sticky: one-time static Device Number assigned by Bus
* @probed: boolean tracking driver state
@@ -645,6 +674,7 @@ struct sdw_slave {
#endif
struct list_head node;
struct completion port_ready[SDW_MAX_PORTS];
+ unsigned int m_port_map[SDW_MAX_PORTS];
enum sdw_clk_stop_mode curr_clk_stop_mode;
u16 dev_num;
u16 dev_num_sticky;
@@ -804,6 +834,7 @@ struct sdw_defer {
/**
* struct sdw_master_ops - Master driver ops
* @read_prop: Read Master properties
+ * @override_adr: Override value read from firmware (quirk for buggy firmware)
* @xfer_msg: Transfer message callback
* @xfer_msg_defer: Defer version of transfer message callback
* @reset_page_addr: Reset the SCP page address registers
@@ -813,7 +844,8 @@ struct sdw_defer {
*/
struct sdw_master_ops {
int (*read_prop)(struct sdw_bus *bus);
-
+ u64 (*override_adr)
+ (struct sdw_bus *bus, u64 addr);
enum sdw_command_response (*xfer_msg)
(struct sdw_bus *bus, struct sdw_msg *msg);
enum sdw_command_response (*xfer_msg_defer)
@@ -1009,5 +1041,7 @@ int sdw_write_no_pm(struct sdw_slave *slave, u32 addr, u8 value);
int sdw_read_no_pm(struct sdw_slave *slave, u32 addr);
int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val);
int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, u8 *val);
+int sdw_compare_devid(struct sdw_slave *slave, struct sdw_slave_id id);
+void sdw_extract_slave_id(struct sdw_bus *bus, u64 addr, struct sdw_slave_id *id);
#endif /* __SOUNDWIRE_H */
diff --git a/include/uapi/linux/android/binder.h b/include/uapi/linux/android/binder.h
index ec84ad106568..156070d18c4f 100644
--- a/include/uapi/linux/android/binder.h
+++ b/include/uapi/linux/android/binder.h
@@ -217,6 +217,18 @@ struct binder_node_info_for_ref {
__u32 reserved3;
};
+struct binder_freeze_info {
+ __u32 pid;
+ __u32 enable;
+ __u32 timeout_ms;
+};
+
+struct binder_frozen_status_info {
+ __u32 pid;
+ __u32 sync_recv;
+ __u32 async_recv;
+};
+
#define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read)
#define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, __s64)
#define BINDER_SET_MAX_THREADS _IOW('b', 5, __u32)
@@ -227,6 +239,8 @@ struct binder_node_info_for_ref {
#define BINDER_GET_NODE_DEBUG_INFO _IOWR('b', 11, struct binder_node_debug_info)
#define BINDER_GET_NODE_INFO_FOR_REF _IOWR('b', 12, struct binder_node_info_for_ref)
#define BINDER_SET_CONTEXT_MGR_EXT _IOW('b', 13, struct flat_binder_object)
+#define BINDER_FREEZE _IOW('b', 14, struct binder_freeze_info)
+#define BINDER_GET_FROZEN_INFO _IOWR('b', 15, struct binder_frozen_status_info)
/*
* NOTE: Two special error codes you should check for when calling
@@ -408,6 +422,12 @@ enum binder_driver_return_protocol {
* The last transaction (either a bcTRANSACTION or
* a bcATTEMPT_ACQUIRE) failed (e.g. out of memory). No parameters.
*/
+
+ BR_FROZEN_REPLY = _IO('r', 18),
+ /*
+ * The target of the last transaction (either a bcTRANSACTION or
+ * a bcATTEMPT_ACQUIRE) is frozen. No parameters.
+ */
};
enum binder_driver_command_protocol {
diff --git a/include/uapi/linux/map_to_7segment.h b/include/uapi/linux/map_to_7segment.h
index 8b02088f96e3..04c8b55812e7 100644
--- a/include/uapi/linux/map_to_7segment.h
+++ b/include/uapi/linux/map_to_7segment.h
@@ -1,20 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
/*
* Copyright (c) 2005 Henk Vergonet <Henk.Vergonet@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MAP_TO_7SEGMENT_H
diff --git a/scripts/spdxcheck.py b/scripts/spdxcheck.py
index cbdb5c83c08f..3e784cf9f401 100755
--- a/scripts/spdxcheck.py
+++ b/scripts/spdxcheck.py
@@ -243,7 +243,7 @@ if __name__ == '__main__':
# Initialize SPDX data
spdx = read_spdxdata(repo)
- # Initilize the parser
+ # Initialize the parser
parser = id_parser(spdx)
except SPDXException as se: