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