Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

pinctrl: spacemit: k3: adjust drive strength and schmitter trigger

K3 SoC expand drive strength to 4 bits which support even larger
settings table comparing to old SoC generation. Also schmitter trigger
setting is changed to 1 bit.

Signed-off-by: Yixun Lan <dlan@gentoo.org>
Signed-off-by: Linus Walleij <linusw@kernel.org>

authored by

Yixun Lan and committed by
Linus Walleij
3f20bdf7 7412311c

+116 -47
+116 -47
drivers/pinctrl/spacemit/pinctrl-k1.c
··· 24 24 #include "pinctrl-k1.h" 25 25 26 26 /* 27 - * +---------+----------+-----------+--------+--------+----------+--------+ 28 - * | pull | drive | schmitter | slew | edge | strong | mux | 29 - * | up/down | strength | trigger | rate | detect | pull | mode | 30 - * +---------+----------+-----------+--------+--------+----------+--------+ 31 - * 3 bits 3 bits 2 bits 1 bit 3 bits 1 bit 3 bits 27 + * | pull | drive | schmitter | slew | edge | strong | mux | 28 + * SoC | up/down | strength | trigger | rate | detect | pull | mode | 29 + *-----+---------+----------+-----------+-------+--------+--------+--------+ 30 + * K1 | 3 bits | 3 bits | 2 bits | 1 bit | 3 bits | 1 bit | 3 bits | 31 + *-----+---------+----------+-----------+-------+--------+--------+--------+ 32 + * K3 | 3 bits | 4 bits | 1 bits | 1 bit | 3 bits | 1 bit | 3 bits | 32 33 */ 33 34 34 35 #define PAD_MUX GENMASK(2, 0) ··· 39 38 #define PAD_EDGE_CLEAR BIT(6) 40 39 #define PAD_SLEW_RATE GENMASK(12, 11) 41 40 #define PAD_SLEW_RATE_EN BIT(7) 42 - #define PAD_SCHMITT GENMASK(9, 8) 43 - #define PAD_DRIVE GENMASK(12, 10) 41 + #define PAD_SCHMITT_K1 GENMASK(9, 8) 42 + #define PAD_DRIVE_K1 GENMASK(12, 10) 43 + #define PAD_SCHMITT_K3 BIT(8) 44 + #define PAD_DRIVE_K3 GENMASK(12, 9) 44 45 #define PAD_PULLDOWN BIT(13) 45 46 #define PAD_PULLUP BIT(14) 46 47 #define PAD_PULL_EN BIT(15) 48 + 49 + struct spacemit_pin_drv_strength { 50 + u8 val; 51 + u32 mA; 52 + }; 53 + 54 + struct spacemit_pinctrl_dconf { 55 + u64 schmitt_mask; 56 + u64 drive_mask; 57 + 58 + struct spacemit_pin_drv_strength *ds_1v8_tbl; 59 + size_t ds_1v8_tbl_num; 60 + struct spacemit_pin_drv_strength *ds_3v3_tbl; 61 + size_t ds_3v3_tbl_num; 62 + }; 47 63 48 64 struct spacemit_pin { 49 65 u16 pin; ··· 85 67 const struct spacemit_pin *data; 86 68 u16 npins; 87 69 unsigned int (*pin_to_offset)(unsigned int pin); 70 + const struct spacemit_pinctrl_dconf *dconf; 88 71 }; 89 72 90 73 struct spacemit_pin_mux_config { 91 74 const struct spacemit_pin *pin; 92 75 u32 config; 93 - }; 94 - 95 - struct spacemit_pin_drv_strength { 96 - u8 val; 97 - u32 mA; 98 76 }; 99 77 100 78 /* map pin id to pinctrl register offset, refer MFPR definition */ ··· 207 193 seq_printf(seq, "mux: %ld reg: 0x%04x", (value & PAD_MUX), value); 208 194 } 209 195 210 - /* use IO high level output current as the table */ 211 - static struct spacemit_pin_drv_strength spacemit_ds_1v8_tbl[4] = { 212 - { 0, 11 }, 213 - { 2, 21 }, 214 - { 4, 32 }, 215 - { 6, 42 }, 196 + static const struct spacemit_pinctrl_dconf k1_drive_conf = { 197 + .drive_mask = PAD_DRIVE_K1, 198 + .schmitt_mask = PAD_SCHMITT_K1, 199 + .ds_1v8_tbl = (struct spacemit_pin_drv_strength[]) { 200 + { 0, 11 }, 201 + { 2, 21 }, 202 + { 4, 32 }, 203 + { 6, 42 }, 204 + }, 205 + .ds_1v8_tbl_num = 4, 206 + .ds_3v3_tbl = (struct spacemit_pin_drv_strength[]) { 207 + { 0, 7 }, 208 + { 2, 10 }, 209 + { 4, 13 }, 210 + { 6, 16 }, 211 + { 1, 19 }, 212 + { 3, 23 }, 213 + { 5, 26 }, 214 + { 7, 29 }, 215 + }, 216 + .ds_3v3_tbl_num = 8, 216 217 }; 217 218 218 - static struct spacemit_pin_drv_strength spacemit_ds_3v3_tbl[8] = { 219 - { 0, 7 }, 220 - { 2, 10 }, 221 - { 4, 13 }, 222 - { 6, 16 }, 223 - { 1, 19 }, 224 - { 3, 23 }, 225 - { 5, 26 }, 226 - { 7, 29 }, 219 + static const struct spacemit_pinctrl_dconf k3_drive_conf = { 220 + .drive_mask = PAD_DRIVE_K3, 221 + .schmitt_mask = PAD_SCHMITT_K3, 222 + .ds_1v8_tbl = (struct spacemit_pin_drv_strength[]) { 223 + { 0, 2 }, 224 + { 1, 4 }, 225 + { 2, 6 }, 226 + { 3, 7 }, 227 + { 4, 9 }, 228 + { 5, 11 }, 229 + { 6, 13 }, 230 + { 7, 14 }, 231 + { 8, 21 }, 232 + { 9, 23 }, 233 + { 10, 25 }, 234 + { 11, 26 }, 235 + { 12, 28 }, 236 + { 13, 30 }, 237 + { 14, 31 }, 238 + { 15, 33 }, 239 + }, 240 + .ds_1v8_tbl_num = 16, 241 + .ds_3v3_tbl = (struct spacemit_pin_drv_strength[]) { 242 + { 0, 3 }, 243 + { 1, 5 }, 244 + { 2, 7 }, 245 + { 3, 9 }, 246 + { 4, 11 }, 247 + { 5, 13 }, 248 + { 6, 15 }, 249 + { 7, 17 }, 250 + { 8, 25 }, 251 + { 9, 27 }, 252 + { 10, 29 }, 253 + { 11, 31 }, 254 + { 12, 33 }, 255 + { 13, 35 }, 256 + { 14, 37 }, 257 + { 15, 38 }, 258 + }, 259 + .ds_3v3_tbl_num = 16, 227 260 }; 228 261 229 262 static inline u8 spacemit_get_ds_value(struct spacemit_pin_drv_strength *tbl, ··· 298 237 } 299 238 300 239 static inline u8 spacemit_get_driver_strength(enum spacemit_pin_io_type type, 240 + const struct spacemit_pinctrl_dconf *dconf, 301 241 u32 mA) 302 242 { 303 243 switch (type) { 304 244 case IO_TYPE_1V8: 305 - return spacemit_get_ds_value(spacemit_ds_1v8_tbl, 306 - ARRAY_SIZE(spacemit_ds_1v8_tbl), 245 + return spacemit_get_ds_value(dconf->ds_1v8_tbl, 246 + dconf->ds_1v8_tbl_num, 307 247 mA); 308 248 case IO_TYPE_3V3: 309 - return spacemit_get_ds_value(spacemit_ds_3v3_tbl, 310 - ARRAY_SIZE(spacemit_ds_3v3_tbl), 249 + return spacemit_get_ds_value(dconf->ds_3v3_tbl, 250 + dconf->ds_3v3_tbl_num, 311 251 mA); 312 252 default: 313 253 return 0; ··· 316 254 } 317 255 318 256 static inline u32 spacemit_get_drive_strength_mA(enum spacemit_pin_io_type type, 257 + const struct spacemit_pinctrl_dconf *dconf, 319 258 u32 value) 320 259 { 321 260 switch (type) { 322 261 case IO_TYPE_1V8: 323 - return spacemit_get_ds_mA(spacemit_ds_1v8_tbl, 324 - ARRAY_SIZE(spacemit_ds_1v8_tbl), 325 - value & 0x6); 262 + return spacemit_get_ds_mA(dconf->ds_1v8_tbl, 263 + dconf->ds_1v8_tbl_num, 264 + value); 326 265 case IO_TYPE_3V3: 327 - return spacemit_get_ds_mA(spacemit_ds_3v3_tbl, 328 - ARRAY_SIZE(spacemit_ds_3v3_tbl), 266 + return spacemit_get_ds_mA(dconf->ds_3v3_tbl, 267 + dconf->ds_3v3_tbl_num, 329 268 value); 330 269 default: 331 270 return 0; ··· 573 510 #define ENABLE_DRV_STRENGTH BIT(1) 574 511 #define ENABLE_SLEW_RATE BIT(2) 575 512 static int spacemit_pinconf_generate_config(const struct spacemit_pin *spin, 513 + const struct spacemit_pinctrl_dconf *dconf, 576 514 unsigned long *configs, 577 515 unsigned int num_configs, 578 516 u32 *value) ··· 611 547 drv_strength = arg; 612 548 break; 613 549 case PIN_CONFIG_INPUT_SCHMITT: 614 - v &= ~PAD_SCHMITT; 615 - v |= FIELD_PREP(PAD_SCHMITT, arg); 550 + v &= ~dconf->schmitt_mask; 551 + v |= (arg << __ffs(dconf->schmitt_mask)) & dconf->schmitt_mask; 616 552 break; 617 553 case PIN_CONFIG_POWER_SOURCE: 618 554 voltage = arg; ··· 648 584 } 649 585 } 650 586 651 - val = spacemit_get_driver_strength(type, drv_strength); 587 + val = spacemit_get_driver_strength(type, dconf, drv_strength); 652 588 653 - v &= ~PAD_DRIVE; 654 - v |= FIELD_PREP(PAD_DRIVE, val); 589 + v &= ~dconf->drive_mask; 590 + v |= (val << __ffs(dconf->drive_mask)) & dconf->drive_mask; 655 591 } 656 592 657 593 if (flag & ENABLE_SLEW_RATE) { ··· 701 637 const struct spacemit_pin *spin = spacemit_get_pin(pctrl, pin); 702 638 u32 value; 703 639 704 - if (spacemit_pinconf_generate_config(spin, configs, num_configs, &value)) 640 + if (spacemit_pinconf_generate_config(spin, pctrl->data->dconf, 641 + configs, num_configs, &value)) 705 642 return -EINVAL; 706 643 707 644 return spacemit_pin_set_config(pctrl, pin, value); ··· 724 659 return -EINVAL; 725 660 726 661 spin = spacemit_get_pin(pctrl, group->grp.pins[0]); 727 - if (spacemit_pinconf_generate_config(spin, configs, num_configs, &value)) 662 + if (spacemit_pinconf_generate_config(spin, pctrl->data->dconf, 663 + configs, num_configs, &value)) 728 664 return -EINVAL; 729 665 730 666 for (i = 0; i < group->grp.npins; i++) ··· 759 693 struct seq_file *seq, unsigned int pin) 760 694 { 761 695 struct spacemit_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 696 + const struct spacemit_pinctrl_dconf *dconf = pctrl->data->dconf; 762 697 const struct spacemit_pin *spin = spacemit_get_pin(pctrl, pin); 763 698 enum spacemit_pin_io_type type = spacemit_to_pin_io_type(spin); 764 699 void __iomem *reg = spacemit_pin_to_reg(pctrl, pin); ··· 770 703 771 704 seq_printf(seq, ", io type (%s)", io_type_desc[type]); 772 705 773 - tmp = FIELD_GET(PAD_DRIVE, value); 706 + tmp = (value & dconf->drive_mask) >> __ffs(dconf->drive_mask); 774 707 if (type == IO_TYPE_1V8 || type == IO_TYPE_3V3) { 775 - mA = spacemit_get_drive_strength_mA(type, tmp); 708 + mA = spacemit_get_drive_strength_mA(type, dconf, tmp); 776 709 seq_printf(seq, ", drive strength (%d mA)", mA); 777 710 } 778 711 779 712 /* drive strength depend on power source, so show all values */ 780 713 if (type == IO_TYPE_EXTERNAL) 781 714 seq_printf(seq, ", drive strength (%d or %d mA)", 782 - spacemit_get_drive_strength_mA(IO_TYPE_1V8, tmp), 783 - spacemit_get_drive_strength_mA(IO_TYPE_3V3, tmp)); 715 + spacemit_get_drive_strength_mA(IO_TYPE_1V8, dconf, tmp), 716 + spacemit_get_drive_strength_mA(IO_TYPE_3V3, dconf, tmp)); 784 717 785 718 seq_printf(seq, ", register (0x%04x)", value); 786 719 } ··· 1118 1051 .data = k1_pin_data, 1119 1052 .npins = ARRAY_SIZE(k1_pin_desc), 1120 1053 .pin_to_offset = spacemit_k1_pin_to_offset, 1054 + .dconf = &k1_drive_conf, 1121 1055 }; 1122 1056 1123 1057 static const struct pinctrl_pin_desc k3_pin_desc[] = { ··· 1455 1387 .data = k3_pin_data, 1456 1388 .npins = ARRAY_SIZE(k3_pin_desc), 1457 1389 .pin_to_offset = spacemit_k3_pin_to_offset, 1390 + .dconf = &k3_drive_conf, 1458 1391 }; 1459 1392 1460 1393 static const struct of_device_id k1_pinctrl_ids[] = {