149c55878SDavid Wu /* 249c55878SDavid Wu * (C) Copyright 2018 Rockchip Electronics Co., Ltd 349c55878SDavid Wu * 449c55878SDavid Wu * SPDX-License-Identifier: GPL-2.0+ 549c55878SDavid Wu */ 649c55878SDavid Wu 749c55878SDavid Wu #include <common.h> 849c55878SDavid Wu #include <dm.h> 949c55878SDavid Wu #include <dm/pinctrl.h> 102208cfa9SKever Yang #include <dm/ofnode.h> 1149c55878SDavid Wu #include <regmap.h> 1249c55878SDavid Wu #include <syscon.h> 1349c55878SDavid Wu 1449c55878SDavid Wu #define MAX_ROCKCHIP_GPIO_PER_BANK 32 1549c55878SDavid Wu #define RK_FUNC_GPIO 0 1687f0ac57SDavid Wu #define MAX_ROCKCHIP_PINS_ENTRIES 30 1749c55878SDavid Wu 1849c55878SDavid Wu enum rockchip_pinctrl_type { 1949c55878SDavid Wu PX30, 2049c55878SDavid Wu RV1108, 2149c55878SDavid Wu RK2928, 2249c55878SDavid Wu RK3066B, 2349c55878SDavid Wu RK3128, 2449c55878SDavid Wu RK3188, 2549c55878SDavid Wu RK3288, 26b3077611SDavid Wu RK3308, 2749c55878SDavid Wu RK3368, 2849c55878SDavid Wu RK3399, 2949c55878SDavid Wu }; 3049c55878SDavid Wu 3149c55878SDavid Wu /** 3249c55878SDavid Wu * Encode variants of iomux registers into a type variable 3349c55878SDavid Wu */ 3449c55878SDavid Wu #define IOMUX_GPIO_ONLY BIT(0) 3549c55878SDavid Wu #define IOMUX_WIDTH_4BIT BIT(1) 3649c55878SDavid Wu #define IOMUX_SOURCE_PMU BIT(2) 3749c55878SDavid Wu #define IOMUX_UNROUTED BIT(3) 3849c55878SDavid Wu #define IOMUX_WIDTH_3BIT BIT(4) 39b3077611SDavid Wu #define IOMUX_8WIDTH_2BIT BIT(5) 404bafc2daSDavid Wu #define IOMUX_WRITABLE_32BIT BIT(6) 4149c55878SDavid Wu 4249c55878SDavid Wu /** 4349c55878SDavid Wu * @type: iomux variant using IOMUX_* constants 4449c55878SDavid Wu * @offset: if initialized to -1 it will be autocalculated, by specifying 4549c55878SDavid Wu * an initial offset value the relevant source offset can be reset 4649c55878SDavid Wu * to a new value for autocalculating the following iomux registers. 4749c55878SDavid Wu */ 4849c55878SDavid Wu struct rockchip_iomux { 4949c55878SDavid Wu int type; 5049c55878SDavid Wu int offset; 5149c55878SDavid Wu }; 5249c55878SDavid Wu 53*55a89bc6SDavid Wu #define DRV_TYPE_IO_MASK GENMASK(31, 16) 54*55a89bc6SDavid Wu #define DRV_TYPE_WRITABLE_32BIT BIT(31) 55*55a89bc6SDavid Wu 5649c55878SDavid Wu /** 5749c55878SDavid Wu * enum type index corresponding to rockchip_perpin_drv_list arrays index. 5849c55878SDavid Wu */ 5949c55878SDavid Wu enum rockchip_pin_drv_type { 6049c55878SDavid Wu DRV_TYPE_IO_DEFAULT = 0, 6149c55878SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 6249c55878SDavid Wu DRV_TYPE_IO_1V8_ONLY, 6349c55878SDavid Wu DRV_TYPE_IO_1V8_3V0_AUTO, 6449c55878SDavid Wu DRV_TYPE_IO_3V3_ONLY, 6549c55878SDavid Wu DRV_TYPE_MAX 6649c55878SDavid Wu }; 6749c55878SDavid Wu 68*55a89bc6SDavid Wu #define PULL_TYPE_IO_MASK GENMASK(31, 16) 69*55a89bc6SDavid Wu #define PULL_TYPE_WRITABLE_32BIT BIT(31) 70*55a89bc6SDavid Wu 7149c55878SDavid Wu /** 7249c55878SDavid Wu * enum type index corresponding to rockchip_pull_list arrays index. 7349c55878SDavid Wu */ 7449c55878SDavid Wu enum rockchip_pin_pull_type { 7549c55878SDavid Wu PULL_TYPE_IO_DEFAULT = 0, 7649c55878SDavid Wu PULL_TYPE_IO_1V8_ONLY, 7749c55878SDavid Wu PULL_TYPE_MAX 7849c55878SDavid Wu }; 7949c55878SDavid Wu 8049c55878SDavid Wu /** 8149c55878SDavid Wu * @drv_type: drive strength variant using rockchip_perpin_drv_type 8249c55878SDavid Wu * @offset: if initialized to -1 it will be autocalculated, by specifying 8349c55878SDavid Wu * an initial offset value the relevant source offset can be reset 8449c55878SDavid Wu * to a new value for autocalculating the following drive strength 8549c55878SDavid Wu * registers. if used chips own cal_drv func instead to calculate 8649c55878SDavid Wu * registers offset, the variant could be ignored. 8749c55878SDavid Wu */ 8849c55878SDavid Wu struct rockchip_drv { 8949c55878SDavid Wu enum rockchip_pin_drv_type drv_type; 9049c55878SDavid Wu int offset; 9149c55878SDavid Wu }; 9249c55878SDavid Wu 9349c55878SDavid Wu /** 9449c55878SDavid Wu * @priv: common pinctrl private basedata 9549c55878SDavid Wu * @pin_base: first pin number 9649c55878SDavid Wu * @nr_pins: number of pins in this bank 9749c55878SDavid Wu * @name: name of the bank 9849c55878SDavid Wu * @bank_num: number of the bank, to account for holes 9949c55878SDavid Wu * @iomux: array describing the 4 iomux sources of the bank 10049c55878SDavid Wu * @drv: array describing the 4 drive strength sources of the bank 10149c55878SDavid Wu * @pull_type: array describing the 4 pull type sources of the bank 10249c55878SDavid Wu * @recalced_mask: bits describing the mux recalced pins of per bank 10349c55878SDavid Wu * @route_mask: bits describing the routing pins of per bank 10449c55878SDavid Wu */ 10549c55878SDavid Wu struct rockchip_pin_bank { 10649c55878SDavid Wu struct rockchip_pinctrl_priv *priv; 10749c55878SDavid Wu u32 pin_base; 10849c55878SDavid Wu u8 nr_pins; 10949c55878SDavid Wu char *name; 11049c55878SDavid Wu u8 bank_num; 11149c55878SDavid Wu struct rockchip_iomux iomux[4]; 11249c55878SDavid Wu struct rockchip_drv drv[4]; 11349c55878SDavid Wu enum rockchip_pin_pull_type pull_type[4]; 11449c55878SDavid Wu u32 recalced_mask; 11549c55878SDavid Wu u32 route_mask; 11649c55878SDavid Wu }; 11749c55878SDavid Wu 11849c55878SDavid Wu #define PIN_BANK(id, pins, label) \ 11949c55878SDavid Wu { \ 12049c55878SDavid Wu .bank_num = id, \ 12149c55878SDavid Wu .nr_pins = pins, \ 12249c55878SDavid Wu .name = label, \ 12349c55878SDavid Wu .iomux = { \ 12449c55878SDavid Wu { .offset = -1 }, \ 12549c55878SDavid Wu { .offset = -1 }, \ 12649c55878SDavid Wu { .offset = -1 }, \ 12749c55878SDavid Wu { .offset = -1 }, \ 12849c55878SDavid Wu }, \ 12949c55878SDavid Wu } 13049c55878SDavid Wu 13149c55878SDavid Wu #define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3) \ 13249c55878SDavid Wu { \ 13349c55878SDavid Wu .bank_num = id, \ 13449c55878SDavid Wu .nr_pins = pins, \ 13549c55878SDavid Wu .name = label, \ 13649c55878SDavid Wu .iomux = { \ 13749c55878SDavid Wu { .type = iom0, .offset = -1 }, \ 13849c55878SDavid Wu { .type = iom1, .offset = -1 }, \ 13949c55878SDavid Wu { .type = iom2, .offset = -1 }, \ 14049c55878SDavid Wu { .type = iom3, .offset = -1 }, \ 14149c55878SDavid Wu }, \ 14249c55878SDavid Wu } 14349c55878SDavid Wu 14449c55878SDavid Wu #define PIN_BANK_DRV_FLAGS(id, pins, label, type0, type1, type2, type3) \ 14549c55878SDavid Wu { \ 14649c55878SDavid Wu .bank_num = id, \ 14749c55878SDavid Wu .nr_pins = pins, \ 14849c55878SDavid Wu .name = label, \ 14949c55878SDavid Wu .iomux = { \ 15049c55878SDavid Wu { .offset = -1 }, \ 15149c55878SDavid Wu { .offset = -1 }, \ 15249c55878SDavid Wu { .offset = -1 }, \ 15349c55878SDavid Wu { .offset = -1 }, \ 15449c55878SDavid Wu }, \ 15549c55878SDavid Wu .drv = { \ 15649c55878SDavid Wu { .drv_type = type0, .offset = -1 }, \ 15749c55878SDavid Wu { .drv_type = type1, .offset = -1 }, \ 15849c55878SDavid Wu { .drv_type = type2, .offset = -1 }, \ 15949c55878SDavid Wu { .drv_type = type3, .offset = -1 }, \ 16049c55878SDavid Wu }, \ 16149c55878SDavid Wu } 16249c55878SDavid Wu 16349c55878SDavid Wu #define PIN_BANK_DRV_FLAGS_PULL_FLAGS(id, pins, label, drv0, drv1, \ 16449c55878SDavid Wu drv2, drv3, pull0, pull1, \ 16549c55878SDavid Wu pull2, pull3) \ 16649c55878SDavid Wu { \ 16749c55878SDavid Wu .bank_num = id, \ 16849c55878SDavid Wu .nr_pins = pins, \ 16949c55878SDavid Wu .name = label, \ 17049c55878SDavid Wu .iomux = { \ 17149c55878SDavid Wu { .offset = -1 }, \ 17249c55878SDavid Wu { .offset = -1 }, \ 17349c55878SDavid Wu { .offset = -1 }, \ 17449c55878SDavid Wu { .offset = -1 }, \ 17549c55878SDavid Wu }, \ 17649c55878SDavid Wu .drv = { \ 17749c55878SDavid Wu { .drv_type = drv0, .offset = -1 }, \ 17849c55878SDavid Wu { .drv_type = drv1, .offset = -1 }, \ 17949c55878SDavid Wu { .drv_type = drv2, .offset = -1 }, \ 18049c55878SDavid Wu { .drv_type = drv3, .offset = -1 }, \ 18149c55878SDavid Wu }, \ 18249c55878SDavid Wu .pull_type[0] = pull0, \ 18349c55878SDavid Wu .pull_type[1] = pull1, \ 18449c55878SDavid Wu .pull_type[2] = pull2, \ 18549c55878SDavid Wu .pull_type[3] = pull3, \ 18649c55878SDavid Wu } 18749c55878SDavid Wu 18849c55878SDavid Wu #define PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(id, pins, label, iom0, iom1, \ 18949c55878SDavid Wu iom2, iom3, drv0, drv1, drv2, \ 19049c55878SDavid Wu drv3, offset0, offset1, \ 19149c55878SDavid Wu offset2, offset3) \ 19249c55878SDavid Wu { \ 19349c55878SDavid Wu .bank_num = id, \ 19449c55878SDavid Wu .nr_pins = pins, \ 19549c55878SDavid Wu .name = label, \ 19649c55878SDavid Wu .iomux = { \ 19749c55878SDavid Wu { .type = iom0, .offset = -1 }, \ 19849c55878SDavid Wu { .type = iom1, .offset = -1 }, \ 19949c55878SDavid Wu { .type = iom2, .offset = -1 }, \ 20049c55878SDavid Wu { .type = iom3, .offset = -1 }, \ 20149c55878SDavid Wu }, \ 20249c55878SDavid Wu .drv = { \ 20349c55878SDavid Wu { .drv_type = drv0, .offset = offset0 }, \ 20449c55878SDavid Wu { .drv_type = drv1, .offset = offset1 }, \ 20549c55878SDavid Wu { .drv_type = drv2, .offset = offset2 }, \ 20649c55878SDavid Wu { .drv_type = drv3, .offset = offset3 }, \ 20749c55878SDavid Wu }, \ 20849c55878SDavid Wu } 20949c55878SDavid Wu 210*55a89bc6SDavid Wu #define PIN_BANK_IOMUX_DRV_PULL_FLAGS(id, pins, label, iom0, iom1, \ 211*55a89bc6SDavid Wu iom2, iom3, drv0, drv1, drv2, \ 212*55a89bc6SDavid Wu drv3, pull0, pull1, pull2, \ 213*55a89bc6SDavid Wu pull3) \ 214*55a89bc6SDavid Wu { \ 215*55a89bc6SDavid Wu .bank_num = id, \ 216*55a89bc6SDavid Wu .nr_pins = pins, \ 217*55a89bc6SDavid Wu .name = label, \ 218*55a89bc6SDavid Wu .iomux = { \ 219*55a89bc6SDavid Wu { .type = iom0, .offset = -1 }, \ 220*55a89bc6SDavid Wu { .type = iom1, .offset = -1 }, \ 221*55a89bc6SDavid Wu { .type = iom2, .offset = -1 }, \ 222*55a89bc6SDavid Wu { .type = iom3, .offset = -1 }, \ 223*55a89bc6SDavid Wu }, \ 224*55a89bc6SDavid Wu .drv = { \ 225*55a89bc6SDavid Wu { .drv_type = drv0, .offset = -1 }, \ 226*55a89bc6SDavid Wu { .drv_type = drv1, .offset = -1 }, \ 227*55a89bc6SDavid Wu { .drv_type = drv2, .offset = -1 }, \ 228*55a89bc6SDavid Wu { .drv_type = drv3, .offset = -1 }, \ 229*55a89bc6SDavid Wu }, \ 230*55a89bc6SDavid Wu .pull_type[0] = pull0, \ 231*55a89bc6SDavid Wu .pull_type[1] = pull1, \ 232*55a89bc6SDavid Wu .pull_type[2] = pull2, \ 233*55a89bc6SDavid Wu .pull_type[3] = pull3, \ 234*55a89bc6SDavid Wu } 235*55a89bc6SDavid Wu 23649c55878SDavid Wu #define PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(id, pins, \ 23749c55878SDavid Wu label, iom0, iom1, iom2, \ 23849c55878SDavid Wu iom3, drv0, drv1, drv2, \ 23949c55878SDavid Wu drv3, offset0, offset1, \ 24049c55878SDavid Wu offset2, offset3, pull0, \ 24149c55878SDavid Wu pull1, pull2, pull3) \ 24249c55878SDavid Wu { \ 24349c55878SDavid Wu .bank_num = id, \ 24449c55878SDavid Wu .nr_pins = pins, \ 24549c55878SDavid Wu .name = label, \ 24649c55878SDavid Wu .iomux = { \ 24749c55878SDavid Wu { .type = iom0, .offset = -1 }, \ 24849c55878SDavid Wu { .type = iom1, .offset = -1 }, \ 24949c55878SDavid Wu { .type = iom2, .offset = -1 }, \ 25049c55878SDavid Wu { .type = iom3, .offset = -1 }, \ 25149c55878SDavid Wu }, \ 25249c55878SDavid Wu .drv = { \ 25349c55878SDavid Wu { .drv_type = drv0, .offset = offset0 }, \ 25449c55878SDavid Wu { .drv_type = drv1, .offset = offset1 }, \ 25549c55878SDavid Wu { .drv_type = drv2, .offset = offset2 }, \ 25649c55878SDavid Wu { .drv_type = drv3, .offset = offset3 }, \ 25749c55878SDavid Wu }, \ 25849c55878SDavid Wu .pull_type[0] = pull0, \ 25949c55878SDavid Wu .pull_type[1] = pull1, \ 26049c55878SDavid Wu .pull_type[2] = pull2, \ 26149c55878SDavid Wu .pull_type[3] = pull3, \ 26249c55878SDavid Wu } 26349c55878SDavid Wu 26449c55878SDavid Wu /** 26549c55878SDavid Wu * struct rockchip_mux_recalced_data: represent a pin iomux data. 26649c55878SDavid Wu * @num: bank number. 26749c55878SDavid Wu * @pin: pin number. 26849c55878SDavid Wu * @bit: index at register. 26949c55878SDavid Wu * @reg: register offset. 27049c55878SDavid Wu * @mask: mask bit 27149c55878SDavid Wu */ 27249c55878SDavid Wu struct rockchip_mux_recalced_data { 27349c55878SDavid Wu u8 num; 27449c55878SDavid Wu u8 pin; 27549c55878SDavid Wu u32 reg; 27649c55878SDavid Wu u8 bit; 27749c55878SDavid Wu u8 mask; 27849c55878SDavid Wu }; 27949c55878SDavid Wu 28049c55878SDavid Wu /** 28149c55878SDavid Wu * struct rockchip_mux_recalced_data: represent a pin iomux data. 28249c55878SDavid Wu * @bank_num: bank number. 28349c55878SDavid Wu * @pin: index at register or used to calc index. 28449c55878SDavid Wu * @func: the min pin. 28549c55878SDavid Wu * @route_offset: the max pin. 28649c55878SDavid Wu * @route_val: the register offset. 28749c55878SDavid Wu */ 28849c55878SDavid Wu struct rockchip_mux_route_data { 28949c55878SDavid Wu u8 bank_num; 29049c55878SDavid Wu u8 pin; 29149c55878SDavid Wu u8 func; 29249c55878SDavid Wu u32 route_offset; 29349c55878SDavid Wu u32 route_val; 29449c55878SDavid Wu }; 29549c55878SDavid Wu 29649c55878SDavid Wu /** 29749c55878SDavid Wu */ 29849c55878SDavid Wu struct rockchip_pin_ctrl { 29949c55878SDavid Wu struct rockchip_pin_bank *pin_banks; 30049c55878SDavid Wu u32 nr_banks; 30149c55878SDavid Wu u32 nr_pins; 30249c55878SDavid Wu char *label; 30349c55878SDavid Wu enum rockchip_pinctrl_type type; 30449c55878SDavid Wu int grf_mux_offset; 30549c55878SDavid Wu int pmu_mux_offset; 30649c55878SDavid Wu int grf_drv_offset; 30749c55878SDavid Wu int pmu_drv_offset; 30849c55878SDavid Wu struct rockchip_mux_recalced_data *iomux_recalced; 30949c55878SDavid Wu u32 niomux_recalced; 31049c55878SDavid Wu struct rockchip_mux_route_data *iomux_routes; 31149c55878SDavid Wu u32 niomux_routes; 31249c55878SDavid Wu 31349c55878SDavid Wu void (*pull_calc_reg)(struct rockchip_pin_bank *bank, 31449c55878SDavid Wu int pin_num, struct regmap **regmap, 31549c55878SDavid Wu int *reg, u8 *bit); 31649c55878SDavid Wu void (*drv_calc_reg)(struct rockchip_pin_bank *bank, 31749c55878SDavid Wu int pin_num, struct regmap **regmap, 31849c55878SDavid Wu int *reg, u8 *bit); 31949c55878SDavid Wu int (*schmitt_calc_reg)(struct rockchip_pin_bank *bank, 32049c55878SDavid Wu int pin_num, struct regmap **regmap, 32149c55878SDavid Wu int *reg, u8 *bit); 32249c55878SDavid Wu }; 32349c55878SDavid Wu 32449c55878SDavid Wu /** 32549c55878SDavid Wu */ 32649c55878SDavid Wu struct rockchip_pinctrl_priv { 32749c55878SDavid Wu struct rockchip_pin_ctrl *ctrl; 32849c55878SDavid Wu struct regmap *regmap_base; 32949c55878SDavid Wu struct regmap *regmap_pmu; 33049c55878SDavid Wu 33149c55878SDavid Wu }; 33249c55878SDavid Wu 33349c55878SDavid Wu static int rockchip_verify_config(struct udevice *dev, u32 bank, u32 pin) 33449c55878SDavid Wu { 33549c55878SDavid Wu struct rockchip_pinctrl_priv *priv = dev_get_priv(dev); 33649c55878SDavid Wu struct rockchip_pin_ctrl *ctrl = priv->ctrl; 33749c55878SDavid Wu 33849c55878SDavid Wu if (bank >= ctrl->nr_banks) { 33949c55878SDavid Wu debug("pin conf bank %d >= nbanks %d\n", bank, ctrl->nr_banks); 34049c55878SDavid Wu return -EINVAL; 34149c55878SDavid Wu } 34249c55878SDavid Wu 34349c55878SDavid Wu if (pin >= MAX_ROCKCHIP_GPIO_PER_BANK) { 34449c55878SDavid Wu debug("pin conf pin %d >= %d\n", pin, 34549c55878SDavid Wu MAX_ROCKCHIP_GPIO_PER_BANK); 34649c55878SDavid Wu return -EINVAL; 34749c55878SDavid Wu } 34849c55878SDavid Wu 34949c55878SDavid Wu return 0; 35049c55878SDavid Wu } 35149c55878SDavid Wu 35249c55878SDavid Wu static struct rockchip_mux_recalced_data rv1108_mux_recalced_data[] = { 35349c55878SDavid Wu { 35449c55878SDavid Wu .num = 1, 35549c55878SDavid Wu .pin = 0, 35649c55878SDavid Wu .reg = 0x418, 35749c55878SDavid Wu .bit = 0, 35849c55878SDavid Wu .mask = 0x3 35949c55878SDavid Wu }, { 36049c55878SDavid Wu .num = 1, 36149c55878SDavid Wu .pin = 1, 36249c55878SDavid Wu .reg = 0x418, 36349c55878SDavid Wu .bit = 2, 36449c55878SDavid Wu .mask = 0x3 36549c55878SDavid Wu }, { 36649c55878SDavid Wu .num = 1, 36749c55878SDavid Wu .pin = 2, 36849c55878SDavid Wu .reg = 0x418, 36949c55878SDavid Wu .bit = 4, 37049c55878SDavid Wu .mask = 0x3 37149c55878SDavid Wu }, { 37249c55878SDavid Wu .num = 1, 37349c55878SDavid Wu .pin = 3, 37449c55878SDavid Wu .reg = 0x418, 37549c55878SDavid Wu .bit = 6, 37649c55878SDavid Wu .mask = 0x3 37749c55878SDavid Wu }, { 37849c55878SDavid Wu .num = 1, 37949c55878SDavid Wu .pin = 4, 38049c55878SDavid Wu .reg = 0x418, 38149c55878SDavid Wu .bit = 8, 38249c55878SDavid Wu .mask = 0x3 38349c55878SDavid Wu }, { 38449c55878SDavid Wu .num = 1, 38549c55878SDavid Wu .pin = 5, 38649c55878SDavid Wu .reg = 0x418, 38749c55878SDavid Wu .bit = 10, 38849c55878SDavid Wu .mask = 0x3 38949c55878SDavid Wu }, { 39049c55878SDavid Wu .num = 1, 39149c55878SDavid Wu .pin = 6, 39249c55878SDavid Wu .reg = 0x418, 39349c55878SDavid Wu .bit = 12, 39449c55878SDavid Wu .mask = 0x3 39549c55878SDavid Wu }, { 39649c55878SDavid Wu .num = 1, 39749c55878SDavid Wu .pin = 7, 39849c55878SDavid Wu .reg = 0x418, 39949c55878SDavid Wu .bit = 14, 40049c55878SDavid Wu .mask = 0x3 40149c55878SDavid Wu }, { 40249c55878SDavid Wu .num = 1, 40349c55878SDavid Wu .pin = 8, 40449c55878SDavid Wu .reg = 0x41c, 40549c55878SDavid Wu .bit = 0, 40649c55878SDavid Wu .mask = 0x3 40749c55878SDavid Wu }, { 40849c55878SDavid Wu .num = 1, 40949c55878SDavid Wu .pin = 9, 41049c55878SDavid Wu .reg = 0x41c, 41149c55878SDavid Wu .bit = 2, 41249c55878SDavid Wu .mask = 0x3 41349c55878SDavid Wu }, 41449c55878SDavid Wu }; 41549c55878SDavid Wu 41649c55878SDavid Wu static struct rockchip_mux_recalced_data rk3128_mux_recalced_data[] = { 41749c55878SDavid Wu { 41849c55878SDavid Wu .num = 2, 41949c55878SDavid Wu .pin = 20, 42049c55878SDavid Wu .reg = 0xe8, 42149c55878SDavid Wu .bit = 0, 42249c55878SDavid Wu .mask = 0x7 42349c55878SDavid Wu }, { 42449c55878SDavid Wu .num = 2, 42549c55878SDavid Wu .pin = 21, 42649c55878SDavid Wu .reg = 0xe8, 42749c55878SDavid Wu .bit = 4, 42849c55878SDavid Wu .mask = 0x7 42949c55878SDavid Wu }, { 43049c55878SDavid Wu .num = 2, 43149c55878SDavid Wu .pin = 22, 43249c55878SDavid Wu .reg = 0xe8, 43349c55878SDavid Wu .bit = 8, 43449c55878SDavid Wu .mask = 0x7 43549c55878SDavid Wu }, { 43649c55878SDavid Wu .num = 2, 43749c55878SDavid Wu .pin = 23, 43849c55878SDavid Wu .reg = 0xe8, 43949c55878SDavid Wu .bit = 12, 44049c55878SDavid Wu .mask = 0x7 44149c55878SDavid Wu }, { 44249c55878SDavid Wu .num = 2, 44349c55878SDavid Wu .pin = 24, 44449c55878SDavid Wu .reg = 0xd4, 44549c55878SDavid Wu .bit = 12, 44649c55878SDavid Wu .mask = 0x7 44749c55878SDavid Wu }, 44849c55878SDavid Wu }; 44949c55878SDavid Wu 450b3077611SDavid Wu static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = { 451b3077611SDavid Wu { 452b3077611SDavid Wu .num = 1, 453b3077611SDavid Wu .pin = 14, 454b3077611SDavid Wu .reg = 0x28, 455b3077611SDavid Wu .bit = 12, 456b3077611SDavid Wu .mask = 0x7 457b3077611SDavid Wu }, { 458b3077611SDavid Wu .num = 1, 459b3077611SDavid Wu .pin = 15, 460b3077611SDavid Wu .reg = 0x2c, 461b3077611SDavid Wu .bit = 0, 462b3077611SDavid Wu .mask = 0x3 463b3077611SDavid Wu }, { 464b3077611SDavid Wu .num = 1, 465b3077611SDavid Wu .pin = 18, 466b3077611SDavid Wu .reg = 0x30, 467b3077611SDavid Wu .bit = 4, 468b3077611SDavid Wu .mask = 0x7 469b3077611SDavid Wu }, { 470b3077611SDavid Wu .num = 1, 471b3077611SDavid Wu .pin = 19, 472b3077611SDavid Wu .reg = 0x30, 473b3077611SDavid Wu .bit = 8, 474b3077611SDavid Wu .mask = 0x7 475b3077611SDavid Wu }, { 476b3077611SDavid Wu .num = 1, 477b3077611SDavid Wu .pin = 20, 478b3077611SDavid Wu .reg = 0x30, 479b3077611SDavid Wu .bit = 12, 480b3077611SDavid Wu .mask = 0x7 481b3077611SDavid Wu }, { 482b3077611SDavid Wu .num = 1, 483b3077611SDavid Wu .pin = 21, 484b3077611SDavid Wu .reg = 0x34, 485b3077611SDavid Wu .bit = 0, 486b3077611SDavid Wu .mask = 0x7 487b3077611SDavid Wu }, { 488b3077611SDavid Wu .num = 1, 489b3077611SDavid Wu .pin = 22, 490b3077611SDavid Wu .reg = 0x34, 491b3077611SDavid Wu .bit = 4, 492b3077611SDavid Wu .mask = 0x7 493b3077611SDavid Wu }, { 494b3077611SDavid Wu .num = 1, 495b3077611SDavid Wu .pin = 23, 496b3077611SDavid Wu .reg = 0x34, 497b3077611SDavid Wu .bit = 8, 498b3077611SDavid Wu .mask = 0x7 499b3077611SDavid Wu }, { 500b3077611SDavid Wu .num = 3, 501b3077611SDavid Wu .pin = 12, 502b3077611SDavid Wu .reg = 0x68, 503b3077611SDavid Wu .bit = 8, 504b3077611SDavid Wu .mask = 0x7 505b3077611SDavid Wu }, { 506b3077611SDavid Wu .num = 3, 507b3077611SDavid Wu .pin = 13, 508b3077611SDavid Wu .reg = 0x68, 509b3077611SDavid Wu .bit = 12, 510b3077611SDavid Wu .mask = 0x7 511b3077611SDavid Wu }, 512b3077611SDavid Wu }; 513b3077611SDavid Wu 51449c55878SDavid Wu static struct rockchip_mux_recalced_data rk3328_mux_recalced_data[] = { 51549c55878SDavid Wu { 51649c55878SDavid Wu .num = 2, 51749c55878SDavid Wu .pin = 12, 51849c55878SDavid Wu .reg = 0x24, 51949c55878SDavid Wu .bit = 8, 52049c55878SDavid Wu .mask = 0x3 52149c55878SDavid Wu }, { 52249c55878SDavid Wu .num = 2, 52349c55878SDavid Wu .pin = 15, 52449c55878SDavid Wu .reg = 0x28, 52549c55878SDavid Wu .bit = 0, 52649c55878SDavid Wu .mask = 0x7 52749c55878SDavid Wu }, { 52849c55878SDavid Wu .num = 2, 52949c55878SDavid Wu .pin = 23, 53049c55878SDavid Wu .reg = 0x30, 53149c55878SDavid Wu .bit = 14, 53249c55878SDavid Wu .mask = 0x3 53349c55878SDavid Wu }, 53449c55878SDavid Wu }; 53549c55878SDavid Wu 53649c55878SDavid Wu static void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin, 53749c55878SDavid Wu int *reg, u8 *bit, int *mask) 53849c55878SDavid Wu { 53949c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 54049c55878SDavid Wu struct rockchip_pin_ctrl *ctrl = priv->ctrl; 54149c55878SDavid Wu struct rockchip_mux_recalced_data *data; 54249c55878SDavid Wu int i; 54349c55878SDavid Wu 54449c55878SDavid Wu for (i = 0; i < ctrl->niomux_recalced; i++) { 54549c55878SDavid Wu data = &ctrl->iomux_recalced[i]; 54649c55878SDavid Wu if (data->num == bank->bank_num && 54749c55878SDavid Wu data->pin == pin) 54849c55878SDavid Wu break; 54949c55878SDavid Wu } 55049c55878SDavid Wu 55149c55878SDavid Wu if (i >= ctrl->niomux_recalced) 55249c55878SDavid Wu return; 55349c55878SDavid Wu 55449c55878SDavid Wu *reg = data->reg; 55549c55878SDavid Wu *mask = data->mask; 55649c55878SDavid Wu *bit = data->bit; 55749c55878SDavid Wu } 55849c55878SDavid Wu 55949c55878SDavid Wu static struct rockchip_mux_route_data px30_mux_route_data[] = { 56049c55878SDavid Wu { 56149c55878SDavid Wu /* cif-d2m0 */ 56249c55878SDavid Wu .bank_num = 2, 56349c55878SDavid Wu .pin = 0, 56449c55878SDavid Wu .func = 1, 56549c55878SDavid Wu .route_offset = 0x184, 56649c55878SDavid Wu .route_val = BIT(16 + 7), 56749c55878SDavid Wu }, { 56849c55878SDavid Wu /* cif-d2m1 */ 56949c55878SDavid Wu .bank_num = 3, 57049c55878SDavid Wu .pin = 3, 57149c55878SDavid Wu .func = 3, 57249c55878SDavid Wu .route_offset = 0x184, 57349c55878SDavid Wu .route_val = BIT(16 + 7) | BIT(7), 57449c55878SDavid Wu }, { 57549c55878SDavid Wu /* pdm-m0 */ 57649c55878SDavid Wu .bank_num = 3, 57749c55878SDavid Wu .pin = 22, 57849c55878SDavid Wu .func = 2, 57949c55878SDavid Wu .route_offset = 0x184, 58049c55878SDavid Wu .route_val = BIT(16 + 8), 58149c55878SDavid Wu }, { 58249c55878SDavid Wu /* pdm-m1 */ 58349c55878SDavid Wu .bank_num = 2, 58449c55878SDavid Wu .pin = 22, 58549c55878SDavid Wu .func = 1, 58649c55878SDavid Wu .route_offset = 0x184, 58749c55878SDavid Wu .route_val = BIT(16 + 8) | BIT(8), 58849c55878SDavid Wu }, { 58949c55878SDavid Wu /* uart2-rxm0 */ 59049c55878SDavid Wu .bank_num = 1, 591793770dfSDavid Wu .pin = 27, 59249c55878SDavid Wu .func = 2, 59349c55878SDavid Wu .route_offset = 0x184, 594793770dfSDavid Wu .route_val = BIT(16 + 10), 59549c55878SDavid Wu }, { 59649c55878SDavid Wu /* uart2-rxm1 */ 59749c55878SDavid Wu .bank_num = 2, 59849c55878SDavid Wu .pin = 14, 59949c55878SDavid Wu .func = 2, 60049c55878SDavid Wu .route_offset = 0x184, 601793770dfSDavid Wu .route_val = BIT(16 + 10) | BIT(10), 60249c55878SDavid Wu }, { 60349c55878SDavid Wu /* uart3-rxm0 */ 60449c55878SDavid Wu .bank_num = 0, 60549c55878SDavid Wu .pin = 17, 60649c55878SDavid Wu .func = 2, 60749c55878SDavid Wu .route_offset = 0x184, 608793770dfSDavid Wu .route_val = BIT(16 + 9), 60949c55878SDavid Wu }, { 61049c55878SDavid Wu /* uart3-rxm1 */ 61149c55878SDavid Wu .bank_num = 1, 612793770dfSDavid Wu .pin = 15, 61349c55878SDavid Wu .func = 2, 61449c55878SDavid Wu .route_offset = 0x184, 615793770dfSDavid Wu .route_val = BIT(16 + 9) | BIT(9), 61649c55878SDavid Wu }, 61749c55878SDavid Wu }; 61849c55878SDavid Wu 61949c55878SDavid Wu static struct rockchip_mux_route_data rk3128_mux_route_data[] = { 62049c55878SDavid Wu { 62149c55878SDavid Wu /* spi-0 */ 62249c55878SDavid Wu .bank_num = 1, 62349c55878SDavid Wu .pin = 10, 62449c55878SDavid Wu .func = 1, 62549c55878SDavid Wu .route_offset = 0x144, 62649c55878SDavid Wu .route_val = BIT(16 + 3) | BIT(16 + 4), 62749c55878SDavid Wu }, { 62849c55878SDavid Wu /* spi-1 */ 62949c55878SDavid Wu .bank_num = 1, 63049c55878SDavid Wu .pin = 27, 63149c55878SDavid Wu .func = 3, 63249c55878SDavid Wu .route_offset = 0x144, 63349c55878SDavid Wu .route_val = BIT(16 + 3) | BIT(16 + 4) | BIT(3), 63449c55878SDavid Wu }, { 63549c55878SDavid Wu /* spi-2 */ 63649c55878SDavid Wu .bank_num = 0, 63749c55878SDavid Wu .pin = 13, 63849c55878SDavid Wu .func = 2, 63949c55878SDavid Wu .route_offset = 0x144, 64049c55878SDavid Wu .route_val = BIT(16 + 3) | BIT(16 + 4) | BIT(4), 64149c55878SDavid Wu }, { 64249c55878SDavid Wu /* i2s-0 */ 64349c55878SDavid Wu .bank_num = 1, 64449c55878SDavid Wu .pin = 5, 64549c55878SDavid Wu .func = 1, 64649c55878SDavid Wu .route_offset = 0x144, 64749c55878SDavid Wu .route_val = BIT(16 + 5), 64849c55878SDavid Wu }, { 64949c55878SDavid Wu /* i2s-1 */ 65049c55878SDavid Wu .bank_num = 0, 65149c55878SDavid Wu .pin = 14, 65249c55878SDavid Wu .func = 1, 65349c55878SDavid Wu .route_offset = 0x144, 65449c55878SDavid Wu .route_val = BIT(16 + 5) | BIT(5), 65549c55878SDavid Wu }, { 65649c55878SDavid Wu /* emmc-0 */ 65749c55878SDavid Wu .bank_num = 1, 65849c55878SDavid Wu .pin = 22, 65949c55878SDavid Wu .func = 2, 66049c55878SDavid Wu .route_offset = 0x144, 66149c55878SDavid Wu .route_val = BIT(16 + 6), 66249c55878SDavid Wu }, { 66349c55878SDavid Wu /* emmc-1 */ 66449c55878SDavid Wu .bank_num = 2, 66549c55878SDavid Wu .pin = 4, 66649c55878SDavid Wu .func = 2, 66749c55878SDavid Wu .route_offset = 0x144, 66849c55878SDavid Wu .route_val = BIT(16 + 6) | BIT(6), 66949c55878SDavid Wu }, 67049c55878SDavid Wu }; 67149c55878SDavid Wu 67249c55878SDavid Wu static struct rockchip_mux_route_data rk3228_mux_route_data[] = { 67349c55878SDavid Wu { 67449c55878SDavid Wu /* pwm0-0 */ 67549c55878SDavid Wu .bank_num = 0, 67649c55878SDavid Wu .pin = 26, 67749c55878SDavid Wu .func = 1, 67849c55878SDavid Wu .route_offset = 0x50, 67949c55878SDavid Wu .route_val = BIT(16), 68049c55878SDavid Wu }, { 68149c55878SDavid Wu /* pwm0-1 */ 68249c55878SDavid Wu .bank_num = 3, 68349c55878SDavid Wu .pin = 21, 68449c55878SDavid Wu .func = 1, 68549c55878SDavid Wu .route_offset = 0x50, 68649c55878SDavid Wu .route_val = BIT(16) | BIT(0), 68749c55878SDavid Wu }, { 68849c55878SDavid Wu /* pwm1-0 */ 68949c55878SDavid Wu .bank_num = 0, 69049c55878SDavid Wu .pin = 27, 69149c55878SDavid Wu .func = 1, 69249c55878SDavid Wu .route_offset = 0x50, 69349c55878SDavid Wu .route_val = BIT(16 + 1), 69449c55878SDavid Wu }, { 69549c55878SDavid Wu /* pwm1-1 */ 69649c55878SDavid Wu .bank_num = 0, 69749c55878SDavid Wu .pin = 30, 69849c55878SDavid Wu .func = 2, 69949c55878SDavid Wu .route_offset = 0x50, 70049c55878SDavid Wu .route_val = BIT(16 + 1) | BIT(1), 70149c55878SDavid Wu }, { 70249c55878SDavid Wu /* pwm2-0 */ 70349c55878SDavid Wu .bank_num = 0, 70449c55878SDavid Wu .pin = 28, 70549c55878SDavid Wu .func = 1, 70649c55878SDavid Wu .route_offset = 0x50, 70749c55878SDavid Wu .route_val = BIT(16 + 2), 70849c55878SDavid Wu }, { 70949c55878SDavid Wu /* pwm2-1 */ 71049c55878SDavid Wu .bank_num = 1, 71149c55878SDavid Wu .pin = 12, 71249c55878SDavid Wu .func = 2, 71349c55878SDavid Wu .route_offset = 0x50, 71449c55878SDavid Wu .route_val = BIT(16 + 2) | BIT(2), 71549c55878SDavid Wu }, { 71649c55878SDavid Wu /* pwm3-0 */ 71749c55878SDavid Wu .bank_num = 3, 71849c55878SDavid Wu .pin = 26, 71949c55878SDavid Wu .func = 1, 72049c55878SDavid Wu .route_offset = 0x50, 72149c55878SDavid Wu .route_val = BIT(16 + 3), 72249c55878SDavid Wu }, { 72349c55878SDavid Wu /* pwm3-1 */ 72449c55878SDavid Wu .bank_num = 1, 72549c55878SDavid Wu .pin = 11, 72649c55878SDavid Wu .func = 2, 72749c55878SDavid Wu .route_offset = 0x50, 72849c55878SDavid Wu .route_val = BIT(16 + 3) | BIT(3), 72949c55878SDavid Wu }, { 73049c55878SDavid Wu /* sdio-0_d0 */ 73149c55878SDavid Wu .bank_num = 1, 73249c55878SDavid Wu .pin = 1, 73349c55878SDavid Wu .func = 1, 73449c55878SDavid Wu .route_offset = 0x50, 73549c55878SDavid Wu .route_val = BIT(16 + 4), 73649c55878SDavid Wu }, { 73749c55878SDavid Wu /* sdio-1_d0 */ 73849c55878SDavid Wu .bank_num = 3, 73949c55878SDavid Wu .pin = 2, 74049c55878SDavid Wu .func = 1, 74149c55878SDavid Wu .route_offset = 0x50, 74249c55878SDavid Wu .route_val = BIT(16 + 4) | BIT(4), 74349c55878SDavid Wu }, { 74449c55878SDavid Wu /* spi-0_rx */ 74549c55878SDavid Wu .bank_num = 0, 74649c55878SDavid Wu .pin = 13, 74749c55878SDavid Wu .func = 2, 74849c55878SDavid Wu .route_offset = 0x50, 74949c55878SDavid Wu .route_val = BIT(16 + 5), 75049c55878SDavid Wu }, { 75149c55878SDavid Wu /* spi-1_rx */ 75249c55878SDavid Wu .bank_num = 2, 75349c55878SDavid Wu .pin = 0, 75449c55878SDavid Wu .func = 2, 75549c55878SDavid Wu .route_offset = 0x50, 75649c55878SDavid Wu .route_val = BIT(16 + 5) | BIT(5), 75749c55878SDavid Wu }, { 75849c55878SDavid Wu /* emmc-0_cmd */ 75949c55878SDavid Wu .bank_num = 1, 76049c55878SDavid Wu .pin = 22, 76149c55878SDavid Wu .func = 2, 76249c55878SDavid Wu .route_offset = 0x50, 76349c55878SDavid Wu .route_val = BIT(16 + 7), 76449c55878SDavid Wu }, { 76549c55878SDavid Wu /* emmc-1_cmd */ 76649c55878SDavid Wu .bank_num = 2, 76749c55878SDavid Wu .pin = 4, 76849c55878SDavid Wu .func = 2, 76949c55878SDavid Wu .route_offset = 0x50, 77049c55878SDavid Wu .route_val = BIT(16 + 7) | BIT(7), 77149c55878SDavid Wu }, { 77249c55878SDavid Wu /* uart2-0_rx */ 77349c55878SDavid Wu .bank_num = 1, 77449c55878SDavid Wu .pin = 19, 77549c55878SDavid Wu .func = 2, 77649c55878SDavid Wu .route_offset = 0x50, 77749c55878SDavid Wu .route_val = BIT(16 + 8), 77849c55878SDavid Wu }, { 77949c55878SDavid Wu /* uart2-1_rx */ 78049c55878SDavid Wu .bank_num = 1, 78149c55878SDavid Wu .pin = 10, 78249c55878SDavid Wu .func = 2, 78349c55878SDavid Wu .route_offset = 0x50, 78449c55878SDavid Wu .route_val = BIT(16 + 8) | BIT(8), 78549c55878SDavid Wu }, { 78649c55878SDavid Wu /* uart1-0_rx */ 78749c55878SDavid Wu .bank_num = 1, 78849c55878SDavid Wu .pin = 10, 78949c55878SDavid Wu .func = 1, 79049c55878SDavid Wu .route_offset = 0x50, 79149c55878SDavid Wu .route_val = BIT(16 + 11), 79249c55878SDavid Wu }, { 79349c55878SDavid Wu /* uart1-1_rx */ 79449c55878SDavid Wu .bank_num = 3, 79549c55878SDavid Wu .pin = 13, 79649c55878SDavid Wu .func = 1, 79749c55878SDavid Wu .route_offset = 0x50, 79849c55878SDavid Wu .route_val = BIT(16 + 11) | BIT(11), 79949c55878SDavid Wu }, 80049c55878SDavid Wu }; 80149c55878SDavid Wu 80249c55878SDavid Wu static struct rockchip_mux_route_data rk3288_mux_route_data[] = { 80349c55878SDavid Wu { 80449c55878SDavid Wu /* edphdmi_cecinoutt1 */ 80549c55878SDavid Wu .bank_num = 7, 80649c55878SDavid Wu .pin = 16, 80749c55878SDavid Wu .func = 2, 80849c55878SDavid Wu .route_offset = 0x264, 80949c55878SDavid Wu .route_val = BIT(16 + 12) | BIT(12), 81049c55878SDavid Wu }, { 81149c55878SDavid Wu /* edphdmi_cecinout */ 81249c55878SDavid Wu .bank_num = 7, 81349c55878SDavid Wu .pin = 23, 81449c55878SDavid Wu .func = 4, 81549c55878SDavid Wu .route_offset = 0x264, 81649c55878SDavid Wu .route_val = BIT(16 + 12), 81749c55878SDavid Wu }, 81849c55878SDavid Wu }; 81949c55878SDavid Wu 820b3077611SDavid Wu static struct rockchip_mux_route_data rk3308_mux_route_data[] = { 821b3077611SDavid Wu { 822b3077611SDavid Wu /* uart2_rxm0 */ 823b3077611SDavid Wu .bank_num = 1, 824b3077611SDavid Wu .pin = 22, 825b3077611SDavid Wu .func = 2, 826b3077611SDavid Wu .route_offset = 0x314, 827b3077611SDavid Wu .route_val = BIT(16 + 2) | BIT(16 + 3), 828b3077611SDavid Wu }, { 829b3077611SDavid Wu /* uart2_rxm1 */ 830b3077611SDavid Wu .bank_num = 4, 831b3077611SDavid Wu .pin = 26, 832b3077611SDavid Wu .func = 2, 833b3077611SDavid Wu .route_offset = 0x314, 834b3077611SDavid Wu .route_val = BIT(16 + 2) | BIT(16 + 3) | BIT(2), 835b3077611SDavid Wu }, { 836b3077611SDavid Wu /* i2c3_sdam0 */ 837b3077611SDavid Wu .bank_num = 0, 838b3077611SDavid Wu .pin = 23, 839b3077611SDavid Wu .func = 2, 840b3077611SDavid Wu .route_offset = 0x314, 841b3077611SDavid Wu .route_val = BIT(16 + 4), 842b3077611SDavid Wu }, { 843b3077611SDavid Wu /* i2c3_sdam1 */ 844b3077611SDavid Wu .bank_num = 3, 845b3077611SDavid Wu .pin = 12, 846b3077611SDavid Wu .func = 2, 847b3077611SDavid Wu .route_offset = 0x314, 848b3077611SDavid Wu .route_val = BIT(16 + 4) | BIT(4), 849b3077611SDavid Wu }, 850b3077611SDavid Wu }; 851b3077611SDavid Wu 85249c55878SDavid Wu static struct rockchip_mux_route_data rk3328_mux_route_data[] = { 85349c55878SDavid Wu { 85449c55878SDavid Wu /* uart2dbg_rxm0 */ 85549c55878SDavid Wu .bank_num = 1, 85649c55878SDavid Wu .pin = 1, 85749c55878SDavid Wu .func = 2, 85849c55878SDavid Wu .route_offset = 0x50, 85949c55878SDavid Wu .route_val = BIT(16) | BIT(16 + 1), 86049c55878SDavid Wu }, { 86149c55878SDavid Wu /* uart2dbg_rxm1 */ 86249c55878SDavid Wu .bank_num = 2, 86349c55878SDavid Wu .pin = 1, 86449c55878SDavid Wu .func = 1, 86549c55878SDavid Wu .route_offset = 0x50, 86649c55878SDavid Wu .route_val = BIT(16) | BIT(16 + 1) | BIT(0), 86749c55878SDavid Wu }, { 86849c55878SDavid Wu /* gmac-m1_rxd0 */ 86949c55878SDavid Wu .bank_num = 1, 87049c55878SDavid Wu .pin = 11, 87149c55878SDavid Wu .func = 2, 87249c55878SDavid Wu .route_offset = 0x50, 87349c55878SDavid Wu .route_val = BIT(16 + 2) | BIT(2), 87449c55878SDavid Wu }, { 87549c55878SDavid Wu /* gmac-m1-optimized_rxd3 */ 87649c55878SDavid Wu .bank_num = 1, 87749c55878SDavid Wu .pin = 14, 87849c55878SDavid Wu .func = 2, 87949c55878SDavid Wu .route_offset = 0x50, 88049c55878SDavid Wu .route_val = BIT(16 + 10) | BIT(10), 88149c55878SDavid Wu }, { 88249c55878SDavid Wu /* pdm_sdi0m0 */ 88349c55878SDavid Wu .bank_num = 2, 88449c55878SDavid Wu .pin = 19, 88549c55878SDavid Wu .func = 2, 88649c55878SDavid Wu .route_offset = 0x50, 88749c55878SDavid Wu .route_val = BIT(16 + 3), 88849c55878SDavid Wu }, { 88949c55878SDavid Wu /* pdm_sdi0m1 */ 89049c55878SDavid Wu .bank_num = 1, 89149c55878SDavid Wu .pin = 23, 89249c55878SDavid Wu .func = 3, 89349c55878SDavid Wu .route_offset = 0x50, 89449c55878SDavid Wu .route_val = BIT(16 + 3) | BIT(3), 89549c55878SDavid Wu }, { 89649c55878SDavid Wu /* spi_rxdm2 */ 89749c55878SDavid Wu .bank_num = 3, 89849c55878SDavid Wu .pin = 2, 89949c55878SDavid Wu .func = 4, 90049c55878SDavid Wu .route_offset = 0x50, 90149c55878SDavid Wu .route_val = BIT(16 + 4) | BIT(16 + 5) | BIT(5), 90249c55878SDavid Wu }, { 90349c55878SDavid Wu /* i2s2_sdim0 */ 90449c55878SDavid Wu .bank_num = 1, 90549c55878SDavid Wu .pin = 24, 90649c55878SDavid Wu .func = 1, 90749c55878SDavid Wu .route_offset = 0x50, 90849c55878SDavid Wu .route_val = BIT(16 + 6), 90949c55878SDavid Wu }, { 91049c55878SDavid Wu /* i2s2_sdim1 */ 91149c55878SDavid Wu .bank_num = 3, 91249c55878SDavid Wu .pin = 2, 91349c55878SDavid Wu .func = 6, 91449c55878SDavid Wu .route_offset = 0x50, 91549c55878SDavid Wu .route_val = BIT(16 + 6) | BIT(6), 91649c55878SDavid Wu }, { 91749c55878SDavid Wu /* card_iom1 */ 91849c55878SDavid Wu .bank_num = 2, 91949c55878SDavid Wu .pin = 22, 92049c55878SDavid Wu .func = 3, 92149c55878SDavid Wu .route_offset = 0x50, 92249c55878SDavid Wu .route_val = BIT(16 + 7) | BIT(7), 92349c55878SDavid Wu }, { 92449c55878SDavid Wu /* tsp_d5m1 */ 92549c55878SDavid Wu .bank_num = 2, 92649c55878SDavid Wu .pin = 16, 92749c55878SDavid Wu .func = 3, 92849c55878SDavid Wu .route_offset = 0x50, 92949c55878SDavid Wu .route_val = BIT(16 + 8) | BIT(8), 93049c55878SDavid Wu }, { 93149c55878SDavid Wu /* cif_data5m1 */ 93249c55878SDavid Wu .bank_num = 2, 93349c55878SDavid Wu .pin = 16, 93449c55878SDavid Wu .func = 4, 93549c55878SDavid Wu .route_offset = 0x50, 93649c55878SDavid Wu .route_val = BIT(16 + 9) | BIT(9), 93749c55878SDavid Wu }, 93849c55878SDavid Wu }; 93949c55878SDavid Wu 94049c55878SDavid Wu static struct rockchip_mux_route_data rk3399_mux_route_data[] = { 94149c55878SDavid Wu { 94249c55878SDavid Wu /* uart2dbga_rx */ 94349c55878SDavid Wu .bank_num = 4, 94449c55878SDavid Wu .pin = 8, 94549c55878SDavid Wu .func = 2, 94649c55878SDavid Wu .route_offset = 0xe21c, 94749c55878SDavid Wu .route_val = BIT(16 + 10) | BIT(16 + 11), 94849c55878SDavid Wu }, { 94949c55878SDavid Wu /* uart2dbgb_rx */ 95049c55878SDavid Wu .bank_num = 4, 95149c55878SDavid Wu .pin = 16, 95249c55878SDavid Wu .func = 2, 95349c55878SDavid Wu .route_offset = 0xe21c, 95449c55878SDavid Wu .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(10), 95549c55878SDavid Wu }, { 95649c55878SDavid Wu /* uart2dbgc_rx */ 95749c55878SDavid Wu .bank_num = 4, 95849c55878SDavid Wu .pin = 19, 95949c55878SDavid Wu .func = 1, 96049c55878SDavid Wu .route_offset = 0xe21c, 96149c55878SDavid Wu .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(11), 96249c55878SDavid Wu }, { 96349c55878SDavid Wu /* pcie_clkreqn */ 96449c55878SDavid Wu .bank_num = 2, 96549c55878SDavid Wu .pin = 26, 96649c55878SDavid Wu .func = 2, 96749c55878SDavid Wu .route_offset = 0xe21c, 96849c55878SDavid Wu .route_val = BIT(16 + 14), 96949c55878SDavid Wu }, { 97049c55878SDavid Wu /* pcie_clkreqnb */ 97149c55878SDavid Wu .bank_num = 4, 97249c55878SDavid Wu .pin = 24, 97349c55878SDavid Wu .func = 1, 97449c55878SDavid Wu .route_offset = 0xe21c, 97549c55878SDavid Wu .route_val = BIT(16 + 14) | BIT(14), 97649c55878SDavid Wu }, 97749c55878SDavid Wu }; 97849c55878SDavid Wu 97949c55878SDavid Wu static bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin, 98049c55878SDavid Wu int mux, u32 *reg, u32 *value) 98149c55878SDavid Wu { 98249c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 98349c55878SDavid Wu struct rockchip_pin_ctrl *ctrl = priv->ctrl; 98449c55878SDavid Wu struct rockchip_mux_route_data *data; 98549c55878SDavid Wu int i; 98649c55878SDavid Wu 98749c55878SDavid Wu for (i = 0; i < ctrl->niomux_routes; i++) { 98849c55878SDavid Wu data = &ctrl->iomux_routes[i]; 98949c55878SDavid Wu if ((data->bank_num == bank->bank_num) && 99049c55878SDavid Wu (data->pin == pin) && (data->func == mux)) 99149c55878SDavid Wu break; 99249c55878SDavid Wu } 99349c55878SDavid Wu 99449c55878SDavid Wu if (i >= ctrl->niomux_routes) 99549c55878SDavid Wu return false; 99649c55878SDavid Wu 99749c55878SDavid Wu *reg = data->route_offset; 99849c55878SDavid Wu *value = data->route_val; 99949c55878SDavid Wu 100049c55878SDavid Wu return true; 100149c55878SDavid Wu } 100249c55878SDavid Wu 100349c55878SDavid Wu static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) 100449c55878SDavid Wu { 100549c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 100649c55878SDavid Wu int iomux_num = (pin / 8); 100749c55878SDavid Wu struct regmap *regmap; 100849c55878SDavid Wu unsigned int val; 100949c55878SDavid Wu int reg, ret, mask, mux_type; 101049c55878SDavid Wu u8 bit; 101149c55878SDavid Wu 101249c55878SDavid Wu if (iomux_num > 3) 101349c55878SDavid Wu return -EINVAL; 101449c55878SDavid Wu 101549c55878SDavid Wu if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { 101649c55878SDavid Wu debug("pin %d is unrouted\n", pin); 101749c55878SDavid Wu return -EINVAL; 101849c55878SDavid Wu } 101949c55878SDavid Wu 102049c55878SDavid Wu if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) 102149c55878SDavid Wu return RK_FUNC_GPIO; 102249c55878SDavid Wu 102349c55878SDavid Wu regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) 102449c55878SDavid Wu ? priv->regmap_pmu : priv->regmap_base; 102549c55878SDavid Wu 102649c55878SDavid Wu /* get basic quadrupel of mux registers and the correct reg inside */ 102749c55878SDavid Wu mux_type = bank->iomux[iomux_num].type; 102849c55878SDavid Wu reg = bank->iomux[iomux_num].offset; 102949c55878SDavid Wu if (mux_type & IOMUX_WIDTH_4BIT) { 103049c55878SDavid Wu if ((pin % 8) >= 4) 103149c55878SDavid Wu reg += 0x4; 103249c55878SDavid Wu bit = (pin % 4) * 4; 103349c55878SDavid Wu mask = 0xf; 103449c55878SDavid Wu } else if (mux_type & IOMUX_WIDTH_3BIT) { 103549c55878SDavid Wu if ((pin % 8) >= 5) 103649c55878SDavid Wu reg += 0x4; 103749c55878SDavid Wu bit = (pin % 8 % 5) * 3; 103849c55878SDavid Wu mask = 0x7; 103949c55878SDavid Wu } else { 104049c55878SDavid Wu bit = (pin % 8) * 2; 104149c55878SDavid Wu mask = 0x3; 104249c55878SDavid Wu } 104349c55878SDavid Wu 104449c55878SDavid Wu if (bank->recalced_mask & BIT(pin)) 104549c55878SDavid Wu rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); 104649c55878SDavid Wu 104749c55878SDavid Wu ret = regmap_read(regmap, reg, &val); 104849c55878SDavid Wu if (ret) 104949c55878SDavid Wu return ret; 105049c55878SDavid Wu 105149c55878SDavid Wu return ((val >> bit) & mask); 105249c55878SDavid Wu } 105349c55878SDavid Wu 105449c55878SDavid Wu static int rockchip_pinctrl_get_gpio_mux(struct udevice *dev, int banknum, 105549c55878SDavid Wu int index) 105649c55878SDavid Wu { struct rockchip_pinctrl_priv *priv = dev_get_priv(dev); 105749c55878SDavid Wu struct rockchip_pin_ctrl *ctrl = priv->ctrl; 105849c55878SDavid Wu 105949c55878SDavid Wu return rockchip_get_mux(&ctrl->pin_banks[banknum], index); 106049c55878SDavid Wu } 106149c55878SDavid Wu 106249c55878SDavid Wu static int rockchip_verify_mux(struct rockchip_pin_bank *bank, 106349c55878SDavid Wu int pin, int mux) 106449c55878SDavid Wu { 106549c55878SDavid Wu int iomux_num = (pin / 8); 106649c55878SDavid Wu 106749c55878SDavid Wu if (iomux_num > 3) 106849c55878SDavid Wu return -EINVAL; 106949c55878SDavid Wu 107049c55878SDavid Wu if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { 107149c55878SDavid Wu debug("pin %d is unrouted\n", pin); 107249c55878SDavid Wu return -EINVAL; 107349c55878SDavid Wu } 107449c55878SDavid Wu 107549c55878SDavid Wu if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) { 107649c55878SDavid Wu if (mux != IOMUX_GPIO_ONLY) { 107749c55878SDavid Wu debug("pin %d only supports a gpio mux\n", pin); 107849c55878SDavid Wu return -ENOTSUPP; 107949c55878SDavid Wu } 108049c55878SDavid Wu } 108149c55878SDavid Wu 108249c55878SDavid Wu return 0; 108349c55878SDavid Wu } 108449c55878SDavid Wu 108549c55878SDavid Wu /* 108649c55878SDavid Wu * Set a new mux function for a pin. 108749c55878SDavid Wu * 108849c55878SDavid Wu * The register is divided into the upper and lower 16 bit. When changing 108949c55878SDavid Wu * a value, the previous register value is not read and changed. Instead 109049c55878SDavid Wu * it seems the changed bits are marked in the upper 16 bit, while the 109149c55878SDavid Wu * changed value gets set in the same offset in the lower 16 bit. 109249c55878SDavid Wu * All pin settings seem to be 2 bit wide in both the upper and lower 109349c55878SDavid Wu * parts. 109449c55878SDavid Wu * @bank: pin bank to change 109549c55878SDavid Wu * @pin: pin to change 109649c55878SDavid Wu * @mux: new mux function to set 109749c55878SDavid Wu */ 109849c55878SDavid Wu static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) 109949c55878SDavid Wu { 110049c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 110149c55878SDavid Wu int iomux_num = (pin / 8); 110249c55878SDavid Wu struct regmap *regmap; 110349c55878SDavid Wu int reg, ret, mask, mux_type; 110449c55878SDavid Wu u8 bit; 110549c55878SDavid Wu u32 data, route_reg, route_val; 110649c55878SDavid Wu 110749c55878SDavid Wu ret = rockchip_verify_mux(bank, pin, mux); 110849c55878SDavid Wu if (ret < 0) 110949c55878SDavid Wu return ret; 111049c55878SDavid Wu 111149c55878SDavid Wu if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) 111249c55878SDavid Wu return 0; 111349c55878SDavid Wu 111449c55878SDavid Wu debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); 111549c55878SDavid Wu 111649c55878SDavid Wu regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) 111749c55878SDavid Wu ? priv->regmap_pmu : priv->regmap_base; 111849c55878SDavid Wu 111949c55878SDavid Wu /* get basic quadrupel of mux registers and the correct reg inside */ 112049c55878SDavid Wu mux_type = bank->iomux[iomux_num].type; 112149c55878SDavid Wu reg = bank->iomux[iomux_num].offset; 112249c55878SDavid Wu if (mux_type & IOMUX_WIDTH_4BIT) { 112349c55878SDavid Wu if ((pin % 8) >= 4) 112449c55878SDavid Wu reg += 0x4; 112549c55878SDavid Wu bit = (pin % 4) * 4; 112649c55878SDavid Wu mask = 0xf; 112749c55878SDavid Wu } else if (mux_type & IOMUX_WIDTH_3BIT) { 112849c55878SDavid Wu if ((pin % 8) >= 5) 112949c55878SDavid Wu reg += 0x4; 113049c55878SDavid Wu bit = (pin % 8 % 5) * 3; 113149c55878SDavid Wu mask = 0x7; 113249c55878SDavid Wu } else { 113349c55878SDavid Wu bit = (pin % 8) * 2; 113449c55878SDavid Wu mask = 0x3; 113549c55878SDavid Wu } 113649c55878SDavid Wu 113749c55878SDavid Wu if (bank->recalced_mask & BIT(pin)) 113849c55878SDavid Wu rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); 113949c55878SDavid Wu 114049c55878SDavid Wu if (bank->route_mask & BIT(pin)) { 114149c55878SDavid Wu if (rockchip_get_mux_route(bank, pin, mux, &route_reg, 114249c55878SDavid Wu &route_val)) { 114349c55878SDavid Wu ret = regmap_write(regmap, route_reg, route_val); 114449c55878SDavid Wu if (ret) 114549c55878SDavid Wu return ret; 114649c55878SDavid Wu } 114749c55878SDavid Wu } 114849c55878SDavid Wu 11494bafc2daSDavid Wu if (mux_type & IOMUX_WRITABLE_32BIT) { 11508bf1bc66SDavid Wu regmap_read(regmap, reg, &data); 11514bafc2daSDavid Wu data &= ~(mask << bit); 11524bafc2daSDavid Wu } else { 115349c55878SDavid Wu data = (mask << (bit + 16)); 11544bafc2daSDavid Wu } 11558bf1bc66SDavid Wu 115649c55878SDavid Wu data |= (mux & mask) << bit; 115749c55878SDavid Wu ret = regmap_write(regmap, reg, data); 115849c55878SDavid Wu 115949c55878SDavid Wu return ret; 116049c55878SDavid Wu } 116149c55878SDavid Wu 116249c55878SDavid Wu #define PX30_PULL_PMU_OFFSET 0x10 116349c55878SDavid Wu #define PX30_PULL_GRF_OFFSET 0x60 116449c55878SDavid Wu #define PX30_PULL_BITS_PER_PIN 2 116549c55878SDavid Wu #define PX30_PULL_PINS_PER_REG 8 116649c55878SDavid Wu #define PX30_PULL_BANK_STRIDE 16 116749c55878SDavid Wu 116849c55878SDavid Wu static void px30_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 116949c55878SDavid Wu int pin_num, struct regmap **regmap, 117049c55878SDavid Wu int *reg, u8 *bit) 117149c55878SDavid Wu { 117249c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 117349c55878SDavid Wu 117449c55878SDavid Wu /* The first 32 pins of the first bank are located in PMU */ 117549c55878SDavid Wu if (bank->bank_num == 0) { 117649c55878SDavid Wu *regmap = priv->regmap_pmu; 117749c55878SDavid Wu *reg = PX30_PULL_PMU_OFFSET; 117849c55878SDavid Wu } else { 117949c55878SDavid Wu *regmap = priv->regmap_base; 118049c55878SDavid Wu *reg = PX30_PULL_GRF_OFFSET; 118149c55878SDavid Wu 118249c55878SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 118349c55878SDavid Wu *reg -= 0x10; 118449c55878SDavid Wu *reg += bank->bank_num * PX30_PULL_BANK_STRIDE; 118549c55878SDavid Wu } 118649c55878SDavid Wu 118749c55878SDavid Wu *reg += ((pin_num / PX30_PULL_PINS_PER_REG) * 4); 118849c55878SDavid Wu *bit = (pin_num % PX30_PULL_PINS_PER_REG); 118949c55878SDavid Wu *bit *= PX30_PULL_BITS_PER_PIN; 119049c55878SDavid Wu } 119149c55878SDavid Wu 119249c55878SDavid Wu #define PX30_DRV_PMU_OFFSET 0x20 119349c55878SDavid Wu #define PX30_DRV_GRF_OFFSET 0xf0 119449c55878SDavid Wu #define PX30_DRV_BITS_PER_PIN 2 119549c55878SDavid Wu #define PX30_DRV_PINS_PER_REG 8 119649c55878SDavid Wu #define PX30_DRV_BANK_STRIDE 16 119749c55878SDavid Wu 119849c55878SDavid Wu static void px30_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 119949c55878SDavid Wu int pin_num, struct regmap **regmap, 120049c55878SDavid Wu int *reg, u8 *bit) 120149c55878SDavid Wu { 120249c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 120349c55878SDavid Wu 120449c55878SDavid Wu /* The first 32 pins of the first bank are located in PMU */ 120549c55878SDavid Wu if (bank->bank_num == 0) { 120649c55878SDavid Wu *regmap = priv->regmap_pmu; 120749c55878SDavid Wu *reg = PX30_DRV_PMU_OFFSET; 120849c55878SDavid Wu } else { 120949c55878SDavid Wu *regmap = priv->regmap_base; 121049c55878SDavid Wu *reg = PX30_DRV_GRF_OFFSET; 121149c55878SDavid Wu 121249c55878SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 121349c55878SDavid Wu *reg -= 0x10; 121449c55878SDavid Wu *reg += bank->bank_num * PX30_DRV_BANK_STRIDE; 121549c55878SDavid Wu } 121649c55878SDavid Wu 121749c55878SDavid Wu *reg += ((pin_num / PX30_DRV_PINS_PER_REG) * 4); 121849c55878SDavid Wu *bit = (pin_num % PX30_DRV_PINS_PER_REG); 121949c55878SDavid Wu *bit *= PX30_DRV_BITS_PER_PIN; 122049c55878SDavid Wu } 122149c55878SDavid Wu 122249c55878SDavid Wu #define PX30_SCHMITT_PMU_OFFSET 0x38 122349c55878SDavid Wu #define PX30_SCHMITT_GRF_OFFSET 0xc0 122449c55878SDavid Wu #define PX30_SCHMITT_PINS_PER_PMU_REG 16 122549c55878SDavid Wu #define PX30_SCHMITT_BANK_STRIDE 16 122649c55878SDavid Wu #define PX30_SCHMITT_PINS_PER_GRF_REG 8 122749c55878SDavid Wu 122849c55878SDavid Wu static int px30_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 122949c55878SDavid Wu int pin_num, 123049c55878SDavid Wu struct regmap **regmap, 123149c55878SDavid Wu int *reg, u8 *bit) 123249c55878SDavid Wu { 123349c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 123449c55878SDavid Wu int pins_per_reg; 123549c55878SDavid Wu 123649c55878SDavid Wu if (bank->bank_num == 0) { 123749c55878SDavid Wu *regmap = priv->regmap_pmu; 123849c55878SDavid Wu *reg = PX30_SCHMITT_PMU_OFFSET; 123949c55878SDavid Wu pins_per_reg = PX30_SCHMITT_PINS_PER_PMU_REG; 124049c55878SDavid Wu } else { 124149c55878SDavid Wu *regmap = priv->regmap_base; 124249c55878SDavid Wu *reg = PX30_SCHMITT_GRF_OFFSET; 124349c55878SDavid Wu pins_per_reg = PX30_SCHMITT_PINS_PER_GRF_REG; 124449c55878SDavid Wu *reg += (bank->bank_num - 1) * PX30_SCHMITT_BANK_STRIDE; 124549c55878SDavid Wu } 124649c55878SDavid Wu *reg += ((pin_num / pins_per_reg) * 4); 124749c55878SDavid Wu *bit = pin_num % pins_per_reg; 124849c55878SDavid Wu 124949c55878SDavid Wu return 0; 125049c55878SDavid Wu } 125149c55878SDavid Wu 125249c55878SDavid Wu #define RV1108_PULL_PMU_OFFSET 0x10 125349c55878SDavid Wu #define RV1108_PULL_OFFSET 0x110 125449c55878SDavid Wu #define RV1108_PULL_PINS_PER_REG 8 125549c55878SDavid Wu #define RV1108_PULL_BITS_PER_PIN 2 125649c55878SDavid Wu #define RV1108_PULL_BANK_STRIDE 16 125749c55878SDavid Wu 125849c55878SDavid Wu static void rv1108_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 125949c55878SDavid Wu int pin_num, struct regmap **regmap, 126049c55878SDavid Wu int *reg, u8 *bit) 126149c55878SDavid Wu { 126249c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 126349c55878SDavid Wu 126449c55878SDavid Wu /* The first 24 pins of the first bank are located in PMU */ 126549c55878SDavid Wu if (bank->bank_num == 0) { 126649c55878SDavid Wu *regmap = priv->regmap_pmu; 126749c55878SDavid Wu *reg = RV1108_PULL_PMU_OFFSET; 126849c55878SDavid Wu } else { 126949c55878SDavid Wu *reg = RV1108_PULL_OFFSET; 127049c55878SDavid Wu *regmap = priv->regmap_base; 127149c55878SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 127249c55878SDavid Wu *reg -= 0x10; 127349c55878SDavid Wu *reg += bank->bank_num * RV1108_PULL_BANK_STRIDE; 127449c55878SDavid Wu } 127549c55878SDavid Wu 127649c55878SDavid Wu *reg += ((pin_num / RV1108_PULL_PINS_PER_REG) * 4); 127749c55878SDavid Wu *bit = (pin_num % RV1108_PULL_PINS_PER_REG); 127849c55878SDavid Wu *bit *= RV1108_PULL_BITS_PER_PIN; 127949c55878SDavid Wu } 128049c55878SDavid Wu 128149c55878SDavid Wu #define RV1108_DRV_PMU_OFFSET 0x20 128249c55878SDavid Wu #define RV1108_DRV_GRF_OFFSET 0x210 128349c55878SDavid Wu #define RV1108_DRV_BITS_PER_PIN 2 128449c55878SDavid Wu #define RV1108_DRV_PINS_PER_REG 8 128549c55878SDavid Wu #define RV1108_DRV_BANK_STRIDE 16 128649c55878SDavid Wu 128749c55878SDavid Wu static void rv1108_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 128849c55878SDavid Wu int pin_num, struct regmap **regmap, 128949c55878SDavid Wu int *reg, u8 *bit) 129049c55878SDavid Wu { 129149c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 129249c55878SDavid Wu 129349c55878SDavid Wu /* The first 24 pins of the first bank are located in PMU */ 129449c55878SDavid Wu if (bank->bank_num == 0) { 129549c55878SDavid Wu *regmap = priv->regmap_pmu; 129649c55878SDavid Wu *reg = RV1108_DRV_PMU_OFFSET; 129749c55878SDavid Wu } else { 129849c55878SDavid Wu *regmap = priv->regmap_base; 129949c55878SDavid Wu *reg = RV1108_DRV_GRF_OFFSET; 130049c55878SDavid Wu 130149c55878SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 130249c55878SDavid Wu *reg -= 0x10; 130349c55878SDavid Wu *reg += bank->bank_num * RV1108_DRV_BANK_STRIDE; 130449c55878SDavid Wu } 130549c55878SDavid Wu 130649c55878SDavid Wu *reg += ((pin_num / RV1108_DRV_PINS_PER_REG) * 4); 130749c55878SDavid Wu *bit = pin_num % RV1108_DRV_PINS_PER_REG; 130849c55878SDavid Wu *bit *= RV1108_DRV_BITS_PER_PIN; 130949c55878SDavid Wu } 131049c55878SDavid Wu 131149c55878SDavid Wu #define RV1108_SCHMITT_PMU_OFFSET 0x30 131249c55878SDavid Wu #define RV1108_SCHMITT_GRF_OFFSET 0x388 131349c55878SDavid Wu #define RV1108_SCHMITT_BANK_STRIDE 8 131449c55878SDavid Wu #define RV1108_SCHMITT_PINS_PER_GRF_REG 16 131549c55878SDavid Wu #define RV1108_SCHMITT_PINS_PER_PMU_REG 8 131649c55878SDavid Wu 131749c55878SDavid Wu static int rv1108_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 131849c55878SDavid Wu int pin_num, 131949c55878SDavid Wu struct regmap **regmap, 132049c55878SDavid Wu int *reg, u8 *bit) 132149c55878SDavid Wu { 132249c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 132349c55878SDavid Wu int pins_per_reg; 132449c55878SDavid Wu 132549c55878SDavid Wu if (bank->bank_num == 0) { 132649c55878SDavid Wu *regmap = priv->regmap_pmu; 132749c55878SDavid Wu *reg = RV1108_SCHMITT_PMU_OFFSET; 132849c55878SDavid Wu pins_per_reg = RV1108_SCHMITT_PINS_PER_PMU_REG; 132949c55878SDavid Wu } else { 133049c55878SDavid Wu *regmap = priv->regmap_base; 133149c55878SDavid Wu *reg = RV1108_SCHMITT_GRF_OFFSET; 133249c55878SDavid Wu pins_per_reg = RV1108_SCHMITT_PINS_PER_GRF_REG; 133349c55878SDavid Wu *reg += (bank->bank_num - 1) * RV1108_SCHMITT_BANK_STRIDE; 133449c55878SDavid Wu } 133549c55878SDavid Wu *reg += ((pin_num / pins_per_reg) * 4); 133649c55878SDavid Wu *bit = pin_num % pins_per_reg; 133749c55878SDavid Wu 133849c55878SDavid Wu return 0; 133949c55878SDavid Wu } 134049c55878SDavid Wu 134149c55878SDavid Wu #define RK2928_PULL_OFFSET 0x118 134249c55878SDavid Wu #define RK2928_PULL_PINS_PER_REG 16 134349c55878SDavid Wu #define RK2928_PULL_BANK_STRIDE 8 134449c55878SDavid Wu 134549c55878SDavid Wu static void rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 134649c55878SDavid Wu int pin_num, struct regmap **regmap, 134749c55878SDavid Wu int *reg, u8 *bit) 134849c55878SDavid Wu { 134949c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 135049c55878SDavid Wu 135149c55878SDavid Wu *regmap = priv->regmap_base; 135249c55878SDavid Wu *reg = RK2928_PULL_OFFSET; 135349c55878SDavid Wu *reg += bank->bank_num * RK2928_PULL_BANK_STRIDE; 135449c55878SDavid Wu *reg += (pin_num / RK2928_PULL_PINS_PER_REG) * 4; 135549c55878SDavid Wu 135649c55878SDavid Wu *bit = pin_num % RK2928_PULL_PINS_PER_REG; 135749c55878SDavid Wu }; 135849c55878SDavid Wu 135949c55878SDavid Wu #define RK3128_PULL_OFFSET 0x118 136049c55878SDavid Wu 136149c55878SDavid Wu static void rk3128_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 136249c55878SDavid Wu int pin_num, struct regmap **regmap, 136349c55878SDavid Wu int *reg, u8 *bit) 136449c55878SDavid Wu { 136549c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 136649c55878SDavid Wu 136749c55878SDavid Wu *regmap = priv->regmap_base; 136849c55878SDavid Wu *reg = RK3128_PULL_OFFSET; 136949c55878SDavid Wu *reg += bank->bank_num * RK2928_PULL_BANK_STRIDE; 137049c55878SDavid Wu *reg += ((pin_num / RK2928_PULL_PINS_PER_REG) * 4); 137149c55878SDavid Wu 137249c55878SDavid Wu *bit = pin_num % RK2928_PULL_PINS_PER_REG; 137349c55878SDavid Wu } 137449c55878SDavid Wu 137549c55878SDavid Wu #define RK3188_PULL_OFFSET 0x164 137649c55878SDavid Wu #define RK3188_PULL_BITS_PER_PIN 2 137749c55878SDavid Wu #define RK3188_PULL_PINS_PER_REG 8 137849c55878SDavid Wu #define RK3188_PULL_BANK_STRIDE 16 137949c55878SDavid Wu #define RK3188_PULL_PMU_OFFSET 0x64 138049c55878SDavid Wu 138149c55878SDavid Wu static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 138249c55878SDavid Wu int pin_num, struct regmap **regmap, 138349c55878SDavid Wu int *reg, u8 *bit) 138449c55878SDavid Wu { 138549c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 138649c55878SDavid Wu 138749c55878SDavid Wu /* The first 12 pins of the first bank are located elsewhere */ 138849c55878SDavid Wu if (bank->bank_num == 0 && pin_num < 12) { 138949c55878SDavid Wu *regmap = priv->regmap_pmu; 139049c55878SDavid Wu *reg = RK3188_PULL_PMU_OFFSET; 139149c55878SDavid Wu 139249c55878SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 139349c55878SDavid Wu *bit = pin_num % RK3188_PULL_PINS_PER_REG; 139449c55878SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 139549c55878SDavid Wu } else { 139649c55878SDavid Wu *regmap = priv->regmap_base; 139749c55878SDavid Wu *reg = RK3188_PULL_OFFSET; 139849c55878SDavid Wu 139949c55878SDavid Wu /* correct the offset, as it is the 2nd pull register */ 140049c55878SDavid Wu *reg -= 4; 140149c55878SDavid Wu *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 140249c55878SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 140349c55878SDavid Wu 140449c55878SDavid Wu /* 140549c55878SDavid Wu * The bits in these registers have an inverse ordering 140649c55878SDavid Wu * with the lowest pin being in bits 15:14 and the highest 140749c55878SDavid Wu * pin in bits 1:0 140849c55878SDavid Wu */ 140949c55878SDavid Wu *bit = 7 - (pin_num % RK3188_PULL_PINS_PER_REG); 141049c55878SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 141149c55878SDavid Wu } 141249c55878SDavid Wu } 141349c55878SDavid Wu 141449c55878SDavid Wu #define RK3288_PULL_OFFSET 0x140 141549c55878SDavid Wu static void rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 141649c55878SDavid Wu int pin_num, struct regmap **regmap, 141749c55878SDavid Wu int *reg, u8 *bit) 141849c55878SDavid Wu { 141949c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 142049c55878SDavid Wu 142149c55878SDavid Wu /* The first 24 pins of the first bank are located in PMU */ 142249c55878SDavid Wu if (bank->bank_num == 0) { 142349c55878SDavid Wu *regmap = priv->regmap_pmu; 142449c55878SDavid Wu *reg = RK3188_PULL_PMU_OFFSET; 142549c55878SDavid Wu 142649c55878SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 142749c55878SDavid Wu *bit = pin_num % RK3188_PULL_PINS_PER_REG; 142849c55878SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 142949c55878SDavid Wu } else { 143049c55878SDavid Wu *regmap = priv->regmap_base; 143149c55878SDavid Wu *reg = RK3288_PULL_OFFSET; 143249c55878SDavid Wu 143349c55878SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 143449c55878SDavid Wu *reg -= 0x10; 143549c55878SDavid Wu *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 143649c55878SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 143749c55878SDavid Wu 143849c55878SDavid Wu *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 143949c55878SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 144049c55878SDavid Wu } 144149c55878SDavid Wu } 144249c55878SDavid Wu 144349c55878SDavid Wu #define RK3288_DRV_PMU_OFFSET 0x70 144449c55878SDavid Wu #define RK3288_DRV_GRF_OFFSET 0x1c0 144549c55878SDavid Wu #define RK3288_DRV_BITS_PER_PIN 2 144649c55878SDavid Wu #define RK3288_DRV_PINS_PER_REG 8 144749c55878SDavid Wu #define RK3288_DRV_BANK_STRIDE 16 144849c55878SDavid Wu 144949c55878SDavid Wu static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 145049c55878SDavid Wu int pin_num, struct regmap **regmap, 145149c55878SDavid Wu int *reg, u8 *bit) 145249c55878SDavid Wu { 145349c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 145449c55878SDavid Wu 145549c55878SDavid Wu /* The first 24 pins of the first bank are located in PMU */ 145649c55878SDavid Wu if (bank->bank_num == 0) { 145749c55878SDavid Wu *regmap = priv->regmap_pmu; 145849c55878SDavid Wu *reg = RK3288_DRV_PMU_OFFSET; 145949c55878SDavid Wu 146049c55878SDavid Wu *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 146149c55878SDavid Wu *bit = pin_num % RK3288_DRV_PINS_PER_REG; 146249c55878SDavid Wu *bit *= RK3288_DRV_BITS_PER_PIN; 146349c55878SDavid Wu } else { 146449c55878SDavid Wu *regmap = priv->regmap_base; 146549c55878SDavid Wu *reg = RK3288_DRV_GRF_OFFSET; 146649c55878SDavid Wu 146749c55878SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 146849c55878SDavid Wu *reg -= 0x10; 146949c55878SDavid Wu *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; 147049c55878SDavid Wu *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 147149c55878SDavid Wu 147249c55878SDavid Wu *bit = (pin_num % RK3288_DRV_PINS_PER_REG); 147349c55878SDavid Wu *bit *= RK3288_DRV_BITS_PER_PIN; 147449c55878SDavid Wu } 147549c55878SDavid Wu } 147649c55878SDavid Wu 147749c55878SDavid Wu #define RK3228_PULL_OFFSET 0x100 147849c55878SDavid Wu 147949c55878SDavid Wu static void rk3228_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 148049c55878SDavid Wu int pin_num, struct regmap **regmap, 148149c55878SDavid Wu int *reg, u8 *bit) 148249c55878SDavid Wu { 148349c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 148449c55878SDavid Wu 148549c55878SDavid Wu *regmap = priv->regmap_base; 148649c55878SDavid Wu *reg = RK3228_PULL_OFFSET; 148749c55878SDavid Wu *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 148849c55878SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 148949c55878SDavid Wu 149049c55878SDavid Wu *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 149149c55878SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 149249c55878SDavid Wu } 149349c55878SDavid Wu 149449c55878SDavid Wu #define RK3228_DRV_GRF_OFFSET 0x200 149549c55878SDavid Wu 149649c55878SDavid Wu static void rk3228_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 149749c55878SDavid Wu int pin_num, struct regmap **regmap, 149849c55878SDavid Wu int *reg, u8 *bit) 149949c55878SDavid Wu { 150049c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 150149c55878SDavid Wu 150249c55878SDavid Wu *regmap = priv->regmap_base; 150349c55878SDavid Wu *reg = RK3228_DRV_GRF_OFFSET; 150449c55878SDavid Wu *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; 150549c55878SDavid Wu *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 150649c55878SDavid Wu 150749c55878SDavid Wu *bit = (pin_num % RK3288_DRV_PINS_PER_REG); 150849c55878SDavid Wu *bit *= RK3288_DRV_BITS_PER_PIN; 150949c55878SDavid Wu } 151049c55878SDavid Wu 1511b3077611SDavid Wu #define RK3308_PULL_OFFSET 0xa0 1512b3077611SDavid Wu 1513b3077611SDavid Wu static void rk3308_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1514b3077611SDavid Wu int pin_num, struct regmap **regmap, 1515b3077611SDavid Wu int *reg, u8 *bit) 1516b3077611SDavid Wu { 1517b3077611SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 1518b3077611SDavid Wu 1519b3077611SDavid Wu *regmap = priv->regmap_base; 1520b3077611SDavid Wu *reg = RK3308_PULL_OFFSET; 1521b3077611SDavid Wu *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 1522b3077611SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 1523b3077611SDavid Wu 1524b3077611SDavid Wu *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 1525b3077611SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 1526b3077611SDavid Wu } 1527b3077611SDavid Wu 1528b3077611SDavid Wu #define RK3308_DRV_GRF_OFFSET 0x100 1529b3077611SDavid Wu 1530b3077611SDavid Wu static void rk3308_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 1531b3077611SDavid Wu int pin_num, struct regmap **regmap, 1532b3077611SDavid Wu int *reg, u8 *bit) 1533b3077611SDavid Wu { 1534b3077611SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 1535b3077611SDavid Wu 1536b3077611SDavid Wu *regmap = priv->regmap_base; 1537b3077611SDavid Wu *reg = RK3308_DRV_GRF_OFFSET; 1538b3077611SDavid Wu *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; 1539b3077611SDavid Wu *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 1540b3077611SDavid Wu 1541b3077611SDavid Wu *bit = (pin_num % RK3288_DRV_PINS_PER_REG); 1542b3077611SDavid Wu *bit *= RK3288_DRV_BITS_PER_PIN; 1543b3077611SDavid Wu } 1544b3077611SDavid Wu 1545b3077611SDavid Wu #define RK3308_SCHMITT_PINS_PER_REG 8 1546b3077611SDavid Wu #define RK3308_SCHMITT_BANK_STRIDE 16 1547b3077611SDavid Wu #define RK3308_SCHMITT_GRF_OFFSET 0x1a0 1548b3077611SDavid Wu 1549b3077611SDavid Wu static int rk3308_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 1550b3077611SDavid Wu int pin_num, 1551b3077611SDavid Wu struct regmap **regmap, 1552b3077611SDavid Wu int *reg, u8 *bit) 1553b3077611SDavid Wu { 1554b3077611SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 1555b3077611SDavid Wu 1556b3077611SDavid Wu *regmap = priv->regmap_base; 1557b3077611SDavid Wu *reg = RK3308_SCHMITT_GRF_OFFSET; 1558b3077611SDavid Wu 1559b3077611SDavid Wu *reg += bank->bank_num * RK3308_SCHMITT_BANK_STRIDE; 1560b3077611SDavid Wu *reg += ((pin_num / RK3308_SCHMITT_PINS_PER_REG) * 4); 1561b3077611SDavid Wu *bit = pin_num % RK3308_SCHMITT_PINS_PER_REG; 1562b3077611SDavid Wu 1563b3077611SDavid Wu return 0; 1564b3077611SDavid Wu } 1565b3077611SDavid Wu 156649c55878SDavid Wu #define RK3368_PULL_GRF_OFFSET 0x100 156749c55878SDavid Wu #define RK3368_PULL_PMU_OFFSET 0x10 156849c55878SDavid Wu 156949c55878SDavid Wu static void rk3368_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 157049c55878SDavid Wu int pin_num, struct regmap **regmap, 157149c55878SDavid Wu int *reg, u8 *bit) 157249c55878SDavid Wu { 157349c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 157449c55878SDavid Wu 157549c55878SDavid Wu /* The first 32 pins of the first bank are located in PMU */ 157649c55878SDavid Wu if (bank->bank_num == 0) { 157749c55878SDavid Wu *regmap = priv->regmap_pmu; 157849c55878SDavid Wu *reg = RK3368_PULL_PMU_OFFSET; 157949c55878SDavid Wu 158049c55878SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 158149c55878SDavid Wu *bit = pin_num % RK3188_PULL_PINS_PER_REG; 158249c55878SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 158349c55878SDavid Wu } else { 158449c55878SDavid Wu *regmap = priv->regmap_base; 158549c55878SDavid Wu *reg = RK3368_PULL_GRF_OFFSET; 158649c55878SDavid Wu 158749c55878SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 158849c55878SDavid Wu *reg -= 0x10; 158949c55878SDavid Wu *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 159049c55878SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 159149c55878SDavid Wu 159249c55878SDavid Wu *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 159349c55878SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 159449c55878SDavid Wu } 159549c55878SDavid Wu } 159649c55878SDavid Wu 159749c55878SDavid Wu #define RK3368_DRV_PMU_OFFSET 0x20 159849c55878SDavid Wu #define RK3368_DRV_GRF_OFFSET 0x200 159949c55878SDavid Wu 160049c55878SDavid Wu static void rk3368_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 160149c55878SDavid Wu int pin_num, struct regmap **regmap, 160249c55878SDavid Wu int *reg, u8 *bit) 160349c55878SDavid Wu { 160449c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 160549c55878SDavid Wu 160649c55878SDavid Wu /* The first 32 pins of the first bank are located in PMU */ 160749c55878SDavid Wu if (bank->bank_num == 0) { 160849c55878SDavid Wu *regmap = priv->regmap_pmu; 160949c55878SDavid Wu *reg = RK3368_DRV_PMU_OFFSET; 161049c55878SDavid Wu 161149c55878SDavid Wu *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 161249c55878SDavid Wu *bit = pin_num % RK3288_DRV_PINS_PER_REG; 161349c55878SDavid Wu *bit *= RK3288_DRV_BITS_PER_PIN; 161449c55878SDavid Wu } else { 161549c55878SDavid Wu *regmap = priv->regmap_base; 161649c55878SDavid Wu *reg = RK3368_DRV_GRF_OFFSET; 161749c55878SDavid Wu 161849c55878SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 161949c55878SDavid Wu *reg -= 0x10; 162049c55878SDavid Wu *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; 162149c55878SDavid Wu *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 162249c55878SDavid Wu 162349c55878SDavid Wu *bit = (pin_num % RK3288_DRV_PINS_PER_REG); 162449c55878SDavid Wu *bit *= RK3288_DRV_BITS_PER_PIN; 162549c55878SDavid Wu } 162649c55878SDavid Wu } 162749c55878SDavid Wu 162849c55878SDavid Wu #define RK3399_PULL_GRF_OFFSET 0xe040 162949c55878SDavid Wu #define RK3399_PULL_PMU_OFFSET 0x40 163049c55878SDavid Wu #define RK3399_DRV_3BITS_PER_PIN 3 163149c55878SDavid Wu 163249c55878SDavid Wu static void rk3399_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 163349c55878SDavid Wu int pin_num, struct regmap **regmap, 163449c55878SDavid Wu int *reg, u8 *bit) 163549c55878SDavid Wu { 163649c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 163749c55878SDavid Wu 163849c55878SDavid Wu /* The bank0:16 and bank1:32 pins are located in PMU */ 163949c55878SDavid Wu if ((bank->bank_num == 0) || (bank->bank_num == 1)) { 164049c55878SDavid Wu *regmap = priv->regmap_pmu; 164149c55878SDavid Wu *reg = RK3399_PULL_PMU_OFFSET; 164249c55878SDavid Wu 164349c55878SDavid Wu *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 164449c55878SDavid Wu 164549c55878SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 164649c55878SDavid Wu *bit = pin_num % RK3188_PULL_PINS_PER_REG; 164749c55878SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 164849c55878SDavid Wu } else { 164949c55878SDavid Wu *regmap = priv->regmap_base; 165049c55878SDavid Wu *reg = RK3399_PULL_GRF_OFFSET; 165149c55878SDavid Wu 165249c55878SDavid Wu /* correct the offset, as we're starting with the 3rd bank */ 165349c55878SDavid Wu *reg -= 0x20; 165449c55878SDavid Wu *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 165549c55878SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 165649c55878SDavid Wu 165749c55878SDavid Wu *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 165849c55878SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 165949c55878SDavid Wu } 166049c55878SDavid Wu } 166149c55878SDavid Wu 166249c55878SDavid Wu static void rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 166349c55878SDavid Wu int pin_num, struct regmap **regmap, 166449c55878SDavid Wu int *reg, u8 *bit) 166549c55878SDavid Wu { 166649c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 166749c55878SDavid Wu int drv_num = (pin_num / 8); 166849c55878SDavid Wu 166949c55878SDavid Wu /* The bank0:16 and bank1:32 pins are located in PMU */ 167049c55878SDavid Wu if ((bank->bank_num == 0) || (bank->bank_num == 1)) 167149c55878SDavid Wu *regmap = priv->regmap_pmu; 167249c55878SDavid Wu else 167349c55878SDavid Wu *regmap = priv->regmap_base; 167449c55878SDavid Wu 167549c55878SDavid Wu *reg = bank->drv[drv_num].offset; 167649c55878SDavid Wu if ((bank->drv[drv_num].drv_type == DRV_TYPE_IO_1V8_3V0_AUTO) || 167749c55878SDavid Wu (bank->drv[drv_num].drv_type == DRV_TYPE_IO_3V3_ONLY)) 167849c55878SDavid Wu *bit = (pin_num % 8) * 3; 167949c55878SDavid Wu else 168049c55878SDavid Wu *bit = (pin_num % 8) * 2; 168149c55878SDavid Wu } 168249c55878SDavid Wu 168349c55878SDavid Wu static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = { 168449c55878SDavid Wu { 2, 4, 8, 12, -1, -1, -1, -1 }, 168549c55878SDavid Wu { 3, 6, 9, 12, -1, -1, -1, -1 }, 168649c55878SDavid Wu { 5, 10, 15, 20, -1, -1, -1, -1 }, 168749c55878SDavid Wu { 4, 6, 8, 10, 12, 14, 16, 18 }, 168849c55878SDavid Wu { 4, 7, 10, 13, 16, 19, 22, 26 } 168949c55878SDavid Wu }; 169049c55878SDavid Wu 169149c55878SDavid Wu static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, 169249c55878SDavid Wu int pin_num, int strength) 169349c55878SDavid Wu { 169449c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 169549c55878SDavid Wu struct rockchip_pin_ctrl *ctrl = priv->ctrl; 169649c55878SDavid Wu struct regmap *regmap; 169749c55878SDavid Wu int reg, ret, i; 169849c55878SDavid Wu u32 data, rmask_bits, temp; 169949c55878SDavid Wu u8 bit; 1700*55a89bc6SDavid Wu int drv_type = bank->drv[pin_num / 8].drv_type & DRV_TYPE_IO_MASK; 170149c55878SDavid Wu 170249c55878SDavid Wu debug("setting drive of GPIO%d-%d to %d\n", bank->bank_num, 170349c55878SDavid Wu pin_num, strength); 170449c55878SDavid Wu 170549c55878SDavid Wu ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit); 170649c55878SDavid Wu 170749c55878SDavid Wu ret = -EINVAL; 170849c55878SDavid Wu for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list[drv_type]); i++) { 170949c55878SDavid Wu if (rockchip_perpin_drv_list[drv_type][i] == strength) { 171049c55878SDavid Wu ret = i; 171149c55878SDavid Wu break; 171249c55878SDavid Wu } else if (rockchip_perpin_drv_list[drv_type][i] < 0) { 171349c55878SDavid Wu ret = rockchip_perpin_drv_list[drv_type][i]; 171449c55878SDavid Wu break; 171549c55878SDavid Wu } 171649c55878SDavid Wu } 171749c55878SDavid Wu 171849c55878SDavid Wu if (ret < 0) { 171949c55878SDavid Wu debug("unsupported driver strength %d\n", strength); 172049c55878SDavid Wu return ret; 172149c55878SDavid Wu } 172249c55878SDavid Wu 172349c55878SDavid Wu switch (drv_type) { 172449c55878SDavid Wu case DRV_TYPE_IO_1V8_3V0_AUTO: 172549c55878SDavid Wu case DRV_TYPE_IO_3V3_ONLY: 172649c55878SDavid Wu rmask_bits = RK3399_DRV_3BITS_PER_PIN; 172749c55878SDavid Wu switch (bit) { 172849c55878SDavid Wu case 0 ... 12: 172949c55878SDavid Wu /* regular case, nothing to do */ 173049c55878SDavid Wu break; 173149c55878SDavid Wu case 15: 173249c55878SDavid Wu /* 173349c55878SDavid Wu * drive-strength offset is special, as it is spread 173449c55878SDavid Wu * over 2 registers, the bit data[15] contains bit 0 173549c55878SDavid Wu * of the value while temp[1:0] contains bits 2 and 1 173649c55878SDavid Wu */ 173749c55878SDavid Wu data = (ret & 0x1) << 15; 173849c55878SDavid Wu temp = (ret >> 0x1) & 0x3; 173949c55878SDavid Wu 174049c55878SDavid Wu data |= BIT(31); 174149c55878SDavid Wu ret = regmap_write(regmap, reg, data); 174249c55878SDavid Wu if (ret) 174349c55878SDavid Wu return ret; 174449c55878SDavid Wu 174549c55878SDavid Wu temp |= (0x3 << 16); 174649c55878SDavid Wu reg += 0x4; 174749c55878SDavid Wu ret = regmap_write(regmap, reg, temp); 174849c55878SDavid Wu 174949c55878SDavid Wu return ret; 175049c55878SDavid Wu case 18 ... 21: 175149c55878SDavid Wu /* setting fully enclosed in the second register */ 175249c55878SDavid Wu reg += 4; 175349c55878SDavid Wu bit -= 16; 175449c55878SDavid Wu break; 175549c55878SDavid Wu default: 175649c55878SDavid Wu debug("unsupported bit: %d for pinctrl drive type: %d\n", 175749c55878SDavid Wu bit, drv_type); 175849c55878SDavid Wu return -EINVAL; 175949c55878SDavid Wu } 176049c55878SDavid Wu break; 176149c55878SDavid Wu case DRV_TYPE_IO_DEFAULT: 176249c55878SDavid Wu case DRV_TYPE_IO_1V8_OR_3V0: 176349c55878SDavid Wu case DRV_TYPE_IO_1V8_ONLY: 176449c55878SDavid Wu rmask_bits = RK3288_DRV_BITS_PER_PIN; 176549c55878SDavid Wu break; 176649c55878SDavid Wu default: 176749c55878SDavid Wu debug("unsupported pinctrl drive type: %d\n", 176849c55878SDavid Wu drv_type); 176949c55878SDavid Wu return -EINVAL; 177049c55878SDavid Wu } 177149c55878SDavid Wu 1772*55a89bc6SDavid Wu if (bank->drv[pin_num / 8].drv_type & DRV_TYPE_WRITABLE_32BIT) { 1773*55a89bc6SDavid Wu regmap_read(regmap, reg, &data); 1774*55a89bc6SDavid Wu data &= ~(((1 << rmask_bits) - 1) << bit); 1775*55a89bc6SDavid Wu } else { 177649c55878SDavid Wu /* enable the write to the equivalent lower bits */ 177749c55878SDavid Wu data = ((1 << rmask_bits) - 1) << (bit + 16); 1778*55a89bc6SDavid Wu } 177949c55878SDavid Wu 1780*55a89bc6SDavid Wu data |= (ret << bit); 178149c55878SDavid Wu ret = regmap_write(regmap, reg, data); 178249c55878SDavid Wu return ret; 178349c55878SDavid Wu } 178449c55878SDavid Wu 178549c55878SDavid Wu static int rockchip_pull_list[PULL_TYPE_MAX][4] = { 178649c55878SDavid Wu { 178749c55878SDavid Wu PIN_CONFIG_BIAS_DISABLE, 178849c55878SDavid Wu PIN_CONFIG_BIAS_PULL_UP, 178949c55878SDavid Wu PIN_CONFIG_BIAS_PULL_DOWN, 179049c55878SDavid Wu PIN_CONFIG_BIAS_BUS_HOLD 179149c55878SDavid Wu }, 179249c55878SDavid Wu { 179349c55878SDavid Wu PIN_CONFIG_BIAS_DISABLE, 179449c55878SDavid Wu PIN_CONFIG_BIAS_PULL_DOWN, 179549c55878SDavid Wu PIN_CONFIG_BIAS_DISABLE, 179649c55878SDavid Wu PIN_CONFIG_BIAS_PULL_UP 179749c55878SDavid Wu }, 179849c55878SDavid Wu }; 179949c55878SDavid Wu 180049c55878SDavid Wu static int rockchip_set_pull(struct rockchip_pin_bank *bank, 180149c55878SDavid Wu int pin_num, int pull) 180249c55878SDavid Wu { 180349c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 180449c55878SDavid Wu struct rockchip_pin_ctrl *ctrl = priv->ctrl; 180549c55878SDavid Wu struct regmap *regmap; 180649c55878SDavid Wu int reg, ret, i, pull_type; 180749c55878SDavid Wu u8 bit; 180849c55878SDavid Wu u32 data; 180949c55878SDavid Wu 181049c55878SDavid Wu debug("setting pull of GPIO%d-%d to %d\n", bank->bank_num, 181149c55878SDavid Wu pin_num, pull); 181249c55878SDavid Wu 181349c55878SDavid Wu /* rk3066b does support any pulls */ 181449c55878SDavid Wu if (ctrl->type == RK3066B) 181549c55878SDavid Wu return pull ? -EINVAL : 0; 181649c55878SDavid Wu 181749c55878SDavid Wu ctrl->pull_calc_reg(bank, pin_num, ®map, ®, &bit); 181849c55878SDavid Wu 181949c55878SDavid Wu switch (ctrl->type) { 182049c55878SDavid Wu case RK2928: 182149c55878SDavid Wu case RK3128: 182249c55878SDavid Wu data = BIT(bit + 16); 182349c55878SDavid Wu if (pull == PIN_CONFIG_BIAS_DISABLE) 182449c55878SDavid Wu data |= BIT(bit); 182549c55878SDavid Wu ret = regmap_write(regmap, reg, data); 182649c55878SDavid Wu break; 182749c55878SDavid Wu case PX30: 182849c55878SDavid Wu case RV1108: 182949c55878SDavid Wu case RK3188: 183049c55878SDavid Wu case RK3288: 1831b3077611SDavid Wu case RK3308: 183249c55878SDavid Wu case RK3368: 183349c55878SDavid Wu case RK3399: 1834*55a89bc6SDavid Wu pull_type = bank->pull_type[pin_num / 8] & PULL_TYPE_IO_MASK; 183549c55878SDavid Wu ret = -EINVAL; 183649c55878SDavid Wu for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[pull_type]); 183749c55878SDavid Wu i++) { 183849c55878SDavid Wu if (rockchip_pull_list[pull_type][i] == pull) { 183949c55878SDavid Wu ret = i; 184049c55878SDavid Wu break; 184149c55878SDavid Wu } 184249c55878SDavid Wu } 184349c55878SDavid Wu 184449c55878SDavid Wu if (ret < 0) { 184549c55878SDavid Wu debug("unsupported pull setting %d\n", pull); 184649c55878SDavid Wu return ret; 184749c55878SDavid Wu } 184849c55878SDavid Wu 1849*55a89bc6SDavid Wu if (bank->pull_type[pin_num / 8] & PULL_TYPE_WRITABLE_32BIT) { 1850*55a89bc6SDavid Wu regmap_read(regmap, reg, &data); 1851*55a89bc6SDavid Wu data &= ~(((1 << RK3188_PULL_BITS_PER_PIN) - 1) << bit); 1852*55a89bc6SDavid Wu } else { 185349c55878SDavid Wu /* enable the write to the equivalent lower bits */ 185449c55878SDavid Wu data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16); 1855*55a89bc6SDavid Wu } 185649c55878SDavid Wu 1857*55a89bc6SDavid Wu data |= (ret << bit); 185849c55878SDavid Wu ret = regmap_write(regmap, reg, data); 185949c55878SDavid Wu break; 186049c55878SDavid Wu default: 186149c55878SDavid Wu debug("unsupported pinctrl type\n"); 186249c55878SDavid Wu return -EINVAL; 186349c55878SDavid Wu } 186449c55878SDavid Wu 186549c55878SDavid Wu return ret; 186649c55878SDavid Wu } 186749c55878SDavid Wu 186849c55878SDavid Wu #define RK3328_SCHMITT_BITS_PER_PIN 1 186949c55878SDavid Wu #define RK3328_SCHMITT_PINS_PER_REG 16 187049c55878SDavid Wu #define RK3328_SCHMITT_BANK_STRIDE 8 187149c55878SDavid Wu #define RK3328_SCHMITT_GRF_OFFSET 0x380 187249c55878SDavid Wu 187349c55878SDavid Wu static int rk3328_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 187449c55878SDavid Wu int pin_num, 187549c55878SDavid Wu struct regmap **regmap, 187649c55878SDavid Wu int *reg, u8 *bit) 187749c55878SDavid Wu { 187849c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 187949c55878SDavid Wu 188049c55878SDavid Wu *regmap = priv->regmap_base; 188149c55878SDavid Wu *reg = RK3328_SCHMITT_GRF_OFFSET; 188249c55878SDavid Wu 188349c55878SDavid Wu *reg += bank->bank_num * RK3328_SCHMITT_BANK_STRIDE; 188449c55878SDavid Wu *reg += ((pin_num / RK3328_SCHMITT_PINS_PER_REG) * 4); 188549c55878SDavid Wu *bit = pin_num % RK3328_SCHMITT_PINS_PER_REG; 188649c55878SDavid Wu 188749c55878SDavid Wu return 0; 188849c55878SDavid Wu } 188949c55878SDavid Wu 189049c55878SDavid Wu static int rockchip_set_schmitt(struct rockchip_pin_bank *bank, 189149c55878SDavid Wu int pin_num, int enable) 189249c55878SDavid Wu { 189349c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 189449c55878SDavid Wu struct rockchip_pin_ctrl *ctrl = priv->ctrl; 189549c55878SDavid Wu struct regmap *regmap; 189649c55878SDavid Wu int reg, ret; 189749c55878SDavid Wu u8 bit; 189849c55878SDavid Wu u32 data; 189949c55878SDavid Wu 190049c55878SDavid Wu debug("setting input schmitt of GPIO%d-%d to %d\n", bank->bank_num, 190149c55878SDavid Wu pin_num, enable); 190249c55878SDavid Wu 190349c55878SDavid Wu ret = ctrl->schmitt_calc_reg(bank, pin_num, ®map, ®, &bit); 190449c55878SDavid Wu if (ret) 190549c55878SDavid Wu return ret; 190649c55878SDavid Wu 190749c55878SDavid Wu /* enable the write to the equivalent lower bits */ 190849c55878SDavid Wu data = BIT(bit + 16) | (enable << bit); 190949c55878SDavid Wu 191049c55878SDavid Wu return regmap_write(regmap, reg, data); 191149c55878SDavid Wu } 191249c55878SDavid Wu 191349c55878SDavid Wu /* 191449c55878SDavid Wu * Pinconf_ops handling 191549c55878SDavid Wu */ 191649c55878SDavid Wu static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, 191749c55878SDavid Wu unsigned int pull) 191849c55878SDavid Wu { 191949c55878SDavid Wu switch (ctrl->type) { 192049c55878SDavid Wu case RK2928: 192149c55878SDavid Wu case RK3128: 192249c55878SDavid Wu return (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT || 192349c55878SDavid Wu pull == PIN_CONFIG_BIAS_DISABLE); 192449c55878SDavid Wu case RK3066B: 192549c55878SDavid Wu return pull ? false : true; 192649c55878SDavid Wu case PX30: 192749c55878SDavid Wu case RV1108: 192849c55878SDavid Wu case RK3188: 192949c55878SDavid Wu case RK3288: 1930b3077611SDavid Wu case RK3308: 193149c55878SDavid Wu case RK3368: 193249c55878SDavid Wu case RK3399: 193349c55878SDavid Wu return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT); 193449c55878SDavid Wu } 193549c55878SDavid Wu 193649c55878SDavid Wu return false; 193749c55878SDavid Wu } 193849c55878SDavid Wu 193949c55878SDavid Wu /* set the pin config settings for a specified pin */ 194049c55878SDavid Wu static int rockchip_pinconf_set(struct rockchip_pin_bank *bank, 194149c55878SDavid Wu u32 pin, u32 param, u32 arg) 194249c55878SDavid Wu { 194349c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 194449c55878SDavid Wu struct rockchip_pin_ctrl *ctrl = priv->ctrl; 194549c55878SDavid Wu int rc; 194649c55878SDavid Wu 194749c55878SDavid Wu switch (param) { 194849c55878SDavid Wu case PIN_CONFIG_BIAS_DISABLE: 194949c55878SDavid Wu rc = rockchip_set_pull(bank, pin, param); 195049c55878SDavid Wu if (rc) 195149c55878SDavid Wu return rc; 195249c55878SDavid Wu break; 195349c55878SDavid Wu 195449c55878SDavid Wu case PIN_CONFIG_BIAS_PULL_UP: 195549c55878SDavid Wu case PIN_CONFIG_BIAS_PULL_DOWN: 195649c55878SDavid Wu case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: 195749c55878SDavid Wu case PIN_CONFIG_BIAS_BUS_HOLD: 195849c55878SDavid Wu if (!rockchip_pinconf_pull_valid(ctrl, param)) 195949c55878SDavid Wu return -ENOTSUPP; 196049c55878SDavid Wu 196149c55878SDavid Wu if (!arg) 196249c55878SDavid Wu return -EINVAL; 196349c55878SDavid Wu 196449c55878SDavid Wu rc = rockchip_set_pull(bank, pin, param); 196549c55878SDavid Wu if (rc) 196649c55878SDavid Wu return rc; 196749c55878SDavid Wu break; 196849c55878SDavid Wu 196949c55878SDavid Wu case PIN_CONFIG_DRIVE_STRENGTH: 197049c55878SDavid Wu if (!ctrl->drv_calc_reg) 197149c55878SDavid Wu return -ENOTSUPP; 197249c55878SDavid Wu 197349c55878SDavid Wu rc = rockchip_set_drive_perpin(bank, pin, arg); 197449c55878SDavid Wu if (rc < 0) 197549c55878SDavid Wu return rc; 197649c55878SDavid Wu break; 197749c55878SDavid Wu 197849c55878SDavid Wu case PIN_CONFIG_INPUT_SCHMITT_ENABLE: 197949c55878SDavid Wu if (!ctrl->schmitt_calc_reg) 198049c55878SDavid Wu return -ENOTSUPP; 198149c55878SDavid Wu 198249c55878SDavid Wu rc = rockchip_set_schmitt(bank, pin, arg); 198349c55878SDavid Wu if (rc < 0) 198449c55878SDavid Wu return rc; 198549c55878SDavid Wu break; 198649c55878SDavid Wu 198749c55878SDavid Wu default: 198849c55878SDavid Wu break; 198949c55878SDavid Wu } 199049c55878SDavid Wu 199149c55878SDavid Wu return 0; 199249c55878SDavid Wu } 199349c55878SDavid Wu 199449c55878SDavid Wu static const struct pinconf_param rockchip_conf_params[] = { 199549c55878SDavid Wu { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, 199649c55878SDavid Wu { "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 }, 199749c55878SDavid Wu { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 }, 199849c55878SDavid Wu { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 }, 199949c55878SDavid Wu { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 }, 200049c55878SDavid Wu { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 }, 200149c55878SDavid Wu { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 }, 200249c55878SDavid Wu { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 }, 200349c55878SDavid Wu { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 }, 200449c55878SDavid Wu }; 200549c55878SDavid Wu 200649c55878SDavid Wu static int rockchip_pinconf_prop_name_to_param(const char *property, 200749c55878SDavid Wu u32 *default_value) 200849c55878SDavid Wu { 200949c55878SDavid Wu const struct pinconf_param *p, *end; 201049c55878SDavid Wu 201149c55878SDavid Wu p = rockchip_conf_params; 201249c55878SDavid Wu end = p + sizeof(rockchip_conf_params) / sizeof(struct pinconf_param); 201349c55878SDavid Wu 201449c55878SDavid Wu /* See if this pctldev supports this parameter */ 201549c55878SDavid Wu for (; p < end; p++) { 201649c55878SDavid Wu if (!strcmp(property, p->property)) { 201749c55878SDavid Wu *default_value = p->default_value; 201849c55878SDavid Wu return p->param; 201949c55878SDavid Wu } 202049c55878SDavid Wu } 202149c55878SDavid Wu 202249c55878SDavid Wu *default_value = 0; 202349c55878SDavid Wu return -EPERM; 202449c55878SDavid Wu } 202549c55878SDavid Wu 202649c55878SDavid Wu static int rockchip_pinctrl_set_state(struct udevice *dev, 202749c55878SDavid Wu struct udevice *config) 202849c55878SDavid Wu { 202949c55878SDavid Wu struct rockchip_pinctrl_priv *priv = dev_get_priv(dev); 203049c55878SDavid Wu struct rockchip_pin_ctrl *ctrl = priv->ctrl; 203149c55878SDavid Wu u32 cells[MAX_ROCKCHIP_PINS_ENTRIES * 4]; 203249c55878SDavid Wu u32 bank, pin, mux, conf, arg, default_val; 203349c55878SDavid Wu int ret, count, i; 203449c55878SDavid Wu const char *prop_name; 203549c55878SDavid Wu const void *value; 20362208cfa9SKever Yang int prop_len, param; 20372208cfa9SKever Yang const u32 *data; 20382208cfa9SKever Yang ofnode node; 20392208cfa9SKever Yang #ifdef CONFIG_OF_LIVE 20402208cfa9SKever Yang const struct device_node *np; 20412208cfa9SKever Yang struct property *pp; 20422208cfa9SKever Yang #else 20432208cfa9SKever Yang int property_offset, pcfg_node; 20442208cfa9SKever Yang const void *blob = gd->fdt_blob; 20452208cfa9SKever Yang #endif 20462208cfa9SKever Yang data = dev_read_prop(config, "rockchip,pins", &count); 204749c55878SDavid Wu if (count < 0) { 204887f0ac57SDavid Wu debug("%s: bad array size %d\n", __func__, count); 204949c55878SDavid Wu return -EINVAL; 205049c55878SDavid Wu } 205149c55878SDavid Wu 205287f0ac57SDavid Wu count /= sizeof(u32); 205349c55878SDavid Wu if (count > MAX_ROCKCHIP_PINS_ENTRIES * 4) { 205449c55878SDavid Wu debug("%s: unsupported pins array count %d\n", 205549c55878SDavid Wu __func__, count); 205649c55878SDavid Wu return -EINVAL; 205749c55878SDavid Wu } 205849c55878SDavid Wu 205987f0ac57SDavid Wu for (i = 0; i < count; i++) 206087f0ac57SDavid Wu cells[i] = fdt32_to_cpu(data[i]); 206187f0ac57SDavid Wu 206249c55878SDavid Wu for (i = 0; i < (count >> 2); i++) { 206349c55878SDavid Wu bank = cells[4 * i + 0]; 206449c55878SDavid Wu pin = cells[4 * i + 1]; 206549c55878SDavid Wu mux = cells[4 * i + 2]; 206649c55878SDavid Wu conf = cells[4 * i + 3]; 206749c55878SDavid Wu 206849c55878SDavid Wu ret = rockchip_verify_config(dev, bank, pin); 206949c55878SDavid Wu if (ret) 207049c55878SDavid Wu return ret; 207149c55878SDavid Wu 207249c55878SDavid Wu ret = rockchip_set_mux(&ctrl->pin_banks[bank], pin, mux); 207349c55878SDavid Wu if (ret) 207449c55878SDavid Wu return ret; 207549c55878SDavid Wu 20762208cfa9SKever Yang node = ofnode_get_by_phandle(conf); 20772208cfa9SKever Yang if (!ofnode_valid(node)) 207849c55878SDavid Wu return -ENODEV; 20792208cfa9SKever Yang #ifdef CONFIG_OF_LIVE 20802208cfa9SKever Yang np = ofnode_to_np(node); 20812208cfa9SKever Yang for (pp = np->properties; pp; pp = pp->next) { 20822208cfa9SKever Yang prop_name = pp->name; 20832208cfa9SKever Yang prop_len = pp->length; 20842208cfa9SKever Yang value = pp->value; 20852208cfa9SKever Yang #else 20862208cfa9SKever Yang pcfg_node = ofnode_to_offset(node); 208749c55878SDavid Wu fdt_for_each_property_offset(property_offset, blob, pcfg_node) { 208849c55878SDavid Wu value = fdt_getprop_by_offset(blob, property_offset, 208949c55878SDavid Wu &prop_name, &prop_len); 209049c55878SDavid Wu if (!value) 209149c55878SDavid Wu return -ENOENT; 20922208cfa9SKever Yang #endif 209349c55878SDavid Wu param = rockchip_pinconf_prop_name_to_param(prop_name, 209449c55878SDavid Wu &default_val); 209549c55878SDavid Wu if (param < 0) 209649c55878SDavid Wu break; 209749c55878SDavid Wu 209849c55878SDavid Wu if (prop_len >= sizeof(fdt32_t)) 209949c55878SDavid Wu arg = fdt32_to_cpu(*(fdt32_t *)value); 210049c55878SDavid Wu else 210149c55878SDavid Wu arg = default_val; 210249c55878SDavid Wu 210349c55878SDavid Wu ret = rockchip_pinconf_set(&ctrl->pin_banks[bank], pin, 210449c55878SDavid Wu param, arg); 210549c55878SDavid Wu if (ret) { 210649c55878SDavid Wu debug("%s: rockchip_pinconf_set fail: %d\n", 210749c55878SDavid Wu __func__, ret); 210849c55878SDavid Wu return ret; 210949c55878SDavid Wu } 211049c55878SDavid Wu } 211149c55878SDavid Wu } 211249c55878SDavid Wu 211349c55878SDavid Wu return 0; 211449c55878SDavid Wu } 211549c55878SDavid Wu 211649c55878SDavid Wu static struct pinctrl_ops rockchip_pinctrl_ops = { 211749c55878SDavid Wu .set_state = rockchip_pinctrl_set_state, 211849c55878SDavid Wu .get_gpio_mux = rockchip_pinctrl_get_gpio_mux, 211949c55878SDavid Wu }; 212049c55878SDavid Wu 212149c55878SDavid Wu /* retrieve the soc specific data */ 212249c55878SDavid Wu static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *dev) 212349c55878SDavid Wu { 212449c55878SDavid Wu struct rockchip_pinctrl_priv *priv = dev_get_priv(dev); 212549c55878SDavid Wu struct rockchip_pin_ctrl *ctrl = 212649c55878SDavid Wu (struct rockchip_pin_ctrl *)dev_get_driver_data(dev); 212749c55878SDavid Wu struct rockchip_pin_bank *bank; 212849c55878SDavid Wu int grf_offs, pmu_offs, drv_grf_offs, drv_pmu_offs, i, j; 212949c55878SDavid Wu 213049c55878SDavid Wu grf_offs = ctrl->grf_mux_offset; 213149c55878SDavid Wu pmu_offs = ctrl->pmu_mux_offset; 213249c55878SDavid Wu drv_pmu_offs = ctrl->pmu_drv_offset; 213349c55878SDavid Wu drv_grf_offs = ctrl->grf_drv_offset; 213449c55878SDavid Wu bank = ctrl->pin_banks; 213549c55878SDavid Wu 213649c55878SDavid Wu for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { 213749c55878SDavid Wu int bank_pins = 0; 213849c55878SDavid Wu 213949c55878SDavid Wu bank->priv = priv; 214049c55878SDavid Wu bank->pin_base = ctrl->nr_pins; 214149c55878SDavid Wu ctrl->nr_pins += bank->nr_pins; 214249c55878SDavid Wu 214349c55878SDavid Wu /* calculate iomux and drv offsets */ 214449c55878SDavid Wu for (j = 0; j < 4; j++) { 214549c55878SDavid Wu struct rockchip_iomux *iom = &bank->iomux[j]; 214649c55878SDavid Wu struct rockchip_drv *drv = &bank->drv[j]; 214749c55878SDavid Wu int inc; 214849c55878SDavid Wu 214949c55878SDavid Wu if (bank_pins >= bank->nr_pins) 215049c55878SDavid Wu break; 215149c55878SDavid Wu 215249c55878SDavid Wu /* preset iomux offset value, set new start value */ 215349c55878SDavid Wu if (iom->offset >= 0) { 215449c55878SDavid Wu if (iom->type & IOMUX_SOURCE_PMU) 215549c55878SDavid Wu pmu_offs = iom->offset; 215649c55878SDavid Wu else 215749c55878SDavid Wu grf_offs = iom->offset; 215849c55878SDavid Wu } else { /* set current iomux offset */ 215949c55878SDavid Wu iom->offset = (iom->type & IOMUX_SOURCE_PMU) ? 216049c55878SDavid Wu pmu_offs : grf_offs; 216149c55878SDavid Wu } 216249c55878SDavid Wu 216349c55878SDavid Wu /* preset drv offset value, set new start value */ 216449c55878SDavid Wu if (drv->offset >= 0) { 216549c55878SDavid Wu if (iom->type & IOMUX_SOURCE_PMU) 216649c55878SDavid Wu drv_pmu_offs = drv->offset; 216749c55878SDavid Wu else 216849c55878SDavid Wu drv_grf_offs = drv->offset; 216949c55878SDavid Wu } else { /* set current drv offset */ 217049c55878SDavid Wu drv->offset = (iom->type & IOMUX_SOURCE_PMU) ? 217149c55878SDavid Wu drv_pmu_offs : drv_grf_offs; 217249c55878SDavid Wu } 217349c55878SDavid Wu 217449c55878SDavid Wu debug("bank %d, iomux %d has iom_offset 0x%x drv_offset 0x%x\n", 217549c55878SDavid Wu i, j, iom->offset, drv->offset); 217649c55878SDavid Wu 217749c55878SDavid Wu /* 217849c55878SDavid Wu * Increase offset according to iomux width. 217949c55878SDavid Wu * 4bit iomux'es are spread over two registers. 218049c55878SDavid Wu */ 218149c55878SDavid Wu inc = (iom->type & (IOMUX_WIDTH_4BIT | 218288a1f7ffSDavid Wu IOMUX_WIDTH_3BIT | 218388a1f7ffSDavid Wu IOMUX_8WIDTH_2BIT)) ? 8 : 4; 218449c55878SDavid Wu if (iom->type & IOMUX_SOURCE_PMU) 218549c55878SDavid Wu pmu_offs += inc; 218649c55878SDavid Wu else 218749c55878SDavid Wu grf_offs += inc; 218849c55878SDavid Wu 218949c55878SDavid Wu /* 219049c55878SDavid Wu * Increase offset according to drv width. 219149c55878SDavid Wu * 3bit drive-strenth'es are spread over two registers. 219249c55878SDavid Wu */ 219349c55878SDavid Wu if ((drv->drv_type == DRV_TYPE_IO_1V8_3V0_AUTO) || 219449c55878SDavid Wu (drv->drv_type == DRV_TYPE_IO_3V3_ONLY)) 219549c55878SDavid Wu inc = 8; 219649c55878SDavid Wu else 219749c55878SDavid Wu inc = 4; 219849c55878SDavid Wu 219949c55878SDavid Wu if (iom->type & IOMUX_SOURCE_PMU) 220049c55878SDavid Wu drv_pmu_offs += inc; 220149c55878SDavid Wu else 220249c55878SDavid Wu drv_grf_offs += inc; 220349c55878SDavid Wu 220449c55878SDavid Wu bank_pins += 8; 220549c55878SDavid Wu } 220649c55878SDavid Wu 220749c55878SDavid Wu /* calculate the per-bank recalced_mask */ 220849c55878SDavid Wu for (j = 0; j < ctrl->niomux_recalced; j++) { 220949c55878SDavid Wu int pin = 0; 221049c55878SDavid Wu 221149c55878SDavid Wu if (ctrl->iomux_recalced[j].num == bank->bank_num) { 221249c55878SDavid Wu pin = ctrl->iomux_recalced[j].pin; 221349c55878SDavid Wu bank->recalced_mask |= BIT(pin); 221449c55878SDavid Wu } 221549c55878SDavid Wu } 221649c55878SDavid Wu 221749c55878SDavid Wu /* calculate the per-bank route_mask */ 221849c55878SDavid Wu for (j = 0; j < ctrl->niomux_routes; j++) { 221949c55878SDavid Wu int pin = 0; 222049c55878SDavid Wu 222149c55878SDavid Wu if (ctrl->iomux_routes[j].bank_num == bank->bank_num) { 222249c55878SDavid Wu pin = ctrl->iomux_routes[j].pin; 222349c55878SDavid Wu bank->route_mask |= BIT(pin); 222449c55878SDavid Wu } 222549c55878SDavid Wu } 222649c55878SDavid Wu } 222749c55878SDavid Wu 222849c55878SDavid Wu return ctrl; 222949c55878SDavid Wu } 223049c55878SDavid Wu 223149c55878SDavid Wu static int rockchip_pinctrl_probe(struct udevice *dev) 223249c55878SDavid Wu { 223349c55878SDavid Wu struct rockchip_pinctrl_priv *priv = dev_get_priv(dev); 223449c55878SDavid Wu struct rockchip_pin_ctrl *ctrl; 223549c55878SDavid Wu struct udevice *syscon; 223649c55878SDavid Wu struct regmap *regmap; 223749c55878SDavid Wu int ret = 0; 223849c55878SDavid Wu 223949c55878SDavid Wu /* get rockchip grf syscon phandle */ 224049c55878SDavid Wu ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,grf", 224149c55878SDavid Wu &syscon); 224249c55878SDavid Wu if (ret) { 224349c55878SDavid Wu debug("unable to find rockchip,grf syscon device (%d)\n", ret); 224449c55878SDavid Wu return ret; 224549c55878SDavid Wu } 224649c55878SDavid Wu 224749c55878SDavid Wu /* get grf-reg base address */ 224849c55878SDavid Wu regmap = syscon_get_regmap(syscon); 224949c55878SDavid Wu if (!regmap) { 225049c55878SDavid Wu debug("unable to find rockchip grf regmap\n"); 225149c55878SDavid Wu return -ENODEV; 225249c55878SDavid Wu } 225349c55878SDavid Wu priv->regmap_base = regmap; 225449c55878SDavid Wu 225549c55878SDavid Wu /* option: get pmu-reg base address */ 225649c55878SDavid Wu ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,pmu", 225749c55878SDavid Wu &syscon); 225849c55878SDavid Wu if (!ret) { 225949c55878SDavid Wu /* get pmugrf-reg base address */ 226049c55878SDavid Wu regmap = syscon_get_regmap(syscon); 226149c55878SDavid Wu if (!regmap) { 226249c55878SDavid Wu debug("unable to find rockchip pmu regmap\n"); 226349c55878SDavid Wu return -ENODEV; 226449c55878SDavid Wu } 226549c55878SDavid Wu priv->regmap_pmu = regmap; 226649c55878SDavid Wu } 226749c55878SDavid Wu 226849c55878SDavid Wu ctrl = rockchip_pinctrl_get_soc_data(dev); 226949c55878SDavid Wu if (!ctrl) { 227049c55878SDavid Wu debug("driver data not available\n"); 227149c55878SDavid Wu return -EINVAL; 227249c55878SDavid Wu } 227349c55878SDavid Wu 227449c55878SDavid Wu priv->ctrl = ctrl; 227549c55878SDavid Wu return 0; 227649c55878SDavid Wu } 227749c55878SDavid Wu 227849c55878SDavid Wu static struct rockchip_pin_bank px30_pin_banks[] = { 227949c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, 228049c55878SDavid Wu IOMUX_SOURCE_PMU, 228149c55878SDavid Wu IOMUX_SOURCE_PMU, 228249c55878SDavid Wu IOMUX_SOURCE_PMU 228349c55878SDavid Wu ), 228449c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, 228549c55878SDavid Wu IOMUX_WIDTH_4BIT, 228649c55878SDavid Wu IOMUX_WIDTH_4BIT, 228749c55878SDavid Wu IOMUX_WIDTH_4BIT 228849c55878SDavid Wu ), 228949c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, 229049c55878SDavid Wu IOMUX_WIDTH_4BIT, 229149c55878SDavid Wu IOMUX_WIDTH_4BIT, 229249c55878SDavid Wu IOMUX_WIDTH_4BIT 229349c55878SDavid Wu ), 229449c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, 229549c55878SDavid Wu IOMUX_WIDTH_4BIT, 229649c55878SDavid Wu IOMUX_WIDTH_4BIT, 229749c55878SDavid Wu IOMUX_WIDTH_4BIT 229849c55878SDavid Wu ), 229949c55878SDavid Wu }; 230049c55878SDavid Wu 230149c55878SDavid Wu static struct rockchip_pin_ctrl px30_pin_ctrl = { 230249c55878SDavid Wu .pin_banks = px30_pin_banks, 230349c55878SDavid Wu .nr_banks = ARRAY_SIZE(px30_pin_banks), 230449c55878SDavid Wu .label = "PX30-GPIO", 230549c55878SDavid Wu .type = PX30, 230649c55878SDavid Wu .grf_mux_offset = 0x0, 230749c55878SDavid Wu .pmu_mux_offset = 0x0, 230849c55878SDavid Wu .iomux_routes = px30_mux_route_data, 230949c55878SDavid Wu .niomux_routes = ARRAY_SIZE(px30_mux_route_data), 231049c55878SDavid Wu .pull_calc_reg = px30_calc_pull_reg_and_bit, 231149c55878SDavid Wu .drv_calc_reg = px30_calc_drv_reg_and_bit, 231249c55878SDavid Wu .schmitt_calc_reg = px30_calc_schmitt_reg_and_bit, 231349c55878SDavid Wu }; 231449c55878SDavid Wu 231549c55878SDavid Wu static struct rockchip_pin_bank rv1108_pin_banks[] = { 231649c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, 231749c55878SDavid Wu IOMUX_SOURCE_PMU, 231849c55878SDavid Wu IOMUX_SOURCE_PMU, 231949c55878SDavid Wu IOMUX_SOURCE_PMU), 232049c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0), 232149c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, 0), 232249c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, 0), 232349c55878SDavid Wu }; 232449c55878SDavid Wu 232549c55878SDavid Wu static struct rockchip_pin_ctrl rv1108_pin_ctrl = { 232649c55878SDavid Wu .pin_banks = rv1108_pin_banks, 232749c55878SDavid Wu .nr_banks = ARRAY_SIZE(rv1108_pin_banks), 232849c55878SDavid Wu .label = "RV1108-GPIO", 232949c55878SDavid Wu .type = RV1108, 233049c55878SDavid Wu .grf_mux_offset = 0x10, 233149c55878SDavid Wu .pmu_mux_offset = 0x0, 233249c55878SDavid Wu .iomux_recalced = rv1108_mux_recalced_data, 233349c55878SDavid Wu .niomux_recalced = ARRAY_SIZE(rv1108_mux_recalced_data), 233449c55878SDavid Wu .pull_calc_reg = rv1108_calc_pull_reg_and_bit, 233549c55878SDavid Wu .drv_calc_reg = rv1108_calc_drv_reg_and_bit, 233649c55878SDavid Wu .schmitt_calc_reg = rv1108_calc_schmitt_reg_and_bit, 233749c55878SDavid Wu }; 233849c55878SDavid Wu 233949c55878SDavid Wu static struct rockchip_pin_bank rk2928_pin_banks[] = { 234049c55878SDavid Wu PIN_BANK(0, 32, "gpio0"), 234149c55878SDavid Wu PIN_BANK(1, 32, "gpio1"), 234249c55878SDavid Wu PIN_BANK(2, 32, "gpio2"), 234349c55878SDavid Wu PIN_BANK(3, 32, "gpio3"), 234449c55878SDavid Wu }; 234549c55878SDavid Wu 234649c55878SDavid Wu static struct rockchip_pin_ctrl rk2928_pin_ctrl = { 234749c55878SDavid Wu .pin_banks = rk2928_pin_banks, 234849c55878SDavid Wu .nr_banks = ARRAY_SIZE(rk2928_pin_banks), 234949c55878SDavid Wu .label = "RK2928-GPIO", 235049c55878SDavid Wu .type = RK2928, 235149c55878SDavid Wu .grf_mux_offset = 0xa8, 235249c55878SDavid Wu .pull_calc_reg = rk2928_calc_pull_reg_and_bit, 235349c55878SDavid Wu }; 235449c55878SDavid Wu 235549c55878SDavid Wu static struct rockchip_pin_bank rk3036_pin_banks[] = { 235649c55878SDavid Wu PIN_BANK(0, 32, "gpio0"), 235749c55878SDavid Wu PIN_BANK(1, 32, "gpio1"), 235849c55878SDavid Wu PIN_BANK(2, 32, "gpio2"), 235949c55878SDavid Wu }; 236049c55878SDavid Wu 236149c55878SDavid Wu static struct rockchip_pin_ctrl rk3036_pin_ctrl = { 236249c55878SDavid Wu .pin_banks = rk3036_pin_banks, 236349c55878SDavid Wu .nr_banks = ARRAY_SIZE(rk3036_pin_banks), 236449c55878SDavid Wu .label = "RK3036-GPIO", 236549c55878SDavid Wu .type = RK2928, 236649c55878SDavid Wu .grf_mux_offset = 0xa8, 236749c55878SDavid Wu .pull_calc_reg = rk2928_calc_pull_reg_and_bit, 236849c55878SDavid Wu }; 236949c55878SDavid Wu 237049c55878SDavid Wu static struct rockchip_pin_bank rk3066a_pin_banks[] = { 237149c55878SDavid Wu PIN_BANK(0, 32, "gpio0"), 237249c55878SDavid Wu PIN_BANK(1, 32, "gpio1"), 237349c55878SDavid Wu PIN_BANK(2, 32, "gpio2"), 237449c55878SDavid Wu PIN_BANK(3, 32, "gpio3"), 237549c55878SDavid Wu PIN_BANK(4, 32, "gpio4"), 237649c55878SDavid Wu PIN_BANK(6, 16, "gpio6"), 237749c55878SDavid Wu }; 237849c55878SDavid Wu 237949c55878SDavid Wu static struct rockchip_pin_ctrl rk3066a_pin_ctrl = { 238049c55878SDavid Wu .pin_banks = rk3066a_pin_banks, 238149c55878SDavid Wu .nr_banks = ARRAY_SIZE(rk3066a_pin_banks), 238249c55878SDavid Wu .label = "RK3066a-GPIO", 238349c55878SDavid Wu .type = RK2928, 238449c55878SDavid Wu .grf_mux_offset = 0xa8, 238549c55878SDavid Wu .pull_calc_reg = rk2928_calc_pull_reg_and_bit, 238649c55878SDavid Wu }; 238749c55878SDavid Wu 238849c55878SDavid Wu static struct rockchip_pin_bank rk3066b_pin_banks[] = { 238949c55878SDavid Wu PIN_BANK(0, 32, "gpio0"), 239049c55878SDavid Wu PIN_BANK(1, 32, "gpio1"), 239149c55878SDavid Wu PIN_BANK(2, 32, "gpio2"), 239249c55878SDavid Wu PIN_BANK(3, 32, "gpio3"), 239349c55878SDavid Wu }; 239449c55878SDavid Wu 239549c55878SDavid Wu static struct rockchip_pin_ctrl rk3066b_pin_ctrl = { 239649c55878SDavid Wu .pin_banks = rk3066b_pin_banks, 239749c55878SDavid Wu .nr_banks = ARRAY_SIZE(rk3066b_pin_banks), 239849c55878SDavid Wu .label = "RK3066b-GPIO", 239949c55878SDavid Wu .type = RK3066B, 240049c55878SDavid Wu .grf_mux_offset = 0x60, 240149c55878SDavid Wu }; 240249c55878SDavid Wu 240349c55878SDavid Wu static struct rockchip_pin_bank rk3128_pin_banks[] = { 240449c55878SDavid Wu PIN_BANK(0, 32, "gpio0"), 240549c55878SDavid Wu PIN_BANK(1, 32, "gpio1"), 240649c55878SDavid Wu PIN_BANK(2, 32, "gpio2"), 240749c55878SDavid Wu PIN_BANK(3, 32, "gpio3"), 240849c55878SDavid Wu }; 240949c55878SDavid Wu 241049c55878SDavid Wu static struct rockchip_pin_ctrl rk3128_pin_ctrl = { 241149c55878SDavid Wu .pin_banks = rk3128_pin_banks, 241249c55878SDavid Wu .nr_banks = ARRAY_SIZE(rk3128_pin_banks), 241349c55878SDavid Wu .label = "RK3128-GPIO", 241449c55878SDavid Wu .type = RK3128, 241549c55878SDavid Wu .grf_mux_offset = 0xa8, 241649c55878SDavid Wu .iomux_recalced = rk3128_mux_recalced_data, 241749c55878SDavid Wu .niomux_recalced = ARRAY_SIZE(rk3128_mux_recalced_data), 241849c55878SDavid Wu .iomux_routes = rk3128_mux_route_data, 241949c55878SDavid Wu .niomux_routes = ARRAY_SIZE(rk3128_mux_route_data), 242049c55878SDavid Wu .pull_calc_reg = rk3128_calc_pull_reg_and_bit, 242149c55878SDavid Wu }; 242249c55878SDavid Wu 242349c55878SDavid Wu static struct rockchip_pin_bank rk3188_pin_banks[] = { 242449c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_GPIO_ONLY, 0, 0, 0), 242549c55878SDavid Wu PIN_BANK(1, 32, "gpio1"), 242649c55878SDavid Wu PIN_BANK(2, 32, "gpio2"), 242749c55878SDavid Wu PIN_BANK(3, 32, "gpio3"), 242849c55878SDavid Wu }; 242949c55878SDavid Wu 243049c55878SDavid Wu static struct rockchip_pin_ctrl rk3188_pin_ctrl = { 243149c55878SDavid Wu .pin_banks = rk3188_pin_banks, 243249c55878SDavid Wu .nr_banks = ARRAY_SIZE(rk3188_pin_banks), 243349c55878SDavid Wu .label = "RK3188-GPIO", 243449c55878SDavid Wu .type = RK3188, 243549c55878SDavid Wu .grf_mux_offset = 0x60, 243649c55878SDavid Wu .pull_calc_reg = rk3188_calc_pull_reg_and_bit, 243749c55878SDavid Wu }; 243849c55878SDavid Wu 243949c55878SDavid Wu static struct rockchip_pin_bank rk3228_pin_banks[] = { 244049c55878SDavid Wu PIN_BANK(0, 32, "gpio0"), 244149c55878SDavid Wu PIN_BANK(1, 32, "gpio1"), 244249c55878SDavid Wu PIN_BANK(2, 32, "gpio2"), 244349c55878SDavid Wu PIN_BANK(3, 32, "gpio3"), 244449c55878SDavid Wu }; 244549c55878SDavid Wu 244649c55878SDavid Wu static struct rockchip_pin_ctrl rk3228_pin_ctrl = { 244749c55878SDavid Wu .pin_banks = rk3228_pin_banks, 244849c55878SDavid Wu .nr_banks = ARRAY_SIZE(rk3228_pin_banks), 244949c55878SDavid Wu .label = "RK3228-GPIO", 245049c55878SDavid Wu .type = RK3288, 245149c55878SDavid Wu .grf_mux_offset = 0x0, 245249c55878SDavid Wu .iomux_routes = rk3228_mux_route_data, 245349c55878SDavid Wu .niomux_routes = ARRAY_SIZE(rk3228_mux_route_data), 245449c55878SDavid Wu .pull_calc_reg = rk3228_calc_pull_reg_and_bit, 245549c55878SDavid Wu .drv_calc_reg = rk3228_calc_drv_reg_and_bit, 245649c55878SDavid Wu }; 245749c55878SDavid Wu 245849c55878SDavid Wu static struct rockchip_pin_bank rk3288_pin_banks[] = { 2459*55a89bc6SDavid Wu PIN_BANK_IOMUX_DRV_PULL_FLAGS(0, 24, "gpio0", 24604bafc2daSDavid Wu IOMUX_SOURCE_PMU | IOMUX_WRITABLE_32BIT, 24614bafc2daSDavid Wu IOMUX_SOURCE_PMU | IOMUX_WRITABLE_32BIT, 2462*55a89bc6SDavid Wu IOMUX_SOURCE_PMU | IOMUX_WRITABLE_32BIT, 2463*55a89bc6SDavid Wu IOMUX_UNROUTED, 2464*55a89bc6SDavid Wu DRV_TYPE_WRITABLE_32BIT, 2465*55a89bc6SDavid Wu DRV_TYPE_WRITABLE_32BIT, 2466*55a89bc6SDavid Wu DRV_TYPE_WRITABLE_32BIT, 2467*55a89bc6SDavid Wu 0, 2468*55a89bc6SDavid Wu PULL_TYPE_WRITABLE_32BIT, 2469*55a89bc6SDavid Wu PULL_TYPE_WRITABLE_32BIT, 2470*55a89bc6SDavid Wu PULL_TYPE_WRITABLE_32BIT, 2471*55a89bc6SDavid Wu 0 247249c55878SDavid Wu ), 247349c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_UNROUTED, 247449c55878SDavid Wu IOMUX_UNROUTED, 247549c55878SDavid Wu IOMUX_UNROUTED, 247649c55878SDavid Wu 0 247749c55878SDavid Wu ), 247849c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, IOMUX_UNROUTED), 247949c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, IOMUX_WIDTH_4BIT), 248049c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, 248149c55878SDavid Wu IOMUX_WIDTH_4BIT, 248249c55878SDavid Wu 0, 248349c55878SDavid Wu 0 248449c55878SDavid Wu ), 248549c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(5, 32, "gpio5", IOMUX_UNROUTED, 248649c55878SDavid Wu 0, 248749c55878SDavid Wu 0, 248849c55878SDavid Wu IOMUX_UNROUTED 248949c55878SDavid Wu ), 249049c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(6, 32, "gpio6", 0, 0, 0, IOMUX_UNROUTED), 249149c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(7, 32, "gpio7", 0, 249249c55878SDavid Wu 0, 249349c55878SDavid Wu IOMUX_WIDTH_4BIT, 249449c55878SDavid Wu IOMUX_UNROUTED 249549c55878SDavid Wu ), 249649c55878SDavid Wu PIN_BANK(8, 16, "gpio8"), 249749c55878SDavid Wu }; 249849c55878SDavid Wu 249949c55878SDavid Wu static struct rockchip_pin_ctrl rk3288_pin_ctrl = { 250049c55878SDavid Wu .pin_banks = rk3288_pin_banks, 250149c55878SDavid Wu .nr_banks = ARRAY_SIZE(rk3288_pin_banks), 250249c55878SDavid Wu .label = "RK3288-GPIO", 250349c55878SDavid Wu .type = RK3288, 250449c55878SDavid Wu .grf_mux_offset = 0x0, 250549c55878SDavid Wu .pmu_mux_offset = 0x84, 250649c55878SDavid Wu .iomux_routes = rk3288_mux_route_data, 250749c55878SDavid Wu .niomux_routes = ARRAY_SIZE(rk3288_mux_route_data), 250849c55878SDavid Wu .pull_calc_reg = rk3288_calc_pull_reg_and_bit, 250949c55878SDavid Wu .drv_calc_reg = rk3288_calc_drv_reg_and_bit, 251049c55878SDavid Wu }; 251149c55878SDavid Wu 2512b3077611SDavid Wu static struct rockchip_pin_bank rk3308_pin_banks[] = { 2513b3077611SDavid Wu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_8WIDTH_2BIT, 2514b3077611SDavid Wu IOMUX_8WIDTH_2BIT, 2515b3077611SDavid Wu IOMUX_8WIDTH_2BIT, 2516b3077611SDavid Wu IOMUX_8WIDTH_2BIT), 2517b3077611SDavid Wu PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_8WIDTH_2BIT, 2518b3077611SDavid Wu IOMUX_8WIDTH_2BIT, 2519b3077611SDavid Wu IOMUX_8WIDTH_2BIT, 2520b3077611SDavid Wu IOMUX_8WIDTH_2BIT), 2521b3077611SDavid Wu PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_8WIDTH_2BIT, 2522b3077611SDavid Wu IOMUX_8WIDTH_2BIT, 2523b3077611SDavid Wu IOMUX_8WIDTH_2BIT, 2524b3077611SDavid Wu IOMUX_8WIDTH_2BIT), 2525b3077611SDavid Wu PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_8WIDTH_2BIT, 2526b3077611SDavid Wu IOMUX_8WIDTH_2BIT, 2527b3077611SDavid Wu IOMUX_8WIDTH_2BIT, 2528b3077611SDavid Wu IOMUX_8WIDTH_2BIT), 2529b3077611SDavid Wu PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_8WIDTH_2BIT, 2530b3077611SDavid Wu IOMUX_8WIDTH_2BIT, 2531b3077611SDavid Wu IOMUX_8WIDTH_2BIT, 2532b3077611SDavid Wu IOMUX_8WIDTH_2BIT), 2533b3077611SDavid Wu }; 2534b3077611SDavid Wu 2535b3077611SDavid Wu static struct rockchip_pin_ctrl rk3308_pin_ctrl = { 2536b3077611SDavid Wu .pin_banks = rk3308_pin_banks, 2537b3077611SDavid Wu .nr_banks = ARRAY_SIZE(rk3308_pin_banks), 2538b3077611SDavid Wu .label = "RK3308-GPIO", 2539b3077611SDavid Wu .type = RK3308, 2540b3077611SDavid Wu .grf_mux_offset = 0x0, 2541b3077611SDavid Wu .iomux_recalced = rk3308_mux_recalced_data, 2542b3077611SDavid Wu .niomux_recalced = ARRAY_SIZE(rk3308_mux_recalced_data), 2543b3077611SDavid Wu .iomux_routes = rk3308_mux_route_data, 2544b3077611SDavid Wu .niomux_routes = ARRAY_SIZE(rk3308_mux_route_data), 2545b3077611SDavid Wu .pull_calc_reg = rk3308_calc_pull_reg_and_bit, 2546b3077611SDavid Wu .drv_calc_reg = rk3308_calc_drv_reg_and_bit, 2547b3077611SDavid Wu .schmitt_calc_reg = rk3308_calc_schmitt_reg_and_bit, 2548b3077611SDavid Wu }; 2549b3077611SDavid Wu 255049c55878SDavid Wu static struct rockchip_pin_bank rk3328_pin_banks[] = { 255149c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 0, 0, 0, 0), 255249c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0), 255349c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 255449c55878SDavid Wu IOMUX_WIDTH_3BIT, 255549c55878SDavid Wu IOMUX_WIDTH_3BIT, 255649c55878SDavid Wu 0), 255749c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 255849c55878SDavid Wu IOMUX_WIDTH_3BIT, 255949c55878SDavid Wu IOMUX_WIDTH_3BIT, 256049c55878SDavid Wu 0, 256149c55878SDavid Wu 0), 256249c55878SDavid Wu }; 256349c55878SDavid Wu 256449c55878SDavid Wu static struct rockchip_pin_ctrl rk3328_pin_ctrl = { 256549c55878SDavid Wu .pin_banks = rk3328_pin_banks, 256649c55878SDavid Wu .nr_banks = ARRAY_SIZE(rk3328_pin_banks), 256749c55878SDavid Wu .label = "RK3328-GPIO", 256849c55878SDavid Wu .type = RK3288, 256949c55878SDavid Wu .grf_mux_offset = 0x0, 257049c55878SDavid Wu .iomux_recalced = rk3328_mux_recalced_data, 257149c55878SDavid Wu .niomux_recalced = ARRAY_SIZE(rk3328_mux_recalced_data), 257249c55878SDavid Wu .iomux_routes = rk3328_mux_route_data, 257349c55878SDavid Wu .niomux_routes = ARRAY_SIZE(rk3328_mux_route_data), 257449c55878SDavid Wu .pull_calc_reg = rk3228_calc_pull_reg_and_bit, 257549c55878SDavid Wu .drv_calc_reg = rk3228_calc_drv_reg_and_bit, 257649c55878SDavid Wu .schmitt_calc_reg = rk3328_calc_schmitt_reg_and_bit, 257749c55878SDavid Wu }; 257849c55878SDavid Wu 257949c55878SDavid Wu static struct rockchip_pin_bank rk3368_pin_banks[] = { 258049c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, 258149c55878SDavid Wu IOMUX_SOURCE_PMU, 258249c55878SDavid Wu IOMUX_SOURCE_PMU, 258349c55878SDavid Wu IOMUX_SOURCE_PMU 258449c55878SDavid Wu ), 258549c55878SDavid Wu PIN_BANK(1, 32, "gpio1"), 258649c55878SDavid Wu PIN_BANK(2, 32, "gpio2"), 258749c55878SDavid Wu PIN_BANK(3, 32, "gpio3"), 258849c55878SDavid Wu }; 258949c55878SDavid Wu 259049c55878SDavid Wu static struct rockchip_pin_ctrl rk3368_pin_ctrl = { 259149c55878SDavid Wu .pin_banks = rk3368_pin_banks, 259249c55878SDavid Wu .nr_banks = ARRAY_SIZE(rk3368_pin_banks), 259349c55878SDavid Wu .label = "RK3368-GPIO", 259449c55878SDavid Wu .type = RK3368, 259549c55878SDavid Wu .grf_mux_offset = 0x0, 259649c55878SDavid Wu .pmu_mux_offset = 0x0, 259749c55878SDavid Wu .pull_calc_reg = rk3368_calc_pull_reg_and_bit, 259849c55878SDavid Wu .drv_calc_reg = rk3368_calc_drv_reg_and_bit, 259949c55878SDavid Wu }; 260049c55878SDavid Wu 260149c55878SDavid Wu static struct rockchip_pin_bank rk3399_pin_banks[] = { 260249c55878SDavid Wu PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(0, 32, "gpio0", 260349c55878SDavid Wu IOMUX_SOURCE_PMU, 260449c55878SDavid Wu IOMUX_SOURCE_PMU, 260549c55878SDavid Wu IOMUX_SOURCE_PMU, 260649c55878SDavid Wu IOMUX_SOURCE_PMU, 260749c55878SDavid Wu DRV_TYPE_IO_1V8_ONLY, 260849c55878SDavid Wu DRV_TYPE_IO_1V8_ONLY, 260949c55878SDavid Wu DRV_TYPE_IO_DEFAULT, 261049c55878SDavid Wu DRV_TYPE_IO_DEFAULT, 261149c55878SDavid Wu 0x80, 261249c55878SDavid Wu 0x88, 261349c55878SDavid Wu -1, 261449c55878SDavid Wu -1, 261549c55878SDavid Wu PULL_TYPE_IO_1V8_ONLY, 261649c55878SDavid Wu PULL_TYPE_IO_1V8_ONLY, 261749c55878SDavid Wu PULL_TYPE_IO_DEFAULT, 261849c55878SDavid Wu PULL_TYPE_IO_DEFAULT 261949c55878SDavid Wu ), 262049c55878SDavid Wu PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(1, 32, "gpio1", IOMUX_SOURCE_PMU, 262149c55878SDavid Wu IOMUX_SOURCE_PMU, 262249c55878SDavid Wu IOMUX_SOURCE_PMU, 262349c55878SDavid Wu IOMUX_SOURCE_PMU, 262449c55878SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 262549c55878SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 262649c55878SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 262749c55878SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 262849c55878SDavid Wu 0xa0, 262949c55878SDavid Wu 0xa8, 263049c55878SDavid Wu 0xb0, 263149c55878SDavid Wu 0xb8 263249c55878SDavid Wu ), 263349c55878SDavid Wu PIN_BANK_DRV_FLAGS_PULL_FLAGS(2, 32, "gpio2", DRV_TYPE_IO_1V8_OR_3V0, 263449c55878SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 263549c55878SDavid Wu DRV_TYPE_IO_1V8_ONLY, 263649c55878SDavid Wu DRV_TYPE_IO_1V8_ONLY, 263749c55878SDavid Wu PULL_TYPE_IO_DEFAULT, 263849c55878SDavid Wu PULL_TYPE_IO_DEFAULT, 263949c55878SDavid Wu PULL_TYPE_IO_1V8_ONLY, 264049c55878SDavid Wu PULL_TYPE_IO_1V8_ONLY 264149c55878SDavid Wu ), 264249c55878SDavid Wu PIN_BANK_DRV_FLAGS(3, 32, "gpio3", DRV_TYPE_IO_3V3_ONLY, 264349c55878SDavid Wu DRV_TYPE_IO_3V3_ONLY, 264449c55878SDavid Wu DRV_TYPE_IO_3V3_ONLY, 264549c55878SDavid Wu DRV_TYPE_IO_1V8_OR_3V0 264649c55878SDavid Wu ), 264749c55878SDavid Wu PIN_BANK_DRV_FLAGS(4, 32, "gpio4", DRV_TYPE_IO_1V8_OR_3V0, 264849c55878SDavid Wu DRV_TYPE_IO_1V8_3V0_AUTO, 264949c55878SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 265049c55878SDavid Wu DRV_TYPE_IO_1V8_OR_3V0 265149c55878SDavid Wu ), 265249c55878SDavid Wu }; 265349c55878SDavid Wu 265449c55878SDavid Wu static struct rockchip_pin_ctrl rk3399_pin_ctrl = { 265549c55878SDavid Wu .pin_banks = rk3399_pin_banks, 265649c55878SDavid Wu .nr_banks = ARRAY_SIZE(rk3399_pin_banks), 265749c55878SDavid Wu .label = "RK3399-GPIO", 265849c55878SDavid Wu .type = RK3399, 265949c55878SDavid Wu .grf_mux_offset = 0xe000, 266049c55878SDavid Wu .pmu_mux_offset = 0x0, 266149c55878SDavid Wu .grf_drv_offset = 0xe100, 266249c55878SDavid Wu .pmu_drv_offset = 0x80, 266349c55878SDavid Wu .iomux_routes = rk3399_mux_route_data, 266449c55878SDavid Wu .niomux_routes = ARRAY_SIZE(rk3399_mux_route_data), 266549c55878SDavid Wu .pull_calc_reg = rk3399_calc_pull_reg_and_bit, 266649c55878SDavid Wu .drv_calc_reg = rk3399_calc_drv_reg_and_bit, 266749c55878SDavid Wu }; 266849c55878SDavid Wu 266949c55878SDavid Wu static const struct udevice_id rockchip_pinctrl_dt_match[] = { 267049c55878SDavid Wu { .compatible = "rockchip,px30-pinctrl", 267149c55878SDavid Wu .data = (ulong)&px30_pin_ctrl }, 267249c55878SDavid Wu { .compatible = "rockchip,rv1108-pinctrl", 267349c55878SDavid Wu .data = (ulong)&rv1108_pin_ctrl }, 267449c55878SDavid Wu { .compatible = "rockchip,rk2928-pinctrl", 267549c55878SDavid Wu .data = (ulong)&rk2928_pin_ctrl }, 267649c55878SDavid Wu { .compatible = "rockchip,rk3036-pinctrl", 267749c55878SDavid Wu .data = (ulong)&rk3036_pin_ctrl }, 267849c55878SDavid Wu { .compatible = "rockchip,rk3066a-pinctrl", 267949c55878SDavid Wu .data = (ulong)&rk3066a_pin_ctrl }, 268049c55878SDavid Wu { .compatible = "rockchip,rk3066b-pinctrl", 268149c55878SDavid Wu .data = (ulong)&rk3066b_pin_ctrl }, 268249c55878SDavid Wu { .compatible = "rockchip,rk3128-pinctrl", 268349c55878SDavid Wu .data = (ulong)&rk3128_pin_ctrl }, 268449c55878SDavid Wu { .compatible = "rockchip,rk3188-pinctrl", 268549c55878SDavid Wu .data = (ulong)&rk3188_pin_ctrl }, 268649c55878SDavid Wu { .compatible = "rockchip,rk3228-pinctrl", 268749c55878SDavid Wu .data = (ulong)&rk3228_pin_ctrl }, 268849c55878SDavid Wu { .compatible = "rockchip,rk3288-pinctrl", 268949c55878SDavid Wu .data = (ulong)&rk3288_pin_ctrl }, 2690b3077611SDavid Wu { .compatible = "rockchip,rk3308-pinctrl", 2691b3077611SDavid Wu .data = (ulong)&rk3308_pin_ctrl }, 269249c55878SDavid Wu { .compatible = "rockchip,rk3328-pinctrl", 269349c55878SDavid Wu .data = (ulong)&rk3328_pin_ctrl }, 269449c55878SDavid Wu { .compatible = "rockchip,rk3368-pinctrl", 269549c55878SDavid Wu .data = (ulong)&rk3368_pin_ctrl }, 269649c55878SDavid Wu { .compatible = "rockchip,rk3399-pinctrl", 269749c55878SDavid Wu .data = (ulong)&rk3399_pin_ctrl }, 269849c55878SDavid Wu {}, 269949c55878SDavid Wu }; 270049c55878SDavid Wu 270149c55878SDavid Wu U_BOOT_DRIVER(pinctrl_rockchip) = { 270249c55878SDavid Wu .name = "rockchip_pinctrl", 270349c55878SDavid Wu .id = UCLASS_PINCTRL, 270449c55878SDavid Wu .of_match = rockchip_pinctrl_dt_match, 270549c55878SDavid Wu .priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv), 270649c55878SDavid Wu .ops = &rockchip_pinctrl_ops, 270749c55878SDavid Wu #if !CONFIG_IS_ENABLED(OF_PLATDATA) 270849c55878SDavid Wu .bind = dm_scan_fdt_dev, 270949c55878SDavid Wu #endif 271049c55878SDavid Wu .probe = rockchip_pinctrl_probe, 271149c55878SDavid Wu }; 2712