From 888043b51487bb2f23f700159eb2e514b0c9ee88 Mon Sep 17 00:00:00 2001 From: Ryan QIAN Date: Tue, 9 Oct 2012 07:44:34 +0800 Subject: ENGR00227420 mmc: sdhci: shorten the delay on disabling clk - change the delay from 10 * HZ to 1 * HZ, though (1 * HZ) might not be the best, just as a base. 1. Since the request has been moved out of interrupt context, there will be no more calling enable_clk in interrupt context. So it's not necessary to keep such a long delay on disabling clock in order to save power. 2. Still keeping the 1*HZ of delay is to avoid frequently enabling/disabling clock. eMMC card performance test result with bonnie++: (512M RAM, 1GB data, 1K buffer) ------------------------------------------------------------------------------ | | 1*HZ | 10 * HZ | ------------------------------------------------------------------------------ | Read | ~24.1MB/s | ~23.9MB/s | ------------------------------------------------------------------------------ | Write | ~10.5MB/s | ~10.5MB/s | ------------------------------------------------------------------------------ WiFi card performance test result with iperf is quite same: ~21Mbps (AR6003@2.4G, TCP, TCP window size option 1MB both for server and client) Acked-by: Robby CAI Signed-off-by: Ryan QIAN --- drivers/mmc/host/sdhci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 49bbaa52f7e6..e8f78aebdefe 100755 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -30,7 +30,7 @@ #include "sdhci.h" #define DRIVER_NAME "sdhci" -#define CLK_TIMEOUT (10 * HZ) +#define CLK_TIMEOUT (1 * HZ) #define DBG(f, x...) \ pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x) -- cgit v1.2.3 From 1c3e0506b0c1ff68e20aa8f96fc35a9f7e15a207 Mon Sep 17 00:00:00 2001 From: Robby Cai Date: Thu, 11 Oct 2012 17:18:15 +0800 Subject: ENGR00227890 ts: fix elan touch screen gets no response upon suspend/resume To reproduce: 1. let system enter suspend mode 2. touch the screen 3. after the system resumes, touch screen does not respond again. The cause: The touch screen interrupt is triggered by falling edge. During suspend stage, once the screen has ever been touched, then the interrupt line will be always pulled low. Since elan ts chip is always powered on and the interrupt gets no chance to be handled during suspend stage, the interrupt line can not recover to high to detect a new one. Workaround: Read out the pending data to make the touch screen come back alive. Signed-off-by: LiGang Signed-off-by: Robby Cai --- drivers/input/touchscreen/elan_ts.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/input/touchscreen/elan_ts.c b/drivers/input/touchscreen/elan_ts.c index 7edd87d6cd1b..90272594d120 100644 --- a/drivers/input/touchscreen/elan_ts.c +++ b/drivers/input/touchscreen/elan_ts.c @@ -359,6 +359,33 @@ static const struct i2c_device_id elan_touch_id[] = { {} }; +static int elan_suspend(struct device *dev) +{ + return 0; +} + +static int elan_resume(struct device *dev) +{ + uint8_t buf[IDX_PACKET_SIZE] = { 0 }; + + if (0 == elan_touch_detect_int_level()) { + dev_dbg(dev, "Got touch during suspend period.\n"); + /* + * if touch screen during suspend, recv and drop the + * data, then touch interrupt pin will return high after + * receving data. + */ + elan_touch_recv_data(elan_touch_data.client, buf); + } + + return 0; +} + +static const struct dev_pm_ops elan_dev_pm_ops = { + .suspend = elan_suspend, + .resume = elan_resume, +}; + static struct i2c_driver elan_touch_driver = { .probe = elan_touch_probe, .remove = elan_touch_remove, @@ -366,6 +393,9 @@ static struct i2c_driver elan_touch_driver = { .driver = { .name = "elan-touch", .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &elan_dev_pm_ops, +#endif }, }; -- cgit v1.2.3 From 08ea59eebbd2ac38bcd1ae2a125fde0b0dd8593d Mon Sep 17 00:00:00 2001 From: Terry Lv Date: Fri, 12 Oct 2012 14:39:34 +0800 Subject: ENGR00229327: otp: driver causes warning when enable CONFIG_LOCKDEP When CONFIG_LOCKDEP is enabled, it will cause warings: ------------[ cut here ]------------ WARNING: at kernel/lockdep.c:2885 sysfs_add_file_mode+0x54/0xc0() Modules linked in: [<80046364>] (unwind_backtrace+0x0/0xfc) from [<800758c0>] (warn_slowpath_common+0x4c/0x64) [<800758c0>] (warn_slowpath_common+0x4c/0x64) from [<800758f4>] (warn_slowpath_null+0x1c/0x24) [<800758f4>] (warn_slowpath_null+0x1c/0x24) from [<801536c4>] (sysfs_add_file_mode+0x54/0xc0) [<801536c4>] (sysfs_add_file_mode+0x54/0xc0) from [<8015616c>] (internal_create_group+0xdc/0x1d8) [<8015616c>] (internal_create_group+0xdc/0x1d8) from [<80524110>] (fsl_otp_probe+0x168/0x1d4) [<80524110>] (fsl_otp_probe+0x168/0x1d4) from [<802b42e8>] (platform_drv_probe+0x18/0x1c) [<802b42e8>] (platform_drv_probe+0x18/0x1c) from [<802b2fe4>] (driver_probe_device+0x98/0x1a4) [<802b2fe4>] (driver_probe_device+0x98/0x1a4) from [<802b3184>] (__driver_attach+0x94/0x98) [<802b3184>] (__driver_attach+0x94/0x98) from [<802b280c>] (bus_for_each_dev+0x60/0x8c) [<802b280c>] (bus_for_each_dev+0x60/0x8c) from [<802b2180>] (bus_add_driver+0x190/0x268) [<802b2180>] (bus_add_driver+0x190/0x268) from [<802b3788>] (driver_register+0x78/0x13c) [<802b3788>] (driver_register+0x78/0x13c) from [<800394ac>] (do_one_initcall+0x30/0x170) [<800394ac>] (do_one_initcall+0x30/0x170) from [<800083cc>] (kernel_init+0x98/0x144) [<800083cc>] (kernel_init+0x98/0x144) from [<8004003c>] (kernel_thread_exit+0x0/0x8) ---[ end trace 877415a10b5d9cb1 ]--- also, on imx6sl, it will cause below issue: BUG: key bffea2e4 not in .data! BUG: key bffea300 not in .data! BUG: key bffea31c not in .data! BUG: key bffea338 not in .data! BUG: key bffea354 not in .data! BUG: key bffea370 not in .data! BUG: key bffea38c not in .data! BUG: key bffea3a8 not in .data! BUG: key bffea3c4 not in .data! BUG: key bffea3e0 not in .data! BUG: key bffea3fc not in .data! BUG: key bffea418 not in .data! BUG: key bffea434 not in .data! BUG: key bffea450 not in .data! BUG: key bffea46c not in .data! BUG: key bffea488 not in .data! BUG: key bffea4a4 not in .data! BUG: key bffea4c0 not in .data! BUG: key bffea4dc not in .data! We need to call sysfs_attr_init to initlize sysfs attr. Signed-off-by: Terry Lv --- drivers/char/fsl_otp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/char/fsl_otp.c b/drivers/char/fsl_otp.c index 05ad55e9d6a9..7021c42c4bfd 100755 --- a/drivers/char/fsl_otp.c +++ b/drivers/char/fsl_otp.c @@ -1,7 +1,7 @@ /* * Freescale On-Chip OTP driver * - * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2010-2012 Freescale Semiconductor, Inc. All Rights Reserved. * * 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 @@ -153,6 +153,7 @@ static int __init alloc_otp_attr(struct mxc_otp_platform_data *pdata) goto error_out; for (i = 0; i < otp_data->fuse_num; i++) { + sysfs_attr_init(&kattr[i].attr); kattr[i].attr.name = pdata->fuse_name[i]; kattr[i].attr.mode = 0600; kattr[i].show = otp_show; -- cgit v1.2.3 From 1a9a72b98ba330463b9e7b27edafed0ca1c64b04 Mon Sep 17 00:00:00 2001 From: Robby Cai Date: Thu, 11 Oct 2012 19:43:49 +0800 Subject: ENGR00229222 mmc: esdhc: allow MMC and SDIO cards switched to 1.8V signalling The current driver only allows SD cards to run at 1.8V. This patch allows MMC and SDIO cards to be switched to 1.8V signalling Acked-by: Dong Aisheng Signed-off-by: Robby Cai --- drivers/mmc/host/sdhci-esdhc-imx.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 39eb287d638b..59cc92ce7410 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -841,12 +841,18 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd MMC_VDD_32_33 | MMC_VDD_33_34; host->ocr_avail_mmc = MMC_VDD_29_30 | MMC_VDD_30_31 | \ MMC_VDD_32_33 | MMC_VDD_33_34; + host->ocr_avail_sdio = MMC_VDD_29_30 | MMC_VDD_30_31 | \ + MMC_VDD_32_33 | MMC_VDD_33_34; if (cpu_is_mx6q() || cpu_is_mx6dl()) sdhci_esdhc_ops.platform_execute_tuning = esdhc_execute_tuning; - if (boarddata->support_18v) + if (boarddata->support_18v) { host->ocr_avail_sd |= MMC_VDD_165_195; + host->ocr_avail_mmc |= MMC_VDD_165_195; + host->ocr_avail_sdio |= MMC_VDD_165_195; + } + if (boarddata->support_8bit) host->mmc->caps |= MMC_CAP_8_BIT_DATA; if (boarddata->keep_power_at_suspend) -- cgit v1.2.3 From 415a6e33057feada07d6e5f2e295ff6d0beeb6de Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 12 Oct 2012 15:23:49 +0800 Subject: ENGR00229338: usb: fix using lock before initialization problem It will cause below problem if spin_lock debug is on: BUG: spinlock lockup on CPU#0, swapper/1, 9a0292a0 The reason is the lock is used before initialization. Signed-off-by: Peter Chen --- drivers/usb/gadget/arcotg_udc.c | 3 ++- drivers/usb/host/ehci-arc.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/arcotg_udc.c b/drivers/usb/gadget/arcotg_udc.c index 86518d9855ac..75fe978a8e01 100755 --- a/drivers/usb/gadget/arcotg_udc.c +++ b/drivers/usb/gadget/arcotg_udc.c @@ -3065,6 +3065,8 @@ static int __devinit fsl_udc_probe(struct platform_device *pdev) goto err2a; } + spin_lock_init(&pdata->lock); + /* Due to mx35/mx25's phy's bug */ reset_phy(); @@ -3210,7 +3212,6 @@ static int __devinit fsl_udc_probe(struct platform_device *pdev) udc_controller->charger.enable = false; #endif - spin_lock_init(&pdata->lock); return 0; err4: diff --git a/drivers/usb/host/ehci-arc.c b/drivers/usb/host/ehci-arc.c index e09f4dfd05d9..35815869bb8d 100755 --- a/drivers/usb/host/ehci-arc.c +++ b/drivers/usb/host/ehci-arc.c @@ -260,6 +260,8 @@ int usb_hcd_fsl_probe(const struct hc_driver *driver, goto err4; } + spin_lock_init(&pdata->lock); + fsl_platform_set_host_mode(hcd); hcd->power_budget = pdata->power_budget; ehci = hcd_to_ehci(hcd); @@ -308,7 +310,6 @@ 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); -- cgit v1.2.3 From d3db7a4dadede46f35eb1b4d570fd8f7a95c0c31 Mon Sep 17 00:00:00 2001 From: make shi Date: Fri, 12 Oct 2012 17:01:33 +0800 Subject: ENGR00229354 Mx6 USB device: fix wrong handle for invalid USB_FEATURE requests There is a bug udc driver handle invalid USB_FEATURE requests in current bsp. The invalid USB_FEATURE request will be handled as a valid USB_FEATURE request. We should set protocol stall on ep0 to handle invalid USB_FEATURE requests. Signed-off-by: make shi --- drivers/usb/gadget/arcotg_udc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/gadget/arcotg_udc.c b/drivers/usb/gadget/arcotg_udc.c index 75fe978a8e01..484e62e79ba9 100755 --- a/drivers/usb/gadget/arcotg_udc.c +++ b/drivers/usb/gadget/arcotg_udc.c @@ -1695,6 +1695,10 @@ static void setup_received_irq(struct fsl_udc *udc, else if (setup->bRequest == USB_DEVICE_A_ALT_HNP_SUPPORT) udc->gadget.a_alt_hnp_support = 1; + else + break; + } else { + break; } rc = 0; } else -- cgit v1.2.3 From b895b75c7f7786252aa65b0e9fa07a3ab81a3de0 Mon Sep 17 00:00:00 2001 From: Robby Cai Date: Thu, 11 Oct 2012 14:50:34 +0800 Subject: ENGR00227726 csi: Disable csi clock when it's inactive Disable csi clock when inactive, otherwise this prevents system from entering low power mode. Signed-off-by: Robby Cai --- drivers/media/video/mxc/capture/csi_v4l2_capture.c | 6 ++++-- drivers/media/video/mxc/capture/fsl_csi.c | 10 ++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/media/video/mxc/capture/csi_v4l2_capture.c b/drivers/media/video/mxc/capture/csi_v4l2_capture.c index a0887b930ea4..5eb750ce82ab 100644 --- a/drivers/media/video/mxc/capture/csi_v4l2_capture.c +++ b/drivers/media/video/mxc/capture/csi_v4l2_capture.c @@ -1536,7 +1536,8 @@ static int csi_v4l2_suspend(struct platform_device *pdev, pm_message_t state) if (cam->overlay_on == true) stop_preview(cam); - camera_power(cam, false); + if (cam->capture_on == true || cam->overlay_on == true) + camera_power(cam, false); return 0; } @@ -1561,7 +1562,8 @@ static int csi_v4l2_resume(struct platform_device *pdev) cam->low_power = false; wake_up_interruptible(&cam->power_queue); - camera_power(cam, true); + if (cam->capture_on == true || cam->overlay_on == true) + camera_power(cam, true); if (cam->overlay_on == true) start_preview(cam); diff --git a/drivers/media/video/mxc/capture/fsl_csi.c b/drivers/media/video/mxc/capture/fsl_csi.c index 33a82242e95e..f5677e473e87 100644 --- a/drivers/media/video/mxc/capture/fsl_csi.c +++ b/drivers/media/video/mxc/capture/fsl_csi.c @@ -250,12 +250,14 @@ static void csi_mclk_recalc(struct clk *clk) void csi_mclk_enable(void) { + clk_enable(&csi_mclk); __raw_writel(__raw_readl(CSI_CSICR1) | BIT_MCLKEN, CSI_CSICR1); } void csi_mclk_disable(void) { __raw_writel(__raw_readl(CSI_CSICR1) & ~BIT_MCLKEN, CSI_CSICR1); + clk_disable(&csi_mclk); } static int __devinit csi_probe(struct platform_device *pdev) @@ -293,8 +295,13 @@ static int __devinit csi_probe(struct platform_device *pdev) return PTR_ERR(per_clk); clk_put(per_clk); + /* + * On mx6sl, there's no divider in CSI module(BIT_MCLKDIV in CSI_CSICR1 + * is marked as reserved). We use CSI clock in CCM. + * However, the value read from BIT_MCLKDIV bits are 0, which is + * equivalent to "divider=1". The code works for mx6sl without change. + */ csi_mclk.parent = per_clk; - clk_enable(per_clk); csi_mclk_recalc(&csi_mclk); err: @@ -303,7 +310,6 @@ err: static int __devexit csi_remove(struct platform_device *pdev) { - clk_disable(&csi_mclk); iounmap(csi_regbase); return 0; -- cgit v1.2.3 From 8452462bb91a3f9e9fbb1b6e3474e0b7fc10fcb5 Mon Sep 17 00:00:00 2001 From: Robby Cai Date: Wed, 10 Oct 2012 15:17:27 +0800 Subject: ENGR00227873-1 pxp/v4l2: make the v4l2 output device index auto assigned It used the hard-coded '0' for historical reason. This patch changes it to -1 to make video device minor to be automatically assigned. Signed-off-by: Robby Cai --- drivers/media/video/mxc/output/mxc_pxp_v4l2.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/mxc/output/mxc_pxp_v4l2.c b/drivers/media/video/mxc/output/mxc_pxp_v4l2.c index a3a8294efb8e..c17f9f1d9cdc 100644 --- a/drivers/media/video/mxc/output/mxc_pxp_v4l2.c +++ b/drivers/media/video/mxc/output/mxc_pxp_v4l2.c @@ -54,6 +54,7 @@ #define V4L2_OUTPUT_TYPE_INTERNAL 4 +static int video_nr = -1; /* -1 ==> auto assign */ static struct pxp_data_format pxp_s0_formats[] = { { .name = "24-bit RGB", @@ -1175,7 +1176,7 @@ static int pxp_probe(struct platform_device *pdev) memcpy(pxp->vdev, &pxp_template, sizeof(pxp_template)); video_set_drvdata(pxp->vdev, pxp); - err = video_register_device(pxp->vdev, VFL_TYPE_GRABBER, 0); + err = video_register_device(pxp->vdev, VFL_TYPE_GRABBER, video_nr); if (err) { dev_err(&pdev->dev, "failed to register video device\n"); goto freevdev; @@ -1235,6 +1236,7 @@ static void __exit pxp_exit(void) module_init(pxp_init); module_exit(pxp_exit); +module_param(video_nr, int, 0444); MODULE_DESCRIPTION("MXC PxP V4L2 driver"); MODULE_AUTHOR("Freescale Semiconductor, Inc."); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From db2d26ee2a68ee9a5859efad768936c37fe90e00 Mon Sep 17 00:00:00 2001 From: Robby Cai Date: Thu, 11 Oct 2012 15:10:13 +0800 Subject: ENGR00227873-2 mx6sl: enable pxp v4l2 option in defconfig Enable CONFIG_VIDEO_MXC_PXP_V4L2 option. Signed-off-by: Robby Cai --- arch/arm/configs/imx6s_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/configs/imx6s_defconfig b/arch/arm/configs/imx6s_defconfig index ac7afdfdf5ff..41f43e5c0d63 100644 --- a/arch/arm/configs/imx6s_defconfig +++ b/arch/arm/configs/imx6s_defconfig @@ -1620,7 +1620,7 @@ CONFIG_MXC_CAMERA_OV5640=y # CONFIG_MXC_CAMERA_OV5640_MIPI is not set CONFIG_MXC_CAMERA_SENSOR_CLK=y CONFIG_VIDEO_MXC_OUTPUT=y -# CONFIG_VIDEO_MXC_PXP_V4L2 is not set +CONFIG_VIDEO_MXC_PXP_V4L2=y # CONFIG_VIDEO_MXC_OPL is not set # CONFIG_VIDEO_CPIA2 is not set # CONFIG_VIDEO_TIMBERDALE is not set -- cgit v1.2.3 From 1f82d60280ffa934968815547df2b231931dbd89 Mon Sep 17 00:00:00 2001 From: Nancy Chen Date: Thu, 11 Oct 2012 10:18:24 -0500 Subject: ENGR00229299 [MX6SL] Kernel cannot boot if enable LOCKDEP 1. Fix mutex_lock nested issue in idle mode 2. Fix mutex_lock nested issue in suspend mode 3. Fix spin_lock nested issue in busfreq Signed-off-by: Nancy Chen --- arch/arm/mach-mx6/bus_freq.c | 7 +------ arch/arm/mach-mx6/clock_mx6sl.c | 2 -- arch/arm/mach-mx6/pm.c | 3 --- arch/arm/mach-mx6/system.c | 10 ++++------ 4 files changed, 5 insertions(+), 17 deletions(-) diff --git a/arch/arm/mach-mx6/bus_freq.c b/arch/arm/mach-mx6/bus_freq.c index 9d18423c85c5..f500516a99a2 100644 --- a/arch/arm/mach-mx6/bus_freq.c +++ b/arch/arm/mach-mx6/bus_freq.c @@ -110,7 +110,7 @@ static struct clk *pll1; static struct clk *pll1_sw_clk; static struct clk *pll3_sw_clk; static struct clk *pll2_200; -static struct clk *mmdc_ch0_axi; +struct clk *mmdc_ch0_axi; static struct clk *pll3_540; static struct delayed_work low_bus_freq_handler; @@ -155,8 +155,6 @@ void reduce_bus_freq(void) u32 div; unsigned long flags; - spin_lock_irqsave(&freq_lock, flags); - if (high_bus_freq_mode) { /* Set periph_clk to be sourced from OSC_CLK */ /* Set AXI to 24MHz. */ @@ -220,7 +218,6 @@ void reduce_bus_freq(void) low_bus_freq_mode = 1; audio_bus_freq_mode = 0; } - spin_unlock_irqrestore(&freq_lock, flags); } high_bus_freq_mode = 0; @@ -322,7 +319,6 @@ int set_high_bus_freq(int high_bus_freq) u32 reg; unsigned long flags; - spin_lock_irqsave(&freq_lock, flags); /* Change DDR freq in IRAM. */ mx6sl_ddr_freq_change_iram(ddr_normal_rate, low_bus_freq_mode); @@ -348,7 +344,6 @@ int set_high_bus_freq(int high_bus_freq) high_bus_freq_mode = 1; low_bus_freq_mode = 0; audio_bus_freq_mode = 0; - spin_unlock_irqrestore(&freq_lock, flags); } else { clk_enable(pll3); if (high_bus_freq) { diff --git a/arch/arm/mach-mx6/clock_mx6sl.c b/arch/arm/mach-mx6/clock_mx6sl.c index 6de15622eede..a18427c51515 100755 --- a/arch/arm/mach-mx6/clock_mx6sl.c +++ b/arch/arm/mach-mx6/clock_mx6sl.c @@ -103,7 +103,6 @@ DEFINE_SPINLOCK(mx6sl_clk_lock); u32 reg; \ unsigned long flags; \ int result = 1; \ - spin_lock_irqsave(&mx6sl_clk_lock, flags); \ gpt_rate = clk_get_rate(&gpt_clk[0]); \ gpt_ticks = timeout / (1000000000 / gpt_rate); \ reg = __raw_readl(timer_base + V2_TSTAT);\ @@ -133,7 +132,6 @@ DEFINE_SPINLOCK(mx6sl_clk_lock); } \ } \ } \ - spin_unlock_irqrestore(&mx6sl_clk_lock, flags); \ result; \ }) diff --git a/arch/arm/mach-mx6/pm.c b/arch/arm/mach-mx6/pm.c index faf1a59ec2d6..b80a6b259965 100644 --- a/arch/arm/mach-mx6/pm.c +++ b/arch/arm/mach-mx6/pm.c @@ -335,9 +335,6 @@ static int mx6_suspend_enter(suspend_state_t state) return -EINVAL; } - axi_org_parent = clk_get_parent(axi_clk); - clk_set_parent(axi_clk, periph_clk); - if (state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY) { if (pm_data && pm_data->suspend_enter) pm_data->suspend_enter(); diff --git a/arch/arm/mach-mx6/system.c b/arch/arm/mach-mx6/system.c index 533d4f5dbfab..fdbf58cec947 100644 --- a/arch/arm/mach-mx6/system.c +++ b/arch/arm/mach-mx6/system.c @@ -51,7 +51,7 @@ extern unsigned int gpc_wake_irq[4]; static void __iomem *gpc_base = IO_ADDRESS(GPC_BASE_ADDR); -static struct clk *ddr_clk; +extern struct clk *mmdc_ch0_axi; volatile unsigned int num_cpu_idle; volatile unsigned int num_cpu_idle_lock = 0x0; @@ -272,11 +272,9 @@ void arch_idle_single_core(void) ca9_do_idle(); } else { if (low_bus_freq_mode || audio_bus_freq_mode) { - u32 ddr_usecount; - if (ddr_clk == NULL) - ddr_clk = clk_get(NULL , - "mmdc_ch0_axi"); - ddr_usecount = clk_get_usecount(ddr_clk); + u32 ddr_usecount; + if ((mmdc_ch0_axi != NULL) && ddr_usecount) + ddr_usecount = clk_get_usecount(mmdc_ch0_axi); if (cpu_is_mx6sl() && low_bus_freq_mode && ddr_usecount == 1) { -- cgit v1.2.3 From b8c142d2e7cfc27b98990d39305b52d2208cb36e Mon Sep 17 00:00:00 2001 From: Michael Minnick Date: Tue, 9 Oct 2012 18:06:31 -0500 Subject: ENGR00229290 EPDC: MX6: Adjust number of LUTs for 5-bit waveform When a 5-bit waveform is loaded, the maximum number of available LUTs is 16. The LUT allocator must account for this. Note that 5-bit waveform loading is currently not supported in the driver. However, this fix makes sure the LUT allocator is correct when 5-bit support is added. Signed-off-by: Michael Minnick --- drivers/video/mxc/mxc_epdc_fb.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/video/mxc/mxc_epdc_fb.c b/drivers/video/mxc/mxc_epdc_fb.c index b702788ae823..38a183c8d861 100644 --- a/drivers/video/mxc/mxc_epdc_fb.c +++ b/drivers/video/mxc/mxc_epdc_fb.c @@ -735,18 +735,24 @@ static int epdc_choose_next_lut(int rev, int *next_lut) { u64 luts_status, unprocessed_luts; bool next_lut_found = false; + /* Available LUTs are reduced to 16 in 5-bit waveform mode */ + u32 format_p5n = __raw_readl(EPDC_FORMAT) & + EPDC_FORMAT_BUF_PIXEL_FORMAT_P5N; luts_status = __raw_readl(EPDC_STATUS_LUTS); - if (rev < 20) + if ((rev < 20) || format_p5n) luts_status &= 0xFFFF; else luts_status |= ((u64)__raw_readl(EPDC_STATUS_LUTS2) << 32); - if (rev < 20) + if (rev < 20) { unprocessed_luts = __raw_readl(EPDC_IRQ) & 0xFFFF; - else + } else { unprocessed_luts = __raw_readl(EPDC_IRQ1) | ((u64)__raw_readl(EPDC_IRQ2) << 32); + if (format_p5n) + unprocessed_luts &= 0xFFFF; + } while (!next_lut_found) { /* @@ -762,7 +768,7 @@ static int epdc_choose_next_lut(int rev, int *next_lut) */ *next_lut = fls64(luts_status); - if (rev < 20) { + if ((rev < 20) || format_p5n) { if (*next_lut > 15) *next_lut = ffz(luts_status); } else { -- cgit v1.2.3 From b5cb68fb26eae39d5022519d5d80d69aef14a2c9 Mon Sep 17 00:00:00 2001 From: Nancy Chen Date: Fri, 12 Oct 2012 10:15:30 -0500 Subject: ENGR00229437 [MX6SL] Fix AHB clock not changed to 3MHz in IDLE mode 1. Fix AHB clock not changed to 3MHz in IDLE mode 2. Fix system hangs in IDLE mode due to changes made for LOCKDEP Signed-off-by: Nancy Chen --- arch/arm/mach-mx6/bus_freq.c | 7 +++++++ arch/arm/mach-mx6/pm.c | 1 - arch/arm/mach-mx6/system.c | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-mx6/bus_freq.c b/arch/arm/mach-mx6/bus_freq.c index f500516a99a2..f25882bd40d1 100644 --- a/arch/arm/mach-mx6/bus_freq.c +++ b/arch/arm/mach-mx6/bus_freq.c @@ -168,8 +168,11 @@ void reduce_bus_freq(void) if (lp_audio_freq) { /* PLL2 is on in this mode, as DDR is at 50MHz. */ /* Now change DDR freq while running from IRAM. */ + + spin_lock_irqsave(&freq_lock, flags); mx6sl_ddr_freq_change_iram(DDR_AUDIO_CLK, low_bus_freq_mode); + spin_unlock_irqrestore(&freq_lock, flags); if (low_bus_freq_mode) { /* Swtich ARM to run off PLL2_PFD2_400MHz @@ -211,9 +214,11 @@ void reduce_bus_freq(void) ; clk_set_parent(pll1_sw_clk, pll1); + spin_lock_irqsave(&freq_lock, flags); /* Now change DDR freq while running from IRAM. */ mx6sl_ddr_freq_change_iram(LPAPM_CLK, low_bus_freq_mode); + spin_unlock_irqrestore(&freq_lock, flags); low_bus_freq_mode = 1; audio_bus_freq_mode = 0; @@ -319,8 +324,10 @@ int set_high_bus_freq(int high_bus_freq) u32 reg; unsigned long flags; + spin_lock_irqsave(&freq_lock, flags); /* Change DDR freq in IRAM. */ mx6sl_ddr_freq_change_iram(ddr_normal_rate, low_bus_freq_mode); + spin_unlock_irqrestore(&freq_lock, flags); /* Set periph_clk to be sourced from pll2_pfd2_400M */ /* First need to set the divider before changing the */ diff --git a/arch/arm/mach-mx6/pm.c b/arch/arm/mach-mx6/pm.c index b80a6b259965..2308e332dc44 100644 --- a/arch/arm/mach-mx6/pm.c +++ b/arch/arm/mach-mx6/pm.c @@ -371,7 +371,6 @@ static int mx6_suspend_enter(suspend_state_t state) } else { cpu_do_idle(); } - clk_set_parent(axi_clk, axi_org_parent); return 0; } diff --git a/arch/arm/mach-mx6/system.c b/arch/arm/mach-mx6/system.c index fdbf58cec947..0e4b534de6eb 100644 --- a/arch/arm/mach-mx6/system.c +++ b/arch/arm/mach-mx6/system.c @@ -272,8 +272,8 @@ void arch_idle_single_core(void) ca9_do_idle(); } else { if (low_bus_freq_mode || audio_bus_freq_mode) { - u32 ddr_usecount; - if ((mmdc_ch0_axi != NULL) && ddr_usecount) + int ddr_usecount = 0; + if ((mmdc_ch0_axi != NULL)) ddr_usecount = clk_get_usecount(mmdc_ch0_axi); if (cpu_is_mx6sl() && low_bus_freq_mode -- cgit v1.2.3 From 1b8db7369e4c1f704fc821662e6a8da157636573 Mon Sep 17 00:00:00 2001 From: Ranjani Vaidyanathan Date: Sat, 13 Oct 2012 18:38:25 -0500 Subject: ENGR00229464 MX6SL-Update the SOC voltages based on datasheet Update the VDDARM and VDDSOC voltages based on IMX6SLCEC_Rev0 datasheet. As the voltages for ARM @ 198MHz and ARM @ 396MHz are the same remove the 198MHz working point. Signed-off-by: Ranjani Vaidyanathan --- arch/arm/mach-mx6/cpu_op-mx6.c | 38 +++++++++++--------------------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/arch/arm/mach-mx6/cpu_op-mx6.c b/arch/arm/mach-mx6/cpu_op-mx6.c index 99336d873756..e6ef0261a285 100644 --- a/arch/arm/mach-mx6/cpu_op-mx6.c +++ b/arch/arm/mach-mx6/cpu_op-mx6.c @@ -217,32 +217,24 @@ static struct cpu_op mx6sl_cpu_op_1G[] = { .pll_rate = 996000000, .cpu_rate = 996000000, .cpu_podf = 0, - .pu_voltage = 1225000, - .soc_voltage = 1225000, - .cpu_voltage = 1275000,}, + .pu_voltage = 1200000, + .soc_voltage = 1200000, + .cpu_voltage = 1250000,}, { .pll_rate = 792000000, .cpu_rate = 792000000, .cpu_podf = 0, .pu_voltage = 1150000, .soc_voltage = 1150000, - .cpu_voltage = 1200000,}, + .cpu_voltage = 1150000,}, { .pll_rate = 396000000, .pll_lpm_rate = 792000000, .cpu_rate = 396000000, .cpu_podf = 0, - .pu_voltage = 1050000, - .soc_voltage = 1050000, - .cpu_voltage = 1100000,}, - { - .pll_rate = 396000000, - .pll_lpm_rate = 792000000, - .cpu_rate = 198000000, - .cpu_podf = 1, - .pu_voltage = 1050000, - .soc_voltage = 1050000, - .cpu_voltage = 1050000,}, + .pu_voltage = 1150000, + .soc_voltage = 1150000, + .cpu_voltage = 950000,}, }; static struct cpu_op mx6sl_cpu_op[] = { @@ -252,23 +244,15 @@ static struct cpu_op mx6sl_cpu_op[] = { .cpu_podf = 0, .pu_voltage = 1150000, .soc_voltage = 1150000, - .cpu_voltage = 1200000,}, + .cpu_voltage = 1150000,}, { .pll_rate = 396000000, .pll_lpm_rate = 792000000, .cpu_rate = 396000000, .cpu_podf = 0, - .pu_voltage = 1050000, - .soc_voltage = 1050000, - .cpu_voltage = 1100000,}, - { - .pll_rate = 396000000, - .pll_lpm_rate = 792000000, - .cpu_rate = 198000000, - .cpu_podf = 1, - .pu_voltage = 1050000, - .soc_voltage = 1050000, - .cpu_voltage = 1050000,}, + .pu_voltage = 1150000, + .soc_voltage = 1150000, + .cpu_voltage = 950000,}, }; static struct dvfs_op dvfs_core_setpoint_1_2G[] = { -- cgit v1.2.3 From 495ca379ba5fef55178b4018bab0dac153accf93 Mon Sep 17 00:00:00 2001 From: Robby Cai Date: Fri, 12 Oct 2012 21:48:40 +0800 Subject: ENGR00227728 csi/v4l: add V4L2_CAP_VIDEO_CAPTURE & V4L2_CAP_STREAMING capability add V4L2_CAP_VIDEO_CAPTURE & V4L2_CAP_STREAMING capability for QUERYCAP ioctl. Signed-off-by: Robby Cai --- drivers/media/video/mxc/capture/csi_v4l2_capture.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/video/mxc/capture/csi_v4l2_capture.c b/drivers/media/video/mxc/capture/csi_v4l2_capture.c index 5eb750ce82ab..3756b00a844d 100644 --- a/drivers/media/video/mxc/capture/csi_v4l2_capture.c +++ b/drivers/media/video/mxc/capture/csi_v4l2_capture.c @@ -1142,6 +1142,7 @@ static long csi_v4l_do_ioctl(struct file *file, strcpy(cap->driver, "csi_v4l2"); cap->version = KERNEL_VERSION(0, 1, 11); cap->capabilities = V4L2_CAP_VIDEO_OVERLAY | + V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT_OVERLAY | V4L2_CAP_READWRITE; cap->card[0] = '\0'; cap->bus_info[0] = '\0'; -- cgit v1.2.3 From 1ad9d9804009c9382a21e253ca1323f8b36268cf Mon Sep 17 00:00:00 2001 From: Ranjani Vaidyanathan Date: Sun, 14 Oct 2012 07:40:10 -0500 Subject: ENGR00229470-1 MX6SL-Add support for debug UART to be sourced from 24MHz. If "debug_uart" is specified in the command line, uart will be sourced from 24MHz XTAL. This is required for getting the correct power measurements on MX6SL. Certain analog power optimizations are done only if ALL PLLs are bypassed on MX6SL. To verify this path, we need to ensure that UART is not sourced from PLL3. Signed-off-by: Ranjani Vaidyanathan --- arch/arm/plat-mxc/cpu.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/plat-mxc/cpu.c b/arch/arm/plat-mxc/cpu.c index 073c237cc387..eb163abd4f36 100755 --- a/arch/arm/plat-mxc/cpu.c +++ b/arch/arm/plat-mxc/cpu.c @@ -61,6 +61,16 @@ static int __init jtag_wfi_setup(char *p) return 0; } early_param("jtag", jtag_wfi_setup); + + +static int __init setup_debug_uart(char *p) +{ + uart_at_24 = 1; + return 0; +} + +early_param("debug_uart", setup_debug_uart); + /** * early_console_setup - setup debugging console * -- cgit v1.2.3 From a79d0352f8ad5f778ca70b94da71b06775e76cb6 Mon Sep 17 00:00:00 2001 From: Ranjani Vaidyanathan Date: Sun, 14 Oct 2012 07:41:05 -0500 Subject: ENGR00229470-2 MX6SL-Add support for debug UART to be sourced from 24MHz. If "debug_uart" is specified in the command line, uart will be sourced from 24MHz XTAL. This is required for getting the correct power measurements on MX6SL. Certain analog power optimizations are done only if ALL PLLs are bypassed on MX6SL. To verify this path, we need to ensure that UART is not sourced from PLL3. Signed-off-by: Ranjani Vaidyanathan --- drivers/tty/serial/imx.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 8a66f3eeb992..5e9594d744d9 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -1742,6 +1742,8 @@ static int serial_imx_resume(struct platform_device *dev) return 0; } +extern int uart_at_24; + static int serial_imx_probe(struct platform_device *pdev) { struct imx_port *sport; @@ -1788,6 +1790,9 @@ static int serial_imx_probe(struct platform_device *pdev) ret = PTR_ERR(sport->clk); goto unmap; } + if (uart_at_24) + clk_set_parent(sport->clk, clk_get(NULL, "osc")); + clk_enable(sport->clk); sport->port.uartclk = clk_get_rate(sport->clk); -- cgit v1.2.3 From 3e61ad06106bb75ba352c1b2d8d6d13fa211b109 Mon Sep 17 00:00:00 2001 From: Jack Lee Date: Wed, 3 Oct 2012 13:31:47 +0800 Subject: ENGR00223348 EPDC: Unable to enable DISPLAY regulator In the maxim 17135 driver, the power good is confirmed by the power good GPIO polarity change when comparing the status at the beginning of driver probe and display regulator enabled. However, it is not reliable since the initial value of the GPIO is not constant. Normally, it is 1 but it can be 0 after system reset unexpectedly. Now, it is changed to POK bit checking in FAULT register. Signed-off-by: Jack Lee --- drivers/regulator/max17135-regulator.c | 20 ++++++++++---------- include/linux/mfd/max17135.h | 5 +---- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/regulator/max17135-regulator.c b/drivers/regulator/max17135-regulator.c index 45d4501ef7a5..5ea70ef5868f 100644 --- a/drivers/regulator/max17135-regulator.c +++ b/drivers/regulator/max17135-regulator.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2010-2012 Freescale Semiconductor, Inc. All Rights Reserved. * * 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 @@ -284,12 +284,14 @@ static int max17135_vcom_is_enabled(struct regulator_dev *reg) static int max17135_is_power_good(struct max17135 *max17135) { - /* - * XOR of polarity (starting value) and current - * value yields whether power is good. - */ - return gpio_get_value(max17135->gpio_pmic_pwrgood) ^ - max17135->pwrgood_polarity; + unsigned int reg_val; + unsigned int fld_val; + + max17135_reg_read(REG_MAX17135_FAULT, ®_val); + fld_val = (reg_val & BITFMASK(FAULT_POK)) >> FAULT_POK_LSH; + + /* Check the POK bit */ + return fld_val; } static int max17135_wait_power_good(struct max17135 *max17135) @@ -302,6 +304,7 @@ static int max17135_wait_power_good(struct max17135 *max17135) msleep(1); } + return -ETIMEDOUT; } @@ -622,9 +625,6 @@ int max17135_register_regulator(struct max17135 *max17135, int reg, */ max17135_setup_timings(max17135); - max17135->pwrgood_polarity = - gpio_get_value(max17135->gpio_pmic_pwrgood); - max17135->init_done = true; } diff --git a/include/linux/mfd/max17135.h b/include/linux/mfd/max17135.h index 265b1588c10a..5785ed415a71 100644 --- a/include/linux/mfd/max17135.h +++ b/include/linux/mfd/max17135.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2010-2012 Freescale Semiconductor, Inc. All Rights Reserved. * * 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 @@ -167,9 +167,6 @@ struct max17135 { /* powerup/powerdown wait time */ int max_wait; - - /* Dynamically determined polarity for PWRGOOD */ - int pwrgood_polarity; }; enum { -- cgit v1.2.3 From bd36e05e8ef25d8c894959156022634868b80f13 Mon Sep 17 00:00:00 2001 From: Ranjani Vaidyanathan Date: Fri, 12 Oct 2012 05:40:03 -0500 Subject: ENGR00229441 MX6SL-Reset MMDC read FIFO in low power IDLE MMDC can clock in bad data due to the glitches caused by changing the setting of various DDR IO pads in low power IDLE to save power. Solution is to reset the MMDC read FIFO before the DDR exits self-refresh. Signed-off-by: Ranjani Vaidyanathan --- arch/arm/mach-mx6/mx6sl_wfi.S | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/arch/arm/mach-mx6/mx6sl_wfi.S b/arch/arm/mach-mx6/mx6sl_wfi.S index dc4107dff7e8..e8936b6862c8 100644 --- a/arch/arm/mach-mx6/mx6sl_wfi.S +++ b/arch/arm/mach-mx6/mx6sl_wfi.S @@ -99,6 +99,31 @@ str r6, [r1, #0x320] /* DRAM_RESET */ str r7, [r1, #0x5c8] /* GPR_CTLDS */ + /* Need to reset the FIFO to avoid MMDC lockup + * caused because of floating/changing the + * configuration of many DDR IO pads. + */ + /* reset read FIFO, RST_RD_FIFO */ + ldr r7, =0x83c + ldr r6, [r1, r7] + orr r6, r6, #0x80000000 + str r6, [r1, r7] +fifo_reset1_wait: + ldr r6, [r1, r7] + and r6, r6, #0x80000000 + cmp r6, #0 + bne fifo_reset1_wait + + /* reset FIFO a second time */ + ldr r6, [r1, r7] + orr r6, r6, #0x80000000 + str r6, [r1, r7] +fifo_reset2_wait: + ldr r6, [r1, r7] + and r6, r6, #0x80000000 + cmp r6, #0 + bne fifo_reset2_wait + .endm .macro sl_ddr_io_set_lpm -- cgit v1.2.3 From ef72abd9021929b629977acc52c617b8ddc4ffa5 Mon Sep 17 00:00:00 2001 From: Michael Minnick Date: Fri, 12 Oct 2012 13:52:36 -0500 Subject: ENGR00229291 EPDC: MX6: Treat fully-collided VOID update as a collision The EPDC set the UPD_VOID (i.e. cancelled) bit in two cases: 1. No pixels needed updating 2. All pixels collided (COL bit also set) The driver was miss-handling case 2. This fix causes case 2 to be treated as a collision and the update to be resubmitted. Signed-off-by: Michael Minnick --- drivers/video/mxc/mxc_epdc_fb.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/video/mxc/mxc_epdc_fb.c b/drivers/video/mxc/mxc_epdc_fb.c index 38a183c8d861..727c6ebc575c 100644 --- a/drivers/video/mxc/mxc_epdc_fb.c +++ b/drivers/video/mxc/mxc_epdc_fb.c @@ -3700,7 +3700,13 @@ static void epdc_intr_work_func(struct work_struct *work) next_marker->update_marker); complete(&next_marker->update_completion); } - } else if (epdc_lut_cancelled) { + } else if (epdc_lut_cancelled && !epdc_collision) { + /* + * Note: The update may be cancelled (void) if all + * pixels collided. In that case we handle it as a + * collision, not a cancel. + */ + /* Clear LUT status (might be set if no AUTOWV used) */ /* -- cgit v1.2.3 From 1c273b724ce7b43799e03e49fed8dad7f94084df Mon Sep 17 00:00:00 2001 From: Robby Cai Date: Sun, 14 Oct 2012 21:33:21 +0800 Subject: ENGR00229473 elcdif fb: fix lcd framebuffer potential recursive locking This can be detected by enabling CONFIG_LOCKDEP and CONFIG_PROVE_LOCKING The dump log: ============================================= [ INFO: possible recursive locking detected ] 3.0.35-02140-gb4181ce-dirty #959 --------------------------------------------- swapper/1 is trying to acquire lock: ((fb_notifier_list).rwsem){.+.+.+}, at: [<80088758>] __blocking_notifier_call_chain+0x44/0x88 but task is already holding lock: ((fb_notifier_list).rwsem){.+.+.+}, at: [<80088758>] __blocking_notifier_call_chain+0x44/0x88 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock((fb_notifier_list).rwsem); lock((fb_notifier_list).rwsem); *** DEADLOCK *** May be due to missing lock nesting notation 5 locks held by swapper/1: #0: (&__lockdep_no_validate__){+.+.+.}, at: [<8027f244>] __driver_attach+0x48/0x98 #1: (&__lockdep_no_validate__){+.+.+.}, at: [<8027f254>] __driver_attach+0x58/0x98 #2: (registration_lock){+.+.+.}, at: [<8023a17c>] register_framebuffer+0x18/0x24c #3: (&fb_info->lock){+.+.+.}, at: [<80238dc8>] lock_fb_info+0x18/0x3c #4: ((fb_notifier_list).rwsem){.+.+.+}, at: [<80088758>] __blocking_notifier_call_chain+0x44/0x88 stack backtrace: [<800405c4>] (unwind_backtrace+0x0/0xf8) from [<80097c78>] (__lock_acquire+0x1644/0x1c18) [<80097c78>] (__lock_acquire+0x1644/0x1c18) from [<80098748>] (lock_acquire+0x84/0x98) [<80098748>] (lock_acquire+0x84/0x98) from [<804d0aa8>] (down_read+0x34/0x44) [<804d0aa8>] (down_read+0x34/0x44) from [<80088758>] (__blocking_notifier_call_chain+0x44/0x88) [<80088758>] (__blocking_notifier_call_chain+0x44/0x88) from [<800887b4>] (blocking_notifier_call_chain+0x18/0x20) [<800887b4>] (blocking_notifier_call_chain+0x18/0x20) from [<802397e0>] (fb_set_var+0x264/0x290) [<802397e0>] (fb_set_var+0x264/0x290) from [<8024a320>] (lcd_init_fb+0x54/0x70) [<8024a320>] (lcd_init_fb+0x54/0x70) from [<8024a3f0>] (lcd_fb_event+0x44/0xb4) [<8024a3f0>] (lcd_fb_event+0x44/0xb4) from [<80088514>] (notifier_call_chain.isra.1+0x74/0xd0) [<80088514>] (notifier_call_chain.isra.1+0x74/0xd0) from [<80088774>] (__blocking_notifier_call_chain+0x60/0x88) [<80088774>] (__blocking_notifier_call_chain+0x60/0x88) from [<800887b4>] (blocking_notifier_call_chain+0x18/0x20) [<800887b4>] (blocking_notifier_call_chain+0x18/0x20) from [<8023a2d4>] (register_framebuffer+0x170/0x24c) [<8023a2d4>] (register_framebuffer+0x170/0x24c) from [<8024fe8c>] (mxc_elcdif_fb_probe+0x464/0x564) [<8024fe8c>] (mxc_elcdif_fb_probe+0x464/0x564) from [<8028031c>] (platform_drv_probe+0x18/0x1c) [<8028031c>] (platform_drv_probe+0x18/0x1c) from [<8027f0f0>] (driver_probe_device+0x90/0x19c) [<8027f0f0>] (driver_probe_device+0x90/0x19c) from [<8027f290>] (__driver_attach+0x94/0x98) [<8027f290>] (__driver_attach+0x94/0x98) from [<8027e2e4>] (bus_for_each_dev+0x5c/0x88) [<8027e2e4>] (bus_for_each_dev+0x5c/0x88) from [<8027eabc>] (bus_add_driver+0x188/0x250) [<8027eabc>] (bus_add_driver+0x188/0x250) from [<8027f750>] (driver_register+0x78/0x13c) [<8027f750>] (driver_register+0x78/0x13c) from [<8001c838>] (mxc_elcdif_fb_init+0x38/0x48) [<8001c838>] (mxc_elcdif_fb_init+0x38/0x48) from [<80035334>] (do_one_initcall+0x34/0x178) [<80035334>] (do_one_initcall+0x34/0x178) from [<80008968>] (kernel_init+0x84/0x124) [<80008968>] (kernel_init+0x84/0x124) from [<8003b614>] (kernel_thread_exit+0x0/0x8) In fact, we don't need support dynamically switch the framebuffer. so, we only need do once registeration in probe function. Signed-off-by: Robby Cai Acked-by: Lily Zhang --- drivers/video/mxc/mxcfb_seiko_wvga.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/video/mxc/mxcfb_seiko_wvga.c b/drivers/video/mxc/mxcfb_seiko_wvga.c index c96238d80cb2..6e9abaf8566b 100644 --- a/drivers/video/mxc/mxcfb_seiko_wvga.c +++ b/drivers/video/mxc/mxcfb_seiko_wvga.c @@ -89,11 +89,6 @@ static int lcd_fb_event(struct notifier_block *nb, unsigned long val, void *v) return 0; switch (val) { - case FB_EVENT_FB_REGISTERED: - lcd_init_fb(event->info); - fb_show_logo(event->info, 0); - lcd_poweron(); - break; case FB_EVENT_BLANK: if ((event->info->var.xres != 800) || (event->info->var.yres != 480)) { -- cgit v1.2.3 From d979c191942eb5214e746ea3f241ac7644cb877d Mon Sep 17 00:00:00 2001 From: Nancy Chen Date: Mon, 15 Oct 2012 10:52:08 -0500 Subject: ENGR00229708 [MX6SL] Fix all build warnings. Fix all build warnings in files: arch/arm/mach-mx6/board-mx6sl_common.h arch/arm/mach-mx6/board-mx6sl_evk.c arch/arm/mach-mx6/clock_mx6sl.c arch/arm/mach-mx6/cpu_regulator-mx6.c arch/arm/mach-mx6/pm.c arch/arm/mach-mx6/system.c arch/arm/plat-mxc/dvfs_core.c Signed-off-by: Nancy Chen --- arch/arm/mach-mx6/board-mx6sl_common.h | 29 ----------------------------- arch/arm/mach-mx6/board-mx6sl_evk.c | 30 ++++++++++++++++++++++++++++++ arch/arm/mach-mx6/clock_mx6sl.c | 1 - arch/arm/mach-mx6/cpu_regulator-mx6.c | 6 ++++-- arch/arm/mach-mx6/pm.c | 1 - arch/arm/mach-mx6/system.c | 2 +- arch/arm/plat-mxc/dvfs_core.c | 5 ++++- 7 files changed, 39 insertions(+), 35 deletions(-) diff --git a/arch/arm/mach-mx6/board-mx6sl_common.h b/arch/arm/mach-mx6/board-mx6sl_common.h index 4a04cbea0694..c432e0a661ba 100644 --- a/arch/arm/mach-mx6/board-mx6sl_common.h +++ b/arch/arm/mach-mx6/board-mx6sl_common.h @@ -389,40 +389,11 @@ static iomux_v3_cfg_t mx6sl_brd_spdc_disable_pads[] = { MX6SL_PAD_EPDC_PWRWAKEUP__GPIO_2_14, }; -static iomux_v3_cfg_t mx6sl_brd_csi_enable_pads[] = { - MX6SL_PAD_EPDC_GDRL__CSI_MCLK, - MX6SL_PAD_EPDC_SDCE3__I2C3_SDA, - MX6SL_PAD_EPDC_SDCE2__I2C3_SCL, - MX6SL_PAD_EPDC_GDCLK__CSI_PIXCLK, - MX6SL_PAD_EPDC_GDSP__CSI_VSYNC, - MX6SL_PAD_EPDC_GDOE__CSI_HSYNC, - MX6SL_PAD_EPDC_SDLE__CSI_D_9, - MX6SL_PAD_EPDC_SDCLK__CSI_D_8, - MX6SL_PAD_EPDC_D7__CSI_D_7, - MX6SL_PAD_EPDC_D6__CSI_D_6, - MX6SL_PAD_EPDC_D5__CSI_D_5, - MX6SL_PAD_EPDC_D4__CSI_D_4, - MX6SL_PAD_EPDC_D3__CSI_D_3, - MX6SL_PAD_EPDC_D2__CSI_D_2, - MX6SL_PAD_EPDC_D1__CSI_D_1, - MX6SL_PAD_EPDC_D0__CSI_D_0, - - MX6SL_PAD_EPDC_SDSHR__GPIO_1_26, /* CMOS_RESET_B GPIO */ - MX6SL_PAD_EPDC_SDOE__GPIO_1_25, /* CMOS_PWDN GPIO */ -}; - static iomux_v3_cfg_t mx6sl_brd_elan_pads[] = { MX6SL_PAD_EPDC_PWRCTRL3__GPIO_2_10, /* INT */ MX6SL_PAD_EPDC_PWRCTRL2__GPIO_2_9, /* CE */ MX6SL_PAD_KEY_COL6__GPIO_4_4, /* RST */ }; - /* uart2 pins */ -static iomux_v3_cfg_t mx6sl_uart2_pads[] = { - MX6SL_PAD_SD2_DAT5__UART2_TXD, - MX6SL_PAD_SD2_DAT4__UART2_RXD, - MX6SL_PAD_SD2_DAT6__UART2_RTS, - MX6SL_PAD_SD2_DAT7__UART2_CTS, -}; #define MX6SL_USDHC_8BIT_PAD_SETTING(id, speed) \ mx6sl_sd##id##_##speed##mhz[] = { \ diff --git a/arch/arm/mach-mx6/board-mx6sl_evk.c b/arch/arm/mach-mx6/board-mx6sl_evk.c index 9bdd6c197e5c..4c9c4d36e740 100644 --- a/arch/arm/mach-mx6/board-mx6sl_evk.c +++ b/arch/arm/mach-mx6/board-mx6sl_evk.c @@ -86,6 +86,36 @@ extern int __init mx6sl_evk_init_pfuze100(u32 int_gpio); static int csi_enabled; +static iomux_v3_cfg_t mx6sl_brd_csi_enable_pads[] = { + MX6SL_PAD_EPDC_GDRL__CSI_MCLK, + MX6SL_PAD_EPDC_SDCE3__I2C3_SDA, + MX6SL_PAD_EPDC_SDCE2__I2C3_SCL, + MX6SL_PAD_EPDC_GDCLK__CSI_PIXCLK, + MX6SL_PAD_EPDC_GDSP__CSI_VSYNC, + MX6SL_PAD_EPDC_GDOE__CSI_HSYNC, + MX6SL_PAD_EPDC_SDLE__CSI_D_9, + MX6SL_PAD_EPDC_SDCLK__CSI_D_8, + MX6SL_PAD_EPDC_D7__CSI_D_7, + MX6SL_PAD_EPDC_D6__CSI_D_6, + MX6SL_PAD_EPDC_D5__CSI_D_5, + MX6SL_PAD_EPDC_D4__CSI_D_4, + MX6SL_PAD_EPDC_D3__CSI_D_3, + MX6SL_PAD_EPDC_D2__CSI_D_2, + MX6SL_PAD_EPDC_D1__CSI_D_1, + MX6SL_PAD_EPDC_D0__CSI_D_0, + + MX6SL_PAD_EPDC_SDSHR__GPIO_1_26, /* CMOS_RESET_B GPIO */ + MX6SL_PAD_EPDC_SDOE__GPIO_1_25, /* CMOS_PWDN GPIO */ +}; + +/* uart2 pins */ +static iomux_v3_cfg_t mx6sl_uart2_pads[] = { + MX6SL_PAD_SD2_DAT5__UART2_TXD, + MX6SL_PAD_SD2_DAT4__UART2_RXD, + MX6SL_PAD_SD2_DAT6__UART2_RTS, + MX6SL_PAD_SD2_DAT7__UART2_CTS, +}; + enum sd_pad_mode { SD_PAD_MODE_LOW_SPEED, SD_PAD_MODE_MED_SPEED, diff --git a/arch/arm/mach-mx6/clock_mx6sl.c b/arch/arm/mach-mx6/clock_mx6sl.c index a18427c51515..544b9951baef 100755 --- a/arch/arm/mach-mx6/clock_mx6sl.c +++ b/arch/arm/mach-mx6/clock_mx6sl.c @@ -101,7 +101,6 @@ DEFINE_SPINLOCK(mx6sl_clk_lock); u32 gpt_ticks; \ u32 gpt_cnt; \ u32 reg; \ - unsigned long flags; \ int result = 1; \ gpt_rate = clk_get_rate(&gpt_clk[0]); \ gpt_ticks = timeout / (1000000000 / gpt_rate); \ diff --git a/arch/arm/mach-mx6/cpu_regulator-mx6.c b/arch/arm/mach-mx6/cpu_regulator-mx6.c index 5019f8bedff2..8eb976d2eefd 100644 --- a/arch/arm/mach-mx6/cpu_regulator-mx6.c +++ b/arch/arm/mach-mx6/cpu_regulator-mx6.c @@ -62,7 +62,9 @@ void mx6_cpu_regulator_init(void) { int cpu; u32 curr_cpu = 0; - +#ifndef CONFIG_SMP + unsigned long old_loops_per_jiffy; +#endif external_pureg = 0; cpu_regulator = regulator_get(NULL, gp_reg_id); if (IS_ERR(cpu_regulator)) @@ -90,7 +92,7 @@ void mx6_cpu_regulator_init(void) curr_cpu / 1000, clk_get_rate(cpu_clk) / 1000); #else - u32 old_loops_per_jiffy = loops_per_jiffy; + old_loops_per_jiffy = loops_per_jiffy; loops_per_jiffy = mx6_cpu_jiffies(old_loops_per_jiffy, diff --git a/arch/arm/mach-mx6/pm.c b/arch/arm/mach-mx6/pm.c index 2308e332dc44..d7889312aeac 100644 --- a/arch/arm/mach-mx6/pm.c +++ b/arch/arm/mach-mx6/pm.c @@ -72,7 +72,6 @@ static struct clk *cpu_clk; static struct clk *axi_clk; static struct clk *periph_clk; -static struct clk *axi_org_parent; static struct clk *pll3_usb_otg_main_clk; static struct pm_platform_data *pm_data; diff --git a/arch/arm/mach-mx6/system.c b/arch/arm/mach-mx6/system.c index 0e4b534de6eb..1c37bacdebda 100644 --- a/arch/arm/mach-mx6/system.c +++ b/arch/arm/mach-mx6/system.c @@ -86,7 +86,7 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode) int stop_mode = 0; void __iomem *anatop_base = IO_ADDRESS(ANATOP_BASE_ADDR); - u32 ccm_clpcr, anatop_val, reg; + u32 ccm_clpcr, anatop_val; ccm_clpcr = __raw_readl(MXC_CCM_CLPCR) & ~(MXC_CCM_CLPCR_LPM_MASK); diff --git a/arch/arm/plat-mxc/dvfs_core.c b/arch/arm/plat-mxc/dvfs_core.c index a4a15482c71f..b5cfba1a5047 100755 --- a/arch/arm/plat-mxc/dvfs_core.c +++ b/arch/arm/plat-mxc/dvfs_core.c @@ -722,6 +722,9 @@ void stop_dvfs(void) unsigned long flags; u32 curr_cpu; int cpu; +#ifndef CONFIG_SMP + unsigned long old_loops_per_jiffy; +#endif if (dvfs_core_is_active) { @@ -752,7 +755,7 @@ void stop_dvfs(void) dvfs_cpu_jiffies(per_cpu(cpu_data, cpu).loops_per_jiffy, curr_cpu/1000, clk_get_rate(cpu_clk) / 1000); #else - u32 old_loops_per_jiffy = loops_per_jiffy; + old_loops_per_jiffy = loops_per_jiffy; loops_per_jiffy = dvfs_cpu_jiffies(old_loops_per_jiffy, -- cgit v1.2.3 From 78547bde94bd059224758f434cbf424b2892bff0 Mon Sep 17 00:00:00 2001 From: Robby Cai Date: Tue, 16 Oct 2012 16:08:29 +0800 Subject: ENGR00229803-1 lcdif: export mxcfb_elcdif_register_mode needed by sii902x driver This is needed when build sii902x hdmi driver as module Signed-off-by: Robby Cai --- drivers/video/mxc/mxc_elcdif_fb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/video/mxc/mxc_elcdif_fb.c b/drivers/video/mxc/mxc_elcdif_fb.c index 83a62dbc8ef0..6624fd0e867e 100644 --- a/drivers/video/mxc/mxc_elcdif_fb.c +++ b/drivers/video/mxc/mxc_elcdif_fb.c @@ -586,6 +586,7 @@ void mxcfb_elcdif_register_mode(const struct fb_videomode *modedb, return; } +EXPORT_SYMBOL(mxcfb_elcdif_register_mode); int mxc_elcdif_frame_addr_setup(dma_addr_t phys) { -- cgit v1.2.3 From 5a1b94e55d3f0f2e3833cd223546b95094db763d Mon Sep 17 00:00:00 2001 From: Robby Cai Date: Tue, 16 Oct 2012 16:21:28 +0800 Subject: ENGR00229803-2 sii902x: add dependency on CONFIG_FB_MXC_ELCDIF_FB Add dependency on CONFIG_FB_MXC_ELCDIF_FB, to avoid build error if as module. Signed-off-by: Robby Cai --- drivers/video/mxc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/mxc/Kconfig b/drivers/video/mxc/Kconfig index 8a4a0792724f..83b094267760 100644 --- a/drivers/video/mxc/Kconfig +++ b/drivers/video/mxc/Kconfig @@ -61,7 +61,7 @@ config FB_MXC_SII902X tristate "Si Image SII9022 DVI/HDMI Interface Chip" config FB_MXC_SII902X_ELCDIF - depends on FB_MXC_SYNC_PANEL && I2C + depends on FB_MXC_ELCDIF_FB && FB_MXC_SYNC_PANEL && I2C tristate "Si Image SII9022 DVI/HDMI Interface Chip for ELCDIF FB" config FB_MXC_CH7026 -- cgit v1.2.3 From 8c757b8134d3dc7b21f4bf716b8591f5c8523c00 Mon Sep 17 00:00:00 2001 From: Robby Cai Date: Tue, 16 Oct 2012 15:53:29 +0800 Subject: ENGR00229785 pgc: disable display power gating when FB_MXC_ELCDIF_FB configured Only enable power gating for PXP and EPDC. The feature for ELCDIF still need to be verified. Signed-off-by: Robby Cai --- arch/arm/mach-mx6/pm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/mach-mx6/pm.c b/arch/arm/mach-mx6/pm.c index d7889312aeac..9933828df0df 100644 --- a/arch/arm/mach-mx6/pm.c +++ b/arch/arm/mach-mx6/pm.c @@ -178,6 +178,8 @@ static void usb_power_up_handler(void) static void disp_power_down(void) { +#if !defined(CONFIG_FB_MXC_ELCDIF_FB) && \ + !defined(CONFIG_FB_MXC_ELCDIF_FB_MODULE) if (cpu_is_mx6sl()) { __raw_writel(0xFFFFFFFF, gpc_base + GPC_PGC_DISP_PUPSCR_OFFSET); __raw_writel(0xFFFFFFFF, gpc_base + GPC_PGC_DISP_PDNSCR_OFFSET); @@ -194,10 +196,13 @@ static void disp_power_down(void) ~MXC_CCM_CCGRx_CG1_MASK, MXC_CCM_CCGR3); } +#endif } static void disp_power_up(void) { +#if !defined(CONFIG_FB_MXC_ELCDIF_FB) && \ + !defined(CONFIG_FB_MXC_ELCDIF_FB_MODULE) if (cpu_is_mx6sl()) { /* * Need to enable EPDC/LCDIF pix clock, and @@ -214,6 +219,7 @@ static void disp_power_up(void) __raw_writel(0x20, gpc_base + GPC_CNTR_OFFSET); __raw_writel(0x1, gpc_base + GPC_PGC_DISP_SR_OFFSET); } +#endif } static void mx6_suspend_store(void) -- cgit v1.2.3 From 247824626f26d24a4b4bbaf0817cb34a99ffbd57 Mon Sep 17 00:00:00 2001 From: Ranjani Vaidyanathan Date: Mon, 15 Oct 2012 05:36:02 -0500 Subject: ENGR00229695 MX6x-Set RBC counters correctly in STOP mode. The REG_BYPASS_COUNTER(RBC) holds off interrupts when the PGC block is sending signals to power gate the core. This is apart from the RBC counter's basic functionality to act as counter to power down the analog portions of the chip. But the counter needs to be set/cleared only when no interrupts are pending. And also for correct hold off the interrupts, enable the counter as close to WFI as possible. The RBC counts CKIL cycles (32KHz) So follow the following steps to set the counter in suspend/resume in mx6_suspend.S: 1. Mask all the GPC interrupts. 2. Write the counter value to the RBC 3. Enable the RBC 4. Unmask all the interrupts. 5. Busy wait for a few usecs to wait for RBC to start counting in case an interrupt is pending. 4. Execute WFI Reset the counter after resume in pm.c: 1. Mask all the GPC interrupts. 2. Disable the counter. 3. Set the RBC counter to 0. 4. Wait for 80usec for the write to get accepted. 5. Unmask all the interrupts. With the above steps, we can minimize the PDNSCR and PUPSCR counters in the GPC. The basic condition for the RBC counter: RBC count >= 25 * IPG_CLK + PDNSCR_SW2ISO. PDNSCR_SW2ISO = PDNSCR_ISO = 1 (counts in IPG_CLK) PUPSCR_SW2ISO = PUPSCR_ISO = 2 (counts in 32K) Signed-off-by: Ranjani Vaidyanathan --- arch/arm/mach-mx6/mx6_suspend.S | 80 +++++++++++++++++++++++++++++++++++++---- arch/arm/mach-mx6/pm.c | 24 +++++++++++++ arch/arm/mach-mx6/system.c | 27 +++++++------- 3 files changed, 110 insertions(+), 21 deletions(-) diff --git a/arch/arm/mach-mx6/mx6_suspend.S b/arch/arm/mach-mx6/mx6_suspend.S index 1987581e56aa..f712700a8e68 100644 --- a/arch/arm/mach-mx6/mx6_suspend.S +++ b/arch/arm/mach-mx6/mx6_suspend.S @@ -233,6 +233,11 @@ wait_for_pll_lock: bic r6, r6, #0x2000000 str r6, [r3, #0x14] +periph_clk_switch1: + ldr r6, [r3, #0x48] + cmp r6, #0 + bne periph_clk_switch1 + /* Set the dividers to default value. */ ldr r6, [r3, #0x14] bic r6, r6, #0x70000 @@ -241,14 +246,9 @@ wait_for_pll_lock: str r6, [r3, #0x14] ahb_podf1: - ldr r0, [r3, #0x48] - cmp r0, #0 - bne ahb_podf1 - -periph_clk_switch1: ldr r6, [r3, #0x48] cmp r6, #0 - bne periph_clk_switch1 + bne ahb_podf1 /* Move MMDC back to PLL2_PFD2_400 */ ldr r6, [r3, #0x14] @@ -262,7 +262,7 @@ mmdc_loop2: /* Set DDR clock to divide by 1. */ ldr r6, [r3, #0x14] - bic r6, r0, #0x38 + bic r6, r6, #0x38 str r6, [r3, #0x14] mmdc_div1: @@ -1099,6 +1099,12 @@ set ddr iomux to low power mode ldr r1, =CCM_BASE_ADDR add r1, r1, #PERIPBASE_VIRT ldr r0, [r1] + ldr r1, =GPC_BASE_ADDR + add r1, r1, #PERIPBASE_VIRT + ldr r0, [r1] + ldr r1, =CCM_BASE_ADDR + add r1, r1, #PERIPBASE_VIRT + ldr r0, [r1] #ifdef CONFIG_MX6_INTER_LDO_BYPASS ldr r1, =ANATOP_BASE_ADDR add r1, r1, #PERIPBASE_VIRT @@ -1173,6 +1179,66 @@ save resume pointer into SRC_GPR1 add r1, r1, #PERIPBASE_VIRT str r3, [r1, #SRC_GPR1_OFFSET] + /* Mask all GPC interrupts before + * enabling the RBC counters to + * avoid the counter starting too + * early if an interupt is already + * pending. + */ + ldr r3, =GPC_BASE_ADDR + add r3, r3, #PERIPBASE_VIRT + ldr r4, [r3, #0x08] + ldr r5, [r3, #0x0c] + ldr r6, [r3, #0x10] + ldr r7, [r3, #0x14] + + ldr r8, =0xffffffff + str r8, [r3, #0x08] + str r8, [r3, #0x0c] + str r8, [r3, #0x10] + str r8, [r3, #0x14] + + /* Enable the RBC bypass counter here + * to hold off the interrupts. + * RBC counter = 32 (1ms) + * Minimum RBC delay should be + * 400us for the analog LDOs to + * power down. + */ + ldr r1, =CCM_BASE_ADDR + add r1, r1, #PERIPBASE_VIRT + ldr r8, [r1, #0x0] + ldr r0, =0x7E00000 + bic r8, r8, r0 + ldr r0, =0x4000000 + orr r8, r8, r0 + str r8, [r1, #0x0] + + /* Enable the counter. */ + ldr r8, [r1, #0x0] + orr r8, r8, #0x8000000 + str r8, [r1, #0x0] + + /* Unmask all the GPC interrupts. */ + str r4, [r3, #0x08] + str r5, [r3, #0x0c] + str r6, [r3, #0x10] + str r7, [r3, #0x14] + + /* Now delay for a short while (3usec) + * ARM is at 1GHz at this point + * so a short loop should be enough. + * This delay is required to ensure that + * the RBC counter can start counting in case an + * interrupt is already pending or in case an interrupt + * arrives just as ARM is about to assert DSM_request. + */ + ldr r4, =2000 +rbc_loop: + sub r4, r4, #0x1 + cmp r4, #0x0 + bne rbc_loop + #ifdef CONFIG_MX6_INTER_LDO_BYPASS ldr r1, =ANATOP_BASE_ADDR add r1, r1, #PERIPBASE_VIRT diff --git a/arch/arm/mach-mx6/pm.c b/arch/arm/mach-mx6/pm.c index 9933828df0df..654881af57bd 100644 --- a/arch/arm/mach-mx6/pm.c +++ b/arch/arm/mach-mx6/pm.c @@ -356,6 +356,30 @@ static int mx6_suspend_enter(suspend_state_t state) suspend_in_iram(state, (unsigned long)iram_paddr, (unsigned long)suspend_iram_base, cpu_type); + /* Reset the RBC counter. */ + /* All interrupts should be masked before the + * RBC counter is reset. + */ + /* Mask all interrupts. These will be unmasked by + * the mx6_suspend_restore routine below. + */ + __raw_writel(0xffffffff, gpc_base + 0x08); + __raw_writel(0xffffffff, gpc_base + 0x0c); + __raw_writel(0xffffffff, gpc_base + 0x10); + __raw_writel(0xffffffff, gpc_base + 0x14); + + /* Clear the RBC counter and RBC_EN bit. */ + /* Disable the REG_BYPASS_COUNTER. */ + __raw_writel(__raw_readl(MXC_CCM_CCR) & + ~MXC_CCM_CCR_RBC_EN, MXC_CCM_CCR); + /* Make sure we clear REG_BYPASS_COUNT*/ + __raw_writel(__raw_readl(MXC_CCM_CCR) & + (~MXC_CCM_CCR_REG_BYPASS_CNT_MASK), MXC_CCM_CCR); + /* Need to wait for a minimum of 2 CLKILS (32KHz) for the + * counter to clear and reset. + */ + udelay(80); + if (arm_pg) { /* restore gic registers */ restore_gic_dist_state(0, &gds); diff --git a/arch/arm/mach-mx6/system.c b/arch/arm/mach-mx6/system.c index 1c37bacdebda..6ecd51e9f9ea 100644 --- a/arch/arm/mach-mx6/system.c +++ b/arch/arm/mach-mx6/system.c @@ -153,8 +153,15 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode) if (stop_mode > 0) { gpc_set_wakeup(gpc_wake_irq); /* Power down and power up sequence */ - __raw_writel(0xFFFFFFFF, gpc_base + GPC_PGC_CPU_PUPSCR_OFFSET); - __raw_writel(0xFFFFFFFF, gpc_base + GPC_PGC_CPU_PDNSCR_OFFSET); + /* The PUPSCR counter counts in terms of CLKIL (32KHz) cycles. + * The PUPSCR should include the time it takes for the ARM LDO to + * ramp up. + */ + __raw_writel(0x202, gpc_base + GPC_PGC_CPU_PUPSCR_OFFSET); + /* The PDNSCR is a counter that counts in IPG_CLK cycles. This counter + * can be set to minimum values to power down faster. + */ + __raw_writel(0x101, gpc_base + GPC_PGC_CPU_PDNSCR_OFFSET); if (stop_mode >= 2) { /* dormant mode, need to power off the arm core */ __raw_writel(0x1, gpc_base + GPC_PGC_CPU_PDN_OFFSET); @@ -198,25 +205,17 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode) HW_ANADIG_REG_2P5); } } - /* DL's TO1.0 can't support DSM mode due to ipg glitch */ - if ((mx6dl_revision() != IMX_CHIP_REVISION_1_0) - && stop_mode != 3) - __raw_writel(__raw_readl(MXC_CCM_CCR) | - MXC_CCM_CCR_RBC_EN, MXC_CCM_CCR); - if (stop_mode != 3) { /* Make sure we clear WB_COUNT * and re-config it. */ __raw_writel(__raw_readl(MXC_CCM_CCR) & - (~MXC_CCM_CCR_WB_COUNT_MASK) & - (~MXC_CCM_CCR_REG_BYPASS_CNT_MASK), MXC_CCM_CCR); - udelay(80); - /* Reconfigurate WB and RBC counter, need to set WB counter + (~MXC_CCM_CCR_WB_COUNT_MASK), + MXC_CCM_CCR); + /* Reconfigure WB, need to set WB counter * to 0x7 to make sure it work normally */ __raw_writel(__raw_readl(MXC_CCM_CCR) | - (0x7 << MXC_CCM_CCR_WB_COUNT_OFFSET) | - (0x20 << MXC_CCM_CCR_REG_BYPASS_CNT_OFFSET), + (0x7 << MXC_CCM_CCR_WB_COUNT_OFFSET), MXC_CCM_CCR); /* Set WB_PER enable */ -- cgit v1.2.3 From 79b9a3709de844e29dad16bcb6ae61455c669267 Mon Sep 17 00:00:00 2001 From: Ranjani Vaidyanathan Date: Tue, 16 Oct 2012 08:15:03 -0500 Subject: ENGR00229924 MX6SL-Fix MMDC FIFO reset code. Write to the MMDC registers when resetting the MMDC after the DDR I/Os have been floated. This fixes the bug introduced by the commit: "2a2f65bd07ad0f947794c2e5f2f825121805d663 MX6SL-Reset MMDC read FIFO in low power IDLE" Signed-off-by: Ranjani Vaidyanathan --- arch/arm/mach-mx6/mx6sl_wfi.S | 46 +++++++++++-------------------------------- 1 file changed, 12 insertions(+), 34 deletions(-) diff --git a/arch/arm/mach-mx6/mx6sl_wfi.S b/arch/arm/mach-mx6/mx6sl_wfi.S index e8936b6862c8..4ec97e424237 100644 --- a/arch/arm/mach-mx6/mx6sl_wfi.S +++ b/arch/arm/mach-mx6/mx6sl_wfi.S @@ -29,12 +29,6 @@ ldr r7, [r1, #0x318] /* DRAM_DQM3 */ stmfd r9!, {r4-r7} - ldr r4, [r1, #0x344] /* DRAM_SDQS0 */ - ldr r5, [r1, #0x348] /* DRAM_SDQS1 */ - ldr r6, [r1, #0x34c] /* DRAM_SDQS2 */ - ldr r7, [r1, #0x350] /* DRAM_SDQS3 */ - stmfd r9!, {r4-r7} - ldr r4, [r1, #0x5c4] /* GPR_B0DS */ ldr r5, [r1, #0x5cc] /* GPR_B1DS */ ldr r6, [r1, #0x5d4] /* GPR_B2DS */ @@ -56,25 +50,22 @@ ldr r4, [r1, #0x330] /* DRAM_SDCKE0 */ ldr r5, [r1, #0x334] /* DRAM_SDCKE1 */ ldr r6, [r1, #0x320] /* DRAM_RESET */ - ldr r7, [r1, #0x5c8] /* GPR_CTLDS */ - stmfd r9!, {r4-r7} + stmfd r9!, {r4-r6} .endm .macro sl_ddr_io_restore + /* r9 points to IRAM stack. + * r1 points to IOMUX base address. + * r8 points to MMDC base address. + */ ldmea r9!, {r4-r7} str r4, [r1, #0x30c] /* DRAM_DQM0 */ str r5, [r1, #0x310] /* DRAM_DQM1 */ str r6, [r1, #0x314] /* DRAM_DQM2 */ str r7, [r1, #0x318] /* DRAM_DQM3 */ - ldmea r9!, {r4-r7} - str r4, [r1, #0x344] /* DRAM_SDQS0 */ - str r5, [r1, #0x348] /* DRAM_SDQS1 */ - str r6, [r1, #0x34c] /* DRAM_SDQS2 */ - str r7, [r1, #0x350] /* DRAM_SDQS3 */ - ldmea r9!, {r4-r7} str r4, [r1, #0x5c4] /* GPR_B0DS */ str r5, [r1, #0x5cc] /* GPR_B1DS */ @@ -93,11 +84,10 @@ str r6, [r1, #0x33c] /* DRAM_SODT0*/ str r7, [r1, #0x340] /* DRAM_SODT1*/ - ldmea r9!, {r4-r7} + ldmea r9!, {r4-r6} str r4, [r1, #0x330] /* DRAM_SDCKE0 */ str r5, [r1, #0x334] /* DRAM_SDCKE1 */ str r6, [r1, #0x320] /* DRAM_RESET */ - str r7, [r1, #0x5c8] /* GPR_CTLDS */ /* Need to reset the FIFO to avoid MMDC lockup * caused because of floating/changing the @@ -105,21 +95,21 @@ */ /* reset read FIFO, RST_RD_FIFO */ ldr r7, =0x83c - ldr r6, [r1, r7] + ldr r6, [r8, r7] orr r6, r6, #0x80000000 - str r6, [r1, r7] + str r6, [r8, r7] fifo_reset1_wait: - ldr r6, [r1, r7] + ldr r6, [r8, r7] and r6, r6, #0x80000000 cmp r6, #0 bne fifo_reset1_wait /* reset FIFO a second time */ - ldr r6, [r1, r7] + ldr r6, [r8, r7] orr r6, r6, #0x80000000 - str r6, [r1, r7] + str r6, [r8, r7] fifo_reset2_wait: - ldr r6, [r1, r7] + ldr r6, [r8, r7] and r6, r6, #0x80000000 cmp r6, #0 bne fifo_reset2_wait @@ -134,18 +124,6 @@ fifo_reset2_wait: str r4, [r1, #0x314] /* DRAM_DQM2 */ str r4, [r1, #0x318] /* DRAM_DQM3 */ - /* Make sure the Pull Ups are enabled. - * So only reduce the drive stength, but - * leave the pull-ups in the original state. - * This is required for LPDDR2. - */ - ldr r4, [r1, #0x344] - orr r4, r4, #0x3000 - str r4, [r1, #0x344] /* DRAM_SDQS0 */ - str r4, [r1, #0x348] /* DRAM_SDQS1 */ - str r4, [r1, #0x34c] /* DRAM_SDQS2 */ - str r4, [r1, #0x350] /* DRAM_SDQS3 */ - str r4, [r1, #0x5c4] /* GPR_B0DS */ str r4, [r1, #0x5cc] /* GPR_B1DS */ str r4, [r1, #0x5d4] /* GPR_B2DS */ -- cgit v1.2.3 From 8b4b95597925c63126dec28162d5ac477d0c50bb Mon Sep 17 00:00:00 2001 From: Michael Minnick Date: Tue, 16 Oct 2012 18:07:20 -0500 Subject: ENGR00227965 EPDC: Init sequence leaves EDPC clocks on A small logic bug prevents the init sequence from properly turning off the clocks. This leads to the clocks being always on if the first update does not complete due to the screen being blanked. Signed-off-by: Michael Minnick --- drivers/video/mxc/mxc_epdc_fb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/video/mxc/mxc_epdc_fb.c b/drivers/video/mxc/mxc_epdc_fb.c index 727c6ebc575c..2df44041e65c 100644 --- a/drivers/video/mxc/mxc_epdc_fb.c +++ b/drivers/video/mxc/mxc_epdc_fb.c @@ -1166,6 +1166,8 @@ static void epdc_init_sequence(struct mxc_epdc_fb_data *fb_data) fb_data->in_init = true; epdc_powerup(fb_data); draw_mode0(fb_data); + /* Force power down event */ + fb_data->powering_down = true; epdc_powerdown(fb_data); fb_data->updates_active = false; } -- cgit v1.2.3 From 259601771ec9bf815df3598e712de99c2b5e9c80 Mon Sep 17 00:00:00 2001 From: Robby Cai Date: Mon, 15 Oct 2012 21:36:44 +0800 Subject: ENGR00229665 pxp: correct crop setting The settings in the PXP_PS_BUF, PXP_OUT_PS_ULC, and PXP_OUT_PS_LRC will determine the subset of the PS buffer, or clipped PS source buffer, that will be used in the output buffer. HW_PXP_OUT_PS_LRC should set the scaled output size rather than the origin size when scaling. Please refer to the "Clipping source images" section in RM for how it works. Signed-off-by: Robby Cai --- drivers/dma/pxp/pxp_dma_v2.c | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/drivers/dma/pxp/pxp_dma_v2.c b/drivers/dma/pxp/pxp_dma_v2.c index b74f62cac032..c6098774ecf2 100644 --- a/drivers/dma/pxp/pxp_dma_v2.c +++ b/drivers/dma/pxp/pxp_dma_v2.c @@ -436,22 +436,27 @@ static void pxp_set_olparam(int layer_no, struct pxps *pxp) static void pxp_set_s0param(struct pxps *pxp) { struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state; - struct pxp_layer_param *s0params_data = &pxp_conf->s0_param; struct pxp_proc_data *proc_data = &pxp_conf->proc_data; u32 s0param; - s0param = BF_PXP_OUT_PS_ULC_X(proc_data->srect.left); - s0param |= BF_PXP_OUT_PS_ULC_Y(proc_data->srect.top); + /* contains the coordinate for the PS in the OUTPUT buffer. */ + s0param = BF_PXP_OUT_PS_ULC_X(proc_data->drect.left); + s0param |= BF_PXP_OUT_PS_ULC_Y(proc_data->drect.top); __raw_writel(s0param, pxp->base + HW_PXP_OUT_PS_ULC); - s0param = BF_PXP_OUT_PS_LRC_X(s0params_data->width); - s0param |= BF_PXP_OUT_PS_LRC_Y(s0params_data->height); + s0param = BF_PXP_OUT_PS_LRC_X(proc_data->drect.left + + proc_data->drect.width - 1); + s0param |= BF_PXP_OUT_PS_LRC_Y(proc_data->drect.top + + proc_data->drect.height - 1); __raw_writel(s0param, pxp->base + HW_PXP_OUT_PS_LRC); - } -/* TODO: crop behavior is re-designed in h/w. */ +/* crop behavior is re-designed in h/w. */ static void pxp_set_s0crop(struct pxps *pxp) { + /* + * place-holder, it's implemented in other functions in this driver. + * Refer to "Clipping source images" section in RM for detail. + */ } static int pxp_set_scaling(struct pxps *pxp) @@ -706,19 +711,36 @@ static void pxp_set_s0buf(struct pxps *pxp) { struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state; struct pxp_layer_param *s0_params = &pxp_conf->s0_param; + struct pxp_proc_data *proc_data = &pxp_conf->proc_data; dma_addr_t Y, U, V; + dma_addr_t Y1, U1, V1; + u32 offset, bpp = 1; Y = s0_params->paddr; - __raw_writel(Y, pxp->base + HW_PXP_PS_BUF); + + if (s0_params->pixel_fmt == PXP_PIX_FMT_RGB565) + bpp = 2; + else if (s0_params->pixel_fmt == PXP_PIX_FMT_RGB24) + bpp = 4; + offset = (proc_data->srect.top * s0_params->width + + proc_data->srect.left) * bpp; + /* clipping or cropping */ + Y1 = Y + offset; + __raw_writel(Y1, pxp->base + HW_PXP_PS_BUF); if ((s0_params->pixel_fmt == PXP_PIX_FMT_YUV420P) || (s0_params->pixel_fmt == PXP_PIX_FMT_YVU420P) || (s0_params->pixel_fmt == PXP_PIX_FMT_GREY)) { /* Set to 1 if YUV format is 4:2:2 rather than 4:2:0 */ int s = 2; + + offset = proc_data->srect.top * s0_params->width / 4 + + proc_data->srect.left / 2; U = Y + (s0_params->width * s0_params->height); + U1 = U + offset; V = U + ((s0_params->width * s0_params->height) >> s); - __raw_writel(U, pxp->base + HW_PXP_PS_UBUF); - __raw_writel(V, pxp->base + HW_PXP_PS_VBUF); + V1 = V + offset; + __raw_writel(U1, pxp->base + HW_PXP_PS_UBUF); + __raw_writel(V1, pxp->base + HW_PXP_PS_VBUF); } /* TODO: only support RGB565, Y8, Y4, YUV420 */ -- cgit v1.2.3 From 94689e1fed43ece131451a90f1716893a418cba0 Mon Sep 17 00:00:00 2001 From: Robby Cai Date: Wed, 17 Oct 2012 09:01:35 +0800 Subject: ENGR00229938 pxp/v4l2: check return value of kmalloc against NULL This is needed sanity check, because on Ubuntu it's likely that low memory will happen. This patch also makes this memory allocated from dma zone. Signed-off-by: Robby Cai --- drivers/media/video/mxc/output/mxc_pxp_v4l2.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/mxc/output/mxc_pxp_v4l2.c b/drivers/media/video/mxc/output/mxc_pxp_v4l2.c index c17f9f1d9cdc..08d16b9f75d3 100644 --- a/drivers/media/video/mxc/output/mxc_pxp_v4l2.c +++ b/drivers/media/video/mxc/output/mxc_pxp_v4l2.c @@ -396,7 +396,12 @@ static int pxp_s_output(struct file *file, void *fh, bpp = 2; pxp->outb_size = fmt->width * fmt->height * bpp; - pxp->outb = kmalloc(fmt->width * fmt->height * bpp, GFP_KERNEL); + pxp->outb = kmalloc(fmt->width * fmt->height * bpp, + GFP_KERNEL | GFP_DMA); + if (pxp->outb == NULL) { + dev_err(&pxp->pdev->dev, "No enough memory!\n"); + return -ENOMEM; + } pxp->outb_phys = virt_to_phys(pxp->outb); dma_map_single(NULL, pxp->outb, fmt->width * fmt->height * bpp, DMA_TO_DEVICE); -- cgit v1.2.3