blob: 036fec93d7272f5f787225cee869cf50a1733286 [file] [log] [blame]
Robert Markoe7a34f12020-07-06 10:37:54 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * TLMM driver for Qualcomm IPQ40xx
4 *
5 * (C) Copyright 2018 Ramon Fried <ramon.fried@gmail.com>
6 *
7 * Copyright (c) 2020 Sartura Ltd.
8 *
9 * Author: Robert Marko <robert.marko@sartura.hr>
10 *
11 */
12
13#include <common.h>
14#include <dm.h>
15#include <errno.h>
16#include <asm/io.h>
Sumit Gargb7572e52022-07-27 13:52:04 +053017#include <dm/device_compat.h>
18#include <dm/lists.h>
Robert Markoe7a34f12020-07-06 10:37:54 +020019#include <dm/pinctrl.h>
20#include <linux/bitops.h>
21#include "pinctrl-snapdragon.h"
22
23struct msm_pinctrl_priv {
24 phys_addr_t base;
25 struct msm_pinctrl_data *data;
26};
27
28#define GPIO_CONFIG_OFFSET(x) ((x) * 0x1000)
29#define TLMM_GPIO_PULL_MASK GENMASK(1, 0)
30#define TLMM_FUNC_SEL_MASK GENMASK(5, 2)
31#define TLMM_DRV_STRENGTH_MASK GENMASK(8, 6)
32#define TLMM_GPIO_DISABLE BIT(9)
33
34static const struct pinconf_param msm_conf_params[] = {
35 { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 2 },
36 { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
37 { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 2 },
38};
39
40static int msm_get_functions_count(struct udevice *dev)
41{
42 struct msm_pinctrl_priv *priv = dev_get_priv(dev);
43
44 return priv->data->functions_count;
45}
46
47static int msm_get_pins_count(struct udevice *dev)
48{
49 struct msm_pinctrl_priv *priv = dev_get_priv(dev);
50
51 return priv->data->pin_count;
52}
53
54static const char *msm_get_function_name(struct udevice *dev,
55 unsigned int selector)
56{
57 struct msm_pinctrl_priv *priv = dev_get_priv(dev);
58
59 return priv->data->get_function_name(dev, selector);
60}
61
62static int msm_pinctrl_probe(struct udevice *dev)
63{
64 struct msm_pinctrl_priv *priv = dev_get_priv(dev);
65
66 priv->base = devfdt_get_addr(dev);
67 priv->data = (struct msm_pinctrl_data *)dev->driver_data;
68
69 return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0;
70}
71
72static const char *msm_get_pin_name(struct udevice *dev, unsigned int selector)
73{
74 struct msm_pinctrl_priv *priv = dev_get_priv(dev);
75
76 return priv->data->get_pin_name(dev, selector);
77}
78
79static int msm_pinmux_set(struct udevice *dev, unsigned int pin_selector,
80 unsigned int func_selector)
81{
82 struct msm_pinctrl_priv *priv = dev_get_priv(dev);
83
84 clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
85 TLMM_FUNC_SEL_MASK | TLMM_GPIO_DISABLE,
86 priv->data->get_function_mux(func_selector) << 2);
87 return 0;
88}
89
90static int msm_pinconf_set(struct udevice *dev, unsigned int pin_selector,
91 unsigned int param, unsigned int argument)
92{
93 struct msm_pinctrl_priv *priv = dev_get_priv(dev);
94
95 switch (param) {
96 case PIN_CONFIG_DRIVE_STRENGTH:
97 clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
98 TLMM_DRV_STRENGTH_MASK, argument << 6);
99 break;
100 case PIN_CONFIG_BIAS_DISABLE:
101 clrbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
102 TLMM_GPIO_PULL_MASK);
103 break;
104 case PIN_CONFIG_BIAS_PULL_UP:
105 clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
106 TLMM_GPIO_PULL_MASK, argument);
107 break;
108 default:
109 return 0;
110 }
111
112 return 0;
113}
114
Sumit Gargb7572e52022-07-27 13:52:04 +0530115static int msm_pinctrl_bind(struct udevice *dev)
116{
117 ofnode node = dev_ofnode(dev);
118 const char *name;
119 int ret;
120
121 ofnode_get_property(node, "gpio-controller", &ret);
122 if (ret < 0)
123 return 0;
124
125 /* Get the name of gpio node */
126 name = ofnode_get_name(node);
127 if (!name)
128 return -EINVAL;
129
130 /* Bind gpio node */
131 ret = device_bind_driver_to_node(dev, "gpio_msm",
132 name, node, NULL);
133 if (ret)
134 return ret;
135
136 dev_dbg(dev, "bind %s\n", name);
137
138 return 0;
139}
140
Robert Markoe7a34f12020-07-06 10:37:54 +0200141static struct pinctrl_ops msm_pinctrl_ops = {
142 .get_pins_count = msm_get_pins_count,
143 .get_pin_name = msm_get_pin_name,
144 .set_state = pinctrl_generic_set_state,
145 .pinmux_set = msm_pinmux_set,
146 .pinconf_num_params = ARRAY_SIZE(msm_conf_params),
147 .pinconf_params = msm_conf_params,
148 .pinconf_set = msm_pinconf_set,
149 .get_functions_count = msm_get_functions_count,
150 .get_function_name = msm_get_function_name,
151};
152
153static const struct udevice_id msm_pinctrl_ids[] = {
Sumit Gargb7572e52022-07-27 13:52:04 +0530154 { .compatible = "qcom,ipq4019-pinctrl", .data = (ulong)&ipq4019_data },
Robert Markoe7a34f12020-07-06 10:37:54 +0200155 { }
156};
157
158U_BOOT_DRIVER(pinctrl_snapdraon) = {
159 .name = "pinctrl_msm",
160 .id = UCLASS_PINCTRL,
161 .of_match = msm_pinctrl_ids,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700162 .priv_auto = sizeof(struct msm_pinctrl_priv),
Robert Markoe7a34f12020-07-06 10:37:54 +0200163 .ops = &msm_pinctrl_ops,
164 .probe = msm_pinctrl_probe,
Sumit Gargb7572e52022-07-27 13:52:04 +0530165 .bind = msm_pinctrl_bind,
Robert Markoe7a34f12020-07-06 10:37:54 +0200166};