1 /* 2 * Copyright 2011 Freescale Semiconductor, Inc. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License as published by the Free 6 * Software Foundation; either version 2 of the License, or (at your option) 7 * any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 17 * MA 02111-1307 USA 18 */ 19 20 #include <common.h> 21 #include <config.h> 22 #include <asm/fsl_law.h> 23 #include <asm/fsl_serdes.h> 24 #include <asm/fsl_srio.h> 25 26 #define SRIO_PORT_ACCEPT_ALL 0x10000001 27 #define SRIO_IB_ATMU_AR 0x80f55000 28 #define SRIO_OB_ATMU_AR_MAINT 0x80077000 29 #define SRIO_OB_ATMU_AR_RW 0x80045000 30 #define SRIO_LCSBA1CSR_OFFSET 0x5c 31 #define SRIO_MAINT_WIN_SIZE 0x1000000 /* 16M */ 32 #define SRIO_RW_WIN_SIZE 0x100000 /* 1M */ 33 #define SRIO_LCSBA1CSR 0x60000000 34 35 #if defined(CONFIG_FSL_CORENET) 36 #define _DEVDISR_SRIO1 FSL_CORENET_DEVDISR_SRIO1 37 #define _DEVDISR_SRIO2 FSL_CORENET_DEVDISR_SRIO2 38 #define _DEVDISR_RMU FSL_CORENET_DEVDISR_RMU 39 #define CONFIG_SYS_MPC8xxx_GUTS_ADDR CONFIG_SYS_MPC85xx_GUTS_ADDR 40 #elif defined(CONFIG_MPC85xx) 41 #define _DEVDISR_SRIO1 MPC85xx_DEVDISR_SRIO 42 #define _DEVDISR_SRIO2 MPC85xx_DEVDISR_SRIO 43 #define _DEVDISR_RMU MPC85xx_DEVDISR_RMSG 44 #define CONFIG_SYS_MPC8xxx_GUTS_ADDR CONFIG_SYS_MPC85xx_GUTS_ADDR 45 #elif defined(CONFIG_MPC86xx) 46 #define _DEVDISR_SRIO1 MPC86xx_DEVDISR_SRIO 47 #define _DEVDISR_SRIO2 MPC86xx_DEVDISR_SRIO 48 #define _DEVDISR_RMU MPC86xx_DEVDISR_RMSG 49 #define CONFIG_SYS_MPC8xxx_GUTS_ADDR \ 50 (&((immap_t *)CONFIG_SYS_IMMR)->im_gur) 51 #else 52 #error "No defines for DEVDISR_SRIO" 53 #endif 54 55 void srio_init(void) 56 { 57 ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC8xxx_GUTS_ADDR; 58 int srio1_used = 0, srio2_used = 0; 59 60 if (is_serdes_configured(SRIO1)) { 61 set_next_law(CONFIG_SYS_SRIO1_MEM_PHYS, 62 law_size_bits(CONFIG_SYS_SRIO1_MEM_SIZE), 63 LAW_TRGT_IF_RIO_1); 64 srio1_used = 1; 65 printf("SRIO1: enabled\n"); 66 } else { 67 printf("SRIO1: disabled\n"); 68 } 69 70 #ifdef CONFIG_SRIO2 71 if (is_serdes_configured(SRIO2)) { 72 set_next_law(CONFIG_SYS_SRIO2_MEM_PHYS, 73 law_size_bits(CONFIG_SYS_SRIO2_MEM_SIZE), 74 LAW_TRGT_IF_RIO_2); 75 srio2_used = 1; 76 printf("SRIO2: enabled\n"); 77 } else { 78 printf("SRIO2: disabled\n"); 79 } 80 #endif 81 82 #ifdef CONFIG_FSL_CORENET 83 /* On FSL_CORENET devices we can disable individual ports */ 84 if (!srio1_used) 85 setbits_be32(&gur->devdisr, FSL_CORENET_DEVDISR_SRIO1); 86 if (!srio2_used) 87 setbits_be32(&gur->devdisr, FSL_CORENET_DEVDISR_SRIO2); 88 #endif 89 90 /* neither port is used - disable everything */ 91 if (!srio1_used && !srio2_used) { 92 setbits_be32(&gur->devdisr, _DEVDISR_SRIO1); 93 setbits_be32(&gur->devdisr, _DEVDISR_SRIO2); 94 setbits_be32(&gur->devdisr, _DEVDISR_RMU); 95 } 96 } 97 98 #ifdef CONFIG_SRIOBOOT_MASTER 99 void srio_boot_master(void) 100 { 101 struct ccsr_rio *srio = (void *)CONFIG_SYS_FSL_SRIO_ADDR; 102 103 /* set port accept-all */ 104 out_be32((void *)&srio->impl.port[CONFIG_SRIOBOOT_MASTER_PORT].ptaacr, 105 SRIO_PORT_ACCEPT_ALL); 106 107 debug("SRIOBOOT - MASTER: Master port [ %d ] for srio boot.\n", 108 CONFIG_SRIOBOOT_MASTER_PORT); 109 /* configure inbound window for slave's u-boot image */ 110 debug("SRIOBOOT - MASTER: Inbound window for slave's image; " 111 "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n", 112 (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_LAW_PHYS1, 113 (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_SRIO_PHYS1, 114 CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE); 115 out_be32((void *)&srio->atmu 116 .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[0].riwtar, 117 CONFIG_SRIOBOOT_SLAVE_IMAGE_LAW_PHYS1 >> 12); 118 out_be32((void *)&srio->atmu 119 .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[0].riwbar, 120 CONFIG_SRIOBOOT_SLAVE_IMAGE_SRIO_PHYS1 >> 12); 121 out_be32((void *)&srio->atmu 122 .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[0].riwar, 123 SRIO_IB_ATMU_AR 124 | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE)); 125 126 /* configure inbound window for slave's u-boot image */ 127 debug("SRIOBOOT - MASTER: Inbound window for slave's image; " 128 "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n", 129 (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_LAW_PHYS2, 130 (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_SRIO_PHYS2, 131 CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE); 132 out_be32((void *)&srio->atmu 133 .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[1].riwtar, 134 CONFIG_SRIOBOOT_SLAVE_IMAGE_LAW_PHYS2 >> 12); 135 out_be32((void *)&srio->atmu 136 .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[1].riwbar, 137 CONFIG_SRIOBOOT_SLAVE_IMAGE_SRIO_PHYS2 >> 12); 138 out_be32((void *)&srio->atmu 139 .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[1].riwar, 140 SRIO_IB_ATMU_AR 141 | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE)); 142 143 /* configure inbound window for slave's ucode */ 144 debug("SRIOBOOT - MASTER: Inbound window for slave's ucode; " 145 "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n", 146 (u64)CONFIG_SRIOBOOT_SLAVE_UCODE_LAW_PHYS, 147 (u64)CONFIG_SRIOBOOT_SLAVE_UCODE_SRIO_PHYS, 148 CONFIG_SRIOBOOT_SLAVE_UCODE_SIZE); 149 out_be32((void *)&srio->atmu 150 .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[2].riwtar, 151 CONFIG_SRIOBOOT_SLAVE_UCODE_LAW_PHYS >> 12); 152 out_be32((void *)&srio->atmu 153 .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[2].riwbar, 154 CONFIG_SRIOBOOT_SLAVE_UCODE_SRIO_PHYS >> 12); 155 out_be32((void *)&srio->atmu 156 .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[2].riwar, 157 SRIO_IB_ATMU_AR 158 | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_UCODE_SIZE)); 159 160 /* configure inbound window for slave's ENV */ 161 debug("SRIOBOOT - MASTER: Inbound window for slave's ENV; " 162 "Local = 0x%llx, Siro = 0x%llx, Size = 0x%x\n", 163 CONFIG_SRIOBOOT_SLAVE_ENV_LAW_PHYS, 164 CONFIG_SRIOBOOT_SLAVE_ENV_SRIO_PHYS, 165 CONFIG_SRIOBOOT_SLAVE_ENV_SIZE); 166 out_be32((void *)&srio->atmu 167 .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[3].riwtar, 168 CONFIG_SRIOBOOT_SLAVE_ENV_LAW_PHYS >> 12); 169 out_be32((void *)&srio->atmu 170 .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[3].riwbar, 171 CONFIG_SRIOBOOT_SLAVE_ENV_SRIO_PHYS >> 12); 172 out_be32((void *)&srio->atmu 173 .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[3].riwar, 174 SRIO_IB_ATMU_AR 175 | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_ENV_SIZE)); 176 } 177 178 #ifdef CONFIG_SRIOBOOT_SLAVE_HOLDOFF 179 void srio_boot_master_release_slave(void) 180 { 181 struct ccsr_rio *srio = (void *)CONFIG_SYS_FSL_SRIO_ADDR; 182 u32 escsr; 183 debug("SRIOBOOT - MASTER: " 184 "Check the port status and release slave core ...\n"); 185 186 escsr = in_be32((void *)&srio->lp_serial 187 .port[CONFIG_SRIOBOOT_MASTER_PORT].pescsr); 188 if (escsr & 0x2) { 189 if (escsr & 0x10100) { 190 debug("SRIOBOOT - MASTER: Port [ %d ] is error.\n", 191 CONFIG_SRIOBOOT_MASTER_PORT); 192 } else { 193 debug("SRIOBOOT - MASTER: " 194 "Port [ %d ] is ready, now release slave's core ...\n", 195 CONFIG_SRIOBOOT_MASTER_PORT); 196 /* 197 * configure outbound window 198 * with maintenance attribute to set slave's LCSBA1CSR 199 */ 200 out_be32((void *)&srio->atmu 201 .port[CONFIG_SRIOBOOT_MASTER_PORT] 202 .outbw[1].rowtar, 0); 203 out_be32((void *)&srio->atmu 204 .port[CONFIG_SRIOBOOT_MASTER_PORT] 205 .outbw[1].rowtear, 0); 206 if (CONFIG_SRIOBOOT_MASTER_PORT) 207 out_be32((void *)&srio->atmu 208 .port[CONFIG_SRIOBOOT_MASTER_PORT] 209 .outbw[1].rowbar, 210 CONFIG_SYS_SRIO2_MEM_PHYS >> 12); 211 else 212 out_be32((void *)&srio->atmu 213 .port[CONFIG_SRIOBOOT_MASTER_PORT] 214 .outbw[1].rowbar, 215 CONFIG_SYS_SRIO1_MEM_PHYS >> 12); 216 out_be32((void *)&srio->atmu 217 .port[CONFIG_SRIOBOOT_MASTER_PORT] 218 .outbw[1].rowar, 219 SRIO_OB_ATMU_AR_MAINT 220 | atmu_size_mask(SRIO_MAINT_WIN_SIZE)); 221 222 /* 223 * configure outbound window 224 * with R/W attribute to set slave's BRR 225 */ 226 out_be32((void *)&srio->atmu 227 .port[CONFIG_SRIOBOOT_MASTER_PORT] 228 .outbw[2].rowtar, 229 SRIO_LCSBA1CSR >> 9); 230 out_be32((void *)&srio->atmu 231 .port[CONFIG_SRIOBOOT_MASTER_PORT] 232 .outbw[2].rowtear, 0); 233 if (CONFIG_SRIOBOOT_MASTER_PORT) 234 out_be32((void *)&srio->atmu 235 .port[CONFIG_SRIOBOOT_MASTER_PORT] 236 .outbw[2].rowbar, 237 (CONFIG_SYS_SRIO2_MEM_PHYS 238 + SRIO_MAINT_WIN_SIZE) >> 12); 239 else 240 out_be32((void *)&srio->atmu 241 .port[CONFIG_SRIOBOOT_MASTER_PORT] 242 .outbw[2].rowbar, 243 (CONFIG_SYS_SRIO1_MEM_PHYS 244 + SRIO_MAINT_WIN_SIZE) >> 12); 245 out_be32((void *)&srio->atmu 246 .port[CONFIG_SRIOBOOT_MASTER_PORT] 247 .outbw[2].rowar, 248 SRIO_OB_ATMU_AR_RW 249 | atmu_size_mask(SRIO_RW_WIN_SIZE)); 250 251 /* 252 * Set the LCSBA1CSR register in slave 253 * by the maint-outbound window 254 */ 255 if (CONFIG_SRIOBOOT_MASTER_PORT) { 256 out_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT 257 + SRIO_LCSBA1CSR_OFFSET, 258 SRIO_LCSBA1CSR); 259 while (in_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT 260 + SRIO_LCSBA1CSR_OFFSET) 261 != SRIO_LCSBA1CSR) 262 ; 263 /* 264 * And then set the BRR register 265 * to release slave core 266 */ 267 out_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT 268 + SRIO_MAINT_WIN_SIZE 269 + CONFIG_SRIOBOOT_SLAVE_BRR_OFFSET, 270 CONFIG_SRIOBOOT_SLAVE_RELEASE_MASK); 271 } else { 272 out_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT 273 + SRIO_LCSBA1CSR_OFFSET, 274 SRIO_LCSBA1CSR); 275 while (in_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT 276 + SRIO_LCSBA1CSR_OFFSET) 277 != SRIO_LCSBA1CSR) 278 ; 279 /* 280 * And then set the BRR register 281 * to release slave core 282 */ 283 out_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT 284 + SRIO_MAINT_WIN_SIZE 285 + CONFIG_SRIOBOOT_SLAVE_BRR_OFFSET, 286 CONFIG_SRIOBOOT_SLAVE_RELEASE_MASK); 287 } 288 debug("SRIOBOOT - MASTER: " 289 "Release slave successfully! Now the slave should start up!\n"); 290 } 291 } else 292 debug("SRIOBOOT - MASTER: Port [ %d ] is not ready.\n", 293 CONFIG_SRIOBOOT_MASTER_PORT); 294 } 295 #endif 296 #endif 297