Lines Matching +full:opp +full:- +full:table
1 /*-
71 #define CPUFREQ_DT_HAVE_REGULATOR(sc) ((sc)->reg != NULL)
78 struct cpufreq_dt_opp *opp;
95 if (CPU_ISSET(cpu, &sc->cpus)) {
97 pc->pc_clock = freq;
114 for (n = 0; n < sc->nopp; n++) {
115 diff = abs64((int64_t)sc->opp[n].freq - (int64_t)freq);
116 DPRINTF(dev, "Testing %ju, diff is %ju\n", sc->opp[n].freq, diff);
120 DPRINTF(dev, "%ju is best for now\n", sc->opp[n].freq);
124 DPRINTF(dev, "Will use %ju\n", sc->opp[best_n].freq);
125 return (&sc->opp[best_n]);
129 cpufreq_dt_opp_to_setting(device_t dev, const struct cpufreq_dt_opp *opp,
134 set->freq = opp->freq / 1000000;
135 set->volts = opp->uvolt_target / 1000;
136 set->power = CPUFREQ_VAL_UNKNOWN;
137 set->lat = opp->clk_latency;
138 set->dev = dev;
145 const struct cpufreq_dt_opp *opp;
151 if (clk_get_freq(sc->clk, &freq) != 0)
154 opp = cpufreq_dt_find_opp(dev, freq);
155 if (opp == NULL) {
156 device_printf(dev, "Can't find the current freq in opp\n");
160 cpufreq_dt_opp_to_setting(dev, opp, set);
162 DPRINTF(dev, "Current freq %dMhz\n", set->freq);
170 const struct cpufreq_dt_opp *opp, *copp;
176 DPRINTF(dev, "Working on cpu %d\n", sc->cpu);
177 DPRINTF(dev, "We have %d cpu on this dev\n", CPU_COUNT(&sc->cpus));
178 if (!CPU_ISSET(sc->cpu, &sc->cpus)) {
183 if (clk_get_freq(sc->clk, &freq) != 0) {
193 error = regulator_get_voltage(sc->reg, &uvolt);
196 * Try oppoints table as backup way. However,
198 * frequency may not be in the table. PLL frequency
200 * oppoint table.
202 copp = cpufreq_dt_find_opp(sc->dev, freq);
205 "Can't find the current freq in opp\n");
208 uvolt = copp->uvolt_target;
213 opp = cpufreq_dt_find_opp(sc->dev, set->freq * 1000000);
214 if (opp == NULL) {
215 device_printf(dev, "Couldn't find an opp for this freq\n");
218 DPRINTF(sc->dev, "Current freq %ju, uvolt: %d\n", freq, uvolt);
219 DPRINTF(sc->dev, "Target freq %ju, , uvolt: %d\n",
220 opp->freq, opp->uvolt_target);
222 if (CPUFREQ_DT_HAVE_REGULATOR(sc) && (uvolt < opp->uvolt_target)) {
224 uvolt, opp->uvolt_target);
225 error = regulator_set_voltage(sc->reg,
226 opp->uvolt_min,
227 opp->uvolt_max);
234 DPRINTF(dev, "Setting clk to %ju\n", opp->freq);
235 error = clk_set_freq(sc->clk, opp->freq, CLK_SET_ROUND_DOWN);
240 error = regulator_set_voltage(sc->reg,
241 copp->uvolt_min,
242 copp->uvolt_max);
246 if (CPUFREQ_DT_HAVE_REGULATOR(sc) && (uvolt > opp->uvolt_target)) {
248 uvolt, opp->uvolt_target);
249 error = regulator_set_voltage(sc->reg,
250 opp->uvolt_min,
251 opp->uvolt_max);
254 opp->uvolt_target);
256 (void)clk_set_freq(sc->clk, copp->freq, 0);
261 if (clk_get_freq(sc->clk, &freq) == 0)
289 if (*count < sc->nopp) {
290 *count = (int)sc->nopp;
294 for (n = 0; n < sc->nopp; n++)
295 cpufreq_dt_opp_to_setting(dev, &sc->opp[n], &sets[n]);
297 *count = (int)sc->nopp;
314 if (!OF_hasprop(node, "operating-points") &&
315 !OF_hasprop(node, "operating-points-v2"))
318 if (device_find_child(parent, "cpufreq_dt", -1) != NULL)
334 * Note - supply isn't required here for probe; we'll check
340 if (!OF_hasprop(node, "operating-points") &&
341 !OF_hasprop(node, "operating-points-v2"))
351 uint32_t *opp, lat;
354 sc->nopp = OF_getencprop_alloc_multi(node, "operating-points",
355 sizeof(uint32_t) * 2, (void **)&opp);
356 if (sc->nopp == -1)
359 if (OF_getencprop(node, "clock-latency", &lat, sizeof(lat)) == -1)
362 sc->opp = malloc(sizeof(*sc->opp) * sc->nopp, M_DEVBUF, M_WAITOK);
364 for (n = 0; n < sc->nopp; n++) {
365 sc->opp[n].freq = opp[n * 2 + 0] * 1000;
366 sc->opp[n].uvolt_min = opp[n * 2 + 1];
367 sc->opp[n].uvolt_max = sc->opp[n].uvolt_min;
368 sc->opp[n].uvolt_target = sc->opp[n].uvolt_min;
369 sc->opp[n].clk_latency = lat;
372 device_printf(sc->dev, "%ju.%03ju MHz, %u uV\n",
373 sc->opp[n].freq / 1000000,
374 sc->opp[n].freq % 1000000,
375 sc->opp[n].uvolt_target);
377 free(opp, M_OFWPROP);
385 phandle_t opp, opp_table, opp_xref;
391 * operating-points-v2 does not require the voltage entries
394 if (OF_getencprop(node, "operating-points-v2", &opp_xref,
395 sizeof(opp_xref)) == -1) {
396 device_printf(sc->dev, "Cannot get xref to oppv2 table\n");
404 if (!OF_hasprop(opp_table, "opp-shared") && mp_ncpus > 1) {
405 device_printf(sc->dev, "Only opp-shared is supported\n");
409 for (opp = OF_child(opp_table); opp > 0; opp = OF_peer(opp))
410 sc->nopp += 1;
412 sc->opp = malloc(sizeof(*sc->opp) * sc->nopp, M_DEVBUF, M_WAITOK);
416 /* opp-hz is a required property */
417 if (OF_getencprop(opp_table, "opp-hz", cell,
418 sizeof(cell)) == -1)
421 sc->opp[i].freq = cell[0];
422 sc->opp[i].freq <<= 32;
423 sc->opp[i].freq |= cell[1];
425 if (OF_getencprop(opp_table, "clock-latency", &lat,
426 sizeof(lat)) == -1)
427 sc->opp[i].clk_latency = CPUFREQ_VAL_UNKNOWN;
429 sc->opp[i].clk_latency = (int)lat;
431 if (OF_hasprop(opp_table, "turbo-mode"))
432 sc->opp[i].turbo_mode = true;
433 if (OF_hasprop(opp_table, "opp-suspend"))
434 sc->opp[i].opp_suspend = true;
438 "opp-microvolt", sizeof(*volts), (void **)&volts);
440 sc->opp[i].uvolt_target = volts[0];
441 sc->opp[i].uvolt_min = volts[0];
442 sc->opp[i].uvolt_max = volts[0];
444 sc->opp[i].uvolt_target = volts[0];
445 sc->opp[i].uvolt_min = volts[1];
446 sc->opp[i].uvolt_max = volts[2];
448 device_printf(sc->dev,
449 "Wrong count of opp-microvolt property\n");
451 free(sc->opp, M_DEVBUF);
457 sc->opp[i].uvolt_target = 0;
458 sc->opp[i].uvolt_min = 0;
459 sc->opp[i].uvolt_max = 0;
463 device_printf(sc->dev, "%ju.%03ju Mhz (%u uV)\n",
464 sc->opp[i].freq / 1000000,
465 sc->opp[i].freq % 1000000,
466 sc->opp[i].uvolt_target);
476 phandle_t cnode, opp, copp;
484 sc->dev = dev;
486 sc->cpu = device_get_unit(device_get_parent(dev));
487 sc->reg = NULL;
489 DPRINTF(dev, "cpu=%d\n", sc->cpu);
490 if (sc->cpu >= mp_ncpus) {
498 * quite yet. If it's operating-points-v2 then regulator
501 if (regulator_get_by_ofw_property(dev, node, "cpu-supply",
502 &sc->reg) == 0)
503 device_printf(dev, "Found cpu-supply\n");
504 else if (regulator_get_by_ofw_property(dev, node, "cpu0-supply",
505 &sc->reg) == 0)
506 device_printf(dev, "Found cpu0-supply\n");
512 if (OF_hasprop(node, "operating-points"))
514 else if (OF_hasprop(node, "operating-points-v2"))
518 "didn't find a valid operating-points or v2 node\n");
533 if (clk_get_by_ofw_index(dev, node, 0, &sc->clk) != 0) {
543 device_printf(dev, "Failed to parse opp-v1 table\n");
546 OF_getencprop(node, "operating-points", &opp,
547 sizeof(opp));
551 device_printf(dev, "Failed to parse opp-v2 table\n");
554 OF_getencprop(node, "operating-points-v2", &opp,
555 sizeof(opp));
562 * Find all CPUs that share the same opp table
564 CPU_ZERO(&sc->cpus);
571 if (cpu == sc->cpu) {
573 CPU_SET(cpu, &sc->cpus);
578 copp = -1;
580 OF_getencprop(cnode, "operating-points", &copp,
583 OF_getencprop(cnode, "operating-points-v2",
585 if (opp == copp) {
586 DPRINTF(dev, "CPU %d is using the same opp as this one (%d)\n",
587 cpu, sc->cpu);
588 CPU_SET(cpu, &sc->cpus);
593 if (clk_get_freq(sc->clk, &freq) == 0)
601 regulator_release(sc->reg);