rk3368: add rockchip_get_temp function and

rockchip_get_leakage support for 3368
This commit is contained in:
guoyi
2015-03-27 11:07:02 +08:00
parent 41f97177a1
commit 873777cb8b
2 changed files with 178 additions and 3 deletions

View File

@@ -10,11 +10,32 @@
#include <linux/delay.h>
#include <linux/rockchip/cpu.h>
#include <linux/rockchip/iomap.h>
#include <linux/cpuidle.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/smp.h>
#include <linux/slab.h>
#include <linux/reboot.h>
#include <linux/pm.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <uapi/linux/psci.h>
#include <asm/compiler.h>
#include <asm/cpu_ops.h>
#include <asm/errno.h>
#include <asm/psci.h>
#include <asm/smp_plat.h>
#include <asm/suspend.h>
#include <asm/system_misc.h>
#ifdef CONFIG_ARM
#include <asm/system_info.h>
#endif
#include "efuse.h"
#define efuse_readl(offset) readl_relaxed(RK_EFUSE_VIRT + offset)
#define efuse_writel(val, offset) writel_relaxed(val, RK_EFUSE_VIRT + offset)
@@ -22,12 +43,144 @@ static u8 efuse_buf[32] = {};
struct rockchip_efuse {
int (*get_leakage)(int ch);
int (*get_temp)(int ch);
int efuse_version;
int process_version;
};
static struct rockchip_efuse efuse;
/****************************secure reg access****************************/
#define SEC_REG_RW_SHT (0x0)
#define SEC_REG_RD (0x0)
#define SEC_REG_WR (0x1)
#define SEC_REG_BITS_SHT (0x1)
#define SEC_REG_32 (0x0)
#define SEC_REG_64 (0x2)
#define SEC_REG_RD_32 (SEC_REG_RD | SEC_REG_32)
#define SEC_REG_RD_64 (SEC_REG_RD | SEC_REG_64)
#define SEC_REG_WR_32 (SEC_REG_WR | SEC_REG_32)
#define SEC_REG_WR_64 (SEC_REG_WR | SEC_REG_64)
#define PSCI_OS_ACCESS_REG (0xba00ffb0)
#define EFUSE_BASE 0xffb00000
/*
* arg2: rd/wr control, bit[0] 0-rd 1-rt, bit[1] 0-32bit, 1-64bit
* arg1: base addr
* arg0: read or write val
* function_id: return fail/succes
*/
noinline int __invoke_reg_access_fn_hvc(u64 function_id, u64 arg0, u64 arg1, u64 arg2, u64 *val)
{
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
__asmeq("%2", "x2")
__asmeq("%3", "x3")
"hvc #0\n"
: "+r" (function_id), "+r" (arg0)
: "r" (arg1), "r" (arg2));
if(!(arg2 & SEC_REG_WR))
*val = arg0;
return function_id;
}
noinline int __invoke_reg_wr_fn_smc(u64 function_id, u64 arg0, u64 arg1, u64 arg2)
{
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
__asmeq("%2", "x2")
__asmeq("%3", "x3")
"smc #0\n"
: "+r" (function_id) ,"+r" (arg0)
: "r" (arg1), "r" (arg2));
return function_id;
}
noinline int __invoke_reg_rd_fn_smc(u64 function_id, u64 arg0, u64 arg1,
u64 arg2, u64 *val)
{
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
__asmeq("%2", "x2")
__asmeq("%3", "x3")
"smc #0\n"
: "+r" (function_id) ,"+r" (arg0)
: "r" (arg1), "r" (arg2));
*val = arg0;
return function_id;
}
int (*invoke_regs_wr_fn)(u64, u64 , u64, u64) = __invoke_reg_wr_fn_smc;
int (*invoke_regs_rd_fn)(u64, u64 , u64, u64, u64 *) = __invoke_reg_rd_fn_smc;
int secure_regs_rd(u64 addr_phy)
{
u64 val_64;
u32 val;
int ret;
ret = invoke_regs_rd_fn(PSCI_OS_ACCESS_REG, 0, addr_phy, SEC_REG_RD_32, &val_64);
val = val_64;
return val;
}
int secure_regs_wr_32(u64 addr_phy, u32 val)
{
u64 val_64 = val;
return invoke_regs_wr_fn(PSCI_OS_ACCESS_REG, val_64, addr_phy, SEC_REG_WR_32);
}
static int __init rk3368_efuse_readregs(u32 addr, u32 length, u8 *buf)
{
int ret = length;
if (!length)
return 0;
if (!buf)
return 0;
secure_regs_wr_32(EFUSE_BASE+REG_EFUSE_CTRL , EFUSE_CSB);
secure_regs_wr_32(EFUSE_BASE+REG_EFUSE_CTRL , EFUSE_LOAD | EFUSE_PGENB);
udelay(2);
do {
secure_regs_wr_32(EFUSE_BASE+REG_EFUSE_CTRL ,
secure_regs_rd(EFUSE_BASE+REG_EFUSE_CTRL) &
(~(EFUSE_A_MASK << EFUSE_A_SHIFT)));
secure_regs_wr_32(EFUSE_BASE+REG_EFUSE_CTRL,
secure_regs_rd(EFUSE_BASE+REG_EFUSE_CTRL) |
((addr & EFUSE_A_MASK) << EFUSE_A_SHIFT));
udelay(2);
secure_regs_wr_32(EFUSE_BASE+REG_EFUSE_CTRL ,
secure_regs_rd(EFUSE_BASE+REG_EFUSE_CTRL) | EFUSE_STROBE);
udelay(2);
*buf = secure_regs_rd(EFUSE_BASE+REG_EFUSE_DOUT);
secure_regs_wr_32(EFUSE_BASE+REG_EFUSE_CTRL ,
secure_regs_rd(EFUSE_BASE+REG_EFUSE_CTRL) & (~EFUSE_STROBE));
udelay(2);
buf++;
addr++;
} while (--length);
udelay(2);
secure_regs_wr_32(EFUSE_BASE+REG_EFUSE_CTRL ,
secure_regs_rd(EFUSE_BASE+REG_EFUSE_CTRL) | EFUSE_CSB);
udelay(1);
return ret;
}
static int __init rk3288_efuse_readregs(u32 addr, u32 length, u8 *buf)
{
int ret = length;
@@ -150,15 +303,36 @@ int rockchip_process_version(void)
int rockchip_get_leakage(int ch)
{
if (efuse.get_leakage)
return efuse.get_leakage(ch);
int ret = 0;
if (efuse.get_leakage){
return efuse.get_leakage(ch);
}else{
ret = rk3368_efuse_readregs(0,32,efuse_buf);
if (ret == 32){
return efuse_buf[23+ch];
}
}
return 0;
}
int rockchip_get_temp(int ch)
{
int ret = 0;
int temp = 0;
ret = rk3368_efuse_readregs(0,32,efuse_buf);
if (ret == 32){
temp = efuse_buf[31+ch];
if(efuse_buf[31+ch] & 0x80)
{
temp = -(efuse_buf[31+ch] & 0x7f);
}
return temp;
}
return 0;
}
void __init rockchip_efuse_init(void)
{
int ret;
if (cpu_is_rk3288()) {
ret = rk3288_efuse_readregs(0, 32, efuse_buf);
if (ret == 32) {

View File

@@ -28,4 +28,5 @@
int rockchip_efuse_version(void);
int rockchip_process_version(void);
int rockchip_get_leakage(int ch);
int rockchip_get_temp(int ch);
#endif