^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver for the NVIDIA Tegra pinmux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Derived from code:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2010 Google, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2010 NVIDIA Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 2009-2011 ST-Ericsson AB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/pinctrl/machine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/pinctrl/pinctrl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/pinctrl/pinmux.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/pinctrl/pinconf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "../core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "../pinctrl-utils.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "pinctrl-tegra.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static inline u32 pmx_readl(struct tegra_pmx *pmx, u32 bank, u32 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) return readl(pmx->regs[bank] + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static inline void pmx_writel(struct tegra_pmx *pmx, u32 val, u32 bank, u32 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) writel_relaxed(val, pmx->regs[bank] + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* make sure pinmux register write completed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) pmx_readl(pmx, bank, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static int tegra_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return pmx->soc->ngroups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static const char *tegra_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) unsigned group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return pmx->soc->groups[group].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static int tegra_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) unsigned group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) const unsigned **pins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) unsigned *num_pins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) *pins = pmx->soc->groups[group].pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) *num_pins = pmx->soc->groups[group].npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static void tegra_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct seq_file *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) seq_printf(s, " %s", dev_name(pctldev->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static const struct cfg_param {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) const char *property;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) enum tegra_pinconf_param param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) } cfg_params[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {"nvidia,pull", TEGRA_PINCONF_PARAM_PULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {"nvidia,tristate", TEGRA_PINCONF_PARAM_TRISTATE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {"nvidia,enable-input", TEGRA_PINCONF_PARAM_ENABLE_INPUT},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {"nvidia,open-drain", TEGRA_PINCONF_PARAM_OPEN_DRAIN},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {"nvidia,lock", TEGRA_PINCONF_PARAM_LOCK},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {"nvidia,io-reset", TEGRA_PINCONF_PARAM_IORESET},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {"nvidia,rcv-sel", TEGRA_PINCONF_PARAM_RCV_SEL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {"nvidia,io-hv", TEGRA_PINCONF_PARAM_RCV_SEL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {"nvidia,high-speed-mode", TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {"nvidia,schmitt", TEGRA_PINCONF_PARAM_SCHMITT},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {"nvidia,low-power-mode", TEGRA_PINCONF_PARAM_LOW_POWER_MODE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {"nvidia,pull-down-strength", TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {"nvidia,pull-up-strength", TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {"nvidia,slew-rate-falling", TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {"nvidia,slew-rate-rising", TEGRA_PINCONF_PARAM_SLEW_RATE_RISING},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {"nvidia,drive-type", TEGRA_PINCONF_PARAM_DRIVE_TYPE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static int tegra_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct pinctrl_map **map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) unsigned *reserved_maps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) unsigned *num_maps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct device *dev = pctldev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) const char *function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) unsigned long config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) unsigned long *configs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) unsigned num_configs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) unsigned reserve;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) const char *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) ret = of_property_read_string(np, "nvidia,function", &function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* EINVAL=missing, which is fine since it's optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (ret != -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) "could not parse property nvidia,function\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) function = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) for (i = 0; i < ARRAY_SIZE(cfg_params); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) ret = of_property_read_u32(np, cfg_params[i].property, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) config = TEGRA_PINCONF_PACK(cfg_params[i].param, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) ret = pinctrl_utils_add_config(pctldev, &configs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) &num_configs, config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* EINVAL=missing, which is fine since it's optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) } else if (ret != -EINVAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) dev_err(dev, "could not parse property %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) cfg_params[i].property);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) reserve = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (function != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) reserve++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (num_configs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) reserve++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) ret = of_property_count_strings(np, "nvidia,pins");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) dev_err(dev, "could not parse property nvidia,pins\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) reserve *= ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) ret = pinctrl_utils_reserve_map(pctldev, map, reserved_maps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) num_maps, reserve);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) of_property_for_each_string(np, "nvidia,pins", prop, group) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (function) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ret = pinctrl_utils_add_map_mux(pctldev, map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) reserved_maps, num_maps, group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (num_configs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) ret = pinctrl_utils_add_map_configs(pctldev, map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) reserved_maps, num_maps, group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) configs, num_configs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) PIN_MAP_TYPE_CONFIGS_GROUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) kfree(configs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static int tegra_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct device_node *np_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct pinctrl_map **map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) unsigned *num_maps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) unsigned reserved_maps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) reserved_maps = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) *map = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) *num_maps = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) for_each_child_of_node(np_config, np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) ret = tegra_pinctrl_dt_subnode_to_map(pctldev, np, map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) &reserved_maps, num_maps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) pinctrl_utils_free_map(pctldev, *map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) *num_maps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static const struct pinctrl_ops tegra_pinctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) .get_groups_count = tegra_pinctrl_get_groups_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) .get_group_name = tegra_pinctrl_get_group_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) .get_group_pins = tegra_pinctrl_get_group_pins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) .pin_dbg_show = tegra_pinctrl_pin_dbg_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) .dt_node_to_map = tegra_pinctrl_dt_node_to_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .dt_free_map = pinctrl_utils_free_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static int tegra_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return pmx->soc->nfunctions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static const char *tegra_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) unsigned function)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return pmx->soc->functions[function].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static int tegra_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) unsigned function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) const char * const **groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) unsigned * const num_groups)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) *groups = pmx->soc->functions[function].groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) *num_groups = pmx->soc->functions[function].ngroups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static int tegra_pinctrl_set_mux(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) unsigned function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) unsigned group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) const struct tegra_pingroup *g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) g = &pmx->soc->groups[group];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (WARN_ON(g->mux_reg < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) for (i = 0; i < ARRAY_SIZE(g->funcs); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (g->funcs[i] == function)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (WARN_ON(i == ARRAY_SIZE(g->funcs)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) val = pmx_readl(pmx, g->mux_bank, g->mux_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) val &= ~(0x3 << g->mux_bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) val |= i << g->mux_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) pmx_writel(pmx, val, g->mux_bank, g->mux_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static int tegra_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) struct pinctrl_gpio_range *range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) const struct tegra_pingroup *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (!pmx->soc->sfsel_in_mux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) group = &pmx->soc->groups[offset];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (group->mux_reg < 0 || group->sfsel_bit < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) value = pmx_readl(pmx, group->mux_bank, group->mux_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) value &= ~BIT(group->sfsel_bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) pmx_writel(pmx, value, group->mux_bank, group->mux_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static void tegra_pinctrl_gpio_disable_free(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct pinctrl_gpio_range *range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) const struct tegra_pingroup *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (!pmx->soc->sfsel_in_mux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) group = &pmx->soc->groups[offset];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (group->mux_reg < 0 || group->sfsel_bit < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) value = pmx_readl(pmx, group->mux_bank, group->mux_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) value |= BIT(group->sfsel_bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) pmx_writel(pmx, value, group->mux_bank, group->mux_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) static const struct pinmux_ops tegra_pinmux_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) .get_functions_count = tegra_pinctrl_get_funcs_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) .get_function_name = tegra_pinctrl_get_func_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) .get_function_groups = tegra_pinctrl_get_func_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) .set_mux = tegra_pinctrl_set_mux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) .gpio_request_enable = tegra_pinctrl_gpio_request_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) .gpio_disable_free = tegra_pinctrl_gpio_disable_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static int tegra_pinconf_reg(struct tegra_pmx *pmx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) const struct tegra_pingroup *g,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) enum tegra_pinconf_param param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) bool report_err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) s8 *bank, s32 *reg, s8 *bit, s8 *width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) switch (param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) case TEGRA_PINCONF_PARAM_PULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) *bank = g->pupd_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) *reg = g->pupd_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) *bit = g->pupd_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) *width = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) case TEGRA_PINCONF_PARAM_TRISTATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) *bank = g->tri_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) *reg = g->tri_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) *bit = g->tri_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) *width = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) case TEGRA_PINCONF_PARAM_ENABLE_INPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) *bank = g->mux_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) *reg = g->mux_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) *bit = g->einput_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) *width = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) case TEGRA_PINCONF_PARAM_OPEN_DRAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) *bank = g->mux_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) *reg = g->mux_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) *bit = g->odrain_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) *width = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) case TEGRA_PINCONF_PARAM_LOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) *bank = g->mux_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) *reg = g->mux_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) *bit = g->lock_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) *width = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) case TEGRA_PINCONF_PARAM_IORESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) *bank = g->mux_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) *reg = g->mux_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) *bit = g->ioreset_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) *width = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) case TEGRA_PINCONF_PARAM_RCV_SEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) *bank = g->mux_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) *reg = g->mux_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) *bit = g->rcv_sel_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) *width = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) case TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (pmx->soc->hsm_in_mux) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) *bank = g->mux_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) *reg = g->mux_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) *bank = g->drv_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) *reg = g->drv_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) *bit = g->hsm_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) *width = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) case TEGRA_PINCONF_PARAM_SCHMITT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (pmx->soc->schmitt_in_mux) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) *bank = g->mux_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) *reg = g->mux_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) *bank = g->drv_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) *reg = g->drv_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) *bit = g->schmitt_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) *width = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) case TEGRA_PINCONF_PARAM_LOW_POWER_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) *bank = g->drv_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) *reg = g->drv_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) *bit = g->lpmd_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) *width = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) case TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) *bank = g->drv_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) *reg = g->drv_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) *bit = g->drvdn_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) *width = g->drvdn_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) case TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) *bank = g->drv_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) *reg = g->drv_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) *bit = g->drvup_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) *width = g->drvup_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) case TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) *bank = g->drv_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) *reg = g->drv_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) *bit = g->slwf_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) *width = g->slwf_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) case TEGRA_PINCONF_PARAM_SLEW_RATE_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) *bank = g->drv_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) *reg = g->drv_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) *bit = g->slwr_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) *width = g->slwr_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) case TEGRA_PINCONF_PARAM_DRIVE_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (pmx->soc->drvtype_in_mux) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) *bank = g->mux_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) *reg = g->mux_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) *bank = g->drv_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) *reg = g->drv_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) *bit = g->drvtype_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) *width = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) dev_err(pmx->dev, "Invalid config param %04x\n", param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (*reg < 0 || *bit < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (report_err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) const char *prop = "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) for (i = 0; i < ARRAY_SIZE(cfg_params); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (cfg_params[i].param == param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) prop = cfg_params[i].property;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) dev_err(pmx->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) "Config param %04x (%s) not supported on group %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) param, prop, g->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) static int tegra_pinconf_get(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) unsigned pin, unsigned long *config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) dev_err(pctldev->dev, "pin_config_get op not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) static int tegra_pinconf_set(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) unsigned pin, unsigned long *configs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) unsigned num_configs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) dev_err(pctldev->dev, "pin_config_set op not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static int tegra_pinconf_group_get(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) unsigned group, unsigned long *config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) enum tegra_pinconf_param param = TEGRA_PINCONF_UNPACK_PARAM(*config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) u16 arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) const struct tegra_pingroup *g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) s8 bank, bit, width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) s32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) u32 val, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) g = &pmx->soc->groups[group];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) ret = tegra_pinconf_reg(pmx, g, param, true, &bank, ®, &bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) &width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) val = pmx_readl(pmx, bank, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) mask = (1 << width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) arg = (val >> bit) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) *config = TEGRA_PINCONF_PACK(param, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) static int tegra_pinconf_group_set(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) unsigned group, unsigned long *configs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) unsigned num_configs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) enum tegra_pinconf_param param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) u16 arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) const struct tegra_pingroup *g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) s8 bank, bit, width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) s32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) u32 val, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) g = &pmx->soc->groups[group];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) for (i = 0; i < num_configs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) param = TEGRA_PINCONF_UNPACK_PARAM(configs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) arg = TEGRA_PINCONF_UNPACK_ARG(configs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) ret = tegra_pinconf_reg(pmx, g, param, true, &bank, ®, &bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) &width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) val = pmx_readl(pmx, bank, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) /* LOCK can't be cleared */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (param == TEGRA_PINCONF_PARAM_LOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if ((val & BIT(bit)) && !arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) dev_err(pctldev->dev, "LOCK bit cannot be cleared\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) /* Special-case Boolean values; allow any non-zero as true */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (width == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) arg = !!arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) /* Range-check user-supplied value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) mask = (1 << width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (arg & ~mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) dev_err(pctldev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) "config %lx: %x too big for %d bit register\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) configs[i], arg, width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) /* Update register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) val &= ~(mask << bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) val |= arg << bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) pmx_writel(pmx, val, bank, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) } /* for each config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) static void tegra_pinconf_dbg_show(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) struct seq_file *s, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) static const char *strip_prefix(const char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) const char *comma = strchr(s, ',');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if (!comma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) return comma + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) static void tegra_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct seq_file *s, unsigned group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) const struct tegra_pingroup *g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) s8 bank, bit, width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) s32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) g = &pmx->soc->groups[group];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) for (i = 0; i < ARRAY_SIZE(cfg_params); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) ret = tegra_pinconf_reg(pmx, g, cfg_params[i].param, false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) &bank, ®, &bit, &width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) val = pmx_readl(pmx, bank, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) val >>= bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) val &= (1 << width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) seq_printf(s, "\n\t%s=%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) strip_prefix(cfg_params[i].property), val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) static void tegra_pinconf_config_dbg_show(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) struct seq_file *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) unsigned long config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) enum tegra_pinconf_param param = TEGRA_PINCONF_UNPACK_PARAM(config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) u16 arg = TEGRA_PINCONF_UNPACK_ARG(config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) const char *pname = "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) for (i = 0; i < ARRAY_SIZE(cfg_params); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (cfg_params[i].param == param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) pname = cfg_params[i].property;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) seq_printf(s, "%s=%d", strip_prefix(pname), arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) static const struct pinconf_ops tegra_pinconf_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) .pin_config_get = tegra_pinconf_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) .pin_config_set = tegra_pinconf_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) .pin_config_group_get = tegra_pinconf_group_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) .pin_config_group_set = tegra_pinconf_group_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) .pin_config_dbg_show = tegra_pinconf_dbg_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) .pin_config_group_dbg_show = tegra_pinconf_group_dbg_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) .pin_config_config_dbg_show = tegra_pinconf_config_dbg_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) static struct pinctrl_gpio_range tegra_pinctrl_gpio_range = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) .name = "Tegra GPIOs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) .id = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) .base = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) static struct pinctrl_desc tegra_pinctrl_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) .pctlops = &tegra_pinctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) .pmxops = &tegra_pinmux_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) .confops = &tegra_pinconf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) static void tegra_pinctrl_clear_parked_bits(struct tegra_pmx *pmx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) const struct tegra_pingroup *g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) for (i = 0; i < pmx->soc->ngroups; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) g = &pmx->soc->groups[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (g->parked_bitmask > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) unsigned int bank, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (g->mux_reg != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) bank = g->mux_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) reg = g->mux_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) bank = g->drv_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) reg = g->drv_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) val = pmx_readl(pmx, bank, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) val &= ~g->parked_bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) pmx_writel(pmx, val, bank, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) static size_t tegra_pinctrl_get_bank_size(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) unsigned int bank_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) struct platform_device *pdev = to_platform_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) res = platform_get_resource(pdev, IORESOURCE_MEM, bank_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) return resource_size(res) / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) static int tegra_pinctrl_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct tegra_pmx *pmx = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) u32 *backup_regs = pmx->backup_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) u32 __iomem *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) size_t bank_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) unsigned int i, k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) for (i = 0; i < pmx->nbanks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) bank_size = tegra_pinctrl_get_bank_size(dev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) regs = pmx->regs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) for (k = 0; k < bank_size; k++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) *backup_regs++ = readl_relaxed(regs++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) return pinctrl_force_sleep(pmx->pctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) static int tegra_pinctrl_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) struct tegra_pmx *pmx = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) u32 *backup_regs = pmx->backup_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) u32 __iomem *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) size_t bank_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) unsigned int i, k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) for (i = 0; i < pmx->nbanks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) bank_size = tegra_pinctrl_get_bank_size(dev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) regs = pmx->regs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) for (k = 0; k < bank_size; k++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) writel_relaxed(*backup_regs++, regs++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) /* flush all the prior writes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) readl_relaxed(pmx->regs[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) /* wait for pinctrl register read to complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) const struct dev_pm_ops tegra_pinctrl_pm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) .suspend_noirq = &tegra_pinctrl_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) .resume_noirq = &tegra_pinctrl_resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) static bool tegra_pinctrl_gpio_node_has_range(struct tegra_pmx *pmx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) bool has_prop = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) np = of_find_compatible_node(NULL, NULL, pmx->soc->gpio_compatible);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) return has_prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) has_prop = of_find_property(np, "gpio-ranges", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) return has_prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) int tegra_pinctrl_probe(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) const struct tegra_pinctrl_soc_data *soc_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) struct tegra_pmx *pmx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) const char **group_pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) int fn, gn, gfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) unsigned long backup_regs_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (!pmx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) pmx->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) pmx->soc = soc_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) * Each mux group will appear in 4 functions' list of groups.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) * This over-allocates slightly, since not all groups are mux groups.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) pmx->group_pins = devm_kcalloc(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) soc_data->ngroups * 4, sizeof(*pmx->group_pins),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (!pmx->group_pins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) group_pins = pmx->group_pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) for (fn = 0; fn < soc_data->nfunctions; fn++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) struct tegra_function *func = &soc_data->functions[fn];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) func->groups = group_pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) for (gn = 0; gn < soc_data->ngroups; gn++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) const struct tegra_pingroup *g = &soc_data->groups[gn];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (g->mux_reg == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) for (gfn = 0; gfn < 4; gfn++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (g->funcs[gfn] == fn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (gfn == 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) BUG_ON(group_pins - pmx->group_pins >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) soc_data->ngroups * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) *group_pins++ = g->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) func->ngroups++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) tegra_pinctrl_gpio_range.npins = pmx->soc->ngpios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) tegra_pinctrl_desc.name = dev_name(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) tegra_pinctrl_desc.pins = pmx->soc->pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) tegra_pinctrl_desc.npins = pmx->soc->npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) for (i = 0; ; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) res = platform_get_resource(pdev, IORESOURCE_MEM, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) if (!res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) backup_regs_size += resource_size(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) pmx->nbanks = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) pmx->regs = devm_kcalloc(&pdev->dev, pmx->nbanks, sizeof(*pmx->regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (!pmx->regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) pmx->backup_regs = devm_kzalloc(&pdev->dev, backup_regs_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (!pmx->backup_regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) for (i = 0; i < pmx->nbanks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) pmx->regs[i] = devm_platform_ioremap_resource(pdev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (IS_ERR(pmx->regs[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return PTR_ERR(pmx->regs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) pmx->pctl = devm_pinctrl_register(&pdev->dev, &tegra_pinctrl_desc, pmx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (IS_ERR(pmx->pctl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) return PTR_ERR(pmx->pctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) tegra_pinctrl_clear_parked_bits(pmx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) if (pmx->soc->ngpios > 0 && !tegra_pinctrl_gpio_node_has_range(pmx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) pinctrl_add_gpio_range(pmx->pctl, &tegra_pinctrl_gpio_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) platform_set_drvdata(pdev, pmx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) dev_dbg(&pdev->dev, "Probed Tegra pinctrl driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }