|  | LIST "KZM9G low-level initialization routine." | 
|  | LIST "Adapted from u-boot KZM9G support code." | 
|  |  | 
|  | LIST "Copyright (C) 2013 Ulrich Hecht" | 
|  |  | 
|  | LIST "This program is free software; you can redistribute it and/or modify" | 
|  | LIST "it under the terms of the GNU General Public License version 2 as" | 
|  | LIST "published by the Free Software Foundation." | 
|  |  | 
|  | LIST "This program is distributed in the hope that it will be useful," | 
|  | LIST "but WITHOUT ANY WARRANTY; without even the implied warranty of" | 
|  | LIST "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the" | 
|  | LIST "GNU General Public License for more details." | 
|  |  | 
|  |  | 
|  | LIST "Register definitions:" | 
|  |  | 
|  | LIST "Secure control register" | 
|  | #define LIFEC_SEC_SRC (0xE6110008) | 
|  |  | 
|  | LIST "RWDT" | 
|  | #define RWDT_BASE   (0xE6020000) | 
|  | #define RWTCSRA0 (RWDT_BASE + 0x04) | 
|  |  | 
|  | LIST "HPB Semaphore Control Registers" | 
|  | #define HPBSCR_BASE (0xE6000000) | 
|  | #define HPBCTRL6 (HPBSCR_BASE + 0x1030) | 
|  |  | 
|  | #define SBSC1_BASE  (0xFE400000) | 
|  | #define SDCR0A		(SBSC1_BASE + 0x0008) | 
|  | #define SDCR1A		(SBSC1_BASE + 0x000C) | 
|  | #define SDPCRA		(SBSC1_BASE + 0x0010) | 
|  | #define SDCR0SA		(SBSC1_BASE + 0x0018) | 
|  | #define SDCR1SA		(SBSC1_BASE + 0x001C) | 
|  | #define RTCSRA		(SBSC1_BASE + 0x0020) | 
|  | #define RTCORA		(SBSC1_BASE + 0x0028) | 
|  | #define RTCORHA		(SBSC1_BASE + 0x002C) | 
|  | #define SDWCRC0A	(SBSC1_BASE + 0x0040) | 
|  | #define SDWCRC1A	(SBSC1_BASE + 0x0044) | 
|  | #define SDWCR00A	(SBSC1_BASE + 0x0048) | 
|  | #define SDWCR01A	(SBSC1_BASE + 0x004C) | 
|  | #define SDWCR10A	(SBSC1_BASE + 0x0050) | 
|  | #define SDWCR11A	(SBSC1_BASE + 0x0054) | 
|  | #define SDWCR2A		(SBSC1_BASE + 0x0060) | 
|  | #define SDWCRC2A	(SBSC1_BASE + 0x0064) | 
|  | #define ZQCCRA		(SBSC1_BASE + 0x0068) | 
|  | #define SDMRACR0A	(SBSC1_BASE + 0x0084) | 
|  | #define SDMRTMPCRA	(SBSC1_BASE + 0x008C) | 
|  | #define SDMRTMPMSKA	(SBSC1_BASE + 0x0094) | 
|  | #define SDGENCNTA	(SBSC1_BASE + 0x009C) | 
|  | #define SDDRVCR0A	(SBSC1_BASE + 0x00B4) | 
|  | #define DLLCNT0A	(SBSC1_BASE + 0x0354) | 
|  |  | 
|  | #define SDMRA1  (0xFE500000) | 
|  | #define SDMRA2  (0xFE5C0000) | 
|  | #define SDMRA3  (0xFE504000) | 
|  |  | 
|  | #define SBSC2_BASE  (0xFB400000) | 
|  | #define SDCR0B		(SBSC2_BASE + 0x0008) | 
|  | #define SDCR1B		(SBSC2_BASE + 0x000C) | 
|  | #define SDPCRB		(SBSC2_BASE + 0x0010) | 
|  | #define SDCR0SB		(SBSC2_BASE + 0x0018) | 
|  | #define SDCR1SB		(SBSC2_BASE + 0x001C) | 
|  | #define RTCSRB		(SBSC2_BASE + 0x0020) | 
|  | #define RTCORB		(SBSC2_BASE + 0x0028) | 
|  | #define RTCORHB		(SBSC2_BASE + 0x002C) | 
|  | #define SDWCRC0B	(SBSC2_BASE + 0x0040) | 
|  | #define SDWCRC1B	(SBSC2_BASE + 0x0044) | 
|  | #define SDWCR00B	(SBSC2_BASE + 0x0048) | 
|  | #define SDWCR01B	(SBSC2_BASE + 0x004C) | 
|  | #define SDWCR10B	(SBSC2_BASE + 0x0050) | 
|  | #define SDWCR11B	(SBSC2_BASE + 0x0054) | 
|  | #define SDPDCR0B	(SBSC2_BASE + 0x0058) | 
|  | #define SDWCR2B		(SBSC2_BASE + 0x0060) | 
|  | #define SDWCRC2B	(SBSC2_BASE + 0x0064) | 
|  | #define ZQCCRB		(SBSC2_BASE + 0x0068) | 
|  | #define SDMRACR0B	(SBSC2_BASE + 0x0084) | 
|  | #define SDMRTMPCRB	(SBSC2_BASE + 0x008C) | 
|  | #define SDMRTMPMSKB	(SBSC2_BASE + 0x0094) | 
|  | #define SDGENCNTB	(SBSC2_BASE + 0x009C) | 
|  | #define DPHYCNT0B	(SBSC2_BASE + 0x00A0) | 
|  | #define DPHYCNT1B	(SBSC2_BASE + 0x00A4) | 
|  | #define DPHYCNT2B	(SBSC2_BASE + 0x00A8) | 
|  | #define SDDRVCR0B	(SBSC2_BASE + 0x00B4) | 
|  | #define DLLCNT0B	(SBSC2_BASE + 0x0354) | 
|  |  | 
|  | #define SDMRB1  (0xFB500000) | 
|  | #define SDMRB2  (0xFB5C0000) | 
|  | #define SDMRB3  (0xFB504000) | 
|  |  | 
|  | #define CPG_BASE   (0xE6150000) | 
|  | #define FRQCRA		(CPG_BASE + 0x0000) | 
|  | #define FRQCRB		(CPG_BASE + 0x0004) | 
|  | #define FRQCRD		(CPG_BASE + 0x00E4) | 
|  | #define VCLKCR1		(CPG_BASE + 0x0008) | 
|  | #define VCLKCR2		(CPG_BASE + 0x000C) | 
|  | #define VCLKCR3		(CPG_BASE + 0x001C) | 
|  | #define ZBCKCR		(CPG_BASE + 0x0010) | 
|  | #define FLCKCR		(CPG_BASE + 0x0014) | 
|  | #define SD0CKCR		(CPG_BASE + 0x0074) | 
|  | #define SD1CKCR		(CPG_BASE + 0x0078) | 
|  | #define SD2CKCR		(CPG_BASE + 0x007C) | 
|  | #define FSIACKCR	(CPG_BASE + 0x0018) | 
|  | #define SUBCKCR		(CPG_BASE + 0x0080) | 
|  | #define SPUACKCR	(CPG_BASE + 0x0084) | 
|  | #define SPUVCKCR	(CPG_BASE + 0x0094) | 
|  | #define MSUCKCR		(CPG_BASE + 0x0088) | 
|  | #define HSICKCR		(CPG_BASE + 0x008C) | 
|  | #define FSIBCKCR	(CPG_BASE + 0x0090) | 
|  | #define MFCK1CR		(CPG_BASE + 0x0098) | 
|  | #define MFCK2CR		(CPG_BASE + 0x009C) | 
|  | #define DSITCKCR	(CPG_BASE + 0x0060) | 
|  | #define DSI0PCKCR	(CPG_BASE + 0x0064) | 
|  | #define DSI1PCKCR	(CPG_BASE + 0x0068) | 
|  | #define DSI0PHYCR	(CPG_BASE + 0x006C) | 
|  | #define DVFSCR3		(CPG_BASE + 0x0174) | 
|  | #define DVFSCR4		(CPG_BASE + 0x0178) | 
|  | #define DVFSCR5		(CPG_BASE + 0x017C) | 
|  | #define MPMODE		(CPG_BASE + 0x00CC) | 
|  |  | 
|  | #define PLLECR		(CPG_BASE + 0x00D0) | 
|  | #define PLL0CR		(CPG_BASE + 0x00D8) | 
|  | #define PLL1CR		(CPG_BASE + 0x0028) | 
|  | #define PLL2CR		(CPG_BASE + 0x002C) | 
|  | #define PLL3CR		(CPG_BASE + 0x00DC) | 
|  | #define PLL0STPCR	(CPG_BASE + 0x00F0) | 
|  | #define PLL1STPCR	(CPG_BASE + 0x00C8) | 
|  | #define PLL2STPCR	(CPG_BASE + 0x00F8) | 
|  | #define PLL3STPCR	(CPG_BASE + 0x00FC) | 
|  | #define RMSTPCR0	(CPG_BASE + 0x0110) | 
|  | #define RMSTPCR1	(CPG_BASE + 0x0114) | 
|  | #define RMSTPCR2	(CPG_BASE + 0x0118) | 
|  | #define RMSTPCR3	(CPG_BASE + 0x011C) | 
|  | #define RMSTPCR4	(CPG_BASE + 0x0120) | 
|  | #define RMSTPCR5	(CPG_BASE + 0x0124) | 
|  | #define SMSTPCR0	(CPG_BASE + 0x0130) | 
|  | #define SMSTPCR2	(CPG_BASE + 0x0138) | 
|  | #define SMSTPCR3	(CPG_BASE + 0x013C) | 
|  | #define CPGXXCR4	(CPG_BASE + 0x0150) | 
|  | #define SRCR0		(CPG_BASE + 0x80A0) | 
|  | #define SRCR2		(CPG_BASE + 0x80B0) | 
|  | #define SRCR3		(CPG_BASE + 0x80A8) | 
|  | #define VREFCR		(CPG_BASE + 0x00EC) | 
|  | #define PCLKCR		(CPG_BASE + 0x1020) | 
|  |  | 
|  | #define PORT32CR (0xE6051020) | 
|  | #define PORT33CR (0xE6051021) | 
|  | #define PORT34CR (0xE6051022) | 
|  | #define PORT35CR (0xE6051023) | 
|  |  | 
|  | LIST "DRAM initialization code:" | 
|  |  | 
|  | EW RWTCSRA0, 0xA507 | 
|  |  | 
|  | ED_AND LIFEC_SEC_SRC, 0xFFFF7FFF | 
|  |  | 
|  | ED_AND SMSTPCR3,0xFFFF7FFF | 
|  | ED_AND SRCR3, 0xFFFF7FFF | 
|  | ED_AND SMSTPCR2,0xFFFBFFFF | 
|  | ED_AND SRCR2, 0xFFFBFFFF | 
|  | ED PLLECR, 0x00000000 | 
|  |  | 
|  | WAIT_MASK PLLECR, 0x00000F00, 0x00000000 | 
|  | WAIT_MASK FRQCRB, 0x80000000, 0x00000000 | 
|  |  | 
|  | ED PLL0CR, 0x2D000000 | 
|  | ED PLL1CR, 0x17100000 | 
|  | ED FRQCRB, 0x96235880 | 
|  | WAIT_MASK FRQCRB, 0x80000000, 0x00000000 | 
|  |  | 
|  | ED FLCKCR, 0x0000000B | 
|  | ED_AND SMSTPCR0, 0xFFFFFFFD | 
|  |  | 
|  | ED_AND SRCR0, 0xFFFFFFFD | 
|  | ED 0xE6001628, 0x514 | 
|  | ED 0xE6001648, 0x514 | 
|  | ED 0xE6001658, 0x514 | 
|  | ED 0xE6001678, 0x514 | 
|  |  | 
|  | ED DVFSCR4, 0x00092000 | 
|  | ED DVFSCR5, 0x000000DC | 
|  | ED PLLECR, 0x00000000 | 
|  | WAIT_MASK PLLECR, 0x00000F00, 0x00000000 | 
|  |  | 
|  | ED FRQCRA, 0x0012453C | 
|  | ED FRQCRB, 0x80431350 | 
|  | WAIT_MASK FRQCRB, 0x80000000, 0x00000000 | 
|  | ED FRQCRD, 0x00000B0B | 
|  | WAIT_MASK FRQCRD, 0x80000000, 0x00000000 | 
|  |  | 
|  | ED PCLKCR, 0x00000003 | 
|  | ED VCLKCR1, 0x0000012F | 
|  | ED VCLKCR2, 0x00000119 | 
|  | ED VCLKCR3, 0x00000119 | 
|  | ED ZBCKCR, 0x00000002 | 
|  | ED FLCKCR, 0x00000005 | 
|  | ED SD0CKCR, 0x00000080 | 
|  | ED SD1CKCR, 0x00000080 | 
|  | ED SD2CKCR, 0x00000080 | 
|  | ED FSIACKCR, 0x0000003F | 
|  | ED FSIBCKCR, 0x0000003F | 
|  | ED SUBCKCR, 0x00000080 | 
|  | ED SPUACKCR, 0x0000000B | 
|  | ED SPUVCKCR, 0x0000000B | 
|  | ED MSUCKCR, 0x0000013F | 
|  | ED HSICKCR, 0x00000080 | 
|  | ED MFCK1CR, 0x0000003F | 
|  | ED MFCK2CR, 0x0000003F | 
|  | ED DSITCKCR, 0x00000107 | 
|  | ED DSI0PCKCR, 0x00000313 | 
|  | ED DSI1PCKCR, 0x0000130D | 
|  | ED DSI0PHYCR, 0x2A800E0E | 
|  | ED PLL0CR, 0x1E000000 | 
|  | ED PLL0CR, 0x2D000000 | 
|  | ED PLL1CR, 0x17100000 | 
|  | ED PLL2CR, 0x27000080 | 
|  | ED PLL3CR, 0x1D000000 | 
|  | ED PLL0STPCR, 0x00080000 | 
|  | ED PLL1STPCR, 0x000120C0 | 
|  | ED PLL2STPCR, 0x00012000 | 
|  | ED PLL3STPCR, 0x00000030 | 
|  | ED PLLECR, 0x0000000B | 
|  | WAIT_MASK PLLECR, 0x00000B00, 0x00000B00 | 
|  |  | 
|  | ED DVFSCR3, 0x000120F0 | 
|  | ED MPMODE, 0x00000020 | 
|  | ED VREFCR, 0x0000028A | 
|  | ED RMSTPCR0, 0xE4628087 | 
|  | ED RMSTPCR1, 0xFFFFFFFF | 
|  | ED RMSTPCR2, 0x53FFFFFF | 
|  | ED RMSTPCR3, 0xFFFFFFFF | 
|  | ED RMSTPCR4, 0x00800D3D | 
|  | ED RMSTPCR5, 0xFFFFF3FF | 
|  | ED SMSTPCR2, 0x00000000 | 
|  | ED SRCR2,  0x00040000 | 
|  | ED_AND PLLECR, 0xFFFFFFF7 | 
|  | WAIT_MASK PLLECR, 0x00000800, 0x00000000 | 
|  |  | 
|  | LIST "set SBSC operational" | 
|  | ED HPBCTRL6, 0x00000001 | 
|  | WAIT_MASK HPBCTRL6, 0x00000001, 0x00000001 | 
|  |  | 
|  | LIST "set SBSC operating frequency" | 
|  | ED FRQCRD, 0x00001414 | 
|  | WAIT_MASK FRQCRD, 0x80000000, 0x00000000 | 
|  | ED PLL3CR, 0x1D000000 | 
|  | ED_OR PLLECR, 0x00000008 | 
|  | WAIT_MASK PLLECR, 0x00000800, 0x00000800 | 
|  |  | 
|  | LIST "enable DLL oscillation in DDRPHY" | 
|  | ED_OR DLLCNT0A, 0x00000002 | 
|  |  | 
|  | LIST "wait >= 100 ns" | 
|  | ED SDGENCNTA, 0x00000005 | 
|  | WAIT_MASK SDGENCNTA, 0xFFFFFFFF, 0x00000000 | 
|  |  | 
|  | LIST "target LPDDR2 device settings" | 
|  | ED SDCR0A, 0xACC90159 | 
|  | ED SDCR1A, 0x00010059 | 
|  | ED SDWCRC0A, 0x50874114 | 
|  | ED SDWCRC1A, 0x33199B37 | 
|  | ED SDWCRC2A, 0x008F2313 | 
|  | ED SDWCR00A, 0x31020707 | 
|  | ED SDWCR01A, 0x0017040A | 
|  | ED SDWCR10A, 0x31020707 | 
|  | ED SDWCR11A, 0x0017040A | 
|  |  | 
|  | ED SDDRVCR0A, 0x055557ff | 
|  |  | 
|  | ED SDWCR2A, 0x30000000 | 
|  |  | 
|  | LIST "drive CKE high" | 
|  | ED_OR SDPCRA, 0x00000080 | 
|  | WAIT_MASK SDPCRA, 0x00000080, 0x00000080 | 
|  |  | 
|  | LIST "wait >= 200 us" | 
|  | ED SDGENCNTA, 0x00002710 | 
|  | WAIT_MASK SDGENCNTA, 0xFFFFFFFF, 0x00000000 | 
|  |  | 
|  | LIST "issue reset command to LPDDR2 device" | 
|  | ED SDMRACR0A, 0x0000003F | 
|  | ED SDMRA1, 0x00000000 | 
|  |  | 
|  | LIST "wait >= 10 (or 1) us (docs inconsistent)" | 
|  | ED SDGENCNTA, 0x000001F4 | 
|  | WAIT_MASK SDGENCNTA, 0xFFFFFFFF, 0x00000000 | 
|  |  | 
|  | LIST "MRW ZS initialization calibration command" | 
|  | ED SDMRACR0A, 0x0000FF0A | 
|  | ED SDMRA3, 0x00000000 | 
|  |  | 
|  | LIST "wait >= 1 us" | 
|  | ED SDGENCNTA, 0x00000032 | 
|  | WAIT_MASK SDGENCNTA, 0xFFFFFFFF, 0x00000000 | 
|  |  | 
|  | LIST "specify operating mode in LPDDR2" | 
|  | ED SDMRACR0A, 0x00002201 | 
|  | ED SDMRA1, 0x00000000 | 
|  | ED SDMRACR0A, 0x00000402 | 
|  | ED SDMRA1, 0x00000000 | 
|  | ED SDMRACR0A, 0x00000203 | 
|  | ED SDMRA1, 0x00000000 | 
|  |  | 
|  | LIST "initialize DDR interface" | 
|  | ED SDMRA2, 0x00000000 | 
|  |  | 
|  | LIST "temperature sensor control" | 
|  | ED SDMRTMPCRA, 0x88800004 | 
|  | ED SDMRTMPMSKA,0x00000004 | 
|  |  | 
|  | LIST "auto-refreshing control" | 
|  | ED RTCORA, 0xA55A0032 | 
|  | ED RTCORHA, 0xA55A000C | 
|  | ED RTCSRA, 0xA55A2048 | 
|  |  | 
|  | ED_OR SDCR0A, 0x00000800 | 
|  | ED_OR SDCR1A, 0x00000400 | 
|  |  | 
|  | LIST "auto ZQ calibration control" | 
|  | ED ZQCCRA, 0xFFF20000 | 
|  |  | 
|  | ED_OR DLLCNT0B, 0x00000002 | 
|  | ED SDGENCNTB, 0x00000005 | 
|  | WAIT_MASK SDGENCNTB, 0xFFFFFFFF, 0x00000000 | 
|  |  | 
|  | ED SDCR0B, 0xACC90159 | 
|  | ED SDCR1B, 0x00010059 | 
|  | ED SDWCRC0B, 0x50874114 | 
|  | ED SDWCRC1B, 0x33199B37 | 
|  | ED SDWCRC2B, 0x008F2313 | 
|  | ED SDWCR00B, 0x31020707 | 
|  | ED SDWCR01B, 0x0017040A | 
|  | ED SDWCR10B, 0x31020707 | 
|  | ED SDWCR11B, 0x0017040A | 
|  | ED SDDRVCR0B, 0x055557ff | 
|  | ED SDWCR2B, 0x30000000 | 
|  | ED_OR SDPCRB, 0x00000080 | 
|  | WAIT_MASK SDPCRB, 0x00000080, 0x00000080 | 
|  |  | 
|  | ED SDGENCNTB, 0x00002710 | 
|  | WAIT_MASK SDGENCNTB, 0xFFFFFFFF, 0x00000000 | 
|  | ED SDMRACR0B, 0x0000003F | 
|  |  | 
|  | LIST "upstream u-boot writes to SDMRA1A for both SBSC 1 and 2, which does" | 
|  | LIST "not seem to make a lot of sense..." | 
|  | ED SDMRB1, 0x00000000 | 
|  |  | 
|  | ED SDGENCNTB, 0x000001F4 | 
|  | WAIT_MASK SDGENCNTB, 0xFFFFFFFF, 0x00000000 | 
|  |  | 
|  | ED SDMRACR0B, 0x0000FF0A | 
|  | ED SDMRB3, 0x00000000 | 
|  | ED SDGENCNTB, 0x00000032 | 
|  | WAIT_MASK SDGENCNTB, 0xFFFFFFFF, 0x00000000 | 
|  |  | 
|  | ED SDMRACR0B, 0x00002201 | 
|  | ED SDMRB1, 0x00000000 | 
|  | ED SDMRACR0B, 0x00000402 | 
|  | ED SDMRB1, 0x00000000 | 
|  | ED SDMRACR0B, 0x00000203 | 
|  | ED SDMRB1, 0x00000000 | 
|  | ED SDMRB2, 0x00000000 | 
|  | ED SDMRTMPCRB, 0x88800004 | 
|  | ED SDMRTMPMSKB, 0x00000004 | 
|  | ED RTCORB,  0xA55A0032 | 
|  | ED RTCORHB, 0xA55A000C | 
|  | ED RTCSRB,  0xA55A2048 | 
|  | ED_OR SDCR0B, 0x00000800 | 
|  | ED_OR SDCR1B, 0x00000400 | 
|  | ED ZQCCRB, 0xFFF20000 | 
|  | ED_OR SDPDCR0B, 0x00030000 | 
|  | ED DPHYCNT1B, 0xA5390000 | 
|  | ED DPHYCNT0B, 0x00001200 | 
|  | ED DPHYCNT1B, 0x07CE0000 | 
|  | ED DPHYCNT0B, 0x00001247 | 
|  | WAIT_MASK DPHYCNT2B, 0xFFFFFFFF, 0x07CE0000 | 
|  |  | 
|  | ED_AND SDPDCR0B, 0xFFFCFFFF | 
|  |  | 
|  | ED FRQCRD, 0x00000B0B | 
|  | WAIT_MASK FRQCRD, 0x80000000, 0x00000000 | 
|  |  | 
|  | ED CPGXXCR4, 0xfffffffc | 
|  |  | 
|  | LIST "Setup SCIF4 / workaround" | 
|  | EB PORT32CR, 0x12 | 
|  | EB PORT33CR, 0x22 | 
|  | EB PORT34CR, 0x12 | 
|  | EB PORT35CR, 0x22 | 
|  |  | 
|  | EW 0xE6C80000, 0 | 
|  | EB 0xE6C80004, 0x19 | 
|  | EW 0xE6C80008, 0x0030 | 
|  | EW 0xE6C80018, 0 | 
|  | EW 0xE6C80030, 0x0014 | 
|  |  | 
|  | LIST "Magic to avoid hangs and corruption on DRAM writes." | 
|  |  | 
|  | LIST "It has been observed that the system would most often hang while" | 
|  | LIST "decompressing the kernel, and if it didn't it would always write" | 
|  | LIST "a corrupt image to DRAM." | 
|  | LIST "This problem does not occur in u-boot, and the reason is that" | 
|  | LIST "u-boot performs an additional cache invalidation after setting up" | 
|  | LIST "the DRAM controller. Such an invalidation should not be necessary at" | 
|  | LIST "this point, and attempts at removing parts of the routine to arrive" | 
|  | LIST "at the minimal snippet of code necessary to avoid the DRAM stability" | 
|  | LIST "problem yielded the following:" | 
|  |  | 
|  | MRC p15, 0, r0, c1, c0, 0 | 
|  | MCR p15, 0, r0, c1, c0, 0 |