Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0)
0002 /*
0003  * oxnas SoC reset driver
0004  * based on:
0005  * Microsemi MIPS SoC reset driver
0006  * and ox820_assert_system_reset() written by Ma Hajun <mahaijuns@gmail.com>
0007  *
0008  * Copyright (c) 2013 Ma Hajun <mahaijuns@gmail.com>
0009  * Copyright (c) 2017 Microsemi Corporation
0010  * Copyright (c) 2020 Daniel Golle <daniel@makrotopia.org>
0011  */
0012 #include <linux/delay.h>
0013 #include <linux/io.h>
0014 #include <linux/notifier.h>
0015 #include <linux/mfd/syscon.h>
0016 #include <linux/of_address.h>
0017 #include <linux/of_device.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/reboot.h>
0020 #include <linux/regmap.h>
0021 
0022 /* bit numbers of reset control register */
0023 #define OX820_SYS_CTRL_RST_SCU                0
0024 #define OX820_SYS_CTRL_RST_COPRO              1
0025 #define OX820_SYS_CTRL_RST_ARM0               2
0026 #define OX820_SYS_CTRL_RST_ARM1               3
0027 #define OX820_SYS_CTRL_RST_USBHS              4
0028 #define OX820_SYS_CTRL_RST_USBHSPHYA          5
0029 #define OX820_SYS_CTRL_RST_MACA               6
0030 #define OX820_SYS_CTRL_RST_MAC                OX820_SYS_CTRL_RST_MACA
0031 #define OX820_SYS_CTRL_RST_PCIEA              7
0032 #define OX820_SYS_CTRL_RST_SGDMA              8
0033 #define OX820_SYS_CTRL_RST_CIPHER             9
0034 #define OX820_SYS_CTRL_RST_DDR                10
0035 #define OX820_SYS_CTRL_RST_SATA               11
0036 #define OX820_SYS_CTRL_RST_SATA_LINK          12
0037 #define OX820_SYS_CTRL_RST_SATA_PHY           13
0038 #define OX820_SYS_CTRL_RST_PCIEPHY            14
0039 #define OX820_SYS_CTRL_RST_STATIC             15
0040 #define OX820_SYS_CTRL_RST_GPIO               16
0041 #define OX820_SYS_CTRL_RST_UART1              17
0042 #define OX820_SYS_CTRL_RST_UART2              18
0043 #define OX820_SYS_CTRL_RST_MISC               19
0044 #define OX820_SYS_CTRL_RST_I2S                20
0045 #define OX820_SYS_CTRL_RST_SD                 21
0046 #define OX820_SYS_CTRL_RST_MACB               22
0047 #define OX820_SYS_CTRL_RST_PCIEB              23
0048 #define OX820_SYS_CTRL_RST_VIDEO              24
0049 #define OX820_SYS_CTRL_RST_DDR_PHY            25
0050 #define OX820_SYS_CTRL_RST_USBHSPHYB          26
0051 #define OX820_SYS_CTRL_RST_USBDEV             27
0052 #define OX820_SYS_CTRL_RST_ARMDBG             29
0053 #define OX820_SYS_CTRL_RST_PLLA               30
0054 #define OX820_SYS_CTRL_RST_PLLB               31
0055 
0056 /* bit numbers of clock control register */
0057 #define OX820_SYS_CTRL_CLK_COPRO              0
0058 #define OX820_SYS_CTRL_CLK_DMA                1
0059 #define OX820_SYS_CTRL_CLK_CIPHER             2
0060 #define OX820_SYS_CTRL_CLK_SD                 3
0061 #define OX820_SYS_CTRL_CLK_SATA               4
0062 #define OX820_SYS_CTRL_CLK_I2S                5
0063 #define OX820_SYS_CTRL_CLK_USBHS              6
0064 #define OX820_SYS_CTRL_CLK_MACA               7
0065 #define OX820_SYS_CTRL_CLK_MAC                OX820_SYS_CTRL_CLK_MACA
0066 #define OX820_SYS_CTRL_CLK_PCIEA              8
0067 #define OX820_SYS_CTRL_CLK_STATIC             9
0068 #define OX820_SYS_CTRL_CLK_MACB               10
0069 #define OX820_SYS_CTRL_CLK_PCIEB              11
0070 #define OX820_SYS_CTRL_CLK_REF600             12
0071 #define OX820_SYS_CTRL_CLK_USBDEV             13
0072 #define OX820_SYS_CTRL_CLK_DDR                14
0073 #define OX820_SYS_CTRL_CLK_DDRPHY             15
0074 #define OX820_SYS_CTRL_CLK_DDRCK              16
0075 
0076 /* Regmap offsets */
0077 #define OX820_CLK_SET_REGOFFSET               0x2c
0078 #define OX820_CLK_CLR_REGOFFSET               0x30
0079 #define OX820_RST_SET_REGOFFSET               0x34
0080 #define OX820_RST_CLR_REGOFFSET               0x38
0081 #define OX820_SECONDARY_SEL_REGOFFSET         0x14
0082 #define OX820_TERTIARY_SEL_REGOFFSET          0x8c
0083 #define OX820_QUATERNARY_SEL_REGOFFSET        0x94
0084 #define OX820_DEBUG_SEL_REGOFFSET             0x9c
0085 #define OX820_ALTERNATIVE_SEL_REGOFFSET       0xa4
0086 #define OX820_PULLUP_SEL_REGOFFSET            0xac
0087 #define OX820_SEC_SECONDARY_SEL_REGOFFSET     0x100014
0088 #define OX820_SEC_TERTIARY_SEL_REGOFFSET      0x10008c
0089 #define OX820_SEC_QUATERNARY_SEL_REGOFFSET    0x100094
0090 #define OX820_SEC_DEBUG_SEL_REGOFFSET         0x10009c
0091 #define OX820_SEC_ALTERNATIVE_SEL_REGOFFSET   0x1000a4
0092 #define OX820_SEC_PULLUP_SEL_REGOFFSET        0x1000ac
0093 
0094 struct oxnas_restart_context {
0095     struct regmap *sys_ctrl;
0096     struct notifier_block restart_handler;
0097 };
0098 
0099 static int ox820_restart_handle(struct notifier_block *this,
0100                  unsigned long mode, void *cmd)
0101 {
0102     struct oxnas_restart_context *ctx = container_of(this, struct
0103                             oxnas_restart_context,
0104                             restart_handler);
0105     u32 value;
0106 
0107     /*
0108      * Assert reset to cores as per power on defaults
0109      * Don't touch the DDR interface as things will come to an impromptu
0110      * stop NB Possibly should be asserting reset for PLLB, but there are
0111      * timing concerns here according to the docs
0112      */
0113     value = BIT(OX820_SYS_CTRL_RST_COPRO)       |
0114         BIT(OX820_SYS_CTRL_RST_USBHS)       |
0115         BIT(OX820_SYS_CTRL_RST_USBHSPHYA)   |
0116         BIT(OX820_SYS_CTRL_RST_MACA)        |
0117         BIT(OX820_SYS_CTRL_RST_PCIEA)       |
0118         BIT(OX820_SYS_CTRL_RST_SGDMA)       |
0119         BIT(OX820_SYS_CTRL_RST_CIPHER)      |
0120         BIT(OX820_SYS_CTRL_RST_SATA)        |
0121         BIT(OX820_SYS_CTRL_RST_SATA_LINK)   |
0122         BIT(OX820_SYS_CTRL_RST_SATA_PHY)    |
0123         BIT(OX820_SYS_CTRL_RST_PCIEPHY)     |
0124         BIT(OX820_SYS_CTRL_RST_STATIC)      |
0125         BIT(OX820_SYS_CTRL_RST_UART1)       |
0126         BIT(OX820_SYS_CTRL_RST_UART2)       |
0127         BIT(OX820_SYS_CTRL_RST_MISC)        |
0128         BIT(OX820_SYS_CTRL_RST_I2S)     |
0129         BIT(OX820_SYS_CTRL_RST_SD)      |
0130         BIT(OX820_SYS_CTRL_RST_MACB)        |
0131         BIT(OX820_SYS_CTRL_RST_PCIEB)       |
0132         BIT(OX820_SYS_CTRL_RST_VIDEO)       |
0133         BIT(OX820_SYS_CTRL_RST_USBHSPHYB)   |
0134         BIT(OX820_SYS_CTRL_RST_USBDEV);
0135 
0136     regmap_write(ctx->sys_ctrl, OX820_RST_SET_REGOFFSET, value);
0137 
0138     /* Release reset to cores as per power on defaults */
0139     regmap_write(ctx->sys_ctrl, OX820_RST_CLR_REGOFFSET,
0140             BIT(OX820_SYS_CTRL_RST_GPIO));
0141 
0142     /*
0143      * Disable clocks to cores as per power-on defaults - must leave DDR
0144      * related clocks enabled otherwise we'll stop rather abruptly.
0145      */
0146     value = BIT(OX820_SYS_CTRL_CLK_COPRO)       |
0147         BIT(OX820_SYS_CTRL_CLK_DMA)     |
0148         BIT(OX820_SYS_CTRL_CLK_CIPHER)      |
0149         BIT(OX820_SYS_CTRL_CLK_SD)      |
0150         BIT(OX820_SYS_CTRL_CLK_SATA)        |
0151         BIT(OX820_SYS_CTRL_CLK_I2S)     |
0152         BIT(OX820_SYS_CTRL_CLK_USBHS)       |
0153         BIT(OX820_SYS_CTRL_CLK_MAC)     |
0154         BIT(OX820_SYS_CTRL_CLK_PCIEA)       |
0155         BIT(OX820_SYS_CTRL_CLK_STATIC)      |
0156         BIT(OX820_SYS_CTRL_CLK_MACB)        |
0157         BIT(OX820_SYS_CTRL_CLK_PCIEB)       |
0158         BIT(OX820_SYS_CTRL_CLK_REF600)      |
0159         BIT(OX820_SYS_CTRL_CLK_USBDEV);
0160 
0161     regmap_write(ctx->sys_ctrl, OX820_CLK_CLR_REGOFFSET, value);
0162 
0163     /* Enable clocks to cores as per power-on defaults */
0164 
0165     /* Set sys-control pin mux'ing as per power-on defaults */
0166     regmap_write(ctx->sys_ctrl, OX820_SECONDARY_SEL_REGOFFSET, 0);
0167     regmap_write(ctx->sys_ctrl, OX820_TERTIARY_SEL_REGOFFSET, 0);
0168     regmap_write(ctx->sys_ctrl, OX820_QUATERNARY_SEL_REGOFFSET, 0);
0169     regmap_write(ctx->sys_ctrl, OX820_DEBUG_SEL_REGOFFSET, 0);
0170     regmap_write(ctx->sys_ctrl, OX820_ALTERNATIVE_SEL_REGOFFSET, 0);
0171     regmap_write(ctx->sys_ctrl, OX820_PULLUP_SEL_REGOFFSET, 0);
0172 
0173     regmap_write(ctx->sys_ctrl, OX820_SEC_SECONDARY_SEL_REGOFFSET, 0);
0174     regmap_write(ctx->sys_ctrl, OX820_SEC_TERTIARY_SEL_REGOFFSET, 0);
0175     regmap_write(ctx->sys_ctrl, OX820_SEC_QUATERNARY_SEL_REGOFFSET, 0);
0176     regmap_write(ctx->sys_ctrl, OX820_SEC_DEBUG_SEL_REGOFFSET, 0);
0177     regmap_write(ctx->sys_ctrl, OX820_SEC_ALTERNATIVE_SEL_REGOFFSET, 0);
0178     regmap_write(ctx->sys_ctrl, OX820_SEC_PULLUP_SEL_REGOFFSET, 0);
0179 
0180     /*
0181      * No need to save any state, as the ROM loader can determine whether
0182      * reset is due to power cycling or programatic action, just hit the
0183      * (self-clearing) CPU reset bit of the block reset register
0184      */
0185     value =
0186         BIT(OX820_SYS_CTRL_RST_SCU) |
0187         BIT(OX820_SYS_CTRL_RST_ARM0) |
0188         BIT(OX820_SYS_CTRL_RST_ARM1);
0189 
0190     regmap_write(ctx->sys_ctrl, OX820_RST_SET_REGOFFSET, value);
0191 
0192     pr_emerg("Unable to restart system\n");
0193     return NOTIFY_DONE;
0194 }
0195 
0196 static int ox820_restart_probe(struct platform_device *pdev)
0197 {
0198     struct oxnas_restart_context *ctx;
0199     struct regmap *sys_ctrl;
0200     struct device *dev = &pdev->dev;
0201     int err = 0;
0202 
0203     sys_ctrl = syscon_node_to_regmap(pdev->dev.of_node);
0204     if (IS_ERR(sys_ctrl))
0205         return PTR_ERR(sys_ctrl);
0206 
0207     ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
0208     if (!ctx)
0209         return -ENOMEM;
0210 
0211     ctx->sys_ctrl = sys_ctrl;
0212     ctx->restart_handler.notifier_call = ox820_restart_handle;
0213     ctx->restart_handler.priority = 192;
0214     err = register_restart_handler(&ctx->restart_handler);
0215     if (err)
0216         dev_err(dev, "can't register restart notifier (err=%d)\n", err);
0217 
0218     return err;
0219 }
0220 
0221 static const struct of_device_id ox820_restart_of_match[] = {
0222     { .compatible = "oxsemi,ox820-sys-ctrl" },
0223     {}
0224 };
0225 
0226 static struct platform_driver ox820_restart_driver = {
0227     .probe = ox820_restart_probe,
0228     .driver = {
0229         .name = "ox820-chip-reset",
0230         .of_match_table = ox820_restart_of_match,
0231     },
0232 };
0233 builtin_platform_driver(ox820_restart_driver);