| .. | .. |
|---|
| 15 | 15 | #include <linux/reboot.h> |
|---|
| 16 | 16 | #include <linux/regmap.h> |
|---|
| 17 | 17 | |
|---|
| 18 | +struct reset_props { |
|---|
| 19 | + const char *syscon; |
|---|
| 20 | + u32 protect_reg; |
|---|
| 21 | + u32 vcore_protect; |
|---|
| 22 | + u32 if_si_owner_bit; |
|---|
| 23 | +}; |
|---|
| 24 | + |
|---|
| 18 | 25 | struct ocelot_reset_context { |
|---|
| 19 | 26 | void __iomem *base; |
|---|
| 20 | 27 | struct regmap *cpu_ctrl; |
|---|
| 28 | + const struct reset_props *props; |
|---|
| 21 | 29 | struct notifier_block restart_handler; |
|---|
| 22 | 30 | }; |
|---|
| 23 | 31 | |
|---|
| 24 | | -#define ICPU_CFG_CPU_SYSTEM_CTRL_RESET 0x20 |
|---|
| 25 | | -#define CORE_RST_PROTECT BIT(2) |
|---|
| 26 | | - |
|---|
| 27 | 32 | #define SOFT_CHIP_RST BIT(0) |
|---|
| 33 | + |
|---|
| 34 | +#define ICPU_CFG_CPU_SYSTEM_CTRL_GENERAL_CTRL 0x24 |
|---|
| 35 | +#define IF_SI_OWNER_MASK GENMASK(1, 0) |
|---|
| 36 | +#define IF_SI_OWNER_SISL 0 |
|---|
| 37 | +#define IF_SI_OWNER_SIBM 1 |
|---|
| 38 | +#define IF_SI_OWNER_SIMC 2 |
|---|
| 28 | 39 | |
|---|
| 29 | 40 | static int ocelot_restart_handle(struct notifier_block *this, |
|---|
| 30 | 41 | unsigned long mode, void *cmd) |
|---|
| .. | .. |
|---|
| 32 | 43 | struct ocelot_reset_context *ctx = container_of(this, struct |
|---|
| 33 | 44 | ocelot_reset_context, |
|---|
| 34 | 45 | restart_handler); |
|---|
| 46 | + u32 if_si_owner_bit = ctx->props->if_si_owner_bit; |
|---|
| 35 | 47 | |
|---|
| 36 | 48 | /* Make sure the core is not protected from reset */ |
|---|
| 37 | | - regmap_update_bits(ctx->cpu_ctrl, ICPU_CFG_CPU_SYSTEM_CTRL_RESET, |
|---|
| 38 | | - CORE_RST_PROTECT, 0); |
|---|
| 49 | + regmap_update_bits(ctx->cpu_ctrl, ctx->props->protect_reg, |
|---|
| 50 | + ctx->props->vcore_protect, 0); |
|---|
| 51 | + |
|---|
| 52 | + /* Make the SI back to boot mode */ |
|---|
| 53 | + regmap_update_bits(ctx->cpu_ctrl, ICPU_CFG_CPU_SYSTEM_CTRL_GENERAL_CTRL, |
|---|
| 54 | + IF_SI_OWNER_MASK << if_si_owner_bit, |
|---|
| 55 | + IF_SI_OWNER_SIBM << if_si_owner_bit); |
|---|
| 56 | + |
|---|
| 57 | + pr_emerg("Resetting SoC\n"); |
|---|
| 39 | 58 | |
|---|
| 40 | 59 | writel(SOFT_CHIP_RST, ctx->base); |
|---|
| 41 | 60 | |
|---|
| .. | .. |
|---|
| 60 | 79 | if (IS_ERR(ctx->base)) |
|---|
| 61 | 80 | return PTR_ERR(ctx->base); |
|---|
| 62 | 81 | |
|---|
| 63 | | - ctx->cpu_ctrl = syscon_regmap_lookup_by_compatible("mscc,ocelot-cpu-syscon"); |
|---|
| 64 | | - if (IS_ERR(ctx->cpu_ctrl)) |
|---|
| 82 | + ctx->props = device_get_match_data(dev); |
|---|
| 83 | + |
|---|
| 84 | + ctx->cpu_ctrl = syscon_regmap_lookup_by_compatible(ctx->props->syscon); |
|---|
| 85 | + if (IS_ERR(ctx->cpu_ctrl)) { |
|---|
| 86 | + dev_err(dev, "No syscon map: %s\n", ctx->props->syscon); |
|---|
| 65 | 87 | return PTR_ERR(ctx->cpu_ctrl); |
|---|
| 88 | + } |
|---|
| 66 | 89 | |
|---|
| 67 | 90 | ctx->restart_handler.notifier_call = ocelot_restart_handle; |
|---|
| 68 | 91 | ctx->restart_handler.priority = 192; |
|---|
| .. | .. |
|---|
| 73 | 96 | return err; |
|---|
| 74 | 97 | } |
|---|
| 75 | 98 | |
|---|
| 99 | +static const struct reset_props reset_props_ocelot = { |
|---|
| 100 | + .syscon = "mscc,ocelot-cpu-syscon", |
|---|
| 101 | + .protect_reg = 0x20, |
|---|
| 102 | + .vcore_protect = BIT(2), |
|---|
| 103 | + .if_si_owner_bit = 4, |
|---|
| 104 | +}; |
|---|
| 105 | + |
|---|
| 106 | +static const struct reset_props reset_props_sparx5 = { |
|---|
| 107 | + .syscon = "microchip,sparx5-cpu-syscon", |
|---|
| 108 | + .protect_reg = 0x84, |
|---|
| 109 | + .vcore_protect = BIT(10), |
|---|
| 110 | + .if_si_owner_bit = 6, |
|---|
| 111 | +}; |
|---|
| 112 | + |
|---|
| 76 | 113 | static const struct of_device_id ocelot_reset_of_match[] = { |
|---|
| 77 | | - { .compatible = "mscc,ocelot-chip-reset" }, |
|---|
| 78 | | - {} |
|---|
| 114 | + { |
|---|
| 115 | + .compatible = "mscc,ocelot-chip-reset", |
|---|
| 116 | + .data = &reset_props_ocelot |
|---|
| 117 | + }, { |
|---|
| 118 | + .compatible = "microchip,sparx5-chip-reset", |
|---|
| 119 | + .data = &reset_props_sparx5 |
|---|
| 120 | + }, |
|---|
| 121 | + { /*sentinel*/ } |
|---|
| 79 | 122 | }; |
|---|
| 80 | 123 | |
|---|
| 81 | 124 | static struct platform_driver ocelot_reset_driver = { |
|---|