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