cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

realtek_otto_wdt.c (10780B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2
      3/*
      4 * Realtek Otto MIPS platform watchdog
      5 *
      6 * Watchdog timer that will reset the system after timeout, using the selected
      7 * reset mode.
      8 *
      9 * Counter scaling and timeouts:
     10 * - Base prescale of (2 << 25), providing tick duration T_0: 168ms @ 200MHz
     11 * - PRESCALE: logarithmic prescaler adding a factor of {1, 2, 4, 8}
     12 * - Phase 1: Times out after (PHASE1 + 1) × PRESCALE × T_0
     13 *   Generates an interrupt, WDT cannot be stopped after phase 1
     14 * - Phase 2: starts after phase 1, times out after (PHASE2 + 1) × PRESCALE × T_0
     15 *   Resets the system according to RST_MODE
     16 */
     17
     18#include <linux/bits.h>
     19#include <linux/bitfield.h>
     20#include <linux/clk.h>
     21#include <linux/delay.h>
     22#include <linux/interrupt.h>
     23#include <linux/io.h>
     24#include <linux/math.h>
     25#include <linux/minmax.h>
     26#include <linux/module.h>
     27#include <linux/mod_devicetable.h>
     28#include <linux/platform_device.h>
     29#include <linux/property.h>
     30#include <linux/reboot.h>
     31#include <linux/watchdog.h>
     32
     33#define OTTO_WDT_REG_CNTR		0x0
     34#define OTTO_WDT_CNTR_PING		BIT(31)
     35
     36#define OTTO_WDT_REG_INTR		0x4
     37#define OTTO_WDT_INTR_PHASE_1		BIT(31)
     38#define OTTO_WDT_INTR_PHASE_2		BIT(30)
     39
     40#define OTTO_WDT_REG_CTRL		0x8
     41#define OTTO_WDT_CTRL_ENABLE		BIT(31)
     42#define OTTO_WDT_CTRL_PRESCALE		GENMASK(30, 29)
     43#define OTTO_WDT_CTRL_PHASE1		GENMASK(26, 22)
     44#define OTTO_WDT_CTRL_PHASE2		GENMASK(19, 15)
     45#define OTTO_WDT_CTRL_RST_MODE		GENMASK(1, 0)
     46#define OTTO_WDT_MODE_SOC		0
     47#define OTTO_WDT_MODE_CPU		1
     48#define OTTO_WDT_MODE_SOFTWARE		2
     49#define OTTO_WDT_CTRL_DEFAULT		OTTO_WDT_MODE_CPU
     50
     51#define OTTO_WDT_PRESCALE_MAX		3
     52
     53/*
     54 * One higher than the max values contained in PHASE{1,2}, since a value of 0
     55 * corresponds to one tick.
     56 */
     57#define OTTO_WDT_PHASE_TICKS_MAX	32
     58
     59/*
     60 * The maximum reset delay is actually 2×32 ticks, but that would require large
     61 * pretimeout values for timeouts longer than 32 ticks. Limit the maximum timeout
     62 * to 32 + 1 to ensure small pretimeout values can be configured as expected.
     63 */
     64#define OTTO_WDT_TIMEOUT_TICKS_MAX	(OTTO_WDT_PHASE_TICKS_MAX + 1)
     65
     66struct otto_wdt_ctrl {
     67	struct watchdog_device wdev;
     68	struct device *dev;
     69	void __iomem *base;
     70	unsigned int clk_rate_khz;
     71	int irq_phase1;
     72};
     73
     74static int otto_wdt_start(struct watchdog_device *wdev)
     75{
     76	struct otto_wdt_ctrl *ctrl = watchdog_get_drvdata(wdev);
     77	u32 v;
     78
     79	v = ioread32(ctrl->base + OTTO_WDT_REG_CTRL);
     80	v |= OTTO_WDT_CTRL_ENABLE;
     81	iowrite32(v, ctrl->base + OTTO_WDT_REG_CTRL);
     82
     83	return 0;
     84}
     85
     86static int otto_wdt_stop(struct watchdog_device *wdev)
     87{
     88	struct otto_wdt_ctrl *ctrl = watchdog_get_drvdata(wdev);
     89	u32 v;
     90
     91	v = ioread32(ctrl->base + OTTO_WDT_REG_CTRL);
     92	v &= ~OTTO_WDT_CTRL_ENABLE;
     93	iowrite32(v, ctrl->base + OTTO_WDT_REG_CTRL);
     94
     95	return 0;
     96}
     97
     98static int otto_wdt_ping(struct watchdog_device *wdev)
     99{
    100	struct otto_wdt_ctrl *ctrl = watchdog_get_drvdata(wdev);
    101
    102	iowrite32(OTTO_WDT_CNTR_PING, ctrl->base + OTTO_WDT_REG_CNTR);
    103
    104	return 0;
    105}
    106
    107static int otto_wdt_tick_ms(struct otto_wdt_ctrl *ctrl, int prescale)
    108{
    109	return DIV_ROUND_CLOSEST(1 << (25 + prescale), ctrl->clk_rate_khz);
    110}
    111
    112/*
    113 * The timer asserts the PHASE1/PHASE2 IRQs when the number of ticks exceeds
    114 * the value stored in those fields. This means each phase will run for at least
    115 * one tick, so small values need to be clamped to correctly reflect the timeout.
    116 */
    117static inline unsigned int div_round_ticks(unsigned int val, unsigned int tick_duration,
    118		unsigned int min_ticks)
    119{
    120	return max(min_ticks, DIV_ROUND_UP(val, tick_duration));
    121}
    122
    123static int otto_wdt_determine_timeouts(struct watchdog_device *wdev, unsigned int timeout,
    124		unsigned int pretimeout)
    125{
    126	struct otto_wdt_ctrl *ctrl = watchdog_get_drvdata(wdev);
    127	unsigned int pretimeout_ms = pretimeout * 1000;
    128	unsigned int timeout_ms = timeout * 1000;
    129	unsigned int prescale_next = 0;
    130	unsigned int phase1_ticks;
    131	unsigned int phase2_ticks;
    132	unsigned int total_ticks;
    133	unsigned int prescale;
    134	unsigned int tick_ms;
    135	u32 v;
    136
    137	do {
    138		prescale = prescale_next;
    139		if (prescale > OTTO_WDT_PRESCALE_MAX)
    140			return -EINVAL;
    141
    142		tick_ms = otto_wdt_tick_ms(ctrl, prescale);
    143		total_ticks = div_round_ticks(timeout_ms, tick_ms, 2);
    144		phase1_ticks = div_round_ticks(timeout_ms - pretimeout_ms, tick_ms, 1);
    145		phase2_ticks = total_ticks - phase1_ticks;
    146
    147		prescale_next++;
    148	} while (phase1_ticks > OTTO_WDT_PHASE_TICKS_MAX
    149		|| phase2_ticks > OTTO_WDT_PHASE_TICKS_MAX);
    150
    151	v = ioread32(ctrl->base + OTTO_WDT_REG_CTRL);
    152
    153	v &= ~(OTTO_WDT_CTRL_PRESCALE | OTTO_WDT_CTRL_PHASE1 | OTTO_WDT_CTRL_PHASE2);
    154	v |= FIELD_PREP(OTTO_WDT_CTRL_PHASE1, phase1_ticks - 1);
    155	v |= FIELD_PREP(OTTO_WDT_CTRL_PHASE2, phase2_ticks - 1);
    156	v |= FIELD_PREP(OTTO_WDT_CTRL_PRESCALE, prescale);
    157
    158	iowrite32(v, ctrl->base + OTTO_WDT_REG_CTRL);
    159
    160	timeout_ms = total_ticks * tick_ms;
    161	ctrl->wdev.timeout = timeout_ms / 1000;
    162
    163	pretimeout_ms = phase2_ticks * tick_ms;
    164	ctrl->wdev.pretimeout = pretimeout_ms / 1000;
    165
    166	return 0;
    167}
    168
    169static int otto_wdt_set_timeout(struct watchdog_device *wdev, unsigned int val)
    170{
    171	return otto_wdt_determine_timeouts(wdev, val, min(wdev->pretimeout, val - 1));
    172}
    173
    174static int otto_wdt_set_pretimeout(struct watchdog_device *wdev, unsigned int val)
    175{
    176	return otto_wdt_determine_timeouts(wdev, wdev->timeout, val);
    177}
    178
    179static int otto_wdt_restart(struct watchdog_device *wdev, unsigned long reboot_mode,
    180		void *data)
    181{
    182	struct otto_wdt_ctrl *ctrl = watchdog_get_drvdata(wdev);
    183	u32 reset_mode;
    184	u32 v;
    185
    186	disable_irq(ctrl->irq_phase1);
    187
    188	switch (reboot_mode) {
    189	case REBOOT_SOFT:
    190		reset_mode = OTTO_WDT_MODE_SOFTWARE;
    191		break;
    192	case REBOOT_WARM:
    193		reset_mode = OTTO_WDT_MODE_CPU;
    194		break;
    195	default:
    196		reset_mode = OTTO_WDT_MODE_SOC;
    197		break;
    198	}
    199
    200	/* Configure for shortest timeout and wait for reset to occur */
    201	v = FIELD_PREP(OTTO_WDT_CTRL_RST_MODE, reset_mode) | OTTO_WDT_CTRL_ENABLE;
    202	iowrite32(v, ctrl->base + OTTO_WDT_REG_CTRL);
    203
    204	mdelay(3 * otto_wdt_tick_ms(ctrl, 0));
    205
    206	return 0;
    207}
    208
    209static irqreturn_t otto_wdt_phase1_isr(int irq, void *dev_id)
    210{
    211	struct otto_wdt_ctrl *ctrl = dev_id;
    212
    213	iowrite32(OTTO_WDT_INTR_PHASE_1, ctrl->base + OTTO_WDT_REG_INTR);
    214	dev_crit(ctrl->dev, "phase 1 timeout\n");
    215	watchdog_notify_pretimeout(&ctrl->wdev);
    216
    217	return IRQ_HANDLED;
    218}
    219
    220static const struct watchdog_ops otto_wdt_ops = {
    221	.owner = THIS_MODULE,
    222	.start = otto_wdt_start,
    223	.stop = otto_wdt_stop,
    224	.ping = otto_wdt_ping,
    225	.set_timeout = otto_wdt_set_timeout,
    226	.set_pretimeout = otto_wdt_set_pretimeout,
    227	.restart = otto_wdt_restart,
    228};
    229
    230static const struct watchdog_info otto_wdt_info = {
    231	.identity = "Realtek Otto watchdog timer",
    232	.options = WDIOF_KEEPALIVEPING |
    233		WDIOF_MAGICCLOSE |
    234		WDIOF_SETTIMEOUT |
    235		WDIOF_PRETIMEOUT,
    236};
    237
    238static void otto_wdt_clock_action(void *data)
    239{
    240	clk_disable_unprepare(data);
    241}
    242
    243static int otto_wdt_probe_clk(struct otto_wdt_ctrl *ctrl)
    244{
    245	struct clk *clk = devm_clk_get(ctrl->dev, NULL);
    246	int ret;
    247
    248	if (IS_ERR(clk))
    249		return dev_err_probe(ctrl->dev, PTR_ERR(clk), "Failed to get clock\n");
    250
    251	ret = clk_prepare_enable(clk);
    252	if (ret)
    253		return dev_err_probe(ctrl->dev, ret, "Failed to enable clock\n");
    254
    255	ret = devm_add_action_or_reset(ctrl->dev, otto_wdt_clock_action, clk);
    256	if (ret)
    257		return ret;
    258
    259	ctrl->clk_rate_khz = clk_get_rate(clk) / 1000;
    260	if (ctrl->clk_rate_khz == 0)
    261		return dev_err_probe(ctrl->dev, -ENXIO, "Failed to get clock rate\n");
    262
    263	return 0;
    264}
    265
    266static int otto_wdt_probe_reset_mode(struct otto_wdt_ctrl *ctrl)
    267{
    268	static const char *mode_property = "realtek,reset-mode";
    269	const struct fwnode_handle *node = ctrl->dev->fwnode;
    270	int mode_count;
    271	u32 mode;
    272	u32 v;
    273
    274	if (!node)
    275		return -ENXIO;
    276
    277	mode_count = fwnode_property_string_array_count(node, mode_property);
    278	if (mode_count < 0)
    279		return mode_count;
    280	else if (mode_count == 0)
    281		return 0;
    282	else if (mode_count != 1)
    283		return -EINVAL;
    284
    285	if (fwnode_property_match_string(node, mode_property, "soc") == 0)
    286		mode = OTTO_WDT_MODE_SOC;
    287	else if (fwnode_property_match_string(node, mode_property, "cpu") == 0)
    288		mode = OTTO_WDT_MODE_CPU;
    289	else if (fwnode_property_match_string(node, mode_property, "software") == 0)
    290		mode = OTTO_WDT_MODE_SOFTWARE;
    291	else
    292		return -EINVAL;
    293
    294	v = ioread32(ctrl->base + OTTO_WDT_REG_CTRL);
    295	v &= ~OTTO_WDT_CTRL_RST_MODE;
    296	v |= FIELD_PREP(OTTO_WDT_CTRL_RST_MODE, mode);
    297	iowrite32(v, ctrl->base + OTTO_WDT_REG_CTRL);
    298
    299	return 0;
    300}
    301
    302static int otto_wdt_probe(struct platform_device *pdev)
    303{
    304	struct device *dev = &pdev->dev;
    305	struct otto_wdt_ctrl *ctrl;
    306	unsigned int max_tick_ms;
    307	int ret;
    308
    309	ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
    310	if (!ctrl)
    311		return -ENOMEM;
    312
    313	ctrl->dev = dev;
    314	ctrl->base = devm_platform_ioremap_resource(pdev, 0);
    315	if (IS_ERR(ctrl->base))
    316		return PTR_ERR(ctrl->base);
    317
    318	/* Clear any old interrupts and reset initial state */
    319	iowrite32(OTTO_WDT_INTR_PHASE_1 | OTTO_WDT_INTR_PHASE_2,
    320			ctrl->base + OTTO_WDT_REG_INTR);
    321	iowrite32(OTTO_WDT_CTRL_DEFAULT, ctrl->base + OTTO_WDT_REG_CTRL);
    322
    323	ret = otto_wdt_probe_clk(ctrl);
    324	if (ret)
    325		return ret;
    326
    327	ctrl->irq_phase1 = platform_get_irq_byname(pdev, "phase1");
    328	if (ctrl->irq_phase1 < 0)
    329		return ctrl->irq_phase1;
    330
    331	ret = devm_request_irq(dev, ctrl->irq_phase1, otto_wdt_phase1_isr, 0,
    332			"realtek-otto-wdt", ctrl);
    333	if (ret)
    334		return dev_err_probe(dev, ret, "Failed to get IRQ for phase1\n");
    335
    336	ret = otto_wdt_probe_reset_mode(ctrl);
    337	if (ret)
    338		return dev_err_probe(dev, ret, "Invalid reset mode specified\n");
    339
    340	ctrl->wdev.parent = dev;
    341	ctrl->wdev.info = &otto_wdt_info;
    342	ctrl->wdev.ops = &otto_wdt_ops;
    343
    344	/*
    345	 * Since pretimeout cannot be disabled, min. timeout is twice the
    346	 * subsystem resolution. Max. timeout is ca. 43s at a bus clock of 200MHz.
    347	 */
    348	ctrl->wdev.min_timeout = 2;
    349	max_tick_ms = otto_wdt_tick_ms(ctrl, OTTO_WDT_PRESCALE_MAX);
    350	ctrl->wdev.max_hw_heartbeat_ms = max_tick_ms * OTTO_WDT_TIMEOUT_TICKS_MAX;
    351	ctrl->wdev.timeout = min(30U, ctrl->wdev.max_hw_heartbeat_ms / 1000);
    352
    353	watchdog_set_drvdata(&ctrl->wdev, ctrl);
    354	watchdog_init_timeout(&ctrl->wdev, 0, dev);
    355	watchdog_stop_on_reboot(&ctrl->wdev);
    356	watchdog_set_restart_priority(&ctrl->wdev, 128);
    357
    358	ret = otto_wdt_determine_timeouts(&ctrl->wdev, ctrl->wdev.timeout, 1);
    359	if (ret)
    360		return dev_err_probe(dev, ret, "Failed to set timeout\n");
    361
    362	return devm_watchdog_register_device(dev, &ctrl->wdev);
    363}
    364
    365static const struct of_device_id otto_wdt_ids[] = {
    366	{ .compatible = "realtek,rtl8380-wdt" },
    367	{ .compatible = "realtek,rtl8390-wdt" },
    368	{ .compatible = "realtek,rtl9300-wdt" },
    369	{ }
    370};
    371MODULE_DEVICE_TABLE(of, otto_wdt_ids);
    372
    373static struct platform_driver otto_wdt_driver = {
    374	.probe = otto_wdt_probe,
    375	.driver = {
    376		.name = "realtek-otto-watchdog",
    377		.of_match_table	= otto_wdt_ids,
    378	},
    379};
    380module_platform_driver(otto_wdt_driver);
    381
    382MODULE_LICENSE("GPL v2");
    383MODULE_AUTHOR("Sander Vanheule <sander@svanheule.net>");
    384MODULE_DESCRIPTION("Realtek Otto watchdog timer driver");