uboot/drivers/pinctrl/pinctrl-kendryte.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2020 Sean Anderson <seanga2@gmail.com>
   4 */
   5
   6#include <common.h>
   7#include <clk.h>
   8#include <dm.h>
   9#include <dm/pinctrl.h>
  10#include <dt-bindings/pinctrl/k210-pinctrl.h>
  11#include <mapmem.h>
  12#include <regmap.h>
  13#include <syscon.h>
  14#include <asm/io.h>
  15#include <linux/err.h>
  16#include <linux/bitfield.h>
  17#include <linux/bitops.h>
  18
  19/*
  20 * The K210 only implements 8 drive levels, even though there is register space
  21 * for 16
  22 */
  23#define K210_PC_DRIVE_MASK GENMASK(11, 8)
  24#define K210_PC_DRIVE_SHIFT 8
  25#define K210_PC_DRIVE_0 (0 << K210_PC_DRIVE_SHIFT)
  26#define K210_PC_DRIVE_1 (1 << K210_PC_DRIVE_SHIFT)
  27#define K210_PC_DRIVE_2 (2 << K210_PC_DRIVE_SHIFT)
  28#define K210_PC_DRIVE_3 (3 << K210_PC_DRIVE_SHIFT)
  29#define K210_PC_DRIVE_4 (4 << K210_PC_DRIVE_SHIFT)
  30#define K210_PC_DRIVE_5 (5 << K210_PC_DRIVE_SHIFT)
  31#define K210_PC_DRIVE_6 (6 << K210_PC_DRIVE_SHIFT)
  32#define K210_PC_DRIVE_7 (7 << K210_PC_DRIVE_SHIFT)
  33#define K210_PC_DRIVE_MAX 7
  34
  35#define K210_PC_MODE_MASK GENMASK(23, 12)
  36/*
  37 * output enabled == PC_OE & (PC_OE_INV ^ FUNCTION_OE) where FUNCTION_OE is a
  38 * physical signal from the function
  39 */
  40#define K210_PC_OE       BIT(12) /* Output Enable */
  41#define K210_PC_OE_INV   BIT(13) /* INVert function-controlled Output Enable */
  42#define K210_PC_DO_OE    BIT(14) /* set Data Out to the Output Enable signal */
  43#define K210_PC_DO_INV   BIT(15) /* INVert final Data Output */
  44#define K210_PC_PU       BIT(16) /* Pull Up */
  45#define K210_PC_PD       BIT(17) /* Pull Down */
  46/* Strong pull up not implemented on K210 */
  47#define K210_PC_SL       BIT(19) /* reduce SLew rate to prevent overshoot */
  48/* Same semantics as OE above */
  49#define K210_PC_IE       BIT(20) /* Input Enable */
  50#define K210_PC_IE_INV   BIT(21) /* INVert function-controlled Input Enable */
  51#define K210_PC_DI_INV   BIT(22) /* INVert Data Input */
  52#define K210_PC_ST       BIT(23) /* Schmitt Trigger */
  53#define K210_PC_DI       BIT(31) /* raw Data Input */
  54#define K210_PC_BIAS_MASK (K210_PC_PU & K210_PC_PD)
  55
  56#define K210_PC_MODE_IN   (K210_PC_IE | K210_PC_ST)
  57#define K210_PC_MODE_OUT  (K210_PC_DRIVE_7 | K210_PC_OE)
  58#define K210_PC_MODE_I2C  (K210_PC_MODE_IN | K210_PC_SL | K210_PC_OE | \
  59                           K210_PC_PU)
  60#define K210_PC_MODE_SCCB (K210_PC_MODE_I2C | K210_PC_OE_INV | K210_PC_IE_INV)
  61#define K210_PC_MODE_SPI  (K210_PC_MODE_IN | K210_PC_IE_INV | \
  62                           K210_PC_MODE_OUT | K210_PC_OE_INV)
  63#define K210_PC_MODE_GPIO (K210_PC_MODE_IN | K210_PC_MODE_OUT)
  64
  65#define K210_PG_FUNC GENMASK(7, 0)
  66#define K210_PG_DO BIT(8)
  67#define K210_PG_PIN GENMASK(22, 16)
  68
  69#define PIN_CONFIG_OUTPUT_INVERT (PIN_CONFIG_END + 1)
  70#define PIN_CONFIG_INPUT_INVERT (PIN_CONFIG_END + 2)
  71
  72struct k210_fpioa {
  73        u32 pins[48];
  74        u32 tie_en[8];
  75        u32 tie_val[8];
  76};
  77
  78struct k210_pc_priv {
  79        struct clk clk;
  80        struct k210_fpioa __iomem *fpioa; /* FPIOA register */
  81        struct regmap *sysctl; /* Sysctl regmap */
  82        u32 power_offset; /* Power bank register offset */
  83};
  84
  85#ifdef CONFIG_CMD_PINMUX
  86static const char k210_pc_pin_names[][6] = {
  87#define PIN(i) \
  88        [i] = "IO_" #i
  89        PIN(0),
  90        PIN(1),
  91        PIN(2),
  92        PIN(3),
  93        PIN(4),
  94        PIN(5),
  95        PIN(6),
  96        PIN(7),
  97        PIN(8),
  98        PIN(9),
  99        PIN(10),
 100        PIN(11),
 101        PIN(12),
 102        PIN(13),
 103        PIN(14),
 104        PIN(15),
 105        PIN(16),
 106        PIN(17),
 107        PIN(18),
 108        PIN(19),
 109        PIN(20),
 110        PIN(21),
 111        PIN(22),
 112        PIN(23),
 113        PIN(24),
 114        PIN(25),
 115        PIN(26),
 116        PIN(27),
 117        PIN(28),
 118        PIN(29),
 119        PIN(30),
 120        PIN(31),
 121        PIN(32),
 122        PIN(33),
 123        PIN(34),
 124        PIN(35),
 125        PIN(36),
 126        PIN(37),
 127        PIN(38),
 128        PIN(39),
 129        PIN(40),
 130        PIN(41),
 131        PIN(42),
 132        PIN(43),
 133        PIN(44),
 134        PIN(45),
 135        PIN(46),
 136        PIN(47),
 137#undef PIN
 138};
 139
 140static int k210_pc_get_pins_count(struct udevice *dev)
 141{
 142        return ARRAY_SIZE(k210_pc_pin_names);
 143};
 144
 145static const char *k210_pc_get_pin_name(struct udevice *dev, unsigned selector)
 146{
 147        return k210_pc_pin_names[selector];
 148}
 149#endif /* CONFIG_CMD_PINMUX */
 150
 151/* These are just power domains */
 152static const char k210_pc_group_names[][3] = {
 153        [0] = "A0",
 154        [1] = "A1",
 155        [2] = "A2",
 156        [3] = "B3",
 157        [4] = "B4",
 158        [5] = "B5",
 159        [6] = "C6",
 160        [7] = "C7",
 161};
 162
 163static int k210_pc_get_groups_count(struct udevice *dev)
 164{
 165        return ARRAY_SIZE(k210_pc_group_names);
 166}
 167
 168static const char *k210_pc_get_group_name(struct udevice *dev,
 169                                          unsigned selector)
 170{
 171        return k210_pc_group_names[selector];
 172}
 173
 174enum k210_pc_mode_id {
 175        K210_PC_DEFAULT_DISABLED,
 176        K210_PC_DEFAULT_IN,
 177        K210_PC_DEFAULT_IN_TIE,
 178        K210_PC_DEFAULT_OUT,
 179        K210_PC_DEFAULT_I2C,
 180        K210_PC_DEFAULT_SCCB,
 181        K210_PC_DEFAULT_SPI,
 182        K210_PC_DEFAULT_GPIO,
 183        K210_PC_DEFAULT_INT13,
 184};
 185
 186static const u32 k210_pc_mode_id_to_mode[] = {
 187#define DEFAULT(mode) \
 188        [K210_PC_DEFAULT_##mode] = K210_PC_MODE_##mode
 189        [K210_PC_DEFAULT_DISABLED] = 0,
 190        DEFAULT(IN),
 191        [K210_PC_DEFAULT_IN_TIE] = K210_PC_MODE_IN,
 192        DEFAULT(OUT),
 193        DEFAULT(I2C),
 194        DEFAULT(SCCB),
 195        DEFAULT(SPI),
 196        DEFAULT(GPIO),
 197        [K210_PC_DEFAULT_INT13] = K210_PC_MODE_IN | K210_PC_PU,
 198#undef DEFAULT
 199};
 200
 201/* This saves around 2K vs having a pointer+mode */
 202struct k210_pcf_info {
 203#ifdef CONFIG_CMD_PINMUX
 204        char name[15];
 205#endif
 206        u8 mode_id;
 207};
 208
 209static const struct k210_pcf_info k210_pcf_infos[] = {
 210#ifdef CONFIG_CMD_PINMUX
 211#define FUNC(id, mode) \
 212        [K210_PCF_##id] = { \
 213                .name = #id, \
 214                .mode_id = K210_PC_DEFAULT_##mode \
 215        }
 216#else
 217#define FUNC(id, mode) \
 218        [K210_PCF_##id] = { \
 219                .mode_id = K210_PC_DEFAULT_##mode \
 220        }
 221#endif
 222        FUNC(JTAG_TCLK,      IN),
 223        FUNC(JTAG_TDI,       IN),
 224        FUNC(JTAG_TMS,       IN),
 225        FUNC(JTAG_TDO,       OUT),
 226        FUNC(SPI0_D0,        SPI),
 227        FUNC(SPI0_D1,        SPI),
 228        FUNC(SPI0_D2,        SPI),
 229        FUNC(SPI0_D3,        SPI),
 230        FUNC(SPI0_D4,        SPI),
 231        FUNC(SPI0_D5,        SPI),
 232        FUNC(SPI0_D6,        SPI),
 233        FUNC(SPI0_D7,        SPI),
 234        FUNC(SPI0_SS0,       OUT),
 235        FUNC(SPI0_SS1,       OUT),
 236        FUNC(SPI0_SS2,       OUT),
 237        FUNC(SPI0_SS3,       OUT),
 238        FUNC(SPI0_ARB,       IN_TIE),
 239        FUNC(SPI0_SCLK,      OUT),
 240        FUNC(UARTHS_RX,      IN),
 241        FUNC(UARTHS_TX,      OUT),
 242        FUNC(RESV6,          IN),
 243        FUNC(RESV7,          IN),
 244        FUNC(CLK_SPI1,       OUT),
 245        FUNC(CLK_I2C1,       OUT),
 246        FUNC(GPIOHS0,        GPIO),
 247        FUNC(GPIOHS1,        GPIO),
 248        FUNC(GPIOHS2,        GPIO),
 249        FUNC(GPIOHS3,        GPIO),
 250        FUNC(GPIOHS4,        GPIO),
 251        FUNC(GPIOHS5,        GPIO),
 252        FUNC(GPIOHS6,        GPIO),
 253        FUNC(GPIOHS7,        GPIO),
 254        FUNC(GPIOHS8,        GPIO),
 255        FUNC(GPIOHS9,        GPIO),
 256        FUNC(GPIOHS10,       GPIO),
 257        FUNC(GPIOHS11,       GPIO),
 258        FUNC(GPIOHS12,       GPIO),
 259        FUNC(GPIOHS13,       GPIO),
 260        FUNC(GPIOHS14,       GPIO),
 261        FUNC(GPIOHS15,       GPIO),
 262        FUNC(GPIOHS16,       GPIO),
 263        FUNC(GPIOHS17,       GPIO),
 264        FUNC(GPIOHS18,       GPIO),
 265        FUNC(GPIOHS19,       GPIO),
 266        FUNC(GPIOHS20,       GPIO),
 267        FUNC(GPIOHS21,       GPIO),
 268        FUNC(GPIOHS22,       GPIO),
 269        FUNC(GPIOHS23,       GPIO),
 270        FUNC(GPIOHS24,       GPIO),
 271        FUNC(GPIOHS25,       GPIO),
 272        FUNC(GPIOHS26,       GPIO),
 273        FUNC(GPIOHS27,       GPIO),
 274        FUNC(GPIOHS28,       GPIO),
 275        FUNC(GPIOHS29,       GPIO),
 276        FUNC(GPIOHS30,       GPIO),
 277        FUNC(GPIOHS31,       GPIO),
 278        FUNC(GPIO0,          GPIO),
 279        FUNC(GPIO1,          GPIO),
 280        FUNC(GPIO2,          GPIO),
 281        FUNC(GPIO3,          GPIO),
 282        FUNC(GPIO4,          GPIO),
 283        FUNC(GPIO5,          GPIO),
 284        FUNC(GPIO6,          GPIO),
 285        FUNC(GPIO7,          GPIO),
 286        FUNC(UART1_RX,       IN),
 287        FUNC(UART1_TX,       OUT),
 288        FUNC(UART2_RX,       IN),
 289        FUNC(UART2_TX,       OUT),
 290        FUNC(UART3_RX,       IN),
 291        FUNC(UART3_TX,       OUT),
 292        FUNC(SPI1_D0,        SPI),
 293        FUNC(SPI1_D1,        SPI),
 294        FUNC(SPI1_D2,        SPI),
 295        FUNC(SPI1_D3,        SPI),
 296        FUNC(SPI1_D4,        SPI),
 297        FUNC(SPI1_D5,        SPI),
 298        FUNC(SPI1_D6,        SPI),
 299        FUNC(SPI1_D7,        SPI),
 300        FUNC(SPI1_SS0,       OUT),
 301        FUNC(SPI1_SS1,       OUT),
 302        FUNC(SPI1_SS2,       OUT),
 303        FUNC(SPI1_SS3,       OUT),
 304        FUNC(SPI1_ARB,       IN_TIE),
 305        FUNC(SPI1_SCLK,      OUT),
 306        FUNC(SPI2_D0,        SPI),
 307        FUNC(SPI2_SS,        IN),
 308        FUNC(SPI2_SCLK,      IN),
 309        FUNC(I2S0_MCLK,      OUT),
 310        FUNC(I2S0_SCLK,      OUT),
 311        FUNC(I2S0_WS,        OUT),
 312        FUNC(I2S0_IN_D0,     IN),
 313        FUNC(I2S0_IN_D1,     IN),
 314        FUNC(I2S0_IN_D2,     IN),
 315        FUNC(I2S0_IN_D3,     IN),
 316        FUNC(I2S0_OUT_D0,    OUT),
 317        FUNC(I2S0_OUT_D1,    OUT),
 318        FUNC(I2S0_OUT_D2,    OUT),
 319        FUNC(I2S0_OUT_D3,    OUT),
 320        FUNC(I2S1_MCLK,      OUT),
 321        FUNC(I2S1_SCLK,      OUT),
 322        FUNC(I2S1_WS,        OUT),
 323        FUNC(I2S1_IN_D0,     IN),
 324        FUNC(I2S1_IN_D1,     IN),
 325        FUNC(I2S1_IN_D2,     IN),
 326        FUNC(I2S1_IN_D3,     IN),
 327        FUNC(I2S1_OUT_D0,    OUT),
 328        FUNC(I2S1_OUT_D1,    OUT),
 329        FUNC(I2S1_OUT_D2,    OUT),
 330        FUNC(I2S1_OUT_D3,    OUT),
 331        FUNC(I2S2_MCLK,      OUT),
 332        FUNC(I2S2_SCLK,      OUT),
 333        FUNC(I2S2_WS,        OUT),
 334        FUNC(I2S2_IN_D0,     IN),
 335        FUNC(I2S2_IN_D1,     IN),
 336        FUNC(I2S2_IN_D2,     IN),
 337        FUNC(I2S2_IN_D3,     IN),
 338        FUNC(I2S2_OUT_D0,    OUT),
 339        FUNC(I2S2_OUT_D1,    OUT),
 340        FUNC(I2S2_OUT_D2,    OUT),
 341        FUNC(I2S2_OUT_D3,    OUT),
 342        FUNC(RESV0,          DISABLED),
 343        FUNC(RESV1,          DISABLED),
 344        FUNC(RESV2,          DISABLED),
 345        FUNC(RESV3,          DISABLED),
 346        FUNC(RESV4,          DISABLED),
 347        FUNC(RESV5,          DISABLED),
 348        FUNC(I2C0_SCLK,      I2C),
 349        FUNC(I2C0_SDA,       I2C),
 350        FUNC(I2C1_SCLK,      I2C),
 351        FUNC(I2C1_SDA,       I2C),
 352        FUNC(I2C2_SCLK,      I2C),
 353        FUNC(I2C2_SDA,       I2C),
 354        FUNC(DVP_XCLK,       OUT),
 355        FUNC(DVP_RST,        OUT),
 356        FUNC(DVP_PWDN,       OUT),
 357        FUNC(DVP_VSYNC,      IN),
 358        FUNC(DVP_HSYNC,      IN),
 359        FUNC(DVP_PCLK,       IN),
 360        FUNC(DVP_D0,         IN),
 361        FUNC(DVP_D1,         IN),
 362        FUNC(DVP_D2,         IN),
 363        FUNC(DVP_D3,         IN),
 364        FUNC(DVP_D4,         IN),
 365        FUNC(DVP_D5,         IN),
 366        FUNC(DVP_D6,         IN),
 367        FUNC(DVP_D7,         IN),
 368        FUNC(SCCB_SCLK,      SCCB),
 369        FUNC(SCCB_SDA,       SCCB),
 370        FUNC(UART1_CTS,      IN),
 371        FUNC(UART1_DSR,      IN),
 372        FUNC(UART1_DCD,      IN),
 373        FUNC(UART1_RI,       IN),
 374        FUNC(UART1_SIR_IN,   IN),
 375        FUNC(UART1_DTR,      OUT),
 376        FUNC(UART1_RTS,      OUT),
 377        FUNC(UART1_OUT2,     OUT),
 378        FUNC(UART1_OUT1,     OUT),
 379        FUNC(UART1_SIR_OUT,  OUT),
 380        FUNC(UART1_BAUD,     OUT),
 381        FUNC(UART1_RE,       OUT),
 382        FUNC(UART1_DE,       OUT),
 383        FUNC(UART1_RS485_EN, OUT),
 384        FUNC(UART2_CTS,      IN),
 385        FUNC(UART2_DSR,      IN),
 386        FUNC(UART2_DCD,      IN),
 387        FUNC(UART2_RI,       IN),
 388        FUNC(UART2_SIR_IN,   IN),
 389        FUNC(UART2_DTR,      OUT),
 390        FUNC(UART2_RTS,      OUT),
 391        FUNC(UART2_OUT2,     OUT),
 392        FUNC(UART2_OUT1,     OUT),
 393        FUNC(UART2_SIR_OUT,  OUT),
 394        FUNC(UART2_BAUD,     OUT),
 395        FUNC(UART2_RE,       OUT),
 396        FUNC(UART2_DE,       OUT),
 397        FUNC(UART2_RS485_EN, OUT),
 398        FUNC(UART3_CTS,      IN),
 399        FUNC(UART3_DSR,      IN),
 400        FUNC(UART3_DCD,      IN),
 401        FUNC(UART3_RI,       IN),
 402        FUNC(UART3_SIR_IN,   IN),
 403        FUNC(UART3_DTR,      OUT),
 404        FUNC(UART3_RTS,      OUT),
 405        FUNC(UART3_OUT2,     OUT),
 406        FUNC(UART3_OUT1,     OUT),
 407        FUNC(UART3_SIR_OUT,  OUT),
 408        FUNC(UART3_BAUD,     OUT),
 409        FUNC(UART3_RE,       OUT),
 410        FUNC(UART3_DE,       OUT),
 411        FUNC(UART3_RS485_EN, OUT),
 412        FUNC(TIMER0_TOGGLE1, OUT),
 413        FUNC(TIMER0_TOGGLE2, OUT),
 414        FUNC(TIMER0_TOGGLE3, OUT),
 415        FUNC(TIMER0_TOGGLE4, OUT),
 416        FUNC(TIMER1_TOGGLE1, OUT),
 417        FUNC(TIMER1_TOGGLE2, OUT),
 418        FUNC(TIMER1_TOGGLE3, OUT),
 419        FUNC(TIMER1_TOGGLE4, OUT),
 420        FUNC(TIMER2_TOGGLE1, OUT),
 421        FUNC(TIMER2_TOGGLE2, OUT),
 422        FUNC(TIMER2_TOGGLE3, OUT),
 423        FUNC(TIMER2_TOGGLE4, OUT),
 424        FUNC(CLK_SPI2,       OUT),
 425        FUNC(CLK_I2C2,       OUT),
 426        FUNC(INTERNAL0,      OUT),
 427        FUNC(INTERNAL1,      OUT),
 428        FUNC(INTERNAL2,      OUT),
 429        FUNC(INTERNAL3,      OUT),
 430        FUNC(INTERNAL4,      OUT),
 431        FUNC(INTERNAL5,      OUT),
 432        FUNC(INTERNAL6,      OUT),
 433        FUNC(INTERNAL7,      OUT),
 434        FUNC(INTERNAL8,      OUT),
 435        FUNC(INTERNAL9,      IN),
 436        FUNC(INTERNAL10,     IN),
 437        FUNC(INTERNAL11,     IN),
 438        FUNC(INTERNAL12,     IN),
 439        FUNC(INTERNAL13,     INT13),
 440        FUNC(INTERNAL14,     I2C),
 441        FUNC(INTERNAL15,     IN),
 442        FUNC(INTERNAL16,     IN),
 443        FUNC(INTERNAL17,     IN),
 444        FUNC(CONSTANT,       DISABLED),
 445        FUNC(INTERNAL18,     IN),
 446        FUNC(DEBUG0,         OUT),
 447        FUNC(DEBUG1,         OUT),
 448        FUNC(DEBUG2,         OUT),
 449        FUNC(DEBUG3,         OUT),
 450        FUNC(DEBUG4,         OUT),
 451        FUNC(DEBUG5,         OUT),
 452        FUNC(DEBUG6,         OUT),
 453        FUNC(DEBUG7,         OUT),
 454        FUNC(DEBUG8,         OUT),
 455        FUNC(DEBUG9,         OUT),
 456        FUNC(DEBUG10,        OUT),
 457        FUNC(DEBUG11,        OUT),
 458        FUNC(DEBUG12,        OUT),
 459        FUNC(DEBUG13,        OUT),
 460        FUNC(DEBUG14,        OUT),
 461        FUNC(DEBUG15,        OUT),
 462        FUNC(DEBUG16,        OUT),
 463        FUNC(DEBUG17,        OUT),
 464        FUNC(DEBUG18,        OUT),
 465        FUNC(DEBUG19,        OUT),
 466        FUNC(DEBUG20,        OUT),
 467        FUNC(DEBUG21,        OUT),
 468        FUNC(DEBUG22,        OUT),
 469        FUNC(DEBUG23,        OUT),
 470        FUNC(DEBUG24,        OUT),
 471        FUNC(DEBUG25,        OUT),
 472        FUNC(DEBUG26,        OUT),
 473        FUNC(DEBUG27,        OUT),
 474        FUNC(DEBUG28,        OUT),
 475        FUNC(DEBUG29,        OUT),
 476        FUNC(DEBUG30,        OUT),
 477        FUNC(DEBUG31,        OUT),
 478#undef FUNC
 479};
 480
 481static int k210_pc_pinmux_set(struct udevice *dev, u32 pinmux_group)
 482{
 483        unsigned pin = FIELD_GET(K210_PG_PIN, pinmux_group);
 484        bool do_oe = FIELD_GET(K210_PG_DO, pinmux_group);
 485        unsigned func = FIELD_GET(K210_PG_FUNC, pinmux_group);
 486        struct k210_pc_priv *priv = dev_get_priv(dev);
 487        const struct k210_pcf_info *info = &k210_pcf_infos[func];
 488        u32 mode = k210_pc_mode_id_to_mode[info->mode_id];
 489        u32 val = func | mode | (do_oe ? K210_PC_DO_OE : 0);
 490
 491        debug("%s(%.8x): IO_%.2u = %3u | %.8x\n", __func__, pinmux_group, pin,
 492              func, mode);
 493
 494        writel(val, &priv->fpioa->pins[pin]);
 495        return pin;
 496}
 497
 498/* Max drive strength in uA */
 499static const int k210_pc_drive_strength[] = {
 500        [0] = 11200,
 501        [1] = 16800,
 502        [2] = 22300,
 503        [3] = 27800,
 504        [4] = 33300,
 505        [5] = 38700,
 506        [6] = 44100,
 507        [7] = 49500,
 508};
 509
 510static int k210_pc_get_drive(unsigned max_strength_ua)
 511{
 512        int i;
 513
 514        for (i = K210_PC_DRIVE_MAX; i; i--)
 515                if (k210_pc_drive_strength[i] < max_strength_ua)
 516                        return i;
 517
 518        return -EINVAL;
 519}
 520
 521static int k210_pc_pinconf_set(struct udevice *dev, unsigned pin_selector,
 522                               unsigned param, unsigned argument)
 523{
 524        struct k210_pc_priv *priv = dev_get_priv(dev);
 525        u32 val = readl(&priv->fpioa->pins[pin_selector]);
 526
 527        switch (param) {
 528        case PIN_CONFIG_BIAS_DISABLE:
 529                val &= ~K210_PC_BIAS_MASK;
 530                break;
 531        case PIN_CONFIG_BIAS_PULL_DOWN:
 532                if (argument)
 533                        val |= K210_PC_PD;
 534                else
 535                        return -EINVAL;
 536                break;
 537        case PIN_CONFIG_BIAS_PULL_UP:
 538                if (argument)
 539                        val |= K210_PC_PD;
 540                else
 541                        return -EINVAL;
 542                break;
 543        case PIN_CONFIG_DRIVE_STRENGTH:
 544                argument *= 1000;
 545        case PIN_CONFIG_DRIVE_STRENGTH_UA: {
 546                int drive = k210_pc_get_drive(argument);
 547
 548                if (IS_ERR_VALUE(drive))
 549                        return drive;
 550                val &= ~K210_PC_DRIVE_MASK;
 551                val |= FIELD_PREP(K210_PC_DRIVE_MASK, drive);
 552                break;
 553        }
 554        case PIN_CONFIG_INPUT_ENABLE:
 555                if (argument)
 556                        val |= K210_PC_IE;
 557                else
 558                        val &= ~K210_PC_IE;
 559                break;
 560        case PIN_CONFIG_INPUT_SCHMITT:
 561                argument = 1;
 562        case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
 563                if (argument)
 564                        val |= K210_PC_ST;
 565                else
 566                        val &= ~K210_PC_ST;
 567                break;
 568        case PIN_CONFIG_OUTPUT:
 569                k210_pc_pinmux_set(dev,
 570                                   K210_FPIOA(pin_selector, K210_PCF_CONSTANT));
 571                val = readl(&priv->fpioa->pins[pin_selector]);
 572                val |= K210_PC_MODE_OUT;
 573
 574                if (!argument)
 575                        val |= K210_PC_DO_INV;
 576                break;
 577        case PIN_CONFIG_OUTPUT_ENABLE:
 578                if (argument)
 579                        val |= K210_PC_OE;
 580                else
 581                        val &= ~K210_PC_OE;
 582                break;
 583        case PIN_CONFIG_SLEW_RATE:
 584                if (argument)
 585                        val |= K210_PC_SL;
 586                else
 587                        val &= ~K210_PC_SL;
 588                break;
 589        case PIN_CONFIG_OUTPUT_INVERT:
 590                if (argument)
 591                        val |= K210_PC_DO_INV;
 592                else
 593                        val &= ~K210_PC_DO_INV;
 594                break;
 595        case PIN_CONFIG_INPUT_INVERT:
 596                if (argument)
 597                        val |= K210_PC_DI_INV;
 598                else
 599                        val &= ~K210_PC_DI_INV;
 600                break;
 601        default:
 602                return -EINVAL;
 603        }
 604
 605        writel(val, &priv->fpioa->pins[pin_selector]);
 606        return 0;
 607}
 608
 609static int k210_pc_pinconf_group_set(struct udevice *dev,
 610                                     unsigned group_selector, unsigned param,
 611                                     unsigned argument)
 612{
 613        struct k210_pc_priv *priv = dev_get_priv(dev);
 614
 615        if (param == PIN_CONFIG_POWER_SOURCE) {
 616                u32 bit = BIT(group_selector);
 617
 618                regmap_update_bits(priv->sysctl, priv->power_offset, bit,
 619                                   argument ? bit : 0);
 620        } else {
 621                return -EINVAL;
 622        }
 623
 624        return 0;
 625}
 626
 627#ifdef CONFIG_CMD_PINMUX
 628static int k210_pc_get_pin_muxing(struct udevice *dev, unsigned int selector,
 629                                  char *buf, int size)
 630{
 631        struct k210_pc_priv *priv = dev_get_priv(dev);
 632        u32 val = readl(&priv->fpioa->pins[selector]);
 633        const struct k210_pcf_info *info = &k210_pcf_infos[val & K210_PCF_MASK];
 634
 635        strncpy(buf, info->name, min((size_t)size, sizeof(info->name)));
 636        return 0;
 637}
 638#endif
 639
 640static const struct pinconf_param k210_pc_pinconf_params[] = {
 641        { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
 642        { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
 643        { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
 644        { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, U32_MAX },
 645        { "drive-strength-ua", PIN_CONFIG_DRIVE_STRENGTH_UA, U32_MAX },
 646        { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
 647        { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
 648        { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
 649        { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
 650        { "power-source", PIN_CONFIG_POWER_SOURCE, K210_PC_POWER_1V8 },
 651        { "output-low", PIN_CONFIG_OUTPUT, 0 },
 652        { "output-high", PIN_CONFIG_OUTPUT, 1 },
 653        { "output-enable", PIN_CONFIG_OUTPUT_ENABLE, 1 },
 654        { "output-disable", PIN_CONFIG_OUTPUT_ENABLE, 0 },
 655        { "slew-rate", PIN_CONFIG_SLEW_RATE, 1 },
 656        { "output-polarity-invert", PIN_CONFIG_OUTPUT_INVERT, 1},
 657        { "input-polarity-invert", PIN_CONFIG_INPUT_INVERT, 1},
 658};
 659
 660static const struct pinctrl_ops k210_pc_pinctrl_ops = {
 661#ifdef CONFIG_CMD_PINMUX
 662        .get_pins_count = k210_pc_get_pins_count,
 663        .get_pin_name = k210_pc_get_pin_name,
 664#endif
 665        .get_groups_count = k210_pc_get_groups_count,
 666        .get_group_name = k210_pc_get_group_name,
 667        .pinmux_property_set = k210_pc_pinmux_set,
 668        .pinconf_num_params = ARRAY_SIZE(k210_pc_pinconf_params),
 669        .pinconf_params = k210_pc_pinconf_params,
 670        .pinconf_set = k210_pc_pinconf_set,
 671        .pinconf_group_set = k210_pc_pinconf_group_set,
 672        .set_state = pinctrl_generic_set_state,
 673#ifdef CONFIG_CMD_PINMUX
 674        .get_pin_muxing = k210_pc_get_pin_muxing,
 675#endif
 676};
 677
 678static int k210_pc_probe(struct udevice *dev)
 679{
 680        int ret, i, j;
 681        struct k210_pc_priv *priv = dev_get_priv(dev);
 682
 683        priv->fpioa = dev_read_addr_ptr(dev);
 684        if (!priv->fpioa)
 685                return -EINVAL;
 686
 687        ret = clk_get_by_index(dev, 0, &priv->clk);
 688        if (ret)
 689                return ret;
 690
 691        ret = clk_enable(&priv->clk);
 692        if (ret && ret != -ENOSYS && ret != -ENOTSUPP)
 693                goto err;
 694
 695        priv->sysctl = syscon_regmap_lookup_by_phandle(dev, "kendryte,sysctl");
 696        if (IS_ERR(priv->sysctl)) {
 697                ret = -ENODEV;
 698                goto err;
 699        }
 700
 701        ret = dev_read_u32(dev, "kendryte,power-offset", &priv->power_offset);
 702        if (ret)
 703                goto err;
 704
 705        debug("%s: fpioa = %p sysctl = %p power offset = %x\n", __func__,
 706              priv->fpioa, (void *)priv->sysctl->ranges[0].start,
 707              priv->power_offset);
 708
 709        /* Init input ties */
 710        for (i = 0; i < ARRAY_SIZE(priv->fpioa->tie_en); i++) {
 711                u32 val = 0;
 712
 713                for (j = 0; j < 32; j++)
 714                        if (k210_pcf_infos[i * 32 + j].mode_id ==
 715                            K210_PC_DEFAULT_IN_TIE)
 716                                val |= BIT(j);
 717                writel(val, &priv->fpioa->tie_en[i]);
 718                writel(val, &priv->fpioa->tie_val[i]);
 719        }
 720
 721        return 0;
 722
 723err:
 724        clk_free(&priv->clk);
 725        return ret;
 726}
 727
 728static const struct udevice_id k210_pc_ids[] = {
 729        { .compatible = "kendryte,k210-fpioa" },
 730        { }
 731};
 732
 733U_BOOT_DRIVER(pinctrl_k210) = {
 734        .name = "pinctrl_k210",
 735        .id = UCLASS_PINCTRL,
 736        .of_match = k210_pc_ids,
 737        .probe = k210_pc_probe,
 738        .priv_auto      = sizeof(struct k210_pc_priv),
 739        .ops = &k210_pc_pinctrl_ops,
 740};
 741