uboot/drivers/pinctrl/rockchip/pinctrl-rk322x.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 rk3228_mux_route_data[] = {
  15        {
  16                /* pwm0-0 */
  17                .bank_num = 0,
  18                .pin = 26,
  19                .func = 1,
  20                .route_offset = 0x50,
  21                .route_val = BIT(16),
  22        }, {
  23                /* pwm0-1 */
  24                .bank_num = 3,
  25                .pin = 21,
  26                .func = 1,
  27                .route_offset = 0x50,
  28                .route_val = BIT(16) | BIT(0),
  29        }, {
  30                /* pwm1-0 */
  31                .bank_num = 0,
  32                .pin = 27,
  33                .func = 1,
  34                .route_offset = 0x50,
  35                .route_val = BIT(16 + 1),
  36        }, {
  37                /* pwm1-1 */
  38                .bank_num = 0,
  39                .pin = 30,
  40                .func = 2,
  41                .route_offset = 0x50,
  42                .route_val = BIT(16 + 1) | BIT(1),
  43        }, {
  44                /* pwm2-0 */
  45                .bank_num = 0,
  46                .pin = 28,
  47                .func = 1,
  48                .route_offset = 0x50,
  49                .route_val = BIT(16 + 2),
  50        }, {
  51                /* pwm2-1 */
  52                .bank_num = 1,
  53                .pin = 12,
  54                .func = 2,
  55                .route_offset = 0x50,
  56                .route_val = BIT(16 + 2) | BIT(2),
  57        }, {
  58                /* pwm3-0 */
  59                .bank_num = 3,
  60                .pin = 26,
  61                .func = 1,
  62                .route_offset = 0x50,
  63                .route_val = BIT(16 + 3),
  64        }, {
  65                /* pwm3-1 */
  66                .bank_num = 1,
  67                .pin = 11,
  68                .func = 2,
  69                .route_offset = 0x50,
  70                .route_val = BIT(16 + 3) | BIT(3),
  71        }, {
  72                /* sdio-0_d0 */
  73                .bank_num = 1,
  74                .pin = 1,
  75                .func = 1,
  76                .route_offset = 0x50,
  77                .route_val = BIT(16 + 4),
  78        }, {
  79                /* sdio-1_d0 */
  80                .bank_num = 3,
  81                .pin = 2,
  82                .func = 1,
  83                .route_offset = 0x50,
  84                .route_val = BIT(16 + 4) | BIT(4),
  85        }, {
  86                /* spi-0_rx */
  87                .bank_num = 0,
  88                .pin = 13,
  89                .func = 2,
  90                .route_offset = 0x50,
  91                .route_val = BIT(16 + 5),
  92        }, {
  93                /* spi-1_rx */
  94                .bank_num = 2,
  95                .pin = 0,
  96                .func = 2,
  97                .route_offset = 0x50,
  98                .route_val = BIT(16 + 5) | BIT(5),
  99        }, {
 100                /* emmc-0_cmd */
 101                .bank_num = 1,
 102                .pin = 22,
 103                .func = 2,
 104                .route_offset = 0x50,
 105                .route_val = BIT(16 + 7),
 106        }, {
 107                /* emmc-1_cmd */
 108                .bank_num = 2,
 109                .pin = 4,
 110                .func = 2,
 111                .route_offset = 0x50,
 112                .route_val = BIT(16 + 7) | BIT(7),
 113        }, {
 114                /* uart2-0_rx */
 115                .bank_num = 1,
 116                .pin = 19,
 117                .func = 2,
 118                .route_offset = 0x50,
 119                .route_val = BIT(16 + 8),
 120        }, {
 121                /* uart2-1_rx */
 122                .bank_num = 1,
 123                .pin = 10,
 124                .func = 2,
 125                .route_offset = 0x50,
 126                .route_val = BIT(16 + 8) | BIT(8),
 127        }, {
 128                /* uart1-0_rx */
 129                .bank_num = 1,
 130                .pin = 10,
 131                .func = 1,
 132                .route_offset = 0x50,
 133                .route_val = BIT(16 + 11),
 134        }, {
 135                /* uart1-1_rx */
 136                .bank_num = 3,
 137                .pin = 13,
 138                .func = 1,
 139                .route_offset = 0x50,
 140                .route_val = BIT(16 + 11) | BIT(11),
 141        },
 142};
 143
 144static int rk3228_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 145{
 146        struct rockchip_pinctrl_priv *priv = bank->priv;
 147        int iomux_num = (pin / 8);
 148        struct regmap *regmap;
 149        int reg, ret, mask, mux_type;
 150        u8 bit;
 151        u32 data, route_reg, route_val;
 152
 153        regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
 154                                ? priv->regmap_pmu : priv->regmap_base;
 155
 156        /* get basic quadrupel of mux registers and the correct reg inside */
 157        mux_type = bank->iomux[iomux_num].type;
 158        reg = bank->iomux[iomux_num].offset;
 159        reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
 160
 161        if (bank->route_mask & BIT(pin)) {
 162                if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
 163                                           &route_val)) {
 164                        ret = regmap_write(regmap, route_reg, route_val);
 165                        if (ret)
 166                                return ret;
 167                }
 168        }
 169
 170        data = (mask << (bit + 16));
 171        data |= (mux & mask) << bit;
 172        ret = regmap_write(regmap, reg, data);
 173
 174        return ret;
 175}
 176
 177#define RK3228_PULL_OFFSET              0x100
 178
 179static void rk3228_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
 180                                         int pin_num, struct regmap **regmap,
 181                                         int *reg, u8 *bit)
 182{
 183        struct rockchip_pinctrl_priv *priv = bank->priv;
 184
 185        *regmap = priv->regmap_base;
 186        *reg = RK3228_PULL_OFFSET;
 187        *reg += bank->bank_num * ROCKCHIP_PULL_BANK_STRIDE;
 188        *reg += ((pin_num / ROCKCHIP_PULL_PINS_PER_REG) * 4);
 189
 190        *bit = (pin_num % ROCKCHIP_PULL_PINS_PER_REG);
 191        *bit *= ROCKCHIP_PULL_BITS_PER_PIN;
 192}
 193
 194static int rk3228_set_pull(struct rockchip_pin_bank *bank,
 195                           int pin_num, int pull)
 196{
 197        struct regmap *regmap;
 198        int reg, ret;
 199        u8 bit, type;
 200        u32 data;
 201
 202        if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
 203                return -ENOTSUPP;
 204
 205        rk3228_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
 206        type = bank->pull_type[pin_num / 8];
 207        ret = rockchip_translate_pull_value(type, pull);
 208        if (ret < 0) {
 209                debug("unsupported pull setting %d\n", pull);
 210                return ret;
 211        }
 212
 213        /* enable the write to the equivalent lower bits */
 214        data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
 215        data |= (ret << bit);
 216        ret = regmap_write(regmap, reg, data);
 217
 218        return ret;
 219}
 220
 221#define RK3228_DRV_GRF_OFFSET           0x200
 222
 223static void rk3228_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
 224                                        int pin_num, struct regmap **regmap,
 225                                        int *reg, u8 *bit)
 226{
 227        struct rockchip_pinctrl_priv *priv = bank->priv;
 228
 229        *regmap = priv->regmap_base;
 230        *reg = RK3228_DRV_GRF_OFFSET;
 231        *reg += bank->bank_num * ROCKCHIP_DRV_BANK_STRIDE;
 232        *reg += ((pin_num / ROCKCHIP_DRV_PINS_PER_REG) * 4);
 233
 234        *bit = (pin_num % ROCKCHIP_DRV_PINS_PER_REG);
 235        *bit *= ROCKCHIP_DRV_BITS_PER_PIN;
 236}
 237
 238static int rk3228_set_drive(struct rockchip_pin_bank *bank,
 239                            int pin_num, int strength)
 240{
 241        struct regmap *regmap;
 242        int reg, ret;
 243        u32 data;
 244        u8 bit;
 245        int type = bank->drv[pin_num / 8].drv_type;
 246
 247        rk3228_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
 248        ret = rockchip_translate_drive_value(type, strength);
 249        if (ret < 0) {
 250                debug("unsupported driver strength %d\n", strength);
 251                return ret;
 252        }
 253
 254        /* enable the write to the equivalent lower bits */
 255        data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16);
 256        data |= (ret << bit);
 257        ret = regmap_write(regmap, reg, data);
 258        return ret;
 259}
 260
 261static struct rockchip_pin_bank rk3228_pin_banks[] = {
 262        PIN_BANK(0, 32, "gpio0"),
 263        PIN_BANK(1, 32, "gpio1"),
 264        PIN_BANK(2, 32, "gpio2"),
 265        PIN_BANK(3, 32, "gpio3"),
 266};
 267
 268static struct rockchip_pin_ctrl rk3228_pin_ctrl = {
 269        .pin_banks              = rk3228_pin_banks,
 270        .nr_banks               = ARRAY_SIZE(rk3228_pin_banks),
 271        .grf_mux_offset         = 0x0,
 272        .iomux_routes           = rk3228_mux_route_data,
 273        .niomux_routes          = ARRAY_SIZE(rk3228_mux_route_data),
 274        .set_mux                = rk3228_set_mux,
 275        .set_pull               = rk3228_set_pull,
 276        .set_drive              = rk3228_set_drive,
 277};
 278
 279static const struct udevice_id rk3228_pinctrl_ids[] = {
 280        {
 281                .compatible = "rockchip,rk3228-pinctrl",
 282                .data = (ulong)&rk3228_pin_ctrl
 283        },
 284        { }
 285};
 286
 287U_BOOT_DRIVER(pinctrl_rk3228) = {
 288        .name           = "rockchip_rk3228_pinctrl",
 289        .id             = UCLASS_PINCTRL,
 290        .of_match       = rk3228_pinctrl_ids,
 291        .priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
 292        .ops            = &rockchip_pinctrl_ops,
 293#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 294        .bind           = dm_scan_fdt_dev,
 295#endif
 296        .probe          = rockchip_pinctrl_probe,
 297};
 298