Merge branch 'for-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
[firefly-linux-kernel-4.4.55.git] / drivers / media / platform / s5p-mfc / s5p_mfc_ctrl.c
1 /*
2  * linux/drivers/media/platform/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/err.h>
15 #include <linux/firmware.h>
16 #include <linux/jiffies.h>
17 #include <linux/sched.h>
18 #include "s5p_mfc_cmd.h"
19 #include "s5p_mfc_common.h"
20 #include "s5p_mfc_debug.h"
21 #include "s5p_mfc_intr.h"
22 #include "s5p_mfc_opr.h"
23 #include "s5p_mfc_pm.h"
24
25 /* Allocate memory for firmware */
26 int s5p_mfc_alloc_firmware(struct s5p_mfc_dev *dev)
27 {
28         void *bank2_virt;
29         dma_addr_t bank2_dma_addr;
30
31         dev->fw_size = dev->variant->buf_size->fw;
32
33         if (dev->fw_virt_addr) {
34                 mfc_err("Attempting to allocate firmware when it seems that it is already loaded\n");
35                 return -ENOMEM;
36         }
37
38         dev->fw_virt_addr = dma_alloc_coherent(dev->mem_dev_l, dev->fw_size,
39                                         &dev->bank1, GFP_KERNEL);
40
41         if (IS_ERR_OR_NULL(dev->fw_virt_addr)) {
42                 dev->fw_virt_addr = NULL;
43                 mfc_err("Allocating bitprocessor buffer failed\n");
44                 return -ENOMEM;
45         }
46
47         if (HAS_PORTNUM(dev) && IS_TWOPORT(dev)) {
48                 bank2_virt = dma_alloc_coherent(dev->mem_dev_r, 1 << MFC_BASE_ALIGN_ORDER,
49                                         &bank2_dma_addr, GFP_KERNEL);
50
51                 if (IS_ERR(dev->fw_virt_addr)) {
52                         mfc_err("Allocating bank2 base failed\n");
53                         dma_free_coherent(dev->mem_dev_l, dev->fw_size,
54                                 dev->fw_virt_addr, dev->bank1);
55                         dev->fw_virt_addr = NULL;
56                         return -ENOMEM;
57                 }
58
59                 /* Valid buffers passed to MFC encoder with LAST_FRAME command
60                  * should not have address of bank2 - MFC will treat it as a null frame.
61                  * To avoid such situation we set bank2 address below the pool address.
62                  */
63                 dev->bank2 = bank2_dma_addr - (1 << MFC_BASE_ALIGN_ORDER);
64
65                 dma_free_coherent(dev->mem_dev_r, 1 << MFC_BASE_ALIGN_ORDER,
66                         bank2_virt, bank2_dma_addr);
67
68         } else {
69                 /* In this case bank2 can point to the same address as bank1.
70                  * Firmware will always occupy the beginning of this area so it is
71                  * impossible having a video frame buffer with zero address. */
72                 dev->bank2 = dev->bank1;
73         }
74         return 0;
75 }
76
77 /* Load firmware */
78 int s5p_mfc_load_firmware(struct s5p_mfc_dev *dev)
79 {
80         struct firmware *fw_blob;
81         int err;
82
83         /* Firmare has to be present as a separate file or compiled
84          * into kernel. */
85         mfc_debug_enter();
86
87         err = request_firmware((const struct firmware **)&fw_blob,
88                                      dev->variant->fw_name, dev->v4l2_dev.dev);
89         if (err != 0) {
90                 mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
91                 return -EINVAL;
92         }
93         if (fw_blob->size > dev->fw_size) {
94                 mfc_err("MFC firmware is too big to be loaded\n");
95                 release_firmware(fw_blob);
96                 return -ENOMEM;
97         }
98         if (!dev->fw_virt_addr) {
99                 mfc_err("MFC firmware is not allocated\n");
100                 release_firmware(fw_blob);
101                 return -EINVAL;
102         }
103         memcpy(dev->fw_virt_addr, fw_blob->data, fw_blob->size);
104         wmb();
105         release_firmware(fw_blob);
106         mfc_debug_leave();
107         return 0;
108 }
109
110 /* Reload firmware to MFC */
111 int s5p_mfc_reload_firmware(struct s5p_mfc_dev *dev)
112 {
113         struct firmware *fw_blob;
114         int err;
115
116         /* Firmare has to be present as a separate file or compiled
117          * into kernel. */
118         mfc_debug_enter();
119
120         err = request_firmware((const struct firmware **)&fw_blob,
121                                      dev->variant->fw_name, dev->v4l2_dev.dev);
122         if (err != 0) {
123                 mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
124                 return -EINVAL;
125         }
126         if (fw_blob->size > dev->fw_size) {
127                 mfc_err("MFC firmware is too big to be loaded\n");
128                 release_firmware(fw_blob);
129                 return -ENOMEM;
130         }
131         if (!dev->fw_virt_addr) {
132                 mfc_err("MFC firmware is not allocated\n");
133                 release_firmware(fw_blob);
134                 return -EINVAL;
135         }
136         memcpy(dev->fw_virt_addr, fw_blob->data, fw_blob->size);
137         wmb();
138         release_firmware(fw_blob);
139         mfc_debug_leave();
140         return 0;
141 }
142
143 /* Release firmware memory */
144 int s5p_mfc_release_firmware(struct s5p_mfc_dev *dev)
145 {
146         /* Before calling this function one has to make sure
147          * that MFC is no longer processing */
148         if (!dev->fw_virt_addr)
149                 return -EINVAL;
150         dma_free_coherent(dev->mem_dev_l, dev->fw_size, dev->fw_virt_addr,
151                                                 dev->bank1);
152         dev->fw_virt_addr = NULL;
153         return 0;
154 }
155
156 /* Reset the device */
157 int s5p_mfc_reset(struct s5p_mfc_dev *dev)
158 {
159         unsigned int mc_status;
160         unsigned long timeout;
161         int i;
162
163         mfc_debug_enter();
164
165         if (IS_MFCV6_PLUS(dev)) {
166                 /* Reset IP */
167                 /*  except RISC, reset */
168                 mfc_write(dev, 0xFEE, S5P_FIMV_MFC_RESET_V6);
169                 /*  reset release */
170                 mfc_write(dev, 0x0, S5P_FIMV_MFC_RESET_V6);
171
172                 /* Zero Initialization of MFC registers */
173                 mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD_V6);
174                 mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD_V6);
175                 mfc_write(dev, 0, S5P_FIMV_FW_VERSION_V6);
176
177                 for (i = 0; i < S5P_FIMV_REG_CLEAR_COUNT_V6; i++)
178                         mfc_write(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN_V6 + (i*4));
179
180                 /* Reset */
181                 mfc_write(dev, 0, S5P_FIMV_RISC_ON_V6);
182                 mfc_write(dev, 0x1FFF, S5P_FIMV_MFC_RESET_V6);
183                 mfc_write(dev, 0, S5P_FIMV_MFC_RESET_V6);
184         } else {
185                 /* Stop procedure */
186                 /*  reset RISC */
187                 mfc_write(dev, 0x3f6, S5P_FIMV_SW_RESET);
188                 /*  All reset except for MC */
189                 mfc_write(dev, 0x3e2, S5P_FIMV_SW_RESET);
190                 mdelay(10);
191
192                 timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
193                 /* Check MC status */
194                 do {
195                         if (time_after(jiffies, timeout)) {
196                                 mfc_err("Timeout while resetting MFC\n");
197                                 return -EIO;
198                         }
199
200                         mc_status = mfc_read(dev, S5P_FIMV_MC_STATUS);
201
202                 } while (mc_status & 0x3);
203
204                 mfc_write(dev, 0x0, S5P_FIMV_SW_RESET);
205                 mfc_write(dev, 0x3fe, S5P_FIMV_SW_RESET);
206         }
207
208         mfc_debug_leave();
209         return 0;
210 }
211
212 static inline void s5p_mfc_init_memctrl(struct s5p_mfc_dev *dev)
213 {
214         if (IS_MFCV6_PLUS(dev)) {
215                 mfc_write(dev, dev->bank1, S5P_FIMV_RISC_BASE_ADDRESS_V6);
216                 mfc_debug(2, "Base Address : %08x\n", dev->bank1);
217         } else {
218                 mfc_write(dev, dev->bank1, S5P_FIMV_MC_DRAMBASE_ADR_A);
219                 mfc_write(dev, dev->bank2, S5P_FIMV_MC_DRAMBASE_ADR_B);
220                 mfc_debug(2, "Bank1: %08x, Bank2: %08x\n",
221                                 dev->bank1, dev->bank2);
222         }
223 }
224
225 static inline void s5p_mfc_clear_cmds(struct s5p_mfc_dev *dev)
226 {
227         if (IS_MFCV6_PLUS(dev)) {
228                 /* Zero initialization should be done before RESET.
229                  * Nothing to do here. */
230         } else {
231                 mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH0_INST_ID);
232                 mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH1_INST_ID);
233                 mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD);
234                 mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD);
235         }
236 }
237
238 /* Initialize hardware */
239 int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
240 {
241         unsigned int ver;
242         int ret;
243
244         mfc_debug_enter();
245         if (!dev->fw_virt_addr) {
246                 mfc_err("Firmware memory is not allocated.\n");
247                 return -EINVAL;
248         }
249
250         /* 0. MFC reset */
251         mfc_debug(2, "MFC reset..\n");
252         s5p_mfc_clock_on();
253         ret = s5p_mfc_reset(dev);
254         if (ret) {
255                 mfc_err("Failed to reset MFC - timeout\n");
256                 return ret;
257         }
258         mfc_debug(2, "Done MFC reset..\n");
259         /* 1. Set DRAM base Addr */
260         s5p_mfc_init_memctrl(dev);
261         /* 2. Initialize registers of channel I/F */
262         s5p_mfc_clear_cmds(dev);
263         /* 3. Release reset signal to the RISC */
264         s5p_mfc_clean_dev_int_flags(dev);
265         if (IS_MFCV6_PLUS(dev))
266                 mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6);
267         else
268                 mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
269         mfc_debug(2, "Will now wait for completion of firmware transfer\n");
270         if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_FW_STATUS_RET)) {
271                 mfc_err("Failed to load firmware\n");
272                 s5p_mfc_reset(dev);
273                 s5p_mfc_clock_off();
274                 return -EIO;
275         }
276         s5p_mfc_clean_dev_int_flags(dev);
277         /* 4. Initialize firmware */
278         ret = s5p_mfc_hw_call(dev->mfc_cmds, sys_init_cmd, dev);
279         if (ret) {
280                 mfc_err("Failed to send command to MFC - timeout\n");
281                 s5p_mfc_reset(dev);
282                 s5p_mfc_clock_off();
283                 return ret;
284         }
285         mfc_debug(2, "Ok, now will write a command to init the system\n");
286         if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_SYS_INIT_RET)) {
287                 mfc_err("Failed to load firmware\n");
288                 s5p_mfc_reset(dev);
289                 s5p_mfc_clock_off();
290                 return -EIO;
291         }
292         dev->int_cond = 0;
293         if (dev->int_err != 0 || dev->int_type !=
294                                         S5P_MFC_R2H_CMD_SYS_INIT_RET) {
295                 /* Failure. */
296                 mfc_err("Failed to init firmware - error: %d int: %d\n",
297                                                 dev->int_err, dev->int_type);
298                 s5p_mfc_reset(dev);
299                 s5p_mfc_clock_off();
300                 return -EIO;
301         }
302         if (IS_MFCV6_PLUS(dev))
303                 ver = mfc_read(dev, S5P_FIMV_FW_VERSION_V6);
304         else
305                 ver = mfc_read(dev, S5P_FIMV_FW_VERSION);
306
307         mfc_debug(2, "MFC F/W version : %02xyy, %02xmm, %02xdd\n",
308                 (ver >> 16) & 0xFF, (ver >> 8) & 0xFF, ver & 0xFF);
309         s5p_mfc_clock_off();
310         mfc_debug_leave();
311         return 0;
312 }
313
314
315 /* Deinitialize hardware */
316 void s5p_mfc_deinit_hw(struct s5p_mfc_dev *dev)
317 {
318         s5p_mfc_clock_on();
319
320         s5p_mfc_reset(dev);
321         s5p_mfc_hw_call(dev->mfc_ops, release_dev_context_buffer, dev);
322
323         s5p_mfc_clock_off();
324 }
325
326 int s5p_mfc_sleep(struct s5p_mfc_dev *dev)
327 {
328         int ret;
329
330         mfc_debug_enter();
331         s5p_mfc_clock_on();
332         s5p_mfc_clean_dev_int_flags(dev);
333         ret = s5p_mfc_hw_call(dev->mfc_cmds, sleep_cmd, dev);
334         if (ret) {
335                 mfc_err("Failed to send command to MFC - timeout\n");
336                 return ret;
337         }
338         if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_SLEEP_RET)) {
339                 mfc_err("Failed to sleep\n");
340                 return -EIO;
341         }
342         s5p_mfc_clock_off();
343         dev->int_cond = 0;
344         if (dev->int_err != 0 || dev->int_type !=
345                                                 S5P_MFC_R2H_CMD_SLEEP_RET) {
346                 /* Failure. */
347                 mfc_err("Failed to sleep - error: %d int: %d\n", dev->int_err,
348                                                                 dev->int_type);
349                 return -EIO;
350         }
351         mfc_debug_leave();
352         return ret;
353 }
354
355 int s5p_mfc_wakeup(struct s5p_mfc_dev *dev)
356 {
357         int ret;
358
359         mfc_debug_enter();
360         /* 0. MFC reset */
361         mfc_debug(2, "MFC reset..\n");
362         s5p_mfc_clock_on();
363         ret = s5p_mfc_reset(dev);
364         if (ret) {
365                 mfc_err("Failed to reset MFC - timeout\n");
366                 return ret;
367         }
368         mfc_debug(2, "Done MFC reset..\n");
369         /* 1. Set DRAM base Addr */
370         s5p_mfc_init_memctrl(dev);
371         /* 2. Initialize registers of channel I/F */
372         s5p_mfc_clear_cmds(dev);
373         s5p_mfc_clean_dev_int_flags(dev);
374         /* 3. Initialize firmware */
375         ret = s5p_mfc_hw_call(dev->mfc_cmds, wakeup_cmd, dev);
376         if (ret) {
377                 mfc_err("Failed to send command to MFC - timeout\n");
378                 return ret;
379         }
380         /* 4. Release reset signal to the RISC */
381         if (IS_MFCV6_PLUS(dev))
382                 mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6);
383         else
384                 mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
385         mfc_debug(2, "Ok, now will write a command to wakeup the system\n");
386         if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_WAKEUP_RET)) {
387                 mfc_err("Failed to load firmware\n");
388                 return -EIO;
389         }
390         s5p_mfc_clock_off();
391         dev->int_cond = 0;
392         if (dev->int_err != 0 || dev->int_type !=
393                                                 S5P_MFC_R2H_CMD_WAKEUP_RET) {
394                 /* Failure. */
395                 mfc_err("Failed to wakeup - error: %d int: %d\n", dev->int_err,
396                                                                 dev->int_type);
397                 return -EIO;
398         }
399         mfc_debug_leave();
400         return 0;
401 }
402
403 int s5p_mfc_open_mfc_inst(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx)
404 {
405         int ret = 0;
406
407         ret = s5p_mfc_hw_call(dev->mfc_ops, alloc_instance_buffer, ctx);
408         if (ret) {
409                 mfc_err("Failed allocating instance buffer\n");
410                 goto err;
411         }
412
413         if (ctx->type == MFCINST_DECODER) {
414                 ret = s5p_mfc_hw_call(dev->mfc_ops,
415                                         alloc_dec_temp_buffers, ctx);
416                 if (ret) {
417                         mfc_err("Failed allocating temporary buffers\n");
418                         goto err_free_inst_buf;
419                 }
420         }
421
422         set_work_bit_irqsave(ctx);
423         s5p_mfc_clean_ctx_int_flags(ctx);
424         s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
425         if (s5p_mfc_wait_for_done_ctx(ctx,
426                 S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET, 0)) {
427                 /* Error or timeout */
428                 mfc_err("Error getting instance from hardware\n");
429                 ret = -EIO;
430                 goto err_free_desc_buf;
431         }
432
433         mfc_debug(2, "Got instance number: %d\n", ctx->inst_no);
434         return ret;
435
436 err_free_desc_buf:
437         if (ctx->type == MFCINST_DECODER)
438                 s5p_mfc_hw_call(dev->mfc_ops, release_dec_desc_buffer, ctx);
439 err_free_inst_buf:
440         s5p_mfc_hw_call(dev->mfc_ops, release_instance_buffer, ctx);
441 err:
442         return ret;
443 }
444
445 void s5p_mfc_close_mfc_inst(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx)
446 {
447         ctx->state = MFCINST_RETURN_INST;
448         set_work_bit_irqsave(ctx);
449         s5p_mfc_clean_ctx_int_flags(ctx);
450         s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
451         /* Wait until instance is returned or timeout occurred */
452         if (s5p_mfc_wait_for_done_ctx(ctx,
453                                 S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0))
454                 mfc_err("Err returning instance\n");
455
456         /* Free resources */
457         s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers, ctx);
458         s5p_mfc_hw_call(dev->mfc_ops, release_instance_buffer, ctx);
459         if (ctx->type == MFCINST_DECODER)
460                 s5p_mfc_hw_call(dev->mfc_ops, release_dec_desc_buffer, ctx);
461
462         ctx->inst_no = MFC_NO_INSTANCE_SET;
463         ctx->state = MFCINST_FREE;
464 }