Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * NVIDIA Tegra20 devfreq driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2019 GRATE-DRIVER project
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/devfreq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/pm_opp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <soc/tegra/mc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include "governor.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define MC_STAT_CONTROL				0x90
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define MC_STAT_EMC_CLOCK_LIMIT			0xa0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define MC_STAT_EMC_CLOCKS			0xa4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define MC_STAT_EMC_CONTROL			0xa8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define MC_STAT_EMC_COUNT			0xb8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define EMC_GATHER_CLEAR			(1 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define EMC_GATHER_ENABLE			(3 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) struct tegra_devfreq {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	struct devfreq *devfreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	struct clk *emc_clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	void __iomem *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) static int tegra_devfreq_target(struct device *dev, unsigned long *freq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 				u32 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	struct tegra_devfreq *tegra = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	struct devfreq *devfreq = tegra->devfreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	struct dev_pm_opp *opp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	unsigned long rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	opp = devfreq_recommended_opp(dev, freq, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	if (IS_ERR(opp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		return PTR_ERR(opp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	rate = dev_pm_opp_get_freq(opp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	dev_pm_opp_put(opp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	err = clk_set_min_rate(tegra->emc_clock, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	err = clk_set_rate(tegra->emc_clock, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		goto restore_min_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) restore_min_rate:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	clk_set_min_rate(tegra->emc_clock, devfreq->previous_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) static int tegra_devfreq_get_dev_status(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 					struct devfreq_dev_status *stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	struct tegra_devfreq *tegra = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	 * EMC_COUNT returns number of memory events, that number is lower
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	 * than the number of clocks. Conversion ratio of 1/8 results in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	 * bit higher bandwidth than actually needed, it is good enough for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	 * the time being because drivers don't support requesting minimum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	 * needed memory bandwidth yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	 * TODO: adjust the ratio value once relevant drivers will support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	 * memory bandwidth management.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	stat->busy_time = readl_relaxed(tegra->regs + MC_STAT_EMC_COUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	stat->total_time = readl_relaxed(tegra->regs + MC_STAT_EMC_CLOCKS) / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	stat->current_frequency = clk_get_rate(tegra->emc_clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	writel_relaxed(EMC_GATHER_CLEAR, tegra->regs + MC_STAT_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	writel_relaxed(EMC_GATHER_ENABLE, tegra->regs + MC_STAT_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) static struct devfreq_dev_profile tegra_devfreq_profile = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	.polling_ms	= 500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	.target		= tegra_devfreq_target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	.get_dev_status	= tegra_devfreq_get_dev_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static struct tegra_mc *tegra_get_memory_controller(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	struct tegra_mc *mc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	np = of_find_compatible_node(NULL, NULL, "nvidia,tegra20-mc-gart");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		return ERR_PTR(-ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	pdev = of_find_device_by_node(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	if (!pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	mc = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	if (!mc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		return ERR_PTR(-EPROBE_DEFER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	return mc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static int tegra_devfreq_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	struct tegra_devfreq *tegra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	struct tegra_mc *mc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	unsigned long max_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	unsigned long rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	mc = tegra_get_memory_controller();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	if (IS_ERR(mc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		err = PTR_ERR(mc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		dev_err(&pdev->dev, "failed to get memory controller: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 			err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	if (!tegra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	/* EMC is a system-critical clock that is always enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	tegra->emc_clock = devm_clk_get(&pdev->dev, "emc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	if (IS_ERR(tegra->emc_clock)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		err = PTR_ERR(tegra->emc_clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		dev_err(&pdev->dev, "failed to get emc clock: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	tegra->regs = mc->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	max_rate = clk_round_rate(tegra->emc_clock, ULONG_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	for (rate = 0; rate <= max_rate; rate++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		rate = clk_round_rate(tegra->emc_clock, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		err = dev_pm_opp_add(&pdev->dev, rate, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 			dev_err(&pdev->dev, "failed to add opp: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 			goto remove_opps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	 * Reset statistic gathers state, select global bandwidth for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	 * statistics collection mode and set clocks counter saturation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	 * limit to maximum.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	writel_relaxed(0x00000000, tegra->regs + MC_STAT_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	writel_relaxed(0x00000000, tegra->regs + MC_STAT_EMC_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	writel_relaxed(0xffffffff, tegra->regs + MC_STAT_EMC_CLOCK_LIMIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	platform_set_drvdata(pdev, tegra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	tegra->devfreq = devfreq_add_device(&pdev->dev, &tegra_devfreq_profile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 					    DEVFREQ_GOV_SIMPLE_ONDEMAND, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	if (IS_ERR(tegra->devfreq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		err = PTR_ERR(tegra->devfreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		goto remove_opps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) remove_opps:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	dev_pm_opp_remove_all_dynamic(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static int tegra_devfreq_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	struct tegra_devfreq *tegra = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	devfreq_remove_device(tegra->devfreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	dev_pm_opp_remove_all_dynamic(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static struct platform_driver tegra_devfreq_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	.probe		= tegra_devfreq_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	.remove		= tegra_devfreq_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	.driver		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		.name	= "tegra20-devfreq",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) module_platform_driver(tegra_devfreq_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) MODULE_ALIAS("platform:tegra20-devfreq");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) MODULE_AUTHOR("Dmitry Osipenko <digetx@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) MODULE_DESCRIPTION("NVIDIA Tegra20 devfreq driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) MODULE_LICENSE("GPL v2");