23.nanopi t2 s5p4418超頻

修復nanopi t2 cpu調頻不起作用
nanopi t2 s5p4418超頻

驅動相關文件

內核版本:linux-3.4.y
相關代碼:
drivers/cpufreq/nxp-cpufreq.c 驅動主邏輯
drivers/cpufreq/s5p4418-cpufreq.c 驅動預設配置
arch/plat-s5p4418/nanopi2/device.c 自定義配置

頻率電壓表

有兩個配置相應的就會有兩個頻率電壓表
drivers/cpufreq/s5p4418-cpufreq.c

#define	ASB_FREQ_MHZ {	\
	[ 0] = 1600,	\
	[ 1] = 1500,	\
	[ 2] = 1400,	\
	[ 3] = 1300,	\
	[ 4] = 1200,	\
	[ 5] = 1100,	\
	[ 6] = 1000,	\
	[ 7] =  900,	\
	[ 8] =  800,	\
	[ 9] =  700,	\
	[10] =  600,	\
	[11] =  500,	\
	[12] =  400,	\
	}

static struct asv_tb_info asv_tables[] = {
	[0] = {	.ids = 10, .ro = 110,
			.Mhz = ASB_FREQ_MHZ,
			.uV  = { UV(1350), UV(1350),	/* OVER FREQ */
					 UV(1350), UV(1300), UV(1250), UV(1200), UV(1175), UV(1150),
					 UV(1125), UV(1100), UV(1075), UV(1075), UV(1075) },
	},
	[1] = {	.ids = 15, .ro = 130,
			.Mhz = ASB_FREQ_MHZ,
			.uV  = { UV(1300), UV(1300),	/* OVER FREQ */
				     UV(1300), UV(1250), UV(1200), UV(1150), UV(1125), UV(1100),
					 UV(1075), UV(1050), UV(1025), UV(1025), UV(1025) },
	},
	[2] = {	.ids = 20, .ro = 140,
			.Mhz = ASB_FREQ_MHZ,
			.uV  = { UV(1250), UV(1250),	/* OVER FREQ */
					 UV(1250), UV(1200), UV(1150), UV(1100), UV(1075), UV(1050),
					 UV(1025), UV(1000), UV(1000), UV(1000), UV(1000) },
	},
	[3] = {	.ids = 50, .ro = 170,
			.Mhz = ASB_FREQ_MHZ,
			.uV  = { UV(1200), UV(1200),	/* OVER FREQ */
					 UV(1200), UV(1150), UV(1100), UV(1050), UV(1025), UV(1000),
					 UV(1000), UV(1000), UV(1000), UV(1000), UV(1000) },
	},
	[4] = {	.ids = 50, .ro = 170,
			.Mhz = ASB_FREQ_MHZ,
			.uV  = { UV(1175), UV(1175),	/* OVER FREQ */
					 UV(1175), UV(1100), UV(1050), UV(1000), UV(1000), UV(1000),
					 UV(1000), UV(1000), UV(1000), UV(1000), UV(1000) },
	},
};
#define	ASV_ARRAY_SIZE	ARRAY_SIZE(asv_tables)

驅動預設值裏面已經由1500Mhz以及1600Mhz的頻率電壓配置了,可以參考這個配置超頻
arch/plat-s5p4418/nanopi2/device.c

#if defined(CONFIG_ARM_NXP_CPUFREQ)
static unsigned long dfs_freq_table[][2] = {
	{ 1400000, 1260000, },
	{ 1200000, 1200000, },
	{ 1000000, 1140000, },
	{  800000, 1100000, },
	{  700000, 1080000, },
	{  600000, 1040000, },
	{  500000, 1040000, },
	{  400000, 1040000, },
};

struct nxp_cpufreq_plat_data dfs_plat_data = {
	.pll_dev		= CONFIG_NXP_CPUFREQ_PLLDEV,
	.supply_name	= "vdd_arm_1.3V",	// refer to CONFIG_REGULATOR_NXE2000
	.freq_table		= dfs_freq_table,
	.table_size		= ARRAY_SIZE(dfs_freq_table),
	.max_cpufreq	= 1400*1000,
	.max_retention	=   10*1000,
	.rest_cpufreq	=  800*1000,
	.rest_retention	=    2*1000,
	.fixed_voltage	= 1280*1000,
};

可以看到頻率表定義最高只到了1400Mhz,下面吧它超到1600Mhz

頻率表加載邏輯

頻率表加載在nxp_cpufreq_make_table函數完成

static void *nxp_cpufreq_make_table(struct platform_device *pdev,
							int *table_size, unsigned long (*dvfs_tables)[2])
{
	struct nxp_cpufreq_plat_data *pdata = pdev->dev.platform_data;
	struct cpufreq_frequency_table *freq_table;
	struct cpufreq_asv_ops *ops = &asv_ops;
	unsigned long (*plat_tbs)[2] = NULL;
	unsigned long plat_n_voltage = 0;
 	int tb_size, asv_size = 0;
	int id = 0, n = 0;

	/* user defined dvfs */
	if (pdata->freq_table && pdata->table_size)
		plat_tbs = (unsigned long(*)[2])pdata->freq_table;

	/* asv dvfs tables */
	if (ops->setup_table)
		asv_size = ops->setup_table(dvfs_tables);

	if (!pdata->table_size && !asv_size) {
		dev_err(&pdev->dev, "failed no freq table !!!\n");
		return NULL;
	}

	tb_size = (pdata->table_size ? pdata->table_size : asv_size);

	/* alloc with end table */
	freq_table = kzalloc((sizeof(*freq_table) * (tb_size + 1)), GFP_KERNEL);
	if (!freq_table) {
		dev_err(&pdev->dev, "failed allocate freq table !!!\n");
		return NULL;
	}

	/* make frequency table with platform data */
	if (asv_size > 0) {
		for (n = 0, id = 0; tb_size > id && asv_size > n; n++) {
			if (plat_tbs && plat_tbs[id][1] > 0)
				plat_n_voltage = plat_tbs[id][1];

			if (plat_n_voltage) {
				dvfs_tables[id][0] = plat_tbs[id][0];	/* frequency */
				dvfs_tables[id][1] = plat_n_voltage;	/* voltage */

			} else if (plat_tbs) {
				for (n = 0; asv_size > n; n++) {
					if (plat_tbs[id][0] == dvfs_tables[n][0]) {
						dvfs_tables[id][0] = dvfs_tables[n][0];	/* frequency */
						dvfs_tables[id][1] = dvfs_tables[n][1];	/* voltage */
						break;
					}
				}
			} else {
				if (dvfs_tables[n][0] > FREQ_MAX_FREQ_KHZ)
					continue;
				dvfs_tables[id][0] = dvfs_tables[n][0];	/* frequency */
				dvfs_tables[id][1] = dvfs_tables[n][1];	/* voltage */
			}
			freq_table[id].index = id;
			freq_table[id].frequency = dvfs_tables[id][0];
			printk(KERN_DEBUG "ASV %2d = %8ld khz, %4ld mV\n", id,
					dvfs_tables[id][0], dvfs_tables[id][1]/1000);
			/* next */
			id++;
		}
	} else {
		for (id = 0; tb_size > id; id++) {
			dvfs_tables[id][0] = plat_tbs[id][0];	/* frequency */
			dvfs_tables[id][1] = plat_tbs[id][1];	/* voltage */
			freq_table[id].index = id;
			freq_table[id].frequency = dvfs_tables[id][0];
			printk("DTB %2d = %8ldkhz, %8ld uV \n", id, dvfs_tables[id][0], dvfs_tables[id][1]);
		}
	}

	/* End table */
	freq_table[id].index = id;
	freq_table[id].frequency = CPUFREQ_TABLE_END;

	*table_size = id;

	return (void*)freq_table;
}

pdevarch/plat-s5p4418/nanopi2/device.c 頻率電壓表配置
dvfs_tablesdrivers/cpufreq/s5p4418-cpufreq.c頻率電壓表配置
可以看到pdev的優先級更高,所以參考驅動預設值修改arch/plat-s5p4418/nanopi2/device.c即可

在這裏插入圖片描述
添加頻率表加到1600Mhz,最大頻率也改成1600Mhz,不是使用電池,電壓就不吝嗇了,直接上到最高1.35V,穩定超頻

效果

[root@minicoco ~]# cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_fr
equencies 
1600000 1500000 1400000 1200000 1000000 800000 700000 600000 500000 400000 
[root@minicoco ~]# 

成功,收工

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章