美文网首页
iTop4412 uboot-2019.2移植之内存控制器(七)

iTop4412 uboot-2019.2移植之内存控制器(七)

作者: simexce | 来源:发表于2019-03-17 13:31 被阅读0次

    一、说明

    内存控制器非常难配置,故而不能出错。我严格按照文档上的步骤配置,其中的参数自行体会。

    二、配置流程

    首先配置内存交错,然后初始化每个DMC。

    223 void mem_ctrl_init(int reset)
    224 {
    225     struct exynos4_dmc *dmc1 = (struct exynos4_dmc *)samsung_get_base_dmc_ctrl();
    226     struct exynos4_dmc *dmc2 = (struct exynos4_dmc *)(samsung_get_base_dmc_ctrl() + DMC_OFFSET);
    227     /**
    228     ¦* 配置内存交错
    229     ¦*/
    230     writel(APB_SFR_INTERLEAVE_CONF_VAL, &dmc1->ivcontrol);
    231     writel(APB_SFR_INTERLEAVE_CONF_VAL, &dmc2->ivcontrol);
    232
    233     /*
    234     ¦* 初始化内存控制器
    235     ¦*/
    236     dmc_init(dmc1);
    237     dmc_init(dmc2);
    238 }
    
    

    配置步骤在代码中,对比手册阅读

    static void dmc_init(struct exynos4_dmc *dmc)
    {
        /**
         * Setup 2:
         *  enable PhyControl1.term_write_en, PhyControl1.term_read_en
         */
        writel(mem.control1, &dmc->phycontrol1); //有差异
    
        /**
         * Stup 3:
         *  disable PhyZQControl.ctrl_zq_mode_noterm
         *  enable PhyZQControl.ctrl_zq_start
         */
        writel(mem.zqcontrol, &dmc->phyzqcontrol);
    
    
        /**
         * Setup 4:
         *  set PhyControl0.ctrl_start_point, PhyControl0.ctrl_inc
         *  set PhyControl0.ctrl_dll_on to 1 ——activate PHY DLL
         */
        phy_control_reset(0, dmc);
    
        /**
         * Setup 5:
         *  set PhyControl1.ctr_shiftc, PhyControl1.ctrl_offsetc
         */
        writel(mem.control1, &dmc->phycontrol1);
    
        /**
         * Setup 6:
         *  set PhyControl0.ctrl_start to 1
         */
        writel((mem.control0 | CTRL_START | CTRL_DLL_ON), &dmc->phycontrol0);
    
    
        /**
         * Setup 7:
         *  set ConControl, close auto refresh
         */
        writel(mem.concontrol, &dmc->concontrol);
    
    
        /**
         * Setup 8:
         *  set MemControl, close power down modes, close pzq_en
         */
        writel(mem.memcontrol, &dmc->memcontrol); //差异
    
        /**
         * Setup 9:
         *  set Memory info
         */
        writel(mem.memconfig0, &dmc->memconfig0);
        writel(mem.memconfig1, &dmc->memconfig1);
    
        /**
         * Setup 10:
         *  set PrechConfig
         */
        writel(mem.prechconfig, &dmc->prechconfig);
    
        /**
         * Setup 11:
         *  set TimingAref, TimingRow, TimingData and TimingPower
         */
        writel(mem.timingref, &dmc->timingref);
        writel(mem.timingrow, &dmc->timingrow);
        writel(mem.timingdata, &dmc->timingdata);
        writel(mem.timingpower, &dmc->timingpower);
    
        /**
         * Setup 13:
         *  wait PhyStatus0.ctrl_clock and PhyStatus0.ctrl_flock to 1
         */
    
        while(!(dmc->phystatus & 2));
    
        /**
         * Setup 15,16:
         *  set PhyContron1.fp_resync to 1
         */
        phy_control_reset(1, dmc);
    
        /**
         * Setup 19:
         *  NOP command
         *  hold CKE to logic high level
         *  chip 0
         */
        writel(DIRECT_CMD_NOP, &dmc->directcmd);
    
        /**
         * Setup 21:
         *  send EMRS2 command
         *  send EMRS3 command
         *  send EMRS command
         *  send MRS command
         *  chip 0
         */
        dmc_config_mrs(dmc, 0);
    
        /**
         *Setup 26:
         send ZQINIT command
         chip 0
         */
        writel(DIRECT_CMD_ZQ, &dmc->directcmd);
    
        /**
         * Setup 19:
         *  NOP command
         *  hold CKE to logic high level
         *  chip 1
         */
        writel((DIRECT_CMD_NOP | DIRECT_CMD_CHIP1_SHIFT), &dmc->directcmd);
    
        /**
         * Setup 21:
         *  send EMRS2 command
         *  send EMRS3 command
         *  send EMRS command
         *  send MRS command
         *  chip 1
         */
        dmc_config_mrs(dmc, 1);
    
        /**
         *Setup 26:
         send ZQINIT command
         chip 1
         */
        writel((DIRECT_CMD_ZQ | DIRECT_CMD_CHIP1_SHIFT), &dmc->directcmd);
    
        /**
         * Setup 28:
         *  set ConControl auto refresh
         */
        writel((mem.concontrol | AREF_EN), &dmc->concontrol);
    
        /**
         * Setup 29:
         *  set MemControl
         */
        writel((mem.memcontrol | MEMCONTROL_OR), &dmc->memcontrol);
    }
    
    

    三、配置参数

    /********************************************************************************
     *
     * 内存控制器的配置
     *
     ********************************************************************************/
    
    /* DMC */
    #define DIRECT_CMD_CHIP1_SHIFT  (1 << 20)
    #define MEM_TIMINGS_MSR_COUNT   4
    #define CTRL_START  (1 << 0)
    #define CTRL_DLL_ON (1 << 1)
    #define AREF_EN     (1 << 5)
    #define DRV_TYPE    (1 << 6)
    
    struct mem_timings {
        unsigned direct_cmd_msr[MEM_TIMINGS_MSR_COUNT];
        unsigned timingref;
        unsigned timingrow;
        unsigned timingdata;
        unsigned timingpower;
        unsigned zqcontrol;
        unsigned control0;
        unsigned control1;
        unsigned control2;
        unsigned concontrol;
        unsigned prechconfig;
        unsigned memcontrol;
        unsigned memconfig0;
        unsigned memconfig1;
        unsigned dll_resync;
        unsigned dll_on;
    };
    
    /* MIU */
    /* MIU Config Register Offsets*/
    
    #ifdef CONFIG_ITOP4412
    #define APB_SFR_INTERLEAVE_CONF_VAL     0x80000007
    #endif
    
    #ifdef CONFIG_MIU_1BIT_INTERLEAVED
    #define APB_SFR_INTERLEAVE_CONF_VAL 0x0000000c
    #endif
    
    #ifdef CONFIG_MIU_2BIT_INTERLEAVED
    #define APB_SFR_INTERLEAVE_CONF_VAL 0x2000150c
    #endif
    
    
    #define FORCE_DLL_RESYNC    3
    #define DLL_CONTROL_ON      1
    
    #define DIRECT_CMD_NOP  0x07000000
    #define DIRECT_CMD1     0x00020000
    #define DIRECT_CMD2     0x00030000
    #define DIRECT_CMD3     0x00010002
    #define DIRECT_CMD4     0x00000328
    #define DIRECT_CMD_ZQ   0x0a000000
    
    #define CTRL_ZQ_MODE_NOTERM (0x1 << 0)
    #define CTRL_ZQ_START       (0x1 << 1)
    #define CTRL_ZQ_DIV         (0x0 << 4)
    #define CTRL_ZQ_MODE_DDS    (0x7 << 8)
    #define CTRL_ZQ_MODE_TERM   (0x2 << 11)
    #define CTRL_ZQ_FORCE_IMPN  (0x5 << 14)
    #define CTRL_ZQ_FORCE_IMPP  (0x6 << 17)
    #define CTRL_DCC            (0xE38 << 20)
    #define ZQ_CONTROL_VAL      (CTRL_ZQ_MODE_NOTERM | CTRL_ZQ_START\
            | CTRL_ZQ_DIV | CTRL_ZQ_MODE_DDS\
            | CTRL_ZQ_MODE_TERM | CTRL_ZQ_FORCE_IMPN\
            | CTRL_ZQ_FORCE_IMPP | CTRL_DCC)
    
    #define ASYNC               (0 << 0)
    #define CLK_RATIO           (1 << 1)
    #define DIV_PIPE            (1 << 3)
    #define AWR_ON              (1 << 4)
    #define AREF_DISABLE        (0 << 5)
    #define DRV_TYPE_DISABLE    (0 << 6)
    #define CHIP0_NOT_EMPTY     (0 << 8)
    #define CHIP1_NOT_EMPTY     (0 << 9)
    #define DQ_SWAP_DISABLE     (0 << 10)
    #define QOS_FAST_DISABLE    (0 << 11)
    #define RD_FETCH            (0x3 << 12)
    #define TIMEOUT_LEVEL0      (0xFFF << 16)
    #define CONCONTROL_VAL      (ASYNC | CLK_RATIO | DIV_PIPE | AWR_ON\
            | AREF_DISABLE | DRV_TYPE_DISABLE\
            | CHIP0_NOT_EMPTY | CHIP1_NOT_EMPTY\
            | DQ_SWAP_DISABLE | QOS_FAST_DISABLE\
            | RD_FETCH | TIMEOUT_LEVEL0)
    
    #define MEMCONTROL_OR       (1 | 2 | (1 << 4) | (1 << 24))
    #define CLK_STOP_DISABLE    (0 << 1)
    #define DPWRDN_DISABLE      (0 << 2)
    #define DPWRDN_TYPE         (0 << 3)
    #define TP_DISABLE          (0 << 4)
    #define DSREF_DIABLE        (0 << 5)
    #define ADD_LAT_PALL        (1 << 6)
    #define MEM_TYPE_DDR3       (6 << 8)
    #define MEM_WIDTH_32        (2 << 12)
    #define NUM_CHIP_2          (1 << 16)
    #define BL_8                (3 << 20)
    #define MEMCONTROL_VAL      (CLK_STOP_DISABLE | DPWRDN_DISABLE\
            | DPWRDN_TYPE | TP_DISABLE | DSREF_DIABLE\
            | ADD_LAT_PALL | MEM_TYPE_DDR3 | MEM_WIDTH_32\
            | NUM_CHIP_2 | BL_8)
    
    
    #define CHIP_BANK_8             (0x3 << 0)
    #define CHIP_COL_10             (0x3 << 8)
    #define CHIP_MAP_INTERLEAVED    (0x1 << 12)
    
    #ifdef CONFIG_MIU_LINEAR
    #define CHIP_ROW                (0x2 << 4)
    #define CHIP0_BASE              (0x40 << 24)
    #define CHIP1_BASE              (0x60 << 24)
    #define CHIP_MASK               (0xe0 << 16)
    #else
    #define CHIP_ROW                (0x3 << 4)
    #define CHIP0_BASE              (0x40 << 24)
    #define CHIP1_BASE              (0x80 << 24)
    #define CHIP_MASK               (0x80 << 16)
    #endif
    
    #define MEMCONFIG0_VAL      (CHIP_BANK_8 | CHIP_ROW | CHIP_COL_10\
            | CHIP_MAP_INTERLEAVED | CHIP_MASK | CHIP0_BASE)
    #define MEMCONFIG1_VAL      (CHIP_BANK_8 | CHIP_ROW | CHIP_COL_10\
            | CHIP_MAP_INTERLEAVED | CHIP_MASK | CHIP1_BASE)
    
    #define TP_CNT              (0x64 << 24)
    #define PRECHCONFIG         TP_CNT
    
    #define CTRL_OFF            (0 << 0)
    #define CTRL_DLL_OFF        (0 << 1)
    #define CTRL_HALF           (0 << 2)
    #define CTRL_DFDQS          (1 << 3)
    #define DQS_DELAY           (0 << 4)
    #define CTRL_START_POINT    (0x10 << 8)
    #define CTRL_INC            (0x10 << 16)
    #define CTRL_FORCE          (0x71 << 24)
    #define CONTROL0_VAL        (CTRL_OFF | CTRL_DLL_OFF | CTRL_HALF\
            | CTRL_DFDQS | DQS_DELAY | CTRL_START_POINT\
            | CTRL_INC | CTRL_FORCE)
    
    #define CTRL_SHIFTC         (6 << 0)
    #define CTRL_REF            (8 << 4)
    #define CTRL_SHGATE         (1 << 29)
    #define TERM_READ_EN        (1 << 30)
    #define TERM_WRITE_EN       (1 << 31)
    #define CONTROL1_VAL        (CTRL_SHIFTC | CTRL_REF | CTRL_SHGATE\
            | TERM_READ_EN | TERM_WRITE_EN)
    
    #define CONTROL2_VAL        0x00000000
    
    #ifdef DRAM_CLK_200
    #define TIMINGREF_VAL       0x000000BB
    #define TIMINGROW_VAL       0x4046654f
    #define TIMINGDATA_VAL      0x46400506
    #define TIMINGPOWER_VAL     0x52000A3C
    #endif
    
    #ifdef DRAM_CLK_330
    #define TIMINGREF_VAL       0x000000BC
    #define TIMINGROW_VAL       0x3545548d
    #define TIMINGDATA_VAL      0x45430506
    #define TIMINGPOWER_VAL     0x4439033c
    #endif
    
    #ifdef DRAM_CLK_400
    #define TIMINGREF_VAL       0x000000BC
    #define TIMINGROW_VAL       0x45430506
    #define TIMINGDATA_VAL      0x56500506
    #define TIMINGPOWER_VAL     0x5444033d
    #endif
    
    #endif
    
    

    修改include/configs/itop4412.h,选择合适的时钟#define CONFIG_CLK_1000_200_200

    四、验证结果

    读写验证:在对应的内存区域随机选择内存地址,直接读写,看能否正常读写。

    内存映射:在地址0x40000000处写入数据,在0x80000000读取数据,看其值是否一样。

    内存间歇:在0x80000000附近读写内存,看内存是否连续。

    内存长度:在0xC0000000附近读写内存,看内存实际容量。

    相关文章

      网友评论

          本文标题:iTop4412 uboot-2019.2移植之内存控制器(七)

          本文链接:https://www.haomeiwen.com/subject/gvxumqtx.html