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) 4049c55878SDavid Wu 4149c55878SDavid Wu /** 4249c55878SDavid Wu * @type: iomux variant using IOMUX_* constants 4349c55878SDavid Wu * @offset: if initialized to -1 it will be autocalculated, by specifying 4449c55878SDavid Wu * an initial offset value the relevant source offset can be reset 4549c55878SDavid Wu * to a new value for autocalculating the following iomux registers. 4649c55878SDavid Wu */ 4749c55878SDavid Wu struct rockchip_iomux { 4849c55878SDavid Wu int type; 4949c55878SDavid Wu int offset; 5049c55878SDavid Wu }; 5149c55878SDavid Wu 5249c55878SDavid Wu /** 5349c55878SDavid Wu * enum type index corresponding to rockchip_perpin_drv_list arrays index. 5449c55878SDavid Wu */ 5549c55878SDavid Wu enum rockchip_pin_drv_type { 5649c55878SDavid Wu DRV_TYPE_IO_DEFAULT = 0, 5749c55878SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 5849c55878SDavid Wu DRV_TYPE_IO_1V8_ONLY, 5949c55878SDavid Wu DRV_TYPE_IO_1V8_3V0_AUTO, 6049c55878SDavid Wu DRV_TYPE_IO_3V3_ONLY, 6149c55878SDavid Wu DRV_TYPE_MAX 6249c55878SDavid Wu }; 6349c55878SDavid Wu 6449c55878SDavid Wu /** 6549c55878SDavid Wu * enum type index corresponding to rockchip_pull_list arrays index. 6649c55878SDavid Wu */ 6749c55878SDavid Wu enum rockchip_pin_pull_type { 6849c55878SDavid Wu PULL_TYPE_IO_DEFAULT = 0, 6949c55878SDavid Wu PULL_TYPE_IO_1V8_ONLY, 7049c55878SDavid Wu PULL_TYPE_MAX 7149c55878SDavid Wu }; 7249c55878SDavid Wu 7349c55878SDavid Wu /** 7449c55878SDavid Wu * @drv_type: drive strength variant using rockchip_perpin_drv_type 7549c55878SDavid Wu * @offset: if initialized to -1 it will be autocalculated, by specifying 7649c55878SDavid Wu * an initial offset value the relevant source offset can be reset 7749c55878SDavid Wu * to a new value for autocalculating the following drive strength 7849c55878SDavid Wu * registers. if used chips own cal_drv func instead to calculate 7949c55878SDavid Wu * registers offset, the variant could be ignored. 8049c55878SDavid Wu */ 8149c55878SDavid Wu struct rockchip_drv { 8249c55878SDavid Wu enum rockchip_pin_drv_type drv_type; 8349c55878SDavid Wu int offset; 8449c55878SDavid Wu }; 8549c55878SDavid Wu 8649c55878SDavid Wu /** 8749c55878SDavid Wu * @priv: common pinctrl private basedata 8849c55878SDavid Wu * @pin_base: first pin number 8949c55878SDavid Wu * @nr_pins: number of pins in this bank 9049c55878SDavid Wu * @name: name of the bank 9149c55878SDavid Wu * @bank_num: number of the bank, to account for holes 9249c55878SDavid Wu * @iomux: array describing the 4 iomux sources of the bank 9349c55878SDavid Wu * @drv: array describing the 4 drive strength sources of the bank 9449c55878SDavid Wu * @pull_type: array describing the 4 pull type sources of the bank 9549c55878SDavid Wu * @recalced_mask: bits describing the mux recalced pins of per bank 9649c55878SDavid Wu * @route_mask: bits describing the routing pins of per bank 9749c55878SDavid Wu */ 9849c55878SDavid Wu struct rockchip_pin_bank { 9949c55878SDavid Wu struct rockchip_pinctrl_priv *priv; 10049c55878SDavid Wu u32 pin_base; 10149c55878SDavid Wu u8 nr_pins; 10249c55878SDavid Wu char *name; 10349c55878SDavid Wu u8 bank_num; 10449c55878SDavid Wu struct rockchip_iomux iomux[4]; 10549c55878SDavid Wu struct rockchip_drv drv[4]; 10649c55878SDavid Wu enum rockchip_pin_pull_type pull_type[4]; 10749c55878SDavid Wu u32 recalced_mask; 10849c55878SDavid Wu u32 route_mask; 10949c55878SDavid Wu }; 11049c55878SDavid Wu 11149c55878SDavid Wu #define PIN_BANK(id, pins, label) \ 11249c55878SDavid Wu { \ 11349c55878SDavid Wu .bank_num = id, \ 11449c55878SDavid Wu .nr_pins = pins, \ 11549c55878SDavid Wu .name = label, \ 11649c55878SDavid Wu .iomux = { \ 11749c55878SDavid Wu { .offset = -1 }, \ 11849c55878SDavid Wu { .offset = -1 }, \ 11949c55878SDavid Wu { .offset = -1 }, \ 12049c55878SDavid Wu { .offset = -1 }, \ 12149c55878SDavid Wu }, \ 12249c55878SDavid Wu } 12349c55878SDavid Wu 12449c55878SDavid Wu #define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3) \ 12549c55878SDavid Wu { \ 12649c55878SDavid Wu .bank_num = id, \ 12749c55878SDavid Wu .nr_pins = pins, \ 12849c55878SDavid Wu .name = label, \ 12949c55878SDavid Wu .iomux = { \ 13049c55878SDavid Wu { .type = iom0, .offset = -1 }, \ 13149c55878SDavid Wu { .type = iom1, .offset = -1 }, \ 13249c55878SDavid Wu { .type = iom2, .offset = -1 }, \ 13349c55878SDavid Wu { .type = iom3, .offset = -1 }, \ 13449c55878SDavid Wu }, \ 13549c55878SDavid Wu } 13649c55878SDavid Wu 13749c55878SDavid Wu #define PIN_BANK_DRV_FLAGS(id, pins, label, type0, type1, type2, type3) \ 13849c55878SDavid Wu { \ 13949c55878SDavid Wu .bank_num = id, \ 14049c55878SDavid Wu .nr_pins = pins, \ 14149c55878SDavid Wu .name = label, \ 14249c55878SDavid Wu .iomux = { \ 14349c55878SDavid Wu { .offset = -1 }, \ 14449c55878SDavid Wu { .offset = -1 }, \ 14549c55878SDavid Wu { .offset = -1 }, \ 14649c55878SDavid Wu { .offset = -1 }, \ 14749c55878SDavid Wu }, \ 14849c55878SDavid Wu .drv = { \ 14949c55878SDavid Wu { .drv_type = type0, .offset = -1 }, \ 15049c55878SDavid Wu { .drv_type = type1, .offset = -1 }, \ 15149c55878SDavid Wu { .drv_type = type2, .offset = -1 }, \ 15249c55878SDavid Wu { .drv_type = type3, .offset = -1 }, \ 15349c55878SDavid Wu }, \ 15449c55878SDavid Wu } 15549c55878SDavid Wu 15649c55878SDavid Wu #define PIN_BANK_DRV_FLAGS_PULL_FLAGS(id, pins, label, drv0, drv1, \ 15749c55878SDavid Wu drv2, drv3, pull0, pull1, \ 15849c55878SDavid Wu pull2, pull3) \ 15949c55878SDavid Wu { \ 16049c55878SDavid Wu .bank_num = id, \ 16149c55878SDavid Wu .nr_pins = pins, \ 16249c55878SDavid Wu .name = label, \ 16349c55878SDavid Wu .iomux = { \ 16449c55878SDavid Wu { .offset = -1 }, \ 16549c55878SDavid Wu { .offset = -1 }, \ 16649c55878SDavid Wu { .offset = -1 }, \ 16749c55878SDavid Wu { .offset = -1 }, \ 16849c55878SDavid Wu }, \ 16949c55878SDavid Wu .drv = { \ 17049c55878SDavid Wu { .drv_type = drv0, .offset = -1 }, \ 17149c55878SDavid Wu { .drv_type = drv1, .offset = -1 }, \ 17249c55878SDavid Wu { .drv_type = drv2, .offset = -1 }, \ 17349c55878SDavid Wu { .drv_type = drv3, .offset = -1 }, \ 17449c55878SDavid Wu }, \ 17549c55878SDavid Wu .pull_type[0] = pull0, \ 17649c55878SDavid Wu .pull_type[1] = pull1, \ 17749c55878SDavid Wu .pull_type[2] = pull2, \ 17849c55878SDavid Wu .pull_type[3] = pull3, \ 17949c55878SDavid Wu } 18049c55878SDavid Wu 18149c55878SDavid Wu #define PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(id, pins, label, iom0, iom1, \ 18249c55878SDavid Wu iom2, iom3, drv0, drv1, drv2, \ 18349c55878SDavid Wu drv3, offset0, offset1, \ 18449c55878SDavid Wu offset2, offset3) \ 18549c55878SDavid Wu { \ 18649c55878SDavid Wu .bank_num = id, \ 18749c55878SDavid Wu .nr_pins = pins, \ 18849c55878SDavid Wu .name = label, \ 18949c55878SDavid Wu .iomux = { \ 19049c55878SDavid Wu { .type = iom0, .offset = -1 }, \ 19149c55878SDavid Wu { .type = iom1, .offset = -1 }, \ 19249c55878SDavid Wu { .type = iom2, .offset = -1 }, \ 19349c55878SDavid Wu { .type = iom3, .offset = -1 }, \ 19449c55878SDavid Wu }, \ 19549c55878SDavid Wu .drv = { \ 19649c55878SDavid Wu { .drv_type = drv0, .offset = offset0 }, \ 19749c55878SDavid Wu { .drv_type = drv1, .offset = offset1 }, \ 19849c55878SDavid Wu { .drv_type = drv2, .offset = offset2 }, \ 19949c55878SDavid Wu { .drv_type = drv3, .offset = offset3 }, \ 20049c55878SDavid Wu }, \ 20149c55878SDavid Wu } 20249c55878SDavid Wu 20349c55878SDavid Wu #define PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(id, pins, \ 20449c55878SDavid Wu label, iom0, iom1, iom2, \ 20549c55878SDavid Wu iom3, drv0, drv1, drv2, \ 20649c55878SDavid Wu drv3, offset0, offset1, \ 20749c55878SDavid Wu offset2, offset3, pull0, \ 20849c55878SDavid Wu pull1, pull2, pull3) \ 20949c55878SDavid Wu { \ 21049c55878SDavid Wu .bank_num = id, \ 21149c55878SDavid Wu .nr_pins = pins, \ 21249c55878SDavid Wu .name = label, \ 21349c55878SDavid Wu .iomux = { \ 21449c55878SDavid Wu { .type = iom0, .offset = -1 }, \ 21549c55878SDavid Wu { .type = iom1, .offset = -1 }, \ 21649c55878SDavid Wu { .type = iom2, .offset = -1 }, \ 21749c55878SDavid Wu { .type = iom3, .offset = -1 }, \ 21849c55878SDavid Wu }, \ 21949c55878SDavid Wu .drv = { \ 22049c55878SDavid Wu { .drv_type = drv0, .offset = offset0 }, \ 22149c55878SDavid Wu { .drv_type = drv1, .offset = offset1 }, \ 22249c55878SDavid Wu { .drv_type = drv2, .offset = offset2 }, \ 22349c55878SDavid Wu { .drv_type = drv3, .offset = offset3 }, \ 22449c55878SDavid Wu }, \ 22549c55878SDavid Wu .pull_type[0] = pull0, \ 22649c55878SDavid Wu .pull_type[1] = pull1, \ 22749c55878SDavid Wu .pull_type[2] = pull2, \ 22849c55878SDavid Wu .pull_type[3] = pull3, \ 22949c55878SDavid Wu } 23049c55878SDavid Wu 23149c55878SDavid Wu /** 23249c55878SDavid Wu * struct rockchip_mux_recalced_data: represent a pin iomux data. 23349c55878SDavid Wu * @num: bank number. 23449c55878SDavid Wu * @pin: pin number. 23549c55878SDavid Wu * @bit: index at register. 23649c55878SDavid Wu * @reg: register offset. 23749c55878SDavid Wu * @mask: mask bit 23849c55878SDavid Wu */ 23949c55878SDavid Wu struct rockchip_mux_recalced_data { 24049c55878SDavid Wu u8 num; 24149c55878SDavid Wu u8 pin; 24249c55878SDavid Wu u32 reg; 24349c55878SDavid Wu u8 bit; 24449c55878SDavid Wu u8 mask; 24549c55878SDavid Wu }; 24649c55878SDavid Wu 24749c55878SDavid Wu /** 24849c55878SDavid Wu * struct rockchip_mux_recalced_data: represent a pin iomux data. 24949c55878SDavid Wu * @bank_num: bank number. 25049c55878SDavid Wu * @pin: index at register or used to calc index. 25149c55878SDavid Wu * @func: the min pin. 25249c55878SDavid Wu * @route_offset: the max pin. 25349c55878SDavid Wu * @route_val: the register offset. 25449c55878SDavid Wu */ 25549c55878SDavid Wu struct rockchip_mux_route_data { 25649c55878SDavid Wu u8 bank_num; 25749c55878SDavid Wu u8 pin; 25849c55878SDavid Wu u8 func; 25949c55878SDavid Wu u32 route_offset; 26049c55878SDavid Wu u32 route_val; 26149c55878SDavid Wu }; 26249c55878SDavid Wu 26349c55878SDavid Wu /** 26449c55878SDavid Wu */ 26549c55878SDavid Wu struct rockchip_pin_ctrl { 26649c55878SDavid Wu struct rockchip_pin_bank *pin_banks; 26749c55878SDavid Wu u32 nr_banks; 26849c55878SDavid Wu u32 nr_pins; 26949c55878SDavid Wu char *label; 27049c55878SDavid Wu enum rockchip_pinctrl_type type; 27149c55878SDavid Wu int grf_mux_offset; 27249c55878SDavid Wu int pmu_mux_offset; 27349c55878SDavid Wu int grf_drv_offset; 27449c55878SDavid Wu int pmu_drv_offset; 27549c55878SDavid Wu struct rockchip_mux_recalced_data *iomux_recalced; 27649c55878SDavid Wu u32 niomux_recalced; 27749c55878SDavid Wu struct rockchip_mux_route_data *iomux_routes; 27849c55878SDavid Wu u32 niomux_routes; 27949c55878SDavid Wu 28049c55878SDavid Wu void (*pull_calc_reg)(struct rockchip_pin_bank *bank, 28149c55878SDavid Wu int pin_num, struct regmap **regmap, 28249c55878SDavid Wu int *reg, u8 *bit); 28349c55878SDavid Wu void (*drv_calc_reg)(struct rockchip_pin_bank *bank, 28449c55878SDavid Wu int pin_num, struct regmap **regmap, 28549c55878SDavid Wu int *reg, u8 *bit); 28649c55878SDavid Wu int (*schmitt_calc_reg)(struct rockchip_pin_bank *bank, 28749c55878SDavid Wu int pin_num, struct regmap **regmap, 28849c55878SDavid Wu int *reg, u8 *bit); 28949c55878SDavid Wu }; 29049c55878SDavid Wu 29149c55878SDavid Wu /** 29249c55878SDavid Wu */ 29349c55878SDavid Wu struct rockchip_pinctrl_priv { 29449c55878SDavid Wu struct rockchip_pin_ctrl *ctrl; 29549c55878SDavid Wu struct regmap *regmap_base; 29649c55878SDavid Wu struct regmap *regmap_pmu; 29749c55878SDavid Wu 29849c55878SDavid Wu }; 29949c55878SDavid Wu 30049c55878SDavid Wu static int rockchip_verify_config(struct udevice *dev, u32 bank, u32 pin) 30149c55878SDavid Wu { 30249c55878SDavid Wu struct rockchip_pinctrl_priv *priv = dev_get_priv(dev); 30349c55878SDavid Wu struct rockchip_pin_ctrl *ctrl = priv->ctrl; 30449c55878SDavid Wu 30549c55878SDavid Wu if (bank >= ctrl->nr_banks) { 30649c55878SDavid Wu debug("pin conf bank %d >= nbanks %d\n", bank, ctrl->nr_banks); 30749c55878SDavid Wu return -EINVAL; 30849c55878SDavid Wu } 30949c55878SDavid Wu 31049c55878SDavid Wu if (pin >= MAX_ROCKCHIP_GPIO_PER_BANK) { 31149c55878SDavid Wu debug("pin conf pin %d >= %d\n", pin, 31249c55878SDavid Wu MAX_ROCKCHIP_GPIO_PER_BANK); 31349c55878SDavid Wu return -EINVAL; 31449c55878SDavid Wu } 31549c55878SDavid Wu 31649c55878SDavid Wu return 0; 31749c55878SDavid Wu } 31849c55878SDavid Wu 31949c55878SDavid Wu static struct rockchip_mux_recalced_data rv1108_mux_recalced_data[] = { 32049c55878SDavid Wu { 32149c55878SDavid Wu .num = 1, 32249c55878SDavid Wu .pin = 0, 32349c55878SDavid Wu .reg = 0x418, 32449c55878SDavid Wu .bit = 0, 32549c55878SDavid Wu .mask = 0x3 32649c55878SDavid Wu }, { 32749c55878SDavid Wu .num = 1, 32849c55878SDavid Wu .pin = 1, 32949c55878SDavid Wu .reg = 0x418, 33049c55878SDavid Wu .bit = 2, 33149c55878SDavid Wu .mask = 0x3 33249c55878SDavid Wu }, { 33349c55878SDavid Wu .num = 1, 33449c55878SDavid Wu .pin = 2, 33549c55878SDavid Wu .reg = 0x418, 33649c55878SDavid Wu .bit = 4, 33749c55878SDavid Wu .mask = 0x3 33849c55878SDavid Wu }, { 33949c55878SDavid Wu .num = 1, 34049c55878SDavid Wu .pin = 3, 34149c55878SDavid Wu .reg = 0x418, 34249c55878SDavid Wu .bit = 6, 34349c55878SDavid Wu .mask = 0x3 34449c55878SDavid Wu }, { 34549c55878SDavid Wu .num = 1, 34649c55878SDavid Wu .pin = 4, 34749c55878SDavid Wu .reg = 0x418, 34849c55878SDavid Wu .bit = 8, 34949c55878SDavid Wu .mask = 0x3 35049c55878SDavid Wu }, { 35149c55878SDavid Wu .num = 1, 35249c55878SDavid Wu .pin = 5, 35349c55878SDavid Wu .reg = 0x418, 35449c55878SDavid Wu .bit = 10, 35549c55878SDavid Wu .mask = 0x3 35649c55878SDavid Wu }, { 35749c55878SDavid Wu .num = 1, 35849c55878SDavid Wu .pin = 6, 35949c55878SDavid Wu .reg = 0x418, 36049c55878SDavid Wu .bit = 12, 36149c55878SDavid Wu .mask = 0x3 36249c55878SDavid Wu }, { 36349c55878SDavid Wu .num = 1, 36449c55878SDavid Wu .pin = 7, 36549c55878SDavid Wu .reg = 0x418, 36649c55878SDavid Wu .bit = 14, 36749c55878SDavid Wu .mask = 0x3 36849c55878SDavid Wu }, { 36949c55878SDavid Wu .num = 1, 37049c55878SDavid Wu .pin = 8, 37149c55878SDavid Wu .reg = 0x41c, 37249c55878SDavid Wu .bit = 0, 37349c55878SDavid Wu .mask = 0x3 37449c55878SDavid Wu }, { 37549c55878SDavid Wu .num = 1, 37649c55878SDavid Wu .pin = 9, 37749c55878SDavid Wu .reg = 0x41c, 37849c55878SDavid Wu .bit = 2, 37949c55878SDavid Wu .mask = 0x3 38049c55878SDavid Wu }, 38149c55878SDavid Wu }; 38249c55878SDavid Wu 38349c55878SDavid Wu static struct rockchip_mux_recalced_data rk3128_mux_recalced_data[] = { 38449c55878SDavid Wu { 38549c55878SDavid Wu .num = 2, 38649c55878SDavid Wu .pin = 20, 38749c55878SDavid Wu .reg = 0xe8, 38849c55878SDavid Wu .bit = 0, 38949c55878SDavid Wu .mask = 0x7 39049c55878SDavid Wu }, { 39149c55878SDavid Wu .num = 2, 39249c55878SDavid Wu .pin = 21, 39349c55878SDavid Wu .reg = 0xe8, 39449c55878SDavid Wu .bit = 4, 39549c55878SDavid Wu .mask = 0x7 39649c55878SDavid Wu }, { 39749c55878SDavid Wu .num = 2, 39849c55878SDavid Wu .pin = 22, 39949c55878SDavid Wu .reg = 0xe8, 40049c55878SDavid Wu .bit = 8, 40149c55878SDavid Wu .mask = 0x7 40249c55878SDavid Wu }, { 40349c55878SDavid Wu .num = 2, 40449c55878SDavid Wu .pin = 23, 40549c55878SDavid Wu .reg = 0xe8, 40649c55878SDavid Wu .bit = 12, 40749c55878SDavid Wu .mask = 0x7 40849c55878SDavid Wu }, { 40949c55878SDavid Wu .num = 2, 41049c55878SDavid Wu .pin = 24, 41149c55878SDavid Wu .reg = 0xd4, 41249c55878SDavid Wu .bit = 12, 41349c55878SDavid Wu .mask = 0x7 41449c55878SDavid Wu }, 41549c55878SDavid Wu }; 41649c55878SDavid Wu 417b3077611SDavid Wu static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = { 418b3077611SDavid Wu { 419b3077611SDavid Wu .num = 1, 420b3077611SDavid Wu .pin = 14, 421b3077611SDavid Wu .reg = 0x28, 422b3077611SDavid Wu .bit = 12, 423b3077611SDavid Wu .mask = 0x7 424b3077611SDavid Wu }, { 425b3077611SDavid Wu .num = 1, 426b3077611SDavid Wu .pin = 15, 427b3077611SDavid Wu .reg = 0x2c, 428b3077611SDavid Wu .bit = 0, 429b3077611SDavid Wu .mask = 0x3 430b3077611SDavid Wu }, { 431b3077611SDavid Wu .num = 1, 432b3077611SDavid Wu .pin = 18, 433b3077611SDavid Wu .reg = 0x30, 434b3077611SDavid Wu .bit = 4, 435b3077611SDavid Wu .mask = 0x7 436b3077611SDavid Wu }, { 437b3077611SDavid Wu .num = 1, 438b3077611SDavid Wu .pin = 19, 439b3077611SDavid Wu .reg = 0x30, 440b3077611SDavid Wu .bit = 8, 441b3077611SDavid Wu .mask = 0x7 442b3077611SDavid Wu }, { 443b3077611SDavid Wu .num = 1, 444b3077611SDavid Wu .pin = 20, 445b3077611SDavid Wu .reg = 0x30, 446b3077611SDavid Wu .bit = 12, 447b3077611SDavid Wu .mask = 0x7 448b3077611SDavid Wu }, { 449b3077611SDavid Wu .num = 1, 450b3077611SDavid Wu .pin = 21, 451b3077611SDavid Wu .reg = 0x34, 452b3077611SDavid Wu .bit = 0, 453b3077611SDavid Wu .mask = 0x7 454b3077611SDavid Wu }, { 455b3077611SDavid Wu .num = 1, 456b3077611SDavid Wu .pin = 22, 457b3077611SDavid Wu .reg = 0x34, 458b3077611SDavid Wu .bit = 4, 459b3077611SDavid Wu .mask = 0x7 460b3077611SDavid Wu }, { 461b3077611SDavid Wu .num = 1, 462b3077611SDavid Wu .pin = 23, 463b3077611SDavid Wu .reg = 0x34, 464b3077611SDavid Wu .bit = 8, 465b3077611SDavid Wu .mask = 0x7 466b3077611SDavid Wu }, { 467b3077611SDavid Wu .num = 3, 468b3077611SDavid Wu .pin = 12, 469b3077611SDavid Wu .reg = 0x68, 470b3077611SDavid Wu .bit = 8, 471b3077611SDavid Wu .mask = 0x7 472b3077611SDavid Wu }, { 473b3077611SDavid Wu .num = 3, 474b3077611SDavid Wu .pin = 13, 475b3077611SDavid Wu .reg = 0x68, 476b3077611SDavid Wu .bit = 12, 477b3077611SDavid Wu .mask = 0x7 478b3077611SDavid Wu }, 479b3077611SDavid Wu }; 480b3077611SDavid Wu 48149c55878SDavid Wu static struct rockchip_mux_recalced_data rk3328_mux_recalced_data[] = { 48249c55878SDavid Wu { 48349c55878SDavid Wu .num = 2, 48449c55878SDavid Wu .pin = 12, 48549c55878SDavid Wu .reg = 0x24, 48649c55878SDavid Wu .bit = 8, 48749c55878SDavid Wu .mask = 0x3 48849c55878SDavid Wu }, { 48949c55878SDavid Wu .num = 2, 49049c55878SDavid Wu .pin = 15, 49149c55878SDavid Wu .reg = 0x28, 49249c55878SDavid Wu .bit = 0, 49349c55878SDavid Wu .mask = 0x7 49449c55878SDavid Wu }, { 49549c55878SDavid Wu .num = 2, 49649c55878SDavid Wu .pin = 23, 49749c55878SDavid Wu .reg = 0x30, 49849c55878SDavid Wu .bit = 14, 49949c55878SDavid Wu .mask = 0x3 50049c55878SDavid Wu }, 50149c55878SDavid Wu }; 50249c55878SDavid Wu 50349c55878SDavid Wu static void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin, 50449c55878SDavid Wu int *reg, u8 *bit, int *mask) 50549c55878SDavid Wu { 50649c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 50749c55878SDavid Wu struct rockchip_pin_ctrl *ctrl = priv->ctrl; 50849c55878SDavid Wu struct rockchip_mux_recalced_data *data; 50949c55878SDavid Wu int i; 51049c55878SDavid Wu 51149c55878SDavid Wu for (i = 0; i < ctrl->niomux_recalced; i++) { 51249c55878SDavid Wu data = &ctrl->iomux_recalced[i]; 51349c55878SDavid Wu if (data->num == bank->bank_num && 51449c55878SDavid Wu data->pin == pin) 51549c55878SDavid Wu break; 51649c55878SDavid Wu } 51749c55878SDavid Wu 51849c55878SDavid Wu if (i >= ctrl->niomux_recalced) 51949c55878SDavid Wu return; 52049c55878SDavid Wu 52149c55878SDavid Wu *reg = data->reg; 52249c55878SDavid Wu *mask = data->mask; 52349c55878SDavid Wu *bit = data->bit; 52449c55878SDavid Wu } 52549c55878SDavid Wu 52649c55878SDavid Wu static struct rockchip_mux_route_data px30_mux_route_data[] = { 52749c55878SDavid Wu { 52849c55878SDavid Wu /* cif-d2m0 */ 52949c55878SDavid Wu .bank_num = 2, 53049c55878SDavid Wu .pin = 0, 53149c55878SDavid Wu .func = 1, 53249c55878SDavid Wu .route_offset = 0x184, 53349c55878SDavid Wu .route_val = BIT(16 + 7), 53449c55878SDavid Wu }, { 53549c55878SDavid Wu /* cif-d2m1 */ 53649c55878SDavid Wu .bank_num = 3, 53749c55878SDavid Wu .pin = 3, 53849c55878SDavid Wu .func = 3, 53949c55878SDavid Wu .route_offset = 0x184, 54049c55878SDavid Wu .route_val = BIT(16 + 7) | BIT(7), 54149c55878SDavid Wu }, { 54249c55878SDavid Wu /* pdm-m0 */ 54349c55878SDavid Wu .bank_num = 3, 54449c55878SDavid Wu .pin = 22, 54549c55878SDavid Wu .func = 2, 54649c55878SDavid Wu .route_offset = 0x184, 54749c55878SDavid Wu .route_val = BIT(16 + 8), 54849c55878SDavid Wu }, { 54949c55878SDavid Wu /* pdm-m1 */ 55049c55878SDavid Wu .bank_num = 2, 55149c55878SDavid Wu .pin = 22, 55249c55878SDavid Wu .func = 1, 55349c55878SDavid Wu .route_offset = 0x184, 55449c55878SDavid Wu .route_val = BIT(16 + 8) | BIT(8), 55549c55878SDavid Wu }, { 55649c55878SDavid Wu /* uart2-rxm0 */ 55749c55878SDavid Wu .bank_num = 1, 558793770dfSDavid Wu .pin = 27, 55949c55878SDavid Wu .func = 2, 56049c55878SDavid Wu .route_offset = 0x184, 561793770dfSDavid Wu .route_val = BIT(16 + 10), 56249c55878SDavid Wu }, { 56349c55878SDavid Wu /* uart2-rxm1 */ 56449c55878SDavid Wu .bank_num = 2, 56549c55878SDavid Wu .pin = 14, 56649c55878SDavid Wu .func = 2, 56749c55878SDavid Wu .route_offset = 0x184, 568793770dfSDavid Wu .route_val = BIT(16 + 10) | BIT(10), 56949c55878SDavid Wu }, { 57049c55878SDavid Wu /* uart3-rxm0 */ 57149c55878SDavid Wu .bank_num = 0, 57249c55878SDavid Wu .pin = 17, 57349c55878SDavid Wu .func = 2, 57449c55878SDavid Wu .route_offset = 0x184, 575793770dfSDavid Wu .route_val = BIT(16 + 9), 57649c55878SDavid Wu }, { 57749c55878SDavid Wu /* uart3-rxm1 */ 57849c55878SDavid Wu .bank_num = 1, 579793770dfSDavid Wu .pin = 15, 58049c55878SDavid Wu .func = 2, 58149c55878SDavid Wu .route_offset = 0x184, 582793770dfSDavid Wu .route_val = BIT(16 + 9) | BIT(9), 58349c55878SDavid Wu }, 58449c55878SDavid Wu }; 58549c55878SDavid Wu 58649c55878SDavid Wu static struct rockchip_mux_route_data rk3128_mux_route_data[] = { 58749c55878SDavid Wu { 58849c55878SDavid Wu /* spi-0 */ 58949c55878SDavid Wu .bank_num = 1, 59049c55878SDavid Wu .pin = 10, 59149c55878SDavid Wu .func = 1, 59249c55878SDavid Wu .route_offset = 0x144, 59349c55878SDavid Wu .route_val = BIT(16 + 3) | BIT(16 + 4), 59449c55878SDavid Wu }, { 59549c55878SDavid Wu /* spi-1 */ 59649c55878SDavid Wu .bank_num = 1, 59749c55878SDavid Wu .pin = 27, 59849c55878SDavid Wu .func = 3, 59949c55878SDavid Wu .route_offset = 0x144, 60049c55878SDavid Wu .route_val = BIT(16 + 3) | BIT(16 + 4) | BIT(3), 60149c55878SDavid Wu }, { 60249c55878SDavid Wu /* spi-2 */ 60349c55878SDavid Wu .bank_num = 0, 60449c55878SDavid Wu .pin = 13, 60549c55878SDavid Wu .func = 2, 60649c55878SDavid Wu .route_offset = 0x144, 60749c55878SDavid Wu .route_val = BIT(16 + 3) | BIT(16 + 4) | BIT(4), 60849c55878SDavid Wu }, { 60949c55878SDavid Wu /* i2s-0 */ 61049c55878SDavid Wu .bank_num = 1, 61149c55878SDavid Wu .pin = 5, 61249c55878SDavid Wu .func = 1, 61349c55878SDavid Wu .route_offset = 0x144, 61449c55878SDavid Wu .route_val = BIT(16 + 5), 61549c55878SDavid Wu }, { 61649c55878SDavid Wu /* i2s-1 */ 61749c55878SDavid Wu .bank_num = 0, 61849c55878SDavid Wu .pin = 14, 61949c55878SDavid Wu .func = 1, 62049c55878SDavid Wu .route_offset = 0x144, 62149c55878SDavid Wu .route_val = BIT(16 + 5) | BIT(5), 62249c55878SDavid Wu }, { 62349c55878SDavid Wu /* emmc-0 */ 62449c55878SDavid Wu .bank_num = 1, 62549c55878SDavid Wu .pin = 22, 62649c55878SDavid Wu .func = 2, 62749c55878SDavid Wu .route_offset = 0x144, 62849c55878SDavid Wu .route_val = BIT(16 + 6), 62949c55878SDavid Wu }, { 63049c55878SDavid Wu /* emmc-1 */ 63149c55878SDavid Wu .bank_num = 2, 63249c55878SDavid Wu .pin = 4, 63349c55878SDavid Wu .func = 2, 63449c55878SDavid Wu .route_offset = 0x144, 63549c55878SDavid Wu .route_val = BIT(16 + 6) | BIT(6), 63649c55878SDavid Wu }, 63749c55878SDavid Wu }; 63849c55878SDavid Wu 63949c55878SDavid Wu static struct rockchip_mux_route_data rk3228_mux_route_data[] = { 64049c55878SDavid Wu { 64149c55878SDavid Wu /* pwm0-0 */ 64249c55878SDavid Wu .bank_num = 0, 64349c55878SDavid Wu .pin = 26, 64449c55878SDavid Wu .func = 1, 64549c55878SDavid Wu .route_offset = 0x50, 64649c55878SDavid Wu .route_val = BIT(16), 64749c55878SDavid Wu }, { 64849c55878SDavid Wu /* pwm0-1 */ 64949c55878SDavid Wu .bank_num = 3, 65049c55878SDavid Wu .pin = 21, 65149c55878SDavid Wu .func = 1, 65249c55878SDavid Wu .route_offset = 0x50, 65349c55878SDavid Wu .route_val = BIT(16) | BIT(0), 65449c55878SDavid Wu }, { 65549c55878SDavid Wu /* pwm1-0 */ 65649c55878SDavid Wu .bank_num = 0, 65749c55878SDavid Wu .pin = 27, 65849c55878SDavid Wu .func = 1, 65949c55878SDavid Wu .route_offset = 0x50, 66049c55878SDavid Wu .route_val = BIT(16 + 1), 66149c55878SDavid Wu }, { 66249c55878SDavid Wu /* pwm1-1 */ 66349c55878SDavid Wu .bank_num = 0, 66449c55878SDavid Wu .pin = 30, 66549c55878SDavid Wu .func = 2, 66649c55878SDavid Wu .route_offset = 0x50, 66749c55878SDavid Wu .route_val = BIT(16 + 1) | BIT(1), 66849c55878SDavid Wu }, { 66949c55878SDavid Wu /* pwm2-0 */ 67049c55878SDavid Wu .bank_num = 0, 67149c55878SDavid Wu .pin = 28, 67249c55878SDavid Wu .func = 1, 67349c55878SDavid Wu .route_offset = 0x50, 67449c55878SDavid Wu .route_val = BIT(16 + 2), 67549c55878SDavid Wu }, { 67649c55878SDavid Wu /* pwm2-1 */ 67749c55878SDavid Wu .bank_num = 1, 67849c55878SDavid Wu .pin = 12, 67949c55878SDavid Wu .func = 2, 68049c55878SDavid Wu .route_offset = 0x50, 68149c55878SDavid Wu .route_val = BIT(16 + 2) | BIT(2), 68249c55878SDavid Wu }, { 68349c55878SDavid Wu /* pwm3-0 */ 68449c55878SDavid Wu .bank_num = 3, 68549c55878SDavid Wu .pin = 26, 68649c55878SDavid Wu .func = 1, 68749c55878SDavid Wu .route_offset = 0x50, 68849c55878SDavid Wu .route_val = BIT(16 + 3), 68949c55878SDavid Wu }, { 69049c55878SDavid Wu /* pwm3-1 */ 69149c55878SDavid Wu .bank_num = 1, 69249c55878SDavid Wu .pin = 11, 69349c55878SDavid Wu .func = 2, 69449c55878SDavid Wu .route_offset = 0x50, 69549c55878SDavid Wu .route_val = BIT(16 + 3) | BIT(3), 69649c55878SDavid Wu }, { 69749c55878SDavid Wu /* sdio-0_d0 */ 69849c55878SDavid Wu .bank_num = 1, 69949c55878SDavid Wu .pin = 1, 70049c55878SDavid Wu .func = 1, 70149c55878SDavid Wu .route_offset = 0x50, 70249c55878SDavid Wu .route_val = BIT(16 + 4), 70349c55878SDavid Wu }, { 70449c55878SDavid Wu /* sdio-1_d0 */ 70549c55878SDavid Wu .bank_num = 3, 70649c55878SDavid Wu .pin = 2, 70749c55878SDavid Wu .func = 1, 70849c55878SDavid Wu .route_offset = 0x50, 70949c55878SDavid Wu .route_val = BIT(16 + 4) | BIT(4), 71049c55878SDavid Wu }, { 71149c55878SDavid Wu /* spi-0_rx */ 71249c55878SDavid Wu .bank_num = 0, 71349c55878SDavid Wu .pin = 13, 71449c55878SDavid Wu .func = 2, 71549c55878SDavid Wu .route_offset = 0x50, 71649c55878SDavid Wu .route_val = BIT(16 + 5), 71749c55878SDavid Wu }, { 71849c55878SDavid Wu /* spi-1_rx */ 71949c55878SDavid Wu .bank_num = 2, 72049c55878SDavid Wu .pin = 0, 72149c55878SDavid Wu .func = 2, 72249c55878SDavid Wu .route_offset = 0x50, 72349c55878SDavid Wu .route_val = BIT(16 + 5) | BIT(5), 72449c55878SDavid Wu }, { 72549c55878SDavid Wu /* emmc-0_cmd */ 72649c55878SDavid Wu .bank_num = 1, 72749c55878SDavid Wu .pin = 22, 72849c55878SDavid Wu .func = 2, 72949c55878SDavid Wu .route_offset = 0x50, 73049c55878SDavid Wu .route_val = BIT(16 + 7), 73149c55878SDavid Wu }, { 73249c55878SDavid Wu /* emmc-1_cmd */ 73349c55878SDavid Wu .bank_num = 2, 73449c55878SDavid Wu .pin = 4, 73549c55878SDavid Wu .func = 2, 73649c55878SDavid Wu .route_offset = 0x50, 73749c55878SDavid Wu .route_val = BIT(16 + 7) | BIT(7), 73849c55878SDavid Wu }, { 73949c55878SDavid Wu /* uart2-0_rx */ 74049c55878SDavid Wu .bank_num = 1, 74149c55878SDavid Wu .pin = 19, 74249c55878SDavid Wu .func = 2, 74349c55878SDavid Wu .route_offset = 0x50, 74449c55878SDavid Wu .route_val = BIT(16 + 8), 74549c55878SDavid Wu }, { 74649c55878SDavid Wu /* uart2-1_rx */ 74749c55878SDavid Wu .bank_num = 1, 74849c55878SDavid Wu .pin = 10, 74949c55878SDavid Wu .func = 2, 75049c55878SDavid Wu .route_offset = 0x50, 75149c55878SDavid Wu .route_val = BIT(16 + 8) | BIT(8), 75249c55878SDavid Wu }, { 75349c55878SDavid Wu /* uart1-0_rx */ 75449c55878SDavid Wu .bank_num = 1, 75549c55878SDavid Wu .pin = 10, 75649c55878SDavid Wu .func = 1, 75749c55878SDavid Wu .route_offset = 0x50, 75849c55878SDavid Wu .route_val = BIT(16 + 11), 75949c55878SDavid Wu }, { 76049c55878SDavid Wu /* uart1-1_rx */ 76149c55878SDavid Wu .bank_num = 3, 76249c55878SDavid Wu .pin = 13, 76349c55878SDavid Wu .func = 1, 76449c55878SDavid Wu .route_offset = 0x50, 76549c55878SDavid Wu .route_val = BIT(16 + 11) | BIT(11), 76649c55878SDavid Wu }, 76749c55878SDavid Wu }; 76849c55878SDavid Wu 76949c55878SDavid Wu static struct rockchip_mux_route_data rk3288_mux_route_data[] = { 77049c55878SDavid Wu { 77149c55878SDavid Wu /* edphdmi_cecinoutt1 */ 77249c55878SDavid Wu .bank_num = 7, 77349c55878SDavid Wu .pin = 16, 77449c55878SDavid Wu .func = 2, 77549c55878SDavid Wu .route_offset = 0x264, 77649c55878SDavid Wu .route_val = BIT(16 + 12) | BIT(12), 77749c55878SDavid Wu }, { 77849c55878SDavid Wu /* edphdmi_cecinout */ 77949c55878SDavid Wu .bank_num = 7, 78049c55878SDavid Wu .pin = 23, 78149c55878SDavid Wu .func = 4, 78249c55878SDavid Wu .route_offset = 0x264, 78349c55878SDavid Wu .route_val = BIT(16 + 12), 78449c55878SDavid Wu }, 78549c55878SDavid Wu }; 78649c55878SDavid Wu 787b3077611SDavid Wu static struct rockchip_mux_route_data rk3308_mux_route_data[] = { 788b3077611SDavid Wu { 789b3077611SDavid Wu /* uart2_rxm0 */ 790b3077611SDavid Wu .bank_num = 1, 791b3077611SDavid Wu .pin = 22, 792b3077611SDavid Wu .func = 2, 793b3077611SDavid Wu .route_offset = 0x314, 794b3077611SDavid Wu .route_val = BIT(16 + 2) | BIT(16 + 3), 795b3077611SDavid Wu }, { 796b3077611SDavid Wu /* uart2_rxm1 */ 797b3077611SDavid Wu .bank_num = 4, 798b3077611SDavid Wu .pin = 26, 799b3077611SDavid Wu .func = 2, 800b3077611SDavid Wu .route_offset = 0x314, 801b3077611SDavid Wu .route_val = BIT(16 + 2) | BIT(16 + 3) | BIT(2), 802b3077611SDavid Wu }, { 803b3077611SDavid Wu /* i2c3_sdam0 */ 804b3077611SDavid Wu .bank_num = 0, 805b3077611SDavid Wu .pin = 23, 806b3077611SDavid Wu .func = 2, 807b3077611SDavid Wu .route_offset = 0x314, 808b3077611SDavid Wu .route_val = BIT(16 + 4), 809b3077611SDavid Wu }, { 810b3077611SDavid Wu /* i2c3_sdam1 */ 811b3077611SDavid Wu .bank_num = 3, 812b3077611SDavid Wu .pin = 12, 813b3077611SDavid Wu .func = 2, 814b3077611SDavid Wu .route_offset = 0x314, 815b3077611SDavid Wu .route_val = BIT(16 + 4) | BIT(4), 816b3077611SDavid Wu }, 817b3077611SDavid Wu }; 818b3077611SDavid Wu 81949c55878SDavid Wu static struct rockchip_mux_route_data rk3328_mux_route_data[] = { 82049c55878SDavid Wu { 82149c55878SDavid Wu /* uart2dbg_rxm0 */ 82249c55878SDavid Wu .bank_num = 1, 82349c55878SDavid Wu .pin = 1, 82449c55878SDavid Wu .func = 2, 82549c55878SDavid Wu .route_offset = 0x50, 82649c55878SDavid Wu .route_val = BIT(16) | BIT(16 + 1), 82749c55878SDavid Wu }, { 82849c55878SDavid Wu /* uart2dbg_rxm1 */ 82949c55878SDavid Wu .bank_num = 2, 83049c55878SDavid Wu .pin = 1, 83149c55878SDavid Wu .func = 1, 83249c55878SDavid Wu .route_offset = 0x50, 83349c55878SDavid Wu .route_val = BIT(16) | BIT(16 + 1) | BIT(0), 83449c55878SDavid Wu }, { 83549c55878SDavid Wu /* gmac-m1_rxd0 */ 83649c55878SDavid Wu .bank_num = 1, 83749c55878SDavid Wu .pin = 11, 83849c55878SDavid Wu .func = 2, 83949c55878SDavid Wu .route_offset = 0x50, 84049c55878SDavid Wu .route_val = BIT(16 + 2) | BIT(2), 84149c55878SDavid Wu }, { 84249c55878SDavid Wu /* gmac-m1-optimized_rxd3 */ 84349c55878SDavid Wu .bank_num = 1, 84449c55878SDavid Wu .pin = 14, 84549c55878SDavid Wu .func = 2, 84649c55878SDavid Wu .route_offset = 0x50, 84749c55878SDavid Wu .route_val = BIT(16 + 10) | BIT(10), 84849c55878SDavid Wu }, { 84949c55878SDavid Wu /* pdm_sdi0m0 */ 85049c55878SDavid Wu .bank_num = 2, 85149c55878SDavid Wu .pin = 19, 85249c55878SDavid Wu .func = 2, 85349c55878SDavid Wu .route_offset = 0x50, 85449c55878SDavid Wu .route_val = BIT(16 + 3), 85549c55878SDavid Wu }, { 85649c55878SDavid Wu /* pdm_sdi0m1 */ 85749c55878SDavid Wu .bank_num = 1, 85849c55878SDavid Wu .pin = 23, 85949c55878SDavid Wu .func = 3, 86049c55878SDavid Wu .route_offset = 0x50, 86149c55878SDavid Wu .route_val = BIT(16 + 3) | BIT(3), 86249c55878SDavid Wu }, { 86349c55878SDavid Wu /* spi_rxdm2 */ 86449c55878SDavid Wu .bank_num = 3, 86549c55878SDavid Wu .pin = 2, 86649c55878SDavid Wu .func = 4, 86749c55878SDavid Wu .route_offset = 0x50, 86849c55878SDavid Wu .route_val = BIT(16 + 4) | BIT(16 + 5) | BIT(5), 86949c55878SDavid Wu }, { 87049c55878SDavid Wu /* i2s2_sdim0 */ 87149c55878SDavid Wu .bank_num = 1, 87249c55878SDavid Wu .pin = 24, 87349c55878SDavid Wu .func = 1, 87449c55878SDavid Wu .route_offset = 0x50, 87549c55878SDavid Wu .route_val = BIT(16 + 6), 87649c55878SDavid Wu }, { 87749c55878SDavid Wu /* i2s2_sdim1 */ 87849c55878SDavid Wu .bank_num = 3, 87949c55878SDavid Wu .pin = 2, 88049c55878SDavid Wu .func = 6, 88149c55878SDavid Wu .route_offset = 0x50, 88249c55878SDavid Wu .route_val = BIT(16 + 6) | BIT(6), 88349c55878SDavid Wu }, { 88449c55878SDavid Wu /* card_iom1 */ 88549c55878SDavid Wu .bank_num = 2, 88649c55878SDavid Wu .pin = 22, 88749c55878SDavid Wu .func = 3, 88849c55878SDavid Wu .route_offset = 0x50, 88949c55878SDavid Wu .route_val = BIT(16 + 7) | BIT(7), 89049c55878SDavid Wu }, { 89149c55878SDavid Wu /* tsp_d5m1 */ 89249c55878SDavid Wu .bank_num = 2, 89349c55878SDavid Wu .pin = 16, 89449c55878SDavid Wu .func = 3, 89549c55878SDavid Wu .route_offset = 0x50, 89649c55878SDavid Wu .route_val = BIT(16 + 8) | BIT(8), 89749c55878SDavid Wu }, { 89849c55878SDavid Wu /* cif_data5m1 */ 89949c55878SDavid Wu .bank_num = 2, 90049c55878SDavid Wu .pin = 16, 90149c55878SDavid Wu .func = 4, 90249c55878SDavid Wu .route_offset = 0x50, 90349c55878SDavid Wu .route_val = BIT(16 + 9) | BIT(9), 90449c55878SDavid Wu }, 90549c55878SDavid Wu }; 90649c55878SDavid Wu 90749c55878SDavid Wu static struct rockchip_mux_route_data rk3399_mux_route_data[] = { 90849c55878SDavid Wu { 90949c55878SDavid Wu /* uart2dbga_rx */ 91049c55878SDavid Wu .bank_num = 4, 91149c55878SDavid Wu .pin = 8, 91249c55878SDavid Wu .func = 2, 91349c55878SDavid Wu .route_offset = 0xe21c, 91449c55878SDavid Wu .route_val = BIT(16 + 10) | BIT(16 + 11), 91549c55878SDavid Wu }, { 91649c55878SDavid Wu /* uart2dbgb_rx */ 91749c55878SDavid Wu .bank_num = 4, 91849c55878SDavid Wu .pin = 16, 91949c55878SDavid Wu .func = 2, 92049c55878SDavid Wu .route_offset = 0xe21c, 92149c55878SDavid Wu .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(10), 92249c55878SDavid Wu }, { 92349c55878SDavid Wu /* uart2dbgc_rx */ 92449c55878SDavid Wu .bank_num = 4, 92549c55878SDavid Wu .pin = 19, 92649c55878SDavid Wu .func = 1, 92749c55878SDavid Wu .route_offset = 0xe21c, 92849c55878SDavid Wu .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(11), 92949c55878SDavid Wu }, { 93049c55878SDavid Wu /* pcie_clkreqn */ 93149c55878SDavid Wu .bank_num = 2, 93249c55878SDavid Wu .pin = 26, 93349c55878SDavid Wu .func = 2, 93449c55878SDavid Wu .route_offset = 0xe21c, 93549c55878SDavid Wu .route_val = BIT(16 + 14), 93649c55878SDavid Wu }, { 93749c55878SDavid Wu /* pcie_clkreqnb */ 93849c55878SDavid Wu .bank_num = 4, 93949c55878SDavid Wu .pin = 24, 94049c55878SDavid Wu .func = 1, 94149c55878SDavid Wu .route_offset = 0xe21c, 94249c55878SDavid Wu .route_val = BIT(16 + 14) | BIT(14), 94349c55878SDavid Wu }, 94449c55878SDavid Wu }; 94549c55878SDavid Wu 94649c55878SDavid Wu static bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin, 94749c55878SDavid Wu int mux, u32 *reg, u32 *value) 94849c55878SDavid Wu { 94949c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 95049c55878SDavid Wu struct rockchip_pin_ctrl *ctrl = priv->ctrl; 95149c55878SDavid Wu struct rockchip_mux_route_data *data; 95249c55878SDavid Wu int i; 95349c55878SDavid Wu 95449c55878SDavid Wu for (i = 0; i < ctrl->niomux_routes; i++) { 95549c55878SDavid Wu data = &ctrl->iomux_routes[i]; 95649c55878SDavid Wu if ((data->bank_num == bank->bank_num) && 95749c55878SDavid Wu (data->pin == pin) && (data->func == mux)) 95849c55878SDavid Wu break; 95949c55878SDavid Wu } 96049c55878SDavid Wu 96149c55878SDavid Wu if (i >= ctrl->niomux_routes) 96249c55878SDavid Wu return false; 96349c55878SDavid Wu 96449c55878SDavid Wu *reg = data->route_offset; 96549c55878SDavid Wu *value = data->route_val; 96649c55878SDavid Wu 96749c55878SDavid Wu return true; 96849c55878SDavid Wu } 96949c55878SDavid Wu 97049c55878SDavid Wu static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) 97149c55878SDavid Wu { 97249c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 97349c55878SDavid Wu int iomux_num = (pin / 8); 97449c55878SDavid Wu struct regmap *regmap; 97549c55878SDavid Wu unsigned int val; 97649c55878SDavid Wu int reg, ret, mask, mux_type; 97749c55878SDavid Wu u8 bit; 97849c55878SDavid Wu 97949c55878SDavid Wu if (iomux_num > 3) 98049c55878SDavid Wu return -EINVAL; 98149c55878SDavid Wu 98249c55878SDavid Wu if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { 98349c55878SDavid Wu debug("pin %d is unrouted\n", pin); 98449c55878SDavid Wu return -EINVAL; 98549c55878SDavid Wu } 98649c55878SDavid Wu 98749c55878SDavid Wu if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) 98849c55878SDavid Wu return RK_FUNC_GPIO; 98949c55878SDavid Wu 99049c55878SDavid Wu regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) 99149c55878SDavid Wu ? priv->regmap_pmu : priv->regmap_base; 99249c55878SDavid Wu 99349c55878SDavid Wu /* get basic quadrupel of mux registers and the correct reg inside */ 99449c55878SDavid Wu mux_type = bank->iomux[iomux_num].type; 99549c55878SDavid Wu reg = bank->iomux[iomux_num].offset; 99649c55878SDavid Wu if (mux_type & IOMUX_WIDTH_4BIT) { 99749c55878SDavid Wu if ((pin % 8) >= 4) 99849c55878SDavid Wu reg += 0x4; 99949c55878SDavid Wu bit = (pin % 4) * 4; 100049c55878SDavid Wu mask = 0xf; 100149c55878SDavid Wu } else if (mux_type & IOMUX_WIDTH_3BIT) { 100249c55878SDavid Wu if ((pin % 8) >= 5) 100349c55878SDavid Wu reg += 0x4; 100449c55878SDavid Wu bit = (pin % 8 % 5) * 3; 100549c55878SDavid Wu mask = 0x7; 100649c55878SDavid Wu } else { 100749c55878SDavid Wu bit = (pin % 8) * 2; 100849c55878SDavid Wu mask = 0x3; 100949c55878SDavid Wu } 101049c55878SDavid Wu 101149c55878SDavid Wu if (bank->recalced_mask & BIT(pin)) 101249c55878SDavid Wu rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); 101349c55878SDavid Wu 101449c55878SDavid Wu ret = regmap_read(regmap, reg, &val); 101549c55878SDavid Wu if (ret) 101649c55878SDavid Wu return ret; 101749c55878SDavid Wu 101849c55878SDavid Wu return ((val >> bit) & mask); 101949c55878SDavid Wu } 102049c55878SDavid Wu 102149c55878SDavid Wu static int rockchip_pinctrl_get_gpio_mux(struct udevice *dev, int banknum, 102249c55878SDavid Wu int index) 102349c55878SDavid Wu { struct rockchip_pinctrl_priv *priv = dev_get_priv(dev); 102449c55878SDavid Wu struct rockchip_pin_ctrl *ctrl = priv->ctrl; 102549c55878SDavid Wu 102649c55878SDavid Wu return rockchip_get_mux(&ctrl->pin_banks[banknum], index); 102749c55878SDavid Wu } 102849c55878SDavid Wu 102949c55878SDavid Wu static int rockchip_verify_mux(struct rockchip_pin_bank *bank, 103049c55878SDavid Wu int pin, int mux) 103149c55878SDavid Wu { 103249c55878SDavid Wu int iomux_num = (pin / 8); 103349c55878SDavid Wu 103449c55878SDavid Wu if (iomux_num > 3) 103549c55878SDavid Wu return -EINVAL; 103649c55878SDavid Wu 103749c55878SDavid Wu if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { 103849c55878SDavid Wu debug("pin %d is unrouted\n", pin); 103949c55878SDavid Wu return -EINVAL; 104049c55878SDavid Wu } 104149c55878SDavid Wu 104249c55878SDavid Wu if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) { 104349c55878SDavid Wu if (mux != IOMUX_GPIO_ONLY) { 104449c55878SDavid Wu debug("pin %d only supports a gpio mux\n", pin); 104549c55878SDavid Wu return -ENOTSUPP; 104649c55878SDavid Wu } 104749c55878SDavid Wu } 104849c55878SDavid Wu 104949c55878SDavid Wu return 0; 105049c55878SDavid Wu } 105149c55878SDavid Wu 105249c55878SDavid Wu /* 105349c55878SDavid Wu * Set a new mux function for a pin. 105449c55878SDavid Wu * 105549c55878SDavid Wu * The register is divided into the upper and lower 16 bit. When changing 105649c55878SDavid Wu * a value, the previous register value is not read and changed. Instead 105749c55878SDavid Wu * it seems the changed bits are marked in the upper 16 bit, while the 105849c55878SDavid Wu * changed value gets set in the same offset in the lower 16 bit. 105949c55878SDavid Wu * All pin settings seem to be 2 bit wide in both the upper and lower 106049c55878SDavid Wu * parts. 106149c55878SDavid Wu * @bank: pin bank to change 106249c55878SDavid Wu * @pin: pin to change 106349c55878SDavid Wu * @mux: new mux function to set 106449c55878SDavid Wu */ 106549c55878SDavid Wu static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) 106649c55878SDavid Wu { 106749c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 106849c55878SDavid Wu int iomux_num = (pin / 8); 106949c55878SDavid Wu struct regmap *regmap; 107049c55878SDavid Wu int reg, ret, mask, mux_type; 107149c55878SDavid Wu u8 bit; 107249c55878SDavid Wu u32 data, route_reg, route_val; 107349c55878SDavid Wu 107449c55878SDavid Wu ret = rockchip_verify_mux(bank, pin, mux); 107549c55878SDavid Wu if (ret < 0) 107649c55878SDavid Wu return ret; 107749c55878SDavid Wu 107849c55878SDavid Wu if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) 107949c55878SDavid Wu return 0; 108049c55878SDavid Wu 108149c55878SDavid Wu debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); 108249c55878SDavid Wu 108349c55878SDavid Wu regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) 108449c55878SDavid Wu ? priv->regmap_pmu : priv->regmap_base; 108549c55878SDavid Wu 108649c55878SDavid Wu /* get basic quadrupel of mux registers and the correct reg inside */ 108749c55878SDavid Wu mux_type = bank->iomux[iomux_num].type; 108849c55878SDavid Wu reg = bank->iomux[iomux_num].offset; 108949c55878SDavid Wu if (mux_type & IOMUX_WIDTH_4BIT) { 109049c55878SDavid Wu if ((pin % 8) >= 4) 109149c55878SDavid Wu reg += 0x4; 109249c55878SDavid Wu bit = (pin % 4) * 4; 109349c55878SDavid Wu mask = 0xf; 109449c55878SDavid Wu } else if (mux_type & IOMUX_WIDTH_3BIT) { 109549c55878SDavid Wu if ((pin % 8) >= 5) 109649c55878SDavid Wu reg += 0x4; 109749c55878SDavid Wu bit = (pin % 8 % 5) * 3; 109849c55878SDavid Wu mask = 0x7; 109949c55878SDavid Wu } else { 110049c55878SDavid Wu bit = (pin % 8) * 2; 110149c55878SDavid Wu mask = 0x3; 110249c55878SDavid Wu } 110349c55878SDavid Wu 110449c55878SDavid Wu if (bank->recalced_mask & BIT(pin)) 110549c55878SDavid Wu rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); 110649c55878SDavid Wu 110749c55878SDavid Wu if (bank->route_mask & BIT(pin)) { 110849c55878SDavid Wu if (rockchip_get_mux_route(bank, pin, mux, &route_reg, 110949c55878SDavid Wu &route_val)) { 111049c55878SDavid Wu ret = regmap_write(regmap, route_reg, route_val); 111149c55878SDavid Wu if (ret) 111249c55878SDavid Wu return ret; 111349c55878SDavid Wu } 111449c55878SDavid Wu } 111549c55878SDavid Wu 111649c55878SDavid Wu data = (mask << (bit + 16)); 111749c55878SDavid Wu data |= (mux & mask) << bit; 111849c55878SDavid Wu ret = regmap_write(regmap, reg, data); 111949c55878SDavid Wu 112049c55878SDavid Wu return ret; 112149c55878SDavid Wu } 112249c55878SDavid Wu 112349c55878SDavid Wu #define PX30_PULL_PMU_OFFSET 0x10 112449c55878SDavid Wu #define PX30_PULL_GRF_OFFSET 0x60 112549c55878SDavid Wu #define PX30_PULL_BITS_PER_PIN 2 112649c55878SDavid Wu #define PX30_PULL_PINS_PER_REG 8 112749c55878SDavid Wu #define PX30_PULL_BANK_STRIDE 16 112849c55878SDavid Wu 112949c55878SDavid Wu static void px30_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 113049c55878SDavid Wu int pin_num, struct regmap **regmap, 113149c55878SDavid Wu int *reg, u8 *bit) 113249c55878SDavid Wu { 113349c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 113449c55878SDavid Wu 113549c55878SDavid Wu /* The first 32 pins of the first bank are located in PMU */ 113649c55878SDavid Wu if (bank->bank_num == 0) { 113749c55878SDavid Wu *regmap = priv->regmap_pmu; 113849c55878SDavid Wu *reg = PX30_PULL_PMU_OFFSET; 113949c55878SDavid Wu } else { 114049c55878SDavid Wu *regmap = priv->regmap_base; 114149c55878SDavid Wu *reg = PX30_PULL_GRF_OFFSET; 114249c55878SDavid Wu 114349c55878SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 114449c55878SDavid Wu *reg -= 0x10; 114549c55878SDavid Wu *reg += bank->bank_num * PX30_PULL_BANK_STRIDE; 114649c55878SDavid Wu } 114749c55878SDavid Wu 114849c55878SDavid Wu *reg += ((pin_num / PX30_PULL_PINS_PER_REG) * 4); 114949c55878SDavid Wu *bit = (pin_num % PX30_PULL_PINS_PER_REG); 115049c55878SDavid Wu *bit *= PX30_PULL_BITS_PER_PIN; 115149c55878SDavid Wu } 115249c55878SDavid Wu 115349c55878SDavid Wu #define PX30_DRV_PMU_OFFSET 0x20 115449c55878SDavid Wu #define PX30_DRV_GRF_OFFSET 0xf0 115549c55878SDavid Wu #define PX30_DRV_BITS_PER_PIN 2 115649c55878SDavid Wu #define PX30_DRV_PINS_PER_REG 8 115749c55878SDavid Wu #define PX30_DRV_BANK_STRIDE 16 115849c55878SDavid Wu 115949c55878SDavid Wu static void px30_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 116049c55878SDavid Wu int pin_num, struct regmap **regmap, 116149c55878SDavid Wu int *reg, u8 *bit) 116249c55878SDavid Wu { 116349c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 116449c55878SDavid Wu 116549c55878SDavid Wu /* The first 32 pins of the first bank are located in PMU */ 116649c55878SDavid Wu if (bank->bank_num == 0) { 116749c55878SDavid Wu *regmap = priv->regmap_pmu; 116849c55878SDavid Wu *reg = PX30_DRV_PMU_OFFSET; 116949c55878SDavid Wu } else { 117049c55878SDavid Wu *regmap = priv->regmap_base; 117149c55878SDavid Wu *reg = PX30_DRV_GRF_OFFSET; 117249c55878SDavid Wu 117349c55878SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 117449c55878SDavid Wu *reg -= 0x10; 117549c55878SDavid Wu *reg += bank->bank_num * PX30_DRV_BANK_STRIDE; 117649c55878SDavid Wu } 117749c55878SDavid Wu 117849c55878SDavid Wu *reg += ((pin_num / PX30_DRV_PINS_PER_REG) * 4); 117949c55878SDavid Wu *bit = (pin_num % PX30_DRV_PINS_PER_REG); 118049c55878SDavid Wu *bit *= PX30_DRV_BITS_PER_PIN; 118149c55878SDavid Wu } 118249c55878SDavid Wu 118349c55878SDavid Wu #define PX30_SCHMITT_PMU_OFFSET 0x38 118449c55878SDavid Wu #define PX30_SCHMITT_GRF_OFFSET 0xc0 118549c55878SDavid Wu #define PX30_SCHMITT_PINS_PER_PMU_REG 16 118649c55878SDavid Wu #define PX30_SCHMITT_BANK_STRIDE 16 118749c55878SDavid Wu #define PX30_SCHMITT_PINS_PER_GRF_REG 8 118849c55878SDavid Wu 118949c55878SDavid Wu static int px30_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 119049c55878SDavid Wu int pin_num, 119149c55878SDavid Wu struct regmap **regmap, 119249c55878SDavid Wu int *reg, u8 *bit) 119349c55878SDavid Wu { 119449c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 119549c55878SDavid Wu int pins_per_reg; 119649c55878SDavid Wu 119749c55878SDavid Wu if (bank->bank_num == 0) { 119849c55878SDavid Wu *regmap = priv->regmap_pmu; 119949c55878SDavid Wu *reg = PX30_SCHMITT_PMU_OFFSET; 120049c55878SDavid Wu pins_per_reg = PX30_SCHMITT_PINS_PER_PMU_REG; 120149c55878SDavid Wu } else { 120249c55878SDavid Wu *regmap = priv->regmap_base; 120349c55878SDavid Wu *reg = PX30_SCHMITT_GRF_OFFSET; 120449c55878SDavid Wu pins_per_reg = PX30_SCHMITT_PINS_PER_GRF_REG; 120549c55878SDavid Wu *reg += (bank->bank_num - 1) * PX30_SCHMITT_BANK_STRIDE; 120649c55878SDavid Wu } 120749c55878SDavid Wu *reg += ((pin_num / pins_per_reg) * 4); 120849c55878SDavid Wu *bit = pin_num % pins_per_reg; 120949c55878SDavid Wu 121049c55878SDavid Wu return 0; 121149c55878SDavid Wu } 121249c55878SDavid Wu 121349c55878SDavid Wu #define RV1108_PULL_PMU_OFFSET 0x10 121449c55878SDavid Wu #define RV1108_PULL_OFFSET 0x110 121549c55878SDavid Wu #define RV1108_PULL_PINS_PER_REG 8 121649c55878SDavid Wu #define RV1108_PULL_BITS_PER_PIN 2 121749c55878SDavid Wu #define RV1108_PULL_BANK_STRIDE 16 121849c55878SDavid Wu 121949c55878SDavid Wu static void rv1108_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 122049c55878SDavid Wu int pin_num, struct regmap **regmap, 122149c55878SDavid Wu int *reg, u8 *bit) 122249c55878SDavid Wu { 122349c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 122449c55878SDavid Wu 122549c55878SDavid Wu /* The first 24 pins of the first bank are located in PMU */ 122649c55878SDavid Wu if (bank->bank_num == 0) { 122749c55878SDavid Wu *regmap = priv->regmap_pmu; 122849c55878SDavid Wu *reg = RV1108_PULL_PMU_OFFSET; 122949c55878SDavid Wu } else { 123049c55878SDavid Wu *reg = RV1108_PULL_OFFSET; 123149c55878SDavid Wu *regmap = priv->regmap_base; 123249c55878SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 123349c55878SDavid Wu *reg -= 0x10; 123449c55878SDavid Wu *reg += bank->bank_num * RV1108_PULL_BANK_STRIDE; 123549c55878SDavid Wu } 123649c55878SDavid Wu 123749c55878SDavid Wu *reg += ((pin_num / RV1108_PULL_PINS_PER_REG) * 4); 123849c55878SDavid Wu *bit = (pin_num % RV1108_PULL_PINS_PER_REG); 123949c55878SDavid Wu *bit *= RV1108_PULL_BITS_PER_PIN; 124049c55878SDavid Wu } 124149c55878SDavid Wu 124249c55878SDavid Wu #define RV1108_DRV_PMU_OFFSET 0x20 124349c55878SDavid Wu #define RV1108_DRV_GRF_OFFSET 0x210 124449c55878SDavid Wu #define RV1108_DRV_BITS_PER_PIN 2 124549c55878SDavid Wu #define RV1108_DRV_PINS_PER_REG 8 124649c55878SDavid Wu #define RV1108_DRV_BANK_STRIDE 16 124749c55878SDavid Wu 124849c55878SDavid Wu static void rv1108_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 124949c55878SDavid Wu int pin_num, struct regmap **regmap, 125049c55878SDavid Wu int *reg, u8 *bit) 125149c55878SDavid Wu { 125249c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 125349c55878SDavid Wu 125449c55878SDavid Wu /* The first 24 pins of the first bank are located in PMU */ 125549c55878SDavid Wu if (bank->bank_num == 0) { 125649c55878SDavid Wu *regmap = priv->regmap_pmu; 125749c55878SDavid Wu *reg = RV1108_DRV_PMU_OFFSET; 125849c55878SDavid Wu } else { 125949c55878SDavid Wu *regmap = priv->regmap_base; 126049c55878SDavid Wu *reg = RV1108_DRV_GRF_OFFSET; 126149c55878SDavid Wu 126249c55878SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 126349c55878SDavid Wu *reg -= 0x10; 126449c55878SDavid Wu *reg += bank->bank_num * RV1108_DRV_BANK_STRIDE; 126549c55878SDavid Wu } 126649c55878SDavid Wu 126749c55878SDavid Wu *reg += ((pin_num / RV1108_DRV_PINS_PER_REG) * 4); 126849c55878SDavid Wu *bit = pin_num % RV1108_DRV_PINS_PER_REG; 126949c55878SDavid Wu *bit *= RV1108_DRV_BITS_PER_PIN; 127049c55878SDavid Wu } 127149c55878SDavid Wu 127249c55878SDavid Wu #define RV1108_SCHMITT_PMU_OFFSET 0x30 127349c55878SDavid Wu #define RV1108_SCHMITT_GRF_OFFSET 0x388 127449c55878SDavid Wu #define RV1108_SCHMITT_BANK_STRIDE 8 127549c55878SDavid Wu #define RV1108_SCHMITT_PINS_PER_GRF_REG 16 127649c55878SDavid Wu #define RV1108_SCHMITT_PINS_PER_PMU_REG 8 127749c55878SDavid Wu 127849c55878SDavid Wu static int rv1108_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 127949c55878SDavid Wu int pin_num, 128049c55878SDavid Wu struct regmap **regmap, 128149c55878SDavid Wu int *reg, u8 *bit) 128249c55878SDavid Wu { 128349c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 128449c55878SDavid Wu int pins_per_reg; 128549c55878SDavid Wu 128649c55878SDavid Wu if (bank->bank_num == 0) { 128749c55878SDavid Wu *regmap = priv->regmap_pmu; 128849c55878SDavid Wu *reg = RV1108_SCHMITT_PMU_OFFSET; 128949c55878SDavid Wu pins_per_reg = RV1108_SCHMITT_PINS_PER_PMU_REG; 129049c55878SDavid Wu } else { 129149c55878SDavid Wu *regmap = priv->regmap_base; 129249c55878SDavid Wu *reg = RV1108_SCHMITT_GRF_OFFSET; 129349c55878SDavid Wu pins_per_reg = RV1108_SCHMITT_PINS_PER_GRF_REG; 129449c55878SDavid Wu *reg += (bank->bank_num - 1) * RV1108_SCHMITT_BANK_STRIDE; 129549c55878SDavid Wu } 129649c55878SDavid Wu *reg += ((pin_num / pins_per_reg) * 4); 129749c55878SDavid Wu *bit = pin_num % pins_per_reg; 129849c55878SDavid Wu 129949c55878SDavid Wu return 0; 130049c55878SDavid Wu } 130149c55878SDavid Wu 130249c55878SDavid Wu #define RK2928_PULL_OFFSET 0x118 130349c55878SDavid Wu #define RK2928_PULL_PINS_PER_REG 16 130449c55878SDavid Wu #define RK2928_PULL_BANK_STRIDE 8 130549c55878SDavid Wu 130649c55878SDavid Wu static void rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 130749c55878SDavid Wu int pin_num, struct regmap **regmap, 130849c55878SDavid Wu int *reg, u8 *bit) 130949c55878SDavid Wu { 131049c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 131149c55878SDavid Wu 131249c55878SDavid Wu *regmap = priv->regmap_base; 131349c55878SDavid Wu *reg = RK2928_PULL_OFFSET; 131449c55878SDavid Wu *reg += bank->bank_num * RK2928_PULL_BANK_STRIDE; 131549c55878SDavid Wu *reg += (pin_num / RK2928_PULL_PINS_PER_REG) * 4; 131649c55878SDavid Wu 131749c55878SDavid Wu *bit = pin_num % RK2928_PULL_PINS_PER_REG; 131849c55878SDavid Wu }; 131949c55878SDavid Wu 132049c55878SDavid Wu #define RK3128_PULL_OFFSET 0x118 132149c55878SDavid Wu 132249c55878SDavid Wu static void rk3128_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 132349c55878SDavid Wu int pin_num, struct regmap **regmap, 132449c55878SDavid Wu int *reg, u8 *bit) 132549c55878SDavid Wu { 132649c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 132749c55878SDavid Wu 132849c55878SDavid Wu *regmap = priv->regmap_base; 132949c55878SDavid Wu *reg = RK3128_PULL_OFFSET; 133049c55878SDavid Wu *reg += bank->bank_num * RK2928_PULL_BANK_STRIDE; 133149c55878SDavid Wu *reg += ((pin_num / RK2928_PULL_PINS_PER_REG) * 4); 133249c55878SDavid Wu 133349c55878SDavid Wu *bit = pin_num % RK2928_PULL_PINS_PER_REG; 133449c55878SDavid Wu } 133549c55878SDavid Wu 133649c55878SDavid Wu #define RK3188_PULL_OFFSET 0x164 133749c55878SDavid Wu #define RK3188_PULL_BITS_PER_PIN 2 133849c55878SDavid Wu #define RK3188_PULL_PINS_PER_REG 8 133949c55878SDavid Wu #define RK3188_PULL_BANK_STRIDE 16 134049c55878SDavid Wu #define RK3188_PULL_PMU_OFFSET 0x64 134149c55878SDavid Wu 134249c55878SDavid Wu static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 134349c55878SDavid Wu int pin_num, struct regmap **regmap, 134449c55878SDavid Wu int *reg, u8 *bit) 134549c55878SDavid Wu { 134649c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 134749c55878SDavid Wu 134849c55878SDavid Wu /* The first 12 pins of the first bank are located elsewhere */ 134949c55878SDavid Wu if (bank->bank_num == 0 && pin_num < 12) { 135049c55878SDavid Wu *regmap = priv->regmap_pmu; 135149c55878SDavid Wu *reg = RK3188_PULL_PMU_OFFSET; 135249c55878SDavid Wu 135349c55878SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 135449c55878SDavid Wu *bit = pin_num % RK3188_PULL_PINS_PER_REG; 135549c55878SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 135649c55878SDavid Wu } else { 135749c55878SDavid Wu *regmap = priv->regmap_base; 135849c55878SDavid Wu *reg = RK3188_PULL_OFFSET; 135949c55878SDavid Wu 136049c55878SDavid Wu /* correct the offset, as it is the 2nd pull register */ 136149c55878SDavid Wu *reg -= 4; 136249c55878SDavid Wu *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 136349c55878SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 136449c55878SDavid Wu 136549c55878SDavid Wu /* 136649c55878SDavid Wu * The bits in these registers have an inverse ordering 136749c55878SDavid Wu * with the lowest pin being in bits 15:14 and the highest 136849c55878SDavid Wu * pin in bits 1:0 136949c55878SDavid Wu */ 137049c55878SDavid Wu *bit = 7 - (pin_num % RK3188_PULL_PINS_PER_REG); 137149c55878SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 137249c55878SDavid Wu } 137349c55878SDavid Wu } 137449c55878SDavid Wu 137549c55878SDavid Wu #define RK3288_PULL_OFFSET 0x140 137649c55878SDavid Wu static void rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 137749c55878SDavid Wu int pin_num, struct regmap **regmap, 137849c55878SDavid Wu int *reg, u8 *bit) 137949c55878SDavid Wu { 138049c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 138149c55878SDavid Wu 138249c55878SDavid Wu /* The first 24 pins of the first bank are located in PMU */ 138349c55878SDavid Wu if (bank->bank_num == 0) { 138449c55878SDavid Wu *regmap = priv->regmap_pmu; 138549c55878SDavid Wu *reg = RK3188_PULL_PMU_OFFSET; 138649c55878SDavid Wu 138749c55878SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 138849c55878SDavid Wu *bit = pin_num % RK3188_PULL_PINS_PER_REG; 138949c55878SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 139049c55878SDavid Wu } else { 139149c55878SDavid Wu *regmap = priv->regmap_base; 139249c55878SDavid Wu *reg = RK3288_PULL_OFFSET; 139349c55878SDavid Wu 139449c55878SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 139549c55878SDavid Wu *reg -= 0x10; 139649c55878SDavid Wu *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 139749c55878SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 139849c55878SDavid Wu 139949c55878SDavid Wu *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 140049c55878SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 140149c55878SDavid Wu } 140249c55878SDavid Wu } 140349c55878SDavid Wu 140449c55878SDavid Wu #define RK3288_DRV_PMU_OFFSET 0x70 140549c55878SDavid Wu #define RK3288_DRV_GRF_OFFSET 0x1c0 140649c55878SDavid Wu #define RK3288_DRV_BITS_PER_PIN 2 140749c55878SDavid Wu #define RK3288_DRV_PINS_PER_REG 8 140849c55878SDavid Wu #define RK3288_DRV_BANK_STRIDE 16 140949c55878SDavid Wu 141049c55878SDavid Wu static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 141149c55878SDavid Wu int pin_num, struct regmap **regmap, 141249c55878SDavid Wu int *reg, u8 *bit) 141349c55878SDavid Wu { 141449c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 141549c55878SDavid Wu 141649c55878SDavid Wu /* The first 24 pins of the first bank are located in PMU */ 141749c55878SDavid Wu if (bank->bank_num == 0) { 141849c55878SDavid Wu *regmap = priv->regmap_pmu; 141949c55878SDavid Wu *reg = RK3288_DRV_PMU_OFFSET; 142049c55878SDavid Wu 142149c55878SDavid Wu *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 142249c55878SDavid Wu *bit = pin_num % RK3288_DRV_PINS_PER_REG; 142349c55878SDavid Wu *bit *= RK3288_DRV_BITS_PER_PIN; 142449c55878SDavid Wu } else { 142549c55878SDavid Wu *regmap = priv->regmap_base; 142649c55878SDavid Wu *reg = RK3288_DRV_GRF_OFFSET; 142749c55878SDavid Wu 142849c55878SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 142949c55878SDavid Wu *reg -= 0x10; 143049c55878SDavid Wu *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; 143149c55878SDavid Wu *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 143249c55878SDavid Wu 143349c55878SDavid Wu *bit = (pin_num % RK3288_DRV_PINS_PER_REG); 143449c55878SDavid Wu *bit *= RK3288_DRV_BITS_PER_PIN; 143549c55878SDavid Wu } 143649c55878SDavid Wu } 143749c55878SDavid Wu 143849c55878SDavid Wu #define RK3228_PULL_OFFSET 0x100 143949c55878SDavid Wu 144049c55878SDavid Wu static void rk3228_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 144149c55878SDavid Wu int pin_num, struct regmap **regmap, 144249c55878SDavid Wu int *reg, u8 *bit) 144349c55878SDavid Wu { 144449c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 144549c55878SDavid Wu 144649c55878SDavid Wu *regmap = priv->regmap_base; 144749c55878SDavid Wu *reg = RK3228_PULL_OFFSET; 144849c55878SDavid Wu *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 144949c55878SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 145049c55878SDavid Wu 145149c55878SDavid Wu *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 145249c55878SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 145349c55878SDavid Wu } 145449c55878SDavid Wu 145549c55878SDavid Wu #define RK3228_DRV_GRF_OFFSET 0x200 145649c55878SDavid Wu 145749c55878SDavid Wu static void rk3228_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 145849c55878SDavid Wu int pin_num, struct regmap **regmap, 145949c55878SDavid Wu int *reg, u8 *bit) 146049c55878SDavid Wu { 146149c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 146249c55878SDavid Wu 146349c55878SDavid Wu *regmap = priv->regmap_base; 146449c55878SDavid Wu *reg = RK3228_DRV_GRF_OFFSET; 146549c55878SDavid Wu *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; 146649c55878SDavid Wu *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 146749c55878SDavid Wu 146849c55878SDavid Wu *bit = (pin_num % RK3288_DRV_PINS_PER_REG); 146949c55878SDavid Wu *bit *= RK3288_DRV_BITS_PER_PIN; 147049c55878SDavid Wu } 147149c55878SDavid Wu 1472b3077611SDavid Wu #define RK3308_PULL_OFFSET 0xa0 1473b3077611SDavid Wu 1474b3077611SDavid Wu static void rk3308_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1475b3077611SDavid Wu int pin_num, struct regmap **regmap, 1476b3077611SDavid Wu int *reg, u8 *bit) 1477b3077611SDavid Wu { 1478b3077611SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 1479b3077611SDavid Wu 1480b3077611SDavid Wu *regmap = priv->regmap_base; 1481b3077611SDavid Wu *reg = RK3308_PULL_OFFSET; 1482b3077611SDavid Wu *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 1483b3077611SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 1484b3077611SDavid Wu 1485b3077611SDavid Wu *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 1486b3077611SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 1487b3077611SDavid Wu } 1488b3077611SDavid Wu 1489b3077611SDavid Wu #define RK3308_DRV_GRF_OFFSET 0x100 1490b3077611SDavid Wu 1491b3077611SDavid Wu static void rk3308_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 1492b3077611SDavid Wu int pin_num, struct regmap **regmap, 1493b3077611SDavid Wu int *reg, u8 *bit) 1494b3077611SDavid Wu { 1495b3077611SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 1496b3077611SDavid Wu 1497b3077611SDavid Wu *regmap = priv->regmap_base; 1498b3077611SDavid Wu *reg = RK3308_DRV_GRF_OFFSET; 1499b3077611SDavid Wu *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; 1500b3077611SDavid Wu *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 1501b3077611SDavid Wu 1502b3077611SDavid Wu *bit = (pin_num % RK3288_DRV_PINS_PER_REG); 1503b3077611SDavid Wu *bit *= RK3288_DRV_BITS_PER_PIN; 1504b3077611SDavid Wu } 1505b3077611SDavid Wu 1506b3077611SDavid Wu #define RK3308_SCHMITT_PINS_PER_REG 8 1507b3077611SDavid Wu #define RK3308_SCHMITT_BANK_STRIDE 16 1508b3077611SDavid Wu #define RK3308_SCHMITT_GRF_OFFSET 0x1a0 1509b3077611SDavid Wu 1510b3077611SDavid Wu static int rk3308_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 1511b3077611SDavid Wu int pin_num, 1512b3077611SDavid Wu struct regmap **regmap, 1513b3077611SDavid Wu int *reg, u8 *bit) 1514b3077611SDavid Wu { 1515b3077611SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 1516b3077611SDavid Wu 1517b3077611SDavid Wu *regmap = priv->regmap_base; 1518b3077611SDavid Wu *reg = RK3308_SCHMITT_GRF_OFFSET; 1519b3077611SDavid Wu 1520b3077611SDavid Wu *reg += bank->bank_num * RK3308_SCHMITT_BANK_STRIDE; 1521b3077611SDavid Wu *reg += ((pin_num / RK3308_SCHMITT_PINS_PER_REG) * 4); 1522b3077611SDavid Wu *bit = pin_num % RK3308_SCHMITT_PINS_PER_REG; 1523b3077611SDavid Wu 1524b3077611SDavid Wu return 0; 1525b3077611SDavid Wu } 1526b3077611SDavid Wu 152749c55878SDavid Wu #define RK3368_PULL_GRF_OFFSET 0x100 152849c55878SDavid Wu #define RK3368_PULL_PMU_OFFSET 0x10 152949c55878SDavid Wu 153049c55878SDavid Wu static void rk3368_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 153149c55878SDavid Wu int pin_num, struct regmap **regmap, 153249c55878SDavid Wu int *reg, u8 *bit) 153349c55878SDavid Wu { 153449c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 153549c55878SDavid Wu 153649c55878SDavid Wu /* The first 32 pins of the first bank are located in PMU */ 153749c55878SDavid Wu if (bank->bank_num == 0) { 153849c55878SDavid Wu *regmap = priv->regmap_pmu; 153949c55878SDavid Wu *reg = RK3368_PULL_PMU_OFFSET; 154049c55878SDavid Wu 154149c55878SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 154249c55878SDavid Wu *bit = pin_num % RK3188_PULL_PINS_PER_REG; 154349c55878SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 154449c55878SDavid Wu } else { 154549c55878SDavid Wu *regmap = priv->regmap_base; 154649c55878SDavid Wu *reg = RK3368_PULL_GRF_OFFSET; 154749c55878SDavid Wu 154849c55878SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 154949c55878SDavid Wu *reg -= 0x10; 155049c55878SDavid Wu *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 155149c55878SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 155249c55878SDavid Wu 155349c55878SDavid Wu *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 155449c55878SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 155549c55878SDavid Wu } 155649c55878SDavid Wu } 155749c55878SDavid Wu 155849c55878SDavid Wu #define RK3368_DRV_PMU_OFFSET 0x20 155949c55878SDavid Wu #define RK3368_DRV_GRF_OFFSET 0x200 156049c55878SDavid Wu 156149c55878SDavid Wu static void rk3368_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 156249c55878SDavid Wu int pin_num, struct regmap **regmap, 156349c55878SDavid Wu int *reg, u8 *bit) 156449c55878SDavid Wu { 156549c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 156649c55878SDavid Wu 156749c55878SDavid Wu /* The first 32 pins of the first bank are located in PMU */ 156849c55878SDavid Wu if (bank->bank_num == 0) { 156949c55878SDavid Wu *regmap = priv->regmap_pmu; 157049c55878SDavid Wu *reg = RK3368_DRV_PMU_OFFSET; 157149c55878SDavid Wu 157249c55878SDavid Wu *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 157349c55878SDavid Wu *bit = pin_num % RK3288_DRV_PINS_PER_REG; 157449c55878SDavid Wu *bit *= RK3288_DRV_BITS_PER_PIN; 157549c55878SDavid Wu } else { 157649c55878SDavid Wu *regmap = priv->regmap_base; 157749c55878SDavid Wu *reg = RK3368_DRV_GRF_OFFSET; 157849c55878SDavid Wu 157949c55878SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 158049c55878SDavid Wu *reg -= 0x10; 158149c55878SDavid Wu *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; 158249c55878SDavid Wu *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 158349c55878SDavid Wu 158449c55878SDavid Wu *bit = (pin_num % RK3288_DRV_PINS_PER_REG); 158549c55878SDavid Wu *bit *= RK3288_DRV_BITS_PER_PIN; 158649c55878SDavid Wu } 158749c55878SDavid Wu } 158849c55878SDavid Wu 158949c55878SDavid Wu #define RK3399_PULL_GRF_OFFSET 0xe040 159049c55878SDavid Wu #define RK3399_PULL_PMU_OFFSET 0x40 159149c55878SDavid Wu #define RK3399_DRV_3BITS_PER_PIN 3 159249c55878SDavid Wu 159349c55878SDavid Wu static void rk3399_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 159449c55878SDavid Wu int pin_num, struct regmap **regmap, 159549c55878SDavid Wu int *reg, u8 *bit) 159649c55878SDavid Wu { 159749c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 159849c55878SDavid Wu 159949c55878SDavid Wu /* The bank0:16 and bank1:32 pins are located in PMU */ 160049c55878SDavid Wu if ((bank->bank_num == 0) || (bank->bank_num == 1)) { 160149c55878SDavid Wu *regmap = priv->regmap_pmu; 160249c55878SDavid Wu *reg = RK3399_PULL_PMU_OFFSET; 160349c55878SDavid Wu 160449c55878SDavid Wu *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 160549c55878SDavid Wu 160649c55878SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 160749c55878SDavid Wu *bit = pin_num % RK3188_PULL_PINS_PER_REG; 160849c55878SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 160949c55878SDavid Wu } else { 161049c55878SDavid Wu *regmap = priv->regmap_base; 161149c55878SDavid Wu *reg = RK3399_PULL_GRF_OFFSET; 161249c55878SDavid Wu 161349c55878SDavid Wu /* correct the offset, as we're starting with the 3rd bank */ 161449c55878SDavid Wu *reg -= 0x20; 161549c55878SDavid Wu *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 161649c55878SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 161749c55878SDavid Wu 161849c55878SDavid Wu *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 161949c55878SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 162049c55878SDavid Wu } 162149c55878SDavid Wu } 162249c55878SDavid Wu 162349c55878SDavid Wu static void rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 162449c55878SDavid Wu int pin_num, struct regmap **regmap, 162549c55878SDavid Wu int *reg, u8 *bit) 162649c55878SDavid Wu { 162749c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 162849c55878SDavid Wu int drv_num = (pin_num / 8); 162949c55878SDavid Wu 163049c55878SDavid Wu /* The bank0:16 and bank1:32 pins are located in PMU */ 163149c55878SDavid Wu if ((bank->bank_num == 0) || (bank->bank_num == 1)) 163249c55878SDavid Wu *regmap = priv->regmap_pmu; 163349c55878SDavid Wu else 163449c55878SDavid Wu *regmap = priv->regmap_base; 163549c55878SDavid Wu 163649c55878SDavid Wu *reg = bank->drv[drv_num].offset; 163749c55878SDavid Wu if ((bank->drv[drv_num].drv_type == DRV_TYPE_IO_1V8_3V0_AUTO) || 163849c55878SDavid Wu (bank->drv[drv_num].drv_type == DRV_TYPE_IO_3V3_ONLY)) 163949c55878SDavid Wu *bit = (pin_num % 8) * 3; 164049c55878SDavid Wu else 164149c55878SDavid Wu *bit = (pin_num % 8) * 2; 164249c55878SDavid Wu } 164349c55878SDavid Wu 164449c55878SDavid Wu static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = { 164549c55878SDavid Wu { 2, 4, 8, 12, -1, -1, -1, -1 }, 164649c55878SDavid Wu { 3, 6, 9, 12, -1, -1, -1, -1 }, 164749c55878SDavid Wu { 5, 10, 15, 20, -1, -1, -1, -1 }, 164849c55878SDavid Wu { 4, 6, 8, 10, 12, 14, 16, 18 }, 164949c55878SDavid Wu { 4, 7, 10, 13, 16, 19, 22, 26 } 165049c55878SDavid Wu }; 165149c55878SDavid Wu 165249c55878SDavid Wu static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, 165349c55878SDavid Wu int pin_num, int strength) 165449c55878SDavid Wu { 165549c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 165649c55878SDavid Wu struct rockchip_pin_ctrl *ctrl = priv->ctrl; 165749c55878SDavid Wu struct regmap *regmap; 165849c55878SDavid Wu int reg, ret, i; 165949c55878SDavid Wu u32 data, rmask_bits, temp; 166049c55878SDavid Wu u8 bit; 166149c55878SDavid Wu int drv_type = bank->drv[pin_num / 8].drv_type; 166249c55878SDavid Wu 166349c55878SDavid Wu debug("setting drive of GPIO%d-%d to %d\n", bank->bank_num, 166449c55878SDavid Wu pin_num, strength); 166549c55878SDavid Wu 166649c55878SDavid Wu ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit); 166749c55878SDavid Wu 166849c55878SDavid Wu ret = -EINVAL; 166949c55878SDavid Wu for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list[drv_type]); i++) { 167049c55878SDavid Wu if (rockchip_perpin_drv_list[drv_type][i] == strength) { 167149c55878SDavid Wu ret = i; 167249c55878SDavid Wu break; 167349c55878SDavid Wu } else if (rockchip_perpin_drv_list[drv_type][i] < 0) { 167449c55878SDavid Wu ret = rockchip_perpin_drv_list[drv_type][i]; 167549c55878SDavid Wu break; 167649c55878SDavid Wu } 167749c55878SDavid Wu } 167849c55878SDavid Wu 167949c55878SDavid Wu if (ret < 0) { 168049c55878SDavid Wu debug("unsupported driver strength %d\n", strength); 168149c55878SDavid Wu return ret; 168249c55878SDavid Wu } 168349c55878SDavid Wu 168449c55878SDavid Wu switch (drv_type) { 168549c55878SDavid Wu case DRV_TYPE_IO_1V8_3V0_AUTO: 168649c55878SDavid Wu case DRV_TYPE_IO_3V3_ONLY: 168749c55878SDavid Wu rmask_bits = RK3399_DRV_3BITS_PER_PIN; 168849c55878SDavid Wu switch (bit) { 168949c55878SDavid Wu case 0 ... 12: 169049c55878SDavid Wu /* regular case, nothing to do */ 169149c55878SDavid Wu break; 169249c55878SDavid Wu case 15: 169349c55878SDavid Wu /* 169449c55878SDavid Wu * drive-strength offset is special, as it is spread 169549c55878SDavid Wu * over 2 registers, the bit data[15] contains bit 0 169649c55878SDavid Wu * of the value while temp[1:0] contains bits 2 and 1 169749c55878SDavid Wu */ 169849c55878SDavid Wu data = (ret & 0x1) << 15; 169949c55878SDavid Wu temp = (ret >> 0x1) & 0x3; 170049c55878SDavid Wu 170149c55878SDavid Wu data |= BIT(31); 170249c55878SDavid Wu ret = regmap_write(regmap, reg, data); 170349c55878SDavid Wu if (ret) 170449c55878SDavid Wu return ret; 170549c55878SDavid Wu 170649c55878SDavid Wu temp |= (0x3 << 16); 170749c55878SDavid Wu reg += 0x4; 170849c55878SDavid Wu ret = regmap_write(regmap, reg, temp); 170949c55878SDavid Wu 171049c55878SDavid Wu return ret; 171149c55878SDavid Wu case 18 ... 21: 171249c55878SDavid Wu /* setting fully enclosed in the second register */ 171349c55878SDavid Wu reg += 4; 171449c55878SDavid Wu bit -= 16; 171549c55878SDavid Wu break; 171649c55878SDavid Wu default: 171749c55878SDavid Wu debug("unsupported bit: %d for pinctrl drive type: %d\n", 171849c55878SDavid Wu bit, drv_type); 171949c55878SDavid Wu return -EINVAL; 172049c55878SDavid Wu } 172149c55878SDavid Wu break; 172249c55878SDavid Wu case DRV_TYPE_IO_DEFAULT: 172349c55878SDavid Wu case DRV_TYPE_IO_1V8_OR_3V0: 172449c55878SDavid Wu case DRV_TYPE_IO_1V8_ONLY: 172549c55878SDavid Wu rmask_bits = RK3288_DRV_BITS_PER_PIN; 172649c55878SDavid Wu break; 172749c55878SDavid Wu default: 172849c55878SDavid Wu debug("unsupported pinctrl drive type: %d\n", 172949c55878SDavid Wu drv_type); 173049c55878SDavid Wu return -EINVAL; 173149c55878SDavid Wu } 173249c55878SDavid Wu 173349c55878SDavid Wu /* enable the write to the equivalent lower bits */ 173449c55878SDavid Wu data = ((1 << rmask_bits) - 1) << (bit + 16); 173549c55878SDavid Wu data |= (ret << bit); 173649c55878SDavid Wu 173749c55878SDavid Wu ret = regmap_write(regmap, reg, data); 173849c55878SDavid Wu return ret; 173949c55878SDavid Wu } 174049c55878SDavid Wu 174149c55878SDavid Wu static int rockchip_pull_list[PULL_TYPE_MAX][4] = { 174249c55878SDavid Wu { 174349c55878SDavid Wu PIN_CONFIG_BIAS_DISABLE, 174449c55878SDavid Wu PIN_CONFIG_BIAS_PULL_UP, 174549c55878SDavid Wu PIN_CONFIG_BIAS_PULL_DOWN, 174649c55878SDavid Wu PIN_CONFIG_BIAS_BUS_HOLD 174749c55878SDavid Wu }, 174849c55878SDavid Wu { 174949c55878SDavid Wu PIN_CONFIG_BIAS_DISABLE, 175049c55878SDavid Wu PIN_CONFIG_BIAS_PULL_DOWN, 175149c55878SDavid Wu PIN_CONFIG_BIAS_DISABLE, 175249c55878SDavid Wu PIN_CONFIG_BIAS_PULL_UP 175349c55878SDavid Wu }, 175449c55878SDavid Wu }; 175549c55878SDavid Wu 175649c55878SDavid Wu static int rockchip_set_pull(struct rockchip_pin_bank *bank, 175749c55878SDavid Wu int pin_num, int pull) 175849c55878SDavid Wu { 175949c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 176049c55878SDavid Wu struct rockchip_pin_ctrl *ctrl = priv->ctrl; 176149c55878SDavid Wu struct regmap *regmap; 176249c55878SDavid Wu int reg, ret, i, pull_type; 176349c55878SDavid Wu u8 bit; 176449c55878SDavid Wu u32 data; 176549c55878SDavid Wu 176649c55878SDavid Wu debug("setting pull of GPIO%d-%d to %d\n", bank->bank_num, 176749c55878SDavid Wu pin_num, pull); 176849c55878SDavid Wu 176949c55878SDavid Wu /* rk3066b does support any pulls */ 177049c55878SDavid Wu if (ctrl->type == RK3066B) 177149c55878SDavid Wu return pull ? -EINVAL : 0; 177249c55878SDavid Wu 177349c55878SDavid Wu ctrl->pull_calc_reg(bank, pin_num, ®map, ®, &bit); 177449c55878SDavid Wu 177549c55878SDavid Wu switch (ctrl->type) { 177649c55878SDavid Wu case RK2928: 177749c55878SDavid Wu case RK3128: 177849c55878SDavid Wu data = BIT(bit + 16); 177949c55878SDavid Wu if (pull == PIN_CONFIG_BIAS_DISABLE) 178049c55878SDavid Wu data |= BIT(bit); 178149c55878SDavid Wu ret = regmap_write(regmap, reg, data); 178249c55878SDavid Wu break; 178349c55878SDavid Wu case PX30: 178449c55878SDavid Wu case RV1108: 178549c55878SDavid Wu case RK3188: 178649c55878SDavid Wu case RK3288: 1787b3077611SDavid Wu case RK3308: 178849c55878SDavid Wu case RK3368: 178949c55878SDavid Wu case RK3399: 179049c55878SDavid Wu pull_type = bank->pull_type[pin_num / 8]; 179149c55878SDavid Wu ret = -EINVAL; 179249c55878SDavid Wu for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[pull_type]); 179349c55878SDavid Wu i++) { 179449c55878SDavid Wu if (rockchip_pull_list[pull_type][i] == pull) { 179549c55878SDavid Wu ret = i; 179649c55878SDavid Wu break; 179749c55878SDavid Wu } 179849c55878SDavid Wu } 179949c55878SDavid Wu 180049c55878SDavid Wu if (ret < 0) { 180149c55878SDavid Wu debug("unsupported pull setting %d\n", pull); 180249c55878SDavid Wu return ret; 180349c55878SDavid Wu } 180449c55878SDavid Wu 180549c55878SDavid Wu /* enable the write to the equivalent lower bits */ 180649c55878SDavid Wu data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16); 180749c55878SDavid Wu data |= (ret << bit); 180849c55878SDavid Wu 180949c55878SDavid Wu ret = regmap_write(regmap, reg, data); 181049c55878SDavid Wu break; 181149c55878SDavid Wu default: 181249c55878SDavid Wu debug("unsupported pinctrl type\n"); 181349c55878SDavid Wu return -EINVAL; 181449c55878SDavid Wu } 181549c55878SDavid Wu 181649c55878SDavid Wu return ret; 181749c55878SDavid Wu } 181849c55878SDavid Wu 181949c55878SDavid Wu #define RK3328_SCHMITT_BITS_PER_PIN 1 182049c55878SDavid Wu #define RK3328_SCHMITT_PINS_PER_REG 16 182149c55878SDavid Wu #define RK3328_SCHMITT_BANK_STRIDE 8 182249c55878SDavid Wu #define RK3328_SCHMITT_GRF_OFFSET 0x380 182349c55878SDavid Wu 182449c55878SDavid Wu static int rk3328_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 182549c55878SDavid Wu int pin_num, 182649c55878SDavid Wu struct regmap **regmap, 182749c55878SDavid Wu int *reg, u8 *bit) 182849c55878SDavid Wu { 182949c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 183049c55878SDavid Wu 183149c55878SDavid Wu *regmap = priv->regmap_base; 183249c55878SDavid Wu *reg = RK3328_SCHMITT_GRF_OFFSET; 183349c55878SDavid Wu 183449c55878SDavid Wu *reg += bank->bank_num * RK3328_SCHMITT_BANK_STRIDE; 183549c55878SDavid Wu *reg += ((pin_num / RK3328_SCHMITT_PINS_PER_REG) * 4); 183649c55878SDavid Wu *bit = pin_num % RK3328_SCHMITT_PINS_PER_REG; 183749c55878SDavid Wu 183849c55878SDavid Wu return 0; 183949c55878SDavid Wu } 184049c55878SDavid Wu 184149c55878SDavid Wu static int rockchip_set_schmitt(struct rockchip_pin_bank *bank, 184249c55878SDavid Wu int pin_num, int enable) 184349c55878SDavid Wu { 184449c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 184549c55878SDavid Wu struct rockchip_pin_ctrl *ctrl = priv->ctrl; 184649c55878SDavid Wu struct regmap *regmap; 184749c55878SDavid Wu int reg, ret; 184849c55878SDavid Wu u8 bit; 184949c55878SDavid Wu u32 data; 185049c55878SDavid Wu 185149c55878SDavid Wu debug("setting input schmitt of GPIO%d-%d to %d\n", bank->bank_num, 185249c55878SDavid Wu pin_num, enable); 185349c55878SDavid Wu 185449c55878SDavid Wu ret = ctrl->schmitt_calc_reg(bank, pin_num, ®map, ®, &bit); 185549c55878SDavid Wu if (ret) 185649c55878SDavid Wu return ret; 185749c55878SDavid Wu 185849c55878SDavid Wu /* enable the write to the equivalent lower bits */ 185949c55878SDavid Wu data = BIT(bit + 16) | (enable << bit); 186049c55878SDavid Wu 186149c55878SDavid Wu return regmap_write(regmap, reg, data); 186249c55878SDavid Wu } 186349c55878SDavid Wu 186449c55878SDavid Wu /* 186549c55878SDavid Wu * Pinconf_ops handling 186649c55878SDavid Wu */ 186749c55878SDavid Wu static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, 186849c55878SDavid Wu unsigned int pull) 186949c55878SDavid Wu { 187049c55878SDavid Wu switch (ctrl->type) { 187149c55878SDavid Wu case RK2928: 187249c55878SDavid Wu case RK3128: 187349c55878SDavid Wu return (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT || 187449c55878SDavid Wu pull == PIN_CONFIG_BIAS_DISABLE); 187549c55878SDavid Wu case RK3066B: 187649c55878SDavid Wu return pull ? false : true; 187749c55878SDavid Wu case PX30: 187849c55878SDavid Wu case RV1108: 187949c55878SDavid Wu case RK3188: 188049c55878SDavid Wu case RK3288: 1881b3077611SDavid Wu case RK3308: 188249c55878SDavid Wu case RK3368: 188349c55878SDavid Wu case RK3399: 188449c55878SDavid Wu return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT); 188549c55878SDavid Wu } 188649c55878SDavid Wu 188749c55878SDavid Wu return false; 188849c55878SDavid Wu } 188949c55878SDavid Wu 189049c55878SDavid Wu /* set the pin config settings for a specified pin */ 189149c55878SDavid Wu static int rockchip_pinconf_set(struct rockchip_pin_bank *bank, 189249c55878SDavid Wu u32 pin, u32 param, u32 arg) 189349c55878SDavid Wu { 189449c55878SDavid Wu struct rockchip_pinctrl_priv *priv = bank->priv; 189549c55878SDavid Wu struct rockchip_pin_ctrl *ctrl = priv->ctrl; 189649c55878SDavid Wu int rc; 189749c55878SDavid Wu 189849c55878SDavid Wu switch (param) { 189949c55878SDavid Wu case PIN_CONFIG_BIAS_DISABLE: 190049c55878SDavid Wu rc = rockchip_set_pull(bank, pin, param); 190149c55878SDavid Wu if (rc) 190249c55878SDavid Wu return rc; 190349c55878SDavid Wu break; 190449c55878SDavid Wu 190549c55878SDavid Wu case PIN_CONFIG_BIAS_PULL_UP: 190649c55878SDavid Wu case PIN_CONFIG_BIAS_PULL_DOWN: 190749c55878SDavid Wu case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: 190849c55878SDavid Wu case PIN_CONFIG_BIAS_BUS_HOLD: 190949c55878SDavid Wu if (!rockchip_pinconf_pull_valid(ctrl, param)) 191049c55878SDavid Wu return -ENOTSUPP; 191149c55878SDavid Wu 191249c55878SDavid Wu if (!arg) 191349c55878SDavid Wu return -EINVAL; 191449c55878SDavid Wu 191549c55878SDavid Wu rc = rockchip_set_pull(bank, pin, param); 191649c55878SDavid Wu if (rc) 191749c55878SDavid Wu return rc; 191849c55878SDavid Wu break; 191949c55878SDavid Wu 192049c55878SDavid Wu case PIN_CONFIG_DRIVE_STRENGTH: 192149c55878SDavid Wu if (!ctrl->drv_calc_reg) 192249c55878SDavid Wu return -ENOTSUPP; 192349c55878SDavid Wu 192449c55878SDavid Wu rc = rockchip_set_drive_perpin(bank, pin, arg); 192549c55878SDavid Wu if (rc < 0) 192649c55878SDavid Wu return rc; 192749c55878SDavid Wu break; 192849c55878SDavid Wu 192949c55878SDavid Wu case PIN_CONFIG_INPUT_SCHMITT_ENABLE: 193049c55878SDavid Wu if (!ctrl->schmitt_calc_reg) 193149c55878SDavid Wu return -ENOTSUPP; 193249c55878SDavid Wu 193349c55878SDavid Wu rc = rockchip_set_schmitt(bank, pin, arg); 193449c55878SDavid Wu if (rc < 0) 193549c55878SDavid Wu return rc; 193649c55878SDavid Wu break; 193749c55878SDavid Wu 193849c55878SDavid Wu default: 193949c55878SDavid Wu break; 194049c55878SDavid Wu } 194149c55878SDavid Wu 194249c55878SDavid Wu return 0; 194349c55878SDavid Wu } 194449c55878SDavid Wu 194549c55878SDavid Wu static const struct pinconf_param rockchip_conf_params[] = { 194649c55878SDavid Wu { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, 194749c55878SDavid Wu { "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 }, 194849c55878SDavid Wu { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 }, 194949c55878SDavid Wu { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 }, 195049c55878SDavid Wu { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 }, 195149c55878SDavid Wu { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 }, 195249c55878SDavid Wu { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 }, 195349c55878SDavid Wu { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 }, 195449c55878SDavid Wu { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 }, 195549c55878SDavid Wu }; 195649c55878SDavid Wu 195749c55878SDavid Wu static int rockchip_pinconf_prop_name_to_param(const char *property, 195849c55878SDavid Wu u32 *default_value) 195949c55878SDavid Wu { 196049c55878SDavid Wu const struct pinconf_param *p, *end; 196149c55878SDavid Wu 196249c55878SDavid Wu p = rockchip_conf_params; 196349c55878SDavid Wu end = p + sizeof(rockchip_conf_params) / sizeof(struct pinconf_param); 196449c55878SDavid Wu 196549c55878SDavid Wu /* See if this pctldev supports this parameter */ 196649c55878SDavid Wu for (; p < end; p++) { 196749c55878SDavid Wu if (!strcmp(property, p->property)) { 196849c55878SDavid Wu *default_value = p->default_value; 196949c55878SDavid Wu return p->param; 197049c55878SDavid Wu } 197149c55878SDavid Wu } 197249c55878SDavid Wu 197349c55878SDavid Wu *default_value = 0; 197449c55878SDavid Wu return -EPERM; 197549c55878SDavid Wu } 197649c55878SDavid Wu 197749c55878SDavid Wu static int rockchip_pinctrl_set_state(struct udevice *dev, 197849c55878SDavid Wu struct udevice *config) 197949c55878SDavid Wu { 198049c55878SDavid Wu struct rockchip_pinctrl_priv *priv = dev_get_priv(dev); 198149c55878SDavid Wu struct rockchip_pin_ctrl *ctrl = priv->ctrl; 198249c55878SDavid Wu u32 cells[MAX_ROCKCHIP_PINS_ENTRIES * 4]; 198349c55878SDavid Wu u32 bank, pin, mux, conf, arg, default_val; 198449c55878SDavid Wu int ret, count, i; 198549c55878SDavid Wu const char *prop_name; 198649c55878SDavid Wu const void *value; 19872208cfa9SKever Yang int prop_len, param; 19882208cfa9SKever Yang const u32 *data; 19892208cfa9SKever Yang ofnode node; 19902208cfa9SKever Yang #ifdef CONFIG_OF_LIVE 19912208cfa9SKever Yang const struct device_node *np; 19922208cfa9SKever Yang struct property *pp; 19932208cfa9SKever Yang #else 19942208cfa9SKever Yang int property_offset, pcfg_node; 19952208cfa9SKever Yang const void *blob = gd->fdt_blob; 19962208cfa9SKever Yang #endif 19972208cfa9SKever Yang data = dev_read_prop(config, "rockchip,pins", &count); 199849c55878SDavid Wu if (count < 0) { 199987f0ac57SDavid Wu debug("%s: bad array size %d\n", __func__, count); 200049c55878SDavid Wu return -EINVAL; 200149c55878SDavid Wu } 200249c55878SDavid Wu 200387f0ac57SDavid Wu count /= sizeof(u32); 200449c55878SDavid Wu if (count > MAX_ROCKCHIP_PINS_ENTRIES * 4) { 200549c55878SDavid Wu debug("%s: unsupported pins array count %d\n", 200649c55878SDavid Wu __func__, count); 200749c55878SDavid Wu return -EINVAL; 200849c55878SDavid Wu } 200949c55878SDavid Wu 201087f0ac57SDavid Wu for (i = 0; i < count; i++) 201187f0ac57SDavid Wu cells[i] = fdt32_to_cpu(data[i]); 201287f0ac57SDavid Wu 201349c55878SDavid Wu for (i = 0; i < (count >> 2); i++) { 201449c55878SDavid Wu bank = cells[4 * i + 0]; 201549c55878SDavid Wu pin = cells[4 * i + 1]; 201649c55878SDavid Wu mux = cells[4 * i + 2]; 201749c55878SDavid Wu conf = cells[4 * i + 3]; 201849c55878SDavid Wu 201949c55878SDavid Wu ret = rockchip_verify_config(dev, bank, pin); 202049c55878SDavid Wu if (ret) 202149c55878SDavid Wu return ret; 202249c55878SDavid Wu 202349c55878SDavid Wu ret = rockchip_set_mux(&ctrl->pin_banks[bank], pin, mux); 202449c55878SDavid Wu if (ret) 202549c55878SDavid Wu return ret; 202649c55878SDavid Wu 20272208cfa9SKever Yang node = ofnode_get_by_phandle(conf); 20282208cfa9SKever Yang if (!ofnode_valid(node)) 202949c55878SDavid Wu return -ENODEV; 20302208cfa9SKever Yang #ifdef CONFIG_OF_LIVE 20312208cfa9SKever Yang np = ofnode_to_np(node); 20322208cfa9SKever Yang for (pp = np->properties; pp; pp = pp->next) { 20332208cfa9SKever Yang prop_name = pp->name; 20342208cfa9SKever Yang prop_len = pp->length; 20352208cfa9SKever Yang value = pp->value; 20362208cfa9SKever Yang #else 20372208cfa9SKever Yang pcfg_node = ofnode_to_offset(node); 203849c55878SDavid Wu fdt_for_each_property_offset(property_offset, blob, pcfg_node) { 203949c55878SDavid Wu value = fdt_getprop_by_offset(blob, property_offset, 204049c55878SDavid Wu &prop_name, &prop_len); 204149c55878SDavid Wu if (!value) 204249c55878SDavid Wu return -ENOENT; 20432208cfa9SKever Yang #endif 204449c55878SDavid Wu param = rockchip_pinconf_prop_name_to_param(prop_name, 204549c55878SDavid Wu &default_val); 204649c55878SDavid Wu if (param < 0) 204749c55878SDavid Wu break; 204849c55878SDavid Wu 204949c55878SDavid Wu if (prop_len >= sizeof(fdt32_t)) 205049c55878SDavid Wu arg = fdt32_to_cpu(*(fdt32_t *)value); 205149c55878SDavid Wu else 205249c55878SDavid Wu arg = default_val; 205349c55878SDavid Wu 205449c55878SDavid Wu ret = rockchip_pinconf_set(&ctrl->pin_banks[bank], pin, 205549c55878SDavid Wu param, arg); 205649c55878SDavid Wu if (ret) { 205749c55878SDavid Wu debug("%s: rockchip_pinconf_set fail: %d\n", 205849c55878SDavid Wu __func__, ret); 205949c55878SDavid Wu return ret; 206049c55878SDavid Wu } 206149c55878SDavid Wu } 206249c55878SDavid Wu } 206349c55878SDavid Wu 206449c55878SDavid Wu return 0; 206549c55878SDavid Wu } 206649c55878SDavid Wu 206749c55878SDavid Wu static struct pinctrl_ops rockchip_pinctrl_ops = { 206849c55878SDavid Wu .set_state = rockchip_pinctrl_set_state, 206949c55878SDavid Wu .get_gpio_mux = rockchip_pinctrl_get_gpio_mux, 207049c55878SDavid Wu }; 207149c55878SDavid Wu 207249c55878SDavid Wu /* retrieve the soc specific data */ 207349c55878SDavid Wu static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *dev) 207449c55878SDavid Wu { 207549c55878SDavid Wu struct rockchip_pinctrl_priv *priv = dev_get_priv(dev); 207649c55878SDavid Wu struct rockchip_pin_ctrl *ctrl = 207749c55878SDavid Wu (struct rockchip_pin_ctrl *)dev_get_driver_data(dev); 207849c55878SDavid Wu struct rockchip_pin_bank *bank; 207949c55878SDavid Wu int grf_offs, pmu_offs, drv_grf_offs, drv_pmu_offs, i, j; 208049c55878SDavid Wu 208149c55878SDavid Wu grf_offs = ctrl->grf_mux_offset; 208249c55878SDavid Wu pmu_offs = ctrl->pmu_mux_offset; 208349c55878SDavid Wu drv_pmu_offs = ctrl->pmu_drv_offset; 208449c55878SDavid Wu drv_grf_offs = ctrl->grf_drv_offset; 208549c55878SDavid Wu bank = ctrl->pin_banks; 208649c55878SDavid Wu 208749c55878SDavid Wu for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { 208849c55878SDavid Wu int bank_pins = 0; 208949c55878SDavid Wu 209049c55878SDavid Wu bank->priv = priv; 209149c55878SDavid Wu bank->pin_base = ctrl->nr_pins; 209249c55878SDavid Wu ctrl->nr_pins += bank->nr_pins; 209349c55878SDavid Wu 209449c55878SDavid Wu /* calculate iomux and drv offsets */ 209549c55878SDavid Wu for (j = 0; j < 4; j++) { 209649c55878SDavid Wu struct rockchip_iomux *iom = &bank->iomux[j]; 209749c55878SDavid Wu struct rockchip_drv *drv = &bank->drv[j]; 209849c55878SDavid Wu int inc; 209949c55878SDavid Wu 210049c55878SDavid Wu if (bank_pins >= bank->nr_pins) 210149c55878SDavid Wu break; 210249c55878SDavid Wu 210349c55878SDavid Wu /* preset iomux offset value, set new start value */ 210449c55878SDavid Wu if (iom->offset >= 0) { 210549c55878SDavid Wu if (iom->type & IOMUX_SOURCE_PMU) 210649c55878SDavid Wu pmu_offs = iom->offset; 210749c55878SDavid Wu else 210849c55878SDavid Wu grf_offs = iom->offset; 210949c55878SDavid Wu } else { /* set current iomux offset */ 211049c55878SDavid Wu iom->offset = (iom->type & IOMUX_SOURCE_PMU) ? 211149c55878SDavid Wu pmu_offs : grf_offs; 211249c55878SDavid Wu } 211349c55878SDavid Wu 211449c55878SDavid Wu /* preset drv offset value, set new start value */ 211549c55878SDavid Wu if (drv->offset >= 0) { 211649c55878SDavid Wu if (iom->type & IOMUX_SOURCE_PMU) 211749c55878SDavid Wu drv_pmu_offs = drv->offset; 211849c55878SDavid Wu else 211949c55878SDavid Wu drv_grf_offs = drv->offset; 212049c55878SDavid Wu } else { /* set current drv offset */ 212149c55878SDavid Wu drv->offset = (iom->type & IOMUX_SOURCE_PMU) ? 212249c55878SDavid Wu drv_pmu_offs : drv_grf_offs; 212349c55878SDavid Wu } 212449c55878SDavid Wu 212549c55878SDavid Wu debug("bank %d, iomux %d has iom_offset 0x%x drv_offset 0x%x\n", 212649c55878SDavid Wu i, j, iom->offset, drv->offset); 212749c55878SDavid Wu 212849c55878SDavid Wu /* 212949c55878SDavid Wu * Increase offset according to iomux width. 213049c55878SDavid Wu * 4bit iomux'es are spread over two registers. 213149c55878SDavid Wu */ 213249c55878SDavid Wu inc = (iom->type & (IOMUX_WIDTH_4BIT | 2133*88a1f7ffSDavid Wu IOMUX_WIDTH_3BIT | 2134*88a1f7ffSDavid Wu IOMUX_8WIDTH_2BIT)) ? 8 : 4; 213549c55878SDavid Wu if (iom->type & IOMUX_SOURCE_PMU) 213649c55878SDavid Wu pmu_offs += inc; 213749c55878SDavid Wu else 213849c55878SDavid Wu grf_offs += inc; 213949c55878SDavid Wu 214049c55878SDavid Wu /* 214149c55878SDavid Wu * Increase offset according to drv width. 214249c55878SDavid Wu * 3bit drive-strenth'es are spread over two registers. 214349c55878SDavid Wu */ 214449c55878SDavid Wu if ((drv->drv_type == DRV_TYPE_IO_1V8_3V0_AUTO) || 214549c55878SDavid Wu (drv->drv_type == DRV_TYPE_IO_3V3_ONLY)) 214649c55878SDavid Wu inc = 8; 214749c55878SDavid Wu else 214849c55878SDavid Wu inc = 4; 214949c55878SDavid Wu 215049c55878SDavid Wu if (iom->type & IOMUX_SOURCE_PMU) 215149c55878SDavid Wu drv_pmu_offs += inc; 215249c55878SDavid Wu else 215349c55878SDavid Wu drv_grf_offs += inc; 215449c55878SDavid Wu 215549c55878SDavid Wu bank_pins += 8; 215649c55878SDavid Wu } 215749c55878SDavid Wu 215849c55878SDavid Wu /* calculate the per-bank recalced_mask */ 215949c55878SDavid Wu for (j = 0; j < ctrl->niomux_recalced; j++) { 216049c55878SDavid Wu int pin = 0; 216149c55878SDavid Wu 216249c55878SDavid Wu if (ctrl->iomux_recalced[j].num == bank->bank_num) { 216349c55878SDavid Wu pin = ctrl->iomux_recalced[j].pin; 216449c55878SDavid Wu bank->recalced_mask |= BIT(pin); 216549c55878SDavid Wu } 216649c55878SDavid Wu } 216749c55878SDavid Wu 216849c55878SDavid Wu /* calculate the per-bank route_mask */ 216949c55878SDavid Wu for (j = 0; j < ctrl->niomux_routes; j++) { 217049c55878SDavid Wu int pin = 0; 217149c55878SDavid Wu 217249c55878SDavid Wu if (ctrl->iomux_routes[j].bank_num == bank->bank_num) { 217349c55878SDavid Wu pin = ctrl->iomux_routes[j].pin; 217449c55878SDavid Wu bank->route_mask |= BIT(pin); 217549c55878SDavid Wu } 217649c55878SDavid Wu } 217749c55878SDavid Wu } 217849c55878SDavid Wu 217949c55878SDavid Wu return ctrl; 218049c55878SDavid Wu } 218149c55878SDavid Wu 218249c55878SDavid Wu static int rockchip_pinctrl_probe(struct udevice *dev) 218349c55878SDavid Wu { 218449c55878SDavid Wu struct rockchip_pinctrl_priv *priv = dev_get_priv(dev); 218549c55878SDavid Wu struct rockchip_pin_ctrl *ctrl; 218649c55878SDavid Wu struct udevice *syscon; 218749c55878SDavid Wu struct regmap *regmap; 218849c55878SDavid Wu int ret = 0; 218949c55878SDavid Wu 219049c55878SDavid Wu /* get rockchip grf syscon phandle */ 219149c55878SDavid Wu ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,grf", 219249c55878SDavid Wu &syscon); 219349c55878SDavid Wu if (ret) { 219449c55878SDavid Wu debug("unable to find rockchip,grf syscon device (%d)\n", ret); 219549c55878SDavid Wu return ret; 219649c55878SDavid Wu } 219749c55878SDavid Wu 219849c55878SDavid Wu /* get grf-reg base address */ 219949c55878SDavid Wu regmap = syscon_get_regmap(syscon); 220049c55878SDavid Wu if (!regmap) { 220149c55878SDavid Wu debug("unable to find rockchip grf regmap\n"); 220249c55878SDavid Wu return -ENODEV; 220349c55878SDavid Wu } 220449c55878SDavid Wu priv->regmap_base = regmap; 220549c55878SDavid Wu 220649c55878SDavid Wu /* option: get pmu-reg base address */ 220749c55878SDavid Wu ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,pmu", 220849c55878SDavid Wu &syscon); 220949c55878SDavid Wu if (!ret) { 221049c55878SDavid Wu /* get pmugrf-reg base address */ 221149c55878SDavid Wu regmap = syscon_get_regmap(syscon); 221249c55878SDavid Wu if (!regmap) { 221349c55878SDavid Wu debug("unable to find rockchip pmu regmap\n"); 221449c55878SDavid Wu return -ENODEV; 221549c55878SDavid Wu } 221649c55878SDavid Wu priv->regmap_pmu = regmap; 221749c55878SDavid Wu } 221849c55878SDavid Wu 221949c55878SDavid Wu ctrl = rockchip_pinctrl_get_soc_data(dev); 222049c55878SDavid Wu if (!ctrl) { 222149c55878SDavid Wu debug("driver data not available\n"); 222249c55878SDavid Wu return -EINVAL; 222349c55878SDavid Wu } 222449c55878SDavid Wu 222549c55878SDavid Wu priv->ctrl = ctrl; 222649c55878SDavid Wu return 0; 222749c55878SDavid Wu } 222849c55878SDavid Wu 222949c55878SDavid Wu static struct rockchip_pin_bank px30_pin_banks[] = { 223049c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, 223149c55878SDavid Wu IOMUX_SOURCE_PMU, 223249c55878SDavid Wu IOMUX_SOURCE_PMU, 223349c55878SDavid Wu IOMUX_SOURCE_PMU 223449c55878SDavid Wu ), 223549c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, 223649c55878SDavid Wu IOMUX_WIDTH_4BIT, 223749c55878SDavid Wu IOMUX_WIDTH_4BIT, 223849c55878SDavid Wu IOMUX_WIDTH_4BIT 223949c55878SDavid Wu ), 224049c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, 224149c55878SDavid Wu IOMUX_WIDTH_4BIT, 224249c55878SDavid Wu IOMUX_WIDTH_4BIT, 224349c55878SDavid Wu IOMUX_WIDTH_4BIT 224449c55878SDavid Wu ), 224549c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, 224649c55878SDavid Wu IOMUX_WIDTH_4BIT, 224749c55878SDavid Wu IOMUX_WIDTH_4BIT, 224849c55878SDavid Wu IOMUX_WIDTH_4BIT 224949c55878SDavid Wu ), 225049c55878SDavid Wu }; 225149c55878SDavid Wu 225249c55878SDavid Wu static struct rockchip_pin_ctrl px30_pin_ctrl = { 225349c55878SDavid Wu .pin_banks = px30_pin_banks, 225449c55878SDavid Wu .nr_banks = ARRAY_SIZE(px30_pin_banks), 225549c55878SDavid Wu .label = "PX30-GPIO", 225649c55878SDavid Wu .type = PX30, 225749c55878SDavid Wu .grf_mux_offset = 0x0, 225849c55878SDavid Wu .pmu_mux_offset = 0x0, 225949c55878SDavid Wu .iomux_routes = px30_mux_route_data, 226049c55878SDavid Wu .niomux_routes = ARRAY_SIZE(px30_mux_route_data), 226149c55878SDavid Wu .pull_calc_reg = px30_calc_pull_reg_and_bit, 226249c55878SDavid Wu .drv_calc_reg = px30_calc_drv_reg_and_bit, 226349c55878SDavid Wu .schmitt_calc_reg = px30_calc_schmitt_reg_and_bit, 226449c55878SDavid Wu }; 226549c55878SDavid Wu 226649c55878SDavid Wu static struct rockchip_pin_bank rv1108_pin_banks[] = { 226749c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, 226849c55878SDavid Wu IOMUX_SOURCE_PMU, 226949c55878SDavid Wu IOMUX_SOURCE_PMU, 227049c55878SDavid Wu IOMUX_SOURCE_PMU), 227149c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0), 227249c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, 0), 227349c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, 0), 227449c55878SDavid Wu }; 227549c55878SDavid Wu 227649c55878SDavid Wu static struct rockchip_pin_ctrl rv1108_pin_ctrl = { 227749c55878SDavid Wu .pin_banks = rv1108_pin_banks, 227849c55878SDavid Wu .nr_banks = ARRAY_SIZE(rv1108_pin_banks), 227949c55878SDavid Wu .label = "RV1108-GPIO", 228049c55878SDavid Wu .type = RV1108, 228149c55878SDavid Wu .grf_mux_offset = 0x10, 228249c55878SDavid Wu .pmu_mux_offset = 0x0, 228349c55878SDavid Wu .iomux_recalced = rv1108_mux_recalced_data, 228449c55878SDavid Wu .niomux_recalced = ARRAY_SIZE(rv1108_mux_recalced_data), 228549c55878SDavid Wu .pull_calc_reg = rv1108_calc_pull_reg_and_bit, 228649c55878SDavid Wu .drv_calc_reg = rv1108_calc_drv_reg_and_bit, 228749c55878SDavid Wu .schmitt_calc_reg = rv1108_calc_schmitt_reg_and_bit, 228849c55878SDavid Wu }; 228949c55878SDavid Wu 229049c55878SDavid Wu static struct rockchip_pin_bank rk2928_pin_banks[] = { 229149c55878SDavid Wu PIN_BANK(0, 32, "gpio0"), 229249c55878SDavid Wu PIN_BANK(1, 32, "gpio1"), 229349c55878SDavid Wu PIN_BANK(2, 32, "gpio2"), 229449c55878SDavid Wu PIN_BANK(3, 32, "gpio3"), 229549c55878SDavid Wu }; 229649c55878SDavid Wu 229749c55878SDavid Wu static struct rockchip_pin_ctrl rk2928_pin_ctrl = { 229849c55878SDavid Wu .pin_banks = rk2928_pin_banks, 229949c55878SDavid Wu .nr_banks = ARRAY_SIZE(rk2928_pin_banks), 230049c55878SDavid Wu .label = "RK2928-GPIO", 230149c55878SDavid Wu .type = RK2928, 230249c55878SDavid Wu .grf_mux_offset = 0xa8, 230349c55878SDavid Wu .pull_calc_reg = rk2928_calc_pull_reg_and_bit, 230449c55878SDavid Wu }; 230549c55878SDavid Wu 230649c55878SDavid Wu static struct rockchip_pin_bank rk3036_pin_banks[] = { 230749c55878SDavid Wu PIN_BANK(0, 32, "gpio0"), 230849c55878SDavid Wu PIN_BANK(1, 32, "gpio1"), 230949c55878SDavid Wu PIN_BANK(2, 32, "gpio2"), 231049c55878SDavid Wu }; 231149c55878SDavid Wu 231249c55878SDavid Wu static struct rockchip_pin_ctrl rk3036_pin_ctrl = { 231349c55878SDavid Wu .pin_banks = rk3036_pin_banks, 231449c55878SDavid Wu .nr_banks = ARRAY_SIZE(rk3036_pin_banks), 231549c55878SDavid Wu .label = "RK3036-GPIO", 231649c55878SDavid Wu .type = RK2928, 231749c55878SDavid Wu .grf_mux_offset = 0xa8, 231849c55878SDavid Wu .pull_calc_reg = rk2928_calc_pull_reg_and_bit, 231949c55878SDavid Wu }; 232049c55878SDavid Wu 232149c55878SDavid Wu static struct rockchip_pin_bank rk3066a_pin_banks[] = { 232249c55878SDavid Wu PIN_BANK(0, 32, "gpio0"), 232349c55878SDavid Wu PIN_BANK(1, 32, "gpio1"), 232449c55878SDavid Wu PIN_BANK(2, 32, "gpio2"), 232549c55878SDavid Wu PIN_BANK(3, 32, "gpio3"), 232649c55878SDavid Wu PIN_BANK(4, 32, "gpio4"), 232749c55878SDavid Wu PIN_BANK(6, 16, "gpio6"), 232849c55878SDavid Wu }; 232949c55878SDavid Wu 233049c55878SDavid Wu static struct rockchip_pin_ctrl rk3066a_pin_ctrl = { 233149c55878SDavid Wu .pin_banks = rk3066a_pin_banks, 233249c55878SDavid Wu .nr_banks = ARRAY_SIZE(rk3066a_pin_banks), 233349c55878SDavid Wu .label = "RK3066a-GPIO", 233449c55878SDavid Wu .type = RK2928, 233549c55878SDavid Wu .grf_mux_offset = 0xa8, 233649c55878SDavid Wu .pull_calc_reg = rk2928_calc_pull_reg_and_bit, 233749c55878SDavid Wu }; 233849c55878SDavid Wu 233949c55878SDavid Wu static struct rockchip_pin_bank rk3066b_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 rk3066b_pin_ctrl = { 234749c55878SDavid Wu .pin_banks = rk3066b_pin_banks, 234849c55878SDavid Wu .nr_banks = ARRAY_SIZE(rk3066b_pin_banks), 234949c55878SDavid Wu .label = "RK3066b-GPIO", 235049c55878SDavid Wu .type = RK3066B, 235149c55878SDavid Wu .grf_mux_offset = 0x60, 235249c55878SDavid Wu }; 235349c55878SDavid Wu 235449c55878SDavid Wu static struct rockchip_pin_bank rk3128_pin_banks[] = { 235549c55878SDavid Wu PIN_BANK(0, 32, "gpio0"), 235649c55878SDavid Wu PIN_BANK(1, 32, "gpio1"), 235749c55878SDavid Wu PIN_BANK(2, 32, "gpio2"), 235849c55878SDavid Wu PIN_BANK(3, 32, "gpio3"), 235949c55878SDavid Wu }; 236049c55878SDavid Wu 236149c55878SDavid Wu static struct rockchip_pin_ctrl rk3128_pin_ctrl = { 236249c55878SDavid Wu .pin_banks = rk3128_pin_banks, 236349c55878SDavid Wu .nr_banks = ARRAY_SIZE(rk3128_pin_banks), 236449c55878SDavid Wu .label = "RK3128-GPIO", 236549c55878SDavid Wu .type = RK3128, 236649c55878SDavid Wu .grf_mux_offset = 0xa8, 236749c55878SDavid Wu .iomux_recalced = rk3128_mux_recalced_data, 236849c55878SDavid Wu .niomux_recalced = ARRAY_SIZE(rk3128_mux_recalced_data), 236949c55878SDavid Wu .iomux_routes = rk3128_mux_route_data, 237049c55878SDavid Wu .niomux_routes = ARRAY_SIZE(rk3128_mux_route_data), 237149c55878SDavid Wu .pull_calc_reg = rk3128_calc_pull_reg_and_bit, 237249c55878SDavid Wu }; 237349c55878SDavid Wu 237449c55878SDavid Wu static struct rockchip_pin_bank rk3188_pin_banks[] = { 237549c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_GPIO_ONLY, 0, 0, 0), 237649c55878SDavid Wu PIN_BANK(1, 32, "gpio1"), 237749c55878SDavid Wu PIN_BANK(2, 32, "gpio2"), 237849c55878SDavid Wu PIN_BANK(3, 32, "gpio3"), 237949c55878SDavid Wu }; 238049c55878SDavid Wu 238149c55878SDavid Wu static struct rockchip_pin_ctrl rk3188_pin_ctrl = { 238249c55878SDavid Wu .pin_banks = rk3188_pin_banks, 238349c55878SDavid Wu .nr_banks = ARRAY_SIZE(rk3188_pin_banks), 238449c55878SDavid Wu .label = "RK3188-GPIO", 238549c55878SDavid Wu .type = RK3188, 238649c55878SDavid Wu .grf_mux_offset = 0x60, 238749c55878SDavid Wu .pull_calc_reg = rk3188_calc_pull_reg_and_bit, 238849c55878SDavid Wu }; 238949c55878SDavid Wu 239049c55878SDavid Wu static struct rockchip_pin_bank rk3228_pin_banks[] = { 239149c55878SDavid Wu PIN_BANK(0, 32, "gpio0"), 239249c55878SDavid Wu PIN_BANK(1, 32, "gpio1"), 239349c55878SDavid Wu PIN_BANK(2, 32, "gpio2"), 239449c55878SDavid Wu PIN_BANK(3, 32, "gpio3"), 239549c55878SDavid Wu }; 239649c55878SDavid Wu 239749c55878SDavid Wu static struct rockchip_pin_ctrl rk3228_pin_ctrl = { 239849c55878SDavid Wu .pin_banks = rk3228_pin_banks, 239949c55878SDavid Wu .nr_banks = ARRAY_SIZE(rk3228_pin_banks), 240049c55878SDavid Wu .label = "RK3228-GPIO", 240149c55878SDavid Wu .type = RK3288, 240249c55878SDavid Wu .grf_mux_offset = 0x0, 240349c55878SDavid Wu .iomux_routes = rk3228_mux_route_data, 240449c55878SDavid Wu .niomux_routes = ARRAY_SIZE(rk3228_mux_route_data), 240549c55878SDavid Wu .pull_calc_reg = rk3228_calc_pull_reg_and_bit, 240649c55878SDavid Wu .drv_calc_reg = rk3228_calc_drv_reg_and_bit, 240749c55878SDavid Wu }; 240849c55878SDavid Wu 240949c55878SDavid Wu static struct rockchip_pin_bank rk3288_pin_banks[] = { 241049c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(0, 24, "gpio0", IOMUX_SOURCE_PMU, 241149c55878SDavid Wu IOMUX_SOURCE_PMU, 241249c55878SDavid Wu IOMUX_SOURCE_PMU, 241349c55878SDavid Wu IOMUX_UNROUTED 241449c55878SDavid Wu ), 241549c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_UNROUTED, 241649c55878SDavid Wu IOMUX_UNROUTED, 241749c55878SDavid Wu IOMUX_UNROUTED, 241849c55878SDavid Wu 0 241949c55878SDavid Wu ), 242049c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, IOMUX_UNROUTED), 242149c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, IOMUX_WIDTH_4BIT), 242249c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, 242349c55878SDavid Wu IOMUX_WIDTH_4BIT, 242449c55878SDavid Wu 0, 242549c55878SDavid Wu 0 242649c55878SDavid Wu ), 242749c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(5, 32, "gpio5", IOMUX_UNROUTED, 242849c55878SDavid Wu 0, 242949c55878SDavid Wu 0, 243049c55878SDavid Wu IOMUX_UNROUTED 243149c55878SDavid Wu ), 243249c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(6, 32, "gpio6", 0, 0, 0, IOMUX_UNROUTED), 243349c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(7, 32, "gpio7", 0, 243449c55878SDavid Wu 0, 243549c55878SDavid Wu IOMUX_WIDTH_4BIT, 243649c55878SDavid Wu IOMUX_UNROUTED 243749c55878SDavid Wu ), 243849c55878SDavid Wu PIN_BANK(8, 16, "gpio8"), 243949c55878SDavid Wu }; 244049c55878SDavid Wu 244149c55878SDavid Wu static struct rockchip_pin_ctrl rk3288_pin_ctrl = { 244249c55878SDavid Wu .pin_banks = rk3288_pin_banks, 244349c55878SDavid Wu .nr_banks = ARRAY_SIZE(rk3288_pin_banks), 244449c55878SDavid Wu .label = "RK3288-GPIO", 244549c55878SDavid Wu .type = RK3288, 244649c55878SDavid Wu .grf_mux_offset = 0x0, 244749c55878SDavid Wu .pmu_mux_offset = 0x84, 244849c55878SDavid Wu .iomux_routes = rk3288_mux_route_data, 244949c55878SDavid Wu .niomux_routes = ARRAY_SIZE(rk3288_mux_route_data), 245049c55878SDavid Wu .pull_calc_reg = rk3288_calc_pull_reg_and_bit, 245149c55878SDavid Wu .drv_calc_reg = rk3288_calc_drv_reg_and_bit, 245249c55878SDavid Wu }; 245349c55878SDavid Wu 2454b3077611SDavid Wu static struct rockchip_pin_bank rk3308_pin_banks[] = { 2455b3077611SDavid Wu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_8WIDTH_2BIT, 2456b3077611SDavid Wu IOMUX_8WIDTH_2BIT, 2457b3077611SDavid Wu IOMUX_8WIDTH_2BIT, 2458b3077611SDavid Wu IOMUX_8WIDTH_2BIT), 2459b3077611SDavid Wu PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_8WIDTH_2BIT, 2460b3077611SDavid Wu IOMUX_8WIDTH_2BIT, 2461b3077611SDavid Wu IOMUX_8WIDTH_2BIT, 2462b3077611SDavid Wu IOMUX_8WIDTH_2BIT), 2463b3077611SDavid Wu PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_8WIDTH_2BIT, 2464b3077611SDavid Wu IOMUX_8WIDTH_2BIT, 2465b3077611SDavid Wu IOMUX_8WIDTH_2BIT, 2466b3077611SDavid Wu IOMUX_8WIDTH_2BIT), 2467b3077611SDavid Wu PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_8WIDTH_2BIT, 2468b3077611SDavid Wu IOMUX_8WIDTH_2BIT, 2469b3077611SDavid Wu IOMUX_8WIDTH_2BIT, 2470b3077611SDavid Wu IOMUX_8WIDTH_2BIT), 2471b3077611SDavid Wu PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_8WIDTH_2BIT, 2472b3077611SDavid Wu IOMUX_8WIDTH_2BIT, 2473b3077611SDavid Wu IOMUX_8WIDTH_2BIT, 2474b3077611SDavid Wu IOMUX_8WIDTH_2BIT), 2475b3077611SDavid Wu }; 2476b3077611SDavid Wu 2477b3077611SDavid Wu static struct rockchip_pin_ctrl rk3308_pin_ctrl = { 2478b3077611SDavid Wu .pin_banks = rk3308_pin_banks, 2479b3077611SDavid Wu .nr_banks = ARRAY_SIZE(rk3308_pin_banks), 2480b3077611SDavid Wu .label = "RK3308-GPIO", 2481b3077611SDavid Wu .type = RK3308, 2482b3077611SDavid Wu .grf_mux_offset = 0x0, 2483b3077611SDavid Wu .iomux_recalced = rk3308_mux_recalced_data, 2484b3077611SDavid Wu .niomux_recalced = ARRAY_SIZE(rk3308_mux_recalced_data), 2485b3077611SDavid Wu .iomux_routes = rk3308_mux_route_data, 2486b3077611SDavid Wu .niomux_routes = ARRAY_SIZE(rk3308_mux_route_data), 2487b3077611SDavid Wu .pull_calc_reg = rk3308_calc_pull_reg_and_bit, 2488b3077611SDavid Wu .drv_calc_reg = rk3308_calc_drv_reg_and_bit, 2489b3077611SDavid Wu .schmitt_calc_reg = rk3308_calc_schmitt_reg_and_bit, 2490b3077611SDavid Wu }; 2491b3077611SDavid Wu 249249c55878SDavid Wu static struct rockchip_pin_bank rk3328_pin_banks[] = { 249349c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 0, 0, 0, 0), 249449c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0), 249549c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 249649c55878SDavid Wu IOMUX_WIDTH_3BIT, 249749c55878SDavid Wu IOMUX_WIDTH_3BIT, 249849c55878SDavid Wu 0), 249949c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 250049c55878SDavid Wu IOMUX_WIDTH_3BIT, 250149c55878SDavid Wu IOMUX_WIDTH_3BIT, 250249c55878SDavid Wu 0, 250349c55878SDavid Wu 0), 250449c55878SDavid Wu }; 250549c55878SDavid Wu 250649c55878SDavid Wu static struct rockchip_pin_ctrl rk3328_pin_ctrl = { 250749c55878SDavid Wu .pin_banks = rk3328_pin_banks, 250849c55878SDavid Wu .nr_banks = ARRAY_SIZE(rk3328_pin_banks), 250949c55878SDavid Wu .label = "RK3328-GPIO", 251049c55878SDavid Wu .type = RK3288, 251149c55878SDavid Wu .grf_mux_offset = 0x0, 251249c55878SDavid Wu .iomux_recalced = rk3328_mux_recalced_data, 251349c55878SDavid Wu .niomux_recalced = ARRAY_SIZE(rk3328_mux_recalced_data), 251449c55878SDavid Wu .iomux_routes = rk3328_mux_route_data, 251549c55878SDavid Wu .niomux_routes = ARRAY_SIZE(rk3328_mux_route_data), 251649c55878SDavid Wu .pull_calc_reg = rk3228_calc_pull_reg_and_bit, 251749c55878SDavid Wu .drv_calc_reg = rk3228_calc_drv_reg_and_bit, 251849c55878SDavid Wu .schmitt_calc_reg = rk3328_calc_schmitt_reg_and_bit, 251949c55878SDavid Wu }; 252049c55878SDavid Wu 252149c55878SDavid Wu static struct rockchip_pin_bank rk3368_pin_banks[] = { 252249c55878SDavid Wu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, 252349c55878SDavid Wu IOMUX_SOURCE_PMU, 252449c55878SDavid Wu IOMUX_SOURCE_PMU, 252549c55878SDavid Wu IOMUX_SOURCE_PMU 252649c55878SDavid Wu ), 252749c55878SDavid Wu PIN_BANK(1, 32, "gpio1"), 252849c55878SDavid Wu PIN_BANK(2, 32, "gpio2"), 252949c55878SDavid Wu PIN_BANK(3, 32, "gpio3"), 253049c55878SDavid Wu }; 253149c55878SDavid Wu 253249c55878SDavid Wu static struct rockchip_pin_ctrl rk3368_pin_ctrl = { 253349c55878SDavid Wu .pin_banks = rk3368_pin_banks, 253449c55878SDavid Wu .nr_banks = ARRAY_SIZE(rk3368_pin_banks), 253549c55878SDavid Wu .label = "RK3368-GPIO", 253649c55878SDavid Wu .type = RK3368, 253749c55878SDavid Wu .grf_mux_offset = 0x0, 253849c55878SDavid Wu .pmu_mux_offset = 0x0, 253949c55878SDavid Wu .pull_calc_reg = rk3368_calc_pull_reg_and_bit, 254049c55878SDavid Wu .drv_calc_reg = rk3368_calc_drv_reg_and_bit, 254149c55878SDavid Wu }; 254249c55878SDavid Wu 254349c55878SDavid Wu static struct rockchip_pin_bank rk3399_pin_banks[] = { 254449c55878SDavid Wu PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(0, 32, "gpio0", 254549c55878SDavid Wu IOMUX_SOURCE_PMU, 254649c55878SDavid Wu IOMUX_SOURCE_PMU, 254749c55878SDavid Wu IOMUX_SOURCE_PMU, 254849c55878SDavid Wu IOMUX_SOURCE_PMU, 254949c55878SDavid Wu DRV_TYPE_IO_1V8_ONLY, 255049c55878SDavid Wu DRV_TYPE_IO_1V8_ONLY, 255149c55878SDavid Wu DRV_TYPE_IO_DEFAULT, 255249c55878SDavid Wu DRV_TYPE_IO_DEFAULT, 255349c55878SDavid Wu 0x80, 255449c55878SDavid Wu 0x88, 255549c55878SDavid Wu -1, 255649c55878SDavid Wu -1, 255749c55878SDavid Wu PULL_TYPE_IO_1V8_ONLY, 255849c55878SDavid Wu PULL_TYPE_IO_1V8_ONLY, 255949c55878SDavid Wu PULL_TYPE_IO_DEFAULT, 256049c55878SDavid Wu PULL_TYPE_IO_DEFAULT 256149c55878SDavid Wu ), 256249c55878SDavid Wu PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(1, 32, "gpio1", IOMUX_SOURCE_PMU, 256349c55878SDavid Wu IOMUX_SOURCE_PMU, 256449c55878SDavid Wu IOMUX_SOURCE_PMU, 256549c55878SDavid Wu IOMUX_SOURCE_PMU, 256649c55878SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 256749c55878SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 256849c55878SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 256949c55878SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 257049c55878SDavid Wu 0xa0, 257149c55878SDavid Wu 0xa8, 257249c55878SDavid Wu 0xb0, 257349c55878SDavid Wu 0xb8 257449c55878SDavid Wu ), 257549c55878SDavid Wu PIN_BANK_DRV_FLAGS_PULL_FLAGS(2, 32, "gpio2", DRV_TYPE_IO_1V8_OR_3V0, 257649c55878SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 257749c55878SDavid Wu DRV_TYPE_IO_1V8_ONLY, 257849c55878SDavid Wu DRV_TYPE_IO_1V8_ONLY, 257949c55878SDavid Wu PULL_TYPE_IO_DEFAULT, 258049c55878SDavid Wu PULL_TYPE_IO_DEFAULT, 258149c55878SDavid Wu PULL_TYPE_IO_1V8_ONLY, 258249c55878SDavid Wu PULL_TYPE_IO_1V8_ONLY 258349c55878SDavid Wu ), 258449c55878SDavid Wu PIN_BANK_DRV_FLAGS(3, 32, "gpio3", DRV_TYPE_IO_3V3_ONLY, 258549c55878SDavid Wu DRV_TYPE_IO_3V3_ONLY, 258649c55878SDavid Wu DRV_TYPE_IO_3V3_ONLY, 258749c55878SDavid Wu DRV_TYPE_IO_1V8_OR_3V0 258849c55878SDavid Wu ), 258949c55878SDavid Wu PIN_BANK_DRV_FLAGS(4, 32, "gpio4", DRV_TYPE_IO_1V8_OR_3V0, 259049c55878SDavid Wu DRV_TYPE_IO_1V8_3V0_AUTO, 259149c55878SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 259249c55878SDavid Wu DRV_TYPE_IO_1V8_OR_3V0 259349c55878SDavid Wu ), 259449c55878SDavid Wu }; 259549c55878SDavid Wu 259649c55878SDavid Wu static struct rockchip_pin_ctrl rk3399_pin_ctrl = { 259749c55878SDavid Wu .pin_banks = rk3399_pin_banks, 259849c55878SDavid Wu .nr_banks = ARRAY_SIZE(rk3399_pin_banks), 259949c55878SDavid Wu .label = "RK3399-GPIO", 260049c55878SDavid Wu .type = RK3399, 260149c55878SDavid Wu .grf_mux_offset = 0xe000, 260249c55878SDavid Wu .pmu_mux_offset = 0x0, 260349c55878SDavid Wu .grf_drv_offset = 0xe100, 260449c55878SDavid Wu .pmu_drv_offset = 0x80, 260549c55878SDavid Wu .iomux_routes = rk3399_mux_route_data, 260649c55878SDavid Wu .niomux_routes = ARRAY_SIZE(rk3399_mux_route_data), 260749c55878SDavid Wu .pull_calc_reg = rk3399_calc_pull_reg_and_bit, 260849c55878SDavid Wu .drv_calc_reg = rk3399_calc_drv_reg_and_bit, 260949c55878SDavid Wu }; 261049c55878SDavid Wu 261149c55878SDavid Wu static const struct udevice_id rockchip_pinctrl_dt_match[] = { 261249c55878SDavid Wu { .compatible = "rockchip,px30-pinctrl", 261349c55878SDavid Wu .data = (ulong)&px30_pin_ctrl }, 261449c55878SDavid Wu { .compatible = "rockchip,rv1108-pinctrl", 261549c55878SDavid Wu .data = (ulong)&rv1108_pin_ctrl }, 261649c55878SDavid Wu { .compatible = "rockchip,rk2928-pinctrl", 261749c55878SDavid Wu .data = (ulong)&rk2928_pin_ctrl }, 261849c55878SDavid Wu { .compatible = "rockchip,rk3036-pinctrl", 261949c55878SDavid Wu .data = (ulong)&rk3036_pin_ctrl }, 262049c55878SDavid Wu { .compatible = "rockchip,rk3066a-pinctrl", 262149c55878SDavid Wu .data = (ulong)&rk3066a_pin_ctrl }, 262249c55878SDavid Wu { .compatible = "rockchip,rk3066b-pinctrl", 262349c55878SDavid Wu .data = (ulong)&rk3066b_pin_ctrl }, 262449c55878SDavid Wu { .compatible = "rockchip,rk3128-pinctrl", 262549c55878SDavid Wu .data = (ulong)&rk3128_pin_ctrl }, 262649c55878SDavid Wu { .compatible = "rockchip,rk3188-pinctrl", 262749c55878SDavid Wu .data = (ulong)&rk3188_pin_ctrl }, 262849c55878SDavid Wu { .compatible = "rockchip,rk3228-pinctrl", 262949c55878SDavid Wu .data = (ulong)&rk3228_pin_ctrl }, 263049c55878SDavid Wu { .compatible = "rockchip,rk3288-pinctrl", 263149c55878SDavid Wu .data = (ulong)&rk3288_pin_ctrl }, 2632b3077611SDavid Wu { .compatible = "rockchip,rk3308-pinctrl", 2633b3077611SDavid Wu .data = (ulong)&rk3308_pin_ctrl }, 263449c55878SDavid Wu { .compatible = "rockchip,rk3328-pinctrl", 263549c55878SDavid Wu .data = (ulong)&rk3328_pin_ctrl }, 263649c55878SDavid Wu { .compatible = "rockchip,rk3368-pinctrl", 263749c55878SDavid Wu .data = (ulong)&rk3368_pin_ctrl }, 263849c55878SDavid Wu { .compatible = "rockchip,rk3399-pinctrl", 263949c55878SDavid Wu .data = (ulong)&rk3399_pin_ctrl }, 264049c55878SDavid Wu {}, 264149c55878SDavid Wu }; 264249c55878SDavid Wu 264349c55878SDavid Wu U_BOOT_DRIVER(pinctrl_rockchip) = { 264449c55878SDavid Wu .name = "rockchip_pinctrl", 264549c55878SDavid Wu .id = UCLASS_PINCTRL, 264649c55878SDavid Wu .of_match = rockchip_pinctrl_dt_match, 264749c55878SDavid Wu .priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv), 264849c55878SDavid Wu .ops = &rockchip_pinctrl_ops, 264949c55878SDavid Wu #if !CONFIG_IS_ENABLED(OF_PLATDATA) 265049c55878SDavid Wu .bind = dm_scan_fdt_dev, 265149c55878SDavid Wu #endif 265249c55878SDavid Wu .probe = rockchip_pinctrl_probe, 265349c55878SDavid Wu }; 2654