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