Merge tag 'cpufreq-arm-updates-6.9' of git://git.kernel.org/pub/scm/linux/kernel...
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 11 Mar 2024 14:29:20 +0000 (15:29 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 11 Mar 2024 14:29:20 +0000 (15:29 +0100)
Merge ARM cpufreq updates for 6.9 from Viresh Kumar:

"- General enhancements / cleanups to cpufreq drivers (tianyu2, NĂ­colas
   F. R. A. Prado, Erick Archer, Arnd Bergmann, Anastasia Belova).
 - Update cpufreq-dt-platdev to block/approve devices (Richard Acayan).
 - scmi: get transition delay from firmware (Pierre Gondois)."

* tag 'cpufreq-arm-updates-6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm:
  cpufreq: scmi: Set transition_delay_us
  firmware: arm_scmi: Populate fast channel rate_limit
  firmware: arm_scmi: Populate perf commands rate_limit
  cpufreq: qcom-hw: add CONFIG_COMMON_CLK dependency
  cpufreq: dt-platdev: block SDM670 in cpufreq-dt-platdev
  cpufreq: mediatek-hw: Don't error out if supply is not found
  Documentation: power: Use kcalloc() instead of kzalloc()
  cpufreq: mediatek-hw: Wait for CPU supplies before probing
  cpufreq: brcmstb-avs-cpufreq: add check for cpufreq_cpu_get's return value
  cpufreq: imx6: use regmap to read ocotp register

1  2 
drivers/firmware/arm_scmi/perf.c

index 211e8e0aef2c2b4fade048990249c2444afb946a,be1801fb848db28cc34f63fd8f209e7ffedc5ca6..fbcbd703198a92bff8ab0f171b840f6757ca059c
@@@ -153,6 -153,7 +153,7 @@@ struct perf_dom_info 
        bool perf_fastchannels;
        bool level_indexing_mode;
        u32 opp_count;
+       u32 rate_limit_us;
        u32 sustained_freq_khz;
        u32 sustained_perf_level;
        unsigned long mult_factor;
@@@ -266,6 -267,8 +267,8 @@@ scmi_perf_domain_attributes_get(const s
                if (PROTOCOL_REV_MAJOR(version) >= 0x4)
                        dom_info->level_indexing_mode =
                                SUPPORTS_LEVEL_INDEXING(flags);
+               dom_info->rate_limit_us = le32_to_cpu(attr->rate_limit_us) &
+                                               GENMASK(19, 0);
                dom_info->sustained_freq_khz =
                                        le32_to_cpu(attr->sustained_freq_khz);
                dom_info->sustained_perf_level =
@@@ -350,8 -353,8 +353,8 @@@ process_response_opp(struct scmi_opp *o
  }
  
  static inline void
 -process_response_opp_v4(struct perf_dom_info *dom, struct scmi_opp *opp,
 -                      unsigned int loop_idx,
 +process_response_opp_v4(struct device *dev, struct perf_dom_info *dom,
 +                      struct scmi_opp *opp, unsigned int loop_idx,
                        const struct scmi_msg_resp_perf_describe_levels_v4 *r)
  {
        opp->perf = le32_to_cpu(r->opp[loop_idx].perf_val);
        /* Note that PERF v4 reports always five 32-bit words */
        opp->indicative_freq = le32_to_cpu(r->opp[loop_idx].indicative_freq);
        if (dom->level_indexing_mode) {
 +              int ret;
 +
                opp->level_index = le32_to_cpu(r->opp[loop_idx].level_index);
  
 -              xa_store(&dom->opps_by_idx, opp->level_index, opp, GFP_KERNEL);
 -              xa_store(&dom->opps_by_lvl, opp->perf, opp, GFP_KERNEL);
 +              ret = xa_insert(&dom->opps_by_idx, opp->level_index, opp,
 +                              GFP_KERNEL);
 +              if (ret)
 +                      dev_warn(dev,
 +                               "Failed to add opps_by_idx at %d - ret:%d\n",
 +                               opp->level_index, ret);
 +
 +              ret = xa_insert(&dom->opps_by_lvl, opp->perf, opp, GFP_KERNEL);
 +              if (ret)
 +                      dev_warn(dev,
 +                               "Failed to add opps_by_lvl at %d - ret:%d\n",
 +                               opp->perf, ret);
 +
                hash_add(dom->opps_by_freq, &opp->hash, opp->indicative_freq);
        }
  }
@@@ -395,7 -385,7 +398,7 @@@ iter_perf_levels_process_response(cons
        if (PROTOCOL_REV_MAJOR(p->version) <= 0x3)
                process_response_opp(opp, st->loop_idx, response);
        else
 -              process_response_opp_v4(p->perf_dom, opp, st->loop_idx,
 +              process_response_opp_v4(ph->dev, p->perf_dom, opp, st->loop_idx,
                                        response);
        p->perf_dom->opp_count++;
  
@@@ -786,23 -776,27 +789,27 @@@ static void scmi_perf_domain_init_fc(co
  
        ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL,
                                   PERF_LEVEL_GET, 4, dom->id,
-                                  &fc[PERF_FC_LEVEL].get_addr, NULL);
+                                  &fc[PERF_FC_LEVEL].get_addr, NULL,
+                                  &fc[PERF_FC_LEVEL].rate_limit);
  
        ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL,
                                   PERF_LIMITS_GET, 8, dom->id,
-                                  &fc[PERF_FC_LIMIT].get_addr, NULL);
+                                  &fc[PERF_FC_LIMIT].get_addr, NULL,
+                                  &fc[PERF_FC_LIMIT].rate_limit);
  
        if (dom->info.set_perf)
                ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL,
                                           PERF_LEVEL_SET, 4, dom->id,
                                           &fc[PERF_FC_LEVEL].set_addr,
-                                          &fc[PERF_FC_LEVEL].set_db);
+                                          &fc[PERF_FC_LEVEL].set_db,
+                                          &fc[PERF_FC_LEVEL].rate_limit);
  
        if (dom->set_limits)
                ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL,
                                           PERF_LIMITS_SET, 8, dom->id,
                                           &fc[PERF_FC_LIMIT].set_addr,
-                                          &fc[PERF_FC_LIMIT].set_db);
+                                          &fc[PERF_FC_LIMIT].set_db,
+                                          &fc[PERF_FC_LIMIT].rate_limit);
  
        dom->fc_info = fc;
  }
@@@ -855,6 -849,23 +862,23 @@@ scmi_dvfs_transition_latency_get(const 
        return dom->opp[dom->opp_count - 1].trans_latency_us * 1000;
  }
  
+ static int
+ scmi_dvfs_rate_limit_get(const struct scmi_protocol_handle *ph,
+                        u32 domain, u32 *rate_limit)
+ {
+       struct perf_dom_info *dom;
+       if (!rate_limit)
+               return -EINVAL;
+       dom = scmi_perf_domain_lookup(ph, domain);
+       if (IS_ERR(dom))
+               return PTR_ERR(dom);
+       *rate_limit = dom->rate_limit_us;
+       return 0;
+ }
  static int scmi_dvfs_freq_set(const struct scmi_protocol_handle *ph, u32 domain,
                              unsigned long freq, bool poll)
  {
@@@ -954,6 -965,25 +978,25 @@@ static bool scmi_fast_switch_possible(c
        return dom->fc_info && dom->fc_info[PERF_FC_LEVEL].set_addr;
  }
  
+ static int scmi_fast_switch_rate_limit(const struct scmi_protocol_handle *ph,
+                                      u32 domain, u32 *rate_limit)
+ {
+       struct perf_dom_info *dom;
+       if (!rate_limit)
+               return -EINVAL;
+       dom = scmi_perf_domain_lookup(ph, domain);
+       if (IS_ERR(dom))
+               return PTR_ERR(dom);
+       if (!dom->fc_info)
+               return -EINVAL;
+       *rate_limit = dom->fc_info[PERF_FC_LEVEL].rate_limit;
+       return 0;
+ }
  static enum scmi_power_scale
  scmi_power_scale_get(const struct scmi_protocol_handle *ph)
  {
@@@ -970,11 -1000,13 +1013,13 @@@ static const struct scmi_perf_proto_op
        .level_set = scmi_perf_level_set,
        .level_get = scmi_perf_level_get,
        .transition_latency_get = scmi_dvfs_transition_latency_get,
+       .rate_limit_get = scmi_dvfs_rate_limit_get,
        .device_opps_add = scmi_dvfs_device_opps_add,
        .freq_set = scmi_dvfs_freq_set,
        .freq_get = scmi_dvfs_freq_get,
        .est_power_get = scmi_dvfs_est_power_get,
        .fast_switch_possible = scmi_fast_switch_possible,
+       .fast_switch_rate_limit = scmi_fast_switch_rate_limit,
        .power_scale_get = scmi_power_scale_get,
  };