Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * System Control and Power Interface (SCMI) Protocol based clock driver
0004  *
0005  * Copyright (C) 2018-2022 ARM Ltd.
0006  */
0007 
0008 #include <linux/clk-provider.h>
0009 #include <linux/device.h>
0010 #include <linux/err.h>
0011 #include <linux/of.h>
0012 #include <linux/module.h>
0013 #include <linux/scmi_protocol.h>
0014 #include <asm/div64.h>
0015 
0016 static const struct scmi_clk_proto_ops *scmi_proto_clk_ops;
0017 
0018 struct scmi_clk {
0019     u32 id;
0020     struct clk_hw hw;
0021     const struct scmi_clock_info *info;
0022     const struct scmi_protocol_handle *ph;
0023 };
0024 
0025 #define to_scmi_clk(clk) container_of(clk, struct scmi_clk, hw)
0026 
0027 static unsigned long scmi_clk_recalc_rate(struct clk_hw *hw,
0028                       unsigned long parent_rate)
0029 {
0030     int ret;
0031     u64 rate;
0032     struct scmi_clk *clk = to_scmi_clk(hw);
0033 
0034     ret = scmi_proto_clk_ops->rate_get(clk->ph, clk->id, &rate);
0035     if (ret)
0036         return 0;
0037     return rate;
0038 }
0039 
0040 static long scmi_clk_round_rate(struct clk_hw *hw, unsigned long rate,
0041                 unsigned long *parent_rate)
0042 {
0043     u64 fmin, fmax, ftmp;
0044     struct scmi_clk *clk = to_scmi_clk(hw);
0045 
0046     /*
0047      * We can't figure out what rate it will be, so just return the
0048      * rate back to the caller. scmi_clk_recalc_rate() will be called
0049      * after the rate is set and we'll know what rate the clock is
0050      * running at then.
0051      */
0052     if (clk->info->rate_discrete)
0053         return rate;
0054 
0055     fmin = clk->info->range.min_rate;
0056     fmax = clk->info->range.max_rate;
0057     if (rate <= fmin)
0058         return fmin;
0059     else if (rate >= fmax)
0060         return fmax;
0061 
0062     ftmp = rate - fmin;
0063     ftmp += clk->info->range.step_size - 1; /* to round up */
0064     do_div(ftmp, clk->info->range.step_size);
0065 
0066     return ftmp * clk->info->range.step_size + fmin;
0067 }
0068 
0069 static int scmi_clk_set_rate(struct clk_hw *hw, unsigned long rate,
0070                  unsigned long parent_rate)
0071 {
0072     struct scmi_clk *clk = to_scmi_clk(hw);
0073 
0074     return scmi_proto_clk_ops->rate_set(clk->ph, clk->id, rate);
0075 }
0076 
0077 static int scmi_clk_enable(struct clk_hw *hw)
0078 {
0079     struct scmi_clk *clk = to_scmi_clk(hw);
0080 
0081     return scmi_proto_clk_ops->enable(clk->ph, clk->id);
0082 }
0083 
0084 static void scmi_clk_disable(struct clk_hw *hw)
0085 {
0086     struct scmi_clk *clk = to_scmi_clk(hw);
0087 
0088     scmi_proto_clk_ops->disable(clk->ph, clk->id);
0089 }
0090 
0091 static int scmi_clk_atomic_enable(struct clk_hw *hw)
0092 {
0093     struct scmi_clk *clk = to_scmi_clk(hw);
0094 
0095     return scmi_proto_clk_ops->enable_atomic(clk->ph, clk->id);
0096 }
0097 
0098 static void scmi_clk_atomic_disable(struct clk_hw *hw)
0099 {
0100     struct scmi_clk *clk = to_scmi_clk(hw);
0101 
0102     scmi_proto_clk_ops->disable_atomic(clk->ph, clk->id);
0103 }
0104 
0105 /*
0106  * We can provide enable/disable atomic callbacks only if the underlying SCMI
0107  * transport for an SCMI instance is configured to handle SCMI commands in an
0108  * atomic manner.
0109  *
0110  * When no SCMI atomic transport support is available we instead provide only
0111  * the prepare/unprepare API, as allowed by the clock framework when atomic
0112  * calls are not available.
0113  *
0114  * Two distinct sets of clk_ops are provided since we could have multiple SCMI
0115  * instances with different underlying transport quality, so they cannot be
0116  * shared.
0117  */
0118 static const struct clk_ops scmi_clk_ops = {
0119     .recalc_rate = scmi_clk_recalc_rate,
0120     .round_rate = scmi_clk_round_rate,
0121     .set_rate = scmi_clk_set_rate,
0122     .prepare = scmi_clk_enable,
0123     .unprepare = scmi_clk_disable,
0124 };
0125 
0126 static const struct clk_ops scmi_atomic_clk_ops = {
0127     .recalc_rate = scmi_clk_recalc_rate,
0128     .round_rate = scmi_clk_round_rate,
0129     .set_rate = scmi_clk_set_rate,
0130     .enable = scmi_clk_atomic_enable,
0131     .disable = scmi_clk_atomic_disable,
0132 };
0133 
0134 static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk,
0135                  const struct clk_ops *scmi_ops)
0136 {
0137     int ret;
0138     unsigned long min_rate, max_rate;
0139 
0140     struct clk_init_data init = {
0141         .flags = CLK_GET_RATE_NOCACHE,
0142         .num_parents = 0,
0143         .ops = scmi_ops,
0144         .name = sclk->info->name,
0145     };
0146 
0147     sclk->hw.init = &init;
0148     ret = devm_clk_hw_register(dev, &sclk->hw);
0149     if (ret)
0150         return ret;
0151 
0152     if (sclk->info->rate_discrete) {
0153         int num_rates = sclk->info->list.num_rates;
0154 
0155         if (num_rates <= 0)
0156             return -EINVAL;
0157 
0158         min_rate = sclk->info->list.rates[0];
0159         max_rate = sclk->info->list.rates[num_rates - 1];
0160     } else {
0161         min_rate = sclk->info->range.min_rate;
0162         max_rate = sclk->info->range.max_rate;
0163     }
0164 
0165     clk_hw_set_rate_range(&sclk->hw, min_rate, max_rate);
0166     return ret;
0167 }
0168 
0169 static int scmi_clocks_probe(struct scmi_device *sdev)
0170 {
0171     int idx, count, err;
0172     unsigned int atomic_threshold;
0173     bool is_atomic;
0174     struct clk_hw **hws;
0175     struct clk_hw_onecell_data *clk_data;
0176     struct device *dev = &sdev->dev;
0177     struct device_node *np = dev->of_node;
0178     const struct scmi_handle *handle = sdev->handle;
0179     struct scmi_protocol_handle *ph;
0180 
0181     if (!handle)
0182         return -ENODEV;
0183 
0184     scmi_proto_clk_ops =
0185         handle->devm_protocol_get(sdev, SCMI_PROTOCOL_CLOCK, &ph);
0186     if (IS_ERR(scmi_proto_clk_ops))
0187         return PTR_ERR(scmi_proto_clk_ops);
0188 
0189     count = scmi_proto_clk_ops->count_get(ph);
0190     if (count < 0) {
0191         dev_err(dev, "%pOFn: invalid clock output count\n", np);
0192         return -EINVAL;
0193     }
0194 
0195     clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, count),
0196                 GFP_KERNEL);
0197     if (!clk_data)
0198         return -ENOMEM;
0199 
0200     clk_data->num = count;
0201     hws = clk_data->hws;
0202 
0203     is_atomic = handle->is_transport_atomic(handle, &atomic_threshold);
0204 
0205     for (idx = 0; idx < count; idx++) {
0206         struct scmi_clk *sclk;
0207         const struct clk_ops *scmi_ops;
0208 
0209         sclk = devm_kzalloc(dev, sizeof(*sclk), GFP_KERNEL);
0210         if (!sclk)
0211             return -ENOMEM;
0212 
0213         sclk->info = scmi_proto_clk_ops->info_get(ph, idx);
0214         if (!sclk->info) {
0215             dev_dbg(dev, "invalid clock info for idx %d\n", idx);
0216             continue;
0217         }
0218 
0219         sclk->id = idx;
0220         sclk->ph = ph;
0221 
0222         /*
0223          * Note that when transport is atomic but SCMI protocol did not
0224          * specify (or support) an enable_latency associated with a
0225          * clock, we default to use atomic operations mode.
0226          */
0227         if (is_atomic &&
0228             sclk->info->enable_latency <= atomic_threshold)
0229             scmi_ops = &scmi_atomic_clk_ops;
0230         else
0231             scmi_ops = &scmi_clk_ops;
0232 
0233         err = scmi_clk_ops_init(dev, sclk, scmi_ops);
0234         if (err) {
0235             dev_err(dev, "failed to register clock %d\n", idx);
0236             devm_kfree(dev, sclk);
0237             hws[idx] = NULL;
0238         } else {
0239             dev_dbg(dev, "Registered clock:%s%s\n",
0240                 sclk->info->name,
0241                 scmi_ops == &scmi_atomic_clk_ops ?
0242                 " (atomic ops)" : "");
0243             hws[idx] = &sclk->hw;
0244         }
0245     }
0246 
0247     return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
0248                        clk_data);
0249 }
0250 
0251 static const struct scmi_device_id scmi_id_table[] = {
0252     { SCMI_PROTOCOL_CLOCK, "clocks" },
0253     { },
0254 };
0255 MODULE_DEVICE_TABLE(scmi, scmi_id_table);
0256 
0257 static struct scmi_driver scmi_clocks_driver = {
0258     .name = "scmi-clocks",
0259     .probe = scmi_clocks_probe,
0260     .id_table = scmi_id_table,
0261 };
0262 module_scmi_driver(scmi_clocks_driver);
0263 
0264 MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
0265 MODULE_DESCRIPTION("ARM SCMI clock driver");
0266 MODULE_LICENSE("GPL v2");