Alexey Minnekhanov | 791dea8 | 2025-03-31 18:55:31 +0300 | [diff] [blame^] | 1 | // SPDX-License-Identifier: GPL-2.0+ |
| 2 | /* |
| 3 | * Qualcomm SDM630/660 TLMM pinctrl |
| 4 | * |
| 5 | */ |
| 6 | |
| 7 | #include <dm.h> |
| 8 | #include "pinctrl-qcom.h" |
| 9 | |
| 10 | #define TLMM_BASE 0x03100000 |
| 11 | #define SOUTH (0x03100000 - TLMM_BASE) /* 0x0 */ |
| 12 | #define CENTER (0x03500000 - TLMM_BASE) /* 0x400000 */ |
| 13 | #define NORTH (0x03900000 - TLMM_BASE) /* 0x800000 */ |
| 14 | |
| 15 | #define MAX_PIN_NAME_LEN 32 |
| 16 | static char pin_name[MAX_PIN_NAME_LEN] __section(".data"); |
| 17 | |
| 18 | static const struct pinctrl_function sdm660_pinctrl_functions[] = { |
| 19 | { "gpio", 0 }, |
| 20 | { "blsp_uart2", 3 }, /* gpio 4 and 5, used for debug uart */ |
| 21 | }; |
| 22 | |
| 23 | static const unsigned int sdm660_pin_offsets[] = { |
| 24 | [0] = SOUTH, |
| 25 | [1] = SOUTH, |
| 26 | [2] = SOUTH, |
| 27 | [3] = SOUTH, |
| 28 | [4] = NORTH, |
| 29 | [5] = SOUTH, |
| 30 | [6] = SOUTH, |
| 31 | [7] = SOUTH, |
| 32 | [8] = NORTH, |
| 33 | [9] = NORTH, |
| 34 | [10] = NORTH, |
| 35 | [11] = NORTH, |
| 36 | [12] = NORTH, |
| 37 | [13] = NORTH, |
| 38 | [14] = NORTH, |
| 39 | [15] = NORTH, |
| 40 | [16] = CENTER, |
| 41 | [17] = CENTER, |
| 42 | [18] = CENTER, |
| 43 | [19] = CENTER, |
| 44 | [20] = SOUTH, |
| 45 | [21] = SOUTH, |
| 46 | [22] = CENTER, |
| 47 | [23] = CENTER, |
| 48 | [24] = NORTH, |
| 49 | [25] = NORTH, |
| 50 | [26] = NORTH, |
| 51 | [27] = NORTH, |
| 52 | [28] = CENTER, |
| 53 | [29] = CENTER, |
| 54 | [30] = CENTER, |
| 55 | [31] = CENTER, |
| 56 | [32] = SOUTH, |
| 57 | [33] = SOUTH, |
| 58 | [34] = SOUTH, |
| 59 | [35] = SOUTH, |
| 60 | [36] = SOUTH, |
| 61 | [37] = SOUTH, |
| 62 | [38] = SOUTH, |
| 63 | [39] = SOUTH, |
| 64 | [40] = SOUTH, |
| 65 | [41] = SOUTH, |
| 66 | [42] = SOUTH, |
| 67 | [43] = SOUTH, |
| 68 | [44] = SOUTH, |
| 69 | [45] = SOUTH, |
| 70 | [46] = SOUTH, |
| 71 | [47] = SOUTH, |
| 72 | [48] = SOUTH, |
| 73 | [49] = SOUTH, |
| 74 | [50] = SOUTH, |
| 75 | [51] = SOUTH, |
| 76 | [52] = SOUTH, |
| 77 | [53] = NORTH, |
| 78 | [54] = NORTH, |
| 79 | [55] = SOUTH, |
| 80 | [56] = SOUTH, |
| 81 | [57] = SOUTH, |
| 82 | [58] = SOUTH, |
| 83 | [59] = NORTH, |
| 84 | [60] = NORTH, |
| 85 | [61] = NORTH, |
| 86 | [62] = NORTH, |
| 87 | [63] = NORTH, |
| 88 | [64] = SOUTH, |
| 89 | [65] = SOUTH, |
| 90 | [66] = NORTH, |
| 91 | [67] = NORTH, |
| 92 | [68] = NORTH, |
| 93 | [69] = NORTH, |
| 94 | [70] = NORTH, |
| 95 | [71] = NORTH, |
| 96 | [72] = NORTH, |
| 97 | [73] = NORTH, |
| 98 | [74] = NORTH, |
| 99 | [75] = NORTH, |
| 100 | [76] = NORTH, |
| 101 | [77] = NORTH, |
| 102 | [78] = NORTH, |
| 103 | [79] = SOUTH, |
| 104 | [80] = SOUTH, |
| 105 | [81] = CENTER, |
| 106 | [82] = CENTER, |
| 107 | [83] = SOUTH, |
| 108 | [84] = SOUTH, |
| 109 | [85] = SOUTH, |
| 110 | [86] = SOUTH, |
| 111 | [87] = SOUTH, |
| 112 | [88] = SOUTH, |
| 113 | [89] = SOUTH, |
| 114 | [90] = SOUTH, |
| 115 | [91] = SOUTH, |
| 116 | [92] = SOUTH, |
| 117 | [93] = SOUTH, |
| 118 | [94] = SOUTH, |
| 119 | [95] = SOUTH, |
| 120 | [96] = SOUTH, |
| 121 | [97] = SOUTH, |
| 122 | [98] = SOUTH, |
| 123 | [99] = SOUTH, |
| 124 | [100] = SOUTH, |
| 125 | [101] = SOUTH, |
| 126 | [102] = SOUTH, |
| 127 | [103] = SOUTH, |
| 128 | [104] = SOUTH, |
| 129 | [105] = SOUTH, |
| 130 | [106] = SOUTH, |
| 131 | [107] = SOUTH, |
| 132 | [108] = SOUTH, |
| 133 | [109] = SOUTH, |
| 134 | [110] = SOUTH, |
| 135 | [111] = SOUTH, |
| 136 | [112] = SOUTH, |
| 137 | [113] = SOUTH, |
| 138 | }; |
| 139 | |
| 140 | /* |
| 141 | * Special pins - eMMC/SD related: [114..120], in total 7 special pins |
| 142 | */ |
| 143 | |
| 144 | #define SDC_QDSD_PINGROUP(pg_name, ctl, pull, drv) \ |
| 145 | { \ |
| 146 | .name = pg_name, \ |
| 147 | .ctl_reg = ctl, \ |
| 148 | .io_reg = 0, \ |
| 149 | .pull_bit = pull, \ |
| 150 | .drv_bit = drv, \ |
| 151 | .oe_bit = -1, \ |
| 152 | .in_bit = -1, \ |
| 153 | .out_bit = -1, \ |
| 154 | } |
| 155 | |
| 156 | /* All SDC pins are in the NORTH tile */ |
| 157 | static const struct msm_special_pin_data sdm660_special_pins_data[] = { |
| 158 | SDC_QDSD_PINGROUP("sdc1_clk", NORTH + 0x9a000, 13, 6), |
| 159 | SDC_QDSD_PINGROUP("sdc1_cmd", NORTH + 0x9a000, 11, 3), |
| 160 | SDC_QDSD_PINGROUP("sdc1_data", NORTH + 0x9a000, 9, 0), |
| 161 | SDC_QDSD_PINGROUP("sdc2_clk", NORTH + 0x9b000, 14, 6), |
| 162 | SDC_QDSD_PINGROUP("sdc2_cmd", NORTH + 0x9b000, 11, 3), |
| 163 | SDC_QDSD_PINGROUP("sdc2_data", NORTH + 0x9b000, 9, 0), |
| 164 | SDC_QDSD_PINGROUP("sdc1_rclk", NORTH + 0x9a000, 15, 0), |
| 165 | }; |
| 166 | |
| 167 | static const char *sdm660_get_function_name(struct udevice *dev, unsigned int selector) |
| 168 | { |
| 169 | return sdm660_pinctrl_functions[selector].name; |
| 170 | } |
| 171 | |
| 172 | static const char *sdm660_get_pin_name(struct udevice *dev, unsigned int selector) |
| 173 | { |
| 174 | static const char * const special_pins_names[] = { |
| 175 | "sdc1_clk", "sdc1_cmd", "sdc1_data", |
| 176 | "sdc2_clk", "sdc2_cmd", "sdc2_data", |
| 177 | "sdc1_rclk" |
| 178 | }; |
| 179 | |
| 180 | if (selector >= 114 && selector <= 120) |
| 181 | snprintf(pin_name, MAX_PIN_NAME_LEN, special_pins_names[selector - 114]); |
| 182 | else |
| 183 | snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector); |
| 184 | |
| 185 | return pin_name; |
| 186 | } |
| 187 | |
| 188 | static int sdm660_get_function_mux(__maybe_unused unsigned int pin, unsigned int selector) |
| 189 | { |
| 190 | if (selector >= 0 && selector < ARRAY_SIZE(sdm660_pinctrl_functions)) |
| 191 | return sdm660_pinctrl_functions[selector].val; |
| 192 | return -EINVAL; |
| 193 | } |
| 194 | |
| 195 | struct msm_pinctrl_data sdm660_data = { |
| 196 | .pin_data = { |
| 197 | .pin_offsets = sdm660_pin_offsets, |
| 198 | .pin_count = ARRAY_SIZE(sdm660_pin_offsets) + ARRAY_SIZE(sdm660_special_pins_data), |
| 199 | .special_pins_start = 114, |
| 200 | .special_pins_data = sdm660_special_pins_data, |
| 201 | }, |
| 202 | .functions_count = ARRAY_SIZE(sdm660_pinctrl_functions), |
| 203 | .get_function_name = sdm660_get_function_name, |
| 204 | .get_function_mux = sdm660_get_function_mux, |
| 205 | .get_pin_name = sdm660_get_pin_name, |
| 206 | }; |
| 207 | |
| 208 | static const struct udevice_id msm_pinctrl_ids[] = { |
| 209 | { |
| 210 | .compatible = "qcom,sdm630-pinctrl", |
| 211 | .data = (ulong)&sdm660_data |
| 212 | }, |
| 213 | { |
| 214 | .compatible = "qcom,sdm660-pinctrl", |
| 215 | .data = (ulong)&sdm660_data |
| 216 | }, |
| 217 | { /* Sentinel */ } |
| 218 | }; |
| 219 | |
| 220 | U_BOOT_DRIVER(pinctrl_ssdm660) = { |
| 221 | .name = "pinctrl_sdm660", |
| 222 | .id = UCLASS_NOP, |
| 223 | .of_match = msm_pinctrl_ids, |
| 224 | .ops = &msm_pinctrl_ops, |
| 225 | .bind = msm_pinctrl_bind, |
| 226 | }; |