summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorXinyu Chen <xinyu.chen@freescale.com>2012-08-30 16:37:48 +0800
committerXinyu Chen <xinyu.chen@freescale.com>2012-08-30 16:37:48 +0800
commita4d0bf3916d2f75a2977869e804d5f4fff4d1d3e (patch)
tree75c1f9f8074170da088e685b03bc40e0de67fe8b /drivers
parent65745dd4b7f80711d03dce5529fc501162428c53 (diff)
parent4d38f38359c287d1000bbef7731a03e32b8d9ca2 (diff)
Merge remote branch 'fsl-linux-sdk/imx_3.0.35_12.09.01' into imx_3.0.35_android
Conflicts: arch/arm/mach-mx6/board-mx6q_sabresd.c arch/arm/mach-mx6/board-mx6sl_arm2.c arch/arm/mach-mx6/bus_freq.c arch/arm/mach-mx6/cpu_op-mx6.c arch/arm/plat-mxc/cpufreq.c
Diffstat (limited to 'drivers')
-rw-r--r--drivers/dma/pxp/pxp_dma_v2.c21
-rw-r--r--drivers/media/video/Kconfig2
-rw-r--r--drivers/media/video/mxc/capture/Makefile2
-rw-r--r--drivers/media/video/mxc/capture/ipu_bg_overlay_sdc.c551
-rw-r--r--drivers/media/video/mxc/capture/ipu_fg_overlay_sdc.c2
-rw-r--r--drivers/media/video/mxc/capture/ipu_prp_sw.h6
-rw-r--r--drivers/media/video/mxc/capture/mxc_v4l2_capture.c8
-rw-r--r--drivers/media/video/mxc/capture/ov5642.c8
-rw-r--r--drivers/media/video/mxc/output/mxc_pxp_v4l2.c15
-rw-r--r--drivers/media/video/mxc/output/mxc_vout.c2
-rw-r--r--drivers/mfd/mxc-hdmi-core.c116
-rw-r--r--drivers/mxc/asrc/mxc_asrc.c36
-rw-r--r--drivers/mxc/ipu3/ipu_capture.c2
-rw-r--r--drivers/mxc/ipu3/ipu_common.c168
-rw-r--r--drivers/mxc/ipu3/ipu_device.c110
-rw-r--r--drivers/mxc/thermal/cooling.c2
-rw-r--r--drivers/mxc/thermal/thermal.c4
-rw-r--r--drivers/mxc/vpu/Kconfig9
-rwxr-xr-xdrivers/usb/gadget/arcotg_udc.c17
-rwxr-xr-xdrivers/usb/host/ehci-arc.c20
-rw-r--r--drivers/video/mxc/ldb.c7
-rw-r--r--drivers/video/mxc/mxc_ipuv3_fb.c6
-rw-r--r--drivers/video/mxc_hdmi.c29
23 files changed, 865 insertions, 278 deletions
diff --git a/drivers/dma/pxp/pxp_dma_v2.c b/drivers/dma/pxp/pxp_dma_v2.c
index ceb72edbd39e..87b8f558ae8c 100644
--- a/drivers/dma/pxp/pxp_dma_v2.c
+++ b/drivers/dma/pxp/pxp_dma_v2.c
@@ -339,7 +339,14 @@ static void pxp_set_outbuf(struct pxps *pxp)
BF_PXP_OUT_LRC_Y(out_params->height - 1),
pxp->base + HW_PXP_OUT_LRC);
- __raw_writel(out_params->stride, pxp->base + HW_PXP_OUT_PITCH);
+ if (out_params->pixel_fmt == PXP_PIX_FMT_RGB24)
+ __raw_writel(out_params->stride << 2,
+ pxp->base + HW_PXP_OUT_PITCH);
+ else if (out_params->pixel_fmt == PXP_PIX_FMT_RGB565)
+ __raw_writel(out_params->stride << 1,
+ pxp->base + HW_PXP_OUT_PITCH);
+ else
+ __raw_writel(out_params->stride, pxp->base + HW_PXP_OUT_PITCH);
}
static void pxp_set_s0colorkey(struct pxps *pxp)
@@ -390,6 +397,13 @@ static void pxp_set_oln(int layer_no, struct pxps *pxp)
__raw_writel(BF_PXP_OUT_AS_LRC_X(olparams_data->width) |
BF_PXP_OUT_AS_LRC_Y(olparams_data->height),
pxp->base + HW_PXP_OUT_AS_LRC);
+
+ if (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB24)
+ __raw_writel(olparams_data->width << 2,
+ pxp->base + HW_PXP_AS_PITCH);
+ else
+ __raw_writel(olparams_data->width << 1,
+ pxp->base + HW_PXP_AS_PITCH);
}
static void pxp_set_olparam(int layer_no, struct pxps *pxp)
@@ -704,8 +718,9 @@ static void pxp_set_s0buf(struct pxps *pxp)
__raw_writel(V, pxp->base + HW_PXP_PS_VBUF);
}
- /* TODO: only support RGB565, Y8, Y4 */
- if (s0_params->pixel_fmt == PXP_PIX_FMT_GREY)
+ /* TODO: only support RGB565, Y8, Y4, YUV420 */
+ if (s0_params->pixel_fmt == PXP_PIX_FMT_GREY ||
+ s0_params->pixel_fmt == PXP_PIX_FMT_YUV420P)
__raw_writel(s0_params->width, pxp->base + HW_PXP_PS_PITCH);
else if (s0_params->pixel_fmt == PXP_PIX_FMT_GY04)
__raw_writel(s0_params->width >> 1, pxp->base + HW_PXP_PS_PITCH);
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index a01553aa0ffc..e0b1633ef218 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -651,7 +651,7 @@ config VIDEO_MXS_PXP
config VIDEO_MXC_PXP_V4L2
tristate "MXC PxP V4L2 driver"
- depends on VIDEO_DEV && VIDEO_V4L2 && ARCH_MX5
+ depends on VIDEO_DEV && VIDEO_V4L2 && (ARCH_MX5 || SOC_IMX6SL)
select VIDEOBUF_DMA_CONTIG
---help---
This is a video4linux driver for the Freescale PxP
diff --git a/drivers/media/video/mxc/capture/Makefile b/drivers/media/video/mxc/capture/Makefile
index 04b715352886..bdef5b401485 100644
--- a/drivers/media/video/mxc/capture/Makefile
+++ b/drivers/media/video/mxc/capture/Makefile
@@ -1,7 +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_DEVICE_QUEUE_SDC) += ipu_fg_overlay_sdc.o ipu_bg_overlay_sdc.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_bg_overlay_sdc.c b/drivers/media/video/mxc/capture/ipu_bg_overlay_sdc.c
new file mode 100644
index 000000000000..1a0229720640
--- /dev/null
+++ b/drivers/media/video/mxc/capture/ipu_bg_overlay_sdc.c
@@ -0,0 +1,551 @@
+
+/*
+ * 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_bg_overlay_sdc_bg.c
+ *
+ * @brief IPU Use case for PRP-VF back-ground
+ *
+ * @ingroup IPU
+ */
+#include <linux/dma-mapping.h>
+#include <linux/fb.h>
+#include <linux/ipu.h>
+#include <mach/mipi_csi2.h>
+#include "mxc_v4l2_capture.h"
+#include "ipu_prp_sw.h"
+
+static int csi_buffer_num;
+static u32 bpp, csi_mem_bufsize = 3;
+static u32 out_format;
+static struct ipu_soc *disp_ipu;
+static u32 offset;
+
+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;
+
+ task.output.paddr = offset;
+ task.output.width = cam->overlay_fb->var.xres;
+ task.output.height = cam->overlay_fb->var.yres;
+ task.output.format = out_format;
+ task.output.rotate = cam->rotation;
+ task.output.crop.pos.x = cam->win.w.left;
+ task.output.crop.pos.y = cam->win.w.top;
+ if (cam->win.w.width > 1024 || cam->win.w.height > 1024) {
+ task.output.crop.w = cam->overlay_fb->var.xres;
+ task.output.crop.h = cam->overlay_fb->var.yres;
+ } else {
+ task.output.crop.w = cam->win.w.width;
+ task.output.crop.h = cam->win.w.height;
+ }
+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");
+}
+
+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);
+ 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
+
+ if (!cam) {
+ printk(KERN_ERR "cam private is NULL\n");
+ return -ENXIO;
+ }
+
+ memset(&params, 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, &params);
+ if (err != 0) {
+ printk(KERN_ERR "ipu_init_channel %d\n", err);
+ goto out_1;
+ }
+
+ pixel_fmt = IPU_PIX_FMT_UYVY;
+ 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;
+
+ 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;
+}
+
+/*!
+ * bg_overlay_start - start the overlay task
+ *
+ * @param private cam_data * mxc v4l2 main structure
+ *
+ */
+static int bg_overlay_start(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+ int err = 0;
+
+ if (!cam) {
+ printk(KERN_ERR "private is NULL\n");
+ return -EIO;
+ }
+
+ if (cam->overlay_active == true) {
+ pr_debug("already start.\n");
+ return 0;
+ }
+
+ get_disp_ipu(cam);
+
+ out_format = cam->v4l2_fb.fmt.pixelformat;
+ if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_BGR24) {
+ bpp = 3, csi_mem_bufsize = 3;
+ pr_info("BGR24\n");
+ } else if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_RGB565) {
+ bpp = 2, csi_mem_bufsize = 2;
+ pr_info("RGB565\n");
+ } else if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_BGR32) {
+ bpp = 4, csi_mem_bufsize = 4;
+ pr_info("BGR32\n");
+ } else {
+ printk(KERN_ERR
+ "unsupported fix format from the framebuffer.\n");
+ return -EINVAL;
+ }
+
+ offset = cam->v4l2_fb.fmt.bytesperline * cam->win.w.top +
+ csi_mem_bufsize * cam->win.w.left;
+
+ if (cam->v4l2_fb.base == 0) {
+ printk(KERN_ERR "invalid frame buffer address.\n");
+ } else {
+ offset += (u32) cam->v4l2_fb.base;
+ }
+
+ csi_mem_bufsize = cam->win.w.width * cam->win.w.height * csi_mem_bufsize;
+
+ 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;
+}
+
+/*!
+ * bg_overlay_stop - stop the overlay task
+ *
+ * @param private cam_data * mxc v4l2 main structure
+ *
+ */
+static int bg_overlay_stop(void *private)
+{
+ int err = 0;
+ cam_data *cam = (cam_data *) private;
+#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;
+
+#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
+
+ flush_work_sync(&cam->csi_work_struct);
+ cancel_work_sync(&cam->csi_work_struct);
+ 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], 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], cam->vf_bufs[1]);
+ cam->vf_bufs_vaddr[1] = NULL;
+ cam->vf_bufs[1] = 0;
+ }
+ if (cam->rot_vf_bufs_vaddr[0]) {
+ dma_free_coherent(0, cam->rot_vf_buf_size[0],
+ cam->rot_vf_bufs_vaddr[0],
+ cam->rot_vf_bufs[0]);
+ cam->rot_vf_bufs_vaddr[0] = NULL;
+ cam->rot_vf_bufs[0] = 0;
+ }
+ if (cam->rot_vf_bufs_vaddr[1]) {
+ dma_free_coherent(0, cam->rot_vf_buf_size[1],
+ cam->rot_vf_bufs_vaddr[1],
+ cam->rot_vf_bufs[1]);
+ cam->rot_vf_bufs_vaddr[1] = NULL;
+ cam->rot_vf_bufs[1] = 0;
+ }
+
+ cam->overlay_active = false;
+ return err;
+}
+
+/*!
+ * Enable csi
+ * @param private struct cam_data * mxc capture instance
+ *
+ * @return status
+ */
+static int bg_overlay_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 bg_overlay_disable_csi(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+
+ return ipu_disable_csi(cam->ipu, cam->csi);
+}
+
+/*!
+ * function to select bg as the working path
+ *
+ * @param private cam_data * mxc v4l2 main structure
+ *
+ * @return status
+ */
+int bg_overlay_sdc_select(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+
+ if (cam) {
+ cam->vf_start_sdc = bg_overlay_start;
+ cam->vf_stop_sdc = bg_overlay_stop;
+ cam->vf_enable_csi = bg_overlay_enable_csi;
+ cam->vf_disable_csi = bg_overlay_disable_csi;
+ cam->overlay_active = false;
+ }
+
+ return 0;
+}
+
+/*!
+ * function to de-select bg as the working path
+ *
+ * @param private cam_data * mxc v4l2 main structure
+ *
+ * @return status
+ */
+int bg_overlay_sdc_deselect(void *private)
+{
+ cam_data *cam = (cam_data *) private;
+
+ if (cam) {
+ cam->vf_start_sdc = NULL;
+ cam->vf_stop_sdc = NULL;
+ cam->vf_enable_csi = NULL;
+ cam->vf_disable_csi = NULL;
+ }
+ return 0;
+}
+
+/*!
+ * Init background overlay task.
+ *
+ * @return Error code indicating success or failure
+ */
+__init int bg_overlay_sdc_init(void)
+{
+ return 0;
+}
+
+/*!
+ * Deinit background overlay task.
+ *
+ * @return Error code indicating success or failure
+ */
+void __exit bg_overlay_sdc_exit(void)
+{
+}
+
+module_init(bg_overlay_sdc_init);
+module_exit(bg_overlay_sdc_exit);
+
+EXPORT_SYMBOL(bg_overlay_sdc_select);
+EXPORT_SYMBOL(bg_overlay_sdc_deselect);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("IPU PRP VF SDC Backgroud Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/mxc/capture/ipu_fg_overlay_sdc.c b/drivers/media/video/mxc/capture/ipu_fg_overlay_sdc.c
index 05c88c7d409b..312462ac60e0 100644
--- a/drivers/media/video/mxc/capture/ipu_fg_overlay_sdc.c
+++ b/drivers/media/video/mxc/capture/ipu_fg_overlay_sdc.c
@@ -508,6 +508,8 @@ static int foreground_stop(void *private)
}
#endif
+ flush_work_sync(&cam->csi_work_struct);
+ cancel_work_sync(&cam->csi_work_struct);
ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_VF, cam->csi, false, false);
if (cam->vf_bufs_vaddr[0]) {
diff --git a/drivers/media/video/mxc/capture/ipu_prp_sw.h b/drivers/media/video/mxc/capture/ipu_prp_sw.h
index 7cdc521711cb..cba47baa4abe 100644
--- a/drivers/media/video/mxc/capture/ipu_prp_sw.h
+++ b/drivers/media/video/mxc/capture/ipu_prp_sw.h
@@ -29,12 +29,14 @@ int prp_enc_deselect(void *private);
#ifdef CONFIG_MXC_IPU_PRP_VF_SDC
int prp_vf_sdc_select(void *private);
int prp_vf_sdc_deselect(void *private);
+int prp_vf_sdc_select_bg(void *private);
+int prp_vf_sdc_deselect_bg(void *private);
#else
int foreground_sdc_select(void *private);
int foreground_sdc_deselect(void *private);
+int bg_overlay_sdc_select(void *private);
+int bg_overlay_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 bddfee530274..423575c9d881 100644
--- a/drivers/media/video/mxc/capture/mxc_v4l2_capture.c
+++ b/drivers/media/video/mxc/capture/mxc_v4l2_capture.c
@@ -655,7 +655,11 @@ static int start_preview(cam_data *cam)
err = foreground_sdc_select(cam);
#endif
else if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_PRIMARY)
+ #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
err = prp_vf_sdc_select_bg(cam);
+ #else
+ err = bg_overlay_sdc_select(cam);
+ #endif
if (err != 0)
return err;
@@ -714,7 +718,11 @@ static int stop_preview(cam_data *cam)
err = foreground_sdc_deselect(cam);
#endif
else if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_PRIMARY)
+ #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
err = prp_vf_sdc_deselect_bg(cam);
+ #else
+ err = bg_overlay_sdc_deselect(cam);
+ #endif
return err;
}
diff --git a/drivers/media/video/mxc/capture/ov5642.c b/drivers/media/video/mxc/capture/ov5642.c
index 245a92c15ef1..492748c6cac4 100644
--- a/drivers/media/video/mxc/capture/ov5642.c
+++ b/drivers/media/video/mxc/capture/ov5642.c
@@ -3228,6 +3228,7 @@ err:
static int ov5642_write_snapshot_para(enum ov5642_frame_rate frame_rate,
enum ov5642_mode mode)
{
+ int ret = 0;
bool m_60Hz = false;
u16 capture_frame_rate = 50;
u16 g_preview_frame_rate = 225;
@@ -3255,7 +3256,10 @@ static int ov5642_write_snapshot_para(enum ov5642_frame_rate frame_rate,
gain = 0;
ov5642_read_reg(0x350b, &gain);
- ov5642_init_mode(frame_rate, mode);
+ ret = ov5642_init_mode(frame_rate, mode);
+ if (ret < 0)
+ return ret;
+
ret_h = ret_m = ret_l = 0;
ov5642_read_reg(0x380e, &ret_h);
ov5642_read_reg(0x380f, &ret_l);
@@ -3331,7 +3335,7 @@ static int ov5642_write_snapshot_para(enum ov5642_frame_rate frame_rate,
ov5642_write_reg(0x3500, exposure_high);
msleep(500);
- return 0;
+ return ret ;
}
diff --git a/drivers/media/video/mxc/output/mxc_pxp_v4l2.c b/drivers/media/video/mxc/output/mxc_pxp_v4l2.c
index a26b5d918a26..a3a8294efb8e 100644
--- a/drivers/media/video/mxc/output/mxc_pxp_v4l2.c
+++ b/drivers/media/video/mxc/output/mxc_pxp_v4l2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2010-2012 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -254,10 +254,12 @@ static int pxp_set_fbinfo(struct pxps *pxp)
fb->fmt.width = fbi->var.xres;
fb->fmt.height = fbi->var.yres;
+ pxp->pxp_conf.out_param.stride = fbi->var.xres;
if (fbi->var.bits_per_pixel == 16)
fb->fmt.pixelformat = V4L2_PIX_FMT_RGB565;
else
fb->fmt.pixelformat = V4L2_PIX_FMT_RGB24;
+
fb->base = (void *)fbi->fix.smem_start;
return 0;
@@ -293,9 +295,9 @@ static int set_fb_blank(int blank)
if (err)
return err;
- acquire_console_sem();
+ console_lock();
fb_blank(fbi, blank);
- release_console_sem();
+ console_unlock();
return err;
}
@@ -679,7 +681,7 @@ static void pxp_buf_free(struct videobuf_queue *q, struct pxp_buffer *buf)
* This waits until this buffer is out of danger, i.e., until it is no
* longer in STATE_QUEUED or STATE_ACTIVE
*/
- videobuf_waiton(vb, 0, 0);
+ videobuf_waiton(q, vb, 0, 0);
if (txd)
async_tx_ack(txd);
@@ -710,7 +712,7 @@ static int pxp_buf_prepare(struct videobuf_queue *q,
if (vb->state == VIDEOBUF_NEEDS_INIT) {
struct pxp_channel *pchan = pxp->pxp_channel[0];
- struct scatterlist *sg = &buf->sg;
+ struct scatterlist *sg = &buf->sg[0];
/* This actually (allocates and) maps buffers */
ret = videobuf_iolock(q, vb, NULL);
@@ -1055,7 +1057,8 @@ out:
V4L2_BUF_TYPE_VIDEO_OUTPUT,
V4L2_FIELD_NONE,
sizeof(struct pxp_buffer),
- pxp);
+ pxp,
+ NULL);
dev_dbg(&pxp->pdev->dev, "call pxp_open\n");
return 0;
diff --git a/drivers/media/video/mxc/output/mxc_vout.c b/drivers/media/video/mxc/output/mxc_vout.c
index 4b3617f89b08..366d27a92286 100644
--- a/drivers/media/video/mxc/output/mxc_vout.c
+++ b/drivers/media/video/mxc/output/mxc_vout.c
@@ -244,7 +244,7 @@ static int alloc_dma_buf(struct mxc_vout_output *vout, struct dma_mem *buf)
{
buf->vaddr = dma_alloc_coherent(vout->vbq.dev, buf->size, &buf->paddr,
- GFP_KERNEL);
+ GFP_DMA | GFP_KERNEL);
if (!buf->vaddr) {
v4l2_err(vout->vfd->v4l2_dev,
"cannot get dma buf size:0x%x\n", buf->size);
diff --git a/drivers/mfd/mxc-hdmi-core.c b/drivers/mfd/mxc-hdmi-core.c
index 332843661d98..e9322477ff6d 100644
--- a/drivers/mfd/mxc-hdmi-core.c
+++ b/drivers/mfd/mxc-hdmi-core.c
@@ -63,6 +63,104 @@ int mxc_hdmi_disp_id;
static struct mxc_edid_cfg hdmi_core_edid_cfg;
static int hdmi_core_init;
static unsigned int hdmi_dma_running;
+static struct snd_pcm_substream *hdmi_audio_stream_playback;
+static unsigned int hdmi_cable_state;
+static unsigned int hdmi_blank_state;
+static spinlock_t hdmi_audio_lock, hdmi_blank_state_lock, hdmi_cable_state_lock;
+
+
+unsigned int hdmi_set_cable_state(unsigned int state)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&hdmi_cable_state_lock, flags);
+ hdmi_cable_state = state;
+ spin_unlock_irqrestore(&hdmi_cable_state_lock, flags);
+
+ return 0;
+}
+
+unsigned int hdmi_set_blank_state(unsigned int state)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&hdmi_blank_state_lock, flags);
+ hdmi_blank_state = state;
+ spin_unlock_irqrestore(&hdmi_blank_state_lock, flags);
+
+ return 0;
+}
+
+static void hdmi_audio_abort_stream(struct snd_pcm_substream *substream)
+{
+ unsigned long flags;
+
+ snd_pcm_stream_lock_irqsave(substream, flags);
+
+ if (snd_pcm_running(substream))
+ snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
+
+ snd_pcm_stream_unlock_irqrestore(substream, flags);
+}
+
+int mxc_hdmi_abort_stream(void)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&hdmi_audio_lock, flags);
+ if (hdmi_audio_stream_playback)
+ hdmi_audio_abort_stream(hdmi_audio_stream_playback);
+ spin_unlock_irqrestore(&hdmi_audio_lock, flags);
+
+ return 0;
+}
+
+static int check_hdmi_state(void)
+{
+ unsigned long flags1, flags2;
+ unsigned int ret;
+
+ spin_lock_irqsave(&hdmi_cable_state_lock, flags1);
+ spin_lock_irqsave(&hdmi_blank_state_lock, flags2);
+
+ ret = hdmi_cable_state && hdmi_blank_state;
+
+ spin_unlock_irqrestore(&hdmi_blank_state_lock, flags2);
+ spin_unlock_irqrestore(&hdmi_cable_state_lock, flags1);
+
+ return ret;
+}
+
+int mxc_hdmi_register_audio(struct snd_pcm_substream *substream)
+{
+ unsigned long flags, flags1;
+ int ret = 0;
+
+ snd_pcm_stream_lock_irqsave(substream, flags);
+
+ if (substream && check_hdmi_state()) {
+ spin_lock_irqsave(&hdmi_audio_lock, flags1);
+ if (hdmi_audio_stream_playback) {
+ pr_err("%s unconsist hdmi auido stream!\n", __func__);
+ ret = -EINVAL;
+ }
+ hdmi_audio_stream_playback = substream;
+ spin_unlock_irqrestore(&hdmi_audio_lock, flags1);
+ } else
+ ret = -EINVAL;
+
+ snd_pcm_stream_unlock_irqrestore(substream, flags);
+
+ return ret;
+}
+
+void mxc_hdmi_unregister_audio(struct snd_pcm_substream *substream)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&hdmi_audio_lock, flags);
+ hdmi_audio_stream_playback = NULL;
+ spin_unlock_irqrestore(&hdmi_audio_lock, flags);
+}
u8 hdmi_readb(unsigned int reg)
{
@@ -466,6 +564,7 @@ static int mxc_hdmi_core_probe(struct platform_device *pdev)
struct fsl_mxc_hdmi_core_platform_data *pdata = pdev->dev.platform_data;
struct mxc_hdmi_data *hdmi_data;
struct resource *res;
+ unsigned long flags;
int ret = 0;
#ifdef DEBUG
@@ -495,6 +594,23 @@ static int mxc_hdmi_core_probe(struct platform_device *pdev)
spin_lock_init(&irq_spinlock);
spin_lock_init(&edid_spinlock);
+
+ spin_lock_init(&hdmi_cable_state_lock);
+ spin_lock_init(&hdmi_blank_state_lock);
+ spin_lock_init(&hdmi_audio_lock);
+
+ spin_lock_irqsave(&hdmi_cable_state_lock, flags);
+ hdmi_cable_state = 0;
+ spin_unlock_irqrestore(&hdmi_cable_state_lock, flags);
+
+ spin_lock_irqsave(&hdmi_blank_state_lock, flags);
+ hdmi_blank_state = 0;
+ spin_unlock_irqrestore(&hdmi_blank_state_lock, flags);
+
+ spin_lock_irqsave(&hdmi_audio_lock, flags);
+ hdmi_audio_stream_playback = NULL;
+ spin_unlock_irqrestore(&hdmi_audio_lock, flags);
+
isfr_clk = clk_get(&hdmi_data->pdev->dev, "hdmi_isfr_clk");
if (IS_ERR(isfr_clk)) {
ret = PTR_ERR(isfr_clk);
diff --git a/drivers/mxc/asrc/mxc_asrc.c b/drivers/mxc/asrc/mxc_asrc.c
index cf41f2994226..62d7ceb0e04f 100644
--- a/drivers/mxc/asrc/mxc_asrc.c
+++ b/drivers/mxc/asrc/mxc_asrc.c
@@ -316,22 +316,22 @@ int asrc_req_pair(int chn_num, enum asrc_pair_index *index)
spin_lock_irqsave(&data_lock, lock_flags);
if (chn_num > 2) {
- pair = &g_asrc->asrc_pair[ASRC_PAIR_C];
+ pair = &g_asrc->asrc_pair[ASRC_PAIR_B];
if (pair->active || (chn_num > pair->chn_max))
err = -EBUSY;
else {
- *index = ASRC_PAIR_C;
+ *index = ASRC_PAIR_B;
pair->chn_num = chn_num;
pair->active = 1;
}
} else {
pair = &g_asrc->asrc_pair[ASRC_PAIR_A];
if (pair->active || (pair->chn_max == 0)) {
- pair = &g_asrc->asrc_pair[ASRC_PAIR_B];
+ pair = &g_asrc->asrc_pair[ASRC_PAIR_C];
if (pair->active || (pair->chn_max == 0))
err = -EBUSY;
else {
- *index = ASRC_PAIR_B;
+ *index = ASRC_PAIR_C;
pair->chn_num = 2;
pair->active = 1;
}
@@ -583,17 +583,23 @@ int asrc_config_pair(struct asrc_config *config)
}
}
- if ((config->inclk == INCLK_ASRCK1_CLK) &&
+ if ((config->inclk == INCLK_NONE) &&
(config->outclk == OUTCLK_ESAI_TX)) {
reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCTR_REG);
- reg |= (1 << (20 + config->pair));
- reg |= (0x02 << (13 + (config->pair << 1)));
+ reg &= ~(1 << (20 + config->pair));
+ reg |= (0x03 << (13 + (config->pair << 1)));
__raw_writel(reg, g_asrc->vaddr + ASRC_ASRCTR_REG);
err = asrc_set_clock_ratio(config->pair,
config->input_sample_rate,
config->output_sample_rate);
if (err < 0)
return err;
+ err = asrc_set_process_configuration(config->pair,
+ config->input_sample_rate,
+ config->
+ output_sample_rate);
+ if (err < 0)
+ return err;
}
/* Config input and output wordwidth */
@@ -667,12 +673,6 @@ void asrc_start_conv(enum asrc_pair_index index)
__raw_writel(reg,
g_asrc->vaddr + ASRC_ASRDIA_REG +
(index << 3));
- __raw_writel(reg,
- g_asrc->vaddr + ASRC_ASRDIA_REG +
- (index << 3));
- __raw_writel(reg,
- g_asrc->vaddr + ASRC_ASRDIA_REG +
- (index << 3));
}
__raw_writel(0x40, g_asrc->vaddr + ASRC_ASRIER_REG);
@@ -813,9 +813,9 @@ static int mxc_init_asrc(void)
/* Enable overflow interrupt */
__raw_writel(0x00, g_asrc->vaddr + ASRC_ASRIER_REG);
- /* Default 6: 2: 2 channel assignment */
- __raw_writel((0x06 << g_asrc->mxc_asrc_data->channel_bits *
- 2) | (0x02 << g_asrc->mxc_asrc_data->channel_bits) | 0x02,
+ /* Default 2: 6: 2 channel assignment */
+ __raw_writel((0x02 << g_asrc->mxc_asrc_data->channel_bits *
+ 2) | (0x06 << g_asrc->mxc_asrc_data->channel_bits) | 0x02,
g_asrc->vaddr + ASRC_ASRCNCR_REG);
/* Parameter Registers recommended settings */
@@ -1696,8 +1696,8 @@ static int mxc_asrc_probe(struct platform_device *pdev)
g_asrc->dev->coherent_dma_mask = DMA_BIT_MASK(32);
g_asrc->asrc_pair[0].chn_max = 2;
- g_asrc->asrc_pair[1].chn_max = 2;
- g_asrc->asrc_pair[2].chn_max = 6;
+ g_asrc->asrc_pair[1].chn_max = 6;
+ g_asrc->asrc_pair[2].chn_max = 2;
g_asrc->asrc_pair[0].overload_error = 0;
g_asrc->asrc_pair[1].overload_error = 0;
g_asrc->asrc_pair[2].overload_error = 0;
diff --git a/drivers/mxc/ipu3/ipu_capture.c b/drivers/mxc/ipu3/ipu_capture.c
index c4eac45a6152..029ab5e9dec7 100644
--- a/drivers/mxc/ipu3/ipu_capture.c
+++ b/drivers/mxc/ipu3/ipu_capture.c
@@ -803,7 +803,7 @@ void _ipu_csi_wait4eof(struct ipu_soc *ipu, ipu_channel_t channel)
dev_err(ipu->dev, "CSI irq %d in use\n", irq);
return;
}
- ret = wait_for_completion_timeout(&ipu->csi_comp, msecs_to_jiffies(50));
+ ret = wait_for_completion_timeout(&ipu->csi_comp, msecs_to_jiffies(500));
ipu_free_irq(ipu, irq, ipu);
dev_dbg(ipu->dev, "CSI stop timeout - %d * 10ms\n", 5 - ret);
}
diff --git a/drivers/mxc/ipu3/ipu_common.c b/drivers/mxc/ipu3/ipu_common.c
index 4e3526c81839..c97d15999301 100644
--- a/drivers/mxc/ipu3/ipu_common.c
+++ b/drivers/mxc/ipu3/ipu_common.c
@@ -176,174 +176,6 @@ static int __devinit ipu_clk_setup_enable(struct ipu_soc *ipu,
return 0;
}
-#if 0
-static void ipu_irq_handler(unsigned int irq, struct irq_desc *desc)
-{
- struct ipu_soc *ipu = irq_desc_get_handler_data(desc);
- const int int_reg[] = { 1, 2, 3, 4, 11, 12, 13, 14, 15, 0 };
- u32 status;
- int i, line;
-
- for (i = 0;; i++) {
- if (int_reg[i] == 0)
- break;
-
- status = ipu_cm_read(ipu, IPU_INT_STAT(int_reg[i]));
- status &= ipu_cm_read(ipu, IPU_INT_CTRL(int_reg[i]));
-
- while ((line = ffs(status))) {
- line--;
- status &= ~(1UL << line);
- line += ipu->irq_start + (int_reg[i] - 1) * 32;
- generic_handle_irq(line);
- }
-
- }
-}
-
-static void ipu_err_irq_handler(unsigned int irq, struct irq_desc *desc)
-{
- struct ipu_soc *ipu = irq_desc_get_handler_data(desc);
- const int int_reg[] = { 5, 6, 9, 10, 0 };
- u32 status;
- int i, line;
-
- for (i = 0;; i++) {
- if (int_reg[i] == 0)
- break;
-
- status = ipu_cm_read(ipu, IPU_INT_STAT(int_reg[i]));
- status &= ipu_cm_read(ipu, IPU_INT_CTRL(int_reg[i]));
-
- while ((line = ffs(status))) {
- line--;
- status &= ~(1UL << line);
- line += ipu->irq_start + (int_reg[i] - 1) * 32;
- generic_handle_irq(line);
- }
-
- }
-}
-
-static void ipu_ack_irq(struct irq_data *d)
-{
- struct ipu_soc *ipu = irq_data_get_irq_chip_data(d);
- unsigned int irq = d->irq - ipu->irq_start;
- unsigned long flags;
-
- spin_lock_irqsave(&ipu->ipu_lock, flags);
- ipu_cm_write(ipu, 1 << (irq % 32), IPU_INT_STAT(irq / 32 + 1));
- spin_unlock_irqrestore(&ipu->ipu_lock, flags);
-}
-
-static void ipu_unmask_irq(struct irq_data *d)
-{
- struct ipu_soc *ipu = irq_data_get_irq_chip_data(d);
- unsigned int irq = d->irq - ipu->irq_start;
- unsigned long flags;
- u32 reg;
-
- spin_lock_irqsave(&ipu->ipu_lock, flags);
- reg = ipu_cm_read(ipu, IPU_INT_CTRL(irq / 32 + 1));
- reg |= 1 << (irq % 32);
- ipu_cm_write(ipu, reg, IPU_INT_CTRL(irq / 32 + 1));
- spin_unlock_irqrestore(&ipu->ipu_lock, flags);
-}
-
-static void ipu_mask_irq(struct irq_data *d)
-{
- struct ipu_soc *ipu = irq_data_get_irq_chip_data(d);
- unsigned int irq = d->irq - ipu->irq_start;
- unsigned long flags;
- u32 reg;
-
- spin_lock_irqsave(&ipu->ipu_lock, flags);
- reg = ipu_cm_read(ipu, IPU_INT_CTRL(irq / 32 + 1));
- reg &= ~(1 << (irq % 32));
- ipu_cm_write(ipu, reg, IPU_INT_CTRL(irq / 32 + 1));
- spin_unlock_irqrestore(&ipu->ipu_lock, flags);
-}
-
-static struct irq_chip ipu_irq_chip = {
- .name = "IPU",
- .irq_ack = ipu_ack_irq,
- .irq_mask = ipu_mask_irq,
- .irq_unmask = ipu_unmask_irq,
-};
-
-static void __devinit ipu_irq_setup(struct ipu_soc *ipu)
-{
- int i;
-
- for (i = ipu->irq_start; i < ipu->irq_start + MX5_IPU_IRQS; i++) {
- irq_set_chip_and_handler(i, &ipu_irq_chip, handle_level_irq);
- set_irq_flags(i, IRQF_VALID);
- irq_set_chip_data(i, ipu);
- }
-
- irq_set_chained_handler(ipu->irq_sync, ipu_irq_handler);
- irq_set_handler_data(ipu->irq_sync, ipu);
- irq_set_chained_handler(ipu->irq_err, ipu_err_irq_handler);
- irq_set_handler_data(ipu->irq_err, ipu);
-}
-
-int ipu_request_irq(struct ipu_soc *ipu, unsigned int irq,
- irq_handler_t handler, unsigned long flags,
- const char *name, void *dev)
-{
- return request_irq(ipu->irq_start + irq, handler, flags, name, dev);
-}
-EXPORT_SYMBOL_GPL(ipu_request_irq);
-
-void ipu_enable_irq(struct ipu_soc *ipu, unsigned int irq)
-{
- return enable_irq(ipu->irq_start + irq);
-}
-EXPORT_SYMBOL_GPL(ipu_disable_irq);
-
-void ipu_disable_irq(struct ipu_soc *ipu, unsigned int irq)
-{
- return disable_irq(ipu->irq_start + irq);
-}
-EXPORT_SYMBOL_GPL(ipu_disable_irq);
-
-void ipu_free_irq(struct ipu_soc *ipu, unsigned int irq, void *dev_id)
-{
- free_irq(ipu->irq_start + irq, dev_id);
-}
-EXPORT_SYMBOL_GPL(ipu_free_irq);
-
-static irqreturn_t ipu_completion_handler(int irq, void *dev)
-{
- struct completion *completion = dev;
-
- complete(completion);
- return IRQ_HANDLED;
-}
-
-int ipu_wait_for_interrupt(struct ipu_soc *ipu, int interrupt, int timeout_ms)
-{
- DECLARE_COMPLETION_ONSTACK(completion);
- int ret;
-
- ret = ipu_request_irq(ipu, interrupt, ipu_completion_handler,
- 0, NULL, &completion);
- if (ret) {
- dev_err(ipu->dev,
- "ipu request irq %d fail\n", interrupt);
- return ret;
- }
-
- ret = wait_for_completion_timeout(&completion,
- msecs_to_jiffies(timeout_ms));
-
- ipu_free_irq(ipu, interrupt, &completion);
-
- return ret > 0 ? 0 : -ETIMEDOUT;
-}
-EXPORT_SYMBOL_GPL(ipu_wait_for_interrupt);
-#endif
-
struct ipu_soc *ipu_get_soc(int id)
{
if (id >= MXC_IPU_MAX_NUM)
diff --git a/drivers/mxc/ipu3/ipu_device.c b/drivers/mxc/ipu3/ipu_device.c
index 215fc706407f..d12ffdfc7847 100644
--- a/drivers/mxc/ipu3/ipu_device.c
+++ b/drivers/mxc/ipu3/ipu_device.c
@@ -1111,7 +1111,7 @@ static int prepare_task(struct ipu_task_entry *t)
if (t->set.task != 0) {
dev_err(t->dev, "ERR: vdoa only task:0x%x, [0x%p].\n",
t->set.task, t);
- BUG();
+ return -EINVAL;
}
t->set.task |= VDOA_ONLY;
}
@@ -1173,7 +1173,8 @@ static int _get_vdoa_ipu_res(struct ipu_task_entry *t)
for (i = 0; i < max_ipu_no; i++) {
ipu = ipu_get_soc(i);
if (IS_ERR(ipu))
- BUG();
+ dev_err(t->dev, "no:0x%x,found_vdoa:%d, ipu:%d\n",
+ t->task_no, found_vdoa, i);
used = &tbl->used[i][IPU_PP_CH_VF];
if (t->set.mode & VDI_MODE) {
@@ -1194,7 +1195,8 @@ static int _get_vdoa_ipu_res(struct ipu_task_entry *t)
break;
}
} else
- BUG();
+ dev_err(t->dev, "no:0x%x,found_vdoa:%d, mode:0x%x\n",
+ t->task_no, found_vdoa, t->set.mode);
}
if (found_ipu)
goto next;
@@ -1202,7 +1204,8 @@ static int _get_vdoa_ipu_res(struct ipu_task_entry *t)
for (i = 0; i < max_ipu_no; i++) {
ipu = ipu_get_soc(i);
if (IS_ERR(ipu))
- BUG();
+ dev_err(t->dev, "no:0x%x,found_vdoa:%d, ipu:%d\n",
+ t->task_no, found_vdoa, i);
if ((t->set.mode & IC_MODE) || only_rot(t->set.mode)) {
used = &tbl->used[i][IPU_PP_CH_PP];
@@ -1225,7 +1228,9 @@ next:
t->ipu_id = i;
t->dev = ipu->dev;
if (atomic_inc_return(&t->res_get) == 2)
- BUG();
+ dev_err(t->dev,
+ "ERR no:0x%x,found_vdoa:%d,get ipu twice\n",
+ t->task_no, found_vdoa);
}
out:
dev_dbg(t->dev,
@@ -1246,12 +1251,12 @@ static void put_vdoa_ipu_res(struct ipu_task_entry *tsk, int vdoa_only)
int rel_vdoa = 0, rel_ipu = 0;
struct ipu_channel_tabel *tbl = &ipu_ch_tbl;
- if (!tsk)
- BUG();
mutex_lock(&tbl->lock);
if (tsk->set.mode & VDOA_MODE) {
if (!tbl->vdoa_used && tsk->vdoa_handle)
- BUG();
+ dev_err(tsk->dev,
+ "ERR no:0x%x,vdoa not used,mode:0x%x\n",
+ tsk->task_no, tsk->set.mode);
if (tbl->vdoa_used && tsk->vdoa_handle) {
tbl->vdoa_used = 0;
vdoa_put_handle(&tsk->vdoa_handle);
@@ -1263,13 +1268,13 @@ static void put_vdoa_ipu_res(struct ipu_task_entry *tsk, int vdoa_only)
}
}
- if (tsk) {
- tbl->used[tsk->ipu_id][tsk->task_id - 1] = 0;
- rel_ipu = 1;
- ret = atomic_inc_return(&tsk->res_free);
- if (ret == 2)
- BUG();
- }
+ tbl->used[tsk->ipu_id][tsk->task_id - 1] = 0;
+ rel_ipu = 1;
+ ret = atomic_inc_return(&tsk->res_free);
+ if (ret == 2)
+ dev_err(tsk->dev,
+ "ERR no:0x%x,rel_vdoa:%d,put ipu twice\n",
+ tsk->task_no, rel_vdoa);
out:
dev_dbg(tsk->dev,
"%s:no:0x%x,rel_vdoa:%d, rel_ipu:%d\n",
@@ -1300,12 +1305,16 @@ static int get_vdoa_ipu_res(struct ipu_task_entry *t)
goto out;
} else {
if (!(t->set.task & VDOA_ONLY) && (!t->ipu))
- BUG();
+ dev_err(t->dev,
+ "ERR[no-0x%x] can not get ipu!\n",
+ t->task_no);
ret = atomic_read(&req_cnt);
if (ret > 0)
ret = atomic_dec_return(&req_cnt);
else
- BUG();
+ dev_err(t->dev,
+ "ERR[no-0x%x] req_cnt:%d mismatch!\n",
+ t->task_no, ret);
dev_dbg(t->dev, "no-0x%x,[0x%p],req_cnt:%d, got_res!\n",
t->task_no, t, ret);
found = 1;
@@ -1827,7 +1836,8 @@ static int init_tiled_ch_bufs(struct ipu_soc *ipu, struct ipu_task_entry *t)
CHECK_RETCODE(ret < 0, "init tiled_ch-n", t->state, done, ret);
} else {
ret = -EINVAL;
- BUG();
+ dev_err(t->dev, "ERR[no-0x%x] invalid fmt:0x%x!\n",
+ t->task_no, t->input.format);
}
done:
@@ -1914,7 +1924,8 @@ static int init_ic(struct ipu_soc *ipu, struct ipu_task_entry *t)
else if (IPU_DEINTERLACE_FIELD_BOTTOM == t->input.deinterlace.field_fmt)
params.mem_prp_vf_mem.field_fmt = V4L2_FIELD_INTERLACED_BT;
else
- BUG();
+ dev_err(t->dev, "ERR[no-0x%x]invalid field fmt:0x%x!\n",
+ t->task_no, t->input.deinterlace.field_fmt);
ret = ipu_init_channel(ipu, t->set.vdi_ic_p_chan, &params);
if (ret < 0) {
t->state = STATE_INIT_CHAN_FAIL;
@@ -2232,8 +2243,10 @@ static void vdi_split_process(struct ipu_soc *ipu, struct ipu_task_entry *t)
unsigned char *base_off;
struct ipu_task_entry *parent = t->parent;
- if (!parent)
- BUG();
+ if (!parent) {
+ dev_err(t->dev, "ERR[0x%x]invalid parent\n", t->task_no);
+ return;
+ }
stripe_mode = t->task_no & 0xf;
task_no = t->task_no >> 4;
@@ -2544,13 +2557,15 @@ static void do_task(struct ipu_task_entry *t)
busy = ic_vf_pp_is_busy(ipu, true);
else if (t->task_id == IPU_TASK_ID_PP)
busy = ic_vf_pp_is_busy(ipu, false);
- else
- BUG();
+ else {
+ dev_err(ipu->dev, "ERR[no:0x%x]ipu task_id:%d invalid!\n",
+ t->task_no, t->task_id);
+ return;
+ }
if (busy) {
dev_err(ipu->dev, "ERR[0x%p-no:0x%x]ipu task_id:%d busy!\n",
(void *)t, t->task_no, t->task_id);
t->state = STATE_IPU_BUSY;
- BUG();
return;
}
@@ -2602,7 +2617,7 @@ static void do_task(struct ipu_task_entry *t)
ipu->rot_dma[rot_idx].vaddr = dma_alloc_coherent(t->dev,
r_size,
&ipu->rot_dma[rot_idx].paddr,
- GFP_KERNEL);
+ GFP_DMA | GFP_KERNEL);
CHECK_RETCODE(ipu->rot_dma[rot_idx].vaddr == NULL,
"ic_and_rot", STATE_SYS_NO_MEM,
chan_setup, -ENOMEM);
@@ -2629,7 +2644,6 @@ static void do_task(struct ipu_task_entry *t)
} else {
dev_err(t->dev, "ERR [0x%p]do task: should not be here\n", t);
t->state = STATE_ERR;
- BUG();
return;
}
@@ -2832,7 +2846,9 @@ static void get_res_do_task(struct ipu_task_entry *t)
found = get_vdoa_ipu_res(t);
if (!found) {
- BUG();
+ dev_err(t->dev, "ERR:[0x%p] no-0x%x can not get res\n",
+ t, t->task_no);
+ return;
} else {
if (t->set.task & VDOA_ONLY)
do_task_vdoa_only(t);
@@ -2886,12 +2902,18 @@ static void wait_split_task_complete(struct ipu_task_entry *parent,
ret = -ETIMEDOUT;
goto out;
} else {
- if (idx < 0)
- BUG();
+ if (idx < 0) {
+ dev_err(parent->dev,
+ "ERR:[0x%p] no-0x%x, invalid task idx:%d\n",
+ parent, parent->task_no, idx);
+ continue;
+ }
tsk = sp_task[idx].child_task;
mutex_lock(lock);
if (!tsk->split_done || !tsk->ipu)
- BUG();
+ dev_err(tsk->dev,
+ "ERR:no-0x%x,split not done:%d/null ipu:0x%p\n",
+ tsk->task_no, tsk->split_done, tsk->ipu);
tsk->split_done = 0;
mutex_unlock(lock);
@@ -2911,7 +2933,8 @@ out:
for (k = 0; k < max_ipu_no; k++) {
ipu = ipu_get_soc(k);
if (IS_ERR(ipu)) {
- BUG();
+ dev_err(parent->dev, "no:0x%x, null ipu:%d\n",
+ parent->task_no, k);
} else {
busy_vf = ic_vf_pp_is_busy(ipu, true);
busy_pp = ic_vf_pp_is_busy(ipu, false);
@@ -2948,10 +2971,6 @@ out:
spin_unlock_irqrestore(&ipu_task_list_lock, flags);
if (!tsk->ipu)
continue;
- if (STATE_IN_PROGRESS == tsk->state) {
- do_task_release(tsk, 1);
- put_vdoa_ipu_res(tsk, 0);
- }
if (tsk->state != STATE_OK) {
dev_err(tsk->dev,
"ERR:[0x%p] no-0x%x,id:%d, sp_tsk state: %s\n",
@@ -2992,7 +3011,9 @@ static inline int find_task(struct ipu_task_entry **t, int thread_id)
"thread_id:%d,[0x%p] task_no:0x%x,mode:0x%x list_del\n",
thread_id, tsk, tsk->task_no, tsk->set.mode);
} else
- BUG();
+ dev_err(tsk->dev,
+ "thread_id:%d,task_no:0x%x,mode:0x%x not on list_del\n",
+ thread_id, tsk->task_no, tsk->set.mode);
}
spin_unlock_irqrestore(&ipu_task_list_lock, flags);
@@ -3027,7 +3048,6 @@ static int ipu_task_thread(void *argv)
&cpu_mask);
if (ret < 0) {
pr_err("%s: sched_setaffinity fail:%d.\n", __func__, ret);
- BUG();
}
pr_debug("%s: sched_setaffinity cpu:%d.\n", __func__, cpu);
}
@@ -3039,8 +3059,11 @@ static int ipu_task_thread(void *argv)
wait_event(thread_waitq, find_task(&tsk, curr_thread_id));
- if (!tsk)
- BUG();
+ if (!tsk) {
+ pr_err("thread:%d can not find task.\n",
+ curr_thread_id);
+ continue;
+ }
/* note: other threads run split child task */
split_parent = need_split(tsk) && !tsk->parent;
@@ -3083,7 +3106,9 @@ static int ipu_task_thread(void *argv)
/* FIXME: ensure the correct sequence for split
4size: 5/6->9/a*/
if (!sp_tsk0)
- BUG();
+ dev_err(tsk->dev,
+ "ERR: no-0x%x,can not get split_tsk0\n",
+ tsk->task_no);
wake_up(&thread_waitq);
get_res_do_task(sp_tsk0);
dev_dbg(sp_tsk0->dev,
@@ -3127,8 +3152,7 @@ static int ipu_task_thread(void *argv)
kref_put(&tsk->refcount, task_mem_free);
}
- pr_info("%s exit.\n", __func__);
- BUG();
+ pr_info("ERR %s exit.\n", __func__);
return 0;
}
@@ -3301,7 +3325,7 @@ static long mxc_ipu_ioctl(struct file *file,
mem->cpu_addr = dma_alloc_coherent(ipu_dev, size,
&mem->phy_addr,
- GFP_KERNEL);
+ GFP_DMA | GFP_KERNEL);
if (mem->cpu_addr == NULL) {
kfree(mem);
return -ENOMEM;
diff --git a/drivers/mxc/thermal/cooling.c b/drivers/mxc/thermal/cooling.c
index 772f771c8149..0feefeaa6008 100644
--- a/drivers/mxc/thermal/cooling.c
+++ b/drivers/mxc/thermal/cooling.c
@@ -177,6 +177,7 @@ int anatop_thermal_cpu_hotplug(bool cpu_on)
sys_write(fd, (char *)"1", MAX_CPU_ONLINE_LEN);
cpu_mask &= ~(0x1 << cpu);
ret = 0;
+ sys_close(fd);
break;
}
sys_close(fd);
@@ -198,6 +199,7 @@ int anatop_thermal_cpu_hotplug(bool cpu_on)
sys_write(fd, (char *)"0", MAX_CPU_ONLINE_LEN);
cpu_mask |= 0x1 << cpu;
ret = 0;
+ sys_close(fd);
break;
}
sys_close(fd);
diff --git a/drivers/mxc/thermal/thermal.c b/drivers/mxc/thermal/thermal.c
index 0f4cfb8304ce..6f3c7a912170 100644
--- a/drivers/mxc/thermal/thermal.c
+++ b/drivers/mxc/thermal/thermal.c
@@ -152,6 +152,8 @@ static const struct anatop_device_id thermal_device_ids[] = {
{ANATOP_THERMAL_HID},
{""},
};
+int thermal_hot;
+EXPORT_SYMBOL(thermal_hot);
enum {
DEBUG_USER_STATE = 1U << 0,
@@ -584,6 +586,7 @@ static int anatop_thermal_notify(struct thermal_zone_device *thermal, int trip,
printk(KERN_WARNING "thermal_notify: trip_critical reached!\n");
arch_reset(mode, cmd);
} else if (trip_type == THERMAL_TRIP_HOT) {
+ thermal_hot = 1;
printk(KERN_DEBUG "thermal_notify: trip_hot reached!\n");
type = ANATOP_THERMAL_NOTIFY_HOT;
/* if temperature increase, continue to detach secondary CPUs*/
@@ -598,6 +601,7 @@ static int anatop_thermal_notify(struct thermal_zone_device *thermal, int trip,
printk(KERN_INFO "No secondary CPUs detached!\n");
full_run = false;
} else {
+ thermal_hot = 0;
if (!full_run) {
temperature_cooling = 0;
if (cooling_cpuhotplug)
diff --git a/drivers/mxc/vpu/Kconfig b/drivers/mxc/vpu/Kconfig
index dada2040e2ad..6562697f25f5 100644
--- a/drivers/mxc/vpu/Kconfig
+++ b/drivers/mxc/vpu/Kconfig
@@ -19,4 +19,13 @@ config MXC_VPU_DEBUG
This is an option for the developers; most people should
say N here. This enables MXC VPU driver debugging.
+config MX6_VPU_352M
+ bool "MX6 VPU 352M"
+ depends on MXC_VPU
+ default n
+ help
+ Increase VPU frequncy to 352M, the config will disable bus frequency
+ adjust dynamic, and CPU lowest setpoint will be 352Mhz.
+ This config is used for special VPU use case.
+
endmenu
diff --git a/drivers/usb/gadget/arcotg_udc.c b/drivers/usb/gadget/arcotg_udc.c
index 048776bfdc57..c3a48307c918 100755
--- a/drivers/usb/gadget/arcotg_udc.c
+++ b/drivers/usb/gadget/arcotg_udc.c
@@ -68,7 +68,6 @@
#define cpu_to_hc32(x) cpu_to_le32((x))
#define hc32_to_cpu(x) le32_to_cpu((x))
#endif
-
#define DMA_ADDR_INVALID (~(dma_addr_t)0)
DEFINE_MUTEX(udc_resume_mutex);
extern void usb_debounce_id_vbus(void);
@@ -340,7 +339,7 @@ static void dr_phy_low_power_mode(struct fsl_udc *udc, bool enable)
struct fsl_usb2_platform_data *pdata = udc->pdata;
u32 portsc;
unsigned long flags;
- spin_lock_irqsave(&udc->lock, flags);
+ spin_lock_irqsave(&pdata->lock, flags);
if (pdata && pdata->phy_lowpower_suspend) {
pdata->phy_lowpower_suspend(pdata, enable);
@@ -356,7 +355,7 @@ static void dr_phy_low_power_mode(struct fsl_udc *udc, bool enable)
}
}
pdata->lowpower = enable;
- spin_unlock_irqrestore(&udc->lock, flags);
+ spin_unlock_irqrestore(&pdata->lock, flags);
}
static int dr_controller_setup(struct fsl_udc *udc)
@@ -473,6 +472,9 @@ static void dr_controller_run(struct fsl_udc *udc)
{
u32 temp;
+ udc_controller->usb_state = USB_STATE_ATTACHED;
+ udc_controller->ep0_dir = 0;
+
fsl_platform_pullup_enable(udc->pdata);
/* Enable DR irq reg */
@@ -2206,9 +2208,9 @@ static void fsl_gadget_disconnect_event(struct work_struct *work)
fsl_writel(tmp | (OTGSC_B_SESSION_VALID_IRQ_EN),
&dr_regs->otgsc);
udc->stopped = 1;
+ spin_unlock_irqrestore(&udc->lock, flags);
/* enable wake up */
dr_wake_up_enable(udc, true);
- spin_unlock_irqrestore(&udc->lock, flags);
/* close USB PHY clock */
dr_phy_low_power_mode(udc, true);
/* close dr controller clock */
@@ -2445,8 +2447,6 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
dr_controller_run(udc_controller);
if (udc_controller->stopped)
dr_clk_gate(false);
- udc_controller->usb_state = USB_STATE_ATTACHED;
- udc_controller->ep0_dir = 0;
}
printk(KERN_INFO "%s: bind to driver %s \n",
udc_controller->gadget.name, driver->driver.name);
@@ -3210,6 +3210,7 @@ static int __devinit fsl_udc_probe(struct platform_device *pdev)
udc_controller->charger.enable = false;
#endif
+ spin_lock_init(&pdata->lock);
return 0;
err4:
@@ -3464,6 +3465,7 @@ static int fsl_udc_resume(struct platform_device *pdev)
*/
if (udc_controller->suspended && !udc_controller->stopped) {
dr_clk_gate(true);
+ dr_wake_up_enable(udc_controller, false);
dr_phy_low_power_mode(udc_controller, false);
}
/* Enable DR irq reg and set controller Run */
@@ -3483,9 +3485,6 @@ static int fsl_udc_resume(struct platform_device *pdev)
dr_controller_setup(udc_controller);
dr_controller_run(udc_controller);
}
- udc_controller->usb_state = USB_STATE_ATTACHED;
- udc_controller->ep0_dir = 0;
-
end:
/* if udc is resume by otg id change and no device
* connecting to the otg, otg will enter low power mode*/
diff --git a/drivers/usb/host/ehci-arc.c b/drivers/usb/host/ehci-arc.c
index 787374ab138d..b872d94b3fc3 100755
--- a/drivers/usb/host/ehci-arc.c
+++ b/drivers/usb/host/ehci-arc.c
@@ -31,6 +31,9 @@
extern void usb_host_set_wakeup(struct device *wkup_dev, bool para);
static void fsl_usb_lowpower_mode(struct fsl_usb2_platform_data *pdata, bool enable)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&pdata->lock, flags);
if (enable) {
if (pdata->phy_lowpower_suspend)
pdata->phy_lowpower_suspend(pdata, true);
@@ -39,6 +42,7 @@ static void fsl_usb_lowpower_mode(struct fsl_usb2_platform_data *pdata, bool ena
pdata->phy_lowpower_suspend(pdata, false);
}
pdata->lowpower = enable;
+ spin_unlock_irqrestore(&pdata->lock, flags);
}
static void fsl_usb_clk_gate(struct fsl_usb2_platform_data *pdata, bool enable)
@@ -304,6 +308,7 @@ int usb_hcd_fsl_probe(const struct hc_driver *driver,
ehci = hcd_to_ehci(hcd);
pdata->pm_command = ehci->command;
+ spin_lock_init(&pdata->lock);
return retval;
err6:
free_irq(irq, (void *)pdev);
@@ -337,7 +342,6 @@ static void usb_hcd_fsl_remove(struct usb_hcd *hcd,
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
u32 tmp;
- unsigned long flags;
if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
/* Need open clock for register access */
@@ -366,9 +370,7 @@ static void usb_hcd_fsl_remove(struct usb_hcd *hcd,
}
/*disable the host wakeup and put phy to low power mode */
usb_host_set_wakeup(hcd->self.controller, false);
- spin_lock_irqsave(&ehci->lock, flags);
fsl_usb_lowpower_mode(pdata, true);
- spin_unlock_irqrestore(&ehci->lock, flags);
/*free the ehci_fsl_pre_irq */
free_irq(hcd->irq, (void *)pdev);
usb_remove_hcd(hcd);
@@ -430,7 +432,6 @@ static int ehci_fsl_bus_suspend(struct usb_hcd *hcd)
struct fsl_usb2_platform_data *pdata;
u32 tmp, portsc, cmd;
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- unsigned long flags;
pdata = hcd->self.controller->platform_data;
printk(KERN_DEBUG "%s begins, %s\n", __func__, pdata->name);
@@ -458,9 +459,7 @@ static int ehci_fsl_bus_suspend(struct usb_hcd *hcd)
if (pdata->platform_suspend)
pdata->platform_suspend(pdata);
usb_host_set_wakeup(hcd->self.controller, true);
- spin_lock_irqsave(&ehci->lock, flags);
fsl_usb_lowpower_mode(pdata, true);
- spin_unlock_irqrestore(&ehci->lock, flags);
fsl_usb_clk_gate(hcd->self.controller->platform_data, false);
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
printk(KERN_DEBUG "%s ends, %s\n", __func__, pdata->name);
@@ -472,8 +471,6 @@ static int ehci_fsl_bus_resume(struct usb_hcd *hcd)
{
int ret = 0;
struct fsl_usb2_platform_data *pdata;
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- unsigned long flags;
pdata = hcd->self.controller->platform_data;
printk(KERN_DEBUG "%s begins, %s\n", __func__, pdata->name);
@@ -490,9 +487,7 @@ static int ehci_fsl_bus_resume(struct usb_hcd *hcd)
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
fsl_usb_clk_gate(hcd->self.controller->platform_data, true);
usb_host_set_wakeup(hcd->self.controller, false);
- spin_lock_irqsave(&ehci->lock, flags);
fsl_usb_lowpower_mode(pdata, false);
- spin_unlock_irqrestore(&ehci->lock, flags);
}
if (pdata->platform_resume)
@@ -669,7 +664,6 @@ static int ehci_fsl_drv_suspend(struct platform_device *pdev,
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
struct usb_device *roothub = hcd->self.root_hub;
- unsigned long flags;
u32 port_status;
struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
@@ -745,9 +739,7 @@ static int ehci_fsl_drv_suspend(struct platform_device *pdev,
pdata->pm_portsc &= ~PORT_PTS_PHCD;
usb_host_set_wakeup(hcd->self.controller, true);
- spin_lock_irqsave(&ehci->lock, flags);
fsl_usb_lowpower_mode(pdata, true);
- spin_unlock_irqrestore(&ehci->lock, flags);
if (test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
@@ -801,9 +793,7 @@ static int ehci_fsl_drv_resume(struct platform_device *pdev)
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
fsl_usb_clk_gate(hcd->self.controller->platform_data, true);
usb_host_set_wakeup(hcd->self.controller, false);
- spin_lock_irqsave(&ehci->lock, flags);
fsl_usb_lowpower_mode(pdata, false);
- spin_unlock_irqrestore(&ehci->lock, flags);
}
spin_lock_irqsave(&ehci->lock, flags);
diff --git a/drivers/video/mxc/ldb.c b/drivers/video/mxc/ldb.c
index 8b84498fd285..426b139b14b8 100644
--- a/drivers/video/mxc/ldb.c
+++ b/drivers/video/mxc/ldb.c
@@ -316,7 +316,14 @@ int ldb_fb_event(struct notifier_block *nb, unsigned long val, void *v)
writel(data, ldb->control_reg);
}
}
+ break;
}
+ case FB_EVENT_SUSPEND:
+ if (ldb->setting[index].clk_en) {
+ clk_disable(ldb->setting[index].ldb_di_clk);
+ ldb->setting[index].clk_en = false;
+ }
+ break;
default:
break;
}
diff --git a/drivers/video/mxc/mxc_ipuv3_fb.c b/drivers/video/mxc/mxc_ipuv3_fb.c
index a2ccbaa81a8d..8a052e0433d3 100644
--- a/drivers/video/mxc/mxc_ipuv3_fb.c
+++ b/drivers/video/mxc/mxc_ipuv3_fb.c
@@ -436,13 +436,13 @@ static int mxcfb_set_par(struct fb_info *fbi)
dma_alloc_coherent(fbi->device,
alpha_mem_len,
&mxc_fbi->alpha_phy_addr0,
- GFP_KERNEL);
+ GFP_DMA | GFP_KERNEL);
mxc_fbi->alpha_virt_addr1 =
dma_alloc_coherent(fbi->device,
alpha_mem_len,
&mxc_fbi->alpha_phy_addr1,
- GFP_KERNEL);
+ GFP_DMA | GFP_KERNEL);
if (mxc_fbi->alpha_virt_addr0 == NULL ||
mxc_fbi->alpha_virt_addr1 == NULL) {
dev_err(fbi->device, "mxcfb: dma alloc for"
@@ -1782,7 +1782,7 @@ static int mxcfb_map_video_memory(struct fb_info *fbi)
fbi->screen_base = dma_alloc_writecombine(fbi->device,
fbi->fix.smem_len,
(dma_addr_t *)&fbi->fix.smem_start,
- GFP_KERNEL);
+ GFP_DMA | GFP_KERNEL);
if (fbi->screen_base == 0) {
dev_err(fbi->device, "Unable to allocate framebuffer memory\n");
fbi->fix.smem_len = 0;
diff --git a/drivers/video/mxc_hdmi.c b/drivers/video/mxc_hdmi.c
index 999e3b157211..9e23bdea331f 100644
--- a/drivers/video/mxc_hdmi.c
+++ b/drivers/video/mxc_hdmi.c
@@ -1543,6 +1543,7 @@ static void mxc_hdmi_notify_fb(struct mxc_hdmi *hdmi)
static void mxc_hdmi_edid_rebuild_modelist(struct mxc_hdmi *hdmi)
{
int i;
+ struct fb_videomode *mode;
dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
@@ -1554,10 +1555,14 @@ static void mxc_hdmi_edid_rebuild_modelist(struct mxc_hdmi *hdmi)
for (i = 0; i < hdmi->fbi->monspecs.modedb_len; i++) {
/*
* We might check here if mode is supported by HDMI.
- * We do not currently support interlaced modes
+ * We do not currently support interlaced modes.
+ * And add CEA modes in the modelist.
*/
- if (!(hdmi->fbi->monspecs.modedb[i].vmode &
- FB_VMODE_INTERLACED)) {
+ mode = &hdmi->fbi->monspecs.modedb[i];
+
+ if (!(mode->vmode & FB_VMODE_INTERLACED) &&
+ (mxc_edid_mode_to_vic(mode) != 0)) {
+
dev_dbg(&hdmi->pdev->dev, "Added mode %d:", i);
dev_dbg(&hdmi->pdev->dev,
"xres = %d, yres = %d, freq = %d, vmode = %d, flag = %d\n",
@@ -1567,8 +1572,7 @@ static void mxc_hdmi_edid_rebuild_modelist(struct mxc_hdmi *hdmi)
hdmi->fbi->monspecs.modedb[i].vmode,
hdmi->fbi->monspecs.modedb[i].flag);
- fb_add_videomode(&hdmi->fbi->monspecs.modedb[i],
- &hdmi->fbi->modelist);
+ fb_add_videomode(mode, &hdmi->fbi->modelist);
}
}
@@ -1651,6 +1655,8 @@ static void mxc_hdmi_set_mode(struct mxc_hdmi *hdmi)
if (fb_mode_is_equal(&hdmi->previous_non_vga_mode, mode)) {
dev_dbg(&hdmi->pdev->dev,
"%s: Video mode same as previous\n", __func__);
+ /* update fbi mode in case modelist is updated */
+ hdmi->fbi->mode = mode;
mxc_hdmi_phy_init(hdmi);
} else {
dev_dbg(&hdmi->pdev->dev, "%s: New video mode\n", __func__);
@@ -1674,6 +1680,13 @@ static void mxc_hdmi_cable_connected(struct mxc_hdmi *hdmi)
/* HDMI Initialization Step C */
edid_status = mxc_hdmi_read_edid(hdmi);
+ /* Read EDID again if first EDID read failed */
+ if (edid_status == HDMI_EDID_NO_MODES ||
+ edid_status == HDMI_EDID_FAIL) {
+ dev_info(&hdmi->pdev->dev, "Read EDID again\n");
+ edid_status = mxc_hdmi_read_edid(hdmi);
+ }
+
/* HDMI Initialization Steps D, E, F */
switch (edid_status) {
case HDMI_EDID_SUCCESS:
@@ -1756,10 +1769,13 @@ static void hotplug_worker(struct work_struct *work)
#ifdef CONFIG_MXC_HDMI_CEC
mxc_hdmi_cec_handle(0x80);
#endif
+ hdmi_set_cable_state(1);
} else if (!(phy_int_pol & HDMI_PHY_HPD)) {
/* Plugout event */
dev_dbg(&hdmi->pdev->dev, "EVENT=plugout\n");
+ hdmi_set_cable_state(0);
+ mxc_hdmi_abort_stream();
mxc_hdmi_cable_disconnected(hdmi);
/* Make HPD intr active high to capture plugin event */
@@ -2048,10 +2064,13 @@ static int mxc_hdmi_fb_event(struct notifier_block *nb,
if (hdmi->fb_reg && hdmi->cable_plugin)
mxc_hdmi_setup(hdmi, val);
+ hdmi_set_blank_state(1);
} else if (*((int *)event->data) != hdmi->blank) {
dev_dbg(&hdmi->pdev->dev,
"event=FB_EVENT_BLANK - BLANK\n");
+ hdmi_set_blank_state(0);
+ mxc_hdmi_abort_stream();
mxc_hdmi_phy_disable(hdmi);