From ea1cafbee705b4846b094df5862dc8d359c1f9f5 Mon Sep 17 00:00:00 2001 From: Andrei-Edward Popa Date: Sat, 18 Mar 2023 22:59:40 +0200 Subject: [PATCH] drivers: clock_control: Added clock driver for Raspberry Pi Pico Added clock driver for Raspberry Pi Pico platform Signed-off-by: Andrei-Edward Popa Signed-off-by: TOKITA Hiroshi --- .../arm/adafruit_kb2040/adafruit_kb2040.dts | 6 - .../adafruit_kb2040/adafruit_kb2040_defconfig | 3 + boards/arm/rpi_pico/rpi_pico-common.dtsi | 6 - boards/arm/rpi_pico/rpi_pico_defconfig | 1 + boards/arm/rpi_pico/rpi_pico_w_defconfig | 1 + .../sparkfun_pro_micro_rp2040.dts | 6 - .../sparkfun_pro_micro_rp2040_defconfig | 3 + drivers/clock_control/CMakeLists.txt | 1 + drivers/clock_control/Kconfig | 2 + drivers/clock_control/Kconfig.rpi_pico | 19 + .../clock_control/clock_control_rpi_pico.c | 876 ++++++++++++++++++ dts/arm/rpi_pico/rp2040.dtsi | 204 +++- .../raspberrypi,pico-clock-controller.yaml | 18 + .../clock/raspberrypi,pico-clock.yaml | 18 + dts/bindings/clock/raspberrypi,pico-pll.yaml | 31 + dts/bindings/clock/raspberrypi,pico-rosc.yaml | 38 + .../zephyr/dt-bindings/clock/rpi_pico_clock.h | 44 + .../pinctrl/rpi-pico-rp2040-pinctrl.h | 7 + .../sensor/bme280/rpi_pico_spi_pio.overlay | 2 +- soc/arm/rpi_pico/rp2/soc.c | 20 - 20 files changed, 1243 insertions(+), 63 deletions(-) create mode 100644 drivers/clock_control/Kconfig.rpi_pico create mode 100644 drivers/clock_control/clock_control_rpi_pico.c create mode 100644 dts/bindings/clock/raspberrypi,pico-clock-controller.yaml create mode 100644 dts/bindings/clock/raspberrypi,pico-clock.yaml create mode 100644 dts/bindings/clock/raspberrypi,pico-pll.yaml create mode 100644 dts/bindings/clock/raspberrypi,pico-rosc.yaml create mode 100644 include/zephyr/dt-bindings/clock/rpi_pico_clock.h diff --git a/boards/arm/adafruit_kb2040/adafruit_kb2040.dts b/boards/arm/adafruit_kb2040/adafruit_kb2040.dts index 2d9c815f57..227bb53e8d 100644 --- a/boards/arm/adafruit_kb2040/adafruit_kb2040.dts +++ b/boards/arm/adafruit_kb2040/adafruit_kb2040.dts @@ -25,12 +25,6 @@ aliases { watchdog0 = &wdt0; }; - - xtal_clk: xtal-clk { - compatible = "fixed-clock"; - clock-frequency = <12000000>; - #clock-cells = <0>; - }; }; &flash0 { diff --git a/boards/arm/adafruit_kb2040/adafruit_kb2040_defconfig b/boards/arm/adafruit_kb2040/adafruit_kb2040_defconfig index 735148fbce..6ce0691032 100644 --- a/boards/arm/adafruit_kb2040/adafruit_kb2040_defconfig +++ b/boards/arm/adafruit_kb2040/adafruit_kb2040_defconfig @@ -17,6 +17,9 @@ CONFIG_UART_CONSOLE=y # Enable reset by default CONFIG_RESET=y +# Enable clock control by default +CONFIG_CLOCK_CONTROL=y + # Code partition needed to target the correct flash range CONFIG_USE_DT_CODE_PARTITION=y diff --git a/boards/arm/rpi_pico/rpi_pico-common.dtsi b/boards/arm/rpi_pico/rpi_pico-common.dtsi index 680d203244..aee3e14436 100644 --- a/boards/arm/rpi_pico/rpi_pico-common.dtsi +++ b/boards/arm/rpi_pico/rpi_pico-common.dtsi @@ -23,12 +23,6 @@ zephyr,code-partition = &code_partition; }; - xtal_clk: xtal-clk { - compatible = "fixed-clock"; - clock-frequency = <12000000>; - #clock-cells = <0>; - }; - aliases { watchdog0 = &wdt0; }; diff --git a/boards/arm/rpi_pico/rpi_pico_defconfig b/boards/arm/rpi_pico/rpi_pico_defconfig index 2a27689211..111edceb14 100644 --- a/boards/arm/rpi_pico/rpi_pico_defconfig +++ b/boards/arm/rpi_pico/rpi_pico_defconfig @@ -11,3 +11,4 @@ CONFIG_BUILD_OUTPUT_UF2=y CONFIG_BUILD_OUTPUT_HEX=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_RESET=y +CONFIG_CLOCK_CONTROL=y diff --git a/boards/arm/rpi_pico/rpi_pico_w_defconfig b/boards/arm/rpi_pico/rpi_pico_w_defconfig index a035561419..9b3868541d 100644 --- a/boards/arm/rpi_pico/rpi_pico_w_defconfig +++ b/boards/arm/rpi_pico/rpi_pico_w_defconfig @@ -11,3 +11,4 @@ CONFIG_BUILD_OUTPUT_UF2=y CONFIG_BUILD_OUTPUT_HEX=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_RESET=y +CONFIG_CLOCK_CONTROL=y diff --git a/boards/arm/sparkfun_pro_micro_rp2040/sparkfun_pro_micro_rp2040.dts b/boards/arm/sparkfun_pro_micro_rp2040/sparkfun_pro_micro_rp2040.dts index 1bd5e226e2..50b92f603f 100644 --- a/boards/arm/sparkfun_pro_micro_rp2040/sparkfun_pro_micro_rp2040.dts +++ b/boards/arm/sparkfun_pro_micro_rp2040/sparkfun_pro_micro_rp2040.dts @@ -23,12 +23,6 @@ aliases { watchdog0 = &wdt0; }; - - xtal_clk: xtal-clk { - compatible = "fixed-clock"; - clock-frequency = <12000000>; - #clock-cells = <0>; - }; }; &flash0 { diff --git a/boards/arm/sparkfun_pro_micro_rp2040/sparkfun_pro_micro_rp2040_defconfig b/boards/arm/sparkfun_pro_micro_rp2040/sparkfun_pro_micro_rp2040_defconfig index 4ec1c6cad4..36aba34920 100644 --- a/boards/arm/sparkfun_pro_micro_rp2040/sparkfun_pro_micro_rp2040_defconfig +++ b/boards/arm/sparkfun_pro_micro_rp2040/sparkfun_pro_micro_rp2040_defconfig @@ -15,6 +15,9 @@ CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y +# Enable clock control by default +CONFIG_CLOCK_CONTROL=y + # Code partition needed to target the correct flash range CONFIG_USE_DT_CODE_PARTITION=y diff --git a/drivers/clock_control/CMakeLists.txt b/drivers/clock_control/CMakeLists.txt index 219aac76b9..14f6c60300 100644 --- a/drivers/clock_control/CMakeLists.txt +++ b/drivers/clock_control/CMakeLists.txt @@ -29,6 +29,7 @@ zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NXP_S32 clock_cont zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_RA clock_control_ra.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_AMBIQ clock_control_ambiq.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_PWM clock_control_pwm.c) +zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_RPI_PICO clock_control_rpi_pico.c) if(CONFIG_CLOCK_CONTROL_STM32_CUBE) diff --git a/drivers/clock_control/Kconfig b/drivers/clock_control/Kconfig index 37cbb2e289..9f7412cd9f 100644 --- a/drivers/clock_control/Kconfig +++ b/drivers/clock_control/Kconfig @@ -86,4 +86,6 @@ source "drivers/clock_control/Kconfig.ambiq" source "drivers/clock_control/Kconfig.pwm" +source "drivers/clock_control/Kconfig.rpi_pico" + endif # CLOCK_CONTROL diff --git a/drivers/clock_control/Kconfig.rpi_pico b/drivers/clock_control/Kconfig.rpi_pico new file mode 100644 index 0000000000..3c7c87121f --- /dev/null +++ b/drivers/clock_control/Kconfig.rpi_pico @@ -0,0 +1,19 @@ +# Raspberry Pi Pico Clock Controller Driver configuration options + +# Copyright (c) 2022 Andrei-Edward Popa +# SPDX-License-Identifier: Apache-2.0 + +config CLOCK_CONTROL_RPI_PICO + bool "Raspberry Pi Pico Clock Controller Driver" + default y + depends on DT_HAS_RASPBERRYPI_PICO_CLOCK_CONTROLLER_ENABLED + +if CLOCK_CONTROL_RPI_PICO + +config RPI_PICO_ROSC_USE_MEASURED_FREQ + bool "Use measured frequency for ring oscillator" + help + Instead of the dts value, use the value measured by + the frequency counter as the rosc frequency. + +endif # CLOCK_CONTROL_RPI_PICO diff --git a/drivers/clock_control/clock_control_rpi_pico.c b/drivers/clock_control/clock_control_rpi_pico.c new file mode 100644 index 0000000000..0313ee2d71 --- /dev/null +++ b/drivers/clock_control/clock_control_rpi_pico.c @@ -0,0 +1,876 @@ +/* + * Copyright (c) 2022 Andrei-Edward Popa + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT raspberrypi_pico_clock_controller + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* Undefine to prevent conflicts with header definitions */ +#undef pll_sys +#undef pll_usb + +#define CTRL_SRC_LSB CLOCKS_CLK_REF_CTRL_SRC_LSB +#define CTRL_SRC_BITS CLOCKS_CLK_REF_CTRL_SRC_BITS +#define CTRL_AUXSRC_LSB CLOCKS_CLK_GPOUT0_CTRL_AUXSRC_LSB +#define CTRL_AUXSRC_BITS CLOCKS_CLK_GPOUT0_CTRL_AUXSRC_BITS +#define CTRL_ENABLE_BITS CLOCKS_CLK_GPOUT0_CTRL_ENABLE_BITS +#define DIV_FRAC_BITS CLOCKS_CLK_GPOUT0_DIV_FRAC_BITS +#define DIV_INT_BITS CLOCKS_CLK_GPOUT0_DIV_INT_BITS +#define DIV_INT_LSB CLOCKS_CLK_GPOUT0_DIV_INT_LSB + +#define PLL_VCO_FREQ_MIN 750000000 +#define PLL_VCO_FREQ_MAX 1600000000 +#define PLL_FB_DIV_MIN 16 +#define PLL_FB_DIV_MAX 320 +#define PLL_POST_DIV_MIN 1 +#define PLL_POST_DIV_MAX 7 + +#define ROSC_PHASE_PASSWD_VALUE_PASS _u(0xAA) + +#define STAGE_DS(n) \ + (COND_CODE_1( \ + DT_PROP_HAS_IDX(DT_INST_CLOCKS_CTLR_BY_NAME(0, rosc), stage_drive_strength, n), \ + (DT_PROP_BY_IDX(DT_INST_CLOCKS_CTLR_BY_NAME(0, rosc), stage_drive_strength, n) & \ + ROSC_FREQA_DS0_BITS), \ + (0)) \ + << (n * 3)) + +#define CLK_SRC_IS(clk, src) \ + DT_SAME_NODE(DT_CLOCKS_CTLR_BY_IDX(DT_INST_CLOCKS_CTLR_BY_NAME(0, clk), 0), \ + DT_INST_CLOCKS_CTLR_BY_NAME(0, src)) + +#define REF_DIV(pll) DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, pll), clock_div) +#define FB_DIV(pll) DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, pll), fb_div) +#define POST_DIV1(pll) DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, pll), post_div1) +#define POST_DIV2(pll) DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, pll), post_div2) +#define VCO_FREQ(pll) ((CLOCK_FREQ_xosc / REF_DIV(pll)) * FB_DIV(pll)) + +/* + * Using the 'clock-names[0]' for expanding macro to frequency value. + * The 'clock-names[0]' is set same as label value that given to the node itself. + * Use it for traverse clock tree to find root of clock source. + */ +#define CLOCK_FREQ(clk) _CONCAT(CLOCK_FREQ_, clk) +#define SRC_CLOCK(clk) DT_STRING_TOKEN_BY_IDX(DT_INST_CLOCKS_CTLR_BY_NAME(0, clk), \ + clock_names, 0) +#define SRC_CLOCK_FREQ(clk) _CONCAT(CLOCK_FREQ_, SRC_CLOCK(clk)) + +#define PLL_FREQ(pll) \ + (DT_PROP(DT_CLOCKS_CTLR_BY_IDX(DT_INST_CLOCKS_CTLR_BY_NAME(0, pll), 0), clock_frequency) / \ + REF_DIV(pll) * FB_DIV(pll) / POST_DIV1(pll) / POST_DIV2(pll)) + +#define CLOCK_FREQ_clk_gpout0 DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, clk_gpout0), clock_frequency) +#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_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) +#define CLOCK_FREQ_clk_adc DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, clk_adc), clock_frequency) +#define CLOCK_FREQ_clk_rtc DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, clk_rtc), clock_frequency) +#define CLOCK_FREQ_clk_peri DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, clk_peri), clock_frequency) +#define CLOCK_FREQ_xosc DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, xosc), clock_frequency) +#define CLOCK_FREQ_rosc DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, rosc), clock_frequency) +#define CLOCK_FREQ_rosc_ph DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, rosc), clock_frequency) +#define CLOCK_FREQ_gpin0 DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, gpin0), clock_frequency) +#define CLOCK_FREQ_gpin1 DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, gpin1), clock_frequency) +#define CLOCK_FREQ_pll_sys PLL_FREQ(pll_sys) +#define CLOCK_FREQ_pll_usb PLL_FREQ(pll_usb) + +#define CLOCK_AUX_SOURCE(clk) _CONCAT(_CONCAT(AUXSTEM_, clk), _CONCAT(AUXSRC_, SRC_CLOCK(clk))) + +#define AUXSRC_xosc XOSC_CLKSRC +#define AUXSRC_rosc ROSC_CLKSRC +#define AUXSRC_rosc_ph ROSC_CLKSRC_PH +#define AUXSRC_pll_sys CLKSRC_PLL_SYS +#define AUXSRC_pll_usb CLKSRC_PLL_USB +#define AUXSRC_clk_ref CLK_REF +#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 + +#define AUXSTEM_clk_gpout0 CLOCKS_CLK_GPOUT0_CTRL_AUXSRC_VALUE_ +#define AUXSTEM_clk_gpout1 CLOCKS_CLK_GPOUT1_CTRL_AUXSRC_VALUE_ +#define AUXSTEM_clk_gpout2 CLOCKS_CLK_GPOUT2_CTRL_AUXSRC_VALUE_ +#define AUXSTEM_clk_gpout3 CLOCKS_CLK_GPOUT3_CTRL_AUXSRC_VALUE_ +#define AUXSTEM_clk_ref CLOCKS_CLK_REF_CTRL_AUXSRC_VALUE_ +#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 TUPLE_ENTRY(n, p, i) \ + { \ + _CONCAT(RPI_PICO_CLKID_, DT_INST_STRING_UPPER_TOKEN_BY_IDX(0, clock_names, i)), \ + COND_CODE_1( \ + DT_PROP_HAS_IDX(DT_CLOCKS_CTLR_BY_IDX(DT_NODELABEL(clocks), i), \ + clocks, 0), \ + (_CONCAT(RPI_PICO_CLKID_, \ + DT_STRING_UPPER_TOKEN_BY_IDX( \ + DT_CLOCKS_CTLR_BY_IDX(DT_NODELABEL(clocks), i), \ + clock_names, 0))), \ + (-1)) \ + } + +enum rpi_pico_clkid { + rpi_pico_clkid_none = -1, + rpi_pico_clkid_clk_gpout0 = RPI_PICO_CLKID_CLK_GPOUT0, + rpi_pico_clkid_clk_gpout1 = RPI_PICO_CLKID_CLK_GPOUT1, + rpi_pico_clkid_clk_gpout2 = RPI_PICO_CLKID_CLK_GPOUT2, + rpi_pico_clkid_clk_gpout3 = RPI_PICO_CLKID_CLK_GPOUT3, + rpi_pico_clkid_clk_ref = RPI_PICO_CLKID_CLK_REF, + rpi_pico_clkid_clk_sys = RPI_PICO_CLKID_CLK_SYS, + 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, + rpi_pico_clkid_clk_rtc = RPI_PICO_CLKID_CLK_RTC, + 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, + rpi_pico_clkid_rosc = RPI_PICO_CLKID_ROSC, + rpi_pico_clkid_rosc_ph = RPI_PICO_CLKID_ROSC_PH, + rpi_pico_clkid_gpin0 = RPI_PICO_CLKID_GPIN0, + rpi_pico_clkid_gpin1 = RPI_PICO_CLKID_GPIN1, + END_OF_RPI_PICO_CLKID, +}; + +struct rpi_pico_clkid_tuple { + enum rpi_pico_clkid clk; + enum rpi_pico_clkid parent; +}; + +struct rpi_pico_clk_config { + uint32_t source; + uint32_t aux_source; + uint32_t rate; + uint32_t source_rate; +}; + +struct rpi_pico_pll_config { + uint32_t ref_div; + uint32_t fb_div; + uint32_t post_div1; + uint32_t post_div2; +}; + +struct rpi_pico_rosc_config { + uint32_t phase; + uint32_t range; + uint32_t div; + uint32_t code; +}; + +struct rpi_pico_gpin_config { + uint32_t frequency; +}; + +struct clock_control_rpi_pico_config { + clocks_hw_t *const clocks_regs; + xosc_hw_t *const xosc_regs; + pll_hw_t *const pll_sys_regs; + pll_hw_t *const pll_usb_regs; + rosc_hw_t *const rosc_regs; + const struct pinctrl_dev_config *pcfg; + struct rpi_pico_pll_config plls_data[RPI_PICO_PLL_COUNT]; + struct rpi_pico_clk_config clocks_data[RPI_PICO_CLOCK_COUNT]; + struct rpi_pico_rosc_config rosc_data; + struct rpi_pico_gpin_config gpin_data[RPI_PICO_GPIN_COUNT]; +}; + +struct clock_control_rpi_pico_data { + uint32_t rosc_freq; + uint32_t rosc_ph_freq; +}; + +uint64_t rpi_pico_frequency_count(const struct device *dev, clock_control_subsys_t sys) +{ + const struct clock_control_rpi_pico_config *config = dev->config; + enum rpi_pico_clkid clkid = (enum rpi_pico_clkid)sys; + fc_hw_t *fc0 = &config->clocks_regs->fc0; + uint32_t fc0_id; + + switch (clkid) { + case rpi_pico_clkid_clk_ref: + fc0_id = CLOCKS_FC0_SRC_VALUE_CLK_REF; + break; + case rpi_pico_clkid_clk_sys: + fc0_id = CLOCKS_FC0_SRC_VALUE_CLK_SYS; + break; + case rpi_pico_clkid_clk_peri: + fc0_id = CLOCKS_FC0_SRC_VALUE_CLK_PERI; + break; + case rpi_pico_clkid_clk_usb: + fc0_id = CLOCKS_FC0_SRC_VALUE_CLK_USB; + break; + case rpi_pico_clkid_clk_adc: + fc0_id = CLOCKS_FC0_SRC_VALUE_CLK_ADC; + break; + case rpi_pico_clkid_clk_rtc: + fc0_id = CLOCKS_FC0_SRC_VALUE_CLK_RTC; + break; + case rpi_pico_clkid_pll_sys: + fc0_id = CLOCKS_FC0_SRC_VALUE_PLL_SYS_CLKSRC_PRIMARY; + break; + case rpi_pico_clkid_pll_usb: + fc0_id = CLOCKS_FC0_SRC_VALUE_PLL_USB_CLKSRC_PRIMARY; + break; + case rpi_pico_clkid_xosc: + fc0_id = CLOCKS_FC0_SRC_VALUE_XOSC_CLKSRC; + break; + case rpi_pico_clkid_rosc: + fc0_id = CLOCKS_FC0_SRC_VALUE_ROSC_CLKSRC; + break; + case rpi_pico_clkid_rosc_ph: + fc0_id = CLOCKS_FC0_SRC_VALUE_ROSC_CLKSRC_PH; + break; + case rpi_pico_clkid_gpin0: + fc0_id = CLOCKS_FC0_SRC_VALUE_CLKSRC_GPIN0; + break; + case rpi_pico_clkid_gpin1: + fc0_id = CLOCKS_FC0_SRC_VALUE_CLKSRC_GPIN0; + break; + default: + return -1; + } + + (void)frequency_count_khz(fc0_id); + + return ((fc0->result >> CLOCKS_FC0_RESULT_KHZ_LSB) * 1000) + + ((fc0->result & CLOCKS_FC0_RESULT_FRAC_BITS) * 1000 / CLOCKS_FC0_RESULT_FRAC_BITS); +} + +static int rpi_pico_rosc_write(const struct device *dev, io_rw_32 *addr, uint32_t value) +{ + hw_clear_bits(&rosc_hw->status, ROSC_STATUS_BADWRITE_BITS); + + if (rosc_hw->status & ROSC_STATUS_BADWRITE_BITS) { + return -EINVAL; + } + + *addr = value; + + if (rosc_hw->status & ROSC_STATUS_BADWRITE_BITS) { + return -EINVAL; + } + + return 0; +} + +/** + * Get source clock id of this clock + * + * @param dev pointer to clock device + * @param id id of this clock + * @return parent clock id + */ +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; + + 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) { + const static enum rpi_pico_clkid table[] = { + rpi_pico_clkid_pll_sys, + rpi_pico_clkid_gpin0, + rpi_pico_clkid_gpin1, + rpi_pico_clkid_pll_usb, + rpi_pico_clkid_rosc_ph, + rpi_pico_clkid_xosc, + rpi_pico_clkid_clk_sys, + rpi_pico_clkid_clk_usb, + rpi_pico_clkid_clk_adc, + rpi_pico_clkid_clk_rtc, + rpi_pico_clkid_clk_ref, + }; + + clock_hw_t *clock_hw = &config->clocks_regs->clk[id]; + uint32_t aux = ((clock_hw->ctrl & CTRL_AUXSRC_BITS) >> CTRL_AUXSRC_LSB); + + srcid = table[aux]; + } else if (id == rpi_pico_clkid_clk_ref) { + const static enum rpi_pico_clkid table[] = { + rpi_pico_clkid_pll_usb, + rpi_pico_clkid_gpin0, + rpi_pico_clkid_gpin1, + }; + + clock_hw_t *clock_hw = &clocks_hw->clk[id]; + uint32_t aux = ((clock_hw->ctrl & CTRL_AUXSRC_BITS) >> CTRL_AUXSRC_LSB); + uint32_t src = ((clock_hw->ctrl >> CTRL_SRC_LSB) & CTRL_SRC_BITS); + + if (src == CLOCKS_CLK_REF_CTRL_SRC_VALUE_ROSC_CLKSRC_PH) { + srcid = rpi_pico_clkid_rosc_ph; + } else if (src == CLOCKS_CLK_REF_CTRL_SRC_VALUE_XOSC_CLKSRC) { + srcid = rpi_pico_clkid_xosc; + } else { + srcid = table[aux]; + } + } else if (id == rpi_pico_clkid_clk_sys) { + const static enum rpi_pico_clkid table[] = { + rpi_pico_clkid_pll_sys, + rpi_pico_clkid_pll_usb, + rpi_pico_clkid_rosc, + rpi_pico_clkid_xosc, + rpi_pico_clkid_gpin0, + rpi_pico_clkid_gpin1, + }; + + clock_hw_t *clock_hw = &clocks_hw->clk[id]; + uint32_t aux = ((clock_hw->ctrl & CTRL_AUXSRC_BITS) >> CTRL_AUXSRC_LSB); + uint32_t src = ((clock_hw->ctrl >> CTRL_SRC_LSB) & CTRL_SRC_BITS); + + if (src == CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLK_REF) { + srcid = rpi_pico_clkid_clk_ref; + } else { + srcid = table[aux]; + } + } else if (id == rpi_pico_clkid_clk_peri) { + const static enum rpi_pico_clkid table[] = { + rpi_pico_clkid_clk_sys, + rpi_pico_clkid_pll_sys, + rpi_pico_clkid_pll_usb, + rpi_pico_clkid_rosc_ph, + rpi_pico_clkid_xosc, + rpi_pico_clkid_gpin0, + rpi_pico_clkid_gpin1, + }; + + clock_hw_t *clock_hw = &clocks_hw->clk[id]; + 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) { + const static enum rpi_pico_clkid table[] = { + rpi_pico_clkid_pll_usb, + rpi_pico_clkid_pll_sys, + rpi_pico_clkid_rosc_ph, + rpi_pico_clkid_xosc, + rpi_pico_clkid_gpin0, + rpi_pico_clkid_gpin1, + }; + + clock_hw_t *clock_hw = &clocks_hw->clk[id]; + 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) { + srcid = rpi_pico_clkid_xosc; + } + + return srcid; +} + +/** + * Query clock is enabled or not + * + * @param dev pointer to clock device + * @param id id of clock + * @return true if the clock enabled, otherwith false + */ +static bool rpi_pico_is_clock_enabled(const struct device *dev, enum rpi_pico_clkid id) +{ + const struct clock_control_rpi_pico_config *config = dev->config; + + if (id == rpi_pico_clkid_clk_sys || id == rpi_pico_clkid_clk_ref) { + return true; + } else if (id == rpi_pico_clkid_clk_usb || + id == rpi_pico_clkid_clk_peri || + id == rpi_pico_clkid_clk_adc || + id == rpi_pico_clkid_clk_rtc || + id == rpi_pico_clkid_clk_gpout0 || + id == rpi_pico_clkid_clk_gpout1 || + id == rpi_pico_clkid_clk_gpout2 || + id == rpi_pico_clkid_clk_gpout3) { + clock_hw_t *clock_hw = &config->clocks_regs->clk[id]; + + if (clock_hw->ctrl & CTRL_ENABLE_BITS) { + return true; + } + } else if (id == rpi_pico_clkid_pll_sys || id == rpi_pico_clkid_pll_usb) { + pll_hw_t *pll = (id == rpi_pico_clkid_pll_sys) ? config->pll_sys_regs + : config->pll_usb_regs; + + if (!(pll->pwr & (PLL_PWR_VCOPD_BITS | PLL_PWR_POSTDIVPD_BITS | PLL_PWR_PD_BITS))) { + return true; + } + } else if (id == rpi_pico_clkid_xosc) { + if (config->xosc_regs->status & XOSC_STATUS_ENABLED_BITS) { + return true; + } + } else if (id == rpi_pico_clkid_rosc || id == rpi_pico_clkid_rosc_ph) { + return true; + } + + return false; +} + +/** + * Calculate clock frequency with traversing clock tree. + * + * @param dev pointer to clock device + * @param id id of clock + * @return frequency value or 0 if disabled + */ +static float rpi_pico_calc_clock_freq(const struct device *dev, enum rpi_pico_clkid id) +{ + const struct clock_control_rpi_pico_config *config = dev->config; + struct clock_control_rpi_pico_data *data = dev->data; + float freq = 0.f; + + if (!rpi_pico_is_clock_enabled(dev, id)) { + return freq; + } + + if (id == rpi_pico_clkid_clk_sys || + id == rpi_pico_clkid_clk_usb || + id == rpi_pico_clkid_clk_adc || + id == rpi_pico_clkid_clk_rtc || + id == rpi_pico_clkid_clk_ref || + id == rpi_pico_clkid_clk_gpout0 || + id == rpi_pico_clkid_clk_gpout1 || + id == rpi_pico_clkid_clk_gpout2 || + id == rpi_pico_clkid_clk_gpout3) { + clock_hw_t *clock_hw = &config->clocks_regs->clk[id]; + + freq = rpi_pico_calc_clock_freq(dev, rpi_pico_get_clock_src(dev, id)) / + (((clock_hw->div & DIV_INT_BITS) >> DIV_INT_LSB) + + ((clock_hw->div & DIV_FRAC_BITS) / (float)DIV_FRAC_BITS)); + } else if (id == rpi_pico_clkid_clk_peri) { + freq = rpi_pico_calc_clock_freq(dev, rpi_pico_get_clock_src(dev, id)); + } else if (id == rpi_pico_clkid_pll_sys || id == rpi_pico_clkid_pll_usb) { + pll_hw_t *pll = (id == rpi_pico_clkid_pll_sys) ? config->pll_sys_regs + : config->pll_usb_regs; + freq = rpi_pico_calc_clock_freq(dev, rpi_pico_get_clock_src(dev, id)) * + (pll->fbdiv_int) / (pll->cs & PLL_CS_REFDIV_BITS) / + ((pll->prim & PLL_PRIM_POSTDIV1_BITS) >> PLL_PRIM_POSTDIV1_LSB) / + ((pll->prim & PLL_PRIM_POSTDIV2_BITS) >> PLL_PRIM_POSTDIV2_LSB); + } else if (id == rpi_pico_clkid_xosc) { + freq = CLOCK_FREQ_xosc; + } else if (id == rpi_pico_clkid_rosc) { + freq = data->rosc_freq; + } else if (id == rpi_pico_clkid_rosc_ph) { + freq = data->rosc_ph_freq; + } + + return freq; +} + +static int rpi_pico_is_valid_clock_index(enum rpi_pico_clkid index) +{ + if (index >= END_OF_RPI_PICO_CLKID) { + return -EINVAL; + } + + return 0; +} + +static int clock_control_rpi_pico_on(const struct device *dev, clock_control_subsys_t sys) +{ + const struct clock_control_rpi_pico_config *config = dev->config; + enum rpi_pico_clkid clkid = (enum rpi_pico_clkid)sys; + clocks_hw_t *clocks_regs = config->clocks_regs; + + if (rpi_pico_is_valid_clock_index(clkid) < 0) { + return -EINVAL; + } + + hw_set_bits(&clocks_regs->clk[clkid].ctrl, CTRL_ENABLE_BITS); + + return 0; +} + +static int clock_control_rpi_pico_off(const struct device *dev, clock_control_subsys_t sys) +{ + const struct clock_control_rpi_pico_config *config = dev->config; + enum rpi_pico_clkid clkid = (enum rpi_pico_clkid)sys; + clocks_hw_t *clocks_regs = config->clocks_regs; + + if (rpi_pico_is_valid_clock_index(clkid) < 0) { + return -EINVAL; + } + + hw_clear_bits(&clocks_regs->clk[clkid].ctrl, CTRL_ENABLE_BITS); + + return 0; +} + +static enum clock_control_status clock_control_rpi_pico_get_status(const struct device *dev, + clock_control_subsys_t sys) +{ + enum rpi_pico_clkid clkid = (enum rpi_pico_clkid)sys; + + if (rpi_pico_is_valid_clock_index(clkid) < 0) { + return -EINVAL; + } + + if (rpi_pico_is_clock_enabled(dev, clkid)) { + return CLOCK_CONTROL_STATUS_ON; + } + + return CLOCK_CONTROL_STATUS_OFF; +} + +static int clock_control_rpi_pico_get_rate(const struct device *dev, clock_control_subsys_t sys, + uint32_t *rate) +{ + struct clock_control_rpi_pico_data *data = dev->data; + enum rpi_pico_clkid clkid = (enum rpi_pico_clkid)sys; + + if (rpi_pico_is_valid_clock_index(clkid) < 0) { + return -EINVAL; + } + + if (IS_ENABLED(CONFIG_RPI_PICO_ROSC_USE_MEASURED_FREQ)) { + if (clkid == rpi_pico_clkid_rosc) { + data->rosc_freq = rpi_pico_frequency_count(dev, sys); + } else if (clkid == rpi_pico_clkid_rosc_ph) { + data->rosc_ph_freq = rpi_pico_frequency_count(dev, sys); + } + } + + *rate = (int)rpi_pico_calc_clock_freq(dev, clkid); + + return 0; +} + +void rpi_pico_clkid_tuple_swap(struct rpi_pico_clkid_tuple *lhs, struct rpi_pico_clkid_tuple *rhs) +{ + struct rpi_pico_clkid_tuple tmp = *lhs; + *lhs = *rhs; + *rhs = tmp; +} + +void rpi_pico_clkid_tuple_reorder_by_dependencies(struct rpi_pico_clkid_tuple *tuples, size_t len) +{ + uint32_t sorted_idx = 0; + uint32_t checked_idx = 0; + uint32_t target = -1; + + while (sorted_idx < len) { + for (uint32_t i = sorted_idx; i < len; i++) { + if (tuples[i].parent == target) { + rpi_pico_clkid_tuple_swap(&tuples[sorted_idx], &tuples[i]); + sorted_idx++; + } + } + target = tuples[checked_idx++].clk; + } +} + +static int clock_control_rpi_pico_init(const struct device *dev) +{ + const struct clock_control_rpi_pico_config *config = dev->config; + struct clock_control_rpi_pico_data *data = dev->data; + clocks_hw_t *clocks_regs = config->clocks_regs; + rosc_hw_t *rosc_regs = config->rosc_regs; + pll_hw_t *plls[] = {config->pll_sys_regs, config->pll_usb_regs}; + struct rpi_pico_clkid_tuple tuples[] = { + DT_INST_FOREACH_PROP_ELEM_SEP(0, clock_names, TUPLE_ENTRY, (,))}; + uint32_t rosc_div; + int ret; + + /* Reset all function before clock configuring */ + reset_block(~(RESETS_RESET_IO_QSPI_BITS | RESETS_RESET_PADS_QSPI_BITS | + RESETS_RESET_PLL_USB_BITS | RESETS_RESET_USBCTRL_BITS | + RESETS_RESET_PLL_USB_BITS | 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_SPI0_BITS | RESETS_RESET_SPI1_BITS | + RESETS_RESET_UART0_BITS | RESETS_RESET_UART1_BITS | + RESETS_RESET_USBCTRL_BITS | RESETS_RESET_PWM_BITS)); + + /* Start tick in watchdog */ + watchdog_hw->tick = ((CLOCK_FREQ_xosc/1000000) | WATCHDOG_TICK_ENABLE_BITS); + + clocks_regs->resus.ctrl = 0; + + /* Configure xosc */ + xosc_init(); + + /* Before we touch PLLs, switch sys and ref cleanly away from their aux sources. */ + clocks_hw->clk[RPI_PICO_CLKID_CLK_SYS].ctrl &= ~CTRL_SRC_BITS; + while (clocks_hw->clk[RPI_PICO_CLKID_CLK_SYS].selected != 0x1) { + ; + } + clocks_hw->clk[RPI_PICO_CLKID_CLK_REF].ctrl &= ~CTRL_SRC_BITS; + while (clocks_hw->clk[RPI_PICO_CLKID_CLK_REF].selected != 0x1) { + ; + } + + /* Configure pll */ + for (uint32_t i = 0; i < RPI_PICO_PLL_COUNT; i++) { + pll_init(plls[i], config->plls_data[i].ref_div, + CLOCK_FREQ_xosc * config->plls_data[i].fb_div, + config->plls_data[i].post_div1, config->plls_data[i].post_div2); + } + + /* Configure clocks */ + rpi_pico_clkid_tuple_reorder_by_dependencies(tuples, ARRAY_SIZE(tuples)); + for (uint32_t i = 0; i < ARRAY_SIZE(tuples); i++) { + if (tuples[i].clk < 0 || tuples[i].clk >= RPI_PICO_CLOCK_COUNT) { + continue; + } + + if (!(clock_configure(tuples[i].clk, config->clocks_data[tuples[i].clk].source, + config->clocks_data[tuples[i].clk].aux_source, + config->clocks_data[tuples[i].clk].source_rate, + config->clocks_data[tuples[i].clk].rate))) { + return -EINVAL; + } + } + + hw_clear_bits(&clocks_regs->clk[rpi_pico_clkid_clk_gpout0].ctrl, CTRL_ENABLE_BITS); + hw_clear_bits(&clocks_regs->clk[rpi_pico_clkid_clk_gpout1].ctrl, CTRL_ENABLE_BITS); + hw_clear_bits(&clocks_regs->clk[rpi_pico_clkid_clk_gpout2].ctrl, CTRL_ENABLE_BITS); + hw_clear_bits(&clocks_regs->clk[rpi_pico_clkid_clk_gpout3].ctrl, CTRL_ENABLE_BITS); + + /* Configure rosc */ + ret = rpi_pico_rosc_write(dev, &rosc_regs->phase, + (ROSC_PHASE_PASSWD_VALUE_PASS << ROSC_PHASE_PASSWD_LSB) | + config->rosc_data.phase); + if (ret < 0) { + return ret; + } + + ret = rpi_pico_rosc_write(dev, &rosc_regs->ctrl, + (ROSC_CTRL_ENABLE_VALUE_ENABLE << ROSC_CTRL_ENABLE_LSB) | + config->rosc_data.range); + if (ret < 0) { + return ret; + } + + if (config->rosc_data.div <= 0) { + rosc_div = ROSC_DIV_VALUE_PASS + 1; + } else if (config->rosc_data.div > 31) { + rosc_div = ROSC_DIV_VALUE_PASS; + } else { + rosc_div = ROSC_DIV_VALUE_PASS + config->rosc_data.div; + } + + ret = rpi_pico_rosc_write(dev, &rosc_regs->div, rosc_div); + if (ret < 0) { + return ret; + } + + ret = rpi_pico_rosc_write(dev, &rosc_regs->freqa, + (ROSC_FREQA_PASSWD_VALUE_PASS << ROSC_FREQA_PASSWD_LSB) | + (config->rosc_data.code & UINT16_MAX)); + if (ret < 0) { + return ret; + } + + ret = rpi_pico_rosc_write(dev, &rosc_regs->freqb, + (ROSC_FREQA_PASSWD_VALUE_PASS << ROSC_FREQA_PASSWD_LSB) | + (config->rosc_data.code >> 16)); + if (ret < 0) { + return ret; + } + + unreset_block_wait(RESETS_RESET_BITS); + + if (IS_ENABLED(CONFIG_RPI_PICO_ROSC_USE_MEASURED_FREQ)) { + data->rosc_freq = + rpi_pico_frequency_count(dev, (clock_control_subsys_t)rpi_pico_clkid_rosc); + data->rosc_ph_freq = rpi_pico_frequency_count( + dev, (clock_control_subsys_t)rpi_pico_clkid_rosc_ph); + } + + return 0; +} + +static const struct clock_control_driver_api clock_control_rpi_pico_api = { + .on = clock_control_rpi_pico_on, + .off = clock_control_rpi_pico_off, + .get_rate = clock_control_rpi_pico_get_rate, + .get_status = clock_control_rpi_pico_get_status, +}; + +BUILD_ASSERT((VCO_FREQ(pll_sys) >= PLL_VCO_FREQ_MIN) && (VCO_FREQ(pll_sys) <= PLL_VCO_FREQ_MAX) && + (VCO_FREQ(pll_sys) >= (CLOCK_FREQ_xosc / REF_DIV(pll_sys) * 16)), + "pll_sys: vco_freq is out of range"); +BUILD_ASSERT((FB_DIV(pll_sys) >= PLL_FB_DIV_MIN) && (FB_DIV(pll_sys) <= PLL_FB_DIV_MAX), + "pll_sys: fb-div is out of range"); +BUILD_ASSERT((POST_DIV1(pll_sys) >= PLL_POST_DIV_MIN) && (POST_DIV1(pll_sys) <= PLL_POST_DIV_MAX), + "pll_sys: post-div1 is out of range"); +BUILD_ASSERT((POST_DIV2(pll_sys) >= PLL_POST_DIV_MIN) && (POST_DIV2(pll_sys) <= PLL_POST_DIV_MAX), + "pll_sys: post-div2 is out of range"); + +BUILD_ASSERT((VCO_FREQ(pll_usb) >= PLL_VCO_FREQ_MIN) && (VCO_FREQ(pll_usb) <= PLL_VCO_FREQ_MAX) && + (VCO_FREQ(pll_usb) >= (CLOCK_FREQ_xosc / REF_DIV(pll_usb) * 16)), + "pll_usb: vco_freq is out of range"); +BUILD_ASSERT((FB_DIV(pll_usb) >= PLL_FB_DIV_MIN) && (FB_DIV(pll_usb) <= PLL_FB_DIV_MAX), + "pll_usb: fb-div is out of range"); +BUILD_ASSERT((POST_DIV1(pll_usb) >= PLL_POST_DIV_MIN) && (POST_DIV1(pll_usb) <= PLL_POST_DIV_MAX), + "pll_usb: post-div is out of range"); +BUILD_ASSERT((POST_DIV2(pll_usb) >= PLL_POST_DIV_MIN) && (POST_DIV2(pll_usb) <= PLL_POST_DIV_MAX), + "pll_usb: post-div is out of range"); + +BUILD_ASSERT(SRC_CLOCK_FREQ(clk_ref) >= CLOCK_FREQ_clk_ref, + "clk_ref: clock divider is out of range"); +BUILD_ASSERT(SRC_CLOCK_FREQ(clk_sys) >= CLOCK_FREQ_clk_sys, + "clk_sys: clock divider is out of range"); +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"); +BUILD_ASSERT(SRC_CLOCK_FREQ(clk_rtc) >= CLOCK_FREQ_clk_rtc, + "clk_rtc: clock divider is out of range"); +BUILD_ASSERT(SRC_CLOCK_FREQ(clk_peri) >= CLOCK_FREQ_clk_peri, + "clk_peri: clock divider is out of range"); + +BUILD_ASSERT(CLOCK_FREQ(rosc_ph) == CLOCK_FREQ(rosc), "rosc_ph: frequency must be equal to rosc"); + +static const struct clock_control_rpi_pico_config clock_control_rpi_pico_config = { + .clocks_regs = (clocks_hw_t *)DT_INST_REG_ADDR_BY_NAME(0, clocks), + .xosc_regs = (xosc_hw_t *)DT_INST_REG_ADDR_BY_NAME(0, xosc), + .pll_sys_regs = (pll_hw_t *)DT_INST_REG_ADDR_BY_NAME(0, pll_sys), + .pll_usb_regs = (pll_hw_t *)DT_INST_REG_ADDR_BY_NAME(0, pll_usb), + .rosc_regs = (rosc_hw_t *)DT_INST_REG_ADDR_BY_NAME(0, rosc), + .clocks_data = { + [RPI_PICO_CLKID_CLK_GPOUT0] = { + .source = 0, + .aux_source = CLOCK_AUX_SOURCE(clk_gpout0), + .source_rate = SRC_CLOCK_FREQ(clk_gpout0), + .rate = CLOCK_FREQ(clk_gpout0), + }, + [RPI_PICO_CLKID_CLK_GPOUT1] = { + .source = 0, + .aux_source = CLOCK_AUX_SOURCE(clk_gpout1), + .source_rate = SRC_CLOCK_FREQ(clk_gpout1), + .rate = CLOCK_FREQ(clk_gpout1), + }, + [RPI_PICO_CLKID_CLK_GPOUT2] = { + .source = 0, + .aux_source = CLOCK_AUX_SOURCE(clk_gpout2), + .source_rate = SRC_CLOCK_FREQ(clk_gpout2), + .rate = CLOCK_FREQ(clk_gpout2), + }, + [RPI_PICO_CLKID_CLK_GPOUT3] = { + .source = 0, + .aux_source = CLOCK_AUX_SOURCE(clk_gpout3), + .source_rate = SRC_CLOCK_FREQ(clk_gpout3), + .rate = CLOCK_FREQ(clk_gpout3), + }, + [RPI_PICO_CLKID_CLK_REF] = { +#if CLK_SRC_IS(clk_ref, rosc_ph) + .source = CLOCKS_CLK_REF_CTRL_SRC_VALUE_ROSC_CLKSRC_PH, + .aux_source = 0, +#elif CLK_SRC_IS(clk_ref, xosc) + .source = CLOCKS_CLK_REF_CTRL_SRC_VALUE_XOSC_CLKSRC, + .aux_source = 0, +#else + .source = CLOCKS_CLK_REF_CTRL_SRC_VALUE_CLKSRC_CLK_REF_AUX, +#endif + .source_rate = SRC_CLOCK_FREQ(clk_ref), + .rate = CLOCK_FREQ(clk_ref), + }, + [RPI_PICO_CLKID_CLK_SYS] = { +#if CLK_SRC_IS(clk_sys, clk_ref) + .source = CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLK_REF, + .aux_source = 0, +#else + .source = CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX, + .aux_source = CLOCK_AUX_SOURCE(clk_sys), +#endif + .source_rate = SRC_CLOCK_FREQ(clk_sys), + .rate = CLOCK_FREQ(clk_sys), + }, + [RPI_PICO_CLKID_CLK_PERI] = { + .source = 0, + .aux_source = CLOCK_AUX_SOURCE(clk_peri), + .source_rate = SRC_CLOCK_FREQ(clk_peri), + .rate = CLOCK_FREQ(clk_peri), + }, + [RPI_PICO_CLKID_CLK_USB] = { + .source = 0, + .aux_source = CLOCK_AUX_SOURCE(clk_usb), + .source_rate = SRC_CLOCK_FREQ(clk_usb), + .rate = CLOCK_FREQ(clk_usb), + }, + [RPI_PICO_CLKID_CLK_ADC] = { + .source = 0, + .aux_source = CLOCK_AUX_SOURCE(clk_adc), + .source_rate = SRC_CLOCK_FREQ(clk_adc), + .rate = CLOCK_FREQ(clk_adc), + }, + [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), + }, + }, + .plls_data = { + [RPI_PICO_PLL_SYS] = { + .ref_div = DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, pll_sys), clock_div), + .fb_div = DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, pll_sys), fb_div), + .post_div1 = DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, pll_sys), post_div1), + .post_div2 = DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, pll_sys), post_div2), + }, + [RPI_PICO_PLL_USB] = { + .ref_div = DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, pll_usb), clock_div), + .fb_div = DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, pll_usb), fb_div), + .post_div1 = DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, pll_usb), post_div1), + .post_div2 = DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, pll_usb), post_div2), + }, + }, + .rosc_data = { + .phase = (COND_CODE_1(DT_NODE_HAS_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, rosc), + phase_flip), + (ROSC_PHASE_FLIP_BITS), (0x0)) | + COND_CODE_1(DT_NODE_HAS_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, rosc), + phase), + ((DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, rosc), phase) & + ROSC_PHASE_SHIFT_BITS) | ROSC_PHASE_ENABLE_BITS), (0x0))), + .div = DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, rosc), clock_div), + .range = DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, rosc), range), + .code = (STAGE_DS(0) | STAGE_DS(1) | STAGE_DS(2) | STAGE_DS(3) | + STAGE_DS(4) | STAGE_DS(5) | STAGE_DS(6) | STAGE_DS(7)), + }, + .gpin_data = { + [RPI_PICO_GPIN_0] = { + COND_CODE_1(DT_NODE_HAS_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, gpin0), + clock_frequency), + (.frequency = DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, gpin0), + clock_frequency),), + (.frequency = 0,)) + }, + [RPI_PICO_GPIN_1] = { + COND_CODE_1(DT_NODE_HAS_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, gpin1), + clock_frequency), + (.frequency = DT_PROP(DT_INST_CLOCKS_CTLR_BY_NAME(0, gpin1), + clock_frequency),), + (.frequency = 0,)) + }, + }, +}; + +static struct clock_control_rpi_pico_data clock_control_rpi_pico_data = { + .rosc_freq = CLOCK_FREQ(rosc), + .rosc_ph_freq = CLOCK_FREQ(rosc_ph), +}; + +DEVICE_DT_INST_DEFINE(0, &clock_control_rpi_pico_init, NULL, &clock_control_rpi_pico_data, + &clock_control_rpi_pico_config, PRE_KERNEL_1, + CONFIG_CLOCK_CONTROL_INIT_PRIORITY, &clock_control_rpi_pico_api); diff --git a/dts/arm/rpi_pico/rp2040.dtsi b/dts/arm/rpi_pico/rp2040.dtsi index 34a09a24dc..72c71bfcfd 100644 --- a/dts/arm/rpi_pico/rp2040.dtsi +++ b/dts/arm/rpi_pico/rp2040.dtsi @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -33,6 +34,149 @@ }; }; + clocks { + clk_gpout0: clk-gpout0 { + compatible = "raspberrypi,pico-clock"; + clocks = <&pll_sys>; + clock-names = "pll_sys"; + clock-frequency = <125000000>; + #clock-cells = <0>; + #address-cells = <0>; + }; + + clk_gpout1: clk-gpout1 { + compatible = "raspberrypi,pico-clock"; + clocks = <&pll_sys>; + clock-names = "pll_sys"; + clock-frequency = <125000000>; + #clock-cells = <0>; + }; + + clk_gpout2: clk-gpout2 { + compatible = "raspberrypi,pico-clock"; + clocks = <&pll_sys>; + clock-names = "pll_sys"; + clock-frequency = <125000000>; + #clock-cells = <0>; + }; + + clk_gpout3: clk-gpout3 { + compatible = "raspberrypi,pico-clock"; + clocks = <&pll_sys>; + clock-names = "pll_sys"; + clock-frequency = <125000000>; + #clock-cells = <0>; + }; + + clk_ref: clk-ref { + compatible = "raspberrypi,pico-clock"; + clocks = <&xosc>; + clock-names = "xosc"; + clock-frequency = <12000000>; + #clock-cells = <0>; + }; + + clk_sys: clk-sys { + compatible = "raspberrypi,pico-clock"; + clocks = <&pll_sys>; + clock-names = "pll_sys"; + clock-frequency = <125000000>; + #clock-cells = <0>; + }; + + clk_usb: clk-usb { + compatible = "raspberrypi,pico-clock"; + clocks = <&pll_usb>; + clock-names = "pll_usb"; + clock-frequency = <48000000>; + #clock-cells = <0>; + }; + + clk_adc: clk-adc { + compatible = "raspberrypi,pico-clock"; + clocks = <&pll_usb>; + clock-names = "pll_usb"; + clock-frequency = <48000000>; + #clock-cells = <0>; + }; + + clk_rtc: clk-rtc { + compatible = "raspberrypi,pico-clock"; + clocks = <&pll_usb>; + clock-names = "pll_usb"; + clock-frequency = <46875>; + #clock-cells = <0>; + }; + + clk_peri: clk-peri { + compatible = "raspberrypi,pico-clock"; + clocks = <&clk_sys>; + clock-names = "clk_sys"; + clock-frequency = <125000000>; + #clock-cells = <0>; + }; + + pll_sys: pll-sys { + compatible = "raspberrypi,pico-pll"; + clocks = <&xosc>; + clock-names = "xosc"; + clock-div= <1>; + fb-div= <125>; + post-div1 = <6>; + post-div2 = <2>; + #clock-cells = <0>; + }; + + pll_usb: pll-usb { + compatible = "raspberrypi,pico-pll"; + clocks = <&xosc>; + clock-names = "xosc"; + clock-div= <1>; + fb-div = <100>; + post-div1 = <5>; + post-div2 = <5>; + #clock-cells = <0>; + }; + + rosc: rosc { + compatible = "raspberrypi,pico-rosc"; + clock-frequency = <6500000>; + range = ; + stage-drive-strength = <0>, <0>, <0>, <0>, <0>, <0>, <0>, <0>; + clock-div = <16>; + phase = <0>; + #clock-cells = <0>; + }; + + rosc_ph: rosc-ph { + compatible = "raspberrypi,pico-clock"; + clock-frequency = <6500000>; + clocks = <&rosc>; + clock-names = "rosc"; + #clock-cells = <0>; + }; + + xosc: xosc { + compatible = "raspberrypi,pico-clock"; + clock-frequency = <12000000>; + #clock-cells = <0>; + }; + + gpin0: gpin0 { + compatible = "raspberrypi,pico-clock"; + status = "disabled"; + clock-frequency = <0>; + #clock-cells = <0>; + }; + + gpin1: gpin1 { + compatible = "raspberrypi,pico-clock"; + status = "disabled"; + clock-frequency = <0>; + #clock-cells = <0>; + }; + }; + soc { compatible = "raspberrypi,rp2040", "simple-bus"; @@ -55,18 +199,6 @@ }; }; - peripheral_clk: peripheral-clk { - compatible = "fixed-clock"; - clock-frequency = <125000000>; - #clock-cells = <0>; - }; - - system_clk: system-clk { - compatible = "fixed-clock"; - clock-frequency = <125000000>; - #clock-cells = <0>; - }; - reset: reset-controller@4000c000 { compatible = "raspberrypi,pico-reset"; reg = <0x4000c000 DT_SIZE_K(4)>; @@ -75,6 +207,28 @@ #reset-cells = <1>; }; + clocks: clock-controller@40008000 { + compatible = "raspberrypi,pico-clock-controller"; + reg = <0x40008000 DT_SIZE_K(4) + 0x40024000 DT_SIZE_K(4) + 0x40028000 DT_SIZE_K(4) + 0x4002c000 DT_SIZE_K(4) + 0x40060000 DT_SIZE_K(4)>; + reg-names = "clocks", "xosc", "pll_sys", "pll_usb", "rosc"; + #clock-cells = <1>; + status = "okay"; + clocks = <&clk_gpout0>, <&clk_gpout1>, <&clk_gpout2>, <&clk_gpout3>, + <&clk_ref>, <&clk_sys>, <&clk_peri>, + <&clk_usb>, <&clk_adc>, <&clk_rtc>, + <&pll_sys>, <&pll_usb>, <&xosc>, <&rosc>, <&rosc_ph>, + <&gpin0>, <&gpin1>; + clock-names = "clk_gpout0", "clk_gpout1", "clk_gpout2", "clk_gpout3", + "clk_ref", "clk_sys", "clk_peri", + "clk_usb", "clk_adc", "clk_rtc", + "pll_sys", "pll_usb", "xosc", "rosc", "rosc_ph", + "gpin0", "gpin1"; + }; + gpio0: gpio@40014000 { compatible = "raspberrypi,pico-gpio"; reg = <0x40014000 DT_SIZE_K(4)>; @@ -88,7 +242,7 @@ uart0: uart@40034000 { compatible = "raspberrypi,pico-uart"; reg = <0x40034000 DT_SIZE_K(4)>; - clocks = <&peripheral_clk>; + clocks = <&clocks RPI_PICO_CLKID_CLK_PERI>; resets = <&reset RPI_PICO_RESETS_RESET_UART0>; interrupts = <20 RPI_PICO_DEFAULT_IRQ_PRIORITY>; interrupt-names = "uart0"; @@ -98,7 +252,7 @@ uart1: uart@40038000 { compatible = "raspberrypi,pico-uart"; reg = <0x40038000 DT_SIZE_K(4)>; - clocks = <&peripheral_clk>; + clocks = <&clocks RPI_PICO_CLKID_CLK_PERI>; resets = <&reset RPI_PICO_RESETS_RESET_UART1>; interrupts = <21 RPI_PICO_DEFAULT_IRQ_PRIORITY>; interrupt-names = "uart1"; @@ -110,7 +264,7 @@ #address-cells = <1>; #size-cells = <0>; reg = <0x4003c000 DT_SIZE_K(4)>; - clocks = <&peripheral_clk>; + clocks = <&clocks RPI_PICO_CLKID_CLK_PERI>; resets = <&reset RPI_PICO_RESETS_RESET_SPI0>; interrupts = <18 RPI_PICO_DEFAULT_IRQ_PRIORITY>; interrupt-names = "spi0"; @@ -123,7 +277,7 @@ #size-cells = <0>; reg = <0x40040000 DT_SIZE_K(4)>; resets = <&reset RPI_PICO_RESETS_RESET_SPI1>; - clocks = <&peripheral_clk>; + clocks = <&clocks RPI_PICO_CLKID_CLK_PERI>; interrupts = <19 RPI_PICO_DEFAULT_IRQ_PRIORITY>; interrupt-names = "spi1"; status = "disabled"; @@ -133,6 +287,7 @@ compatible = "raspberrypi,pico-adc"; reg = <0x4004c000 DT_SIZE_K(4)>; resets = <&reset RPI_PICO_RESETS_RESET_ADC>; + clocks = <&clocks RPI_PICO_CLKID_CLK_ADC>; interrupts = <22 RPI_PICO_DEFAULT_IRQ_PRIORITY>; interrupt-names = "adc0"; status = "disabled"; @@ -145,7 +300,7 @@ #size-cells = <0>; reg = <0x40044000 DT_SIZE_K(4)>; resets = <&reset RPI_PICO_RESETS_RESET_I2C0>; - clocks = <&system_clk>; + clocks = <&clocks RPI_PICO_CLKID_CLK_SYS>; interrupts = <23 RPI_PICO_DEFAULT_IRQ_PRIORITY>; interrupt-names = "i2c0"; status = "disabled"; @@ -157,7 +312,7 @@ #size-cells = <0>; reg = <0x40048000 DT_SIZE_K(4)>; resets = <&reset RPI_PICO_RESETS_RESET_I2C0>; - clocks = <&system_clk>; + clocks = <&clocks RPI_PICO_CLKID_CLK_SYS>; interrupts = <24 RPI_PICO_DEFAULT_IRQ_PRIORITY>; interrupt-names = "i2c1"; status = "disabled"; @@ -166,7 +321,7 @@ wdt0: watchdog@40058000 { compatible = "raspberrypi,pico-watchdog"; reg = <0x40058000 DT_SIZE_K(4)>; - clocks = <&xtal_clk>; + clocks = <&clocks RPI_PICO_CLKID_CLK_REF>; status = "disabled"; }; @@ -174,6 +329,7 @@ compatible = "raspberrypi,pico-usbd"; reg = <0x50100000 0x10000>; resets = <&reset RPI_PICO_RESETS_RESET_USBCTRL>; + clocks = <&clocks RPI_PICO_CLKID_CLK_USB>; interrupts = <5 RPI_PICO_DEFAULT_IRQ_PRIORITY>; interrupt-names = "usbctrl"; num-bidir-endpoints = <16>; @@ -184,7 +340,7 @@ compatible = "raspberrypi,pico-pwm"; reg = <0x40050000 DT_SIZE_K(4)>; resets = <&reset RPI_PICO_RESETS_RESET_PWM>; - clocks = <&system_clk>; + clocks = <&clocks RPI_PICO_CLKID_CLK_SYS>; interrupts = <4 RPI_PICO_DEFAULT_IRQ_PRIORITY>; interrupt-names = "PWM_IRQ_WRAP"; status = "disabled"; @@ -195,7 +351,7 @@ compatible = "raspberrypi,pico-timer"; reg = <0x40054000 DT_SIZE_K(4)>; resets = <&reset RPI_PICO_RESETS_RESET_TIMER>; - clocks = <&xtal_clk>; + clocks = <&clocks RPI_PICO_CLKID_CLK_REF>; interrupts = <0 RPI_PICO_DEFAULT_IRQ_PRIORITY>, <1 RPI_PICO_DEFAULT_IRQ_PRIORITY>, <2 RPI_PICO_DEFAULT_IRQ_PRIORITY>, @@ -211,7 +367,7 @@ compatible = "raspberrypi,pico-dma"; reg = <0x50000000 DT_SIZE_K(64)>; resets = <&reset RPI_PICO_RESETS_RESET_DMA>; - clocks = <&system_clk>; + clocks = <&clocks RPI_PICO_CLKID_CLK_SYS>; interrupts = <11 RPI_PICO_DEFAULT_IRQ_PRIORITY>, <12 RPI_PICO_DEFAULT_IRQ_PRIORITY>; interrupt-names = "dma0", "dma1"; @@ -231,7 +387,7 @@ pio0: pio@50200000 { compatible = "raspberrypi,pico-pio"; reg = <0x50200000 DT_SIZE_K(4)>; - clocks = <&system_clk>; + clocks = <&clocks RPI_PICO_CLKID_CLK_SYS>; resets = <&reset RPI_PICO_RESETS_RESET_PIO0>; status = "disabled"; }; @@ -239,7 +395,7 @@ pio1: pio@50300000 { compatible = "raspberrypi,pico-pio"; reg = <0x50300000 DT_SIZE_K(4)>; - clocks = <&system_clk>; + clocks = <&clocks RPI_PICO_CLKID_CLK_SYS>; resets = <&reset RPI_PICO_RESETS_RESET_PIO1>; status = "disabled"; }; diff --git a/dts/bindings/clock/raspberrypi,pico-clock-controller.yaml b/dts/bindings/clock/raspberrypi,pico-clock-controller.yaml new file mode 100644 index 0000000000..cf74065494 --- /dev/null +++ b/dts/bindings/clock/raspberrypi,pico-clock-controller.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2022 Andrei-Edward Popa +# SPDX-License-Identifier: Apache-2.0 + +description: Raspberry Pi Pico clock controller node + +compatible: "raspberrypi,pico-clock-controller" + +include: [base.yaml, clock-controller.yaml] + +properties: + reg: + required: true + + "#clock-cells": + const: 1 + +clock-cells: + - clk-id diff --git a/dts/bindings/clock/raspberrypi,pico-clock.yaml b/dts/bindings/clock/raspberrypi,pico-clock.yaml new file mode 100644 index 0000000000..c787f3c7e8 --- /dev/null +++ b/dts/bindings/clock/raspberrypi,pico-clock.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +description: | + The representation of Raspberry Pi Pico's clock + +compatible: "raspberrypi,pico-clock" + +include: fixed-clock.yaml + +properties: + clocks: + type: phandle-array + description: Clock gate information + + clock-names: + type: string-array + description: name of each clock diff --git a/dts/bindings/clock/raspberrypi,pico-pll.yaml b/dts/bindings/clock/raspberrypi,pico-pll.yaml new file mode 100644 index 0000000000..d3859802c7 --- /dev/null +++ b/dts/bindings/clock/raspberrypi,pico-pll.yaml @@ -0,0 +1,31 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +description: | + The representation of Raspberry Pi Pico's PLL. + +compatible: "raspberrypi,pico-pll" + +include: [base.yaml, fixed-factor-clock.yaml] + +properties: + fb-div: + type: int + required: true + description: | + The feedback divider value. + The valid range is 16 to 320. + + post-div1: + type: int + required: true + description: | + The post clock divider. + The valid range is 1 to 49. + + post-div2: + type: int + required: true + description: | + The post clock divider. + The valid range is 1 to 49. diff --git a/dts/bindings/clock/raspberrypi,pico-rosc.yaml b/dts/bindings/clock/raspberrypi,pico-rosc.yaml new file mode 100644 index 0000000000..189ba12c0f --- /dev/null +++ b/dts/bindings/clock/raspberrypi,pico-rosc.yaml @@ -0,0 +1,38 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +description: | + The representation of Raspberry Pi Pico ring oscillator. + +compatible: "raspberrypi,pico-rosc" + +include: [fixed-clock.yaml, fixed-factor-clock.yaml] + +properties: + range: + type: int + required: true + description: | + Specify the number of ring oscillator stages to use. + - LOW: 8 (default) + - MEDIUM: 6 + - HIGH: 4 + - TOOHIGH: 2 + + stage-drive-strength: + type: array + required: true + description: | + Specifies the drive strength of the eight stages of the ring oscillator. + The valid range of each value is between 0 and 7. + + phase-flip: + type: boolean + description: | + Flipping phase-shifter output. + + phase: + type: int + description: | + The phase-shift vlaue. + The valid range is 0 to 3 diff --git a/include/zephyr/dt-bindings/clock/rpi_pico_clock.h b/include/zephyr/dt-bindings/clock/rpi_pico_clock.h new file mode 100644 index 0000000000..07522be663 --- /dev/null +++ b/include/zephyr/dt-bindings/clock/rpi_pico_clock.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022 Andrei-Edward Popa + * + * 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_ + +#define RPI_PICO_PLL_SYS 0 +#define RPI_PICO_PLL_USB 1 +#define RPI_PICO_PLL_COUNT 2 + +#define RPI_PICO_GPIN_0 0 +#define RPI_PICO_GPIN_1 1 +#define RPI_PICO_GPIN_COUNT 2 + +#define RPI_PICO_CLKID_CLK_GPOUT0 0 +#define RPI_PICO_CLKID_CLK_GPOUT1 1 +#define RPI_PICO_CLKID_CLK_GPOUT2 2 +#define RPI_PICO_CLKID_CLK_GPOUT3 3 +#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 + +#define RPI_PICO_CLKID_PLL_SYS 10 +#define RPI_PICO_CLKID_PLL_USB 11 +#define RPI_PICO_CLKID_XOSC 12 +#define RPI_PICO_CLKID_ROSC 13 +#define RPI_PICO_CLKID_ROSC_PH 14 +#define RPI_PICO_CLKID_GPIN0 15 +#define RPI_PICO_CLKID_GPIN1 16 + +#define RPI_PICO_ROSC_RANGE_RESET 0xAA0 +#define RPI_PICO_ROSC_RANGE_LOW 0xFA4 +#define RPI_PICO_ROSC_RANGE_MEDIUM 0xFA5 +#define RPI_PICO_ROSC_RANGE_HIGH 0xFA7 +#define RPI_PICO_ROSC_RANGE_TOOHIGH 0xFA6 + +#define RPI_PICO_CLOCK_COUNT 10 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RPI_PICO_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/rpi-pico-rp2040-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/rpi-pico-rp2040-pinctrl.h index 4249fd24a3..c7870a2108 100644 --- a/include/zephyr/dt-bindings/pinctrl/rpi-pico-rp2040-pinctrl.h +++ b/include/zephyr/dt-bindings/pinctrl/rpi-pico-rp2040-pinctrl.h @@ -219,4 +219,11 @@ #define PIO1_P28 RP2040_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_PIO1) #define PIO1_P29 RP2040_PINMUX(29, RP2_PINCTRL_GPIO_FUNC_PIO1) +#define GPIN0_P20 RP2040_PINMUX(20, RP2_PINCTRL_GPIO_FUNC_GPCK) +#define GPIN1_P22 RP2040_PINMUX(22, RP2_PINCTRL_GPIO_FUNC_GPCK) +#define GPOUT0_P21 RP2040_PINMUX(21, RP2_PINCTRL_GPIO_FUNC_GPCK) +#define GPOUT1_P23 RP2040_PINMUX(23, RP2_PINCTRL_GPIO_FUNC_GPCK) +#define GPOUT2_P24 RP2040_PINMUX(24, RP2_PINCTRL_GPIO_FUNC_GPCK) +#define GPOUT3_P25 RP2040_PINMUX(25, RP2_PINCTRL_GPIO_FUNC_GPCK) + #endif /* __RP2040_PINCTRL_H__ */ diff --git a/samples/sensor/bme280/rpi_pico_spi_pio.overlay b/samples/sensor/bme280/rpi_pico_spi_pio.overlay index 473cfae2a0..a555e93213 100644 --- a/samples/sensor/bme280/rpi_pico_spi_pio.overlay +++ b/samples/sensor/bme280/rpi_pico_spi_pio.overlay @@ -22,7 +22,7 @@ status = "okay"; #address-cells = <1>; #size-cells = <0>; - clocks = < &system_clk >; + clocks = <&clocks RPI_PICO_CLKID_CLK_SYS>; miso-gpios = <&gpio0 12 0>; cs-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; clk-gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>; diff --git a/soc/arm/rpi_pico/rp2/soc.c b/soc/arm/rpi_pico/rp2/soc.c index d953436f77..012f543128 100644 --- a/soc/arm/rpi_pico/rp2/soc.c +++ b/soc/arm/rpi_pico/rp2/soc.c @@ -26,24 +26,6 @@ LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); -static int rp2040_init(void) -{ - reset_block(~(RESETS_RESET_IO_QSPI_BITS | RESETS_RESET_PADS_QSPI_BITS | - RESETS_RESET_PLL_USB_BITS | RESETS_RESET_PLL_SYS_BITS)); - - unreset_block_wait(RESETS_RESET_BITS & - ~(RESETS_RESET_ADC_BITS | RESETS_RESET_RTC_BITS | - RESETS_RESET_SPI0_BITS | RESETS_RESET_SPI1_BITS | - RESETS_RESET_UART0_BITS | RESETS_RESET_UART1_BITS | - RESETS_RESET_USBCTRL_BITS | RESETS_RESET_PWM_BITS)); - - clocks_init(); - - unreset_block_wait(RESETS_RESET_BITS); - - return 0; -} - /* * Some pico-sdk drivers call panic on fatal error. * This alternative implementation of panic handles the panic @@ -57,5 +39,3 @@ void __attribute__((noreturn)) panic(const char *fmt, ...) vprintf(fmt, args); k_fatal_halt(K_ERR_CPU_EXCEPTION); } - -SYS_INIT(rp2040_init, PRE_KERNEL_1, 0);