diff options
author | Xinyu Chen <xinyu.chen@freescale.com> | 2012-08-10 16:27:20 +0800 |
---|---|---|
committer | Xinyu Chen <xinyu.chen@freescale.com> | 2012-08-10 16:27:20 +0800 |
commit | 14839768c2e0f5448f1767729a7fe5791cd4f3dd (patch) | |
tree | 9f69e695154d828ca8f6e81d76451843f9d543f4 | |
parent | 76b225cc90ecdd50e67c4bdb79448973db49ead6 (diff) | |
parent | f588fca89c529c559ef280a96b4c9143aec904bc (diff) |
Merge remote branch 'fsl-linux-sdk/imx_3.0.35' into imx_3.0.35_android
23 files changed, 839 insertions, 57 deletions
diff --git a/arch/arm/configs/imx6_defconfig b/arch/arm/configs/imx6_defconfig index 181cf312d2b4..495cdf7ea588 100644 --- a/arch/arm/configs/imx6_defconfig +++ b/arch/arm/configs/imx6_defconfig @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/arm 3.0.15 Kernel Configuration +# Linux/arm 3.0.35 Kernel Configuration # CONFIG_ARM=y CONFIG_HAVE_PWM=y @@ -314,6 +314,7 @@ CONFIG_MACH_MX6Q_SABREAUTO=y # MX6 Options: # # CONFIG_IMX_PCIE is not set +CONFIG_USB_EHCI_ARC_H1=y # CONFIG_MX6_INTER_LDO_BYPASS is not set CONFIG_ISP1504_MXC=y # CONFIG_MXC_IRQ_PRIOR is not set @@ -1622,7 +1623,7 @@ CONFIG_MXC_CAMERA_OV5642=m CONFIG_MXC_TVIN_ADV7180=m CONFIG_MXC_CAMERA_OV5640_MIPI=m CONFIG_MXC_CAMERA_SENSOR_CLK=m -CONFIG_MXC_IPU_PRP_VF_SDC=m +CONFIG_MXC_IPU_DEVICE_QUEUE_SDC=m CONFIG_MXC_IPU_PRP_ENC=m CONFIG_MXC_IPU_CSI_ENC=m CONFIG_VIDEO_MXC_OUTPUT=y @@ -1938,7 +1939,6 @@ CONFIG_USB_OTG=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ARC=y CONFIG_USB_EHCI_ARC_OTG=y -CONFIG_USB_EHCI_ARC_H1=y # CONFIG_USB_EHCI_ARC_HSIC is not set # CONFIG_USB_STATIC_IRAM is not set CONFIG_USB_EHCI_ROOT_HUB_TT=y diff --git a/arch/arm/mach-mx6/board-mx6q_arm2.c b/arch/arm/mach-mx6/board-mx6q_arm2.c index 64cba5af1f08..98394c54d7d6 100644 --- a/arch/arm/mach-mx6/board-mx6q_arm2.c +++ b/arch/arm/mach-mx6/board-mx6q_arm2.c @@ -53,6 +53,9 @@ #include <linux/regulator/fixed.h> #include <linux/mfd/max17135.h> #include <sound/pcm.h> +#include <linux/mxc_asrc.h> +#include <linux/mfd/mxc-hdmi-core.h> + #include <mach/common.h> #include <mach/hardware.h> @@ -1411,7 +1414,7 @@ static void hdmi_init(int ipu_id, int disp_id) mxc_iomux_set_gpr_register(3, 2, 2, hdmi_mux_setting); /* Set HDMI event as SDMA event2 while Chip version later than TO1.2 */ - if ((mx6q_revision() > IMX_CHIP_REVISION_1_1)) + if (hdmi_SDMA_check()) mxc_iomux_set_gpr_register(0, 0, 1, 1); } @@ -1569,8 +1572,14 @@ static const struct pm_platform_data mx6_arm2_pm_data __initconst = { .suspend_exit = arm2_suspend_exit, }; +static const struct asrc_p2p_params esai_p2p __initconst = { + .p2p_rate = 44100, + .p2p_width = ASRC_WIDTH_24_BIT, +}; + static struct mxc_audio_platform_data sab_audio_data = { .sysclk = 16934400, + .priv = (void *)&esai_p2p, }; static struct platform_device sab_audio_device = { diff --git a/arch/arm/mach-mx6/board-mx6q_sabreauto.c b/arch/arm/mach-mx6/board-mx6q_sabreauto.c index 4578ce1d003c..b8f609c136cc 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabreauto.c +++ b/arch/arm/mach-mx6/board-mx6q_sabreauto.c @@ -57,6 +57,7 @@ #include <linux/regulator/fixed.h> #include <linux/mxc_asrc.h> #include <sound/pcm.h> +#include <linux/mfd/mxc-hdmi-core.h> #include <mach/common.h> #include <mach/hardware.h> @@ -913,7 +914,7 @@ static void hdmi_init(int ipu_id, int disp_id) mxc_iomux_set_gpr_register(3, 2, 2, hdmi_mux_setting); /* Set HDMI event as SDMA event2 while Chip version later than TO1.2 */ - if ((mx6q_revision() > IMX_CHIP_REVISION_1_1)) + if (hdmi_SDMA_check()) mxc_iomux_set_gpr_register(0, 0, 1, 1); } diff --git a/arch/arm/mach-mx6/board-mx6q_sabresd.c b/arch/arm/mach-mx6/board-mx6q_sabresd.c index 594dfdff899a..405ae9c015e7 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabresd.c +++ b/arch/arm/mach-mx6/board-mx6q_sabresd.c @@ -56,6 +56,7 @@ #include <linux/mfd/wm8994/pdata.h> #include <linux/mfd/wm8994/gpio.h> #include <sound/wm8962.h> +#include <linux/mfd/mxc-hdmi-core.h> #include <mach/common.h> #include <mach/hardware.h> @@ -1279,7 +1280,7 @@ static void hdmi_init(int ipu_id, int disp_id) mxc_iomux_set_gpr_register(3, 2, 2, hdmi_mux_setting); /* Set HDMI event as SDMA event2 while Chip version later than TO1.2 */ - if ((mx6q_revision() > IMX_CHIP_REVISION_1_1)) + if (hdmi_SDMA_check()) mxc_iomux_set_gpr_register(0, 0, 1, 1); } diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index 28828b9e559c..f2c8595ccb9b 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -278,6 +278,21 @@ static int caam_probe(struct platform_device *pdev) setbits32(&topregs->ctrl.mcr, MCFGR_WDENABLE | (sizeof(dma_addr_t) == sizeof(u64) ? MCFGR_LONG_PTR : 0)); +#ifdef CONFIG_ARCH_MX6 + /* + * ERRATA: mx6 devices have an issue wherein AXI bus transactions + * may not occur in the correct order. This isn't a problem running + * single descriptors, but can be if running multiple concurrent + * descriptors. Reworking the driver to throttle to single requests + * is impractical, thus the workaround is to limit the AXI pipeline + * to a depth of 1 (from it's default of 4) to preclude this situation + * from occurring. + */ + wr_reg32(&topregs->ctrl.mcr, + (rd_reg32(&topregs->ctrl.mcr) & ~(MCFGR_AXIPIPE_MASK)) | + ((1 << MCFGR_AXIPIPE_SHIFT) & MCFGR_AXIPIPE_MASK)); +#endif + /* Set DMA masks according to platform ranging */ if (sizeof(dma_addr_t) == sizeof(u64)) dma_set_mask(dev, DMA_BIT_MASK(36)); diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 3d0612eab0c2..e93c4ea1a1a8 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -760,7 +760,6 @@ static int sdma_set_chan_private_data(struct sdma_channel *sdmac) static int sdma_config_channel(struct sdma_channel *sdmac) { int ret; - struct imx_dma_data *data = sdmac->chan.private; sdma_disable_channel(sdmac); diff --git a/drivers/media/video/mxc/capture/Kconfig b/drivers/media/video/mxc/capture/Kconfig index eaebf2eb2f29..a7b14cb23b9b 100644 --- a/drivers/media/video/mxc/capture/Kconfig +++ b/drivers/media/video/mxc/capture/Kconfig @@ -122,11 +122,23 @@ config MXC_CAMERA_SENSOR_CLK ---help--- If you plan to use the Camera with your MXC system, say Y here. +choice + prompt "Select Overlay Rounting" + default MXC_IPU_DEVICE_QUEUE_SDC + depends on VIDEO_MXC_IPU_CAMERA && FB_MXC_SYNC_PANEL + +config MXC_IPU_DEVICE_QUEUE_SDC + tristate "Queue ipu device for overlay library" + depends on VIDEO_MXC_IPU_CAMERA + ---help--- + Use case CSI->MEM->IPU DEVICE->SDC: + Images from sensor will be frist recieved in memory,then + queue to ipu device for processing if needed, and displaying + it on synchronous display with SDC use case. config MXC_IPU_PRP_VF_SDC - tristate "Pre-Processor VF SDC library" - depends on VIDEO_MXC_IPU_CAMERA && FB_MXC_SYNC_PANEL - default y + bool "Pre-Processor VF SDC library" + depends on VIDEO_MXC_IPU_CAMERA ---help--- Use case PRP_VF_SDC: Preprocessing image from smart sensor for viewfinder and @@ -136,6 +148,8 @@ config MXC_IPU_PRP_VF_SDC MEM -> IC (ROT) -> MEM MEM -> SDC (FG/BG) +endchoice + config MXC_IPU_PRP_ENC tristate "Pre-processor Encoder library" depends on VIDEO_MXC_IPU_CAMERA diff --git a/drivers/media/video/mxc/capture/Makefile b/drivers/media/video/mxc/capture/Makefile index d2499239cd45..04b715352886 100644 --- a/drivers/media/video/mxc/capture/Makefile +++ b/drivers/media/video/mxc/capture/Makefile @@ -1,6 +1,7 @@ ifeq ($(CONFIG_VIDEO_MXC_IPU_CAMERA),y) obj-$(CONFIG_VIDEO_MXC_CAMERA) += mxc_v4l2_capture.o obj-$(CONFIG_MXC_IPU_PRP_VF_SDC) += ipu_prp_vf_sdc.o ipu_prp_vf_sdc_bg.o + obj-$(CONFIG_MXC_IPU_DEVICE_QUEUE_SDC) += ipu_fg_overlay_sdc.o ipu_prp_vf_sdc_bg.o obj-$(CONFIG_MXC_IPU_PRP_ENC) += ipu_prp_enc.o ipu_still.o obj-$(CONFIG_MXC_IPU_CSI_ENC) += ipu_csi_enc.o ipu_still.o endif diff --git a/drivers/media/video/mxc/capture/ipu_fg_overlay_sdc.c b/drivers/media/video/mxc/capture/ipu_fg_overlay_sdc.c new file mode 100644 index 000000000000..05c88c7d409b --- /dev/null +++ b/drivers/media/video/mxc/capture/ipu_fg_overlay_sdc.c @@ -0,0 +1,630 @@ +/* + * Copyright 2004-2012 Freescale Semiconductor, Inc. All Rights Reserved. + */ +/* * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/*! + * @file ipu_foreground_sdc.c + * + * @brief IPU Use case for PRP-VF + * + * @ingroup IPU + */ + +#include <linux/dma-mapping.h> +#include <linux/console.h> +#include <linux/ipu.h> +#include <linux/mxcfb.h> +#include <mach/hardware.h> +#include <mach/mipi_csi2.h> +#include "mxc_v4l2_capture.h" +#include "ipu_prp_sw.h" + +#define OVERLAY_FB_SUPPORT_NONSTD (cpu_is_mx5() || cpu_is_mx6()) + +#ifdef CAMERA_DBG + #define CAMERA_TRACE(x) (printk)x +#else + #define CAMERA_TRACE(x) +#endif + +static int csi_buffer_num, buffer_num; +static u32 csi_mem_bufsize; +static struct ipu_soc *disp_ipu; +static struct fb_info *fbi; +static struct fb_var_screeninfo fbvar; +static u32 vf_out_format; +static void csi_buf_work_func(struct work_struct *work) +{ + int err = 0; + cam_data *cam = + container_of(work, struct _cam_data, csi_work_struct); + + struct ipu_task task; + memset(&task, 0, sizeof(task)); + + if (csi_buffer_num) + task.input.paddr = cam->vf_bufs[0]; + else + task.input.paddr = cam->vf_bufs[1]; + task.input.width = cam->crop_current.width; + task.input.height = cam->crop_current.height; + task.input.format = IPU_PIX_FMT_UYVY; + + if (buffer_num == 0) + task.output.paddr = fbi->fix.smem_start + + (fbi->fix.line_length * fbvar.yres); + else + task.output.paddr = fbi->fix.smem_start; + task.output.width = cam->win.w.width; + task.output.height = cam->win.w.height; + task.output.format = vf_out_format; + task.output.rotate = cam->rotation; +again: + err = ipu_check_task(&task); + if (err != IPU_CHECK_OK) { + if (err > IPU_CHECK_ERR_MIN) { + if (err == IPU_CHECK_ERR_SPLIT_INPUTW_OVER) { + task.input.crop.w -= 8; + goto again; + } + if (err == IPU_CHECK_ERR_SPLIT_INPUTH_OVER) { + task.input.crop.h -= 8; + goto again; + } + if (err == IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER) { + task.output.width -= 8; + task.output.crop.w = task.output.width; + goto again; + } + if (err == IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER) { + task.output.height -= 8; + task.output.crop.h = task.output.height; + goto again; + } + printk(KERN_ERR "check ipu taks fail\n"); + return; + } + printk(KERN_ERR "check ipu taks fail\n"); + return; + } + err = ipu_queue_task(&task); + if (err < 0) + printk(KERN_ERR "queue ipu task error\n"); + ipu_select_buffer(disp_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER, buffer_num); + buffer_num = (buffer_num == 0) ? 1 : 0; +} + +static void get_disp_ipu(cam_data *cam) +{ + if (cam->output > 2) + disp_ipu = ipu_get_soc(1); /* using DISP4 */ + else + disp_ipu = ipu_get_soc(0); +} + +/*! + * csi ENC callback function. + * + * @param irq int irq line + * @param dev_id void * device id + * + * @return status IRQ_HANDLED for handled + */ +static irqreturn_t csi_enc_callback(int irq, void *dev_id) +{ + cam_data *cam = (cam_data *) dev_id; + + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, csi_buffer_num); + if ((cam->crop_current.width != cam->win.w.width) || + (cam->crop_current.height != cam->win.w.height) || + (vf_out_format != IPU_PIX_FMT_UYVY) || + (cam->rotation >= IPU_ROTATE_VERT_FLIP)) + schedule_work(&cam->csi_work_struct); + csi_buffer_num = (csi_buffer_num == 0) ? 1 : 0; + return IRQ_HANDLED; +} + +static int csi_enc_setup(cam_data *cam) +{ + ipu_channel_params_t params; + u32 pixel_fmt; + int err = 0, sensor_protocol = 0; +#ifdef CONFIG_MXC_MIPI_CSI2 + void *mipi_csi2_info; + int ipu_id; + int csi_id; +#endif + + CAMERA_TRACE("In csi_enc_setup\n"); + if (!cam) { + printk(KERN_ERR "cam private is NULL\n"); + return -ENXIO; + } + + memset(¶ms, 0, sizeof(ipu_channel_params_t)); + params.csi_mem.csi = cam->csi; + + sensor_protocol = ipu_csi_get_sensor_protocol(cam->ipu, cam->csi); + switch (sensor_protocol) { + case IPU_CSI_CLK_MODE_GATED_CLK: + case IPU_CSI_CLK_MODE_NONGATED_CLK: + case IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE: + case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR: + case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR: + params.csi_mem.interlaced = false; + break; + case IPU_CSI_CLK_MODE_CCIR656_INTERLACED: + case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR: + case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR: + params.csi_mem.interlaced = true; + break; + default: + printk(KERN_ERR "sensor protocol unsupported\n"); + return -EINVAL; + } + + ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_ENC, cam->csi, true, true); + +#ifdef CONFIG_MXC_MIPI_CSI2 + mipi_csi2_info = mipi_csi2_get_info(); + + if (mipi_csi2_info) { + if (mipi_csi2_get_status(mipi_csi2_info)) { + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info); + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info); + + if (cam->ipu == ipu_get_soc(ipu_id) + && cam->csi == csi_id) { + params.csi_mem.mipi_en = true; + params.csi_mem.mipi_vc = + mipi_csi2_get_virtual_channel(mipi_csi2_info); + params.csi_mem.mipi_id = + mipi_csi2_get_datatype(mipi_csi2_info); + + mipi_csi2_pixelclk_enable(mipi_csi2_info); + } else { + params.csi_mem.mipi_en = false; + params.csi_mem.mipi_vc = 0; + params.csi_mem.mipi_id = 0; + } + } else { + params.csi_mem.mipi_en = false; + params.csi_mem.mipi_vc = 0; + params.csi_mem.mipi_id = 0; + } + } else { + printk(KERN_ERR "Fail to get mipi_csi2_info!\n"); + return -EPERM; + } +#endif + + if (cam->vf_bufs_vaddr[0]) { + dma_free_coherent(0, cam->vf_bufs_size[0], + cam->vf_bufs_vaddr[0], + (dma_addr_t) cam->vf_bufs[0]); + } + if (cam->vf_bufs_vaddr[1]) { + dma_free_coherent(0, cam->vf_bufs_size[1], + cam->vf_bufs_vaddr[1], + (dma_addr_t) cam->vf_bufs[1]); + } + csi_mem_bufsize = cam->crop_current.width * cam->crop_current.height * 2; + cam->vf_bufs_size[0] = PAGE_ALIGN(csi_mem_bufsize); + cam->vf_bufs_vaddr[0] = (void *)dma_alloc_coherent(0, + cam->vf_bufs_size[0], + (dma_addr_t *) & + cam->vf_bufs[0], + GFP_DMA | + GFP_KERNEL); + if (cam->vf_bufs_vaddr[0] == NULL) { + printk(KERN_ERR "Error to allocate vf buffer\n"); + err = -ENOMEM; + goto out_2; + } + cam->vf_bufs_size[1] = PAGE_ALIGN(csi_mem_bufsize); + cam->vf_bufs_vaddr[1] = (void *)dma_alloc_coherent(0, + cam->vf_bufs_size[1], + (dma_addr_t *) & + cam->vf_bufs[1], + GFP_DMA | + GFP_KERNEL); + if (cam->vf_bufs_vaddr[1] == NULL) { + printk(KERN_ERR "Error to allocate vf buffer\n"); + err = -ENOMEM; + goto out_1; + } + pr_debug("vf_bufs %x %x\n", cam->vf_bufs[0], cam->vf_bufs[1]); + + err = ipu_init_channel(cam->ipu, CSI_MEM, ¶ms); + if (err != 0) { + printk(KERN_ERR "ipu_init_channel %d\n", err); + goto out_1; + } + + pixel_fmt = IPU_PIX_FMT_UYVY; + if ((cam->crop_current.width == cam->win.w.width) && + (cam->crop_current.height == cam->win.w.height) && + (vf_out_format == IPU_PIX_FMT_UYVY) && + (cam->rotation < IPU_ROTATE_VERT_FLIP)) { + err = ipu_init_channel_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, + pixel_fmt, cam->crop_current.width, + cam->crop_current.height, + cam->crop_current.width, IPU_ROTATE_NONE, + fbi->fix.smem_start + (fbi->fix.line_length * fbvar.yres), + fbi->fix.smem_start, 0, + cam->offset.u_offset, cam->offset.u_offset); + } else { + err = ipu_init_channel_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, + pixel_fmt, cam->crop_current.width, + cam->crop_current.height, + cam->crop_current.width, IPU_ROTATE_NONE, + cam->vf_bufs[0], cam->vf_bufs[1], 0, + cam->offset.u_offset, cam->offset.u_offset); + } + if (err != 0) { + printk(KERN_ERR "CSI_MEM output buffer\n"); + goto out_1; + } + err = ipu_enable_channel(cam->ipu, CSI_MEM); + if (err < 0) { + printk(KERN_ERR "ipu_enable_channel CSI_MEM\n"); + goto out_1; + } + + csi_buffer_num = 0; + + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, 0); + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, 1); + return err; +out_1: + if (cam->vf_bufs_vaddr[0]) { + dma_free_coherent(0, cam->vf_bufs_size[0], + cam->vf_bufs_vaddr[0], + (dma_addr_t) cam->vf_bufs[0]); + cam->vf_bufs_vaddr[0] = NULL; + cam->vf_bufs[0] = 0; + } + if (cam->vf_bufs_vaddr[1]) { + dma_free_coherent(0, cam->vf_bufs_size[1], + cam->vf_bufs_vaddr[1], + (dma_addr_t) cam->vf_bufs[1]); + cam->vf_bufs_vaddr[1] = NULL; + cam->vf_bufs[1] = 0; + } +out_2: + return err; +} + +/*! + * Enable encoder task + * @param private struct cam_data * mxc capture instance + * + * @return status + */ +static int csi_enc_enabling_tasks(void *private) +{ + cam_data *cam = (cam_data *) private; + int err = 0; + CAMERA_TRACE("IPU:In csi_enc_enabling_tasks\n"); + + ipu_clear_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF); + err = ipu_request_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF, + csi_enc_callback, 0, "Mxc Camera", cam); + if (err != 0) { + printk(KERN_ERR "Error registering CSI0_OUT_EOF irq\n"); + return err; + } + + INIT_WORK(&cam->csi_work_struct, csi_buf_work_func); + + err = csi_enc_setup(cam); + if (err != 0) { + printk(KERN_ERR "csi_enc_setup %d\n", err); + goto out1; + } + + return err; +out1: + ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF, cam); + return err; +} + +/* + * Function definitions + */ + +/*! + * foreground_start - start the vf task + * + * @param private cam_data * mxc v4l2 main structure + * + */ +static int foreground_start(void *private) +{ + cam_data *cam = (cam_data *) private; + int err = 0, i = 0; + short *tmp, color; + + if (!cam) { + printk(KERN_ERR "private is NULL\n"); + return -EIO; + } + + if (cam->overlay_active == true) { + pr_debug("already started.\n"); + return 0; + } + + get_disp_ipu(cam); + + for (i = 0; i < num_registered_fb; i++) { + char *idstr = registered_fb[i]->fix.id; + if (((strcmp(idstr, "DISP3 FG") == 0) && (cam->output < 3)) || + ((strcmp(idstr, "DISP4 FG") == 0) && (cam->output >= 3))) { + fbi = registered_fb[i]; + break; + } + } + + if (fbi == NULL) { + printk(KERN_ERR "DISP FG fb not found\n"); + return -EPERM; + } + + fbvar = fbi->var; + + /* Store the overlay frame buffer's original std */ + cam->fb_origin_std = fbvar.nonstd; + + if (OVERLAY_FB_SUPPORT_NONSTD) { + /* Use DP to do CSC so that we can get better performance */ + vf_out_format = IPU_PIX_FMT_UYVY; + fbvar.nonstd = vf_out_format; + color = 0x80; + } else { + vf_out_format = IPU_PIX_FMT_RGB565; + fbvar.nonstd = 0; + color = 0x0; + } + + fbvar.bits_per_pixel = 16; + fbvar.xres = fbvar.xres_virtual = cam->win.w.width; + fbvar.yres = cam->win.w.height; + fbvar.yres_virtual = cam->win.w.height * 2; + fbvar.yoffset = 0; + fbvar.accel_flags = FB_ACCEL_DOUBLE_FLAG; + fbvar.activate |= FB_ACTIVATE_FORCE; + fb_set_var(fbi, &fbvar); + + ipu_disp_set_window_pos(disp_ipu, MEM_FG_SYNC, cam->win.w.left, + cam->win.w.top); + + /* Fill black color for framebuffer */ + tmp = (short *) fbi->screen_base; + for (i = 0; i < (fbi->fix.line_length * fbi->var.yres)/2; + i++, tmp++) + *tmp = color; + + console_lock(); + fb_blank(fbi, FB_BLANK_UNBLANK); + console_unlock(); + + /* correct display ch buffer address */ + ipu_update_channel_buffer(disp_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER, + 0, fbi->fix.smem_start + + (fbi->fix.line_length * fbvar.yres)); + ipu_update_channel_buffer(disp_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER, + 1, fbi->fix.smem_start); + + err = csi_enc_enabling_tasks(cam); + if (err != 0) { + printk(KERN_ERR "Error csi enc enable fail\n"); + return err; + } + + cam->overlay_active = true; + return err; + +} + +/*! + * foreground_stop - stop the vf task + * + * @param private cam_data * mxc v4l2 main structure + * + */ +static int foreground_stop(void *private) +{ + cam_data *cam = (cam_data *) private; + int err = 0, i = 0; + struct fb_info *fbi = NULL; + struct fb_var_screeninfo fbvar; + +#ifdef CONFIG_MXC_MIPI_CSI2 + void *mipi_csi2_info; + int ipu_id; + int csi_id; +#endif + + if (cam->overlay_active == false) + return 0; + + ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF, cam); + + err = ipu_disable_channel(cam->ipu, CSI_MEM, true); + + ipu_uninit_channel(cam->ipu, CSI_MEM); + + csi_buffer_num = 0; + buffer_num = 0; + + for (i = 0; i < num_registered_fb; i++) { + char *idstr = registered_fb[i]->fix.id; + if (((strcmp(idstr, "DISP3 FG") == 0) && (cam->output < 3)) || + ((strcmp(idstr, "DISP4 FG") == 0) && (cam->output >= 3))) { + fbi = registered_fb[i]; + break; + } + } + + if (fbi == NULL) { + printk(KERN_ERR "DISP FG fb not found\n"); + return -EPERM; + } + + console_lock(); + fb_blank(fbi, FB_BLANK_POWERDOWN); + console_unlock(); + + /* Set the overlay frame buffer std to what it is used to be */ + fbvar = fbi->var; + fbvar.accel_flags = FB_ACCEL_TRIPLE_FLAG; + fbvar.nonstd = cam->fb_origin_std; + fbvar.activate |= FB_ACTIVATE_FORCE; + fb_set_var(fbi, &fbvar); + +#ifdef CONFIG_MXC_MIPI_CSI2 + mipi_csi2_info = mipi_csi2_get_info(); + + if (mipi_csi2_info) { + if (mipi_csi2_get_status(mipi_csi2_info)) { + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info); + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info); + + if (cam->ipu == ipu_get_soc(ipu_id) + && cam->csi == csi_id) + mipi_csi2_pixelclk_disable(mipi_csi2_info); + } + } else { + printk(KERN_ERR "Fail to get mipi_csi2_info!\n"); + return -EPERM; + } +#endif + + ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_VF, cam->csi, false, false); + + if (cam->vf_bufs_vaddr[0]) { + dma_free_coherent(0, cam->vf_bufs_size[0], + cam->vf_bufs_vaddr[0], + (dma_addr_t) cam->vf_bufs[0]); + cam->vf_bufs_vaddr[0] = NULL; + cam->vf_bufs[0] = 0; + } + if (cam->vf_bufs_vaddr[1]) { + dma_free_coherent(0, cam->vf_bufs_size[1], + cam->vf_bufs_vaddr[1], + (dma_addr_t) cam->vf_bufs[1]); + cam->vf_bufs_vaddr[1] = NULL; + cam->vf_bufs[1] = 0; + } + + cam->overlay_active = false; + return err; +} + +/*! + * Enable csi + * @param private struct cam_data * mxc capture instance + * + * @return status + */ +static int foreground_enable_csi(void *private) +{ + cam_data *cam = (cam_data *) private; + + return ipu_enable_csi(cam->ipu, cam->csi); +} + +/*! + * Disable csi + * @param private struct cam_data * mxc capture instance + * + * @return status + */ +static int foreground_disable_csi(void *private) +{ + cam_data *cam = (cam_data *) private; + + return ipu_disable_csi(cam->ipu, cam->csi); +} + +/*! + * function to select foreground as the working path + * + * @param private cam_data * mxc v4l2 main structure + * + * @return status + */ +int foreground_sdc_select(void *private) +{ + cam_data *cam; + int err = 0; + if (private) { + cam = (cam_data *) private; + cam->vf_start_sdc = foreground_start; + cam->vf_stop_sdc = foreground_stop; + cam->vf_enable_csi = foreground_enable_csi; + cam->vf_disable_csi = foreground_disable_csi; + cam->overlay_active = false; + } else + err = -EIO; + + return err; +} + +/*! + * function to de-select foreground as the working path + * + * @param private cam_data * mxc v4l2 main structure + * + * @return int + */ +int foreground_sdc_deselect(void *private) +{ + cam_data *cam; + + if (private) { + cam = (cam_data *) private; + cam->vf_start_sdc = NULL; + cam->vf_stop_sdc = NULL; + cam->vf_enable_csi = NULL; + cam->vf_disable_csi = NULL; + } + return 0; +} + +/*! + * Init viewfinder task. + * + * @return Error code indicating success or failure + */ +__init int foreground_sdc_init(void) +{ + return 0; +} + +/*! + * Deinit viewfinder task. + * + * @return Error code indicating success or failure + */ +void __exit foreground_sdc_exit(void) +{ +} + +module_init(foreground_sdc_init); +module_exit(foreground_sdc_exit); + +EXPORT_SYMBOL(foreground_sdc_select); +EXPORT_SYMBOL(foreground_sdc_deselect); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("IPU PRP VF SDC Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/mxc/capture/ipu_prp_sw.h b/drivers/media/video/mxc/capture/ipu_prp_sw.h index 85dd102471f8..7cdc521711cb 100644 --- a/drivers/media/video/mxc/capture/ipu_prp_sw.h +++ b/drivers/media/video/mxc/capture/ipu_prp_sw.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2004-2012 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -26,9 +26,14 @@ int csi_enc_select(void *private); int csi_enc_deselect(void *private); int prp_enc_select(void *private); int prp_enc_deselect(void *private); +#ifdef CONFIG_MXC_IPU_PRP_VF_SDC int prp_vf_sdc_select(void *private); -int prp_vf_sdc_select_bg(void *private); int prp_vf_sdc_deselect(void *private); +#else +int foreground_sdc_select(void *private); +int foreground_sdc_deselect(void *private); +#endif +int prp_vf_sdc_select_bg(void *private); int prp_vf_sdc_deselect_bg(void *private); int prp_still_select(void *private); int prp_still_deselect(void *private); diff --git a/drivers/media/video/mxc/capture/mxc_v4l2_capture.c b/drivers/media/video/mxc/capture/mxc_v4l2_capture.c index fa1004365b8f..9e9bcc314ca5 100644 --- a/drivers/media/video/mxc/capture/mxc_v4l2_capture.c +++ b/drivers/media/video/mxc/capture/mxc_v4l2_capture.c @@ -649,7 +649,11 @@ static int start_preview(cam_data *cam) pr_debug("MVC: start_preview\n"); if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_OVERLAY) + #ifdef CONFIG_MXC_IPU_PRP_VF_SDC err = prp_vf_sdc_select(cam); + #else + err = foreground_sdc_select(cam); + #endif else if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_PRIMARY) err = prp_vf_sdc_select_bg(cam); if (err != 0) @@ -704,7 +708,11 @@ static int stop_preview(cam_data *cam) } if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_OVERLAY) + #ifdef CONFIG_MXC_IPU_PRP_VF_SDC err = prp_vf_sdc_deselect(cam); + #else + err = foreground_sdc_deselect(cam); + #endif else if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_PRIMARY) err = prp_vf_sdc_deselect_bg(cam); @@ -1140,11 +1148,14 @@ static int mxc_v4l2_s_ctrl(cam_data *cam, struct v4l2_control *c) default: ret = -EINVAL; } - + #ifdef CONFIG_MXC_IPU_PRP_VF_SDC if (c->id == V4L2_CID_MXC_VF_ROT) cam->vf_rotation = tmp_rotation; else cam->rotation = tmp_rotation; + #else + cam->rotation = tmp_rotation; + #endif break; case V4L2_CID_HUE: diff --git a/drivers/media/video/mxc/capture/mxc_v4l2_capture.h b/drivers/media/video/mxc/capture/mxc_v4l2_capture.h index dcb90a9f4ce5..27f8a78a93b3 100644 --- a/drivers/media/video/mxc/capture/mxc_v4l2_capture.h +++ b/drivers/media/video/mxc/capture/mxc_v4l2_capture.h @@ -142,6 +142,7 @@ typedef struct _cam_data { int output; struct fb_info *overlay_fb; int fb_origin_std; + struct work_struct csi_work_struct; /* v4l2 format */ struct v4l2_format v2f; diff --git a/drivers/mfd/mxc-hdmi-core.c b/drivers/mfd/mxc-hdmi-core.c index 6ccf5504a034..332843661d98 100644 --- a/drivers/mfd/mxc-hdmi-core.c +++ b/drivers/mfd/mxc-hdmi-core.c @@ -40,6 +40,7 @@ #include "../mxc/ipu3/ipu_prv.h" #include <linux/mfd/mxc-hdmi-core.h> #include <linux/fsl_devices.h> +#include <mach/hardware.h> struct mxc_hdmi_data { struct platform_device *pdev; @@ -397,6 +398,12 @@ static void hdmi_set_clk_regenerator(void) hdmi_set_clock_regenerator_n(clk_n); } +unsigned int hdmi_SDMA_check(void) +{ + return (mx6q_revision() > IMX_CHIP_REVISION_1_1) || + (mx6dl_revision() > IMX_CHIP_REVISION_1_0); +} + /* Need to run this before phy is enabled the first time to prevent * overflow condition in HDMI_IH_FC_STAT2 */ void hdmi_init_clk_regenerator(void) diff --git a/drivers/mxc/ipu3/ipu_disp.c b/drivers/mxc/ipu3/ipu_disp.c index 0c09256b4322..7a344319e28a 100644 --- a/drivers/mxc/ipu3/ipu_disp.c +++ b/drivers/mxc/ipu3/ipu_disp.c @@ -909,6 +909,9 @@ void _ipu_dp_dc_enable(struct ipu_soc *ipu, ipu_channel_t channel) reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8; ipu_cm_write(ipu, reg, IPU_SRM_PRI2); return; + } else if (channel == MEM_BG_SYNC) { + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8; + ipu_cm_write(ipu, reg, IPU_SRM_PRI2); } di = ipu->dc_di_assignment[dc_chan]; @@ -2014,8 +2017,16 @@ int32_t _ipu_disp_set_window_pos(struct ipu_soc *ipu, ipu_channel_t channel, ipu_dp_write(ipu, (x_pos << 16) | y_pos, DP_FG_POS(flow)); - reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8; - ipu_cm_write(ipu, reg, IPU_SRM_PRI2); + if (ipu_is_channel_busy(ipu, channel)) { + /* controled by FSU if channel enabled */ + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) & (~(0x3 << dp_srm_shift)); + reg |= (0x1 << dp_srm_shift); + ipu_cm_write(ipu, reg, IPU_SRM_PRI2); + } else { + /* disable auto swap, controled by MCU if channel disabled */ + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) & (~(0x3 << dp_srm_shift)); + ipu_cm_write(ipu, reg, IPU_SRM_PRI2); + } return 0; } diff --git a/drivers/mxc/vpu/mxc_vpu.c b/drivers/mxc/vpu/mxc_vpu.c index 26fc95a69574..890456802331 100644 --- a/drivers/mxc/vpu/mxc_vpu.c +++ b/drivers/mxc/vpu/mxc_vpu.c @@ -821,6 +821,10 @@ static int vpu_resume(struct platform_device *pdev) clk_enable(vpu_clk); + /* reset VPU in case of voltage change */ + if (vpu_plat->reset) + vpu_plat->reset(); + pc = READ_REG(BIT_CUR_PC); if (pc) { clk_disable(vpu_clk); diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 467b5355de89..920b8a01f9cb 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -226,6 +226,26 @@ static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv, (reg_esr & FLEXCAN_ESR_ERR_BUS); } +static inline void flexcan_enter_stop(struct flexcan_priv *priv) +{ + /* enable stop request for wakeup */ + if (priv->version >= FLEXCAN_VER_10_0_12) + /* CAN1/CAN2_STOP_REQ bit 28/29 in group 13 */ + mxc_iomux_set_gpr_register(13, 28 + priv->id, 1, 1); + + udelay(10); +} + +static inline void flexcan_exit_stop(struct flexcan_priv *priv) +{ + /* remove stop request */ + if (priv->version >= FLEXCAN_VER_10_0_12) + /* CAN1/CAN2_STOP_REQ bit 28/29 in group 13 */ + mxc_iomux_set_gpr_register(13, 28 + priv->id, 1, 0); + + udelay(10); +} + static inline void flexcan_chip_enable(struct flexcan_priv *priv) { struct flexcan_regs __iomem *regs = priv->base; @@ -579,10 +599,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) writel(FLEXCAN_ESR_ERR_INT, ®s->esr); /* ACK err IRQ */ if (reg_esr & FLEXCAN_ESR_WAK_INT) { - /* first clear stop request then wakeup irq status */ - if (priv->version >= FLEXCAN_VER_10_0_12) - /* CAN1/CAN2_STOP_REQ bit 28/29 in group 13 */ - mxc_iomux_set_gpr_register(13, 28 + priv->id, 1, 0); + flexcan_exit_stop(priv); writel(FLEXCAN_ESR_WAK_INT, ®s->esr); } @@ -1074,18 +1091,16 @@ static int flexcan_suspend(struct platform_device *pdev, pm_message_t state) if (netif_running(dev)) { netif_stop_queue(dev); netif_device_detach(dev); - } - priv->can.state = CAN_STATE_SLEEPING; + /* enter stop mode if device is up */ + flexcan_enter_stop(priv); - /* enable stop request for wakeup */ - if (priv->version >= FLEXCAN_VER_10_0_12) - /* CAN1/CAN2_STOP_REQ bit 28/29 in group 13 */ - mxc_iomux_set_gpr_register(13, 28 + priv->id, 1, 1); + ret = irq_set_irq_wake(dev->irq, 1); + if (ret) + return ret; + } - ret = irq_set_irq_wake(dev->irq, 1); - if (ret) - return ret; + priv->can.state = CAN_STATE_SLEEPING; return 0; } @@ -1096,13 +1111,15 @@ static int flexcan_resume(struct platform_device *pdev) struct flexcan_priv *priv = netdev_priv(dev); int ret; - ret = irq_set_irq_wake(dev->irq, 0); - if (ret) - return ret; - priv->can.state = CAN_STATE_ERROR_ACTIVE; if (netif_running(dev)) { + ret = irq_set_irq_wake(dev->irq, 0); + if (ret) + return ret; + + flexcan_exit_stop(priv); + netif_device_attach(dev); netif_start_queue(dev); } diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 1ae6cb0f0210..b1fa4647f911 100755 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -156,6 +156,13 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address"); #define PKT_MINBUF_SIZE 64 #define PKT_MAXBLR_SIZE 1520 +/* Pause frame feild and FIFO threshold */ +#define FEC_ENET_FCE (1 << 5) +#define FEC_ENET_RSEM_V 0x84 +#define FEC_ENET_RSFL_V 16 +#define FEC_ENET_RAEM_V 0x8 +#define FEC_ENET_RAFL_V 0x8 +#define FEC_ENET_OPD_V 0xFFF0 /* * The 5270/5271/5280/5282/532x RX control register also contains maximum frame @@ -1449,6 +1456,28 @@ static const struct net_device_ops fec_netdev_ops = { #endif }; +/* Init TX buffer descriptors + */ +static void fec_enet_txbd_init(struct net_device *dev) +{ + struct fec_enet_private *fep = netdev_priv(dev); + struct bufdesc *bdp; + int i; + + /* ...and the same for transmit */ + bdp = fep->tx_bd_base; + for (i = 0; i < TX_RING_SIZE; i++) { + + /* Initialize the BD for every fragment in the page. */ + bdp->cbd_sc = 0; + bdp++; + } + + /* Set the last buffer to wrap */ + bdp--; + bdp->cbd_sc |= BD_SC_WRAP; +} + /* * XXX: We need to clean up on failure exits here. * @@ -1505,19 +1534,8 @@ static int fec_enet_init(struct net_device *ndev) bdp--; bdp->cbd_sc |= BD_SC_WRAP; - /* ...and the same for transmit */ - bdp = fep->tx_bd_base; - for (i = 0; i < TX_RING_SIZE; i++) { - - /* Initialize the BD for every fragment in the page. */ - bdp->cbd_sc = 0; - bdp->cbd_bufaddr = 0; - bdp++; - } - - /* Set the last buffer to wrap */ - bdp--; - bdp->cbd_sc |= BD_SC_WRAP; + /* Init transmit descriptors */ + fec_enet_txbd_init(ndev); fec_restart(ndev, 0); @@ -1568,6 +1586,8 @@ fec_restart(struct net_device *dev, int duplex) writel(fep->bd_dma, fep->hwp + FEC_R_DES_START); writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE, fep->hwp + FEC_X_DES_START); + /* Reinit transmit descriptors */ + fec_enet_txbd_init(dev); fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; fep->cur_rx = fep->rx_bd_base; @@ -1617,6 +1637,16 @@ fec_restart(struct net_device *dev, int duplex) else val |= (1 << 9); + /* Enable pause frame + * ENET pause frame has two issues as ticket TKT116501 + * The issues have been fixed on Rigel TO1.1 and Arik TO1.2 + */ + if ((cpu_is_mx6q() && + (mx6q_revision() >= IMX_CHIP_REVISION_1_2)) || + (cpu_is_mx6dl() && + (mx6dl_revision() >= IMX_CHIP_REVISION_1_1))) + val |= FEC_ENET_FCE; + writel(val, fep->hwp + FEC_R_CNTRL); } @@ -1670,6 +1700,23 @@ fec_restart(struct net_device *dev, int duplex) fep->phy_dev->speed == SPEED_1000) val |= (0x1 << 5); + /* RX FIFO threshold setting for ENET pause frame feature + * Only set the parameters after ticket TKT116501 fixed. + * The issue has been fixed on Rigel TO1.1 and Arik TO1.2 + */ + if ((cpu_is_mx6q() && + (mx6q_revision() >= IMX_CHIP_REVISION_1_2)) || + (cpu_is_mx6dl() && + (mx6dl_revision() >= IMX_CHIP_REVISION_1_1))) { + writel(FEC_ENET_RSEM_V, fep->hwp + FEC_R_FIFO_RSEM); + writel(FEC_ENET_RSFL_V, fep->hwp + FEC_R_FIFO_RSFL); + writel(FEC_ENET_RAEM_V, fep->hwp + FEC_R_FIFO_RAEM); + writel(FEC_ENET_RAFL_V, fep->hwp + FEC_R_FIFO_RAFL); + + /* OPD */ + writel(FEC_ENET_OPD_V, fep->hwp + FEC_OPD); + } + if (cpu_is_mx6q() || cpu_is_mx6dl()) { /* enable endian swap */ val |= (0x1 << 8); diff --git a/drivers/net/fec.h b/drivers/net/fec.h index 1c4063c05ec2..0c26c6c2db95 100644 --- a/drivers/net/fec.h +++ b/drivers/net/fec.h @@ -45,6 +45,10 @@ #define FEC_R_DES_START 0x180 /* Receive descriptor ring */ #define FEC_X_DES_START 0x184 /* Transmit descriptor ring */ #define FEC_R_BUFF_SIZE 0x188 /* Maximum receive buff size */ +#define FEC_R_FIFO_RSFL 0x190 /* Receive FIFO section full threshold */ +#define FEC_R_FIFO_RSEM 0x194 /* Receive FIFO section empty threshold */ +#define FEC_R_FIFO_RAEM 0x198 /* Receive FIFO almost empty threshold */ +#define FEC_R_FIFO_RAFL 0x19c /* Receive FIFO almost full threshold */ #define FEC_MIIGSK_CFGR 0x300 /* MIIGSK Configuration reg */ #define FEC_MIIGSK_ENR 0x308 /* MIIGSK Enable reg */ diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 2a106a94cdd0..2a1db8c6d231 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2394,11 +2394,11 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) */ tty_dev = tty_register_device(drv->tty_driver, uport->line, uport->dev); if (likely(!IS_ERR(tty_dev))) { - device_init_wakeup(tty_dev, 1); - device_set_wakeup_enable(tty_dev, 0); - } else + device_set_wakeup_capable(tty_dev, 1); + } else { printk(KERN_ERR "Cannot register tty device on line %d\n", uport->line); + } /* * Ensure UPF_DEAD is not set. diff --git a/drivers/video/mxc/mxc_epdc_fb.c b/drivers/video/mxc/mxc_epdc_fb.c index f78200887054..0b3923c2cea6 100644 --- a/drivers/video/mxc/mxc_epdc_fb.c +++ b/drivers/video/mxc/mxc_epdc_fb.c @@ -857,6 +857,7 @@ static void epdc_init_settings(struct mxc_epdc_fb_data *fb_data) /* Enable clocks to access EPDC regs */ clk_enable(fb_data->epdc_clk_axi); + clk_enable(fb_data->epdc_clk_pix); /* Reset */ __raw_writel(EPDC_CTRL_SFTRST, EPDC_CTRL_SET); @@ -1027,6 +1028,7 @@ static void epdc_init_settings(struct mxc_epdc_fb_data *fb_data) /* Disable clock */ clk_disable(fb_data->epdc_clk_axi); + clk_disable(fb_data->epdc_clk_pix); } static void epdc_powerup(struct mxc_epdc_fb_data *fb_data) diff --git a/drivers/video/mxc_hdmi.c b/drivers/video/mxc_hdmi.c index ce8f1ffd6645..999e3b157211 100644 --- a/drivers/video/mxc_hdmi.c +++ b/drivers/video/mxc_hdmi.c @@ -2113,6 +2113,9 @@ static int mxc_hdmi_disp_init(struct mxc_dispdrv_handle *disp, hdmi->dft_mode_set = false; + /* Setting HDMI default to blank state */ + hdmi->blank = FB_BLANK_POWERDOWN; + setting->dev_id = mxc_hdmi_ipu_id; setting->disp_id = mxc_hdmi_disp_id; setting->if_fmt = IPU_PIX_FMT_RGB24; diff --git a/include/linux/mfd/mxc-hdmi-core.h b/include/linux/mfd/mxc-hdmi-core.h index 6ed08d31b02c..8ddea5a040cc 100644 --- a/include/linux/mfd/mxc-hdmi-core.h +++ b/include/linux/mfd/mxc-hdmi-core.h @@ -49,5 +49,6 @@ extern int mxc_hdmi_disp_id; void hdmi_set_registered(int registered); int hdmi_get_registered(void); +unsigned int hdmi_SDMA_check(void); #endif diff --git a/sound/soc/imx/imx-hdmi-dma.c b/sound/soc/imx/imx-hdmi-dma.c index 443ff1096946..18e3a016cca8 100644 --- a/sound/soc/imx/imx-hdmi-dma.c +++ b/sound/soc/imx/imx-hdmi-dma.c @@ -993,8 +993,7 @@ static int hdmi_dma_hw_free(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct imx_hdmi_dma_runtime_data *params = runtime->private_data; - if ((mx6q_revision() > IMX_CHIP_REVISION_1_1) && - (params->dma_channel)) { + if (hdmi_SDMA_check() && (params->dma_channel)) { dma_release_channel(params->dma_channel); params->dma_channel = NULL; } @@ -1037,7 +1036,7 @@ static int hdmi_dma_hw_params(struct snd_pcm_substream *substream, } rtd->dma_period_bytes = rtd->period_bytes * rtd->buffer_ratio; - if ((mx6q_revision() > IMX_CHIP_REVISION_1_1)) { + if (hdmi_SDMA_check()) { rtd->sdma_params.buffer_num = rtd->periods; rtd->sdma_params.phyaddr = rtd->phy_hdmi_sdma_t; @@ -1096,7 +1095,7 @@ static int hdmi_dma_trigger(struct snd_pcm_substream *substream, int cmd) hdmi_dma_start(); hdmi_dma_irq_mask(0); hdmi_set_dma_mode(1); - if ((mx6q_revision() > IMX_CHIP_REVISION_1_1)) + if (hdmi_SDMA_check()) dmaengine_submit(rtd->desc); break; @@ -1107,7 +1106,7 @@ static int hdmi_dma_trigger(struct snd_pcm_substream *substream, int cmd) hdmi_dma_stop(); hdmi_set_dma_mode(0); hdmi_dma_irq_mask(1); - if ((mx6q_revision() > IMX_CHIP_REVISION_1_1)) + if (hdmi_SDMA_check()) dmaengine_terminate_all(rtd->dma_channel); break; @@ -1155,7 +1154,7 @@ static void hdmi_dma_irq_enable(struct imx_hdmi_dma_runtime_data *rtd) spin_lock_irqsave(&hdmi_dma_priv->irq_lock, flags); hdmi_dma_clear_irq_status(0xff); - if ((mx6q_revision() > IMX_CHIP_REVISION_1_1)) + if (hdmi_SDMA_check()) hdmi_dma_irq_mute(1); else hdmi_dma_irq_mute(0); @@ -1335,7 +1334,7 @@ static int __devinit imx_soc_platform_probe(struct platform_device *pdev) if (hdmi_dma_priv == NULL) return -ENOMEM; - if ((mx6q_revision() > IMX_CHIP_REVISION_1_1)) { + if (hdmi_SDMA_check()) { /*To alloc a buffer non cacheable for hdmi script use*/ hdmi_dma_priv->hdmi_sdma_t = dma_alloc_coherent(NULL, @@ -1365,7 +1364,7 @@ static int __devinit imx_soc_platform_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Unable to get HDMI ahb clk: %d\n", ret); goto e_clk_get2; } - if ((mx6q_revision() <= IMX_CHIP_REVISION_1_1)) { + if (!hdmi_SDMA_check()) { if (request_irq(hdmi_dma_priv->irq, hdmi_dma_isr, IRQF_SHARED, "hdmi dma", hdmi_dma_priv)) { dev_err(&pdev->dev, @@ -1395,7 +1394,7 @@ e_clk_get1: static int __devexit imx_soc_platform_remove(struct platform_device *pdev) { free_irq(hdmi_dma_priv->irq, hdmi_dma_priv); - if ((mx6q_revision() > IMX_CHIP_REVISION_1_1)) { + if (hdmi_SDMA_check()) { dma_free_coherent(NULL, sizeof(struct hdmi_sdma_script_data), hdmi_dma_priv->hdmi_sdma_t, |