diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2013-08-22 23:42:26 +0200 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2013-08-22 23:42:26 +0200 |
commit | fb35f06bf5812a3256b7313b78d39e8fec112fe8 (patch) | |
tree | 8c8b41f11a6a1f58472b1e2acbe7bc885eab06c6 /firmware | |
parent | 142ce48771206a362988f1745a33b9ada74f66dd (diff) | |
download | rockbox-fb35f06bf5812a3256b7313b78d39e8fec112fe8.tar.gz rockbox-fb35f06bf5812a3256b7313b78d39e8fec112fe8.zip |
imx233: rework emi frequency scaling
Drop most of the cases: only keep 64 MHz and 133 MHz. Pick values
from the manual which seem to match real life values.
Change-Id: I912752fbe372f9f44207db6853d0ff92fd619bed
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/target/arm/imx233/emi-imx233.c | 105 |
1 files changed, 48 insertions, 57 deletions
diff --git a/firmware/target/arm/imx233/emi-imx233.c b/firmware/target/arm/imx233/emi-imx233.c index 7e44c17c05..1ae6e22f48 100644 --- a/firmware/target/arm/imx233/emi-imx233.c +++ b/firmware/target/arm/imx233/emi-imx233.c | |||
@@ -28,62 +28,48 @@ struct emi_reg_t | |||
28 | uint32_t value; | 28 | uint32_t value; |
29 | }; | 29 | }; |
30 | 30 | ||
31 | /* hardcode all the register values for the different settings. This is ugly | 31 | /* hardcode all the register values for the different settings. This avoid |
32 | * but I don't understand what they mean and it's faster this way so... | 32 | * computing the register values at runtime since they never change and also |
33 | * Recall that everything should be put in iram ! | 33 | * avoid wasting some space in iram. |
34 | * Values from IMX233 manual, for Mobile DDR 7.5ns (133 MHz and 64MHz) | ||
34 | * Make sure the last value is written to register 40. */ | 35 | * Make sure the last value is written to register 40. */ |
35 | 36 | ||
36 | /* Values extracted from Sigmatel linux port (GPL) */ | ||
37 | |||
38 | /** mDDR value */ | ||
39 | static struct emi_reg_t settings_24M[15] ICONST_ATTR = | ||
40 | { | ||
41 | {4, 0x01000101}, {7, 0x01000101}, {12, 0x02010002}, {13, 0x06060a02}, | ||
42 | {15, 0x01030000}, {17, 0x2d000102}, {18, 0x20200000}, {19, 0x027f1414}, | ||
43 | {20, 0x01021608}, {21, 0x00000002}, {26, 0x000000b3}, {32, 0x00030687}, | ||
44 | {33, 0x00000003}, {34, 0x000012c1}, {40, 0x00010000} | ||
45 | }; | ||
46 | |||
47 | static struct emi_reg_t settings_48M[15] ICONST_ATTR = | ||
48 | { | ||
49 | {4, 0x01000101}, {7, 0x01000101}, {13, 0x06060a02}, {12, 0x02010002}, | ||
50 | {15, 0x02040000}, {17, 0x2d000104}, {18, 0x1f1f0000}, {19, 0x027f0a0a}, | ||
51 | {20, 0x01021608}, {21, 0x00000004}, {26, 0x0000016f}, {32, 0x00060d17}, | ||
52 | {33, 0x00000006}, {34, 0x00002582}, {40, 0x00020000} | ||
53 | }; | ||
54 | |||
55 | static struct emi_reg_t settings_60M[15] ICONST_ATTR = | 37 | static struct emi_reg_t settings_60M[15] ICONST_ATTR = |
56 | { | 38 | { |
57 | {4, 0x01000101}, {7, 0x01000101}, {12, 0x02020002}, {13, 0x06060a02}, | 39 | {4, 0x01000101}, /* DLL bypass mode, concurrent auto-precharge and bank split */ |
58 | {15, 0x02040000}, {17, 0x2d000005}, {18, 0x1f1f0000}, {19, 0x027f0a0a}, | 40 | {7, 0x01000101}, /* Read/write grouping, extra clock for back to back, priority placement */ |
59 | {20, 0x02040a10}, {21, 0x00000006}, {26, 0x000001cc}, {32, 0x00081060}, | 41 | {12, 0x02020002}, /* tWR = 2 cycles, tRRD = 1 cycles, tCKE = 2 cycles */ |
60 | {33, 0x00000008}, {34, 0x00002ee5}, {40, 0x00020000} | 42 | {13, 0x06060a02}, /* CAS lat gate = 3.0 cycles, CAS lat = 3.0 cycles, tWTR = 2 */ |
61 | }; | 43 | {15, 0x02040000}, /* tRP = 2 cycles, tDAL = 4 cycles */ |
62 | 44 | {17, 0x2d000005}, /* DDL: start point = 45, lock = 0, increment = 0, tRC = 5 cycles */ | |
63 | static struct emi_reg_t settings_80M[15] ICONST_ATTR __attribute__((alias("settings_60M"))); | 45 | {18, 0x00000000}, /* */ |
64 | 46 | {19, 0x01000b0b}, /* DLL: DQS out shift (bypass) = 1, DQS delay bypass (1/0) = 11 / 11 */ | |
65 | static struct emi_reg_t settings_96M[15] ICONST_ATTR = | 47 | {20, 0x02030a00}, /* tRCD = 2 cycles, tRAS (min) = 3 cycles, DQS write shift (bypass) = 10 */ |
66 | { | 48 | {21, 0x00000005}, /* tRFC = 5 cycles */ |
67 | {4, 0x00000101}, {7, 0x01000001}, {12, 0x02020002}, {13, 0x06070a02}, | 49 | {26, 0x000001cc}, /* tREF = 460 cycles */ |
68 | {15, 0x03050000}, {17, 0x2d000808}, {18, 0x1f1f0000}, {19, 0x020c1010}, | 50 | {32, 0x00081060}, /* tRAS (max) = 4192 cycles, tXSNR = 8 cycles */ |
69 | {20, 0x0305101c}, {21, 0x00000007}, {26, 0x000002e6}, {32, 0x000c1a3b}, | 51 | {33, 0x00000008}, /* tXSR = 8 cycles */ |
70 | {33, 0x0000000c}, {34, 0x00004b0d}, {40, 0x00030000} | 52 | {34, 0x00002ee5}, /* tINIT = 12005 cycles */ |
71 | }; | 53 | {40, 0x00020000} /* tPDEX = 2 */ |
72 | |||
73 | static struct emi_reg_t settings_120M[15] ICONST_ATTR = | ||
74 | { | ||
75 | {4, 0x00000101}, {7, 0x01000001}, {12, 0x02020002}, {13, 0x06070a02}, | ||
76 | {15, 0x03050000}, {17, 0x2300080a}, {18, 0x1f1f0000}, {19, 0x020c1010}, | ||
77 | {20, 0x0306101c}, {21, 0x00000009}, {26, 0x000003a1}, {32, 0x000f20ca}, | ||
78 | {33, 0x0000000f}, {34, 0x00005dca}, {40, 0x00040000} | ||
79 | }; | 54 | }; |
80 | 55 | ||
81 | static struct emi_reg_t settings_133M[15] ICONST_ATTR = | 56 | static struct emi_reg_t settings_133M[15] ICONST_ATTR = |
82 | { | 57 | { |
83 | {4, 0x00000101}, {7, 0x01000001}, {12, 0x02020002}, {13, 0x06070a02}, | 58 | {4, 0x00000101}, /* concurrent auto-precharge and bank split */ |
84 | {15, 0x03050000}, {17, 0x2000080a}, {18, 0x1f1f0000}, {19, 0x020c1010}, | 59 | {7, 0x01000001}, /* Read/write grouping, priority placement */ |
85 | {20, 0x0306101c}, {21, 0x0000000a}, {26, 0x00000408}, {32, 0x0010245f}, | 60 | {12, 0x02020002}, /* tWR = 2 cycles, tRRD = 2 cycles, tCKE = 2 cycles */ |
86 | {33, 0x00000010}, {34, 0x00006808}, {40, 0x00040000} | 61 | {13, 0x06070a02}, /* CAS lat gate = 3.0 cycles, CAS lat = 3.5 cycles, tWTR = 2 */ |
62 | {15, 0x03050000}, /* tRP = 3 cycles, tDAL = 5 cycles */ | ||
63 | {17, 0x19000f0a}, /* DDL: start point = 25, lock = 0, increment = 15, tRC = 10 cycles */ | ||
64 | {18, 0x1f1f0000}, /* DLL: DQS delay (1/0) = 31 / 31 */ | ||
65 | {19, 0x000a0000}, /* DLL: DQS out shift = 10 */ | ||
66 | {20, 0x03060023}, /* tRCD = 3 cycles, tRAS (min) = 6 cycles, DQS write shift = 35 */ | ||
67 | {21, 0x0000000a}, /* tRFC = 10 cycles */ | ||
68 | {26, 0x000003f7}, /* tREF = 1015 cycles */ | ||
69 | {32, 0x001023cd}, /* tRAS (max) = 9165 cycles, tXSNR = 16 cycles */ | ||
70 | {33, 0x00000010}, /* tXSR = 16 cycles */ | ||
71 | {34, 0x00006665}, /* tINIT = 26213 cycles */ | ||
72 | {40, 0x00040000} /* tPDEX = 4 */ | ||
87 | }; | 73 | }; |
88 | 74 | ||
89 | static struct emi_reg_t settings_155M[15] ICONST_ATTR __attribute__((alias("settings_133M"))); | 75 | static struct emi_reg_t settings_155M[15] ICONST_ATTR __attribute__((alias("settings_133M"))); |
@@ -148,7 +134,7 @@ void imx233_emi_set_frequency(unsigned long freq) | |||
148 | * possible in this state anyway. | 134 | * possible in this state anyway. |
149 | * WARNING DANGER don't call any external function when sdram is disabled | 135 | * WARNING DANGER don't call any external function when sdram is disabled |
150 | * otherwise you'll poke sdram and trigger a fatal data abort ! */ | 136 | * otherwise you'll poke sdram and trigger a fatal data abort ! */ |
151 | 137 | ||
152 | /* first disable all interrupts */ | 138 | /* first disable all interrupts */ |
153 | int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS); | 139 | int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS); |
154 | /* flush the cache */ | 140 | /* flush the cache */ |
@@ -159,14 +145,19 @@ void imx233_emi_set_frequency(unsigned long freq) | |||
159 | while(!BF_RD(EMI_STAT, DRAM_HALTED)); | 145 | while(!BF_RD(EMI_STAT, DRAM_HALTED)); |
160 | /* load timings */ | 146 | /* load timings */ |
161 | struct emi_reg_t *regs; | 147 | struct emi_reg_t *regs; |
162 | if(freq <= 24000) regs = settings_24M; | 148 | switch(freq) |
163 | else if(freq <= 48000) regs = settings_48M; | 149 | { |
164 | else if(freq <= 60000) regs = settings_60M; | 150 | case IMX233_EMIFREQ_151_MHz: |
165 | else if(freq <= 80000) regs = settings_80M; | 151 | regs = settings_155M; |
166 | else if(freq <= 96000) regs = settings_96M; | 152 | break; |
167 | else if(freq <= 120000) regs = settings_120M; | 153 | case IMX233_EMIFREQ_130_MHz: |
168 | else if(freq <= 133000) regs = settings_133M; | 154 | regs = settings_133M; |
169 | else regs = settings_155M; | 155 | break; |
156 | case IMX233_EMIFREQ_64_MHz: | ||
157 | default: | ||
158 | regs = settings_60M; | ||
159 | break; | ||
160 | } | ||
170 | 161 | ||
171 | do | 162 | do |
172 | HW_DRAM_CTLxx(regs->index) = regs->value; | 163 | HW_DRAM_CTLxx(regs->index) = regs->value; |