^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) * PRCMU clock implementation for ux500 platform.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2012 ST-Ericsson SA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author: Ulf Hansson <ulf.hansson@linaro.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/mfd/dbx500-prcmu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "clk.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define to_clk_prcmu(_hw) container_of(_hw, struct clk_prcmu, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) struct clk_prcmu {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) u8 cg_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) int is_prepared;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) int is_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) int opp_requested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* PRCMU clock operations. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static int clk_prcmu_prepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct clk_prcmu *clk = to_clk_prcmu(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) ret = prcmu_request_clock(clk->cg_sel, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) clk->is_prepared = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static void clk_prcmu_unprepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct clk_prcmu *clk = to_clk_prcmu(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (prcmu_request_clock(clk->cg_sel, false))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) clk_hw_get_name(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) clk->is_prepared = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static int clk_prcmu_is_prepared(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct clk_prcmu *clk = to_clk_prcmu(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return clk->is_prepared;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static int clk_prcmu_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct clk_prcmu *clk = to_clk_prcmu(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) clk->is_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static void clk_prcmu_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct clk_prcmu *clk = to_clk_prcmu(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) clk->is_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static int clk_prcmu_is_enabled(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct clk_prcmu *clk = to_clk_prcmu(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return clk->is_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static unsigned long clk_prcmu_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct clk_prcmu *clk = to_clk_prcmu(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return prcmu_clock_rate(clk->cg_sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static long clk_prcmu_round_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) unsigned long *parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct clk_prcmu *clk = to_clk_prcmu(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return prcmu_round_clock_rate(clk->cg_sel, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static int clk_prcmu_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct clk_prcmu *clk = to_clk_prcmu(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return prcmu_set_clock_rate(clk->cg_sel, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static int clk_prcmu_opp_prepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct clk_prcmu *clk = to_clk_prcmu(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (!clk->opp_requested) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) err = prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) (char *)clk_hw_get_name(hw),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) pr_err("clk_prcmu: %s fail req APE OPP for %s.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) __func__, clk_hw_get_name(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) clk->opp_requested = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) err = prcmu_request_clock(clk->cg_sel, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) (char *)clk_hw_get_name(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) clk->opp_requested = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) clk->is_prepared = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static void clk_prcmu_opp_unprepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct clk_prcmu *clk = to_clk_prcmu(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (prcmu_request_clock(clk->cg_sel, false)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) clk_hw_get_name(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (clk->opp_requested) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) (char *)clk_hw_get_name(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) clk->opp_requested = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) clk->is_prepared = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static int clk_prcmu_opp_volt_prepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct clk_prcmu *clk = to_clk_prcmu(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (!clk->opp_requested) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) err = prcmu_request_ape_opp_100_voltage(true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) pr_err("clk_prcmu: %s fail req APE OPP VOLT for %s.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) __func__, clk_hw_get_name(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) clk->opp_requested = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) err = prcmu_request_clock(clk->cg_sel, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) prcmu_request_ape_opp_100_voltage(false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) clk->opp_requested = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) clk->is_prepared = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static void clk_prcmu_opp_volt_unprepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct clk_prcmu *clk = to_clk_prcmu(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (prcmu_request_clock(clk->cg_sel, false)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) clk_hw_get_name(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (clk->opp_requested) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) prcmu_request_ape_opp_100_voltage(false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) clk->opp_requested = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) clk->is_prepared = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static const struct clk_ops clk_prcmu_scalable_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) .prepare = clk_prcmu_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) .unprepare = clk_prcmu_unprepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) .is_prepared = clk_prcmu_is_prepared,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) .enable = clk_prcmu_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) .disable = clk_prcmu_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) .is_enabled = clk_prcmu_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) .recalc_rate = clk_prcmu_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) .round_rate = clk_prcmu_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) .set_rate = clk_prcmu_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static const struct clk_ops clk_prcmu_gate_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) .prepare = clk_prcmu_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) .unprepare = clk_prcmu_unprepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) .is_prepared = clk_prcmu_is_prepared,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) .enable = clk_prcmu_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) .disable = clk_prcmu_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) .is_enabled = clk_prcmu_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) .recalc_rate = clk_prcmu_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static const struct clk_ops clk_prcmu_scalable_rate_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) .is_enabled = clk_prcmu_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) .recalc_rate = clk_prcmu_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) .round_rate = clk_prcmu_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) .set_rate = clk_prcmu_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static const struct clk_ops clk_prcmu_rate_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .is_enabled = clk_prcmu_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .recalc_rate = clk_prcmu_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static const struct clk_ops clk_prcmu_opp_gate_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) .prepare = clk_prcmu_opp_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) .unprepare = clk_prcmu_opp_unprepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) .is_prepared = clk_prcmu_is_prepared,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) .enable = clk_prcmu_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) .disable = clk_prcmu_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) .is_enabled = clk_prcmu_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) .recalc_rate = clk_prcmu_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static const struct clk_ops clk_prcmu_opp_volt_scalable_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) .prepare = clk_prcmu_opp_volt_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) .unprepare = clk_prcmu_opp_volt_unprepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) .is_prepared = clk_prcmu_is_prepared,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) .enable = clk_prcmu_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) .disable = clk_prcmu_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) .is_enabled = clk_prcmu_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) .recalc_rate = clk_prcmu_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) .round_rate = clk_prcmu_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) .set_rate = clk_prcmu_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static struct clk *clk_reg_prcmu(const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) const char *parent_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) u8 cg_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) unsigned long flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) const struct clk_ops *clk_prcmu_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct clk_prcmu *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct clk_init_data clk_prcmu_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct clk *clk_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (!name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) pr_err("clk_prcmu: %s invalid arguments passed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) clk = kzalloc(sizeof(*clk), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (!clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) clk->cg_sel = cg_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) clk->is_prepared = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) clk->is_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) clk->opp_requested = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* "rate" can be used for changing the initial frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) prcmu_set_clock_rate(cg_sel, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) clk_prcmu_init.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) clk_prcmu_init.ops = clk_prcmu_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) clk_prcmu_init.flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) clk_prcmu_init.parent_names = (parent_name ? &parent_name : NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) clk_prcmu_init.num_parents = (parent_name ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) clk->hw.init = &clk_prcmu_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) clk_reg = clk_register(NULL, &clk->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (IS_ERR_OR_NULL(clk_reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) goto free_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return clk_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) free_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) kfree(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) pr_err("clk_prcmu: %s failed to register clk\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct clk *clk_reg_prcmu_scalable(const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) const char *parent_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) u8 cg_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) unsigned long flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) &clk_prcmu_scalable_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) struct clk *clk_reg_prcmu_gate(const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) const char *parent_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) u8 cg_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) unsigned long flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) &clk_prcmu_gate_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct clk *clk_reg_prcmu_scalable_rate(const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) const char *parent_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) u8 cg_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) unsigned long flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) &clk_prcmu_scalable_rate_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) struct clk *clk_reg_prcmu_rate(const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) const char *parent_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) u8 cg_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) unsigned long flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) &clk_prcmu_rate_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct clk *clk_reg_prcmu_opp_gate(const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) const char *parent_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) u8 cg_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) unsigned long flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) &clk_prcmu_opp_gate_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) struct clk *clk_reg_prcmu_opp_volt_scalable(const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) const char *parent_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) u8 cg_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) unsigned long flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) &clk_prcmu_opp_volt_scalable_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }