xref: /openbmc/u-boot/arch/arm/mach-at91/sdram.c (revision c5f18a0b)
1 /*
2  * (C) Copyright 2014
3  * Heiko Schocher, DENX Software Engineering, hs@denx.de.
4  *
5  * Based on:
6  * (C) Copyright 2007-2008
7  * Stelian Pop <stelian@popies.net>
8  * Lead Tech Design <www.leadtechdesign.com>
9  *
10  * SPDX-License-Identifier:	GPL-2.0+
11  */
12 
13 #include <common.h>
14 #include <asm/io.h>
15 #include <asm/arch/at91_common.h>
16 #include <asm/arch/at91_pmc.h>
17 #include <asm/arch/at91sam9_sdramc.h>
18 #include <asm/arch/gpio.h>
19 
20 int sdramc_initialize(unsigned int sdram_address, const struct sdramc_reg *p)
21 {
22 	struct sdramc_reg *reg = (struct sdramc_reg *)ATMEL_BASE_SDRAMC;
23 	unsigned int i;
24 
25 	/* SDRAM feature must be in the configuration register */
26 	writel(p->cr, &reg->cr);
27 
28 	/* The SDRAM memory type must be set in the Memory Device Register */
29 	writel(p->mdr, &reg->mdr);
30 
31 	/*
32 	 * The minimum pause of 200 us is provided to precede any single
33 	 * toggle
34 	 */
35 	for (i = 0; i < 1000; i++)
36 		;
37 
38 	/* A NOP command is issued to the SDRAM devices */
39 	writel(AT91_SDRAMC_MODE_NOP, &reg->mr);
40 	writel(0x00000000, sdram_address);
41 
42 	/* An All Banks Precharge command is issued to the SDRAM devices */
43 	writel(AT91_SDRAMC_MODE_PRECHARGE, &reg->mr);
44 	writel(0x00000000, sdram_address);
45 
46 	for (i = 0; i < 10000; i++)
47 		;
48 
49 	/* Eight auto-refresh cycles are provided */
50 	for (i = 0; i < 8; i++) {
51 		writel(AT91_SDRAMC_MODE_REFRESH, &reg->mr);
52 		writel(0x00000001 + i, sdram_address + 4 + 4 * i);
53 	}
54 
55 	/*
56 	 * A Mode Register set (MRS) cyscle is issued to program the
57 	 * SDRAM parameters(TCSR, PASR, DS)
58 	 */
59 	writel(AT91_SDRAMC_MODE_LMR, &reg->mr);
60 	writel(0xcafedede, sdram_address + 0x24);
61 
62 	/*
63 	 * The application must go into Normal Mode, setting Mode
64 	 * to 0 in the Mode Register and perform a write access at
65 	 * any location in the SDRAM.
66 	 */
67 	writel(AT91_SDRAMC_MODE_NORMAL, &reg->mr);
68 	writel(0x00000000, sdram_address);	/* Perform Normal mode */
69 
70 	/*
71 	 * Write the refresh rate into the count field in the SDRAMC
72 	 * Refresh Timer Rgister.
73 	 */
74 	writel(p->tr, &reg->tr);
75 
76 	return 0;
77 }
78