summaryrefslogtreecommitdiff
path: root/firmware/target/arm/s5l8702/system-s5l8702.c
diff options
context:
space:
mode:
authorCástor Muñoz <cmvidal@gmail.com>2016-02-04 22:49:01 +0100
committerCástor Muñoz <cmvidal@gmail.com>2016-05-25 10:59:31 +0200
commit1aefd9ea4146ebb7eee606be4efb5cf22654b082 (patch)
treeffbe9f88c2e0624faf93419c5bc9bd63963766ec /firmware/target/arm/s5l8702/system-s5l8702.c
parentc31fcddd985a9855ece85f4209a4bdae77f3f9c8 (diff)
downloadrockbox-1aefd9ea4146ebb7eee606be4efb5cf22654b082.tar.gz
rockbox-1aefd9ea4146ebb7eee606be4efb5cf22654b082.zip
iPod Classic: HW preliminary initialization for bootloader
When the bootloader starts, most of HW never has been initialized. This patch includes all code needed to perform the preliminary initialization on SYSCON, GPIO, i2c, and MIU. The code is based on emCORE and OF reverse engineering, ported to C for readability. Change-Id: I9ecf2c3e8b1b636241a211dbba8735137accd05c
Diffstat (limited to 'firmware/target/arm/s5l8702/system-s5l8702.c')
-rw-r--r--firmware/target/arm/s5l8702/system-s5l8702.c121
1 files changed, 121 insertions, 0 deletions
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