1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * (C) Copyright 2023 4 * Svyatoslav Ryhel <clamor95@gmail.com> 5 */ 6 7#include <dm.h> 8#include <dm/device_compat.h> 9#include <dm/pinctrl.h> 10#include <stdlib.h> 11 12#include <asm/arch/pinmux.h> 13 14static void tegra_pinctrl_set_pin(struct udevice *config) 15{ 16 int i, count, pin_id, ret; 17 int pull, tristate; 18 const char **pins; 19 20 ret = dev_read_u32(config, "nvidia,pull", &pull); 21 if (ret) 22 pull = ret; 23 24 ret = dev_read_u32(config, "nvidia,tristate", &tristate); 25 if (ret) 26 tristate = ret; 27 28 count = dev_read_string_list(config, "nvidia,pins", &pins); 29 if (count < 0) { 30 log_debug("%s: could not parse property nvidia,pins\n", __func__); 31 return; 32 } 33 34 for (i = 0; i < count; i++) { 35 for (pin_id = 0; pin_id < PMUX_PINGRP_COUNT; pin_id++) 36 if (tegra_pinctrl_to_pingrp[pin_id]) 37 if (!strcmp(pins[i], tegra_pinctrl_to_pingrp[pin_id])) 38 break; 39 40 if (pull >= 0) 41 pinmux_set_pullupdown(pin_id, pull); 42 43 if (tristate >= 0) { 44 if (!tristate) 45 pinmux_tristate_disable(pin_id); 46 else 47 pinmux_tristate_enable(pin_id); 48 } 49 } 50 51 free(pins); 52} 53 54static void tegra_pinctrl_set_func(struct udevice *config) 55{ 56 int i, count, func_id, pin_id; 57 const char *function; 58 const char **pins; 59 60 function = dev_read_string(config, "nvidia,function"); 61 if (function) 62 for (i = 0; i < PMUX_FUNC_COUNT; i++) 63 if (tegra_pinctrl_to_func[i]) 64 if (!strcmp(function, tegra_pinctrl_to_func[i])) 65 break; 66 67 func_id = i; 68 69 count = dev_read_string_list(config, "nvidia,pins", &pins); 70 if (count < 0) { 71 log_debug("%s: could not parse property nvidia,pins\n", __func__); 72 return; 73 } 74 75 for (i = 0; i < count; i++) { 76 for (pin_id = 0; pin_id < PMUX_PINGRP_COUNT; pin_id++) 77 if (tegra_pinctrl_to_pingrp[pin_id]) 78 if (!strcmp(pins[i], tegra_pinctrl_to_pingrp[pin_id])) 79 break; 80 81 debug("%s(%d) muxed to %s(%d)\n", pins[i], pin_id, function, func_id); 82 83 pinmux_set_func(pin_id, func_id); 84 } 85 86 free(pins); 87} 88 89static int tegra_pinctrl_set_state(struct udevice *dev, struct udevice *config) 90{ 91 struct udevice *child; 92 93 device_foreach_child(child, config) { 94 /* 95 * Tegra20 pinmux is set differently then any other 96 * Tegra SOC. Nodes are arranged by function muxing, 97 * then actual pins setup (with node name prefix 98 * conf_*) and then drive setup. 99 */ 100 if (!strncmp(child->name, "conf_", 5)) 101 tegra_pinctrl_set_pin(child); 102 else if (!strncmp(child->name, "drive_", 6)) 103 debug("%s: drive configuration is not supported\n", __func__); 104 else 105 tegra_pinctrl_set_func(child); 106 } 107 108 return 0; 109} 110 111static int tegra_pinctrl_get_pins_count(struct udevice *dev) 112{ 113 return PMUX_PINGRP_COUNT; 114} 115 116static const char *tegra_pinctrl_get_pin_name(struct udevice *dev, 117 unsigned int selector) 118{ 119 return tegra_pinctrl_to_pingrp[selector]; 120} 121 122static int tegra_pinctrl_get_groups_count(struct udevice *dev) 123{ 124 return PMUX_DRVGRP_COUNT; 125} 126 127static const char *tegra_pinctrl_get_group_name(struct udevice *dev, 128 unsigned int selector) 129{ 130 return tegra_pinctrl_to_drvgrp[selector]; 131} 132 133static int tegra_pinctrl_get_functions_count(struct udevice *dev) 134{ 135 return PMUX_FUNC_COUNT; 136} 137 138static const char *tegra_pinctrl_get_function_name(struct udevice *dev, 139 unsigned int selector) 140{ 141 return tegra_pinctrl_to_func[selector]; 142} 143 144const struct pinctrl_ops tegra_pinctrl_ops = { 145 .get_pins_count = tegra_pinctrl_get_pins_count, 146 .get_pin_name = tegra_pinctrl_get_pin_name, 147 .get_groups_count = tegra_pinctrl_get_groups_count, 148 .get_group_name = tegra_pinctrl_get_group_name, 149 .get_functions_count = tegra_pinctrl_get_functions_count, 150 .get_function_name = tegra_pinctrl_get_function_name, 151 .set_state = tegra_pinctrl_set_state, 152}; 153 154static int tegra_pinctrl_bind(struct udevice *dev) 155{ 156 /* 157 * Make sure that the pinctrl driver gets probed after binding 158 * to provide initial configuration and assure that further 159 * probed devices are working correctly. 160 */ 161 dev_or_flags(dev, DM_FLAG_PROBE_AFTER_BIND); 162 163 return 0; 164} 165 166static const struct udevice_id tegra_pinctrl_ids[] = { 167 { .compatible = "nvidia,tegra20-pinmux" }, 168 { }, 169}; 170 171U_BOOT_DRIVER(tegra_pinctrl) = { 172 .name = "tegra_pinctrl", 173 .id = UCLASS_PINCTRL, 174 .of_match = tegra_pinctrl_ids, 175 .bind = tegra_pinctrl_bind, 176 .ops = &tegra_pinctrl_ops, 177}; 178