1 /* 2 * Copyright 2008-2010 Freescale Semiconductor, Inc. 3 * 4 * See file CREDITS for list of people who contributed to this 5 * project. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as 9 * published by the Free Software Foundation; either version 2 of 10 * the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 20 * MA 02111-1307 USA 21 */ 22 23 #include <common.h> 24 #include <asm/processor.h> 25 #include <asm/mmu.h> 26 #include <ioports.h> 27 #include <lmb.h> 28 #include <asm/io.h> 29 #include <asm/mp.h> 30 31 DECLARE_GLOBAL_DATA_PTR; 32 33 int cpu_reset(int nr) 34 { 35 /* dummy function so common/cmd_mp.c will build 36 * should be implemented in the future, when cpu_release() 37 * is supported. Be aware there may be a similiar bug 38 * as exists on MPC85xx w/its PIC having a timing window 39 * associated to resetting the core */ 40 return 1; 41 } 42 43 int cpu_status(int nr) 44 { 45 /* dummy function so common/cmd_mp.c will build */ 46 return 0; 47 } 48 49 int cpu_disable(int nr) 50 { 51 volatile immap_t *immap = (immap_t *) CONFIG_SYS_CCSRBAR; 52 volatile ccsr_gur_t *gur = &immap->im_gur; 53 54 switch (nr) { 55 case 0: 56 setbits_be32(&gur->devdisr, MPC86xx_DEVDISR_CPU0); 57 break; 58 case 1: 59 setbits_be32(&gur->devdisr, MPC86xx_DEVDISR_CPU1); 60 break; 61 default: 62 printf("Invalid cpu number for disable %d\n", nr); 63 return 1; 64 } 65 66 return 0; 67 } 68 69 int is_core_disabled(int nr) { 70 immap_t *immap = (immap_t *) CONFIG_SYS_CCSRBAR; 71 ccsr_gur_t *gur = &immap->im_gur; 72 u32 devdisr = in_be32(&gur->devdisr); 73 74 switch (nr) { 75 case 0: 76 return (devdisr & MPC86xx_DEVDISR_CPU0); 77 case 1: 78 return (devdisr & MPC86xx_DEVDISR_CPU1); 79 default: 80 printf("Invalid cpu number for disable %d\n", nr); 81 } 82 83 return 0; 84 } 85 86 int cpu_release(int nr, int argc, char * const argv[]) 87 { 88 /* dummy function so common/cmd_mp.c will build 89 * should be implemented in the future */ 90 return 1; 91 } 92 93 u32 determine_mp_bootpg(unsigned int *pagesize) 94 { 95 if (pagesize) 96 *pagesize = 4096; 97 98 /* if we have 4G or more of memory, put the boot page at 4Gb-1M */ 99 if ((u64)gd->ram_size > 0xfffff000) 100 return (0xfff00000); 101 102 return (gd->ram_size - (1024 * 1024)); 103 } 104 105 void cpu_mp_lmb_reserve(struct lmb *lmb) 106 { 107 u32 bootpg = determine_mp_bootpg(NULL); 108 109 /* tell u-boot we stole a page */ 110 lmb_reserve(lmb, bootpg, 4096); 111 } 112 113 /* 114 * Copy the code for other cpus to execute into an 115 * aligned location accessible via BPTR 116 */ 117 void setup_mp(void) 118 { 119 extern ulong __secondary_start_page; 120 ulong fixup = (ulong)&__secondary_start_page; 121 u32 bootpg = determine_mp_bootpg(NULL); 122 u32 bootpg_va; 123 124 if (bootpg >= CONFIG_SYS_MAX_DDR_BAT_SIZE) { 125 /* We're not covered by the DDR mapping, set up BAT */ 126 write_bat(DBAT7, CONFIG_SYS_SCRATCH_VA | BATU_BL_128K | 127 BATU_VS | BATU_VP, 128 bootpg | BATL_PP_RW | BATL_MEMCOHERENCE); 129 bootpg_va = CONFIG_SYS_SCRATCH_VA; 130 } else { 131 bootpg_va = bootpg; 132 } 133 134 memcpy((void *)bootpg_va, (void *)fixup, 4096); 135 flush_cache(bootpg_va, 4096); 136 137 /* remove the temporary BAT mapping */ 138 if (bootpg >= CONFIG_SYS_MAX_DDR_BAT_SIZE) 139 write_bat(DBAT7, 0, 0); 140 141 /* If the physical location of bootpg is not at fff00000, set BPTR */ 142 if (bootpg != 0xfff00000) 143 out_be32((uint *)(CONFIG_SYS_CCSRBAR + 0x20), 0x80000000 | 144 (bootpg >> 12)); 145 } 146