mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-11 07:34:31 +00:00
sunxi: Add F1C100s DRAM initial support
Add support for F1C100s internal dram controller. Signed-off-by: Icenowy Zheng <icenowy@aosc.io> Signed-off-by: Jesse Taube <Mr.Bossman075@gmail.com> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
This commit is contained in:
parent
5d35f0f254
commit
645ee3c25d
5 changed files with 474 additions and 0 deletions
|
@ -31,6 +31,8 @@
|
|||
#include <asm/arch/dram_sun50i_h6.h>
|
||||
#elif defined(CONFIG_MACH_SUN50I_H616)
|
||||
#include <asm/arch/dram_sun50i_h616.h>
|
||||
#elif defined(CONFIG_MACH_SUNIV)
|
||||
#include <asm/arch/dram_suniv.h>
|
||||
#else
|
||||
#include <asm/arch/dram_sun4i.h>
|
||||
#endif
|
||||
|
|
46
arch/arm/include/asm/arch-sunxi/dram_suniv.h
Normal file
46
arch/arm/include/asm/arch-sunxi/dram_suniv.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* suniv DRAM controller register definition
|
||||
*
|
||||
* Copyright (C) 2018 Icenowy Zheng <icenowy@aosc.io>
|
||||
*
|
||||
* Based on xboot's arch/arm32/mach-f1c100s/sys-dram.c, which is:
|
||||
*
|
||||
* Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com>
|
||||
*/
|
||||
|
||||
#define PIO_SDRAM_DRV (0x2c0)
|
||||
#define PIO_SDRAM_PULL (0x2c4)
|
||||
|
||||
#define DRAM_SCONR (0x00)
|
||||
#define DRAM_STMG0R (0x04)
|
||||
#define DRAM_STMG1R (0x08)
|
||||
#define DRAM_SCTLR (0x0c)
|
||||
#define DRAM_SREFR (0x10)
|
||||
#define DRAM_SEXTMR (0x14)
|
||||
#define DRAM_DDLYR (0x24)
|
||||
#define DRAM_DADRR (0x28)
|
||||
#define DRAM_DVALR (0x2c)
|
||||
#define DRAM_DRPTR0 (0x30)
|
||||
#define DRAM_DRPTR1 (0x34)
|
||||
#define DRAM_DRPTR2 (0x38)
|
||||
#define DRAM_DRPTR3 (0x3c)
|
||||
#define DRAM_SEFR (0x40)
|
||||
#define DRAM_MAE (0x44)
|
||||
#define DRAM_ASPR (0x48)
|
||||
#define DRAM_SDLY0 (0x4C)
|
||||
#define DRAM_SDLY1 (0x50)
|
||||
#define DRAM_SDLY2 (0x54)
|
||||
#define DRAM_MCR0 (0x100)
|
||||
#define DRAM_MCR1 (0x104)
|
||||
#define DRAM_MCR2 (0x108)
|
||||
#define DRAM_MCR3 (0x10c)
|
||||
#define DRAM_MCR4 (0x110)
|
||||
#define DRAM_MCR5 (0x114)
|
||||
#define DRAM_MCR6 (0x118)
|
||||
#define DRAM_MCR7 (0x11c)
|
||||
#define DRAM_MCR8 (0x120)
|
||||
#define DRAM_MCR9 (0x124)
|
||||
#define DRAM_MCR10 (0x128)
|
||||
#define DRAM_MCR11 (0x12c)
|
||||
#define DRAM_BWCR (0x140)
|
|
@ -13,6 +13,7 @@ obj-y += dram_helpers.o
|
|||
obj-y += pinmux.o
|
||||
obj-$(CONFIG_SUN6I_PRCM) += prcm.o
|
||||
obj-$(CONFIG_AXP_PMIC_BUS) += pmic_bus.o
|
||||
obj-$(CONFIG_MACH_SUNIV) += clock_sun6i.o
|
||||
obj-$(CONFIG_MACH_SUN4I) += clock_sun4i.o
|
||||
obj-$(CONFIG_MACH_SUN5I) += clock_sun4i.o
|
||||
obj-$(CONFIG_MACH_SUN6I) += clock_sun6i.o
|
||||
|
@ -30,6 +31,7 @@ obj-y += timer.o
|
|||
endif
|
||||
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
obj-$(CONFIG_MACH_SUNIV) += dram_suniv.o
|
||||
obj-$(CONFIG_DRAM_SUN4I) += dram_sun4i.o
|
||||
obj-$(CONFIG_DRAM_SUN6I) += dram_sun6i.o
|
||||
obj-$(CONFIG_DRAM_SUN8I_A23) += dram_sun8i_a23.o
|
||||
|
|
|
@ -26,7 +26,10 @@ void mctl_await_completion(u32 *reg, u32 mask, u32 val)
|
|||
|
||||
/*
|
||||
* Test if memory at offset offset matches memory at begin of DRAM
|
||||
*
|
||||
* Note: dsb() is not available on ARMv5 in Thumb mode
|
||||
*/
|
||||
#ifndef CONFIG_MACH_SUNIV
|
||||
bool mctl_mem_matches(u32 offset)
|
||||
{
|
||||
/* Try to write different values to RAM at two addresses */
|
||||
|
@ -37,3 +40,4 @@ bool mctl_mem_matches(u32 offset)
|
|||
return readl(CONFIG_SYS_SDRAM_BASE) ==
|
||||
readl((ulong)CONFIG_SYS_SDRAM_BASE + offset);
|
||||
}
|
||||
#endif
|
||||
|
|
420
arch/arm/mach-sunxi/dram_suniv.c
Normal file
420
arch/arm/mach-sunxi/dram_suniv.c
Normal file
|
@ -0,0 +1,420 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0+)
|
||||
/*
|
||||
* suniv DRAM initialization
|
||||
*
|
||||
* Copyright (C) 2018 Icenowy Zheng <icenowy@aosc.io>
|
||||
*
|
||||
* Based on xboot's arch/arm32/mach-f1c100s/sys-dram.c, which is:
|
||||
*
|
||||
* Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/dram.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/delay.h>
|
||||
#include <hang.h>
|
||||
|
||||
#define SDR_T_CAS (0x2)
|
||||
#define SDR_T_RAS (0x8)
|
||||
#define SDR_T_RCD (0x3)
|
||||
#define SDR_T_RP (0x3)
|
||||
#define SDR_T_WR (0x3)
|
||||
#define SDR_T_RFC (0xd)
|
||||
#define SDR_T_XSR (0xf9)
|
||||
#define SDR_T_RC (0xb)
|
||||
#define SDR_T_INIT (0x8)
|
||||
#define SDR_T_INIT_REF (0x7)
|
||||
#define SDR_T_WTR (0x2)
|
||||
#define SDR_T_RRD (0x2)
|
||||
#define SDR_T_XP (0x0)
|
||||
|
||||
enum dram_type {
|
||||
DRAM_TYPE_SDR = 0,
|
||||
DRAM_TYPE_DDR = 1,
|
||||
/* Not supported yet. */
|
||||
DRAM_TYPE_MDDR = 2,
|
||||
};
|
||||
|
||||
struct dram_para {
|
||||
u32 size; /* dram size (unit: MByte) */
|
||||
u32 clk; /* dram work clock (unit: MHz) */
|
||||
u32 access_mode; /* 0: interleave mode 1: sequence mode */
|
||||
u32 cs_num; /* dram chip count 1: one chip 2: two chip */
|
||||
u32 ddr8_remap; /* for 8bits data width DDR 0: normal 1: 8bits */
|
||||
enum dram_type sdr_ddr;
|
||||
u32 bwidth; /* dram bus width */
|
||||
u32 col_width; /* column address width */
|
||||
u32 row_width; /* row address width */
|
||||
u32 bank_size; /* dram bank count */
|
||||
u32 cas; /* dram cas */
|
||||
};
|
||||
|
||||
struct dram_para suniv_dram_para = {
|
||||
.size = 32,
|
||||
.clk = 156,
|
||||
.access_mode = 1,
|
||||
.cs_num = 1,
|
||||
.ddr8_remap = 0,
|
||||
.sdr_ddr = DRAM_TYPE_DDR,
|
||||
.bwidth = 16,
|
||||
.col_width = 10,
|
||||
.row_width = 13,
|
||||
.bank_size = 4,
|
||||
.cas = 0x3,
|
||||
};
|
||||
|
||||
static int dram_initial(void)
|
||||
{
|
||||
unsigned int time = 0xffffff;
|
||||
|
||||
setbits_le32(SUNXI_DRAMC_BASE + DRAM_SCTLR, 0x1);
|
||||
while ((readl(SUNXI_DRAMC_BASE + DRAM_SCTLR) & 0x1) && time--) {
|
||||
if (time == 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dram_delay_scan(void)
|
||||
{
|
||||
unsigned int time = 0xffffff;
|
||||
|
||||
setbits_le32(SUNXI_DRAMC_BASE + DRAM_DDLYR, 0x1);
|
||||
while ((readl(SUNXI_DRAMC_BASE + DRAM_DDLYR) & 0x1) && time--) {
|
||||
if (time == 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void dram_set_autofresh_cycle(u32 clk)
|
||||
{
|
||||
u32 val = 0;
|
||||
u32 row = 0;
|
||||
u32 temp = 0;
|
||||
|
||||
row = readl(SUNXI_DRAMC_BASE + DRAM_SCONR);
|
||||
row &= 0x1e0;
|
||||
row >>= 0x5;
|
||||
|
||||
if (row == 0xc) {
|
||||
if (clk >= 1000000) {
|
||||
temp = clk + (clk >> 3) + (clk >> 4) + (clk >> 5);
|
||||
while (temp >= (10000000 >> 6)) {
|
||||
temp -= (10000000 >> 6);
|
||||
val++;
|
||||
}
|
||||
} else {
|
||||
val = (clk * 499) >> 6;
|
||||
}
|
||||
} else if (row == 0xb) {
|
||||
if (clk >= 1000000) {
|
||||
temp = clk + (clk >> 3) + (clk >> 4) + (clk >> 5);
|
||||
while (temp >= (10000000 >> 7)) {
|
||||
temp -= (10000000 >> 7);
|
||||
val++;
|
||||
}
|
||||
} else {
|
||||
val = (clk * 499) >> 5;
|
||||
}
|
||||
}
|
||||
writel(val, SUNXI_DRAMC_BASE + DRAM_SREFR);
|
||||
}
|
||||
|
||||
static int dram_para_setup(struct dram_para *para)
|
||||
{
|
||||
u32 val = 0;
|
||||
|
||||
val = (para->ddr8_remap) | (0x1 << 1) |
|
||||
((para->bank_size >> 2) << 3) |
|
||||
((para->cs_num >> 1) << 4) |
|
||||
((para->row_width - 1) << 5) |
|
||||
((para->col_width - 1) << 9) |
|
||||
((para->sdr_ddr ? (para->bwidth >> 4) : (para->bwidth >> 5)) << 13) |
|
||||
(para->access_mode << 15) |
|
||||
(para->sdr_ddr << 16);
|
||||
|
||||
writel(val, SUNXI_DRAMC_BASE + DRAM_SCONR);
|
||||
setbits_le32(SUNXI_DRAMC_BASE + DRAM_SCTLR, 0x1 << 19);
|
||||
return dram_initial();
|
||||
}
|
||||
|
||||
static u32 dram_check_delay(u32 bwidth)
|
||||
{
|
||||
u32 dsize;
|
||||
int i, j;
|
||||
u32 num = 0;
|
||||
u32 dflag = 0;
|
||||
|
||||
dsize = ((bwidth == 16) ? 4 : 2);
|
||||
for (i = 0; i < dsize; i++) {
|
||||
if (i == 0)
|
||||
dflag = readl(SUNXI_DRAMC_BASE + DRAM_DRPTR0);
|
||||
else if (i == 1)
|
||||
dflag = readl(SUNXI_DRAMC_BASE + DRAM_DRPTR1);
|
||||
else if (i == 2)
|
||||
dflag = readl(SUNXI_DRAMC_BASE + DRAM_DRPTR2);
|
||||
else if (i == 3)
|
||||
dflag = readl(SUNXI_DRAMC_BASE + DRAM_DRPTR3);
|
||||
|
||||
for (j = 0; j < 32; j++) {
|
||||
if (dflag & 0x1)
|
||||
num++;
|
||||
dflag >>= 1;
|
||||
}
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
static int sdr_readpipe_scan(void)
|
||||
{
|
||||
u32 k = 0;
|
||||
|
||||
for (k = 0; k < 32; k++)
|
||||
writel(k, CONFIG_SYS_SDRAM_BASE + 4 * k);
|
||||
for (k = 0; k < 32; k++) {
|
||||
if (readl(CONFIG_SYS_SDRAM_BASE + 4 * k) != k)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static u32 sdr_readpipe_select(void)
|
||||
{
|
||||
u32 value = 0;
|
||||
u32 i = 0;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
clrsetbits_le32(SUNXI_DRAMC_BASE + DRAM_SCTLR,
|
||||
0x7 << 6, i << 6);
|
||||
if (sdr_readpipe_scan()) {
|
||||
value = i;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
static u32 dram_check_type(struct dram_para *para)
|
||||
{
|
||||
u32 times = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
clrsetbits_le32(SUNXI_DRAMC_BASE + DRAM_SCTLR,
|
||||
0x7 << 6, i << 6);
|
||||
dram_delay_scan();
|
||||
if (readl(SUNXI_DRAMC_BASE + DRAM_DDLYR) & 0x30)
|
||||
times++;
|
||||
}
|
||||
|
||||
if (times == 8) {
|
||||
para->sdr_ddr = DRAM_TYPE_SDR;
|
||||
return 0;
|
||||
}
|
||||
para->sdr_ddr = DRAM_TYPE_DDR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static u32 dram_scan_readpipe(struct dram_para *para)
|
||||
{
|
||||
u32 rp_best = 0, rp_val = 0;
|
||||
u32 readpipe[8];
|
||||
int i;
|
||||
|
||||
if (para->sdr_ddr == DRAM_TYPE_DDR) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
clrsetbits_le32(SUNXI_DRAMC_BASE + DRAM_SCTLR,
|
||||
0x7 << 6, i << 6);
|
||||
dram_delay_scan();
|
||||
readpipe[i] = 0;
|
||||
if ((((readl(SUNXI_DRAMC_BASE + DRAM_DDLYR) >> 4) & 0x3) == 0x0) &&
|
||||
(((readl(SUNXI_DRAMC_BASE + DRAM_DDLYR) >> 4) & 0x1) == 0x0))
|
||||
readpipe[i] = dram_check_delay(para->bwidth);
|
||||
if (rp_val < readpipe[i]) {
|
||||
rp_val = readpipe[i];
|
||||
rp_best = i;
|
||||
}
|
||||
}
|
||||
clrsetbits_le32(SUNXI_DRAMC_BASE + DRAM_SCTLR,
|
||||
0x7 << 6, rp_best << 6);
|
||||
dram_delay_scan();
|
||||
} else {
|
||||
clrbits_le32(SUNXI_DRAMC_BASE + DRAM_SCONR,
|
||||
(0x1 << 16) | (0x3 << 13));
|
||||
rp_best = sdr_readpipe_select();
|
||||
clrsetbits_le32(SUNXI_DRAMC_BASE + DRAM_SCTLR,
|
||||
0x7 << 6, rp_best << 6);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 dram_get_dram_size(struct dram_para *para)
|
||||
{
|
||||
u32 colflag = 10, rowflag = 13;
|
||||
u32 val1 = 0;
|
||||
u32 count = 0;
|
||||
u32 addr1, addr2;
|
||||
int i;
|
||||
|
||||
para->col_width = colflag;
|
||||
para->row_width = rowflag;
|
||||
dram_para_setup(para);
|
||||
dram_scan_readpipe(para);
|
||||
for (i = 0; i < 32; i++) {
|
||||
*((u8 *)(CONFIG_SYS_SDRAM_BASE + 0x200 + i)) = 0x11;
|
||||
*((u8 *)(CONFIG_SYS_SDRAM_BASE + 0x600 + i)) = 0x22;
|
||||
}
|
||||
for (i = 0; i < 32; i++) {
|
||||
val1 = *((u8 *)(CONFIG_SYS_SDRAM_BASE + 0x200 + i));
|
||||
if (val1 == 0x22)
|
||||
count++;
|
||||
}
|
||||
if (count == 32)
|
||||
colflag = 9;
|
||||
else
|
||||
colflag = 10;
|
||||
count = 0;
|
||||
para->col_width = colflag;
|
||||
para->row_width = rowflag;
|
||||
dram_para_setup(para);
|
||||
if (colflag == 10) {
|
||||
addr1 = CONFIG_SYS_SDRAM_BASE + 0x400000;
|
||||
addr2 = CONFIG_SYS_SDRAM_BASE + 0xc00000;
|
||||
} else {
|
||||
addr1 = CONFIG_SYS_SDRAM_BASE + 0x200000;
|
||||
addr2 = CONFIG_SYS_SDRAM_BASE + 0x600000;
|
||||
}
|
||||
for (i = 0; i < 32; i++) {
|
||||
*((u8 *)(addr1 + i)) = 0x33;
|
||||
*((u8 *)(addr2 + i)) = 0x44;
|
||||
}
|
||||
for (i = 0; i < 32; i++) {
|
||||
val1 = *((u8 *)(addr1 + i));
|
||||
if (val1 == 0x44)
|
||||
count++;
|
||||
}
|
||||
if (count == 32)
|
||||
rowflag = 12;
|
||||
else
|
||||
rowflag = 13;
|
||||
para->col_width = colflag;
|
||||
para->row_width = rowflag;
|
||||
if (para->row_width != 13)
|
||||
para->size = 16;
|
||||
else if (para->col_width == 10)
|
||||
para->size = 64;
|
||||
else
|
||||
para->size = 32;
|
||||
dram_set_autofresh_cycle(para->clk);
|
||||
para->access_mode = 0;
|
||||
dram_para_setup(para);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void simple_dram_check(void)
|
||||
{
|
||||
volatile u32 *dram = (u32 *)CONFIG_SYS_SDRAM_BASE;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 0x40; i++)
|
||||
dram[i] = i;
|
||||
|
||||
for (i = 0; i < 0x40; i++) {
|
||||
if (dram[i] != i) {
|
||||
printf("DRAM initialization failed: dram[0x%x] != 0x%x.", i, dram[i]);
|
||||
hang();
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 0x10000; i += 0x40)
|
||||
dram[i] = i;
|
||||
|
||||
for (i = 0; i < 0x10000; i += 0x40) {
|
||||
if (dram[i] != i) {
|
||||
printf("DRAM initialization failed: dram[0x%x] != 0x%x.", i, dram[i]);
|
||||
hang();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void do_dram_init(struct dram_para *para)
|
||||
{
|
||||
struct sunxi_ccm_reg * const ccm =
|
||||
(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
|
||||
u32 val;
|
||||
u8 m; /* PLL_DDR clock factor */
|
||||
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPB(3), 0x7);
|
||||
mdelay(5);
|
||||
/* TODO: dig out what's them... some analog register? */
|
||||
if ((para->cas >> 3) & 0x1)
|
||||
setbits_le32(SUNXI_PIO_BASE + 0x2c4, (0x1 << 23) | (0x20 << 17));
|
||||
|
||||
if (para->clk >= 144 && para->clk <= 180)
|
||||
writel(0xaaa, SUNXI_PIO_BASE + 0x2c0);
|
||||
if (para->clk >= 180)
|
||||
writel(0xfff, SUNXI_PIO_BASE + 0x2c0);
|
||||
|
||||
if (para->cas & BIT(4))
|
||||
writel(0xd1303333, &ccm->pll5_pattern_cfg);
|
||||
else if (para->cas & BIT(5))
|
||||
writel(0xcce06666, &ccm->pll5_pattern_cfg);
|
||||
else if (para->cas & BIT(6))
|
||||
writel(0xc8909999, &ccm->pll5_pattern_cfg);
|
||||
else if (para->cas & BIT(7))
|
||||
writel(0xc440cccc, &ccm->pll5_pattern_cfg);
|
||||
|
||||
if (para->clk <= 96)
|
||||
m = 2;
|
||||
else
|
||||
m = 1;
|
||||
|
||||
val = CCM_PLL5_CTRL_EN | CCM_PLL5_CTRL_UPD |
|
||||
CCM_PLL5_CTRL_N((para->clk * 2) / (24 / m)) |
|
||||
CCM_PLL5_CTRL_K(1) | CCM_PLL5_CTRL_M(m);
|
||||
if (para->cas & GENMASK(7, 4))
|
||||
val |= CCM_PLL5_CTRL_SIGMA_DELTA_EN;
|
||||
writel(val, &ccm->pll5_cfg);
|
||||
setbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_UPD);
|
||||
mctl_await_completion(&ccm->pll5_cfg, BIT(28), BIT(28));
|
||||
mdelay(5);
|
||||
|
||||
setbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_MCTL));
|
||||
clrbits_le32(&ccm->ahb_reset0_cfg, (1 << AHB_RESET_OFFSET_MCTL));
|
||||
udelay(50);
|
||||
setbits_le32(&ccm->ahb_reset0_cfg, (1 << AHB_RESET_OFFSET_MCTL));
|
||||
|
||||
clrsetbits_le32(SUNXI_PIO_BASE + 0x2c4, (1 << 16),
|
||||
((para->sdr_ddr == DRAM_TYPE_DDR) << 16));
|
||||
|
||||
val = (SDR_T_CAS << 0) | (SDR_T_RAS << 3) | (SDR_T_RCD << 7) |
|
||||
(SDR_T_RP << 10) | (SDR_T_WR << 13) | (SDR_T_RFC << 15) |
|
||||
(SDR_T_XSR << 19) | (SDR_T_RC << 28);
|
||||
writel(val, SUNXI_DRAMC_BASE + DRAM_STMG0R);
|
||||
val = (SDR_T_INIT << 0) | (SDR_T_INIT_REF << 16) | (SDR_T_WTR << 20) |
|
||||
(SDR_T_RRD << 22) | (SDR_T_XP << 25);
|
||||
writel(val, SUNXI_DRAMC_BASE + DRAM_STMG1R);
|
||||
dram_para_setup(para);
|
||||
dram_check_type(para);
|
||||
|
||||
clrsetbits_le32(SUNXI_PIO_BASE + 0x2c4, (1 << 16),
|
||||
((para->sdr_ddr == DRAM_TYPE_DDR) << 16));
|
||||
|
||||
dram_set_autofresh_cycle(para->clk);
|
||||
dram_scan_readpipe(para);
|
||||
dram_get_dram_size(para);
|
||||
simple_dram_check();
|
||||
}
|
||||
|
||||
unsigned long sunxi_dram_init(void)
|
||||
{
|
||||
do_dram_init(&suniv_dram_para);
|
||||
|
||||
return suniv_dram_para.size * 1024 * 1024;
|
||||
}
|
Loading…
Reference in a new issue