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