diff options
Diffstat (limited to 'arch/arm/mach-omap2/sdrc.c')
-rw-r--r-- | arch/arm/mach-omap2/sdrc.c | 68 |
1 files changed, 45 insertions, 23 deletions
diff --git a/arch/arm/mach-omap2/sdrc.c b/arch/arm/mach-omap2/sdrc.c index 2045441e8385..9e3bd4fa7810 100644 --- a/arch/arm/mach-omap2/sdrc.c +++ b/arch/arm/mach-omap2/sdrc.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <mach/sdrc.h> | 32 | #include <mach/sdrc.h> |
33 | #include "sdrc.h" | 33 | #include "sdrc.h" |
34 | 34 | ||
35 | static struct omap_sdrc_params *sdrc_init_params; | 35 | static struct omap_sdrc_params *sdrc_init_params_cs0, *sdrc_init_params_cs1; |
36 | 36 | ||
37 | void __iomem *omap2_sdrc_base; | 37 | void __iomem *omap2_sdrc_base; |
38 | void __iomem *omap2_sms_base; | 38 | void __iomem *omap2_sms_base; |
@@ -45,33 +45,49 @@ void __iomem *omap2_sms_base; | |||
45 | /** | 45 | /** |
46 | * omap2_sdrc_get_params - return SDRC register values for a given clock rate | 46 | * omap2_sdrc_get_params - return SDRC register values for a given clock rate |
47 | * @r: SDRC clock rate (in Hz) | 47 | * @r: SDRC clock rate (in Hz) |
48 | * @sdrc_cs0: chip select 0 ram timings ** | ||
49 | * @sdrc_cs1: chip select 1 ram timings ** | ||
48 | * | 50 | * |
49 | * Return pre-calculated values for the SDRC_ACTIM_CTRLA, | 51 | * Return pre-calculated values for the SDRC_ACTIM_CTRLA, |
50 | * SDRC_ACTIM_CTRLB, SDRC_RFR_CTRL, and SDRC_MR registers, for a given | 52 | * SDRC_ACTIM_CTRLB, SDRC_RFR_CTRL and SDRC_MR registers in sdrc_cs[01] |
51 | * SDRC clock rate 'r'. These parameters control various timing | 53 | * structs,for a given SDRC clock rate 'r'. |
52 | * delays in the SDRAM controller that are expressed in terms of the | 54 | * These parameters control various timing delays in the SDRAM controller |
53 | * number of SDRC clock cycles to wait; hence the clock rate | 55 | * that are expressed in terms of the number of SDRC clock cycles to |
54 | * dependency. Note that sdrc_init_params must be sorted rate | 56 | * wait; hence the clock rate dependency. |
55 | * descending. Also assumes that both chip-selects use the same | 57 | * |
56 | * timing parameters. Returns a struct omap_sdrc_params * upon | 58 | * Supports 2 different timing parameters for both chip selects. |
57 | * success, or NULL upon failure. | 59 | * |
60 | * Note 1: the sdrc_init_params_cs[01] must be sorted rate descending. | ||
61 | * Note 2: If sdrc_init_params_cs_1 is not NULL it must be of same size | ||
62 | * as sdrc_init_params_cs_0. | ||
63 | * | ||
64 | * Fills in the struct omap_sdrc_params * for each chip select. | ||
65 | * Returns 0 upon success or -1 upon failure. | ||
58 | */ | 66 | */ |
59 | struct omap_sdrc_params *omap2_sdrc_get_params(unsigned long r) | 67 | int omap2_sdrc_get_params(unsigned long r, |
68 | struct omap_sdrc_params **sdrc_cs0, | ||
69 | struct omap_sdrc_params **sdrc_cs1) | ||
60 | { | 70 | { |
61 | struct omap_sdrc_params *sp; | 71 | struct omap_sdrc_params *sp0, *sp1; |
62 | 72 | ||
63 | if (!sdrc_init_params) | 73 | if (!sdrc_init_params_cs0) |
64 | return NULL; | 74 | return -1; |
65 | 75 | ||
66 | sp = sdrc_init_params; | 76 | sp0 = sdrc_init_params_cs0; |
77 | sp1 = sdrc_init_params_cs1; | ||
67 | 78 | ||
68 | while (sp->rate && sp->rate != r) | 79 | while (sp0->rate && sp0->rate != r) { |
69 | sp++; | 80 | sp0++; |
81 | if (sdrc_init_params_cs1) | ||
82 | sp1++; | ||
83 | } | ||
70 | 84 | ||
71 | if (!sp->rate) | 85 | if (!sp0->rate) |
72 | return NULL; | 86 | return -1; |
73 | 87 | ||
74 | return sp; | 88 | *sdrc_cs0 = sp0; |
89 | *sdrc_cs1 = sp1; | ||
90 | return 0; | ||
75 | } | 91 | } |
76 | 92 | ||
77 | 93 | ||
@@ -83,13 +99,15 @@ void __init omap2_set_globals_sdrc(struct omap_globals *omap2_globals) | |||
83 | 99 | ||
84 | /** | 100 | /** |
85 | * omap2_sdrc_init - initialize SMS, SDRC devices on boot | 101 | * omap2_sdrc_init - initialize SMS, SDRC devices on boot |
86 | * @sp: pointer to a null-terminated list of struct omap_sdrc_params | 102 | * @sdrc_cs[01]: pointers to a null-terminated list of struct omap_sdrc_params |
103 | * Support for 2 chip selects timings | ||
87 | * | 104 | * |
88 | * Turn on smart idle modes for SDRAM scheduler and controller. | 105 | * Turn on smart idle modes for SDRAM scheduler and controller. |
89 | * Program a known-good configuration for the SDRC to deal with buggy | 106 | * Program a known-good configuration for the SDRC to deal with buggy |
90 | * bootloaders. | 107 | * bootloaders. |
91 | */ | 108 | */ |
92 | void __init omap2_sdrc_init(struct omap_sdrc_params *sp) | 109 | void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0, |
110 | struct omap_sdrc_params *sdrc_cs1) | ||
93 | { | 111 | { |
94 | u32 l; | 112 | u32 l; |
95 | 113 | ||
@@ -103,11 +121,15 @@ void __init omap2_sdrc_init(struct omap_sdrc_params *sp) | |||
103 | l |= (0x2 << 3); | 121 | l |= (0x2 << 3); |
104 | sdrc_write_reg(l, SDRC_SYSCONFIG); | 122 | sdrc_write_reg(l, SDRC_SYSCONFIG); |
105 | 123 | ||
106 | sdrc_init_params = sp; | 124 | sdrc_init_params_cs0 = sdrc_cs0; |
125 | sdrc_init_params_cs1 = sdrc_cs1; | ||
107 | 126 | ||
108 | /* XXX Enable SRFRONIDLEREQ here also? */ | 127 | /* XXX Enable SRFRONIDLEREQ here also? */ |
128 | /* | ||
129 | * PWDENA should not be set due to 34xx erratum 1.150 - PWDENA | ||
130 | * can cause random memory corruption | ||
131 | */ | ||
109 | l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) | | 132 | l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) | |
110 | (1 << SDRC_POWER_PWDENA_SHIFT) | | ||
111 | (1 << SDRC_POWER_PAGEPOLICY_SHIFT); | 133 | (1 << SDRC_POWER_PAGEPOLICY_SHIFT); |
112 | sdrc_write_reg(l, SDRC_POWER); | 134 | sdrc_write_reg(l, SDRC_POWER); |
113 | } | 135 | } |