1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - dsp
3 File: dsp_graphics.c
4
5 Copyright 2008 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Date:: 2009-03-02#$
14 $Rev: 10122 $
15 $Author: kitase_hirotake $
16 *---------------------------------------------------------------------------*/
17 #include <twl.h>
18 #include <twl/dsp.h>
19 #include <twl/dsp/common/graphics.h>
20
21 #include "dsp_process.h"
22
23 extern const u8 DSPiFirmware_graphics[];
24
25 /*---------------------------------------------------------------------------*/
26 /* Variables */
27
28 static DSPPipe binOut[1];
29 static BOOL DSPiGraphicsAvailable = FALSE;
30 static DSPProcessContext DSPiProcessGraphics[1];
31
32 static u16 replyReg;
33
34 /*---------------------------------------------------------------------------*/
35 /* Functions */
36
37 /*---------------------------------------------------------------------------*
38 Name: DSPi_OpenStaticComponentGraphicsCore
39
40 Description: Opens the memory file for the graphics component.
41 It is no longer necessary to prepare a file system in advance. Because it is linked as static memory, the program size increases.
42
43
44 Arguments: file: FSFile structure that opens the memory file
45
46 Returns: None.
47 *---------------------------------------------------------------------------*/
DSPi_OpenStaticComponentGraphicsCore(FSFile * file)48 void DSPi_OpenStaticComponentGraphicsCore(FSFile *file)
49 {
50 extern const u8 DSPiFirmware_graphics[];
51 (void)DSPi_CreateMemoryFile(file, DSPiFirmware_graphics);
52 }
53
54 /*---------------------------------------------------------------------------*
55 Name: DSPi_GraphicsEvents(viod *userdata)
56
57 Description: Event handler of the DSP graphics component.
58
59 Arguments: None.
60
61 Returns: None.
62 *---------------------------------------------------------------------------*/
DSPi_GraphicsEvents(void * userdata)63 static void DSPi_GraphicsEvents(void *userdata)
64 {
65 (void)userdata;
66
67 // When running asynchronous processing, check the presence of end notices
68 if ( isAsync )
69 {
70 replyReg = DSP_RecvData(DSP_GRAPHICS_REP_REGISTER);
71 if (replyReg == DSP_STATE_SUCCESS)
72 {
73 isBusy = FALSE;
74 isAsync = FALSE;
75
76 if ( callBackFunc != NULL)
77 {
78 callBackFunc();
79 }
80 }
81 else if (replyReg == DSP_STATE_FAIL)
82 {
83 OS_Warning("a process on DSP is failed.\n");
84 isBusy = FALSE;
85 isAsync = FALSE;
86 }
87 else
88 {
89 OS_Warning("unknown error occured.\n");
90 isBusy = FALSE;
91 isAsync = FALSE;
92 }
93 }
94 else // Synchronous version
95 {
96 // replyReg = DSP_RecvData(DSP_GRAPHICS_REP_REGISTER);
97 // isBusy = FALSE;
98 }
99 }
100
101 /*---------------------------------------------------------------------------*
102 Name: DSP_LoadGraphicsCore
103
104 Description: Loads graphics component to DSP.
105
106 Arguments: file: Graphics component file
107 slotB: WRAM-B allowed for use for code memory
108 slotC: WRAM-C allowed for use for data memory
109
110 Returns: TRUE if the graphics component is correctly loaded to DSP.
111 *---------------------------------------------------------------------------*/
DSPi_LoadGraphicsCore(FSFile * file,int slotB,int slotC)112 BOOL DSPi_LoadGraphicsCore(FSFile *file, int slotB, int slotC)
113 {
114 if (!DSPiGraphicsAvailable)
115 {
116 isBusy = FALSE;
117 isAsync = FALSE;
118 DSP_InitProcessContext(DSPiProcessGraphics, "graphics");
119 // (If there is specification to a linker script file on the DSP side, this explicit setting is unnecessary)
120 DSPiProcessGraphics->flags |= DSP_PROCESS_FLAG_USING_OS;
121 DSP_SetProcessHook(DSPiProcessGraphics,
122 DSP_HOOK_REPLY_(DSP_GRAPHICS_REP_REGISTER),
123 DSPi_GraphicsEvents, NULL);
124 if (DSP_ExecuteProcess(DSPiProcessGraphics, file, slotB, slotC))
125 {
126 DSPiGraphicsAvailable = TRUE;
127 }
128
129 (void)DSP_LoadPipe(binOut, DSP_PIPE_BINARY, DSP_PIPE_OUTPUT);
130 }
131
132 return DSPiGraphicsAvailable;
133 }
134
135 /*---------------------------------------------------------------------------*
136 Name: DSP_UnloadGraphicsCore
137
138 Description: Ends the DSP graphics component.
139
140 Arguments: None.
141
142 Returns: None.
143 *---------------------------------------------------------------------------*/
DSPi_UnloadGraphicsCore(void)144 void DSPi_UnloadGraphicsCore(void)
145 {
146 if(DSPiGraphicsAvailable)
147 {
148 DSP_QuitProcess(DSPiProcessGraphics);
149 DSPiGraphicsAvailable = FALSE;
150 }
151 }
152
153 /*---------------------------------------------------------------------------*
154 Name: DSPi_YuvToRgbConvertCore
155
156 Description: Converts YUV to RGB.
157
158 Arguments: src: Processing origin data address
159 dest: Address for storing data (destination) after processing
160 size: src data size
161 callback: Pointer for callback function run after conversion ends
162 async: TRUE when running asynchronously
163
164 Returns: TRUE if successful.
165 *---------------------------------------------------------------------------*/
DSPi_ConvertYuvToRgbCore(const void * src,void * dst,u32 size,DSP_GraphicsCallback callback,BOOL async)166 BOOL DSPi_ConvertYuvToRgbCore(const void* src, void* dst, u32 size, DSP_GraphicsCallback callback, BOOL async)
167 {
168 DSPYuv2RgbParam yr_param;
169 u32 offset = 0;
170 u16 command;
171
172 // Check one more time whether DSP is busy
173 if (isBusy)
174 {
175 OS_TPrintf("dsp is busy.\n");
176 return FALSE;
177 }
178 isBusy = TRUE;
179
180 // Register the callback function
181 callBackFunc = callback;
182 isAsync = async;
183
184 if (async)
185 {
186 DSP_SetProcessHook(DSPiProcessGraphics,
187 DSP_HOOK_REPLY_(DSP_GRAPHICS_REP_REGISTER),
188 DSPi_GraphicsEvents, NULL);
189 }
190 else
191 {
192 DSP_SetProcessHook(DSPiProcessGraphics,
193 DSP_HOOK_REPLY_(DSP_GRAPHICS_REP_REGISTER),
194 NULL, NULL);
195 }
196
197 // Notify the content of processes to start to DSP
198 command = DSP_G_FUNCID_YUV2RGB;
199 DSP_SendData(DSP_GRAPHICS_COM_REGISTER, command);
200
201 // Parameter transmission to DSP
202 yr_param.size = size;
203 yr_param.src = (u32)((u32)src + offset);
204 yr_param.dst = (u32)((u32)dst + offset);
205
206 DSP_WritePipe(binOut, &yr_param, sizeof(DSPYuv2RgbParam));
207
208 if (async)
209 {
210 return TRUE;
211 }
212 else
213 {
214 // Wait for a reply from the DSP
215 while (!DSP_RecvDataIsReady(DSP_GRAPHICS_REP_REGISTER)) {
216 OS_Sleep(1);
217 }
218 replyReg = DSP_RecvData(DSP_GRAPHICS_REP_REGISTER);
219 isBusy = FALSE;
220
221 if ( replyReg == DSP_STATE_SUCCESS)
222 {
223 return TRUE;
224 }
225 else
226 {
227 return FALSE;
228 }
229 }
230
231 return FALSE;
232 }
233
234 /*---------------------------------------------------------------------------*
235 Name: DSPi_ScalingCore
236
237 Description: Scales the image data.
238
239 Returns: TRUE if successful.
240 *---------------------------------------------------------------------------*/
DSPi_ScalingCore(const void * src,void * dst,u16 img_width,u16 img_height,f32 rx,f32 ry,DSPGraphicsScalingMode mode,u16 x,u16 y,u16 width,u16 height,DSP_GraphicsCallback callback,BOOL async)241 BOOL DSPi_ScalingCore(const void* src, void* dst, u16 img_width, u16 img_height, f32 rx, f32 ry, DSPGraphicsScalingMode mode,
242 u16 x, u16 y, u16 width, u16 height, DSP_GraphicsCallback callback, BOOL async)
243 {
244 DSPScalingParam sc_param;
245
246 u16 command;
247
248 // Check one more time whether DSP is busy
249 if (isBusy)
250 {
251 OS_TPrintf("dsp is busy.\n");
252 return FALSE;
253 }
254 isBusy = TRUE;
255
256 // Register the callback function
257 callBackFunc = callback;
258 isAsync = async;
259 if (async)
260 {
261 DSP_SetProcessHook(DSPiProcessGraphics,
262 DSP_HOOK_REPLY_(DSP_GRAPHICS_REP_REGISTER),
263 DSPi_GraphicsEvents, NULL);
264 }
265 else
266 {
267 DSP_SetProcessHook(DSPiProcessGraphics,
268 DSP_HOOK_REPLY_(DSP_GRAPHICS_REP_REGISTER),
269 NULL, NULL);
270 }
271
272 // Notify the content of processes to start to DSP
273 command = DSP_G_FUNCID_SCALING;
274 DSP_SendData(DSP_GRAPHICS_COM_REGISTER, command);
275
276 // Transfer parameters to DSP
277 sc_param.src = (u32)src;
278 sc_param.dst = (u32)dst;
279 sc_param.mode = mode;
280 sc_param.img_width = img_width;
281 sc_param.img_height = img_height;
282 sc_param.rate_w = (u16)(rx * 1000);
283 sc_param.rate_h = (u16)(ry * 1000);
284 sc_param.block_x = x;
285 sc_param.block_y = y;
286 sc_param.width = width;
287 sc_param.height = height;
288
289 DSP_WritePipe(binOut, &sc_param, sizeof(DSPScalingParam));
290
291 // Branch if running asynchronously
292 if(isAsync)
293 {
294 return TRUE;
295 }
296 else
297 {
298 // Wait for a reply from the DSP
299 while (!DSP_RecvDataIsReady(DSP_GRAPHICS_REP_REGISTER)) {
300 OS_Sleep(1);
301 }
302
303 replyReg = DSP_RecvData(DSP_GRAPHICS_REP_REGISTER);
304 isBusy = FALSE;
305
306 if ( replyReg == DSP_STATE_SUCCESS )
307 {
308 return TRUE;
309 }
310 else
311 {
312 return FALSE;
313 }
314 }
315
316 return FALSE;
317 }
318
DSPi_ScalingFxCore(const void * src,void * dst,u16 img_width,u16 img_height,fx32 rx,fx32 ry,DSPGraphicsScalingMode mode,u16 x,u16 y,u16 width,u16 height,DSP_GraphicsCallback callback,BOOL async)319 BOOL DSPi_ScalingFxCore(const void* src, void* dst, u16 img_width, u16 img_height, fx32 rx, fx32 ry, DSPGraphicsScalingMode mode,
320 u16 x, u16 y, u16 width, u16 height, DSP_GraphicsCallback callback, BOOL async)
321 {
322 DSPScalingParam sc_param;
323
324 u16 command;
325
326 // Check one more time whether DSP is busy
327 if (isBusy)
328 {
329 OS_TPrintf("dsp is busy.\n");
330 return FALSE;
331 }
332 isBusy = TRUE;
333
334 // Register the callback function
335 callBackFunc = callback;
336 isAsync = async;
337
338 if (async)
339 {
340 DSP_SetProcessHook(DSPiProcessGraphics,
341 DSP_HOOK_REPLY_(DSP_GRAPHICS_REP_REGISTER),
342 DSPi_GraphicsEvents, NULL);
343 }
344 else
345 {
346 DSP_SetProcessHook(DSPiProcessGraphics,
347 DSP_HOOK_REPLY_(DSP_GRAPHICS_REP_REGISTER),
348 NULL, NULL);
349 }
350
351 // Notify the content of processes to start to DSP
352 command = DSP_G_FUNCID_SCALING;
353 DSP_SendData(DSP_GRAPHICS_COM_REGISTER, command);
354
355 // Transfer parameters to DSP
356 sc_param.src = (u32)src;
357 sc_param.dst = (u32)dst;
358 sc_param.mode = mode;
359 sc_param.img_width = img_width;
360 sc_param.img_height = img_height;
361 sc_param.rate_w = (u16)(rx / 4096.0f * 1000);
362 sc_param.rate_h = (u16)(ry / 4096.0f * 1000);
363 sc_param.block_x = x;
364 sc_param.block_y = y;
365 sc_param.width = width;
366 sc_param.height = height;
367
368 DSP_WritePipe(binOut, &sc_param, sizeof(DSPScalingParam));
369
370 // Branch if running asynchronously
371 if(isAsync)
372 {
373 return TRUE;
374 }
375 else
376 {
377 // Wait for a reply from the DSP
378 while (!DSP_RecvDataIsReady(DSP_GRAPHICS_REP_REGISTER)) {
379 OS_Sleep(1);
380 }
381 replyReg = DSP_RecvData(DSP_GRAPHICS_REP_REGISTER);
382 isBusy = FALSE;
383
384 if ( replyReg == DSP_STATE_SUCCESS )
385 {
386 return TRUE;
387 }
388 else
389 {
390 return FALSE;
391 }
392 }
393
394 return FALSE;
395 }
396
397