0001
0002
0003
0004
0005
0006
0007 #include <linux/mfd/syscon.h>
0008 #include <linux/module.h>
0009 #include <linux/of.h>
0010 #include <linux/of_device.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/regmap.h>
0013 #include <linux/reset-controller.h>
0014
0015 struct uniphier_reset_data {
0016 unsigned int id;
0017 unsigned int reg;
0018 unsigned int bit;
0019 unsigned int flags;
0020 #define UNIPHIER_RESET_ACTIVE_LOW BIT(0)
0021 };
0022
0023 #define UNIPHIER_RESET_ID_END ((unsigned int)(-1))
0024
0025 #define UNIPHIER_RESET_END \
0026 { .id = UNIPHIER_RESET_ID_END }
0027
0028 #define UNIPHIER_RESET(_id, _reg, _bit) \
0029 { \
0030 .id = (_id), \
0031 .reg = (_reg), \
0032 .bit = (_bit), \
0033 }
0034
0035 #define UNIPHIER_RESETX(_id, _reg, _bit) \
0036 { \
0037 .id = (_id), \
0038 .reg = (_reg), \
0039 .bit = (_bit), \
0040 .flags = UNIPHIER_RESET_ACTIVE_LOW, \
0041 }
0042
0043
0044 static const struct uniphier_reset_data uniphier_ld4_sys_reset_data[] = {
0045 UNIPHIER_RESETX(2, 0x2000, 2),
0046 UNIPHIER_RESETX(8, 0x2000, 10),
0047 UNIPHIER_RESET_END,
0048 };
0049
0050 static const struct uniphier_reset_data uniphier_pro4_sys_reset_data[] = {
0051 UNIPHIER_RESETX(2, 0x2000, 2),
0052 UNIPHIER_RESETX(6, 0x2000, 12),
0053 UNIPHIER_RESETX(8, 0x2000, 10),
0054 UNIPHIER_RESETX(12, 0x2000, 6),
0055 UNIPHIER_RESETX(14, 0x2000, 17),
0056 UNIPHIER_RESETX(15, 0x2004, 17),
0057 UNIPHIER_RESETX(28, 0x2000, 18),
0058 UNIPHIER_RESETX(29, 0x2004, 18),
0059 UNIPHIER_RESETX(30, 0x2000, 19),
0060 UNIPHIER_RESETX(40, 0x2000, 13),
0061 UNIPHIER_RESET_END,
0062 };
0063
0064 static const struct uniphier_reset_data uniphier_pro5_sys_reset_data[] = {
0065 UNIPHIER_RESETX(2, 0x2000, 2),
0066 UNIPHIER_RESETX(8, 0x2000, 10),
0067 UNIPHIER_RESETX(12, 0x2000, 6),
0068 UNIPHIER_RESETX(14, 0x2000, 17),
0069 UNIPHIER_RESETX(15, 0x2004, 17),
0070 UNIPHIER_RESETX(24, 0x2008, 2),
0071 UNIPHIER_RESETX(40, 0x2000, 13),
0072 UNIPHIER_RESET_END,
0073 };
0074
0075 static const struct uniphier_reset_data uniphier_pxs2_sys_reset_data[] = {
0076 UNIPHIER_RESETX(2, 0x2000, 2),
0077 UNIPHIER_RESETX(6, 0x2000, 12),
0078 UNIPHIER_RESETX(8, 0x2000, 10),
0079 UNIPHIER_RESETX(14, 0x2000, 17),
0080 UNIPHIER_RESETX(15, 0x2004, 17),
0081 UNIPHIER_RESETX(16, 0x2014, 4),
0082 UNIPHIER_RESETX(17, 0x2014, 0),
0083 UNIPHIER_RESETX(18, 0x2014, 2),
0084 UNIPHIER_RESETX(20, 0x2014, 5),
0085 UNIPHIER_RESETX(21, 0x2014, 1),
0086 UNIPHIER_RESETX(28, 0x2014, 12),
0087 UNIPHIER_RESET(30, 0x2014, 8),
0088 UNIPHIER_RESETX(40, 0x2000, 13),
0089 UNIPHIER_RESET_END,
0090 };
0091
0092 static const struct uniphier_reset_data uniphier_ld11_sys_reset_data[] = {
0093 UNIPHIER_RESETX(2, 0x200c, 0),
0094 UNIPHIER_RESETX(4, 0x200c, 2),
0095 UNIPHIER_RESETX(6, 0x200c, 6),
0096 UNIPHIER_RESETX(8, 0x200c, 8),
0097 UNIPHIER_RESETX(9, 0x200c, 9),
0098 UNIPHIER_RESETX(40, 0x2008, 0),
0099 UNIPHIER_RESETX(41, 0x2008, 1),
0100 UNIPHIER_RESETX(42, 0x2010, 2),
0101 UNIPHIER_RESET_END,
0102 };
0103
0104 static const struct uniphier_reset_data uniphier_ld20_sys_reset_data[] = {
0105 UNIPHIER_RESETX(2, 0x200c, 0),
0106 UNIPHIER_RESETX(4, 0x200c, 2),
0107 UNIPHIER_RESETX(6, 0x200c, 6),
0108 UNIPHIER_RESETX(8, 0x200c, 8),
0109 UNIPHIER_RESETX(9, 0x200c, 9),
0110 UNIPHIER_RESETX(14, 0x200c, 5),
0111 UNIPHIER_RESETX(16, 0x200c, 12),
0112 UNIPHIER_RESETX(17, 0x200c, 13),
0113 UNIPHIER_RESETX(18, 0x200c, 14),
0114 UNIPHIER_RESETX(19, 0x200c, 15),
0115 UNIPHIER_RESETX(24, 0x200c, 4),
0116 UNIPHIER_RESETX(40, 0x2008, 0),
0117 UNIPHIER_RESETX(41, 0x2008, 1),
0118 UNIPHIER_RESETX(42, 0x2010, 2),
0119 UNIPHIER_RESET_END,
0120 };
0121
0122 static const struct uniphier_reset_data uniphier_pxs3_sys_reset_data[] = {
0123 UNIPHIER_RESETX(2, 0x200c, 0),
0124 UNIPHIER_RESETX(4, 0x200c, 2),
0125 UNIPHIER_RESETX(6, 0x200c, 9),
0126 UNIPHIER_RESETX(7, 0x200c, 10),
0127 UNIPHIER_RESETX(8, 0x200c, 12),
0128 UNIPHIER_RESETX(12, 0x200c, 4),
0129 UNIPHIER_RESETX(13, 0x200c, 5),
0130 UNIPHIER_RESETX(16, 0x200c, 16),
0131 UNIPHIER_RESETX(17, 0x200c, 18),
0132 UNIPHIER_RESETX(18, 0x200c, 20),
0133 UNIPHIER_RESETX(20, 0x200c, 17),
0134 UNIPHIER_RESETX(21, 0x200c, 19),
0135 UNIPHIER_RESETX(24, 0x200c, 3),
0136 UNIPHIER_RESETX(28, 0x200c, 7),
0137 UNIPHIER_RESETX(29, 0x200c, 8),
0138 UNIPHIER_RESETX(30, 0x200c, 21),
0139 UNIPHIER_RESETX(40, 0x2008, 0),
0140 UNIPHIER_RESETX(42, 0x2010, 2),
0141 UNIPHIER_RESET_END,
0142 };
0143
0144 static const struct uniphier_reset_data uniphier_nx1_sys_reset_data[] = {
0145 UNIPHIER_RESETX(4, 0x2008, 8),
0146 UNIPHIER_RESETX(6, 0x200c, 0),
0147 UNIPHIER_RESETX(12, 0x200c, 16),
0148 UNIPHIER_RESETX(16, 0x200c, 24),
0149 UNIPHIER_RESETX(17, 0x200c, 25),
0150 UNIPHIER_RESETX(18, 0x200c, 26),
0151 UNIPHIER_RESETX(24, 0x200c, 8),
0152 UNIPHIER_RESETX(52, 0x2010, 0),
0153 UNIPHIER_RESETX(58, 0x2010, 8),
0154 UNIPHIER_RESET_END,
0155 };
0156
0157
0158 #define UNIPHIER_MIO_RESET_SD(id, ch) \
0159 UNIPHIER_RESETX((id), 0x110 + 0x200 * (ch), 0)
0160
0161 #define UNIPHIER_MIO_RESET_SD_BRIDGE(id, ch) \
0162 UNIPHIER_RESETX((id), 0x110 + 0x200 * (ch), 26)
0163
0164 #define UNIPHIER_MIO_RESET_EMMC_HW_RESET(id, ch) \
0165 UNIPHIER_RESETX((id), 0x80 + 0x200 * (ch), 0)
0166
0167 #define UNIPHIER_MIO_RESET_USB2(id, ch) \
0168 UNIPHIER_RESETX((id), 0x114 + 0x200 * (ch), 0)
0169
0170 #define UNIPHIER_MIO_RESET_USB2_BRIDGE(id, ch) \
0171 UNIPHIER_RESETX((id), 0x110 + 0x200 * (ch), 24)
0172
0173 #define UNIPHIER_MIO_RESET_DMAC(id) \
0174 UNIPHIER_RESETX((id), 0x110, 17)
0175
0176 static const struct uniphier_reset_data uniphier_ld4_mio_reset_data[] = {
0177 UNIPHIER_MIO_RESET_SD(0, 0),
0178 UNIPHIER_MIO_RESET_SD(1, 1),
0179 UNIPHIER_MIO_RESET_SD(2, 2),
0180 UNIPHIER_MIO_RESET_SD_BRIDGE(3, 0),
0181 UNIPHIER_MIO_RESET_SD_BRIDGE(4, 1),
0182 UNIPHIER_MIO_RESET_SD_BRIDGE(5, 2),
0183 UNIPHIER_MIO_RESET_EMMC_HW_RESET(6, 1),
0184 UNIPHIER_MIO_RESET_DMAC(7),
0185 UNIPHIER_MIO_RESET_USB2(8, 0),
0186 UNIPHIER_MIO_RESET_USB2(9, 1),
0187 UNIPHIER_MIO_RESET_USB2(10, 2),
0188 UNIPHIER_MIO_RESET_USB2_BRIDGE(12, 0),
0189 UNIPHIER_MIO_RESET_USB2_BRIDGE(13, 1),
0190 UNIPHIER_MIO_RESET_USB2_BRIDGE(14, 2),
0191 UNIPHIER_RESET_END,
0192 };
0193
0194 static const struct uniphier_reset_data uniphier_pro5_sd_reset_data[] = {
0195 UNIPHIER_MIO_RESET_SD(0, 0),
0196 UNIPHIER_MIO_RESET_SD(1, 1),
0197 UNIPHIER_MIO_RESET_EMMC_HW_RESET(6, 1),
0198 UNIPHIER_RESET_END,
0199 };
0200
0201
0202 #define UNIPHIER_PERI_RESET_UART(id, ch) \
0203 UNIPHIER_RESETX((id), 0x114, 19 + (ch))
0204
0205 #define UNIPHIER_PERI_RESET_I2C(id, ch) \
0206 UNIPHIER_RESETX((id), 0x114, 5 + (ch))
0207
0208 #define UNIPHIER_PERI_RESET_FI2C(id, ch) \
0209 UNIPHIER_RESETX((id), 0x114, 24 + (ch))
0210
0211 #define UNIPHIER_PERI_RESET_SCSSI(id, ch) \
0212 UNIPHIER_RESETX((id), 0x110, 17 + (ch))
0213
0214 #define UNIPHIER_PERI_RESET_MCSSI(id) \
0215 UNIPHIER_RESETX((id), 0x114, 14)
0216
0217 static const struct uniphier_reset_data uniphier_ld4_peri_reset_data[] = {
0218 UNIPHIER_PERI_RESET_UART(0, 0),
0219 UNIPHIER_PERI_RESET_UART(1, 1),
0220 UNIPHIER_PERI_RESET_UART(2, 2),
0221 UNIPHIER_PERI_RESET_UART(3, 3),
0222 UNIPHIER_PERI_RESET_I2C(4, 0),
0223 UNIPHIER_PERI_RESET_I2C(5, 1),
0224 UNIPHIER_PERI_RESET_I2C(6, 2),
0225 UNIPHIER_PERI_RESET_I2C(7, 3),
0226 UNIPHIER_PERI_RESET_I2C(8, 4),
0227 UNIPHIER_PERI_RESET_SCSSI(11, 0),
0228 UNIPHIER_RESET_END,
0229 };
0230
0231 static const struct uniphier_reset_data uniphier_pro4_peri_reset_data[] = {
0232 UNIPHIER_PERI_RESET_UART(0, 0),
0233 UNIPHIER_PERI_RESET_UART(1, 1),
0234 UNIPHIER_PERI_RESET_UART(2, 2),
0235 UNIPHIER_PERI_RESET_UART(3, 3),
0236 UNIPHIER_PERI_RESET_FI2C(4, 0),
0237 UNIPHIER_PERI_RESET_FI2C(5, 1),
0238 UNIPHIER_PERI_RESET_FI2C(6, 2),
0239 UNIPHIER_PERI_RESET_FI2C(7, 3),
0240 UNIPHIER_PERI_RESET_FI2C(8, 4),
0241 UNIPHIER_PERI_RESET_FI2C(9, 5),
0242 UNIPHIER_PERI_RESET_FI2C(10, 6),
0243 UNIPHIER_PERI_RESET_SCSSI(11, 0),
0244 UNIPHIER_PERI_RESET_SCSSI(12, 1),
0245 UNIPHIER_PERI_RESET_SCSSI(13, 2),
0246 UNIPHIER_PERI_RESET_SCSSI(14, 3),
0247 UNIPHIER_PERI_RESET_MCSSI(15),
0248 UNIPHIER_RESET_END,
0249 };
0250
0251
0252 static const struct uniphier_reset_data uniphier_ld11_adamv_reset_data[] = {
0253 UNIPHIER_RESETX(0, 0x10, 6),
0254 UNIPHIER_RESET_END,
0255 };
0256
0257
0258 struct uniphier_reset_priv {
0259 struct reset_controller_dev rcdev;
0260 struct device *dev;
0261 struct regmap *regmap;
0262 const struct uniphier_reset_data *data;
0263 };
0264
0265 #define to_uniphier_reset_priv(_rcdev) \
0266 container_of(_rcdev, struct uniphier_reset_priv, rcdev)
0267
0268 static int uniphier_reset_update(struct reset_controller_dev *rcdev,
0269 unsigned long id, int assert)
0270 {
0271 struct uniphier_reset_priv *priv = to_uniphier_reset_priv(rcdev);
0272 const struct uniphier_reset_data *p;
0273
0274 for (p = priv->data; p->id != UNIPHIER_RESET_ID_END; p++) {
0275 unsigned int mask, val;
0276
0277 if (p->id != id)
0278 continue;
0279
0280 mask = BIT(p->bit);
0281
0282 if (assert)
0283 val = mask;
0284 else
0285 val = ~mask;
0286
0287 if (p->flags & UNIPHIER_RESET_ACTIVE_LOW)
0288 val = ~val;
0289
0290 return regmap_write_bits(priv->regmap, p->reg, mask, val);
0291 }
0292
0293 dev_err(priv->dev, "reset_id=%lu was not handled\n", id);
0294 return -EINVAL;
0295 }
0296
0297 static int uniphier_reset_assert(struct reset_controller_dev *rcdev,
0298 unsigned long id)
0299 {
0300 return uniphier_reset_update(rcdev, id, 1);
0301 }
0302
0303 static int uniphier_reset_deassert(struct reset_controller_dev *rcdev,
0304 unsigned long id)
0305 {
0306 return uniphier_reset_update(rcdev, id, 0);
0307 }
0308
0309 static int uniphier_reset_status(struct reset_controller_dev *rcdev,
0310 unsigned long id)
0311 {
0312 struct uniphier_reset_priv *priv = to_uniphier_reset_priv(rcdev);
0313 const struct uniphier_reset_data *p;
0314
0315 for (p = priv->data; p->id != UNIPHIER_RESET_ID_END; p++) {
0316 unsigned int val;
0317 int ret, asserted;
0318
0319 if (p->id != id)
0320 continue;
0321
0322 ret = regmap_read(priv->regmap, p->reg, &val);
0323 if (ret)
0324 return ret;
0325
0326 asserted = !!(val & BIT(p->bit));
0327
0328 if (p->flags & UNIPHIER_RESET_ACTIVE_LOW)
0329 asserted = !asserted;
0330
0331 return asserted;
0332 }
0333
0334 dev_err(priv->dev, "reset_id=%lu was not found\n", id);
0335 return -EINVAL;
0336 }
0337
0338 static const struct reset_control_ops uniphier_reset_ops = {
0339 .assert = uniphier_reset_assert,
0340 .deassert = uniphier_reset_deassert,
0341 .status = uniphier_reset_status,
0342 };
0343
0344 static int uniphier_reset_probe(struct platform_device *pdev)
0345 {
0346 struct device *dev = &pdev->dev;
0347 struct uniphier_reset_priv *priv;
0348 const struct uniphier_reset_data *p, *data;
0349 struct regmap *regmap;
0350 struct device_node *parent;
0351 unsigned int nr_resets = 0;
0352
0353 data = of_device_get_match_data(dev);
0354 if (WARN_ON(!data))
0355 return -EINVAL;
0356
0357 parent = of_get_parent(dev->of_node);
0358 regmap = syscon_node_to_regmap(parent);
0359 of_node_put(parent);
0360 if (IS_ERR(regmap)) {
0361 dev_err(dev, "failed to get regmap (error %ld)\n",
0362 PTR_ERR(regmap));
0363 return PTR_ERR(regmap);
0364 }
0365
0366 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0367 if (!priv)
0368 return -ENOMEM;
0369
0370 for (p = data; p->id != UNIPHIER_RESET_ID_END; p++)
0371 nr_resets = max(nr_resets, p->id + 1);
0372
0373 priv->rcdev.ops = &uniphier_reset_ops;
0374 priv->rcdev.owner = dev->driver->owner;
0375 priv->rcdev.of_node = dev->of_node;
0376 priv->rcdev.nr_resets = nr_resets;
0377 priv->dev = dev;
0378 priv->regmap = regmap;
0379 priv->data = data;
0380
0381 return devm_reset_controller_register(&pdev->dev, &priv->rcdev);
0382 }
0383
0384 static const struct of_device_id uniphier_reset_match[] = {
0385
0386 {
0387 .compatible = "socionext,uniphier-ld4-reset",
0388 .data = uniphier_ld4_sys_reset_data,
0389 },
0390 {
0391 .compatible = "socionext,uniphier-pro4-reset",
0392 .data = uniphier_pro4_sys_reset_data,
0393 },
0394 {
0395 .compatible = "socionext,uniphier-sld8-reset",
0396 .data = uniphier_ld4_sys_reset_data,
0397 },
0398 {
0399 .compatible = "socionext,uniphier-pro5-reset",
0400 .data = uniphier_pro5_sys_reset_data,
0401 },
0402 {
0403 .compatible = "socionext,uniphier-pxs2-reset",
0404 .data = uniphier_pxs2_sys_reset_data,
0405 },
0406 {
0407 .compatible = "socionext,uniphier-ld11-reset",
0408 .data = uniphier_ld11_sys_reset_data,
0409 },
0410 {
0411 .compatible = "socionext,uniphier-ld20-reset",
0412 .data = uniphier_ld20_sys_reset_data,
0413 },
0414 {
0415 .compatible = "socionext,uniphier-pxs3-reset",
0416 .data = uniphier_pxs3_sys_reset_data,
0417 },
0418 {
0419 .compatible = "socionext,uniphier-nx1-reset",
0420 .data = uniphier_nx1_sys_reset_data,
0421 },
0422
0423 {
0424 .compatible = "socionext,uniphier-ld4-mio-reset",
0425 .data = uniphier_ld4_mio_reset_data,
0426 },
0427 {
0428 .compatible = "socionext,uniphier-pro4-mio-reset",
0429 .data = uniphier_ld4_mio_reset_data,
0430 },
0431 {
0432 .compatible = "socionext,uniphier-sld8-mio-reset",
0433 .data = uniphier_ld4_mio_reset_data,
0434 },
0435 {
0436 .compatible = "socionext,uniphier-pro5-sd-reset",
0437 .data = uniphier_pro5_sd_reset_data,
0438 },
0439 {
0440 .compatible = "socionext,uniphier-pxs2-sd-reset",
0441 .data = uniphier_pro5_sd_reset_data,
0442 },
0443 {
0444 .compatible = "socionext,uniphier-ld11-mio-reset",
0445 .data = uniphier_ld4_mio_reset_data,
0446 },
0447 {
0448 .compatible = "socionext,uniphier-ld11-sd-reset",
0449 .data = uniphier_pro5_sd_reset_data,
0450 },
0451 {
0452 .compatible = "socionext,uniphier-ld20-sd-reset",
0453 .data = uniphier_pro5_sd_reset_data,
0454 },
0455 {
0456 .compatible = "socionext,uniphier-pxs3-sd-reset",
0457 .data = uniphier_pro5_sd_reset_data,
0458 },
0459 {
0460 .compatible = "socionext,uniphier-nx1-sd-reset",
0461 .data = uniphier_pro5_sd_reset_data,
0462 },
0463
0464 {
0465 .compatible = "socionext,uniphier-ld4-peri-reset",
0466 .data = uniphier_ld4_peri_reset_data,
0467 },
0468 {
0469 .compatible = "socionext,uniphier-pro4-peri-reset",
0470 .data = uniphier_pro4_peri_reset_data,
0471 },
0472 {
0473 .compatible = "socionext,uniphier-sld8-peri-reset",
0474 .data = uniphier_ld4_peri_reset_data,
0475 },
0476 {
0477 .compatible = "socionext,uniphier-pro5-peri-reset",
0478 .data = uniphier_pro4_peri_reset_data,
0479 },
0480 {
0481 .compatible = "socionext,uniphier-pxs2-peri-reset",
0482 .data = uniphier_pro4_peri_reset_data,
0483 },
0484 {
0485 .compatible = "socionext,uniphier-ld11-peri-reset",
0486 .data = uniphier_pro4_peri_reset_data,
0487 },
0488 {
0489 .compatible = "socionext,uniphier-ld20-peri-reset",
0490 .data = uniphier_pro4_peri_reset_data,
0491 },
0492 {
0493 .compatible = "socionext,uniphier-pxs3-peri-reset",
0494 .data = uniphier_pro4_peri_reset_data,
0495 },
0496 {
0497 .compatible = "socionext,uniphier-nx1-peri-reset",
0498 .data = uniphier_pro4_peri_reset_data,
0499 },
0500
0501 {
0502 .compatible = "socionext,uniphier-ld11-adamv-reset",
0503 .data = uniphier_ld11_adamv_reset_data,
0504 },
0505 {
0506 .compatible = "socionext,uniphier-ld20-adamv-reset",
0507 .data = uniphier_ld11_adamv_reset_data,
0508 },
0509 { }
0510 };
0511 MODULE_DEVICE_TABLE(of, uniphier_reset_match);
0512
0513 static struct platform_driver uniphier_reset_driver = {
0514 .probe = uniphier_reset_probe,
0515 .driver = {
0516 .name = "uniphier-reset",
0517 .of_match_table = uniphier_reset_match,
0518 },
0519 };
0520 module_platform_driver(uniphier_reset_driver);
0521
0522 MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
0523 MODULE_DESCRIPTION("UniPhier Reset Controller Driver");
0524 MODULE_LICENSE("GPL");