Initial commit
[kernel/linux-3.0.git] / drivers / media / video / s5p-mfc / s5p_mfc_ctrl.c
1 /*
2  * linux/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
3  *
4  * Copyright (c) 2010 Samsung Electronics Co., Ltd.
5  *              http://www.samsung.com/
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  */
12
13 #include <linux/delay.h>
14 #include <linux/jiffies.h>
15
16 #include <linux/firmware.h>
17 #include <linux/err.h>
18 #include <linux/sched.h>
19 #include <linux/cma.h>
20
21 #include "s5p_mfc_common.h"
22
23 #include "s5p_mfc_mem.h"
24 #include "s5p_mfc_intr.h"
25 #include "s5p_mfc_debug.h"
26 #include "s5p_mfc_reg.h"
27 #include "s5p_mfc_cmd.h"
28 #include "s5p_mfc_pm.h"
29
30 static void *s5p_mfc_bitproc_buf;
31 static dma_addr_t s5p_mfc_bitproc_phys;
32 static unsigned char *s5p_mfc_bitproc_virt;
33 //static dma_addr_t s5p_mfc_bitproc_dma;
34
35 /* Allocate firmware */
36 int s5p_mfc_alloc_firmware(struct s5p_mfc_dev *dev)
37 {
38 #if defined(CONFIG_S5P_MFC_VB2_CMA)
39         int err;
40         struct cma_info mem_info_f, mem_info_a, mem_info_b;
41 #endif
42         unsigned int base_align = dev->variant->buf_align->mfc_base_align;
43         unsigned int firmware_size = dev->variant->buf_size->firmware_code;
44
45         mfc_debug_enter();
46
47 #if !defined(CONFIG_S5P_MFC_VB2_ION)
48         if (s5p_mfc_bitproc_buf) {
49                 mfc_err("Attempting to allocate firmware when it seems that it is already loaded.\n");
50                 return -ENOMEM;
51         }
52 #else
53         if (s5p_mfc_bitproc_buf)
54                 return 0;
55 #endif
56
57         /* Get memory region information and check if it is correct */
58 #if defined(CONFIG_S5P_MFC_VB2_CMA)
59         err = cma_info(&mem_info_f, dev->v4l2_dev.dev, MFC_CMA_FW);
60         mfc_debug(3, "Area \"%s\" is from %08x to %08x and has size %08x", "f",
61                                 mem_info_f.lower_bound, mem_info_f.upper_bound,
62                                                         mem_info_f.total_size);
63         if (err) {
64                 mfc_err("Couldn't get memory information from CMA.\n");
65                 return -EINVAL;
66         }
67         err = cma_info(&mem_info_a, dev->v4l2_dev.dev, MFC_CMA_BANK1);
68         mfc_debug(3, "Area \"%s\" is from %08x to %08x and has size %08x", "a",
69                         mem_info_a.lower_bound, mem_info_a.upper_bound,
70                                                 mem_info_a.total_size);
71         if (err) {
72                 mfc_err("Couldn't get memory information from CMA.\n");
73                 return -EINVAL;
74         }
75
76         if (mem_info_f.upper_bound > mem_info_a.lower_bound) {
77                         mfc_err("Firmware has to be "
78                         "allocated before  memory for buffers (bank A).\n");
79                 return -EINVAL;
80         }
81         mfc_debug(2, "Allocating memory for firmware.\n");
82         s5p_mfc_bitproc_buf = s5p_mfc_mem_allocate(
83                 dev->alloc_ctx[MFC_CMA_FW_ALLOC_CTX], firmware_size);
84         if (IS_ERR(s5p_mfc_bitproc_buf)) {
85                 s5p_mfc_bitproc_buf = 0;
86                 printk(KERN_ERR "Allocating bitprocessor buffer failed\n");
87                 return -ENOMEM;
88         }
89         s5p_mfc_bitproc_phys = s5p_mfc_mem_dma_addr(s5p_mfc_bitproc_buf);
90
91         if (s5p_mfc_bitproc_phys & ((1 << base_align) - 1)) {
92                 mfc_err("The base memory is not aligned to %dBytes.\n",
93                                 (1 << base_align));
94                 s5p_mfc_mem_free(s5p_mfc_bitproc_buf);
95                 s5p_mfc_bitproc_phys = 0;
96                 s5p_mfc_bitproc_buf = 0;
97                 return -EIO;
98         }
99         dev->port_a = s5p_mfc_bitproc_phys;
100
101         s5p_mfc_bitproc_virt = s5p_mfc_mem_vaddr(s5p_mfc_bitproc_buf);
102
103         mfc_debug(2, "Virtual address for FW: %08lx\n",
104                                 (long unsigned int)s5p_mfc_bitproc_virt);
105         if (!s5p_mfc_bitproc_virt) {
106                 mfc_err("Bitprocessor memory remap failed\n");
107                 s5p_mfc_mem_free(s5p_mfc_bitproc_buf);
108                 s5p_mfc_bitproc_phys = 0;
109                 s5p_mfc_bitproc_buf = 0;
110                 return -EIO;
111         }
112
113         if (HAS_PORTNUM(dev) && IS_TWOPORT(dev)) {
114                 err = cma_info(&mem_info_b, dev->v4l2_dev.dev, MFC_CMA_BANK2);
115                 mfc_debug(3, "Area \"%s\" is from %08x to %08x and has size %08x", "b",
116                                 mem_info_b.lower_bound, mem_info_b.upper_bound,
117                                 mem_info_b.total_size);
118                 if (err) {
119                         mfc_err("Couldn't get memory information from CMA.\n");
120                         return -EINVAL;
121                 }
122                 dev->port_b = mem_info_b.lower_bound;
123                 mfc_debug(2, "Port A: %08x Port B: %08x (FW: %08x size: %08x)\n",
124                                 dev->port_a, dev->port_b, s5p_mfc_bitproc_phys,
125                                                         firmware_size);
126         } else {
127                 mfc_debug(2, "Port : %08x (FW: %08x size: %08x)\n",
128                                 dev->port_a, s5p_mfc_bitproc_phys,
129                                                 firmware_size);
130         }
131 #elif defined(CONFIG_S5P_MFC_VB2_SDVMM)
132         mfc_debug(2, "Allocating memory for firmware.\n");
133         s5p_mfc_bitproc_buf = s5p_mfc_mem_alloc(
134                 dev->alloc_ctx[MFC_CMA_FW_ALLOC_CTX], firmware_size);
135         if (IS_ERR(s5p_mfc_bitproc_buf)) {
136                 s5p_mfc_bitproc_buf = 0;
137                 printk(KERN_ERR "Allocating bitprocessor buffer failed\n");
138                 return -ENOMEM;
139         }
140
141         s5p_mfc_bitproc_phys = s5p_mfc_mem_cookie(
142                 dev->alloc_ctx[MFC_CMA_FW_ALLOC_CTX], s5p_mfc_bitproc_buf);
143         if (s5p_mfc_bitproc_phys & ((1 << base_align) - 1)) {
144                 mfc_err("The base memory is not aligned to %dBytes.\n",
145                                 (1 << base_align));
146                 s5p_mfc_mem_put(dev->alloc_ctx[MFC_CMA_FW_ALLOC_CTX],
147                                                         s5p_mfc_bitproc_buf);
148                 s5p_mfc_bitproc_phys = 0;
149                 s5p_mfc_bitproc_buf = 0;
150                 return -EIO;
151         }
152
153         s5p_mfc_bitproc_virt = s5p_mfc_mem_vaddr(
154                 dev->alloc_ctx[MFC_CMA_FW_ALLOC_CTX], s5p_mfc_bitproc_buf);
155         mfc_debug(2, "Virtual address for FW: %08lx\n",
156                                 (long unsigned int)s5p_mfc_bitproc_virt);
157         if (!s5p_mfc_bitproc_virt) {
158                 mfc_err("Bitprocessor memory remap failed\n");
159                 s5p_mfc_mem_put(dev->alloc_ctx[MFC_CMA_FW_ALLOC_CTX],
160                                                         s5p_mfc_bitproc_buf);
161                 s5p_mfc_bitproc_phys = 0;
162                 s5p_mfc_bitproc_buf = 0;
163                 return -EIO;
164         }
165
166         dev->port_a = s5p_mfc_bitproc_phys;
167         dev->port_b = s5p_mfc_bitproc_phys;
168
169         mfc_debug(2, "Port A: %08x Port B: %08x (FW: %08x size: %08x)\n",
170                         dev->port_a, dev->port_b,
171                         s5p_mfc_bitproc_phys,
172                         firmware_size);
173 #elif defined(CONFIG_S5P_MFC_VB2_ION)
174         mfc_debug(2, "Allocating memory for firmware.\n");
175         s5p_mfc_bitproc_buf = s5p_mfc_mem_allocate(
176                 dev->alloc_ctx[MFC_CMA_FW_ALLOC_CTX], firmware_size);
177         if (IS_ERR(s5p_mfc_bitproc_buf)) {
178                 s5p_mfc_bitproc_buf = 0;
179                 printk(KERN_ERR "Allocating bitprocessor buffer failed\n");
180                 return -ENOMEM;
181         }
182
183         s5p_mfc_bitproc_phys = s5p_mfc_mem_dma_addr(s5p_mfc_bitproc_buf);
184         if (s5p_mfc_bitproc_phys & ((1 << base_align) - 1)) {
185                 mfc_err("The base memory is not aligned to %dBytes.\n",
186                                 (1 << base_align));
187                 s5p_mfc_mem_free(s5p_mfc_bitproc_buf);
188                 s5p_mfc_bitproc_phys = 0;
189                 s5p_mfc_bitproc_buf = 0;
190                 return -EIO;
191         }
192
193         s5p_mfc_bitproc_virt = s5p_mfc_mem_vaddr(s5p_mfc_bitproc_buf);
194         mfc_debug(2, "Virtual address for FW: %08lx\n",
195                                 (long unsigned int)s5p_mfc_bitproc_virt);
196         if (!s5p_mfc_bitproc_virt) {
197                 mfc_err("Bitprocessor memory remap failed\n");
198                 s5p_mfc_mem_free(s5p_mfc_bitproc_buf);
199                 s5p_mfc_bitproc_phys = 0;
200                 s5p_mfc_bitproc_buf = 0;
201                 return -EIO;
202         }
203
204         dev->port_a = s5p_mfc_bitproc_phys;
205         dev->port_b = s5p_mfc_bitproc_phys;
206
207         mfc_debug(2, "Port A: %08x Port B: %08x (FW: %08x size: %08x)\n",
208                         dev->port_a, dev->port_b,
209                         s5p_mfc_bitproc_phys,
210                         firmware_size);
211
212 #endif
213         mfc_debug_leave();
214
215         return 0;
216 }
217
218 /* Load firmware to MFC */
219 int s5p_mfc_load_firmware(struct s5p_mfc_dev *dev)
220 {
221         struct firmware *fw_blob;
222         unsigned int firmware_size = dev->variant->buf_size->firmware_code;
223         int err;
224
225         /* Firmare has to be present as a separate file or compiled
226          * into kernel. */
227         mfc_debug_enter();
228         mfc_debug(2, "Requesting fw\n");
229         err = request_firmware((const struct firmware **)&fw_blob,
230                                         MFC_FW_NAME, dev->v4l2_dev.dev);
231
232         if (err != 0) {
233                 mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel.\n");
234                 return -EINVAL;
235         }
236
237         mfc_debug(2, "Ret of request_firmware: %d Size: %d\n", err, fw_blob->size);
238
239         if (fw_blob->size > firmware_size) {
240                 mfc_err("MFC firmware is too big to be loaded.\n");
241                 release_firmware(fw_blob);
242                 return -ENOMEM;
243         }
244         if (s5p_mfc_bitproc_buf == 0 || s5p_mfc_bitproc_phys == 0) {
245                 mfc_err("MFC firmware is not allocated or was not mapped correctly.\n");
246                 release_firmware(fw_blob);
247                 return -EINVAL;
248         }
249         memcpy(s5p_mfc_bitproc_virt, fw_blob->data, fw_blob->size);
250         /*
251         s5p_mfc_bitproc_dma = dma_map_single(dev->v4l2_dev.dev,
252                                              s5p_mfc_bitproc_virt,
253                                              FIRMWARE_CODE_SIZE,
254                                              DMA_TO_DEVICE);
255         */
256         s5p_mfc_cache_clean_fw(s5p_mfc_bitproc_buf);
257         release_firmware(fw_blob);
258         mfc_debug_leave();
259         return 0;
260 }
261
262 /* Release firmware memory */
263 int s5p_mfc_release_firmware(struct s5p_mfc_dev *dev)
264 {
265         /* Before calling this function one has to make sure
266          * that MFC is no longer processing */
267         if (!s5p_mfc_bitproc_buf)
268                 return -EINVAL;
269         /*
270         if (s5p_mfc_bitproc_dma)
271                 dma_unmap_single(dev->v4l2_dev.dev, s5p_mfc_bitproc_dma,
272                                  FIRMWARE_CODE_SIZE, DMA_TO_DEVICE);
273         */
274         s5p_mfc_mem_free(s5p_mfc_bitproc_buf);
275
276         s5p_mfc_bitproc_virt =  0;
277         s5p_mfc_bitproc_phys = 0;
278         s5p_mfc_bitproc_buf = 0;
279         /*
280         s5p_mfc_bitproc_dma = 0;
281         */
282         return 0;
283 }
284
285 /* Reset the device */
286 static int s5p_mfc_reset(struct s5p_mfc_dev *dev)
287 {
288         int i;
289         unsigned int status;
290         unsigned long timeout;
291
292         mfc_debug_enter();
293
294         /* Stop procedure */
295         /* FIXME: F/W can be access invalid address */
296         /* Reset VI */
297         /*
298         s5p_mfc_write_reg(0x3f7, S5P_FIMV_SW_RESET);
299         */
300
301         if (IS_MFCV6(dev)) {
302                 /* Reset IP */
303                 s5p_mfc_write_reg(0xFEE, S5P_FIMV_MFC_RESET);   /*  except RISC, reset */
304                 s5p_mfc_write_reg(0x0, S5P_FIMV_MFC_RESET);     /*  reset release */
305
306                 /* Zero Initialization of MFC registers */
307                 s5p_mfc_write_reg(0, S5P_FIMV_RISC2HOST_CMD);
308                 s5p_mfc_write_reg(0, S5P_FIMV_HOST2RISC_CMD);
309                 s5p_mfc_write_reg(0, S5P_FIMV_FW_VERSION);
310
311                 for (i = 0; i < S5P_FIMV_REG_CLEAR_COUNT; i++)
312                         s5p_mfc_write_reg(0, S5P_FIMV_REG_CLEAR_BEGIN + (i*4));
313
314                 /* Reset */
315                 s5p_mfc_write_reg(0x1, S5P_FIMV_MFC_BUS_RESET_CTRL);
316
317                 timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
318                 /* Check bus status */
319                 do {
320                         if (time_after(jiffies, timeout)) {
321                                 mfc_err("Timeout while resetting MFC.\n");
322                                 return -EIO;
323                         }
324                         status = s5p_mfc_read_reg(S5P_FIMV_MFC_BUS_RESET_CTRL);
325                 } while ((status & 0x2) == 0);
326
327                 s5p_mfc_write_reg(0, S5P_FIMV_RISC_ON);
328                 s5p_mfc_write_reg(0x1FFF, S5P_FIMV_MFC_RESET);
329                 s5p_mfc_write_reg(0, S5P_FIMV_MFC_RESET);
330         } else {
331                 s5p_mfc_write_reg(0x3f6, S5P_FIMV_SW_RESET);    /*  reset RISC */
332                 s5p_mfc_write_reg(0x3e2, S5P_FIMV_SW_RESET);    /*  All reset except for MC */
333                 mdelay(10);
334
335                 timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
336
337                 /* Check MC status */
338                 do {
339                         if (time_after(jiffies, timeout)) {
340                                 mfc_err("Timeout while resetting MFC.\n");
341                                 return -EIO;
342                         }
343
344                         status = s5p_mfc_read_reg(S5P_FIMV_MC_STATUS);
345
346                 } while (status & 0x3);
347
348                 s5p_mfc_write_reg(0x0, S5P_FIMV_SW_RESET);
349                 s5p_mfc_write_reg(0x3fe, S5P_FIMV_SW_RESET);
350         }
351
352         mfc_debug_leave();
353
354         return 0;
355 }
356
357 static inline void s5p_mfc_init_memctrl(struct s5p_mfc_dev *dev)
358 {
359         if (IS_MFCV6(dev)) {
360                 s5p_mfc_write_reg(dev->port_a, S5P_FIMV_RISC_BASE_ADDRESS);
361                 mfc_debug(2, "Base Address : %08x\n", dev->port_a);
362         } else {
363                 /* channelA, port0 */
364                 s5p_mfc_write_reg(dev->port_a, S5P_FIMV_MC_DRAMBASE_ADR_A);
365                 /* channelB, port1 */
366                 s5p_mfc_write_reg(dev->port_b, S5P_FIMV_MC_DRAMBASE_ADR_B);
367
368                 mfc_debug(2, "Port A: %08x, Port B: %08x\n", dev->port_a, dev->port_b);
369         }
370 }
371
372 static inline void s5p_mfc_clear_cmds(struct s5p_mfc_dev *dev)
373 {
374         if (IS_MFCV6(dev)) {
375                 /* Zero initialization should be done before RESET.
376                  * Nothing to do here. */
377         } else {
378                 s5p_mfc_write_reg(0xffffffff, S5P_FIMV_SI_CH0_INST_ID);
379                 s5p_mfc_write_reg(0xffffffff, S5P_FIMV_SI_CH1_INST_ID);
380
381                 s5p_mfc_write_reg(0, S5P_FIMV_RISC2HOST_CMD);
382                 s5p_mfc_write_reg(0, S5P_FIMV_HOST2RISC_CMD);
383         }
384 }
385
386 /* Initialize hardware */
387 int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
388 {
389         char dvx_info;
390         int mfc_info;
391         int ret = 0;
392
393         mfc_debug_enter();
394
395         /* RMVME: */
396         if (!s5p_mfc_bitproc_buf)
397                 return -EINVAL;
398
399         /* 0. MFC reset */
400         mfc_debug(2, "MFC reset...\n");
401
402         s5p_mfc_clock_on();
403
404         ret = s5p_mfc_reset(dev);
405         if (ret) {
406                 mfc_err("Failed to reset MFC - timeout.\n");
407                 goto err_init_hw;
408         }
409         mfc_debug(2, "Done MFC reset...\n");
410
411         /* 1. Set DRAM base Addr */
412         s5p_mfc_init_memctrl(dev);
413
414         /* 2. Initialize registers of channel I/F */
415         s5p_mfc_clear_cmds(dev);
416
417         /* 3. Release reset signal to the RISC */
418         if (IS_MFCV6(dev))
419                 s5p_mfc_write_reg(0x1, S5P_FIMV_RISC_ON);
420         else
421                 s5p_mfc_write_reg(0x3ff, S5P_FIMV_SW_RESET);
422
423         mfc_debug(2, "Will now wait for completion of firmware transfer.\n");
424         if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_FW_STATUS_RET)) {
425                 mfc_err("Failed to load firmware.\n");
426                 s5p_mfc_clean_dev_int_flags(dev);
427                 ret = -EIO;
428                 goto err_init_hw;
429         }
430
431         s5p_mfc_clean_dev_int_flags(dev);
432         /* 4. Initialize firmware */
433         ret = s5p_mfc_sys_init_cmd(dev);
434         if (ret) {
435                 mfc_err("Failed to send command to MFC - timeout.\n");
436                 goto err_init_hw;
437         }
438         mfc_debug(2, "Ok, now will write a command to init the system\n");
439         if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_SYS_INIT_RET)) {
440                 mfc_err("Failed to load firmware\n");
441                 ret = -EIO;
442                 /* Disable the clock that enabled in s5p_mfc_sys_init_cmd() */
443                 s5p_mfc_clock_off();
444                 goto err_init_hw;
445         }
446
447         dev->int_cond = 0;
448         if (dev->int_err != 0 || dev->int_type !=
449                                                 S5P_FIMV_R2H_CMD_SYS_INIT_RET) {
450                 /* Failure. */
451                 mfc_err("Failed to init firmware - error: %d"
452                                 " int: %d.\n",dev->int_err, dev->int_type);
453                 ret = -EIO;
454                 goto err_init_hw;
455         }
456
457         dvx_info = MFC_GET_REG(SYS_FW_DVX_INFO);
458         if (dvx_info != 'D' && dvx_info != 'E')
459                 dvx_info = 'N';
460
461         mfc_info("MFC v%x.%x, F/W : (%c) %02xyy, %02xmm, %02xdd\n",
462                  MFC_VER_MAJOR(dev->fw.ver),
463                  MFC_VER_MINOR(dev->fw.ver),
464                  dvx_info,
465                  MFC_GET_REG(SYS_FW_VER_YEAR),
466                  MFC_GET_REG(SYS_FW_VER_MONTH),
467                  MFC_GET_REG(SYS_FW_VER_DATE));
468
469         dev->fw.date = MFC_GET_REG(SYS_FW_VER_ALL);
470         /* Check MFC version and F/W version */
471         if (dev->fw.date >= 0x120328) {
472                 mfc_info = MFC_GET_REG(SYS_MFC_VER);
473                 if (mfc_info != dev->fw.ver) {
474                         mfc_err("Invalid F/W version(0x%x) for MFC H/W(0x%x)\n",
475                                         mfc_info, dev->fw.ver);
476                         ret = -EIO;
477                         goto err_init_hw;
478                 }
479         }
480
481 err_init_hw:
482         s5p_mfc_clock_off();
483         mfc_debug_leave();
484
485         return ret;
486 }
487
488
489 /* Deinitialize hardware */
490 void s5p_mfc_deinit_hw(struct s5p_mfc_dev *dev)
491 {
492         s5p_mfc_clock_on();
493
494         s5p_mfc_reset(dev);
495         if (IS_MFCV6(dev))
496                 s5p_mfc_release_dev_context_buffer(dev);
497
498         s5p_mfc_clock_off();
499 }
500
501 int s5p_mfc_sleep(struct s5p_mfc_dev *dev)
502 {
503         int ret;
504
505         mfc_debug_enter();
506
507         s5p_mfc_clock_on();
508
509         s5p_mfc_clean_dev_int_flags(dev);
510         ret = s5p_mfc_sleep_cmd(dev);
511         if (ret) {
512                 mfc_err("Failed to send command to MFC - timeout.\n");
513                 goto err_mfc_sleep;
514         }
515         if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_SLEEP_RET)) {
516                 mfc_err("Failed to sleep\n");
517                 ret = -EIO;
518                 goto err_mfc_sleep;
519         }
520
521         dev->int_cond = 0;
522         if (dev->int_err != 0 || dev->int_type !=
523                                                 S5P_FIMV_R2H_CMD_SLEEP_RET) {
524                 /* Failure. */
525                 mfc_err("Failed to sleep - error: %d"
526                                 " int: %d.\n",dev->int_err, dev->int_type);
527                 ret = -EIO;
528                 goto err_mfc_sleep;
529         }
530
531 err_mfc_sleep:
532         s5p_mfc_clock_off();
533         mfc_debug_leave();
534
535         return ret;
536 }
537
538 int s5p_mfc_wakeup(struct s5p_mfc_dev *dev)
539 {
540         int ret;
541
542         mfc_debug_enter();
543
544         /* 0. MFC reset */
545         mfc_debug(2, "MFC reset...\n");
546
547         s5p_mfc_clock_on();
548
549         ret = s5p_mfc_reset(dev);
550         if (ret) {
551                 mfc_err("Failed to reset MFC - timeout.\n");
552                 goto err_mfc_wakeup;
553         }
554         mfc_debug(2, "Done MFC reset...\n");
555
556         /* 1. Set DRAM base Addr */
557         s5p_mfc_init_memctrl(dev);
558
559         /* 2. Initialize registers of channel I/F */
560         s5p_mfc_clear_cmds(dev);
561
562         s5p_mfc_clean_dev_int_flags(dev);
563         /* 3. Initialize firmware */
564         ret = s5p_mfc_wakeup_cmd(dev);
565         if (ret) {
566                 mfc_err("Failed to send command to MFC - timeout.\n");
567                 goto err_mfc_wakeup;
568         }
569
570         /* 4. Release reset signal to the RISC */
571         if (IS_MFCV6(dev))
572                 s5p_mfc_write_reg(0x1, S5P_FIMV_RISC_ON);
573         else
574                 s5p_mfc_write_reg(0x3ff, S5P_FIMV_SW_RESET);
575
576         mfc_debug(2, "Ok, now will write a command to wakeup the system\n");
577         if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_WAKEUP_RET)) {
578                 mfc_err("Failed to load firmware\n");
579                 ret = -EIO;
580                 goto err_mfc_wakeup;
581         }
582
583         dev->int_cond = 0;
584         if (dev->int_err != 0 || dev->int_type !=
585                                                 S5P_FIMV_R2H_CMD_WAKEUP_RET) {
586                 /* Failure. */
587                 mfc_err("Failed to wakeup - error: %d"
588                                 " int: %d.\n",dev->int_err, dev->int_type);
589                 ret = -EIO;
590                 goto err_mfc_wakeup;
591         }
592
593 err_mfc_wakeup:
594         s5p_mfc_clock_off();
595         mfc_debug_leave();
596
597         return 0;
598 }