Samsung MFC (Multi Format Codec) Firmware and linux3.xfirmware under Linux3.X
By cool liukun321
From: http://blog.csdn.net/liukun321
The Samsung series processor has integrated a Multi Format Multi-Format media Codec hardware module from the very beginning of the SOC. In addition, Samsung's linux BSP is open-source to drive it. A friend who has read the MFC driver will surely find out that the kernel needs to load a Samsung MFC firmware during driver initialization. It cannot be used without MFC. Next let's take a look at how the firmware is associated with the kernel. Where can I obtain the firmware.
First look at the MFC firmware loading, this process is as follows, with exynos4412 Linux 3.5 BSP as an example, In the linux-3.5 \ drivers \ media \ video \ s5p-mfc \ s5p_mfc.c:
static int s5p_mfc_open(struct file *file){ structs5p_mfc_dev *dev = video_drvdata(file); structs5p_mfc_ctx *ctx = NULL; structvb2_queue *q; unsignedlong flags; intret = 0; exynos_cpufreq_lock_freq(1,MAX_CPU_FREQ);#ifdef CONFIG_BUSFREQ_OPP dev_lock(dev->bus_dev,dev->device, BUSFREQ_400MHZ);#endif mfc_debug_enter(); dev->num_inst++; /* It is guarded by mfc_mutex in vfd */ /*Allocate memory for context */ ctx= kzalloc(sizeof *ctx, GFP_KERNEL); if(!ctx) { mfc_err("Notenough memory\n"); ret= -ENOMEM; gotoerr_alloc; } v4l2_fh_init(&ctx->fh,video_devdata(file)); file->private_data= &ctx->fh; v4l2_fh_add(&ctx->fh); ctx->dev= dev; INIT_LIST_HEAD(&ctx->src_queue); INIT_LIST_HEAD(&ctx->dst_queue); ctx->src_queue_cnt= 0; ctx->dst_queue_cnt= 0; /*Get context number */ ctx->num= 0; while(dev->ctx[ctx->num]) { ctx->num++; if(ctx->num >= MFC_NUM_CONTEXTS) { mfc_err("Toomany open contexts\n"); ret= -EBUSY; gotoerr_no_ctx; } } /*Mark context as idle */ spin_lock_irqsave(&dev->condlock,flags); clear_bit(ctx->num,&dev->ctx_work_bits); spin_unlock_irqrestore(&dev->condlock,flags); dev->ctx[ctx->num]= ctx; if(s5p_mfc_get_node_type(file) == MFCNODE_DECODER) { ctx->type= MFCINST_DECODER; ctx->c_ops= get_dec_codec_ops(); /*Setup ctrl handler */ ret= s5p_mfc_dec_ctrls_setup(ctx); if(ret) { mfc_err("Failedto setup mfc controls\n"); gotoerr_ctrls_setup; } }else if (s5p_mfc_get_node_type(file) == MFCNODE_ENCODER) { ctx->type= MFCINST_ENCODER; ctx->c_ops= get_enc_codec_ops(); /*only for encoder */ INIT_LIST_HEAD(&ctx->ref_queue); ctx->ref_queue_cnt= 0; /*Setup ctrl handler */ ret= s5p_mfc_enc_ctrls_setup(ctx); if(ret) { mfc_err("Failedto setup mfc controls\n"); gotoerr_ctrls_setup; } }else { ret= -ENOENT; gotoerr_bad_node; } ctx->fh.ctrl_handler= &ctx->ctrl_handler; ctx->inst_no= -1; /*Load firmware if this is the first instance */ if(dev->num_inst == 1) { dev->watchdog_timer.expires= jiffies + msecs_to_jiffies(MFC_WATCHDOG_INTERVAL); add_timer(&dev->watchdog_timer); ret= s5p_mfc_power_on(); if(ret < 0) { mfc_err("poweron failed\n"); gotoerr_pwr_enable; } s5p_mfc_clock_on(); ret = s5p_mfc_alloc_and_load_firmware(dev); if(ret) gotoerr_alloc_fw; /*Init the FW */ ret= s5p_mfc_init_hw(dev); if(ret) gotoerr_init_hw; s5p_mfc_clock_off(); } /*Init videobuf2 queue for CAPTURE */ q= &ctx->vq_dst; q->type= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; q->drv_priv= &ctx->fh; if(s5p_mfc_get_node_type(file) == MFCNODE_DECODER) { q->io_modes= VB2_MMAP | VB2_DMABUF; q->ops= get_dec_queue_ops(); }else if (s5p_mfc_get_node_type(file) == MFCNODE_ENCODER) { q->io_modes= VB2_MMAP | VB2_USERPTR | VB2_DMABUF; q->ops= get_enc_queue_ops(); }else { ret= -ENOENT; gotoerr_queue_init; } q->mem_ops= (struct vb2_mem_ops *)&vb2_dma_contig_memops; ret= vb2_queue_init(q); if(ret) { mfc_err("Failedto initialize videobuf2 queue(capture)\n"); gotoerr_queue_init; } /*Init videobuf2 queue for OUTPUT */ q= &ctx->vq_src; q->type= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; q->io_modes= VB2_MMAP; q->drv_priv= &ctx->fh; if(s5p_mfc_get_node_type(file) == MFCNODE_DECODER) { q->io_modes= VB2_MMAP | VB2_DMABUF; q->ops= get_dec_queue_ops(); }else if (s5p_mfc_get_node_type(file) == MFCNODE_ENCODER) { q->io_modes= VB2_MMAP | VB2_USERPTR | VB2_DMABUF; q->ops= get_enc_queue_ops(); }else { ret= -ENOENT; gotoerr_queue_init; } q->mem_ops= (struct vb2_mem_ops *)&vb2_dma_contig_memops; ret= vb2_queue_init(q); if(ret) { mfc_err("Failedto initialize videobuf2 queue(output)\n"); gotoerr_queue_init; } init_waitqueue_head(&ctx->queue); mfc_debug_leave(); returnret; /*Deinit when failure occured */err_queue_init:err_init_hw: s5p_mfc_release_firmware(dev);err_alloc_fw: dev->ctx[ctx->num]= NULL; del_timer_sync(&dev->watchdog_timer); s5p_mfc_clock_off();err_pwr_enable: if(dev->num_inst == 1) { if(s5p_mfc_power_off() < 0) mfc_err("poweroff failed\n"); s5p_mfc_release_firmware(dev); }err_ctrls_setup: s5p_mfc_dec_ctrls_delete(ctx);err_bad_node:err_no_ctx: v4l2_fh_del(&ctx->fh); v4l2_fh_exit(&ctx->fh); kfree(ctx);err_alloc: dev->num_inst--; mfc_debug_leave(); returnret;}
Expand the row 83rd function ret = s5p_mfc_alloc_and_load_firmware (dev );:
int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev){struct firmware *fw_blob;size_t bank2_base_phys;void *b_base;int err;/* Firmare has to be present as a separate file or compiled * into kernel. */mfc_debug_enter();err = request_firmware((const struct firmware **)&fw_blob, "s5p-mfc.fw", dev->v4l2_dev.dev);if (err != 0) {mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");return -EINVAL;}dev->fw_size = ALIGN(fw_blob->size, FIRMWARE_ALIGN);if (s5p_mfc_bitproc_buf) {mfc_err("Attempting to allocate firmware when it seems that it is already loaded\n");release_firmware(fw_blob);return -ENOMEM;}s5p_mfc_bitproc_buf = vb2_dma_contig_memops.alloc(dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], dev->fw_size);if (IS_ERR(s5p_mfc_bitproc_buf)) {s5p_mfc_bitproc_buf = NULL;mfc_err("Allocating bitprocessor buffer failed\n");release_firmware(fw_blob);return -ENOMEM;}
Look at the key part, analyze the request_firmware (const struct firmware **) & fw_blob, "s5p-mfc.fw", dev-> v4l2_dev.dev); from the function name, it is not difficult to think of its function: load the firmware. In fact, it is to move the data in the firmware to the memory pointed by a member of fw_blob. For details, refer to the following analysis. Here, we need to look at the definition of the structure struct firmware.
Struct firmware {
Size_t size;
Const u8 * data;
Struct page ** pages;
};
Let's talk about the firmware loading process. During request_firmware execution, memory will be allocated to the instantiated struct firmware structure, in addition, the function will create a new directory named by the device name under/sys/class/firmware, which contains three attributes:
Loading: This attribute should be set to 1 by the user space process loading the firmware. When the load is completed, it is set to 0. When it is set to-1, the firmware loading will be aborted.
Data: A Binary Attribute used to receive firmware data. After loading is set to 1, the user space process writes the firmware to this attribute.
Device: A symbolic link to the entry items under/sys/devices.
Once the sysfs entry item is created, the kernel will generate a hot swapping event for the device and pass the environment variables including the FIRMWARE variable to the user space program that handles hot swapping. FIRMWARE is set to the FIRMWARE file name provided to request_firmware.
The user space program locates the firmware file and copies it to the Binary Attribute provided by the kernel. If the file cannot be located, the user space program sets the loading attribute to-1.
If the firmware request is not served within 10 seconds, the kernel will give up and return a failed status to the driver. The timeout period can be changed through the sysfs attribute/sys/class/firmware/timeout.
After talking so much, it is still a key point. In fact, there is another process when executing request_firmware: Determine whether the firmware is compiled into the kernel. If the firmware is added to the kernel compilation process, the process mentioned above is white-it is useless. See the following code:
Fw_priv = _ request_firmware_prepare (firmware_p, name, device, true, false );
If (IS_ERR_OR_NULL (fw_priv ))
ReturnPTR_RET (fw_priv );
This is a short piece of code starting with the request_firmware function. during the execution of the _ request_firmware_prepare function, if the firmware is compiled into the kernel, The Global firmware address (pointer) of the kernel is copied to the target address, that is, copy to the memory pointed by the structfirmware data member (the firmware is finally loaded), then _ request_firmware_prepare returns a null pointer, and then the request_firmware function returns. The code for this process is as follows:
static struct firmware_priv *_request_firmware_prepare(const struct firmware **firmware_p, const char *name, struct device *device, bool uevent, bool nowait){struct firmware *firmware;struct firmware_priv *fw_priv;if (!firmware_p)return ERR_PTR(-EINVAL);*firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL);if (!firmware) {dev_err(device, "%s: kmalloc(struct firmware) failed\n",__func__);return ERR_PTR(-ENOMEM);}if (fw_get_builtin_firmware(firmware, name)) {dev_dbg(device, "firmware: using built-in firmware %s\n", name);return NULL;}。。。。。}
There are a bunch of things involved in the firmware loading process. In fact, it is not just MFC, but almost all the firmware loading processes follow the above process.
Let's try something practical.
Where can we get the firmware?
1. Find Samsung technical support.
2. Find a third-party development board after-sales.
3. Go Down from the Internet.
The first two are nonsense and Samsung will not take care of our small users. After-sales development board? They only say: find it on your own, and find it on the CD! There is a CD, but where do I want a higher version?
This is not difficult. google's popular release version of the Linux kernel branch, the firmware is well applied to the entire platform. Now we have it.
The firmware I got is attached below:
Samsung MFC firmware download
This file contains the following files:
* MFCv5 firmware (s5p-mfc.fw) * MFCv6 firmware, version 1 (s5p-mfc-v6.fw) * MFCv6 firmware, version 2 (s5p-mfc-v6-v2.fw) * MFCv7 firmware (s5p-mfc-v7.fw) * MFCv8 firmware (s5p-mfc-v8.fw)
In my kernel package, s5p-mfc.fw is used, that is, MFCv5.
In addition, we found some information about the relationship between the MFC firmware version and the processor:
S5p-mfc-v7.fw: Used in exynos 5420.
S5p-mfc-v8.fw: Used in exynos 5800.
The content of this article is so much that the next article hopes to be followed by an analysis of the Live555 server process. Live555 is short in time, and the text is coded out. The quality is poor. Let's get things done.
What are the advantages of samsung S5PV210 processors? And the development boards that use this chip all have those, which manufacturers are more cost-effective
You can leave a mailbox to send you some information. Currently, this chip is widely used in MID, and ti also has DM3730.
S5PV210 is a 32-bit RISC cost-tive, low power, and high performance microprocessor solution for mobile
Phones and general applications. It integrates the ARM Cortex-A8 core, which implements the ARM architecture
V7-A with supporting peripherals.
To provide optimized Hardware (H/W) performance for the 3G and 3.5G communication services, S5PV210
Adopts 64-bit internal bus architecture. This primary des has powerful hardware accelerators for tasks such
Motion video processing, display control, and scaling. Integrated Multi Format Codec (MFC) supports encoding
And decoding of MPEG-1/2/4, H.263, and H.264, and decoding of VC1. This hardware accelerator (MFC) supports
Real-time video conferencing and Analog TV out, HDMI for NTSC, and PAL mode.
S5PV210 has an interface to external memory that is capable of sustaining heavy memory bandwidths required in
High-end communication services. The memory system has Flash/ROM external memory ports for parallel access
And DRAM port to meet high bandwidths. DRAM controller supports LPDDR1 (mobile DDR), DDR2, or LPDDR2.
Flash/ROM port supports NAND Flash, NOR-Flash, OneNAND, SRAM, and ROM type external memory.
To reduce the total system cost and enhance the overall functionality, S5PV210 between des includes hardware
Peripherals such as TFT 24-bit true color LCD controller, Camera Interface, MIPI DSI, CSI-2, System Manager
Power management, ATA interface, four U ...... the remaining full text>