From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5964BCD6E75 for ; Fri, 5 Jun 2026 01:00:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=PXOGCojLUBGZIqNUtQ7tDvedemfOzrCuti6WoAljgjQ=; b=yJTeEceTDIjQtIVjj6BliBF/w1 QSRn9hQ6bPe3FVf6i2FZTKyGTCgNIR/H9vhNFO9Q351V6dZCk4Ktg3oZJ2On0s52beW5pOsRZeSAV 5qDSFj02Il/Fsi93HDKMYoKx/+AGZiwUlPFjRKdWiVn+eDXRyV4JNNgX4HMYt5NY0Qay18ng69k6F LMa54/DR3xARUuUhkvIIvjvW6esVbRvyGgKl8QUwnUsAGCWerw+n3ByrAXdjHkgUl+paJ0pNcKe0m wbRyNHFIDarrbnM+ja5sx4ZK8CzpqR27QQB1dmRN56C96Y294w6hpzIPsc/m+hQZ+e5Px+JbzZwWM vSDRFe8g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1wVIvQ-0000000HTcR-3kab; Fri, 05 Jun 2026 01:00:40 +0000 Received: from mail-oi1-x22b.google.com ([2607:f8b0:4864:20::22b]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1wVIvO-0000000HTbH-2VhC for linux-arm-kernel@lists.infradead.org; Fri, 05 Jun 2026 01:00:39 +0000 Received: by mail-oi1-x22b.google.com with SMTP id 5614622812f47-48633190849so528646b6e.3 for ; Thu, 04 Jun 2026 18:00:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=riscstar-com.20251104.gappssmtp.com; s=20251104; t=1780621238; x=1781226038; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=PXOGCojLUBGZIqNUtQ7tDvedemfOzrCuti6WoAljgjQ=; b=UFHift8W9l3zk9bzpuB+pqmv8kw0YvpcV7kmsc2hCY5dKUMgmXLJGnOxnIoBZMn2M+ cvrhLA/V34kF8GO4XUcDYQjnoAt61PnX7UP+X7xyJswSntWJi5Rdgxa0Nk35T3kWNk46 nXUD6wDMhsiP78Ki+Tv+T/xFowu61E1WQB/Mj4NjzMzTFP4umPn6HNIULHxV2W3BeaL/ wF6XSj71rtqeD+KwIHnD17+/D1WL9uX9Ayifh9zfbnijWdAF7vB2MZslVMjlCMeCd/aK YC2PgpYVxz/YdcIXEenEY0vieNfLCjpvtd/9d0/AG/U2m4tW4ZRx2KY9TCqwsh5uy8uI qsZw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780621238; x=1781226038; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=PXOGCojLUBGZIqNUtQ7tDvedemfOzrCuti6WoAljgjQ=; b=gPd3P4hfjJypd7UPbIr8JurpLNytHYHMOQlB/2fVJJyJum3SsDYH6ATVexU3fY2Y9o vAcqT+4z5xZ2DlDixSagahDA6rwo99PaaEAejCEQdRQozeFeybXIYIdcBl5R6+4FD2tF AW0OnrHvk0aZaAdX/iFjfJn9wkXwO5FbC9klu5llOXGBrVwMHxy8gBpWkGqpSwMGzBWe QqANhM4+VwRQzyWBBVnLVd5gKF+Nzx9XDnSgOKbo4EIBWfuujTUP8V6NXrLxNS4+uaGL bfvkDU3x5JWqDHEl0WFbh7Eut01d3jrxtlxqrnvr1bAC6Mja0tR3ks7/MH9aNdBsReSK JD/A== X-Forwarded-Encrypted: i=1; AFNElJ9WFQqq0IDgRGeiu0MIYykYsxs05EUKxcUzDqzNcCrU/g9xOMzm4re9FyjV9Go6ZjANzfIBW4C7VLvE/LjSb2ab@lists.infradead.org X-Gm-Message-State: AOJu0YzyPWC46Ep2+rg+pNpYA5a9/pigrqw1jZdVdhQiayGRo+0VS4tO S62egk+4p5+GeGWg8a0KyAxEL8Du82B5a+/SI3D7ytpcUU6wyhMq2zXetGCU09T7y7w= X-Gm-Gg: Acq92OFQrOkB5dbkT9h3eDhV7zbKoi1OQV4hWdg+W4hSrjdy2iOQlHMRC/7DlQAutcu Iv7B3R3OpJQwdsUxjLokB0cJp0yoqdJOZ5K4bF08D+q+pozv79iK5Wxsm45xQMKx4PXLyJWG6kY 9ZuQLjtR5aS1vpgxoQgrYtyVPTyRXTkRAsMxHcNTcpliMbMQ8biObFeFYOZkC2pCPJE8EbJ1O1u qfx1UDT7n558Pt6fOLMtvW+kZw7BhokR1gF7Svh3Bcqw+5IcyMSG4+StXruoeakbJRJ94h/5vz6 N2emS1Iqc16wr6lgsoKoFOYlT3ubhWDTZQV1HVVhLbcsA8vwRYrpNt5BP2mK0bGFhXEcq3kkG5C f1B15cWipGlvHo8k5l70XkRzV6kBYrWC/+DuBiVSef/r7D4jdunRH2YcI2Yj8246XqI1JrWi2vn /j5vWr7eXrMxSuzzMyJmgD8j3PUiBCXH1AC6Jz9A== X-Received: by 2002:a05:6808:1a0d:b0:486:5275:8144 with SMTP id 5614622812f47-4868dc44e20mr851607b6e.2.1780621237642; Thu, 04 Jun 2026 18:00:37 -0700 (PDT) Received: from zippy.localdomain ([73.62.185.64]) by smtp.gmail.com with ESMTPSA id 5614622812f47-4865b6ec694sm5544631b6e.5.2026.06.04.18.00.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jun 2026 18:00:37 -0700 (PDT) From: Alex Elder To: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, maxime.chevallier@bootlin.com, rmk+kernel@armlinux.org.uk, andersson@kernel.org, konradybcio@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, linusw@kernel.org, brgl@kernel.org, arnd@arndb.de, gregkh@linuxfoundation.org Cc: Daniel Thompson , elder@riscstar.com, mohd.anwar@oss.qualcomm.com, a0987203069@gmail.com, alexandre.torgue@foss.st.com, ast@kernel.org, boon.khai.ng@altera.com, chenchuangyu@xiaomi.com, chenhuacai@kernel.org, daniel@iogearbox.net, hawk@kernel.org, hkallweit1@gmail.com, inochiama@gmail.com, john.fastabend@gmail.com, julianbraha@gmail.com, livelycarpet87@gmail.com, mcoquelin.stm32@gmail.com, me@ziyao.cc, prabhakar.mahadev-lad.rj@bp.renesas.com, richardcochran@gmail.com, rohan.g.thomas@altera.com, sdf@fomichev.me, siyanteng@cqsoftware.com.cn, weishangjuan@eswincomputing.com, wens@kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, linux-gpio@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v2 03/14] net: pcs: pcs-xpcs-regmap: support XPCS memory-mapped MDIO bus via regmap Date: Thu, 4 Jun 2026 20:00:10 -0500 Message-ID: <20260605010022.968612-4-elder@riscstar.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260605010022.968612-1-elder@riscstar.com> References: <20260605010022.968612-1-elder@riscstar.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260604_180038_687357_8A3BD514 X-CRM114-Status: GOOD ( 23.70 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Daniel Thompson In some DesignWare XPCS implementatons the memory-mapped MDIO bus is allocated to a register window that does not align to a page boundary. This makes iomapping the registers problematic. For example the Toshiba TC9564 (a PCIe Ethernet-AVB/TSN bridge) provides an "eMAC" subsystem with the XPCS base address cuddled up to XGMAC registers. Let's introduce helpers to allow the driver that owns the eMAC to register an XPCS using is regmap for the memory-mapped MDIO bus. Signed-off-by: Daniel Thompson Signed-off-by: Alex Elder --- MAINTAINERS | 2 + drivers/net/pcs/Makefile | 4 +- drivers/net/pcs/pcs-xpcs-regmap.c | 219 ++++++++++++++++++++++++++++ include/linux/pcs/pcs-xpcs-regmap.h | 20 +++ 4 files changed, 243 insertions(+), 2 deletions(-) create mode 100644 drivers/net/pcs/pcs-xpcs-regmap.c create mode 100644 include/linux/pcs/pcs-xpcs-regmap.h diff --git a/MAINTAINERS b/MAINTAINERS index eb8cdcc76324f..2aa6ea012c848 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -25931,8 +25931,10 @@ F: drivers/net/ethernet/synopsys/ SYNOPSYS DESIGNWARE ETHERNET XPCS DRIVER L: netdev@vger.kernel.org S: Orphan +F: drivers/net/pcs/pcs-xpcs-regmap.c F: drivers/net/pcs/pcs-xpcs.c F: drivers/net/pcs/pcs-xpcs.h +F include/linux/pcs/pcs-xpcs-regmap.h F: include/linux/pcs/pcs-xpcs.h SYNOPSYS DESIGNWARE HDMI RX CONTROLLER DRIVER diff --git a/drivers/net/pcs/Makefile b/drivers/net/pcs/Makefile index 4f7920618b900..565f1b63fce0b 100644 --- a/drivers/net/pcs/Makefile +++ b/drivers/net/pcs/Makefile @@ -1,8 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 # Makefile for Linux PCS drivers -pcs_xpcs-$(CONFIG_PCS_XPCS) := pcs-xpcs.o pcs-xpcs-plat.o \ - pcs-xpcs-nxp.o pcs-xpcs-wx.o +pcs_xpcs-$(CONFIG_PCS_XPCS) := pcs-xpcs.o pcs-xpcs-nxp.o pcs-xpcs-regmap.o \ + pcs-xpcs-plat.o pcs-xpcs-wx.o obj-$(CONFIG_PCS_XPCS) += pcs_xpcs.o obj-$(CONFIG_PCS_LYNX) += pcs-lynx.o diff --git a/drivers/net/pcs/pcs-xpcs-regmap.c b/drivers/net/pcs/pcs-xpcs-regmap.c new file mode 100644 index 0000000000000..55cd05d09c7db --- /dev/null +++ b/drivers/net/pcs/pcs-xpcs-regmap.c @@ -0,0 +1,219 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Synopsys DesignWare XPCS regmap helpers + * + * Copyright (C) 2026 RISCstar Solutions. + * Copyright (C) 2024 Serge Semin + */ + +#include +#include +#include +#include +#include +#include + +#include "pcs-xpcs.h" + +/* Page select register for the indirect MMIO CSRs access */ +#define DW_VR_CSR_VIEWPORT 0xff + +struct dw_xpcs_regmap { + struct device *dev; + struct mii_bus *bus; + struct regmap *regmap; + bool reg_indir; +}; + +static ptrdiff_t xpcs_regmap_addr_format(int dev, int reg) +{ + return FIELD_PREP(0x1f0000, dev) | FIELD_PREP(0xffff, reg); +} + +static u16 xpcs_regmap_addr_page(ptrdiff_t csr) +{ + return FIELD_GET(0x1fff00, csr); +} + +static ptrdiff_t xpcs_regmap_addr_offset(ptrdiff_t csr) +{ + return FIELD_GET(0xff, csr); +} + +static int xpcs_regmap_read_reg_indirect(struct dw_xpcs_regmap *pxpcs, int dev, + int reg) +{ + ptrdiff_t csr, ofs; + unsigned int val; + u16 page; + int res; + + csr = xpcs_regmap_addr_format(dev, reg); + page = xpcs_regmap_addr_page(csr); + ofs = xpcs_regmap_addr_offset(csr); + + res = regmap_write(pxpcs->regmap, DW_VR_CSR_VIEWPORT, page); + if (res < 0) + return res; + + res = regmap_read(pxpcs->regmap, ofs, &val); + if (res < 0) + return res; + + return val & 0xffff; +} + +static int xpcs_regmap_write_reg_indirect(struct dw_xpcs_regmap *pxpcs, int dev, + int reg, u16 val) +{ + ptrdiff_t csr, ofs; + u16 page; + int res; + + csr = xpcs_regmap_addr_format(dev, reg); + page = xpcs_regmap_addr_page(csr); + ofs = xpcs_regmap_addr_offset(csr); + + res = regmap_write(pxpcs->regmap, DW_VR_CSR_VIEWPORT, page); + if (res < 0) + return res; + + return regmap_write(pxpcs->regmap, ofs, val); +} + +static int xpcs_regmap_read_reg_direct(struct dw_xpcs_regmap *pxpcs, int dev, + int reg) +{ + unsigned int val; + ptrdiff_t csr; + int res; + + csr = xpcs_regmap_addr_format(dev, reg); + res = regmap_read(pxpcs->regmap, csr, &val); + if (res < 0) + return res; + + return val & 0xffff; +} + +static int xpcs_regmap_write_reg_direct(struct dw_xpcs_regmap *pxpcs, int dev, + int reg, u16 val) +{ + ptrdiff_t csr = xpcs_regmap_addr_format(dev, reg); + + return regmap_write(pxpcs->regmap, csr, val); +} + +static int xpcs_regmap_read_c22(struct mii_bus *bus, int addr, int reg) +{ + struct dw_xpcs_regmap *pxpcs = bus->priv; + + if (addr != 0) + return -ENODEV; + + if (pxpcs->reg_indir) + return xpcs_regmap_read_reg_indirect(pxpcs, MDIO_MMD_VEND2, reg); + else + return xpcs_regmap_read_reg_direct(pxpcs, MDIO_MMD_VEND2, reg); +} + +static int xpcs_regmap_write_c22(struct mii_bus *bus, int addr, int reg, u16 val) +{ + struct dw_xpcs_regmap *pxpcs = bus->priv; + + if (addr != 0) + return -ENODEV; + + if (pxpcs->reg_indir) + return xpcs_regmap_write_reg_indirect(pxpcs, MDIO_MMD_VEND2, reg, val); + else + return xpcs_regmap_write_reg_direct(pxpcs, MDIO_MMD_VEND2, reg, val); +} + +static int xpcs_regmap_read_c45(struct mii_bus *bus, int addr, int dev, int reg) +{ + struct dw_xpcs_regmap *pxpcs = bus->priv; + + if (addr != 0) + return -ENODEV; + + if (pxpcs->reg_indir) + return xpcs_regmap_read_reg_indirect(pxpcs, dev, reg); + else + return xpcs_regmap_read_reg_direct(pxpcs, dev, reg); +} + +static int xpcs_regmap_write_c45(struct mii_bus *bus, int addr, int dev, + int reg, u16 val) +{ + struct dw_xpcs_regmap *pxpcs = bus->priv; + + if (addr != 0) + return -ENODEV; + + if (pxpcs->reg_indir) + return xpcs_regmap_write_reg_indirect(pxpcs, dev, reg, val); + else + return xpcs_regmap_write_reg_direct(pxpcs, dev, reg, val); +} + +static void devm_xpcs_regmap_destroy(void *data) +{ + struct dw_xpcs *xpcs = data; + + xpcs_destroy(xpcs); +} + +struct dw_xpcs *devm_xpcs_regmap_register(struct device *dev, + const struct xpcs_regmap_config *config) +{ + static atomic_t id = ATOMIC_INIT(-1); + struct dw_xpcs_regmap *pxpcs; + struct dw_xpcs *xpcs; + int ret; + + pxpcs = devm_kzalloc(dev, sizeof(*pxpcs), GFP_KERNEL); + if (!pxpcs) + return ERR_PTR(-ENOMEM); + + pxpcs->dev = dev; + pxpcs->regmap = config->regmap; + pxpcs->reg_indir = config->reg_indir; + + pxpcs->bus = devm_mdiobus_alloc_size(dev, 0); + if (!pxpcs->bus) + return ERR_PTR(-ENOMEM); + + pxpcs->bus->name = "DW XPCS MCI/APB3"; + pxpcs->bus->read = xpcs_regmap_read_c22; + pxpcs->bus->write = xpcs_regmap_write_c22; + pxpcs->bus->read_c45 = xpcs_regmap_read_c45; + pxpcs->bus->write_c45 = xpcs_regmap_write_c45; + pxpcs->bus->phy_mask = ~0; + pxpcs->bus->parent = dev; + pxpcs->bus->priv = pxpcs; + + snprintf(pxpcs->bus->id, MII_BUS_ID_SIZE, + "dwxpcs-%x", atomic_inc_return(&id)); + + /* MDIO-bus here serves as just a back-end engine abstracting out + * the MDIO and MCI/APB3 IO interfaces utilized for the DW XPCS CSRs + * access. + */ + ret = devm_mdiobus_register(dev, pxpcs->bus); + if (ret) { + dev_err(dev, "Failed to create MDIO bus\n"); + return ERR_PTR(ret); + } + + xpcs = xpcs_create_mdiodev(pxpcs->bus, 0); + if (IS_ERR(xpcs)) + return xpcs; + + ret = devm_add_action_or_reset(dev, devm_xpcs_regmap_destroy, xpcs); + if (ret) + return ERR_PTR(ret); + + return xpcs; +} +EXPORT_SYMBOL_GPL(devm_xpcs_regmap_register); diff --git a/include/linux/pcs/pcs-xpcs-regmap.h b/include/linux/pcs/pcs-xpcs-regmap.h new file mode 100644 index 0000000000000..19c99d4160365 --- /dev/null +++ b/include/linux/pcs/pcs-xpcs-regmap.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __LINUX_PCS_XPCS_REGMAP_H +#define __LINUX_PCS_XPCS_REGMAP_H + +#include + +struct device; +struct regmap; +struct dw_xpcs; + +struct xpcs_regmap_config { + struct regmap *regmap; + bool reg_indir; +}; + +struct dw_xpcs *devm_xpcs_regmap_register( + struct device *dev, const struct xpcs_regmap_config *config); + +#endif /* __LINUX_PCS_XPCS_REGMAP_H */ -- 2.51.0