1 /*
2 * Copyright (c) 2024 Nuvoton Technology Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT nuvoton_npcx_rst
8
9 #include <zephyr/kernel.h>
10 #include <zephyr/drivers/reset.h>
11
12 #if defined(CONFIG_SOC_SERIES_NPCX7)
13 #include <zephyr/dt-bindings/reset/npcx7_reset.h>
14 #elif defined(CONFIG_SOC_SERIES_NPCX9)
15 #include <zephyr/dt-bindings/reset/npcx9_reset.h>
16 #elif defined(CONFIG_SOC_SERIES_NPCX4)
17 #include <zephyr/dt-bindings/reset/npcx4_reset.h>
18 #endif
19
20 #include <zephyr/logging/log.h>
21 LOG_MODULE_REGISTER(rst_npcx);
22
23 #define NPCX_RESET_CTL_REG_BYTE_SIZE 4
24 #define NPCX_RESET_CTL_REG_OFFSET(id) ((id) >> (NPCX_RESET_CTL_REG_BYTE_SIZE + 1))
25 #define NPCX_RESET_CTL_REG_BIT(id) (((id) & ((1 << (NPCX_RESET_CTL_REG_BYTE_SIZE + 1)) - 1)))
26
27 #define NPCX_SWRST_TRG_WORD_START 0xC183
28 #define NPCX_SWRST_TRG_WORD_CLEAR 0x0
29 #define NPCX_SWRST_TRG_WORD_DONE 0xFFFF
30 #define NPCX_SWRST_DONE_TIMEOUT_US 100
31
32 struct reset_npcx_dev_config {
33 struct swrst_reg *reg_base;
34 };
35
reset_npcx_line_toggle(const struct device * dev,uint32_t id)36 static int reset_npcx_line_toggle(const struct device *dev, uint32_t id)
37 {
38 const struct reset_npcx_dev_config *const config = dev->config;
39 struct swrst_reg *const reg = config->reg_base;
40 unsigned int key;
41 uint8_t reg_offset;
42 uint8_t reg_bit;
43 int ret = 0;
44
45 if (!IN_RANGE(id, NPCX_RESET_ID_START, NPCX_RESET_ID_END)) {
46 LOG_ERR("Invalid Reset ID");
47 return -EINVAL;
48 }
49 reg_offset = NPCX_RESET_CTL_REG_OFFSET(id);
50 reg_bit = NPCX_RESET_CTL_REG_BIT(id);
51
52 key = irq_lock();
53
54 reg->SWRST_CTL[reg_offset] |= BIT(reg_bit);
55 reg->SWRST_TRG = NPCX_SWRST_TRG_WORD_CLEAR;
56 reg->SWRST_TRG = NPCX_SWRST_TRG_WORD_START;
57
58 if (!WAIT_FOR((reg->SWRST_TRG == NPCX_SWRST_TRG_WORD_DONE), NPCX_SWRST_DONE_TIMEOUT_US,
59 NULL)) {
60 LOG_ERR("Reset trig timeout");
61 ret = -EBUSY;
62 }
63
64 irq_unlock(key);
65
66 return ret;
67 }
68
69 static DEVICE_API(reset, reset_npcx_driver_api) = {
70 .line_toggle = reset_npcx_line_toggle,
71 };
72
73 static const struct reset_npcx_dev_config reset_npcx_config = {
74 .reg_base = (struct swrst_reg *)DT_INST_REG_ADDR(0),
75 };
76
77 DEVICE_DT_INST_DEFINE(0, NULL, NULL, NULL, &reset_npcx_config, PRE_KERNEL_1,
78 CONFIG_RESET_INIT_PRIORITY, &reset_npcx_driver_api);
79