uboot/drivers/pinctrl/rockchip/pinctrl-rk3288.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
  11#include "pinctrl-rockchip.h"
  12
  13static struct rockchip_mux_route_data rk3288_mux_route_data[] = {
  14        {
  15                /* edphdmi_cecinoutt1 */
  16                .bank_num = 7,
  17                .pin = 16,
  18                .func = 2,
  19                .route_offset = 0x264,
  20                .route_val = BIT(16 + 12) | BIT(12),
  21        }, {
  22                /* edphdmi_cecinout */
  23                .bank_num = 7,
  24                .pin = 23,
  25                .func = 4,
  26                .route_offset = 0x264,
  27                .route_val = BIT(16 + 12),
  28        },
  29};
  30
  31static int rk3288_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
  32{
  33        struct rockchip_pinctrl_priv *priv = bank->priv;
  34        int iomux_num = (pin / 8);
  35        struct regmap *regmap;
  36        int reg, ret, mask, mux_type;
  37        u8 bit;
  38        u32 data, route_reg, route_val;
  39
  40        regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
  41                                ? priv->regmap_pmu : priv->regmap_base;
  42
  43        /* get basic quadrupel of mux registers and the correct reg inside */
  44        mux_type = bank->iomux[iomux_num].type;
  45        reg = bank->iomux[iomux_num].offset;
  46        reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
  47
  48        if (bank->route_mask & BIT(pin)) {
  49                if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
  50                                           &route_val)) {
  51                        ret = regmap_write(regmap, route_reg, route_val);
  52                        if (ret)
  53                                return ret;
  54                }
  55        }
  56
  57        /* bank0 is special, there are no higher 16 bit writing bits. */
  58        if (bank->bank_num == 0) {
  59                regmap_read(regmap, reg, &data);
  60                data &= ~(mask << bit);
  61        } else {
  62                /* enable the write to the equivalent lower bits */
  63                data = (mask << (bit + 16));
  64        }
  65
  66        data |= (mux & mask) << bit;
  67        ret = regmap_write(regmap, reg, data);
  68
  69        return ret;
  70}
  71
  72#define RK3288_PULL_OFFSET              0x140
  73#define RK3288_PULL_PMU_OFFSET          0x64
  74
  75static void rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
  76                                         int pin_num, struct regmap **regmap,
  77                                         int *reg, u8 *bit)
  78{
  79        struct rockchip_pinctrl_priv *priv = bank->priv;
  80
  81        /* The first 24 pins of the first bank are located in PMU */
  82        if (bank->bank_num == 0) {
  83                *regmap = priv->regmap_pmu;
  84                *reg = RK3288_PULL_PMU_OFFSET;
  85        } else {
  86                *regmap = priv->regmap_base;
  87                *reg = RK3288_PULL_OFFSET;
  88
  89                /* correct the offset, as we're starting with the 2nd bank */
  90                *reg -= 0x10;
  91                *reg += bank->bank_num * ROCKCHIP_PULL_BANK_STRIDE;
  92        }
  93
  94        *reg += ((pin_num / ROCKCHIP_PULL_PINS_PER_REG) * 4);
  95
  96        *bit = (pin_num % ROCKCHIP_PULL_PINS_PER_REG);
  97        *bit *= ROCKCHIP_PULL_BITS_PER_PIN;
  98}
  99
 100static int rk3288_set_pull(struct rockchip_pin_bank *bank,
 101                           int pin_num, int pull)
 102{
 103        struct regmap *regmap;
 104        int reg, ret;
 105        u8 bit, type;
 106        u32 data;
 107
 108        if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
 109                return -ENOTSUPP;
 110
 111        rk3288_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
 112        type = bank->pull_type[pin_num / 8];
 113        ret = rockchip_translate_pull_value(type, pull);
 114        if (ret < 0) {
 115                debug("unsupported pull setting %d\n", pull);
 116                return ret;
 117        }
 118
 119        /* bank0 is special, there are no higher 16 bit writing bits */
 120        if (bank->bank_num == 0) {
 121                regmap_read(regmap, reg, &data);
 122                data &= ~(((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << bit);
 123        } else {
 124                /* enable the write to the equivalent lower bits */
 125                data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
 126        }
 127
 128        data |= (ret << bit);
 129        ret = regmap_write(regmap, reg, data);
 130
 131        return ret;
 132}
 133
 134#define RK3288_DRV_PMU_OFFSET           0x70
 135#define RK3288_DRV_GRF_OFFSET           0x1c0
 136
 137static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
 138                                        int pin_num, struct regmap **regmap,
 139                                        int *reg, u8 *bit)
 140{
 141        struct rockchip_pinctrl_priv *priv = bank->priv;
 142
 143        /* The first 24 pins of the first bank are located in PMU */
 144        if (bank->bank_num == 0) {
 145                *regmap = priv->regmap_pmu;
 146                *reg = RK3288_DRV_PMU_OFFSET;
 147        } else {
 148                *regmap = priv->regmap_base;
 149                *reg = RK3288_DRV_GRF_OFFSET;
 150
 151                /* correct the offset, as we're starting with the 2nd bank */
 152                *reg -= 0x10;
 153                *reg += bank->bank_num * ROCKCHIP_DRV_BANK_STRIDE;
 154        }
 155
 156        *reg += ((pin_num / ROCKCHIP_DRV_PINS_PER_REG) * 4);
 157        *bit = (pin_num % ROCKCHIP_DRV_PINS_PER_REG);
 158        *bit *= ROCKCHIP_DRV_BITS_PER_PIN;
 159}
 160
 161static int rk3288_set_drive(struct rockchip_pin_bank *bank,
 162                            int pin_num, int strength)
 163{
 164        struct regmap *regmap;
 165        int reg, ret;
 166        u32 data;
 167        u8 bit;
 168        int type = bank->drv[pin_num / 8].drv_type;
 169
 170        rk3288_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
 171        ret = rockchip_translate_drive_value(type, strength);
 172        if (ret < 0) {
 173                debug("unsupported driver strength %d\n", strength);
 174                return ret;
 175        }
 176
 177        /* bank0 is special, there are no higher 16 bit writing bits. */
 178        if (bank->bank_num == 0) {
 179                regmap_read(regmap, reg, &data);
 180                data &= ~(((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << bit);
 181        } else {
 182                /* enable the write to the equivalent lower bits */
 183                data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16);
 184        }
 185
 186        data |= (ret << bit);
 187        ret = regmap_write(regmap, reg, data);
 188        return ret;
 189}
 190
 191static struct rockchip_pin_bank rk3288_pin_banks[] = {
 192        PIN_BANK_IOMUX_FLAGS(0, 24, "gpio0", IOMUX_SOURCE_PMU,
 193                                             IOMUX_SOURCE_PMU,
 194                                             IOMUX_SOURCE_PMU,
 195                                             IOMUX_UNROUTED
 196                            ),
 197        PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_UNROUTED,
 198                                             IOMUX_UNROUTED,
 199                                             IOMUX_UNROUTED,
 200                                             0
 201                            ),
 202        PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, IOMUX_UNROUTED),
 203        PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, IOMUX_WIDTH_4BIT),
 204        PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
 205                                             IOMUX_WIDTH_4BIT,
 206                                             0,
 207                                             0
 208                            ),
 209        PIN_BANK_IOMUX_FLAGS(5, 32, "gpio5", IOMUX_UNROUTED,
 210                                             0,
 211                                             0,
 212                                             IOMUX_UNROUTED
 213                            ),
 214        PIN_BANK_IOMUX_FLAGS(6, 32, "gpio6", 0, 0, 0, IOMUX_UNROUTED),
 215        PIN_BANK_IOMUX_FLAGS(7, 32, "gpio7", 0,
 216                                             0,
 217                                             IOMUX_WIDTH_4BIT,
 218                                             IOMUX_UNROUTED
 219                            ),
 220        PIN_BANK(8, 16, "gpio8"),
 221};
 222
 223static struct rockchip_pin_ctrl rk3288_pin_ctrl = {
 224        .pin_banks              = rk3288_pin_banks,
 225        .nr_banks               = ARRAY_SIZE(rk3288_pin_banks),
 226        .grf_mux_offset         = 0x0,
 227        .pmu_mux_offset         = 0x84,
 228        .iomux_routes           = rk3288_mux_route_data,
 229        .niomux_routes          = ARRAY_SIZE(rk3288_mux_route_data),
 230        .set_mux                = rk3288_set_mux,
 231        .set_pull               = rk3288_set_pull,
 232        .set_drive              = rk3288_set_drive,
 233};
 234
 235static const struct udevice_id rk3288_pinctrl_ids[] = {
 236        {
 237                .compatible = "rockchip,rk3288-pinctrl",
 238                .data = (ulong)&rk3288_pin_ctrl
 239        },
 240        { }
 241};
 242
 243U_BOOT_DRIVER(pinctrl_rk3288) = {
 244        .name           = "rockchip_rk3288_pinctrl",
 245        .id             = UCLASS_PINCTRL,
 246        .of_match       = rk3288_pinctrl_ids,
 247        .priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
 248        .ops            = &rockchip_pinctrl_ops,
 249#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 250        .bind           = dm_scan_fdt_dev,
 251#endif
 252        .probe          = rockchip_pinctrl_probe,
 253};
 254