From: Imre Kaloz <kaloz@kernel.org>
To: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: linux-mips@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 23/38] MIPS: PCI: xtalk-bridge: recognize the PIC widget's 64-bit-only registers
Date: Thu, 1 Oct 2026 18:11:58 +0200 [thread overview]
Message-ID: <b1b33df20ce6a5b85c842ae81b82fa4617744ee1.1790857966.git.kaloz@kernel.org> (raw)
In-Reply-To: <cover.1790857966.git.kaloz@kernel.org>
PIC replicates the Bridge/XBridge register layout, twice in one widget
window for its two PCI buses, and does not accept a 32-bit write to half
of a 64-bit register. Flag it, widen the register accessors to the
double word, and spawn a controller per bus.
Signed-off-by: Imre Kaloz <kaloz@kernel.org>
---
arch/mips/include/asm/pci/bridge.h | 70 +++++++++++++++++++++++++++---
arch/mips/sgi-ip27/ip27-xtalk.c | 30 ++++++++++---
2 files changed, 89 insertions(+), 11 deletions(-)
diff --git a/arch/mips/include/asm/pci/bridge.h b/arch/mips/include/asm/pci/bridge.h
index 2ea0f1e2cd76..76c5db983748 100644
--- a/arch/mips/include/asm/pci/bridge.h
+++ b/arch/mips/include/asm/pci/bridge.h
@@ -12,6 +12,8 @@
#ifndef _ASM_PCI_BRIDGE_H
#define _ASM_PCI_BRIDGE_H
+#include <linux/build_bug.h>
+#include <linux/stddef.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <asm/xtalk/xwidget.h> /* generic widget header */
@@ -39,6 +41,9 @@
#define BRIDGE_SSRAM_64K 0x00010000 /* 64kB */
#define BRIDGE_SSRAM_0K 0x00000000 /* 0kB */
+/* PIC replicates its register block twice within one widget's 16MB window. */
+#define PIC_BUS1_OFFSET 0x800000
+
/* ========================================================================
* Bridge address map
*/
@@ -264,6 +269,15 @@ struct bridge_regs {
} b_external_flash; /* 0xC00000 */
};
+/*
+ * Pin b_device[]/b_rrb_map[]'s low-half placement: bridge_readl() and
+ * bridge_writel() rely on it.
+ */
+static_assert(offsetof(struct bridge_regs, b_device[0].reg) == 0x204);
+static_assert(offsetof(struct bridge_regs, b_device[1].reg) == 0x20c);
+static_assert(offsetof(struct bridge_regs, b_rrb_map[0].reg) == 0x284);
+static_assert(offsetof(struct bridge_regs, b_rrb_map[1].reg) == 0x28c);
+
/*
* Field formats for Error Command Word and Auxiliary Error Command Word
* of bridge.
@@ -394,6 +408,7 @@ struct bridge_err_cmdword {
/* Widget part number of bridge */
#define BRIDGE_WIDGET_PART_NUM 0xc002
#define XBRIDGE_WIDGET_PART_NUM 0xd002
+#define PIC_WIDGET_PART_NUM 0xd102
/* Manufacturer of bridge */
#define BRIDGE_WIDGET_MFGR_NUM 0x036
@@ -817,11 +832,54 @@ struct bridge_controller {
#define BRIDGE_CONTROLLER(bus) \
((struct bridge_controller *)((bus)->sysdata))
-#define bridge_read(bc, reg) __raw_readl(&bc->base->reg)
-#define bridge_write(bc, reg, val) __raw_writel(val, &bc->base->reg)
-#define bridge_set(bc, reg, val) \
- __raw_writel(__raw_readl(&bc->base->reg) | (val), &bc->base->reg)
-#define bridge_clr(bc, reg, val) \
- __raw_writel(__raw_readl(&bc->base->reg) & ~(val), &bc->base->reg)
+/*
+ * PIC does not accept a 32-bit write to half of a 64-bit register, so
+ * widen each access to the 8-byte-aligned double word and extract or
+ * insert the 32-bit value at its byte position. The pointer is
+ * volatile-qualified because widget_cfg_t is, and b_widget sits in
+ * every bridge_regs.
+ */
+static inline u32 bridge_readl(struct bridge_controller *bc, volatile u32 *reg)
+{
+ void *dw;
+ unsigned int shift;
+
+ if (likely(!bc->is_pic))
+ return __raw_readl(reg);
+
+ dw = (void *)((unsigned long)reg & ~7UL);
+ shift = ((unsigned long)reg & 4) ? 0 : 32;
+
+ return __raw_readq(dw) >> shift;
+}
+
+static inline void bridge_writel(struct bridge_controller *bc,
+ volatile u32 *reg, u32 val)
+{
+ void *dw;
+ unsigned int shift;
+ u64 tmp;
+
+ if (likely(!bc->is_pic)) {
+ __raw_writel(val, reg);
+ return;
+ }
+
+ dw = (void *)((unsigned long)reg & ~7UL);
+ shift = ((unsigned long)reg & 4) ? 0 : 32;
+
+ tmp = __raw_readq(dw);
+ tmp = (tmp & ~(0xffffffffULL << shift)) | ((u64)val << shift);
+ __raw_writeq(tmp, dw);
+}
+
+#define bridge_read(bc, reg) bridge_readl(bc, &bc->base->reg)
+#define bridge_write(bc, reg, val) bridge_writel(bc, &bc->base->reg, val)
+#define bridge_set(bc, reg, val) \
+ bridge_writel(bc, &bc->base->reg, \
+ bridge_readl(bc, &bc->base->reg) | (val))
+#define bridge_clr(bc, reg, val) \
+ bridge_writel(bc, &bc->base->reg, \
+ bridge_readl(bc, &bc->base->reg) & ~(val))
#endif /* _ASM_PCI_BRIDGE_H */
diff --git a/arch/mips/sgi-ip27/ip27-xtalk.c b/arch/mips/sgi-ip27/ip27-xtalk.c
index 105977316391..73b2eef96bdb 100644
--- a/arch/mips/sgi-ip27/ip27-xtalk.c
+++ b/arch/mips/sgi-ip27/ip27-xtalk.c
@@ -27,6 +27,8 @@
enum xtalk_bridge_type {
XTALK_BRIDGE,
XTALK_XBRIDGE,
+ XTALK_PIC_BUS0,
+ XTALK_PIC_BUS1,
};
static void bridge_platform_create(nasid_t nasid, int widget, int masterwid,
@@ -88,21 +90,32 @@ static void bridge_platform_create(nasid_t nasid, int widget, int masterwid,
}
- bd->bridge_addr = RAW_NODE_SWIN_BASE(nasid, widget);
+ bd->bridge_addr = RAW_NODE_SWIN_BASE(nasid, widget) +
+ (type == XTALK_PIC_BUS1 ? PIC_BUS1_OFFSET : 0);
bd->intr_addr = BIT_ULL(47) + 0x01800000 + PI_INT_PEND_MOD;
bd->nasid = nasid;
bd->masterwid = masterwid;
bd->is_xbridge = type == XTALK_XBRIDGE;
+ bd->is_pic = type == XTALK_PIC_BUS0 || type == XTALK_PIC_BUS1;
+ /* Split a PIC's window at bus 1 or its resource request fails. */
bd->mem.name = "Bridge PCI MEM";
- bd->mem.start = offset + (widget << SWIN_SIZE_BITS) + BRIDGE_DEVIO0;
- bd->mem.end = offset + (widget << SWIN_SIZE_BITS) + SWIN_SIZE - 1;
+ bd->mem.start = offset + (widget << SWIN_SIZE_BITS) +
+ (type == XTALK_PIC_BUS1 ? PIC_BUS1_OFFSET : 0) +
+ BRIDGE_DEVIO0;
+ bd->mem.end = offset + (widget << SWIN_SIZE_BITS) +
+ (type == XTALK_PIC_BUS0 ? PIC_BUS1_OFFSET :
+ SWIN_SIZE) - 1;
bd->mem.flags = IORESOURCE_MEM;
bd->mem_offset = offset;
bd->io.name = "Bridge PCI IO";
- bd->io.start = offset + (widget << SWIN_SIZE_BITS) + BRIDGE_DEVIO0;
- bd->io.end = offset + (widget << SWIN_SIZE_BITS) + SWIN_SIZE - 1;
+ bd->io.start = offset + (widget << SWIN_SIZE_BITS) +
+ (type == XTALK_PIC_BUS1 ? PIC_BUS1_OFFSET : 0) +
+ BRIDGE_DEVIO0;
+ bd->io.end = offset + (widget << SWIN_SIZE_BITS) +
+ (type == XTALK_PIC_BUS0 ? PIC_BUS1_OFFSET :
+ SWIN_SIZE) - 1;
bd->io.flags = IORESOURCE_IO;
bd->io_offset = offset;
@@ -149,6 +162,13 @@ static int probe_one_port(nasid_t nasid, int widget, int masterwid)
case XBRIDGE_WIDGET_PART_NUM:
bridge_platform_create(nasid, widget, masterwid, XTALK_XBRIDGE);
break;
+ case PIC_WIDGET_PART_NUM:
+ /* PIC always has both buses in silicon: probe each. */
+ bridge_platform_create(nasid, widget, masterwid,
+ XTALK_PIC_BUS0);
+ bridge_platform_create(nasid, widget, masterwid,
+ XTALK_PIC_BUS1);
+ break;
default:
pr_info("xtalk:n%d/%d unknown widget (0x%x)\n",
nasid, widget, partnum);
--
2.47.3
next prev parent reply other threads:[~2026-10-01 16:14 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-01 16:11 [PATCH 00/38] MIPS: SGI-IP27: add support for the IP35 (Bedrock hub) machines Imre Kaloz
2026-10-01 16:11 ` [PATCH 01/38] MIPS: Xtalk: guard the widget identification table from assembly Imre Kaloz
2026-10-01 16:11 ` [PATCH 02/38] MIPS: SGI-IP27: dump the NMI save areas the CPU scan recorded Imre Kaloz
2026-10-01 16:11 ` [PATCH 03/38] MIPS: SGI-IP27: add REMOTE_HUB_PI_S()/REMOTE_HUB_PI_L() Imre Kaloz
2026-10-01 16:11 ` [PATCH 04/38] MIPS: SGI-IP27: detect Bedrock hubs at boot Imre Kaloz
2026-10-01 16:11 ` [PATCH 05/38] MIPS: SGI-IP27: widen Kconfig for the Bedrock-based machines Imre Kaloz
2026-10-01 16:11 ` [PATCH 06/38] MIPS: SGI-IP27: fold the dead SN1 arm out of klconfig.h Imre Kaloz
2026-10-01 16:11 ` [PATCH 07/38] MIPS: SGI-IP27: choose the node address layout at runtime Imre Kaloz
2026-10-01 16:11 ` [PATCH 08/38] MIPS: SGI-IP27: add the Bedrock hub register windows Imre Kaloz
2026-10-01 16:11 ` [PATCH 09/38] MIPS: SGI-IP27: decode a Bedrock hub's node id and system size Imre Kaloz
2026-10-01 16:11 ` [PATCH 10/38] MIPS: SGI-IP27: put a Bedrock hub's boot CPU in slot 0 Imre Kaloz
2026-10-01 16:11 ` [PATCH 11/38] MIPS: SGI-IP27: lay out node memory in 1GB banks on Bedrock hubs Imre Kaloz
2026-10-01 16:11 ` [PATCH 12/38] MIPS: SGI-IP27: reserve the bottom 64MB of node 0 " Imre Kaloz
2026-10-01 16:11 ` [PATCH 13/38] MIPS: SGI-IP27: route interrupt masks and slices through both PIs Imre Kaloz
2026-10-01 16:11 ` [PATCH 14/38] MIPS: SGI-IP27: address a CPU's own PI for NMI, IPI and RT counter Imre Kaloz
2026-10-01 16:11 ` [PATCH 15/38] MIPS: SGI-IP27: take a CPU's node from the CPU table in per_cpu_init() Imre Kaloz
2026-10-01 16:11 ` [PATCH 16/38] MIPS: SGI-IP27: resolve the mapped-kernel node shift at runtime Imre Kaloz
2026-10-01 16:11 ` [PATCH 17/38] MIPS: SGI-IP27: load the kernel at node offset 0x40000 Imre Kaloz
2026-10-01 16:11 ` [PATCH 18/38] MIPS: SGI-IP27: xbow_probe(): recognize KLTYPE_PBRICK_XBOW Imre Kaloz
2026-10-01 16:11 ` [PATCH 19/38] MIPS: ip27_defconfig: enable the IOC3 MFD, its cell drivers and tg3 Imre Kaloz
2026-10-01 16:11 ` [PATCH 20/38] net: ethernet: sgi: ioc3-eth: apply the DMA attributes only to 64-bit addresses Imre Kaloz
2026-10-01 16:11 ` [PATCH 21/38] MIPS: SGI-IP27: route XBridge and PIC DMA through the 32-bit window Imre Kaloz
2026-10-05 8:39 ` Christoph Hellwig
2026-10-05 13:15 ` Imre Kaloz
2026-10-01 16:11 ` [PATCH 22/38] MIPS: SGI-IP27: recognize the PXBow crossbar Imre Kaloz
2026-10-01 16:11 ` Imre Kaloz [this message]
2026-10-01 16:11 ` [PATCH 24/38] MIPS: PCI: xtalk-bridge: match PIC's register-level differences Imre Kaloz
2026-10-01 16:12 ` [PATCH 25/38] rtc: m48t35: support the SGI IP35 timekeeper's 1968 year base Imre Kaloz
2026-10-01 16:12 ` [PATCH 26/38] mfd: ioc3: add support for IOC4 Imre Kaloz
2026-10-01 16:12 ` [PATCH 27/38] MIPS: SGI-IP27: dispatch the early console between IOC3 and IOC4 Imre Kaloz
2026-10-01 16:12 ` [PATCH 28/38] MIPS: SGI-IP27: add L1 system controller support Imre Kaloz
2026-10-01 16:12 ` [PATCH 29/38] MIPS: SGI-IP27: wire the L1 into reset and the Ethernet address Imre Kaloz
2026-10-01 16:12 ` [PATCH 30/38] MIPS: PCI: xtalk-bridge: take the board part number from the L1 Imre Kaloz
2026-10-01 16:12 ` [PATCH 31/38] mfd: ioc3: add IP34 system-board entry to ioc3_infos[] Imre Kaloz
2026-10-02 10:02 ` Lee Jones
2026-10-02 10:29 ` Imre Kaloz
2026-10-01 16:12 ` [PATCH 32/38] net: ethernet: sgi: ioc3-eth: fall back to the platform MAC address Imre Kaloz
2026-10-01 16:12 ` [PATCH 33/38] MIPS: SGI-IP27: don't register a w1 master on an XBridge or PIC Imre Kaloz
2026-10-01 16:12 ` [PATCH 34/38] MIPS: SGI-IP27: report a Bedrock machine as SGI IP35 Imre Kaloz
2026-10-01 16:12 ` [PATCH 35/38] MIPS: SGI-IP27: identify the machine by the L1 brick type Imre Kaloz
2026-10-01 16:12 ` [PATCH 36/38] MIPS: SGI-IP27: register the Odyssey graphics widget Imre Kaloz
2026-10-01 16:12 ` [PATCH 37/38] MIPS: SGI-IP27: take the console from the KLCONFIG header on IP35 Imre Kaloz
2026-10-01 16:12 ` [PATCH 38/38] MIPS: SGI-IP27: give each CPU its own topology package id Imre Kaloz
2026-10-02 15:46 ` [PATCH 00/38] MIPS: SGI-IP27: add support for the IP35 (Bedrock hub) machines Thomas Bogendoerfer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=b1b33df20ce6a5b85c842ae81b82fa4617744ee1.1790857966.git.kaloz@kernel.org \
--to=kaloz@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mips@vger.kernel.org \
--cc=tsbogend@alpha.franken.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®