| #include <linux/kernel.h> |
| #include <linux/of.h> |
| #include <linux/of_address.h> |
| #include <linux/io.h> |
| #include <asm/cacheflush.h> |
| #include <asm/uaccess.h> |
| #include <asm/io.h> |
| //#include <mt-plat/sync_write.h> |
| //#include <mt-plat/mtk_io.h> |
| //#include "x_hal_io.h" |
| //#include "x_hal_5381.h" |
| #include "mtk_typedefs.h" |
| #include "core_plf_init.h" |
| #include "mtk_emi_bm.h" |
| #include "mtk_dramc.h" |
| #include "met_drv.h" |
| #include "interface.h" |
| |
| #define IOMEM(x) ((void __force __iomem *)(x)) |
| |
| #define mt_reg_sync_writel(v, a) \ |
| do { \ |
| __raw_writel((v), (void __force __iomem *)((a))); \ |
| mb(); \ |
| } while (0) |
| |
| #if 0 |
| #undef MET_BOOT_MSG |
| #if defined(MET_BOOT_MSG) |
| extern char met_boot_msg_tmp[256]; |
| extern int pr_bootmsg(int str_len, char *str); |
| #define PR_BOOTMSG(fmt, args...) { \ |
| int str_len = snprintf(met_boot_msg_tmp, sizeof(met_boot_msg_tmp), \ |
| fmt, ##args); \ |
| pr_bootmsg(str_len, met_boot_msg_tmp); } |
| #define PR_BOOTMSG_ONCE(fmt, args...) { \ |
| static int once; \ |
| if (!once) { \ |
| int str_len = snprintf(met_boot_msg_tmp, \ |
| sizeof(met_boot_msg_tmp), \ |
| fmt, ##args); \ |
| pr_bootmsg(str_len, met_boot_msg_tmp); \ |
| once = 1; \ |
| } } |
| #else |
| #define pr_bootmsg(str_len, str) |
| #define PR_BOOTMSG(fmt, args...) |
| #define PR_BOOTMSG_ONCE(fmt, args...) |
| #endif |
| #endif |
| |
| //static unsigned long gEMIBaseAddr = EMI_REG_BASE; |
| |
| |
| /* MET internal define */ |
| #ifndef DRAMC0_NAO_BASE |
| #define DRAMC0_NAO_BASE (IO_VIRT + 0x204000) |
| #endif |
| #ifndef DRAMC1_NAO_BASE |
| #define DRAMC1_NAO_BASE (IO_VIRT + 0x20C000) |
| #endif |
| #ifndef DRAMC2_NAO_BASE |
| #define DRAMC2_NAO_BASE (IO_VIRT + 0x214000) |
| #endif |
| #ifndef DRAMC3_NAO_BASE |
| #define DRAMC3_NAO_BASE (IO_VIRT + 0x21C000) |
| #endif |
| static unsigned long gDRAMCBaseAddr[] = |
| { |
| DRAMC0_NAO_BASE, |
| DRAMC1_NAO_BASE, |
| DRAMC2_NAO_BASE, |
| DRAMC3_NAO_BASE, |
| }; |
| |
| #define MX_DRAMC_CHAN_NR (sizeof(gDRAMCBaseAddr)/sizeof(gDRAMCBaseAddr[0])) |
| |
| /* GET EMI Base Address */ |
| #if 0 |
| unsigned long get_emi_base_addr(void) |
| { |
| return gEMIBaseAddr; |
| } |
| #endif |
| |
| unsigned long get_dram_nao_base_addr(int idx) |
| { |
| if (idx >= MX_DRAMC_CHAN_NR) { |
| METERROR("Invalid DRAMC idx: %d !\n", idx); |
| PR_BOOTMSG_ONCE("Invalid DRAMC idx: %d !\n", idx); |
| return 0; |
| } |
| return gDRAMCBaseAddr[idx]; |
| } |
| |
| #undef DEBUG |
| #undef debug_reg |
| |
| #ifdef debug_reg |
| static inline unsigned int emi_readl(void __iomem *padr) |
| { |
| unsigned int tmp; |
| |
| tmp = readl(padr); |
| MET_TRACE("[MET_EMI] RD_Reg: %p: %08x\n", padr, tmp); |
| return tmp; |
| } |
| |
| static inline void __emi_reg_sync_writel(unsigned int data, void __iomem *padr) |
| { |
| unsigned int tmp; |
| |
| mt_reg_sync_writel(data, padr); |
| tmp = readl(padr); |
| MET_TRACE("[MET_EMI] WR_Reg: %p: %08x, %08x\n", padr, data, tmp); |
| } |
| |
| #define emi_reg_sync_writel(data, adr) __emi_reg_sync_writel(data, IOMEM(adr)) |
| |
| #else |
| #define emi_readl readl |
| #define emi_reg_sync_writel mt_reg_sync_writel |
| #endif |
| |
| #define MASK_MASTER 0xFF |
| #define MASK_TRANS_TYPE 0xFF |
| |
| static void __iomem *BaseAddrEMI; |
| static void __iomem *BaseAddrDRAMC0; |
| static void __iomem *BaseAddrDRAMC1; |
| static void __iomem *BaseAddrDRAMC2; |
| static void __iomem *BaseAddrDRAMC3; |
| static void __iomem *AddrDramDatarate; |
| |
| /* |
| * MET_REG_BSET/MET_REG_BCLR: |
| * reading value before set and clear |
| */ |
| static inline void MET_REG_BSET(unsigned long reg, u32 shift) |
| { |
| volatile unsigned int read_val = 0; |
| |
| read_val = emi_readl(IOMEM(reg)); |
| emi_reg_sync_writel(read_val | (1<<shift), reg); |
| } |
| |
| static inline void MET_REG_BCLR(unsigned long reg, u32 shift) |
| { |
| volatile unsigned int read_val = 0; |
| |
| read_val = emi_readl(IOMEM(reg)); |
| emi_reg_sync_writel(read_val & (~((1<<shift) & 0xFFFFFFFF)), reg); |
| } |
| |
| #define GET_EMI_FROM_DTS |
| //#undef GET_EMI_FROM_DTS |
| |
| int MET_BM_Init(void) |
| { |
| #ifdef GET_EMI_FROM_DTS |
| struct device_node *node; |
| |
| /* Device Tree Path */ |
| node = of_find_compatible_node(NULL, NULL, of_emi_desc); |
| if (!node) { |
| METINFO("node of_emi_desc not found\n"); |
| PR_BOOTMSG_ONCE("node of_emi_desc not found\n"); |
| return -1; |
| } |
| |
| BaseAddrEMI = (void *)of_iomap(node, 0); |
| #else |
| BaseAddrEMI = (void*)get_emi_base_addr(); |
| #endif |
| if (BaseAddrEMI == 0) { |
| METERROR("BaseAddrEMI = 0\n"); |
| PR_BOOTMSG_ONCE("BaseAddrEMI = 0\n"); |
| return -1; |
| } |
| METINFO("MET EMI: map emi to %p\n", BaseAddrEMI); |
| PR_BOOTMSG("MET EMI: map emi to %p\n", BaseAddrEMI); |
| |
| #ifdef GET_EMI_FROM_DTS |
| /* DRAMC TBD */ |
| /* MAP NAO (NON-AO) DRAMC address */ |
| node = of_find_compatible_node(NULL, NULL, of_dramc_desc); |
| if (!node) { |
| METINFO("node of_dramc_desc not found\n"); |
| PR_BOOTMSG_ONCE("node of_dramc_desc not found\n"); |
| return -1; |
| } |
| BaseAddrDRAMC0 = (void *)of_iomap(node, 0); |
| BaseAddrDRAMC1 = (void *)of_iomap(node, 1); |
| BaseAddrDRAMC2 = (void *)of_iomap(node, 2); |
| BaseAddrDRAMC3 = (void *)of_iomap(node, 3); |
| #else |
| BaseAddrDRAMC0 = (void *) get_dram_nao_base_addr(0); |
| BaseAddrDRAMC1 = (void *) get_dram_nao_base_addr(1); |
| BaseAddrDRAMC2 = (void *) get_dram_nao_base_addr(2); |
| BaseAddrDRAMC3 = (void *) get_dram_nao_base_addr(3); |
| #endif |
| |
| AddrDramDatarate = ioremap_nocache(0x10100000, 0x1000); |
| if (AddrDramDatarate == NULL) { |
| pr_err("ioremap AddrDramDatarate fail ...\n"); |
| return -1; |
| } |
| |
| if (BaseAddrDRAMC0 == 0 |
| || BaseAddrDRAMC1 == 0 |
| || BaseAddrDRAMC2 == 0 |
| || BaseAddrDRAMC3 == 0 |
| ) { |
| METERROR("BaseAddrDRAMC0 = %p\n", BaseAddrDRAMC0); |
| METERROR("BaseAddrDRAMC1 = %p\n", BaseAddrDRAMC1); |
| METERROR("BaseAddrDRAMC2 = %p\n", BaseAddrDRAMC2); |
| METERROR("BaseAddrDRAMC3 = %p\n", BaseAddrDRAMC3); |
| PR_BOOTMSG_ONCE("BaseAddrDRAMC0 = %p\n", BaseAddrDRAMC0); |
| PR_BOOTMSG_ONCE("BaseAddrDRAMC1 = %p\n", BaseAddrDRAMC1); |
| PR_BOOTMSG_ONCE("BaseAddrDRAMC2 = %p\n", BaseAddrDRAMC2); |
| PR_BOOTMSG_ONCE("BaseAddrDRAMC3 = %p\n", BaseAddrDRAMC3); |
| return -1; |
| } |
| METINFO("MET EMI: map nao dramcA to %p\n", BaseAddrDRAMC0); |
| METINFO("MET EMI: map nao dramcB to %p\n", BaseAddrDRAMC1); |
| METINFO("MET EMI: map nao dramcC to %p\n", BaseAddrDRAMC2); |
| METINFO("MET EMI: map nao dramcD to %p\n", BaseAddrDRAMC3); |
| PR_BOOTMSG("MET EMI: map nao dramcA to %p\n", BaseAddrDRAMC0); |
| PR_BOOTMSG("MET EMI: map nao dramcB to %p\n", BaseAddrDRAMC1); |
| PR_BOOTMSG("MET EMI: map nao dramcC to %p\n", BaseAddrDRAMC2); |
| PR_BOOTMSG("MET EMI: map nao dramcD to %p\n", BaseAddrDRAMC3); |
| return 0; |
| } |
| |
| void MET_BM_DeInit(void) |
| { |
| } |
| |
| void MET_BM_Enable(const unsigned int enable) |
| { |
| volatile unsigned long int value_check; |
| int i = 0; |
| |
| while (i < 100) { |
| |
| if (enable == 0) { |
| /* SET BIT IDLE */ |
| MET_REG_BSET(ADDR_EMI+EMI_BMEN, BUS_MON_IDLE_SHIFT); |
| |
| /* CLR BIT EN */ |
| MET_REG_BCLR(ADDR_EMI+EMI_BMEN, BUS_MON_EN_SHIFT); |
| |
| /* CLR BIT IDLE */ |
| MET_REG_BCLR(ADDR_EMI+EMI_BMEN, BUS_MON_IDLE_SHIFT); |
| } else { |
| /* CLR BIT IDLE */ |
| MET_REG_BCLR(ADDR_EMI+EMI_BMEN, BUS_MON_IDLE_SHIFT); |
| |
| /* SET BIT EN */ |
| MET_REG_BSET(ADDR_EMI+EMI_BMEN, BUS_MON_EN_SHIFT); |
| } |
| |
| value_check = emi_readl(IOMEM(ADDR_EMI+EMI_BMEN)); |
| |
| if (enable == 0) { |
| /* EN == 0, IDLE == 0 when EMI RESET*/ |
| if (!test_bit(BUS_MON_EN_SHIFT, &value_check) |
| && !test_bit(BUS_MON_IDLE_SHIFT, &value_check)) { |
| break; |
| } |
| } else { |
| /* EN == 1, IDLE == 0 when EMI START*/ |
| if (test_bit(BUS_MON_EN_SHIFT, &value_check) |
| && !test_bit(BUS_MON_IDLE_SHIFT, &value_check)) { |
| break; |
| } |
| } |
| i++; |
| } |
| for (i = 0; i < MX_DRAMC_CHAN_NR; i++) { |
| if (enable == 0) |
| /* Disable Dramc Bus Monitor */ |
| MET_DRAMC_BMEnable(i, 0); |
| else |
| /* Enable Dramc Bus Monitor */ |
| MET_DRAMC_BMEnable(i, 1); |
| } |
| /*MET_TRACE("[MET_BM_ENABLE] value_check: %lx, enable = %d\n", value_check, enable);*/ |
| |
| } |
| |
| void MET_BM_Pause(void) |
| { |
| int i = 0; |
| const unsigned int value = emi_readl(IOMEM(ADDR_EMI+EMI_BMEN)); |
| |
| emi_reg_sync_writel(value | (1<<BUS_MON_PAUSE_SHIFT), ADDR_EMI+EMI_BMEN); |
| for (i = 0; i < MX_DRAMC_CHAN_NR; i++) { |
| /* Pause Dramc Bus Monitor */ |
| MET_DRAMC_BMPause(i, 1); |
| } |
| } |
| |
| void MET_BM_Continue(void) |
| { |
| int i = 0; |
| const unsigned int value = emi_readl(IOMEM(ADDR_EMI+EMI_BMEN)); |
| |
| emi_reg_sync_writel(value & (~(1<<BUS_MON_PAUSE_SHIFT)), ADDR_EMI+EMI_BMEN); |
| for (i = 0; i < MX_DRAMC_CHAN_NR; i++) { |
| /* Enable Dramc Bus Monitor */ |
| MET_DRAMC_BMPause(i, 0); |
| } |
| } |
| |
| unsigned int MET_BM_IsOverrun(void) |
| { |
| /* |
| * return 0 if EMI_BCNT(bus cycle counts) or |
| * EMI_WACT(total word counts) is overrun, |
| * otherwise return an !0 value |
| */ |
| const unsigned int value = emi_readl(IOMEM(ADDR_EMI+EMI_BMEN)); |
| |
| return (value & (1<<BC_OVERRUN_SHIFT)); |
| } |
| |
| unsigned int MET_BM_GetReadWriteType(void) |
| { |
| const unsigned int value = emi_readl(IOMEM(ADDR_EMI+EMI_BMEN)); |
| |
| return ((value & 0xFFFFFFCF) >> 4); |
| } |
| |
| void MET_BM_SetReadWriteType(const unsigned int ReadWriteType) |
| { |
| const unsigned int value = emi_readl(IOMEM(ADDR_EMI+EMI_BMEN)); |
| |
| /* |
| * ReadWriteType: 00/11 --> both R/W |
| * 01 --> only R |
| * 10 --> only W |
| */ |
| emi_reg_sync_writel((value & 0xFFFFFFCF) | (ReadWriteType << 4), ADDR_EMI+EMI_BMEN); |
| } |
| |
| int MET_BM_GetBusCycCount(void) |
| { |
| return MET_BM_IsOverrun() ? BM_ERR_OVERRUN : emi_readl(IOMEM(ADDR_EMI+EMI_BCNT));/*Bus cycle counter*/ |
| } |
| |
| unsigned int MET_BM_GetTransAllCount(void) |
| { |
| return emi_readl(IOMEM(ADDR_EMI+EMI_TACT)); |
| } |
| |
| int MET_BM_GetTransCount(const unsigned int counter_num) |
| { |
| unsigned int iCount; |
| |
| switch (counter_num) { |
| case 1: |
| iCount = emi_readl(IOMEM(ADDR_EMI+EMI_TSCT)); |
| break; |
| |
| case 2: |
| iCount = emi_readl(IOMEM(ADDR_EMI+EMI_TSCT2)); |
| break; |
| |
| case 3: |
| iCount = emi_readl(IOMEM(ADDR_EMI+EMI_TSCT3)); |
| break; |
| |
| default: |
| return BM_ERR_WRONG_REQ; |
| } |
| |
| return iCount; |
| } |
| |
| int MET_BM_GetWordAllCount(void) |
| { |
| return MET_BM_IsOverrun() ? BM_ERR_OVERRUN : emi_readl(IOMEM(ADDR_EMI+EMI_WACT)); |
| } |
| |
| int MET_BM_GetWordCount(const unsigned int counter_num) |
| { |
| unsigned int iCount; |
| |
| switch (counter_num) { |
| case 1: |
| iCount = emi_readl(IOMEM(ADDR_EMI+EMI_WSCT)); |
| break; |
| |
| case 2: |
| iCount = emi_readl(IOMEM(ADDR_EMI+EMI_WSCT2)); |
| break; |
| |
| case 3: |
| iCount = emi_readl(IOMEM(ADDR_EMI+EMI_WSCT3)); |
| break; |
| |
| case 4: |
| iCount = emi_readl(IOMEM(ADDR_EMI+EMI_WSCT4)); |
| break; |
| |
| default: |
| return BM_ERR_WRONG_REQ; |
| } |
| |
| return iCount; |
| } |
| |
| unsigned int MET_BM_GetBandwidthWordCount(void) |
| { |
| return emi_readl(IOMEM(ADDR_EMI+EMI_BACT));/*Bandwidth counter for access*/ |
| } |
| |
| unsigned int MET_BM_GetOverheadWordCount(void) |
| { |
| return emi_readl(IOMEM(ADDR_EMI+EMI_BSCT));/*Overhead counter*/ |
| } |
| |
| int MET_BM_GetTransTypeCount(const unsigned int counter_num) |
| { |
| return (counter_num < 1 || counter_num > BM_COUNTER_MAX) |
| ? BM_ERR_WRONG_REQ : emi_readl(IOMEM(ADDR_EMI+EMI_TTYPE1 + (counter_num - 1) * 8)); |
| } |
| |
| int MET_BM_GetMDCT(void) |
| { |
| return emi_readl(IOMEM(ADDR_EMI+EMI_MDCT)); |
| } |
| |
| int MET_BM_GetMDCT_2(void) |
| { |
| return emi_readl(IOMEM(ADDR_EMI+EMI_MDCT_2ND)); |
| } |
| |
| int MET_BM_SetMDCT_MDMCU(unsigned int mdmcu_rd_buf) |
| { |
| volatile unsigned int value_origin; |
| |
| value_origin = emi_readl(IOMEM(ADDR_EMI+EMI_MDCT_2ND)); |
| MET_TRACE("[MET_BM_SetMDCT_MDMCU] value_origin: %x\n", value_origin); |
| |
| value_origin = value_origin & ~(0x7); |
| value_origin = value_origin | ((mdmcu_rd_buf)&0x7); |
| |
| emi_reg_sync_writel(value_origin, ADDR_EMI+EMI_MDCT_2ND); |
| |
| return BM_REQ_OK; |
| } |
| |
| |
| int MET_BM_GetMonitorCounter(const unsigned int counter_num, |
| unsigned int *master, |
| unsigned int *trans_type) |
| { |
| unsigned int value, addr; |
| |
| if (counter_num < 1 || counter_num > BM_COUNTER_MAX) |
| return BM_ERR_WRONG_REQ; |
| |
| |
| if (counter_num == 1) { |
| addr = EMI_BMEN; |
| value = emi_readl(IOMEM(ADDR_EMI+addr)); |
| *master = (value>>16) & MASK_MASTER; |
| *trans_type = (value>>24) & MASK_TRANS_TYPE; |
| } else { |
| addr = (counter_num <= 3) ? |
| EMI_MSEL : (EMI_MSEL2 + (counter_num / 2 - 2) * 8); |
| value = emi_readl(IOMEM(ADDR_EMI+addr)) >> ((counter_num % 2) * 16); |
| *master = value & MASK_MASTER; |
| *trans_type = (value>>8) & MASK_TRANS_TYPE; |
| } |
| |
| return BM_REQ_OK; |
| } |
| |
| int MET_BM_SetMonitorCounter(const unsigned int counter_num, |
| const unsigned int master, |
| const unsigned int trans_type) |
| { |
| unsigned int value, addr; |
| const unsigned int iMask = (MASK_TRANS_TYPE << 8) | MASK_MASTER; |
| |
| if (counter_num < 1 || counter_num > BM_COUNTER_MAX) |
| return BM_ERR_WRONG_REQ; |
| |
| |
| if (counter_num == 1) { |
| addr = EMI_BMEN; |
| value = (emi_readl(IOMEM(ADDR_EMI+addr)) & ~(iMask << 16)) | |
| ((trans_type & MASK_TRANS_TYPE) << 24) | |
| ((master & MASK_MASTER) << 16); |
| } else { |
| addr = (counter_num <= 3) ? |
| EMI_MSEL : (EMI_MSEL2 + (counter_num / 2 - 2) * 8); |
| |
| /* clear master and transaction type fields */ |
| value = emi_readl(IOMEM(ADDR_EMI+addr)) & ~(iMask << ((counter_num % 2) * 16)); |
| |
| /* set master and transaction type fields */ |
| value |= (((trans_type & MASK_TRANS_TYPE) << 8) | |
| (master & MASK_MASTER)) << |
| ((counter_num % 2) * 16); |
| } |
| |
| emi_reg_sync_writel(value, ADDR_EMI+addr); |
| |
| return BM_REQ_OK; |
| } |
| |
| int MET_BM_SetTtypeCounterRW(unsigned int bmrw0_val, unsigned int bmrw1_val) |
| { |
| |
| volatile unsigned int value_origin; |
| |
| value_origin = emi_readl(IOMEM(ADDR_EMI+EMI_BMRW0)); |
| MET_TRACE("[MET_EMI_settype1] value_origin: %x\n", value_origin); |
| if (value_origin != bmrw0_val) { |
| emi_reg_sync_writel(bmrw0_val, ADDR_EMI+EMI_BMRW0); |
| MET_TRACE("[MET_EMI_settype1] bmrw0_val: %x, value_origin: %x\n", bmrw0_val, value_origin); |
| } |
| |
| |
| value_origin = emi_readl(IOMEM(ADDR_EMI+EMI_BMRW1)); |
| MET_TRACE("[MET_EMI_settype2] value_origin: %x\n", value_origin); |
| if (value_origin != bmrw1_val) { |
| emi_reg_sync_writel(bmrw1_val, ADDR_EMI+EMI_BMRW1); |
| MET_TRACE("[MET_EMI_settype2] bmrw0_val: %x, value_origin: %x\n", bmrw1_val, value_origin); |
| |
| } |
| return BM_REQ_OK; |
| } |
| |
| int MET_BM_Set_WsctTsct_id_sel(unsigned int counter_num, unsigned int enable) |
| { |
| unsigned int value; |
| |
| if (counter_num > 3) |
| return BM_ERR_WRONG_REQ; |
| |
| value = ((emi_readl(IOMEM(ADDR_EMI+EMI_BMEN2)) & (~(1 << (28+counter_num)))) | (enable << (28+counter_num))); |
| emi_reg_sync_writel(value, ADDR_EMI+EMI_BMEN2); |
| |
| return BM_REQ_OK; |
| } |
| |
| int MET_BM_SetMaster(const unsigned int counter_num, const unsigned int master) |
| { |
| unsigned int value, addr; |
| const unsigned int iMask = 0x7F; |
| |
| if (counter_num < 1 || counter_num > BM_COUNTER_MAX) |
| return BM_ERR_WRONG_REQ; |
| |
| |
| if (counter_num == 1) { |
| addr = EMI_BMEN; |
| value = (emi_readl(IOMEM(ADDR_EMI+addr)) & ~(iMask << 16)) | ((master & iMask) << 16); |
| } else { |
| addr = (counter_num <= 3) ? EMI_MSEL : (EMI_MSEL2 + (counter_num / 2 - 2) * 8); |
| |
| /* clear master and transaction type fields */ |
| value = emi_readl(IOMEM(ADDR_EMI+addr)) & ~(iMask << ((counter_num % 2) * 16)); |
| |
| /* set master and transaction type fields */ |
| value |= ((master & iMask) << ((counter_num % 2) * 16)); |
| } |
| |
| emi_reg_sync_writel(value, ADDR_EMI+addr); |
| |
| return BM_REQ_OK; |
| } |
| |
| int MET_BM_SetIDSelect(const unsigned int counter_num, |
| const unsigned int id, |
| const unsigned int enable) |
| { |
| unsigned int value, addr, shift_num; |
| |
| if (enable == 0) { |
| |
| value = (emi_readl(IOMEM(ADDR_EMI+EMI_BMEN2)) |
| & ~(1 << (counter_num - 1))); |
| |
| |
| emi_reg_sync_writel(value, ADDR_EMI+EMI_BMEN2); |
| return BM_REQ_OK; |
| } |
| |
| if ((counter_num < 1 || counter_num > BM_COUNTER_MAX) || (id > EMI_BMID_MASK) || (enable > 1)) |
| return BM_ERR_WRONG_REQ; |
| |
| |
| addr = EMI_BMID0 + (counter_num - 1) / 2 * 4; |
| |
| /* field's offset in the target EMI_BMIDx register */ |
| shift_num = ((counter_num - 1) % 2) * 16; |
| |
| /* clear SELx_ID field */ |
| value = emi_readl(IOMEM(ADDR_EMI+addr)) & ~(EMI_BMID_MASK << shift_num); |
| |
| /* set SELx_ID field */ |
| value |= id << shift_num; |
| |
| emi_reg_sync_writel(value, ADDR_EMI+addr); |
| |
| value = (emi_readl(IOMEM(ADDR_EMI+EMI_BMEN2)) |
| & ~(1 << (counter_num - 1))) |
| | (enable << (counter_num - 1)); |
| |
| emi_reg_sync_writel(value, ADDR_EMI+EMI_BMEN2); |
| |
| return BM_REQ_OK; |
| } |
| |
| int MET_BM_SetUltraHighFilter(const unsigned int counter_num, const unsigned int enable) |
| { |
| unsigned int value; |
| |
| if ((counter_num < 1 || counter_num > BM_COUNTER_MAX) || (enable > 1)) |
| return BM_ERR_WRONG_REQ; |
| |
| |
| value = (emi_readl(IOMEM(ADDR_EMI+EMI_BMEN1)) |
| & ~(1 << (counter_num - 1))) |
| | (enable << (counter_num - 1)); |
| |
| emi_reg_sync_writel(value, ADDR_EMI+EMI_BMEN1); |
| |
| return BM_REQ_OK; |
| } |
| |
| int MET_BM_SetLatencyCounter(unsigned int enable) |
| { |
| unsigned int value; |
| |
| value = emi_readl(IOMEM(ADDR_EMI+EMI_BMEN2)) & ~(0x3 << 24); |
| /* |
| * emi_ttype1 -- emi_ttype8 change as total latencies |
| * for m0 -- m7, |
| * and emi_ttype9 -- emi_ttype16 change as total transaction counts |
| * for m0 -- m7 |
| */ |
| if (enable == 1) |
| value |= (0x2 << 24); |
| |
| emi_reg_sync_writel(value, ADDR_EMI+EMI_BMEN2); |
| |
| return BM_REQ_OK; |
| } |
| |
| int MET_BM_GetLatencyCycle(const unsigned int counter_num) |
| { |
| unsigned int cycle_count; |
| |
| switch (counter_num) { |
| case 1: |
| cycle_count = emi_readl(IOMEM(ADDR_EMI+EMI_TTYPE1)); |
| break; |
| case 2: |
| cycle_count = emi_readl(IOMEM(ADDR_EMI+EMI_TTYPE2)); |
| break; |
| case 3: |
| cycle_count = emi_readl(IOMEM(ADDR_EMI+EMI_TTYPE3)); |
| break; |
| case 4: |
| cycle_count = emi_readl(IOMEM(ADDR_EMI+EMI_TTYPE4)); |
| break; |
| case 5: |
| cycle_count = emi_readl(IOMEM(ADDR_EMI+EMI_TTYPE5)); |
| break; |
| case 6: |
| cycle_count = emi_readl(IOMEM(ADDR_EMI+EMI_TTYPE6)); |
| break; |
| case 7: |
| cycle_count = emi_readl(IOMEM(ADDR_EMI+EMI_TTYPE7)); |
| break; |
| case 8: |
| cycle_count = emi_readl(IOMEM(ADDR_EMI+EMI_TTYPE8)); |
| break; |
| case 9: |
| cycle_count = emi_readl(IOMEM(ADDR_EMI+EMI_TTYPE9)); |
| break; |
| case 10: |
| cycle_count = emi_readl(IOMEM(ADDR_EMI+EMI_TTYPE10)); |
| break; |
| case 11: |
| cycle_count = emi_readl(IOMEM(ADDR_EMI+EMI_TTYPE11)); |
| break; |
| case 12: |
| cycle_count = emi_readl(IOMEM(ADDR_EMI+EMI_TTYPE12)); |
| break; |
| case 13: |
| cycle_count = emi_readl(IOMEM(ADDR_EMI+EMI_TTYPE13)); |
| break; |
| case 14: |
| cycle_count = emi_readl(IOMEM(ADDR_EMI+EMI_TTYPE14)); |
| break; |
| case 15: |
| cycle_count = emi_readl(IOMEM(ADDR_EMI+EMI_TTYPE15)); |
| break; |
| case 16: |
| cycle_count = emi_readl(IOMEM(ADDR_EMI+EMI_TTYPE16)); |
| break; |
| case 17: |
| cycle_count = emi_readl(IOMEM(ADDR_EMI+EMI_TTYPE17)); |
| break; |
| case 18: |
| cycle_count = emi_readl(IOMEM(ADDR_EMI+EMI_TTYPE18)); |
| break; |
| case 19: |
| cycle_count = emi_readl(IOMEM(ADDR_EMI+EMI_TTYPE19)); |
| break; |
| case 20: |
| cycle_count = emi_readl(IOMEM(ADDR_EMI+EMI_TTYPE20)); |
| break; |
| case 21: |
| cycle_count = emi_readl(IOMEM(ADDR_EMI+EMI_TTYPE21)); |
| break; |
| default: |
| return BM_ERR_WRONG_REQ; |
| } |
| |
| return cycle_count; |
| } |
| |
| unsigned int MET_BM_GetEmiDcm(void) |
| { |
| return (emi_readl(IOMEM(ADDR_EMI+EMI_CONM))>>24); |
| } |
| |
| int MET_BM_SetEmiDcm(const unsigned int setting) |
| { |
| unsigned int value; |
| |
| value = emi_readl(IOMEM(ADDR_EMI+EMI_CONM)); |
| emi_reg_sync_writel((value & 0x00FFFFFF) | (setting << 24), ADDR_EMI+EMI_CONM); |
| |
| return BM_REQ_OK; |
| } |
| |
| /* DRAMC */ |
| unsigned int MET_DRAMC_GetPageHitCount(DRAMC_Cnt_Type CountType, int chann) |
| { |
| unsigned int iCount; |
| unsigned long addr_base = ADDR_DRAMC0; |
| |
| if (chann == 0) |
| addr_base = ADDR_DRAMC0; |
| else if (chann == 1) |
| addr_base = ADDR_DRAMC1; |
| else if (chann == 2) |
| addr_base = ADDR_DRAMC2; |
| else if (chann == 3) |
| addr_base = ADDR_DRAMC3; |
| else |
| return BM_ERR_WRONG_REQ; |
| |
| |
| switch (CountType) { |
| case DRAMC_R2R: |
| iCount = emi_readl(IOMEM(addr_base+DRAMC_R2R_PAGE_HIT)); |
| break; |
| case DRAMC_R2W: |
| iCount = emi_readl(IOMEM(addr_base+DRAMC_R2W_PAGE_HIT)); |
| break; |
| case DRAMC_W2R: |
| iCount = emi_readl(IOMEM(addr_base+DRAMC_W2R_PAGE_HIT)); |
| break; |
| case DRAMC_W2W: |
| iCount = emi_readl(IOMEM(addr_base+DRAMC_W2W_PAGE_HIT)); |
| break; |
| case DRAMC_ALL: |
| iCount = emi_readl(IOMEM(addr_base+DRAMC_R2R_PAGE_HIT)) + |
| emi_readl(IOMEM(addr_base+DRAMC_R2W_PAGE_HIT)) + |
| emi_readl(IOMEM(addr_base+DRAMC_W2R_PAGE_HIT)) + |
| emi_readl(IOMEM(addr_base+DRAMC_W2W_PAGE_HIT)); |
| break; |
| default: |
| return BM_ERR_WRONG_REQ; |
| } |
| |
| return iCount; |
| } |
| |
| unsigned int MET_DRAMC_GetPageMissCount(DRAMC_Cnt_Type CountType, int chann) |
| { |
| unsigned int iCount; |
| unsigned long addr_base = ADDR_DRAMC0; |
| |
| if (chann == 0) |
| addr_base = ADDR_DRAMC0; |
| else if (chann == 1) |
| addr_base = ADDR_DRAMC1; |
| else if (chann == 2) |
| addr_base = ADDR_DRAMC2; |
| else if (chann == 3) |
| addr_base = ADDR_DRAMC3; |
| else |
| return BM_ERR_WRONG_REQ; |
| |
| |
| switch (CountType) { |
| case DRAMC_R2R: |
| iCount = emi_readl(IOMEM(addr_base+DRAMC_R2R_PAGE_MISS)); |
| break; |
| case DRAMC_R2W: |
| iCount = emi_readl(IOMEM(addr_base+DRAMC_R2W_PAGE_MISS)); |
| break; |
| case DRAMC_W2R: |
| iCount = emi_readl(IOMEM(addr_base+DRAMC_W2R_PAGE_MISS)); |
| break; |
| case DRAMC_W2W: |
| iCount = emi_readl(IOMEM(addr_base+DRAMC_W2W_PAGE_MISS)); |
| break; |
| case DRAMC_ALL: |
| iCount = emi_readl(IOMEM(addr_base+DRAMC_R2R_PAGE_MISS)) + |
| emi_readl(IOMEM(addr_base+DRAMC_R2W_PAGE_MISS)) + |
| emi_readl(IOMEM(addr_base+DRAMC_W2R_PAGE_MISS)) + |
| emi_readl(IOMEM(addr_base+DRAMC_W2W_PAGE_MISS)); |
| break; |
| default: |
| return BM_ERR_WRONG_REQ; |
| } |
| |
| return iCount; |
| } |
| |
| unsigned int MET_DRAMC_GetInterbankCount(DRAMC_Cnt_Type CountType, int chann) |
| { |
| unsigned int iCount; |
| unsigned long addr_base = ADDR_DRAMC0; |
| |
| if (chann == 0) |
| addr_base = ADDR_DRAMC0; |
| else if (chann == 1) |
| addr_base = ADDR_DRAMC1; |
| else if (chann == 2) |
| addr_base = ADDR_DRAMC2; |
| else if (chann == 3) |
| addr_base = ADDR_DRAMC3; |
| else |
| return BM_ERR_WRONG_REQ; |
| |
| |
| switch (CountType) { |
| case DRAMC_R2R: |
| iCount = emi_readl(IOMEM(addr_base+DRAMC_R2R_INTERBANK)); |
| break; |
| case DRAMC_R2W: |
| iCount = emi_readl(IOMEM(addr_base+DRAMC_R2W_INTERBANK)); |
| break; |
| case DRAMC_W2R: |
| iCount = emi_readl(IOMEM(addr_base+DRAMC_W2R_INTERBANK)); |
| break; |
| case DRAMC_W2W: |
| iCount = emi_readl(IOMEM(addr_base+DRAMC_W2W_INTERBANK)); |
| break; |
| case DRAMC_ALL: |
| iCount = emi_readl(IOMEM(addr_base+DRAMC_R2R_INTERBANK)) + |
| emi_readl(IOMEM(addr_base+DRAMC_R2W_INTERBANK)) + |
| emi_readl(IOMEM(addr_base+DRAMC_W2R_INTERBANK)) + |
| emi_readl(IOMEM(addr_base+DRAMC_W2W_INTERBANK)); |
| break; |
| default: |
| return BM_ERR_WRONG_REQ; |
| } |
| |
| return iCount; |
| } |
| |
| unsigned int MET_DRAMC_GetIdleCount(int chann) |
| { |
| unsigned long addr_base = ADDR_DRAMC0; |
| |
| if (chann == 0) |
| addr_base = ADDR_DRAMC0; |
| else if (chann == 1) |
| addr_base = ADDR_DRAMC1; |
| else if (chann == 2) |
| addr_base = ADDR_DRAMC2; |
| else if (chann == 3) |
| addr_base = ADDR_DRAMC3; |
| else |
| return BM_ERR_WRONG_REQ; |
| |
| return emi_readl(IOMEM(addr_base+DRAMC_IDLE_COUNT)); |
| } |
| |
| unsigned int MET_DRAMC_Misc_Status(int chann) |
| { |
| unsigned long addr_base = ADDR_DRAMC0; |
| |
| if (chann == 0) |
| addr_base = ADDR_DRAMC0; |
| else if (chann == 1) |
| addr_base = ADDR_DRAMC1; |
| else if (chann == 2) |
| addr_base = ADDR_DRAMC2; |
| else if (chann == 3) |
| addr_base = ADDR_DRAMC3; |
| else |
| return BM_ERR_WRONG_REQ; |
| |
| return emi_readl(IOMEM(addr_base+DRAMC_MISC_STATUSA)); |
| } |
| |
| int MET_DRAMC_BMPause(int chann, int set) |
| { |
| unsigned long addr_base = ADDR_DRAMC0; |
| unsigned int value; |
| |
| if (chann == 0) |
| addr_base = ADDR_DRAMC0; |
| else if (chann == 1) |
| addr_base = ADDR_DRAMC1; |
| else if (chann == 2) |
| addr_base = ADDR_DRAMC2; |
| else if (chann == 3) |
| addr_base = ADDR_DRAMC3; |
| else |
| return BM_ERR_WRONG_REQ; |
| |
| value = emi_readl(IOMEM(addr_base+DRAMC_DMMONITOR)); |
| if (set == 0) { |
| /* Continue DRAMC Monitor*/ |
| value = (value & 0xFFFFFFFB); |
| } |
| else if (set == 1) { |
| /* Pause DRAMC Monitor*/ |
| value = (value | 0x00000004); |
| } |
| else |
| return BM_ERR_WRONG_REQ; |
| emi_reg_sync_writel(value, addr_base+DRAMC_DMMONITOR); |
| |
| return BM_REQ_OK; |
| } |
| |
| |
| int MET_DRAMC_BMEnable(int chann, int set) |
| { |
| unsigned long addr_base = ADDR_DRAMC0; |
| unsigned int value; |
| |
| if (chann == 0) |
| addr_base = ADDR_DRAMC0; |
| else if (chann == 1) |
| addr_base = ADDR_DRAMC1; |
| else if (chann == 2) |
| addr_base = ADDR_DRAMC2; |
| else if (chann == 3) |
| addr_base = ADDR_DRAMC3; |
| else |
| return BM_ERR_WRONG_REQ; |
| |
| value = emi_readl(IOMEM(addr_base+DRAMC_DMMONITOR)); |
| if (set == 0) { |
| /* Disable DRAMC Monitor*/ |
| value = (value & 0xFFFFFFF7); |
| } |
| else if (set == 1) { |
| /* Enable DRAMC Monitor*/ |
| value = (value | 0x00000008); |
| } |
| else |
| return BM_ERR_WRONG_REQ; |
| emi_reg_sync_writel(value, addr_base+DRAMC_DMMONITOR); |
| |
| return BM_REQ_OK; |
| } |
| |
| unsigned int MET_DRAMC_RefPop(int chann) |
| { |
| unsigned long addr_base = ADDR_DRAMC0; |
| |
| if (chann == 0) |
| addr_base = ADDR_DRAMC0; |
| else if (chann == 1) |
| addr_base = ADDR_DRAMC1; |
| else if (chann == 2) |
| addr_base = ADDR_DRAMC2; |
| else if (chann == 3) |
| addr_base = ADDR_DRAMC3; |
| else |
| return BM_ERR_WRONG_REQ; |
| |
| return emi_readl(IOMEM(addr_base+DRAMC_REFRESH_POP)); |
| } |
| |
| |
| |
| unsigned int MET_DRAMC_Free26M(int chann) |
| { |
| unsigned long addr_base = ADDR_DRAMC0; |
| |
| if (chann == 0) |
| addr_base = ADDR_DRAMC0; |
| else if (chann == 1) |
| addr_base = ADDR_DRAMC1; |
| else if (chann == 2) |
| addr_base = ADDR_DRAMC2; |
| else if (chann == 3) |
| addr_base = ADDR_DRAMC3; |
| else |
| return BM_ERR_WRONG_REQ; |
| |
| return emi_readl(IOMEM(addr_base+DRAMC_FREERUN_26M)); |
| } |
| |
| unsigned int MET_DRAMC_RByte(int chann) |
| { |
| unsigned long addr_base = ADDR_DRAMC0; |
| |
| if (chann == 0) |
| addr_base = ADDR_DRAMC0; |
| else if (chann == 1) |
| addr_base = ADDR_DRAMC1; |
| else if (chann == 2) |
| addr_base = ADDR_DRAMC2; |
| else if (chann == 3) |
| addr_base = ADDR_DRAMC3; |
| else |
| return BM_ERR_WRONG_REQ; |
| |
| return emi_readl(IOMEM(addr_base+DRAMC_READ_BYTES)); |
| } |
| |
| unsigned int MET_DRAMC_WByte(int chann) |
| { |
| unsigned long addr_base = ADDR_DRAMC0; |
| |
| if (chann == 0) |
| addr_base = ADDR_DRAMC0; |
| else if (chann == 1) |
| addr_base = ADDR_DRAMC1; |
| else if (chann == 2) |
| addr_base = ADDR_DRAMC2; |
| else if (chann == 3) |
| addr_base = ADDR_DRAMC3; |
| else |
| return BM_ERR_WRONG_REQ; |
| |
| return emi_readl(IOMEM(addr_base+DRAMC_WRITE_BYTES)); |
| } |
| |
| unsigned int MET_EMI_GetMDCT(void) |
| { |
| return emi_readl(IOMEM(ADDR_EMI+EMI_MDCT)); |
| } |
| |
| unsigned int MET_EMI_GetMDCT_2ND(void) |
| { |
| return emi_readl(IOMEM(ADDR_EMI+EMI_MDCT_2ND)); |
| } |
| |
| |
| unsigned int MET_EMI_GetARBA(void) |
| { |
| /* EMI_ARBA EMI Bandwidth Filter Control M0/1 */ |
| return emi_readl(IOMEM(ADDR_EMI+EMI_ARBA)); |
| } |
| |
| unsigned int MET_EMI_GetARBB(void) |
| { |
| /* return emi_readl(IOMEM(ADDR_EMI+EMI_ARBB)); */ |
| /* Note: Olympus Coda doesn't has this regiester, So we return 0 */ |
| return 0; |
| } |
| |
| unsigned int MET_EMI_GetARBC(void) |
| { |
| return emi_readl(IOMEM(ADDR_EMI+EMI_ARBC)); |
| } |
| |
| unsigned int MET_EMI_GetARBD(void) |
| { |
| return emi_readl(IOMEM(ADDR_EMI+EMI_ARBD)); |
| } |
| |
| unsigned int MET_EMI_GetARBE(void) |
| { |
| return emi_readl(IOMEM(ADDR_EMI+EMI_ARBE)); |
| } |
| |
| unsigned int MET_EMI_GetARBF(void) |
| { |
| return emi_readl(IOMEM(ADDR_EMI+EMI_ARBF)); |
| } |
| |
| unsigned int MET_EMI_GetARBG(void) |
| { |
| return emi_readl(IOMEM(ADDR_EMI+EMI_ARBG)); |
| } |
| |
| unsigned int MET_EMI_GetARBH(void) |
| { |
| return emi_readl(IOMEM(ADDR_EMI+EMI_ARBH)); |
| } |
| |
| /* Total BW status*/ |
| unsigned int MET_EMI_GetBWCT0(void) |
| { |
| return emi_readl(IOMEM(ADDR_EMI+EMI_BWCT0)); |
| } |
| |
| /* Total BW status*/ |
| unsigned int MET_EMI_GetBWCT1(void) |
| { |
| return emi_readl(IOMEM(ADDR_EMI+EMI_BWCT1)); |
| } |
| |
| /* Total BW status*/ |
| unsigned int MET_EMI_GetBWCT2(void) |
| { |
| return emi_readl(IOMEM(ADDR_EMI+EMI_BWCT2)); |
| } |
| |
| /* Total BW status*/ |
| unsigned int MET_EMI_GetBWCT3(void) |
| { |
| return emi_readl(IOMEM(ADDR_EMI+EMI_BWCT3)); |
| } |
| |
| /* Total BW status*/ |
| unsigned int MET_EMI_GetBWCT4(void) |
| { |
| return emi_readl(IOMEM(ADDR_EMI+EMI_BWCT4)); |
| } |
| |
| /* Total BW status*/ |
| unsigned int MET_EMI_GetBWST0(void) |
| { |
| return emi_readl(IOMEM(ADDR_EMI+EMI_BWST0)); |
| } |
| |
| /* Total BW status*/ |
| unsigned int MET_EMI_GetBWST1(void) |
| { |
| return emi_readl(IOMEM(ADDR_EMI+EMI_BWST1)); |
| } |
| |
| |
| /* C+G BW status*/ |
| unsigned int MET_EMI_GetBWCT0_2ND(void) |
| { |
| return emi_readl(IOMEM(ADDR_EMI+EMI_BWCT0_2ND)); |
| } |
| |
| /* C+G BW status*/ |
| unsigned int MET_EMI_GetBWCT1_2ND(void) |
| { |
| return emi_readl(IOMEM(ADDR_EMI+EMI_BWCT1_2ND)); |
| } |
| |
| /* C+G BW status*/ |
| unsigned int MET_EMI_GetBWST_2ND(void) |
| { |
| return emi_readl(IOMEM(ADDR_EMI+EMI_BWST_2ND)); |
| } |
| |
| unsigned int MET_EMI_GetBMRW0(void) |
| { |
| return readl(IOMEM(ADDR_EMI+EMI_BMRW0)); |
| } |
| |
| void emi_dump_reg(void) |
| { |
| int i; |
| |
| MET_TRACE("[emi_regdump]\n"); |
| for (i = 0x400; i < 0x500; i = i+16) |
| MET_TRACE("%4x__ %8x %8x %8x %8x\n", i, readl(IOMEM(ADDR_EMI+i)), |
| readl(IOMEM(ADDR_EMI+i+4)), readl(IOMEM(ADDR_EMI+i+8)), readl(IOMEM(ADDR_EMI+i+12))); |
| } |
| |
| unsigned int MET_EMI_GetDramChannNum(void) |
| { |
| int num = -1; |
| |
| if (BaseAddrEMI) { |
| num = emi_readl(IOMEM(ADDR_EMI+EMI_CONA)); |
| num = ((num >> 8) & 0x0000003); |
| } else { |
| return 1; |
| } |
| |
| if (num == M0_DOUBLE_HALF_BW_1CH) |
| return 1; |
| else if (num == M0_DOUBLE_HALF_BW_2CH) |
| return 2; |
| else if (num == M0_DOUBLE_HALF_BW_4CH) |
| return 4; |
| |
| else /* default return single channel */ |
| return 1; |
| |
| } |
| |
| void MET_DRAMC_GetDebugCounter(int *value, int chann) |
| { |
| int i; |
| unsigned long addr_base = ADDR_DRAMC0; |
| |
| for (i = 0; i < chann; i++) { |
| |
| if (i == 0) |
| addr_base = ADDR_DRAMC0; |
| else if (i == 1) |
| addr_base = ADDR_DRAMC1; |
| else if (i == 2) |
| addr_base = ADDR_DRAMC2; |
| else if (i == 3) |
| addr_base = ADDR_DRAMC3; |
| else |
| return; |
| |
| |
| value[DRAMC_Debug_MAX_CNT*i + BM_RK0_PRE_STANDBY] = |
| emi_readl(IOMEM(addr_base + DRAMC_RK0_PRE_STANDBY)); |
| value[DRAMC_Debug_MAX_CNT*i + BM_RK0_PRE_POWERDOWN] = |
| emi_readl(IOMEM(addr_base + DRAMC_RK0_PRE_POWERDOWN)); |
| value[DRAMC_Debug_MAX_CNT*i + BM_RK0_ACT_STANDBY] = |
| emi_readl(IOMEM(addr_base + DRAMC_RK0_ACT_STANDBY)); |
| value[DRAMC_Debug_MAX_CNT*i + BM_RK0_ACT_POWERDOWN] = |
| emi_readl(IOMEM(addr_base + DRAMC_RK0_ACT_POWERDOWN)); |
| |
| value[DRAMC_Debug_MAX_CNT*i + BM_RK1_PRE_STANDBY] = |
| emi_readl(IOMEM(addr_base + DRAMC_RK1_PRE_STANDBY)); |
| value[DRAMC_Debug_MAX_CNT*i + BM_RK1_PRE_POWERDOWN] = |
| emi_readl(IOMEM(addr_base + DRAMC_RK1_PRE_POWERDOWN)); |
| value[DRAMC_Debug_MAX_CNT*i + BM_RK1_ACT_STANDBY] = |
| emi_readl(IOMEM(addr_base + DRAMC_RK1_ACT_STANDBY)); |
| value[DRAMC_Debug_MAX_CNT*i + BM_RK1_ACT_POWERDOWN] = |
| emi_readl(IOMEM(addr_base + DRAMC_RK1_ACT_POWERDOWN)); |
| |
| value[DRAMC_Debug_MAX_CNT*i + BM_RK2_PRE_STANDBY] = |
| emi_readl(IOMEM(addr_base + DRAMC_RK2_PRE_STANDBY)); |
| value[DRAMC_Debug_MAX_CNT*i + BM_RK2_PRE_POWERDOWN] = |
| emi_readl(IOMEM(addr_base + DRAMC_RK2_PRE_POWERDOWN)); |
| value[DRAMC_Debug_MAX_CNT*i + BM_RK2_ACT_STANDBY] = |
| emi_readl(IOMEM(addr_base + DRAMC_RK2_ACT_STANDBY)); |
| value[DRAMC_Debug_MAX_CNT*i + BM_RK2_ACT_POWERDOWN] = |
| emi_readl(IOMEM(addr_base + DRAMC_RK2_ACT_POWERDOWN)); |
| } |
| } |
| #if 1 |
| static inline unsigned int dramc_reg_read(unsigned long addr) |
| { |
| #if 0 |
| #ifdef CONFIG_64BIT |
| unsigned int value = 0; |
| value = HAL_READ32((void*)addr); |
| #else |
| unsigned int value = readl((void*)addr); |
| #endif |
| #endif |
| |
| unsigned int value = readl((void*)addr); |
| |
| mb(); |
| return value; |
| } |
| |
| #if 0 |
| u32 DRAMC_GetDramcFreq(void) |
| { |
| unsigned long tcm_dramc_flags = 0; |
| tcm_dramc_flags = dramc_reg_read(TCM_DRAM_FLAGS_ADDR); |
| return TCMGET_DDR_CLK(tcm_dramc_flags); |
| } |
| |
| unsigned int get_dram_data_rate(void) |
| { |
| return DRAMC_GetDramcFreq()/1000000; |
| } |
| #else |
| |
| #define DRAM_DATARATE_REG 0x10100D9C |
| |
| u32 DRAMC_GetDramcFreq(void) |
| { |
| unsigned long reg_val; |
| unsigned long dram_datarate = 0; |
| |
| reg_val = dramc_reg_read((unsigned long)(AddrDramDatarate + 0xD9C)); |
| // pr_err("dram datarate reg val = 0x%lx, reg_val[9-16] = %lu\n", reg_val, (reg_val >> 9) & 0xff); |
| dram_datarate = (((dramc_reg_read((unsigned long)(AddrDramDatarate + 0xD9C))) >> 16) & 0x1ffff) * 26 / 256; |
| |
| return dram_datarate; |
| } |
| |
| unsigned int get_dram_data_rate(void) |
| { |
| return DRAMC_GetDramcFreq(); |
| } |
| #endif |
| |
| |
| #else |
| #define DRAMC_AO_CHA_BASE_ADDR (DRAM_BASE) |
| #define PDEF_DRAMC0_CHA_REG_0E4 IOMEM((DRAMC_AO_CHA_BASE_ADDR + 0x00e4)) |
| #define PDEF_DRAMC0_CHA_REG_010 IOMEM((DRAMC_AO_CHA_BASE_ADDR + 0x0010)) |
| #define DDRPHY_CHA_BASE_ADDR (DRAM_DDRPHY_CHA_BANK) |
| unsigned int DRAM_TYPE = 0; |
| enum DDRTYPE { |
| TYPE_LPDDR3 = 1, |
| TYPE_LPDDR4, |
| TYPE_LPDDR4X |
| }; |
| |
| static unsigned int get_shuffle_status(void) |
| { |
| /* HPM = 0, LPM = 1, ULPM = 2; */ |
| return (emi_readl(PDEF_DRAMC0_CHA_REG_0E4) & 0x6) >> 1; |
| } |
| |
| unsigned int get_dram_data_rate(void) |
| { |
| return DRAMC_GetDramcFreq(); |
| |
| unsigned long addr_base = DDRPHY_CHA_BASE_ADDR; |
| unsigned int u4ShuLevel, u4SDM_PCW, u4PREDIV, u4POSDIV, u4CKDIV4, u4VCOFreq, u4DataRate = 0; |
| if (DRAM_TYPE == 0) |
| DRAM_TYPE = (emi_readl(PDEF_DRAMC0_CHA_REG_010) & 0x1C00) >> 10; |
| u4ShuLevel = get_shuffle_status(); |
| |
| u4SDM_PCW = emi_readl(IOMEM(addr_base + 0xd94 + 0x500 * u4ShuLevel)) >> 16; |
| u4PREDIV = (emi_readl(IOMEM(addr_base + 0xda0 + 0x500 * u4ShuLevel)) & 0x000c0000) >> 18; |
| u4POSDIV = emi_readl(IOMEM(addr_base + 0xda0 + 0x500 * u4ShuLevel)) & 0x00000007; |
| u4CKDIV4 = (emi_readl(IOMEM(addr_base + 0xd18 + 0x500 * u4ShuLevel)) & 0x08000000) >> 27; |
| |
| u4VCOFreq = ((52>>u4PREDIV)*(u4SDM_PCW>>8))>>u4POSDIV; |
| |
| u4DataRate = u4VCOFreq>>u4CKDIV4; |
| |
| /* pr_err("[DRAMC Driver] u4ShuLevel=%d, PCW=0x%X, u4PREDIV=%d, u4POSDIV=%d, CKDIV4=%d, DataRate=%d\n", |
| * u4ShuLevel, u4SDM_PCW, u4PREDIV, u4POSDIV, u4CKDIV4, u4DataRate); |
| */ |
| |
| // if (DRAM_TYPE == TYPE_LPDDR4X) { |
| if (u4DataRate == 3198) |
| u4DataRate = 3200; |
| else if (u4DataRate == 2652) |
| u4DataRate = 2667; |
| else if (u4DataRate == 1599) |
| u4DataRate = 1600; |
| else if (u4DataRate == 799) |
| u4DataRate = 800; |
| else |
| u4DataRate = 0; |
| // } else |
| // u4DataRate = 0; |
| |
| return u4DataRate; |
| } |
| #endif |