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 ~]# 

成功,收工

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值