uboot/drivers/pinctrl/rockchip/pinctrl_rk3288.c
<<
>>
Prefs
   1/*
   2 * Pinctrl driver for Rockchip SoCs
   3 * Copyright (c) 2015 Google, Inc
   4 * Written by Simon Glass <sjg@chromium.org>
   5 *
   6 * SPDX-License-Identifier:     GPL-2.0+
   7 */
   8
   9#include <common.h>
  10#include <dm.h>
  11#include <errno.h>
  12#include <syscon.h>
  13#include <asm/io.h>
  14#include <asm/arch/clock.h>
  15#include <asm/arch/grf_rk3288.h>
  16#include <asm/arch/hardware.h>
  17#include <asm/arch/periph.h>
  18#include <asm/arch/pmu_rk3288.h>
  19#include <dm/pinctrl.h>
  20#include <dm/root.h>
  21
  22DECLARE_GLOBAL_DATA_PTR;
  23
  24struct rk3288_pinctrl_priv {
  25        struct rk3288_grf *grf;
  26        struct rk3288_pmu *pmu;
  27        int num_banks;
  28};
  29
  30/**
  31 * Encode variants of iomux registers into a type variable
  32 */
  33#define IOMUX_GPIO_ONLY         BIT(0)
  34#define IOMUX_WIDTH_4BIT        BIT(1)
  35#define IOMUX_SOURCE_PMU        BIT(2)
  36#define IOMUX_UNROUTED          BIT(3)
  37
  38/**
  39 * @type: iomux variant using IOMUX_* constants
  40 * @offset: if initialized to -1 it will be autocalculated, by specifying
  41 *          an initial offset value the relevant source offset can be reset
  42 *          to a new value for autocalculating the following iomux registers.
  43 */
  44struct rockchip_iomux {
  45        u8 type;
  46        s16 offset;
  47};
  48
  49/**
  50 * @reg: register offset of the gpio bank
  51 * @nr_pins: number of pins in this bank
  52 * @bank_num: number of the bank, to account for holes
  53 * @name: name of the bank
  54 * @iomux: array describing the 4 iomux sources of the bank
  55 */
  56struct rockchip_pin_bank {
  57        u16 reg;
  58        u8 nr_pins;
  59        u8 bank_num;
  60        char *name;
  61        struct rockchip_iomux iomux[4];
  62};
  63
  64#define PIN_BANK(id, pins, label)                       \
  65        {                                               \
  66                .bank_num       = id,                   \
  67                .nr_pins        = pins,                 \
  68                .name           = label,                \
  69                .iomux          = {                     \
  70                        { .offset = -1 },               \
  71                        { .offset = -1 },               \
  72                        { .offset = -1 },               \
  73                        { .offset = -1 },               \
  74                },                                      \
  75        }
  76
  77#define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3)   \
  78        {                                                               \
  79                .bank_num       = id,                                   \
  80                .nr_pins        = pins,                                 \
  81                .name           = label,                                \
  82                .iomux          = {                                     \
  83                        { .type = iom0, .offset = -1 },                 \
  84                        { .type = iom1, .offset = -1 },                 \
  85                        { .type = iom2, .offset = -1 },                 \
  86                        { .type = iom3, .offset = -1 },                 \
  87                },                                                      \
  88        }
  89
  90#ifndef CONFIG_SPL_BUILD
  91static struct rockchip_pin_bank rk3288_pin_banks[] = {
  92        PIN_BANK_IOMUX_FLAGS(0, 24, "gpio0", IOMUX_SOURCE_PMU,
  93                                             IOMUX_SOURCE_PMU,
  94                                             IOMUX_SOURCE_PMU,
  95                                             IOMUX_UNROUTED
  96                            ),
  97        PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_UNROUTED,
  98                                             IOMUX_UNROUTED,
  99                                             IOMUX_UNROUTED,
 100                                             0
 101                            ),
 102        PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, IOMUX_UNROUTED),
 103        PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, IOMUX_WIDTH_4BIT),
 104        PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
 105                                             IOMUX_WIDTH_4BIT,
 106                                             0,
 107                                             0
 108                            ),
 109        PIN_BANK_IOMUX_FLAGS(5, 32, "gpio5", IOMUX_UNROUTED,
 110                                             0,
 111                                             0,
 112                                             IOMUX_UNROUTED
 113                            ),
 114        PIN_BANK_IOMUX_FLAGS(6, 32, "gpio6", 0, 0, 0, IOMUX_UNROUTED),
 115        PIN_BANK_IOMUX_FLAGS(7, 32, "gpio7", 0,
 116                                             0,
 117                                             IOMUX_WIDTH_4BIT,
 118                                             IOMUX_UNROUTED
 119                            ),
 120        PIN_BANK(8, 16, "gpio8"),
 121};
 122#endif
 123
 124static void pinctrl_rk3288_pwm_config(struct rk3288_grf *grf, int pwm_id)
 125{
 126        switch (pwm_id) {
 127        case PERIPH_ID_PWM0:
 128                rk_clrsetreg(&grf->gpio7a_iomux, GPIO7A0_MASK << GPIO7A0_SHIFT,
 129                             GPIO7A0_PWM_0 << GPIO7A0_SHIFT);
 130                break;
 131        case PERIPH_ID_PWM1:
 132                rk_clrsetreg(&grf->gpio7a_iomux, GPIO7A1_MASK << GPIO7A1_SHIFT,
 133                             GPIO7A1_PWM_1 << GPIO7A1_SHIFT);
 134                break;
 135        case PERIPH_ID_PWM2:
 136                rk_clrsetreg(&grf->gpio7a_iomux, GPIO7C6_MASK << GPIO7C6_SHIFT,
 137                             GPIO7C6_PWM_2 << GPIO7C6_SHIFT);
 138                break;
 139        case PERIPH_ID_PWM3:
 140                rk_clrsetreg(&grf->gpio7a_iomux, GPIO7C7_MASK << GPIO7C6_SHIFT,
 141                             GPIO7C7_PWM_3 << GPIO7C7_SHIFT);
 142                break;
 143        default:
 144                debug("pwm id = %d iomux error!\n", pwm_id);
 145                break;
 146        }
 147}
 148
 149static void pinctrl_rk3288_i2c_config(struct rk3288_grf *grf,
 150                                      struct rk3288_pmu *pmu, int i2c_id)
 151{
 152        switch (i2c_id) {
 153        case PERIPH_ID_I2C0:
 154                clrsetbits_le32(&pmu->gpio0_iomux[PMU_GPIO0_B],
 155                                GPIO0_B7_MASK << GPIO0_B7_SHIFT,
 156                                GPIO0_B7_I2C0PMU_SDA << GPIO0_B7_SHIFT);
 157                clrsetbits_le32(&pmu->gpio0_iomux[PMU_GPIO0_C],
 158                                GPIO0_C0_MASK << GPIO0_C0_SHIFT,
 159                                GPIO0_C0_I2C0PMU_SCL << GPIO0_C0_SHIFT);
 160                break;
 161#ifndef CONFIG_SPL_BUILD
 162        case PERIPH_ID_I2C1:
 163                rk_clrsetreg(&grf->gpio8a_iomux,
 164                             GPIO8A4_MASK << GPIO8A4_SHIFT |
 165                             GPIO8A5_MASK << GPIO8A5_SHIFT,
 166                             GPIO8A4_I2C2SENSOR_SDA << GPIO8A4_SHIFT |
 167                             GPIO8A5_I2C2SENSOR_SCL << GPIO8A5_SHIFT);
 168                break;
 169        case PERIPH_ID_I2C2:
 170                rk_clrsetreg(&grf->gpio6b_iomux,
 171                             GPIO6B1_MASK << GPIO6B1_SHIFT |
 172                             GPIO6B2_MASK << GPIO6B2_SHIFT,
 173                             GPIO6B1_I2C1AUDIO_SDA << GPIO6B1_SHIFT |
 174                             GPIO6B2_I2C1AUDIO_SCL << GPIO6B2_SHIFT);
 175                break;
 176        case PERIPH_ID_I2C3:
 177                rk_clrsetreg(&grf->gpio2c_iomux,
 178                             GPIO2C1_MASK << GPIO2C1_SHIFT |
 179                             GPIO2C0_MASK << GPIO2C0_SHIFT,
 180                             GPIO2C1_I2C3CAM_SDA << GPIO2C1_SHIFT |
 181                             GPIO2C0_I2C3CAM_SCL << GPIO2C0_SHIFT);
 182                break;
 183        case PERIPH_ID_I2C4:
 184                rk_clrsetreg(&grf->gpio7cl_iomux,
 185                             GPIO7C1_MASK << GPIO7C1_SHIFT |
 186                             GPIO7C2_MASK << GPIO7C2_SHIFT,
 187                             GPIO7C1_I2C4TP_SDA << GPIO7C1_SHIFT |
 188                             GPIO7C2_I2C4TP_SCL << GPIO7C2_SHIFT);
 189                break;
 190        case PERIPH_ID_I2C5:
 191                rk_clrsetreg(&grf->gpio7cl_iomux,
 192                             GPIO7C3_MASK << GPIO7C3_SHIFT,
 193                             GPIO7C3_I2C5HDMI_SDA << GPIO7C3_SHIFT);
 194                rk_clrsetreg(&grf->gpio7ch_iomux,
 195                             GPIO7C4_MASK << GPIO7C4_SHIFT,
 196                             GPIO7C4_I2C5HDMI_SCL << GPIO7C4_SHIFT);
 197                break;
 198#endif
 199        default:
 200                debug("i2c id = %d iomux error!\n", i2c_id);
 201                break;
 202        }
 203}
 204
 205#ifndef CONFIG_SPL_BUILD
 206static void pinctrl_rk3288_lcdc_config(struct rk3288_grf *grf, int lcd_id)
 207{
 208        switch (lcd_id) {
 209        case PERIPH_ID_LCDC0:
 210                rk_clrsetreg(&grf->gpio1d_iomux,
 211                             GPIO1D3_MASK << GPIO1D0_SHIFT |
 212                             GPIO1D2_MASK << GPIO1D2_SHIFT |
 213                             GPIO1D1_MASK << GPIO1D1_SHIFT |
 214                             GPIO1D0_MASK << GPIO1D0_SHIFT,
 215                             GPIO1D3_LCDC0_DCLK << GPIO1D3_SHIFT |
 216                             GPIO1D2_LCDC0_DEN << GPIO1D2_SHIFT |
 217                             GPIO1D1_LCDC0_VSYNC << GPIO1D1_SHIFT |
 218                             GPIO1D0_LCDC0_HSYNC << GPIO1D0_SHIFT);
 219                break;
 220        default:
 221                debug("lcdc id = %d iomux error!\n", lcd_id);
 222                break;
 223        }
 224}
 225#endif
 226
 227static int pinctrl_rk3288_spi_config(struct rk3288_grf *grf,
 228                                     enum periph_id spi_id, int cs)
 229{
 230        switch (spi_id) {
 231#ifndef CONFIG_SPL_BUILD
 232        case PERIPH_ID_SPI0:
 233                switch (cs) {
 234                case 0:
 235                        rk_clrsetreg(&grf->gpio5b_iomux,
 236                                     GPIO5B5_MASK << GPIO5B5_SHIFT,
 237                                     GPIO5B5_SPI0_CSN0 << GPIO5B5_SHIFT);
 238                        break;
 239                case 1:
 240                        rk_clrsetreg(&grf->gpio5c_iomux,
 241                                     GPIO5C0_MASK << GPIO5C0_SHIFT,
 242                                     GPIO5C0_SPI0_CSN1 << GPIO5C0_SHIFT);
 243                        break;
 244                default:
 245                        goto err;
 246                }
 247                rk_clrsetreg(&grf->gpio5b_iomux,
 248                             GPIO5B7_MASK << GPIO5B7_SHIFT |
 249                             GPIO5B6_MASK << GPIO5B6_SHIFT |
 250                             GPIO5B4_MASK << GPIO5B4_SHIFT,
 251                             GPIO5B7_SPI0_RXD << GPIO5B7_SHIFT |
 252                             GPIO5B6_SPI0_TXD << GPIO5B6_SHIFT |
 253                             GPIO5B4_SPI0_CLK << GPIO5B4_SHIFT);
 254                break;
 255        case PERIPH_ID_SPI1:
 256                if (cs != 0)
 257                        goto err;
 258                rk_clrsetreg(&grf->gpio7b_iomux,
 259                             GPIO7B6_MASK << GPIO7B6_SHIFT |
 260                             GPIO7B7_MASK << GPIO7B7_SHIFT |
 261                             GPIO7B5_MASK << GPIO7B5_SHIFT |
 262                             GPIO7B4_MASK << GPIO7B4_SHIFT,
 263                             GPIO7B6_SPI1_RXD << GPIO7B6_SHIFT |
 264                             GPIO7B7_SPI1_TXD << GPIO7B7_SHIFT |
 265                             GPIO7B5_SPI1_CSN0 << GPIO7B5_SHIFT |
 266                             GPIO7B4_SPI1_CLK << GPIO7B4_SHIFT);
 267                break;
 268#endif
 269        case PERIPH_ID_SPI2:
 270                switch (cs) {
 271                case 0:
 272                        rk_clrsetreg(&grf->gpio8a_iomux,
 273                                     GPIO8A7_MASK << GPIO8A7_SHIFT,
 274                                     GPIO8A7_SPI2_CSN0 << GPIO8A7_SHIFT);
 275                        break;
 276                case 1:
 277                        rk_clrsetreg(&grf->gpio8a_iomux,
 278                                     GPIO8A3_MASK << GPIO8A3_SHIFT,
 279                                     GPIO8A3_SPI2_CSN1 << GPIO8A3_SHIFT);
 280                        break;
 281                default:
 282                        goto err;
 283                }
 284                rk_clrsetreg(&grf->gpio8b_iomux,
 285                             GPIO8B1_MASK << GPIO8B1_SHIFT |
 286                             GPIO8B0_MASK << GPIO8B0_SHIFT,
 287                             GPIO8B1_SPI2_TXD << GPIO8B1_SHIFT |
 288                             GPIO8B0_SPI2_RXD << GPIO8B0_SHIFT);
 289                rk_clrsetreg(&grf->gpio8a_iomux,
 290                             GPIO8A6_MASK << GPIO8A6_SHIFT,
 291                             GPIO8A6_SPI2_CLK << GPIO8A6_SHIFT);
 292                break;
 293        default:
 294                goto err;
 295        }
 296
 297        return 0;
 298err:
 299        debug("rkspi: periph%d cs=%d not supported", spi_id, cs);
 300        return -ENOENT;
 301}
 302
 303static void pinctrl_rk3288_uart_config(struct rk3288_grf *grf, int uart_id)
 304{
 305        switch (uart_id) {
 306#ifndef CONFIG_SPL_BUILD
 307        case PERIPH_ID_UART_BT:
 308                rk_clrsetreg(&grf->gpio4c_iomux,
 309                             GPIO4C3_MASK << GPIO4C3_SHIFT |
 310                             GPIO4C2_MASK << GPIO4C2_SHIFT |
 311                             GPIO4C1_MASK << GPIO4C1_SHIFT |
 312                             GPIO4C0_MASK << GPIO4C0_SHIFT,
 313                             GPIO4C3_UART0BT_RTSN << GPIO4C3_SHIFT |
 314                             GPIO4C2_UART0BT_CTSN << GPIO4C2_SHIFT |
 315                             GPIO4C1_UART0BT_SOUT << GPIO4C1_SHIFT |
 316                             GPIO4C0_UART0BT_SIN << GPIO4C0_SHIFT);
 317                break;
 318        case PERIPH_ID_UART_BB:
 319                rk_clrsetreg(&grf->gpio5b_iomux,
 320                             GPIO5B3_MASK << GPIO5B3_SHIFT |
 321                             GPIO5B2_MASK << GPIO5B2_SHIFT |
 322                             GPIO5B1_MASK << GPIO5B1_SHIFT |
 323                             GPIO5B0_MASK << GPIO5B0_SHIFT,
 324                             GPIO5B3_UART1BB_RTSN << GPIO5B3_SHIFT |
 325                             GPIO5B2_UART1BB_CTSN << GPIO5B2_SHIFT |
 326                             GPIO5B1_UART1BB_SOUT << GPIO5B1_SHIFT |
 327                             GPIO5B0_UART1BB_SIN << GPIO5B0_SHIFT);
 328                break;
 329#endif
 330        case PERIPH_ID_UART_DBG:
 331                rk_clrsetreg(&grf->gpio7ch_iomux,
 332                             GPIO7C7_MASK << GPIO7C7_SHIFT |
 333                             GPIO7C6_MASK << GPIO7C6_SHIFT,
 334                             GPIO7C7_UART2DBG_SOUT << GPIO7C7_SHIFT |
 335                             GPIO7C6_UART2DBG_SIN << GPIO7C6_SHIFT);
 336                break;
 337#ifndef CONFIG_SPL_BUILD
 338        case PERIPH_ID_UART_GPS:
 339                rk_clrsetreg(&grf->gpio7b_iomux,
 340                             GPIO7B2_MASK << GPIO7B2_SHIFT |
 341                             GPIO7B1_MASK << GPIO7B1_SHIFT |
 342                             GPIO7B0_MASK << GPIO7B0_SHIFT,
 343                             GPIO7B2_UART3GPS_RTSN << GPIO7B2_SHIFT |
 344                             GPIO7B1_UART3GPS_CTSN << GPIO7B1_SHIFT |
 345                             GPIO7B0_UART3GPS_SOUT << GPIO7B0_SHIFT);
 346                rk_clrsetreg(&grf->gpio7a_iomux,
 347                             GPIO7A7_MASK << GPIO7A7_SHIFT,
 348                             GPIO7A7_UART3GPS_SIN << GPIO7A7_SHIFT);
 349                break;
 350        case PERIPH_ID_UART_EXP:
 351                rk_clrsetreg(&grf->gpio5b_iomux,
 352                             GPIO5B5_MASK << GPIO5B5_SHIFT |
 353                             GPIO5B4_MASK << GPIO5B4_SHIFT |
 354                             GPIO5B6_MASK << GPIO5B6_SHIFT |
 355                             GPIO5B7_MASK << GPIO5B7_SHIFT,
 356                             GPIO5B5_UART4EXP_RTSN << GPIO5B5_SHIFT |
 357                             GPIO5B4_UART4EXP_CTSN << GPIO5B4_SHIFT |
 358                             GPIO5B6_UART4EXP_SOUT << GPIO5B6_SHIFT |
 359                             GPIO5B7_UART4EXP_SIN << GPIO5B7_SHIFT);
 360                break;
 361#endif
 362        default:
 363                debug("uart id = %d iomux error!\n", uart_id);
 364                break;
 365        }
 366}
 367
 368static void pinctrl_rk3288_sdmmc_config(struct rk3288_grf *grf, int mmc_id)
 369{
 370        switch (mmc_id) {
 371        case PERIPH_ID_EMMC:
 372                rk_clrsetreg(&grf->gpio3a_iomux, 0xffff,
 373                             GPIO3A7_EMMC_DATA7 << GPIO3A7_SHIFT |
 374                             GPIO3A6_EMMC_DATA6 << GPIO3A6_SHIFT |
 375                             GPIO3A5_EMMC_DATA5 << GPIO3A5_SHIFT |
 376                             GPIO3A4_EMMC_DATA4 << GPIO3A4_SHIFT |
 377                             GPIO3A3_EMMC_DATA3 << GPIO3A3_SHIFT |
 378                             GPIO3A2_EMMC_DATA2 << GPIO3A2_SHIFT |
 379                             GPIO3A1_EMMC_DATA1 << GPIO3A1_SHIFT |
 380                             GPIO3A0_EMMC_DATA0 << GPIO3A0_SHIFT);
 381                rk_clrsetreg(&grf->gpio3b_iomux, GPIO3B1_MASK << GPIO3B1_SHIFT,
 382                             GPIO3B1_EMMC_PWREN << GPIO3B1_SHIFT);
 383                rk_clrsetreg(&grf->gpio3c_iomux,
 384                             GPIO3C0_MASK << GPIO3C0_SHIFT,
 385                             GPIO3C0_EMMC_CMD << GPIO3C0_SHIFT);
 386                break;
 387        case PERIPH_ID_SDCARD:
 388                rk_clrsetreg(&grf->gpio6c_iomux, 0xffff,
 389                             GPIO6C6_SDMMC0_DECTN << GPIO6C6_SHIFT |
 390                             GPIO6C5_SDMMC0_CMD << GPIO6C5_SHIFT |
 391                             GPIO6C4_SDMMC0_CLKOUT << GPIO6C4_SHIFT |
 392                             GPIO6C3_SDMMC0_DATA3 << GPIO6C3_SHIFT |
 393                             GPIO6C2_SDMMC0_DATA2 << GPIO6C2_SHIFT |
 394                             GPIO6C1_SDMMC0_DATA1 << GPIO6C1_SHIFT |
 395                             GPIO6C0_SDMMC0_DATA0 << GPIO6C0_SHIFT);
 396
 397                /* use sdmmc0 io, disable JTAG function */
 398                rk_clrsetreg(&grf->soc_con0, 1 << GRF_FORCE_JTAG_SHIFT, 0);
 399                break;
 400        default:
 401                debug("mmc id = %d iomux error!\n", mmc_id);
 402                break;
 403        }
 404}
 405
 406#ifndef CONFIG_SPL_BUILD
 407static void pinctrl_rk3288_hdmi_config(struct rk3288_grf *grf, int hdmi_id)
 408{
 409        switch (hdmi_id) {
 410        case PERIPH_ID_HDMI:
 411                rk_clrsetreg(&grf->gpio7cl_iomux, GPIO7C3_MASK << GPIO7C3_SHIFT,
 412                             GPIO7C3_EDPHDMII2C_SDA << GPIO7C3_SHIFT);
 413                rk_clrsetreg(&grf->gpio7ch_iomux, GPIO7C4_MASK << GPIO7C4_SHIFT,
 414                             GPIO7C4_EDPHDMII2C_SCL << GPIO7C4_SHIFT);
 415                break;
 416        default:
 417                debug("hdmi id = %d iomux error!\n", hdmi_id);
 418                break;
 419        }
 420}
 421#endif
 422
 423static int rk3288_pinctrl_request(struct udevice *dev, int func, int flags)
 424{
 425        struct rk3288_pinctrl_priv *priv = dev_get_priv(dev);
 426
 427        debug("%s: func=%x, flags=%x\n", __func__, func, flags);
 428        switch (func) {
 429        case PERIPH_ID_PWM0:
 430        case PERIPH_ID_PWM1:
 431        case PERIPH_ID_PWM2:
 432        case PERIPH_ID_PWM3:
 433        case PERIPH_ID_PWM4:
 434                pinctrl_rk3288_pwm_config(priv->grf, func);
 435                break;
 436        case PERIPH_ID_I2C0:
 437        case PERIPH_ID_I2C1:
 438        case PERIPH_ID_I2C2:
 439        case PERIPH_ID_I2C3:
 440        case PERIPH_ID_I2C4:
 441        case PERIPH_ID_I2C5:
 442                pinctrl_rk3288_i2c_config(priv->grf, priv->pmu, func);
 443                break;
 444        case PERIPH_ID_SPI0:
 445        case PERIPH_ID_SPI1:
 446        case PERIPH_ID_SPI2:
 447                pinctrl_rk3288_spi_config(priv->grf, func, flags);
 448                break;
 449        case PERIPH_ID_UART0:
 450        case PERIPH_ID_UART1:
 451        case PERIPH_ID_UART2:
 452        case PERIPH_ID_UART3:
 453        case PERIPH_ID_UART4:
 454                pinctrl_rk3288_uart_config(priv->grf, func);
 455                break;
 456#ifndef CONFIG_SPL_BUILD
 457        case PERIPH_ID_LCDC0:
 458        case PERIPH_ID_LCDC1:
 459                pinctrl_rk3288_lcdc_config(priv->grf, func);
 460                break;
 461        case PERIPH_ID_HDMI:
 462                pinctrl_rk3288_hdmi_config(priv->grf, func);
 463                break;
 464#endif
 465        case PERIPH_ID_SDMMC0:
 466        case PERIPH_ID_SDMMC1:
 467                pinctrl_rk3288_sdmmc_config(priv->grf, func);
 468                break;
 469        default:
 470                return -EINVAL;
 471        }
 472
 473        return 0;
 474}
 475
 476static int rk3288_pinctrl_get_periph_id(struct udevice *dev,
 477                                        struct udevice *periph)
 478{
 479        u32 cell[3];
 480        int ret;
 481
 482        ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
 483                                   "interrupts", cell, ARRAY_SIZE(cell));
 484        if (ret < 0)
 485                return -EINVAL;
 486
 487        switch (cell[1]) {
 488        case 44:
 489                return PERIPH_ID_SPI0;
 490        case 45:
 491                return PERIPH_ID_SPI1;
 492        case 46:
 493                return PERIPH_ID_SPI2;
 494        case 60:
 495                return PERIPH_ID_I2C0;
 496        case 62: /* Note strange order */
 497                return PERIPH_ID_I2C1;
 498        case 61:
 499                return PERIPH_ID_I2C2;
 500        case 63:
 501                return PERIPH_ID_I2C3;
 502        case 64:
 503                return PERIPH_ID_I2C4;
 504        case 65:
 505                return PERIPH_ID_I2C5;
 506        case 103:
 507                return PERIPH_ID_HDMI;
 508        }
 509
 510        return -ENOENT;
 511}
 512
 513static int rk3288_pinctrl_set_state_simple(struct udevice *dev,
 514                                           struct udevice *periph)
 515{
 516        int func;
 517
 518        func = rk3288_pinctrl_get_periph_id(dev, periph);
 519        if (func < 0)
 520                return func;
 521        return rk3288_pinctrl_request(dev, func, 0);
 522}
 523
 524#ifndef CONFIG_SPL_BUILD
 525int rk3288_pinctrl_get_pin_info(struct rk3288_pinctrl_priv *priv,
 526                                int banknum, int ind, u32 **addrp, uint *shiftp,
 527                                uint *maskp)
 528{
 529        struct rockchip_pin_bank *bank = &rk3288_pin_banks[banknum];
 530        uint muxnum;
 531        u32 *addr;
 532
 533        for (muxnum = 0; muxnum < 4; muxnum++) {
 534                struct rockchip_iomux *mux = &bank->iomux[muxnum];
 535
 536                if (ind >= 8) {
 537                        ind -= 8;
 538                        continue;
 539                }
 540
 541                if (mux->type & IOMUX_SOURCE_PMU)
 542                        addr = priv->pmu->gpio0_iomux;
 543                else
 544                        addr = (u32 *)priv->grf - 4;
 545                addr += mux->offset;
 546                *shiftp = ind & 7;
 547                if (mux->type & IOMUX_WIDTH_4BIT) {
 548                        *maskp = 0xf;
 549                        *shiftp *= 4;
 550                        if (*shiftp >= 16) {
 551                                *shiftp -= 16;
 552                                addr++;
 553                        }
 554                } else {
 555                        *maskp = 3;
 556                        *shiftp *= 2;
 557                }
 558
 559                debug("%s: addr=%p, mask=%x, shift=%x\n", __func__, addr,
 560                      *maskp, *shiftp);
 561                *addrp = addr;
 562                return 0;
 563        }
 564
 565        return -EINVAL;
 566}
 567
 568static int rk3288_pinctrl_get_gpio_mux(struct udevice *dev, int banknum,
 569                                       int index)
 570{
 571        struct rk3288_pinctrl_priv *priv = dev_get_priv(dev);
 572        uint shift;
 573        uint mask;
 574        u32 *addr;
 575        int ret;
 576
 577        ret = rk3288_pinctrl_get_pin_info(priv, banknum, index, &addr, &shift,
 578                                          &mask);
 579        if (ret)
 580                return ret;
 581        return (readl(addr) & mask) >> shift;
 582}
 583
 584static int rk3288_pinctrl_set_pins(struct udevice *dev, int banknum, int index,
 585                                   int muxval, int flags)
 586{
 587        struct rk3288_pinctrl_priv *priv = dev_get_priv(dev);
 588        uint shift, ind = index;
 589        uint mask;
 590        u32 *addr;
 591        int ret;
 592
 593        debug("%s: %x %x %x %x\n", __func__, banknum, index, muxval, flags);
 594        ret = rk3288_pinctrl_get_pin_info(priv, banknum, index, &addr, &shift,
 595                                          &mask);
 596        if (ret)
 597                return ret;
 598        rk_clrsetreg(addr, mask << shift, muxval << shift);
 599
 600        /* Handle pullup/pulldown */
 601        if (flags) {
 602                uint val = 0;
 603
 604                if (flags & (1 << PIN_CONFIG_BIAS_PULL_UP))
 605                        val = 1;
 606                else if (flags & (1 << PIN_CONFIG_BIAS_PULL_DOWN))
 607                        val = 2;
 608                shift = (index & 7) * 2;
 609                ind = index >> 3;
 610                if (banknum == 0)
 611                        addr = &priv->pmu->gpio0pull[ind];
 612                else
 613                        addr = &priv->grf->gpio1_p[banknum - 1][ind];
 614                debug("%s: addr=%p, val=%x, shift=%x\n", __func__, addr, val,
 615                      shift);
 616                rk_clrsetreg(addr, 3 << shift, val << shift);
 617        }
 618
 619        return 0;
 620}
 621
 622static int rk3288_pinctrl_set_state(struct udevice *dev, struct udevice *config)
 623{
 624        const void *blob = gd->fdt_blob;
 625        int pcfg_node, ret, flags, count, i;
 626        u32 cell[40], *ptr;
 627
 628        debug("%s: %s %s\n", __func__, dev->name, config->name);
 629        ret = fdtdec_get_int_array_count(blob, config->of_offset,
 630                                         "rockchip,pins", cell,
 631                                         ARRAY_SIZE(cell));
 632        if (ret < 0) {
 633                debug("%s: bad array %d\n", __func__, ret);
 634                return -EINVAL;
 635        }
 636        count = ret;
 637        for (i = 0, ptr = cell; i < count; i += 4, ptr += 4) {
 638                pcfg_node = fdt_node_offset_by_phandle(blob, ptr[3]);
 639                if (pcfg_node < 0)
 640                        return -EINVAL;
 641                flags = pinctrl_decode_pin_config(blob, pcfg_node);
 642                if (flags < 0)
 643                        return flags;
 644
 645                ret = rk3288_pinctrl_set_pins(dev, ptr[0], ptr[1], ptr[2],
 646                                              flags);
 647                if (ret)
 648                        return ret;
 649        }
 650
 651        return 0;
 652}
 653#endif
 654
 655static struct pinctrl_ops rk3288_pinctrl_ops = {
 656#ifndef CONFIG_SPL_BUILD
 657        .set_state      = rk3288_pinctrl_set_state,
 658        .get_gpio_mux   = rk3288_pinctrl_get_gpio_mux,
 659#endif
 660        .set_state_simple       = rk3288_pinctrl_set_state_simple,
 661        .request        = rk3288_pinctrl_request,
 662        .get_periph_id  = rk3288_pinctrl_get_periph_id,
 663};
 664
 665static int rk3288_pinctrl_bind(struct udevice *dev)
 666{
 667        /* scan child GPIO banks */
 668        return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
 669}
 670
 671#ifndef CONFIG_SPL_BUILD
 672static int rk3288_pinctrl_parse_tables(struct rk3288_pinctrl_priv *priv,
 673                                       struct rockchip_pin_bank *banks,
 674                                       int count)
 675{
 676        struct rockchip_pin_bank *bank;
 677        uint reg, muxnum, banknum;
 678
 679        reg = 0;
 680        for (banknum = 0; banknum < count; banknum++) {
 681                bank = &banks[banknum];
 682                bank->reg = reg;
 683                debug("%s: bank %d, reg %x\n", __func__, banknum, reg * 4);
 684                for (muxnum = 0; muxnum < 4; muxnum++) {
 685                        struct rockchip_iomux *mux = &bank->iomux[muxnum];
 686
 687                        if (!(mux->type & IOMUX_UNROUTED))
 688                                mux->offset = reg;
 689                        if (mux->type & IOMUX_WIDTH_4BIT)
 690                                reg += 2;
 691                        else
 692                                reg += 1;
 693                }
 694        }
 695
 696        return 0;
 697}
 698#endif
 699
 700static int rk3288_pinctrl_probe(struct udevice *dev)
 701{
 702        struct rk3288_pinctrl_priv *priv = dev_get_priv(dev);
 703        int ret = 0;
 704
 705        priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
 706        priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
 707        debug("%s: grf=%p, pmu=%p\n", __func__, priv->grf, priv->pmu);
 708#ifndef CONFIG_SPL_BUILD
 709        ret = rk3288_pinctrl_parse_tables(priv, rk3288_pin_banks,
 710                                          ARRAY_SIZE(rk3288_pin_banks));
 711#endif
 712
 713        return ret;
 714}
 715
 716static const struct udevice_id rk3288_pinctrl_ids[] = {
 717        { .compatible = "rockchip,rk3288-pinctrl" },
 718        { }
 719};
 720
 721U_BOOT_DRIVER(pinctrl_rk3288) = {
 722        .name           = "pinctrl_rk3288",
 723        .id             = UCLASS_PINCTRL,
 724        .of_match       = rk3288_pinctrl_ids,
 725        .priv_auto_alloc_size = sizeof(struct rk3288_pinctrl_priv),
 726        .ops            = &rk3288_pinctrl_ops,
 727        .bind           = rk3288_pinctrl_bind,
 728        .probe          = rk3288_pinctrl_probe,
 729};
 730