1 // SPDX-License-Identifier: GPL-2.0
3 * Xilinx pinctrl driver for ZynqMP
8 * Copyright (C) 2021 Xilinx, Inc. All rights reserved.
14 #include <zynqmp_firmware.h>
15 #include <asm/arch/sys_proto.h>
17 #include <dm/device_compat.h>
18 #include <dm/pinctrl.h>
19 #include <linux/compat.h>
20 #include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
22 #define PINCTRL_GET_FUNC_GROUPS_RESP_LEN 12
23 #define PINCTRL_GET_PIN_GROUPS_RESP_LEN 12
24 #define NUM_GROUPS_PER_RESP 6
26 #define RESERVED_GROUP -2
27 #define MAX_GROUP_PIN 50
28 #define MAX_PIN_GROUPS 50
29 #define MAX_GROUP_NAME_LEN 32
30 #define MAX_FUNC_NAME_LEN 16
32 #define DRIVE_STRENGTH_2MA 2
33 #define DRIVE_STRENGTH_4MA 4
34 #define DRIVE_STRENGTH_8MA 8
35 #define DRIVE_STRENGTH_12MA 12
38 * This driver works with very simple configuration that has the same name
39 * for group and function. This way it is compatible with the Linux Kernel
42 struct zynqmp_pinctrl_priv {
46 struct zynqmp_pmux_function *funcs;
47 struct zynqmp_pctrl_group *groups;
51 * struct zynqmp_pinctrl_config - pinconfig parameters
52 * @slew: Slew rate slow or fast
53 * @bias: Bias enabled or disabled
54 * @pull_ctrl: Pull control pull up or pull down
55 * @input_type: CMOS or Schmitt
56 * @drive_strength: Drive strength 2mA/4mA/8mA/12mA
57 * @volt_sts: Voltage status 1.8V or 3.3V
58 * @tri_state: Tristate enabled or disabled
60 * This structure holds information about pin control config
61 * option that can be set for each pin.
63 struct zynqmp_pinctrl_config {
74 * enum zynqmp_pin_config_param - possible pin configuration parameters
75 * @PIN_CFG_IOSTANDARD: if the pin can select an IO standard,
76 * the argument to this parameter (on a
77 * custom format) tells the driver which
78 * alternative IO standard to use
79 * @PIN_CONFIG_SCHMITTCMOS: this parameter (on a custom format) allows
80 * to select schmitt or cmos input for MIO pins
82 enum zynqmp_pin_config_param {
83 PIN_CFG_IOSTANDARD = PIN_CONFIG_END + 1,
84 PIN_CONFIG_SCHMITTCMOS,
88 * struct zynqmp_pmux_function - a pinmux function
89 * @name: Name of the pinmux function
90 * @groups: List of pingroups for this function
91 * @ngroups: Number of entries in @groups
93 * This structure holds information about pin control function
94 * and function group names supporting that function.
96 struct zynqmp_pmux_function {
97 char name[MAX_FUNC_NAME_LEN];
98 const char * const *groups;
103 * struct zynqmp_pctrl_group - Pin control group info
105 * @pins: Group pin numbers
106 * @npins: Number of pins in group
108 struct zynqmp_pctrl_group {
110 unsigned int pins[MAX_GROUP_PIN];
114 static char pin_name[PINNAME_SIZE];
117 * zynqmp_pm_query_data() - Get query data from firmware
118 * @qid: Value of enum pm_query_id
121 * @out: Returned output value
123 * Return: Returns status, either success or error+reason
125 static int zynqmp_pm_query_data(enum pm_query_id qid, u32 arg1, u32 arg2, u32 *out)
128 u32 ret_payload[PAYLOAD_ARG_CNT];
130 ret = xilinx_pm_request(PM_QUERY_DATA, qid, arg1, arg2, 0, ret_payload);
134 *out = ret_payload[1];
139 static int zynqmp_pm_pinctrl_get_config(const u32 pin, const u32 param, u32 *value)
142 u32 ret_payload[PAYLOAD_ARG_CNT];
144 /* Get config for the pin */
145 ret = xilinx_pm_request(PM_PINCTRL_CONFIG_PARAM_GET, pin, param, 0, 0, ret_payload);
147 printf("%s failed\n", __func__);
151 *value = ret_payload[1];
156 static int zynqmp_pm_pinctrl_set_config(const u32 pin, const u32 param, u32 value)
160 if (param == PM_PINCTRL_CONFIG_TRI_STATE) {
161 ret = zynqmp_pm_feature(PM_PINCTRL_CONFIG_PARAM_SET);
162 if (ret < PM_PINCTRL_PARAM_SET_VERSION)
166 /* Request the pin first */
167 ret = xilinx_pm_request(PM_PINCTRL_REQUEST, pin, 0, 0, 0, NULL);
169 printf("%s: pin request failed\n", __func__);
173 /* Set config for the pin */
174 ret = xilinx_pm_request(PM_PINCTRL_CONFIG_PARAM_SET, pin, param, value, 0, NULL);
176 printf("%s failed\n", __func__);
183 static int zynqmp_pinctrl_get_function_groups(u32 fid, u32 index, u16 *groups)
186 u32 ret_payload[PAYLOAD_ARG_CNT];
188 ret = xilinx_pm_request(PM_QUERY_DATA, PM_QID_PINCTRL_GET_FUNCTION_GROUPS,
189 fid, index, 0, ret_payload);
191 printf("%s failed\n", __func__);
195 memcpy(groups, &ret_payload[1], PINCTRL_GET_FUNC_GROUPS_RESP_LEN);
200 static int zynqmp_pinctrl_prepare_func_groups(u32 fid,
201 struct zynqmp_pmux_function *func,
202 struct zynqmp_pctrl_group *groups)
204 const char **fgroups;
205 char name[MAX_GROUP_NAME_LEN];
206 u16 resp[NUM_GROUPS_PER_RESP] = {0};
209 fgroups = kcalloc(func->ngroups, sizeof(*fgroups), GFP_KERNEL);
213 for (index = 0; index < func->ngroups; index += NUM_GROUPS_PER_RESP) {
214 ret = zynqmp_pinctrl_get_function_groups(fid, index, resp);
218 for (i = 0; i < NUM_GROUPS_PER_RESP; i++) {
219 if (resp[i] == (u16)NA_GROUP)
221 if (resp[i] == (u16)RESERVED_GROUP)
224 snprintf(name, MAX_GROUP_NAME_LEN, "%s_%d_grp",
225 func->name, index + i);
226 fgroups[index + i] = strdup(name);
228 snprintf(name, MAX_GROUP_NAME_LEN, "%s_%d_grp",
229 func->name, index + i);
230 groups[resp[i]].name = strdup(name);
234 func->groups = fgroups;
239 static int zynqmp_pinctrl_get_pin_groups(u32 pin, u32 index, u16 *groups)
242 u32 ret_payload[PAYLOAD_ARG_CNT];
244 ret = xilinx_pm_request(PM_QUERY_DATA, PM_QID_PINCTRL_GET_PIN_GROUPS,
245 pin, index, 0, ret_payload);
247 printf("%s failed to get pin groups\n", __func__);
251 memcpy(groups, &ret_payload[1], PINCTRL_GET_PIN_GROUPS_RESP_LEN);
256 static void zynqmp_pinctrl_group_add_pin(struct zynqmp_pctrl_group *group,
259 group->pins[group->npins++] = pin;
262 static int zynqmp_pinctrl_create_pin_groups(struct zynqmp_pctrl_group *groups,
265 u16 resp[NUM_GROUPS_PER_RESP] = {0};
266 int ret, i, index = 0;
269 ret = zynqmp_pinctrl_get_pin_groups(pin, index, resp);
273 for (i = 0; i < NUM_GROUPS_PER_RESP; i++) {
274 if (resp[i] == (u16)NA_GROUP)
276 if (resp[i] == (u16)RESERVED_GROUP)
278 zynqmp_pinctrl_group_add_pin(&groups[resp[i]], pin);
280 index += NUM_GROUPS_PER_RESP;
281 } while (index <= MAX_PIN_GROUPS);
287 static int zynqmp_pinctrl_probe(struct udevice *dev)
289 struct zynqmp_pinctrl_priv *priv = dev_get_priv(dev);
292 u32 ret_payload[PAYLOAD_ARG_CNT];
294 /* Get number of pins first */
295 ret = zynqmp_pm_query_data(PM_QID_PINCTRL_GET_NUM_PINS, 0, 0, &priv->npins);
297 printf("%s failed to get no of pins\n", __func__);
301 /* Get number of functions available */
302 ret = zynqmp_pm_query_data(PM_QID_PINCTRL_GET_NUM_FUNCTIONS, 0, 0, &priv->nfuncs);
304 printf("%s failed to get no of functions\n", __func__);
308 /* Allocating structures for functions and its groups */
309 priv->funcs = kzalloc(sizeof(*priv->funcs) * priv->nfuncs, GFP_KERNEL);
313 for (i = 0; i < priv->nfuncs; i++) {
314 /* Get function name for the function and fill */
315 xilinx_pm_request(PM_QUERY_DATA, PM_QID_PINCTRL_GET_FUNCTION_NAME,
316 i, 0, 0, ret_payload);
318 memcpy((void *)priv->funcs[i].name, ret_payload, MAX_FUNC_NAME_LEN);
320 /* And fill number of groups available for certain function */
321 xilinx_pm_request(PM_QUERY_DATA, PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS,
322 i, 0, 0, ret_payload);
324 priv->funcs[i].ngroups = ret_payload[1];
325 priv->ngroups += priv->funcs[i].ngroups;
328 /* Prepare all groups */
329 priv->groups = kzalloc(sizeof(*priv->groups) * priv->ngroups,
334 for (i = 0; i < priv->nfuncs; i++) {
335 ret = zynqmp_pinctrl_prepare_func_groups(i, &priv->funcs[i],
338 printf("Failed to prepare_func_groups\n");
343 for (pin = 0; pin < priv->npins; pin++) {
344 ret = zynqmp_pinctrl_create_pin_groups(priv->groups, pin);
352 static int zynqmp_pinctrl_get_functions_count(struct udevice *dev)
354 struct zynqmp_pinctrl_priv *priv = dev_get_priv(dev);
359 static const char *zynqmp_pinctrl_get_function_name(struct udevice *dev,
360 unsigned int selector)
362 struct zynqmp_pinctrl_priv *priv = dev_get_priv(dev);
364 return priv->funcs[selector].name;
367 static int zynqmp_pinmux_set(struct udevice *dev, unsigned int selector,
368 unsigned int func_selector)
372 /* Request the pin first */
373 ret = xilinx_pm_request(PM_PINCTRL_REQUEST, selector, 0, 0, 0, NULL);
375 printf("%s: pin request failed\n", __func__);
379 /* Set the pin function */
380 ret = xilinx_pm_request(PM_PINCTRL_SET_FUNCTION, selector, func_selector,
383 printf("%s: Failed to set pinmux function\n", __func__);
390 static int zynqmp_pinmux_group_set(struct udevice *dev, unsigned int selector,
391 unsigned int func_selector)
394 struct zynqmp_pinctrl_priv *priv = dev_get_priv(dev);
395 const struct zynqmp_pctrl_group *pgrp = &priv->groups[selector];
397 for (i = 0; i < pgrp->npins; i++)
398 zynqmp_pinmux_set(dev, pgrp->pins[i], func_selector);
403 static int zynqmp_pinconf_set(struct udevice *dev, unsigned int pin,
404 unsigned int param, unsigned int arg)
410 case PIN_CONFIG_SLEW_RATE:
411 param = PM_PINCTRL_CONFIG_SLEW_RATE;
412 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);
414 case PIN_CONFIG_BIAS_PULL_UP:
415 param = PM_PINCTRL_CONFIG_PULL_CTRL;
416 arg = PM_PINCTRL_BIAS_PULL_UP;
417 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);
419 case PIN_CONFIG_BIAS_PULL_DOWN:
420 param = PM_PINCTRL_CONFIG_PULL_CTRL;
421 arg = PM_PINCTRL_BIAS_PULL_DOWN;
422 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);
424 case PIN_CONFIG_BIAS_DISABLE:
425 param = PM_PINCTRL_CONFIG_BIAS_STATUS;
426 arg = PM_PINCTRL_BIAS_DISABLE;
427 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);
429 case PIN_CONFIG_SCHMITTCMOS:
430 param = PM_PINCTRL_CONFIG_SCHMITT_CMOS;
431 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);
433 case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
434 param = PM_PINCTRL_CONFIG_SCHMITT_CMOS;
435 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);
437 case PIN_CONFIG_DRIVE_STRENGTH:
439 case DRIVE_STRENGTH_2MA:
440 value = PM_PINCTRL_DRIVE_STRENGTH_2MA;
442 case DRIVE_STRENGTH_4MA:
443 value = PM_PINCTRL_DRIVE_STRENGTH_4MA;
445 case DRIVE_STRENGTH_8MA:
446 value = PM_PINCTRL_DRIVE_STRENGTH_8MA;
448 case DRIVE_STRENGTH_12MA:
449 value = PM_PINCTRL_DRIVE_STRENGTH_12MA;
452 /* Invalid drive strength */
453 dev_warn(dev, "Invalid drive strength for pin %d\n", pin);
457 param = PM_PINCTRL_CONFIG_DRIVE_STRENGTH;
458 ret = zynqmp_pm_pinctrl_set_config(pin, param, value);
460 case PIN_CFG_IOSTANDARD:
461 param = PM_PINCTRL_CONFIG_VOLTAGE_STATUS;
462 ret = zynqmp_pm_pinctrl_get_config(pin, param, &value);
464 dev_warn(dev, "Invalid IO Standard requested for pin %d\n",
467 case PIN_CONFIG_POWER_SOURCE:
468 param = PM_PINCTRL_CONFIG_VOLTAGE_STATUS;
469 ret = zynqmp_pm_pinctrl_get_config(pin, param, &value);
471 dev_warn(dev, "Invalid IO Standard requested for pin %d\n",
474 case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
475 param = PM_PINCTRL_CONFIG_TRI_STATE;
476 arg = PM_PINCTRL_TRI_STATE_ENABLE;
477 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);
479 case PIN_CONFIG_LOW_POWER_MODE:
481 * This cases are mentioned in dts but configurable
482 * registers are unknown. So falling through to ignore
483 * boot time warnings as of now.
487 case PIN_CONFIG_OUTPUT_ENABLE:
488 param = PM_PINCTRL_CONFIG_TRI_STATE;
489 arg = PM_PINCTRL_TRI_STATE_DISABLE;
490 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);
493 dev_warn(dev, "unsupported configuration parameter '%u'\n",
502 static int zynqmp_pinconf_group_set(struct udevice *dev,
503 unsigned int group_selector,
504 unsigned int param, unsigned int arg)
507 struct zynqmp_pinctrl_priv *priv = dev_get_priv(dev);
508 const struct zynqmp_pctrl_group *pgrp = &priv->groups[group_selector];
510 for (i = 0; i < pgrp->npins; i++)
511 zynqmp_pinconf_set(dev, pgrp->pins[i], param, arg);
516 static int zynqmp_pinctrl_get_pins_count(struct udevice *dev)
518 struct zynqmp_pinctrl_priv *priv = dev_get_priv(dev);
523 static const char *zynqmp_pinctrl_get_pin_name(struct udevice *dev,
524 unsigned int selector)
526 snprintf(pin_name, PINNAME_SIZE, "MIO%d", selector);
531 static int zynqmp_pinctrl_get_pin_muxing(struct udevice *dev,
532 unsigned int selector,
536 struct zynqmp_pinctrl_config pinmux;
538 zynqmp_pm_pinctrl_get_config(selector, PM_PINCTRL_CONFIG_SLEW_RATE,
540 zynqmp_pm_pinctrl_get_config(selector, PM_PINCTRL_CONFIG_BIAS_STATUS,
542 zynqmp_pm_pinctrl_get_config(selector, PM_PINCTRL_CONFIG_PULL_CTRL,
544 zynqmp_pm_pinctrl_get_config(selector, PM_PINCTRL_CONFIG_SCHMITT_CMOS,
546 zynqmp_pm_pinctrl_get_config(selector, PM_PINCTRL_CONFIG_DRIVE_STRENGTH,
547 &pinmux.drive_strength);
548 zynqmp_pm_pinctrl_get_config(selector, PM_PINCTRL_CONFIG_VOLTAGE_STATUS,
550 zynqmp_pm_pinctrl_get_config(selector, PM_PINCTRL_CONFIG_TRI_STATE,
553 switch (pinmux.drive_strength) {
554 case PM_PINCTRL_DRIVE_STRENGTH_2MA:
555 pinmux.drive_strength = DRIVE_STRENGTH_2MA;
557 case PM_PINCTRL_DRIVE_STRENGTH_4MA:
558 pinmux.drive_strength = DRIVE_STRENGTH_4MA;
560 case PM_PINCTRL_DRIVE_STRENGTH_8MA:
561 pinmux.drive_strength = DRIVE_STRENGTH_8MA;
563 case PM_PINCTRL_DRIVE_STRENGTH_12MA:
564 pinmux.drive_strength = DRIVE_STRENGTH_12MA;
567 /* Invalid drive strength */
568 dev_warn(dev, "Invalid drive strength\n");
573 "slew:%s\tbias:%s\tpull:%s\tinput:%s\tdrive:%dmA\tvolt:%s\ttri_state:%s",
574 pinmux.slew ? "slow" : "fast",
575 pinmux.bias ? "enabled" : "disabled",
576 pinmux.pull_ctrl ? "up" : "down",
577 pinmux.input_type ? "schmitt" : "cmos",
578 pinmux.drive_strength,
579 pinmux.volt_sts ? "1.8" : "3.3",
580 pinmux.tri_state ? "enabled" : "disabled");
585 static int zynqmp_pinctrl_get_groups_count(struct udevice *dev)
587 struct zynqmp_pinctrl_priv *priv = dev_get_priv(dev);
589 return priv->ngroups;
592 static const char *zynqmp_pinctrl_get_group_name(struct udevice *dev,
593 unsigned int selector)
595 struct zynqmp_pinctrl_priv *priv = dev_get_priv(dev);
597 return priv->groups[selector].name;
600 static const struct pinconf_param zynqmp_conf_params[] = {
601 { "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 },
602 { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
603 { "bias-high-impedance", PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0 },
604 { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
605 { "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 },
606 { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
607 { "drive-open-drain", PIN_CONFIG_DRIVE_OPEN_DRAIN, 0 },
608 { "drive-open-source", PIN_CONFIG_DRIVE_OPEN_SOURCE, 0 },
609 { "drive-push-pull", PIN_CONFIG_DRIVE_PUSH_PULL, 0 },
610 { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
611 { "drive-strength-microamp", PIN_CONFIG_DRIVE_STRENGTH_UA, 0 },
612 { "input-debounce", PIN_CONFIG_INPUT_DEBOUNCE, 0 },
613 { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
614 { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
615 { "input-schmitt", PIN_CONFIG_INPUT_SCHMITT, 0 },
616 { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
617 { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
618 { "low-power-disable", PIN_CONFIG_LOW_POWER_MODE, 0 },
619 { "low-power-enable", PIN_CONFIG_LOW_POWER_MODE, 1 },
620 { "output-disable", PIN_CONFIG_OUTPUT_ENABLE, 0 },
621 { "output-enable", PIN_CONFIG_OUTPUT_ENABLE, 1 },
622 { "output-high", PIN_CONFIG_OUTPUT, 1, },
623 { "output-low", PIN_CONFIG_OUTPUT, 0, },
624 { "power-source", PIN_CONFIG_POWER_SOURCE, 0 },
625 { "sleep-hardware-state", PIN_CONFIG_SLEEP_HARDWARE_STATE, 0 },
626 { "slew-rate", PIN_CONFIG_SLEW_RATE, 0 },
627 { "skew-delay", PIN_CONFIG_SKEW_DELAY, 0 },
628 /* zynqmp specific */
629 {"io-standard", PIN_CFG_IOSTANDARD, IO_STANDARD_LVCMOS18},
630 {"schmitt-cmos", PIN_CONFIG_SCHMITTCMOS, PM_PINCTRL_INPUT_TYPE_SCHMITT},
633 static struct pinctrl_ops zynqmp_pinctrl_ops = {
634 .get_pins_count = zynqmp_pinctrl_get_pins_count,
635 .get_pin_name = zynqmp_pinctrl_get_pin_name,
636 .get_pin_muxing = zynqmp_pinctrl_get_pin_muxing,
637 .set_state = pinctrl_generic_set_state,
638 .get_groups_count = zynqmp_pinctrl_get_groups_count,
639 .get_group_name = zynqmp_pinctrl_get_group_name,
640 .get_functions_count = zynqmp_pinctrl_get_functions_count,
641 .get_function_name = zynqmp_pinctrl_get_function_name,
642 .pinmux_group_set = zynqmp_pinmux_group_set,
643 .pinmux_set = zynqmp_pinmux_set,
644 .pinconf_params = zynqmp_conf_params,
645 .pinconf_group_set = zynqmp_pinconf_group_set,
646 .pinconf_set = zynqmp_pinconf_set,
647 .pinconf_num_params = ARRAY_SIZE(zynqmp_conf_params),
650 static const struct udevice_id zynqmp_pinctrl_ids[] = {
651 { .compatible = "xlnx,zynqmp-pinctrl" },
655 U_BOOT_DRIVER(pinctrl_zynqmp) = {
656 .name = "zynqmp-pinctrl",
657 .id = UCLASS_PINCTRL,
658 .of_match = zynqmp_pinctrl_ids,
659 .priv_auto = sizeof(struct zynqmp_pinctrl_priv),
660 .ops = &zynqmp_pinctrl_ops,
661 .probe = zynqmp_pinctrl_probe,