pinctrl: starfive: Add StarFive JHB100 sys0 controller driver

Add pinctrl driver for StarFive JHB100 SoC System-0(sys0) pinctrl
controller.

Simultaneously add a generic pinctrl driver framework for registering
the pinctrl of other domains (sys1, sys2, and so on) in the JHB100 SoC.

Co-developed-by: Lianfeng Ouyang <lianfeng.ouyang@starfivetech.com>
Signed-off-by: Lianfeng Ouyang <lianfeng.ouyang@starfivetech.com>
Signed-off-by: Alex Soo <yuklin.soo@starfivetech.com>
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
Signed-off-by: Linus Walleij <linusw@kernel.org>
This commit is contained in:
Changhuang Liang 2026-09-10 03:03:39 -07:00 committed by Linus Walleij
parent 9d3dc8decb
commit 9c4d0c8fc4
6 changed files with 1750 additions and 0 deletions

View File

@ -26203,6 +26203,14 @@ S: Supported
F: Documentation/devicetree/bindings/interrupt-controller/starfive,jhb100-intc.yaml F: Documentation/devicetree/bindings/interrupt-controller/starfive,jhb100-intc.yaml
F: drivers/irqchip/irq-starfive-jhb100-intc.c F: drivers/irqchip/irq-starfive-jhb100-intc.c
STARFIVE JHB100 PINCTRL DRIVERS
M: Changhuang Liang <changhuang.liang@starfivetech.com>
M: Lianfeng Ouyang <lianfeng.ouyang@starfivetech.com>
L: linux-gpio@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/pinctrl/starfive,jhb1*.yaml
F: drivers/pinctrl/starfive/pinctrl-starfive-jhb1*
STATIC BRANCH/CALL STATIC BRANCH/CALL
M: Peter Zijlstra <peterz@infradead.org> M: Peter Zijlstra <peterz@infradead.org>
M: Josh Poimboeuf <jpoimboe@kernel.org> M: Josh Poimboeuf <jpoimboe@kernel.org>

View File

@ -47,3 +47,22 @@ config PINCTRL_STARFIVE_JH7110_AON
This also provides an interface to the GPIO pins not used by other This also provides an interface to the GPIO pins not used by other
peripherals supporting inputs, outputs, configuring pull-up/pull-down peripherals supporting inputs, outputs, configuring pull-up/pull-down
and interrupts on input changes. and interrupts on input changes.
config PINCTRL_STARFIVE_JHB100
bool
depends on OF
select GENERIC_PINCTRL
select GPIOLIB
select GPIOLIB_IRQCHIP
select OF_GPIO
config PINCTRL_STARFIVE_JHB100_SYS0
tristate "StarFive JHB100 SoC System-0 pinctrl and GPIO driver"
depends on ARCH_STARFIVE || COMPILE_TEST
select PINCTRL_STARFIVE_JHB100
default ARCH_STARFIVE
help
Say yes here to support system-0 pin control on the StarFive JHB100 SoC.
This also provides an interface to the GPIO pins not used by other
peripherals supporting inputs, outputs, configuring pull-up/pull-down
and interrupts on input changes.

View File

@ -5,3 +5,6 @@ obj-$(CONFIG_PINCTRL_STARFIVE_JH7100) += pinctrl-starfive-jh7100.o
obj-$(CONFIG_PINCTRL_STARFIVE_JH7110) += pinctrl-starfive-jh7110.o obj-$(CONFIG_PINCTRL_STARFIVE_JH7110) += pinctrl-starfive-jh7110.o
obj-$(CONFIG_PINCTRL_STARFIVE_JH7110_SYS) += pinctrl-starfive-jh7110-sys.o obj-$(CONFIG_PINCTRL_STARFIVE_JH7110_SYS) += pinctrl-starfive-jh7110-sys.o
obj-$(CONFIG_PINCTRL_STARFIVE_JH7110_AON) += pinctrl-starfive-jh7110-aon.o obj-$(CONFIG_PINCTRL_STARFIVE_JH7110_AON) += pinctrl-starfive-jh7110-aon.o
obj-$(CONFIG_PINCTRL_STARFIVE_JHB100) += pinctrl-starfive-jhb100.o
obj-$(CONFIG_PINCTRL_STARFIVE_JHB100_SYS0) += pinctrl-starfive-jhb100-sys0.o

View File

@ -0,0 +1,121 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Pinctrl / GPIO driver for StarFive JHB100 SoC System-0 domain
*
* Copyright (C) 2024 StarFive Technology Co., Ltd.
* Author: Alex Soo <yuklin.soo@starfivetech.com>
*
*/
#include <linux/platform_device.h>
#include "pinctrl-starfive-jhb100.h"
/* sys0 pad numbers */
#define PADNUM_SYS0_GPIO_A2 2
#define PADNUM_SYS0_GPIO_A3 3
static const struct jhb100_pin_layout_desc jhb100_sys0_pl_desc[] = {
{ .pin_start = 0, .pin_cnt = 3, .name = "gpio", .gpio_func_sel = 0, },
{ .pin_start = 3, .pin_cnt = 1, .name = "bmcpcierp_pe2rst_out", .gpio_func_sel = 1, },
{ .pin_start = 4, .pin_cnt = 1, .name = "testen", .gpio_func_sel = -1, },
{ .pin_start = 5, .pin_cnt = 1, .name = "syspok_in", .gpio_func_sel = -1, },
{ .pin_start = 6, .pin_cnt = 1, .name = "sysrstn_in", .gpio_func_sel = -1, },
{ .pin_start = 7, .pin_cnt = 1, .name = "perstn0_in", .gpio_func_sel = -1, },
{ .pin_start = 8, .pin_cnt = 1, .name = "perstn1_in", .gpio_func_sel = -1, },
{ .pin_start = 9, .pin_cnt = 1, .name = "aprstn_out", .gpio_func_sel = -1, },
{ .pin_start = 10, .pin_cnt = 1, .name = "pcierp_wake", .gpio_func_sel = -1, },
{ 0xff },
};
static const struct config_reg_layout_desc jhb100_sys0_pinctrl_crl_desc[] = {
{
.pin_start = 0,
.pin_cnt = 4,
.fields[PAD_CFG_DRIVE_STRENGTH_2BIT] = { .shift = 0, .width = 2 },
.fields[PAD_CFG_INPUT_ENABLE] = { .shift = 2, .width = 1 },
.fields[PAD_CFG_PULL_DOWN] = { .shift = 3, .width = 1 },
.fields[PAD_CFG_PULL_UP] = { .shift = 4, .width = 1 },
.fields[PAD_CFG_SLEW_RATE] = { .shift = 5, .width = 1 },
.fields[PAD_CFG_SCHMITT_TRIGGER_SELECT] = { .shift = 6, .width = 1 },
.fields[PAD_CFG_DEBOUNCE_WIDTH] = { .shift = 15, .width = 17 },
},
{
.pin_start = 4,
.pin_cnt = 5,
.fields[PAD_CFG_SCHMITT_TRIGGER_SELECT] = { .shift = 0, .width = 1 },
},
{
.pin_start = 9,
.pin_cnt = 1,
.fields[PAD_CFG_DRIVE_STRENGTH_2BIT] = { .shift = 0, .width = 2 },
.fields[PAD_CFG_SLEW_RATE] = { .shift = 2, .width = 1 },
},
{
.pin_start = 10,
.pin_cnt = 1,
.fields[PAD_CFG_DRIVE_STRENGTH_2BIT] = { .shift = 0, .width = 2 },
.fields[PAD_CFG_INPUT_ENABLE] = { .shift = 2, .width = 1 },
.fields[PAD_CFG_PULL_DOWN] = { .shift = 3, .width = 1 },
.fields[PAD_CFG_PULL_UP] = { .shift = 4, .width = 1 },
.fields[PAD_CFG_SLEW_RATE] = { .shift = 5, .width = 1 },
.fields[PAD_CFG_SCHMITT_TRIGGER_SELECT] = { .shift = 6, .width = 1 },
},
{ 0xff },
};
static const struct starfive_pinctrl_regs jhb100_sys0_pinctrl_regs = {
.func_sel = { .reg = 0x44, .width_per_pin = 2 },
.config = 0x0c,
.output = 0x38,
.output_en = 0x3c,
.gpio_status = 0x40,
.irq_en = 0x48,
.irq_status = 0x4c,
.irq_clr = 0x50,
.irq_trigger = 0x54,
.irq_level = 0x58,
.irq_both_edge = 0x5c,
.irq_edge = 0x60,
};
static const struct jhb100_pinctrl_func_maps jhb100_func_maps_sys0[] = {
{ .func = "auxpwrgood", .val = 1 },
{ .func = "gpio", .val = 0,
.max_pin = JHB100_FUNC_MAPS_MAX_PIN(PADNUM_SYS0_GPIO_A2) },
{ .func = "gpio", .val = 1,
.max_pin = JHB100_FUNC_MAPS_MAX_PIN(PADNUM_SYS0_GPIO_A3) },
{ .func = "hbled", .val = 1 },
{ .func = "pe2rst_out", .val = 0 },
};
static const struct jhb100_pinctrl_domain_info jhb100_sys0_pinctrl_info = {
.name = "jhb100-sys0",
.pl_desc = jhb100_sys0_pl_desc,
.crl_desc = jhb100_sys0_pinctrl_crl_desc,
.regs = &jhb100_sys0_pinctrl_regs,
.fmaps = jhb100_func_maps_sys0,
.num_maps = ARRAY_SIZE(jhb100_func_maps_sys0),
};
static const struct of_device_id jhb100_sys0_pinctrl_of_match[] = {
{
.compatible = "starfive,jhb100-sys0-pinctrl",
.data = &jhb100_sys0_pinctrl_info,
},
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, jhb100_sys0_pinctrl_of_match);
static struct platform_driver jhb100_sys0_pinctrl_driver = {
.probe = jhb100_pinctrl_probe,
.driver = {
.name = "starfive-jhb100-sys0-pinctrl",
.of_match_table = jhb100_sys0_pinctrl_of_match,
},
};
module_platform_driver(jhb100_sys0_pinctrl_driver);
MODULE_DESCRIPTION("Pinctrl driver for StarFive JHB100 SoC System-0 domain");
MODULE_AUTHOR("Alex Soo <yuklin.soo@starfivetech.com>");
MODULE_LICENSE("GPL");

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,153 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Pinctrl / GPIO driver for StarFive JHB100 SoC
*
* Copyright (C) 2024 StarFive Technology Co., Ltd.
* Author: Alex Soo <yuklin.soo@starfivetech.com>
*
*/
#ifndef __PINCTRL_STARFIVE_JHB100_H__
#define __PINCTRL_STARFIVE_JHB100_H__
#include <linux/gpio/driver.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinmux.h>
/* power-source value */
enum jhb100_pinvref {
JHB100_PINVREF_3_3V,
JHB100_PINVREF_2_5V,
JHB100_PINVREF_1_8V,
JHB100_PINVREF_NUM
};
#define JHB100_MAX_BANKS 2
struct jhb100_pin_layout_desc {
unsigned int pin_start;
unsigned int pin_cnt;
const char *name;
s8 gpio_func_sel;
};
struct jhb100_pinctrl {
struct device *dev;
struct gpio_chip gc;
unsigned int num_banks;
struct pinctrl_gpio_range gpios;
raw_spinlock_t lock;
const char *iodomain_name;
void __iomem *base;
struct pinctrl_dev *pctl;
/* register read/write mutex */
struct mutex mutex;
const struct jhb100_pinctrl_domain_info *info;
int irq;
struct irq_domain *irq_domain;
const struct pinctrl_pin_desc *pins;
unsigned int npins;
unsigned int ngpios;
s8 *gpio_func_sel_arr;
};
struct pinvref_desc {
unsigned int range;
u32 pin_grp[32];
u32 num_pins;
};
struct pinvref_reg {
unsigned int reg;
const struct pinvref_desc *pv_desc;
u32 num_pv;
};
struct gpio_irq_reg {
unsigned int reg;
unsigned int width_per_pin;
};
struct starfive_pinctrl_regs {
struct pinvref_reg vref;
struct gpio_irq_reg func_sel;
unsigned int config;
unsigned int output;
unsigned int output_en;
unsigned int gpio_status;
unsigned int irq_en;
unsigned int irq_status;
unsigned int irq_clr;
unsigned int irq_trigger;
unsigned int irq_level;
unsigned int irq_both_edge;
unsigned int irq_edge;
};
struct reg_layout_field {
unsigned char shift;
unsigned char width;
};
enum jhb100_pad_cfg_field {
PAD_CFG_DEBOUNCE_WIDTH,
PAD_CFG_DRIVE_STRENGTH_2BIT,
PAD_CFG_DRIVE_STRENGTH_3BIT,
PAD_CFG_INPUT_ENABLE,
PAD_CFG_VSEL,
PAD_CFG_MODE_SELECT,
PAD_CFG_OPEN_DRAIN_PULL_UP_SEL,
PAD_CFG_PULL_DOWN,
PAD_CFG_PULL_UP,
PAD_CFG_SCHMITT_TRIGGER_SELECT,
PAD_CFG_SLEW_RATE,
PAD_CFG_COUNT
};
#define RL_DESC_SUPPORTED(crl_desc, field_enum) ({ \
typeof(crl_desc) _desc = (crl_desc); \
(_desc && (_desc)->fields[(field_enum)].width > 0); \
})
#define RL_DESC_SHIFT(crl_desc, field_enum) ({ \
typeof(crl_desc) __desc = (crl_desc); \
(__desc)->fields[(field_enum)].shift; \
})
#define RL_DESC_GENMASK(crl_desc, field_enum) ({ \
typeof(crl_desc) __desc = (crl_desc); \
RL_DESC_SUPPORTED(__desc, field_enum) ? \
GENMASK( \
(__desc)->fields[(field_enum)].shift + (__desc)->fields[(field_enum)].width - 1, \
(__desc)->fields[(field_enum)].shift \
) : 0; \
})
struct config_reg_layout_desc {
unsigned int pin_start;
unsigned int pin_cnt;
struct reg_layout_field fields[PAD_CFG_COUNT];
};
#define JHB100_FUNC_MAPS_MAX_PIN(n) ((n) + 1)
struct jhb100_pinctrl_func_maps {
char *func;
unsigned char val;
u32 max_pin;
};
struct jhb100_pinctrl_domain_info {
const char *name;
const struct pinctrl_pin_desc *pins;
const struct jhb100_pin_layout_desc *pl_desc;
const struct jhb100_pinctrl_func_maps *fmaps;
u32 num_maps;
const struct config_reg_layout_desc *crl_desc;
const struct starfive_pinctrl_regs *regs;
};
int jhb100_pinctrl_probe(struct platform_device *pdev);
#endif /* __PINCTRL_STARFIVE_JHB100_H__ */