Home | History | Annotate | Download | only in parser
      1 #include "fw_pvt.h"
      2 #include "viddec_fw_parser_ipclib_config.h"
      3 
      4 extern uint32_t timer;
      5 
      6 /*------------------------------------------------------------------------------
      7  * Function:  memcpy
      8  * This is a memory-copy function.
      9  *------------------------------------------------------------------------------
     10  */
     11 /* NOTE: we are inventing memcpy since we don't want to include string libs as part of FW Due to size limitations*/
     12 void *memcpy(void *dest, const void *src, uint32_t n)
     13 {
     14     uint8_t *ptr8_frm, *ptr8_to;
     15     uint32_t *ptr32_frm, *ptr32_to;
     16     uint32_t bytes_left=n,trail = 0;
     17     uint32_t align=0;
     18 
     19     ptr8_frm = (uint8_t *)src;
     20     ptr8_to = (uint8_t *)dest;
     21 
     22     trail = ((uint32_t)ptr8_frm) & 0x3;
     23     if((trail == (((uint32_t)ptr8_to) & 0x3)) && (n > 4))
     24     {
     25         /* check to see what's the offset bytes to go to a word alignment */
     26         bytes_left -= trail;
     27         while(align > 0){
     28             *ptr8_to ++ = *ptr8_frm ++;
     29             trail--;
     30         }
     31         /* check to see if rest of bytes is a multiple of 4. */
     32         trail = bytes_left & 0x3;
     33         bytes_left = (bytes_left >> 2) << 2;
     34         ptr32_to = (uint32_t *)ptr8_to;
     35         ptr32_frm = (uint32_t *)ptr8_frm;
     36         /* copy word by word */
     37         while(bytes_left > 0){
     38             *ptr32_to ++ = *ptr32_frm ++;
     39             bytes_left -= 4;
     40         }
     41         /* If there are any trailing bytes do a byte copy */
     42         ptr8_to = (uint8_t *)ptr32_to;
     43         ptr8_frm = (uint8_t *)ptr32_frm;
     44         while(trail > 0){
     45             *ptr8_to ++ = *ptr8_frm ++;
     46             trail--;
     47         }
     48     }
     49     else
     50     {/* case when src and dest addr are not on same alignment.
     51         Just do a byte copy */
     52         while(bytes_left > 0){
     53             *ptr8_to ++ = *ptr8_frm ++;
     54             bytes_left -= 1;
     55         }
     56     }
     57     return dest;
     58 }
     59 
     60 /*------------------------------------------------------------------------------
     61  * Function:  memset
     62  * This is a function to copy specificed value into memory array.
     63  *------------------------------------------------------------------------------
     64  */
     65 /* NOTE: we are inventing memset since we don't want to include string libs as part of FW Due to size limitations*/
     66 void *memset(void *s, int32_t c, uint32_t n)
     67 {
     68     uint8_t *ptr8 = (uint8_t *)s;
     69     uint32_t *ptr32, data;
     70     uint32_t mask = 0, bytes_left = n;
     71 
     72     mask = c & 0xFF;
     73     mask |= (mask << 8);
     74     mask |= (mask << 16);
     75     if(n >= 4)
     76     {
     77         uint32_t trail=0;
     78         trail = 4 - (((uint32_t)ptr8) & 0x3);
     79         if(trail < 4)
     80         {
     81             ptr32 = (uint32_t *)(((uint32_t)ptr8) & ~0x3);
     82             data = (*ptr32 >> (8*trail)) << (8*trail);
     83             data |= (mask >> (32 - (8*trail)));
     84             *ptr32 = data;
     85             bytes_left -= trail;
     86             ptr8 += trail;
     87         }
     88         ptr32 = (uint32_t *)((uint32_t)ptr8);
     89         while(bytes_left >= 4)
     90         {
     91             *ptr32 = mask;
     92             ptr32++;
     93             bytes_left -=4;
     94         }
     95         if(bytes_left > 0)
     96         {
     97             data = (*ptr32 << (8*bytes_left)) >> (8*bytes_left);
     98             data |= (mask << (32 - (8*bytes_left)));
     99             *ptr32=data;
    100         }
    101     }
    102 
    103     return s;
    104 }
    105 
    106 /*------------------------------------------------------------------------------
    107  * Function:  cp_using_dma
    108  * This is a function to copy data from local memory to/from system memory.
    109  * Params:
    110  *         [in] ddr_addr  : Word aligned ddr address.
    111  *         [in] local_addr: Word aligned local address.
    112  *         [in] size      : No of bytes to transfer.
    113  *         [in] to_ddr    : Direction of copy, if true copy to ddr else copy to local memory.
    114  *         [in] swap      : Enable or disable byte swap(endian).
    115  *         [out] return   : Actual number of bytes copied, which can be more than what was requested
    116  *                          since we can only copy words at a time.
    117  * Limitations: DMA can transfer Words only, Local addr & DDR addr should be word aligned.
    118  *------------------------------------------------------------------------------
    119  */
    120 uint32_t cp_using_dma(uint32_t ddr_addr, uint32_t local_addr, uint32_t size, char to_ddr, char swap)
    121 {
    122     uint32_t val=0, wrote = size;
    123 
    124     while((reg_read(DMA_CONTROL_STATUS) & DMA_CTRL_STATUS_BUSY) != 0)
    125     {
    126         /* wait if DMA is busy with a transcation Error condition??*/
    127     }
    128 
    129     reg_write(DMA_SYSTEM_ADDRESS, (ddr_addr & ~3) & ~GV_DDR_MEM_MASK);
    130     reg_write(DMA_LOCAL_ADDRESS, (local_addr & 0xfffc));
    131     //wrote += (ddr_addr & 0x3);
    132     wrote = (wrote+3)>>2;/* make number of bytes multiple of 4 */
    133     val=(wrote & 0xffff) << 2;
    134     reg_write(DMA_CONTROL_STATUS, DMA_CTRL_STATUS_DONE);
    135     val |= DMA_CTRL_STATUS_START;
    136 	/* If size > 64 use 128 byte burst speed */
    137     if(wrote > 64)
    138         val |= (1<<18);
    139     if(swap) /* Endian swap if needed */
    140         val |= DMA_CTRL_STATUS_SWAP;
    141     if(to_ddr)
    142         val = val | DMA_CTRL_STATUS_DIRCN;
    143     reg_write(DMA_CONTROL_STATUS, val);
    144     while((reg_read(DMA_CONTROL_STATUS) & DMA_CTRL_STATUS_DONE) == 0)
    145     {
    146 		/* wait till DMA is done */
    147     }
    148     reg_write(DMA_CONTROL_STATUS, DMA_CTRL_STATUS_DONE);
    149 
    150     return (wrote << 2);
    151 }
    152 
    153 /*------------------------------------------------------------------------------
    154  * Function:  cp_using_dma
    155  * This is a function to copy data from local memory to/from system memory.
    156  * Params:
    157  *         [in] ddr_addr  : Word aligned ddr address.
    158  *         [in] local_addr: Word aligned local address.
    159  *         [in] size      : No of bytes to transfer.
    160  *         [in] to_ddr    : Direction of copy, if true copy to ddr else copy to local memory.
    161  *         [in] swap      : Enable or disable byte swap(endian).
    162  *         [out] return   : Actual number of bytes copied, which can be more than what was requested
    163  *                          since we can only copy words at a time.
    164  * Limitations: DMA can transfer Words only, Local addr & DDR addr should be word aligned.
    165  *------------------------------------------------------------------------------
    166  */
    167 uint32_t cp_using_dma_phys(uint32_t ddr_addr, uint32_t local_addr, uint32_t size, char to_ddr, char swap)
    168 {
    169     uint32_t val=0, wrote = size;
    170 
    171     while((reg_read(DMA_CONTROL_STATUS) & DMA_CTRL_STATUS_BUSY) != 0)
    172     {
    173         /* wait if DMA is busy with a transcation Error condition??*/
    174     }
    175 
    176     reg_write(DMA_SYSTEM_ADDRESS, (ddr_addr & ~3));
    177     reg_write(DMA_LOCAL_ADDRESS, (local_addr & 0xfffc));
    178     //wrote += (ddr_addr & 0x3);
    179     wrote = (wrote+3)>>2;/* make number of bytes multiple of 4 */
    180     val=(wrote & 0xffff) << 2;
    181     reg_write(DMA_CONTROL_STATUS, DMA_CTRL_STATUS_DONE);
    182     val |= DMA_CTRL_STATUS_START;
    183 	/* If size > 64 use 128 byte burst speed */
    184     if(wrote > 64)
    185         val |= (1<<18);
    186     if(swap) /* Endian swap if needed */
    187         val |= DMA_CTRL_STATUS_SWAP;
    188     if(to_ddr)
    189         val = val | DMA_CTRL_STATUS_DIRCN;
    190     reg_write(DMA_CONTROL_STATUS, val);
    191     while((reg_read(DMA_CONTROL_STATUS) & DMA_CTRL_STATUS_DONE) == 0)
    192     {
    193 		/* wait till DMA is done */
    194     }
    195     reg_write(DMA_CONTROL_STATUS, DMA_CTRL_STATUS_DONE);
    196 
    197     return (wrote << 2);
    198 }
    199 
    200 void update_ctrl_reg(uint8_t enable, uint32_t mask)
    201 {
    202     uint32_t read_val = 0;
    203     read_val = reg_read(CONFIG_CP_CONTROL_REG);
    204     if(enable)
    205     {
    206         read_val = read_val | mask;
    207     }
    208     else
    209     {
    210         read_val = read_val & ~mask;
    211     }
    212     reg_write(CONFIG_CP_CONTROL_REG, read_val);
    213     return;
    214 
    215 }
    216 
    217 extern uint32_t sven_get_timestamp();
    218 
    219 uint32_t set_wdog(uint32_t offset)
    220 {
    221 #ifdef B0_TIMER_FIX
    222     update_ctrl_reg(0, WATCH_DOG_ENABLE);
    223     reg_write(INT_REG, INT_WDOG_ENABLE);
    224     reg_write(WATCH_DOG_COUNTER, offset & WATCH_DOG_MASK);
    225     update_ctrl_reg(1, WATCH_DOG_ENABLE);
    226     return offset & WATCH_DOG_MASK;
    227 #else
    228     return sven_get_timestamp();
    229 #endif
    230 }
    231 
    232 void get_wdog(uint32_t *value)
    233 {
    234 #ifdef B0_TIMER_FIX
    235     *value = reg_read(WATCH_DOG_COUNTER) & WATCH_DOG_MASK;
    236     reg_write(INT_REG, ~INT_WDOG_ENABLE);
    237     update_ctrl_reg(0, WATCH_DOG_ENABLE);
    238 #else
    239     *value = sven_get_timestamp();
    240 #endif
    241 }
    242 
    243 uint32_t get_total_ticks(uint32_t start, uint32_t end)
    244 {
    245     uint32_t value;
    246 #ifdef B0_TIMER_FIX
    247     value = (start-end) + (start*timer);
    248     timer=0;
    249 #else
    250     value = end-start;/* convert to 1 MHz clocks */
    251 #endif
    252     return value;
    253 }
    254