linux/drivers/reset/reset-npcm.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2// Copyright (c) 2019 Nuvoton Technology corporation.
   3
   4#include <linux/delay.h>
   5#include <linux/err.h>
   6#include <linux/io.h>
   7#include <linux/init.h>
   8#include <linux/of.h>
   9#include <linux/of_device.h>
  10#include <linux/platform_device.h>
  11#include <linux/reboot.h>
  12#include <linux/reset-controller.h>
  13#include <linux/spinlock.h>
  14#include <linux/mfd/syscon.h>
  15#include <linux/regmap.h>
  16#include <linux/of_address.h>
  17
  18/* NPCM7xx GCR registers */
  19#define NPCM_MDLR_OFFSET        0x7C
  20#define NPCM_MDLR_USBD0         BIT(9)
  21#define NPCM_MDLR_USBD1         BIT(8)
  22#define NPCM_MDLR_USBD2_4       BIT(21)
  23#define NPCM_MDLR_USBD5_9       BIT(22)
  24
  25#define NPCM_USB1PHYCTL_OFFSET  0x140
  26#define NPCM_USB2PHYCTL_OFFSET  0x144
  27#define NPCM_USBXPHYCTL_RS      BIT(28)
  28
  29/* NPCM7xx Reset registers */
  30#define NPCM_SWRSTR             0x14
  31#define NPCM_SWRST              BIT(2)
  32
  33#define NPCM_IPSRST1            0x20
  34#define NPCM_IPSRST1_USBD1      BIT(5)
  35#define NPCM_IPSRST1_USBD2      BIT(8)
  36#define NPCM_IPSRST1_USBD3      BIT(25)
  37#define NPCM_IPSRST1_USBD4      BIT(22)
  38#define NPCM_IPSRST1_USBD5      BIT(23)
  39#define NPCM_IPSRST1_USBD6      BIT(24)
  40
  41#define NPCM_IPSRST2            0x24
  42#define NPCM_IPSRST2_USB_HOST   BIT(26)
  43
  44#define NPCM_IPSRST3            0x34
  45#define NPCM_IPSRST3_USBD0      BIT(4)
  46#define NPCM_IPSRST3_USBD7      BIT(5)
  47#define NPCM_IPSRST3_USBD8      BIT(6)
  48#define NPCM_IPSRST3_USBD9      BIT(7)
  49#define NPCM_IPSRST3_USBPHY1    BIT(24)
  50#define NPCM_IPSRST3_USBPHY2    BIT(25)
  51
  52#define NPCM_RC_RESETS_PER_REG  32
  53#define NPCM_MASK_RESETS        GENMASK(4, 0)
  54
  55struct npcm_rc_data {
  56        struct reset_controller_dev rcdev;
  57        struct notifier_block restart_nb;
  58        u32 sw_reset_number;
  59        void __iomem *base;
  60        spinlock_t lock;
  61};
  62
  63#define to_rc_data(p) container_of(p, struct npcm_rc_data, rcdev)
  64
  65static int npcm_rc_restart(struct notifier_block *nb, unsigned long mode,
  66                           void *cmd)
  67{
  68        struct npcm_rc_data *rc = container_of(nb, struct npcm_rc_data,
  69                                               restart_nb);
  70
  71        writel(NPCM_SWRST << rc->sw_reset_number, rc->base + NPCM_SWRSTR);
  72        mdelay(1000);
  73
  74        pr_emerg("%s: unable to restart system\n", __func__);
  75
  76        return NOTIFY_DONE;
  77}
  78
  79static int npcm_rc_setclear_reset(struct reset_controller_dev *rcdev,
  80                                  unsigned long id, bool set)
  81{
  82        struct npcm_rc_data *rc = to_rc_data(rcdev);
  83        unsigned int rst_bit = BIT(id & NPCM_MASK_RESETS);
  84        unsigned int ctrl_offset = id >> 8;
  85        unsigned long flags;
  86        u32 stat;
  87
  88        spin_lock_irqsave(&rc->lock, flags);
  89        stat = readl(rc->base + ctrl_offset);
  90        if (set)
  91                writel(stat | rst_bit, rc->base + ctrl_offset);
  92        else
  93                writel(stat & ~rst_bit, rc->base + ctrl_offset);
  94        spin_unlock_irqrestore(&rc->lock, flags);
  95
  96        return 0;
  97}
  98
  99static int npcm_rc_assert(struct reset_controller_dev *rcdev, unsigned long id)
 100{
 101        return npcm_rc_setclear_reset(rcdev, id, true);
 102}
 103
 104static int npcm_rc_deassert(struct reset_controller_dev *rcdev,
 105                            unsigned long id)
 106{
 107        return npcm_rc_setclear_reset(rcdev, id, false);
 108}
 109
 110static int npcm_rc_status(struct reset_controller_dev *rcdev,
 111                          unsigned long id)
 112{
 113        struct npcm_rc_data *rc = to_rc_data(rcdev);
 114        unsigned int rst_bit = BIT(id & NPCM_MASK_RESETS);
 115        unsigned int ctrl_offset = id >> 8;
 116
 117        return (readl(rc->base + ctrl_offset) & rst_bit);
 118}
 119
 120static int npcm_reset_xlate(struct reset_controller_dev *rcdev,
 121                            const struct of_phandle_args *reset_spec)
 122{
 123        unsigned int offset, bit;
 124
 125        offset = reset_spec->args[0];
 126        if (offset != NPCM_IPSRST1 && offset != NPCM_IPSRST2 &&
 127            offset != NPCM_IPSRST3) {
 128                dev_err(rcdev->dev, "Error reset register (0x%x)\n", offset);
 129                return -EINVAL;
 130        }
 131        bit = reset_spec->args[1];
 132        if (bit >= NPCM_RC_RESETS_PER_REG) {
 133                dev_err(rcdev->dev, "Error reset number (%d)\n", bit);
 134                return -EINVAL;
 135        }
 136
 137        return (offset << 8) | bit;
 138}
 139
 140static const struct of_device_id npcm_rc_match[] = {
 141        { .compatible = "nuvoton,npcm750-reset",
 142                .data = (void *)"nuvoton,npcm750-gcr" },
 143        { }
 144};
 145
 146/*
 147 *  The following procedure should be observed in USB PHY, USB device and
 148 *  USB host initialization at BMC boot
 149 */
 150static int npcm_usb_reset(struct platform_device *pdev, struct npcm_rc_data *rc)
 151{
 152        u32 mdlr, iprst1, iprst2, iprst3;
 153        struct device *dev = &pdev->dev;
 154        struct regmap *gcr_regmap;
 155        u32 ipsrst1_bits = 0;
 156        u32 ipsrst2_bits = NPCM_IPSRST2_USB_HOST;
 157        u32 ipsrst3_bits = 0;
 158        const char *gcr_dt;
 159
 160        gcr_dt = (const char *)
 161        of_match_device(dev->driver->of_match_table, dev)->data;
 162
 163        gcr_regmap = syscon_regmap_lookup_by_compatible(gcr_dt);
 164        if (IS_ERR(gcr_regmap)) {
 165                dev_err(&pdev->dev, "Failed to find %s\n", gcr_dt);
 166                return PTR_ERR(gcr_regmap);
 167        }
 168
 169        /* checking which USB device is enabled */
 170        regmap_read(gcr_regmap, NPCM_MDLR_OFFSET, &mdlr);
 171        if (!(mdlr & NPCM_MDLR_USBD0))
 172                ipsrst3_bits |= NPCM_IPSRST3_USBD0;
 173        if (!(mdlr & NPCM_MDLR_USBD1))
 174                ipsrst1_bits |= NPCM_IPSRST1_USBD1;
 175        if (!(mdlr & NPCM_MDLR_USBD2_4))
 176                ipsrst1_bits |= (NPCM_IPSRST1_USBD2 |
 177                                 NPCM_IPSRST1_USBD3 |
 178                                 NPCM_IPSRST1_USBD4);
 179        if (!(mdlr & NPCM_MDLR_USBD0)) {
 180                ipsrst1_bits |= (NPCM_IPSRST1_USBD5 |
 181                                 NPCM_IPSRST1_USBD6);
 182                ipsrst3_bits |= (NPCM_IPSRST3_USBD7 |
 183                                 NPCM_IPSRST3_USBD8 |
 184                                 NPCM_IPSRST3_USBD9);
 185        }
 186
 187        /* assert reset USB PHY and USB devices */
 188        iprst1 = readl(rc->base + NPCM_IPSRST1);
 189        iprst2 = readl(rc->base + NPCM_IPSRST2);
 190        iprst3 = readl(rc->base + NPCM_IPSRST3);
 191
 192        iprst1 |= ipsrst1_bits;
 193        iprst2 |= ipsrst2_bits;
 194        iprst3 |= (ipsrst3_bits | NPCM_IPSRST3_USBPHY1 |
 195                   NPCM_IPSRST3_USBPHY2);
 196
 197        writel(iprst1, rc->base + NPCM_IPSRST1);
 198        writel(iprst2, rc->base + NPCM_IPSRST2);
 199        writel(iprst3, rc->base + NPCM_IPSRST3);
 200
 201        /* clear USB PHY RS bit */
 202        regmap_update_bits(gcr_regmap, NPCM_USB1PHYCTL_OFFSET,
 203                           NPCM_USBXPHYCTL_RS, 0);
 204        regmap_update_bits(gcr_regmap, NPCM_USB2PHYCTL_OFFSET,
 205                           NPCM_USBXPHYCTL_RS, 0);
 206
 207        /* deassert reset USB PHY */
 208        iprst3 &= ~(NPCM_IPSRST3_USBPHY1 | NPCM_IPSRST3_USBPHY2);
 209        writel(iprst3, rc->base + NPCM_IPSRST3);
 210
 211        udelay(50);
 212
 213        /* set USB PHY RS bit */
 214        regmap_update_bits(gcr_regmap, NPCM_USB1PHYCTL_OFFSET,
 215                           NPCM_USBXPHYCTL_RS, NPCM_USBXPHYCTL_RS);
 216        regmap_update_bits(gcr_regmap, NPCM_USB2PHYCTL_OFFSET,
 217                           NPCM_USBXPHYCTL_RS, NPCM_USBXPHYCTL_RS);
 218
 219        /* deassert reset USB devices*/
 220        iprst1 &= ~ipsrst1_bits;
 221        iprst2 &= ~ipsrst2_bits;
 222        iprst3 &= ~ipsrst3_bits;
 223
 224        writel(iprst1, rc->base + NPCM_IPSRST1);
 225        writel(iprst2, rc->base + NPCM_IPSRST2);
 226        writel(iprst3, rc->base + NPCM_IPSRST3);
 227
 228        return 0;
 229}
 230
 231static const struct reset_control_ops npcm_rc_ops = {
 232        .assert         = npcm_rc_assert,
 233        .deassert       = npcm_rc_deassert,
 234        .status         = npcm_rc_status,
 235};
 236
 237static int npcm_rc_probe(struct platform_device *pdev)
 238{
 239        struct npcm_rc_data *rc;
 240        int ret;
 241
 242        rc = devm_kzalloc(&pdev->dev, sizeof(*rc), GFP_KERNEL);
 243        if (!rc)
 244                return -ENOMEM;
 245
 246        rc->base = devm_platform_ioremap_resource(pdev, 0);
 247        if (IS_ERR(rc->base))
 248                return PTR_ERR(rc->base);
 249
 250        spin_lock_init(&rc->lock);
 251
 252        rc->rcdev.owner = THIS_MODULE;
 253        rc->rcdev.ops = &npcm_rc_ops;
 254        rc->rcdev.of_node = pdev->dev.of_node;
 255        rc->rcdev.of_reset_n_cells = 2;
 256        rc->rcdev.of_xlate = npcm_reset_xlate;
 257
 258        platform_set_drvdata(pdev, rc);
 259
 260        ret = devm_reset_controller_register(&pdev->dev, &rc->rcdev);
 261        if (ret) {
 262                dev_err(&pdev->dev, "unable to register device\n");
 263                return ret;
 264        }
 265
 266        if (npcm_usb_reset(pdev, rc))
 267                dev_warn(&pdev->dev, "NPCM USB reset failed, can cause issues with UDC and USB host\n");
 268
 269        if (!of_property_read_u32(pdev->dev.of_node, "nuvoton,sw-reset-number",
 270                                  &rc->sw_reset_number)) {
 271                if (rc->sw_reset_number && rc->sw_reset_number < 5) {
 272                        rc->restart_nb.priority = 192,
 273                        rc->restart_nb.notifier_call = npcm_rc_restart,
 274                        ret = register_restart_handler(&rc->restart_nb);
 275                        if (ret)
 276                                dev_warn(&pdev->dev, "failed to register restart handler\n");
 277                }
 278        }
 279
 280        return ret;
 281}
 282
 283static struct platform_driver npcm_rc_driver = {
 284        .probe  = npcm_rc_probe,
 285        .driver = {
 286                .name                   = "npcm-reset",
 287                .of_match_table         = npcm_rc_match,
 288                .suppress_bind_attrs    = true,
 289        },
 290};
 291builtin_platform_driver(npcm_rc_driver);
 292