From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-qv1-f53.google.com (mail-qv1-f53.google.com [209.85.219.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 41C633D332C for ; Fri, 1 May 2026 15:54:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.53 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777650874; cv=none; b=OLyHYFAEz4mjHIdFv8njH6uvkMHoU+phln3TZk+5oa3lFTpsiylgCj5E7/fD9Hx0uWY0IahQyGDdUjAoRarw7gdLxiGE7hATSkdpL83RjEIXDSu333DSqmPLJ2dzRdXPBEVdIpgPMnmOE0vCf1vqkcqlgByUzE+IGygSdiKRO4M= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777650874; c=relaxed/simple; bh=aDKuyOACGE1gNZqDJy0tqBgdZCQkU/jSoB8ed5fRm2I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SC/XZ9B5VDOYNsS2wG10APhFgsJlp317gt8F1oF2B4YqADz+p4RHl4GYmaWixvcoj0wF11UeGfGNU6jaGCQ/TOBYD2d1t3elPSSi8UaK6fcFFtvj/Htpdwl6Zrapu/lTMvRSPuGj7JSkEFydiwiqChH65GO6e5bW7wGZdPcxzaQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=riscstar.com; spf=pass smtp.mailfrom=riscstar.com; dkim=pass (2048-bit key) header.d=riscstar-com.20251104.gappssmtp.com header.i=@riscstar-com.20251104.gappssmtp.com header.b=fMtk1Sre; arc=none smtp.client-ip=209.85.219.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=riscstar.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=riscstar.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=riscstar-com.20251104.gappssmtp.com header.i=@riscstar-com.20251104.gappssmtp.com header.b="fMtk1Sre" Received: by mail-qv1-f53.google.com with SMTP id 6a1803df08f44-8a151012558so22894746d6.3 for ; Fri, 01 May 2026 08:54:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=riscstar-com.20251104.gappssmtp.com; s=20251104; t=1777650871; x=1778255671; darn=vger.kernel.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=KFcS3U32PymUNY1RdncskmbPJS8yXxMzYT9xI+/9Gm4=; b=fMtk1SreB86rwdZGjIcNe4L88MESDiLdwzL2hEN8M6lap7/SBDpeCiJqKTw3rMZuRa ooCBx9tKT6+v+VVCqqaHnHI1GbFcoUUZl2IGpKZUUtBRQEbKUogIOu/gL/DeeFcOXrSa sTMU3VRF4+jsL9r3egqMEdKIIQcbr2o73xPUEkZoCcAu994iyGR0Wg54RW4ZJPNjRmcm yRIOsO4td7jtDAn7uMe+kyL1dXmmAgvMEuy5+xxvawtYFycwSLCDW6oZhGHpkWtzgFVN 7d39T2F4wRmV8h3uwPQ/e7rR9U7ddRrhjP+gOdkC1HxZQMnhN5LKHnXsmHKffbgp+Zpa tNAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777650871; x=1778255671; 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=KFcS3U32PymUNY1RdncskmbPJS8yXxMzYT9xI+/9Gm4=; b=Z+wadWVxdHSkIGFMuGOY7xzgZ5YvUXbL2Chv/bOU/1uR8j8bX6WPQhb9OA51j9qEXm v9130DgPgxpwp8H3lhiQ3CCjTK6QyHdUJ4hGrEsjC5zMUNZ4gUaNSQ9UK7Qa3A+Q3jba KF2J7b5GvFf+YXN57skGyCm+965OIm/dP05yPDGeFt7luOKZuGUbexYLAGbpMBpGr9Lh kTd714KAO3hKWqolyo4FcGB14BSzdHIK0heNF8TtoNoklx22Ze7Az2QU3AtSwC/9zDxG vtFWn3LKIoZrWk6SOv7GxZPumpdLCxodIZj9PqQNHYynEY1I109N63zyFUfzF9nabGdE unXA== X-Forwarded-Encrypted: i=1; AFNElJ8GhSj0wgxprI+Xwd4jKceZypsMHDQAuVmDKujaXP7oTHiptpjbjOXIfGeCaAPmjzYO3l2g4Dw4Adb/@vger.kernel.org X-Gm-Message-State: AOJu0YyIj3s8BckZWgwzyNGa3x/X07Ndldp9+YJDv0yDao3Hhf9vndH4 OdNUa7Up2UX1TuzQAhqz6QkQHLILv44gfjM5BXqacuyfnuZ9O4m+17c8srUu0qwEVvY= X-Gm-Gg: AeBDievwB0clxFy471qapfbEOmN8nevyRWd8eossC88K5HcwhhNzUviQ3LlFQch73Bh RoblPMxkg4oVMN3RBzsLAUhk8cOnKiVOyOMRKK4ZNTskZ6t+qNrdAt4tqjGo5AnPWivU/TUja4n vdJ40SAm/nz3yU2uT5HxDHofUnIsGQydj0dzd+10RfXXmeToEk7BtZVHZknyBmARX4nDuGs7YO9 178r20FjdyFnAZo3f5EmoSSktyVbCoazPKJtieeCZ7/rlnkGesPhN3KwfgS05dt+aMROCPuXiMX CJ3Gnk+dI+dsLMB7vTUCoRl+wHvMRon04EsmI8BxSVKRHLfAyCh7DNhU8Y5jwez59A7T42+8kcJ ShdEawQA1plJK+sjTN/DkFbzKXeJLzgvHxhZoBdtj4ZlAt8TsSKlxuS7f7pqIzPEkJGImPRqhOE fNJUf4TimHHe33AClnb1FRdJ50IciBn7PbKcBkmRCxhPjHovlYRrnOTAU636cq6ZZkbRtMnI43d wQz0lxgV7A0rxuc X-Received: by 2002:a05:6214:4c88:b0:8a6:1216:fb6f with SMTP id 6a1803df08f44-8b667a83663mr713716d6.32.1777650871067; Fri, 01 May 2026 08:54:31 -0700 (PDT) Received: from zippy.localdomain (c-75-72-117-212.hsd1.mn.comcast.net. [75.72.117.212]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-8b539aa7293sm26615406d6.22.2026.05.01.08.54.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 May 2026 08:54:30 -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, matthew.gerlach@altera.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 01/12] net: pcs: pcs-xpcs-regmap: support XPCS memory-mapped MDIO bus via regmap Date: Fri, 1 May 2026 10:54:09 -0500 Message-ID: <20260501155421.3329862-2-elder@riscstar.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260501155421.3329862-1-elder@riscstar.com> References: <20260501155421.3329862-1-elder@riscstar.com> Precedence: bulk X-Mailing-List: devicetree@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 --- drivers/net/pcs/Makefile | 4 +- drivers/net/pcs/pcs-xpcs-regmap.c | 203 ++++++++++++++++++++++++++++ include/linux/pcs/pcs-xpcs-regmap.h | 20 +++ 3 files changed, 225 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/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..20a54a3605951 --- /dev/null +++ b/drivers/net/pcs/pcs-xpcs-regmap.c @@ -0,0 +1,203 @@ +// 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); +} + +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; + 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); + } + + return xpcs_create_mdiodev(pxpcs->bus, 0); +} +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