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