1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2016 Socionext Inc. 4 * Author: Masahiro Yamada <yamada.masahiro@socionext.com> 5 */ 6 7 #include <linux/mfd/syscon.h> 8 #include <linux/module.h> 9 #include <linux/of.h> 10 #include <linux/of_device.h> 11 #include <linux/platform_device.h> 12 #include <linux/regmap.h> 13 #include <linux/reset-controller.h> 14 15 struct uniphier_reset_data { 16 unsigned int id; 17 unsigned int reg; 18 unsigned int bit; 19 unsigned int flags; 20 #define UNIPHIER_RESET_ACTIVE_LOW BIT(0) 21 }; 22 23 #define UNIPHIER_RESET_ID_END ((unsigned int)(-1)) 24 25 #define UNIPHIER_RESET_END \ 26 { .id = UNIPHIER_RESET_ID_END } 27 28 #define UNIPHIER_RESET(_id, _reg, _bit) \ 29 { \ 30 .id = (_id), \ 31 .reg = (_reg), \ 32 .bit = (_bit), \ 33 } 34 35 #define UNIPHIER_RESETX(_id, _reg, _bit) \ 36 { \ 37 .id = (_id), \ 38 .reg = (_reg), \ 39 .bit = (_bit), \ 40 .flags = UNIPHIER_RESET_ACTIVE_LOW, \ 41 } 42 43 /* System reset data */ 44 static const struct uniphier_reset_data uniphier_ld4_sys_reset_data[] = { 45 UNIPHIER_RESETX(2, 0x2000, 2), /* NAND */ 46 UNIPHIER_RESETX(8, 0x2000, 10), /* STDMAC (Ether, HSC, MIO) */ 47 UNIPHIER_RESET_END, 48 }; 49 50 static const struct uniphier_reset_data uniphier_pro4_sys_reset_data[] = { 51 UNIPHIER_RESETX(2, 0x2000, 2), /* NAND */ 52 UNIPHIER_RESETX(6, 0x2000, 12), /* Ether */ 53 UNIPHIER_RESETX(8, 0x2000, 10), /* STDMAC (HSC, MIO, RLE) */ 54 UNIPHIER_RESETX(12, 0x2000, 6), /* GIO (Ether, SATA, USB3) */ 55 UNIPHIER_RESETX(14, 0x2000, 17), /* USB30 */ 56 UNIPHIER_RESETX(15, 0x2004, 17), /* USB31 */ 57 UNIPHIER_RESETX(28, 0x2000, 18), /* SATA0 */ 58 UNIPHIER_RESETX(29, 0x2004, 18), /* SATA1 */ 59 UNIPHIER_RESETX(30, 0x2000, 19), /* SATA-PHY */ 60 UNIPHIER_RESETX(40, 0x2000, 13), /* AIO */ 61 UNIPHIER_RESET_END, 62 }; 63 64 static const struct uniphier_reset_data uniphier_pro5_sys_reset_data[] = { 65 UNIPHIER_RESETX(2, 0x2000, 2), /* NAND */ 66 UNIPHIER_RESETX(8, 0x2000, 10), /* STDMAC (HSC) */ 67 UNIPHIER_RESETX(12, 0x2000, 6), /* GIO (PCIe, USB3) */ 68 UNIPHIER_RESETX(14, 0x2000, 17), /* USB30 */ 69 UNIPHIER_RESETX(15, 0x2004, 17), /* USB31 */ 70 UNIPHIER_RESETX(24, 0x2008, 2), /* PCIe */ 71 UNIPHIER_RESETX(40, 0x2000, 13), /* AIO */ 72 UNIPHIER_RESET_END, 73 }; 74 75 static const struct uniphier_reset_data uniphier_pxs2_sys_reset_data[] = { 76 UNIPHIER_RESETX(2, 0x2000, 2), /* NAND */ 77 UNIPHIER_RESETX(6, 0x2000, 12), /* Ether */ 78 UNIPHIER_RESETX(8, 0x2000, 10), /* STDMAC (HSC, RLE) */ 79 UNIPHIER_RESETX(14, 0x2000, 17), /* USB30 */ 80 UNIPHIER_RESETX(15, 0x2004, 17), /* USB31 */ 81 UNIPHIER_RESETX(16, 0x2014, 4), /* USB30-PHY0 */ 82 UNIPHIER_RESETX(17, 0x2014, 0), /* USB30-PHY1 */ 83 UNIPHIER_RESETX(18, 0x2014, 2), /* USB30-PHY2 */ 84 UNIPHIER_RESETX(20, 0x2014, 5), /* USB31-PHY0 */ 85 UNIPHIER_RESETX(21, 0x2014, 1), /* USB31-PHY1 */ 86 UNIPHIER_RESETX(28, 0x2014, 12), /* SATA */ 87 UNIPHIER_RESET(30, 0x2014, 8), /* SATA-PHY (active high) */ 88 UNIPHIER_RESETX(40, 0x2000, 13), /* AIO */ 89 UNIPHIER_RESET_END, 90 }; 91 92 static const struct uniphier_reset_data uniphier_ld11_sys_reset_data[] = { 93 UNIPHIER_RESETX(2, 0x200c, 0), /* NAND */ 94 UNIPHIER_RESETX(4, 0x200c, 2), /* eMMC */ 95 UNIPHIER_RESETX(6, 0x200c, 6), /* Ether */ 96 UNIPHIER_RESETX(8, 0x200c, 8), /* STDMAC (HSC, MIO) */ 97 UNIPHIER_RESETX(9, 0x200c, 9), /* HSC */ 98 UNIPHIER_RESETX(40, 0x2008, 0), /* AIO */ 99 UNIPHIER_RESETX(41, 0x2008, 1), /* EVEA */ 100 UNIPHIER_RESETX(42, 0x2010, 2), /* EXIV */ 101 UNIPHIER_RESET_END, 102 }; 103 104 static const struct uniphier_reset_data uniphier_ld20_sys_reset_data[] = { 105 UNIPHIER_RESETX(2, 0x200c, 0), /* NAND */ 106 UNIPHIER_RESETX(4, 0x200c, 2), /* eMMC */ 107 UNIPHIER_RESETX(6, 0x200c, 6), /* Ether */ 108 UNIPHIER_RESETX(8, 0x200c, 8), /* STDMAC (HSC) */ 109 UNIPHIER_RESETX(9, 0x200c, 9), /* HSC */ 110 UNIPHIER_RESETX(14, 0x200c, 5), /* USB30 */ 111 UNIPHIER_RESETX(16, 0x200c, 12), /* USB30-PHY0 */ 112 UNIPHIER_RESETX(17, 0x200c, 13), /* USB30-PHY1 */ 113 UNIPHIER_RESETX(18, 0x200c, 14), /* USB30-PHY2 */ 114 UNIPHIER_RESETX(19, 0x200c, 15), /* USB30-PHY3 */ 115 UNIPHIER_RESETX(24, 0x200c, 4), /* PCIe */ 116 UNIPHIER_RESETX(40, 0x2008, 0), /* AIO */ 117 UNIPHIER_RESETX(41, 0x2008, 1), /* EVEA */ 118 UNIPHIER_RESETX(42, 0x2010, 2), /* EXIV */ 119 UNIPHIER_RESET_END, 120 }; 121 122 static const struct uniphier_reset_data uniphier_pxs3_sys_reset_data[] = { 123 UNIPHIER_RESETX(2, 0x200c, 0), /* NAND */ 124 UNIPHIER_RESETX(4, 0x200c, 2), /* eMMC */ 125 UNIPHIER_RESETX(6, 0x200c, 9), /* Ether0 */ 126 UNIPHIER_RESETX(7, 0x200c, 10), /* Ether1 */ 127 UNIPHIER_RESETX(8, 0x200c, 12), /* STDMAC */ 128 UNIPHIER_RESETX(12, 0x200c, 4), /* USB30 link */ 129 UNIPHIER_RESETX(13, 0x200c, 5), /* USB31 link */ 130 UNIPHIER_RESETX(16, 0x200c, 16), /* USB30-PHY0 */ 131 UNIPHIER_RESETX(17, 0x200c, 18), /* USB30-PHY1 */ 132 UNIPHIER_RESETX(18, 0x200c, 20), /* USB30-PHY2 */ 133 UNIPHIER_RESETX(20, 0x200c, 17), /* USB31-PHY0 */ 134 UNIPHIER_RESETX(21, 0x200c, 19), /* USB31-PHY1 */ 135 UNIPHIER_RESETX(24, 0x200c, 3), /* PCIe */ 136 UNIPHIER_RESETX(28, 0x200c, 7), /* SATA0 */ 137 UNIPHIER_RESETX(29, 0x200c, 8), /* SATA1 */ 138 UNIPHIER_RESETX(30, 0x200c, 21), /* SATA-PHY */ 139 UNIPHIER_RESET_END, 140 }; 141 142 /* Media I/O reset data */ 143 #define UNIPHIER_MIO_RESET_SD(id, ch) \ 144 UNIPHIER_RESETX((id), 0x110 + 0x200 * (ch), 0) 145 146 #define UNIPHIER_MIO_RESET_SD_BRIDGE(id, ch) \ 147 UNIPHIER_RESETX((id), 0x110 + 0x200 * (ch), 26) 148 149 #define UNIPHIER_MIO_RESET_EMMC_HW_RESET(id, ch) \ 150 UNIPHIER_RESETX((id), 0x80 + 0x200 * (ch), 0) 151 152 #define UNIPHIER_MIO_RESET_USB2(id, ch) \ 153 UNIPHIER_RESETX((id), 0x114 + 0x200 * (ch), 0) 154 155 #define UNIPHIER_MIO_RESET_USB2_BRIDGE(id, ch) \ 156 UNIPHIER_RESETX((id), 0x110 + 0x200 * (ch), 24) 157 158 #define UNIPHIER_MIO_RESET_DMAC(id) \ 159 UNIPHIER_RESETX((id), 0x110, 17) 160 161 static const struct uniphier_reset_data uniphier_ld4_mio_reset_data[] = { 162 UNIPHIER_MIO_RESET_SD(0, 0), 163 UNIPHIER_MIO_RESET_SD(1, 1), 164 UNIPHIER_MIO_RESET_SD(2, 2), 165 UNIPHIER_MIO_RESET_SD_BRIDGE(3, 0), 166 UNIPHIER_MIO_RESET_SD_BRIDGE(4, 1), 167 UNIPHIER_MIO_RESET_SD_BRIDGE(5, 2), 168 UNIPHIER_MIO_RESET_EMMC_HW_RESET(6, 1), 169 UNIPHIER_MIO_RESET_DMAC(7), 170 UNIPHIER_MIO_RESET_USB2(8, 0), 171 UNIPHIER_MIO_RESET_USB2(9, 1), 172 UNIPHIER_MIO_RESET_USB2(10, 2), 173 UNIPHIER_MIO_RESET_USB2_BRIDGE(12, 0), 174 UNIPHIER_MIO_RESET_USB2_BRIDGE(13, 1), 175 UNIPHIER_MIO_RESET_USB2_BRIDGE(14, 2), 176 UNIPHIER_RESET_END, 177 }; 178 179 static const struct uniphier_reset_data uniphier_pro5_sd_reset_data[] = { 180 UNIPHIER_MIO_RESET_SD(0, 0), 181 UNIPHIER_MIO_RESET_SD(1, 1), 182 UNIPHIER_MIO_RESET_EMMC_HW_RESET(6, 1), 183 UNIPHIER_RESET_END, 184 }; 185 186 /* Peripheral reset data */ 187 #define UNIPHIER_PERI_RESET_UART(id, ch) \ 188 UNIPHIER_RESETX((id), 0x114, 19 + (ch)) 189 190 #define UNIPHIER_PERI_RESET_I2C(id, ch) \ 191 UNIPHIER_RESETX((id), 0x114, 5 + (ch)) 192 193 #define UNIPHIER_PERI_RESET_FI2C(id, ch) \ 194 UNIPHIER_RESETX((id), 0x114, 24 + (ch)) 195 196 #define UNIPHIER_PERI_RESET_SCSSI(id, ch) \ 197 UNIPHIER_RESETX((id), 0x110, 17 + (ch)) 198 199 #define UNIPHIER_PERI_RESET_MCSSI(id) \ 200 UNIPHIER_RESETX((id), 0x114, 14) 201 202 static const struct uniphier_reset_data uniphier_ld4_peri_reset_data[] = { 203 UNIPHIER_PERI_RESET_UART(0, 0), 204 UNIPHIER_PERI_RESET_UART(1, 1), 205 UNIPHIER_PERI_RESET_UART(2, 2), 206 UNIPHIER_PERI_RESET_UART(3, 3), 207 UNIPHIER_PERI_RESET_I2C(4, 0), 208 UNIPHIER_PERI_RESET_I2C(5, 1), 209 UNIPHIER_PERI_RESET_I2C(6, 2), 210 UNIPHIER_PERI_RESET_I2C(7, 3), 211 UNIPHIER_PERI_RESET_I2C(8, 4), 212 UNIPHIER_PERI_RESET_SCSSI(11, 0), 213 UNIPHIER_RESET_END, 214 }; 215 216 static const struct uniphier_reset_data uniphier_pro4_peri_reset_data[] = { 217 UNIPHIER_PERI_RESET_UART(0, 0), 218 UNIPHIER_PERI_RESET_UART(1, 1), 219 UNIPHIER_PERI_RESET_UART(2, 2), 220 UNIPHIER_PERI_RESET_UART(3, 3), 221 UNIPHIER_PERI_RESET_FI2C(4, 0), 222 UNIPHIER_PERI_RESET_FI2C(5, 1), 223 UNIPHIER_PERI_RESET_FI2C(6, 2), 224 UNIPHIER_PERI_RESET_FI2C(7, 3), 225 UNIPHIER_PERI_RESET_FI2C(8, 4), 226 UNIPHIER_PERI_RESET_FI2C(9, 5), 227 UNIPHIER_PERI_RESET_FI2C(10, 6), 228 UNIPHIER_PERI_RESET_SCSSI(11, 0), 229 UNIPHIER_PERI_RESET_SCSSI(12, 1), 230 UNIPHIER_PERI_RESET_SCSSI(13, 2), 231 UNIPHIER_PERI_RESET_SCSSI(14, 3), 232 UNIPHIER_PERI_RESET_MCSSI(15), 233 UNIPHIER_RESET_END, 234 }; 235 236 /* Analog signal amplifiers reset data */ 237 static const struct uniphier_reset_data uniphier_ld11_adamv_reset_data[] = { 238 UNIPHIER_RESETX(0, 0x10, 6), /* EVEA */ 239 UNIPHIER_RESET_END, 240 }; 241 242 /* core implementaton */ 243 struct uniphier_reset_priv { 244 struct reset_controller_dev rcdev; 245 struct device *dev; 246 struct regmap *regmap; 247 const struct uniphier_reset_data *data; 248 }; 249 250 #define to_uniphier_reset_priv(_rcdev) \ 251 container_of(_rcdev, struct uniphier_reset_priv, rcdev) 252 253 static int uniphier_reset_update(struct reset_controller_dev *rcdev, 254 unsigned long id, int assert) 255 { 256 struct uniphier_reset_priv *priv = to_uniphier_reset_priv(rcdev); 257 const struct uniphier_reset_data *p; 258 259 for (p = priv->data; p->id != UNIPHIER_RESET_ID_END; p++) { 260 unsigned int mask, val; 261 262 if (p->id != id) 263 continue; 264 265 mask = BIT(p->bit); 266 267 if (assert) 268 val = mask; 269 else 270 val = ~mask; 271 272 if (p->flags & UNIPHIER_RESET_ACTIVE_LOW) 273 val = ~val; 274 275 return regmap_write_bits(priv->regmap, p->reg, mask, val); 276 } 277 278 dev_err(priv->dev, "reset_id=%lu was not handled\n", id); 279 return -EINVAL; 280 } 281 282 static int uniphier_reset_assert(struct reset_controller_dev *rcdev, 283 unsigned long id) 284 { 285 return uniphier_reset_update(rcdev, id, 1); 286 } 287 288 static int uniphier_reset_deassert(struct reset_controller_dev *rcdev, 289 unsigned long id) 290 { 291 return uniphier_reset_update(rcdev, id, 0); 292 } 293 294 static int uniphier_reset_status(struct reset_controller_dev *rcdev, 295 unsigned long id) 296 { 297 struct uniphier_reset_priv *priv = to_uniphier_reset_priv(rcdev); 298 const struct uniphier_reset_data *p; 299 300 for (p = priv->data; p->id != UNIPHIER_RESET_ID_END; p++) { 301 unsigned int val; 302 int ret, asserted; 303 304 if (p->id != id) 305 continue; 306 307 ret = regmap_read(priv->regmap, p->reg, &val); 308 if (ret) 309 return ret; 310 311 asserted = !!(val & BIT(p->bit)); 312 313 if (p->flags & UNIPHIER_RESET_ACTIVE_LOW) 314 asserted = !asserted; 315 316 return asserted; 317 } 318 319 dev_err(priv->dev, "reset_id=%lu was not found\n", id); 320 return -EINVAL; 321 } 322 323 static const struct reset_control_ops uniphier_reset_ops = { 324 .assert = uniphier_reset_assert, 325 .deassert = uniphier_reset_deassert, 326 .status = uniphier_reset_status, 327 }; 328 329 static int uniphier_reset_probe(struct platform_device *pdev) 330 { 331 struct device *dev = &pdev->dev; 332 struct uniphier_reset_priv *priv; 333 const struct uniphier_reset_data *p, *data; 334 struct regmap *regmap; 335 struct device_node *parent; 336 unsigned int nr_resets = 0; 337 338 data = of_device_get_match_data(dev); 339 if (WARN_ON(!data)) 340 return -EINVAL; 341 342 parent = of_get_parent(dev->of_node); /* parent should be syscon node */ 343 regmap = syscon_node_to_regmap(parent); 344 of_node_put(parent); 345 if (IS_ERR(regmap)) { 346 dev_err(dev, "failed to get regmap (error %ld)\n", 347 PTR_ERR(regmap)); 348 return PTR_ERR(regmap); 349 } 350 351 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 352 if (!priv) 353 return -ENOMEM; 354 355 for (p = data; p->id != UNIPHIER_RESET_ID_END; p++) 356 nr_resets = max(nr_resets, p->id + 1); 357 358 priv->rcdev.ops = &uniphier_reset_ops; 359 priv->rcdev.owner = dev->driver->owner; 360 priv->rcdev.of_node = dev->of_node; 361 priv->rcdev.nr_resets = nr_resets; 362 priv->dev = dev; 363 priv->regmap = regmap; 364 priv->data = data; 365 366 return devm_reset_controller_register(&pdev->dev, &priv->rcdev); 367 } 368 369 static const struct of_device_id uniphier_reset_match[] = { 370 /* System reset */ 371 { 372 .compatible = "socionext,uniphier-ld4-reset", 373 .data = uniphier_ld4_sys_reset_data, 374 }, 375 { 376 .compatible = "socionext,uniphier-pro4-reset", 377 .data = uniphier_pro4_sys_reset_data, 378 }, 379 { 380 .compatible = "socionext,uniphier-sld8-reset", 381 .data = uniphier_ld4_sys_reset_data, 382 }, 383 { 384 .compatible = "socionext,uniphier-pro5-reset", 385 .data = uniphier_pro5_sys_reset_data, 386 }, 387 { 388 .compatible = "socionext,uniphier-pxs2-reset", 389 .data = uniphier_pxs2_sys_reset_data, 390 }, 391 { 392 .compatible = "socionext,uniphier-ld11-reset", 393 .data = uniphier_ld11_sys_reset_data, 394 }, 395 { 396 .compatible = "socionext,uniphier-ld20-reset", 397 .data = uniphier_ld20_sys_reset_data, 398 }, 399 { 400 .compatible = "socionext,uniphier-pxs3-reset", 401 .data = uniphier_pxs3_sys_reset_data, 402 }, 403 /* Media I/O reset, SD reset */ 404 { 405 .compatible = "socionext,uniphier-ld4-mio-reset", 406 .data = uniphier_ld4_mio_reset_data, 407 }, 408 { 409 .compatible = "socionext,uniphier-pro4-mio-reset", 410 .data = uniphier_ld4_mio_reset_data, 411 }, 412 { 413 .compatible = "socionext,uniphier-sld8-mio-reset", 414 .data = uniphier_ld4_mio_reset_data, 415 }, 416 { 417 .compatible = "socionext,uniphier-pro5-sd-reset", 418 .data = uniphier_pro5_sd_reset_data, 419 }, 420 { 421 .compatible = "socionext,uniphier-pxs2-sd-reset", 422 .data = uniphier_pro5_sd_reset_data, 423 }, 424 { 425 .compatible = "socionext,uniphier-ld11-mio-reset", 426 .data = uniphier_ld4_mio_reset_data, 427 }, 428 { 429 .compatible = "socionext,uniphier-ld11-sd-reset", 430 .data = uniphier_pro5_sd_reset_data, 431 }, 432 { 433 .compatible = "socionext,uniphier-ld20-sd-reset", 434 .data = uniphier_pro5_sd_reset_data, 435 }, 436 { 437 .compatible = "socionext,uniphier-pxs3-sd-reset", 438 .data = uniphier_pro5_sd_reset_data, 439 }, 440 /* Peripheral reset */ 441 { 442 .compatible = "socionext,uniphier-ld4-peri-reset", 443 .data = uniphier_ld4_peri_reset_data, 444 }, 445 { 446 .compatible = "socionext,uniphier-pro4-peri-reset", 447 .data = uniphier_pro4_peri_reset_data, 448 }, 449 { 450 .compatible = "socionext,uniphier-sld8-peri-reset", 451 .data = uniphier_ld4_peri_reset_data, 452 }, 453 { 454 .compatible = "socionext,uniphier-pro5-peri-reset", 455 .data = uniphier_pro4_peri_reset_data, 456 }, 457 { 458 .compatible = "socionext,uniphier-pxs2-peri-reset", 459 .data = uniphier_pro4_peri_reset_data, 460 }, 461 { 462 .compatible = "socionext,uniphier-ld11-peri-reset", 463 .data = uniphier_pro4_peri_reset_data, 464 }, 465 { 466 .compatible = "socionext,uniphier-ld20-peri-reset", 467 .data = uniphier_pro4_peri_reset_data, 468 }, 469 { 470 .compatible = "socionext,uniphier-pxs3-peri-reset", 471 .data = uniphier_pro4_peri_reset_data, 472 }, 473 /* Analog signal amplifiers reset */ 474 { 475 .compatible = "socionext,uniphier-ld11-adamv-reset", 476 .data = uniphier_ld11_adamv_reset_data, 477 }, 478 { 479 .compatible = "socionext,uniphier-ld20-adamv-reset", 480 .data = uniphier_ld11_adamv_reset_data, 481 }, 482 { /* sentinel */ } 483 }; 484 MODULE_DEVICE_TABLE(of, uniphier_reset_match); 485 486 static struct platform_driver uniphier_reset_driver = { 487 .probe = uniphier_reset_probe, 488 .driver = { 489 .name = "uniphier-reset", 490 .of_match_table = uniphier_reset_match, 491 }, 492 }; 493 module_platform_driver(uniphier_reset_driver); 494 495 MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>"); 496 MODULE_DESCRIPTION("UniPhier Reset Controller Driver"); 497 MODULE_LICENSE("GPL"); 498