1673 lines
44 KiB
C
1673 lines
44 KiB
C
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
|
|
/*
|
|
* common/cmd_cpu_temp.c
|
|
*
|
|
* Copyright (C) 2020 Amlogic, Inc. All rights reserved.
|
|
*
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <asm/io.h>
|
|
#include <asm/arch/efuse.h>
|
|
#include <command.h>
|
|
#include <asm/arch/secure_apb.h>
|
|
#include <asm/arch/mailbox.h>
|
|
#include <asm/arch/thermal.h>
|
|
#include <asm/cpu_id.h>
|
|
#include <asm/arch/bl31_apis.h>
|
|
#include <linux/arm-smccc.h>
|
|
|
|
#ifdef CONFIG_AML_MESON_TXHD
|
|
#define NEW_THERMAL_MODE 1
|
|
#endif
|
|
|
|
#ifdef CONFIG_AML_MESON_G12A
|
|
#define R1P1_TSENSOR_MODE 1
|
|
#endif
|
|
|
|
//#define HHI_SAR_CLK_CNTL 0xc883c000+0xf6*4 //0xc883c3d8
|
|
int temp_base = 27;
|
|
#define NUM 16 /*for trim sensor*/
|
|
#define READ_NUM 2 /*for read sensor*/
|
|
uint32_t vref_en = 0;
|
|
uint32_t trim = 0;
|
|
int saradc_vref = -1;
|
|
|
|
#define MANUAL_POWER 1 //not use vref, use 1.8V power
|
|
|
|
int r1p1_read_entry(void);
|
|
int r1p1_trim_entry(int tempbase, int tempver);
|
|
|
|
static int get_tsc(int temp)
|
|
{
|
|
int vmeasure, TS_C;
|
|
switch (get_cpu_id().family_id) {
|
|
case MESON_CPU_MAJOR_ID_GXBB:
|
|
case MESON_CPU_MAJOR_ID_GXTVBB:
|
|
/*TS_C = (adc-435)/8.25+16*/
|
|
vmeasure = temp - (435 + (temp_base - 27) * 3.4);
|
|
printf("vmeasure=%d\n", vmeasure);
|
|
TS_C = ((vmeasure) / 8.25) + 16;
|
|
break;
|
|
case MESON_CPU_MAJOR_ID_GXL:
|
|
case MESON_CPU_MAJOR_ID_GXM:
|
|
case MESON_CPU_MAJOR_ID_GXLX:
|
|
if (vref_en) {
|
|
/*TS_C = 16-(adc-1655)/37.6*/
|
|
vmeasure = temp - (1655 + (temp_base - 27) * 15.3);
|
|
printf("vmeasure=%d\n", vmeasure);
|
|
TS_C = 16 - ((vmeasure) / 37.6);
|
|
break;
|
|
} else {
|
|
/*TS_C = 16-(adc-1778)/42*/
|
|
vmeasure = temp - (1778 + (temp_base - 27) * 17);
|
|
printf("vmeasure=%d\n", vmeasure);
|
|
TS_C = 16 - ((vmeasure) / 42);
|
|
break;
|
|
}
|
|
case MESON_CPU_MAJOR_ID_TXL:
|
|
/*TS_C = 16-(adc-1530)/40*/
|
|
vmeasure = temp - (1530 + (temp_base - 27) * 15.5);
|
|
printf("vmeasure=%d\n", vmeasure);
|
|
TS_C = 16-((vmeasure)/40);
|
|
break;
|
|
case MESON_CPU_MAJOR_ID_TXLX:
|
|
case MESON_CPU_MAJOR_ID_AXG:
|
|
case MESON_CPU_MAJOR_ID_TXHD:
|
|
/*TS_C = 16-(adc-1750)/42*/
|
|
vmeasure = temp - (1750 + (temp_base - 27) * 17);
|
|
printf("vmeasure=%d\n", vmeasure);
|
|
TS_C = 16 - ((vmeasure) / 42);
|
|
break;
|
|
default:
|
|
printf("cpu family id not support!!!\n");
|
|
return -1;
|
|
}
|
|
|
|
if (TS_C > 31)
|
|
TS_C = 31;
|
|
else if (TS_C < 0)
|
|
TS_C = 0;
|
|
printf("TS_C=%d\n", TS_C);
|
|
return TS_C;
|
|
}
|
|
|
|
static int adc_init_chan6(void)
|
|
{
|
|
#ifdef MANUAL_POWER
|
|
int ver = (readl(SEC_AO_SEC_SD_CFG12) >> 24) & 0xff;
|
|
#endif
|
|
switch (get_cpu_id().family_id) {
|
|
case MESON_CPU_MAJOR_ID_GXBB:
|
|
case MESON_CPU_MAJOR_ID_GXTVBB:
|
|
writel(0x002c2000, SAR_ADC_REG11);/*bit20: test mode disabled*/
|
|
writel(0x00000006, SAR_ADC_CHAN_LIST);
|
|
writel(0x00003000, SAR_ADC_AVG_CNTL);
|
|
writel(0xc3a8500a, SAR_ADC_REG3);
|
|
writel(0x010a000a, SAR_ADC_DELAY);
|
|
writel(0x03eb1a0c, SAR_ADC_AUX_SW);
|
|
writel(0x008c000c, SAR_ADC_CHAN_10_SW);
|
|
writel(0x030e030c, SAR_ADC_DETECT_IDLE_SW);
|
|
writel(0x0c00c400, SAR_ADC_DELTA_10);
|
|
writel(0x00000114, SAR_CLK_CNTL); /* Clock */
|
|
writel(readl(0xc110868c) | (0x1 << 28), SAR_ADC_REG3);
|
|
break;
|
|
case MESON_CPU_MAJOR_ID_GXL:
|
|
case MESON_CPU_MAJOR_ID_GXM:
|
|
case MESON_CPU_MAJOR_ID_GXLX:
|
|
writel(0x002c2060, SAR_ADC_REG11);/*bit20 disabled*/
|
|
writel(0x00000006, SAR_ADC_CHAN_LIST);/*channel 6*/
|
|
writel(0x00003000, SAR_ADC_AVG_CNTL);
|
|
writel(0xc8a8500a, SAR_ADC_REG3);/*bit27:0*/
|
|
writel(0x010a000a, SAR_ADC_DELAY);
|
|
writel(0x03eb1a0c, SAR_ADC_AUX_SW);
|
|
writel(0x008c000c, SAR_ADC_CHAN_10_SW);
|
|
writel(0x030e030c, SAR_ADC_DETECT_IDLE_SW);
|
|
writel(0x0c00c400, SAR_ADC_DELTA_10);
|
|
writel(0x00000114, SAR_CLK_CNTL);/*Clock*/
|
|
break;
|
|
case MESON_CPU_MAJOR_ID_TXL:
|
|
writel(0x00000006, SAR_ADC_CHAN_LIST);/*channel 6*/
|
|
writel(0x00003000, SAR_ADC_AVG_CNTL);
|
|
writel(0xc8a8500a, SAR_ADC_REG3);/*bit27:1 disable*/
|
|
writel(0x010a000a, SAR_ADC_DELAY);
|
|
writel(0x03eb1a0c, SAR_ADC_AUX_SW);
|
|
writel(0x008c000c, SAR_ADC_CHAN_10_SW);
|
|
writel(0x030e030c, SAR_ADC_DETECT_IDLE_SW);
|
|
writel(0x0c00c400, SAR_ADC_DELTA_10);
|
|
writel(0x00000110, SAR_CLK_CNTL);/*Clock*/
|
|
writel(0x002c2060, SAR_ADC_REG11);/*bit20 disabled*/
|
|
break;
|
|
case MESON_CPU_MAJOR_ID_TXLX:
|
|
writel(0x00000006, SAR_ADC_CHAN_LIST);/*channel 6*/
|
|
writel(0x00003000, SAR_ADC_AVG_CNTL);
|
|
writel(0xc8a8500a, SAR_ADC_REG3);/*bit27:1 disable*/
|
|
writel(0x010a000a, SAR_ADC_DELAY);
|
|
writel(0x03eb1a0c, SAR_ADC_AUX_SW);
|
|
writel(0x008c000c, SAR_ADC_CHAN_10_SW);
|
|
writel(0x030e030c, SAR_ADC_DETECT_IDLE_SW);
|
|
writel(0x0c00c400, SAR_ADC_DELTA_10);
|
|
writel(0x00000110, SAR_CLK_CNTL);/*Clock*/
|
|
writel(0x002c2060, SAR_ADC_REG11);/*bit20 disabled*/
|
|
#ifndef MANUAL_POWER
|
|
if (ver != 0xa0)
|
|
#endif
|
|
writel(readl(SAR_ADC_REG11) | 0x1, SAR_ADC_REG11);/*manual trim use 1.8V*/
|
|
break;
|
|
case MESON_CPU_MAJOR_ID_AXG:
|
|
case MESON_CPU_MAJOR_ID_TXHD:
|
|
writel(0x00000006, SAR_ADC_CHAN_LIST);/*channel 6*/
|
|
writel(0x00003000, SAR_ADC_AVG_CNTL);
|
|
writel(0xc8a8500a, SAR_ADC_REG3);/*bit27:1 disable*/
|
|
writel(0x010a000a, SAR_ADC_DELAY);
|
|
writel(0x03eb1a0c, SAR_ADC_AUX_SW);
|
|
writel(0x008c000c, SAR_ADC_CHAN_10_SW);
|
|
writel(0x030e030c, SAR_ADC_DETECT_IDLE_SW);
|
|
writel(0x0c00c400, SAR_ADC_DELTA_10);
|
|
writel(0x00000110, SAR_CLK_CNTL);/*Clock*/
|
|
writel(0x002c2060, SAR_ADC_REG11);/*bit20 disabled*/
|
|
#ifdef MANUAL_POWER
|
|
if (0 == ((ver == 0x9) || (ver == 0xa) || (ver == 0xb)))/*ft trim no use 1.8v*/
|
|
#endif
|
|
writel(readl(SAR_ADC_REG11) | 0x1, SAR_ADC_REG11);/*manual trim use 1.8V*/
|
|
break;
|
|
default:
|
|
printf("cpu family id not support!!!\n");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int get_adc_sample(int chan)
|
|
{
|
|
unsigned value;
|
|
int count = 0;
|
|
|
|
if (!(readl(SAR_CLK_CNTL) & (1 << 8)))/*check and open clk*/
|
|
writel(readl(SAR_CLK_CNTL) | (1 << 8), SAR_CLK_CNTL);
|
|
if (!(readl(SAR_BUS_CLK_EN) & (1 << EN_BIT)))/*check and open clk*/
|
|
writel(readl(SAR_BUS_CLK_EN) | (1 << EN_BIT), HHI_GCLK_MPEG2);
|
|
|
|
/*adc reg4 bit14~15: read adc sample value flag*/
|
|
/*0x21a4: bit14: kernel bit15: bl30*/
|
|
for (; count <= 100; count++) {
|
|
if (count == 100) {
|
|
printf("%s: get flag timeout!\n",__func__);
|
|
return -1;
|
|
}
|
|
|
|
if (!((readl(SAR_ADC_DELAY) >> 14) & 3)) {
|
|
writel(readl(SAR_ADC_DELAY) | (FLAG_BUSY_BL30),
|
|
SAR_ADC_DELAY);
|
|
if (((readl(SAR_ADC_DELAY) >> 14) & 3) != 0x2)
|
|
/*maybe kernel set flag, try again*/
|
|
writel(readl(SAR_ADC_DELAY) & (~(FLAG_BUSY_BL30)),
|
|
SAR_ADC_DELAY);
|
|
else
|
|
break;/*set bl30 read flag ok*/
|
|
} else{/*kernel set flag, clear bl30 flag and wait*/
|
|
writel(readl(SAR_ADC_DELAY) & (~(FLAG_BUSY_BL30)),
|
|
SAR_ADC_DELAY);
|
|
udelay(20);
|
|
}
|
|
}
|
|
#ifndef CONFIG_CHIP_AML_GXB
|
|
/* if thermal VREF(5 bits) is not zero, write it to SAR_ADC_REG13[13:9]
|
|
* and set SAR_ADC_REG13[8]:0, chipid >= GXL
|
|
*/
|
|
if (get_cpu_id().family_id >= MESON_CPU_MAJOR_ID_GXL) {
|
|
saradc_vref = (readl(SAR_ADC_REG13) >> 8) & 0x3f; /*back up SAR_ADC_REG13[13:8]*/
|
|
if ((readl(AO_SEC_SD_CFG12) >> 19) & 0x1f) { /*thermal VREF*/
|
|
writel(((readl(SAR_ADC_REG13)) & (~(0x3f << 8))) /*SAR_ADC_REG13[8]:0*/
|
|
|(((readl(AO_SEC_SD_CFG12) >> 19) & 0x1f) << 9), /*SAR_ADC_REG13[13:9]*/
|
|
SAR_ADC_REG13);
|
|
vref_en = 1;
|
|
} else if ((get_cpu_id().family_id >= MESON_CPU_MAJOR_ID_TXL)&&
|
|
((trim == 1)||
|
|
((((readl(SEC_AO_SEC_SD_CFG12)) >> 24) & 0xff) == 0xc0))) {
|
|
writel(((readl(SAR_ADC_REG13)) & (~(0x3f << 8))) /*SAR_ADC_REG13[13:8]:0*/
|
|
| (0x1e << 8), /*SAR_ADC_REG13[13:8]:[0x1e]*/
|
|
SAR_ADC_REG13);
|
|
} else {
|
|
writel((readl(SAR_ADC_REG13)) & (~(0x3f << 8)), SAR_ADC_REG13);
|
|
}
|
|
}
|
|
#endif
|
|
writel(0x00000006, SAR_ADC_CHAN_LIST);/*channel 6*/
|
|
writel(0xc000c | (0x6 << 23) | (0x6 << 7), SAR_ADC_DETECT_IDLE_SW);/*channel 6*/
|
|
|
|
writel((readl(SAR_ADC_REG0) & (~(1 << 0))), SAR_ADC_REG0);
|
|
writel((readl(SAR_ADC_REG0)|(1 << 0)), SAR_ADC_REG0);
|
|
writel((readl(SAR_ADC_REG0)|(1 << 2)), SAR_ADC_REG0);/*start sample*/
|
|
|
|
count = 0;
|
|
do {
|
|
udelay(20);
|
|
count++;
|
|
} while ((readl(SAR_ADC_REG0) & (0x7 << 28))
|
|
&& (count < 100));/*finish sample?*/
|
|
if (count == 100) {
|
|
writel(readl(SAR_ADC_REG3) & (~(1 << 29)), SAR_ADC_REG3);
|
|
printf("%s: wait finish sample timeout!\n",__func__);
|
|
return -1;
|
|
}
|
|
|
|
value = readl(SAR_ADC_FIFO_RD);
|
|
#ifndef CONFIG_CHIP_AML_GXB
|
|
if (saradc_vref >= 0) /*write back SAR_ADC_REG13[13:8]*/
|
|
writel(((readl(SAR_ADC_REG13)) & (~(0x3f << 8))) |
|
|
((saradc_vref & 0x3f) << 8),
|
|
SAR_ADC_REG13);
|
|
#endif
|
|
writel(readl(SAR_ADC_DELAY) & (~(FLAG_BUSY_BL30)), SAR_ADC_DELAY);
|
|
if (((value >> 12) & 0x7) == 0x6)
|
|
value = value & SAMPLE_BIT_MASK;
|
|
else{
|
|
value = -1;
|
|
printf("%s:sample value err! ch:%d, flag:%d\n", __func__,
|
|
((value>>12) & 0x7), ((readl(SAR_ADC_DELAY) >> 14) & 3));
|
|
}
|
|
return value;
|
|
}
|
|
|
|
static unsigned int get_cpu_temp(int tsc, int flag)
|
|
{
|
|
unsigned value;
|
|
if (flag) {
|
|
value = readl(SAR_ADC_REG11);
|
|
writel(((value&(~(0x1f << 14))) | ((tsc & 0x1f) << 14)), SAR_ADC_REG11);
|
|
/* bit[14-18]:tsc */
|
|
} else{
|
|
value = readl(SAR_ADC_REG11);
|
|
writel(((value&(~(0x1f << 14))) | (0x10 << 14)), SAR_ADC_REG11);
|
|
/* bit[14-18]:0x16 */
|
|
}
|
|
return get_adc_sample(6);
|
|
}
|
|
|
|
void quicksort(int a[], int numsize)
|
|
{
|
|
int i = 0, j = numsize - 1;
|
|
int val = a[0];
|
|
if (numsize > 1) {
|
|
while (i < j) {
|
|
for (; j > i; j--)
|
|
if (a[j] < val) {
|
|
a[i] = a[j];
|
|
break;
|
|
}
|
|
for (; i < j; i++)
|
|
if (a[i] > val) {
|
|
a[j] = a[i];
|
|
break;
|
|
}
|
|
}
|
|
a[i] = val;
|
|
quicksort(a, i);
|
|
quicksort(a + i + 1, numsize - 1 - i);
|
|
}
|
|
}
|
|
|
|
static unsigned do_read_calib_data(int *flag, int *temp, int *TS_C)
|
|
{
|
|
char buf[2];
|
|
unsigned ret;
|
|
*flag = 0;
|
|
buf[0] = 0; buf[1] = 0;
|
|
|
|
char flagbuf;
|
|
|
|
ret = readl(AO_SEC_SD_CFG12);
|
|
flagbuf = (ret >> 24) & 0xff;
|
|
if (((int)flagbuf != 0xA0) && ((int)flagbuf != 0x40)
|
|
&& ((int)flagbuf != 0xC0)
|
|
&& ((int)flagbuf != 0x05) && ((int)flagbuf != 0x06)
|
|
&& ((int)flagbuf != 0x07) && ((int)flagbuf != 0x09)
|
|
&& ((int)flagbuf != 0x0a) && ((int)flagbuf != 0x0b)
|
|
&& ((int)flagbuf != 0x0d) && ((int)flagbuf != 0x0e)
|
|
&& ((int)flagbuf != 0x0f)
|
|
) {
|
|
if (flagbuf)
|
|
printf("thermal ver flag error!\n");
|
|
printf("flagbuf is 0x%x!\n", flagbuf);
|
|
return 0;
|
|
}
|
|
|
|
buf[0] = (ret) & 0xff;
|
|
buf[1] = (ret >> 8) & 0xff;
|
|
|
|
*temp = buf[1];
|
|
*temp = (*temp << 8) | buf[0];
|
|
*TS_C = *temp & 0x1f;
|
|
*flag = (*temp & 0x8000) >> 15;
|
|
*temp = (*temp & 0x7fff) >> 5;
|
|
|
|
if ((get_cpu_id().family_id == MESON_CPU_MAJOR_ID_GXBB)
|
|
&&(0x40 == (int)flagbuf))/*ver2*/
|
|
*TS_C = 16;
|
|
|
|
if (get_cpu_id().family_id >= MESON_CPU_MAJOR_ID_GXL)
|
|
*temp = (*temp) << 2; /*adc 12bit sample*/
|
|
|
|
printf("adc=%d,TS_C=%d,flag=%d\n", *temp, *TS_C, *flag);
|
|
return ret;
|
|
}
|
|
#if defined(NEW_THERMAL_MODE)
|
|
static unsigned int do_read_calib_data1(unsigned int *ver, unsigned int *u_efuse)
|
|
{
|
|
char buf[2];
|
|
unsigned ret;
|
|
buf[0] = 0; buf[1] = 0;
|
|
|
|
if (!ver)
|
|
return 0;
|
|
ret = readl(AO_SEC_GP_CFG10);
|
|
*ver = (ret >> 24) & 0xff;
|
|
if ((*ver != 0x05) && ((int)*ver != 0x06)
|
|
&& ((int)*ver != 0x07) && ((int)*ver != 0x0d)
|
|
&& ((int)*ver != 0x0e) && ((int)*ver != 0x0f)
|
|
&& ((int)*ver != 0x09) && ((int)*ver != 0x0a)
|
|
&& ((int)*ver != 0x0b)) {
|
|
if (ver)
|
|
printf("thermal ver flag error!\n");
|
|
printf("ver is 0x%x!\n", *ver);
|
|
return 0;
|
|
}
|
|
|
|
buf[0] = (ret) & 0xff;
|
|
buf[1] = (ret >> 8) & 0xff;
|
|
|
|
*u_efuse = buf[1];
|
|
*u_efuse = (*u_efuse << 8) | buf[0];
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
#if defined(NEW_THERMAL_MODE)
|
|
static int write_trim1(void)
|
|
{
|
|
unsigned int ret,ver, u_efuse;//, ret;
|
|
unsigned int signbit;
|
|
unsigned long value,tmp1,tmp2;
|
|
int family_id;
|
|
|
|
family_id = get_cpu_id().family_id;
|
|
switch (get_cpu_id().family_id) {
|
|
case MESON_CPU_MAJOR_ID_TXHD:
|
|
writel(1 << 7 | (0x30), HHI_TS_CLK_CNTL); /*clk:0.5M*/
|
|
writel(0x50ab, TS_CFG_REG);/*0x50ab is enable the new thermal module*/
|
|
break;
|
|
default:
|
|
printf("cpu xxxx family id not support!!! id: %d\n", family_id);
|
|
return -1;
|
|
}
|
|
mdelay(5); /*at least 4.2ms*/
|
|
|
|
ret = do_read_calib_data1(&ver, &u_efuse);
|
|
if (ret) {
|
|
printf("This chip has trimmed!!!\n");
|
|
return -1;
|
|
}
|
|
|
|
value = readl(TS_YOUT);
|
|
printf("value: 0x%lx\n",value);
|
|
value = value & (0xffff);/*maybe the value need to read more times*/
|
|
printf("temp_base: %d\n",temp_base);
|
|
|
|
printf("YOUT: 0x%lx\n", value);
|
|
if ((value < 0x18a9) || (value > 0x31c0)) { /*-20~125 ideal yout*/
|
|
printf("%s : YOUT: 0x%lx out of range! ERROR! \n",__func__,value);
|
|
return -1;
|
|
}
|
|
|
|
/* T = (727.8*(5.05*Yout)/((1<<16)+4.05*Yout)) - 274.7 */
|
|
/* u_efuse = u_ideal - u_real */
|
|
tmp1 = (((int64_t)temp_base * 10 + 2747) * (1 << 16)) / 7278; /*ideal u*/
|
|
printf("%s : tmp1: 0x%lx\n", __func__, tmp1);
|
|
tmp2 = (505 * (int64_t)value * (1 << 16)) / ((1 << 16) * 100 + 405 * value);
|
|
printf("%s : tmp2: 0x%lx\n", __func__, tmp2);
|
|
signbit = ((tmp1 > tmp2) ? 0 : 1);
|
|
u_efuse = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
|
|
u_efuse = (signbit << 15) | u_efuse;
|
|
printf("%s : u_efuse: 0x%x\n", __func__, u_efuse);
|
|
|
|
ret = thermal_calibration(2, u_efuse);
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
static int write_trim0(void)
|
|
{
|
|
int temp = 0;
|
|
int temp1[NUM];
|
|
char buf[2];
|
|
unsigned int data;
|
|
int i, TS_C;
|
|
int ret;
|
|
int flag;
|
|
|
|
memset(temp1, 0, NUM);
|
|
|
|
ret = adc_init_chan6();
|
|
if (ret)
|
|
goto err;
|
|
|
|
ret = do_read_calib_data(&flag, &temp, &TS_C);
|
|
if (ret) {
|
|
printf("chip has trimed!!!\n");
|
|
return -1;
|
|
} else {
|
|
printf("chip is not triming! triming now......\n");
|
|
flag = 0;
|
|
temp = 0;
|
|
TS_C = 0;
|
|
trim = 1;
|
|
}
|
|
for (i = 0; i < NUM; i++) {
|
|
udelay(10000);
|
|
/*adc sample value*/
|
|
temp1[i] = get_cpu_temp(16, 0);
|
|
}
|
|
|
|
printf("raw data\n");
|
|
for (i = 0; i < NUM; i++)
|
|
printf("%d ", temp1[i]);
|
|
|
|
printf("\nsort data\n");
|
|
|
|
quicksort(temp1, NUM);
|
|
for (i = 0; i < NUM; i++)
|
|
printf("%d ", temp1[i]);
|
|
printf("\n");
|
|
for (i = 2; i < NUM - 2; i++)
|
|
temp += temp1[i];
|
|
temp = temp / (NUM - 4);
|
|
printf("the adc cpu adc=%d\n", temp);
|
|
|
|
/**********************************/
|
|
TS_C = get_tsc(temp);
|
|
if ((TS_C == 31) || (TS_C <= 0)) {
|
|
printf("TS_C: %d NO Trim! Bad chip!Please check!!!\n", TS_C);
|
|
goto err;
|
|
}
|
|
/**********************************/
|
|
temp = 0;
|
|
memset(temp1, 0, NUM);
|
|
/* flag=1; */
|
|
for (i = 0; i < NUM; i++) {
|
|
udelay(10000);
|
|
temp1[i] = get_cpu_temp(TS_C, 1);
|
|
}
|
|
printf("use triming data\n");
|
|
quicksort(temp1, NUM);
|
|
for (i = 0; i < NUM; i++)
|
|
printf("%d ", temp1[i]);
|
|
printf("\n");
|
|
for (i = 2; i < NUM-2; i++)
|
|
temp += temp1[i];
|
|
temp = temp / (NUM - 4);
|
|
printf("the adc cpu adc=%d\n", temp);
|
|
|
|
/**************recalculate to 27******/
|
|
switch (get_cpu_id().family_id) {
|
|
case MESON_CPU_MAJOR_ID_GXBB:
|
|
case MESON_CPU_MAJOR_ID_GXTVBB:
|
|
temp = temp - 3.4 * (temp_base - 27);
|
|
break;
|
|
case MESON_CPU_MAJOR_ID_GXL:/*12bit*/
|
|
case MESON_CPU_MAJOR_ID_GXM:
|
|
case MESON_CPU_MAJOR_ID_GXLX:
|
|
if (vref_en) {
|
|
temp = temp - 15.3*(temp_base - 27);
|
|
temp = temp >> 2;/*efuse only 10bit adc*/
|
|
break;
|
|
} else {
|
|
temp = temp - 17 * (temp_base - 27);
|
|
temp = temp >> 2;/*efuse only 10bit adc*/
|
|
break;
|
|
}
|
|
case MESON_CPU_MAJOR_ID_TXL:
|
|
temp = temp - 15.5 * (temp_base - 27);
|
|
temp = temp >> 2;/*efuse only 10bit adc*/
|
|
break;
|
|
case MESON_CPU_MAJOR_ID_TXLX:
|
|
case MESON_CPU_MAJOR_ID_AXG:
|
|
case MESON_CPU_MAJOR_ID_TXHD:
|
|
temp = temp - 17 * (temp_base - 27);
|
|
temp = temp >> 2;/*efuse only 10bit adc*/
|
|
break;
|
|
default:
|
|
printf("cpu family id not support, thermal0!!!\n");
|
|
goto err;
|
|
}
|
|
/**********************************/
|
|
temp = ((temp << 5) | (TS_C & 0x1f)) & 0xffff;
|
|
/* write efuse tsc,flag */
|
|
buf[0] = (char)(temp & 0xff);
|
|
buf[1] = (char)((temp >> 8) & 0xff);
|
|
buf[1] |= 0x80;
|
|
printf("buf[0]=%x,buf[1]=%x\n", buf[0], buf[1]);
|
|
data = buf[1] << 8 | buf[0];
|
|
ret = thermal_calibration(0, data);
|
|
return ret;
|
|
err:
|
|
return -1;
|
|
}
|
|
|
|
static int do_write_trim(cmd_tbl_t *cmdtp, int flag1,
|
|
int argc, char * const argv[])
|
|
{
|
|
#if defined(NEW_THERMAL_MODE)
|
|
unsigned int choose = simple_strtoul(argv[1], NULL, 10);
|
|
#endif
|
|
int ret;
|
|
|
|
#if defined(NEW_THERMAL_MODE)
|
|
if (choose == 1) {
|
|
printf("%s: will trim thermal1.....\n",__func__);
|
|
ret = write_trim1();
|
|
} else
|
|
#endif
|
|
{
|
|
printf("%s: will trim thermal0.....\n",__func__);
|
|
ret = write_trim0();
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int read_temp0(void)
|
|
{
|
|
#ifndef R1P1_TSENSOR_MODE
|
|
int temp;
|
|
int TS_C;
|
|
int flag, adc, count, tempa;
|
|
unsigned ret;
|
|
flag = 0;
|
|
char buf[100] = {};
|
|
|
|
setenv("tempa", " ");
|
|
adc_init_chan6();
|
|
ret = do_read_calib_data(&flag, &temp, &TS_C);
|
|
if (ret) {
|
|
adc = 0;
|
|
count = 0;
|
|
while (count < 64) {
|
|
adc += get_cpu_temp(TS_C, flag);
|
|
count++;
|
|
udelay(200);
|
|
}
|
|
adc /= count;
|
|
tempa = 0;
|
|
printf("adc=%d\n", adc);
|
|
if (flag) {
|
|
switch (get_cpu_id().family_id) {
|
|
case MESON_CPU_MAJOR_ID_GXBB:
|
|
case MESON_CPU_MAJOR_ID_GXTVBB:
|
|
tempa = (10 * (adc-temp)) / 34 + 27;
|
|
break;
|
|
case MESON_CPU_MAJOR_ID_GXL:
|
|
case MESON_CPU_MAJOR_ID_GXM:
|
|
case MESON_CPU_MAJOR_ID_GXLX:
|
|
if (vref_en)/*thermal VREF*/
|
|
tempa = (10 * (adc - temp)) / 153 + 27;
|
|
else
|
|
tempa = (10 * (adc - temp)) / 171 + 27;
|
|
break;
|
|
case MESON_CPU_MAJOR_ID_TXL:
|
|
tempa = (10 * (adc - temp)) / 155 + 27;
|
|
break;
|
|
case MESON_CPU_MAJOR_ID_TXLX:
|
|
case MESON_CPU_MAJOR_ID_AXG:
|
|
case MESON_CPU_MAJOR_ID_TXHD:
|
|
tempa = (adc - temp) / 17 + 27;
|
|
break;
|
|
default:
|
|
printf("cpu family id not support!!!\n");
|
|
return -1;
|
|
}
|
|
printf("tempa=%d\n", tempa);
|
|
|
|
sprintf(buf, "%d", tempa);
|
|
setenv("tempa", buf);
|
|
memset(buf, 0, sizeof(buf));
|
|
sprintf(buf, "temp:%d, adc:%d, tsc:%d, dout:%d", tempa, adc, TS_C, temp);
|
|
setenv("err_info_tempa", buf);
|
|
} else {
|
|
printf("This chip is not trimmed\n");
|
|
sprintf(buf, "%s", "This chip is not trimmed");
|
|
setenv("err_info_tempa", buf);
|
|
return -1;
|
|
}
|
|
} else {
|
|
printf("read calibrated data failed\n");
|
|
sprintf(buf, "%s", "read calibrated data failed");
|
|
setenv("err_info_tempa", buf);
|
|
return -1;
|
|
}
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
#if defined(NEW_THERMAL_MODE)
|
|
static int read_temp1(void)
|
|
{
|
|
unsigned int ret;
|
|
unsigned long value;
|
|
unsigned int ver, u_efuse; //tmp for debug
|
|
int family_id;
|
|
int64_t temp;
|
|
|
|
family_id = get_cpu_id().family_id;
|
|
switch (get_cpu_id().family_id) {
|
|
case MESON_CPU_MAJOR_ID_TXHD:
|
|
writel(1 << 7 | (0x30), HHI_TS_CLK_CNTL); /*clk:0.5M*/
|
|
writel(0x50ab, TS_CFG_REG);/*0x50ab is enable the new thermal module*/
|
|
break;
|
|
default:
|
|
printf("cpu xxxx family id not support!!! id: %d\n", family_id);
|
|
return -1;
|
|
}
|
|
mdelay(5); /*at least 4.2ms*/
|
|
|
|
ret = do_read_calib_data1(&ver,&u_efuse);
|
|
if (!ret) {
|
|
printf("This chip is not trimmed\n");
|
|
return -1;
|
|
}
|
|
|
|
value = readl(TS_YOUT);
|
|
value = value & (0xffff);
|
|
|
|
printf("YOUT: 0x%lx\n", value);
|
|
printf("u_efuse: 0x%x\n", u_efuse);
|
|
/* T = 727.8*(u_real+u_efuse/(1<<16)) - 274.7 */
|
|
/* u_readl = (5.05*YOUT)/((1<<16)+ 4.05*YOUT) */
|
|
temp = (value * 505) * (1 << 16) / (100 * (1 << 16) + 405 * value);
|
|
|
|
if (u_efuse & 0x8000)
|
|
temp = ((temp - (u_efuse & (0x7fff))) * 7278 / (1 << 16) - 2747) / 10;
|
|
else
|
|
temp = ((temp + u_efuse) * 7278 / (1 << 16) - 2747) / 10;
|
|
printf("newtemp: %lld\n", temp);
|
|
return temp;
|
|
}
|
|
#endif
|
|
|
|
static int do_read_temp(cmd_tbl_t *cmdtp, int flag1,
|
|
int argc, char * const argv[])
|
|
{
|
|
#if defined(R1P1_TSENSOR_MODE)
|
|
printf("read temp\n");
|
|
r1p1_read_entry();
|
|
#endif
|
|
#if defined(NEW_THERMAL_MODE)
|
|
printf("read new and old temp\n");
|
|
read_temp1();
|
|
#endif
|
|
read_temp0();
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int do_write_version(cmd_tbl_t *cmdtp, int flag1,
|
|
int argc, char * const argv[])
|
|
{
|
|
int ret;
|
|
unsigned int val = simple_strtoul(argv[1], NULL, 16);
|
|
|
|
ret = thermal_calibration(1, val);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int do_set_trim_base(cmd_tbl_t *cmdtp, int flag1,
|
|
int argc, char * const argv[])
|
|
{
|
|
int temp = simple_strtoul(argv[1], NULL, 10);
|
|
temp_base = temp;
|
|
printf("set base temperature: %d\n", temp_base);
|
|
return 0;
|
|
}
|
|
|
|
static int do_temp_triming(cmd_tbl_t *cmdtp, int flag1,
|
|
int argc, char * const argv[])
|
|
{
|
|
int cmd_result = -1;
|
|
int temp;
|
|
|
|
#if defined (CONFIG_AML_MESON_AXG) || defined (CONFIG_AML_MESON_TXHD) || (R1P1_TSENSOR_MODE)
|
|
unsigned int ver;
|
|
int ret = -1;
|
|
#endif
|
|
|
|
if (argc < 2)
|
|
return CMD_RET_USAGE;
|
|
|
|
temp = simple_strtoul(argv[1], NULL, 10);
|
|
temp_base = temp;
|
|
printf("set base temperature: %d\n", temp_base);
|
|
|
|
switch (get_cpu_id().family_id) {
|
|
case MESON_CPU_MAJOR_ID_GXBB:
|
|
case MESON_CPU_MAJOR_ID_GXTVBB:
|
|
case MESON_CPU_MAJOR_ID_GXL:
|
|
case MESON_CPU_MAJOR_ID_GXM:
|
|
case MESON_CPU_MAJOR_ID_TXL:
|
|
case MESON_CPU_MAJOR_ID_TXLX:
|
|
case MESON_CPU_MAJOR_ID_GXLX:
|
|
cmd_result = run_command("write_trim", 0);
|
|
if (cmd_result == CMD_RET_SUCCESS) {
|
|
/*FB calibration v5: 1010 0000*/
|
|
/*manual calibration v2: 0100 0000*/
|
|
printf("manual calibration v3: 1100 0000\n");
|
|
cmd_result = run_command("write_version 0xc0", 0);
|
|
if (cmd_result != CMD_RET_SUCCESS)
|
|
printf("write version error!!!\n");
|
|
} else {
|
|
printf("trim FAIL!!!Please check!!!\n");
|
|
return -1;
|
|
}
|
|
run_command("read_temp", 0);
|
|
break;
|
|
#ifdef CONFIG_AML_MESON_AXG
|
|
case MESON_CPU_MAJOR_ID_AXG:
|
|
if (argc <3) {
|
|
printf("too little args for AXG temp triming!!\n");
|
|
return CMD_RET_USAGE;
|
|
}
|
|
ver = simple_strtoul(argv[2], NULL, 10);
|
|
printf("ver: %d\n", ver);
|
|
switch (ver) {
|
|
case 0x5:
|
|
case 0xd: /*thermal0*/
|
|
cmd_result = run_command("write_trim", 0);
|
|
if (cmd_result != CMD_RET_SUCCESS) {
|
|
printf("trim FAIL!!!Please check!!!\n");
|
|
return -1;
|
|
} else
|
|
ret = 0;
|
|
break;
|
|
default:
|
|
printf("thermal version not support!!!Please check!\n");
|
|
return -1;
|
|
}
|
|
printf("trim thermal data ok\n");
|
|
if (!ret) { //write data ok
|
|
char str[20];
|
|
sprintf(str, "write_version 0x%x", ver);
|
|
|
|
cmd_result = run_command(str, 0);
|
|
if (cmd_result == CMD_RET_SUCCESS)
|
|
printf("write thermal version ok\n");
|
|
else {
|
|
printf("trim FAIL!!!Please check version!!!\n");
|
|
return -1;
|
|
}
|
|
}
|
|
break;
|
|
#endif
|
|
#ifdef CONFIG_AML_MESON_TXHD
|
|
case MESON_CPU_MAJOR_ID_TXHD:
|
|
if (argc <3) {
|
|
printf("too little args for txhd temp triming!!\n");
|
|
return CMD_RET_USAGE;
|
|
}
|
|
ver = simple_strtoul(argv[2], NULL, 10);
|
|
printf("ver: %d\n", ver);
|
|
switch (ver) {
|
|
case 0x6:
|
|
case 0xe: /*thermal1*/
|
|
if (get_cpu_id().chip_rev != 0x7) {
|
|
cmd_result = run_command("write_trim 1", 0);
|
|
if (cmd_result != CMD_RET_SUCCESS) {
|
|
printf("trim FAIL!!!Please check!!!\n");
|
|
return -1;
|
|
} else
|
|
ret = 0;
|
|
} else
|
|
printf("chip version: 0x%x not support!!!Please check!\n",
|
|
get_cpu_id().chip_rev);
|
|
break;
|
|
case 0x5:
|
|
case 0xd: /*thermal0*/
|
|
cmd_result = run_command("write_trim", 0);
|
|
if (cmd_result != CMD_RET_SUCCESS) {
|
|
printf("trim FAIL!!!Please check!!!\n");
|
|
return -1;
|
|
} else
|
|
ret = 0;
|
|
break;
|
|
case 0x7:
|
|
case 0xf:
|
|
if (get_cpu_id().chip_rev != 0x7) {
|
|
cmd_result = run_command("write_trim 1", 0);
|
|
if (cmd_result != CMD_RET_SUCCESS) {
|
|
printf("trim FAIL!!!Please check!!!\n");
|
|
return -1;
|
|
} else {
|
|
ret = 0;
|
|
cmd_result = run_command("write_trim", 0);
|
|
if (cmd_result != CMD_RET_SUCCESS) {
|
|
printf("trim FAIL!!!Please check!!!\n");
|
|
return -1;
|
|
} else
|
|
ret = 0;
|
|
}
|
|
} else
|
|
printf("chip version: 0x%x not support!!!Please check!\n",
|
|
get_cpu_id().chip_rev);
|
|
break;
|
|
default:
|
|
printf("thermal version not support!!!Please check!\n");
|
|
return -1;
|
|
}
|
|
printf("trim thermal data ok\n");
|
|
if (!ret) { //write data ok
|
|
char str[20];
|
|
sprintf(str, "write_version 0x%x", ver);
|
|
|
|
cmd_result = run_command(str, 0);
|
|
if (cmd_result == CMD_RET_SUCCESS)
|
|
printf("write thermal version ok\n");
|
|
else {
|
|
printf("trim FAIL!!!Please check version!!!\n");
|
|
return -1;
|
|
}
|
|
}
|
|
break;
|
|
#endif
|
|
|
|
#if defined(R1P1_TSENSOR_MODE)
|
|
case MESON_CPU_MAJOR_ID_G12A:
|
|
case MESON_CPU_MAJOR_ID_G12B:
|
|
case MESON_CPU_MAJOR_ID_TL1:
|
|
case MESON_CPU_MAJOR_ID_SM1:
|
|
case MESON_CPU_MAJOR_ID_TM2:
|
|
case MESON_CPU_MAJOR_ID_T5:
|
|
case MESON_CPU_MAJOR_ID_T5D:
|
|
if (argc <3) {
|
|
printf("too little args for txhd temp triming!!\n");
|
|
return CMD_RET_USAGE;
|
|
}
|
|
ver = simple_strtoul(argv[2], NULL, 16);
|
|
ret = r1p1_trim_entry(temp_base, ver);
|
|
return ret;
|
|
break;
|
|
#endif
|
|
|
|
default:
|
|
printf("cpu family id not support!!!\n");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#ifdef R1P1_TSENSOR_MODE
|
|
|
|
#ifndef TS_SAR_CFG_REG1
|
|
#define TS_SAR_CFG_REG1 TS_DDR_CFG_REG1
|
|
#endif
|
|
|
|
#ifndef TS_SAR_STAT0
|
|
#define TS_SAR_STAT0 TS_DDR_STAT0
|
|
#endif
|
|
|
|
/* for sending tsensor calibration data to bl31 */
|
|
#define TSENSOR_CALI_SET 0x8200004C
|
|
|
|
int tsensor_tz_calibration(unsigned int type, unsigned int data)
|
|
{
|
|
int ret;
|
|
struct arm_smccc_res res;
|
|
|
|
arm_smccc_smc(TSENSOR_CALI_SET, type, data, 0, 0, 0, 0, 0, &res);
|
|
ret = res.a0;
|
|
|
|
if (!ret)
|
|
return -1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
int r1p1_codetotemp(unsigned long value, unsigned int u_efuse,
|
|
int ts_b, int ts_a, int ts_m, int ts_n)
|
|
{
|
|
int64_t temp;
|
|
|
|
/* T = 727.8*(u_real+u_efuse/(1<<16)) - 274.7 */
|
|
/* u_readl = (5.05*YOUT)/((1<<16)+ 4.05*YOUT) */
|
|
temp = (value * ts_m) * (1 << 16) / (100 * (1 << 16) + ts_n * value);
|
|
if (u_efuse & 0x8000) {
|
|
temp = ((temp - (u_efuse & 0x7fff)) * ts_a / (1 << 16) - ts_b) / 10;
|
|
} else {
|
|
temp = ((temp + (u_efuse & 0x7fff)) * ts_a / (1 << 16) - ts_b) / 10;
|
|
}
|
|
return temp;
|
|
}
|
|
|
|
int r1p1_temp_read(int type, int *temp)
|
|
{
|
|
unsigned int ret, u_efuse, regdata;//, ret;
|
|
unsigned int value_ts, value_all_ts;
|
|
int family_id;
|
|
int tmp = -1;
|
|
int i, ts_a, ts_b, ts_m, ts_n, cnt;
|
|
char buf[2];
|
|
|
|
family_id = get_cpu_id().family_id;
|
|
switch (family_id) {
|
|
case MESON_CPU_MAJOR_ID_G12A:
|
|
case MESON_CPU_MAJOR_ID_G12B:
|
|
case MESON_CPU_MAJOR_ID_TL1:
|
|
case MESON_CPU_MAJOR_ID_SM1:
|
|
case MESON_CPU_MAJOR_ID_TM2:
|
|
case MESON_CPU_MAJOR_ID_T5:
|
|
case MESON_CPU_MAJOR_ID_T5D:
|
|
case MESON_CPU_MAJOR_ID_T5W:
|
|
ts_b = 3159;
|
|
ts_a = 9411;
|
|
ts_m = 424;
|
|
ts_n = 324;
|
|
switch (type) {
|
|
case 1:
|
|
/*enable thermal1*/
|
|
regdata = 0x62b;/*enable control*/
|
|
writel(regdata, TS_PLL_CFG_REG1);
|
|
regdata = 0x130;/*enable tsclk*/
|
|
writel(regdata, HHI_TS_CLK_CNTL);
|
|
ret = readl(AO_SEC_GP_CFG10);/*thermal1 cali data in reg CFG10*/
|
|
mdelay(5);
|
|
buf[0] = (ret) & 0xff;
|
|
buf[1] = (ret >> 8) & 0xff;
|
|
u_efuse = buf[1];
|
|
u_efuse = (u_efuse << 8) | buf[0];
|
|
value_ts = 0;
|
|
value_all_ts = 0;
|
|
cnt = 0;
|
|
for (i = 0; i <= 10; i ++) {
|
|
udelay(50);
|
|
value_ts = readl(TS_PLL_STAT0) & 0xffff;
|
|
}
|
|
for (i = 0; i < READ_NUM; i ++) {
|
|
udelay(4500);
|
|
value_ts = readl(TS_PLL_STAT0) & 0xffff;
|
|
if ((value_ts >= 0x1500) && (value_ts <= 0x3500)) {
|
|
value_all_ts += value_ts;
|
|
cnt ++;
|
|
}
|
|
}
|
|
if (cnt) {
|
|
value_ts = value_all_ts / cnt;
|
|
} else {
|
|
value_ts = 0;
|
|
printf("tsensor read temp cnt is 0\n");
|
|
}
|
|
printf("pll tsensor avg: 0x%x, u_efuse: 0x%x\n", value_ts, u_efuse);
|
|
if (value_ts == 0) {
|
|
printf("tsensor read temp is zero\n");
|
|
return -1;
|
|
}
|
|
tmp = r1p1_codetotemp(value_ts, u_efuse, ts_b, ts_a, ts_m, ts_n);
|
|
printf("temp1: %d\n", tmp);
|
|
break;
|
|
case 2:
|
|
/*enable thermal2*/
|
|
regdata = 0x62b;/*enable control*/
|
|
writel(regdata,TS_DDR_CFG_REG1);
|
|
regdata = 0x130;/*enable tsclk*/
|
|
writel(regdata,HHI_TS_CLK_CNTL);
|
|
mdelay(5);
|
|
ret = readl(AO_SEC_SD_CFG12);/*thermal1 cali data in reg CFG10*/
|
|
buf[0] = (ret) & 0xff;
|
|
buf[1] = (ret >> 8) & 0xff;
|
|
u_efuse = buf[1];
|
|
u_efuse = (u_efuse << 8) | buf[0];
|
|
value_ts = 0;
|
|
value_all_ts = 0;
|
|
cnt = 0;
|
|
for (i = 0; i <= 10; i ++) {
|
|
udelay(50);
|
|
value_ts = readl(TS_DDR_STAT0) & 0xffff;
|
|
}
|
|
for (i = 0; i < READ_NUM; i ++) {
|
|
udelay(4500);
|
|
value_ts = readl(TS_DDR_STAT0) & 0xffff;
|
|
if ((value_ts >= 0x1500) && (value_ts <= 0x3500)) {
|
|
value_all_ts += value_ts;
|
|
cnt ++;
|
|
}
|
|
}
|
|
if (cnt) {
|
|
value_ts = value_all_ts / cnt;
|
|
} else {
|
|
value_ts = 0;
|
|
printf("tsensor read temp cnt is 0\n");
|
|
}
|
|
printf("ddr tsensor avg: 0x%x, u_efuse: 0x%x\n", value_ts, u_efuse);
|
|
if (value_ts == 0) {
|
|
printf("tsensor read temp is zero\n");
|
|
return -1;
|
|
}
|
|
tmp = r1p1_codetotemp(value_ts, u_efuse, ts_b, ts_a, ts_m, ts_n);
|
|
printf("temp2: %d\n", tmp);
|
|
break;
|
|
case 3:
|
|
/*enable thermal2*/
|
|
regdata = 0x62b;/*enable control*/
|
|
writel(regdata, TS_SAR_CFG_REG1);
|
|
regdata = 0x130;/*enable tsclk*/
|
|
writel(regdata, HHI_TS_CLK_CNTL);
|
|
mdelay(5);
|
|
ret = readl(AO_SEC_GP_CFG11);/*thermal3 cali data in reg GP_CFG11*/
|
|
buf[0] = (ret) & 0xff;
|
|
buf[1] = (ret >> 8) & 0xff;
|
|
u_efuse = buf[1];
|
|
u_efuse = (u_efuse << 8) | buf[0];
|
|
value_ts = 0;
|
|
value_all_ts = 0;
|
|
cnt = 0;
|
|
for (i = 0; i <= 10; i ++) {
|
|
udelay(50);
|
|
value_ts = readl(TS_SAR_STAT0) & 0xffff;
|
|
}
|
|
for (i = 0; i < READ_NUM; i ++) {
|
|
udelay(4500);
|
|
value_ts = readl(TS_SAR_STAT0) & 0xffff;
|
|
if ((value_ts >= 0x1500) && (value_ts <= 0x3500)) {
|
|
value_all_ts += value_ts;
|
|
cnt ++;
|
|
}
|
|
}
|
|
if (cnt) {
|
|
value_ts = value_all_ts / cnt;
|
|
} else {
|
|
value_ts = 0;
|
|
printf("tsensor read temp cnt is 0\n");
|
|
}
|
|
printf("sar tsensor avg: 0x%x, u_efuse: 0x%x\n", value_ts, u_efuse);
|
|
if (value_ts == 0) {
|
|
printf("tsensor read temp is zero\n");
|
|
return -1;
|
|
}
|
|
tmp = r1p1_codetotemp(value_ts, u_efuse, ts_b, ts_a, ts_m, ts_n);
|
|
printf("temp3: %d\n", tmp);
|
|
break;
|
|
default:
|
|
printf("r1p1 tsensor trim type not support\n");
|
|
}
|
|
}
|
|
if (temp)
|
|
*temp = tmp;
|
|
return 0;
|
|
}
|
|
|
|
|
|
int r1p1_read_entry(void)
|
|
{
|
|
unsigned int ret, ver;//, ret;
|
|
int family_id;
|
|
|
|
family_id = get_cpu_id().family_id;
|
|
switch (family_id) {
|
|
case MESON_CPU_MAJOR_ID_G12A:
|
|
case MESON_CPU_MAJOR_ID_G12B:
|
|
case MESON_CPU_MAJOR_ID_SM1:
|
|
ret = readl(AO_SEC_GP_CFG10);
|
|
ver = (ret >> 24) & 0xff;
|
|
if ((ver & 0x80) == 0) {
|
|
printf("tsensor no trimmed, ver:0x%x\n", ver);
|
|
return -1;
|
|
}
|
|
ver = (ver & 0xf) >> 2;
|
|
switch (ver) {
|
|
case 0x2:
|
|
r1p1_temp_read(1, NULL);
|
|
r1p1_temp_read(2, NULL);
|
|
printf("read the thermal1 and thermal2\n");
|
|
break;
|
|
case 0x0:
|
|
case 0x1:
|
|
case 0x3:
|
|
printf("temp type no support\n");
|
|
break;
|
|
default:
|
|
printf("thermal version not support!!!Please check!\n");
|
|
return -1;
|
|
}
|
|
break;
|
|
case MESON_CPU_MAJOR_ID_TL1:
|
|
case MESON_CPU_MAJOR_ID_TM2:
|
|
ret = readl(AO_SEC_GP_CFG10);
|
|
ver = (ret >> 24) & 0xff;
|
|
if ((ver & 0x80) == 0) {
|
|
printf("tsensor no trimmed, ver:0x%x\n", ver);
|
|
return -1;
|
|
}
|
|
ver = (ver & 0xf) >> 2;
|
|
switch (ver) {
|
|
case 0x2:
|
|
r1p1_temp_read(1, NULL);
|
|
r1p1_temp_read(2, NULL);
|
|
printf("read the thermal1 2\n");
|
|
break;
|
|
case 0x3:
|
|
r1p1_temp_read(1, NULL);
|
|
r1p1_temp_read(2, NULL);
|
|
r1p1_temp_read(3, NULL);
|
|
printf("read the thermal1 2 3\n");
|
|
break;
|
|
case 0x0:
|
|
case 0x1:
|
|
printf("temp type no support\n");
|
|
break;
|
|
}
|
|
break;
|
|
case MESON_CPU_MAJOR_ID_T5:
|
|
case MESON_CPU_MAJOR_ID_T5D:
|
|
case MESON_CPU_MAJOR_ID_T5W:
|
|
ret = readl(AO_SEC_GP_CFG10);
|
|
ver = (ret >> 24) & 0xff;
|
|
if ((ver & 0x80) == 0) {
|
|
printf("tsensor no trimmed, ver:0x%x\n", ver);
|
|
return -1;
|
|
}
|
|
r1p1_temp_read(1, NULL);
|
|
printf("read the thermal1\n");
|
|
break;
|
|
default:
|
|
printf("chip major id not support!!!Please check!\n");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
unsigned int r1p1_temptocode(unsigned long value, int tempbase,
|
|
int ts_b, int ts_a, int ts_m, int ts_n)
|
|
{
|
|
unsigned long tmp1, tmp2, u_efuse, signbit;
|
|
/* T = (727.8*(5.05*Yout)/((1<<16)+4.05*Yout)) - 274.7 */
|
|
/* u_efuse = u_ideal - u_real */
|
|
printf("a b m n: %d, %d, %d, %d\n", ts_a, ts_b, ts_m, ts_n);
|
|
tmp1 = (((int64_t)tempbase * 10 + ts_b) * (1 << 16)) / ts_a; /*ideal u*/
|
|
printf("%s : tmp1: 0x%lx\n", __func__, tmp1);
|
|
tmp2 = (ts_m * (int64_t)value * (1 << 16)) / ((1 << 16) * 100 + ts_n * value);
|
|
printf("%s : tmp2: 0x%lx\n", __func__, tmp2);
|
|
signbit = ((tmp1 > tmp2) ? 0 : 1);
|
|
u_efuse = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
|
|
u_efuse = u_efuse & 0x7fff;/*efuse size supports 15bits*/
|
|
u_efuse = (signbit << 15) | u_efuse;
|
|
return u_efuse;
|
|
}
|
|
|
|
int r1p1_temp_trim(int tempbase, int tempver, int type)
|
|
{
|
|
unsigned int u_efuse, regdata, index_ts, index_ver;//, ret;
|
|
unsigned int value_ts, value_all_ts;
|
|
int family_id;
|
|
int i, ts_a, ts_b, ts_m, ts_n, cnt;
|
|
|
|
family_id = get_cpu_id().family_id;
|
|
printf("r1p1 temp trim type: 0x%x, familyid: %d\n", type, family_id);
|
|
switch (family_id) {
|
|
case MESON_CPU_MAJOR_ID_G12A:
|
|
case MESON_CPU_MAJOR_ID_G12B:
|
|
case MESON_CPU_MAJOR_ID_TL1:
|
|
case MESON_CPU_MAJOR_ID_SM1:
|
|
case MESON_CPU_MAJOR_ID_TM2:
|
|
ts_b = 3159;
|
|
ts_a = 9411;
|
|
ts_m = 424;
|
|
ts_n = 324;
|
|
switch (type) {
|
|
case 0:
|
|
index_ver = 5;
|
|
if (thermal_calibration(index_ver, tempver) < 0)
|
|
printf("version tsensor thermal_calibration send error\n");
|
|
break;
|
|
case 1:
|
|
value_ts = 0;
|
|
value_all_ts = 0;
|
|
index_ts = 6;
|
|
cnt = 0;
|
|
|
|
/*enable thermal1*/
|
|
regdata = 0x62b;/*enable control*/
|
|
writel(regdata, TS_PLL_CFG_REG1);
|
|
regdata = 0x130;/*enable tsclk*/
|
|
writel(regdata, HHI_TS_CLK_CNTL);
|
|
for (i = 0; i <= 10; i ++) {
|
|
udelay(50);
|
|
value_ts = readl(TS_PLL_STAT0) & 0xffff;
|
|
}
|
|
for (i = 0; i <= NUM; i ++) {
|
|
udelay(5000);
|
|
value_ts = readl(TS_PLL_STAT0) & 0xffff;
|
|
printf("pll tsensor read: 0x%x\n", value_ts);
|
|
if ((value_ts >= 0x1500) && (value_ts <= 0x3500)) {
|
|
value_all_ts += value_ts;
|
|
cnt ++;
|
|
}
|
|
}
|
|
value_ts = value_all_ts / cnt;
|
|
printf("pll tsensor avg: 0x%x\n", value_ts);
|
|
if (value_ts == 0) {
|
|
printf("pll tsensor read temp is zero\n");
|
|
return -1;
|
|
}
|
|
u_efuse = r1p1_temptocode(value_ts, tempbase, ts_b, ts_a, ts_m, ts_n);
|
|
printf("pll ts efuse:%d\n", u_efuse);
|
|
printf("pll ts efuse:0x%x, index: %d\n", u_efuse, index_ts);
|
|
if (thermal_calibration(index_ts, u_efuse) < 0) {
|
|
printf("pll tsensor thermal_calibration send error\n");
|
|
return -1;
|
|
}
|
|
break;
|
|
case 2:
|
|
value_ts = 0;
|
|
value_all_ts = 0;
|
|
index_ts = 7;
|
|
cnt = 0;
|
|
|
|
/*enable thermal2*/
|
|
regdata = 0x62b;/*enable control*/
|
|
writel(regdata, TS_DDR_CFG_REG1);
|
|
regdata = 0x130;/*enable tsclk*/
|
|
writel(regdata, HHI_TS_CLK_CNTL);
|
|
for (i = 0; i <= 10; i ++) {
|
|
udelay(50);
|
|
value_ts = readl(TS_DDR_STAT0) & 0xffff;
|
|
}
|
|
for (i = 0; i <= NUM; i ++) {
|
|
udelay(5000);
|
|
value_ts = readl(TS_DDR_STAT0) & 0xffff;
|
|
printf("ddr tsensor read: 0x%x\n", value_ts);
|
|
if ((value_ts >= 0x1500) && (value_ts <= 0x3500)) {
|
|
value_all_ts += value_ts;
|
|
cnt ++;
|
|
}
|
|
}
|
|
value_ts = value_all_ts / cnt;
|
|
printf("ddr tsensor avg: 0x%x\n", value_ts);
|
|
if (value_ts == 0) {
|
|
printf("ddr tsensor read temp is zero\n");
|
|
return -1;
|
|
}
|
|
u_efuse = r1p1_temptocode(value_ts, tempbase, ts_b, ts_a, ts_m, ts_n);
|
|
printf("ddr ts efuse:%d\n", u_efuse);
|
|
printf("ddr ts efuse:0x%x, index: %d\n", u_efuse, index_ts);
|
|
if (thermal_calibration(index_ts, u_efuse) < 0) {
|
|
printf("ddr tsensor thermal_calibration send error\n");
|
|
return -1;
|
|
}
|
|
break;
|
|
case 3:
|
|
value_ts = 0;
|
|
value_all_ts = 0;
|
|
index_ts = 8;
|
|
cnt = 0;
|
|
|
|
/*enable thermal3*/
|
|
regdata = 0x62b;/*enable control*/
|
|
writel(regdata, TS_SAR_CFG_REG1);
|
|
regdata = 0x130;/*enable tsclk*/
|
|
writel(regdata, HHI_TS_CLK_CNTL);
|
|
for (i = 0; i <= 10; i ++) {
|
|
udelay(50);
|
|
value_ts = readl(TS_SAR_STAT0) & 0xffff;
|
|
}
|
|
for (i = 0; i <= NUM; i ++) {
|
|
udelay(5000);
|
|
value_ts = readl(TS_SAR_STAT0) & 0xffff;
|
|
printf("sar tsensor read: 0x%x\n", value_ts);
|
|
if ((value_ts >= 0x1500) && (value_ts <= 0x3500)) {
|
|
value_all_ts += value_ts;
|
|
cnt ++;
|
|
}
|
|
}
|
|
value_ts = value_all_ts / cnt;
|
|
printf("sar tsensor avg: 0x%x\n", value_ts);
|
|
if (value_ts == 0) {
|
|
printf("sar tsensor read temp is zero\n");
|
|
return -1;
|
|
}
|
|
u_efuse = r1p1_temptocode(value_ts, tempbase, ts_b, ts_a, ts_m, ts_n);
|
|
printf("sar ts efuse:%d\n", u_efuse);
|
|
printf("sar ts efuse:0x%x, index: %d\n", u_efuse, index_ts);
|
|
if (thermal_calibration(index_ts, u_efuse) < 0) {
|
|
printf("sar tsensor thermal_calibration send error\n");
|
|
return -1;
|
|
}
|
|
break;
|
|
default:
|
|
printf("r1p1 tsensor trim type not support\n");
|
|
return -1;
|
|
break;
|
|
}
|
|
break;
|
|
case MESON_CPU_MAJOR_ID_T5:
|
|
case MESON_CPU_MAJOR_ID_T5D:
|
|
ts_b = 3159;
|
|
ts_a = 9411;
|
|
ts_m = 424;
|
|
ts_n = 324;
|
|
switch (type) {
|
|
case 0:
|
|
index_ver = 5;
|
|
tempver = tempver & 0xf;
|
|
if (tsensor_tz_calibration(index_ver, tempver) < 0)
|
|
printf("version tsensor thermal_calibration send error\n");
|
|
break;
|
|
case 1:
|
|
value_ts = 0;
|
|
value_all_ts = 0;
|
|
index_ts = 6;
|
|
cnt = 0;
|
|
|
|
/*enable thermal1*/
|
|
regdata = 0x62b;/*enable control*/
|
|
writel(regdata, TS_PLL_CFG_REG1);
|
|
regdata = 0x130;/*enable tsclk*/
|
|
writel(regdata, HHI_TS_CLK_CNTL);
|
|
for (i = 0; i <= 10; i ++) {
|
|
udelay(50);
|
|
value_ts = readl(TS_PLL_STAT0) & 0xffff;
|
|
}
|
|
for (i = 0; i <= NUM; i ++) {
|
|
udelay(5000);
|
|
value_ts = readl(TS_PLL_STAT0) & 0xffff;
|
|
printf("pll tsensor read: 0x%x\n", value_ts);
|
|
if ((value_ts >= 0x1500) && (value_ts <= 0x3500)) {
|
|
value_all_ts += value_ts;
|
|
cnt ++;
|
|
}
|
|
}
|
|
value_ts = value_all_ts / cnt;
|
|
printf("pll tsensor avg: 0x%x\n", value_ts);
|
|
if (value_ts == 0) {
|
|
printf("pll tsensor read temp is zero\n");
|
|
return -1;
|
|
}
|
|
u_efuse = r1p1_temptocode(value_ts, tempbase, ts_b, ts_a, ts_m, ts_n);
|
|
if (u_efuse & 0x8000) {
|
|
u_efuse = u_efuse & 0x3fff;/*t5 efuse size supports 14bits*/
|
|
u_efuse = u_efuse | 0xc000;
|
|
}else{
|
|
u_efuse = u_efuse & 0x3fff;/*t5 efuse size supports 14bits*/
|
|
u_efuse = u_efuse | 0x8000;
|
|
}
|
|
printf("pll ts efuse:%d\n", u_efuse);
|
|
printf("pll ts efuse:0x%x, index: %d\n", u_efuse, index_ts);
|
|
if (tsensor_tz_calibration(index_ts, u_efuse) < 0) {
|
|
printf("pll tsensor thermal_calibration send error\n");
|
|
return -1;
|
|
}
|
|
break;
|
|
default:
|
|
printf("r1p1 tsensor trim type not support\n");
|
|
return -1;
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
printf("r1p1 tsensor family_id not support\n");
|
|
return -1;
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int r1p1_trim_entry(int tempbase, int tempver)
|
|
{
|
|
unsigned int ret, ver;
|
|
int family_id;
|
|
|
|
family_id = get_cpu_id().family_id;
|
|
switch (family_id) {
|
|
case MESON_CPU_MAJOR_ID_G12A:
|
|
case MESON_CPU_MAJOR_ID_G12B:
|
|
case MESON_CPU_MAJOR_ID_SM1:
|
|
ret = readl(AO_SEC_GP_CFG10);
|
|
ver = (ret >> 24) & 0xff;
|
|
if (ver & 0x80) {
|
|
printf("tsensor has trimmed, ver:0x%x\n", ver);
|
|
printf("tsensor cali data: 0x%x, 0x%x\n",
|
|
readl(AO_SEC_GP_CFG10), readl(AO_SEC_SD_CFG12));
|
|
return -1;
|
|
}
|
|
printf("tsensor input trim tempver, tempver:0x%x\n", tempver);
|
|
switch (tempver) {
|
|
case 0x88:
|
|
r1p1_temp_trim(tempbase, tempver, 1);
|
|
r1p1_temp_trim(tempbase, tempver, 2);
|
|
r1p1_temp_trim(tempbase, tempver, 0);
|
|
printf("triming the thermal1 and thermal2 by bbt-sw\n");
|
|
break;
|
|
case 0x89:
|
|
r1p1_temp_trim(tempbase, tempver, 1);
|
|
r1p1_temp_trim(tempbase, tempver, 2);
|
|
r1p1_temp_trim(tempbase, tempver, 0);
|
|
printf("triming the thermal1 and thermal2 by bbt-ops\n");
|
|
break;
|
|
case 0x8b:
|
|
r1p1_temp_trim(tempbase, tempver, 1);
|
|
r1p1_temp_trim(tempbase, tempver, 2);
|
|
r1p1_temp_trim(tempbase, tempver, 0);
|
|
printf("triming the thermal1 and thermal2 by slt\n");
|
|
break;
|
|
default:
|
|
printf("thermal version not support!!!Please check!\n");
|
|
return -1;
|
|
}
|
|
break;
|
|
case MESON_CPU_MAJOR_ID_TL1:
|
|
case MESON_CPU_MAJOR_ID_TM2:
|
|
ret = readl(AO_SEC_GP_CFG10);
|
|
ver = (ret >> 24) & 0xff;
|
|
if (ver & 0x80) {
|
|
printf("tsensor has trimmed, ver:0x%x\n", ver);
|
|
printf("tsensor cali data: 0x%x, 0x%x, 0x%x\n",
|
|
readl(AO_SEC_GP_CFG10), readl(AO_SEC_SD_CFG12), readl(AO_SEC_GP_CFG11));
|
|
return -1;
|
|
}
|
|
printf("tsensor input trim tempver, tempver:0x%x\n", tempver);
|
|
switch (tempver) {
|
|
case 0x8c:
|
|
r1p1_temp_trim(tempbase, tempver, 1);
|
|
r1p1_temp_trim(tempbase, tempver, 2);
|
|
r1p1_temp_trim(tempbase, tempver, 3);
|
|
r1p1_temp_trim(tempbase, tempver, 0);
|
|
printf("triming the thermal1 2 3 by sw-bbt\n");
|
|
break;
|
|
case 0x8d:
|
|
r1p1_temp_trim(tempbase, tempver, 1);
|
|
r1p1_temp_trim(tempbase, tempver, 2);
|
|
r1p1_temp_trim(tempbase, tempver, 3);
|
|
r1p1_temp_trim(tempbase, tempver, 0);
|
|
printf("triming the thermal1 2 3 by ops-bbt\n");
|
|
break;
|
|
case 0x8f:
|
|
r1p1_temp_trim(tempbase, tempver, 1);
|
|
r1p1_temp_trim(tempbase, tempver, 2);
|
|
r1p1_temp_trim(tempbase, tempver, 3);
|
|
r1p1_temp_trim(tempbase, tempver, 0);
|
|
printf("triming the thermal1 2 3 by slt\n");
|
|
break;
|
|
default:
|
|
printf("thermal version not support!!!Please check!\n");
|
|
return -1;
|
|
}
|
|
break;
|
|
case MESON_CPU_MAJOR_ID_T5:
|
|
case MESON_CPU_MAJOR_ID_T5D:
|
|
ret = readl(AO_SEC_GP_CFG10);
|
|
ver = (ret >> 24) & 0xff;
|
|
if (ver & 0x80) {
|
|
printf("tsensor has trimmed, ver:0x%x\n", ver);
|
|
printf("tsensor cali data: 0x%x\n", readl(AO_SEC_GP_CFG10));
|
|
return -1;
|
|
}
|
|
printf("tsensor input trim tempver, tempver:0x%x\n", tempver);
|
|
switch (tempver) {
|
|
case 0x80:
|
|
r1p1_temp_trim(tempbase, tempver, 1);
|
|
r1p1_temp_trim(tempbase, tempver, 0);
|
|
printf("triming the thermal by sw-bbt\n");
|
|
break;
|
|
case 0x81:
|
|
r1p1_temp_trim(tempbase, tempver, 1);
|
|
r1p1_temp_trim(tempbase, tempver, 0);
|
|
printf("triming the thermal by ops-bbt\n");
|
|
break;
|
|
case 0x83:
|
|
r1p1_temp_trim(tempbase, tempver, 1);
|
|
r1p1_temp_trim(tempbase, tempver, 0);
|
|
printf("triming the thermal by slt\n");
|
|
break;
|
|
default:
|
|
printf("thermal version not support!!!Please check!\n");
|
|
return -1;
|
|
}
|
|
break;
|
|
default:
|
|
printf("chip major id not support!!! Please check!\n");
|
|
break;
|
|
}
|
|
return 0;
|
|
|
|
}
|
|
|
|
#ifdef CONFIG_HIGH_TEMP_COOL
|
|
void r1p1_temp_cooling(void)
|
|
{
|
|
int family_id, temp, temp1, temp2;
|
|
unsigned int sensornum;
|
|
|
|
family_id = get_cpu_id().family_id;
|
|
switch (family_id) {
|
|
case MESON_CPU_MAJOR_ID_G12A:
|
|
case MESON_CPU_MAJOR_ID_G12B:
|
|
case MESON_CPU_MAJOR_ID_SM1:
|
|
while (1) {
|
|
r1p1_temp_read(1, &temp1);
|
|
r1p1_temp_read(2, &temp2);
|
|
temp = temp1 > temp2 ? temp1 : temp2;
|
|
if (temp <= CONFIG_HIGH_TEMP_COOL) {
|
|
printf("device cool done\n");
|
|
break;
|
|
}
|
|
mdelay(2000);
|
|
printf("warning: temp %d over %d, cooling\n", temp,
|
|
CONFIG_HIGH_TEMP_COOL);
|
|
}
|
|
break;
|
|
case MESON_CPU_MAJOR_ID_TL1:
|
|
case MESON_CPU_MAJOR_ID_TM2:
|
|
sensornum = readl(AO_SEC_GP_CFG10);
|
|
sensornum = ((sensornum >> 24) & 0xf) >> 2;
|
|
while (1) {
|
|
r1p1_temp_read(1, &temp1);
|
|
r1p1_temp_read(2, &temp2);
|
|
temp = temp1 > temp2 ? temp1 : temp2;
|
|
if (sensornum == 0x3) {
|
|
r1p1_temp_read(3, &temp1);
|
|
temp = temp > temp1 ? temp : temp1;
|
|
}
|
|
if (temp <= CONFIG_HIGH_TEMP_COOL) {
|
|
printf("device cool done\n");
|
|
break;
|
|
}
|
|
mdelay(2000);
|
|
printf("warning: temp %d over %d, cooling\n", temp,
|
|
CONFIG_HIGH_TEMP_COOL);
|
|
}
|
|
break;
|
|
case MESON_CPU_MAJOR_ID_T5:
|
|
case MESON_CPU_MAJOR_ID_T5D:
|
|
while (1) {
|
|
r1p1_temp_read(1, &temp);
|
|
if (temp <= CONFIG_HIGH_TEMP_COOL) {
|
|
printf("device cool done\n");
|
|
break;
|
|
}
|
|
mdelay(2000);
|
|
printf("warning: temp %d over %d, cooling\n", temp,
|
|
CONFIG_HIGH_TEMP_COOL);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
static int do_boot_cooling(cmd_tbl_t *cmdtp, int flag1,
|
|
int argc, char * const argv[])
|
|
{
|
|
#if defined (CONFIG_HIGH_TEMP_COOL) && defined (R1P1_TSENSOR_MODE)
|
|
r1p1_temp_cooling();
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
U_BOOT_CMD(
|
|
boot_cooling, 5, 0, do_boot_cooling,
|
|
"cpu temp-system",
|
|
"boot_cooling pos"
|
|
);
|
|
|
|
U_BOOT_CMD(
|
|
write_trim, 5, 0, do_write_trim,
|
|
"cpu temp-system",
|
|
"write_trim data"
|
|
);
|
|
|
|
U_BOOT_CMD(
|
|
read_temp, 5, 0, do_read_temp,
|
|
"cpu temp-system",
|
|
"read_temp pos"
|
|
);
|
|
|
|
U_BOOT_CMD(
|
|
write_version, 5, 0, do_write_version,
|
|
"cpu temp-system",
|
|
"write_flag"
|
|
);
|
|
|
|
static char temp_trim_help_text[] =
|
|
"temp_triming x [ver]\n"
|
|
" - for manual trimming chip\n"
|
|
" - x: [decimal]the temperature of the chip surface\n"
|
|
" - [ver]: [decimal]only for New thermal sensor\n"
|
|
" BBT: OPS socket board, which can change chips\n"
|
|
" online: reference boards witch chip mounted\n"
|
|
" AXG or TXHD:\n"
|
|
" 5 (0101)b: BBT, thermal0\n"
|
|
" 6 (0110)b: BBT, thermal1\n"
|
|
" 7 (0111)b: BBT, thermal01\n"
|
|
" 13 (1101)b: online, thermal0\n"
|
|
" 14 (1110)b: online, thermal1\n"
|
|
" 15 (1111)b: online, thermal01\n"
|
|
" G12A or G12B:\n"
|
|
" 88 (10001000)b: BBT-SW, thermal1 thermal2, valid thermal cali data\n"
|
|
" 89 (10001001)b: BBT-OPS, thermal1 thermal2, valid thermal cali data\n"
|
|
" 8b (10001001)b: SLT, thermal1 thermal2, valid thermal cali data\n"
|
|
" TL1 or TM2:\n"
|
|
" 8c (10001001)b: BBT-SW, thermal1 ~ 3, valid thermal cali data\n"
|
|
" 8d (10001001)b: BBT-OPS, thermal1 ~ 3, valid thermal cali data\n"
|
|
" 8f (10001001)b: SLT, thermal1 ~ 3, valid thermal cali data\n";
|
|
|
|
U_BOOT_CMD(
|
|
temp_triming, 5, 1, do_temp_triming,
|
|
"cpu temp-system",
|
|
temp_trim_help_text
|
|
);
|
|
|
|
U_BOOT_CMD(
|
|
set_trim_base, 5, 1, do_set_trim_base,
|
|
"cpu temp-system",
|
|
"set triming base temp"
|
|
);
|