Lines Matching +full:tegra30 +full:- +full:emc

1 // SPDX-License-Identifier: GPL-2.0-only
76 * struct tegra_devfreq_device_config - configuration specific to an ACTMON
96 * increasing the EMC frequency when the CPU is very busy but not
152 * struct tegra_devfreq_device - state specific to an ACTMON device
221 return readl_relaxed(tegra->regs + offset); in actmon_readl()
226 writel_relaxed(val, tegra->regs + offset); in actmon_writel()
231 return readl_relaxed(dev->regs + offset); in device_readl()
237 writel_relaxed(val, dev->regs + offset); in device_writel()
255 u32 avg_band_freq = tegra->max_freq * ACTMON_DEFAULT_AVG_BAND / KHZ; in tegra_devfreq_update_avg_wmark()
256 u32 band = avg_band_freq * tegra->devfreq->profile->polling_ms; in tegra_devfreq_update_avg_wmark()
259 avg = min(dev->avg_count, U32_MAX - band); in tegra_devfreq_update_avg_wmark()
262 avg = max(dev->avg_count, band); in tegra_devfreq_update_avg_wmark()
263 device_writel(dev, avg - band, ACTMON_DEV_AVG_LOWER_WMARK); in tegra_devfreq_update_avg_wmark()
269 u32 val = tegra->cur_freq * tegra->devfreq->profile->polling_ms; in tegra_devfreq_update_wmark()
271 device_writel(dev, do_percent(val, dev->config->boost_up_threshold), in tegra_devfreq_update_wmark()
274 device_writel(dev, do_percent(val, dev->config->boost_down_threshold), in tegra_devfreq_update_wmark()
283 dev->avg_count = device_readl(dev, ACTMON_DEV_AVG_COUNT); in actmon_isr_device()
293 dev->boost_freq = do_percent(dev->boost_freq, in actmon_isr_device()
294 dev->config->boost_up_coeff); in actmon_isr_device()
295 dev->boost_freq += ACTMON_BOOST_FREQ_STEP; in actmon_isr_device()
299 if (dev->boost_freq >= tegra->max_freq) { in actmon_isr_device()
301 dev->boost_freq = tegra->max_freq; in actmon_isr_device()
308 dev->boost_freq = do_percent(dev->boost_freq, in actmon_isr_device()
309 dev->config->boost_down_coeff); in actmon_isr_device()
313 if (dev->boost_freq < (ACTMON_BOOST_FREQ_STEP >> 1)) { in actmon_isr_device()
315 dev->boost_freq = 0; in actmon_isr_device()
331 if (cpu_freq >= ratio->cpu_freq) { in actmon_cpu_to_emc_rate()
332 if (ratio->emc_freq >= tegra->max_freq) in actmon_cpu_to_emc_rate()
333 return tegra->max_freq; in actmon_cpu_to_emc_rate()
335 return ratio->emc_freq; in actmon_cpu_to_emc_rate()
348 target_freq = dev->avg_count / tegra->devfreq->profile->polling_ms; in actmon_device_target_freq()
349 avg_sustain_coef = 100 * 100 / dev->config->boost_up_threshold; in actmon_device_target_freq()
361 dev->target_freq = actmon_device_target_freq(tegra, dev); in actmon_update_target()
363 if (dev->config->avg_dependency_threshold && in actmon_update_target()
364 dev->config->avg_dependency_threshold <= dev->target_freq) { in actmon_update_target()
368 dev->target_freq += dev->boost_freq; in actmon_update_target()
369 dev->target_freq = max(dev->target_freq, static_cpu_emc_freq); in actmon_update_target()
371 dev->target_freq += dev->boost_freq; in actmon_update_target()
382 mutex_lock(&tegra->devfreq->lock); in actmon_thread_isr()
385 for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) { in actmon_thread_isr()
386 if (val & tegra->devices[i].config->irq_mask) { in actmon_thread_isr()
387 actmon_isr_device(tegra, tegra->devices + i); in actmon_thread_isr()
393 update_devfreq(tegra->devfreq); in actmon_thread_isr()
395 mutex_unlock(&tegra->devfreq->lock); in actmon_thread_isr()
413 tegra->cur_freq = data->new_rate / KHZ; in tegra_actmon_clk_notify_cb()
415 for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) { in tegra_actmon_clk_notify_cb()
416 dev = &tegra->devices[i]; in tegra_actmon_clk_notify_cb()
429 mutex_lock(&tegra->devfreq->lock); in tegra_actmon_delayed_update()
430 update_devfreq(tegra->devfreq); in tegra_actmon_delayed_update()
431 mutex_unlock(&tegra->devfreq->lock); in tegra_actmon_delayed_update()
438 struct tegra_devfreq_device *actmon_dev = &tegra->devices[MCCPU]; in tegra_actmon_cpufreq_contribution()
444 if (dev_freq < actmon_dev->config->avg_dependency_threshold) in tegra_actmon_cpufreq_contribution()
449 if (dev_freq + actmon_dev->boost_freq >= static_cpu_emc_freq) in tegra_actmon_cpufreq_contribution()
471 if (mutex_trylock(&tegra->devfreq->lock)) { in tegra_actmon_cpu_notify_cb()
472 old = tegra_actmon_cpufreq_contribution(tegra, freqs->old); in tegra_actmon_cpu_notify_cb()
473 new = tegra_actmon_cpufreq_contribution(tegra, freqs->new); in tegra_actmon_cpu_notify_cb()
474 mutex_unlock(&tegra->devfreq->lock); in tegra_actmon_cpu_notify_cb()
479 * state because ISR will re-check CPU's frequency on the in tegra_actmon_cpu_notify_cb()
493 schedule_delayed_work(&tegra->cpufreq_update_work, delay); in tegra_actmon_cpu_notify_cb()
504 dev->boost_freq = 0; in tegra_actmon_configure_device()
506 dev->target_freq = tegra->cur_freq; in tegra_actmon_configure_device()
508 dev->avg_count = tegra->cur_freq * tegra->devfreq->profile->polling_ms; in tegra_actmon_configure_device()
509 device_writel(dev, dev->avg_count, ACTMON_DEV_INIT_AVG); in tegra_actmon_configure_device()
514 device_writel(dev, tegra->soc->count_weight, ACTMON_DEV_COUNT_WEIGHT); in tegra_actmon_configure_device()
518 val |= (ACTMON_AVERAGE_WINDOW_LOG2 - 1) in tegra_actmon_configure_device()
520 val |= (ACTMON_BELOW_WMARK_WINDOW - 1) in tegra_actmon_configure_device()
522 val |= (ACTMON_ABOVE_WMARK_WINDOW - 1) in tegra_actmon_configure_device()
534 struct tegra_devfreq_device *dev = tegra->devices; in tegra_actmon_stop_devices()
537 for (i = 0; i < ARRAY_SIZE(tegra->devices); i++, dev++) { in tegra_actmon_stop_devices()
549 if (!tegra->devfreq->profile->polling_ms || !tegra->started) in tegra_actmon_resume()
552 actmon_writel(tegra, tegra->devfreq->profile->polling_ms - 1, in tegra_actmon_resume()
560 err = clk_notifier_register(tegra->emc_clock, in tegra_actmon_resume()
561 &tegra->clk_rate_change_nb); in tegra_actmon_resume()
563 dev_err(tegra->devfreq->dev.parent, in tegra_actmon_resume()
568 tegra->cur_freq = clk_get_rate(tegra->emc_clock) / KHZ; in tegra_actmon_resume()
570 for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) in tegra_actmon_resume()
571 tegra_actmon_configure_device(tegra, &tegra->devices[i]); in tegra_actmon_resume()
580 err = cpufreq_register_notifier(&tegra->cpu_rate_change_nb, in tegra_actmon_resume()
583 dev_err(tegra->devfreq->dev.parent, in tegra_actmon_resume()
588 enable_irq(tegra->irq); in tegra_actmon_resume()
595 clk_notifier_unregister(tegra->emc_clock, &tegra->clk_rate_change_nb); in tegra_actmon_resume()
604 if (!tegra->started) { in tegra_actmon_start()
605 tegra->started = true; in tegra_actmon_start()
609 tegra->started = false; in tegra_actmon_start()
617 if (!tegra->devfreq->profile->polling_ms || !tegra->started) in tegra_actmon_pause()
620 disable_irq(tegra->irq); in tegra_actmon_pause()
622 cpufreq_unregister_notifier(&tegra->cpu_rate_change_nb, in tegra_actmon_pause()
625 cancel_delayed_work_sync(&tegra->cpufreq_update_work); in tegra_actmon_pause()
629 clk_notifier_unregister(tegra->emc_clock, &tegra->clk_rate_change_nb); in tegra_actmon_pause()
635 tegra->started = false; in tegra_actmon_stop()
663 cur_freq = READ_ONCE(tegra->cur_freq); in tegra_devfreq_get_dev_status()
666 stat->private_data = tegra; in tegra_devfreq_get_dev_status()
669 stat->current_frequency = cur_freq * KHZ; in tegra_devfreq_get_dev_status()
671 actmon_dev = &tegra->devices[MCALL]; in tegra_devfreq_get_dev_status()
674 stat->busy_time = device_readl(actmon_dev, ACTMON_DEV_AVG_COUNT); in tegra_devfreq_get_dev_status()
677 stat->busy_time *= 100 / BUS_SATURATION_RATIO; in tegra_devfreq_get_dev_status()
680 stat->total_time = tegra->devfreq->profile->polling_ms * cur_freq; in tegra_devfreq_get_dev_status()
682 stat->busy_time = min(stat->busy_time, stat->total_time); in tegra_devfreq_get_dev_status()
708 stat = &devfreq->last_status; in tegra_governor_get_target()
710 tegra = stat->private_data; in tegra_governor_get_target()
712 for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) { in tegra_governor_get_target()
713 dev = &tegra->devices[i]; in tegra_governor_get_target()
717 target_freq = max(target_freq, dev->target_freq); in tegra_governor_get_target()
721 * tegra-devfreq driver operates with KHz units, while OPP table in tegra_governor_get_target()
733 struct tegra_devfreq *tegra = dev_get_drvdata(devfreq->dev.parent); in tegra_governor_event_handler()
738 * Couple devfreq-device with the governor early because it is in tegra_governor_event_handler()
741 tegra->devfreq = devfreq; in tegra_governor_event_handler()
760 ret = -EINVAL; in tegra_governor_event_handler()
802 tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL); in tegra_devfreq_probe()
804 return -ENOMEM; in tegra_devfreq_probe()
806 tegra->soc = of_device_get_match_data(&pdev->dev); in tegra_devfreq_probe()
808 tegra->regs = devm_platform_ioremap_resource(pdev, 0); in tegra_devfreq_probe()
809 if (IS_ERR(tegra->regs)) in tegra_devfreq_probe()
810 return PTR_ERR(tegra->regs); in tegra_devfreq_probe()
812 tegra->reset = devm_reset_control_get(&pdev->dev, "actmon"); in tegra_devfreq_probe()
813 if (IS_ERR(tegra->reset)) { in tegra_devfreq_probe()
814 dev_err(&pdev->dev, "Failed to get reset\n"); in tegra_devfreq_probe()
815 return PTR_ERR(tegra->reset); in tegra_devfreq_probe()
818 tegra->clock = devm_clk_get(&pdev->dev, "actmon"); in tegra_devfreq_probe()
819 if (IS_ERR(tegra->clock)) { in tegra_devfreq_probe()
820 dev_err(&pdev->dev, "Failed to get actmon clock\n"); in tegra_devfreq_probe()
821 return PTR_ERR(tegra->clock); in tegra_devfreq_probe()
824 tegra->emc_clock = devm_clk_get(&pdev->dev, "emc"); in tegra_devfreq_probe()
825 if (IS_ERR(tegra->emc_clock)) in tegra_devfreq_probe()
826 return dev_err_probe(&pdev->dev, PTR_ERR(tegra->emc_clock), in tegra_devfreq_probe()
827 "Failed to get emc clock\n"); in tegra_devfreq_probe()
833 tegra->irq = err; in tegra_devfreq_probe()
835 irq_set_status_flags(tegra->irq, IRQ_NOAUTOEN); in tegra_devfreq_probe()
837 err = devm_request_threaded_irq(&pdev->dev, tegra->irq, NULL, in tegra_devfreq_probe()
839 "tegra-devfreq", tegra); in tegra_devfreq_probe()
841 dev_err(&pdev->dev, "Interrupt request failed: %d\n", err); in tegra_devfreq_probe()
845 tegra->opp_table = dev_pm_opp_set_supported_hw(&pdev->dev, in tegra_devfreq_probe()
847 err = PTR_ERR_OR_ZERO(tegra->opp_table); in tegra_devfreq_probe()
849 dev_err(&pdev->dev, "Failed to set supported HW: %d\n", err); in tegra_devfreq_probe()
853 err = dev_pm_opp_of_add_table_noclk(&pdev->dev, 0); in tegra_devfreq_probe()
855 dev_err(&pdev->dev, "Failed to add OPP table: %d\n", err); in tegra_devfreq_probe()
859 err = clk_prepare_enable(tegra->clock); in tegra_devfreq_probe()
861 dev_err(&pdev->dev, in tegra_devfreq_probe()
866 err = reset_control_reset(tegra->reset); in tegra_devfreq_probe()
868 dev_err(&pdev->dev, "Failed to reset hardware: %d\n", err); in tegra_devfreq_probe()
872 rate = clk_round_rate(tegra->emc_clock, ULONG_MAX); in tegra_devfreq_probe()
874 dev_err(&pdev->dev, "Failed to round clock rate: %ld\n", rate); in tegra_devfreq_probe()
879 tegra->max_freq = rate / KHZ; in tegra_devfreq_probe()
881 for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) { in tegra_devfreq_probe()
882 dev = tegra->devices + i; in tegra_devfreq_probe()
883 dev->config = tegra->soc->configs + i; in tegra_devfreq_probe()
884 dev->regs = tegra->regs + dev->config->offset; in tegra_devfreq_probe()
889 tegra->clk_rate_change_nb.notifier_call = tegra_actmon_clk_notify_cb; in tegra_devfreq_probe()
890 tegra->cpu_rate_change_nb.notifier_call = tegra_actmon_cpu_notify_cb; in tegra_devfreq_probe()
892 INIT_DELAYED_WORK(&tegra->cpufreq_update_work, in tegra_devfreq_probe()
897 dev_err(&pdev->dev, "Failed to add governor: %d\n", err); in tegra_devfreq_probe()
901 tegra_devfreq_profile.initial_freq = clk_get_rate(tegra->emc_clock); in tegra_devfreq_probe()
903 devfreq = devfreq_add_device(&pdev->dev, &tegra_devfreq_profile, in tegra_devfreq_probe()
916 dev_pm_opp_remove_all_dynamic(&pdev->dev); in tegra_devfreq_probe()
918 reset_control_reset(tegra->reset); in tegra_devfreq_probe()
920 clk_disable_unprepare(tegra->clock); in tegra_devfreq_probe()
922 dev_pm_opp_of_remove_table(&pdev->dev); in tegra_devfreq_probe()
924 dev_pm_opp_put_supported_hw(tegra->opp_table); in tegra_devfreq_probe()
933 devfreq_remove_device(tegra->devfreq); in tegra_devfreq_remove()
936 reset_control_reset(tegra->reset); in tegra_devfreq_remove()
937 clk_disable_unprepare(tegra->clock); in tegra_devfreq_remove()
939 dev_pm_opp_of_remove_table(&pdev->dev); in tegra_devfreq_remove()
940 dev_pm_opp_put_supported_hw(tegra->opp_table); in tegra_devfreq_remove()
950 * and each transaction takes 4 EMC clocks.
961 { .compatible = "nvidia,tegra30-actmon", .data = &tegra30_soc, },
962 { .compatible = "nvidia,tegra124-actmon", .data = &tegra124_soc, },
972 .name = "tegra-devfreq",