1 /* 2 * Copyright 2008-2010 Freescale Semiconductor, Inc. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <asm/processor.h> 9 #include <asm/mmu.h> 10 #include <ioports.h> 11 #include <lmb.h> 12 #include <asm/io.h> 13 #include <asm/mp.h> 14 15 DECLARE_GLOBAL_DATA_PTR; 16 17 int cpu_reset(int nr) 18 { 19 /* dummy function so common/cmd_mp.c will build 20 * should be implemented in the future, when cpu_release() 21 * is supported. Be aware there may be a similiar bug 22 * as exists on MPC85xx w/its PIC having a timing window 23 * associated to resetting the core */ 24 return 1; 25 } 26 27 int cpu_status(int nr) 28 { 29 /* dummy function so common/cmd_mp.c will build */ 30 return 0; 31 } 32 33 int cpu_disable(int nr) 34 { 35 volatile immap_t *immap = (immap_t *) CONFIG_SYS_CCSRBAR; 36 volatile ccsr_gur_t *gur = &immap->im_gur; 37 38 switch (nr) { 39 case 0: 40 setbits_be32(&gur->devdisr, MPC86xx_DEVDISR_CPU0); 41 break; 42 case 1: 43 setbits_be32(&gur->devdisr, MPC86xx_DEVDISR_CPU1); 44 break; 45 default: 46 printf("Invalid cpu number for disable %d\n", nr); 47 return 1; 48 } 49 50 return 0; 51 } 52 53 int is_core_disabled(int nr) { 54 immap_t *immap = (immap_t *) CONFIG_SYS_CCSRBAR; 55 ccsr_gur_t *gur = &immap->im_gur; 56 u32 devdisr = in_be32(&gur->devdisr); 57 58 switch (nr) { 59 case 0: 60 return (devdisr & MPC86xx_DEVDISR_CPU0); 61 case 1: 62 return (devdisr & MPC86xx_DEVDISR_CPU1); 63 default: 64 printf("Invalid cpu number for disable %d\n", nr); 65 } 66 67 return 0; 68 } 69 70 int cpu_release(int nr, int argc, char * const argv[]) 71 { 72 /* dummy function so common/cmd_mp.c will build 73 * should be implemented in the future */ 74 return 1; 75 } 76 77 u32 determine_mp_bootpg(unsigned int *pagesize) 78 { 79 if (pagesize) 80 *pagesize = 4096; 81 82 /* if we have 4G or more of memory, put the boot page at 4Gb-1M */ 83 if ((u64)gd->ram_size > 0xfffff000) 84 return (0xfff00000); 85 86 return (gd->ram_size - (1024 * 1024)); 87 } 88 89 void cpu_mp_lmb_reserve(struct lmb *lmb) 90 { 91 u32 bootpg = determine_mp_bootpg(NULL); 92 93 /* tell u-boot we stole a page */ 94 lmb_reserve(lmb, bootpg, 4096); 95 } 96 97 /* 98 * Copy the code for other cpus to execute into an 99 * aligned location accessible via BPTR 100 */ 101 void setup_mp(void) 102 { 103 extern ulong __secondary_start_page; 104 ulong fixup = (ulong)&__secondary_start_page; 105 u32 bootpg = determine_mp_bootpg(NULL); 106 u32 bootpg_va; 107 108 if (bootpg >= CONFIG_SYS_MAX_DDR_BAT_SIZE) { 109 /* We're not covered by the DDR mapping, set up BAT */ 110 write_bat(DBAT7, CONFIG_SYS_SCRATCH_VA | BATU_BL_128K | 111 BATU_VS | BATU_VP, 112 bootpg | BATL_PP_RW | BATL_MEMCOHERENCE); 113 bootpg_va = CONFIG_SYS_SCRATCH_VA; 114 } else { 115 bootpg_va = bootpg; 116 } 117 118 memcpy((void *)bootpg_va, (void *)fixup, 4096); 119 flush_cache(bootpg_va, 4096); 120 121 /* remove the temporary BAT mapping */ 122 if (bootpg >= CONFIG_SYS_MAX_DDR_BAT_SIZE) 123 write_bat(DBAT7, 0, 0); 124 125 /* If the physical location of bootpg is not at fff00000, set BPTR */ 126 if (bootpg != 0xfff00000) 127 out_be32((uint *)(CONFIG_SYS_CCSRBAR + 0x20), 0x80000000 | 128 (bootpg >> 12)); 129 } 130