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