Skip to content

Commit c0cfa3a

Browse files
AntonioBorneoLinus Walleij
authored andcommitted
pinctrl: stm32: Support I/O synchronization parameters
Devices in the stm32mp2xx family include an I/O synchronization block on each pin that is used to fine tune and improve the I/O timing margins of high speed synchronous interfaces. It can be configured to provide independently for each pin: - skew rate on input direction or latch delay on output direction; - inversion of clock signals or re-sampling of data signals. Add support for the generic properties: - skew-delay-input-ps; - skew-delay-output-ps. Add support for the property 'st,io-sync' to configure clock inversion or data re-sampling mode. Show the new parameters on debugfs pinconf-pins. Enable it for the stm32mp257 pinctrl driver. Co-developed-by: Valentin Caron <valentin.caron@foss.st.com> Signed-off-by: Valentin Caron <valentin.caron@foss.st.com> Co-developed-by: Fabien Dessenne <fabien.dessenne@foss.st.com> Signed-off-by: Fabien Dessenne <fabien.dessenne@foss.st.com> Signed-off-by: Antonio Borneo <antonio.borneo@foss.st.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
1 parent 78a3ce9 commit c0cfa3a

3 files changed

Lines changed: 258 additions & 0 deletions

File tree

drivers/pinctrl/stm32/pinctrl-stm32.c

Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,23 @@
5151
#define STM32_GPIO_AFRL 0x20
5252
#define STM32_GPIO_AFRH 0x24
5353
#define STM32_GPIO_SECCFGR 0x30
54+
#define STM32_GPIO_DELAYRL 0x40
55+
#define STM32_GPIO_ADVCFGRL 0x48
5456
#define STM32_GPIO_CIDCFGR(x) (0x50 + (0x8 * (x)))
5557
#define STM32_GPIO_SEMCR(x) (0x54 + (0x8 * (x)))
5658

59+
/* Unitary delay for STM32_GPIO_DELAYRL */
60+
#define STM32_GPIO_DELAYRL_PS 250
61+
62+
#define STM32_GPIO_ADVCFGR_DLYPATH_MASK BIT(0)
63+
#define STM32_GPIO_ADVCFGR_DE_MASK BIT(1)
64+
#define STM32_GPIO_ADVCFGR_INVCLK_MASK BIT(2)
65+
#define STM32_GPIO_ADVCFGR_RET_MASK BIT(3)
66+
#define STM32_GPIO_ADVCFGR_IO_SYNC_MASK \
67+
(STM32_GPIO_ADVCFGR_DE_MASK \
68+
| STM32_GPIO_ADVCFGR_INVCLK_MASK \
69+
| STM32_GPIO_ADVCFGR_RET_MASK)
70+
5771
#define STM32_GPIO_CIDCFGR_CFEN BIT(0)
5872
#define STM32_GPIO_CIDCFGR_SEMEN BIT(1)
5973
#define STM32_GPIO_CIDCFGR_SCID_MASK GENMASK(5, 4)
@@ -67,6 +81,9 @@
6781

6882
#define SYSCFG_IRQMUX_MASK GENMASK(3, 0)
6983

84+
/* Vendor specific pin configuration */
85+
#define STM32_GPIO_PIN_CONFIG_IO_SYNC (PIN_CONFIG_END + 1)
86+
7087
#define gpio_range_to_bank(chip) \
7188
container_of(chip, struct stm32_gpio_bank, range)
7289

@@ -82,6 +99,32 @@ static const char * const stm32_gpio_functions[] = {
8299
"reserved",
83100
};
84101

102+
static const char * const stm32_gpio_io_sync[] = {
103+
"pass-through",
104+
"clock inverted",
105+
"data on rising edge",
106+
"data on falling edge",
107+
"data on both edges",
108+
};
109+
110+
static u8 io_sync_2_advcfgr[] = {
111+
/* data or clock GPIO pass-through */
112+
[0] = 0,
113+
/* clock GPIO inverted */
114+
[1] = STM32_GPIO_ADVCFGR_INVCLK_MASK,
115+
/* data GPIO re-sampled on clock rising edge */
116+
[2] = STM32_GPIO_ADVCFGR_RET_MASK,
117+
/* data GPIO re-sampled on clock falling edge */
118+
[3] = STM32_GPIO_ADVCFGR_RET_MASK | STM32_GPIO_ADVCFGR_INVCLK_MASK,
119+
/* data GPIO re-sampled on both clock edges */
120+
[4] = STM32_GPIO_ADVCFGR_RET_MASK | STM32_GPIO_ADVCFGR_DE_MASK,
121+
};
122+
123+
static const struct pinconf_generic_params stm32_gpio_bindings[] = {
124+
{"st,io-sync", STM32_GPIO_PIN_CONFIG_IO_SYNC, 0,
125+
stm32_gpio_io_sync, ARRAY_SIZE(stm32_gpio_io_sync)},
126+
};
127+
85128
struct stm32_pinctrl_group {
86129
const char *name;
87130
unsigned long config;
@@ -95,6 +138,8 @@ struct stm32_pin_backup {
95138
unsigned int speed:2;
96139
unsigned int drive:1;
97140
unsigned int value:1;
141+
unsigned int advcfg:4;
142+
unsigned int skew_delay:4;
98143
};
99144

100145
struct stm32_gpio_bank {
@@ -110,6 +155,7 @@ struct stm32_gpio_bank {
110155
struct stm32_pin_backup pin_backup[STM32_GPIO_PINS_PER_BANK];
111156
u8 irq_type[STM32_GPIO_PINS_PER_BANK];
112157
bool secure_control;
158+
bool io_sync_control;
113159
bool rif_control;
114160
};
115161

@@ -201,6 +247,21 @@ static void stm32_gpio_backup_bias(struct stm32_gpio_bank *bank, u32 offset,
201247
bank->pin_backup[offset].bias = bias;
202248
}
203249

250+
static void stm32_gpio_backup_advcfg(struct stm32_gpio_bank *bank, u32 offset, u32 mask, u32 value)
251+
{
252+
u32 val;
253+
254+
val = bank->pin_backup[offset].advcfg;
255+
val &= ~mask;
256+
val |= value & mask;
257+
bank->pin_backup[offset].advcfg = val;
258+
}
259+
260+
static void stm32_gpio_backup_skew_delay(struct stm32_gpio_bank *bank, u32 offset, u32 delay)
261+
{
262+
bank->pin_backup[offset].skew_delay = delay;
263+
}
264+
204265
/* RIF functions */
205266

206267
static bool stm32_gpio_rif_valid(struct stm32_gpio_bank *bank, unsigned int gpio_nr)
@@ -1145,6 +1206,155 @@ static u32 stm32_pconf_get_bias(struct stm32_gpio_bank *bank,
11451206
return (val >> (offset * 2));
11461207
}
11471208

1209+
static void
1210+
stm32_pconf_set_advcfgr_nolock(struct stm32_gpio_bank *bank, int offset, u32 mask, u32 value)
1211+
{
1212+
int advcfgr_offset = STM32_GPIO_ADVCFGRL + (offset / 8) * 4;
1213+
int advcfgr_shift = (offset % 8) * 4;
1214+
u32 val;
1215+
1216+
val = readl_relaxed(bank->base + advcfgr_offset);
1217+
val &= ~(mask << advcfgr_shift);
1218+
val |= (value & mask) << advcfgr_shift;
1219+
writel_relaxed(val, bank->base + advcfgr_offset);
1220+
1221+
stm32_gpio_backup_advcfg(bank, offset, mask, value);
1222+
}
1223+
1224+
static int stm32_pconf_set_advcfgr(struct stm32_gpio_bank *bank, int offset, u32 mask, u32 value)
1225+
{
1226+
struct stm32_pinctrl *pctl = dev_get_drvdata(bank->gpio_chip.parent);
1227+
unsigned long flags;
1228+
int err = 0;
1229+
1230+
if (!bank->io_sync_control)
1231+
return -ENOTSUPP;
1232+
1233+
spin_lock_irqsave(&bank->lock, flags);
1234+
1235+
if (pctl->hwlock) {
1236+
err = hwspin_lock_timeout_in_atomic(pctl->hwlock, HWSPNLCK_TIMEOUT);
1237+
if (err) {
1238+
dev_err(pctl->dev, "Can't get hwspinlock\n");
1239+
goto unlock;
1240+
}
1241+
}
1242+
1243+
stm32_pconf_set_advcfgr_nolock(bank, offset, mask, value);
1244+
1245+
if (pctl->hwlock)
1246+
hwspin_unlock_in_atomic(pctl->hwlock);
1247+
1248+
unlock:
1249+
spin_unlock_irqrestore(&bank->lock, flags);
1250+
1251+
return err;
1252+
}
1253+
1254+
static u32 stm32_pconf_get_advcfgr(struct stm32_gpio_bank *bank, int offset, u32 mask)
1255+
{
1256+
int advcfgr_offset = STM32_GPIO_ADVCFGRL + (offset / 8) * 4;
1257+
int advcfgr_shift = (offset % 8) * 4;
1258+
u32 val;
1259+
1260+
if (!bank->io_sync_control)
1261+
return 0;
1262+
1263+
val = readl_relaxed(bank->base + advcfgr_offset);
1264+
val >>= advcfgr_shift;
1265+
1266+
return val & mask;
1267+
}
1268+
1269+
static int stm32_pconf_set_io_sync(struct stm32_gpio_bank *bank, int offset, u32 io_sync)
1270+
{
1271+
if (io_sync >= ARRAY_SIZE(io_sync_2_advcfgr))
1272+
return -EINVAL;
1273+
1274+
return stm32_pconf_set_advcfgr(bank, offset, STM32_GPIO_ADVCFGR_IO_SYNC_MASK,
1275+
io_sync_2_advcfgr[io_sync]);
1276+
}
1277+
1278+
static const char *stm32_pconf_get_io_sync_str(struct stm32_gpio_bank *bank, int offset)
1279+
{
1280+
u32 io_sync = stm32_pconf_get_advcfgr(bank, offset, STM32_GPIO_ADVCFGR_IO_SYNC_MASK);
1281+
1282+
if (io_sync & STM32_GPIO_ADVCFGR_RET_MASK) {
1283+
if (io_sync & STM32_GPIO_ADVCFGR_DE_MASK)
1284+
return "data GPIO re-sampled on both clock edges";
1285+
1286+
if (io_sync & STM32_GPIO_ADVCFGR_INVCLK_MASK)
1287+
return "data GPIO re-sampled on clock falling edge";
1288+
1289+
return "data GPIO re-sampled on clock rising edge";
1290+
}
1291+
1292+
if (io_sync & STM32_GPIO_ADVCFGR_INVCLK_MASK)
1293+
return "clock GPIO inverted";
1294+
1295+
return NULL;
1296+
}
1297+
1298+
static int
1299+
stm32_pconf_set_skew_delay(struct stm32_gpio_bank *bank, int offset, u32 delay, bool is_dir_input)
1300+
{
1301+
struct stm32_pinctrl *pctl = dev_get_drvdata(bank->gpio_chip.parent);
1302+
int delay_offset = STM32_GPIO_DELAYRL + (offset / 8) * 4;
1303+
int delay_shift = (offset % 8) * 4;
1304+
unsigned long flags;
1305+
int err = 0;
1306+
u32 val;
1307+
1308+
if (!bank->io_sync_control)
1309+
return -ENOTSUPP;
1310+
1311+
spin_lock_irqsave(&bank->lock, flags);
1312+
1313+
if (pctl->hwlock) {
1314+
err = hwspin_lock_timeout_in_atomic(pctl->hwlock, HWSPNLCK_TIMEOUT);
1315+
if (err) {
1316+
dev_err(pctl->dev, "Can't get hwspinlock\n");
1317+
goto unlock;
1318+
}
1319+
}
1320+
1321+
val = readl_relaxed(bank->base + delay_offset);
1322+
val &= ~GENMASK(delay_shift + 3, delay_shift);
1323+
val |= (delay << delay_shift);
1324+
writel_relaxed(val, bank->base + delay_offset);
1325+
1326+
stm32_gpio_backup_skew_delay(bank, offset, delay);
1327+
1328+
stm32_pconf_set_advcfgr_nolock(bank, offset, STM32_GPIO_ADVCFGR_DLYPATH_MASK,
1329+
is_dir_input ? STM32_GPIO_ADVCFGR_DLYPATH_MASK : 0);
1330+
1331+
if (pctl->hwlock)
1332+
hwspin_unlock_in_atomic(pctl->hwlock);
1333+
1334+
unlock:
1335+
spin_unlock_irqrestore(&bank->lock, flags);
1336+
1337+
return err;
1338+
}
1339+
1340+
static u32 stm32_pconf_get_skew_delay_val(struct stm32_gpio_bank *bank, int offset)
1341+
{
1342+
int delay_offset = STM32_GPIO_DELAYRL + (offset / 8) * 4;
1343+
int delay_shift = (offset % 8) * 4;
1344+
u32 val;
1345+
1346+
val = readl_relaxed(bank->base + delay_offset);
1347+
val &= GENMASK(delay_shift + 3, delay_shift);
1348+
1349+
return val >> delay_shift;
1350+
}
1351+
1352+
static const char *stm32_pconf_get_skew_dir_str(struct stm32_gpio_bank *bank, int offset)
1353+
{
1354+
return stm32_pconf_get_advcfgr(bank, offset, STM32_GPIO_ADVCFGR_DLYPATH_MASK) ?
1355+
"input" : "output";
1356+
}
1357+
11481358
static bool stm32_pconf_get(struct stm32_gpio_bank *bank,
11491359
unsigned int offset, bool dir)
11501360
{
@@ -1207,6 +1417,17 @@ static int stm32_pconf_parse_conf(struct pinctrl_dev *pctldev,
12071417
__stm32_gpio_set(bank, offset, arg);
12081418
ret = stm32_pmx_gpio_set_direction(pctldev, range, pin, false);
12091419
break;
1420+
case PIN_CONFIG_SKEW_DELAY_INPUT_PS:
1421+
arg /= STM32_GPIO_DELAYRL_PS;
1422+
ret = stm32_pconf_set_skew_delay(bank, offset, arg, true);
1423+
break;
1424+
case PIN_CONFIG_SKEW_DELAY_OUTPUT_PS:
1425+
arg /= STM32_GPIO_DELAYRL_PS;
1426+
ret = stm32_pconf_set_skew_delay(bank, offset, arg, false);
1427+
break;
1428+
case STM32_GPIO_PIN_CONFIG_IO_SYNC:
1429+
ret = stm32_pconf_set_io_sync(bank, offset, arg);
1430+
break;
12101431
default:
12111432
ret = -ENOTSUPP;
12121433
}
@@ -1349,6 +1570,22 @@ static void stm32_pconf_dbg_show(struct pinctrl_dev *pctldev,
13491570
case 3:
13501571
break;
13511572
}
1573+
1574+
if (bank->io_sync_control) {
1575+
const char *io_sync_str, *skew_dir_str;
1576+
u32 skew_delay;
1577+
1578+
io_sync_str = stm32_pconf_get_io_sync_str(bank, offset);
1579+
skew_dir_str = stm32_pconf_get_skew_dir_str(bank, offset);
1580+
skew_delay = stm32_pconf_get_skew_delay_val(bank, offset);
1581+
1582+
if (io_sync_str)
1583+
seq_printf(s, " - IO-sync: %s", io_sync_str);
1584+
1585+
if (skew_delay)
1586+
seq_printf(s, " - Skew-delay: %u (%u ps) %s", skew_delay,
1587+
skew_delay * STM32_GPIO_DELAYRL_PS, skew_dir_str);
1588+
}
13521589
}
13531590

13541591
static const struct pinconf_ops stm32_pconf_ops = {
@@ -1441,6 +1678,7 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode
14411678
bank->bank_nr = bank_nr;
14421679
bank->bank_ioport_nr = bank_ioport_nr;
14431680
bank->secure_control = pctl->match_data->secure_control;
1681+
bank->io_sync_control = pctl->match_data->io_sync_control;
14441682
bank->rif_control = pctl->match_data->rif_control;
14451683
spin_lock_init(&bank->lock);
14461684

@@ -1683,6 +1921,8 @@ int stm32_pctl_probe(struct platform_device *pdev)
16831921
pctl->pctl_desc.confops = &stm32_pconf_ops;
16841922
pctl->pctl_desc.pctlops = &stm32_pctrl_ops;
16851923
pctl->pctl_desc.pmxops = &stm32_pmx_ops;
1924+
pctl->pctl_desc.num_custom_params = ARRAY_SIZE(stm32_gpio_bindings);
1925+
pctl->pctl_desc.custom_params = stm32_gpio_bindings;
16861926
pctl->dev = &pdev->dev;
16871927

16881928
pctl->pctl_dev = devm_pinctrl_register(&pdev->dev, &pctl->pctl_desc,
@@ -1804,6 +2044,21 @@ static int __maybe_unused stm32_pinctrl_restore_gpio_regs(
18042044
if (ret)
18052045
return ret;
18062046

2047+
if (bank->io_sync_control) {
2048+
bool is_input = bank->pin_backup[offset].advcfg & STM32_GPIO_ADVCFGR_DLYPATH_MASK;
2049+
2050+
ret = stm32_pconf_set_skew_delay(bank, offset,
2051+
bank->pin_backup[offset].skew_delay,
2052+
is_input);
2053+
if (ret)
2054+
return ret;
2055+
2056+
ret = stm32_pconf_set_advcfgr(bank, offset, STM32_GPIO_ADVCFGR_IO_SYNC_MASK,
2057+
bank->pin_backup[offset].advcfg);
2058+
if (ret)
2059+
return ret;
2060+
}
2061+
18072062
if (pin_is_irq)
18082063
regmap_field_write(pctl->irqmux[offset], bank->bank_ioport_nr);
18092064

drivers/pinctrl/stm32/pinctrl-stm32.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ struct stm32_pinctrl_match_data {
6464
const struct stm32_desc_pin *pins;
6565
const unsigned int npins;
6666
bool secure_control;
67+
bool io_sync_control;
6768
bool rif_control;
6869
};
6970

drivers/pinctrl/stm32/pinctrl-stm32mp257.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2543,13 +2543,15 @@ static const struct stm32_desc_pin stm32mp257_z_pins[] = {
25432543
static struct stm32_pinctrl_match_data stm32mp257_match_data = {
25442544
.pins = stm32mp257_pins,
25452545
.npins = ARRAY_SIZE(stm32mp257_pins),
2546+
.io_sync_control = true,
25462547
.secure_control = true,
25472548
.rif_control = true,
25482549
};
25492550

25502551
static struct stm32_pinctrl_match_data stm32mp257_z_match_data = {
25512552
.pins = stm32mp257_z_pins,
25522553
.npins = ARRAY_SIZE(stm32mp257_z_pins),
2554+
.io_sync_control = true,
25532555
.secure_control = true,
25542556
.rif_control = true,
25552557
};

0 commit comments

Comments
 (0)