From nobody Mon Feb 9 09:32:41 2026 Received: from TWMBX01.aspeed.com (mail.aspeedtech.com [211.20.114.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CDB7E366075; Fri, 23 Jan 2026 09:27:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.20.114.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769160438; cv=none; b=kDWp8chQf5uVpNmTRuSW2458EFoFd8Ub4S8iVZ3THIAQvRbO92xPwnmTDyC5DneR5KjleOKtBf/nrzvWX2RmCE4qEg+FqDcEXZKt72Tm1Bo6/OaPURceCEcmK14mg9o4CIFqq44M4pus816CCg+j6r6UIZnGzH8kvf66//Ho05M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769160438; c=relaxed/simple; bh=Yc0Am0JOK83f2qlQR8wy0adnCkIm88yQxe8eRCbOxTw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=C9rZCZQ4etOE8C6RRxQMvDyMTbJLSS4u5cXVLABhLQkXauhGSXqzUr67mY8lCrlWZTHnLf+KoDRB01hmoc6h15hV0egMiC0fEz2TGihjMQqxalhpgrZo+BTdu9k9hdMWPW9omaucNrIwudaGX2oku4wOM0zQK6RDN0dAPqm5iAw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=aspeedtech.com; spf=pass smtp.mailfrom=aspeedtech.com; arc=none smtp.client-ip=211.20.114.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=aspeedtech.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=aspeedtech.com Received: from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.10; Fri, 23 Jan 2026 17:26:27 +0800 Received: from [127.0.1.1] (192.168.10.13) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server id 15.2.1748.10 via Frontend Transport; Fri, 23 Jan 2026 17:26:27 +0800 From: Billy Tsai Date: Fri, 23 Jan 2026 17:26:31 +0800 Subject: [PATCH v2 6/6] gpio: aspeed-sgpio: Support G7 Aspeed sgpiom controller Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-ID: <20260123-upstream_sgpio-v2-6-69cfd1631400@aspeedtech.com> References: <20260123-upstream_sgpio-v2-0-69cfd1631400@aspeedtech.com> In-Reply-To: <20260123-upstream_sgpio-v2-0-69cfd1631400@aspeedtech.com> To: Linus Walleij , Bartosz Golaszewski , Joel Stanley , Andrew Jeffery , Rob Herring , Krzysztof Kozlowski , Conor Dooley CC: , , , , "Andrew Jeffery" , , , Billy Tsai X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1769160386; l=5872; i=billy_tsai@aspeedtech.com; s=20251118; h=from:subject:message-id; bh=Yc0Am0JOK83f2qlQR8wy0adnCkIm88yQxe8eRCbOxTw=; b=qDEskd91oEVv3mtQ7vh96cpdr2vm6lBb1mwHJDfrJmAukdsk6JrYvA9PUjH5GxI1Rikq2++1z jOWA1tTl43NCaSCKupaIC6opihZ2EYMQNMir4ljwlIbTtckHZ+MwOMJ X-Developer-Key: i=billy_tsai@aspeedtech.com; a=ed25519; pk=/A8qvgZ6CPfnwKgT6/+k+nvXOkN477MshEGJvVdzeeQ= In the 7th generation of the SoC from Aspeed, the control logic of the SGPIO controller has been updated to support per-pin control. Each pin now has its own 32-bit register, allowing for individual control of the pin's value, interrupt type, and other settings. Reviewed-by: Linus Walleij Signed-off-by: Billy Tsai --- drivers/gpio/gpio-aspeed-sgpio.c | 110 +++++++++++++++++++++++++++++++++++= +++- 1 file changed, 108 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-aspeed-sgpio.c b/drivers/gpio/gpio-aspeed-sg= pio.c index b5270e11b153..4225261f61c8 100644 --- a/drivers/gpio/gpio-aspeed-sgpio.c +++ b/drivers/gpio/gpio-aspeed-sgpio.c @@ -19,7 +19,31 @@ #include #include =20 -#define ASPEED_SGPIO_CTRL 0x54 +#define SGPIO_G7_IRQ_STS_BASE 0x40 +#define SGPIO_G7_IRQ_STS_OFFSET(x) (SGPIO_G7_IRQ_STS_BASE + (x) * 0x4) +#define SGPIO_G7_CTRL_REG_BASE 0x80 +#define SGPIO_G7_CTRL_REG_OFFSET(x) (SGPIO_G7_CTRL_REG_BASE + (x) * 0x4) +#define SGPIO_G7_OUT_DATA BIT(0) +#define SGPIO_G7_PARALLEL_OUT_DATA BIT(1) +#define SGPIO_G7_IRQ_EN BIT(2) +#define SGPIO_G7_IRQ_TYPE0 BIT(3) +#define SGPIO_G7_IRQ_TYPE1 BIT(4) +#define SGPIO_G7_IRQ_TYPE2 BIT(5) +#define SGPIO_G7_RST_TOLERANCE BIT(6) +#define SGPIO_G7_INPUT_MASK BIT(9) +#define SGPIO_G7_HW_BYPASS_EN BIT(10) +#define SGPIO_G7_HW_IN_SEL BIT(11) +#define SGPIO_G7_IRQ_STS BIT(12) +#define SGPIO_G7_IN_DATA BIT(13) +#define SGPIO_G7_PARALLEL_IN_DATA BIT(14) +#define SGPIO_G7_SERIAL_OUT_SEL GENMASK(17, 16) +#define SGPIO_G7_PARALLEL_OUT_SEL GENMASK(19, 18) +#define SELECT_FROM_CSR 0 +#define SELECT_FROM_PARALLEL_IN 1 +#define SELECT_FROM_SERIAL_IN 2 + +#define ASPEED_SGPIO_G4_CFG_OFFSET 0x54 +#define ASPEED_SGPIO_G7_CFG_OFFSET 0x0 =20 #define ASPEED_SGPIO_CLK_DIV_MASK GENMASK(31, 16) #define ASPEED_SGPIO_ENABLE BIT(0) @@ -28,6 +52,7 @@ struct aspeed_sgpio_pdata { const u32 pin_mask; const struct aspeed_sgpio_llops *llops; + const u32 cfg_offset; }; =20 struct aspeed_sgpio { @@ -135,6 +160,30 @@ static void __iomem *aspeed_sgpio_g4_bank_reg(struct a= speed_sgpio *gpio, } } =20 +static u32 aspeed_sgpio_g7_reg_mask(const enum aspeed_sgpio_reg reg) +{ + switch (reg) { + case reg_val: + case reg_rdata: + return SGPIO_G7_OUT_DATA; + case reg_irq_enable: + return SGPIO_G7_IRQ_EN; + case reg_irq_type0: + return SGPIO_G7_IRQ_TYPE0; + case reg_irq_type1: + return SGPIO_G7_IRQ_TYPE1; + case reg_irq_type2: + return SGPIO_G7_IRQ_TYPE2; + case reg_irq_status: + return SGPIO_G7_IRQ_STS; + case reg_tolerance: + return SGPIO_G7_RST_TOLERANCE; + default: + WARN_ON_ONCE(1); + return 0; + } +} + #define GPIO_BANK(x) ((x) >> 6) #define GPIO_OFFSET(x) ((x) & GENMASK(5, 0)) #define GPIO_BIT(x) BIT(GPIO_OFFSET(x) >> 1) @@ -457,6 +506,7 @@ static const struct aspeed_sgpio_llops aspeed_sgpio_g4_= llops =3D { static const struct aspeed_sgpio_pdata ast2400_sgpio_pdata =3D { .pin_mask =3D GENMASK(9, 6), .llops =3D &aspeed_sgpio_g4_llops, + .cfg_offset =3D ASPEED_SGPIO_G4_CFG_OFFSET, }; =20 static int aspeed_sgpio_reset_tolerance(struct gpio_chip *chip, @@ -486,12 +536,68 @@ static int aspeed_sgpio_set_config(struct gpio_chip *= chip, unsigned int offset, static const struct aspeed_sgpio_pdata ast2600_sgpiom_pdata =3D { .pin_mask =3D GENMASK(10, 6), .llops =3D &aspeed_sgpio_g4_llops, + .cfg_offset =3D ASPEED_SGPIO_G4_CFG_OFFSET, +}; + +static void aspeed_sgpio_g7_reg_bit_set(struct aspeed_sgpio *gpio, unsigne= d int offset, + const enum aspeed_sgpio_reg reg, bool val) +{ + u32 mask =3D aspeed_sgpio_g7_reg_mask(reg); + void __iomem *addr =3D gpio->base + SGPIO_G7_CTRL_REG_OFFSET(offset >> 1); + u32 write_val; + + if (mask) { + write_val =3D (ioread32(addr) & ~(mask)) | field_prep(mask, val); + iowrite32(write_val, addr); + } +} + +static bool aspeed_sgpio_g7_reg_bit_get(struct aspeed_sgpio *gpio, unsigne= d int offset, + const enum aspeed_sgpio_reg reg) +{ + u32 mask =3D aspeed_sgpio_g7_reg_mask(reg); + void __iomem *addr; + + addr =3D gpio->base + SGPIO_G7_CTRL_REG_OFFSET(offset >> 1); + if (reg =3D=3D reg_val) + mask =3D SGPIO_G7_IN_DATA; + + if (mask) + return field_get(mask, ioread32(addr)); + else + return 0; +} + +static int aspeed_sgpio_g7_reg_bank_get(struct aspeed_sgpio *gpio, unsigne= d int offset, + const enum aspeed_sgpio_reg reg) +{ + void __iomem *addr; + + if (reg =3D=3D reg_irq_status) { + addr =3D gpio->base + SGPIO_G7_IRQ_STS_OFFSET(offset >> 6); + return ioread32(addr); + } else { + return -EOPNOTSUPP; + } +} + +static const struct aspeed_sgpio_llops aspeed_sgpio_g7_llops =3D { + .reg_bit_set =3D aspeed_sgpio_g7_reg_bit_set, + .reg_bit_get =3D aspeed_sgpio_g7_reg_bit_get, + .reg_bank_get =3D aspeed_sgpio_g7_reg_bank_get, +}; + +static const struct aspeed_sgpio_pdata ast2700_sgpiom_pdata =3D { + .pin_mask =3D GENMASK(11, 6), + .llops =3D &aspeed_sgpio_g7_llops, + .cfg_offset =3D ASPEED_SGPIO_G7_CFG_OFFSET, }; =20 static const struct of_device_id aspeed_sgpio_of_table[] =3D { { .compatible =3D "aspeed,ast2400-sgpio", .data =3D &ast2400_sgpio_pdata,= }, { .compatible =3D "aspeed,ast2500-sgpio", .data =3D &ast2400_sgpio_pdata,= }, { .compatible =3D "aspeed,ast2600-sgpiom", .data =3D &ast2600_sgpiom_pdat= a, }, + { .compatible =3D "aspeed,ast2700-sgpiom", .data =3D &ast2700_sgpiom_pdat= a, }, {} }; =20 @@ -562,7 +668,7 @@ static int aspeed_sgpio_probe(struct platform_device *p= dev) =20 gpio_cnt_regval =3D ((nr_gpios / 8) << ASPEED_SGPIO_PINS_SHIFT) & pin_mas= k; iowrite32(FIELD_PREP(ASPEED_SGPIO_CLK_DIV_MASK, sgpio_clk_div) | gpio_cnt= _regval | - ASPEED_SGPIO_ENABLE, gpio->base + ASPEED_SGPIO_CTRL); + ASPEED_SGPIO_ENABLE, gpio->base + gpio->pdata->cfg_offset); =20 raw_spin_lock_init(&gpio->lock); =20 --=20 2.34.1