uboot/drivers/pinctrl/rockchip/pinctrl-rk3399.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2019 Rockchip Electronics Co., Ltd
   4 */
   5
   6#include <common.h>
   7#include <dm.h>
   8#include <dm/pinctrl.h>
   9#include <regmap.h>
  10#include <syscon.h>
  11
  12#include "pinctrl-rockchip.h"
  13
  14static struct rockchip_mux_route_data rk3399_mux_route_data[] = {
  15        {
  16                /* uart2dbga_rx */
  17                .bank_num = 4,
  18                .pin = 8,
  19                .func = 2,
  20                .route_offset = 0xe21c,
  21                .route_val = BIT(16 + 10) | BIT(16 + 11),
  22        }, {
  23                /* uart2dbgb_rx */
  24                .bank_num = 4,
  25                .pin = 16,
  26                .func = 2,
  27                .route_offset = 0xe21c,
  28                .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(10),
  29        }, {
  30                /* uart2dbgc_rx */
  31                .bank_num = 4,
  32                .pin = 19,
  33                .func = 1,
  34                .route_offset = 0xe21c,
  35                .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(11),
  36        }, {
  37                /* pcie_clkreqn */
  38                .bank_num = 2,
  39                .pin = 26,
  40                .func = 2,
  41                .route_offset = 0xe21c,
  42                .route_val = BIT(16 + 14),
  43        }, {
  44                /* pcie_clkreqnb */
  45                .bank_num = 4,
  46                .pin = 24,
  47                .func = 1,
  48                .route_offset = 0xe21c,
  49                .route_val = BIT(16 + 14) | BIT(14),
  50        },
  51};
  52
  53static int rk3399_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
  54{
  55        struct rockchip_pinctrl_priv *priv = bank->priv;
  56        int iomux_num = (pin / 8);
  57        struct regmap *regmap;
  58        int reg, ret, mask, mux_type;
  59        u8 bit;
  60        u32 data, route_reg, route_val;
  61
  62        regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
  63                                ? priv->regmap_pmu : priv->regmap_base;
  64
  65        /* get basic quadrupel of mux registers and the correct reg inside */
  66        mux_type = bank->iomux[iomux_num].type;
  67        reg = bank->iomux[iomux_num].offset;
  68        reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
  69
  70        if (bank->route_mask & BIT(pin)) {
  71                if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
  72                                           &route_val)) {
  73                        ret = regmap_write(regmap, route_reg, route_val);
  74                        if (ret)
  75                                return ret;
  76                }
  77        }
  78
  79        data = (mask << (bit + 16));
  80        data |= (mux & mask) << bit;
  81        ret = regmap_write(regmap, reg, data);
  82
  83        return ret;
  84}
  85
  86#define RK3399_PULL_GRF_OFFSET          0xe040
  87#define RK3399_PULL_PMU_OFFSET          0x40
  88
  89static void rk3399_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
  90                                         int pin_num, struct regmap **regmap,
  91                                         int *reg, u8 *bit)
  92{
  93        struct rockchip_pinctrl_priv *priv = bank->priv;
  94
  95        /* The bank0:16 and bank1:32 pins are located in PMU */
  96        if (bank->bank_num == 0 || bank->bank_num == 1) {
  97                *regmap = priv->regmap_pmu;
  98                *reg = RK3399_PULL_PMU_OFFSET;
  99
 100                *reg += bank->bank_num * ROCKCHIP_PULL_BANK_STRIDE;
 101        } else {
 102                *regmap = priv->regmap_base;
 103                *reg = RK3399_PULL_GRF_OFFSET;
 104
 105                /* correct the offset, as we're starting with the 3rd bank */
 106                *reg -= 0x20;
 107                *reg += bank->bank_num * ROCKCHIP_PULL_BANK_STRIDE;
 108        }
 109
 110        *reg += ((pin_num / ROCKCHIP_PULL_PINS_PER_REG) * 4);
 111
 112        *bit = (pin_num % ROCKCHIP_PULL_PINS_PER_REG);
 113        *bit *= ROCKCHIP_PULL_BITS_PER_PIN;
 114}
 115
 116static int rk3399_set_pull(struct rockchip_pin_bank *bank,
 117                           int pin_num, int pull)
 118{
 119        struct regmap *regmap;
 120        int reg, ret;
 121        u8 bit, type;
 122        u32 data;
 123
 124        if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
 125                return -ENOTSUPP;
 126
 127        rk3399_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
 128        type = bank->pull_type[pin_num / 8];
 129        ret = rockchip_translate_pull_value(type, pull);
 130        if (ret < 0) {
 131                debug("unsupported pull setting %d\n", pull);
 132                return ret;
 133        }
 134
 135        /* enable the write to the equivalent lower bits */
 136        data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
 137        data |= (ret << bit);
 138        ret = regmap_write(regmap, reg, data);
 139
 140        return ret;
 141}
 142
 143static void rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
 144                                        int pin_num, struct regmap **regmap,
 145                                        int *reg, u8 *bit)
 146{
 147        struct rockchip_pinctrl_priv *priv = bank->priv;
 148        int drv_num = (pin_num / 8);
 149
 150        /*  The bank0:16 and bank1:32 pins are located in PMU */
 151        if (bank->bank_num == 0 || bank->bank_num == 1)
 152                *regmap = priv->regmap_pmu;
 153        else
 154                *regmap = priv->regmap_base;
 155
 156        *reg = bank->drv[drv_num].offset;
 157        if (bank->drv[drv_num].drv_type == DRV_TYPE_IO_1V8_3V0_AUTO ||
 158            bank->drv[drv_num].drv_type == DRV_TYPE_IO_3V3_ONLY)
 159                *bit = (pin_num % 8) * 3;
 160        else
 161                *bit = (pin_num % 8) * 2;
 162}
 163
 164static int rk3399_set_drive(struct rockchip_pin_bank *bank,
 165                            int pin_num, int strength)
 166{
 167        struct regmap *regmap;
 168        int reg, ret;
 169        u32 data, rmask_bits, temp;
 170        u8 bit;
 171        int drv_type = bank->drv[pin_num / 8].drv_type;
 172
 173        rk3399_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
 174        ret = rockchip_translate_drive_value(drv_type, strength);
 175        if (ret < 0) {
 176                debug("unsupported driver strength %d\n", strength);
 177                return ret;
 178        }
 179
 180        switch (drv_type) {
 181        case DRV_TYPE_IO_1V8_3V0_AUTO:
 182        case DRV_TYPE_IO_3V3_ONLY:
 183                rmask_bits = ROCKCHIP_DRV_3BITS_PER_PIN;
 184                switch (bit) {
 185                case 0 ... 12:
 186                        /* regular case, nothing to do */
 187                        break;
 188                case 15:
 189                        /*
 190                         * drive-strength offset is special, as it is spread
 191                         * over 2 registers, the bit data[15] contains bit 0
 192                         * of the value while temp[1:0] contains bits 2 and 1
 193                         */
 194                        data = (ret & 0x1) << 15;
 195                        temp = (ret >> 0x1) & 0x3;
 196
 197                        data |= BIT(31);
 198                        ret = regmap_write(regmap, reg, data);
 199                        if (ret)
 200                                return ret;
 201
 202                        temp |= (0x3 << 16);
 203                        reg += 0x4;
 204                        ret = regmap_write(regmap, reg, temp);
 205
 206                        return ret;
 207                case 18 ... 21:
 208                        /* setting fully enclosed in the second register */
 209                        reg += 4;
 210                        bit -= 16;
 211                        break;
 212                default:
 213                        debug("unsupported bit: %d for pinctrl drive type: %d\n",
 214                              bit, drv_type);
 215                        return -EINVAL;
 216                }
 217                break;
 218        case DRV_TYPE_IO_DEFAULT:
 219        case DRV_TYPE_IO_1V8_OR_3V0:
 220        case DRV_TYPE_IO_1V8_ONLY:
 221                rmask_bits = ROCKCHIP_DRV_BITS_PER_PIN;
 222                break;
 223        default:
 224                debug("unsupported pinctrl drive type: %d\n",
 225                      drv_type);
 226                return -EINVAL;
 227        }
 228
 229        /* enable the write to the equivalent lower bits */
 230        data = ((1 << rmask_bits) - 1) << (bit + 16);
 231        data |= (ret << bit);
 232        ret = regmap_write(regmap, reg, data);
 233
 234        return ret;
 235}
 236
 237static struct rockchip_pin_bank rk3399_pin_banks[] = {
 238        PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(0, 32, "gpio0",
 239                                                         IOMUX_SOURCE_PMU,
 240                                                         IOMUX_SOURCE_PMU,
 241                                                         IOMUX_SOURCE_PMU,
 242                                                         IOMUX_SOURCE_PMU,
 243                                                         DRV_TYPE_IO_1V8_ONLY,
 244                                                         DRV_TYPE_IO_1V8_ONLY,
 245                                                         DRV_TYPE_IO_DEFAULT,
 246                                                         DRV_TYPE_IO_DEFAULT,
 247                                                         0x80,
 248                                                         0x88,
 249                                                         -1,
 250                                                         -1,
 251                                                         PULL_TYPE_IO_1V8_ONLY,
 252                                                         PULL_TYPE_IO_1V8_ONLY,
 253                                                         PULL_TYPE_IO_DEFAULT,
 254                                                         PULL_TYPE_IO_DEFAULT
 255                                                        ),
 256        PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(1, 32, "gpio1", IOMUX_SOURCE_PMU,
 257                                        IOMUX_SOURCE_PMU,
 258                                        IOMUX_SOURCE_PMU,
 259                                        IOMUX_SOURCE_PMU,
 260                                        DRV_TYPE_IO_1V8_OR_3V0,
 261                                        DRV_TYPE_IO_1V8_OR_3V0,
 262                                        DRV_TYPE_IO_1V8_OR_3V0,
 263                                        DRV_TYPE_IO_1V8_OR_3V0,
 264                                        0xa0,
 265                                        0xa8,
 266                                        0xb0,
 267                                        0xb8
 268                                        ),
 269        PIN_BANK_DRV_FLAGS_PULL_FLAGS(2, 32, "gpio2", DRV_TYPE_IO_1V8_OR_3V0,
 270                                      DRV_TYPE_IO_1V8_OR_3V0,
 271                                      DRV_TYPE_IO_1V8_ONLY,
 272                                      DRV_TYPE_IO_1V8_ONLY,
 273                                      PULL_TYPE_IO_DEFAULT,
 274                                      PULL_TYPE_IO_DEFAULT,
 275                                      PULL_TYPE_IO_1V8_ONLY,
 276                                      PULL_TYPE_IO_1V8_ONLY
 277                                      ),
 278        PIN_BANK_DRV_FLAGS(3, 32, "gpio3", DRV_TYPE_IO_3V3_ONLY,
 279                           DRV_TYPE_IO_3V3_ONLY,
 280                           DRV_TYPE_IO_3V3_ONLY,
 281                           DRV_TYPE_IO_1V8_OR_3V0
 282                           ),
 283        PIN_BANK_DRV_FLAGS(4, 32, "gpio4", DRV_TYPE_IO_1V8_OR_3V0,
 284                           DRV_TYPE_IO_1V8_3V0_AUTO,
 285                           DRV_TYPE_IO_1V8_OR_3V0,
 286                           DRV_TYPE_IO_1V8_OR_3V0
 287                           ),
 288};
 289
 290static struct rockchip_pin_ctrl rk3399_pin_ctrl = {
 291        .pin_banks              = rk3399_pin_banks,
 292        .nr_banks               = ARRAY_SIZE(rk3399_pin_banks),
 293        .grf_mux_offset         = 0xe000,
 294        .pmu_mux_offset         = 0x0,
 295        .grf_drv_offset         = 0xe100,
 296        .pmu_drv_offset         = 0x80,
 297        .iomux_routes           = rk3399_mux_route_data,
 298        .niomux_routes          = ARRAY_SIZE(rk3399_mux_route_data),
 299        .set_mux                = rk3399_set_mux,
 300        .set_pull               = rk3399_set_pull,
 301        .set_drive              = rk3399_set_drive,
 302};
 303
 304static const struct udevice_id rk3399_pinctrl_ids[] = {
 305        {
 306                .compatible = "rockchip,rk3399-pinctrl",
 307                .data = (ulong)&rk3399_pin_ctrl
 308        },
 309        { }
 310};
 311
 312U_BOOT_DRIVER(pinctrl_rk3399) = {
 313        .name           = "rockchip_rk3399_pinctrl",
 314        .id             = UCLASS_PINCTRL,
 315        .of_match       = rk3399_pinctrl_ids,
 316        .priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
 317        .ops            = &rockchip_pinctrl_ops,
 318#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 319        .bind           = dm_scan_fdt_dev,
 320#endif
 321        .probe          = rockchip_pinctrl_probe,
 322};
 323