11802d0beSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2d3e51161SHeiko Stübner /* 3d3e51161SHeiko Stübner * Pinctrl driver for Rockchip SoCs 4d3e51161SHeiko Stübner * 5d3e51161SHeiko Stübner * Copyright (c) 2013 MundoReader S.L. 6d3e51161SHeiko Stübner * Author: Heiko Stuebner <heiko@sntech.de> 7d3e51161SHeiko Stübner * 8d3e51161SHeiko Stübner * With some ideas taken from pinctrl-samsung: 9d3e51161SHeiko Stübner * Copyright (c) 2012 Samsung Electronics Co., Ltd. 10d3e51161SHeiko Stübner * http://www.samsung.com 11d3e51161SHeiko Stübner * Copyright (c) 2012 Linaro Ltd 123e3f742bSAlexander A. Klimov * https://www.linaro.org 13d3e51161SHeiko Stübner * 14d3e51161SHeiko Stübner * and pinctrl-at91: 15d3e51161SHeiko Stübner * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> 16d3e51161SHeiko Stübner */ 17d3e51161SHeiko Stübner 182f436204SPaul Gortmaker #include <linux/init.h> 19be786ac5SJianqun Xu #include <linux/module.h> 20d3e51161SHeiko Stübner #include <linux/platform_device.h> 21d3e51161SHeiko Stübner #include <linux/io.h> 22d3e51161SHeiko Stübner #include <linux/bitops.h> 231c5fb66aSLinus Walleij #include <linux/gpio/driver.h> 24d3e51161SHeiko Stübner #include <linux/of_address.h> 259ce9a020SJianqun Xu #include <linux/of_device.h> 26d3e51161SHeiko Stübner #include <linux/of_irq.h> 27d3e51161SHeiko Stübner #include <linux/pinctrl/machine.h> 28d3e51161SHeiko Stübner #include <linux/pinctrl/pinconf.h> 29d3e51161SHeiko Stübner #include <linux/pinctrl/pinctrl.h> 30d3e51161SHeiko Stübner #include <linux/pinctrl/pinmux.h> 31d3e51161SHeiko Stübner #include <linux/pinctrl/pinconf-generic.h> 32d3e51161SHeiko Stübner #include <linux/irqchip/chained_irq.h> 337e865abbSHeiko Stübner #include <linux/clk.h> 34751a99abSHeiko Stübner #include <linux/regmap.h> 3514dee867SHeiko Stübner #include <linux/mfd/syscon.h> 36069d7796SAndy Shevchenko #include <linux/string_helpers.h> 37069d7796SAndy Shevchenko 38d3e51161SHeiko Stübner #include <dt-bindings/pinctrl/rockchip.h> 39d3e51161SHeiko Stübner 40d3e51161SHeiko Stübner #include "core.h" 41d3e51161SHeiko Stübner #include "pinconf.h" 42e1450694SJianqun Xu #include "pinctrl-rockchip.h" 43d3e51161SHeiko Stübner 445a83227bSAndy Shevchenko /* 45c0dadc0eSJianqun Xu * Generate a bitmask for setting a value (v) with a write mask bit in hiword 46c0dadc0eSJianqun Xu * register 31:16 area. 47c0dadc0eSJianqun Xu */ 48c0dadc0eSJianqun Xu #define WRITE_MASK_VAL(h, l, v) \ 49c0dadc0eSJianqun Xu (GENMASK(((h) + 16), ((l) + 16)) | (((v) << (l)) & GENMASK((h), (l)))) 50c0dadc0eSJianqun Xu 51e1524ea8SLee Jones /* 52fc72c923SHeiko Stübner * Encode variants of iomux registers into a type variable 53fc72c923SHeiko Stübner */ 54fc72c923SHeiko Stübner #define IOMUX_GPIO_ONLY BIT(0) 5503716e1dSHeiko Stübner #define IOMUX_WIDTH_4BIT BIT(1) 5695ec8ae4SHeiko Stübner #define IOMUX_SOURCE_PMU BIT(2) 5762f49226SHeiko Stübner #define IOMUX_UNROUTED BIT(3) 588b6c6f93Sdavid.wu #define IOMUX_WIDTH_3BIT BIT(4) 597825aeb7SJianqun Xu #define IOMUX_WIDTH_2BIT BIT(5) 60fc72c923SHeiko Stübner 61d3e51161SHeiko Stübner #define PIN_BANK(id, pins, label) \ 62d3e51161SHeiko Stübner { \ 63d3e51161SHeiko Stübner .bank_num = id, \ 64d3e51161SHeiko Stübner .nr_pins = pins, \ 65d3e51161SHeiko Stübner .name = label, \ 666bc0d121SHeiko Stübner .iomux = { \ 676bc0d121SHeiko Stübner { .offset = -1 }, \ 686bc0d121SHeiko Stübner { .offset = -1 }, \ 696bc0d121SHeiko Stübner { .offset = -1 }, \ 706bc0d121SHeiko Stübner { .offset = -1 }, \ 716bc0d121SHeiko Stübner }, \ 72d3e51161SHeiko Stübner } 73d3e51161SHeiko Stübner 74fc72c923SHeiko Stübner #define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3) \ 75fc72c923SHeiko Stübner { \ 76fc72c923SHeiko Stübner .bank_num = id, \ 77fc72c923SHeiko Stübner .nr_pins = pins, \ 78fc72c923SHeiko Stübner .name = label, \ 79fc72c923SHeiko Stübner .iomux = { \ 806bc0d121SHeiko Stübner { .type = iom0, .offset = -1 }, \ 816bc0d121SHeiko Stübner { .type = iom1, .offset = -1 }, \ 826bc0d121SHeiko Stübner { .type = iom2, .offset = -1 }, \ 836bc0d121SHeiko Stübner { .type = iom3, .offset = -1 }, \ 84fc72c923SHeiko Stübner }, \ 85fc72c923SHeiko Stübner } 86fc72c923SHeiko Stübner 87b6c23275SDavid Wu #define PIN_BANK_DRV_FLAGS(id, pins, label, type0, type1, type2, type3) \ 88b6c23275SDavid Wu { \ 89b6c23275SDavid Wu .bank_num = id, \ 90b6c23275SDavid Wu .nr_pins = pins, \ 91b6c23275SDavid Wu .name = label, \ 92b6c23275SDavid Wu .iomux = { \ 93b6c23275SDavid Wu { .offset = -1 }, \ 94b6c23275SDavid Wu { .offset = -1 }, \ 95b6c23275SDavid Wu { .offset = -1 }, \ 96b6c23275SDavid Wu { .offset = -1 }, \ 97b6c23275SDavid Wu }, \ 98b6c23275SDavid Wu .drv = { \ 99b6c23275SDavid Wu { .drv_type = type0, .offset = -1 }, \ 100b6c23275SDavid Wu { .drv_type = type1, .offset = -1 }, \ 101b6c23275SDavid Wu { .drv_type = type2, .offset = -1 }, \ 102b6c23275SDavid Wu { .drv_type = type3, .offset = -1 }, \ 103b6c23275SDavid Wu }, \ 104b6c23275SDavid Wu } 105b6c23275SDavid Wu 1063ba6767aSDavid Wu #define PIN_BANK_DRV_FLAGS_PULL_FLAGS(id, pins, label, drv0, drv1, \ 1073ba6767aSDavid Wu drv2, drv3, pull0, pull1, \ 1083ba6767aSDavid Wu pull2, pull3) \ 1093ba6767aSDavid Wu { \ 1103ba6767aSDavid Wu .bank_num = id, \ 1113ba6767aSDavid Wu .nr_pins = pins, \ 1123ba6767aSDavid Wu .name = label, \ 1133ba6767aSDavid Wu .iomux = { \ 1143ba6767aSDavid Wu { .offset = -1 }, \ 1153ba6767aSDavid Wu { .offset = -1 }, \ 1163ba6767aSDavid Wu { .offset = -1 }, \ 1173ba6767aSDavid Wu { .offset = -1 }, \ 1183ba6767aSDavid Wu }, \ 1193ba6767aSDavid Wu .drv = { \ 1203ba6767aSDavid Wu { .drv_type = drv0, .offset = -1 }, \ 1213ba6767aSDavid Wu { .drv_type = drv1, .offset = -1 }, \ 1223ba6767aSDavid Wu { .drv_type = drv2, .offset = -1 }, \ 1233ba6767aSDavid Wu { .drv_type = drv3, .offset = -1 }, \ 1243ba6767aSDavid Wu }, \ 1253ba6767aSDavid Wu .pull_type[0] = pull0, \ 1263ba6767aSDavid Wu .pull_type[1] = pull1, \ 1273ba6767aSDavid Wu .pull_type[2] = pull2, \ 1283ba6767aSDavid Wu .pull_type[3] = pull3, \ 1293ba6767aSDavid Wu } 1303ba6767aSDavid Wu 131b6c23275SDavid Wu #define PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(id, pins, label, iom0, iom1, \ 132b6c23275SDavid Wu iom2, iom3, drv0, drv1, drv2, \ 133b6c23275SDavid Wu drv3, offset0, offset1, \ 134b6c23275SDavid Wu offset2, offset3) \ 135b6c23275SDavid Wu { \ 136b6c23275SDavid Wu .bank_num = id, \ 137b6c23275SDavid Wu .nr_pins = pins, \ 138b6c23275SDavid Wu .name = label, \ 139b6c23275SDavid Wu .iomux = { \ 140b6c23275SDavid Wu { .type = iom0, .offset = -1 }, \ 141b6c23275SDavid Wu { .type = iom1, .offset = -1 }, \ 142b6c23275SDavid Wu { .type = iom2, .offset = -1 }, \ 143b6c23275SDavid Wu { .type = iom3, .offset = -1 }, \ 144b6c23275SDavid Wu }, \ 145b6c23275SDavid Wu .drv = { \ 146b6c23275SDavid Wu { .drv_type = drv0, .offset = offset0 }, \ 147b6c23275SDavid Wu { .drv_type = drv1, .offset = offset1 }, \ 148b6c23275SDavid Wu { .drv_type = drv2, .offset = offset2 }, \ 149b6c23275SDavid Wu { .drv_type = drv3, .offset = offset3 }, \ 150b6c23275SDavid Wu }, \ 151b6c23275SDavid Wu } 152b6c23275SDavid Wu 1533ba6767aSDavid Wu #define PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(id, pins, \ 1543ba6767aSDavid Wu label, iom0, iom1, iom2, \ 1553ba6767aSDavid Wu iom3, drv0, drv1, drv2, \ 1563ba6767aSDavid Wu drv3, offset0, offset1, \ 1573ba6767aSDavid Wu offset2, offset3, pull0, \ 1583ba6767aSDavid Wu pull1, pull2, pull3) \ 1593ba6767aSDavid Wu { \ 1603ba6767aSDavid Wu .bank_num = id, \ 1613ba6767aSDavid Wu .nr_pins = pins, \ 1623ba6767aSDavid Wu .name = label, \ 1633ba6767aSDavid Wu .iomux = { \ 1643ba6767aSDavid Wu { .type = iom0, .offset = -1 }, \ 1653ba6767aSDavid Wu { .type = iom1, .offset = -1 }, \ 1663ba6767aSDavid Wu { .type = iom2, .offset = -1 }, \ 1673ba6767aSDavid Wu { .type = iom3, .offset = -1 }, \ 1683ba6767aSDavid Wu }, \ 1693ba6767aSDavid Wu .drv = { \ 1703ba6767aSDavid Wu { .drv_type = drv0, .offset = offset0 }, \ 1713ba6767aSDavid Wu { .drv_type = drv1, .offset = offset1 }, \ 1723ba6767aSDavid Wu { .drv_type = drv2, .offset = offset2 }, \ 1733ba6767aSDavid Wu { .drv_type = drv3, .offset = offset3 }, \ 1743ba6767aSDavid Wu }, \ 1753ba6767aSDavid Wu .pull_type[0] = pull0, \ 1763ba6767aSDavid Wu .pull_type[1] = pull1, \ 1773ba6767aSDavid Wu .pull_type[2] = pull2, \ 1783ba6767aSDavid Wu .pull_type[3] = pull3, \ 1793ba6767aSDavid Wu } 1803ba6767aSDavid Wu 181c0dadc0eSJianqun Xu #define PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, FLAG) \ 182c0dadc0eSJianqun Xu { \ 183c0dadc0eSJianqun Xu .bank_num = ID, \ 184c0dadc0eSJianqun Xu .pin = PIN, \ 185c0dadc0eSJianqun Xu .func = FUNC, \ 186c0dadc0eSJianqun Xu .route_offset = REG, \ 187c0dadc0eSJianqun Xu .route_val = VAL, \ 188c0dadc0eSJianqun Xu .route_location = FLAG, \ 189c0dadc0eSJianqun Xu } 190c0dadc0eSJianqun Xu 191c0dadc0eSJianqun Xu #define RK_MUXROUTE_SAME(ID, PIN, FUNC, REG, VAL) \ 192c0dadc0eSJianqun Xu PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_SAME) 193c0dadc0eSJianqun Xu 194c0dadc0eSJianqun Xu #define RK_MUXROUTE_GRF(ID, PIN, FUNC, REG, VAL) \ 195c0dadc0eSJianqun Xu PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_GRF) 196c0dadc0eSJianqun Xu 197c0dadc0eSJianqun Xu #define RK_MUXROUTE_PMU(ID, PIN, FUNC, REG, VAL) \ 198c0dadc0eSJianqun Xu PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_PMU) 199c0dadc0eSJianqun Xu 200751a99abSHeiko Stübner static struct regmap_config rockchip_regmap_config = { 201751a99abSHeiko Stübner .reg_bits = 32, 202751a99abSHeiko Stübner .val_bits = 32, 203751a99abSHeiko Stübner .reg_stride = 4, 204751a99abSHeiko Stübner }; 205751a99abSHeiko Stübner 20656411f3cSArnd Bergmann static inline const struct rockchip_pin_group *pinctrl_name_to_group( 207d3e51161SHeiko Stübner const struct rockchip_pinctrl *info, 208d3e51161SHeiko Stübner const char *name) 209d3e51161SHeiko Stübner { 210d3e51161SHeiko Stübner int i; 211d3e51161SHeiko Stübner 212d3e51161SHeiko Stübner for (i = 0; i < info->ngroups; i++) { 2131cb95395SAxel Lin if (!strcmp(info->groups[i].name, name)) 2141cb95395SAxel Lin return &info->groups[i]; 215d3e51161SHeiko Stübner } 216d3e51161SHeiko Stübner 2171cb95395SAxel Lin return NULL; 218d3e51161SHeiko Stübner } 219d3e51161SHeiko Stübner 220d3e51161SHeiko Stübner /* 221d3e51161SHeiko Stübner * given a pin number that is local to a pin controller, find out the pin bank 222d3e51161SHeiko Stübner * and the register base of the pin bank. 223d3e51161SHeiko Stübner */ 224d3e51161SHeiko Stübner static struct rockchip_pin_bank *pin_to_bank(struct rockchip_pinctrl *info, 225d3e51161SHeiko Stübner unsigned pin) 226d3e51161SHeiko Stübner { 227d3e51161SHeiko Stübner struct rockchip_pin_bank *b = info->ctrl->pin_banks; 228d3e51161SHeiko Stübner 22951578b9bSAxel Lin while (pin >= (b->pin_base + b->nr_pins)) 230d3e51161SHeiko Stübner b++; 231d3e51161SHeiko Stübner 232d3e51161SHeiko Stübner return b; 233d3e51161SHeiko Stübner } 234d3e51161SHeiko Stübner 235d3e51161SHeiko Stübner static struct rockchip_pin_bank *bank_num_to_bank( 236d3e51161SHeiko Stübner struct rockchip_pinctrl *info, 237d3e51161SHeiko Stübner unsigned num) 238d3e51161SHeiko Stübner { 239d3e51161SHeiko Stübner struct rockchip_pin_bank *b = info->ctrl->pin_banks; 240d3e51161SHeiko Stübner int i; 241d3e51161SHeiko Stübner 2421cb95395SAxel Lin for (i = 0; i < info->ctrl->nr_banks; i++, b++) { 243d3e51161SHeiko Stübner if (b->bank_num == num) 2441cb95395SAxel Lin return b; 245d3e51161SHeiko Stübner } 246d3e51161SHeiko Stübner 247d3e51161SHeiko Stübner return ERR_PTR(-EINVAL); 248d3e51161SHeiko Stübner } 249d3e51161SHeiko Stübner 250d3e51161SHeiko Stübner /* 251d3e51161SHeiko Stübner * Pinctrl_ops handling 252d3e51161SHeiko Stübner */ 253d3e51161SHeiko Stübner 254d3e51161SHeiko Stübner static int rockchip_get_groups_count(struct pinctrl_dev *pctldev) 255d3e51161SHeiko Stübner { 256d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 257d3e51161SHeiko Stübner 258d3e51161SHeiko Stübner return info->ngroups; 259d3e51161SHeiko Stübner } 260d3e51161SHeiko Stübner 261d3e51161SHeiko Stübner static const char *rockchip_get_group_name(struct pinctrl_dev *pctldev, 262d3e51161SHeiko Stübner unsigned selector) 263d3e51161SHeiko Stübner { 264d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 265d3e51161SHeiko Stübner 266d3e51161SHeiko Stübner return info->groups[selector].name; 267d3e51161SHeiko Stübner } 268d3e51161SHeiko Stübner 269d3e51161SHeiko Stübner static int rockchip_get_group_pins(struct pinctrl_dev *pctldev, 270d3e51161SHeiko Stübner unsigned selector, const unsigned **pins, 271d3e51161SHeiko Stübner unsigned *npins) 272d3e51161SHeiko Stübner { 273d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 274d3e51161SHeiko Stübner 275d3e51161SHeiko Stübner if (selector >= info->ngroups) 276d3e51161SHeiko Stübner return -EINVAL; 277d3e51161SHeiko Stübner 278d3e51161SHeiko Stübner *pins = info->groups[selector].pins; 279d3e51161SHeiko Stübner *npins = info->groups[selector].npins; 280d3e51161SHeiko Stübner 281d3e51161SHeiko Stübner return 0; 282d3e51161SHeiko Stübner } 283d3e51161SHeiko Stübner 284d3e51161SHeiko Stübner static int rockchip_dt_node_to_map(struct pinctrl_dev *pctldev, 285d3e51161SHeiko Stübner struct device_node *np, 286d3e51161SHeiko Stübner struct pinctrl_map **map, unsigned *num_maps) 287d3e51161SHeiko Stübner { 288d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 289d3e51161SHeiko Stübner const struct rockchip_pin_group *grp; 290e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 291d3e51161SHeiko Stübner struct pinctrl_map *new_map; 292d3e51161SHeiko Stübner struct device_node *parent; 293d3e51161SHeiko Stübner int map_num = 1; 294d3e51161SHeiko Stübner int i; 295d3e51161SHeiko Stübner 296d3e51161SHeiko Stübner /* 297d3e51161SHeiko Stübner * first find the group of this node and check if we need to create 298d3e51161SHeiko Stübner * config maps for pins 299d3e51161SHeiko Stübner */ 300d3e51161SHeiko Stübner grp = pinctrl_name_to_group(info, np->name); 301d3e51161SHeiko Stübner if (!grp) { 302e4dd7fd5SAndy Shevchenko dev_err(dev, "unable to find group for node %pOFn\n", np); 303d3e51161SHeiko Stübner return -EINVAL; 304d3e51161SHeiko Stübner } 305d3e51161SHeiko Stübner 306d3e51161SHeiko Stübner map_num += grp->npins; 307d7faa8ffSDafna Hirschfeld 308d7faa8ffSDafna Hirschfeld new_map = kcalloc(map_num, sizeof(*new_map), GFP_KERNEL); 309d3e51161SHeiko Stübner if (!new_map) 310d3e51161SHeiko Stübner return -ENOMEM; 311d3e51161SHeiko Stübner 312d3e51161SHeiko Stübner *map = new_map; 313d3e51161SHeiko Stübner *num_maps = map_num; 314d3e51161SHeiko Stübner 315d3e51161SHeiko Stübner /* create mux map */ 316d3e51161SHeiko Stübner parent = of_get_parent(np); 317d3e51161SHeiko Stübner if (!parent) { 318d7faa8ffSDafna Hirschfeld kfree(new_map); 319d3e51161SHeiko Stübner return -EINVAL; 320d3e51161SHeiko Stübner } 321d3e51161SHeiko Stübner new_map[0].type = PIN_MAP_TYPE_MUX_GROUP; 322d3e51161SHeiko Stübner new_map[0].data.mux.function = parent->name; 323d3e51161SHeiko Stübner new_map[0].data.mux.group = np->name; 324d3e51161SHeiko Stübner of_node_put(parent); 325d3e51161SHeiko Stübner 326d3e51161SHeiko Stübner /* create config map */ 327d3e51161SHeiko Stübner new_map++; 328d3e51161SHeiko Stübner for (i = 0; i < grp->npins; i++) { 329d3e51161SHeiko Stübner new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN; 330d3e51161SHeiko Stübner new_map[i].data.configs.group_or_pin = 331d3e51161SHeiko Stübner pin_get_name(pctldev, grp->pins[i]); 332d3e51161SHeiko Stübner new_map[i].data.configs.configs = grp->data[i].configs; 333d3e51161SHeiko Stübner new_map[i].data.configs.num_configs = grp->data[i].nconfigs; 334d3e51161SHeiko Stübner } 335d3e51161SHeiko Stübner 336e4dd7fd5SAndy Shevchenko dev_dbg(dev, "maps: function %s group %s num %d\n", 337d3e51161SHeiko Stübner (*map)->data.mux.function, (*map)->data.mux.group, map_num); 338d3e51161SHeiko Stübner 339d3e51161SHeiko Stübner return 0; 340d3e51161SHeiko Stübner } 341d3e51161SHeiko Stübner 342d3e51161SHeiko Stübner static void rockchip_dt_free_map(struct pinctrl_dev *pctldev, 343d3e51161SHeiko Stübner struct pinctrl_map *map, unsigned num_maps) 344d3e51161SHeiko Stübner { 345d7faa8ffSDafna Hirschfeld kfree(map); 346d3e51161SHeiko Stübner } 347d3e51161SHeiko Stübner 348d3e51161SHeiko Stübner static const struct pinctrl_ops rockchip_pctrl_ops = { 349d3e51161SHeiko Stübner .get_groups_count = rockchip_get_groups_count, 350d3e51161SHeiko Stübner .get_group_name = rockchip_get_group_name, 351d3e51161SHeiko Stübner .get_group_pins = rockchip_get_group_pins, 352d3e51161SHeiko Stübner .dt_node_to_map = rockchip_dt_node_to_map, 353d3e51161SHeiko Stübner .dt_free_map = rockchip_dt_free_map, 354d3e51161SHeiko Stübner }; 355d3e51161SHeiko Stübner 356d3e51161SHeiko Stübner /* 357d3e51161SHeiko Stübner * Hardware access 358d3e51161SHeiko Stübner */ 359d3e51161SHeiko Stübner 36012b8f018SDavid Wu static struct rockchip_mux_recalced_data rv1108_mux_recalced_data[] = { 36112b8f018SDavid Wu { 36212b8f018SDavid Wu .num = 1, 36312b8f018SDavid Wu .pin = 0, 36412b8f018SDavid Wu .reg = 0x418, 36512b8f018SDavid Wu .bit = 0, 36612b8f018SDavid Wu .mask = 0x3 36712b8f018SDavid Wu }, { 36812b8f018SDavid Wu .num = 1, 36912b8f018SDavid Wu .pin = 1, 37012b8f018SDavid Wu .reg = 0x418, 37112b8f018SDavid Wu .bit = 2, 37212b8f018SDavid Wu .mask = 0x3 37312b8f018SDavid Wu }, { 37412b8f018SDavid Wu .num = 1, 37512b8f018SDavid Wu .pin = 2, 37612b8f018SDavid Wu .reg = 0x418, 37712b8f018SDavid Wu .bit = 4, 37812b8f018SDavid Wu .mask = 0x3 37912b8f018SDavid Wu }, { 38012b8f018SDavid Wu .num = 1, 38112b8f018SDavid Wu .pin = 3, 38212b8f018SDavid Wu .reg = 0x418, 38312b8f018SDavid Wu .bit = 6, 38412b8f018SDavid Wu .mask = 0x3 38512b8f018SDavid Wu }, { 38612b8f018SDavid Wu .num = 1, 38712b8f018SDavid Wu .pin = 4, 38812b8f018SDavid Wu .reg = 0x418, 38912b8f018SDavid Wu .bit = 8, 39012b8f018SDavid Wu .mask = 0x3 39112b8f018SDavid Wu }, { 39212b8f018SDavid Wu .num = 1, 39312b8f018SDavid Wu .pin = 5, 39412b8f018SDavid Wu .reg = 0x418, 39512b8f018SDavid Wu .bit = 10, 39612b8f018SDavid Wu .mask = 0x3 39712b8f018SDavid Wu }, { 39812b8f018SDavid Wu .num = 1, 39912b8f018SDavid Wu .pin = 6, 40012b8f018SDavid Wu .reg = 0x418, 40112b8f018SDavid Wu .bit = 12, 40212b8f018SDavid Wu .mask = 0x3 40312b8f018SDavid Wu }, { 40412b8f018SDavid Wu .num = 1, 40512b8f018SDavid Wu .pin = 7, 40612b8f018SDavid Wu .reg = 0x418, 40712b8f018SDavid Wu .bit = 14, 40812b8f018SDavid Wu .mask = 0x3 40912b8f018SDavid Wu }, { 41012b8f018SDavid Wu .num = 1, 41112b8f018SDavid Wu .pin = 8, 41212b8f018SDavid Wu .reg = 0x41c, 41312b8f018SDavid Wu .bit = 0, 41412b8f018SDavid Wu .mask = 0x3 41512b8f018SDavid Wu }, { 41612b8f018SDavid Wu .num = 1, 41712b8f018SDavid Wu .pin = 9, 41812b8f018SDavid Wu .reg = 0x41c, 41912b8f018SDavid Wu .bit = 2, 42012b8f018SDavid Wu .mask = 0x3 42112b8f018SDavid Wu }, 42212b8f018SDavid Wu }; 42312b8f018SDavid Wu 424d23c66dfSDavid Wu static struct rockchip_mux_recalced_data rk3128_mux_recalced_data[] = { 425d23c66dfSDavid Wu { 426d23c66dfSDavid Wu .num = 2, 427d23c66dfSDavid Wu .pin = 20, 428d23c66dfSDavid Wu .reg = 0xe8, 429d23c66dfSDavid Wu .bit = 0, 430d23c66dfSDavid Wu .mask = 0x7 431d23c66dfSDavid Wu }, { 432d23c66dfSDavid Wu .num = 2, 433d23c66dfSDavid Wu .pin = 21, 434d23c66dfSDavid Wu .reg = 0xe8, 435d23c66dfSDavid Wu .bit = 4, 436d23c66dfSDavid Wu .mask = 0x7 437d23c66dfSDavid Wu }, { 438d23c66dfSDavid Wu .num = 2, 439d23c66dfSDavid Wu .pin = 22, 440d23c66dfSDavid Wu .reg = 0xe8, 441d23c66dfSDavid Wu .bit = 8, 442d23c66dfSDavid Wu .mask = 0x7 443d23c66dfSDavid Wu }, { 444d23c66dfSDavid Wu .num = 2, 445d23c66dfSDavid Wu .pin = 23, 446d23c66dfSDavid Wu .reg = 0xe8, 447d23c66dfSDavid Wu .bit = 12, 448d23c66dfSDavid Wu .mask = 0x7 449d23c66dfSDavid Wu }, { 450d23c66dfSDavid Wu .num = 2, 451d23c66dfSDavid Wu .pin = 24, 452d23c66dfSDavid Wu .reg = 0xd4, 453d23c66dfSDavid Wu .bit = 12, 454d23c66dfSDavid Wu .mask = 0x7 455d23c66dfSDavid Wu }, 456d23c66dfSDavid Wu }; 457d23c66dfSDavid Wu 4587825aeb7SJianqun Xu static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = { 4597825aeb7SJianqun Xu { 460*1f3e25a0SLuca Ceresoli /* gpio1b6_sel */ 4617825aeb7SJianqun Xu .num = 1, 4627825aeb7SJianqun Xu .pin = 14, 4637825aeb7SJianqun Xu .reg = 0x28, 4647825aeb7SJianqun Xu .bit = 12, 4657825aeb7SJianqun Xu .mask = 0xf 4667825aeb7SJianqun Xu }, { 467*1f3e25a0SLuca Ceresoli /* gpio1b7_sel */ 4687825aeb7SJianqun Xu .num = 1, 4697825aeb7SJianqun Xu .pin = 15, 4707825aeb7SJianqun Xu .reg = 0x2c, 4717825aeb7SJianqun Xu .bit = 0, 4727825aeb7SJianqun Xu .mask = 0x3 4737825aeb7SJianqun Xu }, { 474*1f3e25a0SLuca Ceresoli /* gpio1c2_sel */ 4757825aeb7SJianqun Xu .num = 1, 4767825aeb7SJianqun Xu .pin = 18, 4777825aeb7SJianqun Xu .reg = 0x30, 4787825aeb7SJianqun Xu .bit = 4, 4797825aeb7SJianqun Xu .mask = 0xf 4807825aeb7SJianqun Xu }, { 481*1f3e25a0SLuca Ceresoli /* gpio1c3_sel */ 4827825aeb7SJianqun Xu .num = 1, 4837825aeb7SJianqun Xu .pin = 19, 4847825aeb7SJianqun Xu .reg = 0x30, 4857825aeb7SJianqun Xu .bit = 8, 4867825aeb7SJianqun Xu .mask = 0xf 4877825aeb7SJianqun Xu }, { 488*1f3e25a0SLuca Ceresoli /* gpio1c4_sel */ 4897825aeb7SJianqun Xu .num = 1, 4907825aeb7SJianqun Xu .pin = 20, 4917825aeb7SJianqun Xu .reg = 0x30, 4927825aeb7SJianqun Xu .bit = 12, 4937825aeb7SJianqun Xu .mask = 0xf 4947825aeb7SJianqun Xu }, { 495*1f3e25a0SLuca Ceresoli /* gpio1c5_sel */ 4967825aeb7SJianqun Xu .num = 1, 4977825aeb7SJianqun Xu .pin = 21, 4987825aeb7SJianqun Xu .reg = 0x34, 4997825aeb7SJianqun Xu .bit = 0, 5007825aeb7SJianqun Xu .mask = 0xf 5017825aeb7SJianqun Xu }, { 502*1f3e25a0SLuca Ceresoli /* gpio1c6_sel */ 5037825aeb7SJianqun Xu .num = 1, 5047825aeb7SJianqun Xu .pin = 22, 5057825aeb7SJianqun Xu .reg = 0x34, 5067825aeb7SJianqun Xu .bit = 4, 5077825aeb7SJianqun Xu .mask = 0xf 5087825aeb7SJianqun Xu }, { 509*1f3e25a0SLuca Ceresoli /* gpio1c7_sel */ 5107825aeb7SJianqun Xu .num = 1, 5117825aeb7SJianqun Xu .pin = 23, 5127825aeb7SJianqun Xu .reg = 0x34, 5137825aeb7SJianqun Xu .bit = 8, 5147825aeb7SJianqun Xu .mask = 0xf 5157825aeb7SJianqun Xu }, { 516*1f3e25a0SLuca Ceresoli /* gpio3b4_sel */ 5177825aeb7SJianqun Xu .num = 3, 5187825aeb7SJianqun Xu .pin = 12, 5197825aeb7SJianqun Xu .reg = 0x68, 5207825aeb7SJianqun Xu .bit = 8, 5217825aeb7SJianqun Xu .mask = 0xf 5227825aeb7SJianqun Xu }, { 523*1f3e25a0SLuca Ceresoli /* gpio3b5_sel */ 5247825aeb7SJianqun Xu .num = 3, 5257825aeb7SJianqun Xu .pin = 13, 5267825aeb7SJianqun Xu .reg = 0x68, 5277825aeb7SJianqun Xu .bit = 12, 5287825aeb7SJianqun Xu .mask = 0xf 5297825aeb7SJianqun Xu }, { 530*1f3e25a0SLuca Ceresoli /* gpio2a2_sel */ 5317825aeb7SJianqun Xu .num = 2, 5327825aeb7SJianqun Xu .pin = 2, 533*1f3e25a0SLuca Ceresoli .reg = 0x40, 534*1f3e25a0SLuca Ceresoli .bit = 4, 535*1f3e25a0SLuca Ceresoli .mask = 0x3 5367825aeb7SJianqun Xu }, { 537*1f3e25a0SLuca Ceresoli /* gpio2a3_sel */ 5387825aeb7SJianqun Xu .num = 2, 5397825aeb7SJianqun Xu .pin = 3, 540*1f3e25a0SLuca Ceresoli .reg = 0x40, 541*1f3e25a0SLuca Ceresoli .bit = 6, 542*1f3e25a0SLuca Ceresoli .mask = 0x3 5437825aeb7SJianqun Xu }, { 544*1f3e25a0SLuca Ceresoli /* gpio2c0_sel */ 5457825aeb7SJianqun Xu .num = 2, 5467825aeb7SJianqun Xu .pin = 16, 547*1f3e25a0SLuca Ceresoli .reg = 0x50, 548*1f3e25a0SLuca Ceresoli .bit = 0, 549*1f3e25a0SLuca Ceresoli .mask = 0x3 5507825aeb7SJianqun Xu }, { 551*1f3e25a0SLuca Ceresoli /* gpio3b2_sel */ 5527825aeb7SJianqun Xu .num = 3, 5537825aeb7SJianqun Xu .pin = 10, 554*1f3e25a0SLuca Ceresoli .reg = 0x68, 555*1f3e25a0SLuca Ceresoli .bit = 4, 556*1f3e25a0SLuca Ceresoli .mask = 0x3 5577825aeb7SJianqun Xu }, { 558*1f3e25a0SLuca Ceresoli /* gpio3b3_sel */ 5597825aeb7SJianqun Xu .num = 3, 5607825aeb7SJianqun Xu .pin = 11, 561*1f3e25a0SLuca Ceresoli .reg = 0x68, 562*1f3e25a0SLuca Ceresoli .bit = 6, 563*1f3e25a0SLuca Ceresoli .mask = 0x3 5647825aeb7SJianqun Xu }, 5657825aeb7SJianqun Xu }; 5667825aeb7SJianqun Xu 567c04c3fa6SDavid Wu static struct rockchip_mux_recalced_data rk3328_mux_recalced_data[] = { 5683818e4a7Sdavid.wu { 5693818e4a7Sdavid.wu .num = 2, 5703818e4a7Sdavid.wu .pin = 12, 5713818e4a7Sdavid.wu .reg = 0x24, 5723818e4a7Sdavid.wu .bit = 8, 5733818e4a7Sdavid.wu .mask = 0x3 5743818e4a7Sdavid.wu }, { 5753818e4a7Sdavid.wu .num = 2, 5763818e4a7Sdavid.wu .pin = 15, 5773818e4a7Sdavid.wu .reg = 0x28, 5783818e4a7Sdavid.wu .bit = 0, 5793818e4a7Sdavid.wu .mask = 0x7 5803818e4a7Sdavid.wu }, { 5813818e4a7Sdavid.wu .num = 2, 5823818e4a7Sdavid.wu .pin = 23, 5833818e4a7Sdavid.wu .reg = 0x30, 5843818e4a7Sdavid.wu .bit = 14, 5853818e4a7Sdavid.wu .mask = 0x3 5863818e4a7Sdavid.wu }, 5873818e4a7Sdavid.wu }; 5883818e4a7Sdavid.wu 589c04c3fa6SDavid Wu static void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin, 590c04c3fa6SDavid Wu int *reg, u8 *bit, int *mask) 5913818e4a7Sdavid.wu { 592c04c3fa6SDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 593c04c3fa6SDavid Wu struct rockchip_pin_ctrl *ctrl = info->ctrl; 594c04c3fa6SDavid Wu struct rockchip_mux_recalced_data *data; 5953818e4a7Sdavid.wu int i; 5963818e4a7Sdavid.wu 597c04c3fa6SDavid Wu for (i = 0; i < ctrl->niomux_recalced; i++) { 598c04c3fa6SDavid Wu data = &ctrl->iomux_recalced[i]; 599c04c3fa6SDavid Wu if (data->num == bank->bank_num && 600c04c3fa6SDavid Wu data->pin == pin) 6013818e4a7Sdavid.wu break; 6023818e4a7Sdavid.wu } 6033818e4a7Sdavid.wu 604c04c3fa6SDavid Wu if (i >= ctrl->niomux_recalced) 6053818e4a7Sdavid.wu return; 6063818e4a7Sdavid.wu 6073818e4a7Sdavid.wu *reg = data->reg; 6083818e4a7Sdavid.wu *mask = data->mask; 6093818e4a7Sdavid.wu *bit = data->bit; 6103818e4a7Sdavid.wu } 6113818e4a7Sdavid.wu 61287065ca9SDavid Wu static struct rockchip_mux_route_data px30_mux_route_data[] = { 613fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA0, 1, 0x184, BIT(16 + 7)), /* cif-d2m0 */ 614fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PA3, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d2m1 */ 615fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PC6, 2, 0x184, BIT(16 + 8)), /* pdm-m0 */ 616fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PC6, 1, 0x184, BIT(16 + 8) | BIT(8)), /* pdm-m1 */ 617fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PD3, 2, 0x184, BIT(16 + 10)), /* uart2-rxm0 */ 618fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PB6, 2, 0x184, BIT(16 + 10) | BIT(10)), /* uart2-rxm1 */ 619fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PC1, 2, 0x184, BIT(16 + 9)), /* uart3-rxm0 */ 620fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB7, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-rxm1 */ 62187065ca9SDavid Wu }; 62287065ca9SDavid Wu 623d23c66dfSDavid Wu static struct rockchip_mux_route_data rk3128_mux_route_data[] = { 624fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB2, 1, 0x144, BIT(16 + 3) | BIT(16 + 4)), /* spi-0 */ 625fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PD3, 3, 0x144, BIT(16 + 3) | BIT(16 + 4) | BIT(3)), /* spi-1 */ 626fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PB5, 2, 0x144, BIT(16 + 3) | BIT(16 + 4) | BIT(4)), /* spi-2 */ 627fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PA5, 1, 0x144, BIT(16 + 5)), /* i2s-0 */ 628fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PB6, 1, 0x144, BIT(16 + 5) | BIT(5)), /* i2s-1 */ 629fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x144, BIT(16 + 6)), /* emmc-0 */ 630fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x144, BIT(16 + 6) | BIT(6)), /* emmc-1 */ 631d23c66dfSDavid Wu }; 632d23c66dfSDavid Wu 633ada62b7cSHeiko Stuebner static struct rockchip_mux_route_data rk3188_mux_route_data[] = { 634fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PD0, 1, 0xa0, BIT(16 + 11)), /* non-iomuxed emmc/flash pins on flash-dqs */ 635fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PD0, 2, 0xa0, BIT(16 + 11) | BIT(11)), /* non-iomuxed emmc/flash pins on emmc-clk */ 636ada62b7cSHeiko Stuebner }; 637ada62b7cSHeiko Stuebner 638d4970ee0SDavid Wu static struct rockchip_mux_route_data rk3228_mux_route_data[] = { 639fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PD2, 1, 0x50, BIT(16)), /* pwm0-0 */ 640fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PC5, 1, 0x50, BIT(16) | BIT(0)), /* pwm0-1 */ 641fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PD3, 1, 0x50, BIT(16 + 1)), /* pwm1-0 */ 642fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PD6, 2, 0x50, BIT(16 + 1) | BIT(1)), /* pwm1-1 */ 643fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PD4, 1, 0x50, BIT(16 + 2)), /* pwm2-0 */ 644fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB4, 2, 0x50, BIT(16 + 2) | BIT(2)), /* pwm2-1 */ 645fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PD2, 1, 0x50, BIT(16 + 3)), /* pwm3-0 */ 646fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB3, 2, 0x50, BIT(16 + 3) | BIT(3)), /* pwm3-1 */ 647fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PA1, 1, 0x50, BIT(16 + 4)), /* sdio-0_d0 */ 648fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PA2, 1, 0x50, BIT(16 + 4) | BIT(4)), /* sdio-1_d0 */ 649fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PB5, 2, 0x50, BIT(16 + 5)), /* spi-0_rx */ 650fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA0, 2, 0x50, BIT(16 + 5) | BIT(5)), /* spi-1_rx */ 651fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x50, BIT(16 + 7)), /* emmc-0_cmd */ 652fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x50, BIT(16 + 7) | BIT(7)), /* emmc-1_cmd */ 653fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC3, 2, 0x50, BIT(16 + 8)), /* uart2-0_rx */ 654fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB2, 2, 0x50, BIT(16 + 8) | BIT(8)), /* uart2-1_rx */ 655fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB2, 1, 0x50, BIT(16 + 11)), /* uart1-0_rx */ 656fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PB5, 1, 0x50, BIT(16 + 11) | BIT(11)), /* uart1-1_rx */ 657d4970ee0SDavid Wu }; 658d4970ee0SDavid Wu 6594e96fd30SHeiko Stuebner static struct rockchip_mux_route_data rk3288_mux_route_data[] = { 660fe202ea8SJianqun Xu RK_MUXROUTE_SAME(7, RK_PC0, 2, 0x264, BIT(16 + 12) | BIT(12)), /* edphdmi_cecinoutt1 */ 661fe202ea8SJianqun Xu RK_MUXROUTE_SAME(7, RK_PC7, 4, 0x264, BIT(16 + 12)), /* edphdmi_cecinout */ 6624e96fd30SHeiko Stuebner }; 6634e96fd30SHeiko Stuebner 6647825aeb7SJianqun Xu static struct rockchip_mux_route_data rk3308_mux_route_data[] = { 665fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PC3, 1, 0x314, BIT(16 + 0) | BIT(0)), /* rtc_clk */ 666fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x314, BIT(16 + 2) | BIT(16 + 3)), /* uart2_rxm0 */ 667fe202ea8SJianqun Xu RK_MUXROUTE_SAME(4, RK_PD2, 2, 0x314, BIT(16 + 2) | BIT(16 + 3) | BIT(2)), /* uart2_rxm1 */ 668fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PB7, 2, 0x608, BIT(16 + 8) | BIT(16 + 9)), /* i2c3_sdam0 */ 669fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PB4, 2, 0x608, BIT(16 + 8) | BIT(16 + 9) | BIT(8)), /* i2c3_sdam1 */ 670fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA0, 3, 0x608, BIT(16 + 8) | BIT(16 + 9) | BIT(9)), /* i2c3_sdam2 */ 671fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PA3, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclktxm0 */ 672fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PA4, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclkrxm0 */ 673fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB5, 2, 0x308, BIT(16 + 3) | BIT(3)), /* i2s-8ch-1-sclktxm1 */ 674fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x308, BIT(16 + 3) | BIT(3)), /* i2s-8ch-1-sclkrxm1 */ 675fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PA4, 3, 0x308, BIT(16 + 12) | BIT(16 + 13)), /* pdm-clkm0 */ 676fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB6, 4, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(12)), /* pdm-clkm1 */ 677fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA6, 2, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(13)), /* pdm-clkm2 */ 678fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA4, 3, 0x600, BIT(16 + 2) | BIT(2)), /* pdm-clkm-m2 */ 679fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PB2, 3, 0x314, BIT(16 + 9)), /* spi1_miso */ 680fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x314, BIT(16 + 9) | BIT(9)), /* spi1_miso_m1 */ 681fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PB3, 3, 0x314, BIT(16 + 10) | BIT(16 + 11)), /* owire_m0 */ 682fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC6, 7, 0x314, BIT(16 + 10) | BIT(16 + 11) | BIT(10)), /* owire_m1 */ 683fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA2, 5, 0x314, BIT(16 + 10) | BIT(16 + 11) | BIT(11)), /* owire_m2 */ 684fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PB3, 2, 0x314, BIT(16 + 12) | BIT(16 + 13)), /* can_rxd_m0 */ 685fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC6, 5, 0x314, BIT(16 + 12) | BIT(16 + 13) | BIT(12)), /* can_rxd_m1 */ 686fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA2, 4, 0x314, BIT(16 + 12) | BIT(16 + 13) | BIT(13)), /* can_rxd_m2 */ 687fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC4, 3, 0x314, BIT(16 + 14)), /* mac_rxd0_m0 */ 688fe202ea8SJianqun Xu RK_MUXROUTE_SAME(4, RK_PA2, 2, 0x314, BIT(16 + 14) | BIT(14)), /* mac_rxd0_m1 */ 689fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PB4, 4, 0x314, BIT(16 + 15)), /* uart3_rx */ 690fe202ea8SJianqun Xu RK_MUXROUTE_SAME(0, RK_PC1, 3, 0x314, BIT(16 + 15) | BIT(15)), /* uart3_rx_m1 */ 6917825aeb7SJianqun Xu }; 6927825aeb7SJianqun Xu 693cedc964aSDavid Wu static struct rockchip_mux_route_data rk3328_mux_route_data[] = { 694fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PA1, 2, 0x50, BIT(16) | BIT(16 + 1)), /* uart2dbg_rxm0 */ 695fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PA1, 1, 0x50, BIT(16) | BIT(16 + 1) | BIT(0)), /* uart2dbg_rxm1 */ 696fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB3, 2, 0x50, BIT(16 + 2) | BIT(2)), /* gmac-m1_rxd0 */ 697fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x50, BIT(16 + 10) | BIT(10)), /* gmac-m1-optimized_rxd3 */ 698fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PC3, 2, 0x50, BIT(16 + 3)), /* pdm_sdi0m0 */ 699fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PC7, 3, 0x50, BIT(16 + 3) | BIT(3)), /* pdm_sdi0m1 */ 700fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PA2, 4, 0x50, BIT(16 + 4) | BIT(16 + 5) | BIT(5)), /* spi_rxdm2 */ 701fe202ea8SJianqun Xu RK_MUXROUTE_SAME(1, RK_PD0, 1, 0x50, BIT(16 + 6)), /* i2s2_sdim0 */ 702fe202ea8SJianqun Xu RK_MUXROUTE_SAME(3, RK_PA2, 6, 0x50, BIT(16 + 6) | BIT(6)), /* i2s2_sdim1 */ 703fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PC6, 3, 0x50, BIT(16 + 7) | BIT(7)), /* card_iom1 */ 704fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PC0, 3, 0x50, BIT(16 + 8) | BIT(8)), /* tsp_d5m1 */ 705fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PC0, 4, 0x50, BIT(16 + 9) | BIT(9)), /* cif_data5m1 */ 706cedc964aSDavid Wu }; 707cedc964aSDavid Wu 708accc1ce7SDavid Wu static struct rockchip_mux_route_data rk3399_mux_route_data[] = { 709fe202ea8SJianqun Xu RK_MUXROUTE_SAME(4, RK_PB0, 2, 0xe21c, BIT(16 + 10) | BIT(16 + 11)), /* uart2dbga_rx */ 710fe202ea8SJianqun Xu RK_MUXROUTE_SAME(4, RK_PC0, 2, 0xe21c, BIT(16 + 10) | BIT(16 + 11) | BIT(10)), /* uart2dbgb_rx */ 711fe202ea8SJianqun Xu RK_MUXROUTE_SAME(4, RK_PC3, 1, 0xe21c, BIT(16 + 10) | BIT(16 + 11) | BIT(11)), /* uart2dbgc_rx */ 712fe202ea8SJianqun Xu RK_MUXROUTE_SAME(2, RK_PD2, 2, 0xe21c, BIT(16 + 14)), /* pcie_clkreqn */ 713fe202ea8SJianqun Xu RK_MUXROUTE_SAME(4, RK_PD0, 1, 0xe21c, BIT(16 + 14) | BIT(14)), /* pcie_clkreqnb */ 714accc1ce7SDavid Wu }; 715accc1ce7SDavid Wu 716c0dadc0eSJianqun Xu static struct rockchip_mux_route_data rk3568_mux_route_data[] = { 717c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PB7, 1, 0x0110, WRITE_MASK_VAL(1, 0, 0)), /* PWM0 IO mux M0 */ 718c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PC7, 2, 0x0110, WRITE_MASK_VAL(1, 0, 1)), /* PWM0 IO mux M1 */ 719c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PC0, 1, 0x0110, WRITE_MASK_VAL(3, 2, 0)), /* PWM1 IO mux M0 */ 720c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PB5, 4, 0x0110, WRITE_MASK_VAL(3, 2, 1)), /* PWM1 IO mux M1 */ 721c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PC1, 1, 0x0110, WRITE_MASK_VAL(5, 4, 0)), /* PWM2 IO mux M0 */ 722c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PB6, 4, 0x0110, WRITE_MASK_VAL(5, 4, 1)), /* PWM2 IO mux M1 */ 723c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PB3, 2, 0x0300, WRITE_MASK_VAL(0, 0, 0)), /* CAN0 IO mux M0 */ 724c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PA1, 4, 0x0300, WRITE_MASK_VAL(0, 0, 1)), /* CAN0 IO mux M1 */ 725c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA1, 3, 0x0300, WRITE_MASK_VAL(2, 2, 0)), /* CAN1 IO mux M0 */ 726c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC3, 3, 0x0300, WRITE_MASK_VAL(2, 2, 1)), /* CAN1 IO mux M1 */ 727c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PB5, 3, 0x0300, WRITE_MASK_VAL(4, 4, 0)), /* CAN2 IO mux M0 */ 728c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PB2, 4, 0x0300, WRITE_MASK_VAL(4, 4, 1)), /* CAN2 IO mux M1 */ 729c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC4, 1, 0x0300, WRITE_MASK_VAL(6, 6, 0)), /* HPDIN IO mux M0 */ 730c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PC2, 2, 0x0300, WRITE_MASK_VAL(6, 6, 1)), /* HPDIN IO mux M1 */ 731c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB1, 3, 0x0300, WRITE_MASK_VAL(8, 8, 0)), /* GMAC1 IO mux M0 */ 732c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PA7, 3, 0x0300, WRITE_MASK_VAL(8, 8, 1)), /* GMAC1 IO mux M1 */ 733c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PD1, 1, 0x0300, WRITE_MASK_VAL(10, 10, 0)), /* HDMITX IO mux M0 */ 734c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PC7, 1, 0x0300, WRITE_MASK_VAL(10, 10, 1)), /* HDMITX IO mux M1 */ 735c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PB6, 1, 0x0300, WRITE_MASK_VAL(14, 14, 0)), /* I2C2 IO mux M0 */ 736c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PB4, 1, 0x0300, WRITE_MASK_VAL(14, 14, 1)), /* I2C2 IO mux M1 */ 737c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA0, 1, 0x0304, WRITE_MASK_VAL(0, 0, 0)), /* I2C3 IO mux M0 */ 738c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB6, 4, 0x0304, WRITE_MASK_VAL(0, 0, 1)), /* I2C3 IO mux M1 */ 739c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PB2, 1, 0x0304, WRITE_MASK_VAL(2, 2, 0)), /* I2C4 IO mux M0 */ 740c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PB1, 2, 0x0304, WRITE_MASK_VAL(2, 2, 1)), /* I2C4 IO mux M1 */ 741c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB4, 4, 0x0304, WRITE_MASK_VAL(4, 4, 0)), /* I2C5 IO mux M0 */ 742c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PD0, 2, 0x0304, WRITE_MASK_VAL(4, 4, 1)), /* I2C5 IO mux M1 */ 743c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB1, 5, 0x0304, WRITE_MASK_VAL(14, 14, 0)), /* PWM8 IO mux M0 */ 744c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PD5, 4, 0x0304, WRITE_MASK_VAL(14, 14, 1)), /* PWM8 IO mux M1 */ 745c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB2, 5, 0x0308, WRITE_MASK_VAL(0, 0, 0)), /* PWM9 IO mux M0 */ 746c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PD6, 4, 0x0308, WRITE_MASK_VAL(0, 0, 1)), /* PWM9 IO mux M1 */ 747c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB5, 5, 0x0308, WRITE_MASK_VAL(2, 2, 0)), /* PWM10 IO mux M0 */ 748c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PA1, 2, 0x0308, WRITE_MASK_VAL(2, 2, 1)), /* PWM10 IO mux M1 */ 749c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB6, 5, 0x0308, WRITE_MASK_VAL(4, 4, 0)), /* PWM11 IO mux M0 */ 750c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC0, 3, 0x0308, WRITE_MASK_VAL(4, 4, 1)), /* PWM11 IO mux M1 */ 751c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB7, 2, 0x0308, WRITE_MASK_VAL(6, 6, 0)), /* PWM12 IO mux M0 */ 752c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(6, 6, 1)), /* PWM12 IO mux M1 */ 753c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC0, 2, 0x0308, WRITE_MASK_VAL(8, 8, 0)), /* PWM13 IO mux M0 */ 754c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC6, 1, 0x0308, WRITE_MASK_VAL(8, 8, 1)), /* PWM13 IO mux M1 */ 755c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC4, 1, 0x0308, WRITE_MASK_VAL(10, 10, 0)), /* PWM14 IO mux M0 */ 756c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC2, 1, 0x0308, WRITE_MASK_VAL(10, 10, 1)), /* PWM14 IO mux M1 */ 757c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(12, 12, 0)), /* PWM15 IO mux M0 */ 758c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC3, 1, 0x0308, WRITE_MASK_VAL(12, 12, 1)), /* PWM15 IO mux M1 */ 759c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PD2, 3, 0x0308, WRITE_MASK_VAL(14, 14, 0)), /* SDMMC2 IO mux M0 */ 760c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PA5, 5, 0x0308, WRITE_MASK_VAL(14, 14, 1)), /* SDMMC2 IO mux M1 */ 761c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PB5, 2, 0x030c, WRITE_MASK_VAL(0, 0, 0)), /* SPI0 IO mux M0 */ 762c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PD3, 3, 0x030c, WRITE_MASK_VAL(0, 0, 1)), /* SPI0 IO mux M1 */ 763c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PB5, 3, 0x030c, WRITE_MASK_VAL(2, 2, 0)), /* SPI1 IO mux M0 */ 764c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC3, 3, 0x030c, WRITE_MASK_VAL(2, 2, 1)), /* SPI1 IO mux M1 */ 765c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PC1, 4, 0x030c, WRITE_MASK_VAL(4, 4, 0)), /* SPI2 IO mux M0 */ 766c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PA0, 3, 0x030c, WRITE_MASK_VAL(4, 4, 1)), /* SPI2 IO mux M1 */ 767c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PB3, 4, 0x030c, WRITE_MASK_VAL(6, 6, 0)), /* SPI3 IO mux M0 */ 768c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC2, 2, 0x030c, WRITE_MASK_VAL(6, 6, 1)), /* SPI3 IO mux M1 */ 769c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PB4, 2, 0x030c, WRITE_MASK_VAL(8, 8, 0)), /* UART1 IO mux M0 */ 770c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(8, 8, 1)), /* UART1 IO mux M1 */ 771c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(10, 10, 0)), /* UART2 IO mux M0 */ 772c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PD5, 2, 0x030c, WRITE_MASK_VAL(10, 10, 1)), /* UART2 IO mux M1 */ 773c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA1, 2, 0x030c, WRITE_MASK_VAL(12, 12, 0)), /* UART3 IO mux M0 */ 774c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB7, 4, 0x030c, WRITE_MASK_VAL(12, 12, 1)), /* UART3 IO mux M1 */ 775c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA6, 2, 0x030c, WRITE_MASK_VAL(14, 14, 0)), /* UART4 IO mux M0 */ 776c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PB2, 4, 0x030c, WRITE_MASK_VAL(14, 14, 1)), /* UART4 IO mux M1 */ 777c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PA2, 3, 0x0310, WRITE_MASK_VAL(0, 0, 0)), /* UART5 IO mux M0 */ 778c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC2, 4, 0x0310, WRITE_MASK_VAL(0, 0, 1)), /* UART5 IO mux M1 */ 779c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PA4, 3, 0x0310, WRITE_MASK_VAL(2, 2, 0)), /* UART6 IO mux M0 */ 780c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PD5, 3, 0x0310, WRITE_MASK_VAL(2, 2, 1)), /* UART6 IO mux M1 */ 781c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PA6, 3, 0x0310, WRITE_MASK_VAL(5, 4, 0)), /* UART7 IO mux M0 */ 782c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC4, 4, 0x0310, WRITE_MASK_VAL(5, 4, 1)), /* UART7 IO mux M1 */ 783c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(5, 4, 2)), /* UART7 IO mux M2 */ 784c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PC5, 3, 0x0310, WRITE_MASK_VAL(6, 6, 0)), /* UART8 IO mux M0 */ 785c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PD7, 4, 0x0310, WRITE_MASK_VAL(6, 6, 1)), /* UART8 IO mux M1 */ 786c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PB0, 3, 0x0310, WRITE_MASK_VAL(9, 8, 0)), /* UART9 IO mux M0 */ 787c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC5, 4, 0x0310, WRITE_MASK_VAL(9, 8, 1)), /* UART9 IO mux M1 */ 788c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PA4, 4, 0x0310, WRITE_MASK_VAL(9, 8, 2)), /* UART9 IO mux M2 */ 789c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA2, 1, 0x0310, WRITE_MASK_VAL(11, 10, 0)), /* I2S1 IO mux M0 */ 790c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC6, 4, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1 IO mux M1 */ 791c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PD0, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1 IO mux M2 */ 792c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PC1, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2 IO mux M0 */ 793c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PB6, 5, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S2 IO mux M1 */ 794c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(14, 14, 0)), /* I2S3 IO mux M0 */ 795c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC2, 5, 0x0310, WRITE_MASK_VAL(14, 14, 1)), /* I2S3 IO mux M1 */ 796c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */ 797c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA6, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */ 798c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PD6, 5, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */ 799c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PA0, 4, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */ 800c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(3, RK_PC4, 5, 0x0314, WRITE_MASK_VAL(1, 0, 2)), /* PDM IO mux M2 */ 801c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PA5, 3, 0x0314, WRITE_MASK_VAL(3, 2, 0)), /* PCIE20 IO mux M0 */ 802c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PD0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 1)), /* PCIE20 IO mux M1 */ 803c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PB0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 2)), /* PCIE20 IO mux M2 */ 804c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(5, 4, 0)), /* PCIE30X1 IO mux M0 */ 805c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PD2, 4, 0x0314, WRITE_MASK_VAL(5, 4, 1)), /* PCIE30X1 IO mux M1 */ 806c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(1, RK_PA5, 4, 0x0314, WRITE_MASK_VAL(5, 4, 2)), /* PCIE30X1 IO mux M2 */ 807c0dadc0eSJianqun Xu RK_MUXROUTE_PMU(0, RK_PA6, 2, 0x0314, WRITE_MASK_VAL(7, 6, 0)), /* PCIE30X2 IO mux M0 */ 808c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(2, RK_PD4, 4, 0x0314, WRITE_MASK_VAL(7, 6, 1)), /* PCIE30X2 IO mux M1 */ 809c0dadc0eSJianqun Xu RK_MUXROUTE_GRF(4, RK_PC2, 4, 0x0314, WRITE_MASK_VAL(7, 6, 2)), /* PCIE30X2 IO mux M2 */ 810d3e51161SHeiko Stübner }; 811d3e51161SHeiko Stübner 812bd35b9bfSDavid Wu static bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin, 81351ff47aaSHeiko Stuebner int mux, u32 *loc, u32 *reg, u32 *value) 814bd35b9bfSDavid Wu { 815bd35b9bfSDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 816bd35b9bfSDavid Wu struct rockchip_pin_ctrl *ctrl = info->ctrl; 817bd35b9bfSDavid Wu struct rockchip_mux_route_data *data; 818bd35b9bfSDavid Wu int i; 819bd35b9bfSDavid Wu 820bd35b9bfSDavid Wu for (i = 0; i < ctrl->niomux_routes; i++) { 821bd35b9bfSDavid Wu data = &ctrl->iomux_routes[i]; 822bd35b9bfSDavid Wu if ((data->bank_num == bank->bank_num) && 823bd35b9bfSDavid Wu (data->pin == pin) && (data->func == mux)) 824bd35b9bfSDavid Wu break; 825bd35b9bfSDavid Wu } 826bd35b9bfSDavid Wu 827bd35b9bfSDavid Wu if (i >= ctrl->niomux_routes) 828bd35b9bfSDavid Wu return false; 829bd35b9bfSDavid Wu 83051ff47aaSHeiko Stuebner *loc = data->route_location; 831bd35b9bfSDavid Wu *reg = data->route_offset; 832bd35b9bfSDavid Wu *value = data->route_val; 833bd35b9bfSDavid Wu 834bd35b9bfSDavid Wu return true; 835bd35b9bfSDavid Wu } 836bd35b9bfSDavid Wu 837a076e2edSHeiko Stübner static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) 838a076e2edSHeiko Stübner { 839a076e2edSHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 840fc72c923SHeiko Stübner int iomux_num = (pin / 8); 84195ec8ae4SHeiko Stübner struct regmap *regmap; 842751a99abSHeiko Stübner unsigned int val; 843ea262ad6Sdavid.wu int reg, ret, mask, mux_type; 844a076e2edSHeiko Stübner u8 bit; 845a076e2edSHeiko Stübner 846fc72c923SHeiko Stübner if (iomux_num > 3) 847fc72c923SHeiko Stübner return -EINVAL; 848fc72c923SHeiko Stübner 84962f49226SHeiko Stübner if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { 85062f49226SHeiko Stübner dev_err(info->dev, "pin %d is unrouted\n", pin); 85162f49226SHeiko Stübner return -EINVAL; 85262f49226SHeiko Stübner } 85362f49226SHeiko Stübner 854fc72c923SHeiko Stübner if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) 855a076e2edSHeiko Stübner return RK_FUNC_GPIO; 856a076e2edSHeiko Stübner 85795ec8ae4SHeiko Stübner regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) 85895ec8ae4SHeiko Stübner ? info->regmap_pmu : info->regmap_base; 85995ec8ae4SHeiko Stübner 860a076e2edSHeiko Stübner /* get basic quadrupel of mux registers and the correct reg inside */ 861ea262ad6Sdavid.wu mux_type = bank->iomux[iomux_num].type; 8626bc0d121SHeiko Stübner reg = bank->iomux[iomux_num].offset; 863ea262ad6Sdavid.wu if (mux_type & IOMUX_WIDTH_4BIT) { 86403716e1dSHeiko Stübner if ((pin % 8) >= 4) 86503716e1dSHeiko Stübner reg += 0x4; 86603716e1dSHeiko Stübner bit = (pin % 4) * 4; 8678b6c6f93Sdavid.wu mask = 0xf; 868ea262ad6Sdavid.wu } else if (mux_type & IOMUX_WIDTH_3BIT) { 8698b6c6f93Sdavid.wu if ((pin % 8) >= 5) 8708b6c6f93Sdavid.wu reg += 0x4; 8718b6c6f93Sdavid.wu bit = (pin % 8 % 5) * 3; 8728b6c6f93Sdavid.wu mask = 0x7; 87303716e1dSHeiko Stübner } else { 874a076e2edSHeiko Stübner bit = (pin % 8) * 2; 8758b6c6f93Sdavid.wu mask = 0x3; 87603716e1dSHeiko Stübner } 877a076e2edSHeiko Stübner 878c04c3fa6SDavid Wu if (bank->recalced_mask & BIT(pin)) 879c04c3fa6SDavid Wu rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); 880ea262ad6Sdavid.wu 88195ec8ae4SHeiko Stübner ret = regmap_read(regmap, reg, &val); 882751a99abSHeiko Stübner if (ret) 883751a99abSHeiko Stübner return ret; 884751a99abSHeiko Stübner 88503716e1dSHeiko Stübner return ((val >> bit) & mask); 886a076e2edSHeiko Stübner } 887a076e2edSHeiko Stübner 88805709c3eSJohn Keeping static int rockchip_verify_mux(struct rockchip_pin_bank *bank, 88905709c3eSJohn Keeping int pin, int mux) 89005709c3eSJohn Keeping { 89105709c3eSJohn Keeping struct rockchip_pinctrl *info = bank->drvdata; 892e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 89305709c3eSJohn Keeping int iomux_num = (pin / 8); 89405709c3eSJohn Keeping 89505709c3eSJohn Keeping if (iomux_num > 3) 89605709c3eSJohn Keeping return -EINVAL; 89705709c3eSJohn Keeping 89805709c3eSJohn Keeping if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { 899e4dd7fd5SAndy Shevchenko dev_err(dev, "pin %d is unrouted\n", pin); 90005709c3eSJohn Keeping return -EINVAL; 90105709c3eSJohn Keeping } 90205709c3eSJohn Keeping 90305709c3eSJohn Keeping if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) { 90405709c3eSJohn Keeping if (mux != RK_FUNC_GPIO) { 905e4dd7fd5SAndy Shevchenko dev_err(dev, "pin %d only supports a gpio mux\n", pin); 90605709c3eSJohn Keeping return -ENOTSUPP; 90705709c3eSJohn Keeping } 90805709c3eSJohn Keeping } 90905709c3eSJohn Keeping 91005709c3eSJohn Keeping return 0; 91105709c3eSJohn Keeping } 91205709c3eSJohn Keeping 913d3e51161SHeiko Stübner /* 914d3e51161SHeiko Stübner * Set a new mux function for a pin. 915d3e51161SHeiko Stübner * 916d3e51161SHeiko Stübner * The register is divided into the upper and lower 16 bit. When changing 917d3e51161SHeiko Stübner * a value, the previous register value is not read and changed. Instead 918d3e51161SHeiko Stübner * it seems the changed bits are marked in the upper 16 bit, while the 919d3e51161SHeiko Stübner * changed value gets set in the same offset in the lower 16 bit. 920d3e51161SHeiko Stübner * All pin settings seem to be 2 bit wide in both the upper and lower 921d3e51161SHeiko Stübner * parts. 922d3e51161SHeiko Stübner * @bank: pin bank to change 923d3e51161SHeiko Stübner * @pin: pin to change 924d3e51161SHeiko Stübner * @mux: new mux function to set 925d3e51161SHeiko Stübner */ 92614797189SHeiko Stübner static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) 927d3e51161SHeiko Stübner { 928d3e51161SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 929e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 930fc72c923SHeiko Stübner int iomux_num = (pin / 8); 93195ec8ae4SHeiko Stübner struct regmap *regmap; 932ea262ad6Sdavid.wu int reg, ret, mask, mux_type; 933d3e51161SHeiko Stübner u8 bit; 93451ff47aaSHeiko Stuebner u32 data, rmask, route_location, route_reg, route_val; 935d3e51161SHeiko Stübner 93605709c3eSJohn Keeping ret = rockchip_verify_mux(bank, pin, mux); 93705709c3eSJohn Keeping if (ret < 0) 93805709c3eSJohn Keeping return ret; 939fc72c923SHeiko Stübner 94005709c3eSJohn Keeping if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) 941c4a532deSHeiko Stübner return 0; 942c4a532deSHeiko Stübner 943e4dd7fd5SAndy Shevchenko dev_dbg(dev, "setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); 944d3e51161SHeiko Stübner 94595ec8ae4SHeiko Stübner regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) 94695ec8ae4SHeiko Stübner ? info->regmap_pmu : info->regmap_base; 94795ec8ae4SHeiko Stübner 948d3e51161SHeiko Stübner /* get basic quadrupel of mux registers and the correct reg inside */ 949ea262ad6Sdavid.wu mux_type = bank->iomux[iomux_num].type; 9506bc0d121SHeiko Stübner reg = bank->iomux[iomux_num].offset; 951ea262ad6Sdavid.wu if (mux_type & IOMUX_WIDTH_4BIT) { 95203716e1dSHeiko Stübner if ((pin % 8) >= 4) 95303716e1dSHeiko Stübner reg += 0x4; 95403716e1dSHeiko Stübner bit = (pin % 4) * 4; 9558b6c6f93Sdavid.wu mask = 0xf; 956ea262ad6Sdavid.wu } else if (mux_type & IOMUX_WIDTH_3BIT) { 9578b6c6f93Sdavid.wu if ((pin % 8) >= 5) 9588b6c6f93Sdavid.wu reg += 0x4; 9598b6c6f93Sdavid.wu bit = (pin % 8 % 5) * 3; 9608b6c6f93Sdavid.wu mask = 0x7; 96103716e1dSHeiko Stübner } else { 962d3e51161SHeiko Stübner bit = (pin % 8) * 2; 9638b6c6f93Sdavid.wu mask = 0x3; 96403716e1dSHeiko Stübner } 965d3e51161SHeiko Stübner 966c04c3fa6SDavid Wu if (bank->recalced_mask & BIT(pin)) 967c04c3fa6SDavid Wu rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); 968ea262ad6Sdavid.wu 969bd35b9bfSDavid Wu if (bank->route_mask & BIT(pin)) { 97051ff47aaSHeiko Stuebner if (rockchip_get_mux_route(bank, pin, mux, &route_location, 97151ff47aaSHeiko Stuebner &route_reg, &route_val)) { 97251ff47aaSHeiko Stuebner struct regmap *route_regmap = regmap; 97351ff47aaSHeiko Stuebner 97451ff47aaSHeiko Stuebner /* handle special locations */ 97551ff47aaSHeiko Stuebner switch (route_location) { 97651ff47aaSHeiko Stuebner case ROCKCHIP_ROUTE_PMU: 97751ff47aaSHeiko Stuebner route_regmap = info->regmap_pmu; 97851ff47aaSHeiko Stuebner break; 97951ff47aaSHeiko Stuebner case ROCKCHIP_ROUTE_GRF: 98051ff47aaSHeiko Stuebner route_regmap = info->regmap_base; 98151ff47aaSHeiko Stuebner break; 98251ff47aaSHeiko Stuebner } 98351ff47aaSHeiko Stuebner 98451ff47aaSHeiko Stuebner ret = regmap_write(route_regmap, route_reg, route_val); 985bd35b9bfSDavid Wu if (ret) 986bd35b9bfSDavid Wu return ret; 987bd35b9bfSDavid Wu } 988bd35b9bfSDavid Wu } 989bd35b9bfSDavid Wu 99003716e1dSHeiko Stübner data = (mask << (bit + 16)); 99199e872d9SSonny Rao rmask = data | (data >> 16); 99203716e1dSHeiko Stübner data |= (mux & mask) << bit; 99399e872d9SSonny Rao ret = regmap_update_bits(regmap, reg, rmask, data); 994d3e51161SHeiko Stübner 995751a99abSHeiko Stübner return ret; 996d3e51161SHeiko Stübner } 997d3e51161SHeiko Stübner 99887065ca9SDavid Wu #define PX30_PULL_PMU_OFFSET 0x10 99987065ca9SDavid Wu #define PX30_PULL_GRF_OFFSET 0x60 100087065ca9SDavid Wu #define PX30_PULL_BITS_PER_PIN 2 100187065ca9SDavid Wu #define PX30_PULL_PINS_PER_REG 8 100287065ca9SDavid Wu #define PX30_PULL_BANK_STRIDE 16 100387065ca9SDavid Wu 100487065ca9SDavid Wu static void px30_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 100587065ca9SDavid Wu int pin_num, struct regmap **regmap, 100687065ca9SDavid Wu int *reg, u8 *bit) 100787065ca9SDavid Wu { 100887065ca9SDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 100987065ca9SDavid Wu 101087065ca9SDavid Wu /* The first 32 pins of the first bank are located in PMU */ 101187065ca9SDavid Wu if (bank->bank_num == 0) { 101287065ca9SDavid Wu *regmap = info->regmap_pmu; 101387065ca9SDavid Wu *reg = PX30_PULL_PMU_OFFSET; 101487065ca9SDavid Wu } else { 101587065ca9SDavid Wu *regmap = info->regmap_base; 101687065ca9SDavid Wu *reg = PX30_PULL_GRF_OFFSET; 101787065ca9SDavid Wu 101887065ca9SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 101987065ca9SDavid Wu *reg -= 0x10; 102087065ca9SDavid Wu *reg += bank->bank_num * PX30_PULL_BANK_STRIDE; 102187065ca9SDavid Wu } 102287065ca9SDavid Wu 102387065ca9SDavid Wu *reg += ((pin_num / PX30_PULL_PINS_PER_REG) * 4); 102487065ca9SDavid Wu *bit = (pin_num % PX30_PULL_PINS_PER_REG); 102587065ca9SDavid Wu *bit *= PX30_PULL_BITS_PER_PIN; 102687065ca9SDavid Wu } 102787065ca9SDavid Wu 102887065ca9SDavid Wu #define PX30_DRV_PMU_OFFSET 0x20 102987065ca9SDavid Wu #define PX30_DRV_GRF_OFFSET 0xf0 103087065ca9SDavid Wu #define PX30_DRV_BITS_PER_PIN 2 103187065ca9SDavid Wu #define PX30_DRV_PINS_PER_REG 8 103287065ca9SDavid Wu #define PX30_DRV_BANK_STRIDE 16 103387065ca9SDavid Wu 103487065ca9SDavid Wu static void px30_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 103587065ca9SDavid Wu int pin_num, struct regmap **regmap, 103687065ca9SDavid Wu int *reg, u8 *bit) 103787065ca9SDavid Wu { 103887065ca9SDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 103987065ca9SDavid Wu 104087065ca9SDavid Wu /* The first 32 pins of the first bank are located in PMU */ 104187065ca9SDavid Wu if (bank->bank_num == 0) { 104287065ca9SDavid Wu *regmap = info->regmap_pmu; 104387065ca9SDavid Wu *reg = PX30_DRV_PMU_OFFSET; 104487065ca9SDavid Wu } else { 104587065ca9SDavid Wu *regmap = info->regmap_base; 104687065ca9SDavid Wu *reg = PX30_DRV_GRF_OFFSET; 104787065ca9SDavid Wu 104887065ca9SDavid Wu /* correct the offset, as we're starting with the 2nd bank */ 104987065ca9SDavid Wu *reg -= 0x10; 105087065ca9SDavid Wu *reg += bank->bank_num * PX30_DRV_BANK_STRIDE; 105187065ca9SDavid Wu } 105287065ca9SDavid Wu 105387065ca9SDavid Wu *reg += ((pin_num / PX30_DRV_PINS_PER_REG) * 4); 105487065ca9SDavid Wu *bit = (pin_num % PX30_DRV_PINS_PER_REG); 105587065ca9SDavid Wu *bit *= PX30_DRV_BITS_PER_PIN; 105687065ca9SDavid Wu } 105787065ca9SDavid Wu 105887065ca9SDavid Wu #define PX30_SCHMITT_PMU_OFFSET 0x38 105987065ca9SDavid Wu #define PX30_SCHMITT_GRF_OFFSET 0xc0 106087065ca9SDavid Wu #define PX30_SCHMITT_PINS_PER_PMU_REG 16 106187065ca9SDavid Wu #define PX30_SCHMITT_BANK_STRIDE 16 106287065ca9SDavid Wu #define PX30_SCHMITT_PINS_PER_GRF_REG 8 106387065ca9SDavid Wu 106487065ca9SDavid Wu static int px30_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 106587065ca9SDavid Wu int pin_num, 106687065ca9SDavid Wu struct regmap **regmap, 106787065ca9SDavid Wu int *reg, u8 *bit) 106887065ca9SDavid Wu { 106987065ca9SDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 107087065ca9SDavid Wu int pins_per_reg; 107187065ca9SDavid Wu 107287065ca9SDavid Wu if (bank->bank_num == 0) { 107387065ca9SDavid Wu *regmap = info->regmap_pmu; 107487065ca9SDavid Wu *reg = PX30_SCHMITT_PMU_OFFSET; 107587065ca9SDavid Wu pins_per_reg = PX30_SCHMITT_PINS_PER_PMU_REG; 107687065ca9SDavid Wu } else { 107787065ca9SDavid Wu *regmap = info->regmap_base; 107887065ca9SDavid Wu *reg = PX30_SCHMITT_GRF_OFFSET; 107987065ca9SDavid Wu pins_per_reg = PX30_SCHMITT_PINS_PER_GRF_REG; 108087065ca9SDavid Wu *reg += (bank->bank_num - 1) * PX30_SCHMITT_BANK_STRIDE; 108187065ca9SDavid Wu } 108287065ca9SDavid Wu 108387065ca9SDavid Wu *reg += ((pin_num / pins_per_reg) * 4); 108487065ca9SDavid Wu *bit = pin_num % pins_per_reg; 108587065ca9SDavid Wu 108687065ca9SDavid Wu return 0; 108787065ca9SDavid Wu } 108887065ca9SDavid Wu 1089b9c6dcabSAndy Yan #define RV1108_PULL_PMU_OFFSET 0x10 1090b9c6dcabSAndy Yan #define RV1108_PULL_OFFSET 0x110 1091b9c6dcabSAndy Yan #define RV1108_PULL_PINS_PER_REG 8 1092b9c6dcabSAndy Yan #define RV1108_PULL_BITS_PER_PIN 2 1093b9c6dcabSAndy Yan #define RV1108_PULL_BANK_STRIDE 16 1094688daf23SAndy Yan 1095b9c6dcabSAndy Yan static void rv1108_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1096688daf23SAndy Yan int pin_num, struct regmap **regmap, 1097688daf23SAndy Yan int *reg, u8 *bit) 1098688daf23SAndy Yan { 1099688daf23SAndy Yan struct rockchip_pinctrl *info = bank->drvdata; 1100688daf23SAndy Yan 1101688daf23SAndy Yan /* The first 24 pins of the first bank are located in PMU */ 1102688daf23SAndy Yan if (bank->bank_num == 0) { 1103688daf23SAndy Yan *regmap = info->regmap_pmu; 1104b9c6dcabSAndy Yan *reg = RV1108_PULL_PMU_OFFSET; 1105688daf23SAndy Yan } else { 1106b9c6dcabSAndy Yan *reg = RV1108_PULL_OFFSET; 1107688daf23SAndy Yan *regmap = info->regmap_base; 1108688daf23SAndy Yan /* correct the offset, as we're starting with the 2nd bank */ 1109688daf23SAndy Yan *reg -= 0x10; 1110b9c6dcabSAndy Yan *reg += bank->bank_num * RV1108_PULL_BANK_STRIDE; 1111688daf23SAndy Yan } 1112688daf23SAndy Yan 1113b9c6dcabSAndy Yan *reg += ((pin_num / RV1108_PULL_PINS_PER_REG) * 4); 1114b9c6dcabSAndy Yan *bit = (pin_num % RV1108_PULL_PINS_PER_REG); 1115b9c6dcabSAndy Yan *bit *= RV1108_PULL_BITS_PER_PIN; 1116688daf23SAndy Yan } 1117688daf23SAndy Yan 1118b9c6dcabSAndy Yan #define RV1108_DRV_PMU_OFFSET 0x20 1119b9c6dcabSAndy Yan #define RV1108_DRV_GRF_OFFSET 0x210 1120b9c6dcabSAndy Yan #define RV1108_DRV_BITS_PER_PIN 2 1121b9c6dcabSAndy Yan #define RV1108_DRV_PINS_PER_REG 8 1122b9c6dcabSAndy Yan #define RV1108_DRV_BANK_STRIDE 16 1123688daf23SAndy Yan 1124b9c6dcabSAndy Yan static void rv1108_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 1125688daf23SAndy Yan int pin_num, struct regmap **regmap, 1126688daf23SAndy Yan int *reg, u8 *bit) 1127688daf23SAndy Yan { 1128688daf23SAndy Yan struct rockchip_pinctrl *info = bank->drvdata; 1129688daf23SAndy Yan 1130688daf23SAndy Yan /* The first 24 pins of the first bank are located in PMU */ 1131688daf23SAndy Yan if (bank->bank_num == 0) { 1132688daf23SAndy Yan *regmap = info->regmap_pmu; 1133b9c6dcabSAndy Yan *reg = RV1108_DRV_PMU_OFFSET; 1134688daf23SAndy Yan } else { 1135688daf23SAndy Yan *regmap = info->regmap_base; 1136b9c6dcabSAndy Yan *reg = RV1108_DRV_GRF_OFFSET; 1137688daf23SAndy Yan 1138688daf23SAndy Yan /* correct the offset, as we're starting with the 2nd bank */ 1139688daf23SAndy Yan *reg -= 0x10; 1140b9c6dcabSAndy Yan *reg += bank->bank_num * RV1108_DRV_BANK_STRIDE; 1141688daf23SAndy Yan } 1142688daf23SAndy Yan 1143b9c6dcabSAndy Yan *reg += ((pin_num / RV1108_DRV_PINS_PER_REG) * 4); 1144b9c6dcabSAndy Yan *bit = pin_num % RV1108_DRV_PINS_PER_REG; 1145b9c6dcabSAndy Yan *bit *= RV1108_DRV_BITS_PER_PIN; 1146688daf23SAndy Yan } 1147688daf23SAndy Yan 11485caff7eaSAndy Yan #define RV1108_SCHMITT_PMU_OFFSET 0x30 11495caff7eaSAndy Yan #define RV1108_SCHMITT_GRF_OFFSET 0x388 11505caff7eaSAndy Yan #define RV1108_SCHMITT_BANK_STRIDE 8 11515caff7eaSAndy Yan #define RV1108_SCHMITT_PINS_PER_GRF_REG 16 11525caff7eaSAndy Yan #define RV1108_SCHMITT_PINS_PER_PMU_REG 8 11535caff7eaSAndy Yan 11545caff7eaSAndy Yan static int rv1108_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 11555caff7eaSAndy Yan int pin_num, 11565caff7eaSAndy Yan struct regmap **regmap, 11575caff7eaSAndy Yan int *reg, u8 *bit) 11585caff7eaSAndy Yan { 11595caff7eaSAndy Yan struct rockchip_pinctrl *info = bank->drvdata; 11605caff7eaSAndy Yan int pins_per_reg; 11615caff7eaSAndy Yan 11625caff7eaSAndy Yan if (bank->bank_num == 0) { 11635caff7eaSAndy Yan *regmap = info->regmap_pmu; 11645caff7eaSAndy Yan *reg = RV1108_SCHMITT_PMU_OFFSET; 11655caff7eaSAndy Yan pins_per_reg = RV1108_SCHMITT_PINS_PER_PMU_REG; 11665caff7eaSAndy Yan } else { 11675caff7eaSAndy Yan *regmap = info->regmap_base; 11685caff7eaSAndy Yan *reg = RV1108_SCHMITT_GRF_OFFSET; 11695caff7eaSAndy Yan pins_per_reg = RV1108_SCHMITT_PINS_PER_GRF_REG; 11705caff7eaSAndy Yan *reg += (bank->bank_num - 1) * RV1108_SCHMITT_BANK_STRIDE; 11715caff7eaSAndy Yan } 11725caff7eaSAndy Yan *reg += ((pin_num / pins_per_reg) * 4); 11735caff7eaSAndy Yan *bit = pin_num % pins_per_reg; 11745caff7eaSAndy Yan 11755caff7eaSAndy Yan return 0; 11765caff7eaSAndy Yan } 11775caff7eaSAndy Yan 11787825aeb7SJianqun Xu #define RK3308_SCHMITT_PINS_PER_REG 8 11797825aeb7SJianqun Xu #define RK3308_SCHMITT_BANK_STRIDE 16 11807825aeb7SJianqun Xu #define RK3308_SCHMITT_GRF_OFFSET 0x1a0 11817825aeb7SJianqun Xu 11827825aeb7SJianqun Xu static int rk3308_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 11837825aeb7SJianqun Xu int pin_num, struct regmap **regmap, 11847825aeb7SJianqun Xu int *reg, u8 *bit) 11857825aeb7SJianqun Xu { 11867825aeb7SJianqun Xu struct rockchip_pinctrl *info = bank->drvdata; 11877825aeb7SJianqun Xu 11887825aeb7SJianqun Xu *regmap = info->regmap_base; 11897825aeb7SJianqun Xu *reg = RK3308_SCHMITT_GRF_OFFSET; 11907825aeb7SJianqun Xu 11917825aeb7SJianqun Xu *reg += bank->bank_num * RK3308_SCHMITT_BANK_STRIDE; 11927825aeb7SJianqun Xu *reg += ((pin_num / RK3308_SCHMITT_PINS_PER_REG) * 4); 11937825aeb7SJianqun Xu *bit = pin_num % RK3308_SCHMITT_PINS_PER_REG; 11947825aeb7SJianqun Xu 11957825aeb7SJianqun Xu return 0; 11967825aeb7SJianqun Xu } 11977825aeb7SJianqun Xu 1198a282926dSHeiko Stübner #define RK2928_PULL_OFFSET 0x118 1199a282926dSHeiko Stübner #define RK2928_PULL_PINS_PER_REG 16 1200a282926dSHeiko Stübner #define RK2928_PULL_BANK_STRIDE 8 1201a282926dSHeiko Stübner 1202a282926dSHeiko Stübner static void rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1203751a99abSHeiko Stübner int pin_num, struct regmap **regmap, 1204751a99abSHeiko Stübner int *reg, u8 *bit) 1205a282926dSHeiko Stübner { 1206a282926dSHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1207a282926dSHeiko Stübner 1208751a99abSHeiko Stübner *regmap = info->regmap_base; 1209751a99abSHeiko Stübner *reg = RK2928_PULL_OFFSET; 1210a282926dSHeiko Stübner *reg += bank->bank_num * RK2928_PULL_BANK_STRIDE; 1211a282926dSHeiko Stübner *reg += (pin_num / RK2928_PULL_PINS_PER_REG) * 4; 1212a282926dSHeiko Stübner 1213a282926dSHeiko Stübner *bit = pin_num % RK2928_PULL_PINS_PER_REG; 1214a282926dSHeiko Stübner }; 1215a282926dSHeiko Stübner 1216d23c66dfSDavid Wu #define RK3128_PULL_OFFSET 0x118 1217d23c66dfSDavid Wu 1218d23c66dfSDavid Wu static void rk3128_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1219d23c66dfSDavid Wu int pin_num, struct regmap **regmap, 1220d23c66dfSDavid Wu int *reg, u8 *bit) 1221d23c66dfSDavid Wu { 1222d23c66dfSDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 1223d23c66dfSDavid Wu 1224d23c66dfSDavid Wu *regmap = info->regmap_base; 1225d23c66dfSDavid Wu *reg = RK3128_PULL_OFFSET; 1226d23c66dfSDavid Wu *reg += bank->bank_num * RK2928_PULL_BANK_STRIDE; 1227d23c66dfSDavid Wu *reg += ((pin_num / RK2928_PULL_PINS_PER_REG) * 4); 1228d23c66dfSDavid Wu 1229d23c66dfSDavid Wu *bit = pin_num % RK2928_PULL_PINS_PER_REG; 1230d23c66dfSDavid Wu } 1231d23c66dfSDavid Wu 1232bfc7a42aSHeiko Stübner #define RK3188_PULL_OFFSET 0x164 12336ca5274dSHeiko Stübner #define RK3188_PULL_BITS_PER_PIN 2 12346ca5274dSHeiko Stübner #define RK3188_PULL_PINS_PER_REG 8 12356ca5274dSHeiko Stübner #define RK3188_PULL_BANK_STRIDE 16 123614dee867SHeiko Stübner #define RK3188_PULL_PMU_OFFSET 0x64 12376ca5274dSHeiko Stübner 12386ca5274dSHeiko Stübner static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1239751a99abSHeiko Stübner int pin_num, struct regmap **regmap, 1240751a99abSHeiko Stübner int *reg, u8 *bit) 12416ca5274dSHeiko Stübner { 12426ca5274dSHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 12436ca5274dSHeiko Stübner 12446ca5274dSHeiko Stübner /* The first 12 pins of the first bank are located elsewhere */ 1245fc72c923SHeiko Stübner if (bank->bank_num == 0 && pin_num < 12) { 124614dee867SHeiko Stübner *regmap = info->regmap_pmu ? info->regmap_pmu 124714dee867SHeiko Stübner : bank->regmap_pull; 124814dee867SHeiko Stübner *reg = info->regmap_pmu ? RK3188_PULL_PMU_OFFSET : 0; 1249751a99abSHeiko Stübner *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 12506ca5274dSHeiko Stübner *bit = pin_num % RK3188_PULL_PINS_PER_REG; 12516ca5274dSHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 12526ca5274dSHeiko Stübner } else { 1253751a99abSHeiko Stübner *regmap = info->regmap_pull ? info->regmap_pull 1254751a99abSHeiko Stübner : info->regmap_base; 1255751a99abSHeiko Stübner *reg = info->regmap_pull ? 0 : RK3188_PULL_OFFSET; 1256751a99abSHeiko Stübner 1257bfc7a42aSHeiko Stübner /* correct the offset, as it is the 2nd pull register */ 1258bfc7a42aSHeiko Stübner *reg -= 4; 12596ca5274dSHeiko Stübner *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 12606ca5274dSHeiko Stübner *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 12616ca5274dSHeiko Stübner 12626ca5274dSHeiko Stübner /* 12636ca5274dSHeiko Stübner * The bits in these registers have an inverse ordering 12646ca5274dSHeiko Stübner * with the lowest pin being in bits 15:14 and the highest 12656ca5274dSHeiko Stübner * pin in bits 1:0 12666ca5274dSHeiko Stübner */ 12676ca5274dSHeiko Stübner *bit = 7 - (pin_num % RK3188_PULL_PINS_PER_REG); 12686ca5274dSHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 12696ca5274dSHeiko Stübner } 12706ca5274dSHeiko Stübner } 12716ca5274dSHeiko Stübner 1272304f077dSHeiko Stübner #define RK3288_PULL_OFFSET 0x140 1273304f077dSHeiko Stübner static void rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1274304f077dSHeiko Stübner int pin_num, struct regmap **regmap, 1275304f077dSHeiko Stübner int *reg, u8 *bit) 1276304f077dSHeiko Stübner { 1277304f077dSHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1278304f077dSHeiko Stübner 1279304f077dSHeiko Stübner /* The first 24 pins of the first bank are located in PMU */ 1280304f077dSHeiko Stübner if (bank->bank_num == 0) { 1281304f077dSHeiko Stübner *regmap = info->regmap_pmu; 1282304f077dSHeiko Stübner *reg = RK3188_PULL_PMU_OFFSET; 1283304f077dSHeiko Stübner 1284304f077dSHeiko Stübner *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 1285304f077dSHeiko Stübner *bit = pin_num % RK3188_PULL_PINS_PER_REG; 1286304f077dSHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 1287304f077dSHeiko Stübner } else { 1288304f077dSHeiko Stübner *regmap = info->regmap_base; 1289304f077dSHeiko Stübner *reg = RK3288_PULL_OFFSET; 1290304f077dSHeiko Stübner 1291304f077dSHeiko Stübner /* correct the offset, as we're starting with the 2nd bank */ 1292304f077dSHeiko Stübner *reg -= 0x10; 1293304f077dSHeiko Stübner *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 1294304f077dSHeiko Stübner *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 1295304f077dSHeiko Stübner 1296304f077dSHeiko Stübner *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 1297304f077dSHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 1298304f077dSHeiko Stübner } 1299304f077dSHeiko Stübner } 1300304f077dSHeiko Stübner 1301b547c800SHeiko Stübner #define RK3288_DRV_PMU_OFFSET 0x70 1302b547c800SHeiko Stübner #define RK3288_DRV_GRF_OFFSET 0x1c0 1303b547c800SHeiko Stübner #define RK3288_DRV_BITS_PER_PIN 2 1304b547c800SHeiko Stübner #define RK3288_DRV_PINS_PER_REG 8 1305b547c800SHeiko Stübner #define RK3288_DRV_BANK_STRIDE 16 1306b547c800SHeiko Stübner 1307b547c800SHeiko Stübner static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 1308b547c800SHeiko Stübner int pin_num, struct regmap **regmap, 1309b547c800SHeiko Stübner int *reg, u8 *bit) 1310b547c800SHeiko Stübner { 1311b547c800SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1312b547c800SHeiko Stübner 1313b547c800SHeiko Stübner /* The first 24 pins of the first bank are located in PMU */ 1314b547c800SHeiko Stübner if (bank->bank_num == 0) { 1315b547c800SHeiko Stübner *regmap = info->regmap_pmu; 1316b547c800SHeiko Stübner *reg = RK3288_DRV_PMU_OFFSET; 1317b547c800SHeiko Stübner 1318b547c800SHeiko Stübner *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 1319b547c800SHeiko Stübner *bit = pin_num % RK3288_DRV_PINS_PER_REG; 1320b547c800SHeiko Stübner *bit *= RK3288_DRV_BITS_PER_PIN; 1321b547c800SHeiko Stübner } else { 1322b547c800SHeiko Stübner *regmap = info->regmap_base; 1323b547c800SHeiko Stübner *reg = RK3288_DRV_GRF_OFFSET; 1324b547c800SHeiko Stübner 1325b547c800SHeiko Stübner /* correct the offset, as we're starting with the 2nd bank */ 1326b547c800SHeiko Stübner *reg -= 0x10; 1327b547c800SHeiko Stübner *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; 1328b547c800SHeiko Stübner *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 1329b547c800SHeiko Stübner 1330b547c800SHeiko Stübner *bit = (pin_num % RK3288_DRV_PINS_PER_REG); 1331b547c800SHeiko Stübner *bit *= RK3288_DRV_BITS_PER_PIN; 1332b547c800SHeiko Stübner } 1333b547c800SHeiko Stübner } 1334b547c800SHeiko Stübner 1335fea0fe60SJeffy Chen #define RK3228_PULL_OFFSET 0x100 1336fea0fe60SJeffy Chen 1337fea0fe60SJeffy Chen static void rk3228_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1338fea0fe60SJeffy Chen int pin_num, struct regmap **regmap, 1339fea0fe60SJeffy Chen int *reg, u8 *bit) 1340fea0fe60SJeffy Chen { 1341fea0fe60SJeffy Chen struct rockchip_pinctrl *info = bank->drvdata; 1342fea0fe60SJeffy Chen 1343fea0fe60SJeffy Chen *regmap = info->regmap_base; 1344fea0fe60SJeffy Chen *reg = RK3228_PULL_OFFSET; 1345fea0fe60SJeffy Chen *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 1346fea0fe60SJeffy Chen *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 1347fea0fe60SJeffy Chen 1348fea0fe60SJeffy Chen *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 1349fea0fe60SJeffy Chen *bit *= RK3188_PULL_BITS_PER_PIN; 1350fea0fe60SJeffy Chen } 1351fea0fe60SJeffy Chen 1352fea0fe60SJeffy Chen #define RK3228_DRV_GRF_OFFSET 0x200 1353fea0fe60SJeffy Chen 1354fea0fe60SJeffy Chen static void rk3228_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 1355fea0fe60SJeffy Chen int pin_num, struct regmap **regmap, 1356fea0fe60SJeffy Chen int *reg, u8 *bit) 1357fea0fe60SJeffy Chen { 1358fea0fe60SJeffy Chen struct rockchip_pinctrl *info = bank->drvdata; 1359fea0fe60SJeffy Chen 1360fea0fe60SJeffy Chen *regmap = info->regmap_base; 1361fea0fe60SJeffy Chen *reg = RK3228_DRV_GRF_OFFSET; 1362fea0fe60SJeffy Chen *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; 1363fea0fe60SJeffy Chen *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 1364fea0fe60SJeffy Chen 1365fea0fe60SJeffy Chen *bit = (pin_num % RK3288_DRV_PINS_PER_REG); 1366fea0fe60SJeffy Chen *bit *= RK3288_DRV_BITS_PER_PIN; 1367fea0fe60SJeffy Chen } 1368fea0fe60SJeffy Chen 13697825aeb7SJianqun Xu #define RK3308_PULL_OFFSET 0xa0 13707825aeb7SJianqun Xu 13717825aeb7SJianqun Xu static void rk3308_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 13727825aeb7SJianqun Xu int pin_num, struct regmap **regmap, 13737825aeb7SJianqun Xu int *reg, u8 *bit) 13747825aeb7SJianqun Xu { 13757825aeb7SJianqun Xu struct rockchip_pinctrl *info = bank->drvdata; 13767825aeb7SJianqun Xu 13777825aeb7SJianqun Xu *regmap = info->regmap_base; 13787825aeb7SJianqun Xu *reg = RK3308_PULL_OFFSET; 13797825aeb7SJianqun Xu *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 13807825aeb7SJianqun Xu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 13817825aeb7SJianqun Xu 13827825aeb7SJianqun Xu *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 13837825aeb7SJianqun Xu *bit *= RK3188_PULL_BITS_PER_PIN; 13847825aeb7SJianqun Xu } 13857825aeb7SJianqun Xu 13867825aeb7SJianqun Xu #define RK3308_DRV_GRF_OFFSET 0x100 13877825aeb7SJianqun Xu 13887825aeb7SJianqun Xu static void rk3308_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 13897825aeb7SJianqun Xu int pin_num, struct regmap **regmap, 13907825aeb7SJianqun Xu int *reg, u8 *bit) 13917825aeb7SJianqun Xu { 13927825aeb7SJianqun Xu struct rockchip_pinctrl *info = bank->drvdata; 13937825aeb7SJianqun Xu 13947825aeb7SJianqun Xu *regmap = info->regmap_base; 13957825aeb7SJianqun Xu *reg = RK3308_DRV_GRF_OFFSET; 13967825aeb7SJianqun Xu *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; 13977825aeb7SJianqun Xu *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 13987825aeb7SJianqun Xu 13997825aeb7SJianqun Xu *bit = (pin_num % RK3288_DRV_PINS_PER_REG); 14007825aeb7SJianqun Xu *bit *= RK3288_DRV_BITS_PER_PIN; 14017825aeb7SJianqun Xu } 14027825aeb7SJianqun Xu 1403daecdc66SHeiko Stübner #define RK3368_PULL_GRF_OFFSET 0x100 1404daecdc66SHeiko Stübner #define RK3368_PULL_PMU_OFFSET 0x10 1405daecdc66SHeiko Stübner 1406daecdc66SHeiko Stübner static void rk3368_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1407daecdc66SHeiko Stübner int pin_num, struct regmap **regmap, 1408daecdc66SHeiko Stübner int *reg, u8 *bit) 1409daecdc66SHeiko Stübner { 1410daecdc66SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1411daecdc66SHeiko Stübner 1412daecdc66SHeiko Stübner /* The first 32 pins of the first bank are located in PMU */ 1413daecdc66SHeiko Stübner if (bank->bank_num == 0) { 1414daecdc66SHeiko Stübner *regmap = info->regmap_pmu; 1415daecdc66SHeiko Stübner *reg = RK3368_PULL_PMU_OFFSET; 1416daecdc66SHeiko Stübner 1417daecdc66SHeiko Stübner *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 1418daecdc66SHeiko Stübner *bit = pin_num % RK3188_PULL_PINS_PER_REG; 1419daecdc66SHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 1420daecdc66SHeiko Stübner } else { 1421daecdc66SHeiko Stübner *regmap = info->regmap_base; 1422daecdc66SHeiko Stübner *reg = RK3368_PULL_GRF_OFFSET; 1423daecdc66SHeiko Stübner 1424daecdc66SHeiko Stübner /* correct the offset, as we're starting with the 2nd bank */ 1425daecdc66SHeiko Stübner *reg -= 0x10; 1426daecdc66SHeiko Stübner *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 1427daecdc66SHeiko Stübner *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 1428daecdc66SHeiko Stübner 1429daecdc66SHeiko Stübner *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 1430daecdc66SHeiko Stübner *bit *= RK3188_PULL_BITS_PER_PIN; 1431daecdc66SHeiko Stübner } 1432daecdc66SHeiko Stübner } 1433daecdc66SHeiko Stübner 1434daecdc66SHeiko Stübner #define RK3368_DRV_PMU_OFFSET 0x20 1435daecdc66SHeiko Stübner #define RK3368_DRV_GRF_OFFSET 0x200 1436daecdc66SHeiko Stübner 1437daecdc66SHeiko Stübner static void rk3368_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 1438daecdc66SHeiko Stübner int pin_num, struct regmap **regmap, 1439daecdc66SHeiko Stübner int *reg, u8 *bit) 1440daecdc66SHeiko Stübner { 1441daecdc66SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1442daecdc66SHeiko Stübner 1443daecdc66SHeiko Stübner /* The first 32 pins of the first bank are located in PMU */ 1444daecdc66SHeiko Stübner if (bank->bank_num == 0) { 1445daecdc66SHeiko Stübner *regmap = info->regmap_pmu; 1446daecdc66SHeiko Stübner *reg = RK3368_DRV_PMU_OFFSET; 1447daecdc66SHeiko Stübner 1448daecdc66SHeiko Stübner *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 1449daecdc66SHeiko Stübner *bit = pin_num % RK3288_DRV_PINS_PER_REG; 1450daecdc66SHeiko Stübner *bit *= RK3288_DRV_BITS_PER_PIN; 1451daecdc66SHeiko Stübner } else { 1452daecdc66SHeiko Stübner *regmap = info->regmap_base; 1453daecdc66SHeiko Stübner *reg = RK3368_DRV_GRF_OFFSET; 1454daecdc66SHeiko Stübner 1455daecdc66SHeiko Stübner /* correct the offset, as we're starting with the 2nd bank */ 1456daecdc66SHeiko Stübner *reg -= 0x10; 1457daecdc66SHeiko Stübner *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE; 1458daecdc66SHeiko Stübner *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4); 1459daecdc66SHeiko Stübner 1460daecdc66SHeiko Stübner *bit = (pin_num % RK3288_DRV_PINS_PER_REG); 1461daecdc66SHeiko Stübner *bit *= RK3288_DRV_BITS_PER_PIN; 1462daecdc66SHeiko Stübner } 1463daecdc66SHeiko Stübner } 1464daecdc66SHeiko Stübner 1465b6c23275SDavid Wu #define RK3399_PULL_GRF_OFFSET 0xe040 1466b6c23275SDavid Wu #define RK3399_PULL_PMU_OFFSET 0x40 1467b6c23275SDavid Wu #define RK3399_DRV_3BITS_PER_PIN 3 1468b6c23275SDavid Wu 1469b6c23275SDavid Wu static void rk3399_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1470b6c23275SDavid Wu int pin_num, struct regmap **regmap, 1471b6c23275SDavid Wu int *reg, u8 *bit) 1472b6c23275SDavid Wu { 1473b6c23275SDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 1474b6c23275SDavid Wu 1475b6c23275SDavid Wu /* The bank0:16 and bank1:32 pins are located in PMU */ 1476b6c23275SDavid Wu if ((bank->bank_num == 0) || (bank->bank_num == 1)) { 1477b6c23275SDavid Wu *regmap = info->regmap_pmu; 1478b6c23275SDavid Wu *reg = RK3399_PULL_PMU_OFFSET; 1479b6c23275SDavid Wu 1480b6c23275SDavid Wu *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 1481b6c23275SDavid Wu 1482b6c23275SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 1483b6c23275SDavid Wu *bit = pin_num % RK3188_PULL_PINS_PER_REG; 1484b6c23275SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 1485b6c23275SDavid Wu } else { 1486b6c23275SDavid Wu *regmap = info->regmap_base; 1487b6c23275SDavid Wu *reg = RK3399_PULL_GRF_OFFSET; 1488b6c23275SDavid Wu 1489b6c23275SDavid Wu /* correct the offset, as we're starting with the 3rd bank */ 1490b6c23275SDavid Wu *reg -= 0x20; 1491b6c23275SDavid Wu *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE; 1492b6c23275SDavid Wu *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4); 1493b6c23275SDavid Wu 1494b6c23275SDavid Wu *bit = (pin_num % RK3188_PULL_PINS_PER_REG); 1495b6c23275SDavid Wu *bit *= RK3188_PULL_BITS_PER_PIN; 1496b6c23275SDavid Wu } 1497b6c23275SDavid Wu } 1498b6c23275SDavid Wu 1499b6c23275SDavid Wu static void rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 1500b6c23275SDavid Wu int pin_num, struct regmap **regmap, 1501b6c23275SDavid Wu int *reg, u8 *bit) 1502b6c23275SDavid Wu { 1503b6c23275SDavid Wu struct rockchip_pinctrl *info = bank->drvdata; 1504b6c23275SDavid Wu int drv_num = (pin_num / 8); 1505b6c23275SDavid Wu 1506b6c23275SDavid Wu /* The bank0:16 and bank1:32 pins are located in PMU */ 1507b6c23275SDavid Wu if ((bank->bank_num == 0) || (bank->bank_num == 1)) 1508b6c23275SDavid Wu *regmap = info->regmap_pmu; 1509b6c23275SDavid Wu else 1510b6c23275SDavid Wu *regmap = info->regmap_base; 1511b6c23275SDavid Wu 1512b6c23275SDavid Wu *reg = bank->drv[drv_num].offset; 1513b6c23275SDavid Wu if ((bank->drv[drv_num].drv_type == DRV_TYPE_IO_1V8_3V0_AUTO) || 1514b6c23275SDavid Wu (bank->drv[drv_num].drv_type == DRV_TYPE_IO_3V3_ONLY)) 1515b6c23275SDavid Wu *bit = (pin_num % 8) * 3; 1516b6c23275SDavid Wu else 1517b6c23275SDavid Wu *bit = (pin_num % 8) * 2; 1518b6c23275SDavid Wu } 1519b6c23275SDavid Wu 1520c0dadc0eSJianqun Xu #define RK3568_PULL_PMU_OFFSET 0x20 1521c0dadc0eSJianqun Xu #define RK3568_PULL_GRF_OFFSET 0x80 1522c0dadc0eSJianqun Xu #define RK3568_PULL_BITS_PER_PIN 2 1523c0dadc0eSJianqun Xu #define RK3568_PULL_PINS_PER_REG 8 1524c0dadc0eSJianqun Xu #define RK3568_PULL_BANK_STRIDE 0x10 1525c0dadc0eSJianqun Xu 1526c0dadc0eSJianqun Xu static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 1527c0dadc0eSJianqun Xu int pin_num, struct regmap **regmap, 1528c0dadc0eSJianqun Xu int *reg, u8 *bit) 1529c0dadc0eSJianqun Xu { 1530c0dadc0eSJianqun Xu struct rockchip_pinctrl *info = bank->drvdata; 1531c0dadc0eSJianqun Xu 1532c0dadc0eSJianqun Xu if (bank->bank_num == 0) { 1533c0dadc0eSJianqun Xu *regmap = info->regmap_pmu; 1534c0dadc0eSJianqun Xu *reg = RK3568_PULL_PMU_OFFSET; 1535c0dadc0eSJianqun Xu *reg += bank->bank_num * RK3568_PULL_BANK_STRIDE; 1536c0dadc0eSJianqun Xu *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4); 1537c0dadc0eSJianqun Xu 1538c0dadc0eSJianqun Xu *bit = pin_num % RK3568_PULL_PINS_PER_REG; 1539c0dadc0eSJianqun Xu *bit *= RK3568_PULL_BITS_PER_PIN; 1540c0dadc0eSJianqun Xu } else { 1541c0dadc0eSJianqun Xu *regmap = info->regmap_base; 1542c0dadc0eSJianqun Xu *reg = RK3568_PULL_GRF_OFFSET; 1543c0dadc0eSJianqun Xu *reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE; 1544c0dadc0eSJianqun Xu *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4); 1545c0dadc0eSJianqun Xu 1546c0dadc0eSJianqun Xu *bit = (pin_num % RK3568_PULL_PINS_PER_REG); 1547c0dadc0eSJianqun Xu *bit *= RK3568_PULL_BITS_PER_PIN; 1548c0dadc0eSJianqun Xu } 1549c0dadc0eSJianqun Xu } 1550c0dadc0eSJianqun Xu 1551c0dadc0eSJianqun Xu #define RK3568_DRV_PMU_OFFSET 0x70 1552c0dadc0eSJianqun Xu #define RK3568_DRV_GRF_OFFSET 0x200 1553c0dadc0eSJianqun Xu #define RK3568_DRV_BITS_PER_PIN 8 1554c0dadc0eSJianqun Xu #define RK3568_DRV_PINS_PER_REG 2 1555c0dadc0eSJianqun Xu #define RK3568_DRV_BANK_STRIDE 0x40 1556c0dadc0eSJianqun Xu 1557c0dadc0eSJianqun Xu static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 1558c0dadc0eSJianqun Xu int pin_num, struct regmap **regmap, 1559c0dadc0eSJianqun Xu int *reg, u8 *bit) 1560c0dadc0eSJianqun Xu { 1561c0dadc0eSJianqun Xu struct rockchip_pinctrl *info = bank->drvdata; 1562c0dadc0eSJianqun Xu 1563c0dadc0eSJianqun Xu /* The first 32 pins of the first bank are located in PMU */ 1564c0dadc0eSJianqun Xu if (bank->bank_num == 0) { 1565c0dadc0eSJianqun Xu *regmap = info->regmap_pmu; 1566c0dadc0eSJianqun Xu *reg = RK3568_DRV_PMU_OFFSET; 1567c0dadc0eSJianqun Xu *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4); 1568c0dadc0eSJianqun Xu 1569c0dadc0eSJianqun Xu *bit = pin_num % RK3568_DRV_PINS_PER_REG; 1570c0dadc0eSJianqun Xu *bit *= RK3568_DRV_BITS_PER_PIN; 1571c0dadc0eSJianqun Xu } else { 1572c0dadc0eSJianqun Xu *regmap = info->regmap_base; 1573c0dadc0eSJianqun Xu *reg = RK3568_DRV_GRF_OFFSET; 1574c0dadc0eSJianqun Xu *reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE; 1575c0dadc0eSJianqun Xu *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4); 1576c0dadc0eSJianqun Xu 1577c0dadc0eSJianqun Xu *bit = (pin_num % RK3568_DRV_PINS_PER_REG); 1578c0dadc0eSJianqun Xu *bit *= RK3568_DRV_BITS_PER_PIN; 1579c0dadc0eSJianqun Xu } 1580c0dadc0eSJianqun Xu } 1581c0dadc0eSJianqun Xu 1582b6c23275SDavid Wu static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = { 1583b6c23275SDavid Wu { 2, 4, 8, 12, -1, -1, -1, -1 }, 1584b6c23275SDavid Wu { 3, 6, 9, 12, -1, -1, -1, -1 }, 1585b6c23275SDavid Wu { 5, 10, 15, 20, -1, -1, -1, -1 }, 1586b6c23275SDavid Wu { 4, 6, 8, 10, 12, 14, 16, 18 }, 1587b6c23275SDavid Wu { 4, 7, 10, 13, 16, 19, 22, 26 } 1588b6c23275SDavid Wu }; 1589ef17f69fSHeiko Stübner 1590ef17f69fSHeiko Stübner static int rockchip_get_drive_perpin(struct rockchip_pin_bank *bank, 1591ef17f69fSHeiko Stübner int pin_num) 1592b547c800SHeiko Stübner { 1593ef17f69fSHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1594ef17f69fSHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 1595e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 1596b547c800SHeiko Stübner struct regmap *regmap; 1597b547c800SHeiko Stübner int reg, ret; 1598b6c23275SDavid Wu u32 data, temp, rmask_bits; 1599b547c800SHeiko Stübner u8 bit; 1600b6c23275SDavid Wu int drv_type = bank->drv[pin_num / 8].drv_type; 1601b547c800SHeiko Stübner 1602ef17f69fSHeiko Stübner ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit); 1603b547c800SHeiko Stübner 1604b6c23275SDavid Wu switch (drv_type) { 1605b6c23275SDavid Wu case DRV_TYPE_IO_1V8_3V0_AUTO: 1606b6c23275SDavid Wu case DRV_TYPE_IO_3V3_ONLY: 1607b6c23275SDavid Wu rmask_bits = RK3399_DRV_3BITS_PER_PIN; 1608b6c23275SDavid Wu switch (bit) { 1609b6c23275SDavid Wu case 0 ... 12: 1610b6c23275SDavid Wu /* regular case, nothing to do */ 1611b6c23275SDavid Wu break; 1612b6c23275SDavid Wu case 15: 1613b6c23275SDavid Wu /* 1614b6c23275SDavid Wu * drive-strength offset is special, as it is 1615b6c23275SDavid Wu * spread over 2 registers 1616b6c23275SDavid Wu */ 1617b6c23275SDavid Wu ret = regmap_read(regmap, reg, &data); 1618b6c23275SDavid Wu if (ret) 1619b6c23275SDavid Wu return ret; 1620b6c23275SDavid Wu 1621b6c23275SDavid Wu ret = regmap_read(regmap, reg + 0x4, &temp); 1622b6c23275SDavid Wu if (ret) 1623b6c23275SDavid Wu return ret; 1624b6c23275SDavid Wu 1625b6c23275SDavid Wu /* 1626b6c23275SDavid Wu * the bit data[15] contains bit 0 of the value 1627b6c23275SDavid Wu * while temp[1:0] contains bits 2 and 1 1628b6c23275SDavid Wu */ 1629b6c23275SDavid Wu data >>= 15; 1630b6c23275SDavid Wu temp &= 0x3; 1631b6c23275SDavid Wu temp <<= 1; 1632b6c23275SDavid Wu data |= temp; 1633b6c23275SDavid Wu 1634b6c23275SDavid Wu return rockchip_perpin_drv_list[drv_type][data]; 1635b6c23275SDavid Wu case 18 ... 21: 1636b6c23275SDavid Wu /* setting fully enclosed in the second register */ 1637b6c23275SDavid Wu reg += 4; 1638b6c23275SDavid Wu bit -= 16; 1639b6c23275SDavid Wu break; 1640b6c23275SDavid Wu default: 1641e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported bit: %d for pinctrl drive type: %d\n", 1642b6c23275SDavid Wu bit, drv_type); 1643b6c23275SDavid Wu return -EINVAL; 1644b6c23275SDavid Wu } 1645b6c23275SDavid Wu 1646b6c23275SDavid Wu break; 1647b6c23275SDavid Wu case DRV_TYPE_IO_DEFAULT: 1648b6c23275SDavid Wu case DRV_TYPE_IO_1V8_OR_3V0: 1649b6c23275SDavid Wu case DRV_TYPE_IO_1V8_ONLY: 1650b6c23275SDavid Wu rmask_bits = RK3288_DRV_BITS_PER_PIN; 1651b6c23275SDavid Wu break; 1652b6c23275SDavid Wu default: 1653e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported pinctrl drive type: %d\n", drv_type); 1654b6c23275SDavid Wu return -EINVAL; 1655b6c23275SDavid Wu } 1656b6c23275SDavid Wu 1657b547c800SHeiko Stübner ret = regmap_read(regmap, reg, &data); 1658b547c800SHeiko Stübner if (ret) 1659b547c800SHeiko Stübner return ret; 1660b547c800SHeiko Stübner 1661b547c800SHeiko Stübner data >>= bit; 1662b6c23275SDavid Wu data &= (1 << rmask_bits) - 1; 1663b547c800SHeiko Stübner 1664b6c23275SDavid Wu return rockchip_perpin_drv_list[drv_type][data]; 1665b547c800SHeiko Stübner } 1666b547c800SHeiko Stübner 1667ef17f69fSHeiko Stübner static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, 1668ef17f69fSHeiko Stübner int pin_num, int strength) 1669b547c800SHeiko Stübner { 1670b547c800SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1671ef17f69fSHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 1672e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 1673b547c800SHeiko Stübner struct regmap *regmap; 1674b547c800SHeiko Stübner int reg, ret, i; 1675b6c23275SDavid Wu u32 data, rmask, rmask_bits, temp; 1676b547c800SHeiko Stübner u8 bit; 1677b6c23275SDavid Wu int drv_type = bank->drv[pin_num / 8].drv_type; 1678b6c23275SDavid Wu 1679e4dd7fd5SAndy Shevchenko dev_dbg(dev, "setting drive of GPIO%d-%d to %d\n", 1680b6c23275SDavid Wu bank->bank_num, pin_num, strength); 1681b547c800SHeiko Stübner 1682ef17f69fSHeiko Stübner ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit); 1683c0dadc0eSJianqun Xu if (ctrl->type == RK3568) { 1684c0dadc0eSJianqun Xu rmask_bits = RK3568_DRV_BITS_PER_PIN; 1685c0dadc0eSJianqun Xu ret = (1 << (strength + 1)) - 1; 1686c0dadc0eSJianqun Xu goto config; 1687c0dadc0eSJianqun Xu } 1688b547c800SHeiko Stübner 1689b547c800SHeiko Stübner ret = -EINVAL; 1690b6c23275SDavid Wu for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list[drv_type]); i++) { 1691b6c23275SDavid Wu if (rockchip_perpin_drv_list[drv_type][i] == strength) { 1692b547c800SHeiko Stübner ret = i; 1693b547c800SHeiko Stübner break; 1694b6c23275SDavid Wu } else if (rockchip_perpin_drv_list[drv_type][i] < 0) { 1695b6c23275SDavid Wu ret = rockchip_perpin_drv_list[drv_type][i]; 1696b6c23275SDavid Wu break; 1697b547c800SHeiko Stübner } 1698b547c800SHeiko Stübner } 1699b547c800SHeiko Stübner 1700b547c800SHeiko Stübner if (ret < 0) { 1701e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported driver strength %d\n", strength); 1702b547c800SHeiko Stübner return ret; 1703b547c800SHeiko Stübner } 1704b547c800SHeiko Stübner 1705b6c23275SDavid Wu switch (drv_type) { 1706b6c23275SDavid Wu case DRV_TYPE_IO_1V8_3V0_AUTO: 1707b6c23275SDavid Wu case DRV_TYPE_IO_3V3_ONLY: 1708b6c23275SDavid Wu rmask_bits = RK3399_DRV_3BITS_PER_PIN; 1709b6c23275SDavid Wu switch (bit) { 1710b6c23275SDavid Wu case 0 ... 12: 1711b6c23275SDavid Wu /* regular case, nothing to do */ 1712b6c23275SDavid Wu break; 1713b6c23275SDavid Wu case 15: 1714b6c23275SDavid Wu /* 1715b6c23275SDavid Wu * drive-strength offset is special, as it is spread 1716b6c23275SDavid Wu * over 2 registers, the bit data[15] contains bit 0 1717b6c23275SDavid Wu * of the value while temp[1:0] contains bits 2 and 1 1718b6c23275SDavid Wu */ 1719b6c23275SDavid Wu data = (ret & 0x1) << 15; 1720b6c23275SDavid Wu temp = (ret >> 0x1) & 0x3; 1721b6c23275SDavid Wu 1722b6c23275SDavid Wu rmask = BIT(15) | BIT(31); 1723b6c23275SDavid Wu data |= BIT(31); 1724b6c23275SDavid Wu ret = regmap_update_bits(regmap, reg, rmask, data); 1725f07bedc3SJohn Keeping if (ret) 1726b6c23275SDavid Wu return ret; 1727b6c23275SDavid Wu 1728b6c23275SDavid Wu rmask = 0x3 | (0x3 << 16); 1729b6c23275SDavid Wu temp |= (0x3 << 16); 1730b6c23275SDavid Wu reg += 0x4; 1731b6c23275SDavid Wu ret = regmap_update_bits(regmap, reg, rmask, temp); 1732b6c23275SDavid Wu 1733b6c23275SDavid Wu return ret; 1734b6c23275SDavid Wu case 18 ... 21: 1735b6c23275SDavid Wu /* setting fully enclosed in the second register */ 1736b6c23275SDavid Wu reg += 4; 1737b6c23275SDavid Wu bit -= 16; 1738b6c23275SDavid Wu break; 1739b6c23275SDavid Wu default: 1740e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported bit: %d for pinctrl drive type: %d\n", 1741b6c23275SDavid Wu bit, drv_type); 1742b6c23275SDavid Wu return -EINVAL; 1743b6c23275SDavid Wu } 1744b6c23275SDavid Wu break; 1745b6c23275SDavid Wu case DRV_TYPE_IO_DEFAULT: 1746b6c23275SDavid Wu case DRV_TYPE_IO_1V8_OR_3V0: 1747b6c23275SDavid Wu case DRV_TYPE_IO_1V8_ONLY: 1748b6c23275SDavid Wu rmask_bits = RK3288_DRV_BITS_PER_PIN; 1749b6c23275SDavid Wu break; 1750b6c23275SDavid Wu default: 1751e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported pinctrl drive type: %d\n", drv_type); 1752b6c23275SDavid Wu return -EINVAL; 1753b6c23275SDavid Wu } 1754b6c23275SDavid Wu 1755c0dadc0eSJianqun Xu config: 1756b547c800SHeiko Stübner /* enable the write to the equivalent lower bits */ 1757b6c23275SDavid Wu data = ((1 << rmask_bits) - 1) << (bit + 16); 175899e872d9SSonny Rao rmask = data | (data >> 16); 1759b547c800SHeiko Stübner data |= (ret << bit); 1760b547c800SHeiko Stübner 176199e872d9SSonny Rao ret = regmap_update_bits(regmap, reg, rmask, data); 1762b547c800SHeiko Stübner 1763b547c800SHeiko Stübner return ret; 1764b547c800SHeiko Stübner } 1765b547c800SHeiko Stübner 17663ba6767aSDavid Wu static int rockchip_pull_list[PULL_TYPE_MAX][4] = { 17673ba6767aSDavid Wu { 17683ba6767aSDavid Wu PIN_CONFIG_BIAS_DISABLE, 17693ba6767aSDavid Wu PIN_CONFIG_BIAS_PULL_UP, 17703ba6767aSDavid Wu PIN_CONFIG_BIAS_PULL_DOWN, 17713ba6767aSDavid Wu PIN_CONFIG_BIAS_BUS_HOLD 17723ba6767aSDavid Wu }, 17733ba6767aSDavid Wu { 17743ba6767aSDavid Wu PIN_CONFIG_BIAS_DISABLE, 17753ba6767aSDavid Wu PIN_CONFIG_BIAS_PULL_DOWN, 17763ba6767aSDavid Wu PIN_CONFIG_BIAS_DISABLE, 17773ba6767aSDavid Wu PIN_CONFIG_BIAS_PULL_UP 17783ba6767aSDavid Wu }, 17793ba6767aSDavid Wu }; 17803ba6767aSDavid Wu 1781d3e51161SHeiko Stübner static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) 1782d3e51161SHeiko Stübner { 1783d3e51161SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1784d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 1785e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 1786751a99abSHeiko Stübner struct regmap *regmap; 17873ba6767aSDavid Wu int reg, ret, pull_type; 1788d3e51161SHeiko Stübner u8 bit; 17896ca5274dSHeiko Stübner u32 data; 1790d3e51161SHeiko Stübner 1791d3e51161SHeiko Stübner /* rk3066b does support any pulls */ 1792a282926dSHeiko Stübner if (ctrl->type == RK3066B) 1793d3e51161SHeiko Stübner return PIN_CONFIG_BIAS_DISABLE; 1794d3e51161SHeiko Stübner 1795751a99abSHeiko Stübner ctrl->pull_calc_reg(bank, pin_num, ®map, ®, &bit); 1796751a99abSHeiko Stübner 1797751a99abSHeiko Stübner ret = regmap_read(regmap, reg, &data); 1798751a99abSHeiko Stübner if (ret) 1799751a99abSHeiko Stübner return ret; 18006ca5274dSHeiko Stübner 1801a282926dSHeiko Stübner switch (ctrl->type) { 1802a282926dSHeiko Stübner case RK2928: 1803d23c66dfSDavid Wu case RK3128: 1804751a99abSHeiko Stübner return !(data & BIT(bit)) 1805d3e51161SHeiko Stübner ? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT 1806d3e51161SHeiko Stübner : PIN_CONFIG_BIAS_DISABLE; 180787065ca9SDavid Wu case PX30: 1808b9c6dcabSAndy Yan case RV1108: 1809a282926dSHeiko Stübner case RK3188: 181066d750e1SHeiko Stübner case RK3288: 18117825aeb7SJianqun Xu case RK3308: 1812daecdc66SHeiko Stübner case RK3368: 1813b6c23275SDavid Wu case RK3399: 18143ba6767aSDavid Wu pull_type = bank->pull_type[pin_num / 8]; 1815751a99abSHeiko Stübner data >>= bit; 18166ca5274dSHeiko Stübner data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1; 18176ca5274dSHeiko Stübner 18183ba6767aSDavid Wu return rockchip_pull_list[pull_type][data]; 1819a282926dSHeiko Stübner default: 1820e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported pinctrl type\n"); 1821a282926dSHeiko Stübner return -EINVAL; 1822a282926dSHeiko Stübner }; 1823d3e51161SHeiko Stübner } 1824d3e51161SHeiko Stübner 1825d3e51161SHeiko Stübner static int rockchip_set_pull(struct rockchip_pin_bank *bank, 1826d3e51161SHeiko Stübner int pin_num, int pull) 1827d3e51161SHeiko Stübner { 1828d3e51161SHeiko Stübner struct rockchip_pinctrl *info = bank->drvdata; 1829d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl = info->ctrl; 1830e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 1831751a99abSHeiko Stübner struct regmap *regmap; 18323ba6767aSDavid Wu int reg, ret, i, pull_type; 1833d3e51161SHeiko Stübner u8 bit; 183499e872d9SSonny Rao u32 data, rmask; 1835d3e51161SHeiko Stübner 1836e4dd7fd5SAndy Shevchenko dev_dbg(dev, "setting pull of GPIO%d-%d to %d\n", bank->bank_num, pin_num, pull); 1837d3e51161SHeiko Stübner 1838d3e51161SHeiko Stübner /* rk3066b does support any pulls */ 1839a282926dSHeiko Stübner if (ctrl->type == RK3066B) 1840d3e51161SHeiko Stübner return pull ? -EINVAL : 0; 1841d3e51161SHeiko Stübner 1842751a99abSHeiko Stübner ctrl->pull_calc_reg(bank, pin_num, ®map, ®, &bit); 1843d3e51161SHeiko Stübner 18446ca5274dSHeiko Stübner switch (ctrl->type) { 18456ca5274dSHeiko Stübner case RK2928: 1846d23c66dfSDavid Wu case RK3128: 1847d3e51161SHeiko Stübner data = BIT(bit + 16); 1848d3e51161SHeiko Stübner if (pull == PIN_CONFIG_BIAS_DISABLE) 1849d3e51161SHeiko Stübner data |= BIT(bit); 1850751a99abSHeiko Stübner ret = regmap_write(regmap, reg, data); 1851a282926dSHeiko Stübner break; 185287065ca9SDavid Wu case PX30: 1853b9c6dcabSAndy Yan case RV1108: 1854a282926dSHeiko Stübner case RK3188: 185566d750e1SHeiko Stübner case RK3288: 18567825aeb7SJianqun Xu case RK3308: 1857daecdc66SHeiko Stübner case RK3368: 1858b6c23275SDavid Wu case RK3399: 1859c0dadc0eSJianqun Xu case RK3568: 18603ba6767aSDavid Wu pull_type = bank->pull_type[pin_num / 8]; 18613ba6767aSDavid Wu ret = -EINVAL; 18623ba6767aSDavid Wu for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[pull_type]); 18633ba6767aSDavid Wu i++) { 18643ba6767aSDavid Wu if (rockchip_pull_list[pull_type][i] == pull) { 18653ba6767aSDavid Wu ret = i; 18663ba6767aSDavid Wu break; 18673ba6767aSDavid Wu } 18683ba6767aSDavid Wu } 1869c0dadc0eSJianqun Xu /* 1870c0dadc0eSJianqun Xu * In the TRM, pull-up being 1 for everything except the GPIO0_D0-D6, 1871c0dadc0eSJianqun Xu * where that pull up value becomes 3. 1872c0dadc0eSJianqun Xu */ 1873c0dadc0eSJianqun Xu if (ctrl->type == RK3568 && bank->bank_num == 0 && pin_num >= 27 && pin_num <= 30) { 1874c0dadc0eSJianqun Xu if (ret == 1) 1875c0dadc0eSJianqun Xu ret = 3; 1876c0dadc0eSJianqun Xu } 18773ba6767aSDavid Wu 18783ba6767aSDavid Wu if (ret < 0) { 1879e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported pull setting %d\n", pull); 18803ba6767aSDavid Wu return ret; 18813ba6767aSDavid Wu } 18823ba6767aSDavid Wu 18836ca5274dSHeiko Stübner /* enable the write to the equivalent lower bits */ 18846ca5274dSHeiko Stübner data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16); 188599e872d9SSonny Rao rmask = data | (data >> 16); 18863ba6767aSDavid Wu data |= (ret << bit); 18876ca5274dSHeiko Stübner 188899e872d9SSonny Rao ret = regmap_update_bits(regmap, reg, rmask, data); 18896ca5274dSHeiko Stübner break; 1890a282926dSHeiko Stübner default: 1891e4dd7fd5SAndy Shevchenko dev_err(dev, "unsupported pinctrl type\n"); 1892a282926dSHeiko Stübner return -EINVAL; 1893d3e51161SHeiko Stübner } 1894d3e51161SHeiko Stübner 1895751a99abSHeiko Stübner return ret; 1896d3e51161SHeiko Stübner } 1897d3e51161SHeiko Stübner 1898728d3f5aSdavid.wu #define RK3328_SCHMITT_BITS_PER_PIN 1 1899728d3f5aSdavid.wu #define RK3328_SCHMITT_PINS_PER_REG 16 1900728d3f5aSdavid.wu #define RK3328_SCHMITT_BANK_STRIDE 8 1901728d3f5aSdavid.wu #define RK3328_SCHMITT_GRF_OFFSET 0x380 1902728d3f5aSdavid.wu 1903728d3f5aSdavid.wu static int rk3328_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 1904728d3f5aSdavid.wu int pin_num, 1905728d3f5aSdavid.wu struct regmap **regmap, 1906728d3f5aSdavid.wu int *reg, u8 *bit) 1907728d3f5aSdavid.wu { 1908728d3f5aSdavid.wu struct rockchip_pinctrl *info = bank->drvdata; 1909728d3f5aSdavid.wu 1910728d3f5aSdavid.wu *regmap = info->regmap_base; 1911728d3f5aSdavid.wu *reg = RK3328_SCHMITT_GRF_OFFSET; 1912728d3f5aSdavid.wu 1913728d3f5aSdavid.wu *reg += bank->bank_num * RK3328_SCHMITT_BANK_STRIDE; 1914728d3f5aSdavid.wu *reg += ((pin_num / RK3328_SCHMITT_PINS_PER_REG) * 4); 1915728d3f5aSdavid.wu *bit = pin_num % RK3328_SCHMITT_PINS_PER_REG; 1916728d3f5aSdavid.wu 1917728d3f5aSdavid.wu return 0; 1918728d3f5aSdavid.wu } 1919728d3f5aSdavid.wu 1920c0dadc0eSJianqun Xu #define RK3568_SCHMITT_BITS_PER_PIN 2 1921c0dadc0eSJianqun Xu #define RK3568_SCHMITT_PINS_PER_REG 8 1922c0dadc0eSJianqun Xu #define RK3568_SCHMITT_BANK_STRIDE 0x10 1923c0dadc0eSJianqun Xu #define RK3568_SCHMITT_GRF_OFFSET 0xc0 1924c0dadc0eSJianqun Xu #define RK3568_SCHMITT_PMUGRF_OFFSET 0x30 1925c0dadc0eSJianqun Xu 1926c0dadc0eSJianqun Xu static int rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 1927c0dadc0eSJianqun Xu int pin_num, 1928c0dadc0eSJianqun Xu struct regmap **regmap, 1929c0dadc0eSJianqun Xu int *reg, u8 *bit) 1930c0dadc0eSJianqun Xu { 1931c0dadc0eSJianqun Xu struct rockchip_pinctrl *info = bank->drvdata; 1932c0dadc0eSJianqun Xu 1933c0dadc0eSJianqun Xu if (bank->bank_num == 0) { 1934c0dadc0eSJianqun Xu *regmap = info->regmap_pmu; 1935c0dadc0eSJianqun Xu *reg = RK3568_SCHMITT_PMUGRF_OFFSET; 1936c0dadc0eSJianqun Xu } else { 1937c0dadc0eSJianqun Xu *regmap = info->regmap_base; 1938c0dadc0eSJianqun Xu *reg = RK3568_SCHMITT_GRF_OFFSET; 1939c0dadc0eSJianqun Xu *reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE; 1940c0dadc0eSJianqun Xu } 1941c0dadc0eSJianqun Xu 1942c0dadc0eSJianqun Xu *reg += ((pin_num / RK3568_SCHMITT_PINS_PER_REG) * 4); 1943c0dadc0eSJianqun Xu *bit = pin_num % RK3568_SCHMITT_PINS_PER_REG; 1944c0dadc0eSJianqun Xu *bit *= RK3568_SCHMITT_BITS_PER_PIN; 1945c0dadc0eSJianqun Xu 1946c0dadc0eSJianqun Xu return 0; 1947c0dadc0eSJianqun Xu } 1948c0dadc0eSJianqun Xu 1949e3b357d7Sdavid.wu static int rockchip_get_schmitt(struct rockchip_pin_bank *bank, int pin_num) 1950e3b357d7Sdavid.wu { 1951e3b357d7Sdavid.wu struct rockchip_pinctrl *info = bank->drvdata; 1952e3b357d7Sdavid.wu struct rockchip_pin_ctrl *ctrl = info->ctrl; 1953e3b357d7Sdavid.wu struct regmap *regmap; 1954e3b357d7Sdavid.wu int reg, ret; 1955e3b357d7Sdavid.wu u8 bit; 1956e3b357d7Sdavid.wu u32 data; 1957e3b357d7Sdavid.wu 1958e3b357d7Sdavid.wu ret = ctrl->schmitt_calc_reg(bank, pin_num, ®map, ®, &bit); 1959e3b357d7Sdavid.wu if (ret) 1960e3b357d7Sdavid.wu return ret; 1961e3b357d7Sdavid.wu 1962e3b357d7Sdavid.wu ret = regmap_read(regmap, reg, &data); 1963e3b357d7Sdavid.wu if (ret) 1964e3b357d7Sdavid.wu return ret; 1965e3b357d7Sdavid.wu 1966e3b357d7Sdavid.wu data >>= bit; 1967c0dadc0eSJianqun Xu switch (ctrl->type) { 1968c0dadc0eSJianqun Xu case RK3568: 1969c0dadc0eSJianqun Xu return data & ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1); 1970c0dadc0eSJianqun Xu default: 1971c0dadc0eSJianqun Xu break; 1972c0dadc0eSJianqun Xu } 1973c0dadc0eSJianqun Xu 1974e3b357d7Sdavid.wu return data & 0x1; 1975e3b357d7Sdavid.wu } 1976e3b357d7Sdavid.wu 1977e3b357d7Sdavid.wu static int rockchip_set_schmitt(struct rockchip_pin_bank *bank, 1978e3b357d7Sdavid.wu int pin_num, int enable) 1979e3b357d7Sdavid.wu { 1980e3b357d7Sdavid.wu struct rockchip_pinctrl *info = bank->drvdata; 1981e3b357d7Sdavid.wu struct rockchip_pin_ctrl *ctrl = info->ctrl; 1982e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 1983e3b357d7Sdavid.wu struct regmap *regmap; 1984e3b357d7Sdavid.wu int reg, ret; 1985e3b357d7Sdavid.wu u8 bit; 1986e3b357d7Sdavid.wu u32 data, rmask; 1987e3b357d7Sdavid.wu 1988e4dd7fd5SAndy Shevchenko dev_dbg(dev, "setting input schmitt of GPIO%d-%d to %d\n", 1989e3b357d7Sdavid.wu bank->bank_num, pin_num, enable); 1990e3b357d7Sdavid.wu 1991e3b357d7Sdavid.wu ret = ctrl->schmitt_calc_reg(bank, pin_num, ®map, ®, &bit); 1992e3b357d7Sdavid.wu if (ret) 1993e3b357d7Sdavid.wu return ret; 1994e3b357d7Sdavid.wu 1995e3b357d7Sdavid.wu /* enable the write to the equivalent lower bits */ 1996c0dadc0eSJianqun Xu switch (ctrl->type) { 1997c0dadc0eSJianqun Xu case RK3568: 1998c0dadc0eSJianqun Xu data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16); 1999c0dadc0eSJianqun Xu rmask = data | (data >> 16); 2000c0dadc0eSJianqun Xu data |= ((enable ? 0x2 : 0x1) << bit); 2001c0dadc0eSJianqun Xu break; 2002c0dadc0eSJianqun Xu default: 2003e3b357d7Sdavid.wu data = BIT(bit + 16) | (enable << bit); 2004e3b357d7Sdavid.wu rmask = BIT(bit + 16) | BIT(bit); 2005c0dadc0eSJianqun Xu break; 2006c0dadc0eSJianqun Xu } 2007e3b357d7Sdavid.wu 2008f07bedc3SJohn Keeping return regmap_update_bits(regmap, reg, rmask, data); 2009e3b357d7Sdavid.wu } 2010e3b357d7Sdavid.wu 2011d3e51161SHeiko Stübner /* 2012d3e51161SHeiko Stübner * Pinmux_ops handling 2013d3e51161SHeiko Stübner */ 2014d3e51161SHeiko Stübner 2015d3e51161SHeiko Stübner static int rockchip_pmx_get_funcs_count(struct pinctrl_dev *pctldev) 2016d3e51161SHeiko Stübner { 2017d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 2018d3e51161SHeiko Stübner 2019d3e51161SHeiko Stübner return info->nfunctions; 2020d3e51161SHeiko Stübner } 2021d3e51161SHeiko Stübner 2022d3e51161SHeiko Stübner static const char *rockchip_pmx_get_func_name(struct pinctrl_dev *pctldev, 2023d3e51161SHeiko Stübner unsigned selector) 2024d3e51161SHeiko Stübner { 2025d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 2026d3e51161SHeiko Stübner 2027d3e51161SHeiko Stübner return info->functions[selector].name; 2028d3e51161SHeiko Stübner } 2029d3e51161SHeiko Stübner 2030d3e51161SHeiko Stübner static int rockchip_pmx_get_groups(struct pinctrl_dev *pctldev, 2031d3e51161SHeiko Stübner unsigned selector, const char * const **groups, 2032d3e51161SHeiko Stübner unsigned * const num_groups) 2033d3e51161SHeiko Stübner { 2034d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 2035d3e51161SHeiko Stübner 2036d3e51161SHeiko Stübner *groups = info->functions[selector].groups; 2037d3e51161SHeiko Stübner *num_groups = info->functions[selector].ngroups; 2038d3e51161SHeiko Stübner 2039d3e51161SHeiko Stübner return 0; 2040d3e51161SHeiko Stübner } 2041d3e51161SHeiko Stübner 204203e9f0caSLinus Walleij static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector, 2043d3e51161SHeiko Stübner unsigned group) 2044d3e51161SHeiko Stübner { 2045d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 2046d3e51161SHeiko Stübner const unsigned int *pins = info->groups[group].pins; 2047d3e51161SHeiko Stübner const struct rockchip_pin_config *data = info->groups[group].data; 2048e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 2049d3e51161SHeiko Stübner struct rockchip_pin_bank *bank; 205014797189SHeiko Stübner int cnt, ret = 0; 2051d3e51161SHeiko Stübner 2052e4dd7fd5SAndy Shevchenko dev_dbg(dev, "enable function %s group %s\n", 2053d3e51161SHeiko Stübner info->functions[selector].name, info->groups[group].name); 2054d3e51161SHeiko Stübner 2055d3e51161SHeiko Stübner /* 205685dc397aSMarkus Elfring * for each pin in the pin group selected, program the corresponding 2057d3e51161SHeiko Stübner * pin function number in the config register. 2058d3e51161SHeiko Stübner */ 2059d3e51161SHeiko Stübner for (cnt = 0; cnt < info->groups[group].npins; cnt++) { 2060d3e51161SHeiko Stübner bank = pin_to_bank(info, pins[cnt]); 206114797189SHeiko Stübner ret = rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 2062d3e51161SHeiko Stübner data[cnt].func); 206314797189SHeiko Stübner if (ret) 206414797189SHeiko Stübner break; 206514797189SHeiko Stübner } 206614797189SHeiko Stübner 206714797189SHeiko Stübner if (ret) { 206814797189SHeiko Stübner /* revert the already done pin settings */ 206914797189SHeiko Stübner for (cnt--; cnt >= 0; cnt--) 207014797189SHeiko Stübner rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0); 207114797189SHeiko Stübner 207214797189SHeiko Stübner return ret; 2073d3e51161SHeiko Stübner } 2074d3e51161SHeiko Stübner 2075d3e51161SHeiko Stübner return 0; 2076d3e51161SHeiko Stübner } 2077d3e51161SHeiko Stübner 2078d3e51161SHeiko Stübner static const struct pinmux_ops rockchip_pmx_ops = { 2079d3e51161SHeiko Stübner .get_functions_count = rockchip_pmx_get_funcs_count, 2080d3e51161SHeiko Stübner .get_function_name = rockchip_pmx_get_func_name, 2081d3e51161SHeiko Stübner .get_function_groups = rockchip_pmx_get_groups, 208203e9f0caSLinus Walleij .set_mux = rockchip_pmx_set, 2083d3e51161SHeiko Stübner }; 2084d3e51161SHeiko Stübner 2085d3e51161SHeiko Stübner /* 2086d3e51161SHeiko Stübner * Pinconf_ops handling 2087d3e51161SHeiko Stübner */ 2088d3e51161SHeiko Stübner 208944b6d930SHeiko Stübner static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, 209044b6d930SHeiko Stübner enum pin_config_param pull) 209144b6d930SHeiko Stübner { 2092a282926dSHeiko Stübner switch (ctrl->type) { 2093a282926dSHeiko Stübner case RK2928: 2094d23c66dfSDavid Wu case RK3128: 2095a282926dSHeiko Stübner return (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT || 2096a282926dSHeiko Stübner pull == PIN_CONFIG_BIAS_DISABLE); 2097a282926dSHeiko Stübner case RK3066B: 209844b6d930SHeiko Stübner return pull ? false : true; 209987065ca9SDavid Wu case PX30: 2100b9c6dcabSAndy Yan case RV1108: 2101a282926dSHeiko Stübner case RK3188: 210266d750e1SHeiko Stübner case RK3288: 21037825aeb7SJianqun Xu case RK3308: 2104daecdc66SHeiko Stübner case RK3368: 2105b6c23275SDavid Wu case RK3399: 2106c0dadc0eSJianqun Xu case RK3568: 2107a282926dSHeiko Stübner return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT); 210844b6d930SHeiko Stübner } 210944b6d930SHeiko Stübner 2110a282926dSHeiko Stübner return false; 211144b6d930SHeiko Stübner } 211244b6d930SHeiko Stübner 2113e7165b1dSHeiko Stuebner static int rockchip_pinconf_defer_output(struct rockchip_pin_bank *bank, 2114e7165b1dSHeiko Stuebner unsigned int pin, u32 arg) 2115e7165b1dSHeiko Stuebner { 2116e7165b1dSHeiko Stuebner struct rockchip_pin_output_deferred *cfg; 2117e7165b1dSHeiko Stuebner 2118e7165b1dSHeiko Stuebner cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); 2119e7165b1dSHeiko Stuebner if (!cfg) 2120e7165b1dSHeiko Stuebner return -ENOMEM; 2121e7165b1dSHeiko Stuebner 2122e7165b1dSHeiko Stuebner cfg->pin = pin; 2123e7165b1dSHeiko Stuebner cfg->arg = arg; 2124e7165b1dSHeiko Stuebner 2125e7165b1dSHeiko Stuebner list_add_tail(&cfg->head, &bank->deferred_output); 2126e7165b1dSHeiko Stuebner 2127e7165b1dSHeiko Stuebner return 0; 2128e7165b1dSHeiko Stuebner } 2129e7165b1dSHeiko Stuebner 2130d3e51161SHeiko Stübner /* set the pin config settings for a specified pin */ 2131d3e51161SHeiko Stübner static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, 213203b054e9SSherman Yin unsigned long *configs, unsigned num_configs) 2133d3e51161SHeiko Stübner { 2134d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 2135d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = pin_to_bank(info, pin); 21369ce9a020SJianqun Xu struct gpio_chip *gpio = &bank->gpio_chip; 213703b054e9SSherman Yin enum pin_config_param param; 213858957d2eSMika Westerberg u32 arg; 213903b054e9SSherman Yin int i; 214003b054e9SSherman Yin int rc; 214103b054e9SSherman Yin 214203b054e9SSherman Yin for (i = 0; i < num_configs; i++) { 214303b054e9SSherman Yin param = pinconf_to_config_param(configs[i]); 214403b054e9SSherman Yin arg = pinconf_to_config_argument(configs[i]); 2145d3e51161SHeiko Stübner 2146d3e51161SHeiko Stübner switch (param) { 2147d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_DISABLE: 214803b054e9SSherman Yin rc = rockchip_set_pull(bank, pin - bank->pin_base, 214903b054e9SSherman Yin param); 215003b054e9SSherman Yin if (rc) 215103b054e9SSherman Yin return rc; 215244b6d930SHeiko Stübner break; 2153d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_PULL_UP: 2154d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_PULL_DOWN: 2155d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: 21566ca5274dSHeiko Stübner case PIN_CONFIG_BIAS_BUS_HOLD: 215744b6d930SHeiko Stübner if (!rockchip_pinconf_pull_valid(info->ctrl, param)) 215844b6d930SHeiko Stübner return -ENOTSUPP; 215944b6d930SHeiko Stübner 216044b6d930SHeiko Stübner if (!arg) 216144b6d930SHeiko Stübner return -EINVAL; 216244b6d930SHeiko Stübner 216303b054e9SSherman Yin rc = rockchip_set_pull(bank, pin - bank->pin_base, 216403b054e9SSherman Yin param); 216503b054e9SSherman Yin if (rc) 216603b054e9SSherman Yin return rc; 2167d3e51161SHeiko Stübner break; 2168a076e2edSHeiko Stübner case PIN_CONFIG_OUTPUT: 21699ce9a020SJianqun Xu rc = rockchip_set_mux(bank, pin - bank->pin_base, 21709ce9a020SJianqun Xu RK_FUNC_GPIO); 21719ce9a020SJianqun Xu if (rc != RK_FUNC_GPIO) 21729ce9a020SJianqun Xu return -EINVAL; 21739ce9a020SJianqun Xu 2174e7165b1dSHeiko Stuebner /* 2175e7165b1dSHeiko Stuebner * Check for gpio driver not being probed yet. 2176e7165b1dSHeiko Stuebner * The lock makes sure that either gpio-probe has completed 2177e7165b1dSHeiko Stuebner * or the gpio driver hasn't probed yet. 2178e7165b1dSHeiko Stuebner */ 2179e7165b1dSHeiko Stuebner mutex_lock(&bank->deferred_lock); 2180e7165b1dSHeiko Stuebner if (!gpio || !gpio->direction_output) { 2181e7165b1dSHeiko Stuebner rc = rockchip_pinconf_defer_output(bank, pin - bank->pin_base, arg); 2182e7165b1dSHeiko Stuebner mutex_unlock(&bank->deferred_lock); 2183e7165b1dSHeiko Stuebner if (rc) 2184e7165b1dSHeiko Stuebner return rc; 2185e7165b1dSHeiko Stuebner 2186e7165b1dSHeiko Stuebner break; 2187e7165b1dSHeiko Stuebner } 2188e7165b1dSHeiko Stuebner mutex_unlock(&bank->deferred_lock); 2189e7165b1dSHeiko Stuebner 21909ce9a020SJianqun Xu rc = gpio->direction_output(gpio, pin - bank->pin_base, 21919ce9a020SJianqun Xu arg); 2192a076e2edSHeiko Stübner if (rc) 2193a076e2edSHeiko Stübner return rc; 2194a076e2edSHeiko Stübner break; 2195b547c800SHeiko Stübner case PIN_CONFIG_DRIVE_STRENGTH: 2196b547c800SHeiko Stübner /* rk3288 is the first with per-pin drive-strength */ 2197ef17f69fSHeiko Stübner if (!info->ctrl->drv_calc_reg) 2198b547c800SHeiko Stübner return -ENOTSUPP; 2199b547c800SHeiko Stübner 2200ef17f69fSHeiko Stübner rc = rockchip_set_drive_perpin(bank, 2201ef17f69fSHeiko Stübner pin - bank->pin_base, arg); 2202b547c800SHeiko Stübner if (rc < 0) 2203b547c800SHeiko Stübner return rc; 2204b547c800SHeiko Stübner break; 2205e3b357d7Sdavid.wu case PIN_CONFIG_INPUT_SCHMITT_ENABLE: 2206e3b357d7Sdavid.wu if (!info->ctrl->schmitt_calc_reg) 2207e3b357d7Sdavid.wu return -ENOTSUPP; 2208e3b357d7Sdavid.wu 2209e3b357d7Sdavid.wu rc = rockchip_set_schmitt(bank, 2210e3b357d7Sdavid.wu pin - bank->pin_base, arg); 2211e3b357d7Sdavid.wu if (rc < 0) 2212e3b357d7Sdavid.wu return rc; 2213e3b357d7Sdavid.wu break; 2214d3e51161SHeiko Stübner default: 2215d3e51161SHeiko Stübner return -ENOTSUPP; 2216d3e51161SHeiko Stübner break; 2217d3e51161SHeiko Stübner } 221803b054e9SSherman Yin } /* for each config */ 2219d3e51161SHeiko Stübner 2220d3e51161SHeiko Stübner return 0; 2221d3e51161SHeiko Stübner } 2222d3e51161SHeiko Stübner 2223d3e51161SHeiko Stübner /* get the pin config settings for a specified pin */ 2224d3e51161SHeiko Stübner static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, 2225d3e51161SHeiko Stübner unsigned long *config) 2226d3e51161SHeiko Stübner { 2227d3e51161SHeiko Stübner struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 2228d3e51161SHeiko Stübner struct rockchip_pin_bank *bank = pin_to_bank(info, pin); 22299ce9a020SJianqun Xu struct gpio_chip *gpio = &bank->gpio_chip; 2230d3e51161SHeiko Stübner enum pin_config_param param = pinconf_to_config_param(*config); 2231dab3eba7SHeiko Stübner u16 arg; 2232a076e2edSHeiko Stübner int rc; 2233d3e51161SHeiko Stübner 2234d3e51161SHeiko Stübner switch (param) { 2235d3e51161SHeiko Stübner case PIN_CONFIG_BIAS_DISABLE: 223644b6d930SHeiko Stübner if (rockchip_get_pull(bank, pin - bank->pin_base) != param) 2237d3e51161SHeiko Stübner return -EINVAL; 2238d3e51161SHeiko Stübner 2239dab3eba7SHeiko Stübner arg = 0; 2240d3e51161SHeiko Stübner break; 224144b6d930SHeiko Stübner case PIN_CONFIG_BIAS_PULL_UP: 224244b6d930SHeiko Stübner case PIN_CONFIG_BIAS_PULL_DOWN: 224344b6d930SHeiko Stübner case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: 22446ca5274dSHeiko Stübner case PIN_CONFIG_BIAS_BUS_HOLD: 224544b6d930SHeiko Stübner if (!rockchip_pinconf_pull_valid(info->ctrl, param)) 224644b6d930SHeiko Stübner return -ENOTSUPP; 224744b6d930SHeiko Stübner 224844b6d930SHeiko Stübner if (rockchip_get_pull(bank, pin - bank->pin_base) != param) 224944b6d930SHeiko Stübner return -EINVAL; 225044b6d930SHeiko Stübner 2251dab3eba7SHeiko Stübner arg = 1; 225244b6d930SHeiko Stübner break; 2253a076e2edSHeiko Stübner case PIN_CONFIG_OUTPUT: 2254a076e2edSHeiko Stübner rc = rockchip_get_mux(bank, pin - bank->pin_base); 2255a076e2edSHeiko Stübner if (rc != RK_FUNC_GPIO) 2256a076e2edSHeiko Stübner return -EINVAL; 2257a076e2edSHeiko Stübner 2258e7165b1dSHeiko Stuebner if (!gpio || !gpio->get) { 2259e7165b1dSHeiko Stuebner arg = 0; 2260e7165b1dSHeiko Stuebner break; 2261e7165b1dSHeiko Stuebner } 2262e7165b1dSHeiko Stuebner 22639ce9a020SJianqun Xu rc = gpio->get(gpio, pin - bank->pin_base); 2264a076e2edSHeiko Stübner if (rc < 0) 2265a076e2edSHeiko Stübner return rc; 2266a076e2edSHeiko Stübner 2267a076e2edSHeiko Stübner arg = rc ? 1 : 0; 2268a076e2edSHeiko Stübner break; 2269b547c800SHeiko Stübner case PIN_CONFIG_DRIVE_STRENGTH: 2270b547c800SHeiko Stübner /* rk3288 is the first with per-pin drive-strength */ 2271ef17f69fSHeiko Stübner if (!info->ctrl->drv_calc_reg) 2272b547c800SHeiko Stübner return -ENOTSUPP; 2273b547c800SHeiko Stübner 2274ef17f69fSHeiko Stübner rc = rockchip_get_drive_perpin(bank, pin - bank->pin_base); 2275b547c800SHeiko Stübner if (rc < 0) 2276b547c800SHeiko Stübner return rc; 2277b547c800SHeiko Stübner 2278b547c800SHeiko Stübner arg = rc; 2279b547c800SHeiko Stübner break; 2280e3b357d7Sdavid.wu case PIN_CONFIG_INPUT_SCHMITT_ENABLE: 2281e3b357d7Sdavid.wu if (!info->ctrl->schmitt_calc_reg) 2282e3b357d7Sdavid.wu return -ENOTSUPP; 2283e3b357d7Sdavid.wu 2284e3b357d7Sdavid.wu rc = rockchip_get_schmitt(bank, pin - bank->pin_base); 2285e3b357d7Sdavid.wu if (rc < 0) 2286e3b357d7Sdavid.wu return rc; 2287e3b357d7Sdavid.wu 2288e3b357d7Sdavid.wu arg = rc; 2289e3b357d7Sdavid.wu break; 2290d3e51161SHeiko Stübner default: 2291d3e51161SHeiko Stübner return -ENOTSUPP; 2292d3e51161SHeiko Stübner break; 2293d3e51161SHeiko Stübner } 2294d3e51161SHeiko Stübner 2295dab3eba7SHeiko Stübner *config = pinconf_to_config_packed(param, arg); 2296dab3eba7SHeiko Stübner 2297d3e51161SHeiko Stübner return 0; 2298d3e51161SHeiko Stübner } 2299d3e51161SHeiko Stübner 2300d3e51161SHeiko Stübner static const struct pinconf_ops rockchip_pinconf_ops = { 2301d3e51161SHeiko Stübner .pin_config_get = rockchip_pinconf_get, 2302d3e51161SHeiko Stübner .pin_config_set = rockchip_pinconf_set, 2303ed62f2f2SHeiko Stübner .is_generic = true, 2304d3e51161SHeiko Stübner }; 2305d3e51161SHeiko Stübner 230665fca613SHeiko Stübner static const struct of_device_id rockchip_bank_match[] = { 230765fca613SHeiko Stübner { .compatible = "rockchip,gpio-bank" }, 23086ca5274dSHeiko Stübner { .compatible = "rockchip,rk3188-gpio-bank0" }, 230965fca613SHeiko Stübner {}, 231065fca613SHeiko Stübner }; 2311d3e51161SHeiko Stübner 2312d3e51161SHeiko Stübner static void rockchip_pinctrl_child_count(struct rockchip_pinctrl *info, 2313d3e51161SHeiko Stübner struct device_node *np) 2314d3e51161SHeiko Stübner { 2315d3e51161SHeiko Stübner struct device_node *child; 2316d3e51161SHeiko Stübner 2317d3e51161SHeiko Stübner for_each_child_of_node(np, child) { 231865fca613SHeiko Stübner if (of_match_node(rockchip_bank_match, child)) 2319d3e51161SHeiko Stübner continue; 2320d3e51161SHeiko Stübner 2321d3e51161SHeiko Stübner info->nfunctions++; 2322d3e51161SHeiko Stübner info->ngroups += of_get_child_count(child); 2323d3e51161SHeiko Stübner } 2324d3e51161SHeiko Stübner } 2325d3e51161SHeiko Stübner 2326d3e51161SHeiko Stübner static int rockchip_pinctrl_parse_groups(struct device_node *np, 2327d3e51161SHeiko Stübner struct rockchip_pin_group *grp, 2328d3e51161SHeiko Stübner struct rockchip_pinctrl *info, 2329d3e51161SHeiko Stübner u32 index) 2330d3e51161SHeiko Stübner { 2331e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 2332d3e51161SHeiko Stübner struct rockchip_pin_bank *bank; 2333d3e51161SHeiko Stübner int size; 2334d3e51161SHeiko Stübner const __be32 *list; 2335d3e51161SHeiko Stübner int num; 2336d3e51161SHeiko Stübner int i, j; 2337d3e51161SHeiko Stübner int ret; 2338d3e51161SHeiko Stübner 2339e4dd7fd5SAndy Shevchenko dev_dbg(dev, "group(%d): %pOFn\n", index, np); 2340d3e51161SHeiko Stübner 2341d3e51161SHeiko Stübner /* Initialise group */ 2342d3e51161SHeiko Stübner grp->name = np->name; 2343d3e51161SHeiko Stübner 2344d3e51161SHeiko Stübner /* 2345d3e51161SHeiko Stübner * the binding format is rockchip,pins = <bank pin mux CONFIG>, 2346d3e51161SHeiko Stübner * do sanity check and calculate pins number 2347d3e51161SHeiko Stübner */ 2348d3e51161SHeiko Stübner list = of_get_property(np, "rockchip,pins", &size); 2349d3e51161SHeiko Stübner /* we do not check return since it's safe node passed down */ 2350d3e51161SHeiko Stübner size /= sizeof(*list); 23510045028fSAndy Shevchenko if (!size || size % 4) 23520045028fSAndy Shevchenko return dev_err_probe(dev, -EINVAL, "wrong pins number or pins and configs should be by 4\n"); 2353d3e51161SHeiko Stübner 2354d3e51161SHeiko Stübner grp->npins = size / 4; 2355d3e51161SHeiko Stübner 2356e4dd7fd5SAndy Shevchenko grp->pins = devm_kcalloc(dev, grp->npins, sizeof(*grp->pins), GFP_KERNEL); 2357e4dd7fd5SAndy Shevchenko grp->data = devm_kcalloc(dev, grp->npins, sizeof(*grp->data), GFP_KERNEL); 2358d3e51161SHeiko Stübner if (!grp->pins || !grp->data) 2359d3e51161SHeiko Stübner return -ENOMEM; 2360d3e51161SHeiko Stübner 2361d3e51161SHeiko Stübner for (i = 0, j = 0; i < size; i += 4, j++) { 2362d3e51161SHeiko Stübner const __be32 *phandle; 2363d3e51161SHeiko Stübner struct device_node *np_config; 2364d3e51161SHeiko Stübner 2365d3e51161SHeiko Stübner num = be32_to_cpu(*list++); 2366d3e51161SHeiko Stübner bank = bank_num_to_bank(info, num); 2367d3e51161SHeiko Stübner if (IS_ERR(bank)) 2368d3e51161SHeiko Stübner return PTR_ERR(bank); 2369d3e51161SHeiko Stübner 2370d3e51161SHeiko Stübner grp->pins[j] = bank->pin_base + be32_to_cpu(*list++); 2371d3e51161SHeiko Stübner grp->data[j].func = be32_to_cpu(*list++); 2372d3e51161SHeiko Stübner 2373d3e51161SHeiko Stübner phandle = list++; 2374d3e51161SHeiko Stübner if (!phandle) 2375d3e51161SHeiko Stübner return -EINVAL; 2376d3e51161SHeiko Stübner 2377d3e51161SHeiko Stübner np_config = of_find_node_by_phandle(be32_to_cpup(phandle)); 2378dd4d01f7SSoren Brinkmann ret = pinconf_generic_parse_dt_config(np_config, NULL, 2379d3e51161SHeiko Stübner &grp->data[j].configs, &grp->data[j].nconfigs); 2380d3e51161SHeiko Stübner if (ret) 2381d3e51161SHeiko Stübner return ret; 2382d3e51161SHeiko Stübner } 2383d3e51161SHeiko Stübner 2384d3e51161SHeiko Stübner return 0; 2385d3e51161SHeiko Stübner } 2386d3e51161SHeiko Stübner 2387d3e51161SHeiko Stübner static int rockchip_pinctrl_parse_functions(struct device_node *np, 2388d3e51161SHeiko Stübner struct rockchip_pinctrl *info, 2389d3e51161SHeiko Stübner u32 index) 2390d3e51161SHeiko Stübner { 2391e4dd7fd5SAndy Shevchenko struct device *dev = info->dev; 2392d3e51161SHeiko Stübner struct device_node *child; 2393d3e51161SHeiko Stübner struct rockchip_pmx_func *func; 2394d3e51161SHeiko Stübner struct rockchip_pin_group *grp; 2395d3e51161SHeiko Stübner int ret; 2396d3e51161SHeiko Stübner static u32 grp_index; 2397d3e51161SHeiko Stübner u32 i = 0; 2398d3e51161SHeiko Stübner 2399e4dd7fd5SAndy Shevchenko dev_dbg(dev, "parse function(%d): %pOFn\n", index, np); 2400d3e51161SHeiko Stübner 2401d3e51161SHeiko Stübner func = &info->functions[index]; 2402d3e51161SHeiko Stübner 2403d3e51161SHeiko Stübner /* Initialise function */ 2404d3e51161SHeiko Stübner func->name = np->name; 2405d3e51161SHeiko Stübner func->ngroups = of_get_child_count(np); 2406d3e51161SHeiko Stübner if (func->ngroups <= 0) 2407d3e51161SHeiko Stübner return 0; 2408d3e51161SHeiko Stübner 2409e4dd7fd5SAndy Shevchenko func->groups = devm_kcalloc(dev, func->ngroups, sizeof(*func->groups), GFP_KERNEL); 2410d3e51161SHeiko Stübner if (!func->groups) 2411d3e51161SHeiko Stübner return -ENOMEM; 2412d3e51161SHeiko Stübner 2413d3e51161SHeiko Stübner for_each_child_of_node(np, child) { 2414d3e51161SHeiko Stübner func->groups[i] = child->name; 2415d3e51161SHeiko Stübner grp = &info->groups[grp_index++]; 2416d3e51161SHeiko Stübner ret = rockchip_pinctrl_parse_groups(child, grp, info, i++); 2417f7a81b7fSJulia Lawall if (ret) { 2418f7a81b7fSJulia Lawall of_node_put(child); 2419d3e51161SHeiko Stübner return ret; 2420d3e51161SHeiko Stübner } 2421f7a81b7fSJulia Lawall } 2422d3e51161SHeiko Stübner 2423d3e51161SHeiko Stübner return 0; 2424d3e51161SHeiko Stübner } 2425d3e51161SHeiko Stübner 2426d3e51161SHeiko Stübner static int rockchip_pinctrl_parse_dt(struct platform_device *pdev, 2427d3e51161SHeiko Stübner struct rockchip_pinctrl *info) 2428d3e51161SHeiko Stübner { 2429d3e51161SHeiko Stübner struct device *dev = &pdev->dev; 2430d3e51161SHeiko Stübner struct device_node *np = dev->of_node; 2431d3e51161SHeiko Stübner struct device_node *child; 2432d3e51161SHeiko Stübner int ret; 2433d3e51161SHeiko Stübner int i; 2434d3e51161SHeiko Stübner 2435d3e51161SHeiko Stübner rockchip_pinctrl_child_count(info, np); 2436d3e51161SHeiko Stübner 2437e4dd7fd5SAndy Shevchenko dev_dbg(dev, "nfunctions = %d\n", info->nfunctions); 2438e4dd7fd5SAndy Shevchenko dev_dbg(dev, "ngroups = %d\n", info->ngroups); 2439d3e51161SHeiko Stübner 2440e4dd7fd5SAndy Shevchenko info->functions = devm_kcalloc(dev, info->nfunctions, sizeof(*info->functions), GFP_KERNEL); 244198c8ee73SMarkus Elfring if (!info->functions) 2442c4f333b7SDafna Hirschfeld return -ENOMEM; 2443d3e51161SHeiko Stübner 2444e4dd7fd5SAndy Shevchenko info->groups = devm_kcalloc(dev, info->ngroups, sizeof(*info->groups), GFP_KERNEL); 244598c8ee73SMarkus Elfring if (!info->groups) 2446c4f333b7SDafna Hirschfeld return -ENOMEM; 2447d3e51161SHeiko Stübner 2448d3e51161SHeiko Stübner i = 0; 2449d3e51161SHeiko Stübner 2450d3e51161SHeiko Stübner for_each_child_of_node(np, child) { 245165fca613SHeiko Stübner if (of_match_node(rockchip_bank_match, child)) 2452d3e51161SHeiko Stübner continue; 245365fca613SHeiko Stübner 2454d3e51161SHeiko Stübner ret = rockchip_pinctrl_parse_functions(child, info, i++); 2455d3e51161SHeiko Stübner if (ret) { 2456e4dd7fd5SAndy Shevchenko dev_err(dev, "failed to parse function\n"); 2457f7a81b7fSJulia Lawall of_node_put(child); 2458d3e51161SHeiko Stübner return ret; 2459d3e51161SHeiko Stübner } 2460d3e51161SHeiko Stübner } 2461d3e51161SHeiko Stübner 2462d3e51161SHeiko Stübner return 0; 2463d3e51161SHeiko Stübner } 2464d3e51161SHeiko Stübner 2465d3e51161SHeiko Stübner static int rockchip_pinctrl_register(struct platform_device *pdev, 2466d3e51161SHeiko Stübner struct rockchip_pinctrl *info) 2467d3e51161SHeiko Stübner { 2468d3e51161SHeiko Stübner struct pinctrl_desc *ctrldesc = &info->pctl; 2469d3e51161SHeiko Stübner struct pinctrl_pin_desc *pindesc, *pdesc; 2470d3e51161SHeiko Stübner struct rockchip_pin_bank *pin_bank; 2471e4dd7fd5SAndy Shevchenko struct device *dev = &pdev->dev; 2472069d7796SAndy Shevchenko char **pin_names; 2473d3e51161SHeiko Stübner int pin, bank, ret; 2474d3e51161SHeiko Stübner int k; 2475d3e51161SHeiko Stübner 2476d3e51161SHeiko Stübner ctrldesc->name = "rockchip-pinctrl"; 2477d3e51161SHeiko Stübner ctrldesc->owner = THIS_MODULE; 2478d3e51161SHeiko Stübner ctrldesc->pctlops = &rockchip_pctrl_ops; 2479d3e51161SHeiko Stübner ctrldesc->pmxops = &rockchip_pmx_ops; 2480d3e51161SHeiko Stübner ctrldesc->confops = &rockchip_pinconf_ops; 2481d3e51161SHeiko Stübner 2482e4dd7fd5SAndy Shevchenko pindesc = devm_kcalloc(dev, info->ctrl->nr_pins, sizeof(*pindesc), GFP_KERNEL); 248398c8ee73SMarkus Elfring if (!pindesc) 2484d3e51161SHeiko Stübner return -ENOMEM; 248598c8ee73SMarkus Elfring 2486d3e51161SHeiko Stübner ctrldesc->pins = pindesc; 2487d3e51161SHeiko Stübner ctrldesc->npins = info->ctrl->nr_pins; 2488d3e51161SHeiko Stübner 2489d3e51161SHeiko Stübner pdesc = pindesc; 2490d3e51161SHeiko Stübner for (bank = 0, k = 0; bank < info->ctrl->nr_banks; bank++) { 2491d3e51161SHeiko Stübner pin_bank = &info->ctrl->pin_banks[bank]; 2492069d7796SAndy Shevchenko 2493069d7796SAndy Shevchenko pin_names = devm_kasprintf_strarray(dev, pin_bank->name, pin_bank->nr_pins); 2494069d7796SAndy Shevchenko if (IS_ERR(pin_names)) 2495069d7796SAndy Shevchenko return PTR_ERR(pin_names); 2496069d7796SAndy Shevchenko 2497d3e51161SHeiko Stübner for (pin = 0; pin < pin_bank->nr_pins; pin++, k++) { 2498d3e51161SHeiko Stübner pdesc->number = k; 2499069d7796SAndy Shevchenko pdesc->name = pin_names[pin]; 2500d3e51161SHeiko Stübner pdesc++; 2501d3e51161SHeiko Stübner } 2502e7165b1dSHeiko Stuebner 2503e7165b1dSHeiko Stuebner INIT_LIST_HEAD(&pin_bank->deferred_output); 2504e7165b1dSHeiko Stuebner mutex_init(&pin_bank->deferred_lock); 2505d3e51161SHeiko Stübner } 2506d3e51161SHeiko Stübner 25070fb7dcb1SDoug Anderson ret = rockchip_pinctrl_parse_dt(pdev, info); 25080fb7dcb1SDoug Anderson if (ret) 25090fb7dcb1SDoug Anderson return ret; 25100fb7dcb1SDoug Anderson 2511e4dd7fd5SAndy Shevchenko info->pctl_dev = devm_pinctrl_register(dev, ctrldesc, info); 25120045028fSAndy Shevchenko if (IS_ERR(info->pctl_dev)) 25130045028fSAndy Shevchenko return dev_err_probe(dev, PTR_ERR(info->pctl_dev), "could not register pinctrl driver\n"); 2514d3e51161SHeiko Stübner 2515d3e51161SHeiko Stübner return 0; 2516d3e51161SHeiko Stübner } 2517d3e51161SHeiko Stübner 2518d3e51161SHeiko Stübner static const struct of_device_id rockchip_pinctrl_dt_match[]; 2519d3e51161SHeiko Stübner 2520d3e51161SHeiko Stübner /* retrieve the soc specific data */ 2521d3e51161SHeiko Stübner static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( 2522d3e51161SHeiko Stübner struct rockchip_pinctrl *d, 2523d3e51161SHeiko Stübner struct platform_device *pdev) 2524d3e51161SHeiko Stübner { 2525e4dd7fd5SAndy Shevchenko struct device *dev = &pdev->dev; 2526e4dd7fd5SAndy Shevchenko struct device_node *node = dev->of_node; 2527d3e51161SHeiko Stübner const struct of_device_id *match; 2528d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl; 2529d3e51161SHeiko Stübner struct rockchip_pin_bank *bank; 2530b6c23275SDavid Wu int grf_offs, pmu_offs, drv_grf_offs, drv_pmu_offs, i, j; 2531d3e51161SHeiko Stübner 2532d3e51161SHeiko Stübner match = of_match_node(rockchip_pinctrl_dt_match, node); 2533d3e51161SHeiko Stübner ctrl = (struct rockchip_pin_ctrl *)match->data; 2534d3e51161SHeiko Stübner 253595ec8ae4SHeiko Stübner grf_offs = ctrl->grf_mux_offset; 253695ec8ae4SHeiko Stübner pmu_offs = ctrl->pmu_mux_offset; 2537b6c23275SDavid Wu drv_pmu_offs = ctrl->pmu_drv_offset; 2538b6c23275SDavid Wu drv_grf_offs = ctrl->grf_drv_offset; 2539d3e51161SHeiko Stübner bank = ctrl->pin_banks; 2540d3e51161SHeiko Stübner for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { 25416bc0d121SHeiko Stübner int bank_pins = 0; 25426bc0d121SHeiko Stübner 254370b7aa7aSJohn Keeping raw_spin_lock_init(&bank->slock); 2544d3e51161SHeiko Stübner bank->drvdata = d; 2545d3e51161SHeiko Stübner bank->pin_base = ctrl->nr_pins; 2546d3e51161SHeiko Stübner ctrl->nr_pins += bank->nr_pins; 25476bc0d121SHeiko Stübner 2548b6c23275SDavid Wu /* calculate iomux and drv offsets */ 25496bc0d121SHeiko Stübner for (j = 0; j < 4; j++) { 25506bc0d121SHeiko Stübner struct rockchip_iomux *iom = &bank->iomux[j]; 2551b6c23275SDavid Wu struct rockchip_drv *drv = &bank->drv[j]; 255203716e1dSHeiko Stübner int inc; 25536bc0d121SHeiko Stübner 25546bc0d121SHeiko Stübner if (bank_pins >= bank->nr_pins) 25556bc0d121SHeiko Stübner break; 25566bc0d121SHeiko Stübner 2557b6c23275SDavid Wu /* preset iomux offset value, set new start value */ 25586bc0d121SHeiko Stübner if (iom->offset >= 0) { 255995ec8ae4SHeiko Stübner if (iom->type & IOMUX_SOURCE_PMU) 256095ec8ae4SHeiko Stübner pmu_offs = iom->offset; 256195ec8ae4SHeiko Stübner else 25626bc0d121SHeiko Stübner grf_offs = iom->offset; 2563b6c23275SDavid Wu } else { /* set current iomux offset */ 256495ec8ae4SHeiko Stübner iom->offset = (iom->type & IOMUX_SOURCE_PMU) ? 256595ec8ae4SHeiko Stübner pmu_offs : grf_offs; 25666bc0d121SHeiko Stübner } 25676bc0d121SHeiko Stübner 2568b6c23275SDavid Wu /* preset drv offset value, set new start value */ 2569b6c23275SDavid Wu if (drv->offset >= 0) { 2570b6c23275SDavid Wu if (iom->type & IOMUX_SOURCE_PMU) 2571b6c23275SDavid Wu drv_pmu_offs = drv->offset; 2572b6c23275SDavid Wu else 2573b6c23275SDavid Wu drv_grf_offs = drv->offset; 2574b6c23275SDavid Wu } else { /* set current drv offset */ 2575b6c23275SDavid Wu drv->offset = (iom->type & IOMUX_SOURCE_PMU) ? 2576b6c23275SDavid Wu drv_pmu_offs : drv_grf_offs; 2577b6c23275SDavid Wu } 2578b6c23275SDavid Wu 2579e4dd7fd5SAndy Shevchenko dev_dbg(dev, "bank %d, iomux %d has iom_offset 0x%x drv_offset 0x%x\n", 2580b6c23275SDavid Wu i, j, iom->offset, drv->offset); 25816bc0d121SHeiko Stübner 25826bc0d121SHeiko Stübner /* 25836bc0d121SHeiko Stübner * Increase offset according to iomux width. 258403716e1dSHeiko Stübner * 4bit iomux'es are spread over two registers. 25856bc0d121SHeiko Stübner */ 25868b6c6f93Sdavid.wu inc = (iom->type & (IOMUX_WIDTH_4BIT | 25877825aeb7SJianqun Xu IOMUX_WIDTH_3BIT | 25887825aeb7SJianqun Xu IOMUX_WIDTH_2BIT)) ? 8 : 4; 258995ec8ae4SHeiko Stübner if (iom->type & IOMUX_SOURCE_PMU) 259095ec8ae4SHeiko Stübner pmu_offs += inc; 259195ec8ae4SHeiko Stübner else 259203716e1dSHeiko Stübner grf_offs += inc; 25936bc0d121SHeiko Stübner 2594b6c23275SDavid Wu /* 2595b6c23275SDavid Wu * Increase offset according to drv width. 2596b6c23275SDavid Wu * 3bit drive-strenth'es are spread over two registers. 2597b6c23275SDavid Wu */ 2598b6c23275SDavid Wu if ((drv->drv_type == DRV_TYPE_IO_1V8_3V0_AUTO) || 2599b6c23275SDavid Wu (drv->drv_type == DRV_TYPE_IO_3V3_ONLY)) 2600b6c23275SDavid Wu inc = 8; 2601b6c23275SDavid Wu else 2602b6c23275SDavid Wu inc = 4; 2603b6c23275SDavid Wu 2604b6c23275SDavid Wu if (iom->type & IOMUX_SOURCE_PMU) 2605b6c23275SDavid Wu drv_pmu_offs += inc; 2606b6c23275SDavid Wu else 2607b6c23275SDavid Wu drv_grf_offs += inc; 2608b6c23275SDavid Wu 26096bc0d121SHeiko Stübner bank_pins += 8; 26106bc0d121SHeiko Stübner } 2611bd35b9bfSDavid Wu 2612c04c3fa6SDavid Wu /* calculate the per-bank recalced_mask */ 2613c04c3fa6SDavid Wu for (j = 0; j < ctrl->niomux_recalced; j++) { 2614c04c3fa6SDavid Wu int pin = 0; 2615c04c3fa6SDavid Wu 2616c04c3fa6SDavid Wu if (ctrl->iomux_recalced[j].num == bank->bank_num) { 2617c04c3fa6SDavid Wu pin = ctrl->iomux_recalced[j].pin; 2618c04c3fa6SDavid Wu bank->recalced_mask |= BIT(pin); 2619c04c3fa6SDavid Wu } 2620c04c3fa6SDavid Wu } 2621c04c3fa6SDavid Wu 2622bd35b9bfSDavid Wu /* calculate the per-bank route_mask */ 2623bd35b9bfSDavid Wu for (j = 0; j < ctrl->niomux_routes; j++) { 2624bd35b9bfSDavid Wu int pin = 0; 2625bd35b9bfSDavid Wu 2626bd35b9bfSDavid Wu if (ctrl->iomux_routes[j].bank_num == bank->bank_num) { 2627bd35b9bfSDavid Wu pin = ctrl->iomux_routes[j].pin; 2628bd35b9bfSDavid Wu bank->route_mask |= BIT(pin); 2629bd35b9bfSDavid Wu } 2630bd35b9bfSDavid Wu } 2631d3e51161SHeiko Stübner } 2632d3e51161SHeiko Stübner 2633d3e51161SHeiko Stübner return ctrl; 2634d3e51161SHeiko Stübner } 2635d3e51161SHeiko Stübner 26368dca9331SChris Zhong #define RK3288_GRF_GPIO6C_IOMUX 0x64 26378dca9331SChris Zhong #define GPIO6C6_SEL_WRITE_ENABLE BIT(28) 26388dca9331SChris Zhong 26398dca9331SChris Zhong static u32 rk3288_grf_gpio6c_iomux; 26408dca9331SChris Zhong 26419198f509SChris Zhong static int __maybe_unused rockchip_pinctrl_suspend(struct device *dev) 26429198f509SChris Zhong { 26439198f509SChris Zhong struct rockchip_pinctrl *info = dev_get_drvdata(dev); 26448dca9331SChris Zhong int ret = pinctrl_force_sleep(info->pctl_dev); 26459198f509SChris Zhong 26468dca9331SChris Zhong if (ret) 26478dca9331SChris Zhong return ret; 26488dca9331SChris Zhong 26498dca9331SChris Zhong /* 26508dca9331SChris Zhong * RK3288 GPIO6_C6 mux would be modified by Maskrom when resume, so save 26518dca9331SChris Zhong * the setting here, and restore it at resume. 26528dca9331SChris Zhong */ 26538dca9331SChris Zhong if (info->ctrl->type == RK3288) { 26548dca9331SChris Zhong ret = regmap_read(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX, 26558dca9331SChris Zhong &rk3288_grf_gpio6c_iomux); 26568dca9331SChris Zhong if (ret) { 26578dca9331SChris Zhong pinctrl_force_default(info->pctl_dev); 26588dca9331SChris Zhong return ret; 26598dca9331SChris Zhong } 26608dca9331SChris Zhong } 26618dca9331SChris Zhong 26628dca9331SChris Zhong return 0; 26639198f509SChris Zhong } 26649198f509SChris Zhong 26659198f509SChris Zhong static int __maybe_unused rockchip_pinctrl_resume(struct device *dev) 26669198f509SChris Zhong { 26679198f509SChris Zhong struct rockchip_pinctrl *info = dev_get_drvdata(dev); 2668c971af25SWang Panzhenzhuan int ret; 2669c971af25SWang Panzhenzhuan 2670c971af25SWang Panzhenzhuan if (info->ctrl->type == RK3288) { 2671c971af25SWang Panzhenzhuan ret = regmap_write(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX, 26728dca9331SChris Zhong rk3288_grf_gpio6c_iomux | 26738dca9331SChris Zhong GPIO6C6_SEL_WRITE_ENABLE); 26748dca9331SChris Zhong if (ret) 26758dca9331SChris Zhong return ret; 2676c971af25SWang Panzhenzhuan } 26779198f509SChris Zhong 26789198f509SChris Zhong return pinctrl_force_default(info->pctl_dev); 26799198f509SChris Zhong } 26809198f509SChris Zhong 26819198f509SChris Zhong static SIMPLE_DEV_PM_OPS(rockchip_pinctrl_dev_pm_ops, rockchip_pinctrl_suspend, 26829198f509SChris Zhong rockchip_pinctrl_resume); 26839198f509SChris Zhong 2684d3e51161SHeiko Stübner static int rockchip_pinctrl_probe(struct platform_device *pdev) 2685d3e51161SHeiko Stübner { 2686d3e51161SHeiko Stübner struct rockchip_pinctrl *info; 2687d3e51161SHeiko Stübner struct device *dev = &pdev->dev; 2688e4dd7fd5SAndy Shevchenko struct device_node *np = dev->of_node, *node; 2689d3e51161SHeiko Stübner struct rockchip_pin_ctrl *ctrl; 2690d3e51161SHeiko Stübner struct resource *res; 2691751a99abSHeiko Stübner void __iomem *base; 2692d3e51161SHeiko Stübner int ret; 2693d3e51161SHeiko Stübner 26940045028fSAndy Shevchenko if (!dev->of_node) 26950045028fSAndy Shevchenko return dev_err_probe(dev, -ENODEV, "device tree node not found\n"); 2696d3e51161SHeiko Stübner 2697283b7ac9SMarkus Elfring info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); 2698d3e51161SHeiko Stübner if (!info) 2699d3e51161SHeiko Stübner return -ENOMEM; 2700d3e51161SHeiko Stübner 2701622f3237SHeiko Stübner info->dev = dev; 2702622f3237SHeiko Stübner 2703d3e51161SHeiko Stübner ctrl = rockchip_pinctrl_get_soc_data(info, pdev); 27040045028fSAndy Shevchenko if (!ctrl) 27050045028fSAndy Shevchenko return dev_err_probe(dev, -EINVAL, "driver data not available\n"); 2706d3e51161SHeiko Stübner info->ctrl = ctrl; 2707d3e51161SHeiko Stübner 27081e747e59SHeiko Stübner node = of_parse_phandle(np, "rockchip,grf", 0); 27091e747e59SHeiko Stübner if (node) { 27101e747e59SHeiko Stübner info->regmap_base = syscon_node_to_regmap(node); 271189388f87SMiaoqian Lin of_node_put(node); 27121e747e59SHeiko Stübner if (IS_ERR(info->regmap_base)) 27131e747e59SHeiko Stübner return PTR_ERR(info->regmap_base); 27141e747e59SHeiko Stübner } else { 2715fb17dcd7SAndy Shevchenko base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 2716751a99abSHeiko Stübner if (IS_ERR(base)) 2717751a99abSHeiko Stübner return PTR_ERR(base); 2718751a99abSHeiko Stübner 2719751a99abSHeiko Stübner rockchip_regmap_config.max_register = resource_size(res) - 4; 2720751a99abSHeiko Stübner rockchip_regmap_config.name = "rockchip,pinctrl"; 2721e4dd7fd5SAndy Shevchenko info->regmap_base = 2722e4dd7fd5SAndy Shevchenko devm_regmap_init_mmio(dev, base, &rockchip_regmap_config); 2723d3e51161SHeiko Stübner 2724bfc7a42aSHeiko Stübner /* to check for the old dt-bindings */ 2725bfc7a42aSHeiko Stübner info->reg_size = resource_size(res); 2726bfc7a42aSHeiko Stübner 2727bfc7a42aSHeiko Stübner /* Honor the old binding, with pull registers as 2nd resource */ 2728bfc7a42aSHeiko Stübner if (ctrl->type == RK3188 && info->reg_size < 0x200) { 2729fb17dcd7SAndy Shevchenko base = devm_platform_get_and_ioremap_resource(pdev, 1, &res); 2730751a99abSHeiko Stübner if (IS_ERR(base)) 2731751a99abSHeiko Stübner return PTR_ERR(base); 2732751a99abSHeiko Stübner 2733e4dd7fd5SAndy Shevchenko rockchip_regmap_config.max_register = resource_size(res) - 4; 2734751a99abSHeiko Stübner rockchip_regmap_config.name = "rockchip,pinctrl-pull"; 2735e4dd7fd5SAndy Shevchenko info->regmap_pull = 2736e4dd7fd5SAndy Shevchenko devm_regmap_init_mmio(dev, base, &rockchip_regmap_config); 27376ca5274dSHeiko Stübner } 27381e747e59SHeiko Stübner } 27396ca5274dSHeiko Stübner 274014dee867SHeiko Stübner /* try to find the optional reference to the pmu syscon */ 274114dee867SHeiko Stübner node = of_parse_phandle(np, "rockchip,pmu", 0); 274214dee867SHeiko Stübner if (node) { 274314dee867SHeiko Stübner info->regmap_pmu = syscon_node_to_regmap(node); 274489388f87SMiaoqian Lin of_node_put(node); 274514dee867SHeiko Stübner if (IS_ERR(info->regmap_pmu)) 274614dee867SHeiko Stübner return PTR_ERR(info->regmap_pmu); 274714dee867SHeiko Stübner } 274814dee867SHeiko Stübner 27499ce9a020SJianqun Xu ret = rockchip_pinctrl_register(pdev, info); 2750d3e51161SHeiko Stübner if (ret) 2751d3e51161SHeiko Stübner return ret; 2752d3e51161SHeiko Stübner 27539ce9a020SJianqun Xu platform_set_drvdata(pdev, info); 27549ce9a020SJianqun Xu 2755bceb6732SJohn Keeping ret = of_platform_populate(np, NULL, NULL, &pdev->dev); 27560045028fSAndy Shevchenko if (ret) 27570045028fSAndy Shevchenko return dev_err_probe(dev, ret, "failed to register gpio device\n"); 2758d3e51161SHeiko Stübner 2759d3e51161SHeiko Stübner return 0; 2760d3e51161SHeiko Stübner } 2761d3e51161SHeiko Stübner 2762e7165b1dSHeiko Stuebner static int rockchip_pinctrl_remove(struct platform_device *pdev) 2763e7165b1dSHeiko Stuebner { 2764e7165b1dSHeiko Stuebner struct rockchip_pinctrl *info = platform_get_drvdata(pdev); 2765e7165b1dSHeiko Stuebner struct rockchip_pin_bank *bank; 2766e7165b1dSHeiko Stuebner struct rockchip_pin_output_deferred *cfg; 2767e7165b1dSHeiko Stuebner int i; 2768e7165b1dSHeiko Stuebner 2769e7165b1dSHeiko Stuebner of_platform_depopulate(&pdev->dev); 2770e7165b1dSHeiko Stuebner 2771e7165b1dSHeiko Stuebner for (i = 0; i < info->ctrl->nr_banks; i++) { 2772e7165b1dSHeiko Stuebner bank = &info->ctrl->pin_banks[i]; 2773e7165b1dSHeiko Stuebner 2774e7165b1dSHeiko Stuebner mutex_lock(&bank->deferred_lock); 2775e7165b1dSHeiko Stuebner while (!list_empty(&bank->deferred_output)) { 2776e7165b1dSHeiko Stuebner cfg = list_first_entry(&bank->deferred_output, 2777e7165b1dSHeiko Stuebner struct rockchip_pin_output_deferred, head); 2778e7165b1dSHeiko Stuebner list_del(&cfg->head); 2779e7165b1dSHeiko Stuebner kfree(cfg); 2780e7165b1dSHeiko Stuebner } 2781e7165b1dSHeiko Stuebner mutex_unlock(&bank->deferred_lock); 2782e7165b1dSHeiko Stuebner } 2783e7165b1dSHeiko Stuebner 2784e7165b1dSHeiko Stuebner return 0; 2785e7165b1dSHeiko Stuebner } 2786e7165b1dSHeiko Stuebner 278787065ca9SDavid Wu static struct rockchip_pin_bank px30_pin_banks[] = { 278887065ca9SDavid Wu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, 278987065ca9SDavid Wu IOMUX_SOURCE_PMU, 279087065ca9SDavid Wu IOMUX_SOURCE_PMU, 279187065ca9SDavid Wu IOMUX_SOURCE_PMU 279287065ca9SDavid Wu ), 279387065ca9SDavid Wu PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, 279487065ca9SDavid Wu IOMUX_WIDTH_4BIT, 279587065ca9SDavid Wu IOMUX_WIDTH_4BIT, 279687065ca9SDavid Wu IOMUX_WIDTH_4BIT 279787065ca9SDavid Wu ), 279887065ca9SDavid Wu PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, 279987065ca9SDavid Wu IOMUX_WIDTH_4BIT, 280087065ca9SDavid Wu IOMUX_WIDTH_4BIT, 280187065ca9SDavid Wu IOMUX_WIDTH_4BIT 280287065ca9SDavid Wu ), 280387065ca9SDavid Wu PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, 280487065ca9SDavid Wu IOMUX_WIDTH_4BIT, 280587065ca9SDavid Wu IOMUX_WIDTH_4BIT, 280687065ca9SDavid Wu IOMUX_WIDTH_4BIT 280787065ca9SDavid Wu ), 280887065ca9SDavid Wu }; 280987065ca9SDavid Wu 281087065ca9SDavid Wu static struct rockchip_pin_ctrl px30_pin_ctrl = { 281187065ca9SDavid Wu .pin_banks = px30_pin_banks, 281287065ca9SDavid Wu .nr_banks = ARRAY_SIZE(px30_pin_banks), 281387065ca9SDavid Wu .label = "PX30-GPIO", 281487065ca9SDavid Wu .type = PX30, 281587065ca9SDavid Wu .grf_mux_offset = 0x0, 281687065ca9SDavid Wu .pmu_mux_offset = 0x0, 281787065ca9SDavid Wu .iomux_routes = px30_mux_route_data, 281887065ca9SDavid Wu .niomux_routes = ARRAY_SIZE(px30_mux_route_data), 281987065ca9SDavid Wu .pull_calc_reg = px30_calc_pull_reg_and_bit, 282087065ca9SDavid Wu .drv_calc_reg = px30_calc_drv_reg_and_bit, 282187065ca9SDavid Wu .schmitt_calc_reg = px30_calc_schmitt_reg_and_bit, 282287065ca9SDavid Wu }; 282387065ca9SDavid Wu 2824b9c6dcabSAndy Yan static struct rockchip_pin_bank rv1108_pin_banks[] = { 2825688daf23SAndy Yan PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, 2826688daf23SAndy Yan IOMUX_SOURCE_PMU, 2827688daf23SAndy Yan IOMUX_SOURCE_PMU, 2828688daf23SAndy Yan IOMUX_SOURCE_PMU), 2829688daf23SAndy Yan PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0), 2830688daf23SAndy Yan PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, 0), 2831688daf23SAndy Yan PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, 0), 2832688daf23SAndy Yan }; 2833688daf23SAndy Yan 2834b9c6dcabSAndy Yan static struct rockchip_pin_ctrl rv1108_pin_ctrl = { 2835b9c6dcabSAndy Yan .pin_banks = rv1108_pin_banks, 2836b9c6dcabSAndy Yan .nr_banks = ARRAY_SIZE(rv1108_pin_banks), 2837b9c6dcabSAndy Yan .label = "RV1108-GPIO", 2838b9c6dcabSAndy Yan .type = RV1108, 2839688daf23SAndy Yan .grf_mux_offset = 0x10, 2840688daf23SAndy Yan .pmu_mux_offset = 0x0, 284112b8f018SDavid Wu .iomux_recalced = rv1108_mux_recalced_data, 284212b8f018SDavid Wu .niomux_recalced = ARRAY_SIZE(rv1108_mux_recalced_data), 2843b9c6dcabSAndy Yan .pull_calc_reg = rv1108_calc_pull_reg_and_bit, 2844b9c6dcabSAndy Yan .drv_calc_reg = rv1108_calc_drv_reg_and_bit, 28455caff7eaSAndy Yan .schmitt_calc_reg = rv1108_calc_schmitt_reg_and_bit, 2846688daf23SAndy Yan }; 2847688daf23SAndy Yan 2848d3e51161SHeiko Stübner static struct rockchip_pin_bank rk2928_pin_banks[] = { 2849d3e51161SHeiko Stübner PIN_BANK(0, 32, "gpio0"), 2850d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 2851d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 2852d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 2853d3e51161SHeiko Stübner }; 2854d3e51161SHeiko Stübner 2855d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk2928_pin_ctrl = { 2856d3e51161SHeiko Stübner .pin_banks = rk2928_pin_banks, 2857d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk2928_pin_banks), 2858d3e51161SHeiko Stübner .label = "RK2928-GPIO", 2859a282926dSHeiko Stübner .type = RK2928, 286095ec8ae4SHeiko Stübner .grf_mux_offset = 0xa8, 2861a282926dSHeiko Stübner .pull_calc_reg = rk2928_calc_pull_reg_and_bit, 2862d3e51161SHeiko Stübner }; 2863d3e51161SHeiko Stübner 2864c5ce7670SXing Zheng static struct rockchip_pin_bank rk3036_pin_banks[] = { 2865c5ce7670SXing Zheng PIN_BANK(0, 32, "gpio0"), 2866c5ce7670SXing Zheng PIN_BANK(1, 32, "gpio1"), 2867c5ce7670SXing Zheng PIN_BANK(2, 32, "gpio2"), 2868c5ce7670SXing Zheng }; 2869c5ce7670SXing Zheng 2870c5ce7670SXing Zheng static struct rockchip_pin_ctrl rk3036_pin_ctrl = { 2871c5ce7670SXing Zheng .pin_banks = rk3036_pin_banks, 2872c5ce7670SXing Zheng .nr_banks = ARRAY_SIZE(rk3036_pin_banks), 2873c5ce7670SXing Zheng .label = "RK3036-GPIO", 2874c5ce7670SXing Zheng .type = RK2928, 2875c5ce7670SXing Zheng .grf_mux_offset = 0xa8, 2876c5ce7670SXing Zheng .pull_calc_reg = rk2928_calc_pull_reg_and_bit, 2877c5ce7670SXing Zheng }; 2878c5ce7670SXing Zheng 2879d3e51161SHeiko Stübner static struct rockchip_pin_bank rk3066a_pin_banks[] = { 2880d3e51161SHeiko Stübner PIN_BANK(0, 32, "gpio0"), 2881d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 2882d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 2883d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 2884d3e51161SHeiko Stübner PIN_BANK(4, 32, "gpio4"), 2885d3e51161SHeiko Stübner PIN_BANK(6, 16, "gpio6"), 2886d3e51161SHeiko Stübner }; 2887d3e51161SHeiko Stübner 2888d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk3066a_pin_ctrl = { 2889d3e51161SHeiko Stübner .pin_banks = rk3066a_pin_banks, 2890d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk3066a_pin_banks), 2891d3e51161SHeiko Stübner .label = "RK3066a-GPIO", 2892a282926dSHeiko Stübner .type = RK2928, 289395ec8ae4SHeiko Stübner .grf_mux_offset = 0xa8, 2894a282926dSHeiko Stübner .pull_calc_reg = rk2928_calc_pull_reg_and_bit, 2895d3e51161SHeiko Stübner }; 2896d3e51161SHeiko Stübner 2897d3e51161SHeiko Stübner static struct rockchip_pin_bank rk3066b_pin_banks[] = { 2898d3e51161SHeiko Stübner PIN_BANK(0, 32, "gpio0"), 2899d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 2900d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 2901d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 2902d3e51161SHeiko Stübner }; 2903d3e51161SHeiko Stübner 2904d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk3066b_pin_ctrl = { 2905d3e51161SHeiko Stübner .pin_banks = rk3066b_pin_banks, 2906d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk3066b_pin_banks), 2907d3e51161SHeiko Stübner .label = "RK3066b-GPIO", 2908a282926dSHeiko Stübner .type = RK3066B, 290995ec8ae4SHeiko Stübner .grf_mux_offset = 0x60, 2910d3e51161SHeiko Stübner }; 2911d3e51161SHeiko Stübner 2912d23c66dfSDavid Wu static struct rockchip_pin_bank rk3128_pin_banks[] = { 2913d23c66dfSDavid Wu PIN_BANK(0, 32, "gpio0"), 2914d23c66dfSDavid Wu PIN_BANK(1, 32, "gpio1"), 2915d23c66dfSDavid Wu PIN_BANK(2, 32, "gpio2"), 2916d23c66dfSDavid Wu PIN_BANK(3, 32, "gpio3"), 2917d23c66dfSDavid Wu }; 2918d23c66dfSDavid Wu 2919d23c66dfSDavid Wu static struct rockchip_pin_ctrl rk3128_pin_ctrl = { 2920d23c66dfSDavid Wu .pin_banks = rk3128_pin_banks, 2921d23c66dfSDavid Wu .nr_banks = ARRAY_SIZE(rk3128_pin_banks), 2922d23c66dfSDavid Wu .label = "RK3128-GPIO", 2923d23c66dfSDavid Wu .type = RK3128, 2924d23c66dfSDavid Wu .grf_mux_offset = 0xa8, 2925d23c66dfSDavid Wu .iomux_recalced = rk3128_mux_recalced_data, 2926d23c66dfSDavid Wu .niomux_recalced = ARRAY_SIZE(rk3128_mux_recalced_data), 2927d23c66dfSDavid Wu .iomux_routes = rk3128_mux_route_data, 2928d23c66dfSDavid Wu .niomux_routes = ARRAY_SIZE(rk3128_mux_route_data), 2929d23c66dfSDavid Wu .pull_calc_reg = rk3128_calc_pull_reg_and_bit, 2930d23c66dfSDavid Wu }; 2931d23c66dfSDavid Wu 2932d3e51161SHeiko Stübner static struct rockchip_pin_bank rk3188_pin_banks[] = { 2933fc72c923SHeiko Stübner PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_GPIO_ONLY, 0, 0, 0), 2934d3e51161SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 2935d3e51161SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 2936d3e51161SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 2937d3e51161SHeiko Stübner }; 2938d3e51161SHeiko Stübner 2939d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk3188_pin_ctrl = { 2940d3e51161SHeiko Stübner .pin_banks = rk3188_pin_banks, 2941d3e51161SHeiko Stübner .nr_banks = ARRAY_SIZE(rk3188_pin_banks), 2942d3e51161SHeiko Stübner .label = "RK3188-GPIO", 2943a282926dSHeiko Stübner .type = RK3188, 294495ec8ae4SHeiko Stübner .grf_mux_offset = 0x60, 2945ada62b7cSHeiko Stuebner .iomux_routes = rk3188_mux_route_data, 2946ada62b7cSHeiko Stuebner .niomux_routes = ARRAY_SIZE(rk3188_mux_route_data), 29476ca5274dSHeiko Stübner .pull_calc_reg = rk3188_calc_pull_reg_and_bit, 2948d3e51161SHeiko Stübner }; 2949d3e51161SHeiko Stübner 2950fea0fe60SJeffy Chen static struct rockchip_pin_bank rk3228_pin_banks[] = { 2951fea0fe60SJeffy Chen PIN_BANK(0, 32, "gpio0"), 2952fea0fe60SJeffy Chen PIN_BANK(1, 32, "gpio1"), 2953fea0fe60SJeffy Chen PIN_BANK(2, 32, "gpio2"), 2954fea0fe60SJeffy Chen PIN_BANK(3, 32, "gpio3"), 2955fea0fe60SJeffy Chen }; 2956fea0fe60SJeffy Chen 2957fea0fe60SJeffy Chen static struct rockchip_pin_ctrl rk3228_pin_ctrl = { 2958fea0fe60SJeffy Chen .pin_banks = rk3228_pin_banks, 2959fea0fe60SJeffy Chen .nr_banks = ARRAY_SIZE(rk3228_pin_banks), 2960fea0fe60SJeffy Chen .label = "RK3228-GPIO", 2961fea0fe60SJeffy Chen .type = RK3288, 2962fea0fe60SJeffy Chen .grf_mux_offset = 0x0, 2963d4970ee0SDavid Wu .iomux_routes = rk3228_mux_route_data, 2964d4970ee0SDavid Wu .niomux_routes = ARRAY_SIZE(rk3228_mux_route_data), 2965fea0fe60SJeffy Chen .pull_calc_reg = rk3228_calc_pull_reg_and_bit, 2966fea0fe60SJeffy Chen .drv_calc_reg = rk3228_calc_drv_reg_and_bit, 2967fea0fe60SJeffy Chen }; 2968fea0fe60SJeffy Chen 2969304f077dSHeiko Stübner static struct rockchip_pin_bank rk3288_pin_banks[] = { 2970304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(0, 24, "gpio0", IOMUX_SOURCE_PMU, 2971304f077dSHeiko Stübner IOMUX_SOURCE_PMU, 2972304f077dSHeiko Stübner IOMUX_SOURCE_PMU, 2973304f077dSHeiko Stübner IOMUX_UNROUTED 2974304f077dSHeiko Stübner ), 2975304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_UNROUTED, 2976304f077dSHeiko Stübner IOMUX_UNROUTED, 2977304f077dSHeiko Stübner IOMUX_UNROUTED, 2978304f077dSHeiko Stübner 0 2979304f077dSHeiko Stübner ), 2980304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, IOMUX_UNROUTED), 2981304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, IOMUX_WIDTH_4BIT), 2982304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, 2983304f077dSHeiko Stübner IOMUX_WIDTH_4BIT, 2984304f077dSHeiko Stübner 0, 2985304f077dSHeiko Stübner 0 2986304f077dSHeiko Stübner ), 2987304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(5, 32, "gpio5", IOMUX_UNROUTED, 2988304f077dSHeiko Stübner 0, 2989304f077dSHeiko Stübner 0, 2990304f077dSHeiko Stübner IOMUX_UNROUTED 2991304f077dSHeiko Stübner ), 2992304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(6, 32, "gpio6", 0, 0, 0, IOMUX_UNROUTED), 2993304f077dSHeiko Stübner PIN_BANK_IOMUX_FLAGS(7, 32, "gpio7", 0, 2994304f077dSHeiko Stübner 0, 2995304f077dSHeiko Stübner IOMUX_WIDTH_4BIT, 2996304f077dSHeiko Stübner IOMUX_UNROUTED 2997304f077dSHeiko Stübner ), 2998304f077dSHeiko Stübner PIN_BANK(8, 16, "gpio8"), 2999304f077dSHeiko Stübner }; 3000304f077dSHeiko Stübner 3001304f077dSHeiko Stübner static struct rockchip_pin_ctrl rk3288_pin_ctrl = { 3002304f077dSHeiko Stübner .pin_banks = rk3288_pin_banks, 3003304f077dSHeiko Stübner .nr_banks = ARRAY_SIZE(rk3288_pin_banks), 3004304f077dSHeiko Stübner .label = "RK3288-GPIO", 300566d750e1SHeiko Stübner .type = RK3288, 3006304f077dSHeiko Stübner .grf_mux_offset = 0x0, 3007304f077dSHeiko Stübner .pmu_mux_offset = 0x84, 30084e96fd30SHeiko Stuebner .iomux_routes = rk3288_mux_route_data, 30094e96fd30SHeiko Stuebner .niomux_routes = ARRAY_SIZE(rk3288_mux_route_data), 3010304f077dSHeiko Stübner .pull_calc_reg = rk3288_calc_pull_reg_and_bit, 3011ef17f69fSHeiko Stübner .drv_calc_reg = rk3288_calc_drv_reg_and_bit, 3012304f077dSHeiko Stübner }; 3013304f077dSHeiko Stübner 30147825aeb7SJianqun Xu static struct rockchip_pin_bank rk3308_pin_banks[] = { 30157825aeb7SJianqun Xu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_WIDTH_2BIT, 30167825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 30177825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 30187825aeb7SJianqun Xu IOMUX_WIDTH_2BIT), 30197825aeb7SJianqun Xu PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_2BIT, 30207825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 30217825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 30227825aeb7SJianqun Xu IOMUX_WIDTH_2BIT), 30237825aeb7SJianqun Xu PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_2BIT, 30247825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 30257825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 30267825aeb7SJianqun Xu IOMUX_WIDTH_2BIT), 30277825aeb7SJianqun Xu PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_2BIT, 30287825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 30297825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 30307825aeb7SJianqun Xu IOMUX_WIDTH_2BIT), 30317825aeb7SJianqun Xu PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_2BIT, 30327825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 30337825aeb7SJianqun Xu IOMUX_WIDTH_2BIT, 30347825aeb7SJianqun Xu IOMUX_WIDTH_2BIT), 30357825aeb7SJianqun Xu }; 30367825aeb7SJianqun Xu 30377825aeb7SJianqun Xu static struct rockchip_pin_ctrl rk3308_pin_ctrl = { 30387825aeb7SJianqun Xu .pin_banks = rk3308_pin_banks, 30397825aeb7SJianqun Xu .nr_banks = ARRAY_SIZE(rk3308_pin_banks), 30407825aeb7SJianqun Xu .label = "RK3308-GPIO", 30417825aeb7SJianqun Xu .type = RK3308, 30427825aeb7SJianqun Xu .grf_mux_offset = 0x0, 30437825aeb7SJianqun Xu .iomux_recalced = rk3308_mux_recalced_data, 30447825aeb7SJianqun Xu .niomux_recalced = ARRAY_SIZE(rk3308_mux_recalced_data), 30457825aeb7SJianqun Xu .iomux_routes = rk3308_mux_route_data, 30467825aeb7SJianqun Xu .niomux_routes = ARRAY_SIZE(rk3308_mux_route_data), 30477825aeb7SJianqun Xu .pull_calc_reg = rk3308_calc_pull_reg_and_bit, 30487825aeb7SJianqun Xu .drv_calc_reg = rk3308_calc_drv_reg_and_bit, 30497825aeb7SJianqun Xu .schmitt_calc_reg = rk3308_calc_schmitt_reg_and_bit, 30507825aeb7SJianqun Xu }; 30517825aeb7SJianqun Xu 30523818e4a7Sdavid.wu static struct rockchip_pin_bank rk3328_pin_banks[] = { 30533818e4a7Sdavid.wu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 0, 0, 0, 0), 30543818e4a7Sdavid.wu PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0), 30553818e4a7Sdavid.wu PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 3056c04c3fa6SDavid Wu IOMUX_WIDTH_3BIT, 3057c04c3fa6SDavid Wu IOMUX_WIDTH_3BIT, 30583818e4a7Sdavid.wu 0), 30593818e4a7Sdavid.wu PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 30603818e4a7Sdavid.wu IOMUX_WIDTH_3BIT, 3061c04c3fa6SDavid Wu IOMUX_WIDTH_3BIT, 30623818e4a7Sdavid.wu 0, 30633818e4a7Sdavid.wu 0), 30643818e4a7Sdavid.wu }; 30653818e4a7Sdavid.wu 30663818e4a7Sdavid.wu static struct rockchip_pin_ctrl rk3328_pin_ctrl = { 30673818e4a7Sdavid.wu .pin_banks = rk3328_pin_banks, 30683818e4a7Sdavid.wu .nr_banks = ARRAY_SIZE(rk3328_pin_banks), 30693818e4a7Sdavid.wu .label = "RK3328-GPIO", 30703818e4a7Sdavid.wu .type = RK3288, 30713818e4a7Sdavid.wu .grf_mux_offset = 0x0, 3072c04c3fa6SDavid Wu .iomux_recalced = rk3328_mux_recalced_data, 3073c04c3fa6SDavid Wu .niomux_recalced = ARRAY_SIZE(rk3328_mux_recalced_data), 3074cedc964aSDavid Wu .iomux_routes = rk3328_mux_route_data, 3075cedc964aSDavid Wu .niomux_routes = ARRAY_SIZE(rk3328_mux_route_data), 30763818e4a7Sdavid.wu .pull_calc_reg = rk3228_calc_pull_reg_and_bit, 30773818e4a7Sdavid.wu .drv_calc_reg = rk3228_calc_drv_reg_and_bit, 3078728d3f5aSdavid.wu .schmitt_calc_reg = rk3328_calc_schmitt_reg_and_bit, 30793818e4a7Sdavid.wu }; 30803818e4a7Sdavid.wu 3081daecdc66SHeiko Stübner static struct rockchip_pin_bank rk3368_pin_banks[] = { 3082daecdc66SHeiko Stübner PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, 3083daecdc66SHeiko Stübner IOMUX_SOURCE_PMU, 3084daecdc66SHeiko Stübner IOMUX_SOURCE_PMU, 3085daecdc66SHeiko Stübner IOMUX_SOURCE_PMU 3086daecdc66SHeiko Stübner ), 3087daecdc66SHeiko Stübner PIN_BANK(1, 32, "gpio1"), 3088daecdc66SHeiko Stübner PIN_BANK(2, 32, "gpio2"), 3089daecdc66SHeiko Stübner PIN_BANK(3, 32, "gpio3"), 3090daecdc66SHeiko Stübner }; 3091daecdc66SHeiko Stübner 3092daecdc66SHeiko Stübner static struct rockchip_pin_ctrl rk3368_pin_ctrl = { 3093daecdc66SHeiko Stübner .pin_banks = rk3368_pin_banks, 3094daecdc66SHeiko Stübner .nr_banks = ARRAY_SIZE(rk3368_pin_banks), 3095daecdc66SHeiko Stübner .label = "RK3368-GPIO", 3096daecdc66SHeiko Stübner .type = RK3368, 3097daecdc66SHeiko Stübner .grf_mux_offset = 0x0, 3098daecdc66SHeiko Stübner .pmu_mux_offset = 0x0, 3099daecdc66SHeiko Stübner .pull_calc_reg = rk3368_calc_pull_reg_and_bit, 3100daecdc66SHeiko Stübner .drv_calc_reg = rk3368_calc_drv_reg_and_bit, 3101daecdc66SHeiko Stübner }; 3102daecdc66SHeiko Stübner 3103b6c23275SDavid Wu static struct rockchip_pin_bank rk3399_pin_banks[] = { 31043ba6767aSDavid Wu PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(0, 32, "gpio0", 31053ba6767aSDavid Wu IOMUX_SOURCE_PMU, 3106b6c23275SDavid Wu IOMUX_SOURCE_PMU, 3107b6c23275SDavid Wu IOMUX_SOURCE_PMU, 3108b6c23275SDavid Wu IOMUX_SOURCE_PMU, 3109b6c23275SDavid Wu DRV_TYPE_IO_1V8_ONLY, 3110b6c23275SDavid Wu DRV_TYPE_IO_1V8_ONLY, 3111b6c23275SDavid Wu DRV_TYPE_IO_DEFAULT, 3112b6c23275SDavid Wu DRV_TYPE_IO_DEFAULT, 3113c437f65cSDavid Wu 0x80, 3114c437f65cSDavid Wu 0x88, 3115b6c23275SDavid Wu -1, 31163ba6767aSDavid Wu -1, 31173ba6767aSDavid Wu PULL_TYPE_IO_1V8_ONLY, 31183ba6767aSDavid Wu PULL_TYPE_IO_1V8_ONLY, 31193ba6767aSDavid Wu PULL_TYPE_IO_DEFAULT, 31203ba6767aSDavid Wu PULL_TYPE_IO_DEFAULT 3121b6c23275SDavid Wu ), 3122b6c23275SDavid Wu PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(1, 32, "gpio1", IOMUX_SOURCE_PMU, 3123b6c23275SDavid Wu IOMUX_SOURCE_PMU, 3124b6c23275SDavid Wu IOMUX_SOURCE_PMU, 3125b6c23275SDavid Wu IOMUX_SOURCE_PMU, 3126b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 3127b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 3128b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 3129b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 3130c437f65cSDavid Wu 0xa0, 3131c437f65cSDavid Wu 0xa8, 3132c437f65cSDavid Wu 0xb0, 3133c437f65cSDavid Wu 0xb8 3134b6c23275SDavid Wu ), 31353ba6767aSDavid Wu PIN_BANK_DRV_FLAGS_PULL_FLAGS(2, 32, "gpio2", DRV_TYPE_IO_1V8_OR_3V0, 3136b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 3137b6c23275SDavid Wu DRV_TYPE_IO_1V8_ONLY, 31383ba6767aSDavid Wu DRV_TYPE_IO_1V8_ONLY, 31393ba6767aSDavid Wu PULL_TYPE_IO_DEFAULT, 31403ba6767aSDavid Wu PULL_TYPE_IO_DEFAULT, 31413ba6767aSDavid Wu PULL_TYPE_IO_1V8_ONLY, 31423ba6767aSDavid Wu PULL_TYPE_IO_1V8_ONLY 3143b6c23275SDavid Wu ), 3144b6c23275SDavid Wu PIN_BANK_DRV_FLAGS(3, 32, "gpio3", DRV_TYPE_IO_3V3_ONLY, 3145b6c23275SDavid Wu DRV_TYPE_IO_3V3_ONLY, 3146b6c23275SDavid Wu DRV_TYPE_IO_3V3_ONLY, 3147b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0 3148b6c23275SDavid Wu ), 3149b6c23275SDavid Wu PIN_BANK_DRV_FLAGS(4, 32, "gpio4", DRV_TYPE_IO_1V8_OR_3V0, 3150b6c23275SDavid Wu DRV_TYPE_IO_1V8_3V0_AUTO, 3151b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0, 3152b6c23275SDavid Wu DRV_TYPE_IO_1V8_OR_3V0 3153b6c23275SDavid Wu ), 3154b6c23275SDavid Wu }; 3155b6c23275SDavid Wu 3156b6c23275SDavid Wu static struct rockchip_pin_ctrl rk3399_pin_ctrl = { 3157b6c23275SDavid Wu .pin_banks = rk3399_pin_banks, 3158b6c23275SDavid Wu .nr_banks = ARRAY_SIZE(rk3399_pin_banks), 3159b6c23275SDavid Wu .label = "RK3399-GPIO", 3160b6c23275SDavid Wu .type = RK3399, 3161b6c23275SDavid Wu .grf_mux_offset = 0xe000, 3162b6c23275SDavid Wu .pmu_mux_offset = 0x0, 3163b6c23275SDavid Wu .grf_drv_offset = 0xe100, 3164b6c23275SDavid Wu .pmu_drv_offset = 0x80, 3165accc1ce7SDavid Wu .iomux_routes = rk3399_mux_route_data, 3166accc1ce7SDavid Wu .niomux_routes = ARRAY_SIZE(rk3399_mux_route_data), 3167b6c23275SDavid Wu .pull_calc_reg = rk3399_calc_pull_reg_and_bit, 3168b6c23275SDavid Wu .drv_calc_reg = rk3399_calc_drv_reg_and_bit, 3169b6c23275SDavid Wu }; 3170daecdc66SHeiko Stübner 3171c0dadc0eSJianqun Xu static struct rockchip_pin_bank rk3568_pin_banks[] = { 3172c0dadc0eSJianqun Xu PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, 3173c0dadc0eSJianqun Xu IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, 3174c0dadc0eSJianqun Xu IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, 3175c0dadc0eSJianqun Xu IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT), 3176c0dadc0eSJianqun Xu PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, 3177c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3178c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3179c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT), 3180c0dadc0eSJianqun Xu PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, 3181c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3182c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3183c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT), 3184c0dadc0eSJianqun Xu PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, 3185c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3186c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3187c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT), 3188c0dadc0eSJianqun Xu PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, 3189c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3190c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT, 3191c0dadc0eSJianqun Xu IOMUX_WIDTH_4BIT), 3192c0dadc0eSJianqun Xu }; 3193c0dadc0eSJianqun Xu 3194c0dadc0eSJianqun Xu static struct rockchip_pin_ctrl rk3568_pin_ctrl = { 3195c0dadc0eSJianqun Xu .pin_banks = rk3568_pin_banks, 3196c0dadc0eSJianqun Xu .nr_banks = ARRAY_SIZE(rk3568_pin_banks), 3197c0dadc0eSJianqun Xu .label = "RK3568-GPIO", 3198c0dadc0eSJianqun Xu .type = RK3568, 3199c0dadc0eSJianqun Xu .grf_mux_offset = 0x0, 3200c0dadc0eSJianqun Xu .pmu_mux_offset = 0x0, 3201c0dadc0eSJianqun Xu .grf_drv_offset = 0x0200, 3202c0dadc0eSJianqun Xu .pmu_drv_offset = 0x0070, 3203c0dadc0eSJianqun Xu .iomux_routes = rk3568_mux_route_data, 3204c0dadc0eSJianqun Xu .niomux_routes = ARRAY_SIZE(rk3568_mux_route_data), 3205c0dadc0eSJianqun Xu .pull_calc_reg = rk3568_calc_pull_reg_and_bit, 3206c0dadc0eSJianqun Xu .drv_calc_reg = rk3568_calc_drv_reg_and_bit, 3207c0dadc0eSJianqun Xu .schmitt_calc_reg = rk3568_calc_schmitt_reg_and_bit, 3208c0dadc0eSJianqun Xu }; 3209c0dadc0eSJianqun Xu 3210d3e51161SHeiko Stübner static const struct of_device_id rockchip_pinctrl_dt_match[] = { 321187065ca9SDavid Wu { .compatible = "rockchip,px30-pinctrl", 321287065ca9SDavid Wu .data = &px30_pin_ctrl }, 3213b9c6dcabSAndy Yan { .compatible = "rockchip,rv1108-pinctrl", 3214cdbbd26fSMasahiro Yamada .data = &rv1108_pin_ctrl }, 3215d3e51161SHeiko Stübner { .compatible = "rockchip,rk2928-pinctrl", 3216cdbbd26fSMasahiro Yamada .data = &rk2928_pin_ctrl }, 3217c5ce7670SXing Zheng { .compatible = "rockchip,rk3036-pinctrl", 3218cdbbd26fSMasahiro Yamada .data = &rk3036_pin_ctrl }, 3219d3e51161SHeiko Stübner { .compatible = "rockchip,rk3066a-pinctrl", 3220cdbbd26fSMasahiro Yamada .data = &rk3066a_pin_ctrl }, 3221d3e51161SHeiko Stübner { .compatible = "rockchip,rk3066b-pinctrl", 3222cdbbd26fSMasahiro Yamada .data = &rk3066b_pin_ctrl }, 3223d23c66dfSDavid Wu { .compatible = "rockchip,rk3128-pinctrl", 3224d23c66dfSDavid Wu .data = (void *)&rk3128_pin_ctrl }, 3225d3e51161SHeiko Stübner { .compatible = "rockchip,rk3188-pinctrl", 3226cdbbd26fSMasahiro Yamada .data = &rk3188_pin_ctrl }, 3227fea0fe60SJeffy Chen { .compatible = "rockchip,rk3228-pinctrl", 3228cdbbd26fSMasahiro Yamada .data = &rk3228_pin_ctrl }, 3229304f077dSHeiko Stübner { .compatible = "rockchip,rk3288-pinctrl", 3230cdbbd26fSMasahiro Yamada .data = &rk3288_pin_ctrl }, 32317825aeb7SJianqun Xu { .compatible = "rockchip,rk3308-pinctrl", 32327825aeb7SJianqun Xu .data = &rk3308_pin_ctrl }, 32333818e4a7Sdavid.wu { .compatible = "rockchip,rk3328-pinctrl", 3234cdbbd26fSMasahiro Yamada .data = &rk3328_pin_ctrl }, 3235daecdc66SHeiko Stübner { .compatible = "rockchip,rk3368-pinctrl", 3236cdbbd26fSMasahiro Yamada .data = &rk3368_pin_ctrl }, 3237b6c23275SDavid Wu { .compatible = "rockchip,rk3399-pinctrl", 3238cdbbd26fSMasahiro Yamada .data = &rk3399_pin_ctrl }, 3239c0dadc0eSJianqun Xu { .compatible = "rockchip,rk3568-pinctrl", 3240c0dadc0eSJianqun Xu .data = &rk3568_pin_ctrl }, 3241d3e51161SHeiko Stübner {}, 3242d3e51161SHeiko Stübner }; 3243d3e51161SHeiko Stübner 3244d3e51161SHeiko Stübner static struct platform_driver rockchip_pinctrl_driver = { 3245d3e51161SHeiko Stübner .probe = rockchip_pinctrl_probe, 3246e7165b1dSHeiko Stuebner .remove = rockchip_pinctrl_remove, 3247d3e51161SHeiko Stübner .driver = { 3248d3e51161SHeiko Stübner .name = "rockchip-pinctrl", 32499198f509SChris Zhong .pm = &rockchip_pinctrl_dev_pm_ops, 32500be9e70dSAxel Lin .of_match_table = rockchip_pinctrl_dt_match, 3251d3e51161SHeiko Stübner }, 3252d3e51161SHeiko Stübner }; 3253d3e51161SHeiko Stübner 3254d3e51161SHeiko Stübner static int __init rockchip_pinctrl_drv_register(void) 3255d3e51161SHeiko Stübner { 3256d3e51161SHeiko Stübner return platform_driver_register(&rockchip_pinctrl_driver); 3257d3e51161SHeiko Stübner } 3258d3e51161SHeiko Stübner postcore_initcall(rockchip_pinctrl_drv_register); 3259be786ac5SJianqun Xu 3260be786ac5SJianqun Xu static void __exit rockchip_pinctrl_drv_unregister(void) 3261be786ac5SJianqun Xu { 3262be786ac5SJianqun Xu platform_driver_unregister(&rockchip_pinctrl_driver); 3263be786ac5SJianqun Xu } 3264be786ac5SJianqun Xu module_exit(rockchip_pinctrl_drv_unregister); 3265be786ac5SJianqun Xu 3266be786ac5SJianqun Xu MODULE_DESCRIPTION("ROCKCHIP Pin Controller Driver"); 3267be786ac5SJianqun Xu MODULE_LICENSE("GPL"); 3268be786ac5SJianqun Xu MODULE_ALIAS("platform:pinctrl-rockchip"); 3269be786ac5SJianqun Xu MODULE_DEVICE_TABLE(of, rockchip_pinctrl_dt_match); 3270