Lines Matching full:tegra
3 * A devfreq driver for NVIDIA Tegra SoCs
24 #include <soc/tegra/fuse.h>
218 static u32 actmon_readl(struct tegra_devfreq *tegra, u32 offset) in actmon_readl() argument
220 return readl_relaxed(tegra->regs + offset); in actmon_readl()
223 static void actmon_writel(struct tegra_devfreq *tegra, u32 val, u32 offset) in actmon_writel() argument
225 writel_relaxed(val, tegra->regs + offset); in actmon_writel()
251 static void tegra_devfreq_update_avg_wmark(struct tegra_devfreq *tegra, in tegra_devfreq_update_avg_wmark() argument
254 u32 avg_band_freq = tegra->max_freq * ACTMON_DEFAULT_AVG_BAND / KHZ; in tegra_devfreq_update_avg_wmark()
255 u32 band = avg_band_freq * tegra->devfreq->profile->polling_ms; in tegra_devfreq_update_avg_wmark()
265 static void tegra_devfreq_update_wmark(struct tegra_devfreq *tegra, in tegra_devfreq_update_wmark() argument
268 u32 val = tegra->cur_freq * tegra->devfreq->profile->polling_ms; in tegra_devfreq_update_wmark()
277 static void actmon_isr_device(struct tegra_devfreq *tegra, in actmon_isr_device() argument
283 tegra_devfreq_update_avg_wmark(tegra, dev); in actmon_isr_device()
298 if (dev->boost_freq >= tegra->max_freq) { in actmon_isr_device()
300 dev->boost_freq = tegra->max_freq; in actmon_isr_device()
323 static unsigned long actmon_cpu_to_emc_rate(struct tegra_devfreq *tegra, in actmon_cpu_to_emc_rate() argument
331 return min(ratio->emc_freq, tegra->max_freq); in actmon_cpu_to_emc_rate()
336 static unsigned long actmon_device_target_freq(struct tegra_devfreq *tegra, in actmon_device_target_freq() argument
342 target_freq = dev->avg_count / tegra->devfreq->profile->polling_ms; in actmon_device_target_freq()
349 static void actmon_update_target(struct tegra_devfreq *tegra, in actmon_update_target() argument
355 dev->target_freq = actmon_device_target_freq(tegra, dev); in actmon_update_target()
360 static_cpu_emc_freq = actmon_cpu_to_emc_rate(tegra, cpu_freq); in actmon_update_target()
371 struct tegra_devfreq *tegra = data; in actmon_thread_isr() local
376 mutex_lock(&tegra->devfreq->lock); in actmon_thread_isr()
378 val = actmon_readl(tegra, ACTMON_GLB_STATUS); in actmon_thread_isr()
379 for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) { in actmon_thread_isr()
380 if (val & tegra->devices[i].config->irq_mask) { in actmon_thread_isr()
381 actmon_isr_device(tegra, tegra->devices + i); in actmon_thread_isr()
387 update_devfreq(tegra->devfreq); in actmon_thread_isr()
389 mutex_unlock(&tegra->devfreq->lock); in actmon_thread_isr()
398 struct tegra_devfreq *tegra; in tegra_actmon_clk_notify_cb() local
405 tegra = container_of(nb, struct tegra_devfreq, clk_rate_change_nb); in tegra_actmon_clk_notify_cb()
407 tegra->cur_freq = data->new_rate / KHZ; in tegra_actmon_clk_notify_cb()
409 for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) { in tegra_actmon_clk_notify_cb()
410 dev = &tegra->devices[i]; in tegra_actmon_clk_notify_cb()
412 tegra_devfreq_update_wmark(tegra, dev); in tegra_actmon_clk_notify_cb()
420 struct tegra_devfreq *tegra = container_of(work, struct tegra_devfreq, in tegra_actmon_delayed_update() local
423 mutex_lock(&tegra->devfreq->lock); in tegra_actmon_delayed_update()
424 update_devfreq(tegra->devfreq); in tegra_actmon_delayed_update()
425 mutex_unlock(&tegra->devfreq->lock); in tegra_actmon_delayed_update()
429 tegra_actmon_cpufreq_contribution(struct tegra_devfreq *tegra, in tegra_actmon_cpufreq_contribution() argument
432 struct tegra_devfreq_device *actmon_dev = &tegra->devices[MCCPU]; in tegra_actmon_cpufreq_contribution()
435 dev_freq = actmon_device_target_freq(tegra, actmon_dev); in tegra_actmon_cpufreq_contribution()
441 static_cpu_emc_freq = actmon_cpu_to_emc_rate(tegra, cpu_freq); in tegra_actmon_cpufreq_contribution()
453 struct tegra_devfreq *tegra; in tegra_actmon_cpu_notify_cb() local
459 tegra = container_of(nb, struct tegra_devfreq, cpu_rate_change_nb); in tegra_actmon_cpu_notify_cb()
465 if (mutex_trylock(&tegra->devfreq->lock)) { in tegra_actmon_cpu_notify_cb()
466 old = tegra_actmon_cpufreq_contribution(tegra, freqs->old); in tegra_actmon_cpu_notify_cb()
467 new = tegra_actmon_cpufreq_contribution(tegra, freqs->new); in tegra_actmon_cpu_notify_cb()
468 mutex_unlock(&tegra->devfreq->lock); in tegra_actmon_cpu_notify_cb()
487 schedule_delayed_work(&tegra->cpufreq_update_work, delay); in tegra_actmon_cpu_notify_cb()
492 static void tegra_actmon_configure_device(struct tegra_devfreq *tegra, in tegra_actmon_configure_device() argument
500 dev->target_freq = tegra->cur_freq; in tegra_actmon_configure_device()
502 dev->avg_count = tegra->cur_freq * tegra->devfreq->profile->polling_ms; in tegra_actmon_configure_device()
505 tegra_devfreq_update_avg_wmark(tegra, dev); in tegra_actmon_configure_device()
506 tegra_devfreq_update_wmark(tegra, dev); in tegra_actmon_configure_device()
508 device_writel(dev, tegra->soc->count_weight, ACTMON_DEV_COUNT_WEIGHT); in tegra_actmon_configure_device()
526 static void tegra_actmon_stop_devices(struct tegra_devfreq *tegra) in tegra_actmon_stop_devices() argument
528 struct tegra_devfreq_device *dev = tegra->devices; in tegra_actmon_stop_devices()
531 for (i = 0; i < ARRAY_SIZE(tegra->devices); i++, dev++) { in tegra_actmon_stop_devices()
538 static int tegra_actmon_resume(struct tegra_devfreq *tegra) in tegra_actmon_resume() argument
543 if (!tegra->devfreq->profile->polling_ms || !tegra->started) in tegra_actmon_resume()
546 actmon_writel(tegra, tegra->devfreq->profile->polling_ms - 1, in tegra_actmon_resume()
554 err = clk_notifier_register(tegra->emc_clock, in tegra_actmon_resume()
555 &tegra->clk_rate_change_nb); in tegra_actmon_resume()
557 dev_err(tegra->devfreq->dev.parent, in tegra_actmon_resume()
562 tegra->cur_freq = clk_get_rate(tegra->emc_clock) / KHZ; in tegra_actmon_resume()
564 for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) in tegra_actmon_resume()
565 tegra_actmon_configure_device(tegra, &tegra->devices[i]); in tegra_actmon_resume()
574 err = cpufreq_register_notifier(&tegra->cpu_rate_change_nb, in tegra_actmon_resume()
577 dev_err(tegra->devfreq->dev.parent, in tegra_actmon_resume()
582 enable_irq(tegra->irq); in tegra_actmon_resume()
587 tegra_actmon_stop_devices(tegra); in tegra_actmon_resume()
589 clk_notifier_unregister(tegra->emc_clock, &tegra->clk_rate_change_nb); in tegra_actmon_resume()
594 static int tegra_actmon_start(struct tegra_devfreq *tegra) in tegra_actmon_start() argument
598 if (!tegra->started) { in tegra_actmon_start()
599 tegra->started = true; in tegra_actmon_start()
601 ret = tegra_actmon_resume(tegra); in tegra_actmon_start()
603 tegra->started = false; in tegra_actmon_start()
609 static void tegra_actmon_pause(struct tegra_devfreq *tegra) in tegra_actmon_pause() argument
611 if (!tegra->devfreq->profile->polling_ms || !tegra->started) in tegra_actmon_pause()
614 disable_irq(tegra->irq); in tegra_actmon_pause()
616 cpufreq_unregister_notifier(&tegra->cpu_rate_change_nb, in tegra_actmon_pause()
619 cancel_delayed_work_sync(&tegra->cpufreq_update_work); in tegra_actmon_pause()
621 tegra_actmon_stop_devices(tegra); in tegra_actmon_pause()
623 clk_notifier_unregister(tegra->emc_clock, &tegra->clk_rate_change_nb); in tegra_actmon_pause()
626 static void tegra_actmon_stop(struct tegra_devfreq *tegra) in tegra_actmon_stop() argument
628 tegra_actmon_pause(tegra); in tegra_actmon_stop()
629 tegra->started = false; in tegra_actmon_stop()
653 struct tegra_devfreq *tegra = dev_get_drvdata(dev); in tegra_devfreq_get_dev_status() local
657 cur_freq = READ_ONCE(tegra->cur_freq); in tegra_devfreq_get_dev_status()
659 /* To be used by the tegra governor */ in tegra_devfreq_get_dev_status()
660 stat->private_data = tegra; in tegra_devfreq_get_dev_status()
665 actmon_dev = &tegra->devices[MCALL]; in tegra_devfreq_get_dev_status()
674 stat->total_time = tegra->devfreq->profile->polling_ms * cur_freq; in tegra_devfreq_get_dev_status()
692 struct tegra_devfreq *tegra; in tegra_governor_get_target() local
704 tegra = stat->private_data; in tegra_governor_get_target()
706 for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) { in tegra_governor_get_target()
707 dev = &tegra->devices[i]; in tegra_governor_get_target()
709 actmon_update_target(tegra, dev); in tegra_governor_get_target()
715 * tegra-devfreq driver operates with KHz units, while OPP table in tegra_governor_get_target()
727 struct tegra_devfreq *tegra = dev_get_drvdata(devfreq->dev.parent); in tegra_governor_event_handler() local
735 tegra->devfreq = devfreq; in tegra_governor_event_handler()
740 ret = tegra_actmon_start(tegra); in tegra_governor_event_handler()
744 tegra_actmon_stop(tegra); in tegra_governor_event_handler()
758 tegra_actmon_pause(tegra); in tegra_governor_event_handler()
760 ret = tegra_actmon_resume(tegra); in tegra_governor_event_handler()
764 tegra_actmon_stop(tegra); in tegra_governor_event_handler()
770 ret = tegra_actmon_start(tegra); in tegra_governor_event_handler()
788 struct tegra_devfreq *tegra = data; in devm_tegra_devfreq_deinit_hw() local
790 reset_control_reset(tegra->reset); in devm_tegra_devfreq_deinit_hw()
791 clk_disable_unprepare(tegra->clock); in devm_tegra_devfreq_deinit_hw()
795 struct tegra_devfreq *tegra) in devm_tegra_devfreq_init_hw() argument
799 err = clk_prepare_enable(tegra->clock); in devm_tegra_devfreq_init_hw()
806 tegra); in devm_tegra_devfreq_init_hw()
810 err = reset_control_reset(tegra->reset); in devm_tegra_devfreq_init_hw()
832 struct tegra_devfreq *tegra; in tegra_devfreq_probe() local
845 tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL); in tegra_devfreq_probe()
846 if (!tegra) in tegra_devfreq_probe()
849 tegra->soc = of_device_get_match_data(&pdev->dev); in tegra_devfreq_probe()
851 tegra->regs = devm_platform_ioremap_resource(pdev, 0); in tegra_devfreq_probe()
852 if (IS_ERR(tegra->regs)) in tegra_devfreq_probe()
853 return PTR_ERR(tegra->regs); in tegra_devfreq_probe()
855 tegra->reset = devm_reset_control_get(&pdev->dev, "actmon"); in tegra_devfreq_probe()
856 if (IS_ERR(tegra->reset)) { in tegra_devfreq_probe()
858 return PTR_ERR(tegra->reset); in tegra_devfreq_probe()
861 tegra->clock = devm_clk_get(&pdev->dev, "actmon"); in tegra_devfreq_probe()
862 if (IS_ERR(tegra->clock)) { in tegra_devfreq_probe()
864 return PTR_ERR(tegra->clock); in tegra_devfreq_probe()
867 tegra->emc_clock = devm_clk_get(&pdev->dev, "emc"); in tegra_devfreq_probe()
868 if (IS_ERR(tegra->emc_clock)) in tegra_devfreq_probe()
869 return dev_err_probe(&pdev->dev, PTR_ERR(tegra->emc_clock), in tegra_devfreq_probe()
876 tegra->irq = err; in tegra_devfreq_probe()
878 irq_set_status_flags(tegra->irq, IRQ_NOAUTOEN); in tegra_devfreq_probe()
880 err = devm_request_threaded_irq(&pdev->dev, tegra->irq, NULL, in tegra_devfreq_probe()
882 "tegra-devfreq", tegra); in tegra_devfreq_probe()
900 err = devm_tegra_devfreq_init_hw(&pdev->dev, tegra); in tegra_devfreq_probe()
904 rate = clk_round_rate(tegra->emc_clock, ULONG_MAX); in tegra_devfreq_probe()
910 tegra->max_freq = rate / KHZ; in tegra_devfreq_probe()
912 for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) { in tegra_devfreq_probe()
913 dev = tegra->devices + i; in tegra_devfreq_probe()
914 dev->config = tegra->soc->configs + i; in tegra_devfreq_probe()
915 dev->regs = tegra->regs + dev->config->offset; in tegra_devfreq_probe()
918 platform_set_drvdata(pdev, tegra); in tegra_devfreq_probe()
920 tegra->clk_rate_change_nb.notifier_call = tegra_actmon_clk_notify_cb; in tegra_devfreq_probe()
921 tegra->cpu_rate_change_nb.notifier_call = tegra_actmon_cpu_notify_cb; in tegra_devfreq_probe()
923 INIT_DELAYED_WORK(&tegra->cpufreq_update_work, in tegra_devfreq_probe()
932 tegra_devfreq_profile.initial_freq = clk_get_rate(tegra->emc_clock); in tegra_devfreq_probe()
970 .name = "tegra-devfreq",
977 MODULE_DESCRIPTION("Tegra devfreq driver");