mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
phy-for-7.1
- New Support - Qualcomm Eliza QMP UFS PHY - Canaan K230 USB 2.0 PHY driver - Mediatek mt8167 dsi-phy - Eswin EIC7700 SATA PHY driver - Updates - Sorted subsytem Makefile/Kconfig and some kernel-doc udpates -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE+vs47OPLdNbVcHzyfBQHDyUjg0cFAmnh4msACgkQfBQHDyUj g0ctew/+K/rVLCUu/UgbvnV1hPH3q/OCytwcymurSp5+lZ2TGsHcwjzGNKrGxCAp nxgzffHwukyuRGq/FHDc1QQa+i5bDzf6dlE3CuZYnZWka8mxbqcBetMQvLb93LXL 9MEQ8YQgjh96AyX87sP0r5IhBVLl3LiGHj2+L6VXoTzMsJeqT6Kx2rABHgFjXM97 gjurp1PbHwi2EGQowa9zjsoQnRnN2C4O2xlZsXeNljzS2KPpToQ+sjADwHSau8nw b9idowJlJMlN+RFrNKJWgja7ro/E17IGQptJT9Hz89j2dXg0QiWIY/uok25o6XAn h0yYWpXP6gaQH1mnpS5Meb8d+ljTL4SNLv/64pYSGPzqXUbuJXVx2Rn7ZBuB3R/H +pmVbrdWSUwhXcgXDyVCMLguhCxns4M/SmaYrjVayrogDiz9gqHlGMTfsSmYCnbI UDqHyFSa6HRZIFnba0pBkb3eyrKE9qMK0FFgQURQp8GCOJu8waeNyCZ4fTCjXo6v MULhauFWDC267LNogt6KGgTC6sFmsitsI8jymMQGfb3g6FdhJUFpQLmNvwYpoHXH AofeTHrzdXWRVNiVKO01J2tPskVCczx5R5q5dfDGTM0mIRXMaHCuzT2RNdRmBpNk rgBlCvIiiE9VbusN+zybPQfTJAQa2eVMTvBRzjwkdLUYeMUJS0I= =qz0Z -----END PGP SIGNATURE----- Merge tag 'phy-for-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy Pull phy updates from Vinod Koul: "New Support: - Qualcomm Eliza QMP UFS PHY - Canaan K230 USB 2.0 PHY driver - Mediatek mt8167 dsi-phy - Eswin EIC7700 SATA PHY driver Updates: - Sorted subsytem Makefile/Kconfig and some kernel-doc udpates" * tag 'phy-for-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy: dt-bindings: phy: qcom,sc8280xp-qmp-ufs-phy: document the Eliza QMP UFS PHY phy: qcom: m31-eusb2: clear PLL_EN during init phy: eswin: Create eswin directory and add EIC7700 SATA PHY driver dt-bindings: phy: eswin: Document the EIC7700 SoC SATA PHY phy: apple: apple: Use local variable for ioremap return value phy: qcom: qmp-usbc: Simplify check for non-NULL pointer phy: marvell: mmp3-hsic: Avoid re-casting __iomem phy: apple: atc: Make atcphy_dwc3_reset_ops variable static dt-bindings: phy: mediatek,dsi-phy: Add support for mt8167 phy: usb: Add driver for Canaan K230 USB 2.0 PHY dt-bindings: phy: Add Canaan K230 USB PHY phy: phy-mtk-tphy: Update names and format of kernel-doc comments phy: Sort the subsystem Kconfig phy: Sort the subsystem Makefile phy: move spacemit pcie driver to its subfolder
This commit is contained in:
commit
3f887edd35
|
|
@ -0,0 +1,35 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/canaan,k230-usb-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Canaan K230 USB2.0 PHY
|
||||
|
||||
maintainers:
|
||||
- Jiayu Du <jiayu.riscv@isrc.iscas.ac.cn>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: canaan,k230-usb-phy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#phy-cells":
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
usbphy: usb-phy@91585000 {
|
||||
compatible = "canaan,k230-usb-phy";
|
||||
reg = <0x91585000 0x400>;
|
||||
#phy-cells = <1>;
|
||||
};
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/eswin,eic7700-sata-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Eswin EIC7700 SoC SATA PHY
|
||||
|
||||
maintainers:
|
||||
- Yulin Lu <luyulin@eswincomputing.com>
|
||||
- Huan He <hehuan1@eswincomputing.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: eswin,eic7700-sata-phy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: phy
|
||||
|
||||
resets:
|
||||
maxItems: 2
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: port
|
||||
- const: phy
|
||||
|
||||
eswin,tx-amplitude-tuning:
|
||||
description: This adjusts the transmitter amplitude signal, and its value
|
||||
is derived from eye diagram tuning. The three values correspond to Gen1,
|
||||
Gen2, and Gen3 parameters respectively.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
items:
|
||||
- description: Gen1 parameter.
|
||||
minimum: 0
|
||||
maximum: 0x7f
|
||||
- description: Gen2 parameter.
|
||||
minimum: 0
|
||||
maximum: 0x7f
|
||||
- description: Gen3 parameter.
|
||||
minimum: 0
|
||||
maximum: 0x7f
|
||||
default: [0, 0, 0]
|
||||
|
||||
eswin,tx-preemph-tuning:
|
||||
description: This adjusts the transmitter de-emphasis signal, and its value
|
||||
is derived from eye diagram tuning. The three values correspond to Gen1,
|
||||
Gen2, and Gen3 parameters respectively.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
items:
|
||||
- description: Gen1 parameter.
|
||||
minimum: 0
|
||||
maximum: 0x3f
|
||||
- description: Gen2 parameter.
|
||||
minimum: 0
|
||||
maximum: 0x3f
|
||||
- description: Gen3 parameter.
|
||||
minimum: 0
|
||||
maximum: 0x3f
|
||||
default: [0, 0, 0]
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
sata-phy@50440300 {
|
||||
compatible = "eswin,eic7700-sata-phy";
|
||||
reg = <0x50440300 0x40>;
|
||||
clocks = <&hspcrg 17>;
|
||||
clock-names = "phy";
|
||||
resets = <&hspcrg 0>, <&hspcrg 1>;
|
||||
reset-names = "port", "phy";
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
|
@ -16,6 +16,10 @@ description:
|
|||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,qcs8300-qmp-ufs-phy
|
||||
- const: qcom,sa8775p-qmp-ufs-phy
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,qcs615-qmp-ufs-phy
|
||||
|
|
@ -26,8 +30,8 @@ properties:
|
|||
- const: qcom,sm8550-qmp-ufs-phy
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,qcs8300-qmp-ufs-phy
|
||||
- const: qcom,sa8775p-qmp-ufs-phy
|
||||
- qcom,eliza-qmp-ufs-phy
|
||||
- const: qcom,sm8650-qmp-ufs-phy
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,kaanapali-qmp-ufs-phy
|
||||
|
|
|
|||
|
|
@ -46,6 +46,26 @@ config GENERIC_PHY_MIPI_DPHY
|
|||
Provides a number of helpers a core functions for MIPI D-PHY
|
||||
drivers to us.
|
||||
|
||||
config PHY_AIROHA_PCIE
|
||||
tristate "Airoha PCIe-PHY Driver"
|
||||
depends on ARCH_AIROHA || COMPILE_TEST
|
||||
depends on OF
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Say Y here to add support for Airoha PCIe PHY driver.
|
||||
This driver create the basic PHY instance and provides initialize
|
||||
callback for PCIe GEN3 port.
|
||||
|
||||
config PHY_CAN_TRANSCEIVER
|
||||
tristate "CAN transceiver PHY"
|
||||
select GENERIC_PHY
|
||||
select MULTIPLEXER
|
||||
help
|
||||
This option enables support for CAN transceivers as a PHY. This
|
||||
driver provides function for putting the transceivers in various
|
||||
functional modes using gpios and sets the attribute max link
|
||||
rate, for CAN drivers.
|
||||
|
||||
config PHY_GOOGLE_USB
|
||||
tristate "Google Tensor SoC USB PHY driver"
|
||||
select GENERIC_PHY
|
||||
|
|
@ -57,6 +77,18 @@ config PHY_GOOGLE_USB
|
|||
both of which are integrated with the DWC3 USB DRD controller.
|
||||
This driver currently supports USB high-speed.
|
||||
|
||||
config USB_LGM_PHY
|
||||
tristate "INTEL Lightning Mountain USB PHY Driver"
|
||||
depends on USB_SUPPORT
|
||||
depends on X86 || COMPILE_TEST
|
||||
select USB_PHY
|
||||
select REGULATOR
|
||||
select REGULATOR_FIXED_VOLTAGE
|
||||
help
|
||||
Enable this to support Intel DWC3 PHY USB phy. This driver provides
|
||||
interface to interact with USB GEN-II and USB 3.x PHY that is part
|
||||
of the Intel network SOC.
|
||||
|
||||
config PHY_LPC18XX_USB_OTG
|
||||
tristate "NXP LPC18xx/43xx SoC USB OTG PHY driver"
|
||||
depends on OF && (ARCH_LPC18XX || COMPILE_TEST)
|
||||
|
|
@ -68,6 +100,17 @@ config PHY_LPC18XX_USB_OTG
|
|||
This driver is need for USB0 support on LPC18xx/43xx and takes
|
||||
care of enabling and clock setup.
|
||||
|
||||
config PHY_NXP_PTN3222
|
||||
tristate "NXP PTN3222 1-port eUSB2 to USB2 redriver"
|
||||
depends on I2C
|
||||
depends on OF
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support NXP PTN3222 1-port eUSB2 to USB2 Redriver.
|
||||
This redriver performs translation between eUSB2 and USB2 signalling
|
||||
schemes. It supports all three USB 2.0 data rates: Low Speed, Full
|
||||
Speed and High Speed.
|
||||
|
||||
config PHY_PISTACHIO_USB
|
||||
tristate "IMG Pistachio USB2.0 PHY driver"
|
||||
depends on MIPS || COMPILE_TEST
|
||||
|
|
@ -90,69 +133,17 @@ config PHY_XGENE
|
|||
help
|
||||
This option enables support for APM X-Gene SoC multi-purpose PHY.
|
||||
|
||||
config USB_LGM_PHY
|
||||
tristate "INTEL Lightning Mountain USB PHY Driver"
|
||||
depends on USB_SUPPORT
|
||||
depends on X86 || COMPILE_TEST
|
||||
select USB_PHY
|
||||
select REGULATOR
|
||||
select REGULATOR_FIXED_VOLTAGE
|
||||
help
|
||||
Enable this to support Intel DWC3 PHY USB phy. This driver provides
|
||||
interface to interact with USB GEN-II and USB 3.x PHY that is part
|
||||
of the Intel network SOC.
|
||||
|
||||
config PHY_CAN_TRANSCEIVER
|
||||
tristate "CAN transceiver PHY"
|
||||
select GENERIC_PHY
|
||||
select MULTIPLEXER
|
||||
help
|
||||
This option enables support for CAN transceivers as a PHY. This
|
||||
driver provides function for putting the transceivers in various
|
||||
functional modes using gpios and sets the attribute max link
|
||||
rate, for CAN drivers.
|
||||
|
||||
config PHY_AIROHA_PCIE
|
||||
tristate "Airoha PCIe-PHY Driver"
|
||||
depends on ARCH_AIROHA || COMPILE_TEST
|
||||
depends on OF
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Say Y here to add support for Airoha PCIe PHY driver.
|
||||
This driver create the basic PHY instance and provides initialize
|
||||
callback for PCIe GEN3 port.
|
||||
|
||||
config PHY_NXP_PTN3222
|
||||
tristate "NXP PTN3222 1-port eUSB2 to USB2 redriver"
|
||||
depends on I2C
|
||||
depends on OF
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support NXP PTN3222 1-port eUSB2 to USB2 Redriver.
|
||||
This redriver performs translation between eUSB2 and USB2 signalling
|
||||
schemes. It supports all three USB 2.0 data rates: Low Speed, Full
|
||||
Speed and High Speed.
|
||||
|
||||
config PHY_SPACEMIT_K1_PCIE
|
||||
tristate "PCIe and combo PHY driver for the SpacemiT K1 SoC"
|
||||
depends on ARCH_SPACEMIT || COMPILE_TEST
|
||||
depends on COMMON_CLK
|
||||
depends on HAS_IOMEM
|
||||
depends on OF
|
||||
select GENERIC_PHY
|
||||
default ARCH_SPACEMIT
|
||||
help
|
||||
Enable support for the PCIe and USB 3 combo PHY and two
|
||||
PCIe-only PHYs used in the SpacemiT K1 SoC.
|
||||
|
||||
source "drivers/phy/allwinner/Kconfig"
|
||||
source "drivers/phy/amlogic/Kconfig"
|
||||
source "drivers/phy/apple/Kconfig"
|
||||
source "drivers/phy/broadcom/Kconfig"
|
||||
source "drivers/phy/cadence/Kconfig"
|
||||
source "drivers/phy/canaan/Kconfig"
|
||||
source "drivers/phy/eswin/Kconfig"
|
||||
source "drivers/phy/freescale/Kconfig"
|
||||
source "drivers/phy/hisilicon/Kconfig"
|
||||
source "drivers/phy/ingenic/Kconfig"
|
||||
source "drivers/phy/intel/Kconfig"
|
||||
source "drivers/phy/lantiq/Kconfig"
|
||||
source "drivers/phy/marvell/Kconfig"
|
||||
source "drivers/phy/mediatek/Kconfig"
|
||||
|
|
@ -174,7 +165,6 @@ source "drivers/phy/starfive/Kconfig"
|
|||
source "drivers/phy/sunplus/Kconfig"
|
||||
source "drivers/phy/tegra/Kconfig"
|
||||
source "drivers/phy/ti/Kconfig"
|
||||
source "drivers/phy/intel/Kconfig"
|
||||
source "drivers/phy/xilinx/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
|
|
|||
|
|
@ -7,21 +7,23 @@ obj-$(CONFIG_PHY_COMMON_PROPS) += phy-common-props.o
|
|||
obj-$(CONFIG_PHY_COMMON_PROPS_TEST) += phy-common-props-test.o
|
||||
obj-$(CONFIG_GENERIC_PHY) += phy-core.o
|
||||
obj-$(CONFIG_GENERIC_PHY_MIPI_DPHY) += phy-core-mipi-dphy.o
|
||||
obj-$(CONFIG_PHY_AIROHA_PCIE) += phy-airoha-pcie.o
|
||||
obj-$(CONFIG_PHY_CAN_TRANSCEIVER) += phy-can-transceiver.o
|
||||
obj-$(CONFIG_PHY_GOOGLE_USB) += phy-google-usb.o
|
||||
obj-$(CONFIG_USB_LGM_PHY) += phy-lgm-usb.o
|
||||
obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o
|
||||
obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
|
||||
obj-$(CONFIG_PHY_NXP_PTN3222) += phy-nxp-ptn3222.o
|
||||
obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o
|
||||
obj-$(CONFIG_PHY_SNPS_EUSB2) += phy-snps-eusb2.o
|
||||
obj-$(CONFIG_USB_LGM_PHY) += phy-lgm-usb.o
|
||||
obj-$(CONFIG_PHY_AIROHA_PCIE) += phy-airoha-pcie.o
|
||||
obj-$(CONFIG_PHY_NXP_PTN3222) += phy-nxp-ptn3222.o
|
||||
obj-$(CONFIG_PHY_SPACEMIT_K1_PCIE) += phy-spacemit-k1-pcie.o
|
||||
obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
|
||||
|
||||
obj-$(CONFIG_GENERIC_PHY) += allwinner/ \
|
||||
amlogic/ \
|
||||
apple/ \
|
||||
broadcom/ \
|
||||
cadence/ \
|
||||
canaan/ \
|
||||
eswin/ \
|
||||
freescale/ \
|
||||
hisilicon/ \
|
||||
ingenic/ \
|
||||
|
|
|
|||
|
|
@ -2023,7 +2023,7 @@ static int atcphy_dwc3_reset_deassert(struct reset_controller_dev *rcdev, unsign
|
|||
return 0;
|
||||
}
|
||||
|
||||
const struct reset_control_ops atcphy_dwc3_reset_ops = {
|
||||
static const struct reset_control_ops atcphy_dwc3_reset_ops = {
|
||||
.assert = atcphy_dwc3_reset_assert,
|
||||
.deassert = atcphy_dwc3_reset_deassert,
|
||||
};
|
||||
|
|
@ -2202,14 +2202,16 @@ static int atcphy_map_resources(struct platform_device *pdev, struct apple_atcph
|
|||
{ "pipehandler", &atcphy->regs.pipehandler, NULL },
|
||||
};
|
||||
struct resource *res;
|
||||
void __iomem *addr;
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(resources); i++) {
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resources[i].name);
|
||||
*resources[i].addr = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(resources[i].addr))
|
||||
return dev_err_probe(atcphy->dev, PTR_ERR(resources[i].addr),
|
||||
addr = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(addr))
|
||||
return dev_err_probe(atcphy->dev, PTR_ERR(addr),
|
||||
"Unable to map %s regs", resources[i].name);
|
||||
|
||||
*resources[i].addr = addr;
|
||||
if (resources[i].res)
|
||||
*resources[i].res = res;
|
||||
}
|
||||
|
|
|
|||
14
drivers/phy/canaan/Kconfig
Normal file
14
drivers/phy/canaan/Kconfig
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Phy drivers for Canaan platforms
|
||||
#
|
||||
config PHY_CANAAN_USB
|
||||
tristate "Canaan USB2 PHY Driver"
|
||||
depends on (ARCH_CANAAN || COMPILE_TEST) && OF
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this driver to support the USB 2.0 PHY controller
|
||||
on Canaan K230 RISC-V SoCs. This PHY controller
|
||||
provides physical layer functionality for USB 2.0 devices.
|
||||
If you have a Canaan K230 board and need USB 2.0 support,
|
||||
say Y or M here.
|
||||
2
drivers/phy/canaan/Makefile
Normal file
2
drivers/phy/canaan/Makefile
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-$(CONFIG_PHY_CANAAN_USB) += phy-k230-usb.o
|
||||
284
drivers/phy/canaan/phy-k230-usb.c
Normal file
284
drivers/phy/canaan/phy-k230-usb.c
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Canaan usb PHY driver
|
||||
*
|
||||
* Copyright (C) 2026 Jiayu Du <jiayu.riscv@isrc.iscas.ac.cn>
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#define MAX_PHYS 2
|
||||
|
||||
/* Register offsets within the HiSysConfig system controller */
|
||||
#define K230_USB0_TEST_REG_BASE 0x70
|
||||
#define K230_USB0_CTL_REG_BASE 0xb0
|
||||
#define K230_USB1_TEST_REG_BASE 0x90
|
||||
#define K230_USB1_CTL_REG_BASE 0xb8
|
||||
|
||||
/* Relative offsets within each PHY's control/test block */
|
||||
#define CTL0_OFFSET 0x00
|
||||
#define CTL1_OFFSET 0x04
|
||||
#define TEST_CTL3_OFFSET 0x0c
|
||||
|
||||
/* Bit definitions for TEST_CTL3 */
|
||||
#define USB_IDPULLUP0 BIT(4)
|
||||
#define USB_DMPULLDOWN0 BIT(8)
|
||||
#define USB_DPPULLDOWN0 BIT(9)
|
||||
|
||||
/* USB control register 0 in HiSysConfig system controller */
|
||||
/* PLL Integral Path Tune */
|
||||
#define USB_CTL0_PLLITUNE_MASK GENMASK(23, 22)
|
||||
|
||||
/* PLL Proportional Path Tune */
|
||||
#define USB_CTL0_PLLPTUNE_MASK GENMASK(21, 18)
|
||||
|
||||
/* PLL Bandwidth Adjustment */
|
||||
#define USB_CTL0_PLLBTUNE_MASK GENMASK(17, 17)
|
||||
|
||||
/* VReg18 Bypass Control */
|
||||
#define USB_CTL0_VREGBYPASS_MASK GENMASK(16, 16)
|
||||
|
||||
/* Retention Mode Enable */
|
||||
#define USB_CTL0_RETENABLEN_MASK GENMASK(15, 15)
|
||||
|
||||
/* Reserved Request Input */
|
||||
#define USB_CTL0_RESREQIN_MASK GENMASK(14, 14)
|
||||
|
||||
/* External VBUS Valid Select */
|
||||
#define USB_CTL0_VBUSVLDEXTSEL0_MASK GENMASK(13, 13)
|
||||
|
||||
/* OTG Block Disable Control */
|
||||
#define USB_CTL0_OTGDISABLE0_MASK GENMASK(12, 12)
|
||||
|
||||
/* Drive VBUS Enable */
|
||||
#define USB_CTL0_DRVVBUS0_MASK GENMASK(11, 11)
|
||||
|
||||
/* Autoresume Mode Enable */
|
||||
#define USB_CTL0_AUTORSMENB0_MASK GENMASK(10, 10)
|
||||
|
||||
/* HS Transceiver Asynchronous Control */
|
||||
#define USB_CTL0_HSXCVREXTCTL0_MASK GENMASK(9, 9)
|
||||
|
||||
/* USB 1.1 Transmit Data */
|
||||
#define USB_CTL0_FSDATAEXT0_MASK GENMASK(8, 8)
|
||||
|
||||
/* USB 1.1 SE0 Generation */
|
||||
#define USB_CTL0_FSSE0EXT0_MASK GENMASK(7, 7)
|
||||
|
||||
/* USB 1.1 Data Enable */
|
||||
#define USB_CTL0_TXENABLEN0_MASK GENMASK(6, 6)
|
||||
|
||||
/* Disconnect Threshold */
|
||||
#define USB_CTL0_COMPDISTUNE0_MASK GENMASK(5, 3)
|
||||
|
||||
/* Squelch Threshold */
|
||||
#define USB_CTL0_SQRXTUNE0_MASK GENMASK(2, 0)
|
||||
|
||||
/* USB control register 1 in HiSysConfig system controller */
|
||||
/* Data Detect Voltage */
|
||||
#define USB_CTL1_VDATREFTUNE0_MASK GENMASK(23, 22)
|
||||
|
||||
/* VBUS Valid Threshold */
|
||||
#define USB_CTL1_OTGTUNE0_MASK GENMASK(21, 19)
|
||||
|
||||
/* Transmitter High-Speed Crossover */
|
||||
#define USB_CTL1_TXHSXVTUNE0_MASK GENMASK(18, 17)
|
||||
|
||||
/* FS/LS Source Impedance */
|
||||
#define USB_CTL1_TXFSLSTUNE0_MASK GENMASK(16, 13)
|
||||
|
||||
/* HS DC Voltage Level */
|
||||
#define USB_CTL1_TXVREFTUNE0_MASK GENMASK(12, 9)
|
||||
|
||||
/* HS Transmitter Rise/Fall Time */
|
||||
#define USB_CTL1_TXRISETUNE0_MASK GENMASK(8, 7)
|
||||
|
||||
/* USB Source Impedance */
|
||||
#define USB_CTL1_TXRESTUNE0_MASK GENMASK(6, 5)
|
||||
|
||||
/* HS Transmitter Pre-Emphasis Current Control */
|
||||
#define USB_CTL1_TXPREEMPAMPTUNE0_MASK GENMASK(4, 3)
|
||||
|
||||
/* HS Transmitter Pre-Emphasis Duration Control */
|
||||
#define USB_CTL1_TXPREEMPPULSETUNE0_MASK GENMASK(2, 2)
|
||||
|
||||
/* charging detection */
|
||||
#define USB_CTL1_CHRGSRCPUENB0_MASK GENMASK(1, 0)
|
||||
|
||||
#define K230_PHY_CTL0_VAL \
|
||||
( \
|
||||
FIELD_PREP(USB_CTL0_PLLITUNE_MASK, 0x0) | \
|
||||
FIELD_PREP(USB_CTL0_PLLPTUNE_MASK, 0xc) | \
|
||||
FIELD_PREP(USB_CTL0_PLLBTUNE_MASK, 0x1) | \
|
||||
FIELD_PREP(USB_CTL0_VREGBYPASS_MASK, 0x1) | \
|
||||
FIELD_PREP(USB_CTL0_RETENABLEN_MASK, 0x1) | \
|
||||
FIELD_PREP(USB_CTL0_RESREQIN_MASK, 0x0) | \
|
||||
FIELD_PREP(USB_CTL0_VBUSVLDEXTSEL0_MASK, 0x0) | \
|
||||
FIELD_PREP(USB_CTL0_OTGDISABLE0_MASK, 0x0) | \
|
||||
FIELD_PREP(USB_CTL0_DRVVBUS0_MASK, 0x1) | \
|
||||
FIELD_PREP(USB_CTL0_AUTORSMENB0_MASK, 0x0) | \
|
||||
FIELD_PREP(USB_CTL0_HSXCVREXTCTL0_MASK, 0x0) | \
|
||||
FIELD_PREP(USB_CTL0_FSDATAEXT0_MASK, 0x0) | \
|
||||
FIELD_PREP(USB_CTL0_FSSE0EXT0_MASK, 0x0) | \
|
||||
FIELD_PREP(USB_CTL0_TXENABLEN0_MASK, 0x0) | \
|
||||
FIELD_PREP(USB_CTL0_COMPDISTUNE0_MASK, 0x3) | \
|
||||
FIELD_PREP(USB_CTL0_SQRXTUNE0_MASK, 0x3) \
|
||||
)
|
||||
|
||||
#define K230_PHY_CTL1_VAL \
|
||||
( \
|
||||
FIELD_PREP(USB_CTL1_VDATREFTUNE0_MASK, 0x1) | \
|
||||
FIELD_PREP(USB_CTL1_OTGTUNE0_MASK, 0x3) | \
|
||||
FIELD_PREP(USB_CTL1_TXHSXVTUNE0_MASK, 0x3) | \
|
||||
FIELD_PREP(USB_CTL1_TXFSLSTUNE0_MASK, 0x3) | \
|
||||
FIELD_PREP(USB_CTL1_TXVREFTUNE0_MASK, 0x3) | \
|
||||
FIELD_PREP(USB_CTL1_TXRISETUNE0_MASK, 0x1) | \
|
||||
FIELD_PREP(USB_CTL1_TXRESTUNE0_MASK, 0x1) | \
|
||||
FIELD_PREP(USB_CTL1_TXPREEMPAMPTUNE0_MASK, 0x0) | \
|
||||
FIELD_PREP(USB_CTL1_TXPREEMPPULSETUNE0_MASK, 0x0) | \
|
||||
FIELD_PREP(USB_CTL1_CHRGSRCPUENB0_MASK, 0x0) \
|
||||
)
|
||||
|
||||
struct k230_usb_phy_instance {
|
||||
struct k230_usb_phy_global *global;
|
||||
struct phy *phy;
|
||||
u32 test_offset;
|
||||
u32 ctl_offset;
|
||||
int index;
|
||||
};
|
||||
|
||||
struct k230_usb_phy_global {
|
||||
struct k230_usb_phy_instance phys[MAX_PHYS];
|
||||
void __iomem *base;
|
||||
};
|
||||
|
||||
static int k230_usb_phy_power_on(struct phy *phy)
|
||||
{
|
||||
struct k230_usb_phy_instance *inst = phy_get_drvdata(phy);
|
||||
struct k230_usb_phy_global *global = inst->global;
|
||||
void __iomem *base = global->base;
|
||||
u32 val;
|
||||
|
||||
/* Apply recommended settings */
|
||||
writel(K230_PHY_CTL0_VAL, base + inst->ctl_offset + CTL0_OFFSET);
|
||||
writel(K230_PHY_CTL1_VAL, base + inst->ctl_offset + CTL1_OFFSET);
|
||||
|
||||
/* Configure test register (pull-ups/pull-downs) */
|
||||
val = readl(base + inst->test_offset + TEST_CTL3_OFFSET);
|
||||
val |= USB_IDPULLUP0;
|
||||
|
||||
if (inst->index == 1)
|
||||
val |= (USB_DMPULLDOWN0 | USB_DPPULLDOWN0);
|
||||
else
|
||||
val &= ~(USB_DMPULLDOWN0 | USB_DPPULLDOWN0);
|
||||
|
||||
writel(val, base + inst->test_offset + TEST_CTL3_OFFSET);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int k230_usb_phy_power_off(struct phy *phy)
|
||||
{
|
||||
struct k230_usb_phy_instance *inst = phy_get_drvdata(phy);
|
||||
struct k230_usb_phy_global *global = inst->global;
|
||||
void __iomem *base = global->base;
|
||||
u32 val;
|
||||
|
||||
val = readl(base + inst->test_offset + TEST_CTL3_OFFSET);
|
||||
val &= ~(USB_DMPULLDOWN0 | USB_DPPULLDOWN0);
|
||||
writel(val, base + inst->test_offset + TEST_CTL3_OFFSET);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct phy_ops k230_usb_phy_ops = {
|
||||
.power_on = k230_usb_phy_power_on,
|
||||
.power_off = k230_usb_phy_power_off,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static struct phy *k230_usb_phy_xlate(struct device *dev,
|
||||
const struct of_phandle_args *args)
|
||||
{
|
||||
struct k230_usb_phy_global *global = dev_get_drvdata(dev);
|
||||
unsigned int idx = args->args[0];
|
||||
|
||||
if (idx >= MAX_PHYS)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
return global->phys[idx].phy;
|
||||
}
|
||||
|
||||
static int k230_usb_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct k230_usb_phy_global *global;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct phy_provider *provider;
|
||||
int i;
|
||||
|
||||
global = devm_kzalloc(dev, sizeof(*global), GFP_KERNEL);
|
||||
if (!global)
|
||||
return -ENOMEM;
|
||||
dev_set_drvdata(dev, global);
|
||||
|
||||
global->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(global->base))
|
||||
return dev_err_probe(dev, PTR_ERR(global->base),
|
||||
"failed to map registers\n");
|
||||
|
||||
static const struct {
|
||||
u32 test_offset;
|
||||
u32 ctl_offset;
|
||||
} phy_reg_info[MAX_PHYS] = {
|
||||
[0] = { K230_USB0_TEST_REG_BASE, K230_USB0_CTL_REG_BASE },
|
||||
[1] = { K230_USB1_TEST_REG_BASE, K230_USB1_CTL_REG_BASE },
|
||||
};
|
||||
|
||||
for (i = 0; i < MAX_PHYS; i++) {
|
||||
struct k230_usb_phy_instance *inst = &global->phys[i];
|
||||
struct phy *phy;
|
||||
|
||||
inst->global = global;
|
||||
inst->index = i;
|
||||
inst->test_offset = phy_reg_info[i].test_offset;
|
||||
inst->ctl_offset = phy_reg_info[i].ctl_offset;
|
||||
|
||||
phy = devm_phy_create(dev, NULL, &k230_usb_phy_ops);
|
||||
if (IS_ERR(phy)) {
|
||||
dev_err(dev, "failed to create phy%d\n", i);
|
||||
return PTR_ERR(phy);
|
||||
}
|
||||
|
||||
phy_set_drvdata(phy, inst);
|
||||
inst->phy = phy;
|
||||
}
|
||||
|
||||
provider = devm_of_phy_provider_register(dev, k230_usb_phy_xlate);
|
||||
if (IS_ERR(provider))
|
||||
return PTR_ERR(provider);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id k230_usb_phy_of_match[] = {
|
||||
{ .compatible = "canaan,k230-usb-phy" },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, k230_usb_phy_of_match);
|
||||
|
||||
static struct platform_driver k230_usb_phy_driver = {
|
||||
.probe = k230_usb_phy_probe,
|
||||
.driver = {
|
||||
.name = "k230-usb-phy",
|
||||
.of_match_table = k230_usb_phy_of_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(k230_usb_phy_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Canaan Kendryte K230 USB 2.0 PHY driver");
|
||||
MODULE_AUTHOR("Jiayu Du <jiayu.riscv@isrc.iscas.ac.cn>");
|
||||
MODULE_LICENSE("GPL");
|
||||
14
drivers/phy/eswin/Kconfig
Normal file
14
drivers/phy/eswin/Kconfig
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Phy drivers for ESWIN platforms
|
||||
#
|
||||
config PHY_EIC7700_SATA
|
||||
tristate "eic7700 Sata SerDes/PHY driver"
|
||||
depends on ARCH_ESWIN || COMPILE_TEST
|
||||
depends on HAS_IOMEM
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support SerDes/Phy found on ESWIN's
|
||||
EIC7700 SoC. This Phy supports SATA 1.5 Gb/s,
|
||||
SATA 3.0 Gb/s, SATA 6.0 Gb/s speeds.
|
||||
It supports one SATA host port to accept one SATA device.
|
||||
2
drivers/phy/eswin/Makefile
Normal file
2
drivers/phy/eswin/Makefile
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-$(CONFIG_PHY_EIC7700_SATA) += phy-eic7700-sata.o
|
||||
273
drivers/phy/eswin/phy-eic7700-sata.c
Normal file
273
drivers/phy/eswin/phy-eic7700-sata.c
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* ESWIN SATA PHY driver
|
||||
*
|
||||
* Copyright 2026, Beijing ESWIN Computing Technology Co., Ltd..
|
||||
* All rights reserved.
|
||||
*
|
||||
* Authors: Yulin Lu <luyulin@eswincomputing.com>
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/reset.h>
|
||||
|
||||
#define SATA_AXI_LP_CTRL 0x08
|
||||
#define SATA_MPLL_CTRL 0x20
|
||||
#define SATA_P0_PHY_STAT 0x24
|
||||
#define SATA_PHY_CTRL0 0x28
|
||||
#define SATA_PHY_CTRL1 0x2c
|
||||
#define SATA_REF_CTRL 0x34
|
||||
#define SATA_REF_CTRL1 0x38
|
||||
#define SATA_LOS_IDEN 0x3c
|
||||
|
||||
#define SATA_CLK_RST_SOURCE_PHY BIT(0)
|
||||
#define SATA_P0_PHY_TX_AMPLITUDE_GEN1_MASK GENMASK(6, 0)
|
||||
#define SATA_P0_PHY_TX_AMPLITUDE_GEN1_DEFAULT 0x42
|
||||
#define SATA_P0_PHY_TX_AMPLITUDE_GEN2_MASK GENMASK(14, 8)
|
||||
#define SATA_P0_PHY_TX_AMPLITUDE_GEN2_DEFAULT 0x46
|
||||
#define SATA_P0_PHY_TX_AMPLITUDE_GEN3_MASK GENMASK(22, 16)
|
||||
#define SATA_P0_PHY_TX_AMPLITUDE_GEN3_DEFAULT 0x73
|
||||
#define SATA_P0_PHY_TX_PREEMPH_GEN1_MASK GENMASK(5, 0)
|
||||
#define SATA_P0_PHY_TX_PREEMPH_GEN1_DEFAULT 0x5
|
||||
#define SATA_P0_PHY_TX_PREEMPH_GEN2_MASK GENMASK(13, 8)
|
||||
#define SATA_P0_PHY_TX_PREEMPH_GEN2_DEFAULT 0x5
|
||||
#define SATA_P0_PHY_TX_PREEMPH_GEN3_MASK GENMASK(21, 16)
|
||||
#define SATA_P0_PHY_TX_PREEMPH_GEN3_DEFAULT 0x23
|
||||
#define SATA_LOS_LEVEL_MASK GENMASK(4, 0)
|
||||
#define SATA_LOS_BIAS_MASK GENMASK(18, 16)
|
||||
#define SATA_M_CSYSREQ BIT(0)
|
||||
#define SATA_S_CSYSREQ BIT(16)
|
||||
#define SATA_REF_REPEATCLK_EN BIT(0)
|
||||
#define SATA_REF_USE_PAD BIT(20)
|
||||
#define SATA_MPLL_MULTIPLIER_MASK GENMASK(22, 16)
|
||||
#define SATA_P0_PHY_READY BIT(0)
|
||||
|
||||
#define PLL_LOCK_SLEEP_US 10
|
||||
#define PLL_LOCK_TIMEOUT_US 1000
|
||||
|
||||
struct eic7700_sata_phy {
|
||||
u32 tx_amplitude_tuning_val[3];
|
||||
u32 tx_preemph_tuning_val[3];
|
||||
struct reset_control *rst;
|
||||
struct regmap *regmap;
|
||||
struct clk *clk;
|
||||
struct phy *phy;
|
||||
};
|
||||
|
||||
static const struct regmap_config eic7700_sata_phy_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.max_register = SATA_LOS_IDEN,
|
||||
};
|
||||
|
||||
static int wait_for_phy_ready(struct regmap *regmap, u32 reg, u32 checkbit,
|
||||
u32 status)
|
||||
{
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read_poll_timeout(regmap, reg, val,
|
||||
(val & checkbit) == status,
|
||||
PLL_LOCK_SLEEP_US, PLL_LOCK_TIMEOUT_US);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int eic7700_sata_phy_init(struct phy *phy)
|
||||
{
|
||||
struct eic7700_sata_phy *sata_phy = phy_get_drvdata(phy);
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(sata_phy->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
regmap_write(sata_phy->regmap, SATA_REF_CTRL1, SATA_CLK_RST_SOURCE_PHY);
|
||||
|
||||
val = FIELD_PREP(SATA_P0_PHY_TX_AMPLITUDE_GEN1_MASK,
|
||||
sata_phy->tx_amplitude_tuning_val[0]) |
|
||||
FIELD_PREP(SATA_P0_PHY_TX_AMPLITUDE_GEN2_MASK,
|
||||
sata_phy->tx_amplitude_tuning_val[1]) |
|
||||
FIELD_PREP(SATA_P0_PHY_TX_AMPLITUDE_GEN3_MASK,
|
||||
sata_phy->tx_amplitude_tuning_val[2]);
|
||||
regmap_write(sata_phy->regmap, SATA_PHY_CTRL0, val);
|
||||
|
||||
val = FIELD_PREP(SATA_P0_PHY_TX_PREEMPH_GEN1_MASK,
|
||||
sata_phy->tx_preemph_tuning_val[0]) |
|
||||
FIELD_PREP(SATA_P0_PHY_TX_PREEMPH_GEN2_MASK,
|
||||
sata_phy->tx_preemph_tuning_val[1]) |
|
||||
FIELD_PREP(SATA_P0_PHY_TX_PREEMPH_GEN3_MASK,
|
||||
sata_phy->tx_preemph_tuning_val[2]);
|
||||
regmap_write(sata_phy->regmap, SATA_PHY_CTRL1, val);
|
||||
|
||||
val = FIELD_PREP(SATA_LOS_LEVEL_MASK, 0x9) |
|
||||
FIELD_PREP(SATA_LOS_BIAS_MASK, 0x2);
|
||||
regmap_write(sata_phy->regmap, SATA_LOS_IDEN, val);
|
||||
|
||||
val = SATA_M_CSYSREQ | SATA_S_CSYSREQ;
|
||||
regmap_write(sata_phy->regmap, SATA_AXI_LP_CTRL, val);
|
||||
|
||||
val = SATA_REF_REPEATCLK_EN | SATA_REF_USE_PAD;
|
||||
regmap_write(sata_phy->regmap, SATA_REF_CTRL, val);
|
||||
|
||||
val = FIELD_PREP(SATA_MPLL_MULTIPLIER_MASK, 0x3c);
|
||||
regmap_write(sata_phy->regmap, SATA_MPLL_CTRL, val);
|
||||
|
||||
usleep_range(15, 20);
|
||||
|
||||
ret = reset_control_deassert(sata_phy->rst);
|
||||
if (ret)
|
||||
goto disable_clk;
|
||||
|
||||
ret = wait_for_phy_ready(sata_phy->regmap, SATA_P0_PHY_STAT,
|
||||
SATA_P0_PHY_READY, 1);
|
||||
if (ret < 0) {
|
||||
dev_err(&sata_phy->phy->dev, "PHY READY check failed\n");
|
||||
goto disable_clk;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
disable_clk:
|
||||
clk_disable_unprepare(sata_phy->clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int eic7700_sata_phy_exit(struct phy *phy)
|
||||
{
|
||||
struct eic7700_sata_phy *sata_phy = phy_get_drvdata(phy);
|
||||
int ret;
|
||||
|
||||
ret = reset_control_assert(sata_phy->rst);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
clk_disable_unprepare(sata_phy->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct phy_ops eic7700_sata_phy_ops = {
|
||||
.init = eic7700_sata_phy_init,
|
||||
.exit = eic7700_sata_phy_exit,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static void eic7700_get_tuning_param(struct device_node *np,
|
||||
struct eic7700_sata_phy *sata_phy)
|
||||
{
|
||||
if (of_property_read_u32_array
|
||||
(np, "eswin,tx-amplitude-tuning",
|
||||
sata_phy->tx_amplitude_tuning_val,
|
||||
ARRAY_SIZE(sata_phy->tx_amplitude_tuning_val))) {
|
||||
sata_phy->tx_amplitude_tuning_val[0] =
|
||||
SATA_P0_PHY_TX_AMPLITUDE_GEN1_DEFAULT;
|
||||
sata_phy->tx_amplitude_tuning_val[1] =
|
||||
SATA_P0_PHY_TX_AMPLITUDE_GEN2_DEFAULT;
|
||||
sata_phy->tx_amplitude_tuning_val[2] =
|
||||
SATA_P0_PHY_TX_AMPLITUDE_GEN3_DEFAULT;
|
||||
}
|
||||
|
||||
if (of_property_read_u32_array
|
||||
(np, "eswin,tx-preemph-tuning",
|
||||
sata_phy->tx_preemph_tuning_val,
|
||||
ARRAY_SIZE(sata_phy->tx_preemph_tuning_val))) {
|
||||
sata_phy->tx_preemph_tuning_val[0] =
|
||||
SATA_P0_PHY_TX_PREEMPH_GEN1_DEFAULT;
|
||||
sata_phy->tx_preemph_tuning_val[1] =
|
||||
SATA_P0_PHY_TX_PREEMPH_GEN2_DEFAULT;
|
||||
sata_phy->tx_preemph_tuning_val[2] =
|
||||
SATA_P0_PHY_TX_PREEMPH_GEN3_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
static int eic7700_sata_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct eic7700_sata_phy *sata_phy;
|
||||
struct phy_provider *phy_provider;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct resource *res;
|
||||
void __iomem *regs;
|
||||
|
||||
sata_phy = devm_kzalloc(dev, sizeof(*sata_phy), GFP_KERNEL);
|
||||
if (!sata_phy)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* Map the I/O resource with platform_get_resource and devm_ioremap
|
||||
* instead of the devm_platform_ioremap_resource API, because the
|
||||
* address region of the SATA-PHY falls into the region of the HSP
|
||||
* clock & reset that has already been obtained by the HSP
|
||||
* clock-and-reset driver.
|
||||
*/
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -ENOENT;
|
||||
|
||||
regs = devm_ioremap(dev, res->start, resource_size(res));
|
||||
if (IS_ERR(regs))
|
||||
return PTR_ERR(regs);
|
||||
|
||||
sata_phy->regmap = devm_regmap_init_mmio
|
||||
(dev, regs, &eic7700_sata_phy_regmap_config);
|
||||
if (IS_ERR(sata_phy->regmap))
|
||||
return dev_err_probe(dev, PTR_ERR(sata_phy->regmap),
|
||||
"failed to init regmap\n");
|
||||
|
||||
dev_set_drvdata(dev, sata_phy);
|
||||
|
||||
eic7700_get_tuning_param(np, sata_phy);
|
||||
|
||||
sata_phy->clk = devm_clk_get(dev, "phy");
|
||||
if (IS_ERR(sata_phy->clk))
|
||||
return PTR_ERR(sata_phy->clk);
|
||||
|
||||
sata_phy->rst = devm_reset_control_array_get_exclusive(dev);
|
||||
if (IS_ERR(sata_phy->rst))
|
||||
return dev_err_probe(dev, PTR_ERR(sata_phy->rst),
|
||||
"failed to get reset control\n");
|
||||
|
||||
sata_phy->phy = devm_phy_create(dev, NULL, &eic7700_sata_phy_ops);
|
||||
if (IS_ERR(sata_phy->phy))
|
||||
return dev_err_probe(dev, PTR_ERR(sata_phy->phy),
|
||||
"failed to create PHY\n");
|
||||
|
||||
phy_set_drvdata(sata_phy->phy, sata_phy);
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
if (IS_ERR(phy_provider))
|
||||
return dev_err_probe(dev, PTR_ERR(phy_provider),
|
||||
"failed to register PHY provider\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id eic7700_sata_phy_of_match[] = {
|
||||
{ .compatible = "eswin,eic7700-sata-phy" },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, eic7700_sata_phy_of_match);
|
||||
|
||||
static struct platform_driver eic7700_sata_phy_driver = {
|
||||
.probe = eic7700_sata_phy_probe,
|
||||
.driver = {
|
||||
.of_match_table = eic7700_sata_phy_of_match,
|
||||
.name = "eic7700-sata-phy",
|
||||
}
|
||||
};
|
||||
module_platform_driver(eic7700_sata_phy_driver);
|
||||
|
||||
MODULE_DESCRIPTION("SATA PHY driver for the ESWIN EIC7700 SoC");
|
||||
MODULE_AUTHOR("Yulin Lu <luyulin@eswincomputing.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -14,15 +14,19 @@
|
|||
#define HSIC_ENABLE BIT(7)
|
||||
#define PLL_BYPASS BIT(4)
|
||||
|
||||
struct mmp3_hsic_data {
|
||||
void __iomem *base;
|
||||
};
|
||||
|
||||
static int mmp3_hsic_phy_init(struct phy *phy)
|
||||
{
|
||||
void __iomem *base = (void __iomem *)phy_get_drvdata(phy);
|
||||
struct mmp3_hsic_data *mmp3 = phy_get_drvdata(phy);
|
||||
u32 hsic_ctrl;
|
||||
|
||||
hsic_ctrl = readl_relaxed(base + HSIC_CTRL);
|
||||
hsic_ctrl = readl_relaxed(mmp3->base + HSIC_CTRL);
|
||||
hsic_ctrl |= HSIC_ENABLE;
|
||||
hsic_ctrl |= PLL_BYPASS;
|
||||
writel_relaxed(hsic_ctrl, base + HSIC_CTRL);
|
||||
writel_relaxed(hsic_ctrl, mmp3->base + HSIC_CTRL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -41,13 +45,17 @@ MODULE_DEVICE_TABLE(of, mmp3_hsic_phy_of_match);
|
|||
static int mmp3_hsic_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct mmp3_hsic_data *mmp3;
|
||||
struct phy_provider *provider;
|
||||
void __iomem *base;
|
||||
struct phy *phy;
|
||||
|
||||
base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
mmp3 = devm_kzalloc(dev, sizeof(*mmp3), GFP_KERNEL);
|
||||
if (!mmp3)
|
||||
return -ENOMEM;
|
||||
|
||||
mmp3->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
|
||||
if (IS_ERR(mmp3->base))
|
||||
return PTR_ERR(mmp3->base);
|
||||
|
||||
phy = devm_phy_create(dev, NULL, &mmp3_hsic_phy_ops);
|
||||
if (IS_ERR(phy)) {
|
||||
|
|
@ -55,7 +63,7 @@ static int mmp3_hsic_phy_probe(struct platform_device *pdev)
|
|||
return PTR_ERR(phy);
|
||||
}
|
||||
|
||||
phy_set_drvdata(phy, (void *)base);
|
||||
phy_set_drvdata(phy, mmp3);
|
||||
provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
if (IS_ERR(provider)) {
|
||||
dev_err(dev, "failed to register PHY provider\n");
|
||||
|
|
|
|||
|
|
@ -276,14 +276,14 @@ enum mtk_phy_version {
|
|||
};
|
||||
|
||||
/**
|
||||
* mtk_phy_pdata - SoC specific platform data
|
||||
* struct mtk_phy_pdata - SoC specific platform data
|
||||
* @avoid_rx_sen_degradation: Avoid TX Sensitivity level degradation (MT6795/8173 only)
|
||||
* @sw_pll_48m_to_26m: Workaround for V3 IP (MT8195) - switch the 48MHz PLL from
|
||||
* fractional mode to integer to output 26MHz for U2PHY
|
||||
* @sw_efuse_supported: Switches off eFuse auto-load from PHY and applies values
|
||||
* read from different nvmem (usually different eFuse array)
|
||||
* that is pointed at in the device tree node for this PHY
|
||||
* @slew_ref_clk_mhz: Default reference clock (in MHz) for slew rate calibration
|
||||
* @slew_ref_clock_mhz: Default reference clock (in MHz) for slew rate calibration
|
||||
* @slew_rate_coefficient: Coefficient for slew rate calibration
|
||||
* @version: PHY IP Version
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ static const struct m31_phy_tbl_entry m31_eusb2_setup_tbl[] = {
|
|||
M31_EUSB_PHY_INIT_CFG(USB_PHY_CFG0, UTMI_PHY_CMN_CTRL_OVERRIDE_EN, 1),
|
||||
M31_EUSB_PHY_INIT_CFG(USB_PHY_UTMI_CTRL5, POR, 1),
|
||||
M31_EUSB_PHY_INIT_CFG(USB_PHY_HS_PHY_CTRL_COMMON0, PHY_ENABLE, 1),
|
||||
M31_EUSB_PHY_INIT_CFG(USB_PHY_CFG1, PLL_EN, 1),
|
||||
M31_EUSB_PHY_INIT_CFG(USB_PHY_CFG1, PLL_EN, 0),
|
||||
M31_EUSB_PHY_INIT_CFG(USB_PHY_FSEL_SEL, FSEL_SEL, 1),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1679,7 +1679,7 @@ static int qmp_usbc_register_clocks(struct qmp_usbc *qmp, struct device_node *np
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (qmp->dp_serdes != 0) {
|
||||
if (qmp->dp_serdes) {
|
||||
ret = phy_dp_clks_register(qmp, np);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
@ -1833,7 +1833,7 @@ static int qmp_usbc_parse_dt(struct qmp_usbc *qmp)
|
|||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
if (offs->dp_serdes != 0) {
|
||||
if (offs->dp_serdes) {
|
||||
qmp->dp_serdes = base + offs->dp_serdes;
|
||||
qmp->dp_tx = base + offs->dp_txa;
|
||||
qmp->dp_tx2 = base + offs->dp_txb;
|
||||
|
|
@ -1982,7 +1982,7 @@ static int qmp_usbc_probe(struct platform_device *pdev)
|
|||
|
||||
phy_set_drvdata(qmp->usb_phy, qmp);
|
||||
|
||||
if (qmp->dp_serdes != 0) {
|
||||
if (qmp->dp_serdes) {
|
||||
qmp->dp_phy = devm_phy_create(dev, np, &qmp_usbc_dp_phy_ops);
|
||||
if (IS_ERR(qmp->dp_phy)) {
|
||||
ret = PTR_ERR(qmp->dp_phy);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,18 @@
|
|||
#
|
||||
# Phy drivers for SpacemiT platforms
|
||||
#
|
||||
config PHY_SPACEMIT_K1_PCIE
|
||||
tristate "PCIe and combo PHY driver for the SpacemiT K1 SoC"
|
||||
depends on ARCH_SPACEMIT || COMPILE_TEST
|
||||
depends on COMMON_CLK
|
||||
depends on HAS_IOMEM
|
||||
depends on OF
|
||||
select GENERIC_PHY
|
||||
default ARCH_SPACEMIT
|
||||
help
|
||||
Enable support for the PCIe and USB 3 combo PHY and two
|
||||
PCIe-only PHYs used in the SpacemiT K1 SoC.
|
||||
|
||||
config PHY_SPACEMIT_K1_USB2
|
||||
tristate "SpacemiT K1 USB 2.0 PHY support"
|
||||
depends on (ARCH_SPACEMIT || COMPILE_TEST) && OF
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_PHY_SPACEMIT_K1_PCIE) += phy-k1-pcie.o
|
||||
obj-$(CONFIG_PHY_SPACEMIT_K1_USB2) += phy-k1-usb2.o
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user