2 * linux/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
4 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
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.
13 #include <linux/delay.h>
14 #include <linux/jiffies.h>
16 #include <linux/firmware.h>
17 #include <linux/err.h>
18 #include <linux/sched.h>
19 #include <linux/cma.h>
21 #include "s5p_mfc_common.h"
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"
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;
35 /* Allocate firmware */
36 int s5p_mfc_alloc_firmware(struct s5p_mfc_dev *dev)
38 #if defined(CONFIG_S5P_MFC_VB2_CMA)
40 struct cma_info mem_info_f, mem_info_a, mem_info_b;
42 unsigned int base_align = dev->variant->buf_align->mfc_base_align;
43 unsigned int firmware_size = dev->variant->buf_size->firmware_code;
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");
53 if (s5p_mfc_bitproc_buf)
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);
64 mfc_err("Couldn't get memory information from CMA.\n");
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);
72 mfc_err("Couldn't get memory information from CMA.\n");
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");
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");
89 s5p_mfc_bitproc_phys = s5p_mfc_mem_dma_addr(s5p_mfc_bitproc_buf);
91 if (s5p_mfc_bitproc_phys & ((1 << base_align) - 1)) {
92 mfc_err("The base memory is not aligned to %dBytes.\n",
94 s5p_mfc_mem_free(s5p_mfc_bitproc_buf);
95 s5p_mfc_bitproc_phys = 0;
96 s5p_mfc_bitproc_buf = 0;
99 dev->port_a = s5p_mfc_bitproc_phys;
101 s5p_mfc_bitproc_virt = s5p_mfc_mem_vaddr(s5p_mfc_bitproc_buf);
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;
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);
119 mfc_err("Couldn't get memory information from CMA.\n");
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,
127 mfc_debug(2, "Port : %08x (FW: %08x size: %08x)\n",
128 dev->port_a, s5p_mfc_bitproc_phys,
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");
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",
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;
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;
166 dev->port_a = s5p_mfc_bitproc_phys;
167 dev->port_b = s5p_mfc_bitproc_phys;
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,
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");
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",
187 s5p_mfc_mem_free(s5p_mfc_bitproc_buf);
188 s5p_mfc_bitproc_phys = 0;
189 s5p_mfc_bitproc_buf = 0;
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;
204 dev->port_a = s5p_mfc_bitproc_phys;
205 dev->port_b = s5p_mfc_bitproc_phys;
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,
218 /* Load firmware to MFC */
219 int s5p_mfc_load_firmware(struct s5p_mfc_dev *dev)
221 struct firmware *fw_blob;
222 unsigned int firmware_size = dev->variant->buf_size->firmware_code;
225 /* Firmare has to be present as a separate file or compiled
228 mfc_debug(2, "Requesting fw\n");
229 err = request_firmware((const struct firmware **)&fw_blob,
230 MFC_FW_NAME, dev->v4l2_dev.dev);
233 mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel.\n");
237 mfc_debug(2, "Ret of request_firmware: %d Size: %d\n", err, fw_blob->size);
239 if (fw_blob->size > firmware_size) {
240 mfc_err("MFC firmware is too big to be loaded.\n");
241 release_firmware(fw_blob);
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);
249 memcpy(s5p_mfc_bitproc_virt, fw_blob->data, fw_blob->size);
251 s5p_mfc_bitproc_dma = dma_map_single(dev->v4l2_dev.dev,
252 s5p_mfc_bitproc_virt,
256 s5p_mfc_cache_clean_fw(s5p_mfc_bitproc_buf);
257 release_firmware(fw_blob);
262 /* Release firmware memory */
263 int s5p_mfc_release_firmware(struct s5p_mfc_dev *dev)
265 /* Before calling this function one has to make sure
266 * that MFC is no longer processing */
267 if (!s5p_mfc_bitproc_buf)
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);
274 s5p_mfc_mem_free(s5p_mfc_bitproc_buf);
276 s5p_mfc_bitproc_virt = 0;
277 s5p_mfc_bitproc_phys = 0;
278 s5p_mfc_bitproc_buf = 0;
280 s5p_mfc_bitproc_dma = 0;
285 /* Reset the device */
286 static int s5p_mfc_reset(struct s5p_mfc_dev *dev)
290 unsigned long timeout;
295 /* FIXME: F/W can be access invalid address */
298 s5p_mfc_write_reg(0x3f7, S5P_FIMV_SW_RESET);
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 */
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);
311 for (i = 0; i < S5P_FIMV_REG_CLEAR_COUNT; i++)
312 s5p_mfc_write_reg(0, S5P_FIMV_REG_CLEAR_BEGIN + (i*4));
315 s5p_mfc_write_reg(0x1, S5P_FIMV_MFC_BUS_RESET_CTRL);
317 timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
318 /* Check bus status */
320 if (time_after(jiffies, timeout)) {
321 mfc_err("Timeout while resetting MFC.\n");
324 status = s5p_mfc_read_reg(S5P_FIMV_MFC_BUS_RESET_CTRL);
325 } while ((status & 0x2) == 0);
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);
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 */
335 timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
337 /* Check MC status */
339 if (time_after(jiffies, timeout)) {
340 mfc_err("Timeout while resetting MFC.\n");
344 status = s5p_mfc_read_reg(S5P_FIMV_MC_STATUS);
346 } while (status & 0x3);
348 s5p_mfc_write_reg(0x0, S5P_FIMV_SW_RESET);
349 s5p_mfc_write_reg(0x3fe, S5P_FIMV_SW_RESET);
357 static inline void s5p_mfc_init_memctrl(struct s5p_mfc_dev *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);
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);
368 mfc_debug(2, "Port A: %08x, Port B: %08x\n", dev->port_a, dev->port_b);
372 static inline void s5p_mfc_clear_cmds(struct s5p_mfc_dev *dev)
375 /* Zero initialization should be done before RESET.
376 * Nothing to do here. */
378 s5p_mfc_write_reg(0xffffffff, S5P_FIMV_SI_CH0_INST_ID);
379 s5p_mfc_write_reg(0xffffffff, S5P_FIMV_SI_CH1_INST_ID);
381 s5p_mfc_write_reg(0, S5P_FIMV_RISC2HOST_CMD);
382 s5p_mfc_write_reg(0, S5P_FIMV_HOST2RISC_CMD);
386 /* Initialize hardware */
387 int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
396 if (!s5p_mfc_bitproc_buf)
400 mfc_debug(2, "MFC reset...\n");
404 ret = s5p_mfc_reset(dev);
406 mfc_err("Failed to reset MFC - timeout.\n");
409 mfc_debug(2, "Done MFC reset...\n");
411 /* 1. Set DRAM base Addr */
412 s5p_mfc_init_memctrl(dev);
414 /* 2. Initialize registers of channel I/F */
415 s5p_mfc_clear_cmds(dev);
417 /* 3. Release reset signal to the RISC */
419 s5p_mfc_write_reg(0x1, S5P_FIMV_RISC_ON);
421 s5p_mfc_write_reg(0x3ff, S5P_FIMV_SW_RESET);
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);
431 s5p_mfc_clean_dev_int_flags(dev);
432 /* 4. Initialize firmware */
433 ret = s5p_mfc_sys_init_cmd(dev);
435 mfc_err("Failed to send command to MFC - timeout.\n");
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");
442 /* Disable the clock that enabled in s5p_mfc_sys_init_cmd() */
448 if (dev->int_err != 0 || dev->int_type !=
449 S5P_FIMV_R2H_CMD_SYS_INIT_RET) {
451 mfc_err("Failed to init firmware - error: %d"
452 " int: %d.\n",dev->int_err, dev->int_type);
457 dvx_info = MFC_GET_REG(SYS_FW_DVX_INFO);
458 if (dvx_info != 'D' && dvx_info != 'E')
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),
465 MFC_GET_REG(SYS_FW_VER_YEAR),
466 MFC_GET_REG(SYS_FW_VER_MONTH),
467 MFC_GET_REG(SYS_FW_VER_DATE));
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);
489 /* Deinitialize hardware */
490 void s5p_mfc_deinit_hw(struct s5p_mfc_dev *dev)
496 s5p_mfc_release_dev_context_buffer(dev);
501 int s5p_mfc_sleep(struct s5p_mfc_dev *dev)
509 s5p_mfc_clean_dev_int_flags(dev);
510 ret = s5p_mfc_sleep_cmd(dev);
512 mfc_err("Failed to send command to MFC - timeout.\n");
515 if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_SLEEP_RET)) {
516 mfc_err("Failed to sleep\n");
522 if (dev->int_err != 0 || dev->int_type !=
523 S5P_FIMV_R2H_CMD_SLEEP_RET) {
525 mfc_err("Failed to sleep - error: %d"
526 " int: %d.\n",dev->int_err, dev->int_type);
538 int s5p_mfc_wakeup(struct s5p_mfc_dev *dev)
545 mfc_debug(2, "MFC reset...\n");
549 ret = s5p_mfc_reset(dev);
551 mfc_err("Failed to reset MFC - timeout.\n");
554 mfc_debug(2, "Done MFC reset...\n");
556 /* 1. Set DRAM base Addr */
557 s5p_mfc_init_memctrl(dev);
559 /* 2. Initialize registers of channel I/F */
560 s5p_mfc_clear_cmds(dev);
562 s5p_mfc_clean_dev_int_flags(dev);
563 /* 3. Initialize firmware */
564 ret = s5p_mfc_wakeup_cmd(dev);
566 mfc_err("Failed to send command to MFC - timeout.\n");
570 /* 4. Release reset signal to the RISC */
572 s5p_mfc_write_reg(0x1, S5P_FIMV_RISC_ON);
574 s5p_mfc_write_reg(0x3ff, S5P_FIMV_SW_RESET);
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");
584 if (dev->int_err != 0 || dev->int_type !=
585 S5P_FIMV_R2H_CMD_WAKEUP_RET) {
587 mfc_err("Failed to wakeup - error: %d"
588 " int: %d.\n",dev->int_err, dev->int_type);