add files to build ducati (m3) side firmware
[gstreamer-omap:ndecs-libdce.git] / ducati / platform / base_image / src / main.c
1 /*\r
2  * Copyright (c) 2010, Texas Instruments Incorporated\r
3  * All rights reserved.\r
4  *\r
5  * Redistribution and use in source and binary forms, with or without\r
6  * modification, are permitted provided that the following conditions\r
7  * are met:\r
8  *\r
9  * *  Redistributions of source code must retain the above copyright\r
10  *    notice, this list of conditions and the following disclaimer.\r
11  *\r
12  * *  Redistributions in binary form must reproduce the above copyright\r
13  *    notice, this list of conditions and the following disclaimer in the\r
14  *    documentation and/or other materials provided with the distribution.\r
15  *\r
16  * *  Neither the name of Texas Instruments Incorporated nor the names of\r
17  *    its contributors may be used to endorse or promote products derived\r
18  *    from this software without specific prior written permission.\r
19  *\r
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\r
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\r
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\r
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
31  */\r
32 \r
33 \r
34 #include <xdc/std.h>\r
35 #include <xdc/runtime/Memory.h>\r
36 #include <xdc/runtime/IHeap.h>\r
37 #include <xdc/runtime/System.h>\r
38 \r
39 #include <ti/sysbios/BIOS.h>\r
40 #include <ti/sysbios/ipc/Semaphore.h>\r
41 #include <ti/sysbios/knl/Task.h>\r
42 #include <ti/sysbios/hal/ammu/AMMU.h>\r
43 #include <ti/sysbios/family/arm/ducati/CTM.h>\r
44 \r
45 #include <ti/sysbios/hal/Hwi.h>\r
46 #include <ti/omap/slpm/idle.h>\r
47 #include <ti/omap/mem/shim/MemMgr.h>\r
48 #include <ti/sysbios/hal/Timer.h>\r
49 #include <ti/sysbios/heaps/HeapMem.h>\r
50 \r
51 #include <ti/sysbios/family/arm/ducati/GateDualCore.h>\r
52 \r
53 \r
54 #include <ti/ipc/Ipc.h>\r
55 #include <ti/ipc/MultiProc.h>\r
56 #include <ti/sdo/utils/MultiProc.h>\r
57 #include <xdc/runtime/Diags.h>\r
58 #include <ti/sdo/fc/global/FCSettings.h>\r
59 #include <ti/sdo/ce/global/CESettings.h>\r
60 \r
61 #include "dce_priv.h"\r
62 \r
63 #define PM_IVAHD_PWRSTCTRL        (*(volatile unsigned int *)0xAA306F00)\r
64 #define RM_IVAHD_RSTCTRL          (*(volatile unsigned int *)0xAA306F10)\r
65 #define RM_IVAHD_RSTST            (*(volatile unsigned int *)0xAA306F14)\r
66 \r
67 #define CM_IVAHD_CLKSTCTRL        (*(volatile unsigned int *)0xAA008F00)\r
68 #define CM_IVAHD_CLKCTRL          (*(volatile unsigned int *)0xAA008F20)\r
69 #define CM_IVAHD_SL2_CLKCTRL      (*(volatile unsigned int *)0xAA008F28)\r
70 \r
71 #define CM_DIV_M5_DPLL_IVA        (*(volatile unsigned int *)0xAA0041BC)\r
72 \r
73 #define IVAHD_CONFIG_REG_BASE     (0xBA000000)\r
74 #define ICONT1_ITCM_BASE          (IVAHD_CONFIG_REG_BASE + 0x08000)\r
75 #define ICONT2_ITCM_BASE          (IVAHD_CONFIG_REG_BASE + 0x18000)\r
76 \r
77 \r
78 \r
79 /*******************************************************************************\r
80  *   Hex code to set for Stack setting, Interrupt vector setting\r
81  *   and instruction to put ICONT in WFI mode.\r
82  *   This shall be placed at TCM_BASE_ADDRESS of given IVAHD, which is\r
83  *   0x0000 locally after reset.\r
84  *******************************************************************************/\r
85 \r
86 const unsigned int icont_boot[] = {\r
87         0xEA000006,\r
88         0xEAFFFFFE,\r
89         0xEAFFFFFE,\r
90         0xEAFFFFFE,\r
91         0xEAFFFFFE,\r
92         0xEAFFFFFE,\r
93         0xEAFFFFFE,\r
94         0xEAFFFFFE,\r
95         0xE3A00000,\r
96         0xEE070F9A,\r
97         0xEE070F90,\r
98         0xE3A00000,\r
99         0xEAFFFFFE,\r
100         0xEAFFFFF1\r
101 };\r
102 \r
103 UInt32 HDVICP_Reset(void * handle, void * iresHandle)\r
104 {\r
105     int i;\r
106     volatile unsigned int *icont1_itcm_base_addr =\r
107             (unsigned int *)ICONT1_ITCM_BASE;\r
108     volatile unsigned int *icont2_itcm_base_addr =\r
109             (unsigned int *)ICONT2_ITCM_BASE;\r
110 \r
111     /*\r
112      * Reset IVA HD, SL2 and ICONTs\r
113      */\r
114 \r
115     DEBUG("HDVICP_Reset");\r
116 \r
117     /* First put IVA into HW Auto mode */\r
118     CM_IVAHD_CLKSTCTRL |= 0x00000003;\r
119 \r
120     /* Wait for IVA HD to standby */\r
121     while (!((CM_IVAHD_CLKCTRL) & 0x00040000));\r
122 \r
123     /* Disable IVAHD and SL2 modules */\r
124     CM_IVAHD_CLKCTRL = 0x00000000;\r
125     CM_IVAHD_SL2_CLKCTRL = 0x00000000;\r
126 \r
127     /* Ensure that IVAHD and SL2 are disabled */\r
128     while (!(CM_IVAHD_CLKCTRL & 0x00030000));\r
129     while (!(CM_IVAHD_SL2_CLKCTRL & 0x00030000));\r
130 \r
131     /* Reset IVAHD sequencers and SL2 */\r
132     RM_IVAHD_RSTCTRL |= 0x00000007;\r
133 \r
134     /*\r
135      * Check if modules are reset\r
136      */\r
137 \r
138     /* First clear the status bits */\r
139     RM_IVAHD_RSTST |= 0x00000007;\r
140 \r
141     /* Wait for confirmation that the systems have been reset */\r
142     /* THIS CHECK MAY NOT BE NECESSARY, AND MOST OF ALL GIVEN OUR STATE,\r
143      * MAY NOT BE POSSIBLE\r
144      */\r
145 \r
146     /* Copy boot code to ICONT1 & ICONT2 memory */\r
147     for (i = 0; i < DIM(icont_boot); i++) {\r
148         *icont1_itcm_base_addr++ = icont_boot[i];\r
149         *icont2_itcm_base_addr++ = icont_boot[i];\r
150     }\r
151 \r
152     /* Ensure that the wake up mode is set to SW_WAKEUP */\r
153     CM_IVAHD_CLKSTCTRL &= 0x00000002;\r
154 \r
155     /* Enable IVAHD and SL2 modules */\r
156     CM_IVAHD_CLKCTRL = 0x00000001;\r
157     CM_IVAHD_SL2_CLKCTRL = 0x00000001;\r
158 \r
159     /* Deassert the SL2 reset */\r
160     RM_IVAHD_RSTCTRL &= 0xFFFFFFFB;\r
161 \r
162     /* Ensure that IVAHD and SL2 are enabled */\r
163     while (CM_IVAHD_CLKCTRL & 0x00030000);\r
164     while (CM_IVAHD_SL2_CLKCTRL & 0x00030000);\r
165 \r
166     return TRUE;\r
167 }\r
168 \r
169 static int ivahd_use_cnt = 0;\r
170 \r
171 static inline void set_ivahd_opp(int opp)\r
172 {\r
173     unsigned int val;\r
174 \r
175     switch (opp) {\r
176         case 0:    val = 0x010e;  break;\r
177         case 50:   val = 0x000e;  break;\r
178         case 100:  val = 0x0007;  break;\r
179         default: ERROR("invalid opp"); return;\r
180     }\r
181 \r
182     DEBUG("CM_DIV_M5_DPLL_IVA=%08x", CM_DIV_M5_DPLL_IVA);\r
183     /* set HSDIVDER_CLKOUT2_DIV */\r
184     CM_DIV_M5_DPLL_IVA = (CM_DIV_M5_DPLL_IVA & ~0x0000011f) | val;\r
185     DEBUG("CM_DIV_M5_DPLL_IVA=%08x", CM_DIV_M5_DPLL_IVA);\r
186 }\r
187 \r
188 void ivahd_acquire(void)\r
189 {\r
190     UInt hwiKey = Hwi_disable();\r
191     if (++ivahd_use_cnt == 1) {\r
192         DEBUG("ivahd acquire");\r
193         set_ivahd_opp(100);\r
194     } else {\r
195         DEBUG("ivahd already acquired");\r
196     }\r
197     Hwi_restore(hwiKey);\r
198 }\r
199 \r
200 void ivahd_release(void)\r
201 {\r
202     UInt hwiKey = Hwi_disable();\r
203     if (ivahd_use_cnt-- == 1) {\r
204         DEBUG("ivahd release");\r
205         set_ivahd_opp(0);\r
206     } else {\r
207         DEBUG("ivahd still in use");\r
208     }\r
209     Hwi_restore(hwiKey);\r
210 }\r
211 \r
212 #define REG32(A)   (*(volatile UInt32 *) (A))\r
213 \r
214 void platform_idle_processing()\r
215 {\r
216     /* wrapper slpm_idle_processing to ensure all necessary wakeup events\r
217      * are enabled
218      */\r
219     REG32(WUGEN_MEVT0) |= (WUGEN_IVAHD_MAILBOX_IRQ_2 | WUGEN_IVAHD_IRQ2 | WUGEN_IVAHD_IRQ1);\r
220     slpm_idle_processing();\r
221 }\r
222 \r
223 \r
224 void platform_init()\r
225 {\r
226         Int status = 0;\r
227         UInt16 hostId = 0, sysProcId = 0;\r
228 \r
229     /* clear HSDIVDER_CLKOUT2_DIV */\r
230     set_ivahd_opp(0);\r
231 \r
232         /* Set up interprocessor notifications */\r
233         DEBUG("Setting up IPC");\r
234         status = Ipc_start();\r
235         if (status < 0) {\r
236             ERROR("Ipc_start failed: %08x", status);\r
237             return;\r
238         }\r
239 \r
240         /* attach to host */\r
241         hostId = MultiProc_getId("MPU");\r
242         DEBUG("APPM3: IPC attaching to MPU, hostId = %d", hostId);\r
243         do {\r
244             status = Ipc_attach(hostId);\r
245             DEBUG("APPM3: IPC attaching... %08x", status);\r
246         } while (status < 0);\r
247 \r
248         /* attach to other M3.. do we need this? */\r
249         sysProcId = MultiProc_getId("SysM3");\r
250         DEBUG("APPM3: IPC attaching to SysM3, sysProcId = %d", sysProcId);\r
251 \r
252         do {\r
253             status = Ipc_attach(sysProcId);\r
254             DEBUG("APPM3: IPC attaching... %08x", status);\r
255         } while (status < 0);\r
256 \r
257         /* maybe above stuff should move into dce_init().. */\r
258         dce_init();\r
259         DEBUG("APPM3: Completed IPC setup and Server Bringup");\r
260 \r
261     return;\r
262 }\r
263 \r
264 \r
265 void platform_deinit()\r
266 {\r
267     DEBUG("APPM3: Shutdown");\r
268         dce_deinit();\r
269 }\r
270 \r
271 \r
272 \r
273 unsigned int ducatiSysClock;\r
274 \r
275 extern Void init_IVAHDFrwk();\r
276 extern Void exit_IVAHDFrwk();\r
277 \r
278 Void Ducati_AppTask (UArg arg1, UArg arg2)\r
279 {\r
280         FCSettings_init();\r
281         Diags_setMask(FCSETTINGS_MODNAME"+12345678LEXAIZFS");\r
282         CESettings_init();\r
283         Diags_setMask(CESETTINGS_MODNAME"+12345678LEXAIZFS");\r
284 //      Diags_setMask("ti.sdo.rcm.RcmServer-12");\r
285 //      Diags_setMask("ti.sysbios.utils.Load-4");\r
286 \r
287     init_IVAHDFrwk();\r
288     HDVICP_Reset(NULL, NULL);\r
289     platform_init();\r
290 \r
291     /* how do we know when to unload.. */\r
292     while (1) {\r
293         Task_sleep(0x7fffffff);\r
294     }\r
295 \r
296     /*The test cases will run in this task's context in the init call.\r
297     Once init returns, testcases have exited so do deinit*/\r
298     platform_deinit();\r
299 \r
300     exit_IVAHDFrwk();\r
301 \r
302     System_exit(0);\r
303 }\r
304 \r
305 /*\r
306  * ===  FUNCTION  ======================================================================\r
307  *         Name:  main\r
308  *  Description:  Main entry for Ducati subsystem\r
309  * =====================================================================================\r
310  */\r
311 \r
312 \r
313 int main(void)\r
314 {\r
315 #if defined(DUCATI_APP_M3)\r
316     /* Hack to enable CMT for APP M3 */\r
317     if ((CTM_ctm.CTGNBL[0] && 0x14) != 0x14) {\r
318         CTM_ctm.CTCNTL |= 1;    /* enable the CTM */\r
319 \r
320         CTM_ctm.CTCR[2] = 0x4;  /* enable Chain mode, count cycles */\r
321         CTM_ctm.CTCR[3] = 0x4;  /* enable Chain mode, count cycles */\r
322         CTM_ctm.CTCR[4] = 0x4;  /* enable Chain mode, count cycles */\r
323         CTM_ctm.CTCR[5] = 0x4;  /* enable Chain mode, count cycles */\r
324 \r
325         CTM_ctm.CTGRST[0] |= 0x3c; /* reset counters 2,3,4,5 syncronously */\r
326         CTM_ctm.CTGNBL[0] |= 0x14; /* enable counters 2,4 syncronously */\r
327     }\r
328 #endif\r
329 \r
330     BIOS_start();\r
331 }\r
332 \r