Lines Matching +full:bank +full:- +full:width

1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved.
10 * Copyright (C) 2009-2011 ST-Ericsson AB
27 #include "../pinctrl-utils.h"
28 #include "pinctrl-tegra.h"
30 static inline u32 pmx_readl(struct tegra_pmx *pmx, u32 bank, u32 reg) in pmx_readl() argument
32 return readl(pmx->regs[bank] + reg); in pmx_readl()
35 static inline void pmx_writel(struct tegra_pmx *pmx, u32 val, u32 bank, u32 reg) in pmx_writel() argument
37 writel_relaxed(val, pmx->regs[bank] + reg); in pmx_writel()
39 pmx_readl(pmx, bank, reg); in pmx_writel()
46 return pmx->soc->ngroups; in tegra_pinctrl_get_groups_count()
54 return pmx->soc->groups[group].name; in tegra_pinctrl_get_group_name()
64 *pins = pmx->soc->groups[group].pins; in tegra_pinctrl_get_group_pins()
65 *num_pins = pmx->soc->groups[group].npins; in tegra_pinctrl_get_group_pins()
75 seq_printf(s, " %s", dev_name(pctldev->dev)); in tegra_pinctrl_pin_dbg_show()
85 {"nvidia,enable-input", TEGRA_PINCONF_PARAM_ENABLE_INPUT},
86 {"nvidia,open-drain", TEGRA_PINCONF_PARAM_OPEN_DRAIN},
88 {"nvidia,io-reset", TEGRA_PINCONF_PARAM_IORESET},
89 {"nvidia,rcv-sel", TEGRA_PINCONF_PARAM_RCV_SEL},
90 {"nvidia,io-hv", TEGRA_PINCONF_PARAM_RCV_SEL},
91 {"nvidia,high-speed-mode", TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE},
93 {"nvidia,low-power-mode", TEGRA_PINCONF_PARAM_LOW_POWER_MODE},
94 {"nvidia,pull-down-strength", TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH},
95 {"nvidia,pull-up-strength", TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH},
96 {"nvidia,slew-rate-falling", TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING},
97 {"nvidia,slew-rate-rising", TEGRA_PINCONF_PARAM_SLEW_RATE_RISING},
98 {"nvidia,drive-type", TEGRA_PINCONF_PARAM_DRIVE_TYPE},
99 {"nvidia,gpio-mode", TEGRA_PINCONF_PARAM_GPIO_MODE},
108 struct device *dev = pctldev->dev; in tegra_pinctrl_dt_subnode_to_map()
122 if (ret != -EINVAL) in tegra_pinctrl_dt_subnode_to_map()
137 } else if (ret != -EINVAL) { in tegra_pinctrl_dt_subnode_to_map()
226 return pmx->soc->nfunctions; in tegra_pinctrl_get_funcs_count()
234 return pmx->functions[function].name; in tegra_pinctrl_get_func_name()
244 *groups = pmx->functions[function].groups; in tegra_pinctrl_get_func_groups()
245 *num_groups = pmx->functions[function].ngroups; in tegra_pinctrl_get_func_groups()
259 g = &pmx->soc->groups[group]; in tegra_pinctrl_set_mux()
261 if (WARN_ON(g->mux_reg < 0)) in tegra_pinctrl_set_mux()
262 return -EINVAL; in tegra_pinctrl_set_mux()
264 for (i = 0; i < ARRAY_SIZE(g->funcs); i++) { in tegra_pinctrl_set_mux()
265 if (g->funcs[i] == function) in tegra_pinctrl_set_mux()
268 if (WARN_ON(i == ARRAY_SIZE(g->funcs))) in tegra_pinctrl_set_mux()
269 return -EINVAL; in tegra_pinctrl_set_mux()
271 val = pmx_readl(pmx, g->mux_bank, g->mux_reg); in tegra_pinctrl_set_mux()
272 val &= ~(0x3 << g->mux_bit); in tegra_pinctrl_set_mux()
273 val |= i << g->mux_bit; in tegra_pinctrl_set_mux()
275 if (pmx->soc->sfsel_in_mux) in tegra_pinctrl_set_mux()
276 val |= (1 << g->sfsel_bit); in tegra_pinctrl_set_mux()
277 pmx_writel(pmx, val, g->mux_bank, g->mux_reg); in tegra_pinctrl_set_mux()
290 for (group = 0; group < pmx->soc->ngroups; ++group) { in tegra_pinctrl_get_group_index()
300 return -EINVAL; in tegra_pinctrl_get_group_index()
309 if (group_index < 0 || group_index >= pmx->soc->ngroups) in tegra_pinctrl_get_group()
312 return &pmx->soc->groups[group_index]; in tegra_pinctrl_get_group()
324 return &pmx->pingroup_configs[group_index]; in tegra_pinctrl_get_group_config()
337 if (!pmx->soc->sfsel_in_mux) in tegra_pinctrl_gpio_request_enable()
344 return -EINVAL; in tegra_pinctrl_gpio_request_enable()
346 if (group->mux_reg < 0 || group->sfsel_bit < 0) in tegra_pinctrl_gpio_request_enable()
347 return -EINVAL; in tegra_pinctrl_gpio_request_enable()
351 return -EINVAL; in tegra_pinctrl_gpio_request_enable()
352 value = pmx_readl(pmx, group->mux_bank, group->mux_reg); in tegra_pinctrl_gpio_request_enable()
353 config->is_sfsel = (value & BIT(group->sfsel_bit)) != 0; in tegra_pinctrl_gpio_request_enable()
354 value &= ~BIT(group->sfsel_bit); in tegra_pinctrl_gpio_request_enable()
355 pmx_writel(pmx, value, group->mux_bank, group->mux_reg); in tegra_pinctrl_gpio_request_enable()
370 if (!pmx->soc->sfsel_in_mux) in tegra_pinctrl_gpio_disable_free()
379 if (group->mux_reg < 0 || group->sfsel_bit < 0) in tegra_pinctrl_gpio_disable_free()
385 value = pmx_readl(pmx, group->mux_bank, group->mux_reg); in tegra_pinctrl_gpio_disable_free()
386 if (config->is_sfsel) in tegra_pinctrl_gpio_disable_free()
387 value |= BIT(group->sfsel_bit); in tegra_pinctrl_gpio_disable_free()
388 pmx_writel(pmx, value, group->mux_bank, group->mux_reg); in tegra_pinctrl_gpio_disable_free()
404 s8 *bank, s32 *reg, s8 *bit, s8 *width) in tegra_pinconf_reg() argument
408 *bank = g->pupd_bank; in tegra_pinconf_reg()
409 *reg = g->pupd_reg; in tegra_pinconf_reg()
410 *bit = g->pupd_bit; in tegra_pinconf_reg()
411 *width = 2; in tegra_pinconf_reg()
414 *bank = g->tri_bank; in tegra_pinconf_reg()
415 *reg = g->tri_reg; in tegra_pinconf_reg()
416 *bit = g->tri_bit; in tegra_pinconf_reg()
417 *width = 1; in tegra_pinconf_reg()
420 *bank = g->mux_bank; in tegra_pinconf_reg()
421 *reg = g->mux_reg; in tegra_pinconf_reg()
422 *bit = g->einput_bit; in tegra_pinconf_reg()
423 *width = 1; in tegra_pinconf_reg()
426 *bank = g->mux_bank; in tegra_pinconf_reg()
427 *reg = g->mux_reg; in tegra_pinconf_reg()
428 *bit = g->odrain_bit; in tegra_pinconf_reg()
429 *width = 1; in tegra_pinconf_reg()
432 *bank = g->mux_bank; in tegra_pinconf_reg()
433 *reg = g->mux_reg; in tegra_pinconf_reg()
434 *bit = g->lock_bit; in tegra_pinconf_reg()
435 *width = 1; in tegra_pinconf_reg()
438 *bank = g->mux_bank; in tegra_pinconf_reg()
439 *reg = g->mux_reg; in tegra_pinconf_reg()
440 *bit = g->ioreset_bit; in tegra_pinconf_reg()
441 *width = 1; in tegra_pinconf_reg()
444 *bank = g->mux_bank; in tegra_pinconf_reg()
445 *reg = g->mux_reg; in tegra_pinconf_reg()
446 *bit = g->rcv_sel_bit; in tegra_pinconf_reg()
447 *width = 1; in tegra_pinconf_reg()
450 if (pmx->soc->hsm_in_mux) { in tegra_pinconf_reg()
451 *bank = g->mux_bank; in tegra_pinconf_reg()
452 *reg = g->mux_reg; in tegra_pinconf_reg()
454 *bank = g->drv_bank; in tegra_pinconf_reg()
455 *reg = g->drv_reg; in tegra_pinconf_reg()
457 *bit = g->hsm_bit; in tegra_pinconf_reg()
458 *width = 1; in tegra_pinconf_reg()
461 if (pmx->soc->schmitt_in_mux) { in tegra_pinconf_reg()
462 *bank = g->mux_bank; in tegra_pinconf_reg()
463 *reg = g->mux_reg; in tegra_pinconf_reg()
465 *bank = g->drv_bank; in tegra_pinconf_reg()
466 *reg = g->drv_reg; in tegra_pinconf_reg()
468 *bit = g->schmitt_bit; in tegra_pinconf_reg()
469 *width = 1; in tegra_pinconf_reg()
472 *bank = g->drv_bank; in tegra_pinconf_reg()
473 *reg = g->drv_reg; in tegra_pinconf_reg()
474 *bit = g->lpmd_bit; in tegra_pinconf_reg()
475 *width = 2; in tegra_pinconf_reg()
478 *bank = g->drv_bank; in tegra_pinconf_reg()
479 *reg = g->drv_reg; in tegra_pinconf_reg()
480 *bit = g->drvdn_bit; in tegra_pinconf_reg()
481 *width = g->drvdn_width; in tegra_pinconf_reg()
484 *bank = g->drv_bank; in tegra_pinconf_reg()
485 *reg = g->drv_reg; in tegra_pinconf_reg()
486 *bit = g->drvup_bit; in tegra_pinconf_reg()
487 *width = g->drvup_width; in tegra_pinconf_reg()
490 *bank = g->drv_bank; in tegra_pinconf_reg()
491 *reg = g->drv_reg; in tegra_pinconf_reg()
492 *bit = g->slwf_bit; in tegra_pinconf_reg()
493 *width = g->slwf_width; in tegra_pinconf_reg()
496 *bank = g->drv_bank; in tegra_pinconf_reg()
497 *reg = g->drv_reg; in tegra_pinconf_reg()
498 *bit = g->slwr_bit; in tegra_pinconf_reg()
499 *width = g->slwr_width; in tegra_pinconf_reg()
502 if (pmx->soc->drvtype_in_mux) { in tegra_pinconf_reg()
503 *bank = g->mux_bank; in tegra_pinconf_reg()
504 *reg = g->mux_reg; in tegra_pinconf_reg()
506 *bank = g->drv_bank; in tegra_pinconf_reg()
507 *reg = g->drv_reg; in tegra_pinconf_reg()
509 *bit = g->drvtype_bit; in tegra_pinconf_reg()
510 *width = 2; in tegra_pinconf_reg()
513 if (pmx->soc->sfsel_in_mux) { in tegra_pinconf_reg()
514 *bank = g->mux_bank; in tegra_pinconf_reg()
515 *reg = g->mux_reg; in tegra_pinconf_reg()
516 *bit = g->sfsel_bit; in tegra_pinconf_reg()
517 *width = 1; in tegra_pinconf_reg()
519 *reg = -EINVAL; in tegra_pinconf_reg()
523 dev_err(pmx->dev, "Invalid config param %04x\n", param); in tegra_pinconf_reg()
524 return -ENOTSUPP; in tegra_pinconf_reg()
539 dev_err(pmx->dev, in tegra_pinconf_reg()
541 param, prop, g->name); in tegra_pinconf_reg()
543 return -ENOTSUPP; in tegra_pinconf_reg()
552 dev_err(pctldev->dev, "pin_config_get op not supported\n"); in tegra_pinconf_get()
553 return -ENOTSUPP; in tegra_pinconf_get()
560 dev_err(pctldev->dev, "pin_config_set op not supported\n"); in tegra_pinconf_set()
561 return -ENOTSUPP; in tegra_pinconf_set()
572 s8 bank, bit, width; in tegra_pinconf_group_get() local
576 g = &pmx->soc->groups[group]; in tegra_pinconf_group_get()
578 ret = tegra_pinconf_reg(pmx, g, param, true, &bank, &reg, &bit, in tegra_pinconf_group_get()
579 &width); in tegra_pinconf_group_get()
583 val = pmx_readl(pmx, bank, reg); in tegra_pinconf_group_get()
584 mask = (1 << width) - 1; in tegra_pinconf_group_get()
601 s8 bank, bit, width; in tegra_pinconf_group_set() local
605 g = &pmx->soc->groups[group]; in tegra_pinconf_group_set()
611 ret = tegra_pinconf_reg(pmx, g, param, true, &bank, &reg, &bit, in tegra_pinconf_group_set()
612 &width); in tegra_pinconf_group_set()
616 val = pmx_readl(pmx, bank, reg); in tegra_pinconf_group_set()
621 dev_err(pctldev->dev, "LOCK bit cannot be cleared\n"); in tegra_pinconf_group_set()
622 return -EINVAL; in tegra_pinconf_group_set()
626 /* Special-case Boolean values; allow any non-zero as true */ in tegra_pinconf_group_set()
627 if (width == 1) in tegra_pinconf_group_set()
630 /* Range-check user-supplied value */ in tegra_pinconf_group_set()
631 mask = (1 << width) - 1; in tegra_pinconf_group_set()
633 dev_err(pctldev->dev, in tegra_pinconf_group_set()
635 configs[i], arg, width); in tegra_pinconf_group_set()
636 return -EINVAL; in tegra_pinconf_group_set()
642 pmx_writel(pmx, val, bank, reg); in tegra_pinconf_group_set()
669 s8 bank, bit, width; in tegra_pinconf_group_dbg_show() local
673 g = &pmx->soc->groups[group]; in tegra_pinconf_group_dbg_show()
677 &bank, &reg, &bit, &width); in tegra_pinconf_group_dbg_show()
681 val = pmx_readl(pmx, bank, reg); in tegra_pinconf_group_dbg_show()
683 val &= (1 << width) - 1; in tegra_pinconf_group_dbg_show()
689 if (g->mux_reg >= 0) { in tegra_pinconf_group_dbg_show()
691 val = pmx_readl(pmx, g->mux_bank, g->mux_reg); in tegra_pinconf_group_dbg_show()
692 val = g->funcs[(val >> g->mux_bit) & 0x3]; in tegra_pinconf_group_dbg_show()
694 seq_printf(s, "\n\tfunction=%s", pmx->functions[val].name); in tegra_pinconf_group_dbg_show()
736 for (i = 0; i < pmx->soc->ngroups; ++i) { in tegra_pinctrl_clear_parked_bits()
737 g = &pmx->soc->groups[i]; in tegra_pinctrl_clear_parked_bits()
738 if (g->parked_bitmask > 0) { in tegra_pinctrl_clear_parked_bits()
739 unsigned int bank, reg; in tegra_pinctrl_clear_parked_bits() local
741 if (g->mux_reg != -1) { in tegra_pinctrl_clear_parked_bits()
742 bank = g->mux_bank; in tegra_pinctrl_clear_parked_bits()
743 reg = g->mux_reg; in tegra_pinctrl_clear_parked_bits()
745 bank = g->drv_bank; in tegra_pinctrl_clear_parked_bits()
746 reg = g->drv_reg; in tegra_pinctrl_clear_parked_bits()
749 val = pmx_readl(pmx, bank, reg); in tegra_pinctrl_clear_parked_bits()
750 val &= ~g->parked_bitmask; in tegra_pinctrl_clear_parked_bits()
751 pmx_writel(pmx, val, bank, reg); in tegra_pinctrl_clear_parked_bits()
770 u32 *backup_regs = pmx->backup_regs; in tegra_pinctrl_suspend()
775 for (i = 0; i < pmx->nbanks; i++) { in tegra_pinctrl_suspend()
777 regs = pmx->regs[i]; in tegra_pinctrl_suspend()
782 return pinctrl_force_sleep(pmx->pctl); in tegra_pinctrl_suspend()
788 u32 *backup_regs = pmx->backup_regs; in tegra_pinctrl_resume()
793 for (i = 0; i < pmx->nbanks; i++) { in tegra_pinctrl_resume()
795 regs = pmx->regs[i]; in tegra_pinctrl_resume()
801 readl_relaxed(pmx->regs[0]); in tegra_pinctrl_resume()
814 np = of_find_compatible_node(NULL, NULL, pmx->soc->gpio_compatible); in tegra_pinctrl_gpio_node_has_range()
818 has_prop = of_find_property(np, "gpio-ranges", NULL); in tegra_pinctrl_gpio_node_has_range()
835 pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL); in tegra_pinctrl_probe()
837 return -ENOMEM; in tegra_pinctrl_probe()
839 pmx->dev = &pdev->dev; in tegra_pinctrl_probe()
840 pmx->soc = soc_data; in tegra_pinctrl_probe()
842 pmx->pingroup_configs = devm_kcalloc(&pdev->dev, in tegra_pinctrl_probe()
843 pmx->soc->ngroups, sizeof(*pmx->pingroup_configs), in tegra_pinctrl_probe()
845 if (!pmx->pingroup_configs) in tegra_pinctrl_probe()
846 return -ENOMEM; in tegra_pinctrl_probe()
850 * This over-allocates slightly, since not all groups are mux groups. in tegra_pinctrl_probe()
852 pmx->group_pins = devm_kcalloc(&pdev->dev, pmx->soc->ngroups * 4, in tegra_pinctrl_probe()
853 sizeof(*pmx->group_pins), GFP_KERNEL); in tegra_pinctrl_probe()
854 if (!pmx->group_pins) in tegra_pinctrl_probe()
855 return -ENOMEM; in tegra_pinctrl_probe()
857 pmx->functions = devm_kcalloc(&pdev->dev, pmx->soc->nfunctions, in tegra_pinctrl_probe()
858 sizeof(*pmx->functions), GFP_KERNEL); in tegra_pinctrl_probe()
859 if (!pmx->functions) in tegra_pinctrl_probe()
860 return -ENOMEM; in tegra_pinctrl_probe()
862 group_pins = pmx->group_pins; in tegra_pinctrl_probe()
864 for (fn = 0; fn < pmx->soc->nfunctions; fn++) { in tegra_pinctrl_probe()
865 struct tegra_function *func = &pmx->functions[fn]; in tegra_pinctrl_probe()
867 func->name = pmx->soc->functions[fn]; in tegra_pinctrl_probe()
868 func->groups = group_pins; in tegra_pinctrl_probe()
870 for (gn = 0; gn < pmx->soc->ngroups; gn++) { in tegra_pinctrl_probe()
871 const struct tegra_pingroup *g = &pmx->soc->groups[gn]; in tegra_pinctrl_probe()
873 if (g->mux_reg == -1) in tegra_pinctrl_probe()
877 if (g->funcs[gfn] == fn) in tegra_pinctrl_probe()
882 BUG_ON(group_pins - pmx->group_pins >= in tegra_pinctrl_probe()
883 pmx->soc->ngroups * 4); in tegra_pinctrl_probe()
884 *group_pins++ = g->name; in tegra_pinctrl_probe()
885 func->ngroups++; in tegra_pinctrl_probe()
889 pmx->gpio_range.name = "Tegra GPIOs"; in tegra_pinctrl_probe()
890 pmx->gpio_range.id = 0; in tegra_pinctrl_probe()
891 pmx->gpio_range.base = 0; in tegra_pinctrl_probe()
892 pmx->gpio_range.npins = pmx->soc->ngpios; in tegra_pinctrl_probe()
894 pmx->desc.pctlops = &tegra_pinctrl_ops; in tegra_pinctrl_probe()
895 pmx->desc.pmxops = &tegra_pinmux_ops; in tegra_pinctrl_probe()
896 pmx->desc.confops = &tegra_pinconf_ops; in tegra_pinctrl_probe()
897 pmx->desc.owner = THIS_MODULE; in tegra_pinctrl_probe()
898 pmx->desc.name = dev_name(&pdev->dev); in tegra_pinctrl_probe()
899 pmx->desc.pins = pmx->soc->pins; in tegra_pinctrl_probe()
900 pmx->desc.npins = pmx->soc->npins; in tegra_pinctrl_probe()
908 pmx->nbanks = i; in tegra_pinctrl_probe()
910 pmx->regs = devm_kcalloc(&pdev->dev, pmx->nbanks, sizeof(*pmx->regs), in tegra_pinctrl_probe()
912 if (!pmx->regs) in tegra_pinctrl_probe()
913 return -ENOMEM; in tegra_pinctrl_probe()
915 pmx->backup_regs = devm_kzalloc(&pdev->dev, backup_regs_size, in tegra_pinctrl_probe()
917 if (!pmx->backup_regs) in tegra_pinctrl_probe()
918 return -ENOMEM; in tegra_pinctrl_probe()
920 for (i = 0; i < pmx->nbanks; i++) { in tegra_pinctrl_probe()
921 pmx->regs[i] = devm_platform_ioremap_resource(pdev, i); in tegra_pinctrl_probe()
922 if (IS_ERR(pmx->regs[i])) in tegra_pinctrl_probe()
923 return PTR_ERR(pmx->regs[i]); in tegra_pinctrl_probe()
926 pmx->pctl = devm_pinctrl_register(&pdev->dev, &pmx->desc, pmx); in tegra_pinctrl_probe()
927 if (IS_ERR(pmx->pctl)) { in tegra_pinctrl_probe()
928 dev_err(&pdev->dev, "Couldn't register pinctrl driver\n"); in tegra_pinctrl_probe()
929 return PTR_ERR(pmx->pctl); in tegra_pinctrl_probe()
934 if (pmx->soc->ngpios > 0 && !tegra_pinctrl_gpio_node_has_range(pmx)) in tegra_pinctrl_probe()
935 pinctrl_add_gpio_range(pmx->pctl, &pmx->gpio_range); in tegra_pinctrl_probe()
939 dev_dbg(&pdev->dev, "Probed Tegra pinctrl driver\n"); in tegra_pinctrl_probe()