drivers: clock_control: rpi_pico: Add support for the RP2350.

Add support for SoC-specific clock ids and update the initialization
function to support the existing RP2040 and add support for the RP2350.

clock_control_rpi_pico.c uses numerical values for clock ids taken from
rpi_pico_clock.h which are the "clock generator". For the RP2350 these
values are different for some of the same logical clock sources, as well
as the RP2040 and RP2350 having different clock sources available.

Signed-off-by: Andrew Featherstone <andrew.featherstone@gmail.com>
This commit is contained in:
Andrew Featherstone 2024-08-21 20:50:36 +01:00 committed by Benjamin Cabé
commit 122784df15
5 changed files with 118 additions and 22 deletions

View file

@ -10,7 +10,11 @@
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/drivers/reset.h>
#include <zephyr/dt-bindings/clock/rpi_pico_clock.h>
#if defined(CONFIG_SOC_SERIES_RP2040)
#include <zephyr/dt-bindings/clock/rpi_pico_rp2040_clock.h>
#else
#include <zephyr/dt-bindings/clock/rpi_pico_rp2350_clock.h>
#endif
#include <hardware/clocks.h>
#include <hardware/xosc.h>
@ -77,6 +81,7 @@
#define CLOCK_FREQ_clk_gpout1 DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, clk_gpout1), clock_frequency)
#define CLOCK_FREQ_clk_gpout2 DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, clk_gpout2), clock_frequency)
#define CLOCK_FREQ_clk_gpout3 DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, clk_gpout3), clock_frequency)
#define CLOCK_FREQ_clk_hstx DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, clk_hstx), clock_frequency)
#define CLOCK_FREQ_clk_ref DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, clk_ref), clock_frequency)
#define CLOCK_FREQ_clk_sys DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, clk_sys), clock_frequency)
#define CLOCK_FREQ_clk_usb DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, clk_usb), clock_frequency)
@ -102,9 +107,16 @@
#define AUXSRC_clk_sys CLK_SYS
#define AUXSRC_clk_usb CLK_USB
#define AUXSRC_clk_adc CLK_ADC
#define AUXSRC_clk_rtc CLK_RTC
#define AUXSRC_clk_gpin0 CLKSRC_GPIN0
#define AUXSRC_clk_gpin1 CLKSRC_GPIN1
#if defined(CONFIG_SOC_SERIES_RP2040)
#define AUXSRC_clk_rtc CLK_RTC
#else
#define AUXSRC_pll_usb_primary_ref_opcg CLKSRC_PLL_PLL_USB_PRIMARY_REF_OPCG
#define AUXSRC_lposc LPOSC_CLKSRC
#define AUXSRC_clk_hstx CLK_HSTX
#define AUXSRC_otp_clk2fc OTP_CLK2FC
#endif
#define AUXSTEM_clk_gpout0 CLOCKS_CLK_GPOUT0_CTRL_AUXSRC_VALUE_
#define AUXSTEM_clk_gpout1 CLOCKS_CLK_GPOUT1_CTRL_AUXSRC_VALUE_
@ -114,8 +126,12 @@
#define AUXSTEM_clk_sys CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_
#define AUXSTEM_clk_usb CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_
#define AUXSTEM_clk_adc CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_
#define AUXSTEM_clk_rtc CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_
#define AUXSTEM_clk_peri CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_
#define AUXSTEM_clk_peri CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_
#if defined(CONFIG_SOC_SERIES_RP2040)
#define AUXSTEM_clk_rtc CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_
#else
#define AUXSTEM_clk_hstx CLOCKS_CLK_HSTX_CTRL_AUXSRC_VALUE_
#endif
#define TUPLE_ENTRY(n, p, i) \
{ \
@ -141,7 +157,9 @@ enum rpi_pico_clkid {
rpi_pico_clkid_clk_peri = RPI_PICO_CLKID_CLK_PERI,
rpi_pico_clkid_clk_usb = RPI_PICO_CLKID_CLK_USB,
rpi_pico_clkid_clk_adc = RPI_PICO_CLKID_CLK_ADC,
#if defined(RPI_PICO_CLKID_CLK_RTC)
rpi_pico_clkid_clk_rtc = RPI_PICO_CLKID_CLK_RTC,
#endif
rpi_pico_clkid_pll_sys = RPI_PICO_CLKID_PLL_SYS,
rpi_pico_clkid_pll_usb = RPI_PICO_CLKID_PLL_USB,
rpi_pico_clkid_xosc = RPI_PICO_CLKID_XOSC,
@ -223,9 +241,11 @@ uint64_t rpi_pico_frequency_count(const struct device *dev, clock_control_subsys
case rpi_pico_clkid_clk_adc:
fc0_id = CLOCKS_FC0_SRC_VALUE_CLK_ADC;
break;
#if defined(CONFIG_SOC_SERIES_RP2040)
case rpi_pico_clkid_clk_rtc:
fc0_id = CLOCKS_FC0_SRC_VALUE_CLK_RTC;
break;
#endif
case rpi_pico_clkid_pll_sys:
fc0_id = CLOCKS_FC0_SRC_VALUE_PLL_SYS_CLKSRC_PRIMARY;
break;
@ -284,10 +304,13 @@ static int rpi_pico_rosc_write(const struct device *dev, io_rw_32 *addr, uint32_
static enum rpi_pico_clkid rpi_pico_get_clock_src(const struct device *dev, enum rpi_pico_clkid id)
{
const struct clock_control_rpi_pico_config *config = dev->config;
enum rpi_pico_clkid srcid = rpi_pico_clkid_none;
enum rpi_pico_clkid srcid;
if (id == rpi_pico_clkid_clk_gpout0 || id == rpi_pico_clkid_clk_gpout1 ||
id == rpi_pico_clkid_clk_gpout2 || id == rpi_pico_clkid_clk_gpout3) {
switch (id) {
case rpi_pico_clkid_clk_gpout0:
case rpi_pico_clkid_clk_gpout1:
case rpi_pico_clkid_clk_gpout2:
case rpi_pico_clkid_clk_gpout3: {
const static enum rpi_pico_clkid table[] = {
rpi_pico_clkid_pll_sys,
rpi_pico_clkid_gpin0,
@ -298,7 +321,9 @@ static enum rpi_pico_clkid rpi_pico_get_clock_src(const struct device *dev, enum
rpi_pico_clkid_clk_sys,
rpi_pico_clkid_clk_usb,
rpi_pico_clkid_clk_adc,
#if defined(CONFIG_SOC_SERIES_RP2040)
rpi_pico_clkid_clk_rtc,
#endif
rpi_pico_clkid_clk_ref,
};
@ -306,7 +331,9 @@ static enum rpi_pico_clkid rpi_pico_get_clock_src(const struct device *dev, enum
uint32_t aux = ((clock_hw->ctrl & CTRL_AUXSRC_BITS) >> CTRL_AUXSRC_LSB);
srcid = table[aux];
} else if (id == rpi_pico_clkid_clk_ref) {
break;
}
case rpi_pico_clkid_clk_ref: {
const static enum rpi_pico_clkid table[] = {
rpi_pico_clkid_pll_usb,
rpi_pico_clkid_gpin0,
@ -324,7 +351,9 @@ static enum rpi_pico_clkid rpi_pico_get_clock_src(const struct device *dev, enum
} else {
srcid = table[aux];
}
} else if (id == rpi_pico_clkid_clk_sys) {
break;
}
case rpi_pico_clkid_clk_sys: {
const static enum rpi_pico_clkid table[] = {
rpi_pico_clkid_pll_sys,
rpi_pico_clkid_pll_usb,
@ -343,7 +372,9 @@ static enum rpi_pico_clkid rpi_pico_get_clock_src(const struct device *dev, enum
} else {
srcid = table[aux];
}
} else if (id == rpi_pico_clkid_clk_peri) {
break;
}
case rpi_pico_clkid_clk_peri: {
const static enum rpi_pico_clkid table[] = {
rpi_pico_clkid_clk_sys,
rpi_pico_clkid_pll_sys,
@ -358,8 +389,16 @@ static enum rpi_pico_clkid rpi_pico_get_clock_src(const struct device *dev, enum
uint32_t aux = ((clock_hw->ctrl & CTRL_AUXSRC_BITS) >> CTRL_AUXSRC_LSB);
srcid = table[aux];
} else if (id == rpi_pico_clkid_clk_usb || id == rpi_pico_clkid_clk_adc ||
id == rpi_pico_clkid_clk_rtc) {
break;
}
case rpi_pico_clkid_clk_usb:
case rpi_pico_clkid_clk_adc:
#if defined(RPI_PICO_CLKID_CLK_RTC)
case rpi_pico_clkid_clk_rtc:
#else
#endif
{
const static enum rpi_pico_clkid table[] = {
rpi_pico_clkid_pll_usb,
rpi_pico_clkid_pll_sys,
@ -373,8 +412,16 @@ static enum rpi_pico_clkid rpi_pico_get_clock_src(const struct device *dev, enum
uint32_t aux = ((clock_hw->ctrl & CTRL_AUXSRC_BITS) >> CTRL_AUXSRC_LSB);
srcid = table[aux];
} else if (id == rpi_pico_clkid_pll_sys || id == rpi_pico_clkid_pll_usb) {
break;
}
case rpi_pico_clkid_pll_sys:
case rpi_pico_clkid_pll_usb: {
srcid = rpi_pico_clkid_xosc;
break;
}
default:
srcid = rpi_pico_clkid_none;
break;
}
return srcid;
@ -396,7 +443,9 @@ static bool rpi_pico_is_clock_enabled(const struct device *dev, enum rpi_pico_cl
} else if (id == rpi_pico_clkid_clk_usb ||
id == rpi_pico_clkid_clk_peri ||
id == rpi_pico_clkid_clk_adc ||
#if defined(RPI_PICO_CLKID_CLK_RTC)
id == rpi_pico_clkid_clk_rtc ||
#endif
id == rpi_pico_clkid_clk_gpout0 ||
id == rpi_pico_clkid_clk_gpout1 ||
id == rpi_pico_clkid_clk_gpout2 ||
@ -444,7 +493,9 @@ static float rpi_pico_calc_clock_freq(const struct device *dev, enum rpi_pico_cl
if (id == rpi_pico_clkid_clk_sys ||
id == rpi_pico_clkid_clk_usb ||
id == rpi_pico_clkid_clk_adc ||
#if defined(RPI_PICO_CLKID_CLK_RTC)
id == rpi_pico_clkid_clk_rtc ||
#endif
id == rpi_pico_clkid_clk_ref ||
id == rpi_pico_clkid_clk_gpout0 ||
id == rpi_pico_clkid_clk_gpout1 ||
@ -611,13 +662,19 @@ static int clock_control_rpi_pico_init(const struct device *dev)
RESETS_RESET_SYSCFG_BITS | RESETS_RESET_PLL_SYS_BITS));
unreset_block_wait(RESETS_RESET_BITS &
~(RESETS_RESET_ADC_BITS | RESETS_RESET_RTC_BITS |
~(RESETS_RESET_ADC_BITS |
#if defined(RESETS_RESET_RTC_BITS)
RESETS_RESET_RTC_BITS |
#endif
#if defined(RESETS_RESET_HSTX_BITS)
RESETS_RESET_HSTX_BITS |
#endif
RESETS_RESET_SPI0_BITS | RESETS_RESET_SPI1_BITS |
RESETS_RESET_UART0_BITS | RESETS_RESET_UART1_BITS |
RESETS_RESET_USBCTRL_BITS));
/* Start tick in watchdog */
watchdog_hw->tick = ((CLOCK_FREQ_xosc/1000000) | WATCHDOG_TICK_ENABLE_BITS);
watchdog_start_tick(CLOCK_FREQ_xosc / 1000000);
clocks_regs->resus.ctrl = 0;
@ -755,8 +812,10 @@ BUILD_ASSERT(SRC_CLOCK_FREQ(clk_usb) >= CLOCK_FREQ_clk_usb,
"clk_usb: clock divider is out of range");
BUILD_ASSERT(SRC_CLOCK_FREQ(clk_adc) >= CLOCK_FREQ_clk_adc,
"clk_adc: clock divider is out of range");
#if defined(CONFIG_SOC_SERIES_RP2040)
BUILD_ASSERT(SRC_CLOCK_FREQ(clk_rtc) >= CLOCK_FREQ_clk_rtc,
"clk_rtc: clock divider is out of range");
#endif
BUILD_ASSERT(SRC_CLOCK_FREQ(clk_peri) >= CLOCK_FREQ_clk_peri,
"clk_peri: clock divider is out of range");
@ -838,12 +897,21 @@ static const struct clock_control_rpi_pico_config clock_control_rpi_pico_config
.source_rate = SRC_CLOCK_FREQ(clk_adc),
.rate = CLOCK_FREQ(clk_adc),
},
#if defined(RPI_PICO_CLKID_CLK_RTC)
[RPI_PICO_CLKID_CLK_RTC] = {
.source = 0,
.aux_source = CLOCK_AUX_SOURCE(clk_rtc),
.source_rate = SRC_CLOCK_FREQ(clk_rtc),
.rate = CLOCK_FREQ(clk_rtc),
},
#elif defined(RPI_PICO_CLKID_CLK_HSTX)
[RPI_PICO_CLKID_CLK_HSTX] = {
.source = 0,
.aux_source = CLOCK_AUX_SOURCE(clk_hstx),
.source_rate = SRC_CLOCK_FREQ(clk_hstx),
.rate = CLOCK_FREQ(clk_hstx),
},
#endif
},
.plls_data = {
[RPI_PICO_PLL_SYS] = {

View file

@ -7,7 +7,7 @@
#include <arm/armv6-m.dtsi>
#include <zephyr/dt-bindings/adc/adc.h>
#include <zephyr/dt-bindings/gpio/gpio.h>
#include <zephyr/dt-bindings/clock/rpi_pico_clock.h>
#include <zephyr/dt-bindings/clock/rpi_pico_rp2040_clock.h>
#include <zephyr/dt-bindings/i2c/i2c.h>
#include <zephyr/dt-bindings/regulator/rpi_pico.h>
#include <zephyr/dt-bindings/reset/rp2040_reset.h>

View file

@ -3,8 +3,8 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_CLOCK_H_
#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_CLOCK_H_
#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_CLOCK_COMMON_H_
#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_CLOCK_COMMON_H_
#define RPI_PICO_PLL_SYS 0
#define RPI_PICO_PLL_USB 1
@ -21,9 +21,7 @@
#define RPI_PICO_CLKID_CLK_REF 4
#define RPI_PICO_CLKID_CLK_SYS 5
#define RPI_PICO_CLKID_CLK_PERI 6
#define RPI_PICO_CLKID_CLK_USB 7
#define RPI_PICO_CLKID_CLK_ADC 8
#define RPI_PICO_CLKID_CLK_RTC 9
/* N.b. clock ids 7-9 are defined in SoC-specific files. */
#define RPI_PICO_CLKID_PLL_SYS 10
#define RPI_PICO_CLKID_PLL_USB 11
@ -41,4 +39,4 @@
#define RPI_PICO_CLOCK_COUNT 10
#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_CLOCK_H_ */
#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_CLOCK_COMMON_H_ */

View file

@ -0,0 +1,15 @@
/*
* Copyright (c) 2022 Andrei-Edward Popa
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_RP2040_CLOCK_H_
#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_RP2040_CLOCK_H_
#include "rpi_pico_clock_common.h"
#define RPI_PICO_CLKID_CLK_USB 7
#define RPI_PICO_CLKID_CLK_ADC 8
#define RPI_PICO_CLKID_CLK_RTC 9
#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_RP2040_CLOCK_H_ */

View file

@ -0,0 +1,15 @@
/*
* Copyright (c) 2024 Andrew Featherstone
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_RP2350_CLOCK_H_
#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_RP2350_CLOCK_H_
#include "rpi_pico_clock_common.h"
#define RPI_PICO_CLKID_CLK_HSTX 7
#define RPI_PICO_CLKID_CLK_USB 8
#define RPI_PICO_CLKID_CLK_ADC 9
#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_RP2350_CLOCK_H_ */