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_FSL_CORENET 99 void srio_boot_master(int port) 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[port - 1].ptaacr, 105 SRIO_PORT_ACCEPT_ALL); 106 107 debug("SRIOBOOT - MASTER: Master port [ %d ] for srio boot.\n", port); 108 /* configure inbound window for slave's u-boot image */ 109 debug("SRIOBOOT - MASTER: Inbound window for slave's image; " 110 "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n", 111 (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS, 112 (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1, 113 CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE); 114 out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwtar, 115 CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS >> 12); 116 out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwbar, 117 CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1 >> 12); 118 out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwar, 119 SRIO_IB_ATMU_AR 120 | atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE)); 121 122 /* configure inbound window for slave's u-boot image */ 123 debug("SRIOBOOT - MASTER: Inbound window for slave's image; " 124 "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n", 125 (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS, 126 (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2, 127 CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE); 128 out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwtar, 129 CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS >> 12); 130 out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwbar, 131 CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2 >> 12); 132 out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwar, 133 SRIO_IB_ATMU_AR 134 | atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE)); 135 136 /* configure inbound window for slave's ucode and ENV */ 137 debug("SRIOBOOT - MASTER: Inbound window for slave's ucode and ENV; " 138 "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n", 139 (u64)CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS, 140 (u64)CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS, 141 CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE); 142 out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwtar, 143 CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS >> 12); 144 out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwbar, 145 CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS >> 12); 146 out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwar, 147 SRIO_IB_ATMU_AR 148 | atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE)); 149 } 150 151 void srio_boot_master_release_slave(int port) 152 { 153 struct ccsr_rio *srio = (void *)CONFIG_SYS_FSL_SRIO_ADDR; 154 u32 escsr; 155 debug("SRIOBOOT - MASTER: " 156 "Check the port status and release slave core ...\n"); 157 158 escsr = in_be32((void *)&srio->lp_serial.port[port - 1].pescsr); 159 if (escsr & 0x2) { 160 if (escsr & 0x10100) { 161 debug("SRIOBOOT - MASTER: Port [ %d ] is error.\n", 162 port); 163 } else { 164 debug("SRIOBOOT - MASTER: " 165 "Port [ %d ] is ready, now release slave's core ...\n", 166 port); 167 /* 168 * configure outbound window 169 * with maintenance attribute to set slave's LCSBA1CSR 170 */ 171 out_be32((void *)&srio->atmu.port[port - 1] 172 .outbw[1].rowtar, 0); 173 out_be32((void *)&srio->atmu.port[port - 1] 174 .outbw[1].rowtear, 0); 175 if (port - 1) 176 out_be32((void *)&srio->atmu.port[port - 1] 177 .outbw[1].rowbar, 178 CONFIG_SYS_SRIO2_MEM_PHYS >> 12); 179 else 180 out_be32((void *)&srio->atmu.port[port - 1] 181 .outbw[1].rowbar, 182 CONFIG_SYS_SRIO1_MEM_PHYS >> 12); 183 out_be32((void *)&srio->atmu.port[port - 1] 184 .outbw[1].rowar, 185 SRIO_OB_ATMU_AR_MAINT 186 | atmu_size_mask(SRIO_MAINT_WIN_SIZE)); 187 188 /* 189 * configure outbound window 190 * with R/W attribute to set slave's BRR 191 */ 192 out_be32((void *)&srio->atmu.port[port - 1] 193 .outbw[2].rowtar, 194 SRIO_LCSBA1CSR >> 9); 195 out_be32((void *)&srio->atmu.port[port - 1] 196 .outbw[2].rowtear, 0); 197 if (port - 1) 198 out_be32((void *)&srio->atmu.port[port - 1] 199 .outbw[2].rowbar, 200 (CONFIG_SYS_SRIO2_MEM_PHYS 201 + SRIO_MAINT_WIN_SIZE) >> 12); 202 else 203 out_be32((void *)&srio->atmu.port[port - 1] 204 .outbw[2].rowbar, 205 (CONFIG_SYS_SRIO1_MEM_PHYS 206 + SRIO_MAINT_WIN_SIZE) >> 12); 207 out_be32((void *)&srio->atmu.port[port - 1] 208 .outbw[2].rowar, 209 SRIO_OB_ATMU_AR_RW 210 | atmu_size_mask(SRIO_RW_WIN_SIZE)); 211 212 /* 213 * Set the LCSBA1CSR register in slave 214 * by the maint-outbound window 215 */ 216 if (port - 1) { 217 out_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT 218 + SRIO_LCSBA1CSR_OFFSET, 219 SRIO_LCSBA1CSR); 220 while (in_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT 221 + SRIO_LCSBA1CSR_OFFSET) 222 != SRIO_LCSBA1CSR) 223 ; 224 /* 225 * And then set the BRR register 226 * to release slave core 227 */ 228 out_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT 229 + SRIO_MAINT_WIN_SIZE 230 + CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET, 231 CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK); 232 } else { 233 out_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT 234 + SRIO_LCSBA1CSR_OFFSET, 235 SRIO_LCSBA1CSR); 236 while (in_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT 237 + SRIO_LCSBA1CSR_OFFSET) 238 != SRIO_LCSBA1CSR) 239 ; 240 /* 241 * And then set the BRR register 242 * to release slave core 243 */ 244 out_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT 245 + SRIO_MAINT_WIN_SIZE 246 + CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET, 247 CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK); 248 } 249 debug("SRIOBOOT - MASTER: " 250 "Release slave successfully! Now the slave should start up!\n"); 251 } 252 } else 253 debug("SRIOBOOT - MASTER: Port [ %d ] is not ready.\n", port); 254 } 255 #endif 256