2 * linux/drivers/media/video/samsung/mfc5x/mfc_ctrl.c
4 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
7 * Control interface for Samsung MFC (Multi Function Codec - FIMV) driver
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
14 #include <linux/types.h>
15 #include <linux/kernel.h>
16 #include <linux/string.h>
17 #include <linux/delay.h>
18 #include <linux/sched.h>
20 #if defined(CONFIG_CPU_S5PV310)
21 #include <mach/regs-mfc.h>
22 #elif defined(CONFIG_ARCH_S5PV210)
23 #include <plat/regs-mfc.h>
33 #include "mfc_errno.h"
36 #define MC_STATUS_TIMEOUT 1000 /* ms */
38 static bool mfc_reset(void)
40 unsigned int mc_status;
41 unsigned long timeo = jiffies;
43 timeo += msecs_to_jiffies(MC_STATUS_TIMEOUT);
46 /* FIXME: F/W can be access invalid address */
49 write_reg(0x3F7, MFC_SW_RESET);
51 write_reg(0x3F6, MFC_SW_RESET); /* Reset RISC */
52 write_reg(0x3E2, MFC_SW_RESET); /* All reset except for MC */
57 mc_status = (read_reg(MFC_MC_STATUS) & 0x3);
62 schedule_timeout_uninterruptible(1);
63 /* FiXME: cpu_relax() */
64 } while (time_before(jiffies, timeo));
69 write_reg(0x0, MFC_SW_RESET);
70 write_reg(0x3FE, MFC_SW_RESET);
75 static void mfc_init_memctrl(void)
77 /* Channel A, Port 0 */
78 write_reg(mfc_mem_base(0), MFC_MC_DRAMBASE_ADR_A);
79 #if CONFIG_VIDEO_MFC_MEM_PORT_COUNT == 1
80 /* Channel B, Port 0 */
81 write_reg(mfc_mem_base(0), MFC_MC_DRAMBASE_ADR_B);
83 /* Channel B, Port 1 */
84 write_reg(mfc_mem_base(1), MFC_MC_DRAMBASE_ADR_B);
86 mfc_dbg("Master A - 0x%08x\n",
87 read_reg(MFC_MC_DRAMBASE_ADR_A));
88 mfc_dbg("Master B - 0x%08x\n",
89 read_reg(MFC_MC_DRAMBASE_ADR_B));
92 static void mfc_clear_cmds(void)
94 write_reg(0xFFFFFFFF, MFC_SI_CH1_INST_ID);
95 write_reg(0xFFFFFFFF, MFC_SI_CH2_INST_ID);
97 write_reg(H2R_NOP, MFC_RISC2HOST_CMD);
98 write_reg(R2H_NOP, MFC_HOST2RISC_CMD);
101 int mfc_load_firmware(const unsigned char *data, size_t size)
103 volatile unsigned char *fw;
105 if (!data || size == 0)
108 /* MFC F/W area already 128KB aligned */
109 fw = mfc_mem_addr(0);
111 memcpy((void *)fw, data, size);
113 mfc_mem_cache_clean((void *)fw, size);
118 int mfc_start(struct mfc_dev *dev)
122 /* FIXME: when MFC start, load firmware again */
124 dev->fw.state = mfc_load_firmware(dev->fw.info->data, dev->fw.info->size);
129 if (mfc_reset() == false) {
137 ret = mfc_cmd_fw_start(dev);
143 ret = mfc_cmd_sys_init(dev);
150 int mfc_sleep(struct mfc_dev *dev)
156 /* FIXME: add SFR backup? */
158 ret = mfc_cmd_sys_sleep(dev);
162 /* FIXME: add mfc_power_off()? */
168 int mfc_wakeup(struct mfc_dev *dev)
172 /* FIXME: add mfc_power_on()? */
176 if (mfc_reset() == false) {
184 ret = mfc_cmd_sys_wakeup(dev);