Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3)  * Copyright (c) 2014, The Linux Foundation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "clk-regmap-divider.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) static inline struct clk_regmap_div *to_clk_regmap_div(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) 	return container_of(to_clk_regmap(hw), struct clk_regmap_div, clkr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static long div_round_ro_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) 			      unsigned long *prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) 	struct clk_regmap_div *divider = to_clk_regmap_div(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) 	struct clk_regmap *clkr = &divider->clkr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) 	regmap_read(clkr->regmap, divider->reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) 	val >>= divider->shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) 	val &= BIT(divider->width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) 	return divider_ro_round_rate(hw, rate, prate, NULL, divider->width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) 				     CLK_DIVIDER_ROUND_CLOSEST, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static long div_round_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) 			   unsigned long *prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) 	struct clk_regmap_div *divider = to_clk_regmap_div(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) 	return divider_round_rate(hw, rate, prate, NULL, divider->width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) 				  CLK_DIVIDER_ROUND_CLOSEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static int div_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) 			unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) 	struct clk_regmap_div *divider = to_clk_regmap_div(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) 	struct clk_regmap *clkr = &divider->clkr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) 	u32 div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) 	div = divider_get_val(rate, parent_rate, NULL, divider->width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) 			      CLK_DIVIDER_ROUND_CLOSEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) 	return regmap_update_bits(clkr->regmap, divider->reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) 				  (BIT(divider->width) - 1) << divider->shift,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) 				  div << divider->shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static unsigned long div_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) 				     unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) 	struct clk_regmap_div *divider = to_clk_regmap_div(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) 	struct clk_regmap *clkr = &divider->clkr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 	u32 div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 	regmap_read(clkr->regmap, divider->reg, &div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) 	div >>= divider->shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 	div &= BIT(divider->width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 	return divider_recalc_rate(hw, parent_rate, div, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) 				   CLK_DIVIDER_ROUND_CLOSEST, divider->width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) const struct clk_ops clk_regmap_div_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) 	.round_rate = div_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) 	.set_rate = div_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) 	.recalc_rate = div_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) EXPORT_SYMBOL_GPL(clk_regmap_div_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) const struct clk_ops clk_regmap_div_ro_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) 	.round_rate = div_round_ro_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) 	.recalc_rate = div_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) EXPORT_SYMBOL_GPL(clk_regmap_div_ro_ops);