/* * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. */ /******** DMC **************************/ /* base address: DDR_REG_BASE_DMC0 DDR_REG_BASE_DMC1 */ /* register offset address */ #define DDR_DMC_CTRL_SREF 0X0 /* DDRC self-refresh control. */ #define DDR_DMC_CFG_SREF 0x20 /* DDRC self-refresh config. */ #define DDR_DMC_CFG_PD 0x28 /* PowerDown */ #define DDR_DMC_CFG_DDRMODE 0x50 #define DDR_DMC_CFG_SCRAMB 0x58 /* DDR scramb config */ #define DDR_DMC_CFG_RNKVOL(n) (0x60 + ((n) << 2)) #define DDR_DMC_CFG_EMRS01 0xf0 #define DDR_DMC_TIMING2 0x108 #define DDR_DMC_SFCREQ 0xc #define DDR_DMC_SFCCMD 0x210 #define DDR_DMC_SFCADDR 0x214 /* read col and row */ #define DDR_DMC_SFCBANK 0x218 #define DDR_DMC_CURR_FUNC 0x294 #ifndef DDR_DMC_SFC_RDATA0 #define DDR_DMC_SFC_RDATA0 0x4A8 /* SFC read data[31:0] */ #endif #ifndef DDR_DMC_SFC_RDATA1 #define DDR_DMC_SFC_RDATA1 0x4AC /* SFC read data[63:32] */ #endif #ifndef DDR_DMC_SFC_RDATA2 #define DDR_DMC_SFC_RDATA2 0x4B0 /* SFC read data[95:64] */ #endif #ifndef DDR_DMC_SFC_RDATA3 #define DDR_DMC_SFC_RDATA3 0x4B4 /* SFC read data[127:96] */ #endif #ifndef DDR_DMC_SFC_RDATA4 #define DDR_DMC_SFC_RDATA4 0x4B8 /* SFC read data[159:128] */ #endif #ifndef DDR_DMC_SFC_RDATA5 #define DDR_DMC_SFC_RDATA5 0x4BC /* SFC read data[191:160] */ #endif #ifndef DDR_DMC_SFC_RDATA6 #define DDR_DMC_SFC_RDATA6 0x4C0 /* SFC read data[223:192] */ #endif #ifndef DDR_DMC_SFC_RDATA7 #define DDR_DMC_SFC_RDATA7 0x4C4 /* SFC read data[255:224] */ #endif /* register mask */ #define DMC_CMD_MRS_MASK 0xffff /* storing data bus width. [00]8bit, [01]16bit, [10]32bit, [11]64bit */ #define DMC_MEM_WIDTH_MASK 0x3 #define DMC_MRS_MASK 0xffff /* [15:0] Mode Register mask */ #define DMC_MR0_BL_MASK 0x3 #define DMC_CFG_DRAM_TYPE_MASK 0xf /* [3:0]101:DDR2, 110:DDR3, 111:DDR4 */ #define DMC_CFG_MEM_BG_MASK 0x3 /* [11:10]0:1, 1:2, 2:4 Bank Group */ #define DMC_CURR_FUNC_IN_SREF_MASK 0x1 #define DMC_RNKVOL_MEM_BANK_MASK 0x3 /* [9:8] */ #define DMC_RNKVOL_MEM_ROW_MASK 0x7 /* [6:4] */ #define DMC_RNKVOL_MEM_COL_MASK 0x7 /* [2:0] */ #define DMC_CFG_INIT_XSREF_PD_MASK 0xc /* [3:2] */ /* register bit */ #define DMC_MEM_WIDTH_BIT 4 /* storing data bus width */ /* [CUSTOM] precharge disable/enable bit */ #define DMC_SFC_PRE_DIS_BIT 30 /* [CUSTOM] [29:12]config MR when LMR command */ #define DMC_SFC_CMD_MRS_BIT 12 #define DMC_SFC_RANK_BIT 16 /* [CUSTOM] [31:16]sfc_rank */ #define DMC_CFG_MEM_BG_BIT 10 /* [11:10] mem_bankgroup */ #define DMC_RNKVOL_MEM_BANK_BIT 8 /* [9:8] */ #define DMC_RNKVOL_MEM_ROW_BIT 4 /* [6:4] */ /* register value */ #define DMC_BANK_MR1 1 #define DMC_BANK_MR3 0x3 #define DMC_CMD_TYPE_LMR 0x2 #define DMC_CMD_TYPE_READ 0x5 /* read */ #define DMC_CMD_TYPE_PRECHARGE_ALL 0x6 /* precharge all */ #define DMC_CMD_MRS_MR3 0x4 /* MR3 = 0x4 */ #define DMC_CMD_MRS_A7 0x80 /* value 1 means exexute command. cmd_rank[0] control DDR RANK0 */ #define DMC_CMD_RANK0 0x1 #define DMC_MR0_BL_BUST8 0x0 /* BC8 (fixed) */ #define DMC_MR0_BL_BUST4 0x2 /* BC4 (fixed) */ #define DMC_AUTO_TIMING_DIS 0xfffff000 /* auto refresh disable */ #define DMC_POWER_DOWN_DIS 0xfffffffe /* powerDown disable */ #define DMC_SCRAMB_DIS 0xffffbfff /* [14] scramb disable */ /* [4] scramb_seed_type, [2:0] scramb_seed_sort */ #define DMC_SCRAMB_CFG 0xffffffe8 #define DMC_CFG_DRAM_TYPE_DDR4 0x7 /* DDR4 */ #define DMC_CFG_DRAM_TYPE_LPDDR4 0x8 /* LPDDR4 */ #define DMC_CFG_MEM_2BG 0x1 /* 2 Bank Group */ #define DMC_CFG_INIT_XSREF_PD 0xc /* LPDDR4:Exit Auto-self refresh enter powerdown */ #define DMC_CTRL_SREF_ENTER 0x1 /* 1 Enter Auto-self refresh */ #define DMC_CTRL_SREF_EXIT 0x2 /* 2 Exit Auto-self refresh */ #define DMC_RNKVOL_MEM_ROW_11 0x0 /* 000: 11 bit */ #ifndef DDR_PHY_NUM #define DDR_PHY_NUM 2 /* phy number */ #endif #ifndef DDR_DMC_PER_PHY_MAX #define DDR_DMC_PER_PHY_MAX 2 #endif #ifndef DDR_AXI_SWITCH_NUM #define DDR_AXI_SWITCH_NUM 4 /* ddr training axi switch number */ #endif #ifndef DDR_RANK_NUM #define DDR_RANK_NUM 2 /* rank number */ #endif #define DMC_SFC_CMD_WRITE(sfc_cmd, addr) \ ddr_write(sfc_cmd | (1 << DMC_SFC_PRE_DIS_BIT), addr) #define DMC_SFC_BANK_WRITE(sfc_bank, addr) \ ddr_write(sfc_bank | (DMC_CMD_RANK0 << DMC_SFC_RANK_BIT), addr) #define DMC_MPR_CHECK_BIT_0_127(cfg) \ ddr_mpr_extract(cfg, \ DDR_DMC_SFC_RDATA3, DDR_DMC_SFC_RDATA2, \ DDR_DMC_SFC_RDATA1, DDR_DMC_SFC_RDATA0) #define DMC_MPR_CHECK_BIT_128_255(cfg) \ ddr_mpr_extract(cfg, \ DDR_DMC_SFC_RDATA7, DDR_DMC_SFC_RDATA6, \ DDR_DMC_SFC_RDATA5, DDR_DMC_SFC_RDATA4) /* dmc scramb */ #define DMC_SAVE_SCRAMB(relate_reg, i, base_dmc) \ do { \ relate_reg->dmc_scramb[i] = \ ddr_read(base_dmc + DDR_DMC_CFG_DDRMODE); \ relate_reg->dmc_scramb_cfg[i] = \ ddr_read(base_dmc + DDR_DMC_CFG_SCRAMB); \ } while (0) #define DMC_DISABLE_SCRAMB(relate_reg, i, base_dmc) \ do { \ ddr_write(relate_reg->dmc_scramb[i] & DMC_SCRAMB_DIS, \ base_dmc + DDR_DMC_CFG_DDRMODE); \ ddr_write(relate_reg->dmc_scramb_cfg[i] & DMC_SCRAMB_CFG, \ base_dmc + DDR_DMC_CFG_SCRAMB); \ } while (0) #define DMC_RESTORE_SCRAMB(relate_reg, i, base_dmc) \ do { \ ddr_write(relate_reg->dmc_scramb[i], \ base_dmc + DDR_DMC_CFG_DDRMODE); \ ddr_write(relate_reg->dmc_scramb_cfg[i], \ base_dmc + DDR_DMC_CFG_SCRAMB); \ } while (0) /******** AXI **************************/ /** * DMC -- PHY * / * DDRT -- AXI * \ * DMC -- PHY */ /* base address: DDR_REG_BASE_AXI */ /* register offset address */ #define DDR_AXI_REGION_ATTRIB0 0x104 /* region 0 */ #define DDR_AXI_REGION_ATTRIB1 0x114 /* region 1 */ /* register mask */ #define AXI_REGION_ATTRIB_CH_MASK 0xfffffff0 /* channel mask */ /* register value */ /* Map to the single channel, independent address */ #define AXI_RNG_ATTR_CH_MODE 0x4 #define AXI_RNG_ATTR_CH_START_0 0x0 #define AXI_RNG_ATTR_CH_START_1 0x1 #define AXI_RNG_ATTR_CH_START_2 0x2 #define AXI_RNG_ATTR_CH_START_3 0x3 #define AXI_RNG_NUM 2 /* region number */ /********data define************************************/ struct ddr_ddrc_data { unsigned int region_attrib[AXI_RNG_NUM]; unsigned int rnkvol; }; #define DDR_AXI_SAVE_FUNC(relate_reg) \ do { \ relate_reg->ddrc.region_attrib[0] = \ ddr_read(DDR_REG_BASE_AXI + DDR_AXI_REGION_ATTRIB0); \ relate_reg->ddrc.region_attrib[1] = \ ddr_read(DDR_REG_BASE_AXI + DDR_AXI_REGION_ATTRIB1); \ } while (0) #define DDR_AXI_RESTORE_FUNC(relate_reg) \ do { \ ddr_write(relate_reg->ddrc.region_attrib[0], \ DDR_REG_BASE_AXI + DDR_AXI_REGION_ATTRIB0); \ ddr_write(relate_reg->ddrc.region_attrib[1], \ DDR_REG_BASE_AXI + DDR_AXI_REGION_ATTRIB1); \ } while (0) /* ch_start value: #define AXI_RNG_ATTR_CH_START_0 0x0 #define AXI_RNG_ATTR_CH_START_1 0x1 #define AXI_RNG_ATTR_CH_START_2 0x2 #define AXI_RNG_ATTR_CH_START_3 0x3 */ #define DDR_AXI_SWITCH_FUNC(cfg) \ do { \ unsigned int ch_start = cfg->phy_idx; \ if (PHY_DRAMCFG_TYPE_LPDDR4 == cfg->phy[cfg->phy_idx].dram_type) \ ch_start = (cfg->phy_idx << 1) + cfg->dmc_idx; \ ddr_write((ddr_read(DDR_REG_BASE_AXI + DDR_AXI_REGION_ATTRIB0) \ & AXI_REGION_ATTRIB_CH_MASK) \ | AXI_RNG_ATTR_CH_MODE | ch_start, \ DDR_REG_BASE_AXI + DDR_AXI_REGION_ATTRIB0); \ ddr_write((ddr_read(DDR_REG_BASE_AXI + DDR_AXI_REGION_ATTRIB1) \ & AXI_REGION_ATTRIB_CH_MASK) \ | AXI_RNG_ATTR_CH_MODE | ch_start, \ DDR_REG_BASE_AXI + DDR_AXI_REGION_ATTRIB1); \ DDR_DEBUG("AXI region0[%x = %x]", \ (DDR_REG_BASE_AXI + DDR_AXI_REGION_ATTRIB0), \ ddr_read(DDR_REG_BASE_AXI + DDR_AXI_REGION_ATTRIB0)); \ DDR_DEBUG("AXI region1[%x = %x]", \ (DDR_REG_BASE_AXI + DDR_AXI_REGION_ATTRIB1), \ ddr_read(DDR_REG_BASE_AXI + DDR_AXI_REGION_ATTRIB1)); \ } while (0) /* save rank0 for ddrt address */ #define DDR_RNKVOL_SAVE_FUNC(relate_reg, base_dmc) \ relate_reg->ddrc.rnkvol = ddr_read(base_dmc + DDR_DMC_CFG_RNKVOL(0)); #define DDR_RNKVOL_RESTORE_FUNC(relate_reg, base_dmc) \ ddr_write(relate_reg->ddrc.rnkvol, base_dmc + DDR_DMC_CFG_RNKVOL(0)); /* set mem_row to 0 */ #define DDR_RNKVOL_SET_FUNC(cfg) \ do { \ if (1 == cfg->rank_idx) { \ ddr_write(ddr_read(cfg->cur_dmc + DDR_DMC_CFG_RNKVOL(0)) & (~DMC_RNKVOL_MEM_ROW_MASK), cfg->cur_dmc + DDR_DMC_CFG_RNKVOL(0)); \ } \ } while (0)