1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
4  */
5 
6 #include <dm.h>
7 #include <stdbool.h>
8 #include <sysreset.h>
9 #include <wait_bit.h>
10 #include <linux/io.h>
11 #include <linux/errno.h>
12 
13 #define REG_RTC_BASE             (void *)0x05026000
14 #define REG_RTC_CTRL_BASE        (void *)0x05025000
15 #define REG_RTC_EN_SHDN_REQ      (REG_RTC_BASE + 0xc0)
16 #define REG_RTC_EN_PWR_CYC_REQ   (REG_RTC_BASE + 0xc8)
17 #define REG_RTC_EN_WARM_RST_REQ  (REG_RTC_BASE + 0xcc)
18 #define REG_RTC_CTRL_UNLOCKKEY   (REG_RTC_CTRL_BASE + 0x4)
19 #define REG_RTC_CTRL             (REG_RTC_CTRL_BASE + 0x8)
20 
21 #define CTRL_UNLOCKKEY_MAGIC     0xAB18
22 
23 /* REG_RTC_CTRL */
24 #define BIT_REQ_SHDN       BIT(0)
25 #define BIT_REQ_PWR_CYC    BIT(3)
26 #define BIT_REQ_WARM_RST   BIT(4)
27 
28 static struct {
29 	void *pre_req_reg;
30 	u32 req_bit;
31 } reset_info[SYSRESET_COUNT] = {
32 	[SYSRESET_WARM]      = { REG_RTC_EN_WARM_RST_REQ, BIT_REQ_WARM_RST },
33 	[SYSRESET_COLD]      = { REG_RTC_EN_WARM_RST_REQ, BIT_REQ_WARM_RST },
34 	[SYSRESET_POWER]     = { REG_RTC_EN_PWR_CYC_REQ, BIT_REQ_PWR_CYC },
35 	[SYSRESET_POWER_OFF] = { REG_RTC_EN_SHDN_REQ, BIT_REQ_SHDN },
36 };
37 
cv1800b_sysreset_request(struct udevice * dev,enum sysreset_t type)38 static int cv1800b_sysreset_request(struct udevice *dev, enum sysreset_t type)
39 {
40 	u32 reg;
41 
42 	writel(1, reset_info[type].pre_req_reg);
43 	writel(CTRL_UNLOCKKEY_MAGIC, REG_RTC_CTRL_UNLOCKKEY);
44 	reg = readl(REG_RTC_CTRL);
45 	writel(0xFFFF0800 | reset_info[type].req_bit, REG_RTC_CTRL);
46 
47 	return -EINPROGRESS;
48 }
49 
50 static struct sysreset_ops cv1800b_sysreset = {
51 	.request = cv1800b_sysreset_request,
52 };
53 
54 static const struct udevice_id cv1800b_sysreset_ids[] = {
55 	{ .compatible = "sophgo,cv1800b-sysreset", },
56 	{},
57 };
58 
59 U_BOOT_DRIVER(sysreset_cv1800b) = {
60 	.name = "cv1800b_sysreset",
61 	.id	  = UCLASS_SYSRESET,
62 	.ops  = &cv1800b_sysreset,
63 	.of_match = cv1800b_sysreset_ids
64 };
65