]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/powerpc/cpu/mpc8xxx/srio.c
Merge branch 'master' of git://git.denx.de/u-boot-video
[karo-tx-uboot.git] / arch / powerpc / cpu / mpc8xxx / srio.c
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