static int gk20a_scale_qos_notify(struct notifier_block *nb, unsigned long n, void *p) { struct gk20a_scale_profile *profile = container_of(nb, struct gk20a_scale_profile, qos_notify_block); struct gk20a_platform *platform = platform_get_drvdata(profile->pdev); struct gk20a *g = get_gk20a(profile->pdev); unsigned long freq; if (!platform->postscale) return NOTIFY_OK; /* get the frequency requirement. if devfreq is enabled, check if it * has higher demand than qos */ freq = gk20a_clk_round_rate(g, pm_qos_request(platform->qos_id)); if (g->devfreq) freq = max(g->devfreq->previous_freq, freq); /* Update gpu load because we may scale the emc target * if the gpu load changed. */ gk20a_pmu_load_update(g); platform->postscale(profile->pdev, freq); return NOTIFY_OK; }
static ssize_t gk20a_load_show(struct device *dev, struct device_attribute *attr, char *buf) { struct platform_device *pdev = to_platform_device(dev); struct gk20a *g = get_gk20a(pdev); u32 busy_time; ssize_t res; int err; if (!g->power_on) { busy_time = 0; } else { err = gk20a_busy(g->dev); if (err) return err; gk20a_pmu_load_update(g); gk20a_pmu_load_norm(g, &busy_time); gk20a_idle(g->dev); } res = snprintf(buf, PAGE_SIZE, "%u\n", busy_time); return res; }
static void gk20a_scale_notify(struct platform_device *pdev, bool busy) { struct gk20a_platform *platform = platform_get_drvdata(pdev); struct gk20a *g = get_gk20a(pdev); struct gk20a_scale_profile *profile = g->scale_profile; struct devfreq *devfreq = g->devfreq; /* update the software shadow */ gk20a_pmu_load_update(g); /* inform edp about new constraint */ if (platform->prescale) platform->prescale(pdev); /* Is the device profile initialised? */ if (!(profile && devfreq)) return; mutex_lock(&devfreq->lock); profile->dev_stat.busy = busy; update_devfreq(devfreq); mutex_unlock(&devfreq->lock); }