Skip to content

Reset Controller Driver #43073

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@
/drivers/pwm/*gecko* @sun681
/drivers/pwm/*it8xxx2* @RuibinChang
/drivers/regulator/*pmic* @danieldegrasse
/drivers/reset/ @andrei-edward-popa
/drivers/sensor/ @MaureenHelm
/drivers/sensor/ams_iAQcore/ @alexanderwachter
/drivers/sensor/ens210/ @alexanderwachter
Expand Down
1 change: 1 addition & 0 deletions boards/arm/rpi_pico/rpi_pico_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ CONFIG_GPIO=y
CONFIG_USE_DT_CODE_PARTITION=y
CONFIG_BUILD_OUTPUT_UF2=y
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_RESET=y
5 changes: 5 additions & 0 deletions doc/reference/api/overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,11 @@ current :ref:`stability level <api_lifecycle>`.
- 2.4
- 2.4

* - :ref:`reset_api`
- Experimental
- 3.1
- 3.1

* - :ref:`spi_api`
- Stable
- 1.0
Expand Down
8 changes: 8 additions & 0 deletions doc/reference/devicetree/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,14 @@ properties related to them.

.. doxygengroup:: devicetree-pwms

Reset Controller
================

These conveniences may be used for nodes which describe reset controllers and
properties related to them.

.. doxygengroup:: devicetree-reset-controller

SPI
===

Expand Down
1 change: 1 addition & 0 deletions doc/reference/peripherals/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Peripherals
ps2.rst
peci.rst
regulators.rst
reset.rst
rtc.rst
sensor.rst
spi.rst
Expand Down
28 changes: 28 additions & 0 deletions doc/reference/peripherals/reset.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
.. _reset_api:

Reset Controller
################

Overview
********

Reset controllers are units that control the reset signals to multiple
peripherals. The reset controller API allows peripheral drivers to request
control over their reset input signals, including the ability to assert,
deassert and toggle those signals. Also, the reset status of the reset input
signal can be checked.

Mainly, the assert and deassert API functions are optional because in most
cases we want to toggle the reset signals.

Configuration Options
*********************

Related configuration options:

* :kconfig:option:`CONFIG_RESET`

API Reference
*************

.. doxygengroup:: reset_controller_interface
1 change: 1 addition & 0 deletions drivers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,4 @@ add_subdirectory_ifdef(CONFIG_PINCTRL pinctrl)
add_subdirectory_ifdef(CONFIG_MBOX mbox)
add_subdirectory_ifdef(CONFIG_BOARD_XENVM xen)
add_subdirectory_ifdef(CONFIG_MM_DRV mm)
add_subdirectory_ifdef(CONFIG_RESET reset)
2 changes: 2 additions & 0 deletions drivers/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,6 @@ source "drivers/power_domain/Kconfig"

source "drivers/usbc/Kconfig"

source "drivers/reset/Kconfig"

endmenu
4 changes: 4 additions & 0 deletions drivers/reset/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# SPDX-License-Identifier: Apache-2.0

zephyr_library()
zephyr_library_sources_ifdef(CONFIG_RESET_RPI_PICO reset_rpi_pico.c)
32 changes: 32 additions & 0 deletions drivers/reset/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Reset Controller driver configuration options

# Copyright (c) 2022 Andrei-Edward Popa <[email protected]>
# SPDX-License-Identifier: Apache-2.0

#
# Reset Controller options
#
menuconfig RESET
bool "Reset Controller drivers"
help
Reset Controller drivers. Reset node represents a region containing
information about reset controller device. The typical use-case is
for some other node's drivers to acquire a reference to the reset
controller node together with some reset information.

if RESET

config RESET_INIT_PRIORITY
int "Reset Controller driver init priority"
default 40
help
This option controls the priority of the reset controller device
initialization. Higher priority ensures that the device is
initialized earlier in the startup cycle. If unsure, leave at default
value

comment "Reset Controller Drivers"

rsource "Kconfig.rpi_pico"

endif # RESET
9 changes: 9 additions & 0 deletions drivers/reset/Kconfig.rpi_pico
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2022 Andrei-Edward Popa
# SPDX-License-Identifier: Apache-2.0

# Workaround for not being able to have commas in macro arguments
DT_COMPAT_RPI_PICO_RESET := raspberrypi,pico-reset

config RESET_RPI_PICO
bool "Raspberry Pi Reset Controller driver"
default $(dt_compat_enabled,$(DT_COMPAT_RPI_PICO_RESET))
159 changes: 159 additions & 0 deletions drivers/reset/reset_rpi_pico.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/*
* Copyright (c) 2022 Andrei-Edward Popa
*
* SPDX-License-Identifier: Apache-2.0
*/

#define DT_DRV_COMPAT raspberrypi_pico_reset

#include <device.h>
#include <drivers/reset.h>

struct reset_rpi_config {
DEVICE_MMIO_ROM;
uint8_t reg_width;
uint8_t active_low;
uintptr_t base_address;
};

static int reset_rpi_read_register(const struct device *dev, uint16_t offset, uint32_t *value)
{
const struct reset_rpi_config *config = dev->config;
uint32_t base_address = config->base_address;

switch (config->reg_width) {
case 1:
*value = sys_read8(base_address + offset);
break;
case 2:
*value = sys_read16(base_address + offset);
break;
case 4:
*value = sys_read32(base_address + offset);
break;
default:
return -EINVAL;
}

return 0;
}

static int reset_rpi_write_register(const struct device *dev, uint16_t offset, uint32_t value)
{
const struct reset_rpi_config *config = dev->config;
uint32_t base_address = config->base_address;

switch (config->reg_width) {
case 1:
sys_write8(value, base_address + offset);
break;
case 2:
sys_write16(value, base_address + offset);
break;
case 4:
sys_write32(value, base_address + offset);
break;
default:
return -EINVAL;
}

return 0;
}

static int reset_rpi_status(const struct device *dev, uint32_t id, uint8_t *status)
{
const struct reset_rpi_config *config = dev->config;
uint16_t offset;
uint32_t value;
uint8_t regbit;
int ret;

offset = id / (config->reg_width * CHAR_BIT);
regbit = id % (config->reg_width * CHAR_BIT);

ret = reset_rpi_read_register(dev, offset, &value);
if (ret) {
return ret;
}

*status = !(value & BIT(regbit)) ^ !config->active_low;

return ret;
}

static int reset_rpi_update(const struct device *dev, uint32_t id, uint8_t assert)
{
const struct reset_rpi_config *config = dev->config;
uint16_t offset;
uint32_t value;
uint8_t regbit;
int ret;

offset = id / (config->reg_width * CHAR_BIT);
regbit = id % (config->reg_width * CHAR_BIT);

ret = reset_rpi_read_register(dev, offset, &value);
if (ret) {
return ret;
}

if (assert ^ config->active_low) {
value |= BIT(regbit);
} else {
value &= ~BIT(regbit);
}

return reset_rpi_write_register(dev, offset, value);
}

static int reset_rpi_assert(const struct device *dev, uint32_t id)
{
return reset_rpi_update(dev, id, 1);
}

static int reset_rpi_deassert(const struct device *dev, uint32_t id)
{
return reset_rpi_update(dev, id, 0);
}

static int reset_rpi_toggle(const struct device *dev, uint32_t id)
{
int ret;

ret = reset_rpi_assert(dev, id);
if (ret) {
return ret;
}

return reset_rpi_deassert(dev, id);
}

static int reset_rpi_init(const struct device *dev)
{
DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE);

return 0;
}

static const struct reset_driver_api reset_rpi_driver_api = {
.status = reset_rpi_status,
.assert = reset_rpi_assert,
.deassert = reset_rpi_deassert,
.toggle = reset_rpi_toggle,
};

#define RPI_RESET_INIT(idx) \
static const struct reset_rpi_config reset_rpi_config_##idx = { \
DEVICE_MMIO_ROM_INIT(DT_DRV_INST(idx)), \
.reg_width = DT_INST_PROP_OR(idx, reg_width, 4), \
.active_low = DT_INST_PROP_OR(idx, active_low, 0), \
.base_address = DT_INST_REG_ADDR(idx), \
}; \
\
DEVICE_DT_INST_DEFINE(idx, reset_rpi_init, \
NULL, NULL, \
&reset_rpi_config_##idx, PRE_KERNEL_1, \
CONFIG_RESET_INIT_PRIORITY, \
&reset_rpi_driver_api);

DT_INST_FOREACH_STATUS_OKAY(RPI_RESET_INIT);
1 change: 1 addition & 0 deletions drivers/serial/Kconfig.rpi_pico
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ config UART_RPI_PICO
select SERIAL_HAS_DRIVER
select PICOSDK_USE_UART
select SERIAL_SUPPORT_INTERRUPT
depends on RESET
5 changes: 4 additions & 1 deletion drivers/serial/uart_rpi_pico.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

#include <drivers/uart.h>
#include <drivers/reset.h>
#include <drivers/pinctrl.h>

/* pico-sdk includes */
Expand All @@ -17,6 +18,7 @@ struct uart_rpi_config {
uart_inst_t *const uart_dev;
uart_hw_t *const uart_regs;
const struct pinctrl_dev_config *pcfg;
const struct reset_dt_spec reset;
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
uart_irq_config_func_t irq_config_func;
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
Expand Down Expand Up @@ -70,7 +72,7 @@ static int uart_rpi_init(const struct device *dev)

/*
* uart_init() may be replaced by register based API once rpi-pico platform
* has a clock controller driver and a reset controller driver
* has a clock controller driver
*/
baudrate = uart_init(uart_inst, data->baudrate);
/* Check if baudrate adjustment returned by 'uart_init' function is a positive value */
Expand Down Expand Up @@ -302,6 +304,7 @@ static const struct uart_driver_api uart_rpi_driver_api = {
.uart_dev = uart##idx, \
.uart_regs = (uart_hw_t *)uart##idx, \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \
.reset = RESET_DT_SPEC_INST_GET(idx), \
RPI_UART_IRQ_CONFIG_INIT(idx), \
}; \
\
Expand Down
11 changes: 11 additions & 0 deletions dts/arm/rpi_pico/rp2040.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@
#clock-cells = <0>;
};

reset: reset-controller@4000c000 {
compatible = "raspberrypi,pico-reset";
reg = <0x4000c000 DT_SIZE_K(4)>;
reg-width = <4>;
active-low = <0>;
#reset-cells = <1>;
label = "RESET";
};

pinctrl: pin-controller@40014000 {
compatible = "raspberrypi,pico-pinctrl";
reg = <0x40014000 DT_SIZE_K(4)>;
Expand All @@ -73,6 +82,7 @@
compatible = "raspberrypi,pico-uart";
reg = <0x40034000 DT_SIZE_K(4)>;
clocks = <&peripheral_clk>;
resets = <&reset RPI_PICO_RESETS_RESET_UART0>;
interrupts = <20 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
interrupt-names = "uart0";
label = "UART_0";
Expand All @@ -83,6 +93,7 @@
compatible = "raspberrypi,pico-uart";
reg = <0x40038000 DT_SIZE_K(4)>;
clocks = <&peripheral_clk>;
resets = <&reset RPI_PICO_RESETS_RESET_UART1>;
interrupts = <21 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
interrupt-names = "uart1";
label = "UART_1";
Expand Down
26 changes: 26 additions & 0 deletions dts/arm/rpi_pico/rpi_pico_common.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,29 @@
#ifndef RPI_PICO_DEFAULT_IRQ_PRIORITY
#define RPI_PICO_DEFAULT_IRQ_PRIORITY 3
#endif

#define RPI_PICO_RESETS_RESET_ADC 0
#define RPI_PICO_RESETS_RESET_BUSCTRL 1
#define RPI_PICO_RESETS_RESET_DMA 2
#define RPI_PICO_RESETS_RESET_I2C0 3
#define RPI_PICO_RESETS_RESET_I2C1 4
#define RPI_PICO_RESETS_RESET_IO_BANK0 5
#define RPI_PICO_RESETS_RESET_IO_QSPI 6
#define RPI_PICO_RESETS_RESET_JTAG 7
#define RPI_PICO_RESETS_RESET_PADS_BANK0 8
#define RPI_PICO_RESETS_RESET_PADS_QSPI 9
#define RPI_PICO_RESETS_RESET_PIO0 10
#define RPI_PICO_RESETS_RESET_PIO1 11
#define RPI_PICO_RESETS_RESET_PLL_SYS 12
#define RPI_PICO_RESETS_RESET_PLL_USB 13
#define RPI_PICO_RESETS_RESET_PWM 14
#define RPI_PICO_RESETS_RESET_RTC 15
#define RPI_PICO_RESETS_RESET_SPI0 16
#define RPI_PICO_RESETS_RESET_SPI1 17
#define RPI_PICO_RESETS_RESET_SYSCFG 18
#define RPI_PICO_RESETS_RESET_SYSINFO 19
#define RPI_PICO_RESETS_RESET_TBMAN 20
#define RPI_PICO_RESETS_RESET_TIMER 21
#define RPI_PICO_RESETS_RESET_UART0 22
#define RPI_PICO_RESETS_RESET_UART1 23
#define RPI_PICO_RESETS_RESET_USBCTRL 24
Loading