162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Copyright (C) 2012 Thomas Langer <thomas.langer@lantiq.com>
562306a36Sopenharmony_ci * Copyright (C) 2012 John Crispin <john@phrozen.org>
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <linux/init.h>
962306a36Sopenharmony_ci#include <linux/io.h>
1062306a36Sopenharmony_ci#include <linux/pm.h>
1162306a36Sopenharmony_ci#include <asm/reboot.h>
1262306a36Sopenharmony_ci#include <linux/export.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <lantiq_soc.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci/*
1762306a36Sopenharmony_ci * Dummy implementation.  Used to allow platform code to find out what
1862306a36Sopenharmony_ci * source was booted from
1962306a36Sopenharmony_ci */
2062306a36Sopenharmony_ciunsigned char ltq_boot_select(void)
2162306a36Sopenharmony_ci{
2262306a36Sopenharmony_ci	return BS_SPI;
2362306a36Sopenharmony_ci}
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#define BOOT_REG_BASE	(KSEG1 | 0x1F200000)
2662306a36Sopenharmony_ci#define BOOT_PW1_REG	(BOOT_REG_BASE | 0x20)
2762306a36Sopenharmony_ci#define BOOT_PW2_REG	(BOOT_REG_BASE | 0x24)
2862306a36Sopenharmony_ci#define BOOT_PW1	0x4C545100
2962306a36Sopenharmony_ci#define BOOT_PW2	0x0051544C
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci#define WDT_REG_BASE	(KSEG1 | 0x1F8803F0)
3262306a36Sopenharmony_ci#define WDT_PW1		0x00BE0000
3362306a36Sopenharmony_ci#define WDT_PW2		0x00DC0000
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_cistatic void machine_restart(char *command)
3662306a36Sopenharmony_ci{
3762306a36Sopenharmony_ci	local_irq_disable();
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci	/* reboot magic */
4062306a36Sopenharmony_ci	ltq_w32(BOOT_PW1, (void *)BOOT_PW1_REG); /* 'LTQ\0' */
4162306a36Sopenharmony_ci	ltq_w32(BOOT_PW2, (void *)BOOT_PW2_REG); /* '\0QTL' */
4262306a36Sopenharmony_ci	ltq_w32(0, (void *)BOOT_REG_BASE); /* reset Bootreg RVEC */
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	/* watchdog magic */
4562306a36Sopenharmony_ci	ltq_w32(WDT_PW1, (void *)WDT_REG_BASE);
4662306a36Sopenharmony_ci	ltq_w32(WDT_PW2 |
4762306a36Sopenharmony_ci		(0x3 << 26) | /* PWL */
4862306a36Sopenharmony_ci		(0x2 << 24) | /* CLKDIV */
4962306a36Sopenharmony_ci		(0x1 << 31) | /* enable */
5062306a36Sopenharmony_ci		(1), /* reload */
5162306a36Sopenharmony_ci		(void *)WDT_REG_BASE);
5262306a36Sopenharmony_ci	unreachable();
5362306a36Sopenharmony_ci}
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_cistatic void machine_halt(void)
5662306a36Sopenharmony_ci{
5762306a36Sopenharmony_ci	local_irq_disable();
5862306a36Sopenharmony_ci	unreachable();
5962306a36Sopenharmony_ci}
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_cistatic void machine_power_off(void)
6262306a36Sopenharmony_ci{
6362306a36Sopenharmony_ci	local_irq_disable();
6462306a36Sopenharmony_ci	unreachable();
6562306a36Sopenharmony_ci}
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_cistatic int __init mips_reboot_setup(void)
6862306a36Sopenharmony_ci{
6962306a36Sopenharmony_ci	_machine_restart = machine_restart;
7062306a36Sopenharmony_ci	_machine_halt = machine_halt;
7162306a36Sopenharmony_ci	pm_power_off = machine_power_off;
7262306a36Sopenharmony_ci	return 0;
7362306a36Sopenharmony_ci}
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ciarch_initcall(mips_reboot_setup);
76