1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2013 Red Hat 4 * Author: Rob Clark <robdclark@gmail.com> 5 */ 6 7 #include "msm_gpu.h" 8 #include "msm_gpu_trace.h" 9 10 #include <linux/devfreq.h> 11 #include <linux/devfreq_cooling.h> 12 13 /* 14 * Power Management: 15 */ 16 17 static int msm_devfreq_target(struct device *dev, unsigned long *freq, 18 u32 flags) 19 { 20 struct msm_gpu *gpu = dev_to_gpu(dev); 21 struct dev_pm_opp *opp; 22 23 opp = devfreq_recommended_opp(dev, freq, flags); 24 25 /* 26 * If the GPU is idle, devfreq is not aware, so just ignore 27 * it's requests 28 */ 29 if (gpu->devfreq.idle_freq) { 30 gpu->devfreq.idle_freq = *freq; 31 return 0; 32 } 33 34 if (IS_ERR(opp)) 35 return PTR_ERR(opp); 36 37 trace_msm_gpu_freq_change(dev_pm_opp_get_freq(opp)); 38 39 if (gpu->funcs->gpu_set_freq) 40 gpu->funcs->gpu_set_freq(gpu, opp); 41 else 42 clk_set_rate(gpu->core_clk, *freq); 43 44 dev_pm_opp_put(opp); 45 46 return 0; 47 } 48 49 static unsigned long get_freq(struct msm_gpu *gpu) 50 { 51 if (gpu->devfreq.idle_freq) 52 return gpu->devfreq.idle_freq; 53 54 if (gpu->funcs->gpu_get_freq) 55 return gpu->funcs->gpu_get_freq(gpu); 56 57 return clk_get_rate(gpu->core_clk); 58 } 59 60 static int msm_devfreq_get_dev_status(struct device *dev, 61 struct devfreq_dev_status *status) 62 { 63 struct msm_gpu *gpu = dev_to_gpu(dev); 64 ktime_t time; 65 66 status->current_frequency = get_freq(gpu); 67 status->busy_time = gpu->funcs->gpu_busy(gpu); 68 69 time = ktime_get(); 70 status->total_time = ktime_us_delta(time, gpu->devfreq.time); 71 gpu->devfreq.time = time; 72 73 return 0; 74 } 75 76 static int msm_devfreq_get_cur_freq(struct device *dev, unsigned long *freq) 77 { 78 *freq = get_freq(dev_to_gpu(dev)); 79 80 return 0; 81 } 82 83 static struct devfreq_dev_profile msm_devfreq_profile = { 84 .timer = DEVFREQ_TIMER_DELAYED, 85 .polling_ms = 50, 86 .target = msm_devfreq_target, 87 .get_dev_status = msm_devfreq_get_dev_status, 88 .get_cur_freq = msm_devfreq_get_cur_freq, 89 }; 90 91 static void msm_devfreq_idle_work(struct kthread_work *work); 92 93 void msm_devfreq_init(struct msm_gpu *gpu) 94 { 95 struct msm_gpu_devfreq *df = &gpu->devfreq; 96 97 /* We need target support to do devfreq */ 98 if (!gpu->funcs->gpu_busy) 99 return; 100 101 msm_devfreq_profile.initial_freq = gpu->fast_rate; 102 103 /* 104 * Don't set the freq_table or max_state and let devfreq build the table 105 * from OPP 106 * After a deferred probe, these may have be left to non-zero values, 107 * so set them back to zero before creating the devfreq device 108 */ 109 msm_devfreq_profile.freq_table = NULL; 110 msm_devfreq_profile.max_state = 0; 111 112 df->devfreq = devm_devfreq_add_device(&gpu->pdev->dev, 113 &msm_devfreq_profile, DEVFREQ_GOV_SIMPLE_ONDEMAND, 114 NULL); 115 116 if (IS_ERR(df->devfreq)) { 117 DRM_DEV_ERROR(&gpu->pdev->dev, "Couldn't initialize GPU devfreq\n"); 118 df->devfreq = NULL; 119 return; 120 } 121 122 devfreq_suspend_device(df->devfreq); 123 124 gpu->cooling = of_devfreq_cooling_register(gpu->pdev->dev.of_node, df->devfreq); 125 if (IS_ERR(gpu->cooling)) { 126 DRM_DEV_ERROR(&gpu->pdev->dev, 127 "Couldn't register GPU cooling device\n"); 128 gpu->cooling = NULL; 129 } 130 131 msm_hrtimer_work_init(&df->idle_work, gpu->worker, msm_devfreq_idle_work, 132 CLOCK_MONOTONIC, HRTIMER_MODE_REL); 133 } 134 135 void msm_devfreq_cleanup(struct msm_gpu *gpu) 136 { 137 devfreq_cooling_unregister(gpu->cooling); 138 } 139 140 void msm_devfreq_resume(struct msm_gpu *gpu) 141 { 142 gpu->devfreq.busy_cycles = 0; 143 gpu->devfreq.time = ktime_get(); 144 145 devfreq_resume_device(gpu->devfreq.devfreq); 146 } 147 148 void msm_devfreq_suspend(struct msm_gpu *gpu) 149 { 150 devfreq_suspend_device(gpu->devfreq.devfreq); 151 } 152 153 void msm_devfreq_active(struct msm_gpu *gpu) 154 { 155 struct msm_gpu_devfreq *df = &gpu->devfreq; 156 struct devfreq_dev_status status; 157 unsigned int idle_time; 158 unsigned long target_freq = df->idle_freq; 159 160 if (!df->devfreq) 161 return; 162 163 /* 164 * Cancel any pending transition to idle frequency: 165 */ 166 hrtimer_cancel(&df->idle_work.timer); 167 168 /* 169 * Hold devfreq lock to synchronize with get_dev_status()/ 170 * target() callbacks 171 */ 172 mutex_lock(&df->devfreq->lock); 173 174 idle_time = ktime_to_ms(ktime_sub(ktime_get(), df->idle_time)); 175 176 /* 177 * If we've been idle for a significant fraction of a polling 178 * interval, then we won't meet the threshold of busyness for 179 * the governor to ramp up the freq.. so give some boost 180 */ 181 if (idle_time > msm_devfreq_profile.polling_ms/2) { 182 target_freq *= 2; 183 } 184 185 df->idle_freq = 0; 186 187 msm_devfreq_target(&gpu->pdev->dev, &target_freq, 0); 188 189 /* 190 * Reset the polling interval so we aren't inconsistent 191 * about freq vs busy/total cycles 192 */ 193 msm_devfreq_get_dev_status(&gpu->pdev->dev, &status); 194 195 mutex_unlock(&df->devfreq->lock); 196 } 197 198 199 static void msm_devfreq_idle_work(struct kthread_work *work) 200 { 201 struct msm_gpu_devfreq *df = container_of(work, 202 struct msm_gpu_devfreq, idle_work.work); 203 struct msm_gpu *gpu = container_of(df, struct msm_gpu, devfreq); 204 unsigned long idle_freq, target_freq = 0; 205 206 if (!df->devfreq) 207 return; 208 209 /* 210 * Hold devfreq lock to synchronize with get_dev_status()/ 211 * target() callbacks 212 */ 213 mutex_lock(&df->devfreq->lock); 214 215 idle_freq = get_freq(gpu); 216 217 if (gpu->clamp_to_idle) 218 msm_devfreq_target(&gpu->pdev->dev, &target_freq, 0); 219 220 df->idle_time = ktime_get(); 221 df->idle_freq = idle_freq; 222 223 mutex_unlock(&df->devfreq->lock); 224 } 225 226 void msm_devfreq_idle(struct msm_gpu *gpu) 227 { 228 struct msm_gpu_devfreq *df = &gpu->devfreq; 229 230 msm_hrtimer_queue_work(&df->idle_work, ms_to_ktime(1), 231 HRTIMER_MODE_ABS); 232 } 233