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*/
memcpy(void * dest,const void * src,uint32_t n)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*/
memset(void * s,int32_t c,uint32_t n)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  */
cp_using_dma(uint32_t ddr_addr,uint32_t local_addr,uint32_t size,char to_ddr,char swap)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  */
cp_using_dma_phys(uint32_t ddr_addr,uint32_t local_addr,uint32_t size,char to_ddr,char swap)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 
update_ctrl_reg(uint8_t enable,uint32_t mask)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 
set_wdog(uint32_t offset)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 
get_wdog(uint32_t * value)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 
get_total_ticks(uint32_t start,uint32_t end)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