Merge branches 'clk-zynq', 'clk-xilinx' and 'clk-stm' into clk-next

- Update Zynqmp driver for Versal NET platforms
 - Add clk driver for Versal clocking wizard IP

* clk-zynq:
  drivers: clk: zynqmp: update divider round rate logic
  drivers: clk: zynqmp: calculate closest mux rate

* clk-xilinx:
  clocking-wizard: Add support for versal clocking wizard
  dt-bindings: clock: xilinx: add versal compatible

* clk-stm:
  dt-bindings: stm32: add clocks and reset binding for stm32mp25 platform
  clk: stm32mp1: use stm32mp13 reset driver
  clk: stm32mp1: move stm32mp1 clock driver into stm32 directory
This commit is contained in:
Stephen Boyd 2024-01-09 11:55:06 -08:00
commit a4dcb2f84b
17 changed files with 1352 additions and 294 deletions

View file

@ -0,0 +1,76 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/st,stm32mp25-rcc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: STM32MP25 Reset Clock Controller
maintainers:
- Gabriel Fernandez <gabriel.fernandez@foss.st.com>
description: |
The RCC hardware block is both a reset and a clock controller.
RCC makes also power management (resume/supend).
See also::
include/dt-bindings/clock/st,stm32mp25-rcc.h
include/dt-bindings/reset/st,stm32mp25-rcc.h
properties:
compatible:
enum:
- st,stm32mp25-rcc
reg:
maxItems: 1
'#clock-cells':
const: 1
'#reset-cells':
const: 1
clocks:
items:
- description: CK_SCMI_HSE High Speed External oscillator (8 to 48 MHz)
- description: CK_SCMI_HSI High Speed Internal oscillator (~ 64 MHz)
- description: CK_SCMI_MSI Low Power Internal oscillator (~ 4 MHz or ~ 16 MHz)
- description: CK_SCMI_LSE Low Speed External oscillator (32 KHz)
- description: CK_SCMI_LSI Low Speed Internal oscillator (~ 32 KHz)
clock-names:
items:
- const: hse
- const: hsi
- const: msi
- const: lse
- const: lsi
required:
- compatible
- reg
- '#clock-cells'
- '#reset-cells'
- clocks
- clock-names
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/st,stm32mp25-rcc.h>
rcc: clock-controller@44200000 {
compatible = "st,stm32mp25-rcc";
reg = <0x44200000 0x10000>;
#clock-cells = <1>;
#reset-cells = <1>;
clock-names = "hse", "hsi", "msi", "lse", "lsi";
clocks = <&scmi_clk CK_SCMI_HSE>,
<&scmi_clk CK_SCMI_HSI>,
<&scmi_clk CK_SCMI_MSI>,
<&scmi_clk CK_SCMI_LSE>,
<&scmi_clk CK_SCMI_LSI>;
};
...

View file

@ -20,6 +20,7 @@ properties:
- xlnx,clocking-wizard
- xlnx,clocking-wizard-v5.2
- xlnx,clocking-wizard-v6.0
- xlnx,versal-clk-wizard
reg:

View file

@ -414,16 +414,6 @@ config COMMON_CLK_VC7
Renesas Versaclock7 is a family of configurable clock generator
and jitter attenuator ICs with fractional and integer dividers.
config COMMON_CLK_STM32MP135
def_bool COMMON_CLK && MACH_STM32MP13
help
Support for stm32mp135 SoC family clocks
config COMMON_CLK_STM32MP157
def_bool COMMON_CLK && MACH_STM32MP157
help
Support for stm32mp157 SoC family clocks
config COMMON_CLK_STM32F
def_bool COMMON_CLK && (MACH_STM32F429 || MACH_STM32F469 || MACH_STM32F746)
help
@ -504,6 +494,7 @@ source "drivers/clk/starfive/Kconfig"
source "drivers/clk/sunxi/Kconfig"
source "drivers/clk/sunxi-ng/Kconfig"
source "drivers/clk/tegra/Kconfig"
source "drivers/clk/stm32/Kconfig"
source "drivers/clk/ti/Kconfig"
source "drivers/clk/uniphier/Kconfig"
source "drivers/clk/visconti/Kconfig"

View file

@ -70,7 +70,6 @@ obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o
obj-$(CONFIG_COMMON_CLK_SP7021) += clk-sp7021.o
obj-$(CONFIG_COMMON_CLK_STM32F) += clk-stm32f4.o
obj-$(CONFIG_COMMON_CLK_STM32H7) += clk-stm32h7.o
obj-$(CONFIG_COMMON_CLK_STM32MP157) += clk-stm32mp1.o
obj-$(CONFIG_COMMON_CLK_TPS68470) += clk-tps68470.o
obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
obj-$(CONFIG_CLK_TWL) += clk-twl.o

29
drivers/clk/stm32/Kconfig Normal file
View file

@ -0,0 +1,29 @@
# SPDX-License-Identifier: GPL-2.0-only
# common clock support for STMicroelectronics SoC family.
menuconfig COMMON_CLK_STM32MP
bool "Clock support for common STM32MP clocks"
depends on ARCH_STM32 || COMPILE_TEST
default y
select RESET_CONTROLLER
help
Support for STM32MP SoC family clocks.
if COMMON_CLK_STM32MP
config COMMON_CLK_STM32MP135
bool "Clock driver for stm32mp13x clocks"
depends on ARM || COMPILE_TEST
default y
help
Support for stm32mp13x SoC family clocks.
config COMMON_CLK_STM32MP157
bool "Clock driver for stm32mp15x clocks"
depends on ARM || COMPILE_TEST
default y
help
Support for stm32mp15x SoC family clocks.
endif

View file

@ -1 +1,2 @@
obj-$(CONFIG_COMMON_CLK_STM32MP135) += clk-stm32mp13.o clk-stm32-core.o reset-stm32.o
obj-$(CONFIG_COMMON_CLK_STM32MP157) += clk-stm32mp1.o reset-stm32.o

View file

@ -70,6 +70,7 @@ static int stm32_rcc_clock_init(struct device *dev,
int stm32_rcc_init(struct device *dev, const struct of_device_id *match_data,
void __iomem *base)
{
const struct stm32_rcc_match_data *rcc_match_data;
const struct of_device_id *match;
int err;
@ -79,8 +80,10 @@ int stm32_rcc_init(struct device *dev, const struct of_device_id *match_data,
return -ENODEV;
}
rcc_match_data = match->data;
/* RCC Reset Configuration */
err = stm32_rcc_reset_init(dev, match, base);
err = stm32_rcc_reset_init(dev, rcc_match_data->reset_data, base);
if (err) {
pr_err("stm32 reset failed to initialize\n");
return err;

View file

@ -70,15 +70,12 @@ struct stm32_rcc_match_data {
const struct clock_config *tab_clocks;
unsigned int maxbinding;
struct clk_stm32_clock_data *clock_data;
u32 clear_offset;
struct clk_stm32_reset_data *reset_data;
int (*check_security)(void __iomem *base,
const struct clock_config *cfg);
int (*multi_mux)(void __iomem *base, const struct clock_config *cfg);
};
int stm32_rcc_reset_init(struct device *dev, const struct of_device_id *match,
void __iomem *base);
int stm32_rcc_init(struct device *dev, const struct of_device_id *match_data,
void __iomem *base);

View file

@ -20,6 +20,10 @@
#include <dt-bindings/clock/stm32mp1-clks.h>
#include "reset-stm32.h"
#define STM32MP1_RESET_ID_MASK GENMASK(15, 0)
static DEFINE_SPINLOCK(rlock);
#define RCC_OCENSETR 0x0C
@ -2137,22 +2141,27 @@ struct stm32_rcc_match_data {
const struct clock_config *cfg;
unsigned int num;
unsigned int maxbinding;
u32 clear_offset;
struct clk_stm32_reset_data *reset_data;
bool (*check_security)(const struct clock_config *cfg);
};
static struct clk_stm32_reset_data stm32mp1_reset_data = {
.nr_lines = STM32MP1_RESET_ID_MASK,
.clear_offset = RCC_CLR,
};
static struct stm32_rcc_match_data stm32mp1_data = {
.cfg = stm32mp1_clock_cfg,
.num = ARRAY_SIZE(stm32mp1_clock_cfg),
.maxbinding = STM32MP1_LAST_CLK,
.clear_offset = RCC_CLR,
.reset_data = &stm32mp1_reset_data,
};
static struct stm32_rcc_match_data stm32mp1_data_secure = {
.cfg = stm32mp1_clock_cfg,
.num = ARRAY_SIZE(stm32mp1_clock_cfg),
.maxbinding = STM32MP1_LAST_CLK,
.clear_offset = RCC_CLR,
.reset_data = &stm32mp1_reset_data,
.check_security = &stm32_check_security
};
@ -2193,113 +2202,6 @@ static int stm32_register_hw_clk(struct device *dev,
return 0;
}
#define STM32_RESET_ID_MASK GENMASK(15, 0)
struct stm32_reset_data {
/* reset lock */
spinlock_t lock;
struct reset_controller_dev rcdev;
void __iomem *membase;
u32 clear_offset;
};
static inline struct stm32_reset_data *
to_stm32_reset_data(struct reset_controller_dev *rcdev)
{
return container_of(rcdev, struct stm32_reset_data, rcdev);
}
static int stm32_reset_update(struct reset_controller_dev *rcdev,
unsigned long id, bool assert)
{
struct stm32_reset_data *data = to_stm32_reset_data(rcdev);
int reg_width = sizeof(u32);
int bank = id / (reg_width * BITS_PER_BYTE);
int offset = id % (reg_width * BITS_PER_BYTE);
if (data->clear_offset) {
void __iomem *addr;
addr = data->membase + (bank * reg_width);
if (!assert)
addr += data->clear_offset;
writel(BIT(offset), addr);
} else {
unsigned long flags;
u32 reg;
spin_lock_irqsave(&data->lock, flags);
reg = readl(data->membase + (bank * reg_width));
if (assert)
reg |= BIT(offset);
else
reg &= ~BIT(offset);
writel(reg, data->membase + (bank * reg_width));
spin_unlock_irqrestore(&data->lock, flags);
}
return 0;
}
static int stm32_reset_assert(struct reset_controller_dev *rcdev,
unsigned long id)
{
return stm32_reset_update(rcdev, id, true);
}
static int stm32_reset_deassert(struct reset_controller_dev *rcdev,
unsigned long id)
{
return stm32_reset_update(rcdev, id, false);
}
static int stm32_reset_status(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct stm32_reset_data *data = to_stm32_reset_data(rcdev);
int reg_width = sizeof(u32);
int bank = id / (reg_width * BITS_PER_BYTE);
int offset = id % (reg_width * BITS_PER_BYTE);
u32 reg;
reg = readl(data->membase + (bank * reg_width));
return !!(reg & BIT(offset));
}
static const struct reset_control_ops stm32_reset_ops = {
.assert = stm32_reset_assert,
.deassert = stm32_reset_deassert,
.status = stm32_reset_status,
};
static int stm32_rcc_reset_init(struct device *dev, void __iomem *base,
const struct of_device_id *match)
{
const struct stm32_rcc_match_data *data = match->data;
struct stm32_reset_data *reset_data = NULL;
reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL);
if (!reset_data)
return -ENOMEM;
spin_lock_init(&reset_data->lock);
reset_data->membase = base;
reset_data->rcdev.owner = THIS_MODULE;
reset_data->rcdev.ops = &stm32_reset_ops;
reset_data->rcdev.of_node = dev_of_node(dev);
reset_data->rcdev.nr_resets = STM32_RESET_ID_MASK;
reset_data->clear_offset = data->clear_offset;
return reset_controller_register(&reset_data->rcdev);
}
static int stm32_rcc_clock_init(struct device *dev, void __iomem *base,
const struct of_device_id *match)
{
@ -2342,6 +2244,7 @@ static int stm32_rcc_clock_init(struct device *dev, void __iomem *base,
static int stm32_rcc_init(struct device *dev, void __iomem *base,
const struct of_device_id *match_data)
{
const struct stm32_rcc_match_data *rcc_match_data;
const struct of_device_id *match;
int err;
@ -2351,8 +2254,10 @@ static int stm32_rcc_init(struct device *dev, void __iomem *base,
return -ENODEV;
}
rcc_match_data = match->data;
/* RCC Reset Configuration */
err = stm32_rcc_reset_init(dev, base, match);
err = stm32_rcc_reset_init(dev, rcc_match_data->reset_data, base);
if (err) {
pr_err("stm32mp1 reset failed to initialize\n");
return err;

View file

@ -10,8 +10,10 @@
#include <linux/platform_device.h>
#include <dt-bindings/clock/stm32mp13-clks.h>
#include "clk-stm32-core.h"
#include "reset-stm32.h"
#include "stm32mp13_rcc.h"
#define STM32MP1_RESET_ID_MASK GENMASK(15, 0)
#define RCC_CLR_OFFSET 0x4
/* STM32 Gates definition */
@ -1511,13 +1513,18 @@ static struct clk_stm32_clock_data stm32mp13_clock_data = {
.is_multi_mux = stm32mp13_is_multi_mux,
};
static struct clk_stm32_reset_data stm32mp13_reset_data = {
.nr_lines = STM32MP1_RESET_ID_MASK,
.clear_offset = RCC_CLR_OFFSET,
};
static const struct stm32_rcc_match_data stm32mp13_data = {
.tab_clocks = stm32mp13_clock_cfg,
.num_clocks = ARRAY_SIZE(stm32mp13_clock_cfg),
.clock_data = &stm32mp13_clock_data,
.check_security = &stm32mp13_clock_is_provided_by_secure,
.maxbinding = STM32MP1_LAST_CLK,
.clear_offset = RCC_CLR_OFFSET,
.reset_data = &stm32mp13_reset_data,
};
static const struct of_device_id stm32mp13_match_data[] = {

View file

@ -11,9 +11,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
#include "clk-stm32-core.h"
#define STM32_RESET_ID_MASK GENMASK(15, 0)
#include "reset-stm32.h"
struct stm32_reset_data {
/* reset lock */
@ -99,24 +97,22 @@ static const struct reset_control_ops stm32_reset_ops = {
.status = stm32_reset_status,
};
int stm32_rcc_reset_init(struct device *dev, const struct of_device_id *match,
int stm32_rcc_reset_init(struct device *dev, struct clk_stm32_reset_data *data,
void __iomem *base)
{
const struct stm32_rcc_match_data *data = match->data;
struct stm32_reset_data *reset_data = NULL;
data = match->data;
struct stm32_reset_data *reset_data;
reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL);
if (!reset_data)
return -ENOMEM;
spin_lock_init(&reset_data->lock);
reset_data->membase = base;
reset_data->rcdev.owner = THIS_MODULE;
reset_data->rcdev.ops = &stm32_reset_ops;
reset_data->rcdev.of_node = dev_of_node(dev);
reset_data->rcdev.nr_resets = STM32_RESET_ID_MASK;
reset_data->rcdev.nr_resets = data->nr_lines;
reset_data->clear_offset = data->clear_offset;
return reset_controller_register(&reset_data->rcdev);

View file

@ -4,5 +4,11 @@
* Author: Gabriel Fernandez <gabriel.fernandez@foss.st.com> for STMicroelectronics.
*/
int stm32_rcc_reset_init(struct device *dev, const struct of_device_id *match,
struct clk_stm32_reset_data {
const struct reset_control_ops *ops;
unsigned int nr_lines;
u32 clear_offset;
};
int stm32_rcc_reset_init(struct device *dev, struct clk_stm32_reset_data *data,
void __iomem *base);

View file

@ -23,15 +23,41 @@
#define WZRD_NUM_OUTPUTS 7
#define WZRD_ACLK_MAX_FREQ 250000000UL
#define WZRD_CLK_CFG_REG(n) (0x200 + 4 * (n))
#define WZRD_CLK_CFG_REG(v, n) (0x200 + 0x130 * (v) + 4 * (n))
#define WZRD_CLKOUT0_FRAC_EN BIT(18)
#define WZRD_CLKFBOUT_FRAC_EN BIT(26)
#define WZRD_CLKFBOUT_1 0
#define WZRD_CLKFBOUT_2 1
#define WZRD_CLKOUT0_1 2
#define WZRD_CLKOUT0_2 3
#define WZRD_DESKEW_2 20
#define WZRD_DIVCLK 21
#define WZRD_CLKFBOUT_4 51
#define WZRD_CLKFBOUT_3 48
#define WZRD_DUTY_CYCLE 2
#define WZRD_O_DIV 4
#define WZRD_CLKFBOUT_FRAC_EN BIT(1)
#define WZRD_CLKFBOUT_PREDIV2 (BIT(11) | BIT(12) | BIT(9))
#define WZRD_MULT_PREDIV2 (BIT(10) | BIT(9) | BIT(12))
#define WZRD_CLKFBOUT_EDGE BIT(8)
#define WZRD_P5EN BIT(13)
#define WZRD_P5EN_SHIFT 13
#define WZRD_P5FEDGE BIT(15)
#define WZRD_DIVCLK_EDGE BIT(10)
#define WZRD_P5FEDGE_SHIFT 15
#define WZRD_CLKOUT0_PREDIV2 BIT(11)
#define WZRD_EDGE_SHIFT 8
#define WZRD_CLKFBOUT_MULT_SHIFT 8
#define WZRD_CLKFBOUT_MULT_MASK (0xff << WZRD_CLKFBOUT_MULT_SHIFT)
#define WZRD_CLKFBOUT_L_SHIFT 0
#define WZRD_CLKFBOUT_H_SHIFT 8
#define WZRD_CLKFBOUT_L_MASK GENMASK(7, 0)
#define WZRD_CLKFBOUT_H_MASK GENMASK(15, 8)
#define WZRD_CLKFBOUT_FRAC_SHIFT 16
#define WZRD_CLKFBOUT_FRAC_MASK (0x3ff << WZRD_CLKFBOUT_FRAC_SHIFT)
#define WZRD_VERSAL_FRAC_MASK GENMASK(5, 0)
#define WZRD_DIVCLK_DIVIDE_SHIFT 0
#define WZRD_DIVCLK_DIVIDE_MASK (0xff << WZRD_DIVCLK_DIVIDE_SHIFT)
#define WZRD_CLKOUT_DIVIDE_SHIFT 0
@ -45,6 +71,7 @@
#define WZRD_DR_STATUS_REG_OFFSET 0x04
#define WZRD_DR_LOCK_BIT_MASK 0x00000001
#define WZRD_DR_INIT_REG_OFFSET 0x25C
#define WZRD_DR_INIT_VERSAL_OFFSET 0x14
#define WZRD_DR_DIV_TO_PHASE_OFFSET 4
#define WZRD_DR_BEGIN_DYNA_RECONF 0x03
#define WZRD_DR_BEGIN_DYNA_RECONF_5_2 0x07
@ -52,6 +79,8 @@
#define WZRD_USEC_POLL 10
#define WZRD_TIMEOUT_POLL 1000
#define WZRD_FRAC_GRADIENT 64
#define PREDIV2_MULT 2
/* Divider limits, from UG572 Table 3-4 for Ultrascale+ */
#define DIV_O 0x01
@ -65,6 +94,14 @@
#define WZRD_VCO_MAX 1600000000
#define WZRD_O_MIN 1
#define WZRD_O_MAX 128
#define VER_WZRD_M_MIN 4
#define VER_WZRD_M_MAX 432
#define VER_WZRD_D_MIN 1
#define VER_WZRD_D_MAX 123
#define VER_WZRD_VCO_MIN 2160000000ULL
#define VER_WZRD_VCO_MAX 4320000000ULL
#define VER_WZRD_O_MIN 2
#define VER_WZRD_O_MAX 511
#define WZRD_MIN_ERR 20000
#define WZRD_FRAC_POINTS 1000
@ -135,6 +172,10 @@ struct clk_wzrd_divider {
spinlock_t *lock; /* divider lock */
};
struct versal_clk_data {
bool is_versal;
};
#define to_clk_wzrd(_nb) container_of(_nb, struct clk_wzrd, nb)
/* maximum frequencies for input/output clocks per speed grade */
@ -147,6 +188,31 @@ static const unsigned long clk_wzrd_max_freq[] = {
/* spin lock variable for clk_wzrd */
static DEFINE_SPINLOCK(clkwzrd_lock);
static unsigned long clk_wzrd_recalc_rate_ver(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
void __iomem *div_addr = divider->base + divider->offset;
u32 div, p5en, edge, prediv2, all;
unsigned int vall, valh;
edge = !!(readl(div_addr) & WZRD_CLKFBOUT_EDGE);
p5en = !!(readl(div_addr) & WZRD_P5EN);
prediv2 = !!(readl(div_addr) & WZRD_CLKOUT0_PREDIV2);
vall = readl(div_addr + 4) & WZRD_CLKFBOUT_L_MASK;
valh = readl(div_addr + 4) >> WZRD_CLKFBOUT_H_SHIFT;
all = valh + vall + edge;
if (!all)
all = 1;
if (prediv2)
div = 2 * all + prediv2 * p5en;
else
div = all;
return DIV_ROUND_UP_ULL((u64)parent_rate, div);
}
static unsigned long clk_wzrd_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
@ -161,19 +227,64 @@ static unsigned long clk_wzrd_recalc_rate(struct clk_hw *hw,
divider->flags, divider->width);
}
static int clk_wzrd_ver_dynamic_reconfig(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
void __iomem *div_addr = divider->base + divider->offset;
u32 value, regh, edged, p5en, p5fedge, regval, regval1;
unsigned long flags;
int err;
spin_lock_irqsave(divider->lock, flags);
value = DIV_ROUND_CLOSEST(parent_rate, rate);
regh = (value / 4);
regval1 = readl(div_addr);
regval1 |= WZRD_CLKFBOUT_PREDIV2;
regval1 = regval1 & ~(WZRD_CLKFBOUT_EDGE | WZRD_P5EN | WZRD_P5FEDGE);
if (value % 4 > 1) {
edged = 1;
regval1 |= (edged << WZRD_EDGE_SHIFT);
}
p5fedge = value % 2;
p5en = value % 2;
regval1 = regval1 | p5en << WZRD_P5EN_SHIFT | p5fedge << WZRD_P5FEDGE_SHIFT;
writel(regval1, div_addr);
regval = regh | regh << WZRD_CLKFBOUT_H_SHIFT;
writel(regval, div_addr + 4);
/* Check status register */
err = readl_poll_timeout_atomic(divider->base + WZRD_DR_STATUS_REG_OFFSET,
value, value & WZRD_DR_LOCK_BIT_MASK,
WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
if (err)
goto err_reconfig;
/* Initiate reconfiguration */
writel(WZRD_DR_BEGIN_DYNA_RECONF,
divider->base + WZRD_DR_INIT_VERSAL_OFFSET);
/* Check status register */
err = readl_poll_timeout_atomic(divider->base + WZRD_DR_STATUS_REG_OFFSET,
value, value & WZRD_DR_LOCK_BIT_MASK,
WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
err_reconfig:
spin_unlock_irqrestore(divider->lock, flags);
return err;
}
static int clk_wzrd_dynamic_reconfig(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
int err;
u32 value;
unsigned long flags = 0;
struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
void __iomem *div_addr = divider->base + divider->offset;
unsigned long flags;
u32 value;
int err;
if (divider->lock)
spin_lock_irqsave(divider->lock, flags);
else
__acquire(divider->lock);
spin_lock_irqsave(divider->lock, flags);
value = DIV_ROUND_CLOSEST(parent_rate, rate);
@ -185,9 +296,9 @@ static int clk_wzrd_dynamic_reconfig(struct clk_hw *hw, unsigned long rate,
writel(0x00, div_addr + WZRD_DR_DIV_TO_PHASE_OFFSET);
/* Check status register */
err = readl_poll_timeout(divider->base + WZRD_DR_STATUS_REG_OFFSET,
value, value & WZRD_DR_LOCK_BIT_MASK,
WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
err = readl_poll_timeout_atomic(divider->base + WZRD_DR_STATUS_REG_OFFSET,
value, value & WZRD_DR_LOCK_BIT_MASK,
WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
if (err)
goto err_reconfig;
@ -198,14 +309,11 @@ static int clk_wzrd_dynamic_reconfig(struct clk_hw *hw, unsigned long rate,
divider->base + WZRD_DR_INIT_REG_OFFSET);
/* Check status register */
err = readl_poll_timeout(divider->base + WZRD_DR_STATUS_REG_OFFSET,
value, value & WZRD_DR_LOCK_BIT_MASK,
WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
err = readl_poll_timeout_atomic(divider->base + WZRD_DR_STATUS_REG_OFFSET,
value, value & WZRD_DR_LOCK_BIT_MASK,
WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
err_reconfig:
if (divider->lock)
spin_unlock_irqrestore(divider->lock, flags);
else
__release(divider->lock);
spin_unlock_irqrestore(divider->lock, flags);
return err;
}
@ -223,18 +331,28 @@ static long clk_wzrd_round_rate(struct clk_hw *hw, unsigned long rate,
return *prate / div;
}
static int clk_wzrd_get_divisors(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
static int clk_wzrd_get_divisors_ver(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
unsigned long vco_freq, freq, diff;
u64 vco_freq, freq, diff, vcomin, vcomax;
u32 m, d, o;
u32 mmin, mmax, dmin, dmax, omin, omax;
for (m = WZRD_M_MIN; m <= WZRD_M_MAX; m++) {
for (d = WZRD_D_MIN; d <= WZRD_D_MAX; d++) {
mmin = VER_WZRD_M_MIN;
mmax = VER_WZRD_M_MAX;
dmin = VER_WZRD_D_MIN;
dmax = VER_WZRD_D_MAX;
omin = VER_WZRD_O_MIN;
omax = VER_WZRD_O_MAX;
vcomin = VER_WZRD_VCO_MIN;
vcomax = VER_WZRD_VCO_MAX;
for (m = mmin; m <= mmax; m++) {
for (d = dmin; d <= dmax; d++) {
vco_freq = DIV_ROUND_CLOSEST((parent_rate * m), d);
if (vco_freq >= WZRD_VCO_MIN && vco_freq <= WZRD_VCO_MAX) {
for (o = WZRD_O_MIN; o <= WZRD_O_MAX; o++) {
if (vco_freq >= vcomin && vco_freq <= vcomax) {
for (o = omin; o <= omax; o++) {
freq = DIV_ROUND_CLOSEST_ULL(vco_freq, o);
diff = abs(freq - rate);
@ -251,12 +369,137 @@ static int clk_wzrd_get_divisors(struct clk_hw *hw, unsigned long rate,
return -EBUSY;
}
static int clk_wzrd_get_divisors(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
u64 vco_freq, freq, diff, vcomin, vcomax;
u32 m, d, o;
u32 mmin, mmax, dmin, dmax, omin, omax;
mmin = WZRD_M_MIN;
mmax = WZRD_M_MAX;
dmin = WZRD_D_MIN;
dmax = WZRD_D_MAX;
omin = WZRD_O_MIN;
omax = WZRD_O_MAX;
vcomin = WZRD_VCO_MIN;
vcomax = WZRD_VCO_MAX;
for (m = mmin; m <= mmax; m++) {
for (d = dmin; d <= dmax; d++) {
vco_freq = DIV_ROUND_CLOSEST((parent_rate * m), d);
if (vco_freq >= vcomin && vco_freq <= vcomax) {
for (o = omin; o <= omax; o++) {
freq = DIV_ROUND_CLOSEST_ULL(vco_freq, o);
diff = abs(freq - rate);
if (diff < WZRD_MIN_ERR) {
divider->m = m;
divider->d = d;
divider->o = o;
return 0;
}
}
}
}
}
return -EBUSY;
}
static int clk_wzrd_reconfig(struct clk_wzrd_divider *divider, void __iomem *div_addr)
{
u32 value;
int err;
/* Check status register */
err = readl_poll_timeout_atomic(divider->base + WZRD_DR_STATUS_REG_OFFSET, value,
value & WZRD_DR_LOCK_BIT_MASK,
WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
if (err)
return -ETIMEDOUT;
/* Initiate reconfiguration */
writel(WZRD_DR_BEGIN_DYNA_RECONF, div_addr);
/* Check status register */
return readl_poll_timeout_atomic(divider->base + WZRD_DR_STATUS_REG_OFFSET, value,
value & WZRD_DR_LOCK_BIT_MASK,
WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
}
static int clk_wzrd_dynamic_ver_all_nolock(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
u32 regh, edged, p5en, p5fedge, value2, m, regval, regval1, value;
struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
void __iomem *div_addr;
int err;
err = clk_wzrd_get_divisors_ver(hw, rate, parent_rate);
if (err)
return err;
writel(0, divider->base + WZRD_CLK_CFG_REG(1, WZRD_CLKFBOUT_4));
m = divider->m;
edged = m % WZRD_DUTY_CYCLE;
regh = m / WZRD_DUTY_CYCLE;
regval1 = readl(divider->base + WZRD_CLK_CFG_REG(1,
WZRD_CLKFBOUT_1));
regval1 |= WZRD_MULT_PREDIV2;
if (edged)
regval1 = regval1 | WZRD_CLKFBOUT_EDGE;
else
regval1 = regval1 & ~WZRD_CLKFBOUT_EDGE;
writel(regval1, divider->base + WZRD_CLK_CFG_REG(1,
WZRD_CLKFBOUT_1));
regval1 = regh | regh << WZRD_CLKFBOUT_H_SHIFT;
writel(regval1, divider->base + WZRD_CLK_CFG_REG(1,
WZRD_CLKFBOUT_2));
value2 = divider->d;
edged = value2 % WZRD_DUTY_CYCLE;
regh = (value2 / WZRD_DUTY_CYCLE);
regval1 = FIELD_PREP(WZRD_DIVCLK_EDGE, edged);
writel(regval1, divider->base + WZRD_CLK_CFG_REG(1,
WZRD_DESKEW_2));
regval1 = regh | regh << WZRD_CLKFBOUT_H_SHIFT;
writel(regval1, divider->base + WZRD_CLK_CFG_REG(1, WZRD_DIVCLK));
value = divider->o;
regh = value / WZRD_O_DIV;
regval1 = readl(divider->base + WZRD_CLK_CFG_REG(1,
WZRD_CLKOUT0_1));
regval1 |= WZRD_CLKFBOUT_PREDIV2;
regval1 = regval1 & ~(WZRD_CLKFBOUT_EDGE | WZRD_P5EN | WZRD_P5FEDGE);
if (value % WZRD_O_DIV > 1) {
edged = 1;
regval1 |= edged << WZRD_CLKFBOUT_H_SHIFT;
}
p5fedge = value % WZRD_DUTY_CYCLE;
p5en = value % WZRD_DUTY_CYCLE;
regval1 = regval1 | FIELD_PREP(WZRD_P5EN, p5en) | FIELD_PREP(WZRD_P5FEDGE, p5fedge);
writel(regval1, divider->base + WZRD_CLK_CFG_REG(1,
WZRD_CLKOUT0_1));
regval = regh | regh << WZRD_CLKFBOUT_H_SHIFT;
writel(regval, divider->base + WZRD_CLK_CFG_REG(1,
WZRD_CLKOUT0_2));
div_addr = divider->base + WZRD_DR_INIT_VERSAL_OFFSET;
return clk_wzrd_reconfig(divider, div_addr);
}
static int clk_wzrd_dynamic_all_nolock(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
unsigned long vco_freq, rate_div, clockout0_div;
u32 reg, pre, value, f;
void __iomem *div_addr = divider->base;
u32 reg, pre, f;
int err;
err = clk_wzrd_get_divisors(hw, rate, parent_rate);
@ -275,35 +518,22 @@ static int clk_wzrd_dynamic_all_nolock(struct clk_hw *hw, unsigned long rate,
reg = FIELD_PREP(WZRD_CLKOUT_DIVIDE_MASK, clockout0_div) |
FIELD_PREP(WZRD_CLKOUT0_FRAC_MASK, f);
writel(reg, divider->base + WZRD_CLK_CFG_REG(2));
writel(reg, divider->base + WZRD_CLK_CFG_REG(0, 2));
/* Set divisor and clear phase offset */
reg = FIELD_PREP(WZRD_CLKFBOUT_MULT_MASK, divider->m) |
FIELD_PREP(WZRD_DIVCLK_DIVIDE_MASK, divider->d);
writel(reg, divider->base + WZRD_CLK_CFG_REG(0));
writel(divider->o, divider->base + WZRD_CLK_CFG_REG(2));
writel(0, divider->base + WZRD_CLK_CFG_REG(3));
/* Check status register */
err = readl_poll_timeout(divider->base + WZRD_DR_STATUS_REG_OFFSET, value,
value & WZRD_DR_LOCK_BIT_MASK,
WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
if (err)
return -ETIMEDOUT;
/* Initiate reconfiguration */
writel(WZRD_DR_BEGIN_DYNA_RECONF,
divider->base + WZRD_DR_INIT_REG_OFFSET);
/* Check status register */
return readl_poll_timeout(divider->base + WZRD_DR_STATUS_REG_OFFSET, value,
value & WZRD_DR_LOCK_BIT_MASK,
WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
writel(reg, divider->base + WZRD_CLK_CFG_REG(0, 0));
writel(divider->o, divider->base + WZRD_CLK_CFG_REG(0, 2));
writel(0, divider->base + WZRD_CLK_CFG_REG(0, 3));
div_addr = divider->base + WZRD_DR_INIT_REG_OFFSET;
return clk_wzrd_reconfig(divider, div_addr);
}
static int clk_wzrd_dynamic_all(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
unsigned long flags = 0;
unsigned long flags;
int ret;
spin_lock_irqsave(divider->lock, flags);
@ -315,21 +545,103 @@ static int clk_wzrd_dynamic_all(struct clk_hw *hw, unsigned long rate,
return ret;
}
static int clk_wzrd_dynamic_all_ver(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
unsigned long flags;
int ret;
spin_lock_irqsave(divider->lock, flags);
ret = clk_wzrd_dynamic_ver_all_nolock(hw, rate, parent_rate);
spin_unlock_irqrestore(divider->lock, flags);
return ret;
}
static unsigned long clk_wzrd_recalc_rate_all(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
u32 m, d, o, div, reg, f;
reg = readl(divider->base + WZRD_CLK_CFG_REG(0));
reg = readl(divider->base + WZRD_CLK_CFG_REG(0, 0));
d = FIELD_GET(WZRD_DIVCLK_DIVIDE_MASK, reg);
m = FIELD_GET(WZRD_CLKFBOUT_MULT_MASK, reg);
reg = readl(divider->base + WZRD_CLK_CFG_REG(2));
reg = readl(divider->base + WZRD_CLK_CFG_REG(0, 2));
o = FIELD_GET(WZRD_DIVCLK_DIVIDE_MASK, reg);
f = FIELD_GET(WZRD_CLKOUT0_FRAC_MASK, reg);
div = DIV_ROUND_CLOSEST(d * (WZRD_FRAC_POINTS * o + f), WZRD_FRAC_POINTS);
return divider_recalc_rate(hw, parent_rate * m, div, divider->table,
divider->flags, divider->width);
}
static unsigned long clk_wzrd_recalc_rate_all_ver(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
u32 edged, div2, p5en, edge, prediv2, all, regl, regh, mult;
u32 div, reg;
edge = !!(readl(divider->base + WZRD_CLK_CFG_REG(1, WZRD_CLKFBOUT_1)) &
WZRD_CLKFBOUT_EDGE);
reg = readl(divider->base + WZRD_CLK_CFG_REG(1, WZRD_CLKFBOUT_2));
regl = FIELD_GET(WZRD_CLKFBOUT_L_MASK, reg);
regh = FIELD_GET(WZRD_CLKFBOUT_H_MASK, reg);
mult = regl + regh + edge;
if (!mult)
mult = 1;
regl = readl(divider->base + WZRD_CLK_CFG_REG(1, WZRD_CLKFBOUT_4)) &
WZRD_CLKFBOUT_FRAC_EN;
if (regl) {
regl = readl(divider->base + WZRD_CLK_CFG_REG(1, WZRD_CLKFBOUT_3))
& WZRD_VERSAL_FRAC_MASK;
mult = mult * WZRD_FRAC_GRADIENT + regl;
parent_rate = DIV_ROUND_CLOSEST((parent_rate * mult), WZRD_FRAC_GRADIENT);
} else {
parent_rate = parent_rate * mult;
}
/* O Calculation */
reg = readl(divider->base + WZRD_CLK_CFG_REG(1, WZRD_CLKOUT0_1));
edged = FIELD_GET(WZRD_CLKFBOUT_EDGE, reg);
p5en = FIELD_GET(WZRD_P5EN, reg);
prediv2 = FIELD_GET(WZRD_CLKOUT0_PREDIV2, reg);
reg = readl(divider->base + WZRD_CLK_CFG_REG(1, WZRD_CLKOUT0_2));
/* Low time */
regl = FIELD_GET(WZRD_CLKFBOUT_L_MASK, reg);
/* High time */
regh = FIELD_GET(WZRD_CLKFBOUT_H_MASK, reg);
all = regh + regl + edged;
if (!all)
all = 1;
if (prediv2)
div2 = PREDIV2_MULT * all + p5en;
else
div2 = all;
/* D calculation */
edged = !!(readl(divider->base + WZRD_CLK_CFG_REG(1, WZRD_DESKEW_2)) &
WZRD_DIVCLK_EDGE);
reg = readl(divider->base + WZRD_CLK_CFG_REG(1, WZRD_DIVCLK));
/* Low time */
regl = FIELD_GET(WZRD_CLKFBOUT_L_MASK, reg);
/* High time */
regh = FIELD_GET(WZRD_CLKFBOUT_H_MASK, reg);
div = regl + regh + edged;
if (!div)
div = 1;
div = div * div2;
return divider_recalc_rate(hw, parent_rate, div, divider->table,
divider->flags, divider->width);
}
@ -360,6 +672,18 @@ static long clk_wzrd_round_rate_all(struct clk_hw *hw, unsigned long rate,
return rate;
}
static const struct clk_ops clk_wzrd_ver_divider_ops = {
.round_rate = clk_wzrd_round_rate,
.set_rate = clk_wzrd_ver_dynamic_reconfig,
.recalc_rate = clk_wzrd_recalc_rate_ver,
};
static const struct clk_ops clk_wzrd_ver_div_all_ops = {
.round_rate = clk_wzrd_round_rate_all,
.set_rate = clk_wzrd_dynamic_all_ver,
.recalc_rate = clk_wzrd_recalc_rate_all_ver,
};
static const struct clk_ops clk_wzrd_clk_divider_ops = {
.round_rate = clk_wzrd_round_rate,
.set_rate = clk_wzrd_dynamic_reconfig,
@ -484,6 +808,53 @@ static struct clk *clk_wzrd_register_divf(struct device *dev,
return hw->clk;
}
static struct clk *clk_wzrd_ver_register_divider(struct device *dev,
const char *name,
const char *parent_name,
unsigned long flags,
void __iomem *base,
u16 offset,
u8 shift, u8 width,
u8 clk_divider_flags,
u32 div_type,
spinlock_t *lock)
{
struct clk_wzrd_divider *div;
struct clk_hw *hw;
struct clk_init_data init;
int ret;
div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL);
if (!div)
return ERR_PTR(-ENOMEM);
init.name = name;
if (clk_divider_flags & CLK_DIVIDER_READ_ONLY)
init.ops = &clk_divider_ro_ops;
else if (div_type == DIV_O)
init.ops = &clk_wzrd_ver_divider_ops;
else
init.ops = &clk_wzrd_ver_div_all_ops;
init.flags = flags;
init.parent_names = &parent_name;
init.num_parents = 1;
div->base = base;
div->offset = offset;
div->shift = shift;
div->width = width;
div->flags = clk_divider_flags;
div->lock = lock;
div->hw.init = &init;
hw = &div->hw;
ret = devm_clk_hw_register(dev, hw);
if (ret)
return ERR_PTR(ret);
return hw->clk;
}
static struct clk *clk_wzrd_register_divider(struct device *dev,
const char *name,
const char *parent_name,
@ -588,18 +959,24 @@ static int __maybe_unused clk_wzrd_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(clk_wzrd_dev_pm_ops, clk_wzrd_suspend,
clk_wzrd_resume);
static const struct versal_clk_data versal_data = {
.is_versal = true,
};
static int clk_wzrd_probe(struct platform_device *pdev)
{
int i, ret;
u32 reg, reg_f, mult;
unsigned long rate;
const char *clk_name;
void __iomem *ctrl_reg;
struct clk_wzrd *clk_wzrd;
const char *clkout_name;
const char *clkout_name, *clk_name, *clk_mul_name;
u32 regl, regh, edge, regld, reghd, edged, div;
struct device_node *np = pdev->dev.of_node;
int nr_outputs;
const struct versal_clk_data *data;
struct clk_wzrd *clk_wzrd;
unsigned long flags = 0;
void __iomem *ctrl_reg;
u32 reg, reg_f, mult;
bool is_versal = false;
unsigned long rate;
int nr_outputs;
int i, ret;
clk_wzrd = devm_kzalloc(&pdev->dev, sizeof(*clk_wzrd), GFP_KERNEL);
if (!clk_wzrd)
@ -641,6 +1018,10 @@ static int clk_wzrd_probe(struct platform_device *pdev)
goto err_disable_clk;
}
data = device_get_match_data(&pdev->dev);
if (data)
is_versal = data->is_versal;
ret = of_property_read_u32(np, "xlnx,nr-outputs", &nr_outputs);
if (ret || nr_outputs > WZRD_NUM_OUTPUTS) {
ret = -EINVAL;
@ -653,26 +1034,61 @@ static int clk_wzrd_probe(struct platform_device *pdev)
goto err_disable_clk;
}
if (nr_outputs == 1) {
clk_wzrd->clkout[0] = clk_wzrd_register_divider
if (is_versal) {
if (nr_outputs == 1) {
clk_wzrd->clkout[0] = clk_wzrd_ver_register_divider
(&pdev->dev, clkout_name,
__clk_get_name(clk_wzrd->clk_in1), 0,
clk_wzrd->base, WZRD_CLK_CFG_REG(3),
clk_wzrd->base, WZRD_CLK_CFG_REG(is_versal, 3),
WZRD_CLKOUT_DIVIDE_SHIFT,
WZRD_CLKOUT_DIVIDE_WIDTH,
CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
DIV_ALL, &clkwzrd_lock);
goto out;
goto out;
}
/* register multiplier */
edge = !!(readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 0)) &
BIT(8));
regl = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 1)) &
WZRD_CLKFBOUT_L_MASK) >> WZRD_CLKFBOUT_L_SHIFT;
regh = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 1)) &
WZRD_CLKFBOUT_H_MASK) >> WZRD_CLKFBOUT_H_SHIFT;
mult = regl + regh + edge;
if (!mult)
mult = 1;
mult = mult * WZRD_FRAC_GRADIENT;
regl = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 51)) &
WZRD_CLKFBOUT_FRAC_EN;
if (regl) {
regl = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 48)) &
WZRD_VERSAL_FRAC_MASK;
mult = mult + regl;
}
div = 64;
} else {
if (nr_outputs == 1) {
clk_wzrd->clkout[0] = clk_wzrd_register_divider
(&pdev->dev, clkout_name,
__clk_get_name(clk_wzrd->clk_in1), 0,
clk_wzrd->base, WZRD_CLK_CFG_REG(is_versal, 3),
WZRD_CLKOUT_DIVIDE_SHIFT,
WZRD_CLKOUT_DIVIDE_WIDTH,
CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
DIV_ALL, &clkwzrd_lock);
goto out;
}
reg = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 0));
reg_f = reg & WZRD_CLKFBOUT_FRAC_MASK;
reg_f = reg_f >> WZRD_CLKFBOUT_FRAC_SHIFT;
reg = reg & WZRD_CLKFBOUT_MULT_MASK;
reg = reg >> WZRD_CLKFBOUT_MULT_SHIFT;
mult = (reg * 1000) + reg_f;
div = 1000;
}
reg = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(0));
reg_f = reg & WZRD_CLKFBOUT_FRAC_MASK;
reg_f = reg_f >> WZRD_CLKFBOUT_FRAC_SHIFT;
reg = reg & WZRD_CLKFBOUT_MULT_MASK;
reg = reg >> WZRD_CLKFBOUT_MULT_SHIFT;
mult = (reg * 1000) + reg_f;
clk_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_mul", dev_name(&pdev->dev));
if (!clk_name) {
ret = -ENOMEM;
@ -681,7 +1097,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
clk_wzrd->clks_internal[wzrd_clk_mul] = clk_register_fixed_factor
(&pdev->dev, clk_name,
__clk_get_name(clk_wzrd->clk_in1),
0, mult, 1000);
0, mult, div);
if (IS_ERR(clk_wzrd->clks_internal[wzrd_clk_mul])) {
dev_err(&pdev->dev, "unable to register fixed-factor clock\n");
ret = PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul]);
@ -694,13 +1110,29 @@ static int clk_wzrd_probe(struct platform_device *pdev)
goto err_rm_int_clk;
}
ctrl_reg = clk_wzrd->base + WZRD_CLK_CFG_REG(0);
/* register div */
clk_wzrd->clks_internal[wzrd_clk_mul_div] = clk_register_divider
if (is_versal) {
edged = !!(readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 20)) &
BIT(10));
regld = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 21)) &
WZRD_CLKFBOUT_L_MASK) >> WZRD_CLKFBOUT_L_SHIFT;
reghd = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 21)) &
WZRD_CLKFBOUT_H_MASK) >> WZRD_CLKFBOUT_H_SHIFT;
div = (regld + reghd + edged);
if (!div)
div = 1;
clk_mul_name = __clk_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]);
clk_wzrd->clks_internal[wzrd_clk_mul_div] =
clk_register_fixed_factor(&pdev->dev, clk_name,
clk_mul_name, 0, 1, div);
} else {
ctrl_reg = clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 0);
clk_wzrd->clks_internal[wzrd_clk_mul_div] = clk_register_divider
(&pdev->dev, clk_name,
__clk_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]),
flags, ctrl_reg, 0, 8, CLK_DIVIDER_ONE_BASED |
CLK_DIVIDER_ALLOW_ZERO, &clkwzrd_lock);
}
if (IS_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div])) {
dev_err(&pdev->dev, "unable to register divider clock\n");
ret = PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div]);
@ -716,24 +1148,35 @@ static int clk_wzrd_probe(struct platform_device *pdev)
goto err_rm_int_clk;
}
if (!i)
clk_wzrd->clkout[i] = clk_wzrd_register_divf
(&pdev->dev, clkout_name,
clk_name, flags,
clk_wzrd->base, (WZRD_CLK_CFG_REG(2) + i * 12),
WZRD_CLKOUT_DIVIDE_SHIFT,
WZRD_CLKOUT_DIVIDE_WIDTH,
CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
DIV_O, &clkwzrd_lock);
else
clk_wzrd->clkout[i] = clk_wzrd_register_divider
(&pdev->dev, clkout_name,
clk_name, 0,
clk_wzrd->base, (WZRD_CLK_CFG_REG(2) + i * 12),
WZRD_CLKOUT_DIVIDE_SHIFT,
WZRD_CLKOUT_DIVIDE_WIDTH,
CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
DIV_O, &clkwzrd_lock);
if (is_versal) {
clk_wzrd->clkout[i] = clk_wzrd_ver_register_divider
(&pdev->dev,
clkout_name, clk_name, 0,
clk_wzrd->base,
(WZRD_CLK_CFG_REG(is_versal, 3) + i * 8),
WZRD_CLKOUT_DIVIDE_SHIFT,
WZRD_CLKOUT_DIVIDE_WIDTH,
CLK_DIVIDER_ONE_BASED |
CLK_DIVIDER_ALLOW_ZERO,
DIV_O, &clkwzrd_lock);
} else {
if (!i)
clk_wzrd->clkout[i] = clk_wzrd_register_divf
(&pdev->dev, clkout_name, clk_name, flags, clk_wzrd->base,
(WZRD_CLK_CFG_REG(is_versal, 2) + i * 12),
WZRD_CLKOUT_DIVIDE_SHIFT,
WZRD_CLKOUT_DIVIDE_WIDTH,
CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
DIV_O, &clkwzrd_lock);
else
clk_wzrd->clkout[i] = clk_wzrd_register_divider
(&pdev->dev, clkout_name, clk_name, 0, clk_wzrd->base,
(WZRD_CLK_CFG_REG(is_versal, 2) + i * 12),
WZRD_CLKOUT_DIVIDE_SHIFT,
WZRD_CLKOUT_DIVIDE_WIDTH,
CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
DIV_O, &clkwzrd_lock);
}
if (IS_ERR(clk_wzrd->clkout[i])) {
int j;
@ -799,9 +1242,10 @@ static void clk_wzrd_remove(struct platform_device *pdev)
}
static const struct of_device_id clk_wzrd_ids[] = {
{ .compatible = "xlnx,clocking-wizard" },
{ .compatible = "xlnx,clocking-wizard-v5.2" },
{ .compatible = "xlnx,clocking-wizard-v6.0" },
{ .compatible = "xlnx,versal-clk-wizard", .data = &versal_data },
{ .compatible = "xlnx,clocking-wizard" },
{ .compatible = "xlnx,clocking-wizard-v5.2" },
{ .compatible = "xlnx,clocking-wizard-v6.0" },
{ },
};
MODULE_DEVICE_TABLE(of, clk_wzrd_ids);

View file

@ -89,7 +89,7 @@ static int zynqmp_clk_mux_set_parent(struct clk_hw *hw, u8 index)
static const struct clk_ops zynqmp_clk_mux_ops = {
.get_parent = zynqmp_clk_mux_get_parent,
.set_parent = zynqmp_clk_mux_set_parent,
.determine_rate = __clk_mux_determine_rate,
.determine_rate = __clk_mux_determine_rate_closest,
};
static const struct clk_ops zynqmp_clk_mux_ro_ops = {

View file

@ -110,52 +110,6 @@ static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw,
return DIV_ROUND_UP_ULL(parent_rate, value);
}
static void zynqmp_get_divider2_val(struct clk_hw *hw,
unsigned long rate,
struct zynqmp_clk_divider *divider,
u32 *bestdiv)
{
int div1;
int div2;
long error = LONG_MAX;
unsigned long div1_prate;
struct clk_hw *div1_parent_hw;
struct zynqmp_clk_divider *pdivider;
struct clk_hw *div2_parent_hw = clk_hw_get_parent(hw);
if (!div2_parent_hw)
return;
pdivider = to_zynqmp_clk_divider(div2_parent_hw);
if (!pdivider)
return;
div1_parent_hw = clk_hw_get_parent(div2_parent_hw);
if (!div1_parent_hw)
return;
div1_prate = clk_hw_get_rate(div1_parent_hw);
*bestdiv = 1;
for (div1 = 1; div1 <= pdivider->max_div;) {
for (div2 = 1; div2 <= divider->max_div;) {
long new_error = ((div1_prate / div1) / div2) - rate;
if (abs(new_error) < abs(error)) {
*bestdiv = div2;
error = new_error;
}
if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
div2 = div2 << 1;
else
div2++;
}
if (pdivider->flags & CLK_DIVIDER_POWER_OF_TWO)
div1 = div1 << 1;
else
div1++;
}
}
/**
* zynqmp_clk_divider_round_rate() - Round rate of divider clock
* @hw: handle between common and hardware-specific interfaces
@ -174,6 +128,7 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw,
u32 div_type = divider->div_type;
u32 bestdiv;
int ret;
u8 width;
/* if read only, just return current value */
if (divider->flags & CLK_DIVIDER_READ_ONLY) {
@ -193,23 +148,12 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw,
return DIV_ROUND_UP_ULL((u64)*prate, bestdiv);
}
bestdiv = zynqmp_divider_get_val(*prate, rate, divider->flags);
width = fls(divider->max_div);
/*
* In case of two divisors, compute best divider values and return
* divider2 value based on compute value. div1 will be automatically
* set to optimum based on required total divider value.
*/
if (div_type == TYPE_DIV2 &&
(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
zynqmp_get_divider2_val(hw, rate, divider, &bestdiv);
}
rate = divider_round_rate(hw, rate, prate, NULL, width, divider->flags);
if ((clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && divider->is_frac)
bestdiv = rate % *prate ? 1 : bestdiv;
bestdiv = min_t(u32, bestdiv, divider->max_div);
*prate = rate * bestdiv;
if (divider->is_frac && (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && (rate % *prate))
*prate = rate;
return rate;
}

View file

@ -0,0 +1,492 @@
/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
/*
* Copyright (C) STMicroelectronics 2023 - All Rights Reserved
* Author: Gabriel Fernandez <gabriel.fernandez@foss.st.com>
*/
#ifndef _DT_BINDINGS_STM32MP25_CLKS_H_
#define _DT_BINDINGS_STM32MP25_CLKS_H_
/* INTERNAL/EXTERNAL OSCILLATORS */
#define HSI_CK 0
#define HSE_CK 1
#define MSI_CK 2
#define LSI_CK 3
#define LSE_CK 4
#define I2S_CK 5
#define RTC_CK 6
#define SPDIF_CK_SYMB 7
/* PLL CLOCKS */
#define PLL1_CK 8
#define PLL2_CK 9
#define PLL3_CK 10
#define PLL4_CK 11
#define PLL5_CK 12
#define PLL6_CK 13
#define PLL7_CK 14
#define PLL8_CK 15
#define CK_CPU1 16
/* APB DIV CLOCKS */
#define CK_ICN_APB1 17
#define CK_ICN_APB2 18
#define CK_ICN_APB3 19
#define CK_ICN_APB4 20
#define CK_ICN_APBDBG 21
/* GLOBAL TIMER */
#define TIMG1_CK 22
#define TIMG2_CK 23
/* FLEXGEN CLOCKS */
#define CK_ICN_HS_MCU 24
#define CK_ICN_SDMMC 25
#define CK_ICN_DDR 26
#define CK_ICN_DISPLAY 27
#define CK_ICN_HSL 28
#define CK_ICN_NIC 29
#define CK_ICN_VID 30
#define CK_FLEXGEN_07 31
#define CK_FLEXGEN_08 32
#define CK_FLEXGEN_09 33
#define CK_FLEXGEN_10 34
#define CK_FLEXGEN_11 35
#define CK_FLEXGEN_12 36
#define CK_FLEXGEN_13 37
#define CK_FLEXGEN_14 38
#define CK_FLEXGEN_15 39
#define CK_FLEXGEN_16 40
#define CK_FLEXGEN_17 41
#define CK_FLEXGEN_18 42
#define CK_FLEXGEN_19 43
#define CK_FLEXGEN_20 44
#define CK_FLEXGEN_21 45
#define CK_FLEXGEN_22 46
#define CK_FLEXGEN_23 47
#define CK_FLEXGEN_24 48
#define CK_FLEXGEN_25 49
#define CK_FLEXGEN_26 50
#define CK_FLEXGEN_27 51
#define CK_FLEXGEN_28 52
#define CK_FLEXGEN_29 53
#define CK_FLEXGEN_30 54
#define CK_FLEXGEN_31 55
#define CK_FLEXGEN_32 56
#define CK_FLEXGEN_33 57
#define CK_FLEXGEN_34 58
#define CK_FLEXGEN_35 59
#define CK_FLEXGEN_36 60
#define CK_FLEXGEN_37 61
#define CK_FLEXGEN_38 62
#define CK_FLEXGEN_39 63
#define CK_FLEXGEN_40 64
#define CK_FLEXGEN_41 65
#define CK_FLEXGEN_42 66
#define CK_FLEXGEN_43 67
#define CK_FLEXGEN_44 68
#define CK_FLEXGEN_45 69
#define CK_FLEXGEN_46 70
#define CK_FLEXGEN_47 71
#define CK_FLEXGEN_48 72
#define CK_FLEXGEN_49 73
#define CK_FLEXGEN_50 74
#define CK_FLEXGEN_51 75
#define CK_FLEXGEN_52 76
#define CK_FLEXGEN_53 77
#define CK_FLEXGEN_54 78
#define CK_FLEXGEN_55 79
#define CK_FLEXGEN_56 80
#define CK_FLEXGEN_57 81
#define CK_FLEXGEN_58 82
#define CK_FLEXGEN_59 83
#define CK_FLEXGEN_60 84
#define CK_FLEXGEN_61 85
#define CK_FLEXGEN_62 86
#define CK_FLEXGEN_63 87
/* LOW SPEED MCU CLOCK */
#define CK_ICN_LS_MCU 88
#define CK_BUS_STM500 89
#define CK_BUS_FMC 90
#define CK_BUS_GPU 91
#define CK_BUS_ETH1 92
#define CK_BUS_ETH2 93
#define CK_BUS_PCIE 94
#define CK_BUS_DDRPHYC 95
#define CK_BUS_SYSCPU1 96
#define CK_BUS_ETHSW 97
#define CK_BUS_HPDMA1 98
#define CK_BUS_HPDMA2 99
#define CK_BUS_HPDMA3 100
#define CK_BUS_ADC12 101
#define CK_BUS_ADC3 102
#define CK_BUS_IPCC1 103
#define CK_BUS_CCI 104
#define CK_BUS_CRC 105
#define CK_BUS_MDF1 106
#define CK_BUS_OSPIIOM 107
#define CK_BUS_BKPSRAM 108
#define CK_BUS_HASH 109
#define CK_BUS_RNG 110
#define CK_BUS_CRYP1 111
#define CK_BUS_CRYP2 112
#define CK_BUS_SAES 113
#define CK_BUS_PKA 114
#define CK_BUS_GPIOA 115
#define CK_BUS_GPIOB 116
#define CK_BUS_GPIOC 117
#define CK_BUS_GPIOD 118
#define CK_BUS_GPIOE 119
#define CK_BUS_GPIOF 120
#define CK_BUS_GPIOG 121
#define CK_BUS_GPIOH 122
#define CK_BUS_GPIOI 123
#define CK_BUS_GPIOJ 124
#define CK_BUS_GPIOK 125
#define CK_BUS_LPSRAM1 126
#define CK_BUS_LPSRAM2 127
#define CK_BUS_LPSRAM3 128
#define CK_BUS_GPIOZ 129
#define CK_BUS_LPDMA 130
#define CK_BUS_HSEM 131
#define CK_BUS_IPCC2 132
#define CK_BUS_RTC 133
#define CK_BUS_SPI8 134
#define CK_BUS_LPUART1 135
#define CK_BUS_I2C8 136
#define CK_BUS_LPTIM3 137
#define CK_BUS_LPTIM4 138
#define CK_BUS_LPTIM5 139
#define CK_BUS_IWDG5 140
#define CK_BUS_WWDG2 141
#define CK_BUS_I3C4 142
#define CK_BUS_TIM2 143
#define CK_BUS_TIM3 144
#define CK_BUS_TIM4 145
#define CK_BUS_TIM5 146
#define CK_BUS_TIM6 147
#define CK_BUS_TIM7 148
#define CK_BUS_TIM10 149
#define CK_BUS_TIM11 150
#define CK_BUS_TIM12 151
#define CK_BUS_TIM13 152
#define CK_BUS_TIM14 153
#define CK_BUS_LPTIM1 154
#define CK_BUS_LPTIM2 155
#define CK_BUS_SPI2 156
#define CK_BUS_SPI3 157
#define CK_BUS_SPDIFRX 158
#define CK_BUS_USART2 159
#define CK_BUS_USART3 160
#define CK_BUS_UART4 161
#define CK_BUS_UART5 162
#define CK_BUS_I2C1 163
#define CK_BUS_I2C2 164
#define CK_BUS_I2C3 165
#define CK_BUS_I2C4 166
#define CK_BUS_I2C5 167
#define CK_BUS_I2C6 168
#define CK_BUS_I2C7 169
#define CK_BUS_I3C1 170
#define CK_BUS_I3C2 171
#define CK_BUS_I3C3 172
#define CK_BUS_TIM1 173
#define CK_BUS_TIM8 174
#define CK_BUS_TIM15 175
#define CK_BUS_TIM16 176
#define CK_BUS_TIM17 177
#define CK_BUS_TIM20 178
#define CK_BUS_SAI1 179
#define CK_BUS_SAI2 180
#define CK_BUS_SAI3 181
#define CK_BUS_SAI4 182
#define CK_BUS_USART1 183
#define CK_BUS_USART6 184
#define CK_BUS_UART7 185
#define CK_BUS_UART8 186
#define CK_BUS_UART9 187
#define CK_BUS_FDCAN 188
#define CK_BUS_SPI1 189
#define CK_BUS_SPI4 190
#define CK_BUS_SPI5 191
#define CK_BUS_SPI6 192
#define CK_BUS_SPI7 193
#define CK_BUS_BSEC 194
#define CK_BUS_IWDG1 195
#define CK_BUS_IWDG2 196
#define CK_BUS_IWDG3 197
#define CK_BUS_IWDG4 198
#define CK_BUS_WWDG1 199
#define CK_BUS_VREF 200
#define CK_BUS_DTS 201
#define CK_BUS_SERC 202
#define CK_BUS_HDP 203
#define CK_BUS_IS2M 204
#define CK_BUS_DSI 205
#define CK_BUS_LTDC 206
#define CK_BUS_CSI 207
#define CK_BUS_DCMIPP 208
#define CK_BUS_DDRC 209
#define CK_BUS_DDRCFG 210
#define CK_BUS_GICV2M 211
#define CK_BUS_USBTC 212
#define CK_BUS_USB3PCIEPHY 214
#define CK_BUS_STGEN 215
#define CK_BUS_VDEC 216
#define CK_BUS_VENC 217
#define CK_SYSDBG 218
#define CK_KER_TIM2 219
#define CK_KER_TIM3 220
#define CK_KER_TIM4 221
#define CK_KER_TIM5 222
#define CK_KER_TIM6 223
#define CK_KER_TIM7 224
#define CK_KER_TIM10 225
#define CK_KER_TIM11 226
#define CK_KER_TIM12 227
#define CK_KER_TIM13 228
#define CK_KER_TIM14 229
#define CK_KER_TIM1 230
#define CK_KER_TIM8 231
#define CK_KER_TIM15 232
#define CK_KER_TIM16 233
#define CK_KER_TIM17 234
#define CK_KER_TIM20 235
#define CK_BUS_SYSRAM 236
#define CK_BUS_VDERAM 237
#define CK_BUS_RETRAM 238
#define CK_BUS_OSPI1 239
#define CK_BUS_OSPI2 240
#define CK_BUS_OTFD1 241
#define CK_BUS_OTFD2 242
#define CK_BUS_SRAM1 243
#define CK_BUS_SRAM2 244
#define CK_BUS_SDMMC1 245
#define CK_BUS_SDMMC2 246
#define CK_BUS_SDMMC3 247
#define CK_BUS_DDR 248
#define CK_BUS_RISAF4 249
#define CK_BUS_USB2OHCI 250
#define CK_BUS_USB2EHCI 251
#define CK_BUS_USB3DR 252
#define CK_KER_LPTIM1 253
#define CK_KER_LPTIM2 254
#define CK_KER_USART2 255
#define CK_KER_UART4 256
#define CK_KER_USART3 257
#define CK_KER_UART5 258
#define CK_KER_SPI2 259
#define CK_KER_SPI3 260
#define CK_KER_SPDIFRX 261
#define CK_KER_I2C1 262
#define CK_KER_I2C2 263
#define CK_KER_I3C1 264
#define CK_KER_I3C2 265
#define CK_KER_I2C3 266
#define CK_KER_I2C5 267
#define CK_KER_I3C3 268
#define CK_KER_I2C4 269
#define CK_KER_I2C6 270
#define CK_KER_I2C7 271
#define CK_KER_SPI1 272
#define CK_KER_SPI4 273
#define CK_KER_SPI5 274
#define CK_KER_SPI6 275
#define CK_KER_SPI7 276
#define CK_KER_USART1 277
#define CK_KER_USART6 278
#define CK_KER_UART7 279
#define CK_KER_UART8 280
#define CK_KER_UART9 281
#define CK_KER_MDF1 282
#define CK_KER_SAI1 283
#define CK_KER_SAI2 284
#define CK_KER_SAI3 285
#define CK_KER_SAI4 286
#define CK_KER_FDCAN 287
#define CK_KER_DSIBLANE 288
#define CK_KER_DSIPHY 289
#define CK_KER_CSI 290
#define CK_KER_CSITXESC 291
#define CK_KER_CSIPHY 292
#define CK_KER_LVDSPHY 293
#define CK_KER_STGEN 294
#define CK_KER_USB3PCIEPHY 295
#define CK_KER_USB2PHY2EN 296
#define CK_KER_I3C4 297
#define CK_KER_SPI8 298
#define CK_KER_I2C8 299
#define CK_KER_LPUART1 300
#define CK_KER_LPTIM3 301
#define CK_KER_LPTIM4 302
#define CK_KER_LPTIM5 303
#define CK_KER_TSDBG 304
#define CK_KER_TPIU 305
#define CK_BUS_ETR 306
#define CK_BUS_SYSATB 307
#define CK_KER_ADC12 308
#define CK_KER_ADC3 309
#define CK_KER_OSPI1 310
#define CK_KER_OSPI2 311
#define CK_KER_FMC 312
#define CK_KER_SDMMC1 313
#define CK_KER_SDMMC2 314
#define CK_KER_SDMMC3 315
#define CK_KER_ETH1 316
#define CK_KER_ETH2 317
#define CK_KER_ETH1PTP 318
#define CK_KER_ETH2PTP 319
#define CK_KER_USB2PHY1 320
#define CK_KER_USB2PHY2 321
#define CK_KER_ETHSW 322
#define CK_KER_ETHSWREF 323
#define CK_MCO1 324
#define CK_MCO2 325
#define CK_KER_DTS 326
#define CK_ETH1_RX 327
#define CK_ETH1_TX 328
#define CK_ETH1_MAC 329
#define CK_ETH2_RX 330
#define CK_ETH2_TX 331
#define CK_ETH2_MAC 332
#define CK_ETH1_STP 333
#define CK_ETH2_STP 334
#define CK_KER_USBTC 335
#define CK_BUS_ADF1 336
#define CK_KER_ADF1 337
#define CK_BUS_LVDS 338
#define CK_KER_LTDC 339
#define CK_KER_GPU 340
#define CK_BUS_ETHSWACMCFG 341
#define CK_BUS_ETHSWACMMSG 342
#define HSE_DIV2_CK 343
#define STM32MP25_LAST_CLK 344
#define CK_SCMI_ICN_HS_MCU 0
#define CK_SCMI_ICN_SDMMC 1
#define CK_SCMI_ICN_DDR 2
#define CK_SCMI_ICN_DISPLAY 3
#define CK_SCMI_ICN_HSL 4
#define CK_SCMI_ICN_NIC 5
#define CK_SCMI_ICN_VID 6
#define CK_SCMI_FLEXGEN_07 7
#define CK_SCMI_FLEXGEN_08 8
#define CK_SCMI_FLEXGEN_09 9
#define CK_SCMI_FLEXGEN_10 10
#define CK_SCMI_FLEXGEN_11 11
#define CK_SCMI_FLEXGEN_12 12
#define CK_SCMI_FLEXGEN_13 13
#define CK_SCMI_FLEXGEN_14 14
#define CK_SCMI_FLEXGEN_15 15
#define CK_SCMI_FLEXGEN_16 16
#define CK_SCMI_FLEXGEN_17 17
#define CK_SCMI_FLEXGEN_18 18
#define CK_SCMI_FLEXGEN_19 19
#define CK_SCMI_FLEXGEN_20 20
#define CK_SCMI_FLEXGEN_21 21
#define CK_SCMI_FLEXGEN_22 22
#define CK_SCMI_FLEXGEN_23 23
#define CK_SCMI_FLEXGEN_24 24
#define CK_SCMI_FLEXGEN_25 25
#define CK_SCMI_FLEXGEN_26 26
#define CK_SCMI_FLEXGEN_27 27
#define CK_SCMI_FLEXGEN_28 28
#define CK_SCMI_FLEXGEN_29 29
#define CK_SCMI_FLEXGEN_30 30
#define CK_SCMI_FLEXGEN_31 31
#define CK_SCMI_FLEXGEN_32 32
#define CK_SCMI_FLEXGEN_33 33
#define CK_SCMI_FLEXGEN_34 34
#define CK_SCMI_FLEXGEN_35 35
#define CK_SCMI_FLEXGEN_36 36
#define CK_SCMI_FLEXGEN_37 37
#define CK_SCMI_FLEXGEN_38 38
#define CK_SCMI_FLEXGEN_39 39
#define CK_SCMI_FLEXGEN_40 40
#define CK_SCMI_FLEXGEN_41 41
#define CK_SCMI_FLEXGEN_42 42
#define CK_SCMI_FLEXGEN_43 43
#define CK_SCMI_FLEXGEN_44 44
#define CK_SCMI_FLEXGEN_45 45
#define CK_SCMI_FLEXGEN_46 46
#define CK_SCMI_FLEXGEN_47 47
#define CK_SCMI_FLEXGEN_48 48
#define CK_SCMI_FLEXGEN_49 49
#define CK_SCMI_FLEXGEN_50 50
#define CK_SCMI_FLEXGEN_51 51
#define CK_SCMI_FLEXGEN_52 52
#define CK_SCMI_FLEXGEN_53 53
#define CK_SCMI_FLEXGEN_54 54
#define CK_SCMI_FLEXGEN_55 55
#define CK_SCMI_FLEXGEN_56 56
#define CK_SCMI_FLEXGEN_57 57
#define CK_SCMI_FLEXGEN_58 58
#define CK_SCMI_FLEXGEN_59 59
#define CK_SCMI_FLEXGEN_60 60
#define CK_SCMI_FLEXGEN_61 61
#define CK_SCMI_FLEXGEN_62 62
#define CK_SCMI_FLEXGEN_63 63
#define CK_SCMI_ICN_LS_MCU 64
#define CK_SCMI_HSE 65
#define CK_SCMI_LSE 66
#define CK_SCMI_HSI 67
#define CK_SCMI_LSI 68
#define CK_SCMI_MSI 69
#define CK_SCMI_HSE_DIV2 70
#define CK_SCMI_CPU1 71
#define CK_SCMI_SYSCPU1 72
#define CK_SCMI_PLL2 73
#define CK_SCMI_PLL3 74
#define CK_SCMI_RTC 75
#define CK_SCMI_RTCCK 76
#define CK_SCMI_ICN_APB1 77
#define CK_SCMI_ICN_APB2 78
#define CK_SCMI_ICN_APB3 79
#define CK_SCMI_ICN_APB4 80
#define CK_SCMI_ICN_APBDBG 81
#define CK_SCMI_TIMG1 82
#define CK_SCMI_TIMG2 83
#define CK_SCMI_BKPSRAM 84
#define CK_SCMI_BSEC 85
#define CK_SCMI_ETR 87
#define CK_SCMI_FMC 88
#define CK_SCMI_GPIOA 89
#define CK_SCMI_GPIOB 90
#define CK_SCMI_GPIOC 91
#define CK_SCMI_GPIOD 92
#define CK_SCMI_GPIOE 93
#define CK_SCMI_GPIOF 94
#define CK_SCMI_GPIOG 95
#define CK_SCMI_GPIOH 96
#define CK_SCMI_GPIOI 97
#define CK_SCMI_GPIOJ 98
#define CK_SCMI_GPIOK 99
#define CK_SCMI_GPIOZ 100
#define CK_SCMI_HPDMA1 101
#define CK_SCMI_HPDMA2 102
#define CK_SCMI_HPDMA3 103
#define CK_SCMI_HSEM 104
#define CK_SCMI_IPCC1 105
#define CK_SCMI_IPCC2 106
#define CK_SCMI_LPDMA 107
#define CK_SCMI_RETRAM 108
#define CK_SCMI_SRAM1 109
#define CK_SCMI_SRAM2 110
#define CK_SCMI_LPSRAM1 111
#define CK_SCMI_LPSRAM2 112
#define CK_SCMI_LPSRAM3 113
#define CK_SCMI_VDERAM 114
#define CK_SCMI_SYSRAM 115
#define CK_SCMI_OSPI1 116
#define CK_SCMI_OSPI2 117
#define CK_SCMI_TPIU 118
#define CK_SCMI_SYSDBG 119
#define CK_SCMI_SYSATB 120
#define CK_SCMI_TSDBG 121
#define CK_SCMI_STM500 122
#endif /* _DT_BINDINGS_STM32MP25_CLKS_H_ */

View file

@ -0,0 +1,167 @@
/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
/*
* Copyright (C) STMicroelectronics 2023 - All Rights Reserved
* Author(s): Gabriel Fernandez <gabriel.fernandez@foss.st.com>
*/
#ifndef _DT_BINDINGS_STM32MP25_RESET_H_
#define _DT_BINDINGS_STM32MP25_RESET_H_
#define TIM1_R 0
#define TIM2_R 1
#define TIM3_R 2
#define TIM4_R 3
#define TIM5_R 4
#define TIM6_R 5
#define TIM7_R 6
#define TIM8_R 7
#define TIM10_R 8
#define TIM11_R 9
#define TIM12_R 10
#define TIM13_R 11
#define TIM14_R 12
#define TIM15_R 13
#define TIM16_R 14
#define TIM17_R 15
#define TIM20_R 16
#define LPTIM1_R 17
#define LPTIM2_R 18
#define LPTIM3_R 19
#define LPTIM4_R 20
#define LPTIM5_R 21
#define SPI1_R 22
#define SPI2_R 23
#define SPI3_R 24
#define SPI4_R 25
#define SPI5_R 26
#define SPI6_R 27
#define SPI7_R 28
#define SPI8_R 29
#define SPDIFRX_R 30
#define USART1_R 31
#define USART2_R 32
#define USART3_R 33
#define UART4_R 34
#define UART5_R 35
#define USART6_R 36
#define UART7_R 37
#define UART8_R 38
#define UART9_R 39
#define LPUART1_R 40
#define IS2M_R 41
#define I2C1_R 42
#define I2C2_R 43
#define I2C3_R 44
#define I2C4_R 45
#define I2C5_R 46
#define I2C6_R 47
#define I2C7_R 48
#define I2C8_R 49
#define SAI1_R 50
#define SAI2_R 51
#define SAI3_R 52
#define SAI4_R 53
#define MDF1_R 54
#define MDF2_R 55
#define FDCAN_R 56
#define HDP_R 57
#define ADC12_R 58
#define ADC3_R 59
#define ETH1_R 60
#define ETH2_R 61
#define USB2_R 62
#define USB2PHY1_R 63
#define USB2PHY2_R 64
#define USB3DR_R 65
#define USB3PCIEPHY_R 66
#define USBTC_R 67
#define ETHSW_R 68
#define SDMMC1_R 69
#define SDMMC1DLL_R 70
#define SDMMC2_R 71
#define SDMMC2DLL_R 72
#define SDMMC3_R 73
#define SDMMC3DLL_R 74
#define GPU_R 75
#define LTDC_R 76
#define DSI_R 77
#define LVDS_R 78
#define CSI_R 79
#define DCMIPP_R 80
#define CCI_R 81
#define VDEC_R 82
#define VENC_R 83
#define WWDG1_R 84
#define WWDG2_R 85
#define VREF_R 86
#define DTS_R 87
#define CRC_R 88
#define SERC_R 89
#define OSPIIOM_R 90
#define I3C1_R 91
#define I3C2_R 92
#define I3C3_R 93
#define I3C4_R 94
#define IWDG2_KER_R 95
#define IWDG4_KER_R 96
#define RNG_R 97
#define PKA_R 98
#define SAES_R 99
#define HASH_R 100
#define CRYP1_R 101
#define CRYP2_R 102
#define PCIE_R 103
#define OSPI1_R 104
#define OSPI1DLL_R 105
#define OSPI2_R 106
#define OSPI2DLL_R 107
#define FMC_R 108
#define DBG_R 109
#define GPIOA_R 110
#define GPIOB_R 111
#define GPIOC_R 112
#define GPIOD_R 113
#define GPIOE_R 114
#define GPIOF_R 115
#define GPIOG_R 116
#define GPIOH_R 117
#define GPIOI_R 118
#define GPIOJ_R 119
#define GPIOK_R 120
#define GPIOZ_R 121
#define HPDMA1_R 122
#define HPDMA2_R 123
#define HPDMA3_R 124
#define LPDMA_R 125
#define HSEM_R 126
#define IPCC1_R 127
#define IPCC2_R 128
#define C2_HOLDBOOT_R 129
#define C1_HOLDBOOT_R 130
#define C1_R 131
#define C1P1POR_R 132
#define C1P1_R 133
#define C2_R 134
#define C3_R 135
#define SYS_R 136
#define VSW_R 137
#define C1MS_R 138
#define DDRCP_R 139
#define DDRCAPB_R 140
#define DDRPHYCAPB_R 141
#define DDRCFG_R 142
#define DDR_R 143
#define STM32MP25_LAST_RESET 144
#define RST_SCMI_C1_R 0
#define RST_SCMI_C2_R 1
#define RST_SCMI_C1_HOLDBOOT_R 2
#define RST_SCMI_C2_HOLDBOOT_R 3
#define RST_SCMI_FMC 4
#define RST_SCMI_OSPI1 5
#define RST_SCMI_OSPI1DLL 6
#define RST_SCMI_OSPI2 7
#define RST_SCMI_OSPI2DLL 8
#endif /* _DT_BINDINGS_STM32MP25_RESET_H_ */