mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00

Some clocks in the Allwinner A523 SoC contain an "update bit" (bit 27), which must be set to apply any register changes, namely the mux selector, the divider and the gate bit. Add a new CCU feature bit to mark those clocks, and set bit 27 whenever we are applying any changes. Signed-off-by: Andre Przywara <andre.przywara@arm.com> Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com> Link: https://patch.msgid.link/20250307002628.10684-4-andre.przywara@arm.com Signed-off-by: Chen-Yu Tsai <wens@csie.org>
86 lines
2.1 KiB
C
86 lines
2.1 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Copyright (c) 2016 Maxime Ripard. All rights reserved.
|
|
*/
|
|
|
|
#ifndef _COMMON_H_
|
|
#define _COMMON_H_
|
|
|
|
#include <linux/compiler.h>
|
|
#include <linux/clk-provider.h>
|
|
|
|
#define CCU_FEATURE_FRACTIONAL BIT(0)
|
|
#define CCU_FEATURE_VARIABLE_PREDIV BIT(1)
|
|
#define CCU_FEATURE_FIXED_PREDIV BIT(2)
|
|
#define CCU_FEATURE_FIXED_POSTDIV BIT(3)
|
|
#define CCU_FEATURE_ALL_PREDIV BIT(4)
|
|
#define CCU_FEATURE_LOCK_REG BIT(5)
|
|
#define CCU_FEATURE_MMC_TIMING_SWITCH BIT(6)
|
|
#define CCU_FEATURE_SIGMA_DELTA_MOD BIT(7)
|
|
#define CCU_FEATURE_KEY_FIELD BIT(8)
|
|
#define CCU_FEATURE_CLOSEST_RATE BIT(9)
|
|
#define CCU_FEATURE_DUAL_DIV BIT(10)
|
|
#define CCU_FEATURE_UPDATE_BIT BIT(11)
|
|
|
|
/* MMC timing mode switch bit */
|
|
#define CCU_MMC_NEW_TIMING_MODE BIT(30)
|
|
|
|
/* Some clocks need this bit to actually apply register changes */
|
|
#define CCU_SUNXI_UPDATE_BIT BIT(27)
|
|
|
|
struct device_node;
|
|
|
|
struct ccu_common {
|
|
void __iomem *base;
|
|
u16 reg;
|
|
u16 lock_reg;
|
|
u32 prediv;
|
|
|
|
unsigned long min_rate;
|
|
unsigned long max_rate;
|
|
|
|
unsigned long features;
|
|
spinlock_t *lock;
|
|
struct clk_hw hw;
|
|
};
|
|
|
|
static inline struct ccu_common *hw_to_ccu_common(struct clk_hw *hw)
|
|
{
|
|
return container_of(hw, struct ccu_common, hw);
|
|
}
|
|
|
|
struct sunxi_ccu_desc {
|
|
struct ccu_common **ccu_clks;
|
|
unsigned long num_ccu_clks;
|
|
|
|
struct clk_hw_onecell_data *hw_clks;
|
|
|
|
const struct ccu_reset_map *resets;
|
|
unsigned long num_resets;
|
|
};
|
|
|
|
void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock);
|
|
|
|
bool ccu_is_better_rate(struct ccu_common *common,
|
|
unsigned long target_rate,
|
|
unsigned long current_rate,
|
|
unsigned long best_rate);
|
|
|
|
struct ccu_pll_nb {
|
|
struct notifier_block clk_nb;
|
|
struct ccu_common *common;
|
|
|
|
u32 enable;
|
|
u32 lock;
|
|
};
|
|
|
|
#define to_ccu_pll_nb(_nb) container_of(_nb, struct ccu_pll_nb, clk_nb)
|
|
|
|
int ccu_pll_notifier_register(struct ccu_pll_nb *pll_nb);
|
|
|
|
int devm_sunxi_ccu_probe(struct device *dev, void __iomem *reg,
|
|
const struct sunxi_ccu_desc *desc);
|
|
void of_sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
|
|
const struct sunxi_ccu_desc *desc);
|
|
|
|
#endif /* _COMMON_H_ */
|