drivers: clock_control: Added clock driver for Raspberry Pi Pico
Added clock driver for Raspberry Pi Pico platform Signed-off-by: Andrei-Edward Popa <andrei.popa105@yahoo.com> Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
This commit is contained in:
parent
0bc8de8444
commit
ea1cafbee7
|
@ -25,12 +25,6 @@
|
||||||
aliases {
|
aliases {
|
||||||
watchdog0 = &wdt0;
|
watchdog0 = &wdt0;
|
||||||
};
|
};
|
||||||
|
|
||||||
xtal_clk: xtal-clk {
|
|
||||||
compatible = "fixed-clock";
|
|
||||||
clock-frequency = <12000000>;
|
|
||||||
#clock-cells = <0>;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
&flash0 {
|
&flash0 {
|
||||||
|
|
|
@ -17,6 +17,9 @@ CONFIG_UART_CONSOLE=y
|
||||||
# Enable reset by default
|
# Enable reset by default
|
||||||
CONFIG_RESET=y
|
CONFIG_RESET=y
|
||||||
|
|
||||||
|
# Enable clock control by default
|
||||||
|
CONFIG_CLOCK_CONTROL=y
|
||||||
|
|
||||||
# Code partition needed to target the correct flash range
|
# Code partition needed to target the correct flash range
|
||||||
CONFIG_USE_DT_CODE_PARTITION=y
|
CONFIG_USE_DT_CODE_PARTITION=y
|
||||||
|
|
||||||
|
|
|
@ -23,12 +23,6 @@
|
||||||
zephyr,code-partition = &code_partition;
|
zephyr,code-partition = &code_partition;
|
||||||
};
|
};
|
||||||
|
|
||||||
xtal_clk: xtal-clk {
|
|
||||||
compatible = "fixed-clock";
|
|
||||||
clock-frequency = <12000000>;
|
|
||||||
#clock-cells = <0>;
|
|
||||||
};
|
|
||||||
|
|
||||||
aliases {
|
aliases {
|
||||||
watchdog0 = &wdt0;
|
watchdog0 = &wdt0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,3 +11,4 @@ CONFIG_BUILD_OUTPUT_UF2=y
|
||||||
CONFIG_BUILD_OUTPUT_HEX=y
|
CONFIG_BUILD_OUTPUT_HEX=y
|
||||||
CONFIG_UART_INTERRUPT_DRIVEN=y
|
CONFIG_UART_INTERRUPT_DRIVEN=y
|
||||||
CONFIG_RESET=y
|
CONFIG_RESET=y
|
||||||
|
CONFIG_CLOCK_CONTROL=y
|
||||||
|
|
|
@ -11,3 +11,4 @@ CONFIG_BUILD_OUTPUT_UF2=y
|
||||||
CONFIG_BUILD_OUTPUT_HEX=y
|
CONFIG_BUILD_OUTPUT_HEX=y
|
||||||
CONFIG_UART_INTERRUPT_DRIVEN=y
|
CONFIG_UART_INTERRUPT_DRIVEN=y
|
||||||
CONFIG_RESET=y
|
CONFIG_RESET=y
|
||||||
|
CONFIG_CLOCK_CONTROL=y
|
||||||
|
|
|
@ -23,12 +23,6 @@
|
||||||
aliases {
|
aliases {
|
||||||
watchdog0 = &wdt0;
|
watchdog0 = &wdt0;
|
||||||
};
|
};
|
||||||
|
|
||||||
xtal_clk: xtal-clk {
|
|
||||||
compatible = "fixed-clock";
|
|
||||||
clock-frequency = <12000000>;
|
|
||||||
#clock-cells = <0>;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
&flash0 {
|
&flash0 {
|
||||||
|
|
|
@ -15,6 +15,9 @@ CONFIG_UART_INTERRUPT_DRIVEN=y
|
||||||
CONFIG_CONSOLE=y
|
CONFIG_CONSOLE=y
|
||||||
CONFIG_UART_CONSOLE=y
|
CONFIG_UART_CONSOLE=y
|
||||||
|
|
||||||
|
# Enable clock control by default
|
||||||
|
CONFIG_CLOCK_CONTROL=y
|
||||||
|
|
||||||
# Code partition needed to target the correct flash range
|
# Code partition needed to target the correct flash range
|
||||||
CONFIG_USE_DT_CODE_PARTITION=y
|
CONFIG_USE_DT_CODE_PARTITION=y
|
||||||
|
|
||||||
|
|
|
@ -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_RA clock_control_ra.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_AMBIQ clock_control_ambiq.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_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)
|
if(CONFIG_CLOCK_CONTROL_STM32_CUBE)
|
||||||
|
|
|
@ -86,4 +86,6 @@ source "drivers/clock_control/Kconfig.ambiq"
|
||||||
|
|
||||||
source "drivers/clock_control/Kconfig.pwm"
|
source "drivers/clock_control/Kconfig.pwm"
|
||||||
|
|
||||||
|
source "drivers/clock_control/Kconfig.rpi_pico"
|
||||||
|
|
||||||
endif # CLOCK_CONTROL
|
endif # CLOCK_CONTROL
|
||||||
|
|
19
drivers/clock_control/Kconfig.rpi_pico
Normal file
19
drivers/clock_control/Kconfig.rpi_pico
Normal file
|
@ -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
|
876
drivers/clock_control/clock_control_rpi_pico.c
Normal file
876
drivers/clock_control/clock_control_rpi_pico.c
Normal file
|
@ -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 <zephyr/drivers/clock_control.h>
|
||||||
|
#include <zephyr/drivers/reset.h>
|
||||||
|
#include <zephyr/dt-bindings/clock/rpi_pico_clock.h>
|
||||||
|
|
||||||
|
#include <hardware/clocks.h>
|
||||||
|
#include <hardware/xosc.h>
|
||||||
|
#include <hardware/structs/rosc.h>
|
||||||
|
#include <hardware/pll.h>
|
||||||
|
#include <hardware/watchdog.h>
|
||||||
|
#include <hardware/resets.h>
|
||||||
|
|
||||||
|
/* 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);
|
|
@ -7,6 +7,7 @@
|
||||||
#include <arm/armv6-m.dtsi>
|
#include <arm/armv6-m.dtsi>
|
||||||
#include <zephyr/dt-bindings/adc/adc.h>
|
#include <zephyr/dt-bindings/adc/adc.h>
|
||||||
#include <zephyr/dt-bindings/gpio/gpio.h>
|
#include <zephyr/dt-bindings/gpio/gpio.h>
|
||||||
|
#include <zephyr/dt-bindings/clock/rpi_pico_clock.h>
|
||||||
#include <zephyr/dt-bindings/i2c/i2c.h>
|
#include <zephyr/dt-bindings/i2c/i2c.h>
|
||||||
#include <zephyr/dt-bindings/regulator/rpi_pico.h>
|
#include <zephyr/dt-bindings/regulator/rpi_pico.h>
|
||||||
#include <mem.h>
|
#include <mem.h>
|
||||||
|
@ -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 = <RPI_PICO_ROSC_RANGE_RESET>;
|
||||||
|
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 {
|
soc {
|
||||||
compatible = "raspberrypi,rp2040", "simple-bus";
|
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 {
|
reset: reset-controller@4000c000 {
|
||||||
compatible = "raspberrypi,pico-reset";
|
compatible = "raspberrypi,pico-reset";
|
||||||
reg = <0x4000c000 DT_SIZE_K(4)>;
|
reg = <0x4000c000 DT_SIZE_K(4)>;
|
||||||
|
@ -75,6 +207,28 @@
|
||||||
#reset-cells = <1>;
|
#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 {
|
gpio0: gpio@40014000 {
|
||||||
compatible = "raspberrypi,pico-gpio";
|
compatible = "raspberrypi,pico-gpio";
|
||||||
reg = <0x40014000 DT_SIZE_K(4)>;
|
reg = <0x40014000 DT_SIZE_K(4)>;
|
||||||
|
@ -88,7 +242,7 @@
|
||||||
uart0: uart@40034000 {
|
uart0: uart@40034000 {
|
||||||
compatible = "raspberrypi,pico-uart";
|
compatible = "raspberrypi,pico-uart";
|
||||||
reg = <0x40034000 DT_SIZE_K(4)>;
|
reg = <0x40034000 DT_SIZE_K(4)>;
|
||||||
clocks = <&peripheral_clk>;
|
clocks = <&clocks RPI_PICO_CLKID_CLK_PERI>;
|
||||||
resets = <&reset RPI_PICO_RESETS_RESET_UART0>;
|
resets = <&reset RPI_PICO_RESETS_RESET_UART0>;
|
||||||
interrupts = <20 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
|
interrupts = <20 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
|
||||||
interrupt-names = "uart0";
|
interrupt-names = "uart0";
|
||||||
|
@ -98,7 +252,7 @@
|
||||||
uart1: uart@40038000 {
|
uart1: uart@40038000 {
|
||||||
compatible = "raspberrypi,pico-uart";
|
compatible = "raspberrypi,pico-uart";
|
||||||
reg = <0x40038000 DT_SIZE_K(4)>;
|
reg = <0x40038000 DT_SIZE_K(4)>;
|
||||||
clocks = <&peripheral_clk>;
|
clocks = <&clocks RPI_PICO_CLKID_CLK_PERI>;
|
||||||
resets = <&reset RPI_PICO_RESETS_RESET_UART1>;
|
resets = <&reset RPI_PICO_RESETS_RESET_UART1>;
|
||||||
interrupts = <21 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
|
interrupts = <21 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
|
||||||
interrupt-names = "uart1";
|
interrupt-names = "uart1";
|
||||||
|
@ -110,7 +264,7 @@
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
reg = <0x4003c000 DT_SIZE_K(4)>;
|
reg = <0x4003c000 DT_SIZE_K(4)>;
|
||||||
clocks = <&peripheral_clk>;
|
clocks = <&clocks RPI_PICO_CLKID_CLK_PERI>;
|
||||||
resets = <&reset RPI_PICO_RESETS_RESET_SPI0>;
|
resets = <&reset RPI_PICO_RESETS_RESET_SPI0>;
|
||||||
interrupts = <18 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
|
interrupts = <18 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
|
||||||
interrupt-names = "spi0";
|
interrupt-names = "spi0";
|
||||||
|
@ -123,7 +277,7 @@
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
reg = <0x40040000 DT_SIZE_K(4)>;
|
reg = <0x40040000 DT_SIZE_K(4)>;
|
||||||
resets = <&reset RPI_PICO_RESETS_RESET_SPI1>;
|
resets = <&reset RPI_PICO_RESETS_RESET_SPI1>;
|
||||||
clocks = <&peripheral_clk>;
|
clocks = <&clocks RPI_PICO_CLKID_CLK_PERI>;
|
||||||
interrupts = <19 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
|
interrupts = <19 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
|
||||||
interrupt-names = "spi1";
|
interrupt-names = "spi1";
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
|
@ -133,6 +287,7 @@
|
||||||
compatible = "raspberrypi,pico-adc";
|
compatible = "raspberrypi,pico-adc";
|
||||||
reg = <0x4004c000 DT_SIZE_K(4)>;
|
reg = <0x4004c000 DT_SIZE_K(4)>;
|
||||||
resets = <&reset RPI_PICO_RESETS_RESET_ADC>;
|
resets = <&reset RPI_PICO_RESETS_RESET_ADC>;
|
||||||
|
clocks = <&clocks RPI_PICO_CLKID_CLK_ADC>;
|
||||||
interrupts = <22 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
|
interrupts = <22 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
|
||||||
interrupt-names = "adc0";
|
interrupt-names = "adc0";
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
|
@ -145,7 +300,7 @@
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
reg = <0x40044000 DT_SIZE_K(4)>;
|
reg = <0x40044000 DT_SIZE_K(4)>;
|
||||||
resets = <&reset RPI_PICO_RESETS_RESET_I2C0>;
|
resets = <&reset RPI_PICO_RESETS_RESET_I2C0>;
|
||||||
clocks = <&system_clk>;
|
clocks = <&clocks RPI_PICO_CLKID_CLK_SYS>;
|
||||||
interrupts = <23 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
|
interrupts = <23 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
|
||||||
interrupt-names = "i2c0";
|
interrupt-names = "i2c0";
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
|
@ -157,7 +312,7 @@
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
reg = <0x40048000 DT_SIZE_K(4)>;
|
reg = <0x40048000 DT_SIZE_K(4)>;
|
||||||
resets = <&reset RPI_PICO_RESETS_RESET_I2C0>;
|
resets = <&reset RPI_PICO_RESETS_RESET_I2C0>;
|
||||||
clocks = <&system_clk>;
|
clocks = <&clocks RPI_PICO_CLKID_CLK_SYS>;
|
||||||
interrupts = <24 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
|
interrupts = <24 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
|
||||||
interrupt-names = "i2c1";
|
interrupt-names = "i2c1";
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
|
@ -166,7 +321,7 @@
|
||||||
wdt0: watchdog@40058000 {
|
wdt0: watchdog@40058000 {
|
||||||
compatible = "raspberrypi,pico-watchdog";
|
compatible = "raspberrypi,pico-watchdog";
|
||||||
reg = <0x40058000 DT_SIZE_K(4)>;
|
reg = <0x40058000 DT_SIZE_K(4)>;
|
||||||
clocks = <&xtal_clk>;
|
clocks = <&clocks RPI_PICO_CLKID_CLK_REF>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -174,6 +329,7 @@
|
||||||
compatible = "raspberrypi,pico-usbd";
|
compatible = "raspberrypi,pico-usbd";
|
||||||
reg = <0x50100000 0x10000>;
|
reg = <0x50100000 0x10000>;
|
||||||
resets = <&reset RPI_PICO_RESETS_RESET_USBCTRL>;
|
resets = <&reset RPI_PICO_RESETS_RESET_USBCTRL>;
|
||||||
|
clocks = <&clocks RPI_PICO_CLKID_CLK_USB>;
|
||||||
interrupts = <5 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
|
interrupts = <5 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
|
||||||
interrupt-names = "usbctrl";
|
interrupt-names = "usbctrl";
|
||||||
num-bidir-endpoints = <16>;
|
num-bidir-endpoints = <16>;
|
||||||
|
@ -184,7 +340,7 @@
|
||||||
compatible = "raspberrypi,pico-pwm";
|
compatible = "raspberrypi,pico-pwm";
|
||||||
reg = <0x40050000 DT_SIZE_K(4)>;
|
reg = <0x40050000 DT_SIZE_K(4)>;
|
||||||
resets = <&reset RPI_PICO_RESETS_RESET_PWM>;
|
resets = <&reset RPI_PICO_RESETS_RESET_PWM>;
|
||||||
clocks = <&system_clk>;
|
clocks = <&clocks RPI_PICO_CLKID_CLK_SYS>;
|
||||||
interrupts = <4 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
|
interrupts = <4 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
|
||||||
interrupt-names = "PWM_IRQ_WRAP";
|
interrupt-names = "PWM_IRQ_WRAP";
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
|
@ -195,7 +351,7 @@
|
||||||
compatible = "raspberrypi,pico-timer";
|
compatible = "raspberrypi,pico-timer";
|
||||||
reg = <0x40054000 DT_SIZE_K(4)>;
|
reg = <0x40054000 DT_SIZE_K(4)>;
|
||||||
resets = <&reset RPI_PICO_RESETS_RESET_TIMER>;
|
resets = <&reset RPI_PICO_RESETS_RESET_TIMER>;
|
||||||
clocks = <&xtal_clk>;
|
clocks = <&clocks RPI_PICO_CLKID_CLK_REF>;
|
||||||
interrupts = <0 RPI_PICO_DEFAULT_IRQ_PRIORITY>,
|
interrupts = <0 RPI_PICO_DEFAULT_IRQ_PRIORITY>,
|
||||||
<1 RPI_PICO_DEFAULT_IRQ_PRIORITY>,
|
<1 RPI_PICO_DEFAULT_IRQ_PRIORITY>,
|
||||||
<2 RPI_PICO_DEFAULT_IRQ_PRIORITY>,
|
<2 RPI_PICO_DEFAULT_IRQ_PRIORITY>,
|
||||||
|
@ -211,7 +367,7 @@
|
||||||
compatible = "raspberrypi,pico-dma";
|
compatible = "raspberrypi,pico-dma";
|
||||||
reg = <0x50000000 DT_SIZE_K(64)>;
|
reg = <0x50000000 DT_SIZE_K(64)>;
|
||||||
resets = <&reset RPI_PICO_RESETS_RESET_DMA>;
|
resets = <&reset RPI_PICO_RESETS_RESET_DMA>;
|
||||||
clocks = <&system_clk>;
|
clocks = <&clocks RPI_PICO_CLKID_CLK_SYS>;
|
||||||
interrupts = <11 RPI_PICO_DEFAULT_IRQ_PRIORITY>,
|
interrupts = <11 RPI_PICO_DEFAULT_IRQ_PRIORITY>,
|
||||||
<12 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
|
<12 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
|
||||||
interrupt-names = "dma0", "dma1";
|
interrupt-names = "dma0", "dma1";
|
||||||
|
@ -231,7 +387,7 @@
|
||||||
pio0: pio@50200000 {
|
pio0: pio@50200000 {
|
||||||
compatible = "raspberrypi,pico-pio";
|
compatible = "raspberrypi,pico-pio";
|
||||||
reg = <0x50200000 DT_SIZE_K(4)>;
|
reg = <0x50200000 DT_SIZE_K(4)>;
|
||||||
clocks = <&system_clk>;
|
clocks = <&clocks RPI_PICO_CLKID_CLK_SYS>;
|
||||||
resets = <&reset RPI_PICO_RESETS_RESET_PIO0>;
|
resets = <&reset RPI_PICO_RESETS_RESET_PIO0>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
@ -239,7 +395,7 @@
|
||||||
pio1: pio@50300000 {
|
pio1: pio@50300000 {
|
||||||
compatible = "raspberrypi,pico-pio";
|
compatible = "raspberrypi,pico-pio";
|
||||||
reg = <0x50300000 DT_SIZE_K(4)>;
|
reg = <0x50300000 DT_SIZE_K(4)>;
|
||||||
clocks = <&system_clk>;
|
clocks = <&clocks RPI_PICO_CLKID_CLK_SYS>;
|
||||||
resets = <&reset RPI_PICO_RESETS_RESET_PIO1>;
|
resets = <&reset RPI_PICO_RESETS_RESET_PIO1>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
18
dts/bindings/clock/raspberrypi,pico-clock-controller.yaml
Normal file
18
dts/bindings/clock/raspberrypi,pico-clock-controller.yaml
Normal file
|
@ -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
|
18
dts/bindings/clock/raspberrypi,pico-clock.yaml
Normal file
18
dts/bindings/clock/raspberrypi,pico-clock.yaml
Normal file
|
@ -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
|
31
dts/bindings/clock/raspberrypi,pico-pll.yaml
Normal file
31
dts/bindings/clock/raspberrypi,pico-pll.yaml
Normal file
|
@ -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.
|
38
dts/bindings/clock/raspberrypi,pico-rosc.yaml
Normal file
38
dts/bindings/clock/raspberrypi,pico-rosc.yaml
Normal file
|
@ -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
|
44
include/zephyr/dt-bindings/clock/rpi_pico_clock.h
Normal file
44
include/zephyr/dt-bindings/clock/rpi_pico_clock.h
Normal file
|
@ -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_ */
|
|
@ -219,4 +219,11 @@
|
||||||
#define PIO1_P28 RP2040_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_PIO1)
|
#define PIO1_P28 RP2040_PINMUX(28, RP2_PINCTRL_GPIO_FUNC_PIO1)
|
||||||
#define PIO1_P29 RP2040_PINMUX(29, 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__ */
|
#endif /* __RP2040_PINCTRL_H__ */
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
status = "okay";
|
status = "okay";
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
clocks = < &system_clk >;
|
clocks = <&clocks RPI_PICO_CLKID_CLK_SYS>;
|
||||||
miso-gpios = <&gpio0 12 0>;
|
miso-gpios = <&gpio0 12 0>;
|
||||||
cs-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
|
cs-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
|
||||||
clk-gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
|
clk-gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
|
||||||
|
|
|
@ -26,24 +26,6 @@
|
||||||
|
|
||||||
LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL);
|
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.
|
* Some pico-sdk drivers call panic on fatal error.
|
||||||
* This alternative implementation of panic handles the panic
|
* This alternative implementation of panic handles the panic
|
||||||
|
@ -57,5 +39,3 @@ void __attribute__((noreturn)) panic(const char *fmt, ...)
|
||||||
vprintf(fmt, args);
|
vprintf(fmt, args);
|
||||||
k_fatal_halt(K_ERR_CPU_EXCEPTION);
|
k_fatal_halt(K_ERR_CPU_EXCEPTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
SYS_INIT(rp2040_init, PRE_KERNEL_1, 0);
|
|
||||||
|
|
Loading…
Reference in a new issue