Move DEBUG outside Hwi
[ivimm/ipumm.git] / src / ti / framework / dce / ivahd.c
1 /*
2  * Copyright (c) 2010, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
34 #include <xdc/std.h>
35 #include <xdc/runtime/System.h>
36 #include <xdc/runtime/Memory.h>
37 #include <xdc/runtime/IHeap.h>
38 #include <xdc/runtime/Error.h>
39 #include <ti/sysbios/knl/Clock.h>
40 #include <ti/sysbios/knl/Task.h>
41 #include <ti/sysbios/hal/Hwi.h>
42 #include <ti/pm/IpcPower.h>
43 #include <ti/sdo/ce/Engine.h>
44 #include <ti/sdo/ce/CERuntime.h>
45 #include <xdc/cfg/global.h>
47 #include "dce_priv.h"
49 #include <ti/xdais/ires.h>
50 #include <ti/sdo/fc/ires/hdvicp/iresman_hdvicp.h>
51 #include <ti/sdo/fc/ires/hdvicp/ires_hdvicp2.h>
52 #include <ti/sdo/fc/ires/tiledmemory/iresman_tiledmemory.h>
53 #include <ti/sdo/fc/rman/rman.h>
54 #include <ti/sdo/fc/ires/hdvicp/hdvicp2.h>
55 #include <ti/sdo/fc/ires/hdvicp/hdvicp2.h>
57 //#define MEMORYSTATS_DEBUG
59 static uint32_t    ivahd_base = 0;
61 static uint32_t get_ivahd_base(void)
62 {
63     if( !ivahd_base ) {
64         ERROR("Chipset ID not set!");
66         while( TRUE ) {
67             asm (" wfi");
68         }
69     }
70     return (ivahd_base);
71 }
73 #define IVAHD_REG(off)            (*(volatile unsigned int *)(get_ivahd_base() + (off)))
75 #define PM_IVAHD_PWRSTCTRL        IVAHD_REG(0x00)
76 #define RM_IVAHD_RSTCTRL          IVAHD_REG(0x10)
77 #define RM_IVAHD_RSTST            IVAHD_REG(0x14)
79 #if (defined OMAP5430_ES10)
80  #define CM_IVAHD_CLKSTCTRL        (*(volatile unsigned int *)0xAA008F00)
81  #define CM_IVAHD_CLKCTRL          (*(volatile unsigned int *)0xAA008F20)
82  #define CM_IVAHD_SL2_CLKCTRL      (*(volatile unsigned int *)0xAA008F28)
83  #define CM_DIV_DPLL_IVA           (*(volatile unsigned int *)0xAA0041BC)
84  #define IVAHD_CONFIG_REG_BASE     (0xBA000000)
85 #elif (defined VAYU_ES10)
86  #define CM_IVAHD_CLKSTCTRL        (*(volatile unsigned int *)0x6A008F00)
87  #define CM_IVAHD_CLKCTRL          (*(volatile unsigned int *)0x6A008F20)
88  #define CM_IVAHD_SL2_CLKCTRL      (*(volatile unsigned int *)0x6A008F28)
89  #define CM_DIV_DPLL_IVA           (*(volatile unsigned int *)0x6A0051B0)
90  #define IVAHD_CONFIG_REG_BASE     (0x7A000000)
91 #elif (defined OMAP5432_ES20)
92  #define CM_IVAHD_CLKSTCTRL        (*(volatile unsigned int *)0xAA009200)
93  #define CM_IVAHD_CLKCTRL          (*(volatile unsigned int *)0xAA009220)
94  #define CM_IVAHD_SL2_CLKCTRL      (*(volatile unsigned int *)0xAA009228)
95  #define CM_DIV_DPLL_IVA           (*(volatile unsigned int *)0xAA0041BC)
96  #define IVAHD_CONFIG_REG_BASE     (0xBA000000)
97 #endif //OMAP5_ES10
99 #define ICONT1_ITCM_BASE          (IVAHD_CONFIG_REG_BASE + 0x08000)
100 #define ICONT2_ITCM_BASE          (IVAHD_CONFIG_REG_BASE + 0x18000)
103 /*******************************************************************************
104  *   Hex code to set for Stack setting, Interrupt vector setting
105  *   and instruction to put ICONT in WFI mode.
106  *   This shall be placed at TCM_BASE_ADDRESS of given IVAHD, which is
107  *   0x0000 locally after reset.
108  *******************************************************************************/
110 const unsigned int    icont_boot[] =
112     0xEA000006,
113     0xEAFFFFFE,
114     0xEAFFFFFE,
115     0xEAFFFFFE,
116     0xEAFFFFFE,
117     0xEAFFFFFE,
118     0xEAFFFFFE,
119     0xEAFFFFFE,
120     0xE3A00000,
121     0xEE070F9A,
122     0xEE070F90,
123     0xE3A00000,
124     0xEAFFFFFE,
125     0xEAFFFFF1
126 };
128 #if 0
129 static inline void sleepms(int ms)
131     Task_sleep(((ms * 1000 + (Clock_tickPeriod - 1)) / Clock_tickPeriod));
133 #endif
135 void ivahd_boot(void)
137     int                      i;
138     volatile unsigned int   *icont1_itcm_base_addr =
139         (unsigned int *)ICONT1_ITCM_BASE;
140     volatile unsigned int   *icont2_itcm_base_addr =
141         (unsigned int *)ICONT2_ITCM_BASE;
143     /*
144      * Reset IVA HD, SL2 and ICONTs
145      */
147     DEBUG("Booting IVAHD...");
150     /* Sequence - J6 system address
151      * Apply Reset on IVA-HD (0x4AE06F10 = 0x7)
152      * Turn IVA power state to on (0x4AE06F00 = 0x3)
153      * Set CM to SW WKUP (0x4A008F00 = 0x2)
154      * Set IVA CLK to Auto (0x4A008F20 = 0x1)
155      * Set SL2 CLK to Auto (0x4A008F28 = 0x1)
156      * Apply reset to ICONT1 and ICONT2 and remove SL2 reset (0x4AE06F10 = 0x3)
157      * Code load ICONTs
158      * Release Reset for ICONT1 and ICONT2 (0x4AE06F10 = 0x0)
159     */
161     /* RESET RST_LOGIC, RST_SEQ2, and RST_SEQ1*/
162     RM_IVAHD_RSTCTRL = 0x00000007;
163     while(! (RM_IVAHD_RSTCTRL & 0x00000007) ) {
164         ;
165     }
167     /*POWERSTATE : IVAHD_PRM:PM_IVAHD_PWRSTCTRL to ON state*/
168     PM_IVAHD_PWRSTCTRL = 0x00000003;
169     while(! (PM_IVAHD_PWRSTCTRL & 0x00000003) ) {
170         ;
171     }
173     /*IVAHD_CM2:CM_IVAHD_CLKSTCTRL = SW_WKUP*/
174     CM_IVAHD_CLKSTCTRL = 0x00000002;
175     while(! (CM_IVAHD_CLKSTCTRL & 0x00000002) ) {
176         ;
177     }
179     /*IVAHD_CM2:CM_IVAHD_IVAHD_CLKCTRL - IVA managed by HW*/
180     CM_IVAHD_CLKCTRL = 0x00000001;
181     while(! (CM_IVAHD_CLKCTRL & 0x00000001) ) {
182         ;
183     }
185     /*IVAHD_CM2:CM_IVAHD_SL2_CLKCTRL - SL2 managed by HW*/
186     CM_IVAHD_SL2_CLKCTRL = 0x00000001;
187     while(! (CM_IVAHD_SL2_CLKCTRL & 0x00000001) ) {
188         ;
189     }
191     /* put ICONT1 & ICONT2 in reset and clear IVA logic and SL2 reset */
192     DEBUG("Putting [ICONTI ICONT2]: RESET and SL2:OutOfRESET...");
193     RM_IVAHD_RSTCTRL = 0x00000003;
194     while(! (RM_IVAHD_RSTCTRL & 0x00000003) ) {
195         ;
196     }
198     /* Check IVA Clock IDLEST to be functional and STBYST to be standby */
199     while( (CM_IVAHD_CLKCTRL & 0x00030001) != 0x00001 ) {
200         DEBUG("ivahd_boot waiting for IVA Clock IDLEST to functional and STBYST CM_IVAHD_CLKCTRL 0x%x", CM_IVAHD_CLKCTRL);
201     }
203     /* Check SL2 Clock IDLEST to be functional */
204     while( (CM_IVAHD_SL2_CLKCTRL & 0x00030001) != 0x00001 ) {
205         DEBUG("ivahd_boot waiting for SL2 Clock IDLEST to functional\n");
206     }
208     /* Copy boot code to ICONT1 & ICONT2 memory - Initialized the TCM memory */
209     for( i = 0; i < DIM(icont_boot); i++ ) {
210         *icont1_itcm_base_addr++ = icont_boot[i];
211         *icont2_itcm_base_addr++ = icont_boot[i];
212     }
214     /* Release Reset - clear SEQ2 and SEQ1 */
215     RM_IVAHD_RSTCTRL = 0x00000000;
216     while( RM_IVAHD_RSTCTRL != 0x00000000 ) {
217         ;
218     }
220     /*Read CM IVAHD CLOCK STATE CONTROL is running or gating/ungating transition is on-going*/
221     DEBUG("Waiting for IVAHD to go out of reset\n");
223     while(((CM_IVAHD_CLKSTCTRL) & 0x100) & ~0x100 ) {
224         ;
225     }
227     DEBUG("ivahd_boot() CM_IVAHD_CLKCTRL 0x%x CM_IVAHD_CLKSTCTRL 0x%x", CM_IVAHD_CLKCTRL, CM_IVAHD_CLKSTCTRL);
230 int ivahd_reset(void *handle, void *iresHandle)
232     /*
233      * Reset IVA HD, SL2 and ICONTs
234      */
236     DEBUG("Resetting IVAHD START CM_IVAHD_CLKCTRL 0x%x CM_IVAHD_CLKSTCTRL 0x%x", CM_IVAHD_CLKCTRL, CM_IVAHD_CLKSTCTRL);
239     /* First put IVA into HW Auto mode */
240     CM_IVAHD_CLKSTCTRL |= 0x00000003;
242     /* Wait for IVA HD to standby */
243     while( !((CM_IVAHD_CLKCTRL) & 0x00040000)) {
244         ;
245     }
247     /* Disable IVAHD and SL2 modules */
248     CM_IVAHD_CLKCTRL = 0x00000000;
249     CM_IVAHD_SL2_CLKCTRL = 0x00000000;
251     /* Ensure that IVAHD and SL2 are enabled */
252     while( !(CM_IVAHD_CLKCTRL & 0x00030000)) {
253         ;
254     }
256     while( !(CM_IVAHD_SL2_CLKCTRL & 0x00030000)) {
257         ;
258     }
260     /* Precondition - TRM DRA7xx Sec. 3.5.6.5 IVA Subsystem Software Warm Reset Sequence
261      * 1. IVA Sequencer CPUS are in IDLE state: CM_IVAHD_CLKCTRL[17:16] IDLEST - has a value 0x2.
262      * 2. IVA subsystem is in STANDBY state: CM_IVAHD_CLKCTRL[18] STBYST - has a value of 0x1.
263      */
264     while( !(CM_IVAHD_CLKCTRL & 0x00060000) ) {
265         ;
266     }
268     /* 3. The functional clock to the IVA subsystem has been gated by the PRCM module
269      * CM_IVA_CLKSTCTRL[8] - has a value of 0x0
270      */
271     while( CM_IVAHD_CLKSTCTRL & 0x100) {
272         ;
273     }
275     /* Reset IVAHD sequencers and SL2 */
276     RM_IVAHD_RSTCTRL |= 0x00000007;
278     /*
279      * Check if modules are reset
280      */
282     /* First clear the status bits */
283     RM_IVAHD_RSTST |= 0x00000007;
285     /* Wait for confirmation that the systems have been reset */
286     /* THIS CHECK MAY NOT BE NECESSARY, AND MOST OF ALL GIVEN OUR STATE,
287      * MAY NOT BE POSSIBLE
288      */
290     /* Ensure that the wake up mode is set to SW_WAKEUP */
291     CM_IVAHD_CLKSTCTRL &= 0x00000002;
293     /* Enable IVAHD and SL2 modules */
294     CM_IVAHD_CLKCTRL = 0x00000001;
295     CM_IVAHD_SL2_CLKCTRL = 0x00000001;
297     /* Deassert the SL2 reset */
298     RM_IVAHD_RSTCTRL &= 0xFFFFFFFB;
300     /* Ensure that IVAHD and SL2 are enabled */
301     while( CM_IVAHD_CLKCTRL & 0x00030000 ) {
302         ;
303     }
305     while( CM_IVAHD_SL2_CLKCTRL & 0x00030000 ) {
306         ;
307     }
309     DEBUG("Resetting IVAHD COMPLETED");
310     return (TRUE);
313 void crash_reset() {
314     ERROR("Received crash_reset");
316     IRES_Status ret;
318     /* RMAN_unregister IRESMAN_TILEDMEMORY */
319     ret = RMAN_unregister(&IRESMAN_TILEDMEMORY);
320     if( ret != IRES_OK ) {
321         ERROR("RMAN_unregister on IRESMAN_TILEDMEMORY fail with ret %d", ret);
322     }
324     /* RMAN_unregister IRESMAN_HDVICP */
325     ret = RMAN_unregister(&IRESMAN_HDVICP);
326     if( ret != IRES_OK ) {
327         ERROR("RMAN_unregister on IRESMAN_HDVICP fail with ret %d", ret);
328     }
330     /* RMAN_exit */
331     ret = RMAN_exit();
332     if( ret != IRES_OK ) {
333         ERROR("RMAN_exit fail with ret %d", ret);
334     }
336     CERuntime_exit();
338     ERROR("crash_reset() CM_IVAHD_CLKCTRL 0x%x CM_IVAHD_CLKSTCTRL 0x%x", CM_IVAHD_CLKCTRL, CM_IVAHD_CLKSTCTRL);
340     if( CM_IVAHD_CLKSTCTRL & 0x100 ) {
341         ERROR("crash_report detects IVA_GCLK is running or gate transition on-going");
342     }
344     /* RESET RST_LOGIC, RST_SEQ2, and RST_SEQ1 before crashing */
345     RM_IVAHD_RSTCTRL = 0x00000007;
347     ERROR("crash_reset() RM_IVAHD_RSTCTRL 0x%x - calling abort NOW", RM_IVAHD_RSTCTRL);
348     abort();
352 static int    ivahd_use_cnt = 0;
354 #ifdef ENABLE_DEAD_CODE
355 static inline void set_ivahd_opp(int opp)
357     unsigned int    val;
359     switch( opp ) {
360         case 0 :
361             val = 0x010e;
362             break;
363         case 50 :
364             val = 0x000e;
365             break;
366         case 100 :
367             val = ivahd_m5div;
368             break;
369         default :
370             ERROR("invalid opp");
371             return;
372     }
374     DEBUG("CM_DIV_DPLL_IVA=%08x", CM_DIV_DPLL_IVA);
375     /* set HSDIVDER_CLKOUT2_DIV */
376     CM_DIV_DPLL_IVA = (CM_DIV_DPLL_IVA & ~0x0000011f) | val;
377     DEBUG("CM_DIV_DPLL_IVA=%08x", CM_DIV_DPLL_IVA);
380 #endif //ENABLE_DEAD_CODE
381 void ivahd_acquire(void)
383     if( ++ivahd_use_cnt == 1 ) {
384         DEBUG("ivahd acquire");
385         UInt hwiKey = Hwi_disable();
386         /* switch SW_WAKEUP mode */
387         CM_IVAHD_CLKSTCTRL = 0x00000002;
388         Hwi_restore(hwiKey);
389     } else {
390         DEBUG("ivahd already acquired");
391     }
394 void ivahd_release(void)
396     if( ivahd_use_cnt-- == 1 ) {
397         DEBUG("ivahd release");
398         UInt hwiKey = Hwi_disable();
399         /* switch HW_AUTO mode */
400         CM_IVAHD_CLKSTCTRL = 0x00000003;
401         Hwi_restore(hwiKey);
402     } else {
403         DEBUG("ivahd still in use");
404     }
407 /* This function is to check IVA clocks to make sure IVAHD is idle */
408 void ivahd_idle_check(void)
410     DEBUG("ivahd_idle check CM_IVAHD_CLKCTRL=0x%x CM_IVAHD_SL2_CLKCTRL=0x%x\n", CM_IVAHD_CLKCTRL, CM_IVAHD_SL2_CLKCTRL);
412     /* Ensure that IVAHD and SL2 idle */
413     while( !(CM_IVAHD_CLKCTRL & 0x00020000)) {
414         ;
415     }
417     while( !(CM_IVAHD_SL2_CLKCTRL & 0x00020000)) {
418         ;
419     }
421     DEBUG("ivahd_idle_check DONE - IVAHD and SL2 are in IDLE state\n");
424 static Bool allocFxn(IALG_MemRec *memTab, Int numRecs);
425 static void freeFxn(IALG_MemRec *memTab, Int numRecs);
427 /* ivahd_init() will be called in 2 situations :
428  * - when omapdce kernel module is loaded
429  * - when resuming from suspend
430  */
431 void ivahd_init(uint32_t chipset_id)
433     IRES_Status       ret;
434     IRESMAN_Params    rman_params =
435     {
436         .size = sizeof(IRESMAN_Params),
437         .allocFxn = allocFxn,
438         .freeFxn = freeFxn,
439     };
442     switch( chipset_id ) {
443         case 0x4430 :
444             ivahd_base = 0xAA306F00;
445             break;
446         case 0x4460 :
447         case 0x4470 :
448             ivahd_base = 0xAA306F00;
449             break;
450         case 0x5430 :
451             ivahd_base = 0xAAE06F00;
452             break;
453         case 0x5432 :
454             ivahd_base = 0xAAE07200;
455             break;
456         case 0x5436 :
457             ivahd_base = 0x6AE06F00;
458             break;
459         default :
460             ERROR("Invalid chipset-id: %x", chipset_id);
461             break;
462     }
464     DEBUG("ivahd_base=%08x", ivahd_base);
466     /* bit of a hack.. not sure if there is a better way for this: */
467     HDVICP2_PARAMS.resetControlAddress[0] = ivahd_base + 0x10;
469     ivahd_acquire();
471     CERuntime_init();
473     ret = RMAN_init();
474     if( ret != IRES_OK ) {
475         goto end;
476     }
478     /* Register HDVICP with RMAN if not already registered */
479     ret = RMAN_register(&IRESMAN_HDVICP, &rman_params);
480     if((ret != IRES_OK) && (ret != IRES_EEXISTS)) {
481         DEBUG("could not register IRESMAN_HDVICP: %d", ret);
482         goto end;
483     }
485     /* NOTE: this might try MemMgr allocations over RCM remote
486      * call back to host side.  Which will fail if we don't
487      * have memsrv.  But will eventually fall back to allocFxn
488      * which will allocate from the local heap.
489      */
490     ret = RMAN_register(&IRESMAN_TILEDMEMORY, &rman_params);
491     if((ret != IRES_OK) && (ret != IRES_EEXISTS)) {
492         DEBUG("could not register IRESMAN_TILEDMEMORY: %d", ret);
493         goto end;
494     }
497     ivahd_boot();
499     DEBUG("RMAN_register() for HDVICP is successful");
501 end:
502     ivahd_release();
503     return;
506 static Bool allocFxn(IALG_MemRec memTab[], Int n)
508     Int    i;
510 #ifdef MEMORYSTATS_DEBUG
511     Memory_Stats    stats;
512 #endif
514     for( i = 0; i < n; i++ ) {
515         Error_Block    eb;
516         Uns            pad, size;
517         void          *blk;
518         MemHeader     *hdr;
520         if( memTab[i].alignment > sizeof(MemHeader)) {
521             pad = memTab[i].alignment;
522         } else {
523             pad = sizeof(MemHeader);
524         }
526         size = memTab[i].size + pad;
528 #ifdef MEMORYSTATS_DEBUG
529         Memory_getStats(NULL, &stats);
530         INFO("Total: %d\tFree: %d\tLargest: %d", stats.totalSize,
531              stats.totalFreeSize, stats.largestFreeSize);
532 #endif
534         blk = Memory_alloc(NULL, size, memTab[i].alignment, &eb);
536         if( !blk ) {
537             ERROR("MemTab Allocation failed at %d", i);
538             freeFxn(memTab, i);
539             return (FALSE);
540         } else {
541             memTab[i].base = (void *)((char *)blk + pad);
542             hdr = P2H(memTab[i].base);
543             hdr->size = size;
544             hdr->ptr  = blk;
545             DEBUG("%d: alloc: %p/%p (%d)", i, hdr->ptr,
546                   memTab[i].base, hdr->size);
547         }
548     }
550     DEBUG("MemTab Allocation is Successful");
551     return (TRUE);
554 static void freeFxn(IALG_MemRec memTab[], Int n)
556     Int    i;
558 #ifdef MEMORYSTATS_DEBUG
559     Memory_Stats    stats;
560 #endif
562     for( i = 0; i < n; i++ ) {
563         if( memTab[i].base != NULL ) {
564             MemHeader   *hdr = P2H(memTab[i].base);
566 #ifdef MEMORYSTATS_DEBUG
567             DEBUG("%d: free: %p/%p (%d)", n, hdr->ptr,
568                   memTab[i].base, hdr->size);
569 #endif
570             Memory_free(NULL, hdr->ptr, hdr->size);
571         }
572 #ifdef MEMORYSTATS_DEBUG
573         Memory_getStats(NULL, &stats);
574         INFO("Total: %d\tFree: %d\tLargest: %d", stats.totalSize,
575              stats.totalFreeSize, stats.largestFreeSize);
576 #endif
577     }