// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2016 Marek Vasut * * Based on RAM init sequence by Piotr Dymacz */ #include #include #include #include #include #include #include #include #include DECLARE_GLOBAL_DATA_PTR; enum { AR934X_SDRAM = 0, AR934X_DDR1, AR934X_DDR2, }; struct ar934x_mem_config { u32 config1; u32 config2; u32 mode; u32 extmode; u32 tap; }; static const struct ar934x_mem_config ar934x_mem_config[] = { [AR934X_SDRAM] = { 0x7fbe8cd0, 0x959f66a8, 0x33, 0, 0x1f1f }, [AR934X_DDR1] = { 0x7fd48cd0, 0x99d0e6a8, 0x33, 0, 0x14 }, [AR934X_DDR2] = { 0xc7d48cd0, 0x9dd0e6a8, 0x33, 0, 0x10012 }, }; void ar934x_ddr_init(const u16 cpu_mhz, const u16 ddr_mhz, const u16 ahb_mhz) { void __iomem *ddr_regs; const struct ar934x_mem_config *memcfg; int memtype; u32 reg, cycle, ctl; ddr_regs = map_physmem(AR71XX_DDR_CTRL_BASE, AR71XX_DDR_CTRL_SIZE, MAP_NOCACHE); reg = ath79_get_bootstrap(); if (reg & AR934X_BOOTSTRAP_SDRAM_DISABLED) { /* DDR */ if (reg & AR934X_BOOTSTRAP_DDR1) { /* DDR 1 */ memtype = AR934X_DDR1; cycle = 0xffff; } else { /* DDR 2 */ memtype = AR934X_DDR2; if (gd->arch.rev) { ctl = BIT(6); /* Undocumented bit :-( */ if (reg & BIT(3)) cycle = 0xff; else cycle = 0xffff; } else { /* Force DDR2/x16 configuratio on old chips. */ ctl = 0; cycle = 0xffff; /* DDR2 16bit */ } writel(0xe59, ddr_regs + AR934X_DDR_REG_DDR2_CONFIG); udelay(100); writel(0x10, ddr_regs + AR71XX_DDR_REG_CONTROL); udelay(10); writel(0x20, ddr_regs + AR71XX_DDR_REG_CONTROL); udelay(10); writel(ctl, ddr_regs + AR934X_DDR_REG_CTL_CONF); udelay(10); } } else { /* SDRAM */ memtype = AR934X_SDRAM; cycle = 0xffffffff; writel(0x13b, ddr_regs + AR934X_DDR_REG_CTL_CONF); udelay(100); /* Undocumented register */ writel(0x13b, ddr_regs + 0x118); udelay(100); } memcfg = &ar934x_mem_config[memtype]; writel(memcfg->config1, ddr_regs + AR71XX_DDR_REG_CONFIG); udelay(100); writel(memcfg->config2, ddr_regs + AR71XX_DDR_REG_CONFIG2); udelay(100); writel(0x8, ddr_regs + AR71XX_DDR_REG_CONTROL); udelay(10); writel(memcfg->mode | 0x100, ddr_regs + AR71XX_DDR_REG_MODE); mdelay(1); writel(0x1, ddr_regs + AR71XX_DDR_REG_CONTROL); udelay(10); if (memtype == AR934X_DDR2) { writel(memcfg->mode | 0x100, ddr_regs + AR71XX_DDR_REG_EMR); udelay(100); writel(0x2, ddr_regs + AR71XX_DDR_REG_CONTROL); udelay(10); } if (memtype != AR934X_SDRAM) writel(0x402, ddr_regs + AR71XX_DDR_REG_EMR); udelay(100); writel(0x2, ddr_regs + AR71XX_DDR_REG_CONTROL); udelay(10); writel(0x8, ddr_regs + AR71XX_DDR_REG_CONTROL); udelay(10); writel(memcfg->mode, ddr_regs + AR71XX_DDR_REG_MODE); udelay(100); writel(0x1, ddr_regs + AR71XX_DDR_REG_CONTROL); udelay(10); writel(0x412c /* FIXME */, ddr_regs + AR71XX_DDR_REG_REFRESH); udelay(100); writel(memcfg->tap, ddr_regs + AR71XX_DDR_REG_TAP_CTRL0); writel(memcfg->tap, ddr_regs + AR71XX_DDR_REG_TAP_CTRL1); if (memtype != AR934X_SDRAM) { if ((gd->arch.rev && (reg & BIT(3))) || !gd->arch.rev) { writel(memcfg->tap, ddr_regs + AR934X_DDR_REG_TAP_CTRL2); writel(memcfg->tap, ddr_regs + AR934X_DDR_REG_TAP_CTRL3); } } writel(cycle, ddr_regs + AR71XX_DDR_REG_RD_CYCLE); udelay(100); writel(0x74444444, ddr_regs + AR934X_DDR_REG_BURST); udelay(100); writel(0x222, ddr_regs + AR934X_DDR_REG_BURST2); udelay(100); writel(0xfffff, ddr_regs + AR934X_DDR_REG_TIMEOUT_MAX); udelay(100); } void ddr_tap_tuning(void) { }