-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
drivers: clock: siwx917: Add dumb clock driver
This driver is mostly the initial seed for further implementation of a real clock driver. Currently, sinc ethe driver do not enable the clock sources, this driver still contains the series of #ifdef to enable the clocks. It also doesn't allow the user to choose the clock source for the various peripherals. The driver hardcodes some sane values. Signed-off-by: Jérôme Pouiller <[email protected]>
- Loading branch information
1 parent
7fbc583
commit af6a902
Showing
10 changed files
with
288 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Copyright (c) 2024 Silicon Laboratories Inc. | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
zephyr_library_amend() | ||
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_SILABS_SIWX917 clock_control_silabs_siwx917.c) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Copyright (c) 2024 Silicon Laboratories Inc. | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
if CLOCK_CONTROL | ||
|
||
rsource "Kconfig.siwx917" | ||
|
||
endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Copyright (c) 2024 Silicon Laboratories Inc. | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
config CLOCK_CONTROL_SILABS_SIWX917 | ||
bool "SiWx917 clock control driver" | ||
default y | ||
depends on DT_HAS_SILABS_SIWX917_CLOCK_ENABLED | ||
help | ||
Enable clock management on Silicon Labs SiWx917 chips. This driver | ||
includes support for HP (High Performace), ULP (Ultra Low Power), and | ||
ULP VBAT locks. | ||
|
||
The original hardware allow to customize the various clocks offered for | ||
every devices. This driver does not provide such customizations. It | ||
just hardcodes sane default parameters for every devices. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
/* Copyright (c) 2024 Silicon Laboratories Inc. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Poor man driver for 917 clocks. 917 includes High Performace (HP) clock | ||
* (@46000000), Ultra Lower Power (ULP) clock (@24041400) and ULP VBAT (@24048000) | ||
* | ||
*/ | ||
#include <zephyr/dt-bindings/clock/silabs/siwx917-clock.h> | ||
#include <zephyr/drivers/clock_control.h> | ||
#include <zephyr/logging/log.h> | ||
|
||
#include "rsi_power_save.h" | ||
#include "rsi_rom_ulpss_clk.h" | ||
#include "rsi_rom_clks.h" | ||
#include "sl_si91x_clock_manager.h" | ||
|
||
#define DT_DRV_COMPAT silabs_siwx917_clock | ||
|
||
LOG_MODULE_REGISTER(siwx917_clock, CONFIG_CLOCK_CONTROL_LOG_LEVEL); | ||
|
||
struct siwx917_clock_data { | ||
uint32_t enable; | ||
}; | ||
|
||
static int siwx917_clock_on(const struct device *dev, clock_control_subsys_t sys) | ||
{ | ||
struct siwx917_clock_data *data = dev->data; | ||
uintptr_t clockid = (uintptr_t)sys; | ||
|
||
switch (clockid) { | ||
case SIWX917_CLK_ULP_UART: | ||
RSI_PS_UlpssPeriPowerUp(ULPSS_PWRGATE_ULP_UART); | ||
RSI_ULPSS_UlpUartClkConfig(ULPCLK, ENABLE_STATIC_CLK, | ||
false, ULP_UART_ULP_32MHZ_RC_CLK, 1); | ||
break; | ||
case SIWX917_CLK_ULP_I2C: | ||
RSI_PS_UlpssPeriPowerUp(ULPSS_PWRGATE_ULP_I2C); | ||
RSI_ULPSS_PeripheralEnable(ULPCLK, ULP_I2C_CLK, ENABLE_STATIC_CLK); | ||
break; | ||
case SIWX917_CLK_ULP_DMA: | ||
RSI_PS_UlpssPeriPowerUp(ULPSS_PWRGATE_ULP_UDMA); | ||
RSI_ULPSS_PeripheralEnable(ULPCLK, ULP_UDMA_CLK, ENABLE_STATIC_CLK); | ||
break; | ||
case SIWX917_CLK_UART1: | ||
RSI_PS_M4ssPeriPowerUp(M4SS_PWRGATE_ULP_EFUSE_PERI); | ||
/* RSI_CLK_UsartClkConfig() calls RSI_CLK_PeripheralClkEnable(); */ | ||
RSI_CLK_UsartClkConfig(M4CLK, ENABLE_STATIC_CLK, 0, USART1, 0, 1); | ||
break; | ||
case SIWX917_CLK_UART2: | ||
RSI_PS_M4ssPeriPowerUp(M4SS_PWRGATE_ULP_EFUSE_PERI); | ||
/* RSI_CLK_UsartClkConfig() calls RSI_CLK_PeripheralClkEnable(); */ | ||
RSI_CLK_UsartClkConfig(M4CLK, ENABLE_STATIC_CLK, 0, USART2, 0, 1); | ||
break; | ||
case SIWX917_CLK_I2C0: | ||
RSI_PS_M4ssPeriPowerUp(M4SS_PWRGATE_ULP_EFUSE_PERI); | ||
RSI_CLK_I2CClkConfig(M4CLK, true, 0); | ||
break; | ||
case SIWX917_CLK_I2C1: | ||
RSI_PS_M4ssPeriPowerUp(M4SS_PWRGATE_ULP_EFUSE_PERI); | ||
RSI_CLK_I2CClkConfig(M4CLK, true, 1); | ||
break; | ||
case SIWX917_CLK_DMA0: | ||
RSI_PS_M4ssPeriPowerUp(M4SS_PWRGATE_ULP_EFUSE_PERI); | ||
RSI_CLK_PeripheralClkEnable(M4CLK, UDMA_CLK, ENABLE_STATIC_CLK); | ||
break; | ||
default: | ||
return -EINVAL; | ||
} | ||
data->enable |= BIT(clockid); | ||
|
||
return 0; | ||
} | ||
|
||
static int siwx917_clock_off(const struct device *dev, clock_control_subsys_t sys) | ||
{ | ||
struct siwx917_clock_data *data = dev->data; | ||
uintptr_t clockid = (uintptr_t)sys; | ||
|
||
switch (clockid) { | ||
case SIWX917_CLK_ULP_I2C: | ||
RSI_ULPSS_PeripheralDisable(ULPCLK, ULP_I2C_CLK); | ||
break; | ||
case SIWX917_CLK_ULP_DMA: | ||
RSI_ULPSS_PeripheralDisable(ULPCLK, ULP_UDMA_CLK); | ||
break; | ||
case SIWX917_CLK_UART1: | ||
RSI_CLK_PeripheralClkDisable(M4CLK, USART1_CLK); | ||
break; | ||
case SIWX917_CLK_UART2: | ||
RSI_CLK_PeripheralClkDisable(M4CLK, USART2_CLK); | ||
break; | ||
case SIWX917_CLK_DMA0: | ||
RSI_CLK_PeripheralClkDisable(M4CLK, UDMA_CLK); | ||
break; | ||
case SIWX917_CLK_ULP_UART: | ||
case SIWX917_CLK_I2C0: | ||
case SIWX917_CLK_I2C1: | ||
/* Not supported */ | ||
return 0; | ||
default: | ||
return -EINVAL; | ||
} | ||
|
||
data->enable &= ~BIT(clockid); | ||
return 0; | ||
} | ||
|
||
static int siwx917_clock_get_rate(const struct device *dev, clock_control_subsys_t sys, | ||
uint32_t *rate) | ||
{ | ||
uintptr_t clockid = (uintptr_t)sys; | ||
|
||
switch (clockid) { | ||
case SIWX917_CLK_ULP_UART: | ||
*rate = 32000000; | ||
return 0; | ||
case SIWX917_CLK_UART1: | ||
*rate = 25000000; | ||
return 0; | ||
case SIWX917_CLK_UART2: | ||
*rate = 20000000; | ||
return 0; | ||
default: | ||
/* For now, no other driver need clock rate */ | ||
return -EINVAL; | ||
} | ||
} | ||
|
||
static enum clock_control_status siwx917_clock_get_status(const struct device *dev, | ||
clock_control_subsys_t sys) | ||
{ | ||
struct siwx917_clock_data *data = dev->data; | ||
uintptr_t clockid = (uintptr_t)sys; | ||
|
||
if (data->enable & BIT(clockid)) { | ||
return CLOCK_CONTROL_STATUS_ON; | ||
} else { | ||
return CLOCK_CONTROL_STATUS_OFF; | ||
} | ||
} | ||
|
||
static int siwx917_clock_init(const struct device *dev) | ||
{ | ||
SystemCoreClockUpdate(); | ||
|
||
/* Use SoC PLL at configured frequency as core clock */ | ||
sl_si91x_clock_manager_m4_set_core_clk(M4_SOCPLLCLK, CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC); | ||
|
||
/* Use interface PLL at configured frequency as peripheral clock */ | ||
sl_si91x_clock_manager_set_pll_freq(INFT_PLL, CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC, | ||
PLL_REF_CLK_VAL_XTAL); | ||
|
||
/* FIXME: Currently the clock consumer use clocks without power on them. | ||
* This should be fixed in drivers. Meanwhile, get the list of required | ||
* clocks using DT labels. | ||
*/ | ||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(ulpuart), okay) | ||
siwx917_clock_on(dev, (clock_control_subsys_t)SIWX917_CLK_ULP_UART); | ||
#endif | ||
|
||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(ulpi2c), okay) | ||
siwx917_clock_on(dev, (clock_control_subsys_t)SIWX917_CLK_ULP_I2C); | ||
#endif | ||
|
||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(ulpdma), okay) | ||
siwx917_clock_on(dev, (clock_control_subsys_t)SIWX917_CLK_ULP_DMA); | ||
#endif | ||
|
||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart1), okay) | ||
siwx917_clock_on(dev, (clock_control_subsys_t)SIWX917_CLK_UART1); | ||
#endif | ||
|
||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart2), okay) | ||
siwx917_clock_on(dev, (clock_control_subsys_t)SIWX917_CLK_UART2); | ||
#endif | ||
|
||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c0), okay) | ||
siwx917_clock_on(dev, (clock_control_subsys_t)SIWX917_CLK_I2C0); | ||
#endif | ||
|
||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) | ||
siwx917_clock_on(dev, (clock_control_subsys_t)SIWX917_CLK_I2C1); | ||
#endif | ||
|
||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(udma0), okay) | ||
siwx917_clock_on(dev, (clock_control_subsys_t)SIWX917_CLK_DMA0); | ||
#endif | ||
|
||
return 0; | ||
} | ||
|
||
static const struct clock_control_driver_api siwx917_clock_api = { | ||
.on = siwx917_clock_on, | ||
.off = siwx917_clock_off, | ||
.get_rate = siwx917_clock_get_rate, | ||
.get_status = siwx917_clock_get_status, | ||
}; | ||
|
||
#define SIWX917_CLOCK_INIT(p) \ | ||
static struct siwx917_clock_data siwx917_clock_data_##p; \ | ||
DEVICE_DT_INST_DEFINE(p, siwx917_clock_init, NULL, &siwx917_clock_data_##p, NULL, \ | ||
PRE_KERNEL_1, CONFIG_CLOCK_CONTROL_INIT_PRIORITY, \ | ||
&siwx917_clock_api); | ||
|
||
DT_INST_FOREACH_STATUS_OKAY(SIWX917_CLOCK_INIT) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Copyright (c) 2024 Silicon Laboratories Inc. | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
description: Clocks embedded on Silabs SiWx917 chips | ||
|
||
compatible: "silabs,siwx917-clock" | ||
|
||
include: [clock-controller.yaml, base.yaml] | ||
|
||
properties: | ||
reg: | ||
required: true | ||
|
||
"#clock-cells": | ||
const: 1 | ||
|
||
clock-cells: | ||
- clkid |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/* Copyright (c) 2024 Silicon Laboratories Inc. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_SILABS_SIWX917_CLOCK_H_ | ||
#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_SILABS_SIWX917_CLOCK_H_ | ||
|
||
#define SIWX917_CLK_ULP_UART 0 | ||
#define SIWX917_CLK_ULP_I2C 1 | ||
#define SIWX917_CLK_ULP_DMA 2 | ||
#define SIWX917_CLK_UART1 3 | ||
#define SIWX917_CLK_UART2 4 | ||
#define SIWX917_CLK_I2C0 5 | ||
#define SIWX917_CLK_I2C1 6 | ||
#define SIWX917_CLK_DMA0 7 | ||
|
||
#endif |
Oops, something went wrong.