0001
0002
0003
0004 #include <linux/clk.h>
0005 #include <linux/devfreq.h>
0006 #include <linux/devfreq_cooling.h>
0007 #include <linux/platform_device.h>
0008 #include <linux/pm_opp.h>
0009
0010 #include "panfrost_device.h"
0011 #include "panfrost_devfreq.h"
0012
0013 static void panfrost_devfreq_update_utilization(struct panfrost_devfreq *pfdevfreq)
0014 {
0015 ktime_t now, last;
0016
0017 now = ktime_get();
0018 last = pfdevfreq->time_last_update;
0019
0020 if (pfdevfreq->busy_count > 0)
0021 pfdevfreq->busy_time += ktime_sub(now, last);
0022 else
0023 pfdevfreq->idle_time += ktime_sub(now, last);
0024
0025 pfdevfreq->time_last_update = now;
0026 }
0027
0028 static int panfrost_devfreq_target(struct device *dev, unsigned long *freq,
0029 u32 flags)
0030 {
0031 struct dev_pm_opp *opp;
0032
0033 opp = devfreq_recommended_opp(dev, freq, flags);
0034 if (IS_ERR(opp))
0035 return PTR_ERR(opp);
0036 dev_pm_opp_put(opp);
0037
0038 return dev_pm_opp_set_rate(dev, *freq);
0039 }
0040
0041 static void panfrost_devfreq_reset(struct panfrost_devfreq *pfdevfreq)
0042 {
0043 pfdevfreq->busy_time = 0;
0044 pfdevfreq->idle_time = 0;
0045 pfdevfreq->time_last_update = ktime_get();
0046 }
0047
0048 static int panfrost_devfreq_get_dev_status(struct device *dev,
0049 struct devfreq_dev_status *status)
0050 {
0051 struct panfrost_device *pfdev = dev_get_drvdata(dev);
0052 struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
0053 unsigned long irqflags;
0054
0055 status->current_frequency = clk_get_rate(pfdev->clock);
0056
0057 spin_lock_irqsave(&pfdevfreq->lock, irqflags);
0058
0059 panfrost_devfreq_update_utilization(pfdevfreq);
0060
0061 status->total_time = ktime_to_ns(ktime_add(pfdevfreq->busy_time,
0062 pfdevfreq->idle_time));
0063
0064 status->busy_time = ktime_to_ns(pfdevfreq->busy_time);
0065
0066 panfrost_devfreq_reset(pfdevfreq);
0067
0068 spin_unlock_irqrestore(&pfdevfreq->lock, irqflags);
0069
0070 dev_dbg(pfdev->dev, "busy %lu total %lu %lu %% freq %lu MHz\n",
0071 status->busy_time, status->total_time,
0072 status->busy_time / (status->total_time / 100),
0073 status->current_frequency / 1000 / 1000);
0074
0075 return 0;
0076 }
0077
0078 static struct devfreq_dev_profile panfrost_devfreq_profile = {
0079 .timer = DEVFREQ_TIMER_DELAYED,
0080 .polling_ms = 50,
0081 .target = panfrost_devfreq_target,
0082 .get_dev_status = panfrost_devfreq_get_dev_status,
0083 };
0084
0085 int panfrost_devfreq_init(struct panfrost_device *pfdev)
0086 {
0087 int ret;
0088 struct dev_pm_opp *opp;
0089 unsigned long cur_freq;
0090 struct device *dev = &pfdev->pdev->dev;
0091 struct devfreq *devfreq;
0092 struct thermal_cooling_device *cooling;
0093 struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
0094
0095 if (pfdev->comp->num_supplies > 1) {
0096
0097
0098
0099
0100 DRM_DEV_INFO(dev, "More than 1 supply is not supported yet\n");
0101 return 0;
0102 }
0103
0104 ret = devm_pm_opp_set_regulators(dev, pfdev->comp->supply_names);
0105 if (ret) {
0106
0107 if (ret != -ENODEV) {
0108 if (ret != -EPROBE_DEFER)
0109 DRM_DEV_ERROR(dev, "Couldn't set OPP regulators\n");
0110 return ret;
0111 }
0112 }
0113
0114 ret = devm_pm_opp_of_add_table(dev);
0115 if (ret) {
0116
0117 if (ret == -ENODEV)
0118 ret = 0;
0119 return ret;
0120 }
0121 pfdevfreq->opp_of_table_added = true;
0122
0123 spin_lock_init(&pfdevfreq->lock);
0124
0125 panfrost_devfreq_reset(pfdevfreq);
0126
0127 cur_freq = clk_get_rate(pfdev->clock);
0128
0129 opp = devfreq_recommended_opp(dev, &cur_freq, 0);
0130 if (IS_ERR(opp))
0131 return PTR_ERR(opp);
0132
0133 panfrost_devfreq_profile.initial_freq = cur_freq;
0134
0135
0136
0137
0138
0139 ret = dev_pm_opp_set_opp(dev, opp);
0140 if (ret) {
0141 DRM_DEV_ERROR(dev, "Couldn't set recommended OPP\n");
0142 return ret;
0143 }
0144
0145 dev_pm_opp_put(opp);
0146
0147
0148
0149
0150
0151 pfdevfreq->gov_data.upthreshold = 45;
0152 pfdevfreq->gov_data.downdifferential = 5;
0153
0154 devfreq = devm_devfreq_add_device(dev, &panfrost_devfreq_profile,
0155 DEVFREQ_GOV_SIMPLE_ONDEMAND,
0156 &pfdevfreq->gov_data);
0157 if (IS_ERR(devfreq)) {
0158 DRM_DEV_ERROR(dev, "Couldn't initialize GPU devfreq\n");
0159 return PTR_ERR(devfreq);
0160 }
0161 pfdevfreq->devfreq = devfreq;
0162
0163 cooling = devfreq_cooling_em_register(devfreq, NULL);
0164 if (IS_ERR(cooling))
0165 DRM_DEV_INFO(dev, "Failed to register cooling device\n");
0166 else
0167 pfdevfreq->cooling = cooling;
0168
0169 return 0;
0170 }
0171
0172 void panfrost_devfreq_fini(struct panfrost_device *pfdev)
0173 {
0174 struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
0175
0176 if (pfdevfreq->cooling) {
0177 devfreq_cooling_unregister(pfdevfreq->cooling);
0178 pfdevfreq->cooling = NULL;
0179 }
0180 }
0181
0182 void panfrost_devfreq_resume(struct panfrost_device *pfdev)
0183 {
0184 struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
0185
0186 if (!pfdevfreq->devfreq)
0187 return;
0188
0189 panfrost_devfreq_reset(pfdevfreq);
0190
0191 devfreq_resume_device(pfdevfreq->devfreq);
0192 }
0193
0194 void panfrost_devfreq_suspend(struct panfrost_device *pfdev)
0195 {
0196 struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
0197
0198 if (!pfdevfreq->devfreq)
0199 return;
0200
0201 devfreq_suspend_device(pfdevfreq->devfreq);
0202 }
0203
0204 void panfrost_devfreq_record_busy(struct panfrost_devfreq *pfdevfreq)
0205 {
0206 unsigned long irqflags;
0207
0208 if (!pfdevfreq->devfreq)
0209 return;
0210
0211 spin_lock_irqsave(&pfdevfreq->lock, irqflags);
0212
0213 panfrost_devfreq_update_utilization(pfdevfreq);
0214
0215 pfdevfreq->busy_count++;
0216
0217 spin_unlock_irqrestore(&pfdevfreq->lock, irqflags);
0218 }
0219
0220 void panfrost_devfreq_record_idle(struct panfrost_devfreq *pfdevfreq)
0221 {
0222 unsigned long irqflags;
0223
0224 if (!pfdevfreq->devfreq)
0225 return;
0226
0227 spin_lock_irqsave(&pfdevfreq->lock, irqflags);
0228
0229 panfrost_devfreq_update_utilization(pfdevfreq);
0230
0231 WARN_ON(--pfdevfreq->busy_count < 0);
0232
0233 spin_unlock_irqrestore(&pfdevfreq->lock, irqflags);
0234 }