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