Exemple #1
0
void zynq_ddr_init(void)
{
    SLCR_REG(DDRIOB_ADDR0) = zynq_ddriob_cfg.addr0;
    SLCR_REG(DDRIOB_ADDR1) = zynq_ddriob_cfg.addr1;
    SLCR_REG(DDRIOB_DATA0) = zynq_ddriob_cfg.data0;
    SLCR_REG(DDRIOB_DATA1) = zynq_ddriob_cfg.data1;
    SLCR_REG(DDRIOB_DIFF0) = zynq_ddriob_cfg.diff0;
    SLCR_REG(DDRIOB_DIFF1) = zynq_ddriob_cfg.diff1;
    SLCR_REG(DDRIOB_CLOCK) = DDRIOB_OUTPUT_EN(0x3);

    /* These register fields are not documented in the TRM. These
     * values represent the defaults generated via the Zynq tools
     */
    SLCR_REG(DDRIOB_DRIVE_SLEW_ADDR) = 0x0018C61CU;
    SLCR_REG(DDRIOB_DRIVE_SLEW_DATA) = 0x00F9861CU;
    SLCR_REG(DDRIOB_DRIVE_SLEW_DIFF) = 0x00F9861CU;
    SLCR_REG(DDRIOB_DRIVE_SLEW_CLOCK) = 0x00F9861CU;
    SLCR_REG(DDRIOB_DDR_CTRL) = 0x00000E60U;
    SLCR_REG(DDRIOB_DCI_CTRL) = 0x00000001U;
    SLCR_REG(DDRIOB_DCI_CTRL) |= 0x00000020U;
    SLCR_REG(DDRIOB_DCI_CTRL) |= 0x00000823U;

    /* Write addresss / value pairs from target table */
    for (size_t i = 0; i < zynq_ddr_cfg_cnt; i += 2) {
        *REG32(zynq_ddr_cfg[i]) = zynq_ddr_cfg[i+1];
    }

    /* Wait for DCI done */
    reg_poll((uintptr_t)&SLCR->DDRIOB_DCI_STATUS, 0x2000);

    /* Bring ddr out of reset and wait until self refresh */
    *REG32(DDRC_CTRL) |= DDRC_CTRL_OUT_OF_RESET;
    reg_poll(DDRC_MODE_STATUS, DDRC_STS_SELF_REFRESH);

    /* Switch timer to 64k */
    *REG32(0XF8007000) = *REG32(0xF8007000) & ~0x20000000U;

    if (zynq_ddriob_cfg.ibuf_disable) {
        SLCR_REG(DDRIOB_DATA0) |= DDRIOB_IBUF_DISABLE_MODE;
        SLCR_REG(DDRIOB_DATA1) |= DDRIOB_IBUF_DISABLE_MODE;
        SLCR_REG(DDRIOB_DIFF0) |= DDRIOB_IBUF_DISABLE_MODE;
        SLCR_REG(DDRIOB_DIFF1) |= DDRIOB_IBUF_DISABLE_MODE;
    }

    if (zynq_ddriob_cfg.term_disable) {
        SLCR_REG(DDRIOB_DATA0) |= DDRIOB_TERM_DISABLE_MODE;
        SLCR_REG(DDRIOB_DATA1) |= DDRIOB_TERM_DISABLE_MODE;
        SLCR_REG(DDRIOB_DIFF0) |= DDRIOB_TERM_DISABLE_MODE;
        SLCR_REG(DDRIOB_DIFF1) |= DDRIOB_TERM_DISABLE_MODE;
    }
}
Exemple #2
0
/* For each PLL we need to configure the cp / res / lock_cnt and then place the PLL in bypass
 * before doing a reset to switch to the new values. Then bypass is removed to switch back to using
 * the PLL once its locked.
 */
int zynq_pll_init(void) {
    const zynq_pll_cfg_tree_t *cfg = &zynq_pll_cfg;

    SLCR_REG(ARM_PLL_CFG)  = PLL_CFG_LOCK_CNT(cfg->arm.lock_cnt) | PLL_CFG_PLL_CP(cfg->arm.cp) |
                                PLL_CFG_PLL_RES(cfg->arm.res);
    SLCR_REG(ARM_PLL_CTRL) = PLL_FDIV(cfg->arm.fdiv) | PLL_BYPASS_FORCE | PLL_RESET;
    SLCR_REG(ARM_PLL_CTRL) &= ~PLL_RESET;

    if (reg_poll((uintptr_t)&SLCR->PLL_STATUS, PLL_STATUS_ARM_PLL_LOCK) == -1) {
        return -1;
    }

    SLCR_REG(ARM_PLL_CTRL) &= ~PLL_BYPASS_FORCE;
    SLCR_REG(ARM_CLK_CTRL) = zynq_clk_cfg.arm_clk;

#if ZYNQ_SDRAM_INIT
    SLCR_REG(DDR_PLL_CFG)  = PLL_CFG_LOCK_CNT(cfg->ddr.lock_cnt) | PLL_CFG_PLL_CP(cfg->ddr.cp) |
                                PLL_CFG_PLL_RES(cfg->ddr.res);
    SLCR_REG(DDR_PLL_CTRL) = PLL_FDIV(cfg->ddr.fdiv) | PLL_BYPASS_FORCE | PLL_RESET;
    SLCR_REG(DDR_PLL_CTRL) &= ~PLL_RESET;

    if (reg_poll((uintptr_t)&SLCR->PLL_STATUS, PLL_STATUS_DDR_PLL_LOCK) == -1) {
        return -1;
    }

    SLCR_REG(DDR_PLL_CTRL) &= ~PLL_BYPASS_FORCE;
    SLCR_REG(DDR_CLK_CTRL) = zynq_clk_cfg.ddr_clk;
#elif SDRAM_SIZE == 0
    /* if we're not using sdram and haven't been told to initialize sdram, stop the DDR pll */
    SLCR_REG(DDR_CLK_CTRL) = 0;
    SLCR_REG(DDR_PLL_CTRL) |= PLL_PWRDOWN;
#endif
    SLCR_REG(IO_PLL_CFG)  = PLL_CFG_LOCK_CNT(cfg->io.lock_cnt) | PLL_CFG_PLL_CP(cfg->io.cp) |
                                PLL_CFG_PLL_RES(cfg->io.res);
    SLCR_REG(IO_PLL_CTRL) = PLL_FDIV(cfg->io.fdiv) | PLL_BYPASS_FORCE | PLL_RESET;
    SLCR_REG(IO_PLL_CTRL) &= ~PLL_RESET;

    if (reg_poll((uintptr_t)&SLCR->PLL_STATUS, PLL_STATUS_IO_PLL_LOCK) == -1) {
        return -1;
    }

    SLCR_REG(IO_PLL_CTRL) &= ~PLL_BYPASS_FORCE;
    return 0;
}
Exemple #3
0
/* For each PLL we need to configure the cp / res / lock_cnt and then place the PLL in bypass
 * before doing a reset to switch to the new values. Then bypass is removed to switch back to using
 * the PLL once its locked.
 */
int zynq_pll_init(void) {
    const zynq_pll_cfg_tree_t *cfg = &zynq_pll_cfg;

    zynq_slcr_unlock();
    SLCR_REG(ARM_PLL_CFG)  = PLL_CFG_LOCK_CNT(cfg->arm.lock_cnt) | PLL_CFG_PLL_CP(cfg->arm.cp) |
                                PLL_CFG_PLL_RES(cfg->arm.res);
    SLCR_REG(ARM_PLL_CTRL) = PLL_FDIV(cfg->arm.fdiv) | PLL_BYPASS_FORCE | PLL_RESET;
    SLCR_REG(ARM_PLL_CTRL) &= ~PLL_RESET;

    if (reg_poll((uintptr_t)&SLCR->PLL_STATUS, PLL_STATUS_ARM_PLL_LOCK) == -1) {
        return -1;
    }

    SLCR_REG(ARM_PLL_CTRL) &= ~PLL_BYPASS_FORCE;
    SLCR_REG(ARM_CLK_CTRL) = zynq_clk_cfg.arm_clk;

#if ZYNQ_SDRAM_INIT
    SLCR_REG(DDR_PLL_CFG)  = PLL_CFG_LOCK_CNT(cfg->ddr.lock_cnt) | PLL_CFG_PLL_CP(cfg->ddr.cp) |
                                PLL_CFG_PLL_RES(cfg->ddr.res);
    SLCR_REG(DDR_PLL_CTRL) = PLL_FDIV(cfg->ddr.fdiv) | PLL_BYPASS_FORCE | PLL_RESET;
    SLCR_REG(DDR_PLL_CTRL) &= ~PLL_RESET;

    if (reg_poll((uintptr_t)&SLCR->PLL_STATUS, PLL_STATUS_DDR_PLL_LOCK) == -1) {
        return -1;
    }

    SLCR_REG(DDR_PLL_CTRL) &= ~PLL_BYPASS_FORCE;
    SLCR_REG(DDR_CLK_CTRL) = zynq_clk_cfg.ddr_clk;
#endif
    SLCR_REG(IO_PLL_CFG)  = PLL_CFG_LOCK_CNT(cfg->io.lock_cnt) | PLL_CFG_PLL_CP(cfg->io.cp) |
                                PLL_CFG_PLL_RES(cfg->io.res);
    SLCR_REG(IO_PLL_CTRL) = PLL_FDIV(cfg->io.fdiv) | PLL_BYPASS_FORCE | PLL_RESET;
    SLCR_REG(IO_PLL_CTRL) &= ~PLL_RESET;

    if (reg_poll((uintptr_t)&SLCR->PLL_STATUS, PLL_STATUS_IO_PLL_LOCK) == -1) {
        return -1;
    }

    SLCR_REG(IO_PLL_CTRL) &= ~PLL_BYPASS_FORCE;
    zynq_slcr_lock();
    return 0;
}
Exemple #4
0
void zynq_ddr_init(void)
{
    zynq_slcr_unlock();

    /* Write addresss / value pairs from target table */
    for (size_t i = 0; i < zynq_ddr_cfg_cnt; i += 2) {
        *REG32(zynq_ddr_cfg[i]) = zynq_ddr_cfg[i+1];
    }

    /* Wait for DCI done */
    reg_poll((uintptr_t)&SLCR->DDRIOB_DCI_STATUS, 0x2000);

    /* Bring ddr out of reset and wait until self refresh */
    *REG32(DDRC_CTRL) |= DDRC_CTRL_OUT_OF_RESET;
    reg_poll(DDRC_MODE_STATUS, DDRC_STS_SELF_REFRESH);

    /* Switch timer to 64k */
    *REG32(0XF8007000) = *REG32(0xF8007000) & ~0x20000000U;

    zynq_slcr_lock();
}
Exemple #5
0
void zynq_ddr_init(void)
{
    zynq_slcr_unlock();

    /* Write addresss / value pairs from target table */
    for (size_t i = 0; i < zynq_ddr_cfg_cnt; i += 2) {
        *REG32(zynq_ddr_cfg[i]) = zynq_ddr_cfg[i+1];
    }

    /* Wait for DCI done */
    reg_poll((uintptr_t)&SLCR->DDRIOB_DCI_STATUS, 0x2000);

    /* Bring ddr out of reset and wait until self refresh */
    *REG32(0XF8006000) = 0x00000081U;
    reg_poll(0xf8006054, 0x00000007);

    /* Switch timer to 64k */
    *REG32(0XF8007000) = *REG32(0xF8007000) & ~0x20000000U;

    zynq_slcr_lock();
}