summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinyu Chen <xinyu.chen@freescale.com>2012-10-24 12:50:34 +0800
committerXinyu Chen <xinyu.chen@freescale.com>2012-10-24 12:50:34 +0800
commit5b53e2720902c5dd9fbfc9b2644484173a5146aa (patch)
treea369ffd3a3231a0d30c306c46636ec3e87cdbf39
parente2f718a0c092f899e354b5179cde70f7aa7ab7a8 (diff)
parent3101ee16f2f39b589d627b2858c5e3eca470dce7 (diff)
Merge remote branch 'fsl-linux-sdk/imx_3.0.35_12.11.01' into imx_3.0.35_android_r13.4.y
Conflicts: arch/arm/configs/imx6s_updater_defconfig arch/arm/include/asm/hardware/coresight.h arch/arm/kernel/etm.c arch/arm/mach-mx6/board-mx6q_sabresd.c arch/arm/mach-mx6/cpu_op-mx6.c arch/arm/mach-mx6/mx6_suspend.S arch/arm/mach-mx6/mx6sl_wfi.S arch/arm/mach-mx6/pm.c arch/arm/mach-mx6/system.c arch/arm/plat-mxc/cpufreq.c drivers/media/video/mxc/capture/ov5640_mipi.c drivers/mfd/mxc-hdmi-core.c drivers/mmc/host/sdhci.c drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c drivers/power/sabresd_battery.c drivers/video/mxc/mxc_ipuv3_fb.c include/linux/mfd/mxc-hdmi-core.h
-rw-r--r--arch/arm/configs/imx6_android_defconfig17
-rw-r--r--arch/arm/configs/imx6_defconfig34
-rw-r--r--arch/arm/configs/imx6_updater_defconfig43
-rw-r--r--arch/arm/configs/imx6s_defconfig57
-rw-r--r--arch/arm/configs/imx6s_updater_defconfig27
-rw-r--r--arch/arm/include/asm/hardware/coresight.h26
-rw-r--r--arch/arm/kernel/etm.c231
-rwxr-xr-xarch/arm/mach-mx5/devices-imx50.h6
-rw-r--r--arch/arm/mach-mx6/Kconfig2
-rw-r--r--arch/arm/mach-mx6/Makefile2
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabreauto.c97
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabreauto.h7
-rwxr-xr-xarch/arm/mach-mx6/board-mx6sl_arm2.c2
-rw-r--r--arch/arm/mach-mx6/board-mx6sl_common.h17
-rw-r--r--arch/arm/mach-mx6/board-mx6sl_evk.c299
-rw-r--r--arch/arm/mach-mx6/board-mx6solo_sabreauto.h4
-rw-r--r--arch/arm/mach-mx6/bus_freq.c18
-rw-r--r--arch/arm/mach-mx6/clock.c3
-rwxr-xr-xarch/arm/mach-mx6/clock_mx6sl.c13
-rw-r--r--arch/arm/mach-mx6/cpu.c8
-rw-r--r--arch/arm/mach-mx6/cpu_op-mx6.c50
-rw-r--r--arch/arm/mach-mx6/cpu_regulator-mx6.c24
-rw-r--r--arch/arm/mach-mx6/devices-imx6q.h12
-rw-r--r--arch/arm/mach-mx6/etm.c110
-rw-r--r--arch/arm/mach-mx6/mx6_anatop_regulator.c140
-rw-r--r--arch/arm/mach-mx6/mx6_suspend.S618
-rw-r--r--arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c6
-rw-r--r--arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c8
-rw-r--r--arch/arm/mach-mx6/mx6sl_wfi.S222
-rw-r--r--arch/arm/mach-mx6/pm.c162
-rw-r--r--arch/arm/mach-mx6/system.c137
-rw-r--r--arch/arm/mach-mx6/usb.h3
-rw-r--r--arch/arm/mach-mx6/usb_dr.c27
-rw-r--r--arch/arm/mach-mx6/usb_h1.c21
-rwxr-xr-xarch/arm/plat-mxc/cpu.c10
-rwxr-xr-xarch/arm/plat-mxc/cpufreq.c20
-rwxr-xr-xarch/arm/plat-mxc/devices/Kconfig3
-rwxr-xr-xarch/arm/plat-mxc/devices/Makefile1
-rw-r--r--arch/arm/plat-mxc/devices/platform-dma.c8
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-fsl-csi.c55
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-uart.c12
-rwxr-xr-xarch/arm/plat-mxc/dvfs_core.c5
-rwxr-xr-xarch/arm/plat-mxc/include/mach/devices-common.h12
-rwxr-xr-xarch/arm/plat-mxc/include/mach/iomux-mx6sl.h9
-rw-r--r--arch/arm/plat-mxc/include/mach/mx6.h17
-rwxr-xr-xarch/arm/plat-mxc/include/mach/mxc.h4
-rwxr-xr-xarch/arm/plat-mxc/usb_common.c37
-rwxr-xr-xdrivers/char/fsl_otp.c3
-rw-r--r--drivers/dma/imx-sdma.c60
-rw-r--r--drivers/dma/mxs-dma.c2
-rw-r--r--drivers/dma/pxp/pxp_dma_v2.c5
-rw-r--r--drivers/media/video/mxc/capture/Kconfig12
-rw-r--r--drivers/media/video/mxc/capture/Makefile3
-rw-r--r--drivers/media/video/mxc/capture/adv7280_mipi_tvin.c281
-rw-r--r--drivers/media/video/mxc/capture/csi_v4l2_capture.c364
-rw-r--r--drivers/media/video/mxc/capture/fsl_csi.c58
-rw-r--r--drivers/media/video/mxc/capture/fsl_csi.h35
-rw-r--r--drivers/media/video/mxc/capture/ipu_prp_enc.c2
-rw-r--r--drivers/media/video/mxc/capture/mt9v111.c4
-rw-r--r--drivers/media/video/mxc/capture/mxc_v4l2_capture.h18
-rw-r--r--drivers/media/video/mxc/capture/ov2640.c4
-rw-r--r--drivers/media/video/mxc/capture/ov5640_mipi.c7
-rw-r--r--drivers/media/video/mxc/capture/ov5642.c17
-rw-r--r--drivers/media/video/mxc/capture/sensor_clock.c28
-rw-r--r--drivers/media/video/mxc/output/mxc_vout.c45
-rw-r--r--drivers/mfd/mxc-hdmi-core.c12
-rwxr-xr-xdrivers/mmc/host/sdhci.c2
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-lib.c2
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.c41
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.h2
-rw-r--r--drivers/mtd/nand/nand_base.c60
-rw-r--r--drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c32
-rw-r--r--drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h2
-rw-r--r--drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c7
-rw-r--r--drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c230
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c198
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h7
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c27
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c89
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c21
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c64
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c37
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c21
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c47
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c6
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h42
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h55
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h316
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h287
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h38
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h10
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h10
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h7
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h116
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h2
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h6
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c26
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h4
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c9
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h3
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c3
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h1
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c195
-rw-r--r--drivers/mxc/ipu3/ipu_device.c24
-rw-r--r--drivers/mxc/thermal/cooling.c3
-rw-r--r--drivers/mxc/vpu/mxc_vpu.c44
-rwxr-xr-xdrivers/net/fec.c14
-rwxr-xr-xdrivers/power/Kconfig1
-rwxr-xr-xdrivers/power/sabresd_battery.c178
-rw-r--r--drivers/regulator/max17135-regulator.c20
-rw-r--r--drivers/tty/serial/imx.c5
-rwxr-xr-xdrivers/usb/gadget/arcotg_udc.c14
-rwxr-xr-xdrivers/usb/host/ehci-arc.c6
-rw-r--r--drivers/video/mxc/Kconfig6
-rw-r--r--drivers/video/mxc/Makefile7
-rw-r--r--drivers/video/mxc/mxc_elcdif_fb.c147
-rw-r--r--drivers/video/mxc/mxc_epdc_fb.c333
-rw-r--r--drivers/video/mxc/mxc_ipuv3_fb.c284
-rw-r--r--drivers/video/mxc/mxcfb_sii902x_elcdif.c560
-rw-r--r--include/linux/fsl_devices.h1
-rw-r--r--include/linux/mfd/max17135.h5
-rw-r--r--include/linux/mfd/mxc-hdmi-core.h1
-rw-r--r--include/linux/mtd/nand.h11
-rw-r--r--include/linux/mxcfb.h11
-rw-r--r--include/linux/power/sabresd_battery.h1
-rw-r--r--sound/soc/codecs/wm8962.c2
-rw-r--r--sound/soc/imx/imx-hdmi-dma.c2
-rw-r--r--sound/soc/imx/imx-spdif.c7
-rw-r--r--tools/perf/util/include/linux/compiler.h2
129 files changed, 5783 insertions, 1537 deletions
diff --git a/arch/arm/configs/imx6_android_defconfig b/arch/arm/configs/imx6_android_defconfig
index f60818719425..06a8697dc619 100644
--- a/arch/arm/configs/imx6_android_defconfig
+++ b/arch/arm/configs/imx6_android_defconfig
@@ -403,6 +403,7 @@ CONFIG_ARM_GIC=y
#
# Bus support
#
+CONFIG_ARM_AMBA=y
# CONFIG_PCI_SYSCALL is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCCARD is not set
@@ -1353,6 +1354,7 @@ CONFIG_INPUT_ISL29023=y
#
CONFIG_SERIO=y
CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
CONFIG_SERIO_LIBPS2=y
# CONFIG_SERIO_RAW is not set
# CONFIG_SERIO_ALTERA_PS2 is not set
@@ -1381,6 +1383,8 @@ CONFIG_DEVKMEM=y
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
# CONFIG_SERIAL_MAX3100 is not set
# CONFIG_SERIAL_MAX3107 is not set
CONFIG_SERIAL_IMX=y
@@ -1454,6 +1458,7 @@ CONFIG_SPI_BITBANG=y
CONFIG_SPI_IMX_VER_2_3=y
CONFIG_SPI_IMX=y
# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PL022 is not set
# CONFIG_SPI_PXA2XX_PCI is not set
# CONFIG_SPI_XILINX is not set
# CONFIG_SPI_DESIGNWARE is not set
@@ -1489,6 +1494,7 @@ CONFIG_GPIO_SYSFS=y
#
# CONFIG_GPIO_BASIC_MMIO is not set
# CONFIG_GPIO_IT8761E is not set
+# CONFIG_GPIO_PL061 is not set
#
# I2C GPIO expanders:
@@ -1640,6 +1646,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y
# Watchdog Device Drivers
#
# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ARM_SP805_WATCHDOG is not set
# CONFIG_MPCORE_WATCHDOG is not set
# CONFIG_MAX63XX_WATCHDOG is not set
CONFIG_IMX2_WDT=y
@@ -1857,6 +1864,7 @@ CONFIG_VIDEO_MXC_IPU_CAMERA=y
CONFIG_MXC_CAMERA_OV5642=y
# CONFIG_MXC_TVIN_ADV7180 is not set
CONFIG_MXC_CAMERA_OV5640_MIPI=y
+# CONFIG_MXC_MIPI_CSI2_TVIN_ADV7280 is not set
CONFIG_MXC_CAMERA_SENSOR_CLK=y
# CONFIG_MXC_IPU_DEVICE_QUEUE_SDC is not set
CONFIG_MXC_IPU_PRP_VF_SDC=y
@@ -1917,6 +1925,7 @@ CONFIG_FB_MODE_HELPERS=y
#
# Frame buffer hardware drivers
#
+# CONFIG_FB_ARMCLCD is not set
# CONFIG_FB_UVESA is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_TMIO is not set
@@ -1946,6 +1955,7 @@ CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL=y
# CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL is not set
# CONFIG_FB_MXC_SEIKO_WVGA_SYNC_PANEL is not set
# CONFIG_FB_MXC_SII902X is not set
+# CONFIG_FB_MXC_SII902X_ELCDIF is not set
# CONFIG_FB_MXC_CH7026 is not set
# CONFIG_FB_MXC_TVOUT_CH7024 is not set
# CONFIG_FB_MXC_ASYNC_PANEL is not set
@@ -1983,6 +1993,7 @@ CONFIG_SND_DRIVERS=y
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 is not set
CONFIG_SND_ARM=y
+# CONFIG_SND_ARMAACI is not set
CONFIG_SND_SPI=y
CONFIG_SND_USB=y
CONFIG_SND_USB_AUDIO=y
@@ -2303,6 +2314,7 @@ CONFIG_MMC_BLOCK_DEFERRED_RESUME=y
#
# MMC/SD/SDIO Host Controller Drivers
#
+# CONFIG_MMC_ARMMMCI is not set
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_IO_ACCESSORS=y
CONFIG_MMC_SDHCI_PLTFM=y
@@ -2430,12 +2442,15 @@ CONFIG_RTC_DRV_SNVS=y
#
# on-CPU RTC drivers
#
+# CONFIG_RTC_DRV_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
CONFIG_DMADEVICES=y
# CONFIG_DMADEVICES_DEBUG is not set
#
# DMA Devices
#
+# CONFIG_AMBA_PL08X is not set
# CONFIG_DW_DMAC is not set
# CONFIG_MXC_PXP_V2 is not set
# CONFIG_TIMB_DMA is not set
@@ -2828,7 +2843,7 @@ CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_STRICT_DEVMEM is not set
CONFIG_ARM_UNWIND=y
# CONFIG_DEBUG_USER is not set
-# CONFIG_OC_ETM is not set
+CONFIG_OC_ETM=y
#
# Security options
diff --git a/arch/arm/configs/imx6_defconfig b/arch/arm/configs/imx6_defconfig
index f9a4eacce42b..f1bab5fe2838 100644
--- a/arch/arm/configs/imx6_defconfig
+++ b/arch/arm/configs/imx6_defconfig
@@ -317,6 +317,7 @@ CONFIG_MACH_MX6Q_SABREAUTO=y
# CONFIG_IMX_PCIE is not set
CONFIG_USB_EHCI_ARC_H1=y
# CONFIG_MX6_INTER_LDO_BYPASS is not set
+# CONFIG_MX6_CLK_FOR_BOOTUI_TRANS is not set
CONFIG_ISP1504_MXC=y
# CONFIG_MXC_IRQ_PRIOR is not set
CONFIG_MXC_PWM=y
@@ -383,6 +384,7 @@ CONFIG_ARM_GIC=y
#
# Bus support
#
+CONFIG_ARM_AMBA=y
# CONFIG_PCI_SYSCALL is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCCARD is not set
@@ -722,8 +724,10 @@ CONFIG_MTD_BLOCK=y
#
# RAM/ROM/Flash chip drivers
#
-# CONFIG_MTD_CFI is not set
+CONFIG_MTD_CFI=y
# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
@@ -734,6 +738,10 @@ CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
@@ -742,6 +750,9 @@ CONFIG_MTD_CFI_I2=y
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
# CONFIG_MTD_PLATRAM is not set
#
@@ -773,7 +784,7 @@ CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_NAND_NANDSIM is not set
-# CONFIG_MTD_NAND_GPMI_NAND is not set
+CONFIG_MTD_NAND_GPMI_NAND=y
# CONFIG_MTD_NAND_PLATFORM is not set
# CONFIG_MTD_ALAUDA is not set
# CONFIG_MTD_ONENAND is not set
@@ -1115,6 +1126,7 @@ CONFIG_INPUT_ISL29023=y
#
CONFIG_SERIO=y
CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
CONFIG_SERIO_LIBPS2=y
# CONFIG_SERIO_RAW is not set
# CONFIG_SERIO_ALTERA_PS2 is not set
@@ -1146,6 +1158,8 @@ CONFIG_DEVKMEM=y
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
# CONFIG_SERIAL_MAX3100 is not set
# CONFIG_SERIAL_MAX3107 is not set
CONFIG_SERIAL_IMX=y
@@ -1219,6 +1233,7 @@ CONFIG_SPI_BITBANG=y
CONFIG_SPI_IMX_VER_2_3=y
CONFIG_SPI_IMX=y
# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PL022 is not set
# CONFIG_SPI_PXA2XX_PCI is not set
# CONFIG_SPI_XILINX is not set
# CONFIG_SPI_DESIGNWARE is not set
@@ -1254,6 +1269,7 @@ CONFIG_GPIO_SYSFS=y
#
# CONFIG_GPIO_BASIC_MMIO is not set
# CONFIG_GPIO_IT8761E is not set
+# CONFIG_GPIO_PL061 is not set
#
# I2C GPIO expanders:
@@ -1405,6 +1421,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y
# Watchdog Device Drivers
#
# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ARM_SP805_WATCHDOG is not set
# CONFIG_MPCORE_WATCHDOG is not set
# CONFIG_MAX63XX_WATCHDOG is not set
CONFIG_IMX2_WDT=y
@@ -1726,6 +1743,7 @@ CONFIG_FB_MODE_HELPERS=y
#
# Frame buffer hardware drivers
#
+# CONFIG_FB_ARMCLCD is not set
# CONFIG_FB_UVESA is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_TMIO is not set
@@ -1755,6 +1773,7 @@ CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL=y
# CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL is not set
# CONFIG_FB_MXC_SEIKO_WVGA_SYNC_PANEL is not set
# CONFIG_FB_MXC_SII902X is not set
+# CONFIG_FB_MXC_SII902X_ELCDIF is not set
# CONFIG_FB_MXC_CH7026 is not set
# CONFIG_FB_MXC_TVOUT_CH7024 is not set
# CONFIG_FB_MXC_ASYNC_PANEL is not set
@@ -1815,6 +1834,7 @@ CONFIG_SND_DRIVERS=y
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 is not set
CONFIG_SND_ARM=y
+# CONFIG_SND_ARMAACI is not set
CONFIG_SND_SPI=y
CONFIG_SND_USB=y
CONFIG_SND_USB_AUDIO=y
@@ -2082,6 +2102,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
#
# MMC/SD/SDIO Host Controller Drivers
#
+# CONFIG_MMC_ARMMMCI is not set
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_IO_ACCESSORS=y
CONFIG_MMC_SDHCI_PLTFM=y
@@ -2203,18 +2224,21 @@ CONFIG_RTC_DRV_SNVS=y
#
# on-CPU RTC drivers
#
+# CONFIG_RTC_DRV_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
CONFIG_DMADEVICES=y
# CONFIG_DMADEVICES_DEBUG is not set
#
# DMA Devices
#
+# CONFIG_AMBA_PL08X is not set
# CONFIG_DW_DMAC is not set
CONFIG_MXC_PXP_V2=y
CONFIG_MXC_PXP_CLIENT_DEVICE=y
# CONFIG_TIMB_DMA is not set
CONFIG_IMX_SDMA=y
-# CONFIG_MXS_DMA is not set
+CONFIG_MXS_DMA=y
CONFIG_DMA_ENGINE=y
#
@@ -2305,7 +2329,7 @@ CONFIG_MXC_MLB150=m
#
# MXC Vivante GPU support
#
-CONFIG_MXC_GPU_VIV=m
+CONFIG_MXC_GPU_VIV=y
#
# ANATOP_THERMAL
@@ -2550,7 +2574,7 @@ CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_STRICT_DEVMEM is not set
CONFIG_ARM_UNWIND=y
# CONFIG_DEBUG_USER is not set
-# CONFIG_OC_ETM is not set
+CONFIG_OC_ETM=y
#
# Security options
diff --git a/arch/arm/configs/imx6_updater_defconfig b/arch/arm/configs/imx6_updater_defconfig
index 02b3707f62d0..06ffbc56eee5 100644
--- a/arch/arm/configs/imx6_updater_defconfig
+++ b/arch/arm/configs/imx6_updater_defconfig
@@ -316,6 +316,7 @@ CONFIG_SOC_IMX6Q=y
CONFIG_SOC_IMX6SL=y
CONFIG_MACH_MX6Q_ARM2=y
CONFIG_MACH_MX6SL_ARM2=y
+# CONFIG_MACH_MX6SL_EVK is not set
CONFIG_MACH_MX6Q_SABRELITE=y
CONFIG_MACH_MX6Q_SABRESD=y
CONFIG_MACH_MX6Q_SABREAUTO=y
@@ -325,6 +326,7 @@ CONFIG_MACH_MX6Q_SABREAUTO=y
#
# CONFIG_IMX_PCIE is not set
# CONFIG_MX6_INTER_LDO_BYPASS is not set
+# CONFIG_MX6_CLK_FOR_BOOTUI_TRANS is not set
CONFIG_ISP1504_MXC=y
# CONFIG_MXC_IRQ_PRIOR is not set
CONFIG_MXC_PWM=y
@@ -392,6 +394,7 @@ CONFIG_ARM_GIC=y
#
# Bus support
#
+CONFIG_ARM_AMBA=y
# CONFIG_PCI_SYSCALL is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCCARD is not set
@@ -697,8 +700,10 @@ CONFIG_MTD_BLOCK=y
#
# RAM/ROM/Flash chip drivers
#
-# CONFIG_MTD_CFI is not set
+CONFIG_MTD_CFI=y
# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
@@ -709,6 +714,10 @@ CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
@@ -717,6 +726,9 @@ CONFIG_MTD_CFI_I2=y
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
# CONFIG_MTD_PLATRAM is not set
#
@@ -748,7 +760,7 @@ CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_NAND_NANDSIM is not set
-# CONFIG_MTD_NAND_GPMI_NAND is not set
+CONFIG_MTD_NAND_GPMI_NAND=y
# CONFIG_MTD_NAND_PLATFORM is not set
# CONFIG_MTD_ALAUDA is not set
# CONFIG_MTD_ONENAND is not set
@@ -1053,6 +1065,8 @@ CONFIG_DEVKMEM=y
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
# CONFIG_SERIAL_MAX3100 is not set
# CONFIG_SERIAL_MAX3107 is not set
CONFIG_SERIAL_IMX=y
@@ -1126,6 +1140,7 @@ CONFIG_SPI_BITBANG=y
CONFIG_SPI_IMX_VER_2_3=y
CONFIG_SPI_IMX=y
# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PL022 is not set
# CONFIG_SPI_PXA2XX_PCI is not set
# CONFIG_SPI_XILINX is not set
# CONFIG_SPI_DESIGNWARE is not set
@@ -1161,6 +1176,7 @@ CONFIG_GPIOLIB=y
#
# CONFIG_GPIO_BASIC_MMIO is not set
# CONFIG_GPIO_IT8761E is not set
+# CONFIG_GPIO_PL061 is not set
#
# I2C GPIO expanders:
@@ -1205,6 +1221,7 @@ CONFIG_POWER_SUPPLY=y
# CONFIG_BATTERY_MAX17042 is not set
# CONFIG_CHARGER_ISP1704 is not set
# CONFIG_CHARGER_MAX8903 is not set
+# CONFIG_SABRESD_MAX8903 is not set
# CONFIG_CHARGER_GPIO is not set
# CONFIG_HWMON is not set
CONFIG_THERMAL=y
@@ -1215,6 +1232,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y
# Watchdog Device Drivers
#
# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ARM_SP805_WATCHDOG is not set
# CONFIG_MAX63XX_WATCHDOG is not set
CONFIG_IMX2_WDT=y
@@ -1417,17 +1435,10 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y
# CONFIG_VIDEO_M52790 is not set
# CONFIG_VIDEO_VIVI is not set
# CONFIG_VIDEO_MXC_CAMERA is not set
-# CONFIG_MXC_CAMERA_MICRON111 is not set
-# CONFIG_MXC_CAMERA_OV2640 is not set
-# CONFIG_MXC_CAMERA_OV3640 is not set
-# CONFIG_MXC_CAMERA_OV5640 is not set
-# CONFIG_MXC_CAMERA_OV8820_MIPI is not set
-# CONFIG_MXC_CAMERA_OV5642 is not set
-# CONFIG_MXC_TVIN_ADV7180 is not set
-# CONFIG_MXC_IPU_DEVICE_QUEUE_SDC is not set
CONFIG_VIDEO_MXC_OUTPUT=y
CONFIG_VIDEO_MXC_IPU_OUTPUT=y
# CONFIG_VIDEO_MXC_IPUV1_WVGA_OUTPUT is not set
+# CONFIG_VIDEO_MXC_PXP_V4L2 is not set
# CONFIG_VIDEO_MXC_OPL is not set
# CONFIG_VIDEO_CPIA2 is not set
# CONFIG_VIDEO_TIMBERDALE is not set
@@ -1467,6 +1478,7 @@ CONFIG_FB_MODE_HELPERS=y
#
# Frame buffer hardware drivers
#
+# CONFIG_FB_ARMCLCD is not set
# CONFIG_FB_UVESA is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_TMIO is not set
@@ -1489,6 +1501,7 @@ CONFIG_FB_MXC_LDB=y
# CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL is not set
# CONFIG_FB_MXC_SEIKO_WVGA_SYNC_PANEL is not set
# CONFIG_FB_MXC_SII902X is not set
+# CONFIG_FB_MXC_SII902X_ELCDIF is not set
# CONFIG_FB_MXC_CH7026 is not set
# CONFIG_FB_MXC_TVOUT_CH7024 is not set
# CONFIG_FB_MXC_ASYNC_PANEL is not set
@@ -1546,6 +1559,7 @@ CONFIG_SND_DRIVERS=y
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 is not set
CONFIG_SND_ARM=y
+# CONFIG_SND_ARMAACI is not set
CONFIG_SND_SPI=y
CONFIG_SND_USB=y
# CONFIG_SND_USB_AUDIO is not set
@@ -1794,6 +1808,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
#
# MMC/SD/SDIO Host Controller Drivers
#
+# CONFIG_MMC_ARMMMCI is not set
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_IO_ACCESSORS=y
CONFIG_MMC_SDHCI_PLTFM=y
@@ -1879,17 +1894,20 @@ CONFIG_RTC_DRV_SNVS=y
#
# on-CPU RTC drivers
#
+# CONFIG_RTC_DRV_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
CONFIG_DMADEVICES=y
# CONFIG_DMADEVICES_DEBUG is not set
#
# DMA Devices
#
+# CONFIG_AMBA_PL08X is not set
# CONFIG_DW_DMAC is not set
# CONFIG_MXC_PXP_V2 is not set
# CONFIG_TIMB_DMA is not set
CONFIG_IMX_SDMA=y
-# CONFIG_MXS_DMA is not set
+CONFIG_MXS_DMA=y
CONFIG_DMA_ENGINE=y
#
@@ -1981,6 +1999,7 @@ CONFIG_MXC_IPU_V3H=y
#
CONFIG_MXC_VPU=y
# CONFIG_MXC_VPU_DEBUG is not set
+# CONFIG_MX6_VPU_352M is not set
#
# MXC Asynchronous Sample Rate Converter support
@@ -2253,7 +2272,7 @@ CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_STRICT_DEVMEM is not set
CONFIG_ARM_UNWIND=y
# CONFIG_DEBUG_USER is not set
-# CONFIG_OC_ETM is not set
+CONFIG_OC_ETM=y
#
# Security options
diff --git a/arch/arm/configs/imx6s_defconfig b/arch/arm/configs/imx6s_defconfig
index f03e456d7386..ac7afdfdf5ff 100644
--- a/arch/arm/configs/imx6s_defconfig
+++ b/arch/arm/configs/imx6s_defconfig
@@ -294,6 +294,7 @@ CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_DSI=y
CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_CSI2=y
CONFIG_IMX_HAVE_PLATFORM_IMX_VDOA=y
CONFIG_IMX_HAVE_PLATFORM_IMX_PCIE=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_FSL_CSI=y
#
# Freescale MXC Implementations
@@ -384,6 +385,7 @@ CONFIG_ARM_GIC=y
#
# Bus support
#
+CONFIG_ARM_AMBA=y
# CONFIG_PCI_SYSCALL is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCCARD is not set
@@ -1104,6 +1106,7 @@ CONFIG_INPUT_ISL29023=y
#
CONFIG_SERIO=y
CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
CONFIG_SERIO_LIBPS2=y
# CONFIG_SERIO_RAW is not set
# CONFIG_SERIO_ALTERA_PS2 is not set
@@ -1135,6 +1138,8 @@ CONFIG_DEVKMEM=y
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
# CONFIG_SERIAL_MAX3100 is not set
# CONFIG_SERIAL_MAX3107 is not set
CONFIG_SERIAL_IMX=y
@@ -1208,6 +1213,7 @@ CONFIG_SPI_BITBANG=y
CONFIG_SPI_IMX_VER_2_3=y
CONFIG_SPI_IMX=y
# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PL022 is not set
# CONFIG_SPI_PXA2XX_PCI is not set
# CONFIG_SPI_XILINX is not set
# CONFIG_SPI_DESIGNWARE is not set
@@ -1243,6 +1249,7 @@ CONFIG_GPIO_SYSFS=y
#
# CONFIG_GPIO_BASIC_MMIO is not set
# CONFIG_GPIO_IT8761E is not set
+# CONFIG_GPIO_PL061 is not set
#
# I2C GPIO expanders:
@@ -1287,7 +1294,8 @@ CONFIG_POWER_SUPPLY=y
# CONFIG_BATTERY_MAX17040 is not set
# CONFIG_BATTERY_MAX17042 is not set
# CONFIG_CHARGER_ISP1704 is not set
-CONFIG_CHARGER_MAX8903=y
+# CONFIG_CHARGER_MAX8903 is not set
+CONFIG_SABRESD_MAX8903=y
# CONFIG_CHARGER_GPIO is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
@@ -1393,6 +1401,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y
# Watchdog Device Drivers
#
# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ARM_SP805_WATCHDOG is not set
# CONFIG_MAX63XX_WATCHDOG is not set
CONFIG_IMX2_WDT=y
@@ -1595,10 +1604,23 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y
# CONFIG_VIDEO_THS7303 is not set
# CONFIG_VIDEO_M52790 is not set
# CONFIG_VIDEO_VIVI is not set
-# CONFIG_VIDEO_MXC_CAMERA is not set
+CONFIG_VIDEO_MXC_CAMERA=y
+
+#
+# MXC Camera/V4L2 PRP Features support
+#
+CONFIG_VIDEO_MXC_CSI_CAMERA=y
+# CONFIG_MXC_CAMERA_MICRON111 is not set
+# CONFIG_MXC_CAMERA_OV2640 is not set
+# CONFIG_MXC_CAMERA_OV3640 is not set
+CONFIG_MXC_CAMERA_OV5640=y
+# CONFIG_MXC_CAMERA_OV8820_MIPI is not set
+# CONFIG_MXC_CAMERA_OV5642 is not set
+# CONFIG_MXC_TVIN_ADV7180 is not set
+# CONFIG_MXC_CAMERA_OV5640_MIPI is not set
+CONFIG_MXC_CAMERA_SENSOR_CLK=y
CONFIG_VIDEO_MXC_OUTPUT=y
-CONFIG_VIDEO_MXC_IPU_OUTPUT=y
-# CONFIG_VIDEO_MXC_IPUV1_WVGA_OUTPUT is not set
+# CONFIG_VIDEO_MXC_PXP_V4L2 is not set
# CONFIG_VIDEO_MXC_OPL is not set
# CONFIG_VIDEO_CPIA2 is not set
# CONFIG_VIDEO_TIMBERDALE is not set
@@ -1694,6 +1716,7 @@ CONFIG_FB_MODE_HELPERS=y
#
# Frame buffer hardware drivers
#
+# CONFIG_FB_ARMCLCD is not set
# CONFIG_FB_UVESA is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_TMIO is not set
@@ -1717,20 +1740,18 @@ CONFIG_FB_MXC=y
CONFIG_FB_MXC_EDID=y
CONFIG_FB_MXC_SYNC_PANEL=y
# CONFIG_FB_MXC_EPSON_VGA_SYNC_PANEL is not set
-CONFIG_FB_MXC_LDB=y
-CONFIG_FB_MXC_MIPI_DSI=y
-CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL=y
# CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL is not set
-# CONFIG_FB_MXC_SEIKO_WVGA_SYNC_PANEL is not set
+CONFIG_FB_MXC_SEIKO_WVGA_SYNC_PANEL=y
# CONFIG_FB_MXC_SII902X is not set
+CONFIG_FB_MXC_SII902X_ELCDIF=y
# CONFIG_FB_MXC_CH7026 is not set
# CONFIG_FB_MXC_TVOUT_CH7024 is not set
# CONFIG_FB_MXC_ASYNC_PANEL is not set
CONFIG_FB_MXC_EINK_PANEL=y
# CONFIG_FB_MXC_EINK_AUTO_UPDATE_MODE is not set
# CONFIG_FB_MXC_SIPIX_PANEL is not set
-# CONFIG_FB_MXC_ELCDIF_FB is not set
-CONFIG_FB_MXC_HDMI=y
+CONFIG_FB_MXC_ELCDIF_FB=y
+# CONFIG_FB_MXC_HDMI is not set
#
# Console display driver support
@@ -1783,6 +1804,7 @@ CONFIG_SND_DRIVERS=y
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 is not set
CONFIG_SND_ARM=y
+# CONFIG_SND_ARMAACI is not set
CONFIG_SND_SPI=y
CONFIG_SND_USB=y
CONFIG_SND_USB_AUDIO=y
@@ -1995,7 +2017,7 @@ CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_VBUS_DRAW=2
CONFIG_USB_GADGET_SELECTED=y
CONFIG_USB_GADGET_ARC=y
-CONFIG_IMX_USB_CHARGER=y
+# CONFIG_IMX_USB_CHARGER is not set
CONFIG_USB_ARC=y
# CONFIG_USB_GADGET_FSL_USB2 is not set
# CONFIG_USB_GADGET_FUSB300 is not set
@@ -2050,6 +2072,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
#
# MMC/SD/SDIO Host Controller Drivers
#
+# CONFIG_MMC_ARMMMCI is not set
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_IO_ACCESSORS=y
CONFIG_MMC_SDHCI_PLTFM=y
@@ -2161,12 +2184,15 @@ CONFIG_RTC_DRV_SNVS=y
#
# on-CPU RTC drivers
#
+# CONFIG_RTC_DRV_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
CONFIG_DMADEVICES=y
# CONFIG_DMADEVICES_DEBUG is not set
#
# DMA Devices
#
+# CONFIG_AMBA_PL08X is not set
# CONFIG_DW_DMAC is not set
CONFIG_MXC_PXP_V2=y
CONFIG_MXC_PXP_CLIENT_DEVICE=y
@@ -2190,9 +2216,7 @@ CONFIG_CLKSRC_MMIO=y
#
# MXC support drivers
#
-CONFIG_MXC_IPU=y
-CONFIG_MXC_IPU_V3=y
-CONFIG_MXC_IPU_V3H=y
+# CONFIG_MXC_IPU is not set
#
# MXC SSI support
@@ -2234,6 +2258,7 @@ CONFIG_MXC_IPU_V3H=y
#
CONFIG_MXC_VPU=y
# CONFIG_MXC_VPU_DEBUG is not set
+# CONFIG_MX6_VPU_352M is not set
#
# MXC Asynchronous Sample Rate Converter support
@@ -2262,7 +2287,7 @@ CONFIG_MXC_MLB150=m
#
# MXC Vivante GPU support
#
-CONFIG_MXC_GPU_VIV=m
+CONFIG_MXC_GPU_VIV=y
#
# ANATOP_THERMAL
@@ -2507,7 +2532,7 @@ CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_STRICT_DEVMEM is not set
CONFIG_ARM_UNWIND=y
# CONFIG_DEBUG_USER is not set
-# CONFIG_OC_ETM is not set
+CONFIG_OC_ETM=y
#
# Security options
diff --git a/arch/arm/configs/imx6s_updater_defconfig b/arch/arm/configs/imx6s_updater_defconfig
index 0bd3bcaac829..bd227b39c4e5 100644
--- a/arch/arm/configs/imx6s_updater_defconfig
+++ b/arch/arm/configs/imx6s_updater_defconfig
@@ -299,6 +299,7 @@ CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_DSI=y
CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_CSI2=y
CONFIG_IMX_HAVE_PLATFORM_IMX_VDOA=y
CONFIG_IMX_HAVE_PLATFORM_IMX_PCIE=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_FSL_CSI=y
#
# Freescale MXC Implementations
@@ -388,6 +389,7 @@ CONFIG_ARM_GIC=y
#
# Bus support
#
+CONFIG_ARM_AMBA=y
# CONFIG_PCI_SYSCALL is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCCARD is not set
@@ -1040,6 +1042,8 @@ CONFIG_DEVKMEM=y
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
# CONFIG_SERIAL_MAX3100 is not set
# CONFIG_SERIAL_MAX3107 is not set
CONFIG_SERIAL_IMX=y
@@ -1113,6 +1117,7 @@ CONFIG_SPI_BITBANG=y
CONFIG_SPI_IMX_VER_2_3=y
CONFIG_SPI_IMX=y
# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PL022 is not set
# CONFIG_SPI_PXA2XX_PCI is not set
# CONFIG_SPI_XILINX is not set
# CONFIG_SPI_DESIGNWARE is not set
@@ -1148,6 +1153,7 @@ CONFIG_GPIOLIB=y
#
# CONFIG_GPIO_BASIC_MMIO is not set
# CONFIG_GPIO_IT8761E is not set
+# CONFIG_GPIO_PL061 is not set
#
# I2C GPIO expanders:
@@ -1192,6 +1198,7 @@ CONFIG_POWER_SUPPLY=y
# CONFIG_BATTERY_MAX17042 is not set
# CONFIG_CHARGER_ISP1704 is not set
# CONFIG_CHARGER_MAX8903 is not set
+# CONFIG_SABRESD_MAX8903 is not set
# CONFIG_CHARGER_GPIO is not set
# CONFIG_HWMON is not set
CONFIG_THERMAL=y
@@ -1202,6 +1209,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y
# Watchdog Device Drivers
#
# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ARM_SP805_WATCHDOG is not set
# CONFIG_MAX63XX_WATCHDOG is not set
CONFIG_IMX2_WDT=y
@@ -1405,8 +1413,6 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y
# CONFIG_VIDEO_VIVI is not set
# CONFIG_VIDEO_MXC_CAMERA is not set
CONFIG_VIDEO_MXC_OUTPUT=y
-CONFIG_VIDEO_MXC_IPU_OUTPUT=y
-# CONFIG_VIDEO_MXC_IPUV1_WVGA_OUTPUT is not set
# CONFIG_VIDEO_MXC_PXP_V4L2 is not set
# CONFIG_VIDEO_MXC_OPL is not set
# CONFIG_VIDEO_CPIA2 is not set
@@ -1447,6 +1453,7 @@ CONFIG_FB_MODE_HELPERS=y
#
# Frame buffer hardware drivers
#
+# CONFIG_FB_ARMCLCD is not set
# CONFIG_FB_UVESA is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_TMIO is not set
@@ -1464,18 +1471,17 @@ CONFIG_FB_MXC=y
CONFIG_FB_MXC_EDID=y
CONFIG_FB_MXC_SYNC_PANEL=y
# CONFIG_FB_MXC_EPSON_VGA_SYNC_PANEL is not set
-CONFIG_FB_MXC_LDB=y
-# CONFIG_FB_MXC_MIPI_DSI is not set
# CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL is not set
# CONFIG_FB_MXC_SEIKO_WVGA_SYNC_PANEL is not set
# CONFIG_FB_MXC_SII902X is not set
+# CONFIG_FB_MXC_SII902X_ELCDIF is not set
# CONFIG_FB_MXC_CH7026 is not set
# CONFIG_FB_MXC_TVOUT_CH7024 is not set
# CONFIG_FB_MXC_ASYNC_PANEL is not set
# CONFIG_FB_MXC_EINK_PANEL is not set
# CONFIG_FB_MXC_SIPIX_PANEL is not set
# CONFIG_FB_MXC_ELCDIF_FB is not set
-CONFIG_FB_MXC_HDMI=y
+# CONFIG_FB_MXC_HDMI is not set
#
# Console display driver support
@@ -1526,6 +1532,7 @@ CONFIG_SND_DRIVERS=y
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 is not set
CONFIG_SND_ARM=y
+# CONFIG_SND_ARMAACI is not set
CONFIG_SND_SPI=y
CONFIG_SND_USB=y
# CONFIG_SND_USB_AUDIO is not set
@@ -1774,6 +1781,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
#
# MMC/SD/SDIO Host Controller Drivers
#
+# CONFIG_MMC_ARMMMCI is not set
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_IO_ACCESSORS=y
CONFIG_MMC_SDHCI_PLTFM=y
@@ -1859,12 +1867,15 @@ CONFIG_RTC_DRV_SNVS=y
#
# on-CPU RTC drivers
#
+# CONFIG_RTC_DRV_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
CONFIG_DMADEVICES=y
# CONFIG_DMADEVICES_DEBUG is not set
#
# DMA Devices
#
+# CONFIG_AMBA_PL08X is not set
# CONFIG_DW_DMAC is not set
# CONFIG_MXC_PXP_V2 is not set
# CONFIG_TIMB_DMA is not set
@@ -1917,9 +1928,7 @@ CONFIG_CLKSRC_MMIO=y
#
# MXC support drivers
#
-CONFIG_MXC_IPU=y
-CONFIG_MXC_IPU_V3=y
-CONFIG_MXC_IPU_V3H=y
+# CONFIG_MXC_IPU is not set
#
# MXC SSI support
@@ -2234,7 +2243,7 @@ CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_STRICT_DEVMEM is not set
CONFIG_ARM_UNWIND=y
# CONFIG_DEBUG_USER is not set
-# CONFIG_OC_ETM is not set
+CONFIG_OC_ETM=y
#
# Security options
diff --git a/arch/arm/include/asm/hardware/coresight.h b/arch/arm/include/asm/hardware/coresight.h
index 6643d6c4f35e..0b21c331bb04 100644
--- a/arch/arm/include/asm/hardware/coresight.h
+++ b/arch/arm/include/asm/hardware/coresight.h
@@ -18,10 +18,16 @@
#define TRACER_RUNNING_BIT 1
#define TRACER_CYCLE_ACC_BIT 2
#define TRACER_TRACE_DATA_BIT 3
+#define TRACER_TIMESTAMP_BIT 4
+#define TRACER_BRANCHOUTPUT_BIT 5
+#define TRACER_RETURN_STACK_BIT 6
#define TRACER_ACCESSED BIT(TRACER_ACCESSED_BIT)
#define TRACER_RUNNING BIT(TRACER_RUNNING_BIT)
#define TRACER_CYCLE_ACC BIT(TRACER_CYCLE_ACC_BIT)
#define TRACER_TRACE_DATA BIT(TRACER_TRACE_DATA_BIT)
+#define TRACER_TIMESTAMP BIT(TRACER_TIMESTAMP_BIT)
+#define TRACER_BRANCHOUTPUT BIT(TRACER_BRANCHOUTPUT_BIT)
+#define TRACER_RETURN_STACK BIT(TRACER_RETURN_STACK_BIT)
#define TRACER_TIMEOUT 10000
@@ -45,7 +51,7 @@
#define ETMCTRL_POWERDOWN 1
#define ETMCTRL_PROGRAM (1 << 10)
#define ETMCTRL_PORTSEL (1 << 11)
-#define ETMCTRL_DO_CONTEXTID (3 << 14)
+#define ETMCTRL_CONTEXTIDSIZE(x) (((x) & 3) << 14)
#define ETMCTRL_PORTMASK1 (7 << 4)
#define ETMCTRL_PORTMASK2 (1 << 21)
#define ETMCTRL_PORTMASK (ETMCTRL_PORTMASK1 | ETMCTRL_PORTMASK2)
@@ -57,9 +63,12 @@
#define ETMCTRL_DATA_DO_BOTH (ETMCTRL_DATA_DO_DATA | ETMCTRL_DATA_DO_ADDR)
#define ETMCTRL_BRANCH_OUTPUT (1 << 8)
#define ETMCTRL_CYCLEACCURATE (1 << 12)
+#define ETMCTRL_TIMESTAMP_EN (1 << 28)
+#define ETMCTRL_RETURN_STACK_EN (1 << 29)
/* ETM configuration code register */
#define ETMR_CONFCODE (0x04)
+#define ETMCCR_ETMIDR_PRESENT BIT(31)
/* ETM trace start/stop resource control register */
#define ETMR_TRACESSCTRL (0x18)
@@ -122,9 +131,18 @@
#define ETMR_VIEWDATACTRL3 0x3c
#define ETMVDC3_EXCLONLY BIT(16)
-#define ETMCTRL_OPTS (ETMCTRL_DO_CPRT | \
- ETMCTRL_BRANCH_OUTPUT | \
- ETMCTRL_DO_CONTEXTID)
+#define ETMCTRL_OPTS (ETMCTRL_DO_CPRT)
+
+#define ETMR_ID 0x1e4
+#define ETMIDR_VERSION(x) (((x) >> 4) & 0xff)
+#define ETMIDR_VERSION_3_1 0x21
+#define ETMIDR_VERSION_PFT_1_0 0x30
+
+#define ETMR_CCE 0x1e8
+#define ETMCCER_RETURN_STACK_IMPLEMENTED BIT(23)
+#define ETMCCER_TIMESTAMPING_IMPLEMENTED BIT(22)
+
+#define ETMR_TRACEIDR 0x200
#define ETMR_TRACEIDR 0x200
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index 496b8b84e455..93d06ba0fb60 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -42,6 +42,7 @@ struct tracectx {
unsigned long flags;
int ncmppairs;
int etm_portsz;
+ int etm_contextid_size;
u32 etb_fc;
unsigned long range_start;
unsigned long range_end;
@@ -108,13 +109,23 @@ static int trace_start_etm(struct tracectx *t, int id)
unsigned long timeout = TRACER_TIMEOUT;
v = ETMCTRL_OPTS | ETMCTRL_PROGRAM | ETMCTRL_PORTSIZE(t->etm_portsz);
+ v |= ETMCTRL_CONTEXTIDSIZE(t->etm_contextid_size);
if (t->flags & TRACER_CYCLE_ACC)
v |= ETMCTRL_CYCLEACCURATE;
+ if (t->flags & TRACER_BRANCHOUTPUT)
+ v |= ETMCTRL_BRANCH_OUTPUT;
+
if (t->flags & TRACER_TRACE_DATA)
v |= ETMCTRL_DATA_DO_ADDR;
+ if (t->flags & TRACER_TIMESTAMP)
+ v |= ETMCTRL_TIMESTAMP_EN;
+
+ if (t->flags & TRACER_RETURN_STACK)
+ v |= ETMCTRL_RETURN_STACK_EN;
+
etm_unlock(t, id);
etm_writel(t, id, v, ETMR_CTRL);
@@ -199,15 +210,36 @@ static int trace_stop_etm(struct tracectx *t, int id)
etm_unlock(t, id);
- etm_writel(t, id, 0x441, ETMR_CTRL);
+ etm_writel(t, id, 0x440, ETMR_CTRL);
while (!(etm_readl(t, id, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
;
if (!timeout) {
- dev_dbg(t->dev, "Waiting for progbit to assert timed out\n");
+ dev_err(t->dev,
+ "etm%d: Waiting for progbit to assert timed out\n",
+ id);
+ etm_lock(t, id);
+ return -EFAULT;
+ }
+
+ etm_lock(t, id);
+ return 0;
+}
+
+static int trace_power_down_etm(struct tracectx *t, int id)
+{
+ unsigned long timeout = TRACER_TIMEOUT;
+ etm_unlock(t, id);
+ while (!(etm_readl(t, id, ETMR_STATUS) & ETMST_PROGBIT) && --timeout)
+ ;
+ if (!timeout) {
+ dev_err(t->dev, "etm%d: Waiting for status progbit to assert timed out\n",
+ id);
etm_lock(t, id);
return -EFAULT;
}
+ etm_writel(t, id, 0x441, ETMR_CTRL);
+
etm_lock(t, id);
return 0;
}
@@ -215,15 +247,14 @@ static int trace_stop_etm(struct tracectx *t, int id)
static int trace_stop(struct tracectx *t)
{
int id;
- int ret;
unsigned long timeout = TRACER_TIMEOUT;
u32 etb_fc = t->etb_fc;
- for (id = 0; id < t->etm_regs_count; id++) {
- ret = trace_stop_etm(t, id);
- if (ret)
- return ret;
- }
+ for (id = 0; id < t->etm_regs_count; id++)
+ trace_stop_etm(t, id);
+
+ for (id = 0; id < t->etm_regs_count; id++)
+ trace_power_down_etm(t, id);
etb_unlock(t);
if (etb_fc) {
@@ -626,6 +657,133 @@ static ssize_t trace_mode_store(struct kobject *kobj,
static struct kobj_attribute trace_mode_attr =
__ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store);
+static ssize_t trace_contextid_size_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ /* 0: No context id tracing, 1: One byte, 2: Two bytes, 3: Four bytes */
+ return sprintf(buf, "%d\n", (1 << tracer.etm_contextid_size) >> 1);
+}
+
+static ssize_t trace_contextid_size_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
+ unsigned int contextid_size;
+
+ if (sscanf(buf, "%u", &contextid_size) != 1)
+ return -EINVAL;
+
+ if (contextid_size == 3 || contextid_size > 4)
+ return -EINVAL;
+
+ mutex_lock(&tracer.mutex);
+ tracer.etm_contextid_size = fls(contextid_size);
+ mutex_unlock(&tracer.mutex);
+
+ return n;
+}
+
+static struct kobj_attribute trace_contextid_size_attr =
+ __ATTR(trace_contextid_size, 0644,
+ trace_contextid_size_show, trace_contextid_size_store);
+
+static ssize_t trace_branch_output_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", !!(tracer.flags & TRACER_BRANCHOUTPUT));
+}
+
+static ssize_t trace_branch_output_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
+ unsigned int branch_output;
+
+ if (sscanf(buf, "%u", &branch_output) != 1)
+ return -EINVAL;
+
+ mutex_lock(&tracer.mutex);
+ if (branch_output) {
+ tracer.flags |= TRACER_BRANCHOUTPUT;
+ /* Branch broadcasting is incompatible with the return stack */
+ tracer.flags &= ~TRACER_RETURN_STACK;
+ } else {
+ tracer.flags &= ~TRACER_BRANCHOUTPUT;
+ }
+ mutex_unlock(&tracer.mutex);
+
+ return n;
+}
+
+static struct kobj_attribute trace_branch_output_attr =
+ __ATTR(trace_branch_output, 0644,
+ trace_branch_output_show, trace_branch_output_store);
+
+static ssize_t trace_return_stack_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", !!(tracer.flags & TRACER_RETURN_STACK));
+}
+
+static ssize_t trace_return_stack_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
+ unsigned int return_stack;
+
+ if (sscanf(buf, "%u", &return_stack) != 1)
+ return -EINVAL;
+
+ mutex_lock(&tracer.mutex);
+ if (return_stack) {
+ tracer.flags |= TRACER_RETURN_STACK;
+ /* Return stack is incompatible with branch broadcasting */
+ tracer.flags &= ~TRACER_BRANCHOUTPUT;
+ } else {
+ tracer.flags &= ~TRACER_RETURN_STACK;
+ }
+ mutex_unlock(&tracer.mutex);
+
+ return n;
+}
+
+static struct kobj_attribute trace_return_stack_attr =
+ __ATTR(trace_return_stack, 0644,
+ trace_return_stack_show, trace_return_stack_store);
+
+static ssize_t trace_timestamp_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", !!(tracer.flags & TRACER_TIMESTAMP));
+}
+
+static ssize_t trace_timestamp_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
+ unsigned int timestamp;
+
+ if (sscanf(buf, "%u", &timestamp) != 1)
+ return -EINVAL;
+
+ mutex_lock(&tracer.mutex);
+ if (timestamp)
+ tracer.flags |= TRACER_TIMESTAMP;
+ else
+ tracer.flags &= ~TRACER_TIMESTAMP;
+ mutex_unlock(&tracer.mutex);
+
+ return n;
+}
+
+static struct kobj_attribute trace_timestamp_attr =
+ __ATTR(trace_timestamp, 0644,
+ trace_timestamp_show, trace_timestamp_store);
+
static ssize_t trace_range_show(struct kobject *kobj,
struct kobj_attribute *attr,
char *buf)
@@ -703,6 +861,10 @@ static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id
int ret = 0;
void __iomem **new_regs;
int new_count;
+ u32 etmccr;
+ u32 etmidr;
+ u32 etmccer = 0;
+ u8 etm_version = 0;
mutex_lock(&t->mutex);
new_count = t->etm_regs_count + 1;
@@ -729,15 +891,23 @@ static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id
amba_set_drvdata(dev, t->etm_regs[t->etm_regs_count]);
- t->flags = TRACER_CYCLE_ACC | TRACER_TRACE_DATA;
+ t->flags = TRACER_CYCLE_ACC | TRACER_TRACE_DATA | TRACER_BRANCHOUTPUT;
t->etm_portsz = 1;
+ t->etm_contextid_size = 3;
etm_unlock(t, t->etm_regs_count);
(void)etm_readl(t, t->etm_regs_count, ETMMR_PDSR);
/* dummy first read */
(void)etm_readl(&tracer, t->etm_regs_count, ETMMR_OSSRR);
- t->ncmppairs = etm_readl(t, t->etm_regs_count, ETMR_CONFCODE) & 0xf;
+ etmccr = etm_readl(t, t->etm_regs_count, ETMR_CONFCODE);
+ t->ncmppairs = etmccr & 0xf;
+ if (etmccr & ETMCCR_ETMIDR_PRESENT) {
+ etmidr = etm_readl(t, t->etm_regs_count, ETMR_ID);
+ etm_version = ETMIDR_VERSION(etmidr);
+ if (etm_version >= ETMIDR_VERSION_3_1)
+ etmccer = etm_readl(t, t->etm_regs_count, ETMR_CCE);
+ }
etm_writel(t, t->etm_regs_count, 0x441, ETMR_CTRL);
etm_writel(t, t->etm_regs_count, new_count, ETMR_TRACEIDR);
etm_lock(t, t->etm_regs_count);
@@ -756,14 +926,47 @@ static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id
if (ret)
dev_dbg(&dev->dev, "Failed to create trace_mode in sysfs\n");
- ret = sysfs_create_file(&dev->dev.kobj, &trace_range_attr.attr);
+ ret = sysfs_create_file(&dev->dev.kobj,
+ &trace_contextid_size_attr.attr);
if (ret)
- dev_dbg(&dev->dev, "Failed to create trace_range in sysfs\n");
+ dev_dbg(&dev->dev,
+ "Failed to create trace_contextid_size in sysfs\n");
- ret = sysfs_create_file(&dev->dev.kobj, &trace_data_range_attr.attr);
+ ret = sysfs_create_file(&dev->dev.kobj,
+ &trace_branch_output_attr.attr);
if (ret)
dev_dbg(&dev->dev,
- "Failed to create trace_data_range in sysfs\n");
+ "Failed to create trace_branch_output in sysfs\n");
+
+ if (etmccer & ETMCCER_RETURN_STACK_IMPLEMENTED) {
+ ret = sysfs_create_file(&dev->dev.kobj,
+ &trace_return_stack_attr.attr);
+ if (ret)
+ dev_dbg(&dev->dev,
+ "Failed to create trace_return_stack in sysfs\n");
+ }
+
+ if (etmccer & ETMCCER_TIMESTAMPING_IMPLEMENTED) {
+ ret = sysfs_create_file(&dev->dev.kobj,
+ &trace_timestamp_attr.attr);
+ if (ret)
+ dev_dbg(&dev->dev,
+ "Failed to create trace_timestamp in sysfs\n");
+ }
+
+ ret = sysfs_create_file(&dev->dev.kobj, &trace_range_attr.attr);
+ if (ret)
+ dev_dbg(&dev->dev, "Failed to create trace_range in sysfs\n");
+
+ if (etm_version < ETMIDR_VERSION_PFT_1_0) {
+ ret = sysfs_create_file(&dev->dev.kobj,
+ &trace_data_range_attr.attr);
+ if (ret)
+ dev_dbg(&dev->dev,
+ "Failed to create trace_data_range in sysfs\n");
+ } else {
+ tracer.flags &= ~TRACER_TRACE_DATA;
+ }
dev_dbg(&dev->dev, "ETM AMBA driver initialized.\n");
diff --git a/arch/arm/mach-mx5/devices-imx50.h b/arch/arm/mach-mx5/devices-imx50.h
index bdaf32213c21..8cba79c489ec 100755
--- a/arch/arm/mach-mx5/devices-imx50.h
+++ b/arch/arm/mach-mx5/devices-imx50.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.
*/
/*
@@ -29,8 +29,8 @@ extern const struct imx_srtc_data imx50_imx_srtc_data __initconst;
#define imx50_add_srtc() \
imx_add_srtc(&imx50_imx_srtc_data)
-extern const struct imx_dma_data imx50_dma_data __initconst;
-#define imx50_add_dma() imx_add_dma(&imx50_dma_data);
+extern const struct imx_dma_res_data imx50_dma_res_data __initconst;
+#define imx50_add_dma() imx_add_dma(&imx50_dma_res_data);
extern const struct imx_fec_data imx50_fec_data;
#define imx50_add_fec(pdata) \
diff --git a/arch/arm/mach-mx6/Kconfig b/arch/arm/mach-mx6/Kconfig
index d50f1a795a09..97262dced063 100644
--- a/arch/arm/mach-mx6/Kconfig
+++ b/arch/arm/mach-mx6/Kconfig
@@ -7,6 +7,7 @@ config ARCH_MX6Q
select ARCH_MXC_AUDMUX_V2
select ARM_GIC
select ARCH_HAS_CPUFREQ
+ select OC_ETM
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_FEC
select IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL
@@ -136,6 +137,7 @@ config MACH_MX6SL_EVK
select IMX_HAVE_PLATFORM_IMX_EPDC
select IMX_HAVE_PLATFORM_IMX_SPDC
select IMX_HAVE_PLATFORM_IMX_PXP
+ select IMX_HAVE_PLATFORM_IMX_FSL_CSI
select IMX_HAVE_PLATFORM_IMX_KEYPAD
select IMX_HAVE_PLATFORM_IMX_DCP
select IMX_HAVE_PLATFORM_RANDOM_RNGC
diff --git a/arch/arm/mach-mx6/Makefile b/arch/arm/mach-mx6/Makefile
index 49b5f86a6920..05dc62dac468 100644
--- a/arch/arm/mach-mx6/Makefile
+++ b/arch/arm/mach-mx6/Makefile
@@ -5,7 +5,7 @@
# Object file lists.
obj-y := cpu.o mm.o system.o devices.o dummy_gpio.o irq.o bus_freq.o usb_dr.o usb_h2.o usb_h3.o\
pm.o cpu_op-mx6.o mx6_wfi.o mx6_fec.o mx6_anatop_regulator.o cpu_regulator-mx6.o \
-mx6_mmdc.o mx6_ddr_freq.o mx6sl_ddr.o mx6sl_wfi.o
+mx6_mmdc.o mx6_ddr_freq.o mx6sl_ddr.o mx6sl_wfi.o etm.o
obj-$(CONFIG_ARCH_MX6) += clock.o mx6_suspend.o clock_mx6sl.o
obj-$(CONFIG_MACH_MX6Q_ARM2) += board-mx6q_arm2.o
diff --git a/arch/arm/mach-mx6/board-mx6q_sabreauto.c b/arch/arm/mach-mx6/board-mx6q_sabreauto.c
index 5175db4350cf..c4d233b60d88 100644
--- a/arch/arm/mach-mx6/board-mx6q_sabreauto.c
+++ b/arch/arm/mach-mx6/board-mx6q_sabreauto.c
@@ -30,11 +30,8 @@
#include <linux/fsl_devices.h>
#include <linux/smsc911x.h>
#include <linux/spi/spi.h>
-#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
#include <linux/spi/flash.h>
-#else
#include <linux/mtd/physmap.h>
-#endif
#include <linux/i2c.h>
#include <linux/i2c/pca953x.h>
#include <linux/ata.h>
@@ -99,11 +96,11 @@
#define SABREAUTO_ANDROID_MENU IMX_GPIO_NR(2, 12)
#define SABREAUTO_ANDROID_VOLUP IMX_GPIO_NR(2, 15)
#define SABREAUTO_CAP_TCH_INT IMX_GPIO_NR(2, 28)
+#define SABREAUTO_eCOMPASS_INT IMX_GPIO_NR(2, 29)
#define SABREAUTO_ECSPI1_CS1 IMX_GPIO_NR(3, 19)
#define SABREAUTO_DISP0_PWR IMX_GPIO_NR(3, 24)
#define SABREAUTO_DISP0_I2C_EN IMX_GPIO_NR(3, 28)
#define SABREAUTO_DISP0_DET_INT IMX_GPIO_NR(3, 31)
-#define SABREAUTO_CSI0_RST IMX_GPIO_NR(4, 5)
#define SABREAUTO_DISP0_RESET IMX_GPIO_NR(5, 0)
#define SABREAUTO_I2C3_STEER IMX_GPIO_NR(5, 4)
#define SABREAUTO_WEIM_NOR_WDOG1 IMX_GPIO_NR(4, 29)
@@ -111,7 +108,6 @@
#define SABREAUTO_PMIC_INT IMX_GPIO_NR(5, 16)
#define SABREAUTO_ALS_INT IMX_GPIO_NR(5, 17)
#define SABREAUTO_SD1_WP IMX_GPIO_NR(5, 20)
-#define SABREAUTO_CSI0_PWN IMX_GPIO_NR(5, 23)
#define SABREAUTO_USB_HOST1_OC IMX_GPIO_NR(5, 0)
#define SABREAUTO_SD3_CD IMX_GPIO_NR(6, 15)
@@ -142,6 +138,7 @@ extern char *soc_reg_id;
extern char *pu_reg_id;
static int mma8451_position = 3;
+static int mag3110_position = 2;
static struct clk *sata_clk;
static int mipi_sensor;
static int can0_enable;
@@ -402,7 +399,6 @@ static const struct spi_imx_master mx6q_sabreauto_spi_data __initconst = {
.num_chipselect = ARRAY_SIZE(mx6q_sabreauto_spi_cs),
};
-#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
static struct mtd_partition m25p32_partitions[] = {
{
.name = "bootloader",
@@ -423,7 +419,6 @@ static struct flash_platform_data m25p32_spi_flash_data = {
};
static struct spi_board_info m25p32_spi0_board_info[] __initdata = {
-#if defined(CONFIG_MTD_M25P80)
{
/* The modalias must be the same as spi device driver name */
.modalias = "m25p80",
@@ -432,14 +427,12 @@ static struct spi_board_info m25p32_spi0_board_info[] __initdata = {
.chip_select = 0,
.platform_data = &m25p32_spi_flash_data,
},
-#endif
};
static void spi_device_init(void)
{
spi_register_board_info(m25p32_spi0_board_info,
ARRAY_SIZE(m25p32_spi0_board_info));
}
-#else
static struct mtd_partition mxc_nor_partitions[] = {
{
.name = "Bootloader",
@@ -489,7 +482,6 @@ static void mx6q_setup_weimcs(void)
__raw_writel(0x1C022000, nor_reg + 0x00000008);
__raw_writel(0x0804a240, nor_reg + 0x00000010);
}
-#endif
static int max7310_1_setup(struct i2c_client *client,
unsigned gpio_base, unsigned ngpio,
@@ -603,18 +595,6 @@ static struct pca953x_platform_data max7310_u43_platdata = {
.setup = max7310_u43_setup,
};
-static struct fsl_mxc_camera_platform_data camera_data = {
- .analog_regulator = "DA9052_LDO7",
- .core_regulator = "DA9052_LDO9",
- .mclk = 24000000,
- .csi = 0,
-};
-
-static struct fsl_mxc_camera_platform_data ov5640_mipi_data = {
- .mclk = 24000000,
- .csi = 0,
-};
-
static void adv7180_pwdn(int pwdn)
{
int status = -1;
@@ -629,6 +609,14 @@ static void adv7180_pwdn(int pwdn)
gpio_free(SABREAUTO_VIDEOIN_PWR);
}
+static void mx6q_csi0_io_init(void)
+{
+ if (cpu_is_mx6q())
+ mxc_iomux_set_gpr_register(1, 19, 1, 1);
+ else if (cpu_is_mx6dl())
+ mxc_iomux_set_gpr_register(13, 0, 3, 4);
+}
+
static struct fsl_mxc_tvin_platform_data adv7180_data = {
.dvddio_reg = NULL,
.dvdd_reg = NULL,
@@ -637,6 +625,16 @@ static struct fsl_mxc_tvin_platform_data adv7180_data = {
.pwdn = adv7180_pwdn,
.reset = NULL,
.cvbs = true,
+ .io_init = mx6q_csi0_io_init,
+};
+
+static struct fsl_mxc_tvin_platform_data adv7280_data = {
+ .dvddio_reg = NULL,
+ .dvdd_reg = NULL,
+ .avdd_reg = NULL,
+ .pvdd_reg = NULL,
+ .pwdn = NULL,
+ .cvbs = true,
};
static struct imxi2c_platform_data mx6q_sabreauto_i2c2_data = {
@@ -672,15 +670,16 @@ static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
I2C_BOARD_INFO("adv7180", 0x21),
.platform_data = (void *)&adv7180_data,
}, {
- I2C_BOARD_INFO("ov3640", 0x3c),
- .platform_data = (void *)&camera_data,
- },
- {
I2C_BOARD_INFO("isl29023", 0x44),
.irq = gpio_to_irq(SABREAUTO_ALS_INT),
.platform_data = &ls_data,
},
{
+ I2C_BOARD_INFO("mag3110", 0x0e),
+ .irq = gpio_to_irq(SABREAUTO_eCOMPASS_INT),
+ .platform_data = (void *)&mag3110_position,
+ },
+ {
I2C_BOARD_INFO("mma8451", 0x1c),
.platform_data = (void *)&mma8451_position,
},
@@ -693,17 +692,16 @@ static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
}, {
I2C_BOARD_INFO("mxc_hdmi_i2c", 0x50),
}, {
- I2C_BOARD_INFO("ov5640_mipi", 0x3c),
- .platform_data = (void *)&ov5640_mipi_data,
- }, {
I2C_BOARD_INFO("cs42888", 0x48),
.platform_data = (void *)&cs42888_data,
- },
- {
+ }, {
I2C_BOARD_INFO("si4763_i2c", 0x63),
+ }, {
+ I2C_BOARD_INFO("adv7280", 0x21),
+ .platform_data = (void *)&adv7280_data,
},
-
};
+
struct platform_device mxc_si4763_audio_device = {
.name = "imx-tuner-si4763",
.id = 0,
@@ -1329,24 +1327,6 @@ static int __init early_enable_can0(char *p)
}
early_param("can0", early_enable_can0);
-static inline void __init mx6q_csi0_io_init(void)
-{
- /* Camera reset */
- gpio_request(SABREAUTO_CSI0_RST, "cam-reset");
- gpio_direction_output(SABREAUTO_CSI0_RST, 1);
-
- /* Camera power down */
- gpio_request(SABREAUTO_CSI0_PWN, "cam-pwdn");
- gpio_direction_output(SABREAUTO_CSI0_PWN, 1);
- msleep(1);
- gpio_set_value(SABREAUTO_CSI0_PWN, 0);
-
- if (cpu_is_mx6q())
- mxc_iomux_set_gpr_register(1, 19, 1, 1);
- else if (cpu_is_mx6dl())
- mxc_iomux_set_gpr_register(13, 0, 3, 4);
-}
-
static struct mxc_spdif_platform_data mxc_spdif_data = {
.spdif_tx = 0, /* disable tx */
.spdif_rx = 1, /* enable rx */
@@ -1586,12 +1566,12 @@ static void __init mx6_board_init(void)
}
/* SPI */
imx6q_add_ecspi(0, &mx6q_sabreauto_spi_data);
-#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
- spi_device_init();
-#else
- mx6q_setup_weimcs();
- platform_device_register(&physmap_flash_device);
-#endif
+ if (spinor_en)
+ spi_device_init();
+ else if (weimnor_en) {
+ mx6q_setup_weimcs();
+ platform_device_register(&physmap_flash_device);
+ }
imx6q_add_mxc_hdmi(&hdmi_data);
imx6q_add_anatop_thermal_imx(1, &mx6q_sabreauto_anatop_thermal_data);
@@ -1616,9 +1596,6 @@ static void __init mx6_board_init(void)
imx_asrc_data.asrc_audio_clk = clk_get(NULL, "asrc_serial_clk");
imx6q_add_asrc(&imx_asrc_data);
- if (!mipi_sensor)
- mx6q_csi0_io_init();
-
/* DISP0 Detect */
gpio_request(SABREAUTO_DISP0_DET_INT, "disp0-detect");
gpio_direction_input(SABREAUTO_DISP0_DET_INT);
@@ -1642,7 +1619,7 @@ static void __init mx6_board_init(void)
imx6q_add_viim();
imx6q_add_imx2_wdt(0, NULL);
imx6q_add_dma();
- if (!uart3_en)
+ if (!uart3_en && !weimnor_en)
imx6q_add_gpmi(&mx6q_gpmi_nand_platform_data);
imx6q_add_dvfs_core(&sabreauto_dvfscore_data);
diff --git a/arch/arm/mach-mx6/board-mx6q_sabreauto.h b/arch/arm/mach-mx6/board-mx6q_sabreauto.h
index c087de6fb789..88cb7ff7456f 100644
--- a/arch/arm/mach-mx6/board-mx6q_sabreauto.h
+++ b/arch/arm/mach-mx6/board-mx6q_sabreauto.h
@@ -172,6 +172,9 @@ static iomux_v3_cfg_t mx6q_sabreauto_pads[] = {
/* DISP0 RESET */
MX6Q_PAD_EIM_WAIT__GPIO_5_0,
+ /* eCompass int */
+ MX6Q_PAD_EIM_EB1__GPIO_2_29,
+
/* SPDIF */
MX6Q_PAD_KEY_COL3__SPDIF_IN1,
@@ -207,10 +210,6 @@ static iomux_v3_cfg_t mx6q_sabreauto_pads[] = {
/* HDMI */
MX6Q_PAD_EIM_A25__HDMI_TX_CEC_LINE,
- /* camera reset */
- MX6Q_PAD_GPIO_19__GPIO_4_5,
- MX6Q_PAD_EIM_D24__GPIO_3_24,
-
/* MLB150 */
MX6Q_PAD_ENET_TXD1__MLB_MLBCLK,
MX6Q_PAD_GPIO_6__MLB_MLBSIG,
diff --git a/arch/arm/mach-mx6/board-mx6sl_arm2.c b/arch/arm/mach-mx6/board-mx6sl_arm2.c
index 419b2447e215..2959d0de6263 100755
--- a/arch/arm/mach-mx6/board-mx6sl_arm2.c
+++ b/arch/arm/mach-mx6/board-mx6sl_arm2.c
@@ -610,7 +610,7 @@ static struct mxc_dvfs_platform_data mx6sl_arm2_dvfscore_data = {
};
static struct viv_gpu_platform_data imx6q_gpu_pdata __initdata = {
- .reserved_mem_size = SZ_128M,
+ .reserved_mem_size = SZ_32M,
};
void __init early_console_setup(unsigned long base, struct clk *clk);
diff --git a/arch/arm/mach-mx6/board-mx6sl_common.h b/arch/arm/mach-mx6/board-mx6sl_common.h
index d005e02cb6ac..c432e0a661ba 100644
--- a/arch/arm/mach-mx6/board-mx6sl_common.h
+++ b/arch/arm/mach-mx6/board-mx6sl_common.h
@@ -20,6 +20,8 @@
#define _BOARD_MX6SL_COMMON_H
#include <mach/iomux-mx6sl.h>
+#define MX6_BRD_LCD_RESET IMX_GPIO_NR(2, 19) /* LCD_REST */
+
#define MX6_BRD_USBOTG1_PWR IMX_GPIO_NR(4, 0) /* KEY_COL4 */
#define MX6_BRD_USBOTG2_PWR IMX_GPIO_NR(4, 2) /* KEY_COL5 */
#define MX6_BRD_LCD_PWR_EN IMX_GPIO_NR(4, 3) /* KEY_ROW5 */
@@ -31,6 +33,10 @@
#define MX6_BRD_SD2_CD IMX_GPIO_NR(5, 0) /* SD2_DAT7 */
#define MX6_BRD_SD3_CD IMX_GPIO_NR(3, 22) /* REF_CLK_32K */
#define MX6_BRD_FEC_PWR_EN IMX_GPIO_NR(4, 21) /* FEC_TX_CLK */
+#define MX6_BRD_CHG_FLT IMX_GPIO_NR(4, 14) /* ECSPI2_MISO */
+#define MX6_BRD_CHG_UOK IMX_GPIO_NR(4, 13) /* ECSPI2_MOSI */
+#define MX6_BRD_CHG_DOK IMX_GPIO_NR(4, 13) /* ECSPI2_MOSI */
+#define MX6_BRD_CHG_STATUS IMX_GPIO_NR(4, 15) /* ECSPI2_SS0 */
/* EPDC GPIO pins */
#define MX6SL_BRD_EPDC_SDDO_0 IMX_GPIO_NR(1, 7)
@@ -76,6 +82,9 @@
#define MX6SL_BRD_ELAN_CE IMX_GPIO_NR(2, 9)
#define MX6SL_BRD_ELAN_INT IMX_GPIO_NR(2, 10)
#define MX6SL_BRD_ELAN_RST IMX_GPIO_NR(4, 4)
+/* CSI */
+#define MX6SL_BRD_CSI_PWDN IMX_GPIO_NR(1, 25)
+#define MX6SL_BRD_CSI_RST IMX_GPIO_NR(1, 26)
static iomux_v3_cfg_t mx6sl_brd_pads[] = {
@@ -89,6 +98,9 @@ static iomux_v3_cfg_t mx6sl_brd_pads[] = {
/* Audio Codec */
MX6SL_PAD_FEC_RX_ER__GPIO_4_19, /* HEADPHONE_DET */
+ /* SPDIF TX */
+ MX6SL_PAD_SD2_DAT4__SPDIF_OUT1,
+
/* UART1 */
MX6SL_PAD_UART1_RXD__UART1_RXD,
MX6SL_PAD_UART1_TXD__UART1_TXD,
@@ -213,6 +225,11 @@ static iomux_v3_cfg_t mx6sl_brd_pads[] = {
/* WDOG */
MX6SL_PAD_WDOG_B__WDOG1_WDOG_B,
+
+ /* Charge */
+ MX6SL_PAD_ECSPI2_MISO__GPIO_4_14, /* CHG_FLT */
+ MX6SL_PAD_ECSPI2_SS0__GPIO_4_15, /* CHG_STATUS */
+ MX6SL_PAD_ECSPI2_MOSI__GPIO_4_13, /* CHG_UOK ,CHG_DOK*/
};
static iomux_v3_cfg_t mx6sl_brd_epdc_enable_pads[] = {
diff --git a/arch/arm/mach-mx6/board-mx6sl_evk.c b/arch/arm/mach-mx6/board-mx6sl_evk.c
index 81654a0c99fd..4c9c4d36e740 100644
--- a/arch/arm/mach-mx6/board-mx6sl_evk.c
+++ b/arch/arm/mach-mx6/board-mx6sl_evk.c
@@ -52,6 +52,7 @@
#include <linux/mfd/max17135.h>
#include <sound/wm8962.h>
#include <sound/pcm.h>
+#include <linux/power/sabresd_battery.h>
#include <mach/common.h>
#include <mach/hardware.h>
@@ -83,12 +84,51 @@ extern char *soc_reg_id;
extern char *pu_reg_id;
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,
SD_PAD_MODE_HIGH_SPEED,
};
+static int __init csi_setup(char *__unused)
+{
+ csi_enabled = 1;
+ return 1;
+}
+__setup("csi", csi_setup);
+
static int plt_sd_pad_change(unsigned int index, int clock)
{
/* LOW speed is the default state of SD pads */
@@ -556,6 +596,115 @@ static int __init imx6q_init_audio(void)
return 0;
}
+static int spdif_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long rate_actual;
+ rate_actual = clk_round_rate(clk, rate);
+ clk_set_rate(clk, rate_actual);
+ return 0;
+}
+
+static struct mxc_spdif_platform_data mxc_spdif_data = {
+ .spdif_tx = 1,
+ .spdif_rx = 0,
+ .spdif_clk_44100 = 1,
+ .spdif_clk_48000 = -1,
+ .spdif_div_44100 = 23,
+ .spdif_clk_set_rate = spdif_clk_set_rate,
+ .spdif_clk = NULL,
+};
+
+int hdmi_enabled;
+static int __init hdmi_setup(char *__unused)
+{
+ hdmi_enabled = 1;
+ return 1;
+}
+__setup("hdmi", hdmi_setup);
+
+static iomux_v3_cfg_t mx6sl_sii902x_hdmi_pads_enabled[] = {
+ MX6SL_PAD_LCD_RESET__GPIO_2_19,
+ MX6SL_PAD_EPDC_PWRCTRL3__GPIO_2_10,
+};
+
+static int sii902x_get_pins(void)
+{
+ /* Sii902x HDMI controller */
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_sii902x_hdmi_pads_enabled, \
+ ARRAY_SIZE(mx6sl_sii902x_hdmi_pads_enabled));
+
+ /* Reset Pin */
+ gpio_request(MX6_BRD_LCD_RESET, "disp0-reset");
+ gpio_direction_output(MX6_BRD_LCD_RESET, 1);
+
+ /* Interrupter pin GPIO */
+ gpio_request(MX6SL_BRD_EPDC_PWRCTRL3, "disp0-detect");
+ gpio_direction_input(MX6SL_BRD_EPDC_PWRCTRL3);
+ return 1;
+}
+
+static void sii902x_put_pins(void)
+{
+ gpio_free(MX6_BRD_LCD_RESET);
+ gpio_free(MX6SL_BRD_EPDC_PWRCTRL3);
+}
+
+static void sii902x_hdmi_reset(void)
+{
+ gpio_set_value(MX6_BRD_LCD_RESET, 0);
+ msleep(10);
+ gpio_set_value(MX6_BRD_LCD_RESET, 1);
+ msleep(10);
+}
+
+static struct fsl_mxc_lcd_platform_data sii902x_hdmi_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .reset = sii902x_hdmi_reset,
+ .get_pins = sii902x_get_pins,
+ .put_pins = sii902x_put_pins,
+};
+
+static void mx6sl_csi_io_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_csi_enable_pads, \
+ ARRAY_SIZE(mx6sl_brd_csi_enable_pads));
+
+ /* Camera reset */
+ gpio_request(MX6SL_BRD_CSI_RST, "cam-reset");
+ gpio_direction_output(MX6SL_BRD_CSI_RST, 1);
+
+ /* Camera power down */
+ gpio_request(MX6SL_BRD_CSI_PWDN, "cam-pwdn");
+ gpio_direction_output(MX6SL_BRD_CSI_PWDN, 1);
+ msleep(5);
+ gpio_set_value(MX6SL_BRD_CSI_PWDN, 0);
+ msleep(5);
+ gpio_set_value(MX6SL_BRD_CSI_RST, 0);
+ msleep(1);
+ gpio_set_value(MX6SL_BRD_CSI_RST, 1);
+ msleep(5);
+ gpio_set_value(MX6SL_BRD_CSI_PWDN, 1);
+}
+
+static void mx6sl_csi_cam_powerdown(int powerdown)
+{
+ if (powerdown)
+ gpio_set_value(MX6SL_BRD_CSI_PWDN, 1);
+ else
+ gpio_set_value(MX6SL_BRD_CSI_PWDN, 0);
+
+ msleep(2);
+}
+
+static struct fsl_mxc_camera_platform_data camera_data = {
+ .mclk = 24000000,
+ .io_init = mx6sl_csi_io_init,
+ .pwdn = mx6sl_csi_cam_powerdown,
+ .core_regulator = "VGEN2_1V5",
+ .analog_regulator = "VGEN6_2V8",
+};
+
static struct imxi2c_platform_data mx6_evk_i2c0_data = {
.bitrate = 100000,
};
@@ -565,7 +714,7 @@ static struct imxi2c_platform_data mx6_evk_i2c1_data = {
};
static struct imxi2c_platform_data mx6_evk_i2c2_data = {
- .bitrate = 400000,
+ .bitrate = 100000,
};
static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
@@ -585,10 +734,17 @@ static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
I2C_BOARD_INFO("wm8962", 0x1a),
.platform_data = &wm8962_config_data,
},
+ {
+ I2C_BOARD_INFO("sii902x", 0),
+ .platform_data = &sii902x_hdmi_data,
+ .irq = gpio_to_irq(MX6SL_BRD_EPDC_PWRCTRL3)
+ },
};
static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
{
+ I2C_BOARD_INFO("ov5640", 0x3c),
+ .platform_data = (void *)&camera_data,
},
};
@@ -623,11 +779,17 @@ static struct mxc_dvfs_platform_data mx6sl_evk_dvfscore_data = {
};
static struct viv_gpu_platform_data imx6q_gpu_pdata __initdata = {
- .reserved_mem_size = SZ_128M,
+ .reserved_mem_size = SZ_32M,
};
void __init early_console_setup(unsigned long base, struct clk *clk);
+static const struct imxuart_platform_data mx6sl_evk_uart1_data __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS | IMXUART_SDMA,
+ .dma_req_rx = MX6Q_DMA_REQ_UART2_RX,
+ .dma_req_tx = MX6Q_DMA_REQ_UART2_TX,
+};
+
static inline void mx6_evk_init_uart(void)
{
imx6q_add_imx_uart(0, NULL); /* DEBUG UART1 */
@@ -1105,7 +1267,7 @@ static struct platform_pwm_backlight_data mx6_evk_pwm_backlight_data = {
.dft_brightness = 128,
.pwm_period_ns = 50000,
};
-static struct fb_videomode video_modes[] = {
+static struct fb_videomode wvga_video_modes[] = {
{
/* 800x480 @ 57 Hz , pixel clk @ 32MHz */
"SEIKO-WVGA", 60, 800, 480, 29850, 99, 164, 33, 10, 10, 10,
@@ -1114,12 +1276,12 @@ static struct fb_videomode video_modes[] = {
0,},
};
-static struct mxc_fb_platform_data fb_data[] = {
+static struct mxc_fb_platform_data wvga_fb_data[] = {
{
.interface_pix_fmt = V4L2_PIX_FMT_RGB24,
.mode_str = "SEIKO-WVGA",
- .mode = video_modes,
- .num_modes = ARRAY_SIZE(video_modes),
+ .mode = wvga_video_modes,
+ .num_modes = ARRAY_SIZE(wvga_video_modes),
},
};
@@ -1127,6 +1289,24 @@ static struct platform_device lcd_wvga_device = {
.name = "lcd_seiko",
};
+static struct fb_videomode hdmi_video_modes[] = {
+ {
+ /* 1920x1080 @ 60 Hz , pixel clk @ 148MHz */
+ "sii9022x_1080p60", 60, 1920, 1080, 6734, 148, 88, 36, 4, 44, 5,
+ FB_SYNC_CLK_LAT_FALL,
+ FB_VMODE_NONINTERLACED,
+ 0,},
+};
+
+static struct mxc_fb_platform_data hdmi_fb_data[] = {
+ {
+ .interface_pix_fmt = V4L2_PIX_FMT_RGB24,
+ .mode_str = "1920x1080M@60",
+ .mode = hdmi_video_modes,
+ .num_modes = ARRAY_SIZE(hdmi_video_modes),
+ },
+};
+
static int mx6sl_evk_keymap[] = {
KEY(0, 0, KEY_SELECT),
KEY(0, 1, KEY_BACK),
@@ -1174,6 +1354,38 @@ static void __init elan_ts_init(void)
gpio_direction_output(MX6SL_BRD_ELAN_CE, 1);
}
+/*
+ *Usually UOK and DOK should have separate
+ *line to differentiate its behaviour (with different
+ * GPIO irq),because connect max8903 pin UOK to
+ *pin DOK from hardware design,cause software cannot
+ *process and distinguish two interrupt, so default
+ *enable dc_valid for ac charger
+ */
+static struct max8903_pdata charger1_data = {
+ .dok = MX6_BRD_CHG_DOK,
+ .uok = MX6_BRD_CHG_UOK,
+ .chg = MX6_BRD_CHG_STATUS,
+ .flt = MX6_BRD_CHG_FLT,
+ .dcm_always_high = true,
+ .dc_valid = true,
+ .usb_valid = false,
+ .feature_flag = 1,
+};
+
+static struct platform_device evk_max8903_charger_1 = {
+ .name = "max8903-charger",
+ .dev = {
+ .platform_data = &charger1_data,
+ },
+};
+
+/*! Device Definition for csi v4l2 device */
+static struct platform_device csi_v4l2_devices = {
+ .name = "csi_v4l2",
+ .id = 0,
+};
+
#define SNVS_LPCR 0x38
static void mx6_snvs_poweroff(void)
{
@@ -1185,11 +1397,27 @@ static void mx6_snvs_poweroff(void)
writel(value | 0x60, mx6_snvs_base + SNVS_LPCR);
}
+static int uart2_enabled;
+static int __init uart2_setup(char * __unused)
+{
+ uart2_enabled = 1;
+ return 1;
+}
+__setup("bluetooth", uart2_setup);
+
+static void __init uart2_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_uart2_pads,
+ ARRAY_SIZE(mx6sl_uart2_pads));
+ imx6sl_add_imx_uart(1, &mx6sl_evk_uart1_data);
+}
/*!
* Board specific initialization.
*/
static void __init mx6_evk_init(void)
{
+ u32 i;
+
mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_pads,
ARRAY_SIZE(mx6sl_brd_pads));
@@ -1211,11 +1439,26 @@ static void __init mx6_evk_init(void)
imx6q_add_imx_i2c(1, &mx6_evk_i2c1_data);
i2c_register_board_info(0, mxc_i2c0_board_info,
ARRAY_SIZE(mxc_i2c0_board_info));
+
+ /* setting sii902x address when hdmi enabled */
+ if (hdmi_enabled) {
+ for (i = 0; i < ARRAY_SIZE(mxc_i2c1_board_info); i++) {
+ if (!strcmp(mxc_i2c1_board_info[i].type, "sii902x")) {
+ mxc_i2c1_board_info[i].addr = 0x39;
+ break;
+ }
+ }
+ }
+
i2c_register_board_info(1, mxc_i2c1_board_info,
ARRAY_SIZE(mxc_i2c1_board_info));
- imx6q_add_imx_i2c(2, &mx6_evk_i2c2_data);
- i2c_register_board_info(2, mxc_i2c2_board_info,
- ARRAY_SIZE(mxc_i2c2_board_info));
+ /* only camera on I2C3, that's why we can do so */
+ if (csi_enabled == 1) {
+ mxc_register_device(&csi_v4l2_devices, NULL);
+ imx6q_add_imx_i2c(2, &mx6_evk_i2c2_data);
+ i2c_register_board_info(2, mxc_i2c2_board_info,
+ ARRAY_SIZE(mxc_i2c2_board_info));
+ }
/* SPI */
imx6q_add_ecspi(0, &mx6_evk_spi_data);
@@ -1243,24 +1486,37 @@ static void __init mx6_evk_init(void)
imx6q_add_otp();
imx6q_add_mxc_pwm(0);
imx6q_add_mxc_pwm_backlight(0, &mx6_evk_pwm_backlight_data);
- imx6dl_add_imx_elcdif(&fb_data[0]);
- gpio_request(MX6_BRD_LCD_PWR_EN, "elcdif-power-on");
- gpio_direction_output(MX6_BRD_LCD_PWR_EN, 1);
- mxc_register_device(&lcd_wvga_device, NULL);
+ if (hdmi_enabled) {
+ imx6dl_add_imx_elcdif(&hdmi_fb_data[0]);
+ } else {
+ imx6dl_add_imx_elcdif(&wvga_fb_data[0]);
+
+ gpio_request(MX6_BRD_LCD_PWR_EN, "elcdif-power-on");
+ gpio_direction_output(MX6_BRD_LCD_PWR_EN, 1);
+ mxc_register_device(&lcd_wvga_device, NULL);
+ }
imx6dl_add_imx_pxp();
imx6dl_add_imx_pxp_client();
mxc_register_device(&max17135_sensor_device, NULL);
setup_spdc();
- if (!spdc_sel)
- imx6dl_add_imx_epdc(&epdc_data);
- else
- imx6sl_add_imx_spdc(&spdc_data);
+ if (csi_enabled) {
+ imx6sl_add_fsl_csi();
+ } else {
+ if (!spdc_sel)
+ imx6dl_add_imx_epdc(&epdc_data);
+ else
+ imx6sl_add_imx_spdc(&spdc_data);
+ }
imx6q_add_dvfs_core(&mx6sl_evk_dvfscore_data);
imx6q_init_audio();
+ /* uart2 for bluetooth */
+ if (uart2_enabled)
+ uart2_init();
+
imx6q_add_viim();
imx6q_add_imx2_wdt(0, NULL);
@@ -1271,10 +1527,17 @@ static void __init mx6_evk_init(void)
imx6sl_add_rngb();
imx6sl_add_imx_pxp_v4l2();
+ mxc_spdif_data.spdif_core_clk = clk_get_sys("mxc_spdif.0", NULL);
+ clk_put(mxc_spdif_data.spdif_core_clk);
+ imx6q_add_spdif(&mxc_spdif_data);
+ imx6q_add_spdif_dai();
+ imx6q_add_spdif_audio_device();
+
imx6q_add_perfmon(0);
imx6q_add_perfmon(1);
imx6q_add_perfmon(2);
-
+ /* Register charger chips */
+ platform_device_register(&evk_max8903_charger_1);
pm_power_off = mx6_snvs_poweroff;
}
diff --git a/arch/arm/mach-mx6/board-mx6solo_sabreauto.h b/arch/arm/mach-mx6/board-mx6solo_sabreauto.h
index 9111e6bc9b19..b752faae33ba 100644
--- a/arch/arm/mach-mx6/board-mx6solo_sabreauto.h
+++ b/arch/arm/mach-mx6/board-mx6solo_sabreauto.h
@@ -207,10 +207,6 @@ static iomux_v3_cfg_t mx6dl_sabreauto_pads[] = {
/* HDMI */
MX6DL_PAD_EIM_A25__HDMI_TX_CEC_LINE,
- /* camera reset */
- MX6DL_PAD_GPIO_19__GPIO_4_5,
- MX6DL_PAD_EIM_D24__GPIO_3_24,
-
/* MLB150 */
MX6DL_PAD_ENET_TXD1__MLB_MLBCLK,
MX6DL_PAD_GPIO_6__MLB_MLBSIG,
diff --git a/arch/arm/mach-mx6/bus_freq.c b/arch/arm/mach-mx6/bus_freq.c
index 9d18423c85c5..6422052ed0b3 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. */
@@ -170,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
@@ -213,14 +214,15 @@ 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;
}
- spin_unlock_irqrestore(&freq_lock, flags);
}
high_bus_freq_mode = 0;
@@ -325,6 +327,7 @@ int set_high_bus_freq(int high_bus_freq)
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 */
@@ -348,7 +351,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) {
@@ -412,7 +414,7 @@ void bus_freq_update(struct clk *clk, bool flag)
*/
high_cpu_freq = 1;
if (low_bus_freq_mode || audio_bus_freq_mode)
- set_high_bus_freq(0);
+ set_high_bus_freq(1);
} else {
/* Update count */
if (clk->flags & AHB_HIGH_SET_POINT)
@@ -471,7 +473,7 @@ void bus_freq_update(struct clk *clk, bool flag)
/* Set to either high or
* medium setpoint.
*/
- set_high_bus_freq(0);
+ set_high_bus_freq(1);
}
}
}
@@ -506,7 +508,7 @@ static ssize_t bus_freq_scaling_enable_store(struct device *dev,
#else
bus_freq_scaling_is_active = 1;
#endif
- set_high_bus_freq(0);
+ set_high_bus_freq(1);
/* Make sure system can enter low bus mode if it should be in
low bus mode */
if (low_freq_bus_used() && !low_bus_freq_mode)
diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c
index 5c3f053ce5fd..0c05c37f81d5 100644
--- a/arch/arm/mach-mx6/clock.c
+++ b/arch/arm/mach-mx6/clock.c
@@ -4854,7 +4854,7 @@ static struct clk usboh3_clk[] = {
.enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
.disable = _clk_disable,
.secondary = &usboh3_clk[1],
- .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
},
{
.parent = &mmdc_ch0_axi_clk[0],
@@ -5304,6 +5304,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, "mlb150_clk", mlb150_clk),
_REGISTER_CLOCK(NULL, "anaclk_1", anaclk_1),
_REGISTER_CLOCK(NULL, "anaclk_2", anaclk_2),
+ _REGISTER_CLOCK(NULL, "apb_pclk", dummy_clk),
};
static void clk_tree_init(void)
diff --git a/arch/arm/mach-mx6/clock_mx6sl.c b/arch/arm/mach-mx6/clock_mx6sl.c
index 616099180008..544b9951baef 100755
--- a/arch/arm/mach-mx6/clock_mx6sl.c
+++ b/arch/arm/mach-mx6/clock_mx6sl.c
@@ -101,9 +101,7 @@ DEFINE_SPINLOCK(mx6sl_clk_lock);
u32 gpt_ticks; \
u32 gpt_cnt; \
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 +131,6 @@ DEFINE_SPINLOCK(mx6sl_clk_lock);
} \
} \
} \
- spin_unlock_irqrestore(&mx6sl_clk_lock, flags); \
result; \
})
@@ -1945,8 +1942,8 @@ static unsigned long _clk_ipu_round_rate(struct clk *clk,
}
static struct clk ipu1_clk = {
- __INIT_CLK_DEBUG(ipu1_clk)
- .parent = &pll2_pfd2_400M,
+ __INIT_CLK_DEBUG(csi_clk)
+ .parent = &osc_clk,
.enable_reg = MXC_CCM_CCGR3,
.enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
.enable = _clk_enable,
@@ -4065,9 +4062,9 @@ int __init mx6sl_clocks_init(unsigned long ckil, unsigned long osc,
3 << MXC_CCM_CCGRx_CG11_OFFSET, MXC_CCM_CCGR1);
__raw_writel(1 << MXC_CCM_CCGRx_CG12_OFFSET |
1 << MXC_CCM_CCGRx_CG11_OFFSET |
- 1 << MXC_CCM_CCGRx_CG10_OFFSET |
- 1 << MXC_CCM_CCGRx_CG9_OFFSET |
- 1 << MXC_CCM_CCGRx_CG8_OFFSET, MXC_CCM_CCGR2);
+ 3 << MXC_CCM_CCGRx_CG10_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG9_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG8_OFFSET, MXC_CCM_CCGR2);
__raw_writel(1 << MXC_CCM_CCGRx_CG14_OFFSET |
3 << MXC_CCM_CCGRx_CG13_OFFSET |
3 << MXC_CCM_CCGRx_CG12_OFFSET |
diff --git a/arch/arm/mach-mx6/cpu.c b/arch/arm/mach-mx6/cpu.c
index be5011aeab34..fbb3827668e0 100644
--- a/arch/arm/mach-mx6/cpu.c
+++ b/arch/arm/mach-mx6/cpu.c
@@ -119,8 +119,14 @@ static int __init post_cpu_init(void)
{
unsigned int reg;
void __iomem *base;
+ u32 iram_size;
- iram_init(MX6Q_IRAM_BASE_ADDR, MX6Q_IRAM_SIZE);
+ if (cpu_is_mx6q())
+ iram_size = MX6Q_IRAM_SIZE;
+ else
+ iram_size = MX6DL_MX6SL_IRAM_SIZE;
+
+ iram_init(MX6Q_IRAM_BASE_ADDR, iram_size);
base = ioremap(AIPS1_ON_BASE_ADDR, PAGE_SIZE);
__raw_writel(0x0, base + 0x40);
diff --git a/arch/arm/mach-mx6/cpu_op-mx6.c b/arch/arm/mach-mx6/cpu_op-mx6.c
index 7e054c1d743c..e6ef0261a285 100644
--- a/arch/arm/mach-mx6/cpu_op-mx6.c
+++ b/arch/arm/mach-mx6/cpu_op-mx6.c
@@ -162,7 +162,7 @@ static struct cpu_op mx6dl_cpu_op_1_2G[] = {
.cpu_podf = 0,
.pu_voltage = 1175000,
.soc_voltage = 1175000,
- .cpu_voltage = 1150000,},
+ .cpu_voltage = 1175000,},
{
.pll_rate = 396000000,
.cpu_rate = 396000000,
@@ -177,16 +177,16 @@ static struct cpu_op mx6dl_cpu_op_1G[] = {
.pll_rate = 996000000,
.cpu_rate = 996000000,
.cpu_podf = 0,
- .pu_voltage = 1250000,
- .soc_voltage = 1250000,
- .cpu_voltage = 1250000,},
+ .pu_voltage = 1275000,
+ .soc_voltage = 1275000,
+ .cpu_voltage = 1275000,},
{
.pll_rate = 792000000,
.cpu_rate = 792000000,
.cpu_podf = 0,
.pu_voltage = 1175000,
.soc_voltage = 1175000,
- .cpu_voltage = 1150000,},
+ .cpu_voltage = 1175000,},
{
.pll_rate = 396000000,
.cpu_rate = 396000000,
@@ -202,7 +202,7 @@ static struct cpu_op mx6dl_cpu_op[] = {
.cpu_podf = 0,
.pu_voltage = 1175000,
.soc_voltage = 1175000,
- .cpu_voltage = 1150000,},
+ .cpu_voltage = 1175000,},
{
.pll_rate = 396000000,
.cpu_rate = 396000000,
@@ -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[] = {
diff --git a/arch/arm/mach-mx6/cpu_regulator-mx6.c b/arch/arm/mach-mx6/cpu_regulator-mx6.c
index cb08cad48204..8eb976d2eefd 100644
--- a/arch/arm/mach-mx6/cpu_regulator-mx6.c
+++ b/arch/arm/mach-mx6/cpu_regulator-mx6.c
@@ -37,6 +37,7 @@ static struct cpu_op *cpu_op_tbl;
extern struct cpu_op *(*get_cpu_op)(int *op);
extern unsigned long loops_per_jiffy;
+int external_pureg;
static inline unsigned long mx6_cpu_jiffies(unsigned long old, u_int div,
u_int mult)
@@ -61,7 +62,10 @@ 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))
printk(KERN_ERR "%s: failed to get cpu regulator\n", __func__);
@@ -88,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,
@@ -108,5 +112,21 @@ void mx6_cpu_regulator_init(void)
pu_regulator = regulator_get(NULL, pu_reg_id);
if (IS_ERR(pu_regulator))
printk(KERN_ERR "%s: failed to get pu regulator\n", __func__);
+ /*If enable CONFIG_MX6_INTER_LDO_BYPASS and VDDPU_IN is single supplied
+ *by external pmic, it means VDDPU_IN can be turned off if GPU/VPU driver
+ *not running.In this case we should set external_pureg which can be used
+ *in pu_enable/pu_disable of arch/arm/mach-mx6/mx6_anatop_regulator.c to
+ *enable or disable external VDDPU regulator from pmic. But for FSL
+ *reference boards, VDDSOC_IN connect with VDDPU_IN, so we didn't set
+ *pu_reg_id to the external pmic regulator supply name in the board file.
+ *In this case external_pureg should be 0 and can't turn off extern pmic
+ *regulator, but can turn off VDDPU by internal anatop power gate.
+ *
+ *If disable CONFIG_MX6_INTER_LDO_BYPASS, external_pureg will be 0, and
+ *VDDPU can be turned off by internal anatop anatop power gate.
+ *
+ */
+ else if (!IS_ERR(pu_regulator) && strcmp(pu_reg_id, "cpu_vddvpu"))
+ external_pureg = 1;
}
diff --git a/arch/arm/mach-mx6/devices-imx6q.h b/arch/arm/mach-mx6/devices-imx6q.h
index bd948cecbcd2..4525e29a472a 100644
--- a/arch/arm/mach-mx6/devices-imx6q.h
+++ b/arch/arm/mach-mx6/devices-imx6q.h
@@ -23,6 +23,10 @@ extern const struct imx_imx_uart_1irq_data imx6q_imx_uart_data[] __initconst;
#define imx6q_add_imx_uart(id, pdata) \
imx_add_imx_uart_1irq(&imx6q_imx_uart_data[id], pdata)
+extern const struct imx_imx_uart_1irq_data imx6sl_imx_uart_data[] __initconst;
+#define imx6sl_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx6sl_imx_uart_data[id], pdata)
+
extern const struct imx_snvs_rtc_data imx6q_imx_snvs_rtc_data __initconst;
#define imx6q_add_imx_snvs_rtc() \
imx_add_snvs_rtc(&imx6q_imx_snvs_rtc_data)
@@ -36,8 +40,8 @@ imx6q_anatop_thermal_imx_data __initconst;
#define imx6q_add_anatop_thermal_imx(id, pdata) \
imx_add_anatop_thermal_imx(&imx6q_anatop_thermal_imx_data, pdata)
-extern const struct imx_dma_data imx6q_dma_data __initconst;
-#define imx6q_add_dma() imx_add_dma(&imx6q_dma_data);
+extern const struct imx_dma_res_data imx6q_dma_res_data __initconst;
+#define imx6q_add_dma() imx_add_dma(&imx6q_dma_res_data);
#define imx6q_add_gpmi(platform_data) imx_add_gpmi(platform_data);
@@ -219,6 +223,10 @@ extern const struct imx_pxp_data imx6dl_pxp_data __initconst;
#define imx6sl_add_imx_pxp_v4l2() \
imx_add_imx_pxp_v4l2()
+extern const struct imx_fsl_csi_data imx6sl_csi_data __initconst;
+#define imx6sl_add_fsl_csi() \
+ imx_add_fsl_csi(&imx6sl_csi_data)
+
extern const struct imx_epdc_data imx6dl_epdc_data __initconst;
#define imx6dl_add_imx_epdc(pdata) \
imx_add_imx_epdc(&imx6dl_epdc_data, pdata)
diff --git a/arch/arm/mach-mx6/etm.c b/arch/arm/mach-mx6/etm.c
new file mode 100644
index 000000000000..8f328608ebfd
--- /dev/null
+++ b/arch/arm/mach-mx6/etm.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/iram_alloc.h>
+#include <linux/delay.h>
+#include <linux/amba/bus.h>
+
+#include <mach/hardware.h>
+#include <asm/io.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/coresight.h>
+
+static struct __init amba_device mx6_etb_device = {
+ .dev = {
+ .init_name = "etb",
+ },
+ .res = {
+ .start = MX6Q_ETB_BASE_ADDR,
+ .end = MX6Q_ETB_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .periphid = 0x3bb907,
+};
+
+static struct __init amba_device mx6_etm_device[] = {
+ {
+ .dev = {
+ .init_name = "etm.0",
+ },
+ .res = {
+ .start = MX6Q_PTM0_BASE_ADDR,
+ .end = MX6Q_PTM0_BASE_ADDR + SZ_4K - 1,
+ },
+ .periphid = 0x1bb950,
+ },
+ {
+ .dev = {
+ .init_name = "etm.1",
+ },
+ .res = {
+ .start = MX6Q_PTM1_BASE_ADDR,
+ .end = MX6Q_PTM1_BASE_ADDR + SZ_4K - 1,
+ },
+ .periphid = 0x1bb950,
+ },
+ {
+ .dev = {
+ .init_name = "etm.2",
+ },
+ .res = {
+ .start = MX6Q_PTM2_BASE_ADDR,
+ .end = MX6Q_PTM2_BASE_ADDR + SZ_4K - 1,
+ },
+ .periphid = 0x1bb950,
+ },
+ {
+ .dev = {
+ .init_name = "etm.3",
+ },
+ .res = {
+ .start = MX6Q_PTM3_BASE_ADDR,
+ .end = MX6Q_PTM3_BASE_ADDR + SZ_4K - 1,
+ },
+ .periphid = 0x1bb950,
+ },
+};
+
+#define FUNNEL_CTL 0
+static int __init etm_init(void)
+{
+ int i;
+ __iomem void *base;
+ base = ioremap(0x02144000, SZ_4K);
+ /*Unlock Funnel*/
+ __raw_writel(UNLOCK_MAGIC, base + CSMR_LOCKACCESS);
+ /*Enable all funnel port*/
+ __raw_writel(__raw_readl(base + FUNNEL_CTL) | 0xFF,
+ base + FUNNEL_CTL);
+ /*Lock Funnel*/
+ __raw_writel(0, base + CSMR_LOCKACCESS);
+ iounmap(base);
+
+ amba_device_register(&mx6_etb_device, &iomem_resource);
+ for (i = 0; i < num_possible_cpus(); i++)
+ amba_device_register(mx6_etm_device + i, &iomem_resource);
+
+ return 0;
+}
+
+subsys_initcall(etm_init);
diff --git a/arch/arm/mach-mx6/mx6_anatop_regulator.c b/arch/arm/mach-mx6/mx6_anatop_regulator.c
index 945adbdb759a..f2c2ebf600b3 100644
--- a/arch/arm/mach-mx6/mx6_anatop_regulator.c
+++ b/arch/arm/mach-mx6/mx6_anatop_regulator.c
@@ -22,6 +22,7 @@
* mx6_anatop_regulator.c -- i.MX6 Driver for Anatop regulators
*/
#include <linux/device.h>
+#include <linux/err.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/regulator/anatop-regulator.h>
@@ -30,6 +31,9 @@
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/gpio.h>
+#include <linux/clk.h>
+
+#include <mach/clock.h>
#include "crm_regs.h"
#include "regs-anadig.h"
@@ -41,8 +45,17 @@ extern struct platform_device sgtl5000_vdda_reg_devices;
extern struct platform_device sgtl5000_vddio_reg_devices;
extern struct platform_device sgtl5000_vddd_reg_devices;
extern void __iomem *gpc_base;
-/* Default PU voltage value set to 1.1V */
-static unsigned int org_ldo = 0x2000;
+/* we use the below flag to keep PU regulator state, because enable/disable
+of PU regulator share with the same register as voltage set of PU regulator.
+PU voltage set by cpufreq driver if the flag is set, and enable/disable by
+GPU/VPU driver*/
+static unsigned int pu_is_enabled;
+static unsigned int get_clk;
+static struct clk *gpu3d_clk, *gpu3d_shade_clk, *gpu2d_clk, *gpu2d_axi_clk;
+static struct clk *openvg_axi_clk, *vpu_clk;
+extern int external_pureg;
+extern struct regulator *pu_regulator;
+
static int get_voltage(struct anatop_regulator *sreg)
{
@@ -90,17 +103,56 @@ static int set_voltage(struct anatop_regulator *sreg, int uv)
static int pu_enable(struct anatop_regulator *sreg)
{
- unsigned int reg;
+ unsigned int reg, vddsoc;
+ int ret = 0;
+ /*get PU related clk to finish PU regulator power up*/
+ if (!get_clk) {
+ if (!cpu_is_mx6sl()) {
+ gpu3d_clk = clk_get(NULL, "gpu3d_clk");
+ if (IS_ERR(gpu3d_clk))
+ printk(KERN_ERR "%s: failed to get gpu3d_clk!\n"
+ , __func__);
+ gpu3d_shade_clk = clk_get(NULL, "gpu3d_shader_clk");
+ if (IS_ERR(gpu3d_shade_clk))
+ printk(KERN_ERR "%s: failed to get shade_clk!\n"
+ , __func__);
+ if (IS_ERR(vpu_clk))
+ printk(KERN_ERR "%s: failed to get vpu_clk!\n",
+ __func__);
+ }
+ gpu2d_clk = clk_get(NULL, "gpu2d_clk");
+ if (IS_ERR(gpu2d_clk))
+ printk(KERN_ERR "%s: failed to get gpu2d_clk!\n",
+ __func__);
+ gpu2d_axi_clk = clk_get(NULL, "gpu2d_axi_clk");
+ if (IS_ERR(gpu2d_axi_clk))
+ printk(KERN_ERR "%s: failed to get gpu2d_axi_clk!\n",
+ __func__);
+ openvg_axi_clk = clk_get(NULL, "openvg_axi_clk");
+ if (IS_ERR(openvg_axi_clk))
+ printk(KERN_ERR "%s: failed to get openvg_axi_clk!\n",
+ __func__);
+ get_clk = 1;
- /* Do not enable PU LDO if it is already enabled */
- reg = __raw_readl(ANADIG_REG_CORE) & (ANADIG_REG_TARGET_MASK
- << ANADIG_REG1_PU_TARGET_OFFSET);
- if (reg != 0)
- return 0;
-
- /* Set the voltage of VDDPU as in normal mode. */
- __raw_writel(org_ldo | (__raw_readl(ANADIG_REG_CORE) &
- (~(ANADIG_REG_TARGET_MASK << ANADIG_REG1_PU_TARGET_OFFSET))), ANADIG_REG_CORE);
+ }
+ if (external_pureg) {
+ /*enable extern PU regulator*/
+ ret = regulator_enable(pu_regulator);
+ if (ret < 0)
+ printk(KERN_ERR "%s: enable pu error!\n", __func__);
+ } else {
+ /*Track the voltage of VDDPU with VDDSOC if use internal PU
+ *regulator.
+ */
+ reg = __raw_readl(ANADIG_REG_CORE);
+ vddsoc = reg & (ANADIG_REG_TARGET_MASK <<
+ ANADIG_REG2_SOC_TARGET_OFFSET);
+ reg &= ~(ANADIG_REG_TARGET_MASK <<
+ ANADIG_REG1_PU_TARGET_OFFSET);
+ reg |= vddsoc >> (ANADIG_REG2_SOC_TARGET_OFFSET
+ -ANADIG_REG1_PU_TARGET_OFFSET);
+ __raw_writel(reg, ANADIG_REG_CORE);
+ }
/* Need to wait for the regulator to come back up */
/*
@@ -109,7 +161,17 @@ static int pu_enable(struct anatop_regulator *sreg)
* 25mV step.
*/
udelay(150);
-
+ /*enable gpu clock to powerup GPU right.*/
+ if (get_clk) {
+ if (!cpu_is_mx6sl()) {
+ clk_enable(gpu3d_clk);
+ clk_enable(gpu3d_shade_clk);
+ clk_enable(vpu_clk);
+ }
+ clk_enable(gpu2d_clk);
+ clk_enable(gpu2d_axi_clk);
+ clk_enable(openvg_axi_clk);
+ }
/* enable power up request */
reg = __raw_readl(gpc_base + GPC_PGC_GPU_PGCR_OFFSET);
__raw_writel(reg | 0x1, gpc_base + GPC_PGC_GPU_PGCR_OFFSET);
@@ -119,7 +181,6 @@ static int pu_enable(struct anatop_regulator *sreg)
/* Wait for the power up bit to clear */
while (__raw_readl(gpc_base + GPC_CNTR_OFFSET) & 0x2)
;
-
/* Enable the Brown Out detection. */
reg = __raw_readl(ANA_MISC2_BASE_ADDR);
reg |= ANADIG_ANA_MISC2_REG1_BO_EN;
@@ -131,19 +192,24 @@ static int pu_enable(struct anatop_regulator *sreg)
reg &= ~0x80000000;
__raw_writel(reg, gpc_base + 0x14);
#endif
-
+ pu_is_enabled = 1;
+ if (get_clk) {
+ if (!cpu_is_mx6sl()) {
+ clk_disable(gpu3d_clk);
+ clk_disable(gpu3d_shade_clk);
+ clk_disable(vpu_clk);
+ }
+ clk_disable(gpu2d_clk);
+ clk_disable(gpu2d_axi_clk);
+ clk_disable(openvg_axi_clk);
+ }
return 0;
}
static int pu_disable(struct anatop_regulator *sreg)
{
unsigned int reg;
-
- /* Do not disable PU LDO if it is not enabled */
- reg = __raw_readl(ANADIG_REG_CORE) & (ANADIG_REG_TARGET_MASK
- << ANADIG_REG1_PU_TARGET_OFFSET);
- if (reg == 0)
- return 0;
+ int ret = 0;
/* Disable the brown out detection since we are going to be
* disabling the LDO.
@@ -163,7 +229,6 @@ static int pu_disable(struct anatop_regulator *sreg)
/* Wait for power down to complete. */
while (__raw_readl(gpc_base + GPC_CNTR_OFFSET) & 0x1)
;
-
#ifndef CONFIG_MX6_INTER_LDO_BYPASS
/* Mask the ANATOP brown out interrupt in the GPC. */
reg = __raw_readl(gpc_base + 0x14);
@@ -171,12 +236,19 @@ static int pu_disable(struct anatop_regulator *sreg)
__raw_writel(reg, gpc_base + 0x14);
#endif
- /* PU power gating. */
- reg = __raw_readl(ANADIG_REG_CORE);
- org_ldo = reg & (ANADIG_REG_TARGET_MASK << ANADIG_REG1_PU_TARGET_OFFSET);
- reg &= ~(ANADIG_REG_TARGET_MASK << ANADIG_REG1_PU_TARGET_OFFSET);
- __raw_writel(reg, ANADIG_REG_CORE);
-
+ if (external_pureg) {
+ /*disable extern PU regulator*/
+ ret = regulator_disable(pu_regulator);
+ if (ret < 0)
+ printk(KERN_ERR "%s: disable pu error!\n", __func__);
+ } else {
+ /* PU power gating. */
+ reg = __raw_readl(ANADIG_REG_CORE);
+ reg &= ~(ANADIG_REG_TARGET_MASK <<
+ ANADIG_REG1_PU_TARGET_OFFSET);
+ __raw_writel(reg, ANADIG_REG_CORE);
+ }
+ pu_is_enabled = 0;
/* Clear the BO interrupt in the ANATOP. */
reg = __raw_readl(ANADIG_MISC1_REG);
reg |= 0x80000000;
@@ -185,14 +257,7 @@ static int pu_disable(struct anatop_regulator *sreg)
}
static int is_pu_enabled(struct anatop_regulator *sreg)
{
- unsigned int reg;
-
- reg = __raw_readl(ANADIG_REG_CORE) & (ANADIG_REG_TARGET_MASK
- << ANADIG_REG1_PU_TARGET_OFFSET);
- if (reg == 0)
- return 0;
- else
- return 1;
+ return pu_is_enabled;
}
static int enable(struct anatop_regulator *sreg)
{
@@ -447,6 +512,9 @@ static int __init regulators_init(void)
anatop_register_regulator(&vdd1p1_reg, ANATOP_VDD1P1, &vdd1p1_init);
anatop_register_regulator(&vdd3p0_reg, ANATOP_VDD3P0, &vdd3p0_init);
+ /* clear flag in boot*/
+ pu_is_enabled = 0;
+ get_clk = 0;
return 0;
}
postcore_initcall(regulators_init);
diff --git a/arch/arm/mach-mx6/mx6_suspend.S b/arch/arm/mach-mx6/mx6_suspend.S
index 0533ad1b20ef..f712700a8e68 100644
--- a/arch/arm/mach-mx6/mx6_suspend.S
+++ b/arch/arm/mach-mx6/mx6_suspend.S
@@ -32,7 +32,7 @@
#define MMDC_MAPSR_OFFSET 0x404
#define MMDC_MAPSR_PSS (1 << 4)
#define MMDC_MAPSR_PSD (1 << 0)
-#define IRAM_SUSPEND_SIZE (1 << 12)
+#define IRAM_SUSPEND_SIZE (1 << 13)
/*************************************************************
mx6_suspend:
@@ -50,6 +50,333 @@ see define in include/linux/suspend.h
r1: iram_paddr
r2: suspend_iram_base
*************************************************************/
+ .macro mx6sl_standy_saving_set
+
+ /* Move periph_clk to OSC_CLK. */
+ ldr r1, =CCM_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+
+ /* Ensure the periph_clk2_sel to OSC clk. */
+ ldr r0, [r1, #0x18]
+ bic r0, r0, #0x3000
+ orr r0, r0, #0x1000
+ str r0, [r1, #0x18]
+
+ ldr r0, [r1, #0x14]
+ orr r0, r0, #0x2000000
+ str r0, [r1, #0x14]
+
+periph_clk_switch:
+ ldr r0, [r1, #0x48]
+ cmp r0, #0
+ bne periph_clk_switch
+
+ /* Set the divider to divider by 8 */
+ ldr r0, [r1, #0x14]
+ orr r0, r0, #0x70000
+ orr r0, r0, #0x1c00
+ str r0, [r1, #0x14]
+
+ahb_podf:
+ ldr r0, [r1, #0x48]
+ cmp r0, #0
+ bne ahb_podf
+
+ /* Move DDR clk to PLL3 clock.
+ */
+ /* First set the divider to 2. */
+ ldr r0, [r1, #0x14]
+ orr r0, r0, #0x1
+ str r0, [r1, #0x14]
+
+ ldr r0, [r1, #0x18]
+ bic r0, r0, #0x100000
+ str r0, [r1, #0x18]
+
+ ldr r0, [r1, #0x14]
+ orr r0, r0, #0x4000000
+ str r0, [r1, #0x14]
+
+ddr_switch:
+ ldr r0, [r1, #0x48]
+ cmp r0, #0
+ bne ddr_switch
+
+ /* Set DDR clock to divide by 8. */
+ ldr r0, [r1, #0x14]
+ orr r0, r0, #0x38
+ str r0, [r1, #0x14]
+
+mmdc_div:
+ ldr r0, [r1, #0x48]
+ cmp r0, #0
+ bne mmdc_div
+
+ /* Now Switch ARM to run from
+ * step_clk sourced from OSC.
+ */
+ ldr r0, [r1, #0xc]
+ bic r0, r1, #0x100
+ str r0, [r1, #0x0c]
+
+ /* Now switch PLL1_SW_CLK to step_clk. */
+ ldr r0, [r1, #0x0c]
+ orr r0, r0, #0x4
+ str r0, [r1, #0x0c]
+
+ ldr r1, =ANATOP_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+
+ /* Need to clock gate the 528 PFDs before
+ * powering down PLL2.
+ * Only the PLL2_PFD2_400M should be ON
+ * as it feeds the MMDC/AHB
+ */
+ ldr r0, [r1, #0x100]
+ orr r0, r0, #0x800000
+ str r0, [r1, #0x100]
+
+ /* Now bypass PLL1 and PLL2. */
+ ldr r0, =0x10000
+ str r0, [r1, #0x4]
+ str r0, [r1, #0x34]
+
+ /* Now do all the analog savings. */
+
+ /* Disable 1p1 brown out. */
+ ldr r0, [r1, #0x110]
+ bic r0, r0, #0x2
+ str r0, [r1, #0x110]
+
+ /* Enable the weak 2P5 */
+ ldr r0, [r1, #0x130]
+ orr r0, r0, #0x40000
+ str r0, [r1, #0x130]
+
+ /*Disable main 2p5. */
+ ldr r0, [r1, #0x130]
+ bic r0, r0, #0x1
+ str r0, [r1, #0x130]
+
+
+ /* Set the OSC bias current to -37.5%
+ * to drop the power on VDDHIGH.
+ */
+ ldr r0, [r1, #0x150]
+ orr r0, r0, #0xC000
+ str r0, [r1, #0x150]
+ .endm
+
+ .macro mx6sl_standby_savings_restore
+
+ /* Set the OSC bias current to max
+ * value for normal operation.
+ */
+ ldr r6, [r1, #0x150]
+ bic r6, r6, #0xC000
+ str r6, [r1, #0x150]
+
+ /*Enable main 2p5. */
+ ldr r6, [r1, #0x130]
+ orr r6, r6, #0x1
+ str r6, [r1, #0x130]
+
+ /* Ensure the 2P5 is up. */
+loop_2p5:
+ ldr r6, [r1, #0x130]
+ and r6, r6, #0x20000
+ cmp r6, #0x20000
+ bne loop_2p5
+
+ /* Disable the weak 2P5 */
+ ldr r6, [r1, #0x130]
+ bic r6, r6, #0x40000
+ str r6, [r1, #0x130]
+
+ /* Enable 1p1 brown out. */
+ ldr r6, [r1, #0x110]
+ orr r6, r6, #0x2
+ str r6, [r1, #0x110]
+
+ /* Unbypass PLLs and
+ * wait for relock.
+ */
+ ldr r6, =(1 << 16)
+ str r6, [r1, #0x08]
+ str r6, [r1, #0x38]
+
+wait_for_pll_lock:
+ ldr r6, [r1, #0x0]
+ and r6, r6, #0x80000000
+ cmp r6, #0x80000000
+ bne wait_for_pll_lock
+
+ /* Set PLL1_sw_clk back to PLL1. */
+ ldr r6, [r3, #0x0c]
+ bic r6, r6, #0x4
+ str r6, [r3, #0xc]
+
+ /* Need to enable the 528 PFDs after
+ * powering up PLL2.
+ * Only the PLL2_PFD2_400M should be ON
+ * as it feeds the MMDC. Rest should have
+ * been managed by clock code.
+ */
+ ldr r6, [r1, #0x100]
+ bic r6, r6, #0x800000
+ str r6, [r1, #0x100]
+
+ /* Move periph_clk back
+ * to PLL2_PFD2_400.
+ */
+ ldr r6, [r3, #0x14]
+ 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
+ bic r6, r6, #0x1c00
+ orr r6, r6, #0x10800
+ str r6, [r3, #0x14]
+
+ahb_podf1:
+ ldr r6, [r3, #0x48]
+ cmp r6, #0
+ bne ahb_podf1
+
+ /* Move MMDC back to PLL2_PFD2_400 */
+ ldr r6, [r3, #0x14]
+ bic r6, r6, #0x4000000
+ str r6, [r3, #0x14]
+
+mmdc_loop2:
+ ldr r6, [r3, #0x48]
+ cmp r6, #0
+ bne mmdc_loop2
+
+ /* Set DDR clock to divide by 1. */
+ ldr r6, [r3, #0x14]
+ bic r6, r6, #0x38
+ str r6, [r3, #0x14]
+
+mmdc_div1:
+ ldr r6, [r3, #0x48]
+ cmp r6, #0
+ bne mmdc_div1
+
+ .endm
+
+ .macro mx6sl_standby_pg_savings_restore
+
+ /* Set the OSC bias current to max
+ * value for normal operation.
+ */
+ ldr r6, [r1, #0x150]
+ bic r6, r6, #0xC000
+ str r6, [r1, #0x150]
+
+ /*Enable main 2p5. */
+ ldr r6, [r1, #0x130]
+ orr r6, r6, #0x1
+ str r6, [r1, #0x130]
+
+ /* Ensure the 2P5 is up. */
+loop_2p5_1:
+ ldr r6, [r1, #0x130]
+ and r6, r6, #0x20000
+ cmp r6, #0x20000
+ bne loop_2p5_1
+
+ /* Disable the weak 2P5 */
+ ldr r6, [r1, #0x130]
+ bic r6, r6, #0x40000
+ str r6, [r1, #0x130]
+
+ /* Enable 1p1 brown out. */
+ ldr r6, [r1, #0x110]
+ orr r6, r6, #0x2
+ str r6, [r1, #0x110]
+
+ /* Unbypass PLLs and
+ * wait for relock.
+ */
+ ldr r6, =(1 << 16)
+ str r6, [r1, #0x08]
+ str r6, [r1, #0x38]
+
+wait_for_pll_lock1:
+ ldr r6, [r1, #0x0]
+ and r6, r6, #0x80000000
+ cmp r6, #0x80000000
+ bne wait_for_pll_lock1
+
+ /* Set PLL1_sw_clk back to PLL1. */
+ ldr r6, [r3, #0x0c]
+ bic r6, r6, #0x4
+ str r6, [r3, #0xc]
+
+ /* Need to enable the 528 PFDs after
+ * powering up PLL2.
+ * Only the PLL2_PFD2_400M should be ON
+ * as it feeds the MMDC. Rest should have
+ * been managed by clock code.
+ */
+ ldr r6, [r1, #0x100]
+ bic r6, r6, #0x800000
+ str r6, [r1, #0x100]
+
+ /* Move DDR clock back to PLL2_PFD2_400 */
+ ldr r6, [r3, #0x14]
+ bic r6, r6, #0x4000000
+ str r6, [r3, #0x14]
+
+mmdc_loop3:
+ ldr r6, [r3, #0x48]
+ cmp r6, #0
+ bne mmdc_loop3
+
+ /* Set DDR clock to divide by 1. */
+ ldr r6, [r3, #0x14]
+ bic r6, r6, #0x38
+ str r6, [r3, #0x14]
+
+mmdc_div2:
+ ldr r6, [r3, #0x48]
+ cmp r6, #0
+ bne mmdc_div2
+
+ /* Move periph_clk back
+ * to PLL2_PFD2_400.
+ */
+ ldr r6, [r3, #0x14]
+ bic r6, r6, #0x2000000
+ str r6, [r3, #0x14]
+
+periph_clk_switch2:
+ ldr r6, [r3, #0x48]
+ cmp r6, #0
+ bne periph_clk_switch2
+
+ /* Set the dividers to default value. */
+ ldr r6, [r3, #0x14]
+ bic r6, r6, #0x70000
+ bic r6, r6, #0x1c00
+ orr r6, r6, #0x10800
+ str r6, [r3, #0x14]
+
+ahb_podf2:
+ ldr r6, [r3, #0x48]
+ cmp r6, #0
+ bne ahb_podf2
+
+ .endm
+
.macro sl_ddr_io_save
ldr r4, [r1, #0x30c] /* DRAM_DQM0 */
@@ -58,12 +385,6 @@ r2: suspend_iram_base
ldr r7, [r1, #0x318] /* DRAM_DQM3 */
stmfd r0!, {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 r0!, {r4-r7}
-
ldr r4, [r1, #0x5c4] /* GPR_B0DS */
ldr r5, [r1, #0x5cc] /* GPR_B1DS */
ldr r6, [r1, #0x5d4] /* GPR_B2DS */
@@ -73,7 +394,7 @@ r2: suspend_iram_base
ldr r4, [r1, #0x300] /* DRAM_CAS */
ldr r5, [r1, #0x31c] /* DRAM_RAS */
ldr r6, [r1, #0x338] /* DRAM_SDCLK_0 */
- ldr r7, [r1, #0x5ac] /* GPR_ADDS*/
+ ldr r7, [r1, #0x5ac] /* GPR_ADDS*/
stmfd r0!, {r4-r7}
ldr r4, [r1, #0x5b0] /* DDRMODE_CTL */
@@ -98,22 +419,16 @@ r2: suspend_iram_base
str r7, [r1, #0x318] /* DRAM_DQM3 */
ldmea r0!, {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 r0!, {r4-r7}
str r4, [r1, #0x5c4] /* GPR_B0DS */
str r5, [r1, #0x5cc] /* GPR_B1DS */
- str r6, [r1, #0x5d4] /* GPR_B2DS */
- str r7, [r1, #0x5d8] /* GPR_B3DS */
+ str r6, [r1, #0x5d4] /* GPR_B2DS */
+ str r7, [r1, #0x5d8] /* GPR_B3DS */
ldmea r0!, {r4-r7}
str r4, [r1, #0x300] /* DRAM_CAS */
str r5, [r1, #0x31c] /* DRAM_RAS */
str r6, [r1, #0x338] /* DRAM_SDCLK_0 */
- str r7, [r1, #0x5ac] /* GPR_ADDS*/
+ str r7, [r1, #0x5ac] /* GPR_ADDS*/
ldmea r0!, {r4-r7}
str r4, [r1, #0x5b0] /* DDRMODE_CTL */
@@ -136,27 +451,15 @@ r2: suspend_iram_base
str r0, [r1, #0x314] /* DRAM_DQM2 */
str r0, [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 r0, [r1, #0x344]
- orr r0, r0, #0x3000
- str r0, [r1, #0x344] /* DRAM_SDQS0 */
- str r0, [r1, #0x348] /* DRAM_SDQS1 */
- str r0, [r1, #0x34c] /* DRAM_SDQS2 */
- str r0, [r1, #0x350] /* DRAM_SDQS3 */
-
str r0, [r1, #0x5c4] /* GPR_B0DS */
str r0, [r1, #0x5cc] /* GPR_B1DS */
- str r0, [r1, #0x5d4] /* GPR_B2DS */
- str r0, [r1, #0x5d8] /* GPR_B3DS */
+ str r0, [r1, #0x5d4] /* GPR_B2DS */
+ str r0, [r1, #0x5d8] /* GPR_B3DS */
str r0, [r1, #0x300] /* DRAM_CAS */
str r0, [r1, #0x31c] /* DRAM_RAS */
str r0, [r1, #0x338] /* DRAM_SDCLK_0 */
- str r0, [r1, #0x5ac] /* GPR_ADDS*/
+ str r0, [r1, #0x5ac] /* GPR_ADDS*/
str r0, [r1, #0x5b0] /* DDRMODE_CTL */
str r0, [r1, #0x5c0] /* DDRMODE */
@@ -617,6 +920,10 @@ ENTRY(mx6_suspend)
suspend mode entry
*************************************************************/
mov r12, r3 /* Save CPU type to r12*/
+ mov r11, r0 /* Save the state in r11 */
+
+ cmp r12, #MXC_CPU_MX6SL
+ beq dormant
cmp r0, #0x1
bne dormant /* dormant mode */
@@ -666,14 +973,17 @@ suspend mode entry
never run to here
************************************************************/
b out /* exit standby */
-
+ /* Place the literal pool here so that
+ * literals are within 4KB range
+ */
+ .ltorg
/************************************************************
dormant entry, data save in stack, save sp in the src_gpr2
************************************************************/
dormant:
mov r3, r1
mov r0, r1
- add r0, r0, #IRAM_SUSPEND_SIZE /* 4K */
+ add r0, r0, #IRAM_SUSPEND_SIZE /* 8K */
ldr r4, =SRC_BASE_ADDR
add r4, r4, #PERIPBASE_VIRT
str r0, [r4, #SRC_GPR2_OFFSET] /* set src_gpr2 */
@@ -701,10 +1011,12 @@ saved register and context as below:
iram_suspend base */
mov r0, r2 /* get suspend_iram_base */
- add r0, r0, #IRAM_SUSPEND_SIZE /* 4K */
+ add r0, r0, #IRAM_SUSPEND_SIZE /* 8K */
mov r4, r12 @ Store cpu type
stmfd r0!, {r4}
+ mov r4, r11 @ Store state entered
+ stmfd r0!, {r4}
ldr r1, =MX6Q_IOMUXC_BASE_ADDR
add r1, r1, #PERIPBASE_VIRT
@@ -784,6 +1096,15 @@ set ddr iomux to low power mode
ldr r1, =SRC_BASE_ADDR
add r1, r1, #PERIPBASE_VIRT
ldr r0, [r1]
+ 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
@@ -795,14 +1116,23 @@ set ddr iomux to low power mode
ldr r1, =MMDC_P0_BASE_ADDR
add r1, r1, #PERIPBASE_VIRT
- ldr r0, [r1, #MMDC_MAPSR_OFFSET]
- bic r0, #MMDC_MAPSR_PSD /* enable lpm */
- str r0, [r1, #MMDC_MAPSR_OFFSET]
-refresh:
- ldr r0, [r1, #MMDC_MAPSR_OFFSET] /* MMDC_MAPSR */
- and r0, r0, #MMDC_MAPSR_PSS /* PSS bit */
- cmp r0, #0
- beq refresh
+
+ /* Put DDR explicitly into self-refresh. */
+ /* Disable Automatic power savings. */
+ ldr r0, [r1, #0x404]
+ orr r0, r0, #0x01
+ str r0, [r1, #0x404]
+
+ /* Make the DDR explicitly enter self-refresh. */
+ ldr r0, [r1, #0x404]
+ orr r0, r0, #0x200000
+ str r0, [r1, #0x404]
+
+ poll_dvfs_set_1:
+ ldr r0, [r1, #0x404]
+ and r0, r0, #0x2000000
+ cmp r0, #0x2000000
+ bne poll_dvfs_set_1
/* set mmdc iomux to low power mode */
ldr r1, =MX6Q_IOMUXC_BASE_ADDR
@@ -822,6 +1152,22 @@ sl_io_set_lpm:
ddr_io_set_lpm_done:
+ /* Do Analog Power Optimizations
+ * for MX6SL in standby mode.
+ */
+ cmp r12, #MXC_CPU_MX6SL
+ bne no_analog_savings
+ cmp r11, #1
+ bne no_analog_savings
+
+ /* We are here because on
+ * MX6SL, we want to lower
+ * the power in Standby mode.
+ */
+ mx6sl_standy_saving_set
+
+no_analog_savings:
+
/****************************************************************
save resume pointer into SRC_GPR1
****************************************************************/
@@ -832,13 +1178,74 @@ save resume pointer into SRC_GPR1
ldr r1, =SRC_BASE_ADDR
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
- ldr r3, [r1, #0x140]
- bic r3, r3, #0x1f
- orr r3, r3, #0x1e
- str r3, [r1, #0x140]
+ ldr r4, [r1, #0x140]
+ bic r4, r4, #0x1f
+ orr r4, r4, #0x1e
+ str r4, [r1, #0x140]
#endif
/****************************************************************
execute a wfi instruction to let SOC go into stop mode.
@@ -863,11 +1270,26 @@ system immediately.
#endif
mov r0, r2 /* get suspend_iram_base */
- add r0, r0, #IRAM_SUSPEND_SIZE /* 4K */
+ add r0, r0, #IRAM_SUSPEND_SIZE /* 8K */
ldmea r0!, {r12} @ get cpu type to make ddr io
@ offset right
+ ldmea r0!, {r11} @ standby or mem
+
+ cmp r12, #MXC_CPU_MX6SL
+ bne no_analog_restore
+
+ cmp r11, #0x1
+ bne no_analog_restore
+
+ ldr r3, =CCM_BASE_ADDR
+ add r3, r3, #PERIPBASE_VIRT
+
+ /* Restore the analog settings. */
+ mx6sl_standby_savings_restore
+
+no_analog_restore:
ldr r1, =MX6Q_IOMUXC_BASE_ADDR
add r1, r1, #PERIPBASE_VIRT
@@ -882,8 +1304,49 @@ dl_io_restore:
b ddr_io_restore_done
sl_io_restore:
sl_ddr_io_restore
+ ldr r1, =MMDC_P0_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+ /* 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
ddr_io_restore_done:
+ ldr r1, =MMDC_P0_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+
+ /* Ensure DDR exits self-refresh. */
+ ldr r6, [r1, #0x404]
+ bic r6, r6, #0x200000
+ str r6, [r1, #0x404]
+
+poll_dvfs_clear_1:
+ ldr r6, [r1, #0x404]
+ and r6, r6, #0x2000000
+ cmp r6, #0x2000000
+ beq poll_dvfs_clear_1
+
+ /* Enable Automatic power savings. */
+ ldr r6, [r1, #0x404]
+ bic r6, r6, #0x01
+ str r6, [r1, #0x404]
+
/* Add enough nops so that the
* prefetcher will not get instructions
* from DDR before its IO pads
@@ -930,6 +1393,7 @@ when SOC exit stop mode, arm core restart from here, currently
are running with MMU off.
****************************************************************/
resume:
+
#ifdef CONFIG_MX6_INTER_LDO_BYPASS
ldr r1, =ANATOP_BASE_ADDR
ldr r3, [r1, #0x140]
@@ -954,6 +1418,22 @@ resume:
ldmea r0!, {r12} @ get cpu type
+ ldmea r0!, {r11} @ standby or mem
+
+
+ cmp r12, #MXC_CPU_MX6SL
+ bne no_analog_restore1
+
+ cmp r11, #0x1
+ bne no_analog_restore1
+
+ ldr r1, =ANATOP_BASE_ADDR
+ ldr r3, =CCM_BASE_ADDR
+
+ /* Restore the analog settings. */
+ mx6sl_standby_pg_savings_restore
+
+no_analog_restore1:
/* Restore DDR IO */
ldr r1, =MX6Q_IOMUXC_BASE_ADDR
@@ -968,8 +1448,46 @@ dl_io_dsm_restore:
b ddr_io_restore_dsm_done
sl_io_dsm_restore:
sl_ddr_io_restore
+ ldr r1, =MMDC_P0_BASE_ADDR
+ /* reset read FIFO, RST_RD_FIFO */
+ ldr r7, =0x83c
+ ldr r6, [r1, r7]
+ orr r6, r6, #0x80000000
+ str r6, [r1, r7]
+dsm_fifo_reset1_wait:
+ ldr r6, [r1, r7]
+ and r6, r6, #0x80000000
+ cmp r6, #0
+ bne dsm_fifo_reset1_wait
+
+ /* reset FIFO a second time */
+ ldr r6, [r1, r7]
+ orr r6, r6, #0x80000000
+ str r6, [r1, r7]
+dsm_fifo_reset2_wait:
+ ldr r6, [r1, r7]
+ and r6, r6, #0x80000000
+ cmp r6, #0
+ bne dsm_fifo_reset2_wait
ddr_io_restore_dsm_done:
+ ldr r1, =MMDC_P0_BASE_ADDR
+
+ /* Ensure DDR exits self-refresh. */
+ ldr r6, [r1, #0x404]
+ bic r6, r6, #0x200000
+ str r6, [r1, #0x404]
+
+poll_dvfs_clear_2:
+ ldr r6, [r1, #0x404]
+ and r6, r6, #0x2000000
+ cmp r6, #0x2000000
+ beq poll_dvfs_clear_2
+
+ /* Enable Automatic power savings. */
+ ldr r6, [r1, #0x404]
+ bic r6, r6, #0x01
+ str r6, [r1, #0x404]
#ifdef CONFIG_CACHE_L2X0
ldr r2, =L2_BASE_ADDR
@@ -1084,11 +1602,11 @@ restore control register to enable cache
#endif
mov r8, lr
- push {r0}
+ push {r0-r3, r12}
/* Set up the per-CPU stacks */
bl cpu_init
- pop {r0}
+ pop {r0-r3, r12}
/*
* Restore the MMU table entry that was modified for
diff --git a/arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c b/arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c
index 134700a6d200..5cf34073bdc1 100644
--- a/arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c
+++ b/arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c
@@ -40,13 +40,13 @@
#define PFUZE100_I2C_ADDR (0x08)
/*SWBST*/
#define PFUZE100_SW1ASTANDBY 33
-#define PFUZE100_SW1ASTANDBY_STBY_VAL (0x16)
+#define PFUZE100_SW1ASTANDBY_STBY_VAL (0x19) /* 925mV */
#define PFUZE100_SW1ASTANDBY_STBY_M (0x3f<<0)
#define PFUZE100_SW1BSTANDBY 40
-#define PFUZE100_SW1BSTANDBY_STBY_VAL (0x16)
+#define PFUZE100_SW1BSTANDBY_STBY_VAL (0x19) /* 925mV */
#define PFUZE100_SW1BSTANDBY_STBY_M (0x3f<<0)
#define PFUZE100_SW1CSTANDBY 47
-#define PFUZE100_SW1CSTANDBY_STBY_VAL (0x16)
+#define PFUZE100_SW1CSTANDBY_STBY_VAL (0x19) /* 925mV */
#define PFUZE100_SW1CSTANDBY_STBY_M (0x3f<<0)
#define PFUZE100_SW2STANDBY 54
#define PFUZE100_SW2STANDBY_STBY_VAL 0x0
diff --git a/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c b/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c
index ee66541f8bff..981d149d7aee 100644
--- a/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c
+++ b/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c
@@ -40,13 +40,13 @@
#define PFUZE100_I2C_ADDR (0x08)
/*SWBST*/
#define PFUZE100_SW1ASTANDBY 33
-#define PFUZE100_SW1ASTANDBY_STBY_VAL (0x16)
+#define PFUZE100_SW1ASTANDBY_STBY_VAL (0x19) /* 925mv */
#define PFUZE100_SW1ASTANDBY_STBY_M (0x3f<<0)
#define PFUZE100_SW1BSTANDBY 40
-#define PFUZE100_SW1BSTANDBY_STBY_VAL (0x16)
+#define PFUZE100_SW1BSTANDBY_STBY_VAL (0x19) /* 925mv */
#define PFUZE100_SW1BSTANDBY_STBY_M (0x3f<<0)
#define PFUZE100_SW1CSTANDBY 47
-#define PFUZE100_SW1CSTANDBY_STBY_VAL (0x16)
+#define PFUZE100_SW1CSTANDBY_STBY_VAL (0x19) /* 925mv */
#define PFUZE100_SW1CSTANDBY_STBY_M (0x3f<<0)
#define PFUZE100_SW2STANDBY 54
#define PFUZE100_SW2STANDBY_STBY_VAL 0x0
@@ -143,7 +143,7 @@ static struct regulator_consumer_supply vgen5_consumers[] = {
};
static struct regulator_consumer_supply vgen6_consumers[] = {
{
- .supply = "VGEN6_3V3",
+ .supply = "VGEN6_2V8",
}
};
diff --git a/arch/arm/mach-mx6/mx6sl_wfi.S b/arch/arm/mach-mx6/mx6sl_wfi.S
index 89fe4e292352..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,13 +50,16 @@
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 */
@@ -70,12 +67,6 @@
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 */
str r6, [r1, #0x5d4] /* GPR_B2DS */
@@ -93,11 +84,35 @@
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
+ * configuration of many DDR IO pads.
+ */
+ /* reset read FIFO, RST_RD_FIFO */
+ ldr r7, =0x83c
+ ldr r6, [r8, r7]
+ orr r6, r6, #0x80000000
+ str r6, [r8, r7]
+fifo_reset1_wait:
+ ldr r6, [r8, r7]
+ and r6, r6, #0x80000000
+ cmp r6, #0
+ bne fifo_reset1_wait
+
+ /* reset FIFO a second time */
+ ldr r6, [r8, r7]
+ orr r6, r6, #0x80000000
+ str r6, [r8, r7]
+fifo_reset2_wait:
+ ldr r6, [r8, r7]
+ and r6, r6, #0x80000000
+ cmp r6, #0
+ bne fifo_reset2_wait
.endm
@@ -109,18 +124,6 @@
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 */
@@ -235,15 +238,53 @@ mmdc_podf:
/* Set the DDR IO in LPM state. */
sl_ddr_io_set_lpm
- /* Set AHB to 8MHz., AXI to 3MHz */
- /* We want to ensure IPG_PERCLK to AHB
- * clk ratio is 1:2.5
+ /* Check if none of the PLLs are
+ * locked, except PLL1 which will get
+ * bypassed below.
+ * We should not be here if PLL2 is not
+ * bypassed.
*/
- /* Store the AXI/AHB podfs. */
+ ldr r7, =1
+ /* USB1 PLL3 */
+ ldr r6, [r3, #0x10]
+ and r6, r6, #0x80000000
+ cmp r6, #0x80000000
+ beq no_analog_saving
+
+ /* USB2 PLL7 */
+ ldr r6, [r3, #0x20]
+ and r6, r6, #0x80000000
+ cmp r6, #0x80000000
+ beq no_analog_saving
+
+ /* Audio PLL4 */
+ ldr r6, [r3, #0x70]
+ and r6, r6, #0x80000000
+ cmp r6, #0x80000000
+ beq no_analog_saving
+
+ /* Video PLL5 */
+ ldr r6, [r3, #0xA0]
+ and r6, r6, #0x80000000
+ cmp r6, #0x80000000
+ beq no_analog_saving
+
+ /* ENET PLL8 */
+ ldr r6, [r3, #0xE0]
+ and r6, r6, #0x80000000
+ cmp r6, #0x80000000
+ beq no_analog_saving
+
+ b cont
+
+no_analog_saving:
+ ldr r7, =0
+
+cont:
+ /*Set the AHB to 3MHz. AXI to 3MHz. */
ldr r9, [r2, #0x14]
mov r6, r9
- bic r6, r6, #0x1c00
- orr r6, r6, #0x800
+ orr r6, r6, #0x1c00
orr r6, r6, #0x70000
str r6, [r2, #0x14]
@@ -271,7 +312,7 @@ ahb_podf:
str r6, [r3, #0x04]
/* Set the ARM PODF to divide by 8. */
- /* IPG is at 4MHz here, we need ARM to
+ /* IPG is at 1.5MHz here, we need ARM to
* run at the 12:5 ratio (WAIT mode issue).
*/
ldr r6, =0x7
@@ -283,9 +324,62 @@ podf_loop:
cmp r6, #0x0
bne podf_loop
- /* Now do WFI. */
- dsb
+ /* Check if we can save some
+ * in the Analog section.
+ */
+ cmp r7, #0x1
+ bne do_wfi
+
+ /* Disable 1p1 brown out. */
+ ldr r6, [r3, #0x110]
+ bic r6, r6, #0x2
+ str r6, [r3, #0x110]
+
+ /* Enable the weak 2P5 */
+ ldr r6, [r3, #0x130]
+ orr r6, r6, #0x40000
+ str r6, [r3, #0x130]
+
+ /*Disable main 2p5. */
+ ldr r6, [r3, #0x130]
+ bic r6, r6, #0x1
+ str r6, [r3, #0x130]
+
+ /* Set the OSC bias current to -37.5%
+ * to drop the power on VDDHIGH.
+ */
+ ldr r6, [r3, #0x150]
+ orr r6, r6, #0xC000
+ str r6, [r3, #0x150]
+
+ /* Enable low power bandgap */
+ ldr r6, [r3, #0x260]
+ orr r6, r6, #0x20
+ str r6, [r3, #0x260]
+ /* turn off the bias current
+ * from the regular bandgap.
+ */
+ ldr r6, [r3, #0x260]
+ orr r6, r6, #0x80
+ str r6, [r3, #0x260]
+
+ /* Clear the REFTOP_SELFBIASOFF,
+ * self-bias circuit of the band gap.
+ * Per RM, should be cleared when
+ * band gap is powered down.
+ */
+ ldr r6, [r3, #0x150]
+ bic r6, r6, #0x8
+ str r6, [r3, #0x150]
+
+ /*Power down the regular bandgap. */
+ ldr r6, [r3, #0x150]
+ orr r6, r6, #0x1
+ str r6, [r3, #0x150]
+
+do_wfi:
+ /* Now do WFI. */
wfi
/* Set original ARM PODF back. */
@@ -297,6 +391,60 @@ podf_loop1:
cmp r6, #0x0
bne podf_loop1
+ /* Check if powered down
+ * analog components.
+ */
+ cmp r7, #0x1
+ bne skip_analog_restore
+
+ /*Power up the regular bandgap. */
+ ldr r6, [r3, #0x150]
+ bic r6, r6, #0x1
+ str r6, [r3, #0x150]
+
+ /* turn on the bias current
+ * from the regular bandgap.
+ */
+ ldr r6, [r3, #0x260]
+ bic r6, r6, #0x80
+ str r6, [r3, #0x260]
+
+ /* Disable the low power bandgap */
+ ldr r6, [r3, #0x260]
+ bic r6, r6, #0x20
+ str r6, [r3, #0x260]
+
+ /* Set the OSC bias current to max
+ * value for normal operation.
+ */
+ ldr r6, [r3, #0x150]
+ bic r6, r6, #0xC000
+ str r6, [r3, #0x150]
+
+ /*Enable main 2p5. */
+ ldr r6, [r3, #0x130]
+ orr r6, r6, #0x1
+ str r6, [r3, #0x130]
+
+ /* Ensure the 2P5 is up. */
+loop_2p5:
+ ldr r6, [r3, #0x130]
+ and r6, r6, #0x20000
+ cmp r6, #0x20000
+ bne loop_2p5
+
+ /* Disable the weak 2P5 */
+ ldr r6, [r3, #0x130]
+ bic r6, r6, #0x40000
+ str r6, [r3, #0x130]
+
+ /* Enable 1p1 brown out. */
+ ldr r6, [r3, #0x110]
+ orr r6, r6, #0x2
+ str r6, [r3, #0x110]
+
+skip_analog_restore:
+
/* Power up PLL1 and un-bypass it. */
ldr r6, =(1 << 12)
str r6, [r3, #0x08]
diff --git a/arch/arm/mach-mx6/pm.c b/arch/arm/mach-mx6/pm.c
index 45b2e6fffbeb..b29c6f6ab0d3 100644
--- a/arch/arm/mach-mx6/pm.c
+++ b/arch/arm/mach-mx6/pm.c
@@ -72,8 +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 *gpu2d_core_clk;
static struct clk *pll3_usb_otg_main_clk;
static struct pm_platform_data *pm_data;
@@ -114,7 +112,6 @@ static u32 ccm_analog_pll3_480;
static u32 ccm_anadig_ana_misc2;
static bool usb_vbus_wakeup_enabled;
-
/*
* The USB VBUS wakeup should be disabled to avoid vbus wake system
* up due to vbus comparator is closed at weak 2p5 mode.
@@ -178,85 +175,6 @@ static void usb_power_up_handler(void)
}
}
-static void gpu_power_down(void)
-{
- int reg;
-
- /* enable power down request */
- reg = __raw_readl(gpc_base + GPC_PGC_GPU_PGCR_OFFSET);
- __raw_writel(reg | 0x1, gpc_base + GPC_PGC_GPU_PGCR_OFFSET);
- /* power down request */
- reg = __raw_readl(gpc_base + GPC_CNTR_OFFSET);
- __raw_writel(reg | 0x1, gpc_base + GPC_CNTR_OFFSET);
- /* disable clocks */
- __raw_writel(ccgr1 &
- ~MXC_CCM_CCGRx_CG12_MASK &
- ~MXC_CCM_CCGRx_CG13_MASK, MXC_CCM_CCGR1);
- __raw_writel(ccgr3 & ~MXC_CCM_CCGRx_CG15_MASK, MXC_CCM_CCGR3);
- __raw_writel(ccgr6 & ~MXC_CCM_CCGRx_CG7_MASK, MXC_CCM_CCGR6);
- /* power off pu */
- reg = __raw_readl(anatop_base + ANATOP_REG_CORE_OFFSET);
- reg &= ~0x0003fe00;
- __raw_writel(reg, anatop_base + ANATOP_REG_CORE_OFFSET);
-}
-
-static void gpu_power_up(void)
-{
- int reg;
- int i;
- /* power on pu */
- reg = __raw_readl(anatop_base + ANATOP_REG_CORE_OFFSET);
- reg &= ~0x0003fe00;
- reg |= 0x10 << 9; /* 1.1v */
- __raw_writel(reg, anatop_base + ANATOP_REG_CORE_OFFSET);
- mdelay(10);
-
- /* enable clocks */
- /* PLL2 PFD0 and PFD1 clock enable */
- __raw_writel(ccm_analog_pfd528 &
- ~ANADIG_PFD0_CLKGATE &
- ~ANADIG_PFD1_CLKGATE, PFD_528_BASE_ADDR);
-
- /* PLL3 480M clock enable which may be used by gpu2d*/
- if (clk_get_parent(gpu2d_core_clk) == pll3_usb_otg_main_clk) {
- __raw_writel(ccm_analog_pll3_480 |
- ANADIG_PLL_POWER_DOWN, PLL3_480_USB1_BASE_ADDR);
- __raw_writel(ccm_anadig_ana_misc2 &
- (~BM_ANADIG_ANA_MISC2_CONTROL0),
- MXC_PLL_BASE + HW_ANADIG_ANA_MISC2);
- for (i = 0; i < 100; i++) {
- if (!(__raw_readl(PLL3_480_USB1_BASE_ADDR) & ANADIG_PLL_LOCK))
- udelay(1);
- else
- break;
- }
- __raw_writel((ccm_analog_pll3_480 & (~ANADIG_PLL_BYPASS)) |
- ANADIG_PLL_ENABLE | ANADIG_PLL_POWER_DOWN,
- PLL3_480_USB1_BASE_ADDR);
- }
- /* gpu3d and gpu2d clock enable */
- __raw_writel(ccgr1 |
- MXC_CCM_CCGRx_CG12_MASK |
- MXC_CCM_CCGRx_CG13_MASK, MXC_CCM_CCGR1);
- /* tzasrc1 clock enable for gpu3d core clock */
- __raw_writel(ccgr2 | MXC_CCM_CCGRx_CG11_MASK, MXC_CCM_CCGR2);
- /* openvgaxi clock enable, mmdc_core_ipg_clk_p0 clock and
- mmdc_core_aclk_fast_core_p0 clock enable for gpu3d core clock */
- __raw_writel(ccgr3 |
- MXC_CCM_CCGRx_CG15_MASK |
- MXC_CCM_CCGRx_CG12_MASK |
- MXC_CCM_CCGRx_CG10_MASK, MXC_CCM_CCGR3);
- /* vpu clock enable */
- __raw_writel(ccgr6 | MXC_CCM_CCGRx_CG7_MASK, MXC_CCM_CCGR6);
-
- /* enable power up request */
- reg = __raw_readl(gpc_base + GPC_PGC_GPU_PGCR_OFFSET);
- __raw_writel(reg | 0x1, gpc_base + GPC_PGC_GPU_PGCR_OFFSET);
- /* power up request */
- reg = __raw_readl(gpc_base + GPC_CNTR_OFFSET);
- __raw_writel(reg | 0x2, gpc_base + GPC_CNTR_OFFSET);
- udelay(10);
-}
static void disp_power_down(void)
{
@@ -266,12 +184,32 @@ static void disp_power_down(void)
__raw_writel(0x1, gpc_base + GPC_PGC_DISP_PGCR_OFFSET);
__raw_writel(0x10, gpc_base + GPC_CNTR_OFFSET);
+
+ /* Disable EPDC/LCDIF pix clock, and EPDC/LCDIF/PXP axi clock */
+ __raw_writel(ccgr3 &
+ ~MXC_CCM_CCGRx_CG5_MASK &
+ ~MXC_CCM_CCGRx_CG4_MASK &
+ ~MXC_CCM_CCGRx_CG3_MASK &
+ ~MXC_CCM_CCGRx_CG2_MASK &
+ ~MXC_CCM_CCGRx_CG1_MASK, MXC_CCM_CCGR3);
+
}
}
static void disp_power_up(void)
{
if (cpu_is_mx6sl()) {
+ /*
+ * Need to enable EPDC/LCDIF pix clock, and
+ * EPDC/LCDIF/PXP axi clock before power up.
+ */
+ __raw_writel(ccgr3 |
+ MXC_CCM_CCGRx_CG5_MASK |
+ MXC_CCM_CCGRx_CG4_MASK |
+ MXC_CCM_CCGRx_CG3_MASK |
+ MXC_CCM_CCGRx_CG2_MASK |
+ MXC_CCM_CCGRx_CG1_MASK, MXC_CCM_CCGR3);
+
__raw_writel(0x0, gpc_base + GPC_PGC_DISP_PGCR_OFFSET);
__raw_writel(0x20, gpc_base + GPC_CNTR_OFFSET);
__raw_writel(0x1, gpc_base + GPC_PGC_DISP_SR_OFFSET);
@@ -343,6 +281,7 @@ static int mx6_suspend_enter(suspend_state_t state)
unsigned int cpu_type;
struct gic_dist_state gds;
struct gic_cpu_state gcs;
+ bool arm_pg = false;
if (cpu_is_mx6q())
cpu_type = MXC_CPU_MX6Q;
@@ -377,21 +316,24 @@ static int mx6_suspend_enter(suspend_state_t state)
switch (state) {
case PM_SUSPEND_MEM:
- gpu_power_down();
disp_power_down();
usb_power_down_handler();
mxc_cpu_lp_set(ARM_POWER_OFF);
+ arm_pg = true;
break;
case PM_SUSPEND_STANDBY:
- mxc_cpu_lp_set(STOP_POWER_OFF);
+ if (cpu_is_mx6sl()) {
+ disp_power_down();
+ usb_power_down_handler();
+ mxc_cpu_lp_set(STOP_XTAL_ON);
+ arm_pg = true;
+ } else
+ mxc_cpu_lp_set(STOP_POWER_OFF);
break;
default:
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();
@@ -399,7 +341,7 @@ static int mx6_suspend_enter(suspend_state_t state)
local_flush_tlb_all();
flush_cache_all();
- if (state == PM_SUSPEND_MEM) {
+ if (arm_pg) {
/* preserve gic state */
save_gic_dist_state(0, &gds);
save_gic_cpu_state(0, &gcs);
@@ -408,23 +350,50 @@ static int mx6_suspend_enter(suspend_state_t state)
suspend_in_iram(state, (unsigned long)iram_paddr,
(unsigned long)suspend_iram_base, cpu_type);
- if (state == PM_SUSPEND_MEM) {
+ /* 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);
restore_gic_cpu_state(0, &gcs);
+ }
+ if (state == PM_SUSPEND_MEM || (cpu_is_mx6sl())) {
usb_power_up_handler();
disp_power_up();
- gpu_power_up();
}
mx6_suspend_restore();
+ __raw_writel(BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG,
+ anatop_base + HW_ANADIG_ANA_MISC0_CLR);
+
if (pm_data && pm_data->suspend_exit)
pm_data->suspend_exit();
} else {
cpu_do_idle();
}
- clk_set_parent(axi_clk, axi_org_parent);
return 0;
}
@@ -517,10 +486,10 @@ static int __init pm_init(void)
suspend_set_ops(&mx6_suspend_ops);
/* Move suspend routine into iRAM */
- cpaddr = (unsigned long)iram_alloc(SZ_4K, &iram_paddr);
+ cpaddr = (unsigned long)iram_alloc(SZ_8K, &iram_paddr);
/* Need to remap the area here since we want the memory region
to be executable. */
- suspend_iram_base = __arm_ioremap(iram_paddr, SZ_4K,
+ suspend_iram_base = __arm_ioremap(iram_paddr, SZ_8K,
MT_MEMORY_NONCACHED);
pr_info("cpaddr = %x suspend_iram_base=%x\n",
(unsigned int)cpaddr, (unsigned int)suspend_iram_base);
@@ -529,7 +498,7 @@ static int __init pm_init(void)
* Need to run the suspend code from IRAM as the DDR needs
* to be put into low power mode manually.
*/
- memcpy((void *)cpaddr, mx6_suspend, SZ_4K);
+ memcpy((void *)cpaddr, mx6_suspend, SZ_8K);
suspend_in_iram = (void *)suspend_iram_base;
@@ -548,11 +517,6 @@ static int __init pm_init(void)
printk(KERN_DEBUG "%s: failed to get periph_clk\n", __func__);
return PTR_ERR(periph_clk);
}
- gpu2d_core_clk = clk_get(NULL, "gpu2d_clk");
- if (IS_ERR(gpu2d_core_clk)) {
- printk(KERN_DEBUG "%s: failed to get gpu2d_clk\n", __func__);
- return PTR_ERR(periph_clk);
- }
pll3_usb_otg_main_clk = clk_get(NULL, "pll3_main_clk");
if (IS_ERR(pll3_usb_otg_main_clk)) {
printk(KERN_DEBUG "%s: failed to get pll3_main_clk\n", __func__);
diff --git a/arch/arm/mach-mx6/system.c b/arch/arm/mach-mx6/system.c
index 800c7cc4e8bd..6ecd51e9f9ea 100644
--- a/arch/arm/mach-mx6/system.c
+++ b/arch/arm/mach-mx6/system.c
@@ -51,6 +51,7 @@
extern unsigned int gpc_wake_irq[4];
static void __iomem *gpc_base = IO_ADDRESS(GPC_BASE_ADDR);
+extern struct clk *mmdc_ch0_axi;
volatile unsigned int num_cpu_idle;
volatile unsigned int num_cpu_idle_lock = 0x0;
@@ -85,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);
@@ -132,8 +133,16 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
stop_mode = 2;
}
break;
- case STOP_POWER_ON:
+ case STOP_XTAL_ON:
ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
+ ccm_clpcr |= MXC_CCM_CLPCR_VSTBY;
+ ccm_clpcr &= ~MXC_CCM_CLPCR_SBYOS;
+ if (cpu_is_mx6sl()) {
+ ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH0_LPM_HS;
+ ccm_clpcr |= MXC_CCM_CLPCR_BYPASS_PMIC_VFUNC_READY;
+ } else
+ ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH1_LPM_HS;
+ stop_mode = 3;
break;
default:
@@ -144,9 +153,16 @@ 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);
- if (stop_mode == 2) {
+ /* 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);
if (cpu_is_mx6q() || cpu_is_mx6dl()) {
@@ -171,38 +187,40 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
HW_ANADIG_REG_CORE);
}
} else {
- /* Disable VDDHIGH_IN to VDDSNVS_IN power path,
- * only used when VDDSNVS_IN is powered by dedicated
- * power rail */
- anatop_val = __raw_readl(anatop_base +
- HW_ANADIG_ANA_MISC0);
- anatop_val |= BM_ANADIG_ANA_MISC0_RTC_RINGOSC_EN;
- __raw_writel(anatop_val, anatop_base +
- HW_ANADIG_ANA_MISC0);
- /* We need to allow the memories to be clock gated
- * in STOP mode, else the power consumption will
- * be very high. */
- reg = __raw_readl(MXC_CCM_CGPR);
- reg |= MXC_CCM_CGPR_MEM_IPG_STOP_MASK;
- __raw_writel(reg, MXC_CCM_CGPR);
+ if (stop_mode == 2) {
+ /* Disable VDDHIGH_IN to VDDSNVS_IN
+ * power path, only used when VDDSNVS_IN
+ * is powered by dedicated
+ * power rail */
+ anatop_val = __raw_readl(anatop_base +
+ HW_ANADIG_ANA_MISC0);
+ anatop_val |= BM_ANADIG_ANA_MISC0_RTC_RINGOSC_EN;
+ __raw_writel(anatop_val, anatop_base +
+ HW_ANADIG_ANA_MISC0);
+ /* Need to enable pull down if 2P5 is disabled */
+ anatop_val = __raw_readl(anatop_base +
+ HW_ANADIG_REG_2P5);
+ anatop_val |= BM_ANADIG_REG_2P5_ENABLE_PULLDOWN;
+ __raw_writel(anatop_val, anatop_base +
+ 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)
+ 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);
+ /* Reconfigure WB, need to set WB counter
+ * to 0x7 to make sure it work normally */
__raw_writel(__raw_readl(MXC_CCM_CCR) |
- MXC_CCM_CCR_RBC_EN, MXC_CCM_CCR);
-
- /* 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 */
- __raw_writel(__raw_readl(MXC_CCM_CCR) |
- (0x1 << MXC_CCM_CCR_WB_COUNT_OFFSET) |
- (0x20 << MXC_CCM_CCR_REG_BYPASS_CNT_OFFSET), MXC_CCM_CCR);
-
- /* Set WB_PER enable */
- ccm_clpcr |= MXC_CCM_CLPCR_WB_PER_AT_LPM;
+ (0x7 << MXC_CCM_CCR_WB_COUNT_OFFSET),
+ MXC_CCM_CCR);
+
+ /* Set WB_PER enable */
+ ccm_clpcr |= MXC_CCM_CLPCR_WB_PER_AT_LPM;
+ }
}
if (cpu_is_mx6sl() ||
(mx6q_revision() > IMX_CHIP_REVISION_1_1) ||
@@ -253,7 +271,12 @@ void arch_idle_single_core(void)
ca9_do_idle();
} else {
if (low_bus_freq_mode || audio_bus_freq_mode) {
- if (cpu_is_mx6sl() && low_bus_freq_mode) {
+ 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
+ && ddr_usecount == 1) {
/* In this mode PLL2 i already in bypass,
* ARM is sourced from PLL1. The code in IRAM
* will set ARM to be sourced from STEP_CLK
@@ -272,17 +295,41 @@ void arch_idle_single_core(void)
* is at 12MHz. This is valid for audio mode on
* MX6SL, and all low power modes on MX6DLS.
*/
- /* PLL1_SW_CLK is sourced from PLL2_PFD2400MHz
- * at this point. Move it to bypassed PLL1.
- */
- reg = __raw_readl(MXC_CCM_CCSR);
- reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
- __raw_writel(reg, MXC_CCM_CCSR);
-
+ if (cpu_is_mx6sl() && low_bus_freq_mode) {
+ /* ARM is from PLL1, need to switch to
+ * STEP_CLK sourced from 24MHz.
+ */
+ /* Swtich STEP_CLK to 24MHz. */
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg &= ~MXC_CCM_CCSR_STEP_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+ /* Set PLL1_SW_CLK to be from
+ *STEP_CLK.
+ */
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+
+ } else {
+ /* PLL1_SW_CLK is sourced from
+ * PLL2_PFD2_400MHz at this point.
+ * Move it to bypassed PLL1.
+ */
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+ }
ca9_do_idle();
- reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
- __raw_writel(reg, MXC_CCM_CCSR);
+ if (cpu_is_mx6sl() && low_bus_freq_mode) {
+ /* Set PLL1_SW_CLK to be from PLL1 */
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+ } else {
+ reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+ }
}
} else {
/*
diff --git a/arch/arm/mach-mx6/usb.h b/arch/arm/mach-mx6/usb.h
index 6914246826f6..f796e7dad87c 100644
--- a/arch/arm/mach-mx6/usb.h
+++ b/arch/arm/mach-mx6/usb.h
@@ -30,9 +30,6 @@ extern void gpio_usbotg_utmi_inactive(void);
extern void __init mx6_usb_dr_init(void);
extern bool usb_icbug_swfix_need(void);
-extern int usb_stop_mode_refcount(bool enable);
-extern void usb_stop_mode_lock(void);
-extern void usb_stop_mode_unlock(void);
extern void __init mx6_usb_h2_init(void);
extern void __init mx6_usb_h3_init(void);
diff --git a/arch/arm/mach-mx6/usb_dr.c b/arch/arm/mach-mx6/usb_dr.c
index 8fe9700a658f..7b79d98c7d5c 100644
--- a/arch/arm/mach-mx6/usb_dr.c
+++ b/arch/arm/mach-mx6/usb_dr.c
@@ -173,9 +173,6 @@ static int usb_phy_enable(struct fsl_usb2_platform_data *pdata)
static int usbotg_init_ext(struct platform_device *pdev)
{
struct clk *usb_clk;
-#ifdef CONFIG_USB_EHCI_ARC_OTG
- void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
-#endif
u32 ret;
/* at mx6q: this clock is AHB clock for usb core */
@@ -201,12 +198,6 @@ static int usbotg_init_ext(struct platform_device *pdev)
mdelay(3);
}
otg_used++;
-#ifdef CONFIG_USB_EHCI_ARC_OTG
- usb_stop_mode_lock();
- if (usb_stop_mode_refcount(true) == 1)
- __raw_writel(BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG, anatop_base_addr + HW_ANADIG_ANA_MISC0_SET);
- usb_stop_mode_unlock();
-#endif
return ret;
}
@@ -214,9 +205,6 @@ static int usbotg_init_ext(struct platform_device *pdev)
static void usbotg_uninit_ext(struct platform_device *pdev)
{
struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
-#ifdef CONFIG_USB_EHCI_ARC_OTG
- void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
-#endif
clk_disable(usb_phy1_clk);
clk_put(usb_phy1_clk);
@@ -226,12 +214,6 @@ static void usbotg_uninit_ext(struct platform_device *pdev)
usbotg_uninit(pdata);
otg_used--;
-#ifdef CONFIG_USB_EHCI_ARC_OTG
- usb_stop_mode_lock();
- if (usb_stop_mode_refcount(false) == 0)
- __raw_writel(BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG, anatop_base_addr + HW_ANADIG_ANA_MISC0_CLR);
- usb_stop_mode_unlock();
-#endif
}
static void usbotg_clock_gate(bool on)
@@ -247,6 +229,13 @@ static void usbotg_clock_gate(bool on)
pr_debug("usb_oh3_clk:%d, usb_phy_clk1_ref_count:%d\n", clk_get_usecount(usb_oh3_clk), clk_get_usecount(usb_phy1_clk));
}
+static void dr_platform_phy_power_on(void)
+{
+ void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
+ __raw_writel(BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG,
+ anatop_base_addr + HW_ANADIG_ANA_MISC0_SET);
+}
+
void mx6_set_otghost_vbus_func(driver_vbus_func driver_vbus)
{
dr_utmi_config.platform_driver_vbus = driver_vbus;
@@ -643,6 +632,7 @@ void __init mx6_usb_dr_init(void)
dr_utmi_config.is_wakeup_event = _is_host_wakeup;
dr_utmi_config.wakeup_pdata = &dr_wakeup_config;
dr_utmi_config.wakeup_handler = host_wakeup_handler;
+ dr_utmi_config.platform_phy_power_on = dr_platform_phy_power_on;
pdev = imx6q_add_fsl_ehci_otg(&dr_utmi_config);
dr_wakeup_config.usb_pdata[1] = pdev->dev.platform_data;
#endif
@@ -657,6 +647,7 @@ void __init mx6_usb_dr_init(void)
dr_utmi_config.wakeup_pdata = &dr_wakeup_config;
dr_utmi_config.wakeup_handler = device_wakeup_handler;
dr_utmi_config.charger_base_addr = anatop_base_addr;
+ dr_utmi_config.platform_phy_power_on = dr_platform_phy_power_on;
pdev = imx6q_add_fsl_usb2_udc(&dr_utmi_config);
dr_wakeup_config.usb_pdata[2] = pdev->dev.platform_data;
#endif
diff --git a/arch/arm/mach-mx6/usb_h1.c b/arch/arm/mach-mx6/usb_h1.c
index bece29f7d44b..f86a4f42b0bd 100644
--- a/arch/arm/mach-mx6/usb_h1.c
+++ b/arch/arm/mach-mx6/usb_h1.c
@@ -90,6 +90,13 @@ static void usbh1_internal_phy_clock_gate(bool on)
}
}
+static void usbh1_platform_phy_power_on(void)
+{
+ void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
+ __raw_writel(BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG,
+ anatop_base_addr + HW_ANADIG_ANA_MISC0_SET);
+}
+
static int usb_phy_enable(struct fsl_usb2_platform_data *pdata)
{
u32 tmp;
@@ -134,7 +141,6 @@ static int fsl_usb_host_init_ext(struct platform_device *pdev)
{
int ret;
struct clk *usb_clk;
- void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
usb_clk = clk_get(NULL, "usboh3_clk");
clk_enable(usb_clk);
usb_oh3_clk = usb_clk;
@@ -146,25 +152,19 @@ static int fsl_usb_host_init_ext(struct platform_device *pdev)
}
usbh1_internal_phy_clock_gate(true);
usb_phy_enable(pdev->dev.platform_data);
- usb_stop_mode_lock();
- if (usb_stop_mode_refcount(true) == 1)
- __raw_writel(BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG, anatop_base_addr + HW_ANADIG_ANA_MISC0_SET);
- usb_stop_mode_unlock();
+
return 0;
}
static void fsl_usb_host_uninit_ext(struct platform_device *pdev)
{
struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
- void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
+
fsl_usb_host_uninit(pdata);
clk_disable(usb_oh3_clk);
clk_put(usb_oh3_clk);
- usb_stop_mode_lock();
- if (usb_stop_mode_refcount(false) == 0)
- __raw_writel(BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG, anatop_base_addr + HW_ANADIG_ANA_MISC0_CLR);
- usb_stop_mode_unlock();
+
}
static void usbh1_clock_gate(bool on)
@@ -374,6 +374,7 @@ static struct fsl_usb2_platform_data usbh1_config = {
.phy_lowpower_suspend = _phy_lowpower_suspend,
.is_wakeup_event = _is_usbh1_wakeup,
.wakeup_handler = h1_wakeup_handler,
+ .platform_phy_power_on = usbh1_platform_phy_power_on,
.transceiver = "utmi",
.phy_regs = USB_PHY1_BASE_ADDR,
};
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
*
diff --git a/arch/arm/plat-mxc/cpufreq.c b/arch/arm/plat-mxc/cpufreq.c
index e7278d9501a5..cc26b7adbc76 100755
--- a/arch/arm/plat-mxc/cpufreq.c
+++ b/arch/arm/plat-mxc/cpufreq.c
@@ -95,15 +95,19 @@ int set_cpu_freq(int freq)
ret = regulator_set_voltage(soc_regulator, soc_volt,
soc_volt);
if (ret < 0) {
- printk(KERN_DEBUG "COULD NOT SET SOC VOLTAGE!!!!\n");
+ printk(KERN_DEBUG
+ "COULD NOT SET SOC VOLTAGE!!!!\n");
return ret;
}
}
- if (!IS_ERR(pu_regulator)) {
+ /*if pu_regulator is enabled, it will be tracked with VDDARM*/
+ if (!IS_ERR(pu_regulator) &&
+ regulator_is_enabled(pu_regulator)) {
ret = regulator_set_voltage(pu_regulator, pu_volt,
pu_volt);
if (ret < 0) {
- printk(KERN_DEBUG "COULD NOT SET PU VOLTAGE!!!!\n");
+ printk(KERN_DEBUG
+ "COULD NOT SET PU VOLTAGE!!!!\n");
return ret;
}
}
@@ -132,15 +136,19 @@ int set_cpu_freq(int freq)
ret = regulator_set_voltage(soc_regulator, soc_volt,
soc_volt);
if (ret < 0) {
- printk(KERN_DEBUG "COULD NOT SET SOC VOLTAGE BACK!!!!\n");
+ printk(KERN_DEBUG
+ "COULD NOT SET SOC VOLTAGE BACK!!!!\n");
return ret;
}
}
- if (!IS_ERR(pu_regulator)) {
+ /*if pu_regulator is enabled, it will be tracked with VDDARM*/
+ if (!IS_ERR(pu_regulator) &&
+ regulator_is_enabled(pu_regulator)) {
ret = regulator_set_voltage(pu_regulator, pu_volt,
pu_volt);
if (ret < 0) {
- printk(KERN_DEBUG "COULD NOT SET PU VOLTAGE!!!!\n");
+ printk(KERN_DEBUG
+ "COULD NOT SET PU VOLTAGE!!!!\n");
return ret;
}
}
diff --git a/arch/arm/plat-mxc/devices/Kconfig b/arch/arm/plat-mxc/devices/Kconfig
index bdea66b7a1f4..2e666bac3afd 100755
--- a/arch/arm/plat-mxc/devices/Kconfig
+++ b/arch/arm/plat-mxc/devices/Kconfig
@@ -185,3 +185,6 @@ config IMX_HAVE_PLATFORM_IMX_VDOA
config IMX_HAVE_PLATFORM_IMX_PCIE
bool
+
+config IMX_HAVE_PLATFORM_IMX_FSL_CSI
+ bool
diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile
index 41287783cb80..102eeaaff38b 100755
--- a/arch/arm/plat-mxc/devices/Makefile
+++ b/arch/arm/plat-mxc/devices/Makefile
@@ -66,4 +66,5 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_DSI) += platform-imx-mipi_dsi.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_CSI2) += platform-imx-mipi_csi2.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_VDOA) += platform-imx-vdoa.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_PCIE) += platform-imx-pcie.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_FSL_CSI) += platform-imx-fsl-csi.o
obj-y += platform-imx-pmu.o
diff --git a/arch/arm/plat-mxc/devices/platform-dma.c b/arch/arm/plat-mxc/devices/platform-dma.c
index b2cba3db6d6d..7f731954192e 100644
--- a/arch/arm/plat-mxc/devices/platform-dma.c
+++ b/arch/arm/plat-mxc/devices/platform-dma.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-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 version 2 as published by the
@@ -13,19 +13,19 @@
#include <mach/devices-common.h>
#ifdef CONFIG_SOC_IMX50
-const struct imx_dma_data imx50_dma_data __initconst = {
+const struct imx_dma_res_data imx50_dma_res_data __initconst = {
.iobase = MX50_APBHDMA_BASE_ADDR,
};
#endif
#ifdef CONFIG_SOC_IMX6Q
-const struct imx_dma_data imx6q_dma_data __initconst = {
+const struct imx_dma_res_data imx6q_dma_res_data __initconst = {
.iobase = APBH_DMA_ARB_BASE_ADDR,
};
#endif
struct platform_device *__init imx_add_dma(
- const struct imx_dma_data *data)
+ const struct imx_dma_res_data *data)
{
struct resource res[] = {
{
diff --git a/arch/arm/plat-mxc/devices/platform-imx-fsl-csi.c b/arch/arm/plat-mxc/devices/platform-imx-fsl-csi.c
new file mode 100644
index 000000000000..8b6601ccc5a0
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-fsl-csi.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_fsl_csi_data_entry_single(soc, size) \
+ { \
+ .iobase = soc ## _CSI_BASE_ADDR, \
+ .irq = soc ## _INT_CSI, \
+ .iosize = size, \
+ }
+
+#ifdef CONFIG_SOC_IMX6SL
+const struct imx_fsl_csi_data imx6sl_csi_data __initconst =
+ imx_fsl_csi_data_entry_single(MX6SL, SZ_16K);
+#endif
+
+struct platform_device *__init imx_add_fsl_csi(
+ const struct imx_fsl_csi_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("fsl_csi", -1,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
+
diff --git a/arch/arm/plat-mxc/devices/platform-imx-uart.c b/arch/arm/plat-mxc/devices/platform-imx-uart.c
index ecfadc3060ea..7f70dc9f8e07 100644
--- a/arch/arm/plat-mxc/devices/platform-imx-uart.c
+++ b/arch/arm/plat-mxc/devices/platform-imx-uart.c
@@ -137,6 +137,18 @@ const struct imx_imx_uart_1irq_data imx6q_imx_uart_data[] __initconst = {
};
#endif /* ifdef CONFIG_SOC_IMX6Q */
+#ifdef CONFIG_SOC_IMX6SL
+const struct imx_imx_uart_1irq_data imx6sl_imx_uart_data[] __initconst = {
+#define imx6sl_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX6SL, _id, _hwid, SZ_4K)
+ imx6sl_imx_uart_data_entry(0, 1),
+ imx6sl_imx_uart_data_entry(1, 2),
+ imx6sl_imx_uart_data_entry(2, 3),
+ imx6sl_imx_uart_data_entry(3, 4),
+ imx6sl_imx_uart_data_entry(4, 5),
+};
+#endif /* ifdef CONFIG_SOC_IMX6SL */
+
struct platform_device *__init imx_add_imx_uart_3irq(
const struct imx_imx_uart_3irq_data *data,
const struct imxuart_platform_data *pdata)
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,
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
index 99ef8abee1e3..1ff68bd8b6dd 100755
--- a/arch/arm/plat-mxc/include/mach/devices-common.h
+++ b/arch/arm/plat-mxc/include/mach/devices-common.h
@@ -25,10 +25,10 @@ static inline struct platform_device *imx_add_platform_device(
name, id, res, num_resources, data, size_data, 0);
}
-struct imx_dma_data {
+struct imx_dma_res_data {
resource_size_t iobase;
};
-struct platform_device *__init imx_add_dma(const struct imx_dma_data *data);
+struct platform_device *__init imx_add_dma(const struct imx_dma_res_data *data);
#include <linux/fec.h>
struct imx_fec_data {
@@ -690,3 +690,11 @@ struct platform_device *__init imx_add_pcie(
const struct imx_pcie_platform_data *pdata);
void __init imx_add_imx_armpmu(void);
+
+struct imx_fsl_csi_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_fsl_csi(
+ const struct imx_fsl_csi_data *data);
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx6sl.h b/arch/arm/plat-mxc/include/mach/iomux-mx6sl.h
index 296df42d3ef7..90de1dd8f4fb 100755
--- a/arch/arm/plat-mxc/include/mach/iomux-mx6sl.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx6sl.h
@@ -77,6 +77,9 @@
#define MX6SL_ADU_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
PAD_CTL_DSE_40ohm | PAD_CTL_PUS_100K_DOWN | \
PAD_CTL_HYS | PAD_CTL_SPEED_MED)
+#define MX6SL_CHG_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP)
+
#define MX6SL_PAD_AUD_MCLK 0x02A4
#define MX6SL_PAD_AUD_RXD 0x02AC
@@ -510,7 +513,7 @@
IOMUX_PAD(0x0364, 0x0074, 7, 0x0000, 0, NO_PAD_CTRL)
#define MX6SL_PAD_ECSPI2_MISO__GPIO_4_14 \
- IOMUX_PAD(0x0368, 0x0078, 5, 0x0000, 0, NO_PAD_CTRL)
+ IOMUX_PAD(0x0368, 0x0078, 5, 0x0000, 0, MX6SL_CHG_PAD_CTRL)
#define MX6SL_PAD_ECSPI2_MISO__USB_USBOTG1_OC \
IOMUX_PAD(0x0368, 0x0078, 6, 0x0824, 0, NO_PAD_CTRL)
#define MX6SL_PAD_ECSPI2_MISO__TPSMP_HDATA_23 \
@@ -541,7 +544,7 @@
#define MX6SL_PAD_ECSPI2_MOSI__USDHC1_VSELECT \
IOMUX_PAD(0x036C, 0x007C, 4, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
#define MX6SL_PAD_ECSPI2_MOSI__GPIO_4_13 \
- IOMUX_PAD(0x036C, 0x007C, 5, 0x0000, 0, NO_PAD_CTRL)
+ IOMUX_PAD(0x036C, 0x007C, 5, 0x0000, 0, MX6SL_CHG_PAD_CTRL)
#define MX6SL_PAD_ECSPI2_MOSI__ANATOP_ANATOP_TESTO_1 \
IOMUX_PAD(0x036C, 0x007C, 6, 0x0000, 0, NO_PAD_CTRL)
#define MX6SL_PAD_ECSPI2_MOSI__TPSMP_HDATA_22 \
@@ -579,7 +582,7 @@
#define MX6SL_PAD_ECSPI2_SS0__USDHC1_CD \
IOMUX_PAD(0x0374, 0x0084, 4, 0x0828, 0, MX6SL_USDHC_PAD_CTRL)
#define MX6SL_PAD_ECSPI2_SS0__GPIO_4_15 \
- IOMUX_PAD(0x0374, 0x0084, 5, 0x0000, 0, NO_PAD_CTRL)
+ IOMUX_PAD(0x0374, 0x0084, 5, 0x0000, 0, MX6SL_CHG_PAD_CTRL)
#define MX6SL_PAD_ECSPI2_SS0__USB_USBOTG1_PWR \
IOMUX_PAD(0x0374, 0x0084, 6, 0x0000, 0, NO_PAD_CTRL)
#define MX6SL_PAD_ECSPI2_SS0__PL301_SIM_MX6SL_PER1_HADDR_24 \
diff --git a/arch/arm/plat-mxc/include/mach/mx6.h b/arch/arm/plat-mxc/include/mach/mx6.h
index aaf8b998ca63..dfb3f6489cc1 100644
--- a/arch/arm/plat-mxc/include/mach/mx6.h
+++ b/arch/arm/plat-mxc/include/mach/mx6.h
@@ -77,7 +77,7 @@
#define MX6Q_IRAM_BASE_ADDR IRAM_BASE_ADDR
/* The last 4K is for cpu hotplug to workaround wdog issue*/
#define MX6Q_IRAM_SIZE (SZ_256K - SZ_4K)
-#define MX6DL_IRAM_SIZE (SZ_128K - SZ_4K)
+#define MX6DL_MX6SL_IRAM_SIZE (SZ_128K - SZ_4K)
/* Blocks connected via pl301periph */
#define ROMCP_ARB_BASE_ADDR 0x00000000
@@ -145,6 +145,7 @@
#define MX6SL_UART5_BASE_ADDR (ATZ1_BASE_ADDR + 0x18000) /* MX6SL */
#define UART1_BASE_ADDR (ATZ1_BASE_ADDR + 0x20000) /* slot 8 */
#define ESAI1_BASE_ADDR (ATZ1_BASE_ADDR + 0x24000) /* slot 9 */
+#define MX6SL_UART1_BASE_ADDR (ATZ1_BASE_ADDR + 0x20000) /* MX6SL */
#define MX6SL_UART2_BASE_ADDR (ATZ1_BASE_ADDR + 0x24000) /* MX6SL */
#define MX6Q_SSI1_BASE_ADDR (ATZ1_BASE_ADDR + 0x28000) /* slot 10 */
#define MX6Q_SSI2_BASE_ADDR (ATZ1_BASE_ADDR + 0x2C000) /* slot 11 */
@@ -215,6 +216,14 @@
/* ARM Cortex A9 MPCore Platform */
#define MX6Q_A9_PLATFRM_BASE (ARM_BASE_ADDR + 0x20000)
+/* ARM Cortex A9 PTM */
+#define MX6Q_PTM0_BASE_ADDR 0x0215C000
+#define MX6Q_PTM1_BASE_ADDR 0x0215D000
+#define MX6Q_PTM2_BASE_ADDR 0x0215E000
+#define MX6Q_PTM3_BASE_ADDR 0x0215F000
+#define MX6Q_FUNNEL_BASE_ADDR 0x02144000
+#define MX6Q_ETB_BASE_ADDR 0x02141000
+
#define MX6Q_PL301_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x0000)
#define MX6Q_USB_OTG_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4000)
#define MX6Q_USB_HS1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4200)
@@ -327,6 +336,7 @@
#define MX6SL_INT_SPDC 38
#define MX6Q_INT_IPU2_ERR 39
#define MX6DL_INT_CSI 39
+#define MX6SL_INT_CSI 39
#define MX6Q_INT_IPU2_SYN 40
#define MXC_INT_GPU3D_IRQ 41
#define MXC_INT_GPU2D_IRQ 42
@@ -474,6 +484,11 @@
#define MX6Q_INT_UART2 MXC_INT_UART2_ANDED
#define MX6Q_INT_UART3 MXC_INT_UART3_ANDED
#define MX6Q_INT_UART4 MXC_INT_UART4_ANDED
+#define MX6SL_INT_UART1 MXC_INT_UART1_ANDED
+#define MX6SL_INT_UART2 MXC_INT_UART2_ANDED
+#define MX6SL_INT_UART3 MXC_INT_UART3_ANDED
+#define MX6SL_INT_UART4 MXC_INT_UART4_ANDED
+#define MX6SL_INT_UART5 MXC_INT_UART5_ANDED
#define MX6Q_INT_FEC MXC_INT_ENET1
#define MX6Q_INT_DSI MXC_INT_DSI
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index 23159090ace8..4260d4a25c2c 100755
--- a/arch/arm/plat-mxc/include/mach/mxc.h
+++ b/arch/arm/plat-mxc/include/mach/mxc.h
@@ -266,8 +266,8 @@ enum mxc_cpu_pwr_mode {
WAIT_CLOCKED, /* wfi only */
WAIT_UNCLOCKED, /* WAIT */
WAIT_UNCLOCKED_POWER_OFF, /* WAIT + SRPG */
- STOP_POWER_ON, /* just STOP */
- STOP_POWER_OFF, /* STOP + SRPG */
+ STOP_XTAL_ON, /* STOP + SRPG + XTAL_ON*/
+ STOP_POWER_OFF, /* STOP + XTAL_OFF */
ARM_POWER_OFF, /* STOP + SRPG + ARM power off */
};
diff --git a/arch/arm/plat-mxc/usb_common.c b/arch/arm/plat-mxc/usb_common.c
index d85d8d663571..97d963a54a54 100755
--- a/arch/arm/plat-mxc/usb_common.c
+++ b/arch/arm/plat-mxc/usb_common.c
@@ -53,9 +53,7 @@ typedef void (*driver_vbus_func)(bool);
void __iomem *imx_otg_base;
static driver_vbus_func s_driver_vbus;
-static int stop_mode_refcount;
-DEFINE_MUTEX(usb_common_mutex);
EXPORT_SYMBOL(imx_otg_base);
#define MXC_NUMBER_USB_TRANSCEIVER 6
@@ -73,41 +71,6 @@ bool usb_icbug_swfix_need(void)
}
EXPORT_SYMBOL(usb_icbug_swfix_need);
-/*
- * The Mx6 phy sometimes work abnormally after system suspend/resume if the 1V1 is off.
- * So we should keep the 1V1 active during the system suspend if any USB host enabled.
- * Set stop_mode_config when any USB host enabled by default, it will impact on system power.
- * #define DISABLE_STOP_MODE will disable the feature.
- */
-#ifndef DISABLE_STOP_MODE
-int usb_stop_mode_refcount(bool enable)
-{
- if (enable)
- stop_mode_refcount++;
- else
- stop_mode_refcount--;
- return stop_mode_refcount;
-}
-#else
-int usb_stop_mode_refcount(bool enable)
-{
- return 0;
-}
-#endif
-EXPORT_SYMBOL(usb_stop_mode_refcount);
-
-void usb_stop_mode_lock(void)
-{
- mutex_lock(&usb_common_mutex);
-}
-EXPORT_SYMBOL(usb_stop_mode_lock);
-
-void usb_stop_mode_unlock(void)
-{
- mutex_unlock(&usb_common_mutex);
-}
-EXPORT_SYMBOL(usb_stop_mode_unlock);
-
void mx6_set_host1_vbus_func(driver_vbus_func driver_vbus)
{
s_driver_vbus = driver_vbus;
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;
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index e93c4ea1a1a8..9de94344a97f 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -32,6 +32,7 @@
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/dmaengine.h>
+#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/sdma.h>
@@ -278,6 +279,7 @@ struct sdma_channel {
enum dma_status status;
unsigned int chn_count;
unsigned int chn_real_count;
+ unsigned int irq_handling;
};
#define MAX_DMA_CHANNELS 32
@@ -324,6 +326,7 @@ struct sdma_engine {
struct dma_device dma_device;
struct clk *clk;
struct sdma_script_start_addrs *script_addrs;
+ spinlock_t irq_reg_lock;
};
#define SDMA_H_CONFIG_DSPDMA (1 << 12) /* indicates if the DSPDMA is used */
@@ -537,18 +540,33 @@ static void mxc_sdma_handle_channel(struct sdma_channel *sdmac)
static irqreturn_t sdma_int_handler(int irq, void *dev_id)
{
struct sdma_engine *sdma = dev_id;
- u32 stat;
+ struct sdma_channel *sdmac;
+ unsigned long flag;
+ int channel;
+ u32 stat, stat_bak;
+ spin_lock_irqsave(&sdma->irq_reg_lock, flag);
stat = readl_relaxed(sdma->regs + SDMA_H_INTR);
writel_relaxed(stat, sdma->regs + SDMA_H_INTR);
+ spin_unlock_irqrestore(&sdma->irq_reg_lock, flag);
+
+ stat_bak = stat;
+ while (stat_bak) {
+ channel = fls(stat_bak) - 1;
+ sdmac = &sdma->channel[channel];
+ sdmac->irq_handling = 1;
+ stat_bak &= ~(1 << channel);
+ }
while (stat) {
- int channel = fls(stat) - 1;
- struct sdma_channel *sdmac = &sdma->channel[channel];
+ channel = fls(stat) - 1;
+ sdmac = &sdma->channel[channel];
- mxc_sdma_handle_channel(sdmac);
+ if (sdmac->irq_handling)
+ mxc_sdma_handle_channel(sdmac);
stat &= ~(1 << channel);
+ sdmac->irq_handling = 0;
}
return IRQ_HANDLED;
@@ -878,6 +896,8 @@ static int sdma_request_channel(struct sdma_channel *sdmac)
sdmac->buf_tail = 0;
+ sdmac->irq_handling = 0;
+
return 0;
out:
@@ -973,11 +993,41 @@ static int sdma_alloc_chan_resources(struct dma_chan *chan)
return 0;
}
+static void sdma_irq_pending_check(struct sdma_channel *sdmac)
+{
+ struct sdma_engine *sdma = sdmac->sdma;
+ unsigned long flag;
+ u32 stat;
+
+ spin_lock_irqsave(&sdma->irq_reg_lock, flag);
+ stat = readl_relaxed(sdma->regs + SDMA_H_INTR);
+
+ /*Check if the current channel's IRQ hasn't been responded*/
+ if (stat & (1 << sdmac->channel)) {
+ /*Handle the irq manually*/
+ writel_relaxed(1 << sdmac->channel, sdma->regs + SDMA_H_INTR);
+ spin_unlock_irqrestore(&sdma->irq_reg_lock, flag);
+
+ /*Prevent irq_handler from doing handle_channel() again*/
+ sdmac->irq_handling = 0;
+ mxc_sdma_handle_channel(sdmac);
+ } else {
+ spin_unlock_irqrestore(&sdma->irq_reg_lock, flag);
+ }
+
+ /*Wait here until irq_handler's finished*/
+ while (sdmac->irq_handling)
+ udelay(100);
+}
+
static void sdma_free_chan_resources(struct dma_chan *chan)
{
struct sdma_channel *sdmac = to_sdma_chan(chan);
struct sdma_engine *sdma = sdmac->sdma;
+ /*Check if irq to the channel is still pending*/
+ sdma_irq_pending_check(sdmac);
+
sdma_disable_channel(sdmac);
if (sdmac->event_id0)
@@ -1449,6 +1499,8 @@ static int __init sdma_probe(struct platform_device *pdev)
dma_cap_set(DMA_SLAVE, sdma->dma_device.cap_mask);
dma_cap_set(DMA_CYCLIC, sdma->dma_device.cap_mask);
+ spin_lock_init(&sdma->irq_reg_lock);
+
INIT_LIST_HEAD(&sdma->dma_device.channels);
/* Initialize channel parameters */
for (i = 0; i < MAX_DMA_CHANNELS; i++) {
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index 162e6c3eb64d..e604cd7ae384 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -323,6 +323,7 @@ static int mxs_dma_alloc_chan_resources(struct dma_chan *chan)
/* the descriptor is ready */
async_tx_ack(&mxs_chan->desc);
+ clk_disable_unprepare(mxs_dma->clk);
return 0;
err_clk:
@@ -339,6 +340,7 @@ static void mxs_dma_free_chan_resources(struct dma_chan *chan)
struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
+ clk_prepare_enable(mxs_dma->clk);
mxs_dma_disable_chan(mxs_chan);
free_irq(mxs_chan->chan_irq, mxs_dma);
diff --git a/drivers/dma/pxp/pxp_dma_v2.c b/drivers/dma/pxp/pxp_dma_v2.c
index 87b8f558ae8c..b74f62cac032 100644
--- a/drivers/dma/pxp/pxp_dma_v2.c
+++ b/drivers/dma/pxp/pxp_dma_v2.c
@@ -264,6 +264,9 @@ static void pxp_set_ctrl(struct pxps *pxp)
case PXP_PIX_FMT_YUV422P:
fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV422;
break;
+ case PXP_PIX_FMT_UYVY:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__UYVY1P422;
+ break;
default:
fmt_ctrl = 0;
}
@@ -654,7 +657,7 @@ static void pxp_set_csc(struct pxps *pxp)
/* CSC1 - YUV->RGB */
__raw_writel(0x84ab01f0, pxp->base + HW_PXP_CSC1_COEF0);
- __raw_writel(0x01230204, pxp->base + HW_PXP_CSC1_COEF1);
+ __raw_writel(0x01980204, pxp->base + HW_PXP_CSC1_COEF1);
__raw_writel(0x0730079c, pxp->base + HW_PXP_CSC1_COEF2);
/* CSC2 - Bypass */
diff --git a/drivers/media/video/mxc/capture/Kconfig b/drivers/media/video/mxc/capture/Kconfig
index a7b14cb23b9b..243b888c0f4f 100644
--- a/drivers/media/video/mxc/capture/Kconfig
+++ b/drivers/media/video/mxc/capture/Kconfig
@@ -13,7 +13,7 @@ config VIDEO_MXC_EMMA_CAMERA
default y
config VIDEO_MXC_CSI_CAMERA
- tristate "MX25 CSI camera support"
+ tristate "CSI camera support"
depends on !VIDEO_MXC_EMMA_CAMERA
config VIDEO_MXC_CSI_DMA
@@ -116,6 +116,16 @@ config MXC_CAMERA_OV5640_MIPI
---help---
If you plan to use the ov5640 Camera with mipi interface in your MXC system, say Y here.
+config MXC_MIPI_CSI2_TVIN_ADV7280
+ tristate "Analog Devices adv7280 TV Decoder Input support using mipi-csi2"
+ depends on (!VIDEO_MXC_EMMA_CAMERA)
+ depends on ARCH_MX6Q
+ select MXC_MIPI_CSI2 if ARCH_MX6Q
+ select MXC_CAMERA_SENSOR_CLK
+ ---help---
+ If you plan to use the adv7280 device with mipi-csi2 interface
+ in your iMX6 system, say Y here.
+
config MXC_CAMERA_SENSOR_CLK
tristate "camera clock"
depends on !VIDEO_MXC_EMMA_CAMERA
diff --git a/drivers/media/video/mxc/capture/Makefile b/drivers/media/video/mxc/capture/Makefile
index bdef5b401485..7f8b168f6f5e 100644
--- a/drivers/media/video/mxc/capture/Makefile
+++ b/drivers/media/video/mxc/capture/Makefile
@@ -52,3 +52,6 @@ obj-$(CONFIG_MXC_CAMERA_OV8820_MIPI) += ov8820_camera_mipi.o
adv7180_tvin-objs := adv7180.o
obj-$(CONFIG_MXC_TVIN_ADV7180) += adv7180_tvin.o
+
+adv7280_tvin-objs := adv7280_mipi_tvin.o
+obj-$(CONFIG_MXC_MIPI_CSI2_TVIN_ADV7280) += adv7280_mipi_tvin.o
diff --git a/drivers/media/video/mxc/capture/adv7280_mipi_tvin.c b/drivers/media/video/mxc/capture/adv7280_mipi_tvin.c
new file mode 100644
index 000000000000..d4e1d2ddc16b
--- /dev/null
+++ b/drivers/media/video/mxc/capture/adv7280_mipi_tvin.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 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 adv7280_mipi_csi2_tvin.c
+ *
+ * @brief Analog Device adv7280 video decoder functions
+ *
+ * @ingroup Camera
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/fsl_devices.h>
+
+#define ADV7280_SAMPLE_SILICON 0x40
+#define ADV7280_PROD_SILICON 0x41
+/** ADV7280 register definitions */
+#define ADV7280_INPUT_CTL 0x00 /* Input Control */
+#define ADV7280_STATUS_1 0x10 /* Status #1 */
+#define ADV7280_BRIGHTNESS 0x0a /* Brightness */
+#define ADV7280_IDENT 0x11 /* IDENT */
+#define ADV7280_VSYNC_FIELD_CTL_1 0x31 /* VSYNC Field Control #1 */
+#define ADV7280_MANUAL_WIN_CTL 0x3d /* Manual Window Control */
+#define ADV7280_SD_SATURATION_CB 0xe3 /* SD Saturation Cb */
+#define ADV7280_SD_SATURATION_CR 0xe4 /* SD Saturation Cr */
+#define ADV7280_PM_REG 0x0f /* Power Management */
+#define ADV7280_ADI_CONTROL1 0x0E /* ADI Control 1 */
+/* adv7280 power management reset bit */
+#define ADV7280_PM_RESET_BIT 0x80
+/** adv7280 input video masks */
+#define ADV7280_INPUT_VIDEO_MASK 0x70 /* input video mask */
+#define ADV7280_PAL_MODE_BIT 0x40 /* PAL mode bit */
+#define ADV7280_PAL_M_MODE_BIT 0x20 /* PAL M mode bit */
+#define ADV7280_NTSC_MODE_BIT 0x00 /* NTSC mode bit */
+#define ADV7280_NTSC_4_43_MODE_BIT 0x10 /* NTSC 4.43 mode bit*/
+/** adv7280 voltages */
+#define ADV7280_VOLTAGE_ANALOG 2800000
+#define ADV7280_VOLTAGE_DIGITAL_CORE 1500000
+#define ADV7280_VOLTAGE_DIGITAL_IO 1800000
+
+struct reg_value {
+ u8 reg;
+ u8 value;
+ u8 mask;
+ u32 delay_ms;
+};
+
+struct adv7280_priv {
+ struct fsl_mxc_tvin_platform_data *pdata;
+ struct i2c_client *client;
+};
+
+/*!
+ * adv7280 initialization register structure
+ * registers are configured based on ADI RM
+ * 1st value = Register Address
+ * 2nd value = default value
+ * 3rd value = Register Mask
+ * 4th value = delay time to wait until next command
+ */
+
+static struct reg_value adv7280_init_params[] = {
+ {0x0F, 0x04, 0x00, 0}, /* exit power down mode, no pwrdwn line available
+ in imx6-AI use i2c powrdwn */
+ {0x00, 0x0E, 0x00, 0}, /* input control */
+ {0x03, 0x0C, 0x00, 0}, /* enable pixel and sync output drivers */
+ {0x04, 0x37, 0x00, 0}, /* enable SFL */
+ {0x13, 0x00, 0x00, 0}, /* enable INTRQ output driver */
+ {0x17, 0x41, 0x00, 0}, /* select SH1 */
+ {0x1D, 0x40, 0x00, 0}, /* enable LCC output driver */
+ {0x52, 0xC0, 0x00, 0}, /* ADI recommended*/
+ {0xFE, 0xA0, 0x00, 0}, /* set CSI-Tx slave address to 0xA0 */
+ {0x59, 0x15, 0x00, 0}, /* GPO control */
+};
+
+/*! Read one register from a ADV7280 i2c slave device.
+ * @param *reg register in the device we wish to access.
+ * @return 0 if success, an error code otherwise.
+ */
+static inline int adv7280_read_reg(struct adv7280_priv *adv7280, u8 reg)
+{
+ int ret;
+
+ ret = i2c_smbus_read_byte_data(adv7280->client, reg);
+ if (ret < 0) {
+ dev_dbg(&adv7280->client->dev, "%s:read reg error: reg=%2x\n",
+ __func__, reg);
+ }
+
+ return ret;
+}
+
+/*! Write one register from a ADV7280 i2c slave device.
+ * @param *reg register in the device we wish to access.
+ * @return 0 if success, an error code otherwise.
+ */
+static inline int adv7280_write_reg(struct adv7280_priv *adv7280,
+ u8 reg, u8 val)
+{
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(adv7280->client, reg, val);
+ if (ret < 0) {
+ dev_dbg(&adv7280->client->dev, "%s:write reg error: reg=%2x\n",
+ __func__, reg);
+ }
+
+ return ret;
+}
+
+/*! Write ADV7280 config paramater array
+ */
+static int adv7280_config(struct adv7280_priv *adv7280,
+ struct reg_value *config, int size) {
+ int i, ret;
+
+ for (i = 0; i < size; i++) {
+ pr_debug("%s[%d]: reg = 0x%02x, value = 0x%02x\n", __func__,
+ i, config[i].reg, config[i].value);
+ ret = adv7280_write_reg(adv7280, config[i].reg,
+ config[i].value | config[i].mask);
+ if (ret < 0) {
+ pr_err("%s: write error %x\n", __func__, ret);
+ return ret;
+ }
+
+ if (config[i].delay_ms)
+ msleep(config[i].delay_ms);
+ }
+
+ return 0;
+}
+
+/*!
+ * ADV7280 I2C probe function.
+ * Function set in i2c_driver struct.
+ * Called by insmod.
+ *
+ * @param *adapter I2C adapter descriptor.
+ * @return Error code indicating success or failure.
+ */
+static int adv7280_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int ret;
+ struct adv7280_priv *adv7280;
+
+ adv7280 = kzalloc(sizeof(struct adv7280_priv), GFP_KERNEL);
+ if (!adv7280)
+ return -ENOMEM;
+
+ adv7280->client = client;
+ adv7280->pdata = client->dev.platform_data;
+ i2c_set_clientdata(client, adv7280);
+
+ ret = adv7280_read_reg(adv7280, ADV7280_IDENT);
+ if (ret < 0) {
+ pr_err("%s: read id error %x\n", __func__, ret);
+ goto err;
+ }
+
+ if ((ret & ADV7280_SAMPLE_SILICON) != 0x40) {
+ pr_err("%s: device ADV7280 not found, ret = 0x%02x\n",
+ __func__, ret);
+ goto err;
+ }
+
+ pr_info("%s: device found, rev_id 0x%02x\n", __func__, ret);
+ /* select main register map */
+ ret = adv7280_write_reg(adv7280, ADV7280_ADI_CONTROL1, 0x00);
+ if (ret < 0) {
+ pr_err("%s: write error, select memory map %x\n",
+ __func__, ret);
+ goto err;
+ }
+
+ /* perform a device reset */
+ ret = adv7280_write_reg(adv7280, ADV7280_PM_REG,
+ ADV7280_PM_RESET_BIT);
+ if (ret < 0) {
+ pr_err("%s: write error, reset %x\n", __func__, ret);
+ goto err;
+ }
+ /* Wait 5ms reset time spec */
+ msleep(5);
+
+ /* Initial device configuration */
+ ret = adv7280_config(adv7280, adv7280_init_params,
+ ARRAY_SIZE(adv7280_init_params));
+ if (ret < 0) {
+ pr_err("%s: config device error %x\n", __func__, ret);
+ goto err;
+ }
+
+ return 0;
+err:
+ kfree(adv7280);
+ return ret;
+}
+
+static int adv7280_i2c_remove(struct i2c_client *i2c_client)
+{
+ struct adv7280_priv *adv7280 = i2c_get_clientdata(i2c_client);
+
+ kfree(adv7280);
+ return 0;
+}
+
+/*!
+ * adv7280_i2c_driver - i2c device identification
+ * This structure tells the I2C subsystem how to identify and support a
+ * given I2C device type.
+ */
+
+static const struct i2c_device_id adv7280_i2c_id[] = {
+ {"adv7280", 0},
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, adv7280_i2c_id);
+
+static struct i2c_driver adv7280_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "adv7280",
+ },
+ .probe = adv7280_i2c_probe,
+ .remove = adv7280_i2c_remove,
+ .id_table = adv7280_i2c_id,
+};
+
+/*!
+ * ADV7280 init function.:
+ * Called on insmod.
+ * @return Error code indicating success or failure.
+ */
+static __init int adv7280_init(void)
+{
+ int err;
+
+ err = i2c_add_driver(&adv7280_i2c_driver);
+
+ if (err < 0)
+ pr_err("%s: driver registration failed, error=%d\n",
+ __func__, err);
+
+ return err;
+}
+
+/*!
+ * ADV7280 cleanup function.
+ * Called on rmmod.
+ * @return Error code indicating success or failure.
+ */
+static void __exit adv7280_clean(void)
+{
+ i2c_del_driver(&adv7280_i2c_driver);
+}
+
+module_init(adv7280_init);
+module_exit(adv7280_clean);
+
+MODULE_AUTHOR("Freescale Semiconductor");
+MODULE_DESCRIPTION("adv7280 video decoder driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/mxc/capture/csi_v4l2_capture.c b/drivers/media/video/mxc/capture/csi_v4l2_capture.c
index eb824ddf5eb3..a0887b930ea4 100644
--- a/drivers/media/video/mxc/capture/csi_v4l2_capture.c
+++ b/drivers/media/video/mxc/capture/csi_v4l2_capture.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2009-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -15,7 +15,7 @@
* @file drivers/media/video/mxc/capture/csi_v4l2_capture.c
* This file is derived from mxc_v4l2_capture.c
*
- * @brief MX25 Video For Linux 2 driver
+ * @brief Video For Linux 2 capture driver
*
* @ingroup MXC_V4L2_CAPTURE
*/
@@ -61,6 +61,198 @@ static struct v4l2_int_device csi_v4l2_int_device = {
},
};
+/* Callback function triggered after PxP receives an EOF interrupt */
+static void pxp_dma_done(void *arg)
+{
+ struct pxp_tx_desc *tx_desc = to_tx_desc(arg);
+ struct dma_chan *chan = tx_desc->txd.chan;
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+ cam_data *cam = pxp_chan->client;
+
+ /* This call will signal wait_for_completion_timeout() */
+ complete(&cam->pxp_tx_cmpl);
+}
+
+static bool chan_filter(struct dma_chan *chan, void *arg)
+{
+ if (imx_dma_is_pxp(chan))
+ return true;
+ else
+ return false;
+}
+
+/* Function to request PXP DMA channel */
+static int pxp_chan_init(cam_data *cam)
+{
+ dma_cap_mask_t mask;
+ struct dma_chan *chan;
+
+ /* Request a free channel */
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+ dma_cap_set(DMA_PRIVATE, mask);
+ chan = dma_request_channel(mask, chan_filter, NULL);
+ if (!chan) {
+ pr_err("Unsuccessfully request channel!\n");
+ return -EBUSY;
+ }
+
+ cam->pxp_chan = to_pxp_channel(chan);
+ cam->pxp_chan->client = cam;
+
+ init_completion(&cam->pxp_tx_cmpl);
+
+ return 0;
+}
+
+/*
+ * Function to call PxP DMA driver and send our new V4L2 buffer
+ * through the PxP and PxP will process this buffer in place.
+ * Note: This is a blocking call, so upon return the PxP tx should be complete.
+ */
+static int pxp_process_update(cam_data *cam)
+{
+ dma_cookie_t cookie;
+ struct scatterlist *sg = cam->sg;
+ struct dma_chan *dma_chan;
+ struct pxp_tx_desc *desc;
+ struct dma_async_tx_descriptor *txd;
+ struct pxp_config_data *pxp_conf = &cam->pxp_conf;
+ struct pxp_proc_data *proc_data = &cam->pxp_conf.proc_data;
+ int i, ret;
+ int length;
+
+ pr_debug("Starting PxP Send Buffer\n");
+
+ /* First, check to see that we have acquired a PxP Channel object */
+ if (cam->pxp_chan == NULL) {
+ /*
+ * PxP Channel has not yet been created and initialized,
+ * so let's go ahead and try
+ */
+ ret = pxp_chan_init(cam);
+ if (ret) {
+ /*
+ * PxP channel init failed, and we can't use the
+ * PxP until the PxP DMA driver has loaded, so we abort
+ */
+ pr_err("PxP chan init failed\n");
+ return -ENODEV;
+ }
+ }
+
+ /*
+ * Init completion, so that we can be properly informed of
+ * the completion of the PxP task when it is done.
+ */
+ init_completion(&cam->pxp_tx_cmpl);
+
+ dma_chan = &cam->pxp_chan->dma_chan;
+
+ txd = dma_chan->device->device_prep_slave_sg(dma_chan, sg, 2,
+ DMA_TO_DEVICE,
+ DMA_PREP_INTERRUPT);
+ if (!txd) {
+ pr_err("Error preparing a DMA transaction descriptor.\n");
+ return -EIO;
+ }
+
+ txd->callback_param = txd;
+ txd->callback = pxp_dma_done;
+
+ /*
+ * Configure PxP for processing of new v4l2 buf
+ */
+ pxp_conf->s0_param.pixel_fmt = PXP_PIX_FMT_UYVY;
+ pxp_conf->s0_param.color_key = -1;
+ pxp_conf->s0_param.color_key_enable = false;
+ pxp_conf->s0_param.width = cam->v2f.fmt.pix.width;
+ pxp_conf->s0_param.height = cam->v2f.fmt.pix.height;
+
+ pxp_conf->ol_param[0].combine_enable = false;
+
+ proc_data->srect.top = 0;
+ proc_data->srect.left = 0;
+ proc_data->srect.width = pxp_conf->s0_param.width;
+ proc_data->srect.height = pxp_conf->s0_param.height;
+
+ proc_data->drect.top = 0;
+ proc_data->drect.left = 0;
+ proc_data->drect.width = proc_data->srect.width;
+ proc_data->drect.height = proc_data->srect.height;
+ proc_data->scaling = 0;
+ proc_data->hflip = 0;
+ proc_data->vflip = 0;
+ proc_data->rotate = 0;
+ proc_data->bgcolor = 0;
+
+ pxp_conf->out_param.pixel_fmt = PXP_PIX_FMT_RGB565;
+ pxp_conf->out_param.width = proc_data->drect.width;
+ pxp_conf->out_param.height = proc_data->drect.height;
+
+ if (cam->rotation >= IPU_ROTATE_90_RIGHT)
+ pxp_conf->out_param.stride = pxp_conf->out_param.height;
+ else
+ pxp_conf->out_param.stride = pxp_conf->out_param.width;
+
+ desc = to_tx_desc(txd);
+ length = desc->len;
+ for (i = 0; i < length; i++) {
+ if (i == 0) {/* S0 */
+ memcpy(&desc->proc_data, proc_data,
+ sizeof(struct pxp_proc_data));
+ pxp_conf->s0_param.paddr = sg_dma_address(&sg[0]);
+ memcpy(&desc->layer_param.s0_param, &pxp_conf->s0_param,
+ sizeof(struct pxp_layer_param));
+ } else if (i == 1) {
+ pxp_conf->out_param.paddr = sg_dma_address(&sg[1]);
+ memcpy(&desc->layer_param.out_param,
+ &pxp_conf->out_param,
+ sizeof(struct pxp_layer_param));
+ }
+
+ desc = desc->next;
+ }
+
+ /* Submitting our TX starts the PxP processing task */
+ cookie = txd->tx_submit(txd);
+ if (cookie < 0) {
+ pr_err("Error sending FB through PxP\n");
+ return -EIO;
+ }
+
+ cam->txd = txd;
+
+ /* trigger PxP */
+ dma_async_issue_pending(dma_chan);
+
+ return 0;
+}
+
+static int pxp_complete_update(cam_data *cam)
+{
+ int ret;
+ /*
+ * Wait for completion event, which will be set
+ * through our TX callback function.
+ */
+ ret = wait_for_completion_timeout(&cam->pxp_tx_cmpl, HZ / 10);
+ if (ret <= 0) {
+ pr_warning("PxP operation failed due to %s\n",
+ ret < 0 ? "user interrupt" : "timeout");
+ dma_release_channel(&cam->pxp_chan->dma_chan);
+ cam->pxp_chan = NULL;
+ return ret ? : -ETIMEDOUT;
+ }
+
+ dma_release_channel(&cam->pxp_chan->dma_chan);
+ cam->pxp_chan = NULL;
+
+ pr_debug("TX completed\n");
+
+ return 0;
+}
+
/*!
* Camera V4l2 callback function.
*
@@ -666,6 +858,23 @@ static int csi_v4l_dqueue(cam_data *cam, struct v4l2_buffer *buf)
buf->flags = frame->buffer.flags;
buf->m = cam->frame[frame->index].buffer.m;
+ /*
+ * Note:
+ * If want to do preview on LCD, use PxP CSC to convert from UYVY
+ * to RGB565; but for encoding, usually we don't use RGB format.
+ */
+ if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) {
+ /* PxP processes it in place */
+ sg_dma_address(&cam->sg[0]) = buf->m.offset;
+ sg_dma_address(&cam->sg[1]) = buf->m.offset;
+ retval = pxp_process_update(cam);
+ if (retval) {
+ pr_err("Unable to submit PxP update task.\n");
+ return retval;
+ }
+ pxp_complete_update(cam);
+ }
+
return retval;
}
@@ -1157,22 +1366,6 @@ static struct video_device csi_v4l_template = {
};
/*!
- * This function can be used to release any platform data on closing.
- */
-static void camera_platform_release(struct device *device)
-{
-}
-
-/*! Device Definition for csi v4l2 device */
-static struct platform_device csi_v4l2_devices = {
- .name = "csi_v4l2",
- .dev = {
- .release = camera_platform_release,
- },
- .id = 0,
-};
-
-/*!
* initialize cam_data structure
*
* @param cam structure cam_data *
@@ -1186,8 +1379,8 @@ static void init_camera_struct(cam_data *cam)
/* Default everything to 0 */
memset(cam, 0, sizeof(cam_data));
- init_MUTEX(&cam->param_lock);
- init_MUTEX(&cam->busy_lock);
+ sema_init(&cam->param_lock, 1);
+ sema_init(&cam->busy_lock, 1);
cam->video_dev = video_device_alloc();
if (cam->video_dev == NULL)
@@ -1196,7 +1389,6 @@ static void init_camera_struct(cam_data *cam)
*(cam->video_dev) = csi_v4l_template;
video_set_drvdata(cam->video_dev, cam);
- dev_set_drvdata(&csi_v4l2_devices.dev, (void *)cam);
cam->video_dev->minor = -1;
init_waitqueue_head(&cam->enc_queue);
@@ -1259,6 +1451,66 @@ static u8 camera_power(cam_data *cam, bool cameraOn)
return 0;
}
+static int __devinit csi_v4l2_probe(struct platform_device *pdev)
+{
+ struct scatterlist *sg;
+ u8 err = 0;
+
+ /* Create g_cam and initialize it. */
+ g_cam = kmalloc(sizeof(cam_data), GFP_KERNEL);
+ if (g_cam == NULL) {
+ pr_err("ERROR: v4l2 capture: failed to register camera\n");
+ err = -ENOMEM;
+ goto out;
+ }
+ init_camera_struct(g_cam);
+ platform_set_drvdata(pdev, (void *)g_cam);
+
+ /* Set up the v4l2 device and register it */
+ csi_v4l2_int_device.priv = g_cam;
+ /* This function contains a bug that won't let this be rmmod'd. */
+ v4l2_int_device_register(&csi_v4l2_int_device);
+
+ /* register v4l video device */
+ if (video_register_device(g_cam->video_dev, VFL_TYPE_GRABBER, video_nr)
+ == -1) {
+ kfree(g_cam);
+ g_cam = NULL;
+ pr_err("ERROR: v4l2 capture: video_register_device failed\n");
+ err = -ENODEV;
+ goto out;
+ }
+ pr_debug(" Video device registered: %s #%d\n",
+ g_cam->video_dev->name, g_cam->video_dev->minor);
+
+ g_cam->pxp_chan = NULL;
+ /* Initialize Scatter-gather list containing 2 buffer addresses. */
+ sg = g_cam->sg;
+ sg_init_table(sg, 2);
+
+out:
+ return err;
+}
+
+static int __devexit csi_v4l2_remove(struct platform_device *pdev)
+{
+ if (g_cam->open_count) {
+ pr_err("ERROR: v4l2 capture:camera open "
+ "-- setting ops to NULL\n");
+ } else {
+ pr_info("V4L2 freeing image input device\n");
+ v4l2_int_device_unregister(&csi_v4l2_int_device);
+ csi_stop_callback(g_cam);
+ video_unregister_device(g_cam->video_dev);
+ platform_set_drvdata(pdev, NULL);
+
+ kfree(g_cam);
+ g_cam = NULL;
+ }
+
+ return 0;
+}
+
/*!
* This function is called to put the sensor in a low power state.
* Refer to the document driver-model/driver.txt in the kernel source tree
@@ -1324,8 +1576,8 @@ static struct platform_driver csi_v4l2_driver = {
.driver = {
.name = "csi_v4l2",
},
- .probe = NULL,
- .remove = NULL,
+ .probe = csi_v4l2_probe,
+ .remove = __devexit_p(csi_v4l2_remove),
#ifdef CONFIG_PM
.suspend = csi_v4l2_suspend,
.resume = csi_v4l2_resume,
@@ -1382,55 +1634,8 @@ static void csi_v4l2_master_detach(struct v4l2_int_device *slave)
*/
static __init int camera_init(void)
{
- u8 err = 0;
-
/* Register the device driver structure. */
- err = platform_driver_register(&csi_v4l2_driver);
- if (err != 0) {
- pr_err("ERROR: v4l2 capture:camera_init: "
- "platform_driver_register failed.\n");
- return err;
- }
-
- /* Create g_cam and initialize it. */
- g_cam = kmalloc(sizeof(cam_data), GFP_KERNEL);
- if (g_cam == NULL) {
- pr_err("ERROR: v4l2 capture: failed to register camera\n");
- platform_driver_unregister(&csi_v4l2_driver);
- return -1;
- }
- init_camera_struct(g_cam);
-
- /* Set up the v4l2 device and register it */
- csi_v4l2_int_device.priv = g_cam;
- /* This function contains a bug that won't let this be rmmod'd. */
- v4l2_int_device_register(&csi_v4l2_int_device);
-
- /* Register the platform device */
- err = platform_device_register(&csi_v4l2_devices);
- if (err != 0) {
- pr_err("ERROR: v4l2 capture: camera_init: "
- "platform_device_register failed.\n");
- platform_driver_unregister(&csi_v4l2_driver);
- kfree(g_cam);
- g_cam = NULL;
- return err;
- }
-
- /* register v4l video device */
- if (video_register_device(g_cam->video_dev, VFL_TYPE_GRABBER, video_nr)
- == -1) {
- platform_device_unregister(&csi_v4l2_devices);
- platform_driver_unregister(&csi_v4l2_driver);
- kfree(g_cam);
- g_cam = NULL;
- pr_err("ERROR: v4l2 capture: video_register_device failed\n");
- return -1;
- }
- pr_debug(" Video device registered: %s #%d\n",
- g_cam->video_dev->name, g_cam->video_dev->minor);
-
- return err;
+ return platform_driver_register(&csi_v4l2_driver);
}
/*!
@@ -1438,22 +1643,7 @@ static __init int camera_init(void)
*/
static void __exit camera_exit(void)
{
- pr_debug("In MVC: %s\n", __func__);
-
- if (g_cam->open_count) {
- pr_err("ERROR: v4l2 capture:camera open "
- "-- setting ops to NULL\n");
- } else {
- pr_info("V4L2 freeing image input device\n");
- v4l2_int_device_unregister(&csi_v4l2_int_device);
- csi_stop_callback(g_cam);
- video_unregister_device(g_cam->video_dev);
- platform_driver_unregister(&csi_v4l2_driver);
- platform_device_unregister(&csi_v4l2_devices);
-
- kfree(g_cam);
- g_cam = NULL;
- }
+ platform_driver_unregister(&csi_v4l2_driver);
}
module_init(camera_init);
diff --git a/drivers/media/video/mxc/capture/fsl_csi.c b/drivers/media/video/mxc/capture/fsl_csi.c
index dba35c4499e2..33a82242e95e 100644
--- a/drivers/media/video/mxc/capture/fsl_csi.c
+++ b/drivers/media/video/mxc/capture/fsl_csi.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2009-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -20,6 +20,7 @@
*/
#include <linux/types.h>
#include <linux/init.h>
+#include <linux/platform_device.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/interrupt.h>
@@ -27,11 +28,14 @@
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/clk.h>
+#include <linux/sched.h>
#include <mach/clock.h>
#include "mxc_v4l2_capture.h"
#include "fsl_csi.h"
+void __iomem *csi_regbase;
+static int irq_nr;
static bool g_csi_mclk_on;
static csi_irq_callback_t g_callback;
static void *g_callback_data;
@@ -164,7 +168,7 @@ void csi_start_callback(void *data)
{
cam_data *cam = (cam_data *) data;
- if (request_irq(MXC_INT_CSI, csi_irq_handler, 0, "csi", cam) < 0)
+ if (request_irq(irq_nr, csi_irq_handler, 0, "csi", cam) < 0)
pr_debug("CSI error: irq request fail\n");
}
@@ -174,7 +178,7 @@ void csi_stop_callback(void *data)
{
cam_data *cam = (cam_data *) data;
- free_irq(MXC_INT_CSI, cam);
+ free_irq(irq_nr, cam);
}
EXPORT_SYMBOL(csi_stop_callback);
@@ -254,10 +258,32 @@ void csi_mclk_disable(void)
__raw_writel(__raw_readl(CSI_CSICR1) & ~BIT_MCLKEN, CSI_CSICR1);
}
-int32_t __init csi_init_module(void)
+static int __devinit csi_probe(struct platform_device *pdev)
{
int ret = 0;
struct clk *per_clk;
+ struct resource *res;
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "No csi irq found.\n");
+ ret = -ENODEV;
+ goto err;
+ }
+ irq_nr = res->start;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "No csi base address found.\n");
+ ret = -ENODEV;
+ goto err;
+ }
+ csi_regbase = ioremap(res->start, resource_size(res));
+ if (!csi_regbase) {
+ dev_err(&pdev->dev, "ioremap failed with csi base\n");
+ ret = -ENOMEM;
+ goto err;
+ }
csihw_reset();
csi_init_interface();
@@ -271,12 +297,34 @@ int32_t __init csi_init_module(void)
clk_enable(per_clk);
csi_mclk_recalc(&csi_mclk);
+err:
return ret;
}
-void __exit csi_cleanup_module(void)
+static int __devexit csi_remove(struct platform_device *pdev)
{
clk_disable(&csi_mclk);
+ iounmap(csi_regbase);
+
+ return 0;
+}
+
+static struct platform_driver csi_driver = {
+ .driver = {
+ .name = "fsl_csi",
+ },
+ .probe = csi_probe,
+ .remove = __devexit_p(csi_remove),
+};
+
+int32_t __init csi_init_module(void)
+{
+ return platform_driver_register(&csi_driver);
+}
+
+void __exit csi_cleanup_module(void)
+{
+ platform_driver_unregister(&csi_driver);
}
module_init(csi_init_module);
diff --git a/drivers/media/video/mxc/capture/fsl_csi.h b/drivers/media/video/mxc/capture/fsl_csi.h
index 00c389892224..8dfce286fe53 100644
--- a/drivers/media/video/mxc/capture/fsl_csi.h
+++ b/drivers/media/video/mxc/capture/fsl_csi.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2009-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -102,23 +102,22 @@
#define CSI_MCLK_I2C 8
#endif
-#define CSI_CSICR1 (IO_ADDRESS(CSI_BASE_ADDR))
-#define CSI_CSICR2 (IO_ADDRESS(CSI_BASE_ADDR + 0x4))
-#define CSI_CSICR3 (IO_ADDRESS(CSI_BASE_ADDR + 0x8))
-#define CSI_STATFIFO (IO_ADDRESS(CSI_BASE_ADDR + 0xC))
-#define CSI_CSIRXFIFO (IO_ADDRESS(CSI_BASE_ADDR + 0x10))
-#define CSI_CSIRXCNT (IO_ADDRESS(CSI_BASE_ADDR + 0x14))
-#define CSI_CSISR (IO_ADDRESS(CSI_BASE_ADDR + 0x18))
-
-#define CSI_CSIDBG (IO_ADDRESS(CSI_BASE_ADDR + 0x1C))
-#define CSI_CSIDMASA_STATFIFO (IO_ADDRESS(CSI_BASE_ADDR + 0x20))
-#define CSI_CSIDMATS_STATFIFO (IO_ADDRESS(CSI_BASE_ADDR + 0x24))
-#define CSI_CSIDMASA_FB1 (IO_ADDRESS(CSI_BASE_ADDR + 0x28))
-#define CSI_CSIDMASA_FB2 (IO_ADDRESS(CSI_BASE_ADDR + 0x2C))
-#define CSI_CSIFBUF_PARA (IO_ADDRESS(CSI_BASE_ADDR + 0x30))
-#define CSI_CSIIMAG_PARA (IO_ADDRESS(CSI_BASE_ADDR + 0x34))
-
-#define CSI_CSIRXFIFO_PHYADDR (CSI_BASE_ADDR + 0x10)
+extern void __iomem *csi_regbase;
+#define CSI_CSICR1 (csi_regbase)
+#define CSI_CSICR2 (csi_regbase + 0x4)
+#define CSI_CSICR3 (csi_regbase + 0x8)
+#define CSI_STATFIFO (csi_regbase + 0xC)
+#define CSI_CSIRXFIFO (csi_regbase + 0x10)
+#define CSI_CSIRXCNT (csi_regbase + 0x14)
+#define CSI_CSISR (csi_regbase + 0x18)
+
+#define CSI_CSIDBG (csi_regbase + 0x1C)
+#define CSI_CSIDMASA_STATFIFO (csi_regbase + 0x20)
+#define CSI_CSIDMATS_STATFIFO (csi_regbase + 0x24)
+#define CSI_CSIDMASA_FB1 (csi_regbase + 0x28)
+#define CSI_CSIDMASA_FB2 (csi_regbase + 0x2C)
+#define CSI_CSIFBUF_PARA (csi_regbase + 0x30)
+#define CSI_CSIIMAG_PARA (csi_regbase + 0x34)
static inline void csi_clear_status(unsigned long status)
{
diff --git a/drivers/media/video/mxc/capture/ipu_prp_enc.c b/drivers/media/video/mxc/capture/ipu_prp_enc.c
index def416570de3..a3c90d53f2eb 100644
--- a/drivers/media/video/mxc/capture/ipu_prp_enc.c
+++ b/drivers/media/video/mxc/capture/ipu_prp_enc.c
@@ -70,7 +70,7 @@ static int prp_enc_setup(cam_data *cam)
{
ipu_channel_params_t enc;
int err = 0;
- dma_addr_t dummy = 0xdeadbeaf;
+ dma_addr_t dummy = cam->dummy_frame.buffer.m.offset;
#ifdef CONFIG_MXC_MIPI_CSI2
void *mipi_csi2_info;
int ipu_id;
diff --git a/drivers/media/video/mxc/capture/mt9v111.c b/drivers/media/video/mxc/capture/mt9v111.c
index 4305c56c82d9..3ae65db04486 100644
--- a/drivers/media/video/mxc/capture/mt9v111.c
+++ b/drivers/media/video/mxc/capture/mt9v111.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -879,7 +879,7 @@ static int ioctl_dev_init(struct v4l2_int_device *s)
gpio_sensor_active();
- set_mclk_rate(&clock_rate);
+ set_mclk_rate(&clock_rate, 0);
mt9v111_rate_cal(&reset_frame_rate, clock_rate);
mt9v111_sensor_lib(mt9v111_device.coreReg, mt9v111_device.ifpReg);
diff --git a/drivers/media/video/mxc/capture/mxc_v4l2_capture.h b/drivers/media/video/mxc/capture/mxc_v4l2_capture.h
index bef4214c8149..d2efbe8453b2 100644
--- a/drivers/media/video/mxc/capture/mxc_v4l2_capture.h
+++ b/drivers/media/video/mxc/capture/mxc_v4l2_capture.h
@@ -31,6 +31,10 @@
#include <linux/list.h>
#include <linux/ipu.h>
#include <linux/mxc_v4l2.h>
+#include <linux/completion.h>
+#include <linux/dmaengine.h>
+#include <linux/pxp_dma.h>
+#include <mach/dma.h>
#include <mach/ipu-v3.h>
#include <media/v4l2-dev.h>
@@ -206,6 +210,14 @@ typedef struct _cam_data {
struct v4l2_int_device *self;
int sensor_index;
void *ipu;
+
+ /* v4l2 buf elements related to PxP DMA */
+ struct completion pxp_tx_cmpl;
+ struct pxp_channel *pxp_chan;
+ struct pxp_config_data pxp_conf;
+ struct dma_async_tx_descriptor *txd;
+ dma_cookie_t cookie;
+ struct scatterlist sg[2];
} cam_data;
struct sensor_data {
@@ -233,11 +245,5 @@ struct sensor_data {
void (*io_init)(void);
};
-#if defined(CONFIG_MXC_IPU_V1) || defined(CONFIG_VIDEO_MXC_EMMA_CAMERA) \
- || defined(CONFIG_VIDEO_MXC_CSI_CAMERA_MODULE) \
- || defined(CONFIG_VIDEO_MXC_CSI_CAMERA)
-void set_mclk_rate(uint32_t *p_mclk_freq);
-#else
void set_mclk_rate(uint32_t *p_mclk_freq, uint32_t csi);
-#endif
#endif /* __MXC_V4L2_CAPTURE_H__ */
diff --git a/drivers/media/video/mxc/capture/ov2640.c b/drivers/media/video/mxc/capture/ov2640.c
index a0a050bca2e9..24ebd5027ff1 100644
--- a/drivers/media/video/mxc/capture/ov2640.c
+++ b/drivers/media/video/mxc/capture/ov2640.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2005-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -801,7 +801,7 @@ static int ioctl_dev_init(struct v4l2_int_device *s)
pr_debug(" Setting mclk to %d MHz\n",
tgt_xclk / 1000000);
- set_mclk_rate(&ov2640_data.mclk);
+ set_mclk_rate(&ov2640_data.mclk, 0);
return ov2640_init_mode(sensor);
}
diff --git a/drivers/media/video/mxc/capture/ov5640_mipi.c b/drivers/media/video/mxc/capture/ov5640_mipi.c
index 44cdd466337e..bde39a51d368 100644
--- a/drivers/media/video/mxc/capture/ov5640_mipi.c
+++ b/drivers/media/video/mxc/capture/ov5640_mipi.c
@@ -1494,12 +1494,15 @@ static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
}
orig_mode = sensor->streamcap.capturemode;
+ ret = ov5640_init_mode(frame_rate,
+ (u32)a->parm.capture.capturemode, orig_mode);
+ if (ret < 0)
+ return ret;
+
sensor->streamcap.timeperframe = *timeperframe;
sensor->streamcap.capturemode =
(u32)a->parm.capture.capturemode;
- ret = ov5640_init_mode(frame_rate,
- sensor->streamcap.capturemode, orig_mode);
break;
/* These are all the possible cases. */
diff --git a/drivers/media/video/mxc/capture/ov5642.c b/drivers/media/video/mxc/capture/ov5642.c
index 2321f68c6384..426438276908 100644
--- a/drivers/media/video/mxc/capture/ov5642.c
+++ b/drivers/media/video/mxc/capture/ov5642.c
@@ -861,7 +861,7 @@ static struct reg_value ov5642_setting_15fps_VGA_640_480[] = {
{0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
{0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
{0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
- {0x3010, 0x10, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
+ {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
{0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
{0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
{0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
@@ -879,8 +879,8 @@ static struct reg_value ov5642_setting_15fps_VGA_640_480[] = {
{0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
{0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
{0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
- {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x03, 0, 0},
- {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x07, 0, 0},
+ {0x380f, 0xd0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
{0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
{0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
{0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x80, 0, 0},
@@ -1202,7 +1202,7 @@ static struct reg_value ov5642_setting_15fps_XGA_1024_768[] = {
{0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
{0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
{0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
- {0x3010, 0x10, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
+ {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
{0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
{0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
{0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
@@ -1220,8 +1220,8 @@ static struct reg_value ov5642_setting_15fps_XGA_1024_768[] = {
{0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
{0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
{0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
- {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x03, 0, 0},
- {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x07, 0, 0},
+ {0x380f, 0xd0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
{0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
{0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
{0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x80, 0, 0},
@@ -1364,7 +1364,7 @@ static struct reg_value ov5642_setting_15fps_XGA_1024_768[] = {
{0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
{0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
{0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x03, 0, 0},
- {0x380b, 0x00, 0, 0}, {0x3815, 0x02, 0, 0},
+ {0x380b, 0x00, 0, 0}, {0x3815, 0x02, 0, 0}, {0x302c, 0x60, 0x60, 0},
};
static struct reg_value ov5642_setting_30fps_QVGA_320_240[] = {
@@ -3526,6 +3526,9 @@ static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
ret = ov5642_change_mode(new_frame_rate, old_frame_rate,
a->parm.capture.capturemode,
sensor->streamcap.capturemode);
+ if (ret < 0)
+ return ret;
+
sensor->streamcap.timeperframe = *timeperframe;
sensor->streamcap.capturemode =
(u32)a->parm.capture.capturemode;
diff --git a/drivers/media/video/mxc/capture/sensor_clock.c b/drivers/media/video/mxc/capture/sensor_clock.c
index 8004aeee5dc2..150659fa5dc0 100644
--- a/drivers/media/video/mxc/capture/sensor_clock.c
+++ b/drivers/media/video/mxc/capture/sensor_clock.c
@@ -26,31 +26,6 @@
#include <mach/hardware.h>
#include <asm/mach-types.h>
-#if defined(CONFIG_MXC_IPU_V1) || defined(CONFIG_VIDEO_MXC_EMMA_CAMERA) \
- || defined(CONFIG_VIDEO_MXC_CSI_CAMERA_MODULE) \
- || defined(CONFIG_VIDEO_MXC_CSI_CAMERA)
-/*
- * set_mclk_rate
- *
- * @param p_mclk_freq mclk frequence
- *
- */
-void set_mclk_rate(uint32_t *p_mclk_freq)
-{
- struct clk *clk;
- uint32_t freq = 0;
-
- clk = clk_get(NULL, "csi_clk");
-
- freq = clk_round_rate(clk, *p_mclk_freq);
- clk_set_rate(clk, freq);
-
- *p_mclk_freq = freq;
-
- clk_put(clk);
- pr_debug("mclk frequency = %d\n", *p_mclk_freq);
-}
-#else
/*
* set_mclk_rate
*
@@ -81,6 +56,8 @@ void set_mclk_rate(uint32_t *p_mclk_freq, uint32_t csi)
pr_err("invalid csi num %d\n", csi);
return;
};
+ } else if (cpu_is_mx25() || cpu_is_mx6sl()) { /* only has CSI0 */
+ mclk = "csi_clk";
} else {
if (csi == 0) {
mclk = "csi_mclk1";
@@ -102,7 +79,6 @@ void set_mclk_rate(uint32_t *p_mclk_freq, uint32_t csi)
clk_put(clk);
pr_debug("%s frequency = %d\n", mclk, *p_mclk_freq);
}
-#endif
/* Exported symbols for modules. */
EXPORT_SYMBOL(set_mclk_rate);
diff --git a/drivers/media/video/mxc/output/mxc_vout.c b/drivers/media/video/mxc/output/mxc_vout.c
index 366d27a92286..388c4b39570f 100644
--- a/drivers/media/video/mxc/output/mxc_vout.c
+++ b/drivers/media/video/mxc/output/mxc_vout.c
@@ -861,6 +861,7 @@ static int mxc_vout_open(struct file *file)
vout->win_pos.x = 0;
vout->win_pos.y = 0;
+ vout->release = true;
}
file->private_data = vout;
@@ -973,6 +974,7 @@ static inline int vdoaipu_try_task(struct mxc_vout_output *vout)
int is_1080p_stream;
size_t size;
struct ipu_task *ipu_task = &vout->task;
+ struct ipu_crop *icrop = &ipu_task->input.crop;
struct ipu_task *vdoa_task = &vout->vdoa_task;
u32 deinterlace = 0;
u32 in_fmt;
@@ -981,15 +983,23 @@ static inline int vdoaipu_try_task(struct mxc_vout_output *vout)
deinterlace = 1;
memset(vdoa_task, 0, sizeof(*vdoa_task));
- memcpy(&vdoa_task->input, &ipu_task->input, sizeof(ipu_task->input));
vdoa_task->output.format = IPU_PIX_FMT_NV12;
- vdoa_task->output.width = ipu_task->input.crop.w;
- vdoa_task->output.height = ipu_task->input.crop.h;
- vdoa_task->output.crop.w = ipu_task->input.crop.w;
- vdoa_task->output.crop.h = ipu_task->input.crop.h;
-
- size = PAGE_ALIGN(ipu_task->input.crop.w *
- ipu_task->input.crop.h *
+ memcpy(&vdoa_task->input, &ipu_task->input,
+ sizeof(ipu_task->input));
+ if ((icrop->w % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
+ (icrop->h % IPU_PIX_FMT_TILED_NV12_MBALIGN)) {
+ vdoa_task->input.crop.w =
+ ALIGN(icrop->w, IPU_PIX_FMT_TILED_NV12_MBALIGN);
+ vdoa_task->input.crop.h =
+ ALIGN(icrop->h, IPU_PIX_FMT_TILED_NV12_MBALIGN);
+ }
+ vdoa_task->output.width = vdoa_task->input.crop.w;
+ vdoa_task->output.height = vdoa_task->input.crop.h;
+ vdoa_task->output.crop.w = vdoa_task->input.crop.w;
+ vdoa_task->output.crop.h = vdoa_task->input.crop.h;
+
+ size = PAGE_ALIGN(vdoa_task->input.crop.w *
+ vdoa_task->input.crop.h *
fmt_to_bpp(vdoa_task->output.format)/8);
if (size > vout->vdoa_work.size) {
if (vout->vdoa_work.vaddr)
@@ -1029,6 +1039,7 @@ static int mxc_vout_try_task(struct mxc_vout_output *vout)
u32 o_height = 0;
u32 ocrop_h = 0;
bool tiled_fmt = false;
+ bool tiled_need_pp = false;
vout->vdoa_1080p = CHECK_TILED_1080P_DISPLAY(vout);
if (vout->vdoa_1080p) {
@@ -1041,10 +1052,17 @@ static int mxc_vout_try_task(struct mxc_vout_output *vout)
if ((IPU_PIX_FMT_TILED_NV12 == input->format) ||
(IPU_PIX_FMT_TILED_NV12F == input->format)) {
- crop->w -= crop->w % IPU_PIX_FMT_TILED_NV12_MBALIGN;
- crop->h -= crop->h % IPU_PIX_FMT_TILED_NV12_MBALIGN;
- crop->pos.x -= crop->pos.x % IPU_PIX_FMT_TILED_NV12_MBALIGN;
- crop->pos.y -= crop->pos.y % IPU_PIX_FMT_TILED_NV12_MBALIGN;
+ if ((input->width % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
+ (input->height % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
+ (crop->pos.x % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
+ (crop->pos.y % IPU_PIX_FMT_TILED_NV12_MBALIGN)) {
+ v4l2_err(vout->vfd->v4l2_dev,
+ "ERR: tiled fmt needs 16 pixel align.\n");
+ return -EINVAL;
+ }
+ if ((crop->w % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
+ (crop->h % IPU_PIX_FMT_TILED_NV12_MBALIGN))
+ tiled_need_pp = true;
} else {
crop->w -= crop->w % 8;
crop->h -= crop->h % 8;
@@ -1072,7 +1090,8 @@ static int mxc_vout_try_task(struct mxc_vout_output *vout)
if ((IPU_PIX_FMT_TILED_NV12 == input->format) ||
(IPU_PIX_FMT_TILED_NV12F == input->format)) {
/* check resize/rotate/flip, or csc task */
- if (!((IPU_ROTATE_NONE != output->rotate) ||
+ if (!(tiled_need_pp ||
+ (IPU_ROTATE_NONE != output->rotate) ||
(input->crop.w != output->crop.w) ||
(input->crop.h != output->crop.h) ||
(!vout->disp_support_csc &&
diff --git a/drivers/mfd/mxc-hdmi-core.c b/drivers/mfd/mxc-hdmi-core.c
index e9322477ff6d..a07db1b0c070 100644
--- a/drivers/mfd/mxc-hdmi-core.c
+++ b/drivers/mfd/mxc-hdmi-core.c
@@ -41,6 +41,7 @@
#include <linux/mfd/mxc-hdmi-core.h>
#include <linux/fsl_devices.h>
#include <mach/hardware.h>
+#include <linux/mfd/mxc-hdmi-core.h>
struct mxc_hdmi_data {
struct platform_device *pdev;
@@ -72,22 +73,29 @@ 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;
+ struct snd_pcm_substream *substream = hdmi_audio_stream_playback;
spin_lock_irqsave(&hdmi_cable_state_lock, flags);
hdmi_cable_state = state;
spin_unlock_irqrestore(&hdmi_cable_state_lock, flags);
+ if (check_hdmi_state() && substream)
+ substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);
return 0;
}
unsigned int hdmi_set_blank_state(unsigned int state)
{
unsigned long flags;
+ struct snd_pcm_substream *substream = hdmi_audio_stream_playback;
spin_lock_irqsave(&hdmi_blank_state_lock, flags);
hdmi_blank_state = state;
spin_unlock_irqrestore(&hdmi_blank_state_lock, flags);
+ if (check_hdmi_state() && substream)
+ substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);
+
return 0;
}
@@ -98,7 +106,7 @@ static void hdmi_audio_abort_stream(struct snd_pcm_substream *substream)
snd_pcm_stream_lock_irqsave(substream, flags);
if (snd_pcm_running(substream))
- snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
+ substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
snd_pcm_stream_unlock_irqrestore(substream, flags);
}
@@ -114,7 +122,7 @@ int mxc_hdmi_abort_stream(void)
return 0;
}
-static int check_hdmi_state(void)
+int check_hdmi_state(void)
{
unsigned long flags1, flags2;
unsigned int ret;
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 2c32faad3b4b..ba625b3ca376 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)
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
index 01c81faffa4a..2138dcb4f8a4 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
@@ -44,7 +44,7 @@ struct timing_threshod timing_default_threshold = {
.max_dll_delay_in_ns = 16,
};
-static struct clk *mxs_dma_clk;
+struct clk *mxs_dma_clk;
static void setup_ddr_timing_onfi(struct gpmi_nand_data *this)
{
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index f25b7c27b101..9bd09fc490e5 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -439,6 +439,12 @@ static bool gpmi_dma_filter(struct dma_chan *chan, void *param)
static void release_dma_channels(struct gpmi_nand_data *this)
{
unsigned int i;
+
+ if (mxs_dma_clk) {
+ clk_put(mxs_dma_clk);
+ mxs_dma_clk = NULL;
+ }
+
for (i = 0; i < DMA_CHANS; i++)
if (this->dma_chans[i]) {
dma_release_channel(this->dma_chans[i]);
@@ -873,7 +879,7 @@ static void block_mark_swapping(struct gpmi_nand_data *this,
}
static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
- uint8_t *buf, int page)
+ uint8_t *buf, int oob_required, int page)
{
struct gpmi_nand_data *this = chip->priv;
struct bch_geometry *nfc_geo = &this->bch_geometry;
@@ -939,17 +945,20 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
mtd->ecc_stats.corrected += corrected;
}
- /*
- * It's time to deliver the OOB bytes. See gpmi_ecc_read_oob() for
- * details about our policy for delivering the OOB.
- *
- * We fill the caller's buffer with set bits, and then copy the block
- * mark to th caller's buffer. Note that, if block mark swapping was
- * necessary, it has already been done, so we can rely on the first
- * byte of the auxiliary buffer to contain the block mark.
- */
- memset(chip->oob_poi, ~0, mtd->oobsize);
- chip->oob_poi[0] = ((uint8_t *) auxiliary_virt)[0];
+ if (oob_required) {
+ /*
+ * It's time to deliver the OOB bytes. See gpmi_ecc_read_oob()
+ * for details about our policy for delivering the OOB.
+ *
+ * We fill the caller's buffer with set bits, and then copy the
+ * block mark to th caller's buffer. Note that, if block mark
+ * swapping was necessary, it has already been done, so we can
+ * rely on the first byte of the auxiliary buffer to contain
+ * the block mark.
+ */
+ memset(chip->oob_poi, ~0, mtd->oobsize);
+ chip->oob_poi[0] = ((uint8_t *) auxiliary_virt)[0];
+ }
read_page_swap_end(this, buf, mtd->writesize,
this->payload_virt, this->payload_phys,
@@ -959,8 +968,8 @@ exit_nfc:
return ret;
}
-static void gpmi_ecc_write_page(struct mtd_info *mtd,
- struct nand_chip *chip, const uint8_t *buf)
+static void gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+ const uint8_t *buf, int oob_required)
{
struct gpmi_nand_data *this = chip->priv;
struct bch_geometry *nfc_geo = &this->bch_geometry;
@@ -1040,7 +1049,7 @@ static int gpmi_verify_buf(struct mtd_info *mtd, const uint8_t * buf, int len)
{
struct nand_chip *nand = mtd->priv;
- gpmi_ecc_read_page(mtd, nand, verify_buf, len);
+ gpmi_ecc_read_page(mtd, nand, verify_buf, 0, len);
if (memcmp(buf, verify_buf, len))
return -EFAULT;
return 0;
@@ -1353,7 +1362,7 @@ static int __devinit mx23_write_transcription_stamp(struct gpmi_nand_data *this)
/* Write the first page of the current stride. */
dev_dbg(dev, "Writing an NCB fingerprint in page 0x%x\n", page);
chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
- chip->ecc.write_page_raw(mtd, chip, buffer);
+ chip->ecc.write_page_raw(mtd, chip, buffer, 0);
chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
/* Wait for the write to finish. */
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
index 21e1f6569211..77d0d273a297 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
@@ -290,4 +290,6 @@ extern int gpmi_read_page(struct gpmi_nand_data *,
#define GPMI_IS_MX23(x) ((x)->pdev->id_entry->driver_data == IS_MX23)
#define GPMI_IS_MX28(x) ((x)->pdev->id_entry->driver_data == IS_MX28)
#define GPMI_IS_MX6Q(x) ((x)->pdev->id_entry->driver_data == IS_MX6Q)
+
+extern struct clk *mxs_dma_clk;
#endif
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index e14f8284e79f..6367eac4461b 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1051,12 +1051,13 @@ EXPORT_SYMBOL(nand_lock);
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: buffer to store read data
+ * @oob_required: caller requires OOB data read to chip->oob_poi
* @page: page number to read
*
* Not for syndrome calculating ecc controllers, which use a special oob layout
*/
static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
- uint8_t *buf, int page)
+ uint8_t *buf, int oob_required, int page)
{
chip->read_buf(mtd, buf, mtd->writesize);
chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -1068,13 +1069,14 @@ static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: buffer to store read data
+ * @oob_required: caller requires OOB data read to chip->oob_poi
* @page: page number to read
*
* We need a special oob layout and handling even when OOB isn't used.
*/
static int nand_read_page_raw_syndrome(struct mtd_info *mtd,
- struct nand_chip *chip,
- uint8_t *buf, int page)
+ struct nand_chip *chip, uint8_t *buf,
+ int oob_required, int page)
{
int eccsize = chip->ecc.size;
int eccbytes = chip->ecc.bytes;
@@ -1111,10 +1113,11 @@ static int nand_read_page_raw_syndrome(struct mtd_info *mtd,
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: buffer to store read data
+ * @oob_required: caller requires OOB data read to chip->oob_poi
* @page: page number to read
*/
static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
- uint8_t *buf, int page)
+ uint8_t *buf, int oob_required, int page)
{
int i, eccsize = chip->ecc.size;
int eccbytes = chip->ecc.bytes;
@@ -1124,7 +1127,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
uint8_t *ecc_code = chip->buffers->ecccode;
uint32_t *eccpos = chip->ecc.layout->eccpos;
- chip->ecc.read_page_raw(mtd, chip, buf, page);
+ chip->ecc.read_page_raw(mtd, chip, buf, 1, page);
for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
chip->ecc.calculate(mtd, p, &ecc_calc[i]);
@@ -1239,12 +1242,13 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: buffer to store read data
+ * @oob_required: caller requires OOB data read to chip->oob_poi
* @page: page number to read
*
* Not for syndrome calculating ecc controllers which need a special oob layout
*/
static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
- uint8_t *buf, int page)
+ uint8_t *buf, int oob_required, int page)
{
int i, eccsize = chip->ecc.size;
int eccbytes = chip->ecc.bytes;
@@ -1284,6 +1288,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: buffer to store read data
+ * @oob_required: caller requires OOB data read to chip->oob_poi
* @page: page number to read
*
* Hardware ECC for large page chips, require OOB to be read first.
@@ -1294,7 +1299,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
* overwriting the NAND manufacturer bad block markings.
*/
static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
- struct nand_chip *chip, uint8_t *buf, int page)
+ struct nand_chip *chip, uint8_t *buf, int oob_required, int page)
{
int i, eccsize = chip->ecc.size;
int eccbytes = chip->ecc.bytes;
@@ -1333,13 +1338,14 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: buffer to store read data
+ * @oob_required: caller requires OOB data read to chip->oob_poi
* @page: page number to read
*
* The hw generator calculates the error syndrome automatically. Therefor
* we need a special oob layout and handling.
*/
static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
- uint8_t *buf, int page)
+ uint8_t *buf, int oob_required, int page)
{
int i, eccsize = chip->ecc.size;
int eccbytes = chip->ecc.bytes;
@@ -1443,7 +1449,7 @@ static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
struct mtd_oob_ops *ops)
{
- int chipnr, page, realpage, col, bytes, aligned;
+ int chipnr, page, realpage, col, bytes, aligned, oob_required;
struct nand_chip *chip = mtd->priv;
struct mtd_ecc_stats stats;
int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;
@@ -1468,6 +1474,7 @@ int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
buf = ops->datbuf;
oob = ops->oobbuf;
+ oob_required = oob ? 1 : 0;
while (1) {
bytes = min(mtd->writesize - col, readlen);
@@ -1485,13 +1492,15 @@ int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
/* Now read the page into the buffer */
if (unlikely(ops->mode == MTD_OOB_RAW))
ret = chip->ecc.read_page_raw(mtd, chip,
- bufpoi, page);
+ bufpoi,
+ oob_required,
+ page);
else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob)
ret = chip->ecc.read_subpage(mtd, chip,
col, bytes, bufpoi);
else
ret = chip->ecc.read_page(mtd, chip, bufpoi,
- page);
+ oob_required, page);
if (ret < 0)
break;
@@ -1893,11 +1902,12 @@ out:
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: data buffer
+ * @oob_required: must write chip->oob_poi to OOB
*
* Not for syndrome calculating ecc controllers, which use a special oob layout
*/
static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
- const uint8_t *buf)
+ const uint8_t *buf, int oob_required)
{
chip->write_buf(mtd, buf, mtd->writesize);
chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -1908,12 +1918,13 @@ static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: data buffer
+ * @oob_required: must write chip->oob_poi to OOB
*
* We need a special oob layout and handling even when ECC isn't checked.
*/
static void nand_write_page_raw_syndrome(struct mtd_info *mtd,
struct nand_chip *chip,
- const uint8_t *buf)
+ const uint8_t *buf, int oob_required)
{
int eccsize = chip->ecc.size;
int eccbytes = chip->ecc.bytes;
@@ -1947,9 +1958,10 @@ static void nand_write_page_raw_syndrome(struct mtd_info *mtd,
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: data buffer
+ * @oob_required: must write chip->oob_poi to OOB
*/
static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
- const uint8_t *buf)
+ const uint8_t *buf, int oob_required)
{
int i, eccsize = chip->ecc.size;
int eccbytes = chip->ecc.bytes;
@@ -1965,7 +1977,7 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
for (i = 0; i < chip->ecc.total; i++)
chip->oob_poi[eccpos[i]] = ecc_calc[i];
- chip->ecc.write_page_raw(mtd, chip, buf);
+ chip->ecc.write_page_raw(mtd, chip, buf, 1);
}
/**
@@ -1973,9 +1985,10 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: data buffer
+ * @oob_required: must write chip->oob_poi to OOB
*/
static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
- const uint8_t *buf)
+ const uint8_t *buf, int oob_required)
{
int i, eccsize = chip->ecc.size;
int eccbytes = chip->ecc.bytes;
@@ -2001,12 +2014,14 @@ static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: data buffer
+ * @oob_required: must write chip->oob_poi to OOB
*
* The hw generator calculates the error syndrome automatically. Therefor
* we need a special oob layout and handling.
*/
static void nand_write_page_syndrome(struct mtd_info *mtd,
- struct nand_chip *chip, const uint8_t *buf)
+ struct nand_chip *chip,
+ const uint8_t *buf, int oob_required)
{
int i, eccsize = chip->ecc.size;
int eccbytes = chip->ecc.bytes;
@@ -2045,21 +2060,23 @@ static void nand_write_page_syndrome(struct mtd_info *mtd,
* @mtd: MTD device structure
* @chip: NAND chip descriptor
* @buf: the data to write
+ * @oob_required: must write chip->oob_poi to OOB
* @page: page number to write
* @cached: cached programming
* @raw: use _raw version of write_page
*/
static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
- const uint8_t *buf, int page, int cached, int raw)
+ const uint8_t *buf, int oob_required, int page,
+ int cached, int raw)
{
int status;
chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
if (unlikely(raw))
- chip->ecc.write_page_raw(mtd, chip, buf);
+ chip->ecc.write_page_raw(mtd, chip, buf, oob_required);
else
- chip->ecc.write_page(mtd, chip, buf);
+ chip->ecc.write_page(mtd, chip, buf, oob_required);
/*
* Cached progamming disabled for now, Not sure if its worth the
@@ -2176,6 +2193,7 @@ int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
uint8_t *oob = ops->oobbuf;
uint8_t *buf = ops->datbuf;
int ret, subpage;
+ int oob_required = oob ? 1 : 0;
ops->retlen = 0;
if (!writelen)
@@ -2238,7 +2256,7 @@ int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
memset(chip->oob_poi, 0xff, mtd->oobsize);
}
- ret = chip->write_page(mtd, chip, wbuf, page, cached,
+ ret = chip->write_page(mtd, chip, wbuf, oob_required, page, cached,
(ops->mode == MTD_OOB_RAW));
if (ret)
break;
diff --git a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c b/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c
index 4670a503ceb4..ec5d85887b70 100644
--- a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c
+++ b/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c
@@ -362,6 +362,8 @@ gckVGHARDWARE_Construct(
/* Set default event mask. */
hardware->eventMask = 0xFFFFFFFF;
+ gcmkERR_BREAK(gckOS_AtomConstruct(Os, &hardware->pageTableDirty));
+
/* Set fast clear to auto. */
gcmkVERIFY_OK(gckVGHARDWARE_SetFastClear(hardware, -1));
@@ -384,6 +386,11 @@ gckVGHARDWARE_Construct(
}
while (gcvFALSE);
+ if (hardware->pageTableDirty != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Os, hardware->pageTableDirty));
+ }
+
if (hardware != gcvNULL)
{
gcmkVERIFY_OK(gckOS_Free(Os, hardware));
@@ -439,6 +446,11 @@ gckVGHARDWARE_Destroy(
Hardware->os, Hardware->idleSignal));
}
+ if (Hardware->pageTableDirty != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Hardware->os, Hardware->pageTableDirty));
+ }
+
/* Free the object. */
status = gckOS_Free(Hardware->os, Hardware);
gcmkFOOTER();
@@ -1277,26 +1289,6 @@ gceSTATUS gckVGHARDWARE_FlushMMU(
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
-#if gcdPOWER_MANAGEMENT
- /* Acquire the power management semaphore. */
- gcmkERR_BREAK(gckOS_AcquireSemaphore(Hardware->os,
- command->powerSemaphore));
-
- status = gckVGCOMMAND_Execute(
- command,
- commandBuffer
- );
- /* Acquire the power management semaphore. */
- gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Hardware->os,
- command->powerSemaphore));
-
- gcmkERR_BREAK(status);
-#else
- gcmkERR_BREAK(gckVGCOMMAND_Execute(
- command,
- commandBuffer
- ));
-#endif
}
while(gcvFALSE);
diff --git a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h b/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h
index bca6f57e0982..e3714b76db77 100644
--- a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h
+++ b/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h
@@ -68,7 +68,7 @@ struct _gckVGHARDWARE
gctUINT32 powerOffTimeout;
gctTHREAD timeIdleThread;
gctBOOL killThread;
-
+ gctPOINTER pageTableDirty;
};
#endif /* __gc_hal_kernel_hardware_h_ */
diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c
index 633081b09c07..d8898a376fe1 100644
--- a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c
+++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c
@@ -905,11 +905,12 @@ _DestroyContext(
/* Free state delta map. */
if (buffer->logical != gcvNULL)
{
- gcmkONERROR(gckOS_FreeContiguous(
- Context->os,
+ gcmkONERROR(gckEVENT_FreeContiguousMemory(
+ Context->hardware->kernel->eventObj,
+ Context->totalSize,
buffer->physical,
buffer->logical,
- Context->totalSize
+ gcvKERNEL_PIXEL
));
buffer->logical = gcvNULL;
diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
index 07c549e8f784..377ce32ed4c3 100644
--- a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
+++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
@@ -603,6 +603,8 @@ gckHARDWARE_Construct(
gcmkONERROR(gckOS_CreateMutex(Os, &hardware->powerMutex));
gcmkONERROR(gckOS_CreateSemaphore(Os, &hardware->globalSemaphore));
+ hardware->startIsr = gcvNULL;
+ hardware->stopIsr = gcvNULL;
#if gcdPOWEROFF_TIMEOUT
hardware->powerOffTimeout = gcdPOWEROFF_TIMEOUT;
@@ -1010,6 +1012,12 @@ gckHARDWARE_InitializeHardware(
}
}
+ /* Update GPU AXI cache atttribute. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00008,
+ 0x00002200));
+
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
@@ -2210,7 +2218,7 @@ gckHARDWARE_Link(
/* Append LINK(bytes / 8), FetchAddress. */
link = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (bytes >> 3) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (bytes >> 3) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
gcmkONERROR(
gckOS_WriteMemory(Hardware->os, logical, link));
@@ -2838,10 +2846,10 @@ gckHARDWARE_FlushMMU(
buffer[1]
= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
gcmkONERROR(gckCOMMAND_Execute(command, 8));
}
@@ -2849,9 +2857,9 @@ gckHARDWARE_FlushMMU(
{
flushSize = 16 * 4;
- gcmkONERROR(gckCOMMAND_Reserve(
+ gcmkONERROR(gckCOMMAND_Reserve(
command, flushSize, &pointer, &bufferSize
- ));
+ ));
buffer = (gctUINT32_PTR) pointer;
@@ -2860,8 +2868,8 @@ gckHARDWARE_FlushMMU(
gcmkONERROR(gckOS_GetPhysicalAddress(command->os, buffer, &physical));
/* Flush cache. */
- buffer[0]
- = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ buffer[0]
+ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
@@ -2903,7 +2911,7 @@ gckHARDWARE_FlushMMU(
buffer[8]
= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
- | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
buffer[9]
= (((((gctUINT32) (~0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) & ((((gctUINT32) (~0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))) );
@@ -3460,62 +3468,6 @@ _PowerEnum(gceCHIPPOWERSTATE State)
}
#endif
-static gceSTATUS
-_GetClock(
- IN gckHARDWARE Hardware,
- IN gceCHIPPOWERSTATE State,
- OUT gctUINT_PTR Clock
-)
-{
- gctUINT clock;
-
- /* Clocks. */
- static const gctUINT clocks[4] =
- {
- /* gcvPOWER_ON */
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (64) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
-
- /* gcvPOWER_OFF */
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
-
- /* gcvPOWER_IDLE */
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
-
- /* gcvPOWER_SUSPEND */
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
- };
-
- gcmkHEADER();
-
- gcmkVERIFY_ARGUMENT(State >= gcvPOWER_ON && State <= gcvPOWER_SUSPEND);
-
- clock = clocks[State];
-
-#if gcdENABLE_FSCALE_VAL_ADJUST
- if (State == gcvPOWER_ON)
- {
- clock = ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (Hardware->powerOnFscaleVal) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2)));
- }
-#endif
-
- *Clock = clock;
-
- gcmkFOOTER();
- return gcvSTATUS_OK;
-}
-
/*******************************************************************************
**
** gckHARDWARE_SetPowerManagementState
@@ -3555,6 +3507,9 @@ gckHARDWARE_SetPowerManagementState(
#endif
gctUINT32 process, thread;
gctBOOL commitEntered = gcvFALSE;
+ gctBOOL commandStarted = gcvFALSE;
+ gctBOOL isrStarted = gcvFALSE;
+
#if gcdENABLE_PROFILING
gctUINT64 time, freq, mutexTime, onTime, stallTime, stopTime, delayTime,
initTime, offTime, startTime, totalTime;
@@ -3619,6 +3574,34 @@ gckHARDWARE_SetPowerManagementState(
},
};
+ /* Clocks. */
+ static const gctUINT clocks[4] =
+ {
+ /* gcvPOWER_ON */
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (64) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
+
+ /* gcvPOWER_OFF */
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
+
+ /* gcvPOWER_IDLE */
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
+
+ /* gcvPOWER_SUSPEND */
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
+ };
+
gcmkHEADER_ARG("Hardware=0x%x State=%d", Hardware, State);
#if gcmIS_DEBUG(gcdDEBUG_TRACE)
gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
@@ -3759,7 +3742,14 @@ gckHARDWARE_SetPowerManagementState(
/* Grab control flags and clock. */
flag = flags[Hardware->chipPowerState][State];
- gcmkONERROR(_GetClock(Hardware, State, &clock));
+ clock = clocks[State];
+
+#if gcdENABLE_FSCALE_VAL_ADJUST
+ if (State == gcvPOWER_ON)
+ {
+ clock = ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (Hardware->powerOnFscaleVal) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2)));
+ }
+#endif
if (State == gcvPOWER_SUSPEND && Hardware->chipPowerState == gcvPOWER_OFF && broadcast)
{
@@ -4011,12 +4001,11 @@ gckHARDWARE_SetPowerManagementState(
/* Stop the command parser. */
gcmkONERROR(gckCOMMAND_Stop(command, gcvFALSE));
-#ifndef __QNXNTO__
/* Stop the Isr. */
- gcmkONERROR(Hardware->stopIsr(Hardware->isrContext));
-#else
- /* QNX does not need to attach-dettach ISP that often */
-#endif
+ if (Hardware->stopIsr)
+ {
+ gcmkONERROR(Hardware->stopIsr(Hardware->isrContext));
+ }
}
/* Get time until stopped. */
@@ -4101,14 +4090,14 @@ gckHARDWARE_SetPowerManagementState(
{
/* Start the command processor. */
gcmkONERROR(gckCOMMAND_Start(command));
+ commandStarted = gcvTRUE;
-#ifndef __QNXNTO__
- /* Start the Isr. */
- gcmkONERROR(Hardware->startIsr(Hardware->isrContext));
-#else
- /* XSUN: QNX does not need to attach-dettach ISP that often
- * with the current release */
-#endif
+ if (Hardware->startIsr)
+ {
+ /* Start the Isr. */
+ gcmkONERROR(Hardware->startIsr(Hardware->isrContext));
+ isrStarted = gcvTRUE;
+ }
/* Set NEW MMU. */
if (Hardware->mmuVersion != 0 && configMmu)
@@ -4198,6 +4187,16 @@ gckHARDWARE_SetPowerManagementState(
return gcvSTATUS_OK;
OnError:
+ if (commandStarted)
+ {
+ gcmkVERIFY_OK(gckCOMMAND_Stop(command, gcvFALSE));
+ }
+
+ if (isrStarted)
+ {
+ gcmkVERIFY_OK(Hardware->stopIsr(Hardware->isrContext));
+ }
+
if (commitEntered)
{
/* Release the command queue mutex. */
@@ -4277,33 +4276,33 @@ gckHARDWARE_SetFscaleValue(
gctUINT32 clock;
gctBOOL acquired = gcvFALSE;
- gcmkHEADER_ARG("Hardware=0x%x FscaleVal=%d", Hardware, FscaleVal);
+ gcmkHEADER_ARG("Hardware=0x%x FscaleValue=%d", Hardware, FscaleValue);
gcmkVERIFY_ARGUMENT(FscaleValue > 0 && FscaleValue <= 64);
- Hardware->powerOnFscaleVal = FscaleValue;
-
gcmkONERROR(
gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE));
acquired = gcvTRUE;
+ Hardware->powerOnFscaleVal = FscaleValue;
+
if (Hardware->chipPowerState == gcvPOWER_ON)
{
gctUINT32 data;
gcmkONERROR(
- gckOS_ReadRegisterEx(Hardware->os,
- Hardware->core,
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
Hardware->powerBaseAddress
- + 0x00104,
+ + 0x00104,
&data));
/* Disable all clock gating. */
gcmkONERROR(
- gckOS_WriteRegisterEx(Hardware->os,
- Hardware->core,
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
Hardware->powerBaseAddress
- + 0x00104,
+ + 0x00104,
((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
@@ -4316,13 +4315,16 @@ gckHARDWARE_SetFscaleValue(
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)))
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1))))))) << (0 ? 11:11))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1))))))) << (0 ? 11:11)))));
- gcmkONERROR(_GetClock(Hardware, gcvPOWER_ON, &clock));
+ clock = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (FscaleValue) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)));
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
Hardware->core,
0x00000,
clock));
-
+
/* Done loading the frequency scaler. */
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
Hardware->core,
@@ -4331,12 +4333,11 @@ gckHARDWARE_SetFscaleValue(
/* Restore all clock gating. */
gcmkONERROR(
- gckOS_WriteRegisterEx(Hardware->os,
- Hardware->core,
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
Hardware->powerBaseAddress
- + 0x00104,
+ + 0x00104,
data));
-
}
gcmkVERIFY(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
@@ -4777,7 +4778,7 @@ _ResetGPU(
{
/* Disable clock gating. */
gcmkONERROR(gckOS_WriteRegisterEx(Os,
- Core,
+ Core,
Hardware->powerBaseAddress +
0x00104,
0x00000000));
@@ -4802,7 +4803,7 @@ _ResetGPU(
gcmkONERROR(gckOS_WriteRegisterEx(Os,
Core,
- 0x00000,
+ 0x00000,
((((gctUINT32) (0x00000900)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)))));
gcmkONERROR(gckOS_WriteRegisterEx(Os,
@@ -4889,6 +4890,8 @@ gckHARDWARE_Reset(
gceSTATUS status;
gckCOMMAND command;
gctBOOL acquired = gcvFALSE;
+ gctBOOL mutexAcquired = gcvFALSE;
+ gctUINT32 process, thread;
gcmkHEADER_ARG("Hardware=0x%x", Hardware);
@@ -4904,6 +4907,25 @@ gckHARDWARE_Reset(
gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
}
+ status = gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, 0);
+ if (status == gcvSTATUS_TIMEOUT)
+ {
+ gcmkONERROR(gckOS_GetProcessID(&process));
+ gcmkONERROR(gckOS_GetThreadID(&thread));
+
+ if ((Hardware->powerProcess == process)
+ && (Hardware->powerThread == thread))
+ {
+ /* No way to recovery from a error in power management. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+ }
+ else
+ {
+ mutexAcquired = gcvTRUE;
+ }
+
if (Hardware->chipPowerState == gcvPOWER_ON)
{
/* Acquire the power management semaphore. */
@@ -4920,10 +4942,11 @@ gckHARDWARE_Reset(
gcmkONERROR(gckCOMMAND_Stop(command, gcvTRUE));
}
-#ifndef __QNXNTO__
/* Stop isr, we will start it again when power on GPU. */
- gcmkONERROR(Hardware->stopIsr(Hardware->isrContext));
-#endif
+ if (Hardware->stopIsr)
+ {
+ gcmkONERROR(Hardware->stopIsr(Hardware->isrContext));
+ }
/* Hardware reset. */
status = gckOS_ResetGPU(Hardware->os, Hardware->core);
@@ -4936,7 +4959,9 @@ gckHARDWARE_Reset(
/* Force an OFF to ON power switch. */
Hardware->chipPowerState = gcvPOWER_OFF;
- gcmkONERROR(gckHARDWARE_SetPowerManagementState(Hardware, gcvPOWER_ON));
+
+ gcmkONERROR(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
+ mutexAcquired = gcvFALSE;
/* Success. */
gcmkFOOTER_NO();
@@ -4950,6 +4975,11 @@ OnError:
gckOS_ReleaseSemaphore(Hardware->os, command->powerSemaphore));
}
+ if (mutexAcquired)
+ {
+ gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex);
+ }
+
/* Return the error. */
gcmkFOOTER();
return status;
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
index b14bf79c038a..15ed52c75208 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
@@ -89,6 +89,18 @@ gctCONST_STRING _DispatchText[] =
};
#endif
+#if gcdENABLE_RECOVERY
+void
+_ResetFinishFunction(
+ gctPOINTER Data
+ )
+{
+ gckKERNEL kernel = (gckKERNEL)Data;
+
+ gckOS_AtomSet(kernel->os, kernel->resetAtom, 0);
+}
+#endif
+
/*******************************************************************************
**
** gckKERNEL_Construct
@@ -246,6 +258,17 @@ gckKERNEL_Construct(
/* Construct the gckMMU object. */
gcmkONERROR(
gckMMU_Construct(kernel, gcdMMU_SIZE, &kernel->mmu));
+
+#if gcdENABLE_RECOVERY
+ gcmkONERROR(
+ gckOS_AtomConstruct(Os, &kernel->resetAtom));
+
+ gcmkVERIFY_OK(
+ gckOS_CreateTimer(Os,
+ (gctTIMERFUNCTION)_ResetFinishFunction,
+ (gctPOINTER)kernel,
+ &kernel->resetFlagClearTimer));
+#endif
}
#if VIVANTE_PROFILER
@@ -302,6 +325,19 @@ OnError:
gcmkVERIFY_OK(gckOS_AtomDestroy(Os, kernel->atomClients));
}
+#if gcdENABLE_RECOVERY
+ if (kernel->resetAtom != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Os, kernel->resetAtom));
+ }
+
+ if (kernel->resetFlagClearTimer)
+ {
+ gcmkVERIFY_OK(gckOS_StopTimer(Os, kernel->resetFlagClearTimer));
+ gcmkVERIFY_OK(gckOS_DestoryTimer(Os, kernel->resetFlagClearTimer));
+ }
+#endif
+
if (kernel->dbCreated && kernel->db != gcvNULL)
{
if (kernel->db->dbMutex != gcvNULL)
@@ -409,6 +445,16 @@ gckKERNEL_Destroy(
/* Destroy the gckHARDWARE object. */
gcmkVERIFY_OK(gckHARDWARE_Destroy(Kernel->hardware));
+
+#if gcdENABLE_RECOVERY
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, Kernel->resetAtom));
+
+ if (Kernel->resetFlagClearTimer)
+ {
+ gcmkVERIFY_OK(gckOS_StopTimer(Kernel->os, Kernel->resetFlagClearTimer));
+ gcmkVERIFY_OK(gckOS_DestoryTimer(Kernel->os, Kernel->resetFlagClearTimer));
+ }
+#endif
}
/* Detsroy the client atom. */
@@ -787,6 +833,12 @@ gckKERNEL_Dispatch(
case gcvHAL_FREE_NON_PAGED_MEMORY:
physical = Interface->u.FreeNonPagedMemory.physical;
+ /* Unmap user logical out of physical memory first. */
+ gcmkONERROR(gckOS_UnmapUserLogical(Kernel->os,
+ physical,
+ Interface->u.FreeNonPagedMemory.bytes,
+ Interface->u.FreeNonPagedMemory.logical));
+
/* Free non-paged memory. */
gcmkONERROR(
gckOS_FreeNonPagedMemory(Kernel->os,
@@ -833,6 +885,12 @@ gckKERNEL_Dispatch(
case gcvHAL_FREE_CONTIGUOUS_MEMORY:
physical = Interface->u.FreeContiguousMemory.physical;
+ /* Unmap user logical out of physical memory first. */
+ gcmkONERROR(gckOS_UnmapUserLogical(Kernel->os,
+ physical,
+ Interface->u.FreeContiguousMemory.bytes,
+ Interface->u.FreeContiguousMemory.logical));
+
/* Free contiguous memory. */
gcmkONERROR(
gckOS_FreeContiguous(Kernel->os,
@@ -1124,10 +1182,70 @@ gckKERNEL_Dispatch(
break;
case gcvUSER_SIGNAL_WAIT:
- /* Wait on the signal. */
- status = gckOS_WaitUserSignal(Kernel->os,
- Interface->u.UserSignal.id,
- Interface->u.UserSignal.wait);
+#if gcdGPU_TIMEOUT
+ if (Interface->u.UserSignal.wait == gcvINFINITE)
+ {
+ gckHARDWARE hardware;
+ gctUINT32 timer = 0;
+
+ for(;;)
+ {
+ /* Wait on the signal. */
+ status = gckOS_WaitUserSignal(Kernel->os,
+ Interface->u.UserSignal.id,
+ gcdGPU_ADVANCETIMER);
+
+ if (status == gcvSTATUS_TIMEOUT)
+ {
+ gcmkONERROR(
+ gckOS_SignalQueryHardware(Kernel->os,
+ (gctSIGNAL)Interface->u.UserSignal.id,
+ &hardware));
+
+ if (hardware)
+ {
+ /* This signal is bound to a hardware,
+ ** so the timeout is limited by gcdGPU_TIMEOUT.
+ */
+ timer += gcdGPU_ADVANCETIMER;
+ }
+
+ if (timer >= gcdGPU_TIMEOUT)
+ {
+ gcmkONERROR(
+ gckOS_Broadcast(Kernel->os,
+ hardware,
+ gcvBROADCAST_GPU_STUCK));
+
+ timer = 0;
+
+ /* If a few process try to reset GPU, only one
+ ** of them can do the real reset, other processes
+ ** still need to wait for this signal is triggered,
+ ** which menas reset is finished.
+ */
+ continue;
+ }
+ }
+ else
+ {
+ /* Bail out on other error. */
+ gcmkONERROR(status);
+
+ /* Wait for signal successfully. */
+ break;
+ }
+ }
+ }
+ else
+#endif
+ {
+ /* Wait on the signal. */
+ status = gckOS_WaitUserSignal(Kernel->os,
+ Interface->u.UserSignal.id,
+ Interface->u.UserSignal.wait);
+ }
+
break;
case gcvUSER_SIGNAL_MAP:
@@ -1823,6 +1941,7 @@ gckKERNEL_Dispatch(
status = gcvSTATUS_NOT_SUPPORTED;
#endif
break;
+
default:
/* Invalid command. */
gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
@@ -1983,6 +2102,24 @@ gckKERNEL_AttachProcessEx(
Kernel->db->lastProcessID = PID;
}
+#if gcdENABLE_VG
+ if (Kernel->vg == gcvNULL)
+#endif
+ {
+ status = gckEVENT_Submit(Kernel->eventObj, gcvTRUE, gcvFALSE);
+
+ if (status == gcvSTATUS_INTERRUPTED && Kernel->eventObj->submitTimer)
+ {
+ gcmkONERROR(gckOS_StartTimer(Kernel->os,
+ Kernel->eventObj->submitTimer,
+ 1));
+ }
+ else
+ {
+ gcmkONERROR(status);
+ }
+ }
+
/* Decrement the number of clients attached. */
gcmkONERROR(
gckOS_AtomDecrement(Kernel->os, Kernel->atomClients, &old));
@@ -2530,7 +2667,7 @@ gckKERNEL_Recovery(
)
{
#if gcdENABLE_RECOVERY
-#define gcvEVENT_MASK 0x3FFFFFFF
+#define gcdEVENT_MASK 0x3FFFFFFF
gceSTATUS status;
gckEVENT eventObj;
gckHARDWARE hardware;
@@ -2538,7 +2675,7 @@ gckKERNEL_Recovery(
gctUINT32 processID;
gcskSECURE_CACHE_PTR cache;
#endif
-
+ gctUINT32 oldValue;
gcmkHEADER_ARG("Kernel=0x%x", Kernel);
/* Validate the arguemnts. */
@@ -2552,22 +2689,6 @@ gckKERNEL_Recovery(
hardware = Kernel->hardware;
gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
- /* Handle all outstanding events now. */
-#if gcdSMP
- gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, gcvEVENT_MASK));
-#else
- eventObj->pending = gcvEVENT_MASK;
-#endif
- gcmkONERROR(gckEVENT_Notify(eventObj, 1));
-
- /* Again in case more events got submitted. */
-#if gcdSMP
- gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, gcvEVENT_MASK));
-#else
- eventObj->pending = gcvEVENT_MASK;
-#endif
- gcmkONERROR(gckEVENT_Notify(eventObj, 2));
-
#if gcdSECURE_USER
/* Flush the secure mapping cache. */
gcmkONERROR(gckOS_GetProcessID(&processID));
@@ -2575,6 +2696,23 @@ gckKERNEL_Recovery(
gcmkONERROR(gckKERNEL_FlushTranslationCache(Kernel, cache, gcvNULL, 0));
#endif
+ gcmkONERROR(
+ gckOS_AtomicExchange(Kernel->os, Kernel->resetAtom, 1, &oldValue));
+
+ if (oldValue)
+ {
+ /* Some one else will recovery GPU. */
+ return gcvSTATUS_OK;
+ }
+
+ /* Start a timer to clear reset flag, before timer is expired,
+ ** other recovery request is ignored. */
+ gcmkVERIFY_OK(
+ gckOS_StartTimer(Kernel->os,
+ Kernel->resetFlagClearTimer,
+ gcdGPU_TIMEOUT - 500));
+
+
/* Try issuing a soft reset for the GPU. */
status = gckHARDWARE_Reset(hardware);
if (status == gcvSTATUS_NOT_SUPPORTED)
@@ -2591,6 +2729,22 @@ gckKERNEL_Recovery(
gcmkONERROR(status);
}
+ /* Handle all outstanding events now. */
+#if gcdSMP
+ gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, gcdEVENT_MASK));
+#else
+ eventObj->pending = gcdEVENT_MASK;
+#endif
+ gcmkONERROR(gckEVENT_Notify(eventObj, 1));
+
+ /* Again in case more events got submitted. */
+#if gcdSMP
+ gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, gcdEVENT_MASK));
+#else
+ eventObj->pending = gcdEVENT_MASK;
+#endif
+ gcmkONERROR(gckEVENT_Notify(eventObj, 2));
+
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
index b627f3b1d5f9..1f3c9ccc20a8 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
@@ -338,6 +338,11 @@ struct _gckKERNEL
gckDB db;
gctBOOL dbCreated;
+#if gcdENABLE_RECOVERY
+ gctPOINTER resetFlagClearTimer;
+ gctPOINTER resetAtom;
+#endif
+
/* Pointer to gckEVENT object. */
gcsTIMER timers[8];
gctUINT32 timeOut;
@@ -525,6 +530,8 @@ struct _gckEVENT
gcsEVENT_QUEUE_PTR freeList;
gcsEVENT_QUEUE repoList[gcdREPO_LIST_COUNT];
gctPOINTER eventListMutex;
+
+ gctPOINTER submitTimer;
};
/* Free all events belonging to a process. */
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c
index 8cf0509cfd92..fbaff6666a10 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c
@@ -30,6 +30,9 @@
#define _GC_OBJ_ZONE gcvZONE_COMMAND
+#if gcdENABLE_FSCALE_VAL_ADJUST
+extern int thermal_hot;
+#endif
/******************************************************************************\
********************************* Support Code *********************************
\******************************************************************************/
@@ -1080,6 +1083,24 @@ gckCOMMAND_Commit(
/* Extract the gckHARDWARE and gckEVENT objects. */
hardware = Command->kernel->hardware;
+#if gcdENABLE_FSCALE_VAL_ADJUST
+ if(hardware->core == gcvCORE_MAJOR){
+ static gctUINT orgFscale,minFscale,maxFscale;
+ static gctBOOL bAlreadyTooHot = gcvFALSE;
+ if((thermal_hot > 0) && (!bAlreadyTooHot)) {
+ gckHARDWARE_GetFscaleValue(hardware,&orgFscale,&minFscale, &maxFscale);
+ gckHARDWARE_SetFscaleValue(hardware, minFscale);
+ bAlreadyTooHot = gcvTRUE;
+ gckOS_Print("System is too hot. GPU3D will work at %d/64 clock.\n", minFscale);
+ } else if((!(thermal_hot > 0)) && bAlreadyTooHot) {
+ gckHARDWARE_SetFscaleValue(hardware, orgFscale);
+ gckOS_Print("Hot alarm is canceled. GPU3D clock will return to %d/64\n", orgFscale);
+ bAlreadyTooHot = gcvFALSE;
+ }
+
+ }
+#endif
+
/* Check wehther we need to copy the structures or not. */
gcmkONERROR(gckOS_QueryNeedCopy(Command->os, ProcessID, &needCopy));
@@ -2619,6 +2640,12 @@ gckCOMMAND_Detach(
/* Construct a gckCONTEXT object. */
gcmkONERROR(gckCONTEXT_Destroy(Context));
+ if (Command->currContext == Context)
+ {
+ /* Detach from gckCOMMAND object if the destoryed context is current context. */
+ Command->currContext = gcvNULL;
+ }
+
/* Release the context switching mutex. */
gcmkONERROR(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
acquired = gcvFALSE;
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c
index 227ab683778e..e5b659262a46 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c
@@ -97,6 +97,30 @@ gcsQUEUE_UPDATE_CONTROL;
/******************************************************************************\
********************************* Support Code *********************************
\******************************************************************************/
+static gceSTATUS
+_FlushMMU(
+ IN gckVGCOMMAND Command
+ )
+{
+ gceSTATUS status;
+ gctUINT32 oldValue;
+ gckVGHARDWARE hardware = Command->hardware;
+
+ gcmkONERROR(gckOS_AtomicExchange(Command->os,
+ hardware->pageTableDirty,
+ 0,
+ &oldValue));
+
+ if (oldValue)
+ {
+ /* Page Table is upated, flush mmu before commit. */
+ gcmkONERROR(gckVGHARDWARE_FlushMMU(hardware));
+ }
+
+ return gcvSTATUS_OK;
+OnError:
+ return status;
+}
static gceSTATUS
_WaitForIdle(
@@ -577,6 +601,67 @@ _FreeTaskContainer(
}
}
+gceSTATUS
+_RemoveRecordFromProcesDB(
+ IN gckVGCOMMAND Command,
+ IN gcsTASK_HEADER_PTR Task
+ )
+{
+ gcsTASK_PTR task = (gcsTASK_PTR)((gctUINT8_PTR)Task - sizeof(gcsTASK));
+ gcsTASK_FREE_VIDEO_MEMORY_PTR freeVideoMemory;
+ gcsTASK_UNLOCK_VIDEO_MEMORY_PTR unlockVideoMemory;
+ gctINT pid;
+ gctUINT32 size;
+
+ /* Get the total size of all tasks. */
+ size = task->size;
+
+ gcmkVERIFY_OK(gckOS_GetProcessID((gctUINT32_PTR)&pid));
+
+ do
+ {
+ switch (Task->id)
+ {
+ case gcvTASK_FREE_VIDEO_MEMORY:
+ freeVideoMemory = (gcsTASK_FREE_VIDEO_MEMORY_PTR)Task;
+
+ /* Remove record from process db. */
+ gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
+ Command->kernel->kernel,
+ pid,
+ gcvDB_VIDEO_MEMORY,
+ freeVideoMemory->node));
+
+ /* Advance to next task. */
+ size -= sizeof(gcsTASK_FREE_VIDEO_MEMORY);
+ Task = (gcsTASK_HEADER_PTR)(freeVideoMemory + 1);
+
+ break;
+ case gcvTASK_UNLOCK_VIDEO_MEMORY:
+ unlockVideoMemory = (gcsTASK_UNLOCK_VIDEO_MEMORY_PTR)Task;
+
+ /* Remove record from process db. */
+ gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
+ Command->kernel->kernel,
+ pid,
+ gcvDB_VIDEO_MEMORY_LOCKED,
+ unlockVideoMemory->node));
+
+ /* Advance to next task. */
+ size -= sizeof(gcsTASK_UNLOCK_VIDEO_MEMORY);
+ Task = (gcsTASK_HEADER_PTR)(unlockVideoMemory + 1);
+
+ break;
+ default:
+ /* Skip the whole task. */
+ size = 0;
+ break;
+ }
+ }
+ while(size);
+
+ return gcvSTATUS_OK;
+}
/******************************************************************************\
********************************* Task Scheduling ******************************
@@ -701,6 +786,8 @@ _ScheduleTasks(
{
gcsTASK_HEADER_PTR taskHeader = (gcsTASK_HEADER_PTR) (userTask + 1);
+ gcmkVERIFY_OK(_RemoveRecordFromProcesDB(Command, taskHeader));
+
gcmkTRACE_ZONE(
gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
" task ID = %d, size = %d\n",
@@ -3363,6 +3450,8 @@ gckVGCOMMAND_Commit(
break;
}
#endif
+ gcmkERR_BREAK(_FlushMMU(Command));
+
do
{
/* Assign a context ID if not yet assigned. */
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
index d94d8e2d6704..9dbb9d3cab25 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
@@ -1144,6 +1144,12 @@ gckKERNEL_DestroyProcessDB(
break;
case gcvDB_NON_PAGED:
+ /* Unmap user logical memory first. */
+ status = gckOS_UnmapUserLogical(Kernel->os,
+ record->physical,
+ record->bytes,
+ record->data);
+
/* Free the non paged memory. */
status = gckOS_FreeNonPagedMemory(Kernel->os,
record->bytes,
@@ -1156,11 +1162,18 @@ gckKERNEL_DestroyProcessDB(
break;
case gcvDB_CONTIGUOUS:
+ /* Unmap user logical memory first. */
+ status = gckOS_UnmapUserLogical(Kernel->os,
+ record->physical,
+ record->bytes,
+ record->data);
+
/* Free the contiguous memory. */
- status = gckOS_FreeContiguous(Kernel->os,
- record->physical,
- record->data,
- record->bytes);
+ status = gckEVENT_FreeContiguousMemory(Kernel->eventObj,
+ record->bytes,
+ record->physical,
+ record->data,
+ gcvKERNEL_PIXEL);
gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
"DB: CONTIGUOUS 0x%x bytes=%lu (status=%d)",
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
index e1b21a0df70b..d38312d3bf9b 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
@@ -328,6 +328,12 @@ __RemoveRecordFromProcessDB(
Record->info.u.UnmapUserMemory.info));
break;
+ case gcvHAL_SIGNAL:
+ gcmkVERIFY_OK(gckOS_SignalSetHardware(Event->os,
+ Record->info.u.Signal.signal,
+ Event->kernel->hardware));
+ break;
+
default:
break;
}
@@ -338,6 +344,15 @@ __RemoveRecordFromProcessDB(
return gcvSTATUS_OK;
}
+void
+_SubmitTimerFunction(
+ gctPOINTER Data
+ )
+{
+ gckEVENT event = (gckEVENT)Data;
+ gcmkVERIFY_OK(gckEVENT_Submit(event, gcvTRUE, gcvFALSE));
+}
+
/******************************************************************************\
******************************* gckEVENT API Code *******************************
\******************************************************************************/
@@ -430,6 +445,11 @@ gckEVENT_Construct(
gcmkONERROR(gckOS_AtomConstruct(os, &eventObj->pending));
#endif
+ gcmkVERIFY_OK(gckOS_CreateTimer(os,
+ _SubmitTimerFunction,
+ (gctPOINTER)eventObj,
+ &eventObj->submitTimer));
+
/* Return pointer to the gckEVENT object. */
*Event = eventObj;
@@ -511,6 +531,12 @@ gckEVENT_Destroy(
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
+ if (Event->submitTimer != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_StopTimer(Event->os, Event->submitTimer));
+ gcmkVERIFY_OK(gckOS_DestoryTimer(Event->os, Event->submitTimer));
+ }
+
/* Delete the queue mutex. */
gcmkVERIFY_OK(gckOS_DeleteMutex(Event->os, Event->eventQueueMutex));
@@ -723,11 +749,6 @@ gckEVENT_GetEvent(
__FUNCTION__, __LINE__
);
- /* Broadcast GPU stuck. */
- gcmkONERROR(gckOS_Broadcast(Event->os,
- Event->kernel->hardware,
- gcvBROADCAST_GPU_STUCK));
-
/* Bail out. */
gcmkONERROR(gcvSTATUS_GPU_NOT_RESPONDING);
}
@@ -961,6 +982,31 @@ gckEVENT_AddList(
queue->tail = record;
}
+ /* Unmap user space logical address.
+ * Linux kernel does not support unmap the memory of other process any more since 3.5.
+ * Let's unmap memory of self process before submit the event to gpu.
+ * */
+ switch(Interface->command)
+ {
+ case gcvHAL_FREE_NON_PAGED_MEMORY:
+ gcmkONERROR(gckOS_UnmapUserLogical(
+ Event->os,
+ Interface->u.FreeNonPagedMemory.physical,
+ Interface->u.FreeNonPagedMemory.bytes,
+ Interface->u.FreeNonPagedMemory.logical));
+ break;
+ case gcvHAL_FREE_CONTIGUOUS_MEMORY:
+ gcmkONERROR(gckOS_UnmapUserLogical(
+ Event->os,
+ Interface->u.FreeContiguousMemory.physical,
+ Interface->u.FreeContiguousMemory.bytes,
+ Interface->u.FreeContiguousMemory.logical));
+ break;
+ default:
+ break;
+ }
+
+
/* Release the mutex. */
gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
@@ -1494,6 +1540,14 @@ OnError:
Event->queues[id].head = gcvNULL;
}
+ if (status == gcvSTATUS_GPU_NOT_RESPONDING)
+ {
+ /* Broadcast GPU stuck. */
+ status = gckOS_Broadcast(Event->os,
+ Event->kernel->hardware,
+ gcvBROADCAST_GPU_STUCK);
+ }
+
/* Return the status. */
gcmkFOOTER();
return status;
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c
index f7a70ac96f58..9012599b1bef 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c
@@ -79,6 +79,23 @@ static gcsSharedPageTable_PTR sharedPageTable = gcvNULL;
#endif
static gceSTATUS
+_FillPageTable(
+ IN gctUINT32_PTR PageTable,
+ IN gctUINT32 PageCount,
+ IN gctUINT32 EntryValue
+)
+{
+ gctUINT i;
+
+ for (i = 0; i < PageCount; i++)
+ {
+ PageTable[i] = EntryValue;
+ }
+
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
_Link(
IN gckMMU Mmu,
IN gctUINT32 Index,
@@ -1036,7 +1053,7 @@ gckMMU_AllocatePages(
}
/* Mark node as used. */
- pageTable[index] = gcvMMU_USED;
+ gcmkONERROR(_FillPageTable(&pageTable[index], PageCount, gcvMMU_USED));
/* Return pointer to page table. */
*PageTable = &pageTable[index];
@@ -1112,6 +1129,8 @@ gckMMU_FreePages(
)
{
gctUINT32_PTR pageTable;
+ gceSTATUS status;
+ gctBOOL acquired = gcvFALSE;
gcmkHEADER_ARG("Mmu=0x%x PageTable=0x%x PageCount=%lu",
Mmu, PageTable, PageCount);
@@ -1124,7 +1143,11 @@ gckMMU_FreePages(
/* Convert the pointer. */
pageTable = (gctUINT32_PTR) PageTable;
+ gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
#if gcdMMU_CLEAR_VALUE
+ if (Mmu->hardware->mmuVersion == 0)
{
gctUINT32 i;
@@ -1150,9 +1173,21 @@ gckMMU_FreePages(
/* We have free nodes. */
Mmu->freeNodes = gcvTRUE;
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
+ acquired = gcvFALSE;
+
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
+ }
+
+ gcmkFOOTER();
+ return status;
}
gceSTATUS
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c
index a4a5e0c802f5..46d1761dac2c 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c
@@ -344,9 +344,6 @@ gceSTATUS gckVGMMU_AllocatePages(
if (!allocated)
{
- /* Flush the MMU. */
- status = gckVGHARDWARE_FlushMMU(Mmu->hardware);
-
if (status >= 0)
{
/* Walk all entries until we find enough slots. */
@@ -506,4 +503,22 @@ gckVGMMU_SetPage(
return gcvSTATUS_OK;
}
+gceSTATUS
+gckVGMMU_Flush(
+ IN gckVGMMU Mmu
+ )
+{
+ gckVGHARDWARE hardware;
+
+ gcmkHEADER_ARG("Mmu=0x%x", Mmu);
+
+ hardware = Mmu->hardware;
+ gcmkVERIFY_OK(
+ gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
#endif /* gcdENABLE_VG */
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c
index bb5330c2bbb0..ee63e9b59373 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c
@@ -438,6 +438,14 @@ gceSTATUS gckVGKERNEL_Dispatch(
break;
case gcvHAL_FREE_NON_PAGED_MEMORY:
+ /* Unmap user logical out of physical memory first. */
+ gcmkERR_BREAK(gckOS_UnmapUserLogical(
+ Kernel->os,
+ kernelInterface->u.AllocateNonPagedMemory.physical,
+ kernelInterface->u.AllocateNonPagedMemory.bytes,
+ kernelInterface->u.AllocateNonPagedMemory.logical
+ ));
+
/* Free non-paged memory. */
gcmkERR_BREAK(gckOS_FreeNonPagedMemory(
Kernel->os,
@@ -459,6 +467,14 @@ gceSTATUS gckVGKERNEL_Dispatch(
break;
case gcvHAL_FREE_CONTIGUOUS_MEMORY:
+ /* Unmap user logical out of physical memory first. */
+ gcmkERR_BREAK(gckOS_UnmapUserLogical(
+ Kernel->os,
+ kernelInterface->u.AllocateNonPagedMemory.physical,
+ kernelInterface->u.AllocateNonPagedMemory.bytes,
+ kernelInterface->u.AllocateNonPagedMemory.logical
+ ));
+
/* Free contiguous memory. */
gcmkERR_BREAK(gckOS_FreeContiguous(
Kernel->os,
@@ -522,6 +538,14 @@ gceSTATUS gckVGKERNEL_Dispatch(
kernelInterface->u.AllocateLinearVideoMemory.type,
&kernelInterface->u.AllocateLinearVideoMemory.node
));
+
+ gcmkERR_BREAK(gckKERNEL_AddProcessDB(Kernel,
+ processID, gcvDB_VIDEO_MEMORY,
+ Interface->u.AllocateLinearVideoMemory.node,
+ gcvNULL,
+ kernelInterface->u.AllocateLinearVideoMemory.bytes
+ ));
+
break;
case gcvHAL_FREE_VIDEO_MEMORY:
@@ -544,6 +568,13 @@ gceSTATUS gckVGKERNEL_Dispatch(
gcmkERR_BREAK(gckVIDMEM_Free(
Interface->u.FreeVideoMemory.node
));
+
+ gcmkERR_BREAK(gckKERNEL_RemoveProcessDB(
+ Kernel,
+ processID, gcvDB_VIDEO_MEMORY,
+ Interface->u.FreeVideoMemory.node
+ ));
+
break;
case gcvHAL_MAP_MEMORY:
@@ -637,6 +668,12 @@ gceSTATUS gckVGKERNEL_Dispatch(
Interface->u.LockVideoMemory.address =
gcmPTR2INT(Interface->u.LockVideoMemory.memory);
#endif
+ gcmkERR_BREAK(
+ gckKERNEL_AddProcessDB(Kernel,
+ processID, gcvDB_VIDEO_MEMORY_LOCKED,
+ Interface->u.LockVideoMemory.node,
+ gcvNULL,
+ 0));
break;
case gcvHAL_UNLOCK_VIDEO_MEMORY:
@@ -674,6 +711,16 @@ gceSTATUS gckVGKERNEL_Dispatch(
bytes));
}
#endif
+
+ if (Interface->u.UnlockVideoMemory.asynchroneous == gcvFALSE)
+ {
+ /* There isn't a event to unlock this node, remove record now */
+ gcmkERR_BREAK(
+ gckKERNEL_RemoveProcessDB(Kernel,
+ processID, gcvDB_VIDEO_MEMORY_LOCKED,
+ Interface->u.UnlockVideoMemory.node));
+ }
+
break;
case gcvHAL_USER_SIGNAL:
#if !USE_NEW_LINUX_SIGNAL
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
index 9d6da636755c..dc39b3927fff 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
@@ -1830,7 +1830,11 @@ gckVIDMEM_Lock(
#endif
#if gcdENABLE_VG
- if (Kernel->core != gcvCORE_VG)
+ if (Kernel->core == gcvCORE_VG)
+ {
+ gcmkONERROR(gckVGMMU_Flush(Kernel->vg->mmu));
+ }
+ else
#endif
{
gcmkONERROR(gckMMU_Flush(Kernel->mmu));
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
index 25ec3eab95f2..5bf887054e04 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
@@ -30,6 +30,9 @@
#include "gc_hal_base.h"
#include "gc_hal_profiler.h"
#include "gc_hal_driver.h"
+#ifndef VIVANTE_NO_3D
+#include "gc_hal_statistics.h"
+#endif
#ifdef __cplusplus
extern "C" {
@@ -503,6 +506,17 @@ gckOS_UnmapMemory(
IN gctPOINTER Logical
);
+/* Unmap user logical memory out of physical memory.
+ * This function is only supported in Linux currently.
+ */
+gceSTATUS
+gckOS_UnmapUserLogical(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ IN gctPOINTER Logical
+ );
+
/* Create a new mutex. */
gceSTATUS
gckOS_CreateMutex(
@@ -1950,6 +1964,22 @@ gckHARDWARE_QueryPowerManagementState(
OUT gceCHIPPOWERSTATE* State
);
+#if gcdENABLE_FSCALE_VAL_ADJUST
+gceSTATUS
+gckHARDWARE_SetFscaleValue(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 FscaleValue
+ );
+
+gceSTATUS
+gckHARDWARE_GetFscaleValue(
+ IN gckHARDWARE Hardware,
+ IN gctUINT * FscaleValue,
+ IN gctUINT * MinFscaleValue,
+ IN gctUINT * MaxFscaleValue
+ );
+#endif
+
#if gcdPOWEROFF_TIMEOUT
gceSTATUS
gckHARDWARE_SetPowerOffTimeout(
@@ -2361,7 +2391,19 @@ gckHARDWARE_QueryProfileRegisters(
);
#endif
+gceSTATUS
+gckOS_SignalQueryHardware(
+ IN gckOS Os,
+ IN gctSIGNAL Signal,
+ OUT gckHARDWARE * Hardware
+ );
+gceSTATUS
+gckOS_SignalSetHardware(
+ IN gckOS Os,
+ IN gctSIGNAL Signal,
+ gckHARDWARE Hardware
+ );
#ifdef __cplusplus
}
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h
index 85b41312f772..7cfd2e119f00 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h
@@ -747,6 +747,25 @@ gcoOS_FreeContiguous(
IN gctSIZE_T Bytes
);
+/* Allocate video memory. */
+gceSTATUS
+gcoOS_AllocateVideoMemory(
+ IN gcoOS Os,
+ IN gctBOOL InUserSpace,
+ IN gctBOOL InCacheable,
+ IN OUT gctSIZE_T * Bytes,
+ OUT gctUINT32 * Physical,
+ OUT gctPOINTER * Logical,
+ OUT gctPOINTER * Handle
+ );
+
+/* Free video memory. */
+gceSTATUS
+gcoOS_FreeVideoMemory(
+ IN gcoOS Os,
+ IN gctPOINTER Handle
+ );
+
#if gcdENABLE_BANK_ALIGNMENT
gceSTATUS
gcoSURF_GetBankOffsetBytes(
@@ -3659,6 +3678,42 @@ gckOS_DebugStatus2Name(
#define MAX_LOOP_COUNT 0x7FFFFFFF
+/******************************************************************************\
+****************************** User Debug Option ******************************
+\******************************************************************************/
+
+/* User option. */
+typedef enum _gceDEBUG_MSG
+{
+ gcvDEBUG_MSG_NONE,
+ gcvDEBUG_MSG_ERROR,
+ gcvDEBUG_MSG_WARNING
+}
+gceDEBUG_MSG;
+
+typedef struct _gcsUSER_DEBUG_OPTION
+{
+ gceDEBUG_MSG debugMsg;
+}
+gcsUSER_DEBUG_OPTION;
+
+gcsUSER_DEBUG_OPTION *
+gcGetUserDebugOption(
+ void
+ );
+
+#define gcmUSER_DEBUG_MSG(level, ...) \
+ do \
+ { \
+ if (level <= gcGetUserDebugOption()->debugMsg) \
+ { \
+ gcoOS_Print(__VA_ARGS__); \
+ } \
+ } while (gcvFALSE)
+
+#define gcmUSER_DEBUG_ERROR_MSG(...) gcmUSER_DEBUG_MSG(gcvDEBUG_MSG_ERROR, "Error: " __VA_ARGS__)
+#define gcmUSER_DEBUG_WARNING_MSG(...) gcmUSER_DEBUG_MSG(gcvDEBUG_MSG_WARNING, "Warring: " __VA_ARGS__)
+
#ifdef __cplusplus
}
#endif
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h
index d0a98a2b71c8..86ab105b389a 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h
@@ -27,216 +27,11 @@
/* Include VDK types. */
#include "gc_hal_types.h"
#include "gc_hal_base.h"
+#include "gc_hal_eglplatform_type.h"
#ifdef __cplusplus
extern "C" {
#endif
-/*******************************************************************************
-** Events. *********************************************************************
-*/
-
-typedef enum _halEventType
-{
- /* Keyboard event. */
- HAL_KEYBOARD,
-
- /* Mouse move event. */
- HAL_POINTER,
-
- /* Mouse button event. */
- HAL_BUTTON,
-
- /* Application close event. */
- HAL_CLOSE,
-
- /* Application window has been updated. */
- HAL_WINDOW_UPDATE
-}
-halEventType;
-
-/* Scancodes for keyboard. */
-typedef enum _halKeys
-{
- HAL_UNKNOWN = -1,
-
- HAL_BACKSPACE = 0x08,
- HAL_TAB,
- HAL_ENTER = 0x0D,
- HAL_ESCAPE = 0x1B,
-
- HAL_SPACE = 0x20,
- HAL_SINGLEQUOTE = 0x27,
- HAL_PAD_ASTERISK = 0x2A,
- HAL_COMMA = 0x2C,
- HAL_HYPHEN,
- HAL_PERIOD,
- HAL_SLASH,
- HAL_0,
- HAL_1,
- HAL_2,
- HAL_3,
- HAL_4,
- HAL_5,
- HAL_6,
- HAL_7,
- HAL_8,
- HAL_9,
- HAL_SEMICOLON = 0x3B,
- HAL_EQUAL = 0x3D,
- HAL_A = 0x41,
- HAL_B,
- HAL_C,
- HAL_D,
- HAL_E,
- HAL_F,
- HAL_G,
- HAL_H,
- HAL_I,
- HAL_J,
- HAL_K,
- HAL_L,
- HAL_M,
- HAL_N,
- HAL_O,
- HAL_P,
- HAL_Q,
- HAL_R,
- HAL_S,
- HAL_T,
- HAL_U,
- HAL_V,
- HAL_W,
- HAL_X,
- HAL_Y,
- HAL_Z,
- HAL_LBRACKET,
- HAL_BACKSLASH,
- HAL_RBRACKET,
- HAL_BACKQUOTE = 0x60,
-
- HAL_F1 = 0x80,
- HAL_F2,
- HAL_F3,
- HAL_F4,
- HAL_F5,
- HAL_F6,
- HAL_F7,
- HAL_F8,
- HAL_F9,
- HAL_F10,
- HAL_F11,
- HAL_F12,
-
- HAL_LCTRL,
- HAL_RCTRL,
- HAL_LSHIFT,
- HAL_RSHIFT,
- HAL_LALT,
- HAL_RALT,
- HAL_CAPSLOCK,
- HAL_NUMLOCK,
- HAL_SCROLLLOCK,
- HAL_PAD_0,
- HAL_PAD_1,
- HAL_PAD_2,
- HAL_PAD_3,
- HAL_PAD_4,
- HAL_PAD_5,
- HAL_PAD_6,
- HAL_PAD_7,
- HAL_PAD_8,
- HAL_PAD_9,
- HAL_PAD_HYPHEN,
- HAL_PAD_PLUS,
- HAL_PAD_SLASH,
- HAL_PAD_PERIOD,
- HAL_PAD_ENTER,
- HAL_SYSRQ,
- HAL_PRNTSCRN,
- HAL_BREAK,
- HAL_UP,
- HAL_LEFT,
- HAL_RIGHT,
- HAL_DOWN,
- HAL_HOME,
- HAL_END,
- HAL_PGUP,
- HAL_PGDN,
- HAL_INSERT,
- HAL_DELETE,
- HAL_LWINDOW,
- HAL_RWINDOW,
- HAL_MENU,
- HAL_POWER,
- HAL_SLEEP,
- HAL_WAKE
-}
-halKeys;
-
-/* Structure that defined keyboard mapping. */
-typedef struct _halKeyMap
-{
- /* Normal key. */
- halKeys normal;
-
- /* Extended key. */
- halKeys extended;
-}
-halKeyMap;
-
-/* Event structure. */
-typedef struct _halEvent
-{
- /* Event type. */
- halEventType type;
-
- /* Event data union. */
- union _halEventData
- {
- /* Event data for keyboard. */
- struct _halKeyboard
- {
- /* Scancode. */
- halKeys scancode;
-
- /* ASCII characte of the key pressed. */
- gctCHAR key;
-
- /* Flag whether the key was pressed (1) or released (0). */
- gctCHAR pressed;
- }
- keyboard;
-
- /* Event data for pointer. */
- struct _halPointer
- {
- /* Current pointer coordinate. */
- gctINT x;
- gctINT y;
- }
- pointer;
-
- /* Event data for mouse buttons. */
- struct _halButton
- {
- /* Left button state. */
- gctINT left;
-
- /* Middle button state. */
- gctINT middle;
-
- /* Right button state. */
- gctINT right;
-
- /* Current pointer coordinate. */
- gctINT x;
- gctINT y;
- }
- button;
- }
- data;
-}
-halEvent;
#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
/* Win32 and Windows CE platforms. */
@@ -379,7 +174,16 @@ typedef void * HALNativePixmapType;
#endif
-
+/* define DUMMY according to the system */
+#if defined(EGL_API_WL)
+# define WL_DUMMY (31415926)
+# define EGL_DUMMY WL_DUMMY
+#elif defined(__ANDROID__) || defined(ANDROID)
+# define ANDROID_DUMMY (31415926)
+# define EGL_DUMMY ANDROID_DUMMY
+#else
+# define EGL_DUMMY (31415926)
+#endif
/*******************************************************************************
** Display. ********************************************************************
@@ -408,51 +212,7 @@ gcoOS_GetDisplayInfo(
OUT gctINT * BitsPerPixel
);
-/* VFK_DISPLAY_INFO structure defining information returned by
- vdkGetDisplayInfoEx. */
-typedef struct _halDISPLAY_INFO
-{
- /* The size of the display in pixels. */
- gctINT width;
- gctINT height;
-
- /* The stride of the dispay. -1 is returned if the stride is not known
- ** for the specified display.*/
- gctINT stride;
-
- /* The color depth of the display in bits per pixel. */
- gctINT bitsPerPixel;
- /* The logical pointer to the display memory buffer. NULL is returned
- ** if the pointer is not known for the specified display. */
- gctPOINTER logical;
-
- /* The physical address of the display memory buffer. ~0 is returned
- ** if the address is not known for the specified display. */
- gctSIZE_T physical;
-
- gctBOOL wrapFB; /* true if compositor, false otherwise. */
-
-#ifndef __QNXNTO__
- /* 355_FB_MULTI_BUFFER */
- gctINT multiBuffer;
- gctINT backBufferY;
-#endif
-
- /* The color info of the display. */
- gctUINT alphaLength;
- gctUINT alphaOffset;
- gctUINT redLength;
- gctUINT redOffset;
- gctUINT greenLength;
- gctUINT greenOffset;
- gctUINT blueLength;
- gctUINT blueOffset;
-
- /* Display flip support. */
- gctINT flip;
-}
-halDISPLAY_INFO;
gceSTATUS
gcoOS_GetDisplayInfoEx(
@@ -498,6 +258,19 @@ gcoOS_SetDisplayVirtual(
);
gceSTATUS
+gcoOS_SetSwapInterval(
+ IN HALNativeDisplayType Display,
+ IN gctINT Interval
+);
+
+gceSTATUS
+gcoOS_GetSwapInterval(
+ IN HALNativeDisplayType Display,
+ IN gctINT_PTR Min,
+ IN gctINT_PTR Max
+);
+
+gceSTATUS
gcoOS_DisplayBufferRegions(
IN HALNativeDisplayType Display,
IN HALNativeWindowType Window,
@@ -779,7 +552,48 @@ gcoOS_DestroyClientBuffer(
IN gctPOINTER ClientBuffer
);
+gceSTATUS
+gcoOS_DestroyContext(
+ IN gctPOINTER Display,
+ IN gctPOINTER Context
+ );
+gceSTATUS
+gcoOS_CreateContext(
+ IN gctPOINTER LocalDisplay,
+ IN gctPOINTER Context
+ );
+
+gceSTATUS
+gcoOS_MakeCurrent(
+ IN gctPOINTER LocalDisplay,
+ IN HALNativeWindowType DrawDrawable,
+ IN HALNativeWindowType ReadDrawable,
+ IN gctPOINTER Context,
+ IN gcoSURF ResolveTarget
+ );
+
+gceSTATUS
+gcoOS_CreateDrawable(
+ IN gctPOINTER LocalDisplay,
+ IN HALNativeWindowType Drawable
+ );
+
+gceSTATUS
+gcoOS_DestroyDrawable(
+ IN gctPOINTER LocalDisplay,
+ IN HALNativeWindowType Drawable
+ );
+gceSTATUS
+gcoOS_SwapBuffers(
+ IN gctPOINTER LocalDisplay,
+ IN HALNativeWindowType Drawable,
+ IN gcoSURF RenderTarget,
+ IN gcoSURF ResolveTarget,
+ IN gctPOINTER ResolveBits,
+ OUT gctUINT *Width,
+ OUT gctUINT *Height
+ );
#ifdef __cplusplus
}
#endif
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h
new file mode 100644
index 000000000000..727758f4d39f
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h
@@ -0,0 +1,287 @@
+/****************************************************************************
+*
+* Copyright (C) 2005 - 2012 by Vivante Corp.
+*
+* 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
+* the Free Software Foundation; either version 2 of the license, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not write to the Free Software
+* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*
+*****************************************************************************/
+
+
+
+#ifndef __gc_hal_eglplatform_type_h_
+#define __gc_hal_eglplatform_type_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+** Events. *********************************************************************
+*/
+
+typedef enum _halEventType
+{
+ /* Keyboard event. */
+ HAL_KEYBOARD,
+
+ /* Mouse move event. */
+ HAL_POINTER,
+
+ /* Mouse button event. */
+ HAL_BUTTON,
+
+ /* Application close event. */
+ HAL_CLOSE,
+
+ /* Application window has been updated. */
+ HAL_WINDOW_UPDATE
+}
+halEventType;
+
+/* Scancodes for keyboard. */
+typedef enum _halKeys
+{
+ HAL_UNKNOWN = -1,
+
+ HAL_BACKSPACE = 0x08,
+ HAL_TAB,
+ HAL_ENTER = 0x0D,
+ HAL_ESCAPE = 0x1B,
+
+ HAL_SPACE = 0x20,
+ HAL_SINGLEQUOTE = 0x27,
+ HAL_PAD_ASTERISK = 0x2A,
+ HAL_COMMA = 0x2C,
+ HAL_HYPHEN,
+ HAL_PERIOD,
+ HAL_SLASH,
+ HAL_0,
+ HAL_1,
+ HAL_2,
+ HAL_3,
+ HAL_4,
+ HAL_5,
+ HAL_6,
+ HAL_7,
+ HAL_8,
+ HAL_9,
+ HAL_SEMICOLON = 0x3B,
+ HAL_EQUAL = 0x3D,
+ HAL_A = 0x41,
+ HAL_B,
+ HAL_C,
+ HAL_D,
+ HAL_E,
+ HAL_F,
+ HAL_G,
+ HAL_H,
+ HAL_I,
+ HAL_J,
+ HAL_K,
+ HAL_L,
+ HAL_M,
+ HAL_N,
+ HAL_O,
+ HAL_P,
+ HAL_Q,
+ HAL_R,
+ HAL_S,
+ HAL_T,
+ HAL_U,
+ HAL_V,
+ HAL_W,
+ HAL_X,
+ HAL_Y,
+ HAL_Z,
+ HAL_LBRACKET,
+ HAL_BACKSLASH,
+ HAL_RBRACKET,
+ HAL_BACKQUOTE = 0x60,
+
+ HAL_F1 = 0x80,
+ HAL_F2,
+ HAL_F3,
+ HAL_F4,
+ HAL_F5,
+ HAL_F6,
+ HAL_F7,
+ HAL_F8,
+ HAL_F9,
+ HAL_F10,
+ HAL_F11,
+ HAL_F12,
+
+ HAL_LCTRL,
+ HAL_RCTRL,
+ HAL_LSHIFT,
+ HAL_RSHIFT,
+ HAL_LALT,
+ HAL_RALT,
+ HAL_CAPSLOCK,
+ HAL_NUMLOCK,
+ HAL_SCROLLLOCK,
+ HAL_PAD_0,
+ HAL_PAD_1,
+ HAL_PAD_2,
+ HAL_PAD_3,
+ HAL_PAD_4,
+ HAL_PAD_5,
+ HAL_PAD_6,
+ HAL_PAD_7,
+ HAL_PAD_8,
+ HAL_PAD_9,
+ HAL_PAD_HYPHEN,
+ HAL_PAD_PLUS,
+ HAL_PAD_SLASH,
+ HAL_PAD_PERIOD,
+ HAL_PAD_ENTER,
+ HAL_SYSRQ,
+ HAL_PRNTSCRN,
+ HAL_BREAK,
+ HAL_UP,
+ HAL_LEFT,
+ HAL_RIGHT,
+ HAL_DOWN,
+ HAL_HOME,
+ HAL_END,
+ HAL_PGUP,
+ HAL_PGDN,
+ HAL_INSERT,
+ HAL_DELETE,
+ HAL_LWINDOW,
+ HAL_RWINDOW,
+ HAL_MENU,
+ HAL_POWER,
+ HAL_SLEEP,
+ HAL_WAKE
+}
+halKeys;
+
+/* Structure that defined keyboard mapping. */
+typedef struct _halKeyMap
+{
+ /* Normal key. */
+ halKeys normal;
+
+ /* Extended key. */
+ halKeys extended;
+}
+halKeyMap;
+
+/* Event structure. */
+typedef struct _halEvent
+{
+ /* Event type. */
+ halEventType type;
+
+ /* Event data union. */
+ union _halEventData
+ {
+ /* Event data for keyboard. */
+ struct _halKeyboard
+ {
+ /* Scancode. */
+ halKeys scancode;
+
+ /* ASCII characte of the key pressed. */
+ char key;
+
+ /* Flag whether the key was pressed (1) or released (0). */
+ char pressed;
+ }
+ keyboard;
+
+ /* Event data for pointer. */
+ struct _halPointer
+ {
+ /* Current pointer coordinate. */
+ int x;
+ int y;
+ }
+ pointer;
+
+ /* Event data for mouse buttons. */
+ struct _halButton
+ {
+ /* Left button state. */
+ int left;
+
+ /* Middle button state. */
+ int middle;
+
+ /* Right button state. */
+ int right;
+
+ /* Current pointer coordinate. */
+ int x;
+ int y;
+ }
+ button;
+ }
+ data;
+}
+halEvent;
+
+/* VFK_DISPLAY_INFO structure defining information returned by
+ vdkGetDisplayInfoEx. */
+typedef struct _halDISPLAY_INFO
+{
+ /* The size of the display in pixels. */
+ int width;
+ int height;
+
+ /* The stride of the dispay. -1 is returned if the stride is not known
+ ** for the specified display.*/
+ int stride;
+
+ /* The color depth of the display in bits per pixel. */
+ int bitsPerPixel;
+
+ /* The logical pointer to the display memory buffer. NULL is returned
+ ** if the pointer is not known for the specified display. */
+ void * logical;
+
+ /* The physical address of the display memory buffer. ~0 is returned
+ ** if the address is not known for the specified display. */
+ unsigned long physical;
+
+ int wrapFB; /* true if compositor, false otherwise. */
+
+#ifndef __QNXNTO__
+ /* 355_FB_MULTI_BUFFER */
+ int multiBuffer;
+ int backBufferY;
+#endif
+
+ /* The color info of the display. */
+ unsigned int alphaLength;
+ unsigned int alphaOffset;
+ unsigned int redLength;
+ unsigned int redOffset;
+ unsigned int greenLength;
+ unsigned int greenOffset;
+ unsigned int blueLength;
+ unsigned int blueOffset;
+
+ /* Display flip support. */
+ int flip;
+}
+halDISPLAY_INFO;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_eglplatform_type_h_ */
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
index c7543072f349..7400b3201b91 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
@@ -871,6 +871,19 @@ gco3D_SetAllEarlyDepthModes(
IN gctBOOL Disable
);
+/* Switch dynamic early mode */
+gceSTATUS
+gco3D_SwitchDynamicEarlyDepthMode(
+ IN gco3D Engine
+ );
+
+/* Set dynamic early mode */
+gceSTATUS
+gco3D_DisableDynamicEarlyDepthMode(
+ IN gco3D Engine,
+ IN gctBOOL Disable
+ );
+
/* Enable or disable depth-only mode. */
gceSTATUS
gco3D_SetDepthOnly(
@@ -1450,6 +1463,21 @@ gcoTEXTURE_UploadCompressed(
IN gctSIZE_T Bytes
);
+/* Upload compressed sub data to an gcoTEXTURE object. */
+gceSTATUS
+gcoTEXTURE_UploadCompressedSub(
+ IN gcoTEXTURE Texture,
+ IN gctUINT MipMap,
+ IN gceTEXTURE_FACE Face,
+ IN gctUINT XOffset,
+ IN gctUINT YOffset,
+ IN gctUINT Width,
+ IN gctUINT Height,
+ IN gctUINT Slice,
+ IN gctCONST_POINTER Memory,
+ IN gctSIZE_T Size
+ );
+
/* Get gcoSURF object for a mipmap level. */
gceSTATUS
gcoTEXTURE_GetMipMap(
@@ -1780,6 +1808,16 @@ gcoVERTEXARRAY_Bind(
IN OUT gctUINT * PrimitiveCount
);
+gctUINT
+gcoVERTEXARRAY_GetMaxStream(
+ IN gcoVERTEXARRAY Vertex
+);
+
+gceSTATUS
+gcoVERTEXARRAY_SetMaxStream(
+ IN gcoVERTEXARRAY Vertex,
+ gctUINT maxStreams
+);
/*******************************************************************************
***** Composition *************************************************************/
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h
index b2e36a258da8..d951c3a965d9 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h
@@ -209,10 +209,14 @@ typedef enum _gceSURF_TYPE
#if gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST
gcvSURF_FLIP = 0x800, /* The Resolve Target the will been flip resolve from RT */
#endif
+ gcvSURF_TILE_STATUS_DIRTY = 0x1000, /* Init tile status to all dirty */
gcvSURF_RENDER_TARGET_NO_TILE_STATUS = gcvSURF_RENDER_TARGET
| gcvSURF_NO_TILE_STATUS,
+ gcvSURF_RENDER_TARGET_TS_DIRTY = gcvSURF_RENDER_TARGET
+ | gcvSURF_TILE_STATUS_DIRTY,
+
gcvSURF_DEPTH_NO_TILE_STATUS = gcvSURF_DEPTH
| gcvSURF_NO_TILE_STATUS,
@@ -646,6 +650,12 @@ typedef enum _gce2D_QUERY
}
gce2D_QUERY;
+typedef enum _gce2D_STATE
+{
+ gcv2D_STATE_SPECIAL_FILTER_MIRROR_MODE = 1,
+}
+gce2D_STATE;
+
#ifndef VIVANTE_NO_3D
/* Texture functions. */
typedef enum _gceTEXTURE_FUNCTION
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
index d1ddd004dc3c..33fddfbbfed2 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
@@ -161,6 +161,14 @@
#endif
/*
+ gcdENABLE_FSCALE_VAL_ADJUST
+ When non-zero, FSCALE_VAL when gcvPOWER_ON can be adjusted externally.
+ */
+#ifndef gcdENABLE_FSCALE_VAL_ADJUST
+# define gcdENABLE_FSCALE_VAL_ADJUST 1
+#endif
+
+/*
gcdDUMP_IN_KERNEL
When set to 1, all dumps will happen in the kernel. This is handy if
@@ -765,7 +773,7 @@
limited by gcdCONTIGUOUS_SIZE_LIMIT.
*/
#ifndef gcdCONTIGUOUS_SIZE_LIMIT
-# define gcdCONTIGUOUS_SIZE_LIMIT 0
+# define gcdCONTIGUOUS_SIZE_LIMIT 4096
#endif
/* gcdALPHA_KILL_IN_SHADER
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h
index 53e9cc6e760b..e3ceadfce7ee 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h
@@ -950,6 +950,13 @@ gco2D_QueryU32(
OUT gctUINT32_PTR Value
);
+gceSTATUS
+gco2D_SetStateU32(
+ IN gco2D Engine,
+ IN gce2D_STATE State,
+ IN OUT gctUINT32_PTR Value
+ );
+
#ifdef __cplusplus
}
#endif
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h
new file mode 100644
index 000000000000..1e85458625e7
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+*
+* Copyright (C) 2005 - 2012 by Vivante Corp.
+*
+* 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
+* the Free Software Foundation; either version 2 of the license, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not write to the Free Software
+* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*
+*****************************************************************************/
+
+
+
+#ifndef __gc_hal_statistics_h_
+#define __gc_hal_statistics_h_
+
+
+#define VIV_STAT_ENABLE_STATISTICS 0
+
+/* Toal number of frames for which the frame time is accounted. We have storage
+ to keep frame times for last this many frames.
+*/
+#define VIV_STAT_FRAME_BUFFER_SIZE 30
+
+/*
+ Total number of frames sampled for a mode. This means
+
+ # of frames for HZ Current : VIV_STAT_EARLY_Z_SAMPLE_FRAMES
+ # of frames for HZ Switched : VIV_STAT_EARLY_Z_SAMPLE_FRAMES
+ +
+ --------------------------------------------------------
+ : (2 * VIV_STAT_EARLY_Z_SAMPLE_FRAMES) frames needed
+
+ IMPORTANT: This total must be smaller than VIV_STAT_FRAME_BUFFER_SIZE
+*/
+#define VIV_STAT_EARLY_Z_SAMPLE_FRAMES 7
+#define VIV_STAT_EARLY_Z_LATENCY_FRAMES 2
+
+/* Multiplication factor for previous Hz off mode. Make it more than 1.0 to advertise HZ on.*/
+#define VIV_STAT_EARLY_Z_FACTOR (1.05f)
+
+/* Defines the statistical data keys monitored by the statistics module */
+typedef enum _gceSTATISTICS
+{
+ gcvFRAME_FPS = 1,
+}
+gceSTATISTICS;
+
+/* HAL statistics information. */
+typedef struct _gcsSTATISTICS_EARLYZ
+{
+ gctUINT switchBackCount;
+ gctUINT nextCheckPoint;
+ gctBOOL disabled;
+}
+gcsSTATISTICS_EARLYZ;
+
+
+/* Defines the statistical data keys monitored by the statistics module */
+typedef enum _gceSTATISTICS_Call
+{
+ gcvSTAT_ES11_GLDRAWELEMENTS = 1,
+}
+gceSTATISTICS_Call;
+
+
+/* HAL statistics information. */
+typedef struct _gcsSTATISTICS
+{
+ gctUINT64 frameTime[VIV_STAT_FRAME_BUFFER_SIZE];
+ gctUINT64 previousFrameTime;
+ gctUINT frame;
+ gcsSTATISTICS_EARLYZ earlyZ;
+ gctUINT ES11_drawElementsCount;
+ gctBOOL applyRTestVAFix;
+}
+gcsSTATISTICS;
+
+
+/* Add a frame based data into current statistics. */
+void
+gcfSTATISTICS_AddData(
+ IN gceSTATISTICS Key,
+ IN gctUINT Value
+ );
+
+/* Marks the frame end and triggers statistical calculations and decisions.*/
+void
+gcfSTATISTICS_MarkFrameEnd (
+ void
+ );
+
+/* Sets whether the dynmaic HZ is disabled or not .*/
+void
+gcfSTATISTICS_DisableDynamicEarlyZ (
+ IN gctBOOL Disabled
+ );
+
+/* Checks whether or not glDrawArray function call will be discarded */
+gctBOOL
+gcfSTATISTICS_DiscardCall(
+ gceSTATISTICS_Call Function
+ );
+
+
+#endif /*__gc_hal_statistics_h_ */
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h
index e9ad6f611820..4e063776cd44 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h
@@ -285,6 +285,8 @@ typedef enum _gceSTATUS
gcvSTATUS_EXECUTED = 18,
gcvSTATUS_TERMINATE = 19,
+ gcvSTATUS_CONVERT_TO_SINGLE_STREAM = 20,
+
gcvSTATUS_INVALID_ARGUMENT = -1,
gcvSTATUS_INVALID_OBJECT = -2,
gcvSTATUS_OUT_OF_MEMORY = -3,
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h
index 372c8ac7817f..87311376e640 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h
@@ -895,6 +895,12 @@ gckVGMMU_SetPage(
IN gctUINT32 *PageEntry
);
+/* Flush MMU */
+gceSTATUS
+gckVGMMU_Flush(
+ IN gckVGMMU Mmu
+ );
+
#endif /* gcdENABLE_VG */
#ifdef __cplusplus
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c
index cff2448d7f92..5a21a94ed7fd 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c
@@ -43,21 +43,21 @@
#include <linux/completion.h>
#include "gc_hal_kernel_linux.h"
-/*
+/*
Prequsite:
1) Debugfs feature must be enabled in the kernel.
1.a) You can enable this, in the compilation of the uImage, all you have to do is, In the "make menuconfig" part,
you have to enable the debugfs in the kernel hacking part of the menu.
-
+
HOW TO USE:
- 1) insert the driver with the following option logFileSize, Ex: insmod galcore.ko ...... logFileSize=10240
+ 1) insert the driver with the following option logFileSize, Ex: insmod galcore.ko ...... logFileSize=10240
This gives a circular buffer of 10 MB
-
+
2)Usually after inserting the driver, the debug file system is mounted under /sys/kernel/debug/
2.a)If the debugfs is not mounted, you must do "mount -t debugfs none /sys/kernel/debug"
-
+
3) To read what is being printed in the debugfs file system:
Ex : cat /sys/kernel/debug/gpu/galcore_trace
@@ -81,7 +81,7 @@
4) insmod it with the logFileSize option
5) Run an application
6) You can get the dump by cat /sys/kernel/debug/gpu/galcore_trace
-
+
*/
/**/
@@ -151,7 +151,7 @@ static gcsDebugFileSystem gc_dbgfs ;
/*******************************************************************************
**
** READ & WRITE FUNCTIONS (START)
- **
+ **
*******************************************************************************/
/*******************************************************************************
@@ -159,9 +159,9 @@ static gcsDebugFileSystem gc_dbgfs ;
** _ReadFromNode
**
** 1) reading bytes out of a circular buffer with wraparound.
- ** 2)returns caddr_t, pointer to data read, which the caller must free.
+ ** 2)returns caddr_t, pointer to data read, which the caller must free.
** 3) length is (a pointer to) the number of bytes to be read, which will be set by this function to
- ** be the number of bytes actually returned
+ ** be the number of bytes actually returned
**
*******************************************************************************/
static caddr_t
@@ -222,7 +222,7 @@ _ReadFromNode (
**
** _WriteToNode
**
- ** 1) writes to a circular buffer with wraparound.
+ ** 1) writes to a circular buffer with wraparound.
** 2)in case of an overflow, it overwrites the oldest unread data.
**
*********************************************************************************/
@@ -275,7 +275,7 @@ _WriteToNode (
/*******************************************************************************
**
** PRINTING UTILITY (START)
- **
+ **
*******************************************************************************/
/*******************************************************************************
@@ -369,7 +369,7 @@ _DebugFSPrint (
/*******************************************************************************
**
** LINUX SYSTEM FUNCTIONS (START)
- **
+ **
*******************************************************************************/
/*******************************************************************************
@@ -538,7 +538,7 @@ static const struct file_operations debugfs_operations = {
/*******************************************************************************
**
** INTERFACE FUNCTIONS (START)
- **
+ **
*******************************************************************************/
/*******************************************************************************
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h
index b0031a83ef41..e0b61424482f 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h
@@ -35,7 +35,7 @@
/*******************************************************************************
**
** System Related
- **
+ **
*******************************************************************************/
gctINT gckDebugFileSystemIsEnabled(void);
@@ -48,7 +48,7 @@ gctINT gckDebugFileSystemTerminate(void);
/*******************************************************************************
**
** Node Related
- **
+ **
*******************************************************************************/
gctINT gckDebugFileSystemCreateNode(
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
index 890d13e17c50..eba81b64be92 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
@@ -358,6 +358,15 @@ gckGALDEVICE_Construct(
gckDebugFileSystemSetCurrentNode(device->dbgnode);
}
}
+ /*get gpu regulator*/
+ device->gpu_regulator = regulator_get(NULL, "cpu_vddgpu");
+ if (IS_ERR(device->gpu_regulator)) {
+ gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DRIVER,
+ "%s(%d): Failed to get gpu regulator %s/%s \n",
+ __FUNCTION__, __LINE__,
+ PARENT_FILE, DEBUG_FILE);
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
/*Initialize the clock structure*/
if (IrqLine != -1) {
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
index 03f7f9b2201e..c15989894600 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
@@ -89,6 +89,9 @@ typedef struct _gckGALDEVICE
struct clk *clk_2d_axi;
struct clk *clk_vg_axi;
+ /*Power management.*/
+ struct regulator *gpu_regulator;
+
}
* gckGALDEVICE;
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
index 3f873f09d1a0..b326463b8133 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
@@ -495,8 +495,7 @@ long drv_ioctl(
}
iface.u.ChipInfo.count = count;
- status = gcvSTATUS_OK;
- iface.status = status;
+ iface.status = status = gcvSTATUS_OK;
}
else
{
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
index 30fb13596dda..a6ed03ffc0f9 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
@@ -47,6 +47,7 @@
#if ENABLE_GPU_CLOCK_BY_DRIVER && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
#endif
#define NTSTRSAFE_NO_CCH_FUNCTIONS
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
index 21e6a22317e5..a44180bfc71a 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
@@ -38,6 +38,7 @@
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
#include <linux/math64.h>
#endif
+#include <linux/delay.h>
#define _GC_OBJ_ZONE gcvZONE_OS
@@ -197,6 +198,8 @@ typedef struct _gcsSIGNAL
/* The owner of the signal. */
gctHANDLE process;
+ gckHARDWARE hardware;
+
/* ID. */
gctUINT32 id;
}
@@ -1158,32 +1161,24 @@ _UnmapUserLogical(
IN gctUINT32 Size
)
{
- struct task_struct *task;
- struct mm_struct *mm;
-
- /* Get the task_struct of the task with stored pid. */
- rcu_read_lock();
-
- task = FIND_TASK_BY_PID(Pid);
-
- if (task == gcvNULL)
+ if (unlikely(current->mm == gcvNULL))
{
- rcu_read_unlock();
+ /* Do nothing if process is exiting. */
return;
}
- /* Get the mm_struct. */
- mm = get_task_mm(task);
-
- rcu_read_unlock();
-
- if (mm == gcvNULL)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+ if (vm_munmap((unsigned long)Logical, Size) < 0)
{
- return;
+ gcmkTRACE_ZONE(
+ gcvLEVEL_WARNING, gcvZONE_OS,
+ "%s(%d): vm_munmap failed",
+ __FUNCTION__, __LINE__
+ );
}
-
- down_write(&mm->mmap_sem);
- if (do_munmap(mm, (unsigned long)Logical, Size) < 0)
+#else
+ down_write(&current->mm->mmap_sem);
+ if (do_munmap(current->mm, (unsigned long)Logical, Size) < 0)
{
gcmkTRACE_ZONE(
gcvLEVEL_WARNING, gcvZONE_OS,
@@ -1191,10 +1186,8 @@ _UnmapUserLogical(
__FUNCTION__, __LINE__
);
}
- up_write(&mm->mmap_sem);
-
- /* Dereference. */
- mmput(mm);
+ up_write(&current->mm->mmap_sem);
+#endif
}
/*******************************************************************************
@@ -1983,6 +1976,55 @@ gckOS_UnmapMemoryEx(
/*******************************************************************************
**
+** gckOS_UnmapUserLogical
+**
+** Unmap user logical memory out of physical memory.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an gckOS object.
+**
+** gctPHYS_ADDR Physical
+** Start of physical address memory.
+**
+** gctSIZE_T Bytes
+** Number of bytes to unmap.
+**
+** gctPOINTER Memory
+** Pointer to a previously mapped memory region.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckOS_UnmapUserLogical(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Bytes,
+ IN gctPOINTER Logical
+ )
+{
+ gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu Logical=0x%X",
+ Os, Physical, Bytes, Logical);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Physical != 0);
+ gcmkVERIFY_ARGUMENT(Bytes > 0);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+
+ gckOS_UnmapMemory(Os, Physical, Bytes, Logical);
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+}
+
+/*******************************************************************************
+**
** gckOS_AllocateNonPagedMemory
**
** Allocate a number of pages from non-paged memory.
@@ -2377,8 +2419,8 @@ gceSTATUS gckOS_FreeNonPagedMemory(
{
if (mdlMap->vmaAddr != gcvNULL)
{
- _UnmapUserLogical(mdlMap->pid, mdlMap->vmaAddr, mdl->numPages * PAGE_SIZE);
- mdlMap->vmaAddr = gcvNULL;
+ /* No mapped memory exists when free nonpaged memory */
+ gcmkASSERT(0);
}
mdlMap = mdlMap->next;
@@ -3762,24 +3804,14 @@ gckOS_Delay(
if (Delay > 0)
{
-#if gcdHIGH_PRECISION_DELAY_ENABLE
- ktime_t wait = ns_to_ktime(Delay * 1000 * 1000);
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_hrtimeout(&wait, HRTIMER_MODE_REL);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
+ ktime_t delay = ktime_set(0, Delay * NSEC_PER_MSEC);
+ __set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_hrtimeout(&delay, HRTIMER_MODE_REL);
#else
- struct timeval now;
- unsigned long jiffies;
-
- /* Convert milliseconds into seconds and microseconds. */
- now.tv_sec = Delay / 1000;
- now.tv_usec = (Delay % 1000) * 1000;
-
- /* Convert timeval to jiffies. */
- jiffies = timeval_to_jiffies(&now);
-
- /* Schedule timeout. */
- schedule_timeout_interruptible(jiffies);
+ msleep(Delay);
#endif
+
}
/* Success. */
@@ -5642,7 +5674,11 @@ OnError:
}
#if gcdENABLE_VG
- if (Core != gcvCORE_VG)
+ if (Core == gcvCORE_VG)
+ {
+ gcmkONERROR(gckVGMMU_Flush(Os->device->kernels[Core]->vg->mmu));
+ }
+ else
#endif
{
gcmkONERROR(gckMMU_Flush(Os->device->kernels[Core]->mmu));
@@ -6517,7 +6553,9 @@ gckOS_Broadcast(
case gcvBROADCAST_GPU_STUCK:
gcmkTRACE_N(gcvLEVEL_ERROR, 0, "gcvBROADCAST_GPU_STUCK\n");
+#if !gcdENABLE_RECOVERY
gcmkONERROR(_DumpGPUState(Os, Hardware->core));
+#endif
gcmkONERROR(gckKERNEL_Recovery(Hardware->kernel));
break;
@@ -6943,6 +6981,7 @@ gckOS_SetGPUPower(
struct clk *clk_vg_axi = Os->device->clk_vg_axi;
gctBOOL oldClockState = gcvFALSE;
+ gctBOOL oldPowerState = gcvFALSE;
gcmkHEADER_ARG("Os=0x%X Core=%d Clock=%d Power=%d", Os, Core, Clock, Power);
@@ -6952,15 +6991,20 @@ gckOS_SetGPUPower(
if (Core == gcvCORE_VG)
{
oldClockState = Os->device->kernels[Core]->vg->hardware->clockState;
+ oldPowerState = Os->device->kernels[Core]->vg->hardware->powerState;
}
else
{
#endif
oldClockState = Os->device->kernels[Core]->hardware->clockState;
+ oldPowerState = Os->device->kernels[Core]->hardware->powerState;
#if gcdENABLE_VG
}
#endif
}
+ if((Power == gcvTRUE) && (oldPowerState == gcvFALSE) &&
+ !IS_ERR(Os->device->gpu_regulator))
+ regulator_enable(Os->device->gpu_regulator);
if (Clock == gcvTRUE) {
if (oldClockState == gcvFALSE) {
@@ -7003,8 +7047,10 @@ gckOS_SetGPUPower(
}
}
}
-
-
+ if((Power == gcvFALSE) && (oldPowerState == gcvTRUE) &&
+ !IS_ERR(Os->device->gpu_regulator))
+ regulator_disable(Os->device->gpu_regulator);
+ /* TODO: Put your code here. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
}
@@ -7195,6 +7241,7 @@ gckOS_CreateSignal(
/* Save the process ID. */
signal->process = (gctHANDLE) _GetProcessID();
signal->manualReset = ManualReset;
+ signal->hardware = gcvNULL;
init_completion(&signal->obj);
atomic_set(&signal->ref, 1);
@@ -7215,6 +7262,61 @@ OnError:
return status;
}
+gceSTATUS
+gckOS_SignalQueryHardware(
+ IN gckOS Os,
+ IN gctSIGNAL Signal,
+ OUT gckHARDWARE * Hardware
+ )
+{
+ gceSTATUS status;
+ gcsSIGNAL_PTR signal;
+
+ gcmkHEADER_ARG("Os=0x%X Signal=0x%X Hardware=0x%X", Os, Signal, Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Hardware != gcvNULL);
+
+ gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)Signal, (gctPOINTER)&signal));
+
+ *Hardware = signal->hardware;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckOS_SignalSetHardware(
+ IN gckOS Os,
+ IN gctSIGNAL Signal,
+ IN gckHARDWARE Hardware
+ )
+{
+ gceSTATUS status;
+ gcsSIGNAL_PTR signal;
+
+ gcmkHEADER_ARG("Os=0x%X Signal=0x%X Hardware=0x%X", Os, Signal, Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
+
+ gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)Signal, (gctPOINTER)&signal));
+
+ signal->hardware = Hardware;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
/*******************************************************************************
**
** gckOS_DestroySignal
@@ -7330,6 +7432,9 @@ gckOS_Signal(
if (State)
{
+ /* unbind the signal from hardware. */
+ signal->hardware = gcvNULL;
+
/* Set the event to a signaled state. */
complete(&signal->obj);
}
diff --git a/drivers/mxc/ipu3/ipu_device.c b/drivers/mxc/ipu3/ipu_device.c
index d12ffdfc7847..be1725129ce2 100644
--- a/drivers/mxc/ipu3/ipu_device.c
+++ b/drivers/mxc/ipu3/ipu_device.c
@@ -340,6 +340,7 @@ struct ipu_alloc_list {
dma_addr_t phy_addr;
void *cpu_addr;
u32 size;
+ void *file_index;
};
static LIST_HEAD(ipu_alloc_list);
@@ -350,6 +351,7 @@ static DEFINE_SPINLOCK(ipu_task_list_lock);
static DECLARE_WAIT_QUEUE_HEAD(thread_waitq);
static DECLARE_WAIT_QUEUE_HEAD(res_waitq);
static atomic_t req_cnt;
+static atomic_t file_index = ATOMIC_INIT(1);
static int major;
static int max_ipu_no;
static int thread_id;
@@ -3274,6 +3276,7 @@ EXPORT_SYMBOL_GPL(ipu_queue_task);
static int mxc_ipu_open(struct inode *inode, struct file *file)
{
+ file->private_data = (void *)atomic_inc_return(&file_index);
return 0;
}
@@ -3330,6 +3333,7 @@ static long mxc_ipu_ioctl(struct file *file,
kfree(mem);
return -ENOMEM;
}
+ mem->file_index = file->private_data;
mutex_lock(&ipu_alloc_lock);
list_add(&mem->list, &ipu_alloc_list);
mutex_unlock(&ipu_alloc_lock);
@@ -3413,6 +3417,26 @@ static int mxc_ipu_mmap(struct file *file, struct vm_area_struct *vma)
static int mxc_ipu_release(struct inode *inode, struct file *file)
{
+ struct ipu_alloc_list *mem;
+ struct ipu_alloc_list *n;
+
+ mutex_lock(&ipu_alloc_lock);
+ list_for_each_entry_safe(mem, n, &ipu_alloc_list, list) {
+ if ((mem->cpu_addr != 0) &&
+ (file->private_data == mem->file_index)) {
+ list_del(&mem->list);
+ dma_free_coherent(ipu_dev,
+ mem->size,
+ mem->cpu_addr,
+ mem->phy_addr);
+ dev_dbg(ipu_dev, "rel-free %d bytes @ 0x%08X\n",
+ mem->size, mem->phy_addr);
+ kfree(mem);
+ }
+ }
+ mutex_unlock(&ipu_alloc_lock);
+ atomic_dec(&file_index);
+
return 0;
}
diff --git a/drivers/mxc/thermal/cooling.c b/drivers/mxc/thermal/cooling.c
index 0feefeaa6008..7019d9949c8a 100644
--- a/drivers/mxc/thermal/cooling.c
+++ b/drivers/mxc/thermal/cooling.c
@@ -57,6 +57,7 @@ cpufreq, it minor 1, and when we promote cpufreq, it add 1, so
if it is 0, mean we didn't change the cpufreq */
static int cpufreq_change_count;
+extern int thermal_hot;
int anatop_thermal_get_cpufreq_cur(void)
{
int ret = -EINVAL;
@@ -237,6 +238,7 @@ imx_processor_set_cur_state(struct thermal_cooling_device *cdev,
secondary CPUs that detached by thermal driver */
if (cooling_cpuhotplug) {
if (!state) {
+ thermal_hot = 0;
for (i = 1; i < 4; i++) {
if (cpu_mask && (0x1 << i)) {
anatop_thermal_cpu_hotplug(true);
@@ -247,6 +249,7 @@ imx_processor_set_cur_state(struct thermal_cooling_device *cdev,
}
} else {
if (!state) {
+ thermal_hot = 0;
if (cpufreq_change_count < 0)
anatop_thermal_cpufreq_up();
else if (cpufreq_change_count > 0)
diff --git a/drivers/mxc/vpu/mxc_vpu.c b/drivers/mxc/vpu/mxc_vpu.c
index 92a1d0dc98c7..6d77afb8a3d6 100644
--- a/drivers/mxc/vpu/mxc_vpu.c
+++ b/drivers/mxc/vpu/mxc_vpu.c
@@ -39,6 +39,7 @@
#include <linux/workqueue.h>
#include <linux/sched.h>
#include <linux/vmalloc.h>
+#include <linux/regulator/consumer.h>
#include <linux/page-flags.h>
#include <linux/mm_types.h>
#include <linux/types.h>
@@ -110,6 +111,7 @@ static int vpu_jpu_irq;
#endif
static unsigned int regBk[64];
+static struct regulator *vpu_regulator;
#define READ_REG(x) __raw_readl(vpu_base + x)
#define WRITE_REG(val, x) __raw_writel(val, vpu_base + x)
@@ -245,8 +247,12 @@ bool vpu_is_valid_phy_memory(u32 paddr)
*/
static int vpu_open(struct inode *inode, struct file *filp)
{
+
mutex_lock(&vpu_data.lock);
- open_count++;
+
+ if (open_count++ == 0 && !IS_ERR(vpu_regulator))
+ regulator_enable(vpu_regulator);
+
filp->private_data = (void *)(&vpu_data);
mutex_unlock(&vpu_data.lock);
return 0;
@@ -531,6 +537,9 @@ static int vpu_release(struct inode *inode, struct file *filp)
mutex_lock(&vpu_data.lock);
if (open_count > 0 && !(--open_count)) {
+ if (!IS_ERR(vpu_regulator))
+ regulator_disable(vpu_regulator);
+
vpu_free_buffers();
/* Free shared memory when vpu device is idle */
@@ -705,6 +714,12 @@ static int vpu_dev_probe(struct platform_device *pdev)
(void *)(&vpu_data));
if (err)
goto err_out_class;
+ vpu_regulator = regulator_get(NULL, "cpu_vddvpu");
+ if (IS_ERR(vpu_regulator)) {
+ printk(KERN_ERR
+ "%s: failed to get vpu regulator\n", __func__);
+ goto err_out_class;
+ }
#ifdef MXC_VPU_HAS_JPU
vpu_jpu_irq = platform_get_irq_byname(pdev, "vpu_jpu_irq");
@@ -752,7 +767,8 @@ static int vpu_dev_remove(struct platform_device *pdev)
iounmap(vpu_base);
if (vpu_plat && vpu_plat->iram_enable && vpu_plat->iram_size)
iram_free(iram.start, vpu_plat->iram_size);
-
+ if (!IS_ERR(vpu_regulator))
+ regulator_put(vpu_regulator);
return 0;
}
@@ -762,6 +778,8 @@ static int vpu_suspend(struct platform_device *pdev, pm_message_t state)
int i;
unsigned long timeout;
+ if (!IS_ERR(vpu_regulator))
+ regulator_enable(vpu_regulator);
/* Wait for vpu go to idle state, suspect vpu cannot be changed
to idle state after about 1 sec */
if (open_count > 0) {
@@ -794,10 +812,21 @@ static int vpu_suspend(struct platform_device *pdev, pm_message_t state)
if (vpu_plat->pg)
vpu_plat->pg(1);
+ /* If VPU is working before suspend, disable
+ * regulator to make usecount right. */
+ if (open_count > 0) {
+ if (!IS_ERR(vpu_regulator))
+ regulator_disable(vpu_regulator);
+ }
+
+ if (!IS_ERR(vpu_regulator))
+ regulator_disable(vpu_regulator);
return 0;
out:
clk_disable(vpu_clk);
+ if (!IS_ERR(vpu_regulator))
+ regulator_disable(vpu_regulator);
return -EAGAIN;
}
@@ -809,9 +838,18 @@ static int vpu_resume(struct platform_device *pdev)
if (cpu_is_mx53())
goto recover_clk;
+ if (!IS_ERR(vpu_regulator))
+ regulator_enable(vpu_regulator);
if (vpu_plat->pg)
vpu_plat->pg(0);
+ /* If VPU is working before suspend, enable
+ * regulator to make usecount right. */
+ if (open_count > 0) {
+ if (!IS_ERR(vpu_regulator))
+ regulator_enable(vpu_regulator);
+ }
+
if (bitwork_mem.cpu_addr != 0) {
u32 *p = (u32 *) bitwork_mem.cpu_addr;
u32 data, pc;
@@ -869,6 +907,8 @@ recover_clk:
/* Recover vpu clock */
for (i = 0; i < vpu_clk_usercount; i++)
clk_enable(vpu_clk);
+ if (!IS_ERR(vpu_regulator))
+ regulator_disable(vpu_regulator);
return 0;
}
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 5af378f391ee..86e4ea3404b3 100755
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -397,7 +397,12 @@ fec_timeout(struct net_device *ndev)
ndev->stats.tx_errors++;
+ netif_device_detach(ndev);
+ fec_stop(ndev);
+
fec_restart(ndev, fep->full_duplex);
+ netif_device_attach(ndev);
+ ndev->trans_start = jiffies; /* prevent tx timeout */
if (fep->link && !fep->tx_full)
netif_wake_queue(ndev);
}
@@ -1320,10 +1325,7 @@ fec_enet_close(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
- /* Don't know what to do yet. */
fep->opened = 0;
- netif_stop_queue(ndev);
- netif_carrier_off(ndev);
if (fep->use_napi)
napi_disable(&fep->napi);
@@ -1760,7 +1762,10 @@ fec_stop(struct net_device *dev)
if (fep->ptimer_present)
fec_ptp_stop(fep->ptp_priv);
writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
- netif_stop_queue(dev);
+
+ if (netif_running(dev))
+ netif_stop_queue(dev);
+ netif_carrier_off(dev); /* prevent tx timeout */
fep->link = 0;
}
@@ -1921,7 +1926,6 @@ fec_suspend(struct device *dev)
if (netif_running(ndev)) {
netif_device_detach(ndev);
fec_stop(ndev);
- netif_carrier_off(ndev);
clk_disable(fep->clk);
}
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 6e53cce3c7fd..a24653787d1d 100755
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -222,7 +222,6 @@ config CHARGER_MAX8903
config SABRESD_MAX8903
tristate "Sabresd Board Battery DC-DC Charger for USB and Adapter Power"
depends on GENERIC_HARDIRQS
- depends on TOUCHSCREEN_MAX11801
help
Say Y to enable support for the MAX8903 DC-DC charger and sysfs on
sabresd board.The driver supports controlling charger and battery
diff --git a/drivers/power/sabresd_battery.c b/drivers/power/sabresd_battery.c
index c7318a6eb02c..648922139790 100755
--- a/drivers/power/sabresd_battery.c
+++ b/drivers/power/sabresd_battery.c
@@ -65,13 +65,11 @@ typedef struct {
u32 voltage;
u32 percent;
} battery_capacity , *pbattery_capacity;
-
static int cpu_type_flag;
static int offset_discharger;
static int offset_charger;
static int offset_usb_charger;
-
static battery_capacity chargingTable[] = {
{4050, 99},
{4040, 98},
@@ -188,9 +186,9 @@ static enum power_supply_property max8903_battery_props[] = {
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_CAPACITY_LEVEL,
};
-
+#ifdef CONFIG_TOUCHSCREEN_MAX11801
extern u32 max11801_read_adc(void);
-
+#endif
static void max8903_charger_update_status(struct max8903_data *data)
{
if (data->usb_in || data->ta_in) {
@@ -205,26 +203,35 @@ static void max8903_charger_update_status(struct max8903_data *data)
}
if (data->charger_online == 0 && data->usb_charger_online == 0) {
data->battery_status = POWER_SUPPLY_STATUS_DISCHARGING;
- } else {
- if (gpio_get_value(data->pdata->chg) == 0) {
- data->battery_status = POWER_SUPPLY_STATUS_CHARGING;
- } else if (data->ta_in &&
- gpio_get_value(data->pdata->chg) == 1) {
- if (data->percent >= 99)
- data->battery_status = POWER_SUPPLY_STATUS_FULL;
- else
- data->battery_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
- }
- else if (data->usb_in &&
- gpio_get_value(data->pdata->chg) == 1) {
- if (data->percent >= 99)
- data->battery_status = POWER_SUPPLY_STATUS_FULL;
- else
- data->battery_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
- }
+ } else {
+ if (gpio_get_value(data->pdata->chg) == 0) {
+ data->battery_status = POWER_SUPPLY_STATUS_CHARGING;
+ } else if (data->ta_in && gpio_get_value(data->pdata->chg) == 1) {
+ if (!data->pdata->feature_flag) {
+ if (data->percent >= 99)
+ data->battery_status = POWER_SUPPLY_STATUS_FULL;
+ else
+ data->battery_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ } else {
+ data->battery_status = POWER_SUPPLY_STATUS_FULL;
+ }
+ } else if (data->usb_in && gpio_get_value(data->pdata->chg) == 1) {
+ if (!data->pdata->feature_flag) {
+ if (data->percent >= 99)
+ data->battery_status = POWER_SUPPLY_STATUS_FULL;
+ else
+ data->battery_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ } else {
+ data->battery_status = POWER_SUPPLY_STATUS_FULL;
+ }
}
- pr_debug("chg: %d \n", gpio_get_value(data->pdata->chg));
+ }
+ pr_debug("chg: %d\n", gpio_get_value(data->pdata->chg));
+ pr_debug("dc: %d\n", gpio_get_value(data->pdata->dok));
+ pr_debug("flt: %d\n", gpio_get_value(data->pdata->flt));
}
+
+#ifdef CONFIG_TOUCHSCREEN_MAX11801
static int cmp_func(const void *_a, const void *_b)
{
const int *a = _a, *b = _b;
@@ -235,6 +242,7 @@ static int cmp_func(const void *_a, const void *_b)
return -1;
return 0;
}
+
u32 calibration_voltage(struct max8903_data *data)
{
int volt[ADC_SAMPLE_COUNT];
@@ -275,51 +283,54 @@ u32 calibration_voltage(struct max8903_data *data)
voltage_data = (volt[2] + volt[ADC_SAMPLE_COUNT - 3]) / 2;
return voltage_data;
}
-
+#endif
static void max8903_battery_update_status(struct max8903_data *data)
{
- int temp;
+ int temp = 0;
static int temp_last;
bool changed_flag;
changed_flag = false;
mutex_lock(&data->work_lock);
- temp = calibration_voltage(data);
- if (temp_last == 0) {
- data->voltage_uV = temp;
- temp_last = temp;
- }
- if (data->charger_online == 0 && temp_last != 0) {
- if (temp < temp_last) {
- temp_last = temp;
- data->voltage_uV = temp;
- } else {
- data->voltage_uV = temp_last;
+ if (!data->pdata->feature_flag) {
+#ifdef CONFIG_TOUCHSCREEN_MAX11801
+ temp = calibration_voltage(data);
+#endif
+ if (temp_last == 0) {
+ data->voltage_uV = temp;
+ temp_last = temp;
+ }
+ if (data->charger_online == 0 && temp_last != 0) {
+ if (temp < temp_last) {
+ temp_last = temp;
+ data->voltage_uV = temp;
+ } else {
+ data->voltage_uV = temp_last;
+ }
+ }
+ if (data->charger_online == 1 || data->usb_charger_online == 1) {
+ data->voltage_uV = temp;
+ temp_last = temp;
+ }
+ data->percent = calibrate_battery_capability_percent(data);
+ if (data->percent != data->old_percent) {
+ data->old_percent = data->percent;
+ changed_flag = true;
+ }
+ if (changed_flag) {
+ changed_flag = false;
+ power_supply_changed(&data->bat);
+ }
+ /*
+ *because boot time gap between led framwork and charger
+ *framwork,when system boots with charger attatched,
+ *charger led framwork loses the first charger online event,
+ *add once extra power_supply_changed can fix this issure
+ */
+ if (data->first_delay_count < 200) {
+ data->first_delay_count = data->first_delay_count + 1 ;
+ power_supply_changed(&data->bat);
}
}
- if (data->charger_online == 1 || data->usb_charger_online == 1) {
- data->voltage_uV = temp;
- temp_last = temp;
- }
- data->percent = calibrate_battery_capability_percent(data);
- if (data->percent != data->old_percent) {
- data->old_percent = data->percent;
- changed_flag = true;
- }
- if (changed_flag) {
- changed_flag = false;
- power_supply_changed(&data->bat);
- }
- /*
- because boot time gap between led framwork and charger
- framwork,when system boots with charger attatched, charger
- led framwork loses the first charger online event,add once extra
- power_supply_changed can fix this issure
- */
- if (data->first_delay_count < 200) {
- data->first_delay_count = data->first_delay_count + 1 ;
- power_supply_changed(&data->bat);
- }
-
mutex_unlock(&data->work_lock);
}
@@ -332,22 +343,27 @@ static int max8903_battery_get_property(struct power_supply *bat,
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
- if (gpio_get_value(di->pdata->chg) == 0) {
- di->battery_status = POWER_SUPPLY_STATUS_CHARGING;
- } else if (di->ta_in &&
- gpio_get_value(di->pdata->chg) == 1) {
+ if (gpio_get_value(di->pdata->chg) == 0) {
+ di->battery_status = POWER_SUPPLY_STATUS_CHARGING;
+ } else if (di->ta_in && gpio_get_value(di->pdata->chg) == 1) {
+ if (!di->pdata->feature_flag) {
if (di->percent >= 99)
di->battery_status = POWER_SUPPLY_STATUS_FULL;
else
di->battery_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ } else {
+ di->battery_status = POWER_SUPPLY_STATUS_FULL;
}
- else if (di->usb_in &&
- gpio_get_value(di->pdata->chg) == 1) {
+ } else if (di->usb_in && gpio_get_value(di->pdata->chg) == 1) {
+ if (!di->pdata->feature_flag) {
if (di->percent >= 99)
di->battery_status = POWER_SUPPLY_STATUS_FULL;
else
- di->battery_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ di->battery_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ } else {
+ di->battery_status = POWER_SUPPLY_STATUS_FULL;
}
+ }
val->intval = di->battery_status;
return 0;
default:
@@ -795,14 +811,13 @@ static __devinit int max8903_probe(struct platform_device *pdev)
ret = request_threaded_irq(gpio_to_irq(pdata->chg),
NULL, max8903_chg,
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
- "MAX8903 Fault", data);
+ "MAX8903 Status", data);
if (ret) {
- dev_err(dev, "Cannot request irq %d for Fault (%d)\n",
+ dev_err(dev, "Cannot request irq %d for Status (%d)\n",
gpio_to_irq(pdata->flt), ret);
goto err_chg_irq;
}
}
-
ret = device_create_file(&pdev->dev, &max8903_discharger_dev_attr);
if (ret)
dev_err(&pdev->dev, "create device file failed!\n");
@@ -822,7 +837,6 @@ static __devinit int max8903_probe(struct platform_device *pdev)
offset_charger = 1485;
offset_usb_charger = 1285;
}
-
max8903_charger_update_status(data);
max8903_battery_update_status(data);
return 0;
@@ -888,10 +902,14 @@ static int max8903_suspend(struct platform_device *pdev,
if (data) {
struct max8903_pdata *pdata = data->pdata;
if (pdata) {
- irq = gpio_to_irq(pdata->dok);
- enable_irq_wake(irq);
- irq = gpio_to_irq(pdata->uok);
- enable_irq_wake(irq);
+ if (pdata->dc_valid) {
+ irq = gpio_to_irq(pdata->dok);
+ enable_irq_wake(irq);
+ }
+ if (pdata->usb_valid) {
+ irq = gpio_to_irq(pdata->uok);
+ enable_irq_wake(irq);
+ }
cancel_delayed_work(&data->work);
}
}
@@ -923,10 +941,14 @@ static int max8903_resume(struct platform_device *pdev)
max8903_charger_update_status(data);
power_supply_changed(&data->usb);
}
- irq = gpio_to_irq(pdata->dok);
- disable_irq_wake(irq);
- irq = gpio_to_irq(pdata->uok);
- disable_irq_wake(irq);
+ if (pdata->dc_valid) {
+ irq = gpio_to_irq(pdata->dok);
+ disable_irq_wake(irq);
+ }
+ if (pdata->usb_valid) {
+ irq = gpio_to_irq(pdata->uok);
+ disable_irq_wake(irq);
+ }
schedule_delayed_work(&data->work, BATTERY_UPDATE_INTERVAL);
}
}
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, &reg_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/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);
diff --git a/drivers/usb/gadget/arcotg_udc.c b/drivers/usb/gadget/arcotg_udc.c
index c3a48307c918..08118b3ba61e 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
@@ -3065,6 +3069,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 +3216,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:
@@ -3323,10 +3328,13 @@ static int udc_suspend(struct fsl_udc *udc)
* charge using usb
*/
if (pdata->pmflags == 0) {
- if (!udc_can_wakeup_system())
+ if (!udc_can_wakeup_system()) {
dr_wake_up_enable(udc, false);
- else
+ } else {
+ if (pdata->platform_phy_power_on)
+ pdata->platform_phy_power_on();
dr_wake_up_enable(udc, true);
+ }
}
/*
diff --git a/drivers/usb/host/ehci-arc.c b/drivers/usb/host/ehci-arc.c
index b872d94b3fc3..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);
@@ -678,6 +679,9 @@ static int ehci_fsl_drv_suspend(struct platform_device *pdev,
usb_host_set_wakeup(hcd->self.controller, false);
fsl_usb_clk_gate(hcd->self.controller->platform_data, false);
+ } else {
+ if (pdata->platform_phy_power_on)
+ pdata->platform_phy_power_on();
}
printk(KERN_DEBUG "host suspend ends\n");
diff --git a/drivers/video/mxc/Kconfig b/drivers/video/mxc/Kconfig
index f0afddc95bd3..8a4a0792724f 100644
--- a/drivers/video/mxc/Kconfig
+++ b/drivers/video/mxc/Kconfig
@@ -1,6 +1,6 @@
config FB_MXC
tristate "MXC Framebuffer support"
- depends on FB && (MXC_IPU || ARCH_MX21 || ARCH_MX27 || ARCH_MX25)
+ depends on FB && (MXC_IPU || ARCH_MX21 || ARCH_MX27 || ARCH_MX25 || ARCH_MX6)
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
@@ -60,6 +60,10 @@ config FB_MXC_SII902X
depends on FB_MXC_SYNC_PANEL && I2C
tristate "Si Image SII9022 DVI/HDMI Interface Chip"
+config FB_MXC_SII902X_ELCDIF
+ depends on FB_MXC_SYNC_PANEL && I2C
+ tristate "Si Image SII9022 DVI/HDMI Interface Chip for ELCDIF FB"
+
config FB_MXC_CH7026
depends on FB_MXC_SYNC_PANEL
tristate "Chrontel CH7026 VGA Interface Chip"
diff --git a/drivers/video/mxc/Makefile b/drivers/video/mxc/Makefile
index 21aef052ecd6..092d0aacba27 100644
--- a/drivers/video/mxc/Makefile
+++ b/drivers/video/mxc/Makefile
@@ -1,9 +1,10 @@
obj-$(CONFIG_FB_MXC_TVOUT_TVE) += tve.o
obj-$(CONFIG_FB_MXC_SII902X) += mxcfb_sii902x.o
+obj-$(CONFIG_FB_MXC_SII902X_ELCDIF) += mxcfb_sii902x_elcdif.o
obj-$(CONFIG_FB_MXC_LDB) += ldb.o
obj-$(CONFIG_FB_MXC_MIPI_DSI) += mipi_dsi.o
obj-$(CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL) += mxcfb_hx8369_wvga.o
-obj-$(CONFIG_FB_MXC_EDID) += mxc_edid.o mxc_dvi.o
+obj-$(CONFIG_FB_MXC_EDID) += mxc_edid.o
ifeq ($(CONFIG_ARCH_MX21)$(CONFIG_ARCH_MX27)$(CONFIG_ARCH_MX25),y)
obj-$(CONFIG_FB_MXC_TVOUT) += fs453.o
obj-$(CONFIG_FB_MXC_SYNC_PANEL) += mx2fb.o mxcfb_modedb.o
@@ -11,8 +12,10 @@ ifeq ($(CONFIG_ARCH_MX21)$(CONFIG_ARCH_MX27)$(CONFIG_ARCH_MX25),y)
else
ifeq ($(CONFIG_MXC_IPU_V1),y)
obj-$(CONFIG_FB_MXC_SYNC_PANEL) += mxcfb.o mxcfb_modedb.o
-else
+endif
+ifeq ($(CONFIG_MXC_IPU_V3),y)
obj-$(CONFIG_FB_MXC_SYNC_PANEL) += mxc_dispdrv.o mxc_lcdif.o mxc_ipuv3_fb.o
+ obj-$(CONFIG_FB_MXC_EDID) += mxc_dvi.o
endif
obj-$(CONFIG_FB_MXC_EPSON_PANEL) += mxcfb_epson.o
obj-$(CONFIG_FB_MXC_EPSON_QVGA_PANEL) += mxcfb_epson_qvga.o
diff --git a/drivers/video/mxc/mxc_elcdif_fb.c b/drivers/video/mxc/mxc_elcdif_fb.c
index 9c3b7b99a411..7eef316b1afe 100644
--- a/drivers/video/mxc/mxc_elcdif_fb.c
+++ b/drivers/video/mxc/mxc_elcdif_fb.c
@@ -72,6 +72,7 @@ struct mxc_elcdif_fb_data {
bool wait4vsync;
bool wait4framedone;
bool panning;
+ bool running;
struct completion vsync_complete;
struct completion frame_done_complete;
struct semaphore flip_sem;
@@ -86,6 +87,12 @@ struct elcdif_signal_cfg {
unsigned Vsync_pol:1; /* true = active high */
};
+struct mxcfb_mode {
+ int dev_mode;
+ int num_modes;
+ struct fb_videomode *mode;
+};
+
static int mxc_elcdif_fb_blank(int blank, struct fb_info *info);
static int mxc_elcdif_fb_map_video_memory(struct fb_info *info);
static int mxc_elcdif_fb_unmap_video_memory(struct fb_info *info);
@@ -97,6 +104,15 @@ static bool g_elcdif_axi_clk_enable;
static bool g_elcdif_pix_clk_enable;
static struct clk *g_elcdif_axi_clk;
static struct clk *g_elcdif_pix_clk;
+static struct mxcfb_mode mxc_disp_mode;
+
+static void dump_fb_videomode(struct fb_videomode *m)
+{
+ pr_debug("fb_videomode = %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
+ m->refresh, m->xres, m->yres, m->pixclock, m->left_margin,
+ m->right_margin, m->upper_margin, m->lower_margin,
+ m->hsync_len, m->vsync_len, m->sync, m->vmode, m->flag);
+}
static inline void setup_dotclk_panel(u32 pixel_clk,
u16 v_pulse_width,
@@ -113,16 +129,39 @@ static inline void setup_dotclk_panel(u32 pixel_clk,
int enable_present)
{
u32 val, rounded_pixel_clk;
+ u32 rounded_parent_clk;
+ struct clk *clk_parent;
if (!g_elcdif_axi_clk_enable) {
clk_enable(g_elcdif_axi_clk);
g_elcdif_axi_clk_enable = true;
}
+ /* Init clocking */
dev_dbg(g_elcdif_dev, "pixel clk = %d\n", pixel_clk);
- rounded_pixel_clk = clk_round_rate(g_elcdif_pix_clk, pixel_clk);
+
+ clk_parent = clk_get_parent(g_elcdif_pix_clk);
+ if (clk_parent == NULL)
+ dev_err(g_elcdif_dev, "%s Failed get clk parent\n", __func__);
+
+ rounded_pixel_clk = pixel_clk * 2;
+
+ rounded_parent_clk = clk_round_rate(clk_parent,
+ rounded_pixel_clk);
+
+ while (rounded_pixel_clk < rounded_parent_clk) {
+ /* the max divider from parent to di is 8 */
+ if (rounded_parent_clk / pixel_clk < 8)
+ rounded_pixel_clk += pixel_clk * 2;
+ }
+
+ clk_set_rate(clk_parent, rounded_pixel_clk);
+ rounded_pixel_clk =
+ clk_round_rate(g_elcdif_pix_clk, pixel_clk);
clk_set_rate(g_elcdif_pix_clk, rounded_pixel_clk);
+ msleep(5);
+
__raw_writel(BM_ELCDIF_CTRL_DATA_SHIFT_DIR,
elcdif_base + HW_ELCDIF_CTRL_CLR);
@@ -519,6 +558,35 @@ static inline void mxc_init_elcdif(void)
return;
}
+void mxcfb_elcdif_register_mode(const struct fb_videomode *modedb,
+ int num_modes, int dev_mode)
+{
+ struct fb_videomode *mode;
+
+ mode = kzalloc(num_modes * sizeof(struct fb_videomode), GFP_KERNEL);
+
+ if (!mode) {
+ dev_err(g_elcdif_dev, "%s Failed to allocate mode data\n", __func__);
+ return;
+ }
+
+ if (mxc_disp_mode.num_modes)
+ memcpy(mode, mxc_disp_mode.mode,
+ mxc_disp_mode.num_modes * sizeof(struct fb_videomode));
+ if (modedb)
+ memcpy(mode + mxc_disp_mode.num_modes, modedb,
+ num_modes * sizeof(struct fb_videomode));
+
+ if (mxc_disp_mode.num_modes)
+ kfree(mxc_disp_mode.mode);
+
+ mxc_disp_mode.mode = mode;
+ mxc_disp_mode.num_modes += num_modes;
+ mxc_disp_mode.dev_mode = dev_mode;
+
+ return;
+}
+
int mxc_elcdif_frame_addr_setup(dma_addr_t phys)
{
int ret = 0;
@@ -548,7 +616,7 @@ static inline void mxc_elcdif_dma_release(void)
return;
}
-static inline void mxc_elcdif_run(void)
+static inline void mxc_elcdif_run(struct mxc_elcdif_fb_data *data)
{
if (!g_elcdif_axi_clk_enable) {
clk_enable(g_elcdif_axi_clk);
@@ -559,6 +627,9 @@ static inline void mxc_elcdif_run(void)
elcdif_base + HW_ELCDIF_CTRL_SET);
__raw_writel(BM_ELCDIF_CTRL_RUN,
elcdif_base + HW_ELCDIF_CTRL_SET);
+
+ data->running = true;
+
return;
}
@@ -813,8 +884,8 @@ static int mxc_elcdif_fb_set_par(struct fb_info *fbi)
dev_dbg(fbi->device, "Reconfiguring framebuffer\n");
/* If parameter no change, don't reconfigure. */
- if (mxc_elcdif_fb_par_equal(fbi, data))
- return 0;
+ if (mxc_elcdif_fb_par_equal(fbi, data) && (data->running == true))
+ return 0;
sema_init(&data->flip_sem, 1);
@@ -882,7 +953,7 @@ static int mxc_elcdif_fb_set_par(struct fb_info *fbi)
sig_cfg,
1);
mxc_elcdif_frame_addr_setup(fbi->fix.smem_start);
- mxc_elcdif_run();
+ mxc_elcdif_run(data);
mxc_elcdif_blank_panel(FB_BLANK_UNBLANK);
fbi->mode = (struct fb_videomode *)fb_match_mode(&fbi->var,
@@ -1236,6 +1307,9 @@ static int mxc_elcdif_fb_probe(struct platform_device *pdev)
struct resource *res;
struct fb_info *fbi;
struct mxc_fb_platform_data *pdata = pdev->dev.platform_data;
+ const struct fb_videomode *mode;
+ struct fb_videomode m;
+ int num;
fbi = framebuffer_alloc(sizeof(struct mxc_elcdif_fb_data), &pdev->dev);
if (fbi == NULL) {
@@ -1296,20 +1370,63 @@ static int mxc_elcdif_fb_probe(struct platform_device *pdev)
if (pdata && !data->output_pix_fmt)
data->output_pix_fmt = pdata->interface_pix_fmt;
+ INIT_LIST_HEAD(&fbi->modelist);
+
if (pdata && pdata->mode && pdata->num_modes)
fb_videomode_to_modelist(pdata->mode, pdata->num_modes,
&fbi->modelist);
+ if (mxc_disp_mode.num_modes) {
+ int i;
+ mode = mxc_disp_mode.mode;
+ num = mxc_disp_mode.num_modes;
+
+ for (i = 0; i < num; i++) {
+ /*
+ * FIXME now we do not support interlaced
+ * mode for ddc mode
+ */
+ if ((mxc_disp_mode.dev_mode
+ & MXC_DISP_DDC_DEV) &&
+ (mode[i].vmode & FB_VMODE_INTERLACED))
+ continue;
+ else {
+ dev_dbg(&pdev->dev, "Added mode %d:", i);
+ dev_dbg(&pdev->dev,
+ "xres = %d, yres = %d, freq = %d, vmode = %d, flag = %d\n",
+ mode[i].xres, mode[i].yres, mode[i].refresh, mode[i].vmode,
+ mode[i].flag);
+ fb_add_videomode(&mode[i], &fbi->modelist);
+ }
+ }
+ }
+
if (!fb_mode && pdata && pdata->mode_str)
fb_mode = pdata->mode_str;
if (fb_mode) {
+ dev_dbg(&pdev->dev, "default video mode %s\n", fb_mode);
ret = fb_find_mode(&fbi->var, fbi, fb_mode, NULL, 0, NULL,
default_bpp);
- if ((!ret || (ret > 2)) && pdata && pdata->mode &&
- pdata->num_modes)
- fb_find_mode(&fbi->var, fbi, fb_mode, pdata->mode,
+ if ((ret == 1) || (ret == 2)) {
+ fb_var_to_videomode(&m, &fbi->var);
+ dump_fb_videomode(&m);
+ mode = fb_find_nearest_mode(&m,
+ &fbi->modelist);
+ fb_videomode_to_var(&fbi->var, mode);
+ } else if (pdata && pdata->mode && pdata->num_modes) {
+ ret = fb_find_mode(&fbi->var, fbi, fb_mode, pdata->mode,
pdata->num_modes, NULL, default_bpp);
+ if (!ret) {
+ dev_err(fbi->device,
+ "No valid video mode found");
+ goto err2;
+ }
+ } else {
+ dev_err(fbi->device,
+ "No valid video mode found");
+ goto err2;
+ }
}
mxc_elcdif_fb_check_var(&fbi->var, fbi);
@@ -1343,6 +1460,19 @@ static int mxc_elcdif_fb_probe(struct platform_device *pdev)
*/
clk_set_rate(g_elcdif_pix_clk, 25000000);
+ fbi->var.activate |= FB_ACTIVATE_FORCE;
+ console_lock();
+ fbi->flags |= FBINFO_MISC_USEREVENT;
+ ret = fb_set_var(fbi, &fbi->var);
+ fbi->flags &= ~FBINFO_MISC_USEREVENT;
+ console_unlock();
+
+ if (data->cur_blank == FB_BLANK_UNBLANK) {
+ console_lock();
+ fb_blank(fbi, FB_BLANK_UNBLANK);
+ console_unlock();
+ }
+
ret = register_framebuffer(fbi);
if (ret)
goto err3;
@@ -1424,6 +1554,7 @@ static int mxc_elcdif_fb_suspend(struct platform_device *pdev,
clk_disable(g_elcdif_axi_clk);
g_elcdif_axi_clk_enable = false;
}
+ data->running = false;
console_unlock();
return 0;
}
diff --git a/drivers/video/mxc/mxc_epdc_fb.c b/drivers/video/mxc/mxc_epdc_fb.c
index 0b3923c2cea6..727c6ebc575c 100644
--- a/drivers/video/mxc/mxc_epdc_fb.c
+++ b/drivers/video/mxc/mxc_epdc_fb.c
@@ -50,6 +50,7 @@
#include <linux/bitops.h>
#include <mach/epdc.h>
#include <mach/dma.h>
+#include <asm/cacheflush.h>
#include "epdc_regs.h"
@@ -69,6 +70,10 @@
#define INVALID_LUT (-1)
#define DRY_RUN_NO_LUT 100
+/* Maximum update buffer image width due to v2.0 and v2.1 errata ERR005313. */
+#define EPDC_V2_MAX_UPDATE_WIDTH 2047
+#define EPDC_V2_ROTATION_ALIGNMENT 8
+
#define DEFAULT_TEMP_INDEX 0
#define DEFAULT_TEMP 20 /* room temp in deg Celsius */
@@ -202,6 +207,8 @@ struct mxc_epdc_fb_data {
bool updates_active;
int pwrdown_delay;
unsigned long tce_prevent;
+ bool restrict_width; /* work around rev >=2.0 width and
+ stride restriction */
/* FB elements related to PxP DMA */
struct completion pxp_tx_cmpl;
@@ -262,6 +269,16 @@ static int pxp_complete_update(struct mxc_epdc_fb_data *fb_data, u32 *hist_stat)
static void draw_mode0(struct mxc_epdc_fb_data *fb_data);
static bool is_free_list_full(struct mxc_epdc_fb_data *fb_data);
+static void do_dithering_processing_Y1_v1_0(
+ unsigned char *update_region_ptr,
+ struct mxcfb_rect *update_region,
+ unsigned long update_region_stride,
+ int *err_dist);
+static void do_dithering_processing_Y4_v1_0(
+ unsigned char *update_region_ptr,
+ struct mxcfb_rect *update_region,
+ unsigned long update_region_stride,
+ int *err_dist);
#ifdef DEBUG
static void dump_pxp_config(struct mxc_epdc_fb_data *fb_data,
@@ -718,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) {
/*
@@ -745,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 {
@@ -1930,10 +1953,10 @@ static int epdc_process_update(struct update_data_list *upd_data_list,
* to copybuf in addition to the PxP structures */
mutex_lock(&fb_data->pxp_mutex);
- if ((((width_unaligned || height_unaligned || input_unaligned) &&
+ if (((((width_unaligned || height_unaligned || input_unaligned) &&
(upd_desc_list->upd_data.waveform_mode == WAVEFORM_MODE_AUTO))
- || line_overflow) && (fb_data->rev < 20)) {
-
+ || line_overflow) && (fb_data->rev < 20)) ||
+ fb_data->restrict_width) {
dev_dbg(fb_data->dev, "Copying update before processing.\n");
/* Update to reflect what the new source buffer will be */
@@ -2137,7 +2160,8 @@ static int epdc_process_update(struct update_data_list *upd_data_list,
}
static int epdc_submit_merge(struct update_desc_list *upd_desc_list,
- struct update_desc_list *update_to_merge)
+ struct update_desc_list *update_to_merge,
+ struct mxc_epdc_fb_data *fb_data)
{
struct mxcfb_update_data *a, *b;
struct mxcfb_rect *arect, *brect;
@@ -2195,6 +2219,19 @@ static int epdc_submit_merge(struct update_desc_list *upd_desc_list,
(arect->top + arect->height - combine.top) :
(brect->top + brect->height - combine.top);
+ /* Don't merge if combined width exceeds max width */
+ if (fb_data->restrict_width) {
+ u32 max_width = EPDC_V2_MAX_UPDATE_WIDTH;
+ u32 combined_width = combine.width;
+ if (fb_data->epdc_fb_var.rotate != FB_ROTATE_UR)
+ max_width -= EPDC_V2_ROTATION_ALIGNMENT;
+ if ((fb_data->epdc_fb_var.rotate == FB_ROTATE_CW) ||
+ (fb_data->epdc_fb_var.rotate == FB_ROTATE_CCW))
+ combined_width = combine.height;
+ if (combined_width > max_width)
+ return MERGE_FAIL;
+ }
+
*arect = combine;
/* Use flags of the later update */
@@ -2226,6 +2263,7 @@ static void epdc_submit_work_func(struct work_struct *work)
bool end_merge = false;
bool is_transform;
u32 update_addr;
+ int *err_dist;
int ret;
/* Protect access to buffer queues and to update HW */
@@ -2260,7 +2298,8 @@ static void epdc_submit_work_func(struct work_struct *work)
break;
} else {
switch (epdc_submit_merge(upd_data_list->update_desc,
- next_update->update_desc)) {
+ next_update->update_desc,
+ fb_data)) {
case MERGE_OK:
dev_dbg(fb_data->dev,
"Update merged [collision]\n");
@@ -2330,7 +2369,7 @@ static void epdc_submit_work_func(struct work_struct *work)
break;
} else {
switch (epdc_submit_merge(upd_data_list->update_desc,
- next_desc)) {
+ next_desc, fb_data)) {
case MERGE_OK:
dev_dbg(fb_data->dev,
"Update merged [queue]\n");
@@ -2371,12 +2410,14 @@ static void epdc_submit_work_func(struct work_struct *work)
* PxP in versions 2.0 and earlier of EPDC.
*/
is_transform = upd_data_list->update_desc->upd_data.flags &
- (EPDC_FLAG_ENABLE_INVERSION |
- EPDC_FLAG_FORCE_MONOCHROME | EPDC_FLAG_USE_CMAP) ?
- true : false;
+ (EPDC_FLAG_ENABLE_INVERSION | EPDC_FLAG_USE_DITHERING_Y1 |
+ EPDC_FLAG_USE_DITHERING_Y4 | EPDC_FLAG_FORCE_MONOCHROME |
+ EPDC_FLAG_USE_CMAP) ? true : false;
+
if ((fb_data->epdc_fb_var.rotate == FB_ROTATE_UR) &&
(fb_data->epdc_fb_var.grayscale == GRAYSCALE_8BIT) &&
- !is_transform && (fb_data->rev > 20)) {
+ !is_transform && (fb_data->rev > 20) &&
+ !fb_data->restrict_width) {
/* If needed, enable EPDC HW while ePxP is processing */
if ((fb_data->power_state == POWER_STATE_OFF)
@@ -2391,7 +2432,6 @@ static void epdc_submit_work_func(struct work_struct *work)
update_addr = fb_data->info.fix.smem_start +
((upd_region->top * fb_data->info.var.xres_virtual) +
upd_region->left) * fb_data->info.var.bits_per_pixel/8;
-
upd_data_list->update_desc->epdc_stride =
fb_data->info.var.xres_virtual *
fb_data->info.var.bits_per_pixel/8;
@@ -2457,6 +2497,45 @@ static void epdc_submit_work_func(struct work_struct *work)
}
/*
+ * Dithering Processing (Version 1.0 - for i.MX508 and i.MX6SL)
+ */
+ if (upd_data_list->update_desc->upd_data.flags &
+ EPDC_FLAG_USE_DITHERING_Y1) {
+
+ err_dist = kzalloc((fb_data->info.var.xres_virtual + 3) * 3
+ * sizeof(int), GFP_KERNEL);
+
+ /* Dithering Y8 -> Y1 */
+ do_dithering_processing_Y1_v1_0(
+ (uint8_t *)(upd_data_list->virt_addr +
+ upd_data_list->update_desc->epdc_offs),
+ &adj_update_region,
+ (fb_data->rev < 20) ?
+ ALIGN(adj_update_region.width, 8) :
+ adj_update_region.width,
+ err_dist);
+
+ kfree(err_dist);
+ } else if (upd_data_list->update_desc->upd_data.flags &
+ EPDC_FLAG_USE_DITHERING_Y4) {
+
+ err_dist = kzalloc((fb_data->info.var.xres_virtual + 3) * 3
+ * sizeof(int), GFP_KERNEL);
+
+ /* Dithering Y8 -> Y1 */
+ do_dithering_processing_Y4_v1_0(
+ (uint8_t *)(upd_data_list->virt_addr +
+ upd_data_list->update_desc->epdc_offs),
+ &adj_update_region,
+ (fb_data->rev < 20) ?
+ ALIGN(adj_update_region.width, 8) :
+ adj_update_region.width,
+ err_dist);
+
+ kfree(err_dist);
+ }
+
+ /*
* If there are no LUTs available,
* then we must wait for the resource to become free.
* The IST will signal this event.
@@ -2572,8 +2651,7 @@ static void epdc_submit_work_func(struct work_struct *work)
mutex_unlock(&fb_data->queue_mutex);
}
-
-int mxc_epdc_fb_send_update(struct mxcfb_update_data *upd_data,
+static int mxc_epdc_fb_send_single_update(struct mxcfb_update_data *upd_data,
struct fb_info *info)
{
struct mxc_epdc_fb_data *fb_data = info ?
@@ -2868,6 +2946,63 @@ int mxc_epdc_fb_send_update(struct mxcfb_update_data *upd_data,
mutex_unlock(&fb_data->queue_mutex);
return 0;
}
+
+int mxc_epdc_fb_send_update(struct mxcfb_update_data *upd_data,
+ struct fb_info *info)
+{
+ struct mxc_epdc_fb_data *fb_data = info ?
+ (struct mxc_epdc_fb_data *)info:g_fb_data;
+
+ if (!fb_data->restrict_width) {
+ /* No width restriction, send entire update region */
+ return mxc_epdc_fb_send_single_update(upd_data, info);
+ } else {
+ int ret;
+ __u32 width, left;
+ __u32 marker;
+ __u32 *region_width, *region_left;
+ u32 max_upd_width = EPDC_V2_MAX_UPDATE_WIDTH;
+
+ /* Further restrict max width due to pxp rotation
+ * alignment requirement
+ */
+ if (fb_data->epdc_fb_var.rotate != FB_ROTATE_UR)
+ max_upd_width -= EPDC_V2_ROTATION_ALIGNMENT;
+
+ /* Select split of width or height based on rotation */
+ if ((fb_data->epdc_fb_var.rotate == FB_ROTATE_UR) ||
+ (fb_data->epdc_fb_var.rotate == FB_ROTATE_UD)) {
+ region_width = &upd_data->update_region.width;
+ region_left = &upd_data->update_region.left;
+ } else {
+ region_width = &upd_data->update_region.height;
+ region_left = &upd_data->update_region.top;
+ }
+
+ if (*region_width <= max_upd_width)
+ return mxc_epdc_fb_send_single_update(upd_data, info);
+
+ width = *region_width;
+ left = *region_left;
+ marker = upd_data->update_marker;
+ upd_data->update_marker = 0;
+
+ do {
+ *region_width = max_upd_width;
+ *region_left = left;
+ ret = mxc_epdc_fb_send_single_update(upd_data, info);
+ if (ret)
+ return ret;
+ width -= max_upd_width;
+ left += max_upd_width;
+ } while (width > max_upd_width);
+
+ *region_width = width;
+ *region_left = left;
+ upd_data->update_marker = marker;
+ return mxc_epdc_fb_send_single_update(upd_data, info);
+ }
+}
EXPORT_SYMBOL(mxc_epdc_fb_send_update);
int mxc_epdc_fb_wait_update_complete(struct mxcfb_update_marker_data *marker_data,
@@ -3041,6 +3176,25 @@ static int mxc_epdc_fb_ioctl(struct fb_info *info, unsigned int cmd,
ret = 0;
break;
}
+
+ case MXCFB_GET_WORK_BUFFER:
+ {
+ /* copy the epdc working buffer to the user space */
+ struct mxc_epdc_fb_data *fb_data = info ?
+ (struct mxc_epdc_fb_data *)info:g_fb_data;
+ flush_cache_all();
+ outer_flush_all();
+ if (copy_to_user((void __user *)arg,
+ (const void *) fb_data->working_buffer_virt,
+ fb_data->working_buffer_size))
+ ret = -EFAULT;
+ else
+ ret = 0;
+ flush_cache_all();
+ outer_flush_all();
+ break;
+ }
+
default:
break;
}
@@ -3546,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) */
/*
@@ -4076,7 +4236,8 @@ static void mxc_epdc_fb_fw_handler(const struct firmware *fw,
&fb_data->info);
if (ret < 0)
dev_err(fb_data->dev,
- "Wait for update complete failed. Error = 0x%x", ret);
+ "Wait for initial update complete failed."
+ " Error = 0x%x", ret);
}
static int mxc_epdc_fb_init_hw(struct fb_info *info)
@@ -4417,6 +4578,8 @@ int __devinit mxc_epdc_fb_probe(struct platform_device *pdev)
} else {
fb_data->num_luts = EPDC_V2_NUM_LUTS;
fb_data->max_num_updates = EPDC_V2_MAX_NUM_UPDATES;
+ if (vmode->xres > EPDC_V2_MAX_UPDATE_WIDTH)
+ fb_data->restrict_width = true;
}
fb_data->max_num_buffers = EPDC_MAX_NUM_BUFFERS;
@@ -4454,8 +4617,9 @@ int __devinit mxc_epdc_fb_probe(struct platform_device *pdev)
* be as big as the full-screen frame buffer
*/
fb_data->virt_addr_updbuf[i] =
- dma_alloc_coherent(fb_data->info.device, fb_data->max_pix_size,
- &fb_data->phys_addr_updbuf[i], GFP_DMA);
+ kmalloc(fb_data->max_pix_size, GFP_KERNEL);
+ fb_data->phys_addr_updbuf[i] =
+ virt_to_phys(fb_data->virt_addr_updbuf[i]);
if (fb_data->virt_addr_updbuf[i] == NULL) {
ret = -ENOMEM;
goto out_upd_buffers;
@@ -4737,10 +4901,7 @@ out_copybuffer:
out_upd_buffers:
for (i = 0; i < fb_data->max_num_buffers; i++)
if (fb_data->virt_addr_updbuf[i] != NULL)
- dma_free_writecombine(&pdev->dev,
- fb_data->max_pix_size,
- fb_data->virt_addr_updbuf[i],
- fb_data->phys_addr_updbuf[i]);
+ kfree(fb_data->virt_addr_updbuf[i]);
if (fb_data->virt_addr_updbuf != NULL)
kfree(fb_data->virt_addr_updbuf);
if (fb_data->phys_addr_updbuf != NULL)
@@ -4785,9 +4946,7 @@ static int mxc_epdc_fb_remove(struct platform_device *pdev)
for (i = 0; i < fb_data->max_num_buffers; i++)
if (fb_data->virt_addr_updbuf[i] != NULL)
- dma_free_writecombine(&pdev->dev, fb_data->max_pix_size,
- fb_data->virt_addr_updbuf[i],
- fb_data->phys_addr_updbuf[i]);
+ kfree(fb_data->virt_addr_updbuf[i]);
if (fb_data->virt_addr_updbuf != NULL)
kfree(fb_data->virt_addr_updbuf);
if (fb_data->phys_addr_updbuf != NULL)
@@ -5082,6 +5241,124 @@ static int pxp_complete_update(struct mxc_epdc_fb_data *fb_data, u32 *hist_stat)
return 0;
}
+/*
+ * Different dithering algorithm can be used. We chose
+ * to implement Bill Atkinson's algorithm as an example
+ * Thanks Bill Atkinson for his dithering algorithm.
+ */
+
+/*
+ * Dithering algorithm implementation - Y8->Y1 version 1.0 for i.MX
+ */
+static void do_dithering_processing_Y1_v1_0(
+ unsigned char *update_region_ptr,
+ struct mxcfb_rect *update_region,
+ unsigned long update_region_stride,
+ int *err_dist)
+{
+
+ /* create a temp error distribution array */
+ int bwPix;
+ int y;
+ int col;
+ int *err_dist_l0, *err_dist_l1, *err_dist_l2, distrib_error;
+ int width_3 = update_region->width + 3;
+ char *y8buf;
+ int x_offset = 0;
+
+ /* prime a few elements the error distribution array */
+ for (y = 0; y < update_region->height; y++) {
+ /* Dithering the Y8 in sbuf to BW suitable for A2 waveform */
+ err_dist_l0 = err_dist + (width_3) * (y % 3);
+ err_dist_l1 = err_dist + (width_3) * ((y + 1) % 3);
+ err_dist_l2 = err_dist + (width_3) * ((y + 2) % 3);
+
+ y8buf = update_region_ptr + x_offset;
+
+ /* scan the line and convert the Y8 to BW */
+ for (col = 1; col <= update_region->width; col++) {
+ bwPix = *(err_dist_l0 + col) + *y8buf;
+
+ if (bwPix >= 128) {
+ *y8buf++ = 0xff;
+ distrib_error = (bwPix - 255) >> 3;
+ } else {
+ *y8buf++ = 0;
+ distrib_error = bwPix >> 3;
+ }
+
+ /* modify the error distribution buffer */
+ *(err_dist_l0 + col + 2) += distrib_error;
+ *(err_dist_l1 + col + 1) += distrib_error;
+ *(err_dist_l0 + col + 1) += distrib_error;
+ *(err_dist_l1 + col - 1) += distrib_error;
+ *(err_dist_l1 + col) += distrib_error;
+ *(err_dist_l2 + col) = distrib_error;
+ }
+ x_offset += update_region_stride;
+ }
+
+ flush_cache_all();
+ outer_flush_all();
+}
+
+/*
+ * Dithering algorithm implementation - Y8->Y4 version 1.0 for i.MX
+ */
+
+static void do_dithering_processing_Y4_v1_0(
+ unsigned char *update_region_ptr,
+ struct mxcfb_rect *update_region,
+ unsigned long update_region_stride,
+ int *err_dist)
+{
+
+ /* create a temp error distribution array */
+ int gcPix;
+ int y;
+ int col;
+ int *err_dist_l0, *err_dist_l1, *err_dist_l2, distrib_error;
+ int width_3 = update_region->width + 3;
+ char *y8buf;
+ int x_offset = 0;
+
+ /* prime a few elements the error distribution array */
+ for (y = 0; y < update_region->height; y++) {
+ /* Dithering the Y8 in sbuf to Y4 */
+ err_dist_l0 = err_dist + (width_3) * (y % 3);
+ err_dist_l1 = err_dist + (width_3) * ((y + 1) % 3);
+ err_dist_l2 = err_dist + (width_3) * ((y + 2) % 3);
+
+ y8buf = update_region_ptr + x_offset;
+
+ /* scan the line and convert the Y8 to Y4 */
+ for (col = 1; col <= update_region->width; col++) {
+ gcPix = *(err_dist_l0 + col) + *y8buf;
+
+ if (gcPix > 255)
+ gcPix = 255;
+ else if (gcPix < 0)
+ gcPix = 0;
+
+ distrib_error = (*y8buf - (gcPix & 0xf0)) >> 3;
+
+ *y8buf++ = gcPix & 0xf0;
+
+ /* modify the error distribution buffer */
+ *(err_dist_l0 + col + 2) += distrib_error;
+ *(err_dist_l1 + col + 1) += distrib_error;
+ *(err_dist_l0 + col + 1) += distrib_error;
+ *(err_dist_l1 + col - 1) += distrib_error;
+ *(err_dist_l1 + col) += distrib_error;
+ *(err_dist_l2 + col) = distrib_error;
+ }
+ x_offset += update_region_stride;
+ }
+
+ flush_cache_all();
+ outer_flush_all();
+}
+
static int __init mxc_epdc_fb_init(void)
{
return platform_driver_register(&mxc_epdc_fb_driver);
diff --git a/drivers/video/mxc/mxc_ipuv3_fb.c b/drivers/video/mxc/mxc_ipuv3_fb.c
index b38f97d246a5..a41001c834c6 100644
--- a/drivers/video/mxc/mxc_ipuv3_fb.c
+++ b/drivers/video/mxc/mxc_ipuv3_fb.c
@@ -113,6 +113,25 @@ struct mxcfb_info {
#endif
};
+struct mxcfb_pfmt {
+ u32 fb_pix_fmt;
+ int bpp;
+ struct fb_bitfield red;
+ struct fb_bitfield green;
+ struct fb_bitfield blue;
+ struct fb_bitfield transp;
+};
+
+static const struct mxcfb_pfmt mxcfb_pfmts[] = {
+ /* pixel bpp red green blue transp */
+ {IPU_PIX_FMT_RGB565, 16, {11, 5, 0}, { 5, 6, 0}, { 0, 5, 0}, { 0, 0, 0} },
+ {IPU_PIX_FMT_RGB24, 24, { 0, 8, 0}, { 8, 8, 0}, {16, 8, 0}, { 0, 0, 0} },
+ {IPU_PIX_FMT_BGR24, 24, {16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, { 0, 0, 0} },
+ {IPU_PIX_FMT_RGB32, 32, { 0, 8, 0}, { 8, 8, 0}, {16, 8, 0}, {24, 8, 0} },
+ {IPU_PIX_FMT_BGR32, 32, {16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, {24, 8, 0} },
+ {IPU_PIX_FMT_ABGR32, 32, {24, 8, 0}, {16, 8, 0}, { 8, 8, 0}, { 0, 8, 0} },
+};
+
struct mxcfb_alloc_list {
struct list_head list;
dma_addr_t phy_addr;
@@ -135,14 +154,12 @@ static void mxcfb_early_suspend(struct early_suspend *h);
static void mxcfb_later_resume(struct early_suspend *h);
#endif
-static uint32_t bpp_to_pixfmt(struct fb_info *fbi)
+/* Return default standard(RGB) pixel format */
+static uint32_t bpp_to_pixfmt(int bpp)
{
uint32_t pixfmt = 0;
- if (fbi->var.nonstd)
- return fbi->var.nonstd;
-
- switch (fbi->var.bits_per_pixel) {
+ switch (bpp) {
case 24:
pixfmt = IPU_PIX_FMT_BGR24;
break;
@@ -156,6 +173,82 @@ static uint32_t bpp_to_pixfmt(struct fb_info *fbi)
return pixfmt;
}
+static inline int bitfield_is_equal(struct fb_bitfield f1,
+ struct fb_bitfield f2)
+{
+ return !memcmp(&f1, &f2, sizeof(f1));
+}
+
+static int pixfmt_to_var(uint32_t pixfmt, struct fb_var_screeninfo *var)
+{
+ int i, ret = -1;
+
+ for (i = 0; i < ARRAY_SIZE(mxcfb_pfmts); i++) {
+ if (pixfmt == mxcfb_pfmts[i].fb_pix_fmt) {
+ var->red = mxcfb_pfmts[i].red;
+ var->green = mxcfb_pfmts[i].green;
+ var->blue = mxcfb_pfmts[i].blue;
+ var->transp = mxcfb_pfmts[i].transp;
+ var->bits_per_pixel = mxcfb_pfmts[i].bpp;
+ ret = 0;
+ break;
+ }
+ }
+ return ret;
+}
+
+static int bpp_to_var(int bpp, struct fb_var_screeninfo *var)
+{
+ uint32_t pixfmt = 0;
+
+ pixfmt = bpp_to_pixfmt(bpp);
+ if (pixfmt)
+ return pixfmt_to_var(pixfmt, var);
+ else
+ return -1;
+}
+
+static int check_var_pixfmt(struct fb_var_screeninfo *var)
+{
+ int i, ret = -1;
+
+ for (i = 0; i < ARRAY_SIZE(mxcfb_pfmts); i++) {
+ if (bitfield_is_equal(var->red, mxcfb_pfmts[i].red) &&
+ bitfield_is_equal(var->green, mxcfb_pfmts[i].green) &&
+ bitfield_is_equal(var->blue, mxcfb_pfmts[i].blue) &&
+ bitfield_is_equal(var->transp, mxcfb_pfmts[i].transp) &&
+ var->bits_per_pixel == mxcfb_pfmts[i].bpp) {
+ ret = 0;
+ break;
+ }
+ }
+ return ret;
+}
+
+static uint32_t fbi_to_pixfmt(struct fb_info *fbi)
+{
+ int i;
+ uint32_t pixfmt = 0;
+
+ if (fbi->var.nonstd)
+ return fbi->var.nonstd;
+
+ for (i = 0; i < ARRAY_SIZE(mxcfb_pfmts); i++) {
+ if (bitfield_is_equal(fbi->var.red, mxcfb_pfmts[i].red) &&
+ bitfield_is_equal(fbi->var.green, mxcfb_pfmts[i].green) &&
+ bitfield_is_equal(fbi->var.blue, mxcfb_pfmts[i].blue) &&
+ bitfield_is_equal(fbi->var.transp, mxcfb_pfmts[i].transp)) {
+ pixfmt = mxcfb_pfmts[i].fb_pix_fmt;
+ break;
+ }
+ }
+
+ if (pixfmt == 0)
+ dev_err(fbi->device, "cannot get pixel format\n");
+
+ return pixfmt;
+}
+
static struct fb_info *found_registered_fb(ipu_channel_t ipu_ch, int ipu_id)
{
int i;
@@ -216,13 +309,13 @@ static int _setup_disp_channel1(struct fb_info *fbi)
if (fbi->var.vmode & FB_VMODE_INTERLACED)
params.mem_dc_sync.interlaced = true;
params.mem_dc_sync.out_pixel_fmt = mxc_fbi->ipu_di_pix_fmt;
- params.mem_dc_sync.in_pixel_fmt = bpp_to_pixfmt(fbi);
+ params.mem_dc_sync.in_pixel_fmt = fbi_to_pixfmt(fbi);
} else {
params.mem_dp_bg_sync.di = mxc_fbi->ipu_di;
if (fbi->var.vmode & FB_VMODE_INTERLACED)
params.mem_dp_bg_sync.interlaced = true;
params.mem_dp_bg_sync.out_pixel_fmt = mxc_fbi->ipu_di_pix_fmt;
- params.mem_dp_bg_sync.in_pixel_fmt = bpp_to_pixfmt(fbi);
+ params.mem_dp_bg_sync.in_pixel_fmt = fbi_to_pixfmt(fbi);
if (mxc_fbi->alpha_chan_en)
params.mem_dp_bg_sync.alpha_chan_en = true;
}
@@ -239,7 +332,7 @@ static int _setup_disp_channel2(struct fb_info *fbi)
unsigned long base;
unsigned int fr_xoff, fr_yoff, fr_w, fr_h;
- switch (bpp_to_pixfmt(fbi)) {
+ switch (fbi_to_pixfmt(fbi)) {
case IPU_PIX_FMT_YUV420P2:
case IPU_PIX_FMT_YVU420P:
case IPU_PIX_FMT_NV12:
@@ -287,7 +380,7 @@ static int _setup_disp_channel2(struct fb_info *fbi)
retval = ipu_init_channel_buffer(mxc_fbi->ipu,
mxc_fbi->ipu_ch, IPU_INPUT_BUFFER,
- bpp_to_pixfmt(fbi),
+ fbi_to_pixfmt(fbi),
fbi->var.xres, fbi->var.yres,
fb_stride,
fbi->var.rotate,
@@ -305,7 +398,7 @@ static int _setup_disp_channel2(struct fb_info *fbi)
/* update u/v offset */
ipu_update_channel_offset(mxc_fbi->ipu, mxc_fbi->ipu_ch,
IPU_INPUT_BUFFER,
- bpp_to_pixfmt(fbi),
+ fbi_to_pixfmt(fbi),
fr_w,
fr_h,
fr_w,
@@ -786,76 +879,9 @@ static int mxcfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
(var->bits_per_pixel != 8))
var->bits_per_pixel = 16;
- switch (var->bits_per_pixel) {
- case 8:
- var->red.length = 3;
- var->red.offset = 5;
- var->red.msb_right = 0;
-
- var->green.length = 3;
- var->green.offset = 2;
- var->green.msb_right = 0;
-
- var->blue.length = 2;
- var->blue.offset = 0;
- var->blue.msb_right = 0;
-
- var->transp.length = 0;
- var->transp.offset = 0;
- var->transp.msb_right = 0;
- break;
- case 16:
- var->red.length = 5;
- var->red.offset = 11;
- var->red.msb_right = 0;
-
- var->green.length = 6;
- var->green.offset = 5;
- var->green.msb_right = 0;
-
- var->blue.length = 5;
- var->blue.offset = 0;
- var->blue.msb_right = 0;
-
- var->transp.length = 0;
- var->transp.offset = 0;
- var->transp.msb_right = 0;
- break;
- case 24:
- var->red.length = 8;
- var->red.offset = 16;
- var->red.msb_right = 0;
-
- var->green.length = 8;
- var->green.offset = 8;
- var->green.msb_right = 0;
-
- var->blue.length = 8;
- var->blue.offset = 0;
- var->blue.msb_right = 0;
-
- var->transp.length = 0;
- var->transp.offset = 0;
- var->transp.msb_right = 0;
- break;
- case 32:
- var->red.length = 8;
- var->red.offset = 16;
- var->red.msb_right = 0;
-
- var->green.length = 8;
- var->green.offset = 8;
- var->green.msb_right = 0;
-
- var->blue.length = 8;
- var->blue.offset = 0;
- var->blue.msb_right = 0;
-
- var->transp.length = 8;
- var->transp.offset = 24;
- var->transp.msb_right = 0;
- break;
- }
+ if (check_var_pixfmt(var))
+ /* Fall back to default */
+ bpp_to_var(var->bits_per_pixel, var);
if (var->pixclock < 1000) {
htotal = var->xres + var->right_margin + var->hsync_len +
@@ -1443,7 +1469,7 @@ mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
if (y_bottom > info->var.yres_virtual)
return -EINVAL;
- switch (bpp_to_pixfmt(info)) {
+ switch (fbi_to_pixfmt(info)) {
case IPU_PIX_FMT_YUV420P2:
case IPU_PIX_FMT_YVU420P:
case IPU_PIX_FMT_NV12:
@@ -1530,7 +1556,7 @@ mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
/* update u/v offset */
ipu_update_channel_offset(mxc_fbi->ipu, mxc_fbi->ipu_ch,
IPU_INPUT_BUFFER,
- bpp_to_pixfmt(info),
+ fbi_to_pixfmt(info),
fr_w,
fr_h,
fr_w,
@@ -1982,12 +2008,14 @@ static int mxcfb_dispdrv_init(struct platform_device *pdev,
* Parse user specified options (`video=trident:')
* example:
* video=mxcfb0:dev=lcd,800x480M-16@55,if=RGB565,bpp=16,noaccel
+ * video=mxcfb0:dev=lcd,800x480M-16@55,if=RGB565,fbpix=RGB565
*/
-static int mxcfb_option_setup(struct platform_device *pdev)
+static int mxcfb_option_setup(struct platform_device *pdev, struct fb_info *fbi)
{
struct ipuv3_fb_platform_data *pdata = pdev->dev.platform_data;
char *options, *opt, *fb_mode_str = NULL;
char name[] = "mxcfb0";
+ uint32_t fb_pix_fmt = 0;
name[5] += pdev->id;
if (fb_get_options(name, &options)) {
@@ -2005,61 +2033,63 @@ static int mxcfb_option_setup(struct platform_device *pdev)
if (!strncmp(opt, "dev=", 4)) {
memcpy(pdata->disp_dev, opt + 4, strlen(opt) - 4);
pdata->disp_dev[strlen(opt) - 4] = '\0';
- continue;
- }
- if (!strncmp(opt, "if=", 3)) {
- if (!strncmp(opt+3, "RGB24", 5)) {
+ } else if (!strncmp(opt, "if=", 3)) {
+ if (!strncmp(opt+3, "RGB24", 5))
pdata->interface_pix_fmt = IPU_PIX_FMT_RGB24;
- continue;
- } else if (!strncmp(opt+6, "BGR24", 5)) {
+ else if (!strncmp(opt+3, "BGR24", 5))
pdata->interface_pix_fmt = IPU_PIX_FMT_BGR24;
- continue;
- }
- if (!strncmp(opt+3, "GBR24", 5)) {
+ else if (!strncmp(opt+3, "GBR24", 5))
pdata->interface_pix_fmt = IPU_PIX_FMT_GBR24;
- continue;
- }
- if (!strncmp(opt+3, "RGB565", 6)) {
+ else if (!strncmp(opt+3, "RGB565", 6))
pdata->interface_pix_fmt = IPU_PIX_FMT_RGB565;
- continue;
- }
- if (!strncmp(opt+3, "RGB666", 6)) {
+ else if (!strncmp(opt+3, "RGB666", 6))
pdata->interface_pix_fmt = IPU_PIX_FMT_RGB666;
- continue;
- }
- if (!strncmp(opt+3, "YUV444", 6)) {
+ else if (!strncmp(opt+3, "YUV444", 6))
pdata->interface_pix_fmt = IPU_PIX_FMT_YUV444;
- continue;
- }
- if (!strncmp(opt+3, "LVDS666", 7)) {
+ else if (!strncmp(opt+3, "LVDS666", 7))
pdata->interface_pix_fmt = IPU_PIX_FMT_LVDS666;
- continue;
- }
- if (!strncmp(opt+3, "YUYV16", 6)) {
+ else if (!strncmp(opt+3, "YUYV16", 6))
pdata->interface_pix_fmt = IPU_PIX_FMT_YUYV;
- continue;
- }
- if (!strncmp(opt+3, "UYVY16", 6)) {
+ else if (!strncmp(opt+3, "UYVY16", 6))
pdata->interface_pix_fmt = IPU_PIX_FMT_UYVY;
- continue;
- }
- if (!strncmp(opt+3, "YVYU16", 6)) {
+ else if (!strncmp(opt+3, "YVYU16", 6))
pdata->interface_pix_fmt = IPU_PIX_FMT_YVYU;
- continue;
- }
- if (!strncmp(opt+3, "VYUY16", 6)) {
+ else if (!strncmp(opt+3, "VYUY16", 6))
pdata->interface_pix_fmt = IPU_PIX_FMT_VYUY;
- continue;
+ } else if (!strncmp(opt, "fbpix=", 6)) {
+ if (!strncmp(opt+6, "RGB24", 5))
+ fb_pix_fmt = IPU_PIX_FMT_RGB24;
+ else if (!strncmp(opt+6, "BGR24", 5))
+ fb_pix_fmt = IPU_PIX_FMT_BGR24;
+ else if (!strncmp(opt+6, "RGB32", 5))
+ fb_pix_fmt = IPU_PIX_FMT_RGB32;
+ else if (!strncmp(opt+6, "BGR32", 5))
+ fb_pix_fmt = IPU_PIX_FMT_BGR32;
+ else if (!strncmp(opt+6, "ABGR32", 6))
+ fb_pix_fmt = IPU_PIX_FMT_ABGR32;
+ else if (!strncmp(opt+6, "RGB565", 6))
+ fb_pix_fmt = IPU_PIX_FMT_RGB565;
+
+ if (fb_pix_fmt) {
+ pixfmt_to_var(fb_pix_fmt, &fbi->var);
+ pdata->default_bpp =
+ fbi->var.bits_per_pixel;
}
- }
- if (!strncmp(opt, "int_clk", 7)) {
+ } else if (!strncmp(opt, "int_clk", 7)) {
pdata->int_clk = true;
continue;
- }
- if (!strncmp(opt, "bpp=", 4))
+ } else if (!strncmp(opt, "bpp=", 4)) {
+ /* bpp setting cannot overwirte fbpix setting */
+ if (fb_pix_fmt)
+ continue;
+
pdata->default_bpp =
simple_strtoul(opt + 4, NULL, 0);
- else
+
+ fb_pix_fmt = bpp_to_pixfmt(pdata->default_bpp);
+ if (fb_pix_fmt)
+ pixfmt_to_var(fb_pix_fmt, &fbi->var);
+ } else
fb_mode_str = opt;
}
@@ -2320,10 +2350,6 @@ static int mxcfb_probe(struct platform_device *pdev)
char buf[32];
int ret = 0;
- ret = mxcfb_option_setup(pdev);
- if (ret)
- goto get_fb_option_failed;
-
/* Initialize FB structures */
fbi = mxcfb_init_fbinfo(&pdev->dev, &mxcfb_ops);
if (!fbi) {
@@ -2331,6 +2357,10 @@ static int mxcfb_probe(struct platform_device *pdev)
goto init_fbinfo_failed;
}
+ ret = mxcfb_option_setup(pdev, fbi);
+ if (ret)
+ goto get_fb_option_failed;
+
mxcfbi = (struct mxcfb_info *)fbi->par;
spin_lock_init(&mxcfbi->lock);
mxcfbi->fbi = fbi;
@@ -2481,8 +2511,8 @@ ipu_in_busy:
init_dispdrv_failed:
fb_dealloc_cmap(&fbi->cmap);
framebuffer_release(fbi);
-init_fbinfo_failed:
get_fb_option_failed:
+init_fbinfo_failed:
return ret;
}
diff --git a/drivers/video/mxc/mxcfb_sii902x_elcdif.c b/drivers/video/mxc/mxcfb_sii902x_elcdif.c
new file mode 100644
index 000000000000..ceab3e66e91c
--- /dev/null
+++ b/drivers/video/mxc/mxcfb_sii902x_elcdif.c
@@ -0,0 +1,560 @@
+/*
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*!
+ * @defgroup Framebuffer Framebuffer Driver for SDC and ADC.
+ */
+
+/*!
+ * @file mxcfb_sii902x_elcdif.c
+ *
+ * @brief MXC ELCDIF Frame buffer driver for SII902x
+ *
+ * @ingroup Framebuffer
+ */
+
+/*!
+ * Include files
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/i2c.h>
+#include <linux/mxcfb.h>
+#include <linux/fsl_devices.h>
+#include <linux/interrupt.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <mach/mxc_edid.h>
+
+#define SII_EDID_LEN 512
+#define MXC_ENABLE 1
+#define MXC_DISABLE 2
+
+struct sii902x_data {
+ struct platform_device *pdev;
+ struct i2c_client *client;
+ struct delayed_work det_work;
+ struct fb_info *fbi;
+ struct mxc_edid_cfg edid_cfg;
+ u8 cable_plugin;
+ u8 edid[SII_EDID_LEN];
+ bool waiting_for_fb;
+} sii902x;
+
+static void sii902x_poweron(void);
+static void sii902x_poweroff(void);
+static void (*sii902x_reset) (void);
+
+#ifdef DEBUG
+static void dump_fb_videomode(struct fb_videomode *m)
+{
+ pr_debug("fb_videomode = %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
+ m->refresh, m->xres, m->yres, m->pixclock, m->left_margin,
+ m->right_margin, m->upper_margin, m->lower_margin,
+ m->hsync_len, m->vsync_len, m->sync, m->vmode, m->flag);
+}
+#else
+static void dump_fb_videomode(struct fb_videomode *m)
+{}
+#endif
+
+static __attribute__ ((unused)) void dump_regs(u8 reg, int len)
+{
+ u8 buf[50];
+ int i;
+
+ i2c_smbus_read_i2c_block_data(sii902x.client, reg, len, buf);
+ for (i = 0; i < len; i++)
+ dev_dbg(&sii902x.client->dev, "reg[0x%02X]: 0x%02X\n",
+ i+reg, buf[i]);
+}
+
+static ssize_t sii902x_show_name(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ strcpy(buf, sii902x.fbi->fix.id);
+ sprintf(buf+strlen(buf), "\n");
+
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(fb_name, S_IRUGO, sii902x_show_name, NULL);
+
+static ssize_t sii902x_show_state(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ if (sii902x.cable_plugin == 0)
+ strcpy(buf, "plugout\n");
+ else
+ strcpy(buf, "plugin\n");
+
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(cable_state, S_IRUGO, sii902x_show_state, NULL);
+
+static ssize_t sii902x_show_edid(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int i, j, len = 0;
+
+ for (j = 0; j < SII_EDID_LEN/16; j++) {
+ for (i = 0; i < 16; i++)
+ len += sprintf(buf+len, "0x%02X ",
+ sii902x.edid[j*16 + i]);
+ len += sprintf(buf+len, "\n");
+ }
+
+ return len;
+}
+
+static DEVICE_ATTR(edid, S_IRUGO, sii902x_show_edid, NULL);
+
+static void sii902x_setup(struct fb_info *fbi)
+{
+ u16 data[4];
+ u32 refresh;
+ u8 *tmp;
+ int i;
+
+ dev_dbg(&sii902x.client->dev, "Sii902x: setup..\n");
+
+ /* Power up */
+ i2c_smbus_write_byte_data(sii902x.client, 0x1E, 0x00);
+
+ /* set TPI video mode */
+ data[0] = PICOS2KHZ(fbi->var.pixclock) / 10;
+ data[2] = fbi->var.hsync_len + fbi->var.left_margin +
+ fbi->var.xres + fbi->var.right_margin;
+ data[3] = fbi->var.vsync_len + fbi->var.upper_margin +
+ fbi->var.yres + fbi->var.lower_margin;
+ refresh = data[2] * data[3];
+ refresh = (PICOS2KHZ(fbi->var.pixclock) * 1000) / refresh;
+ data[1] = refresh * 100;
+ tmp = (u8 *)data;
+ for (i = 0; i < 8; i++)
+ i2c_smbus_write_byte_data(sii902x.client, i, tmp[i]);
+
+ /* input bus/pixel: full pixel wide (24bit), rising edge */
+ i2c_smbus_write_byte_data(sii902x.client, 0x08, 0x70);
+ /* Set input format to RGB */
+ i2c_smbus_write_byte_data(sii902x.client, 0x09, 0x00);
+ /* set output format to RGB */
+ i2c_smbus_write_byte_data(sii902x.client, 0x0A, 0x00);
+ /* audio setup */
+ i2c_smbus_write_byte_data(sii902x.client, 0x25, 0x00);
+ i2c_smbus_write_byte_data(sii902x.client, 0x26, 0x40);
+ i2c_smbus_write_byte_data(sii902x.client, 0x27, 0x00);
+}
+
+#ifdef CONFIG_FB_MODE_HELPERS
+static int sii902x_read_edid(struct fb_info *fbi)
+{
+ int old, dat, ret, cnt = 100;
+ unsigned short addr = 0x50;
+
+ dev_dbg(&sii902x.pdev->dev, "%s\n", __func__);
+
+ old = i2c_smbus_read_byte_data(sii902x.client, 0x1A);
+
+ i2c_smbus_write_byte_data(sii902x.client, 0x1A, old | 0x4);
+ do {
+ cnt--;
+ msleep(10);
+ dat = i2c_smbus_read_byte_data(sii902x.client, 0x1A);
+ } while ((!(dat & 0x2)) && cnt);
+
+ if (!cnt) {
+ ret = -1;
+ goto done;
+ }
+
+ i2c_smbus_write_byte_data(sii902x.client, 0x1A, old | 0x06);
+
+ /* edid reading */
+ ret = mxc_edid_read(sii902x.client->adapter, addr,
+ sii902x.edid, &sii902x.edid_cfg, fbi);
+
+ cnt = 100;
+ do {
+ cnt--;
+ i2c_smbus_write_byte_data(sii902x.client, 0x1A, old & ~0x6);
+ msleep(10);
+ dat = i2c_smbus_read_byte_data(sii902x.client, 0x1A);
+ } while ((dat & 0x6) && cnt);
+
+ if (!cnt)
+ ret = -1;
+
+done:
+
+ i2c_smbus_write_byte_data(sii902x.client, 0x1A, old);
+ return ret;
+}
+#else
+static int sii902x_read_edid(struct fb_info *fbi)
+{
+ return -1;
+}
+#endif
+
+static void det_worker(struct work_struct *work)
+{
+ int dat;
+ char event_string[16];
+ char *envp[] = { event_string, NULL };
+
+ dev_dbg(&sii902x.pdev->dev, "%s\n", __func__);
+
+ dat = i2c_smbus_read_byte_data(sii902x.client, 0x3D);
+ if (dat & 0x1) {
+ /* cable connection changes */
+ if (dat & 0x4) {
+ sii902x.cable_plugin = 1;
+ dev_dbg(&sii902x.pdev->dev, "EVENT=plugin\n");
+ sprintf(event_string, "EVENT=plugin");
+
+ /* make sure fb is powerdown */
+ console_lock();
+ fb_blank(sii902x.fbi, FB_BLANK_POWERDOWN);
+ console_unlock();
+
+ if (sii902x_read_edid(sii902x.fbi) < 0)
+ dev_err(&sii902x.client->dev,
+ "Sii902x: read edid fail\n");
+ else {
+ if (sii902x.fbi->monspecs.modedb_len > 0) {
+
+ int i;
+ const struct fb_videomode *mode;
+ struct fb_videomode m;
+
+ fb_destroy_modelist(&sii902x.fbi->modelist);
+
+ for (i = 0; i < sii902x.fbi->monspecs.modedb_len; i++) {
+ /*FIXME now we do not support interlaced mode */
+ mode = &sii902x.fbi->monspecs.modedb[i];
+
+ if (!(mode->vmode & FB_VMODE_INTERLACED)) {
+
+ dev_dbg(&sii902x.pdev->dev, "Added mode %d:", i);
+ dev_dbg(&sii902x.pdev->dev,
+ "xres = %d, yres = %d, freq = %d, vmode = %d, flag = %d\n",
+ mode->xres, mode->yres, mode->refresh,
+ mode->vmode, mode->flag);
+
+ fb_add_videomode(mode, &sii902x.fbi->modelist);
+ }
+ }
+
+ fb_var_to_videomode(&m, &sii902x.fbi->var);
+ dump_fb_videomode(&m);
+
+ mode = fb_find_nearest_mode(&m,
+ &sii902x.fbi->modelist);
+
+ fb_videomode_to_var(&sii902x.fbi->var, mode);
+
+ sii902x.fbi->var.activate |= FB_ACTIVATE_FORCE;
+ console_lock();
+ sii902x.fbi->flags |= FBINFO_MISC_USEREVENT;
+ fb_set_var(sii902x.fbi, &sii902x.fbi->var);
+ sii902x.fbi->flags &= ~FBINFO_MISC_USEREVENT;
+ console_unlock();
+ }
+
+ console_lock();
+ fb_blank(sii902x.fbi, FB_BLANK_UNBLANK);
+ console_unlock();
+ }
+ } else {
+ sii902x.cable_plugin = 0;
+ dev_dbg(&sii902x.pdev->dev, "EVENT=plugout\n");
+ sprintf(event_string, "EVENT=plugout");
+ console_lock();
+ fb_blank(sii902x.fbi, FB_BLANK_POWERDOWN);
+ console_unlock();
+ }
+ kobject_uevent_env(&sii902x.pdev->dev.kobj, KOBJ_CHANGE, envp);
+ }
+ i2c_smbus_write_byte_data(sii902x.client, 0x3D, dat);
+
+ dev_dbg(&sii902x.pdev->dev, "exit %s\n", __func__);
+
+}
+
+static irqreturn_t sii902x_detect_handler(int irq, void *data)
+{
+ if (sii902x.fbi)
+ schedule_delayed_work(&(sii902x.det_work), msecs_to_jiffies(20));
+ else
+ sii902x.waiting_for_fb = true;
+
+ return IRQ_HANDLED;
+}
+
+static int sii902x_fb_event(struct notifier_block *nb, unsigned long val, void *v)
+{
+ struct fb_event *event = v;
+ struct fb_info *fbi = event->info;
+
+ dev_dbg(&sii902x.pdev->dev, "%s\n", __func__);
+
+ switch (val) {
+ case FB_EVENT_FB_REGISTERED:
+ if (sii902x.fbi == NULL) {
+ sii902x.fbi = fbi;
+ if (sii902x.waiting_for_fb)
+ det_worker(NULL);
+ }
+ fb_show_logo(fbi, 0);
+ break;
+ case FB_EVENT_MODE_CHANGE:
+ sii902x_setup(fbi);
+ break;
+ case FB_EVENT_BLANK:
+ if (*((int *)event->data) == FB_BLANK_UNBLANK) {
+ dev_dbg(&sii902x.pdev->dev, "FB_BLANK_UNBLANK\n");
+ sii902x_poweron();
+ } else {
+ dev_dbg(&sii902x.pdev->dev, "FB_BLANK_BLANK\n");
+ sii902x_poweroff();
+ }
+ break;
+ }
+ return 0;
+}
+
+static struct notifier_block nb = {
+ .notifier_call = sii902x_fb_event,
+};
+
+static int __devinit sii902x_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int i, dat, ret;
+ struct fsl_mxc_lcd_platform_data *plat = client->dev.platform_data;
+ struct fb_info edid_fbi;
+
+ dev_dbg(&sii902x.pdev->dev, "%s\n", __func__);;
+
+ sii902x.client = client;
+
+ /* Claim HDMI pins */
+ if (plat->get_pins)
+ if (!plat->get_pins())
+ return -EACCES;
+
+ if (plat->reset) {
+ sii902x_reset = plat->reset;
+ sii902x_reset();
+ }
+
+ /* Set 902x in hardware TPI mode on and jump out of D3 state */
+ if (i2c_smbus_write_byte_data(sii902x.client, 0xc7, 0x00) < 0) {
+ dev_err(&sii902x.client->dev,
+ "Sii902x: cound not find device\n");
+ return -ENODEV;
+ }
+
+ /* read device ID */
+ for (i = 10; i > 0; i--) {
+ dat = i2c_smbus_read_byte_data(sii902x.client, 0x1B);
+ printk(KERN_DEBUG "Sii902x: read id = 0x%02X", dat);
+ if (dat == 0xb0) {
+ dat = i2c_smbus_read_byte_data(sii902x.client, 0x1C);
+ printk(KERN_DEBUG "-0x%02X", dat);
+ dat = i2c_smbus_read_byte_data(sii902x.client, 0x1D);
+ printk(KERN_DEBUG "-0x%02X", dat);
+ dat = i2c_smbus_read_byte_data(sii902x.client, 0x30);
+ printk(KERN_DEBUG "-0x%02X\n", dat);
+ break;
+ }
+ }
+ if (i == 0) {
+ dev_err(&sii902x.client->dev,
+ "Sii902x: cound not find device\n");
+ return -ENODEV;
+ }
+
+ /* try to read edid */
+ ret = sii902x_read_edid(&edid_fbi);
+ if (ret < 0)
+ dev_warn(&sii902x.client->dev, "Can not read edid\n");
+
+ if (ret >= 0)
+ mxcfb_elcdif_register_mode(edid_fbi.monspecs.modedb,
+ edid_fbi.monspecs.modedb_len, MXC_DISP_DDC_DEV);
+
+ if (sii902x.client->irq) {
+ ret = request_irq(sii902x.client->irq, sii902x_detect_handler,
+ IRQF_TRIGGER_FALLING,
+ "SII902x_det", &sii902x);
+ if (ret < 0)
+ dev_warn(&sii902x.client->dev,
+ "Sii902x: cound not request det irq %d\n",
+ sii902x.client->irq);
+ else {
+ /*enable cable hot plug irq*/
+ i2c_smbus_write_byte_data(sii902x.client, 0x3c, 0x01);
+ INIT_DELAYED_WORK(&(sii902x.det_work), det_worker);
+ }
+ ret = device_create_file(&sii902x.pdev->dev, &dev_attr_fb_name);
+ if (ret < 0)
+ dev_warn(&sii902x.client->dev,
+ "Sii902x: cound not create sys node for fb name\n");
+ ret = device_create_file(&sii902x.pdev->dev, &dev_attr_cable_state);
+ if (ret < 0)
+ dev_warn(&sii902x.client->dev,
+ "Sii902x: cound not create sys node for cable state\n");
+ ret = device_create_file(&sii902x.pdev->dev, &dev_attr_edid);
+ if (ret < 0)
+ dev_warn(&sii902x.client->dev,
+ "Sii902x: cound not create sys node for edid\n");
+
+ }
+
+ fb_register_client(&nb);
+
+ dev_dbg(&sii902x.pdev->dev, "%s exit\n", __func__);;
+
+ return 0;
+}
+
+static int __devexit sii902x_remove(struct i2c_client *client)
+{
+ struct fsl_mxc_lcd_platform_data *plat = sii902x.client->dev.platform_data;
+
+ dev_dbg(&sii902x.pdev->dev, "%s\n", __func__);
+
+ fb_unregister_client(&nb);
+ sii902x_poweroff();
+
+ /* Release HDMI pins */
+ if (plat->put_pins)
+ plat->put_pins();
+
+ return 0;
+}
+
+static int sii902x_suspend(struct i2c_client *client, pm_message_t message)
+{
+ /*TODO*/
+ return 0;
+}
+
+static int sii902x_resume(struct i2c_client *client)
+{
+ /*TODO*/
+ return 0;
+}
+
+static void sii902x_poweron(void)
+{
+ struct fsl_mxc_lcd_platform_data *plat = sii902x.client->dev.platform_data;
+
+ dev_dbg(&sii902x.pdev->dev, "%s\n", __func__);
+
+ /* Enable pins to HDMI */
+ if (plat->enable_pins)
+ plat->enable_pins();
+
+ /* Turn on DVI or HDMI */
+ if (sii902x.edid_cfg.hdmi_cap)
+ i2c_smbus_write_byte_data(sii902x.client, 0x1A, 0x01);
+ else
+ i2c_smbus_write_byte_data(sii902x.client, 0x1A, 0x00);
+ return;
+}
+
+static void sii902x_poweroff(void)
+{
+ struct fsl_mxc_lcd_platform_data *plat = sii902x.client->dev.platform_data;
+
+ dev_dbg(&sii902x.pdev->dev, "%s\n", __func__);
+
+ /* disable tmds before changing resolution */
+ if (sii902x.edid_cfg.hdmi_cap)
+ i2c_smbus_write_byte_data(sii902x.client, 0x1A, 0x11);
+ else
+ i2c_smbus_write_byte_data(sii902x.client, 0x1A, 0x10);
+
+ /* Disable pins to HDMI */
+ if (plat->disable_pins)
+ plat->disable_pins();
+
+ return;
+}
+
+static const struct i2c_device_id sii902x_id[] = {
+ { "sii902x", 0 },
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, sii902x_id);
+
+static struct i2c_driver sii902x_i2c_driver = {
+ .driver = {
+ .name = "sii902x",
+ },
+ .probe = sii902x_probe,
+ .remove = sii902x_remove,
+ .suspend = sii902x_suspend,
+ .resume = sii902x_resume,
+ .id_table = sii902x_id,
+};
+
+static int __init sii902x_init(void)
+{
+ int ret;
+
+ memset(&sii902x, 0, sizeof(sii902x));
+
+ sii902x.pdev = platform_device_register_simple("sii902x", 0, NULL, 0);
+ if (IS_ERR(sii902x.pdev)) {
+ printk(KERN_ERR
+ "Unable to register Sii902x as a platform device\n");
+ ret = PTR_ERR(sii902x.pdev);
+ goto err;
+ }
+
+ return i2c_add_driver(&sii902x_i2c_driver);
+err:
+ return ret;
+}
+
+static void __exit sii902x_exit(void)
+{
+ i2c_del_driver(&sii902x_i2c_driver);
+ platform_device_unregister(sii902x.pdev);
+}
+
+module_init(sii902x_init);
+module_exit(sii902x_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("SII902x DVI/HDMI driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index 2a9557307643..ab22c4a9472e 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -135,6 +135,7 @@ struct fsl_usb2_platform_data {
void (*platform_rh_suspend)(struct fsl_usb2_platform_data *);
void (*platform_rh_resume)(struct fsl_usb2_platform_data *);
void (*platform_set_disconnect_det)(struct fsl_usb2_platform_data *, bool);
+ void (*platform_phy_power_on)(void);
struct fsl_usb2_wakeup_platform_data *wakeup_pdata;
struct platform_device *pdev;
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 {
diff --git a/include/linux/mfd/mxc-hdmi-core.h b/include/linux/mfd/mxc-hdmi-core.h
index f16b11cb5cf4..26fa47d09abf 100644
--- a/include/linux/mfd/mxc-hdmi-core.h
+++ b/include/linux/mfd/mxc-hdmi-core.h
@@ -60,5 +60,6 @@ int mxc_hdmi_register_audio(struct snd_pcm_substream *substream);
void mxc_hdmi_unregister_audio(struct snd_pcm_substream *substream);
unsigned int hdmi_set_cable_state(unsigned int state);
unsigned int hdmi_set_blank_state(unsigned int state);
+int check_hdmi_state(void);
#endif
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 1cd6d901dcd4..57aac193a943 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -373,15 +373,15 @@ struct nand_ecc_ctrl {
int (*correct)(struct mtd_info *mtd, uint8_t *dat, uint8_t *read_ecc,
uint8_t *calc_ecc);
int (*read_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
- uint8_t *buf, int page);
+ uint8_t *buf, int oob_required, int page);
void (*write_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
- const uint8_t *buf);
+ const uint8_t *buf, int oob_required);
int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
- uint8_t *buf, int page);
+ uint8_t *buf, int oob_required, int page);
int (*read_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
uint32_t offs, uint32_t len, uint8_t *buf);
void (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
- const uint8_t *buf);
+ const uint8_t *buf, int oob_required);
int (*read_oob)(struct mtd_info *mtd, struct nand_chip *chip, int page,
int sndcmd);
int (*write_oob)(struct mtd_info *mtd, struct nand_chip *chip,
@@ -507,7 +507,8 @@ struct nand_chip {
int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state,
int status, int page);
int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
- const uint8_t *buf, int page, int cached, int raw);
+ const uint8_t *buf, int oob_required, int page,
+ int cached, int raw);
int chip_delay;
unsigned int options;
diff --git a/include/linux/mxcfb.h b/include/linux/mxcfb.h
index 7588d9d09d16..962aa6072b82 100644
--- a/include/linux/mxcfb.h
+++ b/include/linux/mxcfb.h
@@ -92,6 +92,8 @@ struct mxcfb_rect {
#define EPDC_FLAG_USE_ALT_BUFFER 0x100
#define EPDC_FLAG_TEST_COLLISION 0x200
#define EPDC_FLAG_GROUP_UPDATE 0x400
+#define EPDC_FLAG_USE_DITHERING_Y1 0x2000
+#define EPDC_FLAG_USE_DITHERING_Y4 0x4000
#define FB_POWERDOWN_DISABLE -1
@@ -153,6 +155,7 @@ struct mxcfb_waveform_modes {
#define MXCFB_SET_PWRDOWN_DELAY _IOW('F', 0x30, int32_t)
#define MXCFB_GET_PWRDOWN_DELAY _IOR('F', 0x31, int32_t)
#define MXCFB_SET_UPDATE_SCHEME _IOW('F', 0x32, __u32)
+#define MXCFB_GET_WORK_BUFFER _IOWR('F', 0x34, unsigned long)
#ifdef __KERNEL__
@@ -160,6 +163,11 @@ extern struct fb_videomode mxcfb_modedb[];
extern int mxcfb_modedb_sz;
enum {
+ MXC_DISP_SPEC_DEV = 0,
+ MXC_DISP_DDC_DEV = 1,
+};
+
+enum {
MXCFB_REFRESH_OFF,
MXCFB_REFRESH_AUTO,
MXCFB_REFRESH_PARTIAL,
@@ -168,5 +176,8 @@ enum {
int mxcfb_set_refresh_mode(struct fb_info *fbi, int mode,
struct mxcfb_rect *update_region);
int mxc_elcdif_frame_addr_setup(dma_addr_t phys);
+void mxcfb_elcdif_register_mode(const struct fb_videomode *modedb,
+ int num_modes, int dev_mode);
+
#endif /* __KERNEL__ */
#endif
diff --git a/include/linux/power/sabresd_battery.h b/include/linux/power/sabresd_battery.h
index c251a748a0db..463fa90afdb6 100644
--- a/include/linux/power/sabresd_battery.h
+++ b/include/linux/power/sabresd_battery.h
@@ -38,6 +38,7 @@ struct max8903_pdata {
int flt; /* Fault output */
int dcm; /* Current-Limit Mode input (1: DC, 2: USB) */
int usus; /* USB Suspend Input (1: suspended) */
+ int feature_flag;/*battery capacity feature(0:enable, 1:disable)*/
/* DCM wired to Logic High
Set this true when DCM pin connect to Logic high.*/
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index b14531157067..784b5957e37a 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -2218,8 +2218,6 @@ SOC_ENUM("Capture LHPF Mode", cap_lhpf_mode),
SOC_DOUBLE_R_TLV("Sidetone Volume", WM8962_DAC_DSP_MIXING_1,
WM8962_DAC_DSP_MIXING_2, 4, 12, 0, st_tlv),
-SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8962_LEFT_DAC_VOLUME,
- WM8962_RIGHT_DAC_VOLUME, 1, 127, 0, digital_tlv),
SOC_SINGLE("DAC High Performance Switch", WM8962_ADC_DAC_CONTROL_2, 0, 1, 0),
SOC_SINGLE("ADC High Performance Switch", WM8962_ADDITIONAL_CONTROL_1,
diff --git a/sound/soc/imx/imx-hdmi-dma.c b/sound/soc/imx/imx-hdmi-dma.c
index 8ada80e0cc74..342f9c85f481 100644
--- a/sound/soc/imx/imx-hdmi-dma.c
+++ b/sound/soc/imx/imx-hdmi-dma.c
@@ -1116,6 +1116,8 @@ static int hdmi_dma_trigger(struct snd_pcm_substream *substream, int cmd)
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ if (!check_hdmi_state())
+ return 0;
rtd->frame_idx = 0;
if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) {
appl_bytes = frames_to_bytes(runtime,
diff --git a/sound/soc/imx/imx-spdif.c b/sound/soc/imx/imx-spdif.c
index efee7696bfbb..13c97aeb0622 100644
--- a/sound/soc/imx/imx-spdif.c
+++ b/sound/soc/imx/imx-spdif.c
@@ -1,7 +1,7 @@
/*
* ASoC S/PDIF driver for IMX development boards
*
- * Copyright (C) 2008-2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2008-2012 Freescale Semiconductor, Inc.
*
* based on stmp3780_devb_spdif.c
*
@@ -119,6 +119,11 @@ static int __init imx_spdif_init(void)
return -ENOMEM;
}
+ if (machine_is_mx6sl_evk()) {
+ imx_spdif_dai_link.name = "HDMI-Audio";
+ imx_spdif_dai_link.stream_name = "HDMI-Audio";
+ }
+
platform_set_drvdata(imx_spdif_snd_device, &snd_soc_card_imx_spdif);
ret = platform_device_add(imx_spdif_snd_device);
diff --git a/tools/perf/util/include/linux/compiler.h b/tools/perf/util/include/linux/compiler.h
index 791f9dd27ebf..547628e97f3d 100644
--- a/tools/perf/util/include/linux/compiler.h
+++ b/tools/perf/util/include/linux/compiler.h
@@ -5,7 +5,9 @@
#define __always_inline inline
#endif
#define __user
+#ifndef __attribute_const__
#define __attribute_const__
+#endif
#define __used __attribute__((__unused__))