Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
s5p_mfc_ctrl.c
Go to the documentation of this file.
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 static void *s5p_mfc_bitproc_buf;
26 static size_t s5p_mfc_bitproc_phys;
27 static unsigned char *s5p_mfc_bitproc_virt;
28 
29 /* Allocate and load firmware */
31 {
32  struct firmware *fw_blob;
33  size_t bank2_base_phys;
34  void *b_base;
35  int err;
36 
37  /* Firmare has to be present as a separate file or compiled
38  * into kernel. */
40 
41  err = request_firmware((const struct firmware **)&fw_blob,
42  dev->variant->fw_name, dev->v4l2_dev.dev);
43  if (err != 0) {
44  mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
45  return -EINVAL;
46  }
47  dev->fw_size = dev->variant->buf_size->fw;
48  if (fw_blob->size > dev->fw_size) {
49  mfc_err("MFC firmware is too big to be loaded\n");
50  release_firmware(fw_blob);
51  return -ENOMEM;
52  }
53  if (s5p_mfc_bitproc_buf) {
54  mfc_err("Attempting to allocate firmware when it seems that it is already loaded\n");
55  release_firmware(fw_blob);
56  return -ENOMEM;
57  }
58  s5p_mfc_bitproc_buf = vb2_dma_contig_memops.alloc(
60  if (IS_ERR(s5p_mfc_bitproc_buf)) {
61  s5p_mfc_bitproc_buf = NULL;
62  mfc_err("Allocating bitprocessor buffer failed\n");
63  release_firmware(fw_blob);
64  return -ENOMEM;
65  }
66  s5p_mfc_bitproc_phys = s5p_mfc_mem_cookie(
67  dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], s5p_mfc_bitproc_buf);
68  if (s5p_mfc_bitproc_phys & ((1 << MFC_BASE_ALIGN_ORDER) - 1)) {
69  mfc_err("The base memory for bank 1 is not aligned to 128KB\n");
70  vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
71  s5p_mfc_bitproc_phys = 0;
72  s5p_mfc_bitproc_buf = NULL;
73  release_firmware(fw_blob);
74  return -EIO;
75  }
76  s5p_mfc_bitproc_virt = vb2_dma_contig_memops.vaddr(s5p_mfc_bitproc_buf);
77  if (!s5p_mfc_bitproc_virt) {
78  mfc_err("Bitprocessor memory remap failed\n");
79  vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
80  s5p_mfc_bitproc_phys = 0;
81  s5p_mfc_bitproc_buf = NULL;
82  release_firmware(fw_blob);
83  return -EIO;
84  }
85  dev->bank1 = s5p_mfc_bitproc_phys;
86  if (HAS_PORTNUM(dev) && IS_TWOPORT(dev)) {
87  b_base = vb2_dma_contig_memops.alloc(
90  if (IS_ERR(b_base)) {
91  vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
92  s5p_mfc_bitproc_phys = 0;
93  s5p_mfc_bitproc_buf = NULL;
94  mfc_err("Allocating bank2 base failed\n");
95  release_firmware(fw_blob);
96  return -ENOMEM;
97  }
98  bank2_base_phys = s5p_mfc_mem_cookie(
99  dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], b_base);
100  vb2_dma_contig_memops.put(b_base);
101  if (bank2_base_phys & ((1 << MFC_BASE_ALIGN_ORDER) - 1)) {
102  mfc_err("The base memory for bank 2 is not aligned to 128KB\n");
103  vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
104  s5p_mfc_bitproc_phys = 0;
105  s5p_mfc_bitproc_buf = NULL;
106  release_firmware(fw_blob);
107  return -EIO;
108  }
109  /* Valid buffers passed to MFC encoder with LAST_FRAME command
110  * should not have address of bank2 - MFC will treat it as a null frame.
111  * To avoid such situation we set bank2 address below the pool address.
112  */
113  dev->bank2 = bank2_base_phys - (1 << MFC_BASE_ALIGN_ORDER);
114  } else {
115  dev->bank2 = dev->bank1;
116  }
117  memcpy(s5p_mfc_bitproc_virt, fw_blob->data, fw_blob->size);
118  wmb();
119  release_firmware(fw_blob);
120  mfc_debug_leave();
121  return 0;
122 }
123 
124 /* Reload firmware to MFC */
126 {
127  struct firmware *fw_blob;
128  int err;
129 
130  /* Firmare has to be present as a separate file or compiled
131  * into kernel. */
132  mfc_debug_enter();
133 
134  err = request_firmware((const struct firmware **)&fw_blob,
135  dev->variant->fw_name, dev->v4l2_dev.dev);
136  if (err != 0) {
137  mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
138  return -EINVAL;
139  }
140  if (fw_blob->size > dev->fw_size) {
141  mfc_err("MFC firmware is too big to be loaded\n");
142  release_firmware(fw_blob);
143  return -ENOMEM;
144  }
145  if (s5p_mfc_bitproc_buf == NULL || s5p_mfc_bitproc_phys == 0) {
146  mfc_err("MFC firmware is not allocated or was not mapped correctly\n");
147  release_firmware(fw_blob);
148  return -EINVAL;
149  }
150  memcpy(s5p_mfc_bitproc_virt, fw_blob->data, fw_blob->size);
151  wmb();
152  release_firmware(fw_blob);
153  mfc_debug_leave();
154  return 0;
155 }
156 
157 /* Release firmware memory */
159 {
160  /* Before calling this function one has to make sure
161  * that MFC is no longer processing */
162  if (!s5p_mfc_bitproc_buf)
163  return -EINVAL;
164  vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
165  s5p_mfc_bitproc_virt = NULL;
166  s5p_mfc_bitproc_phys = 0;
167  s5p_mfc_bitproc_buf = NULL;
168  return 0;
169 }
170 
171 /* Reset the device */
173 {
174  unsigned int mc_status;
175  unsigned long timeout;
176  int i;
177 
178  mfc_debug_enter();
179 
180  if (IS_MFCV6(dev)) {
181  /* Reset IP */
182  /* except RISC, reset */
183  mfc_write(dev, 0xFEE, S5P_FIMV_MFC_RESET_V6);
184  /* reset release */
185  mfc_write(dev, 0x0, S5P_FIMV_MFC_RESET_V6);
186 
187  /* Zero Initialization of MFC registers */
191 
192  for (i = 0; i < S5P_FIMV_REG_CLEAR_COUNT_V6; i++)
193  mfc_write(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN_V6 + (i*4));
194 
195  /* Reset */
197  mfc_write(dev, 0x1FFF, S5P_FIMV_MFC_RESET_V6);
199  } else {
200  /* Stop procedure */
201  /* reset RISC */
202  mfc_write(dev, 0x3f6, S5P_FIMV_SW_RESET);
203  /* All reset except for MC */
204  mfc_write(dev, 0x3e2, S5P_FIMV_SW_RESET);
205  mdelay(10);
206 
208  /* Check MC status */
209  do {
210  if (time_after(jiffies, timeout)) {
211  mfc_err("Timeout while resetting MFC\n");
212  return -EIO;
213  }
214 
215  mc_status = mfc_read(dev, S5P_FIMV_MC_STATUS);
216 
217  } while (mc_status & 0x3);
218 
219  mfc_write(dev, 0x0, S5P_FIMV_SW_RESET);
220  mfc_write(dev, 0x3fe, S5P_FIMV_SW_RESET);
221  }
222 
223  mfc_debug_leave();
224  return 0;
225 }
226 
227 static inline void s5p_mfc_init_memctrl(struct s5p_mfc_dev *dev)
228 {
229  if (IS_MFCV6(dev)) {
231  mfc_debug(2, "Base Address : %08x\n", dev->bank1);
232  } else {
235  mfc_debug(2, "Bank1: %08x, Bank2: %08x\n",
236  dev->bank1, dev->bank2);
237  }
238 }
239 
240 static inline void s5p_mfc_clear_cmds(struct s5p_mfc_dev *dev)
241 {
242  if (IS_MFCV6(dev)) {
243  /* Zero initialization should be done before RESET.
244  * Nothing to do here. */
245  } else {
246  mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH0_INST_ID);
247  mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH1_INST_ID);
250  }
251 }
252 
253 /* Initialize hardware */
254 int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
255 {
256  unsigned int ver;
257  int ret;
258 
259  mfc_debug_enter();
260  if (!s5p_mfc_bitproc_buf)
261  return -EINVAL;
262 
263  /* 0. MFC reset */
264  mfc_debug(2, "MFC reset..\n");
266  ret = s5p_mfc_reset(dev);
267  if (ret) {
268  mfc_err("Failed to reset MFC - timeout\n");
269  return ret;
270  }
271  mfc_debug(2, "Done MFC reset..\n");
272  /* 1. Set DRAM base Addr */
273  s5p_mfc_init_memctrl(dev);
274  /* 2. Initialize registers of channel I/F */
275  s5p_mfc_clear_cmds(dev);
276  /* 3. Release reset signal to the RISC */
278  if (IS_MFCV6(dev))
279  mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6);
280  else
281  mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
282  mfc_debug(2, "Will now wait for completion of firmware transfer\n");
284  mfc_err("Failed to load firmware\n");
285  s5p_mfc_reset(dev);
287  return -EIO;
288  }
290  /* 4. Initialize firmware */
291  ret = s5p_mfc_hw_call(dev->mfc_cmds, sys_init_cmd, dev);
292  if (ret) {
293  mfc_err("Failed to send command to MFC - timeout\n");
294  s5p_mfc_reset(dev);
296  return ret;
297  }
298  mfc_debug(2, "Ok, now will write a command to init the system\n");
300  mfc_err("Failed to load firmware\n");
301  s5p_mfc_reset(dev);
303  return -EIO;
304  }
305  dev->int_cond = 0;
306  if (dev->int_err != 0 || dev->int_type !=
308  /* Failure. */
309  mfc_err("Failed to init firmware - error: %d int: %d\n",
310  dev->int_err, dev->int_type);
311  s5p_mfc_reset(dev);
313  return -EIO;
314  }
315  if (IS_MFCV6(dev))
316  ver = mfc_read(dev, S5P_FIMV_FW_VERSION_V6);
317  else
318  ver = mfc_read(dev, S5P_FIMV_FW_VERSION);
319 
320  mfc_debug(2, "MFC F/W version : %02xyy, %02xmm, %02xdd\n",
321  (ver >> 16) & 0xFF, (ver >> 8) & 0xFF, ver & 0xFF);
323  mfc_debug_leave();
324  return 0;
325 }
326 
327 
328 /* Deinitialize hardware */
330 {
332 
333  s5p_mfc_reset(dev);
334  s5p_mfc_hw_call(dev->mfc_ops, release_dev_context_buffer, dev);
335 
337 }
338 
339 int s5p_mfc_sleep(struct s5p_mfc_dev *dev)
340 {
341  int ret;
342 
343  mfc_debug_enter();
346  ret = s5p_mfc_hw_call(dev->mfc_cmds, sleep_cmd, dev);
347  if (ret) {
348  mfc_err("Failed to send command to MFC - timeout\n");
349  return ret;
350  }
352  mfc_err("Failed to sleep\n");
353  return -EIO;
354  }
356  dev->int_cond = 0;
357  if (dev->int_err != 0 || dev->int_type !=
359  /* Failure. */
360  mfc_err("Failed to sleep - error: %d int: %d\n", dev->int_err,
361  dev->int_type);
362  return -EIO;
363  }
364  mfc_debug_leave();
365  return ret;
366 }
367 
368 int s5p_mfc_wakeup(struct s5p_mfc_dev *dev)
369 {
370  int ret;
371 
372  mfc_debug_enter();
373  /* 0. MFC reset */
374  mfc_debug(2, "MFC reset..\n");
376  ret = s5p_mfc_reset(dev);
377  if (ret) {
378  mfc_err("Failed to reset MFC - timeout\n");
379  return ret;
380  }
381  mfc_debug(2, "Done MFC reset..\n");
382  /* 1. Set DRAM base Addr */
383  s5p_mfc_init_memctrl(dev);
384  /* 2. Initialize registers of channel I/F */
385  s5p_mfc_clear_cmds(dev);
387  /* 3. Initialize firmware */
388  ret = s5p_mfc_hw_call(dev->mfc_cmds, wakeup_cmd, dev);
389  if (ret) {
390  mfc_err("Failed to send command to MFC - timeout\n");
391  return ret;
392  }
393  /* 4. Release reset signal to the RISC */
394  if (IS_MFCV6(dev))
395  mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6);
396  else
397  mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
398  mfc_debug(2, "Ok, now will write a command to wakeup the system\n");
400  mfc_err("Failed to load firmware\n");
401  return -EIO;
402  }
404  dev->int_cond = 0;
405  if (dev->int_err != 0 || dev->int_type !=
407  /* Failure. */
408  mfc_err("Failed to wakeup - error: %d int: %d\n", dev->int_err,
409  dev->int_type);
410  return -EIO;
411  }
412  mfc_debug_leave();
413  return 0;
414 }
415