summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/export/i2c-s5l8702.h1
-rw-r--r--firmware/target/arm/s5l8702/clocking-s5l8702.c121
-rw-r--r--firmware/target/arm/s5l8702/clocking-s5l8702.h17
-rw-r--r--firmware/target/arm/s5l8702/gpio-s5l8702.c19
-rw-r--r--firmware/target/arm/s5l8702/gpio-s5l8702.h4
-rw-r--r--firmware/target/arm/s5l8702/i2c-s5l8702.c28
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/pmu-ipod6g.c109
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/pmu-target.h9
-rw-r--r--firmware/target/arm/s5l8702/system-s5l8702.c121
-rw-r--r--firmware/target/arm/s5l8702/system-target.h4
10 files changed, 429 insertions, 4 deletions
diff --git a/firmware/export/i2c-s5l8702.h b/firmware/export/i2c-s5l8702.h
index 3883c8abc0..aef0e536bf 100644
--- a/firmware/export/i2c-s5l8702.h
+++ b/firmware/export/i2c-s5l8702.h
@@ -29,6 +29,7 @@ int i2c_write(int bus, unsigned char slave, int address, int len, const unsigned
29int i2c_read(int bus, unsigned char slave, int address, int len, unsigned char *data); 29int i2c_read(int bus, unsigned char slave, int address, int len, unsigned char *data);
30 30
31#ifdef BOOTLOADER 31#ifdef BOOTLOADER
32void i2c_preinit(int bus);
32int i2c_wr(int bus, unsigned char slave, int address, int len, const unsigned char *data); 33int i2c_wr(int bus, unsigned char slave, int address, int len, const unsigned char *data);
33int i2c_rd(int bus, unsigned char slave, int address, int len, unsigned char *data); 34int i2c_rd(int bus, unsigned char slave, int address, int len, unsigned char *data);
34#endif 35#endif
diff --git a/firmware/target/arm/s5l8702/clocking-s5l8702.c b/firmware/target/arm/s5l8702/clocking-s5l8702.c
index 5293385453..3ef70ba1de 100644
--- a/firmware/target/arm/s5l8702/clocking-s5l8702.c
+++ b/firmware/target/arm/s5l8702/clocking-s5l8702.c
@@ -213,6 +213,125 @@ void set_clocking_level(int level)
213 udelay(50); /* TBC: probably not needed */ 213 udelay(50); /* TBC: probably not needed */
214} 214}
215 215
216#ifdef BOOTLOADER
217int pll_config(int pll, int op_mode, int p, int m, int s, int lock_time)
218{
219 PLLPMS(pll) = ((p & PLLPMS_PDIV_MSK) << PLLPMS_PDIV_POS)
220 | ((m & PLLPMS_MDIV_MSK) << PLLPMS_MDIV_POS)
221 | ((s & PLLPMS_SDIV_MSK) << PLLPMS_SDIV_POS);
222
223 /* lock_time are PClk ticks */
224 PLLCNT(pll) = lock_time & PLLCNT_MSK;
225
226 if (pll < 2)
227 {
228 if (op_mode == PLLOP_MM) {
229 PLLMODE &= ~PLLMODE_PMSMOD_BIT(pll); /* MM */
230 return 0;
231 }
232
233 PLLMODE |= PLLMODE_PMSMOD_BIT(pll);
234
235 if (op_mode == PLLOP_DM) {
236 PLLMOD2 &= ~PLLMOD2_DMOSC_BIT(pll); /* DM */
237 return 0;
238 }
239
240 PLLMOD2 |= PLLMOD2_DMOSC_BIT(pll);
241 }
242 else
243 {
244 if (op_mode == PLLOP_MM)
245 return -1; /* PLL2 does not support MM */
246
247 if (op_mode == PLLOP_DM) {
248 PLLMODE &= ~PLLMODE_PLL2DMOSC_BIT; /* DM */
249 return 0;
250 }
251
252 PLLMODE |= PLLMODE_PLL2DMOSC_BIT;
253 }
254
255 /* ALTOSCx */
256 PLLMOD2 = (PLLMOD2 & ~PLLMOD2_ALTOSC_BIT(pll)) |
257 ((op_mode == PLLOP_ALT0) ? 0 : PLLMOD2_ALTOSC_BIT(pll));
258
259 return 0;
260}
261
262int pll_onoff(int pll, bool onoff)
263{
264 if (onoff)
265 {
266 PLLMODE |= PLLMODE_EN_BIT(pll); /* start PLL */
267 while (!(PLLLOCK & PLLLOCK_LCK_BIT(pll))); /* locking... */
268 PLLMODE |= PLLMODE_PLLOUT_BIT(pll); /* slow mode OFF */
269
270 /* returns DMLCK status, only meaningful for Divisor Mode (DM) */
271 return (PLLLOCK & PLLLOCK_DMLCK_BIT(pll)) ? 1 : 0;
272 }
273 else
274 {
275 PLLMODE &= ~PLLMODE_PLLOUT_BIT(pll); /* slow mode ON */
276 udelay(50); /* TBC: needed when current F_in is 0 Hz */
277 PLLMODE &= ~PLLMODE_EN_BIT(pll); /* stop PLL */
278
279 return 0;
280 }
281}
282
283/* configure and enable/disable 16-bit clockgate */
284void cg16_config(volatile uint16_t* cg16,
285 bool onoff, int clksel, int div1, int div2)
286{
287 uint16_t val16 = ((clksel & CG16_SEL_MSK) << CG16_SEL_POS)
288 | (((div1 - 1) & CG16_DIV1_MSK) << CG16_DIV1_POS)
289 | (((div2 - 1) & CG16_DIV2_MSK) << CG16_DIV2_POS)
290 | (onoff ? 0 : CG16_DISABLE_BIT);
291
292 volatile uint32_t* reg32 = (uint32_t *)((int)cg16 & ~3);
293 int shift = ((int)cg16 & 2) << 3;
294
295 *reg32 = (*reg32 & (0xffff0000 >> shift)) | (val16 << shift);
296
297 /*udelay(100);*/ /* probably not needed */
298
299 while (*cg16 != val16);
300}
301
302void clockgate_enable(int gate, bool enable)
303{
304 int i = (gate >> 5) & 1;
305 uint32_t bit = 1 << (gate & 0x1f);
306 if (enable) PWRCON(i) &= ~bit;
307 else PWRCON(i) |= bit;
308}
309
310/* Configures EClk for USEC_TIMER. DRAM refresh also depends on EClk,
311 * this clock should be initialized by the bootloader, so USEC_TIMER
312 * is ready to use for RB.
313 */
314void usec_timer_init(void)
315{
316 /* select OSC0 for CG16 SEL_OSC */
317 PLLMODE &= ~PLLMODE_OSCSEL_BIT;
318
319 /* configure and enable ECLK */
320 cg16_config(&CG16_RTIME, true, CG16_SEL_OSC, 1, 1);
321
322 /* unmask timer controller clock gate */
323 clockgate_enable(CLOCKGATE_TIMER, true);
324
325 /* configure and start timer E */
326 TECON = (4 << 8) | /* TE_CS = ECLK / 1 */
327 (1 << 6) | /* select ECLK (12 MHz on Classic) */
328 (0 << 4); /* TE_MODE_SEL = interval mode */
329 TEPRE = (S5L8702_OSC0_HZ / 1000000) - 1; /* prescaler */
330 TEDATA0 = ~0;
331 TECMD = (1 << 1) | /* TE_CLR = initialize timer */
332 (1 << 0); /* TE_EN = enable */
333}
334
216#if 0 335#if 0
217/* - This function is mainly to documment how s5l8702 ROMBOOT and iPod 336/* - This function is mainly to documment how s5l8702 ROMBOOT and iPod
218 * Classic diagnostic OF detects primary external clock. 337 * Classic diagnostic OF detects primary external clock.
@@ -228,3 +347,5 @@ unsigned soc_get_osc0(void)
228 return (PDAT3 & 0x20) ? 24000000 : 12000000; 347 return (PDAT3 & 0x20) ? 24000000 : 12000000;
229} 348}
230#endif 349#endif
350
351#endif /* BOOTLOADER */
diff --git a/firmware/target/arm/s5l8702/clocking-s5l8702.h b/firmware/target/arm/s5l8702/clocking-s5l8702.h
index e7e4fab3bd..f21c25929b 100644
--- a/firmware/target/arm/s5l8702/clocking-s5l8702.h
+++ b/firmware/target/arm/s5l8702/clocking-s5l8702.h
@@ -433,4 +433,21 @@ unsigned pll_get_out_freq(int pll);
433unsigned soc_get_oscsel_freq(void); 433unsigned soc_get_oscsel_freq(void);
434int soc_get_hsdiv(void); 434int soc_get_hsdiv(void);
435 435
436#ifdef BOOTLOADER
437#include <stdbool.h>
438
439void usec_timer_init(void);
440void clockgate_enable(int gate, bool enable);
441
442void soc_set_system_divs(unsigned cdiv, unsigned hdiv, unsigned hprat);
443unsigned soc_get_system_divs(unsigned *cdiv, unsigned *hdiv, unsigned *pdiv);
444void soc_set_hsdiv(int hsdiv);
445
446void cg16_config(volatile uint16_t* cg16,
447 bool onoff, int clksel, int div1, int div2);
448
449int pll_config(int pll, int op_mode, int p, int m, int s, int lock_time);
450int pll_onoff(int pll, bool onoff);
451#endif
452
436#endif /* __CLOCKING_S5L8702_H */ 453#endif /* __CLOCKING_S5L8702_H */
diff --git a/firmware/target/arm/s5l8702/gpio-s5l8702.c b/firmware/target/arm/s5l8702/gpio-s5l8702.c
index bd87005ad8..85033de78c 100644
--- a/firmware/target/arm/s5l8702/gpio-s5l8702.c
+++ b/firmware/target/arm/s5l8702/gpio-s5l8702.c
@@ -214,3 +214,22 @@ void ICODE_ATTR INT_EXT6(void)
214 gpio_handler(0); 214 gpio_handler(0);
215} 215}
216#endif 216#endif
217
218#ifdef BOOTLOADER
219static uint32_t gpio_data[16] =
220{
221 0x5322222F, 0xEEEEEE00, 0x2332EEEE, 0x3333E222,
222 0x33333333, 0x33333333, 0x3F000E33, 0xEEEEEEEE,
223 0xEEEEEEEE, 0xEEEEEEEE, 0xE0EEEEEE, 0xEE00EE0E,
224 0xEEEE0EEE, 0xEEEEEEEE, 0xEE2222EE, 0xEEEE0EEE
225};
226
227void gpio_preinit(void)
228{
229 for (int i = 0; i < 16; i++) {
230 PCON(i) = gpio_data[i];
231 PUNB(i) = 0;
232 PUNC(i) = 0;
233 }
234}
235#endif
diff --git a/firmware/target/arm/s5l8702/gpio-s5l8702.h b/firmware/target/arm/s5l8702/gpio-s5l8702.h
index 00f5ba18f3..108d8feb0d 100644
--- a/firmware/target/arm/s5l8702/gpio-s5l8702.h
+++ b/firmware/target/arm/s5l8702/gpio-s5l8702.h
@@ -142,4 +142,8 @@ void gpio_int_disable(int gpio_n);
142uint32_t gpio_group_get(int group); 142uint32_t gpio_group_get(int group);
143void gpio_group_set(int group, uint32_t mask, uint32_t cfg); 143void gpio_group_set(int group, uint32_t mask, uint32_t cfg);
144 144
145#ifdef BOOTLOADER
146void gpio_preinit(void);
147#endif
148
145#endif /* __GPIO_S5L8702_H__ */ 149#endif /* __GPIO_S5L8702_H__ */
diff --git a/firmware/target/arm/s5l8702/i2c-s5l8702.c b/firmware/target/arm/s5l8702/i2c-s5l8702.c
index 619768410a..13787d7357 100644
--- a/firmware/target/arm/s5l8702/i2c-s5l8702.c
+++ b/firmware/target/arm/s5l8702/i2c-s5l8702.c
@@ -179,3 +179,31 @@ int i2c_read(int bus, unsigned char slave, int address, int len, unsigned char *
179 mutex_unlock(&i2c_mtx[bus]); 179 mutex_unlock(&i2c_mtx[bus]);
180 return ret; 180 return ret;
181} 181}
182
183#ifdef BOOTLOADER
184#include "clocking-s5l8702.h"
185
186static void wait_rdy(int bus)
187{
188 while (IICUNK10(bus));
189}
190
191void i2c_preinit(int bus)
192{
193 clockgate_enable(I2CCLKGATE(bus), true);
194 wait_rdy(bus);
195 IICADD(bus) = 0x40; /* own slave address */
196 wait_rdy(bus);
197 IICUNK14(bus) = 0;
198 wait_rdy(bus);
199 IICUNK18(bus) = 0;
200 wait_rdy(bus);
201 IICSTAT(bus) = 0x80; /* master Rx mode, Tx/Rx off */
202 wait_rdy(bus);
203 IICCON(bus) = 0;
204 wait_rdy(bus);
205 IICSTAT(bus) = 0; /* slave Rx mode, Tx/Rx off */
206 wait_rdy(bus);
207 clockgate_enable(I2CCLKGATE(bus), false);
208}
209#endif
diff --git a/firmware/target/arm/s5l8702/ipod6g/pmu-ipod6g.c b/firmware/target/arm/s5l8702/ipod6g/pmu-ipod6g.c
index 2a9236046c..9c3ec8e711 100644
--- a/firmware/target/arm/s5l8702/ipod6g/pmu-ipod6g.c
+++ b/firmware/target/arm/s5l8702/ipod6g/pmu-ipod6g.c
@@ -165,4 +165,113 @@ int pmu_wr(int address, unsigned char val)
165{ 165{
166 return pmu_wr_multiple(address, 1, &val); 166 return pmu_wr_multiple(address, 1, &val);
167} 167}
168
169void pmu_preinit(void)
170{
171 static const char init_data[] =
172 {
173 /* reset OOC shutdown register */
174 PCF5063X_REG_OOCSHDWN, 0x0,
175
176 /* LDO_UNK1: 3000 mV, enabled */
177 PCF5063X_REG_LDO1OUT, 0x15,
178 PCF5063X_REG_LDO1ENA, 0x1,
179
180 /* LDO_UNK2: 3000 mV, enabled */
181 PCF5063X_REG_LDO2OUT, 0x15,
182 PCF5063X_REG_LDO2ENA, 0x1,
183
184 /* LDO_LCD: 3000 mV, enabled */
185 PCF5063X_REG_LDO3OUT, 0x15,
186 PCF5063X_REG_LDO3ENA, 0x1,
187
188 /* LDO_CODEC: 1800 mV, enabled */
189 PCF5063X_REG_LDO4OUT, 0x9,
190 PCF5063X_REG_LDO4ENA, 0x1,
191
192 /* LDO_UNK5: 3000 mV, disabled */
193 PCF5063X_REG_LDO5OUT, 0x15,
194 PCF5063X_REG_LDO5ENA, 0x0,
195
196 /* LDO_CWHEEL: 3000 mV, ON when GPIO2 High */
197 PCF5063X_REG_LDO6OUT, 0x15,
198 PCF5063X_REG_LDO6ENA, 0x4,
199
200 /* LDO_ACCY: 3300 mV, disabled */
201 PCF5063X_REG_HCLDOOUT, 0x18,
202 PCF5063X_REG_HCLDOENA, 0x0,
203
204 /* LDO_CWHEEL is ON in STANDBY state,
205 LDO_CWHEEL and MEMLDO are ON in UNKNOWN state (TBC) */
206 PCF5063X_REG_STBYCTL1, 0x0,
207 PCF5063X_REG_STBYCTL2, 0x8c,
208
209 /* GPIO1,2 = input, GPIO3 = output */
210 PCF5063X_REG_GPIOCTL, 0x3,
211 PCF5063X_REG_GPIO1CFG, 0x0,
212 PCF5063X_REG_GPIO2CFG, 0x0,
213
214 /* DOWN2 converter (SDRAM): 1800 mV, enabled,
215 startup current limit = 15mA*0x10 (TBC) */
216 PCF5063X_REG_DOWN2OUT, 0x2f,
217 PCF5063X_REG_DOWN2ENA, 0x1,
218 PCF5063X_REG_DOWN2CTL, 0x0,
219 PCF5063X_REG_DOWN2MXC, 0x10,
220
221 /* MEMLDO: 1800 mV, enabled */
222 PCF5063X_REG_MEMLDOOUT, 0x9,
223 PCF5063X_REG_MEMLDOENA, 0x1,
224
225 /* AUTOLDO (HDD): 3400 mV, disabled,
226 limit = 1000 mA (40mA*0x19), limit always active */
227 PCF5063X_REG_AUTOOUT, 0x6f,
228 PCF5063X_REG_AUTOENA, 0x0,
229 PCF5063X_REG_AUTOCTL, 0x0,
230 PCF5063X_REG_AUTOMXC, 0x59,
231
232 /* Vsysok = 3100 mV */
233 PCF5063X_REG_SVMCTL, 0x8,
234
235 /* Reserved */
236 0x58, 0x0,
237
238 /* Mask all PMU interrupts */
239 PCF5063X_REG_INT1M, 0xff,
240 PCF5063X_REG_INT2M, 0xff,
241 PCF5063X_REG_INT3M, 0xff,
242 PCF5063X_REG_INT4M, 0xff,
243 PCF5063X_REG_INT5M, 0xff,
244 PCF50635_REG_INT6M, 0xff,
245
246 /* Wakeup on rising edge for EXTON1 and EXTON2,
247 wakeup on falling edge for EXTON3 and !ONKEY,
248 wakeup on RTC alarm, wakeup on adapter insert,
249 Vbat status has no effect in state machine */
250 PCF5063X_REG_OOCWAKE, 0xdf,
251 PCF5063X_REG_OOCTIM1, 0xaa,
252 PCF5063X_REG_OOCTIM2, 0x4a,
253 PCF5063X_REG_OOCMODE, 0x5,
254 PCF5063X_REG_OOCCTL, 0x27,
255
256 /* GPO selection = LED external NFET drive signal */
257 PCF5063X_REG_GPOCFG, 0x1,
258 /* LED converter OFF, overvoltage protection enabled,
259 OCP limit is 500 mA, led_dimstep = 16*0x6/32768 */
260 PCF5063X_REG_LEDENA, 0x0,
261 PCF5063X_REG_LEDCTL, 0x5,
262 PCF5063X_REG_LEDDIM, 0x6,
263
264 /* end marker */
265 0
266 };
267
268 const char* ptr;
269 for (ptr = init_data; *ptr != 0; ptr += 2)
270 pmu_wr(ptr[0], ptr[1]);
271
272 /* clear PMU interrupts */
273 unsigned char rd_buf[5];
274 pmu_rd_multiple(PCF5063X_REG_INT1, 5, rd_buf);
275 pmu_rd(PCF50635_REG_INT6);
276}
168#endif /* BOOTLOADER */ 277#endif /* BOOTLOADER */
diff --git a/firmware/target/arm/s5l8702/ipod6g/pmu-target.h b/firmware/target/arm/s5l8702/ipod6g/pmu-target.h
index 3a90ad8789..e4bef6f47c 100644
--- a/firmware/target/arm/s5l8702/ipod6g/pmu-target.h
+++ b/firmware/target/arm/s5l8702/ipod6g/pmu-target.h
@@ -40,8 +40,8 @@
40#define LDO_UNK5 5 /* TBC: nano3g NAND */ 40#define LDO_UNK5 5 /* TBC: nano3g NAND */
41#define LDO_CWHEEL 6 41#define LDO_CWHEEL 6
42#define LDO_ACCY 7 /* HCLDO */ 42#define LDO_ACCY 7 /* HCLDO */
43 43/*
44/* Other LDOs: 44 * Other LDOs:
45 * AUTOLDO: Hard Disk 45 * AUTOLDO: Hard Disk
46 * DOWN1: CPU 46 * DOWN1: CPU
47 * DOWN2: SDRAM 47 * DOWN2: SDRAM
@@ -50,9 +50,9 @@
50 * EXTON inputs: 50 * EXTON inputs:
51 * EXTON1: button/holdswitch related (TBC) 51 * EXTON1: button/holdswitch related (TBC)
52 * EXTON2: USB Vbus (High when present) 52 * EXTON2: USB Vbus (High when present)
53 * EXTON3: ACCESORY (Low when present) 53 * EXTON3: ACCESSORY (Low when present)
54 * 54 *
55 * GPIO: 55 * PMU GPIO:
56 * GPIO1: input, Mikey (jack remote ctrl) interrupt (TBC) 56 * GPIO1: input, Mikey (jack remote ctrl) interrupt (TBC)
57 * GPIO2: input, hold switch (TBC) 57 * GPIO2: input, hold switch (TBC)
58 * GPIO3: output, unknown 58 * GPIO3: output, unknown
@@ -82,6 +82,7 @@ unsigned char pmu_rd(int address);
82int pmu_wr(int address, unsigned char val); 82int pmu_wr(int address, unsigned char val);
83int pmu_rd_multiple(int address, int count, unsigned char* buffer); 83int pmu_rd_multiple(int address, int count, unsigned char* buffer);
84int pmu_wr_multiple(int address, int count, unsigned char* buffer); 84int pmu_wr_multiple(int address, int count, unsigned char* buffer);
85void pmu_preinit(void);
85#endif 86#endif
86 87
87#endif /* __PMU_TARGET_H__ */ 88#endif /* __PMU_TARGET_H__ */
diff --git a/firmware/target/arm/s5l8702/system-s5l8702.c b/firmware/target/arm/s5l8702/system-s5l8702.c
index fd3a464e2f..d285efde78 100644
--- a/firmware/target/arm/s5l8702/system-s5l8702.c
+++ b/firmware/target/arm/s5l8702/system-s5l8702.c
@@ -277,3 +277,124 @@ void memory_init(void)
277 set_page_tables(); 277 set_page_tables();
278 enable_mmu(); 278 enable_mmu();
279} 279}
280
281#ifdef BOOTLOADER
282#include "i2c-s5l8702.h"
283
284static void syscon_preinit(void)
285{
286 /* after ROM boot, CG16_SYS is using PLL0 @108 MHz
287 CClk = 108 MHz, HClk = 54 MHz, PClk = 27 MHz */
288
289 CLKCON0 &= ~CLKCON0_SDR_DISABLE_BIT;
290
291 PLLMODE &= ~PLLMODE_OSCSEL_BIT; /* CG16_SEL_OSC = OSC0 */
292 cg16_config(&CG16_SYS, true, CG16_SEL_OSC, 1, 1);
293 soc_set_system_divs(1, 1, 1);
294
295 /* stop all PLLs */
296 for (int pll = 0; pll < 3; pll++)
297 pll_onoff(pll, false);
298
299 pll_config(2, PLLOP_DM, 1, 36, 1, 32400);
300 pll_onoff(2, true);
301 soc_set_system_divs(1, 2, 2 /*hprat*/);
302 cg16_config(&CG16_SYS, true, CG16_SEL_PLL2, 1, 1);
303 cg16_config(&CG16_2L, false, CG16_SEL_OSC, 1, 1);
304 cg16_config(&CG16_SVID, false, CG16_SEL_OSC, 1, 1);
305 cg16_config(&CG16_AUD0, false, CG16_SEL_OSC, 1, 1);
306 cg16_config(&CG16_AUD1, false, CG16_SEL_OSC, 1, 1);
307 cg16_config(&CG16_AUD2, false, CG16_SEL_OSC, 1, 1);
308 cg16_config(&CG16_RTIME, true, CG16_SEL_OSC, 1, 1);
309 cg16_config(&CG16_5L, false, CG16_SEL_OSC, 1, 1);
310
311 soc_set_hsdiv(1);
312
313 PWRCON_AHB = ~((1 << CLOCKGATE_SMx) |
314 (1 << CLOCKGATE_SM1));
315 PWRCON_APB = ~((1 << (CLOCKGATE_TIMER - 32)) |
316 (1 << (CLOCKGATE_GPIO - 32)));
317}
318
319static void miu_preinit(bool selfrefreshing)
320{
321 if (selfrefreshing)
322 MIUCON = 0x11; /* TBC: self-refresh -> IDLE */
323
324 MIUCON = 0x80D; /* remap = 1 (IRAM mapped to 0x0),
325 TBC: SDRAM bank and column configuration */
326 MIU_REG(0xF0) = 0x0;
327
328 MIUAREF = 0x6105D; /* Auto-Refresh enabled,
329 Row refresh interval = 0x5d/12MHz = 7.75 uS */
330 MIUSDPARA = 0x1FB621;
331
332 MIU_REG(0x200) = 0x1845;
333 MIU_REG(0x204) = 0x1845;
334 MIU_REG(0x210) = 0x1800;
335 MIU_REG(0x214) = 0x1800;
336 MIU_REG(0x220) = 0x1845;
337 MIU_REG(0x224) = 0x1845;
338 MIU_REG(0x230) = 0x1885;
339 MIU_REG(0x234) = 0x1885;
340 MIU_REG(0x14) = 0x19; /* 2^19 = 0x2000000 = SDRAMSIZE (32Mb) */
341 MIU_REG(0x18) = 0x19; /* 2^19 = 0x2000000 = SDRAMSIZE (32Mb) */
342 MIU_REG(0x1C) = 0x790682B;
343 MIU_REG(0x314) &= ~0x10;
344
345 for (int i = 0; i < 0x24; i++)
346 MIU_REG(0x2C + i*4) &= ~(1 << 24);
347
348 MIU_REG(0x1CC) = 0x540;
349 MIU_REG(0x1D4) |= 0x80;
350
351 MIUCOM = 0x33; /* No action CMD */
352 MIUCOM = 0x33;
353 MIUCOM = 0x233; /* Precharge all banks CMD */
354 MIUCOM = 0x33;
355 MIUCOM = 0x33;
356 MIUCOM = 0x33;
357 MIUCOM = 0x333; /* Auto-refresh CMD */
358 MIUCOM = 0x33;
359 MIUCOM = 0x33;
360 MIUCOM = 0x33;
361 MIUCOM = 0x333; /* Auto-refresh CMD */
362 MIUCOM = 0x33;
363 MIUCOM = 0x33;
364 MIUCOM = 0x33;
365
366 if (!selfrefreshing)
367 {
368 MIUMRS = 0x33; /* MRS: Bust Length = 8, CAS = 3 */
369 MIUCOM = 0x133; /* Mode Register Set CMD */
370 MIUCOM = 0x33;
371 MIUCOM = 0x33;
372 MIUCOM = 0x33;
373 MIUMRS = 0x8040; /* EMRS: Strength = 1/4, Self refresh area = Full */
374 MIUCOM = 0x133; /* Mode Register Set CMD */
375 MIUCOM = 0x33;
376 MIUCOM = 0x33;
377 MIUCOM = 0x33;
378 }
379
380 MIUAREF |= 0x61000; /* Auto-refresh enabled */
381}
382
383/* Preliminary HW initialization */
384void system_preinit(void)
385{
386 bool gpio3out, coldboot;
387
388 syscon_preinit();
389 gpio_preinit();
390 i2c_preinit(0);
391
392 /* get (previously) configured output selection for GPIO3 */
393 gpio3out = (pmu_rd(PCF5063X_REG_GPIO3CFG) & 7);
394 /* coldboot: when set, device has been in NoPower state */
395 coldboot = (pmu_rd(PCF5063X_REG_OOCSHDWN) & PCF5063X_OOCSHDWN_COLDBOOT);
396 pmu_preinit();
397
398 miu_preinit(!coldboot && !gpio3out);
399}
400#endif
diff --git a/firmware/target/arm/s5l8702/system-target.h b/firmware/target/arm/s5l8702/system-target.h
index 235e68e8ca..b40d563e46 100644
--- a/firmware/target/arm/s5l8702/system-target.h
+++ b/firmware/target/arm/s5l8702/system-target.h
@@ -47,4 +47,8 @@ static inline void udelay(unsigned usecs)
47 while (TIME_BEFORE(USEC_TIMER, stop)); 47 while (TIME_BEFORE(USEC_TIMER, stop));
48} 48}
49 49
50#ifdef BOOTLOADER
51void system_preinit(void);
52#endif
53
50#endif /* SYSTEM_TARGET_H */ 54#endif /* SYSTEM_TARGET_H */