Lines Matching +full:cpu +full:- +full:version

1 /*-
37 #include <sys/cpu.h>
71 #define CPUFREQ_DT_HAVE_REGULATOR(sc) ((sc)->reg != NULL)
81 int cpu; member
90 int cpu; in cpufreq_dt_notify() local
94 CPU_FOREACH(cpu) { in cpufreq_dt_notify()
95 if (CPU_ISSET(cpu, &sc->cpus)) { in cpufreq_dt_notify()
96 pc = pcpu_find(cpu); in cpufreq_dt_notify()
97 pc->pc_clock = freq; in cpufreq_dt_notify()
114 for (n = 0; n < sc->nopp; n++) { in cpufreq_dt_find_opp()
115 diff = abs64((int64_t)sc->opp[n].freq - (int64_t)freq); in cpufreq_dt_find_opp()
116 DPRINTF(dev, "Testing %ju, diff is %ju\n", sc->opp[n].freq, diff); in cpufreq_dt_find_opp()
120 DPRINTF(dev, "%ju is best for now\n", sc->opp[n].freq); in cpufreq_dt_find_opp()
124 DPRINTF(dev, "Will use %ju\n", sc->opp[best_n].freq); in cpufreq_dt_find_opp()
125 return (&sc->opp[best_n]); in cpufreq_dt_find_opp()
134 set->freq = opp->freq / 1000000; in cpufreq_dt_opp_to_setting()
135 set->volts = opp->uvolt_target / 1000; in cpufreq_dt_opp_to_setting()
136 set->power = CPUFREQ_VAL_UNKNOWN; in cpufreq_dt_opp_to_setting()
137 set->lat = opp->clk_latency; in cpufreq_dt_opp_to_setting()
138 set->dev = dev; in cpufreq_dt_opp_to_setting()
151 if (clk_get_freq(sc->clk, &freq) != 0) in cpufreq_dt_get()
162 DPRINTF(dev, "Current freq %dMhz\n", set->freq); in cpufreq_dt_get()
176 DPRINTF(dev, "Working on cpu %d\n", sc->cpu); in cpufreq_dt_set()
177 DPRINTF(dev, "We have %d cpu on this dev\n", CPU_COUNT(&sc->cpus)); in cpufreq_dt_set()
178 if (!CPU_ISSET(sc->cpu, &sc->cpus)) { in cpufreq_dt_set()
179 DPRINTF(dev, "Not for this CPU\n"); in cpufreq_dt_set()
183 if (clk_get_freq(sc->clk, &freq) != 0) { in cpufreq_dt_set()
193 error = regulator_get_voltage(sc->reg, &uvolt); in cpufreq_dt_set()
202 copp = cpufreq_dt_find_opp(sc->dev, freq); in cpufreq_dt_set()
208 uvolt = copp->uvolt_target; in cpufreq_dt_set()
213 opp = cpufreq_dt_find_opp(sc->dev, (uint64_t)set->freq * 1000000); in cpufreq_dt_set()
218 DPRINTF(sc->dev, "Current freq %ju, uvolt: %d\n", freq, uvolt); in cpufreq_dt_set()
219 DPRINTF(sc->dev, "Target freq %ju, , uvolt: %d\n", in cpufreq_dt_set()
220 opp->freq, opp->uvolt_target); in cpufreq_dt_set()
222 if (CPUFREQ_DT_HAVE_REGULATOR(sc) && (uvolt < opp->uvolt_target)) { in cpufreq_dt_set()
224 uvolt, opp->uvolt_target); in cpufreq_dt_set()
225 error = regulator_set_voltage(sc->reg, in cpufreq_dt_set()
226 opp->uvolt_min, in cpufreq_dt_set()
227 opp->uvolt_max); in cpufreq_dt_set()
234 DPRINTF(dev, "Setting clk to %ju\n", opp->freq); in cpufreq_dt_set()
235 error = clk_set_freq(sc->clk, opp->freq, CLK_SET_ROUND_DOWN); in cpufreq_dt_set()
240 error = regulator_set_voltage(sc->reg, in cpufreq_dt_set()
241 copp->uvolt_min, in cpufreq_dt_set()
242 copp->uvolt_max); in cpufreq_dt_set()
246 if (CPUFREQ_DT_HAVE_REGULATOR(sc) && (uvolt > opp->uvolt_target)) { in cpufreq_dt_set()
248 uvolt, opp->uvolt_target); in cpufreq_dt_set()
249 error = regulator_set_voltage(sc->reg, in cpufreq_dt_set()
250 opp->uvolt_min, in cpufreq_dt_set()
251 opp->uvolt_max); in cpufreq_dt_set()
254 opp->uvolt_target); in cpufreq_dt_set()
255 /* Restore previous CPU frequency (best effort) */ in cpufreq_dt_set()
256 (void)clk_set_freq(sc->clk, copp->freq, 0); in cpufreq_dt_set()
261 if (clk_get_freq(sc->clk, &freq) == 0) in cpufreq_dt_set()
289 if (*count < sc->nopp) { in cpufreq_dt_settings()
290 *count = (int)sc->nopp; in cpufreq_dt_settings()
294 for (n = 0; n < sc->nopp; n++) in cpufreq_dt_settings()
295 cpufreq_dt_opp_to_setting(dev, &sc->opp[n], &sets[n]); in cpufreq_dt_settings()
297 *count = (int)sc->nopp; in cpufreq_dt_settings()
307 /* Properties must be listed under node /cpus/cpu@0 */ in cpufreq_dt_identify()
310 /* The cpu@0 node must have the following properties */ in cpufreq_dt_identify()
314 if (!OF_hasprop(node, "operating-points") && in cpufreq_dt_identify()
315 !OF_hasprop(node, "operating-points-v2")) in cpufreq_dt_identify()
334 * Note - supply isn't required here for probe; we'll check in cpufreq_dt_probe()
340 if (!OF_hasprop(node, "operating-points") && in cpufreq_dt_probe()
341 !OF_hasprop(node, "operating-points-v2")) in cpufreq_dt_probe()
354 sc->nopp = OF_getencprop_alloc_multi(node, "operating-points", in cpufreq_dt_oppv1_parse()
356 if (sc->nopp == -1) in cpufreq_dt_oppv1_parse()
359 if (OF_getencprop(node, "clock-latency", &lat, sizeof(lat)) == -1) in cpufreq_dt_oppv1_parse()
362 sc->opp = malloc(sizeof(*sc->opp) * sc->nopp, M_DEVBUF, M_WAITOK); in cpufreq_dt_oppv1_parse()
364 for (n = 0; n < sc->nopp; n++) { in cpufreq_dt_oppv1_parse()
365 sc->opp[n].freq = opp[n * 2 + 0] * 1000; in cpufreq_dt_oppv1_parse()
366 sc->opp[n].uvolt_min = opp[n * 2 + 1]; in cpufreq_dt_oppv1_parse()
367 sc->opp[n].uvolt_max = sc->opp[n].uvolt_min; in cpufreq_dt_oppv1_parse()
368 sc->opp[n].uvolt_target = sc->opp[n].uvolt_min; in cpufreq_dt_oppv1_parse()
369 sc->opp[n].clk_latency = lat; in cpufreq_dt_oppv1_parse()
372 device_printf(sc->dev, "%ju.%03ju MHz, %u uV\n", in cpufreq_dt_oppv1_parse()
373 sc->opp[n].freq / 1000000, in cpufreq_dt_oppv1_parse()
374 sc->opp[n].freq % 1000000, in cpufreq_dt_oppv1_parse()
375 sc->opp[n].uvolt_target); in cpufreq_dt_oppv1_parse()
391 * operating-points-v2 does not require the voltage entries in cpufreq_dt_oppv2_parse()
394 if (OF_getencprop(node, "operating-points-v2", &opp_xref, in cpufreq_dt_oppv2_parse()
395 sizeof(opp_xref)) == -1) { in cpufreq_dt_oppv2_parse()
396 device_printf(sc->dev, "Cannot get xref to oppv2 table\n"); in cpufreq_dt_oppv2_parse()
404 if (!OF_hasprop(opp_table, "opp-shared") && mp_ncpus > 1) { in cpufreq_dt_oppv2_parse()
405 device_printf(sc->dev, "Only opp-shared is supported\n"); in cpufreq_dt_oppv2_parse()
410 sc->nopp += 1; in cpufreq_dt_oppv2_parse()
412 sc->opp = malloc(sizeof(*sc->opp) * sc->nopp, M_DEVBUF, M_WAITOK); in cpufreq_dt_oppv2_parse()
416 /* opp-hz is a required property */ in cpufreq_dt_oppv2_parse()
417 if (OF_getencprop(opp_table, "opp-hz", cell, in cpufreq_dt_oppv2_parse()
418 sizeof(cell)) == -1) in cpufreq_dt_oppv2_parse()
421 sc->opp[i].freq = cell[0]; in cpufreq_dt_oppv2_parse()
422 sc->opp[i].freq <<= 32; in cpufreq_dt_oppv2_parse()
423 sc->opp[i].freq |= cell[1]; in cpufreq_dt_oppv2_parse()
425 if (OF_getencprop(opp_table, "clock-latency", &lat, in cpufreq_dt_oppv2_parse()
426 sizeof(lat)) == -1) in cpufreq_dt_oppv2_parse()
427 sc->opp[i].clk_latency = CPUFREQ_VAL_UNKNOWN; in cpufreq_dt_oppv2_parse()
429 sc->opp[i].clk_latency = (int)lat; in cpufreq_dt_oppv2_parse()
431 if (OF_hasprop(opp_table, "turbo-mode")) in cpufreq_dt_oppv2_parse()
432 sc->opp[i].turbo_mode = true; in cpufreq_dt_oppv2_parse()
433 if (OF_hasprop(opp_table, "opp-suspend")) in cpufreq_dt_oppv2_parse()
434 sc->opp[i].opp_suspend = true; in cpufreq_dt_oppv2_parse()
438 "opp-microvolt", sizeof(*volts), (void **)&volts); in cpufreq_dt_oppv2_parse()
440 sc->opp[i].uvolt_target = volts[0]; in cpufreq_dt_oppv2_parse()
441 sc->opp[i].uvolt_min = volts[0]; in cpufreq_dt_oppv2_parse()
442 sc->opp[i].uvolt_max = volts[0]; in cpufreq_dt_oppv2_parse()
444 sc->opp[i].uvolt_target = volts[0]; in cpufreq_dt_oppv2_parse()
445 sc->opp[i].uvolt_min = volts[1]; in cpufreq_dt_oppv2_parse()
446 sc->opp[i].uvolt_max = volts[2]; in cpufreq_dt_oppv2_parse()
448 device_printf(sc->dev, in cpufreq_dt_oppv2_parse()
449 "Wrong count of opp-microvolt property\n"); in cpufreq_dt_oppv2_parse()
451 free(sc->opp, M_DEVBUF); in cpufreq_dt_oppv2_parse()
457 sc->opp[i].uvolt_target = 0; in cpufreq_dt_oppv2_parse()
458 sc->opp[i].uvolt_min = 0; in cpufreq_dt_oppv2_parse()
459 sc->opp[i].uvolt_max = 0; in cpufreq_dt_oppv2_parse()
463 device_printf(sc->dev, "%ju.%03ju Mhz (%u uV)\n", in cpufreq_dt_oppv2_parse()
464 sc->opp[i].freq / 1000000, in cpufreq_dt_oppv2_parse()
465 sc->opp[i].freq % 1000000, in cpufreq_dt_oppv2_parse()
466 sc->opp[i].uvolt_target); in cpufreq_dt_oppv2_parse()
477 int cpu; in cpufreq_dt_attach() local
481 enum opp_version version; in cpufreq_dt_attach() local
484 sc->dev = dev; in cpufreq_dt_attach()
486 sc->cpu = device_get_unit(device_get_parent(dev)); in cpufreq_dt_attach()
487 sc->reg = NULL; in cpufreq_dt_attach()
489 DPRINTF(dev, "cpu=%d\n", sc->cpu); in cpufreq_dt_attach()
490 if (sc->cpu >= mp_ncpus) { in cpufreq_dt_attach()
491 device_printf(dev, "Not attaching as cpu is not present\n"); in cpufreq_dt_attach()
498 * quite yet. If it's operating-points-v2 then regulator in cpufreq_dt_attach()
501 if (regulator_get_by_ofw_property(dev, node, "cpu-supply", in cpufreq_dt_attach()
502 &sc->reg) == 0) in cpufreq_dt_attach()
503 device_printf(dev, "Found cpu-supply\n"); in cpufreq_dt_attach()
504 else if (regulator_get_by_ofw_property(dev, node, "cpu0-supply", in cpufreq_dt_attach()
505 &sc->reg) == 0) in cpufreq_dt_attach()
506 device_printf(dev, "Found cpu0-supply\n"); in cpufreq_dt_attach()
512 if (OF_hasprop(node, "operating-points")) in cpufreq_dt_attach()
513 version = OPP_V1; in cpufreq_dt_attach()
514 else if (OF_hasprop(node, "operating-points-v2")) in cpufreq_dt_attach()
515 version = OPP_V2; in cpufreq_dt_attach()
518 "didn't find a valid operating-points or v2 node\n"); in cpufreq_dt_attach()
526 if ((version == OPP_V1) && !CPUFREQ_DT_HAVE_REGULATOR(sc)) { in cpufreq_dt_attach()
533 if (clk_get_by_ofw_index(dev, node, 0, &sc->clk) != 0) { in cpufreq_dt_attach()
540 if (version == OPP_V1) { in cpufreq_dt_attach()
543 device_printf(dev, "Failed to parse opp-v1 table\n"); in cpufreq_dt_attach()
546 OF_getencprop(node, "operating-points", &opp, in cpufreq_dt_attach()
548 } else if (version == OPP_V2) { in cpufreq_dt_attach()
551 device_printf(dev, "Failed to parse opp-v2 table\n"); in cpufreq_dt_attach()
554 OF_getencprop(node, "operating-points-v2", &opp, in cpufreq_dt_attach()
557 device_printf(dev, "operating points version is incorrect\n"); in cpufreq_dt_attach()
564 CPU_ZERO(&sc->cpus); in cpufreq_dt_attach()
566 for (cpu = 0, cnode = OF_child(cnode); cnode > 0; cnode = OF_peer(cnode)) { in cpufreq_dt_attach()
569 if (strcmp(device_type, "cpu") != 0) in cpufreq_dt_attach()
571 if (cpu == sc->cpu) { in cpufreq_dt_attach()
572 DPRINTF(dev, "Skipping our cpu\n"); in cpufreq_dt_attach()
573 CPU_SET(cpu, &sc->cpus); in cpufreq_dt_attach()
574 cpu++; in cpufreq_dt_attach()
577 DPRINTF(dev, "Testing CPU %d\n", cpu); in cpufreq_dt_attach()
578 copp = -1; in cpufreq_dt_attach()
579 if (version == OPP_V1) in cpufreq_dt_attach()
580 OF_getencprop(cnode, "operating-points", &copp, in cpufreq_dt_attach()
582 else if (version == OPP_V2) in cpufreq_dt_attach()
583 OF_getencprop(cnode, "operating-points-v2", in cpufreq_dt_attach()
586 DPRINTF(dev, "CPU %d is using the same opp as this one (%d)\n", in cpufreq_dt_attach()
587 cpu, sc->cpu); in cpufreq_dt_attach()
588 CPU_SET(cpu, &sc->cpus); in cpufreq_dt_attach()
590 cpu++; in cpufreq_dt_attach()
593 if (clk_get_freq(sc->clk, &freq) == 0) in cpufreq_dt_attach()
601 regulator_release(sc->reg); in cpufreq_dt_attach()
626 DRIVER_MODULE(cpufreq_dt, cpu, cpufreq_dt_driver, 0, 0);