18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * PRCMU clock implementation for ux500 platform.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2012 ST-Ericsson SA
68c2ecf20Sopenharmony_ci * Author: Ulf Hansson <ulf.hansson@linaro.org>
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/clk-provider.h>
108c2ecf20Sopenharmony_ci#include <linux/mfd/dbx500-prcmu.h>
118c2ecf20Sopenharmony_ci#include <linux/slab.h>
128c2ecf20Sopenharmony_ci#include <linux/io.h>
138c2ecf20Sopenharmony_ci#include <linux/err.h>
148c2ecf20Sopenharmony_ci#include "clk.h"
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#define to_clk_prcmu(_hw) container_of(_hw, struct clk_prcmu, hw)
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_cistruct clk_prcmu {
198c2ecf20Sopenharmony_ci	struct clk_hw hw;
208c2ecf20Sopenharmony_ci	u8 cg_sel;
218c2ecf20Sopenharmony_ci	int is_prepared;
228c2ecf20Sopenharmony_ci	int is_enabled;
238c2ecf20Sopenharmony_ci	int opp_requested;
248c2ecf20Sopenharmony_ci};
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci/* PRCMU clock operations. */
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_cistatic int clk_prcmu_prepare(struct clk_hw *hw)
298c2ecf20Sopenharmony_ci{
308c2ecf20Sopenharmony_ci	int ret;
318c2ecf20Sopenharmony_ci	struct clk_prcmu *clk = to_clk_prcmu(hw);
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci	ret = prcmu_request_clock(clk->cg_sel, true);
348c2ecf20Sopenharmony_ci	if (!ret)
358c2ecf20Sopenharmony_ci		clk->is_prepared = 1;
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci	return ret;
388c2ecf20Sopenharmony_ci}
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_cistatic void clk_prcmu_unprepare(struct clk_hw *hw)
418c2ecf20Sopenharmony_ci{
428c2ecf20Sopenharmony_ci	struct clk_prcmu *clk = to_clk_prcmu(hw);
438c2ecf20Sopenharmony_ci	if (prcmu_request_clock(clk->cg_sel, false))
448c2ecf20Sopenharmony_ci		pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
458c2ecf20Sopenharmony_ci			clk_hw_get_name(hw));
468c2ecf20Sopenharmony_ci	else
478c2ecf20Sopenharmony_ci		clk->is_prepared = 0;
488c2ecf20Sopenharmony_ci}
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_cistatic int clk_prcmu_is_prepared(struct clk_hw *hw)
518c2ecf20Sopenharmony_ci{
528c2ecf20Sopenharmony_ci	struct clk_prcmu *clk = to_clk_prcmu(hw);
538c2ecf20Sopenharmony_ci	return clk->is_prepared;
548c2ecf20Sopenharmony_ci}
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_cistatic int clk_prcmu_enable(struct clk_hw *hw)
578c2ecf20Sopenharmony_ci{
588c2ecf20Sopenharmony_ci	struct clk_prcmu *clk = to_clk_prcmu(hw);
598c2ecf20Sopenharmony_ci	clk->is_enabled = 1;
608c2ecf20Sopenharmony_ci	return 0;
618c2ecf20Sopenharmony_ci}
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_cistatic void clk_prcmu_disable(struct clk_hw *hw)
648c2ecf20Sopenharmony_ci{
658c2ecf20Sopenharmony_ci	struct clk_prcmu *clk = to_clk_prcmu(hw);
668c2ecf20Sopenharmony_ci	clk->is_enabled = 0;
678c2ecf20Sopenharmony_ci}
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_cistatic int clk_prcmu_is_enabled(struct clk_hw *hw)
708c2ecf20Sopenharmony_ci{
718c2ecf20Sopenharmony_ci	struct clk_prcmu *clk = to_clk_prcmu(hw);
728c2ecf20Sopenharmony_ci	return clk->is_enabled;
738c2ecf20Sopenharmony_ci}
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_cistatic unsigned long clk_prcmu_recalc_rate(struct clk_hw *hw,
768c2ecf20Sopenharmony_ci					   unsigned long parent_rate)
778c2ecf20Sopenharmony_ci{
788c2ecf20Sopenharmony_ci	struct clk_prcmu *clk = to_clk_prcmu(hw);
798c2ecf20Sopenharmony_ci	return prcmu_clock_rate(clk->cg_sel);
808c2ecf20Sopenharmony_ci}
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_cistatic long clk_prcmu_round_rate(struct clk_hw *hw, unsigned long rate,
838c2ecf20Sopenharmony_ci				 unsigned long *parent_rate)
848c2ecf20Sopenharmony_ci{
858c2ecf20Sopenharmony_ci	struct clk_prcmu *clk = to_clk_prcmu(hw);
868c2ecf20Sopenharmony_ci	return prcmu_round_clock_rate(clk->cg_sel, rate);
878c2ecf20Sopenharmony_ci}
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_cistatic int clk_prcmu_set_rate(struct clk_hw *hw, unsigned long rate,
908c2ecf20Sopenharmony_ci			      unsigned long parent_rate)
918c2ecf20Sopenharmony_ci{
928c2ecf20Sopenharmony_ci	struct clk_prcmu *clk = to_clk_prcmu(hw);
938c2ecf20Sopenharmony_ci	return prcmu_set_clock_rate(clk->cg_sel, rate);
948c2ecf20Sopenharmony_ci}
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_cistatic int clk_prcmu_opp_prepare(struct clk_hw *hw)
978c2ecf20Sopenharmony_ci{
988c2ecf20Sopenharmony_ci	int err;
998c2ecf20Sopenharmony_ci	struct clk_prcmu *clk = to_clk_prcmu(hw);
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci	if (!clk->opp_requested) {
1028c2ecf20Sopenharmony_ci		err = prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP,
1038c2ecf20Sopenharmony_ci						(char *)clk_hw_get_name(hw),
1048c2ecf20Sopenharmony_ci						100);
1058c2ecf20Sopenharmony_ci		if (err) {
1068c2ecf20Sopenharmony_ci			pr_err("clk_prcmu: %s fail req APE OPP for %s.\n",
1078c2ecf20Sopenharmony_ci				__func__, clk_hw_get_name(hw));
1088c2ecf20Sopenharmony_ci			return err;
1098c2ecf20Sopenharmony_ci		}
1108c2ecf20Sopenharmony_ci		clk->opp_requested = 1;
1118c2ecf20Sopenharmony_ci	}
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci	err = prcmu_request_clock(clk->cg_sel, true);
1148c2ecf20Sopenharmony_ci	if (err) {
1158c2ecf20Sopenharmony_ci		prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP,
1168c2ecf20Sopenharmony_ci					(char *)clk_hw_get_name(hw));
1178c2ecf20Sopenharmony_ci		clk->opp_requested = 0;
1188c2ecf20Sopenharmony_ci		return err;
1198c2ecf20Sopenharmony_ci	}
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ci	clk->is_prepared = 1;
1228c2ecf20Sopenharmony_ci	return 0;
1238c2ecf20Sopenharmony_ci}
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_cistatic void clk_prcmu_opp_unprepare(struct clk_hw *hw)
1268c2ecf20Sopenharmony_ci{
1278c2ecf20Sopenharmony_ci	struct clk_prcmu *clk = to_clk_prcmu(hw);
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_ci	if (prcmu_request_clock(clk->cg_sel, false)) {
1308c2ecf20Sopenharmony_ci		pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
1318c2ecf20Sopenharmony_ci			clk_hw_get_name(hw));
1328c2ecf20Sopenharmony_ci		return;
1338c2ecf20Sopenharmony_ci	}
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_ci	if (clk->opp_requested) {
1368c2ecf20Sopenharmony_ci		prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP,
1378c2ecf20Sopenharmony_ci					(char *)clk_hw_get_name(hw));
1388c2ecf20Sopenharmony_ci		clk->opp_requested = 0;
1398c2ecf20Sopenharmony_ci	}
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ci	clk->is_prepared = 0;
1428c2ecf20Sopenharmony_ci}
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_cistatic int clk_prcmu_opp_volt_prepare(struct clk_hw *hw)
1458c2ecf20Sopenharmony_ci{
1468c2ecf20Sopenharmony_ci	int err;
1478c2ecf20Sopenharmony_ci	struct clk_prcmu *clk = to_clk_prcmu(hw);
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci	if (!clk->opp_requested) {
1508c2ecf20Sopenharmony_ci		err = prcmu_request_ape_opp_100_voltage(true);
1518c2ecf20Sopenharmony_ci		if (err) {
1528c2ecf20Sopenharmony_ci			pr_err("clk_prcmu: %s fail req APE OPP VOLT for %s.\n",
1538c2ecf20Sopenharmony_ci				__func__, clk_hw_get_name(hw));
1548c2ecf20Sopenharmony_ci			return err;
1558c2ecf20Sopenharmony_ci		}
1568c2ecf20Sopenharmony_ci		clk->opp_requested = 1;
1578c2ecf20Sopenharmony_ci	}
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci	err = prcmu_request_clock(clk->cg_sel, true);
1608c2ecf20Sopenharmony_ci	if (err) {
1618c2ecf20Sopenharmony_ci		prcmu_request_ape_opp_100_voltage(false);
1628c2ecf20Sopenharmony_ci		clk->opp_requested = 0;
1638c2ecf20Sopenharmony_ci		return err;
1648c2ecf20Sopenharmony_ci	}
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci	clk->is_prepared = 1;
1678c2ecf20Sopenharmony_ci	return 0;
1688c2ecf20Sopenharmony_ci}
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_cistatic void clk_prcmu_opp_volt_unprepare(struct clk_hw *hw)
1718c2ecf20Sopenharmony_ci{
1728c2ecf20Sopenharmony_ci	struct clk_prcmu *clk = to_clk_prcmu(hw);
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci	if (prcmu_request_clock(clk->cg_sel, false)) {
1758c2ecf20Sopenharmony_ci		pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
1768c2ecf20Sopenharmony_ci			clk_hw_get_name(hw));
1778c2ecf20Sopenharmony_ci		return;
1788c2ecf20Sopenharmony_ci	}
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci	if (clk->opp_requested) {
1818c2ecf20Sopenharmony_ci		prcmu_request_ape_opp_100_voltage(false);
1828c2ecf20Sopenharmony_ci		clk->opp_requested = 0;
1838c2ecf20Sopenharmony_ci	}
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci	clk->is_prepared = 0;
1868c2ecf20Sopenharmony_ci}
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_cistatic const struct clk_ops clk_prcmu_scalable_ops = {
1898c2ecf20Sopenharmony_ci	.prepare = clk_prcmu_prepare,
1908c2ecf20Sopenharmony_ci	.unprepare = clk_prcmu_unprepare,
1918c2ecf20Sopenharmony_ci	.is_prepared = clk_prcmu_is_prepared,
1928c2ecf20Sopenharmony_ci	.enable = clk_prcmu_enable,
1938c2ecf20Sopenharmony_ci	.disable = clk_prcmu_disable,
1948c2ecf20Sopenharmony_ci	.is_enabled = clk_prcmu_is_enabled,
1958c2ecf20Sopenharmony_ci	.recalc_rate = clk_prcmu_recalc_rate,
1968c2ecf20Sopenharmony_ci	.round_rate = clk_prcmu_round_rate,
1978c2ecf20Sopenharmony_ci	.set_rate = clk_prcmu_set_rate,
1988c2ecf20Sopenharmony_ci};
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_cistatic const struct clk_ops clk_prcmu_gate_ops = {
2018c2ecf20Sopenharmony_ci	.prepare = clk_prcmu_prepare,
2028c2ecf20Sopenharmony_ci	.unprepare = clk_prcmu_unprepare,
2038c2ecf20Sopenharmony_ci	.is_prepared = clk_prcmu_is_prepared,
2048c2ecf20Sopenharmony_ci	.enable = clk_prcmu_enable,
2058c2ecf20Sopenharmony_ci	.disable = clk_prcmu_disable,
2068c2ecf20Sopenharmony_ci	.is_enabled = clk_prcmu_is_enabled,
2078c2ecf20Sopenharmony_ci	.recalc_rate = clk_prcmu_recalc_rate,
2088c2ecf20Sopenharmony_ci};
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_cistatic const struct clk_ops clk_prcmu_scalable_rate_ops = {
2118c2ecf20Sopenharmony_ci	.is_enabled = clk_prcmu_is_enabled,
2128c2ecf20Sopenharmony_ci	.recalc_rate = clk_prcmu_recalc_rate,
2138c2ecf20Sopenharmony_ci	.round_rate = clk_prcmu_round_rate,
2148c2ecf20Sopenharmony_ci	.set_rate = clk_prcmu_set_rate,
2158c2ecf20Sopenharmony_ci};
2168c2ecf20Sopenharmony_ci
2178c2ecf20Sopenharmony_cistatic const struct clk_ops clk_prcmu_rate_ops = {
2188c2ecf20Sopenharmony_ci	.is_enabled = clk_prcmu_is_enabled,
2198c2ecf20Sopenharmony_ci	.recalc_rate = clk_prcmu_recalc_rate,
2208c2ecf20Sopenharmony_ci};
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_cistatic const struct clk_ops clk_prcmu_opp_gate_ops = {
2238c2ecf20Sopenharmony_ci	.prepare = clk_prcmu_opp_prepare,
2248c2ecf20Sopenharmony_ci	.unprepare = clk_prcmu_opp_unprepare,
2258c2ecf20Sopenharmony_ci	.is_prepared = clk_prcmu_is_prepared,
2268c2ecf20Sopenharmony_ci	.enable = clk_prcmu_enable,
2278c2ecf20Sopenharmony_ci	.disable = clk_prcmu_disable,
2288c2ecf20Sopenharmony_ci	.is_enabled = clk_prcmu_is_enabled,
2298c2ecf20Sopenharmony_ci	.recalc_rate = clk_prcmu_recalc_rate,
2308c2ecf20Sopenharmony_ci};
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_cistatic const struct clk_ops clk_prcmu_opp_volt_scalable_ops = {
2338c2ecf20Sopenharmony_ci	.prepare = clk_prcmu_opp_volt_prepare,
2348c2ecf20Sopenharmony_ci	.unprepare = clk_prcmu_opp_volt_unprepare,
2358c2ecf20Sopenharmony_ci	.is_prepared = clk_prcmu_is_prepared,
2368c2ecf20Sopenharmony_ci	.enable = clk_prcmu_enable,
2378c2ecf20Sopenharmony_ci	.disable = clk_prcmu_disable,
2388c2ecf20Sopenharmony_ci	.is_enabled = clk_prcmu_is_enabled,
2398c2ecf20Sopenharmony_ci	.recalc_rate = clk_prcmu_recalc_rate,
2408c2ecf20Sopenharmony_ci	.round_rate = clk_prcmu_round_rate,
2418c2ecf20Sopenharmony_ci	.set_rate = clk_prcmu_set_rate,
2428c2ecf20Sopenharmony_ci};
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_cistatic struct clk *clk_reg_prcmu(const char *name,
2458c2ecf20Sopenharmony_ci				 const char *parent_name,
2468c2ecf20Sopenharmony_ci				 u8 cg_sel,
2478c2ecf20Sopenharmony_ci				 unsigned long rate,
2488c2ecf20Sopenharmony_ci				 unsigned long flags,
2498c2ecf20Sopenharmony_ci				 const struct clk_ops *clk_prcmu_ops)
2508c2ecf20Sopenharmony_ci{
2518c2ecf20Sopenharmony_ci	struct clk_prcmu *clk;
2528c2ecf20Sopenharmony_ci	struct clk_init_data clk_prcmu_init;
2538c2ecf20Sopenharmony_ci	struct clk *clk_reg;
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_ci	if (!name) {
2568c2ecf20Sopenharmony_ci		pr_err("clk_prcmu: %s invalid arguments passed\n", __func__);
2578c2ecf20Sopenharmony_ci		return ERR_PTR(-EINVAL);
2588c2ecf20Sopenharmony_ci	}
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_ci	clk = kzalloc(sizeof(*clk), GFP_KERNEL);
2618c2ecf20Sopenharmony_ci	if (!clk)
2628c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_ci	clk->cg_sel = cg_sel;
2658c2ecf20Sopenharmony_ci	clk->is_prepared = 1;
2668c2ecf20Sopenharmony_ci	clk->is_enabled = 1;
2678c2ecf20Sopenharmony_ci	clk->opp_requested = 0;
2688c2ecf20Sopenharmony_ci	/* "rate" can be used for changing the initial frequency */
2698c2ecf20Sopenharmony_ci	if (rate)
2708c2ecf20Sopenharmony_ci		prcmu_set_clock_rate(cg_sel, rate);
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_ci	clk_prcmu_init.name = name;
2738c2ecf20Sopenharmony_ci	clk_prcmu_init.ops = clk_prcmu_ops;
2748c2ecf20Sopenharmony_ci	clk_prcmu_init.flags = flags;
2758c2ecf20Sopenharmony_ci	clk_prcmu_init.parent_names = (parent_name ? &parent_name : NULL);
2768c2ecf20Sopenharmony_ci	clk_prcmu_init.num_parents = (parent_name ? 1 : 0);
2778c2ecf20Sopenharmony_ci	clk->hw.init = &clk_prcmu_init;
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci	clk_reg = clk_register(NULL, &clk->hw);
2808c2ecf20Sopenharmony_ci	if (IS_ERR_OR_NULL(clk_reg))
2818c2ecf20Sopenharmony_ci		goto free_clk;
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci	return clk_reg;
2848c2ecf20Sopenharmony_ci
2858c2ecf20Sopenharmony_cifree_clk:
2868c2ecf20Sopenharmony_ci	kfree(clk);
2878c2ecf20Sopenharmony_ci	pr_err("clk_prcmu: %s failed to register clk\n", __func__);
2888c2ecf20Sopenharmony_ci	return ERR_PTR(-ENOMEM);
2898c2ecf20Sopenharmony_ci}
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_cistruct clk *clk_reg_prcmu_scalable(const char *name,
2928c2ecf20Sopenharmony_ci				   const char *parent_name,
2938c2ecf20Sopenharmony_ci				   u8 cg_sel,
2948c2ecf20Sopenharmony_ci				   unsigned long rate,
2958c2ecf20Sopenharmony_ci				   unsigned long flags)
2968c2ecf20Sopenharmony_ci{
2978c2ecf20Sopenharmony_ci	return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags,
2988c2ecf20Sopenharmony_ci			&clk_prcmu_scalable_ops);
2998c2ecf20Sopenharmony_ci}
3008c2ecf20Sopenharmony_ci
3018c2ecf20Sopenharmony_cistruct clk *clk_reg_prcmu_gate(const char *name,
3028c2ecf20Sopenharmony_ci			       const char *parent_name,
3038c2ecf20Sopenharmony_ci			       u8 cg_sel,
3048c2ecf20Sopenharmony_ci			       unsigned long flags)
3058c2ecf20Sopenharmony_ci{
3068c2ecf20Sopenharmony_ci	return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags,
3078c2ecf20Sopenharmony_ci			&clk_prcmu_gate_ops);
3088c2ecf20Sopenharmony_ci}
3098c2ecf20Sopenharmony_ci
3108c2ecf20Sopenharmony_cistruct clk *clk_reg_prcmu_scalable_rate(const char *name,
3118c2ecf20Sopenharmony_ci					const char *parent_name,
3128c2ecf20Sopenharmony_ci					u8 cg_sel,
3138c2ecf20Sopenharmony_ci					unsigned long rate,
3148c2ecf20Sopenharmony_ci					unsigned long flags)
3158c2ecf20Sopenharmony_ci{
3168c2ecf20Sopenharmony_ci	return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags,
3178c2ecf20Sopenharmony_ci			&clk_prcmu_scalable_rate_ops);
3188c2ecf20Sopenharmony_ci}
3198c2ecf20Sopenharmony_ci
3208c2ecf20Sopenharmony_cistruct clk *clk_reg_prcmu_rate(const char *name,
3218c2ecf20Sopenharmony_ci			       const char *parent_name,
3228c2ecf20Sopenharmony_ci			       u8 cg_sel,
3238c2ecf20Sopenharmony_ci			       unsigned long flags)
3248c2ecf20Sopenharmony_ci{
3258c2ecf20Sopenharmony_ci	return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags,
3268c2ecf20Sopenharmony_ci			&clk_prcmu_rate_ops);
3278c2ecf20Sopenharmony_ci}
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_cistruct clk *clk_reg_prcmu_opp_gate(const char *name,
3308c2ecf20Sopenharmony_ci				   const char *parent_name,
3318c2ecf20Sopenharmony_ci				   u8 cg_sel,
3328c2ecf20Sopenharmony_ci				   unsigned long flags)
3338c2ecf20Sopenharmony_ci{
3348c2ecf20Sopenharmony_ci	return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags,
3358c2ecf20Sopenharmony_ci			&clk_prcmu_opp_gate_ops);
3368c2ecf20Sopenharmony_ci}
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_cistruct clk *clk_reg_prcmu_opp_volt_scalable(const char *name,
3398c2ecf20Sopenharmony_ci					    const char *parent_name,
3408c2ecf20Sopenharmony_ci					    u8 cg_sel,
3418c2ecf20Sopenharmony_ci					    unsigned long rate,
3428c2ecf20Sopenharmony_ci					    unsigned long flags)
3438c2ecf20Sopenharmony_ci{
3448c2ecf20Sopenharmony_ci	return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags,
3458c2ecf20Sopenharmony_ci			&clk_prcmu_opp_volt_scalable_ops);
3468c2ecf20Sopenharmony_ci}
347