mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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


  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®