summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2013-08-21 11:11:36 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2013-08-21 20:18:36 +0200
commit96d355abba19f3f099f94a8b2d3e95be32c39be7 (patch)
treef7f7a31eb7f6d69430f9a2eda4e2dd5d8dcebdfe /firmware/target
parent462adf2a0fefbfdbccfafa11c999ac6beb114e8a (diff)
downloadrockbox-96d355abba19f3f099f94a8b2d3e95be32c39be7.tar.gz
rockbox-96d355abba19f3f099f94a8b2d3e95be32c39be7.zip
imx233: fix drive strength for sd/mmc
At high speed, we need a drive strength of 8mA on the clock line to get stable transfers. Change-Id: Ida668db10cd3e10ad5740e35fd973f2fa394edb2
Diffstat (limited to 'firmware/target')
-rw-r--r--firmware/target/arm/imx233/sdmmc-imx233.c20
-rw-r--r--firmware/target/arm/imx233/ssp-imx233.c61
-rw-r--r--firmware/target/arm/imx233/ssp-imx233.h6
3 files changed, 47 insertions, 40 deletions
diff --git a/firmware/target/arm/imx233/sdmmc-imx233.c b/firmware/target/arm/imx233/sdmmc-imx233.c
index 99dd817ec6..164bf79eee 100644
--- a/firmware/target/arm/imx233/sdmmc-imx233.c
+++ b/firmware/target/arm/imx233/sdmmc-imx233.c
@@ -206,6 +206,17 @@ static void sdmmc_detect_callback(int ssp)
206 imx233_ssp_sdmmc_is_detect_inverted(ssp)); 206 imx233_ssp_sdmmc_is_detect_inverted(ssp));
207} 207}
208 208
209static void sdmmc_enable_pullups(int drive, bool pullup)
210{
211 /* setup pins, never use alternatives pin on SSP1 because no device use it
212 * but this could be made a flag */
213 int bus_width = SDMMC_MODE(drive) == MMC_MODE ? 8 : 4;
214 if(SDMMC_SSP(drive) == 1)
215 imx233_ssp_setup_ssp1_sd_mmc_pins(pullup, bus_width, false);
216 else
217 imx233_ssp_setup_ssp2_sd_mmc_pins(pullup, bus_width);
218}
219
209static void sdmmc_power(int drive, bool on) 220static void sdmmc_power(int drive, bool on)
210{ 221{
211 /* power chip if needed */ 222 /* power chip if needed */
@@ -223,13 +234,8 @@ static void sdmmc_power(int drive, bool on)
223 } 234 }
224 if(SDMMC_FLAGS(drive) & POWER_DELAY) 235 if(SDMMC_FLAGS(drive) & POWER_DELAY)
225 sleep(SDMMC_CONF(drive).power_delay); 236 sleep(SDMMC_CONF(drive).power_delay);
226 /* setup pins, never use alternatives pin on SSP1 because no device use it 237 /* enable pullups for identification */
227 * but this could be made a flag */ 238 sdmmc_enable_pullups(drive, true);
228 int bus_width = SDMMC_MODE(drive) == MMC_MODE ? 8 : 4;
229 if(SDMMC_SSP(drive) == 1)
230 imx233_ssp_setup_ssp1_sd_mmc_pins(on, bus_width, PINCTRL_DRIVE_4mA, false);
231 else
232 imx233_ssp_setup_ssp2_sd_mmc_pins(on, bus_width, PINCTRL_DRIVE_4mA);
233} 239}
234 240
235#define MCI_NO_RESP 0 241#define MCI_NO_RESP 0
diff --git a/firmware/target/arm/imx233/ssp-imx233.c b/firmware/target/arm/imx233/ssp-imx233.c
index e73c09bfca..2873ab9604 100644
--- a/firmware/target/arm/imx233/ssp-imx233.c
+++ b/firmware/target/arm/imx233/ssp-imx233.c
@@ -168,24 +168,27 @@ void imx233_ssp_softreset(int ssp)
168void imx233_ssp_set_timings(int ssp, int divide, int rate, int timeout) 168void imx233_ssp_set_timings(int ssp, int divide, int rate, int timeout)
169{ 169{
170 ASSERT_SSP(ssp) 170 ASSERT_SSP(ssp)
171 if(divide == 0 || (divide % 2) == 1)
172 panicf("SSP timing divide must be event");
171 SSP_REGn(SSP_TIMING, ssp) = BF_OR3(SSP_TIMING, CLOCK_DIVIDE(divide), 173 SSP_REGn(SSP_TIMING, ssp) = BF_OR3(SSP_TIMING, CLOCK_DIVIDE(divide),
172 CLOCK_RATE(rate), TIMEOUT(timeout)); 174 CLOCK_RATE(rate), TIMEOUT(timeout));
173} 175}
174 176
175void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width, 177void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width, bool use_alt)
176 unsigned drive_strength, bool use_alt)
177{ 178{
178 (void) use_alt; 179 (void) use_alt;
180 unsigned clk_drive = PINCTRL_DRIVE_8mA;
181 unsigned dat_drive = PINCTRL_DRIVE_4mA;
179 /* SSP_{CMD,SCK} */ 182 /* SSP_{CMD,SCK} */
180 imx233_pinctrl_setup_vpin(VPIN_SSP1_CMD, "ssp1_cmd", drive_strength, enable_pullups); 183 imx233_pinctrl_setup_vpin(VPIN_SSP1_CMD, "ssp1_cmd", dat_drive, enable_pullups);
181 imx233_pinctrl_setup_vpin(VPIN_SSP1_SCK, "ssp1_sck", drive_strength, false); 184 imx233_pinctrl_setup_vpin(VPIN_SSP1_SCK, "ssp1_sck", clk_drive, false);
182 /* SSP_DATA{0-3} */ 185 /* SSP_DATA{0-3} */
183 imx233_pinctrl_setup_vpin(VPIN_SSP1_D0, "ssp1_d0", drive_strength, enable_pullups); 186 imx233_pinctrl_setup_vpin(VPIN_SSP1_D0, "ssp1_d0", dat_drive, enable_pullups);
184 if(bus_width >= 4) 187 if(bus_width >= 4)
185 { 188 {
186 imx233_pinctrl_setup_vpin(VPIN_SSP1_D1, "ssp1_d1", drive_strength, enable_pullups); 189 imx233_pinctrl_setup_vpin(VPIN_SSP1_D1, "ssp1_d1", dat_drive, enable_pullups);
187 imx233_pinctrl_setup_vpin(VPIN_SSP1_D2, "ssp1_d2", drive_strength, enable_pullups); 190 imx233_pinctrl_setup_vpin(VPIN_SSP1_D2, "ssp1_d2", dat_drive, enable_pullups);
188 imx233_pinctrl_setup_vpin(VPIN_SSP1_D3, "ssp1_d3", drive_strength, enable_pullups); 191 imx233_pinctrl_setup_vpin(VPIN_SSP1_D3, "ssp1_d3", dat_drive, enable_pullups);
189 } 192 }
190 if(bus_width >= 8) 193 if(bus_width >= 8)
191 { 194 {
@@ -193,20 +196,20 @@ void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width,
193 if(use_alt) 196 if(use_alt)
194 { 197 {
195#ifdef VPIN_SSP1_D4_ALT 198#ifdef VPIN_SSP1_D4_ALT
196 imx233_pinctrl_setup_vpin(VPIN_SSP1_D4_ALT, "ssp1_d4", drive_strength, enable_pullups); 199 imx233_pinctrl_setup_vpin(VPIN_SSP1_D4_ALT, "ssp1_d4", dat_drive, enable_pullups);
197 imx233_pinctrl_setup_vpin(VPIN_SSP1_D5_ALT, "ssp1_d5", drive_strength, enable_pullups); 200 imx233_pinctrl_setup_vpin(VPIN_SSP1_D5_ALT, "ssp1_d5", dat_drive, enable_pullups);
198 imx233_pinctrl_setup_vpin(VPIN_SSP1_D6_ALT, "ssp1_d6", drive_strength, enable_pullups); 201 imx233_pinctrl_setup_vpin(VPIN_SSP1_D6_ALT, "ssp1_d6", dat_drive, enable_pullups);
199 imx233_pinctrl_setup_vpin(VPIN_SSP1_D7_ALT, "ssp1_d7", drive_strength, enable_pullups); 202 imx233_pinctrl_setup_vpin(VPIN_SSP1_D7_ALT, "ssp1_d7", dat_drive, enable_pullups);
200#else 203#else
201 panicf("there is ssp1 alt on this soc!"); 204 panicf("there is ssp1 alt on this soc!");
202#endif 205#endif
203 } 206 }
204 else 207 else
205 { 208 {
206 imx233_pinctrl_setup_vpin(VPIN_SSP1_D4, "ssp1_d4", drive_strength, enable_pullups); 209 imx233_pinctrl_setup_vpin(VPIN_SSP1_D4, "ssp1_d4", dat_drive, enable_pullups);
207 imx233_pinctrl_setup_vpin(VPIN_SSP1_D5, "ssp1_d5", drive_strength, enable_pullups); 210 imx233_pinctrl_setup_vpin(VPIN_SSP1_D5, "ssp1_d5", dat_drive, enable_pullups);
208 imx233_pinctrl_setup_vpin(VPIN_SSP1_D6, "ssp1_d6", drive_strength, enable_pullups); 211 imx233_pinctrl_setup_vpin(VPIN_SSP1_D6, "ssp1_d6", dat_drive, enable_pullups);
209 imx233_pinctrl_setup_vpin(VPIN_SSP1_D7, "ssp1_d7", drive_strength, enable_pullups); 212 imx233_pinctrl_setup_vpin(VPIN_SSP1_D7, "ssp1_d7", dat_drive, enable_pullups);
210 } 213 }
211#else 214#else
212 panicf("ssp1 bus width is limited to 4 on this soc!"); 215 panicf("ssp1 bus width is limited to 4 on this soc!");
@@ -214,30 +217,30 @@ void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width,
214 } 217 }
215} 218}
216 219
217void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width, 220void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width)
218 unsigned drive_strength)
219{ 221{
220 (void) enable_pullups; 222 (void) enable_pullups;
221 (void) bus_width; 223 (void) bus_width;
222 (void) drive_strength; 224 unsigned clk_drive = PINCTRL_DRIVE_8mA;
225 unsigned dat_drive = PINCTRL_DRIVE_4mA;
223#ifdef VPIN_SSP2_CMD 226#ifdef VPIN_SSP2_CMD
224 /* SSP_{CMD,SCK} */ 227 /* SSP_{CMD,SCK} */
225 imx233_pinctrl_setup_vpin(VPIN_SSP2_CMD, "ssp2_cmd", drive_strength, enable_pullups); 228 imx233_pinctrl_setup_vpin(VPIN_SSP2_CMD, "ssp2_cmd", dat_drive, enable_pullups);
226 imx233_pinctrl_setup_vpin(VPIN_SSP2_SCK, "ssp2_sck", drive_strength, false); 229 imx233_pinctrl_setup_vpin(VPIN_SSP2_SCK, "ssp2_sck", clk_drive, false);
227 /* SSP_DATA{0-3} */ 230 /* SSP_DATA{0-3} */
228 imx233_pinctrl_setup_vpin(VPIN_SSP2_D0, "ssp2_d0", drive_strength, enable_pullups); 231 imx233_pinctrl_setup_vpin(VPIN_SSP2_D0, "ssp2_d0", dat_drive, enable_pullups);
229 if(bus_width >= 4) 232 if(bus_width >= 4)
230 { 233 {
231 imx233_pinctrl_setup_vpin(VPIN_SSP2_D1, "ssp2_d1", drive_strength, enable_pullups); 234 imx233_pinctrl_setup_vpin(VPIN_SSP2_D1, "ssp2_d1", dat_drive, enable_pullups);
232 imx233_pinctrl_setup_vpin(VPIN_SSP2_D2, "ssp2_d2", drive_strength, enable_pullups); 235 imx233_pinctrl_setup_vpin(VPIN_SSP2_D2, "ssp2_d2", dat_drive, enable_pullups);
233 imx233_pinctrl_setup_vpin(VPIN_SSP2_D3, "ssp2_d3", drive_strength, enable_pullups); 236 imx233_pinctrl_setup_vpin(VPIN_SSP2_D3, "ssp2_d3", dat_drive, enable_pullups);
234 } 237 }
235 if(bus_width >= 8) 238 if(bus_width >= 8)
236 { 239 {
237 imx233_pinctrl_setup_vpin(VPIN_SSP2_D4, "ssp2_d4", drive_strength, enable_pullups); 240 imx233_pinctrl_setup_vpin(VPIN_SSP2_D4, "ssp2_d4", dat_drive, enable_pullups);
238 imx233_pinctrl_setup_vpin(VPIN_SSP2_D5, "ssp2_d5", drive_strength, enable_pullups); 241 imx233_pinctrl_setup_vpin(VPIN_SSP2_D5, "ssp2_d5", dat_drive, enable_pullups);
239 imx233_pinctrl_setup_vpin(VPIN_SSP2_D6, "ssp2_d6", drive_strength, enable_pullups); 242 imx233_pinctrl_setup_vpin(VPIN_SSP2_D6, "ssp2_d6", dat_drive, enable_pullups);
240 imx233_pinctrl_setup_vpin(VPIN_SSP2_D7, "ssp2_d7", drive_strength, enable_pullups); 243 imx233_pinctrl_setup_vpin(VPIN_SSP2_D7, "ssp2_d7", dat_drive, enable_pullups);
241 } 244 }
242#else 245#else
243 panicf("there is no ssp2 on this soc!"); 246 panicf("there is no ssp2 on this soc!");
diff --git a/firmware/target/arm/imx233/ssp-imx233.h b/firmware/target/arm/imx233/ssp-imx233.h
index e58c9e1c09..42c8d1fe7b 100644
--- a/firmware/target/arm/imx233/ssp-imx233.h
+++ b/firmware/target/arm/imx233/ssp-imx233.h
@@ -98,10 +98,8 @@ enum imx233_ssp_error_t imx233_ssp_sd_mmc_transfer(int ssp, uint8_t cmd,
98 uint32_t cmd_arg, enum imx233_ssp_resp_t resp, void *buffer, unsigned block_count, 98 uint32_t cmd_arg, enum imx233_ssp_resp_t resp, void *buffer, unsigned block_count,
99 bool wait4irq, bool read, uint32_t *resp_ptr); 99 bool wait4irq, bool read, uint32_t *resp_ptr);
100/* pullups/alternative are ignored on targets which don't support it */ 100/* pullups/alternative are ignored on targets which don't support it */
101void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width, 101void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width, bool use_alt);
102 unsigned drive_strength, bool use_alt); 102void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width);
103void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width,
104 unsigned drive_strength);
105/* after callback is fired, imx233_ssp_sdmmc_setup_detect needs to be called 103/* after callback is fired, imx233_ssp_sdmmc_setup_detect needs to be called
106 * to enable detection again. If first_time is true, the callback will 104 * to enable detection again. If first_time is true, the callback will
107 * be called if the sd card is inserted when the function is called, otherwise 105 * be called if the sd card is inserted when the function is called, otherwise