Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #include <asm/reg.h>
0003 #include <asm/ppc_asm.h>
0004 #include <asm/processor.h>
0005 #include <asm/cache.h>
0006 
0007 
0008 #define SDRAM_CTRL  0x104
0009 #define SC_MODE_EN  (1<<31)
0010 #define SC_CKE      (1<<30)
0011 #define SC_REF_EN   (1<<28)
0012 #define SC_SOFT_PRE (1<<1)
0013 
0014 #define GPIOW_GPIOE 0xc00
0015 #define GPIOW_DDR   0xc08
0016 #define GPIOW_DVO   0xc0c
0017 
0018 #define CDM_CE      0x214
0019 #define CDM_SDRAM   (1<<3)
0020 
0021 
0022 /* helpers... beware: r10 and r4 are overwritten */
0023 #define SAVE_SPRN(reg, addr)        \
0024     mfspr   r10, SPRN_##reg;    \
0025     stw r10, ((addr)*4)(r4);
0026 
0027 #define LOAD_SPRN(reg, addr)        \
0028     lwz r10, ((addr)*4)(r4);    \
0029     mtspr   SPRN_##reg, r10;    \
0030     sync;               \
0031     isync;
0032 
0033 
0034     .data
0035 registers:
0036     .space 0x5c*4
0037     .text
0038 
0039 /* ---------------------------------------------------------------------- */
0040 /* low-power mode with help of M68HLC908QT1 */
0041 
0042     .globl lite5200_low_power
0043 lite5200_low_power:
0044 
0045     mr  r7, r3  /* save SRAM va */
0046     mr  r8, r4  /* save MBAR va */
0047 
0048     /* setup wakeup address for u-boot at physical location 0x0 */
0049     lis r3, CONFIG_KERNEL_START@h
0050     lis r4, lite5200_wakeup@h
0051     ori r4, r4, lite5200_wakeup@l
0052     sub r4, r4, r3
0053     stw r4, 0(r3)
0054 
0055 
0056     /*
0057      * save stuff BDI overwrites
0058      * 0xf0 (0xe0->0x100 gets overwritten when BDI connected;
0059      *   even when CONFIG_BDI_SWITCH is disabled and MMU XLAT commented; heisenbug?))
0060      * WARNING: self-refresh doesn't seem to work when BDI2000 is connected,
0061      *   possibly because BDI sets SDRAM registers before wakeup code does
0062      */
0063     lis r4, registers@h
0064     ori r4, r4, registers@l
0065     lwz r10, 0xf0(r3)
0066     stw r10, (0x1d*4)(r4)
0067 
0068     /* save registers to r4 [destroys r10] */
0069     SAVE_SPRN(LR, 0x1c)
0070     bl  save_regs
0071 
0072     /* flush caches [destroys r3, r4] */
0073     bl  flush_data_cache
0074 
0075 
0076     /* copy code to sram */
0077     mr  r4, r7
0078     li  r3, (sram_code_end - sram_code)/4
0079     mtctr   r3
0080     lis r3, sram_code@h
0081     ori r3, r3, sram_code@l
0082 1:
0083     lwz r5, 0(r3)
0084     stw r5, 0(r4)
0085     addi    r3, r3, 4
0086     addi    r4, r4, 4
0087     bdnz    1b
0088 
0089     /* get tb_ticks_per_usec */
0090     lis r3, tb_ticks_per_usec@h
0091     lwz r11, tb_ticks_per_usec@l(r3)
0092 
0093     /* disable I and D caches */
0094     mfspr   r3, SPRN_HID0
0095     ori r3, r3, HID0_ICE | HID0_DCE
0096     xori    r3, r3, HID0_ICE | HID0_DCE
0097     sync; isync;
0098     mtspr   SPRN_HID0, r3
0099     sync; isync;
0100 
0101     /* jump to sram */
0102     mtlr    r7
0103     blrl
0104     /* doesn't return */
0105 
0106 
0107 sram_code:
0108     /* self refresh */
0109     lwz r4, SDRAM_CTRL(r8)
0110 
0111     /* send NOP (precharge) */
0112     oris    r4, r4, SC_MODE_EN@h    /* mode_en */
0113     stw r4, SDRAM_CTRL(r8)
0114     sync
0115 
0116     ori r4, r4, SC_SOFT_PRE /* soft_pre */
0117     stw r4, SDRAM_CTRL(r8)
0118     sync
0119     xori    r4, r4, SC_SOFT_PRE
0120 
0121     xoris   r4, r4, SC_MODE_EN@h    /* !mode_en */
0122     stw r4, SDRAM_CTRL(r8)
0123     sync
0124 
0125     /* delay (for NOP to finish) */
0126     li  r12, 1
0127     bl  udelay
0128 
0129     /*
0130      * mode_en must not be set when enabling self-refresh
0131      * send AR with CKE low (self-refresh)
0132      */
0133     oris    r4, r4, (SC_REF_EN | SC_CKE)@h
0134     xoris   r4, r4, (SC_CKE)@h  /* ref_en !cke */
0135     stw r4, SDRAM_CTRL(r8)
0136     sync
0137 
0138     /* delay (after !CKE there should be two cycles) */
0139     li  r12, 1
0140     bl  udelay
0141 
0142     /* disable clock */
0143     lwz r4, CDM_CE(r8)
0144     ori r4, r4, CDM_SDRAM
0145     xori    r4, r4, CDM_SDRAM
0146     stw r4, CDM_CE(r8)
0147     sync
0148 
0149     /* delay a bit */
0150     li  r12, 1
0151     bl  udelay
0152 
0153 
0154     /* turn off with QT chip */
0155     li  r4, 0x02
0156     stb r4, GPIOW_GPIOE(r8) /* enable gpio_wkup1 */
0157     sync
0158 
0159     stb r4, GPIOW_DVO(r8)   /* "output" high */
0160     sync
0161     stb r4, GPIOW_DDR(r8)   /* output */
0162     sync
0163     stb r4, GPIOW_DVO(r8)   /* output high */
0164     sync
0165 
0166     /* 10uS delay */
0167     li  r12, 10
0168     bl  udelay
0169 
0170     /* turn off */
0171     li  r4, 0
0172     stb r4, GPIOW_DVO(r8)   /* output low */
0173     sync
0174 
0175     /* wait until we're offline */
0176   1:
0177     b   1b
0178 
0179 
0180     /* local udelay in sram is needed */
0181   udelay: /* r11 - tb_ticks_per_usec, r12 - usecs, overwrites r13 */
0182     mullw   r12, r12, r11
0183     mftb    r13 /* start */
0184     add r12, r13, r12 /* end */
0185     1:
0186     mftb    r13 /* current */
0187     cmp cr0, r13, r12
0188     blt 1b
0189     blr
0190 
0191 sram_code_end:
0192 
0193 
0194 
0195 /* uboot jumps here on resume */
0196 lite5200_wakeup:
0197     bl  restore_regs
0198 
0199 
0200     /* HIDs, MSR */
0201     LOAD_SPRN(HID1, 0x19)
0202     LOAD_SPRN(HID2, 0x1a)
0203 
0204 
0205     /* address translation is tricky (see turn_on_mmu) */
0206     mfmsr   r10
0207     ori r10, r10, MSR_DR | MSR_IR
0208 
0209 
0210     mtspr   SPRN_SRR1, r10
0211     lis r10, mmu_on@h
0212     ori r10, r10, mmu_on@l
0213     mtspr   SPRN_SRR0, r10
0214     sync
0215     rfi
0216 mmu_on:
0217     /* kernel offset (r4 is still set from restore_registers) */
0218     addis   r4, r4, CONFIG_KERNEL_START@h
0219 
0220 
0221     /* restore MSR */
0222     lwz r10, (4*0x1b)(r4)
0223     mtmsr   r10
0224     sync; isync;
0225 
0226     /* invalidate caches */
0227     mfspr   r10, SPRN_HID0
0228     ori r5, r10, HID0_ICFI | HID0_DCI
0229     mtspr   SPRN_HID0, r5   /* invalidate caches */
0230     sync; isync;
0231     mtspr   SPRN_HID0, r10
0232     sync; isync;
0233 
0234     /* enable caches */
0235     lwz r10, (4*0x18)(r4)
0236     mtspr   SPRN_HID0, r10  /* restore (enable caches, DPM) */
0237     /* ^ this has to be after address translation set in MSR */
0238     sync
0239     isync
0240 
0241 
0242     /* restore 0xf0 (BDI2000) */
0243     lis r3, CONFIG_KERNEL_START@h
0244     lwz r10, (0x1d*4)(r4)
0245     stw r10, 0xf0(r3)
0246 
0247     LOAD_SPRN(LR, 0x1c)
0248 
0249 
0250     blr
0251 _ASM_NOKPROBE_SYMBOL(lite5200_wakeup)
0252 
0253 
0254 /* ---------------------------------------------------------------------- */
0255 /* boring code: helpers */
0256 
0257 /* save registers */
0258 #define SAVE_BAT(n, addr)       \
0259     SAVE_SPRN(DBAT##n##L, addr);    \
0260     SAVE_SPRN(DBAT##n##U, addr+1);  \
0261     SAVE_SPRN(IBAT##n##L, addr+2);  \
0262     SAVE_SPRN(IBAT##n##U, addr+3);
0263 
0264 #define SAVE_SR(n, addr)        \
0265     mfsr    r10, n;         \
0266     stw r10, ((addr)*4)(r4);
0267 
0268 #define SAVE_4SR(n, addr)   \
0269     SAVE_SR(n, addr);   \
0270     SAVE_SR(n+1, addr+1);   \
0271     SAVE_SR(n+2, addr+2);   \
0272     SAVE_SR(n+3, addr+3);
0273 
0274 save_regs:
0275     stw r0, 0(r4)
0276     stw r1, 0x4(r4)
0277     stw r2, 0x8(r4)
0278     stmw    r11, 0xc(r4) /* 0xc -> 0x5f, (0x18*4-1) */
0279 
0280     SAVE_SPRN(HID0, 0x18)
0281     SAVE_SPRN(HID1, 0x19)
0282     SAVE_SPRN(HID2, 0x1a)
0283     mfmsr   r10
0284     stw r10, (4*0x1b)(r4)
0285     /*SAVE_SPRN(LR, 0x1c) have to save it before the call */
0286     /* 0x1d reserved by 0xf0 */
0287     SAVE_SPRN(RPA,   0x1e)
0288     SAVE_SPRN(SDR1,  0x1f)
0289 
0290     /* save MMU regs */
0291     SAVE_BAT(0, 0x20)
0292     SAVE_BAT(1, 0x24)
0293     SAVE_BAT(2, 0x28)
0294     SAVE_BAT(3, 0x2c)
0295     SAVE_BAT(4, 0x30)
0296     SAVE_BAT(5, 0x34)
0297     SAVE_BAT(6, 0x38)
0298     SAVE_BAT(7, 0x3c)
0299 
0300     SAVE_4SR(0, 0x40)
0301     SAVE_4SR(4, 0x44)
0302     SAVE_4SR(8, 0x48)
0303     SAVE_4SR(12, 0x4c)
0304 
0305     SAVE_SPRN(SPRG0, 0x50)
0306     SAVE_SPRN(SPRG1, 0x51)
0307     SAVE_SPRN(SPRG2, 0x52)
0308     SAVE_SPRN(SPRG3, 0x53)
0309     SAVE_SPRN(SPRG4, 0x54)
0310     SAVE_SPRN(SPRG5, 0x55)
0311     SAVE_SPRN(SPRG6, 0x56)
0312     SAVE_SPRN(SPRG7, 0x57)
0313 
0314     SAVE_SPRN(IABR,  0x58)
0315     SAVE_SPRN(DABR,  0x59)
0316     SAVE_SPRN(TBRL,  0x5a)
0317     SAVE_SPRN(TBRU,  0x5b)
0318 
0319     blr
0320 
0321 
0322 /* restore registers */
0323 #define LOAD_BAT(n, addr)       \
0324     LOAD_SPRN(DBAT##n##L, addr);    \
0325     LOAD_SPRN(DBAT##n##U, addr+1);  \
0326     LOAD_SPRN(IBAT##n##L, addr+2);  \
0327     LOAD_SPRN(IBAT##n##U, addr+3);
0328 
0329 #define LOAD_SR(n, addr)        \
0330     lwz r10, ((addr)*4)(r4);    \
0331     mtsr    n, r10;
0332 
0333 #define LOAD_4SR(n, addr)   \
0334     LOAD_SR(n, addr);   \
0335     LOAD_SR(n+1, addr+1);   \
0336     LOAD_SR(n+2, addr+2);   \
0337     LOAD_SR(n+3, addr+3);
0338 
0339 restore_regs:
0340     lis r4, registers@h
0341     ori r4, r4, registers@l
0342 
0343     /* MMU is not up yet */
0344     subis   r4, r4, CONFIG_KERNEL_START@h
0345 
0346     lwz r0, 0(r4)
0347     lwz r1, 0x4(r4)
0348     lwz r2, 0x8(r4)
0349     lmw r11, 0xc(r4)
0350 
0351     /*
0352      * these are a bit tricky
0353      *
0354      * 0x18 - HID0
0355      * 0x19 - HID1
0356      * 0x1a - HID2
0357      * 0x1b - MSR
0358      * 0x1c - LR
0359      * 0x1d - reserved by 0xf0 (BDI2000)
0360      */
0361     LOAD_SPRN(RPA,   0x1e);
0362     LOAD_SPRN(SDR1,  0x1f);
0363 
0364     /* restore MMU regs */
0365     LOAD_BAT(0, 0x20)
0366     LOAD_BAT(1, 0x24)
0367     LOAD_BAT(2, 0x28)
0368     LOAD_BAT(3, 0x2c)
0369     LOAD_BAT(4, 0x30)
0370     LOAD_BAT(5, 0x34)
0371     LOAD_BAT(6, 0x38)
0372     LOAD_BAT(7, 0x3c)
0373 
0374     LOAD_4SR(0, 0x40)
0375     LOAD_4SR(4, 0x44)
0376     LOAD_4SR(8, 0x48)
0377     LOAD_4SR(12, 0x4c)
0378 
0379     /* rest of regs */
0380     LOAD_SPRN(SPRG0, 0x50);
0381     LOAD_SPRN(SPRG1, 0x51);
0382     LOAD_SPRN(SPRG2, 0x52);
0383     LOAD_SPRN(SPRG3, 0x53);
0384     LOAD_SPRN(SPRG4, 0x54);
0385     LOAD_SPRN(SPRG5, 0x55);
0386     LOAD_SPRN(SPRG6, 0x56);
0387     LOAD_SPRN(SPRG7, 0x57);
0388 
0389     LOAD_SPRN(IABR,  0x58);
0390     LOAD_SPRN(DABR,  0x59);
0391     LOAD_SPRN(TBWL,  0x5a); /* these two have separate R/W regs */
0392     LOAD_SPRN(TBWU,  0x5b);
0393 
0394     blr
0395 _ASM_NOKPROBE_SYMBOL(restore_regs)
0396 
0397 
0398 
0399 /* cache flushing code. copied from arch/ppc/boot/util.S */
0400 #define NUM_CACHE_LINES (128*8)
0401 
0402 /*
0403  * Flush data cache
0404  * Do this by just reading lots of stuff into the cache.
0405  */
0406 flush_data_cache:
0407     lis r3,CONFIG_KERNEL_START@h
0408     ori r3,r3,CONFIG_KERNEL_START@l
0409     li  r4,NUM_CACHE_LINES
0410     mtctr   r4
0411 1:
0412     lwz r4,0(r3)
0413     addi    r3,r3,L1_CACHE_BYTES    /* Next line, please */
0414     bdnz    1b
0415     blr