* Re: [PATCH 5/8] dt-bindings: mmc: axiado: Add axiado eMMC variant
From: Tzu-Hao Wei @ 2026-02-05 3:35 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: SriNavmani A, Prasad Bolisetty, Vinod Koul, Neil Armstrong,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Harshit Shah,
Ulf Hansson, Adrian Hunter, Michal Simek, linux-phy, devicetree,
linux-arm-kernel, linux-kernel, linux-mmc
In-Reply-To: <20251227-industrious-mammoth-of-culture-ff9dbe@quoll>
On 12/27/2025 8:50 PM, Krzysztof Kozlowski wrote:
> CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
>
>
> On Mon, Dec 22, 2025 at 04:45:04PM +0800, Tzu-Hao Wei wrote:
>> From: SriNavmani A <srinavmani@axiado.com>
>>
>> Add device tree binding variant for the Axiado AX3000 Arasan eMMC
>> controller. This variant identifies the specific eMMC controller
>> implementation used on the AX3000 SoC and enables the appropriate
>> driver configuration.
>>
>> Signed-off-by: Tzu-Hao Wei <twei@axiado.com>
>
> Incorrect DCO chain.
>
>
> Best regards,
> Krzysztof
>
Fixed DOC chain in the new patchset.
Best regards,
TH
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 6/8] mmc: host: axiado: add AX3000 eMMC PHY support to sdhci-of-arasan
From: Tzu-Hao Wei @ 2026-02-05 3:36 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: SriNavmani A, Prasad Bolisetty, Vinod Koul, Neil Armstrong,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Harshit Shah,
Ulf Hansson, Adrian Hunter, Michal Simek, linux-phy, devicetree,
linux-arm-kernel, linux-kernel, linux-mmc
In-Reply-To: <20251223-optimal-ochre-kestrel-a8cb1c@quoll>
On 12/23/2025 10:34 PM, Krzysztof Kozlowski wrote:
>> @@ -2019,15 +2023,17 @@ static int sdhci_arasan_probe(struct platform_device *pdev)
>> goto unreg_clk;
>> }
>>
>> - host->mmc_host_ops.hs400_enhanced_strobe =
>> + if (!of_device_is_compatible(np, "axiado,ax3000-sdhci-5.1-emmc")) {
>
> No, don't sprinkle compatibles all around. You should use driver match
> data for this.
>
> Best regards,
> Krzysztof
>
Thanks for suggestion. The new patch uses driver match data instead of sprinkling compatibles.
Best regards,
TH
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 2/8] phy: axiado: add Arasan eMMC-PHY for Axiado
From: Tzu-Hao Wei @ 2026-02-05 3:36 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: SriNavmani A, Prasad Bolisetty, Vinod Koul, Neil Armstrong,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Harshit Shah,
Ulf Hansson, Adrian Hunter, Michal Simek, linux-phy, devicetree,
linux-arm-kernel, linux-kernel, linux-mmc
In-Reply-To: <20251223-grumpy-daft-loon-6a6186@quoll>
On 12/23/2025 10:32 PM, Krzysztof Kozlowski wrote:
> CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
>
>
> On Mon, Dec 22, 2025 at 04:45:01PM +0800, Tzu-Hao Wei wrote:
>> @@ -15,6 +15,7 @@ obj-$(CONFIG_PHY_AIROHA_PCIE) += phy-airoha-pcie.o
>> obj-$(CONFIG_PHY_NXP_PTN3222) += phy-nxp-ptn3222.o
>
>
> Where is maintainers file update in this patch? Why shall we take
> unmaintained code?
>
It's in this series 4/8.
>> obj-y += allwinner/ \
>> amlogic/ \
>> + axiado/ \
>> broadcom/ \
>> cadence/ \
>> freescale/ \
>> diff --git a/drivers/phy/axiado/Kconfig b/drivers/phy/axiado/Kconfig
>> new file mode 100644
>> index 0000000000000000000000000000000000000000..824114e6068da327308321b9884552ad33db9efc
>> --- /dev/null
>> +++ b/drivers/phy/axiado/Kconfig
>> @@ -0,0 +1,15 @@
>> +#
>> +# PHY drivers for Axiado platforms
>> +#
>> +
>
> Missing menuconfig or other if-block for groupping this with your ARCH
> and COMPILE_TEST dependency.
>
Updated in the next version with
depends on OF && (ARCH_AXIADO || COMPILE_TEST)
> Look how other NEW and MAINTAINED platforms did it.
>
>> +config PHY_AX3000_EMMC
>> + tristate "Axiado eMMC PHY driver"
>> + select GENERIC_PHY
>> + help
>> + This enables support for the eMMC PHY block found on the
>> + Axiado AX3000 SoCs. The PHY provides the physical layer
>> + interface used by the Arasan SDHCI host controller for emmc
>> + signaling and timing adjustment.
>> +
>> + If you are building a kernel for AX3000 platform with
>> + eMMC storage, say Y or N.
>
> ...
>
>
Clean up the description in the new patch.
>> +static void arasan_emmc_phy_write(struct axiado_emmc_phy *ax_phy, u32 offset, u32 data)
>> +{
>> + writel(data, ax_phy->reg_base + offset);
>> +}
>> +
>> +static int arasan_emmc_phy_read(struct axiado_emmc_phy *ax_phy, u32 offset)
>
> Useless wrappers. Just use readl/writel directly. You are not making
> code more readable.
>
Removed wrappers and use readl/writel directly.
>> +
>> + while (1) {
>
> You proper read_poll loop.
Removed while() and use readl_poll_timeout()
>> + bool timedout = ktime_after(ktime_get(), timeout);
>> +
>> + if (arasan_emmc_phy_read(ax_phy, STATUS) & DLL_RDY_MASK)
>> + break;
>> +
>> + if (timedout) {
>> + dev_err(&phy->dev, "DLL_RDY_MASK bit is not cleared.");
>> + return -ETIMEDOUT;
>> + }
>> + udelay(TIMEOUT_DELAY);
>
> ...
>
Removed.
>> +static int axiado_emmc_phy_probe(struct platform_device *pdev)
>> +{
>> + struct axiado_emmc_phy *ax_phy;
>> + struct phy_provider *phy_provider;
>> + struct device *dev = &pdev->dev;
>> + const struct of_device_id *id;
>> + struct phy *generic_phy;
>> + struct resource *res;
>> +
>> + if (!dev->of_node)
>> + return -ENODEV;
>> +
>> + ax_phy = devm_kzalloc(dev, sizeof(*ax_phy), GFP_KERNEL);
>> + if (!ax_phy)
>> + return -ENOMEM;
>> +
>> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +
>
> Use proper wrapper to combine get resource and ioremap.
>
Fixed.
Calling devm_platform_ioremap_resource(pdev, 0) now.
>> + ax_phy->reg_base = devm_ioremap_resource(&pdev->dev, res);
>> +
>
> Drop blank line, there's never such.
>
Removed
>> + if (IS_ERR(ax_phy->reg_base))
>> + return PTR_ERR(ax_phy->reg_base);
>> +
>> + id = of_match_node(axiado_emmc_phy_of_match, pdev->dev.of_node);
>> + if (!id) {
>> + dev_err(dev, "failed to get match_node\n");
>
> What is the point of this? You do not use this match at all, no other
> devices. How can your device bind and still fail the match?
>
> Drop
>
Removed.
>> + return -EINVAL;
>> + }
>> +
>> + generic_phy = devm_phy_create(dev, dev->of_node, &axiado_emmc_phy_ops);
>> + if (IS_ERR(generic_phy)) {
>> + dev_err(dev, "failed to create PHY\n");
>> + return PTR_ERR(generic_phy);
>
> Syntax is - return dev_err_probe.
>
Fixed.
> Didn't Axiado receive this feedback before? Are you sure that you have
> procedures set inside to avoid repeating same mistakes?
>
> Best regards,
> Krzysztof
>
Thanks Krzysztof.
I have checked the comments one-by-one and make sure every comments
are adopted.
Best regards,
TH
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 1/8] dt-bindings: phy: axiado,ax3000-emmc-phy: add Axiado eMMC PHY document
From: Tzu-Hao Wei @ 2026-02-05 3:36 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: SriNavmani A, Prasad Bolisetty, Vinod Koul, Neil Armstrong,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Harshit Shah,
Ulf Hansson, Adrian Hunter, Michal Simek, linux-phy, devicetree,
linux-arm-kernel, linux-kernel, linux-mmc
In-Reply-To: <20251223-adder-of-imminent-recreation-ea90c0@quoll>
On 12/23/2025 10:23 PM, Krzysztof Kozlowski wrote:
> CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
>
>
> On Mon, Dec 22, 2025 at 04:45:00PM +0800, Tzu-Hao Wei wrote:
>> From: SriNavmani A <srinavmani@axiado.com>
>>
>> Add device tree bindings for the Axiado AX3000 eMMC PHY. The bindings
>> define the required properties for configuring the external Arasan
>
> Ah, and also:
>
> A nit, subject: drop second/last, redundant "document". The
> "dt-bindings" prefix is already stating that these are documents.
> See also:
> https://elixir.bootlin.com/linux/v6.17-rc3/source/Documentation/devicetree/bindings/submitting-patches.rst#L18
>
> Best regards,
> Krzysztof
>
Revised the subject in the new patch
Best regards,
TH
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v2 2/2] mmc: sdhci-of-arasan: add support on Axiado AX3000 SoC
From: Tzu-Hao Wei @ 2026-02-05 3:37 UTC (permalink / raw)
To: Adrian Hunter
Cc: linux-phy, devicetree, linux-arm-kernel, linux-kernel, linux-mmc,
openbmc, SriNavmani A, Prasad Bolisetty, Vinod Koul,
Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Ulf Hansson, Michal Simek
In-Reply-To: <d370870a-d4f9-4989-ade3-e2b26b2a1134@intel.com>
On 1/12/2026 4:23 PM, Adrian Hunter wrote:
> CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
>
>
> On 09/01/2026 11:46, Tzu-Hao Wei wrote:
>> From: SriNavmani A <srinavmani@axiado.com>
>>
>> Axiado AX3000 SoC eMMC controller is based on Arasan eMMC 5.1 host
>> controller IP.
>>
>> Signed-off-by: SriNavmani A <srinavmani@axiado.com>
>> Signed-off-by: Tzu-Hao Wei <twei@axiado.com>
>
> Apart from dt-bindings issues:
>
> Acked-by: Adrian Hunter <adrian.hunter@intel.com>
>
>> ---
>> drivers/mmc/host/sdhci-of-arasan.c | 14 ++++++++++++++
>> 1 file changed, 14 insertions(+)
>>
>> diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
>> index ab7f0ffe7b4f007a58eb0a26868b08b0b02b40f3..5da915edd7416ab5c725a784867098c5e19236b6 100644
>> --- a/drivers/mmc/host/sdhci-of-arasan.c
>> +++ b/drivers/mmc/host/sdhci-of-arasan.c
>> @@ -1512,6 +1512,16 @@ static struct sdhci_arasan_of_data intel_keembay_sdio_data = {
>> .clk_ops = &arasan_clk_ops,
>> };
>>
>> +static const struct sdhci_pltfm_data sdhci_arasan_axiado_pdata = {
>> + .ops = &sdhci_arasan_ops,
>> + .quirks = SDHCI_QUIRK_BROKEN_CQE,
>> +};
>> +
>> +static struct sdhci_arasan_of_data sdhci_arasan_axiado_data = {
>> + .pdata = &sdhci_arasan_axiado_pdata,
>> + .clk_ops = &arasan_clk_ops,
>> +};
>> +
>> static const struct of_device_id sdhci_arasan_of_match[] = {
>> /* SoC-specific compatible strings w/ soc_ctl_map */
>> {
>> @@ -1538,6 +1548,10 @@ static const struct of_device_id sdhci_arasan_of_match[] = {
>> .compatible = "intel,keembay-sdhci-5.1-sdio",
>> .data = &intel_keembay_sdio_data,
>> },
>> + {
>> + .compatible = "axiado,ax3000-sdhci-5.1-emmc",
>> + .data = &sdhci_arasan_axiado_data,
>> + },
>> /* Generic compatible below here */
>> {
>> .compatible = "arasan,sdhci-8.9a",
>>
>
Thanks for reviewing.
There is one line change in the upcoming latest patch so I didn't add your Acked-by.
Best regards,
TH
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 1/8] dt-bindings: phy: axiado,ax3000-emmc-phy: add Axiado eMMC PHY document
From: Tzu-Hao Wei @ 2026-02-05 3:38 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: SriNavmani A, Prasad Bolisetty, Vinod Koul, Neil Armstrong,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Harshit Shah,
Ulf Hansson, Adrian Hunter, Michal Simek, linux-phy, devicetree,
linux-arm-kernel, linux-kernel, linux-mmc
In-Reply-To: <20251223-nondescript-horned-mouflon-36ba75@quoll>
On 12/23/2025 10:23 PM, Krzysztof Kozlowski wrote:
> On Mon, Dec 22, 2025 at 04:45:00PM +0800, Tzu-Hao Wei wrote:
>> From: SriNavmani A <srinavmani@axiado.com>
>>
>> Add device tree bindings for the Axiado AX3000 eMMC PHY. The bindings
>> define the required properties for configuring the external Arasan
>> eMMC PHY, including register base addresses and clock references
>> needed for HS200 mode operation.
>
> Do not say what the bindings are supposed to do. We can read the diff.
> Explain the hardware.
>
Simplified the messages in the new patch.
>>
>> Signed-off-by: SriNavmani A <srinavmani@axiado.com>
>> Signed-off-by: Tzu-Hao Wei <twei@axiado.com>
>> ---
>> .../bindings/phy/axiado,ax3000-emmc-phy.yaml | 46 ++++++++++++++++++++++
>> 1 file changed, 46 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/axiado,ax3000-emmc-phy.yaml b/Documentation/devicetree/bindings/phy/axiado,ax3000-emmc-phy.yaml
>> new file mode 100644
>> index 0000000000000000000000000000000000000000..f88941ce60cbd99a73e8c504e0bf36c626bbf674
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/phy/axiado,ax3000-emmc-phy.yaml
>> @@ -0,0 +1,46 @@
>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/phy/axiado,ax3000-emmc-phy.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Axiado AX3000 Arasan eMMC PHY
>> +
>> +maintainers:
>> + - SriNavmani A <srinavmani@axiado.com>
>> + - Tzu-Hao Wei <twei@axiado.com>
>> + - Prasad Bolisetty <pbolisetty@axiado.com>
>> +
>> +description: |+
>> + Bindings for eMMC PHY on Axiado AX3000 SoC.
>
> Irrelevant
>
Removed.
>> +
>> + - compatible: Should be one of the following:
>> + "axiado,ax3000-emmc-phy"
>> + - reg:
>> + maxItems: 1
>
> Entire description is not correct. Do you see any file written like
> this/
>
Revised. It can pass DT_SCHEMA_CHECK and CHECK_DTBS now.
>> +
>> +properties:
>> + compatible:
>> + enum:
>> + - axiado,ax3000-emmc-phy
>> +
>> + "#phy-cells":
>> + const: 0
>> +
>> + reg:
>> + maxItems: 1
>> +
>> +required:
>> + - "#phy-cells"
>> + - compatible
>> + - reg
>
> Wrong order, use the same as in properties.
>
Fixed.
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> + - |
>> + emmc_phy: emmc-phy@80801C00 {
>
> Drop label and node is just phy@
>
> Also, use lowercase hex everywhere.
>
> Read DTS coding style - Axiado already received this feedback, so you
> should follow it in all your submissions.
>
> Best regards,
> Krzysztof
>
Dropped label, used lowercase hex.
Thanks for your feedback.
We will follow the style in the future.
Best regards,
TH
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v9 0/2] Add driver support for Eswin EIC7700 SoC SATA PHY
From: Yulin Lu @ 2026-02-05 8:20 UTC (permalink / raw)
To: vkoul, neil.armstrong, robh, krzk+dt, conor+dt, p.zabel,
linux-phy, devicetree, linux-kernel
Cc: ningyu, linmin, fenglin, Yulin Lu
Updates:
v9 -> v8:
- eswin,eic7700-sata-phy.yaml
- Modify the format of the "default" field in the
"eswin,tx-amplitude-tuning" and "eswin,tx-preemph-tuning"
properties.
- phy-eic7700-sata.c
- Correct the incorrectly formatted symbol "-" in the comments.
- Link to v8: https://lore.kernel.org/lkml/20260123024823.1612-1-luyulin@eswincomputing.com/
v8 -> v7:
- eswin,eic7700-sata-phy.yaml
- Add "eswin,tx-amplitude-tuning" and "eswin,tx-preemph-tuning"
properties, because these parameters may vary across different
circuit boards.
- Delete reviewed-by tag of Krzysztof Kozlowski, because the tuning
properties are introduced.
- phy-eic7700-sata.c
- Try to get SATA PHY transmitter amplitude and pre-emphasis signal
eye diagram tuning parameters from dts instead of hardcoded values
in the code. Because, these parameters may vary across different
circuit boards. Define default tuning parameters and use it when
these properties are not declared in dts.
- Add a comment to explain the reason for mapping I/O resources with
platform_get_resource and devm_ioremap instead of using the
devm_platform_ioremap_resource API.
- Link to v7: https://lore.kernel.org/lkml/20260106062944.1529-1-luyulin@eswincomputing.com/
v7 -> v6:
- phy-eic7700-sata.c
- Rename PHY_READY_TIMEOUT to PLL_LOCK_TIMEOUT_US with value 1000.
- Add macro PLL_LOCK_SLEEP_US set to 10.
- Add "goto disable_clk" in the eic7700_sata_phy_init function.
- Modify Copyright year from 2024 to 2026.
- Link to v6: https://lore.kernel.org/lkml/20251201060737.868-1-luyulin@eswincomputing.com/
v6 -> v5:
- eswin,eic7700-ahci.yaml
- Delete this file and it has already been applied in reply[1].
- eswin,eic7700-sata-phy.yaml
- Add clock and reset related properties.
- phy-eic7700-sata.c
- Map the io resource with platform_get_resource and devm_ioremap
instead of devm_platform_ioremap_resource API. Because the address
region of sata-phy falls into the region of hsp clock&reset which
has been got by hsp clock&reset driver.
- Use regmap_read_poll_timeout in wait_for_phy_ready to replace the
while loop check.
- Use devm_regmap_init_mmio and regmap_write to replace writel.
- Adapt to the clock and reset driver framework, replacing the
original readl and writel.
Because we are implementing the HSP layer clock and reset drivers,
the corresponding clock and reset registers can be registered into
the driver framework. And I have tested on the Sifive HiFive
Premier P550 board.
- Link to v5: https://lore.kernel.org/lkml/20250930083754.15-1-luyulin@eswincomputing.com/
v5 -> v4:
- eswin,eic7700-ahci.yaml
- Add "dt-bindings: ata:" prefix to the subject.
- Wrap at 80 characters in the YAML description field.
- Link to v4: https://lore.kernel.org/lkml/20250915125902.375-1-luyulin@eswincomputing.com/
v4 -> v3:
- eswin,eic7700-ahci.yaml
- Fix grammatical errors in patch subject and commit message
- Add an explanation in the commit message of patch 1 for retaining
the "ports-implemented" field, which Rob Herring suggested to
remove in the review comments on v2.
Link to Rob Herring's review:
https://lore.kernel.org/lkml/CAL_JsqKFotNLZZXwiy7S6K8qXLdGRAnsa-1zvZRDQBE39Gf5kg@mail.gmail.com/
Link to my question and Niklas Cassel's reply:
https://lore.kernel.org/lkml/aLBUC116MdJqDGIJ@flawful.org/
In this reply, Niklas Cassel mentioned his view:
If the ports-implemented register gets reset from
ahci_platform_assert_rsts(), then it seems acceptable to
retain the ports-implemented property in the device tree.
This aligns with our design.
Link to my reply:
https://lore.kernel.org/lkml/4ab70c6a.8be.198f47da494.Coremail.luyulin@eswincomputing.com/
Link to Niklas Cassel's question and my further explanation:
https://lore.kernel.org/lkml/aLlYkZWBaI5Yz6fo@ryzen/
https://lore.kernel.org/lkml/7206383a.d98.19918c22570.Coremail.luyulin@eswincomputing.com/
- eswin,eic7700-sata-phy.yaml
- Fix grammatical errors in patch subject and commit message
- Adjust the position of reg in the properties and required arrays
- Add reviewed-by tag of Krzysztof Kozlowski
- phy-eic7700-sata.c
- Correct the loop condition in wait_for_phy_ready() to use the
current jiffies instead of the fixed start time.
- Change the return value from -EFAULT to -ETIMEDOUT to correctly
indicate a timeout condition.
- Remove redundant clock disable handling in probe error path, as
SATA_SYS_CLK_EN is managed in phy_init() and phy_exit().
- Use dev_err_probe return in probe.
- Reorder local variables to follow reverse Xmas tree order.
- Wrap each line in the extended comments to 80 columns before
splitting lines.
- Adjust the position of `#include <linux/io.h>` for proper ordering.
- Link to v3: https://lore.kernel.org/lkml/20250904063427.1954-1-luyulin@eswincomputing.com/
v2 -> v3:
- Use full name in "From" and "Signed-off-by" fields information
- eswin,eic7700-ahci.yaml
- Remove the introduction to the reg, interrupts, phys, and
phy-names fields.
- Modify the usage of the clocks field in the examples.
- Correct the order of dt properties.
- phy-eic7700-sata.c
- Register operations use the GENMASK macro and FIELD_PREP instead
of the original bit offset method, and add
"#include <linux/bitfield.h>".
- Modify some macro definition names.
- Remove the redundant initialization assignments for "ret" and
"val".
- Delete ".suppress_bind_attrs = true".
- Modify the driver name.
- Add "#include <linux/io.h>" to fix the robot test issue.
- Link to v2: https://lore.kernel.org/lkml/20250819134722.220-1-luyulin@eswincomputing.com/
v2 -> v1:
- Delete the original controller driver and use ahci_dwc.c instead.
- Add eswin,eic7700-ahci.yaml
- Correct the descriptions of reset, interrupt and other hardware
resources for the sata controller on EIC7700 SoC.
- The clocks for both sata controller and sata PHY are controlled
via a register bit in the HSP bus and are not registered in the
clock tree. Clock are managed within the PHY driver, therefore it
is not described in this document.
- Add $ref: snps,dwc-ahci-common.yaml#.
- Add eswin,eic7700-sata-phy.yaml
- Add this file to include the description of the PHY on EIC7700 SoC.
- Add an eswin directory under the PHY driver path, and include the
SATA PHY driver code for EIC7700 SoC.
- Link to v1: https://lore.kernel.org/all/20250515085114.1692-1-hehuan1@eswincomputing.com/
Yulin Lu (2):
dt-bindings: phy: eswin: Document the EIC7700 SoC SATA PHY
phy: eswin: Create eswin directory and add EIC7700 SATA PHY driver
.../bindings/phy/eswin,eic7700-sata-phy.yaml | 92 ++++++
drivers/phy/Kconfig | 1 +
drivers/phy/Makefile | 1 +
drivers/phy/eswin/Kconfig | 14 +
drivers/phy/eswin/Makefile | 2 +
drivers/phy/eswin/phy-eic7700-sata.c | 273 ++++++++++++++++++
6 files changed, 383 insertions(+)
create mode 100644 Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml
create mode 100644 drivers/phy/eswin/Kconfig
create mode 100644 drivers/phy/eswin/Makefile
create mode 100644 drivers/phy/eswin/phy-eic7700-sata.c
--
2.25.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v9 1/2] dt-bindings: phy: eswin: Document the EIC7700 SoC SATA PHY
From: Yulin Lu @ 2026-02-05 8:21 UTC (permalink / raw)
To: vkoul, neil.armstrong, robh, krzk+dt, conor+dt, p.zabel,
linux-phy, devicetree, linux-kernel
Cc: ningyu, linmin, fenglin, Yulin Lu
In-Reply-To: <20260205082009.1780-1-luyulin@eswincomputing.com>
Document the SATA PHY on the EIC7700 SoC platform,
describing its usage.
Signed-off-by: Yulin Lu <luyulin@eswincomputing.com>
---
.../bindings/phy/eswin,eic7700-sata-phy.yaml | 92 +++++++++++++++++++
1 file changed, 92 insertions(+)
create mode 100644 Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml
diff --git a/Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml b/Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml
new file mode 100644
index 000000000000..fc7dbac77acf
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml
@@ -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>;
+ };
--
2.25.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v9 2/2] phy: eswin: Create eswin directory and add EIC7700 SATA PHY driver
From: Yulin Lu @ 2026-02-05 8:22 UTC (permalink / raw)
To: vkoul, neil.armstrong, robh, krzk+dt, conor+dt, p.zabel,
linux-phy, devicetree, linux-kernel
Cc: ningyu, linmin, fenglin, Yulin Lu
In-Reply-To: <20260205082009.1780-1-luyulin@eswincomputing.com>
Create the eswin phy driver directory and add support for the
SATA PHY driver on the EIC7700 SoC platform.
Signed-off-by: Yulin Lu <luyulin@eswincomputing.com>
---
drivers/phy/Kconfig | 1 +
drivers/phy/Makefile | 1 +
drivers/phy/eswin/Kconfig | 14 ++
drivers/phy/eswin/Makefile | 2 +
drivers/phy/eswin/phy-eic7700-sata.c | 273 +++++++++++++++++++++++++++
5 files changed, 291 insertions(+)
create mode 100644 drivers/phy/eswin/Kconfig
create mode 100644 drivers/phy/eswin/Makefile
create mode 100644 drivers/phy/eswin/phy-eic7700-sata.c
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 678dd0452f0a..6d50704917f0 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -105,6 +105,7 @@ source "drivers/phy/allwinner/Kconfig"
source "drivers/phy/amlogic/Kconfig"
source "drivers/phy/broadcom/Kconfig"
source "drivers/phy/cadence/Kconfig"
+source "drivers/phy/eswin/Kconfig"
source "drivers/phy/freescale/Kconfig"
source "drivers/phy/hisilicon/Kconfig"
source "drivers/phy/ingenic/Kconfig"
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index bfb27fb5a494..482a143d3417 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -17,6 +17,7 @@ obj-y += allwinner/ \
amlogic/ \
broadcom/ \
cadence/ \
+ eswin/ \
freescale/ \
hisilicon/ \
ingenic/ \
diff --git a/drivers/phy/eswin/Kconfig b/drivers/phy/eswin/Kconfig
new file mode 100644
index 000000000000..cf2bf2efc32f
--- /dev/null
+++ b/drivers/phy/eswin/Kconfig
@@ -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.
diff --git a/drivers/phy/eswin/Makefile b/drivers/phy/eswin/Makefile
new file mode 100644
index 000000000000..db08c66be812
--- /dev/null
+++ b/drivers/phy/eswin/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_PHY_EIC7700_SATA) += phy-eic7700-sata.o
diff --git a/drivers/phy/eswin/phy-eic7700-sata.c b/drivers/phy/eswin/phy-eic7700-sata.c
new file mode 100644
index 000000000000..c33653d48daa
--- /dev/null
+++ b/drivers/phy/eswin/phy-eic7700-sata.c
@@ -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");
--
2.25.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH 0/3] phy: qcom: edp: Add DP/eDP switch for phys
From: Yongxing Mou @ 2026-02-05 9:20 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong
Cc: linux-arm-msm, linux-phy, linux-kernel, Yongxing Mou
Currently the PHY selects the DP/eDP configuration tables in a fixed way,
choosing the table when enable. This driver has known issues:
1. The selected table does not match the actual platform mode.
2. It cannot support both modes at the same time.
As discussed here[1], this series:
1. Cleans up duplicated and incorrect tables based on the HPG.
2. Fixes the LDO programming error in eDP mode.
3. Adds DP/eDP mode switching support.
Note: x1e80100/sa8775p/sc7280 have been tested, while glymur/sc8280xp
have not been tested.
[1] https://lore.kernel.org/all/20260119-klm_dpphy-v2-1-52252190940b@oss.qualcomm.com/
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
---
Yongxing Mou (3):
phy: qcom: edp: Correct and clean up eDP/DP combo PHY configuration values
phy: qcom: edp: Add per-version LDO configuration callback
phy: qcom: edp: Add eDP phy mode switch support
drivers/phy/qualcomm/phy-qcom-edp.c | 191 ++++++++++++++++++++++++++----------
1 file changed, 138 insertions(+), 53 deletions(-)
---
base-commit: fc4e91c639c0af93d63c3d5bc0ee45515dd7504a
change-id: 20260205-edp_phy-1eca3ed074c0
Best regards,
--
Yongxing Mou <yongxing.mou@oss.qualcomm.com>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH 1/3] phy: qcom: edp: Correct and clean up eDP/DP combo PHY configuration values
From: Yongxing Mou @ 2026-02-05 9:20 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong
Cc: linux-arm-msm, linux-phy, linux-kernel, Yongxing Mou
In-Reply-To: <20260205-edp_phy-v1-0-231882bbf3f1@oss.qualcomm.com>
According to the current HPG settings, most eDP/DP combo PHYs can reuse the
same configuration values.
DP mode:
-sa8775p/sc7280/sc8280xp/x1e80100
-glymur
eDP mode(low vdiff):
-glymur/sa8775p/sc8280xp/x1e80100
-sc7280
The current driver still keeps multiple versions of these tables and
doesn't fully support every combo PHY mode. This patch removes the
redundant configs and keeps only the sets we actually use, matching the
platforms listed above.
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-edp.c | 41 +++++++++----------------------------
1 file changed, 10 insertions(+), 31 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
index 13feab99feec..10cbb7d9a8a0 100644
--- a/drivers/phy/qualcomm/phy-qcom-edp.c
+++ b/drivers/phy/qualcomm/phy-qcom-edp.c
@@ -116,17 +116,17 @@ struct qcom_edp {
};
static const u8 dp_swing_hbr_rbr[4][4] = {
- { 0x08, 0x0f, 0x16, 0x1f },
+ { 0x07, 0x0f, 0x16, 0x1f },
{ 0x11, 0x1e, 0x1f, 0xff },
{ 0x16, 0x1f, 0xff, 0xff },
{ 0x1f, 0xff, 0xff, 0xff }
};
static const u8 dp_pre_emp_hbr_rbr[4][4] = {
- { 0x00, 0x0d, 0x14, 0x1a },
+ { 0x00, 0x0e, 0x15, 0x1a },
{ 0x00, 0x0e, 0x15, 0xff },
{ 0x00, 0x0e, 0xff, 0xff },
- { 0x03, 0xff, 0xff, 0xff }
+ { 0x04, 0xff, 0xff, 0xff }
};
static const u8 dp_swing_hbr2_hbr3[4][4] = {
@@ -158,7 +158,7 @@ static const u8 edp_swing_hbr_rbr[4][4] = {
};
static const u8 edp_pre_emp_hbr_rbr[4][4] = {
- { 0x05, 0x12, 0x17, 0x1d },
+ { 0x05, 0x11, 0x17, 0x1d },
{ 0x05, 0x11, 0x18, 0xff },
{ 0x06, 0x11, 0xff, 0xff },
{ 0x00, 0xff, 0xff, 0xff }
@@ -172,10 +172,10 @@ static const u8 edp_swing_hbr2_hbr3[4][4] = {
};
static const u8 edp_pre_emp_hbr2_hbr3[4][4] = {
- { 0x08, 0x11, 0x17, 0x1b },
- { 0x00, 0x0c, 0x13, 0xff },
- { 0x05, 0x10, 0xff, 0xff },
- { 0x00, 0xff, 0xff, 0xff }
+ { 0x0c, 0x15, 0x19, 0x1e },
+ { 0x0b, 0x15, 0x19, 0xff },
+ { 0x0e, 0x14, 0xff, 0xff },
+ { 0x0d, 0xff, 0xff, 0xff }
};
static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg = {
@@ -193,27 +193,6 @@ static const u8 edp_phy_vco_div_cfg_v4[4] = {
0x01, 0x01, 0x02, 0x00,
};
-static const u8 edp_pre_emp_hbr_rbr_v5[4][4] = {
- { 0x05, 0x11, 0x17, 0x1d },
- { 0x05, 0x11, 0x18, 0xff },
- { 0x06, 0x11, 0xff, 0xff },
- { 0x00, 0xff, 0xff, 0xff }
-};
-
-static const u8 edp_pre_emp_hbr2_hbr3_v5[4][4] = {
- { 0x0c, 0x15, 0x19, 0x1e },
- { 0x0b, 0x15, 0x19, 0xff },
- { 0x0e, 0x14, 0xff, 0xff },
- { 0x0d, 0xff, 0xff, 0xff }
-};
-
-static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg_v5 = {
- .swing_hbr_rbr = &edp_swing_hbr_rbr,
- .swing_hbr3_hbr2 = &edp_swing_hbr2_hbr3,
- .pre_emphasis_hbr_rbr = &edp_pre_emp_hbr_rbr_v5,
- .pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3_v5,
-};
-
static const u8 edp_phy_aux_cfg_v5[DP_AUX_CFG_SIZE] = {
0x00, 0x13, 0xa4, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03, 0x02, 0x02, 0x00,
};
@@ -564,7 +543,7 @@ static const struct qcom_edp_phy_cfg sa8775p_dp_phy_cfg = {
.is_edp = false,
.aux_cfg = edp_phy_aux_cfg_v5,
.vco_div_cfg = edp_phy_vco_div_cfg_v4,
- .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v5,
+ .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
.ver_ops = &qcom_edp_phy_ops_v4,
};
@@ -944,7 +923,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v8 = {
static struct qcom_edp_phy_cfg glymur_phy_cfg = {
.aux_cfg = edp_phy_aux_cfg_v8,
.vco_div_cfg = edp_phy_vco_div_cfg_v8,
- .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v5,
+ .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
.ver_ops = &qcom_edp_phy_ops_v8,
};
--
2.43.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH 3/3] phy: qcom: edp: Add eDP phy mode switch support
From: Yongxing Mou @ 2026-02-05 9:20 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong
Cc: linux-arm-msm, linux-phy, linux-kernel, Yongxing Mou
In-Reply-To: <20260205-edp_phy-v1-0-231882bbf3f1@oss.qualcomm.com>
Add DP/eDP switch support by splitting the PHY swing/pre-emphasis tables
into separate DP and eDP configurations. This allows the driver to select
the correct table based on the is_edp flag.
Add a dedicated table for the SC7280/glymur platforms, as they are not
compatible with the others.
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-edp.c | 72 ++++++++++++++++++++++++++++---------
1 file changed, 56 insertions(+), 16 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
index 388226dbad7f..85caa869a8c0 100644
--- a/drivers/phy/qualcomm/phy-qcom-edp.c
+++ b/drivers/phy/qualcomm/phy-qcom-edp.c
@@ -88,7 +88,8 @@ struct qcom_edp_phy_cfg {
bool is_edp;
const u8 *aux_cfg;
const u8 *vco_div_cfg;
- const struct qcom_edp_swing_pre_emph_cfg *swing_pre_emph_cfg;
+ const struct qcom_edp_swing_pre_emph_cfg *dp_swing_pre_emph_cfg;
+ const struct qcom_edp_swing_pre_emph_cfg *edp_swing_pre_emph_cfg;
const struct phy_ver_ops *ver_ops;
};
@@ -151,6 +152,20 @@ static const struct qcom_edp_swing_pre_emph_cfg dp_phy_swing_pre_emph_cfg = {
.pre_emphasis_hbr3_hbr2 = &dp_pre_emp_hbr2_hbr3,
};
+static const u8 dp_pre_emp_hbr_rbr_v8[4][4] = {
+ { 0x00, 0x0e, 0x15, 0x1a },
+ { 0x00, 0x0e, 0x15, 0xff },
+ { 0x00, 0x0e, 0xff, 0xff },
+ { 0x00, 0xff, 0xff, 0xff }
+};
+
+static const struct qcom_edp_swing_pre_emph_cfg dp_phy_swing_pre_emph_cfg_v8 = {
+ .swing_hbr_rbr = &dp_swing_hbr_rbr,
+ .swing_hbr3_hbr2 = &dp_swing_hbr2_hbr3,
+ .pre_emphasis_hbr_rbr = &dp_pre_emp_hbr_rbr_v8,
+ .pre_emphasis_hbr3_hbr2 = &dp_pre_emp_hbr2_hbr3,
+};
+
static const u8 edp_swing_hbr_rbr[4][4] = {
{ 0x07, 0x0f, 0x16, 0x1f },
{ 0x0d, 0x16, 0x1e, 0xff },
@@ -186,6 +201,27 @@ static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg = {
.pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3,
};
+static const u8 edp_swing_hbr2_hbr3_v3[4][4] = {
+ { 0x0b, 0x11, 0x16, 0x1b },
+ { 0x0b, 0x19, 0x1f, 0xff },
+ { 0x18, 0x1f, 0xff, 0xff },
+ { 0x1f, 0xff, 0xff, 0xff }
+};
+
+static const u8 edp_pre_emp_hbr2_hbr3_v3[4][4] = {
+ { 0x0c, 0x15, 0x19, 0x1e },
+ { 0x09, 0x14, 0x19, 0xff },
+ { 0x0f, 0x14, 0xff, 0xff },
+ { 0x0d, 0xff, 0xff, 0xff }
+};
+
+static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg_v3 = {
+ .swing_hbr_rbr = &edp_swing_hbr_rbr,
+ .swing_hbr3_hbr2 = &edp_swing_hbr2_hbr3_v3,
+ .pre_emphasis_hbr_rbr = &edp_pre_emp_hbr_rbr,
+ .pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3_v3,
+};
+
static const u8 edp_phy_aux_cfg_v4[DP_AUX_CFG_SIZE] = {
0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03, 0x02, 0x02, 0x00,
};
@@ -242,12 +278,7 @@ static int qcom_edp_phy_init(struct phy *phy)
DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
edp->edp + DP_PHY_PD_CTL);
- /*
- * TODO: Re-work the conditions around setting the cfg8 value
- * when more information becomes available about why this is
- * even needed.
- */
- if (edp->cfg->swing_pre_emph_cfg && !edp->is_edp)
+ if (!edp->is_edp)
aux_cfg[8] = 0xb7;
writel(0xfc, edp->edp + DP_PHY_MODE);
@@ -271,7 +302,7 @@ static int qcom_edp_phy_init(struct phy *phy)
static int qcom_edp_set_voltages(struct qcom_edp *edp, const struct phy_configure_opts_dp *dp_opts)
{
- const struct qcom_edp_swing_pre_emph_cfg *cfg = edp->cfg->swing_pre_emph_cfg;
+ const struct qcom_edp_swing_pre_emph_cfg *cfg;
unsigned int v_level = 0;
unsigned int p_level = 0;
int ret;
@@ -279,12 +310,14 @@ static int qcom_edp_set_voltages(struct qcom_edp *edp, const struct phy_configur
u8 emph;
int i;
+ if (edp->is_edp)
+ cfg = edp->cfg->edp_swing_pre_emph_cfg;
+ else
+ cfg = edp->cfg->dp_swing_pre_emph_cfg;
+
if (!cfg)
return 0;
- if (edp->is_edp)
- cfg = &edp_phy_swing_pre_emph_cfg;
-
for (i = 0; i < dp_opts->lanes; i++) {
v_level = max(v_level, dp_opts->voltage[i]);
p_level = max(p_level, dp_opts->pre[i]);
@@ -591,20 +624,24 @@ static const struct qcom_edp_phy_cfg sa8775p_dp_phy_cfg = {
.is_edp = false,
.aux_cfg = edp_phy_aux_cfg_v5,
.vco_div_cfg = edp_phy_vco_div_cfg_v4,
- .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
+ .dp_swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
+ .edp_swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
.ver_ops = &qcom_edp_phy_ops_v4,
};
static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
.aux_cfg = edp_phy_aux_cfg_v4,
.vco_div_cfg = edp_phy_vco_div_cfg_v4,
+ .dp_swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
+ .edp_swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v3,
.ver_ops = &qcom_edp_phy_ops_v3,
};
static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = {
.aux_cfg = edp_phy_aux_cfg_v4,
.vco_div_cfg = edp_phy_vco_div_cfg_v4,
- .swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
+ .dp_swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
+ .edp_swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
.ver_ops = &qcom_edp_phy_ops_v4,
};
@@ -612,7 +649,8 @@ static const struct qcom_edp_phy_cfg sc8280xp_edp_phy_cfg = {
.is_edp = true,
.aux_cfg = edp_phy_aux_cfg_v4,
.vco_div_cfg = edp_phy_vco_div_cfg_v4,
- .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
+ .dp_swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
+ .edp_swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
.ver_ops = &qcom_edp_phy_ops_v4,
};
@@ -811,7 +849,8 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v6 = {
static struct qcom_edp_phy_cfg x1e80100_phy_cfg = {
.aux_cfg = edp_phy_aux_cfg_v4,
.vco_div_cfg = edp_phy_vco_div_cfg_v4,
- .swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
+ .dp_swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
+ .edp_swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
.ver_ops = &qcom_edp_phy_ops_v6,
};
@@ -991,7 +1030,8 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v8 = {
static struct qcom_edp_phy_cfg glymur_phy_cfg = {
.aux_cfg = edp_phy_aux_cfg_v8,
.vco_div_cfg = edp_phy_vco_div_cfg_v8,
- .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
+ .dp_swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg_v8,
+ .edp_swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg,
.ver_ops = &qcom_edp_phy_ops_v8,
};
--
2.43.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH 2/3] phy: qcom: edp: Add per-version LDO configuration callback
From: Yongxing Mou @ 2026-02-05 9:20 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong
Cc: linux-arm-msm, linux-phy, linux-kernel, Yongxing Mou
In-Reply-To: <20260205-edp_phy-v1-0-231882bbf3f1@oss.qualcomm.com>
Introduce the com_ldo_config callback to support per‑PHY LDO
configuration.
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-edp.c | 86 ++++++++++++++++++++++++++++++++-----
1 file changed, 76 insertions(+), 10 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
index 10cbb7d9a8a0..388226dbad7f 100644
--- a/drivers/phy/qualcomm/phy-qcom-edp.c
+++ b/drivers/phy/qualcomm/phy-qcom-edp.c
@@ -81,6 +81,7 @@ struct phy_ver_ops {
int (*com_clk_fwd_cfg)(const struct qcom_edp *edp);
int (*com_configure_pll)(const struct qcom_edp *edp);
int (*com_configure_ssc)(const struct qcom_edp *edp);
+ int (*com_ldo_config)(const struct qcom_edp *edp);
};
struct qcom_edp_phy_cfg {
@@ -273,7 +274,7 @@ static int qcom_edp_set_voltages(struct qcom_edp *edp, const struct phy_configur
const struct qcom_edp_swing_pre_emph_cfg *cfg = edp->cfg->swing_pre_emph_cfg;
unsigned int v_level = 0;
unsigned int p_level = 0;
- u8 ldo_config;
+ int ret;
u8 swing;
u8 emph;
int i;
@@ -300,13 +301,13 @@ static int qcom_edp_set_voltages(struct qcom_edp *edp, const struct phy_configur
if (swing == 0xff || emph == 0xff)
return -EINVAL;
- ldo_config = edp->is_edp ? 0x0 : 0x1;
+ ret = edp->cfg->ver_ops->com_ldo_config(edp);
+ if (ret)
+ return ret;
- writel(ldo_config, edp->tx0 + TXn_LDO_CONFIG);
writel(swing, edp->tx0 + TXn_TX_DRV_LVL);
writel(emph, edp->tx0 + TXn_TX_EMP_POST1_LVL);
- writel(ldo_config, edp->tx1 + TXn_LDO_CONFIG);
writel(swing, edp->tx1 + TXn_TX_DRV_LVL);
writel(emph, edp->tx1 + TXn_TX_EMP_POST1_LVL);
@@ -530,6 +531,52 @@ static int qcom_edp_com_configure_pll_v4(const struct qcom_edp *edp)
return 0;
}
+static int qcom_edp_ldo_config_v3(const struct qcom_edp *edp)
+{
+ const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
+ u32 ldo_config;
+
+ if (!edp->is_edp)
+ ldo_config = 0x0;
+ else if (dp_opts->link_rate <= 2700)
+ ldo_config = 0x81;
+ else
+ ldo_config = 0x41;
+
+ writel(ldo_config, edp->tx0 + TXn_LDO_CONFIG);
+ writel(ldo_config, edp->tx1 + TXn_LDO_CONFIG);
+
+ return 0;
+}
+
+static int qcom_edp_ldo_config_v4(const struct qcom_edp *edp)
+{
+ const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
+ u32 ldo_config;
+
+ if (!edp->is_edp)
+ ldo_config = 0x0;
+ else if (dp_opts->link_rate <= 2700)
+ ldo_config = 0xC1;
+ else
+ ldo_config = 0x81;
+
+ writel(ldo_config, edp->tx0 + TXn_LDO_CONFIG);
+ writel(ldo_config, edp->tx1 + TXn_LDO_CONFIG);
+
+ return 0;
+}
+
+static const struct phy_ver_ops qcom_edp_phy_ops_v3 = {
+ .com_power_on = qcom_edp_phy_power_on_v4,
+ .com_resetsm_cntrl = qcom_edp_phy_com_resetsm_cntrl_v4,
+ .com_bias_en_clkbuflr = qcom_edp_com_bias_en_clkbuflr_v4,
+ .com_clk_fwd_cfg = qcom_edp_com_clk_fwd_cfg_v4,
+ .com_configure_pll = qcom_edp_com_configure_pll_v4,
+ .com_configure_ssc = qcom_edp_com_configure_ssc_v4,
+ .com_ldo_config = qcom_edp_ldo_config_v3,
+};
+
static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
.com_power_on = qcom_edp_phy_power_on_v4,
.com_resetsm_cntrl = qcom_edp_phy_com_resetsm_cntrl_v4,
@@ -537,6 +584,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
.com_clk_fwd_cfg = qcom_edp_com_clk_fwd_cfg_v4,
.com_configure_pll = qcom_edp_com_configure_pll_v4,
.com_configure_ssc = qcom_edp_com_configure_ssc_v4,
+ .com_ldo_config = qcom_edp_ldo_config_v4,
};
static const struct qcom_edp_phy_cfg sa8775p_dp_phy_cfg = {
@@ -550,7 +598,7 @@ static const struct qcom_edp_phy_cfg sa8775p_dp_phy_cfg = {
static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
.aux_cfg = edp_phy_aux_cfg_v4,
.vco_div_cfg = edp_phy_vco_div_cfg_v4,
- .ver_ops = &qcom_edp_phy_ops_v4,
+ .ver_ops = &qcom_edp_phy_ops_v3,
};
static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = {
@@ -733,12 +781,31 @@ static int qcom_edp_com_configure_pll_v6(const struct qcom_edp *edp)
return 0;
}
+static int qcom_edp_ldo_config_v6(const struct qcom_edp *edp)
+{
+ const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
+ u32 ldo_config;
+
+ if (!edp->is_edp)
+ ldo_config = 0x0;
+ else if (dp_opts->link_rate <= 2700)
+ ldo_config = 0x51;
+ else
+ ldo_config = 0x91;
+
+ writel(ldo_config, edp->tx0 + TXn_LDO_CONFIG);
+ writel(ldo_config, edp->tx1 + TXn_LDO_CONFIG);
+
+ return 0;
+}
+
static const struct phy_ver_ops qcom_edp_phy_ops_v6 = {
.com_power_on = qcom_edp_phy_power_on_v6,
.com_resetsm_cntrl = qcom_edp_phy_com_resetsm_cntrl_v6,
.com_bias_en_clkbuflr = qcom_edp_com_bias_en_clkbuflr_v6,
.com_configure_pll = qcom_edp_com_configure_pll_v6,
.com_configure_ssc = qcom_edp_com_configure_ssc_v6,
+ .com_ldo_config = qcom_edp_ldo_config_v6,
};
static struct qcom_edp_phy_cfg x1e80100_phy_cfg = {
@@ -918,6 +985,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v8 = {
.com_clk_fwd_cfg = qcom_edp_com_clk_fwd_cfg_v8,
.com_configure_pll = qcom_edp_com_configure_pll_v8,
.com_configure_ssc = qcom_edp_com_configure_ssc_v8,
+ .com_ldo_config = qcom_edp_ldo_config_v6,
};
static struct qcom_edp_phy_cfg glymur_phy_cfg = {
@@ -932,7 +1000,6 @@ static int qcom_edp_phy_power_on(struct phy *phy)
const struct qcom_edp *edp = phy_get_drvdata(phy);
u32 bias0_en, drvr0_en, bias1_en, drvr1_en;
unsigned long pixel_freq;
- u8 ldo_config = 0x0;
int ret;
u32 val;
u8 cfg1;
@@ -941,11 +1008,10 @@ static int qcom_edp_phy_power_on(struct phy *phy)
if (ret)
return ret;
- if (edp->cfg->swing_pre_emph_cfg && !edp->is_edp)
- ldo_config = 0x1;
+ ret = edp->cfg->ver_ops->com_ldo_config(edp);
+ if (ret)
+ return ret;
- writel(ldo_config, edp->tx0 + TXn_LDO_CONFIG);
- writel(ldo_config, edp->tx1 + TXn_LDO_CONFIG);
writel(0x00, edp->tx0 + TXn_LANE_MODE_1);
writel(0x00, edp->tx1 + TXn_LANE_MODE_1);
--
2.43.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* Re: [PATCH 6/8] mmc: host: axiado: add AX3000 eMMC PHY support to sdhci-of-arasan
From: Krzysztof Kozlowski @ 2026-02-05 9:47 UTC (permalink / raw)
To: Tzu-Hao Wei
Cc: SriNavmani A, Prasad Bolisetty, Vinod Koul, Neil Armstrong,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Harshit Shah,
Ulf Hansson, Adrian Hunter, Michal Simek, linux-phy, devicetree,
linux-arm-kernel, linux-kernel, linux-mmc
In-Reply-To: <c96d21ab-2a76-46ca-8392-6edde3b9ce2d@axiado.com>
On 05/02/2026 04:36, Tzu-Hao Wei wrote:
> On 12/23/2025 10:34 PM, Krzysztof Kozlowski wrote:
>>> @@ -2019,15 +2023,17 @@ static int sdhci_arasan_probe(struct platform_device *pdev)
>>> goto unreg_clk;
>>> }
>>>
>>> - host->mmc_host_ops.hs400_enhanced_strobe =
>>> + if (!of_device_is_compatible(np, "axiado,ax3000-sdhci-5.1-emmc")) {
>>
>> No, don't sprinkle compatibles all around. You should use driver match
>> data for this.
>>
>> Best regards,
>> Krzysztof
>>
> Thanks for suggestion. The new patch uses driver match data instead of sprinkling compatibles.
You replied to a review from more than a month ago, even though I gave
you review after one day. I don't have anything of this in my inbox, so
in case you asked of something - I still expect all feedback to be
implemented.
Best regards,
Krzysztof
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH] phy: intel: phy-intel-lgm-combo: Add missing boot trigger
From: Florian Eckert @ 2026-02-05 12:02 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Dilip Kota
Cc: linux-phy, linux-kernel, Florian Eckert, Florian Eckert
In the current implementation, the PHY firmware is not started on the LGM.
The PCIe RC cannot establish a connection to the PCIe EP via LTSSM, because
the PCIe RC on the PHY is never started. Setting the bit 1 in the
PCIE_PHY_SRAM_CSR app register boots the PHY firmware.
This changes are based on patched kernel sources of the MaxLinear SDK,
which can be found at https://github.com/maxlinear/linux
Signed-off-by: Florian Eckert <fe@dev.tdt.de>
---
drivers/phy/intel/phy-intel-lgm-combo.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/phy/intel/phy-intel-lgm-combo.c b/drivers/phy/intel/phy-intel-lgm-combo.c
index 9ee3cf61cdd00439f6a9b76c715aec0fa95c8a15..61690d418a5632d4b0c685116a443edba1fe8363 100644
--- a/drivers/phy/intel/phy-intel-lgm-combo.c
+++ b/drivers/phy/intel/phy-intel-lgm-combo.c
@@ -24,6 +24,9 @@
#define PAD_DIS_CFG 0x174
+#define PCIE_PHY_SRAM_CSR 0x08
+#define PCIE_PHY_SRAM_LD_DONE BIT(1)
+
#define PCS_XF_ATE_OVRD_IN_2 0x3008
#define ADAPT_REQ_MSK GENMASK(5, 4)
@@ -345,6 +348,16 @@ static int intel_cbphy_init(struct phy *phy)
cbphy->init_cnt++;
+ combo_phy_w32_off_mask(cbphy->app_base, PCIE_PHY_SRAM_CSR,
+ PCIE_PHY_SRAM_LD_DONE,
+ FIELD_PREP(PCIE_PHY_SRAM_LD_DONE, 1));
+
+ mutex_unlock(&cbphy->lock);
+
+ /* 15ms is required for the FW to take effect after load */
+ mdelay(15);
+ return 0;
+
err:
mutex_unlock(&cbphy->lock);
---
base-commit: 18f7fcd5e69a04df57b563360b88be72471d6b62
change-id: 20260205-phy-intel-lgm-combo-d79252514393
Best regards,
--
Florian Eckert <fe@dev.tdt.de>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* Re: [PATCH v9 1/2] dt-bindings: phy: eswin: Document the EIC7700 SoC SATA PHY
From: Krzysztof Kozlowski @ 2026-02-05 13:41 UTC (permalink / raw)
To: Yulin Lu
Cc: vkoul, neil.armstrong, robh, krzk+dt, conor+dt, p.zabel,
linux-phy, devicetree, linux-kernel, ningyu, linmin, fenglin
In-Reply-To: <20260205082129.1482-1-luyulin@eswincomputing.com>
On Thu, Feb 05, 2026 at 04:21:29PM +0800, Yulin Lu wrote:
> Document the SATA PHY on the EIC7700 SoC platform,
> describing its usage.
>
> Signed-off-by: Yulin Lu <luyulin@eswincomputing.com>
> ---
> .../bindings/phy/eswin,eic7700-sata-phy.yaml | 92 +++++++++++++++++++
> 1 file changed, 92 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Best regards,
Krzysztof
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH net-next] doc: generic phy: update generic PHY documentation
From: Russell King (Oracle) @ 2026-02-05 14:56 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong; +Cc: Jonathan Corbet, linux-doc, linux-phy
Update the generic PHY documentation as a result of the discussion for
the s32g submission.
Link: https://lore.kernel.org/r/aXtvDn_-pCuKPrnf@vaman
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
I didn't get any replies to my follow-up question to Vinod:
Please also indicate in the documentation whether changing the submode
of the serdes (particularly for ethernet) is permitted without doing a
phy_power_down()..phy_power_up() dance around the phy_set_mode_ext()
call.
I also didn't get any response to:
For drivers such as stmmac, it will be important that details such as
whether phy_est_mode*() can be called with the PHY powered on are
riveted down and not left up to the generic PHY driver author - without
that, generic PHYs basically aren't usable from SoC/platform
independent code, and stmmac has bazillions of platform specific glue
already because of (a) bad code structuring and (b) lack of
generalisation through standardised interfaces that abstract platform
differences.
I want to be able for core stmmac code, or even phylink code (which
is even more platform generic) to be able to make use of generic PHY
stuff, but if the calls that can be made into generic PHY are platform
dependent, that is a blocking issue against that, and makes me question
why we have the generic PHY subsystem... it's not very generic if it
exposes the differences of each implementation to users of its
interfaces.
Documentation/driver-api/phy/phy.rst | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Documentation/driver-api/phy/phy.rst b/Documentation/driver-api/phy/phy.rst
index 719a2b3fd2ab..cf73e4fb0951 100644
--- a/Documentation/driver-api/phy/phy.rst
+++ b/Documentation/driver-api/phy/phy.rst
@@ -142,6 +142,7 @@ Order of API calls
[devm_][of_]phy_get()
phy_init()
+ [phy_set_mode[_ext]()]
phy_power_on()
[phy_set_mode[_ext]()]
...
@@ -154,7 +155,7 @@ but controllers should always call these functions to be compatible with other
PHYs. Some PHYs may require :c:func:`phy_set_mode <phy_set_mode_ext>`, while
others may use a default mode (typically configured via devicetree or other
firmware). For compatibility, you should always call this function if you know
-what mode you will be using. Generally, this function should be called after
+what mode you will be using. Generally, this function should be called before
:c:func:`phy_power_on`, although some PHY drivers may allow it at any time.
Releasing a reference to the PHY
--
2.47.3
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* Re: [PATCH 1/8] dt-bindings: pci: xilinx-nwl: Add resets
From: Sean Anderson @ 2026-02-05 15:47 UTC (permalink / raw)
To: Pandey, Radhey Shyam, Laurent Pinchart, Vinod Koul,
linux-phy@lists.infradead.org
Cc: Krzysztof Wilczyński, Lorenzo Pieralisi,
linux-kernel@vger.kernel.org, Simek, Michal,
linux-arm-kernel@lists.infradead.org, linux-pci@vger.kernel.org,
Neil Armstrong, Rob Herring, Havalige, Thippeswamy,
Manivannan Sadhasivam, Bjorn Helgaas, Conor Dooley,
Krzysztof Kozlowski, devicetree@vger.kernel.org
In-Reply-To: <MN0PR12MB59537BC8B60D76CCE0B1391CB798A@MN0PR12MB5953.namprd12.prod.outlook.com>
On 2/4/26 03:32, Pandey, Radhey Shyam wrote:
> [AMD Official Use Only - AMD Internal Distribution Only]
>
>> -----Original Message-----
>> From: Sean Anderson <sean.anderson@linux.dev>
>> Sent: Tuesday, February 3, 2026 5:51 AM
>> To: Laurent Pinchart <laurent.pinchart@ideasonboard.com>; Vinod Koul
>> <vkoul@kernel.org>; linux-phy@lists.infradead.org
>> Cc: Krzysztof Wilczyński <kwilczynski@kernel.org>; Lorenzo Pieralisi
>> <lpieralisi@kernel.org>; Pandey, Radhey Shyam
>> <radhey.shyam.pandey@amd.com>; linux-kernel@vger.kernel.org; Simek, Michal
>> <michal.simek@amd.com>; linux-arm-kernel@lists.infradead.org; linux-
>> pci@vger.kernel.org; Neil Armstrong <neil.armstrong@linaro.org>; Rob Herring
>> <robh@kernel.org>; Havalige, Thippeswamy <thippeswamy.havalige@amd.com>;
>> Manivannan Sadhasivam <mani@kernel.org>; Bjorn Helgaas
>> <bhelgaas@google.com>; Sean Anderson <sean.anderson@linux.dev>; Conor
>> Dooley <conor+dt@kernel.org>; Krzysztof Kozlowski <krzk+dt@kernel.org>;
>> devicetree@vger.kernel.org
>> Subject: [PATCH 1/8] dt-bindings: pci: xilinx-nwl: Add resets
>>
>> Add resets so we can hold the bridge in reset while we perform phy calibration.
>
> Seems like this should a required property?
It's optional as it does not exist in previous versions of the
devicetree. In the past I have received pushback against making these
sort of properties required.
If the resets don't exist we just don't assert them and assume the
bootloader has deasserted them.
--Sean
> Rest looks fine to me.
>
>>
>> Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
>> ---
>>
>> .../devicetree/bindings/pci/xlnx,nwl-pcie.yaml | 17 +++++++++++++++++
>> 1 file changed, 17 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/pci/xlnx,nwl-pcie.yaml
>> b/Documentation/devicetree/bindings/pci/xlnx,nwl-pcie.yaml
>> index 9de3c09efb6e..7efb3dd9955f 100644
>> --- a/Documentation/devicetree/bindings/pci/xlnx,nwl-pcie.yaml
>> +++ b/Documentation/devicetree/bindings/pci/xlnx,nwl-pcie.yaml
>> @@ -69,6 +69,18 @@ properties:
>> power-domains:
>> maxItems: 1
>>
>> + resets:
>> + maxItems: 3
>> +
>> + reset-names:
>> + items:
>> + - description: APB register block reset
>> + const: cfg
>> + - description: AXI-PCIe bridge reset
>> + const: bridge
>> + - description: PCIe MAC reset
>> + const: ctrl
>> +
>> iommus:
>> maxItems: 1
>>
>> @@ -117,6 +129,7 @@ examples:
>> #include <dt-bindings/interrupt-controller/irq.h>
>> #include <dt-bindings/phy/phy.h>
>> #include <dt-bindings/power/xlnx-zynqmp-power.h>
>> + #include <dt-bindings/reset/xlnx-zynqmp-resets.h>
>> soc {
>> #address-cells = <2>;
>> #size-cells = <2>;
>> @@ -146,6 +159,10 @@ examples:
>> msi-parent = <&nwl_pcie>;
>> phys = <&psgtr 0 PHY_TYPE_PCIE 0 0>;
>> power-domains = <&zynqmp_firmware PD_PCIE>;
>> + resets = <&zynqmp_reset ZYNQMP_RESET_PCIE_CFG>,
>> + <&zynqmp_reset ZYNQMP_RESET_PCIE_BRIDGE>,
>> + <&zynqmp_reset ZYNQMP_RESET_PCIE_CTRL>;
>> + reset-names = "cfg", "bridge", "ctrl";
>> iommus = <&smmu 0x4d0>;
>> pcie_intc: legacy-interrupt-controller {
>> interrupt-controller;
>> --
>> 2.35.1.1320.gc452695387.dirty
>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v2 2/6] phy: qcom: qmp-usbc: Fix possible NULL-deref on early runtime suspend
From: Loic Poulain @ 2026-02-05 15:57 UTC (permalink / raw)
To: Konrad Dybcio
Cc: vkoul, kishon, linux-arm-msm, linux-phy, dmitry.baryshkov,
neil.armstrong
In-Reply-To: <3facbb23-80ad-4648-b81c-73f4608129f5@oss.qualcomm.com>
On Thu, Jan 22, 2026 at 4:00 PM Konrad Dybcio
<konrad.dybcio@oss.qualcomm.com> wrote:
>
> On 1/21/26 3:28 PM, Loic Poulain wrote:
> > There is a small window where the runtime suspend callback may run
> > after pm_runtime_enable() and before pm_runtime_forbid(). In this
> > case, a crash occurs because runtime suspend/resume dereferences
> > qmp->phy pointer, which is not yet initialized:
> > `if (!qmp->phy->init_count) {`
> >
> > This can also occur if user re-enables runtime-pm via the sysfs
> > attribute before qmp phy is initialized.
> >
> > Use qmp->usb_init_count instead of qmp->phy->init_count to avoid
> > depending on the possibly uninitialized phy pointer.
> >
> > Fixes: 19281571a4d5 ("phy: qcom: qmp-usb: split USB-C PHY driver")
> > Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
> > ---
> > drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> > index 5e7fcb26744a..edfaa14db967 100644
> > --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> > @@ -690,7 +690,7 @@ static int __maybe_unused qmp_usbc_runtime_suspend(struct device *dev)
> >
> > dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode);
> >
> > - if (!qmp->phy->init_count) {
> > + if (!qmp->usb_init_count) {
>
> This function changed a month ago, please rebase against next
>
> Although I believe this patch becomes unnecessary with 3 in the picture.
Thanks. I can indeed remove this patch from the series
> I suppose the case that you mention in the commit message, however
> improbable, could be fixed by moving the pm call to after devm_phy_create
For whatever scheduling effect, this behavior has been seen quite
regularly (~1/50 boots) during stress‑test scenarios with other PHY
driver (qcom-qusb2).
As Dmitry noted earlier, PM must be enabled before calling
devm_phy_create(), because phy_create() relies on the PM‑enabled state
to configure its own runtime PM behavior.
>
> Although we'd then rely on devlink to make sure a consumer doesn't snatch
> the reference halfway through .probe...
>
> Konrad
Cheers,
Loic
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v3 2/5] phy: qcom: qmp-usbc: Prevent unnecessary PM runtime suspend at boot
From: Loic Poulain @ 2026-02-05 16:02 UTC (permalink / raw)
To: vkoul, kishon
Cc: linux-arm-msm, linux-phy, dmitry.baryshkov, neil.armstrong,
konrad.dybcio, Loic Poulain, Abel Vesa
In-Reply-To: <20260205160240.748371-1-loic.poulain@oss.qualcomm.com>
There is a small window where the device can suspend after
pm_runtime_enable() and before pm_runtime_forbid(), causing an
unnecessary suspend/resume cycle while the PHY is not yet registered.
Move pm_runtime_forbid() before pm_runtime_enable() to eliminate
this race.
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
index 14feb77789b3..90ea6ca64026 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
@@ -1959,15 +1959,15 @@ static int qmp_usbc_probe(struct platform_device *pdev)
if (ret)
goto err_node_put;
+ /*
+ * Enable runtime PM support, but forbid it by default.
+ * Users can allow it again via the power/control attribute in sysfs.
+ */
pm_runtime_set_active(dev);
+ pm_runtime_forbid(dev);
ret = devm_pm_runtime_enable(dev);
if (ret)
goto err_node_put;
- /*
- * Prevent runtime pm from being ON by default. Users can enable
- * it using power/control in sysfs.
- */
- pm_runtime_forbid(dev);
ret = qmp_usbc_register_clocks(qmp, np);
if (ret)
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v3 1/5] phy: qcom: qmp-combo: Prevent unnecessary PM runtime suspend at boot
From: Loic Poulain @ 2026-02-05 16:02 UTC (permalink / raw)
To: vkoul, kishon
Cc: linux-arm-msm, linux-phy, dmitry.baryshkov, neil.armstrong,
konrad.dybcio, Loic Poulain, Abel Vesa
In-Reply-To: <20260205160240.748371-1-loic.poulain@oss.qualcomm.com>
There is a small window where the device can suspend after
pm_runtime_enable() and before pm_runtime_forbid(), causing an
unnecessary suspend/resume cycle while the PHY is not yet registered.
Move pm_runtime_forbid() before pm_runtime_enable() to eliminate
this race.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
index 93f1aa10d400..c3661872bb7a 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
@@ -4932,15 +4932,15 @@ static int qmp_combo_probe(struct platform_device *pdev)
if (ret)
goto err_node_put;
+ /*
+ * Enable runtime PM support, but forbid it by default.
+ * Users can allow it again via the power/control attribute in sysfs.
+ */
pm_runtime_set_active(dev);
+ pm_runtime_forbid(dev);
ret = devm_pm_runtime_enable(dev);
if (ret)
goto err_node_put;
- /*
- * Prevent runtime pm from being ON by default. Users can enable
- * it using power/control in sysfs.
- */
- pm_runtime_forbid(dev);
ret = qmp_combo_register_clocks(qmp, usb_np, dp_np);
if (ret)
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v3 3/5] phy: qcom: qmp-usb-legacy: Fix possible NULL-deref on early runtime suspend
From: Loic Poulain @ 2026-02-05 16:02 UTC (permalink / raw)
To: vkoul, kishon
Cc: linux-arm-msm, linux-phy, dmitry.baryshkov, neil.armstrong,
konrad.dybcio, Loic Poulain, Abel Vesa
In-Reply-To: <20260205160240.748371-1-loic.poulain@oss.qualcomm.com>
There is a small window where the runtime suspend callback may run
after pm_runtime_enable() and before pm_runtime_forbid(). In this
case, a crash occurs because runtime suspend/resume dereferences
qmp->phy pointer, which is not yet initialized:
`if (!qmp->phy->init_count) {`
This can also happen if user re-enables runtime-pm via the sysfs
attribute before qmp phy is initialized.
Similarly to other qcom phy drivers, introduce a qmp->phy_initialized
variable that can be used to avoid relying on the possibly uninitialized
phy pointer.
Fixes: e464a3180a43 ("phy: qcom-qmp-usb: split off the legacy USB+dp_com support")
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
index 8bf951b0490c..258e0e966a02 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
@@ -541,6 +541,7 @@ struct qmp_usb {
struct regulator_bulk_data *vregs;
enum phy_mode mode;
+ bool phy_initialized;
struct phy *phy;
@@ -895,6 +896,7 @@ static int qmp_usb_legacy_power_off(struct phy *phy)
static int qmp_usb_legacy_enable(struct phy *phy)
{
+ struct qmp_usb *qmp = phy_get_drvdata(phy);
int ret;
ret = qmp_usb_legacy_init(phy);
@@ -904,14 +906,19 @@ static int qmp_usb_legacy_enable(struct phy *phy)
ret = qmp_usb_legacy_power_on(phy);
if (ret)
qmp_usb_legacy_exit(phy);
+ else
+ qmp->phy_initialized = true;
return ret;
}
static int qmp_usb_legacy_disable(struct phy *phy)
{
+ struct qmp_usb *qmp = phy_get_drvdata(phy);
int ret;
+ qmp->phy_initialized = false;
+
ret = qmp_usb_legacy_power_off(phy);
if (ret)
return ret;
@@ -988,7 +995,7 @@ static int __maybe_unused qmp_usb_legacy_runtime_suspend(struct device *dev)
dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode);
- if (!qmp->phy->init_count) {
+ if (!qmp->phy_initialized) {
dev_vdbg(dev, "PHY not initialized, bailing out\n");
return 0;
}
@@ -1009,7 +1016,7 @@ static int __maybe_unused qmp_usb_legacy_runtime_resume(struct device *dev)
dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode);
- if (!qmp->phy->init_count) {
+ if (!qmp->phy_initialized) {
dev_vdbg(dev, "PHY not initialized, bailing out\n");
return 0;
}
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v3 4/5] phy: qcom: qmp-usb-legacy: Prevent unnecessary PM runtime suspend at boot
From: Loic Poulain @ 2026-02-05 16:02 UTC (permalink / raw)
To: vkoul, kishon
Cc: linux-arm-msm, linux-phy, dmitry.baryshkov, neil.armstrong,
konrad.dybcio, Loic Poulain, Abel Vesa
In-Reply-To: <20260205160240.748371-1-loic.poulain@oss.qualcomm.com>
There is a small window where the device can suspend after
pm_runtime_enable() and before pm_runtime_forbid(), causing an
unnecessary suspend/resume cycle while the PHY is not yet registered.
Move pm_runtime_forbid() before pm_runtime_enable() to eliminate
this race.
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
index 258e0e966a02..73439d223f1d 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
@@ -1284,15 +1284,15 @@ static int qmp_usb_legacy_probe(struct platform_device *pdev)
if (ret)
goto err_node_put;
+ /*
+ * Enable runtime PM support, but forbid it by default.
+ * Users can allow it again via the power/control attribute in sysfs.
+ */
pm_runtime_set_active(dev);
+ pm_runtime_forbid(dev);
ret = devm_pm_runtime_enable(dev);
if (ret)
goto err_node_put;
- /*
- * Prevent runtime pm from being ON by default. Users can enable
- * it using power/control in sysfs.
- */
- pm_runtime_forbid(dev);
ret = phy_pipe_clk_register(qmp, np);
if (ret)
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v3 0/5] phy: qcom: Fix possible NULL-deref and runtime PM race conditions
From: Loic Poulain @ 2026-02-05 16:02 UTC (permalink / raw)
To: vkoul, kishon
Cc: linux-arm-msm, linux-phy, dmitry.baryshkov, neil.armstrong,
konrad.dybcio, Loic Poulain
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 1532 bytes --]
Address potential NULL pointer dereferences and race conditions related
to runtime PM in several Qualcomm PHY drivers. In all cases, enabling
runtime PM before the PHY instance is fully initialized can lead to
crashes during early runtime suspend callbacks.
- Attach driver data before enabling runtime PM.
- Introduce initialization flags where needed to avoid dereferencing
uninitialized pointers.
- Reorder pm_runtime_enable() and pm_runtime_forbid() calls to prevent
unnecessary suspend/resume cycles during driver probe.
- Use devres-managed PM runtime helpers for proper cleanup.
Changes in V3:
Rebase on next and remove 2/6 (obsolete)
Changes in V2:
Split patches 2/4 and 3/4 so that the null‑pointer dereference fix and
the runtime‑PM enable/forbid reordering are logically separated.
Loic Poulain (5):
phy: qcom: qmp-combo: Prevent unnecessary PM runtime suspend at boot
phy: qcom: qmp-usbc: Prevent unnecessary PM runtime suspend at boot
phy: qcom: qmp-usb-legacy: Fix possible NULL-deref on early runtime
suspend
phy: qcom: qmp-usb-legacy: Prevent unnecessary PM runtime suspend at
boot
phy: qcom: snps-femto-v2: Fix possible NULL-deref on early runtime
suspend
drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 10 ++++-----
.../phy/qualcomm/phy-qcom-qmp-usb-legacy.c | 21 ++++++++++++-------
drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 10 ++++-----
drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c | 15 ++++++-------
4 files changed, 32 insertions(+), 24 deletions(-)
--
2.34.1
[-- Attachment #2: Type: text/plain, Size: 112 bytes --]
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v3 5/5] phy: qcom: snps-femto-v2: Fix possible NULL-deref on early runtime suspend
From: Loic Poulain @ 2026-02-05 16:02 UTC (permalink / raw)
To: vkoul, kishon
Cc: linux-arm-msm, linux-phy, dmitry.baryshkov, neil.armstrong,
konrad.dybcio, Loic Poulain, Abel Vesa
In-Reply-To: <20260205160240.748371-1-loic.poulain@oss.qualcomm.com>
Enabling runtime PM before attaching the hsphy instance as driver data
can lead to a NULL pointer dereference in runtime PM callbacks that
expect valid driver data. There is a small window where the suspend
callback may run after PM runtime enabling and before runtime forbid.
Attach the hsphy instance as driver data before enabling runtime PM to
prevent NULL pointer dereference in runtime PM callbacks.
Reorder pm_runtime_enable() and pm_runtime_forbid() to prevent a
short window where an unnecessary runtime suspend can occur.
Use the devres-managed version to ensure PM runtime is symmetrically
disabled during driver removal for proper cleanup.
Fixes: 0d75f508a9d5 ("phy: qcom-snps: Add runtime suspend and resume handlers")
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
index eb0b0f61d98e..d1288a6c202e 100644
--- a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
+++ b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c
@@ -599,13 +599,17 @@ static int qcom_snps_hsphy_probe(struct platform_device *pdev)
return dev_err_probe(dev, ret,
"failed to get regulator supplies\n");
- pm_runtime_set_active(dev);
- pm_runtime_enable(dev);
+ dev_set_drvdata(dev, hsphy);
+
/*
- * Prevent runtime pm from being ON by default. Users can enable
- * it using power/control in sysfs.
+ * Enable runtime PM support, but forbid it by default.
+ * Users can allow it again via the power/control attribute in sysfs.
*/
+ pm_runtime_set_active(dev);
pm_runtime_forbid(dev);
+ ret = devm_pm_runtime_enable(dev);
+ if (ret)
+ return ret;
generic_phy = devm_phy_create(dev, NULL, &qcom_snps_hsphy_gen_ops);
if (IS_ERR(generic_phy)) {
@@ -615,15 +619,12 @@ static int qcom_snps_hsphy_probe(struct platform_device *pdev)
}
hsphy->phy = generic_phy;
- dev_set_drvdata(dev, hsphy);
phy_set_drvdata(generic_phy, hsphy);
qcom_snps_hsphy_read_override_param_seq(dev);
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
if (!IS_ERR(phy_provider))
dev_dbg(dev, "Registered Qcom-SNPS HS phy\n");
- else
- pm_runtime_disable(dev);
return PTR_ERR_OR_ZERO(phy_provider);
}
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox