blob: 517035961dabeff7ce65189079781ae5ca66226e [file] [log] [blame]
Ashok Reddy Soma52a32812022-02-23 15:23:05 +01001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Xilinx pinctrl driver for ZynqMP
4 *
5 * Author(s): Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
Michal Simeka8c94362023-07-10 14:35:49 +02006 * Michal Simek <michal.simek@amd.com>
Ashok Reddy Soma52a32812022-02-23 15:23:05 +01007 *
8 * Copyright (C) 2021 Xilinx, Inc. All rights reserved.
9 */
10
11#include <common.h>
12#include <dm.h>
13#include <errno.h>
14#include <malloc.h>
15#include <zynqmp_firmware.h>
16#include <asm/arch/sys_proto.h>
17#include <asm/io.h>
18#include <dm/device_compat.h>
19#include <dm/pinctrl.h>
20#include <linux/compat.h>
21#include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
22
23#define PINCTRL_GET_FUNC_GROUPS_RESP_LEN 12
24#define PINCTRL_GET_PIN_GROUPS_RESP_LEN 12
25#define NUM_GROUPS_PER_RESP 6
26#define NA_GROUP -1
27#define RESERVED_GROUP -2
28#define MAX_GROUP_PIN 50
29#define MAX_PIN_GROUPS 50
30#define MAX_GROUP_NAME_LEN 32
31#define MAX_FUNC_NAME_LEN 16
32
33#define DRIVE_STRENGTH_2MA 2
34#define DRIVE_STRENGTH_4MA 4
35#define DRIVE_STRENGTH_8MA 8
36#define DRIVE_STRENGTH_12MA 12
37
38/*
39 * This driver works with very simple configuration that has the same name
40 * for group and function. This way it is compatible with the Linux Kernel
41 * driver.
42 */
43struct zynqmp_pinctrl_priv {
44 u32 npins;
45 u32 nfuncs;
46 u32 ngroups;
47 struct zynqmp_pmux_function *funcs;
48 struct zynqmp_pctrl_group *groups;
49};
50
51/**
52 * struct zynqmp_pinctrl_config - pinconfig parameters
53 * @slew: Slew rate slow or fast
54 * @bias: Bias enabled or disabled
55 * @pull_ctrl: Pull control pull up or pull down
56 * @input_type: CMOS or Schmitt
57 * @drive_strength: Drive strength 2mA/4mA/8mA/12mA
58 * @volt_sts: Voltage status 1.8V or 3.3V
59 * @tri_state: Tristate enabled or disabled
60 *
61 * This structure holds information about pin control config
62 * option that can be set for each pin.
63 */
64struct zynqmp_pinctrl_config {
65 u32 slew;
66 u32 bias;
67 u32 pull_ctrl;
68 u32 input_type;
69 u32 drive_strength;
70 u32 volt_sts;
71 u32 tri_state;
72};
73
74/**
75 * enum zynqmp_pin_config_param - possible pin configuration parameters
Tom Rini364d0022023-01-10 11:19:45 -050076 * @PIN_CFG_IOSTANDARD: if the pin can select an IO standard,
Ashok Reddy Soma52a32812022-02-23 15:23:05 +010077 * the argument to this parameter (on a
78 * custom format) tells the driver which
79 * alternative IO standard to use
80 * @PIN_CONFIG_SCHMITTCMOS: this parameter (on a custom format) allows
81 * to select schmitt or cmos input for MIO pins
82 */
83enum zynqmp_pin_config_param {
Tom Rini364d0022023-01-10 11:19:45 -050084 PIN_CFG_IOSTANDARD = PIN_CONFIG_END + 1,
Ashok Reddy Soma52a32812022-02-23 15:23:05 +010085 PIN_CONFIG_SCHMITTCMOS,
86};
87
88/**
89 * struct zynqmp_pmux_function - a pinmux function
90 * @name: Name of the pinmux function
91 * @groups: List of pingroups for this function
92 * @ngroups: Number of entries in @groups
93 *
94 * This structure holds information about pin control function
95 * and function group names supporting that function.
96 */
97struct zynqmp_pmux_function {
98 char name[MAX_FUNC_NAME_LEN];
99 const char * const *groups;
100 unsigned int ngroups;
101};
102
103/**
104 * struct zynqmp_pctrl_group - Pin control group info
105 * @name: Group name
106 * @pins: Group pin numbers
107 * @npins: Number of pins in group
108 */
109struct zynqmp_pctrl_group {
110 const char *name;
111 unsigned int pins[MAX_GROUP_PIN];
112 unsigned int npins;
113};
114
115static char pin_name[PINNAME_SIZE];
116
117/**
118 * zynqmp_pm_query_data() - Get query data from firmware
119 * @qid: Value of enum pm_query_id
120 * @arg1: Argument 1
121 * @arg2: Argument 2
122 * @out: Returned output value
123 *
124 * Return: Returns status, either success or error+reason
125 */
126static int zynqmp_pm_query_data(enum pm_query_id qid, u32 arg1, u32 arg2, u32 *out)
127{
128 int ret;
129 u32 ret_payload[PAYLOAD_ARG_CNT];
130
131 ret = xilinx_pm_request(PM_QUERY_DATA, qid, arg1, arg2, 0, ret_payload);
132 if (ret)
133 return ret;
134
135 *out = ret_payload[1];
136
137 return ret;
138}
139
140static int zynqmp_pm_pinctrl_get_config(const u32 pin, const u32 param, u32 *value)
141{
142 int ret;
143 u32 ret_payload[PAYLOAD_ARG_CNT];
144
145 /* Get config for the pin */
146 ret = xilinx_pm_request(PM_PINCTRL_CONFIG_PARAM_GET, pin, param, 0, 0, ret_payload);
147 if (ret) {
148 printf("%s failed\n", __func__);
149 return ret;
150 }
151
152 *value = ret_payload[1];
153
154 return ret;
155}
156
157static int zynqmp_pm_pinctrl_set_config(const u32 pin, const u32 param, u32 value)
158{
159 int ret;
160
Ashok Reddy Soma346a24e2023-08-10 23:48:28 -0600161 if (param == PM_PINCTRL_CONFIG_TRI_STATE) {
162 ret = zynqmp_pm_feature(PM_PINCTRL_CONFIG_PARAM_SET);
163 if (ret < PM_PINCTRL_PARAM_SET_VERSION)
164 return -EOPNOTSUPP;
165 }
166
Ashok Reddy Soma52a32812022-02-23 15:23:05 +0100167 /* Request the pin first */
168 ret = xilinx_pm_request(PM_PINCTRL_REQUEST, pin, 0, 0, 0, NULL);
169 if (ret) {
170 printf("%s: pin request failed\n", __func__);
171 return ret;
172 }
173
174 /* Set config for the pin */
175 ret = xilinx_pm_request(PM_PINCTRL_CONFIG_PARAM_SET, pin, param, value, 0, NULL);
176 if (ret) {
177 printf("%s failed\n", __func__);
178 return ret;
179 }
180
181 return ret;
182}
183
184static int zynqmp_pinctrl_get_function_groups(u32 fid, u32 index, u16 *groups)
185{
186 int ret;
187 u32 ret_payload[PAYLOAD_ARG_CNT];
188
189 ret = xilinx_pm_request(PM_QUERY_DATA, PM_QID_PINCTRL_GET_FUNCTION_GROUPS,
190 fid, index, 0, ret_payload);
191 if (ret) {
192 printf("%s failed\n", __func__);
193 return ret;
194 }
195
196 memcpy(groups, &ret_payload[1], PINCTRL_GET_FUNC_GROUPS_RESP_LEN);
197
198 return ret;
199}
200
201static int zynqmp_pinctrl_prepare_func_groups(u32 fid,
202 struct zynqmp_pmux_function *func,
203 struct zynqmp_pctrl_group *groups)
204{
205 const char **fgroups;
206 char name[MAX_GROUP_NAME_LEN];
207 u16 resp[NUM_GROUPS_PER_RESP] = {0};
208 int ret, index, i;
209
210 fgroups = kcalloc(func->ngroups, sizeof(*fgroups), GFP_KERNEL);
211 if (!fgroups)
212 return -ENOMEM;
213
214 for (index = 0; index < func->ngroups; index += NUM_GROUPS_PER_RESP) {
215 ret = zynqmp_pinctrl_get_function_groups(fid, index, resp);
216 if (ret)
217 return ret;
218
219 for (i = 0; i < NUM_GROUPS_PER_RESP; i++) {
220 if (resp[i] == (u16)NA_GROUP)
221 goto done;
222 if (resp[i] == (u16)RESERVED_GROUP)
223 continue;
224
225 snprintf(name, MAX_GROUP_NAME_LEN, "%s_%d_grp",
226 func->name, index + i);
227 fgroups[index + i] = strdup(name);
228
229 snprintf(name, MAX_GROUP_NAME_LEN, "%s_%d_grp",
230 func->name, index + i);
231 groups[resp[i]].name = strdup(name);
232 }
233 }
234done:
235 func->groups = fgroups;
236
237 return ret;
238}
239
240static int zynqmp_pinctrl_get_pin_groups(u32 pin, u32 index, u16 *groups)
241{
242 int ret;
243 u32 ret_payload[PAYLOAD_ARG_CNT];
244
245 ret = xilinx_pm_request(PM_QUERY_DATA, PM_QID_PINCTRL_GET_PIN_GROUPS,
246 pin, index, 0, ret_payload);
247 if (ret) {
248 printf("%s failed to get pin groups\n", __func__);
249 return ret;
250 }
251
252 memcpy(groups, &ret_payload[1], PINCTRL_GET_PIN_GROUPS_RESP_LEN);
253
254 return ret;
255}
256
257static void zynqmp_pinctrl_group_add_pin(struct zynqmp_pctrl_group *group,
258 unsigned int pin)
259{
260 group->pins[group->npins++] = pin;
261}
262
263static int zynqmp_pinctrl_create_pin_groups(struct zynqmp_pctrl_group *groups,
264 unsigned int pin)
265{
266 u16 resp[NUM_GROUPS_PER_RESP] = {0};
267 int ret, i, index = 0;
268
269 do {
270 ret = zynqmp_pinctrl_get_pin_groups(pin, index, resp);
271 if (ret)
272 return ret;
273
274 for (i = 0; i < NUM_GROUPS_PER_RESP; i++) {
275 if (resp[i] == (u16)NA_GROUP)
276 goto done;
277 if (resp[i] == (u16)RESERVED_GROUP)
278 continue;
279 zynqmp_pinctrl_group_add_pin(&groups[resp[i]], pin);
280 }
281 index += NUM_GROUPS_PER_RESP;
282 } while (index <= MAX_PIN_GROUPS);
283
284done:
285 return ret;
286}
287
288static int zynqmp_pinctrl_probe(struct udevice *dev)
289{
290 struct zynqmp_pinctrl_priv *priv = dev_get_priv(dev);
291 int ret, i;
292 u32 pin;
293 u32 ret_payload[PAYLOAD_ARG_CNT];
294
295 /* Get number of pins first */
296 ret = zynqmp_pm_query_data(PM_QID_PINCTRL_GET_NUM_PINS, 0, 0, &priv->npins);
297 if (ret) {
298 printf("%s failed to get no of pins\n", __func__);
299 return ret;
300 }
301
302 /* Get number of functions available */
303 ret = zynqmp_pm_query_data(PM_QID_PINCTRL_GET_NUM_FUNCTIONS, 0, 0, &priv->nfuncs);
304 if (ret) {
305 printf("%s failed to get no of functions\n", __func__);
306 return ret;
307 }
308
309 /* Allocating structures for functions and its groups */
310 priv->funcs = kzalloc(sizeof(*priv->funcs) * priv->nfuncs, GFP_KERNEL);
311 if (!priv->funcs)
312 return -ENOMEM;
313
314 for (i = 0; i < priv->nfuncs; i++) {
315 /* Get function name for the function and fill */
316 xilinx_pm_request(PM_QUERY_DATA, PM_QID_PINCTRL_GET_FUNCTION_NAME,
317 i, 0, 0, ret_payload);
318
319 memcpy((void *)priv->funcs[i].name, ret_payload, MAX_FUNC_NAME_LEN);
320
321 /* And fill number of groups available for certain function */
322 xilinx_pm_request(PM_QUERY_DATA, PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS,
323 i, 0, 0, ret_payload);
324
325 priv->funcs[i].ngroups = ret_payload[1];
326 priv->ngroups += priv->funcs[i].ngroups;
327 }
328
329 /* Prepare all groups */
330 priv->groups = kzalloc(sizeof(*priv->groups) * priv->ngroups,
331 GFP_KERNEL);
332 if (!priv->groups)
333 return -ENOMEM;
334
335 for (i = 0; i < priv->nfuncs; i++) {
336 ret = zynqmp_pinctrl_prepare_func_groups(i, &priv->funcs[i],
337 priv->groups);
338 if (ret) {
339 printf("Failed to prepare_func_groups\n");
340 return ret;
341 }
342 }
343
344 for (pin = 0; pin < priv->npins; pin++) {
345 ret = zynqmp_pinctrl_create_pin_groups(priv->groups, pin);
346 if (ret)
347 return ret;
348 }
349
350 return 0;
351}
352
353static int zynqmp_pinctrl_get_functions_count(struct udevice *dev)
354{
355 struct zynqmp_pinctrl_priv *priv = dev_get_priv(dev);
356
357 return priv->nfuncs;
358}
359
360static const char *zynqmp_pinctrl_get_function_name(struct udevice *dev,
361 unsigned int selector)
362{
363 struct zynqmp_pinctrl_priv *priv = dev_get_priv(dev);
364
365 return priv->funcs[selector].name;
366}
367
368static int zynqmp_pinmux_set(struct udevice *dev, unsigned int selector,
369 unsigned int func_selector)
370{
371 int ret;
372
373 /* Request the pin first */
374 ret = xilinx_pm_request(PM_PINCTRL_REQUEST, selector, 0, 0, 0, NULL);
375 if (ret) {
376 printf("%s: pin request failed\n", __func__);
377 return ret;
378 }
379
380 /* Set the pin function */
381 ret = xilinx_pm_request(PM_PINCTRL_SET_FUNCTION, selector, func_selector,
382 0, 0, NULL);
383 if (ret) {
384 printf("%s: Failed to set pinmux function\n", __func__);
385 return ret;
386 }
387
388 return 0;
389}
390
391static int zynqmp_pinmux_group_set(struct udevice *dev, unsigned int selector,
392 unsigned int func_selector)
393{
394 int i;
395 struct zynqmp_pinctrl_priv *priv = dev_get_priv(dev);
396 const struct zynqmp_pctrl_group *pgrp = &priv->groups[selector];
397
398 for (i = 0; i < pgrp->npins; i++)
399 zynqmp_pinmux_set(dev, pgrp->pins[i], func_selector);
400
401 return 0;
402}
403
404static int zynqmp_pinconf_set(struct udevice *dev, unsigned int pin,
405 unsigned int param, unsigned int arg)
406{
407 int ret = 0;
408 unsigned int value;
409
410 switch (param) {
411 case PIN_CONFIG_SLEW_RATE:
412 param = PM_PINCTRL_CONFIG_SLEW_RATE;
413 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);
414 break;
415 case PIN_CONFIG_BIAS_PULL_UP:
416 param = PM_PINCTRL_CONFIG_PULL_CTRL;
417 arg = PM_PINCTRL_BIAS_PULL_UP;
418 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);
419 break;
420 case PIN_CONFIG_BIAS_PULL_DOWN:
421 param = PM_PINCTRL_CONFIG_PULL_CTRL;
422 arg = PM_PINCTRL_BIAS_PULL_DOWN;
423 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);
424 break;
425 case PIN_CONFIG_BIAS_DISABLE:
426 param = PM_PINCTRL_CONFIG_BIAS_STATUS;
427 arg = PM_PINCTRL_BIAS_DISABLE;
428 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);
429 break;
430 case PIN_CONFIG_SCHMITTCMOS:
431 param = PM_PINCTRL_CONFIG_SCHMITT_CMOS;
432 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);
433 break;
434 case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
435 param = PM_PINCTRL_CONFIG_SCHMITT_CMOS;
436 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);
437 break;
438 case PIN_CONFIG_DRIVE_STRENGTH:
439 switch (arg) {
440 case DRIVE_STRENGTH_2MA:
441 value = PM_PINCTRL_DRIVE_STRENGTH_2MA;
442 break;
443 case DRIVE_STRENGTH_4MA:
444 value = PM_PINCTRL_DRIVE_STRENGTH_4MA;
445 break;
446 case DRIVE_STRENGTH_8MA:
447 value = PM_PINCTRL_DRIVE_STRENGTH_8MA;
448 break;
449 case DRIVE_STRENGTH_12MA:
450 value = PM_PINCTRL_DRIVE_STRENGTH_12MA;
451 break;
452 default:
453 /* Invalid drive strength */
454 dev_warn(dev, "Invalid drive strength for pin %d\n", pin);
455 return -EINVAL;
456 }
457
458 param = PM_PINCTRL_CONFIG_DRIVE_STRENGTH;
459 ret = zynqmp_pm_pinctrl_set_config(pin, param, value);
460 break;
Tom Rini364d0022023-01-10 11:19:45 -0500461 case PIN_CFG_IOSTANDARD:
Ashok Reddy Soma52a32812022-02-23 15:23:05 +0100462 param = PM_PINCTRL_CONFIG_VOLTAGE_STATUS;
463 ret = zynqmp_pm_pinctrl_get_config(pin, param, &value);
464 if (arg != value)
465 dev_warn(dev, "Invalid IO Standard requested for pin %d\n",
466 pin);
467 break;
468 case PIN_CONFIG_POWER_SOURCE:
469 param = PM_PINCTRL_CONFIG_VOLTAGE_STATUS;
470 ret = zynqmp_pm_pinctrl_get_config(pin, param, &value);
471 if (arg != value)
472 dev_warn(dev, "Invalid IO Standard requested for pin %d\n",
473 pin);
474 break;
475 case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
Ashok Reddy Soma0bd27532023-08-10 23:48:29 -0600476 param = PM_PINCTRL_CONFIG_TRI_STATE;
477 arg = PM_PINCTRL_TRI_STATE_ENABLE;
478 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);
479 break;
Ashok Reddy Soma52a32812022-02-23 15:23:05 +0100480 case PIN_CONFIG_LOW_POWER_MODE:
481 /*
482 * This cases are mentioned in dts but configurable
483 * registers are unknown. So falling through to ignore
484 * boot time warnings as of now.
485 */
486 ret = 0;
487 break;
Ashok Reddy Soma0bd27532023-08-10 23:48:29 -0600488 case PIN_CONFIG_OUTPUT_ENABLE:
489 param = PM_PINCTRL_CONFIG_TRI_STATE;
490 arg = PM_PINCTRL_TRI_STATE_DISABLE;
491 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);
492 break;
Ashok Reddy Soma52a32812022-02-23 15:23:05 +0100493 default:
494 dev_warn(dev, "unsupported configuration parameter '%u'\n",
495 param);
496 ret = -ENOTSUPP;
497 break;
498 }
499
500 return ret;
501}
502
503static int zynqmp_pinconf_group_set(struct udevice *dev,
504 unsigned int group_selector,
505 unsigned int param, unsigned int arg)
506{
507 int i;
508 struct zynqmp_pinctrl_priv *priv = dev_get_priv(dev);
509 const struct zynqmp_pctrl_group *pgrp = &priv->groups[group_selector];
510
511 for (i = 0; i < pgrp->npins; i++)
512 zynqmp_pinconf_set(dev, pgrp->pins[i], param, arg);
513
514 return 0;
515}
516
517static int zynqmp_pinctrl_get_pins_count(struct udevice *dev)
518{
519 struct zynqmp_pinctrl_priv *priv = dev_get_priv(dev);
520
521 return priv->npins;
522}
523
524static const char *zynqmp_pinctrl_get_pin_name(struct udevice *dev,
525 unsigned int selector)
526{
527 snprintf(pin_name, PINNAME_SIZE, "MIO%d", selector);
528
529 return pin_name;
530}
531
532static int zynqmp_pinctrl_get_pin_muxing(struct udevice *dev,
533 unsigned int selector,
534 char *buf,
535 int size)
536{
537 struct zynqmp_pinctrl_config pinmux;
538
539 zynqmp_pm_pinctrl_get_config(selector, PM_PINCTRL_CONFIG_SLEW_RATE,
540 &pinmux.slew);
541 zynqmp_pm_pinctrl_get_config(selector, PM_PINCTRL_CONFIG_BIAS_STATUS,
542 &pinmux.bias);
543 zynqmp_pm_pinctrl_get_config(selector, PM_PINCTRL_CONFIG_PULL_CTRL,
544 &pinmux.pull_ctrl);
545 zynqmp_pm_pinctrl_get_config(selector, PM_PINCTRL_CONFIG_SCHMITT_CMOS,
546 &pinmux.input_type);
547 zynqmp_pm_pinctrl_get_config(selector, PM_PINCTRL_CONFIG_DRIVE_STRENGTH,
548 &pinmux.drive_strength);
549 zynqmp_pm_pinctrl_get_config(selector, PM_PINCTRL_CONFIG_VOLTAGE_STATUS,
550 &pinmux.volt_sts);
551
552 switch (pinmux.drive_strength) {
553 case PM_PINCTRL_DRIVE_STRENGTH_2MA:
554 pinmux.drive_strength = DRIVE_STRENGTH_2MA;
555 break;
556 case PM_PINCTRL_DRIVE_STRENGTH_4MA:
557 pinmux.drive_strength = DRIVE_STRENGTH_4MA;
558 break;
559 case PM_PINCTRL_DRIVE_STRENGTH_8MA:
560 pinmux.drive_strength = DRIVE_STRENGTH_8MA;
561 break;
562 case PM_PINCTRL_DRIVE_STRENGTH_12MA:
563 pinmux.drive_strength = DRIVE_STRENGTH_12MA;
564 break;
565 default:
566 /* Invalid drive strength */
567 dev_warn(dev, "Invalid drive strength\n");
568 return -EINVAL;
569 }
570
571 snprintf(buf, size, "slew:%s\tbias:%s\tpull:%s\tinput:%s\tdrive:%dmA\tvolt:%s",
572 pinmux.slew ? "slow" : "fast",
573 pinmux.bias ? "enabled" : "disabled",
574 pinmux.pull_ctrl ? "up" : "down",
575 pinmux.input_type ? "schmitt" : "cmos",
576 pinmux.drive_strength,
577 pinmux.volt_sts ? "1.8" : "3.3");
578
579 return 0;
580}
581
582static int zynqmp_pinctrl_get_groups_count(struct udevice *dev)
583{
584 struct zynqmp_pinctrl_priv *priv = dev_get_priv(dev);
585
586 return priv->ngroups;
587}
588
589static const char *zynqmp_pinctrl_get_group_name(struct udevice *dev,
590 unsigned int selector)
591{
592 struct zynqmp_pinctrl_priv *priv = dev_get_priv(dev);
593
594 return priv->groups[selector].name;
595}
596
597static const struct pinconf_param zynqmp_conf_params[] = {
598 { "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 },
599 { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
600 { "bias-high-impedance", PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0 },
601 { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
602 { "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 },
603 { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
604 { "drive-open-drain", PIN_CONFIG_DRIVE_OPEN_DRAIN, 0 },
605 { "drive-open-source", PIN_CONFIG_DRIVE_OPEN_SOURCE, 0 },
606 { "drive-push-pull", PIN_CONFIG_DRIVE_PUSH_PULL, 0 },
607 { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
608 { "drive-strength-microamp", PIN_CONFIG_DRIVE_STRENGTH_UA, 0 },
609 { "input-debounce", PIN_CONFIG_INPUT_DEBOUNCE, 0 },
610 { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
611 { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
612 { "input-schmitt", PIN_CONFIG_INPUT_SCHMITT, 0 },
613 { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
614 { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
615 { "low-power-disable", PIN_CONFIG_LOW_POWER_MODE, 0 },
616 { "low-power-enable", PIN_CONFIG_LOW_POWER_MODE, 1 },
617 { "output-disable", PIN_CONFIG_OUTPUT_ENABLE, 0 },
618 { "output-enable", PIN_CONFIG_OUTPUT_ENABLE, 1 },
619 { "output-high", PIN_CONFIG_OUTPUT, 1, },
620 { "output-low", PIN_CONFIG_OUTPUT, 0, },
621 { "power-source", PIN_CONFIG_POWER_SOURCE, 0 },
622 { "sleep-hardware-state", PIN_CONFIG_SLEEP_HARDWARE_STATE, 0 },
623 { "slew-rate", PIN_CONFIG_SLEW_RATE, 0 },
624 { "skew-delay", PIN_CONFIG_SKEW_DELAY, 0 },
625 /* zynqmp specific */
Tom Rini364d0022023-01-10 11:19:45 -0500626 {"io-standard", PIN_CFG_IOSTANDARD, IO_STANDARD_LVCMOS18},
Ashok Reddy Soma52a32812022-02-23 15:23:05 +0100627 {"schmitt-cmos", PIN_CONFIG_SCHMITTCMOS, PM_PINCTRL_INPUT_TYPE_SCHMITT},
628};
629
630static struct pinctrl_ops zynqmp_pinctrl_ops = {
631 .get_pins_count = zynqmp_pinctrl_get_pins_count,
632 .get_pin_name = zynqmp_pinctrl_get_pin_name,
633 .get_pin_muxing = zynqmp_pinctrl_get_pin_muxing,
634 .set_state = pinctrl_generic_set_state,
635 .get_groups_count = zynqmp_pinctrl_get_groups_count,
636 .get_group_name = zynqmp_pinctrl_get_group_name,
637 .get_functions_count = zynqmp_pinctrl_get_functions_count,
638 .get_function_name = zynqmp_pinctrl_get_function_name,
639 .pinmux_group_set = zynqmp_pinmux_group_set,
640 .pinmux_set = zynqmp_pinmux_set,
641 .pinconf_params = zynqmp_conf_params,
642 .pinconf_group_set = zynqmp_pinconf_group_set,
643 .pinconf_set = zynqmp_pinconf_set,
644 .pinconf_num_params = ARRAY_SIZE(zynqmp_conf_params),
645};
646
647static const struct udevice_id zynqmp_pinctrl_ids[] = {
648 { .compatible = "xlnx,zynqmp-pinctrl" },
649 { }
650};
651
652U_BOOT_DRIVER(pinctrl_zynqmp) = {
653 .name = "zynqmp-pinctrl",
654 .id = UCLASS_PINCTRL,
655 .of_match = zynqmp_pinctrl_ids,
656 .priv_auto = sizeof(struct zynqmp_pinctrl_priv),
657 .ops = &zynqmp_pinctrl_ops,
658 .probe = zynqmp_pinctrl_probe,
659};