From: "Grégoire Layet" <gregoire.layet@9elements.com>
To: joel@jms.id.au, andrew@codeconstruct.com.au, robh@kernel.org,
krzk+dt@kernel.org, conor+dt@kernel.org, corey@minyard.net,
devicetree@vger.kernel.org
Cc: jammy_huang@aspeedtech.com, yc_hsieh@aspeedtech.com,
openipmi-developer@lists.sourceforge.net,
linux-aspeed@lists.ozlabs.org,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org,
"Grégoire Layet" <gregoire.layet@9elements.com>
Subject: [PATCH v3 1/2] ipmi: kcs_bmc_aspeed: g6: Add KCS Channel 4 over PCIe
Date: Mon, 27 Jul 2026 09:27:40 +0200 [thread overview]
Message-ID: <45f36ea6a3a2df18b51c5b83200c7596dbafe133.1785135437.git.gregoire.layet@9elements.com> (raw)
In-Reply-To: <cover.1785135437.git.gregoire.layet@9elements.com>
Created a 5th KCS channel to match against the KCS 4 over PCIe addresses.
The ASPEED AST2600 has a PCIe to LPC controller. It includes a KCS
interface on channel 4. This is a fully KCS-compatible interface
that is exposed over PCIe.
The 5th channel created is only valid on the AST2600.
This cannot be used for AST2400 and AST2500 chips, as they don't have LPC
over PCIE.
Signed-off-by: Grégoire Layet <gregoire.layet@9elements.com>
---
drivers/char/ipmi/kcs_bmc_aspeed.c | 41 ++++++++++++++++++++++++++++--
1 file changed, 39 insertions(+), 2 deletions(-)
diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c b/drivers/char/ipmi/kcs_bmc_aspeed.c
index a13a3470c17a..97daa2b3d6a0 100644
--- a/drivers/char/ipmi/kcs_bmc_aspeed.c
+++ b/drivers/char/ipmi/kcs_bmc_aspeed.c
@@ -26,7 +26,7 @@
#define DEVICE_NAME "ast-kcs-bmc"
-#define KCS_CHANNEL_MAX 4
+#define KCS_CHANNEL_MAX 5
/*
* Field class descriptions
@@ -102,6 +102,12 @@
#define LPC_LSADR12_LSADR2_SHIFT 16
#define LPC_LSADR12_LSADR1_MASK GENMASK(15, 0)
#define LPC_LSADR12_LSADR1_SHIFT 0
+#define PCIE_LPC_HICRB 0x900
+#define PCIE_LPC_HICRC 0x904
+#define PCIE_LPC_LADR4 0x910
+#define PCIE_LPC_IDR4 0x914
+#define PCIE_LPC_ODR4 0x918
+#define PCIE_LPC_STR4 0x91C
#define OBE_POLL_PERIOD (HZ / 2)
@@ -159,6 +165,7 @@ static void aspeed_kcs_outb(struct kcs_bmc_device *kcs_bmc, u32 reg, u8 data)
case LPC_ODR2:
case LPC_ODR3:
case LPC_ODR4:
+ case PCIE_LPC_ODR4:
break;
default:
return;
@@ -191,6 +198,9 @@ static void aspeed_kcs_outb(struct kcs_bmc_device *kcs_bmc, u32 reg, u8 data)
case 4:
regmap_update_bits(priv->map, LPC_HICRC, LPC_HICRC_IRQXE4, LPC_HICRC_IRQXE4);
break;
+ case 5:
+ regmap_update_bits(priv->map, PCIE_LPC_HICRC, LPC_HICRC_IRQXE4, LPC_HICRC_IRQXE4);
+ break;
default:
break;
}
@@ -278,6 +288,14 @@ static int aspeed_kcs_set_address(struct kcs_bmc_device *kcs_bmc, u32 addrs[2],
break;
+ case 5:
+ if (nr_addrs == 1)
+ regmap_write(priv->map, PCIE_LPC_LADR4, ((addrs[0] + 1) << 16) | addrs[0]);
+ else
+ regmap_write(priv->map, PCIE_LPC_LADR4, (addrs[1] << 16) | addrs[0]);
+
+ break;
+
default:
return -EINVAL;
}
@@ -344,6 +362,11 @@ static int aspeed_kcs_config_upstream_irq(struct aspeed_kcs_bmc *priv, u32 id, u
val = (id << LPC_HICRC_ID4IRQX_SHIFT) | (hw_type << LPC_HICRC_TY4IRQX_SHIFT);
regmap_update_bits(priv->map, LPC_HICRC, mask, val);
break;
+ case 5:
+ mask = LPC_HICRC_ID4IRQX_MASK | LPC_HICRC_TY4IRQX_MASK | LPC_HICRC_OBF4_AUTO_CLR;
+ val = (id << LPC_HICRC_ID4IRQX_SHIFT) | (hw_type << LPC_HICRC_TY4IRQX_SHIFT);
+ regmap_update_bits(priv->map, PCIE_LPC_HICRC, mask, val);
+ break;
default:
dev_warn(priv->kcs_bmc.dev,
"SerIRQ configuration not supported on KCS channel %d\n",
@@ -373,6 +396,10 @@ static void aspeed_kcs_enable_channel(struct kcs_bmc_device *kcs_bmc, bool enabl
case 4:
regmap_update_bits(priv->map, LPC_HICRB, LPC_HICRB_LPC4E, enable * LPC_HICRB_LPC4E);
return;
+ case 5:
+ regmap_update_bits(priv->map, PCIE_LPC_HICRB, LPC_HICRB_LPC4E,
+ enable * LPC_HICRB_LPC4E);
+ return;
default:
pr_warn("%s: Unsupported channel: %d", __func__, kcs_bmc->channel);
return;
@@ -452,6 +479,10 @@ static void aspeed_kcs_irq_mask_update(struct kcs_bmc_device *kcs_bmc, u8 mask,
regmap_update_bits(priv->map, LPC_HICRB, LPC_HICRB_IBFIE4,
enable * LPC_HICRB_IBFIE4);
return;
+ case 5:
+ regmap_update_bits(priv->map, PCIE_LPC_HICRB, LPC_HICRB_IBFIE4,
+ enable * LPC_HICRB_IBFIE4);
+ return;
default:
pr_warn("%s: Unsupported channel: %d", __func__, kcs_bmc->channel);
return;
@@ -492,6 +523,7 @@ static const struct kcs_ioreg ast_kcs_bmc_ioregs[KCS_CHANNEL_MAX] = {
{ .idr = LPC_IDR2, .odr = LPC_ODR2, .str = LPC_STR2 },
{ .idr = LPC_IDR3, .odr = LPC_ODR3, .str = LPC_STR3 },
{ .idr = LPC_IDR4, .odr = LPC_ODR4, .str = LPC_STR4 },
+ { .idr = PCIE_LPC_IDR4, .odr = PCIE_LPC_ODR4, .str = PCIE_LPC_STR4 },
};
static int aspeed_kcs_of_get_channel(struct platform_device *pdev)
@@ -575,11 +607,16 @@ static int aspeed_kcs_probe(struct platform_device *pdev)
if (channel < 0)
return channel;
+ np = pdev->dev.of_node;
+ if (channel == 5 && !of_device_is_compatible(np, "aspeed,ast2600-kcs-bmc")) {
+ dev_err(&pdev->dev, "LPC over PCIE KCS4 only supported on ast2600\n");
+ return -ENODEV;
+ }
+
nr_addrs = aspeed_kcs_of_get_io_address(pdev, addrs);
if (nr_addrs < 0)
return nr_addrs;
- np = pdev->dev.of_node;
rc = of_property_read_u32_array(np, "aspeed,lpc-interrupts", upstream_irq, 2);
if (rc && rc != -EINVAL)
return -EINVAL;
--
2.54.0
WARNING: multiple messages have this Message-ID
From: "Grégoire Layet" <gregoire.layet@9elements.com>
To: joel@jms.id.au, andrew@codeconstruct.com.au, robh@kernel.org,
krzk+dt@kernel.org, conor+dt@kernel.org, corey@minyard.net,
devicetree@vger.kernel.org
Cc: jammy_huang@aspeedtech.com, yc_hsieh@aspeedtech.com,
openipmi-developer@lists.sourceforge.net,
linux-aspeed@lists.ozlabs.org,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org,
"Grégoire Layet" <gregoire.layet@9elements.com>
Subject: [PATCH v3 1/2 RESEND] ipmi: kcs_bmc_aspeed: g6: Add KCS Channel 4 over PCIe
Date: Wed, 5 Aug 2026 10:19:00 +0200 [thread overview]
Message-ID: <45f36ea6a3a2df18b51c5b83200c7596dbafe133.1785135437.git.gregoire.layet@9elements.com> (raw)
Message-ID: <20260805081900.IM37rUwLGR_JPFyhAlc2VEZVjUhOGHQe7HAnpWdmQEw@z> (raw)
In-Reply-To: <cover.1785135437.git.gregoire.layet@9elements.com>
Created a 5th KCS channel to match against the KCS 4 over PCIe addresses.
The ASPEED AST2600 has a PCIe to LPC controller. It includes a KCS
interface on channel 4. This is a fully KCS-compatible interface
that is exposed over PCIe.
The 5th channel created is only valid on the AST2600.
This cannot be used for AST2400 and AST2500 chips, as they don't have LPC
over PCIE.
Signed-off-by: Grégoire Layet <gregoire.layet@9elements.com>
---
drivers/char/ipmi/kcs_bmc_aspeed.c | 41 ++++++++++++++++++++++++++++--
1 file changed, 39 insertions(+), 2 deletions(-)
diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c b/drivers/char/ipmi/kcs_bmc_aspeed.c
index a13a3470c17a..97daa2b3d6a0 100644
--- a/drivers/char/ipmi/kcs_bmc_aspeed.c
+++ b/drivers/char/ipmi/kcs_bmc_aspeed.c
@@ -26,7 +26,7 @@
#define DEVICE_NAME "ast-kcs-bmc"
-#define KCS_CHANNEL_MAX 4
+#define KCS_CHANNEL_MAX 5
/*
* Field class descriptions
@@ -102,6 +102,12 @@
#define LPC_LSADR12_LSADR2_SHIFT 16
#define LPC_LSADR12_LSADR1_MASK GENMASK(15, 0)
#define LPC_LSADR12_LSADR1_SHIFT 0
+#define PCIE_LPC_HICRB 0x900
+#define PCIE_LPC_HICRC 0x904
+#define PCIE_LPC_LADR4 0x910
+#define PCIE_LPC_IDR4 0x914
+#define PCIE_LPC_ODR4 0x918
+#define PCIE_LPC_STR4 0x91C
#define OBE_POLL_PERIOD (HZ / 2)
@@ -159,6 +165,7 @@ static void aspeed_kcs_outb(struct kcs_bmc_device *kcs_bmc, u32 reg, u8 data)
case LPC_ODR2:
case LPC_ODR3:
case LPC_ODR4:
+ case PCIE_LPC_ODR4:
break;
default:
return;
@@ -191,6 +198,9 @@ static void aspeed_kcs_outb(struct kcs_bmc_device *kcs_bmc, u32 reg, u8 data)
case 4:
regmap_update_bits(priv->map, LPC_HICRC, LPC_HICRC_IRQXE4, LPC_HICRC_IRQXE4);
break;
+ case 5:
+ regmap_update_bits(priv->map, PCIE_LPC_HICRC, LPC_HICRC_IRQXE4, LPC_HICRC_IRQXE4);
+ break;
default:
break;
}
@@ -278,6 +288,14 @@ static int aspeed_kcs_set_address(struct kcs_bmc_device *kcs_bmc, u32 addrs[2],
break;
+ case 5:
+ if (nr_addrs == 1)
+ regmap_write(priv->map, PCIE_LPC_LADR4, ((addrs[0] + 1) << 16) | addrs[0]);
+ else
+ regmap_write(priv->map, PCIE_LPC_LADR4, (addrs[1] << 16) | addrs[0]);
+
+ break;
+
default:
return -EINVAL;
}
@@ -344,6 +362,11 @@ static int aspeed_kcs_config_upstream_irq(struct aspeed_kcs_bmc *priv, u32 id, u
val = (id << LPC_HICRC_ID4IRQX_SHIFT) | (hw_type << LPC_HICRC_TY4IRQX_SHIFT);
regmap_update_bits(priv->map, LPC_HICRC, mask, val);
break;
+ case 5:
+ mask = LPC_HICRC_ID4IRQX_MASK | LPC_HICRC_TY4IRQX_MASK | LPC_HICRC_OBF4_AUTO_CLR;
+ val = (id << LPC_HICRC_ID4IRQX_SHIFT) | (hw_type << LPC_HICRC_TY4IRQX_SHIFT);
+ regmap_update_bits(priv->map, PCIE_LPC_HICRC, mask, val);
+ break;
default:
dev_warn(priv->kcs_bmc.dev,
"SerIRQ configuration not supported on KCS channel %d\n",
@@ -373,6 +396,10 @@ static void aspeed_kcs_enable_channel(struct kcs_bmc_device *kcs_bmc, bool enabl
case 4:
regmap_update_bits(priv->map, LPC_HICRB, LPC_HICRB_LPC4E, enable * LPC_HICRB_LPC4E);
return;
+ case 5:
+ regmap_update_bits(priv->map, PCIE_LPC_HICRB, LPC_HICRB_LPC4E,
+ enable * LPC_HICRB_LPC4E);
+ return;
default:
pr_warn("%s: Unsupported channel: %d", __func__, kcs_bmc->channel);
return;
@@ -452,6 +479,10 @@ static void aspeed_kcs_irq_mask_update(struct kcs_bmc_device *kcs_bmc, u8 mask,
regmap_update_bits(priv->map, LPC_HICRB, LPC_HICRB_IBFIE4,
enable * LPC_HICRB_IBFIE4);
return;
+ case 5:
+ regmap_update_bits(priv->map, PCIE_LPC_HICRB, LPC_HICRB_IBFIE4,
+ enable * LPC_HICRB_IBFIE4);
+ return;
default:
pr_warn("%s: Unsupported channel: %d", __func__, kcs_bmc->channel);
return;
@@ -492,6 +523,7 @@ static const struct kcs_ioreg ast_kcs_bmc_ioregs[KCS_CHANNEL_MAX] = {
{ .idr = LPC_IDR2, .odr = LPC_ODR2, .str = LPC_STR2 },
{ .idr = LPC_IDR3, .odr = LPC_ODR3, .str = LPC_STR3 },
{ .idr = LPC_IDR4, .odr = LPC_ODR4, .str = LPC_STR4 },
+ { .idr = PCIE_LPC_IDR4, .odr = PCIE_LPC_ODR4, .str = PCIE_LPC_STR4 },
};
static int aspeed_kcs_of_get_channel(struct platform_device *pdev)
@@ -575,11 +607,16 @@ static int aspeed_kcs_probe(struct platform_device *pdev)
if (channel < 0)
return channel;
+ np = pdev->dev.of_node;
+ if (channel == 5 && !of_device_is_compatible(np, "aspeed,ast2600-kcs-bmc")) {
+ dev_err(&pdev->dev, "LPC over PCIE KCS4 only supported on ast2600\n");
+ return -ENODEV;
+ }
+
nr_addrs = aspeed_kcs_of_get_io_address(pdev, addrs);
if (nr_addrs < 0)
return nr_addrs;
- np = pdev->dev.of_node;
rc = of_property_read_u32_array(np, "aspeed,lpc-interrupts", upstream_irq, 2);
if (rc && rc != -EINVAL)
return -EINVAL;
--
2.54.0
next prev parent reply other threads:[~2026-07-27 7:30 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-27 7:27 [PATCH v3 0/2] " Grégoire Layet
2026-07-27 7:27 ` Grégoire Layet [this message]
2026-08-05 8:19 ` [PATCH v3 1/2 RESEND] " Grégoire Layet
2026-07-27 7:27 ` [PATCH v3 2/2] ARM: dts: aspeed-g6: add pcie-kcs4 Grégoire Layet
2026-08-05 8:19 ` [PATCH v3 2/2 RESEND] " Grégoire Layet
2026-08-05 8:18 ` [PATCH v3 0/2 RESEND] soc: aspeed: ipmi: add KCS Channel 4 over PCIe Grégoire Layet
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=45f36ea6a3a2df18b51c5b83200c7596dbafe133.1785135437.git.gregoire.layet@9elements.com \
--to=gregoire.layet@9elements.com \
--cc=andrew@codeconstruct.com.au \
--cc=conor+dt@kernel.org \
--cc=corey@minyard.net \
--cc=devicetree@vger.kernel.org \
--cc=jammy_huang@aspeedtech.com \
--cc=joel@jms.id.au \
--cc=krzk+dt@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-aspeed@lists.ozlabs.org \
--cc=linux-kernel@vger.kernel.org \
--cc=openipmi-developer@lists.sourceforge.net \
--cc=robh@kernel.org \
--cc=yc_hsieh@aspeedtech.com \
/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®