1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Qualcomm sc7280 pinctrl
4  *
5  * (C) Copyright 2024 Linaro Ltd.
6  *
7  */
8 
9 #include <dm.h>
10 
11 #include "pinctrl-qcom.h"
12 
13 #define WEST 0x00000000
14 #define SOUTH 0x00400000
15 #define NORTH 0x00800000
16 
17 #define MAX_PIN_NAME_LEN 32
18 static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
19 
20 static const struct pinctrl_function msm_pinctrl_functions[] = {
21 	{ "qup05", 1 },
22 	{ "gpio", 0 },
23 	{ "pcie1_clkreqn", 3},
24 };
25 #define SDC_PINGROUP(pg_name, ctl, pull, drv)		\
26 	{						\
27 		.name = pg_name,			\
28 		.ctl_reg = ctl,				\
29 		.io_reg = 0,				\
30 		.pull_bit = pull,			\
31 		.drv_bit = drv,				\
32 		.oe_bit = -1,				\
33 		.in_bit = -1,				\
34 		.out_bit = -1,				\
35 	}
36 
37 #define UFS_RESET(pg_name, offset)			\
38 	{						\
39 		.name = pg_name,			\
40 		.ctl_reg = offset,			\
41 		.io_reg = offset + 0x4,			\
42 		.pull_bit = 3,				\
43 		.drv_bit = 0,				\
44 		.oe_bit = -1,				\
45 		.in_bit = -1,				\
46 		.out_bit = 0,				\
47 	}
48 
49 static const struct msm_special_pin_data sc7280_special_pins_data[] = {
50 	[0] = UFS_RESET("ufs_reset", SOUTH + 0xbe000),
51 	[1] = SDC_PINGROUP("sdc1_rclk", 0xb3004, 0, 6),
52 	[2] = SDC_PINGROUP("sdc1_clk", 0xb3000, 13, 6),
53 	[3] = SDC_PINGROUP("sdc1_cmd", 0xb3000, 11, 3),
54 	[4] = SDC_PINGROUP("sdc1_data", 0xb3000, 9, 0),
55 	[5] = SDC_PINGROUP("sdc2_clk", 0xb4000, 14, 6),
56 	[6] = SDC_PINGROUP("sdc2_cmd", 0xb4000, 11, 3),
57 	[7] = SDC_PINGROUP("sdc2_data", 0xb4000, 9, 0),
58 };
59 
sc7280_get_function_name(struct udevice * dev,unsigned int selector)60 static const char *sc7280_get_function_name(struct udevice *dev, unsigned int selector)
61 {
62 	return msm_pinctrl_functions[selector].name;
63 }
64 
sc7280_get_pin_name(struct udevice * dev,unsigned int selector)65 static const char *sc7280_get_pin_name(struct udevice *dev, unsigned int selector)
66 {
67 	if (selector >= 175 && selector <= 182)
68 		snprintf(pin_name, MAX_PIN_NAME_LEN,
69 			 sc7280_special_pins_data[selector - 175].name);
70 	else
71 		snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
72 
73 	return pin_name;
74 }
75 
sc7280_get_function_mux(__maybe_unused unsigned int pin,unsigned int selector)76 static int sc7280_get_function_mux(__maybe_unused unsigned int pin, unsigned int selector)
77 {
78 	return msm_pinctrl_functions[selector].val;
79 }
80 
81 static struct msm_pinctrl_data sc7280_data = {
82 	.pin_data = {
83 		.pin_count = 183,
84 		.special_pins_start = 175,
85 		.special_pins_data = sc7280_special_pins_data,
86 	},
87 	.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
88 	.get_function_name = sc7280_get_function_name,
89 	.get_function_mux = sc7280_get_function_mux,
90 	.get_pin_name = sc7280_get_pin_name,
91 };
92 
93 static const struct udevice_id msm_pinctrl_ids[] = {
94 	{
95 		.compatible = "qcom,sc7280-pinctrl",
96 		.data = (ulong)&sc7280_data
97 	},
98 	{ /* Sentinel */ } };
99 
100 U_BOOT_DRIVER(pinctrl_sc7280) = {
101 	.name = "pinctrl_sc7280",
102 	.id = UCLASS_NOP,
103 	.of_match = msm_pinctrl_ids,
104 	.ops = &msm_pinctrl_ops,
105 	.bind = msm_pinctrl_bind,
106 };
107