1*e7ae4cf2SDavid Wu // SPDX-License-Identifier: GPL-2.0+ 2*e7ae4cf2SDavid Wu /* 3*e7ae4cf2SDavid Wu * (C) Copyright 2019 Rockchip Electronics Co., Ltd 4*e7ae4cf2SDavid Wu */ 5*e7ae4cf2SDavid Wu 6*e7ae4cf2SDavid Wu #include <common.h> 7*e7ae4cf2SDavid Wu #include <dm.h> 8*e7ae4cf2SDavid Wu #include <dm/pinctrl.h> 9*e7ae4cf2SDavid Wu #include <regmap.h> 10*e7ae4cf2SDavid Wu #include <syscon.h> 11*e7ae4cf2SDavid Wu 12*e7ae4cf2SDavid Wu #include "pinctrl-rockchip.h" 13*e7ae4cf2SDavid Wu 14*e7ae4cf2SDavid Wu static struct rockchip_mux_recalced_data rv1108_mux_recalced_data[] = { 15*e7ae4cf2SDavid Wu { 16*e7ae4cf2SDavid Wu .num = 1, 17*e7ae4cf2SDavid Wu .pin = 0, 18*e7ae4cf2SDavid Wu .reg = 0x418, 19*e7ae4cf2SDavid Wu .bit = 0, 20*e7ae4cf2SDavid Wu .mask = 0x3 21*e7ae4cf2SDavid Wu }, { 22*e7ae4cf2SDavid Wu .num = 1, 23*e7ae4cf2SDavid Wu .pin = 1, 24*e7ae4cf2SDavid Wu .reg = 0x418, 25*e7ae4cf2SDavid Wu .bit = 2, 26*e7ae4cf2SDavid Wu .mask = 0x3 27*e7ae4cf2SDavid Wu }, { 28*e7ae4cf2SDavid Wu .num = 1, 29*e7ae4cf2SDavid Wu .pin = 2, 30*e7ae4cf2SDavid Wu .reg = 0x418, 31*e7ae4cf2SDavid Wu .bit = 4, 32*e7ae4cf2SDavid Wu .mask = 0x3 33*e7ae4cf2SDavid Wu }, { 34*e7ae4cf2SDavid Wu .num = 1, 35*e7ae4cf2SDavid Wu .pin = 3, 36*e7ae4cf2SDavid Wu .reg = 0x418, 37*e7ae4cf2SDavid Wu .bit = 6, 38*e7ae4cf2SDavid Wu .mask = 0x3 39*e7ae4cf2SDavid Wu }, { 40*e7ae4cf2SDavid Wu .num = 1, 41*e7ae4cf2SDavid Wu .pin = 4, 42*e7ae4cf2SDavid Wu .reg = 0x418, 43*e7ae4cf2SDavid Wu .bit = 8, 44*e7ae4cf2SDavid Wu .mask = 0x3 45*e7ae4cf2SDavid Wu }, { 46*e7ae4cf2SDavid Wu .num = 1, 47*e7ae4cf2SDavid Wu .pin = 5, 48*e7ae4cf2SDavid Wu .reg = 0x418, 49*e7ae4cf2SDavid Wu .bit = 10, 50*e7ae4cf2SDavid Wu .mask = 0x3 51*e7ae4cf2SDavid Wu }, { 52*e7ae4cf2SDavid Wu .num = 1, 53*e7ae4cf2SDavid Wu .pin = 6, 54*e7ae4cf2SDavid Wu .reg = 0x418, 55*e7ae4cf2SDavid Wu .bit = 12, 56*e7ae4cf2SDavid Wu .mask = 0x3 57*e7ae4cf2SDavid Wu }, { 58*e7ae4cf2SDavid Wu .num = 1, 59*e7ae4cf2SDavid Wu .pin = 7, 60*e7ae4cf2SDavid Wu .reg = 0x418, 61*e7ae4cf2SDavid Wu .bit = 14, 62*e7ae4cf2SDavid Wu .mask = 0x3 63*e7ae4cf2SDavid Wu }, { 64*e7ae4cf2SDavid Wu .num = 1, 65*e7ae4cf2SDavid Wu .pin = 8, 66*e7ae4cf2SDavid Wu .reg = 0x41c, 67*e7ae4cf2SDavid Wu .bit = 0, 68*e7ae4cf2SDavid Wu .mask = 0x3 69*e7ae4cf2SDavid Wu }, { 70*e7ae4cf2SDavid Wu .num = 1, 71*e7ae4cf2SDavid Wu .pin = 9, 72*e7ae4cf2SDavid Wu .reg = 0x41c, 73*e7ae4cf2SDavid Wu .bit = 2, 74*e7ae4cf2SDavid Wu .mask = 0x3 75*e7ae4cf2SDavid Wu }, 76*e7ae4cf2SDavid Wu }; 77*e7ae4cf2SDavid Wu 78*e7ae4cf2SDavid Wu #define RV1108_PULL_PMU_OFFSET 0x10 79*e7ae4cf2SDavid Wu #define RV1108_PULL_OFFSET 0x110 80*e7ae4cf2SDavid Wu 81*e7ae4cf2SDavid Wu static void rv1108_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 82*e7ae4cf2SDavid Wu int pin_num, struct regmap **regmap, 83*e7ae4cf2SDavid Wu int *reg, u8 *bit) 84*e7ae4cf2SDavid Wu { 85*e7ae4cf2SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 86*e7ae4cf2SDavid Wu 87*e7ae4cf2SDavid Wu /* The first 24 pins of the first bank are located in PMU */ 88*e7ae4cf2SDavid Wu if (bank->bank_num == 0) { 89*e7ae4cf2SDavid Wu *regmap = priv->regmap_pmu; 90*e7ae4cf2SDavid Wu *reg = RV1108_PULL_PMU_OFFSET; 91*e7ae4cf2SDavid Wu } else { 92*e7ae4cf2SDavid Wu *reg = RV1108_PULL_OFFSET; 93*e7ae4cf2SDavid Wu *regmap = priv->regmap_base; 94*e7ae4cf2SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 95*e7ae4cf2SDavid Wu *reg -= 0x10; 96*e7ae4cf2SDavid Wu *reg += bank->bank_num * ROCKCHIP_PULL_BANK_STRIDE; 97*e7ae4cf2SDavid Wu } 98*e7ae4cf2SDavid Wu 99*e7ae4cf2SDavid Wu *reg += ((pin_num / ROCKCHIP_PULL_PINS_PER_REG) * 4); 100*e7ae4cf2SDavid Wu *bit = (pin_num % ROCKCHIP_PULL_PINS_PER_REG); 101*e7ae4cf2SDavid Wu *bit *= ROCKCHIP_PULL_BITS_PER_PIN; 102*e7ae4cf2SDavid Wu } 103*e7ae4cf2SDavid Wu 104*e7ae4cf2SDavid Wu #define RV1108_DRV_PMU_OFFSET 0x20 105*e7ae4cf2SDavid Wu #define RV1108_DRV_GRF_OFFSET 0x210 106*e7ae4cf2SDavid Wu 107*e7ae4cf2SDavid Wu static void rv1108_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 108*e7ae4cf2SDavid Wu int pin_num, struct regmap **regmap, 109*e7ae4cf2SDavid Wu int *reg, u8 *bit) 110*e7ae4cf2SDavid Wu { 111*e7ae4cf2SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 112*e7ae4cf2SDavid Wu 113*e7ae4cf2SDavid Wu /* The first 24 pins of the first bank are located in PMU */ 114*e7ae4cf2SDavid Wu if (bank->bank_num == 0) { 115*e7ae4cf2SDavid Wu *regmap = priv->regmap_pmu; 116*e7ae4cf2SDavid Wu *reg = RV1108_DRV_PMU_OFFSET; 117*e7ae4cf2SDavid Wu } else { 118*e7ae4cf2SDavid Wu *regmap = priv->regmap_base; 119*e7ae4cf2SDavid Wu *reg = RV1108_DRV_GRF_OFFSET; 120*e7ae4cf2SDavid Wu 121*e7ae4cf2SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 122*e7ae4cf2SDavid Wu *reg -= 0x10; 123*e7ae4cf2SDavid Wu *reg += bank->bank_num * ROCKCHIP_DRV_BANK_STRIDE; 124*e7ae4cf2SDavid Wu } 125*e7ae4cf2SDavid Wu 126*e7ae4cf2SDavid Wu *reg += ((pin_num / ROCKCHIP_DRV_PINS_PER_REG) * 4); 127*e7ae4cf2SDavid Wu *bit = pin_num % ROCKCHIP_DRV_PINS_PER_REG; 128*e7ae4cf2SDavid Wu *bit *= ROCKCHIP_DRV_BITS_PER_PIN; 129*e7ae4cf2SDavid Wu } 130*e7ae4cf2SDavid Wu 131*e7ae4cf2SDavid Wu #define RV1108_SCHMITT_PMU_OFFSET 0x30 132*e7ae4cf2SDavid Wu #define RV1108_SCHMITT_GRF_OFFSET 0x388 133*e7ae4cf2SDavid Wu #define RV1108_SCHMITT_BANK_STRIDE 8 134*e7ae4cf2SDavid Wu #define RV1108_SCHMITT_PINS_PER_GRF_REG 16 135*e7ae4cf2SDavid Wu #define RV1108_SCHMITT_PINS_PER_PMU_REG 8 136*e7ae4cf2SDavid Wu 137*e7ae4cf2SDavid Wu static int rv1108_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 138*e7ae4cf2SDavid Wu int pin_num, 139*e7ae4cf2SDavid Wu struct regmap **regmap, 140*e7ae4cf2SDavid Wu int *reg, u8 *bit) 141*e7ae4cf2SDavid Wu { 142*e7ae4cf2SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 143*e7ae4cf2SDavid Wu int pins_per_reg; 144*e7ae4cf2SDavid Wu 145*e7ae4cf2SDavid Wu if (bank->bank_num == 0) { 146*e7ae4cf2SDavid Wu *regmap = priv->regmap_pmu; 147*e7ae4cf2SDavid Wu *reg = RV1108_SCHMITT_PMU_OFFSET; 148*e7ae4cf2SDavid Wu pins_per_reg = RV1108_SCHMITT_PINS_PER_PMU_REG; 149*e7ae4cf2SDavid Wu } else { 150*e7ae4cf2SDavid Wu *regmap = priv->regmap_base; 151*e7ae4cf2SDavid Wu *reg = RV1108_SCHMITT_GRF_OFFSET; 152*e7ae4cf2SDavid Wu pins_per_reg = RV1108_SCHMITT_PINS_PER_GRF_REG; 153*e7ae4cf2SDavid Wu *reg += (bank->bank_num - 1) * RV1108_SCHMITT_BANK_STRIDE; 154*e7ae4cf2SDavid Wu } 155*e7ae4cf2SDavid Wu *reg += ((pin_num / pins_per_reg) * 4); 156*e7ae4cf2SDavid Wu *bit = pin_num % pins_per_reg; 157*e7ae4cf2SDavid Wu 158*e7ae4cf2SDavid Wu return 0; 159*e7ae4cf2SDavid Wu } 160*e7ae4cf2SDavid Wu 161*e7ae4cf2SDavid Wu static struct rockchip_pin_bank rv1108_pin_banks[] = { 162*e7ae4cf2SDavid Wu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, 163*e7ae4cf2SDavid Wu IOMUX_SOURCE_PMU, 164*e7ae4cf2SDavid Wu IOMUX_SOURCE_PMU, 165*e7ae4cf2SDavid Wu IOMUX_SOURCE_PMU), 166*e7ae4cf2SDavid Wu PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0), 167*e7ae4cf2SDavid Wu PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, 0), 168*e7ae4cf2SDavid Wu PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, 0), 169*e7ae4cf2SDavid Wu }; 170*e7ae4cf2SDavid Wu 171*e7ae4cf2SDavid Wu static struct rockchip_pin_ctrl rv1108_pin_ctrl = { 172*e7ae4cf2SDavid Wu .pin_banks = rv1108_pin_banks, 173*e7ae4cf2SDavid Wu .nr_banks = ARRAY_SIZE(rv1108_pin_banks), 174*e7ae4cf2SDavid Wu .label = "RV1108-GPIO", 175*e7ae4cf2SDavid Wu .type = RV1108, 176*e7ae4cf2SDavid Wu .grf_mux_offset = 0x10, 177*e7ae4cf2SDavid Wu .pmu_mux_offset = 0x0, 178*e7ae4cf2SDavid Wu .iomux_recalced = rv1108_mux_recalced_data, 179*e7ae4cf2SDavid Wu .niomux_recalced = ARRAY_SIZE(rv1108_mux_recalced_data), 180*e7ae4cf2SDavid Wu .pull_calc_reg = rv1108_calc_pull_reg_and_bit, 181*e7ae4cf2SDavid Wu .drv_calc_reg = rv1108_calc_drv_reg_and_bit, 182*e7ae4cf2SDavid Wu .schmitt_calc_reg = rv1108_calc_schmitt_reg_and_bit, 183*e7ae4cf2SDavid Wu }; 184*e7ae4cf2SDavid Wu 185*e7ae4cf2SDavid Wu static const struct udevice_id rv1108_pinctrl_ids[] = { 186*e7ae4cf2SDavid Wu { 187*e7ae4cf2SDavid Wu .compatible = "rockchip,rv1108-pinctrl", 188*e7ae4cf2SDavid Wu .data = (ulong)&rv1108_pin_ctrl 189*e7ae4cf2SDavid Wu }, 190*e7ae4cf2SDavid Wu { } 191*e7ae4cf2SDavid Wu }; 192*e7ae4cf2SDavid Wu 193*e7ae4cf2SDavid Wu U_BOOT_DRIVER(pinctrl_rv1108) = { 194*e7ae4cf2SDavid Wu .name = "pinctrl_rv1108", 195*e7ae4cf2SDavid Wu .id = UCLASS_PINCTRL, 196*e7ae4cf2SDavid Wu .of_match = rv1108_pinctrl_ids, 197*e7ae4cf2SDavid Wu .priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv), 198*e7ae4cf2SDavid Wu .ops = &rockchip_pinctrl_ops, 199*e7ae4cf2SDavid Wu #if !CONFIG_IS_ENABLED(OF_PLATDATA) 200*e7ae4cf2SDavid Wu .bind = dm_scan_fdt_dev, 201*e7ae4cf2SDavid Wu #endif 202*e7ae4cf2SDavid Wu .probe = rockchip_pinctrl_probe, 203*e7ae4cf2SDavid Wu }; 204