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 <log.h> 9#include <dm/pinctrl.h> 10#include <regmap.h> 11#include <syscon.h> 12 13#include "pinctrl-rockchip.h" 14 15static int rk3188_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) 16{ 17 struct rockchip_pinctrl_priv *priv = bank->priv; 18 int iomux_num = (pin / 8); 19 struct regmap *regmap; 20 int reg, ret, mask, mux_type; 21 u8 bit; 22 u32 data; 23 24 regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) 25 ? priv->regmap_pmu : priv->regmap_base; 26 27 /* get basic quadrupel of mux registers and the correct reg inside */ 28 mux_type = bank->iomux[iomux_num].type; 29 reg = bank->iomux[iomux_num].offset; 30 reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask); 31 32 data = (mask << (bit + 16)); 33 data |= (mux & mask) << bit; 34 ret = regmap_write(regmap, reg, data); 35 36 return ret; 37} 38 39#define RK3188_PULL_OFFSET 0x164 40#define RK3188_PULL_PMU_OFFSET 0x64 41 42static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 43 int pin_num, struct regmap **regmap, 44 int *reg, u8 *bit) 45{ 46 struct rockchip_pinctrl_priv *priv = bank->priv; 47 48 /* The first 12 pins of the first bank are located elsewhere */ 49 if (bank->bank_num == 0 && pin_num < 12) { 50 *regmap = priv->regmap_pmu; 51 *reg = RK3188_PULL_PMU_OFFSET; 52 53 *reg += ((pin_num / ROCKCHIP_PULL_PINS_PER_REG) * 4); 54 *bit = pin_num % ROCKCHIP_PULL_PINS_PER_REG; 55 *bit *= ROCKCHIP_PULL_BITS_PER_PIN; 56 } else { 57 *regmap = priv->regmap_base; 58 *reg = RK3188_PULL_OFFSET; 59 60 /* correct the offset, as it is the 2nd pull register */ 61 *reg -= 4; 62 *reg += bank->bank_num * ROCKCHIP_PULL_BANK_STRIDE; 63 *reg += ((pin_num / ROCKCHIP_PULL_PINS_PER_REG) * 4); 64 65 /* 66 * The bits in these registers have an inverse ordering 67 * with the lowest pin being in bits 15:14 and the highest 68 * pin in bits 1:0 69 */ 70 *bit = 7 - (pin_num % ROCKCHIP_PULL_PINS_PER_REG); 71 *bit *= ROCKCHIP_PULL_BITS_PER_PIN; 72 } 73} 74 75static int rk3188_set_pull(struct rockchip_pin_bank *bank, 76 int pin_num, int pull) 77{ 78 struct regmap *regmap; 79 int reg, ret; 80 u8 bit, type; 81 u32 data; 82 83 if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) 84 return -ENOTSUPP; 85 86 rk3188_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); 87 type = bank->pull_type[pin_num / 8]; 88 ret = rockchip_translate_pull_value(type, pull); 89 if (ret < 0) { 90 debug("unsupported pull setting %d\n", pull); 91 return ret; 92 } 93 94 /* enable the write to the equivalent lower bits */ 95 data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); 96 data |= (ret << bit); 97 ret = regmap_write(regmap, reg, data); 98 99 return ret; 100} 101 102static struct rockchip_pin_bank rk3188_pin_banks[] = { 103 PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_GPIO_ONLY, 0, 0, 0), 104 PIN_BANK(1, 32, "gpio1"), 105 PIN_BANK(2, 32, "gpio2"), 106 PIN_BANK(3, 32, "gpio3"), 107}; 108 109static struct rockchip_pin_ctrl rk3188_pin_ctrl = { 110 .pin_banks = rk3188_pin_banks, 111 .nr_banks = ARRAY_SIZE(rk3188_pin_banks), 112 .grf_mux_offset = 0x60, 113 .set_mux = rk3188_set_mux, 114 .set_pull = rk3188_set_pull, 115}; 116 117static const struct udevice_id rk3188_pinctrl_ids[] = { 118 { .compatible = "rockchip,rk3188-pinctrl", 119 .data = (ulong)&rk3188_pin_ctrl }, 120 { } 121}; 122 123U_BOOT_DRIVER(rockchip_rk3188_pinctrl) = { 124 .name = "rockchip_rk3188_pinctrl", 125 .id = UCLASS_PINCTRL, 126 .of_match = rk3188_pinctrl_ids, 127 .priv_auto = sizeof(struct rockchip_pinctrl_priv), 128 .ops = &rockchip_pinctrl_ops, 129#if CONFIG_IS_ENABLED(OF_REAL) 130 .bind = dm_scan_fdt_dev, 131#endif 132 .probe = rockchip_pinctrl_probe, 133}; 134