developer | e194781 | 2019-09-25 17:45:26 +0800 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | /* |
| 3 | * Copyright (C) 2019 MediaTek Inc. All Rights Reserved. |
| 4 | * |
| 5 | * Author: Weijie Gao <weijie.gao@mediatek.com> |
| 6 | */ |
| 7 | |
| 8 | #include <common.h> |
| 9 | #include <dm.h> |
Simon Glass | 3ba929a | 2020-10-30 21:38:53 -0600 | [diff] [blame] | 10 | #include <asm/global_data.h> |
developer | e194781 | 2019-09-25 17:45:26 +0800 | [diff] [blame] | 11 | #include <dm/pinctrl.h> |
| 12 | #include <linux/bitops.h> |
| 13 | #include <linux/io.h> |
| 14 | |
| 15 | #include "pinctrl-mtmips-common.h" |
| 16 | |
| 17 | DECLARE_GLOBAL_DATA_PTR; |
| 18 | |
| 19 | #define AGPIO_OFS 0 |
| 20 | #define GPIOMODE1_OFS 0x24 |
| 21 | #define GPIOMODE2_OFS 0x28 |
| 22 | |
| 23 | #define EPHY4_1_PAD_SHIFT 17 |
| 24 | #define EPHY4_1_PAD_MASK 0x0f |
| 25 | #define EPHY0_SHIFT 16 |
| 26 | #define RF_OLT_MODE_SHIFT 12 |
| 27 | #define N9_EINT_SRC_SHIFT 9 |
| 28 | #define WLED_OD_SHIFT 8 |
| 29 | #define REF_CLKO_PAD_SHIFT 4 |
| 30 | #define I2S_CLK_PAD_SHIFT 3 |
| 31 | #define I2S_WS_PAD_SHIFT 2 |
| 32 | #define I2S_SDO_PAD_SHIFT 1 |
| 33 | #define I2S_SDI_PAD_SHIFT 0 |
| 34 | |
| 35 | #define GM4_MASK 3 |
| 36 | |
| 37 | #define P4LED_K_SHIFT 26 |
| 38 | #define P3LED_K_SHIFT 24 |
| 39 | #define P2LED_K_SHIFT 22 |
| 40 | #define P1LED_K_SHIFT 20 |
| 41 | #define P0LED_K_SHIFT 18 |
| 42 | #define WLED_K_SHIFT 16 |
| 43 | #define P4LED_A_SHIFT 10 |
| 44 | #define P3LED_A_SHIFT 8 |
| 45 | #define P2LED_A_SHIFT 6 |
| 46 | #define P1LED_A_SHIFT 4 |
| 47 | #define P0LED_A_SHIFT 2 |
| 48 | #define WLED_A_SHIFT 0 |
| 49 | |
| 50 | #define PWM1_SHIFT 30 |
| 51 | #define PWM0_SHIFT 28 |
| 52 | #define UART2_SHIFT 26 |
| 53 | #define UART1_SHIFT 24 |
| 54 | #define I2C_SHIFT 20 |
| 55 | #define REFCLK_SHIFT 18 |
| 56 | #define PERST_SHIFT 16 |
| 57 | #define ESD_SHIFT 15 |
| 58 | #define WDT_SHIFT 14 |
| 59 | #define SPI_SHIFT 12 |
| 60 | #define SDMODE_SHIFT 10 |
| 61 | #define UART0_SHIFT 8 |
| 62 | #define I2S_SHIFT 6 |
| 63 | #define SPI_CS1_SHIFT 4 |
| 64 | #define SPIS_SHIFT 2 |
| 65 | #define GPIO0_SHIFT 0 |
| 66 | |
| 67 | #define PAD_PU_G0_REG 0x00 |
| 68 | #define PAD_PU_G1_REG 0x04 |
| 69 | #define PAD_PD_G0_REG 0x10 |
| 70 | #define PAD_PD_G1_REG 0x14 |
| 71 | #define PAD_SR_G0_REG 0x20 |
| 72 | #define PAD_SR_G1_REG 0x24 |
| 73 | #define PAD_SMT_G0_REG 0x30 |
| 74 | #define PAD_SMT_G1_REG 0x34 |
| 75 | #define PAD_E2_G0_REG 0x40 |
| 76 | #define PAD_E2_G1_REG 0x44 |
| 77 | #define PAD_E4_G0_REG 0x50 |
| 78 | #define PAD_E4_G1_REG 0x54 |
| 79 | #define PAD_E8_G0_REG 0x60 |
| 80 | #define PAD_E8_G1_REG 0x64 |
| 81 | |
| 82 | #define PIN_CONFIG_DRIVE_STRENGTH_28 (PIN_CONFIG_END + 1) |
| 83 | #define PIN_CONFIG_DRIVE_STRENGTH_4G (PIN_CONFIG_END + 2) |
| 84 | |
| 85 | struct mt7628_pinctrl_priv { |
| 86 | struct mtmips_pinctrl_priv mp; |
| 87 | |
| 88 | void __iomem *pcbase; |
| 89 | }; |
| 90 | |
| 91 | #if CONFIG_IS_ENABLED(PINMUX) |
| 92 | static const struct mtmips_pmx_func ephy4_1_pad_grp[] = { |
| 93 | FUNC("digital", 0xf), |
| 94 | FUNC("analog", 0), |
| 95 | }; |
| 96 | |
| 97 | static const struct mtmips_pmx_func ephy0_grp[] = { |
| 98 | FUNC("disable", 1), |
| 99 | FUNC("enable", 0), |
| 100 | }; |
| 101 | |
| 102 | static const struct mtmips_pmx_func rf_olt_grp[] = { |
| 103 | FUNC("enable", 1), |
| 104 | FUNC("disable", 0), |
| 105 | }; |
| 106 | |
| 107 | static const struct mtmips_pmx_func n9_eint_src_grp[] = { |
| 108 | FUNC("gpio", 1), |
| 109 | FUNC("utif", 0), |
| 110 | }; |
| 111 | |
| 112 | static const struct mtmips_pmx_func wlen_od_grp[] = { |
| 113 | FUNC("enable", 1), |
| 114 | FUNC("disable", 0), |
| 115 | }; |
| 116 | |
| 117 | static const struct mtmips_pmx_func ref_clko_grp[] = { |
| 118 | FUNC("digital", 1), |
| 119 | FUNC("analog", 0), |
| 120 | }; |
| 121 | |
| 122 | static const struct mtmips_pmx_func i2s_clk_grp[] = { |
| 123 | FUNC("digital", 1), |
| 124 | FUNC("analog", 0), |
| 125 | }; |
| 126 | |
| 127 | static const struct mtmips_pmx_func i2s_ws_grp[] = { |
| 128 | FUNC("digital", 1), |
| 129 | FUNC("analog", 0), |
| 130 | }; |
| 131 | |
| 132 | static const struct mtmips_pmx_func i2s_sdo_grp[] = { |
| 133 | FUNC("digital", 1), |
| 134 | FUNC("analog", 0), |
| 135 | }; |
| 136 | |
| 137 | static const struct mtmips_pmx_func i2s_sdi_grp[] = { |
| 138 | FUNC("digital", 1), |
| 139 | FUNC("analog", 0), |
| 140 | }; |
| 141 | |
| 142 | static const struct mtmips_pmx_func pwm1_grp[] = { |
| 143 | FUNC("sdxc d6", 3), |
| 144 | FUNC("utif", 2), |
| 145 | FUNC("gpio", 1), |
| 146 | FUNC("pwm1", 0), |
| 147 | }; |
| 148 | |
| 149 | static const struct mtmips_pmx_func pwm0_grp[] = { |
| 150 | FUNC("sdxc d7", 3), |
| 151 | FUNC("utif", 2), |
| 152 | FUNC("gpio", 1), |
| 153 | FUNC("pwm0", 0), |
| 154 | }; |
| 155 | |
| 156 | static const struct mtmips_pmx_func uart2_grp[] = { |
| 157 | FUNC("sdxc d5 d4", 3), |
| 158 | FUNC("pwm", 2), |
| 159 | FUNC("gpio", 1), |
| 160 | FUNC("uart2", 0), |
| 161 | }; |
| 162 | |
| 163 | static const struct mtmips_pmx_func uart1_grp[] = { |
| 164 | FUNC("sw_r", 3), |
| 165 | FUNC("pwm", 2), |
| 166 | FUNC("gpio", 1), |
| 167 | FUNC("uart1", 0), |
| 168 | }; |
| 169 | |
| 170 | static const struct mtmips_pmx_func i2c_grp[] = { |
| 171 | FUNC("-", 3), |
| 172 | FUNC("debug", 2), |
| 173 | FUNC("gpio", 1), |
| 174 | FUNC("i2c", 0), |
| 175 | }; |
| 176 | |
| 177 | static const struct mtmips_pmx_func refclk_grp[] = { |
| 178 | FUNC("gpio", 1), |
| 179 | FUNC("refclk", 0), |
| 180 | }; |
| 181 | |
| 182 | static const struct mtmips_pmx_func perst_grp[] = { |
| 183 | FUNC("gpio", 1), |
| 184 | FUNC("perst", 0), |
| 185 | }; |
| 186 | |
| 187 | static const struct mtmips_pmx_func esd_grp[] = { |
| 188 | FUNC("router", 1), |
| 189 | FUNC("iot", 0), |
| 190 | }; |
| 191 | |
| 192 | static const struct mtmips_pmx_func wdt_grp[] = { |
| 193 | FUNC("gpio", 1), |
| 194 | FUNC("wdt", 0), |
| 195 | }; |
| 196 | |
| 197 | static const struct mtmips_pmx_func spi_grp[] = { |
| 198 | FUNC("gpio", 1), |
| 199 | FUNC("spi", 0), |
| 200 | }; |
| 201 | |
| 202 | static const struct mtmips_pmx_func sd_mode_grp[] = { |
| 203 | FUNC("n9 jtag", 3), |
| 204 | FUNC("utif1", 2), |
| 205 | FUNC("gpio", 1), |
| 206 | FUNC("sdxc", 0), |
| 207 | }; |
| 208 | |
| 209 | static const struct mtmips_pmx_func uart0_grp[] = { |
| 210 | FUNC("-", 3), |
| 211 | FUNC("-", 2), |
| 212 | FUNC("gpio", 1), |
| 213 | FUNC("uart0", 0), |
| 214 | }; |
| 215 | |
| 216 | static const struct mtmips_pmx_func i2s_grp[] = { |
| 217 | FUNC("antenna", 3), |
| 218 | FUNC("pcm", 2), |
| 219 | FUNC("gpio", 1), |
| 220 | FUNC("i2s", 0), |
| 221 | }; |
| 222 | |
| 223 | static const struct mtmips_pmx_func spi_cs1_grp[] = { |
| 224 | FUNC("-", 3), |
| 225 | FUNC("refclk", 2), |
| 226 | FUNC("gpio", 1), |
| 227 | FUNC("spi cs1", 0), |
| 228 | }; |
| 229 | |
| 230 | static const struct mtmips_pmx_func spis_grp[] = { |
| 231 | FUNC("pwm_uart2", 3), |
| 232 | FUNC("utif", 2), |
| 233 | FUNC("gpio", 1), |
| 234 | FUNC("spis", 0), |
| 235 | }; |
| 236 | |
| 237 | static const struct mtmips_pmx_func gpio0_grp[] = { |
| 238 | FUNC("perst", 3), |
| 239 | FUNC("refclk", 2), |
| 240 | FUNC("gpio", 1), |
| 241 | FUNC("gpio0", 0), |
| 242 | }; |
| 243 | |
| 244 | static const struct mtmips_pmx_func wled_a_grp[] = { |
| 245 | FUNC("-", 3), |
| 246 | FUNC("-", 2), |
| 247 | FUNC("gpio", 1), |
| 248 | FUNC("led", 0), |
| 249 | }; |
| 250 | |
| 251 | static const struct mtmips_pmx_func p0led_a_grp[] = { |
| 252 | FUNC("jtag", 3), |
| 253 | FUNC("rsvd", 2), |
| 254 | FUNC("gpio", 1), |
| 255 | FUNC("led", 0), |
| 256 | }; |
| 257 | |
| 258 | static const struct mtmips_pmx_func p1led_a_grp[] = { |
| 259 | FUNC("jtag", 3), |
| 260 | FUNC("utif", 2), |
| 261 | FUNC("gpio", 1), |
| 262 | FUNC("led", 0), |
| 263 | }; |
| 264 | |
| 265 | static const struct mtmips_pmx_func p2led_a_grp[] = { |
| 266 | FUNC("jtag", 3), |
| 267 | FUNC("utif", 2), |
| 268 | FUNC("gpio", 1), |
| 269 | FUNC("led", 0), |
| 270 | }; |
| 271 | |
| 272 | static const struct mtmips_pmx_func p3led_a_grp[] = { |
| 273 | FUNC("jtag", 3), |
| 274 | FUNC("utif", 2), |
| 275 | FUNC("gpio", 1), |
| 276 | FUNC("led", 0), |
| 277 | }; |
| 278 | |
| 279 | static const struct mtmips_pmx_func p4led_a_grp[] = { |
| 280 | FUNC("jtag", 3), |
| 281 | FUNC("utif", 2), |
| 282 | FUNC("gpio", 1), |
| 283 | FUNC("led", 0), |
| 284 | }; |
| 285 | |
| 286 | static const struct mtmips_pmx_func wled_k_grp[] = { |
| 287 | FUNC("-", 3), |
| 288 | FUNC("-", 2), |
| 289 | FUNC("gpio", 1), |
| 290 | FUNC("led", 0), |
| 291 | }; |
| 292 | |
| 293 | static const struct mtmips_pmx_func p0led_k_grp[] = { |
| 294 | FUNC("jtag", 3), |
| 295 | FUNC("rsvd", 2), |
| 296 | FUNC("gpio", 1), |
| 297 | FUNC("led", 0), |
| 298 | }; |
| 299 | |
| 300 | static const struct mtmips_pmx_func p1led_k_grp[] = { |
| 301 | FUNC("jtag", 3), |
| 302 | FUNC("utif", 2), |
| 303 | FUNC("gpio", 1), |
| 304 | FUNC("led", 0), |
| 305 | }; |
| 306 | |
| 307 | static const struct mtmips_pmx_func p2led_k_grp[] = { |
| 308 | FUNC("jtag", 3), |
| 309 | FUNC("utif", 2), |
| 310 | FUNC("gpio", 1), |
| 311 | FUNC("led", 0), |
| 312 | }; |
| 313 | |
| 314 | static const struct mtmips_pmx_func p3led_k_grp[] = { |
| 315 | FUNC("jtag", 3), |
| 316 | FUNC("utif", 2), |
| 317 | FUNC("gpio", 1), |
| 318 | FUNC("led", 0), |
| 319 | }; |
| 320 | |
| 321 | static const struct mtmips_pmx_func p4led_k_grp[] = { |
| 322 | FUNC("jtag", 3), |
| 323 | FUNC("utif", 2), |
| 324 | FUNC("gpio", 1), |
| 325 | FUNC("led", 0), |
| 326 | }; |
| 327 | |
| 328 | static const struct mtmips_pmx_group mt7628_pinmux_data[] = { |
| 329 | GRP("ephy4_1_pad", ephy4_1_pad_grp, AGPIO_OFS, EPHY4_1_PAD_SHIFT, |
| 330 | EPHY4_1_PAD_MASK), |
| 331 | GRP("ephy0", ephy0_grp, AGPIO_OFS, EPHY0_SHIFT, 1), |
| 332 | GRP("rf_olt", rf_olt_grp, AGPIO_OFS, RF_OLT_MODE_SHIFT, 1), |
| 333 | GRP("n9_eint_src", n9_eint_src_grp, AGPIO_OFS, N9_EINT_SRC_SHIFT, 1), |
| 334 | GRP("wlen_od", wlen_od_grp, AGPIO_OFS, WLED_OD_SHIFT, 1), |
| 335 | GRP("ref_clko_pad", ref_clko_grp, AGPIO_OFS, REF_CLKO_PAD_SHIFT, 1), |
| 336 | GRP("i2s_clk_pad", i2s_clk_grp, AGPIO_OFS, I2S_CLK_PAD_SHIFT, 1), |
| 337 | GRP("i2s_ws_pad", i2s_ws_grp, AGPIO_OFS, I2S_WS_PAD_SHIFT, 1), |
| 338 | GRP("i2s_sdo_pad", i2s_sdo_grp, AGPIO_OFS, I2S_SDO_PAD_SHIFT, 1), |
| 339 | GRP("i2s_sdi_pad", i2s_sdi_grp, AGPIO_OFS, I2S_SDI_PAD_SHIFT, 1), |
| 340 | GRP("pwm1", pwm1_grp, GPIOMODE1_OFS, PWM1_SHIFT, GM4_MASK), |
| 341 | GRP("pwm0", pwm0_grp, GPIOMODE1_OFS, PWM0_SHIFT, GM4_MASK), |
| 342 | GRP("uart2", uart2_grp, GPIOMODE1_OFS, UART2_SHIFT, GM4_MASK), |
| 343 | GRP("uart1", uart1_grp, GPIOMODE1_OFS, UART1_SHIFT, GM4_MASK), |
| 344 | GRP("i2c", i2c_grp, GPIOMODE1_OFS, I2C_SHIFT, GM4_MASK), |
| 345 | GRP("refclk", refclk_grp, GPIOMODE1_OFS, REFCLK_SHIFT, 1), |
| 346 | GRP("perst", perst_grp, GPIOMODE1_OFS, PERST_SHIFT, 1), |
| 347 | GRP("sd router", esd_grp, GPIOMODE1_OFS, ESD_SHIFT, 1), |
| 348 | GRP("wdt", wdt_grp, GPIOMODE1_OFS, WDT_SHIFT, 1), |
| 349 | GRP("spi", spi_grp, GPIOMODE1_OFS, SPI_SHIFT, 1), |
| 350 | GRP("sdmode", sd_mode_grp, GPIOMODE1_OFS, SDMODE_SHIFT, GM4_MASK), |
| 351 | GRP("uart0", uart0_grp, GPIOMODE1_OFS, UART0_SHIFT, GM4_MASK), |
| 352 | GRP("i2s", i2s_grp, GPIOMODE1_OFS, I2S_SHIFT, GM4_MASK), |
| 353 | GRP("spi cs1", spi_cs1_grp, GPIOMODE1_OFS, SPI_CS1_SHIFT, GM4_MASK), |
| 354 | GRP("spis", spis_grp, GPIOMODE1_OFS, SPIS_SHIFT, GM4_MASK), |
| 355 | GRP("gpio0", gpio0_grp, GPIOMODE1_OFS, GPIO0_SHIFT, GM4_MASK), |
| 356 | GRP("wled_a", wled_a_grp, GPIOMODE2_OFS, WLED_A_SHIFT, GM4_MASK), |
| 357 | GRP("p0led_a", p0led_a_grp, GPIOMODE2_OFS, P0LED_A_SHIFT, GM4_MASK), |
| 358 | GRP("p1led_a", p1led_a_grp, GPIOMODE2_OFS, P1LED_A_SHIFT, GM4_MASK), |
| 359 | GRP("p2led_a", p2led_a_grp, GPIOMODE2_OFS, P2LED_A_SHIFT, GM4_MASK), |
| 360 | GRP("p3led_a", p3led_a_grp, GPIOMODE2_OFS, P3LED_A_SHIFT, GM4_MASK), |
| 361 | GRP("p4led_a", p4led_a_grp, GPIOMODE2_OFS, P4LED_A_SHIFT, GM4_MASK), |
| 362 | GRP("wled_k", wled_k_grp, GPIOMODE2_OFS, WLED_K_SHIFT, GM4_MASK), |
| 363 | GRP("p0led_k", p0led_k_grp, GPIOMODE2_OFS, P0LED_K_SHIFT, GM4_MASK), |
| 364 | GRP("p1led_k", p1led_k_grp, GPIOMODE2_OFS, P1LED_K_SHIFT, GM4_MASK), |
| 365 | GRP("p2led_k", p2led_k_grp, GPIOMODE2_OFS, P2LED_K_SHIFT, GM4_MASK), |
| 366 | GRP("p3led_k", p3led_k_grp, GPIOMODE2_OFS, P3LED_K_SHIFT, GM4_MASK), |
| 367 | GRP("p4led_k", p4led_k_grp, GPIOMODE2_OFS, P4LED_K_SHIFT, GM4_MASK), |
| 368 | }; |
| 369 | |
| 370 | static int mt7628_get_groups_count(struct udevice *dev) |
| 371 | { |
| 372 | return ARRAY_SIZE(mt7628_pinmux_data); |
| 373 | } |
| 374 | |
| 375 | static const char *mt7628_get_group_name(struct udevice *dev, |
| 376 | unsigned int selector) |
| 377 | { |
| 378 | return mt7628_pinmux_data[selector].name; |
| 379 | } |
| 380 | #endif /* CONFIG_IS_ENABLED(PINMUX) */ |
| 381 | |
| 382 | #if CONFIG_IS_ENABLED(PINCONF) |
| 383 | static const struct pinconf_param mt7628_conf_params[] = { |
| 384 | { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, |
| 385 | { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 }, |
| 386 | { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 }, |
| 387 | { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 }, |
| 388 | { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 }, |
| 389 | { "drive-strength-28", PIN_CONFIG_DRIVE_STRENGTH_28, 0 }, |
| 390 | { "drive-strength-4g", PIN_CONFIG_DRIVE_STRENGTH_4G, 0 }, |
| 391 | { "slew-rate", PIN_CONFIG_SLEW_RATE, 0 }, |
| 392 | }; |
| 393 | |
| 394 | static const char *const mt7628_pins[] = { |
| 395 | "i2s_sdi", |
| 396 | "i2s_sdo", |
| 397 | "i2s_ws", |
| 398 | "i2s_clk", |
| 399 | "i2s_sclk", |
| 400 | "i2c_sd", |
| 401 | "spi_cs1", |
| 402 | "spi_clk", |
| 403 | "spi_mosi", |
| 404 | "spi_miso", |
| 405 | "spi_cs0", |
| 406 | "gpio0", |
| 407 | "uart0_txd", |
| 408 | "uart0_rxd", |
| 409 | "spis_cs", |
| 410 | "spis_clk", |
| 411 | "spis_miso", |
| 412 | "spis_mosi", |
| 413 | "pwm_ch0", |
| 414 | "pwm_ch1", |
| 415 | "uart2_txd", |
| 416 | "uart2_rxd", |
| 417 | "sd_wp", |
| 418 | "sd_cd", |
| 419 | "sd_d1", |
| 420 | "sd_d0", |
| 421 | "sd_clk", |
| 422 | "sd_cmd", |
| 423 | "sd_d3", |
| 424 | "sd_d2", |
| 425 | "ephy_led4_k", |
| 426 | "ephy_led3_k", |
| 427 | "ephy_led2_k", |
| 428 | "ephy_led1_k", |
| 429 | "ephy_led0_k", |
| 430 | "wled_k", |
| 431 | "perst_n", |
| 432 | "co_clko", |
| 433 | "wdt", |
| 434 | "ephy_led4_a", |
| 435 | "ephy_led3_a", |
| 436 | "ephy_led2_a", |
| 437 | "ephy_led1_a", |
| 438 | "ephy_led0_a", |
| 439 | "wled_a", |
| 440 | "uart1_txd", |
| 441 | "uart1_rxd", |
| 442 | }; |
| 443 | |
| 444 | static const u32 mt7628_drv_strength_28_tbl[] = {2, 4, 6, 8}; |
| 445 | static const u32 mt7628_drv_strength_4g_tbl[] = {4, 8, 12, 16}; |
| 446 | |
| 447 | static int mt7628_set_drv_strength(void __iomem *base, u32 val, u32 bit, |
| 448 | const u32 tbl[], u32 reg_lo, u32 reg_hi) |
| 449 | { |
| 450 | int i; |
| 451 | |
| 452 | for (i = 0; i < 4; i++) |
| 453 | if (tbl[i] == val) |
| 454 | break; |
| 455 | |
| 456 | if (i >= 4) |
| 457 | return -EINVAL; |
| 458 | |
| 459 | clrsetbits_32(base + reg_lo, BIT(bit), (i & 1) << bit); |
| 460 | clrsetbits_32(base + reg_hi, BIT(bit), ((i >> 1) & 1) << bit); |
| 461 | |
| 462 | return 0; |
| 463 | } |
| 464 | |
| 465 | static int mt7628_get_pins_count(struct udevice *dev) |
| 466 | { |
| 467 | return ARRAY_SIZE(mt7628_pins); |
| 468 | } |
| 469 | |
| 470 | static const char *mt7628_get_pin_name(struct udevice *dev, |
| 471 | unsigned int selector) |
| 472 | { |
| 473 | return mt7628_pins[selector]; |
| 474 | } |
| 475 | |
| 476 | static int mt7628_pinconf_set(struct udevice *dev, unsigned int pin_selector, |
| 477 | unsigned int param, unsigned int argument) |
| 478 | { |
| 479 | struct mt7628_pinctrl_priv *priv = dev_get_priv(dev); |
| 480 | u32 offs, bit; |
| 481 | int ret = 0; |
| 482 | |
| 483 | offs = (pin_selector / 32) * 4; |
| 484 | bit = pin_selector % 32; |
| 485 | |
| 486 | switch (param) { |
| 487 | case PIN_CONFIG_BIAS_DISABLE: |
| 488 | clrbits_32(priv->pcbase + offs + PAD_PU_G0_REG, BIT(bit)); |
| 489 | clrbits_32(priv->pcbase + offs + PAD_PD_G0_REG, BIT(bit)); |
| 490 | break; |
| 491 | case PIN_CONFIG_BIAS_PULL_UP: |
| 492 | setbits_32(priv->pcbase + offs + PAD_PU_G0_REG, BIT(bit)); |
| 493 | clrbits_32(priv->pcbase + offs + PAD_PD_G0_REG, BIT(bit)); |
| 494 | break; |
| 495 | case PIN_CONFIG_BIAS_PULL_DOWN: |
| 496 | clrbits_32(priv->pcbase + offs + PAD_PU_G0_REG, BIT(bit)); |
| 497 | setbits_32(priv->pcbase + offs + PAD_PD_G0_REG, BIT(bit)); |
| 498 | break; |
| 499 | case PIN_CONFIG_INPUT_SCHMITT_ENABLE: |
| 500 | clrsetbits_32(priv->pcbase + offs + PAD_SMT_G0_REG, |
| 501 | BIT(bit), (!!argument) << bit); |
| 502 | break; |
| 503 | case PIN_CONFIG_DRIVE_STRENGTH_28: |
| 504 | ret = mt7628_set_drv_strength(priv->pcbase + offs, argument, |
| 505 | bit, mt7628_drv_strength_28_tbl, |
| 506 | PAD_E2_G0_REG, PAD_E4_G0_REG); |
| 507 | break; |
| 508 | case PIN_CONFIG_DRIVE_STRENGTH_4G: |
| 509 | ret = mt7628_set_drv_strength(priv->pcbase + offs, argument, |
| 510 | bit, mt7628_drv_strength_4g_tbl, |
| 511 | PAD_E4_G0_REG, PAD_E8_G0_REG); |
| 512 | break; |
| 513 | case PIN_CONFIG_SLEW_RATE: |
| 514 | clrsetbits_32(priv->pcbase + offs + PAD_SR_G0_REG, |
| 515 | BIT(bit), (!!argument) << bit); |
| 516 | break; |
| 517 | default: |
| 518 | ret = -EINVAL; |
| 519 | } |
| 520 | |
| 521 | return ret; |
| 522 | } |
| 523 | #endif |
| 524 | |
| 525 | static int mt7628_pinctrl_probe(struct udevice *dev) |
| 526 | { |
| 527 | struct mt7628_pinctrl_priv *priv = dev_get_priv(dev); |
| 528 | int ret = 0; |
| 529 | |
| 530 | #if CONFIG_IS_ENABLED(PINMUX) |
| 531 | ret = mtmips_pinctrl_probe(&priv->mp, ARRAY_SIZE(mt7628_pinmux_data), |
| 532 | mt7628_pinmux_data); |
| 533 | #endif /* CONFIG_IS_ENABLED(PINMUX) */ |
| 534 | |
| 535 | return ret; |
| 536 | } |
| 537 | |
Simon Glass | aad29ae | 2020-12-03 16:55:21 -0700 | [diff] [blame] | 538 | static int mt7628_pinctrl_of_to_plat(struct udevice *dev) |
developer | e194781 | 2019-09-25 17:45:26 +0800 | [diff] [blame] | 539 | { |
| 540 | struct mt7628_pinctrl_priv *priv = dev_get_priv(dev); |
| 541 | |
| 542 | priv->mp.base = (void __iomem *)dev_remap_addr_index(dev, 0); |
| 543 | |
| 544 | if (!priv->mp.base) |
| 545 | return -EINVAL; |
| 546 | |
| 547 | priv->pcbase = (void __iomem *)dev_remap_addr_index(dev, 1); |
| 548 | |
| 549 | if (!priv->pcbase) |
| 550 | return -EINVAL; |
| 551 | |
| 552 | return 0; |
| 553 | } |
| 554 | |
| 555 | static const struct pinctrl_ops mt7628_pinctrl_ops = { |
| 556 | #if CONFIG_IS_ENABLED(PINMUX) |
| 557 | .get_groups_count = mt7628_get_groups_count, |
| 558 | .get_group_name = mt7628_get_group_name, |
| 559 | .get_functions_count = mtmips_get_functions_count, |
| 560 | .get_function_name = mtmips_get_function_name, |
| 561 | .pinmux_group_set = mtmips_pinmux_group_set, |
| 562 | #endif /* CONFIG_IS_ENABLED(PINMUX) */ |
| 563 | #if CONFIG_IS_ENABLED(PINCONF) |
| 564 | .pinconf_num_params = ARRAY_SIZE(mt7628_conf_params), |
| 565 | .pinconf_params = mt7628_conf_params, |
| 566 | .get_pins_count = mt7628_get_pins_count, |
| 567 | .get_pin_name = mt7628_get_pin_name, |
| 568 | .pinconf_set = mt7628_pinconf_set, |
| 569 | #endif /* CONFIG_IS_ENABLED(PINCONF) */ |
| 570 | .set_state = pinctrl_generic_set_state, |
| 571 | }; |
| 572 | |
| 573 | static const struct udevice_id mt7628_pinctrl_ids[] = { |
| 574 | { .compatible = "mediatek,mt7628-pinctrl" }, |
| 575 | { } |
| 576 | }; |
| 577 | |
| 578 | U_BOOT_DRIVER(mt7628_pinctrl) = { |
| 579 | .name = "mt7628-pinctrl", |
| 580 | .id = UCLASS_PINCTRL, |
| 581 | .of_match = mt7628_pinctrl_ids, |
Simon Glass | aad29ae | 2020-12-03 16:55:21 -0700 | [diff] [blame] | 582 | .of_to_plat = mt7628_pinctrl_of_to_plat, |
developer | e194781 | 2019-09-25 17:45:26 +0800 | [diff] [blame] | 583 | .ops = &mt7628_pinctrl_ops, |
| 584 | .probe = mt7628_pinctrl_probe, |
Simon Glass | 8a2b47f | 2020-12-03 16:55:17 -0700 | [diff] [blame] | 585 | .priv_auto = sizeof(struct mt7628_pinctrl_priv), |
developer | e194781 | 2019-09-25 17:45:26 +0800 | [diff] [blame] | 586 | }; |