nt9856x/BSP/linux-kernel/drivers/soc/nvt/otp/otp_drv.c
2023-03-28 15:07:53 +08:00

925 lines
23 KiB
C
Executable File

#include <linux/wait.h>
#include <linux/param.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/uaccess.h>
#include <linux/clk.h>
#include "otp_drv.h"
//#include "otp_ioctl.h"
#include "otp_dbg.h"
#include "otp_platform.h"
#include <plat/top.h>
#include <plat/hardware.h>
#include <plat/efuse_protected.h>
/*===========================================================================*/
/* Function declaration */
/*===========================================================================*/
int nvt_ddr_arb_drv_wait_cmd_complete(PMODULE_INFO pmodule_info);
int nvt_ddr_arb_drv_ioctl(unsigned char if_id, MODULE_INFO *pmodule_info, unsigned int cmd, unsigned long arg);
void nvt_ddr_arb_drv_do_tasklet(unsigned long data);
irqreturn_t nvt_ddr_arb_drv_isr(int irq, void *devid);
irqreturn_t nvt_ddr_arb2_drv_isr(int irq, void *devid);
/*===========================================================================*/
/* Define */
/*===========================================================================*/
typedef irqreturn_t (*irq_handler_t)(int, void *);
static UINT32 ETH_BASE_ADDR = 0;
static UINT32 ARB1_BASE_ADDR = 0;
static UINT32 ARB2_BASE_ADDR = 0;
/*===========================================================================*/
/* Global variable */
/*===========================================================================*/
/*===========================================================================*/
/* Function define */
/*===========================================================================*/
#ifndef EFUSE_DDRP_LDO_TRIM_DATA
#if !defined(CONFIG_NVT_IVOT_PLAT_NA51089)
#define EFUSE_DDRP_LDO_TRIM_DATA EFUSE_DDRP_ZQ_TRIM_DATA
#endif
#endif
int nvt_otp_drv_open(PMODULE_INFO pmodule_info, unsigned char if_id)
{
nvt_dbg(IND, "%d\n", if_id);
/* Add HW Moduel initial operation here when the device file opened*/
return 0;
}
int nvt_otp_drv_release(PMODULE_INFO pmodule_info, unsigned char if_id)
{
nvt_dbg(IND, "%d\n", if_id);
/* Add HW Moduel release operation here when device file closed */
return 0;
}
int nvt_otp_drv_init(MODULE_INFO *pmodule_info)
{
int err = 0;
// init_waitqueue_head(&pmodule_info->xxx_wait_queue);
// spin_lock_init(&pmodule_info->xxx_spinlock);
// sema_init(&pmodule_info->xxx_sem, 1);
// init_completion(&pmodule_info->xxx_completion);
// tasklet_init(&pmodule_info->xxx_tasklet, nvt_ddr_arb_drv_do_tasklet, (unsigned long)pmodule_info);
/* allocate graphic resource here */
otp_platform_create_resource(pmodule_info);
//printk("%s: resource done\r\n", __func__);
/* initial clock here */
/* Add HW Module initialization here when driver loaded */
/* Add error handler here */
return err;
}
int nvt_otp_drv_remove(MODULE_INFO *pmodule_info)
{
/* Add HW Moduel release operation here*/
/* release OS resources */
otp_platform_release_resource();
return 0;
}
int nvt_otp_drv_suspend(MODULE_INFO *pmodule_info)
{
nvt_dbg(IND, "\n");
/* Add suspend operation here*/
return 0;
}
int nvt_otp_drv_resume(MODULE_INFO *pmodule_info)
{
nvt_dbg(IND, "\n");
/* Add resume operation here*/
return 0;
}
int nvt_otp_drv_ioctl(unsigned char if_id, MODULE_INFO *pmodule_info, unsigned int cmd, unsigned long arg)
{
int err = 0;
#if 0
int __user *argp = (int __user *)arg;
//nvt_dbg(IND, "IF-%d cmd:%x\n =>%08X", if_id, cmd,DDR_ARB_IOC_CHKSUM);
switch (cmd) {
case DDR_ARB_IOC_CHKSUM: {
ARB_CHKSUM param = {0};
if (unlikely(copy_from_user(&param, argp, sizeof(param)))) {
DBG_ERR("failed to copy_from_user\r\n");
return -EFAULT;
}
if (param.version != DDR_ARB_IOC_VERSION) {
DBG_ERR("version not matched kernel(%08X), user(%08X)\r\n", DDR_ARB_IOC_VERSION, param.version);
return -EFAULT;
}
param.sum = arb_chksum(param.ddr_id, param.phy_addr, param.len);
if (unlikely(copy_to_user(argp, &param, sizeof(param)))) {
DBG_ERR("failed to copy_to_user\r\n");
return -EFAULT;
}
} break;
}
#endif
return err;
}
#define REG_PHY_PAGE_SEL 0xFE
#define ZQK_OFFSET 0x110
#define TRIM_CLK_LDO_0_95_V 0xA8
#define TRIM_CLK_LDO_0_90_V 0xFC
#define TRIM_IOPAD_LDO_0_95_V 0x0A
#define TRIM_IOPAD_LDO_0_90_V 0x0F
#define LDO_STEP_CNT 16
#define RZQ_STEP_CNT 32
//ETH trim related
#define TX_TRIM_ROUT_CNT 8
#define TX_TRIM_DAC_CNT 32
#define TX_TRIM_RX_TX_SEC_CNT 8
const static CHAR *TX_TRIM_ROUT_DEFINE[TX_TRIM_ROUT_CNT] = {
" 100ohm",
" 106ohm (+6%)",
"113ohm (+13%)",
"124ohm (+24%)",
" 95ohm (-5%)",
" 92ohm (-8%)",
" 89ohm (-11%)",
" 86ohm (-14%)",
};
const static BOOL TX_TRIM_ROUT_AVAILABLE[TX_TRIM_ROUT_CNT] = {
1,
1,
1,
1,
1,
1,
1,
1,
};
const static CHAR *TX_TRIM_DAC_DEFINE[TX_TRIM_DAC_CNT] = {
" 50u (+0%)",
" 51u (+2%)",
" 52u (+4%)",
" 53u (+6%)",
" 54u (+8%)",
"55u (+10%)",
"56u (+12%)",
"57u (+14%)",
"58u (+16%)",
"59u (+18%)",
"60u (+20%)",
"61u (+22%)",
"62u (+24%)",
"63u (+26%)",
"64u (+28%)",
"65u (+30%)",
"34u (-32%)",
"35u (-30%)",
"36u (-28%)",
"37u (-26%)",
"38u (-24%)",
"39u (-22%)",
"40u (-20%)",
"41u (-18%)",
"42u (-16%)",
"43u (-14%)",
"44u (-12%)",
"45u (-10%)",
" 46u (-8%)",
" 47u (-6%)",
" 48u (-4%)",
" 49u (-2%)",
};
const static BOOL TX_TRIM_DAC_AVAILABLE[TX_TRIM_DAC_CNT] = {
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
0,
0,
0,
0,
0,
0,
0,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
};
//Reverse Notice
const static CHAR *TX_TRIM_RX_TX_SE_DEFINE[TX_TRIM_RX_TX_SEC_CNT] = {
"+20%",
"+13%",
" +6%",
" +0%",
" -5%",
"-10%",
"-15%",
"-20%",
};
const static BOOL TX_TRIM_RX_TX_SEL_AVAILABLE[TX_TRIM_RX_TX_SEC_CNT] = {
0,
1,
1,
1,
1,
1,
1,
1,
};
STATIC_ASSERT(sizeof(TX_TRIM_RX_TX_SE_DEFINE) / sizeof(UINT32) == (TX_TRIM_RX_TX_SEC_CNT));
STATIC_ASSERT(sizeof(TX_TRIM_RX_TX_SEL_AVAILABLE) / sizeof(UINT32) == (TX_TRIM_RX_TX_SEC_CNT));
STATIC_ASSERT(sizeof(TX_TRIM_ROUT_DEFINE) / sizeof(UINT32) == (TX_TRIM_ROUT_CNT));
STATIC_ASSERT(sizeof(TX_TRIM_ROUT_AVAILABLE) / sizeof(UINT32) == (TX_TRIM_ROUT_CNT));
STATIC_ASSERT(sizeof(TX_TRIM_DAC_DEFINE) / sizeof(UINT32) == (TX_TRIM_DAC_CNT));
STATIC_ASSERT(sizeof(TX_TRIM_DAC_AVAILABLE) / sizeof(UINT32) == (TX_TRIM_DAC_CNT));
const static CHAR *RZQ_STEP_NAME[RZQ_STEP_CNT] = {
"null",
"-15",
"-14",
"-13",
"-12",
"-11",
"-10",
" -9",
" -8",
" -7",
" -6",
" -5",
" -4",
" -3",
" -2",
" -1",
"default",
" +1",
" +2",
" +3",
" +4",
" +5",
" +6",
" +7",
" +8",
" +9",
"+10",
"+11",
"+12",
"+13",
"+14",
"+15",
};
const static UINT32 RZQ_STEP_EFUSE_VALUE[RZQ_STEP_CNT] = {
0x20,
0x1F,
0x1E,
0x1D,
0x1C,
0x1B,
0x1A,
0x19,
0x18,
0x17,
0x16,
0x15,
0x14,
0x13,
0x12,
0x11,
0x00,
0x01,
0x02,
0x03,
0x04,
0x05,
0x06,
0x07,
0x08,
0x09,
0x0A,
0x0B,
0x0C,
0x0D,
0x0E,
0x0F,
};
STATIC_ASSERT(sizeof(RZQ_STEP_NAME) / sizeof(UINT32) == (RZQ_STEP_CNT));
STATIC_ASSERT(sizeof(RZQ_STEP_EFUSE_VALUE) / sizeof(UINT32) == (RZQ_STEP_CNT));
#define INREG32(x) (*((volatile UINT32*)(x)))
#define OUTREG32(x, y) (*((volatile UINT32*)(x)) = (y))
static UINT32 io_read32(uintptr_t addr)
{
const volatile uintptr_t *ptr = (volatile uintptr_t *) addr;
const volatile UINT32 *ptr32 = (volatile UINT32 *)ptr;
return *ptr32;
}
static void io_write32(uintptr_t addr, UINT32 val)
{
volatile uintptr_t *ptr = (volatile uintptr_t *) addr;
volatile UINT32 *ptr32 = (volatile UINT32 *)ptr;
*ptr32 = val;
}
static uintptr_t phy_ahb_addr(int phy_id, UINT8 real_offset)
{
//const uintptr_t phy_base[] = {PHY_BASE_0, PHY_BASE_1};
if(phy_id == 0) {
return (ARB1_BASE_ADDR + ((uintptr_t)real_offset << 2));
} else {
return (ARB2_BASE_ADDR + ((uintptr_t)real_offset << 2));
}
}
static void phy_change_page(int phy_id, UINT8 target_page)
{
// static u8 current_page[PHY_NUMBER] = { -1 };
// static u8 current_page[PHY_NUMBER] = { -1, -1};
/* change page only if current page is different then target page */
//if (current_page[phy_id] != target_page) {
io_write32(phy_ahb_addr(phy_id, REG_PHY_PAGE_SEL), target_page);
//current_page[phy_id] = target_page;
//}
}
static UINT8 phy_page(UINT16 offset)
{
return (offset >> 8) & 0xF;
}
static UINT8 phy_real_offset(UINT16 offset)
{
return (UINT8)offset;
}
static UINT8 _phy_read(int phy_id, UINT8 page, UINT8 real_offset)
{
uintptr_t ahb_addr = phy_ahb_addr(phy_id, real_offset);
phy_change_page(phy_id, page);
return io_read32(ahb_addr);
}
static UINT32 bitCount(UINT32 data)
{
UINT32 count;
count = 0;
while(data)
{
data &= (data - 1);
count++;
}
return count;
}
static void emu_disp_bit_mask(UINT32 value, UINT32 mask)
{
UINT32 uiData = value & mask;
UINT32 uiBits;
UINT32 bitCnt = bitCount(mask);
for (uiBits = 0; uiBits < bitCnt; uiBits++) {
if (uiData & (1 << uiBits)) {
pr_cont("1");
} else {
pr_cont("0");
}
}
}
static UINT8 phy_mask_get(int phy_id, UINT16 offset, UINT8 mask)
{
UINT8 val;
UINT8 page = phy_page(offset);
UINT8 real_offset = phy_real_offset(offset);
// ddr_fatal(!phy_id_valid(phy_id), "phy_mask_get error: phy_id=%d\n",
// phy_id);
val = _phy_read(phy_id, page, real_offset) & mask;
// phy_io_dbg("phy_mask_get %d [0x%03x]=0x%02x\n", phy_id, offset, val);
return val;
}
//rx_tx_sel 0 -> RX, 1 -> TX
static void emu_disp_RX_TX_SEL_trim(UINT32 rx_tx_sel, UINT32 table_cnt, UINT32 trim, UINT32 reg)
{
UINT32 index;
UINT32 real_trim;
if(rx_tx_sel == 0) {
pr_info("RX_TRIM_SEL_RX reg [mention] trim\n");
} else {
pr_info("RX_TRIM_SEL_TX reg [mention] trim\n");
}
pr_info("=============================================\n");
for(index = 0; index < table_cnt; index ++) {
real_trim = table_cnt - index - 1;
if(reg == real_trim) {
pr_cont("---->");
} else {
pr_cont(" ");
}
emu_disp_bit_mask(index, 0x7);
pr_cont(" ");
pr_cont("%s", TX_TRIM_RX_TX_SE_DEFINE[index]);
if(TX_TRIM_RX_TX_SEL_AVAILABLE[index])
pr_cont("---------[O]");
else
pr_cont("---------[X]");
if(trim == real_trim) {
pr_cont("<=====");
} else {
pr_cont(" ");
}
pr_cont("\r\n");
}
pr_cont("=============================================\r\n");
}
//TX trim ROUT
static void emu_disp_TX_trim_DAC(UINT32 table_cnt, UINT32 trim, UINT32 reg)
{
UINT32 index;
pr_info("TX_trim_DAC reg [mention] trim\n");
pr_info("=============================================\n");
for(index = 0; index < table_cnt; index ++) {
if(reg == index) {
pr_cont("---->");
} else {
pr_cont(" ");
}
emu_disp_bit_mask(index, 0x1F);
pr_cont(" ");
pr_cont("%s", TX_TRIM_DAC_DEFINE[index]);
if(TX_TRIM_DAC_AVAILABLE[index])
pr_cont("---[O]");
else
pr_cont("---[X]");
if(trim == index) {
pr_cont("<=====");
} else {
pr_cont(" ");
}
pr_cont("\r\n");
}
pr_cont("=============================================\r\n");
}
//TX trim ROUT
static void emu_disp_TX_trim_ROUT(UINT32 table_cnt, UINT32 trim, UINT32 reg)
{
UINT32 index;
pr_info("=============================================\n");
pr_info("TX_trim_ROUT reg [mention] trim\r\n");
pr_info("=============================================\n");
for(index = 0; index < table_cnt; index ++) {
if(reg == index) {
pr_cont("---->");
} else {
pr_cont(" ");
}
emu_disp_bit_mask(index, 0x7);
pr_cont(" ");
pr_cont("%s", TX_TRIM_ROUT_DEFINE[index]);
if(TX_TRIM_ROUT_AVAILABLE[index])
pr_cont("---[O]");
else
pr_cont("---[X]");
if(trim == index) {
pr_cont("<=====");
} else {
pr_cont(" ");
}
pr_cont("\r\n");
}
pr_cont("=============================================\r\n");
}
static void emu_disp_zqk_trim_table(UINT32 phyID, UINT32 DDR_value, UINT32 trim, UINT32 table_cnt)
{
// UINT32 uiBits;
UINT32 index;
pr_cont("[DDR[%d] register] [rzq efuse trim] [Mention]\r\n", phyID);
pr_cont("==================================================\r\n");
for(index = 1; index < table_cnt; index ++) {
pr_cont(" ");
emu_disp_bit_mask(index, 0x1F);
if(DDR_value == index)
pr_cont("<===== ");
else
pr_cont(" ");
emu_disp_bit_mask(RZQ_STEP_EFUSE_VALUE[index], 0x1F);
if(trim == RZQ_STEP_EFUSE_VALUE[index])
pr_cont("<===== ");
else
pr_cont(" ");
pr_cont("%s", RZQ_STEP_NAME[index]);
pr_cont("\r\n");
}
pr_cont("==================================================\r\n");
}
static void emu_disp_ldo_trim(UINT32 phyID, UINT32 table_cnt, UINT32 trim)
{
// UINT32 uiBits;
UINT32 index;
pr_cont("[DDR[%d] LDO PLL trim] [LDO PLL]\r\n", phyID);
pr_cont("=======================================\r\n");
for(index = 0; index < table_cnt; index ++) {
if(index < 4) {
pr_cont(" %02x", index);
pr_cont(" ");
pr_cont("1.00V");
} else if(index >=4 && index <= 9) {
pr_cont(" %02x", index);
pr_cont(" ");
pr_cont("0.95V");
} else {
pr_cont(" %02x", index);
pr_cont(" ");
pr_cont("0.90V");
}
if(trim == index)
{
pr_cont("<======");
}
pr_cont("\r\n");
}
pr_cont("=======================================\r\n");
}
static void emu_disp_ldo_clk_iopd_trim(UINT32 phyID, UINT32 table_cnt, UINT32 trim)
{
UINT32 index;
pr_cont("[DDR[%d]LDO CLK(IO)trim] [LDO PLL]\r\n", phyID);
pr_cont("=======================================\r\n");
for(index = 0; index < table_cnt; index ++) {
if(index < 4) {
pr_cont(" %02x", index);
pr_cont(" ");
pr_cont("0.95V");
} else {
pr_cont(" %02x", index);
pr_cont(" ");
pr_cont("0.90V");
}
if(trim == index)
{
pr_cont("<======");
}
pr_cont("\r\n");
}
pr_cont("=======================================\r\n");
}
void trim_drvdump(void) {
INT32 trim;
UINT16 value;
UINT32 TX_TRIM_ROUT, TX_TRIM_DAC, TX_TRIM_SEL_RX, TX_TRIM_SEL_TX;
UINT32 REG_TX_TRIM_ROUT, REG_TX_TRIM_DAC, REG_TX_TRIM_SEL_RX, REG_TX_TRIM_SEL_TX;
UINT32 zqk;
UINT8 sum;
UINT8 page;
UINT8 real_offset;
UINT32 DDR2_EN;
UINT32 LDO_TRIM_VALUE;
UINT8 H_LDO, V_LDO;
UINT8 PLL_LDO;
UINT8 CLK_LDO;
UINT8 IOPAD_LDO;
ETH_BASE_ADDR = (UINT32)ioremap_nocache(NVT_ETH_BASE_PHYS, 0x4000);
ARB1_BASE_ADDR= (UINT32)ioremap_nocache(NVT_DDR1_PHY_BASE_PHYS, 0x800);
ARB2_BASE_ADDR= (UINT32)ioremap_nocache(NVT_DDR2_PHY_BASE_PHYS, 0x800);
if( nvt_get_chip_id() == CHIP_NA51084) {
trim = efuse_readParamOps(EFUSE_ETHERNET_TRIM_DATA, &value);
pr_info("####### Ethernet ######\n");
if(trim == E_OK) {
pr_info(" 0x3B74 = [0x%08x]\n", (int)INREG32(ETH_BASE_ADDR + 0x3B74));
pr_info(" 0x3B78 = [0x%08x]\n", (int)INREG32(ETH_BASE_ADDR + 0x3B78));
pr_info(" 0x3B68 = [0x%08x]\n", (int)INREG32(ETH_BASE_ADDR + 0x3B68));
TX_TRIM_ROUT = value & 0x7; // bit[2..0] all available
TX_TRIM_DAC = ((value >> 3) & 0x1F); // bit[7..3]
TX_TRIM_SEL_RX = ((value >> 8) & 0x7); // bit[10..8]
TX_TRIM_SEL_TX = ((value >>11) & 0x7); // bit[13..11]
//0xF02B3B74 bit[5..3]
REG_TX_TRIM_ROUT = (INREG32(ETH_BASE_ADDR + 0x3B74) >> 3) & 0x7;
//0xF02B3B78 bit[4..0]
REG_TX_TRIM_DAC = (INREG32(ETH_BASE_ADDR + 0x3B78) >> 0) & 0x1F;
//0xF02B3B68 bit[7..5]
REG_TX_TRIM_SEL_RX = (INREG32(ETH_BASE_ADDR + 0x3B68) >> 5) & 0x7;
//0xF02B3B68 bit[4..2]
REG_TX_TRIM_SEL_TX = (INREG32(ETH_BASE_ADDR + 0x3B68) >> 2) & 0x7;
emu_disp_TX_trim_ROUT(TX_TRIM_ROUT_CNT, TX_TRIM_ROUT, REG_TX_TRIM_ROUT);
emu_disp_TX_trim_DAC(TX_TRIM_DAC_CNT, TX_TRIM_DAC, REG_TX_TRIM_DAC);
emu_disp_RX_TX_SEL_trim(0, TX_TRIM_RX_TX_SEC_CNT, TX_TRIM_SEL_RX, REG_TX_TRIM_SEL_RX);
emu_disp_RX_TX_SEL_trim(1, TX_TRIM_RX_TX_SEC_CNT, TX_TRIM_SEL_TX, REG_TX_TRIM_SEL_TX);
if((TX_TRIM_ROUT == REG_TX_TRIM_ROUT) && (TX_TRIM_DAC == REG_TX_TRIM_DAC) && (TX_TRIM_SEL_RX == REG_TX_TRIM_SEL_RX) && (TX_TRIM_SEL_TX == REG_TX_TRIM_SEL_TX)) {
pr_info(" TX_TRIM_ROUT[0x%02x]=REG[0x%02x]\n", (int)TX_TRIM_ROUT, (int)REG_TX_TRIM_ROUT);
pr_info(" TX_TRIM_DAC[0x%02x]=REG[0x%02x]\n", (int)TX_TRIM_DAC, (int)REG_TX_TRIM_DAC);
pr_info("TX_TRIM_SEL_RX[0x%02x]=REG[0x%02x]\n", (int)TX_TRIM_SEL_RX, (int)REG_TX_TRIM_SEL_RX);
pr_info("TX_TRIM_SEL_TX[0x%02x]=REG[0x%02x]\n", (int)TX_TRIM_SEL_TX, (int)REG_TX_TRIM_SEL_TX);
pr_info(" *Eth Trim data range success 0x%08x\n", (int)value);
} else {
pr_info(" TX_TRIM_ROUT[0x%02x]!=REG[0x%02x]\n", (int)TX_TRIM_ROUT, (int)REG_TX_TRIM_ROUT);
pr_info(" TX_TRIM_DAC[0x%02x]!=REG[0x%02x]\n", (int)TX_TRIM_DAC, (int)REG_TX_TRIM_DAC);
pr_info("TX_TRIM_SEL_RX[0x%02x]!=REG[0x%02x]\n", (int)TX_TRIM_SEL_RX, (int)REG_TX_TRIM_SEL_RX);
pr_info("TX_TRIM_SEL_TX[0x%02x]!=REG[0x%02x]\n", (int)TX_TRIM_SEL_TX, (int)REG_TX_TRIM_SEL_TX);
}
pr_info("####### ZQK ######\n");
trim = efuse_readParamOps(EFUSE_DDRP_H_TRIM_DATA, &value);
if(trim == EFUSE_SUCCESS)
{
page = phy_page(ZQK_OFFSET);
real_offset = phy_real_offset(ZQK_OFFSET);
zqk = _phy_read(0, page, real_offset);
emu_disp_zqk_trim_table(0, zqk, value, RZQ_STEP_CNT);
pr_info("zqk trim[0] = [0x%08x]\r\n", (int)value);
pr_info(" zqk reg[0] = [0x%08x]\r\n", (int)zqk);
if(zqk & 0x10) {
if((zqk - value) != 0x10) {
pr_info(" !!!!rzq reg read back check error[1]!!!!\n");
} else {
pr_info(" rzq reg read back check success[1]\n");
}
} else {
sum = (value + zqk);
if(sum != 0x20) {
pr_info(" !!!!rzq reg read back check error[0] sum = 0x%02x!!!!\r\n", (int)sum);
} else {
pr_info(" rzq reg read back check success[0]\r\n");
}
}
}
else
{
pr_info(" !!!!RZQ DDR1 trim read error [%d]!!!!\r\n", trim);
}
#if 0
DDR2_EN = *(volatile UINT32 *)(ARB2_BASE_ADDR - 0x1000 + 4); //bit[5] = 1?
if((DDR2_EN & (1<<5)) == (1<<5)) {
trim = efuse_readParamOps(EFUSE_DDRP_V_TRIM_DATA, &value);
if(trim == EFUSE_SUCCESS)
{
page = phy_page(ZQK_OFFSET);
real_offset = phy_real_offset(ZQK_OFFSET);
zqk = _phy_read(1, page, real_offset);
emu_disp_zqk_trim_table(1, zqk, value, RZQ_STEP_CNT);
pr_info("zqk trim[1] = [0x%08x]\r\n", (int)value);
pr_info(" zqk reg[1] = [0x%08x]\r\n", (int)zqk);
if(zqk & 0x10) {
if((zqk - value) != 0x10) {
pr_info("!!!!rzq reg read back check error[1]!!!!\n");
} else {
pr_info(" rzq reg read back check success[1]\n");
}
} else {
sum = (value + zqk);
if(sum != 0x20) {
pr_info("!!!!rzq reg read back check error[0] sum = 0x%02x!!!!\n", (int)sum);
} else {
pr_info(" rzq reg read back check success[0]\n");
}
}
}
else
{
pr_info("!!!!RZQ DDR2 trim read error [%d]!!!!\n", trim);
}
}else {
pr_info("No DDR2 init\n");
}
#endif
}
pr_info("####### LDO ######\n");
trim = efuse_readParamOps(EFUSE_DDRP_LDO_TRIM_DATA, &value);
if(trim == EFUSE_SUCCESS)
{
pr_info("LDO Trim data read success\r\n");
LDO_TRIM_VALUE = (value & 0xFF);
H_LDO = (LDO_TRIM_VALUE & 0xF);
V_LDO = ((LDO_TRIM_VALUE & 0xF0) >> 4);
DDR2_EN = *(volatile UINT32 *)(ARB2_BASE_ADDR - 0x1000 + 4); //bit[5] = 1?
pr_info(" LDO Trim data range success LDO [%d] 0~31 H_LDO[%d], V_LDO[%d]\r\n", (int)LDO_TRIM_VALUE, (int)H_LDO, (int)V_LDO);
PLL_LDO = phy_mask_get(0, 0x0BF, 0x30); //get bit[5..4]
CLK_LDO = phy_mask_get(0, 0x0D8, 0xfc); //get bit[7..2]
IOPAD_LDO = phy_mask_get(0, 0x0D9, 0x0f); //get bit[3..0]
pr_info(" PLL_LDO register[0] = 0x%02x\r\n", (int)PLL_LDO);
if(PLL_LDO == 0x00) {
pr_info(" PLL_LDO = 1.05V => Error\r\n");
} else if(PLL_LDO == 0x10) {
pr_info(" PLL_LDO = 1.00V\r\n");
if(H_LDO > 4) {
pr_info(" PLL_LDO = 1.00V but trim > 4\r\n");
}
} else if(PLL_LDO == 0x20) {
pr_info(" PLL_LDO = 0.95V\r\n");
if(H_LDO < 4 || H_LDO > 9) {
pr_info(" PLL_LDO = 0.95V but trim < 4 or > 9\r\n");
}
} else if(PLL_LDO == 0x30) {
pr_info(" PLL_LDO = 0.90V\r\n");
if(H_LDO < 0xa) {
pr_info(" PLL_LDO = 0.90V but H_LDO < 0xa\r\n");
}
}
pr_info(" CLK_LDO register[0] = 0x%02x\r\n", (int)CLK_LDO);
if(CLK_LDO == TRIM_CLK_LDO_0_95_V) {
pr_info(" CLK_LDO = 0.95V\r\n");
if(H_LDO >= 4) {
pr_info(" CLK_LDO = 0.95V but trim >= 4\r\n");
}
} else if(CLK_LDO == TRIM_CLK_LDO_0_90_V) {
pr_info(" CLK_LDO = 0.90V\r\n");
if(H_LDO < 4) {
pr_info(" CLK_LDO = 0.90V but H_LDO < 4\r\n");
}
} else {
pr_info(" UNKNOW CLK_LDO\r\n");
}
pr_info(" IOPAD_LDO register[0] = 0x%02x\r\n", (int)IOPAD_LDO);
if(IOPAD_LDO == TRIM_IOPAD_LDO_0_95_V) {
pr_info(" IOPAD_LDO = 0.95V\r\n");
if(H_LDO >= 4) {
pr_info(" IOPAD_LDO = 0.95V but trim >= 4\r\n");
}
} else if(IOPAD_LDO == TRIM_IOPAD_LDO_0_90_V) {
pr_info(" IOPAD_LDO = 0.90V\r\n");
if(H_LDO < 4) {
pr_info(" IOPAD_LDO = 0.90V but H_LDO < 4\r\n");
}
} else {
pr_info(" UNKNOW IOPAD_LDO\r\n");
}
emu_disp_ldo_trim(0, LDO_STEP_CNT, H_LDO);
emu_disp_ldo_clk_iopd_trim(0, LDO_STEP_CNT, H_LDO);
if((DDR2_EN & (1<<5)) == (1<<5)) {
pr_info("DDR2 EN [0x%08x]\r\n", (int)DDR2_EN);
PLL_LDO = phy_mask_get(1, 0x0BF, 0x30); //get bit[5..4]
CLK_LDO = phy_mask_get(1, 0x0D8, 0xfc); //get bit[7..2]
IOPAD_LDO = phy_mask_get(1, 0x0D9, 0x0f); //get bit[3..0]
pr_info(" PLL_LDO register[1] = 0x%02x\r\n", (int)PLL_LDO);
if(PLL_LDO == 0x00) {
pr_info(" PLL_LDO = 1.05V => Error\r\n");
} else if(PLL_LDO == 0x10) {
pr_info(" PLL_LDO = 1.00V\r\n");
if(V_LDO > 4) {
pr_info(" PLL_LDO = 1.00V but trim > 4\r\n");
}
} else if(PLL_LDO == 0x20) {
pr_info(" PLL_LDO = 0.95V\r\n");
if(V_LDO < 4 || V_LDO > 9) {
pr_info(" PLL_LDO = 0.95V but trim < 4 or > 9\r\n");
}
} else if(PLL_LDO == 0x30) {
pr_info(" PLL_LDO = 0.90V\r\n");
if(V_LDO < 0xa) {
pr_info(" PLL_LDO = 0.90V but H_LDO < 0xa\r\n");
}
}
pr_info(" CLK_LDO register[1] = 0x%02x\r\n", (int)CLK_LDO);
if(CLK_LDO == TRIM_CLK_LDO_0_95_V) {
pr_info(" CLK_LDO = 0.95V\r\n");
if(V_LDO >= 4) {
pr_info(" CLK_LDO = 0.95V but trim >= 4\r\n");
}
} else if(CLK_LDO == TRIM_CLK_LDO_0_90_V) {
pr_info(" CLK_LDO = 0.90V\r\n");
if(V_LDO < 4) {
pr_info(" CLK_LDO = 0.90V but H_LDO < 4\r\n");
}
} else {
pr_info(" UNKNOW CLK_LDO\r\n");
}
pr_info(" IOPAD_LDO register[1] = 0x%02x\r\n", (int)IOPAD_LDO);
if(IOPAD_LDO == TRIM_IOPAD_LDO_0_95_V) {
pr_info(" IOPAD_LDO = 0.95V\r\n");
if(V_LDO >= 4) {
pr_info(" IOPAD_LDO = 0.95V but trim >= 4\r\n");
}
} else if(IOPAD_LDO == TRIM_IOPAD_LDO_0_90_V) {
pr_info(" IOPAD_LDO = 0.90V\r\n");
if(V_LDO < 4) {
pr_info(" IOPAD_LDO = 0.90V but H_LDO < 4\r\n");
}
} else {
pr_info(" UNKNOW IOPAD_LDO\r\n");
}
emu_disp_ldo_trim(1, LDO_STEP_CNT, V_LDO);
emu_disp_ldo_clk_iopd_trim(1, LDO_STEP_CNT, V_LDO);
}
}
}
iounmap((volatile void __iomem *)ETH_BASE_ADDR);
iounmap((volatile void __iomem *)ARB1_BASE_ADDR);
iounmap((volatile void __iomem *)ARB2_BASE_ADDR);
}
EXPORT_SYMBOL(trim_drvdump);