mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
rk3368: add rockchip_get_temp function and
rockchip_get_leakage support for 3368
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user