Lines Matching +full:duty +full:- +full:cycle

1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2018-2024 ARM Ltd.
9 #include <linux/clk-provider.h>
51 ret = scmi_proto_clk_ops->rate_get(clk->ph, clk->id, &rate); in scmi_clk_recalc_rate()
69 if (clk->info->rate_discrete) in scmi_clk_round_rate()
72 fmin = clk->info->range.min_rate; in scmi_clk_round_rate()
73 fmax = clk->info->range.max_rate; in scmi_clk_round_rate()
79 ftmp = rate - fmin; in scmi_clk_round_rate()
80 ftmp += clk->info->range.step_size - 1; /* to round up */ in scmi_clk_round_rate()
81 do_div(ftmp, clk->info->range.step_size); in scmi_clk_round_rate()
83 return ftmp * clk->info->range.step_size + fmin; in scmi_clk_round_rate()
91 return scmi_proto_clk_ops->rate_set(clk->ph, clk->id, rate); in scmi_clk_set_rate()
98 return scmi_proto_clk_ops->parent_set(clk->ph, clk->id, parent_index); in scmi_clk_set_parent()
107 ret = scmi_proto_clk_ops->parent_get(clk->ph, clk->id, &parent_id); in scmi_clk_get_parent()
111 for (p_idx = 0; p_idx < clk->info->num_parents; p_idx++) { in scmi_clk_get_parent()
112 if (clk->parent_data[p_idx].index == parent_id) in scmi_clk_get_parent()
116 if (p_idx == clk->info->num_parents) in scmi_clk_get_parent()
135 return scmi_proto_clk_ops->enable(clk->ph, clk->id, NOT_ATOMIC); in scmi_clk_enable()
142 scmi_proto_clk_ops->disable(clk->ph, clk->id, NOT_ATOMIC); in scmi_clk_disable()
149 return scmi_proto_clk_ops->enable(clk->ph, clk->id, ATOMIC); in scmi_clk_atomic_enable()
156 scmi_proto_clk_ops->disable(clk->ph, clk->id, ATOMIC); in scmi_clk_atomic_disable()
165 ret = scmi_proto_clk_ops->state_get(clk->ph, clk->id, &enabled, atomic); in __scmi_clk_is_enabled()
167 dev_warn(clk->dev, in __scmi_clk_is_enabled()
168 "Failed to get state for clock ID %d\n", clk->id); in __scmi_clk_is_enabled()
183 static int scmi_clk_get_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) in scmi_clk_get_duty_cycle() argument
189 ret = scmi_proto_clk_ops->config_oem_get(clk->ph, clk->id, in scmi_clk_get_duty_cycle()
193 duty->num = val; in scmi_clk_get_duty_cycle()
194 duty->den = 100; in scmi_clk_get_duty_cycle()
196 dev_warn(clk->dev, in scmi_clk_get_duty_cycle()
197 "Failed to get duty cycle for clock ID %d\n", clk->id); in scmi_clk_get_duty_cycle()
203 static int scmi_clk_set_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) in scmi_clk_set_duty_cycle() argument
209 /* SCMI OEM Duty Cycle is expressed as a percentage */ in scmi_clk_set_duty_cycle()
210 val = (duty->num * 100) / duty->den; in scmi_clk_set_duty_cycle()
211 ret = scmi_proto_clk_ops->config_oem_set(clk->ph, clk->id, in scmi_clk_set_duty_cycle()
215 dev_warn(clk->dev, in scmi_clk_set_duty_cycle()
216 "Failed to set duty cycle(%u/%u) for clock ID %d\n", in scmi_clk_set_duty_cycle()
217 duty->num, duty->den, clk->id); in scmi_clk_set_duty_cycle()
230 .num_parents = sclk->info->num_parents, in scmi_clk_ops_init()
232 .name = sclk->info->name, in scmi_clk_ops_init()
233 .parent_data = sclk->parent_data, in scmi_clk_ops_init()
236 sclk->hw.init = &init; in scmi_clk_ops_init()
237 ret = devm_clk_hw_register(dev, &sclk->hw); in scmi_clk_ops_init()
241 if (sclk->info->rate_discrete) { in scmi_clk_ops_init()
242 int num_rates = sclk->info->list.num_rates; in scmi_clk_ops_init()
245 return -EINVAL; in scmi_clk_ops_init()
247 min_rate = sclk->info->list.rates[0]; in scmi_clk_ops_init()
248 max_rate = sclk->info->list.rates[num_rates - 1]; in scmi_clk_ops_init()
250 min_rate = sclk->info->range.min_rate; in scmi_clk_ops_init()
251 max_rate = sclk->info->range.max_rate; in scmi_clk_ops_init()
254 clk_hw_set_rate_range(&sclk->hw, min_rate, max_rate); in scmi_clk_ops_init()
259 * scmi_clk_ops_alloc() - Alloc and configure clock operations
288 ops->enable = scmi_clk_atomic_enable; in scmi_clk_ops_alloc()
289 ops->disable = scmi_clk_atomic_disable; in scmi_clk_ops_alloc()
291 ops->prepare = scmi_clk_enable; in scmi_clk_ops_alloc()
292 ops->unprepare = scmi_clk_disable; in scmi_clk_ops_alloc()
297 ops->is_enabled = scmi_clk_atomic_is_enabled; in scmi_clk_ops_alloc()
299 ops->is_prepared = scmi_clk_is_enabled; in scmi_clk_ops_alloc()
302 ops->recalc_rate = scmi_clk_recalc_rate; in scmi_clk_ops_alloc()
303 ops->round_rate = scmi_clk_round_rate; in scmi_clk_ops_alloc()
304 ops->determine_rate = scmi_clk_determine_rate; in scmi_clk_ops_alloc()
306 ops->set_rate = scmi_clk_set_rate; in scmi_clk_ops_alloc()
309 ops->get_parent = scmi_clk_get_parent; in scmi_clk_ops_alloc()
311 ops->set_parent = scmi_clk_set_parent; in scmi_clk_ops_alloc()
313 /* Duty cycle */ in scmi_clk_ops_alloc()
315 ops->get_duty_cycle = scmi_clk_get_duty_cycle; in scmi_clk_ops_alloc()
316 ops->set_duty_cycle = scmi_clk_set_duty_cycle; in scmi_clk_ops_alloc()
323 * scmi_clk_ops_select() - Select a proper set of clock operations
352 const struct scmi_clock_info *ci = sclk->info; in scmi_clk_ops_select()
361 if (atomic_capable && ci->enable_latency <= atomic_threshold_us) in scmi_clk_ops_select()
364 if (!ci->state_ctrl_forbidden) in scmi_clk_ops_select()
367 if (!ci->rate_ctrl_forbidden) in scmi_clk_ops_select()
370 if (!ci->parent_ctrl_forbidden) in scmi_clk_ops_select()
373 if (ci->extended_config) in scmi_clk_ops_select()
384 /* Did not find a pre-allocated clock_ops */ in scmi_clk_ops_select()
385 ops = scmi_clk_ops_alloc(sclk->dev, feats_key); in scmi_clk_ops_select()
402 struct device *dev = &sdev->dev; in scmi_clocks_probe()
403 struct device_node *np = dev->of_node; in scmi_clocks_probe()
404 const struct scmi_handle *handle = sdev->handle; in scmi_clocks_probe()
409 return -ENODEV; in scmi_clocks_probe()
412 handle->devm_protocol_get(sdev, SCMI_PROTOCOL_CLOCK, &ph); in scmi_clocks_probe()
416 count = scmi_proto_clk_ops->count_get(ph); in scmi_clocks_probe()
419 return -EINVAL; in scmi_clocks_probe()
425 return -ENOMEM; in scmi_clocks_probe()
427 clk_data->num = count; in scmi_clocks_probe()
428 hws = clk_data->hws; in scmi_clocks_probe()
430 transport_is_atomic = handle->is_transport_atomic(handle, in scmi_clocks_probe()
439 return -ENOMEM; in scmi_clocks_probe()
441 sclk->info = scmi_proto_clk_ops->info_get(ph, idx); in scmi_clocks_probe()
442 if (!sclk->info) { in scmi_clocks_probe()
448 sclk->id = idx; in scmi_clocks_probe()
449 sclk->ph = ph; in scmi_clocks_probe()
450 sclk->dev = dev; in scmi_clocks_probe()
454 * because it cannot be shared between mulitple probe-sequences in scmi_clocks_probe()
463 return -ENOMEM; in scmi_clocks_probe()
466 if (sclk->info->num_parents > 0) { in scmi_clocks_probe()
467 sclk->parent_data = devm_kcalloc(dev, sclk->info->num_parents, in scmi_clocks_probe()
468 sizeof(*sclk->parent_data), GFP_KERNEL); in scmi_clocks_probe()
469 if (!sclk->parent_data) in scmi_clocks_probe()
470 return -ENOMEM; in scmi_clocks_probe()
472 for (int i = 0; i < sclk->info->num_parents; i++) { in scmi_clocks_probe()
473 sclk->parent_data[i].index = sclk->info->parents[i]; in scmi_clocks_probe()
474 sclk->parent_data[i].hw = hws[sclk->info->parents[i]]; in scmi_clocks_probe()
481 devm_kfree(dev, sclk->parent_data); in scmi_clocks_probe()
486 sclk->info->name, in scmi_clocks_probe()
487 scmi_ops->enable ? " (atomic ops)" : ""); in scmi_clocks_probe()
488 hws[idx] = &sclk->hw; in scmi_clocks_probe()
503 .name = "scmi-clocks",