From 1aefd9ea4146ebb7eee606be4efb5cf22654b082 Mon Sep 17 00:00:00 2001 From: Cástor Muñoz Date: Thu, 4 Feb 2016 22:49:01 +0100 Subject: 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 --- firmware/target/arm/s5l8702/system-s5l8702.c | 121 +++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) (limited to 'firmware/target/arm/s5l8702/system-s5l8702.c') 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) set_page_tables(); enable_mmu(); } + +#ifdef BOOTLOADER +#include "i2c-s5l8702.h" + +static void syscon_preinit(void) +{ + /* after ROM boot, CG16_SYS is using PLL0 @108 MHz + CClk = 108 MHz, HClk = 54 MHz, PClk = 27 MHz */ + + CLKCON0 &= ~CLKCON0_SDR_DISABLE_BIT; + + PLLMODE &= ~PLLMODE_OSCSEL_BIT; /* CG16_SEL_OSC = OSC0 */ + cg16_config(&CG16_SYS, true, CG16_SEL_OSC, 1, 1); + soc_set_system_divs(1, 1, 1); + + /* stop all PLLs */ + for (int pll = 0; pll < 3; pll++) + pll_onoff(pll, false); + + pll_config(2, PLLOP_DM, 1, 36, 1, 32400); + pll_onoff(2, true); + soc_set_system_divs(1, 2, 2 /*hprat*/); + cg16_config(&CG16_SYS, true, CG16_SEL_PLL2, 1, 1); + cg16_config(&CG16_2L, false, CG16_SEL_OSC, 1, 1); + cg16_config(&CG16_SVID, false, CG16_SEL_OSC, 1, 1); + cg16_config(&CG16_AUD0, false, CG16_SEL_OSC, 1, 1); + cg16_config(&CG16_AUD1, false, CG16_SEL_OSC, 1, 1); + cg16_config(&CG16_AUD2, false, CG16_SEL_OSC, 1, 1); + cg16_config(&CG16_RTIME, true, CG16_SEL_OSC, 1, 1); + cg16_config(&CG16_5L, false, CG16_SEL_OSC, 1, 1); + + soc_set_hsdiv(1); + + PWRCON_AHB = ~((1 << CLOCKGATE_SMx) | + (1 << CLOCKGATE_SM1)); + PWRCON_APB = ~((1 << (CLOCKGATE_TIMER - 32)) | + (1 << (CLOCKGATE_GPIO - 32))); +} + +static void miu_preinit(bool selfrefreshing) +{ + if (selfrefreshing) + MIUCON = 0x11; /* TBC: self-refresh -> IDLE */ + + MIUCON = 0x80D; /* remap = 1 (IRAM mapped to 0x0), + TBC: SDRAM bank and column configuration */ + MIU_REG(0xF0) = 0x0; + + MIUAREF = 0x6105D; /* Auto-Refresh enabled, + Row refresh interval = 0x5d/12MHz = 7.75 uS */ + MIUSDPARA = 0x1FB621; + + MIU_REG(0x200) = 0x1845; + MIU_REG(0x204) = 0x1845; + MIU_REG(0x210) = 0x1800; + MIU_REG(0x214) = 0x1800; + MIU_REG(0x220) = 0x1845; + MIU_REG(0x224) = 0x1845; + MIU_REG(0x230) = 0x1885; + MIU_REG(0x234) = 0x1885; + MIU_REG(0x14) = 0x19; /* 2^19 = 0x2000000 = SDRAMSIZE (32Mb) */ + MIU_REG(0x18) = 0x19; /* 2^19 = 0x2000000 = SDRAMSIZE (32Mb) */ + MIU_REG(0x1C) = 0x790682B; + MIU_REG(0x314) &= ~0x10; + + for (int i = 0; i < 0x24; i++) + MIU_REG(0x2C + i*4) &= ~(1 << 24); + + MIU_REG(0x1CC) = 0x540; + MIU_REG(0x1D4) |= 0x80; + + MIUCOM = 0x33; /* No action CMD */ + MIUCOM = 0x33; + MIUCOM = 0x233; /* Precharge all banks CMD */ + MIUCOM = 0x33; + MIUCOM = 0x33; + MIUCOM = 0x33; + MIUCOM = 0x333; /* Auto-refresh CMD */ + MIUCOM = 0x33; + MIUCOM = 0x33; + MIUCOM = 0x33; + MIUCOM = 0x333; /* Auto-refresh CMD */ + MIUCOM = 0x33; + MIUCOM = 0x33; + MIUCOM = 0x33; + + if (!selfrefreshing) + { + MIUMRS = 0x33; /* MRS: Bust Length = 8, CAS = 3 */ + MIUCOM = 0x133; /* Mode Register Set CMD */ + MIUCOM = 0x33; + MIUCOM = 0x33; + MIUCOM = 0x33; + MIUMRS = 0x8040; /* EMRS: Strength = 1/4, Self refresh area = Full */ + MIUCOM = 0x133; /* Mode Register Set CMD */ + MIUCOM = 0x33; + MIUCOM = 0x33; + MIUCOM = 0x33; + } + + MIUAREF |= 0x61000; /* Auto-refresh enabled */ +} + +/* Preliminary HW initialization */ +void system_preinit(void) +{ + bool gpio3out, coldboot; + + syscon_preinit(); + gpio_preinit(); + i2c_preinit(0); + + /* get (previously) configured output selection for GPIO3 */ + gpio3out = (pmu_rd(PCF5063X_REG_GPIO3CFG) & 7); + /* coldboot: when set, device has been in NoPower state */ + coldboot = (pmu_rd(PCF5063X_REG_OOCSHDWN) & PCF5063X_OOCSHDWN_COLDBOOT); + pmu_preinit(); + + miu_preinit(!coldboot && !gpio3out); +} +#endif -- cgit v1.2.3