drivers: rp2: Add support for RP2350 for vreg
Adds support for RP2350 in vreg regulator driver Signed-off-by: Camille BAUD <mail@massdriver.space>
This commit is contained in:
committed by
Henrik Brix Andersen
parent
1cbaa5f3f5
commit
f8f94fd6cd
@@ -10,19 +10,51 @@
|
||||
#include <zephyr/dt-bindings/regulator/rpi_pico.h>
|
||||
#include <zephyr/sys/linear_range.h>
|
||||
#include <zephyr/toolchain.h>
|
||||
|
||||
#ifdef CONFIG_SOC_SERIES_RP2350
|
||||
#include <hardware/regs/powman.h>
|
||||
#include <hardware/structs/powman.h>
|
||||
#else
|
||||
#include <hardware/regs/vreg_and_chip_reset.h>
|
||||
#include <hardware/structs/vreg_and_chip_reset.h>
|
||||
#endif
|
||||
|
||||
static const struct linear_range core_ranges[] = {
|
||||
#ifdef CONFIG_SOC_SERIES_RP2350
|
||||
LINEAR_RANGE_INIT(550000u, 50000u, 0u, 17u),
|
||||
LINEAR_RANGE_INIT(1500000u, 100000u, 18u, 19u),
|
||||
LINEAR_RANGE_INIT(1650000u, 50000u, 20u, 21u),
|
||||
LINEAR_RANGE_INIT(1800000u, 100000u, 22u, 24u),
|
||||
LINEAR_RANGE_INIT(2350000u, 50000u, 25u, 25u),
|
||||
LINEAR_RANGE_INIT(2500000u, 150000u, 26u, 28u),
|
||||
LINEAR_RANGE_INIT(3000000u, 150000u, 29u, 31u),
|
||||
#else
|
||||
LINEAR_RANGE_INIT(800000u, 0u, 0u, 5u),
|
||||
LINEAR_RANGE_INIT(850000u, 50000u, 6u, 15u),
|
||||
#endif
|
||||
};
|
||||
|
||||
static const size_t num_core_ranges = ARRAY_SIZE(core_ranges);
|
||||
|
||||
#ifdef CONFIG_SOC_SERIES_RP2350
|
||||
#define REG_PICO_TYPE powman_hw_t
|
||||
#define REG_VSEL_POS POWMAN_VREG_VSEL_LSB
|
||||
#define REG_VSEL_MSK POWMAN_VREG_VSEL_BITS
|
||||
#define REG_VALIN(value) (POWMAN_PASSWORD_BITS | (value))
|
||||
#define REG_BOD_VSEL_POS POWMAN_BOD_VSEL_LSB
|
||||
#define REG_BOD_EN_POS POWMAN_BOD_EN_LSB
|
||||
#else
|
||||
#define REG_PICO_TYPE vreg_and_chip_reset_hw_t
|
||||
#define REG_VSEL_POS VREG_AND_CHIP_RESET_VREG_VSEL_LSB
|
||||
#define REG_VSEL_MSK VREG_AND_CHIP_RESET_VREG_VSEL_BITS
|
||||
#define REG_VALIN(value) (value)
|
||||
#define REG_BOD_VSEL_POS VREG_AND_CHIP_RESET_BOD_VSEL_LSB
|
||||
#define REG_BOD_EN_POS VREG_AND_CHIP_RESET_BOD_EN_LSB
|
||||
#endif
|
||||
|
||||
struct regulator_rpi_pico_config {
|
||||
struct regulator_common_config common;
|
||||
vreg_and_chip_reset_hw_t * const reg;
|
||||
REG_PICO_TYPE * const reg;
|
||||
const bool brown_out_detection;
|
||||
const uint32_t brown_out_threshold;
|
||||
};
|
||||
@@ -31,6 +63,17 @@ struct regulator_rpi_pico_data {
|
||||
struct regulator_common_data data;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SOC_SERIES_RP2350
|
||||
static void regulator_rpi_pico_wait_powman(const struct device *dev)
|
||||
{
|
||||
const struct regulator_rpi_pico_config *config = dev->config;
|
||||
|
||||
while (config->reg->vreg & POWMAN_VREG_UPDATE_IN_PROGRESS_BITS) {
|
||||
k_usleep(10);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* APIs
|
||||
*/
|
||||
@@ -57,8 +100,16 @@ static int regulator_rpi_pico_set_voltage(const struct device *dev, int32_t min_
|
||||
return ret;
|
||||
}
|
||||
|
||||
config->reg->vreg = ((config->reg->vreg & ~VREG_AND_CHIP_RESET_VREG_VSEL_BITS) |
|
||||
(idx << VREG_AND_CHIP_RESET_VREG_VSEL_LSB));
|
||||
#ifdef CONFIG_SOC_SERIES_RP2350
|
||||
config->reg->vreg_ctrl |= REG_VALIN(POWMAN_VREG_CTRL_UNLOCK_BITS);
|
||||
regulator_rpi_pico_wait_powman(dev);
|
||||
#endif
|
||||
|
||||
config->reg->vreg = REG_VALIN((config->reg->vreg & ~REG_VSEL_MSK) | idx << REG_VSEL_POS);
|
||||
|
||||
#ifdef CONFIG_SOC_SERIES_RP2350
|
||||
regulator_rpi_pico_wait_powman(dev);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -69,25 +120,27 @@ static int regulator_rpi_pico_get_voltage(const struct device *dev, int32_t *vol
|
||||
|
||||
return linear_range_group_get_value(
|
||||
core_ranges, num_core_ranges,
|
||||
((config->reg->vreg & VREG_AND_CHIP_RESET_VREG_VSEL_BITS) >>
|
||||
VREG_AND_CHIP_RESET_VREG_VSEL_LSB),
|
||||
volt_uv);
|
||||
((config->reg->vreg & REG_VSEL_MSK) >> REG_VSEL_POS), volt_uv);
|
||||
}
|
||||
|
||||
static int regulator_rpi_pico_enable(const struct device *dev)
|
||||
{
|
||||
#ifdef CONFIG_SOC_SERIES_RP2040
|
||||
const struct regulator_rpi_pico_config *config = dev->config;
|
||||
|
||||
config->reg->vreg |= BIT(VREG_AND_CHIP_RESET_VREG_EN_LSB);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int regulator_rpi_pico_disable(const struct device *dev)
|
||||
{
|
||||
#ifdef CONFIG_SOC_SERIES_RP2040
|
||||
const struct regulator_rpi_pico_config *config = dev->config;
|
||||
|
||||
config->reg->vreg &= ~BIT(VREG_AND_CHIP_RESET_VREG_EN_LSB);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -97,9 +150,9 @@ static int regulator_rpi_pico_set_mode(const struct device *dev, regulator_mode_
|
||||
const struct regulator_rpi_pico_config *config = dev->config;
|
||||
|
||||
if (mode & REGULATOR_RPI_PICO_MODE_HI_Z) {
|
||||
config->reg->vreg |= REGULATOR_RPI_PICO_MODE_HI_Z;
|
||||
config->reg->vreg |= REG_VALIN(REGULATOR_RPI_PICO_MODE_HI_Z);
|
||||
} else {
|
||||
config->reg->vreg &= (~REGULATOR_RPI_PICO_MODE_HI_Z);
|
||||
config->reg->vreg = REG_VALIN(config->reg->vreg & ~REGULATOR_RPI_PICO_MODE_HI_Z);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -119,11 +172,10 @@ static int regulator_rpi_pico_init(const struct device *dev)
|
||||
const struct regulator_rpi_pico_config *config = dev->config;
|
||||
|
||||
if (config->brown_out_detection) {
|
||||
config->reg->bod =
|
||||
(BIT(VREG_AND_CHIP_RESET_BOD_EN_LSB) |
|
||||
(config->brown_out_threshold << VREG_AND_CHIP_RESET_BOD_VSEL_LSB));
|
||||
config->reg->bod = REG_VALIN(BIT(REG_BOD_EN_POS) |
|
||||
(config->brown_out_threshold << REG_BOD_VSEL_POS));
|
||||
} else {
|
||||
config->reg->bod &= ~BIT(VREG_AND_CHIP_RESET_BOD_EN_LSB);
|
||||
config->reg->bod = REG_VALIN(config->reg->bod & ~BIT(REG_BOD_EN_POS));
|
||||
}
|
||||
|
||||
regulator_common_data_init(dev);
|
||||
@@ -147,12 +199,15 @@ static DEVICE_API(regulator, api) = {
|
||||
\
|
||||
static const struct regulator_rpi_pico_config config_##inst = { \
|
||||
.common = REGULATOR_DT_COMMON_CONFIG_INIT(inst), \
|
||||
.reg = (vreg_and_chip_reset_hw_t * const)DT_INST_REG_ADDR(inst), \
|
||||
.reg = (REG_PICO_TYPE * const)DT_INST_REG_ADDR(inst), \
|
||||
.brown_out_detection = DT_INST_PROP(inst, raspberrypi_brown_out_detection), \
|
||||
.brown_out_threshold = DT_INST_ENUM_IDX(inst, raspberrypi_brown_out_threshold), \
|
||||
}; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(inst, regulator_rpi_pico_init, NULL, &data_##inst, &config_##inst, \
|
||||
POST_KERNEL, CONFIG_REGULATOR_RPI_PICO_INIT_PRIORITY, &api);
|
||||
POST_KERNEL, CONFIG_REGULATOR_RPI_PICO_INIT_PRIORITY, &api); \
|
||||
IF_ENABLED(CONFIG_SOC_SERIES_RP2040, \
|
||||
(BUILD_ASSERT(DT_INST_ENUM_IDX(inst, raspberrypi_brown_out_threshold) < 16, \
|
||||
"On RP2040, BOD threshold must be lower than 1161000");)) \
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(REGULATOR_RPI_PICO_DEFINE_ALL)
|
||||
|
||||
@@ -43,6 +43,9 @@ properties:
|
||||
- 1032000
|
||||
- 1075000
|
||||
- 1118000
|
||||
- 1161000
|
||||
- 1204000
|
||||
description: |
|
||||
Reset if the core voltage drops below this threshold for a particular time
|
||||
(determined by the 'brown-out detection assertion delay').
|
||||
On RP2040, the threshold must be less than 1.161V.
|
||||
|
||||
7
dts/vendor/raspberrypi/rpi_pico/rp2350.dtsi
vendored
7
dts/vendor/raspberrypi/rpi_pico/rp2350.dtsi
vendored
@@ -405,6 +405,13 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
vreg: vreg@40100000 {
|
||||
compatible = "raspberrypi,core-supply-regulator";
|
||||
reg = <0x40100000 0x200>;
|
||||
status = "okay";
|
||||
raspberrypi,brown-out-detection;
|
||||
};
|
||||
|
||||
dma: dma@50000000 {
|
||||
compatible = "raspberrypi,pico-dma";
|
||||
reg = <0x50000000 DT_SIZE_K(64)>;
|
||||
|
||||
Reference in New Issue
Block a user